diff --git a/polkadot/.cargo/config.toml b/polkadot/.cargo/config.toml new file mode 100644 index 0000000000000000000000000000000000000000..4796a2c26965c1021d14c6acc854bca1aea76941 --- /dev/null +++ b/polkadot/.cargo/config.toml @@ -0,0 +1,33 @@ +# +# An auto defined `clippy` feature was introduced, +# but it was found to clash with user defined features, +# so was renamed to `cargo-clippy`. +# +# If you want standard clippy run: +# RUSTFLAGS= cargo clippy +[target.'cfg(feature = "cargo-clippy")'] +rustflags = [ + "-Aclippy::all", + "-Dclippy::correctness", + "-Aclippy::if-same-then-else", + "-Aclippy::clone-double-ref", + "-Dclippy::complexity", + "-Aclippy::zero-prefixed-literal", # 00_1000_000 + "-Aclippy::type_complexity", # raison d'etre + "-Aclippy::nonminimal-bool", # maybe + "-Aclippy::borrowed-box", # Reasonable to fix this one + "-Aclippy::too-many-arguments", # (Turning this on would lead to) + "-Aclippy::unnecessary_cast", # Types may change + "-Aclippy::identity-op", # One case where we do 0 + + "-Aclippy::useless_conversion", # Types may change + "-Aclippy::unit_arg", # styalistic. + "-Aclippy::option-map-unit-fn", # styalistic + "-Aclippy::bind_instead_of_map", # styalistic + "-Aclippy::erasing_op", # E.g. 0 * DOLLARS + "-Aclippy::eq_op", # In tests we test equality. + "-Aclippy::while_immutable_condition", # false positives + "-Aclippy::needless_option_as_deref", # false positives + "-Aclippy::derivable_impls", # false positives + "-Aclippy::stable_sort_primitive", # prefer stable sort + "-Aclippy::extra-unused-type-parameters", # stylistic +] diff --git a/polkadot/.dockerignore b/polkadot/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..45051abf40fe3d34770628313e59c838a2f56d89 --- /dev/null +++ b/polkadot/.dockerignore @@ -0,0 +1,2 @@ +doc +**/target diff --git a/polkadot/.editorconfig b/polkadot/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..6b736d884f229f6f4f479e9ead5bedebf412099a --- /dev/null +++ b/polkadot/.editorconfig @@ -0,0 +1,26 @@ +root = true + +[*.rs] +indent_style=tab +indent_size=tab +tab_width=4 +max_line_length=120 +end_of_line=lf +charset=utf-8 +trim_trailing_whitespace=true +insert_final_newline=true + +[*.yml] +indent_style=space +indent_size=2 +tab_width=8 +end_of_line=lf +charset=utf-8 +trim_trailing_whitespace=true +insert_final_newline=true + +[*.sh] +indent_style=space +indent_size=2 +tab_width=8 +end_of_line=lf diff --git a/polkadot/.gitattributes b/polkadot/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..2ea1ab2d6b9cff5f075666eb5a780575870c221e --- /dev/null +++ b/polkadot/.gitattributes @@ -0,0 +1,2 @@ +/.gitlab-ci.yml filter=ci-prettier +/scripts/ci/gitlab/pipeline/*.yml filter=ci-prettier diff --git a/polkadot/.github/CODEOWNERS b/polkadot/.github/CODEOWNERS new file mode 100644 index 0000000000000000000000000000000000000000..a92dc0bb006cb377d2c4a6b0075fca882b820647 --- /dev/null +++ b/polkadot/.github/CODEOWNERS @@ -0,0 +1,6 @@ +# CI +/.github/ @paritytech/ci @chevdor +/scripts/ci/ @paritytech/ci @chevdor +/.gitlab-ci.yml @paritytech/ci +# lingua.dic is not managed by CI team +/scripts/ci/gitlab/lingua.dic diff --git a/polkadot/.github/ISSUE_TEMPLATE/bug_report.md b/polkadot/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000000000000000000000000000000000..c2214ab7d93276beb1422f043992ddc620b44f61 --- /dev/null +++ b/polkadot/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,13 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +- It would help if you submit info about the system you are running, e.g.: operating system, kernel version, amount of available memory and swap, etc. +- Logs could be very helpful. If possible, submit the whole log. Please format it as ```code blocks```. +- Describe the role your node plays, e.g. validator, full node or light client. +- Any command-line options were passed? diff --git a/polkadot/.github/ISSUE_TEMPLATE/release.md b/polkadot/.github/ISSUE_TEMPLATE/release.md new file mode 100644 index 0000000000000000000000000000000000000000..37b422a9b3ecceef31a6bb4f06ca37c6e46151aa --- /dev/null +++ b/polkadot/.github/ISSUE_TEMPLATE/release.md @@ -0,0 +1,52 @@ +--- +name: Release issue template +about: Tracking issue for new releases +title: Polkadot {{ env.VERSION }} Release checklist +--- +# Release Checklist + +This is the release checklist for Polkadot {{ env.VERSION }}. **All** following +checks should be completed before publishing a new release of the +Polkadot/Kusama/Westend/Rococo runtime or client. The current release candidate can be +checked out with `git checkout release-{{ env.VERSION }}` + +### Runtime Releases + +These checks should be performed on the codebase prior to forking to a release- +candidate branch. + +- [ ] Verify [`spec_version`](https://github.com/paritytech/polkadot/blob/master/doc/release-checklist.md#spec-version) has been incremented since the + last release for any native runtimes from any existing use on public + (non-private) networks. If the runtime was published (release or pre-release), either + the `spec_version` or `impl` must be bumped. +- [ ] Verify previously [completed migrations](https://github.com/paritytech/polkadot/blob/master/doc/release-checklist.md#old-migrations-removed) are + removed for any public (non-private/test) networks. +- [ ] Verify pallet and [extrinsic ordering](https://github.com/paritytech/polkadot/blob/master/doc/release-checklist.md#extrinsic-ordering) has stayed + the same. Bump `transaction_version` if not. +- [ ] Verify new extrinsics have been correctly whitelisted/blacklisted for + [proxy filters](https://github.com/paritytech/polkadot/blob/master/doc/release-checklist.md#proxy-filtering). +- [ ] Verify [benchmarks](https://github.com/paritytech/polkadot/blob/master/doc/release-checklist.md#benchmarks) have been updated for any modified + runtime logic. + +The following checks can be performed after we have forked off to the release- +candidate branch or started an additional release candidate branch (rc-2, rc-3, etc) + +- [ ] Verify [new migrations](https://github.com/paritytech/polkadot/blob/master/doc/release-checklist.md#new-migrations) complete successfully, and the + runtime state is correctly updated for any public (non-private/test) + networks. +- [ ] Verify [Polkadot JS API](https://github.com/paritytech/polkadot/blob/master/doc/release-checklist.md#polkadot-js) are up to date with the latest + runtime changes. +- [ ] Check with the Signer's team to make sure metadata update QR are lined up +- [ ] Push runtime upgrade to Westend and verify network stability. + +### All Releases + +- [ ] Check that the new client versions have [run on the network](https://github.com/paritytech/polkadot/blob/master/doc/release-checklist.md#burn-in) + without issue for 12+ hours on >75% of our validator nodes. +- [ ] Check that a draft release has been created at + https://github.com/paritytech/polkadot/releases with relevant [release + notes](https://github.com/paritytech/polkadot/blob/master/doc/release-checklist.md#release-notes) +- [ ] Check that [build artifacts](https://github.com/paritytech/polkadot/blob/master/doc/release-checklist.md#build-artifacts) have been added to the + draft-release +- [ ] Check that all items listed in the [milestone](https://github.com/paritytech/polkadot/milestones) are included in the release. +- [ ] Ensure that no `freenotes` were added into the release branch after the latest generated RC diff --git a/polkadot/.github/dependabot.yml b/polkadot/.github/dependabot.yml new file mode 100644 index 0000000000000000000000000000000000000000..a1fa925970bbb088349d610bd81284f1129cb154 --- /dev/null +++ b/polkadot/.github/dependabot.yml @@ -0,0 +1,26 @@ +version: 2 +updates: + - package-ecosystem: "cargo" + directory: "/" + labels: ["A2-insubstantial", "B0-silent", "C1-low", "E2-dependencies"] + # Handle updates for crates from github.com/paritytech/substrate manually. + ignore: + - dependency-name: "substrate-*" + - dependency-name: "sc-*" + - dependency-name: "sp-*" + - dependency-name: "frame-*" + - dependency-name: "fork-tree" + - dependency-name: "frame-remote-externalities" + - dependency-name: "pallet-*" + - dependency-name: "beefy-*" + - dependency-name: "try-runtime-*" + - dependency-name: "test-runner" + - dependency-name: "generate-bags" + - dependency-name: "sub-tokens" + schedule: + interval: "daily" + - package-ecosystem: github-actions + directory: '/' + labels: ["A2-insubstantial", "B0-silent", "C1-low", "E2-dependencies"] + schedule: + interval: daily diff --git a/polkadot/.github/pr-custom-review.yml b/polkadot/.github/pr-custom-review.yml new file mode 100644 index 0000000000000000000000000000000000000000..136c9e75ff2deca5a031e41f065aec74a264ab1f --- /dev/null +++ b/polkadot/.github/pr-custom-review.yml @@ -0,0 +1,42 @@ +# 🔒 PROTECTED: Changes to locks-review-team should be approved by the current locks-review-team +locks-review-team: locks-review +team-leads-team: polkadot-review +action-review-team: ci + +rules: + - name: Runtime files + check_type: changed_files + condition: + include: ^runtime\/(kusama|polkadot)\/src\/.+\.rs$ + exclude: ^runtime\/(kusama|polkadot)\/src\/weights\/.+\.rs$ + all_distinct: + - min_approvals: 1 + teams: + - locks-review + - min_approvals: 1 + teams: + - polkadot-review + + - name: Core developers + check_type: changed_files + condition: + include: .* + # excluding files from 'Runtime files' and 'CI files' rules + exclude: ^runtime/(kusama|polkadot)/src/[^/]+\.rs$|^\.gitlab-ci\.yml|^(?!.*\.dic$|.*spellcheck\.toml$)scripts/ci/.*|^\.github/.* + min_approvals: 3 + teams: + - core-devs + + - name: CI files + check_type: changed_files + condition: + # dictionary files are excluded + include: ^\.gitlab-ci\.yml|^(?!.*\.dic$|.*spellcheck\.toml$)scripts/ci/.*|^\.github/.* + min_approvals: 2 + teams: + - ci + - release-engineering + +prevent-review-request: + teams: + - core-devs diff --git a/polkadot/.github/workflows/burnin-label-notification.yml b/polkadot/.github/workflows/burnin-label-notification.yml new file mode 100644 index 0000000000000000000000000000000000000000..536f8fa2a3f6571a3643db62ee41e08bf3fec5da --- /dev/null +++ b/polkadot/.github/workflows/burnin-label-notification.yml @@ -0,0 +1,24 @@ +name: Notify devops when burn-in label applied +on: + pull_request: + types: [labeled] + +jobs: + notify-devops: + runs-on: ubuntu-latest + strategy: + matrix: + channel: + - name: 'Team: DevOps' + room: '!lUslSijLMgNcEKcAiE:parity.io' + + steps: + - name: Send Matrix message to ${{ matrix.channel.name }} + if: startsWith(github.event.label.name, 'A1-') + uses: s3krit/matrix-message-action@70ad3fb812ee0e45ff8999d6af11cafad11a6ecf # v0.0.3 + with: + room_id: ${{ matrix.channel.room }} + access_token: ${{ secrets.RELEASENOTES_MATRIX_V2_ACCESS_TOKEN }} + server: m.parity.io + message: | + @room Burn-in request received for the following PR: ${{ github.event.pull_request.html_url }} diff --git a/polkadot/.github/workflows/check-D-labels.yml b/polkadot/.github/workflows/check-D-labels.yml new file mode 100644 index 0000000000000000000000000000000000000000..9abefaa6fa10034c56432709ede371309a77df2b --- /dev/null +++ b/polkadot/.github/workflows/check-D-labels.yml @@ -0,0 +1,50 @@ +name: Check D labels + +on: + pull_request: + types: [labeled, opened, synchronize, unlabeled] + paths: + - runtime/polkadot/** + - runtime/kusama/** + - runtime/common/** + - primitives/src/** + +jobs: + check-labels: + runs-on: ubuntu-latest + steps: + - name: Pull image + env: + IMAGE: paritytech/ruled_labels:0.4.0 + run: docker pull $IMAGE + + - name: Check labels + env: + IMAGE: paritytech/ruled_labels:0.4.0 + MOUNT: /work + GITHUB_PR: ${{ github.event.pull_request.number }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + API_BASE: https://api.github.com/repos + REPO: ${{ github.repository }} + RULES_PATH: labels/ruled_labels + CHECK_SPECS: specs_polkadot.yaml + run: | + echo "REPO: ${REPO}" + echo "GITHUB_PR: ${GITHUB_PR}" + # Clone repo with labels specs + git clone https://github.com/paritytech/labels + # Fetch the labels for the PR under test + labels=$( curl -H "Authorization: token ${GITHUB_TOKEN}" -s "$API_BASE/${REPO}/pulls/${GITHUB_PR}" | jq '.labels | .[] | .name' | tr "\n" ",") + + if [ -z "${labels}" ]; then + docker run --rm -i -v $PWD/${RULES_PATH}/:$MOUNT $IMAGE check $MOUNT/$CHECK_SPECS --tags audit --no-label + fi + + labels_args=${labels: :-1} + printf "Checking labels: %s\n" "${labels_args}" + + # Prevent the shell from splitting labels with spaces + IFS="," + + # --dev is more useful to debug mode to debug + docker run --rm -i -v $PWD/${RULES_PATH}/:$MOUNT $IMAGE check $MOUNT/$CHECK_SPECS --labels ${labels_args} --dev --tags audit diff --git a/polkadot/.github/workflows/check-bootnodes.yml b/polkadot/.github/workflows/check-bootnodes.yml new file mode 100644 index 0000000000000000000000000000000000000000..897a90d3ae928336688d6fdcbc2a6f80036e11a3 --- /dev/null +++ b/polkadot/.github/workflows/check-bootnodes.yml @@ -0,0 +1,31 @@ +# checks all networks we care about (kusama, polkadot, westend) and ensures +# the bootnodes in their respective chainspecs are contactable + +name: Check all bootnodes +on: + push: + branches: + # Catches v1.2.3 and v1.2.3-rc1 + - release-v[0-9]+.[0-9]+.[0-9]+* + +jobs: + check_bootnodes: + strategy: + fail-fast: false + matrix: + runtime: [westend, kusama, polkadot] + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v3 + - name: Install polkadot + shell: bash + run: | + curl -L "$(curl -s https://api.github.com/repos/paritytech/polkadot/releases/latest \ + | jq -r '.assets | .[] | select(.name == "polkadot").browser_download_url')" \ + | sudo tee /usr/local/bin/polkadot > /dev/null + sudo chmod +x /usr/local/bin/polkadot + polkadot --version + - name: Check ${{ matrix.runtime }} bootnodes + shell: bash + run: scripts/ci/github/check_bootnodes.sh node/service/chain-specs/${{ matrix.runtime }}.json diff --git a/polkadot/.github/workflows/check-labels.yml b/polkadot/.github/workflows/check-labels.yml new file mode 100644 index 0000000000000000000000000000000000000000..df0a0e9cf02dd182492f7ecbf5a8bf9c4ebbf254 --- /dev/null +++ b/polkadot/.github/workflows/check-labels.yml @@ -0,0 +1,45 @@ +name: Check labels + +on: + pull_request: + types: [labeled, opened, synchronize, unlabeled] + +jobs: + check-labels: + runs-on: ubuntu-latest + steps: + - name: Pull image + env: + IMAGE: paritytech/ruled_labels:0.4.0 + run: docker pull $IMAGE + + - name: Check labels + env: + IMAGE: paritytech/ruled_labels:0.4.0 + MOUNT: /work + GITHUB_PR: ${{ github.event.pull_request.number }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + API_BASE: https://api.github.com/repos + REPO: ${{ github.repository }} + RULES_PATH: labels/ruled_labels + CHECK_SPECS: specs_polkadot.yaml + run: | + echo "REPO: ${REPO}" + echo "GITHUB_PR: ${GITHUB_PR}" + # Clone repo with labels specs + git clone https://github.com/paritytech/labels + # Fetch the labels for the PR under test + labels=$( curl -H "Authorization: token ${GITHUB_TOKEN}" -s "$API_BASE/${REPO}/pulls/${GITHUB_PR}" | jq '.labels | .[] | .name' | tr "\n" ",") + + if [ -z "${labels}" ]; then + docker run --rm -i -v $PWD/${RULES_PATH}/:$MOUNT $IMAGE check $MOUNT/$CHECK_SPECS --tags PR --no-label + fi + + labels_args=${labels: :-1} + printf "Checking labels: %s\n" "${labels_args}" + + # Prevent the shell from splitting labels with spaces + IFS="," + + # --dev is more useful to debug mode to debug + docker run --rm -i -v $PWD/${RULES_PATH}/:$MOUNT $IMAGE check $MOUNT/$CHECK_SPECS --labels ${labels_args} --dev --tags PR diff --git a/polkadot/.github/workflows/check-licenses.yml b/polkadot/.github/workflows/check-licenses.yml new file mode 100644 index 0000000000000000000000000000000000000000..1e654f7b30705751b3877ccdf93c76ac12723682 --- /dev/null +++ b/polkadot/.github/workflows/check-licenses.yml @@ -0,0 +1,26 @@ +name: Check licenses + +on: + pull_request: + +jobs: + check-licenses: + runs-on: ubuntu-22.04 + steps: + - name: Checkout sources + uses: actions/checkout@v3 + - uses: actions/setup-node@v3.8.1 + with: + node-version: '18.x' + registry-url: 'https://npm.pkg.github.com' + scope: '@paritytech' + - name: Check the licenses + run: | + shopt -s globstar + + npx @paritytech/license-scanner@0.0.5 scan \ + --ensure-licenses=Apache-2.0 \ + --ensure-licenses=GPL-3.0-only \ + ./**/*.rs + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/polkadot/.github/workflows/check-new-bootnodes.yml b/polkadot/.github/workflows/check-new-bootnodes.yml new file mode 100644 index 0000000000000000000000000000000000000000..25b2a0a56fe5f8f93854e38ea4b20416a35064a9 --- /dev/null +++ b/polkadot/.github/workflows/check-new-bootnodes.yml @@ -0,0 +1,28 @@ +# If a chainspec file is updated with new bootnodes, we check to make sure those bootnodes are contactable + +name: Check new bootnodes +on: + pull_request: + paths: + - 'node/service/chain-specs/*.json' + +jobs: + check_bootnodes: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install polkadot + shell: bash + run: | + curl -L "$(curl -s https://api.github.com/repos/paritytech/polkadot/releases/latest \ + | jq -r '.assets | .[] | select(.name == "polkadot").browser_download_url')" \ + | sudo tee /usr/local/bin/polkadot > /dev/null + sudo chmod +x /usr/local/bin/polkadot + polkadot --version + - name: Check new bootnodes + shell: bash + run: | + scripts/ci/github/check_new_bootnodes.sh diff --git a/polkadot/.github/workflows/check-weights.yml b/polkadot/.github/workflows/check-weights.yml new file mode 100644 index 0000000000000000000000000000000000000000..e6a6c43e0a6a9b76448d448685d63672d8288a3f --- /dev/null +++ b/polkadot/.github/workflows/check-weights.yml @@ -0,0 +1,49 @@ +name: Check updated weights + +on: + pull_request: + paths: +  - 'runtime/*/src/weights/**' + +jobs: + check_weights_files: + strategy: + fail-fast: false + matrix: + runtime: [westend, kusama, polkadot, rococo] + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v3 + - name: Check weights files + shell: bash + run: | + scripts/ci/github/verify_updated_weights.sh ${{ matrix.runtime }} + + # This job uses https://github.com/ggwpez/substrate-weight-compare to compare the weights of the current + # release with the last release, then adds them as a comment to the PR. + check_weight_changes: + strategy: + fail-fast: false + matrix: + runtime: [westend, kusama, polkadot, rococo] + runs-on: ubuntu-latest + steps: + - name: Get latest release + run: | + LAST_RELEASE=$(curl -s https://api.github.com/repos/paritytech/polkadot/releases/latest | jq -r .tag_name) + echo "LAST_RELEASE=$LAST_RELEASE" >> $GITHUB_ENV + - name: Checkout current sources + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Check weight changes + shell: bash + run: | + cargo install --git https://github.com/ggwpez/substrate-weight-compare swc + ./scripts/ci/github/check_weights_swc.sh ${{ matrix.runtime }} "$LAST_RELEASE" | tee swc_output_${{ matrix.runtime }}.md + - name: Add comment + uses: thollander/actions-comment-pull-request@v2 + with: + filePath: ./swc_output_${{ matrix.runtime }}.md + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/polkadot/.github/workflows/honggfuzz.yml b/polkadot/.github/workflows/honggfuzz.yml new file mode 100644 index 0000000000000000000000000000000000000000..27fa0d9967f3b062e75266364092ec9e2cb7c306 --- /dev/null +++ b/polkadot/.github/workflows/honggfuzz.yml @@ -0,0 +1,137 @@ +name: Run nightly fuzzer jobs + +on: + schedule: + - cron: '0 0 * * *' + +jobs: + xcm-fuzzer: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v3 + with: + fetch-depth: 1 + + - name: Install minimal stable Rust + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Install minimal nightly Rust + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + target: wasm32-unknown-unknown + + - name: Install honggfuzz deps + run: sudo apt-get install --no-install-recommends binutils-dev libunwind8-dev + + - name: Install honggfuzz + uses: actions-rs/cargo@v1 + with: + command: install + args: honggfuzz --version "0.5.54" + + - name: Build fuzzer binaries + working-directory: xcm/xcm-simulator/fuzzer/ + run: cargo hfuzz build + + - name: Run fuzzer + working-directory: xcm/xcm-simulator/fuzzer/ + run: bash $GITHUB_WORKSPACE/scripts/ci/github/run_fuzzer.sh xcm-fuzzer + + erasure-coding-round-trip: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v3 + with: + fetch-depth: 1 + + - name: Cache Seed + id: cache-seed-round-trip + uses: actions/cache@v3 + with: + path: erasure-coding/fuzzer/hfuzz_workspace + key: ${{ runner.os }}-erasure-coding + + - name: Install minimal stable Rust + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Install minimal nightly Rust + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + target: wasm32-unknown-unknown + + - name: Install honggfuzz deps + run: sudo apt-get install --no-install-recommends binutils-dev libunwind8-dev + + - name: Install honggfuzz + uses: actions-rs/cargo@v1 + with: + command: install + args: honggfuzz --version "0.5.54" + + - name: Build fuzzer binaries + working-directory: erasure-coding/fuzzer + run: cargo hfuzz build + + - name: Run fuzzer + working-directory: erasure-coding/fuzzer + run: bash $GITHUB_WORKSPACE/scripts/ci/github/run_fuzzer.sh round_trip + + erasure-coding-reconstruct: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v3 + with: + fetch-depth: 1 + + - name: Cache Seed + id: cache-seed-reconstruct + uses: actions/cache@v3 + with: + path: erasure-coding/fuzzer/hfuzz_workspace + key: ${{ runner.os }}-erasure-coding + + - name: Install minimal stable Rust + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Install minimal nightly Rust + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + target: wasm32-unknown-unknown + + - name: Install honggfuzz deps + run: sudo apt-get install --no-install-recommends binutils-dev libunwind8-dev + + - name: Install honggfuzz + uses: actions-rs/cargo@v1 + with: + command: install + args: honggfuzz --version "0.5.54" + + - name: Build fuzzer binaries + working-directory: erasure-coding/fuzzer + run: cargo hfuzz build + + - name: Run fuzzer + working-directory: erasure-coding/fuzzer + run: bash $GITHUB_WORKSPACE/scripts/ci/github/run_fuzzer.sh reconstruct diff --git a/polkadot/.github/workflows/pr-custom-review.yml b/polkadot/.github/workflows/pr-custom-review.yml new file mode 100644 index 0000000000000000000000000000000000000000..8e40c9ee72989d9ef244247456aa578d3836f8c6 --- /dev/null +++ b/polkadot/.github/workflows/pr-custom-review.yml @@ -0,0 +1,42 @@ +name: Assign reviewers + +on: + pull_request: + branches: + - master + - main + types: + - opened + - reopened + - synchronize + - review_requested + - review_request_removed + - ready_for_review + - converted_to_draft + pull_request_review: + +jobs: + pr-custom-review: + runs-on: ubuntu-latest + steps: + - name: Skip if pull request is in Draft + # `if: github.event.pull_request.draft == true` should be kept here, at + # the step level, rather than at the job level. The latter is not + # recommended because when the PR is moved from "Draft" to "Ready to + # review" the workflow will immediately be passing (since it was skipped), + # even though it hasn't actually ran, since it takes a few seconds for + # the workflow to start. This is also disclosed in: + # https://github.community/t/dont-run-actions-on-draft-pull-requests/16817/17 + # That scenario would open an opportunity for the check to be bypassed: + # 1. Get your PR approved + # 2. Move it to Draft + # 3. Push whatever commits you want + # 4. Move it to "Ready for review"; now the workflow is passing (it was + # skipped) and "Check reviews" is also passing (it won't be updated + # until the workflow is finished) + if: github.event.pull_request.draft == true + run: exit 1 + - name: pr-custom-review + uses: paritytech/pr-custom-review@action-v3 + with: + checks-reviews-api: http://pcr.parity-prod.parity.io/api/v1/check_reviews diff --git a/polkadot/.github/workflows/release-01_branch-check.yml b/polkadot/.github/workflows/release-01_branch-check.yml new file mode 100644 index 0000000000000000000000000000000000000000..f2b559b7c176bb52b5668e1ce9a3ac217a388f69 --- /dev/null +++ b/polkadot/.github/workflows/release-01_branch-check.yml @@ -0,0 +1,21 @@ +name: Release - Branch check +on: + push: + branches: + # Catches v1.2.3 and v1.2.3-rc1 + - release-v[0-9]+.[0-9]+.[0-9]+* + + workflow_dispatch: + +jobs: + check_branch: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Run check + shell: bash + run: ./scripts/ci/github/check-rel-br diff --git a/polkadot/.github/workflows/release-10_candidate.yml b/polkadot/.github/workflows/release-10_candidate.yml new file mode 100644 index 0000000000000000000000000000000000000000..54a937a7819a155346aca1405399bdcacaf5f0e3 --- /dev/null +++ b/polkadot/.github/workflows/release-10_candidate.yml @@ -0,0 +1,71 @@ +name: Release - RC automation +on: + push: + branches: + # Catches v1.2.3 and v1.2.3-rc1 + - release-v[0-9]+.[0-9]+.[0-9]+* +jobs: + tag_rc: + runs-on: ubuntu-latest + strategy: + matrix: + channel: + - name: "RelEng: Polkadot Release Coordination" + room: '!cqAmzdIcbOFwrdrubV:parity.io' + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - id: compute_tag + name: Compute next rc tag + shell: bash + run: | + # Get last rc tag if exists, else set it to {version}-rc1 + version=${GITHUB_REF#refs/heads/release-} + echo "$version" + echo "version=$version" >> $GITHUB_OUTPUT + git tag -l + last_rc=$(git tag -l "$version-rc*" | sort -V | tail -n 1) + if [ -n "$last_rc" ]; then + suffix=$(echo "$last_rc" | grep -Eo '[0-9]+$') + echo $suffix + ((suffix++)) + echo $suffix + echo "new_tag=$version-rc$suffix" >> $GITHUB_OUTPUT + echo "first_rc=false" >> $GITHUB_OUTPUT + else + echo "new_tag=$version-rc1" >> $GITHUB_OUTPUT + echo "first_rc=true" >> $GITHUB_OUTPUT + fi + + - name: Apply new tag + uses: tvdias/github-tagger@ed7350546e3e503b5e942dffd65bc8751a95e49d # v0.0.2 + with: + # We can't use the normal GITHUB_TOKEN for the following reason: + # https://docs.github.com/en/actions/reference/events-that-trigger-workflows#triggering-new-workflows-using-a-personal-access-token + # RELEASE_BRANCH_TOKEN requires public_repo OAuth scope + repo-token: "${{ secrets.RELEASE_BRANCH_TOKEN }}" + tag: ${{ steps.compute_tag.outputs.new_tag }} + + - id: create-issue + uses: JasonEtco/create-an-issue@e27dddc79c92bc6e4562f268fffa5ed752639abd # v2.9.1 + # Only create the issue if it's the first release candidate + if: steps.compute_tag.outputs.first_rc == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ steps.compute_tag.outputs.version }} + with: + filename: .github/ISSUE_TEMPLATE/release.md + + - name: Send Matrix message to ${{ matrix.channel.name }} + uses: s3krit/matrix-message-action@70ad3fb812ee0e45ff8999d6af11cafad11a6ecf # v0.0.3 + if: steps.create-issue.outputs.url != '' + with: + room_id: ${{ matrix.channel.room }} + access_token: ${{ secrets.RELEASENOTES_MATRIX_V2_ACCESS_TOKEN }} + server: m.parity.io + message: | + Release process for polkadot ${{ steps.compute_tag.outputs.version }} has been started.
+ Tracking issue: ${{ steps.create-issue.outputs.url }} diff --git a/polkadot/.github/workflows/release-20_extrinsic-ordering-check-from-bin.yml b/polkadot/.github/workflows/release-20_extrinsic-ordering-check-from-bin.yml new file mode 100644 index 0000000000000000000000000000000000000000..0613ed04d35a93f16b0e0f7be3557216a665d0fc --- /dev/null +++ b/polkadot/.github/workflows/release-20_extrinsic-ordering-check-from-bin.yml @@ -0,0 +1,81 @@ +# This workflow performs the Extrinsic Ordering Check on demand using a binary + +name: Release - Extrinsic Ordering Check +on: + workflow_dispatch: + inputs: + reference_url: + description: The WebSocket url of the reference node + default: wss://kusama-rpc.polkadot.io + required: true + binary_url: + description: A url to a Linux binary for the node containing the runtime to test + default: https://releases.parity.io/polkadot/x86_64-debian:stretch/v0.9.10/polkadot + required: true + chain: + description: The name of the chain under test. Usually, you would pass a local chain + default: kusama-local + required: true + +jobs: + check: + name: Run check + runs-on: ubuntu-latest + env: + CHAIN: ${{github.event.inputs.chain}} + BIN_URL: ${{github.event.inputs.binary_url}} + REF_URL: ${{github.event.inputs.reference_url}} + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Fetch binary + run: | + echo Fetching $BIN_URL + wget $BIN_URL + chmod a+x polkadot + ./polkadot --version + + - name: Start local node + run: | + echo Running on $CHAIN + ./polkadot --chain=$CHAIN & + + - name: Prepare output + run: | + VERSION=$(./polkadot --version) + echo "Metadata comparison:" >> output.txt + echo "Date: $(date)" >> output.txt + echo "Reference: $REF_URL" >> output.txt + echo "Target version: $VERSION" >> output.txt + echo "Chain: $CHAIN" >> output.txt + echo "----------------------------------------------------------------------" >> output.txt + + - name: Pull polkadot-js-tools image + run: docker pull jacogr/polkadot-js-tools + + - name: Compare the metadata + run: | + CMD="docker run --pull always --network host jacogr/polkadot-js-tools metadata $REF_URL ws://localhost:9944" + echo -e "Running:\n$CMD" + $CMD >> output.txt + sed -z -i 's/\n\n/\n/g' output.txt + cat output.txt | egrep -n -i '' + SUMMARY=$(./scripts/ci/github/extrinsic-ordering-filter.sh output.txt) + echo -e $SUMMARY + echo -e $SUMMARY >> output.txt + + - name: Show result + run: | + cat output.txt + + - name: Stop our local node + run: pkill polkadot + + - name: Save output as artifact + uses: actions/upload-artifact@v3 + with: + name: ${{ env.CHAIN }} + path: | + output.txt diff --git a/polkadot/.github/workflows/release-21_extrinsic-ordering-check-from-two.yml b/polkadot/.github/workflows/release-21_extrinsic-ordering-check-from-two.yml new file mode 100644 index 0000000000000000000000000000000000000000..6513897f4a13451a1ea8ffa4ea68d51f722c9513 --- /dev/null +++ b/polkadot/.github/workflows/release-21_extrinsic-ordering-check-from-two.yml @@ -0,0 +1,97 @@ +# This workflow performs the Extrinsic Ordering Check on demand using two reference binaries + +name: Release - Extrinsic API Check with reference bins +on: + workflow_dispatch: + inputs: + reference_binary_url: + description: A url to a Linux binary for the node containing the reference runtime to test against + default: https://releases.parity.io/polkadot/x86_64-debian:stretch/v0.9.26/polkadot + required: true + binary_url: + description: A url to a Linux binary for the node containing the runtime to test + default: https://releases.parity.io/polkadot/x86_64-debian:stretch/v0.9.27-rc1/polkadot + required: true + +jobs: + check: + name: Run check + runs-on: ubuntu-latest + env: + BIN_URL: ${{github.event.inputs.binary_url}} + REF_URL: ${{github.event.inputs.reference_binary_url}} + strategy: + fail-fast: false + matrix: + chain: [polkadot, kusama, westend, rococo] + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Fetch reference binary + run: | + echo Fetching $REF_URL + curl $REF_URL -o polkadot-ref + chmod a+x polkadot-ref + ./polkadot-ref --version + + - name: Fetch test binary + run: | + echo Fetching $BIN_URL + curl $BIN_URL -o polkadot + chmod a+x polkadot + ./polkadot --version + + - name: Start local reference node + run: | + echo Running reference on ${{ matrix.chain }}-local + ./polkadot-ref --chain=${{ matrix.chain }}-local --rpc-port=9934 --ws-port=9945 --base-path=polkadot-ref-base/ & + + - name: Start local test node + run: | + echo Running test on ${{ matrix.chain }}-local + ./polkadot --chain=${{ matrix.chain }}-local & + + - name: Prepare output + run: | + REF_VERSION=$(./polkadot-ref --version) + BIN_VERSION=$(./polkadot --version) + echo "Metadata comparison:" >> output.txt + echo "Date: $(date)" >> output.txt + echo "Ref. binary: $REF_URL" >> output.txt + echo "Test binary: $BIN_URL" >> output.txt + echo "Ref. version: $REF_VERSION" >> output.txt + echo "Test version: $BIN_VERSION" >> output.txt + echo "Chain: ${{ matrix.chain }}-local" >> output.txt + echo "----------------------------------------------------------------------" >> output.txt + + - name: Pull polkadot-js-tools image + run: docker pull jacogr/polkadot-js-tools + + - name: Compare the metadata + run: | + CMD="docker run --pull always --network host jacogr/polkadot-js-tools metadata ws://localhost:9945 ws://localhost:9944" + echo -e "Running:\n$CMD" + $CMD >> output.txt + sed -z -i 's/\n\n/\n/g' output.txt + cat output.txt | egrep -n -i '' + SUMMARY=$(./scripts/ci/github/extrinsic-ordering-filter.sh output.txt) + echo -e $SUMMARY + echo -e $SUMMARY >> output.txt + + - name: Show result + run: | + cat output.txt + + - name: Save output as artifact + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.chain }} + path: | + output.txt + + - name: Stop our local nodes + run: | + pkill polkadot-ref + pkill polkadot diff --git a/polkadot/.github/workflows/release-30_publish-draft-release.yml b/polkadot/.github/workflows/release-30_publish-draft-release.yml new file mode 100644 index 0000000000000000000000000000000000000000..206b1871d80a48672ab89434f90b33b99492dd74 --- /dev/null +++ b/polkadot/.github/workflows/release-30_publish-draft-release.yml @@ -0,0 +1,199 @@ +name: Release - Publish draft + +on: + push: + tags: + # Catches v1.2.3 and v1.2.3-rc1 + - v[0-9]+.[0-9]+.[0-9]+* + +jobs: + get-rust-versions: + runs-on: ubuntu-latest + container: + image: paritytech/ci-linux:production + outputs: + rustc-stable: ${{ steps.get-rust-versions.outputs.stable }} + rustc-nightly: ${{ steps.get-rust-versions.outputs.nightly }} + steps: + - id: get-rust-versions + run: | + echo "stable=$(rustc +stable --version)" >> $GITHUB_OUTPUT + echo "nightly=$(rustc +nightly --version)" >> $GITHUB_OUTPUT + + build-runtimes: + runs-on: ubuntu-latest + strategy: + matrix: + runtime: ["polkadot", "kusama", "westend", "rococo"] + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Cache target dir + uses: actions/cache@v3 + with: + path: "${{ github.workspace }}/runtime/${{ matrix.runtime }}/target" + key: srtool-target-${{ matrix.runtime }}-${{ github.sha }} + restore-keys: | + srtool-target-${{ matrix.runtime }}- + srtool-target- + + - name: Build ${{ matrix.runtime }} runtime + id: srtool_build + uses: chevdor/srtool-actions@v0.8.0 + with: + image: paritytech/srtool + chain: ${{ matrix.runtime }} + + - name: Store srtool digest to disk + run: | + echo '${{ steps.srtool_build.outputs.json }}' | jq > ${{ matrix.runtime }}_srtool_output.json + + - name: Upload ${{ matrix.runtime }} srtool json + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.runtime }}-srtool-json + path: ${{ matrix.runtime }}_srtool_output.json + + - name: Upload ${{ matrix.runtime }} runtime + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.runtime }}-runtime + path: | + ${{ steps.srtool_build.outputs.wasm_compressed }} + + publish-draft-release: + runs-on: ubuntu-latest + needs: ["get-rust-versions", "build-runtimes"] + outputs: + release_url: ${{ steps.create-release.outputs.html_url }} + asset_upload_url: ${{ steps.create-release.outputs.upload_url }} + steps: + - name: Checkout sources + uses: actions/checkout@v3 + with: + fetch-depth: 0 + path: polkadot + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.0.0 + + - name: Download srtool json output + uses: actions/download-artifact@v3 + + - name: Prepare tooling + run: | + cd polkadot/scripts/ci/changelog + gem install bundler changelogerator:0.9.1 + bundle install + changelogerator --help + + URL=https://github.com/chevdor/tera-cli/releases/download/v0.2.1/tera-cli_linux_amd64.deb + wget $URL -O tera.deb + sudo dpkg -i tera.deb + tera --version + + - name: Generate release notes + env: + RUSTC_STABLE: ${{ needs.get-rust-versions.outputs.rustc-stable }} + RUSTC_NIGHTLY: ${{ needs.get-rust-versions.outputs.rustc-nightly }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NO_CACHE: 1 + DEBUG: 1 + ROCOCO_DIGEST: ${{ github.workspace}}/rococo-srtool-json/rococo_srtool_output.json + WESTEND_DIGEST: ${{ github.workspace}}/westend-srtool-json/westend_srtool_output.json + KUSAMA_DIGEST: ${{ github.workspace}}/kusama-srtool-json/kusama_srtool_output.json + POLKADOT_DIGEST: ${{ github.workspace}}/polkadot-srtool-json/polkadot_srtool_output.json + PRE_RELEASE: ${{ github.event.inputs.pre_release }} + run: | + find ${{env.GITHUB_WORKSPACE}} -type f -name "*_srtool_output.json" + ls -al $ROCOCO_DIGEST + ls -al $WESTEND_DIGEST + ls -al $KUSAMA_DIGEST + ls -al $POLKADOT_DIGEST + + cd polkadot/scripts/ci/changelog + + ./bin/changelog ${GITHUB_REF} + ls -al release-notes.md + ls -al context.json + + - name: Archive artifact context.json + uses: actions/upload-artifact@v3 + with: + name: release-notes-context + path: | + polkadot/scripts/ci/changelog/context.json + **/*_srtool_output.json + + - name: Create draft release + id: create-release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Polkadot ${{ github.ref }} + body_path: ./polkadot/scripts/ci/changelog/release-notes.md + draft: true + + publish-runtimes: + runs-on: ubuntu-latest + needs: ["publish-draft-release"] + env: + RUNTIME_DIR: runtime + strategy: + matrix: + runtime: ["polkadot", "kusama", "westend", "rococo"] + steps: + - name: Checkout sources + uses: actions/checkout@v3 + - name: Download artifacts + uses: actions/download-artifact@v3 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.0.0 + - name: Get runtime version + id: get-runtime-ver + run: | + echo "require './scripts/ci/github/lib.rb'" > script.rb + echo "puts get_runtime(runtime: \"${{ matrix.runtime }}\", runtime_dir: \"$RUNTIME_DIR\")" >> script.rb + + echo "Current folder: $PWD" + ls "$RUNTIME_DIR/${{ matrix.runtime }}" + runtime_ver=$(ruby script.rb) + echo "Found version: >$runtime_ver<" + echo "runtime_ver=$runtime_ver" >> $GITHUB_OUTPUT + + - name: Upload compressed ${{ matrix.runtime }} wasm + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.publish-draft-release.outputs.asset_upload_url }} + asset_path: "${{ matrix.runtime }}-runtime/${{ matrix.runtime }}_runtime.compact.compressed.wasm" + asset_name: ${{ matrix.runtime }}_runtime-v${{ steps.get-runtime-ver.outputs.runtime_ver }}.compact.compressed.wasm + asset_content_type: application/wasm + + post_to_matrix: + runs-on: ubuntu-latest + needs: publish-draft-release + strategy: + matrix: + channel: + - name: "RelEng: Polkadot Release Coordination" + room: '!cqAmzdIcbOFwrdrubV:parity.io' + + steps: + - name: Send Matrix message to ${{ matrix.channel.name }} + uses: s3krit/matrix-message-action@70ad3fb812ee0e45ff8999d6af11cafad11a6ecf # v0.0.3 + with: + room_id: ${{ matrix.channel.room }} + access_token: ${{ secrets.RELEASENOTES_MATRIX_V2_ACCESS_TOKEN }} + server: m.parity.io + message: | + **New version of polkadot tagged**: ${{ github.ref }}
+ Draft release created: ${{ needs.publish-draft-release.outputs.release_url }} diff --git a/polkadot/.github/workflows/release-40_publish-rc-image.yml b/polkadot/.github/workflows/release-40_publish-rc-image.yml new file mode 100644 index 0000000000000000000000000000000000000000..3d91c5b8c682b85d3ae937ff0b98690394b41114 --- /dev/null +++ b/polkadot/.github/workflows/release-40_publish-rc-image.yml @@ -0,0 +1,132 @@ +name: Release - Publish RC Container image +# see https://github.com/paritytech/release-engineering/issues/97#issuecomment-1651372277 + +on: + workflow_dispatch: + inputs: + release_id: + description: | + Release ID. + You can find it using the command: + curl -s \ + -H "Authorization: Bearer ${GITHUB_TOKEN}" https://api.github.com/repos/$OWNER/$REPO/releases | \ + jq '.[] | { name: .name, id: .id }' + required: true + type: string + registry: + description: "Container registry" + required: true + type: string + default: docker.io + owner: + description: Owner of the container image repo + required: true + type: string + default: parity + +env: + RELEASE_ID: ${{ inputs.release_id }} + ENGINE: docker + REGISTRY: ${{ inputs.registry }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCKER_OWNER: ${{ inputs.owner || github.repository_owner }} + REPO: ${{ github.repository }} + +jobs: + fetch-artifacts: + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Fetch all artifacts + run: | + . ./scripts/ci/common/lib.sh + fetch_release_artifacts + + - name: Cache the artifacts + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + with: + key: artifacts-${{ github.sha }} + path: | + ./release-artifacts/**/* + + build-container: + runs-on: ubuntu-latest + needs: fetch-artifacts + + strategy: + matrix: + binary: ["polkadot", "staking-miner"] + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Get artifacts from cache + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + with: + key: artifacts-${{ github.sha }} + fail-on-cache-miss: true + path: | + ./release-artifacts/**/* + + - name: Check sha256 ${{ matrix.binary }} + working-directory: ./release-artifacts + run: | + . ../scripts/ci/common/lib.sh + + echo "Checking binary ${{ matrix.binary }}" + check_sha256 ${{ matrix.binary }} && echo "OK" || echo "ERR" + + - name: Check GPG ${{ matrix.binary }} + working-directory: ./release-artifacts + run: | + . ../scripts/ci/common/lib.sh + import_gpg_keys + check_gpg ${{ matrix.binary }} + + - name: Fetch commit and tag + id: fetch_refs + run: | + release=release-${{ inputs.release_id }} && \ + echo "release=${release}" >> $GITHUB_OUTPUT + + commit=$(git rev-parse --short HEAD) && \ + echo "commit=${commit}" >> $GITHUB_OUTPUT + + tag=$(git name-rev --tags --name-only $(git rev-parse HEAD)) && \ + [ "${tag}" != "undefined" ] && echo "tag=${tag}" >> $GITHUB_OUTPUT || \ + echo "No tag, doing without" + + - name: Build Injected Container image for ${{ matrix.binary }} + env: + BIN_FOLDER: ./release-artifacts + BINARY: ${{ matrix.binary }} + TAGS: ${{join(steps.fetch_refs.outputs.*, ',')}} + run: | + echo "Building container for ${{ matrix.binary }}" + ./scripts/ci/dockerfiles/build-injected.sh + + - name: Login to Dockerhub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Push Container image for ${{ matrix.binary }} + id: docker_push + env: + BINARY: ${{ matrix.binary }} + run: | + $ENGINE images | grep ${BINARY} + $ENGINE push --all-tags ${REGISTRY}/${DOCKER_OWNER}/${BINARY} + + - name: Check version for the published image for ${{ matrix.binary }} + env: + BINARY: ${{ matrix.binary }} + RELEASE_TAG: ${{ steps.fetch_refs.outputs.release }} + run: | + echo "Checking tag ${RELEASE_TAG} for image ${REGISTRY}/${DOCKER_OWNER}/${BINARY}" + $ENGINE run -i ${REGISTRY}/${DOCKER_OWNER}/${BINARY}:${RELEASE_TAG} --version diff --git a/polkadot/.github/workflows/release-50_publish-docker-release.yml b/polkadot/.github/workflows/release-50_publish-docker-release.yml new file mode 100644 index 0000000000000000000000000000000000000000..81e5caa718f3e251f8eeded4210d2d4448ecb036 --- /dev/null +++ b/polkadot/.github/workflows/release-50_publish-docker-release.yml @@ -0,0 +1,44 @@ +name: Release - Publish Docker image for new releases + +on: + release: + types: + - published + +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@95cb08cb2672c73d4ffd2f422e6d11953d2a9c70 # v2.1.0 + - name: Cache Docker layers + uses: actions/cache@v3 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + - name: Login to Dockerhub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push + id: docker_build + uses: docker/build-push-action@v4 + with: + push: true + file: scripts/ci/dockerfiles/polkadot/polkadot_injected_debian.Dockerfile + tags: | + parity/polkadot:latest + parity/polkadot:${{ github.event.release.tag_name }} + build-args: | + POLKADOT_VERSION=${{ github.event.release.tag_name }} + VCS_REF=${{ github.ref }} + BUILD_DATE=${{ github.event.release.published_at }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache + - name: Image digest + run: echo ${{ steps.docker_build.outputs.digest }} diff --git a/polkadot/.github/workflows/release-51_publish-docker-manual.yml b/polkadot/.github/workflows/release-51_publish-docker-manual.yml new file mode 100644 index 0000000000000000000000000000000000000000..919769f8700d1ac70f0d831a5f6645aff86f42f2 --- /dev/null +++ b/polkadot/.github/workflows/release-51_publish-docker-manual.yml @@ -0,0 +1,51 @@ +name: Release - Publish Docker image (manual dispatch) + +on: + workflow_dispatch: + inputs: + version: + description: version to build/release + default: v0.9.18 + required: true + date: + description: release date of version + default: "2022-02-23T19:11:58Z" + required: true + +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@95cb08cb2672c73d4ffd2f422e6d11953d2a9c70 # v2.1.0 + - name: Cache Docker layers + uses: actions/cache@v3 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + - name: Login to Dockerhub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push + id: docker_build + uses: docker/build-push-action@v4 + with: + push: true + file: scripts/ci/dockerfiles/polkadot/polkadot_injected_debian.Dockerfile + tags: | + parity/polkadot:latest + parity/polkadot:${{ github.event.inputs.version }} + build-args: | + POLKADOT_VERSION=${{ github.event.inputs.version }} + VCS_REF=${{ github.ref }} + BUILD_DATE=${{ github.event.inputs.date }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache + - name: Image digest + run: echo ${{ steps.docker_build.outputs.digest }} diff --git a/polkadot/.github/workflows/release-99_bot.yml b/polkadot/.github/workflows/release-99_bot.yml new file mode 100644 index 0000000000000000000000000000000000000000..5d45c0d44eda3d43e77ce6cc2272b79cc35f5c7e --- /dev/null +++ b/polkadot/.github/workflows/release-99_bot.yml @@ -0,0 +1,49 @@ +name: Release - Send new release notification to matrix channels +on: + release: + types: + - published + +jobs: + ping_matrix: + strategy: + matrix: + channel: + - name: '#KusamaValidatorLounge:polkadot.builders' + room: '!LhjZccBOqFNYKLdmbb:polkadot.builders' + pre-releases: false + - name: '#kusama-announcements:matrix.parity.io' + room: '!FMwxpQnYhRCNDRsYGI:matrix.parity.io' + pre-release: false + - name: '#polkadotvalidatorlounge:web3.foundation' + room: '!NZrbtteFeqYKCUGQtr:matrix.parity.io' + pre-release: false + - name: '#polkadot-announcements:matrix.parity.io' + room: '!UqHPWiCBGZWxrmYBkF:matrix.parity.io' + pre-release: false + - name: "RelEng: Polkadot Release Coordination" + room: '!cqAmzdIcbOFwrdrubV:parity.io' + pre-release: true + - name: 'Ledger <> Polkadot Coordination' + room: '!EoIhaKfGPmFOBrNSHT:web3.foundation' + pre-release: true + - name: 'General: Rust, Polkadot, Substrate' + room: '!aJymqQYtCjjqImFLSb:parity.io' + pre-release: false + - name: 'Team: DevOps' + room: '!lUslSijLMgNcEKcAiE:parity.io' + pre-release: true + + runs-on: ubuntu-latest + steps: + - name: Send Matrix message to ${{ matrix.channel.name }} + if: github.event.release.prerelease == false || matrix.channel.pre-release + uses: s3krit/matrix-message-action@70ad3fb812ee0e45ff8999d6af11cafad11a6ecf # v0.0.3 + with: + room_id: ${{ matrix.channel.room }} + access_token: ${{ secrets.RELEASENOTES_MATRIX_V2_ACCESS_TOKEN }} + server: m.parity.io + message: | + ***Polkadot ${{github.event.release.tag_name}} has been released!***
+ ${{github.event.release.html_url}}

+ ${{github.event.release.body}}
diff --git a/polkadot/.gitignore b/polkadot/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..61ef9e91a55e7007926b35e3cba2aea95788830b --- /dev/null +++ b/polkadot/.gitignore @@ -0,0 +1,16 @@ +**/target/ +**/*.rs.bk +*.swp +.wasm-binaries +runtime/wasm/target/ +**/._* +.idea +.vscode +polkadot.* +!polkadot.service +.DS_Store +.env + +artifacts +release-artifacts +release.json diff --git a/polkadot/.gitlab-ci.yml b/polkadot/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..b2d91e61da94a53a791cd1085357eb986ef67c12 --- /dev/null +++ b/polkadot/.gitlab-ci.yml @@ -0,0 +1,287 @@ +# .gitlab-ci.yml +# +# polkadot +# +# Pipelines can be triggered manually in the web. +# +# Please do not add new jobs without "rules:" and "*-env". There are &test-refs for everything, +# "docker-env" is used for Rust jobs. +# And "kubernetes-env" for everything else. Please mention "image:" container name to be used +# with it, as there's no default one. + +# All jobs are sorted according to their duration using DAG mechanism +# Currently, test-linux-stable job is the longest one and other jobs are +# sorted in order to complete during this job and occupy less runners in one +# moment of time. + +stages: + - .pre + - weights + - check + - test + - build + - publish + - zombienet + - short-benchmarks + +workflow: + rules: + - if: $CI_COMMIT_TAG + - if: $CI_COMMIT_BRANCH + +variables: + GIT_STRATEGY: fetch + GIT_DEPTH: 100 + CI_SERVER_NAME: "GitLab CI" + CI_IMAGE: !reference [.ci-unified, variables, CI_IMAGE] + BUILDAH_IMAGE: "quay.io/buildah/stable:v1.29" + BUILDAH_COMMAND: "buildah --storage-driver overlay2" + DOCKER_OS: "debian:stretch" + ARCH: "x86_64" + ZOMBIENET_IMAGE: "docker.io/paritytech/zombienet:v1.3.65" + +default: + cache: {} + retry: + max: 2 + when: + - runner_system_failure + - unknown_failure + - api_failure + interruptible: true + +.common-before-script: + before_script: + - !reference [.job-switcher, before_script] + - !reference [.timestamp, before_script] + +.collect-artifacts: + artifacts: + name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}" + when: on_success + expire_in: 7 days + paths: + - ./artifacts/ + +.collect-artifacts-short: + artifacts: + name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}" + when: on_success + expire_in: 1 days + paths: + - ./artifacts/ + +# collecting vars for pipeline stopper +# they will be used if the job fails +.pipeline-stopper-vars: + before_script: + - echo "FAILED_JOB_URL=${CI_JOB_URL}" > pipeline-stopper.env + - echo "FAILED_JOB_NAME=${CI_JOB_NAME}" >> pipeline-stopper.env + - echo "FAILED_JOB_NAME=${CI_JOB_NAME}" >> pipeline-stopper.env + - echo "PR_NUM=${CI_COMMIT_REF_NAME}" >> pipeline-stopper.env + +.pipeline-stopper-artifacts: + artifacts: + reports: + dotenv: pipeline-stopper.env + +.job-switcher: + before_script: + - if echo "$CI_DISABLED_JOBS" | grep -xF "$CI_JOB_NAME"; then echo "The job has been cancelled in CI settings"; exit 0; fi + +.kubernetes-env: + image: "${CI_IMAGE}" + before_script: + - !reference [.common-before-script, before_script] + tags: + - kubernetes-parity-build + +.docker-env: + image: "${CI_IMAGE}" + before_script: + - !reference [.common-before-script, before_script] + tags: + - linux-docker-vm-c2 + +.compiler-info: + before_script: + - !reference [.common-before-script, before_script] + - rustup show + - cargo --version + +.test-refs: + rules: + - if: $CI_PIPELINE_SOURCE == "web" + - if: $CI_PIPELINE_SOURCE == "schedule" + - if: $CI_COMMIT_REF_NAME == "master" + - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs + +.common-refs: + # these jobs run always* + rules: + - if: $CI_PIPELINE_SOURCE == "web" + - if: $CI_PIPELINE_SOURCE == "schedule" + - if: $CI_COMMIT_REF_NAME == "master" + - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs + - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + - if: $CI_COMMIT_REF_NAME =~ /^release-v[0-9]+\.[0-9]+.*$/ # i.e. release-v0.9.27 + +.test-pr-refs: + rules: + - if: $CI_PIPELINE_SOURCE == "pipeline" + when: never + - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs + +.zombienet-refs: + rules: + - if: $CI_PIPELINE_SOURCE == "pipeline" + when: never + - if: $CI_PIPELINE_SOURCE == "schedule" + when: never + - if: $CI_COMMIT_REF_NAME == "master" + - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs + +.deploy-testnet-refs: + rules: + - if: $CI_PIPELINE_SOURCE == "pipeline" + when: never + - if: $CI_PIPELINE_SOURCE == "schedule" + - if: $CI_COMMIT_REF_NAME == "master" + +.publish-refs: + rules: + - if: $CI_PIPELINE_SOURCE == "pipeline" + when: never + - if: $CI_PIPELINE_SOURCE == "schedule" + - if: $CI_PIPELINE_SOURCE == "web" && + $CI_COMMIT_REF_NAME == "master" + - if: $CI_COMMIT_REF_NAME == "master" + - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + +.build-push-image: + variables: + CI_IMAGE: "${BUILDAH_IMAGE}" + + REGISTRY: "docker.io" + DOCKER_OWNER: "paritypr" + DOCKER_USER: "${PARITYPR_USER}" + DOCKER_PASS: "${PARITYPR_PASS}" + IMAGE: "${REGISTRY}/${DOCKER_OWNER}/${IMAGE_NAME}" + + ENGINE: "${BUILDAH_COMMAND}" + BUILDAH_FORMAT: "docker" + SKIP_IMAGE_VALIDATION: 1 + + PROJECT_ROOT: "." + BIN_FOLDER: "./artifacts" + VCS_REF: "${CI_COMMIT_SHA}" + + before_script: + - !reference [.common-before-script, before_script] + - test -s ./artifacts/VERSION || exit 1 + - test -s ./artifacts/EXTRATAG || exit 1 + - export VERSION="$(cat ./artifacts/VERSION)" + - EXTRATAG="$(cat ./artifacts/EXTRATAG)" + - echo "Polkadot version = ${VERSION} (EXTRATAG = ${EXTRATAG})" + script: + - test "$DOCKER_USER" -a "$DOCKER_PASS" || + ( echo "no docker credentials provided"; exit 1 ) + - TAGS="${VERSION},${EXTRATAG}" scripts/ci/dockerfiles/build-injected.sh + - echo "$DOCKER_PASS" | + buildah login --username "$DOCKER_USER" --password-stdin "${REGISTRY}" + - $BUILDAH_COMMAND info + - $BUILDAH_COMMAND push --format=v2s2 "$IMAGE:$VERSION" + - $BUILDAH_COMMAND push --format=v2s2 "$IMAGE:$EXTRATAG" + after_script: + - buildah logout --all + +#### stage: .pre + +# By default our pipelines are interruptible, but some special pipelines shouldn't be interrupted: +# * multi-project pipelines such as the ones triggered by the scripts repo +# +# In those cases, we add an uninterruptible .pre job; once that one has started, +# the entire pipeline becomes uninterruptible. +uninterruptible-pipeline: + extends: .kubernetes-env + variables: + CI_IMAGE: "paritytech/tools:latest" + stage: .pre + interruptible: false + rules: + - if: $CI_PIPELINE_SOURCE == "pipeline" + script: "true" + +include: + # weights jobs + - scripts/ci/gitlab/pipeline/weights.yml + # check jobs + - scripts/ci/gitlab/pipeline/check.yml + # test jobs + - scripts/ci/gitlab/pipeline/test.yml + # build jobs + - scripts/ci/gitlab/pipeline/build.yml + # short-benchmarks jobs + - scripts/ci/gitlab/pipeline/short-benchmarks.yml + # publish jobs + - scripts/ci/gitlab/pipeline/publish.yml + # zombienet jobs + - scripts/ci/gitlab/pipeline/zombienet.yml + # timestamp handler + - project: parity/infrastructure/ci_cd/shared + ref: main + file: /common/timestamp.yml + - project: parity/infrastructure/ci_cd/shared + ref: main + file: /common/ci-unified.yml + + +#### stage: .post + +deploy-parity-testnet: + stage: .post + extends: + - .deploy-testnet-refs + variables: + POLKADOT_CI_COMMIT_NAME: "${CI_COMMIT_REF_NAME}" + POLKADOT_CI_COMMIT_REF: "${CI_COMMIT_SHORT_SHA}" + allow_failure: false + trigger: "parity/infrastructure/parity-testnet" + +# This job cancels the whole pipeline if any of provided jobs fail. +# In a DAG, every jobs chain is executed independently of others. The `fail_fast` principle suggests +# to fail the pipeline as soon as possible to shorten the feedback loop. +.cancel-pipeline-template: + stage: .post + rules: + - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs + when: on_failure + variables: + PROJECT_ID: "${CI_PROJECT_ID}" + PROJECT_NAME: "${CI_PROJECT_NAME}" + PIPELINE_ID: "${CI_PIPELINE_ID}" + FAILED_JOB_URL: "${FAILED_JOB_URL}" + FAILED_JOB_NAME: "${FAILED_JOB_NAME}" + PR_NUM: "${PR_NUM}" + trigger: + project: "parity/infrastructure/ci_cd/pipeline-stopper" + branch: "as-improve" + +remove-cancel-pipeline-message: + stage: .post + rules: + - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs + variables: + PROJECT_ID: "${CI_PROJECT_ID}" + PROJECT_NAME: "${CI_PROJECT_NAME}" + PIPELINE_ID: "${CI_PIPELINE_ID}" + FAILED_JOB_URL: "https://gitlab.com" + FAILED_JOB_NAME: "nope" + PR_NUM: "${CI_COMMIT_REF_NAME}" + trigger: + project: "parity/infrastructure/ci_cd/pipeline-stopper" + +cancel-pipeline-test-linux-stable: + extends: .cancel-pipeline-template + needs: + - job: test-linux-stable diff --git a/polkadot/.rpm/polkadot.spec b/polkadot/.rpm/polkadot.spec new file mode 100644 index 0000000000000000000000000000000000000000..06fa0f57504d81aa4c2a914d348efe2126fbbfb6 --- /dev/null +++ b/polkadot/.rpm/polkadot.spec @@ -0,0 +1,48 @@ +%define debug_package %{nil} + +Name: polkadot +Summary: Implementation of a https://polkadot.network node in Rust based on the Substrate framework. +Version: @@VERSION@@ +Release: @@RELEASE@@%{?dist} +License: GPLv3 +Group: Applications/System +Source0: %{name}-%{version}.tar.gz + +Requires: systemd, shadow-utils +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + +%description +%{summary} + + +%prep +%setup -q + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot} +cp -a * %{buildroot} + +%post +config_file="/etc/default/polkadot" +getent group polkadot >/dev/null || groupadd -r polkadot +getent passwd polkadot >/dev/null || \ + useradd -r -g polkadot -d /home/polkadot -m -s /sbin/nologin \ + -c "User account for running polkadot as a service" polkadot +if [ ! -e "$config_file" ]; then + echo 'POLKADOT_CLI_ARGS=""' > /etc/default/polkadot +fi +exit 0 + +%clean +rm -rf %{buildroot} + +%files +%defattr(-,root,root,-) +%{_bindir}/* +/usr/lib/systemd/system/polkadot.service diff --git a/polkadot/CODE_OF_CONDUCT.md b/polkadot/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000000000000000000000000000000000..400c9b3901e26a7e5a1840816897ed31927156f5 --- /dev/null +++ b/polkadot/CODE_OF_CONDUCT.md @@ -0,0 +1,52 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +### Facilitation, Not Strongarming + +We recognise that this software is merely a tool for users to create and maintain their blockchain of preference. We see that blockchains are naturally community platforms with users being the ultimate decision makers. We assert that good software will maximise user agency by facilitate user-expression on the network. As such: + +* This project will strive to give users as much choice as is both reasonable and possible over what protocol they adhere to; but +* use of the project's technical forums, commenting systems, pull requests and issue trackers as a means to express individual protocol preferences is forbidden. + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at . The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://contributor-covenant.org/version/1/4 + +[homepage]: https://contributor-covenant.org diff --git a/polkadot/CONTRIBUTING.md b/polkadot/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..d82b80bd8d2ecb303595cd3df14df2817b4cbc86 --- /dev/null +++ b/polkadot/CONTRIBUTING.md @@ -0,0 +1,46 @@ +# Contributing + +## Rules + +There are a few basic ground-rules for contributors (including the maintainer(s) of the project): + +- **No `--force` pushes** or modifying the Git history in any way. If you need to rebase, ensure you do it in your own repo. +- **Non-master branches**, prefixed with a short name moniker (e.g. `gav-my-feature`) must be used for ongoing work. +- **All modifications** must be made in a **pull-request** to solicit feedback from other contributors. +- A pull-request _must not be merged until CI_ has finished successfully. +- Contributors should adhere to the [house coding style](https://github.com/paritytech/substrate/blob/master/docs/STYLE_GUIDE.md). + +### Merging pull requests once CI is successful + +- A pull request that does not alter any logic (e.g. comments, dependencies, docs) may be tagged [`insubstantial`](https://github.com/paritytech/polkadot/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+label%3AA2-insubstantial) and merged by its author. +- A pull request with no large change to logic that is an urgent fix may be merged after a non-author contributor has reviewed it well. +- All other PRs should sit for 48 hours with the [`pleasereview`](https://github.com/paritytech/polkadot/pulls?q=is:pr+is:open+label:A0-pleasereview) tag in order to garner feedback. +- No PR should be merged until all reviews' comments are addressed. + +### Reviewing pull requests + +When reviewing a pull request, the end-goal is to suggest useful changes to the author. Reviews should finish with approval unless there are issues that would result in: + +- Buggy behavior. +- Undue maintenance burden. +- Breaking with house coding style. +- Pessimization (i.e. reduction of speed as measured in the projects benchmarks). +- Feature reduction (i.e. it removes some aspect of functionality that a significant minority of users rely on). +- Uselessness (i.e. it does not strictly add a feature or fix a known issue). + +### Reviews may not be used as an effective veto for a PR because + +- 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. + +## Releases + +Declaring formal releases remains the prerogative of the project maintainer(s). + +## Changes to this arrangement + +This is an experiment and feedback is welcome! This document may also be subject to pull-requests or changes by contributors where you believe you have something valuable to add or change. + +## Heritage + +These contributing guidelines are modified from the "OPEN Open Source Project" guidelines for the Level project: diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock new file mode 100644 index 0000000000000000000000000000000000000000..3271f6671401fb9c2e2ef1f40a69cdf8553c70b1 --- /dev/null +++ b/polkadot/Cargo.lock @@ -0,0 +1,15397 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli", +] + +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "aead" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", +] + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array 0.14.7", +] + +[[package]] +name = "aes" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" +dependencies = [ + "aes-soft", + "aesni", + "cipher 0.2.5", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "opaque-debug 0.3.0", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" +dependencies = [ + "aead 0.4.3", + "aes 0.7.5", + "cipher 0.3.0", + "ctr 0.8.0", + "ghash 0.4.4", + "subtle", +] + +[[package]] +name = "aes-gcm" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" +dependencies = [ + "aead 0.5.2", + "aes 0.8.3", + "cipher 0.4.4", + "ctr 0.9.2", + "ghash 0.5.0", + "subtle", +] + +[[package]] +name = "aes-soft" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" +dependencies = [ + "cipher 0.2.5", + "opaque-debug 0.3.0", +] + +[[package]] +name = "aesni" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" +dependencies = [ + "cipher 0.2.5", + "opaque-debug 0.3.0", +] + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.10", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "getrandom 0.2.10", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "always-assert" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4436e0292ab1bb631b42973c61205e704475fe8126af845c8d923c0996328127" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" + +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "aquamarine" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df752953c49ce90719c7bf1fc587bc8227aed04732ea0c0f85e5397d7fdbd1a1" +dependencies = [ + "include_dir", + "itertools", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "arbitrary" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e" + +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ed-on-bls12-381-bandersnatch" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9cde0f2aa063a2a5c28d39b47761aa102bda7c13c84fc118a61b87c7b2f785c" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-secret-scalar" +version = "0.0.2" +source = "git+https://github.com/w3f/ring-vrf?rev=c86ebd4#c86ebd4114d3165d05f9ce28c1d9e8d7a9a4e801" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", + "ark-transcript", + "digest 0.10.7", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-transcript" +version = "0.0.2" +source = "git+https://github.com/w3f/ring-vrf?rev=c86ebd4#c86ebd4114d3165d05f9ce28c1d9e8d7a9a4e801" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "digest 0.10.7", + "rand_core 0.6.4", + "sha3", +] + +[[package]] +name = "array-bytes" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b1c5a481ec30a5abd8dfbd94ab5cf1bb4e9a66be7f1b3b322f2f1170c200fd" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "asn1-rs" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ff05a702273012438132f449575dbc804e27b2f3cbe3069aa237d26c98fa33" +dependencies = [ + "asn1-rs-derive 0.1.0", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time 0.3.25", +] + +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +dependencies = [ + "asn1-rs-derive 0.4.0", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time 0.3.25", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8b7511298d5b7784b40b092d9e9dcd3a627a5707e4b5e507931ab0d44eeebf" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "assert_cmd" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88903cb14723e4d4003335bb7f8a14f27691649105346a0f0957466c096adfe6" +dependencies = [ + "anstyle", + "bstr", + "doc-comment", + "predicates 3.0.3", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite", + "log", + "parking", + "polling", + "rustix 0.37.23", + "slab", + "socket2 0.4.9", + "waker-fn", +] + +[[package]] +name = "async-lock" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-recursion" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "async-trait" +version = "0.1.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "asynchronous-codec" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" +dependencies = [ + "bytes", + "futures-sink", + "futures-util", + "memchr", + "pin-project-lite 0.2.10", +] + +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line 0.20.0", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object 0.31.1", + "rustc-demangle", +] + +[[package]] +name = "bandersnatch_vrfs" +version = "0.0.1" +source = "git+https://github.com/w3f/ring-vrf?rev=c86ebd4#c86ebd4114d3165d05f9ce28c1d9e8d7a9a4e801" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ed-on-bls12-381-bandersnatch", + "ark-ff", + "ark-serialize", + "ark-std", + "dleq_vrf", + "fflonk", + "merlin 3.0.0", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "ring 0.1.0", + "sha2 0.10.7", + "zeroize", +] + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "basic-toml" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bfc506e7a2370ec239e1d072507b2a80c833083699d3c6fa176fbb4de8448c6" +dependencies = [ + "serde", +] + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +dependencies = [ + "serde", +] + +[[package]] +name = "binary-merkle-tree" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "hash-db", + "log", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.65.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "prettyplease 0.2.12", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.28", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" +dependencies = [ + "arrayref", + "arrayvec 0.7.4", + "constant_time_eq 0.2.6", +] + +[[package]] +name = "blake2s_simd" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" +dependencies = [ + "arrayref", + "arrayvec 0.7.4", + "constant_time_eq 0.2.6", +] + +[[package]] +name = "blake3" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" +dependencies = [ + "arrayref", + "arrayvec 0.7.4", + "cc", + "cfg-if", + "constant_time_eq 0.3.0", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding 0.1.5", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "block-modes" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" +dependencies = [ + "block-padding 0.2.1", + "cipher 0.2.5", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "bounded-collections" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b05133427c07c4776906f673ccf36c21b102c9829c641a5b56bd151d44fd6" +dependencies = [ + "log", + "parity-scale-codec", + "scale-info", + "serde", +] + +[[package]] +name = "bounded-vec" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68534a48cbf63a4b1323c433cf21238c9ec23711e0df13b08c33e5c2082663ce" +dependencies = [ + "thiserror", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bstr" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +dependencies = [ + "memchr", + "regex-automata 0.3.4", + "serde", +] + +[[package]] +name = "build-helper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdce191bf3fa4995ce948c8c83b4640a1745457a149e73c6db75b4ffe36aad5f" +dependencies = [ + "semver 0.6.0", +] + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.18", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c6b2562119bf28c3439f7f02db99faf0aa1a8cdfe5772a2ee155d32227239f0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "ccm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aca1a8fbc20b50ac9673ff014abfb2b5f4085ee1a850d408f14a159c5853ac7" +dependencies = [ + "aead 0.3.2", + "cipher 0.2.5", + "subtle", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-expr" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b40ccee03b5175c18cde8f37e7d2a33bcef6f8ec8f7cc0d81090d1bb380949c9" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "chacha20" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "zeroize", +] + +[[package]] +name = "chacha20poly1305" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" +dependencies = [ + "aead 0.4.3", + "chacha20", + "cipher 0.3.0", + "poly1305", + "zeroize", +] + +[[package]] +name = "chrono" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "time 0.1.45", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "ciborium" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" + +[[package]] +name = "ciborium-ll" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "cid" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9b68e3193982cd54187d71afdb2a271ad4cf8af157858e9cb911b91321de143" +dependencies = [ + "core2", + "multibase", + "multihash", + "serde", + "unsigned-varint", +] + +[[package]] +name = "cipher" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "ckb-merkle-mountain-range" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ccb671c5921be8a84686e6212ca184cb1d7c51cadcdbfcbd1cc3f042f5dfb8" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_derive 3.2.25", + "clap_lex 0.2.4", + "indexmap 1.9.3", + "once_cell", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap" +version = "4.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +dependencies = [ + "clap_builder", + "clap_derive 4.3.12", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +dependencies = [ + "anstream", + "anstyle", + "clap_lex 0.5.0", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "clap_derive" +version = "4.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "clap_lex" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" + +[[package]] +name = "coarsetime" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a90d114103adbc625300f346d4d09dfb4ab1c4a8df6868435dd903392ecf4354" +dependencies = [ + "libc", + "once_cell", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "color-eyre" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" +dependencies = [ + "backtrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "comfy-table" +version = "7.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ab77dbd8adecaf3f0db40581631b995f312a8a5ae3aa9993188bb8f23d83a5b" +dependencies = [ + "strum", + "strum_macros", + "unicode-width", +] + +[[package]] +name = "common" +version = "0.1.0" +source = "git+https://github.com/w3f/ring-proof#0e948f3c28cbacecdd3020403c4841c0eb339213" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "fflonk", + "merlin 3.0.0", +] + +[[package]] +name = "common-path" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101" + +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.45.0", +] + +[[package]] +name = "const-oid" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" + +[[package]] +name = "const-random" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e" +dependencies = [ + "const-random-macro", + "proc-macro-hack", +] + +[[package]] +name = "const-random-macro" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb" +dependencies = [ + "getrandom 0.2.10", + "once_cell", + "proc-macro-hack", + "tiny-keccak", +] + +[[package]] +name = "constant_time_eq" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" + +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpp_demangle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeaa953eaad386a53111e47172c2fedba671e5684c8dd601a5f474f4f118710f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cpp_demangle" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee34052ee3d93d6d8f3e6f81d85c47921f6653a19a7b70e939e3e602d893a674" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cpu-time" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e393a7668fe1fad3075085b86c781883000b4ede868f43627b34a87c8b7ded" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "cranelift-bforest" +version = "0.95.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1277fbfa94bc82c8ec4af2ded3e639d49ca5f7f3c7eeab2c66accd135ece4e70" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.95.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e8c31ad3b2270e9aeec38723888fe1b0ace3bea2b06b3f749ccf46661d3220" +dependencies = [ + "bumpalo", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-entity", + "cranelift-isle", + "gimli", + "hashbrown 0.13.2", + "log", + "regalloc2", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.95.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ac5ac30d62b2d66f12651f6b606dbdfd9c2cfd0908de6b387560a277c5c9da" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.95.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd82b8b376247834b59ed9bdc0ddeb50f517452827d4a11bccf5937b213748b8" + +[[package]] +name = "cranelift-entity" +version = "0.95.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40099d38061b37e505e63f89bab52199037a72b931ad4868d9089ff7268660b0" +dependencies = [ + "serde", +] + +[[package]] +name = "cranelift-frontend" +version = "0.95.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a25d9d0a0ae3079c463c34115ec59507b4707175454f0eee0891e83e30e82d" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.95.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80de6a7d0486e4acbd5f9f87ec49912bf4c8fb6aea00087b989685460d4469ba" + +[[package]] +name = "cranelift-native" +version = "0.95.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6b03e0e03801c4b3fd8ce0758a94750c07a44e7944cc0ffbf0d3f2e7c79b00" +dependencies = [ + "cranelift-codegen", + "libc", + "target-lexicon", +] + +[[package]] +name = "cranelift-wasm" +version = "0.95.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff3220489a3d928ad91e59dd7aeaa8b3de18afb554a6211213673a71c90737ac" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "itertools", + "log", + "smallvec", + "wasmparser", + "wasmtime-types", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "criterion" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" +dependencies = [ + "anes", + "atty", + "cast", + "ciborium", + "clap 3.2.25", + "criterion-plot", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.9.0", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array 0.14.7", + "subtle", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array 0.14.7", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher 0.3.0", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher 0.4.4", +] + +[[package]] +name = "curve25519-dalek" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" +dependencies = [ + "byteorder", + "digest 0.8.1", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "cxx" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f68e12e817cb19eaab81aaec582b4052d07debd3c3c6b083b9d361db47c7dc9d" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e789217e4ab7cf8cc9ce82253180a9fe331f35f5d339f0ccfe0270b39433f397" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 2.0.28", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78a19f4c80fd9ab6c882286fa865e92e07688f4387370a209508014ead8751d0" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fcfa71f66c8563c4fa9dd2bb68368d50267856f831ac5d85367e0805f9606c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "dashmap" +version = "5.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d" +dependencies = [ + "cfg-if", + "hashbrown 0.14.0", + "lock_api", + "once_cell", + "parking_lot_core 0.9.8", +] + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "data-encoding-macro" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +dependencies = [ + "data-encoding", + "syn 1.0.109", +] + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "uuid", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" +dependencies = [ + "asn1-rs 0.3.1", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der-parser" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +dependencies = [ + "asn1-rs 0.5.2", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive-syn-parse" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79116f119dd1dba1abf1f3405f03b9b0e79a27a3883864bfebded8a3dc768cd" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07adf7be193b71cc36b193d0f5fe60b918a3a9db4dad0449f57bcfd519704a3" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0314b72bed045f3a68671b3c86328386762c93f82d98c65c3cb5e5f573dd68" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "directories-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "dissimilar" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" + +[[package]] +name = "dleq_vrf" +version = "0.0.2" +source = "git+https://github.com/w3f/ring-vrf?rev=c86ebd4#c86ebd4114d3165d05f9ce28c1d9e8d7a9a4e801" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-secret-scalar", + "ark-serialize", + "ark-std", + "ark-transcript", + "arrayvec 0.7.4", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "dlmalloc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "203540e710bfadb90e5e29930baf5d10270cec1f43ab34f46f78b147b2de715a" +dependencies = [ + "libc", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "docify" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029de870d175d11969524d91a3fb2cbf6d488b853bff99d41cf65e533ac7d9d2" +dependencies = [ + "docify_macros", +] + +[[package]] +name = "docify_macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cac43324656a1b05eb0186deb51f27d2d891c704c37f34de281ef6297ba193e5" +dependencies = [ + "common-path", + "derive-syn-parse", + "once_cell", + "proc-macro2", + "quote", + "regex", + "syn 2.0.28", + "termcolor", + "toml 0.7.6", + "walkdir", +] + +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dyn-clonable" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" +dependencies = [ + "dyn-clonable-impl", + "dyn-clone", +] + +[[package]] +name = "dyn-clonable-impl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "dyn-clone" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der 0.7.7", + "digest 0.10.7", + "elliptic-curve 0.13.5", + "rfc6979 0.4.0", + "signature 2.1.0", + "spki 0.7.2", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature 1.6.4", +] + +[[package]] +name = "ed25519" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" +dependencies = [ + "pkcs8 0.10.2", + "signature 2.1.0", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519 1.5.3", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +dependencies = [ + "curve25519-dalek 4.0.0", + "ed25519 2.2.2", + "serde", + "sha2 0.10.7", + "zeroize", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek 3.2.0", + "hashbrown 0.12.3", + "hex", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array 0.14.7", + "group 0.12.1", + "hkdf", + "pem-rfc7468", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.2", + "digest 0.10.7", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-as-inner" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "enumflags2" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2" +dependencies = [ + "enumflags2_derive", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "enumn" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b893c4eb2dc092c811165f84dc7447fae16fb66521717968c34c509b39b1a5c5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "environmental" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48c92028aaa870e83d51c64e5d4e0b6981b360c522198c23959f219a4e1b15b" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "erased-serde" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da96524cc884f6558f1769b6c46686af2fe8e8b4cd253bd5a3cdba8181b8e070" +dependencies = [ + "serde", +] + +[[package]] +name = "erasure_coding_fuzzer" +version = "0.9.43" +dependencies = [ + "honggfuzz", + "polkadot-erasure-coding", + "polkadot-node-primitives", + "polkadot-primitives", +] + +[[package]] +name = "errno" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "exit-future" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" +dependencies = [ + "futures", +] + +[[package]] +name = "exitcode" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193" + +[[package]] +name = "expander" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a718c0675c555c5f976fff4ea9e2c150fa06cefa201cadef87cfbf9324075881" +dependencies = [ + "blake3", + "fs-err", + "proc-macro2", + "quote", +] + +[[package]] +name = "expander" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3774182a5df13c3d1690311ad32fbe913feef26baba609fa2dd5f72042bd2ab6" +dependencies = [ + "blake2", + "fs-err", + "proc-macro2", + "quote", +] + +[[package]] +name = "expander" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f86a749cf851891866c10515ef6c299b5c69661465e9c3bbe7e07a2b77fb0f7" +dependencies = [ + "blake2", + "fs-err", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + +[[package]] +name = "fatality" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad875162843b0d046276327afe0136e9ed3a23d5a754210fb6f1f33610d39ab" +dependencies = [ + "fatality-proc-macro", + "thiserror", +] + +[[package]] +name = "fatality-proc-macro" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5aa1e3ae159e592ad222dc90c5acbad632b527779ba88486abe92782ab268bd" +dependencies = [ + "expander 0.0.4", + "indexmap 1.9.3", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", + "thiserror", +] + +[[package]] +name = "fdlimit" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4c9e43643f5a3be4ca5b67d26b98031ff9db6806c3440ae32e02e3ceac3f1b" +dependencies = [ + "libc", +] + +[[package]] +name = "femme" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc04871e5ae3aa2952d552dae6b291b3099723bf779a8054281c1366a54613ef" +dependencies = [ + "cfg-if", + "js-sys", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fflonk" +version = "0.1.0" +source = "git+https://github.com/w3f/fflonk#26a5045b24e169cffc1f9328ca83d71061145c40" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "merlin 3.0.0", +] + +[[package]] +name = "fiat-crypto" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" + +[[package]] +name = "file-per-thread-logger" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f2e425d9790201ba4af4630191feac6dcc98765b118d4d18e91d23c2353866" +dependencies = [ + "env_logger 0.10.0", + "log", +] + +[[package]] +name = "filetime" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.2.16", + "windows-sys 0.48.0", +] + +[[package]] +name = "finality-grandpa" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36530797b9bf31cd4ff126dcfee8170f86b00cfdcea3269d73133cc0415945c3" +dependencies = [ + "either", + "futures", + "futures-timer", + "log", + "num-traits", + "parity-scale-codec", + "parking_lot 0.12.1", + "scale-info", +] + +[[package]] +name = "findshlibs" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64" +dependencies = [ + "cc", + "lazy_static", + "libc", + "winapi", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +dependencies = [ + "crc32fast", + "libz-sys", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fork-tree" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fragile" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" + +[[package]] +name = "frame-benchmarking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support", + "frame-support-procedural", + "frame-system", + "linregress", + "log", + "parity-scale-codec", + "paste", + "scale-info", + "serde", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-runtime", + "sp-runtime-interface", + "sp-std", + "sp-storage", + "static_assertions", +] + +[[package]] +name = "frame-benchmarking-cli" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "Inflector", + "array-bytes", + "chrono", + "clap 4.3.19", + "comfy-table", + "frame-benchmarking", + "frame-support", + "frame-system", + "gethostname", + "handlebars", + "itertools", + "lazy_static", + "linked-hash-map", + "log", + "parity-scale-codec", + "rand 0.8.5", + "rand_pcg", + "sc-block-builder", + "sc-cli", + "sc-client-api", + "sc-client-db", + "sc-executor", + "sc-service", + "sc-sysinfo", + "serde", + "serde_json", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-database", + "sp-externalities", + "sp-inherents", + "sp-io", + "sp-keystore", + "sp-runtime", + "sp-state-machine", + "sp-storage", + "sp-trie", + "sp-wasm-interface", + "thiserror", + "thousands", +] + +[[package]] +name = "frame-election-provider-solution-type" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "frame-election-provider-support" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-election-provider-solution-type", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-npos-elections", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "frame-executive" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support", + "frame-system", + "frame-try-runtime", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", +] + +[[package]] +name = "frame-metadata" +version = "16.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cf1549fba25a6fcac22785b61698317d958e96cac72a59102ea45b9ae64692" +dependencies = [ + "cfg-if", + "parity-scale-codec", + "scale-info", + "serde", +] + +[[package]] +name = "frame-remote-externalities" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-recursion", + "futures", + "indicatif", + "jsonrpsee", + "log", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-state-machine", + "spinners", + "substrate-rpc-client", + "tokio", + "tokio-retry", +] + +[[package]] +name = "frame-support" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "aquamarine", + "bitflags 1.3.2", + "docify", + "environmental", + "frame-metadata", + "frame-support-procedural", + "impl-trait-for-tuples", + "k256", + "log", + "macro_magic", + "parity-scale-codec", + "paste", + "scale-info", + "serde", + "serde_json", + "smallvec", + "sp-api", + "sp-arithmetic", + "sp-core", + "sp-core-hashing-proc-macro", + "sp-debug-derive", + "sp-genesis-builder", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-state-machine", + "sp-std", + "sp-tracing", + "sp-weights", + "tt-call", +] + +[[package]] +name = "frame-support-procedural" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "Inflector", + "cfg-expr", + "derive-syn-parse", + "expander 2.0.0", + "frame-support-procedural-tools", + "itertools", + "macro_magic", + "proc-macro-warning", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "frame-support-procedural-tools" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support-procedural-tools-derive", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "frame-support-procedural-tools-derive" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "frame-support-test" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-executive", + "frame-support", + "frame-support-test-pallet", + "frame-system", + "parity-scale-codec", + "pretty_assertions", + "rustversion", + "scale-info", + "serde", + "sp-api", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-version", + "static_assertions", + "trybuild", +] + +[[package]] +name = "frame-support-test-pallet" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "serde", + "sp-runtime", +] + +[[package]] +name = "frame-system" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "cfg-if", + "frame-support", + "log", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-version", + "sp-weights", +] + +[[package]] +name = "frame-system-benchmarking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "frame-system-rpc-runtime-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "sp-api", +] + +[[package]] +name = "frame-try-runtime" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support", + "parity-scale-codec", + "sp-api", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "fs-err" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" + +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "fs4" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" +dependencies = [ + "rustix 0.38.6", + "windows-sys 0.48.0", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite 0.2.10", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "futures-rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" +dependencies = [ + "futures-io", + "rustls 0.20.8", + "webpki 0.22.0", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite 0.2.10", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generate-bags" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "chrono", + "frame-election-provider-support", + "frame-support", + "frame-system", + "num-format", + "pallet-staking", + "sp-staking", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "ghash" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +dependencies = [ + "opaque-debug 0.3.0", + "polyval 0.5.3", +] + +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug 0.3.0", + "polyval 0.6.1", +] + +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +dependencies = [ + "fallible-iterator", + "indexmap 1.9.3", + "stable_deref_trait", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "globset" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aca8bbd8e0707c1887a8bbb7e6b40e228f251ff5d62c8220a4a7a53c73aff006" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + +[[package]] +name = "handlebars" +version = "4.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83c3372087601b532857d332f5957cbae686da52bb7810bf038c3e3c3cc2fa0d" +dependencies = [ + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "hash-db" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e7d7786361d7425ae2fe4f9e407eb0efaa0840f5212d109cc018c40c35c6ab4" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", +] + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +dependencies = [ + "ahash 0.8.3", + "allocator-api2", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac 0.8.0", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array 0.14.7", + "hmac 0.8.1", +] + +[[package]] +name = "honggfuzz" +version = "0.5.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848e9c511092e0daa0a35a63e8e6e475a3e8f870741448b9f6028d69b142f18e" +dependencies = [ + "arbitrary", + "lazy_static", + "memmap2", + "rustc_version", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite 0.2.10", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite 0.2.10", + "socket2 0.4.9", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +dependencies = [ + "http", + "hyper", + "log", + "rustls 0.20.8", + "rustls-native-certs", + "tokio", + "tokio-rustls 0.23.4", + "webpki-roots", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +dependencies = [ + "futures-util", + "http", + "hyper", + "log", + "rustls 0.21.6", + "rustls-native-certs", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows 0.48.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "if-addrs" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc0fa01ffc752e9dbc72818cdb072cd028b86be5e09dd04c5a643704fe101a9" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "if-watch" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9465340214b296cd17a0009acdb890d6160010b8adf8f78a00d0d7ab270f79f" +dependencies = [ + "async-io", + "core-foundation", + "fnv", + "futures", + "if-addrs", + "ipnet", + "log", + "rtnetlink", + "system-configuration", + "tokio", + "windows 0.34.0", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "include_dir" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + +[[package]] +name = "indicatif" +version = "0.17.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "integer-encoding" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" + +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] + +[[package]] +name = "interceptor" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e8a11ae2da61704edada656798b61c94b35ecac2c58eb955156987d5e6be90b" +dependencies = [ + "async-trait", + "bytes", + "log", + "rand 0.8.5", + "rtcp", + "rtp", + "thiserror", + "tokio", + "waitgroup", + "webrtc-srtp", + "webrtc-util", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.2", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ip_network" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2 0.5.3", + "widestring", + "windows-sys 0.48.0", + "winreg 0.50.0", +] + +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi 0.3.2", + "rustix 0.38.6", + "windows-sys 0.48.0", +] + +[[package]] +name = "is_executable" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa9acdc6d67b75e626ad644734e8bc6df893d9cd2a834129065d3dd6158ea9c8" +dependencies = [ + "winapi", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + +[[package]] +name = "jsonrpsee" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d291e3a5818a2384645fd9756362e6d89cf0541b0b916fa7702ea4a9833608e" +dependencies = [ + "jsonrpsee-core", + "jsonrpsee-http-client", + "jsonrpsee-proc-macros", + "jsonrpsee-server", + "jsonrpsee-types", + "jsonrpsee-ws-client", + "tracing", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965de52763f2004bc91ac5bcec504192440f0b568a5d621c59d9dbd6f886c3fb" +dependencies = [ + "futures-util", + "http", + "jsonrpsee-core", + "jsonrpsee-types", + "pin-project", + "rustls-native-certs", + "soketto", + "thiserror", + "tokio", + "tokio-rustls 0.23.4", + "tokio-util", + "tracing", + "webpki-roots", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e70b4439a751a5de7dd5ed55eacff78ebf4ffe0fc009cb1ebb11417f5b536b" +dependencies = [ + "anyhow", + "arrayvec 0.7.4", + "async-lock", + "async-trait", + "beef", + "futures-channel", + "futures-timer", + "futures-util", + "globset", + "hyper", + "jsonrpsee-types", + "parking_lot 0.12.1", + "rand 0.8.5", + "rustc-hash", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc345b0a43c6bc49b947ebeb936e886a419ee3d894421790c969cc56040542ad" +dependencies = [ + "async-trait", + "hyper", + "hyper-rustls 0.23.2", + "jsonrpsee-core", + "jsonrpsee-types", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-proc-macros" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa6da1e4199c10d7b1d0a6e5e8bd8e55f351163b6f4b3cbb044672a69bd4c1c" +dependencies = [ + "heck", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "jsonrpsee-server" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb69dad85df79527c019659a992498d03f8495390496da2f07e6c24c2b356fc" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "hyper", + "jsonrpsee-core", + "jsonrpsee-types", + "serde", + "serde_json", + "soketto", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bd522fe1ce3702fd94812965d7bb7a3364b1c9aba743944c5a00529aae80f8c" +dependencies = [ + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b83daeecfc6517cfe210df24e570fb06213533dfb990318fae781f4c7119dd9" +dependencies = [ + "http", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", +] + +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa 0.16.8", + "elliptic-curve 0.13.5", + "once_cell", + "sha2 0.10.7", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "kusama-runtime" +version = "0.9.43" +dependencies = [ + "binary-merkle-tree", + "bitvec", + "frame-benchmarking", + "frame-election-provider-support", + "frame-executive", + "frame-remote-externalities", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "frame-try-runtime", + "hex-literal 0.4.1", + "kusama-runtime-constants", + "log", + "pallet-authority-discovery", + "pallet-authorship", + "pallet-babe", + "pallet-bags-list", + "pallet-balances", + "pallet-beefy", + "pallet-beefy-mmr", + "pallet-bounties", + "pallet-child-bounties", + "pallet-collective", + "pallet-conviction-voting", + "pallet-democracy", + "pallet-election-provider-multi-phase", + "pallet-election-provider-support-benchmarking", + "pallet-elections-phragmen", + "pallet-fast-unstake", + "pallet-grandpa", + "pallet-identity", + "pallet-im-online", + "pallet-indices", + "pallet-membership", + "pallet-message-queue", + "pallet-mmr", + "pallet-multisig", + "pallet-nis", + "pallet-nomination-pools", + "pallet-nomination-pools-benchmarking", + "pallet-nomination-pools-runtime-api", + "pallet-offences", + "pallet-offences-benchmarking", + "pallet-preimage", + "pallet-proxy", + "pallet-ranked-collective", + "pallet-recovery", + "pallet-referenda", + "pallet-scheduler", + "pallet-session", + "pallet-session-benchmarking", + "pallet-society", + "pallet-staking", + "pallet-staking-runtime-api", + "pallet-state-trie-migration", + "pallet-timestamp", + "pallet-tips", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-treasury", + "pallet-utility", + "pallet-vesting", + "pallet-whitelist", + "pallet-xcm", + "pallet-xcm-benchmarks", + "parity-scale-codec", + "polkadot-primitives", + "polkadot-runtime-common", + "polkadot-runtime-parachains", + "rustc-hex", + "scale-info", + "separator", + "serde", + "serde_derive", + "serde_json", + "smallvec", + "sp-api", + "sp-application-crypto", + "sp-arithmetic", + "sp-authority-discovery", + "sp-block-builder", + "sp-consensus-babe", + "sp-consensus-beefy", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-mmr-primitives", + "sp-npos-elections", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-transaction-pool", + "sp-trie", + "sp-version", + "static_assertions", + "substrate-wasm-builder", + "tiny-keccak", + "tokio", + "xcm", + "xcm-builder", + "xcm-executor", +] + +[[package]] +name = "kusama-runtime-constants" +version = "0.9.43" +dependencies = [ + "frame-support", + "polkadot-primitives", + "polkadot-runtime-common", + "smallvec", + "sp-core", + "sp-runtime", + "sp-weights", +] + +[[package]] +name = "kvdb" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d770dcb02bf6835887c3a979b5107a04ff4bbde97a5f0928d27404a155add9" +dependencies = [ + "smallvec", +] + +[[package]] +name = "kvdb-memorydb" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7a85fe66f9ff9cd74e169fdd2c94c6e1e74c412c99a73b4df3200b5d3760b2" +dependencies = [ + "kvdb", + "parking_lot 0.12.1", +] + +[[package]] +name = "kvdb-rocksdb" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b644c70b92285f66bfc2032922a79000ea30af7bc2ab31902992a5dcb9b434f6" +dependencies = [ + "kvdb", + "num_cpus", + "parking_lot 0.12.1", + "regex", + "rocksdb", + "smallvec", +] + +[[package]] +name = "kvdb-shared-tests" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d3b4e3e80c369f1b5364b6acdeba9b8a02285e91a5570f7c0404b7f9024541" +dependencies = [ + "kvdb", +] + +[[package]] +name = "landlock" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520baa32708c4e957d2fc3a186bc5bd8d26637c33137f399ddfc202adb240068" +dependencies = [ + "enumflags2", + "libc", + "thiserror", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "libflate" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ff4ae71b685bbad2f2f391fe74f6b7659a34871c08b210fdc039e43bee07d18" +dependencies = [ + "adler32", + "crc32fast", + "libflate_lz77", +] + +[[package]] +name = "libflate_lz77" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a52d3a8bfc85f250440e4424db7d857e241a3aebbbe301f3eb606ab15c39acbf" +dependencies = [ + "rle-decode-fast", +] + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libp2p" +version = "0.51.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f210d259724eae82005b5c48078619b7745edb7b76de370b03f8ba59ea103097" +dependencies = [ + "bytes", + "futures", + "futures-timer", + "getrandom 0.2.10", + "instant", + "libp2p-allow-block-list", + "libp2p-connection-limits", + "libp2p-core", + "libp2p-dns", + "libp2p-identify", + "libp2p-identity", + "libp2p-kad", + "libp2p-mdns", + "libp2p-metrics", + "libp2p-noise", + "libp2p-ping", + "libp2p-quic", + "libp2p-request-response", + "libp2p-swarm", + "libp2p-tcp", + "libp2p-wasm-ext", + "libp2p-webrtc", + "libp2p-websocket", + "libp2p-yamux", + "multiaddr", + "pin-project", +] + +[[package]] +name = "libp2p-allow-block-list" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "510daa05efbc25184458db837f6f9a5143888f1caa742426d92e1833ddd38a50" +dependencies = [ + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "void", +] + +[[package]] +name = "libp2p-connection-limits" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4caa33f1d26ed664c4fe2cca81a08c8e07d4c1c04f2f4ac7655c2dd85467fda0" +dependencies = [ + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "void", +] + +[[package]] +name = "libp2p-core" +version = "0.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c1df63c0b582aa434fb09b2d86897fa2b419ffeccf934b36f87fcedc8e835c2" +dependencies = [ + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-identity", + "log", + "multiaddr", + "multihash", + "multistream-select", + "once_cell", + "parking_lot 0.12.1", + "pin-project", + "quick-protobuf", + "rand 0.8.5", + "rw-stream-sink", + "smallvec", + "thiserror", + "unsigned-varint", + "void", +] + +[[package]] +name = "libp2p-dns" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146ff7034daae62077c415c2376b8057368042df6ab95f5432ad5e88568b1554" +dependencies = [ + "futures", + "libp2p-core", + "log", + "parking_lot 0.12.1", + "smallvec", + "trust-dns-resolver", +] + +[[package]] +name = "libp2p-identify" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5455f472243e63b9c497ff320ded0314254a9eb751799a39c283c6f20b793f3c" +dependencies = [ + "asynchronous-codec", + "either", + "futures", + "futures-timer", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "log", + "lru 0.10.1", + "quick-protobuf", + "quick-protobuf-codec", + "smallvec", + "thiserror", + "void", +] + +[[package]] +name = "libp2p-identity" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e2d584751cecb2aabaa56106be6be91338a60a0f4e420cf2af639204f596fc1" +dependencies = [ + "bs58", + "ed25519-dalek 1.0.1", + "log", + "multiaddr", + "multihash", + "quick-protobuf", + "rand 0.8.5", + "sha2 0.10.7", + "thiserror", + "zeroize", +] + +[[package]] +name = "libp2p-kad" +version = "0.43.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39d5ef876a2b2323d63c258e63c2f8e36f205fe5a11f0b3095d59635650790ff" +dependencies = [ + "arrayvec 0.7.4", + "asynchronous-codec", + "bytes", + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "log", + "quick-protobuf", + "rand 0.8.5", + "sha2 0.10.7", + "smallvec", + "thiserror", + "uint", + "unsigned-varint", + "void", +] + +[[package]] +name = "libp2p-mdns" +version = "0.43.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19983e1f949f979a928f2c603de1cf180cc0dc23e4ac93a62651ccb18341460b" +dependencies = [ + "data-encoding", + "futures", + "if-watch", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "log", + "rand 0.8.5", + "smallvec", + "socket2 0.4.9", + "tokio", + "trust-dns-proto", + "void", +] + +[[package]] +name = "libp2p-metrics" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a42ec91e227d7d0dafa4ce88b333cdf5f277253873ab087555c92798db2ddd46" +dependencies = [ + "libp2p-core", + "libp2p-identify", + "libp2p-kad", + "libp2p-ping", + "libp2p-swarm", + "prometheus-client", +] + +[[package]] +name = "libp2p-noise" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3673da89d29936bc6435bafc638e2f184180d554ce844db65915113f86ec5e" +dependencies = [ + "bytes", + "curve25519-dalek 3.2.0", + "futures", + "libp2p-core", + "libp2p-identity", + "log", + "once_cell", + "quick-protobuf", + "rand 0.8.5", + "sha2 0.10.7", + "snow", + "static_assertions", + "thiserror", + "x25519-dalek 1.1.1", + "zeroize", +] + +[[package]] +name = "libp2p-ping" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e57759c19c28a73ef1eb3585ca410cefb72c1a709fcf6de1612a378e4219202" +dependencies = [ + "either", + "futures", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-swarm", + "log", + "rand 0.8.5", + "void", +] + +[[package]] +name = "libp2p-quic" +version = "0.7.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6b26abd81cd2398382a1edfe739b539775be8a90fa6914f39b2ab49571ec735" +dependencies = [ + "bytes", + "futures", + "futures-timer", + "if-watch", + "libp2p-core", + "libp2p-identity", + "libp2p-tls", + "log", + "parking_lot 0.12.1", + "quinn-proto", + "rand 0.8.5", + "rustls 0.20.8", + "thiserror", + "tokio", +] + +[[package]] +name = "libp2p-request-response" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffdb374267d42dc5ed5bc53f6e601d4a64ac5964779c6e40bb9e4f14c1e30d5" +dependencies = [ + "async-trait", + "futures", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "rand 0.8.5", + "smallvec", +] + +[[package]] +name = "libp2p-swarm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "903b3d592d7694e56204d211f29d31bc004be99386644ba8731fc3e3ef27b296" +dependencies = [ + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm-derive", + "log", + "rand 0.8.5", + "smallvec", + "tokio", + "void", +] + +[[package]] +name = "libp2p-swarm-derive" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fba456131824ab6acd4c7bf61e9c0f0a3014b5fc9868ccb8e10d344594cdc4f" +dependencies = [ + "heck", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "libp2p-tcp" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d33698596d7722d85d3ab0c86c2c322254fce1241e91208e3679b4eb3026cf" +dependencies = [ + "futures", + "futures-timer", + "if-watch", + "libc", + "libp2p-core", + "log", + "socket2 0.4.9", + "tokio", +] + +[[package]] +name = "libp2p-tls" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff08d13d0dc66e5e9ba6279c1de417b84fa0d0adc3b03e5732928c180ec02781" +dependencies = [ + "futures", + "futures-rustls", + "libp2p-core", + "libp2p-identity", + "rcgen 0.10.0", + "ring 0.16.20", + "rustls 0.20.8", + "thiserror", + "webpki 0.22.0", + "x509-parser 0.14.0", + "yasna", +] + +[[package]] +name = "libp2p-wasm-ext" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77dff9d32353a5887adb86c8afc1de1a94d9e8c3bc6df8b2201d7cdf5c848f43" +dependencies = [ + "futures", + "js-sys", + "libp2p-core", + "parity-send-wrapper", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "libp2p-webrtc" +version = "0.4.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba48592edbc2f60b4bc7c10d65445b0c3964c07df26fdf493b6880d33be36f8" +dependencies = [ + "async-trait", + "asynchronous-codec", + "bytes", + "futures", + "futures-timer", + "hex", + "if-watch", + "libp2p-core", + "libp2p-identity", + "libp2p-noise", + "log", + "multihash", + "quick-protobuf", + "quick-protobuf-codec", + "rand 0.8.5", + "rcgen 0.9.3", + "serde", + "stun", + "thiserror", + "tinytemplate", + "tokio", + "tokio-util", + "webrtc", +] + +[[package]] +name = "libp2p-websocket" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "111273f7b3d3510524c752e8b7a5314b7f7a1fee7e68161c01a7d72cbb06db9f" +dependencies = [ + "either", + "futures", + "futures-rustls", + "libp2p-core", + "log", + "parking_lot 0.12.1", + "quicksink", + "rw-stream-sink", + "soketto", + "url", + "webpki-roots", +] + +[[package]] +name = "libp2p-yamux" +version = "0.43.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd21d950662700a385d4c6d68e2f5f54d778e97068cdd718522222ef513bda" +dependencies = [ + "futures", + "libp2p-core", + "log", + "thiserror", + "yamux", +] + +[[package]] +name = "librocksdb-sys" +version = "0.11.0+8.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +dependencies = [ + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "tikv-jemalloc-sys", +] + +[[package]] +name = "libsecp256k1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" +dependencies = [ + "arrayref", + "base64 0.13.1", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.8.5", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libz-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "link-cplusplus" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" +dependencies = [ + "cc", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linked_hash_set" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "linregress" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4de0b5f52a9f84544d268f5fabb71b38962d6aa3c6600b8bcd27d44ccf9c9c45" +dependencies = [ + "nalgebra", +] + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +dependencies = [ + "serde", + "value-bag", +] + +[[package]] +name = "lru" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +dependencies = [ + "hashbrown 0.13.2", +] + +[[package]] +name = "lru" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eedb2bdbad7e0634f83989bf596f497b070130daaa398ab22d84c39e266deec5" +dependencies = [ + "hashbrown 0.14.0", +] + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "lz4" +version = "1.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e9e2dd86df36ce760a60f6ff6ad526f7ba1f14ba0356f8254fb6905e6494df1" +dependencies = [ + "libc", + "lz4-sys", +] + +[[package]] +name = "lz4-sys" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "macro_magic" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aee866bfee30d2d7e83835a4574aad5b45adba4cc807f2a3bbba974e5d4383c9" +dependencies = [ + "macro_magic_core", + "macro_magic_macros", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "macro_magic_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e766a20fd9c72bab3e1e64ed63f36bd08410e75803813df210d1ce297d7ad00" +dependencies = [ + "const-random", + "derive-syn-parse", + "macro_magic_core_macros", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "macro_magic_core_macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c12469fc165526520dff2807c2975310ab47cf7190a45b99b49a7dc8befab17b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "macro_magic_macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fb85ec1620619edf2984a7693497d4ec88a9665d8b87e942856884c92dbf2a" +dependencies = [ + "macro_magic_core", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "matrixmultiply" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090126dc04f95dc0d1c1c91f61bdd474b3930ca064c1edc8a849da2c6cbe1e77" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memfd" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc89ccdc6e10d6907450f753537ebc5c5d3460d2e4e62ea74bd571db62c0f9e" +dependencies = [ + "rustix 0.37.23", +] + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memory-db" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808b50db46293432a45e63bc15ea51e0ab4c0a1647b8eb114e31a3e698dd6fbe" +dependencies = [ + "hash-db", +] + +[[package]] +name = "merlin" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "mick-jaeger" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69672161530e8aeca1d1400fbf3f1a1747ff60ea604265a4e906c2442df20532" +dependencies = [ + "futures", + "rand 0.8.5", + "thrift", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "mmr-gadget" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "futures", + "log", + "parity-scale-codec", + "sc-client-api", + "sc-offchain", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-consensus-beefy", + "sp-core", + "sp-mmr-primitives", + "sp-runtime", +] + +[[package]] +name = "mmr-rpc" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "anyhow", + "jsonrpsee", + "parity-scale-codec", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-mmr-primitives", + "sp-runtime", +] + +[[package]] +name = "mockall" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "lazy_static", + "mockall_derive", + "predicates 2.1.5", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "multiaddr" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "log", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "url", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" +dependencies = [ + "blake2b_simd", + "blake2s_simd", + "blake3", + "core2", + "digest 0.10.7", + "multihash-derive", + "sha2 0.10.7", + "sha3", + "unsigned-varint", +] + +[[package]] +name = "multihash-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc076939022111618a5026d3be019fd8b366e76314538ff9a1b59ffbcbf98bcd" +dependencies = [ + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "multistream-select" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8552ab875c1313b97b8d20cb857b9fd63e2d1d6a0a1b53ce9821e575405f27a" +dependencies = [ + "bytes", + "futures", + "log", + "pin-project", + "smallvec", + "unsigned-varint", +] + +[[package]] +name = "nalgebra" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" +dependencies = [ + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", +] + +[[package]] +name = "nalgebra-macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "names" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d66043b25d4a6cccb23619d10c19c25304b355a7dccd4a8e11423dd2382146" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "names" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc" +dependencies = [ + "clap 3.2.25", + "rand 0.8.5", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" + +[[package]] +name = "netlink-packet-core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" +dependencies = [ + "anyhow", + "byteorder", + "libc", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-route" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" +dependencies = [ + "anyhow", + "bitflags 1.3.2", + "byteorder", + "libc", + "netlink-packet-core", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-utils" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34" +dependencies = [ + "anyhow", + "byteorder", + "paste", + "thiserror", +] + +[[package]] +name = "netlink-proto" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" +dependencies = [ + "bytes", + "futures", + "log", + "netlink-packet-core", + "netlink-sys", + "thiserror", + "tokio", +] + +[[package]] +name = "netlink-sys" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6471bf08e7ac0135876a9581bf3217ef0333c191c128d34878079f42ee150411" +dependencies = [ + "bytes", + "futures", + "libc", + "log", + "tokio", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", + "static_assertions", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-format" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" +dependencies = [ + "arrayvec 0.7.4", + "itoa", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.2", + "libc", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.30.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +dependencies = [ + "crc32fast", + "hashbrown 0.13.2", + "indexmap 1.9.3", + "memchr", +] + +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + +[[package]] +name = "oid-registry" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e20717fa0541f39bd146692035c37bedfa532b3e5071b35761082407546b2a" +dependencies = [ + "asn1-rs 0.3.1", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs 0.5.2", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "orchestra" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "227585216d05ba65c7ab0a0450a3cf2cbd81a98862a54c4df8e14d5ac6adb015" +dependencies = [ + "async-trait", + "dyn-clonable", + "futures", + "futures-timer", + "orchestra-proc-macro", + "pin-project", + "prioritized-metered-channel", + "thiserror", + "tracing", +] + +[[package]] +name = "orchestra-proc-macro" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2871aadd82a2c216ee68a69837a526dfe788ecbe74c4c5038a6acdbff6653066" +dependencies = [ + "expander 0.0.6", + "itertools", + "petgraph", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ordered-float" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3305af35278dd29f46fcdd139e0b1fbfae2153f0e5928b39b035542dd31e37b7" +dependencies = [ + "num-traits", +] + +[[package]] +name = "os_str_bytes" +version = "6.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.7", +] + +[[package]] +name = "p384" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" +dependencies = [ + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.7", +] + +[[package]] +name = "pallet-assets" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-authority-discovery" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support", + "frame-system", + "pallet-session", + "parity-scale-codec", + "scale-info", + "sp-application-crypto", + "sp-authority-discovery", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-authorship" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-babe" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "pallet-session", + "pallet-timestamp", + "parity-scale-codec", + "scale-info", + "sp-application-crypto", + "sp-consensus-babe", + "sp-core", + "sp-io", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", +] + +[[package]] +name = "pallet-bags-list" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "aquamarine", + "docify", + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-system", + "log", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", +] + +[[package]] +name = "pallet-bags-list-remote-tests" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-election-provider-support", + "frame-remote-externalities", + "frame-support", + "frame-system", + "log", + "pallet-bags-list", + "pallet-staking", + "sp-core", + "sp-runtime", + "sp-std", + "sp-storage", + "sp-tracing", +] + +[[package]] +name = "pallet-balances" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-beefy" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support", + "frame-system", + "pallet-authorship", + "pallet-session", + "parity-scale-codec", + "scale-info", + "serde", + "sp-consensus-beefy", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", +] + +[[package]] +name = "pallet-beefy-mmr" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "binary-merkle-tree", + "frame-support", + "frame-system", + "log", + "pallet-beefy", + "pallet-mmr", + "pallet-session", + "parity-scale-codec", + "scale-info", + "serde", + "sp-api", + "sp-consensus-beefy", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-bounties" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-treasury", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-child-bounties" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-bounties", + "pallet-treasury", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-collective" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-conviction-voting" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "assert_matches", + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "serde", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-democracy" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-election-provider-multi-phase" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-system", + "log", + "pallet-election-provider-support-benchmarking", + "parity-scale-codec", + "rand 0.8.5", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-npos-elections", + "sp-runtime", + "sp-std", + "strum", +] + +[[package]] +name = "pallet-election-provider-support-benchmarking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-election-provider-support", + "frame-system", + "parity-scale-codec", + "sp-npos-elections", + "sp-runtime", +] + +[[package]] +name = "pallet-elections-phragmen" +version = "5.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-npos-elections", + "sp-runtime", + "sp-staking", + "sp-std", +] + +[[package]] +name = "pallet-fast-unstake" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "docify", + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", +] + +[[package]] +name = "pallet-grandpa" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "pallet-session", + "parity-scale-codec", + "scale-info", + "sp-application-crypto", + "sp-consensus-grandpa", + "sp-core", + "sp-io", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", +] + +[[package]] +name = "pallet-identity" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "enumflags2", + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-im-online" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "parity-scale-codec", + "scale-info", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", +] + +[[package]] +name = "pallet-indices" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-keyring", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-membership" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-message-queue" +version = "7.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-weights", +] + +[[package]] +name = "pallet-mmr" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-mmr-primitives", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-multisig" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-nis" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-nomination-pools" +version = "1.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support", + "frame-system", + "log", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", + "sp-tracing", +] + +[[package]] +name = "pallet-nomination-pools-benchmarking" +version = "1.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-system", + "pallet-bags-list", + "pallet-nomination-pools", + "pallet-staking", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-runtime-interface", + "sp-staking", + "sp-std", +] + +[[package]] +name = "pallet-nomination-pools-runtime-api" +version = "1.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "pallet-nomination-pools", + "parity-scale-codec", + "sp-api", + "sp-std", +] + +[[package]] +name = "pallet-offences" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support", + "frame-system", + "log", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "serde", + "sp-runtime", + "sp-staking", + "sp-std", +] + +[[package]] +name = "pallet-offences-benchmarking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-system", + "log", + "pallet-babe", + "pallet-balances", + "pallet-grandpa", + "pallet-im-online", + "pallet-offences", + "pallet-session", + "pallet-staking", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-staking", + "sp-std", +] + +[[package]] +name = "pallet-preimage" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-proxy" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-ranked-collective" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-recovery" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-referenda" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "assert_matches", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "serde", + "sp-arithmetic", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-salary" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-scheduler" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "docify", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-io", + "sp-runtime", + "sp-std", + "sp-weights", +] + +[[package]] +name = "pallet-session" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "log", + "pallet-timestamp", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-trie", +] + +[[package]] +name = "pallet-session-benchmarking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-session", + "pallet-staking", + "rand 0.8.5", + "sp-runtime", + "sp-session", + "sp-std", +] + +[[package]] +name = "pallet-society" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "rand_chacha 0.2.2", + "scale-info", + "sp-arithmetic", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-staking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "pallet-session", + "parity-scale-codec", + "rand_chacha 0.2.2", + "scale-info", + "serde", + "sp-application-crypto", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", +] + +[[package]] +name = "pallet-staking-reward-curve" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "pallet-staking-reward-fn" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "log", + "sp-arithmetic", +] + +[[package]] +name = "pallet-staking-runtime-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "sp-api", +] + +[[package]] +name = "pallet-state-trie-migration" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-sudo" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-timestamp" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-std", + "sp-timestamp", +] + +[[package]] +name = "pallet-tips" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-treasury", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-transaction-payment" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-transaction-payment-rpc" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "jsonrpsee", + "pallet-transaction-payment-rpc-runtime-api", + "parity-scale-codec", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-rpc", + "sp-runtime", + "sp-weights", +] + +[[package]] +name = "pallet-transaction-payment-rpc-runtime-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "pallet-transaction-payment", + "parity-scale-codec", + "sp-api", + "sp-runtime", + "sp-weights", +] + +[[package]] +name = "pallet-treasury" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "serde", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-uniques" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-utility" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-vesting" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-whitelist" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-xcm" +version = "0.9.43" +dependencies = [ + "bounded-collections", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-balances", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-runtime-parachains", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "xcm", + "xcm-builder", + "xcm-executor", +] + +[[package]] +name = "pallet-xcm-benchmarks" +version = "0.9.43" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-assets", + "pallet-balances", + "pallet-xcm", + "parity-scale-codec", + "polkadot-primitives", + "polkadot-runtime-common", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", + "xcm", + "xcm-builder", + "xcm-executor", +] + +[[package]] +name = "parity-db" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78f19d20a0d2cc52327a88d131fa1c4ea81ea4a04714aedcfeca2dd410049cf8" +dependencies = [ + "blake2", + "crc32fast", + "fs2", + "hex", + "libc", + "log", + "lz4", + "memmap2", + "parking_lot 0.12.1", + "rand 0.8.5", + "siphasher", + "snap", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" +dependencies = [ + "arrayvec 0.7.4", + "bitvec", + "byte-slice-cast", + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parity-send-wrapper" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" + +[[package]] +name = "parity-wasm" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" + +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.8", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "smallvec", + "windows-targets 0.48.1", +] + +[[package]] +name = "partial_sort" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7924d1d0ad836f665c9065e26d016c673ece3993f30d340068b16f282afc1156" + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pbkdf2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" +dependencies = [ + "crypto-mac 0.11.1", +] + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem-rfc7468" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pest" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" +dependencies = [ + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "pest_meta" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.7", +] + +[[package]] +name = "petgraph" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +dependencies = [ + "fixedbitset", + "indexmap 1.9.3", +] + +[[package]] +name = "pin-project" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" + +[[package]] +name = "pin-project-lite" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.7", + "spki 0.7.2", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "platforms" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" + +[[package]] +name = "polkadot" +version = "0.9.43" +dependencies = [ + "assert_cmd", + "color-eyre", + "nix 0.26.2", + "polkadot-cli", + "polkadot-core-primitives", + "polkadot-node-core-pvf", + "polkadot-node-core-pvf-common", + "polkadot-node-core-pvf-execute-worker", + "polkadot-node-core-pvf-prepare-worker", + "polkadot-overseer", + "substrate-build-script-utils", + "substrate-rpc-client", + "tempfile", + "tikv-jemallocator", + "tokio", +] + +[[package]] +name = "polkadot-approval-distribution" +version = "0.9.43" +dependencies = [ + "assert_matches", + "env_logger 0.9.3", + "futures", + "futures-timer", + "log", + "polkadot-node-jaeger", + "polkadot-node-metrics", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_core 0.5.1", + "schnorrkel", + "sp-authority-discovery", + "sp-core", + "tracing-gum", +] + +[[package]] +name = "polkadot-availability-bitfield-distribution" +version = "0.9.43" +dependencies = [ + "always-assert", + "assert_matches", + "bitvec", + "env_logger 0.9.3", + "futures", + "futures-timer", + "log", + "maplit", + "polkadot-node-network-protocol", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "rand 0.8.5", + "rand_chacha 0.3.1", + "sp-application-crypto", + "sp-authority-discovery", + "sp-core", + "sp-keyring", + "sp-keystore", + "tracing-gum", +] + +[[package]] +name = "polkadot-availability-distribution" +version = "0.9.43" +dependencies = [ + "assert_matches", + "derive_more", + "fatality", + "futures", + "futures-timer", + "lru 0.11.0", + "parity-scale-codec", + "polkadot-erasure-coding", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "rand 0.8.5", + "sc-network", + "sp-core", + "sp-keyring", + "sp-keystore", + "sp-tracing", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-availability-recovery" +version = "0.9.43" +dependencies = [ + "assert_matches", + "env_logger 0.9.3", + "fatality", + "futures", + "futures-timer", + "log", + "lru 0.11.0", + "parity-scale-codec", + "polkadot-erasure-coding", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "rand 0.8.5", + "sc-network", + "sp-application-crypto", + "sp-core", + "sp-keyring", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-cli" +version = "0.9.43" +dependencies = [ + "clap 4.3.19", + "frame-benchmarking-cli", + "futures", + "log", + "polkadot-node-metrics", + "polkadot-performance-test", + "polkadot-service", + "pyroscope", + "pyroscope_pprofrs", + "sc-cli", + "sc-executor", + "sc-service", + "sc-storage-monitor", + "sc-sysinfo", + "sc-tracing", + "sp-core", + "sp-io", + "sp-keyring", + "sp-maybe-compressed-blob", + "substrate-build-script-utils", + "thiserror", + "try-runtime-cli", +] + +[[package]] +name = "polkadot-collator-protocol" +version = "0.9.43" +dependencies = [ + "assert_matches", + "bitvec", + "env_logger 0.9.3", + "fatality", + "futures", + "futures-timer", + "log", + "parity-scale-codec", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sc-keystore", + "sc-network", + "sp-core", + "sp-keyring", + "sp-keystore", + "sp-runtime", + "thiserror", + "tokio-util", + "tracing-gum", +] + +[[package]] +name = "polkadot-core-primitives" +version = "0.9.43" +dependencies = [ + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "polkadot-dispute-distribution" +version = "0.9.43" +dependencies = [ + "assert_matches", + "async-channel", + "async-trait", + "derive_more", + "fatality", + "futures", + "futures-timer", + "indexmap 1.9.3", + "lazy_static", + "lru 0.11.0", + "parity-scale-codec", + "polkadot-erasure-coding", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sc-keystore", + "sc-network", + "sp-application-crypto", + "sp-keyring", + "sp-keystore", + "sp-tracing", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-erasure-coding" +version = "0.9.43" +dependencies = [ + "criterion", + "parity-scale-codec", + "polkadot-node-primitives", + "polkadot-primitives", + "reed-solomon-novelpoly", + "sp-core", + "sp-trie", + "thiserror", +] + +[[package]] +name = "polkadot-gossip-support" +version = "0.9.43" +dependencies = [ + "assert_matches", + "async-trait", + "futures", + "futures-timer", + "lazy_static", + "polkadot-node-network-protocol", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "rand 0.8.5", + "rand_chacha 0.3.1", + "sc-network", + "sc-network-common", + "sp-application-crypto", + "sp-authority-discovery", + "sp-consensus-babe", + "sp-core", + "sp-keyring", + "sp-keystore", + "sp-tracing", + "tracing-gum", +] + +[[package]] +name = "polkadot-network-bridge" +version = "0.9.43" +dependencies = [ + "always-assert", + "assert_matches", + "async-trait", + "bytes", + "fatality", + "futures", + "futures-timer", + "parity-scale-codec", + "parking_lot 0.12.1", + "polkadot-node-metrics", + "polkadot-node-network-protocol", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-overseer", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sc-network", + "sp-consensus", + "sp-core", + "sp-keyring", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-collation-generation" +version = "0.9.43" +dependencies = [ + "assert_matches", + "futures", + "parity-scale-codec", + "polkadot-erasure-coding", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sp-core", + "sp-keyring", + "sp-maybe-compressed-blob", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-approval-voting" +version = "0.9.43" +dependencies = [ + "assert_matches", + "async-trait", + "bitvec", + "derive_more", + "futures", + "futures-timer", + "kvdb", + "kvdb-memorydb", + "lru 0.11.0", + "merlin 2.0.1", + "parity-scale-codec", + "parking_lot 0.12.1", + "polkadot-node-jaeger", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-overseer", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "rand_core 0.5.1", + "sc-keystore", + "schnorrkel", + "sp-application-crypto", + "sp-consensus", + "sp-consensus-babe", + "sp-consensus-slots", + "sp-core", + "sp-keyring", + "sp-keystore", + "sp-runtime", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-av-store" +version = "0.9.43" +dependencies = [ + "assert_matches", + "bitvec", + "env_logger 0.9.3", + "futures", + "futures-timer", + "kvdb", + "kvdb-memorydb", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "polkadot-erasure-coding", + "polkadot-node-jaeger", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-overseer", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sp-consensus", + "sp-core", + "sp-keyring", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-backing" +version = "0.9.43" +dependencies = [ + "assert_matches", + "bitvec", + "fatality", + "futures", + "polkadot-erasure-coding", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "polkadot-statement-table", + "sc-keystore", + "sp-application-crypto", + "sp-core", + "sp-keyring", + "sp-keystore", + "sp-tracing", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-bitfield-signing" +version = "0.9.43" +dependencies = [ + "futures", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sp-keystore", + "thiserror", + "tracing-gum", + "wasm-timer", +] + +[[package]] +name = "polkadot-node-core-candidate-validation" +version = "0.9.43" +dependencies = [ + "assert_matches", + "async-trait", + "futures", + "futures-timer", + "parity-scale-codec", + "polkadot-node-core-pvf", + "polkadot-node-metrics", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-overseer", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sp-core", + "sp-keyring", + "sp-maybe-compressed-blob", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-chain-api" +version = "0.9.43" +dependencies = [ + "futures", + "maplit", + "parity-scale-codec", + "polkadot-node-metrics", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-primitives", + "sc-client-api", + "sc-consensus-babe", + "sp-blockchain", + "sp-core", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-chain-selection" +version = "0.9.43" +dependencies = [ + "assert_matches", + "futures", + "futures-timer", + "kvdb", + "kvdb-memorydb", + "parity-scale-codec", + "parking_lot 0.12.1", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "sp-core", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-dispute-coordinator" +version = "0.9.43" +dependencies = [ + "assert_matches", + "fatality", + "futures", + "futures-timer", + "kvdb", + "kvdb-memorydb", + "lru 0.11.0", + "parity-scale-codec", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sc-keystore", + "sp-application-crypto", + "sp-core", + "sp-keyring", + "sp-keystore", + "sp-tracing", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-parachains-inherent" +version = "0.9.43" +dependencies = [ + "async-trait", + "futures", + "futures-timer", + "polkadot-node-subsystem", + "polkadot-overseer", + "polkadot-primitives", + "sp-blockchain", + "sp-inherents", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-prospective-parachains" +version = "0.9.43" +dependencies = [ + "assert_matches", + "bitvec", + "fatality", + "futures", + "parity-scale-codec", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-types", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sc-keystore", + "sp-application-crypto", + "sp-core", + "sp-keyring", + "sp-keystore", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-provisioner" +version = "0.9.43" +dependencies = [ + "bitvec", + "fatality", + "futures", + "futures-timer", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sp-application-crypto", + "sp-keystore", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-pvf" +version = "0.9.43" +dependencies = [ + "always-assert", + "assert_matches", + "futures", + "futures-timer", + "hex-literal 0.3.4", + "libc", + "parity-scale-codec", + "pin-project", + "polkadot-core-primitives", + "polkadot-node-core-pvf", + "polkadot-node-core-pvf-common", + "polkadot-node-core-pvf-execute-worker", + "polkadot-node-core-pvf-prepare-worker", + "polkadot-node-metrics", + "polkadot-node-primitives", + "polkadot-parachain", + "polkadot-primitives", + "rand 0.8.5", + "slotmap", + "sp-core", + "sp-maybe-compressed-blob", + "sp-tracing", + "sp-wasm-interface", + "substrate-build-script-utils", + "tempfile", + "test-parachain-adder", + "test-parachain-halt", + "tokio", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-pvf-checker" +version = "0.9.43" +dependencies = [ + "futures", + "futures-timer", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-util", + "polkadot-overseer", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sc-keystore", + "sp-application-crypto", + "sp-core", + "sp-keyring", + "sp-keystore", + "sp-runtime", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-pvf-common" +version = "0.9.43" +dependencies = [ + "assert_matches", + "cpu-time", + "futures", + "landlock", + "libc", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-primitives", + "sc-executor", + "sc-executor-common", + "sc-executor-wasmtime", + "sp-core", + "sp-externalities", + "sp-io", + "sp-tracing", + "tempfile", + "tokio", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-pvf-execute-worker" +version = "0.9.43" +dependencies = [ + "cpu-time", + "futures", + "parity-scale-codec", + "polkadot-node-core-pvf-common", + "polkadot-parachain", + "polkadot-primitives", + "rayon", + "sp-core", + "sp-maybe-compressed-blob", + "sp-tracing", + "tikv-jemalloc-ctl", + "tokio", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-pvf-prepare-worker" +version = "0.9.43" +dependencies = [ + "futures", + "libc", + "parity-scale-codec", + "polkadot-node-core-pvf-common", + "polkadot-parachain", + "polkadot-primitives", + "rayon", + "sc-executor", + "sc-executor-common", + "sc-executor-wasmtime", + "sp-io", + "sp-maybe-compressed-blob", + "sp-tracing", + "tikv-jemalloc-ctl", + "tokio", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-core-runtime-api" +version = "0.9.43" +dependencies = [ + "async-trait", + "futures", + "lru 0.11.0", + "polkadot-node-metrics", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-types", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "sp-api", + "sp-consensus-babe", + "sp-core", + "sp-keyring", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-jaeger" +version = "0.9.43" +dependencies = [ + "lazy_static", + "log", + "mick-jaeger", + "parity-scale-codec", + "parking_lot 0.12.1", + "polkadot-node-primitives", + "polkadot-primitives", + "sc-network", + "sp-core", + "thiserror", + "tokio", +] + +[[package]] +name = "polkadot-node-metrics" +version = "0.9.43" +dependencies = [ + "assert_cmd", + "bs58", + "futures", + "futures-timer", + "hyper", + "log", + "parity-scale-codec", + "polkadot-primitives", + "polkadot-test-service", + "prioritized-metered-channel", + "prometheus-parse", + "sc-cli", + "sc-service", + "sc-tracing", + "sp-keyring", + "substrate-prometheus-endpoint", + "substrate-test-utils", + "tempfile", + "tokio", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-network-protocol" +version = "0.9.43" +dependencies = [ + "async-channel", + "async-trait", + "bitvec", + "derive_more", + "fatality", + "futures", + "hex", + "parity-scale-codec", + "polkadot-node-jaeger", + "polkadot-node-primitives", + "polkadot-primitives", + "rand 0.8.5", + "rand_chacha 0.3.1", + "sc-authority-discovery", + "sc-network", + "strum", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-node-primitives" +version = "0.9.43" +dependencies = [ + "bounded-vec", + "futures", + "parity-scale-codec", + "polkadot-erasure-coding", + "polkadot-parachain", + "polkadot-primitives", + "schnorrkel", + "serde", + "sp-application-crypto", + "sp-consensus-babe", + "sp-core", + "sp-keystore", + "sp-maybe-compressed-blob", + "sp-runtime", + "thiserror", + "zstd 0.11.2+zstd.1.5.2", +] + +[[package]] +name = "polkadot-node-subsystem" +version = "0.9.43" +dependencies = [ + "polkadot-node-jaeger", + "polkadot-node-subsystem-types", + "polkadot-overseer", +] + +[[package]] +name = "polkadot-node-subsystem-test-helpers" +version = "0.9.43" +dependencies = [ + "async-trait", + "futures", + "parking_lot 0.12.1", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-overseer", + "polkadot-primitives", + "sc-keystore", + "sp-application-crypto", + "sp-core", + "sp-keyring", + "sp-keystore", +] + +[[package]] +name = "polkadot-node-subsystem-types" +version = "0.9.43" +dependencies = [ + "async-trait", + "derive_more", + "futures", + "orchestra", + "polkadot-node-jaeger", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-primitives", + "polkadot-statement-table", + "sc-network", + "sc-transaction-pool-api", + "smallvec", + "sp-api", + "sp-authority-discovery", + "sp-consensus-babe", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "polkadot-node-subsystem-util" +version = "0.9.43" +dependencies = [ + "assert_matches", + "async-trait", + "derive_more", + "env_logger 0.9.3", + "fatality", + "futures", + "futures-channel", + "itertools", + "kvdb", + "kvdb-memorydb", + "kvdb-shared-tests", + "lazy_static", + "log", + "lru 0.11.0", + "parity-db", + "parity-scale-codec", + "parking_lot 0.11.2", + "pin-project", + "polkadot-node-jaeger", + "polkadot-node-metrics", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-overseer", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "prioritized-metered-channel", + "rand 0.8.5", + "sp-application-crypto", + "sp-core", + "sp-keystore", + "tempfile", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-overseer" +version = "0.9.43" +dependencies = [ + "assert_matches", + "async-trait", + "femme", + "futures", + "futures-timer", + "lru 0.11.0", + "orchestra", + "parking_lot 0.12.1", + "polkadot-node-metrics", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-node-subsystem-types", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "prioritized-metered-channel", + "sc-client-api", + "sp-api", + "sp-core", + "tikv-jemalloc-ctl", + "tracing-gum", +] + +[[package]] +name = "polkadot-parachain" +version = "0.9.43" +dependencies = [ + "bounded-collections", + "derive_more", + "frame-support", + "parity-scale-codec", + "polkadot-core-primitives", + "scale-info", + "serde", + "sp-core", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "polkadot-performance-test" +version = "0.9.43" +dependencies = [ + "env_logger 0.9.3", + "kusama-runtime", + "log", + "polkadot-erasure-coding", + "polkadot-node-core-pvf-prepare-worker", + "polkadot-node-primitives", + "polkadot-primitives", + "quote", + "sc-executor-common", + "sp-maybe-compressed-blob", + "thiserror", +] + +[[package]] +name = "polkadot-primitives" +version = "0.9.43" +dependencies = [ + "bitvec", + "hex-literal 0.4.1", + "parity-scale-codec", + "polkadot-core-primitives", + "polkadot-parachain", + "scale-info", + "serde", + "sp-api", + "sp-application-crypto", + "sp-arithmetic", + "sp-authority-discovery", + "sp-consensus-slots", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keystore", + "sp-runtime", + "sp-staking", + "sp-std", +] + +[[package]] +name = "polkadot-primitives-test-helpers" +version = "0.9.43" +dependencies = [ + "polkadot-primitives", + "rand 0.8.5", + "sp-application-crypto", + "sp-core", + "sp-keyring", + "sp-runtime", +] + +[[package]] +name = "polkadot-rpc" +version = "0.9.43" +dependencies = [ + "jsonrpsee", + "mmr-rpc", + "pallet-transaction-payment-rpc", + "polkadot-primitives", + "sc-chain-spec", + "sc-client-api", + "sc-consensus-babe", + "sc-consensus-babe-rpc", + "sc-consensus-beefy", + "sc-consensus-beefy-rpc", + "sc-consensus-epochs", + "sc-consensus-grandpa", + "sc-consensus-grandpa-rpc", + "sc-rpc", + "sc-sync-state-rpc", + "sc-transaction-pool-api", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-keystore", + "sp-runtime", + "substrate-frame-rpc-system", + "substrate-state-trie-migration-rpc", +] + +[[package]] +name = "polkadot-runtime" +version = "0.9.43" +dependencies = [ + "bitvec", + "frame-benchmarking", + "frame-election-provider-support", + "frame-executive", + "frame-remote-externalities", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "frame-try-runtime", + "hex-literal 0.4.1", + "log", + "pallet-authority-discovery", + "pallet-authorship", + "pallet-babe", + "pallet-bags-list", + "pallet-balances", + "pallet-bounties", + "pallet-child-bounties", + "pallet-collective", + "pallet-conviction-voting", + "pallet-democracy", + "pallet-election-provider-multi-phase", + "pallet-election-provider-support-benchmarking", + "pallet-elections-phragmen", + "pallet-fast-unstake", + "pallet-grandpa", + "pallet-identity", + "pallet-im-online", + "pallet-indices", + "pallet-membership", + "pallet-message-queue", + "pallet-multisig", + "pallet-nomination-pools", + "pallet-nomination-pools-benchmarking", + "pallet-nomination-pools-runtime-api", + "pallet-offences", + "pallet-offences-benchmarking", + "pallet-preimage", + "pallet-proxy", + "pallet-referenda", + "pallet-scheduler", + "pallet-session", + "pallet-session-benchmarking", + "pallet-staking", + "pallet-staking-reward-curve", + "pallet-staking-runtime-api", + "pallet-timestamp", + "pallet-tips", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-treasury", + "pallet-utility", + "pallet-vesting", + "pallet-whitelist", + "pallet-xcm", + "pallet-xcm-benchmarks", + "parity-scale-codec", + "polkadot-primitives", + "polkadot-runtime-common", + "polkadot-runtime-constants", + "polkadot-runtime-parachains", + "rustc-hex", + "scale-info", + "separator", + "serde", + "serde_derive", + "serde_json", + "smallvec", + "sp-api", + "sp-arithmetic", + "sp-authority-discovery", + "sp-block-builder", + "sp-consensus-babe", + "sp-consensus-beefy", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-mmr-primitives", + "sp-npos-elections", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-transaction-pool", + "sp-trie", + "sp-version", + "static_assertions", + "substrate-wasm-builder", + "tiny-keccak", + "tokio", + "xcm", + "xcm-builder", + "xcm-executor", +] + +[[package]] +name = "polkadot-runtime-common" +version = "0.9.43" +dependencies = [ + "bitvec", + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-support-test", + "frame-system", + "hex-literal 0.4.1", + "impl-trait-for-tuples", + "libsecp256k1", + "log", + "pallet-authorship", + "pallet-babe", + "pallet-balances", + "pallet-election-provider-multi-phase", + "pallet-fast-unstake", + "pallet-session", + "pallet-staking", + "pallet-staking-reward-fn", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-treasury", + "pallet-vesting", + "parity-scale-codec", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "polkadot-runtime-parachains", + "rustc-hex", + "scale-info", + "serde", + "serde_derive", + "serde_json", + "slot-range-helper", + "sp-api", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-keystore", + "sp-npos-elections", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "static_assertions", + "xcm", +] + +[[package]] +name = "polkadot-runtime-constants" +version = "0.9.43" +dependencies = [ + "frame-support", + "polkadot-primitives", + "polkadot-runtime-common", + "smallvec", + "sp-core", + "sp-runtime", + "sp-weights", +] + +[[package]] +name = "polkadot-runtime-metrics" +version = "0.9.43" +dependencies = [ + "bs58", + "frame-benchmarking", + "parity-scale-codec", + "polkadot-primitives", + "sp-std", + "sp-tracing", +] + +[[package]] +name = "polkadot-runtime-parachains" +version = "0.9.43" +dependencies = [ + "assert_matches", + "bitflags 1.3.2", + "bitvec", + "derive_more", + "frame-benchmarking", + "frame-support", + "frame-support-test", + "frame-system", + "futures", + "hex-literal 0.4.1", + "log", + "pallet-authority-discovery", + "pallet-authorship", + "pallet-babe", + "pallet-balances", + "pallet-message-queue", + "pallet-session", + "pallet-staking", + "pallet-timestamp", + "pallet-vesting", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "polkadot-runtime-metrics", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rustc-hex", + "sc-keystore", + "scale-info", + "serde", + "serde_json", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-keystore", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-tracing", + "static_assertions", + "thousands", + "xcm", + "xcm-executor", +] + +[[package]] +name = "polkadot-service" +version = "0.9.43" +dependencies = [ + "assert_matches", + "async-trait", + "env_logger 0.9.3", + "frame-benchmarking", + "frame-benchmarking-cli", + "frame-support", + "frame-system", + "frame-system-rpc-runtime-api", + "futures", + "hex-literal 0.4.1", + "is_executable", + "kusama-runtime", + "kusama-runtime-constants", + "kvdb", + "kvdb-rocksdb", + "log", + "lru 0.11.0", + "mmr-gadget", + "pallet-babe", + "pallet-im-online", + "pallet-staking", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "parity-db", + "parity-scale-codec", + "polkadot-approval-distribution", + "polkadot-availability-bitfield-distribution", + "polkadot-availability-distribution", + "polkadot-availability-recovery", + "polkadot-collator-protocol", + "polkadot-core-primitives", + "polkadot-dispute-distribution", + "polkadot-gossip-support", + "polkadot-network-bridge", + "polkadot-node-collation-generation", + "polkadot-node-core-approval-voting", + "polkadot-node-core-av-store", + "polkadot-node-core-backing", + "polkadot-node-core-bitfield-signing", + "polkadot-node-core-candidate-validation", + "polkadot-node-core-chain-api", + "polkadot-node-core-chain-selection", + "polkadot-node-core-dispute-coordinator", + "polkadot-node-core-parachains-inherent", + "polkadot-node-core-prospective-parachains", + "polkadot-node-core-provisioner", + "polkadot-node-core-pvf", + "polkadot-node-core-pvf-checker", + "polkadot-node-core-runtime-api", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-types", + "polkadot-node-subsystem-util", + "polkadot-overseer", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-rpc", + "polkadot-runtime", + "polkadot-runtime-common", + "polkadot-runtime-constants", + "polkadot-runtime-parachains", + "polkadot-statement-distribution", + "polkadot-test-client", + "rococo-runtime", + "rococo-runtime-constants", + "sc-authority-discovery", + "sc-basic-authorship", + "sc-block-builder", + "sc-chain-spec", + "sc-client-api", + "sc-client-db", + "sc-consensus", + "sc-consensus-babe", + "sc-consensus-beefy", + "sc-consensus-grandpa", + "sc-consensus-slots", + "sc-executor", + "sc-keystore", + "sc-network", + "sc-network-common", + "sc-network-sync", + "sc-offchain", + "sc-service", + "sc-sync-state-rpc", + "sc-sysinfo", + "sc-telemetry", + "sc-transaction-pool", + "sc-transaction-pool-api", + "serde", + "serde_json", + "serial_test", + "sp-api", + "sp-authority-discovery", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-consensus-beefy", + "sp-consensus-grandpa", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-keystore", + "sp-mmr-primitives", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-state-machine", + "sp-storage", + "sp-timestamp", + "sp-transaction-pool", + "sp-version", + "sp-weights", + "substrate-prometheus-endpoint", + "tempfile", + "thiserror", + "tracing-gum", + "westend-runtime", + "westend-runtime-constants", +] + +[[package]] +name = "polkadot-statement-distribution" +version = "0.9.43" +dependencies = [ + "arrayvec 0.7.4", + "assert_matches", + "async-channel", + "bitvec", + "fatality", + "futures", + "futures-timer", + "indexmap 1.9.3", + "parity-scale-codec", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-types", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-primitives-test-helpers", + "rand_chacha 0.3.1", + "sc-keystore", + "sc-network", + "sp-application-crypto", + "sp-authority-discovery", + "sp-core", + "sp-keyring", + "sp-keystore", + "sp-staking", + "sp-tracing", + "thiserror", + "tracing-gum", +] + +[[package]] +name = "polkadot-statement-table" +version = "0.9.43" +dependencies = [ + "parity-scale-codec", + "polkadot-primitives", + "sp-core", +] + +[[package]] +name = "polkadot-test-client" +version = "0.9.43" +dependencies = [ + "frame-benchmarking", + "futures", + "parity-scale-codec", + "polkadot-node-subsystem", + "polkadot-primitives", + "polkadot-test-runtime", + "polkadot-test-service", + "sc-block-builder", + "sc-consensus", + "sc-offchain", + "sc-service", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-runtime", + "sp-state-machine", + "sp-timestamp", + "substrate-test-client", +] + +[[package]] +name = "polkadot-test-malus" +version = "0.9.43" +dependencies = [ + "assert_matches", + "async-trait", + "clap 4.3.19", + "color-eyre", + "futures", + "futures-timer", + "polkadot-cli", + "polkadot-erasure-coding", + "polkadot-node-core-backing", + "polkadot-node-core-candidate-validation", + "polkadot-node-core-dispute-coordinator", + "polkadot-node-core-pvf-common", + "polkadot-node-core-pvf-execute-worker", + "polkadot-node-core-pvf-prepare-worker", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-node-subsystem-types", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "rand 0.8.5", + "sp-core", + "sp-keystore", + "substrate-build-script-utils", + "tracing-gum", +] + +[[package]] +name = "polkadot-test-runtime" +version = "0.9.43" +dependencies = [ + "bitvec", + "frame-election-provider-support", + "frame-executive", + "frame-support", + "frame-system", + "frame-system-rpc-runtime-api", + "hex-literal 0.4.1", + "log", + "pallet-authority-discovery", + "pallet-authorship", + "pallet-babe", + "pallet-balances", + "pallet-grandpa", + "pallet-indices", + "pallet-offences", + "pallet-session", + "pallet-staking", + "pallet-staking-reward-curve", + "pallet-sudo", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-vesting", + "pallet-xcm", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-runtime-common", + "polkadot-runtime-parachains", + "rustc-hex", + "scale-info", + "serde", + "serde_derive", + "serde_json", + "smallvec", + "sp-api", + "sp-authority-discovery", + "sp-block-builder", + "sp-consensus-babe", + "sp-consensus-beefy", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-mmr-primitives", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-transaction-pool", + "sp-trie", + "sp-version", + "substrate-wasm-builder", + "test-runtime-constants", + "tiny-keccak", + "xcm", + "xcm-builder", + "xcm-executor", +] + +[[package]] +name = "polkadot-test-service" +version = "0.9.43" +dependencies = [ + "frame-system", + "futures", + "hex", + "pallet-balances", + "pallet-staking", + "pallet-transaction-payment", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-overseer", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-rpc", + "polkadot-runtime-common", + "polkadot-runtime-parachains", + "polkadot-service", + "polkadot-test-runtime", + "rand 0.8.5", + "sc-authority-discovery", + "sc-chain-spec", + "sc-cli", + "sc-client-api", + "sc-consensus", + "sc-consensus-babe", + "sc-consensus-grandpa", + "sc-network", + "sc-service", + "sc-tracing", + "sc-transaction-pool", + "serde_json", + "sp-arithmetic", + "sp-authority-discovery", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-consensus-grandpa", + "sp-core", + "sp-inherents", + "sp-keyring", + "sp-runtime", + "sp-state-machine", + "substrate-test-client", + "substrate-test-utils", + "tempfile", + "test-runtime-constants", + "tokio", + "tracing-gum", +] + +[[package]] +name = "polkadot-voter-bags" +version = "0.9.43" +dependencies = [ + "clap 4.3.19", + "generate-bags", + "kusama-runtime", + "polkadot-runtime", + "sp-io", + "westend-runtime", +] + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite 0.2.10", + "windows-sys 0.48.0", +] + +[[package]] +name = "poly1305" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +dependencies = [ + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash 0.4.1", +] + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash 0.4.1", +] + +[[package]] +name = "polyval" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash 0.5.1", +] + +[[package]] +name = "portable-atomic" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" + +[[package]] +name = "pprof" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "196ded5d4be535690899a4631cc9f18cdc41b7ebf24a79400f46f48e49a11059" +dependencies = [ + "backtrace", + "cfg-if", + "findshlibs", + "libc", + "log", + "nix 0.26.2", + "once_cell", + "parking_lot 0.12.1", + "smallvec", + "symbolic-demangle", + "tempfile", + "thiserror", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "predicates" +version = "2.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" +dependencies = [ + "difflib", + "float-cmp", + "itertools", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09963355b9f467184c04017ced4a2ba2d75cbcb4e7462690d388233253d4b1a9" +dependencies = [ + "anstyle", + "difflib", + "itertools", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" + +[[package]] +name = "predicates-tree" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "prettyplease" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" +dependencies = [ + "proc-macro2", + "syn 2.0.28", +] + +[[package]] +name = "primitive-types" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "prioritized-metered-channel" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382698e48a268c832d0b181ed438374a6bb708a82a8ca273bb0f61c74cf209c4" +dependencies = [ + "coarsetime", + "crossbeam-queue", + "derive_more", + "futures", + "futures-timer", + "nanorand", + "thiserror", + "tracing", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro-warning" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70550716265d1ec349c41f70dd4f964b4fd88394efe4405f0c1da679c4799a07" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prometheus" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "memchr", + "parking_lot 0.12.1", + "thiserror", +] + +[[package]] +name = "prometheus-client" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6fa99d535dd930d1249e6c79cb3c2915f9172a540fe2b02a4c8f9ca954721e" +dependencies = [ + "dtoa", + "itoa", + "parking_lot 0.12.1", + "prometheus-client-derive-encode", +] + +[[package]] +name = "prometheus-client-derive-encode" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b6a5217beb0ad503ee7fa752d451c905113d70721b937126158f3106a48cc1" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prometheus-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2aa5feb83bf4b2c8919eaf563f51dbab41183de73ba2353c0e03cd7b6bd892" +dependencies = [ + "chrono", + "itertools", + "once_cell", + "regex", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease 0.1.25", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + +[[package]] +name = "pyroscope" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ce54d81c50f7fd6442ee671597f661a068ccebd82ed1557775b6791b14aba7" +dependencies = [ + "json", + "libc", + "libflate", + "log", + "names 0.14.0", + "prost", + "reqwest", + "thiserror", + "url", + "winapi", +] + +[[package]] +name = "pyroscope_pprofrs" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57add45daa57783490913a5d3d88e3249126971b61ac97ee0c7bac293ef0114a" +dependencies = [ + "log", + "pprof", + "pyroscope", + "thiserror", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + +[[package]] +name = "quick-protobuf-codec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1693116345026436eb2f10b677806169c1a1260c1c60eaaffe3fb5a29ae23d8b" +dependencies = [ + "asynchronous-codec", + "bytes", + "quick-protobuf", + "thiserror", + "unsigned-varint", +] + +[[package]] +name = "quicksink" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77de3c815e5a160b1539c6592796801df2043ae35e123b46d73380cfa57af858" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project-lite 0.1.12", +] + +[[package]] +name = "quinn-proto" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31999cfc7927c4e212e60fd50934ab40e8e8bfd2d493d6095d2d306bc0764d9" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring 0.16.20", + "rustc-hash", + "rustls 0.20.8", + "slab", + "thiserror", + "tinyvec", + "tracing", + "webpki 0.22.0", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "rcgen" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" +dependencies = [ + "pem", + "ring 0.16.20", + "time 0.3.25", + "x509-parser 0.13.2", + "yasna", +] + +[[package]] +name = "rcgen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +dependencies = [ + "pem", + "ring 0.16.20", + "time 0.3.25", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom 0.2.10", + "redox_syscall 0.2.16", + "thiserror", +] + +[[package]] +name = "reed-solomon-novelpoly" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd8f48b2066e9f69ab192797d66da804d1935bf22763204ed3675740cb0f221" +dependencies = [ + "derive_more", + "fs-err", + "itertools", + "static_init 0.5.2", + "thiserror", +] + +[[package]] +name = "ref-cast" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ef7e18e8841942ddb1cf845054f8008410030a3997875d9e49b7a363063df1" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfaf0c85b766276c797f3791f5bc6d5bd116b41d53049af2789666b0c0bc9fa" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "regalloc2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80535183cae11b149d618fbd3c37e38d7cda589d82d7769e196ca9a9042d7621" +dependencies = [ + "fxhash", + "log", + "slice-group-by", + "smallvec", +] + +[[package]] +name = "regex" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.3.4", + "regex-syntax 0.7.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.4", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + +[[package]] +name = "remote-ext-tests-bags-list" +version = "0.9.43" +dependencies = [ + "clap 4.3.19", + "frame-system", + "kusama-runtime", + "kusama-runtime-constants", + "log", + "pallet-bags-list-remote-tests", + "polkadot-runtime", + "polkadot-runtime-constants", + "sp-core", + "sp-tracing", + "tokio", + "westend-runtime", + "westend-runtime-constants", +] + +[[package]] +name = "reqwest" +version = "0.11.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +dependencies = [ + "base64 0.21.2", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls 0.24.1", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite 0.2.10", + "rustls 0.21.6", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg 0.10.1", +] + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac 0.12.1", + "zeroize", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle", +] + +[[package]] +name = "ring" +version = "0.1.0" +source = "git+https://github.com/w3f/ring-proof#0e948f3c28cbacecdd3020403c4841c0eb339213" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "common", + "fflonk", + "merlin 3.0.0", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + +[[package]] +name = "rocksdb" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" +dependencies = [ + "libc", + "librocksdb-sys", +] + +[[package]] +name = "rococo-runtime" +version = "0.9.43" +dependencies = [ + "binary-merkle-tree", + "frame-benchmarking", + "frame-executive", + "frame-remote-externalities", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "frame-try-runtime", + "hex-literal 0.4.1", + "log", + "pallet-authority-discovery", + "pallet-authorship", + "pallet-babe", + "pallet-balances", + "pallet-beefy", + "pallet-beefy-mmr", + "pallet-bounties", + "pallet-child-bounties", + "pallet-collective", + "pallet-democracy", + "pallet-elections-phragmen", + "pallet-grandpa", + "pallet-identity", + "pallet-im-online", + "pallet-indices", + "pallet-membership", + "pallet-message-queue", + "pallet-mmr", + "pallet-multisig", + "pallet-nis", + "pallet-offences", + "pallet-preimage", + "pallet-proxy", + "pallet-recovery", + "pallet-scheduler", + "pallet-session", + "pallet-society", + "pallet-staking", + "pallet-state-trie-migration", + "pallet-sudo", + "pallet-timestamp", + "pallet-tips", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-treasury", + "pallet-utility", + "pallet-vesting", + "pallet-xcm", + "pallet-xcm-benchmarks", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-runtime-common", + "polkadot-runtime-parachains", + "rococo-runtime-constants", + "scale-info", + "separator", + "serde", + "serde_derive", + "serde_json", + "smallvec", + "sp-api", + "sp-authority-discovery", + "sp-block-builder", + "sp-consensus-babe", + "sp-consensus-beefy", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-mmr-primitives", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-transaction-pool", + "sp-trie", + "sp-version", + "static_assertions", + "substrate-wasm-builder", + "tiny-keccak", + "tokio", + "xcm", + "xcm-builder", + "xcm-executor", +] + +[[package]] +name = "rococo-runtime-constants" +version = "0.9.43" +dependencies = [ + "frame-support", + "polkadot-primitives", + "polkadot-runtime-common", + "smallvec", + "sp-core", + "sp-runtime", + "sp-weights", +] + +[[package]] +name = "rpassword" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" +dependencies = [ + "libc", + "rtoolbox", + "winapi", +] + +[[package]] +name = "rtcp" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1919efd6d4a6a85d13388f9487549bb8e359f17198cc03ffd72f79b553873691" +dependencies = [ + "bytes", + "thiserror", + "webrtc-util", +] + +[[package]] +name = "rtnetlink" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0" +dependencies = [ + "futures", + "log", + "netlink-packet-route", + "netlink-proto", + "nix 0.24.3", + "thiserror", + "tokio", +] + +[[package]] +name = "rtoolbox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "rtp" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a095411ff00eed7b12e4c6a118ba984d113e1079582570d56a5ee723f11f80" +dependencies = [ + "async-trait", + "bytes", + "rand 0.8.5", + "serde", + "thiserror", + "webrtc-util", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.18", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "rustix" +version = "0.36.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c37f1bd5ef1b5422177b7646cba67430579cfe2ace80f284fee876bca52ad941" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.1.4", + "windows-sys 0.45.0", +] + +[[package]] +name = "rustix" +version = "0.37.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee020b1716f0a80e2ace9b03441a749e402e86712f15f16fe8a8f75afac732f" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys 0.4.5", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64 0.13.1", + "log", + "ring 0.16.20", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +dependencies = [ + "log", + "ring 0.16.20", + "sct 0.7.0", + "webpki 0.22.0", +] + +[[package]] +name = "rustls" +version = "0.21.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" +dependencies = [ + "log", + "ring 0.16.20", + "rustls-webpki", + "sct 0.7.0", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64 0.21.2", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" +dependencies = [ + "ring 0.16.20", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "rw-stream-sink" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26338f5e09bb721b85b135ea05af7767c90b52f6de4f087d4f4a3a9d64e7dc04" +dependencies = [ + "futures", + "pin-project", + "static_assertions", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "safe_arch" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sc-allocator" +version = "4.1.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "log", + "sp-core", + "sp-wasm-interface", + "thiserror", +] + +[[package]] +name = "sc-authority-discovery" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "futures", + "futures-timer", + "ip_network", + "libp2p", + "log", + "multihash", + "parity-scale-codec", + "prost", + "prost-build", + "rand 0.8.5", + "sc-client-api", + "sc-network", + "sp-api", + "sp-authority-discovery", + "sp-blockchain", + "sp-core", + "sp-keystore", + "sp-runtime", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "sc-basic-authorship" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "futures", + "futures-timer", + "log", + "parity-scale-codec", + "sc-block-builder", + "sc-client-api", + "sc-proposer-metrics", + "sc-telemetry", + "sc-transaction-pool-api", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-inherents", + "sp-runtime", + "substrate-prometheus-endpoint", +] + +[[package]] +name = "sc-block-builder" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "sc-client-api", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-core", + "sp-inherents", + "sp-runtime", +] + +[[package]] +name = "sc-chain-spec" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "memmap2", + "sc-chain-spec-derive", + "sc-client-api", + "sc-executor", + "sc-network", + "sc-telemetry", + "serde", + "serde_json", + "sp-blockchain", + "sp-core", + "sp-runtime", + "sp-state-machine", +] + +[[package]] +name = "sc-chain-spec-derive" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "sc-cli" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "chrono", + "clap 4.3.19", + "fdlimit", + "futures", + "libp2p-identity", + "log", + "names 0.13.0", + "parity-scale-codec", + "rand 0.8.5", + "regex", + "rpassword", + "sc-client-api", + "sc-client-db", + "sc-keystore", + "sc-network", + "sc-service", + "sc-telemetry", + "sc-tracing", + "sc-utils", + "serde", + "serde_json", + "sp-blockchain", + "sp-core", + "sp-keyring", + "sp-keystore", + "sp-panic-handler", + "sp-runtime", + "sp-version", + "thiserror", + "tiny-bip39", + "tokio", +] + +[[package]] +name = "sc-client-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "fnv", + "futures", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-executor", + "sc-transaction-pool-api", + "sc-utils", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-database", + "sp-externalities", + "sp-runtime", + "sp-state-machine", + "sp-statement-store", + "sp-storage", + "substrate-prometheus-endpoint", +] + +[[package]] +name = "sc-client-db" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "hash-db", + "kvdb", + "kvdb-memorydb", + "kvdb-rocksdb", + "linked-hash-map", + "log", + "parity-db", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-client-api", + "sc-state-db", + "schnellru", + "sp-arithmetic", + "sp-blockchain", + "sp-core", + "sp-database", + "sp-runtime", + "sp-state-machine", + "sp-trie", +] + +[[package]] +name = "sc-consensus" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "futures", + "futures-timer", + "libp2p-identity", + "log", + "mockall", + "parking_lot 0.12.1", + "sc-client-api", + "sc-utils", + "serde", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-runtime", + "sp-state-machine", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "sc-consensus-babe" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "fork-tree", + "futures", + "log", + "num-bigint", + "num-rational", + "num-traits", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-client-api", + "sc-consensus", + "sc-consensus-epochs", + "sc-consensus-slots", + "sc-telemetry", + "sc-transaction-pool-api", + "scale-info", + "sp-api", + "sp-application-crypto", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-consensus-slots", + "sp-core", + "sp-inherents", + "sp-keystore", + "sp-runtime", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "sc-consensus-babe-rpc" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "futures", + "jsonrpsee", + "sc-consensus-babe", + "sc-consensus-epochs", + "sc-rpc-api", + "serde", + "sp-api", + "sp-application-crypto", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-core", + "sp-keystore", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "sc-consensus-beefy" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "async-channel", + "async-trait", + "fnv", + "futures", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-client-api", + "sc-consensus", + "sc-network", + "sc-network-gossip", + "sc-network-sync", + "sc-utils", + "sp-api", + "sp-application-crypto", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", + "sp-consensus-beefy", + "sp-core", + "sp-keystore", + "sp-mmr-primitives", + "sp-runtime", + "substrate-prometheus-endpoint", + "thiserror", + "wasm-timer", +] + +[[package]] +name = "sc-consensus-beefy-rpc" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "futures", + "jsonrpsee", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-consensus-beefy", + "sc-rpc", + "serde", + "sp-consensus-beefy", + "sp-core", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "sc-consensus-epochs" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "fork-tree", + "parity-scale-codec", + "sc-client-api", + "sc-consensus", + "sp-blockchain", + "sp-runtime", +] + +[[package]] +name = "sc-consensus-grandpa" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "ahash 0.8.3", + "array-bytes", + "async-trait", + "dyn-clone", + "finality-grandpa", + "fork-tree", + "futures", + "futures-timer", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "rand 0.8.5", + "sc-block-builder", + "sc-chain-spec", + "sc-client-api", + "sc-consensus", + "sc-network", + "sc-network-common", + "sc-network-gossip", + "sc-telemetry", + "sc-transaction-pool-api", + "sc-utils", + "serde_json", + "sp-api", + "sp-application-crypto", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", + "sp-consensus-grandpa", + "sp-core", + "sp-keystore", + "sp-runtime", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "sc-consensus-grandpa-rpc" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "finality-grandpa", + "futures", + "jsonrpsee", + "log", + "parity-scale-codec", + "sc-client-api", + "sc-consensus-grandpa", + "sc-rpc", + "serde", + "sp-blockchain", + "sp-core", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "sc-consensus-slots" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "futures", + "futures-timer", + "log", + "parity-scale-codec", + "sc-client-api", + "sc-consensus", + "sc-telemetry", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", + "sp-consensus-slots", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", +] + +[[package]] +name = "sc-executor" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-executor-common", + "sc-executor-wasmtime", + "schnellru", + "sp-api", + "sp-core", + "sp-externalities", + "sp-io", + "sp-panic-handler", + "sp-runtime-interface", + "sp-trie", + "sp-version", + "sp-wasm-interface", + "tracing", +] + +[[package]] +name = "sc-executor-common" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "sc-allocator", + "sp-maybe-compressed-blob", + "sp-wasm-interface", + "thiserror", + "wasm-instrument", +] + +[[package]] +name = "sc-executor-wasmtime" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "anyhow", + "cfg-if", + "libc", + "log", + "rustix 0.36.15", + "sc-allocator", + "sc-executor-common", + "sp-runtime-interface", + "sp-wasm-interface", + "wasmtime", +] + +[[package]] +name = "sc-informant" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "ansi_term", + "futures", + "futures-timer", + "log", + "sc-client-api", + "sc-network", + "sc-network-common", + "sp-blockchain", + "sp-runtime", +] + +[[package]] +name = "sc-keystore" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "parking_lot 0.12.1", + "serde_json", + "sp-application-crypto", + "sp-core", + "sp-keystore", + "thiserror", +] + +[[package]] +name = "sc-network" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "async-channel", + "async-trait", + "asynchronous-codec", + "bytes", + "either", + "fnv", + "futures", + "futures-timer", + "ip_network", + "libp2p", + "linked_hash_set", + "log", + "mockall", + "parity-scale-codec", + "parking_lot 0.12.1", + "partial_sort", + "pin-project", + "rand 0.8.5", + "sc-client-api", + "sc-network-common", + "sc-utils", + "serde", + "serde_json", + "smallvec", + "sp-arithmetic", + "sp-blockchain", + "sp-core", + "sp-runtime", + "substrate-prometheus-endpoint", + "thiserror", + "unsigned-varint", + "wasm-timer", + "zeroize", +] + +[[package]] +name = "sc-network-bitswap" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-channel", + "cid", + "futures", + "libp2p-identity", + "log", + "prost", + "prost-build", + "sc-client-api", + "sc-network", + "sp-blockchain", + "sp-runtime", + "thiserror", + "unsigned-varint", +] + +[[package]] +name = "sc-network-common" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "bitflags 1.3.2", + "futures", + "libp2p-identity", + "parity-scale-codec", + "prost-build", + "sc-consensus", + "sp-consensus", + "sp-consensus-grandpa", + "sp-runtime", +] + +[[package]] +name = "sc-network-gossip" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "ahash 0.8.3", + "futures", + "futures-timer", + "libp2p", + "log", + "sc-network", + "sc-network-common", + "schnellru", + "sp-runtime", + "substrate-prometheus-endpoint", + "tracing", +] + +[[package]] +name = "sc-network-light" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "async-channel", + "futures", + "libp2p-identity", + "log", + "parity-scale-codec", + "prost", + "prost-build", + "sc-client-api", + "sc-network", + "sp-blockchain", + "sp-core", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "sc-network-sync" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "async-channel", + "async-trait", + "fork-tree", + "futures", + "futures-timer", + "libp2p", + "log", + "mockall", + "parity-scale-codec", + "prost", + "prost-build", + "sc-client-api", + "sc-consensus", + "sc-network", + "sc-network-common", + "sc-utils", + "schnellru", + "smallvec", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", + "sp-consensus-grandpa", + "sp-core", + "sp-runtime", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "sc-network-transactions" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "futures", + "libp2p", + "log", + "parity-scale-codec", + "sc-network", + "sc-network-common", + "sc-utils", + "sp-consensus", + "sp-runtime", + "substrate-prometheus-endpoint", +] + +[[package]] +name = "sc-offchain" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "bytes", + "fnv", + "futures", + "futures-timer", + "hyper", + "hyper-rustls 0.24.1", + "libp2p", + "log", + "num_cpus", + "once_cell", + "parity-scale-codec", + "parking_lot 0.12.1", + "rand 0.8.5", + "sc-client-api", + "sc-network", + "sc-network-common", + "sc-transaction-pool-api", + "sc-utils", + "sp-api", + "sp-core", + "sp-externalities", + "sp-keystore", + "sp-offchain", + "sp-runtime", + "threadpool", + "tracing", +] + +[[package]] +name = "sc-proposer-metrics" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "log", + "substrate-prometheus-endpoint", +] + +[[package]] +name = "sc-rpc" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "futures", + "jsonrpsee", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-block-builder", + "sc-chain-spec", + "sc-client-api", + "sc-rpc-api", + "sc-tracing", + "sc-transaction-pool-api", + "sc-utils", + "serde_json", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-keystore", + "sp-offchain", + "sp-rpc", + "sp-runtime", + "sp-session", + "sp-statement-store", + "sp-version", + "tokio", +] + +[[package]] +name = "sc-rpc-api" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "jsonrpsee", + "parity-scale-codec", + "sc-chain-spec", + "sc-transaction-pool-api", + "scale-info", + "serde", + "serde_json", + "sp-core", + "sp-rpc", + "sp-runtime", + "sp-version", + "thiserror", +] + +[[package]] +name = "sc-rpc-server" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "http", + "jsonrpsee", + "log", + "serde_json", + "substrate-prometheus-endpoint", + "tokio", + "tower", + "tower-http", +] + +[[package]] +name = "sc-rpc-spec-v2" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "futures", + "futures-util", + "hex", + "jsonrpsee", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-chain-spec", + "sc-client-api", + "sc-transaction-pool-api", + "sc-utils", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-runtime", + "sp-version", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "sc-service" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "directories", + "exit-future", + "futures", + "futures-timer", + "jsonrpsee", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "pin-project", + "rand 0.8.5", + "sc-block-builder", + "sc-chain-spec", + "sc-client-api", + "sc-client-db", + "sc-consensus", + "sc-executor", + "sc-informant", + "sc-keystore", + "sc-network", + "sc-network-bitswap", + "sc-network-common", + "sc-network-light", + "sc-network-sync", + "sc-network-transactions", + "sc-rpc", + "sc-rpc-server", + "sc-rpc-spec-v2", + "sc-sysinfo", + "sc-telemetry", + "sc-tracing", + "sc-transaction-pool", + "sc-transaction-pool-api", + "sc-utils", + "serde", + "serde_json", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-externalities", + "sp-keystore", + "sp-runtime", + "sp-session", + "sp-state-machine", + "sp-storage", + "sp-transaction-pool", + "sp-transaction-storage-proof", + "sp-trie", + "sp-version", + "static_init 1.0.3", + "substrate-prometheus-endpoint", + "tempfile", + "thiserror", + "tokio", + "tracing", + "tracing-futures", +] + +[[package]] +name = "sc-state-db" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "sp-core", +] + +[[package]] +name = "sc-storage-monitor" +version = "0.1.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "clap 4.3.19", + "fs4", + "log", + "sc-client-db", + "sp-core", + "thiserror", + "tokio", +] + +[[package]] +name = "sc-sync-state-rpc" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "jsonrpsee", + "parity-scale-codec", + "sc-chain-spec", + "sc-client-api", + "sc-consensus-babe", + "sc-consensus-epochs", + "sc-consensus-grandpa", + "serde", + "serde_json", + "sp-blockchain", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "sc-sysinfo" +version = "6.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "futures", + "libc", + "log", + "rand 0.8.5", + "rand_pcg", + "regex", + "sc-telemetry", + "serde", + "serde_json", + "sp-core", + "sp-io", + "sp-std", +] + +[[package]] +name = "sc-telemetry" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "chrono", + "futures", + "libp2p", + "log", + "parking_lot 0.12.1", + "pin-project", + "rand 0.8.5", + "sc-utils", + "serde", + "serde_json", + "thiserror", + "wasm-timer", +] + +[[package]] +name = "sc-tracing" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "ansi_term", + "atty", + "chrono", + "lazy_static", + "libc", + "log", + "parking_lot 0.12.1", + "regex", + "rustc-hash", + "sc-client-api", + "sc-tracing-proc-macro", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-rpc", + "sp-runtime", + "sp-tracing", + "thiserror", + "tracing", + "tracing-log", + "tracing-subscriber 0.2.25", +] + +[[package]] +name = "sc-tracing-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "sc-transaction-pool" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "futures", + "futures-timer", + "linked-hash-map", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-client-api", + "sc-transaction-pool-api", + "sc-utils", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-runtime", + "sp-tracing", + "sp-transaction-pool", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "sc-transaction-pool-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "futures", + "log", + "parity-scale-codec", + "serde", + "sp-blockchain", + "sp-core", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "sc-utils" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-channel", + "futures", + "futures-timer", + "lazy_static", + "log", + "parking_lot 0.12.1", + "prometheus", + "sp-arithmetic", +] + +[[package]] +name = "scale-info" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" +dependencies = [ + "bitvec", + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", + "serde", +] + +[[package]] +name = "scale-info-derive" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "schnellru" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" +dependencies = [ + "ahash 0.8.3", + "cfg-if", + "hashbrown 0.13.2", +] + +[[package]] +name = "schnorrkel" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "curve25519-dalek 2.1.3", + "getrandom 0.1.16", + "merlin 2.0.1", + "rand 0.7.3", + "rand_core 0.5.1", + "sha2 0.8.2", + "subtle", + "zeroize", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scratch" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring 0.16.20", + "untrusted", +] + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring 0.16.20", + "untrusted", +] + +[[package]] +name = "sdp" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d22a5ef407871893fd72b4562ee15e4742269b173959db4b8df6f538c414e13" +dependencies = [ + "rand 0.8.5", + "substring", + "thiserror", + "url", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array 0.14.7", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.7", + "generic-array 0.14.7", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" +dependencies = [ + "cc", +] + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +dependencies = [ + "serde", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "separator" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5" + +[[package]] +name = "serde" +version = "1.0.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea67f183f058fe88a4e3ec6e2788e003840893b91bac4559cabedd00863b3ed" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e744d7782b686ab3b73267ef05697159cc0e5abbed3f47f9933165e5219036" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_json" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serial_test" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d" +dependencies = [ + "dashmap", + "futures", + "lazy_static", + "log", + "parking_lot 0.12.1", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signal-hook-tokio" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213241f76fb1e37e27de3b6aa1b068a2c333233b59cca6634f634b80a27ecf1e" +dependencies = [ + "futures-core", + "libc", + "signal-hook", + "tokio", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "simba" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + +[[package]] +name = "slot-range-helper" +version = "0.9.43" +dependencies = [ + "enumn", + "parity-scale-codec", + "paste", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "snap" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" + +[[package]] +name = "snow" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9d1425eb528a21de2755c75af4c9b5d57f50a0d4c3b7f1828a4cd03f8ba155" +dependencies = [ + "aes-gcm 0.9.4", + "blake2", + "chacha20poly1305", + "curve25519-dalek 4.0.0", + "rand_core 0.6.4", + "ring 0.16.20", + "rustc_version", + "sha2 0.10.7", + "subtle", +] + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "flate2", + "futures", + "http", + "httparse", + "log", + "rand 0.8.5", + "sha-1 0.9.8", +] + +[[package]] +name = "sp-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "hash-db", + "log", + "parity-scale-codec", + "scale-info", + "sp-api-proc-macro", + "sp-core", + "sp-externalities", + "sp-metadata-ir", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-trie", + "sp-version", + "thiserror", +] + +[[package]] +name = "sp-api-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "Inflector", + "blake2", + "expander 2.0.0", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "sp-application-crypto" +version = "23.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-std", +] + +[[package]] +name = "sp-arithmetic" +version = "16.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "scale-info", + "serde", + "sp-std", + "static_assertions", +] + +[[package]] +name = "sp-authority-discovery" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-application-crypto", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "sp-block-builder" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "sp-api", + "sp-inherents", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "sp-blockchain" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "futures", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "schnellru", + "sp-api", + "sp-consensus", + "sp-database", + "sp-runtime", + "sp-state-machine", + "thiserror", +] + +[[package]] +name = "sp-consensus" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "futures", + "log", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", + "thiserror", +] + +[[package]] +name = "sp-consensus-aura" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-application-crypto", + "sp-consensus-slots", + "sp-inherents", + "sp-runtime", + "sp-std", + "sp-timestamp", +] + +[[package]] +name = "sp-consensus-babe" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "parity-scale-codec", + "scale-info", + "serde", + "sp-api", + "sp-application-crypto", + "sp-consensus-slots", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-std", + "sp-timestamp", +] + +[[package]] +name = "sp-consensus-beefy" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "lazy_static", + "parity-scale-codec", + "scale-info", + "serde", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-mmr-primitives", + "sp-runtime", + "sp-std", + "strum", +] + +[[package]] +name = "sp-consensus-grandpa" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "finality-grandpa", + "log", + "parity-scale-codec", + "scale-info", + "serde", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-keystore", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "sp-consensus-slots" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-std", + "sp-timestamp", +] + +[[package]] +name = "sp-core" +version = "21.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "arrayvec 0.7.4", + "bandersnatch_vrfs", + "bitflags 1.3.2", + "blake2", + "bounded-collections", + "bs58", + "dyn-clonable", + "ed25519-zebra", + "futures", + "hash-db", + "hash256-std-hasher", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin 2.0.1", + "parity-scale-codec", + "parking_lot 0.12.1", + "paste", + "primitive-types", + "rand 0.8.5", + "regex", + "scale-info", + "schnorrkel", + "secp256k1", + "secrecy", + "serde", + "sp-core-hashing", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-std", + "sp-storage", + "ss58-registry", + "substrate-bip39", + "thiserror", + "tiny-bip39", + "tracing", + "zeroize", +] + +[[package]] +name = "sp-core-hashing" +version = "9.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "blake2b_simd", + "byteorder", + "digest 0.10.7", + "sha2 0.10.7", + "sha3", + "twox-hash", +] + +[[package]] +name = "sp-core-hashing-proc-macro" +version = "9.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "quote", + "sp-core-hashing", + "syn 2.0.28", +] + +[[package]] +name = "sp-database" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "kvdb", + "parking_lot 0.12.1", +] + +[[package]] +name = "sp-debug-derive" +version = "8.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "sp-externalities" +version = "0.19.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "environmental", + "parity-scale-codec", + "sp-std", + "sp-storage", +] + +[[package]] +name = "sp-genesis-builder" +version = "0.1.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "serde_json", + "sp-api", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "sp-inherents" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "impl-trait-for-tuples", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-std", + "thiserror", +] + +[[package]] +name = "sp-io" +version = "23.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "bytes", + "ed25519-dalek 2.0.0", + "libsecp256k1", + "log", + "parity-scale-codec", + "rustversion", + "secp256k1", + "sp-core", + "sp-externalities", + "sp-keystore", + "sp-runtime-interface", + "sp-state-machine", + "sp-std", + "sp-tracing", + "sp-trie", + "tracing", + "tracing-core", +] + +[[package]] +name = "sp-keyring" +version = "24.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "lazy_static", + "sp-core", + "sp-runtime", + "strum", +] + +[[package]] +name = "sp-keystore" +version = "0.27.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "parking_lot 0.12.1", + "sp-core", + "sp-externalities", + "thiserror", +] + +[[package]] +name = "sp-maybe-compressed-blob" +version = "4.1.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "thiserror", + "zstd 0.12.4", +] + +[[package]] +name = "sp-metadata-ir" +version = "0.1.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-metadata", + "parity-scale-codec", + "scale-info", + "sp-std", +] + +[[package]] +name = "sp-mmr-primitives" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "ckb-merkle-mountain-range", + "log", + "parity-scale-codec", + "scale-info", + "serde", + "sp-api", + "sp-core", + "sp-debug-derive", + "sp-runtime", + "sp-std", + "thiserror", +] + +[[package]] +name = "sp-npos-elections" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-arithmetic", + "sp-core", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "sp-offchain" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "sp-api", + "sp-core", + "sp-runtime", +] + +[[package]] +name = "sp-panic-handler" +version = "8.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "backtrace", + "lazy_static", + "regex", +] + +[[package]] +name = "sp-rpc" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "rustc-hash", + "serde", + "sp-core", +] + +[[package]] +name = "sp-runtime" +version = "24.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "either", + "hash256-std-hasher", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "paste", + "rand 0.8.5", + "scale-info", + "serde", + "sp-application-crypto", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-std", + "sp-weights", +] + +[[package]] +name = "sp-runtime-interface" +version = "17.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec", + "primitive-types", + "sp-externalities", + "sp-runtime-interface-proc-macro", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-wasm-interface", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "11.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "Inflector", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "sp-session" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-core", + "sp-keystore", + "sp-runtime", + "sp-staking", + "sp-std", +] + +[[package]] +name = "sp-staking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "sp-state-machine" +version = "0.28.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "hash-db", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "rand 0.8.5", + "smallvec", + "sp-core", + "sp-externalities", + "sp-panic-handler", + "sp-std", + "sp-trie", + "thiserror", + "tracing", + "trie-db", +] + +[[package]] +name = "sp-statement-store" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "aes-gcm 0.10.2", + "curve25519-dalek 4.0.0", + "ed25519-dalek 2.0.0", + "hkdf", + "parity-scale-codec", + "rand 0.8.5", + "scale-info", + "sha2 0.10.7", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-externalities", + "sp-runtime", + "sp-runtime-interface", + "sp-std", + "thiserror", + "x25519-dalek 2.0.0", +] + +[[package]] +name = "sp-std" +version = "8.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" + +[[package]] +name = "sp-storage" +version = "13.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "ref-cast", + "serde", + "sp-debug-derive", + "sp-std", +] + +[[package]] +name = "sp-timestamp" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "parity-scale-codec", + "sp-inherents", + "sp-runtime", + "sp-std", + "thiserror", +] + +[[package]] +name = "sp-tracing" +version = "10.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "sp-std", + "tracing", + "tracing-core", + "tracing-subscriber 0.2.25", +] + +[[package]] +name = "sp-transaction-pool" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "sp-api", + "sp-runtime", +] + +[[package]] +name = "sp-transaction-storage-proof" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-std", + "sp-trie", +] + +[[package]] +name = "sp-trie" +version = "22.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "ahash 0.8.3", + "hash-db", + "hashbrown 0.13.2", + "lazy_static", + "memory-db", + "nohash-hasher", + "parity-scale-codec", + "parking_lot 0.12.1", + "scale-info", + "schnellru", + "sp-core", + "sp-std", + "thiserror", + "tracing", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-version" +version = "22.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "parity-wasm", + "scale-info", + "serde", + "sp-core-hashing-proc-macro", + "sp-runtime", + "sp-std", + "sp-version-proc-macro", + "thiserror", +] + +[[package]] +name = "sp-version-proc-macro" +version = "8.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "sp-wasm-interface" +version = "14.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "anyhow", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "sp-std", + "wasmtime", +] + +[[package]] +name = "sp-weights" +version = "20.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "smallvec", + "sp-arithmetic", + "sp-core", + "sp-debug-derive", + "sp-std", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spinners" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08615eea740067d9899969bc2891c68a19c315cb1f66640af9a9ecb91b13bcab" +dependencies = [ + "lazy_static", + "maplit", + "strum", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.7", +] + +[[package]] +name = "ss58-registry" +version = "1.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfc443bad666016e012538782d9e3006213a7db43e9fb1dda91657dc06a6fa08" +dependencies = [ + "Inflector", + "num-format", + "proc-macro2", + "quote", + "serde", + "serde_json", + "unicode-xid", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "staking-miner" +version = "0.9.43" +dependencies = [ + "assert_cmd", + "clap 4.3.19", + "exitcode", + "frame-election-provider-support", + "frame-remote-externalities", + "frame-support", + "frame-system", + "futures-util", + "jsonrpsee", + "kusama-runtime", + "log", + "pallet-balances", + "pallet-election-provider-multi-phase", + "pallet-staking", + "pallet-transaction-payment", + "parity-scale-codec", + "paste", + "polkadot-core-primitives", + "polkadot-runtime", + "polkadot-runtime-common", + "sc-transaction-pool-api", + "serde", + "serde_json", + "signal-hook", + "signal-hook-tokio", + "sp-core", + "sp-npos-elections", + "sp-runtime", + "sp-state-machine", + "sp-version", + "sub-tokens", + "thiserror", + "tokio", + "tracing-subscriber 0.3.17", + "westend-runtime", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "static_init" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11b73400442027c4adedda20a9f9b7945234a5bd8d5f7e86da22bd5d0622369c" +dependencies = [ + "cfg_aliases", + "libc", + "parking_lot 0.11.2", + "static_init_macro 0.5.0", +] + +[[package]] +name = "static_init" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a2a1c578e98c1c16fc3b8ec1328f7659a500737d7a0c6d625e73e830ff9c1f6" +dependencies = [ + "bitflags 1.3.2", + "cfg_aliases", + "libc", + "parking_lot 0.11.2", + "parking_lot_core 0.8.6", + "static_init_macro 1.0.2", + "winapi", +] + +[[package]] +name = "static_init_macro" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2261c91034a1edc3fc4d1b80e89d82714faede0515c14a75da10cb941546bbf" +dependencies = [ + "cfg_aliases", + "memchr", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "static_init_macro" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a2595fc3aa78f2d0e45dd425b22282dd863273761cc77780914b2cf3003acf" +dependencies = [ + "cfg_aliases", + "memchr", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "stun" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7e94b1ec00bad60e6410e058b52f1c66de3dc5fe4d62d09b3e52bb7d3b73e25" +dependencies = [ + "base64 0.13.1", + "crc", + "lazy_static", + "md-5", + "rand 0.8.5", + "ring 0.16.20", + "subtle", + "thiserror", + "tokio", + "url", + "webrtc-util", +] + +[[package]] +name = "sub-tokens" +version = "0.1.0" +source = "git+https://github.com/paritytech/substrate-debug-kit?branch=master#e12503ab781e913735dc389865a3b8b4a6c6399d" +dependencies = [ + "separator", +] + +[[package]] +name = "substrate-bip39" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49eee6965196b32f882dd2ee85a92b1dbead41b04e53907f269de3b0dc04733c" +dependencies = [ + "hmac 0.11.0", + "pbkdf2 0.8.0", + "schnorrkel", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "substrate-build-script-utils" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" + +[[package]] +name = "substrate-frame-rpc-system" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "frame-system-rpc-runtime-api", + "futures", + "jsonrpsee", + "log", + "parity-scale-codec", + "sc-rpc-api", + "sc-transaction-pool-api", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-core", + "sp-runtime", +] + +[[package]] +name = "substrate-prometheus-endpoint" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "hyper", + "log", + "prometheus", + "thiserror", + "tokio", +] + +[[package]] +name = "substrate-rpc-client" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "jsonrpsee", + "log", + "sc-rpc-api", + "serde", + "sp-runtime", +] + +[[package]] +name = "substrate-state-trie-migration-rpc" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "jsonrpsee", + "parity-scale-codec", + "sc-client-api", + "sc-rpc-api", + "serde", + "sp-core", + "sp-runtime", + "sp-state-machine", + "sp-trie", + "trie-db", +] + +[[package]] +name = "substrate-test-client" +version = "2.0.1" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "array-bytes", + "async-trait", + "futures", + "parity-scale-codec", + "sc-client-api", + "sc-client-db", + "sc-consensus", + "sc-executor", + "sc-offchain", + "sc-service", + "serde", + "serde_json", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-keyring", + "sp-keystore", + "sp-runtime", + "sp-state-machine", +] + +[[package]] +name = "substrate-test-utils" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "futures", + "substrate-test-utils-derive", + "tokio", +] + +[[package]] +name = "substrate-test-utils-derive" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "substrate-wasm-builder" +version = "5.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "ansi_term", + "build-helper", + "cargo_metadata", + "filetime", + "parity-wasm", + "sp-maybe-compressed-blob", + "strum", + "tempfile", + "toml 0.7.6", + "walkdir", + "wasm-opt", +] + +[[package]] +name = "substring" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" +dependencies = [ + "autocfg", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "sval" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b031320a434d3e9477ccf9b5756d57d4272937b8d22cb88af80b7633a1b78b1" + +[[package]] +name = "sval_buffer" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bf7e9412af26b342f3f2cc5cc4122b0105e9d16eb76046cd14ed10106cf6028" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0ef628e8a77a46ed3338db8d1b08af77495123cc229453084e47cd716d403cf" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_ref" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703ca1942a984bd0d9b5a4c0a65ab8b4b794038d080af4eb303c71bc6bf22d7c" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830926cd0581f7c3e5d51efae4d35c6b6fc4db583842652891ba2f1bed8db046" +dependencies = [ + "serde", + "sval", + "sval_buffer", + "sval_fmt", +] + +[[package]] +name = "symbolic-common" +version = "10.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b55cdc318ede251d0957f07afe5fed912119b8c1bc5a7804151826db999e737" +dependencies = [ + "debugid", + "memmap2", + "stable_deref_trait", + "uuid", +] + +[[package]] +name = "symbolic-demangle" +version = "10.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79be897be8a483a81fff6a3a4e195b4ac838ef73ca42d348b3f722da9902e489" +dependencies = [ + "cpp_demangle 0.4.2", + "rustc-demangle", + "symbolic-common", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "target-lexicon" +version = "0.12.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" + +[[package]] +name = "tempfile" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +dependencies = [ + "cfg-if", + "fastrand 2.0.0", + "redox_syscall 0.3.5", + "rustix 0.38.6", + "windows-sys 0.48.0", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "termtree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" + +[[package]] +name = "test-parachain-adder" +version = "0.9.43" +dependencies = [ + "dlmalloc", + "parity-scale-codec", + "polkadot-parachain", + "sp-io", + "sp-std", + "substrate-wasm-builder", + "tiny-keccak", +] + +[[package]] +name = "test-parachain-adder-collator" +version = "0.9.43" +dependencies = [ + "clap 4.3.19", + "futures", + "futures-timer", + "log", + "parity-scale-codec", + "polkadot-cli", + "polkadot-node-core-pvf", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-service", + "polkadot-test-service", + "sc-cli", + "sc-service", + "sp-core", + "sp-keyring", + "substrate-test-utils", + "test-parachain-adder", + "test-parachain-adder-collator", + "tokio", +] + +[[package]] +name = "test-parachain-halt" +version = "0.9.43" +dependencies = [ + "rustversion", + "substrate-wasm-builder", +] + +[[package]] +name = "test-parachain-undying" +version = "0.9.43" +dependencies = [ + "dlmalloc", + "log", + "parity-scale-codec", + "polkadot-parachain", + "sp-io", + "sp-std", + "substrate-wasm-builder", + "tiny-keccak", +] + +[[package]] +name = "test-parachain-undying-collator" +version = "0.9.43" +dependencies = [ + "clap 4.3.19", + "futures", + "futures-timer", + "log", + "parity-scale-codec", + "polkadot-cli", + "polkadot-node-core-pvf", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-service", + "polkadot-test-service", + "sc-cli", + "sc-service", + "sp-core", + "sp-keyring", + "substrate-test-utils", + "test-parachain-undying", + "test-parachain-undying-collator", + "tokio", +] + +[[package]] +name = "test-parachains" +version = "0.9.43" +dependencies = [ + "parity-scale-codec", + "sp-core", + "test-parachain-adder", + "test-parachain-halt", + "tiny-keccak", +] + +[[package]] +name = "test-runtime-constants" +version = "0.9.43" +dependencies = [ + "frame-support", + "polkadot-primitives", + "polkadot-runtime-common", + "smallvec", + "sp-core", + "sp-runtime", + "sp-weights", +] + +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + +[[package]] +name = "thiserror" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "thousands" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "thrift" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b82ca8f46f95b3ce96081fe3dd89160fdea970c254bb72925255d1b62aae692e" +dependencies = [ + "byteorder", + "integer-encoding", + "log", + "ordered-float", + "threadpool", +] + +[[package]] +name = "tikv-jemalloc-ctl" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619bfed27d807b54f7f776b9430d4f8060e66ee138a28632ca898584d462c31c" +dependencies = [ + "libc", + "paste", + "tikv-jemalloc-sys", +] + +[[package]] +name = "tikv-jemalloc-sys" +version = "0.5.4+5.3.0-patched" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "tikv-jemallocator" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965fe0c26be5c56c94e38ba547249074803efd52adfb66de62107d95aab3eaca" +dependencies = [ + "libc", + "tikv-jemalloc-sys", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" +dependencies = [ + "deranged", + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-bip39" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" +dependencies = [ + "anyhow", + "hmac 0.12.1", + "once_cell", + "pbkdf2 0.11.0", + "rand 0.8.5", + "rustc-hash", + "sha2 0.10.7", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +dependencies = [ + "autocfg", + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite 0.2.10", + "signal-hook-registry", + "socket2 0.4.9", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "tokio-retry" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" +dependencies = [ + "pin-project", + "rand 0.8.5", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.8", + "tokio", + "webpki 0.22.0", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.6", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite 0.2.10", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite 0.2.10", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +dependencies = [ + "indexmap 2.0.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" +dependencies = [ + "bitflags 2.3.3", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite 0.2.10", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite 0.2.10", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-gum" +version = "0.9.43" +dependencies = [ + "coarsetime", + "polkadot-node-jaeger", + "polkadot-primitives", + "tracing", + "tracing-gum-proc-macro", +] + +[[package]] +name = "tracing-gum-proc-macro" +version = "0.9.43" +dependencies = [ + "assert_matches", + "expander 2.0.0", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers 0.0.1", + "parking_lot 0.11.2", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "matchers 0.1.0", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trie-db" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "767abe6ffed88a1889671a102c2861ae742726f52e0a5a425b92c9fbfa7e9c85" +dependencies = [ + "hash-db", + "hashbrown 0.13.2", + "log", + "rustc-hex", + "smallvec", +] + +[[package]] +name = "trie-root" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4ed310ef5ab98f5fa467900ed906cb9232dd5376597e00fd4cba2a449d06c0b" +dependencies = [ + "hash-db", +] + +[[package]] +name = "trust-dns-proto" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.2.3", + "ipnet", + "lazy_static", + "rand 0.8.5", + "smallvec", + "socket2 0.4.9", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lazy_static", + "lru-cache", + "parking_lot 0.12.1", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", + "trust-dns-proto", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "try-runtime-cli" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=master#51695bb7009ea2e0996eb94ab4dfdc643a076702" +dependencies = [ + "async-trait", + "clap 4.3.19", + "frame-remote-externalities", + "frame-try-runtime", + "hex", + "log", + "parity-scale-codec", + "sc-cli", + "sc-executor", + "serde", + "serde_json", + "sp-api", + "sp-consensus-aura", + "sp-consensus-babe", + "sp-core", + "sp-debug-derive", + "sp-externalities", + "sp-inherents", + "sp-io", + "sp-keystore", + "sp-rpc", + "sp-runtime", + "sp-state-machine", + "sp-timestamp", + "sp-transaction-storage-proof", + "sp-version", + "sp-weights", + "substrate-rpc-client", + "zstd 0.12.4", +] + +[[package]] +name = "trybuild" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84e0202ea606ba5ebee8507ab2bfbe89b98551ed9b8f0be198109275cff284b" +dependencies = [ + "basic-toml", + "dissimilar", + "glob", + "once_cell", + "serde", + "serde_derive", + "serde_json", + "termcolor", +] + +[[package]] +name = "tt-call" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f195fd851901624eee5a58c4bb2b4f06399148fcd0ed336e6f1cb60a9881df" + +[[package]] +name = "tungstenite" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand 0.8.5", + "sha-1 0.10.1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "turn" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4712ee30d123ec7ae26d1e1b218395a16c87cdbaf4b3925d170d684af62ea5e8" +dependencies = [ + "async-trait", + "base64 0.13.1", + "futures", + "log", + "md-5", + "rand 0.8.5", + "ring 0.16.20", + "stun", + "thiserror", + "tokio", + "webrtc-util", +] + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "digest 0.10.7", + "rand 0.8.5", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array 0.14.7", + "subtle", +] + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "unsigned-varint" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" +dependencies = [ + "asynchronous-codec", + "bytes", + "futures-io", + "futures-util", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +dependencies = [ + "form_urlencoded", + "idna 0.4.0", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "value-bag" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0b9f3feef403a50d4d67e9741a6d8fc688bcbb4e4f31bd4aab72cc690284394" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b24f4146b6f3361e91cbf527d1fb35e9376c3c0cef72ca5ec5af6d640fad7d" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "waitgroup" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1f50000a783467e6c0200f9d10642f4bc424e39efc1b770203e88b488f79292" +dependencies = [ + "atomic-waker", +] + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "serde", + "serde_json", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.28", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "wasm-instrument" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa1dafb3e60065305741e83db35c6c2584bb3725b692b5b66148a38d72ace6cd" +dependencies = [ + "parity-wasm", +] + +[[package]] +name = "wasm-opt" +version = "0.114.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d005a95f934878a1fb446a816d51c3601a0120ff929005ba3bab3c749cfd1c7" +dependencies = [ + "anyhow", + "libc", + "strum", + "strum_macros", + "tempfile", + "thiserror", + "wasm-opt-cxx-sys", + "wasm-opt-sys", +] + +[[package]] +name = "wasm-opt-cxx-sys" +version = "0.114.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d04e240598162810fad3b2e96fa0dec6dba1eb65a03f3bd99a9248ab8b56caa" +dependencies = [ + "anyhow", + "cxx", + "cxx-build", + "wasm-opt-sys", +] + +[[package]] +name = "wasm-opt-sys" +version = "0.114.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2efd2aaca519d64098c4faefc8b7433a97ed511caf4c9e516384eb6aef1ff4f9" +dependencies = [ + "anyhow", + "cc", + "cxx", + "cxx-build", +] + +[[package]] +name = "wasm-timer" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.11.2", + "pin-utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasmparser" +version = "0.102.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48134de3d7598219ab9eaf6b91b15d8e50d31da76b8519fe4ecfcec2cf35104b" +dependencies = [ + "indexmap 1.9.3", + "url", +] + +[[package]] +name = "wasmtime" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f907fdead3153cb9bfb7a93bbd5b62629472dc06dee83605358c64c52ed3dda9" +dependencies = [ + "anyhow", + "bincode", + "cfg-if", + "indexmap 1.9.3", + "libc", + "log", + "object 0.30.4", + "once_cell", + "paste", + "psm", + "rayon", + "serde", + "target-lexicon", + "wasmparser", + "wasmtime-cache", + "wasmtime-cranelift", + "wasmtime-environ", + "wasmtime-jit", + "wasmtime-runtime", + "windows-sys 0.45.0", +] + +[[package]] +name = "wasmtime-asm-macros" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b9daa7c14cd4fa3edbf69de994408d5f4b7b0959ac13fa69d465f6597f810d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "wasmtime-cache" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86437fa68626fe896e5afc69234bb2b5894949083586535f200385adfd71213" +dependencies = [ + "anyhow", + "base64 0.21.2", + "bincode", + "directories-next", + "file-per-thread-logger", + "log", + "rustix 0.36.15", + "serde", + "sha2 0.10.7", + "toml 0.5.11", + "windows-sys 0.45.0", + "zstd 0.11.2+zstd.1.5.2", +] + +[[package]] +name = "wasmtime-cranelift" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1cefde0cce8cb700b1b21b6298a3837dba46521affd7b8c38a9ee2c869eee04" +dependencies = [ + "anyhow", + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "cranelift-wasm", + "gimli", + "log", + "object 0.30.4", + "target-lexicon", + "thiserror", + "wasmparser", + "wasmtime-cranelift-shared", + "wasmtime-environ", +] + +[[package]] +name = "wasmtime-cranelift-shared" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd041e382ef5aea1b9fc78442394f1a4f6d676ce457e7076ca4cb3f397882f8b" +dependencies = [ + "anyhow", + "cranelift-codegen", + "cranelift-native", + "gimli", + "object 0.30.4", + "target-lexicon", + "wasmtime-environ", +] + +[[package]] +name = "wasmtime-environ" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a990198cee4197423045235bf89d3359e69bd2ea031005f4c2d901125955c949" +dependencies = [ + "anyhow", + "cranelift-entity", + "gimli", + "indexmap 1.9.3", + "log", + "object 0.30.4", + "serde", + "target-lexicon", + "thiserror", + "wasmparser", + "wasmtime-types", +] + +[[package]] +name = "wasmtime-jit" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de48df552cfca1c9b750002d3e07b45772dd033b0b206d5c0968496abf31244" +dependencies = [ + "addr2line 0.19.0", + "anyhow", + "bincode", + "cfg-if", + "cpp_demangle 0.3.5", + "gimli", + "log", + "object 0.30.4", + "rustc-demangle", + "serde", + "target-lexicon", + "wasmtime-environ", + "wasmtime-jit-debug", + "wasmtime-jit-icache-coherence", + "wasmtime-runtime", + "windows-sys 0.45.0", +] + +[[package]] +name = "wasmtime-jit-debug" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0554b84c15a27d76281d06838aed94e13a77d7bf604bbbaf548aa20eb93846" +dependencies = [ + "object 0.30.4", + "once_cell", + "rustix 0.36.15", +] + +[[package]] +name = "wasmtime-jit-icache-coherence" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aecae978b13f7f67efb23bd827373ace4578f2137ec110bbf6a4a7cde4121bbd" +dependencies = [ + "cfg-if", + "libc", + "windows-sys 0.45.0", +] + +[[package]] +name = "wasmtime-runtime" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658cf6f325232b6760e202e5255d823da5e348fdea827eff0a2a22319000b441" +dependencies = [ + "anyhow", + "cc", + "cfg-if", + "indexmap 1.9.3", + "libc", + "log", + "mach", + "memfd", + "memoffset 0.8.0", + "paste", + "rand 0.8.5", + "rustix 0.36.15", + "wasmtime-asm-macros", + "wasmtime-environ", + "wasmtime-jit-debug", + "windows-sys 0.45.0", +] + +[[package]] +name = "wasmtime-types" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4f6fffd2a1011887d57f07654dd112791e872e3ff4a2e626aee8059ee17f06f" +dependencies = [ + "cranelift-entity", + "serde", + "thiserror", + "wasmparser", +] + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring 0.16.20", + "untrusted", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring 0.16.20", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki 0.22.0", +] + +[[package]] +name = "webrtc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3bc9049bdb2cea52f5fd4f6f728184225bdb867ed0dc2410eab6df5bdd67bb" +dependencies = [ + "arc-swap", + "async-trait", + "bytes", + "hex", + "interceptor", + "lazy_static", + "log", + "rand 0.8.5", + "rcgen 0.9.3", + "regex", + "ring 0.16.20", + "rtcp", + "rtp", + "rustls 0.19.1", + "sdp", + "serde", + "serde_json", + "sha2 0.10.7", + "stun", + "thiserror", + "time 0.3.25", + "tokio", + "turn", + "url", + "waitgroup", + "webrtc-data", + "webrtc-dtls", + "webrtc-ice", + "webrtc-mdns", + "webrtc-media", + "webrtc-sctp", + "webrtc-srtp", + "webrtc-util", +] + +[[package]] +name = "webrtc-data" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef36a4d12baa6e842582fe9ec16a57184ba35e1a09308307b67d43ec8883100" +dependencies = [ + "bytes", + "derive_builder", + "log", + "thiserror", + "tokio", + "webrtc-sctp", + "webrtc-util", +] + +[[package]] +name = "webrtc-dtls" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942be5bd85f072c3128396f6e5a9bfb93ca8c1939ded735d177b7bcba9a13d05" +dependencies = [ + "aes 0.6.0", + "aes-gcm 0.10.2", + "async-trait", + "bincode", + "block-modes", + "byteorder", + "ccm", + "curve25519-dalek 3.2.0", + "der-parser 8.2.0", + "elliptic-curve 0.12.3", + "hkdf", + "hmac 0.12.1", + "log", + "oid-registry 0.6.1", + "p256", + "p384", + "rand 0.8.5", + "rand_core 0.6.4", + "rcgen 0.9.3", + "ring 0.16.20", + "rustls 0.19.1", + "sec1 0.3.0", + "serde", + "sha1", + "sha2 0.10.7", + "signature 1.6.4", + "subtle", + "thiserror", + "tokio", + "webpki 0.21.4", + "webrtc-util", + "x25519-dalek 2.0.0", + "x509-parser 0.13.2", +] + +[[package]] +name = "webrtc-ice" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465a03cc11e9a7d7b4f9f99870558fe37a102b65b93f8045392fef7c67b39e80" +dependencies = [ + "arc-swap", + "async-trait", + "crc", + "log", + "rand 0.8.5", + "serde", + "serde_json", + "stun", + "thiserror", + "tokio", + "turn", + "url", + "uuid", + "waitgroup", + "webrtc-mdns", + "webrtc-util", +] + +[[package]] +name = "webrtc-mdns" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f08dfd7a6e3987e255c4dbe710dde5d94d0f0574f8a21afa95d171376c143106" +dependencies = [ + "log", + "socket2 0.4.9", + "thiserror", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-media" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f72e1650a8ae006017d1a5280efb49e2610c19ccc3c0905b03b648aee9554991" +dependencies = [ + "byteorder", + "bytes", + "rand 0.8.5", + "rtp", + "thiserror", +] + +[[package]] +name = "webrtc-sctp" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d47adcd9427eb3ede33d5a7f3424038f63c965491beafcc20bc650a2f6679c0" +dependencies = [ + "arc-swap", + "async-trait", + "bytes", + "crc", + "log", + "rand 0.8.5", + "thiserror", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-srtp" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6183edc4c1c6c0175f8812eefdce84dfa0aea9c3ece71c2bf6ddd3c964de3da5" +dependencies = [ + "aead 0.4.3", + "aes 0.7.5", + "aes-gcm 0.9.4", + "async-trait", + "byteorder", + "bytes", + "ctr 0.8.0", + "hmac 0.11.0", + "log", + "rtcp", + "rtp", + "sha-1 0.9.8", + "subtle", + "thiserror", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-util" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f1db1727772c05cf7a2cfece52c3aca8045ca1e176cd517d323489aa3c6d87" +dependencies = [ + "async-trait", + "bitflags 1.3.2", + "bytes", + "cc", + "ipnet", + "lazy_static", + "libc", + "log", + "nix 0.24.3", + "rand 0.8.5", + "thiserror", + "tokio", + "winapi", +] + +[[package]] +name = "westend-runtime" +version = "0.9.43" +dependencies = [ + "binary-merkle-tree", + "bitvec", + "frame-benchmarking", + "frame-election-provider-support", + "frame-executive", + "frame-remote-externalities", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "frame-try-runtime", + "hex-literal 0.4.1", + "log", + "pallet-authority-discovery", + "pallet-authorship", + "pallet-babe", + "pallet-bags-list", + "pallet-balances", + "pallet-beefy", + "pallet-beefy-mmr", + "pallet-collective", + "pallet-democracy", + "pallet-election-provider-multi-phase", + "pallet-election-provider-support-benchmarking", + "pallet-elections-phragmen", + "pallet-fast-unstake", + "pallet-grandpa", + "pallet-identity", + "pallet-im-online", + "pallet-indices", + "pallet-membership", + "pallet-message-queue", + "pallet-mmr", + "pallet-multisig", + "pallet-nomination-pools", + "pallet-nomination-pools-benchmarking", + "pallet-nomination-pools-runtime-api", + "pallet-offences", + "pallet-offences-benchmarking", + "pallet-preimage", + "pallet-proxy", + "pallet-recovery", + "pallet-scheduler", + "pallet-session", + "pallet-session-benchmarking", + "pallet-society", + "pallet-staking", + "pallet-staking-reward-curve", + "pallet-staking-runtime-api", + "pallet-state-trie-migration", + "pallet-sudo", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-treasury", + "pallet-utility", + "pallet-vesting", + "pallet-xcm", + "pallet-xcm-benchmarks", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-runtime-common", + "polkadot-runtime-parachains", + "rustc-hex", + "scale-info", + "serde", + "serde_derive", + "serde_json", + "smallvec", + "sp-api", + "sp-application-crypto", + "sp-authority-discovery", + "sp-block-builder", + "sp-consensus-babe", + "sp-consensus-beefy", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-mmr-primitives", + "sp-npos-elections", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-transaction-pool", + "sp-version", + "substrate-wasm-builder", + "tiny-keccak", + "tokio", + "westend-runtime-constants", + "xcm", + "xcm-builder", + "xcm-executor", +] + +[[package]] +name = "westend-runtime-constants" +version = "0.9.43" +dependencies = [ + "frame-support", + "polkadot-primitives", + "polkadot-runtime-common", + "smallvec", + "sp-core", + "sp-runtime", + "sp-weights", +] + +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + +[[package]] +name = "wide" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa469ffa65ef7e0ba0f164183697b89b854253fd31aeb92358b7b6155177d62f" +dependencies = [ + "bytemuck", + "safe_arch", +] + +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45296b64204227616fdbf2614cefa4c236b98ee64dfaaaa435207ed99fe7829f" +dependencies = [ + "windows_aarch64_msvc 0.34.0", + "windows_i686_gnu 0.34.0", + "windows_i686_msvc 0.34.0", + "windows_x86_64_gnu 0.34.0", + "windows_x86_64_msvc 0.34.0", +] + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.1", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46aab759304e4d7b2075a9aecba26228bb073ee8c50db796b2c72c676b5d807" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek 3.2.0", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "x25519-dalek" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" +dependencies = [ + "curve25519-dalek 4.0.0", + "rand_core 0.6.4", + "serde", + "zeroize", +] + +[[package]] +name = "x509-parser" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9bace5b5589ffead1afb76e43e34cff39cd0f3ce7e170ae0c29e53b88eb1c" +dependencies = [ + "asn1-rs 0.3.1", + "base64 0.13.1", + "data-encoding", + "der-parser 7.0.0", + "lazy_static", + "nom", + "oid-registry 0.4.0", + "ring 0.16.20", + "rusticata-macros", + "thiserror", + "time 0.3.25", +] + +[[package]] +name = "x509-parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" +dependencies = [ + "asn1-rs 0.5.2", + "base64 0.13.1", + "data-encoding", + "der-parser 8.2.0", + "lazy_static", + "nom", + "oid-registry 0.6.1", + "rusticata-macros", + "thiserror", + "time 0.3.25", +] + +[[package]] +name = "xcm" +version = "0.9.43" +dependencies = [ + "bounded-collections", + "derivative", + "hex", + "hex-literal 0.4.1", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "scale-info", + "serde", + "sp-io", + "sp-weights", + "xcm-procedural", +] + +[[package]] +name = "xcm-builder" +version = "0.9.43" +dependencies = [ + "assert_matches", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "log", + "pallet-assets", + "pallet-balances", + "pallet-salary", + "pallet-transaction-payment", + "pallet-xcm", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-runtime-parachains", + "polkadot-test-runtime", + "primitive-types", + "scale-info", + "sp-arithmetic", + "sp-io", + "sp-runtime", + "sp-std", + "sp-weights", + "xcm", + "xcm-executor", +] + +[[package]] +name = "xcm-executor" +version = "0.9.43" +dependencies = [ + "environmental", + "frame-benchmarking", + "frame-support", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-weights", + "xcm", +] + +[[package]] +name = "xcm-executor-integration-tests" +version = "0.9.43" +dependencies = [ + "frame-support", + "frame-system", + "futures", + "pallet-xcm", + "parity-scale-codec", + "polkadot-test-client", + "polkadot-test-runtime", + "polkadot-test-service", + "sp-consensus", + "sp-keyring", + "sp-runtime", + "sp-state-machine", + "sp-tracing", + "xcm", + "xcm-executor", +] + +[[package]] +name = "xcm-procedural" +version = "0.9.43" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "xcm-simulator" +version = "0.9.43" +dependencies = [ + "frame-support", + "parity-scale-codec", + "paste", + "polkadot-core-primitives", + "polkadot-parachain", + "polkadot-runtime-parachains", + "sp-io", + "sp-std", + "xcm", + "xcm-builder", + "xcm-executor", +] + +[[package]] +name = "xcm-simulator-example" +version = "0.9.43" +dependencies = [ + "frame-support", + "frame-system", + "log", + "pallet-balances", + "pallet-message-queue", + "pallet-uniques", + "pallet-xcm", + "parity-scale-codec", + "polkadot-core-primitives", + "polkadot-parachain", + "polkadot-runtime-parachains", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", + "xcm", + "xcm-builder", + "xcm-executor", + "xcm-simulator", +] + +[[package]] +name = "xcm-simulator-fuzzer" +version = "0.9.43" +dependencies = [ + "arbitrary", + "frame-support", + "frame-system", + "honggfuzz", + "pallet-balances", + "pallet-message-queue", + "pallet-xcm", + "parity-scale-codec", + "polkadot-core-primitives", + "polkadot-parachain", + "polkadot-runtime-parachains", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "xcm", + "xcm-builder", + "xcm-executor", + "xcm-simulator", +] + +[[package]] +name = "yamux" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d9ba232399af1783a58d8eb26f6b5006fbefe2dc9ef36bd283324792d03ea5" +dependencies = [ + "futures", + "log", + "nohash-hasher", + "parking_lot 0.12.1", + "rand 0.8.5", + "static_assertions", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time 0.3.25", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "zombienet-backchannel" +version = "0.9.43" +dependencies = [ + "futures-util", + "lazy_static", + "parity-scale-codec", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing-gum", + "url", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe 5.0.2+zstd.1.5.2", +] + +[[package]] +name = "zstd" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +dependencies = [ + "zstd-safe 6.0.6", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-safe" +version = "6.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.8+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +dependencies = [ + "cc", + "libc", + "pkg-config", +] diff --git a/polkadot/Cargo.toml b/polkadot/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..c1b94357c3cdfc7bcf5ed4009474743aa4562d35 --- /dev/null +++ b/polkadot/Cargo.toml @@ -0,0 +1,256 @@ +[[bin]] +name = "polkadot" +path = "src/main.rs" + +[[bin]] +name = "polkadot-execute-worker" +path = "src/bin/execute-worker.rs" + +[[bin]] +name = "polkadot-prepare-worker" +path = "src/bin/prepare-worker.rs" + +[package] +name = "polkadot" +description = "Implementation of a `https://polkadot.network` node in Rust based on the Substrate framework." +rust-version = "1.64.0" # workspace properties +readme = "README.md" +default-run = "polkadot" +authors.workspace = true +edition.workspace = true +license.workspace = true +version.workspace = true + +[workspace.package] +authors = ["Parity Technologies "] +edition = "2021" +license = "GPL-3.0-only" +repository = "https://github.com/paritytech/polkadot.git" +version = "0.9.43" + +[dependencies] +color-eyre = { version = "0.6.1", default-features = false } +tikv-jemallocator = "0.5.0" + +# Crates in our workspace, defined as dependencies so we can pass them feature flags. +polkadot-cli = { path = "cli", features = [ "polkadot-native", "kusama-native", "westend-native", "rococo-native" ] } +polkadot-node-core-pvf = { path = "node/core/pvf" } +polkadot-node-core-pvf-prepare-worker = { path = "node/core/pvf/prepare-worker" } +polkadot-overseer = { path = "node/overseer" } + +# Needed for worker binaries. +polkadot-node-core-pvf-common = { path = "node/core/pvf/common", features = ["test-utils"] } +polkadot-node-core-pvf-execute-worker = { path = "node/core/pvf/execute-worker" } + +[dev-dependencies] +assert_cmd = "2.0.4" +nix = { version = "0.26.1", features = ["signal"] } +tempfile = "3.2.0" +tokio = "1.24.2" +substrate-rpc-client = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot-core-primitives = { path = "core-primitives" } + +[build-dependencies] +substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[workspace] +members = [ + "cli", + "core-primitives", + "erasure-coding", + "erasure-coding/fuzzer", + "primitives", + "primitives/test-helpers", + "runtime/common", + "runtime/common/slot_range_helper", + "runtime/metrics", + "runtime/parachains", + "runtime/polkadot", + "runtime/polkadot/constants", + "runtime/kusama", + "runtime/kusama/constants", + "runtime/rococo", + "runtime/rococo/constants", + "runtime/westend", + "runtime/westend/constants", + "runtime/test-runtime", + "runtime/test-runtime/constants", + "statement-table", + "xcm", + "xcm/xcm-builder", + "xcm/xcm-executor", + "xcm/xcm-executor/integration-tests", + "xcm/xcm-simulator", + "xcm/xcm-simulator/example", + "xcm/xcm-simulator/fuzzer", + "xcm/pallet-xcm", + "xcm/pallet-xcm-benchmarks", + "xcm/procedural", + "node/collation-generation", + "node/core/approval-voting", + "node/core/av-store", + "node/core/backing", + "node/core/bitfield-signing", + "node/core/candidate-validation", + "node/core/chain-api", + "node/core/chain-selection", + "node/core/dispute-coordinator", + "node/core/parachains-inherent", + "node/core/prospective-parachains", + "node/core/provisioner", + "node/core/pvf", + "node/core/pvf/common", + "node/core/pvf/execute-worker", + "node/core/pvf/prepare-worker", + "node/core/pvf-checker", + "node/core/runtime-api", + "node/network/approval-distribution", + "node/network/bridge", + "node/network/protocol", + "node/network/statement-distribution", + "node/network/bitfield-distribution", + "node/network/availability-distribution", + "node/network/availability-recovery", + "node/network/collator-protocol", + "node/network/gossip-support", + "node/network/dispute-distribution", + "node/overseer", + "node/malus", + "node/primitives", + "node/service", + "node/subsystem", + "node/subsystem-types", + "node/subsystem-test-helpers", + "node/subsystem-util", + "node/jaeger", + "node/gum", + "node/gum/proc-macro", + "node/metrics", + "node/test/client", + "node/test/performance-test", + "node/test/service", + "node/zombienet-backchannel", + "rpc", + "parachain", + "parachain/test-parachains", + "parachain/test-parachains/adder", + "parachain/test-parachains/adder/collator", + "parachain/test-parachains/halt", + "parachain/test-parachains/undying", + "parachain/test-parachains/undying/collator", + "utils/staking-miner", + "utils/remote-ext-tests/bags-list", + "utils/generate-bags", +] + +[badges] +maintenance = { status = "actively-developed" } + +# The list of dependencies below (which can be both direct and indirect dependencies) are crates +# that are suspected to be CPU-intensive, and that are unlikely to require debugging (as some of +# their debug info might be missing) or to require to be frequently recompiled. We compile these +# dependencies with `opt-level=3` even in "dev" mode in order to make "dev" mode more usable. +# The majority of these crates are cryptographic libraries. +# +# If you see an error mentioning "profile package spec ... did not match any packages", it +# probably concerns this list. +# +# This list is ordered alphabetically. +[profile.dev.package] +blake2 = { opt-level = 3 } +blake2b_simd = { opt-level = 3 } +chacha20poly1305 = { opt-level = 3 } +cranelift-codegen = { opt-level = 3 } +cranelift-wasm = { opt-level = 3 } +crc32fast = { opt-level = 3 } +crossbeam-deque = { opt-level = 3 } +crypto-mac = { opt-level = 3 } +curve25519-dalek = { opt-level = 3 } +ed25519-dalek = { opt-level = 3 } +futures-channel = { opt-level = 3 } +hash-db = { opt-level = 3 } +hashbrown = { opt-level = 3 } +hmac = { opt-level = 3 } +httparse = { opt-level = 3 } +integer-sqrt = { opt-level = 3 } +keccak = { opt-level = 3 } +libm = { opt-level = 3 } +librocksdb-sys = { opt-level = 3 } +libsecp256k1 = { opt-level = 3 } +libz-sys = { opt-level = 3 } +mio = { opt-level = 3 } +nalgebra = { opt-level = 3 } +num-bigint = { opt-level = 3 } +parking_lot = { opt-level = 3 } +parking_lot_core = { opt-level = 3 } +percent-encoding = { opt-level = 3 } +primitive-types = { opt-level = 3 } +reed-solomon-novelpoly = { opt-level = 3 } +ring = { opt-level = 3 } +rustls = { opt-level = 3 } +sha2 = { opt-level = 3 } +sha3 = { opt-level = 3 } +smallvec = { opt-level = 3 } +snow = { opt-level = 3 } +substrate-bip39 = {opt-level = 3} +twox-hash = { opt-level = 3 } +uint = { opt-level = 3 } +x25519-dalek = { opt-level = 3 } +yamux = { opt-level = 3 } +zeroize = { opt-level = 3 } + +[profile.release] +# Polkadot runtime requires unwinding. +panic = "unwind" +opt-level = 3 + +# make sure dev builds with backtrace do +# not slow us down +[profile.dev.package.backtrace] +inherits = "release" + +[profile.production] +inherits = "release" +lto = true +codegen-units = 1 + +[profile.testnet] +inherits = "release" +debug = 1 # debug symbols are useful for profilers +debug-assertions = true +overflow-checks = true + +[features] +runtime-benchmarks= [ "polkadot-cli/runtime-benchmarks" ] +try-runtime = [ "polkadot-cli/try-runtime" ] +fast-runtime = [ "polkadot-cli/fast-runtime" ] +runtime-metrics = [ "polkadot-cli/runtime-metrics" ] +pyroscope = ["polkadot-cli/pyroscope"] +jemalloc-allocator = ["polkadot-node-core-pvf-prepare-worker/jemalloc-allocator", "polkadot-overseer/jemalloc-allocator"] +network-protocol-staging = ["polkadot-cli/network-protocol-staging"] + +# Enables timeout-based tests supposed to be run only in CI environment as they may be flaky +# when run locally depending on system load +ci-only-tests = ["polkadot-node-core-pvf/ci-only-tests"] + +# Configuration for building a .deb package - for use with `cargo-deb` +[package.metadata.deb] +name = "polkadot" +extended-description = "Implementation of a https://polkadot.network node in Rust based on the Substrate framework." +section = "misc" +maintainer = "security@parity.io" +license-file = ["LICENSE", "0"] +# https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html +maintainer-scripts = "scripts/packaging/deb-maintainer-scripts" +assets = [ + ["target/release/polkadot", "/usr/bin/", "755"], + ["target/release/polkadot-prepare-worker", "/usr/lib/polkadot/", "755"], + ["target/release/polkadot-execute-worker", "/usr/lib/polkadot/", "755"], + ["scripts/packaging/polkadot.service", "/lib/systemd/system/", "644"] +] +conf-files = [ + "/etc/default/polkadot" +] + +[package.metadata.spellcheck] +config = "./scripts/ci/gitlab/spellcheck.toml" diff --git a/polkadot/LICENSE b/polkadot/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..733c072369ca77331f392c40da7404c85c36542c --- /dev/null +++ b/polkadot/LICENSE @@ -0,0 +1,675 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + diff --git a/polkadot/README.md b/polkadot/README.md new file mode 100644 index 0000000000000000000000000000000000000000..59e0cff015d39c5d3bdbdb83668b81ab019a4112 --- /dev/null +++ b/polkadot/README.md @@ -0,0 +1,13 @@ +Dear contributors and users, + +We would like to inform you that we have recently made significant changes to our repository structure. In order to streamline our development process and foster better contributions, we have merged three separate repositories Cumulus, Substrate and Polkadot into a single new repository: [the Polkadot SDK](https://github.com/paritytech/polkadot-sdk). Go ahead and make sure to support us by giving a star ⭐️ to the new repo. + +By consolidating our codebase, we aim to enhance collaboration and provide a more efficient platform for future development. + +If you currently have an open pull request in any of the merged repositories, we kindly request that you resubmit your PR in the new repository. This will ensure that your contributions are considered within the updated context and enable us to review and merge them more effectively. + +We appreciate your understanding and ongoing support throughout this transition. Should you have any questions or require further assistance, please don't hesitate to [reach out to us](https://forum.polkadot.network/t/psa-parity-is-currently-working-on-merging-the-polkadot-stack-repositories-into-one-single-repository/2883). + +Best Regards, + +Parity Technologies \ No newline at end of file diff --git a/polkadot/RELEASE.md b/polkadot/RELEASE.md new file mode 100644 index 0000000000000000000000000000000000000000..937c1e6e515fba0c523fec02b845365934a105fe --- /dev/null +++ b/polkadot/RELEASE.md @@ -0,0 +1,57 @@ +Polkadot Release Process +------------------------ + +### Branches +* release-candidate branch: The branch used for staging of the next release. + Named like `release-v0.8.26` + +### Notes +* The release-candidate branch *must* be made in the paritytech/polkadot repo in +order for release automation to work correctly +* Any new pushes/merges to the release-candidate branch (for example, +refs/heads/release-v0.8.26) will result in the rc index being bumped (e.g., v0.8.26-rc1 +to v0.8.26-rc2) and new wasms built. + +### Release workflow + +Below are the steps of the release workflow. Steps prefixed with NOACTION are +automated and require no human action. + +1. To initiate the release process: + 1. branch master off to a release candidate branch: + - `git checkout master; git pull; git checkout -b release-v0.8.26` + 2. In the [substrate](https://github.com/paritytech/substrate) repo, check out the commit used by polkadot (this can be found using the following command in the *polkadot* repo: `grep 'paritytech/substrate' Cargo.lock | grep -E '[0-9a-f]{40}' | sort | uniq ` + 3. Branch off this **substrate** commit into its own branch: `git branch -b polkadot-v0.8.26; git push origin refs/heads/polkadot-v0.8.26` + 4. In the **polkadot** repository, use [diener](https://github.com/bkchr/diener/) to switch to this branch: `diener update --branch "polkadot-v0.8.26" --substrate`. Update Cargo.lock (to do this, you can run `cargo build` and then ctrl+c once it finishes fetching and begins compiling) + 5. Push the **polkadot** `release-v0.8.26` branch to Github: `git push origin refs/heads/release-v0.8.26` +2. NOACTION: The current HEAD of the release-candidate branch is tagged `v0.8.26-rc1` +3. NOACTION: A draft release and runtime WASMs are created for this + release-candidate automatically. A link to the draft release will be linked in + the internal polkadot matrix channel. +4. NOACTION: A new Github issue is created containing a checklist of manual + steps to be completed before we are confident with the release. This will be + linked in Matrix. +5. Complete the steps in the issue created in step 4, signing them off as + completed +6. (optional) If a fix is required to the release-candidate: + 1. Merge the fix with `master` first + 2. Cherry-pick the commit from `master` to `release-v0.8.26`, fixing any + merge conflicts. Try to avoid unnecessarily bumping crates. + 3. Push the release-candidate branch to Github - this is now the new release- + candidate + 4. Depending on the cherry-picked changes, it may be necessary to perform some + or all of the manual tests again. + 5. If there are **substrate** changes required, these should be cherry-picked to the substrate `polkadot-v0.8.26` branch and pushed, and the version of substrate used in **polkadot** updated using `cargo update -p sp-io` +7. Once happy with the release-candidate, tag the current top commit in the release candidate branch and push to Github: `git tag -s -m 'v0.8.26' v0.8.26; git push --tags` +9. NOACTION: The HEAD of the `release` branch will be tagged with `v0.8.26`, + and a final draft release will be created on Github. + +### Security releases + +Occasionally there may be changes that need to be made to the most recently +released version of Polkadot, without taking *every* change to `master` since +the last release. For example, in the event of a security vulnerability being +found, where releasing a fixed version is a matter of some expediency. In cases +like this, the fix should first be merged with master, cherry-picked to a branch +forked from `release`, tested, and then finally merged with `release`. A +sensible versioning scheme for changes like this is `vX.Y.Z-1`. diff --git a/polkadot/SECURITY.md b/polkadot/SECURITY.md new file mode 100644 index 0000000000000000000000000000000000000000..db81bcaab4d0474a5ee635399b2a594d094224bd --- /dev/null +++ b/polkadot/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 sent 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/polkadot/build.rs b/polkadot/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..84fe22e23ed6f1a2e1d68a0194c41d23eb75b76c --- /dev/null +++ b/polkadot/build.rs @@ -0,0 +1,22 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +fn main() { + substrate_build_script_utils::generate_cargo_keys(); + // For the node/worker version check, make sure we always rebuild the node and binary workers + // when the version changes. + substrate_build_script_utils::rerun_if_git_head_changed(); +} diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..9846bc4cf66ee21cfe00f0c0eedc5cf71341fe81 --- /dev/null +++ b/polkadot/cli/Cargo.toml @@ -0,0 +1,78 @@ +[package] +name = "polkadot-cli" +description = "Polkadot Relay-chain Client Node" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[package.metadata.wasm-pack.profile.release] +# `wasm-opt` has some problems on Linux, see +# https://github.com/rustwasm/wasm-pack/issues/781 etc. +wasm-opt = false + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +clap = { version = "4.0.9", features = ["derive"], optional = true } +log = "0.4.17" +thiserror = "1.0.31" +futures = "0.3.21" +pyro = { package = "pyroscope", version = "0.5.3", optional = true } +pyroscope_pprofrs = { version = "0.2", optional = true } + +service = { package = "polkadot-service", path = "../node/service", default-features = false, optional = true } +polkadot-performance-test = { path = "../node/test/performance-test", optional = true } + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-maybe-compressed-blob = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true } +try-runtime-cli = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true } +polkadot-node-metrics = { path = "../node/metrics" } +sc-tracing = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true } +sc-sysinfo = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-storage-monitor = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[build-dependencies] +substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = ["db", "cli", "full-node"] +db = ["service/db"] +cli = [ + "clap", + "sc-cli", + "sc-service", + "sc-tracing", + "frame-benchmarking-cli", + "try-runtime-cli", + "service", +] +runtime-benchmarks = [ + "service/runtime-benchmarks", + "polkadot-node-metrics/runtime-benchmarks", + "polkadot-performance-test?/runtime-benchmarks" +] +full-node = ["service/full-node"] +try-runtime = ["service/try-runtime", "try-runtime-cli/try-runtime"] +fast-runtime = ["service/fast-runtime"] +pyroscope = ["pyro", "pyroscope_pprofrs"] +hostperfcheck = ["polkadot-performance-test"] + +# Configure the native runtimes to use. Polkadot is enabled by default. +# +# Validators require the native runtime currently +polkadot-native = ["service/polkadot-native"] +kusama-native = ["service/kusama-native"] +westend-native = ["service/westend-native"] +rococo-native = ["service/rococo-native"] + +malus = ["full-node", "service/malus"] +runtime-metrics = ["service/runtime-metrics", "polkadot-node-metrics/runtime-metrics"] +network-protocol-staging = ["service/network-protocol-staging"] diff --git a/polkadot/cli/build.rs b/polkadot/cli/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..483cc04163fc492a14cc3c48c1b8b64eceb67055 --- /dev/null +++ b/polkadot/cli/build.rs @@ -0,0 +1,25 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +fn main() { + if let Ok(profile) = std::env::var("PROFILE") { + println!("cargo:rustc-cfg=build_type=\"{}\"", profile); + } + substrate_build_script_utils::generate_cargo_keys(); + // For the node/worker version check, make sure we always rebuild the node when the version + // changes. + substrate_build_script_utils::rerun_if_git_head_changed(); +} diff --git a/polkadot/cli/src/cli.rs b/polkadot/cli/src/cli.rs new file mode 100644 index 0000000000000000000000000000000000000000..66205902b79dfd26e2ccb3a615c52c7ad0d72738 --- /dev/null +++ b/polkadot/cli/src/cli.rs @@ -0,0 +1,157 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot CLI library. + +use clap::Parser; +use std::path::PathBuf; + +/// The version of the node. The passed-in version of the workers should match this. +pub const NODE_VERSION: &'static str = env!("SUBSTRATE_CLI_IMPL_VERSION"); + +#[allow(missing_docs)] +#[derive(Debug, Parser)] +pub enum Subcommand { + /// Build a chain specification. + BuildSpec(sc_cli::BuildSpecCmd), + + /// Validate blocks. + CheckBlock(sc_cli::CheckBlockCmd), + + /// Export blocks. + ExportBlocks(sc_cli::ExportBlocksCmd), + + /// Export the state of a given block into a chain spec. + ExportState(sc_cli::ExportStateCmd), + + /// Import blocks. + ImportBlocks(sc_cli::ImportBlocksCmd), + + /// Remove the whole chain. + PurgeChain(sc_cli::PurgeChainCmd), + + /// Revert the chain to a previous state. + Revert(sc_cli::RevertCmd), + + /// Sub-commands concerned with benchmarking. + /// The pallet benchmarking moved to the `pallet` sub-command. + #[command(subcommand)] + Benchmark(frame_benchmarking_cli::BenchmarkCmd), + + /// Runs performance checks such as PVF compilation in order to measure machine + /// capabilities of running a validator. + HostPerfCheck, + + /// Try-runtime has migrated to a standalone CLI + /// (). The subcommand exists as a stub and + /// deprecation notice. It will be removed entirely some time after Janurary 2024. + TryRuntime, + + /// Key management CLI utilities + #[command(subcommand)] + Key(sc_cli::KeySubcommand), + + /// Db meta columns information. + ChainInfo(sc_cli::ChainInfoCmd), +} + +#[allow(missing_docs)] +#[derive(Debug, Parser)] +#[group(skip)] +pub struct RunCmd { + #[clap(flatten)] + pub base: sc_cli::RunCmd, + + /// Force using Kusama native runtime. + #[arg(long = "force-kusama")] + pub force_kusama: bool, + + /// Force using Westend native runtime. + #[arg(long = "force-westend")] + pub force_westend: bool, + + /// Force using Rococo native runtime. + #[arg(long = "force-rococo")] + pub force_rococo: bool, + + /// Setup a GRANDPA scheduled voting pause. + /// + /// This parameter takes two values, namely a block number and a delay (in + /// blocks). After the given block number is finalized the GRANDPA voter + /// will temporarily stop voting for new blocks until the given delay has + /// elapsed (i.e. until a block at height `pause_block + delay` is imported). + #[arg(long = "grandpa-pause", num_args = 2)] + pub grandpa_pause: Vec, + + /// Disable the BEEFY gadget + /// (currently enabled by default on Rococo, Wococo and Versi). + #[arg(long)] + pub no_beefy: bool, + + /// Add the destination address to the jaeger agent. + /// + /// Must be valid socket address, of format `IP:Port` + /// commonly `127.0.0.1:6831`. + #[arg(long)] + pub jaeger_agent: Option, + + /// Add the destination address to the `pyroscope` agent. + /// + /// Must be valid socket address, of format `IP:Port` + /// commonly `127.0.0.1:4040`. + #[arg(long)] + pub pyroscope_server: Option, + + /// Disable automatic hardware benchmarks. + /// + /// By default these benchmarks are automatically ran at startup and measure + /// the CPU speed, the memory bandwidth and the disk speed. + /// + /// The results are then printed out in the logs, and also sent as part of + /// telemetry, if telemetry is enabled. + #[arg(long)] + pub no_hardware_benchmarks: bool, + + /// Overseer message capacity override. + /// + /// **Dangerous!** Do not touch unless explicitly adviced to. + #[arg(long)] + pub overseer_channel_capacity_override: Option, + + /// Path to the directory where auxiliary worker binaries reside. If not specified, the main + /// binary's directory is searched first, then `/usr/lib/polkadot` is searched. TESTING ONLY: + /// if the path points to an executable rather then directory, that executable is used both as + /// preparation and execution worker. + #[arg(long, value_name = "PATH")] + pub workers_path: Option, + + /// TESTING ONLY: disable the version check between nodes and workers. + #[arg(long, hide = true)] + pub disable_worker_version_check: bool, +} + +#[allow(missing_docs)] +#[derive(Debug, Parser)] +pub struct Cli { + #[command(subcommand)] + pub subcommand: Option, + + #[clap(flatten)] + pub run: RunCmd, + + #[clap(flatten)] + pub storage_monitor: sc_storage_monitor::StorageMonitorParams, +} diff --git a/polkadot/cli/src/command.rs b/polkadot/cli/src/command.rs new file mode 100644 index 0000000000000000000000000000000000000000..a2a00d0ebd3f87939f94a1f22b2201d6e74d683d --- /dev/null +++ b/polkadot/cli/src/command.rs @@ -0,0 +1,567 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::cli::{Cli, Subcommand, NODE_VERSION}; +use frame_benchmarking_cli::{BenchmarkCmd, ExtrinsicFactory, SUBSTRATE_REFERENCE_HARDWARE}; +use futures::future::TryFutureExt; +use log::{info, warn}; +use sc_cli::SubstrateCli; +use service::{ + self, + benchmarking::{benchmark_inherent_data, RemarkBuilder, TransferKeepAliveBuilder}, + HeaderBackend, IdentifyVariant, +}; +use sp_core::crypto::Ss58AddressFormatRegistry; +use sp_keyring::Sr25519Keyring; +use std::net::ToSocketAddrs; + +pub use crate::{error::Error, service::BlockId}; +#[cfg(feature = "hostperfcheck")] +pub use polkadot_performance_test::PerfCheckError; +#[cfg(feature = "pyroscope")] +use pyroscope_pprofrs::{pprof_backend, PprofConfig}; + +impl From for Error { + fn from(s: String) -> Self { + Self::Other(s) + } +} + +type Result = std::result::Result; + +fn get_exec_name() -> Option { + std::env::current_exe() + .ok() + .and_then(|pb| pb.file_name().map(|s| s.to_os_string())) + .and_then(|s| s.into_string().ok()) +} + +impl SubstrateCli for Cli { + fn impl_name() -> String { + "Parity Polkadot".into() + } + + fn impl_version() -> String { + NODE_VERSION.into() + } + + fn description() -> String { + env!("CARGO_PKG_DESCRIPTION").into() + } + + fn author() -> String { + env!("CARGO_PKG_AUTHORS").into() + } + + fn support_url() -> String { + "https://github.com/paritytech/polkadot/issues/new".into() + } + + fn copyright_start_year() -> i32 { + 2017 + } + + fn executable_name() -> String { + "polkadot".into() + } + + fn load_spec(&self, id: &str) -> std::result::Result, String> { + let id = if id == "" { + let n = get_exec_name().unwrap_or_default(); + ["polkadot", "kusama", "westend", "rococo", "versi"] + .iter() + .cloned() + .find(|&chain| n.starts_with(chain)) + .unwrap_or("polkadot") + } else { + id + }; + Ok(match id { + "kusama" => Box::new(service::chain_spec::kusama_config()?), + #[cfg(feature = "kusama-native")] + "kusama-dev" => Box::new(service::chain_spec::kusama_development_config()?), + #[cfg(feature = "kusama-native")] + "kusama-local" => Box::new(service::chain_spec::kusama_local_testnet_config()?), + #[cfg(feature = "kusama-native")] + "kusama-staging" => Box::new(service::chain_spec::kusama_staging_testnet_config()?), + #[cfg(not(feature = "kusama-native"))] + name if name.starts_with("kusama-") && !name.ends_with(".json") => + Err(format!("`{}` only supported with `kusama-native` feature enabled.", name))?, + "polkadot" => Box::new(service::chain_spec::polkadot_config()?), + #[cfg(feature = "polkadot-native")] + "polkadot-dev" | "dev" => Box::new(service::chain_spec::polkadot_development_config()?), + #[cfg(feature = "polkadot-native")] + "polkadot-local" => Box::new(service::chain_spec::polkadot_local_testnet_config()?), + "rococo" => Box::new(service::chain_spec::rococo_config()?), + #[cfg(feature = "rococo-native")] + "rococo-dev" => Box::new(service::chain_spec::rococo_development_config()?), + #[cfg(feature = "rococo-native")] + "rococo-local" => Box::new(service::chain_spec::rococo_local_testnet_config()?), + #[cfg(feature = "rococo-native")] + "rococo-staging" => Box::new(service::chain_spec::rococo_staging_testnet_config()?), + #[cfg(not(feature = "rococo-native"))] + name if name.starts_with("rococo-") && !name.ends_with(".json") => + Err(format!("`{}` only supported with `rococo-native` feature enabled.", name))?, + "westend" => Box::new(service::chain_spec::westend_config()?), + #[cfg(feature = "westend-native")] + "westend-dev" => Box::new(service::chain_spec::westend_development_config()?), + #[cfg(feature = "westend-native")] + "westend-local" => Box::new(service::chain_spec::westend_local_testnet_config()?), + #[cfg(feature = "westend-native")] + "westend-staging" => Box::new(service::chain_spec::westend_staging_testnet_config()?), + #[cfg(not(feature = "westend-native"))] + name if name.starts_with("westend-") && !name.ends_with(".json") => + Err(format!("`{}` only supported with `westend-native` feature enabled.", name))?, + "wococo" => Box::new(service::chain_spec::wococo_config()?), + #[cfg(feature = "rococo-native")] + "wococo-dev" => Box::new(service::chain_spec::wococo_development_config()?), + #[cfg(feature = "rococo-native")] + "wococo-local" => Box::new(service::chain_spec::wococo_local_testnet_config()?), + #[cfg(not(feature = "rococo-native"))] + name if name.starts_with("wococo-") => + Err(format!("`{}` only supported with `rococo-native` feature enabled.", name))?, + #[cfg(feature = "rococo-native")] + "versi-dev" => Box::new(service::chain_spec::versi_development_config()?), + #[cfg(feature = "rococo-native")] + "versi-local" => Box::new(service::chain_spec::versi_local_testnet_config()?), + #[cfg(feature = "rococo-native")] + "versi-staging" => Box::new(service::chain_spec::versi_staging_testnet_config()?), + #[cfg(not(feature = "rococo-native"))] + name if name.starts_with("versi-") => + Err(format!("`{}` only supported with `rococo-native` feature enabled.", name))?, + path => { + let path = std::path::PathBuf::from(path); + + let chain_spec = Box::new(service::PolkadotChainSpec::from_json_file(path.clone())?) + as Box; + + // When `force_*` is given or the file name starts with the name of one of the known + // chains, we use the chain spec for the specific chain. + if self.run.force_rococo || + chain_spec.is_rococo() || + chain_spec.is_wococo() || + chain_spec.is_versi() + { + Box::new(service::RococoChainSpec::from_json_file(path)?) + } else if self.run.force_kusama || chain_spec.is_kusama() { + Box::new(service::KusamaChainSpec::from_json_file(path)?) + } else if self.run.force_westend || chain_spec.is_westend() { + Box::new(service::WestendChainSpec::from_json_file(path)?) + } else { + chain_spec + } + }, + }) + } +} + +fn set_default_ss58_version(spec: &Box) { + let ss58_version = if spec.is_kusama() { + Ss58AddressFormatRegistry::KusamaAccount + } else if spec.is_westend() { + Ss58AddressFormatRegistry::SubstrateAccount + } else { + Ss58AddressFormatRegistry::PolkadotAccount + } + .into(); + + sp_core::crypto::set_default_ss58_version(ss58_version); +} + +const DEV_ONLY_ERROR_PATTERN: &'static str = + "can only use subcommand with --chain [polkadot-dev, kusama-dev, westend-dev, rococo-dev, wococo-dev], got "; + +fn ensure_dev(spec: &Box) -> std::result::Result<(), String> { + if spec.is_dev() { + Ok(()) + } else { + Err(format!("{}{}", DEV_ONLY_ERROR_PATTERN, spec.id())) + } +} + +/// Runs performance checks. +/// Should only be used in release build since the check would take too much time otherwise. +fn host_perf_check() -> Result<()> { + #[cfg(not(feature = "hostperfcheck"))] + { + return Err(Error::FeatureNotEnabled { feature: "hostperfcheck" }.into()) + } + + #[cfg(all(not(build_type = "release"), feature = "hostperfcheck"))] + { + return Err(PerfCheckError::WrongBuildType.into()) + } + + #[cfg(all(feature = "hostperfcheck", build_type = "release"))] + { + crate::host_perf_check::host_perf_check()?; + return Ok(()) + } +} + +/// Launch a node, accepting arguments just like a regular node, +/// accepts an alternative overseer generator, to adjust behavior +/// for integration tests as needed. +/// `malus_finality_delay` restrict finality votes of this node +/// to be at most `best_block - malus_finality_delay` height. +#[cfg(feature = "malus")] +pub fn run_node( + run: Cli, + overseer_gen: impl service::OverseerGen, + malus_finality_delay: Option, +) -> Result<()> { + run_node_inner(run, overseer_gen, malus_finality_delay, |_logger_builder, _config| {}) +} + +fn run_node_inner( + cli: Cli, + overseer_gen: impl service::OverseerGen, + maybe_malus_finality_delay: Option, + logger_hook: F, +) -> Result<()> +where + F: FnOnce(&mut sc_cli::LoggerBuilder, &sc_service::Configuration), +{ + let runner = cli + .create_runner_with_logger_hook::(&cli.run.base, logger_hook) + .map_err(Error::from)?; + let chain_spec = &runner.config().chain_spec; + + // By default, enable BEEFY on all networks except Polkadot (for now), unless + // explicitly disabled through CLI. + let mut enable_beefy = !chain_spec.is_polkadot() && !cli.run.no_beefy; + // BEEFY doesn't (yet) support warp sync: + // Until we implement https://github.com/paritytech/substrate/issues/14756 + // - disallow warp sync for validators, + // - disable BEEFY when warp sync for non-validators. + if enable_beefy && runner.config().network.sync_mode.is_warp() { + if runner.config().role.is_authority() { + return Err(Error::Other( + "Warp sync not supported for validator nodes running BEEFY.".into(), + )) + } else { + // disable BEEFY for non-validator nodes that are warp syncing + warn!("🥩 BEEFY not supported when warp syncing. Disabling BEEFY."); + enable_beefy = false; + } + } + + set_default_ss58_version(chain_spec); + + let grandpa_pause = if cli.run.grandpa_pause.is_empty() { + None + } else { + Some((cli.run.grandpa_pause[0], cli.run.grandpa_pause[1])) + }; + + if chain_spec.is_kusama() { + info!("----------------------------"); + info!("This chain is not in any way"); + info!(" endorsed by the "); + info!(" KUSAMA FOUNDATION "); + info!("----------------------------"); + } + + let jaeger_agent = if let Some(ref jaeger_agent) = cli.run.jaeger_agent { + Some( + jaeger_agent + .to_socket_addrs() + .map_err(Error::AddressResolutionFailure)? + .next() + .ok_or_else(|| Error::AddressResolutionMissing)?, + ) + } else { + None + }; + + let node_version = + if cli.run.disable_worker_version_check { None } else { Some(NODE_VERSION.to_string()) }; + + runner.run_node_until_exit(move |config| async move { + let hwbench = (!cli.run.no_hardware_benchmarks) + .then_some(config.database.path().map(|database_path| { + let _ = std::fs::create_dir_all(&database_path); + sc_sysinfo::gather_hwbench(Some(database_path)) + })) + .flatten(); + + let database_source = config.database.clone(); + let task_manager = service::build_full( + config, + service::NewFullParams { + is_parachain_node: service::IsParachainNode::No, + grandpa_pause, + enable_beefy, + jaeger_agent, + telemetry_worker_handle: None, + node_version, + workers_path: cli.run.workers_path, + workers_names: None, + overseer_gen, + overseer_message_channel_capacity_override: cli + .run + .overseer_channel_capacity_override, + malus_finality_delay: maybe_malus_finality_delay, + hwbench, + }, + ) + .map(|full| full.task_manager)?; + + sc_storage_monitor::StorageMonitorService::try_spawn( + cli.storage_monitor, + database_source, + &task_manager.spawn_essential_handle(), + )?; + + Ok(task_manager) + }) +} + +/// Parses polkadot specific CLI arguments and run the service. +pub fn run() -> Result<()> { + let cli: Cli = Cli::from_args(); + + #[cfg(feature = "pyroscope")] + let mut pyroscope_agent_maybe = if let Some(ref agent_addr) = cli.run.pyroscope_server { + let address = agent_addr + .to_socket_addrs() + .map_err(Error::AddressResolutionFailure)? + .next() + .ok_or_else(|| Error::AddressResolutionMissing)?; + // The pyroscope agent requires a `http://` prefix, so we just do that. + let agent = pyro::PyroscopeAgent::builder( + "http://".to_owned() + address.to_string().as_str(), + "polkadot".to_owned(), + ) + .backend(pprof_backend(PprofConfig::new().sample_rate(113))) + .build()?; + Some(agent.start()?) + } else { + None + }; + + #[cfg(not(feature = "pyroscope"))] + if cli.run.pyroscope_server.is_some() { + return Err(Error::PyroscopeNotCompiledIn) + } + + match &cli.subcommand { + None => run_node_inner( + cli, + service::RealOverseerGen, + None, + polkadot_node_metrics::logger_hook(), + ), + Some(Subcommand::BuildSpec(cmd)) => { + let runner = cli.create_runner(cmd)?; + Ok(runner.sync_run(|config| cmd.run(config.chain_spec, config.network))?) + }, + Some(Subcommand::CheckBlock(cmd)) => { + let runner = cli.create_runner(cmd).map_err(Error::SubstrateCli)?; + let chain_spec = &runner.config().chain_spec; + + set_default_ss58_version(chain_spec); + + runner.async_run(|mut config| { + let (client, _, import_queue, task_manager) = + service::new_chain_ops(&mut config, None)?; + Ok((cmd.run(client, import_queue).map_err(Error::SubstrateCli), task_manager)) + }) + }, + Some(Subcommand::ExportBlocks(cmd)) => { + let runner = cli.create_runner(cmd)?; + let chain_spec = &runner.config().chain_spec; + + set_default_ss58_version(chain_spec); + + Ok(runner.async_run(|mut config| { + let (client, _, _, task_manager) = + service::new_chain_ops(&mut config, None).map_err(Error::PolkadotService)?; + Ok((cmd.run(client, config.database).map_err(Error::SubstrateCli), task_manager)) + })?) + }, + Some(Subcommand::ExportState(cmd)) => { + let runner = cli.create_runner(cmd)?; + let chain_spec = &runner.config().chain_spec; + + set_default_ss58_version(chain_spec); + + Ok(runner.async_run(|mut config| { + let (client, _, _, task_manager) = service::new_chain_ops(&mut config, None)?; + Ok((cmd.run(client, config.chain_spec).map_err(Error::SubstrateCli), task_manager)) + })?) + }, + Some(Subcommand::ImportBlocks(cmd)) => { + let runner = cli.create_runner(cmd)?; + let chain_spec = &runner.config().chain_spec; + + set_default_ss58_version(chain_spec); + + Ok(runner.async_run(|mut config| { + let (client, _, import_queue, task_manager) = + service::new_chain_ops(&mut config, None)?; + Ok((cmd.run(client, import_queue).map_err(Error::SubstrateCli), task_manager)) + })?) + }, + Some(Subcommand::PurgeChain(cmd)) => { + let runner = cli.create_runner(cmd)?; + Ok(runner.sync_run(|config| cmd.run(config.database))?) + }, + Some(Subcommand::Revert(cmd)) => { + let runner = cli.create_runner(cmd)?; + let chain_spec = &runner.config().chain_spec; + + set_default_ss58_version(chain_spec); + + Ok(runner.async_run(|mut config| { + let (client, backend, _, task_manager) = service::new_chain_ops(&mut config, None)?; + let aux_revert = Box::new(|client, backend, blocks| { + service::revert_backend(client, backend, blocks, config).map_err(|err| { + match err { + service::Error::Blockchain(err) => err.into(), + // Generic application-specific error. + err => sc_cli::Error::Application(err.into()), + } + }) + }); + Ok(( + cmd.run(client, backend, Some(aux_revert)).map_err(Error::SubstrateCli), + task_manager, + )) + })?) + }, + Some(Subcommand::Benchmark(cmd)) => { + let runner = cli.create_runner(cmd)?; + let chain_spec = &runner.config().chain_spec; + + match cmd { + #[cfg(not(feature = "runtime-benchmarks"))] + BenchmarkCmd::Storage(_) => + return Err(sc_cli::Error::Input( + "Compile with --features=runtime-benchmarks \ + to enable storage benchmarks." + .into(), + ) + .into()), + #[cfg(feature = "runtime-benchmarks")] + BenchmarkCmd::Storage(cmd) => runner.sync_run(|mut config| { + let (client, backend, _, _) = service::new_chain_ops(&mut config, None)?; + let db = backend.expose_db(); + let storage = backend.expose_storage(); + + cmd.run(config, client.clone(), db, storage).map_err(Error::SubstrateCli) + }), + BenchmarkCmd::Block(cmd) => runner.sync_run(|mut config| { + let (client, _, _, _) = service::new_chain_ops(&mut config, None)?; + + cmd.run(client.clone()).map_err(Error::SubstrateCli) + }), + // These commands are very similar and can be handled in nearly the same way. + BenchmarkCmd::Extrinsic(_) | BenchmarkCmd::Overhead(_) => { + ensure_dev(chain_spec).map_err(Error::Other)?; + runner.sync_run(|mut config| { + let (client, _, _, _) = service::new_chain_ops(&mut config, None)?; + let header = client.header(client.info().genesis_hash).unwrap().unwrap(); + let inherent_data = benchmark_inherent_data(header) + .map_err(|e| format!("generating inherent data: {:?}", e))?; + let remark_builder = + RemarkBuilder::new(client.clone(), config.chain_spec.identify_chain()); + + match cmd { + BenchmarkCmd::Extrinsic(cmd) => { + let tka_builder = TransferKeepAliveBuilder::new( + client.clone(), + Sr25519Keyring::Alice.to_account_id(), + config.chain_spec.identify_chain(), + ); + + let ext_factory = ExtrinsicFactory(vec![ + Box::new(remark_builder), + Box::new(tka_builder), + ]); + + cmd.run(client.clone(), inherent_data, Vec::new(), &ext_factory) + .map_err(Error::SubstrateCli) + }, + BenchmarkCmd::Overhead(cmd) => cmd + .run( + config, + client.clone(), + inherent_data, + Vec::new(), + &remark_builder, + ) + .map_err(Error::SubstrateCli), + _ => unreachable!("Ensured by the outside match; qed"), + } + }) + }, + BenchmarkCmd::Pallet(cmd) => { + set_default_ss58_version(chain_spec); + ensure_dev(chain_spec).map_err(Error::Other)?; + + if cfg!(feature = "runtime-benchmarks") { + runner.sync_run(|config| { + cmd.run::(config) + .map_err(|e| Error::SubstrateCli(e)) + }) + } else { + Err(sc_cli::Error::Input( + "Benchmarking wasn't enabled when building the node. \ + You can enable it with `--features runtime-benchmarks`." + .into(), + ) + .into()) + } + }, + BenchmarkCmd::Machine(cmd) => runner.sync_run(|config| { + cmd.run(&config, SUBSTRATE_REFERENCE_HARDWARE.clone()) + .map_err(Error::SubstrateCli) + }), + // NOTE: this allows the Polkadot client to leniently implement + // new benchmark commands. + #[allow(unreachable_patterns)] + _ => Err(Error::CommandNotImplemented), + } + }, + Some(Subcommand::HostPerfCheck) => { + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_colors(true); + builder.init()?; + + host_perf_check() + }, + Some(Subcommand::Key(cmd)) => Ok(cmd.run(&cli)?), + #[cfg(feature = "try-runtime")] + Some(Subcommand::TryRuntime) => Err(try_runtime_cli::DEPRECATION_NOTICE.to_owned().into()), + #[cfg(not(feature = "try-runtime"))] + Some(Subcommand::TryRuntime) => Err("TryRuntime wasn't enabled when building the node. \ + You can enable it with `--features try-runtime`." + .to_owned() + .into()), + Some(Subcommand::ChainInfo(cmd)) => { + let runner = cli.create_runner(cmd)?; + Ok(runner.sync_run(|config| cmd.run::(&config))?) + }, + }?; + + #[cfg(feature = "pyroscope")] + if let Some(pyroscope_agent) = pyroscope_agent_maybe.take() { + let agent = pyroscope_agent.stop()?; + agent.shutdown(); + } + Ok(()) +} diff --git a/polkadot/cli/src/error.rs b/polkadot/cli/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..a4591e2508c9796764d09296405bdb05fb834a3c --- /dev/null +++ b/polkadot/cli/src/error.rs @@ -0,0 +1,60 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + PolkadotService(#[from] service::Error), + + #[error(transparent)] + SubstrateCli(#[from] sc_cli::Error), + + #[error(transparent)] + SubstrateService(#[from] sc_service::Error), + + #[error(transparent)] + SubstrateTracing(#[from] sc_tracing::logging::Error), + + #[error(transparent)] + #[cfg(feature = "hostperfcheck")] + PerfCheck(#[from] polkadot_performance_test::PerfCheckError), + + #[cfg(not(feature = "pyroscope"))] + #[error("Binary was not compiled with `--feature=pyroscope`")] + PyroscopeNotCompiledIn, + + #[cfg(feature = "pyroscope")] + #[error("Failed to connect to pyroscope agent")] + PyroscopeError(#[from] pyro::error::PyroscopeError), + + #[error("Failed to resolve provided URL")] + AddressResolutionFailure(#[from] std::io::Error), + + #[error("URL did not resolve to anything")] + AddressResolutionMissing, + + #[error("Command is not implemented")] + CommandNotImplemented, + + #[error(transparent)] + Storage(#[from] sc_storage_monitor::Error), + + #[error("Other: {0}")] + Other(String), + + #[error("This subcommand is only available when compiled with `{feature}`")] + FeatureNotEnabled { feature: &'static str }, +} diff --git a/polkadot/cli/src/host_perf_check.rs b/polkadot/cli/src/host_perf_check.rs new file mode 100644 index 0000000000000000000000000000000000000000..adfdebce6779bd2d0cd18ad09141bcfa514d2631 --- /dev/null +++ b/polkadot/cli/src/host_perf_check.rs @@ -0,0 +1,74 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use log::info; +use polkadot_performance_test::{ + measure_erasure_coding, measure_pvf_prepare, PerfCheckError, ERASURE_CODING_N_VALIDATORS, + ERASURE_CODING_TIME_LIMIT, PVF_PREPARE_TIME_LIMIT, VALIDATION_CODE_BOMB_LIMIT, +}; +use std::time::Duration; + +pub fn host_perf_check() -> Result<(), PerfCheckError> { + let pvf_prepare_time_limit = time_limit_from_baseline(PVF_PREPARE_TIME_LIMIT); + let erasure_coding_time_limit = time_limit_from_baseline(ERASURE_CODING_TIME_LIMIT); + let wasm_code = + polkadot_performance_test::WASM_BINARY.ok_or(PerfCheckError::WasmBinaryMissing)?; + + // Decompress the code before running checks. + let code = sp_maybe_compressed_blob::decompress(wasm_code, VALIDATION_CODE_BOMB_LIMIT) + .or(Err(PerfCheckError::CodeDecompressionFailed))?; + + info!("Running the performance checks..."); + + perf_check("PVF-prepare", pvf_prepare_time_limit, || measure_pvf_prepare(code.as_ref()))?; + + perf_check("Erasure-coding", erasure_coding_time_limit, || { + measure_erasure_coding(ERASURE_CODING_N_VALIDATORS, code.as_ref()) + })?; + + Ok(()) +} + +/// Returns a no-warning threshold for the given time limit. +fn green_threshold(duration: Duration) -> Duration { + duration * 4 / 5 +} + +/// Returns an extended time limit to be used for the actual check. +fn time_limit_from_baseline(duration: Duration) -> Duration { + duration * 3 / 2 +} + +fn perf_check( + test_name: &str, + time_limit: Duration, + test: impl Fn() -> Result, +) -> Result<(), PerfCheckError> { + let elapsed = test()?; + + if elapsed < green_threshold(time_limit) { + info!("🟢 {} performance check passed, elapsed: {:?}", test_name, elapsed); + Ok(()) + } else if elapsed <= time_limit { + info!( + "🟡 {} performance check passed, {:?} limit almost exceeded, elapsed: {:?}", + test_name, time_limit, elapsed + ); + Ok(()) + } else { + Err(PerfCheckError::TimeOut { elapsed, limit: time_limit }) + } +} diff --git a/polkadot/cli/src/lib.rs b/polkadot/cli/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..057592fa8a10ea79939b66bad8f6adc2e7476059 --- /dev/null +++ b/polkadot/cli/src/lib.rs @@ -0,0 +1,43 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot CLI library. + +#![warn(missing_docs)] + +#[cfg(feature = "cli")] +mod cli; +#[cfg(feature = "cli")] +mod command; +#[cfg(feature = "cli")] +mod error; +#[cfg(all(feature = "hostperfcheck", build_type = "release"))] +mod host_perf_check; + +#[cfg(feature = "service")] +pub use service::{self, Block, CoreApi, IdentifyVariant, ProvideRuntimeApi, TFullClient}; + +#[cfg(feature = "malus")] +pub use service::overseer::prepared_overseer_builder; + +#[cfg(feature = "cli")] +pub use cli::*; + +#[cfg(feature = "cli")] +pub use command::*; + +#[cfg(feature = "cli")] +pub use sc_cli::{Error, Result}; diff --git a/polkadot/core-primitives/Cargo.toml b/polkadot/core-primitives/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..0ed315e1307e034441c6ae91f5931a08d7ef4a7d --- /dev/null +++ b/polkadot/core-primitives/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "polkadot-core-primitives" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +parity-scale-codec = { version = "3.6.1", default-features = false, features = [ "derive" ] } + +[features] +default = [ "std" ] +std = [ + "scale-info/std", + "sp-core/std", + "sp-runtime/std", + "sp-std/std", + "scale-info/std", + "parity-scale-codec/std", +] diff --git a/polkadot/core-primitives/src/lib.rs b/polkadot/core-primitives/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..aa01cf8dfc4594d711d6d233332c412ec37961d2 --- /dev/null +++ b/polkadot/core-primitives/src/lib.rs @@ -0,0 +1,157 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +//! Core Polkadot types. +//! +//! These core Polkadot types are used by the relay chain and the Parachains. + +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_runtime::{ + generic, + traits::{IdentifyAccount, Verify}, + MultiSignature, +}; + +pub use sp_runtime::traits::{BlakeTwo256, Hash as HashT}; + +/// The block number type used by Polkadot. +/// 32-bits will allow for 136 years of blocks assuming 1 block per second. +pub type BlockNumber = u32; + +/// An instant or duration in time. +pub type Moment = u64; + +/// Alias to type for a signature for a transaction on the relay chain. This allows one of several +/// kinds of underlying crypto to be used, so isn't a fixed size when encoded. +pub type Signature = MultiSignature; + +/// Alias to the public key used for this chain, actually a `MultiSigner`. Like the signature, this +/// also isn't a fixed size when encoded, as different cryptos have different size public keys. +pub type AccountPublic = ::Signer; + +/// Alias to the opaque account ID type for this chain, actually a `AccountId32`. This is always +/// 32 bytes. +pub type AccountId = ::AccountId; + +/// The type for looking up accounts. We don't expect more than 4 billion of them. +pub type AccountIndex = u32; + +/// Identifier for a chain. 32-bit should be plenty. +pub type ChainId = u32; + +/// A hash of some data used by the relay chain. +pub type Hash = sp_core::H256; + +/// Unit type wrapper around [`type@Hash`] that represents a candidate hash. +/// +/// This type is produced by [`CandidateReceipt::hash`]. +/// +/// This type makes it easy to enforce that a hash is a candidate hash on the type level. +#[derive(Clone, Copy, Encode, Decode, Hash, Eq, PartialEq, Default, PartialOrd, Ord, TypeInfo)] +pub struct CandidateHash(pub Hash); + +#[cfg(feature = "std")] +impl std::ops::Deref for CandidateHash { + type Target = Hash; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[cfg(feature = "std")] +impl std::fmt::Display for CandidateHash { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl sp_std::fmt::Debug for CandidateHash { + fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { + write!(f, "{:?}", self.0) + } +} + +/// Index of a transaction in the relay chain. 32-bit should be plenty. +pub type Nonce = u32; + +/// The balance of an account. +/// 128-bits (or 38 significant decimal figures) will allow for 10 m currency (`10^7`) at a +/// resolution to all for one second's worth of an annualised 50% reward be paid to a unit holder +/// (`10^11` unit denomination), or `10^18` total atomic units, to grow at 50%/year for 51 years +/// (`10^9` multiplier) for an eventual total of `10^27` units (27 significant decimal figures). +/// We round denomination to `10^12` (12 SDF), and leave the other redundancy at the upper end so +/// that 32 bits may be multiplied with a balance in 128 bits without worrying about overflow. +pub type Balance = u128; + +/// Header type. +pub type Header = generic::Header; +/// Block type. +pub type Block = generic::Block; +/// Block ID. +pub type BlockId = generic::BlockId; + +/// Opaque, encoded, unchecked extrinsic. +pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; + +/// The information that goes alongside a `transfer_into_parachain` operation. Entirely opaque, it +/// will generally be used for identifying the reason for the transfer. Typically it will hold the +/// destination account to which the transfer should be credited. If still more information is +/// needed, then this should be a hash with the pre-image presented via an off-chain mechanism on +/// the parachain. +pub type Remark = [u8; 32]; + +/// A message sent from the relay-chain down to a parachain. +/// +/// The size of the message is limited by the `config.max_downward_message_size` parameter. +pub type DownwardMessage = sp_std::vec::Vec; + +/// A wrapped version of `DownwardMessage`. The difference is that it has attached the block number +/// when the message was sent. +#[derive(Encode, Decode, Clone, sp_runtime::RuntimeDebug, PartialEq, TypeInfo)] +pub struct InboundDownwardMessage { + /// The block number at which these messages were put into the downward message queue. + pub sent_at: BlockNumber, + /// The actual downward message to processes. + pub msg: DownwardMessage, +} + +/// An HRMP message seen from the perspective of a recipient. +#[derive(Encode, Decode, Clone, sp_runtime::RuntimeDebug, PartialEq, TypeInfo)] +pub struct InboundHrmpMessage { + /// The block number at which this message was sent. + /// Specifically, it is the block number at which the candidate that sends this message was + /// enacted. + pub sent_at: BlockNumber, + /// The message payload. + pub data: sp_std::vec::Vec, +} + +/// An HRMP message seen from the perspective of a sender. +#[derive(Encode, Decode, Clone, sp_runtime::RuntimeDebug, PartialEq, Eq, Hash, TypeInfo)] +pub struct OutboundHrmpMessage { + /// The para that will get this message in its downward message queue. + pub recipient: Id, + /// The message payload. + pub data: sp_std::vec::Vec, +} + +/// `V2` primitives. +pub mod v2 { + pub use super::*; +} diff --git a/polkadot/doc/docker.md b/polkadot/doc/docker.md new file mode 100644 index 0000000000000000000000000000000000000000..f20c2d001edd4b9a75261573b7955e5146b28002 --- /dev/null +++ b/polkadot/doc/docker.md @@ -0,0 +1,157 @@ +# Using Containers + +The following commands should work no matter if you use Docker or Podman. In general, Podman is recommended. All commands are "engine neutral" so you can use the container engine of your choice while still being able to copy/paste the commands below. + +Let's start defining Podman as our engine: +``` +ENGINE=podman +``` + +If you prefer to stick with Docker, use: +``` +ENGINE=docker +``` + +## The easiest way + +The easiest/faster option to run Polkadot in Docker is to use the latest release images. These are small images that use the latest official release of the Polkadot binary, pulled from our Debian package. + +**_The following examples are running on westend chain and without SSL. They can be used to quick start and learn how Polkadot needs to be configured. Please find out how to secure your node, if you want to operate it on the internet. Do not expose RPC and WS ports, if they are not correctly configured._** + +Let's first check the version we have. The first time you run this command, the Polkadot docker image will be downloaded. This takes a bit of time and bandwidth, be patient: + +```bash +$ENGINE run --rm -it parity/polkadot:latest --version +``` + +You can also pass any argument/flag that Polkadot supports: + +```bash +$ENGINE run --rm -it parity/polkadot:latest --chain westend --name "PolkaDocker" +``` + +## Examples + +Once you are done experimenting and picking the best node name :) you can start Polkadot as daemon, exposes the Polkadot ports and mount a volume that will keep your blockchain data locally. Make sure that you set the ownership of your local directory to the Polkadot user that is used by the container. + +Set user id 1000 and group id 1000, by running `chown 1000.1000 /my/local/folder -R` if you use a bind mount. + +To start a Polkadot node on default rpc port 9933 and default p2p port 30333 use the following command. If you want to connect to rpc port 9933, then must add Polkadot startup parameter: `--rpc-external`. + +```bash +$ENGINE run -d -p 30333:30333 -p 9933:9933 \ + -v /my/local/folder:/polkadot \ + parity/polkadot:latest \ + --chain westend --rpc-external --rpc-cors all \ + --name "PolkaDocker +``` + +If you also want to expose the webservice port 9944 use the following command: + +```bash +$ENGINE run -d -p 30333:30333 -p 9933:9933 -p 9944:9944 \ + -v /my/local/folder:/polkadot \ + parity/polkadot:latest \ + --chain westend --ws-external --rpc-external --rpc-cors all --name "PolkaDocker" +``` + +## Using Docker compose + +You can use the following docker-compose.yml file: + +```bash +version: '2' + +services: + polkadot: + container_name: polkadot + image: parity/polkadot + ports: + - 30333:30333 # p2p port + - 9933:9933 # rpc port + - 9944:9944 # ws port + - 9615:9615 # Prometheus port + volumes: + - /my/local/folder:/polkadot + command: [ + "--name", "PolkaDocker", + "--ws-external", + "--rpc-external", + "--prometheus-external", + "--rpc-cors", "all" + ] +``` + +With following `docker-compose.yml` you can set up a node and use polkadot-js-apps as the front end on port 80. After starting the node use a browser and enter your Docker host IP in the URL field: __ + +```bash +version: '2' + +services: + polkadot: + container_name: polkadot + image: parity/polkadot + ports: + - 30333:30333 # p2p port + - 9933:9933 # rpc port + - 9944:9944 # ws port + - 9615:9615 # Prometheus port + command: [ + "--name", "PolkaDocker", + "--ws-external", + "--rpc-external", + "--prometheus-external", + "--rpc-cors", "all" + ] + + polkadotui: + container_name: polkadotui + image: jacogr/polkadot-js-apps + environment: + - WS_URL=ws://[YOUR_DOCKER_HOST_IP]:9944 + ports: + - 80:80 +``` + +## Limiting Resources + +Chain syncing will utilize all available memory and CPU power your server has to offer, which can lead to crashing. + +If running on a low resource VPS, use `--memory` and `--cpus` to limit the resources used. E.g. To allow a maximum of 512MB memory and 50% of 1 CPU, use `--cpus=".5" --memory="512m"`. Read more about limiting a container's resources [here](https://docs.docker.com/config/containers/resource_constraints). + + +## Build your own image + +There are 3 options to build a polkadot container image: +- using the builder image +- using the injected "Debian" image +- using the generic injected image + +### Builder image + +To get up and running with the smallest footprint on your system, you may use an existing Polkadot Container image. + +You may also build a polkadot container image yourself (it takes a while...) using the container specs `scripts/ci/dockerfiles/polkadot/polkadot_builder.Dockerfile`. + +### Debian injected + +The Debian injected image is how the official polkadot container image is produced. It relies on the Debian package that is published upon each release. The Debian injected image is usually available a few minutes after a new release is published. +It has the benefit of relying on the GPG signatures embedded in the Debian package. + +### Generic injected + +For simple testing purposes, the easiest option for polkadot and also random binaries, is to use the `binary_injected.Dockerfile` container spec. This option is less secure since the injected binary is not checked at all but it has the benefit to be simple. This option requires to already have a valid `polkadot` binary, compiled for Linux. + +This binary is then simply copied inside the `parity/base-bin` image. + +## Reporting issues + +If you run into issues with Polkadot when using docker, please run the following command +(replace the tag with the appropriate one if you do not use latest): + +```bash +$ENGINE run --rm -it parity/polkadot:latest --version +``` + +This will show you the Polkadot version as well as the git commit ref that was used to build your container. +You can now paste the version information in a [new issue](https://github.com/paritytech/polkadot/issues/new/choose). diff --git a/polkadot/doc/release-checklist.md b/polkadot/doc/release-checklist.md new file mode 100644 index 0000000000000000000000000000000000000000..4be7c9bcd5df87e8a183f1bfbea43b83cc754eb0 --- /dev/null +++ b/polkadot/doc/release-checklist.md @@ -0,0 +1,98 @@ + +## Notes + +### Burn In + +Ensure that Parity DevOps has run the new release on Westend, Kusama, and +Polkadot validators for at least 12 hours prior to publishing the release. + +### Build Artifacts + +Add any necessary assets to the release. They should include: + +- Linux binary +- GPG signature of the Linux binary +- SHA256 of binary +- Source code +- Wasm binaries of any runtimes + +### Release notes + +The release notes should list: + +- The priority of the release (i.e., how quickly users should upgrade) - this is + based on the max priority of any *client* changes. +- Which native runtimes and their versions are included +- The proposal hashes of the runtimes as built with + [srtool](https://gitlab.com/chevdor/srtool) +- Any changes in this release that are still awaiting audit + +The release notes may also list: + +- Free text at the beginning of the notes mentioning anything important + regarding this release +- Notable changes (those labelled with B[1-9]-* labels) separated into sections + +### Spec Version + +A runtime upgrade must bump the spec number. This may follow a pattern with the +client release (e.g. runtime v12 corresponds to v0.8.12, even if the current +runtime is not v11). + +### Old Migrations Removed + +Any previous `on_runtime_upgrade` functions from old upgrades must be removed +to prevent them from executing a second time. The `on_runtime_upgrade` function +can be found in `runtime//src/lib.rs`. + +### New Migrations + +Ensure that any migrations that are required due to storage or logic changes +are included in the `on_runtime_upgrade` function of the appropriate pallets. + +### Extrinsic Ordering + +Offline signing libraries depend on a consistent ordering of call indices and +functions. Compare the metadata of the current and new runtimes and ensure that +the `module index, call index` tuples map to the same set of functions. In case +of a breaking change, increase `transaction_version`. + +To verify the order has not changed, you may manually start the following [Github Action](https://github.com/paritytech/polkadot/actions/workflows/extrinsic-ordering-check-from-bin.yml). It takes around a minute to run and will produce the report as artifact you need to manually check. + +The things to look for in the output are lines like: + - `[Identity] idx 28 -> 25 (calls 15)` - indicates the index for `Identity` has changed + - `[+] Society, Recovery` - indicates the new version includes 2 additional modules/pallets. + - If no indices have changed, every modules line should look something like `[Identity] idx 25 (calls 15)` + +Note: Adding new functions to the runtime does not constitute a breaking change +as long as the indexes did not change. + +### Proxy Filtering + +The runtime contains proxy filters that map proxy types to allowable calls. If +the new runtime contains any new calls, verify that the proxy filters are up to +date to include them. + +### Benchmarks + +There are three benchmarking machines reserved for updating the weights at +release-time. To initialise a benchmark run for each production runtime +(westend, kusama, polkadot): +* Go to https://gitlab.parity.io/parity/polkadot/-/pipelines?page=1&scope=branches&ref=master +* Click the link to the last pipeline run for master +* Start each of the manual jobs: + * 'update_westend_weights' + * 'update_polkadot_weights' + * 'update_kusama_weights' +* When these jobs have completed (it takes a few hours), a git PATCH file will + be available to download as an artifact. +* On your local machine, branch off master +* Download the patch file and apply it to your branch with `git patch patchfile.patch` +* Commit the changes to your branch and submit a PR against master +* The weights should be (Currently manually) checked to make sure there are no + big outliers (i.e., twice or half the weight). + +### Polkadot JS + +Ensure that a release of [Polkadot JS API]() contains any new types or +interfaces necessary to interact with the new runtime. diff --git a/polkadot/doc/shell-completion.md b/polkadot/doc/shell-completion.md new file mode 100644 index 0000000000000000000000000000000000000000..9c53cf43a10ff7ddc4f438872a6cdd773a51fff6 --- /dev/null +++ b/polkadot/doc/shell-completion.md @@ -0,0 +1,40 @@ +# Shell completion + +The Polkadot CLI command supports shell auto-completion. For this to work, you will need to run the completion script matching you build and system. + +Assuming you built a release version using `cargo build --release` and use `bash` run the following: + +```bash +source target/release/completion-scripts/polkadot.bash +``` + +You can find completion scripts for: + +- bash +- fish +- zsh +- elvish +- powershell + +To make this change persistent, you can proceed as follow: + +## First install + +```bash +COMPL_DIR=$HOME/.completion +mkdir -p $COMPL_DIR +cp -f target/release/completion-scripts/polkadot.bash $COMPL_DIR/ +echo "source $COMPL_DIR/polkadot.bash" >> $HOME/.bash_profile +source $HOME/.bash_profile +``` + +## Update + +When you build a new version of Polkadot, the following will ensure you auto-completion script matches the current binary: + +```bash +COMPL_DIR=$HOME/.completion +mkdir -p $COMPL_DIR +cp -f target/release/completion-scripts/polkadot.bash $COMPL_DIR/ +source $HOME/.bash_profile +``` diff --git a/polkadot/doc/testing.md b/polkadot/doc/testing.md new file mode 100644 index 0000000000000000000000000000000000000000..78ad77e0e0fda7230cbe4f7f6a6890ed3362c68f --- /dev/null +++ b/polkadot/doc/testing.md @@ -0,0 +1,263 @@ +# Testing + +Automated testing is an essential tool to assure correctness. + +## Scopes + +The testing strategy for polkadot is 4-fold: + +### Unit testing (1) + +Boring, small scale correctness tests of individual functions. + +### Integration tests + +There are two variants of integration tests: + +#### Subsystem tests (2) + +One particular subsystem (subsystem under test) interacts with a +mocked overseer that is made to assert incoming and outgoing messages +of the subsystem under test. +This is largely present today, but has some fragmentation in the evolved +integration test implementation. A `proc-macro`/`macro_rules` would allow +for more consistent implementation and structure. + +#### Behavior tests (3) + +Launching small scale networks, with multiple adversarial nodes without any further tooling required. +This should include tests around the thresholds in order to evaluate the error handling once certain +assumed invariants fail. + +For this purpose based on `AllSubsystems` and `proc-macro` `AllSubsystemsGen`. + +This assumes a simplistic test runtime. + +#### Testing at scale (4) + +Launching many nodes with configurable network speed and node features in a cluster of nodes. +At this scale the [Simnet][simnet] comes into play which launches a full cluster of nodes. +The scale is handled by spawning a kubernetes cluster and the meta description +is covered by [Gurke][Gurke]. +Asserts are made using Grafana rules, based on the existing prometheus metrics. This can +be extended by adding an additional service translating `jaeger` spans into addition +prometheus avoiding additional polkadot source changes. + +_Behavior tests_ and _testing at scale_ have naturally soft boundary. +The most significant difference is the presence of a real network and +the number of nodes, since a single host often not capable to run +multiple nodes at once. + +--- + +## Coverage + +Coverage gives a _hint_ of the actually covered source lines by tests and test applications. + +The state of the art is currently [tarpaulin][tarpaulin] which unfortunately yields a +lot of false negatives. Lines that are in fact covered, marked as uncovered due to a mere linebreak in a statement can cause these artifacts. This leads to +lower coverage percentages than there actually is. + +Since late 2020 rust has gained [MIR based coverage tooling]( +https://blog.rust-lang.org/inside-rust/2020/11/12/source-based-code-coverage.html). + +```sh +# setup +rustup component add llvm-tools-preview +cargo install grcov miniserve + +export CARGO_INCREMENTAL=0 +# wasm is not happy with the instrumentation +export SKIP_BUILD_WASM=true +export BUILD_DUMMY_WASM_BINARY=true +# the actully collected coverage data +export LLVM_PROFILE_FILE="llvmcoveragedata-%p-%m.profraw" +# build wasm without instrumentation +export WASM_TARGET_DIRECTORY=/tmp/wasm +cargo +nightly build +# required rust flags +export RUSTFLAGS="-Zinstrument-coverage" +# assure target dir is clean +rm -r target/{debug,tests} +# run tests to get coverage data +cargo +nightly test --all + +# create the *html* report out of all the test binaries +# mostly useful for local inspection +grcov . --binary-path ./target/debug -s . -t html --branch --ignore-not-existing -o ./coverage/ +miniserve -r ./coverage + +# create a *codecov* compatible report +grcov . --binary-path ./target/debug/ -s . -t lcov --branch --ignore-not-existing --ignore "/*" -o lcov.info +``` + +The test coverage in `lcov` can the be published to . + +```sh +bash <(curl -s https://codecov.io/bash) -f lcov.info +``` + +or just printed as part of the PR using a github action i.e. [`jest-lcov-reporter`](https://github.com/marketplace/actions/jest-lcov-reporter). + +For full examples on how to use [`grcov` /w polkadot specifics see the github repo](https://github.com/mozilla/grcov#coverallscodecov-output). + +## Fuzzing + +Fuzzing is an approach to verify correctness against arbitrary or partially structured inputs. + +Currently implemented fuzzing targets: + +* `erasure-coding` + +The tooling of choice here is `honggfuzz-rs` as it allows _fastest_ coverage according to "some paper" which is a positive feature when run as part of PRs. + +Fuzzing is generally not applicable for data secured by cryptographic hashes or signatures. Either the input has to be specifically crafted, such that the discarded input +percentage stays in an acceptable range. +System level fuzzing is hence simply not feasible due to the amount of state that is required. + +Other candidates to implement fuzzing are: + +* `rpc` +* ... + +## Performance metrics + +There are various ways of performance metrics. + +* timing with `criterion` +* cache hits/misses w/ `iai` harness or `criterion-perf` +* `coz` a performance based compiler + +Most of them are standard tools to aid in the creation of statistical tests regarding change in time of certain unit tests. + +`coz` is meant for runtime. In our case, the system is far too large to yield a sufficient number of measurements in finite time. +An alternative approach could be to record incoming package streams per subsystem and store dumps of them, which in return could be replayed repeatedly at an +accelerated speed, with which enough metrics could be obtained to yield +information on which areas would improve the metrics. +This unfortunately will not yield much information, since most if not all of the subsystem code is linear based on the input to generate one or multiple output messages, it is unlikely to get any useful metrics without mocking a sufficiently large part of the other subsystem which overlaps with [#Integration tests] which is unfortunately not repeatable as of now. +As such the effort gain seems low and this is not pursued at the current time. + +## Writing small scope integration tests with preconfigured workers + +Requirements: + +* spawn nodes with preconfigured behaviors +* allow multiple types of configuration to be specified +* allow extendability via external crates +* ... + +--- + +## Implementation of different behavior strain nodes + +### Goals + +The main goals are is to allow creating a test node which +exhibits a certain behavior by utilizing a subset of _wrapped_ or _replaced_ subsystems easily. +The runtime must not matter at all for these tests and should be simplistic. +The execution must be fast, this mostly means to assure a close to zero network latency as +well as shorting the block time and epoch times down to a few `100ms` and a few dozend blocks per epoch. + +### Approach + +#### MVP + +A simple small scale builder pattern would suffice for stage one implementation of allowing to +replace individual subsystems. +An alternative would be to harness the existing `AllSubsystems` type +and replace the subsystems as needed. + +#### Full `proc-macro` implementation + +`Overseer` is a common pattern. +It could be extracted as `proc` macro and generative `proc-macro`. +This would replace the `AllSubsystems` type as well as implicitly create +the `AllMessages` enum as `AllSubsystemsGen` does today. + +The implementation is yet to be completed, see the [implementation PR](https://github.com/paritytech/polkadot/pull/2962) for details. + +##### Declare an overseer implementation + +```rust +struct BehaveMaleficient; + +impl OverseerGen for BehaveMaleficient { + fn generate<'a, Spawner, RuntimeClient>( + &self, + args: OverseerGenArgs<'a, Spawner, RuntimeClient>, + ) -> Result<(Overseer>, OverseerHandler), Error> + where + RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, + RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + Spawner: 'static + overseer::gen::Spawner + Clone + Unpin, + { + let spawner = args.spawner.clone(); + let leaves = args.leaves.clone(); + let runtime_client = args.runtime_client.clone(); + let registry = args.registry.clone(); + let candidate_validation_config = args.candidate_validation_config.clone(); + // modify the subsystem(s) as needed: + let all_subsystems = create_default_subsystems(args)?. + // or spawn an entirely new set + + replace_candidate_validation( + // create the filtered subsystem + FilteredSubsystem::new( + CandidateValidationSubsystem::with_config( + candidate_validation_config, + Metrics::register(registry)?, + ), + // an implementation of + Skippy::default(), + ), + ); + + Overseer::new(leaves, all_subsystems, registry, runtime_client, spawner) + .map_err(|e| e.into()) + + // A builder pattern will simplify this further + // WIP https://github.com/paritytech/polkadot/pull/2962 + } +} + +fn main() -> eyre::Result<()> { + color_eyre::install()?; + let cli = Cli::from_args(); + assert_matches::assert_matches!(cli.subcommand, None); + polkadot_cli::run_node(cli, BehaveMaleficient)?; + Ok(()) +} +``` + +[`variant-a`](../node/malus/src/variant-a.rs) is a fully working example. + +#### Simnet + +Spawn a kubernetes cluster based on a meta description using [Gurke] with the +[Simnet] scripts. + +Coordinated attacks of multiple nodes or subsystems must be made possible via +a side-channel, that is out of scope for this document. + +The individual node configurations are done as targets with a particular +builder configuration. + +#### Behavior tests w/o Simnet + +Commonly this will require multiple nodes, and most machines are limited to +running two or three nodes concurrently. +Hence, this is not the common case and is just an implementation _idea_. + +```rust +behavior_testcase!{ +"TestRuntime" => +"Alice": , +"Bob": , +"Charles": Default, +"David": "Charles", +"Eve": "Bob", +} +``` + +[Gurke]: https://github.com/paritytech/gurke +[simnet]: https://github.com/paritytech/simnet_scripts diff --git a/polkadot/erasure-coding/Cargo.toml b/polkadot/erasure-coding/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..8dfb775c6f49be4d5bdb9f66faf4dc828095c3ae --- /dev/null +++ b/polkadot/erasure-coding/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "polkadot-erasure-coding" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +polkadot-primitives = { path = "../primitives" } +polkadot-node-primitives = { package = "polkadot-node-primitives", path = "../node/primitives" } +novelpoly = { package = "reed-solomon-novelpoly", version = "1.0.0" } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["std", "derive"] } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } +thiserror = "1.0.31" + +[dev-dependencies] +criterion = { version = "0.4.0", default-features = false, features = ["cargo_bench_support"] } + +[[bench]] +name = "scaling_with_validators" +harness = false diff --git a/polkadot/erasure-coding/benches/README.md b/polkadot/erasure-coding/benches/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e643643229e882bee30c5a6c727e239a17794c02 --- /dev/null +++ b/polkadot/erasure-coding/benches/README.md @@ -0,0 +1,39 @@ +### Run benches +``` +$ cd erasure-coding # ensure you are in the right directory +$ cargo bench +``` + +### `scaling_with_validators` + +This benchmark evaluates the performance of constructing the chunks and the erasure root from PoV and +reconstructing the PoV from chunks. You can see the results of running this bench on 5950x below. +Interestingly, with `10_000` chunks (validators) its slower than with `50_000` for both construction +and reconstruction. +``` +construct/200 time: [93.924 ms 94.525 ms 95.214 ms] + thrpt: [52.513 MiB/s 52.896 MiB/s 53.234 MiB/s] +construct/500 time: [111.25 ms 111.52 ms 111.80 ms] + thrpt: [44.721 MiB/s 44.837 MiB/s 44.946 MiB/s] +construct/1000 time: [117.37 ms 118.28 ms 119.21 ms] + thrpt: [41.941 MiB/s 42.273 MiB/s 42.601 MiB/s] +construct/2000 time: [125.05 ms 125.72 ms 126.38 ms] + thrpt: [39.564 MiB/s 39.772 MiB/s 39.983 MiB/s] +construct/10000 time: [270.46 ms 275.11 ms 279.81 ms] + thrpt: [17.869 MiB/s 18.174 MiB/s 18.487 MiB/s] +construct/50000 time: [205.86 ms 209.66 ms 213.64 ms] + thrpt: [23.404 MiB/s 23.848 MiB/s 24.288 MiB/s] + +reconstruct/200 time: [180.73 ms 184.09 ms 187.73 ms] + thrpt: [26.634 MiB/s 27.160 MiB/s 27.666 MiB/s] +reconstruct/500 time: [195.59 ms 198.58 ms 201.76 ms] + thrpt: [24.781 MiB/s 25.179 MiB/s 25.564 MiB/s] +reconstruct/1000 time: [207.92 ms 211.57 ms 215.57 ms] + thrpt: [23.195 MiB/s 23.633 MiB/s 24.048 MiB/s] +reconstruct/2000 time: [218.59 ms 223.68 ms 229.18 ms] + thrpt: [21.817 MiB/s 22.354 MiB/s 22.874 MiB/s] +reconstruct/10000 time: [496.35 ms 505.17 ms 515.42 ms] + thrpt: [9.7008 MiB/s 9.8977 MiB/s 10.074 MiB/s] +reconstruct/50000 time: [276.56 ms 277.53 ms 278.58 ms] + thrpt: [17.948 MiB/s 18.016 MiB/s 18.079 MiB/s] +``` diff --git a/polkadot/erasure-coding/benches/scaling_with_validators.rs b/polkadot/erasure-coding/benches/scaling_with_validators.rs new file mode 100644 index 0000000000000000000000000000000000000000..759385bbdef4ed85e5db087d2d93c7cb51250db8 --- /dev/null +++ b/polkadot/erasure-coding/benches/scaling_with_validators.rs @@ -0,0 +1,90 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; +use polkadot_primitives::Hash; +use std::time::Duration; + +fn chunks(n_validators: usize, pov: &Vec) -> Vec> { + polkadot_erasure_coding::obtain_chunks(n_validators, pov).unwrap() +} + +fn erasure_root(n_validators: usize, pov: &Vec) -> Hash { + let chunks = chunks(n_validators, pov); + polkadot_erasure_coding::branches(&chunks).root() +} + +fn construct_and_reconstruct_5mb_pov(c: &mut Criterion) { + const N_VALIDATORS: [usize; 6] = [200, 500, 1000, 2000, 10_000, 50_000]; + + const KB: usize = 1024; + const MB: usize = 1024 * KB; + + let pov = vec![0xfe; 5 * MB]; + + let mut group = c.benchmark_group("construct"); + for n_validators in N_VALIDATORS { + let expected_root = erasure_root(n_validators, &pov); + + group.throughput(Throughput::Bytes(pov.len() as u64)); + group.bench_with_input( + BenchmarkId::from_parameter(n_validators), + &n_validators, + |b, &n| { + b.iter(|| { + let root = erasure_root(n, &pov); + assert_eq!(root, expected_root); + }); + }, + ); + } + group.finish(); + + let mut group = c.benchmark_group("reconstruct"); + for n_validators in N_VALIDATORS { + let all_chunks = chunks(n_validators, &pov); + + let mut c: Vec<_> = all_chunks.iter().enumerate().map(|(i, c)| (&c[..], i)).collect(); + let last_chunks = c.split_off((c.len() - 1) * 2 / 3); + + group.throughput(Throughput::Bytes(pov.len() as u64)); + group.bench_with_input( + BenchmarkId::from_parameter(n_validators), + &n_validators, + |b, &n| { + b.iter(|| { + let _pov: Vec = + polkadot_erasure_coding::reconstruct(n, last_chunks.clone()).unwrap(); + }); + }, + ); + } + group.finish(); +} + +fn criterion_config() -> Criterion { + Criterion::default() + .sample_size(15) + .warm_up_time(Duration::from_millis(200)) + .measurement_time(Duration::from_secs(3)) +} + +criterion_group!( + name = re_construct; + config = criterion_config(); + targets = construct_and_reconstruct_5mb_pov, +); +criterion_main!(re_construct); diff --git a/polkadot/erasure-coding/fuzzer/.gitignore b/polkadot/erasure-coding/fuzzer/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..75e32f898f47e271cd625c731d6fb197ee008b02 --- /dev/null +++ b/polkadot/erasure-coding/fuzzer/.gitignore @@ -0,0 +1,3 @@ +hfuzz_target/ +hfuzz_workspace/ +Cargo.lock diff --git a/polkadot/erasure-coding/fuzzer/Cargo.toml b/polkadot/erasure-coding/fuzzer/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..9dee8e6578404a68f4dbd52335b73b533b149112 --- /dev/null +++ b/polkadot/erasure-coding/fuzzer/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "erasure_coding_fuzzer" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +publish = false + +[dependencies] +polkadot-erasure-coding = { path = ".." } +honggfuzz = "0.5" +polkadot-primitives = { path = "../../primitives" } +primitives = { package = "polkadot-node-primitives", path = "../../node/primitives/" } + +[[bin]] +name = "reconstruct" +path = "src/reconstruct.rs" + +[[bin]] +name = "round_trip" +path = "src/round_trip.rs" diff --git a/polkadot/erasure-coding/fuzzer/src/reconstruct.rs b/polkadot/erasure-coding/fuzzer/src/reconstruct.rs new file mode 100644 index 0000000000000000000000000000000000000000..b2f9690a6fd3791f04eca052a902ab660c777e07 --- /dev/null +++ b/polkadot/erasure-coding/fuzzer/src/reconstruct.rs @@ -0,0 +1,32 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use honggfuzz::fuzz; +use polkadot_erasure_coding::*; +use primitives::AvailableData; + +fn main() { + loop { + fuzz!(|data: (usize, Vec<(Vec, usize)>)| { + let (num_validators, chunk_input) = data; + let reconstructed: Result = reconstruct_v1( + num_validators, + chunk_input.iter().map(|t| (&*t.0, t.1)).collect::>(), + ); + println!("reconstructed {:?}", reconstructed); + }); + } +} diff --git a/polkadot/erasure-coding/fuzzer/src/round_trip.rs b/polkadot/erasure-coding/fuzzer/src/round_trip.rs new file mode 100644 index 0000000000000000000000000000000000000000..2e38becf651d447d71e2b26463f0c26df277994b --- /dev/null +++ b/polkadot/erasure-coding/fuzzer/src/round_trip.rs @@ -0,0 +1,49 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use honggfuzz::fuzz; +use polkadot_erasure_coding::*; +use polkadot_primitives::PersistedValidationData; +use primitives::{AvailableData, BlockData, PoV}; +use std::sync::Arc; + +fn main() { + loop { + fuzz!(|data: &[u8]| { + let pov_block = PoV { block_data: BlockData(data.iter().cloned().collect()) }; + + let available_data = AvailableData { + pov: Arc::new(pov_block), + validation_data: PersistedValidationData::default(), + }; + let chunks = obtain_chunks_v1(10, &available_data).unwrap(); + + assert_eq!(chunks.len(), 10); + + // any 4 chunks should work. + let reconstructed: AvailableData = reconstruct_v1( + 10, + [(&*chunks[1], 1), (&*chunks[4], 4), (&*chunks[6], 6), (&*chunks[9], 9)] + .iter() + .cloned(), + ) + .unwrap(); + + assert_eq!(reconstructed, available_data); + println!("{:?}", reconstructed); + }); + } +} diff --git a/polkadot/erasure-coding/src/lib.rs b/polkadot/erasure-coding/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..36847b46371533833c7de5a36e7c9e858ec1116c --- /dev/null +++ b/polkadot/erasure-coding/src/lib.rs @@ -0,0 +1,419 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! As part of Polkadot's availability system, certain pieces of data +//! for each block are required to be kept available. +//! +//! The way we accomplish this is by erasure coding the data into n pieces +//! and constructing a merkle root of the data. +//! +//! Each of n validators stores their piece of data. We assume `n = 3f + k`, `0 < k ≤ 3`. +//! f is the maximum number of faulty validators in the system. +//! The data is coded so any f+1 chunks can be used to reconstruct the full data. + +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_primitives::{AvailableData, Proof}; +use polkadot_primitives::{BlakeTwo256, Hash as H256, HashT}; +use sp_core::Blake2Hasher; +use sp_trie::{ + trie_types::{TrieDBBuilder, TrieDBMutBuilderV0 as TrieDBMutBuilder}, + LayoutV0, MemoryDB, Trie, TrieMut, EMPTY_PREFIX, +}; +use thiserror::Error; + +use novelpoly::{CodeParams, WrappedShard}; + +// we are limited to the field order of GF(2^16), which is 65536 +const MAX_VALIDATORS: usize = novelpoly::f2e16::FIELD_SIZE; + +/// Errors in erasure coding. +#[derive(Debug, Clone, PartialEq, Error)] +pub enum Error { + /// Returned when there are too many validators. + #[error("There are too many validators")] + TooManyValidators, + /// Cannot encode something for zero or one validator + #[error("Expected at least 2 validators")] + NotEnoughValidators, + /// Cannot reconstruct: wrong number of validators. + #[error("Validator count mismatches between encoding and decoding")] + WrongValidatorCount, + /// Not enough chunks present. + #[error("Not enough chunks to reconstruct message")] + NotEnoughChunks, + /// Too many chunks present. + #[error("Too many chunks present")] + TooManyChunks, + /// Chunks not of uniform length or the chunks are empty. + #[error("Chunks are not uniform, mismatch in length or are zero sized")] + NonUniformChunks, + /// An uneven byte-length of a shard is not valid for `GF(2^16)` encoding. + #[error("Uneven length is not valid for field GF(2^16)")] + UnevenLength, + /// Chunk index out of bounds. + #[error("Chunk is out of bounds: {chunk_index} not included in 0..{n_validators}")] + ChunkIndexOutOfBounds { chunk_index: usize, n_validators: usize }, + /// Bad payload in reconstructed bytes. + #[error("Reconstructed payload invalid")] + BadPayload, + /// Invalid branch proof. + #[error("Invalid branch proof")] + InvalidBranchProof, + /// Branch out of bounds. + #[error("Branch is out of bounds")] + BranchOutOfBounds, + /// Unknown error + #[error("An unknown error has appeared when reconstructing erasure code chunks")] + UnknownReconstruction, + /// Unknown error + #[error("An unknown error has appeared when deriving code parameters from validator count")] + UnknownCodeParam, +} + +/// Obtain a threshold of chunks that should be enough to recover the data. +pub const fn recovery_threshold(n_validators: usize) -> Result { + if n_validators > MAX_VALIDATORS { + return Err(Error::TooManyValidators) + } + if n_validators <= 1 { + return Err(Error::NotEnoughValidators) + } + + let needed = n_validators.saturating_sub(1) / 3; + Ok(needed + 1) +} + +fn code_params(n_validators: usize) -> Result { + // we need to be able to reconstruct from 1/3 - eps + + let n_wanted = n_validators; + let k_wanted = recovery_threshold(n_wanted)?; + + if n_wanted > MAX_VALIDATORS as usize { + return Err(Error::TooManyValidators) + } + + CodeParams::derive_parameters(n_wanted, k_wanted).map_err(|e| match e { + novelpoly::Error::WantedShardCountTooHigh(_) => Error::TooManyValidators, + novelpoly::Error::WantedShardCountTooLow(_) => Error::NotEnoughValidators, + _ => Error::UnknownCodeParam, + }) +} + +/// Obtain erasure-coded chunks for v1 `AvailableData`, one for each validator. +/// +/// Works only up to 65536 validators, and `n_validators` must be non-zero. +pub fn obtain_chunks_v1(n_validators: usize, data: &AvailableData) -> Result>, Error> { + obtain_chunks(n_validators, data) +} + +/// Obtain erasure-coded chunks, one for each validator. +/// +/// Works only up to 65536 validators, and `n_validators` must be non-zero. +pub fn obtain_chunks(n_validators: usize, data: &T) -> Result>, Error> { + let params = code_params(n_validators)?; + let encoded = data.encode(); + + if encoded.is_empty() { + return Err(Error::BadPayload) + } + + let shards = params + .make_encoder() + .encode::(&encoded[..]) + .expect("Payload non-empty, shard sizes are uniform, and validator numbers checked; qed"); + + Ok(shards.into_iter().map(|w: WrappedShard| w.into_inner()).collect()) +} + +/// Reconstruct the v1 available data from a set of chunks. +/// +/// Provide an iterator containing chunk data and the corresponding index. +/// The indices of the present chunks must be indicated. If too few chunks +/// are provided, recovery is not possible. +/// +/// Works only up to 65536 validators, and `n_validators` must be non-zero. +pub fn reconstruct_v1<'a, I: 'a>(n_validators: usize, chunks: I) -> Result +where + I: IntoIterator, +{ + reconstruct(n_validators, chunks) +} + +/// Reconstruct decodable data from a set of chunks. +/// +/// Provide an iterator containing chunk data and the corresponding index. +/// The indices of the present chunks must be indicated. If too few chunks +/// are provided, recovery is not possible. +/// +/// Works only up to 65536 validators, and `n_validators` must be non-zero. +pub fn reconstruct<'a, I: 'a, T: Decode>(n_validators: usize, chunks: I) -> Result +where + I: IntoIterator, +{ + let params = code_params(n_validators)?; + let mut received_shards: Vec> = vec![None; n_validators]; + let mut shard_len = None; + for (chunk_data, chunk_idx) in chunks.into_iter().take(n_validators) { + if chunk_idx >= n_validators { + return Err(Error::ChunkIndexOutOfBounds { chunk_index: chunk_idx, n_validators }) + } + + let shard_len = shard_len.get_or_insert_with(|| chunk_data.len()); + + if *shard_len % 2 != 0 { + return Err(Error::UnevenLength) + } + + if *shard_len != chunk_data.len() || *shard_len == 0 { + return Err(Error::NonUniformChunks) + } + + received_shards[chunk_idx] = Some(WrappedShard::new(chunk_data.to_vec())); + } + + let res = params.make_encoder().reconstruct(received_shards); + + let payload_bytes = match res { + Err(e) => match e { + novelpoly::Error::NeedMoreShards { .. } => return Err(Error::NotEnoughChunks), + novelpoly::Error::ParamterMustBePowerOf2 { .. } => return Err(Error::UnevenLength), + novelpoly::Error::WantedShardCountTooHigh(_) => return Err(Error::TooManyValidators), + novelpoly::Error::WantedShardCountTooLow(_) => return Err(Error::NotEnoughValidators), + novelpoly::Error::PayloadSizeIsZero { .. } => return Err(Error::BadPayload), + novelpoly::Error::InconsistentShardLengths { .. } => + return Err(Error::NonUniformChunks), + _ => return Err(Error::UnknownReconstruction), + }, + Ok(payload_bytes) => payload_bytes, + }; + + Decode::decode(&mut &payload_bytes[..]).or_else(|_e| Err(Error::BadPayload)) +} + +/// An iterator that yields merkle branches and chunk data for all chunks to +/// be sent to other validators. +pub struct Branches<'a, I> { + trie_storage: MemoryDB, + root: H256, + chunks: &'a [I], + current_pos: usize, +} + +impl<'a, I: AsRef<[u8]>> Branches<'a, I> { + /// Get the trie root. + pub fn root(&self) -> H256 { + self.root + } +} + +impl<'a, I: AsRef<[u8]>> Iterator for Branches<'a, I> { + type Item = (Proof, &'a [u8]); + + fn next(&mut self) -> Option { + use sp_trie::Recorder; + + let mut recorder = Recorder::>::new(); + let res = { + let trie = TrieDBBuilder::new(&self.trie_storage, &self.root) + .with_recorder(&mut recorder) + .build(); + + (self.current_pos as u32).using_encoded(|s| trie.get(s)) + }; + + match res.expect("all nodes in trie present; qed") { + Some(_) => { + let nodes: Vec> = recorder.drain().into_iter().map(|r| r.data).collect(); + let chunk = self.chunks.get(self.current_pos).expect( + "there is a one-to-one mapping of chunks to valid merkle branches; qed", + ); + self.current_pos += 1; + Proof::try_from(nodes).ok().map(|proof| (proof, chunk.as_ref())) + }, + None => None, + } + } +} + +/// Construct a trie from chunks of an erasure-coded value. This returns the root hash and an +/// iterator of merkle proofs, one for each validator. +pub fn branches<'a, I: 'a>(chunks: &'a [I]) -> Branches<'a, I> +where + I: AsRef<[u8]>, +{ + let mut trie_storage: MemoryDB = MemoryDB::default(); + let mut root = H256::default(); + + // construct trie mapping each chunk's index to its hash. + { + let mut trie = TrieDBMutBuilder::new(&mut trie_storage, &mut root).build(); + for (i, chunk) in chunks.as_ref().iter().enumerate() { + (i as u32).using_encoded(|encoded_index| { + let chunk_hash = BlakeTwo256::hash(chunk.as_ref()); + trie.insert(encoded_index, chunk_hash.as_ref()) + .expect("a fresh trie stored in memory cannot have errors loading nodes; qed"); + }) + } + } + + Branches { trie_storage, root, chunks, current_pos: 0 } +} + +/// Verify a merkle branch, yielding the chunk hash meant to be present at that +/// index. +pub fn branch_hash(root: &H256, branch_nodes: &Proof, index: usize) -> Result { + let mut trie_storage: MemoryDB = MemoryDB::default(); + for node in branch_nodes.iter() { + (&mut trie_storage as &mut sp_trie::HashDB<_>).insert(EMPTY_PREFIX, node); + } + + let trie = TrieDBBuilder::new(&trie_storage, &root).build(); + let res = (index as u32).using_encoded(|key| { + trie.get_with(key, |raw_hash: &[u8]| H256::decode(&mut &raw_hash[..])) + }); + + match res { + Ok(Some(Ok(hash))) => Ok(hash), + Ok(Some(Err(_))) => Err(Error::InvalidBranchProof), // hash failed to decode + Ok(None) => Err(Error::BranchOutOfBounds), + Err(_) => Err(Error::InvalidBranchProof), + } +} + +// input for `codec` which draws data from the data shards +struct ShardInput<'a, I> { + remaining_len: usize, + shards: I, + cur_shard: Option<(&'a [u8], usize)>, +} + +impl<'a, I: Iterator> parity_scale_codec::Input for ShardInput<'a, I> { + fn remaining_len(&mut self) -> Result, parity_scale_codec::Error> { + Ok(Some(self.remaining_len)) + } + + fn read(&mut self, into: &mut [u8]) -> Result<(), parity_scale_codec::Error> { + let mut read_bytes = 0; + + loop { + if read_bytes == into.len() { + break + } + + let cur_shard = self.cur_shard.take().or_else(|| self.shards.next().map(|s| (s, 0))); + let (active_shard, mut in_shard) = match cur_shard { + Some((s, i)) => (s, i), + None => break, + }; + + if in_shard >= active_shard.len() { + continue + } + + let remaining_len_out = into.len() - read_bytes; + let remaining_len_shard = active_shard.len() - in_shard; + + let write_len = std::cmp::min(remaining_len_out, remaining_len_shard); + into[read_bytes..][..write_len].copy_from_slice(&active_shard[in_shard..][..write_len]); + + in_shard += write_len; + read_bytes += write_len; + self.cur_shard = Some((active_shard, in_shard)) + } + + self.remaining_len -= read_bytes; + if read_bytes == into.len() { + Ok(()) + } else { + Err("slice provided too big for input".into()) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use polkadot_node_primitives::{AvailableData, BlockData, PoV}; + + // In order to adequately compute the number of entries in the Merkle + // trie, we must account for the fixed 16-ary trie structure. + const KEY_INDEX_NIBBLE_SIZE: usize = 4; + + #[test] + fn field_order_is_right_size() { + assert_eq!(MAX_VALIDATORS, 65536); + } + + #[test] + fn round_trip_works() { + let pov = PoV { block_data: BlockData((0..255).collect()) }; + + let available_data = AvailableData { pov: pov.into(), validation_data: Default::default() }; + let chunks = obtain_chunks(10, &available_data).unwrap(); + + assert_eq!(chunks.len(), 10); + + // any 4 chunks should work. + let reconstructed: AvailableData = reconstruct( + 10, + [(&*chunks[1], 1), (&*chunks[4], 4), (&*chunks[6], 6), (&*chunks[9], 9)] + .iter() + .cloned(), + ) + .unwrap(); + + assert_eq!(reconstructed, available_data); + } + + #[test] + fn reconstruct_does_not_panic_on_low_validator_count() { + let reconstructed = reconstruct_v1(1, [].iter().cloned()); + assert_eq!(reconstructed, Err(Error::NotEnoughValidators)); + } + + fn generate_trie_and_generate_proofs(magnitude: u32) { + let n_validators = 2_u32.pow(magnitude) as usize; + let pov = PoV { block_data: BlockData(vec![2; n_validators / KEY_INDEX_NIBBLE_SIZE]) }; + + let available_data = AvailableData { pov: pov.into(), validation_data: Default::default() }; + + let chunks = obtain_chunks(magnitude as usize, &available_data).unwrap(); + + assert_eq!(chunks.len() as u32, magnitude); + + let branches = branches(chunks.as_ref()); + let root = branches.root(); + + let proofs: Vec<_> = branches.map(|(proof, _)| proof).collect(); + assert_eq!(proofs.len() as u32, magnitude); + for (i, proof) in proofs.into_iter().enumerate() { + let encode = Encode::encode(&proof); + let decode = Decode::decode(&mut &encode[..]).unwrap(); + assert_eq!(proof, decode); + assert_eq!(encode, Encode::encode(&decode)); + + assert_eq!(branch_hash(&root, &proof, i).unwrap(), BlakeTwo256::hash(&chunks[i])); + } + } + + #[test] + fn roundtrip_proof_encoding() { + for i in 2..16 { + generate_trie_and_generate_proofs(i); + } + } +} diff --git a/polkadot/file_header.txt b/polkadot/file_header.txt new file mode 100644 index 0000000000000000000000000000000000000000..47483d33a42a9e80952d99c4a8bdc513e9866d3b --- /dev/null +++ b/polkadot/file_header.txt @@ -0,0 +1,15 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . diff --git a/polkadot/grafana/README.md b/polkadot/grafana/README.md new file mode 100644 index 0000000000000000000000000000000000000000..73c5b6feacf2e1b51f19f991343382089208cd4b --- /dev/null +++ b/polkadot/grafana/README.md @@ -0,0 +1,93 @@ +# Do I need this ? + +Polkadot nodes collect and produce Prometheus metrics and logs. These include health, performance and debug +information such as last finalized block, height of the chain, and many other deeper implementation details +of the Polkadot/Substrate node subsystems. These are crucial pieces of information that one needs to successfully +monitor the liveliness and performance of a network and its validators. + +# How does it work ? + +Just import the dashboard JSON files from this folder in your Grafana installation. All dashboards are grouped in +folder percategory (like for example `parachains`). The files have been created by Grafana export functionality and +follow the data model specified [here](https://grafana.com/docs/grafana/latest/dashboards/json-model/). + +We aim to keep the dashboards here in sync with the implementation, except dashboards for development and +testing. + +# Contributing + +**Your contributions are most welcome!** + +Please make sure to follow the following design guidelines: +- Add a new entry in this file and describe the usecase and key metrics +- Ensure proper names and descriptions for dashboard panels and add relevant documentation when needed. +This is very important as not all users have similar depth of understanding of the implementation +- Have labels for axis +- All values have proper units of measurement +- A crisp and clear color scheme is used + +# Prerequisites + +Before you continue make sure you have Grafana set up, or otherwise follow this +[guide](https://wiki.polkadot.network/docs/maintain-guides-how-to-monitor-your-node). + +You might also need to [setup Loki](https://grafana.com/go/webinar/loki-getting-started/). + +# Alerting + +Alerts are currently out of the scope of the dashboards, but their setup can be done manually or automated +(see [installing and configuring Alert Manager](https://wiki.polkadot.network/docs/maintain-guides-how-to-monitor-your-node#installing-and-configuring-alertmanager-optional)) + +# Dashboards + +This section is a list of dashboards, their use case as well as the key metrics that are covered. + +## Node Versions + +Useful for monitoring versions and logs of validator nodes. Includes time series panels that +track node warning and error log rates. These can be further investigated in Grafana Loki. + +Requires Loki for log aggregation and querying. + +[Dashboard JSON](general/kusama_deployment.json) + +## Parachain Status + +This dashboard allows you to see at a glance how fast are candidates approved, disputed and +finalized. It was originally designed for observing liveliness after parachain deployment in + Kusama/Polkadot, but can be useful generally in production or testing. + +It includes panels covering key subsystems of the parachain node side implementation: +- Backing +- PVF execution +- Approval voting +- Disputes coordinator +- Chain selection + +It is important to note that this dashboard applies only for validator nodes. The prometheus +queries assume the `instance` label value contains the string `validator` only for validator nodes. + +[Dashboard JSON](parachains/status.json) + +### Key liveliness indicators +- **Relay chain finality lag**. How far behind finality is compared to the current best block. By design, + GRANDPA never finalizes past last 2 blocks, so this value is always >=2 blocks. +- **Approval checking finality lag**. The distance (in blocks) between the chain head and the last block +on which Approval voting is happening. The block is generally the highest approved ancestor of the head +block and the metric is computed during relay chain selection. +- **Disputes finality lag**. How far behind the chain head is the last approved and non disputed block. +This value is always higher than approval checking lag as it further restricts finality to only undisputed +chains. +- **PVF preparation and execution time**. Each parachain has it's own PVF (parachain validation function): +a wasm blob that is executed by validators during backing, approval checking and disputing. The PVF +preparation time refers to the time it takes for the PVF wasm to be compiled. This step is done once and +then result cached. PVF execution will use the resulting artifact to execute the PVF for a given candidate. +PVFs are expected to have a limited execution time to ensure there is enough time left for the parachain +block to be included in the relay block. +- **Time to recover and check candidate**. This is part of approval voting and covers the time it takes +to recover the candidate block available data from other validators, check it (includes PVF execution time) +and issue statement or initiate dispute. +- **Assignment delay tranches**. Approval voting is designed such that validators assigned to check a specific +candidate are split up into equal delay tranches (0.5 seconds each). All validators checks are ordered by the delay +tranche index. Early tranches of validators have the opportunity to check the candidate first before later tranches +that act as as backups in case of no shows. diff --git a/polkadot/grafana/general/kusama_deployment.json b/polkadot/grafana/general/kusama_deployment.json new file mode 100644 index 0000000000000000000000000000000000000000..1d0c6900196fd08dbb1b3e689c9234a601cb7bbf --- /dev/null +++ b/polkadot/grafana/general/kusama_deployment.json @@ -0,0 +1,928 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "description": "Monitors deployed versions, warnings and errors logged.", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": 88, + "iteration": 1640613477360, + "links": [], + "liveNow": false, + "panels": [ + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 36, + "title": "Overview", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [] + }, + "overrides": [] + }, + "gridPos": { + "h": 13, + "w": 7, + "x": 0, + "y": 1 + }, + "id": 22, + "options": { + "displayLabels": [ + "name", + "percent" + ], + "legend": { + "displayMode": "hidden", + "placement": "bottom", + "values": [ + "percent" + ] + }, + "pieType": "donut", + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": false, + "expr": "sort_desc (count by (version) (polkadot_build_info{chain=\"kusama\", instance=~\".*validator.*\"}))", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ version }}", + "refId": "A" + } + ], + "title": "Versions", + "type": "piechart" + }, + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [] + }, + "overrides": [] + }, + "gridPos": { + "h": 13, + "w": 7, + "x": 7, + "y": 1 + }, + "id": 31, + "links": [], + "options": { + "displayLabels": [ + "name", + "percent" + ], + "legend": { + "displayMode": "hidden", + "placement": "bottom" + }, + "pieType": "donut", + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "expr": "sum(count_over_time({host=~\"kusama-validator.*\", level=\"WARN\"} [1h])) by (target)", + "instant": false, + "legendFormat": "{{ target }}", + "range": true, + "refId": "A" + } + ], + "title": "Warnings / h / target", + "transformations": [], + "type": "piechart" + }, + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [] + }, + "overrides": [] + }, + "gridPos": { + "h": 13, + "w": 7, + "x": 14, + "y": 1 + }, + "id": 33, + "links": [], + "options": { + "displayLabels": [ + "name", + "percent" + ], + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "pieType": "donut", + "reduceOptions": { + "calcs": [], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "expr": "sum(count_over_time({host=~\"kusama-validator.*\", level=\"ERROR\"} [1h])) by (target)", + "instant": false, + "legendFormat": "{{ target }}", + "range": true, + "refId": "A" + } + ], + "title": "Errors / h / target", + "transformations": [], + "type": "piechart" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 16, + "panels": [], + "title": "Validator versions", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "description": "Version information for all nodes.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-RdYlGr" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 14, + "x": 0, + "y": 15 + }, + "id": 13, + "options": { + "displayMode": "lcd", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": true, + "text": { + "titleSize": 12, + "valueSize": 22 + } + }, + "pluginVersion": "8.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": false, + "expr": "sort_desc (count by (version) (polkadot_build_info{chain=\"kusama\", instance=~\".*validator.*\"}))", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ version }}", + "refId": "A" + } + ], + "title": "Versions", + "type": "bargauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "displayMode": "auto" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 232 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "name" + }, + "properties": [ + { + "id": "custom.width", + "value": 220 + } + ] + } + ] + }, + "gridPos": { + "h": 12, + "w": 10, + "x": 14, + "y": 15 + }, + "id": 20, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "frameIndex": 2, + "showHeader": true, + "sortBy": [ + { + "desc": false, + "displayName": "version (lastNotNull)" + } + ] + }, + "pluginVersion": "8.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": false, + "expr": "polkadot_build_info{instance=~\".*validator.*\",chain=\"kusama\"}", + "format": "table", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Node versions ", + "transformations": [ + { + "id": "groupBy", + "options": { + "fields": { + "name": { + "aggregations": [], + "operation": "groupby" + }, + "version": { + "aggregations": [ + "lastNotNull" + ], + "operation": "aggregate" + } + } + } + } + ], + "type": "table" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 27 + }, + "id": 18, + "panels": [], + "title": "Warnings and errors", + "type": "row" + }, + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic", + "seriesBy": "last" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "hue", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 500 + }, + { + "color": "red", + "value": 1000 + } + ] + }, + "unit": "warnings/h" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 12, + "x": 0, + "y": 28 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "expr": "sum(count_over_time({host=~\"kusama-validator.*\", level=\"WARN\"} [1h])) by (target)", + "instant": false, + "legendFormat": "{{target}}", + "range": true, + "refId": "A" + } + ], + "title": "All warnings / hour", + "transformations": [], + "type": "timeseries" + }, + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic", + "seriesBy": "last" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "hue", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 500 + }, + { + "color": "red", + "value": 1000 + } + ] + }, + "unit": "warnings/h" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 12, + "x": 12, + "y": 28 + }, + "id": 30, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "expr": "sum(count_over_time({host=~\"kusama-validator.*\", level=\"WARN\", target=\"parachain\"}[1h])) by (subtarget)", + "hide": false, + "instant": false, + "legendFormat": "{{subtarget}}", + "range": true, + "refId": "B" + } + ], + "title": "Parachain warnings/hour", + "transformations": [], + "type": "timeseries" + }, + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic", + "seriesBy": "last" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "hue", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "dark-red", + "value": 3 + } + ] + }, + "unit": "warnings/h" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 12, + "x": 0, + "y": 40 + }, + "id": 34, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "expr": "sum(count_over_time({host=~\"kusama-validator.*\", level=\"ERROR\"} [1h])) by (target)", + "instant": false, + "legendFormat": "{{target}}", + "range": true, + "refId": "A" + } + ], + "title": "All errors / hour", + "transformations": [], + "type": "timeseries" + }, + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic", + "seriesBy": "last" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "hue", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 5 + }, + { + "color": "red", + "value": 15 + } + ] + }, + "unit": "warnings/h" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 12, + "x": 12, + "y": 40 + }, + "id": 32, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P367D1C7027A603FA" + }, + "expr": "sum(count_over_time({host=~\"kusama-validator.*\", level=\"ERROR\", target=\"parachain\"}[1h])) by (subtarget)", + "hide": false, + "instant": false, + "legendFormat": "{{subtarget}}", + "range": true, + "refId": "B" + } + ], + "title": "Parachain errors/hour", + "transformations": [], + "type": "timeseries" + } + ], + "refresh": "15m", + "schemaVersion": 34, + "style": "dark", + "tags": [ + "Kusama", + "Loki", + "Logs" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "definition": "polkadot_build_info{chain=\"$chain\"}", + "description": "Version of the node", + "hide": 0, + "includeAll": true, + "label": "Version", + "multi": true, + "name": "version", + "options": [], + "query": { + "query": "polkadot_build_info{chain=\"$chain\"}", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": ".*version=\"(.*?)\".*", + "skipUrlSync": false, + "sort": 5, + "type": "query" + }, + { + "current": { + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "definition": "polkadot_sync_peers{chain=\"$chain\"}", + "description": "Validator hosts", + "hide": 0, + "includeAll": true, + "label": "Instance", + "multi": true, + "name": "instance", + "options": [], + "query": { + "query": "polkadot_sync_peers{chain=\"$chain\"}", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": ".*instance=\"(.*validator.*)*", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-7d", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Kusama Validators Overview", + "uid": "0i-QjQ82j", + "version": 29, + "weekStart": "" +} \ No newline at end of file diff --git a/polkadot/grafana/parachains/status.json b/polkadot/grafana/parachains/status.json new file mode 100644 index 0000000000000000000000000000000000000000..5942cbdf44793d611ca050eb36500086f4f0d455 --- /dev/null +++ b/polkadot/grafana/parachains/status.json @@ -0,0 +1,1826 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "description": "Information related to the operation of parachains", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 93, + "iteration": 1640613381999, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 31, + "panels": [], + "title": "Overview", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "Measures how far behind finality is compared to the current best block. By design, GRANDPA never finalizes past last 2 blocks, so this value is always >=2.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 15, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 5 + }, + { + "color": "red", + "value": 10 + } + ] + }, + "unit": "blocks" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 5, + "x": 0, + "y": 1 + }, + "id": 41, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "avg(polkadot_block_height{chain=\"$chain\",instance=~\".*validator.*\", status=\"best\"} - on( instance) polkadot_block_height{chain=\"$chain\",instance=~\".*validator.*\", status=\"finalized\"})", + "interval": "", + "legendFormat": "", + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "Relay chain finality lag (avg)", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "Measures how far behind finality is compared to the current best block. By design, GRANDPA never finalizes past last 2 blocks, so this value is always >=2.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 15, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 5 + }, + { + "color": "red", + "value": 10 + } + ] + }, + "unit": "blocks" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 5, + "x": 5, + "y": 1 + }, + "id": 44, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "avg(polkadot_parachain_approval_checking_finality_lag{chain=\"$chain\", instance=~\".*validator.*\"})", + "interval": "", + "legendFormat": "", + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "Approval checking finality lag (avg)", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "How far behind the chain head is the last approved and non disputed block. \nThis value is always higher than approval checking lag as it further restricts finality to only undisputed \nchains.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 15, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 5 + }, + { + "color": "red", + "value": 10 + } + ] + }, + "unit": "blocks" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 5, + "x": 10, + "y": 1 + }, + "id": 32, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "avg(polkadot_parachain_disputes_finality_lag{chain=\"$chain\"})", + "format": "time_series", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Disputes Finality Lag (avg)", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic", + "seriesBy": "last" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 5, + "gradientMode": "hue", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "max": 15, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "blocks" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 9, + "x": 15, + "y": 1 + }, + "id": 29, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "avg(polkadot_parachain_approval_checking_finality_lag{chain=\"$chain\", instance=~\".*validator.*\"})", + "interval": "", + "legendFormat": "Approval checking finality lag", + "queryType": "randomWalk", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "avg(polkadot_block_height{chain=\"$chain\",instance=~\".*validator.*\", status=\"best\"} - on( instance) polkadot_block_height{chain=\"$chain\",instance=~\".*validator.*\", status=\"finalized\"})", + "hide": false, + "interval": "", + "legendFormat": "Relay chain finality lag", + "queryType": "randomWalk", + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "avg(polkadot_parachain_disputes_finality_lag{chain=\"$chain\", instance=~\".*validator.*\"})", + "hide": false, + "interval": "", + "legendFormat": "Disputes finality lag", + "queryType": "randomWalk", + "refId": "B" + } + ], + "title": "Finality lag ", + "type": "timeseries" + }, + { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateInferno", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "", + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 8 + }, + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "id": 42, + "legend": { + "show": true + }, + "pluginVersion": "7.3.6", + "reverseYBuckets": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "polkadot_parachain_approval_checking_finality_lag{chain=\"$chain\", instance=~\".*validator.*\"}", + "format": "time_series", + "interval": "", + "legendFormat": "", + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "Approval checking finality lag (heatmap)", + "tooltip": { + "show": true, + "showHistogram": false + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "xBucketSize": "1m", + "yAxis": { + "format": "blocks", + "logBase": 1, + "max": "10", + "min": "0", + "show": true + }, + "yBucketBound": "auto", + "yBucketSize": 1 + }, + { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateInferno", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "", + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 8 + }, + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "id": 33, + "legend": { + "show": true + }, + "pluginVersion": "7.3.6", + "reverseYBuckets": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "polkadot_parachain_disputes_finality_lag{chain=\"$chain\", instance=~\".*validator.*\"}", + "format": "time_series", + "interval": "", + "legendFormat": "", + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "Disputes finality lag (heatmap)", + "tooltip": { + "show": true, + "showHistogram": true + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "xBucketSize": "1m", + "yAxis": { + "format": "blocks", + "logBase": 1, + "max": "10", + "min": "0", + "show": true + }, + "yBucketBound": "auto", + "yBucketSize": 1 + }, + { + "cards": {}, + "color": { + "cardColor": "#B877D9", + "colorScale": "sqrt", + "colorScheme": "interpolateInferno", + "exponent": 0.2, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "The time spent in preparing Parachain Validation Function artifacts in seconds.", + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 18 + }, + "heatmap": {}, + "hideZeroBuckets": true, + "highlightCards": true, + "id": 36, + "legend": { + "show": true + }, + "maxDataPoints": 1340, + "pluginVersion": "8.2.2", + "reverseYBuckets": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": false, + "expr": "sum(rate(polkadot_pvf_preparation_time_bucket{instance=~\".*validator.*\", chain=\"$chain\"}[$__rate_interval])) by (le)", + "format": "heatmap", + "instant": false, + "interval": "", + "legendFormat": "{{le}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "PVF preparation time (heatmap)", + "tooltip": { + "show": true, + "showHistogram": false + }, + "transformations": [], + "type": "heatmap", + "xAxis": { + "show": true + }, + "yAxis": { + "format": "s", + "logBase": 1, + "show": true + }, + "yBucketBound": "auto" + }, + { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateInferno", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "Parachain Validation Function execution time distribution. PVFs are expected to have a limited execution time to ensure there is enough time left for the parachain block to be included in the relay block. ", + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 18 + }, + "heatmap": {}, + "hideZeroBuckets": true, + "highlightCards": true, + "id": 38, + "legend": { + "show": true + }, + "maxDataPoints": 1340, + "pluginVersion": "8.3.3", + "reverseYBuckets": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": false, + "expr": "sum(increase(polkadot_pvf_execution_time_bucket{instance=~\".*validator.*\", chain=\"$chain\"}[$__rate_interval])) by (le)", + "format": "heatmap", + "instant": false, + "interval": "", + "legendFormat": "{{le}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "PVF execution time (heatmap)", + "tooltip": { + "show": true, + "showHistogram": true + }, + "tooltipDecimals": 0, + "transformations": [], + "type": "heatmap", + "xAxis": { + "show": true + }, + "yAxis": { + "decimals": 0, + "format": "s", + "logBase": 1, + "show": true + }, + "yBucketBound": "auto" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 35, + "panels": [], + "title": "Candidate backing", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "Number of candidates seconded and signed statements.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic", + "seriesBy": "max" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 29 + }, + "id": 27, + "maxDataPoints": 1340, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "sum(rate(polkadot_parachain_candidate_backing_candidates_seconded_total{chain=\"$chain\"}[$__rate_interval]))", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "Candidates seconded", + "queryType": "randomWalk", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "sum(rate(polkadot_parachain_candidate_backing_signed_statements_total{chain=\"$chain\"}[$__rate_interval]))", + "format": "time_series", + "hide": false, + "interval": "", + "legendFormat": "Statements signed", + "queryType": "randomWalk", + "refId": "B" + } + ], + "title": "Candidate backing", + "transformations": [], + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "Number of erasure-encoded chunks of data belonging to candidate blocks. ", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic", + "seriesBy": "max" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "chunks/s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 29 + }, + "id": 43, + "maxDataPoints": 1340, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "sum(rate(polkadot_parachain_received_availability_chunks_total{chain=\"$chain\", instance=~\".*validator.*\"}[$__rate_interval]))", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "Chunks received", + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "Availability", + "transformations": [], + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 37 + }, + "id": 22, + "panels": [], + "title": "Disputes", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "disputes/s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 38 + }, + "id": 39, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": false, + "expr": "sum(rate(polkadot_parachain_candidate_dispute_concluded{chain=\"$chain\"}[$__rate_interval])) by (validity)", + "interval": "", + "legendFormat": "Concluded {{validity}}", + "queryType": "randomWalk", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "exemplar": false, + "expr": "sum(rate(polkadot_parachain_candidate_disputes_total{chain=\"$chain\"}[$__rate_interval]))", + "hide": false, + "interval": "", + "legendFormat": "disputes raised", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "exemplar": false, + "expr": "sum(rate(polkadot_parachain_candidate_dispute_votes{chain=\"$chain\"}[$__rate_interval])) by (validity)", + "hide": false, + "interval": "", + "legendFormat": "{{validity}} votes", + "refId": "C" + } + ], + "title": "Dispute votes and outcomes", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "disputes/s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 38 + }, + "id": 40, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": false, + "expr": "sum(rate(polkadot_parachain_dispute_participations{chain=\"$chain\"}[$__rate_interval])) by (priority)", + "interval": "", + "legendFormat": "{{priority}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "Dispute participations", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 46 + }, + "id": 16, + "panels": [], + "title": "Candidate Validation", + "type": "row" + }, + { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateInferno", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "description": "", + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 47 + }, + "heatmap": {}, + "hideZeroBuckets": true, + "highlightCards": true, + "id": 18, + "legend": { + "show": false + }, + "pluginVersion": "8.2.2", + "reverseYBuckets": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": false, + "expr": "sum(increase(polkadot_parachain_candidate_validation_validate_from_chain_state_bucket{chain=\"$chain\"} [$__rate_interval])) by (le) +\nsum(increase(polkadot_parachain_candidate_validation_validate_from_exhaustive_bucket{chain=\"$chain\"} [$__rate_interval])) by (le) +\nsum(increase(polkadot_parachain_candidate_validation_validate_candidate_exhaustive_bucket{chain=\"$chain\"} [$__rate_interval])) by (le)\n", + "format": "heatmap", + "interval": "", + "legendFormat": "{{le}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "Candidate Validation Times (distribution)", + "tooltip": { + "show": true, + "showHistogram": false + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "yAxis": { + "decimals": 0, + "format": "s", + "logBase": 1, + "show": true + }, + "yBucketBound": "auto" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "cps" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Approvals (success)" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Assignments" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 56 + }, + "id": 26, + "interval": "6s", + "maxDataPoints": 1340, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "sum(rate(polkadot_parachain_imported_candidates_total{chain=\"$chain\"}[$__rate_interval]))", + "format": "time_series", + "hide": false, + "interval": "", + "legendFormat": "Imported", + "queryType": "randomWalk", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "sum(increase(polkadot_parachain_candidate_backing_candidates_seconded_total{chain=\"$chain\"}[$__rate_interval]))", + "format": "time_series", + "hide": false, + "interval": "", + "legendFormat": "Seconded", + "queryType": "randomWalk", + "refId": "B" + } + ], + "title": "Candidates imported/seconded", + "transformations": [], + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 56 + }, + "id": 20, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "sum(rate(polkadot_parachain_validation_requests_total{chain=\"$chain\"}[$__rate_interval])) by (validity)", + "interval": "", + "legendFormat": "{{validity}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "Candidate validation requests", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 65 + }, + "id": 2, + "panels": [], + "title": "Approval voting", + "type": "row" + }, + { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolatePlasma", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "Approval voting requires that validators which are assigned to check a specific \ncandidate are split up into delay tranches (0.5s each). Then, all validators checks are ordered by the delay \ntranche index. Early tranches of validators will check the candidate first and later tranches act as as backups in case of no shows.", + "gridPos": { + "h": 9, + "w": 18, + "x": 0, + "y": 66 + }, + "heatmap": {}, + "hideZeroBuckets": true, + "highlightCards": true, + "id": 6, + "legend": { + "show": true + }, + "pluginVersion": "8.3.3", + "reverseYBuckets": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": false, + "expr": "sum(increase(polkadot_parachain_assignments_produced_bucket{chain=\"$chain\"}[$__rate_interval])) by (le)", + "format": "heatmap", + "interval": "", + "legendFormat": "{{le}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "Assignment Delay Tranches", + "tooltip": { + "show": true, + "showHistogram": false + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "yAxis": { + "format": "short", + "logBase": 1, + "show": true + }, + "yBucketBound": "auto" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [], + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 18, + "y": 66 + }, + "id": 28, + "options": { + "displayLabels": [ + "percent", + "name" + ], + "legend": { + "displayMode": "hidden", + "placement": "right", + "values": [] + }, + "pieType": "donut", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "sum(rate(polkadot_parachain_assignments_produced_count{chain=\"$chain\"}[$__rate_interval]))", + "format": "time_series", + "interval": "", + "legendFormat": "Assignments", + "queryType": "randomWalk", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "sum(rate(polkadot_parachain_approvals_produced_total{chain=\"$chain\"}[$__rate_interval])) by (status)", + "interval": "", + "legendFormat": "Approvals ({{status}})", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "sum(rate(polkadot_parachain_approvals_no_shows_total{chain=\"$chain\"}[$__rate_interval]))", + "hide": false, + "interval": "", + "legendFormat": "No shows", + "refId": "C" + } + ], + "title": "Assignments, approvals and no shows", + "transformations": [], + "type": "piechart" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "description": "This covers the full time it takes to: recover candidate available data from other validators; check the candidate; issue statement or initiate dispute", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 75 + }, + "id": 12, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": true, + "expr": "histogram_quantile(0.95, sum(rate(polkadot_parachain_time_recover_and_approve_bucket{chain=\"$chain\"}[$__rate_interval])) by (le))", + "interval": "", + "legendFormat": "99th %", + "queryType": "randomWalk", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "expr": "histogram_quantile(0.5, sum(rate(polkadot_parachain_time_recover_and_approve_bucket{chain=\"$chain\"}[$__rate_interval])) by (le))", + "interval": "", + "legendFormat": "50th %", + "refId": "B" + } + ], + "title": "Time to Recover and Check Candidate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$data_source" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 75 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": false, + "expr": "sum(rate(polkadot_parachain_assignments_produced_count{chain=\"$chain\"}[$__rate_interval]))", + "format": "time_series", + "interval": "", + "legendFormat": "Assignments", + "queryType": "randomWalk", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P5CA6DFE95AABF258" + }, + "exemplar": false, + "expr": "sum(rate(polkadot_parachain_approvals_produced_total{chain=\"$chain\"}[$__rate_interval])) by (status)", + "interval": "", + "legendFormat": "Approvals ({{status}})", + "refId": "B" + } + ], + "title": "Assignments and approvals", + "transformations": [], + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 34, + "style": "dark", + "tags": [ + "Kusama", + "Polkadot", + "Parachains", + "On-call" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "prometheus.parity-mgmt", + "value": "prometheus.parity-mgmt" + }, + "hide": 0, + "includeAll": false, + "label": "Source of data", + "multi": false, + "name": "data_source", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": { + "selected": false, + "text": "kusama", + "value": "kusama" + }, + "hide": 0, + "includeAll": false, + "label": "Chain", + "multi": false, + "name": "chain", + "options": [ + { + "selected": true, + "text": "kusama", + "value": "kusama" + }, + { + "selected": false, + "text": "polkadot", + "value": "polkadot" + } + ], + "query": "kusama,polkadot", + "queryValue": "", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "utc", + "title": "Parachains Liveliness", + "uid": "d10KsNXny", + "version": 62, + "weekStart": "" +} \ No newline at end of file diff --git a/polkadot/node/collation-generation/Cargo.toml b/polkadot/node/collation-generation/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..60c165784673c515cfc40a446d69914bd43f21ce --- /dev/null +++ b/polkadot/node/collation-generation/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "polkadot-node-collation-generation" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +gum = { package = "tracing-gum", path = "../gum" } +polkadot-erasure-coding = { path = "../../erasure-coding" } +polkadot-node-primitives = { path = "../primitives" } +polkadot-node-subsystem = { path = "../subsystem" } +polkadot-node-subsystem-util = { path = "../subsystem-util" } +polkadot-primitives = { path = "../../primitives" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-maybe-compressed-blob = { git = "https://github.com/paritytech/substrate", branch = "master" } +thiserror = "1.0.31" +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["bit-vec", "derive"] } + +[dev-dependencies] +polkadot-node-subsystem-test-helpers = { path = "../subsystem-test-helpers" } +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../primitives/test-helpers" } +assert_matches = "1.4.0" +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/polkadot/node/collation-generation/src/error.rs b/polkadot/node/collation-generation/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..ac5db6cd7f285b266da2fa2204d92a1cb6331b1c --- /dev/null +++ b/polkadot/node/collation-generation/src/error.rs @@ -0,0 +1,33 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum Error { + #[error(transparent)] + Subsystem(#[from] polkadot_node_subsystem::SubsystemError), + #[error(transparent)] + OneshotRecv(#[from] futures::channel::oneshot::Canceled), + #[error(transparent)] + Runtime(#[from] polkadot_node_subsystem::errors::RuntimeApiError), + #[error(transparent)] + Util(#[from] polkadot_node_subsystem_util::Error), + #[error(transparent)] + Erasure(#[from] polkadot_erasure_coding::Error), +} + +pub type Result = std::result::Result; diff --git a/polkadot/node/collation-generation/src/lib.rs b/polkadot/node/collation-generation/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..27779f3d1acbb8bd05a1b3f63f1d7ebdc92bd895 --- /dev/null +++ b/polkadot/node/collation-generation/src/lib.rs @@ -0,0 +1,591 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The collation generation subsystem is the interface between polkadot and the collators. +//! +//! # Protocol +//! +//! On every `ActiveLeavesUpdate`: +//! +//! * If there is no collation generation config, ignore. +//! * Otherwise, for each `activated` head in the update: +//! * Determine if the para is scheduled on any core by fetching the `availability_cores` Runtime +//! API. +//! * Use the Runtime API subsystem to fetch the full validation data. +//! * Invoke the `collator`, and use its outputs to produce a [`CandidateReceipt`], signed with +//! the configuration's `key`. +//! * Dispatch a [`CollatorProtocolMessage::DistributeCollation`]`(receipt, pov)`. + +#![deny(missing_docs)] + +use futures::{channel::oneshot, future::FutureExt, join, select}; +use parity_scale_codec::Encode; +use polkadot_node_primitives::{ + AvailableData, Collation, CollationGenerationConfig, CollationSecondedSignal, PoV, + SubmitCollationParams, +}; +use polkadot_node_subsystem::{ + messages::{CollationGenerationMessage, CollatorProtocolMessage}, + overseer, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, RuntimeApiError, SpawnedSubsystem, + SubsystemContext, SubsystemError, SubsystemResult, +}; +use polkadot_node_subsystem_util::{ + request_availability_cores, request_persisted_validation_data, + request_staging_async_backing_params, request_validation_code, request_validation_code_hash, + request_validators, +}; +use polkadot_primitives::{ + collator_signature_payload, CandidateCommitments, CandidateDescriptor, CandidateReceipt, + CollatorPair, CoreState, Hash, Id as ParaId, OccupiedCoreAssumption, PersistedValidationData, + ValidationCodeHash, +}; +use sp_core::crypto::Pair; +use std::sync::Arc; + +mod error; + +#[cfg(test)] +mod tests; + +mod metrics; +use self::metrics::Metrics; + +const LOG_TARGET: &'static str = "parachain::collation-generation"; + +/// Collation Generation Subsystem +pub struct CollationGenerationSubsystem { + config: Option>, + metrics: Metrics, +} + +#[overseer::contextbounds(CollationGeneration, prefix = self::overseer)] +impl CollationGenerationSubsystem { + /// Create a new instance of the `CollationGenerationSubsystem`. + pub fn new(metrics: Metrics) -> Self { + Self { config: None, metrics } + } + + /// Run this subsystem + /// + /// Conceptually, this is very simple: it just loops forever. + /// + /// - On incoming overseer messages, it starts or stops jobs as appropriate. + /// - On other incoming messages, if they can be converted into `Job::ToJob` and include a hash, + /// then they're forwarded to the appropriate individual job. + /// - On outgoing messages from the jobs, it forwards them to the overseer. + /// + /// If `err_tx` is not `None`, errors are forwarded onto that channel as they occur. + /// Otherwise, most are logged and then discarded. + async fn run(mut self, mut ctx: Context) { + loop { + select! { + incoming = ctx.recv().fuse() => { + if self.handle_incoming::(incoming, &mut ctx).await { + break; + } + }, + } + } + } + + // handle an incoming message. return true if we should break afterwards. + // note: this doesn't strictly need to be a separate function; it's more an administrative + // function so that we don't clutter the run loop. It could in principle be inlined directly + // into there. it should hopefully therefore be ok that it's an async function mutably borrowing + // self. + async fn handle_incoming( + &mut self, + incoming: SubsystemResult::Message>>, + ctx: &mut Context, + ) -> bool { + match incoming { + Ok(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated, + .. + }))) => { + // follow the procedure from the guide + if let Some(config) = &self.config { + let metrics = self.metrics.clone(); + if let Err(err) = handle_new_activations( + config.clone(), + activated.into_iter().map(|v| v.hash), + ctx, + metrics, + ) + .await + { + gum::warn!(target: LOG_TARGET, err = ?err, "failed to handle new activations"); + } + } + + false + }, + Ok(FromOrchestra::Signal(OverseerSignal::Conclude)) => true, + Ok(FromOrchestra::Communication { + msg: CollationGenerationMessage::Initialize(config), + }) => { + if self.config.is_some() { + gum::error!(target: LOG_TARGET, "double initialization"); + } else { + self.config = Some(Arc::new(config)); + } + false + }, + Ok(FromOrchestra::Communication { + msg: CollationGenerationMessage::SubmitCollation(params), + }) => { + if let Some(config) = &self.config { + if let Err(err) = + handle_submit_collation(params, config, ctx, &self.metrics).await + { + gum::error!(target: LOG_TARGET, ?err, "Failed to submit collation"); + } + } else { + gum::error!(target: LOG_TARGET, "Collation submitted before initialization"); + } + + false + }, + Ok(FromOrchestra::Signal(OverseerSignal::BlockFinalized(..))) => false, + Err(err) => { + gum::error!( + target: LOG_TARGET, + err = ?err, + "error receiving message from subsystem context: {:?}", + err + ); + true + }, + } + } +} + +#[overseer::subsystem(CollationGeneration, error=SubsystemError, prefix=self::overseer)] +impl CollationGenerationSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = async move { + self.run(ctx).await; + Ok(()) + } + .boxed(); + + SpawnedSubsystem { name: "collation-generation-subsystem", future } + } +} + +#[overseer::contextbounds(CollationGeneration, prefix = self::overseer)] +async fn handle_new_activations( + config: Arc, + activated: impl IntoIterator, + ctx: &mut Context, + metrics: Metrics, +) -> crate::error::Result<()> { + // follow the procedure from the guide: + // https://paritytech.github.io/polkadot/book/node/collators/collation-generation.html + + if config.collator.is_none() { + return Ok(()) + } + + let _overall_timer = metrics.time_new_activations(); + + for relay_parent in activated { + let _relay_parent_timer = metrics.time_new_activations_relay_parent(); + + let (availability_cores, validators, async_backing_params) = join!( + request_availability_cores(relay_parent, ctx.sender()).await, + request_validators(relay_parent, ctx.sender()).await, + request_staging_async_backing_params(relay_parent, ctx.sender()).await, + ); + + let availability_cores = availability_cores??; + let n_validators = validators??.len(); + let async_backing_params = async_backing_params?.ok(); + + for (core_idx, core) in availability_cores.into_iter().enumerate() { + let _availability_core_timer = metrics.time_new_activations_availability_core(); + + let (scheduled_core, assumption) = match core { + CoreState::Scheduled(scheduled_core) => + (scheduled_core, OccupiedCoreAssumption::Free), + CoreState::Occupied(occupied_core) => match async_backing_params { + Some(params) if params.max_candidate_depth >= 1 => { + // maximum candidate depth when building on top of a block + // pending availability is necessarily 1 - the depth of the + // pending block is 0 so the child has depth 1. + + // TODO [now]: this assumes that next up == current. + // in practice we should only set `OccupiedCoreAssumption::Included` + // when the candidate occupying the core is also of the same para. + if let Some(scheduled) = occupied_core.next_up_on_available { + (scheduled, OccupiedCoreAssumption::Included) + } else { + continue + } + }, + _ => { + gum::trace!( + target: LOG_TARGET, + core_idx = %core_idx, + relay_parent = ?relay_parent, + "core is occupied. Keep going.", + ); + continue + }, + }, + CoreState::Free => { + gum::trace!( + target: LOG_TARGET, + core_idx = %core_idx, + "core is free. Keep going.", + ); + continue + }, + }; + + if scheduled_core.para_id != config.para_id { + gum::trace!( + target: LOG_TARGET, + core_idx = %core_idx, + relay_parent = ?relay_parent, + our_para = %config.para_id, + their_para = %scheduled_core.para_id, + "core is not assigned to our para. Keep going.", + ); + continue + } + + // we get validation data and validation code synchronously for each core instead of + // within the subtask loop, because we have only a single mutable handle to the + // context, so the work can't really be distributed + + let validation_data = match request_persisted_validation_data( + relay_parent, + scheduled_core.para_id, + assumption, + ctx.sender(), + ) + .await + .await?? + { + Some(v) => v, + None => { + gum::trace!( + target: LOG_TARGET, + core_idx = %core_idx, + relay_parent = ?relay_parent, + our_para = %config.para_id, + their_para = %scheduled_core.para_id, + "validation data is not available", + ); + continue + }, + }; + + let validation_code_hash = match obtain_validation_code_hash_with_assumption( + relay_parent, + scheduled_core.para_id, + assumption, + ctx.sender(), + ) + .await? + { + Some(v) => v, + None => { + gum::trace!( + target: LOG_TARGET, + core_idx = %core_idx, + relay_parent = ?relay_parent, + our_para = %config.para_id, + their_para = %scheduled_core.para_id, + "validation code hash is not found.", + ); + continue + }, + }; + + let task_config = config.clone(); + let metrics = metrics.clone(); + let mut task_sender = ctx.sender().clone(); + ctx.spawn( + "collation-builder", + Box::pin(async move { + let collator_fn = match task_config.collator.as_ref() { + Some(x) => x, + None => return, + }; + + let (collation, result_sender) = + match collator_fn(relay_parent, &validation_data).await { + Some(collation) => collation.into_inner(), + None => { + gum::debug!( + target: LOG_TARGET, + para_id = %scheduled_core.para_id, + "collator returned no collation on collate", + ); + return + }, + }; + + construct_and_distribute_receipt( + PreparedCollation { + collation, + para_id: scheduled_core.para_id, + relay_parent, + validation_data, + validation_code_hash, + n_validators, + }, + task_config.key.clone(), + &mut task_sender, + result_sender, + &metrics, + ) + .await; + }), + )?; + } + } + + Ok(()) +} + +#[overseer::contextbounds(CollationGeneration, prefix = self::overseer)] +async fn handle_submit_collation( + params: SubmitCollationParams, + config: &CollationGenerationConfig, + ctx: &mut Context, + metrics: &Metrics, +) -> crate::error::Result<()> { + let _timer = metrics.time_submit_collation(); + + let SubmitCollationParams { + relay_parent, + collation, + parent_head, + validation_code_hash, + result_sender, + } = params; + + let validators = request_validators(relay_parent, ctx.sender()).await.await??; + let n_validators = validators.len(); + + // We need to swap the parent-head data, but all other fields here will be correct. + let mut validation_data = match request_persisted_validation_data( + relay_parent, + config.para_id, + OccupiedCoreAssumption::TimedOut, + ctx.sender(), + ) + .await + .await?? + { + Some(v) => v, + None => { + gum::debug!( + target: LOG_TARGET, + relay_parent = ?relay_parent, + our_para = %config.para_id, + "No validation data for para - does it exist at this relay-parent?", + ); + return Ok(()) + }, + }; + + validation_data.parent_head = parent_head; + + let collation = PreparedCollation { + collation, + relay_parent, + para_id: config.para_id, + validation_data, + validation_code_hash, + n_validators, + }; + + construct_and_distribute_receipt( + collation, + config.key.clone(), + ctx.sender(), + result_sender, + metrics, + ) + .await; + + Ok(()) +} + +struct PreparedCollation { + collation: Collation, + para_id: ParaId, + relay_parent: Hash, + validation_data: PersistedValidationData, + validation_code_hash: ValidationCodeHash, + n_validators: usize, +} + +/// Takes a prepared collation, along with its context, and produces a candidate receipt +/// which is distributed to validators. +async fn construct_and_distribute_receipt( + collation: PreparedCollation, + key: CollatorPair, + sender: &mut impl overseer::CollationGenerationSenderTrait, + result_sender: Option>, + metrics: &Metrics, +) { + let PreparedCollation { + collation, + para_id, + relay_parent, + validation_data, + validation_code_hash, + n_validators, + } = collation; + + let persisted_validation_data_hash = validation_data.hash(); + let parent_head_data_hash = validation_data.parent_head.hash(); + + // Apply compression to the block data. + let pov = { + let pov = collation.proof_of_validity.into_compressed(); + let encoded_size = pov.encoded_size(); + + // As long as `POV_BOMB_LIMIT` is at least `max_pov_size`, this ensures + // that honest collators never produce a PoV which is uncompressed. + // + // As such, honest collators never produce an uncompressed PoV which starts with + // a compression magic number, which would lead validators to reject the collation. + if encoded_size > validation_data.max_pov_size as usize { + gum::debug!( + target: LOG_TARGET, + para_id = %para_id, + size = encoded_size, + max_size = validation_data.max_pov_size, + "PoV exceeded maximum size" + ); + + return + } + + pov + }; + + let pov_hash = pov.hash(); + + let signature_payload = collator_signature_payload( + &relay_parent, + ¶_id, + &persisted_validation_data_hash, + &pov_hash, + &validation_code_hash, + ); + + let erasure_root = match erasure_root(n_validators, validation_data, pov.clone()) { + Ok(erasure_root) => erasure_root, + Err(err) => { + gum::error!( + target: LOG_TARGET, + para_id = %para_id, + err = ?err, + "failed to calculate erasure root", + ); + return + }, + }; + + let commitments = CandidateCommitments { + upward_messages: collation.upward_messages, + horizontal_messages: collation.horizontal_messages, + new_validation_code: collation.new_validation_code, + head_data: collation.head_data, + processed_downward_messages: collation.processed_downward_messages, + hrmp_watermark: collation.hrmp_watermark, + }; + + let ccr = CandidateReceipt { + commitments_hash: commitments.hash(), + descriptor: CandidateDescriptor { + signature: key.sign(&signature_payload), + para_id, + relay_parent, + collator: key.public(), + persisted_validation_data_hash, + pov_hash, + erasure_root, + para_head: commitments.head_data.hash(), + validation_code_hash, + }, + }; + + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?ccr.hash(), + ?pov_hash, + ?relay_parent, + para_id = %para_id, + "candidate is generated", + ); + metrics.on_collation_generated(); + + sender + .send_message(CollatorProtocolMessage::DistributeCollation( + ccr, + parent_head_data_hash, + pov, + result_sender, + )) + .await; +} + +async fn obtain_validation_code_hash_with_assumption( + relay_parent: Hash, + para_id: ParaId, + assumption: OccupiedCoreAssumption, + sender: &mut impl overseer::CollationGenerationSenderTrait, +) -> crate::error::Result> { + match request_validation_code_hash(relay_parent, para_id, assumption, sender) + .await + .await? + { + Ok(Some(v)) => Ok(Some(v)), + Ok(None) => Ok(None), + Err(RuntimeApiError::NotSupported { .. }) => { + match request_validation_code(relay_parent, para_id, assumption, sender).await.await? { + Ok(Some(v)) => Ok(Some(v.hash())), + Ok(None) => Ok(None), + Err(e) => { + // We assume that the `validation_code` API is always available, so any error + // is unexpected. + Err(e.into()) + }, + } + }, + Err(e @ RuntimeApiError::Execution { .. }) => Err(e.into()), + } +} + +fn erasure_root( + n_validators: usize, + persisted_validation: PersistedValidationData, + pov: PoV, +) -> crate::error::Result { + let available_data = + AvailableData { validation_data: persisted_validation, pov: Arc::new(pov) }; + + let chunks = polkadot_erasure_coding::obtain_chunks_v1(n_validators, &available_data)?; + Ok(polkadot_erasure_coding::branches(&chunks).root()) +} diff --git a/polkadot/node/collation-generation/src/metrics.rs b/polkadot/node/collation-generation/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..c7690ec82c4fb686bfc6d6c8a661adbda2341d9e --- /dev/null +++ b/polkadot/node/collation-generation/src/metrics.rs @@ -0,0 +1,117 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) collations_generated_total: prometheus::Counter, + pub(crate) new_activations_overall: prometheus::Histogram, + pub(crate) new_activations_per_relay_parent: prometheus::Histogram, + pub(crate) new_activations_per_availability_core: prometheus::Histogram, + pub(crate) submit_collation: prometheus::Histogram, +} + +/// `CollationGenerationSubsystem` metrics. +#[derive(Default, Clone)] +pub struct Metrics(pub(crate) Option); + +impl Metrics { + pub fn on_collation_generated(&self) { + if let Some(metrics) = &self.0 { + metrics.collations_generated_total.inc(); + } + } + + /// Provide a timer for new activations which updates on drop. + pub fn time_new_activations(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.new_activations_overall.start_timer()) + } + + /// Provide a timer per relay parents which updates on drop. + pub fn time_new_activations_relay_parent( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.new_activations_per_relay_parent.start_timer()) + } + + /// Provide a timer per availability core which updates on drop. + pub fn time_new_activations_availability_core( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.new_activations_per_availability_core.start_timer()) + } + + /// Provide a timer for submitting a collation which updates on drop. + pub fn time_submit_collation(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.submit_collation.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + collations_generated_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_collations_generated_total", + "Number of collations generated." + )?, + registry, + )?, + new_activations_overall: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collation_generation_new_activations", + "Time spent within fn handle_new_activations", + ) + )?, + registry, + )?, + new_activations_per_relay_parent: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collation_generation_per_relay_parent", + "Time spent handling a particular relay parent within fn handle_new_activations" + ) + )?, + registry, + )?, + new_activations_per_availability_core: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collation_generation_per_availability_core", + "Time spent handling a particular availability core for a relay parent in fn handle_new_activations", + ) + )?, + registry, + )?, + submit_collation: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collation_generation_submit_collation", + "Time spent preparing and submitting a collation to the network protocol", + ) + )?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/collation-generation/src/tests.rs b/polkadot/node/collation-generation/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..da6b343e6aee4715e9bf45eb1a7b25aa056fca3a --- /dev/null +++ b/polkadot/node/collation-generation/src/tests.rs @@ -0,0 +1,636 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use assert_matches::assert_matches; +use futures::{ + lock::Mutex, + task::{Context as FuturesContext, Poll}, + Future, +}; +use polkadot_node_primitives::{BlockData, Collation, CollationResult, MaybeCompressedPoV, PoV}; +use polkadot_node_subsystem::{ + errors::RuntimeApiError, + messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}, +}; +use polkadot_node_subsystem_test_helpers::{subsystem_test_harness, TestSubsystemContextHandle}; +use polkadot_node_subsystem_util::TimeoutExt; +use polkadot_primitives::{ + CollatorPair, HeadData, Id as ParaId, PersistedValidationData, ScheduledCore, ValidationCode, +}; +use sp_keyring::sr25519::Keyring as Sr25519Keyring; +use std::pin::Pin; +use test_helpers::{dummy_hash, dummy_head_data, dummy_validator}; + +type VirtualOverseer = TestSubsystemContextHandle; + +fn test_harness>(test: impl FnOnce(VirtualOverseer) -> T) { + let pool = sp_core::testing::TaskExecutor::new(); + let (context, virtual_overseer) = + polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); + let subsystem = async move { + let subsystem = crate::CollationGenerationSubsystem::new(Metrics::default()); + + subsystem.run(context).await; + }; + + let test_fut = test(virtual_overseer); + + futures::pin_mut!(test_fut); + futures::executor::block_on(futures::future::join( + async move { + let mut virtual_overseer = test_fut.await; + // Ensure we have handled all responses. + if let Ok(Some(msg)) = virtual_overseer.rx.try_next() { + panic!("Did not handle all responses: {:?}", msg); + } + // Conclude. + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }, + subsystem, + )); +} + +fn test_collation() -> Collation { + Collation { + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + head_data: dummy_head_data(), + proof_of_validity: MaybeCompressedPoV::Raw(PoV { block_data: BlockData(Vec::new()) }), + processed_downward_messages: 0_u32, + hrmp_watermark: 0_u32.into(), + } +} + +fn test_collation_compressed() -> Collation { + let mut collation = test_collation(); + let compressed = collation.proof_of_validity.clone().into_compressed(); + collation.proof_of_validity = MaybeCompressedPoV::Compressed(compressed); + collation +} + +fn test_validation_data() -> PersistedValidationData { + let mut persisted_validation_data = PersistedValidationData::default(); + persisted_validation_data.max_pov_size = 1024; + persisted_validation_data +} + +// Box + Unpin + Send +struct TestCollator; + +impl Future for TestCollator { + type Output = Option; + + fn poll(self: Pin<&mut Self>, _cx: &mut FuturesContext) -> Poll { + Poll::Ready(Some(CollationResult { collation: test_collation(), result_sender: None })) + } +} + +impl Unpin for TestCollator {} + +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { + const TIMEOUT: std::time::Duration = std::time::Duration::from_millis(2000); + + overseer + .recv() + .timeout(TIMEOUT) + .await + .expect(&format!("{:?} is long enough to receive messages", TIMEOUT)) +} + +fn test_config>(para_id: Id) -> CollationGenerationConfig { + CollationGenerationConfig { + key: CollatorPair::generate().0, + collator: Some(Box::new(|_: Hash, _vd: &PersistedValidationData| TestCollator.boxed())), + para_id: para_id.into(), + } +} + +fn test_config_no_collator>(para_id: Id) -> CollationGenerationConfig { + CollationGenerationConfig { + key: CollatorPair::generate().0, + collator: None, + para_id: para_id.into(), + } +} + +fn scheduled_core_for>(para_id: Id) -> ScheduledCore { + ScheduledCore { para_id: para_id.into(), collator: None } +} + +#[test] +fn requests_availability_per_relay_parent() { + let activated_hashes: Vec = + vec![[1; 32].into(), [4; 32].into(), [9; 32].into(), [16; 32].into()]; + + let requested_availability_cores = Arc::new(Mutex::new(Vec::new())); + + let overseer_requested_availability_cores = requested_availability_cores.clone(); + let overseer = |mut handle: TestSubsystemContextHandle| async move { + loop { + match handle.try_recv().await { + None => break, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(hash, RuntimeApiRequest::AvailabilityCores(tx)))) => { + overseer_requested_availability_cores.lock().await.push(hash); + tx.send(Ok(vec![])).unwrap(); + } + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(_hash, RuntimeApiRequest::Validators(tx)))) => { + tx.send(Ok(vec![dummy_validator(); 3])).unwrap(); + } + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::StagingAsyncBackingParams( + tx, + ), + ))) => { + tx.send(Err(RuntimeApiError::NotSupported { runtime_api_name: "doesnt_matter" })).unwrap(); + }, + Some(msg) => panic!("didn't expect any other overseer requests given no availability cores; got {:?}", msg), + } + } + }; + + let subsystem_activated_hashes = activated_hashes.clone(); + subsystem_test_harness(overseer, |mut ctx| async move { + handle_new_activations( + Arc::new(test_config(123u32)), + subsystem_activated_hashes, + &mut ctx, + Metrics(None), + ) + .await + .unwrap(); + }); + + let mut requested_availability_cores = Arc::try_unwrap(requested_availability_cores) + .expect("overseer should have shut down by now") + .into_inner(); + requested_availability_cores.sort(); + + assert_eq!(requested_availability_cores, activated_hashes); +} + +#[test] +fn requests_validation_data_for_scheduled_matches() { + let activated_hashes: Vec = vec![ + Hash::repeat_byte(1), + Hash::repeat_byte(4), + Hash::repeat_byte(9), + Hash::repeat_byte(16), + ]; + + let requested_validation_data = Arc::new(Mutex::new(Vec::new())); + + let overseer_requested_validation_data = requested_validation_data.clone(); + let overseer = |mut handle: TestSubsystemContextHandle| async move { + loop { + match handle.try_recv().await { + None => break, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::AvailabilityCores(tx), + ))) => { + tx.send(Ok(vec![ + CoreState::Free, + // this is weird, see explanation below + CoreState::Scheduled(scheduled_core_for( + (hash.as_fixed_bytes()[0] * 4) as u32, + )), + CoreState::Scheduled(scheduled_core_for( + (hash.as_fixed_bytes()[0] * 5) as u32, + )), + ])) + .unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::PersistedValidationData( + _para_id, + _occupied_core_assumption, + tx, + ), + ))) => { + overseer_requested_validation_data.lock().await.push(hash); + tx.send(Ok(None)).unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::Validators(tx), + ))) => { + tx.send(Ok(vec![dummy_validator(); 3])).unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::StagingAsyncBackingParams(tx), + ))) => { + tx.send(Err(RuntimeApiError::NotSupported { + runtime_api_name: "doesnt_matter", + })) + .unwrap(); + }, + Some(msg) => { + panic!("didn't expect any other overseer requests; got {:?}", msg) + }, + } + } + }; + + subsystem_test_harness(overseer, |mut ctx| async move { + handle_new_activations( + Arc::new(test_config(16)), + activated_hashes, + &mut ctx, + Metrics(None), + ) + .await + .unwrap(); + }); + + let requested_validation_data = Arc::try_unwrap(requested_validation_data) + .expect("overseer should have shut down by now") + .into_inner(); + + // the only activated hash should be from the 4 hash: + // each activated hash generates two scheduled cores: one with its value * 4, one with its value + // * 5 given that the test configuration has a `para_id` of 16, there's only one way to get that + // value: with the 4 hash. + assert_eq!(requested_validation_data, vec![[4; 32].into()]); +} + +#[test] +fn sends_distribute_collation_message() { + let activated_hashes: Vec = vec![ + Hash::repeat_byte(1), + Hash::repeat_byte(4), + Hash::repeat_byte(9), + Hash::repeat_byte(16), + ]; + + // empty vec doesn't allocate on the heap, so it's ok we throw it away + let to_collator_protocol = Arc::new(Mutex::new(Vec::new())); + let inner_to_collator_protocol = to_collator_protocol.clone(); + + let overseer = |mut handle: TestSubsystemContextHandle| async move { + loop { + match handle.try_recv().await { + None => break, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::AvailabilityCores(tx), + ))) => { + tx.send(Ok(vec![ + CoreState::Free, + // this is weird, see explanation below + CoreState::Scheduled(scheduled_core_for( + (hash.as_fixed_bytes()[0] * 4) as u32, + )), + CoreState::Scheduled(scheduled_core_for( + (hash.as_fixed_bytes()[0] * 5) as u32, + )), + ])) + .unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::PersistedValidationData( + _para_id, + _occupied_core_assumption, + tx, + ), + ))) => { + tx.send(Ok(Some(test_validation_data()))).unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::Validators(tx), + ))) => { + tx.send(Ok(vec![dummy_validator(); 3])).unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::ValidationCodeHash( + _para_id, + OccupiedCoreAssumption::Free, + tx, + ), + ))) => { + tx.send(Ok(Some(ValidationCode(vec![1, 2, 3]).hash()))).unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::StagingAsyncBackingParams(tx), + ))) => { + tx.send(Err(RuntimeApiError::NotSupported { + runtime_api_name: "doesnt_matter", + })) + .unwrap(); + }, + Some(msg @ AllMessages::CollatorProtocol(_)) => { + inner_to_collator_protocol.lock().await.push(msg); + }, + Some(msg) => { + panic!("didn't expect any other overseer requests; got {:?}", msg) + }, + } + } + }; + + let config = Arc::new(test_config(16)); + let subsystem_config = config.clone(); + + subsystem_test_harness(overseer, |mut ctx| async move { + handle_new_activations(subsystem_config, activated_hashes, &mut ctx, Metrics(None)) + .await + .unwrap(); + }); + + let mut to_collator_protocol = Arc::try_unwrap(to_collator_protocol) + .expect("subsystem should have shut down by now") + .into_inner(); + + // we expect a single message to be sent, containing a candidate receipt. + // we don't care too much about the `commitments_hash` right now, but let's ensure that we've + // calculated the correct descriptor + let expect_pov_hash = test_collation_compressed().proof_of_validity.into_compressed().hash(); + let expect_validation_data_hash = test_validation_data().hash(); + let expect_relay_parent = Hash::repeat_byte(4); + let expect_validation_code_hash = ValidationCode(vec![1, 2, 3]).hash(); + let expect_payload = collator_signature_payload( + &expect_relay_parent, + &config.para_id, + &expect_validation_data_hash, + &expect_pov_hash, + &expect_validation_code_hash, + ); + let expect_descriptor = CandidateDescriptor { + signature: config.key.sign(&expect_payload), + para_id: config.para_id, + relay_parent: expect_relay_parent, + collator: config.key.public(), + persisted_validation_data_hash: expect_validation_data_hash, + pov_hash: expect_pov_hash, + erasure_root: dummy_hash(), // this isn't something we're checking right now + para_head: test_collation().head_data.hash(), + validation_code_hash: expect_validation_code_hash, + }; + + assert_eq!(to_collator_protocol.len(), 1); + match AllMessages::from(to_collator_protocol.pop().unwrap()) { + AllMessages::CollatorProtocol(CollatorProtocolMessage::DistributeCollation( + CandidateReceipt { descriptor, .. }, + _pov, + .., + )) => { + // signature generation is non-deterministic, so we can't just assert that the + // expected descriptor is correct. What we can do is validate that the produced + // descriptor has a valid signature, then just copy in the generated signature + // and check the rest of the fields for equality. + assert!(CollatorPair::verify( + &descriptor.signature, + &collator_signature_payload( + &descriptor.relay_parent, + &descriptor.para_id, + &descriptor.persisted_validation_data_hash, + &descriptor.pov_hash, + &descriptor.validation_code_hash, + ) + .as_ref(), + &descriptor.collator, + )); + let expect_descriptor = { + let mut expect_descriptor = expect_descriptor; + expect_descriptor.signature = descriptor.signature.clone(); + expect_descriptor.erasure_root = descriptor.erasure_root; + expect_descriptor + }; + assert_eq!(descriptor, expect_descriptor); + }, + _ => panic!("received wrong message type"), + } +} + +#[test] +fn fallback_when_no_validation_code_hash_api() { + // This is a variant of the above test, but with the validation code hash API disabled. + + let activated_hashes: Vec = vec![ + Hash::repeat_byte(1), + Hash::repeat_byte(4), + Hash::repeat_byte(9), + Hash::repeat_byte(16), + ]; + + // empty vec doesn't allocate on the heap, so it's ok we throw it away + let to_collator_protocol = Arc::new(Mutex::new(Vec::new())); + let inner_to_collator_protocol = to_collator_protocol.clone(); + + let overseer = |mut handle: TestSubsystemContextHandle| async move { + loop { + match handle.try_recv().await { + None => break, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::AvailabilityCores(tx), + ))) => { + tx.send(Ok(vec![ + CoreState::Free, + CoreState::Scheduled(scheduled_core_for( + (hash.as_fixed_bytes()[0] * 4) as u32, + )), + CoreState::Scheduled(scheduled_core_for( + (hash.as_fixed_bytes()[0] * 5) as u32, + )), + ])) + .unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::PersistedValidationData( + _para_id, + _occupied_core_assumption, + tx, + ), + ))) => { + tx.send(Ok(Some(test_validation_data()))).unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::Validators(tx), + ))) => { + tx.send(Ok(vec![dummy_validator(); 3])).unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::ValidationCodeHash( + _para_id, + OccupiedCoreAssumption::Free, + tx, + ), + ))) => { + tx.send(Err(RuntimeApiError::NotSupported { + runtime_api_name: "validation_code_hash", + })) + .unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::ValidationCode(_para_id, OccupiedCoreAssumption::Free, tx), + ))) => { + tx.send(Ok(Some(ValidationCode(vec![1, 2, 3])))).unwrap(); + }, + Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::StagingAsyncBackingParams(tx), + ))) => { + tx.send(Err(RuntimeApiError::NotSupported { + runtime_api_name: "doesnt_matter", + })) + .unwrap(); + }, + Some(msg @ AllMessages::CollatorProtocol(_)) => { + inner_to_collator_protocol.lock().await.push(msg); + }, + Some(msg) => { + panic!("didn't expect any other overseer requests; got {:?}", msg) + }, + } + } + }; + + let config = Arc::new(test_config(16u32)); + let subsystem_config = config.clone(); + + // empty vec doesn't allocate on the heap, so it's ok we throw it away + subsystem_test_harness(overseer, |mut ctx| async move { + handle_new_activations(subsystem_config, activated_hashes, &mut ctx, Metrics(None)) + .await + .unwrap(); + }); + + let to_collator_protocol = Arc::try_unwrap(to_collator_protocol) + .expect("subsystem should have shut down by now") + .into_inner(); + + let expect_validation_code_hash = ValidationCode(vec![1, 2, 3]).hash(); + + assert_eq!(to_collator_protocol.len(), 1); + match &to_collator_protocol[0] { + AllMessages::CollatorProtocol(CollatorProtocolMessage::DistributeCollation( + CandidateReceipt { descriptor, .. }, + _pov, + .., + )) => { + assert_eq!(expect_validation_code_hash, descriptor.validation_code_hash); + }, + _ => panic!("received wrong message type"), + } +} + +#[test] +fn submit_collation_is_no_op_before_initialization() { + test_harness(|mut virtual_overseer| async move { + virtual_overseer + .send(FromOrchestra::Communication { + msg: CollationGenerationMessage::SubmitCollation(SubmitCollationParams { + relay_parent: Hash::repeat_byte(0), + collation: test_collation(), + parent_head: vec![1, 2, 3].into(), + validation_code_hash: Hash::repeat_byte(1).into(), + result_sender: None, + }), + }) + .await; + + virtual_overseer + }); +} + +#[test] +fn submit_collation_leads_to_distribution() { + let relay_parent = Hash::repeat_byte(0); + let validation_code_hash = ValidationCodeHash::from(Hash::repeat_byte(42)); + let parent_head = HeadData::from(vec![1, 2, 3]); + let para_id = ParaId::from(5); + let expected_pvd = PersistedValidationData { + parent_head: parent_head.clone(), + relay_parent_number: 10, + relay_parent_storage_root: Hash::repeat_byte(1), + max_pov_size: 1024, + }; + + test_harness(|mut virtual_overseer| async move { + virtual_overseer + .send(FromOrchestra::Communication { + msg: CollationGenerationMessage::Initialize(test_config_no_collator(para_id)), + }) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: CollationGenerationMessage::SubmitCollation(SubmitCollationParams { + relay_parent, + collation: test_collation(), + parent_head: vec![1, 2, 3].into(), + validation_code_hash, + result_sender: None, + }), + }) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(rp, RuntimeApiRequest::Validators(tx))) => { + assert_eq!(rp, relay_parent); + let _ = tx.send(Ok(vec![ + Sr25519Keyring::Alice.public().into(), + Sr25519Keyring::Bob.public().into(), + Sr25519Keyring::Charlie.public().into(), + ])); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(rp, RuntimeApiRequest::PersistedValidationData(id, a, tx))) => { + assert_eq!(rp, relay_parent); + assert_eq!(id, para_id); + assert_eq!(a, OccupiedCoreAssumption::TimedOut); + + // Candidate receipt should be constructed with the real parent head. + let mut pvd = expected_pvd.clone(); + pvd.parent_head = vec![4, 5, 6].into(); + let _ = tx.send(Ok(Some(pvd))); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CollatorProtocol(CollatorProtocolMessage::DistributeCollation( + ccr, + parent_head_data_hash, + .. + )) => { + assert_eq!(parent_head_data_hash, parent_head.hash()); + assert_eq!(ccr.descriptor().persisted_validation_data_hash, expected_pvd.hash()); + assert_eq!(ccr.descriptor().para_head, dummy_head_data().hash()); + assert_eq!(ccr.descriptor().validation_code_hash, validation_code_hash); + } + ); + + virtual_overseer + }); +} diff --git a/polkadot/node/core/README.md b/polkadot/node/core/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1656bb569fe404634cacc09a449f7ed89a045d0e --- /dev/null +++ b/polkadot/node/core/README.md @@ -0,0 +1 @@ +This folder contains core subsystems, each with their own crate. diff --git a/polkadot/node/core/approval-voting/Cargo.toml b/polkadot/node/core/approval-voting/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..f31c7d0a16947206051c1ac708d273717684f9a5 --- /dev/null +++ b/polkadot/node/core/approval-voting/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "polkadot-node-core-approval-voting" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +futures-timer = "3.0.2" +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["bit-vec", "derive"] } +gum = { package = "tracing-gum", path = "../../gum" } +bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } +lru = "0.11.0" +merlin = "2.0" +schnorrkel = "0.9.1" +kvdb = "0.13.0" +derive_more = "0.99.17" +thiserror = "1.0.31" + +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-overseer = { path = "../../overseer" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-jaeger = { path = "../../jaeger" } + +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = ["full_crypto"] } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +[dev-dependencies] +async-trait = "0.1.57" +parking_lot = "0.12.0" +rand_core = "0.5.1" # should match schnorrkel +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +assert_matches = "1.4.0" +kvdb-memorydb = "0.13.0" +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/core/approval-voting/src/approval_checking.rs b/polkadot/node/core/approval-voting/src/approval_checking.rs new file mode 100644 index 0000000000000000000000000000000000000000..f345b57029b5a63f1f171578d6b2cb45d703a263 --- /dev/null +++ b/polkadot/node/core/approval-voting/src/approval_checking.rs @@ -0,0 +1,1383 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Utilities for checking whether a candidate has been approved under a given block. + +use bitvec::{order::Lsb0 as BitOrderLsb0, slice::BitSlice}; +use polkadot_node_primitives::approval::DelayTranche; +use polkadot_primitives::ValidatorIndex; + +use crate::{ + persisted_entries::{ApprovalEntry, CandidateEntry, TrancheEntry}, + time::Tick, +}; + +/// The required tranches of assignments needed to determine whether a candidate is approved. +#[derive(Debug, PartialEq, Clone)] +pub enum RequiredTranches { + /// All validators appear to be required, based on tranches already taken and remaining + /// no-shows. + All, + /// More tranches required - We're awaiting more assignments. + Pending { + /// The highest considered delay tranche when counting assignments. + considered: DelayTranche, + /// The tick at which the next no-show, of the assignments counted, would occur. + next_no_show: Option, + /// The highest tranche to consider when looking to broadcast own assignment. + /// This should be considered along with the clock drift to avoid broadcasting + /// assignments that are before the local time. + maximum_broadcast: DelayTranche, + /// The clock drift, in ticks, to apply to the local clock when determining whether + /// to broadcast an assignment or when to schedule a wakeup. The local clock should be + /// treated as though it is `clock_drift` ticks earlier. + clock_drift: Tick, + }, + /// An exact number of required tranches and a number of no-shows. This indicates that + /// at least the amount of `needed_approvals` are assigned and additionally all no-shows + /// are covered. + Exact { + /// The tranche to inspect up to. + needed: DelayTranche, + /// The amount of missing votes that should be tolerated. + tolerated_missing: usize, + /// When the next no-show would be, if any. This is used to schedule the next wakeup in the + /// event that there are some assignments that don't have corresponding approval votes. If + /// this is `None`, all assignments have approvals. + next_no_show: Option, + /// The last tick at which a needed assignment was received. + last_assignment_tick: Option, + }, +} + +/// The result of a check. +#[derive(Debug, Clone, Copy)] +pub enum Check { + /// The candidate is unapproved. + Unapproved, + /// The candidate is approved, with the given amount of no-shows, + /// with the last counted assignment being received at the given + /// tick. + Approved(usize, Option), + /// The candidate is approved by one third of all validators. + ApprovedOneThird, +} + +impl Check { + /// Whether the candidate is approved and all relevant assignments + /// have at most the given assignment tick. + pub fn is_approved(&self, max_assignment_tick: Tick) -> bool { + match *self { + Check::Unapproved => false, + Check::Approved(_, last_assignment_tick) => + last_assignment_tick.map_or(true, |t| t <= max_assignment_tick), + Check::ApprovedOneThird => true, + } + } + + /// The number of known no-shows in this computation. + pub fn known_no_shows(&self) -> usize { + match *self { + Check::Approved(n, _) => n, + _ => 0, + } + } +} + +/// Check the approval of a candidate. +pub fn check_approval( + candidate: &CandidateEntry, + approval: &ApprovalEntry, + required: RequiredTranches, +) -> Check { + // any set of size f+1 contains at least one honest node. If at least one + // honest node approves, the candidate should be approved. + let approvals = candidate.approvals(); + if 3 * approvals.count_ones() > approvals.len() { + return Check::ApprovedOneThird + } + + match required { + RequiredTranches::Pending { .. } => Check::Unapproved, + RequiredTranches::All => Check::Unapproved, + RequiredTranches::Exact { needed, tolerated_missing, last_assignment_tick, .. } => { + // whether all assigned validators up to `needed` less no_shows have approved. + // e.g. if we had 5 tranches and 1 no-show, we would accept all validators in + // tranches 0..=5 except for 1 approving. In that example, we also accept all + // validators in tranches 0..=5 approving, but that would indicate that the + // RequiredTranches value was incorrectly constructed, so it is not realistic. + // If there are more missing approvals than there are no-shows, that indicates + // that there are some assignments which are not yet no-shows, but may become + // no-shows. + + let mut assigned_mask = approval.assignments_up_to(needed); + let approvals = candidate.approvals(); + + let n_assigned = assigned_mask.count_ones(); + + // Filter the amount of assigned validators by those which have approved. + assigned_mask &= approvals; + let n_approved = assigned_mask.count_ones(); + + // note: the process of computing `required` only chooses `exact` if + // that will surpass a minimum amount of checks. + // shouldn't typically go above, since all no-shows are supposed to be covered. + if n_approved + tolerated_missing >= n_assigned { + Check::Approved(tolerated_missing, last_assignment_tick) + } else { + Check::Unapproved + } + }, + } +} + +// Determining the amount of tranches required for approval or which assignments are pending +// involves moving through a series of states while looping over the tranches +// +// that we are aware of. First, we perform an initial count of the number of assignments +// until we reach the number of needed assignments for approval. As we progress, we count the +// number of no-shows in each tranche. +// +// Then, if there are any no-shows, we proceed into a series of subsequent states for covering +// no-shows. +// +// We cover each no-show by a non-empty tranche, keeping track of the amount of further +// no-shows encountered along the way. Once all of the no-shows we were previously aware +// of are covered, we then progress to cover the no-shows we encountered while covering those, +// and so on. +#[derive(Debug)] +struct State { + /// The total number of assignments obtained. + assignments: usize, + /// The depth of no-shows we are currently covering. + depth: usize, + /// The amount of no-shows that have been covered at the previous or current depths. + covered: usize, + /// The amount of assignments that we are attempting to cover at this depth. + /// + /// At depth 0, these are the initial needed approvals, and at other depths these + /// are no-shows. + covering: usize, + /// The number of uncovered no-shows encountered at this depth. These will be the + /// `covering` of the next depth. + uncovered: usize, + /// The next tick at which a no-show would occur, if any. + next_no_show: Option, + /// The last tick at which a considered assignment was received. + last_assignment_tick: Option, +} + +impl State { + fn output( + &self, + tranche: DelayTranche, + needed_approvals: usize, + n_validators: usize, + no_show_duration: Tick, + ) -> RequiredTranches { + let covering = if self.depth == 0 { 0 } else { self.covering }; + if self.depth != 0 && self.assignments + covering + self.uncovered >= n_validators { + return RequiredTranches::All + } + + // If we have enough assignments and all no-shows are covered, we have reached the number + // of tranches that we need to have. + if self.assignments >= needed_approvals && (covering + self.uncovered) == 0 { + return RequiredTranches::Exact { + needed: tranche, + tolerated_missing: self.covered, + next_no_show: self.next_no_show, + last_assignment_tick: self.last_assignment_tick, + } + } + + // We're pending more assignments and should look at more tranches. + let clock_drift = self.clock_drift(no_show_duration); + if self.depth == 0 { + RequiredTranches::Pending { + considered: tranche, + next_no_show: self.next_no_show, + // during the initial assignment-gathering phase, we want to accept assignments + // from any tranche. Note that honest validators will still not broadcast their + // assignment until it is time to do so, regardless of this value. + maximum_broadcast: DelayTranche::max_value(), + clock_drift, + } + } else { + RequiredTranches::Pending { + considered: tranche, + next_no_show: self.next_no_show, + maximum_broadcast: tranche + (covering + self.uncovered) as DelayTranche, + clock_drift, + } + } + } + + fn clock_drift(&self, no_show_duration: Tick) -> Tick { + self.depth as Tick * no_show_duration + } + + fn advance( + &self, + new_assignments: usize, + new_no_shows: usize, + next_no_show: Option, + last_assignment_tick: Option, + ) -> State { + let new_covered = if self.depth == 0 { + new_assignments + } else { + // When covering no-shows, we treat each non-empty tranche as covering 1 assignment, + // regardless of how many assignments are within the tranche. + new_assignments.min(1) + }; + + let assignments = self.assignments + new_assignments; + let covering = self.covering.saturating_sub(new_covered); + let covered = if self.depth == 0 { + // If we're at depth 0, we're not actually covering no-shows, + // so we don't need to count them as such. + 0 + } else { + self.covered + new_covered + }; + let uncovered = self.uncovered + new_no_shows; + let next_no_show = super::min_prefer_some(self.next_no_show, next_no_show); + let last_assignment_tick = std::cmp::max(self.last_assignment_tick, last_assignment_tick); + + let (depth, covering, uncovered) = if covering == 0 { + if uncovered == 0 { + (self.depth, 0, uncovered) + } else { + (self.depth + 1, uncovered, 0) + } + } else { + (self.depth, covering, uncovered) + }; + + State { + assignments, + depth, + covered, + covering, + uncovered, + next_no_show, + last_assignment_tick, + } + } +} + +/// Constructs an infinite iterator from an array of `TrancheEntry` values. Any missing tranches +/// are filled with empty assignments, as they are needed to compute the approved tranches. +fn filled_tranche_iterator( + tranches: &[TrancheEntry], +) -> impl Iterator { + let mut gap_end = None; + + let approval_entries_filled = tranches.iter().flat_map(move |tranche_entry| { + let tranche = tranche_entry.tranche(); + let assignments = tranche_entry.assignments(); + + // The new gap_start immediately follows the prior gap_end, if one exists. + // Otherwise, on the first pass, the new gap_start is set to the first + // tranche so that the range below will be empty. + let gap_start = gap_end.map(|end| end + 1).unwrap_or(tranche); + gap_end = Some(tranche); + + (gap_start..tranche) + .map(|i| (i, &[] as &[_])) + .chain(std::iter::once((tranche, assignments))) + }); + + let pre_end = tranches.first().map(|t| t.tranche()); + let post_start = tranches.last().map_or(0, |t| t.tranche() + 1); + + let pre = pre_end.into_iter().flat_map(|pre_end| (0..pre_end).map(|i| (i, &[] as &[_]))); + let post = (post_start..).map(|i| (i, &[] as &[_])); + + pre.chain(approval_entries_filled).chain(post) +} + +/// Computes the number of `no_show` validators in a set of assignments given the relevant approvals +/// and tick parameters. This method also returns the next tick at which a `no_show` will occur +/// amongst the set of validators that have not submitted an approval. +/// +/// This also bounds the earliest tick of all assignments to be equal to the +/// block tick for the purposes of the calculation, so no assignment can be treated +/// as being received before the block itself. This is unlikely if not impossible +/// in practice, but can occur during test code. +/// +/// If the returned `next_no_show` is not None, there are two possible cases for the value of +/// based on the earliest assignment `tick` of a non-approving, yet-to-be-no-show validator: +/// - if `tick` <= `clock_drift`: the value will always be `clock_drift` + `no_show_duration`. +/// - if `tick` > `clock_drift`: the value is equal to `tick` + `no_show_duration`. +fn count_no_shows( + assignments: &[(ValidatorIndex, Tick)], + approvals: &BitSlice, + clock_drift: Tick, + block_tick: Tick, + no_show_duration: Tick, + drifted_tick_now: Tick, +) -> (usize, Option) { + let mut next_no_show = None; + let no_shows = assignments + .iter() + .map(|(v_index, tick)| { + (v_index, tick.max(&block_tick).saturating_sub(clock_drift) + no_show_duration) + }) + .filter(|&(v_index, no_show_at)| { + let has_approved = if let Some(approved) = approvals.get(v_index.0 as usize) { + *approved + } else { + return false + }; + + let is_no_show = !has_approved && no_show_at <= drifted_tick_now; + + if !is_no_show && !has_approved { + // When doing the comparison above, no_show_at and drifted_tick_now are calculated + // with the clock_drift removed. The reason for adding back the clock_drift in + // computing next_no_show is so that the scheduler knows the deadline at which + // *this node* should observe whether or not the validator is a no show. Recall + // that when the when drifted_tick_now is computed during that subsequent wake up, + // the clock drift will be removed again to do the comparison above. + next_no_show = super::min_prefer_some(next_no_show, Some(no_show_at + clock_drift)); + } + + is_no_show + }) + .count(); + + (no_shows, next_no_show) +} + +/// Determine the amount of tranches of assignments needed to determine approval of a candidate. +pub fn tranches_to_approve( + approval_entry: &ApprovalEntry, + approvals: &BitSlice, + tranche_now: DelayTranche, + block_tick: Tick, + no_show_duration: Tick, + needed_approvals: usize, +) -> RequiredTranches { + let tick_now = tranche_now as Tick + block_tick; + let n_validators = approval_entry.n_validators(); + + let initial_state = State { + assignments: 0, + depth: 0, + covered: 0, + covering: needed_approvals, + uncovered: 0, + next_no_show: None, + last_assignment_tick: None, + }; + + // The `ApprovalEntry` doesn't have any data for empty tranches. We still want to iterate over + // these empty tranches, so we create an iterator to fill the gaps. + // + // This iterator has an infinitely long amount of non-empty tranches appended to the end. + let tranches_with_gaps_filled = filled_tranche_iterator(approval_entry.tranches()); + + tranches_with_gaps_filled + .scan(Some(initial_state), |state, (tranche, assignments)| { + // The `Option` here is used for early exit. + let s = state.take()?; + + let clock_drift = s.clock_drift(no_show_duration); + let drifted_tick_now = tick_now.saturating_sub(clock_drift); + let drifted_tranche_now = drifted_tick_now.saturating_sub(block_tick) as DelayTranche; + + // Break the loop once we've taken enough tranches. + // Note that we always take tranche 0 as `drifted_tranche_now` cannot be less than 0. + if tranche > drifted_tranche_now { + return None; + } + + // Count the number of valid validator assignments. + let n_assignments = assignments.iter() + .filter(|(v_index, _)| v_index.0 < n_validators as u32) + .count(); + + // Get the latest tick of valid validator assignments. + let last_assignment_tick = assignments.iter() + .map(|(_, t)| *t) + .max(); + + // count no-shows. An assignment is a no-show if there is no corresponding approval vote + // after a fixed duration. + // + // While we count the no-shows, we also determine the next possible no-show we might + // see within this tranche. + let (no_shows, next_no_show) = count_no_shows( + assignments, + approvals, + clock_drift, + block_tick, + no_show_duration, + drifted_tick_now, + ); + + let s = s.advance(n_assignments, no_shows, next_no_show, last_assignment_tick); + let output = s.output(tranche, needed_approvals, n_validators, no_show_duration); + + *state = match output { + RequiredTranches::Exact { .. } | RequiredTranches::All => { + // Wipe the state clean so the next iteration of this closure will terminate + // the iterator. This guarantees that we can call `last` further down to see + // either a `Finished` or `Pending` result + None + } + RequiredTranches::Pending { .. } => { + // Pending results are only interesting when they are the last result of the iterator + // i.e. we never achieve a satisfactory level of assignment. + Some(s) + } + }; + + Some(output) + }) + .last() + .expect("the underlying iterator is infinite, starts at 0, and never exits early before tranche 1; qed") +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{approval_db, BTreeMap}; + use ::test_helpers::{dummy_candidate_receipt, dummy_hash}; + use bitvec::{bitvec, order::Lsb0 as BitOrderLsb0, vec::BitVec}; + use polkadot_primitives::GroupIndex; + + #[test] + fn pending_is_not_approved() { + let candidate = approval_db::v1::CandidateEntry { + candidate: dummy_candidate_receipt(dummy_hash()), + session: 0, + block_assignments: BTreeMap::default(), + approvals: BitVec::default(), + } + .into(); + + let approval_entry = approval_db::v1::ApprovalEntry { + tranches: Vec::new(), + assignments: BitVec::default(), + our_assignment: None, + our_approval_sig: None, + backing_group: GroupIndex(0), + approved: false, + } + .into(); + + assert!(!check_approval( + &candidate, + &approval_entry, + RequiredTranches::Pending { + considered: 0, + next_no_show: None, + maximum_broadcast: 0, + clock_drift: 0, + }, + ) + .is_approved(Tick::max_value())); + } + + #[test] + fn exact_takes_only_assignments_up_to() { + let mut candidate: CandidateEntry = approval_db::v1::CandidateEntry { + candidate: dummy_candidate_receipt(dummy_hash()), + session: 0, + block_assignments: BTreeMap::default(), + approvals: bitvec![u8, BitOrderLsb0; 0; 10], + } + .into(); + + for i in 0..3 { + candidate.mark_approval(ValidatorIndex(i)); + } + + let approval_entry = approval_db::v1::ApprovalEntry { + tranches: vec![ + approval_db::v1::TrancheEntry { + tranche: 0, + assignments: (0..2).map(|i| (ValidatorIndex(i), 0.into())).collect(), + }, + approval_db::v1::TrancheEntry { + tranche: 1, + assignments: (2..5).map(|i| (ValidatorIndex(i), 1.into())).collect(), + }, + approval_db::v1::TrancheEntry { + tranche: 2, + assignments: (5..10).map(|i| (ValidatorIndex(i), 0.into())).collect(), + }, + ], + assignments: bitvec![u8, BitOrderLsb0; 1; 10], + our_assignment: None, + our_approval_sig: None, + backing_group: GroupIndex(0), + approved: false, + } + .into(); + + assert!(check_approval( + &candidate, + &approval_entry, + RequiredTranches::Exact { + needed: 0, + tolerated_missing: 0, + next_no_show: None, + last_assignment_tick: None + }, + ) + .is_approved(Tick::max_value())); + assert!(!check_approval( + &candidate, + &approval_entry, + RequiredTranches::Exact { + needed: 1, + tolerated_missing: 0, + next_no_show: None, + last_assignment_tick: None + }, + ) + .is_approved(Tick::max_value())); + assert!(check_approval( + &candidate, + &approval_entry, + RequiredTranches::Exact { + needed: 1, + tolerated_missing: 2, + next_no_show: None, + last_assignment_tick: None + }, + ) + .is_approved(Tick::max_value())); + } + + #[test] + fn one_honest_node_always_approves() { + let mut candidate: CandidateEntry = approval_db::v1::CandidateEntry { + candidate: dummy_candidate_receipt(dummy_hash()), + session: 0, + block_assignments: BTreeMap::default(), + approvals: bitvec![u8, BitOrderLsb0; 0; 10], + } + .into(); + + for i in 0..3 { + candidate.mark_approval(ValidatorIndex(i)); + } + + let approval_entry = approval_db::v1::ApprovalEntry { + tranches: vec![ + approval_db::v1::TrancheEntry { + tranche: 0, + assignments: (0..4).map(|i| (ValidatorIndex(i), 0.into())).collect(), + }, + approval_db::v1::TrancheEntry { + tranche: 1, + assignments: (4..6).map(|i| (ValidatorIndex(i), 1.into())).collect(), + }, + approval_db::v1::TrancheEntry { + tranche: 2, + assignments: (6..10).map(|i| (ValidatorIndex(i), 0.into())).collect(), + }, + ], + assignments: bitvec![u8, BitOrderLsb0; 1; 10], + our_assignment: None, + our_approval_sig: None, + backing_group: GroupIndex(0), + approved: false, + } + .into(); + + let exact_all = RequiredTranches::Exact { + needed: 10, + tolerated_missing: 0, + next_no_show: None, + last_assignment_tick: None, + }; + + let pending_all = RequiredTranches::Pending { + considered: 5, + next_no_show: None, + maximum_broadcast: 8, + clock_drift: 12, + }; + + assert!(!check_approval(&candidate, &approval_entry, RequiredTranches::All,) + .is_approved(Tick::max_value())); + + assert!(!check_approval(&candidate, &approval_entry, exact_all.clone(),) + .is_approved(Tick::max_value())); + + assert!(!check_approval(&candidate, &approval_entry, pending_all.clone(),) + .is_approved(Tick::max_value())); + + // This creates a set of 4/10 approvals, which is always an approval. + candidate.mark_approval(ValidatorIndex(3)); + + assert!(check_approval(&candidate, &approval_entry, RequiredTranches::All,) + .is_approved(Tick::max_value())); + + assert!( + check_approval(&candidate, &approval_entry, exact_all,).is_approved(Tick::max_value()) + ); + + assert!(check_approval(&candidate, &approval_entry, pending_all,) + .is_approved(Tick::max_value())); + } + + #[test] + fn tranches_to_approve_everyone_present() { + let block_tick = 20; + let no_show_duration = 10; + let needed_approvals = 4; + + let mut approval_entry: ApprovalEntry = approval_db::v1::ApprovalEntry { + tranches: Vec::new(), + assignments: bitvec![u8, BitOrderLsb0; 0; 5], + our_assignment: None, + our_approval_sig: None, + backing_group: GroupIndex(0), + approved: false, + } + .into(); + + approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); + approval_entry.import_assignment(0, ValidatorIndex(1), block_tick); + + approval_entry.import_assignment(1, ValidatorIndex(2), block_tick + 1); + approval_entry.import_assignment(1, ValidatorIndex(3), block_tick + 1); + + approval_entry.import_assignment(2, ValidatorIndex(4), block_tick + 2); + + let approvals = bitvec![u8, BitOrderLsb0; 1; 5]; + + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + 2, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Exact { + needed: 1, + tolerated_missing: 0, + next_no_show: None, + last_assignment_tick: Some(21) + }, + ); + } + + #[test] + fn tranches_to_approve_not_enough_initial_count() { + let block_tick = 20; + let no_show_duration = 10; + let needed_approvals = 4; + + let mut approval_entry: ApprovalEntry = approval_db::v1::ApprovalEntry { + tranches: Vec::new(), + assignments: bitvec![u8, BitOrderLsb0; 0; 10], + our_assignment: None, + our_approval_sig: None, + backing_group: GroupIndex(0), + approved: false, + } + .into(); + + approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); + approval_entry.import_assignment(1, ValidatorIndex(2), block_tick); + + let approvals = bitvec![u8, BitOrderLsb0; 0; 10]; + + let tranche_now = 2; + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + tranche_now, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Pending { + considered: 2, + next_no_show: Some(block_tick + no_show_duration), + maximum_broadcast: DelayTranche::max_value(), + clock_drift: 0, + }, + ); + } + + #[test] + fn tranches_to_approve_no_shows_before_initial_count_treated_same_as_not_initial() { + let block_tick = 20; + let no_show_duration = 10; + let needed_approvals = 4; + + let mut approval_entry: ApprovalEntry = approval_db::v1::ApprovalEntry { + tranches: Vec::new(), + assignments: bitvec![u8, BitOrderLsb0; 0; 10], + our_assignment: None, + our_approval_sig: None, + backing_group: GroupIndex(0), + approved: false, + } + .into(); + + approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); + approval_entry.import_assignment(0, ValidatorIndex(1), block_tick); + + approval_entry.import_assignment(1, ValidatorIndex(2), block_tick); + + let mut approvals = bitvec![u8, BitOrderLsb0; 0; 10]; + approvals.set(0, true); + approvals.set(1, true); + + let tranche_now = no_show_duration as DelayTranche + 1; + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + tranche_now, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Pending { + considered: 11, + next_no_show: None, + maximum_broadcast: DelayTranche::max_value(), + clock_drift: 0, + }, + ); + } + + #[test] + fn tranches_to_approve_cover_no_show_not_enough() { + let block_tick = 20; + let no_show_duration = 10; + let needed_approvals = 4; + let n_validators = 8; + + let mut approval_entry: ApprovalEntry = approval_db::v1::ApprovalEntry { + tranches: Vec::new(), + assignments: bitvec![u8, BitOrderLsb0; 0; n_validators], + our_assignment: None, + our_approval_sig: None, + backing_group: GroupIndex(0), + approved: false, + } + .into(); + + approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); + approval_entry.import_assignment(0, ValidatorIndex(1), block_tick); + + approval_entry.import_assignment(1, ValidatorIndex(2), block_tick); + approval_entry.import_assignment(1, ValidatorIndex(3), block_tick); + + let mut approvals = bitvec![u8, BitOrderLsb0; 0; n_validators]; + approvals.set(0, true); + approvals.set(1, true); + // skip 2 + approvals.set(3, true); + + let tranche_now = no_show_duration as DelayTranche + 1; + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + tranche_now, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Pending { + considered: 1, + next_no_show: None, + maximum_broadcast: 2, // tranche 1 + 1 no-show + clock_drift: 1 * no_show_duration, + } + ); + + approvals.set(0, false); + + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + tranche_now, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Pending { + considered: 1, + next_no_show: None, + maximum_broadcast: 3, // tranche 1 + 2 no-shows + clock_drift: 1 * no_show_duration, + } + ); + } + + #[test] + fn tranches_to_approve_multi_cover_not_enough() { + let block_tick = 20; + let no_show_duration = 10; + let needed_approvals = 4; + let n_validators = 8; + + let mut approval_entry: ApprovalEntry = approval_db::v1::ApprovalEntry { + tranches: Vec::new(), + assignments: bitvec![u8, BitOrderLsb0; 0; n_validators], + our_assignment: None, + our_approval_sig: None, + backing_group: GroupIndex(0), + approved: false, + } + .into(); + + approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); + approval_entry.import_assignment(0, ValidatorIndex(1), block_tick); + + approval_entry.import_assignment(1, ValidatorIndex(2), block_tick + 1); + approval_entry.import_assignment(1, ValidatorIndex(3), block_tick + 1); + + approval_entry.import_assignment(2, ValidatorIndex(4), block_tick + no_show_duration + 2); + approval_entry.import_assignment(2, ValidatorIndex(5), block_tick + no_show_duration + 2); + + let mut approvals = bitvec![u8, BitOrderLsb0; 0; n_validators]; + approvals.set(0, true); + approvals.set(1, true); + // skip 2 + approvals.set(3, true); + // skip 4 + approvals.set(5, true); + + let tranche_now = 1; + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + tranche_now, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Exact { + needed: 1, + tolerated_missing: 0, + next_no_show: Some(block_tick + no_show_duration + 1), + last_assignment_tick: Some(block_tick + 1), + }, + ); + + // first no-show covered. + let tranche_now = no_show_duration as DelayTranche + 2; + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + tranche_now, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Exact { + needed: 2, + tolerated_missing: 1, + next_no_show: Some(block_tick + 2 * no_show_duration + 2), + last_assignment_tick: Some(block_tick + no_show_duration + 2), + }, + ); + + // another no-show in tranche 2. + let tranche_now = (no_show_duration * 2) as DelayTranche + 2; + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + tranche_now, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Pending { + considered: 2, + next_no_show: None, + maximum_broadcast: 3, // tranche 2 + 1 uncovered no-show. + clock_drift: 2 * no_show_duration, + }, + ); + } + + #[test] + fn tranches_to_approve_cover_no_show() { + let block_tick = 20; + let no_show_duration = 10; + let needed_approvals = 4; + let n_validators = 8; + + let mut approval_entry: ApprovalEntry = approval_db::v1::ApprovalEntry { + tranches: Vec::new(), + assignments: bitvec![u8, BitOrderLsb0; 0; n_validators], + our_assignment: None, + our_approval_sig: None, + backing_group: GroupIndex(0), + approved: false, + } + .into(); + + approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); + approval_entry.import_assignment(0, ValidatorIndex(1), block_tick); + + approval_entry.import_assignment(1, ValidatorIndex(2), block_tick + 1); + approval_entry.import_assignment(1, ValidatorIndex(3), block_tick + 1); + + approval_entry.import_assignment(2, ValidatorIndex(4), block_tick + no_show_duration + 2); + approval_entry.import_assignment(2, ValidatorIndex(5), block_tick + no_show_duration + 2); + + let mut approvals = bitvec![u8, BitOrderLsb0; 0; n_validators]; + approvals.set(0, true); + approvals.set(1, true); + // skip 2 + approvals.set(3, true); + approvals.set(4, true); + approvals.set(5, true); + + let tranche_now = no_show_duration as DelayTranche + 2; + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + tranche_now, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Exact { + needed: 2, + tolerated_missing: 1, + next_no_show: None, + last_assignment_tick: Some(block_tick + no_show_duration + 2) + }, + ); + + // Even though tranche 2 has 2 validators, it only covers 1 no-show. + // to cover a second no-show, we need to take another non-empty tranche. + + approvals.set(0, false); + + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + tranche_now, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Pending { + considered: 2, + next_no_show: None, + maximum_broadcast: 3, + clock_drift: no_show_duration, + }, + ); + + approval_entry.import_assignment(3, ValidatorIndex(6), block_tick); + approvals.set(6, true); + + let tranche_now = no_show_duration as DelayTranche + 3; + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + tranche_now, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Exact { + needed: 3, + tolerated_missing: 2, + next_no_show: None, + last_assignment_tick: Some(block_tick + no_show_duration + 2), + }, + ); + } + + #[test] + fn validator_indexes_out_of_range_are_ignored_in_assignments() { + let block_tick = 20; + let no_show_duration = 10; + let needed_approvals = 3; + + let mut candidate: CandidateEntry = approval_db::v1::CandidateEntry { + candidate: dummy_candidate_receipt(dummy_hash()), + session: 0, + block_assignments: BTreeMap::default(), + approvals: bitvec![u8, BitOrderLsb0; 0; 3], + } + .into(); + + for i in 0..3 { + candidate.mark_approval(ValidatorIndex(i)); + } + + let approval_entry = approval_db::v1::ApprovalEntry { + tranches: vec![ + // Assignments with invalid validator indexes. + approval_db::v1::TrancheEntry { + tranche: 1, + assignments: (2..5).map(|i| (ValidatorIndex(i), 1.into())).collect(), + }, + ], + assignments: bitvec![u8, BitOrderLsb0; 1; 3], + our_assignment: None, + our_approval_sig: None, + backing_group: GroupIndex(0), + approved: false, + } + .into(); + + let approvals = bitvec![u8, BitOrderLsb0; 0; 3]; + + let tranche_now = 10; + assert_eq!( + tranches_to_approve( + &approval_entry, + &approvals, + tranche_now, + block_tick, + no_show_duration, + needed_approvals, + ), + RequiredTranches::Pending { + considered: 10, + next_no_show: None, + maximum_broadcast: DelayTranche::max_value(), + clock_drift: 0, + }, + ); + } + + #[test] + fn filled_tranche_iterator_yields_sequential_tranches() { + const PREFIX: u32 = 10; + + let test_tranches = vec![ + vec![], // empty set + vec![0], // zero start + vec![0, 3], // zero start with gap + vec![2], // non-zero start + vec![2, 4], // non-zero start with gap + vec![0, 1, 2], // zero start with run and no gap + vec![2, 3, 4, 8], // non-zero start with run and gap + vec![0, 1, 2, 5, 6, 7], // zero start with runs and gap + ]; + + for test_tranche in test_tranches { + let mut approval_entry: ApprovalEntry = approval_db::v1::ApprovalEntry { + tranches: Vec::new(), + backing_group: GroupIndex(0), + our_assignment: None, + our_approval_sig: None, + assignments: bitvec![u8, BitOrderLsb0; 0; 3], + approved: false, + } + .into(); + + // Populate the requested tranches. The assignemnts aren't inspected in + // this test. + for &t in &test_tranche { + approval_entry.import_assignment(t, ValidatorIndex(0), 0) + } + + let filled_tranches = filled_tranche_iterator(approval_entry.tranches()); + + // Take the first PREFIX entries and map them to their tranche. + let tranches: Vec = + filled_tranches.take(PREFIX as usize).map(|e| e.0).collect(); + + // We expect this sequence to be sequential. + let exp_tranches: Vec = (0..PREFIX).collect(); + assert_eq!(tranches, exp_tranches, "for test tranches: {:?}", test_tranche); + } + } + + #[derive(Debug)] + struct NoShowTest { + assignments: Vec<(ValidatorIndex, Tick)>, + approvals: Vec, + clock_drift: crate::time::Tick, + no_show_duration: crate::time::Tick, + drifted_tick_now: crate::time::Tick, + exp_no_shows: usize, + exp_next_no_show: Option, + } + + fn test_count_no_shows(test: NoShowTest) { + let n_validators = 4; + let block_tick = 20; + + let mut approvals = bitvec![u8, BitOrderLsb0; 0; n_validators]; + for &v_index in &test.approvals { + approvals.set(v_index, true); + } + + let (no_shows, next_no_show) = count_no_shows( + &test.assignments, + &approvals, + test.clock_drift, + block_tick, + test.no_show_duration, + test.drifted_tick_now, + ); + assert_eq!(no_shows, test.exp_no_shows, "for test: {:?}", test); + assert_eq!(next_no_show, test.exp_next_no_show, "for test {:?}", test); + } + + #[test] + fn count_no_shows_empty_assignments() { + test_count_no_shows(NoShowTest { + assignments: vec![], + approvals: vec![], + clock_drift: 0, + no_show_duration: 0, + drifted_tick_now: 0, + exp_no_shows: 0, + exp_next_no_show: None, + }) + } + + #[test] + fn count_no_shows_single_validator_is_next_no_show() { + test_count_no_shows(NoShowTest { + assignments: vec![(ValidatorIndex(1), 31)], + approvals: vec![], + clock_drift: 10, + no_show_duration: 10, + drifted_tick_now: 20, + exp_no_shows: 0, + exp_next_no_show: Some(41), + }) + } + + #[test] + fn count_no_shows_single_validator_approval_at_drifted_tick_now() { + test_count_no_shows(NoShowTest { + assignments: vec![(ValidatorIndex(1), 20)], + approvals: vec![1], + clock_drift: 10, + no_show_duration: 10, + drifted_tick_now: 20, + exp_no_shows: 0, + exp_next_no_show: None, + }) + } + + #[test] + fn count_no_shows_single_validator_approval_after_drifted_tick_now() { + test_count_no_shows(NoShowTest { + assignments: vec![(ValidatorIndex(1), 21)], + approvals: vec![1], + clock_drift: 10, + no_show_duration: 10, + drifted_tick_now: 20, + exp_no_shows: 0, + exp_next_no_show: None, + }) + } + + #[test] + fn count_no_shows_two_validators_next_no_show_ordered_first() { + test_count_no_shows(NoShowTest { + assignments: vec![(ValidatorIndex(1), 31), (ValidatorIndex(2), 32)], + approvals: vec![], + clock_drift: 10, + no_show_duration: 10, + drifted_tick_now: 20, + exp_no_shows: 0, + exp_next_no_show: Some(41), + }) + } + + #[test] + fn count_no_shows_two_validators_next_no_show_ordered_last() { + test_count_no_shows(NoShowTest { + assignments: vec![(ValidatorIndex(1), 32), (ValidatorIndex(2), 31)], + approvals: vec![], + clock_drift: 10, + no_show_duration: 10, + drifted_tick_now: 20, + exp_no_shows: 0, + exp_next_no_show: Some(41), + }) + } + + #[test] + fn count_no_shows_three_validators_one_almost_late_one_no_show_one_approving() { + test_count_no_shows(NoShowTest { + assignments: vec![ + (ValidatorIndex(1), 31), + (ValidatorIndex(2), 19), + (ValidatorIndex(3), 19), + ], + approvals: vec![3], + clock_drift: 10, + no_show_duration: 10, + drifted_tick_now: 20, + exp_no_shows: 1, + exp_next_no_show: Some(41), + }) + } + + #[test] + fn count_no_shows_three_no_show_validators() { + test_count_no_shows(NoShowTest { + assignments: vec![ + (ValidatorIndex(1), 20), + (ValidatorIndex(2), 20), + (ValidatorIndex(3), 20), + ], + approvals: vec![], + clock_drift: 10, + no_show_duration: 10, + drifted_tick_now: 20, + exp_no_shows: 3, + exp_next_no_show: None, + }) + } + + #[test] + fn count_no_shows_three_approving_validators() { + test_count_no_shows(NoShowTest { + assignments: vec![ + (ValidatorIndex(1), 20), + (ValidatorIndex(2), 20), + (ValidatorIndex(3), 20), + ], + approvals: vec![1, 2, 3], + clock_drift: 10, + no_show_duration: 10, + drifted_tick_now: 20, + exp_no_shows: 0, + exp_next_no_show: None, + }) + } + + #[test] + fn count_no_shows_earliest_possible_next_no_show_is_clock_drift_plus_no_show_duration() { + test_count_no_shows(NoShowTest { + assignments: vec![(ValidatorIndex(1), 0)], + approvals: vec![], + clock_drift: 10, + no_show_duration: 20, + drifted_tick_now: 0, + exp_no_shows: 0, + exp_next_no_show: Some(40), + }) + } + + #[test] + fn count_no_shows_assignment_tick_equal_to_clock_drift_yields_earliest_possible_next_no_show() { + test_count_no_shows(NoShowTest { + assignments: vec![(ValidatorIndex(1), 10)], + approvals: vec![], + clock_drift: 10, + no_show_duration: 20, + drifted_tick_now: 0, + exp_no_shows: 0, + exp_next_no_show: Some(40), + }) + } + + #[test] + fn count_no_shows_validator_index_out_of_approvals_range_is_ignored_as_no_show() { + test_count_no_shows(NoShowTest { + assignments: vec![(ValidatorIndex(1000), 20)], + approvals: vec![], + clock_drift: 10, + no_show_duration: 10, + drifted_tick_now: 20, + exp_no_shows: 0, + exp_next_no_show: None, + }) + } + + #[test] + fn count_no_shows_validator_index_out_of_approvals_range_is_ignored_as_next_no_show() { + test_count_no_shows(NoShowTest { + assignments: vec![(ValidatorIndex(1000), 21)], + approvals: vec![], + clock_drift: 10, + no_show_duration: 10, + drifted_tick_now: 20, + exp_no_shows: 0, + exp_next_no_show: None, + }) + } + + #[test] + fn depth_0_covering_not_treated_as_such() { + let state = State { + assignments: 0, + depth: 0, + covered: 0, + covering: 10, + uncovered: 0, + next_no_show: None, + last_assignment_tick: None, + }; + + assert_eq!( + state.output(0, 10, 10, 20), + RequiredTranches::Pending { + considered: 0, + next_no_show: None, + maximum_broadcast: DelayTranche::max_value(), + clock_drift: 0, + }, + ); + } + + #[test] + fn depth_0_issued_as_exact_even_when_all() { + let state = State { + assignments: 10, + depth: 0, + covered: 0, + covering: 0, + uncovered: 0, + next_no_show: None, + last_assignment_tick: None, + }; + + assert_eq!( + state.output(0, 10, 10, 20), + RequiredTranches::Exact { + needed: 0, + tolerated_missing: 0, + next_no_show: None, + last_assignment_tick: None + }, + ); + } +} diff --git a/polkadot/node/core/approval-voting/src/approval_db/mod.rs b/polkadot/node/core/approval-voting/src/approval_db/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..f0ace95613da8d39165813e728804605e27cd373 --- /dev/null +++ b/polkadot/node/core/approval-voting/src/approval_db/mod.rs @@ -0,0 +1,33 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Approval DB accessors and writers for on-disk persisted approval storage +//! data. +//! +//! We persist data to disk although it is not intended to be used across runs of the +//! program. This is because under medium to long periods of finality stalling, for whatever +//! reason that may be, the amount of data we'd need to keep would be potentially too large +//! for memory. +//! +//! With tens or hundreds of parachains, hundreds of validators, and parablocks +//! in every relay chain block, there can be a humongous amount of information to reference +//! at any given time. +//! +//! As such, we provide a function from this module to clear the database on start-up. +//! In the future, we may use a temporary DB which doesn't need to be wiped, but for the +//! time being we share the same DB with the rest of Substrate. + +pub mod v1; diff --git a/polkadot/node/core/approval-voting/src/approval_db/v1/mod.rs b/polkadot/node/core/approval-voting/src/approval_db/v1/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..c31389269d2ef2093ffb355738ec0f998505b347 --- /dev/null +++ b/polkadot/node/core/approval-voting/src/approval_db/v1/mod.rs @@ -0,0 +1,351 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Version 1 of the DB schema. +//! +//! Note that the version here differs from the actual version of the parachains +//! database (check `CURRENT_VERSION` in `node/service/src/parachains_db/upgrade.rs`). +//! The code in this module implements the way approval voting works with +//! its data in the database. Any breaking changes here will still +//! require a db migration (check `node/service/src/parachains_db/upgrade.rs`). + +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_primitives::approval::{AssignmentCert, DelayTranche}; +use polkadot_node_subsystem::{SubsystemError, SubsystemResult}; +use polkadot_node_subsystem_util::database::{DBTransaction, Database}; +use polkadot_primitives::{ + BlockNumber, CandidateHash, CandidateReceipt, CoreIndex, GroupIndex, Hash, SessionIndex, + ValidatorIndex, ValidatorSignature, +}; +use sp_consensus_slots::Slot; + +use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; +use std::{collections::BTreeMap, sync::Arc}; + +use crate::{ + backend::{Backend, BackendWriteOp}, + persisted_entries, +}; + +const STORED_BLOCKS_KEY: &[u8] = b"Approvals_StoredBlocks"; + +#[cfg(test)] +pub mod tests; + +/// `DbBackend` is a concrete implementation of the higher-level Backend trait +pub struct DbBackend { + inner: Arc, + config: Config, +} + +impl DbBackend { + /// Create a new [`DbBackend`] with the supplied key-value store and + /// config. + pub fn new(db: Arc, config: Config) -> Self { + DbBackend { inner: db, config } + } +} + +impl Backend for DbBackend { + fn load_block_entry( + &self, + block_hash: &Hash, + ) -> SubsystemResult> { + load_block_entry(&*self.inner, &self.config, block_hash).map(|e| e.map(Into::into)) + } + + fn load_candidate_entry( + &self, + candidate_hash: &CandidateHash, + ) -> SubsystemResult> { + load_candidate_entry(&*self.inner, &self.config, candidate_hash).map(|e| e.map(Into::into)) + } + + fn load_blocks_at_height(&self, block_height: &BlockNumber) -> SubsystemResult> { + load_blocks_at_height(&*self.inner, &self.config, block_height) + } + + fn load_all_blocks(&self) -> SubsystemResult> { + load_all_blocks(&*self.inner, &self.config) + } + + fn load_stored_blocks(&self) -> SubsystemResult> { + load_stored_blocks(&*self.inner, &self.config) + } + + /// Atomically write the list of operations, with later operations taking precedence over prior. + fn write(&mut self, ops: I) -> SubsystemResult<()> + where + I: IntoIterator, + { + let mut tx = DBTransaction::new(); + for op in ops { + match op { + BackendWriteOp::WriteStoredBlockRange(stored_block_range) => { + tx.put_vec( + self.config.col_approval_data, + &STORED_BLOCKS_KEY, + stored_block_range.encode(), + ); + }, + BackendWriteOp::DeleteStoredBlockRange => { + tx.delete(self.config.col_approval_data, &STORED_BLOCKS_KEY); + }, + BackendWriteOp::WriteBlocksAtHeight(h, blocks) => { + tx.put_vec( + self.config.col_approval_data, + &blocks_at_height_key(h), + blocks.encode(), + ); + }, + BackendWriteOp::DeleteBlocksAtHeight(h) => { + tx.delete(self.config.col_approval_data, &blocks_at_height_key(h)); + }, + BackendWriteOp::WriteBlockEntry(block_entry) => { + let block_entry: BlockEntry = block_entry.into(); + tx.put_vec( + self.config.col_approval_data, + &block_entry_key(&block_entry.block_hash), + block_entry.encode(), + ); + }, + BackendWriteOp::DeleteBlockEntry(hash) => { + tx.delete(self.config.col_approval_data, &block_entry_key(&hash)); + }, + BackendWriteOp::WriteCandidateEntry(candidate_entry) => { + let candidate_entry: CandidateEntry = candidate_entry.into(); + tx.put_vec( + self.config.col_approval_data, + &candidate_entry_key(&candidate_entry.candidate.hash()), + candidate_entry.encode(), + ); + }, + BackendWriteOp::DeleteCandidateEntry(candidate_hash) => { + tx.delete(self.config.col_approval_data, &candidate_entry_key(&candidate_hash)); + }, + } + } + + self.inner.write(tx).map_err(|e| e.into()) + } +} + +/// A range from earliest..last block number stored within the DB. +#[derive(Encode, Decode, Debug, Clone, PartialEq)] +pub struct StoredBlockRange(pub BlockNumber, pub BlockNumber); + +// slot_duration * 2 + DelayTranche gives the number of delay tranches since the +// unix epoch. +#[derive(Encode, Decode, Clone, Copy, Debug, PartialEq)] +pub struct Tick(u64); + +/// Convenience type definition +pub type Bitfield = BitVec; + +/// The database config. +#[derive(Debug, Clone, Copy)] +pub struct Config { + /// The column family in the database where data is stored. + pub col_approval_data: u32, +} + +/// Details pertaining to our assignment on a block. +#[derive(Encode, Decode, Debug, Clone, PartialEq)] +pub struct OurAssignment { + pub cert: AssignmentCert, + pub tranche: DelayTranche, + pub validator_index: ValidatorIndex, + // Whether the assignment has been triggered already. + pub triggered: bool, +} + +/// Metadata regarding a specific tranche of assignments for a specific candidate. +#[derive(Encode, Decode, Debug, Clone, PartialEq)] +pub struct TrancheEntry { + pub tranche: DelayTranche, + // Assigned validators, and the instant we received their assignment, rounded + // to the nearest tick. + pub assignments: Vec<(ValidatorIndex, Tick)>, +} + +/// Metadata regarding approval of a particular candidate within the context of some +/// particular block. +#[derive(Encode, Decode, Debug, Clone, PartialEq)] +pub struct ApprovalEntry { + pub tranches: Vec, + pub backing_group: GroupIndex, + pub our_assignment: Option, + pub our_approval_sig: Option, + // `n_validators` bits. + pub assignments: Bitfield, + pub approved: bool, +} + +/// Metadata regarding approval of a particular candidate. +#[derive(Encode, Decode, Debug, Clone, PartialEq)] +pub struct CandidateEntry { + pub candidate: CandidateReceipt, + pub session: SessionIndex, + // Assignments are based on blocks, so we need to track assignments separately + // based on the block we are looking at. + pub block_assignments: BTreeMap, + pub approvals: Bitfield, +} + +/// Metadata regarding approval of a particular block, by way of approval of the +/// candidates contained within it. +#[derive(Encode, Decode, Debug, Clone, PartialEq)] +pub struct BlockEntry { + pub block_hash: Hash, + pub block_number: BlockNumber, + pub parent_hash: Hash, + pub session: SessionIndex, + pub slot: Slot, + /// Random bytes derived from the VRF submitted within the block by the block + /// author as a credential and used as input to approval assignment criteria. + pub relay_vrf_story: [u8; 32], + // The candidates included as-of this block and the index of the core they are + // leaving. Sorted ascending by core index. + pub candidates: Vec<(CoreIndex, CandidateHash)>, + // A bitfield where the i'th bit corresponds to the i'th candidate in `candidates`. + // The i'th bit is `true` iff the candidate has been approved in the context of this + // block. The block can be considered approved if the bitfield has all bits set to `true`. + pub approved_bitfield: Bitfield, + pub children: Vec, +} + +impl From for Tick { + fn from(tick: crate::Tick) -> Tick { + Tick(tick) + } +} + +impl From for crate::Tick { + fn from(tick: Tick) -> crate::Tick { + tick.0 + } +} + +/// Errors while accessing things from the DB. +#[derive(Debug, derive_more::From, derive_more::Display)] +pub enum Error { + Io(std::io::Error), + InvalidDecoding(parity_scale_codec::Error), +} + +impl std::error::Error for Error {} + +/// Result alias for DB errors. +pub type Result = std::result::Result; + +pub(crate) fn load_decode( + store: &dyn Database, + col_approval_data: u32, + key: &[u8], +) -> Result> { + match store.get(col_approval_data, key)? { + None => Ok(None), + Some(raw) => D::decode(&mut &raw[..]).map(Some).map_err(Into::into), + } +} + +/// The key a given block entry is stored under. +pub(crate) fn block_entry_key(block_hash: &Hash) -> [u8; 46] { + const BLOCK_ENTRY_PREFIX: [u8; 14] = *b"Approvals_blck"; + + let mut key = [0u8; 14 + 32]; + key[0..14].copy_from_slice(&BLOCK_ENTRY_PREFIX); + key[14..][..32].copy_from_slice(block_hash.as_ref()); + + key +} + +/// The key a given candidate entry is stored under. +pub(crate) fn candidate_entry_key(candidate_hash: &CandidateHash) -> [u8; 46] { + const CANDIDATE_ENTRY_PREFIX: [u8; 14] = *b"Approvals_cand"; + + let mut key = [0u8; 14 + 32]; + key[0..14].copy_from_slice(&CANDIDATE_ENTRY_PREFIX); + key[14..][..32].copy_from_slice(candidate_hash.0.as_ref()); + + key +} + +/// The key a set of block hashes corresponding to a block number is stored under. +pub(crate) fn blocks_at_height_key(block_number: BlockNumber) -> [u8; 16] { + const BLOCKS_AT_HEIGHT_PREFIX: [u8; 12] = *b"Approvals_at"; + + let mut key = [0u8; 12 + 4]; + key[0..12].copy_from_slice(&BLOCKS_AT_HEIGHT_PREFIX); + block_number.using_encoded(|s| key[12..16].copy_from_slice(s)); + + key +} + +/// Return all blocks which have entries in the DB, ascending, by height. +pub fn load_all_blocks(store: &dyn Database, config: &Config) -> SubsystemResult> { + let mut hashes = Vec::new(); + if let Some(stored_blocks) = load_stored_blocks(store, config)? { + for height in stored_blocks.0..stored_blocks.1 { + let blocks = load_blocks_at_height(store, config, &height)?; + hashes.extend(blocks); + } + } + + Ok(hashes) +} + +/// Load the stored-blocks key from the state. +pub fn load_stored_blocks( + store: &dyn Database, + config: &Config, +) -> SubsystemResult> { + load_decode(store, config.col_approval_data, STORED_BLOCKS_KEY) + .map_err(|e| SubsystemError::with_origin("approval-voting", e)) +} + +/// Load a blocks-at-height entry for a given block number. +pub fn load_blocks_at_height( + store: &dyn Database, + config: &Config, + block_number: &BlockNumber, +) -> SubsystemResult> { + load_decode(store, config.col_approval_data, &blocks_at_height_key(*block_number)) + .map(|x| x.unwrap_or_default()) + .map_err(|e| SubsystemError::with_origin("approval-voting", e)) +} + +/// Load a block entry from the aux store. +pub fn load_block_entry( + store: &dyn Database, + config: &Config, + block_hash: &Hash, +) -> SubsystemResult> { + load_decode(store, config.col_approval_data, &block_entry_key(block_hash)) + .map(|u: Option| u.map(|v| v.into())) + .map_err(|e| SubsystemError::with_origin("approval-voting", e)) +} + +/// Load a candidate entry from the aux store. +pub fn load_candidate_entry( + store: &dyn Database, + config: &Config, + candidate_hash: &CandidateHash, +) -> SubsystemResult> { + load_decode(store, config.col_approval_data, &candidate_entry_key(candidate_hash)) + .map(|u: Option| u.map(|v| v.into())) + .map_err(|e| SubsystemError::with_origin("approval-voting", e)) +} diff --git a/polkadot/node/core/approval-voting/src/approval_db/v1/tests.rs b/polkadot/node/core/approval-voting/src/approval_db/v1/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..07d8242b772ea9e107edf10a83cf1acd697d031f --- /dev/null +++ b/polkadot/node/core/approval-voting/src/approval_db/v1/tests.rs @@ -0,0 +1,569 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests for the aux-schema of approval voting. + +use super::{DbBackend, StoredBlockRange, *}; +use crate::{ + backend::{Backend, OverlayedBackend}, + ops::{add_block_entry, canonicalize, force_approve, NewCandidateInfo}, +}; +use polkadot_node_subsystem_util::database::Database; +use polkadot_primitives::Id as ParaId; +use std::{collections::HashMap, sync::Arc}; + +use ::test_helpers::{dummy_candidate_receipt, dummy_candidate_receipt_bad_sig, dummy_hash}; + +const DATA_COL: u32 = 0; + +const NUM_COLUMNS: u32 = 1; + +const TEST_CONFIG: Config = Config { col_approval_data: DATA_COL }; + +fn make_db() -> (DbBackend, Arc) { + let db = kvdb_memorydb::create(NUM_COLUMNS); + let db = polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter::new(db, &[]); + let db_writer: Arc = Arc::new(db); + (DbBackend::new(db_writer.clone(), TEST_CONFIG), db_writer) +} + +fn make_bitvec(len: usize) -> BitVec { + bitvec::bitvec![u8, BitOrderLsb0; 0; len] +} + +fn make_block_entry( + block_hash: Hash, + parent_hash: Hash, + block_number: BlockNumber, + candidates: Vec<(CoreIndex, CandidateHash)>, +) -> BlockEntry { + BlockEntry { + block_hash, + parent_hash, + block_number, + session: 1, + slot: Slot::from(1), + relay_vrf_story: [0u8; 32], + approved_bitfield: make_bitvec(candidates.len()), + candidates, + children: Vec::new(), + } +} + +fn make_candidate(para_id: ParaId, relay_parent: Hash) -> CandidateReceipt { + let mut c = dummy_candidate_receipt(dummy_hash()); + + c.descriptor.para_id = para_id; + c.descriptor.relay_parent = relay_parent; + + c +} + +#[test] +fn read_write() { + let (mut db, store) = make_db(); + + let hash_a = Hash::repeat_byte(1); + let hash_b = Hash::repeat_byte(2); + let candidate_hash = dummy_candidate_receipt_bad_sig(dummy_hash(), None).hash(); + + let range = StoredBlockRange(10, 20); + let at_height = vec![hash_a, hash_b]; + + let block_entry = + make_block_entry(hash_a, Default::default(), 1, vec![(CoreIndex(0), candidate_hash)]); + + let candidate_entry = CandidateEntry { + candidate: dummy_candidate_receipt_bad_sig(dummy_hash(), None), + session: 5, + block_assignments: vec![( + hash_a, + ApprovalEntry { + tranches: Vec::new(), + backing_group: GroupIndex(1), + our_assignment: None, + our_approval_sig: None, + assignments: Default::default(), + approved: false, + }, + )] + .into_iter() + .collect(), + approvals: Default::default(), + }; + + let mut overlay_db = OverlayedBackend::new(&db); + overlay_db.write_stored_block_range(range.clone()); + overlay_db.write_blocks_at_height(1, at_height.clone()); + overlay_db.write_block_entry(block_entry.clone().into()); + overlay_db.write_candidate_entry(candidate_entry.clone().into()); + + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + assert_eq!(load_stored_blocks(store.as_ref(), &TEST_CONFIG).unwrap(), Some(range)); + assert_eq!(load_blocks_at_height(store.as_ref(), &TEST_CONFIG, &1).unwrap(), at_height); + assert_eq!( + load_block_entry(store.as_ref(), &TEST_CONFIG, &hash_a).unwrap(), + Some(block_entry.into()) + ); + assert_eq!( + load_candidate_entry(store.as_ref(), &TEST_CONFIG, &candidate_hash).unwrap(), + Some(candidate_entry.into()), + ); + + let mut overlay_db = OverlayedBackend::new(&db); + overlay_db.delete_blocks_at_height(1); + overlay_db.delete_block_entry(&hash_a); + overlay_db.delete_candidate_entry(&candidate_hash); + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + assert!(load_blocks_at_height(store.as_ref(), &TEST_CONFIG, &1).unwrap().is_empty()); + assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &hash_a).unwrap().is_none()); + assert!(load_candidate_entry(store.as_ref(), &TEST_CONFIG, &candidate_hash) + .unwrap() + .is_none()); +} + +#[test] +fn add_block_entry_works() { + let (mut db, store) = make_db(); + + let parent_hash = Hash::repeat_byte(1); + let block_hash_a = Hash::repeat_byte(2); + let block_hash_b = Hash::repeat_byte(69); + + let candidate_receipt_a = make_candidate(ParaId::from(1_u32), parent_hash); + let candidate_receipt_b = make_candidate(ParaId::from(2_u32), parent_hash); + + let candidate_hash_a = candidate_receipt_a.hash(); + let candidate_hash_b = candidate_receipt_b.hash(); + + let block_number = 10; + + let block_entry_a = make_block_entry( + block_hash_a, + parent_hash, + block_number, + vec![(CoreIndex(0), candidate_hash_a)], + ); + + let block_entry_b = make_block_entry( + block_hash_b, + parent_hash, + block_number, + vec![(CoreIndex(0), candidate_hash_a), (CoreIndex(1), candidate_hash_b)], + ); + + let n_validators = 10; + + let mut new_candidate_info = HashMap::new(); + new_candidate_info + .insert(candidate_hash_a, NewCandidateInfo::new(candidate_receipt_a, GroupIndex(0), None)); + + let mut overlay_db = OverlayedBackend::new(&db); + add_block_entry(&mut overlay_db, block_entry_a.clone().into(), n_validators, |h| { + new_candidate_info.get(h).map(|x| x.clone()) + }) + .unwrap(); + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + new_candidate_info + .insert(candidate_hash_b, NewCandidateInfo::new(candidate_receipt_b, GroupIndex(1), None)); + + let mut overlay_db = OverlayedBackend::new(&db); + add_block_entry(&mut overlay_db, block_entry_b.clone().into(), n_validators, |h| { + new_candidate_info.get(h).map(|x| x.clone()) + }) + .unwrap(); + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + assert_eq!( + load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_a).unwrap(), + Some(block_entry_a.into()) + ); + assert_eq!( + load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_b).unwrap(), + Some(block_entry_b.into()) + ); + + let candidate_entry_a = load_candidate_entry(store.as_ref(), &TEST_CONFIG, &candidate_hash_a) + .unwrap() + .unwrap(); + assert_eq!( + candidate_entry_a.block_assignments.keys().collect::>(), + vec![&block_hash_a, &block_hash_b] + ); + + let candidate_entry_b = load_candidate_entry(store.as_ref(), &TEST_CONFIG, &candidate_hash_b) + .unwrap() + .unwrap(); + assert_eq!(candidate_entry_b.block_assignments.keys().collect::>(), vec![&block_hash_b]); +} + +#[test] +fn add_block_entry_adds_child() { + let (mut db, store) = make_db(); + + let parent_hash = Hash::repeat_byte(1); + let block_hash_a = Hash::repeat_byte(2); + let block_hash_b = Hash::repeat_byte(69); + + let mut block_entry_a = make_block_entry(block_hash_a, parent_hash, 1, Vec::new()); + + let block_entry_b = make_block_entry(block_hash_b, block_hash_a, 2, Vec::new()); + + let n_validators = 10; + + let mut overlay_db = OverlayedBackend::new(&db); + add_block_entry(&mut overlay_db, block_entry_a.clone().into(), n_validators, |_| None).unwrap(); + + add_block_entry(&mut overlay_db, block_entry_b.clone().into(), n_validators, |_| None).unwrap(); + + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + block_entry_a.children.push(block_hash_b); + + assert_eq!( + load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_a).unwrap(), + Some(block_entry_a.into()) + ); + assert_eq!( + load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_b).unwrap(), + Some(block_entry_b.into()) + ); +} + +#[test] +fn canonicalize_works() { + let (mut db, store) = make_db(); + + // -> B1 -> C1 -> D1 + // A -> B2 -> C2 -> D2 + // + // We'll canonicalize C1. Everytning except D1 should disappear. + // + // Candidates: + // Cand1 in B2 + // Cand2 in C2 + // Cand3 in C2 and D1 + // Cand4 in D1 + // Cand5 in D2 + // Only Cand3 and Cand4 should remain after canonicalize. + + let n_validators = 10; + + let mut overlay_db = OverlayedBackend::new(&db); + overlay_db.write_stored_block_range(StoredBlockRange(1, 5)); + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + let genesis = Hash::repeat_byte(0); + + let block_hash_a = Hash::repeat_byte(1); + let block_hash_b1 = Hash::repeat_byte(2); + let block_hash_b2 = Hash::repeat_byte(3); + let block_hash_c1 = Hash::repeat_byte(4); + let block_hash_c2 = Hash::repeat_byte(5); + let block_hash_d1 = Hash::repeat_byte(6); + let block_hash_d2 = Hash::repeat_byte(7); + + let candidate_receipt_genesis = make_candidate(ParaId::from(1_u32), genesis); + let candidate_receipt_a = make_candidate(ParaId::from(2_u32), block_hash_a); + let candidate_receipt_b = make_candidate(ParaId::from(3_u32), block_hash_a); + let candidate_receipt_b1 = make_candidate(ParaId::from(4_u32), block_hash_b1); + let candidate_receipt_c1 = make_candidate(ParaId::from(5_u32), block_hash_c1); + + let cand_hash_1 = candidate_receipt_genesis.hash(); + let cand_hash_2 = candidate_receipt_a.hash(); + let cand_hash_3 = candidate_receipt_b.hash(); + let cand_hash_4 = candidate_receipt_b1.hash(); + let cand_hash_5 = candidate_receipt_c1.hash(); + + let block_entry_a = make_block_entry(block_hash_a, genesis, 1, Vec::new()); + let block_entry_b1 = make_block_entry(block_hash_b1, block_hash_a, 2, Vec::new()); + let block_entry_b2 = + make_block_entry(block_hash_b2, block_hash_a, 2, vec![(CoreIndex(0), cand_hash_1)]); + let block_entry_c1 = make_block_entry(block_hash_c1, block_hash_b1, 3, Vec::new()); + let block_entry_c2 = make_block_entry( + block_hash_c2, + block_hash_b2, + 3, + vec![(CoreIndex(0), cand_hash_2), (CoreIndex(1), cand_hash_3)], + ); + let block_entry_d1 = make_block_entry( + block_hash_d1, + block_hash_c1, + 4, + vec![(CoreIndex(0), cand_hash_3), (CoreIndex(1), cand_hash_4)], + ); + let block_entry_d2 = + make_block_entry(block_hash_d2, block_hash_c2, 4, vec![(CoreIndex(0), cand_hash_5)]); + + let candidate_info = { + let mut candidate_info = HashMap::new(); + candidate_info.insert( + cand_hash_1, + NewCandidateInfo::new(candidate_receipt_genesis, GroupIndex(1), None), + ); + + candidate_info + .insert(cand_hash_2, NewCandidateInfo::new(candidate_receipt_a, GroupIndex(2), None)); + + candidate_info + .insert(cand_hash_3, NewCandidateInfo::new(candidate_receipt_b, GroupIndex(3), None)); + + candidate_info + .insert(cand_hash_4, NewCandidateInfo::new(candidate_receipt_b1, GroupIndex(4), None)); + + candidate_info + .insert(cand_hash_5, NewCandidateInfo::new(candidate_receipt_c1, GroupIndex(5), None)); + + candidate_info + }; + + // now insert all the blocks. + let blocks = vec![ + block_entry_a.clone(), + block_entry_b1.clone(), + block_entry_b2.clone(), + block_entry_c1.clone(), + block_entry_c2.clone(), + block_entry_d1.clone(), + block_entry_d2.clone(), + ]; + + let mut overlay_db = OverlayedBackend::new(&db); + for block_entry in blocks { + add_block_entry(&mut overlay_db, block_entry.into(), n_validators, |h| { + candidate_info.get(h).map(|x| x.clone()) + }) + .unwrap(); + } + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + let check_candidates_in_store = |expected: Vec<(CandidateHash, Option>)>| { + for (c_hash, in_blocks) in expected { + let (entry, in_blocks) = match in_blocks { + None => { + assert!(load_candidate_entry(store.as_ref(), &TEST_CONFIG, &c_hash) + .unwrap() + .is_none()); + continue + }, + Some(i) => ( + load_candidate_entry(store.as_ref(), &TEST_CONFIG, &c_hash).unwrap().unwrap(), + i, + ), + }; + + assert_eq!(entry.block_assignments.len(), in_blocks.len()); + + for x in in_blocks { + assert!(entry.block_assignments.contains_key(&x)); + } + } + }; + + let check_blocks_in_store = |expected: Vec<(Hash, Option>)>| { + for (hash, with_candidates) in expected { + let (entry, with_candidates) = match with_candidates { + None => { + assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &hash) + .unwrap() + .is_none()); + continue + }, + Some(i) => + (load_block_entry(store.as_ref(), &TEST_CONFIG, &hash).unwrap().unwrap(), i), + }; + + assert_eq!(entry.candidates.len(), with_candidates.len()); + + for x in with_candidates { + assert!(entry.candidates.iter().any(|(_, c)| c == &x)); + } + } + }; + + check_candidates_in_store(vec![ + (cand_hash_1, Some(vec![block_hash_b2])), + (cand_hash_2, Some(vec![block_hash_c2])), + (cand_hash_3, Some(vec![block_hash_c2, block_hash_d1])), + (cand_hash_4, Some(vec![block_hash_d1])), + (cand_hash_5, Some(vec![block_hash_d2])), + ]); + + check_blocks_in_store(vec![ + (block_hash_a, Some(vec![])), + (block_hash_b1, Some(vec![])), + (block_hash_b2, Some(vec![cand_hash_1])), + (block_hash_c1, Some(vec![])), + (block_hash_c2, Some(vec![cand_hash_2, cand_hash_3])), + (block_hash_d1, Some(vec![cand_hash_3, cand_hash_4])), + (block_hash_d2, Some(vec![cand_hash_5])), + ]); + + let mut overlay_db = OverlayedBackend::new(&db); + canonicalize(&mut overlay_db, 3, block_hash_c1).unwrap(); + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + assert_eq!( + load_stored_blocks(store.as_ref(), &TEST_CONFIG).unwrap().unwrap(), + StoredBlockRange(4, 5) + ); + + check_candidates_in_store(vec![ + (cand_hash_1, None), + (cand_hash_2, None), + (cand_hash_3, Some(vec![block_hash_d1])), + (cand_hash_4, Some(vec![block_hash_d1])), + (cand_hash_5, None), + ]); + + check_blocks_in_store(vec![ + (block_hash_a, None), + (block_hash_b1, None), + (block_hash_b2, None), + (block_hash_c1, None), + (block_hash_c2, None), + (block_hash_d1, Some(vec![cand_hash_3, cand_hash_4])), + (block_hash_d2, None), + ]); +} + +#[test] +fn force_approve_works() { + let (mut db, store) = make_db(); + let n_validators = 10; + + let mut overlay_db = OverlayedBackend::new(&db); + overlay_db.write_stored_block_range(StoredBlockRange(1, 4)); + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + let single_candidate_vec = vec![(CoreIndex(0), candidate_hash)]; + let candidate_info = { + let mut candidate_info = HashMap::new(); + candidate_info.insert( + candidate_hash, + NewCandidateInfo::new( + make_candidate(ParaId::from(1_u32), Default::default()), + GroupIndex(1), + None, + ), + ); + + candidate_info + }; + + let block_hash_a = Hash::repeat_byte(1); // 1 + let block_hash_b = Hash::repeat_byte(2); + let block_hash_c = Hash::repeat_byte(3); + let block_hash_d = Hash::repeat_byte(4); // 4 + + let block_entry_a = + make_block_entry(block_hash_a, Default::default(), 1, single_candidate_vec.clone()); + let block_entry_b = + make_block_entry(block_hash_b, block_hash_a, 2, single_candidate_vec.clone()); + let block_entry_c = + make_block_entry(block_hash_c, block_hash_b, 3, single_candidate_vec.clone()); + let block_entry_d = + make_block_entry(block_hash_d, block_hash_c, 4, single_candidate_vec.clone()); + + let blocks = vec![ + block_entry_a.clone(), + block_entry_b.clone(), + block_entry_c.clone(), + block_entry_d.clone(), + ]; + + let mut overlay_db = OverlayedBackend::new(&db); + for block_entry in blocks { + add_block_entry(&mut overlay_db, block_entry.into(), n_validators, |h| { + candidate_info.get(h).map(|x| x.clone()) + }) + .unwrap(); + } + let approved_hashes = force_approve(&mut overlay_db, block_hash_d, 2).unwrap(); + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_a,) + .unwrap() + .unwrap() + .approved_bitfield + .all()); + assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_b,) + .unwrap() + .unwrap() + .approved_bitfield + .all()); + assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_c,) + .unwrap() + .unwrap() + .approved_bitfield + .not_any()); + assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_d,) + .unwrap() + .unwrap() + .approved_bitfield + .not_any()); + assert_eq!(approved_hashes, vec![block_hash_b, block_hash_a]); +} + +#[test] +fn load_all_blocks_works() { + let (mut db, store) = make_db(); + + let parent_hash = Hash::repeat_byte(1); + let block_hash_a = Hash::repeat_byte(2); + let block_hash_b = Hash::repeat_byte(69); + let block_hash_c = Hash::repeat_byte(42); + + let block_number = 10; + + let block_entry_a = make_block_entry(block_hash_a, parent_hash, block_number, vec![]); + + let block_entry_b = make_block_entry(block_hash_b, parent_hash, block_number, vec![]); + + let block_entry_c = make_block_entry(block_hash_c, block_hash_a, block_number + 1, vec![]); + + let n_validators = 10; + + let mut overlay_db = OverlayedBackend::new(&db); + add_block_entry(&mut overlay_db, block_entry_a.clone().into(), n_validators, |_| None).unwrap(); + + // add C before B to test sorting. + add_block_entry(&mut overlay_db, block_entry_c.clone().into(), n_validators, |_| None).unwrap(); + + add_block_entry(&mut overlay_db, block_entry_b.clone().into(), n_validators, |_| None).unwrap(); + + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + assert_eq!( + load_all_blocks(store.as_ref(), &TEST_CONFIG).unwrap(), + vec![block_hash_a, block_hash_b, block_hash_c], + ) +} diff --git a/polkadot/node/core/approval-voting/src/backend.rs b/polkadot/node/core/approval-voting/src/backend.rs new file mode 100644 index 0000000000000000000000000000000000000000..87d67c52c467a2079044a3c86179ce162dd0fc43 --- /dev/null +++ b/polkadot/node/core/approval-voting/src/backend.rs @@ -0,0 +1,221 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! An abstraction over storage used by the chain selection subsystem. +//! +//! This provides both a [`Backend`] trait and an [`OverlayedBackend`] +//! struct which allows in-memory changes to be applied on top of a +//! [`Backend`], maintaining consistency between queries and temporary writes, +//! before any commit to the underlying storage is made. + +use polkadot_node_subsystem::SubsystemResult; +use polkadot_primitives::{BlockNumber, CandidateHash, Hash}; + +use std::collections::HashMap; + +use super::{ + approval_db::v1::StoredBlockRange, + persisted_entries::{BlockEntry, CandidateEntry}, +}; + +#[derive(Debug)] +pub enum BackendWriteOp { + WriteStoredBlockRange(StoredBlockRange), + WriteBlocksAtHeight(BlockNumber, Vec), + WriteBlockEntry(BlockEntry), + WriteCandidateEntry(CandidateEntry), + DeleteStoredBlockRange, + DeleteBlocksAtHeight(BlockNumber), + DeleteBlockEntry(Hash), + DeleteCandidateEntry(CandidateHash), +} + +/// An abstraction over backend storage for the logic of this subsystem. +pub trait Backend { + /// Load a block entry from the DB. + fn load_block_entry(&self, hash: &Hash) -> SubsystemResult>; + /// Load a candidate entry from the DB. + fn load_candidate_entry( + &self, + candidate_hash: &CandidateHash, + ) -> SubsystemResult>; + /// Load all blocks at a specific height. + fn load_blocks_at_height(&self, height: &BlockNumber) -> SubsystemResult>; + /// Load all block from the DB. + fn load_all_blocks(&self) -> SubsystemResult>; + /// Load stored block range form the DB. + fn load_stored_blocks(&self) -> SubsystemResult>; + /// Atomically write the list of operations, with later operations taking precedence over prior. + fn write(&mut self, ops: I) -> SubsystemResult<()> + where + I: IntoIterator; +} + +// Status of block range in the `OverlayedBackend`. +#[derive(PartialEq)] +enum BlockRangeStatus { + // Value has not been modified. + NotModified, + // Value has been deleted + Deleted, + // Value has been updated. + Inserted(StoredBlockRange), +} + +/// An in-memory overlay over the backend. +/// +/// This maintains read-only access to the underlying backend, but can be +/// converted into a set of write operations which will, when written to +/// the underlying backend, give the same view as the state of the overlay. +pub struct OverlayedBackend<'a, B: 'a> { + inner: &'a B, + // `Some(None)` means deleted. Missing (`None`) means query inner. + stored_block_range: BlockRangeStatus, + // `None` means 'deleted', missing means query inner. + blocks_at_height: HashMap>>, + // `None` means 'deleted', missing means query inner. + block_entries: HashMap>, + // `None` means 'deleted', missing means query inner. + candidate_entries: HashMap>, +} + +impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> { + pub fn new(backend: &'a B) -> Self { + OverlayedBackend { + inner: backend, + stored_block_range: BlockRangeStatus::NotModified, + blocks_at_height: HashMap::new(), + block_entries: HashMap::new(), + candidate_entries: HashMap::new(), + } + } + + pub fn is_empty(&self) -> bool { + self.block_entries.is_empty() && + self.candidate_entries.is_empty() && + self.blocks_at_height.is_empty() && + self.stored_block_range == BlockRangeStatus::NotModified + } + + pub fn load_all_blocks(&self) -> SubsystemResult> { + let mut hashes = Vec::new(); + if let Some(stored_blocks) = self.load_stored_blocks()? { + for height in stored_blocks.0..stored_blocks.1 { + hashes.extend(self.load_blocks_at_height(&height)?); + } + } + + Ok(hashes) + } + + pub fn load_stored_blocks(&self) -> SubsystemResult> { + match self.stored_block_range { + BlockRangeStatus::Inserted(ref value) => Ok(Some(value.clone())), + BlockRangeStatus::Deleted => Ok(None), + BlockRangeStatus::NotModified => self.inner.load_stored_blocks(), + } + } + + pub fn load_blocks_at_height(&self, height: &BlockNumber) -> SubsystemResult> { + if let Some(val) = self.blocks_at_height.get(&height) { + return Ok(val.clone().unwrap_or_default()) + } + + self.inner.load_blocks_at_height(height) + } + + pub fn load_block_entry(&self, hash: &Hash) -> SubsystemResult> { + if let Some(val) = self.block_entries.get(&hash) { + return Ok(val.clone()) + } + + self.inner.load_block_entry(hash) + } + + pub fn load_candidate_entry( + &self, + candidate_hash: &CandidateHash, + ) -> SubsystemResult> { + if let Some(val) = self.candidate_entries.get(&candidate_hash) { + return Ok(val.clone()) + } + + self.inner.load_candidate_entry(candidate_hash) + } + + pub fn write_stored_block_range(&mut self, range: StoredBlockRange) { + self.stored_block_range = BlockRangeStatus::Inserted(range); + } + + pub fn delete_stored_block_range(&mut self) { + self.stored_block_range = BlockRangeStatus::Deleted; + } + + pub fn write_blocks_at_height(&mut self, height: BlockNumber, blocks: Vec) { + self.blocks_at_height.insert(height, Some(blocks)); + } + + pub fn delete_blocks_at_height(&mut self, height: BlockNumber) { + self.blocks_at_height.insert(height, None); + } + + pub fn write_block_entry(&mut self, entry: BlockEntry) { + self.block_entries.insert(entry.block_hash(), Some(entry)); + } + + pub fn delete_block_entry(&mut self, hash: &Hash) { + self.block_entries.insert(*hash, None); + } + + pub fn write_candidate_entry(&mut self, entry: CandidateEntry) { + self.candidate_entries.insert(entry.candidate_receipt().hash(), Some(entry)); + } + + pub fn delete_candidate_entry(&mut self, hash: &CandidateHash) { + self.candidate_entries.insert(*hash, None); + } + + /// Transform this backend into a set of write-ops to be written to the + /// inner backend. + pub fn into_write_ops(self) -> impl Iterator { + let blocks_at_height_ops = self.blocks_at_height.into_iter().map(|(h, v)| match v { + Some(v) => BackendWriteOp::WriteBlocksAtHeight(h, v), + None => BackendWriteOp::DeleteBlocksAtHeight(h), + }); + + let block_entry_ops = self.block_entries.into_iter().map(|(h, v)| match v { + Some(v) => BackendWriteOp::WriteBlockEntry(v), + None => BackendWriteOp::DeleteBlockEntry(h), + }); + + let candidate_entry_ops = self.candidate_entries.into_iter().map(|(h, v)| match v { + Some(v) => BackendWriteOp::WriteCandidateEntry(v), + None => BackendWriteOp::DeleteCandidateEntry(h), + }); + + let stored_block_range_ops = match self.stored_block_range { + BlockRangeStatus::Inserted(val) => Some(BackendWriteOp::WriteStoredBlockRange(val)), + BlockRangeStatus::Deleted => Some(BackendWriteOp::DeleteStoredBlockRange), + BlockRangeStatus::NotModified => None, + }; + + stored_block_range_ops + .into_iter() + .chain(blocks_at_height_ops) + .chain(block_entry_ops) + .chain(candidate_entry_ops) + } +} diff --git a/polkadot/node/core/approval-voting/src/criteria.rs b/polkadot/node/core/approval-voting/src/criteria.rs new file mode 100644 index 0000000000000000000000000000000000000000..0e1d18198c210fa14629a7343087c508a9ccc2ca --- /dev/null +++ b/polkadot/node/core/approval-voting/src/criteria.rs @@ -0,0 +1,879 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Assignment criteria VRF generation and checking. + +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_primitives::approval::{ + self as approval_types, AssignmentCert, AssignmentCertKind, DelayTranche, RelayVRFStory, +}; +use polkadot_primitives::{ + AssignmentId, AssignmentPair, CandidateHash, CoreIndex, GroupIndex, IndexedVec, SessionInfo, + ValidatorIndex, +}; +use sc_keystore::LocalKeystore; +use sp_application_crypto::ByteArray; + +use merlin::Transcript; +use schnorrkel::vrf::VRFInOut; + +use std::collections::{hash_map::Entry, HashMap}; + +use super::LOG_TARGET; + +/// Details pertaining to our assignment on a block. +#[derive(Debug, Clone, Encode, Decode, PartialEq)] +pub struct OurAssignment { + cert: AssignmentCert, + tranche: DelayTranche, + validator_index: ValidatorIndex, + // Whether the assignment has been triggered already. + triggered: bool, +} + +impl OurAssignment { + pub(crate) fn cert(&self) -> &AssignmentCert { + &self.cert + } + + pub(crate) fn tranche(&self) -> DelayTranche { + self.tranche + } + + pub(crate) fn validator_index(&self) -> ValidatorIndex { + self.validator_index + } + + pub(crate) fn triggered(&self) -> bool { + self.triggered + } + + pub(crate) fn mark_triggered(&mut self) { + self.triggered = true; + } +} + +impl From for OurAssignment { + fn from(entry: crate::approval_db::v1::OurAssignment) -> Self { + OurAssignment { + cert: entry.cert, + tranche: entry.tranche, + validator_index: entry.validator_index, + triggered: entry.triggered, + } + } +} + +impl From for crate::approval_db::v1::OurAssignment { + fn from(entry: OurAssignment) -> Self { + Self { + cert: entry.cert, + tranche: entry.tranche, + validator_index: entry.validator_index, + triggered: entry.triggered, + } + } +} + +fn relay_vrf_modulo_transcript(relay_vrf_story: RelayVRFStory, sample: u32) -> Transcript { + // combine the relay VRF story with a sample number. + let mut t = Transcript::new(approval_types::RELAY_VRF_MODULO_CONTEXT); + t.append_message(b"RC-VRF", &relay_vrf_story.0); + sample.using_encoded(|s| t.append_message(b"sample", s)); + + t +} + +fn relay_vrf_modulo_core(vrf_in_out: &VRFInOut, n_cores: u32) -> CoreIndex { + let bytes: [u8; 4] = vrf_in_out.make_bytes(approval_types::CORE_RANDOMNESS_CONTEXT); + + // interpret as little-endian u32. + let random_core = u32::from_le_bytes(bytes) % n_cores; + CoreIndex(random_core) +} + +fn relay_vrf_delay_transcript(relay_vrf_story: RelayVRFStory, core_index: CoreIndex) -> Transcript { + let mut t = Transcript::new(approval_types::RELAY_VRF_DELAY_CONTEXT); + t.append_message(b"RC-VRF", &relay_vrf_story.0); + core_index.0.using_encoded(|s| t.append_message(b"core", s)); + t +} + +fn relay_vrf_delay_tranche( + vrf_in_out: &VRFInOut, + num_delay_tranches: u32, + zeroth_delay_tranche_width: u32, +) -> DelayTranche { + let bytes: [u8; 4] = vrf_in_out.make_bytes(approval_types::TRANCHE_RANDOMNESS_CONTEXT); + + // interpret as little-endian u32 and reduce by the number of tranches. + let wide_tranche = + u32::from_le_bytes(bytes) % (num_delay_tranches + zeroth_delay_tranche_width); + + // Consolidate early results to tranche zero so tranche zero is extra wide. + wide_tranche.saturating_sub(zeroth_delay_tranche_width) +} + +fn assigned_core_transcript(core_index: CoreIndex) -> Transcript { + let mut t = Transcript::new(approval_types::ASSIGNED_CORE_CONTEXT); + core_index.0.using_encoded(|s| t.append_message(b"core", s)); + t +} + +/// Information about the world assignments are being produced in. +#[derive(Clone)] +pub(crate) struct Config { + /// The assignment public keys for validators. + assignment_keys: Vec, + /// The groups of validators assigned to each core. + validator_groups: IndexedVec>, + /// The number of availability cores used by the protocol during this session. + n_cores: u32, + /// The zeroth delay tranche width. + zeroth_delay_tranche_width: u32, + /// The number of samples we do of `relay_vrf_modulo`. + relay_vrf_modulo_samples: u32, + /// The number of delay tranches in total. + n_delay_tranches: u32, +} + +impl<'a> From<&'a SessionInfo> for Config { + fn from(s: &'a SessionInfo) -> Self { + Config { + assignment_keys: s.assignment_keys.clone(), + validator_groups: s.validator_groups.clone(), + n_cores: s.n_cores, + zeroth_delay_tranche_width: s.zeroth_delay_tranche_width, + relay_vrf_modulo_samples: s.relay_vrf_modulo_samples, + n_delay_tranches: s.n_delay_tranches, + } + } +} + +/// A trait for producing and checking assignments. Used to mock. +pub(crate) trait AssignmentCriteria { + fn compute_assignments( + &self, + keystore: &LocalKeystore, + relay_vrf_story: RelayVRFStory, + config: &Config, + leaving_cores: Vec<(CandidateHash, CoreIndex, GroupIndex)>, + ) -> HashMap; + + fn check_assignment_cert( + &self, + claimed_core_index: CoreIndex, + validator_index: ValidatorIndex, + config: &Config, + relay_vrf_story: RelayVRFStory, + assignment: &AssignmentCert, + backing_group: GroupIndex, + ) -> Result; +} + +pub(crate) struct RealAssignmentCriteria; + +impl AssignmentCriteria for RealAssignmentCriteria { + fn compute_assignments( + &self, + keystore: &LocalKeystore, + relay_vrf_story: RelayVRFStory, + config: &Config, + leaving_cores: Vec<(CandidateHash, CoreIndex, GroupIndex)>, + ) -> HashMap { + compute_assignments(keystore, relay_vrf_story, config, leaving_cores) + } + + fn check_assignment_cert( + &self, + claimed_core_index: CoreIndex, + validator_index: ValidatorIndex, + config: &Config, + relay_vrf_story: RelayVRFStory, + assignment: &AssignmentCert, + backing_group: GroupIndex, + ) -> Result { + check_assignment_cert( + claimed_core_index, + validator_index, + config, + relay_vrf_story, + assignment, + backing_group, + ) + } +} + +/// Compute the assignments for a given block. Returns a map containing all assignments to cores in +/// the block. If more than one assignment targets the given core, only the earliest assignment is +/// kept. +/// +/// The `leaving_cores` parameter indicates all cores within the block where a candidate was +/// included, as well as the group index backing those. +/// +/// The current description of the protocol assigns every validator to check every core. But at +/// different times. The idea is that most assignments are never triggered and fall by the wayside. +/// +/// This will not assign to anything the local validator was part of the backing group for. +pub(crate) fn compute_assignments( + keystore: &LocalKeystore, + relay_vrf_story: RelayVRFStory, + config: &Config, + leaving_cores: impl IntoIterator + Clone, +) -> HashMap { + if config.n_cores == 0 || + config.assignment_keys.is_empty() || + config.validator_groups.is_empty() + { + gum::trace!( + target: LOG_TARGET, + n_cores = config.n_cores, + has_assignment_keys = !config.assignment_keys.is_empty(), + has_validator_groups = !config.validator_groups.is_empty(), + "Not producing assignments because config is degenerate", + ); + + return HashMap::new() + } + + let (index, assignments_key): (ValidatorIndex, AssignmentPair) = { + let key = config.assignment_keys.iter().enumerate().find_map(|(i, p)| { + match keystore.key_pair(p) { + Ok(Some(pair)) => Some((ValidatorIndex(i as _), pair)), + Ok(None) => None, + Err(sc_keystore::Error::Unavailable) => None, + Err(sc_keystore::Error::Io(e)) if e.kind() == std::io::ErrorKind::NotFound => None, + Err(e) => { + gum::warn!(target: LOG_TARGET, "Encountered keystore error: {:?}", e); + None + }, + } + }); + + match key { + None => { + gum::trace!(target: LOG_TARGET, "No assignment key"); + return HashMap::new() + }, + Some(k) => k, + } + }; + + // Ignore any cores where the assigned group is our own. + let leaving_cores = leaving_cores + .into_iter() + .filter(|(_, _, g)| !is_in_backing_group(&config.validator_groups, index, *g)) + .map(|(c_hash, core, _)| (c_hash, core)) + .collect::>(); + + gum::trace!( + target: LOG_TARGET, + assignable_cores = leaving_cores.len(), + "Assigning to candidates from different backing groups" + ); + + let assignments_key: &sp_application_crypto::sr25519::Pair = assignments_key.as_ref(); + let assignments_key: &schnorrkel::Keypair = assignments_key.as_ref(); + + let mut assignments = HashMap::new(); + + // First run `RelayVRFModulo` for each sample. + compute_relay_vrf_modulo_assignments( + &assignments_key, + index, + config, + relay_vrf_story.clone(), + leaving_cores.iter().cloned(), + &mut assignments, + ); + + // Then run `RelayVRFDelay` once for the whole block. + compute_relay_vrf_delay_assignments( + &assignments_key, + index, + config, + relay_vrf_story, + leaving_cores, + &mut assignments, + ); + + assignments +} + +fn compute_relay_vrf_modulo_assignments( + assignments_key: &schnorrkel::Keypair, + validator_index: ValidatorIndex, + config: &Config, + relay_vrf_story: RelayVRFStory, + leaving_cores: impl IntoIterator + Clone, + assignments: &mut HashMap, +) { + for rvm_sample in 0..config.relay_vrf_modulo_samples { + let mut core = CoreIndex::default(); + + let maybe_assignment = { + // Extra scope to ensure borrowing instead of moving core + // into closure. + let core = &mut core; + assignments_key.vrf_sign_extra_after_check( + relay_vrf_modulo_transcript(relay_vrf_story.clone(), rvm_sample), + |vrf_in_out| { + *core = relay_vrf_modulo_core(&vrf_in_out, config.n_cores); + if let Some((candidate_hash, _)) = + leaving_cores.clone().into_iter().find(|(_, c)| c == core) + { + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?core, + ?validator_index, + tranche = 0, + "RelayVRFModulo Assignment." + ); + + Some(assigned_core_transcript(*core)) + } else { + None + } + }, + ) + }; + + if let Some((vrf_in_out, vrf_proof, _)) = maybe_assignment { + // Sanity: `core` is always initialized to non-default here, as the closure above + // has been executed. + let cert = AssignmentCert { + kind: AssignmentCertKind::RelayVRFModulo { sample: rvm_sample }, + vrf: approval_types::VrfSignature { + output: approval_types::VrfOutput(vrf_in_out.to_output()), + proof: approval_types::VrfProof(vrf_proof), + }, + }; + + // All assignments of type RelayVRFModulo have tranche 0. + assignments.entry(core).or_insert(OurAssignment { + cert, + tranche: 0, + validator_index, + triggered: false, + }); + } + } +} + +fn compute_relay_vrf_delay_assignments( + assignments_key: &schnorrkel::Keypair, + validator_index: ValidatorIndex, + config: &Config, + relay_vrf_story: RelayVRFStory, + leaving_cores: impl IntoIterator, + assignments: &mut HashMap, +) { + for (candidate_hash, core) in leaving_cores { + let (vrf_in_out, vrf_proof, _) = + assignments_key.vrf_sign(relay_vrf_delay_transcript(relay_vrf_story.clone(), core)); + + let tranche = relay_vrf_delay_tranche( + &vrf_in_out, + config.n_delay_tranches, + config.zeroth_delay_tranche_width, + ); + + let cert = AssignmentCert { + kind: AssignmentCertKind::RelayVRFDelay { core_index: core }, + vrf: approval_types::VrfSignature { + output: approval_types::VrfOutput(vrf_in_out.to_output()), + proof: approval_types::VrfProof(vrf_proof), + }, + }; + + let our_assignment = OurAssignment { cert, tranche, validator_index, triggered: false }; + + let used = match assignments.entry(core) { + Entry::Vacant(e) => { + let _ = e.insert(our_assignment); + true + }, + Entry::Occupied(mut e) => + if e.get().tranche > our_assignment.tranche { + e.insert(our_assignment); + true + } else { + false + }, + }; + + if used { + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?core, + ?validator_index, + tranche, + "RelayVRFDelay Assignment", + ); + } + } +} + +/// Assignment invalid. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct InvalidAssignment(pub(crate) InvalidAssignmentReason); + +impl std::fmt::Display for InvalidAssignment { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Invalid Assignment: {:?}", self.0) + } +} + +impl std::error::Error for InvalidAssignment {} + +/// Failure conditions when checking an assignment cert. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum InvalidAssignmentReason { + ValidatorIndexOutOfBounds, + SampleOutOfBounds, + CoreIndexOutOfBounds, + InvalidAssignmentKey, + IsInBackingGroup, + VRFModuloCoreIndexMismatch, + VRFModuloOutputMismatch, + VRFDelayCoreIndexMismatch, + VRFDelayOutputMismatch, +} + +/// Checks the crypto of an assignment cert. Failure conditions: +/// * Validator index out of bounds +/// * VRF signature check fails +/// * VRF output doesn't match assigned core +/// * Core is not covered by extra data in signature +/// * Core index out of bounds +/// * Sample is out of bounds +/// * Validator is present in backing group. +/// +/// This function does not check whether the core is actually a valid assignment or not. That should +/// be done outside the scope of this function. +pub(crate) fn check_assignment_cert( + claimed_core_index: CoreIndex, + validator_index: ValidatorIndex, + config: &Config, + relay_vrf_story: RelayVRFStory, + assignment: &AssignmentCert, + backing_group: GroupIndex, +) -> Result { + use InvalidAssignmentReason as Reason; + + let validator_public = config + .assignment_keys + .get(validator_index.0 as usize) + .ok_or(InvalidAssignment(Reason::ValidatorIndexOutOfBounds))?; + + let public = schnorrkel::PublicKey::from_bytes(validator_public.as_slice()) + .map_err(|_| InvalidAssignment(Reason::InvalidAssignmentKey))?; + + if claimed_core_index.0 >= config.n_cores { + return Err(InvalidAssignment(Reason::CoreIndexOutOfBounds)) + } + + // Check that the validator was not part of the backing group + // and not already assigned. + let is_in_backing = + is_in_backing_group(&config.validator_groups, validator_index, backing_group); + + if is_in_backing { + return Err(InvalidAssignment(Reason::IsInBackingGroup)) + } + + let vrf_signature = &assignment.vrf; + match assignment.kind { + AssignmentCertKind::RelayVRFModulo { sample } => { + if sample >= config.relay_vrf_modulo_samples { + return Err(InvalidAssignment(Reason::SampleOutOfBounds)) + } + + let (vrf_in_out, _) = public + .vrf_verify_extra( + relay_vrf_modulo_transcript(relay_vrf_story, sample), + &vrf_signature.output.0, + &vrf_signature.proof.0, + assigned_core_transcript(claimed_core_index), + ) + .map_err(|_| InvalidAssignment(Reason::VRFModuloOutputMismatch))?; + + // ensure that the `vrf_in_out` actually gives us the claimed core. + if relay_vrf_modulo_core(&vrf_in_out, config.n_cores) == claimed_core_index { + Ok(0) + } else { + Err(InvalidAssignment(Reason::VRFModuloCoreIndexMismatch)) + } + }, + AssignmentCertKind::RelayVRFDelay { core_index } => { + if core_index != claimed_core_index { + return Err(InvalidAssignment(Reason::VRFDelayCoreIndexMismatch)) + } + + let (vrf_in_out, _) = public + .vrf_verify( + relay_vrf_delay_transcript(relay_vrf_story, core_index), + &vrf_signature.output.0, + &vrf_signature.proof.0, + ) + .map_err(|_| InvalidAssignment(Reason::VRFDelayOutputMismatch))?; + + Ok(relay_vrf_delay_tranche( + &vrf_in_out, + config.n_delay_tranches, + config.zeroth_delay_tranche_width, + )) + }, + } +} + +fn is_in_backing_group( + validator_groups: &IndexedVec>, + validator: ValidatorIndex, + group: GroupIndex, +) -> bool { + validator_groups.get(group).map_or(false, |g| g.contains(&validator)) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::import::tests::garbage_vrf_signature; + use polkadot_primitives::{Hash, ASSIGNMENT_KEY_TYPE_ID}; + use sp_application_crypto::sr25519; + use sp_core::crypto::Pair as PairT; + use sp_keyring::sr25519::Keyring as Sr25519Keyring; + use sp_keystore::Keystore; + + // sets up a keystore with the given keyring accounts. + fn make_keystore(accounts: &[Sr25519Keyring]) -> LocalKeystore { + let store = LocalKeystore::in_memory(); + + for s in accounts.iter().copied().map(|k| k.to_seed()) { + store.sr25519_generate_new(ASSIGNMENT_KEY_TYPE_ID, Some(s.as_str())).unwrap(); + } + + store + } + + fn assignment_keys(accounts: &[Sr25519Keyring]) -> Vec { + assignment_keys_plus_random(accounts, 0) + } + + fn assignment_keys_plus_random( + accounts: &[Sr25519Keyring], + random: usize, + ) -> Vec { + let gen_random = + (0..random).map(|_| AssignmentId::from(sr25519::Pair::generate().0.public())); + + accounts + .iter() + .map(|k| AssignmentId::from(k.public())) + .chain(gen_random) + .collect() + } + + fn basic_groups( + n_validators: usize, + n_groups: usize, + ) -> IndexedVec> { + let size = n_validators / n_groups; + let big_groups = n_validators % n_groups; + let scraps = n_groups * size; + + (0..n_groups) + .map(|i| { + (i * size..(i + 1) * size) + .chain(if i < big_groups { Some(scraps + i) } else { None }) + .map(|j| ValidatorIndex(j as _)) + .collect::>() + }) + .collect() + } + + #[test] + fn assignments_produced_for_non_backing() { + let keystore = make_keystore(&[Sr25519Keyring::Alice]); + + let c_a = CandidateHash(Hash::repeat_byte(0)); + let c_b = CandidateHash(Hash::repeat_byte(1)); + + let relay_vrf_story = RelayVRFStory([42u8; 32]); + let assignments = compute_assignments( + &keystore, + relay_vrf_story, + &Config { + assignment_keys: assignment_keys(&[ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + ]), + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0)], + vec![ValidatorIndex(1), ValidatorIndex(2)], + ]), + n_cores: 2, + zeroth_delay_tranche_width: 10, + relay_vrf_modulo_samples: 3, + n_delay_tranches: 40, + }, + vec![(c_a, CoreIndex(0), GroupIndex(1)), (c_b, CoreIndex(1), GroupIndex(0))], + ); + + // Note that alice is in group 0, which was the backing group for core 1. + // Alice should have self-assigned to check core 0 but not 1. + assert_eq!(assignments.len(), 1); + assert!(assignments.get(&CoreIndex(0)).is_some()); + } + + #[test] + fn assign_to_nonzero_core() { + let keystore = make_keystore(&[Sr25519Keyring::Alice]); + + let c_a = CandidateHash(Hash::repeat_byte(0)); + let c_b = CandidateHash(Hash::repeat_byte(1)); + + let relay_vrf_story = RelayVRFStory([42u8; 32]); + let assignments = compute_assignments( + &keystore, + relay_vrf_story, + &Config { + assignment_keys: assignment_keys(&[ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + ]), + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0)], + vec![ValidatorIndex(1), ValidatorIndex(2)], + ]), + n_cores: 2, + zeroth_delay_tranche_width: 10, + relay_vrf_modulo_samples: 3, + n_delay_tranches: 40, + }, + vec![(c_a, CoreIndex(0), GroupIndex(0)), (c_b, CoreIndex(1), GroupIndex(1))], + ); + + assert_eq!(assignments.len(), 1); + assert!(assignments.get(&CoreIndex(1)).is_some()); + } + + #[test] + fn succeeds_empty_for_0_cores() { + let keystore = make_keystore(&[Sr25519Keyring::Alice]); + + let relay_vrf_story = RelayVRFStory([42u8; 32]); + let assignments = compute_assignments( + &keystore, + relay_vrf_story, + &Config { + assignment_keys: assignment_keys(&[ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + ]), + validator_groups: Default::default(), + n_cores: 0, + zeroth_delay_tranche_width: 10, + relay_vrf_modulo_samples: 3, + n_delay_tranches: 40, + }, + vec![], + ); + + assert!(assignments.is_empty()); + } + + struct MutatedAssignment { + core: CoreIndex, + cert: AssignmentCert, + group: GroupIndex, + own_group: GroupIndex, + val_index: ValidatorIndex, + config: Config, + } + + // This fails if the closure requests to skip everything. + fn check_mutated_assignments( + n_validators: usize, + n_cores: usize, + rotation_offset: usize, + f: impl Fn(&mut MutatedAssignment) -> Option, // None = skip + ) { + let keystore = make_keystore(&[Sr25519Keyring::Alice]); + + let group_for_core = |i| GroupIndex(((i + rotation_offset) % n_cores) as _); + + let config = Config { + assignment_keys: assignment_keys_plus_random( + &[Sr25519Keyring::Alice], + n_validators - 1, + ), + validator_groups: basic_groups(n_validators, n_cores), + n_cores: n_cores as u32, + zeroth_delay_tranche_width: 10, + relay_vrf_modulo_samples: 3, + n_delay_tranches: 40, + }; + + let relay_vrf_story = RelayVRFStory([42u8; 32]); + let assignments = compute_assignments( + &keystore, + relay_vrf_story.clone(), + &config, + (0..n_cores) + .map(|i| { + ( + CandidateHash(Hash::repeat_byte(i as u8)), + CoreIndex(i as u32), + group_for_core(i), + ) + }) + .collect::>(), + ); + + let mut counted = 0; + for (core, assignment) in assignments { + let mut mutated = MutatedAssignment { + core, + group: group_for_core(core.0 as _), + cert: assignment.cert, + own_group: GroupIndex(0), + val_index: ValidatorIndex(0), + config: config.clone(), + }; + + let expected = match f(&mut mutated) { + None => continue, + Some(e) => e, + }; + + counted += 1; + + let is_good = check_assignment_cert( + mutated.core, + mutated.val_index, + &mutated.config, + relay_vrf_story.clone(), + &mutated.cert, + mutated.group, + ) + .is_ok(); + + assert_eq!(expected, is_good) + } + + assert!(counted > 0); + } + + #[test] + fn computed_assignments_pass_checks() { + check_mutated_assignments(200, 100, 25, |_| Some(true)); + } + + #[test] + fn check_rejects_claimed_core_out_of_bounds() { + check_mutated_assignments(200, 100, 25, |m| { + m.core.0 += 100; + Some(false) + }); + } + + #[test] + fn check_rejects_in_backing_group() { + check_mutated_assignments(200, 100, 25, |m| { + m.group = m.own_group; + Some(false) + }); + } + + #[test] + fn check_rejects_nonexistent_key() { + check_mutated_assignments(200, 100, 25, |m| { + m.val_index.0 += 200; + Some(false) + }); + } + + #[test] + fn check_rejects_delay_bad_vrf() { + check_mutated_assignments(40, 10, 8, |m| { + match m.cert.kind.clone() { + AssignmentCertKind::RelayVRFDelay { .. } => { + m.cert.vrf = garbage_vrf_signature(); + Some(false) + }, + _ => None, // skip everything else. + } + }); + } + + #[test] + fn check_rejects_modulo_bad_vrf() { + check_mutated_assignments(200, 100, 25, |m| { + match m.cert.kind.clone() { + AssignmentCertKind::RelayVRFModulo { .. } => { + m.cert.vrf = garbage_vrf_signature(); + Some(false) + }, + _ => None, // skip everything else. + } + }); + } + + #[test] + fn check_rejects_modulo_sample_out_of_bounds() { + check_mutated_assignments(200, 100, 25, |m| { + match m.cert.kind.clone() { + AssignmentCertKind::RelayVRFModulo { sample } => { + m.config.relay_vrf_modulo_samples = sample; + Some(false) + }, + _ => None, // skip everything else. + } + }); + } + + #[test] + fn check_rejects_delay_claimed_core_wrong() { + check_mutated_assignments(200, 100, 25, |m| { + match m.cert.kind.clone() { + AssignmentCertKind::RelayVRFDelay { .. } => { + m.core = CoreIndex((m.core.0 + 1) % 100); + Some(false) + }, + _ => None, // skip everything else. + } + }); + } + + #[test] + fn check_rejects_modulo_core_wrong() { + check_mutated_assignments(200, 100, 25, |m| { + match m.cert.kind.clone() { + AssignmentCertKind::RelayVRFModulo { .. } => { + m.core = CoreIndex((m.core.0 + 1) % 100); + Some(false) + }, + _ => None, // skip everything else. + } + }); + } +} diff --git a/polkadot/node/core/approval-voting/src/import.rs b/polkadot/node/core/approval-voting/src/import.rs new file mode 100644 index 0000000000000000000000000000000000000000..c504ba71b3c2d801a8f97b3920404a6cc99d7776 --- /dev/null +++ b/polkadot/node/core/approval-voting/src/import.rs @@ -0,0 +1,1389 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Block import logic for the approval voting subsystem. +//! +//! There are two major concerns when handling block import notifications. +//! * Determining all new blocks. +//! * Handling session changes +//! +//! When receiving a block import notification from the overseer, the +//! approval voting subsystem needs to account for the fact that there +//! may have been blocks missed by the notification. It needs to iterate +//! the ancestry of the block notification back to either the last finalized +//! block or a block that is already accounted for within the DB. +//! +//! We maintain a rolling window of session indices. This starts as empty + +use polkadot_node_jaeger as jaeger; +use polkadot_node_primitives::{ + approval::{self as approval_types, BlockApprovalMeta, RelayVRFStory}, + MAX_FINALITY_LAG, +}; +use polkadot_node_subsystem::{ + messages::{ + ApprovalDistributionMessage, ChainApiMessage, ChainSelectionMessage, RuntimeApiMessage, + RuntimeApiRequest, + }, + overseer, RuntimeApiError, SubsystemError, SubsystemResult, +}; +use polkadot_node_subsystem_util::{determine_new_blocks, runtime::RuntimeInfo}; +use polkadot_primitives::{ + BlockNumber, CandidateEvent, CandidateHash, CandidateReceipt, ConsensusLog, CoreIndex, + GroupIndex, Hash, Header, SessionIndex, +}; +use sc_keystore::LocalKeystore; +use sp_consensus_slots::Slot; + +use bitvec::order::Lsb0 as BitOrderLsb0; +use futures::{channel::oneshot, prelude::*}; + +use std::collections::HashMap; + +use super::approval_db::v1; +use crate::{ + backend::{Backend, OverlayedBackend}, + criteria::{AssignmentCriteria, OurAssignment}, + get_session_info, + persisted_entries::CandidateEntry, + time::{slot_number_to_tick, Tick}, +}; + +use super::{State, LOG_TARGET}; + +#[derive(Debug)] +struct ImportedBlockInfo { + included_candidates: Vec<(CandidateHash, CandidateReceipt, CoreIndex, GroupIndex)>, + session_index: SessionIndex, + assignments: HashMap, + n_validators: usize, + relay_vrf_story: RelayVRFStory, + slot: Slot, + force_approve: Option, +} + +struct ImportedBlockInfoEnv<'a> { + runtime_info: &'a mut RuntimeInfo, + assignment_criteria: &'a (dyn AssignmentCriteria + Send + Sync), + keystore: &'a LocalKeystore, +} + +#[derive(Debug, thiserror::Error)] +enum ImportedBlockInfoError { + // NOTE: The `RuntimeApiError` already prints out which request it was, + // so it's not necessary to include that here. + #[error(transparent)] + RuntimeError(RuntimeApiError), + + #[error("future cancalled while requesting {0}")] + FutureCancelled(&'static str, futures::channel::oneshot::Canceled), + + #[error(transparent)] + ApprovalError(approval_types::ApprovalError), + + #[error("block is already finalized")] + BlockAlreadyFinalized, + + #[error("session info unavailable")] + SessionInfoUnavailable, + + #[error("VRF info unavailable")] + VrfInfoUnavailable, +} + +/// Computes information about the imported block. Returns an error if the info couldn't be +/// extracted. +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +async fn imported_block_info( + ctx: &mut Context, + env: ImportedBlockInfoEnv<'_>, + block_hash: Hash, + block_header: &Header, + last_finalized_height: &Option, +) -> Result { + // Ignore any runtime API errors - that means these blocks are old and finalized. + // Only unfinalized blocks factor into the approval voting process. + + // fetch candidates + let included_candidates: Vec<_> = { + let (c_tx, c_rx) = oneshot::channel(); + ctx.send_message(RuntimeApiMessage::Request( + block_hash, + RuntimeApiRequest::CandidateEvents(c_tx), + )) + .await; + + let events: Vec = match c_rx.await { + Ok(Ok(events)) => events, + Ok(Err(error)) => return Err(ImportedBlockInfoError::RuntimeError(error)), + Err(error) => + return Err(ImportedBlockInfoError::FutureCancelled("CandidateEvents", error)), + }; + + events + .into_iter() + .filter_map(|e| match e { + CandidateEvent::CandidateIncluded(receipt, _, core, group) => + Some((receipt.hash(), receipt, core, group)), + _ => None, + }) + .collect() + }; + + // fetch session. ignore blocks that are too old, but unless sessions are really + // short, that shouldn't happen. + let session_index = { + let (s_tx, s_rx) = oneshot::channel(); + ctx.send_message(RuntimeApiMessage::Request( + block_header.parent_hash, + RuntimeApiRequest::SessionIndexForChild(s_tx), + )) + .await; + + let session_index = match s_rx.await { + Ok(Ok(s)) => s, + Ok(Err(error)) => return Err(ImportedBlockInfoError::RuntimeError(error)), + Err(error) => + return Err(ImportedBlockInfoError::FutureCancelled("SessionIndexForChild", error)), + }; + + // We can't determine if the block is finalized or not - try processing it + if last_finalized_height.map_or(false, |finalized| block_header.number < finalized) { + gum::debug!( + target: LOG_TARGET, + session = session_index, + finalized = ?last_finalized_height, + "Block {} is either finalized or last finalized height is unknown. Skipping", + block_hash, + ); + + return Err(ImportedBlockInfoError::BlockAlreadyFinalized) + } + + session_index + }; + + let babe_epoch = { + let (s_tx, s_rx) = oneshot::channel(); + + // It's not obvious whether to use the hash or the parent hash for this, intuitively. We + // want to use the block hash itself, and here's why: + // + // First off, 'epoch' in BABE means 'session' in other places. 'epoch' is the terminology + // from the paper, which we fulfill using 'session's, which are a Substrate consensus + // concept. + // + // In BABE, the on-chain and off-chain view of the current epoch can differ at epoch + // boundaries because epochs change precisely at a slot. When a block triggers a new epoch, + // the state of its parent will still have the old epoch. Conversely, we have the invariant + // that every block in BABE has the epoch _it was authored in_ within its post-state. So we + // use the block, and not its parent. + // + // It's worth nothing that Polkadot session changes, at least for the purposes of + // parachains, would function the same way, except for the fact that they're always delayed + // by one block. This gives us the opposite invariant for sessions - the parent block's + // post-state gives us the canonical information about the session index for any of its + // children, regardless of which slot number they might be produced at. + ctx.send_message(RuntimeApiMessage::Request( + block_hash, + RuntimeApiRequest::CurrentBabeEpoch(s_tx), + )) + .await; + + match s_rx.await { + Ok(Ok(s)) => s, + Ok(Err(error)) => return Err(ImportedBlockInfoError::RuntimeError(error)), + Err(error) => + return Err(ImportedBlockInfoError::FutureCancelled("CurrentBabeEpoch", error)), + } + }; + + let session_info = get_session_info(env.runtime_info, ctx.sender(), block_hash, session_index) + .await + .ok_or(ImportedBlockInfoError::SessionInfoUnavailable)?; + + let (assignments, slot, relay_vrf_story) = { + let unsafe_vrf = approval_types::babe_unsafe_vrf_info(&block_header); + + match unsafe_vrf { + Some(unsafe_vrf) => { + let slot = unsafe_vrf.slot(); + + match unsafe_vrf.compute_randomness( + &babe_epoch.authorities, + &babe_epoch.randomness, + babe_epoch.epoch_index, + ) { + Ok(relay_vrf) => { + let assignments = env.assignment_criteria.compute_assignments( + &env.keystore, + relay_vrf.clone(), + &crate::criteria::Config::from(session_info), + included_candidates + .iter() + .map(|(c_hash, _, core, group)| (*c_hash, *core, *group)) + .collect(), + ); + + (assignments, slot, relay_vrf) + }, + Err(error) => return Err(ImportedBlockInfoError::ApprovalError(error)), + } + }, + None => { + gum::debug!( + target: LOG_TARGET, + "BABE VRF info unavailable for block {}", + block_hash, + ); + + return Err(ImportedBlockInfoError::VrfInfoUnavailable) + }, + } + }; + + gum::trace!(target: LOG_TARGET, n_assignments = assignments.len(), "Produced assignments"); + + let force_approve = + block_header.digest.convert_first(|l| match ConsensusLog::from_digest_item(l) { + Ok(Some(ConsensusLog::ForceApprove(num))) if num < block_header.number => { + gum::trace!( + target: LOG_TARGET, + ?block_hash, + current_number = block_header.number, + approved_number = num, + "Force-approving based on header digest" + ); + + Some(num) + }, + Ok(Some(_)) => None, + Ok(None) => None, + Err(err) => { + gum::warn!( + target: LOG_TARGET, + ?err, + ?block_hash, + "Malformed consensus digest in header", + ); + + None + }, + }); + + Ok(ImportedBlockInfo { + included_candidates, + session_index, + assignments, + n_validators: session_info.validators.len(), + relay_vrf_story, + slot, + force_approve, + }) +} + +/// Information about a block and imported candidates. +pub struct BlockImportedCandidates { + pub block_hash: Hash, + pub block_number: BlockNumber, + pub block_tick: Tick, + pub no_show_duration: Tick, + pub imported_candidates: Vec<(CandidateHash, CandidateEntry)>, +} + +/// Handle a new notification of a header. This will +/// * determine all blocks to import, +/// * extract candidate information from them +/// * update the rolling session window +/// * compute our assignments +/// * import the block and candidates to the approval DB +/// * and return information about all candidates imported under each block. +/// +/// It is the responsibility of the caller to schedule wakeups for each block. +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +pub(crate) async fn handle_new_head( + ctx: &mut Context, + state: &State, + db: &mut OverlayedBackend<'_, B>, + session_info_provider: &mut RuntimeInfo, + head: Hash, + finalized_number: &Option, +) -> SubsystemResult> { + const MAX_HEADS_LOOK_BACK: BlockNumber = MAX_FINALITY_LAG; + let _handle_new_head_span = state + .spans + .get(&head) + .map(|span| span.child("handle-new-head")) + .unwrap_or_else(|| jaeger::Span::new(head, "handle-new-head")) + .with_string_tag("head", format!("{:?}", head)) + .with_stage(jaeger::Stage::ApprovalChecking); + + let header = { + let (h_tx, h_rx) = oneshot::channel(); + ctx.send_message(ChainApiMessage::BlockHeader(head, h_tx)).await; + match h_rx.await? { + Err(e) => { + gum::debug!( + target: LOG_TARGET, + "Chain API subsystem temporarily unreachable {}", + e, + ); + // May be a better way of handling errors here. + return Ok(Vec::new()) + }, + Ok(None) => { + gum::warn!(target: LOG_TARGET, "Missing header for new head {}", head); + // May be a better way of handling warnings here. + return Ok(Vec::new()) + }, + Ok(Some(h)) => h, + } + }; + + // If we've just started the node and are far behind, + // import at most `MAX_HEADS_LOOK_BACK` blocks. + let lower_bound_number = header.number.saturating_sub(MAX_HEADS_LOOK_BACK); + let lower_bound_number = finalized_number.unwrap_or(lower_bound_number).max(lower_bound_number); + + let new_blocks = determine_new_blocks( + ctx.sender(), + |h| db.load_block_entry(h).map(|e| e.is_some()), + head, + &header, + lower_bound_number, + ) + .map_err(|e| SubsystemError::with_origin("approval-voting", e)) + .await?; + + if new_blocks.is_empty() { + return Ok(Vec::new()) + } + + let mut approval_meta: Vec = Vec::with_capacity(new_blocks.len()); + let mut imported_candidates = Vec::with_capacity(new_blocks.len()); + + // `determine_new_blocks` gives us a vec in backwards order. we want to move forwards. + let imported_blocks_and_info = { + let mut imported_blocks_and_info = Vec::with_capacity(new_blocks.len()); + for (block_hash, block_header) in new_blocks.into_iter().rev() { + let env = ImportedBlockInfoEnv { + runtime_info: session_info_provider, + assignment_criteria: &*state.assignment_criteria, + keystore: &state.keystore, + }; + + match imported_block_info(ctx, env, block_hash, &block_header, finalized_number).await { + Ok(i) => imported_blocks_and_info.push((block_hash, block_header, i)), + Err(error) => { + // It's possible that we've lost a race with finality. + let (tx, rx) = oneshot::channel(); + ctx.send_message(ChainApiMessage::FinalizedBlockHash(block_header.number, tx)) + .await; + + let lost_to_finality = match rx.await { + Ok(Ok(Some(h))) if h != block_hash => true, + _ => false, + }; + + if !lost_to_finality { + // Such errors are likely spurious, but this prevents us from getting gaps + // in the approval-db. + gum::warn!( + target: LOG_TARGET, + "Skipping chain: unable to gather info about imported block {:?}: {}", + (block_hash, block_header.number), + error, + ); + } + + return Ok(Vec::new()) + }, + }; + } + + imported_blocks_and_info + }; + + gum::trace!( + target: LOG_TARGET, + imported_blocks = imported_blocks_and_info.len(), + "Inserting imported blocks into database" + ); + + for (block_hash, block_header, imported_block_info) in imported_blocks_and_info { + let ImportedBlockInfo { + included_candidates, + session_index, + assignments, + n_validators, + relay_vrf_story, + slot, + force_approve, + } = imported_block_info; + + let session_info = match get_session_info( + session_info_provider, + ctx.sender(), + head, + session_index, + ) + .await + { + Some(session_info) => session_info, + None => return Ok(Vec::new()), + }; + + let (block_tick, no_show_duration) = { + let block_tick = slot_number_to_tick(state.slot_duration_millis, slot); + let no_show_duration = slot_number_to_tick( + state.slot_duration_millis, + Slot::from(u64::from(session_info.no_show_slots)), + ); + (block_tick, no_show_duration) + }; + + let needed_approvals = session_info.needed_approvals; + let validator_group_lens: Vec = + session_info.validator_groups.iter().map(|v| v.len()).collect(); + // insta-approve candidates on low-node testnets: + // cf. https://github.com/paritytech/polkadot/issues/2411 + let num_candidates = included_candidates.len(); + let approved_bitfield = { + if needed_approvals == 0 { + gum::debug!( + target: LOG_TARGET, + block_hash = ?block_hash, + "Insta-approving all candidates", + ); + bitvec::bitvec![u8, BitOrderLsb0; 1; num_candidates] + } else { + let mut result = bitvec::bitvec![u8, BitOrderLsb0; 0; num_candidates]; + for (i, &(_, _, _, backing_group)) in included_candidates.iter().enumerate() { + let backing_group_size = + validator_group_lens.get(backing_group.0 as usize).copied().unwrap_or(0); + let needed_approvals = + usize::try_from(needed_approvals).expect("usize is at least u32; qed"); + if n_validators.saturating_sub(backing_group_size) < needed_approvals { + result.set(i, true); + } + } + if result.any() { + gum::debug!( + target: LOG_TARGET, + block_hash = ?block_hash, + "Insta-approving {}/{} candidates as the number of validators is too low", + result.count_ones(), + result.len(), + ); + } + result + } + }; + // If all bits are already set, then send an approve message. + if approved_bitfield.count_ones() == approved_bitfield.len() { + ctx.send_message(ChainSelectionMessage::Approved(block_hash)).await; + } + + let block_entry = v1::BlockEntry { + block_hash, + parent_hash: block_header.parent_hash, + block_number: block_header.number, + session: session_index, + slot, + relay_vrf_story: relay_vrf_story.0, + candidates: included_candidates + .iter() + .map(|(hash, _, core, _)| (*core, *hash)) + .collect(), + approved_bitfield, + children: Vec::new(), + }; + + gum::trace!( + target: LOG_TARGET, + ?block_hash, + block_number = block_header.number, + "Writing BlockEntry", + ); + + let candidate_entries = + crate::ops::add_block_entry(db, block_entry.into(), n_validators, |candidate_hash| { + included_candidates.iter().find(|(hash, _, _, _)| candidate_hash == hash).map( + |(_, receipt, core, backing_group)| { + super::ops::NewCandidateInfo::new( + receipt.clone(), + *backing_group, + assignments.get(core).map(|a| a.clone().into()), + ) + }, + ) + }) + .map_err(|e| SubsystemError::with_origin("approval-voting", e))?; + + // force-approve needs to load the current block entry as well as all + // ancestors. this can only be done after writing the block entry above. + if let Some(up_to) = force_approve { + gum::debug!(target: LOG_TARGET, ?block_hash, up_to, "Enacting force-approve"); + let approved_hashes = crate::ops::force_approve(db, block_hash, up_to) + .map_err(|e| SubsystemError::with_origin("approval-voting", e))?; + gum::debug!( + target: LOG_TARGET, + ?block_hash, + up_to, + "Force-approving {} blocks", + approved_hashes.len() + ); + + // Notify chain-selection of all approved hashes. + for hash in approved_hashes { + ctx.send_message(ChainSelectionMessage::Approved(hash)).await; + } + } + + approval_meta.push(BlockApprovalMeta { + hash: block_hash, + number: block_header.number, + parent_hash: block_header.parent_hash, + candidates: included_candidates.iter().map(|(hash, _, _, _)| *hash).collect(), + slot, + session: session_index, + }); + + imported_candidates.push(BlockImportedCandidates { + block_hash, + block_number: block_header.number, + block_tick, + no_show_duration, + imported_candidates: candidate_entries + .into_iter() + .map(|(h, e)| (h, e.into())) + .collect(), + }); + } + + gum::trace!( + target: LOG_TARGET, + head = ?head, + chain_length = approval_meta.len(), + "Informing distribution of newly imported chain", + ); + + ctx.send_unbounded_message(ApprovalDistributionMessage::NewBlocks(approval_meta)); + Ok(imported_candidates) +} + +#[cfg(test)] +pub(crate) mod tests { + use super::*; + use crate::{approval_db::v1::DbBackend, RuntimeInfo, RuntimeInfoConfig}; + use ::test_helpers::{dummy_candidate_receipt, dummy_hash}; + use assert_matches::assert_matches; + use polkadot_node_primitives::{ + approval::{VrfSignature, VrfTranscript}, + DISPUTE_WINDOW, + }; + use polkadot_node_subsystem::messages::{AllMessages, ApprovalVotingMessage}; + use polkadot_node_subsystem_test_helpers::make_subsystem_context; + use polkadot_node_subsystem_util::database::Database; + use polkadot_primitives::{Id as ParaId, IndexedVec, SessionInfo, ValidatorId, ValidatorIndex}; + pub(crate) use sp_consensus_babe::{ + digests::{CompatibleDigestItem, PreDigest, SecondaryVRFPreDigest}, + AllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch, + }; + use sp_core::{crypto::VrfSecret, testing::TaskExecutor}; + use sp_keyring::sr25519::Keyring as Sr25519Keyring; + pub(crate) use sp_runtime::{Digest, DigestItem}; + use std::{pin::Pin, sync::Arc}; + + use crate::{approval_db::v1::Config as DatabaseConfig, criteria, BlockEntry}; + + const DATA_COL: u32 = 0; + + const NUM_COLUMNS: u32 = 1; + + const TEST_CONFIG: DatabaseConfig = DatabaseConfig { col_approval_data: DATA_COL }; + #[derive(Default)] + struct MockClock; + + impl crate::time::Clock for MockClock { + fn tick_now(&self) -> Tick { + 42 // chosen by fair dice roll + } + + fn wait(&self, _tick: Tick) -> Pin + Send + 'static>> { + Box::pin(async move { () }) + } + } + + fn blank_state() -> State { + State { + keystore: Arc::new(LocalKeystore::in_memory()), + slot_duration_millis: 6_000, + clock: Box::new(MockClock::default()), + assignment_criteria: Box::new(MockAssignmentCriteria), + spans: HashMap::new(), + } + } + + fn single_session_state() -> (State, RuntimeInfo) { + ( + blank_state(), + RuntimeInfo::new_with_config(RuntimeInfoConfig { + keystore: None, + session_cache_lru_size: DISPUTE_WINDOW.into(), + }), + ) + } + + struct MockAssignmentCriteria; + + impl AssignmentCriteria for MockAssignmentCriteria { + fn compute_assignments( + &self, + _keystore: &LocalKeystore, + _relay_vrf_story: polkadot_node_primitives::approval::RelayVRFStory, + _config: &criteria::Config, + _leaving_cores: Vec<( + CandidateHash, + polkadot_primitives::CoreIndex, + polkadot_primitives::GroupIndex, + )>, + ) -> HashMap { + HashMap::new() + } + + fn check_assignment_cert( + &self, + _claimed_core_index: polkadot_primitives::CoreIndex, + _validator_index: polkadot_primitives::ValidatorIndex, + _config: &criteria::Config, + _relay_vrf_story: polkadot_node_primitives::approval::RelayVRFStory, + _assignment: &polkadot_node_primitives::approval::AssignmentCert, + _backing_group: polkadot_primitives::GroupIndex, + ) -> Result { + Ok(0) + } + } + + // used for generating assignments where the validity of the VRF doesn't matter. + pub(crate) fn garbage_vrf_signature() -> VrfSignature { + let transcript = VrfTranscript::new(b"test-garbage", &[]); + Sr25519Keyring::Alice.pair().vrf_sign(&transcript.into()) + } + + fn dummy_session_info(index: SessionIndex) -> SessionInfo { + SessionInfo { + validators: Default::default(), + discovery_keys: Vec::new(), + assignment_keys: Vec::new(), + validator_groups: Default::default(), + n_cores: index as _, + zeroth_delay_tranche_width: index as _, + relay_vrf_modulo_samples: index as _, + n_delay_tranches: index as _, + no_show_slots: index as _, + needed_approvals: index as _, + active_validator_indices: Vec::new(), + dispute_period: 6, + random_seed: [0u8; 32], + } + } + + #[test] + fn imported_block_info_is_good() { + let pool = TaskExecutor::new(); + let (mut ctx, mut handle) = + make_subsystem_context::(pool.clone()); + + let session = 5; + let session_info = dummy_session_info(session); + + let slot = Slot::from(10); + + let header = Header { + digest: { + let mut d = Digest::default(); + let vrf_signature = garbage_vrf_signature(); + d.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF( + SecondaryVRFPreDigest { authority_index: 0, slot, vrf_signature }, + ))); + + d + }, + extrinsics_root: Default::default(), + number: 5, + state_root: Default::default(), + parent_hash: Default::default(), + }; + + let hash = header.hash(); + let make_candidate = |para_id| { + let mut r = dummy_candidate_receipt(dummy_hash()); + r.descriptor.para_id = para_id; + r.descriptor.relay_parent = hash; + r + }; + let candidates = vec![ + (make_candidate(1.into()), CoreIndex(0), GroupIndex(2)), + (make_candidate(2.into()), CoreIndex(1), GroupIndex(3)), + ]; + + let inclusion_events = candidates + .iter() + .cloned() + .map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g)) + .collect::>(); + + let test_fut = { + let included_candidates = candidates + .iter() + .map(|(r, c, g)| (r.hash(), r.clone(), *c, *g)) + .collect::>(); + + let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig { + keystore: None, + session_cache_lru_size: DISPUTE_WINDOW.into(), + }); + + let header = header.clone(); + Box::pin(async move { + let env = ImportedBlockInfoEnv { + runtime_info: &mut runtime_info, + assignment_criteria: &MockAssignmentCriteria, + keystore: &LocalKeystore::in_memory(), + }; + + let info = + imported_block_info(&mut ctx, env, hash, &header, &Some(4)).await.unwrap(); + + assert_eq!(info.included_candidates, included_candidates); + assert_eq!(info.session_index, session); + assert!(info.assignments.is_empty()); + assert_eq!(info.n_validators, 0); + assert_eq!(info.slot, slot); + assert!(info.force_approve.is_none()); + }) + }; + + let aux_fut = Box::pin(async move { + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::CandidateEvents(c_tx), + )) => { + assert_eq!(h, hash); + let _ = c_tx.send(Ok(inclusion_events)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::SessionIndexForChild(c_tx), + )) => { + assert_eq!(h, header.parent_hash); + let _ = c_tx.send(Ok(session)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::CurrentBabeEpoch(c_tx), + )) => { + assert_eq!(h, hash); + let _ = c_tx.send(Ok(BabeEpoch { + epoch_index: session as _, + start_slot: Slot::from(0), + duration: 200, + authorities: vec![(Sr25519Keyring::Alice.public().into(), 1)], + randomness: [0u8; 32], + config: BabeEpochConfiguration { + c: (1, 4), + allowed_slots: AllowedSlots::PrimarySlots, + }, + })); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + req_block_hash, + RuntimeApiRequest::SessionInfo(idx, si_tx), + ) + ) => { + assert_eq!(session, idx); + assert_eq!(req_block_hash, hash); + si_tx.send(Ok(Some(session_info.clone()))).unwrap(); + } + ); + }); + + futures::executor::block_on(futures::future::join(test_fut, aux_fut)); + } + + #[test] + fn imported_block_info_fails_if_no_babe_vrf() { + let pool = TaskExecutor::new(); + let (mut ctx, mut handle) = + make_subsystem_context::(pool.clone()); + + let session = 5; + let session_info = dummy_session_info(session); + + let header = Header { + digest: Digest::default(), + extrinsics_root: Default::default(), + number: 5, + state_root: Default::default(), + parent_hash: Default::default(), + }; + + let hash = header.hash(); + let make_candidate = |para_id| { + let mut r = dummy_candidate_receipt(dummy_hash()); + r.descriptor.para_id = para_id; + r.descriptor.relay_parent = hash; + r + }; + let candidates = vec![ + (make_candidate(1.into()), CoreIndex(0), GroupIndex(2)), + (make_candidate(2.into()), CoreIndex(1), GroupIndex(3)), + ]; + + let inclusion_events = candidates + .iter() + .cloned() + .map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g)) + .collect::>(); + + let test_fut = { + let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig { + keystore: None, + session_cache_lru_size: DISPUTE_WINDOW.into(), + }); + + let header = header.clone(); + Box::pin(async move { + let env = ImportedBlockInfoEnv { + runtime_info: &mut runtime_info, + assignment_criteria: &MockAssignmentCriteria, + keystore: &LocalKeystore::in_memory(), + }; + + let info = imported_block_info(&mut ctx, env, hash, &header, &Some(4)).await; + + assert_matches!(info, Err(ImportedBlockInfoError::VrfInfoUnavailable)); + }) + }; + + let aux_fut = Box::pin(async move { + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::CandidateEvents(c_tx), + )) => { + assert_eq!(h, hash); + let _ = c_tx.send(Ok(inclusion_events)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::SessionIndexForChild(c_tx), + )) => { + assert_eq!(h, header.parent_hash); + let _ = c_tx.send(Ok(session)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::CurrentBabeEpoch(c_tx), + )) => { + assert_eq!(h, hash); + let _ = c_tx.send(Ok(BabeEpoch { + epoch_index: session as _, + start_slot: Slot::from(0), + duration: 200, + authorities: vec![(Sr25519Keyring::Alice.public().into(), 1)], + randomness: [0u8; 32], + config: BabeEpochConfiguration { + c: (1, 4), + allowed_slots: AllowedSlots::PrimarySlots, + }, + })); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + req_block_hash, + RuntimeApiRequest::SessionInfo(idx, si_tx), + ) + ) => { + assert_eq!(session, idx); + assert_eq!(req_block_hash, hash); + si_tx.send(Ok(Some(session_info.clone()))).unwrap(); + } + ); + }); + + futures::executor::block_on(futures::future::join(test_fut, aux_fut)); + } + + #[test] + fn imported_block_info_fails_if_ancient_session() { + let pool = TaskExecutor::new(); + let (mut ctx, mut handle) = + make_subsystem_context::(pool.clone()); + + let session = 5; + + let header = Header { + digest: Digest::default(), + extrinsics_root: Default::default(), + number: 5, + state_root: Default::default(), + parent_hash: Default::default(), + }; + + let hash = header.hash(); + let make_candidate = |para_id| { + let mut r = dummy_candidate_receipt(dummy_hash()); + r.descriptor.para_id = para_id; + r.descriptor.relay_parent = hash; + r + }; + let candidates = vec![ + (make_candidate(1.into()), CoreIndex(0), GroupIndex(2)), + (make_candidate(2.into()), CoreIndex(1), GroupIndex(3)), + ]; + + let inclusion_events = candidates + .iter() + .cloned() + .map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g)) + .collect::>(); + + let test_fut = { + let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig { + keystore: None, + session_cache_lru_size: DISPUTE_WINDOW.into(), + }); + + let header = header.clone(); + Box::pin(async move { + let env = ImportedBlockInfoEnv { + runtime_info: &mut runtime_info, + assignment_criteria: &MockAssignmentCriteria, + keystore: &LocalKeystore::in_memory(), + }; + + let info = imported_block_info(&mut ctx, env, hash, &header, &Some(6)).await; + + assert_matches!(info, Err(ImportedBlockInfoError::BlockAlreadyFinalized)); + }) + }; + + let aux_fut = Box::pin(async move { + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::CandidateEvents(c_tx), + )) => { + assert_eq!(h, hash); + let _ = c_tx.send(Ok(inclusion_events)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::SessionIndexForChild(c_tx), + )) => { + assert_eq!(h, header.parent_hash); + let _ = c_tx.send(Ok(session)); + } + ); + }); + + futures::executor::block_on(futures::future::join(test_fut, aux_fut)); + } + + #[test] + fn imported_block_info_extracts_force_approve() { + let pool = TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context(pool.clone()); + + let session = 5; + let session_info = dummy_session_info(session); + + let slot = Slot::from(10); + + let header = Header { + digest: { + let mut d = Digest::default(); + let vrf_signature = garbage_vrf_signature(); + d.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF( + SecondaryVRFPreDigest { authority_index: 0, slot, vrf_signature }, + ))); + + d.push(ConsensusLog::ForceApprove(3).into()); + + d + }, + extrinsics_root: Default::default(), + number: 5, + state_root: Default::default(), + parent_hash: Default::default(), + }; + + let hash = header.hash(); + let make_candidate = |para_id| { + let mut r = dummy_candidate_receipt(dummy_hash()); + r.descriptor.para_id = para_id; + r.descriptor.relay_parent = hash; + r + }; + let candidates = vec![ + (make_candidate(1.into()), CoreIndex(0), GroupIndex(2)), + (make_candidate(2.into()), CoreIndex(1), GroupIndex(3)), + ]; + + let inclusion_events = candidates + .iter() + .cloned() + .map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g)) + .collect::>(); + + let test_fut = { + let included_candidates = candidates + .iter() + .map(|(r, c, g)| (r.hash(), r.clone(), *c, *g)) + .collect::>(); + + let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig { + keystore: None, + session_cache_lru_size: DISPUTE_WINDOW.into(), + }); + + let header = header.clone(); + Box::pin(async move { + let env = ImportedBlockInfoEnv { + runtime_info: &mut runtime_info, + assignment_criteria: &MockAssignmentCriteria, + keystore: &LocalKeystore::in_memory(), + }; + + let info = + imported_block_info(&mut ctx, env, hash, &header, &Some(4)).await.unwrap(); + + assert_eq!(info.included_candidates, included_candidates); + assert_eq!(info.session_index, session); + assert!(info.assignments.is_empty()); + assert_eq!(info.n_validators, 0); + assert_eq!(info.slot, slot); + assert_eq!(info.force_approve, Some(3)); + }) + }; + + let aux_fut = Box::pin(async move { + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::CandidateEvents(c_tx), + )) => { + assert_eq!(h, hash); + let _ = c_tx.send(Ok(inclusion_events)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::SessionIndexForChild(c_tx), + )) => { + assert_eq!(h, header.parent_hash); + let _ = c_tx.send(Ok(session)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::CurrentBabeEpoch(c_tx), + )) => { + assert_eq!(h, hash); + let _ = c_tx.send(Ok(BabeEpoch { + epoch_index: session as _, + start_slot: Slot::from(0), + duration: 200, + authorities: vec![(Sr25519Keyring::Alice.public().into(), 1)], + randomness: [0u8; 32], + config: BabeEpochConfiguration { + c: (1, 4), + allowed_slots: AllowedSlots::PrimarySlots, + }, + })); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + req_block_hash, + RuntimeApiRequest::SessionInfo(idx, si_tx), + ) + ) => { + assert_eq!(session, idx); + assert_eq!(req_block_hash, hash); + si_tx.send(Ok(Some(session_info.clone()))).unwrap(); + } + ); + }); + + futures::executor::block_on(futures::future::join(test_fut, aux_fut)); + } + + #[test] + fn insta_approval_works() { + let db = kvdb_memorydb::create(NUM_COLUMNS); + let db = polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter::new(db, &[]); + let db_writer: Arc = Arc::new(db); + let mut db = DbBackend::new(db_writer.clone(), TEST_CONFIG); + let mut overlay_db = OverlayedBackend::new(&db); + + let pool = TaskExecutor::new(); + let (mut ctx, mut handle) = + make_subsystem_context::(pool.clone()); + + let session = 5; + let irrelevant = 666; + let session_info = + SessionInfo { + validators: IndexedVec::::from( + vec![Sr25519Keyring::Alice.public().into(); 6], + ), + discovery_keys: Vec::new(), + assignment_keys: Vec::new(), + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0); 5], + vec![ValidatorIndex(0); 2], + ]), + n_cores: 6, + needed_approvals: 2, + zeroth_delay_tranche_width: irrelevant, + relay_vrf_modulo_samples: irrelevant, + n_delay_tranches: irrelevant, + no_show_slots: irrelevant, + active_validator_indices: Vec::new(), + dispute_period: 6, + random_seed: [0u8; 32], + }; + + let slot = Slot::from(10); + + let parent_hash = Hash::repeat_byte(0x01); + + let header = Header { + digest: { + let mut d = Digest::default(); + let vrf_signature = garbage_vrf_signature(); + d.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF( + SecondaryVRFPreDigest { authority_index: 0, slot, vrf_signature }, + ))); + + d + }, + extrinsics_root: Default::default(), + number: 5, + state_root: Default::default(), + parent_hash, + }; + + let hash = header.hash(); + let make_candidate = |para_id| { + let mut r = dummy_candidate_receipt(dummy_hash()); + r.descriptor.para_id = para_id; + r.descriptor.relay_parent = hash; + r + }; + let candidates = vec![ + (make_candidate(ParaId::from(1)), CoreIndex(0), GroupIndex(0)), + (make_candidate(ParaId::from(2)), CoreIndex(1), GroupIndex(1)), + ]; + let inclusion_events = candidates + .iter() + .cloned() + .map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g)) + .collect::>(); + + let (state, mut session_info_provider) = single_session_state(); + overlay_db.write_block_entry( + v1::BlockEntry { + block_hash: parent_hash, + parent_hash: Default::default(), + block_number: 4, + session, + slot, + relay_vrf_story: Default::default(), + candidates: Vec::new(), + approved_bitfield: Default::default(), + children: Vec::new(), + } + .into(), + ); + + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + let test_fut = { + Box::pin(async move { + let mut overlay_db = OverlayedBackend::new(&db); + let result = handle_new_head( + &mut ctx, + &state, + &mut overlay_db, + &mut session_info_provider, + hash, + &Some(1), + ) + .await + .unwrap(); + + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); + + assert_eq!(result.len(), 1); + let candidates = &result[0].imported_candidates; + assert_eq!(candidates.len(), 2); + assert_eq!(candidates[0].1.approvals().len(), 6); + assert_eq!(candidates[1].1.approvals().len(), 6); + // the first candidate should be insta-approved + // the second should not + let entry: BlockEntry = + v1::load_block_entry(db_writer.as_ref(), &TEST_CONFIG, &hash) + .unwrap() + .unwrap() + .into(); + assert!(entry.is_candidate_approved(&candidates[0].0)); + assert!(!entry.is_candidate_approved(&candidates[1].0)); + }) + }; + + let aux_fut = Box::pin(async move { + assert_matches!( + handle.recv().await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader( + h, + tx, + )) => { + assert_eq!(h, hash); + let _ = tx.send(Ok(Some(header.clone()))); + } + ); + + // determine_new_blocks exits early as the parent_hash is in the DB + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::CandidateEvents(c_tx), + )) => { + assert_eq!(h, hash.clone()); + let _ = c_tx.send(Ok(inclusion_events)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::SessionIndexForChild(c_tx), + )) => { + assert_eq!(h, parent_hash.clone()); + let _ = c_tx.send(Ok(session)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::CurrentBabeEpoch(c_tx), + )) => { + assert_eq!(h, hash); + let _ = c_tx.send(Ok(BabeEpoch { + epoch_index: session as _, + start_slot: Slot::from(0), + duration: 200, + authorities: vec![(Sr25519Keyring::Alice.public().into(), 1)], + randomness: [0u8; 32], + config: BabeEpochConfiguration { + c: (1, 4), + allowed_slots: AllowedSlots::PrimarySlots, + }, + })); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + req_block_hash, + RuntimeApiRequest::SessionInfo(idx, si_tx), + ) + ) => { + assert_eq!(session, idx); + assert_eq!(req_block_hash, hash); + si_tx.send(Ok(Some(session_info.clone()))).unwrap(); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks( + approval_meta + )) => { + assert_eq!(approval_meta.len(), 1); + } + ); + }); + + futures::executor::block_on(futures::future::join(test_fut, aux_fut)); + } +} diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..b29e47b4c4354f559ba9daaa0f56e7effdede9a9 --- /dev/null +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -0,0 +1,2866 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Approval Voting Subsystem. +//! +//! This subsystem is responsible for determining candidates to do approval checks +//! on, performing those approval checks, and tracking the assignments and approvals +//! of others. It uses this information to determine when candidates and blocks have +//! been sufficiently approved to finalize. + +use jaeger::{hash_to_trace_identifier, PerLeafSpan}; +use polkadot_node_jaeger as jaeger; +use polkadot_node_primitives::{ + approval::{ + BlockApprovalMeta, DelayTranche, IndirectAssignmentCert, IndirectSignedApprovalVote, + }, + ValidationResult, DISPUTE_WINDOW, +}; +use polkadot_node_subsystem::{ + errors::RecoveryError, + messages::{ + ApprovalCheckError, ApprovalCheckResult, ApprovalDistributionMessage, + ApprovalVotingMessage, AssignmentCheckError, AssignmentCheckResult, + AvailabilityRecoveryMessage, BlockDescription, CandidateValidationMessage, ChainApiMessage, + ChainSelectionMessage, DisputeCoordinatorMessage, HighestApprovedAncestorBlock, + RuntimeApiMessage, RuntimeApiRequest, + }, + overseer, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, SubsystemResult, + SubsystemSender, +}; +use polkadot_node_subsystem_util::{ + self, + database::Database, + metrics::{self, prometheus}, + runtime::{Config as RuntimeInfoConfig, RuntimeInfo}, + TimeoutExt, +}; +use polkadot_primitives::{ + ApprovalVote, BlockNumber, CandidateHash, CandidateIndex, CandidateReceipt, DisputeStatement, + GroupIndex, Hash, PvfExecTimeoutKind, SessionIndex, SessionInfo, ValidDisputeStatementKind, + ValidatorId, ValidatorIndex, ValidatorPair, ValidatorSignature, +}; +use sc_keystore::LocalKeystore; +use sp_application_crypto::Pair; +use sp_consensus::SyncOracle; +use sp_consensus_slots::Slot; + +use futures::{ + channel::oneshot, + future::{BoxFuture, RemoteHandle}, + prelude::*, + stream::FuturesUnordered, +}; + +use std::{ + collections::{ + btree_map::Entry as BTMEntry, hash_map::Entry as HMEntry, BTreeMap, HashMap, HashSet, + }, + num::NonZeroUsize, + sync::Arc, + time::Duration, +}; + +use approval_checking::RequiredTranches; +use criteria::{AssignmentCriteria, RealAssignmentCriteria}; +use persisted_entries::{ApprovalEntry, BlockEntry, CandidateEntry}; +use time::{slot_number_to_tick, Clock, ClockExt, SystemClock, Tick}; + +mod approval_checking; +mod approval_db; +mod backend; +mod criteria; +mod import; +mod ops; +mod persisted_entries; +mod time; + +use crate::{ + approval_db::v1::{Config as DatabaseConfig, DbBackend}, + backend::{Backend, OverlayedBackend}, +}; + +#[cfg(test)] +mod tests; + +const APPROVAL_CHECKING_TIMEOUT: Duration = Duration::from_secs(120); +/// How long are we willing to wait for approval signatures? +/// +/// Value rather arbitrarily: Should not be hit in practice, it exists to more easily diagnose dead +/// lock issues for example. +const WAIT_FOR_SIGS_TIMEOUT: Duration = Duration::from_millis(500); +const APPROVAL_CACHE_SIZE: NonZeroUsize = match NonZeroUsize::new(1024) { + Some(cap) => cap, + None => panic!("Approval cache size must be non-zero."), +}; + +const TICK_TOO_FAR_IN_FUTURE: Tick = 20; // 10 seconds. +const APPROVAL_DELAY: Tick = 2; +const LOG_TARGET: &str = "parachain::approval-voting"; + +/// Configuration for the approval voting subsystem +#[derive(Debug, Clone)] +pub struct Config { + /// The column family in the DB where approval-voting data is stored. + pub col_approval_data: u32, + /// The slot duration of the consensus algorithm, in milliseconds. Should be evenly + /// divisible by 500. + pub slot_duration_millis: u64, +} + +// The mode of the approval voting subsystem. It should start in a `Syncing` mode when it first +// starts, and then once it's reached the head of the chain it should move into the `Active` mode. +// +// In `Active` mode, the node is an active participant in the approvals protocol. When syncing, +// the node follows the new incoming blocks and finalized number, but does not yet participate. +// +// When transitioning from `Syncing` to `Active`, the node notifies the `ApprovalDistribution` +// subsystem of all unfinalized blocks and the candidates included within them, as well as all +// votes that the local node itself has cast on candidates within those blocks. +enum Mode { + Active, + Syncing(Box), +} + +/// The approval voting subsystem. +pub struct ApprovalVotingSubsystem { + /// `LocalKeystore` is needed for assignment keys, but not necessarily approval keys. + /// + /// We do a lot of VRF signing and need the keys to have low latency. + keystore: Arc, + db_config: DatabaseConfig, + slot_duration_millis: u64, + db: Arc, + mode: Mode, + metrics: Metrics, +} + +#[derive(Clone)] +struct MetricsInner { + imported_candidates_total: prometheus::Counter, + assignments_produced: prometheus::Histogram, + approvals_produced_total: prometheus::CounterVec, + no_shows_total: prometheus::Counter, + wakeups_triggered_total: prometheus::Counter, + candidate_approval_time_ticks: prometheus::Histogram, + block_approval_time_ticks: prometheus::Histogram, + time_db_transaction: prometheus::Histogram, + time_recover_and_approve: prometheus::Histogram, + candidate_signatures_requests_total: prometheus::Counter, + unapproved_candidates_in_unfinalized_chain: prometheus::Gauge, +} + +/// Approval Voting metrics. +#[derive(Default, Clone)] +pub struct Metrics(Option); + +impl Metrics { + fn on_candidate_imported(&self) { + if let Some(metrics) = &self.0 { + metrics.imported_candidates_total.inc(); + } + } + + fn on_assignment_produced(&self, tranche: DelayTranche) { + if let Some(metrics) = &self.0 { + metrics.assignments_produced.observe(tranche as f64); + } + } + + fn on_approval_stale(&self) { + if let Some(metrics) = &self.0 { + metrics.approvals_produced_total.with_label_values(&["stale"]).inc() + } + } + + fn on_approval_invalid(&self) { + if let Some(metrics) = &self.0 { + metrics.approvals_produced_total.with_label_values(&["invalid"]).inc() + } + } + + fn on_approval_unavailable(&self) { + if let Some(metrics) = &self.0 { + metrics.approvals_produced_total.with_label_values(&["unavailable"]).inc() + } + } + + fn on_approval_error(&self) { + if let Some(metrics) = &self.0 { + metrics.approvals_produced_total.with_label_values(&["internal error"]).inc() + } + } + + fn on_approval_produced(&self) { + if let Some(metrics) = &self.0 { + metrics.approvals_produced_total.with_label_values(&["success"]).inc() + } + } + + fn on_no_shows(&self, n: usize) { + if let Some(metrics) = &self.0 { + metrics.no_shows_total.inc_by(n as u64); + } + } + + fn on_wakeup(&self) { + if let Some(metrics) = &self.0 { + metrics.wakeups_triggered_total.inc(); + } + } + + fn on_candidate_approved(&self, ticks: Tick) { + if let Some(metrics) = &self.0 { + metrics.candidate_approval_time_ticks.observe(ticks as f64); + } + } + + fn on_block_approved(&self, ticks: Tick) { + if let Some(metrics) = &self.0 { + metrics.block_approval_time_ticks.observe(ticks as f64); + } + } + + fn on_candidate_signatures_request(&self) { + if let Some(metrics) = &self.0 { + metrics.candidate_signatures_requests_total.inc(); + } + } + + fn time_db_transaction(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.time_db_transaction.start_timer()) + } + + fn time_recover_and_approve(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.time_recover_and_approve.start_timer()) + } + + fn on_unapproved_candidates_in_unfinalized_chain(&self, count: usize) { + if let Some(metrics) = &self.0 { + metrics.unapproved_candidates_in_unfinalized_chain.set(count as u64); + } + } +} + +impl metrics::Metrics for Metrics { + fn try_register( + registry: &prometheus::Registry, + ) -> std::result::Result { + let metrics = MetricsInner { + imported_candidates_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_imported_candidates_total", + "Number of candidates imported by the approval voting subsystem", + )?, + registry, + )?, + assignments_produced: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_assignments_produced", + "Assignments and tranches produced by the approval voting subsystem", + ).buckets(vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 10.0, 15.0, 25.0, 40.0, 70.0]), + )?, + registry, + )?, + approvals_produced_total: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_approvals_produced_total", + "Number of approvals produced by the approval voting subsystem", + ), + &["status"] + )?, + registry, + )?, + no_shows_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_approvals_no_shows_total", + "Number of assignments which became no-shows in the approval voting subsystem", + )?, + registry, + )?, + wakeups_triggered_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_approvals_wakeups_total", + "Number of times we woke up to process a candidate in the approval voting subsystem", + )?, + registry, + )?, + candidate_approval_time_ticks: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_approvals_candidate_approval_time_ticks", + "Number of ticks (500ms) to approve candidates.", + ).buckets(vec![6.0, 12.0, 18.0, 24.0, 30.0, 36.0, 72.0, 100.0, 144.0]), + )?, + registry, + )?, + block_approval_time_ticks: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_approvals_blockapproval_time_ticks", + "Number of ticks (500ms) to approve blocks.", + ).buckets(vec![6.0, 12.0, 18.0, 24.0, 30.0, 36.0, 72.0, 100.0, 144.0]), + )?, + registry, + )?, + time_db_transaction: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_time_approval_db_transaction", + "Time spent writing an approval db transaction.", + ) + )?, + registry, + )?, + time_recover_and_approve: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_time_recover_and_approve", + "Time spent recovering and approving data in approval voting", + ) + )?, + registry, + )?, + candidate_signatures_requests_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_approval_candidate_signatures_requests_total", + "Number of times signatures got requested by other subsystems", + )?, + registry, + )?, + unapproved_candidates_in_unfinalized_chain: prometheus::register( + prometheus::Gauge::new( + "polkadot_parachain_approval_unapproved_candidates_in_unfinalized_chain", + "Number of unapproved candidates in unfinalized chain", + )?, + registry, + )?, + }; + + Ok(Metrics(Some(metrics))) + } +} + +impl ApprovalVotingSubsystem { + /// Create a new approval voting subsystem with the given keystore, config, and database. + pub fn with_config( + config: Config, + db: Arc, + keystore: Arc, + sync_oracle: Box, + metrics: Metrics, + ) -> Self { + ApprovalVotingSubsystem { + keystore, + slot_duration_millis: config.slot_duration_millis, + db, + db_config: DatabaseConfig { col_approval_data: config.col_approval_data }, + mode: Mode::Syncing(sync_oracle), + metrics, + } + } + + /// Revert to the block corresponding to the specified `hash`. + /// The operation is not allowed for blocks older than the last finalized one. + pub fn revert_to(&self, hash: Hash) -> Result<(), SubsystemError> { + let config = + approval_db::v1::Config { col_approval_data: self.db_config.col_approval_data }; + let mut backend = approval_db::v1::DbBackend::new(self.db.clone(), config); + let mut overlay = OverlayedBackend::new(&backend); + + ops::revert_to(&mut overlay, hash)?; + + let ops = overlay.into_write_ops(); + backend.write(ops) + } +} + +// Checks and logs approval vote db state. It is perfectly normal to start with an +// empty approval vote DB if we changed DB type or the node will sync from scratch. +fn db_sanity_check(db: Arc, config: DatabaseConfig) -> SubsystemResult<()> { + let backend = DbBackend::new(db, config); + let all_blocks = backend.load_all_blocks()?; + + if all_blocks.is_empty() { + gum::info!(target: LOG_TARGET, "Starting with an empty approval vote DB.",); + } else { + gum::debug!( + target: LOG_TARGET, + "Starting with {} blocks in approval vote DB.", + all_blocks.len() + ); + } + + Ok(()) +} + +#[overseer::subsystem(ApprovalVoting, error = SubsystemError, prefix = self::overseer)] +impl ApprovalVotingSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let backend = DbBackend::new(self.db.clone(), self.db_config); + let future = run::( + ctx, + self, + Box::new(SystemClock), + Box::new(RealAssignmentCriteria), + backend, + ) + .map_err(|e| SubsystemError::with_origin("approval-voting", e)) + .boxed(); + + SpawnedSubsystem { name: "approval-voting-subsystem", future } + } +} + +#[derive(Debug, Clone)] +struct ApprovalVoteRequest { + validator_index: ValidatorIndex, + block_hash: Hash, +} + +#[derive(Default)] +struct Wakeups { + // Tick -> [(Relay Block, Candidate Hash)] + wakeups: BTreeMap>, + reverse_wakeups: HashMap<(Hash, CandidateHash), Tick>, + block_numbers: BTreeMap>, +} + +impl Wakeups { + // Returns the first tick there exist wakeups for, if any. + fn first(&self) -> Option { + self.wakeups.keys().next().map(|t| *t) + } + + fn note_block(&mut self, block_hash: Hash, block_number: BlockNumber) { + self.block_numbers.entry(block_number).or_default().insert(block_hash); + } + + // Schedules a wakeup at the given tick. no-op if there is already an earlier or equal wake-up + // for these values. replaces any later wakeup. + fn schedule( + &mut self, + block_hash: Hash, + block_number: BlockNumber, + candidate_hash: CandidateHash, + tick: Tick, + ) { + if let Some(prev) = self.reverse_wakeups.get(&(block_hash, candidate_hash)) { + if prev <= &tick { + return + } + + // we are replacing previous wakeup with an earlier one. + if let BTMEntry::Occupied(mut entry) = self.wakeups.entry(*prev) { + if let Some(pos) = + entry.get().iter().position(|x| x == &(block_hash, candidate_hash)) + { + entry.get_mut().remove(pos); + } + + if entry.get().is_empty() { + let _ = entry.remove_entry(); + } + } + } else { + self.note_block(block_hash, block_number); + } + + self.reverse_wakeups.insert((block_hash, candidate_hash), tick); + self.wakeups.entry(tick).or_default().push((block_hash, candidate_hash)); + } + + fn prune_finalized_wakeups( + &mut self, + finalized_number: BlockNumber, + spans: &mut HashMap, + ) { + let after = self.block_numbers.split_off(&(finalized_number + 1)); + let pruned_blocks: HashSet<_> = std::mem::replace(&mut self.block_numbers, after) + .into_iter() + .flat_map(|(_number, hashes)| hashes) + .collect(); + + let mut pruned_wakeups = BTreeMap::new(); + self.reverse_wakeups.retain(|(h, c_h), tick| { + let live = !pruned_blocks.contains(h); + if !live { + pruned_wakeups.entry(*tick).or_insert_with(HashSet::new).insert((*h, *c_h)); + } + live + }); + + for (tick, pruned) in pruned_wakeups { + if let BTMEntry::Occupied(mut entry) = self.wakeups.entry(tick) { + entry.get_mut().retain(|wakeup| !pruned.contains(wakeup)); + if entry.get().is_empty() { + let _ = entry.remove(); + } + } + } + + // Remove all spans that are associated with pruned blocks. + spans.retain(|h, _| !pruned_blocks.contains(h)); + } + + // Get the wakeup for a particular block/candidate combo, if any. + fn wakeup_for(&self, block_hash: Hash, candidate_hash: CandidateHash) -> Option { + self.reverse_wakeups.get(&(block_hash, candidate_hash)).map(|t| *t) + } + + // Returns the next wakeup. this future never returns if there are no wakeups. + async fn next(&mut self, clock: &(dyn Clock + Sync)) -> (Tick, Hash, CandidateHash) { + match self.first() { + None => future::pending().await, + Some(tick) => { + clock.wait(tick).await; + match self.wakeups.entry(tick) { + BTMEntry::Vacant(_) => { + panic!("entry is known to exist since `first` was `Some`; qed") + }, + BTMEntry::Occupied(mut entry) => { + let (hash, candidate_hash) = entry.get_mut().pop() + .expect("empty entries are removed here and in `schedule`; no other mutation of this map; qed"); + + if entry.get().is_empty() { + let _ = entry.remove(); + } + + self.reverse_wakeups.remove(&(hash, candidate_hash)); + + (tick, hash, candidate_hash) + }, + } + }, + } + } +} + +struct ApprovalStatus { + required_tranches: RequiredTranches, + tranche_now: DelayTranche, + block_tick: Tick, +} + +#[derive(Copy, Clone)] +enum ApprovalOutcome { + Approved, + Failed, + TimedOut, +} + +struct ApprovalState { + validator_index: ValidatorIndex, + candidate_hash: CandidateHash, + approval_outcome: ApprovalOutcome, +} + +impl ApprovalState { + fn approved(validator_index: ValidatorIndex, candidate_hash: CandidateHash) -> Self { + Self { validator_index, candidate_hash, approval_outcome: ApprovalOutcome::Approved } + } + fn failed(validator_index: ValidatorIndex, candidate_hash: CandidateHash) -> Self { + Self { validator_index, candidate_hash, approval_outcome: ApprovalOutcome::Failed } + } +} + +struct CurrentlyCheckingSet { + candidate_hash_map: HashMap>, + currently_checking: FuturesUnordered>, +} + +impl Default for CurrentlyCheckingSet { + fn default() -> Self { + Self { candidate_hash_map: HashMap::new(), currently_checking: FuturesUnordered::new() } + } +} + +impl CurrentlyCheckingSet { + // This function will lazily launch approval voting work whenever the + // candidate is not already undergoing validation. + pub async fn insert_relay_block_hash( + &mut self, + candidate_hash: CandidateHash, + validator_index: ValidatorIndex, + relay_block: Hash, + launch_work: impl Future>>, + ) -> SubsystemResult<()> { + match self.candidate_hash_map.entry(candidate_hash) { + HMEntry::Occupied(mut entry) => { + // validation already undergoing. just add the relay hash if unknown. + entry.get_mut().insert(relay_block); + }, + HMEntry::Vacant(entry) => { + // validation not ongoing. launch work and time out the remote handle. + entry.insert(HashSet::new()).insert(relay_block); + let work = launch_work.await?; + self.currently_checking.push(Box::pin(async move { + match work.timeout(APPROVAL_CHECKING_TIMEOUT).await { + None => ApprovalState { + candidate_hash, + validator_index, + approval_outcome: ApprovalOutcome::TimedOut, + }, + Some(approval_state) => approval_state, + } + })); + }, + } + + Ok(()) + } + + pub async fn next( + &mut self, + approvals_cache: &mut lru::LruCache, + ) -> (HashSet, ApprovalState) { + if !self.currently_checking.is_empty() { + if let Some(approval_state) = self.currently_checking.next().await { + let out = self + .candidate_hash_map + .remove(&approval_state.candidate_hash) + .unwrap_or_default(); + approvals_cache.put(approval_state.candidate_hash, approval_state.approval_outcome); + return (out, approval_state) + } + } + + future::pending().await + } +} + +async fn get_session_info<'a, Sender>( + runtime_info: &'a mut RuntimeInfo, + sender: &mut Sender, + relay_parent: Hash, + session_index: SessionIndex, +) -> Option<&'a SessionInfo> +where + Sender: SubsystemSender, +{ + match runtime_info + .get_session_info_by_index(sender, relay_parent, session_index) + .await + { + Ok(extended_info) => Some(&extended_info.session_info), + Err(_) => { + gum::debug!( + target: LOG_TARGET, + session = session_index, + ?relay_parent, + "Can't obtain SessionInfo" + ); + None + }, + } +} + +struct State { + keystore: Arc, + slot_duration_millis: u64, + clock: Box, + assignment_criteria: Box, + spans: HashMap, +} + +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +impl State { + // Compute the required tranches for approval for this block and candidate combo. + // Fails if there is no approval entry for the block under the candidate or no candidate entry + // under the block, or if the session is out of bounds. + async fn approval_status( + &'a self, + sender: &mut Sender, + session_info_provider: &'a mut RuntimeInfo, + block_entry: &'a BlockEntry, + candidate_entry: &'b CandidateEntry, + ) -> Option<(&'b ApprovalEntry, ApprovalStatus)> + where + Sender: SubsystemSender, + { + let session_info = match get_session_info( + session_info_provider, + sender, + block_entry.parent_hash(), + block_entry.session(), + ) + .await + { + Some(s) => s, + None => return None, + }; + let block_hash = block_entry.block_hash(); + + let tranche_now = self.clock.tranche_now(self.slot_duration_millis, block_entry.slot()); + let block_tick = slot_number_to_tick(self.slot_duration_millis, block_entry.slot()); + let no_show_duration = slot_number_to_tick( + self.slot_duration_millis, + Slot::from(u64::from(session_info.no_show_slots)), + ); + + if let Some(approval_entry) = candidate_entry.approval_entry(&block_hash) { + let required_tranches = approval_checking::tranches_to_approve( + approval_entry, + candidate_entry.approvals(), + tranche_now, + block_tick, + no_show_duration, + session_info.needed_approvals as _, + ); + + let status = ApprovalStatus { required_tranches, block_tick, tranche_now }; + + Some((approval_entry, status)) + } else { + None + } + } +} + +#[derive(Debug, Clone)] +enum Action { + ScheduleWakeup { + block_hash: Hash, + block_number: BlockNumber, + candidate_hash: CandidateHash, + tick: Tick, + }, + LaunchApproval { + candidate_hash: CandidateHash, + indirect_cert: IndirectAssignmentCert, + assignment_tranche: DelayTranche, + relay_block_hash: Hash, + candidate_index: CandidateIndex, + session: SessionIndex, + candidate: CandidateReceipt, + backing_group: GroupIndex, + }, + NoteApprovedInChainSelection(Hash), + IssueApproval(CandidateHash, ApprovalVoteRequest), + BecomeActive, + Conclude, +} + +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +async fn run( + mut ctx: Context, + mut subsystem: ApprovalVotingSubsystem, + clock: Box, + assignment_criteria: Box, + mut backend: B, +) -> SubsystemResult<()> +where + B: Backend, +{ + if let Err(err) = db_sanity_check(subsystem.db.clone(), subsystem.db_config) { + gum::warn!(target: LOG_TARGET, ?err, "Could not run approval vote DB sanity check"); + } + + let mut state = State { + keystore: subsystem.keystore, + slot_duration_millis: subsystem.slot_duration_millis, + clock, + assignment_criteria, + spans: HashMap::new(), + }; + + // `None` on start-up. Gets initialized/updated on leaf update + let mut session_info_provider = RuntimeInfo::new_with_config(RuntimeInfoConfig { + keystore: None, + session_cache_lru_size: DISPUTE_WINDOW.into(), + }); + let mut wakeups = Wakeups::default(); + let mut currently_checking_set = CurrentlyCheckingSet::default(); + let mut approvals_cache = lru::LruCache::new(APPROVAL_CACHE_SIZE); + + let mut last_finalized_height: Option = { + let (tx, rx) = oneshot::channel(); + ctx.send_message(ChainApiMessage::FinalizedBlockNumber(tx)).await; + match rx.await? { + Ok(number) => Some(number), + Err(err) => { + gum::warn!(target: LOG_TARGET, ?err, "Failed fetching finalized number"); + None + }, + } + }; + + loop { + let mut overlayed_db = OverlayedBackend::new(&backend); + let actions = futures::select! { + (_tick, woken_block, woken_candidate) = wakeups.next(&*state.clock).fuse() => { + subsystem.metrics.on_wakeup(); + process_wakeup( + &mut ctx, + &state, + &mut overlayed_db, + &mut session_info_provider, + woken_block, + woken_candidate, + &subsystem.metrics, + ).await? + } + next_msg = ctx.recv().fuse() => { + let mut actions = handle_from_overseer( + &mut ctx, + &mut state, + &mut overlayed_db, + &mut session_info_provider, + &subsystem.metrics, + next_msg?, + &mut last_finalized_height, + &mut wakeups, + ).await?; + + if let Mode::Syncing(ref mut oracle) = subsystem.mode { + if !oracle.is_major_syncing() { + // note that we're active before processing other actions. + actions.insert(0, Action::BecomeActive) + } + } + + actions + } + approval_state = currently_checking_set.next(&mut approvals_cache).fuse() => { + let mut actions = Vec::new(); + let ( + relay_block_hashes, + ApprovalState { + validator_index, + candidate_hash, + approval_outcome, + } + ) = approval_state; + + if matches!(approval_outcome, ApprovalOutcome::Approved) { + let mut approvals: Vec = relay_block_hashes + .into_iter() + .map(|block_hash| + Action::IssueApproval( + candidate_hash, + ApprovalVoteRequest { + validator_index, + block_hash, + }, + ) + ) + .collect(); + actions.append(&mut approvals); + } + + actions + } + }; + + if handle_actions( + &mut ctx, + &state, + &mut overlayed_db, + &mut session_info_provider, + &subsystem.metrics, + &mut wakeups, + &mut currently_checking_set, + &mut approvals_cache, + &mut subsystem.mode, + actions, + ) + .await? + { + break + } + + if !overlayed_db.is_empty() { + let _timer = subsystem.metrics.time_db_transaction(); + let ops = overlayed_db.into_write_ops(); + backend.write(ops)?; + } + } + + Ok(()) +} + +// Handle actions is a function that accepts a set of instructions +// and subsequently updates the underlying approvals_db in accordance +// with the linear set of instructions passed in. Therefore, actions +// must be processed in series to ensure that earlier actions are not +// negated/corrupted by later actions being executed out-of-order. +// +// However, certain Actions can cause additional actions to need to be +// processed by this function. In order to preserve linearity, we would +// need to handle these newly generated actions before we finalize +// completing additional actions in the submitted sequence of actions. +// +// Since recursive async functions are not not stable yet, we are +// forced to modify the actions iterator on the fly whenever a new set +// of actions are generated by handling a single action. +// +// This particular problem statement is specified in issue 3311: +// https://github.com/paritytech/polkadot/issues/3311 +// +// returns `true` if any of the actions was a `Conclude` command. +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +async fn handle_actions( + ctx: &mut Context, + state: &State, + overlayed_db: &mut OverlayedBackend<'_, impl Backend>, + session_info_provider: &mut RuntimeInfo, + metrics: &Metrics, + wakeups: &mut Wakeups, + currently_checking_set: &mut CurrentlyCheckingSet, + approvals_cache: &mut lru::LruCache, + mode: &mut Mode, + actions: Vec, +) -> SubsystemResult { + let mut conclude = false; + let mut actions_iter = actions.into_iter(); + while let Some(action) = actions_iter.next() { + match action { + Action::ScheduleWakeup { block_hash, block_number, candidate_hash, tick } => { + wakeups.schedule(block_hash, block_number, candidate_hash, tick); + }, + Action::IssueApproval(candidate_hash, approval_request) => { + // Note that the IssueApproval action will create additional + // actions that will need to all be processed before we can + // handle the next action in the set passed to the ambient + // function. + // + // In order to achieve this, we append the existing iterator + // to the end of the iterator made up of these newly generated + // actions. + // + // Note that chaining these iterators is O(n) as we must consume + // the prior iterator. + let next_actions: Vec = issue_approval( + ctx, + state, + overlayed_db, + session_info_provider, + metrics, + candidate_hash, + approval_request, + ) + .await? + .into_iter() + .map(|v| v.clone()) + .chain(actions_iter) + .collect(); + + actions_iter = next_actions.into_iter(); + }, + Action::LaunchApproval { + candidate_hash, + indirect_cert, + assignment_tranche, + relay_block_hash, + candidate_index, + session, + candidate, + backing_group, + } => { + // Don't launch approval work if the node is syncing. + if let Mode::Syncing(_) = *mode { + continue + } + + let mut launch_approval_span = state + .spans + .get(&relay_block_hash) + .map(|span| span.child("launch-approval")) + .unwrap_or_else(|| jaeger::Span::new(candidate_hash, "launch-approval")) + .with_trace_id(candidate_hash) + .with_candidate(candidate_hash) + .with_stage(jaeger::Stage::ApprovalChecking); + + metrics.on_assignment_produced(assignment_tranche); + let block_hash = indirect_cert.block_hash; + launch_approval_span.add_string_tag("block-hash", format!("{:?}", block_hash)); + let validator_index = indirect_cert.validator; + + ctx.send_unbounded_message(ApprovalDistributionMessage::DistributeAssignment( + indirect_cert, + candidate_index, + )); + + match approvals_cache.get(&candidate_hash) { + Some(ApprovalOutcome::Approved) => { + let new_actions: Vec = std::iter::once(Action::IssueApproval( + candidate_hash, + ApprovalVoteRequest { validator_index, block_hash }, + )) + .map(|v| v.clone()) + .chain(actions_iter) + .collect(); + actions_iter = new_actions.into_iter(); + }, + None => { + let ctx = &mut *ctx; + currently_checking_set + .insert_relay_block_hash( + candidate_hash, + validator_index, + relay_block_hash, + async move { + launch_approval( + ctx, + metrics.clone(), + session, + candidate, + validator_index, + block_hash, + backing_group, + &launch_approval_span, + ) + .await + }, + ) + .await?; + }, + Some(_) => {}, + } + }, + Action::NoteApprovedInChainSelection(block_hash) => { + let _span = state + .spans + .get(&block_hash) + .map(|span| span.child("note-approved-in-chain-selection")) + .unwrap_or_else(|| { + jaeger::Span::new(block_hash, "note-approved-in-chain-selection") + }) + .with_string_tag("block-hash", format!("{:?}", block_hash)) + .with_stage(jaeger::Stage::ApprovalChecking); + ctx.send_message(ChainSelectionMessage::Approved(block_hash)).await; + }, + Action::BecomeActive => { + *mode = Mode::Active; + + let messages = distribution_messages_for_activation(overlayed_db, state)?; + + ctx.send_messages(messages.into_iter()).await; + }, + Action::Conclude => { + conclude = true; + }, + } + } + + Ok(conclude) +} + +fn distribution_messages_for_activation( + db: &OverlayedBackend<'_, impl Backend>, + state: &State, +) -> SubsystemResult> { + let all_blocks: Vec = db.load_all_blocks()?; + + let mut approval_meta = Vec::with_capacity(all_blocks.len()); + let mut messages = Vec::new(); + + messages.push(ApprovalDistributionMessage::NewBlocks(Vec::new())); // dummy value. + + for block_hash in all_blocks { + let mut distribution_message_span = state + .spans + .get(&block_hash) + .map(|span| span.child("distribution-messages-for-activation")) + .unwrap_or_else(|| { + jaeger::Span::new(block_hash, "distribution-messages-for-activation") + }) + .with_stage(jaeger::Stage::ApprovalChecking) + .with_string_tag("block-hash", format!("{:?}", block_hash)); + let block_entry = match db.load_block_entry(&block_hash)? { + Some(b) => b, + None => { + gum::warn!(target: LOG_TARGET, ?block_hash, "Missing block entry"); + + continue + }, + }; + + distribution_message_span.add_string_tag("block-hash", &block_hash.to_string()); + distribution_message_span + .add_string_tag("parent-hash", &block_entry.parent_hash().to_string()); + approval_meta.push(BlockApprovalMeta { + hash: block_hash, + number: block_entry.block_number(), + parent_hash: block_entry.parent_hash(), + candidates: block_entry.candidates().iter().map(|(_, c_hash)| *c_hash).collect(), + slot: block_entry.slot(), + session: block_entry.session(), + }); + + for (i, (_, candidate_hash)) in block_entry.candidates().iter().enumerate() { + let _candidate_span = + distribution_message_span.child("candidate").with_candidate(*candidate_hash); + let candidate_entry = match db.load_candidate_entry(&candidate_hash)? { + Some(c) => c, + None => { + gum::warn!( + target: LOG_TARGET, + ?block_hash, + ?candidate_hash, + "Missing candidate entry", + ); + + continue + }, + }; + + match candidate_entry.approval_entry(&block_hash) { + Some(approval_entry) => { + match approval_entry.local_statements() { + (None, None) | (None, Some(_)) => {}, // second is impossible case. + (Some(assignment), None) => { + messages.push(ApprovalDistributionMessage::DistributeAssignment( + IndirectAssignmentCert { + block_hash, + validator: assignment.validator_index(), + cert: assignment.cert().clone(), + }, + i as _, + )); + }, + (Some(assignment), Some(approval_sig)) => { + messages.push(ApprovalDistributionMessage::DistributeAssignment( + IndirectAssignmentCert { + block_hash, + validator: assignment.validator_index(), + cert: assignment.cert().clone(), + }, + i as _, + )); + + messages.push(ApprovalDistributionMessage::DistributeApproval( + IndirectSignedApprovalVote { + block_hash, + candidate_index: i as _, + validator: assignment.validator_index(), + signature: approval_sig, + }, + )) + }, + } + }, + None => { + gum::warn!( + target: LOG_TARGET, + ?block_hash, + ?candidate_hash, + "Missing approval entry", + ); + }, + } + } + } + + messages[0] = ApprovalDistributionMessage::NewBlocks(approval_meta); + Ok(messages) +} + +// Handle an incoming signal from the overseer. Returns true if execution should conclude. +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +async fn handle_from_overseer( + ctx: &mut Context, + state: &mut State, + db: &mut OverlayedBackend<'_, impl Backend>, + session_info_provider: &mut RuntimeInfo, + metrics: &Metrics, + x: FromOrchestra, + last_finalized_height: &mut Option, + wakeups: &mut Wakeups, +) -> SubsystemResult> { + let actions = match x { + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => { + let mut actions = Vec::new(); + if let Some(activated) = update.activated { + let head = activated.hash; + let approval_voting_span = + jaeger::PerLeafSpan::new(activated.span, "approval-voting"); + state.spans.insert(head, approval_voting_span); + match import::handle_new_head( + ctx, + state, + db, + session_info_provider, + head, + last_finalized_height, + ) + .await + { + Err(e) => return Err(SubsystemError::with_origin("db", e)), + Ok(block_imported_candidates) => { + // Schedule wakeups for all imported candidates. + for block_batch in block_imported_candidates { + gum::debug!( + target: LOG_TARGET, + block_number = ?block_batch.block_number, + block_hash = ?block_batch.block_hash, + num_candidates = block_batch.imported_candidates.len(), + "Imported new block.", + ); + + for (c_hash, c_entry) in block_batch.imported_candidates { + metrics.on_candidate_imported(); + + let our_tranche = c_entry + .approval_entry(&block_batch.block_hash) + .and_then(|a| a.our_assignment().map(|a| a.tranche())); + + if let Some(our_tranche) = our_tranche { + let tick = our_tranche as Tick + block_batch.block_tick; + gum::trace!( + target: LOG_TARGET, + tranche = our_tranche, + candidate_hash = ?c_hash, + block_hash = ?block_batch.block_hash, + block_tick = block_batch.block_tick, + "Scheduling first wakeup.", + ); + + // Our first wakeup will just be the tranche of our assignment, + // if any. This will likely be superseded by incoming + // assignments and approvals which trigger rescheduling. + actions.push(Action::ScheduleWakeup { + block_hash: block_batch.block_hash, + block_number: block_batch.block_number, + candidate_hash: c_hash, + tick, + }); + } + } + } + }, + } + } + + actions + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(block_hash, block_number)) => { + gum::debug!(target: LOG_TARGET, ?block_hash, ?block_number, "Block finalized"); + *last_finalized_height = Some(block_number); + + crate::ops::canonicalize(db, block_number, block_hash) + .map_err(|e| SubsystemError::with_origin("db", e))?; + + // `prune_finalized_wakeups` prunes all finalized block hashes. We prune spans + // accordingly. + wakeups.prune_finalized_wakeups(block_number, &mut state.spans); + + // // `prune_finalized_wakeups` prunes all finalized block hashes. We prune spans + // accordingly. let hash_set = + // wakeups.block_numbers.values().flatten().collect::>(); state.spans. + // retain(|hash, _| hash_set.contains(hash)); + + Vec::new() + }, + FromOrchestra::Signal(OverseerSignal::Conclude) => { + vec![Action::Conclude] + }, + FromOrchestra::Communication { msg } => match msg { + ApprovalVotingMessage::CheckAndImportAssignment(a, claimed_core, res) => { + let (check_outcome, actions) = check_and_import_assignment( + ctx.sender(), + state, + db, + session_info_provider, + a, + claimed_core, + ) + .await?; + let _ = res.send(check_outcome); + + actions + }, + ApprovalVotingMessage::CheckAndImportApproval(a, res) => + check_and_import_approval( + ctx.sender(), + state, + db, + session_info_provider, + metrics, + a, + |r| { + let _ = res.send(r); + }, + ) + .await? + .0, + ApprovalVotingMessage::ApprovedAncestor(target, lower_bound, res) => { + let mut approved_ancestor_span = state + .spans + .get(&target) + .map(|span| span.child("approved-ancestor")) + .unwrap_or_else(|| jaeger::Span::new(target, "approved-ancestor")) + .with_stage(jaeger::Stage::ApprovalChecking) + .with_string_tag("leaf", format!("{:?}", target)); + match handle_approved_ancestor( + ctx, + db, + target, + lower_bound, + wakeups, + &mut approved_ancestor_span, + &metrics, + ) + .await + { + Ok(v) => { + let _ = res.send(v); + }, + Err(e) => { + let _ = res.send(None); + return Err(e) + }, + } + + Vec::new() + }, + ApprovalVotingMessage::GetApprovalSignaturesForCandidate(candidate_hash, tx) => { + metrics.on_candidate_signatures_request(); + get_approval_signatures_for_candidate(ctx, db, candidate_hash, tx).await?; + Vec::new() + }, + }, + }; + + Ok(actions) +} + +/// Retrieve approval signatures. +/// +/// This involves an unbounded message send to approval-distribution, the caller has to ensure that +/// calls to this function are infrequent and bounded. +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +async fn get_approval_signatures_for_candidate( + ctx: &mut Context, + db: &OverlayedBackend<'_, impl Backend>, + candidate_hash: CandidateHash, + tx: oneshot::Sender>, +) -> SubsystemResult<()> { + let send_votes = |votes| { + if let Err(_) = tx.send(votes) { + gum::debug!( + target: LOG_TARGET, + "Sending approval signatures back failed, as receiver got closed." + ); + } + }; + let entry = match db.load_candidate_entry(&candidate_hash)? { + None => { + send_votes(HashMap::new()); + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + "Sent back empty votes because the candidate was not found in db." + ); + return Ok(()) + }, + Some(e) => e, + }; + + let relay_hashes = entry.block_assignments.keys(); + + let mut candidate_indices = HashSet::new(); + // Retrieve `CoreIndices`/`CandidateIndices` as required by approval-distribution: + for hash in relay_hashes { + let entry = match db.load_block_entry(hash)? { + None => { + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + ?hash, + "Block entry for assignment missing." + ); + continue + }, + Some(e) => e, + }; + for (candidate_index, (_core_index, c_hash)) in entry.candidates().iter().enumerate() { + if c_hash == &candidate_hash { + candidate_indices.insert((*hash, candidate_index as u32)); + break + } + } + } + + let mut sender = ctx.sender().clone(); + let get_approvals = async move { + let (tx_distribution, rx_distribution) = oneshot::channel(); + sender.send_unbounded_message(ApprovalDistributionMessage::GetApprovalSignatures( + candidate_indices, + tx_distribution, + )); + + // Because of the unbounded sending and the nature of the call (just fetching data from + // state), this should not block long: + match rx_distribution.timeout(WAIT_FOR_SIGS_TIMEOUT).await { + None => { + gum::warn!( + target: LOG_TARGET, + "Waiting for approval signatures timed out - dead lock?" + ); + }, + Some(Err(_)) => gum::debug!( + target: LOG_TARGET, + "Request for approval signatures got cancelled by `approval-distribution`." + ), + Some(Ok(votes)) => send_votes(votes), + } + }; + + // No need to block subsystem on this (also required to break cycle). + // We should not be sending this message frequently - caller must make sure this is bounded. + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + "Spawning task for fetching sinatures from approval-distribution" + ); + ctx.spawn("get-approval-signatures", Box::pin(get_approvals)) +} + +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +async fn handle_approved_ancestor( + ctx: &mut Context, + db: &OverlayedBackend<'_, impl Backend>, + target: Hash, + lower_bound: BlockNumber, + wakeups: &Wakeups, + span: &mut jaeger::Span, + metrics: &Metrics, +) -> SubsystemResult> { + const MAX_TRACING_WINDOW: usize = 200; + const ABNORMAL_DEPTH_THRESHOLD: usize = 5; + const LOGGING_DEPTH_THRESHOLD: usize = 10; + let mut span = span + .child("handle-approved-ancestor") + .with_stage(jaeger::Stage::ApprovalChecking); + use bitvec::{order::Lsb0, vec::BitVec}; + + let mut all_approved_max = None; + + let target_number = { + let (tx, rx) = oneshot::channel(); + + ctx.send_message(ChainApiMessage::BlockNumber(target, tx)).await; + + match rx.await { + Ok(Ok(Some(n))) => n, + Ok(Ok(None)) => return Ok(None), + Ok(Err(_)) | Err(_) => return Ok(None), + } + }; + + span.add_uint_tag("leaf-number", target_number as u64); + span.add_uint_tag("lower-bound", lower_bound as u64); + if target_number <= lower_bound { + return Ok(None) + } + + // request ancestors up to but not including the lower bound, + // as a vote on the lower bound is implied if we cannot find + // anything else. + let ancestry = if target_number > lower_bound + 1 { + let (tx, rx) = oneshot::channel(); + + ctx.send_message(ChainApiMessage::Ancestors { + hash: target, + k: (target_number - (lower_bound + 1)) as usize, + response_channel: tx, + }) + .await; + + match rx.await { + Ok(Ok(a)) => a, + Err(_) | Ok(Err(_)) => return Ok(None), + } + } else { + Vec::new() + }; + let ancestry_len = ancestry.len(); + + let mut block_descriptions = Vec::new(); + + let mut bits: BitVec = Default::default(); + for (i, block_hash) in std::iter::once(target).chain(ancestry).enumerate() { + let mut entry_span = + span.child("load-block-entry").with_stage(jaeger::Stage::ApprovalChecking); + entry_span.add_string_tag("block-hash", format!("{:?}", block_hash)); + // Block entries should be present as the assumption is that + // nothing here is finalized. If we encounter any missing block + // entries we can fail. + let entry = match db.load_block_entry(&block_hash)? { + None => { + let block_number = target_number.saturating_sub(i as u32); + gum::info!( + target: LOG_TARGET, + unknown_number = ?block_number, + unknown_hash = ?block_hash, + "Chain between ({}, {}) and {} not fully known. Forcing vote on {}", + target, + target_number, + lower_bound, + lower_bound, + ); + return Ok(None) + }, + Some(b) => b, + }; + + // even if traversing millions of blocks this is fairly cheap and always dwarfed by the + // disk lookups. + bits.push(entry.is_fully_approved()); + if entry.is_fully_approved() { + if all_approved_max.is_none() { + // First iteration of the loop is target, i = 0. After that, + // ancestry is moving backwards. + all_approved_max = Some((block_hash, target_number - i as BlockNumber)); + } + block_descriptions.push(BlockDescription { + block_hash, + session: entry.session(), + candidates: entry + .candidates() + .iter() + .map(|(_idx, candidate_hash)| *candidate_hash) + .collect(), + }); + } else if bits.len() <= ABNORMAL_DEPTH_THRESHOLD { + all_approved_max = None; + block_descriptions.clear(); + } else { + all_approved_max = None; + block_descriptions.clear(); + + let unapproved: Vec<_> = entry.unapproved_candidates().collect(); + gum::debug!( + target: LOG_TARGET, + "Block {} is {} blocks deep and has {}/{} candidates unapproved", + block_hash, + bits.len() - 1, + unapproved.len(), + entry.candidates().len(), + ); + if ancestry_len >= LOGGING_DEPTH_THRESHOLD && i > ancestry_len - LOGGING_DEPTH_THRESHOLD + { + gum::trace!( + target: LOG_TARGET, + ?block_hash, + "Unapproved candidates at depth {}: {:?}", + bits.len(), + unapproved + ) + } + metrics.on_unapproved_candidates_in_unfinalized_chain(unapproved.len()); + entry_span.add_uint_tag("unapproved-candidates", unapproved.len() as u64); + for candidate_hash in unapproved { + match db.load_candidate_entry(&candidate_hash)? { + None => { + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + "Missing expected candidate in DB", + ); + + continue + }, + Some(c_entry) => match c_entry.approval_entry(&block_hash) { + None => { + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + ?block_hash, + "Missing expected approval entry under candidate.", + ); + }, + Some(a_entry) => { + let status = || { + let n_assignments = a_entry.n_assignments(); + + // Take the approvals, filtered by the assignments + // for this block. + let n_approvals = c_entry + .approvals() + .iter() + .by_vals() + .enumerate() + .filter(|(i, approved)| { + *approved && a_entry.is_assigned(ValidatorIndex(*i as _)) + }) + .count(); + + format!( + "{}/{}/{}", + n_assignments, + n_approvals, + a_entry.n_validators(), + ) + }; + + match a_entry.our_assignment() { + None => gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + ?block_hash, + status = %status(), + "no assignment." + ), + Some(a) => { + let tranche = a.tranche(); + let triggered = a.triggered(); + + let next_wakeup = + wakeups.wakeup_for(block_hash, candidate_hash); + + let approved = + triggered && { a_entry.local_statements().1.is_some() }; + + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + ?block_hash, + tranche, + ?next_wakeup, + status = %status(), + triggered, + approved, + "assigned." + ); + }, + } + }, + }, + } + } + } + } + + gum::debug!( + target: LOG_TARGET, + "approved blocks {}-[{}]-{}", + target_number, + { + // formatting to divide bits by groups of 10. + // when comparing logs on multiple machines where the exact vote + // targets may differ, this grouping is useful. + let mut s = String::with_capacity(bits.len()); + for (i, bit) in bits.iter().enumerate().take(MAX_TRACING_WINDOW) { + s.push(if *bit { '1' } else { '0' }); + if (target_number - i as u32) % 10 == 0 && i != bits.len() - 1 { + s.push(' '); + } + } + + s + }, + if bits.len() > MAX_TRACING_WINDOW { + format!( + "{}... (truncated due to large window)", + target_number - MAX_TRACING_WINDOW as u32 + 1, + ) + } else { + format!("{}", lower_bound + 1) + }, + ); + + // `reverse()` to obtain the ascending order from lowest to highest + // block within the candidates, which is the expected order + block_descriptions.reverse(); + + let all_approved_max = + all_approved_max.map(|(hash, block_number)| HighestApprovedAncestorBlock { + hash, + number: block_number, + descriptions: block_descriptions, + }); + match all_approved_max { + Some(HighestApprovedAncestorBlock { ref hash, ref number, .. }) => { + span.add_uint_tag("highest-approved-number", *number as u64); + span.add_string_fmt_debug_tag("highest-approved-hash", hash); + }, + None => { + span.add_string_tag("reached-lower-bound", "true"); + }, + } + + Ok(all_approved_max) +} + +// `Option::cmp` treats `None` as less than `Some`. +fn min_prefer_some(a: Option, b: Option) -> Option { + match (a, b) { + (None, None) => None, + (None, Some(x)) | (Some(x), None) => Some(x), + (Some(x), Some(y)) => Some(std::cmp::min(x, y)), + } +} + +fn schedule_wakeup_action( + approval_entry: &ApprovalEntry, + block_hash: Hash, + block_number: BlockNumber, + candidate_hash: CandidateHash, + block_tick: Tick, + tick_now: Tick, + required_tranches: RequiredTranches, +) -> Option { + let maybe_action = match required_tranches { + _ if approval_entry.is_approved() => None, + RequiredTranches::All => None, + RequiredTranches::Exact { next_no_show, last_assignment_tick, .. } => { + // Take the earlier of the next no show or the last assignment tick + required delay, + // only considering the latter if it is after the current moment. + min_prefer_some( + last_assignment_tick.map(|l| l + APPROVAL_DELAY).filter(|t| t > &tick_now), + next_no_show, + ) + .map(|tick| Action::ScheduleWakeup { block_hash, block_number, candidate_hash, tick }) + }, + RequiredTranches::Pending { considered, next_no_show, clock_drift, .. } => { + // select the minimum of `next_no_show`, or the tick of the next non-empty tranche + // after `considered`, including any tranche that might contain our own untriggered + // assignment. + let next_non_empty_tranche = { + let next_announced = approval_entry + .tranches() + .iter() + .skip_while(|t| t.tranche() <= considered) + .map(|t| t.tranche()) + .next(); + + let our_untriggered = approval_entry.our_assignment().and_then(|t| { + if !t.triggered() && t.tranche() > considered { + Some(t.tranche()) + } else { + None + } + }); + + // Apply the clock drift to these tranches. + min_prefer_some(next_announced, our_untriggered) + .map(|t| t as Tick + block_tick + clock_drift) + }; + + min_prefer_some(next_non_empty_tranche, next_no_show).map(|tick| { + Action::ScheduleWakeup { block_hash, block_number, candidate_hash, tick } + }) + }, + }; + + match maybe_action { + Some(Action::ScheduleWakeup { ref tick, .. }) => gum::trace!( + target: LOG_TARGET, + tick, + ?candidate_hash, + ?block_hash, + block_tick, + "Scheduling next wakeup.", + ), + None => gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?block_hash, + block_tick, + "No wakeup needed.", + ), + Some(_) => {}, // unreachable + } + + maybe_action +} + +async fn check_and_import_assignment( + sender: &mut Sender, + state: &State, + db: &mut OverlayedBackend<'_, impl Backend>, + session_info_provider: &mut RuntimeInfo, + assignment: IndirectAssignmentCert, + candidate_index: CandidateIndex, +) -> SubsystemResult<(AssignmentCheckResult, Vec)> +where + Sender: SubsystemSender, +{ + let tick_now = state.clock.tick_now(); + + let mut check_and_import_assignment_span = state + .spans + .get(&assignment.block_hash) + .map(|span| span.child("check-and-import-assignment")) + .unwrap_or_else(|| jaeger::Span::new(assignment.block_hash, "check-and-import-assignment")) + .with_relay_parent(assignment.block_hash) + .with_uint_tag("candidate-index", candidate_index as u64) + .with_stage(jaeger::Stage::ApprovalChecking); + + let block_entry = match db.load_block_entry(&assignment.block_hash)? { + Some(b) => b, + None => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::UnknownBlock( + assignment.block_hash, + )), + Vec::new(), + )), + }; + + let session_info = match get_session_info( + session_info_provider, + sender, + block_entry.parent_hash(), + block_entry.session(), + ) + .await + { + Some(s) => s, + None => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::UnknownSessionIndex( + block_entry.session(), + )), + Vec::new(), + )), + }; + + let (claimed_core_index, assigned_candidate_hash) = + match block_entry.candidate(candidate_index as usize) { + Some((c, h)) => (*c, *h), + None => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidateIndex( + candidate_index, + )), + Vec::new(), + )), // no candidate at core. + }; + + check_and_import_assignment_span + .add_string_tag("candidate-hash", format!("{:?}", assigned_candidate_hash)); + check_and_import_assignment_span.add_string_tag( + "traceID", + format!("{:?}", jaeger::hash_to_trace_identifier(assigned_candidate_hash.0)), + ); + + let mut candidate_entry = match db.load_candidate_entry(&assigned_candidate_hash)? { + Some(c) => c, + None => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidate( + candidate_index, + assigned_candidate_hash, + )), + Vec::new(), + )), + }; + + let res = { + // import the assignment. + let approval_entry = match candidate_entry.approval_entry_mut(&assignment.block_hash) { + Some(a) => a, + None => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::Internal( + assignment.block_hash, + assigned_candidate_hash, + )), + Vec::new(), + )), + }; + + let res = state.assignment_criteria.check_assignment_cert( + claimed_core_index, + assignment.validator, + &criteria::Config::from(session_info), + block_entry.relay_vrf_story(), + &assignment.cert, + approval_entry.backing_group(), + ); + + let tranche = match res { + Err(crate::criteria::InvalidAssignment(reason)) => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCert( + assignment.validator, + format!("{:?}", reason), + )), + Vec::new(), + )), + Ok(tranche) => { + let current_tranche = + state.clock.tranche_now(state.slot_duration_millis, block_entry.slot()); + + let too_far_in_future = current_tranche + TICK_TOO_FAR_IN_FUTURE as DelayTranche; + + if tranche >= too_far_in_future { + return Ok((AssignmentCheckResult::TooFarInFuture, Vec::new())) + } + + tranche + }, + }; + + check_and_import_assignment_span.add_uint_tag("tranche", tranche as u64); + + let is_duplicate = approval_entry.is_assigned(assignment.validator); + approval_entry.import_assignment(tranche, assignment.validator, tick_now); + + if is_duplicate { + AssignmentCheckResult::AcceptedDuplicate + } else { + gum::trace!( + target: LOG_TARGET, + validator = assignment.validator.0, + candidate_hash = ?assigned_candidate_hash, + para_id = ?candidate_entry.candidate_receipt().descriptor.para_id, + "Imported assignment.", + ); + + AssignmentCheckResult::Accepted + } + }; + + let mut actions = Vec::new(); + + // We've imported a new approval, so we need to schedule a wake-up for when that might no-show. + if let Some((approval_entry, status)) = state + .approval_status(sender, session_info_provider, &block_entry, &candidate_entry) + .await + { + actions.extend(schedule_wakeup_action( + approval_entry, + block_entry.block_hash(), + block_entry.block_number(), + assigned_candidate_hash, + status.block_tick, + tick_now, + status.required_tranches, + )); + } + + // We also write the candidate entry as it now contains the new candidate. + db.write_candidate_entry(candidate_entry.into()); + + Ok((res, actions)) +} + +async fn check_and_import_approval( + sender: &mut Sender, + state: &State, + db: &mut OverlayedBackend<'_, impl Backend>, + session_info_provider: &mut RuntimeInfo, + metrics: &Metrics, + approval: IndirectSignedApprovalVote, + with_response: impl FnOnce(ApprovalCheckResult) -> T, +) -> SubsystemResult<(Vec, T)> +where + Sender: SubsystemSender, +{ + macro_rules! respond_early { + ($e: expr) => {{ + let t = with_response($e); + return Ok((Vec::new(), t)) + }}; + } + + let mut span = state + .spans + .get(&approval.block_hash) + .map(|span| span.child("check-and-import-approval")) + .unwrap_or_else(|| jaeger::Span::new(approval.block_hash, "check-and-import-approval")) + .with_uint_tag("candidate-index", approval.candidate_index as u64) + .with_relay_parent(approval.block_hash) + .with_stage(jaeger::Stage::ApprovalChecking); + + let block_entry = match db.load_block_entry(&approval.block_hash)? { + Some(b) => b, + None => { + respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::UnknownBlock( + approval.block_hash + ),)) + }, + }; + + let session_info = match get_session_info( + session_info_provider, + sender, + approval.block_hash, + block_entry.session(), + ) + .await + { + Some(s) => s, + None => { + respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::UnknownSessionIndex( + block_entry.session() + ),)) + }, + }; + + let approved_candidate_hash = match block_entry.candidate(approval.candidate_index as usize) { + Some((_, h)) => *h, + None => respond_early!(ApprovalCheckResult::Bad( + ApprovalCheckError::InvalidCandidateIndex(approval.candidate_index), + )), + }; + + span.add_string_tag("candidate-hash", format!("{:?}", approved_candidate_hash)); + span.add_string_tag( + "traceID", + format!("{:?}", hash_to_trace_identifier(approved_candidate_hash.0)), + ); + + let pubkey = match session_info.validators.get(approval.validator) { + Some(k) => k, + None => respond_early!(ApprovalCheckResult::Bad( + ApprovalCheckError::InvalidValidatorIndex(approval.validator), + )), + }; + + // Signature check: + match DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking).check_signature( + &pubkey, + approved_candidate_hash, + block_entry.session(), + &approval.signature, + ) { + Err(_) => respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::InvalidSignature( + approval.validator + ),)), + Ok(()) => {}, + }; + + let candidate_entry = match db.load_candidate_entry(&approved_candidate_hash)? { + Some(c) => c, + None => { + respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::InvalidCandidate( + approval.candidate_index, + approved_candidate_hash + ),)) + }, + }; + + // Don't accept approvals until assignment. + match candidate_entry.approval_entry(&approval.block_hash) { + None => { + respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::Internal( + approval.block_hash, + approved_candidate_hash + ),)) + }, + Some(e) if !e.is_assigned(approval.validator) => { + respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::NoAssignment( + approval.validator + ),)) + }, + _ => {}, + } + + // importing the approval can be heavy as it may trigger acceptance for a series of blocks. + let t = with_response(ApprovalCheckResult::Accepted); + + gum::trace!( + target: LOG_TARGET, + validator_index = approval.validator.0, + validator = ?pubkey, + candidate_hash = ?approved_candidate_hash, + para_id = ?candidate_entry.candidate_receipt().descriptor.para_id, + "Importing approval vote", + ); + + let actions = advance_approval_state( + sender, + state, + db, + session_info_provider, + &metrics, + block_entry, + approved_candidate_hash, + candidate_entry, + ApprovalStateTransition::RemoteApproval(approval.validator), + ) + .await; + + Ok((actions, t)) +} + +#[derive(Debug)] +enum ApprovalStateTransition { + RemoteApproval(ValidatorIndex), + LocalApproval(ValidatorIndex, ValidatorSignature), + WakeupProcessed, +} + +impl ApprovalStateTransition { + fn validator_index(&self) -> Option { + match *self { + ApprovalStateTransition::RemoteApproval(v) | + ApprovalStateTransition::LocalApproval(v, _) => Some(v), + ApprovalStateTransition::WakeupProcessed => None, + } + } + + fn is_local_approval(&self) -> bool { + match *self { + ApprovalStateTransition::RemoteApproval(_) => false, + ApprovalStateTransition::LocalApproval(_, _) => true, + ApprovalStateTransition::WakeupProcessed => false, + } + } +} + +// Advance the approval state, either by importing an approval vote which is already checked to be +// valid and corresponding to an assigned validator on the candidate and block, or by noting that +// there are no further wakeups or tranches needed. This updates the block entry and candidate entry +// as necessary and schedules any further wakeups. +async fn advance_approval_state( + sender: &mut Sender, + state: &State, + db: &mut OverlayedBackend<'_, impl Backend>, + session_info_provider: &mut RuntimeInfo, + metrics: &Metrics, + mut block_entry: BlockEntry, + candidate_hash: CandidateHash, + mut candidate_entry: CandidateEntry, + transition: ApprovalStateTransition, +) -> Vec +where + Sender: SubsystemSender, +{ + let validator_index = transition.validator_index(); + + let already_approved_by = validator_index.as_ref().map(|v| candidate_entry.mark_approval(*v)); + let candidate_approved_in_block = block_entry.is_candidate_approved(&candidate_hash); + + // Check for early exits. + // + // If the candidate was approved + // but not the block, it means that we still need more approvals for the candidate under the + // block. + // + // If the block was approved, but the validator hadn't approved it yet, we should still hold + // onto the approval vote on-disk in case we restart and rebroadcast votes. Otherwise, our + // assignment might manifest as a no-show. + if !transition.is_local_approval() { + // We don't store remote votes and there's nothing to store for processed wakeups, + // so we can early exit as long at the candidate is already concluded under the + // block i.e. we don't need more approvals. + if candidate_approved_in_block { + return Vec::new() + } + } + + let mut actions = Vec::new(); + let block_hash = block_entry.block_hash(); + let block_number = block_entry.block_number(); + + let tick_now = state.clock.tick_now(); + + let (is_approved, status) = if let Some((approval_entry, status)) = state + .approval_status(sender, session_info_provider, &block_entry, &candidate_entry) + .await + { + let check = approval_checking::check_approval( + &candidate_entry, + approval_entry, + status.required_tranches.clone(), + ); + + // Check whether this is approved, while allowing a maximum + // assignment tick of `now - APPROVAL_DELAY` - that is, that + // all counted assignments are at least `APPROVAL_DELAY` ticks old. + let is_approved = check.is_approved(tick_now.saturating_sub(APPROVAL_DELAY)); + + if is_approved { + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?block_hash, + "Candidate approved under block.", + ); + + let no_shows = check.known_no_shows(); + + let was_block_approved = block_entry.is_fully_approved(); + block_entry.mark_approved_by_hash(&candidate_hash); + let is_block_approved = block_entry.is_fully_approved(); + + if no_shows != 0 { + metrics.on_no_shows(no_shows); + } + + metrics.on_candidate_approved(status.tranche_now as _); + + if is_block_approved && !was_block_approved { + metrics.on_block_approved(status.tranche_now as _); + actions.push(Action::NoteApprovedInChainSelection(block_hash)); + } + + db.write_block_entry(block_entry.into()); + } + + (is_approved, status) + } else { + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + ?block_hash, + ?validator_index, + "No approval entry for approval under block", + ); + + return Vec::new() + }; + + { + let approval_entry = candidate_entry + .approval_entry_mut(&block_hash) + .expect("Approval entry just fetched; qed"); + + let was_approved = approval_entry.is_approved(); + let newly_approved = is_approved && !was_approved; + + if is_approved { + approval_entry.mark_approved(); + } + + if let ApprovalStateTransition::LocalApproval(_, ref sig) = transition { + approval_entry.import_approval_sig(sig.clone()); + } + + actions.extend(schedule_wakeup_action( + &approval_entry, + block_hash, + block_number, + candidate_hash, + status.block_tick, + tick_now, + status.required_tranches, + )); + + // We have no need to write the candidate entry if all of the following + // is true: + // + // 1. This is not a local approval, as we don't store anything new in the approval entry. + // 2. The candidate is not newly approved, as we haven't altered the approval entry's + // approved flag with `mark_approved` above. + // 3. The approver, if any, had already approved the candidate, as we haven't altered the + // bitfield. + if transition.is_local_approval() || newly_approved || !already_approved_by.unwrap_or(true) + { + // In all other cases, we need to write the candidate entry. + db.write_candidate_entry(candidate_entry); + } + } + + actions +} + +fn should_trigger_assignment( + approval_entry: &ApprovalEntry, + candidate_entry: &CandidateEntry, + required_tranches: RequiredTranches, + tranche_now: DelayTranche, +) -> bool { + match approval_entry.our_assignment() { + None => false, + Some(ref assignment) if assignment.triggered() => false, + Some(ref assignment) if assignment.tranche() == 0 => true, + Some(ref assignment) => { + match required_tranches { + RequiredTranches::All => !approval_checking::check_approval( + &candidate_entry, + &approval_entry, + RequiredTranches::All, + ) + // when all are required, we are just waiting for the first 1/3+ + .is_approved(Tick::max_value()), + RequiredTranches::Pending { maximum_broadcast, clock_drift, .. } => { + let drifted_tranche_now = + tranche_now.saturating_sub(clock_drift as DelayTranche); + assignment.tranche() <= maximum_broadcast && + assignment.tranche() <= drifted_tranche_now + }, + RequiredTranches::Exact { .. } => { + // indicates that no new assignments are needed at the moment. + false + }, + } + }, + } +} + +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +async fn process_wakeup( + ctx: &mut Context, + state: &State, + db: &mut OverlayedBackend<'_, impl Backend>, + session_info_provider: &mut RuntimeInfo, + relay_block: Hash, + candidate_hash: CandidateHash, + metrics: &Metrics, +) -> SubsystemResult> { + let mut span = state + .spans + .get(&relay_block) + .map(|span| span.child("process-wakeup")) + .unwrap_or_else(|| jaeger::Span::new(candidate_hash, "process-wakeup")) + .with_trace_id(candidate_hash) + .with_relay_parent(relay_block) + .with_candidate(candidate_hash) + .with_stage(jaeger::Stage::ApprovalChecking); + + let block_entry = db.load_block_entry(&relay_block)?; + let candidate_entry = db.load_candidate_entry(&candidate_hash)?; + + // If either is not present, we have nothing to wakeup. Might have lost a race with finality + let (block_entry, mut candidate_entry) = match (block_entry, candidate_entry) { + (Some(b), Some(c)) => (b, c), + _ => return Ok(Vec::new()), + }; + + let session_info = match get_session_info( + session_info_provider, + ctx.sender(), + block_entry.parent_hash(), + block_entry.session(), + ) + .await + { + Some(i) => i, + None => return Ok(Vec::new()), + }; + + let block_tick = slot_number_to_tick(state.slot_duration_millis, block_entry.slot()); + let no_show_duration = slot_number_to_tick( + state.slot_duration_millis, + Slot::from(u64::from(session_info.no_show_slots)), + ); + let tranche_now = state.clock.tranche_now(state.slot_duration_millis, block_entry.slot()); + span.add_uint_tag("tranche", tranche_now as u64); + gum::trace!( + target: LOG_TARGET, + tranche = tranche_now, + ?candidate_hash, + block_hash = ?relay_block, + "Processing wakeup", + ); + + let (should_trigger, backing_group) = { + let approval_entry = match candidate_entry.approval_entry(&relay_block) { + Some(e) => e, + None => return Ok(Vec::new()), + }; + + let tranches_to_approve = approval_checking::tranches_to_approve( + &approval_entry, + candidate_entry.approvals(), + tranche_now, + block_tick, + no_show_duration, + session_info.needed_approvals as _, + ); + + let should_trigger = should_trigger_assignment( + &approval_entry, + &candidate_entry, + tranches_to_approve, + tranche_now, + ); + + (should_trigger, approval_entry.backing_group()) + }; + + gum::trace!(target: LOG_TARGET, "Wakeup processed. Should trigger: {}", should_trigger); + + let mut actions = Vec::new(); + let candidate_receipt = candidate_entry.candidate_receipt().clone(); + + let maybe_cert = if should_trigger { + let maybe_cert = { + let approval_entry = candidate_entry + .approval_entry_mut(&relay_block) + .expect("should_trigger only true if this fetched earlier; qed"); + + approval_entry.trigger_our_assignment(state.clock.tick_now()) + }; + + db.write_candidate_entry(candidate_entry.clone()); + + maybe_cert + } else { + None + }; + + if let Some((cert, val_index, tranche)) = maybe_cert { + let indirect_cert = + IndirectAssignmentCert { block_hash: relay_block, validator: val_index, cert }; + + let index_in_candidate = + block_entry.candidates().iter().position(|(_, h)| &candidate_hash == h); + + if let Some(i) = index_in_candidate { + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + para_id = ?candidate_receipt.descriptor.para_id, + block_hash = ?relay_block, + "Launching approval work.", + ); + + // sanity: should always be present. + actions.push(Action::LaunchApproval { + candidate_hash, + indirect_cert, + assignment_tranche: tranche, + relay_block_hash: relay_block, + candidate_index: i as _, + session: block_entry.session(), + candidate: candidate_receipt, + backing_group, + }); + } + } + // Although we checked approval earlier in this function, + // this wakeup might have advanced the state to approved via + // a no-show that was immediately covered and therefore + // we need to check for that and advance the state on-disk. + // + // Note that this function also schedules a wakeup as necessary. + actions.extend( + advance_approval_state( + ctx.sender(), + state, + db, + session_info_provider, + metrics, + block_entry, + candidate_hash, + candidate_entry, + ApprovalStateTransition::WakeupProcessed, + ) + .await, + ); + + Ok(actions) +} + +// Launch approval work, returning an `AbortHandle` which corresponds to the background task +// spawned. When the background work is no longer needed, the `AbortHandle` should be dropped +// to cancel the background work and any requests it has spawned. +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +async fn launch_approval( + ctx: &mut Context, + metrics: Metrics, + session_index: SessionIndex, + candidate: CandidateReceipt, + validator_index: ValidatorIndex, + block_hash: Hash, + backing_group: GroupIndex, + span: &jaeger::Span, +) -> SubsystemResult> { + let (a_tx, a_rx) = oneshot::channel(); + let (code_tx, code_rx) = oneshot::channel(); + + // The background future returned by this function may + // be dropped before completing. This guard is used to ensure that the approval + // work is correctly counted as stale even if so. + struct StaleGuard(Option); + + impl StaleGuard { + fn take(mut self) -> Metrics { + self.0.take().expect( + " + consumed after take; so this cannot be called twice; \ + nothing in this function reaches into the struct to avoid this API; \ + qed + ", + ) + } + } + + impl Drop for StaleGuard { + fn drop(&mut self) { + if let Some(metrics) = self.0.as_ref() { + metrics.on_approval_stale(); + } + } + } + + let candidate_hash = candidate.hash(); + let para_id = candidate.descriptor.para_id; + gum::trace!(target: LOG_TARGET, ?candidate_hash, ?para_id, "Recovering data."); + + let request_validation_data_span = span + .child("request-validation-data") + .with_trace_id(candidate_hash) + .with_candidate(candidate_hash) + .with_string_tag("block-hash", format!("{:?}", block_hash)) + .with_stage(jaeger::Stage::ApprovalChecking); + + let timer = metrics.time_recover_and_approve(); + ctx.send_message(AvailabilityRecoveryMessage::RecoverAvailableData( + candidate.clone(), + session_index, + Some(backing_group), + a_tx, + )) + .await; + + let request_validation_result_span = span + .child("request-validation-result") + .with_trace_id(candidate_hash) + .with_candidate(candidate_hash) + .with_string_tag("block-hash", format!("{:?}", block_hash)) + .with_stage(jaeger::Stage::ApprovalChecking); + + ctx.send_message(RuntimeApiMessage::Request( + block_hash, + RuntimeApiRequest::ValidationCodeByHash(candidate.descriptor.validation_code_hash, code_tx), + )) + .await; + + let candidate = candidate.clone(); + let metrics_guard = StaleGuard(Some(metrics)); + let mut sender = ctx.sender().clone(); + let background = async move { + // Force the move of the timer into the background task. + let _timer = timer; + + let available_data = match a_rx.await { + Err(_) => return ApprovalState::failed(validator_index, candidate_hash), + Ok(Ok(a)) => a, + Ok(Err(e)) => { + match &e { + &RecoveryError::Unavailable => { + gum::warn!( + target: LOG_TARGET, + ?para_id, + ?candidate_hash, + "Data unavailable for candidate {:?}", + (candidate_hash, candidate.descriptor.para_id), + ); + // do nothing. we'll just be a no-show and that'll cause others to rise up. + metrics_guard.take().on_approval_unavailable(); + }, + &RecoveryError::ChannelClosed => { + gum::warn!( + target: LOG_TARGET, + ?para_id, + ?candidate_hash, + "Channel closed while recovering data for candidate {:?}", + (candidate_hash, candidate.descriptor.para_id), + ); + // do nothing. we'll just be a no-show and that'll cause others to rise up. + metrics_guard.take().on_approval_unavailable(); + }, + &RecoveryError::Invalid => { + gum::warn!( + target: LOG_TARGET, + ?para_id, + ?candidate_hash, + "Data recovery invalid for candidate {:?}", + (candidate_hash, candidate.descriptor.para_id), + ); + issue_local_invalid_statement( + &mut sender, + session_index, + candidate_hash, + candidate.clone(), + ); + metrics_guard.take().on_approval_invalid(); + }, + } + return ApprovalState::failed(validator_index, candidate_hash) + }, + }; + drop(request_validation_data_span); + + let validation_code = match code_rx.await { + Err(_) => return ApprovalState::failed(validator_index, candidate_hash), + Ok(Err(_)) => return ApprovalState::failed(validator_index, candidate_hash), + Ok(Ok(Some(code))) => code, + Ok(Ok(None)) => { + gum::warn!( + target: LOG_TARGET, + "Validation code unavailable for block {:?} in the state of block {:?} (a recent descendant)", + candidate.descriptor.relay_parent, + block_hash, + ); + + // No dispute necessary, as this indicates that the chain is not behaving + // according to expectations. + metrics_guard.take().on_approval_unavailable(); + return ApprovalState::failed(validator_index, candidate_hash) + }, + }; + + let (val_tx, val_rx) = oneshot::channel(); + sender + .send_message(CandidateValidationMessage::ValidateFromExhaustive( + available_data.validation_data, + validation_code, + candidate.clone(), + available_data.pov, + PvfExecTimeoutKind::Approval, + val_tx, + )) + .await; + + match val_rx.await { + Err(_) => return ApprovalState::failed(validator_index, candidate_hash), + Ok(Ok(ValidationResult::Valid(_, _))) => { + // Validation checked out. Issue an approval command. If the underlying service is + // unreachable, then there isn't anything we can do. + + gum::trace!(target: LOG_TARGET, ?candidate_hash, ?para_id, "Candidate Valid"); + + let _ = metrics_guard.take(); + return ApprovalState::approved(validator_index, candidate_hash) + }, + Ok(Ok(ValidationResult::Invalid(reason))) => { + gum::warn!( + target: LOG_TARGET, + ?reason, + ?candidate_hash, + ?para_id, + "Detected invalid candidate as an approval checker.", + ); + + issue_local_invalid_statement( + &mut sender, + session_index, + candidate_hash, + candidate.clone(), + ); + metrics_guard.take().on_approval_invalid(); + return ApprovalState::failed(validator_index, candidate_hash) + }, + Ok(Err(e)) => { + gum::error!( + target: LOG_TARGET, + err = ?e, + ?candidate_hash, + ?para_id, + "Failed to validate candidate due to internal error", + ); + metrics_guard.take().on_approval_error(); + drop(request_validation_result_span); + return ApprovalState::failed(validator_index, candidate_hash) + }, + } + }; + let (background, remote_handle) = background.remote_handle(); + ctx.spawn("approval-checks", Box::pin(background)).map(move |()| remote_handle) +} + +// Issue and import a local approval vote. Should only be invoked after approval checks +// have been done. +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +async fn issue_approval( + ctx: &mut Context, + state: &State, + db: &mut OverlayedBackend<'_, impl Backend>, + session_info_provider: &mut RuntimeInfo, + metrics: &Metrics, + candidate_hash: CandidateHash, + ApprovalVoteRequest { validator_index, block_hash }: ApprovalVoteRequest, +) -> SubsystemResult> { + let mut issue_approval_span = state + .spans + .get(&block_hash) + .map(|span| span.child("issue-approval")) + .unwrap_or_else(|| jaeger::Span::new(block_hash, "issue-approval")) + .with_trace_id(candidate_hash) + .with_string_tag("block-hash", format!("{:?}", block_hash)) + .with_candidate(candidate_hash) + .with_validator_index(validator_index) + .with_stage(jaeger::Stage::ApprovalChecking); + + let block_entry = match db.load_block_entry(&block_hash)? { + Some(b) => b, + None => { + // not a cause for alarm - just lost a race with pruning, most likely. + metrics.on_approval_stale(); + return Ok(Vec::new()) + }, + }; + + let candidate_index = match block_entry.candidates().iter().position(|e| e.1 == candidate_hash) + { + None => { + gum::warn!( + target: LOG_TARGET, + "Candidate hash {} is not present in the block entry's candidates for relay block {}", + candidate_hash, + block_entry.parent_hash(), + ); + + metrics.on_approval_error(); + return Ok(Vec::new()) + }, + Some(idx) => idx, + }; + issue_approval_span.add_int_tag("candidate_index", candidate_index as i64); + + let session_info = match get_session_info( + session_info_provider, + ctx.sender(), + block_entry.parent_hash(), + block_entry.session(), + ) + .await + { + Some(s) => s, + None => { + metrics.on_approval_error(); + return Ok(Vec::new()) + }, + }; + + let candidate_hash = match block_entry.candidate(candidate_index as usize) { + Some((_, h)) => *h, + None => { + gum::warn!( + target: LOG_TARGET, + "Received malformed request to approve out-of-bounds candidate index {} included at block {:?}", + candidate_index, + block_hash, + ); + + metrics.on_approval_error(); + return Ok(Vec::new()) + }, + }; + + let candidate_entry = match db.load_candidate_entry(&candidate_hash)? { + Some(c) => c, + None => { + gum::warn!( + target: LOG_TARGET, + "Missing entry for candidate index {} included at block {:?}", + candidate_index, + block_hash, + ); + + metrics.on_approval_error(); + return Ok(Vec::new()) + }, + }; + + let validator_pubkey = match session_info.validators.get(validator_index) { + Some(p) => p, + None => { + gum::warn!( + target: LOG_TARGET, + "Validator index {} out of bounds in session {}", + validator_index.0, + block_entry.session(), + ); + + metrics.on_approval_error(); + return Ok(Vec::new()) + }, + }; + + let session = block_entry.session(); + let sig = match sign_approval(&state.keystore, &validator_pubkey, candidate_hash, session) { + Some(sig) => sig, + None => { + gum::warn!( + target: LOG_TARGET, + validator_index = ?validator_index, + session, + "Could not issue approval signature. Assignment key present but not validator key?", + ); + + metrics.on_approval_error(); + return Ok(Vec::new()) + }, + }; + + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?block_hash, + validator_index = validator_index.0, + "Issuing approval vote", + ); + + let actions = advance_approval_state( + ctx.sender(), + state, + db, + session_info_provider, + metrics, + block_entry, + candidate_hash, + candidate_entry, + ApprovalStateTransition::LocalApproval(validator_index as _, sig.clone()), + ) + .await; + + metrics.on_approval_produced(); + + // dispatch to approval distribution. + ctx.send_unbounded_message(ApprovalDistributionMessage::DistributeApproval( + IndirectSignedApprovalVote { + block_hash, + candidate_index: candidate_index as _, + validator: validator_index, + signature: sig, + }, + )); + + Ok(actions) +} + +// Sign an approval vote. Fails if the key isn't present in the store. +fn sign_approval( + keystore: &LocalKeystore, + public: &ValidatorId, + candidate_hash: CandidateHash, + session_index: SessionIndex, +) -> Option { + let key = keystore.key_pair::(public).ok().flatten()?; + + let payload = ApprovalVote(candidate_hash).signing_payload(session_index); + + Some(key.sign(&payload[..])) +} + +/// Send `IssueLocalStatement` to dispute-coordinator. +fn issue_local_invalid_statement( + sender: &mut Sender, + session_index: SessionIndex, + candidate_hash: CandidateHash, + candidate: CandidateReceipt, +) where + Sender: overseer::ApprovalVotingSenderTrait, +{ + // We need to send an unbounded message here to break a cycle: + // DisputeCoordinatorMessage::IssueLocalStatement -> + // ApprovalVotingMessage::GetApprovalSignaturesForCandidate. + // + // Use of unbounded _should_ be fine here as raising a dispute should be an + // exceptional event. Even in case of bugs: There can be no more than + // number of slots per block requests every block. Also for sending this + // message a full recovery and validation procedure took place, which takes + // longer than issuing a local statement + import. + sender.send_unbounded_message(DisputeCoordinatorMessage::IssueLocalStatement( + session_index, + candidate_hash, + candidate.clone(), + false, + )); +} diff --git a/polkadot/node/core/approval-voting/src/ops.rs b/polkadot/node/core/approval-voting/src/ops.rs new file mode 100644 index 0000000000000000000000000000000000000000..6f57b2f80e8a47facdc664a874d9ee0879889189 --- /dev/null +++ b/polkadot/node/core/approval-voting/src/ops.rs @@ -0,0 +1,426 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Middleware interface that leverages low-level database operations +//! to provide a clean API for processing block and candidate imports. + +use polkadot_node_subsystem::{SubsystemError, SubsystemResult}; + +use bitvec::order::Lsb0 as BitOrderLsb0; +use polkadot_primitives::{BlockNumber, CandidateHash, CandidateReceipt, GroupIndex, Hash}; + +use std::collections::{hash_map::Entry, BTreeMap, HashMap}; + +use super::{ + approval_db::v1::{OurAssignment, StoredBlockRange}, + backend::{Backend, OverlayedBackend}, + persisted_entries::{ApprovalEntry, BlockEntry, CandidateEntry}, + LOG_TARGET, +}; + +/// Information about a new candidate necessary to instantiate the requisite +/// candidate and approval entries. +#[derive(Clone)] +pub struct NewCandidateInfo { + candidate: CandidateReceipt, + backing_group: GroupIndex, + our_assignment: Option, +} + +impl NewCandidateInfo { + /// Convenience constructor + pub fn new( + candidate: CandidateReceipt, + backing_group: GroupIndex, + our_assignment: Option, + ) -> Self { + Self { candidate, backing_group, our_assignment } + } +} + +fn visit_and_remove_block_entry( + block_hash: Hash, + overlayed_db: &mut OverlayedBackend<'_, impl Backend>, + visited_candidates: &mut HashMap, +) -> SubsystemResult> { + let block_entry = match overlayed_db.load_block_entry(&block_hash)? { + None => return Ok(Vec::new()), + Some(b) => b, + }; + + overlayed_db.delete_block_entry(&block_hash); + for (_, candidate_hash) in block_entry.candidates() { + let candidate = match visited_candidates.entry(*candidate_hash) { + Entry::Occupied(e) => e.into_mut(), + Entry::Vacant(e) => { + e.insert(match overlayed_db.load_candidate_entry(candidate_hash)? { + None => continue, // Should not happen except for corrupt DB + Some(c) => c, + }) + }, + }; + + candidate.block_assignments.remove(&block_hash); + } + + Ok(block_entry.children) +} + +/// Canonicalize some particular block, pruning everything before it and +/// pruning any competing branches at the same height. +pub fn canonicalize( + overlay_db: &mut OverlayedBackend<'_, impl Backend>, + canon_number: BlockNumber, + canon_hash: Hash, +) -> SubsystemResult<()> { + let range = match overlay_db.load_stored_blocks()? { + None => return Ok(()), + Some(range) if range.0 >= canon_number => return Ok(()), + Some(range) => range, + }; + + // Storing all candidates in memory is potentially heavy, but should be fine + // as long as finality doesn't stall for a long while. We could optimize this + // by keeping only the metadata about which blocks reference each candidate. + let mut visited_candidates = HashMap::new(); + + // All the block heights we visited but didn't necessarily delete everything from. + let mut visited_heights = HashMap::new(); + + // First visit everything before the height. + for i in range.0..canon_number { + let at_height = overlay_db.load_blocks_at_height(&i)?; + overlay_db.delete_blocks_at_height(i); + + for b in at_height { + let _ = visit_and_remove_block_entry(b, overlay_db, &mut visited_candidates)?; + } + } + + // Then visit everything at the height. + let pruned_branches = { + let at_height = overlay_db.load_blocks_at_height(&canon_number)?; + overlay_db.delete_blocks_at_height(canon_number); + + // Note that while there may be branches descending from blocks at earlier heights, + // we have already covered them by removing everything at earlier heights. + let mut pruned_branches = Vec::new(); + + for b in at_height { + let children = visit_and_remove_block_entry(b, overlay_db, &mut visited_candidates)?; + + if b != canon_hash { + pruned_branches.extend(children); + } + } + + pruned_branches + }; + + // Follow all children of non-canonicalized blocks. + { + let mut frontier: Vec<(BlockNumber, Hash)> = + pruned_branches.into_iter().map(|h| (canon_number + 1, h)).collect(); + while let Some((height, next_child)) = frontier.pop() { + let children = + visit_and_remove_block_entry(next_child, overlay_db, &mut visited_candidates)?; + + // extend the frontier of branches to include the given height. + frontier.extend(children.into_iter().map(|h| (height + 1, h))); + + // visit the at-height key for this deleted block's height. + let at_height = match visited_heights.entry(height) { + Entry::Occupied(e) => e.into_mut(), + Entry::Vacant(e) => e.insert(overlay_db.load_blocks_at_height(&height)?), + }; + if let Some(i) = at_height.iter().position(|x| x == &next_child) { + at_height.remove(i); + } + } + } + + // Update all `CandidateEntry`s, deleting all those which now have empty `block_assignments`. + for (candidate_hash, candidate) in visited_candidates.into_iter() { + if candidate.block_assignments.is_empty() { + overlay_db.delete_candidate_entry(&candidate_hash); + } else { + overlay_db.write_candidate_entry(candidate); + } + } + + // Update all blocks-at-height keys, deleting all those which now have empty + // `block_assignments`. + for (h, at) in visited_heights.into_iter() { + if at.is_empty() { + overlay_db.delete_blocks_at_height(h); + } else { + overlay_db.write_blocks_at_height(h, at); + } + } + + // due to the fork pruning, this range actually might go too far above where our actual highest + // block is, if a relatively short fork is canonicalized. + // TODO https://github.com/paritytech/polkadot/issues/3389 + let new_range = StoredBlockRange(canon_number + 1, std::cmp::max(range.1, canon_number + 2)); + + overlay_db.write_stored_block_range(new_range); + + Ok(()) +} + +/// Record a new block entry. +/// +/// This will update the blocks-at-height mapping, the stored block range, if necessary, +/// and add block and candidate entries. It will also add approval entries to existing +/// candidate entries and add this as a child of any block entry corresponding to the +/// parent hash. +/// +/// Has no effect if there is already an entry for the block or `candidate_info` returns +/// `None` for any of the candidates referenced by the block entry. In these cases, +/// no information about new candidates will be referred to by this function. +pub fn add_block_entry( + store: &mut OverlayedBackend<'_, impl Backend>, + entry: BlockEntry, + n_validators: usize, + candidate_info: impl Fn(&CandidateHash) -> Option, +) -> SubsystemResult> { + let session = entry.session(); + let parent_hash = entry.parent_hash(); + let number = entry.block_number(); + + // Update the stored block range. + { + let new_range = match store.load_stored_blocks()? { + None => Some(StoredBlockRange(number, number + 1)), + Some(range) if range.1 <= number => Some(StoredBlockRange(range.0, number + 1)), + Some(_) => None, + }; + + new_range.map(|n| store.write_stored_block_range(n)); + }; + + // Update the blocks at height meta key. + { + let mut blocks_at_height = store.load_blocks_at_height(&number)?; + if blocks_at_height.contains(&entry.block_hash()) { + // seems we already have a block entry for this block. nothing to do here. + return Ok(Vec::new()) + } + + blocks_at_height.push(entry.block_hash()); + store.write_blocks_at_height(number, blocks_at_height) + }; + + let mut candidate_entries = Vec::with_capacity(entry.candidates().len()); + + // read and write all updated entries. + { + for (_, candidate_hash) in entry.candidates() { + let NewCandidateInfo { candidate, backing_group, our_assignment } = + match candidate_info(candidate_hash) { + None => return Ok(Vec::new()), + Some(info) => info, + }; + + let mut candidate_entry = + store.load_candidate_entry(&candidate_hash)?.unwrap_or_else(move || { + CandidateEntry { + candidate, + session, + block_assignments: BTreeMap::new(), + approvals: bitvec::bitvec![u8, BitOrderLsb0; 0; n_validators], + } + }); + + candidate_entry.block_assignments.insert( + entry.block_hash(), + ApprovalEntry::new( + Vec::new(), + backing_group, + our_assignment.map(|v| v.into()), + None, + bitvec::bitvec![u8, BitOrderLsb0; 0; n_validators], + false, + ), + ); + + store.write_candidate_entry(candidate_entry.clone()); + + candidate_entries.push((*candidate_hash, candidate_entry)); + } + }; + + // Update the child index for the parent. + store.load_block_entry(&parent_hash)?.map(|mut e| { + e.children.push(entry.block_hash()); + store.write_block_entry(e); + }); + + // Put the new block entry in. + store.write_block_entry(entry); + + Ok(candidate_entries) +} + +/// Forcibly approve all candidates included at up to the given relay-chain height in the indicated +/// chain. +pub fn force_approve( + store: &mut OverlayedBackend<'_, impl Backend>, + chain_head: Hash, + up_to: BlockNumber, +) -> SubsystemResult> { + #[derive(PartialEq, Eq)] + enum State { + WalkTo, + Approving, + } + let mut approved_hashes = Vec::new(); + + let mut cur_hash = chain_head; + let mut state = State::WalkTo; + let mut cur_block_number: BlockNumber = 0; + + // iterate back to the `up_to` block, and then iterate backwards until all blocks + // are updated. + while let Some(mut entry) = store.load_block_entry(&cur_hash)? { + cur_block_number = entry.block_number(); + if cur_block_number <= up_to { + if state == State::WalkTo { + gum::debug!( + target: LOG_TARGET, + block_hash = ?chain_head, + ?cur_hash, + ?cur_block_number, + "Start forced approval from block", + ); + } + state = State::Approving; + } + + cur_hash = entry.parent_hash(); + + match state { + State::WalkTo => {}, + State::Approving => { + entry.approved_bitfield.iter_mut().for_each(|mut b| *b = true); + approved_hashes.push(entry.block_hash()); + store.write_block_entry(entry); + }, + } + } + + if state == State::WalkTo { + gum::warn!( + target: LOG_TARGET, + ?chain_head, + ?cur_hash, + ?cur_block_number, + ?up_to, + "Missing block in the chain, cannot start force approval" + ); + } + + Ok(approved_hashes) +} + +/// Revert to the block corresponding to the specified `hash`. +/// The operation is not allowed for blocks older than the last finalized one. +pub fn revert_to( + overlay: &mut OverlayedBackend<'_, impl Backend>, + hash: Hash, +) -> SubsystemResult<()> { + let mut stored_range = overlay.load_stored_blocks()?.ok_or_else(|| { + SubsystemError::Context("no available blocks to infer revert point height".to_string()) + })?; + + let (children, children_height) = match overlay.load_block_entry(&hash)? { + Some(mut entry) => { + let children_height = entry.block_number() + 1; + let children = std::mem::take(&mut entry.children); + // Write revert point block entry without the children. + overlay.write_block_entry(entry); + (children, children_height) + }, + None => { + let children_height = stored_range.0; + let children = overlay.load_blocks_at_height(&children_height)?; + + let child_entry = children + .first() + .and_then(|hash| overlay.load_block_entry(hash).ok()) + .flatten() + .ok_or_else(|| { + SubsystemError::Context("lookup failure for first block".to_string()) + })?; + + // The parent is expected to be the revert point + if child_entry.parent_hash() != hash { + return Err(SubsystemError::Context( + "revert below last finalized block or corrupted storage".to_string(), + )) + } + + (children, children_height) + }, + }; + + let mut stack: Vec<_> = children.into_iter().map(|h| (h, children_height)).collect(); + let mut range_end = stored_range.1; + + while let Some((hash, number)) = stack.pop() { + let mut blocks_at_height = overlay.load_blocks_at_height(&number)?; + blocks_at_height.retain(|h| h != &hash); + + // Check if we need to update the range top + if blocks_at_height.is_empty() && number < range_end { + range_end = number; + } + + overlay.write_blocks_at_height(number, blocks_at_height); + + if let Some(entry) = overlay.load_block_entry(&hash)? { + overlay.delete_block_entry(&hash); + + // Cleanup the candidate entries by removing any reference to the + // removed block. If for a candidate entry the block block_assignments + // drops to zero then we remove the entry. + for (_, candidate_hash) in entry.candidates() { + if let Some(mut candidate_entry) = overlay.load_candidate_entry(candidate_hash)? { + candidate_entry.block_assignments.remove(&hash); + if candidate_entry.block_assignments.is_empty() { + overlay.delete_candidate_entry(candidate_hash); + } else { + overlay.write_candidate_entry(candidate_entry); + } + } + } + + stack.extend(entry.children.into_iter().map(|h| (h, number + 1))); + } + } + + // Check if our modifications to the dag has reduced the range top + if range_end != stored_range.1 { + if stored_range.0 < range_end { + stored_range.1 = range_end; + overlay.write_stored_block_range(stored_range); + } else { + overlay.delete_stored_block_range(); + } + } + + Ok(()) +} diff --git a/polkadot/node/core/approval-voting/src/persisted_entries.rs b/polkadot/node/core/approval-voting/src/persisted_entries.rs new file mode 100644 index 0000000000000000000000000000000000000000..9b6592220275dedcde80e902c65a8d19d1b47ce2 --- /dev/null +++ b/polkadot/node/core/approval-voting/src/persisted_entries.rs @@ -0,0 +1,447 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Entries pertaining to approval which need to be persisted. +//! +//! The actual persisting of data is handled by the `approval_db` module. +//! Within that context, things are plain-old-data. Within this module, +//! data and logic are intertwined. + +use polkadot_node_primitives::approval::{AssignmentCert, DelayTranche, RelayVRFStory}; +use polkadot_primitives::{ + BlockNumber, CandidateHash, CandidateReceipt, CoreIndex, GroupIndex, Hash, SessionIndex, + ValidatorIndex, ValidatorSignature, +}; +use sp_consensus_slots::Slot; + +use bitvec::{order::Lsb0 as BitOrderLsb0, slice::BitSlice, vec::BitVec}; +use std::collections::BTreeMap; + +use super::{criteria::OurAssignment, time::Tick}; + +/// Metadata regarding a specific tranche of assignments for a specific candidate. +#[derive(Debug, Clone, PartialEq)] +pub struct TrancheEntry { + tranche: DelayTranche, + // Assigned validators, and the instant we received their assignment, rounded + // to the nearest tick. + assignments: Vec<(ValidatorIndex, Tick)>, +} + +impl TrancheEntry { + /// Get the tranche of this entry. + pub fn tranche(&self) -> DelayTranche { + self.tranche + } + + /// Get the assignments for this entry. + pub fn assignments(&self) -> &[(ValidatorIndex, Tick)] { + &self.assignments + } +} + +impl From for TrancheEntry { + fn from(entry: crate::approval_db::v1::TrancheEntry) -> Self { + TrancheEntry { + tranche: entry.tranche, + assignments: entry.assignments.into_iter().map(|(v, t)| (v, t.into())).collect(), + } + } +} + +impl From for crate::approval_db::v1::TrancheEntry { + fn from(entry: TrancheEntry) -> Self { + Self { + tranche: entry.tranche, + assignments: entry.assignments.into_iter().map(|(v, t)| (v, t.into())).collect(), + } + } +} + +/// Metadata regarding approval of a particular candidate within the context of some +/// particular block. +#[derive(Debug, Clone, PartialEq)] +pub struct ApprovalEntry { + tranches: Vec, + backing_group: GroupIndex, + our_assignment: Option, + our_approval_sig: Option, + // `n_validators` bits. + assignments: BitVec, + approved: bool, +} + +impl ApprovalEntry { + /// Convenience constructor + pub fn new( + tranches: Vec, + backing_group: GroupIndex, + our_assignment: Option, + our_approval_sig: Option, + // `n_validators` bits. + assignments: BitVec, + approved: bool, + ) -> Self { + Self { tranches, backing_group, our_assignment, our_approval_sig, assignments, approved } + } + + // Access our assignment for this approval entry. + pub fn our_assignment(&self) -> Option<&OurAssignment> { + self.our_assignment.as_ref() + } + + // Note that our assignment is triggered. No-op if already triggered. + pub fn trigger_our_assignment( + &mut self, + tick_now: Tick, + ) -> Option<(AssignmentCert, ValidatorIndex, DelayTranche)> { + let our = self.our_assignment.as_mut().and_then(|a| { + if a.triggered() { + return None + } + a.mark_triggered(); + + Some(a.clone()) + }); + + our.map(|a| { + self.import_assignment(a.tranche(), a.validator_index(), tick_now); + + (a.cert().clone(), a.validator_index(), a.tranche()) + }) + } + + /// Import our local approval vote signature for this candidate. + pub fn import_approval_sig(&mut self, approval_sig: ValidatorSignature) { + self.our_approval_sig = Some(approval_sig); + } + + /// Whether a validator is already assigned. + pub fn is_assigned(&self, validator_index: ValidatorIndex) -> bool { + self.assignments.get(validator_index.0 as usize).map(|b| *b).unwrap_or(false) + } + + /// Import an assignment. No-op if already assigned on the same tranche. + pub fn import_assignment( + &mut self, + tranche: DelayTranche, + validator_index: ValidatorIndex, + tick_now: Tick, + ) { + // linear search probably faster than binary. not many tranches typically. + let idx = match self.tranches.iter().position(|t| t.tranche >= tranche) { + Some(pos) => { + if self.tranches[pos].tranche > tranche { + self.tranches.insert(pos, TrancheEntry { tranche, assignments: Vec::new() }); + } + + pos + }, + None => { + self.tranches.push(TrancheEntry { tranche, assignments: Vec::new() }); + + self.tranches.len() - 1 + }, + }; + + self.tranches[idx].assignments.push((validator_index, tick_now)); + self.assignments.set(validator_index.0 as _, true); + } + + // Produce a bitvec indicating the assignments of all validators up to and + // including `tranche`. + pub fn assignments_up_to(&self, tranche: DelayTranche) -> BitVec { + self.tranches.iter().take_while(|e| e.tranche <= tranche).fold( + bitvec::bitvec![u8, BitOrderLsb0; 0; self.assignments.len()], + |mut a, e| { + for &(v, _) in &e.assignments { + a.set(v.0 as _, true); + } + + a + }, + ) + } + + /// Whether the approval entry is approved + pub fn is_approved(&self) -> bool { + self.approved + } + + /// Mark the approval entry as approved. + pub fn mark_approved(&mut self) { + self.approved = true; + } + + /// Access the tranches. + pub fn tranches(&self) -> &[TrancheEntry] { + &self.tranches + } + + /// Get the number of validators in this approval entry. + pub fn n_validators(&self) -> usize { + self.assignments.len() + } + + /// Get the number of assignments by validators, including the local validator. + pub fn n_assignments(&self) -> usize { + self.assignments.count_ones() + } + + /// Get the backing group index of the approval entry. + pub fn backing_group(&self) -> GroupIndex { + self.backing_group + } + + /// Get the assignment cert & approval signature. + /// + /// The approval signature will only be `Some` if the assignment is too. + pub fn local_statements(&self) -> (Option, Option) { + let approval_sig = self.our_approval_sig.clone(); + if let Some(our_assignment) = self.our_assignment.as_ref().filter(|a| a.triggered()) { + (Some(our_assignment.clone()), approval_sig) + } else { + (None, None) + } + } +} + +impl From for ApprovalEntry { + fn from(entry: crate::approval_db::v1::ApprovalEntry) -> Self { + ApprovalEntry { + tranches: entry.tranches.into_iter().map(Into::into).collect(), + backing_group: entry.backing_group, + our_assignment: entry.our_assignment.map(Into::into), + our_approval_sig: entry.our_approval_sig.map(Into::into), + assignments: entry.assignments, + approved: entry.approved, + } + } +} + +impl From for crate::approval_db::v1::ApprovalEntry { + fn from(entry: ApprovalEntry) -> Self { + Self { + tranches: entry.tranches.into_iter().map(Into::into).collect(), + backing_group: entry.backing_group, + our_assignment: entry.our_assignment.map(Into::into), + our_approval_sig: entry.our_approval_sig.map(Into::into), + assignments: entry.assignments, + approved: entry.approved, + } + } +} + +/// Metadata regarding approval of a particular candidate. +#[derive(Debug, Clone, PartialEq)] +pub struct CandidateEntry { + pub candidate: CandidateReceipt, + pub session: SessionIndex, + // Assignments are based on blocks, so we need to track assignments separately + // based on the block we are looking at. + pub block_assignments: BTreeMap, + pub approvals: BitVec, +} + +impl CandidateEntry { + /// Access the bit-vec of approvals. + pub fn approvals(&self) -> &BitSlice { + &self.approvals + } + + /// Note that a given validator has approved. Return the previous approval state. + pub fn mark_approval(&mut self, validator: ValidatorIndex) -> bool { + let prev = self.has_approved(validator); + self.approvals.set(validator.0 as usize, true); + prev + } + + /// Query whether a given validator has approved the candidate. + pub fn has_approved(&self, validator: ValidatorIndex) -> bool { + self.approvals.get(validator.0 as usize).map(|b| *b).unwrap_or(false) + } + + /// Get the candidate receipt. + pub fn candidate_receipt(&self) -> &CandidateReceipt { + &self.candidate + } + + /// Get the approval entry, mutably, for this candidate under a specific block. + pub fn approval_entry_mut(&mut self, block_hash: &Hash) -> Option<&mut ApprovalEntry> { + self.block_assignments.get_mut(block_hash) + } + + /// Get the approval entry for this candidate under a specific block. + pub fn approval_entry(&self, block_hash: &Hash) -> Option<&ApprovalEntry> { + self.block_assignments.get(block_hash) + } +} + +impl From for CandidateEntry { + fn from(entry: crate::approval_db::v1::CandidateEntry) -> Self { + CandidateEntry { + candidate: entry.candidate, + session: entry.session, + block_assignments: entry + .block_assignments + .into_iter() + .map(|(h, ae)| (h, ae.into())) + .collect(), + approvals: entry.approvals, + } + } +} + +impl From for crate::approval_db::v1::CandidateEntry { + fn from(entry: CandidateEntry) -> Self { + Self { + candidate: entry.candidate, + session: entry.session, + block_assignments: entry + .block_assignments + .into_iter() + .map(|(h, ae)| (h, ae.into())) + .collect(), + approvals: entry.approvals, + } + } +} + +/// Metadata regarding approval of a particular block, by way of approval of the +/// candidates contained within it. +#[derive(Debug, Clone, PartialEq)] +pub struct BlockEntry { + block_hash: Hash, + parent_hash: Hash, + block_number: BlockNumber, + session: SessionIndex, + slot: Slot, + relay_vrf_story: RelayVRFStory, + // The candidates included as-of this block and the index of the core they are + // leaving. Sorted ascending by core index. + candidates: Vec<(CoreIndex, CandidateHash)>, + // A bitfield where the i'th bit corresponds to the i'th candidate in `candidates`. + // The i'th bit is `true` iff the candidate has been approved in the context of this + // block. The block can be considered approved if the bitfield has all bits set to `true`. + pub approved_bitfield: BitVec, + pub children: Vec, +} + +impl BlockEntry { + /// Mark a candidate as fully approved in the bitfield. + pub fn mark_approved_by_hash(&mut self, candidate_hash: &CandidateHash) { + if let Some(p) = self.candidates.iter().position(|(_, h)| h == candidate_hash) { + self.approved_bitfield.set(p, true); + } + } + + /// Whether a candidate is approved in the bitfield. + pub fn is_candidate_approved(&self, candidate_hash: &CandidateHash) -> bool { + self.candidates + .iter() + .position(|(_, h)| h == candidate_hash) + .and_then(|p| self.approved_bitfield.get(p).map(|b| *b)) + .unwrap_or(false) + } + + /// Whether the block entry is fully approved. + pub fn is_fully_approved(&self) -> bool { + self.approved_bitfield.all() + } + + /// Iterate over all unapproved candidates. + pub fn unapproved_candidates(&self) -> impl Iterator + '_ { + self.approved_bitfield.iter().enumerate().filter_map(move |(i, a)| { + if !*a { + Some(self.candidates[i].1) + } else { + None + } + }) + } + + /// Get the slot of the block. + pub fn slot(&self) -> Slot { + self.slot + } + + /// Get the relay-vrf-story of the block. + pub fn relay_vrf_story(&self) -> RelayVRFStory { + self.relay_vrf_story.clone() + } + + /// Get the session index of the block. + pub fn session(&self) -> SessionIndex { + self.session + } + + /// Get the i'th candidate. + pub fn candidate(&self, i: usize) -> Option<&(CoreIndex, CandidateHash)> { + self.candidates.get(i) + } + + /// Access the underlying candidates as a slice. + pub fn candidates(&self) -> &[(CoreIndex, CandidateHash)] { + &self.candidates + } + + /// Access the block number of the block entry. + pub fn block_number(&self) -> BlockNumber { + self.block_number + } + + /// Access the block hash of the block entry. + pub fn block_hash(&self) -> Hash { + self.block_hash + } + + /// Access the parent hash of the block entry. + pub fn parent_hash(&self) -> Hash { + self.parent_hash + } +} + +impl From for BlockEntry { + fn from(entry: crate::approval_db::v1::BlockEntry) -> Self { + BlockEntry { + block_hash: entry.block_hash, + parent_hash: entry.parent_hash, + block_number: entry.block_number, + session: entry.session, + slot: entry.slot, + relay_vrf_story: RelayVRFStory(entry.relay_vrf_story), + candidates: entry.candidates, + approved_bitfield: entry.approved_bitfield, + children: entry.children, + } + } +} + +impl From for crate::approval_db::v1::BlockEntry { + fn from(entry: BlockEntry) -> Self { + Self { + block_hash: entry.block_hash, + parent_hash: entry.parent_hash, + block_number: entry.block_number, + session: entry.session, + slot: entry.slot, + relay_vrf_story: entry.relay_vrf_story.0, + candidates: entry.candidates, + approved_bitfield: entry.approved_bitfield, + children: entry.children, + } + } +} diff --git a/polkadot/node/core/approval-voting/src/tests.rs b/polkadot/node/core/approval-voting/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..f58e60c6a4879f320a850b0058e6aeb07a6d0e68 --- /dev/null +++ b/polkadot/node/core/approval-voting/src/tests.rs @@ -0,0 +1,3125 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use polkadot_node_primitives::{ + approval::{ + AssignmentCert, AssignmentCertKind, DelayTranche, VrfOutput, VrfProof, VrfSignature, + RELAY_VRF_MODULO_CONTEXT, + }, + AvailableData, BlockData, PoV, +}; +use polkadot_node_subsystem::{ + messages::{ + AllMessages, ApprovalVotingMessage, AssignmentCheckResult, AvailabilityRecoveryMessage, + }, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, +}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_node_subsystem_util::TimeoutExt; +use polkadot_overseer::HeadSupportsParachains; +use polkadot_primitives::{ + CandidateCommitments, CandidateEvent, CoreIndex, GroupIndex, Header, Id as ParaId, IndexedVec, + ValidationCode, ValidatorSignature, +}; +use std::time::Duration; + +use assert_matches::assert_matches; +use async_trait::async_trait; +use parking_lot::Mutex; +use sp_keyring::sr25519::Keyring as Sr25519Keyring; +use sp_keystore::Keystore; +use std::{ + pin::Pin, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, +}; + +use super::{ + approval_db::v1::StoredBlockRange, + backend::BackendWriteOp, + import::tests::{ + garbage_vrf_signature, AllowedSlots, BabeEpoch, BabeEpochConfiguration, + CompatibleDigestItem, Digest, DigestItem, PreDigest, SecondaryVRFPreDigest, + }, +}; + +use ::test_helpers::{dummy_candidate_receipt, dummy_candidate_receipt_bad_sig}; + +const SLOT_DURATION_MILLIS: u64 = 5000; + +const TIMEOUT: Duration = Duration::from_millis(2000); + +#[derive(Clone)] +struct TestSyncOracle { + flag: Arc, + done_syncing_sender: Arc>>>, +} + +struct TestSyncOracleHandle { + done_syncing_receiver: oneshot::Receiver<()>, +} + +impl TestSyncOracleHandle { + async fn await_mode_switch(self) { + let _ = self.done_syncing_receiver.await; + } +} + +impl SyncOracle for TestSyncOracle { + fn is_major_syncing(&self) -> bool { + let is_major_syncing = self.flag.load(Ordering::SeqCst); + + if !is_major_syncing { + if let Some(sender) = self.done_syncing_sender.lock().take() { + let _ = sender.send(()); + } + } + + is_major_syncing + } + + fn is_offline(&self) -> bool { + unimplemented!("not used in network bridge") + } +} + +// val - result of `is_major_syncing`. +fn make_sync_oracle(val: bool) -> (Box, TestSyncOracleHandle) { + let (tx, rx) = oneshot::channel(); + let flag = Arc::new(AtomicBool::new(val)); + let oracle = TestSyncOracle { flag, done_syncing_sender: Arc::new(Mutex::new(Some(tx))) }; + let handle = TestSyncOracleHandle { done_syncing_receiver: rx }; + + (Box::new(oracle), handle) +} + +#[cfg(test)] +pub mod test_constants { + use crate::approval_db::v1::Config as DatabaseConfig; + const DATA_COL: u32 = 0; + + pub(crate) const NUM_COLUMNS: u32 = 1; + + pub(crate) const TEST_CONFIG: DatabaseConfig = DatabaseConfig { col_approval_data: DATA_COL }; +} + +struct MockSupportsParachains; + +#[async_trait] +impl HeadSupportsParachains for MockSupportsParachains { + async fn head_supports_parachains(&self, _head: &Hash) -> bool { + true + } +} + +fn slot_to_tick(t: impl Into) -> crate::time::Tick { + crate::time::slot_number_to_tick(SLOT_DURATION_MILLIS, t.into()) +} + +#[derive(Default, Clone)] +struct MockClock { + inner: Arc>, +} + +impl MockClock { + fn new(tick: Tick) -> Self { + let me = Self::default(); + me.inner.lock().set_tick(tick); + me + } +} + +impl Clock for MockClock { + fn tick_now(&self) -> Tick { + self.inner.lock().tick + } + + fn wait(&self, tick: Tick) -> Pin + Send + 'static>> { + let rx = self.inner.lock().register_wakeup(tick, true); + + Box::pin(async move { + rx.await.expect("i exist in a timeless void. yet, i remain"); + }) + } +} + +// This mock clock allows us to manipulate the time and +// be notified when wakeups have been triggered. +#[derive(Default)] +struct MockClockInner { + tick: Tick, + wakeups: Vec<(Tick, oneshot::Sender<()>)>, +} + +impl MockClockInner { + fn set_tick(&mut self, tick: Tick) { + self.tick = tick; + self.wakeup_all(tick); + } + + fn wakeup_all(&mut self, up_to: Tick) { + // This finds the position of the first wakeup after + // the given tick, or the end of the map. + let drain_up_to = self.wakeups.partition_point(|w| w.0 <= up_to); + for (_, wakeup) in self.wakeups.drain(..drain_up_to) { + let _ = wakeup.send(()); + } + } + + fn next_wakeup(&self) -> Option { + self.wakeups.iter().map(|w| w.0).next() + } + + fn current_wakeup_is(&mut self, tick: Tick) -> bool { + // first, prune away all wakeups which aren't actually being awaited + // on. + self.wakeups.retain(|(_, tx)| !tx.is_canceled()); + + // Then see if any remaining wakeups match the tick. + // This should be the only wakeup. + self.wakeups.binary_search_by_key(&tick, |w| w.0).is_ok() + } + + // If `pre_emptive` is true, we compare the given tick to the internal + // tick of the clock for an early return. + // + // Otherwise, the wakeup will only trigger alongside another wakeup of + // equal or greater tick. + // + // When the pre-emptive wakeup is disabled, this can be used in combination with + // a preceding call to `set_tick` to wait until some other wakeup at that same tick + // has been triggered. + fn register_wakeup(&mut self, tick: Tick, pre_emptive: bool) -> oneshot::Receiver<()> { + let (tx, rx) = oneshot::channel(); + + let pos = self.wakeups.partition_point(|w| w.0 <= tick); + self.wakeups.insert(pos, (tick, tx)); + + if pre_emptive { + // if `tick > self.tick`, this won't wake up the new + // listener. + self.wakeup_all(self.tick); + } + + rx + } +} + +struct MockAssignmentCriteria(Compute, Check); + +impl AssignmentCriteria for MockAssignmentCriteria +where + Compute: Fn() -> HashMap, + Check: Fn(ValidatorIndex) -> Result, +{ + fn compute_assignments( + &self, + _keystore: &LocalKeystore, + _relay_vrf_story: polkadot_node_primitives::approval::RelayVRFStory, + _config: &criteria::Config, + _leaving_cores: Vec<( + CandidateHash, + polkadot_primitives::CoreIndex, + polkadot_primitives::GroupIndex, + )>, + ) -> HashMap { + self.0() + } + + fn check_assignment_cert( + &self, + _claimed_core_index: polkadot_primitives::CoreIndex, + validator_index: ValidatorIndex, + _config: &criteria::Config, + _relay_vrf_story: polkadot_node_primitives::approval::RelayVRFStory, + _assignment: &polkadot_node_primitives::approval::AssignmentCert, + _backing_group: polkadot_primitives::GroupIndex, + ) -> Result { + self.1(validator_index) + } +} + +impl + MockAssignmentCriteria HashMap, F> +{ + fn check_only(f: F) -> Self { + MockAssignmentCriteria(Default::default, f) + } +} + +#[derive(Default, Clone)] +struct TestStoreInner { + stored_block_range: Option, + blocks_at_height: HashMap>, + block_entries: HashMap, + candidate_entries: HashMap, +} + +impl Backend for TestStoreInner { + fn load_block_entry(&self, block_hash: &Hash) -> SubsystemResult> { + Ok(self.block_entries.get(block_hash).cloned()) + } + + fn load_candidate_entry( + &self, + candidate_hash: &CandidateHash, + ) -> SubsystemResult> { + Ok(self.candidate_entries.get(candidate_hash).cloned()) + } + + fn load_blocks_at_height(&self, height: &BlockNumber) -> SubsystemResult> { + Ok(self.blocks_at_height.get(height).cloned().unwrap_or_default()) + } + + fn load_all_blocks(&self) -> SubsystemResult> { + let mut hashes: Vec<_> = self.block_entries.keys().cloned().collect(); + + hashes.sort_by_key(|k| self.block_entries.get(k).unwrap().block_number()); + + Ok(hashes) + } + + fn load_stored_blocks(&self) -> SubsystemResult> { + Ok(self.stored_block_range.clone()) + } + + fn write(&mut self, ops: I) -> SubsystemResult<()> + where + I: IntoIterator, + { + for op in ops { + match op { + BackendWriteOp::WriteStoredBlockRange(stored_block_range) => { + self.stored_block_range = Some(stored_block_range); + }, + BackendWriteOp::DeleteStoredBlockRange => { + self.stored_block_range = None; + }, + BackendWriteOp::WriteBlocksAtHeight(h, blocks) => { + self.blocks_at_height.insert(h, blocks); + }, + BackendWriteOp::DeleteBlocksAtHeight(h) => { + let _ = self.blocks_at_height.remove(&h); + }, + BackendWriteOp::WriteBlockEntry(block_entry) => { + self.block_entries.insert(block_entry.block_hash(), block_entry); + }, + BackendWriteOp::DeleteBlockEntry(hash) => { + let _ = self.block_entries.remove(&hash); + }, + BackendWriteOp::WriteCandidateEntry(candidate_entry) => { + self.candidate_entries + .insert(candidate_entry.candidate_receipt().hash(), candidate_entry); + }, + BackendWriteOp::DeleteCandidateEntry(candidate_hash) => { + let _ = self.candidate_entries.remove(&candidate_hash); + }, + } + } + + Ok(()) + } +} + +#[derive(Default, Clone)] +pub struct TestStore { + store: Arc>, +} + +impl Backend for TestStore { + fn load_block_entry(&self, block_hash: &Hash) -> SubsystemResult> { + let store = self.store.lock(); + store.load_block_entry(block_hash) + } + + fn load_candidate_entry( + &self, + candidate_hash: &CandidateHash, + ) -> SubsystemResult> { + let store = self.store.lock(); + store.load_candidate_entry(candidate_hash) + } + + fn load_blocks_at_height(&self, height: &BlockNumber) -> SubsystemResult> { + let store = self.store.lock(); + store.load_blocks_at_height(height) + } + + fn load_all_blocks(&self) -> SubsystemResult> { + let store = self.store.lock(); + store.load_all_blocks() + } + + fn load_stored_blocks(&self) -> SubsystemResult> { + let store = self.store.lock(); + store.load_stored_blocks() + } + + fn write(&mut self, ops: I) -> SubsystemResult<()> + where + I: IntoIterator, + { + let mut store = self.store.lock(); + store.write(ops) + } +} + +fn garbage_assignment_cert(kind: AssignmentCertKind) -> AssignmentCert { + let ctx = schnorrkel::signing_context(RELAY_VRF_MODULO_CONTEXT); + let msg = b"test-garbage"; + let mut prng = rand_core::OsRng; + let keypair = schnorrkel::Keypair::generate_with(&mut prng); + let (inout, proof, _) = keypair.vrf_sign(ctx.bytes(msg)); + let out = inout.to_output(); + + AssignmentCert { kind, vrf: VrfSignature { output: VrfOutput(out), proof: VrfProof(proof) } } +} + +fn sign_approval( + key: Sr25519Keyring, + candidate_hash: CandidateHash, + session_index: SessionIndex, +) -> ValidatorSignature { + key.sign(&ApprovalVote(candidate_hash).signing_payload(session_index)).into() +} + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; + +#[derive(Default)] +struct HarnessConfigBuilder { + sync_oracle: Option<(Box, TestSyncOracleHandle)>, + clock: Option, + backend: Option, + assignment_criteria: Option>, +} + +impl HarnessConfigBuilder { + pub fn assignment_criteria( + &mut self, + assignment_criteria: Box, + ) -> &mut Self { + self.assignment_criteria = Some(assignment_criteria); + self + } + + pub fn build(&mut self) -> HarnessConfig { + let (sync_oracle, sync_oracle_handle) = + self.sync_oracle.take().unwrap_or_else(|| make_sync_oracle(false)); + + let assignment_criteria = self + .assignment_criteria + .take() + .unwrap_or_else(|| Box::new(MockAssignmentCriteria::check_only(|_| Ok(0)))); + + HarnessConfig { + sync_oracle, + sync_oracle_handle, + clock: self.clock.take().unwrap_or_else(|| MockClock::new(0)), + backend: self.backend.take().unwrap_or_else(|| TestStore::default()), + assignment_criteria, + } + } +} + +struct HarnessConfig { + sync_oracle: Box, + sync_oracle_handle: TestSyncOracleHandle, + clock: MockClock, + backend: TestStore, + assignment_criteria: Box, +} + +impl HarnessConfig { + pub fn backend(&self) -> TestStore { + self.backend.clone() + } +} + +impl Default for HarnessConfig { + fn default() -> Self { + HarnessConfigBuilder::default().build() + } +} + +struct TestHarness { + virtual_overseer: VirtualOverseer, + clock: Box, + sync_oracle_handle: TestSyncOracleHandle, +} + +fn test_harness>( + config: HarnessConfig, + test: impl FnOnce(TestHarness) -> T, +) { + let HarnessConfig { sync_oracle, sync_oracle_handle, clock, backend, assignment_criteria } = + config; + + let pool = sp_core::testing::TaskExecutor::new(); + let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool); + + let keystore = LocalKeystore::in_memory(); + let _ = keystore.sr25519_generate_new( + polkadot_primitives::PARACHAIN_KEY_TYPE_ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ); + + let clock = Box::new(clock); + let db = kvdb_memorydb::create(test_constants::NUM_COLUMNS); + let db = polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter::new(db, &[]); + + let subsystem = run( + context, + ApprovalVotingSubsystem::with_config( + Config { + col_approval_data: test_constants::TEST_CONFIG.col_approval_data, + slot_duration_millis: SLOT_DURATION_MILLIS, + }, + Arc::new(db), + Arc::new(keystore), + sync_oracle, + Metrics::default(), + ), + clock.clone(), + assignment_criteria, + backend, + ); + + let test_fut = test(TestHarness { virtual_overseer, clock, sync_oracle_handle }); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + futures::executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )) + .1 + .unwrap(); +} + +async fn overseer_send(overseer: &mut VirtualOverseer, msg: FromOrchestra) { + gum::trace!("Sending message:\n{:?}", &msg); + overseer + .send(msg) + .timeout(TIMEOUT) + .await + .expect(&format!("{:?} is enough for sending messages.", TIMEOUT)); +} + +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { + let msg = overseer_recv_with_timeout(overseer, TIMEOUT) + .await + .expect(&format!("{:?} is enough to receive messages.", TIMEOUT)); + + gum::trace!("Received message:\n{:?}", &msg); + + msg +} + +async fn overseer_recv_with_timeout( + overseer: &mut VirtualOverseer, + timeout: Duration, +) -> Option { + gum::trace!("Waiting for message..."); + overseer.recv().timeout(timeout).await +} + +async fn overseer_signal(overseer: &mut VirtualOverseer, signal: OverseerSignal) { + overseer + .send(FromOrchestra::Signal(signal)) + .timeout(TIMEOUT) + .await + .expect(&format!("{:?} is more than enough for sending signals.", TIMEOUT)); +} + +fn overlay_txn(db: &mut T, mut f: F) +where + T: Backend, + F: FnMut(&mut OverlayedBackend<'_, T>), +{ + let mut overlay_db = OverlayedBackend::new(db); + f(&mut overlay_db); + let write_ops = overlay_db.into_write_ops(); + db.write(write_ops).unwrap(); +} + +fn make_candidate(para_id: ParaId, hash: &Hash) -> CandidateReceipt { + let mut r = dummy_candidate_receipt_bad_sig(*hash, Some(Default::default())); + r.descriptor.para_id = para_id; + r +} + +async fn check_and_import_approval( + overseer: &mut VirtualOverseer, + block_hash: Hash, + candidate_index: CandidateIndex, + validator: ValidatorIndex, + candidate_hash: CandidateHash, + session_index: SessionIndex, + expect_chain_approved: bool, + signature_opt: Option, +) -> oneshot::Receiver { + let signature = signature_opt.unwrap_or(sign_approval( + Sr25519Keyring::Alice, + candidate_hash, + session_index, + )); + let (tx, rx) = oneshot::channel(); + overseer_send( + overseer, + FromOrchestra::Communication { + msg: ApprovalVotingMessage::CheckAndImportApproval( + IndirectSignedApprovalVote { block_hash, candidate_index, validator, signature }, + tx, + ), + }, + ) + .await; + if expect_chain_approved { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ChainSelection(ChainSelectionMessage::Approved(b_hash)) => { + assert_eq!(b_hash, block_hash); + } + ); + } + rx +} + +async fn check_and_import_assignment( + overseer: &mut VirtualOverseer, + block_hash: Hash, + candidate_index: CandidateIndex, + validator: ValidatorIndex, +) -> oneshot::Receiver { + let (tx, rx) = oneshot::channel(); + overseer_send( + overseer, + FromOrchestra::Communication { + msg: ApprovalVotingMessage::CheckAndImportAssignment( + IndirectAssignmentCert { + block_hash, + validator, + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), + }, + candidate_index, + tx, + ), + }, + ) + .await; + rx +} + +struct BlockConfig { + slot: Slot, + candidates: Option>, + session_info: Option, +} + +struct ChainBuilder { + blocks_by_hash: HashMap, + blocks_at_height: BTreeMap>, +} + +impl ChainBuilder { + const GENESIS_HASH: Hash = Hash::repeat_byte(0xff); + const GENESIS_PARENT_HASH: Hash = Hash::repeat_byte(0x00); + + pub fn new() -> Self { + let mut builder = + Self { blocks_by_hash: HashMap::new(), blocks_at_height: BTreeMap::new() }; + builder.add_block_inner( + Self::GENESIS_HASH, + Self::GENESIS_PARENT_HASH, + 0, + BlockConfig { slot: Slot::from(0), candidates: None, session_info: None }, + ); + builder + } + + pub fn add_block( + &mut self, + hash: Hash, + parent_hash: Hash, + number: u32, + config: BlockConfig, + ) -> &mut Self { + assert!(number != 0, "cannot add duplicate genesis block"); + assert!(hash != Self::GENESIS_HASH, "cannot add block with genesis hash"); + assert!( + parent_hash != Self::GENESIS_PARENT_HASH, + "cannot add block with genesis parent hash" + ); + assert!(self.blocks_by_hash.len() < u8::MAX.into()); + self.add_block_inner(hash, parent_hash, number, config) + } + + fn add_block_inner( + &mut self, + hash: Hash, + parent_hash: Hash, + number: u32, + config: BlockConfig, + ) -> &mut Self { + let header = ChainBuilder::make_header(parent_hash, config.slot, number); + assert!( + self.blocks_by_hash.insert(hash, (header, config)).is_none(), + "block with hash {:?} already exists", + hash, + ); + self.blocks_at_height.entry(number).or_insert_with(Vec::new).push(hash); + self + } + + pub async fn build(&self, overseer: &mut VirtualOverseer) { + for (number, blocks) in self.blocks_at_height.iter() { + for (i, hash) in blocks.iter().enumerate() { + let mut cur_hash = *hash; + let (_, block_config) = + self.blocks_by_hash.get(&cur_hash).expect("block not found"); + let mut ancestry = Vec::new(); + while cur_hash != Self::GENESIS_PARENT_HASH { + let (cur_header, _) = + self.blocks_by_hash.get(&cur_hash).expect("chain is not contiguous"); + ancestry.push((cur_hash, cur_header.clone())); + cur_hash = cur_header.parent_hash; + } + ancestry.reverse(); + + import_block(overseer, ancestry.as_ref(), *number, block_config, false, i > 0) + .await; + let _: Option<()> = future::pending().timeout(Duration::from_millis(100)).await; + } + } + } + + fn make_header(parent_hash: Hash, slot: Slot, number: u32) -> Header { + let digest = { + let mut digest = Digest::default(); + let vrf_signature = garbage_vrf_signature(); + digest.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF( + SecondaryVRFPreDigest { authority_index: 0, slot, vrf_signature }, + ))); + digest + }; + + Header { + digest, + extrinsics_root: Default::default(), + number, + state_root: Default::default(), + parent_hash, + } + } +} + +fn session_info(keys: &[Sr25519Keyring]) -> SessionInfo { + SessionInfo { + validators: keys.iter().map(|v| v.public().into()).collect(), + discovery_keys: keys.iter().map(|v| v.public().into()).collect(), + assignment_keys: keys.iter().map(|v| v.public().into()).collect(), + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0)], + vec![ValidatorIndex(1)], + ]), + n_cores: keys.len() as _, + needed_approvals: 2, + zeroth_delay_tranche_width: 5, + relay_vrf_modulo_samples: 3, + n_delay_tranches: 50, + no_show_slots: 2, + active_validator_indices: vec![], + dispute_period: 6, + random_seed: [0u8; 32], + } +} + +async fn import_block( + overseer: &mut VirtualOverseer, + hashes: &[(Hash, Header)], + number: u32, + config: &BlockConfig, + gap: bool, + fork: bool, +) { + let (new_head, new_header) = &hashes[hashes.len() - 1]; + let candidates = config.candidates.clone().unwrap_or(vec![( + make_candidate(ParaId::from(0_u32), &new_head), + CoreIndex(0), + GroupIndex(0), + )]); + + let session_info = config.session_info.clone().unwrap_or({ + let validators = vec![Sr25519Keyring::Alice, Sr25519Keyring::Bob]; + SessionInfo { needed_approvals: 1, ..session_info(&validators) } + }); + + overseer_send( + overseer, + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( + ActivatedLeaf { + hash: *new_head, + number, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }, + ))), + ) + .await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(head, h_tx)) => { + assert_eq!(*new_head, head); + h_tx.send(Ok(Some(new_header.clone()))).unwrap(); + } + ); + if !fork { + let mut _ancestry_step = 0; + if gap { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ChainApi(ChainApiMessage::Ancestors { + hash, + k, + response_channel, + }) => { + assert_eq!(hash, *new_head); + let history: Vec = hashes.iter().map(|v| v.0).take(k).collect(); + let _ = response_channel.send(Ok(history)); + _ancestry_step = k; + } + ); + + for i in 0.._ancestry_step { + match overseer_recv(overseer).await { + AllMessages::ChainApi(ChainApiMessage::BlockHeader(_, h_tx)) => { + let (hash, header) = hashes[i as usize].clone(); + assert_eq!(hash, *new_head); + h_tx.send(Ok(Some(header))).unwrap(); + }, + AllMessages::ChainApi(ChainApiMessage::Ancestors { + hash, + k, + response_channel, + }) => { + assert_eq!(hash, *new_head); + assert_eq!(k as u32, number - 1); + let history: Vec = hashes.iter().map(|v| v.0).take(k).collect(); + response_channel.send(Ok(history)).unwrap(); + }, + _ => unreachable! {}, + } + } + } + } + + if number > 0 { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(hash, RuntimeApiRequest::CandidateEvents(c_tx)) + ) => { + assert_eq!(hash, *new_head); + let inclusion_events = candidates.into_iter() + .map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g)) + .collect::>(); + c_tx.send(Ok(inclusion_events)).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + req_block_hash, + RuntimeApiRequest::SessionIndexForChild(s_tx) + ) + ) => { + let hash = &hashes[(number-1) as usize]; + assert_eq!(req_block_hash, hash.0.clone()); + s_tx.send(Ok(number.into())).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + req_block_hash, + RuntimeApiRequest::CurrentBabeEpoch(c_tx), + ) + ) => { + let hash = &hashes[number as usize]; + assert_eq!(req_block_hash, hash.0.clone()); + let _ = c_tx.send(Ok(BabeEpoch { + epoch_index: number as _, + start_slot: Slot::from(0), + duration: 200, + authorities: vec![(Sr25519Keyring::Alice.public().into(), 1)], + randomness: [0u8; 32], + config: BabeEpochConfiguration { + c: (1, 4), + allowed_slots: AllowedSlots::PrimarySlots, + }, + })); + } + ); + } + + if number == 0 { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks(v)) => { + assert_eq!(v.len(), 0usize); + } + ); + } else { + if !fork { + // SessionInfo won't be called for forks - it's already cached + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + req_block_hash, + RuntimeApiRequest::SessionInfo(_, si_tx), + ) + ) => { + // Make sure all SessionInfo calls are not made for the leaf (but for its relay parent) + assert_ne!(req_block_hash, hashes[(number-1) as usize].0); + si_tx.send(Ok(Some(session_info.clone()))).unwrap(); + } + ); + } + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalDistribution( + ApprovalDistributionMessage::NewBlocks(mut approval_vec) + ) => { + assert_eq!(approval_vec.len(), 1); + let metadata = approval_vec.pop().unwrap(); + let hash = &hashes[number as usize]; + let parent_hash = &hashes[(number - 1) as usize]; + assert_eq!(metadata.hash, hash.0.clone()); + assert_eq!(metadata.parent_hash, parent_hash.0.clone()); + assert_eq!(metadata.slot, config.slot); + } + ); + } +} + +#[test] +fn subsystem_rejects_bad_assignment_ok_criteria() { + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle: _sync_oracle_handle, .. } = + test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let candidate_index = 0; + let validator = ValidatorIndex(0); + + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + let slot = Slot::from(1 as u64); + builder.add_block( + block_hash, + head, + 1, + BlockConfig { slot, candidates: None, session_info: None }, + ); + builder.build(&mut virtual_overseer).await; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted),); + + // unknown hash + let unknown_hash = Hash::repeat_byte(0x02); + + let rx = check_and_import_assignment( + &mut virtual_overseer, + unknown_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!( + rx.await, + Ok(AssignmentCheckResult::Bad(AssignmentCheckError::UnknownBlock(unknown_hash))), + ); + + virtual_overseer + }); +} + +#[test] +fn subsystem_rejects_bad_assignment_err_criteria() { + let assignment_criteria = Box::new(MockAssignmentCriteria::check_only(move |_| { + Err(criteria::InvalidAssignment( + criteria::InvalidAssignmentReason::ValidatorIndexOutOfBounds, + )) + })); + let config = HarnessConfigBuilder::default().assignment_criteria(assignment_criteria).build(); + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle: _sync_oracle_handle, .. } = + test_harness; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let candidate_index = 0; + let validator = ValidatorIndex(0); + + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + let slot = Slot::from(1 as u64); + builder.add_block( + block_hash, + head, + 1, + BlockConfig { slot, candidates: None, session_info: None }, + ); + builder.build(&mut virtual_overseer).await; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!( + rx.await, + Ok(AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCert( + ValidatorIndex(0), + "ValidatorIndexOutOfBounds".to_string(), + ))), + ); + + virtual_overseer + }); +} + +#[test] +fn blank_subsystem_act_on_bad_block() { + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle, .. } = test_harness; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let (tx, rx) = oneshot::channel(); + + let bad_block_hash: Hash = Default::default(); + + overseer_send( + &mut virtual_overseer, + FromOrchestra::Communication { + msg: ApprovalVotingMessage::CheckAndImportAssignment( + IndirectAssignmentCert { + block_hash: bad_block_hash, + validator: 0u32.into(), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { + sample: 0, + }), + }, + 0u32, + tx, + ), + }, + ) + .await; + + sync_oracle_handle.await_mode_switch().await; + + assert_matches!( + rx.await, + Ok( + AssignmentCheckResult::Bad(AssignmentCheckError::UnknownBlock(hash)) + ) => { + assert_eq!(hash, bad_block_hash); + } + ); + + virtual_overseer + }); +} + +#[test] +fn subsystem_rejects_approval_if_no_candidate_entry() { + let config = HarnessConfig::default(); + let store = config.backend(); + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle: _sync_oracle_handle, .. } = + test_harness; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let candidate_index = 0; + let validator = ValidatorIndex(0); + + let candidate_descriptor = make_candidate(ParaId::from(1_u32), &block_hash); + let candidate_hash = candidate_descriptor.hash(); + + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + let slot = Slot::from(1 as u64); + builder.add_block( + block_hash, + head, + 1, + BlockConfig { + slot, + candidates: Some(vec![(candidate_descriptor, CoreIndex(1), GroupIndex(1))]), + session_info: None, + }, + ); + builder.build(&mut virtual_overseer).await; + + overlay_txn(&mut store.clone(), |overlay_db| { + overlay_db.delete_candidate_entry(&candidate_hash) + }); + + let session_index = 1; + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + candidate_hash, + session_index, + false, + None, + ) + .await; + + assert_matches!( + rx.await, + Ok(ApprovalCheckResult::Bad(ApprovalCheckError::InvalidCandidate(0, hash))) => { + assert_eq!(candidate_hash, hash); + } + ); + + virtual_overseer + }); +} + +#[test] +fn subsystem_rejects_approval_if_no_block_entry() { + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle: _sync_oracle_handle, .. } = + test_harness; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let candidate_index = 0; + let validator = ValidatorIndex(0); + let candidate_hash = dummy_candidate_receipt(block_hash).hash(); + let session_index = 1; + + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + candidate_hash, + session_index, + false, + None, + ) + .await; + + assert_matches!( + rx.await, + Ok(ApprovalCheckResult::Bad(ApprovalCheckError::UnknownBlock(hash))) => { + assert_eq!(hash, block_hash); + } + ); + + virtual_overseer + }); +} + +#[test] +fn subsystem_rejects_approval_before_assignment() { + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle: _sync_oracle_handle, .. } = + test_harness; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + + let candidate_hash = { + let mut candidate_receipt = + dummy_candidate_receipt_bad_sig(block_hash, Some(Default::default())); + candidate_receipt.descriptor.para_id = ParaId::from(0_u32); + candidate_receipt.descriptor.relay_parent = block_hash; + candidate_receipt.hash() + }; + + let candidate_index = 0; + let validator = ValidatorIndex(0); + let session_index = 1; + + // Add block hash 00. + ChainBuilder::new() + .add_block( + block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + ) + .build(&mut virtual_overseer) + .await; + + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + candidate_hash, + session_index, + false, + None, + ) + .await; + + assert_matches!( + rx.await, + Ok(ApprovalCheckResult::Bad(ApprovalCheckError::NoAssignment(v))) => { + assert_eq!(v, validator); + } + ); + + virtual_overseer + }); +} + +#[test] +fn subsystem_rejects_assignment_in_future() { + let assignment_criteria = + Box::new(MockAssignmentCriteria::check_only(|_| Ok(TICK_TOO_FAR_IN_FUTURE as _))); + let config = HarnessConfigBuilder::default().assignment_criteria(assignment_criteria).build(); + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle: _sync_oracle_handle } = + test_harness; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let candidate_index = 0; + let validator = ValidatorIndex(0); + + // Add block hash 00. + ChainBuilder::new() + .add_block( + block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { slot: Slot::from(0), candidates: None, session_info: None }, + ) + .build(&mut virtual_overseer) + .await; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::TooFarInFuture)); + + // Advance clock to make assignment reasonably near. + clock.inner.lock().set_tick(9); + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + + virtual_overseer + }); +} + +#[test] +fn subsystem_accepts_duplicate_assignment() { + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle: _sync_oracle_handle, .. } = + test_harness; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let candidate_index = 0; + let validator = ValidatorIndex(0); + + // Add block hash 00. + ChainBuilder::new() + .add_block( + block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + ) + .build(&mut virtual_overseer) + .await; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::AcceptedDuplicate)); + + virtual_overseer + }); +} + +#[test] +fn subsystem_rejects_assignment_with_unknown_candidate() { + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle: _sync_oracle_handle, .. } = + test_harness; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let candidate_index = 7; + let validator = ValidatorIndex(0); + + // Add block hash 00. + ChainBuilder::new() + .add_block( + block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + ) + .build(&mut virtual_overseer) + .await; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!( + rx.await, + Ok(AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidateIndex( + candidate_index + ))), + ); + + virtual_overseer + }); +} + +#[test] +fn subsystem_accepts_and_imports_approval_after_assignment() { + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle: _sync_oracle_handle, .. } = + test_harness; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + + let candidate_hash = { + let mut candidate_receipt = + dummy_candidate_receipt_bad_sig(block_hash, Some(Default::default())); + candidate_receipt.descriptor.para_id = ParaId::from(0_u32); + candidate_receipt.descriptor.relay_parent = block_hash; + candidate_receipt.hash() + }; + + let candidate_index = 0; + let validator = ValidatorIndex(0); + let session_index = 1; + + // Add block hash 0x01... + ChainBuilder::new() + .add_block( + block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + ) + .build(&mut virtual_overseer) + .await; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + candidate_hash, + session_index, + true, + None, + ) + .await; + + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted)); + + virtual_overseer + }); +} + +#[test] +fn subsystem_second_approval_import_only_schedules_wakeups() { + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { + mut virtual_overseer, + clock, + sync_oracle_handle: _sync_oracle_handle, + .. + } = test_harness; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + clock.inner.lock().set_tick(APPROVAL_DELAY); + + let block_hash = Hash::repeat_byte(0x01); + + let candidate_hash = { + let mut candidate_receipt = + dummy_candidate_receipt_bad_sig(block_hash, Some(Default::default())); + candidate_receipt.descriptor.para_id = ParaId::from(0_u32); + candidate_receipt.descriptor.relay_parent = block_hash; + candidate_receipt.hash() + }; + + let candidate_index = 0; + let validator = ValidatorIndex(0); + let session_index = 1; + + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + ]; + let session_info = SessionInfo { + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2)], + vec![ValidatorIndex(3), ValidatorIndex(4)], + ]), + needed_approvals: 1, + ..session_info(&validators) + }; + + // Add block hash 0x01... + ChainBuilder::new() + .add_block( + block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { + slot: Slot::from(0), + candidates: None, + session_info: Some(session_info), + }, + ) + .build(&mut virtual_overseer) + .await; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + + assert!(clock.inner.lock().current_wakeup_is(APPROVAL_DELAY + 2)); + + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + candidate_hash, + session_index, + false, + None, + ) + .await; + + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted)); + + futures_timer::Delay::new(Duration::from_millis(100)).await; + assert!(clock.inner.lock().current_wakeup_is(APPROVAL_DELAY + 2)); + + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + candidate_hash, + session_index, + false, + None, + ) + .await; + + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted)); + + futures_timer::Delay::new(Duration::from_millis(100)).await; + assert!(clock.inner.lock().current_wakeup_is(APPROVAL_DELAY + 2)); + + virtual_overseer + }); +} + +#[test] +fn subsystem_assignment_import_updates_candidate_entry_and_schedules_wakeup() { + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { + mut virtual_overseer, + clock, + sync_oracle_handle: _sync_oracle_handle, + .. + } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + + let candidate_index = 0; + let validator = ValidatorIndex(0); + + // Add block hash 0x01... + ChainBuilder::new() + .add_block( + block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + ) + .build(&mut virtual_overseer) + .await; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + + assert!(clock.inner.lock().current_wakeup_is(2)); + + virtual_overseer + }); +} + +#[test] +fn subsystem_process_wakeup_schedules_wakeup() { + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { + mut virtual_overseer, + clock, + sync_oracle_handle: _sync_oracle_handle, + .. + } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + + let candidate_index = 0; + let validator = ValidatorIndex(0); + + // Add block hash 0x01... + ChainBuilder::new() + .add_block( + block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + ) + .build(&mut virtual_overseer) + .await; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + + assert!(clock.inner.lock().current_wakeup_is(2)); + + // Activate the wakeup present above, and sleep to allow process_wakeups to execute.. + clock.inner.lock().set_tick(2); + futures_timer::Delay::new(Duration::from_millis(100)).await; + + // The wakeup should have been rescheduled. + assert!(clock.inner.lock().current_wakeup_is(30)); + + virtual_overseer + }); +} + +#[test] +fn linear_import_act_on_leaf() { + let session = 3u32; + + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let mut head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + for i in 1..session { + let slot = Slot::from(i as u64); + + let hash = Hash::repeat_byte(i as u8); + builder.add_block( + hash, + head, + i, + BlockConfig { slot, candidates: None, session_info: None }, + ); + head = hash; + } + + builder.build(&mut virtual_overseer).await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + FromOrchestra::Communication { + msg: ApprovalVotingMessage::CheckAndImportAssignment( + IndirectAssignmentCert { + block_hash: head, + validator: 0u32.into(), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { + sample: 0, + }), + }, + 0u32, + tx, + ), + }, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + + virtual_overseer + }); +} + +#[test] +fn forkful_import_at_same_height_act_on_leaf() { + let session = 3u32; + + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle: _sync_oracle_handle, .. } = + test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let mut head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + for i in 1..session { + let slot = Slot::from(i as u64); + let hash = Hash::repeat_byte(i as u8); + builder.add_block( + hash, + head, + i, + BlockConfig { slot, candidates: None, session_info: None }, + ); + head = hash; + } + let num_forks = 3; + let forks = Vec::new(); + + for i in 0..num_forks { + let slot = Slot::from(session as u64); + let hash = Hash::repeat_byte(session as u8 + i); + builder.add_block( + hash, + head, + session, + BlockConfig { slot, candidates: None, session_info: None }, + ); + } + builder.build(&mut virtual_overseer).await; + + for head in forks.into_iter() { + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + FromOrchestra::Communication { + msg: ApprovalVotingMessage::CheckAndImportAssignment( + IndirectAssignmentCert { + block_hash: head, + validator: 0u32.into(), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { + sample: 0, + }), + }, + 0u32, + tx, + ), + }, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + } + virtual_overseer + }); +} + +#[test] +fn import_checked_approval_updates_entries_and_schedules() { + let config = HarnessConfig::default(); + let store = config.backend(); + test_harness(config, |test_harness| async move { + let TestHarness { + mut virtual_overseer, + clock, + sync_oracle_handle: _sync_oracle_handle, + .. + } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let validator_index_a = ValidatorIndex(0); + let validator_index_b = ValidatorIndex(1); + + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + ]; + let session_info = SessionInfo { + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2)], + vec![ValidatorIndex(3), ValidatorIndex(4)], + ]), + ..session_info(&validators) + }; + + let candidate_descriptor = make_candidate(ParaId::from(1_u32), &block_hash); + let candidate_hash = candidate_descriptor.hash(); + + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + let slot = Slot::from(1 as u64); + builder.add_block( + block_hash, + head, + 1, + BlockConfig { + slot, + candidates: Some(vec![(candidate_descriptor, CoreIndex(0), GroupIndex(0))]), + session_info: Some(session_info), + }, + ); + builder.build(&mut virtual_overseer).await; + + let candidate_index = 0; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_a, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted),); + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_b, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted),); + + let session_index = 1; + let sig_a = sign_approval(Sr25519Keyring::Alice, candidate_hash, session_index); + + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_a, + candidate_hash, + session_index, + false, + Some(sig_a), + ) + .await; + + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted),); + + // Sleep to ensure we get a consistent read on the database. + futures_timer::Delay::new(Duration::from_millis(100)).await; + + // The candidate should not yet be approved and a wakeup should be scheduled on the first + // approval. + let candidate_entry = store.load_candidate_entry(&candidate_hash).unwrap().unwrap(); + assert!(!candidate_entry.approval_entry(&block_hash).unwrap().is_approved()); + assert!(clock.inner.lock().current_wakeup_is(2)); + + // Clear the wake ups to assert that later approval also schedule wakeups. + clock.inner.lock().wakeup_all(2); + + let sig_b = sign_approval(Sr25519Keyring::Bob, candidate_hash, session_index); + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_b, + candidate_hash, + session_index, + true, + Some(sig_b), + ) + .await; + + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted),); + + // Sleep to ensure we get a consistent read on the database. + // + // NOTE: Since the response above occurs before writing to the database, we are somewhat + // breaking the external consistency of the API by reaching into the database directly. + // Under normal operation, this wouldn't be necessary, since all requests are serialized by + // the event loop and we write at the end of each pass. However, if the database write were + // to fail, a downstream subsystem may expect for this candidate to be approved, and + // possibly take further actions on the assumption that the candidate is approved, when + // that may not be the reality from the database's perspective. This could be avoided + // entirely by having replies processed after database writes, but that would constitute a + // larger refactor and incur a performance penalty. + futures_timer::Delay::new(Duration::from_millis(100)).await; + + // The candidate should now be approved. + let candidate_entry = store.load_candidate_entry(&candidate_hash).unwrap().unwrap(); + assert!(candidate_entry.approval_entry(&block_hash).unwrap().is_approved()); + + virtual_overseer + }); +} + +#[test] +fn subsystem_import_checked_approval_sets_one_block_bit_at_a_time() { + let config = HarnessConfig::default(); + let store = config.backend(); + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle: _sync_oracle_handle, .. } = + test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + + let candidate_receipt1 = { + let mut receipt = dummy_candidate_receipt(block_hash); + receipt.descriptor.para_id = ParaId::from(1_u32); + receipt + }; + let candidate_receipt2 = { + let mut receipt = dummy_candidate_receipt(block_hash); + receipt.descriptor.para_id = ParaId::from(2_u32); + receipt + }; + let candidate_hash1 = candidate_receipt1.hash(); + let candidate_hash2 = candidate_receipt2.hash(); + let candidate_index1 = 0; + let candidate_index2 = 1; + + let validator1 = ValidatorIndex(0); + let validator2 = ValidatorIndex(1); + let session_index = 1; + + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + ]; + let session_info = SessionInfo { + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2)], + vec![ValidatorIndex(3), ValidatorIndex(4)], + ]), + ..session_info(&validators) + }; + + ChainBuilder::new() + .add_block( + block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { + slot: Slot::from(0), + candidates: Some(vec![ + (candidate_receipt1, CoreIndex(1), GroupIndex(1)), + (candidate_receipt2, CoreIndex(1), GroupIndex(1)), + ]), + session_info: Some(session_info), + }, + ) + .build(&mut virtual_overseer) + .await; + + let assignments = vec![ + (candidate_index1, validator1), + (candidate_index2, validator1), + (candidate_index1, validator2), + (candidate_index2, validator2), + ]; + + for (candidate_index, validator) in assignments { + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator, + ) + .await; + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + } + + let approvals = vec![ + (candidate_index1, validator1, candidate_hash1), + (candidate_index1, validator2, candidate_hash1), + (candidate_index2, validator1, candidate_hash2), + (candidate_index2, validator2, candidate_hash2), + ]; + + for (i, (candidate_index, validator, candidate_hash)) in approvals.iter().enumerate() { + let expect_candidate1_approved = i >= 1; + let expect_candidate2_approved = i >= 3; + let expect_block_approved = expect_candidate2_approved; + + let signature = if *validator == validator1 { + sign_approval(Sr25519Keyring::Alice, *candidate_hash, session_index) + } else { + sign_approval(Sr25519Keyring::Bob, *candidate_hash, session_index) + }; + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + *candidate_index, + *validator, + *candidate_hash, + session_index, + expect_block_approved, + Some(signature), + ) + .await; + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted)); + + // Sleep to get a consistent read on the database. + futures_timer::Delay::new(Duration::from_millis(200)).await; + + let block_entry = store.load_block_entry(&block_hash).unwrap().unwrap(); + assert_eq!(block_entry.is_fully_approved(), expect_block_approved); + assert_eq!( + block_entry.is_candidate_approved(&candidate_hash1), + expect_candidate1_approved + ); + assert_eq!( + block_entry.is_candidate_approved(&candidate_hash2), + expect_candidate2_approved + ); + } + + virtual_overseer + }); +} + +fn approved_ancestor_test( + skip_approval: impl Fn(BlockNumber) -> bool, + approved_height: BlockNumber, +) { + test_harness(HarnessConfig::default(), |test_harness| async move { + let TestHarness { mut virtual_overseer, sync_oracle_handle: _sync_oracle_handle, .. } = + test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hashes = vec![ + Hash::repeat_byte(0x01), + Hash::repeat_byte(0x02), + Hash::repeat_byte(0x03), + Hash::repeat_byte(0x04), + ]; + + let candidate_receipts: Vec<_> = block_hashes + .iter() + .enumerate() + .map(|(i, hash)| { + let mut candidate_receipt = dummy_candidate_receipt(*hash); + candidate_receipt.descriptor.para_id = i.into(); + candidate_receipt + }) + .collect(); + + let candidate_hashes: Vec<_> = candidate_receipts.iter().map(|r| r.hash()).collect(); + + let candidate_index = 0; + let validator = ValidatorIndex(0); + + let mut builder = ChainBuilder::new(); + for (i, (block_hash, candidate_receipt)) in + block_hashes.iter().zip(candidate_receipts).enumerate() + { + let parent_hash = if i == 0 { ChainBuilder::GENESIS_HASH } else { block_hashes[i - 1] }; + builder.add_block( + *block_hash, + parent_hash, + i as u32 + 1, + BlockConfig { + slot: Slot::from(i as u64), + candidates: Some(vec![(candidate_receipt, CoreIndex(0), GroupIndex(0))]), + session_info: None, + }, + ); + } + builder.build(&mut virtual_overseer).await; + + for (i, (block_hash, candidate_hash)) in + block_hashes.iter().zip(candidate_hashes).enumerate() + { + let rx = check_and_import_assignment( + &mut virtual_overseer, + *block_hash, + candidate_index, + validator, + ) + .await; + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + + if skip_approval(i as BlockNumber + 1) { + continue + } + + let rx = check_and_import_approval( + &mut virtual_overseer, + *block_hash, + candidate_index, + validator, + candidate_hash, + i as u32 + 1, + true, + None, + ) + .await; + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted)); + } + + let target = block_hashes[block_hashes.len() - 1]; + let block_number = block_hashes.len(); + + let (tx, rx) = oneshot::channel(); + overseer_send( + &mut virtual_overseer, + FromOrchestra::Communication { + msg: ApprovalVotingMessage::ApprovedAncestor(target, 0, tx), + }, + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::BlockNumber(hash, tx)) => { + assert_eq!(target, hash); + tx.send(Ok(Some(block_number as BlockNumber))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::Ancestors { + hash, + k, + response_channel: tx, + }) => { + assert_eq!(target, hash); + assert_eq!(k, block_number - (0 + 1)); + let ancestors = block_hashes.iter() + .take(block_number-1) + .rev() + .cloned() + .collect::>(); + tx.send(Ok(ancestors)).unwrap(); + } + ); + + let approved_hash = block_hashes[approved_height as usize - 1]; + let HighestApprovedAncestorBlock { hash, number, .. } = rx.await.unwrap().unwrap(); + assert_eq!(approved_hash, hash); + assert_eq!(number, approved_height); + + virtual_overseer + }); +} + +#[test] +fn subsystem_approved_ancestor_all_approved() { + // Don't skip any approvals, highest approved ancestor should be 4. + approved_ancestor_test(|_| false, 4); +} + +#[test] +fn subsystem_approved_ancestor_missing_approval() { + // Skip approval for the third block, highest approved ancestor should be 2. + approved_ancestor_test(|i| i == 3, 2); +} + +#[test] +fn subsystem_validate_approvals_cache() { + let assignment_criteria = Box::new(MockAssignmentCriteria( + || { + let mut assignments = HashMap::new(); + let _ = assignments.insert( + CoreIndex(0), + approval_db::v1::OurAssignment { + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), + tranche: 0, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + assignments + }, + |_| Ok(0), + )); + let config = HarnessConfigBuilder::default().assignment_criteria(assignment_criteria).build(); + let store = config.backend(); + + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle: _sync_oracle_handle } = + test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let fork_block_hash = Hash::repeat_byte(0x02); + let candidate_commitments = CandidateCommitments::default(); + let mut candidate_receipt = dummy_candidate_receipt(block_hash); + candidate_receipt.commitments_hash = candidate_commitments.hash(); + let candidate_hash = candidate_receipt.hash(); + let slot = Slot::from(1); + let candidate_index = 0; + + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + ]; + let session_info = SessionInfo { + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2)], + vec![ValidatorIndex(3), ValidatorIndex(4)], + ]), + ..session_info(&validators) + }; + + let candidates = Some(vec![(candidate_receipt.clone(), CoreIndex(0), GroupIndex(0))]); + ChainBuilder::new() + .add_block( + block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { + slot, + candidates: candidates.clone(), + session_info: Some(session_info.clone()), + }, + ) + .add_block( + fork_block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { slot, candidates, session_info: Some(session_info) }, + ) + .build(&mut virtual_overseer) + .await; + + assert!(!clock.inner.lock().current_wakeup_is(1)); + clock.inner.lock().wakeup_all(1); + + assert!(clock.inner.lock().current_wakeup_is(slot_to_tick(slot))); + clock.inner.lock().wakeup_all(slot_to_tick(slot)); + + futures_timer::Delay::new(Duration::from_millis(200)).await; + + clock.inner.lock().wakeup_all(slot_to_tick(slot + 2)); + + assert_eq!(clock.inner.lock().wakeups.len(), 0); + + futures_timer::Delay::new(Duration::from_millis(200)).await; + + let candidate_entry = store.load_candidate_entry(&candidate_hash).unwrap().unwrap(); + let our_assignment = + candidate_entry.approval_entry(&block_hash).unwrap().our_assignment().unwrap(); + assert!(our_assignment.triggered()); + + // Handle the the next two assignment imports, where only one should trigger approvals work + handle_double_assignment_import(&mut virtual_overseer, candidate_index).await; + + virtual_overseer + }); +} + +/// Ensure that when two assignments are imported, only one triggers the Approval Checking work +async fn handle_double_assignment_import( + virtual_overseer: &mut VirtualOverseer, + candidate_index: CandidateIndex, +) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + c_index, + )) => { + assert_eq!(candidate_index, c_index); + } + ); + + recover_available_data(virtual_overseer).await; + fetch_validation_code(virtual_overseer).await; + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + c_index + )) => { + assert_eq!(candidate_index, c_index); + } + ); + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, timeout, tx)) if timeout == PvfExecTimeoutKind::Approval => { + tx.send(Ok(ValidationResult::Valid(Default::default(), Default::default()))) + .unwrap(); + } + ); + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(_)) + ); + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(_)) + ); + + // Assert that there are no more messages being sent by the subsystem + assert!(overseer_recv(virtual_overseer).timeout(TIMEOUT / 2).await.is_none()); +} + +/// Handles validation code fetch, returns the received relay parent hash. +async fn fetch_validation_code(virtual_overseer: &mut VirtualOverseer) -> Hash { + let validation_code = ValidationCode(Vec::new()); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::ValidationCodeByHash( + _, + tx, + ) + )) => { + tx.send(Ok(Some(validation_code))).unwrap(); + hash + }, + "overseer did not receive runtime API request for validation code", + ) +} + +async fn recover_available_data(virtual_overseer: &mut VirtualOverseer) { + let pov_block = PoV { block_data: BlockData(Vec::new()) }; + + let available_data = + AvailableData { pov: Arc::new(pov_block), validation_data: Default::default() }; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityRecovery( + AvailabilityRecoveryMessage::RecoverAvailableData(_, _, _, tx) + ) => { + tx.send(Ok(available_data)).unwrap(); + }, + "overseer did not receive recover available data message", + ); +} + +struct TriggersAssignmentConfig { + our_assigned_tranche: DelayTranche, + assign_validator_tranche: F1, + no_show_slots: u32, + assignments_to_import: Vec, + approvals_to_import: Vec, + ticks: Vec, + should_be_triggered: F2, +} + +fn triggers_assignment_test(config: TriggersAssignmentConfig) +where + F1: 'static + + Fn(ValidatorIndex) -> Result + + Send + + Sync, + F2: Fn(Tick) -> bool, +{ + let TriggersAssignmentConfig { + our_assigned_tranche, + assign_validator_tranche, + no_show_slots, + assignments_to_import, + approvals_to_import, + ticks, + should_be_triggered, + } = config; + + let assignment_criteria = Box::new(MockAssignmentCriteria( + move || { + let mut assignments = HashMap::new(); + let _ = assignments.insert( + CoreIndex(0), + approval_db::v1::OurAssignment { + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), + tranche: our_assigned_tranche, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + assignments + }, + assign_validator_tranche, + )); + let config = HarnessConfigBuilder::default().assignment_criteria(assignment_criteria).build(); + let store = config.backend(); + + test_harness(config, |test_harness| async move { + let TestHarness { + mut virtual_overseer, + clock, + sync_oracle_handle: _sync_oracle_handle, + .. + } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let candidate_receipt = dummy_candidate_receipt(block_hash); + let candidate_hash = candidate_receipt.hash(); + let slot = Slot::from(1); + let candidate_index = 0; + + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + Sr25519Keyring::Ferdie, + ]; + let session_info = SessionInfo { + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2), ValidatorIndex(3)], + vec![ValidatorIndex(4), ValidatorIndex(5)], + ]), + relay_vrf_modulo_samples: 2, + no_show_slots, + ..session_info(&validators) + }; + + ChainBuilder::new() + .add_block( + block_hash, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { + slot, + candidates: Some(vec![(candidate_receipt, CoreIndex(0), GroupIndex(2))]), + session_info: Some(session_info), + }, + ) + .build(&mut virtual_overseer) + .await; + + for validator in assignments_to_import { + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + ValidatorIndex(validator), + ) + .await; + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + } + + let n_validators = validators.len(); + for (i, &validator_index) in approvals_to_import.iter().enumerate() { + let expect_chain_approved = 3 * (i + 1) > n_validators; + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + ValidatorIndex(validator_index), + candidate_hash, + 1, + expect_chain_approved, + Some(sign_approval(validators[validator_index as usize], candidate_hash, 1)), + ) + .await; + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted)); + } + + let debug = false; + if debug { + step_until_done(&clock).await; + return virtual_overseer + } + + futures_timer::Delay::new(Duration::from_millis(200)).await; + + for tick in ticks { + // Assert that this tick is the next to wake up, requiring the test harness to encode + // all relevant wakeups sequentially. + assert_eq!(Some(tick), clock.inner.lock().next_wakeup()); + + clock.inner.lock().set_tick(tick); + futures_timer::Delay::new(Duration::from_millis(100)).await; + + // Assert that Alice's assignment is triggered at the correct tick. + let candidate_entry = store.load_candidate_entry(&candidate_hash).unwrap().unwrap(); + let our_assignment = + candidate_entry.approval_entry(&block_hash).unwrap().our_assignment().unwrap(); + assert_eq!(our_assignment.triggered(), should_be_triggered(tick), "at tick {:?}", tick); + } + + virtual_overseer + }); +} + +// This method is used to generate a trace for an execution of a triggers_assignment_test given a +// starting configuration. The relevant ticks (all scheduled wakeups) are printed after no further +// ticks are scheduled. To create a valid test, a prefix of the relevant ticks should be included +// in the final test configuration, ending at the tick with the desired inputs to +// should_trigger_assignemnt. +async fn step_until_done(clock: &MockClock) { + let mut relevant_ticks = Vec::new(); + loop { + futures_timer::Delay::new(Duration::from_millis(200)).await; + let mut clock = clock.inner.lock(); + if let Some(tick) = clock.next_wakeup() { + println!("TICK: {:?}", tick); + relevant_ticks.push(tick); + clock.set_tick(tick); + } else { + break + } + } + println!("relevant_ticks: {:?}", relevant_ticks); +} + +#[test] +fn subsystem_process_wakeup_trigger_assignment_launch_approval() { + triggers_assignment_test(TriggersAssignmentConfig { + our_assigned_tranche: 0, + assign_validator_tranche: |_| Ok(0), + no_show_slots: 0, + assignments_to_import: vec![1], + approvals_to_import: vec![1], + ticks: vec![ + 10, // Alice wakeup, assignment triggered + ], + should_be_triggered: |_| true, + }); +} + +#[test] +fn subsystem_assignment_triggered_solo_zero_tranche() { + triggers_assignment_test(TriggersAssignmentConfig { + our_assigned_tranche: 0, + assign_validator_tranche: |_| Ok(0), + no_show_slots: 2, + assignments_to_import: vec![], + approvals_to_import: vec![], + ticks: vec![ + 10, // Alice wakeup, assignment triggered + ], + should_be_triggered: |_| true, + }); +} + +#[test] +fn subsystem_assignment_triggered_by_all_with_less_than_threshold() { + triggers_assignment_test(TriggersAssignmentConfig { + our_assigned_tranche: 11, + assign_validator_tranche: |_| Ok(0), + no_show_slots: 2, + assignments_to_import: vec![1, 2, 3, 4, 5], + approvals_to_import: vec![2, 4], + ticks: vec![ + 2, // APPROVAL_DELAY + 21, // Check for no shows + ], + should_be_triggered: |t| t == 20, + }); +} + +#[test] +fn subsystem_assignment_not_triggered_by_all_with_threshold() { + triggers_assignment_test(TriggersAssignmentConfig { + our_assigned_tranche: 11, + assign_validator_tranche: |_| Ok(0), + no_show_slots: 2, + assignments_to_import: vec![1, 2, 3, 4, 5], + approvals_to_import: vec![1, 3, 5], + ticks: vec![ + 2, // APPROVAL_DELAY + 21, // Check no shows + ], + should_be_triggered: |_| false, + }); +} + +#[test] +fn subsystem_assignment_triggered_if_below_maximum_and_clock_is_equal() { + triggers_assignment_test(TriggersAssignmentConfig { + our_assigned_tranche: 11, + assign_validator_tranche: |_| Ok(0), + no_show_slots: 2, + assignments_to_import: vec![1], + approvals_to_import: vec![], + ticks: vec![ + 21, // Check no shows + 23, // Alice wakeup, assignment triggered + ], + should_be_triggered: |tick| tick >= 21, + }); +} + +#[test] +fn subsystem_assignment_not_triggered_more_than_maximum() { + triggers_assignment_test(TriggersAssignmentConfig { + our_assigned_tranche: 3, + assign_validator_tranche: |_| Ok(0), + no_show_slots: 2, + assignments_to_import: vec![2, 3], + approvals_to_import: vec![], + ticks: vec![ + 2, // APPROVAL_DELAY + 13, // Alice wakeup + 30, // Check no shows + ], + should_be_triggered: |_| false, + }); +} + +#[test] +fn subsystem_assignment_triggered_if_at_maximum() { + triggers_assignment_test(TriggersAssignmentConfig { + our_assigned_tranche: 21, + assign_validator_tranche: |_| Ok(2), + no_show_slots: 2, + assignments_to_import: vec![1], + approvals_to_import: vec![], + ticks: vec![ + 12, // Bob wakeup + 30, // Check no shows + ], + should_be_triggered: |_| false, + }); +} + +#[test] +fn subsystem_assignment_not_triggered_by_exact() { + triggers_assignment_test(TriggersAssignmentConfig { + our_assigned_tranche: 2, + assign_validator_tranche: |_| Ok(1), + no_show_slots: 2, + assignments_to_import: vec![2, 3], + approvals_to_import: vec![], + ticks: vec![ + 11, // Charlie and Dave wakeup + ], + should_be_triggered: |_| false, + }); +} + +#[test] +fn subsystem_assignment_not_triggered_if_at_maximum_but_clock_is_before() { + triggers_assignment_test(TriggersAssignmentConfig { + our_assigned_tranche: 6, + assign_validator_tranche: |validator: ValidatorIndex| Ok(validator.0 as _), + no_show_slots: 0, + assignments_to_import: vec![2, 3, 4], + approvals_to_import: vec![], + ticks: vec![ + 12, // Charlie wakeup + 13, // Dave wakeup + 14, // Eve wakeup + ], + should_be_triggered: |_| false, + }); +} + +#[test] +fn subsystem_assignment_not_triggered_if_at_maximum_but_clock_is_before_with_drift() { + triggers_assignment_test(TriggersAssignmentConfig { + our_assigned_tranche: 5, + assign_validator_tranche: |validator: ValidatorIndex| Ok(validator.0 as _), + no_show_slots: 2, + assignments_to_import: vec![2, 3, 4], + approvals_to_import: vec![], + ticks: vec![ + 12, // Charlie wakeup + 13, // Dave wakeup + 15, // Alice wakeup, noop + 30, // Check no shows + 34, // Eve wakeup + ], + should_be_triggered: |_| false, + }); +} + +#[test] +fn pre_covers_dont_stall_approval() { + // A, B are tranche 0. + // C is tranche 1. + // + // All assignments imported at once, and B, C approvals imported immediately. + // A no-shows, leading to being covered by C. + // Technically, this is an approved block, but it will be approved + // when the no-show timer hits, not as a response to an approval vote. + // + // Note that we have 6 validators, otherwise the 2nd approval triggers + // the >1/3 insta-approval condition. + + let assignment_criteria = Box::new(MockAssignmentCriteria::check_only( + move |validator_index| match validator_index { + ValidatorIndex(0 | 1) => Ok(0), + ValidatorIndex(2) => Ok(1), + ValidatorIndex(_) => Err(criteria::InvalidAssignment( + criteria::InvalidAssignmentReason::ValidatorIndexOutOfBounds, + )), + }, + )); + + let config = HarnessConfigBuilder::default().assignment_criteria(assignment_criteria).build(); + let store = config.backend(); + test_harness(config, |test_harness| async move { + let TestHarness { + mut virtual_overseer, + clock, + sync_oracle_handle: _sync_oracle_handle, + .. + } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let validator_index_a = ValidatorIndex(0); + let validator_index_b = ValidatorIndex(1); + let validator_index_c = ValidatorIndex(2); + + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + Sr25519Keyring::One, + ]; + let session_info = SessionInfo { + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2), ValidatorIndex(5)], + vec![ValidatorIndex(3), ValidatorIndex(4)], + ]), + ..session_info(&validators) + }; + + let candidate_descriptor = make_candidate(ParaId::from(1_u32), &block_hash); + let candidate_hash = candidate_descriptor.hash(); + + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + let slot = Slot::from(1 as u64); + builder.add_block( + block_hash, + head, + 1, + BlockConfig { + slot, + candidates: Some(vec![(candidate_descriptor, CoreIndex(0), GroupIndex(0))]), + session_info: Some(session_info), + }, + ); + builder.build(&mut virtual_overseer).await; + + let candidate_index = 0; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_a, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted),); + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_b, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted),); + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_c, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted),); + + let session_index = 1; + let sig_b = sign_approval(Sr25519Keyring::Bob, candidate_hash, session_index); + + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_b, + candidate_hash, + session_index, + false, + Some(sig_b), + ) + .await; + + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted),); + + let sig_c = sign_approval(Sr25519Keyring::Charlie, candidate_hash, session_index); + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_c, + candidate_hash, + session_index, + false, + Some(sig_c), + ) + .await; + + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted),); + + // Sleep to ensure we get a consistent read on the database. + // + // NOTE: Since the response above occurs before writing to the database, we are somewhat + // breaking the external consistency of the API by reaching into the database directly. + // Under normal operation, this wouldn't be necessary, since all requests are serialized by + // the event loop and we write at the end of each pass. However, if the database write were + // to fail, a downstream subsystem may expect for this candidate to be approved, and + // possibly take further actions on the assumption that the candidate is approved, when + // that may not be the reality from the database's perspective. This could be avoided + // entirely by having replies processed after database writes, but that would constitute a + // larger refactor and incur a performance penalty. + futures_timer::Delay::new(Duration::from_millis(100)).await; + + // The candidate should not be approved. + let candidate_entry = store.load_candidate_entry(&candidate_hash).unwrap().unwrap(); + assert!(!candidate_entry.approval_entry(&block_hash).unwrap().is_approved()); + assert!(clock.inner.lock().current_wakeup_is(2)); + + // Wait for the no-show timer to observe the approval from + // tranche 0 and set a wakeup for tranche 1. + clock.inner.lock().set_tick(30); + + // Sleep to ensure we get a consistent read on the database. + futures_timer::Delay::new(Duration::from_millis(100)).await; + + // The next wakeup should observe the assignment & approval from + // tranche 1, and the no-show from tranche 0 should be immediately covered. + assert_eq!(clock.inner.lock().next_wakeup(), Some(31)); + clock.inner.lock().set_tick(31); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainSelection(ChainSelectionMessage::Approved(b_hash)) => { + assert_eq!(b_hash, block_hash); + } + ); + + // The candidate and block should now be approved. + let candidate_entry = store.load_candidate_entry(&candidate_hash).unwrap().unwrap(); + assert!(candidate_entry.approval_entry(&block_hash).unwrap().is_approved()); + assert!(clock.inner.lock().next_wakeup().is_none()); + + let block_entry = store.load_block_entry(&block_hash).unwrap().unwrap(); + assert!(block_entry.is_fully_approved()); + + virtual_overseer + }); +} + +#[test] +fn waits_until_approving_assignments_are_old_enough() { + // A, B are tranche 0. + + let assignment_criteria = Box::new(MockAssignmentCriteria::check_only(|_| Ok(0))); + + let config = HarnessConfigBuilder::default().assignment_criteria(assignment_criteria).build(); + let store = config.backend(); + test_harness(config, |test_harness| async move { + let TestHarness { + mut virtual_overseer, + clock, + sync_oracle_handle: _sync_oracle_handle, + .. + } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + clock.inner.lock().set_tick(APPROVAL_DELAY); + + let block_hash = Hash::repeat_byte(0x01); + let validator_index_a = ValidatorIndex(0); + let validator_index_b = ValidatorIndex(1); + + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + Sr25519Keyring::One, + ]; + let session_info = SessionInfo { + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2), ValidatorIndex(5)], + vec![ValidatorIndex(3), ValidatorIndex(4)], + ]), + ..session_info(&validators) + }; + + let candidate_descriptor = make_candidate(ParaId::from(1_u32), &block_hash); + let candidate_hash = candidate_descriptor.hash(); + + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + let slot = Slot::from(1 as u64); + builder.add_block( + block_hash, + head, + 1, + BlockConfig { + slot, + candidates: Some(vec![(candidate_descriptor, CoreIndex(0), GroupIndex(0))]), + session_info: Some(session_info), + }, + ); + builder.build(&mut virtual_overseer).await; + + let candidate_index = 0; + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_a, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted),); + + let rx = check_and_import_assignment( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_b, + ) + .await; + + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted),); + + assert!(clock.inner.lock().current_wakeup_is(APPROVAL_DELAY + APPROVAL_DELAY)); + + let session_index = 1; + + let sig_a = sign_approval(Sr25519Keyring::Alice, candidate_hash, session_index); + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_a, + candidate_hash, + session_index, + false, + Some(sig_a), + ) + .await; + + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted),); + + let sig_b = sign_approval(Sr25519Keyring::Bob, candidate_hash, session_index); + + let rx = check_and_import_approval( + &mut virtual_overseer, + block_hash, + candidate_index, + validator_index_b, + candidate_hash, + session_index, + false, + Some(sig_b), + ) + .await; + + assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted),); + + // Sleep to ensure we get a consistent read on the database. + futures_timer::Delay::new(Duration::from_millis(100)).await; + + // The candidate should not be approved, even though at this + // point in time we have 2 assignments and 2 approvals. + // + // This is because the assignments were imported at tick `APPROVAL_DELAY` + // and won't be considered until `APPROVAL_DELAY` more ticks have passed. + let candidate_entry = store.load_candidate_entry(&candidate_hash).unwrap().unwrap(); + assert!(!candidate_entry.approval_entry(&block_hash).unwrap().is_approved()); + assert!(clock.inner.lock().current_wakeup_is(APPROVAL_DELAY + APPROVAL_DELAY)); + + // Trigger the wakeup. + clock.inner.lock().set_tick(APPROVAL_DELAY + APPROVAL_DELAY); + + // Sleep to ensure we get a consistent read on the database. + futures_timer::Delay::new(Duration::from_millis(100)).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainSelection(ChainSelectionMessage::Approved(b_hash)) => { + assert_eq!(b_hash, block_hash); + } + ); + + // The candidate and block should now be approved. + let candidate_entry = store.load_candidate_entry(&candidate_hash).unwrap().unwrap(); + assert!(candidate_entry.approval_entry(&block_hash).unwrap().is_approved()); + assert!(clock.inner.lock().next_wakeup().is_none()); + + let block_entry = store.load_block_entry(&block_hash).unwrap().unwrap(); + assert!(block_entry.is_fully_approved()); + + virtual_overseer + }); +} diff --git a/polkadot/node/core/approval-voting/src/time.rs b/polkadot/node/core/approval-voting/src/time.rs new file mode 100644 index 0000000000000000000000000000000000000000..34132dc22b2338c168dd18a21b31fd812d49229e --- /dev/null +++ b/polkadot/node/core/approval-voting/src/time.rs @@ -0,0 +1,90 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Time utilities for approval voting. + +use futures::prelude::*; +use polkadot_node_primitives::approval::DelayTranche; +use sp_consensus_slots::Slot; +use std::{ + pin::Pin, + time::{Duration, SystemTime}, +}; + +const TICK_DURATION_MILLIS: u64 = 500; + +/// A base unit of time, starting from the Unix epoch, split into half-second intervals. +pub(crate) type Tick = u64; + +/// A clock which allows querying of the current tick as well as +/// waiting for a tick to be reached. +pub(crate) trait Clock { + /// Yields the current tick. + fn tick_now(&self) -> Tick; + + /// Yields a future which concludes when the given tick is reached. + fn wait(&self, tick: Tick) -> Pin + Send + 'static>>; +} + +/// Extension methods for clocks. +pub(crate) trait ClockExt { + fn tranche_now(&self, slot_duration_millis: u64, base_slot: Slot) -> DelayTranche; +} + +impl ClockExt for C { + fn tranche_now(&self, slot_duration_millis: u64, base_slot: Slot) -> DelayTranche { + self.tick_now() + .saturating_sub(slot_number_to_tick(slot_duration_millis, base_slot)) as u32 + } +} + +/// A clock which uses the actual underlying system clock. +pub(crate) struct SystemClock; + +impl Clock for SystemClock { + /// Yields the current tick. + fn tick_now(&self) -> Tick { + match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { + Err(_) => 0, + Ok(d) => d.as_millis() as u64 / TICK_DURATION_MILLIS, + } + } + + /// Yields a future which concludes when the given tick is reached. + fn wait(&self, tick: Tick) -> Pin + Send>> { + let fut = async move { + let now = SystemTime::now(); + let tick_onset = tick_to_time(tick); + if now < tick_onset { + if let Some(until) = tick_onset.duration_since(now).ok() { + futures_timer::Delay::new(until).await; + } + } + }; + + Box::pin(fut) + } +} + +fn tick_to_time(tick: Tick) -> SystemTime { + SystemTime::UNIX_EPOCH + Duration::from_millis(TICK_DURATION_MILLIS * tick) +} + +/// assumes `slot_duration_millis` evenly divided by tick duration. +pub(crate) fn slot_number_to_tick(slot_duration_millis: u64, slot: Slot) -> Tick { + let ticks_per_slot = slot_duration_millis / TICK_DURATION_MILLIS; + u64::from(slot) * ticks_per_slot +} diff --git a/polkadot/node/core/av-store/Cargo.toml b/polkadot/node/core/av-store/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..4861386bfd7aaa17579b5c753486be38faad50dd --- /dev/null +++ b/polkadot/node/core/av-store/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "polkadot-node-core-av-store" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +futures-timer = "3.0.2" +kvdb = "0.13.0" +thiserror = "1.0.31" +gum = { package = "tracing-gum", path = "../../gum" } +bitvec = "1.0.0" + +parity-scale-codec = { version = "3.6.1", features = ["derive"] } +erasure = { package = "polkadot-erasure-coding", path = "../../../erasure-coding" } +polkadot-node-subsystem = {path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-overseer = { path = "../../overseer" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-primitives = { path = "../../primitives" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +polkadot-node-jaeger = { path = "../../jaeger" } + +[dev-dependencies] +log = "0.4.17" +env_logger = "0.9.0" +assert_matches = "1.4.0" +kvdb-memorydb = "0.13.0" + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +parking_lot = "0.12.0" +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/core/av-store/src/lib.rs b/polkadot/node/core/av-store/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..ef7dcecac0755084efbba839d12b532ff0f336cb --- /dev/null +++ b/polkadot/node/core/av-store/src/lib.rs @@ -0,0 +1,1391 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implements a `AvailabilityStoreSubsystem`. + +#![recursion_limit = "256"] +#![warn(missing_docs)] + +use std::{ + collections::{BTreeSet, HashMap, HashSet}, + io, + sync::Arc, + time::{Duration, SystemTime, SystemTimeError, UNIX_EPOCH}, +}; + +use futures::{ + channel::{ + mpsc::{channel, Receiver as MpscReceiver, Sender as MpscSender}, + oneshot, + }, + future, select, FutureExt, SinkExt, StreamExt, +}; +use futures_timer::Delay; +use parity_scale_codec::{Decode, Encode, Error as CodecError, Input}; +use polkadot_node_subsystem_util::database::{DBTransaction, Database}; +use sp_consensus::SyncOracle; + +use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; +use polkadot_node_jaeger as jaeger; +use polkadot_node_primitives::{AvailableData, ErasureChunk}; +use polkadot_node_subsystem::{ + errors::{ChainApiError, RuntimeApiError}, + messages::{AvailabilityStoreMessage, ChainApiMessage, StoreAvailableDataError}, + overseer, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, +}; +use polkadot_node_subsystem_util as util; +use polkadot_primitives::{ + BlockNumber, CandidateEvent, CandidateHash, CandidateReceipt, Hash, Header, ValidatorIndex, +}; + +mod metrics; +pub use self::metrics::*; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &str = "parachain::availability-store"; + +/// The following constants are used under normal conditions: + +const AVAILABLE_PREFIX: &[u8; 9] = b"available"; +const CHUNK_PREFIX: &[u8; 5] = b"chunk"; +const META_PREFIX: &[u8; 4] = b"meta"; +const UNFINALIZED_PREFIX: &[u8; 11] = b"unfinalized"; +const PRUNE_BY_TIME_PREFIX: &[u8; 13] = b"prune_by_time"; + +// We have some keys we want to map to empty values because existence of the key is enough. We use +// this because rocksdb doesn't support empty values. +const TOMBSTONE_VALUE: &[u8] = b" "; + +/// Unavailable blocks are kept for 1 hour. +const KEEP_UNAVAILABLE_FOR: Duration = Duration::from_secs(60 * 60); + +/// Finalized data is kept for 25 hours. +const KEEP_FINALIZED_FOR: Duration = Duration::from_secs(25 * 60 * 60); + +/// The pruning interval. +const PRUNING_INTERVAL: Duration = Duration::from_secs(60 * 5); + +/// Unix time wrapper with big-endian encoding. +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)] +struct BETimestamp(u64); + +impl Encode for BETimestamp { + fn size_hint(&self) -> usize { + std::mem::size_of::() + } + + fn using_encoded R>(&self, f: F) -> R { + f(&self.0.to_be_bytes()) + } +} + +impl Decode for BETimestamp { + fn decode(value: &mut I) -> Result { + <[u8; 8]>::decode(value).map(u64::from_be_bytes).map(Self) + } +} + +impl From for BETimestamp { + fn from(d: Duration) -> Self { + BETimestamp(d.as_secs()) + } +} + +impl Into for BETimestamp { + fn into(self) -> Duration { + Duration::from_secs(self.0) + } +} + +/// [`BlockNumber`] wrapper with big-endian encoding. +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)] +struct BEBlockNumber(BlockNumber); + +impl Encode for BEBlockNumber { + fn size_hint(&self) -> usize { + std::mem::size_of::() + } + + fn using_encoded R>(&self, f: F) -> R { + f(&self.0.to_be_bytes()) + } +} + +impl Decode for BEBlockNumber { + fn decode(value: &mut I) -> Result { + <[u8; std::mem::size_of::()]>::decode(value) + .map(BlockNumber::from_be_bytes) + .map(Self) + } +} + +#[derive(Debug, Encode, Decode)] +enum State { + /// Candidate data was first observed at the given time but is not available in any block. + #[codec(index = 0)] + Unavailable(BETimestamp), + /// The candidate was first observed at the given time and was included in the given list of + /// unfinalized blocks, which may be empty. The timestamp here is not used for pruning. Either + /// one of these blocks will be finalized or the state will regress to `State::Unavailable`, in + /// which case the same timestamp will be reused. Blocks are sorted ascending first by block + /// number and then hash. + #[codec(index = 1)] + Unfinalized(BETimestamp, Vec<(BEBlockNumber, Hash)>), + /// Candidate data has appeared in a finalized block and did so at the given time. + #[codec(index = 2)] + Finalized(BETimestamp), +} + +// Meta information about a candidate. +#[derive(Debug, Encode, Decode)] +struct CandidateMeta { + state: State, + data_available: bool, + chunks_stored: BitVec, +} + +fn query_inner( + db: &Arc, + column: u32, + key: &[u8], +) -> Result, Error> { + match db.get(column, key) { + Ok(Some(raw)) => { + let res = D::decode(&mut &raw[..])?; + Ok(Some(res)) + }, + Ok(None) => Ok(None), + Err(err) => { + gum::warn!(target: LOG_TARGET, ?err, "Error reading from the availability store"); + Err(err.into()) + }, + } +} + +fn write_available_data( + tx: &mut DBTransaction, + config: &Config, + hash: &CandidateHash, + available_data: &AvailableData, +) { + let key = (AVAILABLE_PREFIX, hash).encode(); + + tx.put_vec(config.col_data, &key[..], available_data.encode()); +} + +fn load_available_data( + db: &Arc, + config: &Config, + hash: &CandidateHash, +) -> Result, Error> { + let key = (AVAILABLE_PREFIX, hash).encode(); + + query_inner(db, config.col_data, &key) +} + +fn delete_available_data(tx: &mut DBTransaction, config: &Config, hash: &CandidateHash) { + let key = (AVAILABLE_PREFIX, hash).encode(); + + tx.delete(config.col_data, &key[..]) +} + +fn load_chunk( + db: &Arc, + config: &Config, + candidate_hash: &CandidateHash, + chunk_index: ValidatorIndex, +) -> Result, Error> { + let key = (CHUNK_PREFIX, candidate_hash, chunk_index).encode(); + + query_inner(db, config.col_data, &key) +} + +fn write_chunk( + tx: &mut DBTransaction, + config: &Config, + candidate_hash: &CandidateHash, + chunk_index: ValidatorIndex, + erasure_chunk: &ErasureChunk, +) { + let key = (CHUNK_PREFIX, candidate_hash, chunk_index).encode(); + + tx.put_vec(config.col_data, &key, erasure_chunk.encode()); +} + +fn delete_chunk( + tx: &mut DBTransaction, + config: &Config, + candidate_hash: &CandidateHash, + chunk_index: ValidatorIndex, +) { + let key = (CHUNK_PREFIX, candidate_hash, chunk_index).encode(); + + tx.delete(config.col_data, &key[..]); +} + +fn load_meta( + db: &Arc, + config: &Config, + hash: &CandidateHash, +) -> Result, Error> { + let key = (META_PREFIX, hash).encode(); + + query_inner(db, config.col_meta, &key) +} + +fn write_meta(tx: &mut DBTransaction, config: &Config, hash: &CandidateHash, meta: &CandidateMeta) { + let key = (META_PREFIX, hash).encode(); + + tx.put_vec(config.col_meta, &key, meta.encode()); +} + +fn delete_meta(tx: &mut DBTransaction, config: &Config, hash: &CandidateHash) { + let key = (META_PREFIX, hash).encode(); + tx.delete(config.col_meta, &key[..]) +} + +fn delete_unfinalized_height(tx: &mut DBTransaction, config: &Config, block_number: BlockNumber) { + let prefix = (UNFINALIZED_PREFIX, BEBlockNumber(block_number)).encode(); + tx.delete_prefix(config.col_meta, &prefix); +} + +fn delete_unfinalized_inclusion( + tx: &mut DBTransaction, + config: &Config, + block_number: BlockNumber, + block_hash: &Hash, + candidate_hash: &CandidateHash, +) { + let key = + (UNFINALIZED_PREFIX, BEBlockNumber(block_number), block_hash, candidate_hash).encode(); + + tx.delete(config.col_meta, &key[..]); +} + +fn delete_pruning_key( + tx: &mut DBTransaction, + config: &Config, + t: impl Into, + h: &CandidateHash, +) { + let key = (PRUNE_BY_TIME_PREFIX, t.into(), h).encode(); + tx.delete(config.col_meta, &key); +} + +fn write_pruning_key( + tx: &mut DBTransaction, + config: &Config, + t: impl Into, + h: &CandidateHash, +) { + let t = t.into(); + let key = (PRUNE_BY_TIME_PREFIX, t, h).encode(); + tx.put(config.col_meta, &key, TOMBSTONE_VALUE); +} + +fn finalized_block_range(finalized: BlockNumber) -> (Vec, Vec) { + // We use big-endian encoding to iterate in ascending order. + let start = UNFINALIZED_PREFIX.encode(); + let end = (UNFINALIZED_PREFIX, BEBlockNumber(finalized + 1)).encode(); + + (start, end) +} + +fn write_unfinalized_block_contains( + tx: &mut DBTransaction, + config: &Config, + n: BlockNumber, + h: &Hash, + ch: &CandidateHash, +) { + let key = (UNFINALIZED_PREFIX, BEBlockNumber(n), h, ch).encode(); + tx.put(config.col_meta, &key, TOMBSTONE_VALUE); +} + +fn pruning_range(now: impl Into) -> (Vec, Vec) { + let start = PRUNE_BY_TIME_PREFIX.encode(); + let end = (PRUNE_BY_TIME_PREFIX, BETimestamp(now.into().0 + 1)).encode(); + + (start, end) +} + +fn decode_unfinalized_key(s: &[u8]) -> Result<(BlockNumber, Hash, CandidateHash), CodecError> { + if !s.starts_with(UNFINALIZED_PREFIX) { + return Err("missing magic string".into()) + } + + <(BEBlockNumber, Hash, CandidateHash)>::decode(&mut &s[UNFINALIZED_PREFIX.len()..]) + .map(|(b, h, ch)| (b.0, h, ch)) +} + +fn decode_pruning_key(s: &[u8]) -> Result<(Duration, CandidateHash), CodecError> { + if !s.starts_with(PRUNE_BY_TIME_PREFIX) { + return Err("missing magic string".into()) + } + + <(BETimestamp, CandidateHash)>::decode(&mut &s[PRUNE_BY_TIME_PREFIX.len()..]) + .map(|(t, ch)| (t.into(), ch)) +} + +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum Error { + #[error(transparent)] + RuntimeApi(#[from] RuntimeApiError), + + #[error(transparent)] + ChainApi(#[from] ChainApiError), + + #[error(transparent)] + Erasure(#[from] erasure::Error), + + #[error(transparent)] + Io(#[from] io::Error), + + #[error(transparent)] + Oneshot(#[from] oneshot::Canceled), + + #[error(transparent)] + Subsystem(#[from] SubsystemError), + + #[error("Context signal channel closed")] + ContextChannelClosed, + + #[error(transparent)] + Time(#[from] SystemTimeError), + + #[error(transparent)] + Codec(#[from] CodecError), + + #[error("Custom databases are not supported")] + CustomDatabase, + + #[error("Erasure root does not match expected one")] + InvalidErasureRoot, +} + +impl Error { + /// Determine if the error is irrecoverable + /// or notifying the user via means of logging + /// is sufficient. + fn is_fatal(&self) -> bool { + match self { + Self::Io(_) => true, + Self::Oneshot(_) => true, + Self::CustomDatabase => true, + Self::ContextChannelClosed => true, + _ => false, + } + } +} + +impl Error { + fn trace(&self) { + match self { + // don't spam the log with spurious errors + Self::RuntimeApi(_) | Self::Oneshot(_) => { + gum::debug!(target: LOG_TARGET, err = ?self) + }, + // it's worth reporting otherwise + _ => gum::warn!(target: LOG_TARGET, err = ?self), + } + } +} + +/// Struct holding pruning timing configuration. +/// The only purpose of this structure is to use different timing +/// configurations in production and in testing. +#[derive(Clone)] +struct PruningConfig { + /// How long unavailable data should be kept. + keep_unavailable_for: Duration, + + /// How long finalized data should be kept. + keep_finalized_for: Duration, + + /// How often to perform data pruning. + pruning_interval: Duration, +} + +impl Default for PruningConfig { + fn default() -> Self { + Self { + keep_unavailable_for: KEEP_UNAVAILABLE_FOR, + keep_finalized_for: KEEP_FINALIZED_FOR, + pruning_interval: PRUNING_INTERVAL, + } + } +} + +/// Configuration for the availability store. +#[derive(Debug, Clone, Copy)] +pub struct Config { + /// The column family for availability data and chunks. + pub col_data: u32, + /// The column family for availability store meta information. + pub col_meta: u32, +} + +trait Clock: Send + Sync { + // Returns time since unix epoch. + fn now(&self) -> Result; +} + +struct SystemClock; + +impl Clock for SystemClock { + fn now(&self) -> Result { + SystemTime::now().duration_since(UNIX_EPOCH).map_err(Into::into) + } +} + +/// An implementation of the Availability Store subsystem. +pub struct AvailabilityStoreSubsystem { + pruning_config: PruningConfig, + config: Config, + db: Arc, + known_blocks: KnownUnfinalizedBlocks, + finalized_number: Option, + metrics: Metrics, + clock: Box, + sync_oracle: Box, +} + +impl AvailabilityStoreSubsystem { + /// Create a new `AvailabilityStoreSubsystem` with a given config on disk. + pub fn new( + db: Arc, + config: Config, + sync_oracle: Box, + metrics: Metrics, + ) -> Self { + Self::with_pruning_config_and_clock( + db, + config, + PruningConfig::default(), + Box::new(SystemClock), + sync_oracle, + metrics, + ) + } + + /// Create a new `AvailabilityStoreSubsystem` with a given config on disk. + fn with_pruning_config_and_clock( + db: Arc, + config: Config, + pruning_config: PruningConfig, + clock: Box, + sync_oracle: Box, + metrics: Metrics, + ) -> Self { + Self { + pruning_config, + config, + db, + metrics, + clock, + known_blocks: KnownUnfinalizedBlocks::default(), + sync_oracle, + finalized_number: None, + } + } +} + +/// We keep the hashes and numbers of all unfinalized +/// processed blocks in memory. +#[derive(Default, Debug)] +struct KnownUnfinalizedBlocks { + by_hash: HashSet, + by_number: BTreeSet<(BlockNumber, Hash)>, +} + +impl KnownUnfinalizedBlocks { + /// Check whether the block has been already processed. + fn is_known(&self, hash: &Hash) -> bool { + self.by_hash.contains(hash) + } + + /// Insert a new block into the known set. + fn insert(&mut self, hash: Hash, number: BlockNumber) { + self.by_hash.insert(hash); + self.by_number.insert((number, hash)); + } + + /// Prune all finalized blocks. + fn prune_finalized(&mut self, finalized: BlockNumber) { + // split_off returns everything after the given key, including the key + let split_point = finalized.saturating_add(1); + let mut finalized = self.by_number.split_off(&(split_point, Hash::zero())); + // after split_off `finalized` actually contains unfinalized blocks, we need to swap + std::mem::swap(&mut self.by_number, &mut finalized); + for (_, block) in finalized { + self.by_hash.remove(&block); + } + } +} + +#[overseer::subsystem(AvailabilityStore, error=SubsystemError, prefix=self::overseer)] +impl AvailabilityStoreSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = run::(self, ctx).map(|_| Ok(())).boxed(); + + SpawnedSubsystem { name: "availability-store-subsystem", future } + } +} + +#[overseer::contextbounds(AvailabilityStore, prefix = self::overseer)] +async fn run(mut subsystem: AvailabilityStoreSubsystem, mut ctx: Context) { + let mut next_pruning = Delay::new(subsystem.pruning_config.pruning_interval).fuse(); + // Pruning interval is in the order of minutes so we shouldn't have more than one task running + // at one moment in time, so 10 should be more than enough. + let (mut pruning_result_tx, mut pruning_result_rx) = channel(10); + loop { + let res = run_iteration( + &mut ctx, + &mut subsystem, + &mut next_pruning, + (&mut pruning_result_tx, &mut pruning_result_rx), + ) + .await; + match res { + Err(e) => { + e.trace(); + if e.is_fatal() { + break + } + }, + Ok(true) => { + gum::info!(target: LOG_TARGET, "received `Conclude` signal, exiting"); + break + }, + Ok(false) => continue, + } + } +} + +#[overseer::contextbounds(AvailabilityStore, prefix = self::overseer)] +async fn run_iteration( + ctx: &mut Context, + subsystem: &mut AvailabilityStoreSubsystem, + mut next_pruning: &mut future::Fuse, + (pruning_result_tx, pruning_result_rx): ( + &mut MpscSender>, + &mut MpscReceiver>, + ), +) -> Result { + select! { + incoming = ctx.recv().fuse() => { + match incoming.map_err(|_| Error::ContextChannelClosed)? { + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(true), + FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate { activated, .. }) + ) => { + for activated in activated.into_iter() { + let _timer = subsystem.metrics.time_block_activated(); + process_block_activated(ctx, subsystem, activated.hash).await?; + } + } + FromOrchestra::Signal(OverseerSignal::BlockFinalized(hash, number)) => { + let _timer = subsystem.metrics.time_process_block_finalized(); + + if !subsystem.known_blocks.is_known(&hash) { + // If we haven't processed this block yet, + // make sure we write the metadata about the + // candidates backed in this finalized block. + // Otherwise, we won't be able to store our chunk + // for these candidates. + if !subsystem.sync_oracle.is_major_syncing() { + // If we're major syncing, processing finalized + // blocks might take quite a very long time + // and make the subsystem unresponsive. + process_block_activated(ctx, subsystem, hash).await?; + } + } + subsystem.finalized_number = Some(number); + subsystem.known_blocks.prune_finalized(number); + process_block_finalized( + ctx, + &subsystem, + hash, + number, + ).await?; + } + FromOrchestra::Communication { msg } => { + let _timer = subsystem.metrics.time_process_message(); + process_message(subsystem, msg)?; + } + } + } + _ = next_pruning => { + // It's important to set the delay before calling `prune_all` because an error in `prune_all` + // could lead to the delay not being set again. Then we would never prune anything anymore. + *next_pruning = Delay::new(subsystem.pruning_config.pruning_interval).fuse(); + start_prune_all(ctx, subsystem, pruning_result_tx.clone()).await?; + }, + // Received the prune result and propagate the errors, so that in case of a fatal error + // the main loop of the subsystem can exit graciously. + result = pruning_result_rx.next() => { + if let Some(result) = result { + result?; + } + }, + } + + Ok(false) +} + +// Start prune-all on a separate thread, so that in the case when the operation takes +// longer than expected we don't keep the whole subsystem blocked. +// See: https://github.com/paritytech/polkadot/issues/7237 for more details. +#[overseer::contextbounds(AvailabilityStore, prefix = self::overseer)] +async fn start_prune_all( + ctx: &mut Context, + subsystem: &mut AvailabilityStoreSubsystem, + mut pruning_result_tx: MpscSender>, +) -> Result<(), Error> { + let metrics = subsystem.metrics.clone(); + let db = subsystem.db.clone(); + let config = subsystem.config; + let time_now = subsystem.clock.now()?; + + ctx.spawn_blocking( + "av-store-prunning", + Box::pin(async move { + let _timer = metrics.time_pruning(); + + gum::debug!(target: LOG_TARGET, "Prunning started"); + let result = prune_all(&db, &config, time_now); + + if let Err(err) = pruning_result_tx.send(result).await { + // This usually means that the node is closing down, log it just in case + gum::debug!(target: LOG_TARGET, ?err, "Failed to send prune_all result",); + } + }), + )?; + Ok(()) +} + +#[overseer::contextbounds(AvailabilityStore, prefix = self::overseer)] +async fn process_block_activated( + ctx: &mut Context, + subsystem: &mut AvailabilityStoreSubsystem, + activated: Hash, +) -> Result<(), Error> { + let now = subsystem.clock.now()?; + + let block_header = { + let (tx, rx) = oneshot::channel(); + + ctx.send_message(ChainApiMessage::BlockHeader(activated, tx)).await; + + match rx.await?? { + None => return Ok(()), + Some(n) => n, + } + }; + let block_number = block_header.number; + + let new_blocks = util::determine_new_blocks( + ctx.sender(), + |hash| -> Result { Ok(subsystem.known_blocks.is_known(hash)) }, + activated, + &block_header, + subsystem.finalized_number.unwrap_or(block_number.saturating_sub(1)), + ) + .await?; + + // determine_new_blocks is descending in block height + for (hash, header) in new_blocks.into_iter().rev() { + // it's important to commit the db transactions for a head before the next one is processed + // alternatively, we could utilize the OverlayBackend from approval-voting + let mut tx = DBTransaction::new(); + process_new_head( + ctx, + &subsystem.db, + &mut tx, + &subsystem.config, + &subsystem.pruning_config, + now, + hash, + header, + ) + .await?; + subsystem.known_blocks.insert(hash, block_number); + subsystem.db.write(tx)?; + } + + Ok(()) +} + +#[overseer::contextbounds(AvailabilityStore, prefix = self::overseer)] +async fn process_new_head( + ctx: &mut Context, + db: &Arc, + db_transaction: &mut DBTransaction, + config: &Config, + pruning_config: &PruningConfig, + now: Duration, + hash: Hash, + header: Header, +) -> Result<(), Error> { + let candidate_events = util::request_candidate_events(hash, ctx.sender()).await.await??; + + // We need to request the number of validators based on the parent state, + // as that is the number of validators used to create this block. + let n_validators = + util::request_validators(header.parent_hash, ctx.sender()).await.await??.len(); + + for event in candidate_events { + match event { + CandidateEvent::CandidateBacked(receipt, _head, _core_index, _group_index) => { + note_block_backed( + db, + db_transaction, + config, + pruning_config, + now, + n_validators, + receipt, + )?; + }, + CandidateEvent::CandidateIncluded(receipt, _head, _core_index, _group_index) => { + note_block_included( + db, + db_transaction, + config, + pruning_config, + (header.number, hash), + receipt, + )?; + }, + _ => {}, + } + } + + Ok(()) +} + +fn note_block_backed( + db: &Arc, + db_transaction: &mut DBTransaction, + config: &Config, + pruning_config: &PruningConfig, + now: Duration, + n_validators: usize, + candidate: CandidateReceipt, +) -> Result<(), Error> { + let candidate_hash = candidate.hash(); + + gum::debug!(target: LOG_TARGET, ?candidate_hash, "Candidate backed"); + + if load_meta(db, config, &candidate_hash)?.is_none() { + let meta = CandidateMeta { + state: State::Unavailable(now.into()), + data_available: false, + chunks_stored: bitvec::bitvec![u8, BitOrderLsb0; 0; n_validators], + }; + + let prune_at = now + pruning_config.keep_unavailable_for; + + write_pruning_key(db_transaction, config, prune_at, &candidate_hash); + write_meta(db_transaction, config, &candidate_hash, &meta); + } + + Ok(()) +} + +fn note_block_included( + db: &Arc, + db_transaction: &mut DBTransaction, + config: &Config, + pruning_config: &PruningConfig, + block: (BlockNumber, Hash), + candidate: CandidateReceipt, +) -> Result<(), Error> { + let candidate_hash = candidate.hash(); + + match load_meta(db, config, &candidate_hash)? { + None => { + // This is alarming. We've observed a block being included without ever seeing it + // backed. Warn and ignore. + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + "Candidate included without being backed?", + ); + }, + Some(mut meta) => { + let be_block = (BEBlockNumber(block.0), block.1); + + gum::debug!(target: LOG_TARGET, ?candidate_hash, "Candidate included"); + + meta.state = match meta.state { + State::Unavailable(at) => { + let at_d: Duration = at.into(); + let prune_at = at_d + pruning_config.keep_unavailable_for; + delete_pruning_key(db_transaction, config, prune_at, &candidate_hash); + + State::Unfinalized(at, vec![be_block]) + }, + State::Unfinalized(at, mut within) => { + if let Err(i) = within.binary_search(&be_block) { + within.insert(i, be_block); + State::Unfinalized(at, within) + } else { + return Ok(()) + } + }, + State::Finalized(_at) => { + // This should never happen as a candidate would have to be included after + // finality. + return Ok(()) + }, + }; + + write_unfinalized_block_contains( + db_transaction, + config, + block.0, + &block.1, + &candidate_hash, + ); + write_meta(db_transaction, config, &candidate_hash, &meta); + }, + } + + Ok(()) +} + +macro_rules! peek_num { + ($iter:ident) => { + match $iter.peek() { + Some(Ok((k, _))) => Ok(decode_unfinalized_key(&k[..]).ok().map(|(b, _, _)| b)), + Some(Err(_)) => Err($iter.next().expect("peek returned Some(Err); qed").unwrap_err()), + None => Ok(None), + } + }; +} + +#[overseer::contextbounds(AvailabilityStore, prefix = self::overseer)] +async fn process_block_finalized( + ctx: &mut Context, + subsystem: &AvailabilityStoreSubsystem, + finalized_hash: Hash, + finalized_number: BlockNumber, +) -> Result<(), Error> { + let now = subsystem.clock.now()?; + + let mut next_possible_batch = 0; + loop { + let mut db_transaction = DBTransaction::new(); + let (start_prefix, end_prefix) = finalized_block_range(finalized_number); + + // We have to do some juggling here of the `iter` to make sure it doesn't cross the `.await` + // boundary as it is not `Send`. That is why we create the iterator once within this loop, + // drop it, do an asynchronous request, and then instantiate the exact same iterator again. + let batch_num = { + let mut iter = subsystem + .db + .iter_with_prefix(subsystem.config.col_meta, &start_prefix) + .take_while(|r| r.as_ref().map_or(true, |(k, _v)| &k[..] < &end_prefix[..])) + .peekable(); + + match peek_num!(iter)? { + None => break, // end of iterator. + Some(n) => n, + } + }; + + if batch_num < next_possible_batch { + continue + } // sanity. + next_possible_batch = batch_num + 1; + + let batch_finalized_hash = if batch_num == finalized_number { + finalized_hash + } else { + let (tx, rx) = oneshot::channel(); + ctx.send_message(ChainApiMessage::FinalizedBlockHash(batch_num, tx)).await; + + match rx.await? { + Err(err) => { + gum::warn!( + target: LOG_TARGET, + batch_num, + ?err, + "Failed to retrieve finalized block number.", + ); + + break + }, + Ok(None) => { + gum::warn!( + target: LOG_TARGET, + "Availability store was informed that block #{} is finalized, \ + but chain API has no finalized hash.", + batch_num, + ); + + break + }, + Ok(Some(h)) => h, + } + }; + + let iter = subsystem + .db + .iter_with_prefix(subsystem.config.col_meta, &start_prefix) + .take_while(|r| r.as_ref().map_or(true, |(k, _v)| &k[..] < &end_prefix[..])) + .peekable(); + + let batch = load_all_at_finalized_height(iter, batch_num, batch_finalized_hash)?; + + // Now that we've iterated over the entire batch at this finalized height, + // update the meta. + + delete_unfinalized_height(&mut db_transaction, &subsystem.config, batch_num); + + update_blocks_at_finalized_height(&subsystem, &mut db_transaction, batch, batch_num, now)?; + + // We need to write at the end of the loop so the prefix iterator doesn't pick up the same + // values again in the next iteration. Another unfortunate effect of having to re-initialize + // the iterator. + subsystem.db.write(db_transaction)?; + } + + Ok(()) +} + +// loads all candidates at the finalized height and maps them to `true` if finalized +// and `false` if unfinalized. +fn load_all_at_finalized_height( + mut iter: std::iter::Peekable>>, + block_number: BlockNumber, + finalized_hash: Hash, +) -> io::Result> { + // maps candidate hashes to true if finalized, false otherwise. + let mut candidates = HashMap::new(); + + // Load all candidates that were included at this height. + loop { + match peek_num!(iter)? { + None => break, // end of iterator. + Some(n) if n != block_number => break, // end of batch. + _ => {}, + } + + let (k, _v) = iter.next().expect("`peek` used to check non-empty; qed")?; + let (_, block_hash, candidate_hash) = + decode_unfinalized_key(&k[..]).expect("`peek_num` checks validity of key; qed"); + + if block_hash == finalized_hash { + candidates.insert(candidate_hash, true); + } else { + candidates.entry(candidate_hash).or_insert(false); + } + } + + Ok(candidates) +} + +fn update_blocks_at_finalized_height( + subsystem: &AvailabilityStoreSubsystem, + db_transaction: &mut DBTransaction, + candidates: impl IntoIterator, + block_number: BlockNumber, + now: Duration, +) -> Result<(), Error> { + for (candidate_hash, is_finalized) in candidates { + let mut meta = match load_meta(&subsystem.db, &subsystem.config, &candidate_hash)? { + None => { + gum::warn!( + target: LOG_TARGET, + "Dangling candidate metadata for {}", + candidate_hash, + ); + + continue + }, + Some(c) => c, + }; + + if is_finalized { + // Clear everything else related to this block. We're finalized now! + match meta.state { + State::Finalized(_) => continue, // sanity + State::Unavailable(at) => { + // This is also not going to happen; the very fact that we are + // iterating over the candidate here indicates that `State` should + // be `Unfinalized`. + delete_pruning_key(db_transaction, &subsystem.config, at, &candidate_hash); + }, + State::Unfinalized(_, blocks) => { + for (block_num, block_hash) in blocks.iter().cloned() { + // this exact height is all getting cleared out anyway. + if block_num.0 != block_number { + delete_unfinalized_inclusion( + db_transaction, + &subsystem.config, + block_num.0, + &block_hash, + &candidate_hash, + ); + } + } + }, + } + + meta.state = State::Finalized(now.into()); + + // Write the meta and a pruning record. + write_meta(db_transaction, &subsystem.config, &candidate_hash, &meta); + write_pruning_key( + db_transaction, + &subsystem.config, + now + subsystem.pruning_config.keep_finalized_for, + &candidate_hash, + ); + } else { + meta.state = match meta.state { + State::Finalized(_) => continue, // sanity. + State::Unavailable(_) => continue, // sanity. + State::Unfinalized(at, mut blocks) => { + // Clear out everything at this height. + blocks.retain(|(n, _)| n.0 != block_number); + + // If empty, we need to go back to being unavailable as we aren't + // aware of any blocks this is included in. + if blocks.is_empty() { + let at_d: Duration = at.into(); + let prune_at = at_d + subsystem.pruning_config.keep_unavailable_for; + write_pruning_key( + db_transaction, + &subsystem.config, + prune_at, + &candidate_hash, + ); + State::Unavailable(at) + } else { + State::Unfinalized(at, blocks) + } + }, + }; + + // Update the meta entry. + write_meta(db_transaction, &subsystem.config, &candidate_hash, &meta) + } + } + + Ok(()) +} + +fn process_message( + subsystem: &mut AvailabilityStoreSubsystem, + msg: AvailabilityStoreMessage, +) -> Result<(), Error> { + match msg { + AvailabilityStoreMessage::QueryAvailableData(candidate, tx) => { + let _ = tx.send(load_available_data(&subsystem.db, &subsystem.config, &candidate)?); + }, + AvailabilityStoreMessage::QueryDataAvailability(candidate, tx) => { + let a = load_meta(&subsystem.db, &subsystem.config, &candidate)? + .map_or(false, |m| m.data_available); + let _ = tx.send(a); + }, + AvailabilityStoreMessage::QueryChunk(candidate, validator_index, tx) => { + let _timer = subsystem.metrics.time_get_chunk(); + let _ = + tx.send(load_chunk(&subsystem.db, &subsystem.config, &candidate, validator_index)?); + }, + AvailabilityStoreMessage::QueryChunkSize(candidate, tx) => { + let meta = load_meta(&subsystem.db, &subsystem.config, &candidate)?; + + let validator_index = meta.map_or(None, |meta| meta.chunks_stored.first_one()); + + let maybe_chunk_size = if let Some(validator_index) = validator_index { + load_chunk( + &subsystem.db, + &subsystem.config, + &candidate, + ValidatorIndex(validator_index as u32), + )? + .map(|erasure_chunk| erasure_chunk.chunk.len()) + } else { + None + }; + + let _ = tx.send(maybe_chunk_size); + }, + AvailabilityStoreMessage::QueryAllChunks(candidate, tx) => { + match load_meta(&subsystem.db, &subsystem.config, &candidate)? { + None => { + let _ = tx.send(Vec::new()); + }, + Some(meta) => { + let mut chunks = Vec::new(); + + for (index, _) in meta.chunks_stored.iter().enumerate().filter(|(_, b)| **b) { + let _timer = subsystem.metrics.time_get_chunk(); + match load_chunk( + &subsystem.db, + &subsystem.config, + &candidate, + ValidatorIndex(index as _), + )? { + Some(c) => chunks.push(c), + None => { + gum::warn!( + target: LOG_TARGET, + ?candidate, + index, + "No chunk found for set bit in meta" + ); + }, + } + } + + let _ = tx.send(chunks); + }, + } + }, + AvailabilityStoreMessage::QueryChunkAvailability(candidate, validator_index, tx) => { + let a = load_meta(&subsystem.db, &subsystem.config, &candidate)?.map_or(false, |m| { + *m.chunks_stored.get(validator_index.0 as usize).as_deref().unwrap_or(&false) + }); + let _ = tx.send(a); + }, + AvailabilityStoreMessage::StoreChunk { candidate_hash, chunk, tx } => { + subsystem.metrics.on_chunks_received(1); + let _timer = subsystem.metrics.time_store_chunk(); + + match store_chunk(&subsystem.db, &subsystem.config, candidate_hash, chunk) { + Ok(true) => { + let _ = tx.send(Ok(())); + }, + Ok(false) => { + let _ = tx.send(Err(())); + }, + Err(e) => { + let _ = tx.send(Err(())); + return Err(e) + }, + } + }, + AvailabilityStoreMessage::StoreAvailableData { + candidate_hash, + n_validators, + available_data, + expected_erasure_root, + tx, + } => { + subsystem.metrics.on_chunks_received(n_validators as _); + + let _timer = subsystem.metrics.time_store_available_data(); + + let res = store_available_data( + &subsystem, + candidate_hash, + n_validators as _, + available_data, + expected_erasure_root, + ); + + match res { + Ok(()) => { + let _ = tx.send(Ok(())); + }, + Err(Error::InvalidErasureRoot) => { + let _ = tx.send(Err(StoreAvailableDataError::InvalidErasureRoot)); + return Err(Error::InvalidErasureRoot) + }, + Err(e) => { + // We do not bubble up internal errors to caller subsystems, instead the + // tx channel is dropped and that error is caught by the caller subsystem. + // + // We bubble up the specific error here so `av-store` logs still tell what + // happend. + return Err(e.into()) + }, + } + }, + } + + Ok(()) +} + +// Ok(true) on success, Ok(false) on failure, and Err on internal error. +fn store_chunk( + db: &Arc, + config: &Config, + candidate_hash: CandidateHash, + chunk: ErasureChunk, +) -> Result { + let mut tx = DBTransaction::new(); + + let mut meta = match load_meta(db, config, &candidate_hash)? { + Some(m) => m, + None => return Ok(false), // we weren't informed of this candidate by import events. + }; + + match meta.chunks_stored.get(chunk.index.0 as usize).map(|b| *b) { + Some(true) => return Ok(true), // already stored. + Some(false) => { + meta.chunks_stored.set(chunk.index.0 as usize, true); + + write_chunk(&mut tx, config, &candidate_hash, chunk.index, &chunk); + write_meta(&mut tx, config, &candidate_hash, &meta); + }, + None => return Ok(false), // out of bounds. + } + + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + chunk_index = %chunk.index.0, + "Stored chunk index for candidate.", + ); + + db.write(tx)?; + Ok(true) +} + +// Ok(true) on success, Ok(false) on failure, and Err on internal error. +fn store_available_data( + subsystem: &AvailabilityStoreSubsystem, + candidate_hash: CandidateHash, + n_validators: usize, + available_data: AvailableData, + expected_erasure_root: Hash, +) -> Result<(), Error> { + let mut tx = DBTransaction::new(); + + let mut meta = match load_meta(&subsystem.db, &subsystem.config, &candidate_hash)? { + Some(m) => { + if m.data_available { + return Ok(()) // already stored. + } + + m + }, + None => { + let now = subsystem.clock.now()?; + + // Write a pruning record. + let prune_at = now + subsystem.pruning_config.keep_unavailable_for; + write_pruning_key(&mut tx, &subsystem.config, prune_at, &candidate_hash); + + CandidateMeta { + state: State::Unavailable(now.into()), + data_available: false, + chunks_stored: BitVec::new(), + } + }, + }; + + let erasure_span = jaeger::Span::new(candidate_hash, "erasure-coding") + .with_candidate(candidate_hash) + .with_pov(&available_data.pov); + + // Important note: This check below is critical for consensus and the `backing` subsystem relies + // on it to ensure candidate validity. + let chunks = erasure::obtain_chunks_v1(n_validators, &available_data)?; + let branches = erasure::branches(chunks.as_ref()); + + if branches.root() != expected_erasure_root { + return Err(Error::InvalidErasureRoot) + } + + drop(erasure_span); + + let erasure_chunks = chunks.iter().zip(branches.map(|(proof, _)| proof)).enumerate().map( + |(index, (chunk, proof))| ErasureChunk { + chunk: chunk.clone(), + proof, + index: ValidatorIndex(index as u32), + }, + ); + + for chunk in erasure_chunks { + write_chunk(&mut tx, &subsystem.config, &candidate_hash, chunk.index, &chunk); + } + + meta.data_available = true; + meta.chunks_stored = bitvec::bitvec![u8, BitOrderLsb0; 1; n_validators]; + + write_meta(&mut tx, &subsystem.config, &candidate_hash, &meta); + write_available_data(&mut tx, &subsystem.config, &candidate_hash, &available_data); + + subsystem.db.write(tx)?; + + gum::debug!(target: LOG_TARGET, ?candidate_hash, "Stored data and chunks"); + + Ok(()) +} + +fn prune_all(db: &Arc, config: &Config, now: Duration) -> Result<(), Error> { + let (range_start, range_end) = pruning_range(now); + + let mut tx = DBTransaction::new(); + let iter = db + .iter_with_prefix(config.col_meta, &range_start[..]) + .take_while(|r| r.as_ref().map_or(true, |(k, _v)| &k[..] < &range_end[..])); + + for r in iter { + let (k, _v) = r?; + tx.delete(config.col_meta, &k[..]); + + let (_, candidate_hash) = match decode_pruning_key(&k[..]) { + Ok(m) => m, + Err(_) => continue, // sanity + }; + + delete_meta(&mut tx, config, &candidate_hash); + + // Clean up all attached data of the candidate. + if let Some(meta) = load_meta(db, config, &candidate_hash)? { + // delete available data. + if meta.data_available { + delete_available_data(&mut tx, config, &candidate_hash) + } + + // delete chunks. + for (i, b) in meta.chunks_stored.iter().enumerate() { + if *b { + delete_chunk(&mut tx, config, &candidate_hash, ValidatorIndex(i as _)); + } + } + + // delete unfinalized block references. Pruning references don't need to be + // manually taken care of as we are deleting them as we go in the outer loop. + if let State::Unfinalized(_, blocks) = meta.state { + for (block_number, block_hash) in blocks { + delete_unfinalized_inclusion( + &mut tx, + config, + block_number.0, + &block_hash, + &candidate_hash, + ); + } + } + } + } + + db.write(tx)?; + Ok(()) +} diff --git a/polkadot/node/core/av-store/src/metrics.rs b/polkadot/node/core/av-store/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..bd85b81c8b83e1f97b250596c994aa8ea3ed8699 --- /dev/null +++ b/polkadot/node/core/av-store/src/metrics.rs @@ -0,0 +1,158 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + received_availability_chunks_total: prometheus::Counter, + pruning: prometheus::Histogram, + process_block_finalized: prometheus::Histogram, + block_activated: prometheus::Histogram, + process_message: prometheus::Histogram, + store_available_data: prometheus::Histogram, + store_chunk: prometheus::Histogram, + get_chunk: prometheus::Histogram, +} + +/// Availability metrics. +#[derive(Default, Clone)] +pub struct Metrics(Option); + +impl Metrics { + pub(crate) fn on_chunks_received(&self, count: usize) { + if let Some(metrics) = &self.0 { + // assume usize fits into u64 + let by = u64::try_from(count).unwrap_or_default(); + metrics.received_availability_chunks_total.inc_by(by); + } + } + + /// Provide a timer for `prune_povs` which observes on drop. + pub(crate) fn time_pruning(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.pruning.start_timer()) + } + + /// Provide a timer for `process_block_finalized` which observes on drop. + pub(crate) fn time_process_block_finalized( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.process_block_finalized.start_timer()) + } + + /// Provide a timer for `block_activated` which observes on drop. + pub(crate) fn time_block_activated( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.block_activated.start_timer()) + } + + /// Provide a timer for `process_message` which observes on drop. + pub(crate) fn time_process_message( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.process_message.start_timer()) + } + + /// Provide a timer for `store_available_data` which observes on drop. + pub(crate) fn time_store_available_data( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.store_available_data.start_timer()) + } + + /// Provide a timer for `store_chunk` which observes on drop. + pub(crate) fn time_store_chunk( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.store_chunk.start_timer()) + } + + /// Provide a timer for `get_chunk` which observes on drop. + pub(crate) fn time_get_chunk(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.get_chunk.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + received_availability_chunks_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_received_availability_chunks_total", + "Number of availability chunks received.", + )?, + registry, + )?, + pruning: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_av_store_pruning", + "Time spent within `av_store::prune_all`", + ))?, + registry, + )?, + process_block_finalized: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_av_store_process_block_finalized", + "Time spent within `av_store::process_block_finalized`", + ))?, + registry, + )?, + block_activated: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_av_store_block_activated", + "Time spent within `av_store::process_block_activated`", + ))?, + registry, + )?, + process_message: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_av_store_process_message", + "Time spent within `av_store::process_message`", + ))?, + registry, + )?, + store_available_data: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_av_store_store_available_data", + "Time spent within `av_store::store_available_data`", + ))?, + registry, + )?, + store_chunk: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_av_store_store_chunk", + "Time spent within `av_store::store_chunk`", + ))?, + registry, + )?, + get_chunk: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_av_store_get_chunk", + "Time spent fetching requested chunks.`", + ) + .buckets(vec![ + 0.000625, 0.00125, 0.0025, 0.005, 0.0075, 0.01, 0.025, 0.05, 0.1, 0.25, + 0.5, 1.0, 2.5, 5.0, 10.0, + ]), + )?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/core/av-store/src/tests.rs b/polkadot/node/core/av-store/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..dbccf1401582270cadab9c4078dacc864f31a2d1 --- /dev/null +++ b/polkadot/node/core/av-store/src/tests.rs @@ -0,0 +1,1264 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use assert_matches::assert_matches; +use futures::{channel::oneshot, executor, future, Future}; + +use ::test_helpers::TestCandidateBuilder; +use parking_lot::Mutex; +use polkadot_node_primitives::{AvailableData, BlockData, PoV, Proof}; +use polkadot_node_subsystem::{ + errors::RuntimeApiError, + jaeger, + messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, +}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_node_subsystem_util::{database::Database, TimeoutExt}; +use polkadot_primitives::{ + CandidateHash, CandidateReceipt, CoreIndex, GroupIndex, HeadData, Header, + PersistedValidationData, ValidatorId, +}; +use sp_keyring::Sr25519Keyring; + +mod columns { + pub const DATA: u32 = 0; + pub const META: u32 = 1; + pub const NUM_COLUMNS: u32 = 2; +} + +const TEST_CONFIG: Config = Config { col_data: columns::DATA, col_meta: columns::META }; + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; + +#[derive(Clone)] +struct TestClock { + inner: Arc>, +} + +impl TestClock { + fn now(&self) -> Duration { + *self.inner.lock() + } + + fn inc(&self, by: Duration) { + *self.inner.lock() += by; + } +} + +impl Clock for TestClock { + fn now(&self) -> Result { + Ok(TestClock::now(self)) + } +} + +#[derive(Clone)] +struct TestState { + persisted_validation_data: PersistedValidationData, + pruning_config: PruningConfig, + clock: TestClock, +} + +impl TestState { + // pruning is only polled periodically, so we sometimes need to delay until + // we're sure the subsystem has done pruning. + async fn wait_for_pruning(&self) { + Delay::new(self.pruning_config.pruning_interval * 2).await + } +} + +impl Default for TestState { + fn default() -> Self { + let persisted_validation_data = PersistedValidationData { + parent_head: HeadData(vec![7, 8, 9]), + relay_parent_number: 5, + max_pov_size: 1024, + relay_parent_storage_root: Default::default(), + }; + + let pruning_config = PruningConfig { + keep_unavailable_for: Duration::from_secs(1), + keep_finalized_for: Duration::from_secs(2), + pruning_interval: Duration::from_millis(250), + }; + + let clock = TestClock { inner: Arc::new(Mutex::new(Duration::from_secs(0))) }; + + Self { persisted_validation_data, pruning_config, clock } + } +} + +struct NoSyncOracle; + +impl sp_consensus::SyncOracle for NoSyncOracle { + fn is_major_syncing(&self) -> bool { + false + } + + fn is_offline(&self) -> bool { + unimplemented!("not used") + } +} + +fn test_harness>( + state: TestState, + store: Arc, + test: impl FnOnce(VirtualOverseer) -> T, +) { + let _ = env_logger::builder() + .is_test(true) + .filter(Some("polkadot_node_core_av_store"), log::LevelFilter::Trace) + .filter(Some(LOG_TARGET), log::LevelFilter::Trace) + .try_init(); + + let pool = sp_core::testing::TaskExecutor::new(); + let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); + + let subsystem = AvailabilityStoreSubsystem::with_pruning_config_and_clock( + store, + TEST_CONFIG, + state.pruning_config.clone(), + Box::new(state.clock), + Box::new(NoSyncOracle), + Metrics::default(), + ); + + let subsystem = run(subsystem, context); + + let test_fut = test(virtual_overseer); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )); +} + +const TIMEOUT: Duration = Duration::from_millis(100); + +async fn overseer_send(overseer: &mut VirtualOverseer, msg: AvailabilityStoreMessage) { + gum::trace!(meg = ?msg, "sending message"); + overseer + .send(FromOrchestra::Communication { msg }) + .timeout(TIMEOUT) + .await + .expect(&format!("{:?} is more than enough for sending messages.", TIMEOUT)); +} + +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { + let msg = overseer_recv_with_timeout(overseer, TIMEOUT) + .await + .expect(&format!("{:?} is more than enough to receive messages", TIMEOUT)); + + gum::trace!(msg = ?msg, "received message"); + + msg +} + +async fn overseer_recv_with_timeout( + overseer: &mut VirtualOverseer, + timeout: Duration, +) -> Option { + gum::trace!("waiting for message..."); + overseer.recv().timeout(timeout).await +} + +async fn overseer_signal(overseer: &mut VirtualOverseer, signal: OverseerSignal) { + overseer + .send(FromOrchestra::Signal(signal)) + .timeout(TIMEOUT) + .await + .expect(&format!("{:?} is more than enough for sending signals.", TIMEOUT)); +} + +fn with_tx(db: &Arc, f: impl FnOnce(&mut DBTransaction)) { + let mut tx = DBTransaction::new(); + f(&mut tx); + db.write(tx).unwrap(); +} + +fn candidate_included(receipt: CandidateReceipt) -> CandidateEvent { + CandidateEvent::CandidateIncluded( + receipt, + HeadData::default(), + CoreIndex::default(), + GroupIndex::default(), + ) +} + +#[cfg(test)] +fn test_store() -> Arc { + let db = kvdb_memorydb::create(columns::NUM_COLUMNS); + let db = + polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter::new(db, &[columns::META]); + Arc::new(db) +} + +#[test] +fn runtime_api_error_does_not_stop_the_subsystem() { + let store = test_store(); + + test_harness(TestState::default(), store, |mut virtual_overseer| async move { + let new_leaf = Hash::repeat_byte(0x01); + + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: new_leaf, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let header = Header { + parent_hash: Hash::zero(), + number: 1, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + }; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader( + relay_parent, + tx, + )) => { + assert_eq!(relay_parent, new_leaf); + tx.send(Ok(Some(header))).unwrap(); + } + ); + + // runtime API call fails + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::CandidateEvents(tx), + )) => { + assert_eq!(relay_parent, new_leaf); + #[derive(Debug)] + struct FauxError; + impl std::error::Error for FauxError {} + impl std::fmt::Display for FauxError { + fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + Ok(()) + } + } + tx.send(Err(RuntimeApiError::Execution { + runtime_api_name: "faux", + source: Arc::new(FauxError), + })).unwrap(); + } + ); + + // but that's fine, we're still alive + let (tx, rx) = oneshot::channel(); + let candidate_hash = CandidateHash(Hash::repeat_byte(33)); + let validator_index = ValidatorIndex(5); + let query_chunk = AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx); + + overseer_send(&mut virtual_overseer, query_chunk.into()).await; + + assert!(rx.await.unwrap().is_none()); + virtual_overseer + }); +} + +#[test] +fn store_chunk_works() { + let store = test_store(); + + test_harness(TestState::default(), store.clone(), |mut virtual_overseer| async move { + let candidate_hash = CandidateHash(Hash::repeat_byte(33)); + let validator_index = ValidatorIndex(5); + let n_validators = 10; + + let chunk = ErasureChunk { + chunk: vec![1, 2, 3], + index: validator_index, + proof: Proof::try_from(vec![vec![3, 4, 5]]).unwrap(), + }; + + // Ensure an entry already exists. In reality this would come from watching + // chain events. + with_tx(&store, |tx| { + super::write_meta( + tx, + &TEST_CONFIG, + &candidate_hash, + &CandidateMeta { + data_available: false, + chunks_stored: bitvec::bitvec![u8, BitOrderLsb0; 0; n_validators], + state: State::Unavailable(BETimestamp(0)), + }, + ); + }); + + let (tx, rx) = oneshot::channel(); + + let chunk_msg = + AvailabilityStoreMessage::StoreChunk { candidate_hash, chunk: chunk.clone(), tx }; + + overseer_send(&mut virtual_overseer, chunk_msg).await; + assert_eq!(rx.await.unwrap(), Ok(())); + + let (tx, rx) = oneshot::channel(); + let query_chunk = AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx); + + overseer_send(&mut virtual_overseer, query_chunk).await; + + assert_eq!(rx.await.unwrap().unwrap(), chunk); + virtual_overseer + }); +} + +#[test] +fn store_chunk_does_nothing_if_no_entry_already() { + let store = test_store(); + + test_harness(TestState::default(), store.clone(), |mut virtual_overseer| async move { + let candidate_hash = CandidateHash(Hash::repeat_byte(33)); + let validator_index = ValidatorIndex(5); + + let chunk = ErasureChunk { + chunk: vec![1, 2, 3], + index: validator_index, + proof: Proof::try_from(vec![vec![3, 4, 5]]).unwrap(), + }; + + let (tx, rx) = oneshot::channel(); + + let chunk_msg = + AvailabilityStoreMessage::StoreChunk { candidate_hash, chunk: chunk.clone(), tx }; + + overseer_send(&mut virtual_overseer, chunk_msg).await; + assert_eq!(rx.await.unwrap(), Err(())); + + let (tx, rx) = oneshot::channel(); + let query_chunk = AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx); + + overseer_send(&mut virtual_overseer, query_chunk).await; + + assert!(rx.await.unwrap().is_none()); + virtual_overseer + }); +} + +#[test] +fn query_chunk_checks_meta() { + let store = test_store(); + + test_harness(TestState::default(), store.clone(), |mut virtual_overseer| async move { + let candidate_hash = CandidateHash(Hash::repeat_byte(33)); + let validator_index = ValidatorIndex(5); + let n_validators = 10; + + // Ensure an entry already exists. In reality this would come from watching + // chain events. + with_tx(&store, |tx| { + super::write_meta( + tx, + &TEST_CONFIG, + &candidate_hash, + &CandidateMeta { + data_available: false, + chunks_stored: { + let mut v = bitvec::bitvec![u8, BitOrderLsb0; 0; n_validators]; + v.set(validator_index.0 as usize, true); + v + }, + state: State::Unavailable(BETimestamp(0)), + }, + ); + }); + + let (tx, rx) = oneshot::channel(); + let query_chunk = + AvailabilityStoreMessage::QueryChunkAvailability(candidate_hash, validator_index, tx); + + overseer_send(&mut virtual_overseer, query_chunk.into()).await; + assert!(rx.await.unwrap()); + + let (tx, rx) = oneshot::channel(); + let query_chunk = AvailabilityStoreMessage::QueryChunkAvailability( + candidate_hash, + ValidatorIndex(validator_index.0 + 1), + tx, + ); + + overseer_send(&mut virtual_overseer, query_chunk.into()).await; + assert!(!rx.await.unwrap()); + virtual_overseer + }); +} + +#[test] +fn store_available_data_erasure_mismatch() { + let store = test_store(); + let test_state = TestState::default(); + test_harness(test_state.clone(), store.clone(), |mut virtual_overseer| async move { + let candidate_hash = CandidateHash(Hash::repeat_byte(1)); + let validator_index = ValidatorIndex(5); + let n_validators = 10; + + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; + + let available_data = AvailableData { + pov: Arc::new(pov), + validation_data: test_state.persisted_validation_data.clone(), + }; + let (tx, rx) = oneshot::channel(); + + let block_msg = AvailabilityStoreMessage::StoreAvailableData { + candidate_hash, + n_validators, + available_data: available_data.clone(), + tx, + // A dummy erasure root should lead to failure. + expected_erasure_root: Hash::default(), + }; + + virtual_overseer.send(FromOrchestra::Communication { msg: block_msg }).await; + assert_eq!(rx.await.unwrap(), Err(StoreAvailableDataError::InvalidErasureRoot)); + + assert!(query_available_data(&mut virtual_overseer, candidate_hash).await.is_none()); + + assert!(query_chunk(&mut virtual_overseer, candidate_hash, validator_index) + .await + .is_none()); + + virtual_overseer + }); +} + +#[test] +fn store_block_works() { + let store = test_store(); + let test_state = TestState::default(); + test_harness(test_state.clone(), store.clone(), |mut virtual_overseer| async move { + let candidate_hash = CandidateHash(Hash::repeat_byte(1)); + let validator_index = ValidatorIndex(5); + let n_validators = 10; + + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; + + let available_data = AvailableData { + pov: Arc::new(pov), + validation_data: test_state.persisted_validation_data.clone(), + }; + let (tx, rx) = oneshot::channel(); + + let chunks = erasure::obtain_chunks_v1(10, &available_data).unwrap(); + let mut branches = erasure::branches(chunks.as_ref()); + + let block_msg = AvailabilityStoreMessage::StoreAvailableData { + candidate_hash, + n_validators, + available_data: available_data.clone(), + tx, + expected_erasure_root: branches.root(), + }; + + virtual_overseer.send(FromOrchestra::Communication { msg: block_msg }).await; + assert_eq!(rx.await.unwrap(), Ok(())); + + let pov = query_available_data(&mut virtual_overseer, candidate_hash).await.unwrap(); + assert_eq!(pov, available_data); + + let chunk = query_chunk(&mut virtual_overseer, candidate_hash, validator_index) + .await + .unwrap(); + + let branch = branches.nth(5).unwrap(); + let expected_chunk = ErasureChunk { + chunk: branch.1.to_vec(), + index: ValidatorIndex(5), + proof: Proof::try_from(branch.0).unwrap(), + }; + + assert_eq!(chunk, expected_chunk); + virtual_overseer + }); +} + +#[test] +fn store_pov_and_query_chunk_works() { + let store = test_store(); + let test_state = TestState::default(); + + test_harness(test_state.clone(), store.clone(), |mut virtual_overseer| async move { + let candidate_hash = CandidateHash(Hash::repeat_byte(1)); + let n_validators = 10; + + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; + + let available_data = AvailableData { + pov: Arc::new(pov), + validation_data: test_state.persisted_validation_data.clone(), + }; + + let chunks_expected = + erasure::obtain_chunks_v1(n_validators as _, &available_data).unwrap(); + let branches = erasure::branches(chunks_expected.as_ref()); + + let (tx, rx) = oneshot::channel(); + let block_msg = AvailabilityStoreMessage::StoreAvailableData { + candidate_hash, + n_validators, + available_data, + tx, + expected_erasure_root: branches.root(), + }; + + virtual_overseer.send(FromOrchestra::Communication { msg: block_msg }).await; + + assert_eq!(rx.await.unwrap(), Ok(())); + + for i in 0..n_validators { + let chunk = query_chunk(&mut virtual_overseer, candidate_hash, ValidatorIndex(i as _)) + .await + .unwrap(); + + assert_eq!(chunk.chunk, chunks_expected[i as usize]); + } + virtual_overseer + }); +} + +#[test] +fn query_all_chunks_works() { + let store = test_store(); + let test_state = TestState::default(); + + test_harness(test_state.clone(), store.clone(), |mut virtual_overseer| async move { + // all chunks for hash 1. + // 1 chunk for hash 2. + // 0 chunks for hash 3. + let candidate_hash_1 = CandidateHash(Hash::repeat_byte(1)); + let candidate_hash_2 = CandidateHash(Hash::repeat_byte(2)); + let candidate_hash_3 = CandidateHash(Hash::repeat_byte(3)); + + let n_validators = 10; + + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; + + let available_data = AvailableData { + pov: Arc::new(pov), + validation_data: test_state.persisted_validation_data.clone(), + }; + + { + let chunks_expected = + erasure::obtain_chunks_v1(n_validators as _, &available_data).unwrap(); + let branches = erasure::branches(chunks_expected.as_ref()); + let (tx, rx) = oneshot::channel(); + let block_msg = AvailabilityStoreMessage::StoreAvailableData { + candidate_hash: candidate_hash_1, + n_validators, + available_data, + tx, + expected_erasure_root: branches.root(), + }; + + virtual_overseer.send(FromOrchestra::Communication { msg: block_msg }).await; + assert_eq!(rx.await.unwrap(), Ok(())); + } + + { + with_tx(&store, |tx| { + super::write_meta( + tx, + &TEST_CONFIG, + &candidate_hash_2, + &CandidateMeta { + data_available: false, + chunks_stored: bitvec::bitvec![u8, BitOrderLsb0; 0; n_validators as _], + state: State::Unavailable(BETimestamp(0)), + }, + ); + }); + + let chunk = ErasureChunk { + chunk: vec![1, 2, 3], + index: ValidatorIndex(1), + proof: Proof::try_from(vec![vec![3, 4, 5]]).unwrap(), + }; + + let (tx, rx) = oneshot::channel(); + let store_chunk_msg = AvailabilityStoreMessage::StoreChunk { + candidate_hash: candidate_hash_2, + chunk, + tx, + }; + + virtual_overseer + .send(FromOrchestra::Communication { msg: store_chunk_msg }) + .await; + assert_eq!(rx.await.unwrap(), Ok(())); + } + + { + let (tx, rx) = oneshot::channel(); + + let msg = AvailabilityStoreMessage::QueryAllChunks(candidate_hash_1, tx); + virtual_overseer.send(FromOrchestra::Communication { msg }).await; + assert_eq!(rx.await.unwrap().len(), n_validators as usize); + } + + { + let (tx, rx) = oneshot::channel(); + + let msg = AvailabilityStoreMessage::QueryAllChunks(candidate_hash_2, tx); + virtual_overseer.send(FromOrchestra::Communication { msg }).await; + assert_eq!(rx.await.unwrap().len(), 1); + } + + { + let (tx, rx) = oneshot::channel(); + + let msg = AvailabilityStoreMessage::QueryAllChunks(candidate_hash_3, tx); + virtual_overseer.send(FromOrchestra::Communication { msg }).await; + assert_eq!(rx.await.unwrap().len(), 0); + } + virtual_overseer + }); +} + +#[test] +fn stored_but_not_included_data_is_pruned() { + let store = test_store(); + let test_state = TestState::default(); + + test_harness(test_state.clone(), store.clone(), |mut virtual_overseer| async move { + let candidate_hash = CandidateHash(Hash::repeat_byte(1)); + let n_validators = 10; + + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; + + let available_data = AvailableData { + pov: Arc::new(pov), + validation_data: test_state.persisted_validation_data.clone(), + }; + + let (tx, rx) = oneshot::channel(); + let chunks = erasure::obtain_chunks_v1(n_validators as _, &available_data).unwrap(); + let branches = erasure::branches(chunks.as_ref()); + + let block_msg = AvailabilityStoreMessage::StoreAvailableData { + candidate_hash, + n_validators, + available_data: available_data.clone(), + tx, + expected_erasure_root: branches.root(), + }; + + virtual_overseer.send(FromOrchestra::Communication { msg: block_msg }).await; + + rx.await.unwrap().unwrap(); + + // At this point data should be in the store. + assert_eq!( + query_available_data(&mut virtual_overseer, candidate_hash).await.unwrap(), + available_data, + ); + + // Wait until pruning. + test_state.clock.inc(test_state.pruning_config.keep_unavailable_for); + test_state.wait_for_pruning().await; + + // The block was not included by this point so it should be pruned now. + assert!(query_available_data(&mut virtual_overseer, candidate_hash).await.is_none()); + virtual_overseer + }); +} + +#[test] +fn stored_data_kept_until_finalized() { + let store = test_store(); + let test_state = TestState::default(); + + test_harness(test_state.clone(), store.clone(), |mut virtual_overseer| async move { + let n_validators = 10; + + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; + + let pov_hash = pov.hash(); + + let candidate = TestCandidateBuilder { pov_hash, ..Default::default() }.build(); + + let candidate_hash = candidate.hash(); + + let available_data = AvailableData { + pov: Arc::new(pov), + validation_data: test_state.persisted_validation_data.clone(), + }; + + let parent = Hash::repeat_byte(2); + let block_number = 10; + + let chunks = erasure::obtain_chunks_v1(n_validators as _, &available_data).unwrap(); + let branches = erasure::branches(chunks.as_ref()); + + let (tx, rx) = oneshot::channel(); + let block_msg = AvailabilityStoreMessage::StoreAvailableData { + candidate_hash, + n_validators, + available_data: available_data.clone(), + tx, + expected_erasure_root: branches.root(), + }; + + virtual_overseer.send(FromOrchestra::Communication { msg: block_msg }).await; + + rx.await.unwrap().unwrap(); + + // At this point data should be in the store. + assert_eq!( + query_available_data(&mut virtual_overseer, candidate_hash).await.unwrap(), + available_data, + ); + + let new_leaf = import_leaf( + &mut virtual_overseer, + parent, + block_number, + vec![candidate_included(candidate)], + (0..n_validators).map(|_| Sr25519Keyring::Alice.public().into()).collect(), + ) + .await; + + // Wait until unavailable data would definitely be pruned. + test_state.clock.inc(test_state.pruning_config.keep_unavailable_for * 10); + test_state.wait_for_pruning().await; + + // At this point data should _still_ be in the store. + assert_eq!( + query_available_data(&mut virtual_overseer, candidate_hash).await.unwrap(), + available_data, + ); + + assert!(has_all_chunks(&mut virtual_overseer, candidate_hash, n_validators, true).await); + + overseer_signal( + &mut virtual_overseer, + OverseerSignal::BlockFinalized(new_leaf, block_number), + ) + .await; + + // Wait until unavailable data would definitely be pruned. + test_state.clock.inc(test_state.pruning_config.keep_finalized_for / 2); + test_state.wait_for_pruning().await; + + // At this point data should _still_ be in the store. + assert_eq!( + query_available_data(&mut virtual_overseer, candidate_hash).await.unwrap(), + available_data, + ); + + assert!(has_all_chunks(&mut virtual_overseer, candidate_hash, n_validators, true).await); + + // Wait until it definitely should be gone. + test_state.clock.inc(test_state.pruning_config.keep_finalized_for); + test_state.wait_for_pruning().await; + + // At this point data should be gone from the store. + assert!(query_available_data(&mut virtual_overseer, candidate_hash).await.is_none()); + + assert!(has_all_chunks(&mut virtual_overseer, candidate_hash, n_validators, false).await); + virtual_overseer + }); +} + +#[test] +fn we_dont_miss_anything_if_import_notifications_are_missed() { + let store = test_store(); + let test_state = TestState::default(); + + test_harness(test_state.clone(), store.clone(), |mut virtual_overseer| async move { + let block_hash = Hash::repeat_byte(1); + overseer_signal(&mut virtual_overseer, OverseerSignal::BlockFinalized(block_hash, 1)).await; + + let header = Header { + parent_hash: Hash::repeat_byte(0), + number: 1, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + }; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader( + relay_parent, + tx, + )) => { + assert_eq!(relay_parent, block_hash); + tx.send(Ok(Some(header))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::CandidateEvents(tx), + )) => { + assert_eq!(relay_parent, block_hash); + tx.send(Ok(Vec::new())).unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Validators(tx), + )) => { + assert_eq!(relay_parent, Hash::zero()); + tx.send(Ok(Vec::new())).unwrap(); + } + ); + + let header = Header { + parent_hash: Hash::repeat_byte(3), + number: 4, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + }; + let new_leaf = Hash::repeat_byte(4); + + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: new_leaf, + number: 4, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader( + relay_parent, + tx, + )) => { + assert_eq!(relay_parent, new_leaf); + tx.send(Ok(Some(header))).unwrap(); + } + ); + + let new_heads = vec![ + (Hash::repeat_byte(2), Hash::repeat_byte(1)), + (Hash::repeat_byte(3), Hash::repeat_byte(2)), + (Hash::repeat_byte(4), Hash::repeat_byte(3)), + ]; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::Ancestors { + hash, + k, + response_channel: tx, + }) => { + assert_eq!(hash, new_leaf); + assert_eq!(k, 2); + let _ = tx.send(Ok(vec![ + Hash::repeat_byte(3), + Hash::repeat_byte(2), + ])); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader( + relay_parent, + tx, + )) => { + assert_eq!(relay_parent, Hash::repeat_byte(3)); + tx.send(Ok(Some(Header { + parent_hash: Hash::repeat_byte(2), + number: 3, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + }))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader( + relay_parent, + tx, + )) => { + assert_eq!(relay_parent, Hash::repeat_byte(2)); + tx.send(Ok(Some(Header { + parent_hash: Hash::repeat_byte(1), + number: 2, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + }))).unwrap(); + } + ); + + for (head, parent) in new_heads { + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::CandidateEvents(tx), + )) => { + assert_eq!(relay_parent, head); + tx.send(Ok(Vec::new())).unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Validators(tx), + )) => { + assert_eq!(relay_parent, parent); + tx.send(Ok(Vec::new())).unwrap(); + } + ); + } + + virtual_overseer + }); +} + +#[test] +fn forkfullness_works() { + let store = test_store(); + let test_state = TestState::default(); + + test_harness(test_state.clone(), store.clone(), |mut virtual_overseer| async move { + let n_validators = 10; + let block_number_1 = 5; + let block_number_2 = 5; + let validators: Vec<_> = + (0..n_validators).map(|_| Sr25519Keyring::Alice.public().into()).collect(); + let parent_1 = Hash::repeat_byte(3); + let parent_2 = Hash::repeat_byte(4); + + let pov_1 = PoV { block_data: BlockData(vec![1, 2, 3]) }; + + let pov_1_hash = pov_1.hash(); + + let pov_2 = PoV { block_data: BlockData(vec![4, 5, 6]) }; + + let pov_2_hash = pov_2.hash(); + + let candidate_1 = + TestCandidateBuilder { pov_hash: pov_1_hash, ..Default::default() }.build(); + + let candidate_1_hash = candidate_1.hash(); + + let candidate_2 = + TestCandidateBuilder { pov_hash: pov_2_hash, ..Default::default() }.build(); + + let candidate_2_hash = candidate_2.hash(); + + let available_data_1 = AvailableData { + pov: Arc::new(pov_1), + validation_data: test_state.persisted_validation_data.clone(), + }; + + let available_data_2 = AvailableData { + pov: Arc::new(pov_2), + validation_data: test_state.persisted_validation_data.clone(), + }; + + let chunks = erasure::obtain_chunks_v1(n_validators as _, &available_data_1).unwrap(); + let branches = erasure::branches(chunks.as_ref()); + + let (tx, rx) = oneshot::channel(); + let msg = AvailabilityStoreMessage::StoreAvailableData { + candidate_hash: candidate_1_hash, + n_validators, + available_data: available_data_1.clone(), + tx, + expected_erasure_root: branches.root(), + }; + + virtual_overseer.send(FromOrchestra::Communication { msg }).await; + + rx.await.unwrap().unwrap(); + + let chunks = erasure::obtain_chunks_v1(n_validators as _, &available_data_2).unwrap(); + let branches = erasure::branches(chunks.as_ref()); + + let (tx, rx) = oneshot::channel(); + let msg = AvailabilityStoreMessage::StoreAvailableData { + candidate_hash: candidate_2_hash, + n_validators, + available_data: available_data_2.clone(), + tx, + expected_erasure_root: branches.root(), + }; + + virtual_overseer.send(FromOrchestra::Communication { msg }).await; + + rx.await.unwrap().unwrap(); + + assert_eq!( + query_available_data(&mut virtual_overseer, candidate_1_hash).await.unwrap(), + available_data_1, + ); + + assert_eq!( + query_available_data(&mut virtual_overseer, candidate_2_hash).await.unwrap(), + available_data_2, + ); + + let new_leaf_1 = import_leaf( + &mut virtual_overseer, + parent_1, + block_number_1, + vec![candidate_included(candidate_1)], + validators.clone(), + ) + .await; + + let _new_leaf_2 = import_leaf( + &mut virtual_overseer, + parent_2, + block_number_2, + vec![candidate_included(candidate_2)], + validators.clone(), + ) + .await; + + overseer_signal( + &mut virtual_overseer, + OverseerSignal::BlockFinalized(new_leaf_1, block_number_1), + ) + .await; + + // Data of both candidates should be still present in the DB. + assert_eq!( + query_available_data(&mut virtual_overseer, candidate_1_hash).await.unwrap(), + available_data_1, + ); + + assert_eq!( + query_available_data(&mut virtual_overseer, candidate_2_hash).await.unwrap(), + available_data_2, + ); + + assert!(has_all_chunks(&mut virtual_overseer, candidate_1_hash, n_validators, true).await); + + assert!(has_all_chunks(&mut virtual_overseer, candidate_2_hash, n_validators, true).await); + + // Candidate 2 should now be considered unavailable and will be pruned. + test_state.clock.inc(test_state.pruning_config.keep_unavailable_for); + test_state.wait_for_pruning().await; + + assert_eq!( + query_available_data(&mut virtual_overseer, candidate_1_hash).await.unwrap(), + available_data_1, + ); + + assert!(query_available_data(&mut virtual_overseer, candidate_2_hash).await.is_none()); + + assert!(has_all_chunks(&mut virtual_overseer, candidate_1_hash, n_validators, true).await); + + assert!(has_all_chunks(&mut virtual_overseer, candidate_2_hash, n_validators, false).await); + + // Wait for longer than finalized blocks should be kept for + test_state.clock.inc(test_state.pruning_config.keep_finalized_for); + test_state.wait_for_pruning().await; + + // Everything should be pruned now. + assert!(query_available_data(&mut virtual_overseer, candidate_1_hash).await.is_none()); + + assert!(query_available_data(&mut virtual_overseer, candidate_2_hash).await.is_none()); + + assert!(has_all_chunks(&mut virtual_overseer, candidate_1_hash, n_validators, false).await); + + assert!(has_all_chunks(&mut virtual_overseer, candidate_2_hash, n_validators, false).await); + virtual_overseer + }); +} + +async fn query_available_data( + virtual_overseer: &mut VirtualOverseer, + candidate_hash: CandidateHash, +) -> Option { + let (tx, rx) = oneshot::channel(); + + let query = AvailabilityStoreMessage::QueryAvailableData(candidate_hash, tx); + virtual_overseer.send(FromOrchestra::Communication { msg: query }).await; + + rx.await.unwrap() +} + +async fn query_chunk( + virtual_overseer: &mut VirtualOverseer, + candidate_hash: CandidateHash, + index: ValidatorIndex, +) -> Option { + let (tx, rx) = oneshot::channel(); + + let query = AvailabilityStoreMessage::QueryChunk(candidate_hash, index, tx); + virtual_overseer.send(FromOrchestra::Communication { msg: query }).await; + + rx.await.unwrap() +} + +async fn has_all_chunks( + virtual_overseer: &mut VirtualOverseer, + candidate_hash: CandidateHash, + n_validators: u32, + expect_present: bool, +) -> bool { + for i in 0..n_validators { + if query_chunk(virtual_overseer, candidate_hash, ValidatorIndex(i)).await.is_some() != + expect_present + { + return false + } + } + true +} + +async fn import_leaf( + virtual_overseer: &mut VirtualOverseer, + parent_hash: Hash, + block_number: BlockNumber, + events: Vec, + validators: Vec, +) -> Hash { + let header = Header { + parent_hash, + number: block_number, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + }; + let new_leaf = header.hash(); + + overseer_signal( + virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: new_leaf, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader( + relay_parent, + tx, + )) => { + assert_eq!(relay_parent, new_leaf); + tx.send(Ok(Some(header))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::CandidateEvents(tx), + )) => { + assert_eq!(relay_parent, new_leaf); + tx.send(Ok(events)).unwrap(); + } + ); + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Validators(tx), + )) => { + assert_eq!(relay_parent, parent_hash); + tx.send(Ok(validators)).unwrap(); + } + ); + + new_leaf +} + +#[test] +fn query_chunk_size_works() { + let store = test_store(); + + test_harness(TestState::default(), store.clone(), |mut virtual_overseer| async move { + let candidate_hash = CandidateHash(Hash::repeat_byte(33)); + let validator_index = ValidatorIndex(5); + let n_validators = 10; + + let chunk = ErasureChunk { + chunk: vec![1, 2, 3], + index: validator_index, + proof: Proof::try_from(vec![vec![3, 4, 5]]).unwrap(), + }; + + // Ensure an entry already exists. In reality this would come from watching + // chain events. + with_tx(&store, |tx| { + super::write_meta( + tx, + &TEST_CONFIG, + &candidate_hash, + &CandidateMeta { + data_available: false, + chunks_stored: bitvec::bitvec![u8, BitOrderLsb0; 0; n_validators], + state: State::Unavailable(BETimestamp(0)), + }, + ); + }); + + let (tx, rx) = oneshot::channel(); + + let chunk_msg = + AvailabilityStoreMessage::StoreChunk { candidate_hash, chunk: chunk.clone(), tx }; + + overseer_send(&mut virtual_overseer, chunk_msg).await; + assert_eq!(rx.await.unwrap(), Ok(())); + + let (tx, rx) = oneshot::channel(); + let query_chunk_size = AvailabilityStoreMessage::QueryChunkSize(candidate_hash, tx); + + overseer_send(&mut virtual_overseer, query_chunk_size).await; + + assert_eq!(rx.await.unwrap().unwrap(), chunk.chunk.len()); + virtual_overseer + }); +} diff --git a/polkadot/node/core/backing/Cargo.toml b/polkadot/node/core/backing/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..d611784d7bba26e472deac4b25c5aaf24a5cedac --- /dev/null +++ b/polkadot/node/core/backing/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "polkadot-node-core-backing" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem = {path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +erasure-coding = { package = "polkadot-erasure-coding", path = "../../../erasure-coding" } +statement-table = { package = "polkadot-statement-table", path = "../../../statement-table" } +bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } +gum = { package = "tracing-gum", path = "../../gum" } +thiserror = "1.0.31" +fatality = "0.0.6" + +[dev-dependencies] +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures = { version = "0.3.21", features = ["thread-pool"] } +assert_matches = "1.4.0" +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/core/backing/src/error.rs b/polkadot/node/core/backing/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..d8f9e82d8f4828f7f65c6910f88065a153e32b16 --- /dev/null +++ b/polkadot/node/core/backing/src/error.rs @@ -0,0 +1,123 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use fatality::Nested; +use futures::channel::{mpsc, oneshot}; + +use polkadot_node_subsystem::{ + messages::{StoreAvailableDataError, ValidationFailed}, + RuntimeApiError, SubsystemError, +}; +use polkadot_node_subsystem_util::{runtime, Error as UtilError}; +use polkadot_primitives::{BackedCandidate, ValidationCodeHash}; + +use crate::LOG_TARGET; + +pub type Result = std::result::Result; +pub type FatalResult = std::result::Result; + +/// Errors that can occur in candidate backing. +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + #[fatal] + #[error("Failed to spawn background task")] + FailedToSpawnBackgroundTask, + + #[fatal(forward)] + #[error("Error while accessing runtime information")] + Runtime(#[from] runtime::Error), + + #[fatal] + #[error(transparent)] + BackgroundValidationMpsc(#[from] mpsc::SendError), + + #[error("Candidate is not found")] + CandidateNotFound, + + #[error("Signature is invalid")] + InvalidSignature, + + #[error("Failed to send candidates {0:?}")] + Send(Vec), + + #[error("FetchPoV failed")] + FetchPoV, + + #[error("Fetching validation code by hash failed {0:?}, {1:?}")] + FetchValidationCode(ValidationCodeHash, RuntimeApiError), + + #[error("Fetching Runtime API version failed {0:?}")] + FetchRuntimeApiVersion(RuntimeApiError), + + #[error("No validation code {0:?}")] + NoValidationCode(ValidationCodeHash), + + #[error("Candidate rejected by prospective parachains subsystem")] + RejectedByProspectiveParachains, + + #[error("ValidateFromExhaustive channel closed before receipt")] + ValidateFromExhaustive(#[source] oneshot::Canceled), + + #[error("StoreAvailableData channel closed before receipt")] + StoreAvailableDataChannel(#[source] oneshot::Canceled), + + #[error("RuntimeAPISubsystem channel closed before receipt")] + RuntimeApiUnavailable(#[source] oneshot::Canceled), + + #[error("a channel was closed before receipt in try_join!")] + JoinMultiple(#[source] oneshot::Canceled), + + #[error("Obtaining erasure chunks failed")] + ObtainErasureChunks(#[from] erasure_coding::Error), + + #[error(transparent)] + ValidationFailed(#[from] ValidationFailed), + + #[error(transparent)] + UtilError(#[from] UtilError), + + #[error(transparent)] + SubsystemError(#[from] SubsystemError), + + #[fatal] + #[error(transparent)] + OverseerExited(SubsystemError), + + #[error("Availability store error")] + StoreAvailableData(#[source] StoreAvailableDataError), +} + +/// Utility for eating top level errors and log them. +/// +/// We basically always want to try and continue on error. This utility function is meant to +/// consume top-level errors by simply logging them +pub fn log_error(result: Result<()>) -> std::result::Result<(), FatalError> { + match result.into_nested()? { + Ok(()) => Ok(()), + Err(jfyi) => { + jfyi.log(); + Ok(()) + }, + } +} + +impl JfyiError { + /// Log a `JfyiError`. + pub fn log(self) { + gum::debug!(target: LOG_TARGET, error = ?self); + } +} diff --git a/polkadot/node/core/backing/src/lib.rs b/polkadot/node/core/backing/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..58763e6d80cc1ad31ea07cd2cedb0b4d1d9076c2 --- /dev/null +++ b/polkadot/node/core/backing/src/lib.rs @@ -0,0 +1,2019 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implements the `CandidateBackingSubsystem`. +//! +//! This subsystem maintains the entire responsibility of tracking parachain +//! candidates which can be backed, as well as the issuance of statements +//! about candidates when run on a validator node. +//! +//! There are two types of statements: `Seconded` and `Valid`. +//! `Seconded` implies `Valid`, and nothing should be stated as +//! `Valid` unless its already been `Seconded`. +//! +//! Validators may only second candidates which fall under their own group +//! assignment, and they may only second one candidate per depth per active leaf. +//! Candidates which are stated as either `Second` or `Valid` by a majority of the +//! assigned group of validators may be backed on-chain and proceed to the availability +//! stage. +//! +//! Depth is a concept relating to asynchronous backing, by which validators +//! short sub-chains of candidates are backed and extended off-chain, and then placed +//! asynchronously into blocks of the relay chain as those are authored and as the +//! relay-chain state becomes ready for them. Asynchronous backing allows parachains to +//! grow mostly independently from the state of the relay chain, which gives more time for +//! parachains to be validated and thereby increases performance. +//! +//! Most of the work of asynchronous backing is handled by the Prospective Parachains +//! subsystem. The 'depth' of a parachain block with respect to a relay chain block is +//! a measure of how many parachain blocks are between the most recent included parachain block +//! in the post-state of the relay-chain block and the candidate. For instance, +//! a candidate that descends directly from the most recent parachain block in the relay-chain +//! state has depth 0. The child of that candidate would have depth 1. And so on. +//! +//! The candidate backing subsystem keeps track of a set of 'active leaves' which are the +//! most recent blocks in the relay-chain (which is in fact a tree) which could be built +//! upon. Depth is always measured against active leaves, and the valid relay-parent that +//! each candidate can have is determined by the active leaves. The Prospective Parachains +//! subsystem enforces that the relay-parent increases monotonically, so that logic +//! is not handled here. By communicating with the Prospective Parachains subsystem, +//! this subsystem extrapolates an "implicit view" from the set of currently active leaves, +//! which determines the set of all recent relay-chain block hashes which could be relay-parents +//! for candidates backed in children of the active leaves. +//! +//! In fact, this subsystem relies on the Statement Distribution subsystem to prevent spam +//! by enforcing the rule that each validator may second at most one candidate per depth per +//! active leaf. This bounds the number of candidates that the system needs to consider and +//! is not handled within this subsystem, except for candidates seconded locally. +//! +//! This subsystem also handles relay-chain heads which don't support asynchronous backing. +//! For such active leaves, the only valid relay-parent is the leaf hash itself and the only +//! allowed depth is 0. + +#![deny(unused_crate_dependencies)] + +use std::{ + collections::{BTreeMap, HashMap, HashSet}, + sync::Arc, +}; + +use bitvec::vec::BitVec; +use futures::{ + channel::{mpsc, oneshot}, + future::BoxFuture, + stream::FuturesOrdered, + FutureExt, SinkExt, StreamExt, TryFutureExt, +}; + +use error::{Error, FatalResult}; +use polkadot_node_primitives::{ + minimum_votes, AvailableData, InvalidCandidate, PoV, SignedFullStatementWithPVD, + StatementWithPVD, ValidationResult, +}; +use polkadot_node_subsystem::{ + messages::{ + AvailabilityDistributionMessage, AvailabilityStoreMessage, CanSecondRequest, + CandidateBackingMessage, CandidateValidationMessage, CollatorProtocolMessage, + HypotheticalCandidate, HypotheticalFrontierRequest, IntroduceCandidateRequest, + ProspectiveParachainsMessage, ProvisionableData, ProvisionerMessage, RuntimeApiMessage, + RuntimeApiRequest, StatementDistributionMessage, StoreAvailableDataError, + }, + overseer, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, +}; +use polkadot_node_subsystem_util::{ + self as util, + backing_implicit_view::{FetchError as ImplicitViewFetchError, View as ImplicitView}, + request_from_runtime, request_session_index_for_child, request_validator_groups, + request_validators, + runtime::{prospective_parachains_mode, ProspectiveParachainsMode}, + Validator, +}; +use polkadot_primitives::{ + BackedCandidate, CandidateCommitments, CandidateHash, CandidateReceipt, + CommittedCandidateReceipt, CoreIndex, CoreState, Hash, Id as ParaId, PersistedValidationData, + PvfExecTimeoutKind, SigningContext, ValidationCode, ValidatorId, ValidatorIndex, + ValidatorSignature, ValidityAttestation, +}; +use sp_keystore::KeystorePtr; +use statement_table::{ + generic::AttestedCandidate as TableAttestedCandidate, + v2::{ + SignedStatement as TableSignedStatement, Statement as TableStatement, + Summary as TableSummary, + }, + Config as TableConfig, Context as TableContextTrait, Table, +}; + +mod error; + +mod metrics; +use self::metrics::Metrics; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &str = "parachain::candidate-backing"; + +/// PoV data to validate. +enum PoVData { + /// Already available (from candidate selection). + Ready(Arc), + /// Needs to be fetched from validator (we are checking a signed statement). + FetchFromValidator { + from_validator: ValidatorIndex, + candidate_hash: CandidateHash, + pov_hash: Hash, + }, +} + +enum ValidatedCandidateCommand { + // We were instructed to second the candidate that has been already validated. + Second(BackgroundValidationResult), + // We were instructed to validate the candidate. + Attest(BackgroundValidationResult), + // We were not able to `Attest` because backing validator did not send us the PoV. + AttestNoPoV(CandidateHash), +} + +impl std::fmt::Debug for ValidatedCandidateCommand { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let candidate_hash = self.candidate_hash(); + match *self { + ValidatedCandidateCommand::Second(_) => write!(f, "Second({})", candidate_hash), + ValidatedCandidateCommand::Attest(_) => write!(f, "Attest({})", candidate_hash), + ValidatedCandidateCommand::AttestNoPoV(_) => write!(f, "Attest({})", candidate_hash), + } + } +} + +impl ValidatedCandidateCommand { + fn candidate_hash(&self) -> CandidateHash { + match *self { + ValidatedCandidateCommand::Second(Ok(ref outputs)) => outputs.candidate.hash(), + ValidatedCandidateCommand::Second(Err(ref candidate)) => candidate.hash(), + ValidatedCandidateCommand::Attest(Ok(ref outputs)) => outputs.candidate.hash(), + ValidatedCandidateCommand::Attest(Err(ref candidate)) => candidate.hash(), + ValidatedCandidateCommand::AttestNoPoV(candidate_hash) => candidate_hash, + } + } +} + +/// The candidate backing subsystem. +pub struct CandidateBackingSubsystem { + keystore: KeystorePtr, + metrics: Metrics, +} + +impl CandidateBackingSubsystem { + /// Create a new instance of the `CandidateBackingSubsystem`. + pub fn new(keystore: KeystorePtr, metrics: Metrics) -> Self { + Self { keystore, metrics } + } +} + +#[overseer::subsystem(CandidateBacking, error = SubsystemError, prefix = self::overseer)] +impl CandidateBackingSubsystem +where + Context: Send + Sync, +{ + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = async move { + run(ctx, self.keystore, self.metrics) + .await + .map_err(|e| SubsystemError::with_origin("candidate-backing", e)) + } + .boxed(); + + SpawnedSubsystem { name: "candidate-backing-subsystem", future } + } +} + +struct PerRelayParentState { + prospective_parachains_mode: ProspectiveParachainsMode, + /// The hash of the relay parent on top of which this job is doing it's work. + parent: Hash, + /// The `ParaId` assigned to the local validator at this relay parent. + assignment: Option, + /// The candidates that are backed by enough validators in their group, by hash. + backed: HashSet, + /// The table of candidates and statements under this relay-parent. + table: Table, + /// The table context, including groups. + table_context: TableContext, + /// We issued `Seconded` or `Valid` statements on about these candidates. + issued_statements: HashSet, + /// These candidates are undergoing validation in the background. + awaiting_validation: HashSet, + /// Data needed for retrying in case of `ValidatedCandidateCommand::AttestNoPoV`. + fallbacks: HashMap, +} + +struct PerCandidateState { + persisted_validation_data: PersistedValidationData, + seconded_locally: bool, + para_id: ParaId, + relay_parent: Hash, +} + +struct ActiveLeafState { + prospective_parachains_mode: ProspectiveParachainsMode, + /// The candidates seconded at various depths under this active + /// leaf with respect to parachain id. A candidate can only be + /// seconded when its hypothetical frontier under every active leaf + /// has an empty entry in this map. + /// + /// When prospective parachains are disabled, the only depth + /// which is allowed is 0. + seconded_at_depth: HashMap>, +} + +/// The state of the subsystem. +struct State { + /// The utility for managing the implicit and explicit views in a consistent way. + /// + /// We only feed leaves which have prospective parachains enabled to this view. + implicit_view: ImplicitView, + /// State tracked for all active leaves, whether or not they have prospective parachains + /// enabled. + per_leaf: HashMap, + /// State tracked for all relay-parents backing work is ongoing for. This includes + /// all active leaves. + /// + /// relay-parents fall into one of 3 categories. + /// 1. active leaves which do support prospective parachains + /// 2. active leaves which do not support prospective parachains + /// 3. relay-chain blocks which are ancestors of an active leaf and do support prospective + /// parachains. + /// + /// Relay-chain blocks which don't support prospective parachains are + /// never included in the fragment trees of active leaves which do. + /// + /// While it would be technically possible to support such leaves in + /// fragment trees, it only benefits the transition period when asynchronous + /// backing is being enabled and complicates code complexity. + per_relay_parent: HashMap, + /// State tracked for all candidates relevant to the implicit view. + /// + /// This is guaranteed to have an entry for each candidate with a relay parent in the implicit + /// or explicit view for which a `Seconded` statement has been successfully imported. + per_candidate: HashMap, + /// A cloneable sender which is dispatched to background candidate validation tasks to inform + /// the main task of the result. + background_validation_tx: mpsc::Sender<(Hash, ValidatedCandidateCommand)>, + /// The handle to the keystore used for signing. + keystore: KeystorePtr, +} + +impl State { + fn new( + background_validation_tx: mpsc::Sender<(Hash, ValidatedCandidateCommand)>, + keystore: KeystorePtr, + ) -> Self { + State { + implicit_view: ImplicitView::default(), + per_leaf: HashMap::default(), + per_relay_parent: HashMap::default(), + per_candidate: HashMap::new(), + background_validation_tx, + keystore, + } + } +} + +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn run( + mut ctx: Context, + keystore: KeystorePtr, + metrics: Metrics, +) -> FatalResult<()> { + let (background_validation_tx, mut background_validation_rx) = mpsc::channel(16); + let mut state = State::new(background_validation_tx, keystore); + + loop { + let res = + run_iteration(&mut ctx, &mut state, &metrics, &mut background_validation_rx).await; + + match res { + Ok(()) => break, + Err(e) => crate::error::log_error(Err(e))?, + } + } + + Ok(()) +} + +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn run_iteration( + ctx: &mut Context, + state: &mut State, + metrics: &Metrics, + background_validation_rx: &mut mpsc::Receiver<(Hash, ValidatedCandidateCommand)>, +) -> Result<(), Error> { + loop { + futures::select!( + validated_command = background_validation_rx.next().fuse() => { + if let Some((relay_parent, command)) = validated_command { + handle_validated_candidate_command( + &mut *ctx, + state, + relay_parent, + command, + metrics, + ).await?; + } else { + panic!("background_validation_tx always alive at this point; qed"); + } + } + from_overseer = ctx.recv().fuse() => { + match from_overseer.map_err(Error::OverseerExited)? { + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => { + handle_active_leaves_update( + &mut *ctx, + update, + state, + ).await?; + } + FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {} + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), + FromOrchestra::Communication { msg } => { + handle_communication(&mut *ctx, state, msg, metrics).await?; + } + } + } + ) + } +} + +/// In case a backing validator does not provide a PoV, we need to retry with other backing +/// validators. +/// +/// This is the data needed to accomplish this. Basically all the data needed for spawning a +/// validation job and a list of backing validators, we can try. +#[derive(Clone)] +struct AttestingData { + /// The candidate to attest. + candidate: CandidateReceipt, + /// Hash of the PoV we need to fetch. + pov_hash: Hash, + /// Validator we are currently trying to get the PoV from. + from_validator: ValidatorIndex, + /// Other backing validators we can try in case `from_validator` failed. + backing: Vec, +} + +#[derive(Default)] +struct TableContext { + validator: Option, + groups: HashMap>, + validators: Vec, +} + +impl TableContextTrait for TableContext { + type AuthorityId = ValidatorIndex; + type Digest = CandidateHash; + type GroupId = ParaId; + type Signature = ValidatorSignature; + type Candidate = CommittedCandidateReceipt; + + fn candidate_digest(candidate: &CommittedCandidateReceipt) -> CandidateHash { + candidate.hash() + } + + fn candidate_group(candidate: &CommittedCandidateReceipt) -> ParaId { + candidate.descriptor().para_id + } + + fn is_member_of(&self, authority: &ValidatorIndex, group: &ParaId) -> bool { + self.groups.get(group).map_or(false, |g| g.iter().any(|a| a == authority)) + } + + fn requisite_votes(&self, group: &ParaId) -> usize { + self.groups.get(group).map_or(usize::MAX, |g| minimum_votes(g.len())) + } +} + +// It looks like it's not possible to do an `impl From` given the current state of +// the code. So this does the necessary conversion. +fn primitive_statement_to_table(s: &SignedFullStatementWithPVD) -> TableSignedStatement { + let statement = match s.payload() { + StatementWithPVD::Seconded(c, _) => TableStatement::Seconded(c.clone()), + StatementWithPVD::Valid(h) => TableStatement::Valid(*h), + }; + + TableSignedStatement { + statement, + signature: s.signature().clone(), + sender: s.validator_index(), + } +} + +fn table_attested_to_backed( + attested: TableAttestedCandidate< + ParaId, + CommittedCandidateReceipt, + ValidatorIndex, + ValidatorSignature, + >, + table_context: &TableContext, +) -> Option { + let TableAttestedCandidate { candidate, validity_votes, group_id: para_id } = attested; + + let (ids, validity_votes): (Vec<_>, Vec) = + validity_votes.into_iter().map(|(id, vote)| (id, vote.into())).unzip(); + + let group = table_context.groups.get(¶_id)?; + + let mut validator_indices = BitVec::with_capacity(group.len()); + + validator_indices.resize(group.len(), false); + + // The order of the validity votes in the backed candidate must match + // the order of bits set in the bitfield, which is not necessarily + // the order of the `validity_votes` we got from the table. + let mut vote_positions = Vec::with_capacity(validity_votes.len()); + for (orig_idx, id) in ids.iter().enumerate() { + if let Some(position) = group.iter().position(|x| x == id) { + validator_indices.set(position, true); + vote_positions.push((orig_idx, position)); + } else { + gum::warn!( + target: LOG_TARGET, + "Logic error: Validity vote from table does not correspond to group", + ); + + return None + } + } + vote_positions.sort_by_key(|(_orig, pos_in_group)| *pos_in_group); + + Some(BackedCandidate { + candidate, + validity_votes: vote_positions + .into_iter() + .map(|(pos_in_votes, _pos_in_group)| validity_votes[pos_in_votes].clone()) + .collect(), + validator_indices, + }) +} + +async fn store_available_data( + sender: &mut impl overseer::CandidateBackingSenderTrait, + n_validators: u32, + candidate_hash: CandidateHash, + available_data: AvailableData, + expected_erasure_root: Hash, +) -> Result<(), Error> { + let (tx, rx) = oneshot::channel(); + // Important: the `av-store` subsystem will check if the erasure root of the `available_data` + // matches `expected_erasure_root` which was provided by the collator in the `CandidateReceipt`. + // This check is consensus critical and the `backing` subsystem relies on it for ensuring + // candidate validity. + sender + .send_message(AvailabilityStoreMessage::StoreAvailableData { + candidate_hash, + n_validators, + available_data, + expected_erasure_root, + tx, + }) + .await; + + rx.await + .map_err(Error::StoreAvailableDataChannel)? + .map_err(Error::StoreAvailableData) +} + +// Make a `PoV` available. +// +// This calls the AV store to write the available data to storage. The AV store also checks the +// erasure root matches the `expected_erasure_root`. +// This returns `Err()` on erasure root mismatch or due to any AV store subsystem error. +// +// Otherwise, it returns `Ok(())`. +async fn make_pov_available( + sender: &mut impl overseer::CandidateBackingSenderTrait, + n_validators: usize, + pov: Arc, + candidate_hash: CandidateHash, + validation_data: PersistedValidationData, + expected_erasure_root: Hash, +) -> Result<(), Error> { + store_available_data( + sender, + n_validators as u32, + candidate_hash, + AvailableData { pov, validation_data }, + expected_erasure_root, + ) + .await +} + +async fn request_pov( + sender: &mut impl overseer::CandidateBackingSenderTrait, + relay_parent: Hash, + from_validator: ValidatorIndex, + para_id: ParaId, + candidate_hash: CandidateHash, + pov_hash: Hash, +) -> Result, Error> { + let (tx, rx) = oneshot::channel(); + sender + .send_message(AvailabilityDistributionMessage::FetchPoV { + relay_parent, + from_validator, + para_id, + candidate_hash, + pov_hash, + tx, + }) + .await; + + let pov = rx.await.map_err(|_| Error::FetchPoV)?; + Ok(Arc::new(pov)) +} + +async fn request_candidate_validation( + sender: &mut impl overseer::CandidateBackingSenderTrait, + pvd: PersistedValidationData, + code: ValidationCode, + candidate_receipt: CandidateReceipt, + pov: Arc, +) -> Result { + let (tx, rx) = oneshot::channel(); + + sender + .send_message(CandidateValidationMessage::ValidateFromExhaustive( + pvd, + code, + candidate_receipt, + pov, + PvfExecTimeoutKind::Backing, + tx, + )) + .await; + + match rx.await { + Ok(Ok(validation_result)) => Ok(validation_result), + Ok(Err(err)) => Err(Error::ValidationFailed(err)), + Err(err) => Err(Error::ValidateFromExhaustive(err)), + } +} + +struct BackgroundValidationOutputs { + candidate: CandidateReceipt, + commitments: CandidateCommitments, + persisted_validation_data: PersistedValidationData, +} + +type BackgroundValidationResult = Result; + +struct BackgroundValidationParams { + sender: S, + tx_command: mpsc::Sender<(Hash, ValidatedCandidateCommand)>, + candidate: CandidateReceipt, + relay_parent: Hash, + persisted_validation_data: PersistedValidationData, + pov: PoVData, + n_validators: usize, + make_command: F, +} + +async fn validate_and_make_available( + params: BackgroundValidationParams< + impl overseer::CandidateBackingSenderTrait, + impl Fn(BackgroundValidationResult) -> ValidatedCandidateCommand + Sync, + >, +) -> Result<(), Error> { + let BackgroundValidationParams { + mut sender, + mut tx_command, + candidate, + relay_parent, + persisted_validation_data, + pov, + n_validators, + make_command, + } = params; + + let validation_code = { + let validation_code_hash = candidate.descriptor().validation_code_hash; + let (tx, rx) = oneshot::channel(); + sender + .send_message(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::ValidationCodeByHash(validation_code_hash, tx), + )) + .await; + + let code = rx.await.map_err(Error::RuntimeApiUnavailable)?; + match code { + Err(e) => return Err(Error::FetchValidationCode(validation_code_hash, e)), + Ok(None) => return Err(Error::NoValidationCode(validation_code_hash)), + Ok(Some(c)) => c, + } + }; + + let pov = match pov { + PoVData::Ready(pov) => pov, + PoVData::FetchFromValidator { from_validator, candidate_hash, pov_hash } => + match request_pov( + &mut sender, + relay_parent, + from_validator, + candidate.descriptor.para_id, + candidate_hash, + pov_hash, + ) + .await + { + Err(Error::FetchPoV) => { + tx_command + .send(( + relay_parent, + ValidatedCandidateCommand::AttestNoPoV(candidate.hash()), + )) + .await + .map_err(Error::BackgroundValidationMpsc)?; + return Ok(()) + }, + Err(err) => return Err(err), + Ok(pov) => pov, + }, + }; + + let v = { + request_candidate_validation( + &mut sender, + persisted_validation_data, + validation_code, + candidate.clone(), + pov.clone(), + ) + .await? + }; + + let res = match v { + ValidationResult::Valid(commitments, validation_data) => { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?candidate.hash(), + "Validation successful", + ); + + let erasure_valid = make_pov_available( + &mut sender, + n_validators, + pov.clone(), + candidate.hash(), + validation_data.clone(), + candidate.descriptor.erasure_root, + ) + .await; + + match erasure_valid { + Ok(()) => Ok(BackgroundValidationOutputs { + candidate, + commitments, + persisted_validation_data: validation_data, + }), + Err(Error::StoreAvailableData(StoreAvailableDataError::InvalidErasureRoot)) => { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?candidate.hash(), + actual_commitments = ?commitments, + "Erasure root doesn't match the announced by the candidate receipt", + ); + Err(candidate) + }, + // Bubble up any other error. + Err(e) => return Err(e), + } + }, + ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch) => { + // If validation produces a new set of commitments, we vote the candidate as invalid. + gum::warn!( + target: LOG_TARGET, + candidate_hash = ?candidate.hash(), + "Validation yielded different commitments", + ); + Err(candidate) + }, + ValidationResult::Invalid(reason) => { + gum::warn!( + target: LOG_TARGET, + candidate_hash = ?candidate.hash(), + reason = ?reason, + "Validation yielded an invalid candidate", + ); + Err(candidate) + }, + }; + + tx_command.send((relay_parent, make_command(res))).await.map_err(Into::into) +} + +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn handle_communication( + ctx: &mut Context, + state: &mut State, + message: CandidateBackingMessage, + metrics: &Metrics, +) -> Result<(), Error> { + match message { + CandidateBackingMessage::Second(_relay_parent, candidate, pvd, pov) => { + handle_second_message(ctx, state, candidate, pvd, pov, metrics).await?; + }, + CandidateBackingMessage::Statement(relay_parent, statement) => { + handle_statement_message(ctx, state, relay_parent, statement, metrics).await?; + }, + CandidateBackingMessage::GetBackedCandidates(requested_candidates, tx) => + handle_get_backed_candidates_message(state, requested_candidates, tx, metrics)?, + CandidateBackingMessage::CanSecond(request, tx) => + handle_can_second_request(ctx, state, request, tx).await, + } + + Ok(()) +} + +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn handle_active_leaves_update( + ctx: &mut Context, + update: ActiveLeavesUpdate, + state: &mut State, +) -> Result<(), Error> { + enum LeafHasProspectiveParachains { + Enabled(Result), + Disabled, + } + + // Activate in implicit view before deactivate, per the docs + // on ImplicitView, this is more efficient. + let res = if let Some(leaf) = update.activated { + // Only activate in implicit view if prospective + // parachains are enabled. + let mode = prospective_parachains_mode(ctx.sender(), leaf.hash).await?; + + let leaf_hash = leaf.hash; + Some(( + leaf, + match mode { + ProspectiveParachainsMode::Disabled => LeafHasProspectiveParachains::Disabled, + ProspectiveParachainsMode::Enabled { .. } => LeafHasProspectiveParachains::Enabled( + state.implicit_view.activate_leaf(ctx.sender(), leaf_hash).await.map(|_| mode), + ), + }, + )) + } else { + None + }; + + for deactivated in update.deactivated { + state.per_leaf.remove(&deactivated); + state.implicit_view.deactivate_leaf(deactivated); + } + + // clean up `per_relay_parent` according to ancestry + // of leaves. we do this so we can clean up candidates right after + // as a result. + // + // when prospective parachains are disabled, the implicit view is empty, + // which means we'll clean up everything that's not a leaf - the expected behavior + // for pre-asynchronous backing. + { + let remaining: HashSet<_> = state + .per_leaf + .keys() + .chain(state.implicit_view.all_allowed_relay_parents()) + .collect(); + + state.per_relay_parent.retain(|r, _| remaining.contains(&r)); + } + + // clean up `per_candidate` according to which relay-parents + // are known. + // + // when prospective parachains are disabled, we clean up all candidates + // because we've cleaned up all relay parents. this is correct. + state + .per_candidate + .retain(|_, pc| state.per_relay_parent.contains_key(&pc.relay_parent)); + + // Get relay parents which might be fresh but might be known already + // that are explicit or implicit from the new active leaf. + let (fresh_relay_parents, leaf_mode) = match res { + None => return Ok(()), + Some((leaf, LeafHasProspectiveParachains::Disabled)) => { + // defensive in this case - for enabled, this manifests as an error. + if state.per_leaf.contains_key(&leaf.hash) { + return Ok(()) + } + + state.per_leaf.insert( + leaf.hash, + ActiveLeafState { + prospective_parachains_mode: ProspectiveParachainsMode::Disabled, + // This is empty because the only allowed relay-parent and depth + // when prospective parachains are disabled is the leaf hash and 0, + // respectively. We've just learned about the leaf hash, so we cannot + // have any candidates seconded with it as a relay-parent yet. + seconded_at_depth: HashMap::new(), + }, + ); + + (vec![leaf.hash], ProspectiveParachainsMode::Disabled) + }, + Some((leaf, LeafHasProspectiveParachains::Enabled(Ok(prospective_parachains_mode)))) => { + let fresh_relay_parents = + state.implicit_view.known_allowed_relay_parents_under(&leaf.hash, None); + + // At this point, all candidates outside of the implicit view + // have been cleaned up. For all which remain, which we've seconded, + // we ask the prospective parachains subsystem where they land in the fragment + // tree for the given active leaf. This comprises our `seconded_at_depth`. + + let remaining_seconded = state + .per_candidate + .iter() + .filter(|(_, cd)| cd.seconded_locally) + .map(|(c_hash, cd)| (*c_hash, cd.para_id)); + + // one-to-one correspondence to remaining_seconded + let mut membership_answers = FuturesOrdered::new(); + + for (candidate_hash, para_id) in remaining_seconded { + let (tx, rx) = oneshot::channel(); + membership_answers + .push_back(rx.map_ok(move |membership| (para_id, candidate_hash, membership))); + + ctx.send_message(ProspectiveParachainsMessage::GetTreeMembership( + para_id, + candidate_hash, + tx, + )) + .await; + } + + let mut seconded_at_depth = HashMap::new(); + if let Some(response) = membership_answers.next().await { + match response { + Err(oneshot::Canceled) => { + gum::warn!( + target: LOG_TARGET, + "Prospective parachains subsystem unreachable for membership request", + ); + }, + Ok((para_id, candidate_hash, membership)) => { + // This request gives membership in all fragment trees. We have some + // wasted data here, and it can be optimized if it proves + // relevant to performance. + if let Some((_, depths)) = + membership.into_iter().find(|(leaf_hash, _)| leaf_hash == &leaf.hash) + { + let para_entry: &mut BTreeMap = + seconded_at_depth.entry(para_id).or_default(); + for depth in depths { + para_entry.insert(depth, candidate_hash); + } + } + }, + } + } + + state.per_leaf.insert( + leaf.hash, + ActiveLeafState { prospective_parachains_mode, seconded_at_depth }, + ); + + let fresh_relay_parent = match fresh_relay_parents { + Some(f) => f.to_vec(), + None => { + gum::warn!( + target: LOG_TARGET, + leaf_hash = ?leaf.hash, + "Implicit view gave no relay-parents" + ); + + vec![leaf.hash] + }, + }; + (fresh_relay_parent, prospective_parachains_mode) + }, + Some((leaf, LeafHasProspectiveParachains::Enabled(Err(e)))) => { + gum::debug!( + target: LOG_TARGET, + leaf_hash = ?leaf.hash, + err = ?e, + "Failed to load implicit view for leaf." + ); + + return Ok(()) + }, + }; + + // add entries in `per_relay_parent`. for all new relay-parents. + for maybe_new in fresh_relay_parents { + if state.per_relay_parent.contains_key(&maybe_new) { + continue + } + + let mode = match state.per_leaf.get(&maybe_new) { + None => { + // If the relay-parent isn't a leaf itself, + // then it is guaranteed by the prospective parachains + // subsystem that it is an ancestor of a leaf which + // has prospective parachains enabled and that the + // block itself did. + leaf_mode + }, + Some(l) => l.prospective_parachains_mode, + }; + + // construct a `PerRelayParent` from the runtime API + // and insert it. + let per = construct_per_relay_parent_state(ctx, maybe_new, &state.keystore, mode).await?; + + if let Some(per) = per { + state.per_relay_parent.insert(maybe_new, per); + } + } + + Ok(()) +} + +/// Load the data necessary to do backing work on top of a relay-parent. +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn construct_per_relay_parent_state( + ctx: &mut Context, + relay_parent: Hash, + keystore: &KeystorePtr, + mode: ProspectiveParachainsMode, +) -> Result, Error> { + macro_rules! try_runtime_api { + ($x: expr) => { + match $x { + Ok(x) => x, + Err(e) => { + gum::warn!( + target: LOG_TARGET, + err = ?e, + "Failed to fetch runtime API data for job", + ); + + // We can't do candidate validation work if we don't have the + // requisite runtime API data. But these errors should not take + // down the node. + return Ok(None); + } + } + } + } + + let parent = relay_parent; + + let (validators, groups, session_index, cores) = futures::try_join!( + request_validators(parent, ctx.sender()).await, + request_validator_groups(parent, ctx.sender()).await, + request_session_index_for_child(parent, ctx.sender()).await, + request_from_runtime(parent, ctx.sender(), |tx| { + RuntimeApiRequest::AvailabilityCores(tx) + },) + .await, + ) + .map_err(Error::JoinMultiple)?; + + let validators: Vec<_> = try_runtime_api!(validators); + let (validator_groups, group_rotation_info) = try_runtime_api!(groups); + let session_index = try_runtime_api!(session_index); + let cores = try_runtime_api!(cores); + + let signing_context = SigningContext { parent_hash: parent, session_index }; + let validator = + match Validator::construct(&validators, signing_context.clone(), keystore.clone()) { + Ok(v) => Some(v), + Err(util::Error::NotAValidator) => None, + Err(e) => { + gum::warn!( + target: LOG_TARGET, + err = ?e, + "Cannot participate in candidate backing", + ); + + return Ok(None) + }, + }; + + let mut groups = HashMap::new(); + let n_cores = cores.len(); + let mut assignment = None; + + for (idx, core) in cores.into_iter().enumerate() { + let core_para_id = match core { + CoreState::Scheduled(scheduled) => scheduled.para_id, + CoreState::Occupied(occupied) => + if mode.is_enabled() { + // Async backing makes it legal to build on top of + // occupied core. + occupied.candidate_descriptor.para_id + } else { + continue + }, + CoreState::Free => continue, + }; + + let core_index = CoreIndex(idx as _); + let group_index = group_rotation_info.group_for_core(core_index, n_cores); + if let Some(g) = validator_groups.get(group_index.0 as usize) { + if validator.as_ref().map_or(false, |v| g.contains(&v.index())) { + assignment = Some(core_para_id); + } + groups.insert(core_para_id, g.clone()); + } + } + + let table_context = TableContext { groups, validators, validator }; + let table_config = TableConfig { + allow_multiple_seconded: match mode { + ProspectiveParachainsMode::Enabled { .. } => true, + ProspectiveParachainsMode::Disabled => false, + }, + }; + + Ok(Some(PerRelayParentState { + prospective_parachains_mode: mode, + parent, + assignment, + backed: HashSet::new(), + table: Table::new(table_config), + table_context, + issued_statements: HashSet::new(), + awaiting_validation: HashSet::new(), + fallbacks: HashMap::new(), + })) +} + +enum SecondingAllowed { + No, + Yes(Vec<(Hash, Vec)>), +} + +/// Checks whether a candidate can be seconded based on its hypothetical frontiers in the fragment +/// tree and what we've already seconded in all active leaves. +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn seconding_sanity_check( + ctx: &mut Context, + active_leaves: &HashMap, + implicit_view: &ImplicitView, + hypothetical_candidate: HypotheticalCandidate, + backed_in_path_only: bool, +) -> SecondingAllowed { + let mut membership = Vec::new(); + let mut responses = FuturesOrdered::>>::new(); + + let candidate_para = hypothetical_candidate.candidate_para(); + let candidate_relay_parent = hypothetical_candidate.relay_parent(); + let candidate_hash = hypothetical_candidate.candidate_hash(); + + for (head, leaf_state) in active_leaves { + if leaf_state.prospective_parachains_mode.is_enabled() { + // Check that the candidate relay parent is allowed for para, skip the + // leaf otherwise. + let allowed_parents_for_para = + implicit_view.known_allowed_relay_parents_under(head, Some(candidate_para)); + if !allowed_parents_for_para.unwrap_or_default().contains(&candidate_relay_parent) { + continue + } + + let (tx, rx) = oneshot::channel(); + ctx.send_message(ProspectiveParachainsMessage::GetHypotheticalFrontier( + HypotheticalFrontierRequest { + candidates: vec![hypothetical_candidate.clone()], + fragment_tree_relay_parent: Some(*head), + backed_in_path_only, + }, + tx, + )) + .await; + let response = rx.map_ok(move |frontiers| { + let depths: Vec = frontiers + .into_iter() + .flat_map(|(candidate, memberships)| { + debug_assert_eq!(candidate.candidate_hash(), candidate_hash); + memberships.into_iter().flat_map(|(relay_parent, depths)| { + debug_assert_eq!(relay_parent, *head); + depths + }) + }) + .collect(); + (depths, head, leaf_state) + }); + responses.push_back(response.boxed()); + } else { + if *head == candidate_relay_parent { + if leaf_state + .seconded_at_depth + .get(&candidate_para) + .map_or(false, |occupied| occupied.contains_key(&0)) + { + // The leaf is already occupied. + return SecondingAllowed::No + } + responses.push_back(futures::future::ok((vec![0], head, leaf_state)).boxed()); + } + } + } + + if responses.is_empty() { + return SecondingAllowed::No + } + + while let Some(response) = responses.next().await { + match response { + Err(oneshot::Canceled) => { + gum::warn!( + target: LOG_TARGET, + "Failed to reach prospective parachains subsystem for hypothetical frontiers", + ); + + return SecondingAllowed::No + }, + Ok((depths, head, leaf_state)) => { + for depth in &depths { + if leaf_state + .seconded_at_depth + .get(&candidate_para) + .map_or(false, |occupied| occupied.contains_key(&depth)) + { + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + depth, + leaf_hash = ?head, + "Refusing to second candidate at depth - already occupied." + ); + + return SecondingAllowed::No + } + } + + membership.push((*head, depths)); + }, + } + } + + // At this point we've checked the depths of the candidate against all active + // leaves. + SecondingAllowed::Yes(membership) +} + +/// Performs seconding sanity check for an advertisement. +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn handle_can_second_request( + ctx: &mut Context, + state: &State, + request: CanSecondRequest, + tx: oneshot::Sender, +) { + let relay_parent = request.candidate_relay_parent; + let response = if state + .per_relay_parent + .get(&relay_parent) + .map_or(false, |pr_state| pr_state.prospective_parachains_mode.is_enabled()) + { + let hypothetical_candidate = HypotheticalCandidate::Incomplete { + candidate_hash: request.candidate_hash, + candidate_para: request.candidate_para_id, + parent_head_data_hash: request.parent_head_data_hash, + candidate_relay_parent: relay_parent, + }; + + let result = seconding_sanity_check( + ctx, + &state.per_leaf, + &state.implicit_view, + hypothetical_candidate, + true, + ) + .await; + + match result { + SecondingAllowed::No => false, + SecondingAllowed::Yes(membership) => { + // Candidate should be recognized by at least some fragment tree. + membership.iter().any(|(_, m)| !m.is_empty()) + }, + } + } else { + // Relay parent is unknown or async backing is disabled. + false + }; + + let _ = tx.send(response); +} + +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn handle_validated_candidate_command( + ctx: &mut Context, + state: &mut State, + relay_parent: Hash, + command: ValidatedCandidateCommand, + metrics: &Metrics, +) -> Result<(), Error> { + match state.per_relay_parent.get_mut(&relay_parent) { + Some(rp_state) => { + let candidate_hash = command.candidate_hash(); + rp_state.awaiting_validation.remove(&candidate_hash); + + match command { + ValidatedCandidateCommand::Second(res) => match res { + Ok(outputs) => { + let BackgroundValidationOutputs { + candidate, + commitments, + persisted_validation_data, + } = outputs; + + if rp_state.issued_statements.contains(&candidate_hash) { + return Ok(()) + } + + let receipt = CommittedCandidateReceipt { + descriptor: candidate.descriptor.clone(), + commitments, + }; + + let parent_head_data_hash = persisted_validation_data.parent_head.hash(); + // Note that `GetHypotheticalFrontier` doesn't account for recursion, + // i.e. candidates can appear at multiple depths in the tree and in fact + // at all depths, and we don't know what depths a candidate will ultimately + // occupy because that's dependent on other candidates we haven't yet + // received. + // + // The only way to effectively rule this out is to have candidate receipts + // directly commit to the parachain block number or some other incrementing + // counter. That requires a major primitives format upgrade, so for now + // we just rule out trivial cycles. + if parent_head_data_hash == receipt.commitments.head_data.hash() { + return Ok(()) + } + let hypothetical_candidate = HypotheticalCandidate::Complete { + candidate_hash, + receipt: Arc::new(receipt.clone()), + persisted_validation_data: persisted_validation_data.clone(), + }; + // sanity check that we're allowed to second the candidate + // and that it doesn't conflict with other candidates we've + // seconded. + let fragment_tree_membership = match seconding_sanity_check( + ctx, + &state.per_leaf, + &state.implicit_view, + hypothetical_candidate, + false, + ) + .await + { + SecondingAllowed::No => return Ok(()), + SecondingAllowed::Yes(membership) => membership, + }; + + let statement = + StatementWithPVD::Seconded(receipt, persisted_validation_data); + + // If we get an Error::RejectedByProspectiveParachains, + // then the statement has not been distributed or imported into + // the table. + let res = sign_import_and_distribute_statement( + ctx, + rp_state, + &mut state.per_candidate, + statement, + state.keystore.clone(), + metrics, + ) + .await; + + if let Err(Error::RejectedByProspectiveParachains) = res { + let candidate_hash = candidate.hash(); + gum::debug!( + target: LOG_TARGET, + relay_parent = ?candidate.descriptor().relay_parent, + ?candidate_hash, + "Attempted to second candidate but was rejected by prospective parachains", + ); + + // Ensure the collator is reported. + ctx.send_message(CollatorProtocolMessage::Invalid( + candidate.descriptor().relay_parent, + candidate, + )) + .await; + + return Ok(()) + } + + if let Some(stmt) = res? { + match state.per_candidate.get_mut(&candidate_hash) { + None => { + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + "Missing `per_candidate` for seconded candidate.", + ); + }, + Some(p) => p.seconded_locally = true, + } + + // update seconded depths in active leaves. + for (leaf, depths) in fragment_tree_membership { + let leaf_data = match state.per_leaf.get_mut(&leaf) { + None => { + gum::warn!( + target: LOG_TARGET, + leaf_hash = ?leaf, + "Missing `per_leaf` for known active leaf." + ); + + continue + }, + Some(d) => d, + }; + + let seconded_at_depth = leaf_data + .seconded_at_depth + .entry(candidate.descriptor().para_id) + .or_default(); + + for depth in depths { + seconded_at_depth.insert(depth, candidate_hash); + } + } + + rp_state.issued_statements.insert(candidate_hash); + + metrics.on_candidate_seconded(); + ctx.send_message(CollatorProtocolMessage::Seconded( + rp_state.parent, + StatementWithPVD::drop_pvd_from_signed(stmt), + )) + .await; + } + }, + Err(candidate) => { + ctx.send_message(CollatorProtocolMessage::Invalid( + rp_state.parent, + candidate, + )) + .await; + }, + }, + ValidatedCandidateCommand::Attest(res) => { + // We are done - avoid new validation spawns: + rp_state.fallbacks.remove(&candidate_hash); + // sanity check. + if !rp_state.issued_statements.contains(&candidate_hash) { + if res.is_ok() { + let statement = StatementWithPVD::Valid(candidate_hash); + + sign_import_and_distribute_statement( + ctx, + rp_state, + &mut state.per_candidate, + statement, + state.keystore.clone(), + metrics, + ) + .await?; + } + rp_state.issued_statements.insert(candidate_hash); + } + }, + ValidatedCandidateCommand::AttestNoPoV(candidate_hash) => { + if let Some(attesting) = rp_state.fallbacks.get_mut(&candidate_hash) { + if let Some(index) = attesting.backing.pop() { + attesting.from_validator = index; + let attesting = attesting.clone(); + + // The candidate state should be available because we've + // validated it before, the relay-parent is still around, + // and candidates are pruned on the basis of relay-parents. + // + // If it's not, then no point in validating it anyway. + if let Some(pvd) = state + .per_candidate + .get(&candidate_hash) + .map(|pc| pc.persisted_validation_data.clone()) + { + kick_off_validation_work( + ctx, + rp_state, + pvd, + &state.background_validation_tx, + attesting, + ) + .await?; + } + } + } else { + gum::warn!( + target: LOG_TARGET, + "AttestNoPoV was triggered without fallback being available." + ); + debug_assert!(false); + } + }, + } + }, + None => { + // simple race condition; can be ignored = this relay-parent + // is no longer relevant. + }, + } + + Ok(()) +} + +fn sign_statement( + rp_state: &PerRelayParentState, + statement: StatementWithPVD, + keystore: KeystorePtr, + metrics: &Metrics, +) -> Option { + let signed = rp_state + .table_context + .validator + .as_ref()? + .sign(keystore, statement) + .ok() + .flatten()?; + metrics.on_statement_signed(); + Some(signed) +} + +/// Import a statement into the statement table and return the summary of the import. +/// +/// This will fail with `Error::RejectedByProspectiveParachains` if the message type +/// is seconded, the candidate is fresh, +/// and any of the following are true: +/// 1. There is no `PersistedValidationData` attached. +/// 2. Prospective parachains are enabled for the relay parent and the prospective parachains +/// subsystem returned an empty `FragmentTreeMembership` i.e. did not recognize the candidate as +/// being applicable to any of the active leaves. +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn import_statement( + ctx: &mut Context, + rp_state: &mut PerRelayParentState, + per_candidate: &mut HashMap, + statement: &SignedFullStatementWithPVD, +) -> Result, Error> { + gum::debug!( + target: LOG_TARGET, + statement = ?statement.payload().to_compact(), + validator_index = statement.validator_index().0, + "Importing statement", + ); + + let candidate_hash = statement.payload().candidate_hash(); + + // If this is a new candidate (statement is 'seconded' and candidate is unknown), + // we need to create an entry in the `PerCandidateState` map. + // + // If the relay parent supports prospective parachains, we also need + // to inform the prospective parachains subsystem of the seconded candidate. + // If `ProspectiveParachainsMessage::Second` fails, then we return + // Error::RejectedByProspectiveParachains. + // + // Persisted Validation Data should be available - it may already be available + // if this is a candidate we are seconding. + // + // We should also not accept any candidates which have no valid depths under any of + // our active leaves. + if let StatementWithPVD::Seconded(candidate, pvd) = statement.payload() { + if !per_candidate.contains_key(&candidate_hash) { + if rp_state.prospective_parachains_mode.is_enabled() { + let (tx, rx) = oneshot::channel(); + ctx.send_message(ProspectiveParachainsMessage::IntroduceCandidate( + IntroduceCandidateRequest { + candidate_para: candidate.descriptor().para_id, + candidate_receipt: candidate.clone(), + persisted_validation_data: pvd.clone(), + }, + tx, + )) + .await; + + match rx.await { + Err(oneshot::Canceled) => { + gum::warn!( + target: LOG_TARGET, + "Could not reach the Prospective Parachains subsystem." + ); + + return Err(Error::RejectedByProspectiveParachains) + }, + Ok(membership) => + if membership.is_empty() { + return Err(Error::RejectedByProspectiveParachains) + }, + } + + ctx.send_message(ProspectiveParachainsMessage::CandidateSeconded( + candidate.descriptor().para_id, + candidate_hash, + )) + .await; + } + + // Only save the candidate if it was approved by prospective parachains. + per_candidate.insert( + candidate_hash, + PerCandidateState { + persisted_validation_data: pvd.clone(), + // This is set after importing when seconding locally. + seconded_locally: false, + para_id: candidate.descriptor().para_id, + relay_parent: candidate.descriptor().relay_parent, + }, + ); + } + } + + let stmt = primitive_statement_to_table(statement); + + Ok(rp_state.table.import_statement(&rp_state.table_context, stmt)) +} + +/// Handles a summary received from [`import_statement`] and dispatches `Backed` notifications and +/// misbehaviors as a result of importing a statement. +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn post_import_statement_actions( + ctx: &mut Context, + rp_state: &mut PerRelayParentState, + summary: Option<&TableSummary>, +) -> Result<(), Error> { + if let Some(attested) = summary + .as_ref() + .and_then(|s| rp_state.table.attested_candidate(&s.candidate, &rp_state.table_context)) + { + let candidate_hash = attested.candidate.hash(); + + // `HashSet::insert` returns true if the thing wasn't in there already. + if rp_state.backed.insert(candidate_hash) { + if let Some(backed) = table_attested_to_backed(attested, &rp_state.table_context) { + let para_id = backed.candidate.descriptor.para_id; + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?candidate_hash, + relay_parent = ?rp_state.parent, + %para_id, + "Candidate backed", + ); + + if rp_state.prospective_parachains_mode.is_enabled() { + // Inform the prospective parachains subsystem + // that the candidate is now backed. + ctx.send_message(ProspectiveParachainsMessage::CandidateBacked( + para_id, + candidate_hash, + )) + .await; + // Backed candidate potentially unblocks new advertisements, + // notify collator protocol. + ctx.send_message(CollatorProtocolMessage::Backed { + para_id, + para_head: backed.candidate.descriptor.para_head, + }) + .await; + // Notify statement distribution of backed candidate. + ctx.send_message(StatementDistributionMessage::Backed(candidate_hash)).await; + } else { + // The provisioner waits on candidate-backing, which means + // that we need to send unbounded messages to avoid cycles. + // + // Backed candidates are bounded by the number of validators, + // parachains, and the block production rate of the relay chain. + let message = ProvisionerMessage::ProvisionableData( + rp_state.parent, + ProvisionableData::BackedCandidate(backed.receipt()), + ); + ctx.send_unbounded_message(message); + } + } + } + } + + issue_new_misbehaviors(ctx, rp_state.parent, &mut rp_state.table); + + Ok(()) +} + +/// Check if there have happened any new misbehaviors and issue necessary messages. +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +fn issue_new_misbehaviors( + ctx: &mut Context, + relay_parent: Hash, + table: &mut Table, +) { + // collect the misbehaviors to avoid double mutable self borrow issues + let misbehaviors: Vec<_> = table.drain_misbehaviors().collect(); + for (validator_id, report) in misbehaviors { + // The provisioner waits on candidate-backing, which means + // that we need to send unbounded messages to avoid cycles. + // + // Misbehaviors are bounded by the number of validators and + // the block production protocol. + ctx.send_unbounded_message(ProvisionerMessage::ProvisionableData( + relay_parent, + ProvisionableData::MisbehaviorReport(relay_parent, validator_id, report), + )); + } +} + +/// Sign, import, and distribute a statement. +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn sign_import_and_distribute_statement( + ctx: &mut Context, + rp_state: &mut PerRelayParentState, + per_candidate: &mut HashMap, + statement: StatementWithPVD, + keystore: KeystorePtr, + metrics: &Metrics, +) -> Result, Error> { + if let Some(signed_statement) = sign_statement(&*rp_state, statement, keystore, metrics) { + let summary = import_statement(ctx, rp_state, per_candidate, &signed_statement).await?; + + // `Share` must always be sent before `Backed`. We send the latter in + // `post_import_statement_action` below. + let smsg = StatementDistributionMessage::Share(rp_state.parent, signed_statement.clone()); + ctx.send_unbounded_message(smsg); + + post_import_statement_actions(ctx, rp_state, summary.as_ref()).await?; + + Ok(Some(signed_statement)) + } else { + Ok(None) + } +} + +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn background_validate_and_make_available( + ctx: &mut Context, + rp_state: &mut PerRelayParentState, + params: BackgroundValidationParams< + impl overseer::CandidateBackingSenderTrait, + impl Fn(BackgroundValidationResult) -> ValidatedCandidateCommand + Send + 'static + Sync, + >, +) -> Result<(), Error> { + let candidate_hash = params.candidate.hash(); + if rp_state.awaiting_validation.insert(candidate_hash) { + // spawn background task. + let bg = async move { + if let Err(e) = validate_and_make_available(params).await { + if let Error::BackgroundValidationMpsc(error) = e { + gum::debug!( + target: LOG_TARGET, + ?error, + "Mpsc background validation mpsc died during validation- leaf no longer active?" + ); + } else { + gum::error!( + target: LOG_TARGET, + "Failed to validate and make available: {:?}", + e + ); + } + } + }; + + ctx.spawn("backing-validation", bg.boxed()) + .map_err(|_| Error::FailedToSpawnBackgroundTask)?; + } + + Ok(()) +} + +/// Kick off validation work and distribute the result as a signed statement. +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn kick_off_validation_work( + ctx: &mut Context, + rp_state: &mut PerRelayParentState, + persisted_validation_data: PersistedValidationData, + background_validation_tx: &mpsc::Sender<(Hash, ValidatedCandidateCommand)>, + attesting: AttestingData, +) -> Result<(), Error> { + let candidate_hash = attesting.candidate.hash(); + if rp_state.issued_statements.contains(&candidate_hash) { + return Ok(()) + } + + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?candidate_hash, + candidate_receipt = ?attesting.candidate, + "Kicking off validation", + ); + + let bg_sender = ctx.sender().clone(); + let pov = PoVData::FetchFromValidator { + from_validator: attesting.from_validator, + candidate_hash, + pov_hash: attesting.pov_hash, + }; + + background_validate_and_make_available( + ctx, + rp_state, + BackgroundValidationParams { + sender: bg_sender, + tx_command: background_validation_tx.clone(), + candidate: attesting.candidate, + relay_parent: rp_state.parent, + persisted_validation_data, + pov, + n_validators: rp_state.table_context.validators.len(), + make_command: ValidatedCandidateCommand::Attest, + }, + ) + .await +} + +/// Import the statement and kick off validation work if it is a part of our assignment. +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn maybe_validate_and_import( + ctx: &mut Context, + state: &mut State, + relay_parent: Hash, + statement: SignedFullStatementWithPVD, +) -> Result<(), Error> { + let rp_state = match state.per_relay_parent.get_mut(&relay_parent) { + Some(r) => r, + None => { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + "Received statement for unknown relay-parent" + ); + + return Ok(()) + }, + }; + + let res = import_statement(ctx, rp_state, &mut state.per_candidate, &statement).await; + + // if we get an Error::RejectedByProspectiveParachains, + // we will do nothing. + if let Err(Error::RejectedByProspectiveParachains) = res { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + "Statement rejected by prospective parachains." + ); + + return Ok(()) + } + + let summary = res?; + post_import_statement_actions(ctx, rp_state, summary.as_ref()).await?; + + if let Some(summary) = summary { + // import_statement already takes care of communicating with the + // prospective parachains subsystem. At this point, the candidate + // has already been accepted into the fragment trees. + + let candidate_hash = summary.candidate; + + if Some(summary.group_id) != rp_state.assignment { + return Ok(()) + } + let attesting = match statement.payload() { + StatementWithPVD::Seconded(receipt, _) => { + let attesting = AttestingData { + candidate: rp_state + .table + .get_candidate(&candidate_hash) + .ok_or(Error::CandidateNotFound)? + .to_plain(), + pov_hash: receipt.descriptor.pov_hash, + from_validator: statement.validator_index(), + backing: Vec::new(), + }; + rp_state.fallbacks.insert(summary.candidate, attesting.clone()); + attesting + }, + StatementWithPVD::Valid(candidate_hash) => { + if let Some(attesting) = rp_state.fallbacks.get_mut(candidate_hash) { + let our_index = rp_state.table_context.validator.as_ref().map(|v| v.index()); + if our_index == Some(statement.validator_index()) { + return Ok(()) + } + + if rp_state.awaiting_validation.contains(candidate_hash) { + // Job already running: + attesting.backing.push(statement.validator_index()); + return Ok(()) + } else { + // No job, so start another with current validator: + attesting.from_validator = statement.validator_index(); + attesting.clone() + } + } else { + return Ok(()) + } + }, + }; + + // After `import_statement` succeeds, the candidate entry is guaranteed + // to exist. + if let Some(pvd) = state + .per_candidate + .get(&candidate_hash) + .map(|pc| pc.persisted_validation_data.clone()) + { + kick_off_validation_work( + ctx, + rp_state, + pvd, + &state.background_validation_tx, + attesting, + ) + .await?; + } + } + Ok(()) +} + +/// Kick off background validation with intent to second. +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn validate_and_second( + ctx: &mut Context, + rp_state: &mut PerRelayParentState, + persisted_validation_data: PersistedValidationData, + candidate: &CandidateReceipt, + pov: Arc, + background_validation_tx: &mpsc::Sender<(Hash, ValidatedCandidateCommand)>, +) -> Result<(), Error> { + let candidate_hash = candidate.hash(); + + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?candidate_hash, + candidate_receipt = ?candidate, + "Validate and second candidate", + ); + + let bg_sender = ctx.sender().clone(); + background_validate_and_make_available( + ctx, + rp_state, + BackgroundValidationParams { + sender: bg_sender, + tx_command: background_validation_tx.clone(), + candidate: candidate.clone(), + relay_parent: rp_state.parent, + persisted_validation_data, + pov: PoVData::Ready(pov), + n_validators: rp_state.table_context.validators.len(), + make_command: ValidatedCandidateCommand::Second, + }, + ) + .await?; + + Ok(()) +} + +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn handle_second_message( + ctx: &mut Context, + state: &mut State, + candidate: CandidateReceipt, + persisted_validation_data: PersistedValidationData, + pov: PoV, + metrics: &Metrics, +) -> Result<(), Error> { + let _timer = metrics.time_process_second(); + + let candidate_hash = candidate.hash(); + let relay_parent = candidate.descriptor().relay_parent; + + if candidate.descriptor().persisted_validation_data_hash != persisted_validation_data.hash() { + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + "Candidate backing was asked to second candidate with wrong PVD", + ); + + return Ok(()) + } + + let rp_state = match state.per_relay_parent.get_mut(&relay_parent) { + None => { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + ?candidate_hash, + "We were asked to second a candidate outside of our view." + ); + + return Ok(()) + }, + Some(r) => r, + }; + + // Sanity check that candidate is from our assignment. + if Some(candidate.descriptor().para_id) != rp_state.assignment { + gum::debug!( + target: LOG_TARGET, + our_assignment = ?rp_state.assignment, + collation = ?candidate.descriptor().para_id, + "Subsystem asked to second for para outside of our assignment", + ); + + return Ok(()) + } + + // If the message is a `CandidateBackingMessage::Second`, sign and dispatch a + // Seconded statement only if we have not signed a Valid statement for the requested candidate. + // + // The actual logic of issuing the signed statement checks that this isn't + // conflicting with other seconded candidates. Not doing that check here + // gives other subsystems the ability to get us to execute arbitrary candidates, + // but no more. + if !rp_state.issued_statements.contains(&candidate_hash) { + let pov = Arc::new(pov); + + validate_and_second( + ctx, + rp_state, + persisted_validation_data, + &candidate, + pov, + &state.background_validation_tx, + ) + .await?; + } + + Ok(()) +} + +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +async fn handle_statement_message( + ctx: &mut Context, + state: &mut State, + relay_parent: Hash, + statement: SignedFullStatementWithPVD, + metrics: &Metrics, +) -> Result<(), Error> { + let _timer = metrics.time_process_statement(); + + match maybe_validate_and_import(ctx, state, relay_parent, statement).await { + Err(Error::ValidationFailed(_)) => Ok(()), + Err(e) => Err(e), + Ok(()) => Ok(()), + } +} + +fn handle_get_backed_candidates_message( + state: &State, + requested_candidates: Vec<(CandidateHash, Hash)>, + tx: oneshot::Sender>, + metrics: &Metrics, +) -> Result<(), Error> { + let _timer = metrics.time_get_backed_candidates(); + + let backed = requested_candidates + .into_iter() + .filter_map(|(candidate_hash, relay_parent)| { + let rp_state = match state.per_relay_parent.get(&relay_parent) { + Some(rp_state) => rp_state, + None => { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + ?candidate_hash, + "Requested candidate's relay parent is out of view", + ); + return None + }, + }; + rp_state + .table + .attested_candidate(&candidate_hash, &rp_state.table_context) + .and_then(|attested| table_attested_to_backed(attested, &rp_state.table_context)) + }) + .collect(); + + tx.send(backed).map_err(|data| Error::Send(data))?; + Ok(()) +} diff --git a/polkadot/node/core/backing/src/metrics.rs b/polkadot/node/core/backing/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..77f0e7f9d92a041cd4ddaf4682ca244bd7fa8edf --- /dev/null +++ b/polkadot/node/core/backing/src/metrics.rs @@ -0,0 +1,107 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) signed_statements_total: prometheus::Counter, + pub(crate) candidates_seconded_total: prometheus::Counter, + pub(crate) process_second: prometheus::Histogram, + pub(crate) process_statement: prometheus::Histogram, + pub(crate) get_backed_candidates: prometheus::Histogram, +} + +/// Candidate backing metrics. +#[derive(Default, Clone)] +pub struct Metrics(pub(crate) Option); + +impl Metrics { + pub fn on_statement_signed(&self) { + if let Some(metrics) = &self.0 { + metrics.signed_statements_total.inc(); + } + } + + pub fn on_candidate_seconded(&self) { + if let Some(metrics) = &self.0 { + metrics.candidates_seconded_total.inc(); + } + } + + /// Provide a timer for handling `CandidateBackingMessage:Second` which observes on drop. + pub fn time_process_second(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.process_second.start_timer()) + } + + /// Provide a timer for handling `CandidateBackingMessage::Statement` which observes on drop. + pub fn time_process_statement( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.process_statement.start_timer()) + } + + /// Provide a timer for handling `CandidateBackingMessage::GetBackedCandidates` which observes + /// on drop. + pub fn time_get_backed_candidates( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.get_backed_candidates.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + signed_statements_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_candidate_backing_signed_statements_total", + "Number of statements signed.", + )?, + registry, + )?, + candidates_seconded_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_candidate_backing_candidates_seconded_total", + "Number of candidates seconded.", + )?, + registry, + )?, + process_second: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_backing_process_second", + "Time spent within `candidate_backing::process_second`", + ))?, + registry, + )?, + process_statement: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_backing_process_statement", + "Time spent within `candidate_backing::process_statement`", + ))?, + registry, + )?, + get_backed_candidates: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_backing_get_backed_candidates", + "Time spent within `candidate_backing::get_backed_candidates`", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/core/backing/src/tests/mod.rs b/polkadot/node/core/backing/src/tests/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..054337669c07781f85514299e93c9ac8886cc5f5 --- /dev/null +++ b/polkadot/node/core/backing/src/tests/mod.rs @@ -0,0 +1,1994 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use ::test_helpers::{ + dummy_candidate_receipt_bad_sig, dummy_collator, dummy_collator_signature, + dummy_committed_candidate_receipt, dummy_hash, +}; +use assert_matches::assert_matches; +use futures::{future, Future}; +use polkadot_node_primitives::{BlockData, InvalidCandidate, SignedFullStatement, Statement}; +use polkadot_node_subsystem::{ + errors::RuntimeApiError, + jaeger, + messages::{ + AllMessages, CollatorProtocolMessage, RuntimeApiMessage, RuntimeApiRequest, + ValidationFailed, + }, + ActivatedLeaf, ActiveLeavesUpdate, FromOrchestra, LeafStatus, OverseerSignal, TimeoutExt, +}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_primitives::{ + CandidateDescriptor, GroupRotationInfo, HeadData, PersistedValidationData, PvfExecTimeoutKind, + ScheduledCore, SessionIndex, +}; +use sp_application_crypto::AppCrypto; +use sp_keyring::Sr25519Keyring; +use sp_keystore::Keystore; +use sp_tracing as _; +use statement_table::v2::Misbehavior; +use std::collections::HashMap; + +mod prospective_parachains; + +const ASYNC_BACKING_DISABLED_ERROR: RuntimeApiError = + RuntimeApiError::NotSupported { runtime_api_name: "test-runtime" }; + +fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec { + val_ids.iter().map(|v| v.public().into()).collect() +} + +fn table_statement_to_primitive(statement: TableStatement) -> Statement { + match statement { + TableStatement::Seconded(committed_candidate_receipt) => + Statement::Seconded(committed_candidate_receipt), + TableStatement::Valid(candidate_hash) => Statement::Valid(candidate_hash), + } +} + +fn dummy_pvd() -> PersistedValidationData { + PersistedValidationData { + parent_head: HeadData(vec![7, 8, 9]), + relay_parent_number: 0_u32.into(), + max_pov_size: 1024, + relay_parent_storage_root: dummy_hash(), + } +} + +struct TestState { + chain_ids: Vec, + keystore: KeystorePtr, + validators: Vec, + validator_public: Vec, + validation_data: PersistedValidationData, + validator_groups: (Vec>, GroupRotationInfo), + availability_cores: Vec, + head_data: HashMap, + signing_context: SigningContext, + relay_parent: Hash, +} + +impl TestState { + fn session(&self) -> SessionIndex { + self.signing_context.session_index + } +} + +impl Default for TestState { + fn default() -> Self { + let chain_a = ParaId::from(1); + let chain_b = ParaId::from(2); + + let chain_ids = vec![chain_a, chain_b]; + + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + Sr25519Keyring::One, + ]; + + let keystore = Arc::new(sc_keystore::LocalKeystore::in_memory()); + // Make sure `Alice` key is in the keystore, so this mocked node will be a parachain + // validator. + Keystore::sr25519_generate_new(&*keystore, ValidatorId::ID, Some(&validators[0].to_seed())) + .expect("Insert key into keystore"); + + let validator_public = validator_pubkeys(&validators); + + let validator_groups = vec![vec![2, 0, 3, 5], vec![1]] + .into_iter() + .map(|g| g.into_iter().map(ValidatorIndex).collect()) + .collect(); + let group_rotation_info = + GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 100, now: 1 }; + + let availability_cores = vec![ + CoreState::Scheduled(ScheduledCore { para_id: chain_a, collator: None }), + CoreState::Scheduled(ScheduledCore { para_id: chain_b, collator: None }), + ]; + + let mut head_data = HashMap::new(); + head_data.insert(chain_a, HeadData(vec![4, 5, 6])); + head_data.insert(chain_b, HeadData(vec![5, 6, 7])); + + let relay_parent = Hash::repeat_byte(5); + + let signing_context = SigningContext { session_index: 1, parent_hash: relay_parent }; + + let validation_data = PersistedValidationData { + parent_head: HeadData(vec![7, 8, 9]), + relay_parent_number: 0_u32.into(), + max_pov_size: 1024, + relay_parent_storage_root: dummy_hash(), + }; + + Self { + chain_ids, + keystore, + validators, + validator_public, + validator_groups: (validator_groups, group_rotation_info), + availability_cores, + head_data, + validation_data, + signing_context, + relay_parent, + } + } +} + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; + +fn test_harness>( + keystore: KeystorePtr, + test: impl FnOnce(VirtualOverseer) -> T, +) { + let pool = sp_core::testing::TaskExecutor::new(); + + let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); + + let subsystem = async move { + if let Err(e) = super::run(context, keystore, Metrics(None)).await { + panic!("{:?}", e); + } + }; + + let test_fut = test(virtual_overseer); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + futures::executor::block_on(future::join( + async move { + let mut virtual_overseer = test_fut.await; + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }, + subsystem, + )); +} + +fn make_erasure_root(test: &TestState, pov: PoV, validation_data: PersistedValidationData) -> Hash { + let available_data = AvailableData { validation_data, pov: Arc::new(pov) }; + + let chunks = erasure_coding::obtain_chunks_v1(test.validators.len(), &available_data).unwrap(); + erasure_coding::branches(&chunks).root() +} + +#[derive(Default, Clone)] +struct TestCandidateBuilder { + para_id: ParaId, + head_data: HeadData, + pov_hash: Hash, + relay_parent: Hash, + erasure_root: Hash, + persisted_validation_data_hash: Hash, + validation_code: Vec, +} + +impl TestCandidateBuilder { + fn build(self) -> CommittedCandidateReceipt { + CommittedCandidateReceipt { + descriptor: CandidateDescriptor { + para_id: self.para_id, + pov_hash: self.pov_hash, + relay_parent: self.relay_parent, + erasure_root: self.erasure_root, + collator: dummy_collator(), + signature: dummy_collator_signature(), + para_head: self.head_data.hash(), + validation_code_hash: ValidationCode(self.validation_code).hash(), + persisted_validation_data_hash: self.persisted_validation_data_hash, + }, + commitments: CandidateCommitments { + head_data: self.head_data, + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0_u32, + }, + } + } +} + +// Tests that the subsystem performs actions that are required on startup. +async fn test_startup(virtual_overseer: &mut VirtualOverseer, test_state: &TestState) { + // Start work on some new parent. + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( + ActivatedLeaf { + hash: test_state.relay_parent, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }, + )))) + .await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) if parent == test_state.relay_parent => { + tx.send(Err(ASYNC_BACKING_DISABLED_ERROR)).unwrap(); + } + ); + + // Check that subsystem job issues a request for a validator set. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::Validators(tx)) + ) if parent == test_state.relay_parent => { + tx.send(Ok(test_state.validator_public.clone())).unwrap(); + } + ); + + // Check that subsystem job issues a request for the validator groups. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::ValidatorGroups(tx)) + ) if parent == test_state.relay_parent => { + tx.send(Ok(test_state.validator_groups.clone())).unwrap(); + } + ); + + // Check that subsystem job issues a request for the session index for child. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx)) + ) if parent == test_state.relay_parent => { + tx.send(Ok(test_state.signing_context.session_index)).unwrap(); + } + ); + + // Check that subsystem job issues a request for the availability cores. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::AvailabilityCores(tx)) + ) if parent == test_state.relay_parent => { + tx.send(Ok(test_state.availability_cores.clone())).unwrap(); + } + ); +} + +// Test that a `CandidateBackingMessage::Second` issues validation work +// and in case validation is successful issues a `StatementDistributionMessage`. +#[test] +fn backing_second_works() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let pov_hash = pov.hash(); + let candidate = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + + let second = CandidateBackingMessage::Second( + test_state.relay_parent, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive( + _pvd, + _validation_code, + candidate_receipt, + _pov, + timeout, + tx, + ), + ) if _pvd == pvd && + _validation_code == validation_code && + *_pov == pov && &candidate_receipt.descriptor == candidate.descriptor() && + timeout == PvfExecTimeoutKind::Backing && + candidate.commitments.hash() == candidate_receipt.commitments_hash => + { + tx.send(Ok(ValidationResult::Valid( + CandidateCommitments { + head_data: expected_head_data.clone(), + horizontal_messages: Default::default(), + upward_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0, + }, + test_state.validation_data.clone(), + ))) + .unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::StoreAvailableData { candidate_hash, tx, .. } + ) if candidate_hash == candidate.hash() => { + tx.send(Ok(())).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share( + parent_hash, + _signed_statement, + ) + ) if parent_hash == test_state.relay_parent => {} + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol(CollatorProtocolMessage::Seconded(hash, statement)) => { + assert_eq!(test_state.relay_parent, hash); + assert_matches!(statement.payload(), Statement::Seconded(_)); + } + ); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; + virtual_overseer + }); +} + +// Test that the candidate reaches quorum successfully. +#[test] +fn backing_works() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![1, 2, 3]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let pov_hash = pov.hash(); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let candidate_a = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + validation_code: validation_code.0.clone(), + ..Default::default() + } + .build(); + + let candidate_a_hash = candidate_a.hash(); + let candidate_a_commitments_hash = candidate_a.commitments.hash(); + + let public1 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[5].to_seed()), + ) + .expect("Insert key into keystore"); + let public2 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .expect("Insert key into keystore"); + + let signed_a = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate_a.clone(), pvd.clone()), + &test_state.signing_context, + ValidatorIndex(2), + &public2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let signed_b = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Valid(candidate_a_hash), + &test_state.signing_context, + ValidatorIndex(5), + &public1.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + // Sending a `Statement::Seconded` for our assignment will start + // validation process. The first thing requested is the PoV. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityDistribution( + AvailabilityDistributionMessage::FetchPoV { + relay_parent, + tx, + .. + } + ) if relay_parent == test_state.relay_parent => { + tx.send(pov.clone()).unwrap(); + } + ); + + // The next step is the actual request to Validation subsystem + // to validate the `Seconded` candidate. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive( + _pvd, + _validation_code, + candidate_receipt, + _pov, + timeout, + tx, + ), + ) if _pvd == pvd && + _validation_code == validation_code && + *_pov == pov && &candidate_receipt.descriptor == candidate_a.descriptor() && + timeout == PvfExecTimeoutKind::Backing && + candidate_a_commitments_hash == candidate_receipt.commitments_hash => + { + tx.send(Ok( + ValidationResult::Valid(CandidateCommitments { + head_data: expected_head_data.clone(), + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0, + }, test_state.validation_data.clone()), + )).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::StoreAvailableData { candidate_hash, tx, .. } + ) if candidate_hash == candidate_a.hash() => { + tx.send(Ok(())).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share(hash, _stmt) + ) => { + assert_eq!(test_state.relay_parent, hash); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::Provisioner( + ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::BackedCandidate(candidate_receipt) + ) + ) => { + assert_eq!(candidate_receipt, candidate_a.to_plain()); + } + ); + + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_b.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; + virtual_overseer + }); +} + +#[test] +fn backing_works_while_validation_ongoing() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![1, 2, 3]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let pov_hash = pov.hash(); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let candidate_a = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + validation_code: validation_code.0.clone(), + ..Default::default() + } + .build(); + + let candidate_a_hash = candidate_a.hash(); + let candidate_a_commitments_hash = candidate_a.commitments.hash(); + + let public1 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[5].to_seed()), + ) + .expect("Insert key into keystore"); + let public2 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .expect("Insert key into keystore"); + let public3 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[3].to_seed()), + ) + .expect("Insert key into keystore"); + + let signed_a = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate_a.clone(), pvd.clone()), + &test_state.signing_context, + ValidatorIndex(2), + &public2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let signed_b = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Valid(candidate_a_hash), + &test_state.signing_context, + ValidatorIndex(5), + &public1.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let signed_c = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Valid(candidate_a_hash), + &test_state.signing_context, + ValidatorIndex(3), + &public3.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + // Sending a `Statement::Seconded` for our assignment will start + // validation process. The first thing requested is PoV from the + // `PoVDistribution`. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityDistribution( + AvailabilityDistributionMessage::FetchPoV { + relay_parent, + tx, + .. + } + ) if relay_parent == test_state.relay_parent => { + tx.send(pov.clone()).unwrap(); + } + ); + + // The next step is the actual request to Validation subsystem + // to validate the `Seconded` candidate. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive( + _pvd, + _validation_code, + candidate_receipt, + _pov, + timeout, + tx, + ), + ) if _pvd == pvd && + _validation_code == validation_code && + *_pov == pov && &candidate_receipt.descriptor == candidate_a.descriptor() && + timeout == PvfExecTimeoutKind::Backing && + candidate_a_commitments_hash == candidate_receipt.commitments_hash => + { + // we never validate the candidate. our local node + // shouldn't issue any statements. + std::mem::forget(tx); + } + ); + + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_b.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + // Candidate gets backed entirely by other votes. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::Provisioner( + ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::BackedCandidate(CandidateReceipt { + descriptor, + .. + }) + ) + ) if descriptor == candidate_a.descriptor + ); + + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_c.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + let (tx, rx) = oneshot::channel(); + let msg = CandidateBackingMessage::GetBackedCandidates( + vec![(candidate_a.hash(), test_state.relay_parent)], + tx, + ); + + virtual_overseer.send(FromOrchestra::Communication { msg }).await; + + let candidates = rx.await.unwrap(); + assert_eq!(1, candidates.len()); + assert_eq!(candidates[0].validity_votes.len(), 3); + + assert!(candidates[0] + .validity_votes + .contains(&ValidityAttestation::Implicit(signed_a.signature().clone()))); + assert!(candidates[0] + .validity_votes + .contains(&ValidityAttestation::Explicit(signed_b.signature().clone()))); + assert!(candidates[0] + .validity_votes + .contains(&ValidityAttestation::Explicit(signed_c.signature().clone()))); + assert_eq!( + candidates[0].validator_indices, + bitvec::bitvec![u8, bitvec::order::Lsb0; 1, 0, 1, 1], + ); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; + virtual_overseer + }); +} + +// Issuing conflicting statements on the same candidate should +// be a misbehavior. +#[test] +fn backing_misbehavior_works() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![1, 2, 3]) }; + + let pov_hash = pov.hash(); + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let candidate_a = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + head_data: expected_head_data.clone(), + validation_code: validation_code.0.clone(), + ..Default::default() + } + .build(); + + let candidate_a_hash = candidate_a.hash(); + let candidate_a_commitments_hash = candidate_a.commitments.hash(); + + let public2 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .expect("Insert key into keystore"); + let seconded_2 = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate_a.clone(), pvd.clone()), + &test_state.signing_context, + ValidatorIndex(2), + &public2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let valid_2 = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Valid(candidate_a_hash), + &test_state.signing_context, + ValidatorIndex(2), + &public2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, seconded_2.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityDistribution( + AvailabilityDistributionMessage::FetchPoV { + relay_parent, + tx, + .. + } + ) if relay_parent == test_state.relay_parent => { + tx.send(pov.clone()).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive( + _pvd, + _validation_code, + candidate_receipt, + _pov, + timeout, + tx, + ), + ) if _pvd == pvd && + _validation_code == validation_code && + *_pov == pov && &candidate_receipt.descriptor == candidate_a.descriptor() && + timeout == PvfExecTimeoutKind::Backing && + candidate_a_commitments_hash == candidate_receipt.commitments_hash => + { + tx.send(Ok( + ValidationResult::Valid(CandidateCommitments { + head_data: expected_head_data.clone(), + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0, + }, test_state.validation_data.clone()), + )).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::StoreAvailableData { candidate_hash, tx, .. } + ) if candidate_hash == candidate_a.hash() => { + tx.send(Ok(())).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share( + relay_parent, + signed_statement, + ) + ) if relay_parent == test_state.relay_parent => { + assert_eq!(*signed_statement.payload(), StatementWithPVD::Valid(candidate_a_hash)); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::Provisioner( + ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::BackedCandidate(CandidateReceipt { + descriptor, + .. + }) + ) + ) if descriptor == candidate_a.descriptor + ); + + // This `Valid` statement is redundant after the `Seconded` statement already sent. + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, valid_2.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::Provisioner( + ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::MisbehaviorReport( + relay_parent, + validator_index, + Misbehavior::ValidityDoubleVote(vdv), + ) + ) + ) if relay_parent == test_state.relay_parent => { + let ((t1, s1), (t2, s2)) = vdv.deconstruct::(); + let t1 = table_statement_to_primitive(t1); + let t2 = table_statement_to_primitive(t2); + + SignedFullStatement::new( + t1, + validator_index, + s1, + &test_state.signing_context, + &test_state.validator_public[validator_index.0 as usize], + ).expect("signature must be valid"); + + SignedFullStatement::new( + t2, + validator_index, + s2, + &test_state.signing_context, + &test_state.validator_public[validator_index.0 as usize], + ).expect("signature must be valid"); + } + ); + virtual_overseer + }); +} + +// Test that if we are asked to second an invalid candidate we +// can still second a valid one afterwards. +#[test] +fn backing_dont_second_invalid() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov_block_a = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd_a = dummy_pvd(); + let validation_code_a = ValidationCode(vec![1, 2, 3]); + + let pov_block_b = PoV { block_data: BlockData(vec![45, 46, 47]) }; + let pvd_b = { + let mut pvd_b = pvd_a.clone(); + pvd_b.parent_head = HeadData(vec![14, 15, 16]); + pvd_b.max_pov_size = pvd_a.max_pov_size / 2; + pvd_b + }; + let validation_code_b = ValidationCode(vec![4, 5, 6]); + + let pov_hash_a = pov_block_a.hash(); + let pov_hash_b = pov_block_b.hash(); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let candidate_a = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash: pov_hash_a, + erasure_root: make_erasure_root(&test_state, pov_block_a.clone(), pvd_a.clone()), + persisted_validation_data_hash: pvd_a.hash(), + validation_code: validation_code_a.0.clone(), + ..Default::default() + } + .build(); + + let candidate_b = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash: pov_hash_b, + erasure_root: make_erasure_root(&test_state, pov_block_b.clone(), pvd_b.clone()), + head_data: expected_head_data.clone(), + persisted_validation_data_hash: pvd_b.hash(), + validation_code: validation_code_b.0.clone(), + } + .build(); + + let second = CandidateBackingMessage::Second( + test_state.relay_parent, + candidate_a.to_plain(), + pvd_a.clone(), + pov_block_a.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code_a.hash() => { + tx.send(Ok(Some(validation_code_a.clone()))).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive( + _pvd, + _validation_code, + candidate_receipt, + _pov, + timeout, + tx, + ), + ) if _pvd == pvd_a && + _validation_code == validation_code_a && + *_pov == pov_block_a && &candidate_receipt.descriptor == candidate_a.descriptor() && + timeout == PvfExecTimeoutKind::Backing && + candidate_a.commitments.hash() == candidate_receipt.commitments_hash => + { + tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::BadReturn))).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol( + CollatorProtocolMessage::Invalid(parent_hash, c) + ) if parent_hash == test_state.relay_parent && c == candidate_a.to_plain() + ); + + let second = CandidateBackingMessage::Second( + test_state.relay_parent, + candidate_b.to_plain(), + pvd_b.clone(), + pov_block_b.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code_b.hash() => { + tx.send(Ok(Some(validation_code_b.clone()))).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive( + pvd, + _validation_code, + candidate_receipt, + _pov, + timeout, + tx, + ), + ) if pvd == pvd_b && + _validation_code == validation_code_b && + *_pov == pov_block_b && &candidate_receipt.descriptor == candidate_b.descriptor() && + timeout == PvfExecTimeoutKind::Backing && + candidate_b.commitments.hash() == candidate_receipt.commitments_hash => + { + tx.send(Ok( + ValidationResult::Valid(CandidateCommitments { + head_data: expected_head_data.clone(), + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0, + }, pvd_b.clone()), + )).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::StoreAvailableData { candidate_hash, tx, .. } + ) if candidate_hash == candidate_b.hash() => { + tx.send(Ok(())).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share( + parent_hash, + signed_statement, + ) + ) if parent_hash == test_state.relay_parent => { + assert_eq!(*signed_statement.payload(), StatementWithPVD::Seconded(candidate_b, pvd_b.clone())); + } + ); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; + virtual_overseer + }); +} + +// Test that if we have already issued a statement (in this case `Invalid`) about a +// candidate we will not be issuing a `Seconded` statement on it. +#[test] +fn backing_second_after_first_fails_works() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let pov_hash = pov.hash(); + + let candidate = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + ..Default::default() + } + .build(); + + let validator2 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .expect("Insert key into keystore"); + + let signed_a = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate.clone(), pvd.clone()), + &test_state.signing_context, + ValidatorIndex(2), + &validator2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + // Send in a `Statement` with a candidate. + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + // Subsystem requests PoV and requests validation. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityDistribution( + AvailabilityDistributionMessage::FetchPoV { + relay_parent, + tx, + .. + } + ) if relay_parent == test_state.relay_parent => { + tx.send(pov.clone()).unwrap(); + } + ); + + // Tell subsystem that this candidate is invalid. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive( + _pvd, + _validation_code, + candidate_receipt, + _pov, + timeout, + tx, + ), + ) if _pvd == pvd && + _validation_code == validation_code && + *_pov == pov && &candidate_receipt.descriptor == candidate.descriptor() && + timeout == PvfExecTimeoutKind::Backing && + candidate.commitments.hash() == candidate_receipt.commitments_hash => + { + tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::BadReturn))).unwrap(); + } + ); + + // Ask subsystem to `Second` a candidate that already has a statement issued about. + // This should emit no actions from subsystem. + let second = CandidateBackingMessage::Second( + test_state.relay_parent, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + let pov_to_second = PoV { block_data: BlockData(vec![3, 2, 1]) }; + let pvd_to_second = dummy_pvd(); + let validation_code_to_second = ValidationCode(vec![5, 6, 7]); + + let pov_hash = pov_to_second.hash(); + + let candidate_to_second = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + erasure_root: make_erasure_root( + &test_state, + pov_to_second.clone(), + pvd_to_second.clone(), + ), + persisted_validation_data_hash: pvd_to_second.hash(), + validation_code: validation_code_to_second.0.clone(), + ..Default::default() + } + .build(); + + let second = CandidateBackingMessage::Second( + test_state.relay_parent, + candidate_to_second.to_plain(), + pvd_to_second.clone(), + pov_to_second.clone(), + ); + + // In order to trigger _some_ actions from subsystem ask it to second another + // candidate. The only reason to do so is to make sure that no actions were + // triggered on the prev step. + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code_to_second.hash() => { + tx.send(Ok(Some(validation_code_to_second.clone()))).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive(_, _, _, pov, ..), + ) => { + assert_eq!(&*pov, &pov_to_second); + } + ); + virtual_overseer + }); +} + +// That that if the validation of the candidate has failed this does not stop +// the work of this subsystem and so it is not fatal to the node. +#[test] +fn backing_works_after_failed_validation() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let pov_hash = pov.hash(); + + let candidate = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + validation_code: validation_code.0.clone(), + ..Default::default() + } + .build(); + + let public2 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .expect("Insert key into keystore"); + let signed_a = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate.clone(), pvd.clone()), + &test_state.signing_context, + ValidatorIndex(2), + &public2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + // Send in a `Statement` with a candidate. + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + // Subsystem requests PoV and requests validation. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityDistribution( + AvailabilityDistributionMessage::FetchPoV { + relay_parent, + tx, + .. + } + ) if relay_parent == test_state.relay_parent => { + tx.send(pov.clone()).unwrap(); + } + ); + + // Tell subsystem that this candidate is invalid. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive( + _pvd, + _validation_code, + candidate_receipt, + _pov, + timeout, + tx, + ), + ) if _pvd == pvd && + _validation_code == validation_code && + *_pov == pov && &candidate_receipt.descriptor == candidate.descriptor() && + timeout == PvfExecTimeoutKind::Backing && + candidate.commitments.hash() == candidate_receipt.commitments_hash => + { + tx.send(Err(ValidationFailed("Internal test error".into()))).unwrap(); + } + ); + + // Try to get a set of backable candidates to trigger _some_ action in the subsystem + // and check that it is still alive. + let (tx, rx) = oneshot::channel(); + let msg = CandidateBackingMessage::GetBackedCandidates( + vec![(candidate.hash(), test_state.relay_parent)], + tx, + ); + + virtual_overseer.send(FromOrchestra::Communication { msg }).await; + assert_eq!(rx.await.unwrap().len(), 0); + virtual_overseer + }); +} + +#[test] +fn candidate_backing_reorders_votes() { + use sp_core::Encode; + + let para_id = ParaId::from(10); + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + Sr25519Keyring::One, + ]; + + let validator_public = validator_pubkeys(&validators); + let validator_groups = { + let mut validator_groups = HashMap::new(); + validator_groups + .insert(para_id, vec![0, 1, 2, 3, 4, 5].into_iter().map(ValidatorIndex).collect()); + validator_groups + }; + + let table_context = TableContext { + validator: None, + groups: validator_groups, + validators: validator_public.clone(), + }; + + let fake_attestation = |idx: u32| { + let candidate = + dummy_candidate_receipt_bad_sig(Default::default(), Some(Default::default())); + let hash = candidate.hash(); + let mut data = vec![0; 64]; + data[0..32].copy_from_slice(hash.0.as_bytes()); + data[32..36].copy_from_slice(idx.encode().as_slice()); + + let sig = ValidatorSignature::try_from(data).unwrap(); + statement_table::generic::ValidityAttestation::Implicit(sig) + }; + + let attested = TableAttestedCandidate { + candidate: dummy_committed_candidate_receipt(dummy_hash()), + validity_votes: vec![ + (ValidatorIndex(5), fake_attestation(5)), + (ValidatorIndex(3), fake_attestation(3)), + (ValidatorIndex(1), fake_attestation(1)), + ], + group_id: para_id, + }; + + let backed = table_attested_to_backed(attested, &table_context).unwrap(); + + let expected_bitvec = { + let mut validator_indices = BitVec::::with_capacity(6); + validator_indices.resize(6, false); + + validator_indices.set(1, true); + validator_indices.set(3, true); + validator_indices.set(5, true); + + validator_indices + }; + + // Should be in bitfield order, which is opposite to the order provided to the function. + let expected_attestations = + vec![fake_attestation(1).into(), fake_attestation(3).into(), fake_attestation(5).into()]; + + assert_eq!(backed.validator_indices, expected_bitvec); + assert_eq!(backed.validity_votes, expected_attestations); +} + +// Test whether we retry on failed PoV fetching. +#[test] +fn retry_works() { + // sp_tracing::try_init_simple(); + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let pov_hash = pov.hash(); + + let candidate = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + ..Default::default() + } + .build(); + + let public2 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .expect("Insert key into keystore"); + let public3 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[3].to_seed()), + ) + .expect("Insert key into keystore"); + let public5 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[5].to_seed()), + ) + .expect("Insert key into keystore"); + let signed_a = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate.clone(), pvd.clone()), + &test_state.signing_context, + ValidatorIndex(2), + &public2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + let signed_b = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Valid(candidate.hash()), + &test_state.signing_context, + ValidatorIndex(3), + &public3.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + let signed_c = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Valid(candidate.hash()), + &test_state.signing_context, + ValidatorIndex(5), + &public5.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + // Send in a `Statement` with a candidate. + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + // Subsystem requests PoV and requests validation. + // We cancel - should mean retry on next backing statement. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityDistribution( + AvailabilityDistributionMessage::FetchPoV { + relay_parent, + tx, + .. + } + ) if relay_parent == test_state.relay_parent => { + std::mem::drop(tx); + } + ); + + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_b.clone()); + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + // Not deterministic which message comes first: + for _ in 0u32..3 { + match virtual_overseer.recv().await { + AllMessages::Provisioner(ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::BackedCandidate(CandidateReceipt { descriptor, .. }), + )) => { + assert_eq!(descriptor, candidate.descriptor); + }, + AllMessages::AvailabilityDistribution( + AvailabilityDistributionMessage::FetchPoV { relay_parent, tx, .. }, + ) if relay_parent == test_state.relay_parent => { + std::mem::drop(tx); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::ValidationCodeByHash(hash, tx), + )) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + }, + msg => { + assert!(false, "Unexpected message: {:?}", msg); + }, + } + } + + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_c.clone()); + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityDistribution( + AvailabilityDistributionMessage::FetchPoV { + relay_parent, + tx, + .. + } + // Subsystem requests PoV and requests validation. + // Now we pass. + ) if relay_parent == test_state.relay_parent => { + tx.send(pov.clone()).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive( + _pvd, + _validation_code, + candidate_receipt, + _pov, + timeout, + .. + ), + ) if _pvd == pvd && + _validation_code == validation_code && + *_pov == pov && &candidate_receipt.descriptor == candidate.descriptor() && + timeout == PvfExecTimeoutKind::Backing && + candidate.commitments.hash() == candidate_receipt.commitments_hash + ); + virtual_overseer + }); +} + +#[test] +fn observes_backing_even_if_not_validator() { + let test_state = TestState::default(); + let empty_keystore = Arc::new(sc_keystore::LocalKeystore::in_memory()); + test_harness(empty_keystore, |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![1, 2, 3]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let pov_hash = pov.hash(); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let candidate_a = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + + let candidate_a_hash = candidate_a.hash(); + let public0 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[0].to_seed()), + ) + .expect("Insert key into keystore"); + let public1 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[5].to_seed()), + ) + .expect("Insert key into keystore"); + let public2 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .expect("Insert key into keystore"); + + // Produce a 3-of-5 quorum on the candidate. + + let signed_a = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate_a.clone(), pvd.clone()), + &test_state.signing_context, + ValidatorIndex(0), + &public0.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let signed_b = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Valid(candidate_a_hash), + &test_state.signing_context, + ValidatorIndex(5), + &public1.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let signed_c = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Valid(candidate_a_hash), + &test_state.signing_context, + ValidatorIndex(2), + &public2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_b.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::Provisioner( + ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::BackedCandidate(candidate_receipt) + ) + ) => { + assert_eq!(candidate_receipt, candidate_a.to_plain()); + } + ); + + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_c.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; + virtual_overseer + }); +} + +// Tests that it's impossible to second multiple candidates per relay parent +// without prospective parachains. +#[test] +fn cannot_second_multiple_candidates_per_parent() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let pov_hash = pov.hash(); + let candidate_builder = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + }; + let candidate = candidate_builder.clone().build(); + + let second = CandidateBackingMessage::Second( + test_state.relay_parent, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive( + _pvd, + _validation_code, + candidate_receipt, + _pov, + timeout, + tx, + ), + ) if _pvd == pvd && + _validation_code == validation_code && + *_pov == pov && &candidate_receipt.descriptor == candidate.descriptor() && + timeout == PvfExecTimeoutKind::Backing && + candidate.commitments.hash() == candidate_receipt.commitments_hash => + { + tx.send(Ok(ValidationResult::Valid( + CandidateCommitments { + head_data: expected_head_data.clone(), + horizontal_messages: Default::default(), + upward_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0, + }, + test_state.validation_data.clone(), + ))) + .unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::StoreAvailableData { candidate_hash, tx, .. } + ) if candidate_hash == candidate.hash() => { + tx.send(Ok(())).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share( + parent_hash, + _signed_statement, + ) + ) if parent_hash == test_state.relay_parent => {} + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol(CollatorProtocolMessage::Seconded(hash, statement)) => { + assert_eq!(test_state.relay_parent, hash); + assert_matches!(statement.payload(), Statement::Seconded(_)); + } + ); + + // Try to second candidate with the same relay parent again. + + // Make sure the candidate hash is different. + let validation_code = ValidationCode(vec![4, 5, 6]); + let mut candidate_builder = candidate_builder; + candidate_builder.validation_code = validation_code.0.clone(); + let candidate = candidate_builder.build(); + + let second = CandidateBackingMessage::Second( + test_state.relay_parent, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + // The validation is still requested. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive(.., tx), + ) => { + tx.send(Ok(ValidationResult::Valid( + CandidateCommitments { + head_data: expected_head_data.clone(), + horizontal_messages: Default::default(), + upward_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0, + }, + test_state.validation_data.clone(), + ))) + .unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::StoreAvailableData { candidate_hash, tx, .. } + ) if candidate_hash == candidate.hash() => { + tx.send(Ok(())).unwrap(); + } + ); + + // Validation done, but the candidate is rejected cause of 0-depth being already occupied. + + assert!(virtual_overseer + .recv() + .timeout(std::time::Duration::from_millis(50)) + .await + .is_none()); + + virtual_overseer + }); +} + +#[test] +fn new_leaf_view_doesnt_clobber_old() { + let mut test_state = TestState::default(); + let relay_parent_2 = Hash::repeat_byte(1); + assert_ne!(test_state.relay_parent, relay_parent_2); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + // New leaf that doesn't clobber old. + { + let old_relay_parent = test_state.relay_parent; + test_state.relay_parent = relay_parent_2; + test_startup(&mut virtual_overseer, &test_state).await; + test_state.relay_parent = old_relay_parent; + } + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let pov_hash = pov.hash(); + let candidate = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + + let second = CandidateBackingMessage::Second( + test_state.relay_parent, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + // If the old leaf was clobbered by the first, the seconded candidate + // would be ignored. + assert!( + virtual_overseer + .recv() + .timeout(std::time::Duration::from_millis(500)) + .await + .is_some(), + "first leaf appears to be inactive" + ); + + virtual_overseer + }); +} diff --git a/polkadot/node/core/backing/src/tests/prospective_parachains.rs b/polkadot/node/core/backing/src/tests/prospective_parachains.rs new file mode 100644 index 0000000000000000000000000000000000000000..7c2773c8e3b6b1a4c6af62ef44af7edb95d1e498 --- /dev/null +++ b/polkadot/node/core/backing/src/tests/prospective_parachains.rs @@ -0,0 +1,1690 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests for the backing subsystem with enabled prospective parachains. + +use polkadot_node_subsystem::{ + messages::{ChainApiMessage, FragmentTreeMembership}, + TimeoutExt, +}; +use polkadot_primitives::{vstaging as vstaging_primitives, BlockNumber, Header, OccupiedCore}; + +use super::*; + +const ASYNC_BACKING_PARAMETERS: vstaging_primitives::AsyncBackingParams = + vstaging_primitives::AsyncBackingParams { max_candidate_depth: 4, allowed_ancestry_len: 3 }; + +struct TestLeaf { + activated: ActivatedLeaf, + min_relay_parents: Vec<(ParaId, u32)>, +} + +fn get_parent_hash(hash: Hash) -> Hash { + Hash::from_low_u64_be(hash.to_low_u64_be() + 1) +} + +async fn activate_leaf( + virtual_overseer: &mut VirtualOverseer, + leaf: TestLeaf, + test_state: &TestState, + seconded_in_view: usize, +) { + let TestLeaf { activated, min_relay_parents } = leaf; + let leaf_hash = activated.hash; + let leaf_number = activated.number; + // Start work on some new parent. + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( + activated, + )))) + .await; + + // Prospective parachains mode is temporarily defined by the Runtime API version. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) if parent == leaf_hash => { + tx.send(Ok(ASYNC_BACKING_PARAMETERS)).unwrap(); + } + ); + + let min_min = *min_relay_parents + .iter() + .map(|(_, block_num)| block_num) + .min() + .unwrap_or(&leaf_number); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetMinimumRelayParents(parent, tx) + ) if parent == leaf_hash => { + tx.send(min_relay_parents).unwrap(); + } + ); + + let ancestry_len = leaf_number + 1 - min_min; + + let ancestry_hashes = std::iter::successors(Some(leaf_hash), |h| Some(get_parent_hash(*h))) + .take(ancestry_len as usize); + let ancestry_numbers = (min_min..=leaf_number).rev(); + let ancestry_iter = ancestry_hashes.zip(ancestry_numbers).peekable(); + + let mut next_overseer_message = None; + // How many blocks were actually requested. + let mut requested_len = 0; + { + let mut ancestry_iter = ancestry_iter.clone(); + while let Some((hash, number)) = ancestry_iter.next() { + // May be `None` for the last element. + let parent_hash = + ancestry_iter.peek().map(|(h, _)| *h).unwrap_or_else(|| get_parent_hash(hash)); + + let msg = virtual_overseer.recv().await; + // It may happen that some blocks were cached by implicit view, + // reuse the message. + if !matches!(&msg, AllMessages::ChainApi(ChainApiMessage::BlockHeader(..))) { + next_overseer_message.replace(msg); + break + } + + assert_matches!( + msg, + AllMessages::ChainApi( + ChainApiMessage::BlockHeader(_hash, tx) + ) if _hash == hash => { + let header = Header { + parent_hash, + number, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + }; + + tx.send(Ok(Some(header))).unwrap(); + } + ); + requested_len += 1; + } + } + + for _ in 0..seconded_in_view { + let msg = match next_overseer_message.take() { + Some(msg) => msg, + None => virtual_overseer.recv().await, + }; + assert_matches!( + msg, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetTreeMembership(.., tx), + ) => { + tx.send(Vec::new()).unwrap(); + } + ); + } + + for (hash, number) in ancestry_iter.take(requested_len) { + // Check that subsystem job issues a request for a validator set. + let msg = match next_overseer_message.take() { + Some(msg) => msg, + None => virtual_overseer.recv().await, + }; + assert_matches!( + msg, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::Validators(tx)) + ) if parent == hash => { + tx.send(Ok(test_state.validator_public.clone())).unwrap(); + } + ); + + // Check that subsystem job issues a request for the validator groups. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::ValidatorGroups(tx)) + ) if parent == hash => { + let (validator_groups, mut group_rotation_info) = test_state.validator_groups.clone(); + group_rotation_info.now = number; + tx.send(Ok((validator_groups, group_rotation_info))).unwrap(); + } + ); + + // Check that subsystem job issues a request for the session index for child. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx)) + ) if parent == hash => { + tx.send(Ok(test_state.signing_context.session_index)).unwrap(); + } + ); + + // Check that subsystem job issues a request for the availability cores. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::AvailabilityCores(tx)) + ) if parent == hash => { + tx.send(Ok(test_state.availability_cores.clone())).unwrap(); + } + ); + } +} + +async fn assert_validate_seconded_candidate( + virtual_overseer: &mut VirtualOverseer, + relay_parent: Hash, + candidate: &CommittedCandidateReceipt, + pov: &PoV, + pvd: &PersistedValidationData, + validation_code: &ValidationCode, + expected_head_data: &HeadData, + fetch_pov: bool, +) { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if parent == relay_parent && hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + if fetch_pov { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityDistribution( + AvailabilityDistributionMessage::FetchPoV { + relay_parent: hash, + tx, + .. + } + ) if hash == relay_parent => { + tx.send(pov.clone()).unwrap(); + } + ); + } + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive( + _pvd, + _validation_code, + candidate_receipt, + _pov, + timeout, + tx, + )) if &_pvd == pvd && + &_validation_code == validation_code && + &*_pov == pov && + &candidate_receipt.descriptor == candidate.descriptor() && + timeout == PvfExecTimeoutKind::Backing && + candidate.commitments.hash() == candidate_receipt.commitments_hash => + { + tx.send(Ok(ValidationResult::Valid( + CandidateCommitments { + head_data: expected_head_data.clone(), + horizontal_messages: Default::default(), + upward_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0, + }, + pvd.clone(), + ))) + .unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::StoreAvailableData { candidate_hash, tx, .. } + ) if candidate_hash == candidate.hash() => { + tx.send(Ok(())).unwrap(); + } + ); +} + +async fn assert_hypothetical_frontier_requests( + virtual_overseer: &mut VirtualOverseer, + mut expected_requests: Vec<( + HypotheticalFrontierRequest, + Vec<(HypotheticalCandidate, FragmentTreeMembership)>, + )>, +) { + // Requests come with no particular order. + let requests_num = expected_requests.len(); + + for _ in 0..requests_num { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetHypotheticalFrontier(request, tx), + ) => { + let idx = match expected_requests.iter().position(|r| r.0 == request) { + Some(idx) => idx, + None => panic!( + "unexpected hypothetical frontier request, no match found for {:?}", + request + ), + }; + let resp = std::mem::take(&mut expected_requests[idx].1); + tx.send(resp).unwrap(); + + expected_requests.remove(idx); + } + ); + } +} + +fn make_hypothetical_frontier_response( + depths: Vec, + hypothetical_candidate: HypotheticalCandidate, + relay_parent_hash: Hash, +) -> Vec<(HypotheticalCandidate, FragmentTreeMembership)> { + vec![(hypothetical_candidate, vec![(relay_parent_hash, depths)])] +} + +// Test that `seconding_sanity_check` works when a candidate is allowed +// for all leaves. +#[test] +fn seconding_sanity_check_allowed() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + // Candidate is seconded in a parent of the activated `leaf_a`. + const LEAF_A_BLOCK_NUMBER: BlockNumber = 100; + const LEAF_A_ANCESTRY_LEN: BlockNumber = 3; + let para_id = test_state.chain_ids[0]; + + // `a` is grandparent of `b`. + let leaf_a_hash = Hash::from_low_u64_be(130); + let leaf_a_parent = get_parent_hash(leaf_a_hash); + let activated = ActivatedLeaf { + hash: leaf_a_hash, + number: LEAF_A_BLOCK_NUMBER, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + let min_relay_parents = vec![(para_id, LEAF_A_BLOCK_NUMBER - LEAF_A_ANCESTRY_LEN)]; + let test_leaf_a = TestLeaf { activated, min_relay_parents }; + + const LEAF_B_BLOCK_NUMBER: BlockNumber = LEAF_A_BLOCK_NUMBER + 2; + const LEAF_B_ANCESTRY_LEN: BlockNumber = 4; + + let leaf_b_hash = Hash::from_low_u64_be(128); + let activated = ActivatedLeaf { + hash: leaf_b_hash, + number: LEAF_B_BLOCK_NUMBER, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + let min_relay_parents = vec![(para_id, LEAF_B_BLOCK_NUMBER - LEAF_B_ANCESTRY_LEN)]; + let test_leaf_b = TestLeaf { activated, min_relay_parents }; + + activate_leaf(&mut virtual_overseer, test_leaf_a, &test_state, 0).await; + activate_leaf(&mut virtual_overseer, test_leaf_b, &test_state, 0).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(¶_id).unwrap(); + + let pov_hash = pov.hash(); + let candidate = TestCandidateBuilder { + para_id, + relay_parent: leaf_a_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + + let second = CandidateBackingMessage::Second( + leaf_a_hash, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_validate_seconded_candidate( + &mut virtual_overseer, + leaf_a_parent, + &candidate, + &pov, + &pvd, + &validation_code, + expected_head_data, + false, + ) + .await; + + // `seconding_sanity_check` + let hypothetical_candidate = HypotheticalCandidate::Complete { + candidate_hash: candidate.hash(), + receipt: Arc::new(candidate.clone()), + persisted_validation_data: pvd.clone(), + }; + let expected_request_a = HypotheticalFrontierRequest { + candidates: vec![hypothetical_candidate.clone()], + fragment_tree_relay_parent: Some(leaf_a_hash), + backed_in_path_only: false, + }; + let expected_response_a = make_hypothetical_frontier_response( + vec![0, 1, 2, 3], + hypothetical_candidate.clone(), + leaf_a_hash, + ); + let expected_request_b = HypotheticalFrontierRequest { + candidates: vec![hypothetical_candidate.clone()], + fragment_tree_relay_parent: Some(leaf_b_hash), + backed_in_path_only: false, + }; + let expected_response_b = + make_hypothetical_frontier_response(vec![3], hypothetical_candidate, leaf_b_hash); + assert_hypothetical_frontier_requests( + &mut virtual_overseer, + vec![ + (expected_request_a, expected_response_a), + (expected_request_b, expected_response_b), + ], + ) + .await; + // Prospective parachains are notified. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::IntroduceCandidate( + req, + tx, + ), + ) if + req.candidate_receipt == candidate + && req.candidate_para == para_id + && pvd == req.persisted_validation_data => { + // Any non-empty response will do. + tx.send(vec![(leaf_a_hash, vec![0, 1, 2, 3])]).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains(ProspectiveParachainsMessage::CandidateSeconded( + _, + _ + )) + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share( + parent_hash, + _signed_statement, + ) + ) if parent_hash == leaf_a_parent => {} + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol(CollatorProtocolMessage::Seconded(hash, statement)) => { + assert_eq!(leaf_a_parent, hash); + assert_matches!(statement.payload(), Statement::Seconded(_)); + } + ); + + virtual_overseer + }); +} + +// Test that `seconding_sanity_check` works when a candidate is disallowed +// for at least one leaf. +#[test] +fn seconding_sanity_check_disallowed() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + // Candidate is seconded in a parent of the activated `leaf_a`. + const LEAF_A_BLOCK_NUMBER: BlockNumber = 100; + const LEAF_A_ANCESTRY_LEN: BlockNumber = 3; + let para_id = test_state.chain_ids[0]; + + let leaf_b_hash = Hash::from_low_u64_be(128); + // `a` is grandparent of `b`. + let leaf_a_hash = Hash::from_low_u64_be(130); + let leaf_a_parent = get_parent_hash(leaf_a_hash); + let activated = ActivatedLeaf { + hash: leaf_a_hash, + number: LEAF_A_BLOCK_NUMBER, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + let min_relay_parents = vec![(para_id, LEAF_A_BLOCK_NUMBER - LEAF_A_ANCESTRY_LEN)]; + let test_leaf_a = TestLeaf { activated, min_relay_parents }; + + const LEAF_B_BLOCK_NUMBER: BlockNumber = LEAF_A_BLOCK_NUMBER + 2; + const LEAF_B_ANCESTRY_LEN: BlockNumber = 4; + + let activated = ActivatedLeaf { + hash: leaf_b_hash, + number: LEAF_B_BLOCK_NUMBER, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + let min_relay_parents = vec![(para_id, LEAF_B_BLOCK_NUMBER - LEAF_B_ANCESTRY_LEN)]; + let test_leaf_b = TestLeaf { activated, min_relay_parents }; + + activate_leaf(&mut virtual_overseer, test_leaf_a, &test_state, 0).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(¶_id).unwrap(); + + let pov_hash = pov.hash(); + let candidate = TestCandidateBuilder { + para_id, + relay_parent: leaf_a_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + + let second = CandidateBackingMessage::Second( + leaf_a_hash, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_validate_seconded_candidate( + &mut virtual_overseer, + leaf_a_parent, + &candidate, + &pov, + &pvd, + &validation_code, + expected_head_data, + false, + ) + .await; + + // `seconding_sanity_check` + let hypothetical_candidate = HypotheticalCandidate::Complete { + candidate_hash: candidate.hash(), + receipt: Arc::new(candidate.clone()), + persisted_validation_data: pvd.clone(), + }; + let expected_request_a = HypotheticalFrontierRequest { + candidates: vec![hypothetical_candidate.clone()], + fragment_tree_relay_parent: Some(leaf_a_hash), + backed_in_path_only: false, + }; + let expected_response_a = make_hypothetical_frontier_response( + vec![0, 1, 2, 3], + hypothetical_candidate, + leaf_a_hash, + ); + assert_hypothetical_frontier_requests( + &mut virtual_overseer, + vec![(expected_request_a, expected_response_a)], + ) + .await; + // Prospective parachains are notified. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::IntroduceCandidate( + req, + tx, + ), + ) if + req.candidate_receipt == candidate + && req.candidate_para == para_id + && pvd == req.persisted_validation_data => { + // Any non-empty response will do. + tx.send(vec![(leaf_a_hash, vec![0, 2, 3])]).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains(ProspectiveParachainsMessage::CandidateSeconded( + _, + _ + )) + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share( + parent_hash, + _signed_statement, + ) + ) if parent_hash == leaf_a_parent => {} + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol(CollatorProtocolMessage::Seconded(hash, statement)) => { + assert_eq!(leaf_a_parent, hash); + assert_matches!(statement.payload(), Statement::Seconded(_)); + } + ); + + // A seconded candidate occupies a depth, try to second another one. + // It is allowed in a new leaf but not allowed in the old one. + // Expect it to be rejected. + activate_leaf(&mut virtual_overseer, test_leaf_b, &test_state, 1).await; + let leaf_a_grandparent = get_parent_hash(leaf_a_parent); + let candidate = TestCandidateBuilder { + para_id, + relay_parent: leaf_a_grandparent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + + let second = CandidateBackingMessage::Second( + leaf_a_hash, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_validate_seconded_candidate( + &mut virtual_overseer, + leaf_a_grandparent, + &candidate, + &pov, + &pvd, + &validation_code, + expected_head_data, + false, + ) + .await; + + // `seconding_sanity_check` + + let hypothetical_candidate = HypotheticalCandidate::Complete { + candidate_hash: candidate.hash(), + receipt: Arc::new(candidate), + persisted_validation_data: pvd, + }; + let expected_request_a = HypotheticalFrontierRequest { + candidates: vec![hypothetical_candidate.clone()], + fragment_tree_relay_parent: Some(leaf_a_hash), + backed_in_path_only: false, + }; + let expected_response_a = make_hypothetical_frontier_response( + vec![3], + hypothetical_candidate.clone(), + leaf_a_hash, + ); + let expected_request_b = HypotheticalFrontierRequest { + candidates: vec![hypothetical_candidate.clone()], + fragment_tree_relay_parent: Some(leaf_b_hash), + backed_in_path_only: false, + }; + let expected_response_b = + make_hypothetical_frontier_response(vec![1], hypothetical_candidate, leaf_b_hash); + assert_hypothetical_frontier_requests( + &mut virtual_overseer, + vec![ + (expected_request_a, expected_response_a), // All depths are occupied. + (expected_request_b, expected_response_b), + ], + ) + .await; + + assert!(virtual_overseer + .recv() + .timeout(std::time::Duration::from_millis(50)) + .await + .is_none()); + + virtual_overseer + }); +} + +// Test that a seconded candidate which is not approved by prospective parachains +// subsystem doesn't change the view. +#[test] +fn prospective_parachains_reject_candidate() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + // Candidate is seconded in a parent of the activated `leaf_a`. + const LEAF_A_BLOCK_NUMBER: BlockNumber = 100; + const LEAF_A_ANCESTRY_LEN: BlockNumber = 3; + let para_id = test_state.chain_ids[0]; + + let leaf_a_hash = Hash::from_low_u64_be(130); + let leaf_a_parent = get_parent_hash(leaf_a_hash); + let activated = ActivatedLeaf { + hash: leaf_a_hash, + number: LEAF_A_BLOCK_NUMBER, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + let min_relay_parents = vec![(para_id, LEAF_A_BLOCK_NUMBER - LEAF_A_ANCESTRY_LEN)]; + let test_leaf_a = TestLeaf { activated, min_relay_parents }; + + activate_leaf(&mut virtual_overseer, test_leaf_a, &test_state, 0).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(¶_id).unwrap(); + + let pov_hash = pov.hash(); + let candidate = TestCandidateBuilder { + para_id, + relay_parent: leaf_a_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + + let second = CandidateBackingMessage::Second( + leaf_a_hash, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_validate_seconded_candidate( + &mut virtual_overseer, + leaf_a_parent, + &candidate, + &pov, + &pvd, + &validation_code, + expected_head_data, + false, + ) + .await; + + // `seconding_sanity_check` + let hypothetical_candidate = HypotheticalCandidate::Complete { + candidate_hash: candidate.hash(), + receipt: Arc::new(candidate.clone()), + persisted_validation_data: pvd.clone(), + }; + let expected_request_a = vec![( + HypotheticalFrontierRequest { + candidates: vec![hypothetical_candidate.clone()], + fragment_tree_relay_parent: Some(leaf_a_hash), + backed_in_path_only: false, + }, + make_hypothetical_frontier_response( + vec![0, 1, 2, 3], + hypothetical_candidate, + leaf_a_hash, + ), + )]; + assert_hypothetical_frontier_requests(&mut virtual_overseer, expected_request_a.clone()) + .await; + + // Prospective parachains are notified. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::IntroduceCandidate( + req, + tx, + ), + ) if + req.candidate_receipt == candidate + && req.candidate_para == para_id + && pvd == req.persisted_validation_data => { + // Reject it. + tx.send(Vec::new()).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol(CollatorProtocolMessage::Invalid( + relay_parent, + candidate_receipt, + )) if candidate_receipt.descriptor() == candidate.descriptor() && + candidate_receipt.commitments_hash == candidate.commitments.hash() && + relay_parent == leaf_a_parent + ); + + // Try seconding the same candidate. + + let second = CandidateBackingMessage::Second( + leaf_a_hash, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_validate_seconded_candidate( + &mut virtual_overseer, + leaf_a_parent, + &candidate, + &pov, + &pvd, + &validation_code, + expected_head_data, + false, + ) + .await; + + // `seconding_sanity_check` + assert_hypothetical_frontier_requests(&mut virtual_overseer, expected_request_a).await; + // Prospective parachains are notified. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::IntroduceCandidate( + req, + tx, + ), + ) if + req.candidate_receipt == candidate + && req.candidate_para == para_id + && pvd == req.persisted_validation_data => { + // Any non-empty response will do. + tx.send(vec![(leaf_a_hash, vec![0, 2, 3])]).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains(ProspectiveParachainsMessage::CandidateSeconded( + _, + _ + )) + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share( + parent_hash, + _signed_statement, + ) + ) if parent_hash == leaf_a_parent => {} + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol(CollatorProtocolMessage::Seconded(hash, statement)) => { + assert_eq!(leaf_a_parent, hash); + assert_matches!(statement.payload(), Statement::Seconded(_)); + } + ); + + virtual_overseer + }); +} + +// Test that a validator can second multiple candidates per single relay parent. +#[test] +fn second_multiple_candidates_per_relay_parent() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + // Candidate `a` is seconded in a parent of the activated `leaf`. + const LEAF_BLOCK_NUMBER: BlockNumber = 100; + const LEAF_ANCESTRY_LEN: BlockNumber = 3; + let para_id = test_state.chain_ids[0]; + + let leaf_hash = Hash::from_low_u64_be(130); + let leaf_parent = get_parent_hash(leaf_hash); + let leaf_grandparent = get_parent_hash(leaf_parent); + let activated = ActivatedLeaf { + hash: leaf_hash, + number: LEAF_BLOCK_NUMBER, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + let min_relay_parents = vec![(para_id, LEAF_BLOCK_NUMBER - LEAF_ANCESTRY_LEN)]; + let test_leaf_a = TestLeaf { activated, min_relay_parents }; + + activate_leaf(&mut virtual_overseer, test_leaf_a, &test_state, 0).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(¶_id).unwrap(); + + let pov_hash = pov.hash(); + let candidate_a = TestCandidateBuilder { + para_id, + relay_parent: leaf_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + }; + let mut candidate_b = candidate_a.clone(); + candidate_b.relay_parent = leaf_grandparent; + + // With depths. + let candidate_a = (candidate_a.build(), 1); + let candidate_b = (candidate_b.build(), 2); + + for candidate in &[candidate_a, candidate_b] { + let (candidate, depth) = candidate; + let second = CandidateBackingMessage::Second( + leaf_hash, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_validate_seconded_candidate( + &mut virtual_overseer, + candidate.descriptor().relay_parent, + &candidate, + &pov, + &pvd, + &validation_code, + expected_head_data, + false, + ) + .await; + + // `seconding_sanity_check` + let hypothetical_candidate = HypotheticalCandidate::Complete { + candidate_hash: candidate.hash(), + receipt: Arc::new(candidate.clone()), + persisted_validation_data: pvd.clone(), + }; + let expected_request_a = vec![( + HypotheticalFrontierRequest { + candidates: vec![hypothetical_candidate.clone()], + fragment_tree_relay_parent: Some(leaf_hash), + backed_in_path_only: false, + }, + make_hypothetical_frontier_response( + vec![*depth], + hypothetical_candidate, + leaf_hash, + ), + )]; + assert_hypothetical_frontier_requests( + &mut virtual_overseer, + expected_request_a.clone(), + ) + .await; + + // Prospective parachains are notified. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::IntroduceCandidate( + req, + tx, + ), + ) if + &req.candidate_receipt == candidate + && req.candidate_para == para_id + && pvd == req.persisted_validation_data + => { + // Any non-empty response will do. + tx.send(vec![(leaf_hash, vec![0, 2, 3])]).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::CandidateSeconded(_, _) + ) + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share( + parent_hash, + _signed_statement, + ) + ) if parent_hash == candidate.descriptor().relay_parent => {} + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol(CollatorProtocolMessage::Seconded(hash, statement)) => { + assert_eq!(candidate.descriptor().relay_parent, hash); + assert_matches!(statement.payload(), Statement::Seconded(_)); + } + ); + } + + virtual_overseer + }); +} + +// Test that the candidate reaches quorum successfully. +#[test] +fn backing_works() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + // Candidate `a` is seconded in a parent of the activated `leaf`. + const LEAF_BLOCK_NUMBER: BlockNumber = 100; + const LEAF_ANCESTRY_LEN: BlockNumber = 3; + let para_id = test_state.chain_ids[0]; + + let leaf_hash = Hash::from_low_u64_be(130); + let leaf_parent = get_parent_hash(leaf_hash); + let activated = ActivatedLeaf { + hash: leaf_hash, + number: LEAF_BLOCK_NUMBER, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + let min_relay_parents = vec![(para_id, LEAF_BLOCK_NUMBER - LEAF_ANCESTRY_LEN)]; + let test_leaf_a = TestLeaf { activated, min_relay_parents }; + + activate_leaf(&mut virtual_overseer, test_leaf_a, &test_state, 0).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(¶_id).unwrap(); + + let pov_hash = pov.hash(); + + let candidate_a = TestCandidateBuilder { + para_id, + relay_parent: leaf_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + validation_code: validation_code.0.clone(), + persisted_validation_data_hash: pvd.hash(), + } + .build(); + + let candidate_a_hash = candidate_a.hash(); + let candidate_a_para_head = candidate_a.descriptor().para_head; + + let public1 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[5].to_seed()), + ) + .expect("Insert key into keystore"); + let public2 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .expect("Insert key into keystore"); + + // Signing context should have a parent hash candidate is based on. + let signing_context = + SigningContext { parent_hash: leaf_parent, session_index: test_state.session() }; + let signed_a = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate_a.clone(), pvd.clone()), + &signing_context, + ValidatorIndex(2), + &public2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let signed_b = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Valid(candidate_a_hash), + &signing_context, + ValidatorIndex(5), + &public1.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let statement = CandidateBackingMessage::Statement(leaf_parent, signed_a.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + // Prospective parachains are notified about candidate seconded first. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::IntroduceCandidate( + req, + tx, + ), + ) if + req.candidate_receipt == candidate_a + && req.candidate_para == para_id + && pvd == req.persisted_validation_data => { + // Any non-empty response will do. + tx.send(vec![(leaf_hash, vec![0, 2, 3])]).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains(ProspectiveParachainsMessage::CandidateSeconded( + _, + _ + )) + ); + + assert_validate_seconded_candidate( + &mut virtual_overseer, + candidate_a.descriptor().relay_parent, + &candidate_a, + &pov, + &pvd, + &validation_code, + expected_head_data, + true, + ) + .await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share(hash, _stmt) + ) => { + assert_eq!(leaf_parent, hash); + } + ); + + // Prospective parachains and collator protocol are notified about candidate backed. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::CandidateBacked( + candidate_para_id, candidate_hash + ), + ) if candidate_a_hash == candidate_hash && candidate_para_id == para_id + ); + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol(CollatorProtocolMessage::Backed { + para_id: _para_id, + para_head, + }) if para_id == _para_id && candidate_a_para_head == para_head + ); + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution(StatementDistributionMessage::Backed ( + candidate_hash + )) if candidate_a_hash == candidate_hash + ); + + let statement = CandidateBackingMessage::Statement(leaf_parent, signed_b.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + virtual_overseer + }); +} + +// Tests that validators start work on consecutive prospective parachain blocks. +#[test] +fn concurrent_dependent_candidates() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + // Candidate `a` is seconded in a grandparent of the activated `leaf`, + // candidate `b` -- in parent. + const LEAF_BLOCK_NUMBER: BlockNumber = 100; + const LEAF_ANCESTRY_LEN: BlockNumber = 3; + let para_id = test_state.chain_ids[0]; + + let leaf_hash = Hash::from_low_u64_be(130); + let leaf_parent = get_parent_hash(leaf_hash); + let leaf_grandparent = get_parent_hash(leaf_parent); + let activated = ActivatedLeaf { + hash: leaf_hash, + number: LEAF_BLOCK_NUMBER, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + let min_relay_parents = vec![(para_id, LEAF_BLOCK_NUMBER - LEAF_ANCESTRY_LEN)]; + let test_leaf_a = TestLeaf { activated, min_relay_parents }; + + activate_leaf(&mut virtual_overseer, test_leaf_a, &test_state, 0).await; + + let head_data = &[ + HeadData(vec![10, 20, 30]), // Before `a`. + HeadData(vec![11, 21, 31]), // After `a`. + HeadData(vec![12, 22]), // After `b`. + ]; + + let pov_a = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd_a = PersistedValidationData { + parent_head: head_data[0].clone(), + relay_parent_number: LEAF_BLOCK_NUMBER - 2, + relay_parent_storage_root: Hash::zero(), + max_pov_size: 1024, + }; + + let pov_b = PoV { block_data: BlockData(vec![22, 14, 100]) }; + let pvd_b = PersistedValidationData { + parent_head: head_data[1].clone(), + relay_parent_number: LEAF_BLOCK_NUMBER - 1, + relay_parent_storage_root: Hash::zero(), + max_pov_size: 1024, + }; + let validation_code = ValidationCode(vec![1, 2, 3]); + + let candidate_a = TestCandidateBuilder { + para_id, + relay_parent: leaf_grandparent, + pov_hash: pov_a.hash(), + head_data: head_data[1].clone(), + erasure_root: make_erasure_root(&test_state, pov_a.clone(), pvd_a.clone()), + persisted_validation_data_hash: pvd_a.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + let candidate_b = TestCandidateBuilder { + para_id, + relay_parent: leaf_parent, + pov_hash: pov_b.hash(), + head_data: head_data[2].clone(), + erasure_root: make_erasure_root(&test_state, pov_b.clone(), pvd_b.clone()), + persisted_validation_data_hash: pvd_b.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + let candidate_a_hash = candidate_a.hash(); + let candidate_b_hash = candidate_b.hash(); + + let public1 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[5].to_seed()), + ) + .expect("Insert key into keystore"); + let public2 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .expect("Insert key into keystore"); + + // Signing context should have a parent hash candidate is based on. + let signing_context = + SigningContext { parent_hash: leaf_grandparent, session_index: test_state.session() }; + let signed_a = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate_a.clone(), pvd_a.clone()), + &signing_context, + ValidatorIndex(2), + &public2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let signing_context = + SigningContext { parent_hash: leaf_parent, session_index: test_state.session() }; + let signed_b = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate_b.clone(), pvd_b.clone()), + &signing_context, + ValidatorIndex(5), + &public1.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let statement_a = CandidateBackingMessage::Statement(leaf_grandparent, signed_a.clone()); + let statement_b = CandidateBackingMessage::Statement(leaf_parent, signed_b.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement_a }).await; + // At this point the subsystem waits for response, the previous message is received, + // send a second one without blocking. + let _ = virtual_overseer + .tx + .start_send_unpin(FromOrchestra::Communication { msg: statement_b }); + + let mut valid_statements = HashSet::new(); + let mut backed_statements = HashSet::new(); + + loop { + let msg = virtual_overseer + .recv() + .timeout(std::time::Duration::from_secs(1)) + .await + .expect("overseer recv timed out"); + + // Order is not guaranteed since we have 2 statements being handled concurrently. + match msg { + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::IntroduceCandidate(_, tx), + ) => { + tx.send(vec![(leaf_hash, vec![0, 2, 3])]).unwrap(); + }, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::CandidateSeconded(_, _), + ) => {}, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::ValidationCodeByHash(_, tx), + )) => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + }, + AllMessages::AvailabilityDistribution( + AvailabilityDistributionMessage::FetchPoV { candidate_hash, tx, .. }, + ) => { + let pov = if candidate_hash == candidate_a_hash { + &pov_a + } else if candidate_hash == candidate_b_hash { + &pov_b + } else { + panic!("unknown candidate hash") + }; + tx.send(pov.clone()).unwrap(); + }, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive(.., candidate, _, _, tx), + ) => { + let candidate_hash = candidate.hash(); + let (head_data, pvd) = if candidate_hash == candidate_a_hash { + (&head_data[1], &pvd_a) + } else if candidate_hash == candidate_b_hash { + (&head_data[2], &pvd_b) + } else { + panic!("unknown candidate hash") + }; + tx.send(Ok(ValidationResult::Valid( + CandidateCommitments { + head_data: head_data.clone(), + horizontal_messages: Default::default(), + upward_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0, + }, + pvd.clone(), + ))) + .unwrap(); + }, + AllMessages::AvailabilityStore(AvailabilityStoreMessage::StoreAvailableData { + tx, + .. + }) => { + tx.send(Ok(())).unwrap(); + }, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::CandidateBacked(..), + ) => {}, + AllMessages::CollatorProtocol(CollatorProtocolMessage::Backed { .. }) => {}, + AllMessages::StatementDistribution(StatementDistributionMessage::Share( + _, + statement, + )) => { + assert_eq!(statement.validator_index(), ValidatorIndex(0)); + let payload = statement.payload(); + assert_matches!( + payload.clone(), + StatementWithPVD::Valid(hash) + if hash == candidate_a_hash || hash == candidate_b_hash => + { + assert!(valid_statements.insert(hash)); + } + ); + }, + AllMessages::StatementDistribution(StatementDistributionMessage::Backed(hash)) => { + // Ensure that `Share` was received first for the candidate. + assert!(valid_statements.contains(&hash)); + backed_statements.insert(hash); + + if backed_statements.len() == 2 { + break + } + }, + _ => panic!("unexpected message received from overseer: {:?}", msg), + } + } + + assert!(valid_statements.contains(&candidate_a_hash)); + assert!(valid_statements.contains(&candidate_b_hash)); + assert!(backed_statements.contains(&candidate_a_hash)); + assert!(backed_statements.contains(&candidate_b_hash)); + + virtual_overseer + }); +} + +// Test that multiple candidates from different paras can occupy the same depth +// in a given relay parent. +#[test] +fn seconding_sanity_check_occupy_same_depth() { + let test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + // Candidate `a` is seconded in a parent of the activated `leaf`. + const LEAF_BLOCK_NUMBER: BlockNumber = 100; + const LEAF_ANCESTRY_LEN: BlockNumber = 3; + + let para_id_a = test_state.chain_ids[0]; + let para_id_b = test_state.chain_ids[1]; + + let leaf_hash = Hash::from_low_u64_be(130); + let leaf_parent = get_parent_hash(leaf_hash); + + let activated = ActivatedLeaf { + hash: leaf_hash, + number: LEAF_BLOCK_NUMBER, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + + let min_block_number = LEAF_BLOCK_NUMBER - LEAF_ANCESTRY_LEN; + let min_relay_parents = vec![(para_id_a, min_block_number), (para_id_b, min_block_number)]; + let test_leaf_a = TestLeaf { activated, min_relay_parents }; + + activate_leaf(&mut virtual_overseer, test_leaf_a, &test_state, 0).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data_a = test_state.head_data.get(¶_id_a).unwrap(); + let expected_head_data_b = test_state.head_data.get(¶_id_b).unwrap(); + + let pov_hash = pov.hash(); + let candidate_a = TestCandidateBuilder { + para_id: para_id_a, + relay_parent: leaf_parent, + pov_hash, + head_data: expected_head_data_a.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + }; + + let mut candidate_b = candidate_a.clone(); + candidate_b.para_id = para_id_b; + candidate_b.head_data = expected_head_data_b.clone(); + // A rotation happens, test validator is assigned to second para here. + candidate_b.relay_parent = leaf_hash; + + let candidate_a = (candidate_a.build(), expected_head_data_a, para_id_a); + let candidate_b = (candidate_b.build(), expected_head_data_b, para_id_b); + + for candidate in &[candidate_a, candidate_b] { + let (candidate, expected_head_data, para_id) = candidate; + let second = CandidateBackingMessage::Second( + leaf_hash, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_validate_seconded_candidate( + &mut virtual_overseer, + candidate.descriptor().relay_parent, + &candidate, + &pov, + &pvd, + &validation_code, + expected_head_data, + false, + ) + .await; + + // `seconding_sanity_check` + let hypothetical_candidate = HypotheticalCandidate::Complete { + candidate_hash: candidate.hash(), + receipt: Arc::new(candidate.clone()), + persisted_validation_data: pvd.clone(), + }; + let expected_request_a = vec![( + HypotheticalFrontierRequest { + candidates: vec![hypothetical_candidate.clone()], + fragment_tree_relay_parent: Some(leaf_hash), + backed_in_path_only: false, + }, + // Send the same membership for both candidates. + make_hypothetical_frontier_response(vec![0, 1], hypothetical_candidate, leaf_hash), + )]; + + assert_hypothetical_frontier_requests( + &mut virtual_overseer, + expected_request_a.clone(), + ) + .await; + + // Prospective parachains are notified. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::IntroduceCandidate( + req, + tx, + ), + ) if + &req.candidate_receipt == candidate + && &req.candidate_para == para_id + && pvd == req.persisted_validation_data + => { + // Any non-empty response will do. + tx.send(vec![(leaf_hash, vec![0, 2, 3])]).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::CandidateSeconded(_, _) + ) + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share( + parent_hash, + _signed_statement, + ) + ) if parent_hash == candidate.descriptor().relay_parent => {} + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol(CollatorProtocolMessage::Seconded(hash, statement)) => { + assert_eq!(candidate.descriptor().relay_parent, hash); + assert_matches!(statement.payload(), Statement::Seconded(_)); + } + ); + } + + virtual_overseer + }); +} + +// Test that the subsystem doesn't skip occupied cores assignments. +#[test] +fn occupied_core_assignment() { + let mut test_state = TestState::default(); + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + // Candidate is seconded in a parent of the activated `leaf_a`. + const LEAF_A_BLOCK_NUMBER: BlockNumber = 100; + const LEAF_A_ANCESTRY_LEN: BlockNumber = 3; + let para_id = test_state.chain_ids[0]; + + // Set the core state to occupied. + let mut candidate_descriptor = ::test_helpers::dummy_candidate_descriptor(Hash::zero()); + candidate_descriptor.para_id = para_id; + test_state.availability_cores[0] = CoreState::Occupied(OccupiedCore { + group_responsible: Default::default(), + next_up_on_available: None, + occupied_since: 100_u32, + time_out_at: 200_u32, + next_up_on_time_out: None, + availability: Default::default(), + candidate_descriptor, + candidate_hash: Default::default(), + }); + + let leaf_a_hash = Hash::from_low_u64_be(130); + let leaf_a_parent = get_parent_hash(leaf_a_hash); + let activated = ActivatedLeaf { + hash: leaf_a_hash, + number: LEAF_A_BLOCK_NUMBER, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + let min_relay_parents = vec![(para_id, LEAF_A_BLOCK_NUMBER - LEAF_A_ANCESTRY_LEN)]; + let test_leaf_a = TestLeaf { activated, min_relay_parents }; + + activate_leaf(&mut virtual_overseer, test_leaf_a, &test_state, 0).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(¶_id).unwrap(); + + let pov_hash = pov.hash(); + let candidate = TestCandidateBuilder { + para_id, + relay_parent: leaf_a_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + + let second = CandidateBackingMessage::Second( + leaf_a_hash, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + assert_validate_seconded_candidate( + &mut virtual_overseer, + leaf_a_parent, + &candidate, + &pov, + &pvd, + &validation_code, + expected_head_data, + false, + ) + .await; + + // `seconding_sanity_check` + let hypothetical_candidate = HypotheticalCandidate::Complete { + candidate_hash: candidate.hash(), + receipt: Arc::new(candidate.clone()), + persisted_validation_data: pvd.clone(), + }; + let expected_request = vec![( + HypotheticalFrontierRequest { + candidates: vec![hypothetical_candidate.clone()], + fragment_tree_relay_parent: Some(leaf_a_hash), + backed_in_path_only: false, + }, + make_hypothetical_frontier_response( + vec![0, 1, 2, 3], + hypothetical_candidate, + leaf_a_hash, + ), + )]; + assert_hypothetical_frontier_requests(&mut virtual_overseer, expected_request).await; + // Prospective parachains are notified. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::IntroduceCandidate( + req, + tx, + ), + ) if + req.candidate_receipt == candidate + && req.candidate_para == para_id + && pvd == req.persisted_validation_data + => { + // Any non-empty response will do. + tx.send(vec![(leaf_a_hash, vec![0, 1, 2, 3])]).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains(ProspectiveParachainsMessage::CandidateSeconded( + _, + _ + )) + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share( + parent_hash, + _signed_statement, + ) + ) if parent_hash == leaf_a_parent => {} + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol(CollatorProtocolMessage::Seconded(hash, statement)) => { + assert_eq!(leaf_a_parent, hash); + assert_matches!(statement.payload(), Statement::Seconded(_)); + } + ); + + virtual_overseer + }); +} diff --git a/polkadot/node/core/bitfield-signing/Cargo.toml b/polkadot/node/core/bitfield-signing/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..ee147fb5c22a9598eea72868d228654675591f4b --- /dev/null +++ b/polkadot/node/core/bitfield-signing/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "polkadot-node-core-bitfield-signing" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +gum = { package = "tracing-gum", path = "../../gum" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +wasm-timer = "0.2.5" +thiserror = "1.0.31" + +[dev-dependencies] +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/core/bitfield-signing/src/lib.rs b/polkadot/node/core/bitfield-signing/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..f29e827e109025de2541c932df55192a21e3e03a --- /dev/null +++ b/polkadot/node/core/bitfield-signing/src/lib.rs @@ -0,0 +1,334 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The bitfield signing subsystem produces `SignedAvailabilityBitfield`s once per block. + +#![deny(unused_crate_dependencies)] +#![warn(missing_docs)] +#![recursion_limit = "256"] + +use futures::{ + channel::{mpsc, oneshot}, + future, + lock::Mutex, + FutureExt, +}; +use polkadot_node_subsystem::{ + errors::RuntimeApiError, + jaeger, + messages::{ + AvailabilityStoreMessage, BitfieldDistributionMessage, RuntimeApiMessage, RuntimeApiRequest, + }, + overseer, ActivatedLeaf, FromOrchestra, LeafStatus, OverseerSignal, PerLeafSpan, + SpawnedSubsystem, SubsystemError, SubsystemResult, SubsystemSender, +}; +use polkadot_node_subsystem_util::{self as util, Validator}; +use polkadot_primitives::{AvailabilityBitfield, CoreState, Hash, ValidatorIndex}; +use sp_keystore::{Error as KeystoreError, KeystorePtr}; +use std::{collections::HashMap, iter::FromIterator, time::Duration}; +use wasm_timer::{Delay, Instant}; + +mod metrics; +use self::metrics::Metrics; + +#[cfg(test)] +mod tests; + +/// Delay between starting a bitfield signing job and its attempting to create a bitfield. +const SPAWNED_TASK_DELAY: Duration = Duration::from_millis(1500); +const LOG_TARGET: &str = "parachain::bitfield-signing"; + +// TODO: use `fatality` (https://github.com/paritytech/polkadot/issues/5540). +/// Errors we may encounter in the course of executing the `BitfieldSigningSubsystem`. +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum Error { + #[error(transparent)] + Util(#[from] util::Error), + + #[error(transparent)] + Io(#[from] std::io::Error), + + #[error(transparent)] + Oneshot(#[from] oneshot::Canceled), + + #[error(transparent)] + MpscSend(#[from] mpsc::SendError), + + #[error(transparent)] + Runtime(#[from] RuntimeApiError), + + #[error("Keystore failed: {0:?}")] + Keystore(KeystoreError), +} + +/// If there is a candidate pending availability, query the Availability Store +/// for whether we have the availability chunk for our validator index. +async fn get_core_availability( + core: &CoreState, + validator_idx: ValidatorIndex, + sender: &Mutex<&mut impl SubsystemSender>, + span: &jaeger::Span, +) -> Result { + if let CoreState::Occupied(core) = core { + let _span = span.child("query-chunk-availability"); + + let (tx, rx) = oneshot::channel(); + sender + .lock() + .await + .send_message( + AvailabilityStoreMessage::QueryChunkAvailability( + core.candidate_hash, + validator_idx, + tx, + ) + .into(), + ) + .await; + + let res = rx.await.map_err(Into::into); + + gum::trace!( + target: LOG_TARGET, + para_id = %core.para_id(), + availability = ?res, + ?core.candidate_hash, + "Candidate availability", + ); + + res + } else { + Ok(false) + } +} + +/// delegates to the v1 runtime API +async fn get_availability_cores( + relay_parent: Hash, + sender: &mut impl SubsystemSender, +) -> Result, Error> { + let (tx, rx) = oneshot::channel(); + sender + .send_message( + RuntimeApiMessage::Request(relay_parent, RuntimeApiRequest::AvailabilityCores(tx)) + .into(), + ) + .await; + match rx.await { + Ok(Ok(out)) => Ok(out), + Ok(Err(runtime_err)) => Err(runtime_err.into()), + Err(err) => Err(err.into()), + } +} + +/// - get the list of core states from the runtime +/// - for each core, concurrently determine chunk availability (see `get_core_availability`) +/// - return the bitfield if there were no errors at any point in this process (otherwise, it's +/// prone to false negatives) +async fn construct_availability_bitfield( + relay_parent: Hash, + span: &jaeger::Span, + validator_idx: ValidatorIndex, + sender: &mut impl SubsystemSender, +) -> Result { + // get the set of availability cores from the runtime + let availability_cores = { + let _span = span.child("get-availability-cores"); + get_availability_cores(relay_parent, sender).await? + }; + + // Wrap the sender in a Mutex to share it between the futures. + // + // We use a `Mutex` here to not `clone` the sender inside the future, because + // cloning the sender will always increase the capacity of the channel by one. + // (for the lifetime of the sender) + let sender = Mutex::new(sender); + + // Handle all cores concurrently + // `try_join_all` returns all results in the same order as the input futures. + let results = future::try_join_all( + availability_cores + .iter() + .map(|core| get_core_availability(core, validator_idx, &sender, span)), + ) + .await?; + + let core_bits = FromIterator::from_iter(results.into_iter()); + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + "Signing Bitfield for {core_count} cores: {core_bits}", + core_count = availability_cores.len(), + core_bits = core_bits, + ); + + Ok(AvailabilityBitfield(core_bits)) +} + +/// The bitfield signing subsystem. +pub struct BitfieldSigningSubsystem { + keystore: KeystorePtr, + metrics: Metrics, +} + +impl BitfieldSigningSubsystem { + /// Create a new instance of the `BitfieldSigningSubsystem`. + pub fn new(keystore: KeystorePtr, metrics: Metrics) -> Self { + Self { keystore, metrics } + } +} + +#[overseer::subsystem(BitfieldSigning, error=SubsystemError, prefix=self::overseer)] +impl BitfieldSigningSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = async move { + run(ctx, self.keystore, self.metrics) + .await + .map_err(|e| SubsystemError::with_origin("bitfield-signing", e)) + } + .boxed(); + + SpawnedSubsystem { name: "bitfield-signing-subsystem", future } + } +} + +#[overseer::contextbounds(BitfieldSigning, prefix = self::overseer)] +async fn run( + mut ctx: Context, + keystore: KeystorePtr, + metrics: Metrics, +) -> SubsystemResult<()> { + // Track spawned jobs per active leaf. + let mut running = HashMap::::new(); + + loop { + match ctx.recv().await? { + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => { + // Abort jobs for deactivated leaves. + for leaf in &update.deactivated { + if let Some(handle) = running.remove(leaf) { + handle.abort(); + } + } + + if let Some(leaf) = update.activated { + let sender = ctx.sender().clone(); + let leaf_hash = leaf.hash; + + let (fut, handle) = future::abortable(handle_active_leaves_update( + sender, + leaf, + keystore.clone(), + metrics.clone(), + )); + + running.insert(leaf_hash, handle); + + ctx.spawn("bitfield-signing-job", fut.map(drop).boxed())?; + } + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {}, + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), + FromOrchestra::Communication { .. } => {}, + } + } +} + +async fn handle_active_leaves_update( + mut sender: Sender, + leaf: ActivatedLeaf, + keystore: KeystorePtr, + metrics: Metrics, +) -> Result<(), Error> +where + Sender: overseer::BitfieldSigningSenderTrait, +{ + if let LeafStatus::Stale = leaf.status { + gum::debug!( + target: LOG_TARGET, + relay_parent = ?leaf.hash, + block_number = ?leaf.number, + "Skip bitfield signing for stale leaf" + ); + return Ok(()) + } + + let span = PerLeafSpan::new(leaf.span, "bitfield-signing"); + let span_delay = span.child("delay"); + let wait_until = Instant::now() + SPAWNED_TASK_DELAY; + + // now do all the work we can before we need to wait for the availability store + // if we're not a validator, we can just succeed effortlessly + let validator = match Validator::new(leaf.hash, keystore.clone(), &mut sender).await { + Ok(validator) => validator, + Err(util::Error::NotAValidator) => return Ok(()), + Err(err) => return Err(Error::Util(err)), + }; + + // wait a bit before doing anything else + Delay::new_at(wait_until).await?; + + // this timer does not appear at the head of the function because we don't want to include + // SPAWNED_TASK_DELAY each time. + let _timer = metrics.time_run(); + + drop(span_delay); + let span_availability = span.child("availability"); + + let bitfield = match construct_availability_bitfield( + leaf.hash, + &span_availability, + validator.index(), + &mut sender, + ) + .await + { + Err(Error::Runtime(runtime_err)) => { + // Don't take down the node on runtime API errors. + gum::warn!(target: LOG_TARGET, err = ?runtime_err, "Encountered a runtime API error"); + return Ok(()) + }, + Err(err) => return Err(err), + Ok(bitfield) => bitfield, + }; + + drop(span_availability); + let span_signing = span.child("signing"); + + let signed_bitfield = + match validator.sign(keystore, bitfield).map_err(|e| Error::Keystore(e))? { + Some(b) => b, + None => { + gum::error!( + target: LOG_TARGET, + "Key was found at construction, but while signing it could not be found.", + ); + return Ok(()) + }, + }; + + metrics.on_bitfield_signed(); + + drop(span_signing); + let _span_gossip = span.child("gossip"); + + sender + .send_message(BitfieldDistributionMessage::DistributeBitfield(leaf.hash, signed_bitfield)) + .await; + + Ok(()) +} diff --git a/polkadot/node/core/bitfield-signing/src/metrics.rs b/polkadot/node/core/bitfield-signing/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..ec66af82e599aa8589ec198f1b2de3e2898d630c --- /dev/null +++ b/polkadot/node/core/bitfield-signing/src/metrics.rs @@ -0,0 +1,68 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) bitfields_signed_total: prometheus::Counter, + pub(crate) run: prometheus::Histogram, +} + +/// Bitfield signing metrics. +#[derive(Default, Clone)] +pub struct Metrics(pub(crate) Option); + +impl Metrics { + pub fn on_bitfield_signed(&self) { + if let Some(metrics) = &self.0 { + metrics.bitfields_signed_total.inc(); + } + } + + /// Provide a timer for `prune_povs` which observes on drop. + pub fn time_run(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.run.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + bitfields_signed_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_bitfields_signed_total", + "Number of bitfields signed.", + )?, + registry, + )?, + run: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_bitfield_signing_run", + "Time spent within `bitfield_signing::run`", + ) + .buckets(vec![ + 0.000625, 0.00125, 0.0025, 0.005, 0.0075, 0.01, 0.025, 0.05, 0.1, 0.25, + 0.5, 1.0, 2.5, 5.0, 10.0, + ]), + )?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/core/bitfield-signing/src/tests.rs b/polkadot/node/core/bitfield-signing/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..106ecc06b1569862d7adeacada748e03b586b4ec --- /dev/null +++ b/polkadot/node/core/bitfield-signing/src/tests.rs @@ -0,0 +1,85 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use futures::{executor::block_on, pin_mut, StreamExt}; +use polkadot_node_subsystem::messages::AllMessages; +use polkadot_primitives::{CandidateHash, OccupiedCore}; +use test_helpers::dummy_candidate_descriptor; + +fn occupied_core(para_id: u32, candidate_hash: CandidateHash) -> CoreState { + CoreState::Occupied(OccupiedCore { + group_responsible: para_id.into(), + next_up_on_available: None, + occupied_since: 100_u32, + time_out_at: 200_u32, + next_up_on_time_out: None, + availability: Default::default(), + candidate_hash, + candidate_descriptor: dummy_candidate_descriptor(Hash::zero()), + }) +} + +#[test] +fn construct_availability_bitfield_works() { + block_on(async move { + let relay_parent = Hash::default(); + let validator_index = ValidatorIndex(1u32); + + let (mut sender, mut receiver) = polkadot_node_subsystem_test_helpers::sender_receiver(); + let future = construct_availability_bitfield( + relay_parent, + &jaeger::Span::Disabled, + validator_index, + &mut sender, + ) + .fuse(); + pin_mut!(future); + + let hash_a = CandidateHash(Hash::repeat_byte(1)); + let hash_b = CandidateHash(Hash::repeat_byte(2)); + + loop { + futures::select! { + m = receiver.next() => match m.unwrap() { + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(rp, RuntimeApiRequest::AvailabilityCores(tx)), + ) => { + assert_eq!(relay_parent, rp); + tx.send(Ok(vec![CoreState::Free, occupied_core(1, hash_a), occupied_core(2, hash_b)])).unwrap(); + } + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::QueryChunkAvailability(c_hash, vidx, tx), + ) => { + assert_eq!(validator_index, vidx); + + tx.send(c_hash == hash_a).unwrap(); + }, + o => panic!("Unknown message: {:?}", o), + }, + r = future => match r { + Ok(r) => { + assert!(!r.0.get(0).unwrap()); + assert!(r.0.get(1).unwrap()); + assert!(!r.0.get(2).unwrap()); + break + }, + Err(e) => panic!("Failed: {:?}", e), + }, + } + } + }); +} diff --git a/polkadot/node/core/candidate-validation/Cargo.toml b/polkadot/node/core/candidate-validation/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..0401c892d426f8da46496b8622613f7c791ed183 --- /dev/null +++ b/polkadot/node/core/candidate-validation/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "polkadot-node-core-candidate-validation" +description = "Polkadot crate that implements the Candidate Validation subsystem. Handles requests to validate candidates according to a PVF." +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +async-trait = "0.1.57" +futures = "0.3.21" +futures-timer = "3.0.2" +gum = { package = "tracing-gum", path = "../../gum" } + +sp-maybe-compressed-blob = { package = "sp-maybe-compressed-blob", git = "https://github.com/paritytech/substrate", branch = "master" } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["bit-vec", "derive"] } + +polkadot-primitives = { path = "../../../primitives" } +polkadot-parachain = { path = "../../../parachain" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-node-metrics = { path = "../../metrics" } +polkadot-overseer = { path = "../../overseer" } + +[target.'cfg(not(any(target_os = "android", target_os = "unknown")))'.dependencies] +polkadot-node-core-pvf = { path = "../pvf" } + +[dev-dependencies] +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures = { version = "0.3.21", features = ["thread-pool"] } +assert_matches = "1.4.0" +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..f53f2a6aee066c236827001ad8149cf67b74cf7f --- /dev/null +++ b/polkadot/node/core/candidate-validation/src/lib.rs @@ -0,0 +1,903 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Candidate Validation subsystem. +//! +//! This handles incoming requests from other subsystems to validate candidates +//! according to a validation function. This delegates validation to an underlying +//! pool of processes used for execution of the Wasm. + +#![deny(unused_crate_dependencies, unused_results)] +#![warn(missing_docs)] + +use polkadot_node_core_pvf::{ + InternalValidationError, InvalidCandidate as WasmInvalidCandidate, PrepareError, + PrepareJobKind, PrepareStats, PvfPrepData, ValidationError, ValidationHost, +}; +use polkadot_node_primitives::{ + BlockData, InvalidCandidate, PoV, ValidationResult, POV_BOMB_LIMIT, VALIDATION_CODE_BOMB_LIMIT, +}; +use polkadot_node_subsystem::{ + errors::RuntimeApiError, + messages::{ + CandidateValidationMessage, PreCheckOutcome, RuntimeApiMessage, RuntimeApiRequest, + ValidationFailed, + }, + overseer, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, SubsystemResult, + SubsystemSender, +}; +use polkadot_node_subsystem_util::executor_params_at_relay_parent; +use polkadot_parachain::primitives::{ValidationParams, ValidationResult as WasmValidationResult}; +use polkadot_primitives::{ + CandidateCommitments, CandidateDescriptor, CandidateReceipt, ExecutorParams, Hash, + OccupiedCoreAssumption, PersistedValidationData, PvfExecTimeoutKind, PvfPrepTimeoutKind, + ValidationCode, ValidationCodeHash, +}; + +use parity_scale_codec::Encode; + +use futures::{channel::oneshot, prelude::*}; + +use std::{ + path::PathBuf, + sync::Arc, + time::{Duration, Instant}, +}; + +use async_trait::async_trait; + +mod metrics; +use self::metrics::Metrics; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &'static str = "parachain::candidate-validation"; + +/// The amount of time to wait before retrying after a retry-able backing validation error. We use a +/// lower value for the backing case, to fit within the lower backing timeout. +#[cfg(not(test))] +const PVF_BACKING_EXECUTION_RETRY_DELAY: Duration = Duration::from_millis(500); +#[cfg(test)] +const PVF_BACKING_EXECUTION_RETRY_DELAY: Duration = Duration::from_millis(200); +/// The amount of time to wait before retrying after a retry-able approval validation error. We use +/// a higher value for the approval case since we have more time, and if we wait longer it is more +/// likely that transient conditions will resolve. +#[cfg(not(test))] +const PVF_APPROVAL_EXECUTION_RETRY_DELAY: Duration = Duration::from_secs(3); +#[cfg(test)] +const PVF_APPROVAL_EXECUTION_RETRY_DELAY: Duration = Duration::from_millis(200); + +// Default PVF timeouts. Must never be changed! Use executor environment parameters in +// `session_info` pallet to adjust them. See also `PvfTimeoutKind` docs. +const DEFAULT_PRECHECK_PREPARATION_TIMEOUT: Duration = Duration::from_secs(60); +const DEFAULT_LENIENT_PREPARATION_TIMEOUT: Duration = Duration::from_secs(360); +const DEFAULT_BACKING_EXECUTION_TIMEOUT: Duration = Duration::from_secs(2); +const DEFAULT_APPROVAL_EXECUTION_TIMEOUT: Duration = Duration::from_secs(12); + +/// Configuration for the candidate validation subsystem +#[derive(Clone)] +pub struct Config { + /// The path where candidate validation can store compiled artifacts for PVFs. + pub artifacts_cache_path: PathBuf, + /// The version of the node. `None` can be passed to skip the version check (only for tests). + pub node_version: Option, + /// Path to the preparation worker binary + pub prep_worker_path: PathBuf, + /// Path to the execution worker binary + pub exec_worker_path: PathBuf, +} + +/// The candidate validation subsystem. +pub struct CandidateValidationSubsystem { + #[allow(missing_docs)] + pub metrics: Metrics, + #[allow(missing_docs)] + pub pvf_metrics: polkadot_node_core_pvf::Metrics, + config: Option, +} + +impl CandidateValidationSubsystem { + /// Create a new `CandidateValidationSubsystem` with the given task spawner and isolation + /// strategy. + /// + /// Check out [`IsolationStrategy`] to get more details. + pub fn with_config( + config: Option, + metrics: Metrics, + pvf_metrics: polkadot_node_core_pvf::Metrics, + ) -> Self { + CandidateValidationSubsystem { config, metrics, pvf_metrics } + } +} + +#[overseer::subsystem(CandidateValidation, error=SubsystemError, prefix=self::overseer)] +impl CandidateValidationSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + if let Some(config) = self.config { + let future = run(ctx, self.metrics, self.pvf_metrics, config) + .map_err(|e| SubsystemError::with_origin("candidate-validation", e)) + .boxed(); + SpawnedSubsystem { name: "candidate-validation-subsystem", future } + } else { + polkadot_overseer::DummySubsystem.start(ctx) + } + } +} + +#[overseer::contextbounds(CandidateValidation, prefix = self::overseer)] +async fn run( + mut ctx: Context, + metrics: Metrics, + pvf_metrics: polkadot_node_core_pvf::Metrics, + Config { artifacts_cache_path, node_version, prep_worker_path, exec_worker_path }: Config, +) -> SubsystemResult<()> { + let (validation_host, task) = polkadot_node_core_pvf::start( + polkadot_node_core_pvf::Config::new( + artifacts_cache_path, + node_version, + prep_worker_path, + exec_worker_path, + ), + pvf_metrics, + ); + ctx.spawn_blocking("pvf-validation-host", task.boxed())?; + + loop { + match ctx.recv().await? { + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(_)) => {}, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {}, + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), + FromOrchestra::Communication { msg } => match msg { + CandidateValidationMessage::ValidateFromChainState( + candidate_receipt, + pov, + timeout, + response_sender, + ) => { + let bg = { + let mut sender = ctx.sender().clone(); + let metrics = metrics.clone(); + let validation_host = validation_host.clone(); + + async move { + let _timer = metrics.time_validate_from_chain_state(); + let res = validate_from_chain_state( + &mut sender, + validation_host, + candidate_receipt, + pov, + timeout, + &metrics, + ) + .await; + + metrics.on_validation_event(&res); + let _ = response_sender.send(res); + } + }; + + ctx.spawn("validate-from-chain-state", bg.boxed())?; + }, + CandidateValidationMessage::ValidateFromExhaustive( + persisted_validation_data, + validation_code, + candidate_receipt, + pov, + timeout, + response_sender, + ) => { + let bg = { + let mut sender = ctx.sender().clone(); + let metrics = metrics.clone(); + let validation_host = validation_host.clone(); + + async move { + let _timer = metrics.time_validate_from_exhaustive(); + let res = validate_candidate_exhaustive( + &mut sender, + validation_host, + persisted_validation_data, + validation_code, + candidate_receipt, + pov, + timeout, + &metrics, + ) + .await; + + metrics.on_validation_event(&res); + let _ = response_sender.send(res); + } + }; + + ctx.spawn("validate-from-exhaustive", bg.boxed())?; + }, + CandidateValidationMessage::PreCheck( + relay_parent, + validation_code_hash, + response_sender, + ) => { + let bg = { + let mut sender = ctx.sender().clone(); + let validation_host = validation_host.clone(); + + async move { + let precheck_result = precheck_pvf( + &mut sender, + validation_host, + relay_parent, + validation_code_hash, + ) + .await; + + let _ = response_sender.send(precheck_result); + } + }; + + ctx.spawn("candidate-validation-pre-check", bg.boxed())?; + }, + }, + } + } +} + +struct RuntimeRequestFailed; + +async fn runtime_api_request( + sender: &mut Sender, + relay_parent: Hash, + request: RuntimeApiRequest, + receiver: oneshot::Receiver>, +) -> Result +where + Sender: SubsystemSender, +{ + sender + .send_message(RuntimeApiMessage::Request(relay_parent, request).into()) + .await; + + receiver + .await + .map_err(|_| { + gum::debug!(target: LOG_TARGET, ?relay_parent, "Runtime API request dropped"); + + RuntimeRequestFailed + }) + .and_then(|res| { + res.map_err(|e| { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + err = ?e, + "Runtime API request internal error" + ); + + RuntimeRequestFailed + }) + }) +} + +async fn request_validation_code_by_hash( + sender: &mut Sender, + relay_parent: Hash, + validation_code_hash: ValidationCodeHash, +) -> Result, RuntimeRequestFailed> +where + Sender: SubsystemSender, +{ + let (tx, rx) = oneshot::channel(); + runtime_api_request( + sender, + relay_parent, + RuntimeApiRequest::ValidationCodeByHash(validation_code_hash, tx), + rx, + ) + .await +} + +async fn precheck_pvf( + sender: &mut Sender, + mut validation_backend: impl ValidationBackend, + relay_parent: Hash, + validation_code_hash: ValidationCodeHash, +) -> PreCheckOutcome +where + Sender: SubsystemSender, +{ + let validation_code = + match request_validation_code_by_hash(sender, relay_parent, validation_code_hash).await { + Ok(Some(code)) => code, + _ => { + // The reasoning why this is "failed" and not invalid is because we assume that + // during pre-checking voting the relay-chain will pin the code. In case the code + // actually is not there, we issue failed since this looks more like a bug. + gum::warn!( + target: LOG_TARGET, + ?relay_parent, + ?validation_code_hash, + "precheck: requested validation code is not found on-chain!", + ); + return PreCheckOutcome::Failed + }, + }; + + let executor_params = + if let Ok(executor_params) = executor_params_at_relay_parent(relay_parent, sender).await { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + ?validation_code_hash, + "precheck: acquired executor params for the session: {:?}", + executor_params, + ); + executor_params + } else { + gum::warn!( + target: LOG_TARGET, + ?relay_parent, + ?validation_code_hash, + "precheck: failed to acquire executor params for the session, thus voting against.", + ); + return PreCheckOutcome::Invalid + }; + + let timeout = pvf_prep_timeout(&executor_params, PvfPrepTimeoutKind::Precheck); + + let pvf = match sp_maybe_compressed_blob::decompress( + &validation_code.0, + VALIDATION_CODE_BOMB_LIMIT, + ) { + Ok(code) => PvfPrepData::from_code( + code.into_owned(), + executor_params, + timeout, + PrepareJobKind::Prechecking, + ), + Err(e) => { + gum::debug!(target: LOG_TARGET, err=?e, "precheck: cannot decompress validation code"); + return PreCheckOutcome::Invalid + }, + }; + + match validation_backend.precheck_pvf(pvf).await { + Ok(_) => PreCheckOutcome::Valid, + Err(prepare_err) => + if prepare_err.is_deterministic() { + PreCheckOutcome::Invalid + } else { + PreCheckOutcome::Failed + }, + } +} + +#[derive(Debug)] +enum AssumptionCheckOutcome { + Matches(PersistedValidationData, ValidationCode), + DoesNotMatch, + BadRequest, +} + +async fn check_assumption_validation_data( + sender: &mut Sender, + descriptor: &CandidateDescriptor, + assumption: OccupiedCoreAssumption, +) -> AssumptionCheckOutcome +where + Sender: SubsystemSender, +{ + let validation_data = { + let (tx, rx) = oneshot::channel(); + let d = runtime_api_request( + sender, + descriptor.relay_parent, + RuntimeApiRequest::PersistedValidationData(descriptor.para_id, assumption, tx), + rx, + ) + .await; + + match d { + Ok(None) | Err(RuntimeRequestFailed) => return AssumptionCheckOutcome::BadRequest, + Ok(Some(d)) => d, + } + }; + + let persisted_validation_data_hash = validation_data.hash(); + + if descriptor.persisted_validation_data_hash == persisted_validation_data_hash { + let (code_tx, code_rx) = oneshot::channel(); + let validation_code = runtime_api_request( + sender, + descriptor.relay_parent, + RuntimeApiRequest::ValidationCode(descriptor.para_id, assumption, code_tx), + code_rx, + ) + .await; + + match validation_code { + Ok(None) | Err(RuntimeRequestFailed) => AssumptionCheckOutcome::BadRequest, + Ok(Some(v)) => AssumptionCheckOutcome::Matches(validation_data, v), + } + } else { + AssumptionCheckOutcome::DoesNotMatch + } +} + +async fn find_assumed_validation_data( + sender: &mut Sender, + descriptor: &CandidateDescriptor, +) -> AssumptionCheckOutcome +where + Sender: SubsystemSender, +{ + // The candidate descriptor has a `persisted_validation_data_hash` which corresponds to + // one of up to two possible values that we can derive from the state of the + // relay-parent. We can fetch these values by getting the persisted validation data + // based on the different `OccupiedCoreAssumption`s. + + const ASSUMPTIONS: &[OccupiedCoreAssumption] = &[ + OccupiedCoreAssumption::Included, + OccupiedCoreAssumption::TimedOut, + // `TimedOut` and `Free` both don't perform any speculation and therefore should be the + // same for our purposes here. In other words, if `TimedOut` matched then the `Free` must + // be matched as well. + ]; + + // Consider running these checks in parallel to reduce validation latency. + for assumption in ASSUMPTIONS { + let outcome = check_assumption_validation_data(sender, descriptor, *assumption).await; + + match outcome { + AssumptionCheckOutcome::Matches(_, _) => return outcome, + AssumptionCheckOutcome::BadRequest => return outcome, + AssumptionCheckOutcome::DoesNotMatch => continue, + } + } + + AssumptionCheckOutcome::DoesNotMatch +} + +/// Returns validation data for a given candidate. +pub async fn find_validation_data( + sender: &mut Sender, + descriptor: &CandidateDescriptor, +) -> Result, ValidationFailed> +where + Sender: SubsystemSender, +{ + match find_assumed_validation_data(sender, &descriptor).await { + AssumptionCheckOutcome::Matches(validation_data, validation_code) => + Ok(Some((validation_data, validation_code))), + AssumptionCheckOutcome::DoesNotMatch => { + // If neither the assumption of the occupied core having the para included or the + // assumption of the occupied core timing out are valid, then the + // persisted_validation_data_hash in the descriptor is not based on the relay parent and + // is thus invalid. + Ok(None) + }, + AssumptionCheckOutcome::BadRequest => + Err(ValidationFailed("Assumption Check: Bad request".into())), + } +} + +async fn validate_from_chain_state( + sender: &mut Sender, + validation_host: ValidationHost, + candidate_receipt: CandidateReceipt, + pov: Arc, + exec_timeout_kind: PvfExecTimeoutKind, + metrics: &Metrics, +) -> Result +where + Sender: SubsystemSender, +{ + let mut new_sender = sender.clone(); + let (validation_data, validation_code) = + match find_validation_data(&mut new_sender, &candidate_receipt.descriptor).await? { + Some((validation_data, validation_code)) => (validation_data, validation_code), + None => return Ok(ValidationResult::Invalid(InvalidCandidate::BadParent)), + }; + + let validation_result = validate_candidate_exhaustive( + sender, + validation_host, + validation_data, + validation_code, + candidate_receipt.clone(), + pov, + exec_timeout_kind, + metrics, + ) + .await; + + if let Ok(ValidationResult::Valid(ref outputs, _)) = validation_result { + let (tx, rx) = oneshot::channel(); + match runtime_api_request( + sender, + candidate_receipt.descriptor.relay_parent, + RuntimeApiRequest::CheckValidationOutputs( + candidate_receipt.descriptor.para_id, + outputs.clone(), + tx, + ), + rx, + ) + .await + { + Ok(true) => {}, + Ok(false) => return Ok(ValidationResult::Invalid(InvalidCandidate::InvalidOutputs)), + Err(RuntimeRequestFailed) => + return Err(ValidationFailed("Check Validation Outputs: Bad request".into())), + } + } + + validation_result +} + +async fn validate_candidate_exhaustive( + sender: &mut Sender, + mut validation_backend: impl ValidationBackend + Send, + persisted_validation_data: PersistedValidationData, + validation_code: ValidationCode, + candidate_receipt: CandidateReceipt, + pov: Arc, + exec_timeout_kind: PvfExecTimeoutKind, + metrics: &Metrics, +) -> Result +where + Sender: SubsystemSender, +{ + let _timer = metrics.time_validate_candidate_exhaustive(); + + let validation_code_hash = validation_code.hash(); + let para_id = candidate_receipt.descriptor.para_id; + gum::debug!( + target: LOG_TARGET, + ?validation_code_hash, + ?para_id, + "About to validate a candidate.", + ); + + if let Err(e) = perform_basic_checks( + &candidate_receipt.descriptor, + persisted_validation_data.max_pov_size, + &pov, + &validation_code_hash, + ) { + gum::info!(target: LOG_TARGET, ?para_id, "Invalid candidate (basic checks)"); + return Ok(ValidationResult::Invalid(e)) + } + + let raw_validation_code = match sp_maybe_compressed_blob::decompress( + &validation_code.0, + VALIDATION_CODE_BOMB_LIMIT, + ) { + Ok(code) => code, + Err(e) => { + gum::info!(target: LOG_TARGET, ?para_id, err=?e, "Invalid candidate (validation code)"); + + // Code already passed pre-checking, if decompression fails now this most likley means + // some local corruption happened. + return Err(ValidationFailed("Code decompression failed".to_string())) + }, + }; + metrics.observe_code_size(raw_validation_code.len()); + + metrics.observe_pov_size(pov.block_data.0.len(), true); + let raw_block_data = + match sp_maybe_compressed_blob::decompress(&pov.block_data.0, POV_BOMB_LIMIT) { + Ok(block_data) => BlockData(block_data.to_vec()), + Err(e) => { + gum::info!(target: LOG_TARGET, ?para_id, err=?e, "Invalid candidate (PoV code)"); + + // If the PoV is invalid, the candidate certainly is. + return Ok(ValidationResult::Invalid(InvalidCandidate::PoVDecompressionFailure)) + }, + }; + metrics.observe_pov_size(raw_block_data.0.len(), false); + + let params = ValidationParams { + parent_head: persisted_validation_data.parent_head.clone(), + block_data: raw_block_data, + relay_parent_number: persisted_validation_data.relay_parent_number, + relay_parent_storage_root: persisted_validation_data.relay_parent_storage_root, + }; + + let executor_params = if let Ok(executor_params) = + executor_params_at_relay_parent(candidate_receipt.descriptor.relay_parent, sender).await + { + gum::debug!( + target: LOG_TARGET, + ?validation_code_hash, + ?para_id, + "Acquired executor params for the session: {:?}", + executor_params, + ); + executor_params + } else { + gum::warn!( + target: LOG_TARGET, + ?validation_code_hash, + ?para_id, + "Failed to acquire executor params for the session", + ); + return Ok(ValidationResult::Invalid(InvalidCandidate::BadParent)) + }; + + let result = validation_backend + .validate_candidate_with_retry( + raw_validation_code.to_vec(), + pvf_exec_timeout(&executor_params, exec_timeout_kind), + exec_timeout_kind, + params, + executor_params, + ) + .await; + + if let Err(ref error) = result { + gum::info!(target: LOG_TARGET, ?para_id, ?error, "Failed to validate candidate"); + } + + match result { + Err(ValidationError::InternalError(e)) => { + gum::warn!( + target: LOG_TARGET, + ?para_id, + ?e, + "An internal error occurred during validation, will abstain from voting", + ); + Err(ValidationFailed(e.to_string())) + }, + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::HardTimeout)) => + Ok(ValidationResult::Invalid(InvalidCandidate::Timeout)), + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::WorkerReportedError(e))) => + Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(e))), + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)) => + Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError( + "ambiguous worker death".to_string(), + ))), + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::Panic(err))) => + Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(err))), + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::PrepareError(e))) => { + // In principle if preparation of the `WASM` fails, the current candidate can not be the + // reason for that. So we can't say whether it is invalid or not. In addition, with + // pre-checking enabled only valid runtimes should ever get enacted, so we can be + // reasonably sure that this is some local problem on the current node. However, as this + // particular error *seems* to indicate a deterministic error, we raise a warning. + gum::warn!( + target: LOG_TARGET, + ?para_id, + ?e, + "Deterministic error occurred during preparation (should have been ruled out by pre-checking phase)", + ); + Err(ValidationFailed(e)) + }, + Ok(res) => + if res.head_data.hash() != candidate_receipt.descriptor.para_head { + gum::info!(target: LOG_TARGET, ?para_id, "Invalid candidate (para_head)"); + Ok(ValidationResult::Invalid(InvalidCandidate::ParaHeadHashMismatch)) + } else { + let outputs = CandidateCommitments { + head_data: res.head_data, + upward_messages: res.upward_messages, + horizontal_messages: res.horizontal_messages, + new_validation_code: res.new_validation_code, + processed_downward_messages: res.processed_downward_messages, + hrmp_watermark: res.hrmp_watermark, + }; + if candidate_receipt.commitments_hash != outputs.hash() { + gum::info!( + target: LOG_TARGET, + ?para_id, + "Invalid candidate (commitments hash)" + ); + + // If validation produced a new set of commitments, we treat the candidate as + // invalid. + Ok(ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch)) + } else { + Ok(ValidationResult::Valid(outputs, persisted_validation_data)) + } + }, + } +} + +#[async_trait] +trait ValidationBackend { + /// Tries executing a PVF a single time (no retries). + async fn validate_candidate( + &mut self, + pvf: PvfPrepData, + exec_timeout: Duration, + encoded_params: Vec, + ) -> Result; + + /// Tries executing a PVF. Will retry once if an error is encountered that may have been + /// transient. + /// + /// NOTE: Should retry only on errors that are a result of execution itself, and not of + /// preparation. + async fn validate_candidate_with_retry( + &mut self, + raw_validation_code: Vec, + exec_timeout: Duration, + exec_timeout_kind: PvfExecTimeoutKind, + params: ValidationParams, + executor_params: ExecutorParams, + ) -> Result { + let prep_timeout = pvf_prep_timeout(&executor_params, PvfPrepTimeoutKind::Lenient); + // Construct the PVF a single time, since it is an expensive operation. Cloning it is cheap. + let pvf = PvfPrepData::from_code( + raw_validation_code, + executor_params, + prep_timeout, + PrepareJobKind::Compilation, + ); + // We keep track of the total time that has passed and stop retrying if we are taking too + // long. + let total_time_start = Instant::now(); + + let mut validation_result = + self.validate_candidate(pvf.clone(), exec_timeout, params.encode()).await; + if validation_result.is_ok() { + return validation_result + } + + let retry_delay = match exec_timeout_kind { + PvfExecTimeoutKind::Backing => PVF_BACKING_EXECUTION_RETRY_DELAY, + PvfExecTimeoutKind::Approval => PVF_APPROVAL_EXECUTION_RETRY_DELAY, + }; + + // Allow limited retries for each kind of error. + let mut num_internal_retries_left = 1; + let mut num_awd_retries_left = 1; + let mut num_panic_retries_left = 1; + loop { + // Stop retrying if we exceeded the timeout. + if total_time_start.elapsed() + retry_delay > exec_timeout { + break + } + + match validation_result { + Err(ValidationError::InvalidCandidate( + WasmInvalidCandidate::AmbiguousWorkerDeath, + )) if num_awd_retries_left > 0 => num_awd_retries_left -= 1, + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::Panic(_))) + if num_panic_retries_left > 0 => + num_panic_retries_left -= 1, + Err(ValidationError::InternalError(_)) if num_internal_retries_left > 0 => + num_internal_retries_left -= 1, + _ => break, + } + + // If we got a possibly transient error, retry once after a brief delay, on the + // assumption that the conditions that caused this error may have resolved on their own. + { + // Wait a brief delay before retrying. + futures_timer::Delay::new(retry_delay).await; + + let new_timeout = exec_timeout.saturating_sub(total_time_start.elapsed()); + + gum::warn!( + target: LOG_TARGET, + ?pvf, + ?new_timeout, + "Re-trying failed candidate validation due to possible transient error: {:?}", + validation_result + ); + + // Encode the params again when re-trying. We expect the retry case to be relatively + // rare, and we want to avoid unconditionally cloning data. + validation_result = + self.validate_candidate(pvf.clone(), new_timeout, params.encode()).await; + } + } + + validation_result + } + + async fn precheck_pvf(&mut self, pvf: PvfPrepData) -> Result; +} + +#[async_trait] +impl ValidationBackend for ValidationHost { + /// Tries executing a PVF a single time (no retries). + async fn validate_candidate( + &mut self, + pvf: PvfPrepData, + exec_timeout: Duration, + encoded_params: Vec, + ) -> Result { + let priority = polkadot_node_core_pvf::Priority::Normal; + + let (tx, rx) = oneshot::channel(); + if let Err(err) = self.execute_pvf(pvf, exec_timeout, encoded_params, priority, tx).await { + return Err(InternalValidationError::HostCommunication(format!( + "cannot send pvf to the validation host, it might have shut down: {:?}", + err + )) + .into()) + } + + rx.await.map_err(|_| { + ValidationError::from(InternalValidationError::HostCommunication( + "validation was cancelled".into(), + )) + })? + } + + async fn precheck_pvf(&mut self, pvf: PvfPrepData) -> Result { + let (tx, rx) = oneshot::channel(); + if let Err(err) = self.precheck_pvf(pvf, tx).await { + // Return an IO error if there was an error communicating with the host. + return Err(PrepareError::IoErr(err)) + } + + let precheck_result = rx.await.map_err(|err| PrepareError::IoErr(err.to_string()))?; + + precheck_result + } +} + +/// Does basic checks of a candidate. Provide the encoded PoV-block. Returns `Ok` if basic checks +/// are passed, `Err` otherwise. +fn perform_basic_checks( + candidate: &CandidateDescriptor, + max_pov_size: u32, + pov: &PoV, + validation_code_hash: &ValidationCodeHash, +) -> Result<(), InvalidCandidate> { + let pov_hash = pov.hash(); + + let encoded_pov_size = pov.encoded_size(); + if encoded_pov_size > max_pov_size as usize { + return Err(InvalidCandidate::ParamsTooLarge(encoded_pov_size as u64)) + } + + if pov_hash != candidate.pov_hash { + return Err(InvalidCandidate::PoVHashMismatch) + } + + if *validation_code_hash != candidate.validation_code_hash { + return Err(InvalidCandidate::CodeHashMismatch) + } + + if let Err(()) = candidate.check_collator_signature() { + return Err(InvalidCandidate::BadSignature) + } + + Ok(()) +} + +fn pvf_prep_timeout(executor_params: &ExecutorParams, kind: PvfPrepTimeoutKind) -> Duration { + if let Some(timeout) = executor_params.pvf_prep_timeout(kind) { + return timeout + } + match kind { + PvfPrepTimeoutKind::Precheck => DEFAULT_PRECHECK_PREPARATION_TIMEOUT, + PvfPrepTimeoutKind::Lenient => DEFAULT_LENIENT_PREPARATION_TIMEOUT, + } +} + +fn pvf_exec_timeout(executor_params: &ExecutorParams, kind: PvfExecTimeoutKind) -> Duration { + if let Some(timeout) = executor_params.pvf_exec_timeout(kind) { + return timeout + } + match kind { + PvfExecTimeoutKind::Backing => DEFAULT_BACKING_EXECUTION_TIMEOUT, + PvfExecTimeoutKind::Approval => DEFAULT_APPROVAL_EXECUTION_TIMEOUT, + } +} diff --git a/polkadot/node/core/candidate-validation/src/metrics.rs b/polkadot/node/core/candidate-validation/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..28fc957ddb1a7acd0b5c67f4a52e70bf5e56f734 --- /dev/null +++ b/polkadot/node/core/candidate-validation/src/metrics.rs @@ -0,0 +1,154 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::{ValidationFailed, ValidationResult}; +use polkadot_node_metrics::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) validation_requests: prometheus::CounterVec, + pub(crate) validate_from_chain_state: prometheus::Histogram, + pub(crate) validate_from_exhaustive: prometheus::Histogram, + pub(crate) validate_candidate_exhaustive: prometheus::Histogram, + pub(crate) pov_size: prometheus::HistogramVec, + pub(crate) code_size: prometheus::Histogram, +} + +/// Candidate validation metrics. +#[derive(Default, Clone)] +pub struct Metrics(Option); + +impl Metrics { + pub fn on_validation_event(&self, event: &Result) { + if let Some(metrics) = &self.0 { + match event { + Ok(ValidationResult::Valid(_, _)) => { + metrics.validation_requests.with_label_values(&["valid"]).inc(); + }, + Ok(ValidationResult::Invalid(_)) => { + metrics.validation_requests.with_label_values(&["invalid"]).inc(); + }, + Err(_) => { + metrics.validation_requests.with_label_values(&["validation failure"]).inc(); + }, + } + } + } + + /// Provide a timer for `validate_from_chain_state` which observes on drop. + pub fn time_validate_from_chain_state( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.validate_from_chain_state.start_timer()) + } + + /// Provide a timer for `validate_from_exhaustive` which observes on drop. + pub fn time_validate_from_exhaustive( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.validate_from_exhaustive.start_timer()) + } + + /// Provide a timer for `validate_candidate_exhaustive` which observes on drop. + pub fn time_validate_candidate_exhaustive( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.validate_candidate_exhaustive.start_timer()) + } + + pub fn observe_code_size(&self, code_size: usize) { + if let Some(metrics) = &self.0 { + metrics.code_size.observe(code_size as f64); + } + } + + pub fn observe_pov_size(&self, pov_size: usize, compressed: bool) { + if let Some(metrics) = &self.0 { + metrics + .pov_size + .with_label_values(&[if compressed { "true" } else { "false" }]) + .observe(pov_size as f64); + } + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + validation_requests: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_validation_requests_total", + "Number of validation requests served.", + ), + &["validity"], + )?, + registry, + )?, + validate_from_chain_state: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_validation_validate_from_chain_state", + "Time spent within `candidate_validation::validate_from_chain_state`", + ))?, + registry, + )?, + validate_from_exhaustive: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_validation_validate_from_exhaustive", + "Time spent within `candidate_validation::validate_from_exhaustive`", + ))?, + registry, + )?, + validate_candidate_exhaustive: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_validation_validate_candidate_exhaustive", + "Time spent within `candidate_validation::validate_candidate_exhaustive`", + ))?, + registry, + )?, + pov_size: prometheus::register( + prometheus::HistogramVec::new( + prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_validation_pov_size", + "The compressed and decompressed size of the proof of validity of a candidate", + ) + .buckets( + prometheus::exponential_buckets(16384.0, 2.0, 10) + .expect("arguments are always valid; qed"), + ), + &["compressed"], + )?, + registry, + )?, + code_size: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_validation_code_size", + "The size of the decompressed WASM validation blob used for checking a candidate", + ) + .buckets( + prometheus::exponential_buckets(16384.0, 2.0, 10) + .expect("arguments are always valid; qed"), + ), + )?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/core/candidate-validation/src/tests.rs b/polkadot/node/core/candidate-validation/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..2dcead4db466510001f732e61ab542c78b8829e5 --- /dev/null +++ b/polkadot/node/core/candidate-validation/src/tests.rs @@ -0,0 +1,1319 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use ::test_helpers::{dummy_hash, make_valid_candidate_descriptor}; +use assert_matches::assert_matches; +use futures::executor; +use polkadot_node_core_pvf::PrepareError; +use polkadot_node_subsystem::messages::AllMessages; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_node_subsystem_util::reexports::SubsystemContext; +use polkadot_primitives::{HeadData, Id as ParaId, UpwardMessage}; +use sp_core::testing::TaskExecutor; +use sp_keyring::Sr25519Keyring; + +fn test_with_executor_params, R, M>( + mut ctx_handle: test_helpers::TestSubsystemContextHandle, + test: impl FnOnce() -> T, +) -> R { + let test_fut = test(); + + let overseer = async move { + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx)) + ) => { + tx.send(Ok(1u32.into())).unwrap(); + } + ); + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(_, tx)) + ) => { + tx.send(Ok(Some(ExecutorParams::default()))).unwrap(); + } + ); + }; + + futures::pin_mut!(test_fut); + futures::pin_mut!(overseer); + let v = executor::block_on(future::join(test_fut, overseer)); + v.0 +} + +#[test] +fn correctly_checks_included_assumption() { + let validation_data: PersistedValidationData = Default::default(); + let validation_code: ValidationCode = vec![1, 2, 3].into(); + + let persisted_validation_data_hash = validation_data.hash(); + let relay_parent = [2; 32].into(); + let para_id = ParaId::from(5_u32); + + let descriptor = make_valid_candidate_descriptor( + para_id, + relay_parent, + persisted_validation_data_hash, + dummy_hash(), + dummy_hash(), + dummy_hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + + let (check_fut, check_result) = check_assumption_validation_data( + ctx.sender(), + &descriptor, + OccupiedCoreAssumption::Included, + ) + .remote_handle(); + + let test_fut = async move { + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + rp, + RuntimeApiRequest::PersistedValidationData( + p, + OccupiedCoreAssumption::Included, + tx + ), + )) => { + assert_eq!(rp, relay_parent); + assert_eq!(p, para_id); + + let _ = tx.send(Ok(Some(validation_data.clone()))); + } + ); + + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + rp, + RuntimeApiRequest::ValidationCode(p, OccupiedCoreAssumption::Included, tx) + )) => { + assert_eq!(rp, relay_parent); + assert_eq!(p, para_id); + + let _ = tx.send(Ok(Some(validation_code.clone()))); + } + ); + + assert_matches!(check_result.await, AssumptionCheckOutcome::Matches(o, v) => { + assert_eq!(o, validation_data); + assert_eq!(v, validation_code); + }); + }; + + let test_fut = future::join(test_fut, check_fut); + executor::block_on(test_fut); +} + +#[test] +fn correctly_checks_timed_out_assumption() { + let validation_data: PersistedValidationData = Default::default(); + let validation_code: ValidationCode = vec![1, 2, 3].into(); + + let persisted_validation_data_hash = validation_data.hash(); + let relay_parent = [2; 32].into(); + let para_id = ParaId::from(5_u32); + + let descriptor = make_valid_candidate_descriptor( + para_id, + relay_parent, + persisted_validation_data_hash, + dummy_hash(), + dummy_hash(), + dummy_hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + + let (check_fut, check_result) = check_assumption_validation_data( + ctx.sender(), + &descriptor, + OccupiedCoreAssumption::TimedOut, + ) + .remote_handle(); + + let test_fut = async move { + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + rp, + RuntimeApiRequest::PersistedValidationData( + p, + OccupiedCoreAssumption::TimedOut, + tx + ), + )) => { + assert_eq!(rp, relay_parent); + assert_eq!(p, para_id); + + let _ = tx.send(Ok(Some(validation_data.clone()))); + } + ); + + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + rp, + RuntimeApiRequest::ValidationCode(p, OccupiedCoreAssumption::TimedOut, tx) + )) => { + assert_eq!(rp, relay_parent); + assert_eq!(p, para_id); + + let _ = tx.send(Ok(Some(validation_code.clone()))); + } + ); + + assert_matches!(check_result.await, AssumptionCheckOutcome::Matches(o, v) => { + assert_eq!(o, validation_data); + assert_eq!(v, validation_code); + }); + }; + + let test_fut = future::join(test_fut, check_fut); + executor::block_on(test_fut); +} + +#[test] +fn check_is_bad_request_if_no_validation_data() { + let validation_data: PersistedValidationData = Default::default(); + let persisted_validation_data_hash = validation_data.hash(); + let relay_parent = [2; 32].into(); + let para_id = ParaId::from(5_u32); + + let descriptor = make_valid_candidate_descriptor( + para_id, + relay_parent, + persisted_validation_data_hash, + dummy_hash(), + dummy_hash(), + dummy_hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + + let (check_fut, check_result) = check_assumption_validation_data( + ctx.sender(), + &descriptor, + OccupiedCoreAssumption::Included, + ) + .remote_handle(); + + let test_fut = async move { + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + rp, + RuntimeApiRequest::PersistedValidationData( + p, + OccupiedCoreAssumption::Included, + tx + ), + )) => { + assert_eq!(rp, relay_parent); + assert_eq!(p, para_id); + + let _ = tx.send(Ok(None)); + } + ); + + assert_matches!(check_result.await, AssumptionCheckOutcome::BadRequest); + }; + + let test_fut = future::join(test_fut, check_fut); + executor::block_on(test_fut); +} + +#[test] +fn check_is_bad_request_if_no_validation_code() { + let validation_data: PersistedValidationData = Default::default(); + let persisted_validation_data_hash = validation_data.hash(); + let relay_parent = [2; 32].into(); + let para_id = ParaId::from(5_u32); + + let descriptor = make_valid_candidate_descriptor( + para_id, + relay_parent, + persisted_validation_data_hash, + dummy_hash(), + dummy_hash(), + dummy_hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + + let (check_fut, check_result) = check_assumption_validation_data( + ctx.sender(), + &descriptor, + OccupiedCoreAssumption::TimedOut, + ) + .remote_handle(); + + let test_fut = async move { + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + rp, + RuntimeApiRequest::PersistedValidationData( + p, + OccupiedCoreAssumption::TimedOut, + tx + ), + )) => { + assert_eq!(rp, relay_parent); + assert_eq!(p, para_id); + + let _ = tx.send(Ok(Some(validation_data.clone()))); + } + ); + + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + rp, + RuntimeApiRequest::ValidationCode(p, OccupiedCoreAssumption::TimedOut, tx) + )) => { + assert_eq!(rp, relay_parent); + assert_eq!(p, para_id); + + let _ = tx.send(Ok(None)); + } + ); + + assert_matches!(check_result.await, AssumptionCheckOutcome::BadRequest); + }; + + let test_fut = future::join(test_fut, check_fut); + executor::block_on(test_fut); +} + +#[test] +fn check_does_not_match() { + let validation_data: PersistedValidationData = Default::default(); + let relay_parent = Hash::repeat_byte(0x02); + let para_id = ParaId::from(5_u32); + + let descriptor = make_valid_candidate_descriptor( + para_id, + relay_parent, + Hash::from([3; 32]), + dummy_hash(), + dummy_hash(), + dummy_hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + + let (check_fut, check_result) = check_assumption_validation_data( + ctx.sender(), + &descriptor, + OccupiedCoreAssumption::Included, + ) + .remote_handle(); + + let test_fut = async move { + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + rp, + RuntimeApiRequest::PersistedValidationData( + p, + OccupiedCoreAssumption::Included, + tx + ), + )) => { + assert_eq!(rp, relay_parent); + assert_eq!(p, para_id); + + let _ = tx.send(Ok(Some(validation_data.clone()))); + } + ); + + assert_matches!(check_result.await, AssumptionCheckOutcome::DoesNotMatch); + }; + + let test_fut = future::join(test_fut, check_fut); + executor::block_on(test_fut); +} + +struct MockValidateCandidateBackend { + result_list: Vec>, + num_times_called: usize, +} + +impl MockValidateCandidateBackend { + fn with_hardcoded_result(result: Result) -> Self { + Self { result_list: vec![result], num_times_called: 0 } + } + + fn with_hardcoded_result_list( + result_list: Vec>, + ) -> Self { + Self { result_list, num_times_called: 0 } + } +} + +#[async_trait] +impl ValidationBackend for MockValidateCandidateBackend { + async fn validate_candidate( + &mut self, + _pvf: PvfPrepData, + _timeout: Duration, + _encoded_params: Vec, + ) -> Result { + // This is expected to panic if called more times than expected, indicating an error in the + // test. + let result = self.result_list[self.num_times_called].clone(); + self.num_times_called += 1; + + result + } + + async fn precheck_pvf(&mut self, _pvf: PvfPrepData) -> Result { + unreachable!() + } +} + +#[test] +fn candidate_validation_ok_is_ok() { + let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() }; + + let pov = PoV { block_data: BlockData(vec![1; 32]) }; + let head_data = HeadData(vec![1, 1, 1]); + let validation_code = ValidationCode(vec![2; 16]); + + let descriptor = make_valid_candidate_descriptor( + ParaId::from(1_u32), + dummy_hash(), + validation_data.hash(), + pov.hash(), + validation_code.hash(), + head_data.hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let check = perform_basic_checks( + &descriptor, + validation_data.max_pov_size, + &pov, + &validation_code.hash(), + ); + assert!(check.is_ok()); + + let validation_result = WasmValidationResult { + head_data, + new_validation_code: Some(vec![2, 2, 2].into()), + upward_messages: Default::default(), + horizontal_messages: Default::default(), + processed_downward_messages: 0, + hrmp_watermark: 0, + }; + + let commitments = CandidateCommitments { + head_data: validation_result.head_data.clone(), + upward_messages: validation_result.upward_messages.clone(), + horizontal_messages: validation_result.horizontal_messages.clone(), + new_validation_code: validation_result.new_validation_code.clone(), + processed_downward_messages: validation_result.processed_downward_messages, + hrmp_watermark: validation_result.hrmp_watermark, + }; + + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: commitments.hash() }; + + let pool = TaskExecutor::new(); + let (mut ctx, ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + let metrics = Metrics::default(); + + let v = test_with_executor_params(ctx_handle, || { + validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)), + validation_data.clone(), + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &metrics, + ) + }) + .unwrap(); + + assert_matches!(v, ValidationResult::Valid(outputs, used_validation_data) => { + assert_eq!(outputs.head_data, HeadData(vec![1, 1, 1])); + assert_eq!(outputs.upward_messages, Vec::::new()); + assert_eq!(outputs.horizontal_messages, Vec::new()); + assert_eq!(outputs.new_validation_code, Some(vec![2, 2, 2].into())); + assert_eq!(outputs.hrmp_watermark, 0); + assert_eq!(used_validation_data, validation_data); + }); +} + +#[test] +fn candidate_validation_bad_return_is_invalid() { + let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() }; + + let pov = PoV { block_data: BlockData(vec![1; 32]) }; + let validation_code = ValidationCode(vec![2; 16]); + + let descriptor = make_valid_candidate_descriptor( + ParaId::from(1_u32), + dummy_hash(), + validation_data.hash(), + pov.hash(), + validation_code.hash(), + dummy_hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let check = perform_basic_checks( + &descriptor, + validation_data.max_pov_size, + &pov, + &validation_code.hash(), + ); + assert!(check.is_ok()); + + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() }; + + let pool = TaskExecutor::new(); + let (mut ctx, ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + let metrics = Metrics::default(); + + let v = test_with_executor_params(ctx_handle, || { + validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result(Err( + ValidationError::InvalidCandidate(WasmInvalidCandidate::HardTimeout), + )), + validation_data, + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &metrics, + ) + }); + + assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::Timeout))); +} + +// Test that we vote valid if we get `AmbiguousWorkerDeath`, retry, and then succeed. +#[test] +fn candidate_validation_one_ambiguous_error_is_valid() { + let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() }; + + let pov = PoV { block_data: BlockData(vec![1; 32]) }; + let head_data = HeadData(vec![1, 1, 1]); + let validation_code = ValidationCode(vec![2; 16]); + + let descriptor = make_valid_candidate_descriptor( + ParaId::from(1_u32), + dummy_hash(), + validation_data.hash(), + pov.hash(), + validation_code.hash(), + head_data.hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let check = perform_basic_checks( + &descriptor, + validation_data.max_pov_size, + &pov, + &validation_code.hash(), + ); + assert!(check.is_ok()); + + let validation_result = WasmValidationResult { + head_data, + new_validation_code: Some(vec![2, 2, 2].into()), + upward_messages: Default::default(), + horizontal_messages: Default::default(), + processed_downward_messages: 0, + hrmp_watermark: 0, + }; + + let commitments = CandidateCommitments { + head_data: validation_result.head_data.clone(), + upward_messages: validation_result.upward_messages.clone(), + horizontal_messages: validation_result.horizontal_messages.clone(), + new_validation_code: validation_result.new_validation_code.clone(), + processed_downward_messages: validation_result.processed_downward_messages, + hrmp_watermark: validation_result.hrmp_watermark, + }; + + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: commitments.hash() }; + + let pool = TaskExecutor::new(); + let (mut ctx, ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + let metrics = Metrics::default(); + + let v = test_with_executor_params(ctx_handle, || { + validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result_list(vec![ + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)), + Ok(validation_result), + ]), + validation_data.clone(), + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &metrics, + ) + }) + .unwrap(); + + assert_matches!(v, ValidationResult::Valid(outputs, used_validation_data) => { + assert_eq!(outputs.head_data, HeadData(vec![1, 1, 1])); + assert_eq!(outputs.upward_messages, Vec::::new()); + assert_eq!(outputs.horizontal_messages, Vec::new()); + assert_eq!(outputs.new_validation_code, Some(vec![2, 2, 2].into())); + assert_eq!(outputs.hrmp_watermark, 0); + assert_eq!(used_validation_data, validation_data); + }); +} + +#[test] +fn candidate_validation_multiple_ambiguous_errors_is_invalid() { + let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() }; + + let pov = PoV { block_data: BlockData(vec![1; 32]) }; + let validation_code = ValidationCode(vec![2; 16]); + + let descriptor = make_valid_candidate_descriptor( + ParaId::from(1_u32), + dummy_hash(), + validation_data.hash(), + pov.hash(), + validation_code.hash(), + dummy_hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let check = perform_basic_checks( + &descriptor, + validation_data.max_pov_size, + &pov, + &validation_code.hash(), + ); + assert!(check.is_ok()); + + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() }; + + let pool = TaskExecutor::new(); + let (mut ctx, ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + let metrics = Metrics::default(); + + let v = test_with_executor_params(ctx_handle, || { + validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result_list(vec![ + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)), + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)), + ]), + validation_data, + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &metrics, + ) + }) + .unwrap(); + + assert_matches!(v, ValidationResult::Invalid(InvalidCandidate::ExecutionError(_))); +} + +// Test that we retry on internal errors. +#[test] +fn candidate_validation_retry_internal_errors() { + let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() }; + + let pov = PoV { block_data: BlockData(vec![1; 32]) }; + let validation_code = ValidationCode(vec![2; 16]); + + let descriptor = make_valid_candidate_descriptor( + ParaId::from(1_u32), + dummy_hash(), + validation_data.hash(), + pov.hash(), + validation_code.hash(), + dummy_hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let check = perform_basic_checks( + &descriptor, + validation_data.max_pov_size, + &pov, + &validation_code.hash(), + ); + assert!(check.is_ok()); + + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() }; + + let pool = TaskExecutor::new(); + let (mut ctx, ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + let metrics = Metrics::default(); + + let v = test_with_executor_params(ctx_handle, || { + validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result_list(vec![ + Err(InternalValidationError::HostCommunication("foo".into()).into()), + // Throw an AWD error, we should still retry again. + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)), + // Throw another internal error. + Err(InternalValidationError::HostCommunication("bar".into()).into()), + ]), + validation_data, + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &metrics, + ) + }); + + assert_matches!(v, Err(ValidationFailed(s)) if s.contains("bar")); +} + +// Test that we retry on panic errors. +#[test] +fn candidate_validation_retry_panic_errors() { + let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() }; + + let pov = PoV { block_data: BlockData(vec![1; 32]) }; + let validation_code = ValidationCode(vec![2; 16]); + + let descriptor = make_valid_candidate_descriptor( + ParaId::from(1_u32), + dummy_hash(), + validation_data.hash(), + pov.hash(), + validation_code.hash(), + dummy_hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let check = perform_basic_checks( + &descriptor, + validation_data.max_pov_size, + &pov, + &validation_code.hash(), + ); + assert!(check.is_ok()); + + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() }; + + let pool = TaskExecutor::new(); + let (mut ctx, ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + let metrics = Metrics::default(); + + let v = test_with_executor_params(ctx_handle, || { + validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result_list(vec![ + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::Panic("foo".into()))), + // Throw an AWD error, we should still retry again. + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)), + // Throw another panic error. + Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::Panic("bar".into()))), + ]), + validation_data, + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &metrics, + ) + }); + + assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(s))) if s == "bar".to_string()); +} + +#[test] +fn candidate_validation_timeout_is_internal_error() { + let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() }; + + let pov = PoV { block_data: BlockData(vec![1; 32]) }; + let validation_code = ValidationCode(vec![2; 16]); + + let descriptor = make_valid_candidate_descriptor( + ParaId::from(1_u32), + dummy_hash(), + validation_data.hash(), + pov.hash(), + validation_code.hash(), + dummy_hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let check = perform_basic_checks( + &descriptor, + validation_data.max_pov_size, + &pov, + &validation_code.hash(), + ); + assert!(check.is_ok()); + + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() }; + + let pool = TaskExecutor::new(); + let (mut ctx, ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + let metrics = Metrics::default(); + + let v = test_with_executor_params(ctx_handle, || { + validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result(Err( + ValidationError::InvalidCandidate(WasmInvalidCandidate::HardTimeout), + )), + validation_data, + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &metrics, + ) + }); + + assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::Timeout))); +} + +#[test] +fn candidate_validation_commitment_hash_mismatch_is_invalid() { + let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() }; + let pov = PoV { block_data: BlockData(vec![0xff; 32]) }; + let validation_code = ValidationCode(vec![0xff; 16]); + let head_data = HeadData(vec![1, 1, 1]); + + let candidate_receipt = CandidateReceipt { + descriptor: make_valid_candidate_descriptor( + ParaId::from(1_u32), + validation_data.parent_head.hash(), + validation_data.hash(), + pov.hash(), + validation_code.hash(), + head_data.hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ), + commitments_hash: Hash::zero(), + }; + + // This will result in different commitments for this candidate. + let validation_result = WasmValidationResult { + head_data, + new_validation_code: None, + upward_messages: Default::default(), + horizontal_messages: Default::default(), + processed_downward_messages: 0, + hrmp_watermark: 12345, + }; + + let pool = TaskExecutor::new(); + let (mut ctx, ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + let metrics = Metrics::default(); + + let result = test_with_executor_params(ctx_handle, || { + validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)), + validation_data, + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &metrics, + ) + }) + .unwrap(); + + // Ensure `post validation` check on the commitments hash works as expected. + assert_matches!(result, ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch)); +} + +#[test] +fn candidate_validation_code_mismatch_is_invalid() { + let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() }; + + let pov = PoV { block_data: BlockData(vec![1; 32]) }; + let validation_code = ValidationCode(vec![2; 16]); + + let descriptor = make_valid_candidate_descriptor( + ParaId::from(1_u32), + dummy_hash(), + validation_data.hash(), + pov.hash(), + ValidationCode(vec![1; 16]).hash(), + dummy_hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let check = perform_basic_checks( + &descriptor, + validation_data.max_pov_size, + &pov, + &validation_code.hash(), + ); + assert_matches!(check, Err(InvalidCandidate::CodeHashMismatch)); + + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() }; + + let pool = TaskExecutor::new(); + let (mut ctx, _ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + + let v = executor::block_on(validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result(Err( + ValidationError::InvalidCandidate(WasmInvalidCandidate::HardTimeout), + )), + validation_data, + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &Default::default(), + )) + .unwrap(); + + assert_matches!(v, ValidationResult::Invalid(InvalidCandidate::CodeHashMismatch)); +} + +#[test] +fn compressed_code_works() { + let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() }; + let pov = PoV { block_data: BlockData(vec![1; 32]) }; + let head_data = HeadData(vec![1, 1, 1]); + + let raw_code = vec![2u8; 16]; + let validation_code = sp_maybe_compressed_blob::compress(&raw_code, VALIDATION_CODE_BOMB_LIMIT) + .map(ValidationCode) + .unwrap(); + + let descriptor = make_valid_candidate_descriptor( + ParaId::from(1_u32), + dummy_hash(), + validation_data.hash(), + pov.hash(), + validation_code.hash(), + head_data.hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let validation_result = WasmValidationResult { + head_data, + new_validation_code: None, + upward_messages: Default::default(), + horizontal_messages: Default::default(), + processed_downward_messages: 0, + hrmp_watermark: 0, + }; + + let commitments = CandidateCommitments { + head_data: validation_result.head_data.clone(), + upward_messages: validation_result.upward_messages.clone(), + horizontal_messages: validation_result.horizontal_messages.clone(), + new_validation_code: validation_result.new_validation_code.clone(), + processed_downward_messages: validation_result.processed_downward_messages, + hrmp_watermark: validation_result.hrmp_watermark, + }; + + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: commitments.hash() }; + + let pool = TaskExecutor::new(); + let (mut ctx, ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + let metrics = Metrics::default(); + + let v = test_with_executor_params(ctx_handle, || { + validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)), + validation_data, + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &metrics, + ) + }); + + assert_matches!(v, Ok(ValidationResult::Valid(_, _))); +} + +#[test] +fn code_decompression_failure_is_error() { + let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() }; + let pov = PoV { block_data: BlockData(vec![1; 32]) }; + let head_data = HeadData(vec![1, 1, 1]); + + let raw_code = vec![2u8; VALIDATION_CODE_BOMB_LIMIT + 1]; + let validation_code = + sp_maybe_compressed_blob::compress(&raw_code, VALIDATION_CODE_BOMB_LIMIT + 1) + .map(ValidationCode) + .unwrap(); + + let descriptor = make_valid_candidate_descriptor( + ParaId::from(1_u32), + dummy_hash(), + validation_data.hash(), + pov.hash(), + validation_code.hash(), + head_data.hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let validation_result = WasmValidationResult { + head_data, + new_validation_code: None, + upward_messages: Default::default(), + horizontal_messages: Default::default(), + processed_downward_messages: 0, + hrmp_watermark: 0, + }; + + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() }; + + let pool = TaskExecutor::new(); + let (mut ctx, _ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + + let v = executor::block_on(validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)), + validation_data, + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &Default::default(), + )); + + assert_matches!(v, Err(_)); +} + +#[test] +fn pov_decompression_failure_is_invalid() { + let validation_data = + PersistedValidationData { max_pov_size: POV_BOMB_LIMIT as u32, ..Default::default() }; + let head_data = HeadData(vec![1, 1, 1]); + + let raw_block_data = vec![2u8; POV_BOMB_LIMIT + 1]; + let pov = sp_maybe_compressed_blob::compress(&raw_block_data, POV_BOMB_LIMIT + 1) + .map(|raw| PoV { block_data: BlockData(raw) }) + .unwrap(); + + let validation_code = ValidationCode(vec![2; 16]); + + let descriptor = make_valid_candidate_descriptor( + ParaId::from(1_u32), + dummy_hash(), + validation_data.hash(), + pov.hash(), + validation_code.hash(), + head_data.hash(), + dummy_hash(), + Sr25519Keyring::Alice, + ); + + let validation_result = WasmValidationResult { + head_data, + new_validation_code: None, + upward_messages: Default::default(), + horizontal_messages: Default::default(), + processed_downward_messages: 0, + hrmp_watermark: 0, + }; + + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() }; + + let pool = TaskExecutor::new(); + let (mut ctx, _ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + + let v = executor::block_on(validate_candidate_exhaustive( + ctx.sender(), + MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)), + validation_data, + validation_code, + candidate_receipt, + Arc::new(pov), + PvfExecTimeoutKind::Backing, + &Default::default(), + )); + + assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::PoVDecompressionFailure))); +} + +struct MockPreCheckBackend { + result: Result, +} + +impl MockPreCheckBackend { + fn with_hardcoded_result(result: Result) -> Self { + Self { result } + } +} + +#[async_trait] +impl ValidationBackend for MockPreCheckBackend { + async fn validate_candidate( + &mut self, + _pvf: PvfPrepData, + _timeout: Duration, + _encoded_params: Vec, + ) -> Result { + unreachable!() + } + + async fn precheck_pvf(&mut self, _pvf: PvfPrepData) -> Result { + self.result.clone() + } +} + +#[test] +fn precheck_works() { + let relay_parent = [3; 32].into(); + let validation_code = ValidationCode(vec![3; 16]); + let validation_code_hash = validation_code.hash(); + + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + + let (check_fut, check_result) = precheck_pvf( + ctx.sender(), + MockPreCheckBackend::with_hardcoded_result(Ok(PrepareStats::default())), + relay_parent, + validation_code_hash, + ) + .remote_handle(); + + let test_fut = async move { + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + rp, + RuntimeApiRequest::ValidationCodeByHash( + vch, + tx + ), + )) => { + assert_eq!(vch, validation_code_hash); + assert_eq!(rp, relay_parent); + + let _ = tx.send(Ok(Some(validation_code.clone()))); + } + ); + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx)) + ) => { + tx.send(Ok(1u32.into())).unwrap(); + } + ); + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(_, tx)) + ) => { + tx.send(Ok(Some(ExecutorParams::default()))).unwrap(); + } + ); + assert_matches!(check_result.await, PreCheckOutcome::Valid); + }; + + let test_fut = future::join(test_fut, check_fut); + executor::block_on(test_fut); +} + +#[test] +fn precheck_invalid_pvf_blob_compression() { + let relay_parent = [3; 32].into(); + + let raw_code = vec![2u8; VALIDATION_CODE_BOMB_LIMIT + 1]; + let validation_code = + sp_maybe_compressed_blob::compress(&raw_code, VALIDATION_CODE_BOMB_LIMIT + 1) + .map(ValidationCode) + .unwrap(); + let validation_code_hash = validation_code.hash(); + + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + + let (check_fut, check_result) = precheck_pvf( + ctx.sender(), + MockPreCheckBackend::with_hardcoded_result(Ok(PrepareStats::default())), + relay_parent, + validation_code_hash, + ) + .remote_handle(); + + let test_fut = async move { + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + rp, + RuntimeApiRequest::ValidationCodeByHash( + vch, + tx + ), + )) => { + assert_eq!(vch, validation_code_hash); + assert_eq!(rp, relay_parent); + + let _ = tx.send(Ok(Some(validation_code.clone()))); + } + ); + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx)) + ) => { + tx.send(Ok(1u32.into())).unwrap(); + } + ); + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(_, tx)) + ) => { + tx.send(Ok(Some(ExecutorParams::default()))).unwrap(); + } + ); + assert_matches!(check_result.await, PreCheckOutcome::Invalid); + }; + + let test_fut = future::join(test_fut, check_fut); + executor::block_on(test_fut); +} + +#[test] +fn precheck_properly_classifies_outcomes() { + let inner = |prepare_result, precheck_outcome| { + let relay_parent = [3; 32].into(); + let validation_code = ValidationCode(vec![3; 16]); + let validation_code_hash = validation_code.hash(); + + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = + test_helpers::make_subsystem_context::(pool.clone()); + + let (check_fut, check_result) = precheck_pvf( + ctx.sender(), + MockPreCheckBackend::with_hardcoded_result(prepare_result), + relay_parent, + validation_code_hash, + ) + .remote_handle(); + + let test_fut = async move { + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + rp, + RuntimeApiRequest::ValidationCodeByHash( + vch, + tx + ), + )) => { + assert_eq!(vch, validation_code_hash); + assert_eq!(rp, relay_parent); + + let _ = tx.send(Ok(Some(validation_code.clone()))); + } + ); + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx)) + ) => { + tx.send(Ok(1u32.into())).unwrap(); + } + ); + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(_, tx)) + ) => { + tx.send(Ok(Some(ExecutorParams::default()))).unwrap(); + } + ); + assert_eq!(check_result.await, precheck_outcome); + }; + + let test_fut = future::join(test_fut, check_fut); + executor::block_on(test_fut); + }; + + inner(Err(PrepareError::Prevalidation("foo".to_owned())), PreCheckOutcome::Invalid); + inner(Err(PrepareError::Preparation("bar".to_owned())), PreCheckOutcome::Invalid); + inner(Err(PrepareError::Panic("baz".to_owned())), PreCheckOutcome::Invalid); + + inner(Err(PrepareError::TimedOut), PreCheckOutcome::Failed); + inner(Err(PrepareError::IoErr("fizz".to_owned())), PreCheckOutcome::Failed); +} diff --git a/polkadot/node/core/chain-api/Cargo.toml b/polkadot/node/core/chain-api/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..69d737ca29732f01185f3b29536cbf76b1ed3fac --- /dev/null +++ b/polkadot/node/core/chain-api/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "polkadot-node-core-chain-api" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +gum = { package = "tracing-gum", path = "../../gum" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-metrics = { path = "../../metrics" } +polkadot-node-subsystem = {path = "../../subsystem" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[dev-dependencies] +futures = { version = "0.3.21", features = ["thread-pool"] } +maplit = "1.0.2" +parity-scale-codec = "3.6.1" +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/polkadot/node/core/chain-api/src/lib.rs b/polkadot/node/core/chain-api/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..9b25481d71860bbc76f19840397360b8e3ee102b --- /dev/null +++ b/polkadot/node/core/chain-api/src/lib.rs @@ -0,0 +1,162 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implements the Chain API Subsystem +//! +//! Provides access to the chain data. Every request may return an error. +//! At the moment, the implementation requires `Client` to implement `HeaderBackend`, +//! we may add more bounds in the future if we will need e.g. block bodies. +//! +//! Supported requests: +//! * Block hash to number +//! * Block hash to header +//! * Block weight (cumulative) +//! * Finalized block number to hash +//! * Last finalized block number +//! * Ancestors + +#![deny(unused_crate_dependencies, unused_results)] +#![warn(missing_docs)] + +use std::sync::Arc; + +use futures::prelude::*; +use sc_client_api::AuxStore; +use sp_blockchain::HeaderBackend; + +use polkadot_node_subsystem::{ + messages::ChainApiMessage, overseer, FromOrchestra, OverseerSignal, SpawnedSubsystem, + SubsystemError, SubsystemResult, +}; +use polkadot_primitives::Block; + +mod metrics; +use self::metrics::Metrics; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &str = "parachain::chain-api"; + +/// The Chain API Subsystem implementation. +pub struct ChainApiSubsystem { + client: Arc, + metrics: Metrics, +} + +impl ChainApiSubsystem { + /// Create a new Chain API subsystem with the given client. + pub fn new(client: Arc, metrics: Metrics) -> Self { + ChainApiSubsystem { client, metrics } + } +} + +#[overseer::subsystem(ChainApi, error = SubsystemError, prefix = self::overseer)] +impl ChainApiSubsystem +where + Client: HeaderBackend + AuxStore + 'static, +{ + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = run::(ctx, self) + .map_err(|e| SubsystemError::with_origin("chain-api", e)) + .boxed(); + SpawnedSubsystem { future, name: "chain-api-subsystem" } + } +} + +#[overseer::contextbounds(ChainApi, prefix = self::overseer)] +async fn run( + mut ctx: Context, + subsystem: ChainApiSubsystem, +) -> SubsystemResult<()> +where + Client: HeaderBackend + AuxStore, +{ + loop { + match ctx.recv().await? { + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(_)) => {}, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {}, + FromOrchestra::Communication { msg } => match msg { + ChainApiMessage::BlockNumber(hash, response_channel) => { + let _timer = subsystem.metrics.time_block_number(); + let result = subsystem.client.number(hash).map_err(|e| e.to_string().into()); + subsystem.metrics.on_request(result.is_ok()); + let _ = response_channel.send(result); + }, + ChainApiMessage::BlockHeader(hash, response_channel) => { + let _timer = subsystem.metrics.time_block_header(); + let result = subsystem.client.header(hash).map_err(|e| e.to_string().into()); + subsystem.metrics.on_request(result.is_ok()); + let _ = response_channel.send(result); + }, + ChainApiMessage::BlockWeight(hash, response_channel) => { + let _timer = subsystem.metrics.time_block_weight(); + let result = sc_consensus_babe::block_weight(&*subsystem.client, hash) + .map_err(|e| e.to_string().into()); + subsystem.metrics.on_request(result.is_ok()); + let _ = response_channel.send(result); + }, + ChainApiMessage::FinalizedBlockHash(number, response_channel) => { + let _timer = subsystem.metrics.time_finalized_block_hash(); + // Note: we don't verify it's finalized + let result = subsystem.client.hash(number).map_err(|e| e.to_string().into()); + subsystem.metrics.on_request(result.is_ok()); + let _ = response_channel.send(result); + }, + ChainApiMessage::FinalizedBlockNumber(response_channel) => { + let _timer = subsystem.metrics.time_finalized_block_number(); + let result = subsystem.client.info().finalized_number; + // always succeeds + subsystem.metrics.on_request(true); + let _ = response_channel.send(Ok(result)); + }, + ChainApiMessage::Ancestors { hash, k, response_channel } => { + let _timer = subsystem.metrics.time_ancestors(); + gum::trace!(target: LOG_TARGET, hash=%hash, k=k, "ChainApiMessage::Ancestors"); + + let mut hash = hash; + + let next_parent = core::iter::from_fn(|| { + let maybe_header = subsystem.client.header(hash); + match maybe_header { + // propagate the error + Err(e) => { + let e = e.to_string().into(); + Some(Err(e)) + }, + // fewer than `k` ancestors are available + Ok(None) => None, + Ok(Some(header)) => { + // stop at the genesis header. + if header.number == 0 { + None + } else { + hash = header.parent_hash; + Some(Ok(hash)) + } + }, + } + }); + + let result = next_parent.take(k).collect::, _>>(); + subsystem.metrics.on_request(result.is_ok()); + let _ = response_channel.send(result); + }, + }, + } + } +} diff --git a/polkadot/node/core/chain-api/src/metrics.rs b/polkadot/node/core/chain-api/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..2cf8d2b68434bf0a17ba53af49a64516018aef68 --- /dev/null +++ b/polkadot/node/core/chain-api/src/metrics.rs @@ -0,0 +1,138 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_metrics::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) chain_api_requests: prometheus::CounterVec, + pub(crate) block_number: prometheus::Histogram, + pub(crate) block_header: prometheus::Histogram, + pub(crate) block_weight: prometheus::Histogram, + pub(crate) finalized_block_hash: prometheus::Histogram, + pub(crate) finalized_block_number: prometheus::Histogram, + pub(crate) ancestors: prometheus::Histogram, +} + +/// Chain API metrics. +#[derive(Default, Clone)] +pub struct Metrics(pub(crate) Option); + +impl Metrics { + pub fn on_request(&self, succeeded: bool) { + if let Some(metrics) = &self.0 { + if succeeded { + metrics.chain_api_requests.with_label_values(&["succeeded"]).inc(); + } else { + metrics.chain_api_requests.with_label_values(&["failed"]).inc(); + } + } + } + + /// Provide a timer for `block_number` which observes on drop. + pub fn time_block_number(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.block_number.start_timer()) + } + + /// Provide a timer for `block_header` which observes on drop. + pub fn time_block_header(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.block_header.start_timer()) + } + + /// Provide a timer for `block_weight` which observes on drop. + pub fn time_block_weight(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.block_weight.start_timer()) + } + + /// Provide a timer for `finalized_block_hash` which observes on drop. + pub fn time_finalized_block_hash( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.finalized_block_hash.start_timer()) + } + + /// Provide a timer for `finalized_block_number` which observes on drop. + pub fn time_finalized_block_number( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.finalized_block_number.start_timer()) + } + + /// Provide a timer for `ancestors` which observes on drop. + pub fn time_ancestors(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.ancestors.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + chain_api_requests: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_chain_api_requests_total", + "Number of Chain API requests served.", + ), + &["success"], + )?, + registry, + )?, + block_number: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_block_number", + "Time spent within `chain_api::block_number`", + ))?, + registry, + )?, + block_header: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_block_headers", + "Time spent within `chain_api::block_headers`", + ))?, + registry, + )?, + block_weight: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_block_weight", + "Time spent within `chain_api::block_weight`", + ))?, + registry, + )?, + finalized_block_hash: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_finalized_block_hash", + "Time spent within `chain_api::finalized_block_hash`", + ))?, + registry, + )?, + finalized_block_number: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_finalized_block_number", + "Time spent within `chain_api::finalized_block_number`", + ))?, + registry, + )?, + ancestors: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_ancestors", + "Time spent within `chain_api::ancestors`", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/core/chain-api/src/tests.rs b/polkadot/node/core/chain-api/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..331a4f9ba820a85307659494e3c2a14f4fee52f9 --- /dev/null +++ b/polkadot/node/core/chain-api/src/tests.rs @@ -0,0 +1,370 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use futures::{channel::oneshot, future::BoxFuture}; +use parity_scale_codec::Encode; +use std::collections::BTreeMap; + +use polkadot_node_primitives::BlockWeight; +use polkadot_node_subsystem_test_helpers::{make_subsystem_context, TestSubsystemContextHandle}; +use polkadot_primitives::{BlockNumber, Hash, Header}; +use sp_blockchain::Info as BlockInfo; +use sp_core::testing::TaskExecutor; + +#[derive(Clone)] +struct TestClient { + blocks: BTreeMap, + block_weights: BTreeMap, + finalized_blocks: BTreeMap, + headers: BTreeMap, +} + +const GENESIS: Hash = Hash::repeat_byte(0xAA); +const ONE: Hash = Hash::repeat_byte(0x01); +const TWO: Hash = Hash::repeat_byte(0x02); +const THREE: Hash = Hash::repeat_byte(0x03); +const FOUR: Hash = Hash::repeat_byte(0x04); +const ERROR_PATH: Hash = Hash::repeat_byte(0xFF); + +fn default_header() -> Header { + Header { + parent_hash: Hash::zero(), + number: 100500, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + } +} + +impl Default for TestClient { + fn default() -> Self { + Self { + blocks: maplit::btreemap! { + GENESIS => 0, + ONE => 1, + TWO => 2, + THREE => 3, + FOUR => 4, + }, + block_weights: maplit::btreemap! { + ONE => 0, + TWO => 1, + THREE => 1, + FOUR => 2, + }, + finalized_blocks: maplit::btreemap! { + 1 => ONE, + 3 => THREE, + }, + headers: maplit::btreemap! { + GENESIS => Header { + parent_hash: Hash::zero(), // Dummy parent with zero hash. + number: 0, + ..default_header() + }, + ONE => Header { + parent_hash: GENESIS, + number: 1, + ..default_header() + }, + TWO => Header { + parent_hash: ONE, + number: 2, + ..default_header() + }, + THREE => Header { + parent_hash: TWO, + number: 3, + ..default_header() + }, + FOUR => Header { + parent_hash: THREE, + number: 4, + ..default_header() + }, + ERROR_PATH => Header { + ..default_header() + } + }, + } + } +} + +fn last_key_value(map: &BTreeMap) -> (K, V) { + assert!(!map.is_empty()); + map.iter().last().map(|(k, v)| (k.clone(), v.clone())).unwrap() +} + +impl HeaderBackend for TestClient { + fn info(&self) -> BlockInfo { + let genesis_hash = self.blocks.iter().next().map(|(h, _)| *h).unwrap(); + let (best_hash, best_number) = last_key_value(&self.blocks); + let (finalized_number, finalized_hash) = last_key_value(&self.finalized_blocks); + + BlockInfo { + best_hash, + best_number, + genesis_hash, + finalized_hash, + finalized_number, + number_leaves: 0, + finalized_state: None, + block_gap: None, + } + } + fn number(&self, hash: Hash) -> sp_blockchain::Result> { + Ok(self.blocks.get(&hash).copied()) + } + fn hash(&self, number: BlockNumber) -> sp_blockchain::Result> { + Ok(self.finalized_blocks.get(&number).copied()) + } + fn header(&self, hash: Hash) -> sp_blockchain::Result> { + if hash.is_zero() { + Err(sp_blockchain::Error::Backend("Zero hashes are illegal!".into())) + } else { + Ok(self.headers.get(&hash).cloned()) + } + } + fn status(&self, _hash: Hash) -> sp_blockchain::Result { + unimplemented!() + } +} + +fn test_harness( + test: impl FnOnce( + Arc, + TestSubsystemContextHandle, + ) -> BoxFuture<'static, ()>, +) { + let (ctx, ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let client = Arc::new(TestClient::default()); + + let subsystem = ChainApiSubsystem::new(client.clone(), Metrics(None)); + let chain_api_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = test(client, ctx_handle); + + futures::executor::block_on(future::join(chain_api_task, test_task)); +} + +impl AuxStore for TestClient { + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >( + &self, + _insert: I, + _delete: D, + ) -> sp_blockchain::Result<()> { + unimplemented!() + } + + fn get_aux(&self, key: &[u8]) -> sp_blockchain::Result>> { + Ok(self + .block_weights + .iter() + .find(|(hash, _)| sc_consensus_babe::aux_schema::block_weight_key(hash) == key) + .map(|(_, weight)| weight.encode())) + } +} + +#[test] +fn request_block_number() { + test_harness(|client, mut sender| { + async move { + let zero = Hash::zero(); + let test_cases = [ + (TWO, client.number(TWO).unwrap()), + (zero, client.number(zero).unwrap()), // not here + ]; + for (hash, expected) in &test_cases { + let (tx, rx) = oneshot::channel(); + + sender + .send(FromOrchestra::Communication { + msg: ChainApiMessage::BlockNumber(*hash, tx), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), *expected); + } + + sender.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + } + .boxed() + }) +} + +#[test] +fn request_block_header() { + test_harness(|client, mut sender| { + async move { + const NOT_HERE: Hash = Hash::repeat_byte(0x5); + let test_cases = + [(TWO, client.header(TWO).unwrap()), (NOT_HERE, client.header(NOT_HERE).unwrap())]; + for (hash, expected) in &test_cases { + let (tx, rx) = oneshot::channel(); + + sender + .send(FromOrchestra::Communication { + msg: ChainApiMessage::BlockHeader(*hash, tx), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), *expected); + } + + sender.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + } + .boxed() + }) +} + +#[test] +fn request_block_weight() { + test_harness(|client, mut sender| { + async move { + const NOT_HERE: Hash = Hash::repeat_byte(0x5); + let test_cases = [ + (TWO, sc_consensus_babe::block_weight(&*client, TWO).unwrap()), + (FOUR, sc_consensus_babe::block_weight(&*client, FOUR).unwrap()), + (NOT_HERE, sc_consensus_babe::block_weight(&*client, NOT_HERE).unwrap()), + ]; + for (hash, expected) in &test_cases { + let (tx, rx) = oneshot::channel(); + + sender + .send(FromOrchestra::Communication { + msg: ChainApiMessage::BlockWeight(*hash, tx), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), *expected); + } + + sender.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + } + .boxed() + }) +} + +#[test] +fn request_finalized_hash() { + test_harness(|client, mut sender| { + async move { + let test_cases = [ + (1, client.hash(1).unwrap()), // not here + (2, client.hash(2).unwrap()), + ]; + for (number, expected) in &test_cases { + let (tx, rx) = oneshot::channel(); + + sender + .send(FromOrchestra::Communication { + msg: ChainApiMessage::FinalizedBlockHash(*number, tx), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), *expected); + } + + sender.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + } + .boxed() + }) +} + +#[test] +fn request_last_finalized_number() { + test_harness(|client, mut sender| { + async move { + let (tx, rx) = oneshot::channel(); + + let expected = client.info().finalized_number; + sender + .send(FromOrchestra::Communication { + msg: ChainApiMessage::FinalizedBlockNumber(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), expected); + + sender.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + } + .boxed() + }) +} + +#[test] +fn request_ancestors() { + test_harness(|_client, mut sender| { + async move { + let (tx, rx) = oneshot::channel(); + sender + .send(FromOrchestra::Communication { + msg: ChainApiMessage::Ancestors { hash: THREE, k: 4, response_channel: tx }, + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), vec![TWO, ONE, GENESIS]); + + // Limit the number of ancestors. + let (tx, rx) = oneshot::channel(); + sender + .send(FromOrchestra::Communication { + msg: ChainApiMessage::Ancestors { hash: TWO, k: 1, response_channel: tx }, + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), vec![ONE]); + + // Ancestor of block #1 is returned. + let (tx, rx) = oneshot::channel(); + sender + .send(FromOrchestra::Communication { + msg: ChainApiMessage::Ancestors { hash: ONE, k: 10, response_channel: tx }, + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), vec![GENESIS]); + + // No ancestors of genesis block. + let (tx, rx) = oneshot::channel(); + sender + .send(FromOrchestra::Communication { + msg: ChainApiMessage::Ancestors { hash: GENESIS, k: 10, response_channel: tx }, + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), Vec::new()); + + let (tx, rx) = oneshot::channel(); + sender + .send(FromOrchestra::Communication { + msg: ChainApiMessage::Ancestors { + hash: ERROR_PATH, + k: 2, + response_channel: tx, + }, + }) + .await; + assert!(rx.await.unwrap().is_err()); + + sender.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + } + .boxed() + }) +} diff --git a/polkadot/node/core/chain-selection/Cargo.toml b/polkadot/node/core/chain-selection/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..071fec4415a4717b0ab43f784a728acc6ddbc2be --- /dev/null +++ b/polkadot/node/core/chain-selection/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "polkadot-node-core-chain-selection" +description = "Chain Selection Subsystem" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +futures-timer = "3" +gum = { package = "tracing-gum", path = "../../gum" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +kvdb = "0.13.0" +thiserror = "1.0.31" +parity-scale-codec = "3.6.1" + +[dev-dependencies] +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +parking_lot = "0.12.0" +assert_matches = "1" +kvdb-memorydb = "0.13.0" diff --git a/polkadot/node/core/chain-selection/src/backend.rs b/polkadot/node/core/chain-selection/src/backend.rs new file mode 100644 index 0000000000000000000000000000000000000000..71fa55ac657569fa1347e5219a832141cf67dfe0 --- /dev/null +++ b/polkadot/node/core/chain-selection/src/backend.rs @@ -0,0 +1,237 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! An abstraction over storage used by the chain selection subsystem. +//! +//! This provides both a [`Backend`] trait and an [`OverlayedBackend`] +//! struct which allows in-memory changes to be applied on top of a +//! [`Backend`], maintaining consistency between queries and temporary writes, +//! before any commit to the underlying storage is made. + +use polkadot_primitives::{BlockNumber, Hash}; + +use std::collections::HashMap; + +use crate::{BlockEntry, Error, LeafEntrySet, Timestamp}; + +pub(super) enum BackendWriteOp { + WriteBlockEntry(BlockEntry), + WriteBlocksByNumber(BlockNumber, Vec), + WriteViableLeaves(LeafEntrySet), + WriteStagnantAt(Timestamp, Vec), + DeleteBlocksByNumber(BlockNumber), + DeleteBlockEntry(Hash), + DeleteStagnantAt(Timestamp), +} + +/// An abstraction over backend storage for the logic of this subsystem. +pub(super) trait Backend { + /// Load a block entry from the DB. + fn load_block_entry(&self, hash: &Hash) -> Result, Error>; + /// Load the active-leaves set. + fn load_leaves(&self) -> Result; + /// Load the stagnant list at the given timestamp. + fn load_stagnant_at(&self, timestamp: Timestamp) -> Result, Error>; + /// Load all stagnant lists up to and including the given Unix timestamp + /// in ascending order. Stop fetching stagnant entries upon reaching `max_elements`. + fn load_stagnant_at_up_to( + &self, + up_to: Timestamp, + max_elements: usize, + ) -> Result)>, Error>; + /// Load the earliest kept block number. + fn load_first_block_number(&self) -> Result, Error>; + /// Load blocks by number. + fn load_blocks_by_number(&self, number: BlockNumber) -> Result, Error>; + + /// Atomically write the list of operations, with later operations taking precedence over prior. + fn write(&mut self, ops: I) -> Result<(), Error> + where + I: IntoIterator; +} + +/// An in-memory overlay over the backend. +/// +/// This maintains read-only access to the underlying backend, but can be +/// converted into a set of write operations which will, when written to +/// the underlying backend, give the same view as the state of the overlay. +pub(super) struct OverlayedBackend<'a, B: 'a> { + inner: &'a B, + + // `None` means 'deleted', missing means query inner. + block_entries: HashMap>, + // `None` means 'deleted', missing means query inner. + blocks_by_number: HashMap>>, + // 'None' means 'deleted', missing means query inner. + stagnant_at: HashMap>>, + // 'None' means query inner. + leaves: Option, +} + +impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> { + pub(super) fn new(backend: &'a B) -> Self { + OverlayedBackend { + inner: backend, + block_entries: HashMap::new(), + blocks_by_number: HashMap::new(), + stagnant_at: HashMap::new(), + leaves: None, + } + } + + pub(super) fn load_block_entry(&self, hash: &Hash) -> Result, Error> { + if let Some(val) = self.block_entries.get(&hash) { + return Ok(val.clone()) + } + + self.inner.load_block_entry(hash) + } + + pub(super) fn load_blocks_by_number(&self, number: BlockNumber) -> Result, Error> { + if let Some(val) = self.blocks_by_number.get(&number) { + return Ok(val.as_ref().map_or(Vec::new(), Clone::clone)) + } + + self.inner.load_blocks_by_number(number) + } + + pub(super) fn load_leaves(&self) -> Result { + if let Some(ref set) = self.leaves { + return Ok(set.clone()) + } + + self.inner.load_leaves() + } + + pub(super) fn load_stagnant_at(&self, timestamp: Timestamp) -> Result, Error> { + if let Some(val) = self.stagnant_at.get(×tamp) { + return Ok(val.as_ref().map_or(Vec::new(), Clone::clone)) + } + + self.inner.load_stagnant_at(timestamp) + } + + pub(super) fn write_block_entry(&mut self, entry: BlockEntry) { + self.block_entries.insert(entry.block_hash, Some(entry)); + } + + pub(super) fn delete_block_entry(&mut self, hash: &Hash) { + self.block_entries.insert(*hash, None); + } + + pub(super) fn write_blocks_by_number(&mut self, number: BlockNumber, blocks: Vec) { + if blocks.is_empty() { + self.blocks_by_number.insert(number, None); + } else { + self.blocks_by_number.insert(number, Some(blocks)); + } + } + + pub(super) fn delete_blocks_by_number(&mut self, number: BlockNumber) { + self.blocks_by_number.insert(number, None); + } + + pub(super) fn write_leaves(&mut self, leaves: LeafEntrySet) { + self.leaves = Some(leaves); + } + + pub(super) fn write_stagnant_at(&mut self, timestamp: Timestamp, hashes: Vec) { + self.stagnant_at.insert(timestamp, Some(hashes)); + } + + pub(super) fn delete_stagnant_at(&mut self, timestamp: Timestamp) { + self.stagnant_at.insert(timestamp, None); + } + + /// Transform this backend into a set of write-ops to be written to the + /// inner backend. + pub(super) fn into_write_ops(self) -> impl Iterator { + let block_entry_ops = self.block_entries.into_iter().map(|(h, v)| match v { + Some(v) => BackendWriteOp::WriteBlockEntry(v), + None => BackendWriteOp::DeleteBlockEntry(h), + }); + + let blocks_by_number_ops = self.blocks_by_number.into_iter().map(|(n, v)| match v { + Some(v) => BackendWriteOp::WriteBlocksByNumber(n, v), + None => BackendWriteOp::DeleteBlocksByNumber(n), + }); + + let leaf_ops = self.leaves.into_iter().map(BackendWriteOp::WriteViableLeaves); + + let stagnant_at_ops = self.stagnant_at.into_iter().map(|(n, v)| match v { + Some(v) => BackendWriteOp::WriteStagnantAt(n, v), + None => BackendWriteOp::DeleteStagnantAt(n), + }); + + block_entry_ops + .chain(blocks_by_number_ops) + .chain(leaf_ops) + .chain(stagnant_at_ops) + } +} + +/// Attempt to find the given ancestor in the chain with given head. +/// +/// If the ancestor is the most recently finalized block, and the `head` is +/// a known unfinalized block, this will return `true`. +/// +/// If the ancestor is an unfinalized block and `head` is known, this will +/// return true if `ancestor` is in `head`'s chain. +/// +/// If the ancestor is an older finalized block, this will return `false`. +fn contains_ancestor(backend: &impl Backend, head: Hash, ancestor: Hash) -> Result { + let mut current_hash = head; + loop { + if current_hash == ancestor { + return Ok(true) + } + match backend.load_block_entry(¤t_hash)? { + Some(e) => current_hash = e.parent_hash, + None => break, + } + } + + Ok(false) +} + +/// This returns the best unfinalized leaf containing the required block. +/// +/// If the required block is finalized but not the most recent finalized block, +/// this will return `None`. +/// +/// If the required block is unfinalized but not an ancestor of any viable leaf, +/// this will return `None`. +// +// Note: this is O(N^2) in the depth of `required` and the number of leaves. +// We expect the number of unfinalized blocks to be small, as in, to not exceed +// single digits in practice, and exceedingly unlikely to surpass 1000. +// +// However, if we need to, we could implement some type of skip-list for +// fast ancestry checks. +pub(super) fn find_best_leaf_containing( + backend: &impl Backend, + required: Hash, +) -> Result, Error> { + let leaves = backend.load_leaves()?; + for leaf in leaves.into_hashes_descending() { + if contains_ancestor(backend, leaf, required)? { + return Ok(Some(leaf)) + } + } + + // If there are no viable leaves containing the ancestor + Ok(None) +} diff --git a/polkadot/node/core/chain-selection/src/db_backend/mod.rs b/polkadot/node/core/chain-selection/src/db_backend/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..f7baf9d3da189af87bbe36cfab617976ee9756e9 --- /dev/null +++ b/polkadot/node/core/chain-selection/src/db_backend/mod.rs @@ -0,0 +1,19 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A database [`Backend`][crate::backend::Backend] for the chain selection subsystem. + +pub(super) mod v1; diff --git a/polkadot/node/core/chain-selection/src/db_backend/v1.rs b/polkadot/node/core/chain-selection/src/db_backend/v1.rs new file mode 100644 index 0000000000000000000000000000000000000000..7c7144bb763dfbf02adfcb958d18a97b6a96dbb8 --- /dev/null +++ b/polkadot/node/core/chain-selection/src/db_backend/v1.rs @@ -0,0 +1,630 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A database [`Backend`][crate::backend::Backend] for the chain selection subsystem. +//! +//! This stores the following schema: +//! +//! ```ignore +//! ("CS_block_entry", Hash) -> BlockEntry; +//! ("CS_block_height", BigEndianBlockNumber) -> Vec; +//! ("CS_stagnant_at", BigEndianTimestamp) -> Vec; +//! ("CS_leaves") -> LeafEntrySet; +//! ``` +//! +//! The big-endian encoding is used for creating iterators over the key-value DB which are +//! accessible by prefix, to find the earliest block number stored as well as the all stagnant +//! blocks. +//! +//! The `Vec`s stored are always non-empty. Empty `Vec`s are not stored on disk so there is no +//! semantic difference between `None` and an empty `Vec`. + +use crate::{ + backend::{Backend, BackendWriteOp}, + Error, +}; + +use polkadot_node_primitives::BlockWeight; +use polkadot_primitives::{BlockNumber, Hash}; + +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_subsystem_util::database::{DBTransaction, Database}; + +use std::sync::Arc; + +const BLOCK_ENTRY_PREFIX: &[u8; 14] = b"CS_block_entry"; +const BLOCK_HEIGHT_PREFIX: &[u8; 15] = b"CS_block_height"; +const STAGNANT_AT_PREFIX: &[u8; 14] = b"CS_stagnant_at"; +const LEAVES_KEY: &[u8; 9] = b"CS_leaves"; + +type Timestamp = u64; + +#[derive(Debug, Encode, Decode, Clone, PartialEq)] +enum Approval { + #[codec(index = 0)] + Approved, + #[codec(index = 1)] + Unapproved, + #[codec(index = 2)] + Stagnant, +} + +impl From for Approval { + fn from(x: crate::Approval) -> Self { + match x { + crate::Approval::Approved => Approval::Approved, + crate::Approval::Unapproved => Approval::Unapproved, + crate::Approval::Stagnant => Approval::Stagnant, + } + } +} + +impl From for crate::Approval { + fn from(x: Approval) -> crate::Approval { + match x { + Approval::Approved => crate::Approval::Approved, + Approval::Unapproved => crate::Approval::Unapproved, + Approval::Stagnant => crate::Approval::Stagnant, + } + } +} + +#[derive(Debug, Encode, Decode, Clone, PartialEq)] +struct ViabilityCriteria { + explicitly_reverted: bool, + approval: Approval, + earliest_unviable_ancestor: Option, +} + +impl From for ViabilityCriteria { + fn from(x: crate::ViabilityCriteria) -> Self { + ViabilityCriteria { + explicitly_reverted: x.explicitly_reverted, + approval: x.approval.into(), + earliest_unviable_ancestor: x.earliest_unviable_ancestor, + } + } +} + +impl From for crate::ViabilityCriteria { + fn from(x: ViabilityCriteria) -> crate::ViabilityCriteria { + crate::ViabilityCriteria { + explicitly_reverted: x.explicitly_reverted, + approval: x.approval.into(), + earliest_unviable_ancestor: x.earliest_unviable_ancestor, + } + } +} + +#[derive(Encode, Decode)] +struct LeafEntry { + weight: BlockWeight, + block_number: BlockNumber, + block_hash: Hash, +} + +impl From for LeafEntry { + fn from(x: crate::LeafEntry) -> Self { + LeafEntry { weight: x.weight, block_number: x.block_number, block_hash: x.block_hash } + } +} + +impl From for crate::LeafEntry { + fn from(x: LeafEntry) -> crate::LeafEntry { + crate::LeafEntry { + weight: x.weight, + block_number: x.block_number, + block_hash: x.block_hash, + } + } +} + +#[derive(Encode, Decode)] +struct LeafEntrySet { + inner: Vec, +} + +impl From for LeafEntrySet { + fn from(x: crate::LeafEntrySet) -> Self { + LeafEntrySet { inner: x.inner.into_iter().map(Into::into).collect() } + } +} + +impl From for crate::LeafEntrySet { + fn from(x: LeafEntrySet) -> crate::LeafEntrySet { + crate::LeafEntrySet { inner: x.inner.into_iter().map(Into::into).collect() } + } +} + +#[derive(Debug, Encode, Decode, Clone, PartialEq)] +struct BlockEntry { + block_hash: Hash, + block_number: BlockNumber, + parent_hash: Hash, + children: Vec, + viability: ViabilityCriteria, + weight: BlockWeight, +} + +impl From for BlockEntry { + fn from(x: crate::BlockEntry) -> Self { + BlockEntry { + block_hash: x.block_hash, + block_number: x.block_number, + parent_hash: x.parent_hash, + children: x.children, + viability: x.viability.into(), + weight: x.weight, + } + } +} + +impl From for crate::BlockEntry { + fn from(x: BlockEntry) -> crate::BlockEntry { + crate::BlockEntry { + block_hash: x.block_hash, + block_number: x.block_number, + parent_hash: x.parent_hash, + children: x.children, + viability: x.viability.into(), + weight: x.weight, + } + } +} + +/// Configuration for the database backend. +#[derive(Debug, Clone, Copy)] +pub struct Config { + /// The column where block metadata is stored. + pub col_data: u32, +} + +/// The database backend. +pub struct DbBackend { + inner: Arc, + config: Config, +} + +impl DbBackend { + /// Create a new [`DbBackend`] with the supplied key-value store and + /// config. + pub fn new(db: Arc, config: Config) -> Self { + DbBackend { inner: db, config } + } +} + +impl Backend for DbBackend { + fn load_block_entry(&self, hash: &Hash) -> Result, Error> { + load_decode::(&*self.inner, self.config.col_data, &block_entry_key(hash)) + .map(|o| o.map(Into::into)) + } + + fn load_leaves(&self) -> Result { + load_decode::(&*self.inner, self.config.col_data, LEAVES_KEY) + .map(|o| o.map(Into::into).unwrap_or_default()) + } + + fn load_stagnant_at(&self, timestamp: crate::Timestamp) -> Result, Error> { + load_decode::>( + &*self.inner, + self.config.col_data, + &stagnant_at_key(timestamp.into()), + ) + .map(|o| o.unwrap_or_default()) + } + + fn load_stagnant_at_up_to( + &self, + up_to: crate::Timestamp, + max_elements: usize, + ) -> Result)>, Error> { + let stagnant_at_iter = + self.inner.iter_with_prefix(self.config.col_data, &STAGNANT_AT_PREFIX[..]); + + let val = stagnant_at_iter + .filter_map(|r| match r { + Ok((k, v)) => + match (decode_stagnant_at_key(&mut &k[..]), >::decode(&mut &v[..]).ok()) + { + (Some(at), Some(stagnant_at)) => Some(Ok((at, stagnant_at))), + _ => None, + }, + Err(e) => Some(Err(e)), + }) + .enumerate() + .take_while(|(idx, r)| { + r.as_ref().map_or(true, |(at, _)| *at <= up_to.into() && *idx < max_elements) + }) + .map(|(_, v)| v) + .collect::, _>>()?; + + Ok(val) + } + + fn load_first_block_number(&self) -> Result, Error> { + let blocks_at_height_iter = + self.inner.iter_with_prefix(self.config.col_data, &BLOCK_HEIGHT_PREFIX[..]); + + let val = blocks_at_height_iter + .filter_map(|r| match r { + Ok((k, _)) => decode_block_height_key(&k[..]).map(Ok), + Err(e) => Some(Err(e)), + }) + .next(); + + val.transpose().map_err(Error::from) + } + + fn load_blocks_by_number(&self, number: BlockNumber) -> Result, Error> { + load_decode::>(&*self.inner, self.config.col_data, &block_height_key(number)) + .map(|o| o.unwrap_or_default()) + } + + /// Atomically write the list of operations, with later operations taking precedence over prior. + fn write(&mut self, ops: I) -> Result<(), Error> + where + I: IntoIterator, + { + let mut tx = DBTransaction::new(); + for op in ops { + match op { + BackendWriteOp::WriteBlockEntry(block_entry) => { + let block_entry: BlockEntry = block_entry.into(); + tx.put_vec( + self.config.col_data, + &block_entry_key(&block_entry.block_hash), + block_entry.encode(), + ); + }, + BackendWriteOp::WriteBlocksByNumber(block_number, v) => + if v.is_empty() { + tx.delete(self.config.col_data, &block_height_key(block_number)); + } else { + tx.put_vec( + self.config.col_data, + &block_height_key(block_number), + v.encode(), + ); + }, + BackendWriteOp::WriteViableLeaves(leaves) => { + let leaves: LeafEntrySet = leaves.into(); + if leaves.inner.is_empty() { + tx.delete(self.config.col_data, &LEAVES_KEY[..]); + } else { + tx.put_vec(self.config.col_data, &LEAVES_KEY[..], leaves.encode()); + } + }, + BackendWriteOp::WriteStagnantAt(timestamp, stagnant_at) => { + let timestamp: Timestamp = timestamp.into(); + if stagnant_at.is_empty() { + tx.delete(self.config.col_data, &stagnant_at_key(timestamp)); + } else { + tx.put_vec( + self.config.col_data, + &stagnant_at_key(timestamp), + stagnant_at.encode(), + ); + } + }, + BackendWriteOp::DeleteBlocksByNumber(block_number) => { + tx.delete(self.config.col_data, &block_height_key(block_number)); + }, + BackendWriteOp::DeleteBlockEntry(hash) => { + tx.delete(self.config.col_data, &block_entry_key(&hash)); + }, + BackendWriteOp::DeleteStagnantAt(timestamp) => { + let timestamp: Timestamp = timestamp.into(); + tx.delete(self.config.col_data, &stagnant_at_key(timestamp)); + }, + } + } + + self.inner.write(tx).map_err(Into::into) + } +} + +fn load_decode( + db: &dyn Database, + col_data: u32, + key: &[u8], +) -> Result, Error> { + match db.get(col_data, key)? { + None => Ok(None), + Some(raw) => D::decode(&mut &raw[..]).map(Some).map_err(Into::into), + } +} + +fn block_entry_key(hash: &Hash) -> [u8; 14 + 32] { + let mut key = [0; 14 + 32]; + key[..14].copy_from_slice(BLOCK_ENTRY_PREFIX); + hash.using_encoded(|s| key[14..].copy_from_slice(s)); + key +} + +fn block_height_key(number: BlockNumber) -> [u8; 15 + 4] { + let mut key = [0; 15 + 4]; + key[..15].copy_from_slice(BLOCK_HEIGHT_PREFIX); + key[15..].copy_from_slice(&number.to_be_bytes()); + key +} + +fn stagnant_at_key(timestamp: Timestamp) -> [u8; 14 + 8] { + let mut key = [0; 14 + 8]; + key[..14].copy_from_slice(STAGNANT_AT_PREFIX); + key[14..].copy_from_slice(×tamp.to_be_bytes()); + key +} + +fn decode_block_height_key(key: &[u8]) -> Option { + if key.len() != 15 + 4 { + return None + } + if !key.starts_with(BLOCK_HEIGHT_PREFIX) { + return None + } + + let mut bytes = [0; 4]; + bytes.copy_from_slice(&key[15..]); + Some(BlockNumber::from_be_bytes(bytes)) +} + +fn decode_stagnant_at_key(key: &[u8]) -> Option { + if key.len() != 14 + 8 { + return None + } + if !key.starts_with(STAGNANT_AT_PREFIX) { + return None + } + + let mut bytes = [0; 8]; + bytes.copy_from_slice(&key[14..]); + Some(Timestamp::from_be_bytes(bytes)) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[cfg(test)] + fn test_db() -> Arc { + let db = kvdb_memorydb::create(1); + let db = polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter::new(db, &[0]); + Arc::new(db) + } + + #[test] + fn block_height_key_decodes() { + let key = block_height_key(5); + assert_eq!(decode_block_height_key(&key), Some(5)); + } + + #[test] + fn stagnant_at_key_decodes() { + let key = stagnant_at_key(5); + assert_eq!(decode_stagnant_at_key(&key), Some(5)); + } + + #[test] + fn lower_block_height_key_lesser() { + for i in 0..256 { + for j in 1..=256 { + let key_a = block_height_key(i); + let key_b = block_height_key(i + j); + + assert!(key_a < key_b); + } + } + } + + #[test] + fn lower_stagnant_at_key_lesser() { + for i in 0..256 { + for j in 1..=256 { + let key_a = stagnant_at_key(i); + let key_b = stagnant_at_key(i + j); + + assert!(key_a < key_b); + } + } + } + + #[test] + fn write_read_block_entry() { + let db = test_db(); + let config = Config { col_data: 0 }; + + let mut backend = DbBackend::new(db, config); + + let block_entry = BlockEntry { + block_hash: Hash::repeat_byte(1), + block_number: 1, + parent_hash: Hash::repeat_byte(0), + children: vec![], + viability: ViabilityCriteria { + earliest_unviable_ancestor: None, + explicitly_reverted: false, + approval: Approval::Unapproved, + }, + weight: 100, + }; + + backend + .write(vec![BackendWriteOp::WriteBlockEntry(block_entry.clone().into())]) + .unwrap(); + + assert_eq!( + backend.load_block_entry(&block_entry.block_hash).unwrap().map(BlockEntry::from), + Some(block_entry), + ); + } + + #[test] + fn delete_block_entry() { + let db = test_db(); + let config = Config { col_data: 0 }; + + let mut backend = DbBackend::new(db, config); + + let block_entry = BlockEntry { + block_hash: Hash::repeat_byte(1), + block_number: 1, + parent_hash: Hash::repeat_byte(0), + children: vec![], + viability: ViabilityCriteria { + earliest_unviable_ancestor: None, + explicitly_reverted: false, + approval: Approval::Unapproved, + }, + weight: 100, + }; + + backend + .write(vec![BackendWriteOp::WriteBlockEntry(block_entry.clone().into())]) + .unwrap(); + + backend + .write(vec![BackendWriteOp::DeleteBlockEntry(block_entry.block_hash)]) + .unwrap(); + + assert!(backend.load_block_entry(&block_entry.block_hash).unwrap().is_none()); + } + + #[test] + fn earliest_block_number() { + let db = test_db(); + let config = Config { col_data: 0 }; + + let mut backend = DbBackend::new(db, config); + + assert!(backend.load_first_block_number().unwrap().is_none()); + + backend + .write(vec![ + BackendWriteOp::WriteBlocksByNumber(2, vec![Hash::repeat_byte(0)]), + BackendWriteOp::WriteBlocksByNumber(5, vec![Hash::repeat_byte(0)]), + BackendWriteOp::WriteBlocksByNumber(10, vec![Hash::repeat_byte(0)]), + ]) + .unwrap(); + + assert_eq!(backend.load_first_block_number().unwrap(), Some(2)); + + backend + .write(vec![ + BackendWriteOp::WriteBlocksByNumber(2, vec![]), + BackendWriteOp::DeleteBlocksByNumber(5), + ]) + .unwrap(); + + assert_eq!(backend.load_first_block_number().unwrap(), Some(10)); + } + + #[test] + fn stagnant_at_up_to() { + let db = test_db(); + let config = Config { col_data: 0 }; + + let mut backend = DbBackend::new(db, config); + + // Prove that it's cheap + assert!(backend + .load_stagnant_at_up_to(Timestamp::max_value(), usize::MAX) + .unwrap() + .is_empty()); + + backend + .write(vec![ + BackendWriteOp::WriteStagnantAt(2, vec![Hash::repeat_byte(1)]), + BackendWriteOp::WriteStagnantAt(5, vec![Hash::repeat_byte(2)]), + BackendWriteOp::WriteStagnantAt(10, vec![Hash::repeat_byte(3)]), + ]) + .unwrap(); + + assert_eq!( + backend.load_stagnant_at_up_to(Timestamp::max_value(), usize::MAX).unwrap(), + vec![ + (2, vec![Hash::repeat_byte(1)]), + (5, vec![Hash::repeat_byte(2)]), + (10, vec![Hash::repeat_byte(3)]), + ] + ); + + assert_eq!( + backend.load_stagnant_at_up_to(10, usize::MAX).unwrap(), + vec![ + (2, vec![Hash::repeat_byte(1)]), + (5, vec![Hash::repeat_byte(2)]), + (10, vec![Hash::repeat_byte(3)]), + ] + ); + + assert_eq!( + backend.load_stagnant_at_up_to(9, usize::MAX).unwrap(), + vec![(2, vec![Hash::repeat_byte(1)]), (5, vec![Hash::repeat_byte(2)]),] + ); + + assert_eq!( + backend.load_stagnant_at_up_to(9, 1).unwrap(), + vec![(2, vec![Hash::repeat_byte(1)]),] + ); + + backend.write(vec![BackendWriteOp::DeleteStagnantAt(2)]).unwrap(); + + assert_eq!( + backend.load_stagnant_at_up_to(5, usize::MAX).unwrap(), + vec![(5, vec![Hash::repeat_byte(2)]),] + ); + + backend.write(vec![BackendWriteOp::WriteStagnantAt(5, vec![])]).unwrap(); + + assert_eq!( + backend.load_stagnant_at_up_to(10, usize::MAX).unwrap(), + vec![(10, vec![Hash::repeat_byte(3)]),] + ); + } + + #[test] + fn write_read_blocks_at_height() { + let db = test_db(); + let config = Config { col_data: 0 }; + + let mut backend = DbBackend::new(db, config); + + backend + .write(vec![ + BackendWriteOp::WriteBlocksByNumber(2, vec![Hash::repeat_byte(1)]), + BackendWriteOp::WriteBlocksByNumber(5, vec![Hash::repeat_byte(2)]), + BackendWriteOp::WriteBlocksByNumber(10, vec![Hash::repeat_byte(3)]), + ]) + .unwrap(); + + assert_eq!(backend.load_blocks_by_number(2).unwrap(), vec![Hash::repeat_byte(1)]); + + assert_eq!(backend.load_blocks_by_number(3).unwrap(), vec![]); + + backend + .write(vec![ + BackendWriteOp::WriteBlocksByNumber(2, vec![]), + BackendWriteOp::DeleteBlocksByNumber(5), + ]) + .unwrap(); + + assert_eq!(backend.load_blocks_by_number(2).unwrap(), vec![]); + + assert_eq!(backend.load_blocks_by_number(5).unwrap(), vec![]); + + assert_eq!(backend.load_blocks_by_number(10).unwrap(), vec![Hash::repeat_byte(3)]); + } +} diff --git a/polkadot/node/core/chain-selection/src/lib.rs b/polkadot/node/core/chain-selection/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..aa5bb9548ad2484b3e0bdc0499b250335ea57f35 --- /dev/null +++ b/polkadot/node/core/chain-selection/src/lib.rs @@ -0,0 +1,743 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implements the Chain Selection Subsystem. + +use polkadot_node_primitives::BlockWeight; +use polkadot_node_subsystem::{ + errors::ChainApiError, + messages::{ChainApiMessage, ChainSelectionMessage}, + overseer::{self, SubsystemSender}, + FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, +}; +use polkadot_node_subsystem_util::database::Database; +use polkadot_primitives::{BlockNumber, ConsensusLog, Hash, Header}; + +use futures::{channel::oneshot, future::Either, prelude::*}; +use parity_scale_codec::Error as CodecError; + +use std::{ + sync::Arc, + time::{Duration, SystemTime, UNIX_EPOCH}, +}; + +use crate::backend::{Backend, BackendWriteOp, OverlayedBackend}; + +mod backend; +mod db_backend; +mod tree; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &str = "parachain::chain-selection"; +/// Timestamp based on the 1 Jan 1970 UNIX base, which is persistent across node restarts and OS +/// reboots. +type Timestamp = u64; + +// If a block isn't approved in 120 seconds, nodes will abandon it +// and begin building on another chain. +const STAGNANT_TIMEOUT: Timestamp = 120; +// Delay prunning of the stagnant keys in prune only mode by 25 hours to avoid interception with the +// finality +const STAGNANT_PRUNE_DELAY: Timestamp = 25 * 60 * 60; +// Maximum number of stagnant entries cleaned during one `STAGNANT_TIMEOUT` iteration +const MAX_STAGNANT_ENTRIES: usize = 1000; + +#[derive(Debug, Clone)] +enum Approval { + // Approved + Approved, + // Unapproved but not stagnant + Unapproved, + // Unapproved and stagnant. + Stagnant, +} + +impl Approval { + fn is_stagnant(&self) -> bool { + matches!(*self, Approval::Stagnant) + } +} + +#[derive(Debug, Clone)] +struct ViabilityCriteria { + // Whether this block has been explicitly reverted by one of its descendants. + explicitly_reverted: bool, + // The approval state of this block specifically. + approval: Approval, + // The earliest unviable ancestor - the hash of the earliest unfinalized + // block in the ancestry which is explicitly reverted or stagnant. + earliest_unviable_ancestor: Option, +} + +impl ViabilityCriteria { + fn is_viable(&self) -> bool { + self.is_parent_viable() && self.is_explicitly_viable() + } + + // Whether the current block is explicitly viable. + // That is, whether the current block is neither reverted nor stagnant. + fn is_explicitly_viable(&self) -> bool { + !self.explicitly_reverted && !self.approval.is_stagnant() + } + + // Whether the parent is viable. This assumes that the parent + // descends from the finalized chain. + fn is_parent_viable(&self) -> bool { + self.earliest_unviable_ancestor.is_none() + } +} + +// Light entries describing leaves of the chain. +// +// These are ordered first by weight and then by block number. +#[derive(Debug, Clone, PartialEq)] +struct LeafEntry { + weight: BlockWeight, + block_number: BlockNumber, + block_hash: Hash, +} + +impl PartialOrd for LeafEntry { + fn partial_cmp(&self, other: &Self) -> Option { + let ord = self.weight.cmp(&other.weight).then(self.block_number.cmp(&other.block_number)); + + if !matches!(ord, std::cmp::Ordering::Equal) { + Some(ord) + } else { + None + } + } +} + +#[derive(Debug, Default, Clone)] +struct LeafEntrySet { + inner: Vec, +} + +impl LeafEntrySet { + fn remove(&mut self, hash: &Hash) -> bool { + match self.inner.iter().position(|e| &e.block_hash == hash) { + None => false, + Some(i) => { + self.inner.remove(i); + true + }, + } + } + + fn insert(&mut self, new: LeafEntry) { + let mut pos = None; + for (i, e) in self.inner.iter().enumerate() { + if e == &new { + return + } + if e < &new { + pos = Some(i); + break + } + } + + match pos { + None => self.inner.push(new), + Some(i) => self.inner.insert(i, new), + } + } + + fn into_hashes_descending(self) -> impl Iterator { + self.inner.into_iter().map(|e| e.block_hash) + } +} + +#[derive(Debug, Clone)] +struct BlockEntry { + block_hash: Hash, + block_number: BlockNumber, + parent_hash: Hash, + children: Vec, + viability: ViabilityCriteria, + weight: BlockWeight, +} + +impl BlockEntry { + fn leaf_entry(&self) -> LeafEntry { + LeafEntry { + block_hash: self.block_hash, + block_number: self.block_number, + weight: self.weight, + } + } + + fn non_viable_ancestor_for_child(&self) -> Option { + if self.viability.is_viable() { + None + } else { + self.viability.earliest_unviable_ancestor.or(Some(self.block_hash)) + } + } +} + +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum Error { + #[error(transparent)] + ChainApi(#[from] ChainApiError), + + #[error(transparent)] + Io(#[from] std::io::Error), + + #[error(transparent)] + Oneshot(#[from] oneshot::Canceled), + + #[error(transparent)] + Subsystem(#[from] SubsystemError), + + #[error(transparent)] + Codec(#[from] CodecError), +} + +impl Error { + fn trace(&self) { + match self { + // don't spam the log with spurious errors + Self::Oneshot(_) => gum::debug!(target: LOG_TARGET, err = ?self), + // it's worth reporting otherwise + _ => gum::warn!(target: LOG_TARGET, err = ?self), + } + } +} + +/// A clock used for fetching the current timestamp. +pub trait Clock { + /// Get the current timestamp. + fn timestamp_now(&self) -> Timestamp; +} + +struct SystemClock; + +impl Clock for SystemClock { + fn timestamp_now(&self) -> Timestamp { + // `SystemTime` is notoriously non-monotonic, so our timers might not work + // exactly as expected. Regardless, stagnation is detected on the order of minutes, + // and slippage of a few seconds in either direction won't cause any major harm. + // + // The exact time that a block becomes stagnant in the local node is always expected + // to differ from other nodes due to network asynchrony and delays in block propagation. + // Non-monotonicity exarcerbates that somewhat, but not meaningfully. + + match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(d) => d.as_secs(), + Err(e) => { + gum::warn!( + target: LOG_TARGET, + err = ?e, + "Current time is before unix epoch. Validation will not work correctly." + ); + + 0 + }, + } + } +} + +/// The interval, in seconds to check for stagnant blocks. +#[derive(Debug, Clone)] +pub struct StagnantCheckInterval(Option); + +impl Default for StagnantCheckInterval { + fn default() -> Self { + // 5 seconds is a reasonable balance between avoiding DB reads and + // ensuring validators are generally in agreement on stagnant blocks. + // + // Assuming a network delay of D, the longest difference in view possible + // between 2 validators is D + 5s. + const DEFAULT_STAGNANT_CHECK_INTERVAL: Duration = Duration::from_secs(5); + + StagnantCheckInterval(Some(DEFAULT_STAGNANT_CHECK_INTERVAL)) + } +} + +impl StagnantCheckInterval { + /// Create a new stagnant-check interval wrapping the given duration. + pub fn new(interval: Duration) -> Self { + StagnantCheckInterval(Some(interval)) + } + + /// Create a `StagnantCheckInterval` which never triggers. + pub fn never() -> Self { + StagnantCheckInterval(None) + } + + fn timeout_stream(&self) -> impl Stream { + match self.0 { + Some(interval) => Either::Left({ + let mut delay = futures_timer::Delay::new(interval); + + futures::stream::poll_fn(move |cx| { + let poll = delay.poll_unpin(cx); + if poll.is_ready() { + delay.reset(interval) + } + + poll.map(Some) + }) + }), + None => Either::Right(futures::stream::pending()), + } + } +} + +/// Mode of the stagnant check operations: check and prune or prune only +#[derive(Debug, Clone)] +pub enum StagnantCheckMode { + CheckAndPrune, + PruneOnly, +} + +impl Default for StagnantCheckMode { + fn default() -> Self { + StagnantCheckMode::PruneOnly + } +} + +/// Configuration for the chain selection subsystem. +#[derive(Debug, Clone)] +pub struct Config { + /// The column in the database that the storage should use. + pub col_data: u32, + /// How often to check for stagnant blocks. + pub stagnant_check_interval: StagnantCheckInterval, + /// Mode of stagnant checks + pub stagnant_check_mode: StagnantCheckMode, +} + +/// The chain selection subsystem. +pub struct ChainSelectionSubsystem { + config: Config, + db: Arc, +} + +impl ChainSelectionSubsystem { + /// Create a new instance of the subsystem with the given config + /// and key-value store. + pub fn new(config: Config, db: Arc) -> Self { + ChainSelectionSubsystem { config, db } + } + + /// Revert to the block corresponding to the specified `hash`. + /// The operation is not allowed for blocks older than the last finalized one. + pub fn revert_to(&self, hash: Hash) -> Result<(), Error> { + let config = db_backend::v1::Config { col_data: self.config.col_data }; + let mut backend = db_backend::v1::DbBackend::new(self.db.clone(), config); + + let ops = tree::revert_to(&backend, hash)?.into_write_ops(); + + backend.write(ops) + } +} + +#[overseer::subsystem(ChainSelection, error = SubsystemError, prefix = self::overseer)] +impl ChainSelectionSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let backend = db_backend::v1::DbBackend::new( + self.db, + db_backend::v1::Config { col_data: self.config.col_data }, + ); + + SpawnedSubsystem { + future: run( + ctx, + backend, + self.config.stagnant_check_interval, + self.config.stagnant_check_mode, + Box::new(SystemClock), + ) + .map(Ok) + .boxed(), + name: "chain-selection-subsystem", + } + } +} + +#[overseer::contextbounds(ChainSelection, prefix = self::overseer)] +async fn run( + mut ctx: Context, + mut backend: B, + stagnant_check_interval: StagnantCheckInterval, + stagnant_check_mode: StagnantCheckMode, + clock: Box, +) where + B: Backend, +{ + #![allow(clippy::all)] + loop { + let res = run_until_error( + &mut ctx, + &mut backend, + &stagnant_check_interval, + &stagnant_check_mode, + &*clock, + ) + .await; + match res { + Err(e) => { + e.trace(); + // All errors are considered fatal right now: + break + }, + Ok(()) => { + gum::info!(target: LOG_TARGET, "received `Conclude` signal, exiting"); + break + }, + } + } +} + +// Run the subsystem until an error is encountered or a `conclude` signal is received. +// Most errors are non-fatal and should lead to another call to this function. +// +// A return value of `Ok` indicates that an exit should be made, while non-fatal errors +// lead to another call to this function. +#[overseer::contextbounds(ChainSelection, prefix = self::overseer)] +async fn run_until_error( + ctx: &mut Context, + backend: &mut B, + stagnant_check_interval: &StagnantCheckInterval, + stagnant_check_mode: &StagnantCheckMode, + clock: &(dyn Clock + Sync), +) -> Result<(), Error> +where + B: Backend, +{ + let mut stagnant_check_stream = stagnant_check_interval.timeout_stream(); + loop { + futures::select! { + msg = ctx.recv().fuse() => { + let msg = msg?; + match msg { + FromOrchestra::Signal(OverseerSignal::Conclude) => { + return Ok(()) + } + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => { + if let Some(leaf) = update.activated { + let write_ops = handle_active_leaf( + ctx.sender(), + &*backend, + clock.timestamp_now() + STAGNANT_TIMEOUT, + leaf.hash, + ).await?; + + backend.write(write_ops)?; + } + } + FromOrchestra::Signal(OverseerSignal::BlockFinalized(h, n)) => { + handle_finalized_block(backend, h, n)? + } + FromOrchestra::Communication { msg } => match msg { + ChainSelectionMessage::Approved(hash) => { + handle_approved_block(backend, hash)? + } + ChainSelectionMessage::Leaves(tx) => { + let leaves = load_leaves(ctx.sender(), &*backend).await?; + let _ = tx.send(leaves); + } + ChainSelectionMessage::BestLeafContaining(required, tx) => { + let best_containing = backend::find_best_leaf_containing( + &*backend, + required, + )?; + + // note - this may be none if the finalized block is + // a leaf. this is fine according to the expected usage of the + // function. `None` responses should just `unwrap_or(required)`, + // so if the required block is the finalized block, then voilá. + + let _ = tx.send(best_containing); + } + ChainSelectionMessage::RevertBlocks(blocks_to_revert) => { + let write_ops = handle_revert_blocks(backend, blocks_to_revert)?; + backend.write(write_ops)?; + } + } + } + } + _ = stagnant_check_stream.next().fuse() => { + match stagnant_check_mode { + StagnantCheckMode::CheckAndPrune => detect_stagnant(backend, clock.timestamp_now(), MAX_STAGNANT_ENTRIES), + StagnantCheckMode::PruneOnly => { + let now_timestamp = clock.timestamp_now(); + prune_only_stagnant(backend, now_timestamp - STAGNANT_PRUNE_DELAY, MAX_STAGNANT_ENTRIES) + }, + }?; + } + } + } +} + +async fn fetch_finalized( + sender: &mut impl SubsystemSender, +) -> Result, Error> { + let (number_tx, number_rx) = oneshot::channel(); + + sender.send_message(ChainApiMessage::FinalizedBlockNumber(number_tx)).await; + + let number = match number_rx.await? { + Ok(number) => number, + Err(err) => { + gum::warn!(target: LOG_TARGET, ?err, "Fetching finalized number failed"); + return Ok(None) + }, + }; + + let (hash_tx, hash_rx) = oneshot::channel(); + + sender.send_message(ChainApiMessage::FinalizedBlockHash(number, hash_tx)).await; + + match hash_rx.await? { + Err(err) => { + gum::warn!(target: LOG_TARGET, number, ?err, "Fetching finalized block number failed"); + Ok(None) + }, + Ok(None) => { + gum::warn!(target: LOG_TARGET, number, "Missing hash for finalized block number"); + Ok(None) + }, + Ok(Some(h)) => Ok(Some((h, number))), + } +} + +async fn fetch_header( + sender: &mut impl SubsystemSender, + hash: Hash, +) -> Result, Error> { + let (tx, rx) = oneshot::channel(); + sender.send_message(ChainApiMessage::BlockHeader(hash, tx)).await; + + Ok(rx.await?.unwrap_or_else(|err| { + gum::warn!(target: LOG_TARGET, ?hash, ?err, "Missing hash for finalized block number"); + None + })) +} + +async fn fetch_block_weight( + sender: &mut impl overseer::SubsystemSender, + hash: Hash, +) -> Result, Error> { + let (tx, rx) = oneshot::channel(); + sender.send_message(ChainApiMessage::BlockWeight(hash, tx)).await; + + let res = rx.await?; + + Ok(res.unwrap_or_else(|err| { + gum::warn!(target: LOG_TARGET, ?hash, ?err, "Missing hash for finalized block number"); + None + })) +} + +// Handle a new active leaf. +async fn handle_active_leaf( + sender: &mut impl overseer::ChainSelectionSenderTrait, + backend: &impl Backend, + stagnant_at: Timestamp, + hash: Hash, +) -> Result, Error> { + let lower_bound = match backend.load_first_block_number()? { + Some(l) => { + // We want to iterate back to finalized, and first block number + // is assumed to be 1 above finalized - the implicit root of the + // tree. + l.saturating_sub(1) + }, + None => fetch_finalized(sender).await?.map_or(1, |(_, n)| n), + }; + + let header = match fetch_header(sender, hash).await? { + None => { + gum::warn!(target: LOG_TARGET, ?hash, "Missing header for new head"); + return Ok(Vec::new()) + }, + Some(h) => h, + }; + + let new_blocks = polkadot_node_subsystem_util::determine_new_blocks( + sender, + |h| backend.load_block_entry(h).map(|b| b.is_some()), + hash, + &header, + lower_bound, + ) + .await?; + + let mut overlay = OverlayedBackend::new(backend); + + // determine_new_blocks gives blocks in descending order. + // for this, we want ascending order. + for (hash, header) in new_blocks.into_iter().rev() { + let weight = match fetch_block_weight(sender, hash).await? { + None => { + gum::warn!( + target: LOG_TARGET, + ?hash, + "Missing block weight for new head. Skipping chain.", + ); + + // If we don't know the weight, we can't import the block. + // And none of its descendants either. + break + }, + Some(w) => w, + }; + + let reversion_logs = extract_reversion_logs(&header); + tree::import_block( + &mut overlay, + hash, + header.number, + header.parent_hash, + reversion_logs, + weight, + stagnant_at, + )?; + } + + Ok(overlay.into_write_ops().collect()) +} + +// Extract all reversion logs from a header in ascending order. +// +// Ignores logs with number >= the block header number. +fn extract_reversion_logs(header: &Header) -> Vec { + let number = header.number; + let mut logs = header + .digest + .logs() + .iter() + .enumerate() + .filter_map(|(i, d)| match ConsensusLog::from_digest_item(d) { + Err(e) => { + gum::warn!( + target: LOG_TARGET, + err = ?e, + index = i, + block_hash = ?header.hash(), + "Digest item failed to encode" + ); + + None + }, + Ok(Some(ConsensusLog::Revert(b))) if b < number => Some(b), + Ok(Some(ConsensusLog::Revert(b))) => { + gum::warn!( + target: LOG_TARGET, + revert_target = b, + block_number = number, + block_hash = ?header.hash(), + "Block issued invalid revert digest targeting itself or future" + ); + + None + }, + Ok(_) => None, + }) + .collect::>(); + + logs.sort(); + + logs +} + +/// Handle a finalized block event. +fn handle_finalized_block( + backend: &mut impl Backend, + finalized_hash: Hash, + finalized_number: BlockNumber, +) -> Result<(), Error> { + let ops = tree::finalize_block(&*backend, finalized_hash, finalized_number)?.into_write_ops(); + + backend.write(ops) +} + +// Handle an approved block event. +fn handle_approved_block(backend: &mut impl Backend, approved_block: Hash) -> Result<(), Error> { + let ops = { + let mut overlay = OverlayedBackend::new(&*backend); + + tree::approve_block(&mut overlay, approved_block)?; + + overlay.into_write_ops() + }; + + backend.write(ops) +} + +// Here we revert a provided group of blocks. The most common cause for this is that +// the dispute coordinator has notified chain selection of a dispute which concluded +// against a candidate. +fn handle_revert_blocks( + backend: &impl Backend, + blocks_to_revert: Vec<(BlockNumber, Hash)>, +) -> Result, Error> { + let mut overlay = OverlayedBackend::new(backend); + for (block_number, block_hash) in blocks_to_revert { + tree::apply_single_reversion(&mut overlay, block_hash, block_number)?; + } + + Ok(overlay.into_write_ops().collect()) +} + +fn detect_stagnant( + backend: &mut impl Backend, + now: Timestamp, + max_elements: usize, +) -> Result<(), Error> { + let ops = { + let overlay = tree::detect_stagnant(&*backend, now, max_elements)?; + + overlay.into_write_ops() + }; + + backend.write(ops) +} + +fn prune_only_stagnant( + backend: &mut impl Backend, + up_to: Timestamp, + max_elements: usize, +) -> Result<(), Error> { + let ops = { + let overlay = tree::prune_only_stagnant(&*backend, up_to, max_elements)?; + + overlay.into_write_ops() + }; + + backend.write(ops) +} + +// Load the leaves from the backend. If there are no leaves, then return +// the finalized block. +async fn load_leaves( + sender: &mut impl overseer::SubsystemSender, + backend: &impl Backend, +) -> Result, Error> { + let leaves: Vec<_> = backend.load_leaves()?.into_hashes_descending().collect(); + + if leaves.is_empty() { + Ok(fetch_finalized(sender).await?.map_or(Vec::new(), |(h, _)| vec![h])) + } else { + Ok(leaves) + } +} diff --git a/polkadot/node/core/chain-selection/src/tests.rs b/polkadot/node/core/chain-selection/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..c04f9aaf66063d6f9d7e16d8b2a4e020c0c75b70 --- /dev/null +++ b/polkadot/node/core/chain-selection/src/tests.rs @@ -0,0 +1,2119 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests for the subsystem. +//! +//! These primarily revolve around having a backend which is shared between +//! both the test code and the tested subsystem, and which also gives the +//! test code the ability to wait for write operations to occur. + +use super::*; +use std::{ + collections::{BTreeMap, HashMap, HashSet}, + sync::{ + atomic::{AtomicU64, Ordering as AtomicOrdering}, + Arc, + }, +}; + +use assert_matches::assert_matches; +use futures::channel::oneshot; +use parity_scale_codec::Encode; +use parking_lot::Mutex; +use sp_core::testing::TaskExecutor; + +use polkadot_node_subsystem::{ + jaeger, messages::AllMessages, ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, +}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_primitives::{BlakeTwo256, ConsensusLog, HashT}; + +#[derive(Default)] +struct TestBackendInner { + leaves: LeafEntrySet, + block_entries: HashMap, + blocks_by_number: BTreeMap>, + stagnant_at: BTreeMap>, + // earlier wakers at the back. + write_wakers: Vec>, +} + +#[derive(Clone)] +struct TestBackend { + inner: Arc>, +} + +impl TestBackend { + // Yields a receiver which will be woken up on some future write + // to the backend along with its position (starting at 0) in the + // queue. + // + // Our tests assume that there is only one task calling this function + // and the index is useful to get a waker that will trigger after + // some known amount of writes to the backend that happen internally + // inside the subsystem. + // + // It's important to call this function at points where no writes + // are pending to the backend. This requires knowing some details + // about the internals of the subsystem, so the abstraction leaks + // somewhat, but this is acceptable enough. + fn await_next_write(&self) -> (usize, oneshot::Receiver<()>) { + let (tx, rx) = oneshot::channel(); + + let mut inner = self.inner.lock(); + let pos = inner.write_wakers.len(); + inner.write_wakers.insert(0, tx); + + (pos, rx) + } + + // Assert the backend contains only the given blocks and no others. + // This does not check the stagnant_at mapping because that is + // pruned lazily by the subsystem as opposed to eagerly. + fn assert_contains_only(&self, blocks: Vec<(BlockNumber, Hash)>) { + let hashes: Vec<_> = blocks.iter().map(|(_, h)| *h).collect(); + let mut by_number: HashMap<_, HashSet<_>> = HashMap::new(); + + for (number, hash) in blocks { + by_number.entry(number).or_default().insert(hash); + } + + let inner = self.inner.lock(); + assert_eq!(inner.block_entries.len(), hashes.len()); + assert_eq!(inner.blocks_by_number.len(), by_number.len()); + + for leaf in inner.leaves.clone().into_hashes_descending() { + assert!(hashes.contains(&leaf)); + } + + for (number, hashes_at_number) in by_number { + let at = inner.blocks_by_number.get(&number).unwrap(); + for hash in at { + assert!(hashes_at_number.contains(&hash)); + } + } + } + + fn assert_stagnant_at_state(&self, stagnant_at: Vec<(Timestamp, Vec)>) { + let inner = self.inner.lock(); + assert_eq!(inner.stagnant_at.len(), stagnant_at.len()); + for (at, hashes) in stagnant_at { + let stored_hashes = inner.stagnant_at.get(&at).unwrap(); + assert_eq!(hashes.len(), stored_hashes.len()); + for hash in hashes { + assert!(stored_hashes.contains(&hash)); + } + } + } +} + +impl Default for TestBackend { + fn default() -> Self { + TestBackend { inner: Default::default() } + } +} + +impl Backend for TestBackend { + fn load_block_entry(&self, hash: &Hash) -> Result, Error> { + Ok(self.inner.lock().block_entries.get(hash).map(|e| e.clone())) + } + fn load_leaves(&self) -> Result { + Ok(self.inner.lock().leaves.clone()) + } + fn load_stagnant_at(&self, timestamp: Timestamp) -> Result, Error> { + Ok(self.inner.lock().stagnant_at.get(×tamp).map_or(Vec::new(), |s| s.clone())) + } + fn load_stagnant_at_up_to( + &self, + up_to: Timestamp, + max_elements: usize, + ) -> Result)>, Error> { + Ok(self + .inner + .lock() + .stagnant_at + .range(..=up_to) + .enumerate() + .take_while(|(idx, _)| *idx < max_elements) + .map(|(_, (t, v))| (*t, v.clone())) + .collect()) + } + fn load_first_block_number(&self) -> Result, Error> { + Ok(self.inner.lock().blocks_by_number.range(..).map(|(k, _)| *k).next()) + } + fn load_blocks_by_number(&self, number: BlockNumber) -> Result, Error> { + Ok(self + .inner + .lock() + .blocks_by_number + .get(&number) + .map_or(Vec::new(), |v| v.clone())) + } + + fn write(&mut self, ops: I) -> Result<(), Error> + where + I: IntoIterator, + { + let ops: Vec<_> = ops.into_iter().collect(); + + // Early return if empty because empty writes shouldn't + // trigger wakeups (they happen on an interval) + if ops.is_empty() { + return Ok(()) + } + let mut inner = self.inner.lock(); + + for op in ops { + match op { + BackendWriteOp::WriteBlockEntry(entry) => { + inner.block_entries.insert(entry.block_hash, entry); + }, + BackendWriteOp::WriteBlocksByNumber(number, hashes) => { + inner.blocks_by_number.insert(number, hashes); + }, + BackendWriteOp::WriteViableLeaves(leaves) => { + inner.leaves = leaves; + }, + BackendWriteOp::WriteStagnantAt(time, hashes) => { + inner.stagnant_at.insert(time, hashes); + }, + BackendWriteOp::DeleteBlocksByNumber(number) => { + inner.blocks_by_number.remove(&number); + }, + BackendWriteOp::DeleteBlockEntry(hash) => { + inner.block_entries.remove(&hash); + }, + BackendWriteOp::DeleteStagnantAt(time) => { + inner.stagnant_at.remove(&time); + }, + } + } + + if let Some(waker) = inner.write_wakers.pop() { + let _ = waker.send(()); + } + Ok(()) + } +} + +#[derive(Clone)] +pub struct TestClock(Arc); + +impl TestClock { + fn new(initial: u64) -> Self { + TestClock(Arc::new(AtomicU64::new(initial))) + } + + fn inc_by(&self, duration: u64) { + self.0.fetch_add(duration, AtomicOrdering::Relaxed); + } +} + +impl Clock for TestClock { + fn timestamp_now(&self) -> Timestamp { + self.0.load(AtomicOrdering::Relaxed) + } +} + +const TEST_STAGNANT_INTERVAL: Duration = Duration::from_millis(20); + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; + +fn test_harness>( + test: impl FnOnce(TestBackend, TestClock, VirtualOverseer) -> T, +) { + let pool = TaskExecutor::new(); + let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool); + + let backend = TestBackend::default(); + let clock = TestClock::new(0); + let subsystem = crate::run( + context, + backend.clone(), + StagnantCheckInterval::new(TEST_STAGNANT_INTERVAL), + StagnantCheckMode::CheckAndPrune, + Box::new(clock.clone()), + ); + + let test_fut = test(backend, clock, virtual_overseer); + let test_and_conclude = async move { + let mut virtual_overseer = test_fut.await; + virtual_overseer.send(OverseerSignal::Conclude.into()).await; + + // Ensure no messages are pending when the subsystem shuts down. + assert!(virtual_overseer.try_recv().await.is_none()); + }; + futures::executor::block_on(futures::future::join(subsystem, test_and_conclude)); +} + +// Answer requests from the subsystem about the finalized block. +async fn answer_finalized_block_info( + overseer: &mut VirtualOverseer, + finalized_number: BlockNumber, + finalized_hash: Hash, +) { + assert_matches!( + overseer.recv().await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(tx)) => { + let _ = tx.send(Ok(finalized_number)); + } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockHash(n, tx)) => { + assert_eq!(n, finalized_number); + let _ = tx.send(Ok(Some(finalized_hash))); + } + ); +} + +async fn answer_header_request( + overseer: &mut VirtualOverseer, + maybe_header: impl Into>, +) { + assert_matches!( + overseer.recv().await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(hash, tx)) => { + let maybe_header = maybe_header.into(); + assert!(maybe_header.as_ref().map_or(true, |h| h.hash() == hash)); + let _ = tx.send(Ok(maybe_header)); + } + ) +} + +async fn answer_weight_request( + overseer: &mut VirtualOverseer, + hash: Hash, + weight: impl Into>, +) { + assert_matches!( + overseer.recv().await, + AllMessages::ChainApi(ChainApiMessage::BlockWeight(h, tx)) => { + assert_eq!(h, hash); + let _ = tx.send(Ok(weight.into())); + } + ) +} + +fn child_header(parent_number: BlockNumber, parent_hash: Hash) -> Header { + Header { + parent_hash, + number: parent_number + 1, + state_root: Default::default(), + extrinsics_root: Default::default(), + digest: Default::default(), + } +} + +fn salt_header(header: &mut Header, salt: impl Encode) { + header.state_root = BlakeTwo256::hash_of(&salt) +} + +fn add_reversions(header: &mut Header, reversions: impl IntoIterator) { + for log in reversions.into_iter().map(ConsensusLog::Revert) { + header.digest.logs.push(log.into()) + } +} + +// Builds a chain on top of the given base, with one block for each +// provided weight. +fn construct_chain_on_base( + weights: impl IntoIterator, + base_number: BlockNumber, + base_hash: Hash, + mut mutate: impl FnMut(&mut Header), +) -> (Hash, Vec<(Header, BlockWeight)>) { + let mut parent_number = base_number; + let mut parent_hash = base_hash; + + let mut chain = Vec::new(); + for weight in weights { + let mut header = child_header(parent_number, parent_hash); + mutate(&mut header); + + parent_number = header.number; + parent_hash = header.hash(); + chain.push((header, weight)); + } + + (parent_hash, chain) +} + +// import blocks 1-by-1. If `finalized_base` is supplied, +// it will be answered before the first block in `answers. +async fn import_blocks_into( + virtual_overseer: &mut VirtualOverseer, + backend: &TestBackend, + mut finalized_base: Option<(BlockNumber, Hash)>, + blocks: Vec<(Header, BlockWeight)>, +) { + for (header, weight) in blocks { + let (_, write_rx) = backend.await_next_write(); + + let hash = header.hash(); + virtual_overseer + .send( + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash, + number: header.number, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })) + .into(), + ) + .await; + + if let Some((f_n, f_h)) = finalized_base.take() { + answer_finalized_block_info(virtual_overseer, f_n, f_h).await; + } + + answer_header_request(virtual_overseer, header.clone()).await; + answer_weight_request(virtual_overseer, hash, weight).await; + + write_rx.await.unwrap(); + } +} + +async fn import_chains_into_empty( + virtual_overseer: &mut VirtualOverseer, + backend: &TestBackend, + finalized_number: BlockNumber, + finalized_hash: Hash, + chains: Vec>, +) { + for (i, chain) in chains.into_iter().enumerate() { + let finalized_base = Some((finalized_number, finalized_hash)).filter(|_| i == 0); + import_blocks_into(virtual_overseer, backend, finalized_base, chain).await; + } +} + +// Import blocks all at once. This assumes that the ancestor is known/finalized +// but none of the other blocks. +// import blocks 1-by-1. If `finalized_base` is supplied, +// it will be answered before the first block. +// +// some pre-blocks may need to be supplied to answer ancestry requests +// that gather batches beyond the beginning of the new chain. +// pre-blocks are those already known by the subsystem, however, +// the subsystem has no way of knowin that until requesting ancestry. +async fn import_all_blocks_into( + virtual_overseer: &mut VirtualOverseer, + backend: &TestBackend, + finalized_base: Option<(BlockNumber, Hash)>, + pre_blocks: Vec
, + blocks: Vec<(Header, BlockWeight)>, +) { + assert!(blocks.len() > 1, "gap only makes sense if importing multiple blocks"); + + let head = blocks.last().unwrap().0.clone(); + let head_hash = head.hash(); + + let (_, write_rx) = backend.await_next_write(); + virtual_overseer + .send( + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: head_hash, + number: head.number, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })) + .into(), + ) + .await; + + if let Some((f_n, f_h)) = finalized_base { + answer_finalized_block_info(virtual_overseer, f_n, f_h).await; + } + + // Head is always fetched first. + answer_header_request(virtual_overseer, head).await; + + // Answer header and ancestry requests until the parent of head + // is imported. + { + let find_block_header = |expected_hash| { + pre_blocks + .iter() + .cloned() + .chain(blocks.iter().map(|(h, _)| h.clone())) + .find(|hdr| hdr.hash() == expected_hash) + .unwrap() + }; + + let mut behind_head = 0; + loop { + let nth_ancestor_of_head = |n: usize| { + // blocks: [d, e, f, head] + // pre: [a, b, c] + // + // [a, b, c, d, e, f, head] + // [6, 5, 4, 3, 2, 1, 0] + + let new_ancestry_end = blocks.len() - 1; + if n > new_ancestry_end { + // [6, 5, 4] -> [2, 1, 0] + let n_in_pre = n - blocks.len(); + let pre_blocks_end = pre_blocks.len() - 1; + pre_blocks[pre_blocks_end - n_in_pre].clone() + } else { + let blocks_end = blocks.len() - 1; + blocks[blocks_end - n].0.clone() + } + }; + + match virtual_overseer.recv().await { + AllMessages::ChainApi(ChainApiMessage::Ancestors { + hash: h, + k, + response_channel: tx, + }) => { + let prev_response = nth_ancestor_of_head(behind_head); + assert_eq!(h, prev_response.hash()); + + let _ = tx.send(Ok((0..k as usize) + .map(|n| n + behind_head + 1) + .map(nth_ancestor_of_head) + .map(|h| h.hash()) + .collect())); + + for _ in 0..k { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(h, tx)) => { + let header = find_block_header(h); + let _ = tx.send(Ok(Some(header))); + } + ) + } + + behind_head = behind_head + k as usize; + }, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(h, tx)) => { + let header = find_block_header(h); + let _ = tx.send(Ok(Some(header))); + + // Assuming that `determine_new_blocks` uses these + // instead of ancestry: 1. + behind_head += 1; + }, + AllMessages::ChainApi(ChainApiMessage::BlockWeight(h, tx)) => { + let (_, weight) = blocks.iter().find(|(hdr, _)| hdr.hash() == h).unwrap(); + let _ = tx.send(Ok(Some(*weight))); + + // Last weight has been returned. Time to go. + if h == head_hash { + break + } + }, + _ => panic!("unexpected message"), + } + } + } + write_rx.await.unwrap(); +} + +async fn finalize_block( + virtual_overseer: &mut VirtualOverseer, + backend: &TestBackend, + block_number: BlockNumber, + block_hash: Hash, +) { + let (_, write_rx) = backend.await_next_write(); + + virtual_overseer + .send(OverseerSignal::BlockFinalized(block_hash, block_number).into()) + .await; + + write_rx.await.unwrap(); +} + +fn extract_info_from_chain( + i: usize, + chain: &[(Header, BlockWeight)], +) -> (BlockNumber, Hash, BlockWeight) { + let &(ref header, weight) = &chain[i]; + + (header.number, header.hash(), weight) +} + +fn assert_backend_contains<'a>( + backend: &TestBackend, + headers: impl IntoIterator, +) { + for header in headers { + let hash = header.hash(); + assert!( + backend.load_blocks_by_number(header.number).unwrap().contains(&hash), + "blocks at {} does not contain {}", + header.number, + hash, + ); + assert!(backend.load_block_entry(&hash).unwrap().is_some(), "no entry found for {}", hash); + } +} + +fn assert_backend_contains_chains(backend: &TestBackend, chains: Vec>) { + for chain in chains { + assert_backend_contains(backend, chain.iter().map(|(hdr, _)| hdr)) + } +} + +fn assert_leaves(backend: &TestBackend, leaves: Vec) { + assert_eq!( + backend + .load_leaves() + .unwrap() + .into_hashes_descending() + .into_iter() + .collect::>(), + leaves, + ); +} + +async fn assert_leaves_query(virtual_overseer: &mut VirtualOverseer, leaves: Vec) { + assert!(!leaves.is_empty(), "empty leaves impossible. answer finalized query"); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { msg: ChainSelectionMessage::Leaves(tx) }) + .await; + + assert_eq!(rx.await.unwrap(), leaves); +} + +async fn assert_finalized_leaves_query( + virtual_overseer: &mut VirtualOverseer, + finalized_number: BlockNumber, + finalized_hash: Hash, +) { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { msg: ChainSelectionMessage::Leaves(tx) }) + .await; + + answer_finalized_block_info(virtual_overseer, finalized_number, finalized_hash).await; + + assert_eq!(rx.await.unwrap(), vec![finalized_hash]); +} + +async fn best_leaf_containing( + virtual_overseer: &mut VirtualOverseer, + required: Hash, +) -> Option { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: ChainSelectionMessage::BestLeafContaining(required, tx), + }) + .await; + + rx.await.unwrap() +} + +async fn approve_block( + virtual_overseer: &mut VirtualOverseer, + backend: &TestBackend, + approved: Hash, +) { + let (_, write_rx) = backend.await_next_write(); + virtual_overseer + .send(FromOrchestra::Communication { msg: ChainSelectionMessage::Approved(approved) }) + .await; + + write_rx.await.unwrap() +} + +#[test] +fn no_op_subsystem_run() { + test_harness(|_, _, virtual_overseer| async move { virtual_overseer }); +} + +#[test] +fn import_direct_child_of_finalized_on_empty() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + let child = child_header(finalized_number, finalized_hash); + let child_hash = child.hash(); + let child_weight = 1; + let child_number = child.number; + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + vec![(child.clone(), child_weight)], + ) + .await; + + assert_eq!(backend.load_first_block_number().unwrap().unwrap(), child_number); + assert_backend_contains(&backend, &[child]); + assert_leaves(&backend, vec![child_hash]); + assert_leaves_query(&mut virtual_overseer, vec![child_hash]).await; + + virtual_overseer + }) +} + +#[test] +fn import_chain_on_finalized_incrementally() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + let (head_hash, chain) = + construct_chain_on_base(vec![1, 2, 3, 4, 5], finalized_number, finalized_hash, |_| {}); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + chain.clone(), + ) + .await; + + assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 1); + assert_backend_contains(&backend, chain.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![head_hash]); + assert_leaves_query(&mut virtual_overseer, vec![head_hash]).await; + + virtual_overseer + }) +} + +#[test] +fn import_two_subtrees_on_finalized() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + let (a_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |_| {}); + + let (b_hash, chain_b) = + construct_chain_on_base(vec![2], finalized_number, finalized_hash, |h| { + salt_header(h, b"b") + }); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + chain_a.clone(), + ) + .await; + + import_blocks_into(&mut virtual_overseer, &backend, None, chain_b.clone()).await; + + assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 1); + assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h)); + assert_backend_contains(&backend, chain_b.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![b_hash, a_hash]); + assert_leaves_query(&mut virtual_overseer, vec![b_hash, a_hash]).await; + + virtual_overseer + }) +} + +#[test] +fn import_two_subtrees_on_nonzero_finalized() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 100; + let finalized_hash = Hash::repeat_byte(0); + + let (a_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |_| {}); + + let (b_hash, chain_b) = + construct_chain_on_base(vec![2], finalized_number, finalized_hash, |h| { + salt_header(h, b"b") + }); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + chain_a.clone(), + ) + .await; + + import_blocks_into(&mut virtual_overseer, &backend, None, chain_b.clone()).await; + + assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 101); + assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h)); + assert_backend_contains(&backend, chain_b.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![b_hash, a_hash]); + assert_leaves_query(&mut virtual_overseer, vec![b_hash, a_hash]).await; + + virtual_overseer + }) +} + +#[test] +fn leaves_ordered_by_weight_and_then_number() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3 + // A1 <- B2 + // F <- C1 <- C2 + // + // expected_leaves: [(C2, 3), (A3, 2), (B2, 2)] + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 1, 2], finalized_number, finalized_hash, |_| {}); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + + let (b2_hash, chain_b) = + construct_chain_on_base(vec![2], 1, a1_hash, |h| salt_header(h, b"b")); + + let (c2_hash, chain_c) = + construct_chain_on_base(vec![1, 3], finalized_number, finalized_hash, |h| { + salt_header(h, b"c") + }); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone(), chain_b.clone(), chain_c.clone()], + ) + .await; + + assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 1); + assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h)); + assert_backend_contains(&backend, chain_b.iter().map(|(h, _)| h)); + assert_backend_contains(&backend, chain_c.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![c2_hash, a3_hash, b2_hash]); + assert_leaves_query(&mut virtual_overseer, vec![c2_hash, a3_hash, b2_hash]).await; + virtual_overseer + }); +} + +#[test] +fn subtrees_imported_even_with_gaps() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3 + // A2 <- B3 <- B4 <- B5 + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |_| {}); + + let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); + + let (b5_hash, chain_b) = + construct_chain_on_base(vec![4, 4, 5], 2, a2_hash, |h| salt_header(h, b"b")); + + import_all_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + Vec::new(), + chain_a.clone(), + ) + .await; + + import_all_blocks_into( + &mut virtual_overseer, + &backend, + None, + vec![chain_a[0].0.clone(), chain_a[1].0.clone()], + chain_b.clone(), + ) + .await; + + assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 1); + assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h)); + assert_backend_contains(&backend, chain_b.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![b5_hash, a3_hash]); + assert_leaves_query(&mut virtual_overseer, vec![b5_hash, a3_hash]).await; + + virtual_overseer + }); +} + +#[test] +fn reversion_removes_viability_of_chain() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3. + // + // A3 reverts A1 + + let (_a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + if h.number == 3 { + add_reversions(h, Some(1)) + } + }); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + chain_a.clone(), + ) + .await; + + assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![]); + assert_finalized_leaves_query(&mut virtual_overseer, finalized_number, finalized_hash) + .await; + + virtual_overseer + }); +} + +#[test] +fn reversion_removes_viability_and_finds_ancestor_as_leaf() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3. + // + // A3 reverts A2 + + let (_a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + if h.number == 3 { + add_reversions(h, Some(2)) + } + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + chain_a.clone(), + ) + .await; + + assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![a1_hash]); + assert_leaves_query(&mut virtual_overseer, vec![a1_hash]).await; + + virtual_overseer + }); +} + +#[test] +fn ancestor_of_unviable_is_not_leaf_if_has_children() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3. + // A1 <- B2 + // + // A3 reverts A2 + + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |_| {}); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + + let (_a3_hash, chain_a_ext) = + construct_chain_on_base(vec![3], 2, a2_hash, |h| add_reversions(h, Some(2))); + + let (b2_hash, chain_b) = + construct_chain_on_base(vec![1], 1, a1_hash, |h| salt_header(h, b"b")); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + chain_a.clone(), + ) + .await; + + import_blocks_into(&mut virtual_overseer, &backend, None, chain_b.clone()).await; + + assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h)); + assert_backend_contains(&backend, chain_b.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![a2_hash, b2_hash]); + + import_blocks_into(&mut virtual_overseer, &backend, None, chain_a_ext.clone()).await; + + assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h)); + assert_backend_contains(&backend, chain_a_ext.iter().map(|(h, _)| h)); + assert_backend_contains(&backend, chain_b.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![b2_hash]); + assert_leaves_query(&mut virtual_overseer, vec![b2_hash]).await; + + virtual_overseer + }); +} + +#[test] +fn self_and_future_reversions_are_ignored() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3. + // + // A3 reverts itself and future blocks. ignored. + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + if h.number == 3 { + add_reversions(h, vec![3, 4, 100]) + } + }); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + chain_a.clone(), + ) + .await; + + assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![a3_hash]); + assert_leaves_query(&mut virtual_overseer, vec![a3_hash]).await; + + virtual_overseer + }); +} + +#[test] +fn revert_finalized_is_ignored() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 10; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3. + // + // A3 reverts itself and future blocks. ignored. + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + if h.number == 13 { + add_reversions(h, vec![10, 9, 8, 0, 1]) + } + }); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + chain_a.clone(), + ) + .await; + + assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![a3_hash]); + assert_leaves_query(&mut virtual_overseer, vec![a3_hash]).await; + + virtual_overseer + }); +} + +#[test] +fn reversion_affects_viability_of_all_subtrees() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3. + // A2 <- B3 <- B4 + // + // B4 reverts A2. + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |_| {}); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); + + let (_b4_hash, chain_b) = construct_chain_on_base(vec![3, 4], 2, a2_hash, |h| { + salt_header(h, b"b"); + if h.number == 4 { + add_reversions(h, Some(2)); + } + }); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + chain_a.clone(), + ) + .await; + + assert_leaves(&backend, vec![a3_hash]); + + import_blocks_into(&mut virtual_overseer, &backend, None, chain_b.clone()).await; + + assert_backend_contains(&backend, chain_a.iter().map(|(h, _)| h)); + assert_backend_contains(&backend, chain_b.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![a1_hash]); + assert_leaves_query(&mut virtual_overseer, vec![a1_hash]).await; + + virtual_overseer + }); +} + +#[test] +fn finalize_viable_prunes_subtrees() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // A2 <- X3 + // F <- A1 <- A2 <- A3. + // A1 <- B2 + // F <- C1 <- C2 <- C3 + // C2 <- D3 + // + // Finalize A2. Only A2, A3, and X3 should remain. + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 10], finalized_number, finalized_hash, |h| { + salt_header(h, b"a") + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); + + let (x3_hash, chain_x) = + construct_chain_on_base(vec![3], 2, a2_hash, |h| salt_header(h, b"x")); + + let (b2_hash, chain_b) = + construct_chain_on_base(vec![6], 1, a1_hash, |h| salt_header(h, b"b")); + + let (c3_hash, chain_c) = + construct_chain_on_base(vec![1, 2, 8], finalized_number, finalized_hash, |h| { + salt_header(h, b"c") + }); + let (_, c2_hash, _) = extract_info_from_chain(1, &chain_c); + + let (d3_hash, chain_d) = + construct_chain_on_base(vec![7], 2, c2_hash, |h| salt_header(h, b"d")); + + let all_chains = vec![ + chain_a.clone(), + chain_x.clone(), + chain_b.clone(), + chain_c.clone(), + chain_d.clone(), + ]; + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + all_chains.clone(), + ) + .await; + + assert_backend_contains_chains(&backend, all_chains.clone()); + assert_leaves(&backend, vec![a3_hash, c3_hash, d3_hash, b2_hash, x3_hash]); + + // Finalize block A2. Now lots of blocks should go missing. + finalize_block(&mut virtual_overseer, &backend, 2, a2_hash).await; + + // A2 <- A3 + // A2 <- X3 + + backend.assert_contains_only(vec![(3, a3_hash), (3, x3_hash)]); + + assert_leaves(&backend, vec![a3_hash, x3_hash]); + assert_leaves_query(&mut virtual_overseer, vec![a3_hash, x3_hash]).await; + + assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 3); + + assert_eq!(backend.load_blocks_by_number(3).unwrap(), vec![a3_hash, x3_hash]); + + virtual_overseer + }); +} + +#[test] +fn finalization_does_not_clobber_unviability() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3 + // A3 reverts A2. + // Finalize A1. + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 10], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + if h.number == 3 { + add_reversions(h, Some(2)); + } + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + chain_a.clone(), + ) + .await; + + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; + + assert_leaves(&backend, vec![]); + assert_finalized_leaves_query(&mut virtual_overseer, 1, a1_hash).await; + backend.assert_contains_only(vec![(3, a3_hash), (2, a2_hash)]); + + virtual_overseer + }); +} + +#[test] +fn finalization_erases_unviable() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3 + // A1 <- B2 + // + // A2 reverts A1. + // Finalize A1. + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + if h.number == 2 { + add_reversions(h, Some(1)); + } + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); + + let (b2_hash, chain_b) = + construct_chain_on_base(vec![1], 1, a1_hash, |h| salt_header(h, b"b")); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone(), chain_b.clone()], + ) + .await; + + assert_leaves(&backend, vec![]); + + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; + + assert_leaves(&backend, vec![a3_hash, b2_hash]); + assert_leaves_query(&mut virtual_overseer, vec![a3_hash, b2_hash]).await; + + backend.assert_contains_only(vec![(3, a3_hash), (2, a2_hash), (2, b2_hash)]); + + virtual_overseer + }); +} + +#[test] +fn finalize_erases_unviable_but_keeps_later_unviability() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3 + // A1 <- B2 + // + // A2 reverts A1. + // A3 reverts A2. + // Finalize A1. A2 is stil unviable, but B2 is viable. + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + if h.number == 2 { + add_reversions(h, Some(1)); + } + if h.number == 3 { + add_reversions(h, Some(2)); + } + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); + + let (b2_hash, chain_b) = + construct_chain_on_base(vec![1], 1, a1_hash, |h| salt_header(h, b"b")); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone(), chain_b.clone()], + ) + .await; + + assert_leaves(&backend, vec![]); + + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; + + assert_leaves(&backend, vec![b2_hash]); + assert_leaves_query(&mut virtual_overseer, vec![b2_hash]).await; + + backend.assert_contains_only(vec![(3, a3_hash), (2, a2_hash), (2, b2_hash)]); + + virtual_overseer + }); +} + +#[test] +fn finalize_erases_unviable_from_one_but_not_all_reverts() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3 + // + // A3 reverts A2 and A1. + // Finalize A1. A2 is stil unviable. + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + if h.number == 3 { + add_reversions(h, Some(1)); + add_reversions(h, Some(2)); + } + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone()], + ) + .await; + + assert_leaves(&backend, vec![]); + + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; + + assert_leaves(&backend, vec![]); + assert_finalized_leaves_query(&mut virtual_overseer, 1, a1_hash).await; + + backend.assert_contains_only(vec![(3, a3_hash), (2, a2_hash)]); + + virtual_overseer + }); +} + +#[test] +fn finalize_triggers_viability_search() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3 + // A2 <- B3 + // A2 <- C3 + // A3 reverts A1. + // Finalize A1. A3, B3, and C3 are all viable now. + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + if h.number == 3 { + add_reversions(h, Some(1)); + } + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); + + let (b3_hash, chain_b) = + construct_chain_on_base(vec![4], 2, a2_hash, |h| salt_header(h, b"b")); + + let (c3_hash, chain_c) = + construct_chain_on_base(vec![5], 2, a2_hash, |h| salt_header(h, b"c")); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone(), chain_b.clone(), chain_c.clone()], + ) + .await; + + assert_leaves(&backend, vec![]); + + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; + + assert_leaves(&backend, vec![c3_hash, b3_hash, a3_hash]); + assert_leaves_query(&mut virtual_overseer, vec![c3_hash, b3_hash, a3_hash]).await; + + backend.assert_contains_only(vec![(3, a3_hash), (3, b3_hash), (3, c3_hash), (2, a2_hash)]); + + virtual_overseer + }); +} + +#[test] +fn best_leaf_none_with_empty_db() { + test_harness(|_backend, _, mut virtual_overseer| async move { + let required = Hash::repeat_byte(1); + let best_leaf = best_leaf_containing(&mut virtual_overseer, required).await; + assert!(best_leaf.is_none()); + + virtual_overseer + }) +} + +#[test] +fn best_leaf_none_with_no_viable_leaves() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 + // + // A2 reverts A1. + + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + if h.number == 2 { + add_reversions(h, Some(1)); + } + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone()], + ) + .await; + + let best_leaf = best_leaf_containing(&mut virtual_overseer, a2_hash).await; + assert!(best_leaf.is_none()); + + let best_leaf = best_leaf_containing(&mut virtual_overseer, a1_hash).await; + assert!(best_leaf.is_none()); + + virtual_overseer + }) +} + +#[test] +fn best_leaf_none_with_unknown_required() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 + + let (_a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + let unknown_hash = Hash::repeat_byte(0x69); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone()], + ) + .await; + + let best_leaf = best_leaf_containing(&mut virtual_overseer, unknown_hash).await; + assert!(best_leaf.is_none()); + + virtual_overseer + }) +} + +#[test] +fn best_leaf_none_with_unviable_required() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 + // F <- B1 <- B2 + // + // A2 reverts A1. + + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + if h.number == 2 { + add_reversions(h, Some(1)); + } + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + + let (_b2_hash, chain_b) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { + salt_header(h, b"b"); + }); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone(), chain_b.clone()], + ) + .await; + + let best_leaf = best_leaf_containing(&mut virtual_overseer, a2_hash).await; + assert!(best_leaf.is_none()); + + let best_leaf = best_leaf_containing(&mut virtual_overseer, a1_hash).await; + assert!(best_leaf.is_none()); + + virtual_overseer + }) +} + +#[test] +fn best_leaf_with_finalized_required() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 + // F <- B1 <- B2 + // + // B2 > A2 + + let (_a2_hash, chain_a) = + construct_chain_on_base(vec![1, 1], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + let (b2_hash, chain_b) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { + salt_header(h, b"b"); + }); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone(), chain_b.clone()], + ) + .await; + + let best_leaf = best_leaf_containing(&mut virtual_overseer, finalized_hash).await; + assert_eq!(best_leaf, Some(b2_hash)); + + virtual_overseer + }) +} + +#[test] +fn best_leaf_with_unfinalized_required() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 + // F <- B1 <- B2 + // + // B2 > A2 + + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 1], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + + let (_b2_hash, chain_b) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { + salt_header(h, b"b"); + }); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone(), chain_b.clone()], + ) + .await; + + let best_leaf = best_leaf_containing(&mut virtual_overseer, a1_hash).await; + assert_eq!(best_leaf, Some(a2_hash)); + + virtual_overseer + }) +} + +#[test] +fn best_leaf_ancestor_of_all_leaves() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3 + // A1 <- B2 <- B3 + // B2 <- C3 + // + // C3 > B3 > A3 + + let (_a3_hash, chain_a) = + construct_chain_on_base(vec![1, 1, 2], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + + let (_b3_hash, chain_b) = construct_chain_on_base(vec![2, 3], 1, a1_hash, |h| { + salt_header(h, b"b"); + }); + + let (_, b2_hash, _) = extract_info_from_chain(0, &chain_b); + + let (c3_hash, chain_c) = construct_chain_on_base(vec![4], 2, b2_hash, |h| { + salt_header(h, b"c"); + }); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone(), chain_b.clone(), chain_c.clone()], + ) + .await; + + let best_leaf = best_leaf_containing(&mut virtual_overseer, a1_hash).await; + assert_eq!(best_leaf, Some(c3_hash)); + + virtual_overseer + }) +} + +#[test] +fn approve_message_approves_block_entry() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3 + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone()], + ) + .await; + + approve_block(&mut virtual_overseer, &backend, a3_hash).await; + + // a3 is approved, but not a1 or a2. + assert_matches!( + backend.load_block_entry(&a3_hash).unwrap().unwrap().viability.approval, + Approval::Approved + ); + + assert_matches!( + backend.load_block_entry(&a2_hash).unwrap().unwrap().viability.approval, + Approval::Unapproved + ); + + assert_matches!( + backend.load_block_entry(&a1_hash).unwrap().unwrap().viability.approval, + Approval::Unapproved + ); + + virtual_overseer + }) +} + +#[test] +fn approve_nonexistent_has_no_effect() { + test_harness(|backend, _, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 <- A3 + + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone()], + ) + .await; + + let nonexistent = Hash::repeat_byte(1); + virtual_overseer + .send(FromOrchestra::Communication { + msg: ChainSelectionMessage::Approved(nonexistent), + }) + .await; + + // None are approved. + assert_matches!( + backend.load_block_entry(&a3_hash).unwrap().unwrap().viability.approval, + Approval::Unapproved + ); + + assert_matches!( + backend.load_block_entry(&a2_hash).unwrap().unwrap().viability.approval, + Approval::Unapproved + ); + + assert_matches!( + backend.load_block_entry(&a1_hash).unwrap().unwrap().viability.approval, + Approval::Unapproved + ); + + virtual_overseer + }) +} + +#[test] +fn block_has_correct_stagnant_at() { + test_harness(|backend, clock, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 + + let (a1_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + let (a2_hash, chain_a_ext) = construct_chain_on_base(vec![1], 1, a1_hash, |h| { + salt_header(h, b"a"); + }); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone()], + ) + .await; + + clock.inc_by(1); + + import_blocks_into(&mut virtual_overseer, &backend, None, chain_a_ext.clone()).await; + + backend.assert_stagnant_at_state(vec![ + (STAGNANT_TIMEOUT, vec![a1_hash]), + (STAGNANT_TIMEOUT + 1, vec![a2_hash]), + ]); + + virtual_overseer + }) +} + +#[test] +fn detects_stagnant() { + test_harness(|backend, clock, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 + + let (a1_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone()], + ) + .await; + + { + let (_, write_rx) = backend.await_next_write(); + clock.inc_by(STAGNANT_TIMEOUT); + + write_rx.await.unwrap(); + } + + backend.assert_stagnant_at_state(vec![]); + + assert_matches!( + backend.load_block_entry(&a1_hash).unwrap().unwrap().viability.approval, + Approval::Stagnant + ); + + assert_leaves(&backend, vec![]); + + virtual_overseer + }) +} + +#[test] +fn finalize_stagnant_unlocks_subtree() { + test_harness(|backend, clock, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 + + let (a1_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + let (a2_hash, chain_a_ext) = construct_chain_on_base(vec![1], 1, a1_hash, |h| { + salt_header(h, b"a"); + }); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone()], + ) + .await; + + clock.inc_by(1); + + import_blocks_into(&mut virtual_overseer, &backend, None, chain_a_ext.clone()).await; + + { + let (_, write_rx) = backend.await_next_write(); + clock.inc_by(STAGNANT_TIMEOUT - 1); + + write_rx.await.unwrap(); + } + + backend.assert_stagnant_at_state(vec![(STAGNANT_TIMEOUT + 1, vec![a2_hash])]); + + assert_matches!( + backend.load_block_entry(&a1_hash).unwrap().unwrap().viability.approval, + Approval::Stagnant + ); + + assert_leaves(&backend, vec![]); + + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; + + assert_leaves(&backend, vec![a2_hash]); + + virtual_overseer + }) +} + +#[test] +fn approval_undoes_stagnant_unlocking_subtree() { + test_harness(|backend, clock, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 + + let (a1_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + let (a2_hash, chain_a_ext) = construct_chain_on_base(vec![1], 1, a1_hash, |h| { + salt_header(h, b"a"); + }); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone()], + ) + .await; + + clock.inc_by(1); + + import_blocks_into(&mut virtual_overseer, &backend, None, chain_a_ext.clone()).await; + + { + let (_, write_rx) = backend.await_next_write(); + clock.inc_by(STAGNANT_TIMEOUT - 1); + + write_rx.await.unwrap(); + } + + backend.assert_stagnant_at_state(vec![(STAGNANT_TIMEOUT + 1, vec![a2_hash])]); + + approve_block(&mut virtual_overseer, &backend, a1_hash).await; + + assert_matches!( + backend.load_block_entry(&a1_hash).unwrap().unwrap().viability.approval, + Approval::Approved + ); + + assert_leaves(&backend, vec![a2_hash]); + + virtual_overseer + }) +} + +#[test] +fn stagnant_preserves_parents_children() { + test_harness(|backend, clock, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 + // A1 <- B2 + + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + + let (b2_hash, chain_b) = construct_chain_on_base(vec![1], 1, a1_hash, |h| { + salt_header(h, b"b"); + }); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone(), chain_b.clone()], + ) + .await; + + approve_block(&mut virtual_overseer, &backend, a1_hash).await; + approve_block(&mut virtual_overseer, &backend, b2_hash).await; + + assert_leaves(&backend, vec![a2_hash, b2_hash]); + + { + let (_, write_rx) = backend.await_next_write(); + clock.inc_by(STAGNANT_TIMEOUT); + + write_rx.await.unwrap(); + } + + backend.assert_stagnant_at_state(vec![]); + assert_leaves(&backend, vec![b2_hash]); + + virtual_overseer + }) +} + +#[test] +fn stagnant_makes_childless_parent_leaf() { + test_harness(|backend, clock, mut virtual_overseer| async move { + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + // F <- A1 <- A2 + + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { + salt_header(h, b"a"); + }); + + let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); + + import_chains_into_empty( + &mut virtual_overseer, + &backend, + finalized_number, + finalized_hash, + vec![chain_a.clone()], + ) + .await; + + approve_block(&mut virtual_overseer, &backend, a1_hash).await; + + assert_leaves(&backend, vec![a2_hash]); + + { + let (_, write_rx) = backend.await_next_write(); + clock.inc_by(STAGNANT_TIMEOUT); + + write_rx.await.unwrap(); + } + + backend.assert_stagnant_at_state(vec![]); + assert_leaves(&backend, vec![a1_hash]); + + virtual_overseer + }) +} + +#[test] +fn revert_blocks_message_triggers_proper_reversion() { + test_harness(|backend, _, mut virtual_overseer| async move { + // Building mini chain with 1 finalized block and 3 unfinalized blocks + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + let (head_hash, built_chain) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |_| {}); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + built_chain.clone(), + ) + .await; + + // Checking mini chain + assert_backend_contains(&backend, built_chain.iter().map(|(h, _)| h)); + assert_leaves(&backend, vec![head_hash]); + assert_leaves_query(&mut virtual_overseer, vec![head_hash]).await; + + let block_1_hash = *backend.load_blocks_by_number(1).unwrap().get(0).unwrap(); + let block_2_hash = *backend.load_blocks_by_number(2).unwrap().get(0).unwrap(); + + // Sending revert blocks message + let (_, write_rx) = backend.await_next_write(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: ChainSelectionMessage::RevertBlocks(Vec::from([(2, block_2_hash)])), + }) + .await; + + write_rx.await.unwrap(); + + // Checking results: + // Block 2 should be explicitly reverted + assert_eq!( + backend + .load_block_entry(&block_2_hash) + .unwrap() + .unwrap() + .viability + .explicitly_reverted, + true + ); + // Block 3 should be non-viable, with 2 as its earliest unviable ancestor + assert_eq!( + backend + .load_block_entry(&head_hash) + .unwrap() + .unwrap() + .viability + .earliest_unviable_ancestor, + Some(block_2_hash) + ); + // Block 1 should be left as the only leaf + assert_leaves(&backend, vec![block_1_hash]); + + virtual_overseer + }) +} + +#[test] +fn revert_blocks_against_finalized_is_ignored() { + test_harness(|backend, _, mut virtual_overseer| async move { + // Building mini chain with 1 finalized block and 3 unfinalized blocks + let finalized_number = 0; + let finalized_hash = Hash::repeat_byte(0); + + let (head_hash, built_chain) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |_| {}); + + import_blocks_into( + &mut virtual_overseer, + &backend, + Some((finalized_number, finalized_hash)), + built_chain.clone(), + ) + .await; + + // Checking mini chain + assert_backend_contains(&backend, built_chain.iter().map(|(h, _)| h)); + + // Sending dispute concluded against message + virtual_overseer + .send(FromOrchestra::Communication { + msg: ChainSelectionMessage::RevertBlocks(Vec::from([( + finalized_number, + finalized_hash, + )])), + }) + .await; + + // Leaf should be head if reversion of finalized was properly ignored + assert_leaves(&backend, vec![head_hash]); + assert_leaves_query(&mut virtual_overseer, vec![head_hash]).await; + + virtual_overseer + }) +} diff --git a/polkadot/node/core/chain-selection/src/tree.rs b/polkadot/node/core/chain-selection/src/tree.rs new file mode 100644 index 0000000000000000000000000000000000000000..b4aba30368a621c1f1eaa5f1834fdb3343427d2f --- /dev/null +++ b/polkadot/node/core/chain-selection/src/tree.rs @@ -0,0 +1,778 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implements the tree-view over the data backend which we use to determine +//! viable leaves. +//! +//! The metadata is structured as a tree, with the root implicitly being the +//! finalized block, which is not stored as part of the tree. +//! +//! Each direct descendant of the finalized block acts as its own sub-tree, +//! and as the finalized block advances, orphaned sub-trees are entirely pruned. + +use polkadot_node_primitives::BlockWeight; +use polkadot_node_subsystem::ChainApiError; +use polkadot_primitives::{BlockNumber, Hash}; + +use std::collections::HashMap; + +use super::{Approval, BlockEntry, Error, LeafEntry, Timestamp, ViabilityCriteria, LOG_TARGET}; +use crate::backend::{Backend, OverlayedBackend}; + +// A viability update to be applied to a block. +struct ViabilityUpdate(Option); + +impl ViabilityUpdate { + // Apply the viability update to a single block, yielding the updated + // block entry along with a vector of children and the updates to apply + // to them. + fn apply(self, mut entry: BlockEntry) -> (BlockEntry, Vec<(Hash, ViabilityUpdate)>) { + // 1. When an ancestor has changed from unviable to viable, + // we erase the `earliest_unviable_ancestor` of all descendants + // until encountering a explicitly unviable descendant D. + // + // We then update the `earliest_unviable_ancestor` for all + // descendants of D to be equal to D. + // + // 2. When an ancestor A has changed from viable to unviable, + // we update the `earliest_unviable_ancestor` for all blocks + // to A. + // + // The following algorithm covers both cases. + // + // Furthermore, if there has been any change in viability, + // it is necessary to visit every single descendant of the root + // block. + // + // If a block B was unviable and is now viable, then every descendant + // has an `earliest_unviable_ancestor` which must be updated either + // to nothing or to the new earliest unviable ancestor. + // + // If a block B was viable and is now unviable, then every descendant + // has an `earliest_unviable_ancestor` which needs to be set to B. + + let maybe_earliest_unviable = self.0; + let next_earliest_unviable = { + if maybe_earliest_unviable.is_none() && !entry.viability.is_explicitly_viable() { + Some(entry.block_hash) + } else { + maybe_earliest_unviable + } + }; + entry.viability.earliest_unviable_ancestor = maybe_earliest_unviable; + + let recurse = entry + .children + .iter() + .cloned() + .map(move |c| (c, ViabilityUpdate(next_earliest_unviable))) + .collect(); + + (entry, recurse) + } +} + +// Propagate viability update to descendants of the given block. This writes +// the `base` entry as well as all descendants. If the parent of the block +// entry is not viable, this will not affect any descendants. +// +// If the block entry provided is self-unviable, then it's assumed that an +// unviability update needs to be propagated to descendants. +// +// If the block entry provided is self-viable, then it's assumed that a +// viability update needs to be propagated to descendants. +fn propagate_viability_update( + backend: &mut OverlayedBackend, + base: BlockEntry, +) -> Result<(), Error> { + enum BlockEntryRef { + Explicit(BlockEntry), + Hash(Hash), + } + + if !base.viability.is_parent_viable() { + // If the parent of the block is still unviable, + // then the `earliest_viable_ancestor` will not change + // regardless of the change in the block here. + // + // Furthermore, in such cases, the set of viable leaves + // does not change at all. + backend.write_block_entry(base); + return Ok(()) + } + + let mut viable_leaves = backend.load_leaves()?; + + // A mapping of Block Hash -> number + // Where the hash is the hash of a viable block which has + // at least 1 unviable child. + // + // The number is the number of known unviable children which is known + // as the pivot count. + let mut viability_pivots = HashMap::new(); + + // If the base block is itself explicitly unviable, + // this will change to a `Some(base_hash)` after the first + // invocation. + let viability_update = ViabilityUpdate(None); + + // Recursively apply update to tree. + // + // As we go, we remove any blocks from the leaves which are no longer viable + // leaves. We also add blocks to the leaves-set which are obviously viable leaves. + // And we build up a frontier of blocks which may either be viable leaves or + // the ancestors of one. + let mut tree_frontier = vec![(BlockEntryRef::Explicit(base), viability_update)]; + while let Some((entry_ref, update)) = tree_frontier.pop() { + let entry = match entry_ref { + BlockEntryRef::Explicit(entry) => entry, + BlockEntryRef::Hash(hash) => match backend.load_block_entry(&hash)? { + None => { + gum::warn!( + target: LOG_TARGET, + block_hash = ?hash, + "Missing expected block entry" + ); + + continue + }, + Some(entry) => entry, + }, + }; + + let (new_entry, children) = update.apply(entry); + + if new_entry.viability.is_viable() { + // A block which is viable has a parent which is obviously not + // in the viable leaves set. + viable_leaves.remove(&new_entry.parent_hash); + + // Furthermore, if the block is viable and has no children, + // it is viable by definition. + if new_entry.children.is_empty() { + viable_leaves.insert(new_entry.leaf_entry()); + } + } else { + // A block which is not viable is certainly not a viable leaf. + viable_leaves.remove(&new_entry.block_hash); + + // When the parent is viable but the entry itself is not, that means + // that the parent is a viability pivot. As we visit the children + // of a viability pivot, we build up an exhaustive pivot count. + if new_entry.viability.is_parent_viable() { + *viability_pivots.entry(new_entry.parent_hash).or_insert(0) += 1; + } + } + + backend.write_block_entry(new_entry); + + tree_frontier + .extend(children.into_iter().map(|(h, update)| (BlockEntryRef::Hash(h), update))); + } + + // Revisit the viability pivots now that we've traversed the entire subtree. + // After this point, the viable leaves set is fully updated. A proof follows. + // + // If the base has become unviable, then we've iterated into all descendants, + // made them unviable and removed them from the set. We know that the parent is + // viable as this function is a no-op otherwise, so we need to see if the parent + // has other children or not. + // + // If the base has become viable, then we've iterated into all descendants, + // and found all blocks which are viable and have no children. We've already added + // those blocks to the leaf set, but what we haven't detected + // is blocks which are viable and have children, but all of the children are + // unviable. + // + // The solution of viability pivots addresses both of these: + // + // When the base has become unviable, the parent's viability is unchanged and therefore + // any leaves descending from parent but not base are still in the viable leaves set. + // If the parent has only one child which is the base, the parent is now a viable leaf. + // We've already visited the base in recursive search so the set of pivots should + // contain only a single entry `(parent, 1)`. qed. + // + // When the base has become viable, we've already iterated into every descendant + // of the base and thus have collected a set of pivots whose corresponding pivot + // counts have already been exhaustively computed from their children. qed. + for (pivot, pivot_count) in viability_pivots { + match backend.load_block_entry(&pivot)? { + None => { + // This means the block is finalized. We might reach this + // code path when the base is a child of the finalized block + // and has become unviable. + // + // Each such child is the root of its own tree + // which, as an invariant, does not depend on the viability + // of the finalized block. So no siblings need to be inspected + // and we can ignore it safely. + // + // Furthermore, if the set of viable leaves is empty, the + // finalized block is implicitly the viable leaf. + continue + }, + Some(entry) => + if entry.children.len() == pivot_count { + viable_leaves.insert(entry.leaf_entry()); + }, + } + } + + backend.write_leaves(viable_leaves); + + Ok(()) +} + +/// Imports a new block and applies any reversions to ancestors. +pub(crate) fn import_block( + backend: &mut OverlayedBackend, + block_hash: Hash, + block_number: BlockNumber, + parent_hash: Hash, + reversion_logs: Vec, + weight: BlockWeight, + stagnant_at: Timestamp, +) -> Result<(), Error> { + add_block(backend, block_hash, block_number, parent_hash, weight, stagnant_at)?; + apply_ancestor_reversions(backend, block_hash, block_number, reversion_logs)?; + + Ok(()) +} + +// Load the given ancestor's block entry, in descending order from the `block_hash`. +// The ancestor_number must be at least one block less than the `block_number`. +// +// The returned entry will be `None` if the range is invalid or any block in the path had +// no entry present. If any block entry was missing, it can safely be assumed to +// be finalized. +fn load_ancestor( + backend: &mut OverlayedBackend, + block_hash: Hash, + block_number: BlockNumber, + ancestor_number: BlockNumber, +) -> Result, Error> { + if block_number <= ancestor_number { + return Ok(None) + } + + let mut current_hash = block_hash; + let mut current_entry = None; + + let segment_length = (block_number - ancestor_number) + 1; + for _ in 0..segment_length { + match backend.load_block_entry(¤t_hash)? { + None => return Ok(None), + Some(entry) => { + let parent_hash = entry.parent_hash; + current_entry = Some(entry); + current_hash = parent_hash; + }, + } + } + + // Current entry should always be `Some` here. + Ok(current_entry) +} + +// Add a new block to the tree, which is assumed to be unreverted and unapproved, +// but not stagnant. It inherits viability from its parent, if any. +// +// This updates the parent entry, if any, and updates the viable leaves set accordingly. +// This also schedules a stagnation-check update and adds the block to the blocks-by-number +// mapping. +fn add_block( + backend: &mut OverlayedBackend, + block_hash: Hash, + block_number: BlockNumber, + parent_hash: Hash, + weight: BlockWeight, + stagnant_at: Timestamp, +) -> Result<(), Error> { + let mut leaves = backend.load_leaves()?; + let parent_entry = backend.load_block_entry(&parent_hash)?; + + let inherited_viability = + parent_entry.as_ref().and_then(|parent| parent.non_viable_ancestor_for_child()); + + // 1. Add the block to the DB assuming it's not reverted. + backend.write_block_entry(BlockEntry { + block_hash, + block_number, + parent_hash, + children: Vec::new(), + viability: ViabilityCriteria { + earliest_unviable_ancestor: inherited_viability, + explicitly_reverted: false, + approval: Approval::Unapproved, + }, + weight, + }); + + // 2. Update leaves if inherited viability is fine. + if inherited_viability.is_none() { + leaves.remove(&parent_hash); + leaves.insert(LeafEntry { block_hash, block_number, weight }); + backend.write_leaves(leaves); + } + + // 3. Update and write the parent + if let Some(mut parent_entry) = parent_entry { + parent_entry.children.push(block_hash); + backend.write_block_entry(parent_entry); + } + + // 4. Add to blocks-by-number. + let mut blocks_by_number = backend.load_blocks_by_number(block_number)?; + blocks_by_number.push(block_hash); + backend.write_blocks_by_number(block_number, blocks_by_number); + + // 5. Add stagnation timeout. + let mut stagnant_at_list = backend.load_stagnant_at(stagnant_at)?; + stagnant_at_list.push(block_hash); + backend.write_stagnant_at(stagnant_at, stagnant_at_list); + + Ok(()) +} + +/// Assuming that a block is already imported, accepts the number of the block +/// as well as a list of reversions triggered by the block in ascending order. +fn apply_ancestor_reversions( + backend: &mut OverlayedBackend, + block_hash: Hash, + block_number: BlockNumber, + reversions: Vec, +) -> Result<(), Error> { + // Note: since revert numbers are in ascending order, the expensive propagation + // of unviability is only heavy on the first log. + for revert_number in reversions { + let maybe_block_entry = load_ancestor(backend, block_hash, block_number, revert_number)?; + if let Some(block_entry) = &maybe_block_entry { + gum::trace!( + target: LOG_TARGET, + ?revert_number, + revert_hash = ?block_entry.block_hash, + "Block marked as reverted via scraped on-chain reversions" + ); + } + revert_single_block_entry_if_present( + backend, + maybe_block_entry, + None, + revert_number, + Some(block_hash), + Some(block_number), + )?; + } + + Ok(()) +} + +/// Marks a single block as explicitly reverted, then propagates viability updates +/// to all its children. This is triggered when the disputes subsystem signals that +/// a dispute has concluded against a candidate. +pub(crate) fn apply_single_reversion( + backend: &mut OverlayedBackend, + revert_hash: Hash, + revert_number: BlockNumber, +) -> Result<(), Error> { + gum::trace!( + target: LOG_TARGET, + ?revert_number, + ?revert_hash, + "Block marked as reverted via ChainSelectionMessage::RevertBlocks" + ); + let maybe_block_entry = backend.load_block_entry(&revert_hash)?; + revert_single_block_entry_if_present( + backend, + maybe_block_entry, + Some(revert_hash), + revert_number, + None, + None, + )?; + Ok(()) +} + +fn revert_single_block_entry_if_present( + backend: &mut OverlayedBackend, + maybe_block_entry: Option, + maybe_revert_hash: Option, + revert_number: BlockNumber, + maybe_reporting_hash: Option, + maybe_reporting_number: Option, +) -> Result<(), Error> { + match maybe_block_entry { + None => { + gum::warn!( + target: LOG_TARGET, + ?maybe_revert_hash, + revert_target = revert_number, + ?maybe_reporting_hash, + ?maybe_reporting_number, + "The hammer has dropped. \ + The protocol has indicated that a finalized block be reverted. \ + Please inform an adult.", + ); + }, + Some(mut block_entry) => { + gum::info!( + target: LOG_TARGET, + ?maybe_revert_hash, + revert_target = revert_number, + ?maybe_reporting_hash, + ?maybe_reporting_number, + "Unfinalized block reverted due to a bad parachain block.", + ); + + block_entry.viability.explicitly_reverted = true; + // Marks children of reverted block as non-viable + propagate_viability_update(backend, block_entry)?; + }, + } + Ok(()) +} + +/// Finalize a block with the given number and hash. +/// +/// This will prune all sub-trees not descending from the given block, +/// all block entries at or before the given height, +/// and will update the viability of all sub-trees descending from the given +/// block if the finalized block was not viable. +/// +/// This is assumed to start with a fresh backend, and will produce +/// an overlay over the backend with all the changes applied. +pub(super) fn finalize_block<'a, B: Backend + 'a>( + backend: &'a B, + finalized_hash: Hash, + finalized_number: BlockNumber, +) -> Result, Error> { + let earliest_stored_number = backend.load_first_block_number()?; + let mut backend = OverlayedBackend::new(backend); + + let earliest_stored_number = match earliest_stored_number { + None => { + // This implies that there are no unfinalized blocks and hence nothing + // to update. + return Ok(backend) + }, + Some(e) => e, + }; + + let mut viable_leaves = backend.load_leaves()?; + + // Walk all numbers up to the finalized number and remove those entries. + for number in earliest_stored_number..finalized_number { + let blocks_at = backend.load_blocks_by_number(number)?; + backend.delete_blocks_by_number(number); + + for block in blocks_at { + viable_leaves.remove(&block); + backend.delete_block_entry(&block); + } + } + + // Remove all blocks at the finalized height, with the exception of the finalized block, + // and their descendants, recursively. + { + let blocks_at_finalized_height = backend.load_blocks_by_number(finalized_number)?; + backend.delete_blocks_by_number(finalized_number); + + let mut frontier: Vec<_> = blocks_at_finalized_height + .into_iter() + .filter(|h| h != &finalized_hash) + .map(|h| (h, finalized_number)) + .collect(); + + while let Some((dead_hash, dead_number)) = frontier.pop() { + let entry = backend.load_block_entry(&dead_hash)?; + backend.delete_block_entry(&dead_hash); + viable_leaves.remove(&dead_hash); + + // This does a few extra `clone`s but is unlikely to be + // a bottleneck. Code complexity is very low as a result. + let mut blocks_at_height = backend.load_blocks_by_number(dead_number)?; + blocks_at_height.retain(|h| h != &dead_hash); + backend.write_blocks_by_number(dead_number, blocks_at_height); + + // Add all children to the frontier. + let next_height = dead_number + 1; + frontier.extend(entry.into_iter().flat_map(|e| e.children).map(|h| (h, next_height))); + } + } + + // Visit and remove the finalized block, fetching its children. + let children_of_finalized = { + let finalized_entry = backend.load_block_entry(&finalized_hash)?; + backend.delete_block_entry(&finalized_hash); + viable_leaves.remove(&finalized_hash); + + finalized_entry.into_iter().flat_map(|e| e.children) + }; + + backend.write_leaves(viable_leaves); + + // Update the viability of each child. + for child in children_of_finalized { + if let Some(mut child) = backend.load_block_entry(&child)? { + // Finalized blocks are always viable. + child.viability.earliest_unviable_ancestor = None; + + propagate_viability_update(&mut backend, child)?; + } else { + gum::debug!( + target: LOG_TARGET, + ?finalized_hash, + finalized_number, + child_hash = ?child, + "Missing child of finalized block", + ); + + // No need to do anything, but this is an inconsistent state. + } + } + + Ok(backend) +} + +/// Mark a block as approved and update the viability of itself and its +/// descendants accordingly. +pub(super) fn approve_block( + backend: &mut OverlayedBackend, + approved_hash: Hash, +) -> Result<(), Error> { + if let Some(mut entry) = backend.load_block_entry(&approved_hash)? { + let was_viable = entry.viability.is_viable(); + entry.viability.approval = Approval::Approved; + let is_viable = entry.viability.is_viable(); + + // Approval can change the viability in only one direction. + // If the viability has changed, then we propagate that to children + // and recalculate the viable leaf set. + if !was_viable && is_viable { + propagate_viability_update(backend, entry)?; + } else { + backend.write_block_entry(entry); + } + } else { + gum::debug!( + target: LOG_TARGET, + block_hash = ?approved_hash, + "Missing entry for freshly-approved block. Ignoring" + ); + } + + Ok(()) +} + +/// Check whether any blocks up to the given timestamp are stagnant and update +/// accordingly. +/// +/// This accepts a fresh backend and returns an overlay on top of it representing +/// all changes made. +pub(super) fn detect_stagnant<'a, B: 'a + Backend>( + backend: &'a B, + up_to: Timestamp, + max_elements: usize, +) -> Result, Error> { + let stagnant_up_to = backend.load_stagnant_at_up_to(up_to, max_elements)?; + let mut backend = OverlayedBackend::new(backend); + + let (min_ts, max_ts) = match stagnant_up_to.len() { + 0 => (0 as Timestamp, 0 as Timestamp), + 1 => (stagnant_up_to[0].0, stagnant_up_to[0].0), + n => (stagnant_up_to[0].0, stagnant_up_to[n - 1].0), + }; + + // As this is in ascending order, only the earliest stagnant + // blocks will involve heavy viability propagations. + gum::debug!( + target: LOG_TARGET, + ?up_to, + ?min_ts, + ?max_ts, + "Prepared {} stagnant entries for checking/pruning", + stagnant_up_to.len() + ); + + for (timestamp, maybe_stagnant) in stagnant_up_to { + backend.delete_stagnant_at(timestamp); + + for block_hash in maybe_stagnant { + if let Some(mut entry) = backend.load_block_entry(&block_hash)? { + let was_viable = entry.viability.is_viable(); + if let Approval::Unapproved = entry.viability.approval { + entry.viability.approval = Approval::Stagnant; + } + let is_viable = entry.viability.is_viable(); + gum::trace!( + target: LOG_TARGET, + ?block_hash, + ?timestamp, + ?was_viable, + ?is_viable, + "Found existing stagnant entry" + ); + + if was_viable && !is_viable { + propagate_viability_update(&mut backend, entry)?; + } else { + backend.write_block_entry(entry); + } + } else { + gum::trace!( + target: LOG_TARGET, + ?block_hash, + ?timestamp, + "Found non-existing stagnant entry" + ); + } + } + } + + Ok(backend) +} + +/// Prune stagnant entries at some timestamp without other checks +/// This function is intended just to clean leftover entries when the real +/// stagnant checks are disabled +pub(super) fn prune_only_stagnant<'a, B: 'a + Backend>( + backend: &'a B, + up_to: Timestamp, + max_elements: usize, +) -> Result, Error> { + let stagnant_up_to = backend.load_stagnant_at_up_to(up_to, max_elements)?; + let mut backend = OverlayedBackend::new(backend); + + let (min_ts, max_ts) = match stagnant_up_to.len() { + 0 => (0 as Timestamp, 0 as Timestamp), + 1 => (stagnant_up_to[0].0, stagnant_up_to[0].0), + n => (stagnant_up_to[0].0, stagnant_up_to[n - 1].0), + }; + + gum::debug!( + target: LOG_TARGET, + ?up_to, + ?min_ts, + ?max_ts, + "Prepared {} stagnant entries for pruning", + stagnant_up_to.len() + ); + + for (timestamp, _) in stagnant_up_to { + backend.delete_stagnant_at(timestamp); + } + + Ok(backend) +} + +/// Revert the tree to the block relative to `hash`. +/// +/// This accepts a fresh backend and returns an overlay on top of it representing +/// all changes made. +pub(super) fn revert_to<'a, B: Backend + 'a>( + backend: &'a B, + hash: Hash, +) -> Result, Error> { + let first_number = backend.load_first_block_number()?.unwrap_or_default(); + + let mut backend = OverlayedBackend::new(backend); + + let mut entry = match backend.load_block_entry(&hash)? { + Some(entry) => entry, + None => { + // May be a revert to the last finalized block. If this is the case, + // then revert to this block should be handled specially since no + // information about finalized blocks is persisted within the tree. + // + // We use part of the information contained in the finalized block + // children (that are expected to be in the tree) to construct a + // dummy block entry for the last finalized block. This will be + // wiped as soon as the next block is finalized. + + let blocks = backend.load_blocks_by_number(first_number)?; + + let block = blocks + .first() + .and_then(|hash| backend.load_block_entry(hash).ok()) + .flatten() + .ok_or_else(|| { + ChainApiError::from(format!( + "Lookup failure for block at height {}", + first_number + )) + })?; + + // The parent is expected to be the last finalized block. + if block.parent_hash != hash { + return Err(ChainApiError::from("Can't revert below last finalized block").into()) + } + + // The weight is set to the one of the first child. Even though this is + // not accurate, it does the job. The reason is that the revert point is + // the last finalized block, i.e. this is the best and only choice. + let block_number = first_number.saturating_sub(1); + let viability = ViabilityCriteria { + explicitly_reverted: false, + approval: Approval::Approved, + earliest_unviable_ancestor: None, + }; + let entry = BlockEntry { + block_hash: hash, + block_number, + parent_hash: Hash::default(), + children: blocks, + viability, + weight: block.weight, + }; + // This becomes the first entry according to the block number. + backend.write_blocks_by_number(block_number, vec![hash]); + entry + }, + }; + + let mut stack: Vec<_> = std::mem::take(&mut entry.children) + .into_iter() + .map(|h| (h, entry.block_number + 1)) + .collect(); + + // Write revert point block entry without the children. + backend.write_block_entry(entry.clone()); + + let mut viable_leaves = backend.load_leaves()?; + + viable_leaves.insert(LeafEntry { + block_hash: hash, + block_number: entry.block_number, + weight: entry.weight, + }); + + while let Some((hash, number)) = stack.pop() { + let entry = backend.load_block_entry(&hash)?; + backend.delete_block_entry(&hash); + + viable_leaves.remove(&hash); + + let mut blocks_at_height = backend.load_blocks_by_number(number)?; + blocks_at_height.retain(|h| h != &hash); + backend.write_blocks_by_number(number, blocks_at_height); + + stack.extend(entry.into_iter().flat_map(|e| e.children).map(|h| (h, number + 1))); + } + + backend.write_leaves(viable_leaves); + + Ok(backend) +} diff --git a/polkadot/node/core/dispute-coordinator/Cargo.toml b/polkadot/node/core/dispute-coordinator/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..e4069f7f3330eeef56c08cc8256179f63f67bb63 --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "polkadot-node-core-dispute-coordinator" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +gum = { package = "tracing-gum", path = "../../gum" } +parity-scale-codec = "3.6.1" +kvdb = "0.13.0" +thiserror = "1.0.31" +lru = "0.11.0" +fatality = "0.0.6" + +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } + +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } + + +[dev-dependencies] +kvdb-memorydb = "0.13.0" +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +assert_matches = "1.4.0" +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../../primitives/test-helpers" } +futures-timer = "3.0.2" +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +# If not enabled, the dispute coordinator will do nothing. +disputes = [] diff --git a/polkadot/node/core/dispute-coordinator/src/backend.rs b/polkadot/node/core/dispute-coordinator/src/backend.rs new file mode 100644 index 0000000000000000000000000000000000000000..cf0bdd4043ca253b75e402564d7a24ecbbeeaa6f --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/backend.rs @@ -0,0 +1,171 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! An abstraction over storage used by the chain selection subsystem. +//! +//! This provides both a [`Backend`] trait and an [`OverlayedBackend`] +//! struct which allows in-memory changes to be applied on top of a +//! [`Backend`], maintaining consistency between queries and temporary writes, +//! before any commit to the underlying storage is made. + +use polkadot_primitives::{CandidateHash, SessionIndex}; + +use std::collections::HashMap; + +use super::db::v1::{CandidateVotes, RecentDisputes}; +use crate::error::FatalResult; + +#[derive(Debug)] +pub enum BackendWriteOp { + WriteEarliestSession(SessionIndex), + WriteRecentDisputes(RecentDisputes), + WriteCandidateVotes(SessionIndex, CandidateHash, CandidateVotes), + DeleteCandidateVotes(SessionIndex, CandidateHash), +} + +/// An abstraction over backend storage for the logic of this subsystem. +pub trait Backend { + /// Load the earliest session, if any. + fn load_earliest_session(&self) -> FatalResult>; + + /// Load the recent disputes, if any. + fn load_recent_disputes(&self) -> FatalResult>; + + /// Load the candidate votes for the specific session-candidate pair, if any. + fn load_candidate_votes( + &self, + session: SessionIndex, + candidate_hash: &CandidateHash, + ) -> FatalResult>; + + /// Atomically writes the list of operations, with later operations taking precedence over + /// prior. + fn write(&mut self, ops: I) -> FatalResult<()> + where + I: IntoIterator; +} + +/// An in-memory overlay for the backend. +/// +/// This maintains read-only access to the underlying backend, but can be converted into a set of +/// write operations which will, when written to the underlying backend, give the same view as the +/// state of the overlay. +pub struct OverlayedBackend<'a, B: 'a> { + inner: &'a B, + + // `None` means unchanged. + earliest_session: Option, + // `None` means unchanged. + recent_disputes: Option, + // `None` means deleted, missing means query inner. + candidate_votes: HashMap<(SessionIndex, CandidateHash), Option>, +} + +impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> { + pub fn new(backend: &'a B) -> Self { + Self { + inner: backend, + earliest_session: None, + recent_disputes: None, + candidate_votes: HashMap::new(), + } + } + + /// Returns true if the are no write operations to perform. + pub fn is_empty(&self) -> bool { + self.earliest_session.is_none() && + self.recent_disputes.is_none() && + self.candidate_votes.is_empty() + } + + /// Load the earliest session, if any. + pub fn load_earliest_session(&self) -> FatalResult> { + if let Some(val) = self.earliest_session { + return Ok(Some(val)) + } + + self.inner.load_earliest_session() + } + + /// Load the recent disputes, if any. + pub fn load_recent_disputes(&self) -> FatalResult> { + if let Some(val) = &self.recent_disputes { + return Ok(Some(val.clone())) + } + + self.inner.load_recent_disputes() + } + + /// Load the candidate votes for the specific session-candidate pair, if any. + pub fn load_candidate_votes( + &self, + session: SessionIndex, + candidate_hash: &CandidateHash, + ) -> FatalResult> { + if let Some(val) = self.candidate_votes.get(&(session, *candidate_hash)) { + return Ok(val.clone()) + } + + self.inner.load_candidate_votes(session, candidate_hash) + } + + /// Prepare a write to the "earliest session" field of the DB. + /// + /// Later calls to this function will override earlier ones. + pub fn write_earliest_session(&mut self, session: SessionIndex) { + self.earliest_session = Some(session); + } + + /// Prepare a write to the recent disputes stored in the DB. + /// + /// Later calls to this function will override earlier ones. + pub fn write_recent_disputes(&mut self, recent_disputes: RecentDisputes) { + self.recent_disputes = Some(recent_disputes) + } + + /// Prepare a write of the candidate votes under the indicated candidate. + /// + /// Later calls to this function for the same candidate will override earlier ones. + pub fn write_candidate_votes( + &mut self, + session: SessionIndex, + candidate_hash: CandidateHash, + votes: CandidateVotes, + ) { + self.candidate_votes.insert((session, candidate_hash), Some(votes)); + } + + /// Transform this backend into a set of write-ops to be written to the inner backend. + pub fn into_write_ops(self) -> impl Iterator { + let earliest_session_ops = self + .earliest_session + .map(|s| BackendWriteOp::WriteEarliestSession(s)) + .into_iter(); + + let recent_dispute_ops = + self.recent_disputes.map(|d| BackendWriteOp::WriteRecentDisputes(d)).into_iter(); + + let candidate_vote_ops = + self.candidate_votes + .into_iter() + .map(|((session, candidate), votes)| match votes { + Some(votes) => BackendWriteOp::WriteCandidateVotes(session, candidate, votes), + None => BackendWriteOp::DeleteCandidateVotes(session, candidate), + }); + + earliest_session_ops.chain(recent_dispute_ops).chain(candidate_vote_ops) + } +} diff --git a/polkadot/node/core/dispute-coordinator/src/db/mod.rs b/polkadot/node/core/dispute-coordinator/src/db/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..87102c5a3c4888ffe32f378635b50599ccfa63ff --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/db/mod.rs @@ -0,0 +1,19 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Database component for the dispute coordinator. + +pub(super) mod v1; diff --git a/polkadot/node/core/dispute-coordinator/src/db/v1.rs b/polkadot/node/core/dispute-coordinator/src/db/v1.rs new file mode 100644 index 0000000000000000000000000000000000000000..f0f17d2325d68bb1d70f40a2a761bdf5f35ebcfb --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/db/v1.rs @@ -0,0 +1,687 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! `V1` database for the dispute coordinator. +//! +//! Note that the version here differs from the actual version of the parachains +//! database (check `CURRENT_VERSION` in `node/service/src/parachains_db/upgrade.rs`). +//! The code in this module implements the way dispute coordinator works with +//! the dispute data in the database. Any breaking changes here will still +//! require a db migration (check `node/service/src/parachains_db/upgrade.rs`). + +use polkadot_node_primitives::DisputeStatus; +use polkadot_node_subsystem_util::database::{DBTransaction, Database}; +use polkadot_primitives::{ + CandidateHash, CandidateReceipt, Hash, InvalidDisputeStatementKind, SessionIndex, + ValidDisputeStatementKind, ValidatorIndex, ValidatorSignature, +}; + +use std::sync::Arc; + +use parity_scale_codec::{Decode, Encode}; + +use crate::{ + backend::{Backend, BackendWriteOp, OverlayedBackend}, + error::{FatalError, FatalResult}, + metrics::Metrics, + LOG_TARGET, +}; + +const RECENT_DISPUTES_KEY: &[u8; 15] = b"recent-disputes"; +const EARLIEST_SESSION_KEY: &[u8; 16] = b"earliest-session"; +const CANDIDATE_VOTES_SUBKEY: &[u8; 15] = b"candidate-votes"; +/// Until what session have votes been cleaned up already? +const CLEANED_VOTES_WATERMARK_KEY: &[u8; 23] = b"cleaned-votes-watermark"; + +/// Restrict number of cleanup operations. +/// +/// On the first run we are starting at session 0 going up all the way to the current session - +/// this should not be done at once, but rather in smaller batches so nodes won't get stalled by +/// this. +/// +/// 300 is with session duration of 1 hour and 30 parachains around <3_000_000 key purges in the +/// worst case. Which is already quite a lot, at the same time we have around 21_000 sessions on +/// Kusama. This means at 300 purged sessions per session, cleaning everything up will take +/// around 3 days. Depending on how severe disk usage becomes, we might want to bump the batch +/// size, at the cost of risking issues at session boundaries (performance). +#[cfg(test)] +const MAX_CLEAN_BATCH_SIZE: u32 = 10; +#[cfg(not(test))] +const MAX_CLEAN_BATCH_SIZE: u32 = 300; + +pub struct DbBackend { + inner: Arc, + config: ColumnConfiguration, + metrics: Metrics, +} + +impl DbBackend { + pub fn new(db: Arc, config: ColumnConfiguration, metrics: Metrics) -> Self { + Self { inner: db, config, metrics } + } + + /// Cleanup old votes. + /// + /// Should be called whenever a new earliest session gets written. + fn add_vote_cleanup_tx( + &mut self, + tx: &mut DBTransaction, + earliest_session: SessionIndex, + ) -> FatalResult<()> { + // Cleanup old votes in db: + let watermark = load_cleaned_votes_watermark(&*self.inner, &self.config)?.unwrap_or(0); + let clean_until = if earliest_session.saturating_sub(watermark) > MAX_CLEAN_BATCH_SIZE { + watermark + MAX_CLEAN_BATCH_SIZE + } else { + earliest_session + }; + gum::trace!( + target: LOG_TARGET, + ?watermark, + ?clean_until, + ?earliest_session, + ?MAX_CLEAN_BATCH_SIZE, + "WriteEarliestSession" + ); + + for index in watermark..clean_until { + gum::trace!( + target: LOG_TARGET, + ?index, + encoded = ?candidate_votes_session_prefix(index), + "Cleaning votes for session index" + ); + tx.delete_prefix(self.config.col_dispute_data, &candidate_votes_session_prefix(index)); + } + // New watermark: + tx.put_vec(self.config.col_dispute_data, CLEANED_VOTES_WATERMARK_KEY, clean_until.encode()); + Ok(()) + } +} + +impl Backend for DbBackend { + /// Load the earliest session, if any. + fn load_earliest_session(&self) -> FatalResult> { + load_earliest_session(&*self.inner, &self.config) + } + + /// Load the recent disputes, if any. + fn load_recent_disputes(&self) -> FatalResult> { + load_recent_disputes(&*self.inner, &self.config) + } + + /// Load the candidate votes for the specific session-candidate pair, if any. + fn load_candidate_votes( + &self, + session: SessionIndex, + candidate_hash: &CandidateHash, + ) -> FatalResult> { + load_candidate_votes(&*self.inner, &self.config, session, candidate_hash) + } + + /// Atomically writes the list of operations, with later operations taking precedence over + /// prior. + /// + /// This also takes care of purging old votes (of obsolete sessions). + fn write(&mut self, ops: I) -> FatalResult<()> + where + I: IntoIterator, + { + let mut tx = DBTransaction::new(); + // Make sure the whole process is timed, including the actual transaction flush: + let mut cleanup_timer = None; + for op in ops { + match op { + BackendWriteOp::WriteEarliestSession(session) => { + cleanup_timer = match cleanup_timer.take() { + None => Some(self.metrics.time_vote_cleanup()), + Some(t) => Some(t), + }; + self.add_vote_cleanup_tx(&mut tx, session)?; + + // Actually write the earliest session. + tx.put_vec( + self.config.col_dispute_data, + EARLIEST_SESSION_KEY, + session.encode(), + ); + }, + BackendWriteOp::WriteRecentDisputes(recent_disputes) => { + tx.put_vec( + self.config.col_dispute_data, + RECENT_DISPUTES_KEY, + recent_disputes.encode(), + ); + }, + BackendWriteOp::WriteCandidateVotes(session, candidate_hash, votes) => { + gum::trace!(target: LOG_TARGET, ?session, "Writing candidate votes"); + tx.put_vec( + self.config.col_dispute_data, + &candidate_votes_key(session, &candidate_hash), + votes.encode(), + ); + }, + BackendWriteOp::DeleteCandidateVotes(session, candidate_hash) => { + tx.delete( + self.config.col_dispute_data, + &candidate_votes_key(session, &candidate_hash), + ); + }, + } + } + + self.inner.write(tx).map_err(FatalError::DbWriteFailed) + } +} + +fn candidate_votes_key(session: SessionIndex, candidate_hash: &CandidateHash) -> [u8; 15 + 4 + 32] { + let mut buf = [0u8; 15 + 4 + 32]; + buf[..15].copy_from_slice(CANDIDATE_VOTES_SUBKEY); + + // big-endian encoding is used to ensure lexicographic ordering. + buf[15..][..4].copy_from_slice(&session.to_be_bytes()); + candidate_hash.using_encoded(|s| buf[(15 + 4)..].copy_from_slice(s)); + + buf +} + +fn candidate_votes_session_prefix(session: SessionIndex) -> [u8; 15 + 4] { + let mut buf = [0u8; 15 + 4]; + buf[..15].copy_from_slice(CANDIDATE_VOTES_SUBKEY); + + // big-endian encoding is used to ensure lexicographic ordering. + buf[15..][..4].copy_from_slice(&session.to_be_bytes()); + buf +} + +/// Column configuration information for the DB. +#[derive(Debug, Clone)] +pub struct ColumnConfiguration { + /// The column in the key-value DB where data is stored. + pub col_dispute_data: u32, +} + +/// Tracked votes on candidates, for the purposes of dispute resolution. +#[derive(Debug, Clone, Encode, Decode)] +pub struct CandidateVotes { + /// The receipt of the candidate itself. + pub candidate_receipt: CandidateReceipt, + /// Votes of validity, sorted by validator index. + pub valid: Vec<(ValidDisputeStatementKind, ValidatorIndex, ValidatorSignature)>, + /// Votes of invalidity, sorted by validator index. + pub invalid: Vec<(InvalidDisputeStatementKind, ValidatorIndex, ValidatorSignature)>, +} + +impl From for polkadot_node_primitives::CandidateVotes { + fn from(db_votes: CandidateVotes) -> polkadot_node_primitives::CandidateVotes { + polkadot_node_primitives::CandidateVotes { + candidate_receipt: db_votes.candidate_receipt, + valid: db_votes.valid.into_iter().map(|(kind, i, sig)| (i, (kind, sig))).collect(), + invalid: db_votes.invalid.into_iter().map(|(kind, i, sig)| (i, (kind, sig))).collect(), + } + } +} + +impl From for CandidateVotes { + fn from(primitive_votes: polkadot_node_primitives::CandidateVotes) -> CandidateVotes { + CandidateVotes { + candidate_receipt: primitive_votes.candidate_receipt, + valid: primitive_votes + .valid + .into_iter() + .map(|(i, (kind, sig))| (kind, i, sig)) + .collect(), + invalid: primitive_votes.invalid.into_iter().map(|(i, (k, sig))| (k, i, sig)).collect(), + } + } +} + +/// The mapping for recent disputes; any which have not yet been pruned for being ancient. +pub type RecentDisputes = std::collections::BTreeMap<(SessionIndex, CandidateHash), DisputeStatus>; + +/// Errors while accessing things from the DB. +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error(transparent)] + Io(#[from] std::io::Error), + #[error(transparent)] + Codec(#[from] parity_scale_codec::Error), +} + +impl From for crate::error::Error { + fn from(err: Error) -> Self { + match err { + Error::Io(io) => Self::Io(io), + Error::Codec(e) => Self::Codec(e), + } + } +} + +/// Result alias for DB errors. +pub type Result = std::result::Result; + +fn load_decode( + db: &dyn Database, + col_dispute_data: u32, + key: &[u8], +) -> Result> { + match db.get(col_dispute_data, key)? { + None => Ok(None), + Some(raw) => D::decode(&mut &raw[..]).map(Some).map_err(Into::into), + } +} + +/// Load the candidate votes for the specific session-candidate pair, if any. +pub(crate) fn load_candidate_votes( + db: &dyn Database, + config: &ColumnConfiguration, + session: SessionIndex, + candidate_hash: &CandidateHash, +) -> FatalResult> { + load_decode(db, config.col_dispute_data, &candidate_votes_key(session, candidate_hash)) + .map_err(|e| FatalError::DbReadFailed(e)) +} + +/// Load the earliest session, if any. +pub(crate) fn load_earliest_session( + db: &dyn Database, + config: &ColumnConfiguration, +) -> FatalResult> { + load_decode(db, config.col_dispute_data, EARLIEST_SESSION_KEY) + .map_err(|e| FatalError::DbReadFailed(e)) +} + +/// Load the recent disputes, if any. +pub(crate) fn load_recent_disputes( + db: &dyn Database, + config: &ColumnConfiguration, +) -> FatalResult> { + load_decode(db, config.col_dispute_data, RECENT_DISPUTES_KEY) + .map_err(|e| FatalError::DbReadFailed(e)) +} + +/// Maybe prune data in the DB based on the provided session index. +/// +/// This is intended to be called on every block, and as such will be used to populate the DB on +/// first launch. If the on-disk data does not need to be pruned, only a single storage read +/// will be performed. +/// +/// If one or more ancient sessions are pruned, all metadata on candidates within the ancient +/// session will be deleted. +pub(crate) fn note_earliest_session( + overlay_db: &mut OverlayedBackend<'_, impl Backend>, + new_earliest_session: SessionIndex, +) -> FatalResult<()> { + match overlay_db.load_earliest_session()? { + None => { + // First launch - write new-earliest. + overlay_db.write_earliest_session(new_earliest_session); + }, + Some(prev_earliest) if new_earliest_session > prev_earliest => { + // Prune all data in the outdated sessions. + overlay_db.write_earliest_session(new_earliest_session); + + // Clear recent disputes metadata. + { + let mut recent_disputes = overlay_db.load_recent_disputes()?.unwrap_or_default(); + + let lower_bound = (new_earliest_session, CandidateHash(Hash::repeat_byte(0x00))); + + let new_recent_disputes = recent_disputes.split_off(&lower_bound); + // Any remanining disputes are considered ancient and must be pruned. + let pruned_disputes = recent_disputes; + + if pruned_disputes.len() != 0 { + overlay_db.write_recent_disputes(new_recent_disputes); + // Note: Deleting old candidate votes is handled in `write` based on the + // earliest session. + } + } + }, + Some(_) => { + // nothing to do. + }, + } + + Ok(()) +} + +/// Until what session votes have been cleaned up already. +/// +/// That is the db has already been purged of votes for sessions older than the returned +/// `SessionIndex`. +fn load_cleaned_votes_watermark( + db: &dyn Database, + config: &ColumnConfiguration, +) -> FatalResult> { + load_decode(db, config.col_dispute_data, CLEANED_VOTES_WATERMARK_KEY) + .map_err(|e| FatalError::DbReadFailed(e)) +} + +#[cfg(test)] +mod tests { + + use super::*; + use ::test_helpers::{dummy_candidate_receipt, dummy_hash}; + use polkadot_node_primitives::DISPUTE_WINDOW; + use polkadot_primitives::{Hash, Id as ParaId}; + + fn make_db() -> DbBackend { + let db = kvdb_memorydb::create(1); + let db = polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter::new(db, &[0]); + let store = Arc::new(db); + let config = ColumnConfiguration { col_dispute_data: 0 }; + DbBackend::new(store, config, Metrics::default()) + } + + #[test] + fn max_clean_batch_size_is_honored() { + let mut backend = make_db(); + + let mut overlay_db = OverlayedBackend::new(&backend); + let current_session = MAX_CLEAN_BATCH_SIZE + DISPUTE_WINDOW.get() + 3; + let earliest_session = current_session - DISPUTE_WINDOW.get(); + + overlay_db.write_earliest_session(0); + let candidate_hash = CandidateHash(Hash::repeat_byte(1)); + + for session in 0..current_session + 1 { + overlay_db.write_candidate_votes( + session, + candidate_hash, + CandidateVotes { + candidate_receipt: dummy_candidate_receipt(dummy_hash()), + valid: Vec::new(), + invalid: Vec::new(), + }, + ); + } + assert!(overlay_db.load_candidate_votes(0, &candidate_hash).unwrap().is_some()); + assert!(overlay_db + .load_candidate_votes(MAX_CLEAN_BATCH_SIZE - 1, &candidate_hash) + .unwrap() + .is_some()); + assert!(overlay_db + .load_candidate_votes(MAX_CLEAN_BATCH_SIZE, &candidate_hash) + .unwrap() + .is_some()); + + // Cleanup only works for votes that have been written already - so write. + let write_ops = overlay_db.into_write_ops(); + backend.write(write_ops).unwrap(); + + let mut overlay_db = OverlayedBackend::new(&backend); + + gum::trace!(target: LOG_TARGET, ?current_session, "Noting current session"); + note_earliest_session(&mut overlay_db, earliest_session).unwrap(); + + let write_ops = overlay_db.into_write_ops(); + backend.write(write_ops).unwrap(); + + let mut overlay_db = OverlayedBackend::new(&backend); + + assert!(overlay_db + .load_candidate_votes(MAX_CLEAN_BATCH_SIZE - 1, &candidate_hash) + .unwrap() + .is_none()); + // After batch size votes should still be there: + assert!(overlay_db + .load_candidate_votes(MAX_CLEAN_BATCH_SIZE, &candidate_hash) + .unwrap() + .is_some()); + + let current_session = current_session + 1; + let earliest_session = earliest_session + 1; + + note_earliest_session(&mut overlay_db, earliest_session).unwrap(); + + let write_ops = overlay_db.into_write_ops(); + backend.write(write_ops).unwrap(); + + let overlay_db = OverlayedBackend::new(&backend); + + // All should be gone now: + assert!(overlay_db + .load_candidate_votes(earliest_session - 1, &candidate_hash) + .unwrap() + .is_none()); + // Earliest session should still be there: + assert!(overlay_db + .load_candidate_votes(earliest_session, &candidate_hash) + .unwrap() + .is_some()); + // Old current session should still be there as well: + assert!(overlay_db + .load_candidate_votes(current_session - 1, &candidate_hash) + .unwrap() + .is_some()); + } + + #[test] + fn overlay_pre_and_post_commit_consistency() { + let mut backend = make_db(); + + let mut overlay_db = OverlayedBackend::new(&backend); + + overlay_db.write_earliest_session(0); + overlay_db.write_earliest_session(1); + + overlay_db.write_recent_disputes( + vec![((0, CandidateHash(Hash::repeat_byte(0))), DisputeStatus::Active)] + .into_iter() + .collect(), + ); + + overlay_db.write_recent_disputes( + vec![((1, CandidateHash(Hash::repeat_byte(1))), DisputeStatus::Active)] + .into_iter() + .collect(), + ); + + overlay_db.write_candidate_votes( + 1, + CandidateHash(Hash::repeat_byte(1)), + CandidateVotes { + candidate_receipt: dummy_candidate_receipt(dummy_hash()), + valid: Vec::new(), + invalid: Vec::new(), + }, + ); + overlay_db.write_candidate_votes( + 1, + CandidateHash(Hash::repeat_byte(1)), + CandidateVotes { + candidate_receipt: { + let mut receipt = dummy_candidate_receipt(dummy_hash()); + receipt.descriptor.para_id = ParaId::from(5_u32); + + receipt + }, + valid: Vec::new(), + invalid: Vec::new(), + }, + ); + + // Test that overlay returns the correct values before committing. + assert_eq!(overlay_db.load_earliest_session().unwrap().unwrap(), 1); + + assert_eq!( + overlay_db.load_recent_disputes().unwrap().unwrap(), + vec![((1, CandidateHash(Hash::repeat_byte(1))), DisputeStatus::Active),] + .into_iter() + .collect() + ); + + assert_eq!( + overlay_db + .load_candidate_votes(1, &CandidateHash(Hash::repeat_byte(1))) + .unwrap() + .unwrap() + .candidate_receipt + .descriptor + .para_id, + ParaId::from(5), + ); + + let write_ops = overlay_db.into_write_ops(); + backend.write(write_ops).unwrap(); + + // Test that subsequent writes were written. + assert_eq!(backend.load_earliest_session().unwrap().unwrap(), 1); + + assert_eq!( + backend.load_recent_disputes().unwrap().unwrap(), + vec![((1, CandidateHash(Hash::repeat_byte(1))), DisputeStatus::Active),] + .into_iter() + .collect() + ); + + assert_eq!( + backend + .load_candidate_votes(1, &CandidateHash(Hash::repeat_byte(1))) + .unwrap() + .unwrap() + .candidate_receipt + .descriptor + .para_id, + ParaId::from(5), + ); + } + + #[test] + fn overlay_preserves_candidate_votes_operation_order() { + let mut backend = make_db(); + + let mut overlay_db = OverlayedBackend::new(&backend); + + overlay_db.write_candidate_votes( + 1, + CandidateHash(Hash::repeat_byte(1)), + CandidateVotes { + candidate_receipt: dummy_candidate_receipt(Hash::random()), + valid: Vec::new(), + invalid: Vec::new(), + }, + ); + + let receipt = dummy_candidate_receipt(dummy_hash()); + + overlay_db.write_candidate_votes( + 1, + CandidateHash(Hash::repeat_byte(1)), + CandidateVotes { + candidate_receipt: receipt.clone(), + valid: Vec::new(), + invalid: Vec::new(), + }, + ); + + let write_ops = overlay_db.into_write_ops(); + backend.write(write_ops).unwrap(); + + assert_eq!( + backend + .load_candidate_votes(1, &CandidateHash(Hash::repeat_byte(1))) + .unwrap() + .unwrap() + .candidate_receipt, + receipt, + ); + } + + #[test] + fn note_earliest_session_prunes_old() { + let mut backend = make_db(); + + let hash_a = CandidateHash(Hash::repeat_byte(0x0a)); + let hash_b = CandidateHash(Hash::repeat_byte(0x0b)); + let hash_c = CandidateHash(Hash::repeat_byte(0x0c)); + let hash_d = CandidateHash(Hash::repeat_byte(0x0d)); + + let prev_earliest_session = 0; + let new_earliest_session = 5; + let current_session = 5 + DISPUTE_WINDOW.get(); + + let super_old_no_dispute = 1; + let very_old = 3; + let slightly_old = 4; + let very_recent = current_session - 1; + + let blank_candidate_votes = || CandidateVotes { + candidate_receipt: dummy_candidate_receipt(dummy_hash()), + valid: Vec::new(), + invalid: Vec::new(), + }; + + let mut overlay_db = OverlayedBackend::new(&backend); + overlay_db.write_earliest_session(prev_earliest_session); + overlay_db.write_recent_disputes( + vec![ + ((very_old, hash_a), DisputeStatus::Active), + ((slightly_old, hash_b), DisputeStatus::Active), + ((new_earliest_session, hash_c), DisputeStatus::Active), + ((very_recent, hash_d), DisputeStatus::Active), + ] + .into_iter() + .collect(), + ); + + overlay_db.write_candidate_votes(super_old_no_dispute, hash_a, blank_candidate_votes()); + overlay_db.write_candidate_votes(very_old, hash_a, blank_candidate_votes()); + + overlay_db.write_candidate_votes(slightly_old, hash_b, blank_candidate_votes()); + + overlay_db.write_candidate_votes(new_earliest_session, hash_c, blank_candidate_votes()); + + overlay_db.write_candidate_votes(very_recent, hash_d, blank_candidate_votes()); + + let write_ops = overlay_db.into_write_ops(); + backend.write(write_ops).unwrap(); + + let mut overlay_db = OverlayedBackend::new(&backend); + note_earliest_session(&mut overlay_db, new_earliest_session).unwrap(); + + assert_eq!(overlay_db.load_earliest_session().unwrap(), Some(new_earliest_session)); + + assert_eq!( + overlay_db.load_recent_disputes().unwrap().unwrap(), + vec![ + ((new_earliest_session, hash_c), DisputeStatus::Active), + ((very_recent, hash_d), DisputeStatus::Active), + ] + .into_iter() + .collect(), + ); + + // Votes are only cleaned up after actual write: + let write_ops = overlay_db.into_write_ops(); + backend.write(write_ops).unwrap(); + + let overlay_db = OverlayedBackend::new(&backend); + + assert!(overlay_db + .load_candidate_votes(super_old_no_dispute, &hash_a) + .unwrap() + .is_none()); + assert!(overlay_db.load_candidate_votes(very_old, &hash_a).unwrap().is_none()); + assert!(overlay_db.load_candidate_votes(slightly_old, &hash_b).unwrap().is_none()); + assert!(overlay_db + .load_candidate_votes(new_earliest_session, &hash_c) + .unwrap() + .is_some()); + assert!(overlay_db.load_candidate_votes(very_recent, &hash_d).unwrap().is_some()); + } +} diff --git a/polkadot/node/core/dispute-coordinator/src/error.rs b/polkadot/node/core/dispute-coordinator/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..cbda3dc1d121a622f38848d32afb389d82e01ed9 --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/error.rs @@ -0,0 +1,132 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use fatality::Nested; +use futures::channel::oneshot; + +use polkadot_node_subsystem::{errors::ChainApiError, SubsystemError}; +use polkadot_node_subsystem_util::runtime; + +use crate::{db, participation, LOG_TARGET}; +use parity_scale_codec::Error as CodecError; + +pub type Result = std::result::Result; +pub type FatalResult = std::result::Result; +pub type JfyiResult = std::result::Result; + +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + /// We received a legacy `SubystemError::Context` error which is considered fatal. + #[fatal] + #[error("SubsystemError::Context error: {0}")] + SubsystemContext(String), + + /// `ctx.spawn` failed with an error. + #[fatal] + #[error("Spawning a task failed: {0}")] + SpawnFailed(#[source] SubsystemError), + + #[fatal] + #[error("Participation worker receiver exhausted.")] + ParticipationWorkerReceiverExhausted, + + /// Receiving subsystem message from overseer failed. + #[fatal] + #[error("Receiving message from overseer failed: {0}")] + SubsystemReceive(#[source] SubsystemError), + + #[fatal] + #[error("Writing to database failed: {0}")] + DbWriteFailed(std::io::Error), + + #[fatal] + #[error("Reading from database failed: {0}")] + DbReadFailed(db::v1::Error), + + #[fatal] + #[error("Oneshot for receiving block number from chain API got cancelled")] + CanceledBlockNumber, + + #[fatal] + #[error("Retrieving block number from chain API failed with error: {0}")] + ChainApiBlockNumber(ChainApiError), + + #[fatal] + #[error(transparent)] + ChainApiAncestors(ChainApiError), + + #[fatal] + #[error("Chain API dropped response channel sender")] + ChainApiSenderDropped, + + #[fatal(forward)] + #[error("Error while accessing runtime information {0}")] + Runtime(#[from] runtime::Error), + + #[error(transparent)] + ChainApi(#[from] ChainApiError), + + #[error(transparent)] + Io(#[from] std::io::Error), + + #[error(transparent)] + Oneshot(#[from] oneshot::Canceled), + + #[error("Could not send import confirmation (receiver canceled)")] + DisputeImportOneshotSend, + + #[error(transparent)] + Subsystem(#[from] SubsystemError), + + #[error(transparent)] + Codec(#[from] CodecError), + + /// `RollingSessionWindow` was not able to retrieve `SessionInfo`s. + #[error("Session can't be fetched via `RuntimeInfo`")] + SessionInfo, + + #[error(transparent)] + QueueError(#[from] participation::QueueError), +} + +/// Utility for eating top level errors and log them. +/// +/// We basically always want to try and continue on error. This utility function is meant to +/// consume top-level errors by simply logging them +pub fn log_error(result: Result<()>) -> std::result::Result<(), FatalError> { + match result.into_nested()? { + Ok(()) => Ok(()), + Err(jfyi) => { + jfyi.log(); + Ok(()) + }, + } +} + +impl JfyiError { + /// Log a `JfyiError`. + pub fn log(self) { + match self { + // don't spam the log with spurious errors + Self::Runtime(runtime::Error::RuntimeRequestCanceled(_)) | Self::Oneshot(_) => { + gum::debug!(target: LOG_TARGET, error = ?self) + }, + // it's worth reporting otherwise + _ => gum::warn!(target: LOG_TARGET, error = ?self), + } + } +} diff --git a/polkadot/node/core/dispute-coordinator/src/import.rs b/polkadot/node/core/dispute-coordinator/src/import.rs new file mode 100644 index 0000000000000000000000000000000000000000..0da3723ebf229cadf88969f8db9ba54daf863742 --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/import.rs @@ -0,0 +1,580 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Vote import logic. +//! +//! This module encapsulates the actual logic for importing new votes and provides easy access of +//! the current state for votes for a particular candidate. +//! +//! In particular there is `CandidateVoteState` which tells what can be concluded for a particular +//! set of votes. E.g. whether a dispute is ongoing, whether it is confirmed, concluded, .. +//! +//! Then there is `ImportResult` which reveals information about what changed once additional votes +//! got imported on top of an existing `CandidateVoteState` and reveals "dynamic" information, like +//! whether due to the import a dispute was raised/got confirmed, ... + +use std::collections::{BTreeMap, HashMap, HashSet}; + +use polkadot_node_primitives::{ + disputes::ValidCandidateVotes, CandidateVotes, DisputeStatus, SignedDisputeStatement, Timestamp, +}; +use polkadot_node_subsystem::overseer; +use polkadot_node_subsystem_util::runtime::RuntimeInfo; +use polkadot_primitives::{ + CandidateReceipt, DisputeStatement, Hash, IndexedVec, SessionIndex, SessionInfo, + ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorPair, ValidatorSignature, +}; +use sc_keystore::LocalKeystore; + +use crate::LOG_TARGET; + +/// (Session) environment of a candidate. +pub struct CandidateEnvironment<'a> { + /// The session the candidate appeared in. + session_index: SessionIndex, + /// Session for above index. + session: &'a SessionInfo, + /// Validator indices controlled by this node. + controlled_indices: HashSet, +} + +#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)] +impl<'a> CandidateEnvironment<'a> { + /// Create `CandidateEnvironment`. + /// + /// Return: `None` in case session is outside of session window. + pub async fn new( + keystore: &LocalKeystore, + ctx: &mut Context, + runtime_info: &'a mut RuntimeInfo, + session_index: SessionIndex, + relay_parent: Hash, + ) -> Option> { + let session_info = match runtime_info + .get_session_info_by_index(ctx.sender(), relay_parent, session_index) + .await + { + Ok(extended_session_info) => &extended_session_info.session_info, + Err(_) => return None, + }; + + let controlled_indices = + find_controlled_validator_indices(keystore, &session_info.validators); + Some(Self { session_index, session: session_info, controlled_indices }) + } + + /// Validators in the candidate's session. + pub fn validators(&self) -> &IndexedVec { + &self.session.validators + } + + /// `SessionInfo` for the candidate's session. + pub fn session_info(&self) -> &SessionInfo { + &self.session + } + + /// Retrieve `SessionIndex` for this environment. + pub fn session_index(&self) -> SessionIndex { + self.session_index + } + + /// Indices controlled by this node. + pub fn controlled_indices(&'a self) -> &'a HashSet { + &self.controlled_indices + } +} + +/// Whether or not we already issued some statement about a candidate. +pub enum OwnVoteState { + /// Our votes, if any. + Voted(Vec<(ValidatorIndex, (DisputeStatement, ValidatorSignature))>), + + /// We are not a parachain validator in the session. + /// + /// Hence we cannot vote. + CannotVote, +} + +impl OwnVoteState { + fn new(votes: &CandidateVotes, env: &CandidateEnvironment<'_>) -> Self { + let controlled_indices = env.controlled_indices(); + if controlled_indices.is_empty() { + return Self::CannotVote + } + + let our_valid_votes = controlled_indices + .iter() + .filter_map(|i| votes.valid.raw().get_key_value(i)) + .map(|(index, (kind, sig))| (*index, (DisputeStatement::Valid(*kind), sig.clone()))); + let our_invalid_votes = controlled_indices + .iter() + .filter_map(|i| votes.invalid.get_key_value(i)) + .map(|(index, (kind, sig))| (*index, (DisputeStatement::Invalid(*kind), sig.clone()))); + + Self::Voted(our_valid_votes.chain(our_invalid_votes).collect()) + } + + /// Is a vote from us missing but we are a validator able to vote? + fn vote_missing(&self) -> bool { + match self { + Self::Voted(votes) if votes.is_empty() => true, + Self::Voted(_) | Self::CannotVote => false, + } + } + + /// Get own approval votes, if any. + /// + /// Empty iterator means, no approval votes. `None` means, there will never be any (we cannot + /// vote). + fn approval_votes( + &self, + ) -> Option> { + match self { + Self::Voted(votes) => Some(votes.iter().filter_map(|(index, (kind, sig))| { + if let DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking) = kind { + Some((*index, sig)) + } else { + None + } + })), + Self::CannotVote => None, + } + } + + /// Get our votes if there are any. + /// + /// Empty iterator means, no votes. `None` means, there will never be any (we cannot + /// vote). + fn votes(&self) -> Option<&Vec<(ValidatorIndex, (DisputeStatement, ValidatorSignature))>> { + match self { + Self::Voted(votes) => Some(&votes), + Self::CannotVote => None, + } + } +} + +/// Complete state of votes for a candidate. +/// +/// All votes + information whether a dispute is ongoing, confirmed, concluded, whether we already +/// voted, ... +pub struct CandidateVoteState { + /// Votes already existing for the candidate + receipt. + votes: Votes, + + /// Information about own votes: + own_vote: OwnVoteState, + + /// Current dispute status, if there is any. + dispute_status: Option, + + /// Are there `byzantine threshold + 1` invalid votes + byzantine_threshold_against: bool, +} + +impl CandidateVoteState { + /// Create an empty `CandidateVoteState` + /// + /// in case there have not been any previous votes. + pub fn new_from_receipt(candidate_receipt: CandidateReceipt) -> Self { + let votes = CandidateVotes { + candidate_receipt, + valid: ValidCandidateVotes::new(), + invalid: BTreeMap::new(), + }; + Self { + votes, + own_vote: OwnVoteState::CannotVote, + dispute_status: None, + byzantine_threshold_against: false, + } + } + + /// Create a new `CandidateVoteState` from already existing votes. + pub fn new(votes: CandidateVotes, env: &CandidateEnvironment, now: Timestamp) -> Self { + let own_vote = OwnVoteState::new(&votes, env); + + let n_validators = env.validators().len(); + + let supermajority_threshold = polkadot_primitives::supermajority_threshold(n_validators); + + // We have a dispute, if we have votes on both sides: + let is_disputed = !votes.invalid.is_empty() && !votes.valid.raw().is_empty(); + + let (dispute_status, byzantine_threshold_against) = if is_disputed { + let mut status = DisputeStatus::active(); + let byzantine_threshold = polkadot_primitives::byzantine_threshold(n_validators); + let is_confirmed = votes.voted_indices().len() > byzantine_threshold; + if is_confirmed { + status = status.confirm(); + }; + let concluded_for = votes.valid.raw().len() >= supermajority_threshold; + if concluded_for { + status = status.conclude_for(now); + }; + + let concluded_against = votes.invalid.len() >= supermajority_threshold; + if concluded_against { + status = status.conclude_against(now); + }; + (Some(status), votes.invalid.len() > byzantine_threshold) + } else { + (None, false) + }; + + Self { votes, own_vote, dispute_status, byzantine_threshold_against } + } + + /// Import fresh statements. + /// + /// Result will be a new state plus information about things that changed due to the import. + pub fn import_statements( + self, + env: &CandidateEnvironment, + statements: Vec<(SignedDisputeStatement, ValidatorIndex)>, + now: Timestamp, + ) -> ImportResult { + let (mut votes, old_state) = self.into_old_state(); + + let mut new_invalid_voters = Vec::new(); + let mut imported_invalid_votes = 0; + let mut imported_valid_votes = 0; + + let expected_candidate_hash = votes.candidate_receipt.hash(); + + for (statement, val_index) in statements { + if env + .validators() + .get(val_index) + .map_or(true, |v| v != statement.validator_public()) + { + gum::error!( + target: LOG_TARGET, + ?val_index, + session= ?env.session_index, + claimed_key = ?statement.validator_public(), + "Validator index doesn't match claimed key", + ); + + continue + } + if statement.candidate_hash() != &expected_candidate_hash { + gum::error!( + target: LOG_TARGET, + ?val_index, + session= ?env.session_index, + given_candidate_hash = ?statement.candidate_hash(), + ?expected_candidate_hash, + "Vote is for unexpected candidate!", + ); + continue + } + if statement.session_index() != env.session_index() { + gum::error!( + target: LOG_TARGET, + ?val_index, + session= ?env.session_index, + given_candidate_hash = ?statement.candidate_hash(), + ?expected_candidate_hash, + "Vote is for unexpected session!", + ); + continue + } + + match statement.statement() { + DisputeStatement::Valid(valid_kind) => { + let fresh = votes.valid.insert_vote( + val_index, + *valid_kind, + statement.into_validator_signature(), + ); + if fresh { + imported_valid_votes += 1; + } + }, + DisputeStatement::Invalid(invalid_kind) => { + let fresh = votes + .invalid + .insert(val_index, (*invalid_kind, statement.into_validator_signature())) + .is_none(); + if fresh { + new_invalid_voters.push(val_index); + imported_invalid_votes += 1; + } + }, + } + } + + let new_state = Self::new(votes, env, now); + + ImportResult { + old_state, + new_state, + imported_invalid_votes, + imported_valid_votes, + imported_approval_votes: 0, + new_invalid_voters, + } + } + + /// Retrieve `CandidateReceipt` in `CandidateVotes`. + pub fn candidate_receipt(&self) -> &CandidateReceipt { + &self.votes.candidate_receipt + } + + /// Extract `CandidateVotes` for handling import of new statements. + fn into_old_state(self) -> (CandidateVotes, CandidateVoteState<()>) { + let CandidateVoteState { votes, own_vote, dispute_status, byzantine_threshold_against } = + self; + ( + votes, + CandidateVoteState { votes: (), own_vote, dispute_status, byzantine_threshold_against }, + ) + } +} + +impl CandidateVoteState { + /// Whether or not we have an ongoing dispute. + pub fn is_disputed(&self) -> bool { + self.dispute_status.is_some() + } + + /// Whether there is an ongoing confirmed dispute. + /// + /// This checks whether there is a dispute ongoing and we have more than byzantine threshold + /// votes. + pub fn is_confirmed(&self) -> bool { + self.dispute_status.map_or(false, |s| s.is_confirmed_concluded()) + } + + /// Are we a validator in the session, but have not yet voted? + pub fn own_vote_missing(&self) -> bool { + self.own_vote.vote_missing() + } + + /// Own approval votes if any: + pub fn own_approval_votes( + &self, + ) -> Option> { + self.own_vote.approval_votes() + } + + /// Get own votes if there are any. + pub fn own_votes( + &self, + ) -> Option<&Vec<(ValidatorIndex, (DisputeStatement, ValidatorSignature))>> { + self.own_vote.votes() + } + + /// Whether or not there is a dispute and it has already enough valid votes to conclude. + pub fn has_concluded_for(&self) -> bool { + self.dispute_status.map_or(false, |s| s.has_concluded_for()) + } + + /// Whether or not there is a dispute and it has already enough invalid votes to conclude. + pub fn has_concluded_against(&self) -> bool { + self.dispute_status.map_or(false, |s| s.has_concluded_against()) + } + + /// Get access to the dispute status, in case there is one. + pub fn dispute_status(&self) -> &Option { + &self.dispute_status + } + + /// Access to underlying votes. + pub fn votes(&self) -> &V { + &self.votes + } +} + +/// An ongoing statement/vote import. +pub struct ImportResult { + /// The state we had before importing new statements. + old_state: CandidateVoteState<()>, + /// The new state after importing the new statements. + new_state: CandidateVoteState, + /// New invalid voters as of this import. + new_invalid_voters: Vec, + /// Number of successfully imported valid votes. + imported_invalid_votes: u32, + /// Number of successfully imported invalid votes. + imported_valid_votes: u32, + /// Number of approval votes imported via `import_approval_votes()`. + /// + /// And only those: If normal import included approval votes, those are not counted here. + /// + /// In other words, without a call `import_approval_votes()` this will always be 0. + imported_approval_votes: u32, +} + +impl ImportResult { + /// Whether or not anything has changed due to the import. + pub fn votes_changed(&self) -> bool { + self.imported_valid_votes != 0 || self.imported_invalid_votes != 0 + } + + /// The dispute state has changed in some way. + /// + /// - freshly disputed + /// - freshly confirmed + /// - freshly concluded (valid or invalid) + pub fn dispute_state_changed(&self) -> bool { + self.is_freshly_disputed() || self.is_freshly_confirmed() || self.is_freshly_concluded() + } + + /// State as it was before import. + pub fn old_state(&self) -> &CandidateVoteState<()> { + &self.old_state + } + + /// State after import + pub fn new_state(&self) -> &CandidateVoteState { + &self.new_state + } + + /// New "invalid" voters encountered during import. + pub fn new_invalid_voters(&self) -> &Vec { + &self.new_invalid_voters + } + + /// Number of imported valid votes. + pub fn imported_valid_votes(&self) -> u32 { + self.imported_valid_votes + } + + /// Number of imported invalid votes. + pub fn imported_invalid_votes(&self) -> u32 { + self.imported_invalid_votes + } + + /// Number of imported approval votes. + pub fn imported_approval_votes(&self) -> u32 { + self.imported_approval_votes + } + + /// Whether we now have a dispute and did not prior to the import. + pub fn is_freshly_disputed(&self) -> bool { + !self.old_state().is_disputed() && self.new_state().is_disputed() + } + + /// Whether we just surpassed the byzantine threshold. + pub fn is_freshly_confirmed(&self) -> bool { + !self.old_state().is_confirmed() && self.new_state().is_confirmed() + } + + /// Whether or not any dispute just concluded valid due to the import. + pub fn is_freshly_concluded_for(&self) -> bool { + !self.old_state().has_concluded_for() && self.new_state().has_concluded_for() + } + + /// Whether or not any dispute just concluded invalid due to the import. + pub fn is_freshly_concluded_against(&self) -> bool { + !self.old_state().has_concluded_against() && self.new_state().has_concluded_against() + } + + /// Whether or not any dispute just concluded either invalid or valid due to the import. + pub fn is_freshly_concluded(&self) -> bool { + self.is_freshly_concluded_against() || self.is_freshly_concluded_for() + } + + /// Whether or not the invalid vote count for the dispute went beyond the byzantine threshold + /// after the last import + pub fn has_fresh_byzantine_threshold_against(&self) -> bool { + !self.old_state().byzantine_threshold_against && + self.new_state().byzantine_threshold_against + } + + /// Modify this `ImportResult`s, by importing additional approval votes. + /// + /// Both results and `new_state` will be changed as if those approval votes had been in the + /// original import. + pub fn import_approval_votes( + self, + env: &CandidateEnvironment, + approval_votes: HashMap, + now: Timestamp, + ) -> Self { + let Self { + old_state, + new_state, + new_invalid_voters, + mut imported_valid_votes, + imported_invalid_votes, + mut imported_approval_votes, + } = self; + + let (mut votes, _) = new_state.into_old_state(); + + for (index, sig) in approval_votes.into_iter() { + debug_assert!( + { + let pub_key = &env.session_info().validators.get(index).expect("indices are validated by approval-voting subsystem; qed"); + let candidate_hash = votes.candidate_receipt.hash(); + let session_index = env.session_index(); + DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking) + .check_signature(pub_key, candidate_hash, session_index, &sig) + .is_ok() + }, + "Signature check for imported approval votes failed! This is a serious bug. Session: {:?}, candidate hash: {:?}, validator index: {:?}", env.session_index(), votes.candidate_receipt.hash(), index + ); + if votes.valid.insert_vote(index, ValidDisputeStatementKind::ApprovalChecking, sig) { + imported_valid_votes += 1; + imported_approval_votes += 1; + } + } + + let new_state = CandidateVoteState::new(votes, env, now); + + Self { + old_state, + new_state, + new_invalid_voters, + imported_valid_votes, + imported_invalid_votes, + imported_approval_votes, + } + } + + /// All done, give me those votes. + /// + /// Returns: `None` in case nothing has changed (import was redundant). + pub fn into_updated_votes(self) -> Option { + if self.votes_changed() { + let CandidateVoteState { votes, .. } = self.new_state; + Some(votes) + } else { + None + } + } +} + +/// Find indices controlled by this validator. +/// +/// That is all `ValidatorIndex`es we have private keys for. Usually this will only be one. +fn find_controlled_validator_indices( + keystore: &LocalKeystore, + validators: &IndexedVec, +) -> HashSet { + let mut controlled = HashSet::new(); + for (index, validator) in validators.iter().enumerate() { + if keystore.key_pair::(validator).ok().flatten().is_none() { + continue + } + + controlled.insert(ValidatorIndex(index as _)); + } + + controlled +} diff --git a/polkadot/node/core/dispute-coordinator/src/initialized.rs b/polkadot/node/core/dispute-coordinator/src/initialized.rs new file mode 100644 index 0000000000000000000000000000000000000000..c1d02ef976cb666f056ffa24602fd1affb9971d1 --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/initialized.rs @@ -0,0 +1,1583 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Dispute coordinator subsystem in initialized state (after first active leaf is received). + +use std::{ + collections::{BTreeMap, VecDeque}, + sync::Arc, +}; + +use futures::{ + channel::{mpsc, oneshot}, + FutureExt, StreamExt, +}; + +use sc_keystore::LocalKeystore; + +use polkadot_node_primitives::{ + disputes::ValidCandidateVotes, CandidateVotes, DisputeStatus, SignedDisputeStatement, + Timestamp, DISPUTE_WINDOW, +}; +use polkadot_node_subsystem::{ + messages::{ + ApprovalVotingMessage, BlockDescription, ChainSelectionMessage, DisputeCoordinatorMessage, + DisputeDistributionMessage, ImportStatementsResult, + }, + overseer, ActivatedLeaf, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, RuntimeApiError, +}; +use polkadot_node_subsystem_util::runtime::{ + self, key_ownership_proof, submit_report_dispute_lost, RuntimeInfo, +}; +use polkadot_primitives::{ + vstaging, BlockNumber, CandidateHash, CandidateReceipt, CompactStatement, DisputeStatement, + DisputeStatementSet, Hash, ScrapedOnChainVotes, SessionIndex, ValidDisputeStatementKind, + ValidatorId, ValidatorIndex, +}; + +use crate::{ + db, + error::{log_error, FatalError, FatalResult, JfyiError, JfyiResult, Result}, + import::{CandidateEnvironment, CandidateVoteState}, + is_potential_spam, + metrics::Metrics, + scraping::ScrapedUpdates, + status::{get_active_with_status, Clock}, + DisputeCoordinatorSubsystem, LOG_TARGET, +}; + +use super::{ + backend::Backend, + make_dispute_message, + participation::{ + self, Participation, ParticipationPriority, ParticipationRequest, ParticipationStatement, + WorkerMessageReceiver, + }, + scraping::ChainScraper, + spam_slots::SpamSlots, + OverlayedBackend, +}; + +/// How many blocks we import votes from per leaf update. +/// +/// Since vote import is relatively slow, we have to limit the maximum amount of work we do on leaf +/// updates (and especially on startup) so the dispute coordinator won't be considered stalling. +const CHAIN_IMPORT_MAX_BATCH_SIZE: usize = 8; + +// Initial data for `dispute-coordinator`. It is provided only at first start. +pub struct InitialData { + pub participations: Vec<(ParticipationPriority, ParticipationRequest)>, + pub votes: Vec, + pub leaf: ActivatedLeaf, +} + +/// After the first active leaves update we transition to `Initialized` state. +/// +/// Before the first active leaves update we can't really do much. We cannot check incoming +/// statements for validity, we cannot query orderings, we have no valid `SessionInfo`, +/// ... +pub(crate) struct Initialized { + keystore: Arc, + runtime_info: RuntimeInfo, + /// This is the highest `SessionIndex` seen via `ActiveLeavesUpdate`. It doesn't matter if it + /// was cached successfully or not. It is used to detect ancient disputes. + highest_session_seen: SessionIndex, + /// Will be set to `true` if an error occured during the last caching attempt + gaps_in_cache: bool, + spam_slots: SpamSlots, + participation: Participation, + scraper: ChainScraper, + participation_receiver: WorkerMessageReceiver, + /// Backlog of still to be imported votes from chain. + /// + /// For some reason importing votes is relatively slow, if there is a large finality lag (~50 + /// blocks) we will be too slow importing all votes from unfinalized chains on startup + /// (dispute-coordinator gets killed because of unresponsiveness). + /// + /// https://github.com/paritytech/polkadot/issues/6912 + /// + /// To resolve this, we limit the amount of votes imported at once to + /// `CHAIN_IMPORT_MAX_BATCH_SIZE` and put the rest here for later processing. + chain_import_backlog: VecDeque, + metrics: Metrics, +} + +#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)] +impl Initialized { + /// Make initialized subsystem, ready to `run`. + pub fn new( + subsystem: DisputeCoordinatorSubsystem, + runtime_info: RuntimeInfo, + spam_slots: SpamSlots, + scraper: ChainScraper, + highest_session_seen: SessionIndex, + gaps_in_cache: bool, + ) -> Self { + let DisputeCoordinatorSubsystem { config: _, store: _, keystore, metrics } = subsystem; + + let (participation_sender, participation_receiver) = mpsc::channel(1); + let participation = Participation::new(participation_sender, metrics.clone()); + + Self { + keystore, + runtime_info, + highest_session_seen, + gaps_in_cache, + spam_slots, + scraper, + participation, + participation_receiver, + chain_import_backlog: VecDeque::new(), + metrics, + } + } + + /// Run the initialized subsystem. + /// + /// `initial_data` is optional. It is passed on first start and is `None` on subsystem restarts. + pub async fn run( + mut self, + mut ctx: Context, + mut backend: B, + mut initial_data: Option, + clock: Box, + ) -> FatalResult<()> + where + B: Backend, + { + loop { + let res = + self.run_until_error(&mut ctx, &mut backend, &mut initial_data, &*clock).await; + if let Ok(()) = res { + gum::info!(target: LOG_TARGET, "received `Conclude` signal, exiting"); + return Ok(()) + } + log_error(res)?; + } + } + + // Run the subsystem until an error is encountered or a `conclude` signal is received. + // Most errors are non-fatal and should lead to another call to this function. + // + // A return value of `Ok` indicates that an exit should be made, while non-fatal errors + // lead to another call to this function. + async fn run_until_error( + &mut self, + ctx: &mut Context, + backend: &mut B, + initial_data: &mut Option, + clock: &dyn Clock, + ) -> Result<()> + where + B: Backend, + { + if let Some(InitialData { participations, votes: on_chain_votes, leaf: first_leaf }) = + initial_data.take() + { + for (priority, request) in participations { + self.participation.queue_participation(ctx, priority, request).await?; + } + + let mut overlay_db = OverlayedBackend::new(backend); + + self.process_chain_import_backlog( + ctx, + &mut overlay_db, + on_chain_votes, + clock.now(), + first_leaf.hash, + ) + .await; + + if !overlay_db.is_empty() { + let ops = overlay_db.into_write_ops(); + backend.write(ops)?; + } + + // Also provide first leaf to participation for good measure. + self.participation + .process_active_leaves_update(ctx, &ActiveLeavesUpdate::start_work(first_leaf)) + .await?; + } + + loop { + gum::trace!(target: LOG_TARGET, "Waiting for message"); + let mut overlay_db = OverlayedBackend::new(backend); + let default_confirm = Box::new(|| Ok(())); + let confirm_write = + match MuxedMessage::receive(ctx, &mut self.participation_receiver).await? { + MuxedMessage::Participation(msg) => { + gum::trace!(target: LOG_TARGET, "MuxedMessage::Participation"); + let ParticipationStatement { + session, + candidate_hash, + candidate_receipt, + outcome, + } = self.participation.get_participation_result(ctx, msg).await?; + if let Some(valid) = outcome.validity() { + gum::trace!( + target: LOG_TARGET, + ?session, + ?candidate_hash, + ?valid, + "Issuing local statement based on participation outcome." + ); + self.issue_local_statement( + ctx, + &mut overlay_db, + candidate_hash, + candidate_receipt, + session, + valid, + clock.now(), + ) + .await?; + } else { + gum::warn!(target: LOG_TARGET, ?outcome, "Dispute participation failed"); + } + default_confirm + }, + MuxedMessage::Subsystem(msg) => match msg { + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => { + gum::trace!(target: LOG_TARGET, "OverseerSignal::ActiveLeaves"); + self.process_active_leaves_update( + ctx, + &mut overlay_db, + update, + clock.now(), + ) + .await?; + default_confirm + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(_, n)) => { + gum::trace!(target: LOG_TARGET, "OverseerSignal::BlockFinalized"); + self.scraper.process_finalized_block(&n); + default_confirm + }, + FromOrchestra::Communication { msg } => + self.handle_incoming(ctx, &mut overlay_db, msg, clock.now()).await?, + }, + }; + + if !overlay_db.is_empty() { + let ops = overlay_db.into_write_ops(); + backend.write(ops)?; + } + // even if the changeset was empty, + // otherwise the caller will error. + confirm_write()?; + } + } + + async fn process_active_leaves_update( + &mut self, + ctx: &mut Context, + overlay_db: &mut OverlayedBackend<'_, impl Backend>, + update: ActiveLeavesUpdate, + now: u64, + ) -> Result<()> { + gum::trace!(target: LOG_TARGET, timestamp = now, "Processing ActiveLeavesUpdate"); + let scraped_updates = + self.scraper.process_active_leaves_update(ctx.sender(), &update).await?; + log_error( + self.participation + .bump_to_priority_for_candidates(ctx, &scraped_updates.included_receipts) + .await, + )?; + self.participation.process_active_leaves_update(ctx, &update).await?; + + if let Some(new_leaf) = update.activated { + let session_idx = + self.runtime_info.get_session_index_for_child(ctx.sender(), new_leaf.hash).await; + + match session_idx { + Ok(session_idx) + if self.gaps_in_cache || session_idx > self.highest_session_seen => + { + // Fetch the last `DISPUTE_WINDOW` number of sessions unless there are no gaps + // in cache and we are not missing too many `SessionInfo`s + let mut lower_bound = session_idx.saturating_sub(DISPUTE_WINDOW.get() - 1); + if !self.gaps_in_cache && self.highest_session_seen > lower_bound { + lower_bound = self.highest_session_seen + 1 + } + + // There is a new session. Perform a dummy fetch to cache it. + for idx in lower_bound..=session_idx { + if let Err(err) = self + .runtime_info + .get_session_info_by_index(ctx.sender(), new_leaf.hash, idx) + .await + { + gum::debug!( + target: LOG_TARGET, + session_idx, + leaf_hash = ?new_leaf.hash, + ?err, + "Error caching SessionInfo on ActiveLeaves update" + ); + self.gaps_in_cache = true; + } + } + + self.highest_session_seen = session_idx; + + db::v1::note_earliest_session( + overlay_db, + session_idx.saturating_sub(DISPUTE_WINDOW.get() - 1), + )?; + self.spam_slots.prune_old(session_idx.saturating_sub(DISPUTE_WINDOW.get() - 1)); + }, + Ok(_) => { /* no new session => nothing to cache */ }, + Err(err) => { + gum::debug!( + target: LOG_TARGET, + ?err, + "Failed to update session cache for disputes - can't fetch session index", + ); + }, + } + + let ScrapedUpdates { unapplied_slashes, on_chain_votes, .. } = scraped_updates; + + self.process_unapplied_slashes(ctx, new_leaf.hash, unapplied_slashes).await; + + gum::trace!( + target: LOG_TARGET, + timestamp = now, + "Will process {} onchain votes", + on_chain_votes.len() + ); + + self.process_chain_import_backlog(ctx, overlay_db, on_chain_votes, now, new_leaf.hash) + .await; + } + + gum::trace!(target: LOG_TARGET, timestamp = now, "Done processing ActiveLeavesUpdate"); + Ok(()) + } + + /// For each unapplied (past-session) slash, report an unsigned extrinsic + /// to the runtime. + async fn process_unapplied_slashes( + &mut self, + ctx: &mut Context, + relay_parent: Hash, + unapplied_slashes: Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>, + ) { + for (session_index, candidate_hash, pending) in unapplied_slashes { + gum::info!( + target: LOG_TARGET, + ?session_index, + ?candidate_hash, + n_slashes = pending.keys.len(), + "Processing unapplied validator slashes", + ); + + let inclusions = self.scraper.get_blocks_including_candidate(&candidate_hash); + if inclusions.is_empty() { + gum::info!( + target: LOG_TARGET, + "Couldn't find inclusion parent for an unapplied slash", + ); + return + } + + // Find the first inclusion parent that we can use + // to generate key ownership proof on. + // We use inclusion parents because of the proper session index. + let mut key_ownership_proofs = Vec::new(); + let mut dispute_proofs = Vec::new(); + + for (_height, inclusion_parent) in inclusions { + for (validator_index, validator_id) in pending.keys.iter() { + let res = + key_ownership_proof(ctx.sender(), inclusion_parent, validator_id.clone()) + .await; + + match res { + Ok(Some(key_ownership_proof)) => { + key_ownership_proofs.push(key_ownership_proof); + let time_slot = vstaging::slashing::DisputesTimeSlot::new( + session_index, + candidate_hash, + ); + let dispute_proof = vstaging::slashing::DisputeProof { + time_slot, + kind: pending.kind, + validator_index: *validator_index, + validator_id: validator_id.clone(), + }; + dispute_proofs.push(dispute_proof); + }, + Ok(None) => {}, + Err(runtime::Error::RuntimeRequest(RuntimeApiError::NotSupported { + .. + })) => { + gum::debug!( + target: LOG_TARGET, + ?session_index, + ?candidate_hash, + ?validator_id, + "Key ownership proof not yet supported.", + ); + }, + Err(error) => { + gum::warn!( + target: LOG_TARGET, + ?error, + ?session_index, + ?candidate_hash, + ?validator_id, + "Could not generate key ownership proof", + ); + }, + } + } + + if !key_ownership_proofs.is_empty() { + // If we found a parent that we can use, stop searching. + // If one key ownership was resolved successfully, all of them should be. + debug_assert_eq!(key_ownership_proofs.len(), pending.keys.len()); + break + } + } + + let expected_keys = pending.keys.len(); + let resolved_keys = key_ownership_proofs.len(); + if resolved_keys < expected_keys { + gum::warn!( + target: LOG_TARGET, + ?session_index, + ?candidate_hash, + "Could not generate key ownership proofs for {} keys", + expected_keys - resolved_keys, + ); + } + debug_assert_eq!(resolved_keys, dispute_proofs.len()); + + for (key_ownership_proof, dispute_proof) in + key_ownership_proofs.into_iter().zip(dispute_proofs.into_iter()) + { + let validator_id = dispute_proof.validator_id.clone(); + + gum::info!( + target: LOG_TARGET, + ?session_index, + ?candidate_hash, + key_ownership_proof_len = key_ownership_proof.len(), + "Trying to submit a slashing report", + ); + + let res = submit_report_dispute_lost( + ctx.sender(), + relay_parent, + dispute_proof, + key_ownership_proof, + ) + .await; + + match res { + Err(runtime::Error::RuntimeRequest(RuntimeApiError::NotSupported { + .. + })) => { + gum::debug!( + target: LOG_TARGET, + ?session_index, + ?candidate_hash, + "Reporting pending slash not yet supported", + ); + }, + Err(error) => { + gum::warn!( + target: LOG_TARGET, + ?error, + ?session_index, + ?candidate_hash, + "Error reporting pending slash", + ); + }, + Ok(Some(())) => { + gum::info!( + target: LOG_TARGET, + ?session_index, + ?candidate_hash, + ?validator_id, + "Successfully reported pending slash", + ); + }, + Ok(None) => { + gum::debug!( + target: LOG_TARGET, + ?session_index, + ?candidate_hash, + ?validator_id, + "Duplicate pending slash report", + ); + }, + } + } + } + } + + /// Process one batch of our `chain_import_backlog`. + /// + /// `new_votes` will be appended beforehand. + async fn process_chain_import_backlog( + &mut self, + ctx: &mut Context, + overlay_db: &mut OverlayedBackend<'_, impl Backend>, + new_votes: Vec, + now: u64, + block_hash: Hash, + ) { + let mut chain_import_backlog = std::mem::take(&mut self.chain_import_backlog); + chain_import_backlog.extend(new_votes); + let import_range = + 0..std::cmp::min(CHAIN_IMPORT_MAX_BATCH_SIZE, chain_import_backlog.len()); + // The `runtime-api` subsystem has an internal queue which serializes the execution, + // so there is no point in running these in parallel + for votes in chain_import_backlog.drain(import_range) { + let res = self.process_on_chain_votes(ctx, overlay_db, votes, now, block_hash).await; + match res { + Ok(()) => {}, + Err(error) => { + gum::warn!(target: LOG_TARGET, ?error, "Skipping scraping block due to error",); + }, + }; + } + self.chain_import_backlog = chain_import_backlog; + } + + /// Scrapes on-chain votes (backing votes and concluded disputes) for a active leaf of the + /// relay chain. + async fn process_on_chain_votes( + &mut self, + ctx: &mut Context, + overlay_db: &mut OverlayedBackend<'_, impl Backend>, + votes: ScrapedOnChainVotes, + now: u64, + block_hash: Hash, + ) -> Result<()> { + let ScrapedOnChainVotes { session, backing_validators_per_candidate, disputes } = votes; + + if backing_validators_per_candidate.is_empty() && disputes.is_empty() { + return Ok(()) + } + + // Scraped on-chain backing votes for the candidates with + // the new active leaf as if we received them via gossip. + for (candidate_receipt, backers) in backing_validators_per_candidate { + // Obtain the session info, for sake of `ValidatorId`s + let relay_parent = candidate_receipt.descriptor.relay_parent; + let session_info = match self + .runtime_info + .get_session_info_by_index(ctx.sender(), relay_parent, session) + .await + { + Ok(extended_session_info) => &extended_session_info.session_info, + Err(err) => { + gum::warn!( + target: LOG_TARGET, + ?session, + ?err, + "Could not retrieve session info from RuntimeInfo", + ); + return Ok(()) + }, + }; + + let candidate_hash = candidate_receipt.hash(); + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?relay_parent, + "Importing backing votes from chain for candidate" + ); + let statements = backers + .into_iter() + .filter_map(|(validator_index, attestation)| { + let validator_public: ValidatorId = session_info + .validators + .get(validator_index) + .or_else(|| { + gum::error!( + target: LOG_TARGET, + ?session, + ?validator_index, + "Missing public key for validator", + ); + None + }) + .cloned()?; + let validator_signature = attestation.signature().clone(); + let valid_statement_kind = + match attestation.to_compact_statement(candidate_hash) { + CompactStatement::Seconded(_) => + ValidDisputeStatementKind::BackingSeconded(relay_parent), + CompactStatement::Valid(_) => + ValidDisputeStatementKind::BackingValid(relay_parent), + }; + debug_assert!( + SignedDisputeStatement::new_checked( + DisputeStatement::Valid(valid_statement_kind), + candidate_hash, + session, + validator_public.clone(), + validator_signature.clone(), + ).is_ok(), + "Scraped backing votes had invalid signature! candidate: {:?}, session: {:?}, validator_public: {:?}, validator_index: {}", + candidate_hash, + session, + validator_public, + validator_index.0, + ); + let signed_dispute_statement = + SignedDisputeStatement::new_unchecked_from_trusted_source( + DisputeStatement::Valid(valid_statement_kind), + candidate_hash, + session, + validator_public, + validator_signature, + ); + Some((signed_dispute_statement, validator_index)) + }) + .collect(); + + // Importantly, handling import statements for backing votes also + // clears spam slots for any newly backed candidates + let import_result = self + .handle_import_statements( + ctx, + overlay_db, + MaybeCandidateReceipt::Provides(candidate_receipt), + session, + statements, + now, + ) + .await?; + match import_result { + ImportStatementsResult::ValidImport => gum::trace!( + target: LOG_TARGET, + ?relay_parent, + ?session, + "Imported backing votes from chain" + ), + ImportStatementsResult::InvalidImport => gum::warn!( + target: LOG_TARGET, + ?relay_parent, + ?session, + "Attempted import of on-chain backing votes failed" + ), + } + } + + // Import disputes from on-chain, this already went through a vote so it's assumed + // as verified. This will only be stored, gossiping it is not necessary. + for DisputeStatementSet { candidate_hash, session, statements } in disputes { + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + "Importing dispute votes from chain for candidate" + ); + let session_info = match self + .runtime_info + .get_session_info_by_index(ctx.sender(), block_hash, session) + .await + { + Ok(extended_session_info) => &extended_session_info.session_info, + Err(err) => { + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + ?err, + "Could not retrieve session info for recently concluded dispute" + ); + continue + }, + }; + + let statements = statements + .into_iter() + .filter_map(|(dispute_statement, validator_index, validator_signature)| { + let validator_public: ValidatorId = session_info + .validators + .get(validator_index) + .or_else(|| { + gum::error!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + "Missing public key for validator {:?} that participated in concluded dispute", + &validator_index + ); + None + }) + .cloned()?; + + Some(( + SignedDisputeStatement::new_unchecked_from_trusted_source( + dispute_statement, + candidate_hash, + session, + validator_public, + validator_signature, + ), + validator_index, + )) + }) + .collect::>(); + if statements.is_empty() { + gum::debug!(target: LOG_TARGET, "Skipping empty from chain dispute import"); + continue + } + let import_result = self + .handle_import_statements( + ctx, + overlay_db, + // TODO + MaybeCandidateReceipt::AssumeBackingVotePresent(candidate_hash), + session, + statements, + now, + ) + .await?; + match import_result { + ImportStatementsResult::ValidImport => gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + "Imported statement of dispute from on-chain" + ), + ImportStatementsResult::InvalidImport => gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + "Attempted import of on-chain statement of dispute failed" + ), + } + } + + Ok(()) + } + + async fn handle_incoming( + &mut self, + ctx: &mut Context, + overlay_db: &mut OverlayedBackend<'_, impl Backend>, + message: DisputeCoordinatorMessage, + now: Timestamp, + ) -> Result JfyiResult<()>>> { + match message { + DisputeCoordinatorMessage::ImportStatements { + candidate_receipt, + session, + statements, + pending_confirmation, + } => { + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?candidate_receipt.hash(), + ?session, + "DisputeCoordinatorMessage::ImportStatements" + ); + let outcome = self + .handle_import_statements( + ctx, + overlay_db, + MaybeCandidateReceipt::Provides(candidate_receipt), + session, + statements, + now, + ) + .await?; + let report = move || match pending_confirmation { + Some(pending_confirmation) => pending_confirmation + .send(outcome) + .map_err(|_| JfyiError::DisputeImportOneshotSend), + None => Ok(()), + }; + + match outcome { + ImportStatementsResult::InvalidImport => { + report()?; + }, + // In case of valid import, delay confirmation until actual disk write: + ImportStatementsResult::ValidImport => return Ok(Box::new(report)), + } + }, + DisputeCoordinatorMessage::RecentDisputes(tx) => { + gum::trace!(target: LOG_TARGET, "Loading recent disputes from db"); + let recent_disputes = if let Some(disputes) = overlay_db.load_recent_disputes()? { + disputes + } else { + BTreeMap::new() + }; + gum::trace!(target: LOG_TARGET, "Loaded recent disputes from db"); + + let _ = tx.send( + recent_disputes.into_iter().map(|(k, v)| (k.0, k.1, v)).collect::>(), + ); + }, + DisputeCoordinatorMessage::ActiveDisputes(tx) => { + gum::trace!(target: LOG_TARGET, "DisputeCoordinatorMessage::ActiveDisputes"); + let recent_disputes = if let Some(disputes) = overlay_db.load_recent_disputes()? { + disputes + } else { + BTreeMap::new() + }; + + let _ = tx.send( + get_active_with_status(recent_disputes.into_iter(), now) + .map(|((session_idx, candidate_hash), dispute_status)| { + (session_idx, candidate_hash, dispute_status) + }) + .collect(), + ); + }, + DisputeCoordinatorMessage::QueryCandidateVotes(query, tx) => { + gum::trace!(target: LOG_TARGET, "DisputeCoordinatorMessage::QueryCandidateVotes"); + let mut query_output = Vec::new(); + for (session_index, candidate_hash) in query { + if let Some(v) = + overlay_db.load_candidate_votes(session_index, &candidate_hash)? + { + query_output.push((session_index, candidate_hash, v.into())); + } else { + gum::debug!( + target: LOG_TARGET, + session_index, + "No votes found for candidate", + ); + } + } + let _ = tx.send(query_output); + }, + DisputeCoordinatorMessage::IssueLocalStatement( + session, + candidate_hash, + candidate_receipt, + valid, + ) => { + gum::trace!(target: LOG_TARGET, "DisputeCoordinatorMessage::IssueLocalStatement"); + self.issue_local_statement( + ctx, + overlay_db, + candidate_hash, + candidate_receipt, + session, + valid, + now, + ) + .await?; + }, + DisputeCoordinatorMessage::DetermineUndisputedChain { + base: (base_number, base_hash), + block_descriptions, + tx, + } => { + gum::trace!( + target: LOG_TARGET, + "DisputeCoordinatorMessage::DetermineUndisputedChain" + ); + + let undisputed_chain = determine_undisputed_chain( + overlay_db, + base_number, + base_hash, + block_descriptions, + )?; + + let _ = tx.send(undisputed_chain); + }, + } + + Ok(Box::new(|| Ok(()))) + } + + // We use fatal result rather than result here. Reason being, We for example increase + // spam slots in this function. If then the import fails for some non fatal and + // unrelated reason, we should likely actually decrement previously incremented spam + // slots again, for non fatal errors - which is cumbersome and actually not needed + async fn handle_import_statements( + &mut self, + ctx: &mut Context, + overlay_db: &mut OverlayedBackend<'_, impl Backend>, + candidate_receipt: MaybeCandidateReceipt, + session: SessionIndex, + statements: Vec<(SignedDisputeStatement, ValidatorIndex)>, + now: Timestamp, + ) -> FatalResult { + gum::trace!(target: LOG_TARGET, ?statements, "In handle import statements"); + if self.session_is_ancient(session) { + // It is not valid to participate in an ancient dispute (spam?) or too new. + return Ok(ImportStatementsResult::InvalidImport) + } + + let candidate_hash = candidate_receipt.hash(); + let votes_in_db = overlay_db.load_candidate_votes(session, &candidate_hash)?; + let relay_parent = match &candidate_receipt { + MaybeCandidateReceipt::Provides(candidate_receipt) => + candidate_receipt.descriptor().relay_parent, + MaybeCandidateReceipt::AssumeBackingVotePresent(candidate_hash) => match &votes_in_db { + Some(votes) => votes.candidate_receipt.descriptor().relay_parent, + None => { + gum::warn!( + target: LOG_TARGET, + session, + ?candidate_hash, + "Cannot obtain relay parent without `CandidateReceipt` available!" + ); + return Ok(ImportStatementsResult::InvalidImport) + }, + }, + }; + + let env = match CandidateEnvironment::new( + &self.keystore, + ctx, + &mut self.runtime_info, + session, + relay_parent, + ) + .await + { + None => { + gum::warn!( + target: LOG_TARGET, + session, + "We are lacking a `SessionInfo` for handling import of statements." + ); + + return Ok(ImportStatementsResult::InvalidImport) + }, + Some(env) => env, + }; + + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + num_validators = ?env.session_info().validators.len(), + "Number of validators" + ); + + // In case we are not provided with a candidate receipt + // we operate under the assumption, that a previous vote + // which included a `CandidateReceipt` was seen. + // This holds since every block is preceded by the `Backing`-phase. + // + // There is one exception: A sufficiently sophisticated attacker could prevent + // us from seeing the backing votes by withholding arbitrary blocks, and hence we do + // not have a `CandidateReceipt` available. + let old_state = match votes_in_db.map(CandidateVotes::from) { + Some(votes) => CandidateVoteState::new(votes, &env, now), + None => + if let MaybeCandidateReceipt::Provides(candidate_receipt) = candidate_receipt { + CandidateVoteState::new_from_receipt(candidate_receipt) + } else { + gum::warn!( + target: LOG_TARGET, + session, + ?candidate_hash, + "Cannot import votes, without `CandidateReceipt` available!" + ); + return Ok(ImportStatementsResult::InvalidImport) + }, + }; + + gum::trace!(target: LOG_TARGET, ?candidate_hash, ?session, "Loaded votes"); + + let controlled_indices = env.controlled_indices(); + let own_statements = statements + .iter() + .filter(|(statement, validator_index)| { + controlled_indices.contains(validator_index) && + *statement.candidate_hash() == candidate_hash + }) + .cloned() + .collect::>(); + + let import_result = { + let intermediate_result = old_state.import_statements(&env, statements, now); + + // Handle approval vote import: + // + // See guide: We import on fresh disputes to maximize likelihood of fetching votes for + // dead forks and once concluded to maximize time for approval votes to trickle in. + if intermediate_result.is_freshly_disputed() || + intermediate_result.is_freshly_concluded() + { + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + "Requesting approval signatures" + ); + let (tx, rx) = oneshot::channel(); + // Use of unbounded channels justified because: + // 1. Only triggered twice per dispute. + // 2. Raising a dispute is costly (requires validation + recovery) by honest nodes, + // dishonest nodes are limited by spam slots. + // 3. Concluding a dispute is even more costly. + // Therefore it is reasonable to expect a simple vote request to succeed way faster + // than disputes are raised. + // 4. We are waiting (and blocking the whole subsystem) on a response right after - + // therefore even with all else failing we will never have more than + // one message in flight at any given time. + ctx.send_unbounded_message( + ApprovalVotingMessage::GetApprovalSignaturesForCandidate(candidate_hash, tx), + ); + match rx.await { + Err(_) => { + gum::warn!( + target: LOG_TARGET, + "Fetch for approval votes got cancelled, only expected during shutdown!" + ); + intermediate_result + }, + Ok(votes) => { + gum::trace!( + target: LOG_TARGET, + count = votes.len(), + "Successfully received approval votes." + ); + intermediate_result.import_approval_votes(&env, votes, now) + }, + } + } else { + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + "Not requested approval signatures" + ); + intermediate_result + } + }; + + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + num_validators = ?env.session_info().validators.len(), + "Import result ready" + ); + let new_state = import_result.new_state(); + + let is_included = self.scraper.is_candidate_included(&candidate_hash); + let is_backed = self.scraper.is_candidate_backed(&candidate_hash); + let own_vote_missing = new_state.own_vote_missing(); + let is_disputed = new_state.is_disputed(); + let is_confirmed = new_state.is_confirmed(); + let potential_spam = is_potential_spam(&self.scraper, &new_state, &candidate_hash); + // We participate only in disputes which are not potential spam. + let allow_participation = !potential_spam; + + gum::trace!( + target: LOG_TARGET, + ?own_vote_missing, + ?potential_spam, + ?is_included, + ?candidate_hash, + confirmed = ?new_state.is_confirmed(), + has_invalid_voters = ?!import_result.new_invalid_voters().is_empty(), + "Is spam?" + ); + + // This check is responsible for all clearing of spam slots. It runs + // whenever a vote is imported from on or off chain, and decrements + // slots whenever a candidate is newly backed, confirmed, or has our + // own vote. + if !potential_spam { + self.spam_slots.clear(&(session, candidate_hash)); + + // Potential spam: + } else if !import_result.new_invalid_voters().is_empty() { + let mut free_spam_slots_available = false; + // Only allow import if at least one validator voting invalid, has not exceeded + // its spam slots: + for index in import_result.new_invalid_voters() { + // Disputes can only be triggered via an invalidity stating vote, thus we only + // need to increase spam slots on invalid votes. (If we did not, we would also + // increase spam slots for backing validators for example - as validators have to + // provide some opposing vote for dispute-distribution). + free_spam_slots_available |= + self.spam_slots.add_unconfirmed(session, candidate_hash, *index); + } + if !free_spam_slots_available { + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + invalid_voters = ?import_result.new_invalid_voters(), + "Rejecting import because of full spam slots." + ); + return Ok(ImportStatementsResult::InvalidImport) + } + } + + // Participate in dispute if we did not cast a vote before and actually have keys to cast a + // local vote. Disputes should fall in one of the categories below, otherwise we will + // refrain from participation: + // - `is_included` lands in prioritised queue + // - `is_confirmed` | `is_backed` lands in best effort queue + // We don't participate in disputes on finalized candidates. + if own_vote_missing && is_disputed && allow_participation { + let priority = ParticipationPriority::with_priority_if(is_included); + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?priority, + "Queuing participation for candidate" + ); + if priority.is_priority() { + self.metrics.on_queued_priority_participation(); + } else { + self.metrics.on_queued_best_effort_participation(); + } + let request_timer = self.metrics.time_participation_pipeline(); + let r = self + .participation + .queue_participation( + ctx, + priority, + ParticipationRequest::new( + new_state.candidate_receipt().clone(), + session, + request_timer, + ), + ) + .await; + log_error(r)?; + } else { + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?is_confirmed, + ?own_vote_missing, + ?is_disputed, + ?allow_participation, + ?is_included, + ?is_backed, + "Will not queue participation for candidate" + ); + + if !allow_participation { + self.metrics.on_refrained_participation(); + } + } + + // Also send any already existing approval vote on new disputes: + if import_result.is_freshly_disputed() { + let our_approval_votes = new_state.own_approval_votes().into_iter().flatten(); + for (validator_index, sig) in our_approval_votes { + let pub_key = match env.validators().get(validator_index) { + None => { + gum::error!( + target: LOG_TARGET, + ?validator_index, + ?session, + "Could not find pub key in `SessionInfo` for our own approval vote!" + ); + continue + }, + Some(k) => k, + }; + let statement = SignedDisputeStatement::new_unchecked_from_trusted_source( + DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking), + candidate_hash, + session, + pub_key.clone(), + sig.clone(), + ); + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + ?validator_index, + "Sending out own approval vote" + ); + match make_dispute_message( + env.session_info(), + &new_state.votes(), + statement, + validator_index, + ) { + Err(err) => { + gum::error!( + target: LOG_TARGET, + ?err, + "No ongoing dispute, but we checked there is one!" + ); + }, + Ok(dispute_message) => { + ctx.send_message(DisputeDistributionMessage::SendDispute(dispute_message)) + .await; + }, + }; + } + } + + // All good, update recent disputes if state has changed: + if let Some(new_status) = new_state.dispute_status() { + // Only bother with db access, if there was an actual change. + if import_result.dispute_state_changed() { + let mut recent_disputes = overlay_db.load_recent_disputes()?.unwrap_or_default(); + + let status = + recent_disputes.entry((session, candidate_hash)).or_insert_with(|| { + gum::info!( + target: LOG_TARGET, + ?candidate_hash, + session, + "New dispute initiated for candidate.", + ); + DisputeStatus::active() + }); + + *status = *new_status; + + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?status, + has_concluded_for = ?new_state.has_concluded_for(), + has_concluded_against = ?new_state.has_concluded_against(), + "Writing recent disputes with updates for candidate" + ); + overlay_db.write_recent_disputes(recent_disputes); + } + } + + // Notify ChainSelection if a dispute has concluded against a candidate. ChainSelection + // will need to mark the candidate's relay parent as reverted. + if import_result.has_fresh_byzantine_threshold_against() { + let blocks_including = self.scraper.get_blocks_including_candidate(&candidate_hash); + for (parent_block_number, parent_block_hash) in &blocks_including { + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?parent_block_number, + ?parent_block_hash, + "Dispute has just concluded against the candidate hash noted. Its parent will be marked as reverted." + ); + } + if blocks_including.len() > 0 { + ctx.send_message(ChainSelectionMessage::RevertBlocks(blocks_including)).await; + } else { + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + "Could not find an including block for candidate against which a dispute has concluded." + ); + } + } + + // Update metrics: + if import_result.is_freshly_disputed() { + self.metrics.on_open(); + } + self.metrics.on_valid_votes(import_result.imported_valid_votes()); + self.metrics.on_invalid_votes(import_result.imported_invalid_votes()); + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + imported_approval_votes = ?import_result.imported_approval_votes(), + imported_valid_votes = ?import_result.imported_valid_votes(), + imported_invalid_votes = ?import_result.imported_invalid_votes(), + total_valid_votes = ?import_result.new_state().votes().valid.raw().len(), + total_invalid_votes = ?import_result.new_state().votes().invalid.len(), + confirmed = ?import_result.new_state().is_confirmed(), + "Import summary" + ); + + self.metrics.on_approval_votes(import_result.imported_approval_votes()); + if import_result.is_freshly_concluded_for() { + gum::info!( + target: LOG_TARGET, + ?candidate_hash, + session, + "Dispute on candidate concluded with 'valid' result", + ); + for (statement, validator_index) in own_statements.iter() { + if statement.statement().indicates_invalidity() { + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + ?validator_index, + "Voted against a candidate that was concluded valid.", + ); + } + } + self.metrics.on_concluded_valid(); + } + if import_result.is_freshly_concluded_against() { + gum::info!( + target: LOG_TARGET, + ?candidate_hash, + session, + "Dispute on candidate concluded with 'invalid' result", + ); + for (statement, validator_index) in own_statements.iter() { + if statement.statement().indicates_validity() { + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + ?validator_index, + "Voted for a candidate that was concluded invalid.", + ); + } + } + self.metrics.on_concluded_invalid(); + } + + // Only write when votes have changed. + if let Some(votes) = import_result.into_updated_votes() { + overlay_db.write_candidate_votes(session, candidate_hash, votes.into()); + } + + Ok(ImportStatementsResult::ValidImport) + } + + async fn issue_local_statement( + &mut self, + ctx: &mut Context, + overlay_db: &mut OverlayedBackend<'_, impl Backend>, + candidate_hash: CandidateHash, + candidate_receipt: CandidateReceipt, + session: SessionIndex, + valid: bool, + now: Timestamp, + ) -> Result<()> { + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + ?valid, + ?now, + "Issuing local statement for candidate!" + ); + + // Load environment: + let env = match CandidateEnvironment::new( + &self.keystore, + ctx, + &mut self.runtime_info, + session, + candidate_receipt.descriptor.relay_parent, + ) + .await + { + None => { + gum::warn!( + target: LOG_TARGET, + session, + "Missing info for session which has an active dispute", + ); + + return Ok(()) + }, + Some(env) => env, + }; + + let votes = overlay_db + .load_candidate_votes(session, &candidate_hash)? + .map(CandidateVotes::from) + .unwrap_or_else(|| CandidateVotes { + candidate_receipt: candidate_receipt.clone(), + valid: ValidCandidateVotes::new(), + invalid: BTreeMap::new(), + }); + + // Sign a statement for each validator index we control which has + // not already voted. This should generally be maximum 1 statement. + let voted_indices = votes.voted_indices(); + let mut statements = Vec::new(); + + let controlled_indices = env.controlled_indices(); + for index in controlled_indices { + if voted_indices.contains(&index) { + continue + } + + let keystore = self.keystore.clone() as Arc<_>; + let res = SignedDisputeStatement::sign_explicit( + &keystore, + valid, + candidate_hash, + session, + env.validators() + .get(*index) + .expect("`controlled_indices` are derived from `validators`; qed") + .clone(), + ); + + match res { + Ok(Some(signed_dispute_statement)) => { + statements.push((signed_dispute_statement, *index)); + }, + Ok(None) => {}, + Err(err) => { + gum::error!( + target: LOG_TARGET, + ?err, + "Encountered keystore error while signing dispute statement", + ); + }, + } + } + + // Get our message out: + for (statement, index) in &statements { + let dispute_message = + match make_dispute_message(env.session_info(), &votes, statement.clone(), *index) { + Err(err) => { + gum::debug!(target: LOG_TARGET, ?err, "Creating dispute message failed."); + continue + }, + Ok(dispute_message) => dispute_message, + }; + + ctx.send_message(DisputeDistributionMessage::SendDispute(dispute_message)).await; + } + + // Do import + if !statements.is_empty() { + match self + .handle_import_statements( + ctx, + overlay_db, + MaybeCandidateReceipt::Provides(candidate_receipt), + session, + statements, + now, + ) + .await? + { + ImportStatementsResult::InvalidImport => { + gum::error!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + "`handle_import_statements` considers our own votes invalid!" + ); + }, + ImportStatementsResult::ValidImport => { + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?session, + "`handle_import_statements` successfully imported our vote!" + ); + }, + } + } + + Ok(()) + } + + fn session_is_ancient(&self, session_idx: SessionIndex) -> bool { + return session_idx < self.highest_session_seen.saturating_sub(DISPUTE_WINDOW.get() - 1) + } +} + +/// Messages to be handled in this subsystem. +enum MuxedMessage { + /// Messages from other subsystems. + Subsystem(FromOrchestra), + /// Messages from participation workers. + Participation(participation::WorkerMessage), +} + +#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)] +impl MuxedMessage { + async fn receive( + ctx: &mut Context, + from_sender: &mut participation::WorkerMessageReceiver, + ) -> FatalResult { + // We are only fusing here to make `select` happy, in reality we will quit if the stream + // ends. + let from_overseer = ctx.recv().fuse(); + futures::pin_mut!(from_overseer, from_sender); + futures::select!( + msg = from_overseer => Ok(Self::Subsystem(msg.map_err(FatalError::SubsystemReceive)?)), + msg = from_sender.next() => Ok(Self::Participation(msg.ok_or(FatalError::ParticipationWorkerReceiverExhausted)?)), + ) + } +} + +#[derive(Debug, Clone)] +enum MaybeCandidateReceipt { + /// Directly provides the candidate receipt. + Provides(CandidateReceipt), + /// Assumes it was seen before by means of seconded message. + AssumeBackingVotePresent(CandidateHash), +} + +impl MaybeCandidateReceipt { + /// Retrieve `CandidateHash` for the corresponding candidate. + pub fn hash(&self) -> CandidateHash { + match self { + Self::Provides(receipt) => receipt.hash(), + Self::AssumeBackingVotePresent(hash) => *hash, + } + } +} + +/// Determine the best block and its block number. +/// Assumes `block_descriptions` are sorted from the one +/// with the lowest `BlockNumber` to the highest. +fn determine_undisputed_chain( + overlay_db: &mut OverlayedBackend<'_, impl Backend>, + base_number: BlockNumber, + base_hash: Hash, + block_descriptions: Vec, +) -> Result<(BlockNumber, Hash)> { + let last = block_descriptions + .last() + .map(|e| (base_number + block_descriptions.len() as BlockNumber, e.block_hash)) + .unwrap_or((base_number, base_hash)); + + // Fast path for no disputes. + let recent_disputes = match overlay_db.load_recent_disputes()? { + None => return Ok(last), + Some(a) if a.is_empty() => return Ok(last), + Some(a) => a, + }; + + let is_possibly_invalid = |session, candidate_hash| { + recent_disputes + .get(&(session, candidate_hash)) + .map_or(false, |status| status.is_possibly_invalid()) + }; + + for (i, BlockDescription { session, candidates, .. }) in block_descriptions.iter().enumerate() { + if candidates.iter().any(|c| is_possibly_invalid(*session, *c)) { + if i == 0 { + return Ok((base_number, base_hash)) + } else { + return Ok((base_number + i as BlockNumber, block_descriptions[i - 1].block_hash)) + } + } + } + + Ok(last) +} diff --git a/polkadot/node/core/dispute-coordinator/src/lib.rs b/polkadot/node/core/dispute-coordinator/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..a2c500e08e283fdd3256ab46bef7d3550bcf3d92 --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/lib.rs @@ -0,0 +1,600 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implements the dispute coordinator subsystem. +//! +//! This is the central subsystem of the node-side components which participate in disputes. +//! This subsystem wraps a database which tracks all statements observed by all validators over some +//! window of sessions. Votes older than this session window are pruned. +//! +//! This subsystem will be the point which produce dispute votes, either positive or negative, based +//! on locally-observed validation results as well as a sink for votes received by other subsystems. +//! When importing a dispute vote from another node, this will trigger dispute participation to +//! recover and validate the block. + +use std::{num::NonZeroUsize, sync::Arc}; + +use futures::FutureExt; + +use gum::CandidateHash; +use sc_keystore::LocalKeystore; + +use polkadot_node_primitives::{ + CandidateVotes, DisputeMessage, DisputeMessageCheckError, SignedDisputeStatement, + DISPUTE_WINDOW, +}; +use polkadot_node_subsystem::{ + messages::DisputeDistributionMessage, overseer, ActivatedLeaf, FromOrchestra, OverseerSignal, + SpawnedSubsystem, SubsystemError, +}; +use polkadot_node_subsystem_util::{ + database::Database, + runtime::{Config as RuntimeInfoConfig, RuntimeInfo}, +}; +use polkadot_primitives::{ + DisputeStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidatorIndex, +}; + +use crate::{ + error::{FatalResult, Result}, + metrics::Metrics, + status::{get_active_with_status, SystemClock}, +}; +use backend::{Backend, OverlayedBackend}; +use db::v1::DbBackend; +use fatality::Split; + +use self::{ + import::{CandidateEnvironment, CandidateVoteState}, + participation::{ParticipationPriority, ParticipationRequest}, + spam_slots::{SpamSlots, UnconfirmedDisputes}, +}; + +pub(crate) mod backend; +pub(crate) mod db; +pub(crate) mod error; + +/// Subsystem after receiving the first active leaf. +mod initialized; +use initialized::{InitialData, Initialized}; + +/// Provider of data scraped from chain. +/// +/// If we have seen a candidate included somewhere, we should treat it as priority and will be able +/// to provide an ordering for participation. Thus a dispute for a candidate where we can get some +/// ordering is high-priority (we know it is a valid dispute) and those can be ordered by +/// `participation` based on `relay_parent` block number and other metrics, so each validator will +/// participate in disputes in a similar order, which ensures we will be resolving disputes, even +/// under heavy load. +mod scraping; +use scraping::ChainScraper; + +/// When importing votes we will check via the `ordering` module, whether or not we know of the +/// candidate to be included somewhere. If not, the votes might be spam, in this case we want to +/// limit the amount of locally imported votes, to prevent DoS attacks/resource exhaustion. The +/// `spam_slots` module helps keeping track of unconfirmed disputes per validators, if a spam slot +/// gets full, we will drop any further potential spam votes from that validator and report back +/// that the import failed. Which will lead to any honest validator to retry, thus the spam slots +/// can be relatively small, as a drop is not fatal. +mod spam_slots; + +/// Handling of participation requests via `Participation`. +/// +/// `Participation` provides an API (`Participation::queue_participation`) for queuing of dispute +/// participations and will process those participation requests, such that most important/urgent +/// disputes will be resolved and processed first and more importantly it will order requests in a +/// way so disputes will get resolved, even if there are lots of them. +pub(crate) mod participation; + +/// Pure processing of vote imports. +pub(crate) mod import; + +/// Metrics types. +mod metrics; + +/// Status tracking of disputes (`DisputeStatus`). +mod status; + +use crate::status::Clock; + +#[cfg(test)] +mod tests; + +pub(crate) const LOG_TARGET: &str = "parachain::dispute-coordinator"; + +/// An implementation of the dispute coordinator subsystem. +pub struct DisputeCoordinatorSubsystem { + config: Config, + store: Arc, + keystore: Arc, + metrics: Metrics, +} + +/// Configuration for the dispute coordinator subsystem. +#[derive(Debug, Clone, Copy)] +pub struct Config { + /// The data column in the store to use for dispute data. + pub col_dispute_data: u32, +} + +impl Config { + fn column_config(&self) -> db::v1::ColumnConfiguration { + db::v1::ColumnConfiguration { col_dispute_data: self.col_dispute_data } + } +} + +#[overseer::subsystem(DisputeCoordinator, error=SubsystemError, prefix=self::overseer)] +impl DisputeCoordinatorSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = async { + let backend = DbBackend::new( + self.store.clone(), + self.config.column_config(), + self.metrics.clone(), + ); + self.run(ctx, backend, Box::new(SystemClock)) + .await + .map_err(|e| SubsystemError::with_origin("dispute-coordinator", e)) + } + .boxed(); + + SpawnedSubsystem { name: "dispute-coordinator-subsystem", future } + } +} + +#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)] +impl DisputeCoordinatorSubsystem { + /// Create a new instance of the subsystem. + pub fn new( + store: Arc, + config: Config, + keystore: Arc, + metrics: Metrics, + ) -> Self { + Self { store, config, keystore, metrics } + } + + /// Initialize and afterwards run `Initialized::run`. + async fn run( + self, + mut ctx: Context, + backend: B, + clock: Box, + ) -> FatalResult<()> + where + B: Backend + 'static, + { + let res = self.initialize(&mut ctx, backend, &*clock).await?; + + let (participations, votes, first_leaf, initialized, backend) = match res { + // Concluded: + None => return Ok(()), + Some(r) => r, + }; + + initialized + .run(ctx, backend, Some(InitialData { participations, votes, leaf: first_leaf }), clock) + .await + } + + /// Make sure to recover participations properly on startup. + async fn initialize( + self, + ctx: &mut Context, + mut backend: B, + clock: &(dyn Clock), + ) -> FatalResult< + Option<( + Vec<(ParticipationPriority, ParticipationRequest)>, + Vec, + ActivatedLeaf, + Initialized, + B, + )>, + > + where + B: Backend + 'static, + { + loop { + let first_leaf = match wait_for_first_leaf(ctx).await { + Ok(Some(activated_leaf)) => activated_leaf, + Ok(None) => continue, + Err(e) => { + e.split()?.log(); + continue + }, + }; + + // `RuntimeInfo` cache should match `DISPUTE_WINDOW` so that we can + // keep all sessions for a dispute window + let mut runtime_info = RuntimeInfo::new_with_config(RuntimeInfoConfig { + keystore: None, + session_cache_lru_size: NonZeroUsize::new(DISPUTE_WINDOW.get() as usize) + .expect("DISPUTE_WINDOW can't be 0; qed."), + }); + let mut overlay_db = OverlayedBackend::new(&mut backend); + let ( + participations, + votes, + spam_slots, + ordering_provider, + highest_session_seen, + gaps_in_cache, + ) = match self + .handle_startup(ctx, first_leaf.clone(), &mut runtime_info, &mut overlay_db, clock) + .await + { + Ok(v) => v, + Err(e) => { + e.split()?.log(); + continue + }, + }; + if !overlay_db.is_empty() { + let ops = overlay_db.into_write_ops(); + backend.write(ops)?; + } + + return Ok(Some(( + participations, + votes, + first_leaf, + Initialized::new( + self, + runtime_info, + spam_slots, + ordering_provider, + highest_session_seen, + gaps_in_cache, + ), + backend, + ))) + } + } + + // Restores the subsystem's state before proceeding with the main event loop. + // + // - Prune any old disputes. + // - Find disputes we need to participate in. + // - Initialize spam slots & OrderingProvider. + async fn handle_startup( + &self, + ctx: &mut Context, + initial_head: ActivatedLeaf, + runtime_info: &mut RuntimeInfo, + overlay_db: &mut OverlayedBackend<'_, impl Backend>, + clock: &dyn Clock, + ) -> Result<( + Vec<(ParticipationPriority, ParticipationRequest)>, + Vec, + SpamSlots, + ChainScraper, + SessionIndex, + bool, + )> { + let now = clock.now(); + + let active_disputes = match overlay_db.load_recent_disputes() { + Ok(disputes) => disputes + .map(|disputes| get_active_with_status(disputes.into_iter(), now)) + .into_iter() + .flatten(), + Err(e) => { + gum::error!(target: LOG_TARGET, "Failed initial load of recent disputes: {:?}", e); + return Err(e.into()) + }, + }; + + // We assume the highest session is the passed leaf. If we can't get the session index + // we can't initialize the subsystem so we'll wait for a new leaf + let highest_session = runtime_info + .get_session_index_for_child(ctx.sender(), initial_head.hash) + .await?; + + let mut gap_in_cache = false; + // Cache the sessions. A failure to fetch a session here is not that critical so we + // won't abort the initialization + for idx in highest_session.saturating_sub(DISPUTE_WINDOW.get() - 1)..=highest_session { + if let Err(e) = runtime_info + .get_session_info_by_index(ctx.sender(), initial_head.hash, idx) + .await + { + gum::debug!( + target: LOG_TARGET, + leaf_hash = ?initial_head.hash, + session_idx = idx, + err = ?e, + "Can't cache SessionInfo during subsystem initialization. Skipping session." + ); + gap_in_cache = true; + continue + }; + } + + // Prune obsolete disputes: + db::v1::note_earliest_session( + overlay_db, + highest_session.saturating_sub(DISPUTE_WINDOW.get() - 1), + )?; + + let mut participation_requests = Vec::new(); + let mut spam_disputes: UnconfirmedDisputes = UnconfirmedDisputes::new(); + let leaf_hash = initial_head.hash; + let (scraper, votes) = ChainScraper::new(ctx.sender(), initial_head).await?; + for ((session, ref candidate_hash), _) in active_disputes { + let env = match CandidateEnvironment::new( + &self.keystore, + ctx, + runtime_info, + highest_session, + leaf_hash, + ) + .await + { + None => { + gum::warn!( + target: LOG_TARGET, + session, + "We are lacking a `SessionInfo` for handling db votes on startup." + ); + + continue + }, + Some(env) => env, + }; + + let votes: CandidateVotes = + match overlay_db.load_candidate_votes(session, candidate_hash) { + Ok(Some(votes)) => votes.into(), + Ok(None) => continue, + Err(e) => { + gum::error!( + target: LOG_TARGET, + "Failed initial load of candidate votes: {:?}", + e + ); + continue + }, + }; + let vote_state = CandidateVoteState::new(votes, &env, now); + + let potential_spam = is_potential_spam(&scraper, &vote_state, candidate_hash); + let is_included = + scraper.is_candidate_included(&vote_state.votes().candidate_receipt.hash()); + + if potential_spam { + gum::trace!( + target: LOG_TARGET, + ?session, + ?candidate_hash, + "Found potential spam dispute on startup" + ); + spam_disputes + .insert((session, *candidate_hash), vote_state.votes().voted_indices()); + } else { + // Participate if need be: + if vote_state.own_vote_missing() { + gum::trace!( + target: LOG_TARGET, + ?session, + ?candidate_hash, + "Found valid dispute, with no vote from us on startup - participating." + ); + let request_timer = self.metrics.time_participation_pipeline(); + participation_requests.push(( + ParticipationPriority::with_priority_if(is_included), + ParticipationRequest::new( + vote_state.votes().candidate_receipt.clone(), + session, + request_timer, + ), + )); + } + // Else make sure our own vote is distributed: + else { + gum::trace!( + target: LOG_TARGET, + ?session, + ?candidate_hash, + "Found valid dispute, with vote from us on startup - send vote." + ); + send_dispute_messages(ctx, &env, &vote_state).await; + } + } + } + + Ok(( + participation_requests, + votes, + SpamSlots::recover_from_state(spam_disputes), + scraper, + highest_session, + gap_in_cache, + )) + } +} + +/// Wait for `ActiveLeavesUpdate`, returns `None` if `Conclude` signal came first. +#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)] +async fn wait_for_first_leaf(ctx: &mut Context) -> Result> { + loop { + match ctx.recv().await? { + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(None), + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => { + if let Some(activated) = update.activated { + return Ok(Some(activated)) + } + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(_, _)) => {}, + FromOrchestra::Communication { msg } => + // NOTE: We could technically actually handle a couple of message types, even if + // not initialized (e.g. all requests that only query the database). The problem + // is, we would deliver potentially outdated information, especially in the event + // of bugs where initialization fails for a while (e.g. `SessionInfo`s are not + // available). So instead of telling subsystems, everything is fine, because of an + // hour old database state, we should rather cancel contained oneshots and delay + // finality until we are fully functional. + { + gum::warn!( + target: LOG_TARGET, + ?msg, + "Received msg before first active leaves update. This is not expected - message will be dropped." + ) + }, + } + } +} + +/// Check wheter a dispute for the given candidate could be spam. +/// +/// That is the candidate could be made up. +pub fn is_potential_spam( + scraper: &ChainScraper, + vote_state: &CandidateVoteState, + candidate_hash: &CandidateHash, +) -> bool { + let is_disputed = vote_state.is_disputed(); + let is_included = scraper.is_candidate_included(candidate_hash); + let is_backed = scraper.is_candidate_backed(candidate_hash); + let is_confirmed = vote_state.is_confirmed(); + + is_disputed && !is_included && !is_backed && !is_confirmed +} + +/// Tell dispute-distribution to send all our votes. +/// +/// Should be called on startup for all active disputes where there are votes from us already. +#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)] +async fn send_dispute_messages( + ctx: &mut Context, + env: &CandidateEnvironment<'_>, + vote_state: &CandidateVoteState, +) { + for own_vote in vote_state.own_votes().into_iter().flatten() { + let (validator_index, (kind, sig)) = own_vote; + let public_key = if let Some(key) = env.session_info().validators.get(*validator_index) { + key.clone() + } else { + gum::error!( + target: LOG_TARGET, + ?validator_index, + session_index = ?env.session_index(), + "Could not find our own key in `SessionInfo`" + ); + continue + }; + let our_vote_signed = SignedDisputeStatement::new_checked( + kind.clone(), + vote_state.votes().candidate_receipt.hash(), + env.session_index(), + public_key, + sig.clone(), + ); + let our_vote_signed = match our_vote_signed { + Ok(signed) => signed, + Err(()) => { + gum::error!( + target: LOG_TARGET, + "Checking our own signature failed - db corruption?" + ); + continue + }, + }; + let dispute_message = match make_dispute_message( + env.session_info(), + vote_state.votes(), + our_vote_signed, + *validator_index, + ) { + Err(err) => { + gum::debug!(target: LOG_TARGET, ?err, "Creating dispute message failed."); + continue + }, + Ok(dispute_message) => dispute_message, + }; + + ctx.send_message(DisputeDistributionMessage::SendDispute(dispute_message)).await; + } +} + +#[derive(Debug, thiserror::Error)] +pub enum DisputeMessageCreationError { + #[error("There was no opposite vote available")] + NoOppositeVote, + #[error("Found vote had an invalid validator index that could not be found")] + InvalidValidatorIndex, + #[error("Statement found in votes had invalid signature.")] + InvalidStoredStatement, + #[error(transparent)] + InvalidStatementCombination(DisputeMessageCheckError), +} + +/// Create a `DisputeMessage` to be sent to `DisputeDistribution`. +pub fn make_dispute_message( + info: &SessionInfo, + votes: &CandidateVotes, + our_vote: SignedDisputeStatement, + our_index: ValidatorIndex, +) -> std::result::Result { + let validators = &info.validators; + + let (valid_statement, valid_index, invalid_statement, invalid_index) = + if let DisputeStatement::Valid(_) = our_vote.statement() { + let (validator_index, (statement_kind, validator_signature)) = + votes.invalid.iter().next().ok_or(DisputeMessageCreationError::NoOppositeVote)?; + let other_vote = SignedDisputeStatement::new_checked( + DisputeStatement::Invalid(*statement_kind), + *our_vote.candidate_hash(), + our_vote.session_index(), + validators + .get(*validator_index) + .ok_or(DisputeMessageCreationError::InvalidValidatorIndex)? + .clone(), + validator_signature.clone(), + ) + .map_err(|()| DisputeMessageCreationError::InvalidStoredStatement)?; + (our_vote, our_index, other_vote, *validator_index) + } else { + let (validator_index, (statement_kind, validator_signature)) = votes + .valid + .raw() + .iter() + .next() + .ok_or(DisputeMessageCreationError::NoOppositeVote)?; + let other_vote = SignedDisputeStatement::new_checked( + DisputeStatement::Valid(*statement_kind), + *our_vote.candidate_hash(), + our_vote.session_index(), + validators + .get(*validator_index) + .ok_or(DisputeMessageCreationError::InvalidValidatorIndex)? + .clone(), + validator_signature.clone(), + ) + .map_err(|()| DisputeMessageCreationError::InvalidStoredStatement)?; + (other_vote, *validator_index, our_vote, our_index) + }; + + DisputeMessage::from_signed_statements( + valid_statement, + valid_index, + invalid_statement, + invalid_index, + votes.candidate_receipt.clone(), + info, + ) + .map_err(DisputeMessageCreationError::InvalidStatementCombination) +} diff --git a/polkadot/node/core/dispute-coordinator/src/metrics.rs b/polkadot/node/core/dispute-coordinator/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..c9454fb1d3ceedfeeed187f45717f2633c3657a9 --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/metrics.rs @@ -0,0 +1,237 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +struct MetricsInner { + /// Number of opened disputes. + open: prometheus::Counter, + /// Votes of all disputes. + votes: prometheus::CounterVec, + /// Number of approval votes explicitly fetched from approval voting. + approval_votes: prometheus::Counter, + /// Conclusion across all disputes. + concluded: prometheus::CounterVec, + /// Number of participations that have been queued. + queued_participations: prometheus::CounterVec, + /// How long vote cleanup batches take. + vote_cleanup_time: prometheus::Histogram, + /// Number of refrained participations. + refrained_participations: prometheus::Counter, + /// Distribution of participation durations. + participation_durations: prometheus::Histogram, + /// Measures the duration of the full participation pipeline: From when + /// a participation request is first queued to when participation in the + /// requested dispute is complete. + participation_pipeline_durations: prometheus::Histogram, + /// Size of participation priority queue + participation_priority_queue_size: prometheus::Gauge, + /// Size of participation best effort queue + participation_best_effort_queue_size: prometheus::Gauge, +} + +/// Candidate validation metrics. +#[derive(Default, Clone)] +pub struct Metrics(Option); + +impl Metrics { + pub(crate) fn on_open(&self) { + if let Some(metrics) = &self.0 { + metrics.open.inc(); + } + } + + pub(crate) fn on_valid_votes(&self, vote_count: u32) { + if let Some(metrics) = &self.0 { + metrics.votes.with_label_values(&["valid"]).inc_by(vote_count as _); + } + } + + pub(crate) fn on_invalid_votes(&self, vote_count: u32) { + if let Some(metrics) = &self.0 { + metrics.votes.with_label_values(&["invalid"]).inc_by(vote_count as _); + } + } + + pub(crate) fn on_approval_votes(&self, vote_count: u32) { + if let Some(metrics) = &self.0 { + metrics.approval_votes.inc_by(vote_count as _); + } + } + + pub(crate) fn on_concluded_valid(&self) { + if let Some(metrics) = &self.0 { + metrics.concluded.with_label_values(&["valid"]).inc(); + } + } + + pub(crate) fn on_concluded_invalid(&self) { + if let Some(metrics) = &self.0 { + metrics.concluded.with_label_values(&["invalid"]).inc(); + } + } + + pub(crate) fn on_queued_priority_participation(&self) { + if let Some(metrics) = &self.0 { + metrics.queued_participations.with_label_values(&["priority"]).inc(); + } + } + + pub(crate) fn on_queued_best_effort_participation(&self) { + if let Some(metrics) = &self.0 { + metrics.queued_participations.with_label_values(&["best-effort"]).inc(); + } + } + + pub(crate) fn time_vote_cleanup(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.vote_cleanup_time.start_timer()) + } + + pub(crate) fn on_refrained_participation(&self) { + if let Some(metrics) = &self.0 { + metrics.refrained_participations.inc(); + } + } + + /// Provide a timer for participation durations which updates on drop. + pub(crate) fn time_participation( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.participation_durations.start_timer()) + } + + /// Provide a timer for participation pipeline durations which updates on drop. + pub(crate) fn time_participation_pipeline( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.participation_pipeline_durations.start_timer()) + } + + /// Set the `priority_queue_size` metric + pub fn report_priority_queue_size(&self, size: u64) { + if let Some(metrics) = &self.0 { + metrics.participation_priority_queue_size.set(size); + } + } + + /// Set the `best_effort_queue_size` metric + pub fn report_best_effort_queue_size(&self, size: u64) { + if let Some(metrics) = &self.0 { + metrics.participation_best_effort_queue_size.set(size); + } + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + open: prometheus::register( + prometheus::Counter::with_opts(prometheus::Opts::new( + "polkadot_parachain_candidate_disputes_total", + "Total number of raised disputes.", + ))?, + registry, + )?, + concluded: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_candidate_dispute_concluded", + "Concluded dispute votes, sorted by candidate is `valid` and `invalid`.", + ), + &["validity"], + )?, + registry, + )?, + votes: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_candidate_dispute_votes", + "Accumulated dispute votes, sorted by candidate is `valid` and `invalid`.", + ), + &["validity"], + )?, + registry, + )?, + approval_votes: prometheus::register( + prometheus::Counter::with_opts(prometheus::Opts::new( + "polkadot_parachain_dispute_candidate_approval_votes_fetched_total", + "Number of approval votes fetched from approval voting.", + ))?, + registry, + )?, + queued_participations: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_dispute_participations", + "Total number of queued participations, grouped by priority and best-effort. (Not every queueing will necessarily lead to an actual participation because of duplicates.)", + ), + &["priority"], + )?, + registry, + )?, + vote_cleanup_time: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_dispute_coordinator_vote_cleanup", + "Time spent cleaning up old votes per batch.", + ) + .buckets([0.01, 0.1, 0.5, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0].into()), + )?, + registry, + )?, + refrained_participations: prometheus::register( + prometheus::Counter::with_opts( + prometheus::Opts::new( + "polkadot_parachain_dispute_refrained_participations", + "Number of refrained participations. We refrain from participation if all of the following conditions are met: disputed candidate is not included, not backed and not confirmed.", + ))?, + registry, + )?, + participation_durations: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_dispute_participation_durations", + "Time spent within fn Participation::participate", + ) + )?, + registry, + )?, + participation_pipeline_durations: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_dispute_participation_pipeline_durations", + "Measures the duration of the full participation pipeline: From when a participation request is first queued to when participation in the requested dispute is complete.", + ) + )?, + registry, + )?, + participation_priority_queue_size: prometheus::register( + prometheus::Gauge::new("polkadot_parachain_dispute_participation_priority_queue_size", + "Number of disputes waiting for local participation in the priority queue.")?, + registry, + )?, + participation_best_effort_queue_size: prometheus::register( + prometheus::Gauge::new("polkadot_parachain_dispute_participation_best_effort_queue_size", + "Number of disputes waiting for local participation in the best effort queue.")?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/core/dispute-coordinator/src/participation/mod.rs b/polkadot/node/core/dispute-coordinator/src/participation/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..25b7352807f6b540c0de0973800ecb6ce983804e --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/participation/mod.rs @@ -0,0 +1,426 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::collections::HashSet; +#[cfg(test)] +use std::time::Duration; + +use futures::{ + channel::{mpsc, oneshot}, + FutureExt, SinkExt, +}; +#[cfg(test)] +use futures_timer::Delay; + +use polkadot_node_primitives::ValidationResult; +use polkadot_node_subsystem::{ + messages::{AvailabilityRecoveryMessage, CandidateValidationMessage}, + overseer, ActiveLeavesUpdate, RecoveryError, +}; +use polkadot_node_subsystem_util::runtime::get_validation_code_by_hash; +use polkadot_primitives::{ + BlockNumber, CandidateHash, CandidateReceipt, Hash, PvfExecTimeoutKind, SessionIndex, +}; + +use crate::LOG_TARGET; + +use crate::error::{FatalError, FatalResult, Result}; + +#[cfg(test)] +mod tests; +#[cfg(test)] +pub use tests::{participation_full_happy_path, participation_missing_availability}; + +mod queues; +use queues::Queues; +pub use queues::{ParticipationPriority, ParticipationRequest, QueueError}; + +use crate::metrics::Metrics; +use polkadot_node_subsystem_util::metrics::prometheus::prometheus; + +/// How many participation processes do we want to run in parallel the most. +/// +/// This should be a relatively low value, while we might have a speedup once we fetched the data, +/// due to multi-core architectures, but the fetching itself can not be improved by parallel +/// requests. This means that higher numbers make it harder for a single dispute to resolve fast. +#[cfg(not(test))] +const MAX_PARALLEL_PARTICIPATIONS: usize = 3; +#[cfg(test)] +pub(crate) const MAX_PARALLEL_PARTICIPATIONS: usize = 1; + +/// Keep track of disputes we need to participate in. +/// +/// - Prioritize and queue participations +/// - Dequeue participation requests in order and launch participation worker. +pub struct Participation { + /// Participations currently being processed. + running_participations: HashSet, + /// Priority and best effort queues. + queue: Queues, + /// Sender to be passed to worker tasks. + worker_sender: WorkerMessageSender, + /// Some recent block for retrieving validation code from chain. + recent_block: Option<(BlockNumber, Hash)>, + /// Metrics handle cloned from Initialized + metrics: Metrics, +} + +/// Message from worker tasks. +#[derive(Debug)] +pub struct WorkerMessage(ParticipationStatement); + +/// Sender use by worker tasks. +pub type WorkerMessageSender = mpsc::Sender; + +/// Receiver to receive messages from worker tasks. +pub type WorkerMessageReceiver = mpsc::Receiver; + +/// Statement as result of the validation process. +#[derive(Debug)] +pub struct ParticipationStatement { + /// Relevant session. + pub session: SessionIndex, + /// The candidate the worker has been spawned for. + pub candidate_hash: CandidateHash, + /// Used receipt. + pub candidate_receipt: CandidateReceipt, + /// Actual result. + pub outcome: ParticipationOutcome, +} + +/// Outcome of the validation process. +#[derive(Copy, Clone, Debug)] +pub enum ParticipationOutcome { + /// Candidate was found to be valid. + Valid, + /// Candidate was found to be invalid. + Invalid, + /// Candidate was found to be unavailable. + Unavailable, + /// Something went wrong (bug), details can be found in the logs. + Error, +} + +impl ParticipationOutcome { + /// If validation was successful, get whether the candidate was valid or invalid. + pub fn validity(self) -> Option { + match self { + Self::Valid => Some(true), + Self::Invalid => Some(false), + Self::Unavailable | Self::Error => None, + } + } +} + +impl WorkerMessage { + fn from_request(req: ParticipationRequest, outcome: ParticipationOutcome) -> Self { + let session = req.session(); + let (candidate_hash, candidate_receipt) = req.into_candidate_info(); + Self(ParticipationStatement { session, candidate_hash, candidate_receipt, outcome }) + } +} + +#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)] +impl Participation { + /// Get ready for managing dispute participation requests. + /// + /// The passed in sender will be used by background workers to communicate back their results. + /// The calling context should make sure to call `Participation::on_worker_message()` for the + /// received messages. + pub fn new(sender: WorkerMessageSender, metrics: Metrics) -> Self { + Self { + running_participations: HashSet::new(), + queue: Queues::new(metrics.clone()), + worker_sender: sender, + recent_block: None, + metrics, + } + } + + /// Queue a dispute for the node to participate in. + /// + /// If capacity is available right now and we already got some relay chain head via + /// `on_active_leaves_update`, the participation will be launched right away. + /// + /// Returns: false, if queues are already full. + pub async fn queue_participation( + &mut self, + ctx: &mut Context, + priority: ParticipationPriority, + mut req: ParticipationRequest, + ) -> Result<()> { + // Participation already running - we can ignore that request, discarding its timer: + if self.running_participations.contains(req.candidate_hash()) { + req.discard_timer(); + return Ok(()) + } + // Available capacity - participate right away (if we already have a recent block): + if let Some((_, h)) = self.recent_block { + if self.running_participations.len() < MAX_PARALLEL_PARTICIPATIONS { + self.fork_participation(ctx, req, h)?; + return Ok(()) + } + } + // Out of capacity/no recent block yet - queue: + self.queue.queue(ctx.sender(), priority, req).await + } + + /// Message from a worker task was received - get the outcome. + /// + /// Call this function to keep participations going and to receive `ParticipationStatement`s. + /// + /// This message has to be called for each received worker message, in order to make sure + /// enough participation processes are running at any given time. + /// + /// Returns: The received `ParticipationStatement` or a fatal error, in case + /// something went wrong when dequeuing more requests (tasks could not be spawned). + pub async fn get_participation_result( + &mut self, + ctx: &mut Context, + msg: WorkerMessage, + ) -> FatalResult { + let WorkerMessage(statement) = msg; + self.running_participations.remove(&statement.candidate_hash); + let recent_block = self.recent_block.expect("We never ever reset recent_block to `None` and we already received a result, so it must have been set before. qed."); + self.dequeue_until_capacity(ctx, recent_block.1).await?; + Ok(statement) + } + + /// Process active leaves update. + /// + /// Make sure we to dequeue participations if that became possible and update most recent + /// block. + pub async fn process_active_leaves_update( + &mut self, + ctx: &mut Context, + update: &ActiveLeavesUpdate, + ) -> FatalResult<()> { + if let Some(activated) = &update.activated { + match self.recent_block { + None => { + self.recent_block = Some((activated.number, activated.hash)); + // Work got potentially unblocked: + self.dequeue_until_capacity(ctx, activated.hash).await?; + }, + Some((number, _)) if activated.number > number => { + self.recent_block = Some((activated.number, activated.hash)); + }, + Some(_) => {}, + } + } + Ok(()) + } + + /// Moving any request concerning the given candidates from best-effort to + /// priority, ignoring any candidates that don't have any queued participation requests. + pub async fn bump_to_priority_for_candidates( + &mut self, + ctx: &mut Context, + included_receipts: &Vec, + ) -> Result<()> { + for receipt in included_receipts { + self.queue.prioritize_if_present(ctx.sender(), receipt).await?; + } + Ok(()) + } + + /// Dequeue until `MAX_PARALLEL_PARTICIPATIONS` is reached. + async fn dequeue_until_capacity( + &mut self, + ctx: &mut Context, + recent_head: Hash, + ) -> FatalResult<()> { + while self.running_participations.len() < MAX_PARALLEL_PARTICIPATIONS { + if let Some(req) = self.queue.dequeue() { + self.fork_participation(ctx, req, recent_head)?; + } else { + break + } + } + Ok(()) + } + + /// Fork a participation task in the background. + fn fork_participation( + &mut self, + ctx: &mut Context, + req: ParticipationRequest, + recent_head: Hash, + ) -> FatalResult<()> { + let participation_timer = self.metrics.time_participation(); + if self.running_participations.insert(*req.candidate_hash()) { + let sender = ctx.sender().clone(); + ctx.spawn( + "participation-worker", + participate( + self.worker_sender.clone(), + sender, + recent_head, + req, + participation_timer, + ) + .boxed(), + ) + .map_err(FatalError::SpawnFailed)?; + } + Ok(()) + } +} + +async fn participate( + mut result_sender: WorkerMessageSender, + mut sender: impl overseer::DisputeCoordinatorSenderTrait, + block_hash: Hash, + req: ParticipationRequest, // Sends metric data via request_timer field when dropped + _participation_timer: Option, // Sends metric data when dropped +) { + #[cfg(test)] + // Hack for tests, so we get recovery messages not too early. + Delay::new(Duration::from_millis(100)).await; + // in order to validate a candidate we need to start by recovering the + // available data + let (recover_available_data_tx, recover_available_data_rx) = oneshot::channel(); + sender + .send_message(AvailabilityRecoveryMessage::RecoverAvailableData( + req.candidate_receipt().clone(), + req.session(), + None, + recover_available_data_tx, + )) + .await; + + let available_data = match recover_available_data_rx.await { + Err(oneshot::Canceled) => { + gum::warn!( + target: LOG_TARGET, + "`Oneshot` got cancelled when recovering available data {:?}", + req.candidate_hash(), + ); + send_result(&mut result_sender, req, ParticipationOutcome::Error).await; + return + }, + Ok(Ok(data)) => data, + Ok(Err(RecoveryError::Invalid)) => { + // the available data was recovered but it is invalid, therefore we'll + // vote negatively for the candidate dispute + send_result(&mut result_sender, req, ParticipationOutcome::Invalid).await; + return + }, + Ok(Err(RecoveryError::Unavailable)) | Ok(Err(RecoveryError::ChannelClosed)) => { + send_result(&mut result_sender, req, ParticipationOutcome::Unavailable).await; + return + }, + }; + + // we also need to fetch the validation code which we can reference by its + // hash as taken from the candidate descriptor + let validation_code = match get_validation_code_by_hash( + &mut sender, + block_hash, + req.candidate_receipt().descriptor.validation_code_hash, + ) + .await + { + Ok(Some(code)) => code, + Ok(None) => { + gum::warn!( + target: LOG_TARGET, + "Validation code unavailable for code hash {:?} in the state of block {:?}", + req.candidate_receipt().descriptor.validation_code_hash, + block_hash, + ); + + send_result(&mut result_sender, req, ParticipationOutcome::Error).await; + return + }, + Err(err) => { + gum::warn!(target: LOG_TARGET, ?err, "Error when fetching validation code."); + send_result(&mut result_sender, req, ParticipationOutcome::Error).await; + return + }, + }; + + // Issue a request to validate the candidate with the provided exhaustive + // parameters + // + // We use the approval execution timeout because this is intended to + // be run outside of backing and therefore should be subject to the + // same level of leeway. + let (validation_tx, validation_rx) = oneshot::channel(); + sender + .send_message(CandidateValidationMessage::ValidateFromExhaustive( + available_data.validation_data, + validation_code, + req.candidate_receipt().clone(), + available_data.pov, + PvfExecTimeoutKind::Approval, + validation_tx, + )) + .await; + + // we cast votes (either positive or negative) depending on the outcome of + // the validation and if valid, whether the commitments hash matches + match validation_rx.await { + Err(oneshot::Canceled) => { + gum::warn!( + target: LOG_TARGET, + "`Oneshot` got cancelled when validating candidate {:?}", + req.candidate_hash(), + ); + send_result(&mut result_sender, req, ParticipationOutcome::Error).await; + return + }, + Ok(Err(err)) => { + gum::warn!( + target: LOG_TARGET, + "Candidate {:?} validation failed with: {:?}", + req.candidate_hash(), + err, + ); + + send_result(&mut result_sender, req, ParticipationOutcome::Error).await; + }, + + Ok(Ok(ValidationResult::Invalid(invalid))) => { + gum::warn!( + target: LOG_TARGET, + "Candidate {:?} considered invalid: {:?}", + req.candidate_hash(), + invalid, + ); + + send_result(&mut result_sender, req, ParticipationOutcome::Invalid).await; + }, + Ok(Ok(ValidationResult::Valid(_, _))) => { + send_result(&mut result_sender, req, ParticipationOutcome::Valid).await; + }, + } +} + +/// Helper function for sending the result back and report any error. +async fn send_result( + sender: &mut WorkerMessageSender, + req: ParticipationRequest, + outcome: ParticipationOutcome, +) { + if let Err(err) = sender.feed(WorkerMessage::from_request(req, outcome)).await { + gum::error!( + target: LOG_TARGET, + ?err, + "Sending back participation result failed. Dispute coordinator not working properly!" + ); + } +} diff --git a/polkadot/node/core/dispute-coordinator/src/participation/queues/mod.rs b/polkadot/node/core/dispute-coordinator/src/participation/queues/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..8a4374999f88392c58eb60d5120a5b957090f9c9 --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/participation/queues/mod.rs @@ -0,0 +1,444 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{ + cmp::Ordering, + collections::{btree_map::Entry, BTreeMap}, +}; + +use futures::channel::oneshot; +use polkadot_node_subsystem::{messages::ChainApiMessage, overseer}; +use polkadot_primitives::{BlockNumber, CandidateHash, CandidateReceipt, Hash, SessionIndex}; + +use crate::{ + error::{FatalError, FatalResult, Result}, + LOG_TARGET, +}; + +use crate::metrics::Metrics; +use polkadot_node_subsystem_util::metrics::prometheus::prometheus; + +#[cfg(test)] +mod tests; + +/// How many potential garbage disputes we want to queue, before starting to drop requests. +#[cfg(not(test))] +const BEST_EFFORT_QUEUE_SIZE: usize = 100; +#[cfg(test)] +const BEST_EFFORT_QUEUE_SIZE: usize = 3; + +/// How many priority disputes can be queued. +/// +/// Once the queue exceeds that size, we will start to drop the newest participation requests in +/// the queue. Note that for each vote import the request will be re-added, if there is free +/// capacity. This limit just serves as a safe guard, it is not expected to ever really be reached. +/// +/// For 100 parachains, this would allow for every single candidate in 100 blocks on +/// two forks to get disputed, which should be plenty to deal with any realistic attack. +#[cfg(not(test))] +const PRIORITY_QUEUE_SIZE: usize = 20_000; +#[cfg(test)] +const PRIORITY_QUEUE_SIZE: usize = 2; + +/// Queues for dispute participation. +/// In both queues we have a strict ordering of candidates and participation will +/// happen in that order. Refer to `CandidateComparator` for details on the ordering. +pub struct Queues { + /// Set of best effort participation requests. + best_effort: BTreeMap, + + /// Priority queue. + priority: BTreeMap, + + /// Handle for recording queues data in metrics + metrics: Metrics, +} + +/// A dispute participation request that can be queued. +#[derive(Debug)] +pub struct ParticipationRequest { + candidate_hash: CandidateHash, + candidate_receipt: CandidateReceipt, + session: SessionIndex, + request_timer: Option, // Sends metric data when request is dropped +} + +/// Whether a `ParticipationRequest` should be put on best-effort or the priority queue. +#[derive(Debug)] +pub enum ParticipationPriority { + BestEffort, + Priority, +} + +impl ParticipationPriority { + /// Create `ParticipationPriority` with either `Priority` + /// + /// or `BestEffort`. + pub fn with_priority_if(is_priority: bool) -> Self { + if is_priority { + Self::Priority + } else { + Self::BestEffort + } + } + + /// Whether or not this is a priority entry. + /// + /// If false, it is best effort. + pub fn is_priority(&self) -> bool { + match self { + Self::Priority => true, + Self::BestEffort => false, + } + } +} + +/// What can go wrong when queuing a request. +#[derive(Debug, thiserror::Error)] +pub enum QueueError { + #[error("Request could not be queued, because best effort queue was already full.")] + BestEffortFull, + #[error("Request could not be queued, because priority queue was already full.")] + PriorityFull, +} + +impl ParticipationRequest { + /// Create a new `ParticipationRequest` to be queued. + pub fn new( + candidate_receipt: CandidateReceipt, + session: SessionIndex, + request_timer: Option, + ) -> Self { + Self { candidate_hash: candidate_receipt.hash(), candidate_receipt, session, request_timer } + } + + pub fn candidate_receipt(&'_ self) -> &'_ CandidateReceipt { + &self.candidate_receipt + } + pub fn candidate_hash(&'_ self) -> &'_ CandidateHash { + &self.candidate_hash + } + pub fn session(&self) -> SessionIndex { + self.session + } + pub fn discard_timer(&mut self) { + if let Some(timer) = self.request_timer.take() { + timer.stop_and_discard(); + } + } + pub fn into_candidate_info(self) -> (CandidateHash, CandidateReceipt) { + let Self { candidate_hash, candidate_receipt, .. } = self; + (candidate_hash, candidate_receipt) + } +} + +// We want to compare and clone participation requests in unit tests, so we +// only implement Eq and Clone for tests. +#[cfg(test)] +impl PartialEq for ParticipationRequest { + fn eq(&self, other: &Self) -> bool { + let ParticipationRequest { candidate_receipt, candidate_hash, session, request_timer: _ } = + self; + candidate_receipt == other.candidate_receipt() && + candidate_hash == other.candidate_hash() && + *session == other.session() + } +} +#[cfg(test)] +impl Eq for ParticipationRequest {} + +impl Queues { + /// Create new `Queues`. + pub fn new(metrics: Metrics) -> Self { + Self { best_effort: BTreeMap::new(), priority: BTreeMap::new(), metrics } + } + + /// Will put message in queue, either priority or best effort depending on priority. + /// + /// If the message was already previously present on best effort, it will be moved to priority + /// if it is considered priority now. + /// + /// Returns error in case a queue was found full already. + pub async fn queue( + &mut self, + sender: &mut impl overseer::DisputeCoordinatorSenderTrait, + priority: ParticipationPriority, + req: ParticipationRequest, + ) -> Result<()> { + let comparator = CandidateComparator::new(sender, &req.candidate_receipt).await?; + + self.queue_with_comparator(comparator, priority, req)?; + Ok(()) + } + + /// Get the next best request for dispute participation if any. + /// First the priority queue is considered and then the best effort one. + pub fn dequeue(&mut self) -> Option { + if let Some(req) = self.pop_priority() { + self.metrics.report_priority_queue_size(self.priority.len() as u64); + return Some(req.1) + } + if let Some(req) = self.pop_best_effort() { + self.metrics.report_best_effort_queue_size(self.best_effort.len() as u64); + return Some(req.1) + } + None + } + + /// Reprioritizes any participation requests pertaining to the + /// passed candidates from best effort to priority. + pub async fn prioritize_if_present( + &mut self, + sender: &mut impl overseer::DisputeCoordinatorSenderTrait, + receipt: &CandidateReceipt, + ) -> Result<()> { + let comparator = CandidateComparator::new(sender, receipt).await?; + self.prioritize_with_comparator(comparator)?; + Ok(()) + } + + fn prioritize_with_comparator( + &mut self, + comparator: CandidateComparator, + ) -> std::result::Result<(), QueueError> { + if self.priority.len() >= PRIORITY_QUEUE_SIZE { + return Err(QueueError::PriorityFull) + } + if let Some(request) = self.best_effort.remove(&comparator) { + self.priority.insert(comparator, request); + // Report changes to both queue sizes + self.metrics.report_priority_queue_size(self.priority.len() as u64); + self.metrics.report_best_effort_queue_size(self.best_effort.len() as u64); + } + Ok(()) + } + + /// Will put message in queue, either priority or best effort depending on priority. + /// + /// If the message was already previously present on best effort, it will be moved to priority + /// if it is considered priority now. + /// + /// Returns error in case a queue was found full already. + /// + /// # Request timers + /// + /// [`ParticipationRequest`]s contain request timers. + /// Where an old request would be replaced by a new one, we keep the old request. + /// This prevents request timers from resetting on each new request. + fn queue_with_comparator( + &mut self, + comparator: CandidateComparator, + priority: ParticipationPriority, + mut req: ParticipationRequest, + ) -> std::result::Result<(), QueueError> { + if priority.is_priority() { + if self.priority.len() >= PRIORITY_QUEUE_SIZE { + return Err(QueueError::PriorityFull) + } + // Remove any best effort entry, using it to replace our new + // request. + if let Some(older_request) = self.best_effort.remove(&comparator) { + req.discard_timer(); + req = older_request; + } + // Keeping old request if any. + match self.priority.entry(comparator) { + Entry::Occupied(_) => req.discard_timer(), + Entry::Vacant(vac) => { + vac.insert(req); + }, + } + self.metrics.report_priority_queue_size(self.priority.len() as u64); + self.metrics.report_best_effort_queue_size(self.best_effort.len() as u64); + } else { + if self.priority.contains_key(&comparator) { + // The candidate is already in priority queue - don't + // add in in best effort too. + return Ok(()) + } + if self.best_effort.len() >= BEST_EFFORT_QUEUE_SIZE { + return Err(QueueError::BestEffortFull) + } + // Keeping old request if any. + match self.best_effort.entry(comparator) { + Entry::Occupied(_) => req.discard_timer(), + Entry::Vacant(vac) => { + vac.insert(req); + }, + } + self.metrics.report_best_effort_queue_size(self.best_effort.len() as u64); + } + Ok(()) + } + + /// Get best from the best effort queue. + fn pop_best_effort(&mut self) -> Option<(CandidateComparator, ParticipationRequest)> { + return Self::pop_impl(&mut self.best_effort) + } + + /// Get best priority queue entry. + fn pop_priority(&mut self) -> Option<(CandidateComparator, ParticipationRequest)> { + return Self::pop_impl(&mut self.priority) + } + + // `pop_best_effort` and `pop_priority` do the same but on different `BTreeMap`s. This function + // has the extracted implementation + fn pop_impl( + target: &mut BTreeMap, + ) -> Option<(CandidateComparator, ParticipationRequest)> { + // Once https://github.com/rust-lang/rust/issues/62924 is there, we can use a simple: + // target.pop_first(). + if let Some((comparator, _)) = target.iter().next() { + let comparator = *comparator; + target + .remove(&comparator) + .map(|participation_request| (comparator, participation_request)) + } else { + None + } + } +} + +/// `Comparator` for ordering of disputes for candidates. +/// +/// This `comparator` makes it possible to order disputes based on age and to ensure some fairness +/// between chains in case of equally old disputes. +/// +/// Objective ordering between nodes is important in case of lots disputes, so nodes will pull in +/// the same direction and work on resolving the same disputes first. This ensures that we will +/// conclude some disputes, even if there are lots of them. While any objective ordering would +/// suffice for this goal, ordering by age ensures we are not only resolving disputes, but also +/// resolve the oldest one first, which are also the most urgent and important ones to resolve. +/// +/// Note: That by `oldest` we mean oldest in terms of relay chain block number, for any block +/// number that has not yet been finalized. If a block has been finalized already it should be +/// treated as low priority when it comes to disputes, as even in the case of a negative outcome, +/// we are already too late. The ordering mechanism here serves to prevent this from happening in +/// the first place. +#[derive(Copy, Clone)] +#[cfg_attr(test, derive(Debug))] +struct CandidateComparator { + /// Block number of the relay parent. It's wrapped in an `Option<>` because there are cases + /// when it can't be obtained. For example when the node is lagging behind and new leaves are + /// received with a slight delay. Candidates with unknown relay parent are treated with the + /// lowest priority. + /// + /// The order enforced by `CandidateComparator` is important because we want to participate in + /// the oldest disputes first. + /// + /// Note: In theory it would make more sense to use the `BlockNumber` of the including + /// block, as inclusion time is the actual relevant event when it comes to ordering. The + /// problem is, that a candidate can get included multiple times on forks, so the `BlockNumber` + /// of the including block is not unique. We could theoretically work around that problem, by + /// just using the lowest `BlockNumber` of all available including blocks - the problem is, + /// that is not stable. If a new fork appears after the fact, we would start ordering the same + /// candidate differently, which would result in the same candidate getting queued twice. + relay_parent_block_number: Option, + /// By adding the `CandidateHash`, we can guarantee a unique ordering across candidates with + /// the same relay parent block number. Candidates without `relay_parent_block_number` are + /// ordered by the `candidate_hash` (and treated with the lowest priority, as already + /// mentioned). + candidate_hash: CandidateHash, +} + +impl CandidateComparator { + /// Create a candidate comparator based on given (fake) values. + /// + /// Useful for testing. + #[cfg(test)] + pub fn new_dummy(block_number: Option, candidate_hash: CandidateHash) -> Self { + Self { relay_parent_block_number: block_number, candidate_hash } + } + + /// Create a candidate comparator for a given candidate. + /// + /// Returns: + /// - `Ok(CandidateComparator{Some(relay_parent_block_number), candidate_hash})` when the + /// relay parent can be obtained. This is the happy case. + /// - `Ok(CandidateComparator{None, candidate_hash})` in case the candidate's relay parent + /// can't be obtained. + /// - `FatalError` in case the chain API call fails with an unexpected error. + pub async fn new( + sender: &mut impl overseer::DisputeCoordinatorSenderTrait, + candidate: &CandidateReceipt, + ) -> FatalResult { + let candidate_hash = candidate.hash(); + let n = get_block_number(sender, candidate.descriptor().relay_parent).await?; + + if n.is_none() { + gum::warn!( + target: LOG_TARGET, + candidate_hash = ?candidate_hash, + "Candidate's relay_parent could not be found via chain API - `CandidateComparator` \ + with an empty relay parent block number will be provided!" + ); + } + + Ok(CandidateComparator { relay_parent_block_number: n, candidate_hash }) + } +} + +impl PartialEq for CandidateComparator { + fn eq(&self, other: &CandidateComparator) -> bool { + Ordering::Equal == self.cmp(other) + } +} + +impl Eq for CandidateComparator {} + +impl PartialOrd for CandidateComparator { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for CandidateComparator { + fn cmp(&self, other: &Self) -> Ordering { + return match (self.relay_parent_block_number, other.relay_parent_block_number) { + (None, None) => { + // No relay parents for both -> compare hashes + self.candidate_hash.cmp(&other.candidate_hash) + }, + (Some(self_relay_parent_block_num), Some(other_relay_parent_block_num)) => { + match self_relay_parent_block_num.cmp(&other_relay_parent_block_num) { + // if the relay parent is the same for both -> compare hashes + Ordering::Equal => self.candidate_hash.cmp(&other.candidate_hash), + // if not - return the result from comparing the relay parent block numbers + o => return o, + } + }, + (Some(_), None) => { + // Candidates with known relay parents are always with priority + Ordering::Less + }, + (None, Some(_)) => { + // Ditto + Ordering::Greater + }, + } + } +} + +async fn get_block_number( + sender: &mut impl overseer::DisputeCoordinatorSenderTrait, + relay_parent: Hash, +) -> FatalResult> { + let (tx, rx) = oneshot::channel(); + sender.send_message(ChainApiMessage::BlockNumber(relay_parent, tx)).await; + rx.await + .map_err(|_| FatalError::ChainApiSenderDropped)? + .map_err(FatalError::ChainApiAncestors) +} diff --git a/polkadot/node/core/dispute-coordinator/src/participation/queues/tests.rs b/polkadot/node/core/dispute-coordinator/src/participation/queues/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..d4f43639ce87f9091c5d4b5493c3e617850dbbb3 --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/participation/queues/tests.rs @@ -0,0 +1,213 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::{metrics::Metrics, ParticipationPriority}; +use ::test_helpers::{dummy_candidate_receipt, dummy_hash}; +use assert_matches::assert_matches; +use polkadot_primitives::{BlockNumber, Hash}; + +use super::{CandidateComparator, ParticipationRequest, QueueError, Queues}; + +/// Make a `ParticipationRequest` based on the given commitments hash. +fn make_participation_request(hash: Hash) -> ParticipationRequest { + let mut receipt = dummy_candidate_receipt(dummy_hash()); + // make it differ: + receipt.commitments_hash = hash; + let request_timer = Metrics::default().time_participation_pipeline(); + ParticipationRequest::new(receipt, 1, request_timer) +} + +/// Make dummy comparator for request, based on the given block number. +fn make_dummy_comparator( + req: &ParticipationRequest, + relay_parent: Option, +) -> CandidateComparator { + CandidateComparator::new_dummy(relay_parent, *req.candidate_hash()) +} + +/// Make a partial clone of the given `ParticipationRequest`, just missing +/// the `request_timer` field. We prefer this helper to implementing Clone +/// for `ParticipationRequest`, since we only clone requests in tests. +fn clone_request(request: &ParticipationRequest) -> ParticipationRequest { + ParticipationRequest { + candidate_receipt: request.candidate_receipt.clone(), + candidate_hash: request.candidate_hash, + session: request.session, + request_timer: None, + } +} + +/// Check that dequeuing acknowledges order. +/// +/// Any priority item will be dequeued before any best effort items, priority and best effort with +/// known parent block number items will be processed in order. Best effort items without known +/// parent block number should be treated with lowest priority. +#[test] +fn ordering_works_as_expected() { + let metrics = Metrics::default(); + let mut queue = Queues::new(metrics.clone()); + let req1 = make_participation_request(Hash::repeat_byte(0x01)); + let req_prio = make_participation_request(Hash::repeat_byte(0x02)); + let req3 = make_participation_request(Hash::repeat_byte(0x03)); + let req_prio_2 = make_participation_request(Hash::repeat_byte(0x04)); + let req5_unknown_parent = make_participation_request(Hash::repeat_byte(0x05)); + let req_full = make_participation_request(Hash::repeat_byte(0x06)); + let req_prio_full = make_participation_request(Hash::repeat_byte(0x07)); + queue + .queue_with_comparator( + make_dummy_comparator(&req1, Some(1)), + ParticipationPriority::BestEffort, + clone_request(&req1), + ) + .unwrap(); + queue + .queue_with_comparator( + make_dummy_comparator(&req_prio, Some(1)), + ParticipationPriority::Priority, + clone_request(&req_prio), + ) + .unwrap(); + queue + .queue_with_comparator( + make_dummy_comparator(&req3, Some(2)), + ParticipationPriority::BestEffort, + clone_request(&req3), + ) + .unwrap(); + queue + .queue_with_comparator( + make_dummy_comparator(&req_prio_2, Some(2)), + ParticipationPriority::Priority, + clone_request(&req_prio_2), + ) + .unwrap(); + queue + .queue_with_comparator( + make_dummy_comparator(&req5_unknown_parent, None), + ParticipationPriority::BestEffort, + clone_request(&req5_unknown_parent), + ) + .unwrap(); + assert_matches!( + queue.queue_with_comparator( + make_dummy_comparator(&req_prio_full, Some(3)), + ParticipationPriority::Priority, + req_prio_full, + ), + Err(QueueError::PriorityFull) + ); + assert_matches!( + queue.queue_with_comparator( + make_dummy_comparator(&req_full, Some(3)), + ParticipationPriority::BestEffort, + req_full, + ), + Err(QueueError::BestEffortFull) + ); + + // Prioritized queue is ordered correctly + assert_eq!(queue.dequeue(), Some(req_prio)); + assert_eq!(queue.dequeue(), Some(req_prio_2)); + // So is the best-effort + assert_eq!(queue.dequeue(), Some(req1)); + assert_eq!(queue.dequeue(), Some(req3)); + assert_eq!(queue.dequeue(), Some(req5_unknown_parent)); + + assert_matches!(queue.dequeue(), None); +} + +/// No matter how often a candidate gets queued, it should only ever get dequeued once. +#[test] +fn candidate_is_only_dequeued_once() { + let metrics = Metrics::default(); + let mut queue = Queues::new(metrics.clone()); + let req1 = make_participation_request(Hash::repeat_byte(0x01)); + let req_prio = make_participation_request(Hash::repeat_byte(0x02)); + let req_best_effort_then_prio = make_participation_request(Hash::repeat_byte(0x03)); + let req_prio_then_best_effort = make_participation_request(Hash::repeat_byte(0x04)); + + queue + .queue_with_comparator( + make_dummy_comparator(&req1, None), + ParticipationPriority::BestEffort, + clone_request(&req1), + ) + .unwrap(); + queue + .queue_with_comparator( + make_dummy_comparator(&req_prio, Some(1)), + ParticipationPriority::Priority, + clone_request(&req_prio), + ) + .unwrap(); + // Insert same best effort again: + queue + .queue_with_comparator( + make_dummy_comparator(&req1, None), + ParticipationPriority::BestEffort, + clone_request(&req1), + ) + .unwrap(); + // insert same prio again: + queue + .queue_with_comparator( + make_dummy_comparator(&req_prio, Some(1)), + ParticipationPriority::Priority, + clone_request(&req_prio), + ) + .unwrap(); + // Insert first as best effort: + queue + .queue_with_comparator( + make_dummy_comparator(&req_best_effort_then_prio, Some(2)), + ParticipationPriority::BestEffort, + clone_request(&req_best_effort_then_prio), + ) + .unwrap(); + // Then as prio: + queue + .queue_with_comparator( + make_dummy_comparator(&req_best_effort_then_prio, Some(2)), + ParticipationPriority::Priority, + clone_request(&req_best_effort_then_prio), + ) + .unwrap(); + + // Make space in prio: + assert_eq!(queue.dequeue(), Some(req_prio)); + + // Insert first as prio: + queue + .queue_with_comparator( + make_dummy_comparator(&req_prio_then_best_effort, Some(3)), + ParticipationPriority::Priority, + clone_request(&req_prio_then_best_effort), + ) + .unwrap(); + // Then as best effort: + queue + .queue_with_comparator( + make_dummy_comparator(&req_prio_then_best_effort, Some(3)), + ParticipationPriority::BestEffort, + clone_request(&req_prio_then_best_effort), + ) + .unwrap(); + + assert_eq!(queue.dequeue(), Some(req_best_effort_then_prio)); + assert_eq!(queue.dequeue(), Some(req_prio_then_best_effort)); + assert_eq!(queue.dequeue(), Some(req1)); + assert_matches!(queue.dequeue(), None); +} diff --git a/polkadot/node/core/dispute-coordinator/src/participation/tests.rs b/polkadot/node/core/dispute-coordinator/src/participation/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..32725a3ac658df73bc25536b99a89a712f82833b --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/participation/tests.rs @@ -0,0 +1,548 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use assert_matches::assert_matches; +use futures::StreamExt; +use polkadot_node_subsystem_util::TimeoutExt; +use std::{sync::Arc, time::Duration}; + +use sp_core::testing::TaskExecutor; + +use super::*; +use ::test_helpers::{ + dummy_candidate_commitments, dummy_candidate_receipt_bad_sig, dummy_digest, dummy_hash, +}; +use parity_scale_codec::Encode; +use polkadot_node_primitives::{AvailableData, BlockData, InvalidCandidate, PoV}; +use polkadot_node_subsystem::{ + jaeger, + messages::{ + AllMessages, ChainApiMessage, DisputeCoordinatorMessage, RuntimeApiMessage, + RuntimeApiRequest, + }, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, SpawnGlue, +}; +use polkadot_node_subsystem_test_helpers::{ + make_subsystem_context, TestSubsystemContext, TestSubsystemContextHandle, +}; +use polkadot_primitives::{ + BlakeTwo256, CandidateCommitments, HashT, Header, PersistedValidationData, ValidationCode, +}; + +type VirtualOverseer = TestSubsystemContextHandle; + +pub fn make_our_subsystem_context( + spawner: S, +) -> ( + TestSubsystemContext>, + TestSubsystemContextHandle, +) { + make_subsystem_context(spawner) +} + +#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)] +async fn participate(ctx: &mut Context, participation: &mut Participation) -> Result<()> { + let commitments = CandidateCommitments::default(); + participate_with_commitments_hash(ctx, participation, commitments.hash()).await +} + +#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)] +async fn participate_with_commitments_hash( + ctx: &mut Context, + participation: &mut Participation, + commitments_hash: Hash, +) -> Result<()> { + let candidate_receipt = { + let mut receipt = dummy_candidate_receipt_bad_sig(dummy_hash(), dummy_hash()); + receipt.commitments_hash = commitments_hash; + receipt + }; + let session = 1; + + let request_timer = participation.metrics.time_participation_pipeline(); + let req = ParticipationRequest::new(candidate_receipt, session, request_timer); + + participation + .queue_participation(ctx, ParticipationPriority::BestEffort, req) + .await +} + +#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)] +async fn activate_leaf( + ctx: &mut Context, + participation: &mut Participation, + block_number: BlockNumber, +) -> FatalResult<()> { + let block_header = Header { + parent_hash: BlakeTwo256::hash(&block_number.encode()), + number: block_number, + digest: dummy_digest(), + state_root: dummy_hash(), + extrinsics_root: dummy_hash(), + }; + + let block_hash = block_header.hash(); + + participation + .process_active_leaves_update( + ctx, + &ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: block_hash, + span: Arc::new(jaeger::Span::Disabled), + number: block_number, + status: LeafStatus::Fresh, + }), + ) + .await +} + +/// Full participation happy path as seen via the overseer. +pub async fn participation_full_happy_path( + ctx_handle: &mut VirtualOverseer, + expected_commitments_hash: Hash, +) { + recover_available_data(ctx_handle).await; + fetch_validation_code(ctx_handle).await; + + assert_matches!( + ctx_handle.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive(_, _, candidate_receipt, _, timeout, tx) + ) if timeout == PvfExecTimeoutKind::Approval => { + if expected_commitments_hash != candidate_receipt.commitments_hash { + tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch))).unwrap(); + } else { + tx.send(Ok(ValidationResult::Valid(dummy_candidate_commitments(None), PersistedValidationData::default()))).unwrap(); + } + }, + "overseer did not receive candidate validation message", + ); +} + +/// Full participation with failing availability recovery. +pub async fn participation_missing_availability(ctx_handle: &mut VirtualOverseer) { + assert_matches!( + ctx_handle.recv().await, + AllMessages::AvailabilityRecovery( + AvailabilityRecoveryMessage::RecoverAvailableData(_, _, _, tx) + ) => { + tx.send(Err(RecoveryError::Unavailable)).unwrap(); + }, + "overseer did not receive recover available data message", + ); +} + +async fn recover_available_data(virtual_overseer: &mut VirtualOverseer) { + let pov_block = PoV { block_data: BlockData(Vec::new()) }; + + let available_data = AvailableData { + pov: Arc::new(pov_block), + validation_data: PersistedValidationData::default(), + }; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityRecovery( + AvailabilityRecoveryMessage::RecoverAvailableData(_, _, _, tx) + ) => { + tx.send(Ok(available_data)).unwrap(); + }, + "overseer did not receive recover available data message", + ); +} + +/// Handles validation code fetch, returns the received relay parent hash. +async fn fetch_validation_code(virtual_overseer: &mut VirtualOverseer) -> Hash { + let validation_code = ValidationCode(Vec::new()); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::ValidationCodeByHash( + _, + tx, + ) + )) => { + tx.send(Ok(Some(validation_code))).unwrap(); + hash + }, + "overseer did not receive runtime API request for validation code", + ) +} + +#[test] +fn same_req_wont_get_queued_if_participation_is_already_running() { + futures::executor::block_on(async { + let (mut ctx, mut ctx_handle) = make_our_subsystem_context(TaskExecutor::new()); + + let (sender, mut worker_receiver) = mpsc::channel(1); + let mut participation = Participation::new(sender, Metrics::default()); + activate_leaf(&mut ctx, &mut participation, 10).await.unwrap(); + participate(&mut ctx, &mut participation).await.unwrap(); + for _ in 0..MAX_PARALLEL_PARTICIPATIONS { + participate(&mut ctx, &mut participation).await.unwrap(); + } + + assert_matches!( + ctx_handle.recv().await, + AllMessages::AvailabilityRecovery( + AvailabilityRecoveryMessage::RecoverAvailableData(_, _, _, tx) + ) => { + tx.send(Err(RecoveryError::Unavailable)).unwrap(); + }, + "overseer did not receive recover available data message", + ); + + let result = participation + .get_participation_result(&mut ctx, worker_receiver.next().await.unwrap()) + .await + .unwrap(); + + assert_matches!( + result.outcome, + ParticipationOutcome::Unavailable => {} + ); + + // we should not have any further results nor recovery requests: + assert_matches!(ctx_handle.recv().timeout(Duration::from_millis(10)).await, None); + assert_matches!(worker_receiver.next().timeout(Duration::from_millis(10)).await, None); + }) +} + +#[test] +fn reqs_get_queued_when_out_of_capacity() { + let (mut ctx, mut ctx_handle) = make_our_subsystem_context(TaskExecutor::new()); + + let test = async { + let (sender, mut worker_receiver) = mpsc::channel(1); + let mut participation = Participation::new(sender, Metrics::default()); + activate_leaf(&mut ctx, &mut participation, 10).await.unwrap(); + participate(&mut ctx, &mut participation).await.unwrap(); + for i in 0..MAX_PARALLEL_PARTICIPATIONS { + participate_with_commitments_hash( + &mut ctx, + &mut participation, + Hash::repeat_byte(i as _), + ) + .await + .unwrap(); + } + + for _ in 0..MAX_PARALLEL_PARTICIPATIONS + 1 { + let result = participation + .get_participation_result(&mut ctx, worker_receiver.next().await.unwrap()) + .await + .unwrap(); + assert_matches!( + result.outcome, + ParticipationOutcome::Unavailable => {} + ); + } + // we should not have any further recovery requests: + assert_matches!(worker_receiver.next().timeout(Duration::from_millis(10)).await, None); + }; + + let request_handler = async { + let mut recover_available_data_msg_count = 0; + let mut block_number_msg_count = 0; + + while recover_available_data_msg_count < MAX_PARALLEL_PARTICIPATIONS + 1 || + block_number_msg_count < 1 + { + match ctx_handle.recv().await { + AllMessages::AvailabilityRecovery( + AvailabilityRecoveryMessage::RecoverAvailableData(_, _, _, tx), + ) => { + tx.send(Err(RecoveryError::Unavailable)).unwrap(); + recover_available_data_msg_count += 1; + }, + AllMessages::ChainApi(ChainApiMessage::BlockNumber(_, tx)) => { + tx.send(Ok(None)).unwrap(); + block_number_msg_count += 1; + }, + _ => assert!(false, "Received unexpected message"), + } + } + + // we should not have any further results + assert_matches!(ctx_handle.recv().timeout(Duration::from_millis(10)).await, None); + }; + + futures::executor::block_on(async { + futures::join!(test, request_handler); + }); +} + +#[test] +fn reqs_get_queued_on_no_recent_block() { + let (mut ctx, mut ctx_handle) = make_our_subsystem_context(TaskExecutor::new()); + let (mut unblock_test, mut wait_for_verification) = mpsc::channel(0); + let test = async { + let (sender, _worker_receiver) = mpsc::channel(1); + let mut participation = Participation::new(sender, Metrics::default()); + participate(&mut ctx, &mut participation).await.unwrap(); + + // We have initiated participation but we'll block `active_leaf` so that we can check that + // the participation is queued in race-free way + let _ = wait_for_verification.next().await.unwrap(); + + activate_leaf(&mut ctx, &mut participation, 10).await.unwrap(); + }; + + // Responds to messages from the test and verifies its behaviour + let request_handler = async { + // If we receive `BlockNumber` request this implicitly proves that the participation is + // queued + assert_matches!( + ctx_handle.recv().await, + AllMessages::ChainApi(ChainApiMessage::BlockNumber(_, tx)) => { + tx.send(Ok(None)).unwrap(); + }, + "overseer did not receive `ChainApiMessage::BlockNumber` message", + ); + + assert!(ctx_handle.recv().timeout(Duration::from_millis(10)).await.is_none()); + + // No activity so the participation is queued => unblock the test + unblock_test.send(()).await.unwrap(); + + // after activating at least one leaf the recent block + // state should be available which should lead to trying + // to participate by first trying to recover the available + // data + assert_matches!( + ctx_handle.recv().await, + AllMessages::AvailabilityRecovery(AvailabilityRecoveryMessage::RecoverAvailableData( + .. + )), + "overseer did not receive recover available data message", + ); + }; + + futures::executor::block_on(async { + futures::join!(test, request_handler); + }); +} + +#[test] +fn cannot_participate_if_cannot_recover_available_data() { + futures::executor::block_on(async { + let (mut ctx, mut ctx_handle) = make_our_subsystem_context(TaskExecutor::new()); + + let (sender, mut worker_receiver) = mpsc::channel(1); + let mut participation = Participation::new(sender, Metrics::default()); + activate_leaf(&mut ctx, &mut participation, 10).await.unwrap(); + participate(&mut ctx, &mut participation).await.unwrap(); + + assert_matches!( + ctx_handle.recv().await, + AllMessages::AvailabilityRecovery( + AvailabilityRecoveryMessage::RecoverAvailableData(_, _, _, tx) + ) => { + tx.send(Err(RecoveryError::Unavailable)).unwrap(); + }, + "overseer did not receive recover available data message", + ); + let result = participation + .get_participation_result(&mut ctx, worker_receiver.next().await.unwrap()) + .await + .unwrap(); + assert_matches!( + result.outcome, + ParticipationOutcome::Unavailable => {} + ); + }) +} + +#[test] +fn cannot_participate_if_cannot_recover_validation_code() { + futures::executor::block_on(async { + let (mut ctx, mut ctx_handle) = make_our_subsystem_context(TaskExecutor::new()); + + let (sender, mut worker_receiver) = mpsc::channel(1); + let mut participation = Participation::new(sender, Metrics::default()); + activate_leaf(&mut ctx, &mut participation, 10).await.unwrap(); + participate(&mut ctx, &mut participation).await.unwrap(); + + recover_available_data(&mut ctx_handle).await; + + assert_matches!( + ctx_handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::ValidationCodeByHash( + _, + tx, + ) + )) => { + tx.send(Ok(None)).unwrap(); + }, + "overseer did not receive runtime API request for validation code", + ); + + let result = participation + .get_participation_result(&mut ctx, worker_receiver.next().await.unwrap()) + .await + .unwrap(); + assert_matches!( + result.outcome, + ParticipationOutcome::Error => {} + ); + }) +} + +#[test] +fn cast_invalid_vote_if_available_data_is_invalid() { + futures::executor::block_on(async { + let (mut ctx, mut ctx_handle) = make_our_subsystem_context(TaskExecutor::new()); + + let (sender, mut worker_receiver) = mpsc::channel(1); + let mut participation = Participation::new(sender, Metrics::default()); + activate_leaf(&mut ctx, &mut participation, 10).await.unwrap(); + participate(&mut ctx, &mut participation).await.unwrap(); + + assert_matches!( + ctx_handle.recv().await, + AllMessages::AvailabilityRecovery( + AvailabilityRecoveryMessage::RecoverAvailableData(_, _, _, tx) + ) => { + tx.send(Err(RecoveryError::Invalid)).unwrap(); + }, + "overseer did not receive recover available data message", + ); + + let result = participation + .get_participation_result(&mut ctx, worker_receiver.next().await.unwrap()) + .await + .unwrap(); + assert_matches!( + result.outcome, + ParticipationOutcome::Invalid => {} + ); + }) +} + +#[test] +fn cast_invalid_vote_if_validation_fails_or_is_invalid() { + futures::executor::block_on(async { + let (mut ctx, mut ctx_handle) = make_our_subsystem_context(TaskExecutor::new()); + + let (sender, mut worker_receiver) = mpsc::channel(1); + let mut participation = Participation::new(sender, Metrics::default()); + activate_leaf(&mut ctx, &mut participation, 10).await.unwrap(); + participate(&mut ctx, &mut participation).await.unwrap(); + + recover_available_data(&mut ctx_handle).await; + assert_eq!( + fetch_validation_code(&mut ctx_handle).await, + participation.recent_block.unwrap().1 + ); + + assert_matches!( + ctx_handle.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, timeout, tx) + ) if timeout == PvfExecTimeoutKind::Approval => { + tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::Timeout))).unwrap(); + }, + "overseer did not receive candidate validation message", + ); + + let result = participation + .get_participation_result(&mut ctx, worker_receiver.next().await.unwrap()) + .await + .unwrap(); + assert_matches!( + result.outcome, + ParticipationOutcome::Invalid => {} + ); + }) +} + +#[test] +fn cast_invalid_vote_if_commitments_dont_match() { + futures::executor::block_on(async { + let (mut ctx, mut ctx_handle) = make_our_subsystem_context(TaskExecutor::new()); + + let (sender, mut worker_receiver) = mpsc::channel(1); + let mut participation = Participation::new(sender, Metrics::default()); + activate_leaf(&mut ctx, &mut participation, 10).await.unwrap(); + participate(&mut ctx, &mut participation).await.unwrap(); + + recover_available_data(&mut ctx_handle).await; + assert_eq!( + fetch_validation_code(&mut ctx_handle).await, + participation.recent_block.unwrap().1 + ); + + assert_matches!( + ctx_handle.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, timeout, tx) + ) if timeout == PvfExecTimeoutKind::Approval => { + tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch))).unwrap(); + }, + "overseer did not receive candidate validation message", + ); + + let result = participation + .get_participation_result(&mut ctx, worker_receiver.next().await.unwrap()) + .await + .unwrap(); + assert_matches!( + result.outcome, + ParticipationOutcome::Invalid => {} + ); + }) +} + +#[test] +fn cast_valid_vote_if_validation_passes() { + futures::executor::block_on(async { + let (mut ctx, mut ctx_handle) = make_our_subsystem_context(TaskExecutor::new()); + + let (sender, mut worker_receiver) = mpsc::channel(1); + let mut participation = Participation::new(sender, Metrics::default()); + activate_leaf(&mut ctx, &mut participation, 10).await.unwrap(); + participate(&mut ctx, &mut participation).await.unwrap(); + + recover_available_data(&mut ctx_handle).await; + assert_eq!( + fetch_validation_code(&mut ctx_handle).await, + participation.recent_block.unwrap().1 + ); + + assert_matches!( + ctx_handle.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, timeout, tx) + ) if timeout == PvfExecTimeoutKind::Approval => { + tx.send(Ok(ValidationResult::Valid(dummy_candidate_commitments(None), PersistedValidationData::default()))).unwrap(); + }, + "overseer did not receive candidate validation message", + ); + + let result = participation + .get_participation_result(&mut ctx, worker_receiver.next().await.unwrap()) + .await + .unwrap(); + assert_matches!( + result.outcome, + ParticipationOutcome::Valid => {} + ); + }) +} diff --git a/polkadot/node/core/dispute-coordinator/src/scraping/candidates.rs b/polkadot/node/core/dispute-coordinator/src/scraping/candidates.rs new file mode 100644 index 0000000000000000000000000000000000000000..38956700545cd46971120a415310880c2b6c3b9f --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/scraping/candidates.rs @@ -0,0 +1,169 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_primitives::{BlockNumber, CandidateHash}; +use std::collections::{BTreeMap, HashMap, HashSet}; + +/// Keeps `CandidateHash` in reference counted way. +/// Each `insert` saves a value with `reference count == 1` or increases the reference +/// count if the value already exists. +/// Each `remove` decreases the reference count for the corresponding `CandidateHash`. +/// If the reference count reaches 0 - the value is removed. +struct RefCountedCandidates { + candidates: HashMap, +} + +impl RefCountedCandidates { + pub fn new() -> Self { + Self { candidates: HashMap::new() } + } + // If `CandidateHash` doesn't exist in the `HashMap` it is created and its reference + // count is set to 1. + // If `CandidateHash` already exists in the `HashMap` its reference count is increased. + pub fn insert(&mut self, candidate: CandidateHash) { + *self.candidates.entry(candidate).or_default() += 1; + } + + // If a `CandidateHash` with reference count equals to 1 is about to be removed - the + // candidate is dropped from the container too. + // If a `CandidateHash` with reference count biger than 1 is about to be removed - the + // reference count is decreased and the candidate remains in the container. + pub fn remove(&mut self, candidate: &CandidateHash) { + match self.candidates.get_mut(candidate) { + Some(v) if *v > 1 => *v -= 1, + Some(v) => { + assert!(*v == 1); + self.candidates.remove(candidate); + }, + None => {}, + } + } + + pub fn contains(&self, candidate: &CandidateHash) -> bool { + self.candidates.contains_key(&candidate) + } +} + +#[cfg(test)] +mod ref_counted_candidates_tests { + use super::*; + use polkadot_primitives::{BlakeTwo256, HashT}; + + #[test] + fn element_is_removed_when_refcount_reaches_zero() { + let mut container = RefCountedCandidates::new(); + + let zero = CandidateHash(BlakeTwo256::hash(&vec![0])); + let one = CandidateHash(BlakeTwo256::hash(&vec![1])); + // add two separate candidates + container.insert(zero); // refcount == 1 + container.insert(one); + + // and increase the reference count for the first + container.insert(zero); // refcount == 2 + + assert!(container.contains(&zero)); + assert!(container.contains(&one)); + + // remove once -> refcount == 1 + container.remove(&zero); + assert!(container.contains(&zero)); + assert!(container.contains(&one)); + + // remove once -> refcount == 0 + container.remove(&zero); + assert!(!container.contains(&zero)); + assert!(container.contains(&one)); + + // remove the other element + container.remove(&one); + assert!(!container.contains(&zero)); + assert!(!container.contains(&one)); + } +} + +/// Keeps track of scraped candidates. Supports `insert`, `remove_up_to_height` and `contains` +/// operations. +pub struct ScrapedCandidates { + /// Main data structure which keeps the candidates we know about. `contains` does lookups only + /// here. + candidates: RefCountedCandidates, + /// Keeps track at which block number a candidate was inserted. Used in `remove_up_to_height`. + /// Without this tracking we won't be able to remove all candidates before block X. + candidates_by_block_number: BTreeMap>, +} + +impl ScrapedCandidates { + pub fn new() -> Self { + Self { + candidates: RefCountedCandidates::new(), + candidates_by_block_number: BTreeMap::new(), + } + } + + pub fn contains(&self, candidate_hash: &CandidateHash) -> bool { + self.candidates.contains(candidate_hash) + } + + // Removes all candidates up to a given height. The candidates at the block height are NOT + // removed. + pub fn remove_up_to_height(&mut self, height: &BlockNumber) -> HashSet { + let mut candidates_modified: HashSet = HashSet::new(); + let not_stale = self.candidates_by_block_number.split_off(&height); + let stale = std::mem::take(&mut self.candidates_by_block_number); + self.candidates_by_block_number = not_stale; + for candidates in stale.values() { + for c in candidates { + self.candidates.remove(c); + candidates_modified.insert(*c); + } + } + candidates_modified + } + + pub fn insert(&mut self, block_number: BlockNumber, candidate_hash: CandidateHash) { + self.candidates.insert(candidate_hash); + self.candidates_by_block_number + .entry(block_number) + .or_default() + .insert(candidate_hash); + } + + // Used only for tests to verify the pruning doesn't leak data. + #[cfg(test)] + pub fn candidates_by_block_number_is_empty(&self) -> bool { + self.candidates_by_block_number.is_empty() + } +} + +#[cfg(test)] +mod scraped_candidates_tests { + use super::*; + use polkadot_primitives::{BlakeTwo256, HashT}; + + #[test] + fn stale_candidates_are_removed() { + let mut candidates = ScrapedCandidates::new(); + let target = CandidateHash(BlakeTwo256::hash(&vec![1, 2, 3])); + candidates.insert(1, target); + + assert!(candidates.contains(&target)); + + candidates.remove_up_to_height(&2); + assert!(!candidates.contains(&target)); + assert!(candidates.candidates_by_block_number_is_empty()); + } +} diff --git a/polkadot/node/core/dispute-coordinator/src/scraping/mod.rs b/polkadot/node/core/dispute-coordinator/src/scraping/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..f93ad0abab91efccabf48f2d8eece0d621ea81a4 --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/scraping/mod.rs @@ -0,0 +1,489 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{ + collections::{BTreeMap, HashSet}, + num::NonZeroUsize, +}; + +use futures::channel::oneshot; +use lru::LruCache; + +use polkadot_node_primitives::{DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION, MAX_FINALITY_LAG}; +use polkadot_node_subsystem::{ + messages::ChainApiMessage, overseer, ActivatedLeaf, ActiveLeavesUpdate, ChainApiError, + RuntimeApiError, SubsystemSender, +}; +use polkadot_node_subsystem_util::runtime::{ + self, get_candidate_events, get_on_chain_votes, get_unapplied_slashes, +}; +use polkadot_primitives::{ + slashing::PendingSlashes, BlockNumber, CandidateEvent, CandidateHash, CandidateReceipt, Hash, + ScrapedOnChainVotes, SessionIndex, +}; + +use crate::{ + error::{FatalError, FatalResult, Result}, + LOG_TARGET, +}; + +#[cfg(test)] +mod tests; + +mod candidates; + +/// Number of hashes to keep in the LRU. +/// +/// +/// When traversing the ancestry of a block we will stop once we hit a hash that we find in the +/// `last_observed_blocks` LRU. This means, this value should the very least be as large as the +/// number of expected forks for keeping chain scraping efficient. Making the LRU much larger than +/// that has very limited use. +const LRU_OBSERVED_BLOCKS_CAPACITY: NonZeroUsize = match NonZeroUsize::new(20) { + Some(cap) => cap, + None => panic!("Observed blocks cache size must be non-zero"), +}; + +/// `ScrapedUpdates` +/// +/// Updates to `on_chain_votes` and included receipts for new active leaf and its unprocessed +/// ancestors. +/// +/// `on_chain_votes`: New votes as seen on chain +/// `included_receipts`: Newly included parachain block candidate receipts as seen on chain +pub struct ScrapedUpdates { + pub on_chain_votes: Vec, + pub included_receipts: Vec, + pub unapplied_slashes: Vec<(SessionIndex, CandidateHash, PendingSlashes)>, +} + +impl ScrapedUpdates { + pub fn new() -> Self { + Self { + on_chain_votes: Vec::new(), + included_receipts: Vec::new(), + unapplied_slashes: Vec::new(), + } + } +} + +/// A structure meant to facilitate chain reversions in the event of a dispute +/// concluding against a candidate. Each candidate hash maps to a number of +/// block heights, which in turn map to vectors of blocks at those heights. +pub struct Inclusions { + inclusions_inner: BTreeMap>>, +} + +impl Inclusions { + pub fn new() -> Self { + Self { inclusions_inner: BTreeMap::new() } + } + + // Add parent block to the vector which has CandidateHash as an outer key and + // BlockNumber as an inner key + pub fn insert( + &mut self, + candidate_hash: CandidateHash, + block_number: BlockNumber, + block_hash: Hash, + ) { + if let Some(blocks_including) = self.inclusions_inner.get_mut(&candidate_hash) { + if let Some(blocks_at_height) = blocks_including.get_mut(&block_number) { + blocks_at_height.push(block_hash); + } else { + blocks_including.insert(block_number, Vec::from([block_hash])); + } + } else { + let mut blocks_including: BTreeMap> = BTreeMap::new(); + blocks_including.insert(block_number, Vec::from([block_hash])); + self.inclusions_inner.insert(candidate_hash, blocks_including); + } + } + + pub fn remove_up_to_height( + &mut self, + height: &BlockNumber, + candidates_modified: HashSet, + ) { + for candidate in candidates_modified { + if let Some(blocks_including) = self.inclusions_inner.get_mut(&candidate) { + // Returns everything after the given key, including the key. This works because the + // blocks are sorted in ascending order. + *blocks_including = blocks_including.split_off(height); + } + } + self.inclusions_inner + .retain(|_, blocks_including| blocks_including.keys().len() > 0); + } + + pub fn get(&self, candidate: &CandidateHash) -> Vec<(BlockNumber, Hash)> { + let mut inclusions_as_vec: Vec<(BlockNumber, Hash)> = Vec::new(); + if let Some(blocks_including) = self.inclusions_inner.get(candidate) { + for (height, blocks_at_height) in blocks_including.iter() { + for block in blocks_at_height { + inclusions_as_vec.push((*height, *block)); + } + } + } + inclusions_as_vec + } +} + +/// Chain scraper +/// +/// Scrapes unfinalized chain in order to collect information from blocks. Chain scraping +/// during disputes enables critical spam prevention. It does so by updating two important +/// criteria determining whether a vote sent during dispute distribution is potential +/// spam. Namely, whether the candidate being voted on is backed or included. +/// +/// Concretely: +/// +/// - Monitors for `CandidateIncluded` events to keep track of candidates that have been included on +/// chains. +/// - Monitors for `CandidateBacked` events to keep track of all backed candidates. +/// - Calls `FetchOnChainVotes` for each block to gather potentially missed votes from chain. +/// +/// With this information it provides a `CandidateComparator` and as a return value of +/// `process_active_leaves_update` any scraped votes. +/// +/// Scraped candidates are available `DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION` more blocks +/// after finalization as a precaution not to prune them prematurely. Besides the newly scraped +/// candidates `DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION` finalized blocks are parsed as +/// another precaution to have their `CandidateReceipts` available in case a dispute is raised on +/// them, +pub struct ChainScraper { + /// All candidates we have seen included, which not yet have been finalized. + included_candidates: candidates::ScrapedCandidates, + /// All candidates we have seen backed + backed_candidates: candidates::ScrapedCandidates, + /// Latest relay blocks observed by the provider. + /// + /// We assume that ancestors of cached blocks are already processed, i.e. we have saved + /// corresponding included candidates. + last_observed_blocks: LruCache, + /// Maps included candidate hashes to one or more relay block heights and hashes. + /// These correspond to all the relay blocks which marked a candidate as included, + /// and are needed to apply reversions in case a dispute is concluded against the + /// candidate. + inclusions: Inclusions, +} + +impl ChainScraper { + /// Limits the number of ancestors received for a single request. + pub(crate) const ANCESTRY_CHUNK_SIZE: u32 = 10; + /// Limits the overall number of ancestors walked through for a given head. + /// + /// As long as we have `MAX_FINALITY_LAG` this makes sense as a value. + pub(crate) const ANCESTRY_SIZE_LIMIT: u32 = MAX_FINALITY_LAG; + + /// Create a properly initialized `OrderingProvider`. + /// + /// Returns: `Self` and any scraped votes. + pub async fn new( + sender: &mut Sender, + initial_head: ActivatedLeaf, + ) -> Result<(Self, Vec)> + where + Sender: overseer::DisputeCoordinatorSenderTrait, + { + let mut s = Self { + included_candidates: candidates::ScrapedCandidates::new(), + backed_candidates: candidates::ScrapedCandidates::new(), + last_observed_blocks: LruCache::new(LRU_OBSERVED_BLOCKS_CAPACITY), + inclusions: Inclusions::new(), + }; + let update = + ActiveLeavesUpdate { activated: Some(initial_head), deactivated: Default::default() }; + let updates = s.process_active_leaves_update(sender, &update).await?; + Ok((s, updates.on_chain_votes)) + } + + /// Check whether we have seen a candidate included on any chain. + pub fn is_candidate_included(&self, candidate_hash: &CandidateHash) -> bool { + self.included_candidates.contains(candidate_hash) + } + + /// Check whether the candidate is backed + pub fn is_candidate_backed(&self, candidate_hash: &CandidateHash) -> bool { + self.backed_candidates.contains(candidate_hash) + } + + /// Query active leaves for any candidate `CandidateEvent::CandidateIncluded` events. + /// + /// and updates current heads, so we can query candidates for all non finalized blocks. + /// + /// Returns: On chain votes and included candidate receipts for the leaf and any + /// ancestors we might not yet have seen. + pub async fn process_active_leaves_update( + &mut self, + sender: &mut Sender, + update: &ActiveLeavesUpdate, + ) -> Result + where + Sender: overseer::DisputeCoordinatorSenderTrait, + { + let activated = match update.activated.as_ref() { + Some(activated) => activated, + None => return Ok(ScrapedUpdates::new()), + }; + + // Fetch ancestry up to `SCRAPED_FINALIZED_BLOCKS_COUNT` blocks beyond + // the last finalized one + let ancestors = self + .get_relevant_block_ancestors(sender, activated.hash, activated.number) + .await?; + + // Ancestors block numbers are consecutive in the descending order. + let earliest_block_number = activated.number - ancestors.len() as u32; + let block_numbers = (earliest_block_number..=activated.number).rev(); + + let block_hashes = std::iter::once(activated.hash).chain(ancestors); + + let mut scraped_updates = ScrapedUpdates::new(); + for (block_number, block_hash) in block_numbers.zip(block_hashes) { + gum::trace!(target: LOG_TARGET, ?block_number, ?block_hash, "In ancestor processing."); + + let receipts_for_block = + self.process_candidate_events(sender, block_number, block_hash).await?; + scraped_updates.included_receipts.extend(receipts_for_block); + + if let Some(votes) = get_on_chain_votes(sender, block_hash).await? { + scraped_updates.on_chain_votes.push(votes); + } + } + + // for unapplied slashes, we only look at the latest activated hash, + // it should accumulate them all + match get_unapplied_slashes(sender, activated.hash).await { + Ok(unapplied_slashes) => { + scraped_updates.unapplied_slashes = unapplied_slashes; + }, + Err(runtime::Error::RuntimeRequest(RuntimeApiError::NotSupported { .. })) => { + gum::debug!( + target: LOG_TARGET, + block_hash = ?activated.hash, + "Fetching unapplied slashes not yet supported.", + ); + }, + Err(error) => { + gum::warn!( + target: LOG_TARGET, + block_hash = ?activated.hash, + ?error, + "Error fetching unapplied slashes.", + ); + }, + } + + self.last_observed_blocks.put(activated.hash, ()); + + Ok(scraped_updates) + } + + /// Prune finalized candidates. + /// + /// We keep each candidate for `DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION` blocks after + /// finalization. After that we treat it as low priority. + pub fn process_finalized_block(&mut self, finalized_block_number: &BlockNumber) { + // `DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION - 1` because + // `finalized_block_number`counts to the candidate lifetime. + match finalized_block_number.checked_sub(DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION - 1) + { + Some(key_to_prune) => { + self.backed_candidates.remove_up_to_height(&key_to_prune); + let candidates_modified = + self.included_candidates.remove_up_to_height(&key_to_prune); + self.inclusions.remove_up_to_height(&key_to_prune, candidates_modified); + }, + None => { + // Nothing to prune. We are still in the beginning of the chain and there are not + // enough finalized blocks yet. + }, + } + {} + } + + /// Process candidate events of a block. + /// + /// Keep track of all included and backed candidates. + /// + /// Returns freshly included candidate receipts + async fn process_candidate_events( + &mut self, + sender: &mut Sender, + block_number: BlockNumber, + block_hash: Hash, + ) -> Result> + where + Sender: overseer::DisputeCoordinatorSenderTrait, + { + let events = get_candidate_events(sender, block_hash).await?; + let mut included_receipts: Vec = Vec::new(); + // Get included and backed events: + for ev in events { + match ev { + CandidateEvent::CandidateIncluded(receipt, _, _, _) => { + let candidate_hash = receipt.hash(); + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?block_number, + "Processing included event" + ); + self.included_candidates.insert(block_number, candidate_hash); + self.inclusions.insert(candidate_hash, block_number, block_hash); + included_receipts.push(receipt); + }, + CandidateEvent::CandidateBacked(receipt, _, _, _) => { + let candidate_hash = receipt.hash(); + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?block_number, + "Processing backed event" + ); + self.backed_candidates.insert(block_number, candidate_hash); + }, + _ => { + // skip the rest + }, + } + } + Ok(included_receipts) + } + + /// Returns ancestors of `head` in the descending order, stopping + /// either at the block present in cache or at `SCRAPED_FINALIZED_BLOCKS_COUNT -1` blocks after + /// the last finalized one (called `target_ancestor`). + /// + /// Both `head` and the `target_ancestor` blocks are **not** included in the result. + async fn get_relevant_block_ancestors( + &mut self, + sender: &mut Sender, + mut head: Hash, + mut head_number: BlockNumber, + ) -> Result> + where + Sender: overseer::DisputeCoordinatorSenderTrait, + { + let target_ancestor = get_finalized_block_number(sender) + .await? + .saturating_sub(DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION); + + let mut ancestors = Vec::new(); + + // If head_number <= target_ancestor + 1 the ancestry will be empty. + if self.last_observed_blocks.get(&head).is_some() || head_number <= target_ancestor + 1 { + return Ok(ancestors) + } + + loop { + let hashes = get_block_ancestors(sender, head, Self::ANCESTRY_CHUNK_SIZE).await?; + + let earliest_block_number = match head_number.checked_sub(hashes.len() as u32) { + Some(number) => number, + None => { + // It's assumed that it's impossible to retrieve + // more than N ancestors for block number N. + gum::error!( + target: LOG_TARGET, + "Received {} ancestors for block number {} from Chain API", + hashes.len(), + head_number, + ); + return Ok(ancestors) + }, + }; + // The reversed order is parent, grandparent, etc. excluding the head. + let block_numbers = (earliest_block_number..head_number).rev(); + + for (block_number, hash) in block_numbers.zip(&hashes) { + // Return if we either met target/cached block or + // hit the size limit for the returned ancestry of head. + if self.last_observed_blocks.get(hash).is_some() || + block_number <= target_ancestor || + ancestors.len() >= Self::ANCESTRY_SIZE_LIMIT as usize + { + return Ok(ancestors) + } + + ancestors.push(*hash); + } + + match hashes.last() { + Some(last_hash) => { + head = *last_hash; + head_number = earliest_block_number; + }, + None => break, + } + } + return Ok(ancestors) + } + + pub fn get_blocks_including_candidate( + &self, + candidate: &CandidateHash, + ) -> Vec<(BlockNumber, Hash)> { + self.inclusions.get(candidate) + } +} + +async fn get_finalized_block_number(sender: &mut Sender) -> FatalResult +where + Sender: overseer::DisputeCoordinatorSenderTrait, +{ + let (number_tx, number_rx) = oneshot::channel(); + send_message_fatal(sender, ChainApiMessage::FinalizedBlockNumber(number_tx), number_rx).await +} + +async fn get_block_ancestors( + sender: &mut Sender, + head: Hash, + num_ancestors: BlockNumber, +) -> FatalResult> +where + Sender: overseer::DisputeCoordinatorSenderTrait, +{ + let (tx, rx) = oneshot::channel(); + sender + .send_message(ChainApiMessage::Ancestors { + hash: head, + k: num_ancestors as usize, + response_channel: tx, + }) + .await; + + rx.await + .or(Err(FatalError::ChainApiSenderDropped))? + .map_err(FatalError::ChainApiAncestors) +} + +async fn send_message_fatal( + sender: &mut Sender, + message: ChainApiMessage, + receiver: oneshot::Receiver>, +) -> FatalResult +where + Sender: SubsystemSender, +{ + sender.send_message(message).await; + + receiver + .await + .map_err(|_| FatalError::ChainApiSenderDropped)? + .map_err(FatalError::ChainApiAncestors) +} diff --git a/polkadot/node/core/dispute-coordinator/src/scraping/tests.rs b/polkadot/node/core/dispute-coordinator/src/scraping/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..3dd58a060d709459bcf612a7958df3165eec4cb2 --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/scraping/tests.rs @@ -0,0 +1,669 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{sync::Arc, time::Duration}; + +use assert_matches::assert_matches; + +use futures::future::join; +use parity_scale_codec::Encode; +use sp_core::testing::TaskExecutor; + +use ::test_helpers::{dummy_collator, dummy_collator_signature, dummy_hash}; +use polkadot_node_primitives::DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION; +use polkadot_node_subsystem::{ + jaeger, + messages::{ + AllMessages, ChainApiMessage, DisputeCoordinatorMessage, RuntimeApiMessage, + RuntimeApiRequest, + }, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, SpawnGlue, +}; +use polkadot_node_subsystem_test_helpers::{ + make_subsystem_context, TestSubsystemContext, TestSubsystemContextHandle, TestSubsystemSender, +}; +use polkadot_node_subsystem_util::{reexports::SubsystemContext, TimeoutExt}; +use polkadot_primitives::{ + BlakeTwo256, BlockNumber, CandidateDescriptor, CandidateEvent, CandidateReceipt, CoreIndex, + GroupIndex, Hash, HashT, HeadData, Id as ParaId, +}; + +use crate::LOG_TARGET; + +use super::ChainScraper; + +type VirtualOverseer = TestSubsystemContextHandle; + +const OVERSEER_RECEIVE_TIMEOUT: Duration = Duration::from_secs(2); + +async fn overseer_recv(virtual_overseer: &mut VirtualOverseer) -> AllMessages { + virtual_overseer + .recv() + .timeout(OVERSEER_RECEIVE_TIMEOUT) + .await + .expect("overseer `recv` timed out") +} + +struct TestState { + chain: Vec, + scraper: ChainScraper, + ctx: TestSubsystemContext>, +} + +impl TestState { + async fn new() -> (Self, VirtualOverseer) { + let (mut ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let chain = vec![get_block_number_hash(0), get_block_number_hash(1)]; + let leaf = get_activated_leaf(1); + + let finalized_block_number = 0; + let overseer_fut = async { + assert_finalized_block_number_request(&mut ctx_handle, finalized_block_number).await; + gum::trace!(target: LOG_TARGET, "After assert_finalized_block_number"); + // No ancestors requests, as list would be empty. + assert_candidate_events_request( + &mut ctx_handle, + &chain, + get_backed_and_included_candidate_events, + ) + .await; + assert_chain_vote_request(&mut ctx_handle, &chain).await; + assert_unapplied_slashes_request(&mut ctx_handle, &chain).await; + }; + + let (scraper, _) = join(ChainScraper::new(ctx.sender(), leaf.clone()), overseer_fut) + .await + .0 + .unwrap(); + gum::trace!(target: LOG_TARGET, "After launching chain scraper"); + + let test_state = Self { chain, scraper, ctx }; + + (test_state, ctx_handle) + } +} + +fn next_block_number(chain: &[Hash]) -> BlockNumber { + chain.len() as u32 +} + +/// Get a new leaf. +fn next_leaf(chain: &mut Vec) -> ActivatedLeaf { + let next_block_number = next_block_number(chain); + let next_hash = get_block_number_hash(next_block_number); + chain.push(next_hash); + get_activated_leaf(next_block_number) +} + +async fn process_active_leaves_update( + sender: &mut TestSubsystemSender, + scraper: &mut ChainScraper, + update: ActivatedLeaf, +) { + scraper + .process_active_leaves_update(sender, &ActiveLeavesUpdate::start_work(update)) + .await + .unwrap(); +} + +fn process_finalized_block(scraper: &mut ChainScraper, finalized: &BlockNumber) { + scraper.process_finalized_block(&finalized) +} + +fn make_candidate_receipt(relay_parent: Hash) -> CandidateReceipt { + let zeros = dummy_hash(); + let descriptor = CandidateDescriptor { + para_id: ParaId::from(0_u32), + relay_parent, + collator: dummy_collator(), + persisted_validation_data_hash: zeros, + pov_hash: zeros, + erasure_root: zeros, + signature: dummy_collator_signature(), + para_head: zeros, + validation_code_hash: zeros.into(), + }; + CandidateReceipt { descriptor, commitments_hash: zeros } +} + +/// Get a dummy `ActivatedLeaf` for a given block number. +fn get_activated_leaf(n: BlockNumber) -> ActivatedLeaf { + ActivatedLeaf { + hash: get_block_number_hash(n), + number: n, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + } +} + +/// Get a dummy relay parent hash for dummy block number. +fn get_block_number_hash(n: BlockNumber) -> Hash { + BlakeTwo256::hash(&n.encode()) +} + +/// Get a dummy event that corresponds to candidate inclusion for the given block number. +fn get_backed_and_included_candidate_events(block_number: BlockNumber) -> Vec { + let candidate_receipt = make_candidate_receipt(get_block_number_hash(block_number)); + vec![ + CandidateEvent::CandidateIncluded( + candidate_receipt.clone(), + HeadData::default(), + CoreIndex::from(0), + GroupIndex::from(0), + ), + CandidateEvent::CandidateBacked( + candidate_receipt, + HeadData::default(), + CoreIndex::from(0), + GroupIndex::from(0), + ), + ] +} + +fn get_backed_candidate_event(block_number: BlockNumber) -> Vec { + let candidate_receipt = make_candidate_receipt(get_block_number_hash(block_number)); + vec![CandidateEvent::CandidateBacked( + candidate_receipt, + HeadData::default(), + CoreIndex::from(0), + GroupIndex::from(0), + )] +} +/// Hash for a 'magic' candidate. This is meant to be a special candidate used to verify special +/// cases. +fn get_magic_candidate_hash() -> Hash { + BlakeTwo256::hash(&"abc".encode()) +} +/// Get a dummy event that corresponds to candidate inclusion for a hardcoded block number. +/// Used to simulate candidates included multiple times at different block heights. +fn get_backed_and_included_magic_candidate_events( + _block_number: BlockNumber, +) -> Vec { + let candidate_receipt = make_candidate_receipt(get_magic_candidate_hash()); + vec![ + CandidateEvent::CandidateIncluded( + candidate_receipt.clone(), + HeadData::default(), + CoreIndex::from(0), + GroupIndex::from(0), + ), + CandidateEvent::CandidateBacked( + candidate_receipt, + HeadData::default(), + CoreIndex::from(0), + GroupIndex::from(0), + ), + ] +} + +async fn assert_candidate_events_request( + virtual_overseer: &mut VirtualOverseer, + chain: &[Hash], + event_generator: F, +) where + F: Fn(u32) -> Vec, +{ + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::CandidateEvents(tx), + )) => { + let maybe_block_number = chain.iter().position(|h| *h == hash); + let response = maybe_block_number + .map(|num| event_generator(num as u32)) + .unwrap_or_default(); + tx.send(Ok(response)).unwrap(); + } + ); +} + +async fn assert_chain_vote_request(virtual_overseer: &mut VirtualOverseer, _chain: &[Hash]) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::FetchOnChainVotes(tx), + )) => { + tx.send(Ok(None)).unwrap(); + } + ); +} + +async fn assert_unapplied_slashes_request(virtual_overseer: &mut VirtualOverseer, _chain: &[Hash]) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _hash, + RuntimeApiRequest::UnappliedSlashes(tx), + )) => { + tx.send(Ok(Vec::new())).unwrap(); + } + ); +} + +async fn assert_finalized_block_number_request( + virtual_overseer: &mut VirtualOverseer, + response: BlockNumber, +) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(tx)) => { + tx.send(Ok(response)).unwrap(); + } + ); +} + +async fn assert_block_ancestors_request(virtual_overseer: &mut VirtualOverseer, chain: &[Hash]) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::Ancestors { hash, k, response_channel }) => { + let maybe_block_position = chain.iter().position(|h| *h == hash); + let ancestors = maybe_block_position + .map(|idx| chain[..idx].iter().rev().take(k).copied().collect()) + .unwrap_or_default(); + response_channel.send(Ok(ancestors)).unwrap(); + } + ); +} + +async fn overseer_process_active_leaves_update( + virtual_overseer: &mut VirtualOverseer, + chain: &[Hash], + finalized_block: BlockNumber, + expected_ancestry_len: usize, + event_generator: F, +) where + F: Fn(u32) -> Vec + Clone, +{ + // Before walking through ancestors provider requests latest finalized block number. + assert_finalized_block_number_request(virtual_overseer, finalized_block).await; + // Expect block ancestors requests with respect to the ancestry step. + for _ in (0..expected_ancestry_len).step_by(ChainScraper::ANCESTRY_CHUNK_SIZE as usize) { + assert_block_ancestors_request(virtual_overseer, chain).await; + } + // For each ancestry and the head return corresponding candidates inclusions. + for _ in 0..expected_ancestry_len { + assert_candidate_events_request(virtual_overseer, chain, event_generator.clone()).await; + assert_chain_vote_request(virtual_overseer, chain).await; + } + assert_unapplied_slashes_request(virtual_overseer, chain).await; +} + +#[test] +fn scraper_provides_included_state_when_initialized() { + let candidate_1 = make_candidate_receipt(get_block_number_hash(1)); + let candidate_2 = make_candidate_receipt(get_block_number_hash(2)); + futures::executor::block_on(async { + let (state, mut virtual_overseer) = TestState::new().await; + + let TestState { mut chain, mut scraper, mut ctx } = state; + + assert!(!scraper.is_candidate_included(&candidate_2.hash())); + assert!(!scraper.is_candidate_backed(&candidate_2.hash())); + assert!(scraper.is_candidate_included(&candidate_1.hash())); + assert!(scraper.is_candidate_backed(&candidate_1.hash())); + + // After next active leaves update we should see the candidate included. + let next_update = next_leaf(&mut chain); + + let finalized_block_number = 0; + let expected_ancestry_len = 1; + let overseer_fut = overseer_process_active_leaves_update( + &mut virtual_overseer, + &chain, + finalized_block_number, + expected_ancestry_len, + get_backed_and_included_candidate_events, + ); + join(process_active_leaves_update(ctx.sender(), &mut scraper, next_update), overseer_fut) + .await; + + assert!(scraper.is_candidate_included(&candidate_2.hash())); + assert!(scraper.is_candidate_backed(&candidate_2.hash())); + }); +} + +#[test] +fn scraper_requests_candidates_of_leaf_ancestors() { + futures::executor::block_on(async { + // How many blocks should we skip before sending a leaf update. + const BLOCKS_TO_SKIP: usize = 30; + + let (state, mut virtual_overseer) = TestState::new().await; + + let TestState { mut chain, mut scraper, mut ctx } = state; + + let next_update = (0..BLOCKS_TO_SKIP).map(|_| next_leaf(&mut chain)).last().unwrap(); + + let finalized_block_number = 0; + let overseer_fut = overseer_process_active_leaves_update( + &mut virtual_overseer, + &chain, + finalized_block_number, + BLOCKS_TO_SKIP, + get_backed_and_included_candidate_events, + ); + join(process_active_leaves_update(ctx.sender(), &mut scraper, next_update), overseer_fut) + .await; + + let next_block_number = next_block_number(&chain); + for block_number in 1..next_block_number { + let candidate = make_candidate_receipt(get_block_number_hash(block_number)); + assert!(scraper.is_candidate_included(&candidate.hash())); + assert!(scraper.is_candidate_backed(&candidate.hash())); + } + }); +} + +#[test] +fn scraper_requests_candidates_of_non_cached_ancestors() { + futures::executor::block_on(async { + // How many blocks should we skip before sending a leaf update. + const BLOCKS_TO_SKIP: &[usize] = &[30, 15]; + + let (state, mut virtual_overseer) = TestState::new().await; + + let TestState { mut chain, scraper: mut ordering, mut ctx } = state; + + let next_update = (0..BLOCKS_TO_SKIP[0]).map(|_| next_leaf(&mut chain)).last().unwrap(); + + let finalized_block_number = 0; + let overseer_fut = overseer_process_active_leaves_update( + &mut virtual_overseer, + &chain, + finalized_block_number, + BLOCKS_TO_SKIP[0], + get_backed_and_included_candidate_events, + ); + join(process_active_leaves_update(ctx.sender(), &mut ordering, next_update), overseer_fut) + .await; + + // Send the second request and verify that we don't go past the cached block. + let next_update = (0..BLOCKS_TO_SKIP[1]).map(|_| next_leaf(&mut chain)).last().unwrap(); + let overseer_fut = overseer_process_active_leaves_update( + &mut virtual_overseer, + &chain, + finalized_block_number, + BLOCKS_TO_SKIP[1], + get_backed_and_included_candidate_events, + ); + join(process_active_leaves_update(ctx.sender(), &mut ordering, next_update), overseer_fut) + .await; + }); +} + +#[test] +fn scraper_requests_candidates_of_non_finalized_ancestors() { + futures::executor::block_on(async { + // How many blocks should we skip before sending a leaf update. + const BLOCKS_TO_SKIP: usize = 30; + + let (state, mut virtual_overseer) = TestState::new().await; + + let TestState { mut chain, scraper: mut ordering, mut ctx } = state; + + // 1 because `TestState` starts at leaf 1. + let next_update = (1..BLOCKS_TO_SKIP).map(|_| next_leaf(&mut chain)).last().unwrap(); + + let finalized_block_number = 17; + let overseer_fut = overseer_process_active_leaves_update( + &mut virtual_overseer, + &chain, + finalized_block_number, + BLOCKS_TO_SKIP - + (finalized_block_number - DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION) as usize, /* Expect the provider not to go past finalized block. */ + get_backed_and_included_candidate_events, + ); + join(process_active_leaves_update(ctx.sender(), &mut ordering, next_update), overseer_fut) + .await; + }); +} + +#[test] +fn scraper_prunes_finalized_candidates() { + const TEST_TARGET_BLOCK_NUMBER: BlockNumber = 2; + + // How many blocks should we skip before sending a leaf update. + const BLOCKS_TO_SKIP: usize = 3; + + futures::executor::block_on(async { + let (state, mut virtual_overseer) = TestState::new().await; + + let TestState { mut chain, mut scraper, mut ctx } = state; + + // 1 because `TestState` starts at leaf 1. + let next_update = (1..BLOCKS_TO_SKIP).map(|_| next_leaf(&mut chain)).last().unwrap(); + + let mut finalized_block_number = 1; + let expected_ancestry_len = BLOCKS_TO_SKIP - finalized_block_number as usize; + let overseer_fut = overseer_process_active_leaves_update( + &mut virtual_overseer, + &chain, + finalized_block_number, + expected_ancestry_len, + |block_num| { + if block_num == TEST_TARGET_BLOCK_NUMBER { + get_backed_and_included_candidate_events(block_num) + } else { + vec![] + } + }, + ); + join(process_active_leaves_update(ctx.sender(), &mut scraper, next_update), overseer_fut) + .await; + + let candidate = make_candidate_receipt(get_block_number_hash(TEST_TARGET_BLOCK_NUMBER)); + + // After `DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION` blocks the candidate should be + // removed + finalized_block_number = + TEST_TARGET_BLOCK_NUMBER + DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION; + process_finalized_block(&mut scraper, &finalized_block_number); + + assert!(!scraper.is_candidate_backed(&candidate.hash())); + assert!(!scraper.is_candidate_included(&candidate.hash())); + }); +} + +#[test] +fn scraper_handles_backed_but_not_included_candidate() { + const TEST_TARGET_BLOCK_NUMBER: BlockNumber = 2; + + // How many blocks should we skip before sending a leaf update. + const BLOCKS_TO_SKIP: usize = 3; + + futures::executor::block_on(async { + let (state, mut virtual_overseer) = TestState::new().await; + + let TestState { mut chain, mut scraper, mut ctx } = state; + + let next_update = (1..BLOCKS_TO_SKIP as BlockNumber) + .map(|_| next_leaf(&mut chain)) + .last() + .unwrap(); + + // Add `ActiveLeavesUpdate` containing `CandidateBacked` event for block `BLOCK_WITH_EVENTS` + let mut finalized_block_number = 1; + let expected_ancestry_len = BLOCKS_TO_SKIP - finalized_block_number as usize; + let overseer_fut = overseer_process_active_leaves_update( + &mut virtual_overseer, + &chain, + finalized_block_number, + expected_ancestry_len, + |block_num| { + if block_num == TEST_TARGET_BLOCK_NUMBER { + get_backed_candidate_event(block_num) + } else { + vec![] + } + }, + ); + join(process_active_leaves_update(ctx.sender(), &mut scraper, next_update), overseer_fut) + .await; + + // Finalize blocks to enforce pruning of scraped events + finalized_block_number += 1; + process_finalized_block(&mut scraper, &finalized_block_number); + + // `FIRST_TEST_BLOCK` is finalized, which is within + // `BACKED_CANDIDATE_LIFETIME_AFTER_FINALIZATION` window. The candidate should still be + // backed. + let candidate = make_candidate_receipt(get_block_number_hash(TEST_TARGET_BLOCK_NUMBER)); + assert!(!scraper.is_candidate_included(&candidate.hash())); + assert!(scraper.is_candidate_backed(&candidate.hash())); + + // Bump the finalized block outside `BACKED_CANDIDATE_LIFETIME_AFTER_FINALIZATION`. + // The candidate should be removed. + assert!( + finalized_block_number < + TEST_TARGET_BLOCK_NUMBER + DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION + ); + finalized_block_number += + TEST_TARGET_BLOCK_NUMBER + DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION; + process_finalized_block(&mut scraper, &finalized_block_number); + + assert!(!scraper.is_candidate_included(&candidate.hash())); + assert!(!scraper.is_candidate_backed(&candidate.hash())); + }); +} + +#[test] +fn scraper_handles_the_same_candidate_incuded_in_two_different_block_heights() { + // Same candidate will be inclued in these two leaves + let test_targets = vec![2, 3]; + + // How many blocks should we skip before sending a leaf update. + const BLOCKS_TO_SKIP: usize = 3; + + futures::executor::block_on(async { + let (state, mut virtual_overseer) = TestState::new().await; + + let TestState { mut chain, mut scraper, mut ctx } = state; + + // 1 because `TestState` starts at leaf 1. + let next_update = (1..BLOCKS_TO_SKIP).map(|_| next_leaf(&mut chain)).last().unwrap(); + + // Now we will add the same magic candidate at two different block heights. + // Check `get_backed_and_included_magic_candidate_event` implementation + let mut finalized_block_number = 1; + let expected_ancestry_len = BLOCKS_TO_SKIP - finalized_block_number as usize; + let overseer_fut = overseer_process_active_leaves_update( + &mut virtual_overseer, + &chain, + finalized_block_number, + expected_ancestry_len, + |block_num| { + if test_targets.contains(&block_num) { + get_backed_and_included_magic_candidate_events(block_num) + } else { + vec![] + } + }, + ); + join(process_active_leaves_update(ctx.sender(), &mut scraper, next_update), overseer_fut) + .await; + + // Finalize blocks to enforce pruning of scraped events. + // The magic candidate was added twice, so it shouldn't be removed if we finalize two more + // blocks. + finalized_block_number = test_targets.first().expect("there are two block nums") + + DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION; + process_finalized_block(&mut scraper, &finalized_block_number); + + let magic_candidate = make_candidate_receipt(get_magic_candidate_hash()); + assert!(scraper.is_candidate_backed(&magic_candidate.hash())); + assert!(scraper.is_candidate_included(&magic_candidate.hash())); + + // On the next finalization the magic candidate should be removed + finalized_block_number += 1; + process_finalized_block(&mut scraper, &finalized_block_number); + + assert!(!scraper.is_candidate_backed(&magic_candidate.hash())); + assert!(!scraper.is_candidate_included(&magic_candidate.hash())); + }); +} + +#[test] +fn inclusions_per_candidate_properly_adds_and_prunes() { + const TEST_TARGET_BLOCK_NUMBER: BlockNumber = 2; + const TEST_TARGET_BLOCK_NUMBER_2: BlockNumber = 3; + + // How many blocks should we skip before sending a leaf update. + const BLOCKS_TO_SKIP: usize = 4; + + futures::executor::block_on(async { + let (state, mut virtual_overseer) = TestState::new().await; + + let TestState { mut chain, mut scraper, mut ctx } = state; + + // 1 because `TestState` starts at leaf 1. + let next_update = (1..BLOCKS_TO_SKIP).map(|_| next_leaf(&mut chain)).last().unwrap(); + + let mut finalized_block_number = 1; + let expected_ancestry_len = BLOCKS_TO_SKIP - finalized_block_number as usize; + let overseer_fut = overseer_process_active_leaves_update( + &mut virtual_overseer, + &chain, + finalized_block_number, + expected_ancestry_len, + |block_num| { + if block_num == TEST_TARGET_BLOCK_NUMBER || block_num == TEST_TARGET_BLOCK_NUMBER_2 + { + get_backed_and_included_candidate_events(TEST_TARGET_BLOCK_NUMBER) + } else { + vec![] + } + }, + ); + join(process_active_leaves_update(ctx.sender(), &mut scraper, next_update), overseer_fut) + .await; + + let candidate = make_candidate_receipt(get_block_number_hash(TEST_TARGET_BLOCK_NUMBER)); + + // We included the same candidate at two different block heights. So both blocks in which + // the candidate is included are recorded + assert_eq!( + scraper.get_blocks_including_candidate(&candidate.hash()), + Vec::from([ + (TEST_TARGET_BLOCK_NUMBER, get_block_number_hash(TEST_TARGET_BLOCK_NUMBER)), + (TEST_TARGET_BLOCK_NUMBER_2, get_block_number_hash(TEST_TARGET_BLOCK_NUMBER_2)) + ]) + ); + + // After `DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION` blocks the earlier inclusion should + // be removed + finalized_block_number = + TEST_TARGET_BLOCK_NUMBER + DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION; + process_finalized_block(&mut scraper, &finalized_block_number); + + // The later inclusion should still be present, as we haven't exceeded its lifetime + assert_eq!( + scraper.get_blocks_including_candidate(&candidate.hash()), + Vec::from([( + TEST_TARGET_BLOCK_NUMBER_2, + get_block_number_hash(TEST_TARGET_BLOCK_NUMBER_2) + )]) + ); + + finalized_block_number = + TEST_TARGET_BLOCK_NUMBER_2 + DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION; + process_finalized_block(&mut scraper, &finalized_block_number); + + // Now both inclusions have exceeded their lifetimes after finalization and should be purged + assert!(scraper.get_blocks_including_candidate(&candidate.hash()).len() == 0); + }); +} diff --git a/polkadot/node/core/dispute-coordinator/src/spam_slots.rs b/polkadot/node/core/dispute-coordinator/src/spam_slots.rs new file mode 100644 index 0000000000000000000000000000000000000000..fd2f65b1bc8ee87cc77b850954eb31864fb9c828 --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/spam_slots.rs @@ -0,0 +1,135 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::collections::{BTreeSet, HashMap}; + +use polkadot_primitives::{CandidateHash, SessionIndex, ValidatorIndex}; + +use crate::LOG_TARGET; + +/// Type used for counting potential spam votes. +type SpamCount = u32; + +/// How many unconfirmed disputes a validator is allowed to import (per session). +/// +/// Unconfirmed means: Node has not seen the candidate be included on any chain, it has not cast a +/// vote itself on that dispute, the dispute has not yet reached more than a third of +/// validator's votes and the including relay chain block has not yet been finalized. +/// +/// Exact number of `MAX_SPAM_VOTES` is not that important here. It is important that the number is +/// low enough to not cause resource exhaustion (disk & memory) on the importing validator, even if +/// multiple validators fully make use of their assigned spam slots. +/// +/// Also if things are working properly, this number cannot really be too low either, as all +/// relevant disputes _should_ have been seen as included by enough validators. (Otherwise the +/// candidate would not have been available in the first place and could not have been included.) +/// So this is really just a fallback mechanism if things go terribly wrong. +#[cfg(not(test))] +const MAX_SPAM_VOTES: SpamCount = 50; +#[cfg(test)] +const MAX_SPAM_VOTES: SpamCount = 1; + +/// Spam slots for raised disputes concerning unknown candidates. +pub struct SpamSlots { + /// Counts per validator and session. + /// + /// Must not exceed `MAX_SPAM_VOTES`. + slots: HashMap<(SessionIndex, ValidatorIndex), SpamCount>, + + /// All unconfirmed candidates we are aware of right now. + unconfirmed: UnconfirmedDisputes, +} + +/// Unconfirmed disputes to be passed at initialization. +pub type UnconfirmedDisputes = HashMap<(SessionIndex, CandidateHash), BTreeSet>; + +impl SpamSlots { + /// Recover `SpamSlots` from state on startup. + /// + /// Initialize based on already existing active disputes. + pub fn recover_from_state(unconfirmed_disputes: UnconfirmedDisputes) -> Self { + let mut slots: HashMap<(SessionIndex, ValidatorIndex), SpamCount> = HashMap::new(); + for ((session, _), validators) in unconfirmed_disputes.iter() { + for validator in validators { + let spam_vote_count = slots.entry((*session, *validator)).or_default(); + *spam_vote_count += 1; + if *spam_vote_count > MAX_SPAM_VOTES { + gum::debug!( + target: LOG_TARGET, + ?session, + ?validator, + count = ?spam_vote_count, + "Import exceeded spam slot for validator" + ); + } + } + } + + Self { slots, unconfirmed: unconfirmed_disputes } + } + + /// Increase a "voting invalid" validator's spam slot. + /// + /// This function should get called for any validator's invalidity vote for any not yet + /// confirmed dispute. + /// + /// Returns: `true` if validator still had vacant spam slots, `false` otherwise. + pub fn add_unconfirmed( + &mut self, + session: SessionIndex, + candidate: CandidateHash, + validator: ValidatorIndex, + ) -> bool { + let spam_vote_count = self.slots.entry((session, validator)).or_default(); + if *spam_vote_count >= MAX_SPAM_VOTES { + return false + } + let validators = self.unconfirmed.entry((session, candidate)).or_default(); + + if validators.insert(validator) { + // We only increment spam slots once per candidate, as each validator has to provide an + // opposing vote for sending out its own vote. Therefore, receiving multiple votes for + // a single candidate is expected and should not get punished here. + *spam_vote_count += 1; + } + + true + } + + /// Clear out spam slots for a given candidate in a session. + /// + /// This effectively reduces the spam slot count for all validators participating in a dispute + /// for that candidate. You should call this function once a dispute became obsolete or got + /// confirmed and thus votes for it should no longer be treated as potential spam. + pub fn clear(&mut self, key: &(SessionIndex, CandidateHash)) { + if let Some(validators) = self.unconfirmed.remove(key) { + let (session, _) = key; + for validator in validators { + if let Some(spam_vote_count) = self.slots.remove(&(*session, validator)) { + let new = spam_vote_count - 1; + if new > 0 { + self.slots.insert((*session, validator), new); + } + } + } + } + } + /// Prune all spam slots for sessions older than the given index. + pub fn prune_old(&mut self, oldest_index: SessionIndex) { + self.unconfirmed.retain(|(session, _), _| *session >= oldest_index); + self.slots.retain(|(session, _), _| *session >= oldest_index); + } +} diff --git a/polkadot/node/core/dispute-coordinator/src/status.rs b/polkadot/node/core/dispute-coordinator/src/status.rs new file mode 100644 index 0000000000000000000000000000000000000000..557d1dacca1d36dfadd4a50a351f4281533eea7b --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/status.rs @@ -0,0 +1,58 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_primitives::{dispute_is_inactive, DisputeStatus, Timestamp}; +use polkadot_primitives::{CandidateHash, SessionIndex}; +use std::time::{SystemTime, UNIX_EPOCH}; + +use crate::LOG_TARGET; + +/// Get active disputes as iterator, preserving its `DisputeStatus`. +pub fn get_active_with_status( + recent_disputes: impl Iterator, + now: Timestamp, +) -> impl Iterator { + recent_disputes.filter(move |(_, status)| !dispute_is_inactive(status, &now)) +} + +pub trait Clock: Send + Sync { + fn now(&self) -> Timestamp; +} + +pub struct SystemClock; + +impl Clock for SystemClock { + fn now(&self) -> Timestamp { + // `SystemTime` is notoriously non-monotonic, so our timers might not work + // exactly as expected. + // + // Regardless, disputes are considered active based on an order of minutes, + // so a few seconds of slippage in either direction shouldn't affect the + // amount of work the node is doing significantly. + match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(d) => d.as_secs(), + Err(e) => { + gum::warn!( + target: LOG_TARGET, + err = ?e, + "Current time is before unix epoch. Validation will not work correctly." + ); + + 0 + }, + } + } +} diff --git a/polkadot/node/core/dispute-coordinator/src/tests.rs b/polkadot/node/core/dispute-coordinator/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..75eae8200dc6afa0ea5b5446b0ecc78564602d1f --- /dev/null +++ b/polkadot/node/core/dispute-coordinator/src/tests.rs @@ -0,0 +1,3589 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{ + collections::HashMap, + sync::{ + atomic::{AtomicU64, Ordering as AtomicOrdering}, + Arc, + }, + time::Duration, +}; + +use assert_matches::assert_matches; +use futures::{ + channel::oneshot, + future::{self, BoxFuture}, +}; + +use polkadot_node_subsystem_util::database::Database; + +use polkadot_node_primitives::{ + DisputeMessage, DisputeStatus, SignedDisputeStatement, SignedFullStatement, Statement, + DISPUTE_WINDOW, +}; +use polkadot_node_subsystem::{ + messages::{ + ApprovalVotingMessage, ChainApiMessage, ChainSelectionMessage, DisputeCoordinatorMessage, + DisputeDistributionMessage, ImportStatementsResult, + }, + overseer::FromOrchestra, + OverseerSignal, +}; + +use polkadot_node_subsystem_util::TimeoutExt; +use sc_keystore::LocalKeystore; +use sp_application_crypto::AppCrypto; +use sp_core::{sr25519::Pair, testing::TaskExecutor, Pair as PairT}; +use sp_keyring::Sr25519Keyring; +use sp_keystore::{Keystore, KeystorePtr}; + +use ::test_helpers::{dummy_candidate_receipt_bad_sig, dummy_digest, dummy_hash}; +use polkadot_node_primitives::{Timestamp, ACTIVE_DURATION_SECS}; +use polkadot_node_subsystem::{ + jaeger, + messages::{AllMessages, BlockDescription, RuntimeApiMessage, RuntimeApiRequest}, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, +}; +use polkadot_node_subsystem_test_helpers::{ + make_buffered_subsystem_context, TestSubsystemContextHandle, +}; +use polkadot_primitives::{ + ApprovalVote, BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash, + CandidateReceipt, CoreIndex, DisputeStatement, GroupIndex, Hash, HeadData, Header, IndexedVec, + MultiDisputeStatementSet, ScrapedOnChainVotes, SessionIndex, SessionInfo, SigningContext, + ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorSignature, +}; + +use crate::{ + backend::Backend, + metrics::Metrics, + participation::{participation_full_happy_path, participation_missing_availability}, + status::Clock, + Config, DisputeCoordinatorSubsystem, +}; + +use super::db::v1::DbBackend; + +const TEST_TIMEOUT: Duration = Duration::from_secs(2); + +// sets up a keystore with the given keyring accounts. +fn make_keystore(seeds: impl Iterator) -> LocalKeystore { + let store = LocalKeystore::in_memory(); + + for s in seeds { + store + .sr25519_generate_new(polkadot_primitives::PARACHAIN_KEY_TYPE_ID, Some(&s)) + .unwrap(); + } + + store +} + +type VirtualOverseer = TestSubsystemContextHandle; + +const OVERSEER_RECEIVE_TIMEOUT: Duration = Duration::from_secs(2); + +async fn overseer_recv(virtual_overseer: &mut VirtualOverseer) -> AllMessages { + virtual_overseer + .recv() + .timeout(OVERSEER_RECEIVE_TIMEOUT) + .await + .expect("overseer `recv` timed out") +} + +enum VoteType { + Backing, + Explicit, +} + +/// Helper to condense repeated code that creates vote pairs, one valid and one +/// invalid. Optionally the valid vote of the pair can be made a backing vote. +async fn generate_opposing_votes_pair( + test_state: &TestState, + valid_voter_idx: ValidatorIndex, + invalid_voter_idx: ValidatorIndex, + candidate_hash: CandidateHash, + session: SessionIndex, + valid_vote_type: VoteType, +) -> (SignedDisputeStatement, SignedDisputeStatement) { + let valid_vote = match valid_vote_type { + VoteType::Backing => + test_state.issue_backing_statement_with_index(valid_voter_idx, candidate_hash, session), + VoteType::Explicit => test_state.issue_explicit_statement_with_index( + valid_voter_idx, + candidate_hash, + session, + true, + ), + }; + let invalid_vote = test_state.issue_explicit_statement_with_index( + invalid_voter_idx, + candidate_hash, + session, + false, + ); + + (valid_vote, invalid_vote) +} + +#[derive(Clone)] +struct MockClock { + time: Arc, +} + +impl Default for MockClock { + fn default() -> Self { + MockClock { time: Arc::new(AtomicU64::default()) } + } +} + +impl Clock for MockClock { + fn now(&self) -> Timestamp { + self.time.load(AtomicOrdering::SeqCst) + } +} + +impl MockClock { + fn set(&self, to: Timestamp) { + self.time.store(to, AtomicOrdering::SeqCst) + } +} + +struct TestState { + validators: Vec, + validator_public: IndexedVec, + validator_groups: IndexedVec>, + master_keystore: Arc, + subsystem_keystore: Arc, + db: Arc, + config: Config, + clock: MockClock, + headers: HashMap, + block_num_to_header: HashMap, + last_block: Hash, + // last session the subsystem knows about. + known_session: Option, +} + +impl Default for TestState { + fn default() -> TestState { + let p1 = Pair::from_string("//Polka", None).unwrap(); + let p2 = Pair::from_string("//Dot", None).unwrap(); + let p3 = Pair::from_string("//Kusama", None).unwrap(); + let validators = vec![ + (Sr25519Keyring::Alice.pair(), Sr25519Keyring::Alice.to_seed()), + (Sr25519Keyring::Bob.pair(), Sr25519Keyring::Bob.to_seed()), + (Sr25519Keyring::Charlie.pair(), Sr25519Keyring::Charlie.to_seed()), + (Sr25519Keyring::Dave.pair(), Sr25519Keyring::Dave.to_seed()), + (Sr25519Keyring::Eve.pair(), Sr25519Keyring::Eve.to_seed()), + (Sr25519Keyring::One.pair(), Sr25519Keyring::One.to_seed()), + (Sr25519Keyring::Ferdie.pair(), Sr25519Keyring::Ferdie.to_seed()), + // Two more keys needed so disputes are not confirmed already with only 3 statements. + (p1, "//Polka".into()), + (p2, "//Dot".into()), + (p3, "//Kusama".into()), + ]; + + let validator_public = validators + .clone() + .into_iter() + .map(|k| ValidatorId::from(k.0.public())) + .collect(); + + let validator_groups = IndexedVec::>::from(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2), ValidatorIndex(3)], + vec![ValidatorIndex(4), ValidatorIndex(5), ValidatorIndex(6)], + ]); + + let master_keystore = make_keystore(validators.iter().map(|v| v.1.clone())).into(); + let subsystem_keystore = + make_keystore(vec![Sr25519Keyring::Alice.to_seed()].into_iter()).into(); + + let db = kvdb_memorydb::create(1); + let db = polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter::new(db, &[0]); + let db = Arc::new(db); + let config = Config { col_dispute_data: 0 }; + + let genesis_header = Header { + parent_hash: Hash::zero(), + number: 0, + digest: dummy_digest(), + state_root: dummy_hash(), + extrinsics_root: dummy_hash(), + }; + let last_block = genesis_header.hash(); + + let mut headers = HashMap::new(); + let _ = headers.insert(last_block, genesis_header.clone()); + let mut block_num_to_header = HashMap::new(); + let _ = block_num_to_header.insert(genesis_header.number, last_block); + + TestState { + validators: validators.into_iter().map(|(pair, _)| pair).collect(), + validator_public, + validator_groups, + master_keystore, + subsystem_keystore, + db, + config, + clock: MockClock::default(), + headers, + block_num_to_header, + last_block, + known_session: None, + } + } +} + +impl TestState { + async fn activate_leaf_at_session( + &mut self, + virtual_overseer: &mut VirtualOverseer, + session: SessionIndex, + block_number: BlockNumber, + candidate_events: Vec, + ) { + assert!(block_number > 0); + + let block_header = Header { + parent_hash: self.last_block, + number: block_number, + digest: dummy_digest(), + state_root: dummy_hash(), + extrinsics_root: dummy_hash(), + }; + let block_hash = block_header.hash(); + + let _ = self.headers.insert(block_hash, block_header.clone()); + let _ = self.block_num_to_header.insert(block_header.number, block_hash); + self.last_block = block_hash; + + gum::debug!(?block_number, "Activating block in activate_leaf_at_session."); + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: block_hash, + span: Arc::new(jaeger::Span::Disabled), + number: block_number, + status: LeafStatus::Fresh, + }), + ))) + .await; + + self.handle_sync_queries(virtual_overseer, block_hash, session, candidate_events) + .await; + } + + /// Returns any sent `DisputeMessage`s. + async fn handle_sync_queries( + &mut self, + virtual_overseer: &mut VirtualOverseer, + block_hash: Hash, + session: SessionIndex, + candidate_events: Vec, + ) -> Vec { + // Order of messages is not fixed (different on initializing): + #[derive(Debug)] + struct FinishedSteps { + got_session_information: bool, + got_scraping_information: bool, + } + + impl FinishedSteps { + fn new() -> Self { + Self { got_session_information: false, got_scraping_information: false } + } + fn is_done(&self) -> bool { + self.got_session_information && self.got_scraping_information + } + } + + let mut finished_steps = FinishedSteps::new(); + let mut sent_disputes = Vec::new(); + + while !finished_steps.is_done() { + let recv = overseer_recv(virtual_overseer).await; + match recv { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + assert!( + !finished_steps.got_session_information, + "session infos already retrieved" + ); + finished_steps.got_session_information = true; + assert_eq!(h, block_hash); + let _ = tx.send(Ok(session)); + + let first_expected_session = session.saturating_sub(DISPUTE_WINDOW.get() - 1); + + // Queries for session caching - see `handle_startup` + if self.known_session.is_none() { + for i in first_expected_session..=session { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::SessionInfo(session_index, tx), + )) => { + assert_eq!(h, block_hash); + assert_eq!(session_index, i); + let _ = tx.send(Ok(Some(self.session_info()))); + } + ); + } + } + + self.known_session = Some(session); + }, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(tx)) => { + assert!( + !finished_steps.got_scraping_information, + "Scraping info was already retrieved!" + ); + finished_steps.got_scraping_information = true; + tx.send(Ok(0)).unwrap(); + }, + AllMessages::ChainApi(ChainApiMessage::BlockNumber(hash, tx)) => { + let block_num = self.headers.get(&hash).map(|header| header.number); + tx.send(Ok(block_num)).unwrap(); + }, + AllMessages::DisputeDistribution(DisputeDistributionMessage::SendDispute(msg)) => { + sent_disputes.push(msg); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _new_leaf, + RuntimeApiRequest::CandidateEvents(tx), + )) => { + tx.send(Ok(candidate_events.clone())).unwrap(); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _new_leaf, + RuntimeApiRequest::FetchOnChainVotes(tx), + )) => { + //add some `BackedCandidates` or resolved disputes here as needed + tx.send(Ok(Some(ScrapedOnChainVotes { + session, + backing_validators_per_candidate: Vec::default(), + disputes: MultiDisputeStatementSet::default(), + }))) + .unwrap(); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _new_leaf, + RuntimeApiRequest::UnappliedSlashes(tx), + )) => { + tx.send(Ok(Vec::new())).unwrap(); + }, + AllMessages::ChainApi(ChainApiMessage::Ancestors { hash, k, response_channel }) => { + let target_header = self + .headers + .get(&hash) + .expect("The function is called for this block so it should exist"); + let mut response = Vec::new(); + for i in target_header.number.saturating_sub(k as u32)..target_header.number { + response.push( + *self + .block_num_to_header + .get(&i) + .expect("headers and block_num_to_header should always be in sync"), + ); + } + let _ = response_channel.send(Ok(response)); + }, + msg => { + panic!("Received unexpected message in `handle_sync_queries`: {:?}", msg); + }, + } + } + return sent_disputes + } + + async fn handle_resume_sync( + &mut self, + virtual_overseer: &mut VirtualOverseer, + session: SessionIndex, + ) -> Vec { + self.handle_resume_sync_with_events(virtual_overseer, session, Vec::new()).await + } + + async fn handle_resume_sync_with_events( + &mut self, + virtual_overseer: &mut VirtualOverseer, + session: SessionIndex, + mut initial_events: Vec, + ) -> Vec { + let leaves: Vec = self.headers.keys().cloned().collect(); + let mut messages = Vec::new(); + for (n, leaf) in leaves.iter().enumerate() { + gum::debug!( + block_number= ?n, + "Activating block in handle resume sync." + ); + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: *leaf, + number: n as u32, + span: Arc::new(jaeger::Span::Disabled), + status: LeafStatus::Fresh, + }), + ))) + .await; + + let events = if n == 1 { std::mem::take(&mut initial_events) } else { Vec::new() }; + + let mut new_messages = + self.handle_sync_queries(virtual_overseer, *leaf, session, events).await; + messages.append(&mut new_messages); + } + messages + } + + fn session_info(&self) -> SessionInfo { + let discovery_keys = self.validators.iter().map(|k| <_>::from(k.public())).collect(); + + let assignment_keys = self.validators.iter().map(|k| <_>::from(k.public())).collect(); + + SessionInfo { + validators: self.validator_public.clone(), + discovery_keys, + assignment_keys, + validator_groups: self.validator_groups.clone(), + n_cores: self.validator_groups.len() as _, + zeroth_delay_tranche_width: 0, + relay_vrf_modulo_samples: 1, + n_delay_tranches: 100, + no_show_slots: 1, + needed_approvals: 10, + active_validator_indices: Vec::new(), + dispute_period: 6, + random_seed: [0u8; 32], + } + } + + fn issue_explicit_statement_with_index( + &self, + index: ValidatorIndex, + candidate_hash: CandidateHash, + session: SessionIndex, + valid: bool, + ) -> SignedDisputeStatement { + let public = self.validator_public.get(index).unwrap().clone(); + + let keystore = self.master_keystore.clone() as KeystorePtr; + + SignedDisputeStatement::sign_explicit(&keystore, valid, candidate_hash, session, public) + .unwrap() + .unwrap() + } + + fn issue_backing_statement_with_index( + &self, + index: ValidatorIndex, + candidate_hash: CandidateHash, + session: SessionIndex, + ) -> SignedDisputeStatement { + let keystore = self.master_keystore.clone() as KeystorePtr; + let validator_id = self.validators[index.0 as usize].public().into(); + let context = + SigningContext { session_index: session, parent_hash: Hash::repeat_byte(0xac) }; + + let statement = SignedFullStatement::sign( + &keystore, + Statement::Valid(candidate_hash), + &context, + index, + &validator_id, + ) + .unwrap() + .unwrap() + .into_unchecked(); + + SignedDisputeStatement::from_backing_statement(&statement, context, validator_id).unwrap() + } + + fn issue_approval_vote_with_index( + &self, + index: ValidatorIndex, + candidate_hash: CandidateHash, + session: SessionIndex, + ) -> SignedDisputeStatement { + let keystore = self.master_keystore.clone() as KeystorePtr; + let validator_id = self.validators[index.0 as usize].public(); + + let payload = ApprovalVote(candidate_hash).signing_payload(session); + let signature = keystore + .sr25519_sign(ValidatorId::ID, &validator_id, &payload) + .ok() + .flatten() + .unwrap(); + + SignedDisputeStatement::new_unchecked_from_trusted_source( + DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking), + candidate_hash, + session, + validator_id.into(), + signature.into(), + ) + } + + fn resume(mut self, test: F) -> Self + where + F: FnOnce(TestState, VirtualOverseer) -> BoxFuture<'static, TestState>, + { + self.known_session = None; + let (ctx, ctx_handle) = make_buffered_subsystem_context(TaskExecutor::new(), 1); + let subsystem = DisputeCoordinatorSubsystem::new( + self.db.clone(), + self.config, + self.subsystem_keystore.clone(), + Metrics::default(), + ); + let backend = + DbBackend::new(self.db.clone(), self.config.column_config(), Metrics::default()); + let subsystem_task = subsystem.run(ctx, backend, Box::new(self.clock.clone())); + let test_task = test(self, ctx_handle); + + let (_, state) = futures::executor::block_on(future::join(subsystem_task, test_task)); + state + } +} + +fn test_harness(test: F) -> TestState +where + F: FnOnce(TestState, VirtualOverseer) -> BoxFuture<'static, TestState>, +{ + let mut test_state = TestState::default(); + + // Add two more blocks after the genesis (which is created in `default()`) + let h1 = Header { + parent_hash: test_state.last_block, + number: 1, + digest: dummy_digest(), + state_root: dummy_hash(), + extrinsics_root: dummy_hash(), + }; + let h1_hash = h1.hash(); + test_state.headers.insert(h1_hash, h1); + test_state.block_num_to_header.insert(1, h1_hash); + test_state.last_block = h1_hash; + + let h2 = Header { + parent_hash: test_state.last_block, + number: 2, + digest: dummy_digest(), + state_root: dummy_hash(), + extrinsics_root: dummy_hash(), + }; + let h2_hash = h2.hash(); + test_state.headers.insert(h2_hash, h2); + test_state.block_num_to_header.insert(2, h2_hash); + test_state.last_block = h2_hash; + + test_state.resume(test) +} + +/// Handle participation messages. +async fn participation_with_distribution( + virtual_overseer: &mut VirtualOverseer, + candidate_hash: &CandidateHash, + expected_commitments_hash: Hash, +) { + participation_full_happy_path(virtual_overseer, expected_commitments_hash).await; + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::DisputeDistribution( + DisputeDistributionMessage::SendDispute(msg) + ) => { + assert_eq!(&msg.candidate_receipt().hash(), candidate_hash); + } + ); +} + +fn make_valid_candidate_receipt() -> CandidateReceipt { + let mut candidate_receipt = dummy_candidate_receipt_bad_sig(dummy_hash(), dummy_hash()); + candidate_receipt.commitments_hash = CandidateCommitments::default().hash(); + candidate_receipt +} + +fn make_invalid_candidate_receipt() -> CandidateReceipt { + dummy_candidate_receipt_bad_sig(Default::default(), Some(Default::default())) +} + +// Generate a `CandidateBacked` event from a `CandidateReceipt`. The rest is dummy data. +fn make_candidate_backed_event(candidate_receipt: CandidateReceipt) -> CandidateEvent { + CandidateEvent::CandidateBacked( + candidate_receipt, + HeadData(Vec::new()), + CoreIndex(0), + GroupIndex(0), + ) +} + +// Generate a `CandidateIncluded` event from a `CandidateReceipt`. The rest is dummy data. +fn make_candidate_included_event(candidate_receipt: CandidateReceipt) -> CandidateEvent { + CandidateEvent::CandidateIncluded( + candidate_receipt, + HeadData(Vec::new()), + CoreIndex(0), + GroupIndex(0), + ) +} + +/// Handle request for approval votes: +pub async fn handle_approval_vote_request( + ctx_handle: &mut VirtualOverseer, + expected_hash: &CandidateHash, + votes_to_send: HashMap, +) { + assert_matches!( + ctx_handle.recv().await, + AllMessages::ApprovalVoting( + ApprovalVotingMessage::GetApprovalSignaturesForCandidate(hash, tx) + ) => { + assert_eq!(&hash, expected_hash); + tx.send(votes_to_send).unwrap(); + }, + "overseer did not receive `GetApprovalSignaturesForCandidate` message.", + ); +} + +/// Handle block number request. In the context of these tests this message is required for +/// handling comparator creation for enqueuing participations. +async fn handle_get_block_number(ctx_handle: &mut VirtualOverseer, test_state: &TestState) { + assert_matches!( + ctx_handle.recv().await, + AllMessages::ChainApi( + ChainApiMessage::BlockNumber(hash, tx)) => { + tx.send(Ok(test_state.headers.get(&hash).map(|r| r.number))).unwrap(); + } + ) +} + +#[test] +fn too_many_unconfirmed_statements_are_considered_spam() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt1 = make_valid_candidate_receipt(); + let candidate_hash1 = candidate_receipt1.hash(); + let candidate_receipt2 = make_invalid_candidate_receipt(); + let candidate_hash2 = candidate_receipt2.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let (valid_vote1, invalid_vote1) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(3), + ValidatorIndex(1), + candidate_hash1, + session, + VoteType::Backing, + ) + .await; + + let (valid_vote2, invalid_vote2) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(3), + ValidatorIndex(1), + candidate_hash2, + session, + VoteType::Backing, + ) + .await; + + gum::trace!("Before sending `ImportStatements`"); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt1.clone(), + session, + statements: vec![ + (valid_vote1, ValidatorIndex(3)), + (invalid_vote1, ValidatorIndex(1)), + ], + pending_confirmation: None, + }, + }) + .await; + gum::trace!("After sending `ImportStatements`"); + + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash1, HashMap::new()) + .await; + + // Participation has to fail here, otherwise the dispute will be confirmed. However + // participation won't happen at all because the dispute is neither backed, not + // confirmed nor the candidate is included. Or in other words - we'll refrain from + // participation. + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!( + rx.await.unwrap(), + vec![(session, candidate_hash1, DisputeStatus::Active)] + ); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash1)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 1); + assert_eq!(votes.invalid.len(), 1); + } + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt2.clone(), + session, + statements: vec![ + (valid_vote2, ValidatorIndex(3)), + (invalid_vote2, ValidatorIndex(1)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash2, HashMap::new()) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash2)], + tx, + ), + }) + .await; + + assert_matches!(rx.await.unwrap().get(0), None); + } + + // Result should be invalid, because it should be considered spam. + assert_matches!(confirmation_rx.await, Ok(ImportStatementsResult::InvalidImport)); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + // No more messages expected: + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn approval_vote_import_works() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt1 = make_valid_candidate_receipt(); + let candidate_hash1 = candidate_receipt1.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let (valid_vote1, invalid_vote1) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(3), + ValidatorIndex(1), + candidate_hash1, + session, + VoteType::Backing, + ) + .await; + + let approval_vote = test_state.issue_approval_vote_with_index( + ValidatorIndex(4), + candidate_hash1, + session, + ); + + gum::trace!("Before sending `ImportStatements`"); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt1.clone(), + session, + statements: vec![ + (valid_vote1, ValidatorIndex(3)), + (invalid_vote1, ValidatorIndex(1)), + ], + pending_confirmation: None, + }, + }) + .await; + gum::trace!("After sending `ImportStatements`"); + + let approval_votes = [(ValidatorIndex(4), approval_vote.into_validator_signature())] + .into_iter() + .collect(); + + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash1, approval_votes) + .await; + + // Participation won't happen here because the dispute is neither backed, not confirmed + // nor the candidate is included. Or in other words - we'll refrain from participation. + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!( + rx.await.unwrap(), + vec![(session, candidate_hash1, DisputeStatus::Active)] + ); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash1)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 2); + assert!( + votes.valid.raw().get(&ValidatorIndex(4)).is_some(), + "Approval vote is missing!" + ); + assert_eq!(votes.invalid.len(), 1); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + // No more messages expected: + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn dispute_gets_confirmed_via_participation() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt1 = make_valid_candidate_receipt(); + let candidate_hash1 = candidate_receipt1.hash(); + let candidate_receipt2 = make_invalid_candidate_receipt(); + let candidate_hash2 = candidate_receipt2.hash(); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![ + make_candidate_backed_event(candidate_receipt1.clone()), + make_candidate_backed_event(candidate_receipt2.clone()), + ], + ) + .await; + + let (valid_vote1, invalid_vote1) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(3), + ValidatorIndex(1), + candidate_hash1, + session, + VoteType::Explicit, + ) + .await; + + let (valid_vote2, invalid_vote2) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(3), + ValidatorIndex(1), + candidate_hash2, + session, + VoteType::Explicit, + ) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt1.clone(), + session, + statements: vec![ + (valid_vote1, ValidatorIndex(3)), + (invalid_vote1, ValidatorIndex(1)), + ], + pending_confirmation: None, + }, + }) + .await; + gum::debug!("After First import!"); + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash1, HashMap::new()) + .await; + + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash1, + candidate_receipt1.commitments_hash, + ) + .await; + gum::debug!("After Participation!"); + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!( + rx.await.unwrap(), + vec![(session, candidate_hash1, DisputeStatus::Active)] + ); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash1)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 2); + assert_eq!(votes.invalid.len(), 1); + } + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt2.clone(), + session, + statements: vec![ + (valid_vote2, ValidatorIndex(3)), + (invalid_vote2, ValidatorIndex(1)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash2, HashMap::new()) + .await; + + participation_missing_availability(&mut virtual_overseer).await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash2)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 1); + assert_eq!(votes.invalid.len(), 1); + } + + // Result should be valid, because our node participated, so spam slots are cleared: + assert_matches!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + // No more messages expected: + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn dispute_gets_confirmed_at_byzantine_threshold() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt1 = make_valid_candidate_receipt(); + let candidate_hash1 = candidate_receipt1.hash(); + let candidate_receipt2 = make_invalid_candidate_receipt(); + let candidate_hash2 = candidate_receipt2.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let (valid_vote1, invalid_vote1) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(3), + ValidatorIndex(1), + candidate_hash1, + session, + VoteType::Explicit, + ) + .await; + + let (valid_vote1a, invalid_vote1a) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(4), + ValidatorIndex(5), + candidate_hash1, + session, + VoteType::Explicit, + ) + .await; + + let (valid_vote2, invalid_vote2) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(3), + ValidatorIndex(1), + candidate_hash2, + session, + VoteType::Explicit, + ) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt1.clone(), + session, + statements: vec![ + (valid_vote1, ValidatorIndex(3)), + (invalid_vote1, ValidatorIndex(1)), + (valid_vote1a, ValidatorIndex(4)), + (invalid_vote1a, ValidatorIndex(5)), + ], + pending_confirmation: None, + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash1, HashMap::new()) + .await; + + // Participation won't happen here because the dispute is neither backed, not confirmed + // nor the candidate is included. Or in other words - we'll refrain from participation. + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!( + rx.await.unwrap(), + vec![(session, candidate_hash1, DisputeStatus::Confirmed)] + ); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash1)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 2); + assert_eq!(votes.invalid.len(), 2); + } + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt2.clone(), + session, + statements: vec![ + (valid_vote2, ValidatorIndex(3)), + (invalid_vote2, ValidatorIndex(1)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash2, HashMap::new()) + .await; + + participation_missing_availability(&mut virtual_overseer).await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash2)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 1); + assert_eq!(votes.invalid.len(), 1); + } + + // Result should be valid, because byzantine threshold has been reached in first + // import, so spam slots are cleared: + assert_matches!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + // No more messages expected: + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn backing_statements_import_works_and_no_spam() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let valid_vote1 = test_state.issue_backing_statement_with_index( + ValidatorIndex(3), + candidate_hash, + session, + ); + + let valid_vote2 = test_state.issue_backing_statement_with_index( + ValidatorIndex(4), + candidate_hash, + session, + ); + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote1, ValidatorIndex(3)), + (valid_vote2, ValidatorIndex(4)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + assert_matches!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + { + // Just backing votes - we should not have any active disputes now. + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 2); + assert_eq!(votes.invalid.len(), 0); + } + + let candidate_receipt = make_invalid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + let valid_vote1 = test_state.issue_backing_statement_with_index( + ValidatorIndex(3), + candidate_hash, + session, + ); + + let valid_vote2 = test_state.issue_backing_statement_with_index( + ValidatorIndex(4), + candidate_hash, + session, + ); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![make_candidate_backed_event(candidate_receipt.clone())], + ) + .await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + // Backing vote import should not have accounted to spam slots, so this should succeed + // as well: + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote1, ValidatorIndex(3)), + (valid_vote2, ValidatorIndex(4)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + + // Import should be valid, as spam slots were not filled + assert_matches!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + // No more messages expected: + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn conflicting_votes_lead_to_dispute_participation() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![make_candidate_backed_event(candidate_receipt.clone())], + ) + .await; + + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(3), + ValidatorIndex(1), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + let invalid_vote_2 = test_state.issue_explicit_statement_with_index( + ValidatorIndex(2), + candidate_hash, + session, + false, + ); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(3)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation: None, + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + candidate_receipt.commitments_hash, + ) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!( + rx.await.unwrap(), + vec![(session, candidate_hash, DisputeStatus::Active)] + ); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 2); + assert_eq!(votes.invalid.len(), 1); + } + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(invalid_vote_2, ValidatorIndex(2))], + pending_confirmation: None, + }, + }) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 2); + assert_eq!(votes.invalid.len(), 2); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + // This confirms that the second vote doesn't lead to participation again. + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn positive_votes_dont_trigger_participation() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![make_candidate_backed_event(candidate_receipt.clone())], + ) + .await; + + let valid_vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(2), + candidate_hash, + session, + true, + ); + + let valid_vote_2 = test_state.issue_explicit_statement_with_index( + ValidatorIndex(1), + candidate_hash, + session, + true, + ); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(valid_vote, ValidatorIndex(2))], + pending_confirmation: None, + }, + }) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 1); + assert!(votes.invalid.is_empty()); + } + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(valid_vote_2, ValidatorIndex(1))], + pending_confirmation: None, + }, + }) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 2); + assert!(votes.invalid.is_empty()); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + // This confirms that no participation request is made. + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn wrong_validator_index_is_ignored() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(2), + ValidatorIndex(1), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation: None, + }, + }) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + assert_matches!(rx.await.unwrap().get(0), None); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + // This confirms that no participation request is made. + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn finality_votes_ignore_disputed_candidates() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![make_candidate_backed_event(candidate_receipt.clone())], + ) + .await; + + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(2), + ValidatorIndex(1), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(2)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation: None, + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + candidate_receipt.commitments_hash, + ) + .await; + + { + let (tx, rx) = oneshot::channel(); + + let base_block = Hash::repeat_byte(0x0f); + let block_hash_a = Hash::repeat_byte(0x0a); + let block_hash_b = Hash::repeat_byte(0x0b); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::DetermineUndisputedChain { + base: (10, base_block), + block_descriptions: vec![BlockDescription { + block_hash: block_hash_a, + session, + candidates: vec![candidate_hash], + }], + tx, + }, + }) + .await; + + assert_eq!(rx.await.unwrap(), (10, base_block)); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::DetermineUndisputedChain { + base: (10, base_block), + block_descriptions: vec![ + BlockDescription { + block_hash: block_hash_a, + session, + candidates: vec![], + }, + BlockDescription { + block_hash: block_hash_b, + session, + candidates: vec![candidate_hash], + }, + ], + tx, + }, + }) + .await; + + assert_eq!(rx.await.unwrap(), (11, block_hash_a)); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn supermajority_valid_dispute_may_be_finalized() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![make_candidate_backed_event(candidate_receipt.clone())], + ) + .await; + + let supermajority_threshold = + polkadot_primitives::supermajority_threshold(test_state.validators.len()); + + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(2), + ValidatorIndex(1), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(2)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation: None, + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + candidate_receipt.commitments_hash, + ) + .await; + + let mut statements = Vec::new(); + for i in (0_u32..supermajority_threshold as u32 - 1).map(|i| i + 3) { + let vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(i), + candidate_hash, + session, + true, + ); + + statements.push((vote, ValidatorIndex(i as _))); + } + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements, + pending_confirmation: None, + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + { + let (tx, rx) = oneshot::channel(); + + let base_hash = Hash::repeat_byte(0x0f); + let block_hash_a = Hash::repeat_byte(0x0a); + let block_hash_b = Hash::repeat_byte(0x0b); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::DetermineUndisputedChain { + base: (10, base_hash), + block_descriptions: vec![BlockDescription { + block_hash: block_hash_a, + session, + candidates: vec![candidate_hash], + }], + tx, + }, + }) + .await; + + assert_eq!(rx.await.unwrap(), (11, block_hash_a)); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::DetermineUndisputedChain { + base: (10, base_hash), + block_descriptions: vec![ + BlockDescription { + block_hash: block_hash_a, + session, + candidates: vec![], + }, + BlockDescription { + block_hash: block_hash_b, + session, + candidates: vec![candidate_hash], + }, + ], + tx, + }, + }) + .await; + + assert_eq!(rx.await.unwrap(), (12, block_hash_b)); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn concluded_supermajority_for_non_active_after_time() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![make_candidate_backed_event(candidate_receipt.clone())], + ) + .await; + + let supermajority_threshold = + polkadot_primitives::supermajority_threshold(test_state.validators.len()); + + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(2), + ValidatorIndex(1), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(2)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation: None, + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + candidate_receipt.commitments_hash, + ) + .await; + + let mut statements = Vec::new(); + // -2: 1 for already imported vote and one for local vote (which is valid). + for i in (0_u32..supermajority_threshold as u32 - 2).map(|i| i + 3) { + let vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(i), + candidate_hash, + session, + true, + ); + + statements.push((vote, ValidatorIndex(i as _))); + } + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements, + pending_confirmation: None, + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + test_state.clock.set(ACTIVE_DURATION_SECS + 1); + + { + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::RecentDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn concluded_supermajority_against_non_active_after_time() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_invalid_candidate_receipt(); + + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![make_candidate_backed_event(candidate_receipt.clone())], + ) + .await; + + let supermajority_threshold = + polkadot_primitives::supermajority_threshold(test_state.validators.len()); + + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(2), + ValidatorIndex(1), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(2)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + assert_matches!(confirmation_rx.await.unwrap(), + ImportStatementsResult::ValidImport => {} + ); + + // Use a different expected commitments hash to ensure the candidate validation returns + // invalid. + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + CandidateCommitments::default().hash(), + ) + .await; + + let mut statements = Vec::new(); + // minus 2, because of local vote and one previously imported invalid vote. + for i in (0_u32..supermajority_threshold as u32 - 2).map(|i| i + 3) { + let vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(i), + candidate_hash, + session, + false, + ); + + statements.push((vote, ValidatorIndex(i as _))); + } + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements, + pending_confirmation: None, + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + test_state.clock.set(ACTIVE_DURATION_SECS + 1); + + { + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::RecentDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert_matches!( + virtual_overseer.try_recv().await, + None => {} + ); + + test_state + }) + }); +} + +#[test] +fn resume_dispute_without_local_statement() { + sp_tracing::init_for_tests(); + let session = 1; + + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(1), + ValidatorIndex(2), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + // Participation won't happen here because the dispute is neither backed, not confirmed + // nor the candidate is included. Or in other words - we'll refrain from participation. + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + { + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }) + // Alice should send a DisputeParticiationMessage::Participate on restart since she has no + // local statement for the active dispute. + .resume(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let candidate_receipt = make_valid_candidate_receipt(); + // Candidate is now backed: + let dispute_messages = test_state + .handle_resume_sync_with_events( + &mut virtual_overseer, + session, + vec![make_candidate_backed_event(candidate_receipt.clone())], + ) + .await; + + assert_eq!(dispute_messages.len(), 0, "We don't expect any messages sent here."); + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + candidate_receipt.commitments_hash, + ) + .await; + + let mut statements = Vec::new(); + // Getting votes for supermajority. Should already have two valid votes. + for i in vec![3, 4, 5, 6, 7] { + let vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(i), + candidate_hash, + session, + true, + ); + + statements.push((vote, ValidatorIndex(i as _))); + } + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements, + pending_confirmation: None, + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + // Advance the clock far enough so that the concluded dispute will be omitted from an + // ActiveDisputes query. + test_state.clock.set(test_state.clock.now() + ACTIVE_DURATION_SECS + 1); + + { + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn resume_dispute_with_local_statement() { + sp_tracing::init_for_tests(); + let session = 1; + + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![make_candidate_backed_event(candidate_receipt.clone())], + ) + .await; + + let local_valid_vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(0), + candidate_hash, + session, + true, + ); + + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(1), + ValidatorIndex(2), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (local_valid_vote, ValidatorIndex(0)), + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + { + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }) + // Alice should not send a DisputeParticiationMessage::Participate on restart since she has a + // local statement for the active dispute, instead she should try to (re-)send her vote. + .resume(|mut test_state, mut virtual_overseer| { + let candidate_receipt = make_valid_candidate_receipt(); + Box::pin(async move { + let messages = test_state + .handle_resume_sync_with_events( + &mut virtual_overseer, + session, + vec![make_candidate_backed_event(candidate_receipt.clone())], + ) + .await; + + assert_eq!(messages.len(), 1, "A message should have gone out."); + + // Assert that subsystem is not sending Participation messages because we issued a local + // statement + assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn resume_dispute_without_local_statement_or_local_key() { + let session = 1; + let mut test_state = TestState::default(); + test_state.subsystem_keystore = + make_keystore(vec![Sr25519Keyring::Two.to_seed()].into_iter()).into(); + test_state + .resume(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![make_candidate_included_event(candidate_receipt.clone())], + ) + .await; + + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(1), + ValidatorIndex(2), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + handle_approval_vote_request( + &mut virtual_overseer, + &candidate_hash, + HashMap::new(), + ) + .await; + + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + { + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert_matches!( + virtual_overseer.try_recv().await, + None => {} + ); + + test_state + }) + }) + // Two should not send a DisputeParticiationMessage::Participate on restart since she is no + // validator in that dispute. + .resume(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + // Assert that subsystem is not sending Participation messages because we issued a + // local statement + assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn issue_valid_local_statement_does_cause_distribution_but_not_duplicate_participation() { + issue_local_statement_does_cause_distribution_but_not_duplicate_participation(true); +} + +#[test] +fn issue_invalid_local_statement_does_cause_distribution_but_not_duplicate_participation() { + issue_local_statement_does_cause_distribution_but_not_duplicate_participation(false); +} + +fn issue_local_statement_does_cause_distribution_but_not_duplicate_participation(validity: bool) { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let other_vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(1), + candidate_hash, + session, + !validity, + ); + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(other_vote, ValidatorIndex(1))], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + // Initiate dispute locally: + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::IssueLocalStatement( + session, + candidate_hash, + candidate_receipt.clone(), + validity, + ), + }) + .await; + + // Dispute distribution should get notified now: + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::DisputeDistribution( + DisputeDistributionMessage::SendDispute(msg) + ) => { + assert_eq!(msg.session_index(), session); + assert_eq!(msg.candidate_receipt(), &candidate_receipt); + } + ); + + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + // Make sure we won't participate: + assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn own_approval_vote_gets_distributed_on_dispute() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let statement = test_state.issue_approval_vote_with_index( + ValidatorIndex(0), + candidate_hash, + session, + ); + + // Import our approval vote: + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(statement, ValidatorIndex(0))], + pending_confirmation: None, + }, + }) + .await; + + // Trigger dispute: + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(2), + ValidatorIndex(1), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (invalid_vote, ValidatorIndex(1)), + (valid_vote, ValidatorIndex(2)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + // Dispute distribution should get notified now (without participation, as we already + // have an approval vote): + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::DisputeDistribution( + DisputeDistributionMessage::SendDispute(msg) + ) => { + assert_eq!(msg.session_index(), session); + assert_eq!(msg.candidate_receipt(), &candidate_receipt); + } + ); + + // No participation should occur: + assert_matches!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await, None); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn negative_issue_local_statement_only_triggers_import() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_invalid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::IssueLocalStatement( + session, + candidate_hash, + candidate_receipt.clone(), + false, + ), + }) + .await; + + // Assert that subsystem is not participating. + assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + let backend = DbBackend::new( + test_state.db.clone(), + test_state.config.column_config(), + Metrics::default(), + ); + + let votes = backend.load_candidate_votes(session, &candidate_hash).unwrap().unwrap(); + assert_eq!(votes.invalid.len(), 1); + assert_eq!(votes.valid.len(), 0); + + let disputes = backend.load_recent_disputes().unwrap(); + assert_eq!(disputes, None); + + test_state + }) + }); +} + +#[test] +fn redundant_votes_ignored() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let valid_vote = test_state.issue_backing_statement_with_index( + ValidatorIndex(1), + candidate_hash, + session, + ); + + let valid_vote_2 = test_state.issue_backing_statement_with_index( + ValidatorIndex(1), + candidate_hash, + session, + ); + + assert!(valid_vote.validator_signature() != valid_vote_2.validator_signature()); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(valid_vote.clone(), ValidatorIndex(1))], + pending_confirmation: Some(tx), + }, + }) + .await; + + rx.await.unwrap(); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(valid_vote_2, ValidatorIndex(1))], + pending_confirmation: Some(tx), + }, + }) + .await; + + rx.await.unwrap(); + + let backend = DbBackend::new( + test_state.db.clone(), + test_state.config.column_config(), + Metrics::default(), + ); + + let votes = backend.load_candidate_votes(session, &candidate_hash).unwrap().unwrap(); + assert_eq!(votes.invalid.len(), 0); + assert_eq!(votes.valid.len(), 1); + assert_eq!(&votes.valid[0].2, valid_vote.validator_signature()); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +/// Make sure no disputes are recorded when there are no opposing votes, even if we reached +/// supermajority. +fn no_onesided_disputes() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let mut statements = Vec::new(); + for index in 1..10 { + statements.push(( + test_state.issue_backing_statement_with_index( + ValidatorIndex(index), + candidate_hash, + session, + ), + ValidatorIndex(index), + )); + } + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements, + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + assert_matches!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + // We should not have any active disputes now. + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + // No more messages expected: + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn refrain_from_participation() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + // activate leaf - no backing/included event + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + // generate two votes + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(1), + ValidatorIndex(2), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation: None, + }, + }) + .await; + + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 1); + assert_eq!(votes.invalid.len(), 1); + } + + // activate leaf - no backing event + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + // confirm that no participation request is made. + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +/// We have got no `participation_for_backed_candidates` test because most of the other tests (e.g. +/// `dispute_gets_confirmed_via_participation`, `backing_statements_import_works_and_no_spam`) use +/// candidate backing event to trigger participation. If they pass - that case works. +#[test] +fn participation_for_included_candidates() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + // activate leaf - with candidate included event + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![make_candidate_included_event(candidate_receipt.clone())], + ) + .await; + + // generate two votes + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(1), + ValidatorIndex(2), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation: None, + }, + }) + .await; + + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + candidate_receipt.commitments_hash, + ) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + + // check if we have participated (cast a vote) + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 2); // 2 => we have participated + assert_eq!(votes.invalid.len(), 1); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + test_state + }) + }); +} + +/// Shows that importing backing votes when a backing event is being processed +/// results in participation. +#[test] +fn local_participation_in_dispute_for_backed_candidate() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + // Step 1: Show that we don't participate when not backed, confirmed, or included + + // activate leaf - without candidate backed event + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, vec![]) + .await; + + // generate two votes + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(1), + ValidatorIndex(2), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation: None, + }, + }) + .await; + + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + assert_matches!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await, None); + + // Step 2: Show that once backing votes are processed we participate + + // Activate leaf: With candidate backed event + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 1, + vec![make_candidate_backed_event(candidate_receipt.clone())], + ) + .await; + + let backing_valid = test_state.issue_backing_statement_with_index( + ValidatorIndex(3), + candidate_hash, + session, + ); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(backing_valid, ValidatorIndex(3))], + pending_confirmation: None, + }, + }) + .await; + + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + candidate_receipt.commitments_hash, + ) + .await; + + // Check for our 1 active dispute + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + + // check if we have participated (casted a vote) + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 3); // 3 => 1 initial vote, 1 backing vote, and our vote + assert_eq!(votes.invalid.len(), 1); + + // Wrap up + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + test_state + }) + }); +} + +/// Shows that when a candidate_included event is scraped from the chain we +/// reprioritize any participation requests pertaining to that candidate. +/// This involves moving the request for this candidate from the best effort +/// queue to the priority queue. +#[test] +fn participation_requests_reprioritized_for_newly_included() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + let mut receipts: Vec = Vec::new(); + + // Generate all receipts + for repetition in 1..=3u8 { + // Building candidate receipts + let mut candidate_receipt = make_valid_candidate_receipt(); + candidate_receipt.descriptor.pov_hash = Hash::from( + [repetition; 32], // Altering this receipt so its hash will be changed + ); + // Set consecutive parents (starting from zero). They will order the candidates for + // participation. + let parent_block_num: BlockNumber = repetition as BlockNumber - 1; + candidate_receipt.descriptor.relay_parent = + *test_state.block_num_to_header.get(&parent_block_num).unwrap(); + receipts.push(candidate_receipt.clone()); + } + + // Mark all candidates as backed, so their participation requests make it to best + // effort. These calls must all occur before including the candidates due to test + // overseer oddities. + let mut candidate_events = Vec::new(); + for r in receipts.iter() { + candidate_events.push(make_candidate_backed_event(r.clone())) + } + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, candidate_events) + .await; + + for (idx, candidate_receipt) in receipts.iter().enumerate() { + let candidate_hash = candidate_receipt.hash(); + + // Create votes for candidates + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(1), + ValidatorIndex(2), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + // Import votes for candidates + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation: None, + }, + }) + .await; + + // Handle corresponding messages to unblock import + // we need to handle `ApprovalVotingMessage::GetApprovalSignaturesForCandidate` for + // import + handle_approval_vote_request( + &mut virtual_overseer, + &candidate_hash, + HashMap::new(), + ) + .await; + + // We'll trigger participation for the first `MAX_PARALLEL_PARTICIPATIONS` + // candidates. The rest will be queued => we need to handle + // `ChainApiMessage::BlockNumber` for them. + if idx >= crate::participation::MAX_PARALLEL_PARTICIPATIONS { + // We send the `idx` as parent block number, because it is used for ordering. + // This way we get predictable ordering and participation. + handle_get_block_number(&mut virtual_overseer, &test_state).await; + } + } + + // Generate included event for one of the candidates here + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 2, + vec![make_candidate_included_event( + receipts.last().expect("There is more than one candidate").clone(), + )], + ) + .await; + + // NB: The checks below are a bit racy. In theory candidate 2 can be processed even + // before candidate 0 and this is okay. If any of the asserts in the two functions after + // this comment fail -> rework `participation_with_distribution` to expect a set of + // commitment hashes instead of just one. + + // This is the candidate for which participation was started initially + // (`MAX_PARALLEL_PARTICIPATIONS` threshold was not yet hit) + participation_with_distribution( + &mut virtual_overseer, + &receipts.get(0).expect("There is more than one candidate").hash(), + receipts.first().expect("There is more than one candidate").commitments_hash, + ) + .await; + + // This one should have been prioritized + participation_with_distribution( + &mut virtual_overseer, + &receipts.get(2).expect("There is more than one candidate").hash(), + receipts.last().expect("There is more than one candidate").commitments_hash, + ) + .await; + + // And this is the last one + participation_with_distribution( + &mut virtual_overseer, + &receipts.get(1).expect("There is more than one candidate").hash(), + receipts.first().expect("There is more than one candidate").commitments_hash, + ) + .await; + + // Wrap up + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + + test_state + }) + }); +} + +// When a dispute has concluded against a parachain block candidate we want to notify +// the chain selection subsystem. Then chain selection can revert the relay parents of +// the disputed candidate and mark all descendants as non-viable. This direct +// notification saves time compared to letting chain selection learn about a dispute +// conclusion from an on chain revert log. +#[test] +fn informs_chain_selection_when_dispute_concluded_against() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_invalid_candidate_receipt(); + let parent_1_number = 1; + let parent_2_number = 2; + + let candidate_hash = candidate_receipt.hash(); + + // Including test candidate in 2 different parent blocks + let block_1_header = Header { + parent_hash: test_state.last_block, + number: parent_1_number, + digest: dummy_digest(), + state_root: dummy_hash(), + extrinsics_root: dummy_hash(), + }; + let parent_1_hash = block_1_header.hash(); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + parent_1_number, + vec![make_candidate_included_event(candidate_receipt.clone())], + ) + .await; + + let block_2_header = Header { + parent_hash: test_state.last_block, + number: parent_2_number, + digest: dummy_digest(), + state_root: dummy_hash(), + extrinsics_root: dummy_hash(), + }; + let parent_2_hash = block_2_header.hash(); + + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + parent_2_number, + vec![make_candidate_included_event(candidate_receipt.clone())], + ) + .await; + + let byzantine_threshold = + polkadot_primitives::byzantine_threshold(test_state.validators.len()); + + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(2), + ValidatorIndex(1), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(2)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + assert_matches!(confirmation_rx.await.unwrap(), + ImportStatementsResult::ValidImport => {} + ); + + // Use a different expected commitments hash to ensure the candidate validation returns + // invalid. + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + CandidateCommitments::default().hash(), + ) + .await; + + let mut statements = Vec::new(); + // own vote + `byzantine_threshold` more votes should be enough to issue `RevertBlocks` + for i in 3_u32..byzantine_threshold as u32 + 3 { + let vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(i), + candidate_hash, + session, + false, + ); + + statements.push((vote, ValidatorIndex(i))); + } + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements, + pending_confirmation: None, + }, + }) + .await; + + // Checking that concluded dispute has signaled the reversion of all parent blocks. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ChainSelection( + ChainSelectionMessage::RevertBlocks(revert_set) + ) => { + assert!(revert_set.contains(&(parent_1_number, parent_1_hash))); + assert!(revert_set.contains(&(parent_2_number, parent_2_hash))); + }, + "Overseer did not receive `ChainSelectionMessage::RevertBlocks` message" + ); + + // One more import which should not trigger reversion + // Validator index is `byzantine_threshold + 4` + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![( + test_state.issue_explicit_statement_with_index( + ValidatorIndex(byzantine_threshold as u32 + 4), + candidate_hash, + session, + false, + ), + ValidatorIndex(byzantine_threshold as u32 + 4), + )], + pending_confirmation: None, + }, + }) + .await; + + // Wrap up + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert_matches!( + virtual_overseer.try_recv().await, + None => {} + ); + + test_state + }) + }); +} + +// On startup `SessionInfo` cache should be populated +#[test] +fn session_info_caching_on_startup_works() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + test_state + }) + }); +} + +// Underflow means that no more than `DISPUTE_WINDOW` sessions should be fetched on startup +#[test] +fn session_info_caching_doesnt_underflow() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = DISPUTE_WINDOW.get() + 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + test_state + }) + }); +} + +// Cached `SessionInfo` shouldn't be re-requested from the runtime +#[test] +fn session_info_is_requested_only_once() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + // This leaf activation shouldn't fetch `SessionInfo` because the session is already + // cached + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session, + 3, + vec![make_candidate_included_event(make_valid_candidate_receipt())], + ) + .await; + + // This leaf activation should fetch `SessionInfo` because the session is new + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session + 1, + 4, + vec![make_candidate_included_event(make_valid_candidate_receipt())], + ) + .await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionInfo(session_index, tx), + )) => { + assert_eq!(session_index, 2); + let _ = tx.send(Ok(Some(test_state.session_info()))); + } + ); + test_state + }) + }); +} + +// Big jump means the new session we see with a leaf update is at least a `DISPUTE_WINDOW` bigger +// than the already known one. In this case The whole `DISPUTE_WINDOW` should be fetched. +#[test] +fn session_info_big_jump_works() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session_on_startup = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session_on_startup).await; + + // This leaf activation shouldn't fetch `SessionInfo` because the session is already + // cached + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session_on_startup, + 3, + vec![make_candidate_included_event(make_valid_candidate_receipt())], + ) + .await; + + let session_after_jump = session_on_startup + DISPUTE_WINDOW.get() + 10; + // This leaf activation should cache all missing `SessionInfo`s + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session_after_jump, + 4, + vec![make_candidate_included_event(make_valid_candidate_receipt())], + ) + .await; + + let first_expected_session = + session_after_jump.saturating_sub(DISPUTE_WINDOW.get() - 1); + for expected_idx in first_expected_session..=session_after_jump { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionInfo(session_index, tx), + )) => { + assert_eq!(session_index, expected_idx); + let _ = tx.send(Ok(Some(test_state.session_info()))); + } + ); + } + test_state + }) + }); +} + +// Small jump means the new session we see with a leaf update is at less than last known one + +// `DISPUTE_WINDOW`. In this case fetching should start from last known one + 1. +#[test] +fn session_info_small_jump_works() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session_on_startup = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session_on_startup).await; + + // This leaf activation shouldn't fetch `SessionInfo` because the session is already + // cached + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session_on_startup, + 3, + vec![make_candidate_included_event(make_valid_candidate_receipt())], + ) + .await; + + let session_after_jump = session_on_startup + DISPUTE_WINDOW.get() - 1; + // This leaf activation should cache all missing `SessionInfo`s + test_state + .activate_leaf_at_session( + &mut virtual_overseer, + session_after_jump, + 4, + vec![make_candidate_included_event(make_valid_candidate_receipt())], + ) + .await; + + let first_expected_session = session_on_startup + 1; + for expected_idx in first_expected_session..=session_after_jump { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionInfo(session_index, tx), + )) => { + assert_eq!(session_index, expected_idx); + let _ = tx.send(Ok(Some(test_state.session_info()))); + } + ); + } + test_state + }) + }); +} diff --git a/polkadot/node/core/parachains-inherent/Cargo.toml b/polkadot/node/core/parachains-inherent/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..fdf785fbe66bbe2b231fc9bf98372d2a3d794182 --- /dev/null +++ b/polkadot/node/core/parachains-inherent/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "polkadot-node-core-parachains-inherent" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +futures-timer = "3.0.2" +gum = { package = "tracing-gum", path = "../../gum" } +thiserror = "1.0.31" +async-trait = "0.1.57" +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-overseer = { path = "../../overseer" } +polkadot-primitives = { path = "../../../primitives" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/polkadot/node/core/parachains-inherent/src/lib.rs b/polkadot/node/core/parachains-inherent/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..3063147fb1360ad87f76c7a2605104677e893104 --- /dev/null +++ b/polkadot/node/core/parachains-inherent/src/lib.rs @@ -0,0 +1,171 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The parachain inherent data provider +//! +//! Parachain backing and approval is an off-chain process, but the parachain needs to progress on +//! chain as well. To make it progress on chain a block producer needs to forward information about +//! the state of a parachain to the runtime. This information is forwarded through an inherent to +//! the runtime. Here we provide the [`ParachainInherentDataProvider`] that requests the relevant +//! data from the provisioner subsystem and creates the the inherent data that the runtime will use +//! to create an inherent. + +#![deny(unused_crate_dependencies, unused_results)] + +use futures::{select, FutureExt}; +use polkadot_node_subsystem::{ + errors::SubsystemError, messages::ProvisionerMessage, overseer::Handle, +}; +use polkadot_primitives::{Block, Hash, InherentData as ParachainsInherentData}; +use std::{sync::Arc, time}; + +pub(crate) const LOG_TARGET: &str = "parachain::parachains-inherent"; + +/// How long to wait for the provisioner, before giving up. +const PROVISIONER_TIMEOUT: time::Duration = core::time::Duration::from_millis(2500); + +/// Provides the parachains inherent data. +pub struct ParachainsInherentDataProvider> { + pub client: Arc, + pub overseer: polkadot_overseer::Handle, + pub parent: Hash, +} + +impl> ParachainsInherentDataProvider { + /// Create a new [`Self`]. + pub fn new(client: Arc, overseer: polkadot_overseer::Handle, parent: Hash) -> Self { + ParachainsInherentDataProvider { client, overseer, parent } + } + + /// Create a new instance of the [`ParachainsInherentDataProvider`]. + pub async fn create( + client: Arc, + mut overseer: Handle, + parent: Hash, + ) -> Result { + let pid = async { + let (sender, receiver) = futures::channel::oneshot::channel(); + gum::trace!( + target: LOG_TARGET, + relay_parent = ?parent, + "Inherent data requested by Babe" + ); + overseer.wait_for_activation(parent, sender).await; + receiver + .await + .map_err(|_| Error::ClosedChannelAwaitingActivation)? + .map_err(|e| Error::Subsystem(e))?; + + let (sender, receiver) = futures::channel::oneshot::channel(); + gum::trace!( + target: LOG_TARGET, + relay_parent = ?parent, + "Requesting inherent data (after having waited for activation)" + ); + overseer + .send_msg( + ProvisionerMessage::RequestInherentData(parent, sender), + std::any::type_name::(), + ) + .await; + + receiver.await.map_err(|_| Error::ClosedChannelAwaitingInherentData) + }; + + let mut timeout = futures_timer::Delay::new(PROVISIONER_TIMEOUT).fuse(); + + let parent_header = match client.header(parent) { + Ok(Some(h)) => h, + Ok(None) => return Err(Error::ParentHeaderNotFound(parent)), + Err(err) => return Err(Error::Blockchain(err)), + }; + + let res = select! { + pid = pid.fuse() => pid, + _ = timeout => Err(Error::Timeout), + }; + + let inherent_data = match res { + Ok(pd) => ParachainsInherentData { + bitfields: pd.bitfields.into_iter().map(Into::into).collect(), + backed_candidates: pd.backed_candidates, + disputes: pd.disputes, + parent_header, + }, + Err(err) => { + gum::debug!( + target: LOG_TARGET, + %err, + "Could not get provisioner inherent data; injecting default data", + ); + ParachainsInherentData { + bitfields: Vec::new(), + backed_candidates: Vec::new(), + disputes: Vec::new(), + parent_header, + } + }, + }; + + Ok(inherent_data) + } +} + +#[async_trait::async_trait] +impl> sp_inherents::InherentDataProvider + for ParachainsInherentDataProvider +{ + async fn provide_inherent_data( + &self, + dst_inherent_data: &mut sp_inherents::InherentData, + ) -> Result<(), sp_inherents::Error> { + let inherent_data = ParachainsInherentDataProvider::create( + self.client.clone(), + self.overseer.clone(), + self.parent, + ) + .await + .map_err(|e| sp_inherents::Error::Application(Box::new(e)))?; + + dst_inherent_data + .put_data(polkadot_primitives::PARACHAINS_INHERENT_IDENTIFIER, &inherent_data) + } + + async fn try_handle_error( + &self, + _identifier: &sp_inherents::InherentIdentifier, + _error: &[u8], + ) -> Option> { + // Inherent isn't checked and can not return any error + None + } +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("Blockchain error")] + Blockchain(#[from] sp_blockchain::Error), + #[error("Timeout: provisioner did not return inherent data after {:?}", PROVISIONER_TIMEOUT)] + Timeout, + #[error("Could not find the parent header in the blockchain: {:?}", _0)] + ParentHeaderNotFound(Hash), + #[error("Closed channel from overseer when awaiting activation")] + ClosedChannelAwaitingActivation, + #[error("Closed channel from provisioner when awaiting inherent data")] + ClosedChannelAwaitingInherentData, + #[error("Subsystem failed")] + Subsystem(#[from] SubsystemError), +} diff --git a/polkadot/node/core/prospective-parachains/Cargo.toml b/polkadot/node/core/prospective-parachains/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..8afd0e4e8d17cdb49087530bc78992e740ae7a15 --- /dev/null +++ b/polkadot/node/core/prospective-parachains/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "polkadot-node-core-prospective-parachains" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.19" +gum = { package = "tracing-gum", path = "../../gum" } +parity-scale-codec = "3.6.4" +thiserror = "1.0.30" +fatality = "0.0.6" +bitvec = "1" + +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } + +[dev-dependencies] +assert_matches = "1" +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +polkadot-node-subsystem-types = { path = "../../subsystem-types" } +polkadot-primitives-test-helpers = { path = "../../../primitives/test-helpers" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/polkadot/node/core/prospective-parachains/src/error.rs b/polkadot/node/core/prospective-parachains/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..0ad98d1ff9088087dc096d14d20e432dba85264a --- /dev/null +++ b/polkadot/node/core/prospective-parachains/src/error.rs @@ -0,0 +1,87 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Error types. + +use futures::channel::oneshot; + +use polkadot_node_subsystem::{ + errors::{ChainApiError, RuntimeApiError}, + SubsystemError, +}; +use polkadot_node_subsystem_util::runtime; + +use crate::LOG_TARGET; +use fatality::Nested; + +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + #[fatal] + #[error("SubsystemError::Context error: {0}")] + SubsystemContext(String), + + #[fatal] + #[error("Spawning a task failed: {0}")] + SpawnFailed(SubsystemError), + + #[fatal] + #[error("Participation worker receiver exhausted.")] + ParticipationWorkerReceiverExhausted, + + #[fatal] + #[error("Receiving message from overseer failed: {0}")] + SubsystemReceive(#[source] SubsystemError), + + #[error("Error while accessing runtime information")] + Runtime(#[from] runtime::Error), + + #[error(transparent)] + RuntimeApi(#[from] RuntimeApiError), + + #[error(transparent)] + ChainApi(#[from] ChainApiError), + + #[error(transparent)] + Subsystem(SubsystemError), + + #[error("Request to chain API subsystem dropped")] + ChainApiRequestCanceled(oneshot::Canceled), + + #[error("Request to runtime API subsystem dropped")] + RuntimeApiRequestCanceled(oneshot::Canceled), +} + +/// General `Result` type. +pub type Result = std::result::Result; +/// Result for non-fatal only failures. +pub type JfyiErrorResult = std::result::Result; +/// Result for fatal only failures. +pub type FatalResult = std::result::Result; + +/// Utility for eating top level errors and log them. +/// +/// We basically always want to try and continue on error. This utility function is meant to +/// consume top-level errors by simply logging them +pub fn log_error(result: Result<()>, ctx: &'static str) -> FatalResult<()> { + match result.into_nested()? { + Ok(()) => Ok(()), + Err(jfyi) => { + gum::debug!(target: LOG_TARGET, error = ?jfyi, ctx); + Ok(()) + }, + } +} diff --git a/polkadot/node/core/prospective-parachains/src/fragment_tree.rs b/polkadot/node/core/prospective-parachains/src/fragment_tree.rs new file mode 100644 index 0000000000000000000000000000000000000000..ec06f2d6070e58139365ef558c9464195f0367c6 --- /dev/null +++ b/polkadot/node/core/prospective-parachains/src/fragment_tree.rs @@ -0,0 +1,1991 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A tree utility for managing parachain fragments not referenced by the relay-chain. +//! +//! # Overview +//! +//! This module exposes two main types: [`FragmentTree`] and [`CandidateStorage`] which are meant to +//! be used in close conjunction. Each fragment tree is associated with a particular relay-parent +//! and each node in the tree represents a candidate. Each parachain has a single candidate storage, +//! but can have multiple trees for each relay chain block in the view. +//! +//! A tree has an associated [`Scope`] which defines limits on candidates within the tree. +//! Candidates themselves have their own [`Constraints`] which are either the constraints from the +//! scope, or, if there are previous nodes in the tree, a modified version of the previous +//! candidate's constraints. +//! +//! This module also makes use of types provided by the Inclusion Emulator module, such as +//! [`Fragment`] and [`Constraints`]. These perform the actual job of checking for validity of +//! prospective fragments. +//! +//! # Usage +//! +//! It's expected that higher-level code will have a tree for each relay-chain block which might +//! reasonably have blocks built upon it. +//! +//! Because a para only has a single candidate storage, trees only store indices into the storage. +//! The storage is meant to be pruned when trees are dropped by higher-level code. +//! +//! # Cycles +//! +//! Nodes do not uniquely refer to a parachain block for two reasons. +//! 1. There's no requirement that head-data is unique for a parachain. Furthermore, a parachain +//! is under no obligation to be acyclic, and this is mostly just because it's totally +//! inefficient to enforce it. Practical use-cases are acyclic, but there is still more than +//! one way to reach the same head-data. +//! 2. and candidates only refer to their parent by its head-data. This whole issue could be +//! resolved by having candidates reference their parent by candidate hash. +//! +//! The implication is that when we receive a candidate receipt, there are actually multiple +//! possibilities for any candidates between the para-head recorded in the relay parent's state +//! and the candidate in question. +//! +//! This means that our candidates need to handle multiple parents and that depth is an +//! attribute of a node in a tree, not a candidate. Put another way, the same candidate might +//! have different depths in different parts of the tree. +//! +//! As an extreme example, a candidate which produces head-data which is the same as its parent +//! can correspond to multiple nodes within the same [`FragmentTree`]. Such cycles are bounded +//! by the maximum depth allowed by the tree. An example with `max_depth: 4`: +//! +//! ```text +//! committed head +//! | +//! depth 0: head_a +//! | +//! depth 1: head_b +//! | +//! depth 2: head_a +//! | +//! depth 3: head_b +//! | +//! depth 4: head_a +//! ``` +//! +//! As long as the [`CandidateStorage`] has bounded input on the number of candidates supplied, +//! [`FragmentTree`] complexity is bounded. This means that higher-level code needs to be selective +//! about limiting the amount of candidates that are considered. +//! +//! The code in this module is not designed for speed or efficiency, but conceptual simplicity. +//! Our assumption is that the amount of candidates and parachains we consider will be reasonably +//! bounded and in practice will not exceed a few thousand at any time. This naive implementation +//! will still perform fairly well under these conditions, despite being somewhat wasteful of +//! memory. + +use std::{ + borrow::Cow, + collections::{ + hash_map::{Entry, HashMap}, + BTreeMap, HashSet, + }, +}; + +use super::LOG_TARGET; +use bitvec::prelude::*; +use polkadot_node_subsystem_util::inclusion_emulator::staging::{ + ConstraintModifications, Constraints, Fragment, ProspectiveCandidate, RelayChainBlockInfo, +}; +use polkadot_primitives::vstaging::{ + BlockNumber, CandidateHash, CommittedCandidateReceipt, Hash, HeadData, Id as ParaId, + PersistedValidationData, +}; + +/// Kinds of failures to import a candidate into storage. +#[derive(Debug, Clone, PartialEq)] +pub enum CandidateStorageInsertionError { + /// An error indicating that a supplied candidate didn't match the persisted + /// validation data provided alongside it. + PersistedValidationDataMismatch, + /// The candidate was already known. + CandidateAlreadyKnown(CandidateHash), +} + +/// Stores candidates and information about them such as their relay-parents and their backing +/// states. +pub(crate) struct CandidateStorage { + // Index from head data hash to candidate hashes with that head data as a parent. + by_parent_head: HashMap>, + + // Index from head data hash to candidate hashes outputting that head data. + by_output_head: HashMap>, + + // Index from candidate hash to fragment node. + by_candidate_hash: HashMap, +} + +impl CandidateStorage { + /// Create a new `CandidateStorage`. + pub fn new() -> Self { + CandidateStorage { + by_parent_head: HashMap::new(), + by_output_head: HashMap::new(), + by_candidate_hash: HashMap::new(), + } + } + + /// Introduce a new candidate. + pub fn add_candidate( + &mut self, + candidate: CommittedCandidateReceipt, + persisted_validation_data: PersistedValidationData, + ) -> Result { + let candidate_hash = candidate.hash(); + + if self.by_candidate_hash.contains_key(&candidate_hash) { + return Err(CandidateStorageInsertionError::CandidateAlreadyKnown(candidate_hash)) + } + + if persisted_validation_data.hash() != candidate.descriptor.persisted_validation_data_hash { + return Err(CandidateStorageInsertionError::PersistedValidationDataMismatch) + } + + let parent_head_hash = persisted_validation_data.parent_head.hash(); + let output_head_hash = candidate.commitments.head_data.hash(); + let entry = CandidateEntry { + candidate_hash, + relay_parent: candidate.descriptor.relay_parent, + state: CandidateState::Introduced, + candidate: ProspectiveCandidate { + commitments: Cow::Owned(candidate.commitments), + collator: candidate.descriptor.collator, + collator_signature: candidate.descriptor.signature, + persisted_validation_data, + pov_hash: candidate.descriptor.pov_hash, + validation_code_hash: candidate.descriptor.validation_code_hash, + }, + }; + + self.by_parent_head.entry(parent_head_hash).or_default().insert(candidate_hash); + self.by_output_head.entry(output_head_hash).or_default().insert(candidate_hash); + // sanity-checked already. + self.by_candidate_hash.insert(candidate_hash, entry); + + Ok(candidate_hash) + } + + /// Remove a candidate from the store. + pub fn remove_candidate(&mut self, candidate_hash: &CandidateHash) { + if let Some(entry) = self.by_candidate_hash.remove(candidate_hash) { + let parent_head_hash = entry.candidate.persisted_validation_data.parent_head.hash(); + if let Entry::Occupied(mut e) = self.by_parent_head.entry(parent_head_hash) { + e.get_mut().remove(&candidate_hash); + if e.get().is_empty() { + e.remove(); + } + } + } + } + + /// Note that an existing candidate has been seconded. + pub fn mark_seconded(&mut self, candidate_hash: &CandidateHash) { + if let Some(entry) = self.by_candidate_hash.get_mut(candidate_hash) { + if entry.state != CandidateState::Backed { + entry.state = CandidateState::Seconded; + } + } + } + + /// Note that an existing candidate has been backed. + pub fn mark_backed(&mut self, candidate_hash: &CandidateHash) { + if let Some(entry) = self.by_candidate_hash.get_mut(candidate_hash) { + entry.state = CandidateState::Backed; + } + } + + /// Whether a candidate is recorded as being backed. + pub fn is_backed(&self, candidate_hash: &CandidateHash) -> bool { + self.by_candidate_hash + .get(candidate_hash) + .map_or(false, |e| e.state == CandidateState::Backed) + } + + /// Whether a candidate is contained within the storage already. + pub fn contains(&self, candidate_hash: &CandidateHash) -> bool { + self.by_candidate_hash.contains_key(candidate_hash) + } + + /// Retain only candidates which pass the predicate. + pub(crate) fn retain(&mut self, pred: impl Fn(&CandidateHash) -> bool) { + self.by_candidate_hash.retain(|h, _v| pred(h)); + self.by_parent_head.retain(|_parent, children| { + children.retain(|h| pred(h)); + !children.is_empty() + }); + self.by_output_head.retain(|_output, candidates| { + candidates.retain(|h| pred(h)); + !candidates.is_empty() + }); + } + + /// Get head-data by hash. + pub(crate) fn head_data_by_hash(&self, hash: &Hash) -> Option<&HeadData> { + // First, search for candidates outputting this head data and extract the head data + // from their commitments if they exist. + // + // Otherwise, search for candidates building upon this head data and extract the head data + // from their persisted validation data if they exist. + self.by_output_head + .get(hash) + .and_then(|m| m.iter().next()) + .and_then(|a_candidate| self.by_candidate_hash.get(a_candidate)) + .map(|e| &e.candidate.commitments.head_data) + .or_else(|| { + self.by_parent_head + .get(hash) + .and_then(|m| m.iter().next()) + .and_then(|a_candidate| self.by_candidate_hash.get(a_candidate)) + .map(|e| &e.candidate.persisted_validation_data.parent_head) + }) + } + + /// Returns candidate's relay parent, if present. + pub(crate) fn relay_parent_by_candidate_hash( + &self, + candidate_hash: &CandidateHash, + ) -> Option { + self.by_candidate_hash.get(candidate_hash).map(|entry| entry.relay_parent) + } + + fn iter_para_children<'a>( + &'a self, + parent_head_hash: &Hash, + ) -> impl Iterator + 'a { + let by_candidate_hash = &self.by_candidate_hash; + self.by_parent_head + .get(parent_head_hash) + .into_iter() + .flat_map(|hashes| hashes.iter()) + .filter_map(move |h| by_candidate_hash.get(h)) + } + + fn get(&'_ self, candidate_hash: &CandidateHash) -> Option<&'_ CandidateEntry> { + self.by_candidate_hash.get(candidate_hash) + } + + #[cfg(test)] + pub fn len(&self) -> (usize, usize) { + (self.by_parent_head.len(), self.by_candidate_hash.len()) + } +} + +/// The state of a candidate. +/// +/// Candidates aren't even considered until they've at least been seconded. +#[derive(Debug, PartialEq)] +enum CandidateState { + /// The candidate has been introduced in a spam-protected way but + /// is not necessarily backed. + Introduced, + /// The candidate has been seconded. + Seconded, + /// The candidate has been completely backed by the group. + Backed, +} + +#[derive(Debug)] +struct CandidateEntry { + candidate_hash: CandidateHash, + relay_parent: Hash, + candidate: ProspectiveCandidate<'static>, + state: CandidateState, +} + +/// A candidate existing on-chain but pending availability, for special treatment +/// in the [`Scope`]. +#[derive(Debug, Clone)] +pub(crate) struct PendingAvailability { + /// The candidate hash. + pub candidate_hash: CandidateHash, + /// The block info of the relay parent. + pub relay_parent: RelayChainBlockInfo, +} + +/// The scope of a [`FragmentTree`]. +#[derive(Debug)] +pub(crate) struct Scope { + para: ParaId, + relay_parent: RelayChainBlockInfo, + ancestors: BTreeMap, + ancestors_by_hash: HashMap, + pending_availability: Vec, + base_constraints: Constraints, + max_depth: usize, +} + +/// An error variant indicating that ancestors provided to a scope +/// had unexpected order. +#[derive(Debug)] +pub struct UnexpectedAncestor { + /// The block number that this error occurred at. + pub number: BlockNumber, + /// The previous seen block number, which did not match `number`. + pub prev: BlockNumber, +} + +impl Scope { + /// Define a new [`Scope`]. + /// + /// All arguments are straightforward except the ancestors. + /// + /// Ancestors should be in reverse order, starting with the parent + /// of the `relay_parent`, and proceeding backwards in block number + /// increments of 1. Ancestors not following these conditions will be + /// rejected. + /// + /// This function will only consume ancestors up to the `min_relay_parent_number` of + /// the `base_constraints`. + /// + /// Only ancestors whose children have the same session as the relay-parent's + /// children should be provided. + /// + /// It is allowed to provide zero ancestors. + pub fn with_ancestors( + para: ParaId, + relay_parent: RelayChainBlockInfo, + base_constraints: Constraints, + pending_availability: Vec, + max_depth: usize, + ancestors: impl IntoIterator, + ) -> Result { + let mut ancestors_map = BTreeMap::new(); + let mut ancestors_by_hash = HashMap::new(); + { + let mut prev = relay_parent.number; + for ancestor in ancestors { + if prev == 0 { + return Err(UnexpectedAncestor { number: ancestor.number, prev }) + } else if ancestor.number != prev - 1 { + return Err(UnexpectedAncestor { number: ancestor.number, prev }) + } else if prev == base_constraints.min_relay_parent_number { + break + } else { + prev = ancestor.number; + ancestors_by_hash.insert(ancestor.hash, ancestor.clone()); + ancestors_map.insert(ancestor.number, ancestor); + } + } + } + + Ok(Scope { + para, + relay_parent, + base_constraints, + pending_availability, + max_depth, + ancestors: ancestors_map, + ancestors_by_hash, + }) + } + + /// Get the earliest relay-parent allowed in the scope of the fragment tree. + pub fn earliest_relay_parent(&self) -> RelayChainBlockInfo { + self.ancestors + .iter() + .next() + .map(|(_, v)| v.clone()) + .unwrap_or_else(|| self.relay_parent.clone()) + } + + /// Get the ancestor of the fragment tree by hash. + pub fn ancestor_by_hash(&self, hash: &Hash) -> Option { + if hash == &self.relay_parent.hash { + return Some(self.relay_parent.clone()) + } + + self.ancestors_by_hash.get(hash).map(|info| info.clone()) + } + + /// Whether the candidate in question is one pending availability in this scope. + pub fn get_pending_availability( + &self, + candidate_hash: &CandidateHash, + ) -> Option<&PendingAvailability> { + self.pending_availability.iter().find(|c| &c.candidate_hash == candidate_hash) + } + + /// Get the base constraints of the scope + pub fn base_constraints(&self) -> &Constraints { + &self.base_constraints + } +} + +/// We use indices into a flat vector to refer to nodes in the tree. +/// Every tree also has an implicit root. +#[derive(Debug, Clone, Copy, PartialEq)] +enum NodePointer { + Root, + Storage(usize), +} + +/// A hypothetical candidate, which may or may not exist in +/// the fragment tree already. +pub(crate) enum HypotheticalCandidate<'a> { + Complete { + receipt: Cow<'a, CommittedCandidateReceipt>, + persisted_validation_data: Cow<'a, PersistedValidationData>, + }, + Incomplete { + relay_parent: Hash, + parent_head_data_hash: Hash, + }, +} + +impl<'a> HypotheticalCandidate<'a> { + fn parent_head_data_hash(&self) -> Hash { + match *self { + HypotheticalCandidate::Complete { ref persisted_validation_data, .. } => + persisted_validation_data.as_ref().parent_head.hash(), + HypotheticalCandidate::Incomplete { ref parent_head_data_hash, .. } => + *parent_head_data_hash, + } + } + + fn relay_parent(&self) -> Hash { + match *self { + HypotheticalCandidate::Complete { ref receipt, .. } => + receipt.descriptor().relay_parent, + HypotheticalCandidate::Incomplete { ref relay_parent, .. } => *relay_parent, + } + } +} + +/// This is a tree of candidates based on some underlying storage of candidates and a scope. +/// +/// All nodes in the tree must be either pending availability or within the scope. Within the scope +/// means it's built off of the relay-parent or an ancestor. +pub(crate) struct FragmentTree { + scope: Scope, + + // Invariant: a contiguous prefix of the 'nodes' storage will contain + // the top-level children. + nodes: Vec, + + // The candidates stored in this tree, mapped to a bitvec indicating the depths + // where the candidate is stored. + candidates: HashMap>, +} + +impl FragmentTree { + /// Create a new [`FragmentTree`] with given scope and populated from the storage. + /// + /// Can be populated recursively (i.e. `populate` will pick up candidates that build on other + /// candidates). + pub fn populate(scope: Scope, storage: &CandidateStorage) -> Self { + gum::trace!( + target: LOG_TARGET, + relay_parent = ?scope.relay_parent.hash, + relay_parent_num = scope.relay_parent.number, + para_id = ?scope.para, + ancestors = scope.ancestors.len(), + "Instantiating Fragment Tree", + ); + + let mut tree = FragmentTree { scope, nodes: Vec::new(), candidates: HashMap::new() }; + + tree.populate_from_bases(storage, vec![NodePointer::Root]); + + tree + } + + /// Get the scope of the Fragment Tree. + pub fn scope(&self) -> &Scope { + &self.scope + } + + // Inserts a node and updates child references in a non-root parent. + fn insert_node(&mut self, node: FragmentNode) { + let pointer = NodePointer::Storage(self.nodes.len()); + let parent_pointer = node.parent; + let candidate_hash = node.candidate_hash; + + let max_depth = self.scope.max_depth; + + self.candidates + .entry(candidate_hash) + .or_insert_with(|| bitvec![u16, Msb0; 0; max_depth + 1]) + .set(node.depth, true); + + match parent_pointer { + NodePointer::Storage(ptr) => { + self.nodes.push(node); + self.nodes[ptr].children.push((pointer, candidate_hash)) + }, + NodePointer::Root => { + // Maintain the invariant of node storage beginning with depth-0. + if self.nodes.last().map_or(true, |last| last.parent == NodePointer::Root) { + self.nodes.push(node); + } else { + let pos = + self.nodes.iter().take_while(|n| n.parent == NodePointer::Root).count(); + self.nodes.insert(pos, node); + } + }, + } + } + + fn node_has_candidate_child( + &self, + pointer: NodePointer, + candidate_hash: &CandidateHash, + ) -> bool { + self.node_candidate_child(pointer, candidate_hash).is_some() + } + + fn node_candidate_child( + &self, + pointer: NodePointer, + candidate_hash: &CandidateHash, + ) -> Option { + match pointer { + NodePointer::Root => self + .nodes + .iter() + .take_while(|n| n.parent == NodePointer::Root) + .enumerate() + .find(|(_, n)| &n.candidate_hash == candidate_hash) + .map(|(i, _)| NodePointer::Storage(i)), + NodePointer::Storage(ptr) => + self.nodes.get(ptr).and_then(|n| n.candidate_child(candidate_hash)), + } + } + + /// Returns an O(n) iterator over the hashes of candidates contained in the + /// tree. + pub(crate) fn candidates(&self) -> impl Iterator + '_ { + self.candidates.keys().cloned() + } + + /// Whether the candidate exists and at what depths. + pub(crate) fn candidate(&self, candidate: &CandidateHash) -> Option> { + self.candidates.get(candidate).map(|d| d.iter_ones().collect()) + } + + /// Add a candidate and recursively populate from storage. + /// + /// Candidates can be added either as children of the root or children of other candidates. + pub(crate) fn add_and_populate(&mut self, hash: CandidateHash, storage: &CandidateStorage) { + let candidate_entry = match storage.get(&hash) { + None => return, + Some(e) => e, + }; + + let candidate_parent = &candidate_entry.candidate.persisted_validation_data.parent_head; + + // Select an initial set of bases, whose required relay-parent matches that of the + // candidate. + let root_base = if &self.scope.base_constraints.required_parent == candidate_parent { + Some(NodePointer::Root) + } else { + None + }; + + let non_root_bases = self + .nodes + .iter() + .enumerate() + .filter(|(_, n)| { + n.cumulative_modifications.required_parent.as_ref() == Some(candidate_parent) + }) + .map(|(i, _)| NodePointer::Storage(i)); + + let bases = root_base.into_iter().chain(non_root_bases).collect(); + + // Pass this into the population function, which will sanity-check stuff like depth, + // fragments, etc. and then recursively populate. + self.populate_from_bases(storage, bases); + } + + /// Returns `true` if the path from the root to the node's parent (inclusive) + /// only contains backed candidates, `false` otherwise. + fn path_contains_backed_only_candidates( + &self, + mut parent_pointer: NodePointer, + candidate_storage: &CandidateStorage, + ) -> bool { + while let NodePointer::Storage(ptr) = parent_pointer { + let node = &self.nodes[ptr]; + let candidate_hash = &node.candidate_hash; + + if candidate_storage.get(candidate_hash).map_or(true, |candidate_entry| { + !matches!(candidate_entry.state, CandidateState::Backed) + }) { + return false + } + parent_pointer = node.parent; + } + + true + } + + /// Returns the hypothetical depths where a candidate with the given hash and parent head data + /// would be added to the tree, without applying other candidates recursively on top of it. + /// + /// If the candidate is already known, this returns the actual depths where this + /// candidate is part of the tree. + /// + /// Setting `backed_in_path_only` to `true` ensures this function only returns such membership + /// that every candidate in the path from the root is backed. + pub(crate) fn hypothetical_depths( + &self, + hash: CandidateHash, + candidate: HypotheticalCandidate, + candidate_storage: &CandidateStorage, + backed_in_path_only: bool, + ) -> Vec { + // if `true`, we always have to traverse the tree. + if !backed_in_path_only { + // if known. + if let Some(depths) = self.candidates.get(&hash) { + return depths.iter_ones().collect() + } + } + + // if out of scope. + let candidate_relay_parent = candidate.relay_parent(); + let candidate_relay_parent = if self.scope.relay_parent.hash == candidate_relay_parent { + self.scope.relay_parent.clone() + } else if let Some(info) = self.scope.ancestors_by_hash.get(&candidate_relay_parent) { + info.clone() + } else { + return Vec::new() + }; + + let max_depth = self.scope.max_depth; + let mut depths = bitvec![u16, Msb0; 0; max_depth + 1]; + + // iterate over all nodes where parent head-data matches, + // relay-parent number is <= candidate, and depth < max_depth. + let node_pointers = (0..self.nodes.len()).map(NodePointer::Storage); + for parent_pointer in std::iter::once(NodePointer::Root).chain(node_pointers) { + let (modifications, child_depth, earliest_rp) = match parent_pointer { + NodePointer::Root => + (ConstraintModifications::identity(), 0, self.scope.earliest_relay_parent()), + NodePointer::Storage(ptr) => { + let node = &self.nodes[ptr]; + let parent_rp = self + .scope + .ancestor_by_hash(&node.relay_parent()) + .or_else(|| { + self.scope + .get_pending_availability(&node.candidate_hash) + .map(|_| self.scope.earliest_relay_parent()) + }) + .expect("All nodes in tree are either pending availability or within scope; qed"); + + (node.cumulative_modifications.clone(), node.depth + 1, parent_rp) + }, + }; + + if child_depth > max_depth { + continue + } + + if earliest_rp.number > candidate_relay_parent.number { + continue + } + + let child_constraints = + match self.scope.base_constraints.apply_modifications(&modifications) { + Err(e) => { + gum::debug!( + target: LOG_TARGET, + new_parent_head = ?modifications.required_parent, + err = ?e, + "Failed to apply modifications", + ); + + continue + }, + Ok(c) => c, + }; + + let parent_head_hash = candidate.parent_head_data_hash(); + if parent_head_hash != child_constraints.required_parent.hash() { + continue + } + + // We do additional checks for complete candidates. + if let HypotheticalCandidate::Complete { ref receipt, ref persisted_validation_data } = + candidate + { + let prospective_candidate = ProspectiveCandidate { + commitments: Cow::Borrowed(&receipt.commitments), + collator: receipt.descriptor().collator.clone(), + collator_signature: receipt.descriptor().signature.clone(), + persisted_validation_data: persisted_validation_data.as_ref().clone(), + pov_hash: receipt.descriptor().pov_hash, + validation_code_hash: receipt.descriptor().validation_code_hash, + }; + + if Fragment::new( + candidate_relay_parent.clone(), + child_constraints, + prospective_candidate, + ) + .is_err() + { + continue + } + } + + // Check that the path only contains backed candidates, if necessary. + if !backed_in_path_only || + self.path_contains_backed_only_candidates(parent_pointer, candidate_storage) + { + depths.set(child_depth, true); + } + } + + depths.iter_ones().collect() + } + + /// Select a candidate after the given `required_path` which passes + /// the predicate. + /// + /// If there are multiple possibilities, this will select the first one. + /// + /// This returns `None` if there is no candidate meeting those criteria. + /// + /// The intention of the `required_path` is to allow queries on the basis of + /// one or more candidates which were previously pending availability becoming + /// available and opening up more room on the core. + pub(crate) fn select_child( + &self, + required_path: &[CandidateHash], + pred: impl Fn(&CandidateHash) -> bool, + ) -> Option { + let base_node = { + // traverse the required path. + let mut node = NodePointer::Root; + for required_step in required_path { + node = self.node_candidate_child(node, &required_step)?; + } + + node + }; + + // TODO [now]: taking the first selection might introduce bias + // or become gameable. + // + // For plausibly unique parachains, this shouldn't matter much. + // figure out alternative selection criteria? + match base_node { + NodePointer::Root => self + .nodes + .iter() + .take_while(|n| n.parent == NodePointer::Root) + .filter(|n| self.scope.get_pending_availability(&n.candidate_hash).is_none()) + .filter(|n| pred(&n.candidate_hash)) + .map(|n| n.candidate_hash) + .next(), + NodePointer::Storage(ptr) => self.nodes[ptr] + .children + .iter() + .filter(|n| self.scope.get_pending_availability(&n.1).is_none()) + .filter(|n| pred(&n.1)) + .map(|n| n.1) + .next(), + } + } + + fn populate_from_bases(&mut self, storage: &CandidateStorage, initial_bases: Vec) { + // Populate the tree breadth-first. + let mut last_sweep_start = None; + + loop { + let sweep_start = self.nodes.len(); + + if Some(sweep_start) == last_sweep_start { + break + } + + let parents: Vec = if let Some(last_start) = last_sweep_start { + (last_start..self.nodes.len()).map(NodePointer::Storage).collect() + } else { + initial_bases.clone() + }; + + // 1. get parent head and find constraints + // 2. iterate all candidates building on the right head and viable relay parent + // 3. add new node + for parent_pointer in parents { + let (modifications, child_depth, earliest_rp) = match parent_pointer { + NodePointer::Root => + (ConstraintModifications::identity(), 0, self.scope.earliest_relay_parent()), + NodePointer::Storage(ptr) => { + let node = &self.nodes[ptr]; + let parent_rp = self + .scope + .ancestor_by_hash(&node.relay_parent()) + .or_else(|| { + // if the relay-parent is out of scope _and_ it is in the tree, + // it must be a candidate pending availability. + self.scope + .get_pending_availability(&node.candidate_hash) + .map(|c| c.relay_parent.clone()) + }) + .expect("All nodes in tree are either pending availability or within scope; qed"); + + (node.cumulative_modifications.clone(), node.depth + 1, parent_rp) + }, + }; + + if child_depth > self.scope.max_depth { + continue + } + + let child_constraints = + match self.scope.base_constraints.apply_modifications(&modifications) { + Err(e) => { + gum::debug!( + target: LOG_TARGET, + new_parent_head = ?modifications.required_parent, + err = ?e, + "Failed to apply modifications", + ); + + continue + }, + Ok(c) => c, + }; + + // Add nodes to tree wherever + // 1. parent hash is correct + // 2. relay-parent does not move backwards. + // 3. all non-pending-availability candidates have relay-parent in scope. + // 4. candidate outputs fulfill constraints + let required_head_hash = child_constraints.required_parent.hash(); + for candidate in storage.iter_para_children(&required_head_hash) { + let pending = self.scope.get_pending_availability(&candidate.candidate_hash); + let relay_parent = pending + .map(|p| p.relay_parent.clone()) + .or_else(|| self.scope.ancestor_by_hash(&candidate.relay_parent)); + + let relay_parent = match relay_parent { + Some(r) => r, + None => continue, + }; + + // require: pending availability candidates don't move backwards + // and only those can be out-of-scope. + // + // earliest_rp can be before the earliest relay parent in the scope + // when the parent is a pending availability candidate as well, but + // only other pending candidates can have a relay parent out of scope. + let min_relay_parent_number = pending + .map(|p| match parent_pointer { + NodePointer::Root => p.relay_parent.number, + NodePointer::Storage(_) => earliest_rp.number, + }) + .unwrap_or_else(|| { + std::cmp::max( + earliest_rp.number, + self.scope.earliest_relay_parent().number, + ) + }); + + if relay_parent.number < min_relay_parent_number { + continue // relay parent moved backwards. + } + + // don't add candidates where the parent already has it as a child. + if self.node_has_candidate_child(parent_pointer, &candidate.candidate_hash) { + continue + } + + let fragment = { + let mut constraints = child_constraints.clone(); + if let Some(ref p) = pending { + // overwrite for candidates pending availability as a special-case. + constraints.min_relay_parent_number = p.relay_parent.number; + } + + let f = Fragment::new( + relay_parent.clone(), + constraints, + candidate.candidate.partial_clone(), + ); + + match f { + Ok(f) => f.into_owned(), + Err(e) => { + gum::debug!( + target: LOG_TARGET, + err = ?e, + ?relay_parent, + candidate_hash = ?candidate.candidate_hash, + "Failed to instantiate fragment", + ); + + continue + }, + } + }; + + let mut cumulative_modifications = modifications.clone(); + cumulative_modifications.stack(fragment.constraint_modifications()); + + let node = FragmentNode { + parent: parent_pointer, + fragment, + candidate_hash: candidate.candidate_hash, + depth: child_depth, + cumulative_modifications, + children: Vec::new(), + }; + + self.insert_node(node); + } + } + + last_sweep_start = Some(sweep_start); + } + } +} + +struct FragmentNode { + // A pointer to the parent node. + parent: NodePointer, + fragment: Fragment<'static>, + candidate_hash: CandidateHash, + depth: usize, + cumulative_modifications: ConstraintModifications, + children: Vec<(NodePointer, CandidateHash)>, +} + +impl FragmentNode { + fn relay_parent(&self) -> Hash { + self.fragment.relay_parent().hash + } + + fn candidate_child(&self, candidate_hash: &CandidateHash) -> Option { + self.children.iter().find(|(_, c)| c == candidate_hash).map(|(p, _)| *p) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use assert_matches::assert_matches; + use polkadot_node_subsystem_util::inclusion_emulator::staging::InboundHrmpLimitations; + use polkadot_primitives::vstaging::{ + BlockNumber, CandidateCommitments, CandidateDescriptor, HeadData, + }; + use polkadot_primitives_test_helpers as test_helpers; + + fn make_constraints( + min_relay_parent_number: BlockNumber, + valid_watermarks: Vec, + required_parent: HeadData, + ) -> Constraints { + Constraints { + min_relay_parent_number, + max_pov_size: 1_000_000, + max_code_size: 1_000_000, + ump_remaining: 10, + ump_remaining_bytes: 1_000, + max_ump_num_per_candidate: 10, + dmp_remaining_messages: [0; 10].into(), + hrmp_inbound: InboundHrmpLimitations { valid_watermarks }, + hrmp_channels_out: HashMap::new(), + max_hrmp_num_per_candidate: 0, + required_parent, + validation_code_hash: Hash::repeat_byte(42).into(), + upgrade_restriction: None, + future_validation_code: None, + } + } + + fn make_committed_candidate( + para_id: ParaId, + relay_parent: Hash, + relay_parent_number: BlockNumber, + parent_head: HeadData, + para_head: HeadData, + hrmp_watermark: BlockNumber, + ) -> (PersistedValidationData, CommittedCandidateReceipt) { + let persisted_validation_data = PersistedValidationData { + parent_head, + relay_parent_number, + relay_parent_storage_root: Hash::repeat_byte(69), + max_pov_size: 1_000_000, + }; + + let candidate = CommittedCandidateReceipt { + descriptor: CandidateDescriptor { + para_id, + relay_parent, + collator: test_helpers::dummy_collator(), + persisted_validation_data_hash: persisted_validation_data.hash(), + pov_hash: Hash::repeat_byte(1), + erasure_root: Hash::repeat_byte(1), + signature: test_helpers::dummy_collator_signature(), + para_head: para_head.hash(), + validation_code_hash: Hash::repeat_byte(42).into(), + }, + commitments: CandidateCommitments { + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + head_data: para_head, + processed_downward_messages: 1, + hrmp_watermark, + }, + }; + + (persisted_validation_data, candidate) + } + + #[test] + fn scope_rejects_ancestors_that_skip_blocks() { + let para_id = ParaId::from(5u32); + let relay_parent = RelayChainBlockInfo { + number: 10, + hash: Hash::repeat_byte(10), + storage_root: Hash::repeat_byte(69), + }; + + let ancestors = vec![RelayChainBlockInfo { + number: 8, + hash: Hash::repeat_byte(8), + storage_root: Hash::repeat_byte(69), + }]; + + let max_depth = 2; + let base_constraints = make_constraints(8, vec![8, 9], vec![1, 2, 3].into()); + let pending_availability = Vec::new(); + + assert_matches!( + Scope::with_ancestors( + para_id, + relay_parent, + base_constraints, + pending_availability, + max_depth, + ancestors + ), + Err(UnexpectedAncestor { number: 8, prev: 10 }) + ); + } + + #[test] + fn scope_rejects_ancestor_for_0_block() { + let para_id = ParaId::from(5u32); + let relay_parent = RelayChainBlockInfo { + number: 0, + hash: Hash::repeat_byte(0), + storage_root: Hash::repeat_byte(69), + }; + + let ancestors = vec![RelayChainBlockInfo { + number: 99999, + hash: Hash::repeat_byte(99), + storage_root: Hash::repeat_byte(69), + }]; + + let max_depth = 2; + let base_constraints = make_constraints(0, vec![], vec![1, 2, 3].into()); + let pending_availability = Vec::new(); + + assert_matches!( + Scope::with_ancestors( + para_id, + relay_parent, + base_constraints, + pending_availability, + max_depth, + ancestors, + ), + Err(UnexpectedAncestor { number: 99999, prev: 0 }) + ); + } + + #[test] + fn scope_only_takes_ancestors_up_to_min() { + let para_id = ParaId::from(5u32); + let relay_parent = RelayChainBlockInfo { + number: 5, + hash: Hash::repeat_byte(0), + storage_root: Hash::repeat_byte(69), + }; + + let ancestors = vec![ + RelayChainBlockInfo { + number: 4, + hash: Hash::repeat_byte(4), + storage_root: Hash::repeat_byte(69), + }, + RelayChainBlockInfo { + number: 3, + hash: Hash::repeat_byte(3), + storage_root: Hash::repeat_byte(69), + }, + RelayChainBlockInfo { + number: 2, + hash: Hash::repeat_byte(2), + storage_root: Hash::repeat_byte(69), + }, + ]; + + let max_depth = 2; + let base_constraints = make_constraints(3, vec![2], vec![1, 2, 3].into()); + let pending_availability = Vec::new(); + + let scope = Scope::with_ancestors( + para_id, + relay_parent, + base_constraints, + pending_availability, + max_depth, + ancestors, + ) + .unwrap(); + + assert_eq!(scope.ancestors.len(), 2); + assert_eq!(scope.ancestors_by_hash.len(), 2); + } + + #[test] + fn storage_add_candidate() { + let mut storage = CandidateStorage::new(); + let relay_parent = Hash::repeat_byte(69); + + let (pvd, candidate) = make_committed_candidate( + ParaId::from(5u32), + relay_parent, + 8, + vec![4, 5, 6].into(), + vec![1, 2, 3].into(), + 7, + ); + + let candidate_hash = candidate.hash(); + let parent_head_hash = pvd.parent_head.hash(); + + storage.add_candidate(candidate, pvd).unwrap(); + assert!(storage.contains(&candidate_hash)); + assert_eq!(storage.iter_para_children(&parent_head_hash).count(), 1); + + assert_eq!(storage.relay_parent_by_candidate_hash(&candidate_hash), Some(relay_parent)); + } + + #[test] + fn storage_retain() { + let mut storage = CandidateStorage::new(); + + let (pvd, candidate) = make_committed_candidate( + ParaId::from(5u32), + Hash::repeat_byte(69), + 8, + vec![4, 5, 6].into(), + vec![1, 2, 3].into(), + 7, + ); + + let candidate_hash = candidate.hash(); + let output_head_hash = candidate.commitments.head_data.hash(); + let parent_head_hash = pvd.parent_head.hash(); + + storage.add_candidate(candidate, pvd).unwrap(); + storage.retain(|_| true); + assert!(storage.contains(&candidate_hash)); + assert_eq!(storage.iter_para_children(&parent_head_hash).count(), 1); + assert!(storage.head_data_by_hash(&output_head_hash).is_some()); + + storage.retain(|_| false); + assert!(!storage.contains(&candidate_hash)); + assert_eq!(storage.iter_para_children(&parent_head_hash).count(), 0); + assert!(storage.head_data_by_hash(&output_head_hash).is_none()); + } + + // [`FragmentTree::populate`] should pick up candidates that build on other candidates. + #[test] + fn populate_works_recursively() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + let relay_parent_b = Hash::repeat_byte(2); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + let candidate_a_hash = candidate_a.hash(); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_b, + 1, + vec![0x0b].into(), + vec![0x0c].into(), + 1, + ); + let candidate_b_hash = candidate_b.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let ancestors = vec![RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }]; + + let relay_parent_b_info = RelayChainBlockInfo { + number: pvd_b.relay_parent_number, + hash: relay_parent_b, + storage_root: pvd_b.relay_parent_storage_root, + }; + + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_b_info, + base_constraints, + pending_availability, + 4, + ancestors, + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + assert!(candidates.contains(&candidate_a_hash)); + assert!(candidates.contains(&candidate_b_hash)); + + assert_eq!(tree.nodes.len(), 2); + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[0].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[0].depth, 0); + + assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); + assert_eq!(tree.nodes[1].candidate_hash, candidate_b_hash); + assert_eq!(tree.nodes[1].depth, 1); + } + + #[test] + fn children_of_root_are_contiguous() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + let relay_parent_b = Hash::repeat_byte(2); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_b, + 1, + vec![0x0b].into(), + vec![0x0c].into(), + 1, + ); + + let (pvd_a2, candidate_a2) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b, 1].into(), + 0, + ); + let candidate_a2_hash = candidate_a2.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let ancestors = vec![RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }]; + + let relay_parent_b_info = RelayChainBlockInfo { + number: pvd_b.relay_parent_number, + hash: relay_parent_b, + storage_root: pvd_b.relay_parent_storage_root, + }; + + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_b_info, + base_constraints, + pending_availability, + 4, + ancestors, + ) + .unwrap(); + let mut tree = FragmentTree::populate(scope, &storage); + + storage.add_candidate(candidate_a2, pvd_a2).unwrap(); + tree.add_and_populate(candidate_a2_hash, &storage); + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 3); + + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[1].parent, NodePointer::Root); + assert_eq!(tree.nodes[2].parent, NodePointer::Storage(0)); + } + + #[test] + fn add_candidate_child_of_root() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0c].into(), + 0, + ); + let candidate_b_hash = candidate_b.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + storage.add_candidate(candidate_a, pvd_a).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + 4, + vec![], + ) + .unwrap(); + let mut tree = FragmentTree::populate(scope, &storage); + + storage.add_candidate(candidate_b, pvd_b).unwrap(); + tree.add_and_populate(candidate_b_hash, &storage); + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[1].parent, NodePointer::Root); + } + + #[test] + fn add_candidate_child_of_non_root() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0b].into(), + vec![0x0c].into(), + 0, + ); + let candidate_b_hash = candidate_b.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + storage.add_candidate(candidate_a, pvd_a).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + 4, + vec![], + ) + .unwrap(); + let mut tree = FragmentTree::populate(scope, &storage); + + storage.add_candidate(candidate_b, pvd_b).unwrap(); + tree.add_and_populate(candidate_b_hash, &storage); + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); + } + + #[test] + fn graceful_cycle_of_0() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0a].into(), // input same as output + 0, + ); + let candidate_a_hash = candidate_a.hash(); + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + let max_depth = 4; + storage.add_candidate(candidate_a, pvd_a).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 1); + assert_eq!(tree.nodes.len(), max_depth + 1); + + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); + assert_eq!(tree.nodes[2].parent, NodePointer::Storage(1)); + assert_eq!(tree.nodes[3].parent, NodePointer::Storage(2)); + assert_eq!(tree.nodes[4].parent, NodePointer::Storage(3)); + + assert_eq!(tree.nodes[0].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[1].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[2].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[3].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[4].candidate_hash, candidate_a_hash); + } + + #[test] + fn graceful_cycle_of_1() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), // input same as output + 0, + ); + let candidate_a_hash = candidate_a.hash(); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0b].into(), + vec![0x0a].into(), // input same as output + 0, + ); + let candidate_b_hash = candidate_b.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + let max_depth = 4; + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + assert_eq!(tree.nodes.len(), max_depth + 1); + + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); + assert_eq!(tree.nodes[2].parent, NodePointer::Storage(1)); + assert_eq!(tree.nodes[3].parent, NodePointer::Storage(2)); + assert_eq!(tree.nodes[4].parent, NodePointer::Storage(3)); + + assert_eq!(tree.nodes[0].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[1].candidate_hash, candidate_b_hash); + assert_eq!(tree.nodes[2].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[3].candidate_hash, candidate_b_hash); + assert_eq!(tree.nodes[4].candidate_hash, candidate_a_hash); + } + + #[test] + fn hypothetical_depths_known_and_unknown() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), // input same as output + 0, + ); + let candidate_a_hash = candidate_a.hash(); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0b].into(), + vec![0x0a].into(), // input same as output + 0, + ); + let candidate_b_hash = candidate_b.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + let max_depth = 4; + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + assert_eq!(tree.nodes.len(), max_depth + 1); + + assert_eq!( + tree.hypothetical_depths( + candidate_a_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![0, 2, 4], + ); + + assert_eq!( + tree.hypothetical_depths( + candidate_b_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0b]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![1, 3], + ); + + assert_eq!( + tree.hypothetical_depths( + CandidateHash(Hash::repeat_byte(21)), + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![0, 2, 4], + ); + + assert_eq!( + tree.hypothetical_depths( + CandidateHash(Hash::repeat_byte(22)), + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0b]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![1, 3] + ); + } + + #[test] + fn hypothetical_depths_stricter_on_complete() { + let storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 1000, // watermark is illegal + ); + + let candidate_a_hash = candidate_a.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + let max_depth = 4; + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + assert_eq!( + tree.hypothetical_depths( + candidate_a_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![0], + ); + + assert!(tree + .hypothetical_depths( + candidate_a_hash, + HypotheticalCandidate::Complete { + receipt: Cow::Owned(candidate_a), + persisted_validation_data: Cow::Owned(pvd_a), + }, + &storage, + false, + ) + .is_empty()); + } + + #[test] + fn hypothetical_depths_backed_in_path() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + let candidate_a_hash = candidate_a.hash(); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0b].into(), + vec![0x0c].into(), + 0, + ); + let candidate_b_hash = candidate_b.hash(); + + let (pvd_c, candidate_c) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0b].into(), + vec![0x0d].into(), + 0, + ); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + let max_depth = 4; + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + storage.add_candidate(candidate_c, pvd_c).unwrap(); + + // `A` and `B` are backed, `C` is not. + storage.mark_backed(&candidate_a_hash); + storage.mark_backed(&candidate_b_hash); + + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 3); + assert_eq!(tree.nodes.len(), 3); + + let candidate_d_hash = CandidateHash(Hash::repeat_byte(0xAA)); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + true, + ), + vec![0], + ); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0c]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + true, + ), + vec![2], + ); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0d]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + true, + ), + Vec::::new(), + ); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0d]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![2], // non-empty if `false`. + ); + } + + #[test] + fn pending_availability_in_scope() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + let relay_parent_b = Hash::repeat_byte(2); + let relay_parent_c = Hash::repeat_byte(3); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + let candidate_a_hash = candidate_a.hash(); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_b, + 1, + vec![0x0b].into(), + vec![0x0c].into(), + 1, + ); + + // Note that relay parent `a` is not allowed. + let base_constraints = make_constraints(1, vec![], vec![0x0a].into()); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + let pending_availability = vec![PendingAvailability { + candidate_hash: candidate_a_hash, + relay_parent: relay_parent_a_info, + }]; + + let relay_parent_b_info = RelayChainBlockInfo { + number: pvd_b.relay_parent_number, + hash: relay_parent_b, + storage_root: pvd_b.relay_parent_storage_root, + }; + let relay_parent_c_info = RelayChainBlockInfo { + number: pvd_b.relay_parent_number + 1, + hash: relay_parent_c, + storage_root: Hash::zero(), + }; + + let max_depth = 4; + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + storage.mark_backed(&candidate_a_hash); + + let scope = Scope::with_ancestors( + para_id, + relay_parent_c_info, + base_constraints, + pending_availability, + max_depth, + vec![relay_parent_b_info], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + assert_eq!(tree.nodes.len(), 2); + + let candidate_d_hash = CandidateHash(Hash::repeat_byte(0xAA)); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0b]).hash(), + relay_parent: relay_parent_c, + }, + &storage, + false, + ), + vec![1], + ); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0c]).hash(), + relay_parent: relay_parent_b, + }, + &storage, + false, + ), + vec![2], + ); + } +} diff --git a/polkadot/node/core/prospective-parachains/src/lib.rs b/polkadot/node/core/prospective-parachains/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..a7f37d873d6a84525a8dc6ab3cf0aac886e3e09e --- /dev/null +++ b/polkadot/node/core/prospective-parachains/src/lib.rs @@ -0,0 +1,939 @@ +// Copyright 2022-2023 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implementation of the Prospective Parachains subsystem - this tracks and handles +//! prospective parachain fragments and informs other backing-stage subsystems +//! of work to be done. +//! +//! This is the main coordinator of work within the node for the collation and +//! backing phases of parachain consensus. +//! +//! This is primarily an implementation of "Fragment Trees", as described in +//! [`polkadot_node_subsystem_util::inclusion_emulator::staging`]. +//! +//! This subsystem also handles concerns such as the relay-chain being forkful and session changes. + +use std::{ + borrow::Cow, + collections::{HashMap, HashSet}, +}; + +use futures::{channel::oneshot, prelude::*}; + +use polkadot_node_subsystem::{ + messages::{ + ChainApiMessage, FragmentTreeMembership, HypotheticalCandidate, + HypotheticalFrontierRequest, IntroduceCandidateRequest, ProspectiveParachainsMessage, + ProspectiveValidationDataRequest, RuntimeApiMessage, RuntimeApiRequest, + }, + overseer, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, +}; +use polkadot_node_subsystem_util::{ + inclusion_emulator::staging::{Constraints, RelayChainBlockInfo}, + request_session_index_for_child, + runtime::{prospective_parachains_mode, ProspectiveParachainsMode}, +}; +use polkadot_primitives::vstaging::{ + BlockNumber, CandidateHash, CandidatePendingAvailability, CommittedCandidateReceipt, CoreState, + Hash, HeadData, Header, Id as ParaId, PersistedValidationData, +}; + +use crate::{ + error::{FatalError, FatalResult, JfyiError, JfyiErrorResult, Result}, + fragment_tree::{ + CandidateStorage, CandidateStorageInsertionError, FragmentTree, Scope as TreeScope, + }, +}; + +mod error; +mod fragment_tree; +#[cfg(test)] +mod tests; + +mod metrics; +use self::metrics::Metrics; + +const LOG_TARGET: &str = "parachain::prospective-parachains"; + +struct RelayBlockViewData { + // Scheduling info for paras and upcoming paras. + fragment_trees: HashMap, + pending_availability: HashSet, +} + +struct View { + // Active or recent relay-chain blocks by block hash. + active_leaves: HashMap, + candidate_storage: HashMap, +} + +impl View { + fn new() -> Self { + View { active_leaves: HashMap::new(), candidate_storage: HashMap::new() } + } +} + +/// The prospective parachains subsystem. +#[derive(Default)] +pub struct ProspectiveParachainsSubsystem { + metrics: Metrics, +} + +impl ProspectiveParachainsSubsystem { + /// Create a new instance of the `ProspectiveParachainsSubsystem`. + pub fn new(metrics: Metrics) -> Self { + Self { metrics } + } +} + +#[overseer::subsystem(ProspectiveParachains, error = SubsystemError, prefix = self::overseer)] +impl ProspectiveParachainsSubsystem +where + Context: Send + Sync, +{ + fn start(self, ctx: Context) -> SpawnedSubsystem { + SpawnedSubsystem { + future: run(ctx, self.metrics) + .map_err(|e| SubsystemError::with_origin("prospective-parachains", e)) + .boxed(), + name: "prospective-parachains-subsystem", + } + } +} + +#[overseer::contextbounds(ProspectiveParachains, prefix = self::overseer)] +async fn run(mut ctx: Context, metrics: Metrics) -> FatalResult<()> { + let mut view = View::new(); + loop { + crate::error::log_error( + run_iteration(&mut ctx, &mut view, &metrics).await, + "Encountered issue during run iteration", + )?; + } +} + +#[overseer::contextbounds(ProspectiveParachains, prefix = self::overseer)] +async fn run_iteration( + ctx: &mut Context, + view: &mut View, + metrics: &Metrics, +) -> Result<()> { + loop { + match ctx.recv().await.map_err(FatalError::SubsystemReceive)? { + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => { + handle_active_leaves_update(&mut *ctx, view, update, metrics).await?; + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {}, + FromOrchestra::Communication { msg } => match msg { + ProspectiveParachainsMessage::IntroduceCandidate(request, tx) => + handle_candidate_introduced(&mut *ctx, view, request, tx).await?, + ProspectiveParachainsMessage::CandidateSeconded(para, candidate_hash) => + handle_candidate_seconded(view, para, candidate_hash), + ProspectiveParachainsMessage::CandidateBacked(para, candidate_hash) => + handle_candidate_backed(&mut *ctx, view, para, candidate_hash).await?, + ProspectiveParachainsMessage::GetBackableCandidate( + relay_parent, + para, + required_path, + tx, + ) => answer_get_backable_candidate(&view, relay_parent, para, required_path, tx), + ProspectiveParachainsMessage::GetHypotheticalFrontier(request, tx) => + answer_hypothetical_frontier_request(&view, request, tx), + ProspectiveParachainsMessage::GetTreeMembership(para, candidate, tx) => + answer_tree_membership_request(&view, para, candidate, tx), + ProspectiveParachainsMessage::GetMinimumRelayParents(relay_parent, tx) => + answer_minimum_relay_parents_request(&view, relay_parent, tx), + ProspectiveParachainsMessage::GetProspectiveValidationData(request, tx) => + answer_prospective_validation_data_request(&view, request, tx), + }, + } + } +} + +#[overseer::contextbounds(ProspectiveParachains, prefix = self::overseer)] +async fn handle_active_leaves_update( + ctx: &mut Context, + view: &mut View, + update: ActiveLeavesUpdate, + metrics: &Metrics, +) -> JfyiErrorResult<()> { + // 1. clean up inactive leaves + // 2. determine all scheduled para at new block + // 3. construct new fragment tree for each para for each new leaf + // 4. prune candidate storage. + + for deactivated in &update.deactivated { + view.active_leaves.remove(deactivated); + } + + let mut temp_header_cache = HashMap::new(); + for activated in update.activated.into_iter() { + let hash = activated.hash; + + let mode = prospective_parachains_mode(ctx.sender(), hash) + .await + .map_err(JfyiError::Runtime)?; + + let ProspectiveParachainsMode::Enabled { max_candidate_depth, allowed_ancestry_len } = mode + else { + gum::trace!( + target: LOG_TARGET, + block_hash = ?hash, + "Skipping leaf activation since async backing is disabled" + ); + + // Not a part of any allowed ancestry. + return Ok(()) + }; + + let mut pending_availability = HashSet::new(); + let scheduled_paras = + fetch_upcoming_paras(&mut *ctx, hash, &mut pending_availability).await?; + + let block_info: RelayChainBlockInfo = + match fetch_block_info(&mut *ctx, &mut temp_header_cache, hash).await? { + None => { + gum::warn!( + target: LOG_TARGET, + block_hash = ?hash, + "Failed to get block info for newly activated leaf block." + ); + + // `update.activated` is an option, but we can use this + // to exit the 'loop' and skip this block without skipping + // pruning logic. + continue + }, + Some(info) => info, + }; + + let ancestry = + fetch_ancestry(&mut *ctx, &mut temp_header_cache, hash, allowed_ancestry_len).await?; + + // Find constraints. + let mut fragment_trees = HashMap::new(); + for para in scheduled_paras { + let candidate_storage = + view.candidate_storage.entry(para).or_insert_with(CandidateStorage::new); + + let backing_state = fetch_backing_state(&mut *ctx, hash, para).await?; + + let (constraints, pending_availability) = match backing_state { + Some(c) => c, + None => { + // This indicates a runtime conflict of some kind. + + gum::debug!( + target: LOG_TARGET, + para_id = ?para, + relay_parent = ?hash, + "Failed to get inclusion backing state." + ); + + continue + }, + }; + + let pending_availability = preprocess_candidates_pending_availability( + ctx, + &mut temp_header_cache, + constraints.required_parent.clone(), + pending_availability, + ) + .await?; + let mut compact_pending = Vec::with_capacity(pending_availability.len()); + + for c in pending_availability { + let res = candidate_storage.add_candidate(c.candidate, c.persisted_validation_data); + let candidate_hash = c.compact.candidate_hash; + compact_pending.push(c.compact); + + match res { + Ok(_) | Err(CandidateStorageInsertionError::CandidateAlreadyKnown(_)) => { + // Anything on-chain is guaranteed to be backed. + candidate_storage.mark_backed(&candidate_hash); + }, + Err(err) => { + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + para_id = ?para, + ?err, + "Scraped invalid candidate pending availability", + ); + }, + } + } + + let scope = TreeScope::with_ancestors( + para, + block_info.clone(), + constraints, + compact_pending, + max_candidate_depth, + ancestry.iter().cloned(), + ) + .expect("ancestors are provided in reverse order and correctly; qed"); + + let tree = FragmentTree::populate(scope, &*candidate_storage); + + fragment_trees.insert(para, tree); + } + + view.active_leaves + .insert(hash, RelayBlockViewData { fragment_trees, pending_availability }); + } + + if !update.deactivated.is_empty() { + // This has potential to be a hotspot. + prune_view_candidate_storage(view, metrics); + } + + Ok(()) +} + +fn prune_view_candidate_storage(view: &mut View, metrics: &Metrics) { + metrics.time_prune_view_candidate_storage(); + + let active_leaves = &view.active_leaves; + let mut live_candidates = HashSet::new(); + let mut live_paras = HashSet::new(); + for sub_view in active_leaves.values() { + for (para_id, fragment_tree) in &sub_view.fragment_trees { + live_candidates.extend(fragment_tree.candidates()); + live_paras.insert(*para_id); + } + + live_candidates.extend(sub_view.pending_availability.iter().cloned()); + } + + view.candidate_storage.retain(|para_id, storage| { + if !live_paras.contains(¶_id) { + return false + } + + storage.retain(|h| live_candidates.contains(&h)); + + // Even if `storage` is now empty, we retain. + // This maintains a convenient invariant that para-id storage exists + // as long as there's an active head which schedules the para. + true + }) +} + +struct ImportablePendingAvailability { + candidate: CommittedCandidateReceipt, + persisted_validation_data: PersistedValidationData, + compact: crate::fragment_tree::PendingAvailability, +} + +#[overseer::contextbounds(ProspectiveParachains, prefix = self::overseer)] +async fn preprocess_candidates_pending_availability( + ctx: &mut Context, + cache: &mut HashMap, + required_parent: HeadData, + pending_availability: Vec, +) -> JfyiErrorResult> { + let mut required_parent = required_parent; + + let mut importable = Vec::new(); + let expected_count = pending_availability.len(); + + for (i, pending) in pending_availability.into_iter().enumerate() { + let relay_parent = + match fetch_block_info(ctx, cache, pending.descriptor.relay_parent).await? { + None => { + gum::debug!( + target: LOG_TARGET, + ?pending.candidate_hash, + ?pending.descriptor.para_id, + index = ?i, + ?expected_count, + "Had to stop processing pending candidates early due to missing info.", + ); + + break + }, + Some(b) => b, + }; + + let next_required_parent = pending.commitments.head_data.clone(); + importable.push(ImportablePendingAvailability { + candidate: CommittedCandidateReceipt { + descriptor: pending.descriptor, + commitments: pending.commitments, + }, + persisted_validation_data: PersistedValidationData { + parent_head: required_parent, + max_pov_size: pending.max_pov_size, + relay_parent_number: relay_parent.number, + relay_parent_storage_root: relay_parent.storage_root, + }, + compact: crate::fragment_tree::PendingAvailability { + candidate_hash: pending.candidate_hash, + relay_parent, + }, + }); + + required_parent = next_required_parent; + } + + Ok(importable) +} + +#[overseer::contextbounds(ProspectiveParachains, prefix = self::overseer)] +async fn handle_candidate_introduced( + _ctx: &mut Context, + view: &mut View, + request: IntroduceCandidateRequest, + tx: oneshot::Sender, +) -> JfyiErrorResult<()> { + let IntroduceCandidateRequest { + candidate_para: para, + candidate_receipt: candidate, + persisted_validation_data: pvd, + } = request; + + // Add the candidate to storage. + // Then attempt to add it to all trees. + let storage = match view.candidate_storage.get_mut(¶) { + None => { + gum::warn!( + target: LOG_TARGET, + para_id = ?para, + candidate_hash = ?candidate.hash(), + "Received seconded candidate for inactive para", + ); + + let _ = tx.send(Vec::new()); + return Ok(()) + }, + Some(storage) => storage, + }; + + let candidate_hash = match storage.add_candidate(candidate, pvd) { + Ok(c) => c, + Err(CandidateStorageInsertionError::CandidateAlreadyKnown(c)) => { + // Candidate known - return existing fragment tree membership. + let _ = tx.send(fragment_tree_membership(&view.active_leaves, para, c)); + return Ok(()) + }, + Err(CandidateStorageInsertionError::PersistedValidationDataMismatch) => { + // We can't log the candidate hash without either doing more ~expensive + // hashing but this branch indicates something is seriously wrong elsewhere + // so it's doubtful that it would affect debugging. + + gum::warn!( + target: LOG_TARGET, + para = ?para, + "Received seconded candidate had mismatching validation data", + ); + + let _ = tx.send(Vec::new()); + return Ok(()) + }, + }; + + let mut membership = Vec::new(); + for (relay_parent, leaf_data) in &mut view.active_leaves { + if let Some(tree) = leaf_data.fragment_trees.get_mut(¶) { + tree.add_and_populate(candidate_hash, &*storage); + if let Some(depths) = tree.candidate(&candidate_hash) { + membership.push((*relay_parent, depths)); + } + } + } + + if membership.is_empty() { + storage.remove_candidate(&candidate_hash); + } + + let _ = tx.send(membership); + + Ok(()) +} + +fn handle_candidate_seconded(view: &mut View, para: ParaId, candidate_hash: CandidateHash) { + let storage = match view.candidate_storage.get_mut(¶) { + None => { + gum::warn!( + target: LOG_TARGET, + para_id = ?para, + ?candidate_hash, + "Received instruction to second unknown candidate", + ); + + return + }, + Some(storage) => storage, + }; + + if !storage.contains(&candidate_hash) { + gum::warn!( + target: LOG_TARGET, + para_id = ?para, + ?candidate_hash, + "Received instruction to second unknown candidate", + ); + + return + } + + storage.mark_seconded(&candidate_hash); +} + +#[overseer::contextbounds(ProspectiveParachains, prefix = self::overseer)] +async fn handle_candidate_backed( + _ctx: &mut Context, + view: &mut View, + para: ParaId, + candidate_hash: CandidateHash, +) -> JfyiErrorResult<()> { + let storage = match view.candidate_storage.get_mut(¶) { + None => { + gum::warn!( + target: LOG_TARGET, + para_id = ?para, + ?candidate_hash, + "Received instruction to back unknown candidate", + ); + + return Ok(()) + }, + Some(storage) => storage, + }; + + if !storage.contains(&candidate_hash) { + gum::warn!( + target: LOG_TARGET, + para_id = ?para, + ?candidate_hash, + "Received instruction to back unknown candidate", + ); + + return Ok(()) + } + + if storage.is_backed(&candidate_hash) { + gum::debug!( + target: LOG_TARGET, + para_id = ?para, + ?candidate_hash, + "Received redundant instruction to mark candidate as backed", + ); + + return Ok(()) + } + + storage.mark_backed(&candidate_hash); + Ok(()) +} + +fn answer_get_backable_candidate( + view: &View, + relay_parent: Hash, + para: ParaId, + required_path: Vec, + tx: oneshot::Sender>, +) { + let data = match view.active_leaves.get(&relay_parent) { + None => { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + para_id = ?para, + "Requested backable candidate for inactive relay-parent." + ); + + let _ = tx.send(None); + return + }, + Some(d) => d, + }; + + let tree = match data.fragment_trees.get(¶) { + None => { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + para_id = ?para, + "Requested backable candidate for inactive para." + ); + + let _ = tx.send(None); + return + }, + Some(tree) => tree, + }; + + let storage = match view.candidate_storage.get(¶) { + None => { + gum::warn!( + target: LOG_TARGET, + ?relay_parent, + para_id = ?para, + "No candidate storage for active para", + ); + + let _ = tx.send(None); + return + }, + Some(s) => s, + }; + + let Some(child_hash) = + tree.select_child(&required_path, |candidate| storage.is_backed(candidate)) + else { + let _ = tx.send(None); + return + }; + let Some(candidate_relay_parent) = storage.relay_parent_by_candidate_hash(&child_hash) else { + gum::error!( + target: LOG_TARGET, + ?child_hash, + para_id = ?para, + "Candidate is present in fragment tree but not in candidate's storage!", + ); + let _ = tx.send(None); + return + }; + + let _ = tx.send(Some((child_hash, candidate_relay_parent))); +} + +fn answer_hypothetical_frontier_request( + view: &View, + request: HypotheticalFrontierRequest, + tx: oneshot::Sender>, +) { + let mut response = Vec::with_capacity(request.candidates.len()); + for candidate in request.candidates { + response.push((candidate, Vec::new())); + } + + let required_active_leaf = request.fragment_tree_relay_parent; + for (active_leaf, leaf_view) in view + .active_leaves + .iter() + .filter(|(h, _)| required_active_leaf.as_ref().map_or(true, |x| h == &x)) + { + for &mut (ref c, ref mut membership) in &mut response { + let fragment_tree = match leaf_view.fragment_trees.get(&c.candidate_para()) { + None => continue, + Some(f) => f, + }; + let candidate_storage = match view.candidate_storage.get(&c.candidate_para()) { + None => continue, + Some(storage) => storage, + }; + + let candidate_hash = c.candidate_hash(); + let hypothetical = match c { + HypotheticalCandidate::Complete { receipt, persisted_validation_data, .. } => + fragment_tree::HypotheticalCandidate::Complete { + receipt: Cow::Borrowed(receipt), + persisted_validation_data: Cow::Borrowed(persisted_validation_data), + }, + HypotheticalCandidate::Incomplete { + parent_head_data_hash, + candidate_relay_parent, + .. + } => fragment_tree::HypotheticalCandidate::Incomplete { + relay_parent: *candidate_relay_parent, + parent_head_data_hash: *parent_head_data_hash, + }, + }; + + let depths = fragment_tree.hypothetical_depths( + candidate_hash, + hypothetical, + candidate_storage, + request.backed_in_path_only, + ); + + if !depths.is_empty() { + membership.push((*active_leaf, depths)); + } + } + } + + let _ = tx.send(response); +} + +fn fragment_tree_membership( + active_leaves: &HashMap, + para: ParaId, + candidate: CandidateHash, +) -> FragmentTreeMembership { + let mut membership = Vec::new(); + for (relay_parent, view_data) in active_leaves { + if let Some(tree) = view_data.fragment_trees.get(¶) { + if let Some(depths) = tree.candidate(&candidate) { + membership.push((*relay_parent, depths)); + } + } + } + membership +} + +fn answer_tree_membership_request( + view: &View, + para: ParaId, + candidate: CandidateHash, + tx: oneshot::Sender, +) { + let _ = tx.send(fragment_tree_membership(&view.active_leaves, para, candidate)); +} + +fn answer_minimum_relay_parents_request( + view: &View, + relay_parent: Hash, + tx: oneshot::Sender>, +) { + let mut v = Vec::new(); + if let Some(leaf_data) = view.active_leaves.get(&relay_parent) { + for (para_id, fragment_tree) in &leaf_data.fragment_trees { + v.push((*para_id, fragment_tree.scope().earliest_relay_parent().number)); + } + } + + let _ = tx.send(v); +} + +fn answer_prospective_validation_data_request( + view: &View, + request: ProspectiveValidationDataRequest, + tx: oneshot::Sender>, +) { + // 1. Try to get the head-data from the candidate store if known. + // 2. Otherwise, it might exist as the base in some relay-parent and we can find it by iterating + // fragment trees. + // 3. Otherwise, it is unknown. + // 4. Also try to find the relay parent block info by scanning fragment trees. + // 5. If head data and relay parent block info are found - success. Otherwise, failure. + + let storage = match view.candidate_storage.get(&request.para_id) { + None => { + let _ = tx.send(None); + return + }, + Some(s) => s, + }; + + let mut head_data = + storage.head_data_by_hash(&request.parent_head_data_hash).map(|x| x.clone()); + let mut relay_parent_info = None; + let mut max_pov_size = None; + + for fragment_tree in view + .active_leaves + .values() + .filter_map(|x| x.fragment_trees.get(&request.para_id)) + { + if head_data.is_some() && relay_parent_info.is_some() && max_pov_size.is_some() { + break + } + if relay_parent_info.is_none() { + relay_parent_info = + fragment_tree.scope().ancestor_by_hash(&request.candidate_relay_parent); + } + if head_data.is_none() { + let required_parent = &fragment_tree.scope().base_constraints().required_parent; + if required_parent.hash() == request.parent_head_data_hash { + head_data = Some(required_parent.clone()); + } + } + if max_pov_size.is_none() { + let contains_ancestor = fragment_tree + .scope() + .ancestor_by_hash(&request.candidate_relay_parent) + .is_some(); + if contains_ancestor { + // We are leaning hard on two assumptions here. + // 1. That the fragment tree never contains allowed relay-parents whose session for + // children is different from that of the base block's. + // 2. That the max_pov_size is only configurable per session. + max_pov_size = Some(fragment_tree.scope().base_constraints().max_pov_size); + } + } + } + + let _ = tx.send(match (head_data, relay_parent_info, max_pov_size) { + (Some(h), Some(i), Some(m)) => Some(PersistedValidationData { + parent_head: h, + relay_parent_number: i.number, + relay_parent_storage_root: i.storage_root, + max_pov_size: m as _, + }), + _ => None, + }); +} + +#[overseer::contextbounds(ProspectiveParachains, prefix = self::overseer)] +async fn fetch_backing_state( + ctx: &mut Context, + relay_parent: Hash, + para_id: ParaId, +) -> JfyiErrorResult)>> { + let (tx, rx) = oneshot::channel(); + ctx.send_message(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::StagingParaBackingState(para_id, tx), + )) + .await; + + Ok(rx + .await + .map_err(JfyiError::RuntimeApiRequestCanceled)?? + .map(|s| (From::from(s.constraints), s.pending_availability))) +} + +#[overseer::contextbounds(ProspectiveParachains, prefix = self::overseer)] +async fn fetch_upcoming_paras( + ctx: &mut Context, + relay_parent: Hash, + pending_availability: &mut HashSet, +) -> JfyiErrorResult> { + let (tx, rx) = oneshot::channel(); + + // This'll have to get more sophisticated with parathreads, + // but for now we can just use the `AvailabilityCores`. + ctx.send_message(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::AvailabilityCores(tx), + )) + .await; + + let cores = rx.await.map_err(JfyiError::RuntimeApiRequestCanceled)??; + let mut upcoming = HashSet::new(); + for core in cores { + match core { + CoreState::Occupied(occupied) => { + pending_availability.insert(occupied.candidate_hash); + + if let Some(next_up_on_available) = occupied.next_up_on_available { + upcoming.insert(next_up_on_available.para_id); + } + if let Some(next_up_on_time_out) = occupied.next_up_on_time_out { + upcoming.insert(next_up_on_time_out.para_id); + } + }, + CoreState::Scheduled(scheduled) => { + upcoming.insert(scheduled.para_id); + }, + CoreState::Free => {}, + } + } + + Ok(upcoming.into_iter().collect()) +} + +// Fetch ancestors in descending order, up to the amount requested. +#[overseer::contextbounds(ProspectiveParachains, prefix = self::overseer)] +async fn fetch_ancestry( + ctx: &mut Context, + cache: &mut HashMap, + relay_hash: Hash, + ancestors: usize, +) -> JfyiErrorResult> { + if ancestors == 0 { + return Ok(Vec::new()) + } + + let (tx, rx) = oneshot::channel(); + ctx.send_message(ChainApiMessage::Ancestors { + hash: relay_hash, + k: ancestors, + response_channel: tx, + }) + .await; + + let hashes = rx.map_err(JfyiError::ChainApiRequestCanceled).await??; + let required_session = request_session_index_for_child(relay_hash, ctx.sender()) + .await + .await + .map_err(JfyiError::RuntimeApiRequestCanceled)??; + + let mut block_info = Vec::with_capacity(hashes.len()); + for hash in hashes { + let info = match fetch_block_info(ctx, cache, hash).await? { + None => { + gum::warn!( + target: LOG_TARGET, + relay_hash = ?hash, + "Failed to fetch info for hash returned from ancestry.", + ); + + // Return, however far we got. + break + }, + Some(info) => info, + }; + + // The relay chain cannot accept blocks backed from previous sessions, with + // potentially previous validators. This is a technical limitation we need to + // respect here. + + let session = request_session_index_for_child(hash, ctx.sender()) + .await + .await + .map_err(JfyiError::RuntimeApiRequestCanceled)??; + + if session == required_session { + block_info.push(info); + } else { + break + } + } + + Ok(block_info) +} + +#[overseer::contextbounds(ProspectiveParachains, prefix = self::overseer)] +async fn fetch_block_header_with_cache( + ctx: &mut Context, + cache: &mut HashMap, + relay_hash: Hash, +) -> JfyiErrorResult> { + if let Some(h) = cache.get(&relay_hash) { + return Ok(Some(h.clone())) + } + + let (tx, rx) = oneshot::channel(); + + ctx.send_message(ChainApiMessage::BlockHeader(relay_hash, tx)).await; + let header = rx.map_err(JfyiError::ChainApiRequestCanceled).await??; + if let Some(ref h) = header { + cache.insert(relay_hash, h.clone()); + } + Ok(header) +} + +#[overseer::contextbounds(ProspectiveParachains, prefix = self::overseer)] +async fn fetch_block_info( + ctx: &mut Context, + cache: &mut HashMap, + relay_hash: Hash, +) -> JfyiErrorResult> { + let header = fetch_block_header_with_cache(ctx, cache, relay_hash).await?; + + Ok(header.map(|header| RelayChainBlockInfo { + hash: relay_hash, + number: header.number, + storage_root: header.state_root, + })) +} diff --git a/polkadot/node/core/prospective-parachains/src/metrics.rs b/polkadot/node/core/prospective-parachains/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..d7a1760bb4597e18eb49d1f5efcbde374f1443a2 --- /dev/null +++ b/polkadot/node/core/prospective-parachains/src/metrics.rs @@ -0,0 +1,52 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) prune_view_candidate_storage: prometheus::Histogram, +} + +/// Candidate backing metrics. +#[derive(Default, Clone)] +pub struct Metrics(pub(crate) Option); + +impl Metrics { + /// Provide a timer for handling `prune_view_candidate_storage` which observes on drop. + pub fn time_prune_view_candidate_storage( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.prune_view_candidate_storage.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + prune_view_candidate_storage: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_prospective_parachains_prune_view_candidate_storage", + "Time spent within `prospective_parachains::prune_view_candidate_storage`", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/core/prospective-parachains/src/tests.rs b/polkadot/node/core/prospective-parachains/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..de7a84d9a608a98efa0baf7fd38eccb6458a5827 --- /dev/null +++ b/polkadot/node/core/prospective-parachains/src/tests.rs @@ -0,0 +1,1652 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use assert_matches::assert_matches; +use polkadot_node_subsystem::{ + errors::RuntimeApiError, + messages::{ + AllMessages, HypotheticalFrontierRequest, ProspectiveParachainsMessage, + ProspectiveValidationDataRequest, + }, +}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_node_subsystem_types::{jaeger, ActivatedLeaf, LeafStatus}; +use polkadot_primitives::{ + vstaging::{AsyncBackingParams, BackingState, Constraints, InboundHrmpLimitations}, + CommittedCandidateReceipt, HeadData, Header, PersistedValidationData, ScheduledCore, + ValidationCodeHash, +}; +use polkadot_primitives_test_helpers::make_candidate; +use std::sync::Arc; + +const ALLOWED_ANCESTRY_LEN: u32 = 3; +const ASYNC_BACKING_PARAMETERS: AsyncBackingParams = + AsyncBackingParams { max_candidate_depth: 4, allowed_ancestry_len: ALLOWED_ANCESTRY_LEN }; + +const ASYNC_BACKING_DISABLED_ERROR: RuntimeApiError = + RuntimeApiError::NotSupported { runtime_api_name: "test-runtime" }; + +const MAX_POV_SIZE: u32 = 1_000_000; + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; + +fn dummy_constraints( + min_relay_parent_number: BlockNumber, + valid_watermarks: Vec, + required_parent: HeadData, + validation_code_hash: ValidationCodeHash, +) -> Constraints { + Constraints { + min_relay_parent_number, + max_pov_size: MAX_POV_SIZE, + max_code_size: 1_000_000, + ump_remaining: 10, + ump_remaining_bytes: 1_000, + max_ump_num_per_candidate: 10, + dmp_remaining_messages: vec![], + hrmp_inbound: InboundHrmpLimitations { valid_watermarks }, + hrmp_channels_out: vec![], + max_hrmp_num_per_candidate: 0, + required_parent, + validation_code_hash, + upgrade_restriction: None, + future_validation_code: None, + } +} + +struct TestState { + availability_cores: Vec, + validation_code_hash: ValidationCodeHash, +} + +impl Default for TestState { + fn default() -> Self { + let chain_a = ParaId::from(1); + let chain_b = ParaId::from(2); + + let availability_cores = vec![ + CoreState::Scheduled(ScheduledCore { para_id: chain_a, collator: None }), + CoreState::Scheduled(ScheduledCore { para_id: chain_b, collator: None }), + ]; + let validation_code_hash = Hash::repeat_byte(42).into(); + + Self { availability_cores, validation_code_hash } + } +} + +fn get_parent_hash(hash: Hash) -> Hash { + Hash::from_low_u64_be(hash.to_low_u64_be() + 1) +} + +fn test_harness>( + test: impl FnOnce(VirtualOverseer) -> T, +) -> View { + let pool = sp_core::testing::TaskExecutor::new(); + + let (mut context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); + + let mut view = View::new(); + let subsystem = async move { + loop { + match run_iteration(&mut context, &mut view, &Metrics(None)).await { + Ok(()) => break, + Err(e) => panic!("{:?}", e), + } + } + + view + }; + + let test_fut = test(virtual_overseer); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + let (_, view) = futures::executor::block_on(future::join( + async move { + let mut virtual_overseer = test_fut.await; + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }, + subsystem, + )); + + view +} + +#[derive(Debug, Clone)] +struct PerParaData { + min_relay_parent: BlockNumber, + head_data: HeadData, + pending_availability: Vec, +} + +impl PerParaData { + pub fn new(min_relay_parent: BlockNumber, head_data: HeadData) -> Self { + Self { min_relay_parent, head_data, pending_availability: Vec::new() } + } + + pub fn new_with_pending( + min_relay_parent: BlockNumber, + head_data: HeadData, + pending: Vec, + ) -> Self { + Self { min_relay_parent, head_data, pending_availability: pending } + } +} + +struct TestLeaf { + number: BlockNumber, + hash: Hash, + para_data: Vec<(ParaId, PerParaData)>, +} + +impl TestLeaf { + pub fn para_data(&self, para_id: ParaId) -> &PerParaData { + self.para_data + .iter() + .find_map(|(p_id, data)| if *p_id == para_id { Some(data) } else { None }) + .unwrap() + } +} + +async fn send_block_header(virtual_overseer: &mut VirtualOverseer, hash: Hash, number: u32) { + let header = Header { + parent_hash: get_parent_hash(hash), + number, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + }; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ChainApi( + ChainApiMessage::BlockHeader(parent, tx) + ) if parent == hash => { + tx.send(Ok(Some(header))).unwrap(); + } + ); +} + +async fn activate_leaf( + virtual_overseer: &mut VirtualOverseer, + leaf: &TestLeaf, + test_state: &TestState, +) { + activate_leaf_with_params(virtual_overseer, leaf, test_state, ASYNC_BACKING_PARAMETERS).await; +} + +async fn activate_leaf_with_params( + virtual_overseer: &mut VirtualOverseer, + leaf: &TestLeaf, + test_state: &TestState, + async_backing_params: AsyncBackingParams, +) { + let TestLeaf { number, hash, .. } = leaf; + + let activated = ActivatedLeaf { + hash: *hash, + number: *number, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( + activated, + )))) + .await; + + handle_leaf_activation(virtual_overseer, leaf, test_state, async_backing_params).await; +} + +async fn handle_leaf_activation( + virtual_overseer: &mut VirtualOverseer, + leaf: &TestLeaf, + test_state: &TestState, + async_backing_params: AsyncBackingParams, +) { + let TestLeaf { number, hash, para_data } = leaf; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) if parent == *hash => { + tx.send(Ok(async_backing_params)).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::AvailabilityCores(tx)) + ) if parent == *hash => { + tx.send(Ok(test_state.availability_cores.clone())).unwrap(); + } + ); + + send_block_header(virtual_overseer, *hash, *number).await; + + // Check that subsystem job issues a request for ancestors. + let min_min = para_data.iter().map(|(_, data)| data.min_relay_parent).min().unwrap_or(*number); + let ancestry_len = number - min_min; + let ancestry_hashes: Vec = + std::iter::successors(Some(*hash), |h| Some(get_parent_hash(*h))) + .skip(1) + .take(ancestry_len as usize) + .collect(); + let ancestry_numbers = (min_min..*number).rev(); + let ancestry_iter = ancestry_hashes.clone().into_iter().zip(ancestry_numbers).peekable(); + if ancestry_len > 0 { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ChainApi( + ChainApiMessage::Ancestors{hash: block_hash, k, response_channel: tx} + ) if block_hash == *hash && k == ALLOWED_ANCESTRY_LEN as usize => { + tx.send(Ok(ancestry_hashes.clone())).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx)) + ) if parent == *hash => { + tx.send(Ok(1)).unwrap(); + } + ); + } + + for (hash, number) in ancestry_iter { + send_block_header(virtual_overseer, hash, number).await; + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx)) + ) if parent == hash => { + tx.send(Ok(1)).unwrap(); + } + ); + } + + for _ in 0..test_state.availability_cores.len() { + let message = virtual_overseer.recv().await; + // Get the para we are working with since the order is not deterministic. + let para_id = match message { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::StagingParaBackingState(p_id, _), + )) => p_id, + _ => panic!("received unexpected message {:?}", message), + }; + + let PerParaData { min_relay_parent, head_data, pending_availability } = + leaf.para_data(para_id); + let constraints = dummy_constraints( + *min_relay_parent, + vec![*number], + head_data.clone(), + test_state.validation_code_hash, + ); + let backing_state = + BackingState { constraints, pending_availability: pending_availability.clone() }; + + assert_matches!( + message, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::StagingParaBackingState(p_id, tx)) + ) if parent == *hash && p_id == para_id => { + tx.send(Ok(Some(backing_state))).unwrap(); + } + ); + + for pending in pending_availability { + send_block_header( + virtual_overseer, + pending.descriptor.relay_parent, + pending.relay_parent_number, + ) + .await; + } + } + + // Get minimum relay parents. + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(overseer::FromOrchestra::Communication { + msg: ProspectiveParachainsMessage::GetMinimumRelayParents(*hash, tx), + }) + .await; + let mut resp = rx.await.unwrap(); + resp.sort(); + let mrp_response: Vec<(ParaId, BlockNumber)> = para_data + .iter() + .map(|(para_id, data)| (*para_id, data.min_relay_parent)) + .collect(); + assert_eq!(resp, mrp_response); +} + +async fn deactivate_leaf(virtual_overseer: &mut VirtualOverseer, hash: Hash) { + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::stop_work( + hash, + )))) + .await; +} + +async fn introduce_candidate( + virtual_overseer: &mut VirtualOverseer, + candidate: CommittedCandidateReceipt, + pvd: PersistedValidationData, +) { + let req = IntroduceCandidateRequest { + candidate_para: candidate.descriptor().para_id, + candidate_receipt: candidate, + persisted_validation_data: pvd, + }; + let (tx, _) = oneshot::channel(); + virtual_overseer + .send(overseer::FromOrchestra::Communication { + msg: ProspectiveParachainsMessage::IntroduceCandidate(req, tx), + }) + .await; +} + +async fn second_candidate( + virtual_overseer: &mut VirtualOverseer, + candidate: CommittedCandidateReceipt, +) { + virtual_overseer + .send(overseer::FromOrchestra::Communication { + msg: ProspectiveParachainsMessage::CandidateSeconded( + candidate.descriptor.para_id, + candidate.hash(), + ), + }) + .await; +} + +async fn back_candidate( + virtual_overseer: &mut VirtualOverseer, + candidate: &CommittedCandidateReceipt, + candidate_hash: CandidateHash, +) { + virtual_overseer + .send(overseer::FromOrchestra::Communication { + msg: ProspectiveParachainsMessage::CandidateBacked( + candidate.descriptor.para_id, + candidate_hash, + ), + }) + .await; +} + +async fn get_membership( + virtual_overseer: &mut VirtualOverseer, + para_id: ParaId, + candidate_hash: CandidateHash, + expected_membership_response: Vec<(Hash, Vec)>, +) { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(overseer::FromOrchestra::Communication { + msg: ProspectiveParachainsMessage::GetTreeMembership(para_id, candidate_hash, tx), + }) + .await; + let resp = rx.await.unwrap(); + assert_eq!(resp, expected_membership_response); +} + +async fn get_backable_candidate( + virtual_overseer: &mut VirtualOverseer, + leaf: &TestLeaf, + para_id: ParaId, + required_path: Vec, + expected_result: Option<(CandidateHash, Hash)>, +) { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(overseer::FromOrchestra::Communication { + msg: ProspectiveParachainsMessage::GetBackableCandidate( + leaf.hash, + para_id, + required_path, + tx, + ), + }) + .await; + let resp = rx.await.unwrap(); + assert_eq!(resp, expected_result); +} + +async fn get_hypothetical_frontier( + virtual_overseer: &mut VirtualOverseer, + candidate_hash: CandidateHash, + receipt: CommittedCandidateReceipt, + persisted_validation_data: PersistedValidationData, + fragment_tree_relay_parent: Hash, + backed_in_path_only: bool, + expected_depths: Vec, +) { + let hypothetical_candidate = HypotheticalCandidate::Complete { + candidate_hash, + receipt: Arc::new(receipt), + persisted_validation_data, + }; + let request = HypotheticalFrontierRequest { + candidates: vec![hypothetical_candidate.clone()], + fragment_tree_relay_parent: Some(fragment_tree_relay_parent), + backed_in_path_only, + }; + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(overseer::FromOrchestra::Communication { + msg: ProspectiveParachainsMessage::GetHypotheticalFrontier(request, tx), + }) + .await; + let resp = rx.await.unwrap(); + let expected_frontier = if expected_depths.is_empty() { + vec![(hypothetical_candidate, vec![])] + } else { + vec![(hypothetical_candidate, vec![(fragment_tree_relay_parent, expected_depths)])] + }; + assert_eq!(resp, expected_frontier); +} + +async fn get_pvd( + virtual_overseer: &mut VirtualOverseer, + para_id: ParaId, + candidate_relay_parent: Hash, + parent_head_data: HeadData, + expected_pvd: Option, +) { + let request = ProspectiveValidationDataRequest { + para_id, + candidate_relay_parent, + parent_head_data_hash: parent_head_data.hash(), + }; + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(overseer::FromOrchestra::Communication { + msg: ProspectiveParachainsMessage::GetProspectiveValidationData(request, tx), + }) + .await; + let resp = rx.await.unwrap(); + assert_eq!(resp, expected_pvd); +} + +#[test] +fn should_do_no_work_if_async_backing_disabled_for_leaf() { + async fn activate_leaf_async_backing_disabled(virtual_overseer: &mut VirtualOverseer) { + let hash = Hash::from_low_u64_be(130); + + // Start work on some new parent. + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) if parent == hash => { + tx.send(Err(ASYNC_BACKING_DISABLED_ERROR)).unwrap(); + } + ); + } + + let view = test_harness(|mut virtual_overseer| async move { + activate_leaf_async_backing_disabled(&mut virtual_overseer).await; + + virtual_overseer + }); + + assert!(view.active_leaves.is_empty()); + assert!(view.candidate_storage.is_empty()); +} + +// Send some candidates and make sure all are found: +// - Two for the same leaf A +// - One for leaf B on parachain 1 +// - One for leaf C on parachain 2 +#[test] +fn send_candidates_and_check_if_found() { + let test_state = TestState::default(); + let view = test_harness(|mut virtual_overseer| async move { + // Leaf A + let leaf_a = TestLeaf { + number: 100, + hash: Hash::from_low_u64_be(130), + para_data: vec![ + (1.into(), PerParaData::new(97, HeadData(vec![1, 2, 3]))), + (2.into(), PerParaData::new(100, HeadData(vec![2, 3, 4]))), + ], + }; + // Leaf B + let leaf_b = TestLeaf { + number: 101, + hash: Hash::from_low_u64_be(131), + para_data: vec![ + (1.into(), PerParaData::new(99, HeadData(vec![3, 4, 5]))), + (2.into(), PerParaData::new(101, HeadData(vec![4, 5, 6]))), + ], + }; + // Leaf C + let leaf_c = TestLeaf { + number: 102, + hash: Hash::from_low_u64_be(132), + para_data: vec![ + (1.into(), PerParaData::new(102, HeadData(vec![5, 6, 7]))), + (2.into(), PerParaData::new(98, HeadData(vec![6, 7, 8]))), + ], + }; + + // Activate leaves. + activate_leaf(&mut virtual_overseer, &leaf_a, &test_state).await; + activate_leaf(&mut virtual_overseer, &leaf_b, &test_state).await; + activate_leaf(&mut virtual_overseer, &leaf_c, &test_state).await; + + // Candidate A1 + let (candidate_a1, pvd_a1) = make_candidate( + leaf_a.hash, + leaf_a.number, + 1.into(), + HeadData(vec![1, 2, 3]), + HeadData(vec![1]), + test_state.validation_code_hash, + ); + let candidate_hash_a1 = candidate_a1.hash(); + let response_a1 = vec![(leaf_a.hash, vec![0])]; + + // Candidate A2 + let (candidate_a2, pvd_a2) = make_candidate( + leaf_a.hash, + leaf_a.number, + 2.into(), + HeadData(vec![2, 3, 4]), + HeadData(vec![2]), + test_state.validation_code_hash, + ); + let candidate_hash_a2 = candidate_a2.hash(); + let response_a2 = vec![(leaf_a.hash, vec![0])]; + + // Candidate B + let (candidate_b, pvd_b) = make_candidate( + leaf_b.hash, + leaf_b.number, + 1.into(), + HeadData(vec![3, 4, 5]), + HeadData(vec![3]), + test_state.validation_code_hash, + ); + let candidate_hash_b = candidate_b.hash(); + let response_b = vec![(leaf_b.hash, vec![0])]; + + // Candidate C + let (candidate_c, pvd_c) = make_candidate( + leaf_c.hash, + leaf_c.number, + 2.into(), + HeadData(vec![6, 7, 8]), + HeadData(vec![4]), + test_state.validation_code_hash, + ); + let candidate_hash_c = candidate_c.hash(); + let response_c = vec![(leaf_c.hash, vec![0])]; + + // Introduce candidates. + introduce_candidate(&mut virtual_overseer, candidate_a1, pvd_a1).await; + introduce_candidate(&mut virtual_overseer, candidate_a2, pvd_a2).await; + introduce_candidate(&mut virtual_overseer, candidate_b, pvd_b).await; + introduce_candidate(&mut virtual_overseer, candidate_c, pvd_c).await; + + // Check candidate tree membership. + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_a1, response_a1).await; + get_membership(&mut virtual_overseer, 2.into(), candidate_hash_a2, response_a2).await; + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_b, response_b).await; + get_membership(&mut virtual_overseer, 2.into(), candidate_hash_c, response_c).await; + + // The candidates should not be found on other parachains. + get_membership(&mut virtual_overseer, 2.into(), candidate_hash_a1, vec![]).await; + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_a2, vec![]).await; + get_membership(&mut virtual_overseer, 2.into(), candidate_hash_b, vec![]).await; + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_c, vec![]).await; + + virtual_overseer + }); + + assert_eq!(view.active_leaves.len(), 3); + assert_eq!(view.candidate_storage.len(), 2); + // Two parents and two candidates per para. + assert_eq!(view.candidate_storage.get(&1.into()).unwrap().len(), (2, 2)); + assert_eq!(view.candidate_storage.get(&2.into()).unwrap().len(), (2, 2)); +} + +// Send some candidates, check if the candidate won't be found once its relay parent leaves the +// view. +#[test] +fn check_candidate_parent_leaving_view() { + let test_state = TestState::default(); + let view = test_harness(|mut virtual_overseer| async move { + // Leaf A + let leaf_a = TestLeaf { + number: 100, + hash: Hash::from_low_u64_be(130), + para_data: vec![ + (1.into(), PerParaData::new(97, HeadData(vec![1, 2, 3]))), + (2.into(), PerParaData::new(100, HeadData(vec![2, 3, 4]))), + ], + }; + // Leaf B + let leaf_b = TestLeaf { + number: 101, + hash: Hash::from_low_u64_be(131), + para_data: vec![ + (1.into(), PerParaData::new(99, HeadData(vec![3, 4, 5]))), + (2.into(), PerParaData::new(101, HeadData(vec![4, 5, 6]))), + ], + }; + // Leaf C + let leaf_c = TestLeaf { + number: 102, + hash: Hash::from_low_u64_be(132), + para_data: vec![ + (1.into(), PerParaData::new(102, HeadData(vec![5, 6, 7]))), + (2.into(), PerParaData::new(98, HeadData(vec![6, 7, 8]))), + ], + }; + + // Activate leaves. + activate_leaf(&mut virtual_overseer, &leaf_a, &test_state).await; + activate_leaf(&mut virtual_overseer, &leaf_b, &test_state).await; + activate_leaf(&mut virtual_overseer, &leaf_c, &test_state).await; + + // Candidate A1 + let (candidate_a1, pvd_a1) = make_candidate( + leaf_a.hash, + leaf_a.number, + 1.into(), + HeadData(vec![1, 2, 3]), + HeadData(vec![1]), + test_state.validation_code_hash, + ); + let candidate_hash_a1 = candidate_a1.hash(); + + // Candidate A2 + let (candidate_a2, pvd_a2) = make_candidate( + leaf_a.hash, + leaf_a.number, + 2.into(), + HeadData(vec![2, 3, 4]), + HeadData(vec![2]), + test_state.validation_code_hash, + ); + let candidate_hash_a2 = candidate_a2.hash(); + + // Candidate B + let (candidate_b, pvd_b) = make_candidate( + leaf_b.hash, + leaf_b.number, + 1.into(), + HeadData(vec![3, 4, 5]), + HeadData(vec![3]), + test_state.validation_code_hash, + ); + let candidate_hash_b = candidate_b.hash(); + let response_b = vec![(leaf_b.hash, vec![0])]; + + // Candidate C + let (candidate_c, pvd_c) = make_candidate( + leaf_c.hash, + leaf_c.number, + 2.into(), + HeadData(vec![6, 7, 8]), + HeadData(vec![4]), + test_state.validation_code_hash, + ); + let candidate_hash_c = candidate_c.hash(); + let response_c = vec![(leaf_c.hash, vec![0])]; + + // Introduce candidates. + introduce_candidate(&mut virtual_overseer, candidate_a1, pvd_a1).await; + introduce_candidate(&mut virtual_overseer, candidate_a2, pvd_a2).await; + introduce_candidate(&mut virtual_overseer, candidate_b, pvd_b).await; + introduce_candidate(&mut virtual_overseer, candidate_c, pvd_c).await; + + // Deactivate leaf A. + deactivate_leaf(&mut virtual_overseer, leaf_a.hash).await; + + // Candidates A1 and A2 should be gone. Candidates B and C should remain. + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_a1, vec![]).await; + get_membership(&mut virtual_overseer, 2.into(), candidate_hash_a2, vec![]).await; + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_b, response_b).await; + get_membership(&mut virtual_overseer, 2.into(), candidate_hash_c, response_c.clone()).await; + + // Deactivate leaf B. + deactivate_leaf(&mut virtual_overseer, leaf_b.hash).await; + + // Candidate B should be gone, C should remain. + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_a1, vec![]).await; + get_membership(&mut virtual_overseer, 2.into(), candidate_hash_a2, vec![]).await; + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_b, vec![]).await; + get_membership(&mut virtual_overseer, 2.into(), candidate_hash_c, response_c).await; + + // Deactivate leaf C. + deactivate_leaf(&mut virtual_overseer, leaf_c.hash).await; + + // Candidate C should be gone. + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_a1, vec![]).await; + get_membership(&mut virtual_overseer, 2.into(), candidate_hash_a2, vec![]).await; + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_b, vec![]).await; + get_membership(&mut virtual_overseer, 2.into(), candidate_hash_c, vec![]).await; + + virtual_overseer + }); + + assert_eq!(view.active_leaves.len(), 0); + assert_eq!(view.candidate_storage.len(), 0); +} + +// Introduce a candidate to multiple forks, see how the membership is returned. +#[test] +fn check_candidate_on_multiple_forks() { + let test_state = TestState::default(); + let view = test_harness(|mut virtual_overseer| async move { + // Leaf A + let leaf_a = TestLeaf { + number: 100, + hash: Hash::from_low_u64_be(130), + para_data: vec![ + (1.into(), PerParaData::new(97, HeadData(vec![1, 2, 3]))), + (2.into(), PerParaData::new(100, HeadData(vec![2, 3, 4]))), + ], + }; + // Leaf B + let leaf_b = TestLeaf { + number: 101, + hash: Hash::from_low_u64_be(131), + para_data: vec![ + (1.into(), PerParaData::new(99, HeadData(vec![3, 4, 5]))), + (2.into(), PerParaData::new(101, HeadData(vec![4, 5, 6]))), + ], + }; + // Leaf C + let leaf_c = TestLeaf { + number: 102, + hash: Hash::from_low_u64_be(132), + para_data: vec![ + (1.into(), PerParaData::new(102, HeadData(vec![5, 6, 7]))), + (2.into(), PerParaData::new(98, HeadData(vec![6, 7, 8]))), + ], + }; + + // Activate leaves. + activate_leaf(&mut virtual_overseer, &leaf_a, &test_state).await; + activate_leaf(&mut virtual_overseer, &leaf_b, &test_state).await; + activate_leaf(&mut virtual_overseer, &leaf_c, &test_state).await; + + // Candidate on leaf A. + let (candidate_a, pvd_a) = make_candidate( + leaf_a.hash, + leaf_a.number, + 1.into(), + HeadData(vec![1, 2, 3]), + HeadData(vec![1]), + test_state.validation_code_hash, + ); + let candidate_hash_a = candidate_a.hash(); + let response_a = vec![(leaf_a.hash, vec![0])]; + + // Candidate on leaf B. + let (candidate_b, pvd_b) = make_candidate( + leaf_b.hash, + leaf_b.number, + 1.into(), + HeadData(vec![3, 4, 5]), + HeadData(vec![1]), + test_state.validation_code_hash, + ); + let candidate_hash_b = candidate_b.hash(); + let response_b = vec![(leaf_b.hash, vec![0])]; + + // Candidate on leaf C. + let (candidate_c, pvd_c) = make_candidate( + leaf_c.hash, + leaf_c.number, + 1.into(), + HeadData(vec![5, 6, 7]), + HeadData(vec![1]), + test_state.validation_code_hash, + ); + let candidate_hash_c = candidate_c.hash(); + let response_c = vec![(leaf_c.hash, vec![0])]; + + // Introduce candidates on all three leaves. + introduce_candidate(&mut virtual_overseer, candidate_a.clone(), pvd_a).await; + introduce_candidate(&mut virtual_overseer, candidate_b.clone(), pvd_b).await; + introduce_candidate(&mut virtual_overseer, candidate_c.clone(), pvd_c).await; + + // Check candidate tree membership. + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_a, response_a).await; + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_b, response_b).await; + get_membership(&mut virtual_overseer, 1.into(), candidate_hash_c, response_c).await; + + virtual_overseer + }); + + assert_eq!(view.active_leaves.len(), 3); + assert_eq!(view.candidate_storage.len(), 2); + // Three parents and three candidates on para 1. + assert_eq!(view.candidate_storage.get(&1.into()).unwrap().len(), (3, 3)); + assert_eq!(view.candidate_storage.get(&2.into()).unwrap().len(), (0, 0)); +} + +// Backs some candidates and tests `GetBackableCandidate`. +#[test] +fn check_backable_query() { + let test_state = TestState::default(); + let view = test_harness(|mut virtual_overseer| async move { + // Leaf A + let leaf_a = TestLeaf { + number: 100, + hash: Hash::from_low_u64_be(130), + para_data: vec![ + (1.into(), PerParaData::new(97, HeadData(vec![1, 2, 3]))), + (2.into(), PerParaData::new(100, HeadData(vec![2, 3, 4]))), + ], + }; + + // Activate leaves. + activate_leaf(&mut virtual_overseer, &leaf_a, &test_state).await; + + // Candidate A + let (candidate_a, pvd_a) = make_candidate( + leaf_a.hash, + leaf_a.number, + 1.into(), + HeadData(vec![1, 2, 3]), + HeadData(vec![1]), + test_state.validation_code_hash, + ); + let candidate_hash_a = candidate_a.hash(); + + // Candidate B + let (mut candidate_b, pvd_b) = make_candidate( + leaf_a.hash, + leaf_a.number, + 1.into(), + HeadData(vec![1]), + HeadData(vec![2]), + test_state.validation_code_hash, + ); + // Set a field to make this candidate unique. + candidate_b.descriptor.para_head = Hash::from_low_u64_le(1000); + let candidate_hash_b = candidate_b.hash(); + + // Introduce candidates. + introduce_candidate(&mut virtual_overseer, candidate_a.clone(), pvd_a).await; + introduce_candidate(&mut virtual_overseer, candidate_b.clone(), pvd_b).await; + + // Should not get any backable candidates. + get_backable_candidate( + &mut virtual_overseer, + &leaf_a, + 1.into(), + vec![candidate_hash_a], + None, + ) + .await; + + // Second candidates. + second_candidate(&mut virtual_overseer, candidate_a.clone()).await; + second_candidate(&mut virtual_overseer, candidate_b.clone()).await; + + // Should not get any backable candidates. + get_backable_candidate( + &mut virtual_overseer, + &leaf_a, + 1.into(), + vec![candidate_hash_a], + None, + ) + .await; + + // Back candidates. + back_candidate(&mut virtual_overseer, &candidate_a, candidate_hash_a).await; + back_candidate(&mut virtual_overseer, &candidate_b, candidate_hash_b).await; + + // Get backable candidate. + get_backable_candidate( + &mut virtual_overseer, + &leaf_a, + 1.into(), + vec![], + Some((candidate_hash_a, leaf_a.hash)), + ) + .await; + get_backable_candidate( + &mut virtual_overseer, + &leaf_a, + 1.into(), + vec![candidate_hash_a], + Some((candidate_hash_b, leaf_a.hash)), + ) + .await; + + // Should not get anything at the wrong path. + get_backable_candidate( + &mut virtual_overseer, + &leaf_a, + 1.into(), + vec![candidate_hash_b], + None, + ) + .await; + + virtual_overseer + }); + + assert_eq!(view.active_leaves.len(), 1); + assert_eq!(view.candidate_storage.len(), 2); + // Two parents and two candidates on para 1. + assert_eq!(view.candidate_storage.get(&1.into()).unwrap().len(), (2, 2)); + assert_eq!(view.candidate_storage.get(&2.into()).unwrap().len(), (0, 0)); +} + +// Test depth query. +#[test] +fn check_hypothetical_frontier_query() { + let test_state = TestState::default(); + let view = test_harness(|mut virtual_overseer| async move { + // Leaf A + let leaf_a = TestLeaf { + number: 100, + hash: Hash::from_low_u64_be(130), + para_data: vec![ + (1.into(), PerParaData::new(97, HeadData(vec![1, 2, 3]))), + (2.into(), PerParaData::new(100, HeadData(vec![2, 3, 4]))), + ], + }; + + // Activate leaves. + activate_leaf(&mut virtual_overseer, &leaf_a, &test_state).await; + + // Candidate A. + let (candidate_a, pvd_a) = make_candidate( + leaf_a.hash, + leaf_a.number, + 1.into(), + HeadData(vec![1, 2, 3]), + HeadData(vec![1]), + test_state.validation_code_hash, + ); + let candidate_hash_a = candidate_a.hash(); + + // Candidate B. + let (candidate_b, pvd_b) = make_candidate( + leaf_a.hash, + leaf_a.number, + 1.into(), + HeadData(vec![1]), + HeadData(vec![2]), + test_state.validation_code_hash, + ); + let candidate_hash_b = candidate_b.hash(); + + // Candidate C. + let (candidate_c, pvd_c) = make_candidate( + leaf_a.hash, + leaf_a.number, + 1.into(), + HeadData(vec![2]), + HeadData(vec![3]), + test_state.validation_code_hash, + ); + let candidate_hash_c = candidate_c.hash(); + + // Get hypothetical frontier of candidate A before adding it. + get_hypothetical_frontier( + &mut virtual_overseer, + candidate_hash_a, + candidate_a.clone(), + pvd_a.clone(), + leaf_a.hash, + false, + vec![0], + ) + .await; + // Should work with `backed_in_path_only: true`, too. + get_hypothetical_frontier( + &mut virtual_overseer, + candidate_hash_a, + candidate_a.clone(), + pvd_a.clone(), + leaf_a.hash, + true, + vec![0], + ) + .await; + + // Add candidate A. + introduce_candidate(&mut virtual_overseer, candidate_a.clone(), pvd_a.clone()).await; + + // Get frontier of candidate A after adding it. + get_hypothetical_frontier( + &mut virtual_overseer, + candidate_hash_a, + candidate_a.clone(), + pvd_a.clone(), + leaf_a.hash, + false, + vec![0], + ) + .await; + + // Get hypothetical frontier of candidate B before adding it. + get_hypothetical_frontier( + &mut virtual_overseer, + candidate_hash_b, + candidate_b.clone(), + pvd_b.clone(), + leaf_a.hash, + false, + vec![1], + ) + .await; + + // Add candidate B. + introduce_candidate(&mut virtual_overseer, candidate_b.clone(), pvd_b.clone()).await; + + // Get frontier of candidate B after adding it. + get_hypothetical_frontier( + &mut virtual_overseer, + candidate_hash_b, + candidate_b, + pvd_b.clone(), + leaf_a.hash, + false, + vec![1], + ) + .await; + + // Get hypothetical frontier of candidate C before adding it. + get_hypothetical_frontier( + &mut virtual_overseer, + candidate_hash_c, + candidate_c.clone(), + pvd_c.clone(), + leaf_a.hash, + false, + vec![2], + ) + .await; + // Should be empty with `backed_in_path_only` because we haven't backed anything. + get_hypothetical_frontier( + &mut virtual_overseer, + candidate_hash_c, + candidate_c.clone(), + pvd_c.clone(), + leaf_a.hash, + true, + vec![], + ) + .await; + + // Add candidate C. + introduce_candidate(&mut virtual_overseer, candidate_c.clone(), pvd_c.clone()).await; + + // Get frontier of candidate C after adding it. + get_hypothetical_frontier( + &mut virtual_overseer, + candidate_hash_c, + candidate_c.clone(), + pvd_c.clone(), + leaf_a.hash, + false, + vec![2], + ) + .await; + // Should be empty with `backed_in_path_only` because we haven't backed anything. + get_hypothetical_frontier( + &mut virtual_overseer, + candidate_hash_c, + candidate_c.clone(), + pvd_c.clone(), + leaf_a.hash, + true, + vec![], + ) + .await; + + virtual_overseer + }); + + assert_eq!(view.active_leaves.len(), 1); + assert_eq!(view.candidate_storage.len(), 2); +} + +#[test] +fn check_pvd_query() { + let test_state = TestState::default(); + let view = test_harness(|mut virtual_overseer| async move { + // Leaf A + let leaf_a = TestLeaf { + number: 100, + hash: Hash::from_low_u64_be(130), + para_data: vec![ + (1.into(), PerParaData::new(97, HeadData(vec![1, 2, 3]))), + (2.into(), PerParaData::new(100, HeadData(vec![2, 3, 4]))), + ], + }; + + // Activate leaves. + activate_leaf(&mut virtual_overseer, &leaf_a, &test_state).await; + + // Candidate A. + let (candidate_a, pvd_a) = make_candidate( + leaf_a.hash, + leaf_a.number, + 1.into(), + HeadData(vec![1, 2, 3]), + HeadData(vec![1]), + test_state.validation_code_hash, + ); + + // Candidate B. + let (candidate_b, pvd_b) = make_candidate( + leaf_a.hash, + leaf_a.number, + 1.into(), + HeadData(vec![1]), + HeadData(vec![2]), + test_state.validation_code_hash, + ); + + // Candidate C. + let (candidate_c, pvd_c) = make_candidate( + leaf_a.hash, + leaf_a.number, + 1.into(), + HeadData(vec![2]), + HeadData(vec![3]), + test_state.validation_code_hash, + ); + + // Get pvd of candidate A before adding it. + get_pvd( + &mut virtual_overseer, + 1.into(), + leaf_a.hash, + HeadData(vec![1, 2, 3]), + Some(pvd_a.clone()), + ) + .await; + + // Add candidate A. + introduce_candidate(&mut virtual_overseer, candidate_a.clone(), pvd_a.clone()).await; + back_candidate(&mut virtual_overseer, &candidate_a, candidate_a.hash()).await; + + // Get pvd of candidate A after adding it. + get_pvd( + &mut virtual_overseer, + 1.into(), + leaf_a.hash, + HeadData(vec![1, 2, 3]), + Some(pvd_a.clone()), + ) + .await; + + // Get pvd of candidate B before adding it. + get_pvd( + &mut virtual_overseer, + 1.into(), + leaf_a.hash, + HeadData(vec![1]), + Some(pvd_b.clone()), + ) + .await; + + // Add candidate B. + introduce_candidate(&mut virtual_overseer, candidate_b, pvd_b.clone()).await; + + // Get pvd of candidate B after adding it. + get_pvd( + &mut virtual_overseer, + 1.into(), + leaf_a.hash, + HeadData(vec![1]), + Some(pvd_b.clone()), + ) + .await; + + // Get pvd of candidate C before adding it. + get_pvd( + &mut virtual_overseer, + 1.into(), + leaf_a.hash, + HeadData(vec![2]), + Some(pvd_c.clone()), + ) + .await; + + // Add candidate C. + introduce_candidate(&mut virtual_overseer, candidate_c, pvd_c.clone()).await; + + // Get pvd of candidate C after adding it. + get_pvd( + &mut virtual_overseer, + 1.into(), + leaf_a.hash, + HeadData(vec![2]), + Some(pvd_c.clone()), + ) + .await; + + virtual_overseer + }); + + assert_eq!(view.active_leaves.len(), 1); + assert_eq!(view.candidate_storage.len(), 2); +} + +// Test simultaneously activating and deactivating leaves, and simultaneously deactivating multiple +// leaves. +#[test] +fn correctly_updates_leaves() { + let test_state = TestState::default(); + let view = test_harness(|mut virtual_overseer| async move { + // Leaf A + let leaf_a = TestLeaf { + number: 100, + hash: Hash::from_low_u64_be(130), + para_data: vec![ + (1.into(), PerParaData::new(97, HeadData(vec![1, 2, 3]))), + (2.into(), PerParaData::new(100, HeadData(vec![2, 3, 4]))), + ], + }; + // Leaf B + let leaf_b = TestLeaf { + number: 101, + hash: Hash::from_low_u64_be(131), + para_data: vec![ + (1.into(), PerParaData::new(99, HeadData(vec![3, 4, 5]))), + (2.into(), PerParaData::new(101, HeadData(vec![4, 5, 6]))), + ], + }; + // Leaf C + let leaf_c = TestLeaf { + number: 102, + hash: Hash::from_low_u64_be(132), + para_data: vec![ + (1.into(), PerParaData::new(102, HeadData(vec![5, 6, 7]))), + (2.into(), PerParaData::new(98, HeadData(vec![6, 7, 8]))), + ], + }; + + // Activate leaves. + activate_leaf(&mut virtual_overseer, &leaf_a, &test_state).await; + activate_leaf(&mut virtual_overseer, &leaf_b, &test_state).await; + + // Try activating a duplicate leaf. + activate_leaf(&mut virtual_overseer, &leaf_b, &test_state).await; + + // Pass in an empty update. + let update = ActiveLeavesUpdate::default(); + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update))) + .await; + + // Activate a leaf and remove one at the same time. + let activated = ActivatedLeaf { + hash: leaf_c.hash, + number: leaf_c.number, + span: Arc::new(jaeger::Span::Disabled), + status: LeafStatus::Fresh, + }; + let update = ActiveLeavesUpdate { + activated: Some(activated), + deactivated: [leaf_b.hash][..].into(), + }; + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update))) + .await; + handle_leaf_activation( + &mut virtual_overseer, + &leaf_c, + &test_state, + ASYNC_BACKING_PARAMETERS, + ) + .await; + + // Remove all remaining leaves. + let update = ActiveLeavesUpdate { + deactivated: [leaf_a.hash, leaf_c.hash][..].into(), + ..Default::default() + }; + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update))) + .await; + + // Activate and deactivate the same leaf. + let activated = ActivatedLeaf { + hash: leaf_a.hash, + number: leaf_a.number, + span: Arc::new(jaeger::Span::Disabled), + status: LeafStatus::Fresh, + }; + let update = ActiveLeavesUpdate { + activated: Some(activated), + deactivated: [leaf_a.hash][..].into(), + }; + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update))) + .await; + handle_leaf_activation( + &mut virtual_overseer, + &leaf_a, + &test_state, + ASYNC_BACKING_PARAMETERS, + ) + .await; + + // Remove the leaf again. Send some unnecessary hashes. + let update = ActiveLeavesUpdate { + deactivated: [leaf_a.hash, leaf_b.hash, leaf_c.hash][..].into(), + ..Default::default() + }; + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update))) + .await; + + virtual_overseer + }); + + assert_eq!(view.active_leaves.len(), 0); + assert_eq!(view.candidate_storage.len(), 0); +} + +#[test] +fn persists_pending_availability_candidate() { + let mut test_state = TestState::default(); + let para_id = ParaId::from(1); + test_state.availability_cores = test_state + .availability_cores + .into_iter() + .filter(|core| core.para_id().map_or(false, |id| id == para_id)) + .collect(); + assert_eq!(test_state.availability_cores.len(), 1); + + test_harness(|mut virtual_overseer| async move { + let para_head = HeadData(vec![1, 2, 3]); + + // Min allowed relay parent for leaf `a` which goes out of scope in the test. + let candidate_relay_parent = Hash::from_low_u64_be(5); + let candidate_relay_parent_number = 97; + + let leaf_a = TestLeaf { + number: candidate_relay_parent_number + ALLOWED_ANCESTRY_LEN, + hash: Hash::from_low_u64_be(2), + para_data: vec![( + para_id, + PerParaData::new(candidate_relay_parent_number, para_head.clone()), + )], + }; + + let leaf_b_hash = Hash::from_low_u64_be(1); + let leaf_b_number = leaf_a.number + 1; + + // Activate leaf. + activate_leaf(&mut virtual_overseer, &leaf_a, &test_state).await; + + // Candidate A + let (candidate_a, pvd_a) = make_candidate( + candidate_relay_parent, + candidate_relay_parent_number, + para_id, + para_head.clone(), + HeadData(vec![1]), + test_state.validation_code_hash, + ); + let candidate_hash_a = candidate_a.hash(); + + // Candidate B, built on top of the candidate which is out of scope but pending + // availability. + let (candidate_b, pvd_b) = make_candidate( + leaf_b_hash, + leaf_b_number, + para_id, + HeadData(vec![1]), + HeadData(vec![2]), + test_state.validation_code_hash, + ); + let candidate_hash_b = candidate_b.hash(); + + introduce_candidate(&mut virtual_overseer, candidate_a.clone(), pvd_a).await; + second_candidate(&mut virtual_overseer, candidate_a.clone()).await; + back_candidate(&mut virtual_overseer, &candidate_a, candidate_hash_a).await; + + let candidate_a_pending_av = CandidatePendingAvailability { + candidate_hash: candidate_hash_a, + descriptor: candidate_a.descriptor.clone(), + commitments: candidate_a.commitments.clone(), + relay_parent_number: candidate_relay_parent_number, + max_pov_size: MAX_POV_SIZE, + }; + let leaf_b = TestLeaf { + number: leaf_b_number, + hash: leaf_b_hash, + para_data: vec![( + 1.into(), + PerParaData::new_with_pending( + candidate_relay_parent_number + 1, + para_head.clone(), + vec![candidate_a_pending_av], + ), + )], + }; + activate_leaf(&mut virtual_overseer, &leaf_b, &test_state).await; + + introduce_candidate(&mut virtual_overseer, candidate_b.clone(), pvd_b).await; + second_candidate(&mut virtual_overseer, candidate_b.clone()).await; + back_candidate(&mut virtual_overseer, &candidate_b, candidate_hash_b).await; + + get_backable_candidate( + &mut virtual_overseer, + &leaf_b, + para_id, + vec![candidate_hash_a], + Some((candidate_hash_b, leaf_b_hash)), + ) + .await; + + virtual_overseer + }); +} + +#[test] +fn backwards_compatible() { + let mut test_state = TestState::default(); + let para_id = ParaId::from(1); + test_state.availability_cores = test_state + .availability_cores + .into_iter() + .filter(|core| core.para_id().map_or(false, |id| id == para_id)) + .collect(); + assert_eq!(test_state.availability_cores.len(), 1); + + test_harness(|mut virtual_overseer| async move { + let para_head = HeadData(vec![1, 2, 3]); + + let leaf_b_hash = Hash::repeat_byte(15); + let candidate_relay_parent = get_parent_hash(leaf_b_hash); + let candidate_relay_parent_number = 100; + + let leaf_a = TestLeaf { + number: candidate_relay_parent_number, + hash: candidate_relay_parent, + para_data: vec![( + para_id, + PerParaData::new(candidate_relay_parent_number, para_head.clone()), + )], + }; + + // Activate leaf. + activate_leaf_with_params( + &mut virtual_overseer, + &leaf_a, + &test_state, + AsyncBackingParams { allowed_ancestry_len: 0, max_candidate_depth: 0 }, + ) + .await; + + // Candidate A + let (candidate_a, pvd_a) = make_candidate( + candidate_relay_parent, + candidate_relay_parent_number, + para_id, + para_head.clone(), + HeadData(vec![1]), + test_state.validation_code_hash, + ); + let candidate_hash_a = candidate_a.hash(); + + introduce_candidate(&mut virtual_overseer, candidate_a.clone(), pvd_a).await; + second_candidate(&mut virtual_overseer, candidate_a.clone()).await; + back_candidate(&mut virtual_overseer, &candidate_a, candidate_hash_a).await; + + get_backable_candidate( + &mut virtual_overseer, + &leaf_a, + para_id, + vec![], + Some((candidate_hash_a, candidate_relay_parent)), + ) + .await; + + let leaf_b = TestLeaf { + number: candidate_relay_parent_number + 1, + hash: leaf_b_hash, + para_data: vec![( + para_id, + PerParaData::new(candidate_relay_parent_number + 1, para_head.clone()), + )], + }; + activate_leaf_with_params( + &mut virtual_overseer, + &leaf_b, + &test_state, + AsyncBackingParams { allowed_ancestry_len: 0, max_candidate_depth: 0 }, + ) + .await; + + get_backable_candidate(&mut virtual_overseer, &leaf_b, para_id, vec![], None).await; + + virtual_overseer + }); +} + +#[test] +fn uses_ancestry_only_within_session() { + test_harness(|mut virtual_overseer| async move { + let number = 5; + let hash = Hash::repeat_byte(5); + let ancestry_len = 3; + let session = 2; + + let ancestry_hashes = + vec![Hash::repeat_byte(4), Hash::repeat_byte(3), Hash::repeat_byte(2)]; + let session_change_hash = Hash::repeat_byte(3); + + let activated = ActivatedLeaf { + hash, + number, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(activated), + ))) + .await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) if parent == hash => { + tx.send(Ok(AsyncBackingParams { max_candidate_depth: 0, allowed_ancestry_len: ancestry_len })).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::AvailabilityCores(tx)) + ) if parent == hash => { + tx.send(Ok(Vec::new())).unwrap(); + } + ); + + send_block_header(&mut virtual_overseer, hash, number).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ChainApi( + ChainApiMessage::Ancestors{hash: block_hash, k, response_channel: tx} + ) if block_hash == hash && k == ancestry_len as usize => { + tx.send(Ok(ancestry_hashes.clone())).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx)) + ) if parent == hash => { + tx.send(Ok(session)).unwrap(); + } + ); + + for (i, hash) in ancestry_hashes.into_iter().enumerate() { + let number = number - (i + 1) as BlockNumber; + send_block_header(&mut virtual_overseer, hash, number).await; + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx)) + ) if parent == hash => { + if hash == session_change_hash { + tx.send(Ok(session - 1)).unwrap(); + break + } else { + tx.send(Ok(session)).unwrap(); + } + } + ); + } + + virtual_overseer + }); +} diff --git a/polkadot/node/core/provisioner/Cargo.toml b/polkadot/node/core/provisioner/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..dac671e7ada5fc2d98d9638576e09029a91390c0 --- /dev/null +++ b/polkadot/node/core/provisioner/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "polkadot-node-core-provisioner" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } +futures = "0.3.21" +gum = { package = "tracing-gum", path = "../../gum" } +thiserror = "1.0.31" +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +futures-timer = "3.0.2" +fatality = "0.0.6" + +[dev-dependencies] +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/core/provisioner/src/disputes/mod.rs b/polkadot/node/core/provisioner/src/disputes/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..2d8f6fb6e93b53decc2c2a8a167ea889e97d2e5b --- /dev/null +++ b/polkadot/node/core/provisioner/src/disputes/mod.rs @@ -0,0 +1,48 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The disputes module is responsible for selecting dispute votes to be sent with the inherent +//! data. + +use crate::LOG_TARGET; +use futures::channel::oneshot; +use polkadot_node_primitives::CandidateVotes; +use polkadot_node_subsystem::{messages::DisputeCoordinatorMessage, overseer}; +use polkadot_primitives::{CandidateHash, SessionIndex}; + +/// Request the relevant dispute statements for a set of disputes identified by `CandidateHash` and +/// the `SessionIndex`. +async fn request_votes( + sender: &mut impl overseer::ProvisionerSenderTrait, + disputes_to_query: Vec<(SessionIndex, CandidateHash)>, +) -> Vec<(SessionIndex, CandidateHash, CandidateVotes)> { + let (tx, rx) = oneshot::channel(); + // Bounded by block production - `ProvisionerMessage::RequestInherentData`. + sender.send_unbounded_message(DisputeCoordinatorMessage::QueryCandidateVotes( + disputes_to_query, + tx, + )); + + match rx.await { + Ok(v) => v, + Err(oneshot::Canceled) => { + gum::warn!(target: LOG_TARGET, "Unable to query candidate votes"); + Vec::new() + }, + } +} + +pub(crate) mod prioritized_selection; diff --git a/polkadot/node/core/provisioner/src/disputes/prioritized_selection/mod.rs b/polkadot/node/core/provisioner/src/disputes/prioritized_selection/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..096b73d271a8de637856b85836761c90593d96ee --- /dev/null +++ b/polkadot/node/core/provisioner/src/disputes/prioritized_selection/mod.rs @@ -0,0 +1,516 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This module uses different approach for selecting dispute votes. It queries the Runtime +//! about the votes already known onchain and tries to select only relevant votes. Refer to +//! the documentation of `select_disputes` for more details about the actual implementation. + +use crate::{error::GetOnchainDisputesError, metrics, LOG_TARGET}; +use futures::channel::oneshot; +use polkadot_node_primitives::{dispute_is_inactive, CandidateVotes, DisputeStatus, Timestamp}; +use polkadot_node_subsystem::{ + errors::RuntimeApiError, + messages::{DisputeCoordinatorMessage, RuntimeApiMessage, RuntimeApiRequest}, + overseer, ActivatedLeaf, +}; +use polkadot_primitives::{ + supermajority_threshold, CandidateHash, DisputeState, DisputeStatement, DisputeStatementSet, + Hash, MultiDisputeStatementSet, SessionIndex, ValidDisputeStatementKind, ValidatorIndex, +}; +use std::{ + collections::{BTreeMap, HashMap}, + time::{SystemTime, UNIX_EPOCH}, +}; + +#[cfg(test)] +mod tests; + +/// The maximum number of disputes Provisioner will include in the inherent data. +/// Serves as a protection not to flood the Runtime with excessive data. +#[cfg(not(test))] +pub const MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME: usize = 200_000; +#[cfg(test)] +pub const MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME: usize = 200; + +/// Controls how much dispute votes to be fetched from the `dispute-coordinator` per iteration in +/// `fn vote_selection`. The purpose is to fetch the votes in batches until +/// `MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME` is reached. If all votes are fetched in single call +/// we might fetch votes which we never use. This will create unnecessary load on +/// `dispute-coordinator`. +/// +/// This value should be less than `MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME`. Increase it in case +/// `provisioner` sends too many `QueryCandidateVotes` messages to `dispite-coordinator`. +#[cfg(not(test))] +const VOTES_SELECTION_BATCH_SIZE: usize = 1_100; +#[cfg(test)] +const VOTES_SELECTION_BATCH_SIZE: usize = 11; + +/// Implements the `select_disputes` function which selects dispute votes which should +/// be sent to the Runtime. +/// +/// # How the prioritization works +/// +/// Generally speaking disputes can be described as: +/// * Active vs Inactive +/// * Known vs Unknown onchain +/// * Offchain vs Onchain +/// * Concluded onchain vs Unconcluded onchain +/// +/// Provisioner fetches all disputes from `dispute-coordinator` and separates them in multiple +/// partitions. Please refer to `struct PartitionedDisputes` for details about the actual +/// partitions. Each partition has got a priority implicitly assigned to it and the disputes are +/// selected based on this priority (e.g. disputes in partition 1, then if there is space - disputes +/// from partition 2 and so on). +/// +/// # Votes selection +/// +/// Besides the prioritization described above the votes in each partition are filtered too. +/// Provisioner fetches all onchain votes and filters them out from all partitions. As a result the +/// Runtime receives only fresh votes (votes it didn't know about). +/// +/// # How the onchain votes are fetched +/// +/// The logic outlined above relies on `RuntimeApiRequest::Disputes` message from the Runtime. The +/// user check the Runtime version before calling `select_disputes`. If the function is used with +/// old runtime an error is logged and the logic will continue with empty onchain votes `HashMap`. +pub async fn select_disputes( + sender: &mut Sender, + metrics: &metrics::Metrics, + leaf: &ActivatedLeaf, +) -> MultiDisputeStatementSet +where + Sender: overseer::ProvisionerSenderTrait, +{ + gum::trace!( + target: LOG_TARGET, + ?leaf, + "Selecting disputes for inherent data using prioritized selection" + ); + + // Fetch the onchain disputes. We'll do a prioritization based on them. + let onchain = match get_onchain_disputes(sender, leaf.hash).await { + Ok(r) => { + gum::trace!( + target: LOG_TARGET, + ?leaf, + "Successfully fetched {} onchain disputes", + r.len() + ); + r + }, + Err(GetOnchainDisputesError::NotSupported(runtime_api_err, relay_parent)) => { + // Runtime version is checked before calling this method, so the error below should + // never happen! + gum::error!( + target: LOG_TARGET, + ?runtime_api_err, + ?relay_parent, + "Can't fetch onchain disputes, because ParachainHost runtime api version is old. Will continue with empty onchain disputes set.", + ); + HashMap::new() + }, + Err(GetOnchainDisputesError::Channel) => { + // This error usually means the node is shutting down. Log just in case. + gum::debug!( + target: LOG_TARGET, + "Channel error occurred while fetching onchain disputes. Will continue with empty onchain disputes set.", + ); + HashMap::new() + }, + Err(GetOnchainDisputesError::Execution(runtime_api_err, parent_hash)) => { + gum::warn!( + target: LOG_TARGET, + ?runtime_api_err, + ?parent_hash, + "Unexpected execution error occurred while fetching onchain votes. Will continue with empty onchain disputes set.", + ); + HashMap::new() + }, + }; + metrics.on_fetched_onchain_disputes(onchain.keys().len() as u64); + + gum::trace!(target: LOG_TARGET, ?leaf, "Fetching recent disputes"); + let recent_disputes = request_disputes(sender).await; + gum::trace!( + target: LOG_TARGET, + ?leaf, + "Got {} recent disputes and {} onchain disputes.", + recent_disputes.len(), + onchain.len(), + ); + + gum::trace!(target: LOG_TARGET, ?leaf, "Filtering recent disputes"); + + // Filter out unconfirmed disputes. However if the dispute is already onchain - don't skip it. + // In this case we'd better push as much fresh votes as possible to bring it to conclusion + // faster. + let recent_disputes = recent_disputes + .into_iter() + .filter(|d| d.2.is_confirmed_concluded() || onchain.contains_key(&(d.0, d.1))) + .collect::>(); + + gum::trace!(target: LOG_TARGET, ?leaf, "Partitioning recent disputes"); + let partitioned = partition_recent_disputes(recent_disputes, &onchain); + metrics.on_partition_recent_disputes(&partitioned); + + if partitioned.inactive_unknown_onchain.len() > 0 { + gum::warn!( + target: LOG_TARGET, + ?leaf, + "Got {} inactive unknown onchain disputes. This should not happen in normal conditions!", + partitioned.inactive_unknown_onchain.len() + ); + } + + gum::trace!(target: LOG_TARGET, ?leaf, "Vote selection for recent disputes"); + let result = vote_selection(sender, partitioned, &onchain).await; + + gum::trace!(target: LOG_TARGET, ?leaf, "Convert to multi dispute statement set"); + make_multi_dispute_statement_set(metrics, result) +} + +/// Selects dispute votes from `PartitionedDisputes` which should be sent to the runtime. Votes +/// which are already onchain are filtered out. Result should be sorted by `(SessionIndex, +/// CandidateHash)` which is enforced by the `BTreeMap`. This is a requirement from the runtime. +async fn vote_selection( + sender: &mut Sender, + partitioned: PartitionedDisputes, + onchain: &HashMap<(SessionIndex, CandidateHash), DisputeState>, +) -> BTreeMap<(SessionIndex, CandidateHash), CandidateVotes> +where + Sender: overseer::ProvisionerSenderTrait, +{ + // fetch in batches until there are enough votes + let mut disputes = partitioned.into_iter().collect::>(); + let mut total_votes_len = 0; + let mut result = BTreeMap::new(); + let mut request_votes_counter = 0; + while !disputes.is_empty() { + gum::trace!(target: LOG_TARGET, "has to process {} disputes left", disputes.len()); + let batch_size = std::cmp::min(VOTES_SELECTION_BATCH_SIZE, disputes.len()); + let batch = Vec::from_iter(disputes.drain(0..batch_size)); + + // Filter votes which are already onchain + request_votes_counter += 1; + gum::trace!(target: LOG_TARGET, "requesting onchain votes",); + let votes = super::request_votes(sender, batch) + .await + .into_iter() + .map(|(session_index, candidate_hash, mut votes)| { + let onchain_state = + if let Some(onchain_state) = onchain.get(&(session_index, candidate_hash)) { + onchain_state + } else { + // onchain knows nothing about this dispute - add all votes + return (session_index, candidate_hash, votes) + }; + + votes.valid.retain(|validator_idx, (statement_kind, _)| { + is_vote_worth_to_keep( + validator_idx, + DisputeStatement::Valid(*statement_kind), + &onchain_state, + ) + }); + votes.invalid.retain(|validator_idx, (statement_kind, _)| { + is_vote_worth_to_keep( + validator_idx, + DisputeStatement::Invalid(*statement_kind), + &onchain_state, + ) + }); + (session_index, candidate_hash, votes) + }) + .collect::>(); + gum::trace!(target: LOG_TARGET, "got {} onchain votes after processing", votes.len()); + + // Check if votes are within the limit + for (session_index, candidate_hash, selected_votes) in votes { + let votes_len = selected_votes.valid.raw().len() + selected_votes.invalid.len(); + if votes_len + total_votes_len > MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME { + // we are done - no more votes can be added. Importantly, we don't add any votes for + // a dispute here if we can't fit them all. This gives us an important invariant, + // that backing votes for disputes make it into the provisioned vote set. + gum::trace!( + target: LOG_TARGET, + ?request_votes_counter, + ?total_votes_len, + "vote_selection DisputeCoordinatorMessage::QueryCandidateVotes counter", + ); + + return result + } + + result.insert((session_index, candidate_hash), selected_votes); + total_votes_len += votes_len + } + } + + gum::trace!( + target: LOG_TARGET, + ?request_votes_counter, + ?total_votes_len, + "vote_selection DisputeCoordinatorMessage::QueryCandidateVotes counter", + ); + + result +} + +/// Contains disputes by partitions. Check the field comments for further details. +#[derive(Default)] +pub(crate) struct PartitionedDisputes { + /// Concluded and inactive disputes which are completely unknown for the Runtime. + /// Hopefully this should never happen. + /// Will be sent to the Runtime with FIRST priority. + pub inactive_unknown_onchain: Vec<(SessionIndex, CandidateHash)>, + /// Disputes which are INACTIVE locally but they are unconcluded for the Runtime. + /// A dispute can have enough local vote to conclude and at the same time the + /// Runtime knows nothing about them at treats it as unconcluded. This discrepancy + /// should be treated with high priority. + /// Will be sent to the Runtime with SECOND priority. + pub inactive_unconcluded_onchain: Vec<(SessionIndex, CandidateHash)>, + /// Active disputes completely unknown onchain. + /// Will be sent to the Runtime with THIRD priority. + pub active_unknown_onchain: Vec<(SessionIndex, CandidateHash)>, + /// Active disputes unconcluded onchain. + /// Will be sent to the Runtime with FOURTH priority. + pub active_unconcluded_onchain: Vec<(SessionIndex, CandidateHash)>, + /// Active disputes concluded onchain. New votes are not that important for + /// this partition. + /// Will be sent to the Runtime with FIFTH priority. + pub active_concluded_onchain: Vec<(SessionIndex, CandidateHash)>, + /// Inactive disputes which has concluded onchain. These are not interesting and + /// won't be sent to the Runtime. + /// Will be DROPPED + pub inactive_concluded_onchain: Vec<(SessionIndex, CandidateHash)>, +} + +impl PartitionedDisputes { + fn new() -> PartitionedDisputes { + Default::default() + } + + fn into_iter(self) -> impl Iterator { + self.inactive_unknown_onchain + .into_iter() + .chain(self.inactive_unconcluded_onchain.into_iter()) + .chain(self.active_unknown_onchain.into_iter()) + .chain(self.active_unconcluded_onchain.into_iter()) + .chain(self.active_concluded_onchain.into_iter()) + // inactive_concluded_onchain is dropped on purpose + } +} + +fn secs_since_epoch() -> Timestamp { + match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(d) => d.as_secs(), + Err(e) => { + gum::warn!( + target: LOG_TARGET, + err = ?e, + "Error getting system time." + ); + 0 + }, + } +} + +fn concluded_onchain(onchain_state: &DisputeState) -> bool { + // Check if there are enough onchain votes for or against to conclude the dispute + let supermajority = supermajority_threshold(onchain_state.validators_for.len()); + + onchain_state.validators_for.count_ones() >= supermajority || + onchain_state.validators_against.count_ones() >= supermajority +} + +fn partition_recent_disputes( + recent: Vec<(SessionIndex, CandidateHash, DisputeStatus)>, + onchain: &HashMap<(SessionIndex, CandidateHash), DisputeState>, +) -> PartitionedDisputes { + let mut partitioned = PartitionedDisputes::new(); + + // Drop any duplicates + let unique_recent = recent + .into_iter() + .map(|(session_index, candidate_hash, dispute_state)| { + ((session_index, candidate_hash), dispute_state) + }) + .collect::>(); + + // Split recent disputes in ACTIVE and INACTIVE + let time_now = &secs_since_epoch(); + let (active, inactive): ( + Vec<(SessionIndex, CandidateHash, DisputeStatus)>, + Vec<(SessionIndex, CandidateHash, DisputeStatus)>, + ) = unique_recent + .into_iter() + .map(|((session_index, candidate_hash), dispute_state)| { + (session_index, candidate_hash, dispute_state) + }) + .partition(|(_, _, status)| !dispute_is_inactive(status, time_now)); + + // Split ACTIVE in three groups... + for (session_index, candidate_hash, _) in active { + match onchain.get(&(session_index, candidate_hash)) { + Some(d) => match concluded_onchain(d) { + true => partitioned.active_concluded_onchain.push((session_index, candidate_hash)), + false => + partitioned.active_unconcluded_onchain.push((session_index, candidate_hash)), + }, + None => partitioned.active_unknown_onchain.push((session_index, candidate_hash)), + }; + } + + // ... and INACTIVE in three more + for (session_index, candidate_hash, _) in inactive { + match onchain.get(&(session_index, candidate_hash)) { + Some(onchain_state) => + if concluded_onchain(onchain_state) { + partitioned.inactive_concluded_onchain.push((session_index, candidate_hash)); + } else { + partitioned.inactive_unconcluded_onchain.push((session_index, candidate_hash)); + }, + None => partitioned.inactive_unknown_onchain.push((session_index, candidate_hash)), + } + } + + partitioned +} + +/// Determines if a vote is worth to be kept, based on the onchain disputes +fn is_vote_worth_to_keep( + validator_index: &ValidatorIndex, + dispute_statement: DisputeStatement, + onchain_state: &DisputeState, +) -> bool { + let (offchain_vote, valid_kind) = match dispute_statement { + DisputeStatement::Valid(kind) => (true, Some(kind)), + DisputeStatement::Invalid(_) => (false, None), + }; + // We want to keep all backing votes. This maximizes the number of backers + // punished when misbehaving. + if let Some(kind) = valid_kind { + match kind { + ValidDisputeStatementKind::BackingValid(_) | + ValidDisputeStatementKind::BackingSeconded(_) => return true, + _ => (), + } + } + + let in_validators_for = onchain_state + .validators_for + .get(validator_index.0 as usize) + .as_deref() + .copied() + .unwrap_or(false); + let in_validators_against = onchain_state + .validators_against + .get(validator_index.0 as usize) + .as_deref() + .copied() + .unwrap_or(false); + + if in_validators_for && in_validators_against { + // The validator has double voted and runtime knows about this. Ignore this vote. + return false + } + + if offchain_vote && in_validators_against || !offchain_vote && in_validators_for { + // offchain vote differs from the onchain vote + // we need this vote to punish the offending validator + return true + } + + // The vote is valid. Return true if it is not seen onchain. + !in_validators_for && !in_validators_against +} + +/// Request disputes identified by `CandidateHash` and the `SessionIndex`. +async fn request_disputes( + sender: &mut impl overseer::ProvisionerSenderTrait, +) -> Vec<(SessionIndex, CandidateHash, DisputeStatus)> { + let (tx, rx) = oneshot::channel(); + let msg = DisputeCoordinatorMessage::RecentDisputes(tx); + + // Bounded by block production - `ProvisionerMessage::RequestInherentData`. + sender.send_unbounded_message(msg); + + let recent_disputes = rx.await.unwrap_or_else(|err| { + gum::warn!(target: LOG_TARGET, err=?err, "Unable to gather recent disputes"); + Vec::new() + }); + recent_disputes +} + +// This function produces the return value for `pub fn select_disputes()` +fn make_multi_dispute_statement_set( + metrics: &metrics::Metrics, + dispute_candidate_votes: BTreeMap<(SessionIndex, CandidateHash), CandidateVotes>, +) -> MultiDisputeStatementSet { + // Transform all `CandidateVotes` into `MultiDisputeStatementSet`. + dispute_candidate_votes + .into_iter() + .map(|((session_index, candidate_hash), votes)| { + let valid_statements = votes + .valid + .into_iter() + .map(|(i, (s, sig))| (DisputeStatement::Valid(s), i, sig)); + + let invalid_statements = votes + .invalid + .into_iter() + .map(|(i, (s, sig))| (DisputeStatement::Invalid(s), i, sig)); + + metrics.inc_valid_statements_by(valid_statements.len()); + metrics.inc_invalid_statements_by(invalid_statements.len()); + metrics.inc_dispute_statement_sets_by(1); + + DisputeStatementSet { + candidate_hash, + session: session_index, + statements: valid_statements.chain(invalid_statements).collect(), + } + }) + .collect() +} + +/// Gets the on-chain disputes at a given block number and returns them as a `HashMap` so that +/// searching in them is cheap. +pub async fn get_onchain_disputes( + sender: &mut Sender, + relay_parent: Hash, +) -> Result, GetOnchainDisputesError> +where + Sender: overseer::ProvisionerSenderTrait, +{ + gum::trace!(target: LOG_TARGET, ?relay_parent, "Fetching on-chain disputes"); + let (tx, rx) = oneshot::channel(); + sender + .send_message(RuntimeApiMessage::Request(relay_parent, RuntimeApiRequest::Disputes(tx))) + .await; + + rx.await + .map_err(|_| GetOnchainDisputesError::Channel) + .and_then(|res| { + res.map_err(|e| match e { + RuntimeApiError::Execution { .. } => + GetOnchainDisputesError::Execution(e, relay_parent), + RuntimeApiError::NotSupported { .. } => + GetOnchainDisputesError::NotSupported(e, relay_parent), + }) + }) + .map(|v| v.into_iter().map(|e| ((e.0, e.1), e.2)).collect()) +} diff --git a/polkadot/node/core/provisioner/src/disputes/prioritized_selection/tests.rs b/polkadot/node/core/provisioner/src/disputes/prioritized_selection/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..2fdeadb2f4f0e532be1e460507d428a07e1cbc1a --- /dev/null +++ b/polkadot/node/core/provisioner/src/disputes/prioritized_selection/tests.rs @@ -0,0 +1,792 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::super::{ + super::{tests::common::test_harness, *}, + prioritized_selection::*, +}; +use bitvec::prelude::*; +use futures::channel::mpsc; +use polkadot_node_primitives::{CandidateVotes, DisputeStatus, ACTIVE_DURATION_SECS}; +use polkadot_node_subsystem::messages::{ + AllMessages, DisputeCoordinatorMessage, RuntimeApiMessage, RuntimeApiRequest, +}; +use polkadot_node_subsystem_test_helpers::TestSubsystemSender; +use polkadot_primitives::{ + CandidateHash, DisputeState, InvalidDisputeStatementKind, SessionIndex, + ValidDisputeStatementKind, ValidatorSignature, +}; +use std::sync::Arc; +use test_helpers; + +// +// Unit tests for various functions +// +#[test] +fn should_keep_vote_behaves() { + let onchain_state = DisputeState { + validators_for: bitvec![u8, Lsb0; 1, 0, 1, 0, 1], + validators_against: bitvec![u8, Lsb0; 0, 1, 0, 0, 1], + start: 1, + concluded_at: None, + }; + + let local_valid_known = (ValidatorIndex(0), ValidDisputeStatementKind::Explicit); + let local_valid_unknown = (ValidatorIndex(3), ValidDisputeStatementKind::Explicit); + + let local_invalid_known = (ValidatorIndex(1), InvalidDisputeStatementKind::Explicit); + let local_invalid_unknown = (ValidatorIndex(3), InvalidDisputeStatementKind::Explicit); + + assert_eq!( + is_vote_worth_to_keep( + &local_valid_known.0, + DisputeStatement::Valid(local_valid_known.1), + &onchain_state + ), + false + ); + assert_eq!( + is_vote_worth_to_keep( + &local_valid_unknown.0, + DisputeStatement::Valid(local_valid_unknown.1), + &onchain_state + ), + true + ); + assert_eq!( + is_vote_worth_to_keep( + &local_invalid_known.0, + DisputeStatement::Invalid(local_invalid_known.1), + &onchain_state + ), + false + ); + assert_eq!( + is_vote_worth_to_keep( + &local_invalid_unknown.0, + DisputeStatement::Invalid(local_invalid_unknown.1), + &onchain_state + ), + true + ); + + //double voting - onchain knows + let local_double_vote_onchain_knows = + (ValidatorIndex(4), InvalidDisputeStatementKind::Explicit); + assert_eq!( + is_vote_worth_to_keep( + &local_double_vote_onchain_knows.0, + DisputeStatement::Invalid(local_double_vote_onchain_knows.1), + &onchain_state + ), + false + ); + + //double voting - onchain doesn't know + let local_double_vote_onchain_doesnt_knows = + (ValidatorIndex(0), InvalidDisputeStatementKind::Explicit); + assert_eq!( + is_vote_worth_to_keep( + &local_double_vote_onchain_doesnt_knows.0, + DisputeStatement::Invalid(local_double_vote_onchain_doesnt_knows.1), + &onchain_state + ), + true + ); + + // empty onchain state + let empty_onchain_state = DisputeState { + validators_for: BitVec::new(), + validators_against: BitVec::new(), + start: 1, + concluded_at: None, + }; + assert_eq!( + is_vote_worth_to_keep( + &local_double_vote_onchain_doesnt_knows.0, + DisputeStatement::Invalid(local_double_vote_onchain_doesnt_knows.1), + &empty_onchain_state + ), + true + ); +} + +#[test] +fn partitioning_happy_case() { + let mut input = Vec::<(SessionIndex, CandidateHash, DisputeStatus)>::new(); + let mut onchain = HashMap::<(u32, CandidateHash), DisputeState>::new(); + let time_now = secs_since_epoch(); + + // Create one dispute for each partition + let inactive_unknown_onchain = ( + 0, + CandidateHash(Hash::random()), + DisputeStatus::ConcludedFor(time_now - ACTIVE_DURATION_SECS * 2), + ); + input.push(inactive_unknown_onchain); + + let inactive_unconcluded_onchain = ( + 1, + CandidateHash(Hash::random()), + DisputeStatus::ConcludedFor(time_now - ACTIVE_DURATION_SECS * 2), + ); + input.push(inactive_unconcluded_onchain); + onchain.insert( + (inactive_unconcluded_onchain.0, inactive_unconcluded_onchain.1), + DisputeState { + validators_for: bitvec![u8, Lsb0; 1, 1, 1, 0, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, Lsb0; 0, 0, 0, 0, 0, 0, 0, 0, 0], + start: 1, + concluded_at: None, + }, + ); + + let active_unknown_onchain = (2, CandidateHash(Hash::random()), DisputeStatus::Active); + input.push(active_unknown_onchain); + + let active_unconcluded_onchain = (3, CandidateHash(Hash::random()), DisputeStatus::Active); + input.push(active_unconcluded_onchain); + onchain.insert( + (active_unconcluded_onchain.0, active_unconcluded_onchain.1), + DisputeState { + validators_for: bitvec![u8, Lsb0; 1, 1, 1, 0, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, Lsb0; 0, 0, 0, 0, 0, 0, 0, 0, 0], + start: 1, + concluded_at: None, + }, + ); + + let active_concluded_onchain = (4, CandidateHash(Hash::random()), DisputeStatus::Active); + input.push(active_concluded_onchain); + onchain.insert( + (active_concluded_onchain.0, active_concluded_onchain.1), + DisputeState { + validators_for: bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 1, 1, 1, 0], + validators_against: bitvec![u8, Lsb0; 0, 0, 0, 0, 0, 0, 0, 0, 0], + start: 1, + concluded_at: Some(3), + }, + ); + + let inactive_concluded_onchain = ( + 5, + CandidateHash(Hash::random()), + DisputeStatus::ConcludedFor(time_now - ACTIVE_DURATION_SECS * 2), + ); + input.push(inactive_concluded_onchain); + onchain.insert( + (inactive_concluded_onchain.0, inactive_concluded_onchain.1), + DisputeState { + validators_for: bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 1, 1, 0, 0], + validators_against: bitvec![u8, Lsb0; 0, 0, 0, 0, 0, 0, 0, 0, 0], + start: 1, + concluded_at: Some(3), + }, + ); + + let result = partition_recent_disputes(input, &onchain); + + // Check results + assert_eq!(result.inactive_unknown_onchain.len(), 1); + assert_eq!( + result.inactive_unknown_onchain.get(0).unwrap(), + &(inactive_unknown_onchain.0, inactive_unknown_onchain.1) + ); + + assert_eq!(result.inactive_unconcluded_onchain.len(), 1); + assert_eq!( + result.inactive_unconcluded_onchain.get(0).unwrap(), + &(inactive_unconcluded_onchain.0, inactive_unconcluded_onchain.1) + ); + + assert_eq!(result.active_unknown_onchain.len(), 1); + assert_eq!( + result.active_unknown_onchain.get(0).unwrap(), + &(active_unknown_onchain.0, active_unknown_onchain.1) + ); + + assert_eq!(result.active_unconcluded_onchain.len(), 1); + assert_eq!( + result.active_unconcluded_onchain.get(0).unwrap(), + &(active_unconcluded_onchain.0, active_unconcluded_onchain.1) + ); + + assert_eq!(result.active_concluded_onchain.len(), 1); + assert_eq!( + result.active_concluded_onchain.get(0).unwrap(), + &(active_concluded_onchain.0, active_concluded_onchain.1) + ); + + assert_eq!(result.inactive_concluded_onchain.len(), 1); + assert_eq!( + result.inactive_concluded_onchain.get(0).unwrap(), + &(inactive_concluded_onchain.0, inactive_concluded_onchain.1) + ); +} + +// This test verifies the double voting behavior. Currently we don't care if a supermajority is +// achieved with or without the 'help' of a double vote (a validator voting for and against at the +// same time). This makes the test a bit pointless but anyway I'm leaving it here to make this +// decision explicit and have the test code ready in case this behavior needs to be further tested +// in the future. Link to the PR with the discussions: https://github.com/paritytech/polkadot/pull/5567 +#[test] +fn partitioning_doubled_onchain_vote() { + let mut input = Vec::<(SessionIndex, CandidateHash, DisputeStatus)>::new(); + let mut onchain = HashMap::<(u32, CandidateHash), DisputeState>::new(); + + // Dispute A relies on a 'double onchain vote' to conclude. Validator with index 0 has voted + // both `for` and `against`. Despite that this dispute should be considered 'can conclude + // onchain'. + let dispute_a = (3, CandidateHash(Hash::random()), DisputeStatus::Active); + // Dispute B has supermajority + 1 votes, so the doubled onchain vote doesn't affect it. It + // should be considered as 'can conclude onchain'. + let dispute_b = (4, CandidateHash(Hash::random()), DisputeStatus::Active); + input.push(dispute_a); + input.push(dispute_b); + onchain.insert( + (dispute_a.0, dispute_a.1), + DisputeState { + validators_for: bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 1, 1, 0, 0], + validators_against: bitvec![u8, Lsb0; 1, 0, 0, 0, 0, 0, 0, 0, 0], + start: 1, + concluded_at: None, + }, + ); + onchain.insert( + (dispute_b.0, dispute_b.1), + DisputeState { + validators_for: bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 1, 1, 1, 0], + validators_against: bitvec![u8, Lsb0; 1, 0, 0, 0, 0, 0, 0, 0, 0], + start: 1, + concluded_at: None, + }, + ); + + let result = partition_recent_disputes(input, &onchain); + + assert_eq!(result.active_unconcluded_onchain.len(), 0); + assert_eq!(result.active_concluded_onchain.len(), 2); +} + +#[test] +fn partitioning_duplicated_dispute() { + let mut input = Vec::<(SessionIndex, CandidateHash, DisputeStatus)>::new(); + let mut onchain = HashMap::<(u32, CandidateHash), DisputeState>::new(); + + let some_dispute = (3, CandidateHash(Hash::random()), DisputeStatus::Active); + input.push(some_dispute); + input.push(some_dispute); + onchain.insert( + (some_dispute.0, some_dispute.1), + DisputeState { + validators_for: bitvec![u8, Lsb0; 1, 1, 1, 0, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, Lsb0; 0, 0, 0, 0, 0, 0, 0, 0, 0], + start: 1, + concluded_at: None, + }, + ); + + let result = partition_recent_disputes(input, &onchain); + + assert_eq!(result.active_unconcluded_onchain.len(), 1); + assert_eq!( + result.active_unconcluded_onchain.get(0).unwrap(), + &(some_dispute.0, some_dispute.1) + ); +} + +// +// end-to-end tests for select_disputes() +// + +async fn mock_overseer( + mut receiver: mpsc::UnboundedReceiver, + disputes_db: &mut TestDisputes, + vote_queries_count: &mut usize, +) { + while let Some(from_job) = receiver.next().await { + match from_job { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::Disputes(sender), + )) => { + let _ = sender.send(Ok(disputes_db + .onchain_disputes + .clone() + .into_iter() + .map(|(k, v)| (k.0, k.1, v)) + .collect::>())); + }, + AllMessages::RuntimeApi(_) => panic!("Unexpected RuntimeApi request"), + AllMessages::DisputeCoordinator(DisputeCoordinatorMessage::RecentDisputes(sender)) => { + let _ = sender.send(disputes_db.local_disputes.clone()); + }, + AllMessages::DisputeCoordinator(DisputeCoordinatorMessage::QueryCandidateVotes( + disputes, + sender, + )) => { + *vote_queries_count += 1; + let mut res = Vec::new(); + for d in disputes.iter() { + let v = disputes_db.votes_db.get(d).unwrap().clone(); + res.push((d.0, d.1, v)); + } + + let _ = sender.send(res); + }, + _ => panic!("Unexpected message: {:?}", from_job), + } + } +} + +fn leaf() -> ActivatedLeaf { + ActivatedLeaf { + hash: Hash::repeat_byte(0xAA), + number: 0xAA, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + } +} + +struct TestDisputes { + pub local_disputes: Vec<(SessionIndex, CandidateHash, DisputeStatus)>, + pub votes_db: HashMap<(SessionIndex, CandidateHash), CandidateVotes>, + pub onchain_disputes: HashMap<(u32, CandidateHash), DisputeState>, + validators_count: usize, +} + +impl TestDisputes { + pub fn new(validators_count: usize) -> TestDisputes { + TestDisputes { + local_disputes: Vec::<(SessionIndex, CandidateHash, DisputeStatus)>::new(), + votes_db: HashMap::<(SessionIndex, CandidateHash), CandidateVotes>::new(), + onchain_disputes: HashMap::<(u32, CandidateHash), DisputeState>::new(), + validators_count, + } + } + + // Offchain disputes are on node side + fn add_offchain_dispute( + &mut self, + dispute: (SessionIndex, CandidateHash, DisputeStatus), + local_votes_count: usize, + dummy_receipt: CandidateReceipt, + ) { + self.local_disputes.push(dispute); + self.votes_db.insert( + (dispute.0, dispute.1), + CandidateVotes { + candidate_receipt: dummy_receipt, + valid: TestDisputes::generate_local_votes( + ValidDisputeStatementKind::Explicit, + 0, + local_votes_count, + ) + .into_iter() + .collect(), + invalid: BTreeMap::new(), + }, + ); + } + + fn add_onchain_dispute( + &mut self, + dispute: (SessionIndex, CandidateHash, DisputeStatus), + onchain_votes_count: usize, + ) { + let concluded_at = match dispute.2 { + DisputeStatus::Active | DisputeStatus::Confirmed => None, + DisputeStatus::ConcludedAgainst(_) | DisputeStatus::ConcludedFor(_) => Some(1), + }; + self.onchain_disputes.insert( + (dispute.0, dispute.1), + DisputeState { + validators_for: TestDisputes::generate_bitvec( + self.validators_count, + 0, + onchain_votes_count, + ), + validators_against: bitvec![u8, Lsb0; 0; self.validators_count], + start: 1, + concluded_at, + }, + ); + } + + pub fn add_unconfirmed_disputes_concluded_onchain( + &mut self, + dispute_count: usize, + ) -> (SessionIndex, usize) { + let local_votes_count = self.validators_count * 90 / 100; + let onchain_votes_count = self.validators_count * 80 / 100; + let session_idx = 0; + let lf = leaf(); + let dummy_receipt = test_helpers::dummy_candidate_receipt(lf.hash); + for _ in 0..dispute_count { + let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); + self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); + self.add_onchain_dispute(d, onchain_votes_count); + } + + (session_idx, (local_votes_count - onchain_votes_count) * dispute_count) + } + + pub fn add_unconfirmed_disputes_unconcluded_onchain( + &mut self, + dispute_count: usize, + ) -> (SessionIndex, usize) { + let local_votes_count = self.validators_count * 90 / 100; + let onchain_votes_count = self.validators_count * 40 / 100; + let session_idx = 1; + let lf = leaf(); + let dummy_receipt = test_helpers::dummy_candidate_receipt(lf.hash); + for _ in 0..dispute_count { + let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); + self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); + self.add_onchain_dispute(d, onchain_votes_count); + } + + (session_idx, (local_votes_count - onchain_votes_count) * dispute_count) + } + + pub fn add_confirmed_disputes_unknown_onchain( + &mut self, + dispute_count: usize, + ) -> (SessionIndex, usize) { + let local_votes_count = self.validators_count * 90 / 100; + let session_idx = 2; + let lf = leaf(); + let dummy_receipt = test_helpers::dummy_candidate_receipt(lf.hash); + for _ in 0..dispute_count { + let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Confirmed); + self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); + } + (session_idx, local_votes_count * dispute_count) + } + + pub fn add_concluded_disputes_known_onchain( + &mut self, + dispute_count: usize, + ) -> (SessionIndex, usize) { + let local_votes_count = self.validators_count * 90 / 100; + let onchain_votes_count = self.validators_count * 75 / 100; + let session_idx = 3; + let lf = leaf(); + let dummy_receipt = test_helpers::dummy_candidate_receipt(lf.hash); + for _ in 0..dispute_count { + let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::ConcludedFor(0)); + self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); + self.add_onchain_dispute(d, onchain_votes_count); + } + (session_idx, (local_votes_count - onchain_votes_count) * dispute_count) + } + + pub fn add_concluded_disputes_unknown_onchain( + &mut self, + dispute_count: usize, + ) -> (SessionIndex, usize) { + let local_votes_count = self.validators_count * 90 / 100; + let session_idx = 4; + let lf = leaf(); + let dummy_receipt = test_helpers::dummy_candidate_receipt(lf.hash); + for _ in 0..dispute_count { + let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::ConcludedFor(0)); + self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); + } + (session_idx, local_votes_count * dispute_count) + } + + pub fn add_unconfirmed_disputes_known_onchain( + &mut self, + dispute_count: usize, + ) -> (SessionIndex, usize) { + let local_votes_count = self.validators_count * 10 / 100; + let onchain_votes_count = self.validators_count * 10 / 100; + let session_idx = 5; + let lf = leaf(); + let dummy_receipt = test_helpers::dummy_candidate_receipt(lf.hash); + for _ in 0..dispute_count { + let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); + self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); + self.add_onchain_dispute(d, onchain_votes_count); + } + + (session_idx, (local_votes_count - onchain_votes_count) * dispute_count) + } + + pub fn add_unconfirmed_disputes_unknown_onchain( + &mut self, + dispute_count: usize, + ) -> (SessionIndex, usize) { + let local_votes_count = self.validators_count * 10 / 100; + let session_idx = 6; + let lf = leaf(); + let dummy_receipt = test_helpers::dummy_candidate_receipt(lf.hash); + for _ in 0..dispute_count { + let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); + self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); + } + + (session_idx, local_votes_count * dispute_count) + } + + fn generate_local_votes( + statement_kind: T, + start_idx: usize, + count: usize, + ) -> BTreeMap { + assert!(start_idx < count); + (start_idx..count) + .map(|idx| { + ( + ValidatorIndex(idx as u32), + (statement_kind.clone(), test_helpers::dummy_signature()), + ) + }) + .collect::>() + } + + fn generate_bitvec( + validator_count: usize, + start_idx: usize, + count: usize, + ) -> BitVec { + assert!(start_idx < count); + assert!(start_idx + count < validator_count); + let mut res = bitvec![u8, Lsb0; 0; validator_count]; + for idx in start_idx..count { + res.set(idx, true); + } + + res + } +} + +#[test] +fn normal_flow() { + const VALIDATOR_COUNT: usize = 10; + const DISPUTES_PER_BATCH: usize = 2; + const ACCEPTABLE_RUNTIME_VOTES_QUERIES_COUNT: usize = 1; + + let mut input = TestDisputes::new(VALIDATOR_COUNT); + + // active, concluded onchain + let (third_idx, third_votes) = + input.add_unconfirmed_disputes_concluded_onchain(DISPUTES_PER_BATCH); + + // active unconcluded onchain + let (first_idx, first_votes) = + input.add_unconfirmed_disputes_unconcluded_onchain(DISPUTES_PER_BATCH); + + //concluded disputes unknown onchain + let (fifth_idx, fifth_votes) = input.add_concluded_disputes_unknown_onchain(DISPUTES_PER_BATCH); + + // concluded disputes known onchain - these should be ignored + let (_, _) = input.add_concluded_disputes_known_onchain(DISPUTES_PER_BATCH); + + // confirmed disputes unknown onchain + let (second_idx, second_votes) = + input.add_confirmed_disputes_unknown_onchain(DISPUTES_PER_BATCH); + + let metrics = metrics::Metrics::new_dummy(); + let mut vote_queries: usize = 0; + test_harness( + |r| mock_overseer(r, &mut input, &mut vote_queries), + |mut tx: TestSubsystemSender| async move { + let lf = leaf(); + let result = select_disputes(&mut tx, &metrics, &lf).await; + + assert!(!result.is_empty()); + + assert_eq!(result.len(), 4 * DISPUTES_PER_BATCH); + + // Naive checks that the result is partitioned correctly + let (first_batch, rest): (Vec, Vec) = + result.into_iter().partition(|d| d.session == first_idx); + assert_eq!(first_batch.len(), DISPUTES_PER_BATCH); + + let (second_batch, rest): (Vec, Vec) = + rest.into_iter().partition(|d| d.session == second_idx); + assert_eq!(second_batch.len(), DISPUTES_PER_BATCH); + + let (third_batch, rest): (Vec, Vec) = + rest.into_iter().partition(|d| d.session == third_idx); + assert_eq!(third_batch.len(), DISPUTES_PER_BATCH); + + let (fifth_batch, rest): (Vec, Vec) = + rest.into_iter().partition(|d| d.session == fifth_idx); + assert_eq!(fifth_batch.len(), DISPUTES_PER_BATCH); + + // Ensure there are no more disputes - fourth_batch should be dropped + assert_eq!(rest.len(), 0); + + assert_eq!( + first_batch.iter().map(|d| d.statements.len()).fold(0, |acc, v| acc + v), + first_votes + ); + assert_eq!( + second_batch.iter().map(|d| d.statements.len()).fold(0, |acc, v| acc + v), + second_votes + ); + assert_eq!( + third_batch.iter().map(|d| d.statements.len()).fold(0, |acc, v| acc + v), + third_votes + ); + assert_eq!( + fifth_batch.iter().map(|d| d.statements.len()).fold(0, |acc, v| acc + v), + fifth_votes + ); + }, + ); + assert!(vote_queries <= ACCEPTABLE_RUNTIME_VOTES_QUERIES_COUNT); +} + +#[test] +fn many_batches() { + const VALIDATOR_COUNT: usize = 10; + const DISPUTES_PER_PARTITION: usize = 10; + + // 10 disputes per partition * 4 partitions = 40 disputes + // BATCH_SIZE = 11 + // => There should be no more than 40 / 11 queries ( ~4 ) + const ACCEPTABLE_RUNTIME_VOTES_QUERIES_COUNT: usize = 4; + + let mut input = TestDisputes::new(VALIDATOR_COUNT); + + // active which can conclude onchain + input.add_unconfirmed_disputes_concluded_onchain(DISPUTES_PER_PARTITION); + + // active which can't conclude onchain + input.add_unconfirmed_disputes_unconcluded_onchain(DISPUTES_PER_PARTITION); + + //concluded disputes unknown onchain + input.add_concluded_disputes_unknown_onchain(DISPUTES_PER_PARTITION); + + // concluded disputes known onchain + input.add_concluded_disputes_known_onchain(DISPUTES_PER_PARTITION); + + // confirmed disputes unknown onchain + input.add_confirmed_disputes_unknown_onchain(DISPUTES_PER_PARTITION); + + let metrics = metrics::Metrics::new_dummy(); + let mut vote_queries: usize = 0; + test_harness( + |r| mock_overseer(r, &mut input, &mut vote_queries), + |mut tx: TestSubsystemSender| async move { + let lf = leaf(); + let result = select_disputes(&mut tx, &metrics, &lf).await; + + assert!(!result.is_empty()); + + let vote_count = result.iter().map(|d| d.statements.len()).fold(0, |acc, v| acc + v); + + assert!( + MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME - VALIDATOR_COUNT <= vote_count && + vote_count <= MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME, + "vote_count: {}", + vote_count + ); + }, + ); + + assert!( + vote_queries <= ACCEPTABLE_RUNTIME_VOTES_QUERIES_COUNT, + "vote_queries: {} ACCEPTABLE_RUNTIME_VOTES_QUERIES_COUNT: {}", + vote_queries, + ACCEPTABLE_RUNTIME_VOTES_QUERIES_COUNT + ); +} + +#[test] +fn votes_above_limit() { + const VALIDATOR_COUNT: usize = 10; + const DISPUTES_PER_PARTITION: usize = 50; + const ACCEPTABLE_RUNTIME_VOTES_QUERIES_COUNT: usize = 4; + + let mut input = TestDisputes::new(VALIDATOR_COUNT); + + // active which can conclude onchain + let (_, second_votes) = + input.add_unconfirmed_disputes_concluded_onchain(DISPUTES_PER_PARTITION); + + // active which can't conclude onchain + let (_, first_votes) = + input.add_unconfirmed_disputes_unconcluded_onchain(DISPUTES_PER_PARTITION); + + //concluded disputes unknown onchain + let (_, third_votes) = input.add_concluded_disputes_unknown_onchain(DISPUTES_PER_PARTITION); + + assert!( + first_votes + second_votes + third_votes > 3 * MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME, + "Total relevant votes generated: {}", + first_votes + second_votes + third_votes + ); + + let metrics = metrics::Metrics::new_dummy(); + let mut vote_queries: usize = 0; + test_harness( + |r| mock_overseer(r, &mut input, &mut vote_queries), + |mut tx: TestSubsystemSender| async move { + let lf = leaf(); + let result = select_disputes(&mut tx, &metrics, &lf).await; + + assert!(!result.is_empty()); + + let vote_count = result.iter().map(|d| d.statements.len()).fold(0, |acc, v| acc + v); + + assert!( + MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME - VALIDATOR_COUNT <= vote_count && + vote_count <= MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME, + "vote_count: {}", + vote_count + ); + }, + ); + + assert!( + vote_queries <= ACCEPTABLE_RUNTIME_VOTES_QUERIES_COUNT, + "vote_queries: {} ACCEPTABLE_RUNTIME_VOTES_QUERIES_COUNT: {}", + vote_queries, + ACCEPTABLE_RUNTIME_VOTES_QUERIES_COUNT + ); +} + +#[test] +fn unconfirmed_are_handled_correctly() { + const VALIDATOR_COUNT: usize = 10; + const DISPUTES_PER_PARTITION: usize = 50; + + let mut input = TestDisputes::new(VALIDATOR_COUNT); + + // Add unconfirmed known onchain -> this should be pushed + let (pushed_idx, _) = input.add_unconfirmed_disputes_known_onchain(DISPUTES_PER_PARTITION); + + // Add unconfirmed unknown onchain -> this should be ignored + input.add_unconfirmed_disputes_unknown_onchain(DISPUTES_PER_PARTITION); + + let metrics = metrics::Metrics::new_dummy(); + let mut vote_queries: usize = 0; + test_harness( + |r| mock_overseer(r, &mut input, &mut vote_queries), + |mut tx: TestSubsystemSender| async move { + let lf = leaf(); + let result = select_disputes(&mut tx, &metrics, &lf).await; + + assert!(result.len() == DISPUTES_PER_PARTITION); + result.iter().for_each(|d| assert!(d.session == pushed_idx)); + }, + ); +} diff --git a/polkadot/node/core/provisioner/src/error.rs b/polkadot/node/core/provisioner/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..376d69f276fc892e92828bf994b29f847fae31d0 --- /dev/null +++ b/polkadot/node/core/provisioner/src/error.rs @@ -0,0 +1,122 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +///! Error types for provisioner module +use fatality::Nested; +use futures::channel::{mpsc, oneshot}; +use polkadot_node_subsystem::errors::{ChainApiError, RuntimeApiError, SubsystemError}; +use polkadot_node_subsystem_util as util; +use polkadot_primitives::Hash; + +pub type FatalResult = std::result::Result; +pub type Result = std::result::Result; + +/// Errors in the provisioner. +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + #[fatal(forward)] + #[error("Error while accessing runtime information")] + Runtime(#[from] util::runtime::Error), + + #[error(transparent)] + Util(#[from] util::Error), + + #[error("failed to get availability cores")] + CanceledAvailabilityCores(#[source] oneshot::Canceled), + + #[error("failed to get persisted validation data")] + CanceledPersistedValidationData(#[source] oneshot::Canceled), + + #[error("failed to get block number")] + CanceledBlockNumber(#[source] oneshot::Canceled), + + #[error("failed to get backed candidates")] + CanceledBackedCandidates(#[source] oneshot::Canceled), + + #[error("failed to get votes on dispute")] + CanceledCandidateVotes(#[source] oneshot::Canceled), + + #[error("failed to get backable candidate from prospective parachains")] + CanceledBackableCandidate(#[source] oneshot::Canceled), + + #[error(transparent)] + ChainApi(#[from] ChainApiError), + + #[error(transparent)] + RuntimeApi(#[from] RuntimeApiError), + + #[error("failed to send message to ChainAPI")] + ChainApiMessageSend(#[source] mpsc::SendError), + + #[error("failed to send message to CandidateBacking to get backed candidates")] + GetBackedCandidatesSend(#[source] mpsc::SendError), + + #[error("Send inherent data timeout.")] + SendInherentDataTimeout, + + #[error("failed to send return message with Inherents")] + InherentDataReturnChannel, + + #[error( + "backed candidate does not correspond to selected candidate; check logic in provisioner" + )] + BackedCandidateOrderingProblem, + + #[fatal] + #[error("Failed to spawn background task")] + FailedToSpawnBackgroundTask, + + #[error(transparent)] + SubsystemError(#[from] SubsystemError), + + #[fatal] + #[error(transparent)] + OverseerExited(SubsystemError), +} + +/// Used by `get_onchain_disputes` to represent errors related to fetching on-chain disputes from +/// the Runtime +#[allow(dead_code)] // Remove when promoting to stable +#[fatality::fatality] +pub enum GetOnchainDisputesError { + #[fatal] + #[error("runtime subsystem is down")] + Channel, + + #[error("runtime execution error occurred while fetching onchain disputes for parent {1}")] + Execution(#[source] RuntimeApiError, Hash), + + #[error("runtime doesn't support RuntimeApiRequest::Disputes for parent {1}")] + NotSupported(#[source] RuntimeApiError, Hash), +} + +pub fn log_error(result: Result<()>) -> std::result::Result<(), FatalError> { + match result.into_nested()? { + Ok(()) => Ok(()), + Err(jfyi) => { + jfyi.log(); + Ok(()) + }, + } +} + +impl JfyiError { + /// Log a `JfyiError`. + pub fn log(self) { + gum::debug!(target: super::LOG_TARGET, error = ?self); + } +} diff --git a/polkadot/node/core/provisioner/src/lib.rs b/polkadot/node/core/provisioner/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..f81e5550b15da98ccab276c55a7dc0877eed27e6 --- /dev/null +++ b/polkadot/node/core/provisioner/src/lib.rs @@ -0,0 +1,917 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The provisioner is responsible for assembling a relay chain block +//! from a set of available parachain candidates of its choice. + +#![deny(missing_docs, unused_crate_dependencies)] + +use bitvec::vec::BitVec; +use futures::{ + channel::oneshot, future::BoxFuture, prelude::*, stream::FuturesUnordered, FutureExt, +}; +use futures_timer::Delay; + +use polkadot_node_subsystem::{ + jaeger, + messages::{ + CandidateBackingMessage, ChainApiMessage, ProspectiveParachainsMessage, ProvisionableData, + ProvisionerInherentData, ProvisionerMessage, RuntimeApiMessage, RuntimeApiRequest, + }, + overseer, ActivatedLeaf, ActiveLeavesUpdate, FromOrchestra, LeafStatus, OverseerSignal, + PerLeafSpan, RuntimeApiError, SpawnedSubsystem, SubsystemError, +}; +use polkadot_node_subsystem_util::{ + request_availability_cores, request_persisted_validation_data, + runtime::{prospective_parachains_mode, ProspectiveParachainsMode}, + TimeoutExt, +}; +use polkadot_primitives::{ + BackedCandidate, BlockNumber, CandidateHash, CandidateReceipt, CoreState, Hash, Id as ParaId, + OccupiedCoreAssumption, SignedAvailabilityBitfield, ValidatorIndex, +}; +use std::collections::{BTreeMap, HashMap}; + +mod disputes; +mod error; +mod metrics; + +pub use self::metrics::*; +use error::{Error, FatalResult}; + +#[cfg(test)] +mod tests; + +/// How long to wait before proposing. +const PRE_PROPOSE_TIMEOUT: std::time::Duration = core::time::Duration::from_millis(2000); +/// Some timeout to ensure task won't hang around in the background forever on issues. +const SEND_INHERENT_DATA_TIMEOUT: std::time::Duration = core::time::Duration::from_millis(500); + +const LOG_TARGET: &str = "parachain::provisioner"; + +const PRIORITIZED_SELECTION_RUNTIME_VERSION_REQUIREMENT: u32 = + RuntimeApiRequest::DISPUTES_RUNTIME_REQUIREMENT; + +/// The provisioner subsystem. +pub struct ProvisionerSubsystem { + metrics: Metrics, +} + +impl ProvisionerSubsystem { + /// Create a new instance of the `ProvisionerSubsystem`. + pub fn new(metrics: Metrics) -> Self { + Self { metrics } + } +} + +/// A per-relay-parent state for the provisioning subsystem. +pub struct PerRelayParent { + leaf: ActivatedLeaf, + backed_candidates: Vec, + prospective_parachains_mode: ProspectiveParachainsMode, + signed_bitfields: Vec, + is_inherent_ready: bool, + awaiting_inherent: Vec>, + span: PerLeafSpan, +} + +impl PerRelayParent { + fn new(leaf: ActivatedLeaf, prospective_parachains_mode: ProspectiveParachainsMode) -> Self { + let span = PerLeafSpan::new(leaf.span.clone(), "provisioner"); + + Self { + leaf, + backed_candidates: Vec::new(), + prospective_parachains_mode, + signed_bitfields: Vec::new(), + is_inherent_ready: false, + awaiting_inherent: Vec::new(), + span, + } + } +} + +type InherentDelays = FuturesUnordered>; + +#[overseer::subsystem(Provisioner, error=SubsystemError, prefix=self::overseer)] +impl ProvisionerSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = async move { + run(ctx, self.metrics) + .await + .map_err(|e| SubsystemError::with_origin("provisioner", e)) + } + .boxed(); + + SpawnedSubsystem { name: "provisioner-subsystem", future } + } +} + +#[overseer::contextbounds(Provisioner, prefix = self::overseer)] +async fn run(mut ctx: Context, metrics: Metrics) -> FatalResult<()> { + let mut inherent_delays = InherentDelays::new(); + let mut per_relay_parent = HashMap::new(); + + loop { + let result = + run_iteration(&mut ctx, &mut per_relay_parent, &mut inherent_delays, &metrics).await; + + match result { + Ok(()) => break, + err => crate::error::log_error(err)?, + } + } + + Ok(()) +} + +#[overseer::contextbounds(Provisioner, prefix = self::overseer)] +async fn run_iteration( + ctx: &mut Context, + per_relay_parent: &mut HashMap, + inherent_delays: &mut InherentDelays, + metrics: &Metrics, +) -> Result<(), Error> { + loop { + futures::select! { + from_overseer = ctx.recv().fuse() => { + // Map the error to ensure that the subsystem exits when the overseer is gone. + match from_overseer.map_err(Error::OverseerExited)? { + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => + handle_active_leaves_update(ctx.sender(), update, per_relay_parent, inherent_delays).await?, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {}, + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), + FromOrchestra::Communication { msg } => { + handle_communication(ctx, per_relay_parent, msg, metrics).await?; + }, + } + }, + hash = inherent_delays.select_next_some() => { + if let Some(state) = per_relay_parent.get_mut(&hash) { + state.is_inherent_ready = true; + + gum::trace!( + target: LOG_TARGET, + relay_parent = ?hash, + "Inherent Data became ready" + ); + + let return_senders = std::mem::take(&mut state.awaiting_inherent); + if !return_senders.is_empty() { + send_inherent_data_bg(ctx, &state, return_senders, metrics.clone()).await?; + } + } + } + } + } +} + +async fn handle_active_leaves_update( + sender: &mut impl overseer::ProvisionerSenderTrait, + update: ActiveLeavesUpdate, + per_relay_parent: &mut HashMap, + inherent_delays: &mut InherentDelays, +) -> Result<(), Error> { + gum::trace!(target: LOG_TARGET, "Handle ActiveLeavesUpdate"); + for deactivated in &update.deactivated { + per_relay_parent.remove(deactivated); + } + + if let Some(leaf) = update.activated { + gum::trace!(target: LOG_TARGET, leaf_hash=?leaf.hash, "Adding delay"); + let prospective_parachains_mode = prospective_parachains_mode(sender, leaf.hash).await?; + let delay_fut = Delay::new(PRE_PROPOSE_TIMEOUT).map(move |_| leaf.hash).boxed(); + per_relay_parent.insert(leaf.hash, PerRelayParent::new(leaf, prospective_parachains_mode)); + inherent_delays.push(delay_fut); + } + + Ok(()) +} + +#[overseer::contextbounds(Provisioner, prefix = self::overseer)] +async fn handle_communication( + ctx: &mut Context, + per_relay_parent: &mut HashMap, + message: ProvisionerMessage, + metrics: &Metrics, +) -> Result<(), Error> { + match message { + ProvisionerMessage::RequestInherentData(relay_parent, return_sender) => { + gum::trace!(target: LOG_TARGET, ?relay_parent, "Inherent data got requested."); + + if let Some(state) = per_relay_parent.get_mut(&relay_parent) { + if state.is_inherent_ready { + gum::trace!(target: LOG_TARGET, ?relay_parent, "Calling send_inherent_data."); + send_inherent_data_bg(ctx, &state, vec![return_sender], metrics.clone()) + .await?; + } else { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + "Queuing inherent data request (inherent data not yet ready)." + ); + state.awaiting_inherent.push(return_sender); + } + } + }, + ProvisionerMessage::ProvisionableData(relay_parent, data) => { + if let Some(state) = per_relay_parent.get_mut(&relay_parent) { + let span = state.span.child("provisionable-data"); + let _timer = metrics.time_provisionable_data(); + + gum::trace!(target: LOG_TARGET, ?relay_parent, "Received provisionable data."); + + note_provisionable_data(state, &span, data); + } + }, + } + + Ok(()) +} + +#[overseer::contextbounds(Provisioner, prefix = self::overseer)] +async fn send_inherent_data_bg( + ctx: &mut Context, + per_relay_parent: &PerRelayParent, + return_senders: Vec>, + metrics: Metrics, +) -> Result<(), Error> { + let leaf = per_relay_parent.leaf.clone(); + let signed_bitfields = per_relay_parent.signed_bitfields.clone(); + let backed_candidates = per_relay_parent.backed_candidates.clone(); + let mode = per_relay_parent.prospective_parachains_mode; + let span = per_relay_parent.span.child("req-inherent-data"); + + let mut sender = ctx.sender().clone(); + + let bg = async move { + let _span = span; + let _timer = metrics.time_request_inherent_data(); + + gum::trace!( + target: LOG_TARGET, + relay_parent = ?leaf.hash, + "Sending inherent data in background." + ); + + let send_result = send_inherent_data( + &leaf, + &signed_bitfields, + &backed_candidates, + mode, + return_senders, + &mut sender, + &metrics, + ) // Make sure call is not taking forever: + .timeout(SEND_INHERENT_DATA_TIMEOUT) + .map(|v| match v { + Some(r) => r, + None => Err(Error::SendInherentDataTimeout), + }); + + match send_result.await { + Err(err) => { + if let Error::CanceledBackedCandidates(_) = err { + gum::debug!( + target: LOG_TARGET, + err = ?err, + "Failed to assemble or send inherent data - block got likely obsoleted already." + ); + } else { + gum::warn!(target: LOG_TARGET, err = ?err, "failed to assemble or send inherent data"); + } + metrics.on_inherent_data_request(Err(())); + }, + Ok(()) => { + metrics.on_inherent_data_request(Ok(())); + gum::debug!( + target: LOG_TARGET, + signed_bitfield_count = signed_bitfields.len(), + leaf_hash = ?leaf.hash, + "inherent data sent successfully" + ); + metrics.observe_inherent_data_bitfields_count(signed_bitfields.len()); + }, + } + }; + + ctx.spawn("send-inherent-data", bg.boxed()) + .map_err(|_| Error::FailedToSpawnBackgroundTask)?; + + Ok(()) +} + +fn note_provisionable_data( + per_relay_parent: &mut PerRelayParent, + span: &jaeger::Span, + provisionable_data: ProvisionableData, +) { + match provisionable_data { + ProvisionableData::Bitfield(_, signed_bitfield) => + per_relay_parent.signed_bitfields.push(signed_bitfield), + ProvisionableData::BackedCandidate(backed_candidate) => { + let candidate_hash = backed_candidate.hash(); + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + para = ?backed_candidate.descriptor().para_id, + "noted backed candidate", + ); + let _span = span + .child("provisionable-backed") + .with_candidate(candidate_hash) + .with_para_id(backed_candidate.descriptor().para_id); + per_relay_parent.backed_candidates.push(backed_candidate); + }, + // We choose not to punish these forms of misbehavior for the time being. + // Risks from misbehavior are sufficiently mitigated at the protocol level + // via reputation changes. Punitive actions here may become desirable + // enough to dedicate time to in the future. + ProvisionableData::MisbehaviorReport(_, _, _) => {}, + // We wait and do nothing here, preferring to initiate a dispute after the + // parablock candidate is included for the following reasons: + // + // 1. A dispute for a candidate triggered at any point before the candidate + // has been made available, including the backing stage, can't be + // guaranteed to conclude. Non-concluding disputes are unacceptable. + // 2. Candidates which haven't been made available don't pose a security + // risk as they can not be included, approved, or finalized. + // + // Currently we rely on approval checkers to trigger disputes for bad + // parablocks once they are included. But we can do slightly better by + // allowing disagreeing backers to record their disagreement and initiate a + // dispute once the parablock in question has been included. This potential + // change is tracked by: https://github.com/paritytech/polkadot/issues/3232 + ProvisionableData::Dispute(_, _) => {}, + } +} + +type CoreAvailability = BitVec; + +/// The provisioner is the subsystem best suited to choosing which specific +/// backed candidates and availability bitfields should be assembled into the +/// block. To engage this functionality, a +/// `ProvisionerMessage::RequestInherentData` is sent; the response is a set of +/// non-conflicting candidates and the appropriate bitfields. Non-conflicting +/// means that there are never two distinct parachain candidates included for +/// the same parachain and that new parachain candidates cannot be included +/// until the previous one either gets declared available or expired. +/// +/// The main complication here is going to be around handling +/// occupied-core-assumptions. We might have candidates that are only +/// includable when some bitfields are included. And we might have candidates +/// that are not includable when certain bitfields are included. +/// +/// When we're choosing bitfields to include, the rule should be simple: +/// maximize availability. So basically, include all bitfields. And then +/// choose a coherent set of candidates along with that. +async fn send_inherent_data( + leaf: &ActivatedLeaf, + bitfields: &[SignedAvailabilityBitfield], + candidates: &[CandidateReceipt], + prospective_parachains_mode: ProspectiveParachainsMode, + return_senders: Vec>, + from_job: &mut impl overseer::ProvisionerSenderTrait, + metrics: &Metrics, +) -> Result<(), Error> { + gum::trace!( + target: LOG_TARGET, + relay_parent = ?leaf.hash, + "Requesting availability cores" + ); + let availability_cores = request_availability_cores(leaf.hash, from_job) + .await + .await + .map_err(|err| Error::CanceledAvailabilityCores(err))??; + + gum::trace!( + target: LOG_TARGET, + relay_parent = ?leaf.hash, + "Selecting disputes" + ); + + debug_assert!( + has_required_runtime( + from_job, + leaf.hash, + PRIORITIZED_SELECTION_RUNTIME_VERSION_REQUIREMENT, + ) + .await, + "randomized selection no longer supported, please upgrade your runtime!" + ); + + let disputes = disputes::prioritized_selection::select_disputes(from_job, metrics, leaf).await; + + gum::trace!( + target: LOG_TARGET, + relay_parent = ?leaf.hash, + "Selected disputes" + ); + + // Only include bitfields on fresh leaves. On chain reversions, we want to make sure that + // there will be at least one block, which cannot get disputed, so the chain can make progress. + let bitfields = match leaf.status { + LeafStatus::Fresh => + select_availability_bitfields(&availability_cores, bitfields, &leaf.hash), + LeafStatus::Stale => Vec::new(), + }; + + gum::trace!( + target: LOG_TARGET, + relay_parent = ?leaf.hash, + "Selected bitfields" + ); + + let candidates = select_candidates( + &availability_cores, + &bitfields, + candidates, + prospective_parachains_mode, + leaf.hash, + from_job, + ) + .await?; + + gum::trace!( + target: LOG_TARGET, + relay_parent = ?leaf.hash, + "Selected candidates" + ); + + gum::debug!( + target: LOG_TARGET, + availability_cores_len = availability_cores.len(), + disputes_count = disputes.len(), + bitfields_count = bitfields.len(), + candidates_count = candidates.len(), + leaf_hash = ?leaf.hash, + "inherent data prepared", + ); + + let inherent_data = + ProvisionerInherentData { bitfields, backed_candidates: candidates, disputes }; + + gum::trace!( + target: LOG_TARGET, + relay_parent = ?leaf.hash, + "Sending back inherent data to requesters." + ); + + for return_sender in return_senders { + return_sender + .send(inherent_data.clone()) + .map_err(|_data| Error::InherentDataReturnChannel)?; + } + + Ok(()) +} + +/// In general, we want to pick all the bitfields. However, we have the following constraints: +/// +/// - not more than one per validator +/// - each 1 bit must correspond to an occupied core +/// +/// If we have too many, an arbitrary selection policy is fine. For purposes of maximizing +/// availability, we pick the one with the greatest number of 1 bits. +/// +/// Note: This does not enforce any sorting precondition on the output; the ordering there will be +/// unrelated to the sorting of the input. +fn select_availability_bitfields( + cores: &[CoreState], + bitfields: &[SignedAvailabilityBitfield], + leaf_hash: &Hash, +) -> Vec { + let mut selected: BTreeMap = BTreeMap::new(); + + gum::debug!( + target: LOG_TARGET, + bitfields_count = bitfields.len(), + ?leaf_hash, + "bitfields count before selection" + ); + + 'a: for bitfield in bitfields.iter().cloned() { + if bitfield.payload().0.len() != cores.len() { + gum::debug!(target: LOG_TARGET, ?leaf_hash, "dropping bitfield due to length mismatch"); + continue + } + + let is_better = selected + .get(&bitfield.validator_index()) + .map_or(true, |b| b.payload().0.count_ones() < bitfield.payload().0.count_ones()); + + if !is_better { + gum::trace!( + target: LOG_TARGET, + val_idx = bitfield.validator_index().0, + ?leaf_hash, + "dropping bitfield due to duplication - the better one is kept" + ); + continue + } + + for (idx, _) in cores.iter().enumerate().filter(|v| !v.1.is_occupied()) { + // Bit is set for an unoccupied core - invalid + if *bitfield.payload().0.get(idx).as_deref().unwrap_or(&false) { + gum::debug!( + target: LOG_TARGET, + val_idx = bitfield.validator_index().0, + ?leaf_hash, + "dropping invalid bitfield - bit is set for an unoccupied core" + ); + continue 'a + } + } + + let _ = selected.insert(bitfield.validator_index(), bitfield); + } + + gum::debug!( + target: LOG_TARGET, + ?leaf_hash, + "selected {} of all {} bitfields (each bitfield is from a unique validator)", + selected.len(), + bitfields.len() + ); + + selected.into_values().collect() +} + +/// Selects candidates from tracked ones to note in a relay chain block. +/// +/// Should be called when prospective parachains are disabled. +async fn select_candidate_hashes_from_tracked( + availability_cores: &[CoreState], + bitfields: &[SignedAvailabilityBitfield], + candidates: &[CandidateReceipt], + relay_parent: Hash, + sender: &mut impl overseer::ProvisionerSenderTrait, +) -> Result, Error> { + let block_number = get_block_number_under_construction(relay_parent, sender).await?; + + let mut selected_candidates = + Vec::with_capacity(candidates.len().min(availability_cores.len())); + + gum::debug!( + target: LOG_TARGET, + leaf_hash=?relay_parent, + n_candidates = candidates.len(), + "Candidate receipts (before selection)", + ); + + for (core_idx, core) in availability_cores.iter().enumerate() { + let (scheduled_core, assumption) = match core { + CoreState::Scheduled(scheduled_core) => (scheduled_core, OccupiedCoreAssumption::Free), + CoreState::Occupied(occupied_core) => { + if bitfields_indicate_availability(core_idx, bitfields, &occupied_core.availability) + { + if let Some(ref scheduled_core) = occupied_core.next_up_on_available { + (scheduled_core, OccupiedCoreAssumption::Included) + } else { + continue + } + } else { + if occupied_core.time_out_at != block_number { + continue + } + if let Some(ref scheduled_core) = occupied_core.next_up_on_time_out { + (scheduled_core, OccupiedCoreAssumption::TimedOut) + } else { + continue + } + } + }, + CoreState::Free => continue, + }; + + let validation_data = match request_persisted_validation_data( + relay_parent, + scheduled_core.para_id, + assumption, + sender, + ) + .await + .await + .map_err(|err| Error::CanceledPersistedValidationData(err))?? + { + Some(v) => v, + None => continue, + }; + + let computed_validation_data_hash = validation_data.hash(); + + // we arbitrarily pick the first of the backed candidates which match the appropriate + // selection criteria + if let Some(candidate) = candidates.iter().find(|backed_candidate| { + let descriptor = &backed_candidate.descriptor; + descriptor.para_id == scheduled_core.para_id && + descriptor.persisted_validation_data_hash == computed_validation_data_hash + }) { + let candidate_hash = candidate.hash(); + gum::trace!( + target: LOG_TARGET, + leaf_hash=?relay_parent, + ?candidate_hash, + para = ?candidate.descriptor.para_id, + core = core_idx, + "Selected candidate receipt", + ); + + selected_candidates.push((candidate_hash, candidate.descriptor.relay_parent)); + } + } + + Ok(selected_candidates) +} + +/// Requests backable candidates from Prospective Parachains subsystem +/// based on core states. +/// +/// Should be called when prospective parachains are enabled. +async fn request_backable_candidates( + availability_cores: &[CoreState], + bitfields: &[SignedAvailabilityBitfield], + relay_parent: Hash, + sender: &mut impl overseer::ProvisionerSenderTrait, +) -> Result, Error> { + let block_number = get_block_number_under_construction(relay_parent, sender).await?; + + let mut selected_candidates = Vec::with_capacity(availability_cores.len()); + + for (core_idx, core) in availability_cores.iter().enumerate() { + let (para_id, required_path) = match core { + CoreState::Scheduled(scheduled_core) => { + // The core is free, pick the first eligible candidate from + // the fragment tree. + (scheduled_core.para_id, Vec::new()) + }, + CoreState::Occupied(occupied_core) => { + if bitfields_indicate_availability(core_idx, bitfields, &occupied_core.availability) + { + if let Some(ref scheduled_core) = occupied_core.next_up_on_available { + // The candidate occupying the core is available, choose its + // child in the fragment tree. + // + // TODO: doesn't work for on-demand parachains. We lean hard on the + // assumption that cores are fixed to specific parachains within a session. + // https://github.com/paritytech/polkadot/issues/5492 + (scheduled_core.para_id, vec![occupied_core.candidate_hash]) + } else { + continue + } + } else { + if occupied_core.time_out_at != block_number { + continue + } + if let Some(ref scheduled_core) = occupied_core.next_up_on_time_out { + // Candidate's availability timed out, practically same as scheduled. + (scheduled_core.para_id, Vec::new()) + } else { + continue + } + } + }, + CoreState::Free => continue, + }; + + let response = get_backable_candidate(relay_parent, para_id, required_path, sender).await?; + + match response { + Some((hash, relay_parent)) => selected_candidates.push((hash, relay_parent)), + None => { + gum::debug!( + target: LOG_TARGET, + leaf_hash = ?relay_parent, + core = core_idx, + "No backable candidate returned by prospective parachains", + ); + }, + } + } + + Ok(selected_candidates) +} + +/// Determine which cores are free, and then to the degree possible, pick a candidate appropriate to +/// each free core. +async fn select_candidates( + availability_cores: &[CoreState], + bitfields: &[SignedAvailabilityBitfield], + candidates: &[CandidateReceipt], + prospective_parachains_mode: ProspectiveParachainsMode, + relay_parent: Hash, + sender: &mut impl overseer::ProvisionerSenderTrait, +) -> Result, Error> { + gum::trace!(target: LOG_TARGET, + leaf_hash=?relay_parent, + "before GetBackedCandidates"); + + let selected_candidates = match prospective_parachains_mode { + ProspectiveParachainsMode::Enabled { .. } => + request_backable_candidates(availability_cores, bitfields, relay_parent, sender).await?, + ProspectiveParachainsMode::Disabled => + select_candidate_hashes_from_tracked( + availability_cores, + bitfields, + &candidates, + relay_parent, + sender, + ) + .await?, + }; + + // now get the backed candidates corresponding to these candidate receipts + let (tx, rx) = oneshot::channel(); + sender.send_unbounded_message(CandidateBackingMessage::GetBackedCandidates( + selected_candidates.clone(), + tx, + )); + let mut candidates = rx.await.map_err(|err| Error::CanceledBackedCandidates(err))?; + gum::trace!(target: LOG_TARGET, leaf_hash=?relay_parent, + "Got {} backed candidates", candidates.len()); + + // `selected_candidates` is generated in ascending order by core index, and + // `GetBackedCandidates` _should_ preserve that property, but let's just make sure. + // + // We can't easily map from `BackedCandidate` to `core_idx`, but we know that every selected + // candidate maps to either 0 or 1 backed candidate, and the hashes correspond. Therefore, by + // checking them in order, we can ensure that the backed candidates are also in order. + let mut backed_idx = 0; + for selected in selected_candidates { + if selected.0 == + candidates.get(backed_idx).ok_or(Error::BackedCandidateOrderingProblem)?.hash() + { + backed_idx += 1; + } + } + if candidates.len() != backed_idx { + Err(Error::BackedCandidateOrderingProblem)?; + } + + // keep only one candidate with validation code. + let mut with_validation_code = false; + candidates.retain(|c| { + if c.candidate.commitments.new_validation_code.is_some() { + if with_validation_code { + return false + } + + with_validation_code = true; + } + + true + }); + + gum::debug!( + target: LOG_TARGET, + n_candidates = candidates.len(), + n_cores = availability_cores.len(), + ?relay_parent, + "Selected backed candidates", + ); + + Ok(candidates) +} + +/// Produces a block number 1 higher than that of the relay parent +/// in the event of an invalid `relay_parent`, returns `Ok(0)` +async fn get_block_number_under_construction( + relay_parent: Hash, + sender: &mut impl overseer::ProvisionerSenderTrait, +) -> Result { + let (tx, rx) = oneshot::channel(); + sender.send_message(ChainApiMessage::BlockNumber(relay_parent, tx)).await; + + match rx.await.map_err(|err| Error::CanceledBlockNumber(err))? { + Ok(Some(n)) => Ok(n + 1), + Ok(None) => Ok(0), + Err(err) => Err(err.into()), + } +} + +/// Requests backable candidate from Prospective Parachains based on +/// the given path in the fragment tree. +async fn get_backable_candidate( + relay_parent: Hash, + para_id: ParaId, + required_path: Vec, + sender: &mut impl overseer::ProvisionerSenderTrait, +) -> Result, Error> { + let (tx, rx) = oneshot::channel(); + sender + .send_message(ProspectiveParachainsMessage::GetBackableCandidate( + relay_parent, + para_id, + required_path, + tx, + )) + .await; + + rx.await.map_err(Error::CanceledBackableCandidate) +} + +/// The availability bitfield for a given core is the transpose +/// of a set of signed availability bitfields. It goes like this: +/// +/// - construct a transverse slice along `core_idx` +/// - bitwise-or it with the availability slice +/// - count the 1 bits, compare to the total length; true on 2/3+ +fn bitfields_indicate_availability( + core_idx: usize, + bitfields: &[SignedAvailabilityBitfield], + availability: &CoreAvailability, +) -> bool { + let mut availability = availability.clone(); + let availability_len = availability.len(); + + for bitfield in bitfields { + let validator_idx = bitfield.validator_index().0 as usize; + match availability.get_mut(validator_idx) { + None => { + // in principle, this function might return a `Result` so that we can + // more clearly express this error condition however, in practice, that would just + // push off an error-handling routine which would look a whole lot like this one. + // simpler to just handle the error internally here. + gum::warn!( + target: LOG_TARGET, + validator_idx = %validator_idx, + availability_len = %availability_len, + "attempted to set a transverse bit at idx {} which is greater than bitfield size {}", + validator_idx, + availability_len, + ); + + return false + }, + Some(mut bit_mut) => *bit_mut |= bitfield.payload().0[core_idx], + } + } + + 3 * availability.count_ones() >= 2 * availability.len() +} + +// If we have to be absolutely precise here, this method gets the version of the `ParachainHost` +// api. For brevity we'll just call it 'runtime version'. +async fn has_required_runtime( + sender: &mut impl overseer::ProvisionerSenderTrait, + relay_parent: Hash, + required_runtime_version: u32, +) -> bool { + gum::trace!(target: LOG_TARGET, ?relay_parent, "Fetching ParachainHost runtime api version"); + + let (tx, rx) = oneshot::channel(); + sender + .send_message(RuntimeApiMessage::Request(relay_parent, RuntimeApiRequest::Version(tx))) + .await; + + match rx.await { + Result::Ok(Ok(runtime_version)) => { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + ?runtime_version, + ?required_runtime_version, + "Fetched ParachainHost runtime api version" + ); + runtime_version >= required_runtime_version + }, + Result::Ok(Err(RuntimeApiError::Execution { source: error, .. })) => { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + ?error, + "Execution error while fetching ParachainHost runtime api version" + ); + false + }, + Result::Ok(Err(RuntimeApiError::NotSupported { .. })) => { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + "NotSupported error while fetching ParachainHost runtime api version" + ); + false + }, + Result::Err(_) => { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + "Cancelled error while fetching ParachainHost runtime api version" + ); + false + }, + } +} diff --git a/polkadot/node/core/provisioner/src/metrics.rs b/polkadot/node/core/provisioner/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..fabbd798cf02b5da4c96ddb922b12aaf68100363 --- /dev/null +++ b/polkadot/node/core/provisioner/src/metrics.rs @@ -0,0 +1,229 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::disputes::prioritized_selection::PartitionedDisputes; +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +struct MetricsInner { + /// Tracks successful/unsuccessful inherent data requests + inherent_data_requests: prometheus::CounterVec, + /// How much time the `RequestInherentData` processing takes + request_inherent_data_duration: prometheus::Histogram, + /// How much time `ProvisionableData` processing takes + provisionable_data_duration: prometheus::Histogram, + /// Bitfields array length in `ProvisionerInherentData` (the result for `RequestInherentData`) + inherent_data_response_bitfields: prometheus::Histogram, + + /// The following metrics track how many disputes/votes the runtime will have to process. These + /// will count all recent statements meaning every dispute from last sessions: 10 min on + /// Rococo, 60 min on Kusama and 4 hours on Polkadot. The metrics are updated only when the + /// node authors a block, so values vary across nodes. + inherent_data_dispute_statement_sets: prometheus::Counter, + inherent_data_dispute_statements: prometheus::CounterVec, + + /// The disputes received from `disputes-coordinator` by partition + partitioned_disputes: prometheus::CounterVec, + + /// The disputes fetched from the runtime. + fetched_onchain_disputes: prometheus::Counter, +} + +/// Provisioner metrics. +#[derive(Default, Clone)] +pub struct Metrics(Option); + +impl Metrics { + /// Creates new dummy `Metrics` instance. Used for testing only. + #[cfg(test)] + pub fn new_dummy() -> Metrics { + Metrics(None) + } + + pub(crate) fn on_inherent_data_request(&self, response: Result<(), ()>) { + if let Some(metrics) = &self.0 { + match response { + Ok(()) => metrics.inherent_data_requests.with_label_values(&["succeeded"]).inc(), + Err(()) => metrics.inherent_data_requests.with_label_values(&["failed"]).inc(), + } + } + } + + /// Provide a timer for `request_inherent_data` which observes on drop. + pub(crate) fn time_request_inherent_data( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.request_inherent_data_duration.start_timer()) + } + + /// Provide a timer for `provisionable_data` which observes on drop. + pub(crate) fn time_provisionable_data( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.provisionable_data_duration.start_timer()) + } + + pub(crate) fn observe_inherent_data_bitfields_count(&self, bitfields_count: usize) { + self.0.as_ref().map(|metrics| { + metrics.inherent_data_response_bitfields.observe(bitfields_count as f64) + }); + } + + pub(crate) fn inc_valid_statements_by(&self, votes: usize) { + if let Some(metrics) = &self.0 { + metrics + .inherent_data_dispute_statements + .with_label_values(&["valid"]) + .inc_by(votes.try_into().unwrap_or(0)); + } + } + + pub(crate) fn inc_invalid_statements_by(&self, votes: usize) { + if let Some(metrics) = &self.0 { + metrics + .inherent_data_dispute_statements + .with_label_values(&["invalid"]) + .inc_by(votes.try_into().unwrap_or(0)); + } + } + + pub(crate) fn inc_dispute_statement_sets_by(&self, disputes: usize) { + if let Some(metrics) = &self.0 { + metrics + .inherent_data_dispute_statement_sets + .inc_by(disputes.try_into().unwrap_or(0)); + } + } + + pub(crate) fn on_partition_recent_disputes(&self, disputes: &PartitionedDisputes) { + if let Some(metrics) = &self.0 { + let PartitionedDisputes { + inactive_unknown_onchain, + inactive_unconcluded_onchain: inactive_unconcluded_known_onchain, + active_unknown_onchain, + active_unconcluded_onchain, + active_concluded_onchain, + inactive_concluded_onchain: inactive_concluded_known_onchain, + } = disputes; + + metrics + .partitioned_disputes + .with_label_values(&["inactive_unknown_onchain"]) + .inc_by(inactive_unknown_onchain.len().try_into().unwrap_or(0)); + metrics + .partitioned_disputes + .with_label_values(&["inactive_unconcluded_known_onchain"]) + .inc_by(inactive_unconcluded_known_onchain.len().try_into().unwrap_or(0)); + metrics + .partitioned_disputes + .with_label_values(&["active_unknown_onchain"]) + .inc_by(active_unknown_onchain.len().try_into().unwrap_or(0)); + metrics + .partitioned_disputes + .with_label_values(&["active_unconcluded_onchain"]) + .inc_by(active_unconcluded_onchain.len().try_into().unwrap_or(0)); + metrics + .partitioned_disputes + .with_label_values(&["active_concluded_onchain"]) + .inc_by(active_concluded_onchain.len().try_into().unwrap_or(0)); + metrics + .partitioned_disputes + .with_label_values(&["inactive_concluded_known_onchain"]) + .inc_by(inactive_concluded_known_onchain.len().try_into().unwrap_or(0)); + } + } + + pub(crate) fn on_fetched_onchain_disputes(&self, onchain_count: u64) { + if let Some(metrics) = &self.0 { + metrics.fetched_onchain_disputes.inc_by(onchain_count); + } + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + inherent_data_requests: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_inherent_data_requests_total", + "Number of InherentData requests served by provisioner.", + ), + &["success"], + )?, + registry, + )?, + request_inherent_data_duration: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_provisioner_request_inherent_data_time", + "Time spent within `provisioner::request_inherent_data`", + ))?, + registry, + )?, + provisionable_data_duration: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_provisioner_provisionable_data_time", + "Time spent within `provisioner::provisionable_data`", + ))?, + registry, + )?, + inherent_data_dispute_statements: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_inherent_data_dispute_statements", + "Number of dispute statements passed to `create_inherent()`.", + ), + &["validity"], + )?, + ®istry, + )?, + inherent_data_dispute_statement_sets: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_inherent_data_dispute_statement_sets", + "Number of dispute statements sets passed to `create_inherent()`.", + )?, + registry, + )?, + inherent_data_response_bitfields: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_provisioner_inherent_data_response_bitfields_sent", + "Number of inherent bitfields sent in response to `ProvisionerMessage::RequestInherentData`.", + ).buckets(vec![0.0, 25.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 400.0, 500.0, 600.0]), + )?, + registry, + )?, + partitioned_disputes: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_provisioner_partitioned_disputes", + "Number of disputes partitioned by type.", + ), + &["partition"], + )?, + ®istry, + )?, + fetched_onchain_disputes: prometheus::register( + prometheus::Counter::new("polkadot_parachain_fetched_onchain_disputes", "Number of disputes fetched from the runtime" + )?, + ®istry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/core/provisioner/src/tests.rs b/polkadot/node/core/provisioner/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..1d7bdfcfcb89c251cfdeb9c6669a5b07e8b05985 --- /dev/null +++ b/polkadot/node/core/provisioner/src/tests.rs @@ -0,0 +1,703 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use ::test_helpers::{dummy_candidate_descriptor, dummy_hash}; +use bitvec::bitvec; +use polkadot_primitives::{OccupiedCore, ScheduledCore}; + +const MOCK_GROUP_SIZE: usize = 5; + +pub fn occupied_core(para_id: u32) -> CoreState { + CoreState::Occupied(OccupiedCore { + group_responsible: para_id.into(), + next_up_on_available: None, + occupied_since: 100_u32, + time_out_at: 200_u32, + next_up_on_time_out: None, + availability: bitvec![u8, bitvec::order::Lsb0; 0; 32], + candidate_descriptor: dummy_candidate_descriptor(dummy_hash()), + candidate_hash: Default::default(), + }) +} + +pub fn build_occupied_core(para_id: u32, builder: Builder) -> CoreState +where + Builder: FnOnce(&mut OccupiedCore), +{ + let mut core = match occupied_core(para_id) { + CoreState::Occupied(core) => core, + _ => unreachable!(), + }; + + builder(&mut core); + + CoreState::Occupied(core) +} + +pub fn default_bitvec(size: usize) -> CoreAvailability { + bitvec![u8, bitvec::order::Lsb0; 0; size] +} + +pub fn scheduled_core(id: u32) -> ScheduledCore { + ScheduledCore { para_id: id.into(), collator: None } +} + +mod select_availability_bitfields { + use super::{super::*, default_bitvec, occupied_core}; + use polkadot_primitives::{ScheduledCore, SigningContext, ValidatorId, ValidatorIndex}; + use sp_application_crypto::AppCrypto; + use sp_keystore::{testing::MemoryKeystore, Keystore, KeystorePtr}; + use std::sync::Arc; + + fn signed_bitfield( + keystore: &KeystorePtr, + field: CoreAvailability, + validator_idx: ValidatorIndex, + ) -> SignedAvailabilityBitfield { + let public = Keystore::sr25519_generate_new(&**keystore, ValidatorId::ID, None) + .expect("generated sr25519 key"); + SignedAvailabilityBitfield::sign( + &keystore, + field.into(), + &>::default(), + validator_idx, + &public.into(), + ) + .ok() + .flatten() + .expect("Should be signed") + } + + #[test] + fn not_more_than_one_per_validator() { + let keystore: KeystorePtr = Arc::new(MemoryKeystore::new()); + let mut bitvec = default_bitvec(2); + bitvec.set(0, true); + bitvec.set(1, true); + + let cores = vec![occupied_core(0), occupied_core(1)]; + + // we pass in three bitfields with two validators + // this helps us check the postcondition that we get two bitfields back, for which the + // validators differ + let bitfields = vec![ + signed_bitfield(&keystore, bitvec.clone(), ValidatorIndex(0)), + signed_bitfield(&keystore, bitvec.clone(), ValidatorIndex(1)), + signed_bitfield(&keystore, bitvec, ValidatorIndex(1)), + ]; + + let mut selected_bitfields = + select_availability_bitfields(&cores, &bitfields, &Hash::repeat_byte(0)); + selected_bitfields.sort_by_key(|bitfield| bitfield.validator_index()); + + assert_eq!(selected_bitfields.len(), 2); + assert_eq!(selected_bitfields[0], bitfields[0]); + // we don't know which of the (otherwise equal) bitfields will be selected + assert!(selected_bitfields[1] == bitfields[1] || selected_bitfields[1] == bitfields[2]); + } + + #[test] + fn each_corresponds_to_an_occupied_core() { + let keystore: KeystorePtr = Arc::new(MemoryKeystore::new()); + let bitvec = default_bitvec(3); + + // invalid: bit on free core + let mut bitvec0 = bitvec.clone(); + bitvec0.set(0, true); + + // invalid: bit on scheduled core + let mut bitvec1 = bitvec.clone(); + bitvec1.set(1, true); + + // valid: bit on occupied core. + let mut bitvec2 = bitvec.clone(); + bitvec2.set(2, true); + + let cores = vec![ + CoreState::Free, + CoreState::Scheduled(ScheduledCore { para_id: Default::default(), collator: None }), + occupied_core(2), + ]; + + let bitfields = vec![ + signed_bitfield(&keystore, bitvec0, ValidatorIndex(0)), + signed_bitfield(&keystore, bitvec1, ValidatorIndex(1)), + signed_bitfield(&keystore, bitvec2.clone(), ValidatorIndex(2)), + ]; + + let selected_bitfields = + select_availability_bitfields(&cores, &bitfields, &Hash::repeat_byte(0)); + + // selects only the valid bitfield + assert_eq!(selected_bitfields.len(), 1); + assert_eq!(selected_bitfields[0].payload().0, bitvec2); + } + + #[test] + fn more_set_bits_win_conflicts() { + let keystore: KeystorePtr = Arc::new(MemoryKeystore::new()); + let mut bitvec = default_bitvec(2); + bitvec.set(0, true); + + let mut bitvec1 = bitvec.clone(); + bitvec1.set(1, true); + + let cores = vec![occupied_core(0), occupied_core(1)]; + + let bitfields = vec![ + signed_bitfield(&keystore, bitvec, ValidatorIndex(1)), + signed_bitfield(&keystore, bitvec1.clone(), ValidatorIndex(1)), + ]; + + let selected_bitfields = + select_availability_bitfields(&cores, &bitfields, &Hash::repeat_byte(0)); + assert_eq!(selected_bitfields.len(), 1); + assert_eq!(selected_bitfields[0].payload().0, bitvec1.clone()); + } + + #[test] + fn more_complex_bitfields() { + let keystore: KeystorePtr = Arc::new(MemoryKeystore::new()); + + let cores = vec![occupied_core(0), occupied_core(1), occupied_core(2), occupied_core(3)]; + + let mut bitvec0 = default_bitvec(4); + bitvec0.set(0, true); + bitvec0.set(2, true); + + let mut bitvec1 = default_bitvec(4); + bitvec1.set(1, true); + + let mut bitvec2 = default_bitvec(4); + bitvec2.set(2, true); + + let mut bitvec3 = default_bitvec(4); + bitvec3.set(0, true); + bitvec3.set(1, true); + bitvec3.set(2, true); + bitvec3.set(3, true); + + // these are out of order but will be selected in order. The better + // bitfield for 3 will be selected. + let bitfields = vec![ + signed_bitfield(&keystore, bitvec2.clone(), ValidatorIndex(3)), + signed_bitfield(&keystore, bitvec3.clone(), ValidatorIndex(3)), + signed_bitfield(&keystore, bitvec0.clone(), ValidatorIndex(0)), + signed_bitfield(&keystore, bitvec2.clone(), ValidatorIndex(2)), + signed_bitfield(&keystore, bitvec1.clone(), ValidatorIndex(1)), + ]; + + let selected_bitfields = + select_availability_bitfields(&cores, &bitfields, &Hash::repeat_byte(0)); + assert_eq!(selected_bitfields.len(), 4); + assert_eq!(selected_bitfields[0].payload().0, bitvec0); + assert_eq!(selected_bitfields[1].payload().0, bitvec1); + assert_eq!(selected_bitfields[2].payload().0, bitvec2); + assert_eq!(selected_bitfields[3].payload().0, bitvec3); + } +} + +pub(crate) mod common { + use super::super::*; + use futures::channel::mpsc; + use polkadot_node_subsystem::messages::AllMessages; + use polkadot_node_subsystem_test_helpers::TestSubsystemSender; + + pub fn test_harness( + overseer_factory: OverseerFactory, + test_factory: TestFactory, + ) where + OverseerFactory: FnOnce(mpsc::UnboundedReceiver) -> Overseer, + Overseer: Future, + TestFactory: FnOnce(TestSubsystemSender) -> Test, + Test: Future, + { + let (tx, rx) = polkadot_node_subsystem_test_helpers::sender_receiver(); + let overseer = overseer_factory(rx); + let test = test_factory(tx); + + futures::pin_mut!(overseer, test); + + let _ = futures::executor::block_on(future::join(overseer, test)); + } +} + +mod select_candidates { + use super::{ + super::*, build_occupied_core, common::test_harness, default_bitvec, occupied_core, + scheduled_core, MOCK_GROUP_SIZE, + }; + use ::test_helpers::{dummy_candidate_descriptor, dummy_hash}; + use futures::channel::mpsc; + use polkadot_node_subsystem::messages::{ + AllMessages, RuntimeApiMessage, + RuntimeApiRequest::{ + AvailabilityCores, PersistedValidationData as PersistedValidationDataReq, + }, + }; + use polkadot_node_subsystem_test_helpers::TestSubsystemSender; + use polkadot_node_subsystem_util::runtime::ProspectiveParachainsMode; + use polkadot_primitives::{ + BlockNumber, CandidateCommitments, CommittedCandidateReceipt, PersistedValidationData, + }; + + const BLOCK_UNDER_PRODUCTION: BlockNumber = 128; + + // For test purposes, we always return this set of availability cores: + // + // [ + // 0: Free, + // 1: Scheduled(default), + // 2: Occupied(no next_up set), + // 3: Occupied(next_up_on_available set but not available), + // 4: Occupied(next_up_on_available set and available), + // 5: Occupied(next_up_on_time_out set but not timeout), + // 6: Occupied(next_up_on_time_out set and timeout but available), + // 7: Occupied(next_up_on_time_out set and timeout and not available), + // 8: Occupied(both next_up set, available), + // 9: Occupied(both next_up set, not available, no timeout), + // 10: Occupied(both next_up set, not available, timeout), + // 11: Occupied(next_up_on_available and available, but different successor para_id) + // ] + fn mock_availability_cores() -> Vec { + use std::ops::Not; + use CoreState::{Free, Scheduled}; + + vec![ + // 0: Free, + Free, + // 1: Scheduled(default), + Scheduled(scheduled_core(1)), + // 2: Occupied(no next_up set), + occupied_core(2), + // 3: Occupied(next_up_on_available set but not available), + build_occupied_core(3, |core| { + core.next_up_on_available = Some(scheduled_core(3)); + }), + // 4: Occupied(next_up_on_available set and available), + build_occupied_core(4, |core| { + core.next_up_on_available = Some(scheduled_core(4)); + core.availability = core.availability.clone().not(); + }), + // 5: Occupied(next_up_on_time_out set but not timeout), + build_occupied_core(5, |core| { + core.next_up_on_time_out = Some(scheduled_core(5)); + }), + // 6: Occupied(next_up_on_time_out set and timeout but available), + build_occupied_core(6, |core| { + core.next_up_on_time_out = Some(scheduled_core(6)); + core.time_out_at = BLOCK_UNDER_PRODUCTION; + core.availability = core.availability.clone().not(); + }), + // 7: Occupied(next_up_on_time_out set and timeout and not available), + build_occupied_core(7, |core| { + core.next_up_on_time_out = Some(scheduled_core(7)); + core.time_out_at = BLOCK_UNDER_PRODUCTION; + }), + // 8: Occupied(both next_up set, available), + build_occupied_core(8, |core| { + core.next_up_on_available = Some(scheduled_core(8)); + core.next_up_on_time_out = Some(scheduled_core(8)); + core.availability = core.availability.clone().not(); + }), + // 9: Occupied(both next_up set, not available, no timeout), + build_occupied_core(9, |core| { + core.next_up_on_available = Some(scheduled_core(9)); + core.next_up_on_time_out = Some(scheduled_core(9)); + }), + // 10: Occupied(both next_up set, not available, timeout), + build_occupied_core(10, |core| { + core.next_up_on_available = Some(scheduled_core(10)); + core.next_up_on_time_out = Some(scheduled_core(10)); + core.time_out_at = BLOCK_UNDER_PRODUCTION; + }), + // 11: Occupied(next_up_on_available and available, but different successor para_id) + build_occupied_core(11, |core| { + core.next_up_on_available = Some(scheduled_core(12)); + core.availability = core.availability.clone().not(); + }), + ] + } + + async fn mock_overseer( + mut receiver: mpsc::UnboundedReceiver, + expected: Vec, + prospective_parachains_mode: ProspectiveParachainsMode, + ) { + use ChainApiMessage::BlockNumber; + use RuntimeApiMessage::Request; + + let mut candidates_iter = expected + .iter() + .map(|candidate| (candidate.hash(), candidate.descriptor().relay_parent)); + + let mut backed_iter = expected.clone().into_iter(); + + while let Some(from_job) = receiver.next().await { + match from_job { + AllMessages::ChainApi(BlockNumber(_relay_parent, tx)) => + tx.send(Ok(Some(BLOCK_UNDER_PRODUCTION - 1))).unwrap(), + AllMessages::RuntimeApi(Request( + _parent_hash, + PersistedValidationDataReq(_para_id, _assumption, tx), + )) => tx.send(Ok(Some(Default::default()))).unwrap(), + AllMessages::RuntimeApi(Request(_parent_hash, AvailabilityCores(tx))) => + tx.send(Ok(mock_availability_cores())).unwrap(), + AllMessages::CandidateBacking(CandidateBackingMessage::GetBackedCandidates( + hashes, + sender, + )) => { + let response: Vec = + backed_iter.by_ref().take(hashes.len()).collect(); + let expected_hashes: Vec<(CandidateHash, Hash)> = response + .iter() + .map(|candidate| (candidate.hash(), candidate.descriptor().relay_parent)) + .collect(); + + assert_eq!(expected_hashes, hashes); + + let _ = sender.send(response); + }, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetBackableCandidate(.., tx), + ) => match prospective_parachains_mode { + ProspectiveParachainsMode::Enabled { .. } => { + let _ = tx.send(candidates_iter.next()); + }, + ProspectiveParachainsMode::Disabled => + panic!("unexpected prospective parachains request"), + }, + _ => panic!("Unexpected message: {:?}", from_job), + } + } + } + + #[test] + fn can_succeed() { + test_harness( + |r| mock_overseer(r, Vec::new(), ProspectiveParachainsMode::Disabled), + |mut tx: TestSubsystemSender| async move { + let prospective_parachains_mode = ProspectiveParachainsMode::Disabled; + select_candidates( + &[], + &[], + &[], + prospective_parachains_mode, + Default::default(), + &mut tx, + ) + .await + .unwrap(); + }, + ) + } + + // this tests that only the appropriate candidates get selected. + // To accomplish this, we supply a candidate list containing one candidate per possible core; + // the candidate selection algorithm must filter them to the appropriate set + #[test] + fn selects_correct_candidates() { + let mock_cores = mock_availability_cores(); + + let empty_hash = PersistedValidationData::::default().hash(); + + let mut descriptor_template = dummy_candidate_descriptor(dummy_hash()); + descriptor_template.persisted_validation_data_hash = empty_hash; + let candidate_template = CandidateReceipt { + descriptor: descriptor_template, + commitments_hash: CandidateCommitments::default().hash(), + }; + + let candidates: Vec<_> = std::iter::repeat(candidate_template) + .take(mock_cores.len()) + .enumerate() + .map(|(idx, mut candidate)| { + candidate.descriptor.para_id = idx.into(); + candidate + }) + .cycle() + .take(mock_cores.len() * 3) + .enumerate() + .map(|(idx, mut candidate)| { + if idx < mock_cores.len() { + // first go-around: use candidates which should work + candidate + } else if idx < mock_cores.len() * 2 { + // for the second repetition of the candidates, give them the wrong hash + candidate.descriptor.persisted_validation_data_hash = Default::default(); + candidate + } else { + // third go-around: right hash, wrong para_id + candidate.descriptor.para_id = idx.into(); + candidate + } + }) + .collect(); + + // why those particular indices? see the comments on mock_availability_cores() + let expected_candidates: Vec<_> = + [1, 4, 7, 8, 10].iter().map(|&idx| candidates[idx].clone()).collect(); + let prospective_parachains_mode = ProspectiveParachainsMode::Disabled; + + let expected_backed = expected_candidates + .iter() + .map(|c| BackedCandidate { + candidate: CommittedCandidateReceipt { + descriptor: c.descriptor.clone(), + commitments: Default::default(), + }, + validity_votes: Vec::new(), + validator_indices: default_bitvec(MOCK_GROUP_SIZE), + }) + .collect(); + + test_harness( + |r| mock_overseer(r, expected_backed, prospective_parachains_mode), + |mut tx: TestSubsystemSender| async move { + let result = select_candidates( + &mock_cores, + &[], + &candidates, + prospective_parachains_mode, + Default::default(), + &mut tx, + ) + .await + .unwrap(); + + result.into_iter().for_each(|c| { + assert!( + expected_candidates.iter().any(|c2| c.candidate.corresponds_to(c2)), + "Failed to find candidate: {:?}", + c, + ) + }); + }, + ) + } + + #[test] + fn selects_max_one_code_upgrade() { + let mock_cores = mock_availability_cores(); + + let empty_hash = PersistedValidationData::::default().hash(); + + // why those particular indices? see the comments on mock_availability_cores() + // the first candidate with code is included out of [1, 4, 7, 8, 10]. + let cores = [1, 4, 7, 8, 10]; + let cores_with_code = [1, 4, 8]; + + let expected_cores = [1, 7, 10]; + + let committed_receipts: Vec<_> = (0..mock_cores.len()) + .map(|i| { + let mut descriptor = dummy_candidate_descriptor(dummy_hash()); + descriptor.para_id = i.into(); + descriptor.persisted_validation_data_hash = empty_hash; + CommittedCandidateReceipt { + descriptor, + commitments: CandidateCommitments { + new_validation_code: if cores_with_code.contains(&i) { + Some(vec![].into()) + } else { + None + }, + ..Default::default() + }, + } + }) + .collect(); + + // Input to select_candidates + let candidates: Vec<_> = committed_receipts.iter().map(|r| r.to_plain()).collect(); + // Build possible outputs from select_candidates + let backed_candidates: Vec<_> = committed_receipts + .iter() + .map(|committed_receipt| BackedCandidate { + candidate: committed_receipt.clone(), + validity_votes: Vec::new(), + validator_indices: default_bitvec(MOCK_GROUP_SIZE), + }) + .collect(); + + // First, provisioner will request backable candidates for each scheduled core. + // Then, some of them get filtered due to new validation code rule. + let expected_backed: Vec<_> = + cores.iter().map(|&idx| backed_candidates[idx].clone()).collect(); + let expected_backed_filtered: Vec<_> = + expected_cores.iter().map(|&idx| candidates[idx].clone()).collect(); + + let prospective_parachains_mode = ProspectiveParachainsMode::Disabled; + + test_harness( + |r| mock_overseer(r, expected_backed, prospective_parachains_mode), + |mut tx: TestSubsystemSender| async move { + let result = select_candidates( + &mock_cores, + &[], + &candidates, + prospective_parachains_mode, + Default::default(), + &mut tx, + ) + .await + .unwrap(); + + assert_eq!(result.len(), 3); + + result.into_iter().for_each(|c| { + assert!( + expected_backed_filtered.iter().any(|c2| c.candidate.corresponds_to(c2)), + "Failed to find candidate: {:?}", + c, + ) + }); + }, + ) + } + + #[test] + fn request_from_prospective_parachains() { + let mock_cores = mock_availability_cores(); + let empty_hash = PersistedValidationData::::default().hash(); + + let mut descriptor_template = dummy_candidate_descriptor(dummy_hash()); + descriptor_template.persisted_validation_data_hash = empty_hash; + let candidate_template = CandidateReceipt { + descriptor: descriptor_template, + commitments_hash: CandidateCommitments::default().hash(), + }; + + let candidates: Vec<_> = std::iter::repeat(candidate_template) + .take(mock_cores.len()) + .enumerate() + .map(|(idx, mut candidate)| { + candidate.descriptor.para_id = idx.into(); + candidate + }) + .collect(); + + // why those particular indices? see the comments on mock_availability_cores() + let expected_candidates: Vec<_> = + [1, 4, 7, 8, 10].iter().map(|&idx| candidates[idx].clone()).collect(); + // Expect prospective parachains subsystem requests. + let prospective_parachains_mode = + ProspectiveParachainsMode::Enabled { max_candidate_depth: 0, allowed_ancestry_len: 0 }; + + let expected_backed = expected_candidates + .iter() + .map(|c| BackedCandidate { + candidate: CommittedCandidateReceipt { + descriptor: c.descriptor.clone(), + commitments: Default::default(), + }, + validity_votes: Vec::new(), + validator_indices: default_bitvec(MOCK_GROUP_SIZE), + }) + .collect(); + + test_harness( + |r| mock_overseer(r, expected_backed, prospective_parachains_mode), + |mut tx: TestSubsystemSender| async move { + let result = select_candidates( + &mock_cores, + &[], + &[], + prospective_parachains_mode, + Default::default(), + &mut tx, + ) + .await + .unwrap(); + + result.into_iter().for_each(|c| { + assert!( + expected_candidates.iter().any(|c2| c.candidate.corresponds_to(c2)), + "Failed to find candidate: {:?}", + c, + ) + }); + }, + ) + } + + #[test] + fn request_receipts_based_on_relay_parent() { + let mock_cores = mock_availability_cores(); + let empty_hash = PersistedValidationData::::default().hash(); + + let mut descriptor_template = dummy_candidate_descriptor(dummy_hash()); + descriptor_template.persisted_validation_data_hash = empty_hash; + let candidate_template = CandidateReceipt { + descriptor: descriptor_template, + commitments_hash: CandidateCommitments::default().hash(), + }; + + let candidates: Vec<_> = std::iter::repeat(candidate_template) + .take(mock_cores.len()) + .enumerate() + .map(|(idx, mut candidate)| { + candidate.descriptor.para_id = idx.into(); + candidate.descriptor.relay_parent = Hash::repeat_byte(idx as u8); + candidate + }) + .collect(); + + // why those particular indices? see the comments on mock_availability_cores() + let expected_candidates: Vec<_> = + [1, 4, 7, 8, 10].iter().map(|&idx| candidates[idx].clone()).collect(); + // Expect prospective parachains subsystem requests. + let prospective_parachains_mode = + ProspectiveParachainsMode::Enabled { max_candidate_depth: 0, allowed_ancestry_len: 0 }; + + let expected_backed = expected_candidates + .iter() + .map(|c| BackedCandidate { + candidate: CommittedCandidateReceipt { + descriptor: c.descriptor.clone(), + commitments: Default::default(), + }, + validity_votes: Vec::new(), + validator_indices: default_bitvec(MOCK_GROUP_SIZE), + }) + .collect(); + + test_harness( + |r| mock_overseer(r, expected_backed, prospective_parachains_mode), + |mut tx: TestSubsystemSender| async move { + let result = select_candidates( + &mock_cores, + &[], + &[], + prospective_parachains_mode, + Default::default(), + &mut tx, + ) + .await + .unwrap(); + + result.into_iter().for_each(|c| { + assert!( + expected_candidates.iter().any(|c2| c.candidate.corresponds_to(c2)), + "Failed to find candidate: {:?}", + c, + ) + }); + }, + ) + } +} diff --git a/polkadot/node/core/pvf-checker/Cargo.toml b/polkadot/node/core/pvf-checker/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..2b6b53be407240b13d3de1c9145607e69d76b421 --- /dev/null +++ b/polkadot/node/core/pvf-checker/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "polkadot-node-core-pvf-checker" +description = "Polkadot crate that implements the PVF pre-checking subsystem. Responsible for checking and voting for PVFs that are pending approval." +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +thiserror = "1.0.31" +gum = { package = "tracing-gum", path = "../../gum" } + +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-overseer = { path = "../../overseer" } + +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[dev-dependencies] +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers"} +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../../primitives/test-helpers" } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures-timer = "3.0.2" diff --git a/polkadot/node/core/pvf-checker/src/interest_view.rs b/polkadot/node/core/pvf-checker/src/interest_view.rs new file mode 100644 index 0000000000000000000000000000000000000000..05a6f12de5d8fbe2a0f1529af1dbbb742ecca8c9 --- /dev/null +++ b/polkadot/node/core/pvf-checker/src/interest_view.rs @@ -0,0 +1,156 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_primitives::{Hash, ValidationCodeHash}; +use std::collections::{ + btree_map::{self, BTreeMap}, + HashSet, +}; + +/// Whether the PVF passed pre-checking or not. +#[derive(Copy, Clone, Debug)] +pub enum Judgement { + Valid, + Invalid, +} + +impl Judgement { + /// Whether the PVF is valid or not. + pub fn is_valid(&self) -> bool { + match self { + Judgement::Valid => true, + Judgement::Invalid => false, + } + } +} + +/// Data about a particular validation code. +#[derive(Default, Debug)] +struct PvfData { + /// If `Some` then the PVF pre-checking was run for this PVF. If `None` we are either waiting + /// for the judgement to come in or the PVF pre-checking failed. + judgement: Option, + + /// The set of block hashes where this PVF was seen. + seen_in: HashSet, +} + +impl PvfData { + /// Initialize a new `PvfData` which is awaiting for the initial judgement. + fn pending(origin: Hash) -> Self { + // Preallocate the hashset with 5 items. This is the anticipated maximum leaves we can + // deal at the same time. In the vast majority of the cases it will have length of 1. + let mut seen_in = HashSet::with_capacity(5); + seen_in.insert(origin); + Self { judgement: None, seen_in } + } + + /// Mark a the `PvfData` as seen in the provided relay-chain block referenced by `relay_hash`. + pub fn seen_in(&mut self, relay_hash: Hash) { + self.seen_in.insert(relay_hash); + } + + /// Removes the given `relay_hash` from the set of seen in, and returns if the set is now empty. + pub fn remove_origin(&mut self, relay_hash: &Hash) -> bool { + self.seen_in.remove(relay_hash); + self.seen_in.is_empty() + } +} + +/// The result of [`InterestView::on_leaves_update`]. +pub struct OnLeavesUpdateOutcome { + /// The list of PVFs that we first seen in the activated block. + pub newcomers: Vec, + /// The number of PVFs that were removed from the view. + pub left_num: usize, +} + +/// A structure that keeps track of relevant PVFs and judgements about them. A relevant PVF is one +/// that resides in at least a single active leaf. +#[derive(Debug)] +pub struct InterestView { + active_leaves: BTreeMap>, + pvfs: BTreeMap, +} + +impl InterestView { + pub fn new() -> Self { + Self { active_leaves: BTreeMap::new(), pvfs: BTreeMap::new() } + } + + pub fn on_leaves_update( + &mut self, + activated: Option<(Hash, Vec)>, + deactivated: &[Hash], + ) -> OnLeavesUpdateOutcome { + let mut newcomers = Vec::new(); + + if let Some((leaf, pending_pvfs)) = activated { + for pvf in &pending_pvfs { + match self.pvfs.entry(*pvf) { + btree_map::Entry::Vacant(v) => { + v.insert(PvfData::pending(leaf)); + newcomers.push(*pvf); + }, + btree_map::Entry::Occupied(mut o) => { + o.get_mut().seen_in(leaf); + }, + } + } + self.active_leaves.entry(leaf).or_default().extend(pending_pvfs); + } + + let mut left_num = 0; + for leaf in deactivated { + let pvfs = self.active_leaves.remove(leaf); + for pvf in pvfs.into_iter().flatten() { + if let btree_map::Entry::Occupied(mut o) = self.pvfs.entry(pvf) { + let now_empty = o.get_mut().remove_origin(leaf); + if now_empty { + left_num += 1; + o.remove(); + } + } + } + } + + OnLeavesUpdateOutcome { newcomers, left_num } + } + + /// Handles a new judgement for the given `pvf`. + /// + /// Returns `Err` if the given PVF hash is not known. + pub fn on_judgement( + &mut self, + subject: ValidationCodeHash, + judgement: Judgement, + ) -> Result<(), ()> { + match self.pvfs.get_mut(&subject) { + Some(data) => { + data.judgement = Some(judgement); + Ok(()) + }, + None => Err(()), + } + } + + /// Returns all PVFs that previously received a judgement. + pub fn judgements(&self) -> impl Iterator + '_ { + self.pvfs + .iter() + .filter_map(|(code_hash, data)| data.judgement.map(|judgement| (*code_hash, judgement))) + } +} diff --git a/polkadot/node/core/pvf-checker/src/lib.rs b/polkadot/node/core/pvf-checker/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..2946f3f78861cccdbac8f94a97a4693fce37a09f --- /dev/null +++ b/polkadot/node/core/pvf-checker/src/lib.rs @@ -0,0 +1,560 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implements the PVF pre-checking subsystem. +//! +//! This subsystem is responsible for scanning the chain for PVFs that are pending for the approval +//! as well as submitting statements regarding them passing or not the PVF pre-checking. + +use futures::{channel::oneshot, future::BoxFuture, prelude::*, stream::FuturesUnordered}; + +use polkadot_node_subsystem::{ + messages::{CandidateValidationMessage, PreCheckOutcome, PvfCheckerMessage, RuntimeApiMessage}, + overseer, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, + SubsystemResult, SubsystemSender, +}; +use polkadot_primitives::{ + BlockNumber, Hash, PvfCheckStatement, SessionIndex, ValidationCodeHash, ValidatorId, + ValidatorIndex, +}; +use sp_keystore::KeystorePtr; +use std::collections::HashSet; + +const LOG_TARGET: &str = "parachain::pvf-checker"; + +mod interest_view; +mod metrics; +mod runtime_api; + +#[cfg(test)] +mod tests; + +use self::{ + interest_view::{InterestView, Judgement}, + metrics::Metrics, +}; + +/// PVF pre-checking subsystem. +pub struct PvfCheckerSubsystem { + enabled: bool, + keystore: KeystorePtr, + metrics: Metrics, +} + +impl PvfCheckerSubsystem { + pub fn new(enabled: bool, keystore: KeystorePtr, metrics: Metrics) -> Self { + PvfCheckerSubsystem { enabled, keystore, metrics } + } +} + +#[overseer::subsystem(PvfChecker, error=SubsystemError, prefix = self::overseer)] +impl PvfCheckerSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + if self.enabled { + let future = run(ctx, self.keystore, self.metrics) + .map_err(|e| SubsystemError::with_origin("pvf-checker", e)) + .boxed(); + + SpawnedSubsystem { name: "pvf-checker-subsystem", future } + } else { + polkadot_overseer::DummySubsystem.start(ctx) + } + } +} + +/// A struct that holds the credentials required to sign the PVF check statements. These credentials +/// are implicitly to pinned to a session where our node acts as a validator. +struct SigningCredentials { + /// The validator public key. + validator_key: ValidatorId, + /// The validator index in the current session. + validator_index: ValidatorIndex, +} + +struct State { + /// If `Some` then our node is in the active validator set during the current session. + /// + /// Updated when a new session index is detected in one of the heads. + credentials: Option, + + /// The number and the hash of the most recent block that we have seen. + /// + /// This is only updated when the PVF pre-checking API is detected in a new leaf block. + recent_block: Option<(BlockNumber, Hash)>, + + /// The session index of the most recent session that we have seen. + /// + /// This is only updated when the PVF pre-checking API is detected in a new leaf block. + latest_session: Option, + + /// The set of PVF hashes that we cast a vote for within the current session. + voted: HashSet, + + /// The collection of PVFs that are observed throughout the active heads. + view: InterestView, + + /// The container for the futures that are waiting for the outcome of the pre-checking. + /// + /// Here are some fun facts about these futures: + /// + /// - Pre-checking can take quite some time, in the matter of tens of seconds, so the futures + /// here can soak for quite some time. + /// - Pre-checking of one PVF can take drastically more time than pre-checking of another PVF. + /// This leads to results coming out of order. + /// + /// Resolving to `None` means that the request was dropped before replying. + currently_checking: + FuturesUnordered>>, +} + +#[overseer::contextbounds(PvfChecker, prefix = self::overseer)] +async fn run( + mut ctx: Context, + keystore: KeystorePtr, + metrics: Metrics, +) -> SubsystemResult<()> { + let mut state = State { + credentials: None, + recent_block: None, + latest_session: None, + voted: HashSet::with_capacity(16), + view: InterestView::new(), + currently_checking: FuturesUnordered::new(), + }; + + loop { + let mut sender = ctx.sender().clone(); + futures::select! { + precheck_response = state.currently_checking.select_next_some() => { + if let Some((outcome, validation_code_hash)) = precheck_response { + handle_pvf_check( + &mut state, + &mut sender, + &keystore, + &metrics, + outcome, + validation_code_hash, + ).await; + } else { + // See note in `initiate_precheck` for why this is possible and why we do not + // care here. + } + } + from_overseer = ctx.recv().fuse() => { + let outcome = handle_from_overseer( + &mut state, + &mut sender, + &keystore, + &metrics, + from_overseer?, + ) + .await; + if let Some(Conclude) = outcome { + return Ok(()); + } + } + } + } +} + +/// Handle an incoming PVF pre-check result from the candidate-validation subsystem. +async fn handle_pvf_check( + state: &mut State, + sender: &mut impl overseer::PvfCheckerSenderTrait, + keystore: &KeystorePtr, + metrics: &Metrics, + outcome: PreCheckOutcome, + validation_code_hash: ValidationCodeHash, +) { + gum::debug!( + target: LOG_TARGET, + ?validation_code_hash, + "Received pre-check result: {:?}", + outcome, + ); + + let judgement = match outcome { + PreCheckOutcome::Valid => Judgement::Valid, + PreCheckOutcome::Invalid => Judgement::Invalid, + PreCheckOutcome::Failed => { + // Always vote against in case of failures. Voting against a PVF when encountering a + // timeout (or an unlikely node-specific issue) can be considered safe, since + // there is no slashing for being on the wrong side on a pre-check vote. + // + // Also, by being more strict here, we can safely be more lenient during preparation and + // avoid the risk of getting slashed there. + gum::info!( + target: LOG_TARGET, + ?validation_code_hash, + "Pre-check failed, voting against", + ); + Judgement::Invalid + }, + }; + + match state.view.on_judgement(validation_code_hash, judgement) { + Ok(()) => (), + Err(()) => { + gum::debug!( + target: LOG_TARGET, + ?validation_code_hash, + "received judgement for an unknown (or removed) PVF hash", + ); + return + }, + } + + match (state.credentials.as_ref(), state.recent_block, state.latest_session) { + // Note, the availability of credentials implies the availability of the recent block and + // the session index. + (Some(credentials), Some(recent_block), Some(session_index)) => { + sign_and_submit_pvf_check_statement( + sender, + keystore, + &mut state.voted, + credentials, + metrics, + recent_block.1, + session_index, + judgement, + validation_code_hash, + ) + .await; + }, + _ => (), + } +} + +/// A marker for the outer loop that the subsystem should stop. +struct Conclude; + +async fn handle_from_overseer( + state: &mut State, + sender: &mut impl overseer::PvfCheckerSenderTrait, + keystore: &KeystorePtr, + metrics: &Metrics, + from_overseer: FromOrchestra, +) -> Option { + match from_overseer { + FromOrchestra::Signal(OverseerSignal::Conclude) => { + gum::info!(target: LOG_TARGET, "Received `Conclude` signal, exiting"); + Some(Conclude) + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(_, _)) => { + // ignore + None + }, + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => { + handle_leaves_update(state, sender, keystore, metrics, update).await; + None + }, + FromOrchestra::Communication { msg } => match msg { + // uninhabited type, thus statically unreachable. + }, + } +} + +async fn handle_leaves_update( + state: &mut State, + sender: &mut impl overseer::PvfCheckerSenderTrait, + keystore: &KeystorePtr, + metrics: &Metrics, + update: ActiveLeavesUpdate, +) { + if let Some(activated) = update.activated { + let ActivationEffect { new_session_index, recent_block, pending_pvfs } = + match examine_activation(state, sender, keystore, activated.hash, activated.number) + .await + { + None => { + // None indicates that the pre-checking runtime API is not supported. + return + }, + Some(e) => e, + }; + + // Note that this is not necessarily the newly activated leaf. + let recent_block_hash = recent_block.1; + state.recent_block = Some(recent_block); + + // Update the PVF view and get the previously unseen PVFs and start working on them. + let outcome = state + .view + .on_leaves_update(Some((activated.hash, pending_pvfs)), &update.deactivated); + metrics.on_pvf_observed(outcome.newcomers.len()); + metrics.on_pvf_left(outcome.left_num); + for newcomer in outcome.newcomers { + initiate_precheck(state, sender, activated.hash, newcomer, metrics).await; + } + + if let Some((new_session_index, credentials)) = new_session_index { + // New session change: + // - update the session index + // - reset the set of all PVFs we voted. + // - set (or reset) the credentials. + state.latest_session = Some(new_session_index); + state.voted.clear(); + state.credentials = credentials; + + // If our node is a validator in the new session, we need to re-sign and submit all + // previously obtained judgements. + if let Some(ref credentials) = state.credentials { + for (code_hash, judgement) in state.view.judgements() { + sign_and_submit_pvf_check_statement( + sender, + keystore, + &mut state.voted, + credentials, + metrics, + recent_block_hash, + new_session_index, + judgement, + code_hash, + ) + .await; + } + } + } + } else { + state.view.on_leaves_update(None, &update.deactivated); + } +} + +struct ActivationEffect { + /// If the activated leaf is in a new session, the index of the new session. If the new session + /// has a validator in the set our node happened to have private key for, the signing + new_session_index: Option<(SessionIndex, Option)>, + /// This is the block hash and number of the newly activated block if it's "better" than the + /// last one we've seen. The block is better if it's number is higher or if there are no blocks + /// observed whatsoever. If the leaf is not better then this holds the existing recent block. + recent_block: (BlockNumber, Hash), + /// The full list of PVFs that are pending pre-checking according to the runtime API. In case + /// the API returned an error this list is empty. + pending_pvfs: Vec, +} + +/// Examines the new leaf and returns the effects of the examination. +/// +/// Returns `None` if the PVF pre-checking runtime API is not supported for the given leaf hash. +async fn examine_activation( + state: &mut State, + sender: &mut impl overseer::PvfCheckerSenderTrait, + keystore: &KeystorePtr, + leaf_hash: Hash, + leaf_number: BlockNumber, +) -> Option { + gum::debug!( + target: LOG_TARGET, + "Examining activation of leaf {:?} ({})", + leaf_hash, + leaf_number, + ); + + let pending_pvfs = match runtime_api::pvfs_require_precheck(sender, leaf_hash).await { + Err(runtime_api::RuntimeRequestError::NotSupported) => return None, + Err(_) => { + gum::debug!( + target: LOG_TARGET, + relay_parent = ?leaf_hash, + "cannot fetch PVFs that require pre-checking from runtime API", + ); + Vec::new() + }, + Ok(v) => v, + }; + + let recent_block = match state.recent_block { + Some((recent_block_num, recent_block_hash)) if leaf_number < recent_block_num => { + // the existing recent block is not worse than the new activation, so leave it. + (recent_block_num, recent_block_hash) + }, + _ => (leaf_number, leaf_hash), + }; + + let new_session_index = match runtime_api::session_index_for_child(sender, leaf_hash).await { + Ok(session_index) => + if state.latest_session.map_or(true, |l| l < session_index) { + let signing_credentials = + check_signing_credentials(sender, keystore, leaf_hash).await; + Some((session_index, signing_credentials)) + } else { + None + }, + Err(e) => { + gum::warn!( + target: LOG_TARGET, + relay_parent = ?leaf_hash, + "cannot fetch session index from runtime API: {:?}", + e, + ); + None + }, + }; + + Some(ActivationEffect { new_session_index, recent_block, pending_pvfs }) +} + +/// Checks the active validators for the given leaf. If we have a signing key for one of them, +/// returns the [`SigningCredentials`]. +async fn check_signing_credentials( + sender: &mut impl SubsystemSender, + keystore: &KeystorePtr, + leaf: Hash, +) -> Option { + let validators = match runtime_api::validators(sender, leaf).await { + Ok(v) => v, + Err(e) => { + gum::warn!( + target: LOG_TARGET, + relay_parent = ?leaf, + "error occured during requesting validators: {:?}", + e + ); + return None + }, + }; + + polkadot_node_subsystem_util::signing_key_and_index(&validators, keystore).map( + |(validator_key, validator_index)| SigningCredentials { validator_key, validator_index }, + ) +} + +/// Signs and submits a vote for or against a given validation code. +/// +/// If the validator already voted for the given code, this function does nothing. +async fn sign_and_submit_pvf_check_statement( + sender: &mut impl overseer::PvfCheckerSenderTrait, + keystore: &KeystorePtr, + voted: &mut HashSet, + credentials: &SigningCredentials, + metrics: &Metrics, + relay_parent: Hash, + session_index: SessionIndex, + judgement: Judgement, + validation_code_hash: ValidationCodeHash, +) { + gum::debug!( + target: LOG_TARGET, + ?validation_code_hash, + ?relay_parent, + "submitting a PVF check statement for validation code = {:?}", + judgement, + ); + + metrics.on_vote_submission_started(); + + if voted.contains(&validation_code_hash) { + gum::trace!( + target: LOG_TARGET, + relay_parent = ?relay_parent, + ?validation_code_hash, + "already voted for this validation code", + ); + metrics.on_vote_duplicate(); + return + } + + voted.insert(validation_code_hash); + + let stmt = PvfCheckStatement { + accept: judgement.is_valid(), + session_index, + subject: validation_code_hash, + validator_index: credentials.validator_index, + }; + let signature = match polkadot_node_subsystem_util::sign( + keystore, + &credentials.validator_key, + &stmt.signing_payload(), + ) { + Ok(Some(signature)) => signature, + Ok(None) => { + gum::warn!( + target: LOG_TARGET, + ?relay_parent, + validator_index = ?credentials.validator_index, + ?validation_code_hash, + "private key for signing is not available", + ); + return + }, + Err(e) => { + gum::warn!( + target: LOG_TARGET, + ?relay_parent, + validator_index = ?credentials.validator_index, + ?validation_code_hash, + "error signing the statement: {:?}", + e, + ); + return + }, + }; + + match runtime_api::submit_pvf_check_statement(sender, relay_parent, stmt, signature).await { + Ok(()) => { + metrics.on_vote_submitted(); + }, + Err(e) => { + gum::warn!( + target: LOG_TARGET, + ?relay_parent, + ?validation_code_hash, + "error occured during submitting a vote: {:?}", + e, + ); + }, + } +} + +/// Sends a request to the candidate-validation subsystem to validate the given PVF. +/// +/// The relay-parent is used as an anchor from where to fetch the PVF code. The request will be put +/// into the `currently_checking` set. +async fn initiate_precheck( + state: &mut State, + sender: &mut impl overseer::PvfCheckerSenderTrait, + relay_parent: Hash, + validation_code_hash: ValidationCodeHash, + metrics: &Metrics, +) { + gum::debug!(target: LOG_TARGET, ?validation_code_hash, ?relay_parent, "initiating a precheck",); + + let (tx, rx) = oneshot::channel(); + sender + .send_message(CandidateValidationMessage::PreCheck(relay_parent, validation_code_hash, tx)) + .await; + + let timer = metrics.time_pre_check_judgement(); + state.currently_checking.push(Box::pin(async move { + let _timer = timer; + match rx.await { + Ok(accept) => Some((accept, validation_code_hash)), + Err(oneshot::Canceled) => { + // Pre-checking request dropped before replying. That can happen in case the + // overseer is shutting down. Our part of shutdown will be handled by the + // overseer conclude signal. Log it here just in case. + gum::debug!( + target: LOG_TARGET, + ?validation_code_hash, + ?relay_parent, + "precheck request was canceled", + ); + None + }, + } + })); +} diff --git a/polkadot/node/core/pvf-checker/src/metrics.rs b/polkadot/node/core/pvf-checker/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..374396b3b650d3c100c161010a5465404765e02e --- /dev/null +++ b/polkadot/node/core/pvf-checker/src/metrics.rs @@ -0,0 +1,130 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Metrics definitions for the PVF pre-checking subsystem. + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +struct MetricsInner { + pre_check_judgement: prometheus::Histogram, + votes_total: prometheus::Counter, + votes_started: prometheus::Counter, + votes_duplicate: prometheus::Counter, + pvfs_observed: prometheus::Counter, + pvfs_left: prometheus::Counter, +} + +#[derive(Default, Clone)] +pub struct Metrics(Option); + +impl Metrics { + /// Time between sending the pre-check request to receiving the response. + pub(crate) fn time_pre_check_judgement( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.pre_check_judgement.start_timer()) + } + + /// Called when a PVF vote/statement is submitted. + pub(crate) fn on_vote_submitted(&self) { + if let Some(metrics) = &self.0 { + metrics.votes_total.inc(); + } + } + + /// Called when a PVF vote/statement is started submission. + pub(crate) fn on_vote_submission_started(&self) { + if let Some(metrics) = &self.0 { + metrics.votes_started.inc(); + } + } + + /// Called when the vote is a duplicate. + pub(crate) fn on_vote_duplicate(&self) { + if let Some(metrics) = &self.0 { + metrics.votes_duplicate.inc(); + } + } + + /// Called when a new PVF is observed. + pub(crate) fn on_pvf_observed(&self, num: usize) { + if let Some(metrics) = &self.0 { + metrics.pvfs_observed.inc_by(num as u64); + } + } + + /// Called when a PVF left the view. + pub(crate) fn on_pvf_left(&self, num: usize) { + if let Some(metrics) = &self.0 { + metrics.pvfs_left.inc_by(num as u64); + } + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + pre_check_judgement: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_pvf_precheck_judgement", + "Time between sending the pre-check request to receiving the response.", + ) + .buckets(vec![0.1, 0.5, 1.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0]), + )?, + registry, + )?, + votes_total: prometheus::register( + prometheus::Counter::new( + "polkadot_pvf_precheck_votes_total", + "The total number of votes submitted.", + )?, + registry, + )?, + votes_started: prometheus::register( + prometheus::Counter::new( + "polkadot_pvf_precheck_votes_started", + "The number of votes that are pending submission", + )?, + registry, + )?, + votes_duplicate: prometheus::register( + prometheus::Counter::new( + "polkadot_pvf_precheck_votes_duplicate", + "The number of votes that are submitted more than once for the same code within\ +the same session.", + )?, + registry, + )?, + pvfs_observed: prometheus::register( + prometheus::Counter::new( + "polkadot_pvf_precheck_pvfs_observed", + "The number of new PVFs observed.", + )?, + registry, + )?, + pvfs_left: prometheus::register( + prometheus::Counter::new( + "polkadot_pvf_precheck_pvfs_left", + "The number of PVFs removed from the view.", + )?, + registry, + )?, + }; + Ok(Self(Some(metrics))) + } +} diff --git a/polkadot/node/core/pvf-checker/src/runtime_api.rs b/polkadot/node/core/pvf-checker/src/runtime_api.rs new file mode 100644 index 0000000000000000000000000000000000000000..ded991e0a4a6ba227f6630b85c61086b50298d0c --- /dev/null +++ b/polkadot/node/core/pvf-checker/src/runtime_api.rs @@ -0,0 +1,108 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::LOG_TARGET; +use futures::channel::oneshot; +use polkadot_node_subsystem::{ + errors::RuntimeApiError as RuntimeApiSubsystemError, + messages::{RuntimeApiMessage, RuntimeApiRequest}, + SubsystemSender, +}; +use polkadot_primitives::{ + Hash, PvfCheckStatement, SessionIndex, ValidationCodeHash, ValidatorId, ValidatorSignature, +}; + +pub(crate) async fn session_index_for_child( + sender: &mut impl SubsystemSender, + relay_parent: Hash, +) -> Result { + let (tx, rx) = oneshot::channel(); + runtime_api_request(sender, relay_parent, RuntimeApiRequest::SessionIndexForChild(tx), rx).await +} + +pub(crate) async fn validators( + sender: &mut impl SubsystemSender, + relay_parent: Hash, +) -> Result, RuntimeRequestError> { + let (tx, rx) = oneshot::channel(); + runtime_api_request(sender, relay_parent, RuntimeApiRequest::Validators(tx), rx).await +} + +pub(crate) async fn submit_pvf_check_statement( + sender: &mut impl SubsystemSender, + relay_parent: Hash, + stmt: PvfCheckStatement, + signature: ValidatorSignature, +) -> Result<(), RuntimeRequestError> { + let (tx, rx) = oneshot::channel(); + runtime_api_request( + sender, + relay_parent, + RuntimeApiRequest::SubmitPvfCheckStatement(stmt, signature, tx), + rx, + ) + .await +} + +pub(crate) async fn pvfs_require_precheck( + sender: &mut impl SubsystemSender, + relay_parent: Hash, +) -> Result, RuntimeRequestError> { + let (tx, rx) = oneshot::channel(); + runtime_api_request(sender, relay_parent, RuntimeApiRequest::PvfsRequirePrecheck(tx), rx).await +} + +#[derive(Debug)] +pub(crate) enum RuntimeRequestError { + NotSupported, + ApiError, + CommunicationError, +} + +pub(crate) async fn runtime_api_request( + sender: &mut impl SubsystemSender, + relay_parent: Hash, + request: RuntimeApiRequest, + receiver: oneshot::Receiver>, +) -> Result { + sender + .send_message(RuntimeApiMessage::Request(relay_parent, request).into()) + .await; + + receiver + .await + .map_err(|_| { + gum::debug!(target: LOG_TARGET, ?relay_parent, "Runtime API request dropped"); + RuntimeRequestError::CommunicationError + }) + .and_then(|res| { + res.map_err(|e| { + use RuntimeApiSubsystemError::*; + match e { + Execution { .. } => { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + err = ?e, + "Runtime API request internal error" + ); + RuntimeRequestError::ApiError + }, + NotSupported { .. } => RuntimeRequestError::NotSupported, + } + }) + }) +} diff --git a/polkadot/node/core/pvf-checker/src/tests.rs b/polkadot/node/core/pvf-checker/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..d1daa7a5813586675e85b4416516a41cd2db0ac9 --- /dev/null +++ b/polkadot/node/core/pvf-checker/src/tests.rs @@ -0,0 +1,937 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use ::test_helpers::{dummy_digest, dummy_hash}; +use futures::{channel::oneshot, future::BoxFuture, prelude::*}; +use polkadot_node_subsystem::{ + jaeger, + messages::{ + AllMessages, CandidateValidationMessage, PreCheckOutcome, PvfCheckerMessage, + RuntimeApiMessage, RuntimeApiRequest, + }, + ActivatedLeaf, ActiveLeavesUpdate, FromOrchestra, LeafStatus, OverseerSignal, RuntimeApiError, +}; +use polkadot_node_subsystem_test_helpers::{make_subsystem_context, TestSubsystemContextHandle}; +use polkadot_primitives::{ + BlockNumber, Hash, Header, PvfCheckStatement, SessionIndex, ValidationCode, ValidationCodeHash, + ValidatorId, +}; +use sp_application_crypto::AppCrypto; +use sp_core::testing::TaskExecutor; +use sp_keyring::Sr25519Keyring; +use sp_keystore::Keystore; +use sp_runtime::traits::AppVerify; +use std::{collections::HashMap, sync::Arc, time::Duration}; + +type VirtualOverseer = TestSubsystemContextHandle; + +fn dummy_validation_code_hash(descriminator: u8) -> ValidationCodeHash { + ValidationCode(vec![descriminator]).hash() +} + +struct StartsNewSession { + session_index: SessionIndex, + validators: Vec, +} + +#[derive(Debug, Clone)] +struct FakeLeaf { + block_hash: Hash, + block_number: BlockNumber, + pvfs: Vec, +} + +impl FakeLeaf { + fn new(parent_hash: Hash, block_number: BlockNumber, pvfs: Vec) -> Self { + let block_header = Header { + parent_hash, + number: block_number, + digest: dummy_digest(), + state_root: dummy_hash(), + extrinsics_root: dummy_hash(), + }; + let block_hash = block_header.hash(); + Self { block_hash, block_number, pvfs } + } + + fn descendant(&self, pvfs: Vec) -> FakeLeaf { + FakeLeaf::new(self.block_hash, self.block_number + 1, pvfs) + } +} + +struct LeafState { + /// The session index at which this leaf was activated. + session_index: SessionIndex, + + /// The list of PVFs that are pending in this leaf. + pvfs: Vec, +} + +/// The state we model about a session. +struct SessionState { + validators: Vec, +} + +struct TestState { + leaves: HashMap, + sessions: HashMap, + last_session_index: SessionIndex, +} + +const OUR_VALIDATOR: Sr25519Keyring = Sr25519Keyring::Alice; + +fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec { + val_ids.iter().map(|v| v.public().into()).collect() +} + +impl TestState { + fn new() -> Self { + // Initialize the default session 1. No validators are present there. + let last_session_index = 1; + let mut sessions = HashMap::new(); + sessions.insert(last_session_index, SessionState { validators: vec![] }); + + let mut leaves = HashMap::new(); + leaves.insert(dummy_hash(), LeafState { session_index: last_session_index, pvfs: vec![] }); + + Self { leaves, sessions, last_session_index } + } + + /// A convenience function to receive a message from the overseer and returning `None` if + /// nothing was received within a reasonable (for local tests anyway) timeout. + async fn recv_timeout(&mut self, handle: &mut VirtualOverseer) -> Option { + futures::select! { + msg = handle.recv().fuse() => { + Some(msg) + } + _ = futures_timer::Delay::new(Duration::from_millis(500)).fuse() => { + None + } + } + } + + async fn send_conclude(&mut self, handle: &mut VirtualOverseer) { + // To ensure that no messages are left in the queue there is no better way to just wait. + match self.recv_timeout(handle).await { + Some(msg) => { + panic!("we supposed to conclude, but received a message: {:#?}", msg); + }, + None => { + // No messages are received. We are good. + }, + } + + handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + } + + /// Convenience function to invoke [`active_leaves_update`] with the new leaf that starts a new + /// session and there are no deactivated leaves. + /// + /// Returns the block hash of the newly activated leaf. + async fn activate_leaf_with_session( + &mut self, + handle: &mut VirtualOverseer, + leaf: FakeLeaf, + starts_new_session: StartsNewSession, + ) { + self.active_leaves_update(handle, Some(leaf), Some(starts_new_session), &[]) + .await + } + + /// Convenience function to invoke [`active_leaves_update`] with a new leaf. The leaf does not + /// start a new session and there are no deactivated leaves. + async fn activate_leaf(&mut self, handle: &mut VirtualOverseer, leaf: FakeLeaf) { + self.active_leaves_update(handle, Some(leaf), None, &[]).await + } + + async fn deactivate_leaves( + &mut self, + handle: &mut VirtualOverseer, + deactivated: impl IntoIterator, + ) { + self.active_leaves_update(handle, None, None, deactivated).await + } + + /// Sends an `ActiveLeavesUpdate` message to the overseer and also updates the test state to + /// record leaves and session changes. + /// + /// NOTE: This function may stall if there is an unhandled message for the overseer. + async fn active_leaves_update( + &mut self, + handle: &mut VirtualOverseer, + fake_leaf: Option, + starts_new_session: Option, + deactivated: impl IntoIterator, + ) { + if let Some(new_session) = starts_new_session { + assert!(fake_leaf.is_some(), "Session can be started only with an activated leaf"); + self.last_session_index = new_session.session_index; + let prev = self.sessions.insert( + new_session.session_index, + SessionState { validators: validator_pubkeys(&new_session.validators) }, + ); + assert!(prev.is_none(), "Session {} already exists", new_session.session_index); + } + + let activated = if let Some(activated_leaf) = fake_leaf { + self.leaves.insert( + activated_leaf.block_hash, + LeafState { + session_index: self.last_session_index, + pvfs: activated_leaf.pvfs.clone(), + }, + ); + + Some(ActivatedLeaf { + hash: activated_leaf.block_hash, + span: Arc::new(jaeger::Span::Disabled), + number: activated_leaf.block_number, + status: LeafStatus::Fresh, + }) + } else { + None + }; + + handle + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated, + deactivated: deactivated.into_iter().cloned().collect(), + }))) + .await; + } + + /// Expects that the subsystem has sent a `Validators` Runtime API request. Answers with the + /// mocked validators for the requested leaf. + async fn expect_validators(&mut self, handle: &mut VirtualOverseer) { + match self.recv_timeout(handle).await.expect("timeout waiting for a message") { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Validators(tx), + )) => match self.leaves.get(&relay_parent) { + Some(leaf) => { + let session_index = leaf.session_index; + let session = self.sessions.get(&session_index).unwrap(); + tx.send(Ok(session.validators.clone())).unwrap(); + }, + None => { + panic!("a request to an unknown relay parent has been made"); + }, + }, + msg => panic!("Unexpected message was received: {:#?}", msg), + } + } + + /// Expects that the subsystem has sent a `SessionIndexForChild` Runtime API request. Answers + /// with the mocked session index for the requested leaf. + async fn expect_session_for_child(&mut self, handle: &mut VirtualOverseer) { + match self.recv_timeout(handle).await.expect("timeout waiting for a message") { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => match self.leaves.get(&relay_parent) { + Some(leaf) => { + tx.send(Ok(leaf.session_index)).unwrap(); + }, + None => { + panic!("a request to an unknown relay parent has been made"); + }, + }, + msg => panic!("Unexpected message was received: {:#?}", msg), + } + } + + /// Expects that the subsystem has sent a `PvfsRequirePrecheck` Runtime API request. Answers + /// with the mocked PVF set for the requested leaf. + async fn expect_pvfs_require_precheck( + &mut self, + handle: &mut VirtualOverseer, + ) -> ExpectPvfsRequirePrecheck<'_> { + match self.recv_timeout(handle).await.expect("timeout waiting for a message") { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::PvfsRequirePrecheck(tx), + )) => ExpectPvfsRequirePrecheck { test_state: self, relay_parent, tx }, + msg => panic!("Unexpected message was received: {:#?}", msg), + } + } + + /// Expects that the subsystem has sent a pre-checking request to candidate-validation. Returns + /// a mocked handle for the request. + async fn expect_candidate_precheck( + &mut self, + handle: &mut VirtualOverseer, + ) -> ExpectCandidatePrecheck { + match self.recv_timeout(handle).await.expect("timeout waiting for a message") { + AllMessages::CandidateValidation(CandidateValidationMessage::PreCheck( + relay_parent, + validation_code_hash, + tx, + )) => ExpectCandidatePrecheck { relay_parent, validation_code_hash, tx }, + msg => panic!("Unexpected message was received: {:#?}", msg), + } + } + + /// Expects that the subsystem has sent a `SubmitPvfCheckStatement` runtime API request. Returns + /// a mocked handle for the request. + async fn expect_submit_vote(&mut self, handle: &mut VirtualOverseer) -> ExpectSubmitVote { + match self.recv_timeout(handle).await.expect("timeout waiting for a message") { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SubmitPvfCheckStatement(stmt, signature, tx), + )) => { + let signing_payload = stmt.signing_payload(); + assert!(signature.verify(&signing_payload[..], &OUR_VALIDATOR.public().into())); + + ExpectSubmitVote { relay_parent, stmt, tx } + }, + msg => panic!("Unexpected message was received: {:#?}", msg), + } + } +} + +#[must_use] +struct ExpectPvfsRequirePrecheck<'a> { + test_state: &'a mut TestState, + relay_parent: Hash, + tx: oneshot::Sender, RuntimeApiError>>, +} + +impl<'a> ExpectPvfsRequirePrecheck<'a> { + fn reply_mock(self) { + match self.test_state.leaves.get(&self.relay_parent) { + Some(leaf) => { + self.tx.send(Ok(leaf.pvfs.clone())).unwrap(); + }, + None => { + panic!( + "a request to an unknown relay parent has been made: {:#?}", + self.relay_parent + ); + }, + } + } + + fn reply_not_supported(self) { + self.tx + .send(Err(RuntimeApiError::NotSupported { runtime_api_name: "pvfs_require_precheck" })) + .unwrap(); + } +} + +#[must_use] +struct ExpectCandidatePrecheck { + relay_parent: Hash, + validation_code_hash: ValidationCodeHash, + tx: oneshot::Sender, +} + +impl ExpectCandidatePrecheck { + fn reply(self, outcome: PreCheckOutcome) { + self.tx.send(outcome).unwrap(); + } +} + +#[must_use] +struct ExpectSubmitVote { + relay_parent: Hash, + stmt: PvfCheckStatement, + tx: oneshot::Sender>, +} + +impl ExpectSubmitVote { + fn reply_ok(self) { + self.tx.send(Ok(())).unwrap(); + } +} + +fn test_harness(test: impl FnOnce(TestState, VirtualOverseer) -> BoxFuture<'static, ()>) { + let pool = TaskExecutor::new(); + let (ctx, handle) = make_subsystem_context::(pool.clone()); + let keystore = Arc::new(sc_keystore::LocalKeystore::in_memory()); + + // Add OUR_VALIDATOR (which is Alice) to the keystore. + Keystore::sr25519_generate_new(&*keystore, ValidatorId::ID, Some(&OUR_VALIDATOR.to_seed())) + .expect("Generating keys for our node failed"); + + let subsystem_task = crate::run(ctx, keystore, crate::Metrics::default()).map(|x| x.unwrap()); + + let test_state = TestState::new(); + let test_task = test(test_state, handle); + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn concludes_correctly() { + test_harness(|mut test_state, mut handle| { + async move { + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn reacts_to_new_pvfs_in_heads() { + test_harness(|mut test_state, mut handle| { + async move { + let block = FakeLeaf::new(dummy_hash(), 1, vec![dummy_validation_code_hash(1)]); + + test_state + .activate_leaf_with_session( + &mut handle, + block.clone(), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + let pre_check = test_state.expect_candidate_precheck(&mut handle).await; + assert_eq!(pre_check.relay_parent, block.block_hash); + pre_check.reply(PreCheckOutcome::Valid); + + let vote = test_state.expect_submit_vote(&mut handle).await; + assert_eq!(vote.relay_parent, block.block_hash); + assert_eq!(vote.stmt.accept, true); + assert_eq!(vote.stmt.session_index, 2); + assert_eq!(vote.stmt.validator_index, 0.into()); + assert_eq!(vote.stmt.subject, dummy_validation_code_hash(1)); + vote.reply_ok(); + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn no_new_session_no_validators_request() { + test_harness(|mut test_state, mut handle| { + async move { + test_state + .activate_leaf_with_session( + &mut handle, + FakeLeaf::new(dummy_hash(), 1, vec![]), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + test_state + .activate_leaf(&mut handle, FakeLeaf::new(dummy_hash(), 2, vec![])) + .await; + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn activation_of_descendant_leaves_pvfs_in_view() { + test_harness(|mut test_state, mut handle| { + async move { + let block_1 = FakeLeaf::new(dummy_hash(), 1, vec![dummy_validation_code_hash(1)]); + let block_2 = block_1.descendant(vec![dummy_validation_code_hash(1)]); + + test_state + .activate_leaf_with_session( + &mut handle, + block_1.clone(), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + test_state + .expect_candidate_precheck(&mut handle) + .await + .reply(PreCheckOutcome::Valid); + test_state.expect_submit_vote(&mut handle).await.reply_ok(); + + // Now we deactivate the first block and activate it's descendant. + test_state + .active_leaves_update( + &mut handle, + Some(block_2), + None, // no new session started + &[block_1.block_hash], + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn reactivating_pvf_leads_to_second_check() { + test_harness(|mut test_state, mut handle| { + async move { + let pvf = dummy_validation_code_hash(1); + let block_1 = FakeLeaf::new(dummy_hash(), 1, vec![pvf]); + let block_2 = block_1.descendant(vec![]); + let block_3 = block_2.descendant(vec![pvf]); + + test_state + .activate_leaf_with_session( + &mut handle, + block_1.clone(), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + test_state + .expect_candidate_precheck(&mut handle) + .await + .reply(PreCheckOutcome::Valid); + test_state.expect_submit_vote(&mut handle).await.reply_ok(); + + // Now activate a descdedant leaf, where the PVF is not present. + test_state + .active_leaves_update( + &mut handle, + Some(block_2.clone()), + None, + &[block_1.block_hash], + ) + .await; + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + + // Now the third block is activated, where the PVF is present. + test_state.activate_leaf(&mut handle, block_3).await; + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state + .expect_candidate_precheck(&mut handle) + .await + .reply(PreCheckOutcome::Valid); + + // We do not vote here, because the PVF was already voted on within this session. + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn dont_double_vote_for_pvfs_in_view() { + test_harness(|mut test_state, mut handle| { + async move { + let pvf = dummy_validation_code_hash(1); + let block_1_1 = FakeLeaf::new([1; 32].into(), 1, vec![pvf]); + let block_2_1 = FakeLeaf::new([2; 32].into(), 1, vec![pvf]); + let block_1_2 = block_1_1.descendant(vec![pvf]); + + test_state + .activate_leaf_with_session( + &mut handle, + block_1_1.clone(), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + // Pre-checking will take quite some time. + let pre_check = test_state.expect_candidate_precheck(&mut handle).await; + + // Activate a sibiling leaf, has the same PVF. + test_state.activate_leaf(&mut handle, block_2_1).await; + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + + // Now activate a descendant leaf with the same PVF. + test_state + .active_leaves_update( + &mut handle, + Some(block_1_2.clone()), + None, + &[block_1_1.block_hash], + ) + .await; + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + + // Now finish the pre-checking request. + pre_check.reply(PreCheckOutcome::Valid); + test_state.expect_submit_vote(&mut handle).await.reply_ok(); + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn judgements_come_out_of_order() { + test_harness(|mut test_state, mut handle| { + async move { + let pvf_1 = dummy_validation_code_hash(1); + let pvf_2 = dummy_validation_code_hash(2); + + let block_1 = FakeLeaf::new([1; 32].into(), 1, vec![pvf_1]); + let block_2 = FakeLeaf::new([2; 32].into(), 1, vec![pvf_2]); + + test_state + .activate_leaf_with_session( + &mut handle, + block_1.clone(), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + let pre_check_1 = test_state.expect_candidate_precheck(&mut handle).await; + + // Activate a sibiling leaf, has the second PVF. + test_state.activate_leaf(&mut handle, block_2).await; + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + + let pre_check_2 = test_state.expect_candidate_precheck(&mut handle).await; + + // Resolve the PVF pre-checks out of order. + pre_check_2.reply(PreCheckOutcome::Valid); + pre_check_1.reply(PreCheckOutcome::Invalid); + + // Catch the vote for the second PVF. + let vote_2 = test_state.expect_submit_vote(&mut handle).await; + assert_eq!(vote_2.stmt.accept, true); + assert_eq!(vote_2.stmt.subject, pvf_2.clone()); + vote_2.reply_ok(); + + // Catch the vote for the first PVF. + let vote_1 = test_state.expect_submit_vote(&mut handle).await; + assert_eq!(vote_1.stmt.accept, false); + assert_eq!(vote_1.stmt.subject, pvf_1.clone()); + vote_1.reply_ok(); + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn dont_vote_until_a_validator() { + test_harness(|mut test_state, mut handle| { + async move { + test_state + .activate_leaf_with_session( + &mut handle, + FakeLeaf::new(dummy_hash(), 1, vec![dummy_validation_code_hash(1)]), + StartsNewSession { session_index: 2, validators: vec![Sr25519Keyring::Bob] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + test_state + .expect_candidate_precheck(&mut handle) + .await + .reply(PreCheckOutcome::Invalid); + + // Now a leaf brings a new session. In this session our validator comes into the active + // set. That means it will cast a vote for each judgement it has. + test_state + .activate_leaf_with_session( + &mut handle, + FakeLeaf::new(dummy_hash(), 2, vec![dummy_validation_code_hash(1)]), + StartsNewSession { + session_index: 3, + validators: vec![Sr25519Keyring::Bob, OUR_VALIDATOR], + }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + let vote = test_state.expect_submit_vote(&mut handle).await; + assert_eq!(vote.stmt.accept, false); + assert_eq!(vote.stmt.session_index, 3); + assert_eq!(vote.stmt.validator_index, 1.into()); + assert_eq!(vote.stmt.subject, dummy_validation_code_hash(1)); + vote.reply_ok(); + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn resign_on_session_change() { + test_harness(|mut test_state, mut handle| { + async move { + let pvf_1 = dummy_validation_code_hash(1); + let pvf_2 = dummy_validation_code_hash(2); + + test_state + .activate_leaf_with_session( + &mut handle, + FakeLeaf::new(dummy_hash(), 1, vec![pvf_1, pvf_2]), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + let pre_check_1 = test_state.expect_candidate_precheck(&mut handle).await; + assert_eq!(pre_check_1.validation_code_hash, pvf_1); + pre_check_1.reply(PreCheckOutcome::Valid); + let pre_check_2 = test_state.expect_candidate_precheck(&mut handle).await; + assert_eq!(pre_check_2.validation_code_hash, pvf_2); + pre_check_2.reply(PreCheckOutcome::Invalid); + + test_state.expect_submit_vote(&mut handle).await.reply_ok(); + test_state.expect_submit_vote(&mut handle).await.reply_ok(); + + // So far so good. Now we change the session. + test_state + .activate_leaf_with_session( + &mut handle, + FakeLeaf::new(dummy_hash(), 2, vec![pvf_1, pvf_2]), + StartsNewSession { session_index: 3, validators: vec![OUR_VALIDATOR] }, + ) + .await; + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + // The votes should be re-signed and re-submitted. + let mut statements = Vec::new(); + let vote_1 = test_state.expect_submit_vote(&mut handle).await; + statements.push(vote_1.stmt.clone()); + vote_1.reply_ok(); + let vote_2 = test_state.expect_submit_vote(&mut handle).await; + statements.push(vote_2.stmt.clone()); + vote_2.reply_ok(); + + // Find and check the votes. + // Unfortunately, the order of revoting is not deterministic so we have to resort to + // a bit of trickery. + assert_eq!(statements.iter().find(|s| s.subject == pvf_1).unwrap().accept, true); + assert_eq!(statements.iter().find(|s| s.subject == pvf_2).unwrap().accept, false); + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn dont_resign_if_not_us() { + test_harness(|mut test_state, mut handle| { + async move { + let pvf_1 = dummy_validation_code_hash(1); + let pvf_2 = dummy_validation_code_hash(2); + + test_state + .activate_leaf_with_session( + &mut handle, + FakeLeaf::new(dummy_hash(), 1, vec![pvf_1, pvf_2]), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + let pre_check_1 = test_state.expect_candidate_precheck(&mut handle).await; + assert_eq!(pre_check_1.validation_code_hash, pvf_1); + pre_check_1.reply(PreCheckOutcome::Valid); + let pre_check_2 = test_state.expect_candidate_precheck(&mut handle).await; + assert_eq!(pre_check_2.validation_code_hash, pvf_2); + pre_check_2.reply(PreCheckOutcome::Invalid); + + test_state.expect_submit_vote(&mut handle).await.reply_ok(); + test_state.expect_submit_vote(&mut handle).await.reply_ok(); + + // So far so good. Now we change the session. + test_state + .activate_leaf_with_session( + &mut handle, + FakeLeaf::new(dummy_hash(), 2, vec![pvf_1, pvf_2]), + StartsNewSession { + session_index: 3, + // not us + validators: vec![Sr25519Keyring::Bob], + }, + ) + .await; + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + // We do not expect any votes to be re-signed. + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn api_not_supported() { + test_harness(|mut test_state, mut handle| { + async move { + test_state + .activate_leaf_with_session( + &mut handle, + FakeLeaf::new(dummy_hash(), 1, vec![dummy_validation_code_hash(1)]), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_not_supported(); + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn not_supported_api_becomes_supported() { + test_harness(|mut test_state, mut handle| { + async move { + test_state + .activate_leaf_with_session( + &mut handle, + FakeLeaf::new(dummy_hash(), 1, vec![dummy_validation_code_hash(1)]), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_not_supported(); + + test_state + .activate_leaf_with_session( + &mut handle, + FakeLeaf::new(dummy_hash(), 1, vec![dummy_validation_code_hash(1)]), + StartsNewSession { session_index: 3, validators: vec![OUR_VALIDATOR] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + test_state + .expect_candidate_precheck(&mut handle) + .await + .reply(PreCheckOutcome::Valid); + test_state.expect_submit_vote(&mut handle).await.reply_ok(); + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +#[test] +fn unexpected_pvf_check_judgement() { + test_harness(|mut test_state, mut handle| { + async move { + let block_1 = FakeLeaf::new(dummy_hash(), 1, vec![dummy_validation_code_hash(1)]); + test_state + .activate_leaf_with_session( + &mut handle, + block_1.clone(), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + // Catch the pre-check request, but don't reply just yet. + let pre_check = test_state.expect_candidate_precheck(&mut handle).await; + + // Now deactivate the leaf and reply to the precheck request. + test_state.deactivate_leaves(&mut handle, &[block_1.block_hash]).await; + pre_check.reply(PreCheckOutcome::Invalid); + + // the subsystem must remain silent. + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} + +// Check that we do not abstain for a nondeterministic failure. Currently, this means the behavior +// is the same as if the pre-check returned `PreCheckOutcome::Invalid`. +#[test] +fn dont_abstain_for_nondeterministic_pvfcheck_failure() { + test_harness(|mut test_state, mut handle| { + async move { + let block_1 = FakeLeaf::new(dummy_hash(), 1, vec![dummy_validation_code_hash(1)]); + test_state + .activate_leaf_with_session( + &mut handle, + block_1.clone(), + StartsNewSession { session_index: 2, validators: vec![OUR_VALIDATOR] }, + ) + .await; + + test_state.expect_pvfs_require_precheck(&mut handle).await.reply_mock(); + test_state.expect_session_for_child(&mut handle).await; + test_state.expect_validators(&mut handle).await; + + // Catch the pre-check request, but don't reply just yet. + let pre_check = test_state.expect_candidate_precheck(&mut handle).await; + + // Now deactivate the leaf and reply to the precheck request. + test_state.deactivate_leaves(&mut handle, &[block_1.block_hash]).await; + pre_check.reply(PreCheckOutcome::Failed); + + // the subsystem must remain silent. + + test_state.send_conclude(&mut handle).await; + } + .boxed() + }); +} diff --git a/polkadot/node/core/pvf/Cargo.toml b/polkadot/node/core/pvf/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..b55df45b0203bf5b787ad6c842b6a729690626dd --- /dev/null +++ b/polkadot/node/core/pvf/Cargo.toml @@ -0,0 +1,59 @@ +[package] +name = "polkadot-node-core-pvf" +description = "Polkadot crate that implements the PVF validation host. Responsible for coordinating preparation and execution of PVFs." +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[[bin]] +name = "puppet_worker" +path = "bin/puppet_worker.rs" +required-features = ["test-utils"] + +[dependencies] +always-assert = "0.1" +futures = "0.3.21" +futures-timer = "3.0.2" +gum = { package = "tracing-gum", path = "../../gum" } +libc = "0.2.139" +pin-project = "1.0.9" +rand = "0.8.5" +slotmap = "1.0" +tempfile = "3.3.0" +tokio = { version = "1.24.2", features = ["fs", "process"] } + +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } + +polkadot-parachain = { path = "../../../parachain" } +polkadot-core-primitives = { path = "../../../core-primitives" } +polkadot-node-core-pvf-common = { path = "common" } +polkadot-node-metrics = { path = "../../metrics" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-primitives = { path = "../../../primitives" } + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-wasm-interface = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-maybe-compressed-blob = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true } +polkadot-node-core-pvf-prepare-worker = { path = "prepare-worker", optional = true } +polkadot-node-core-pvf-execute-worker = { path = "execute-worker", optional = true } + +[build-dependencies] +substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[dev-dependencies] +assert_matches = "1.4.0" +hex-literal = "0.3.4" +polkadot-node-core-pvf-common = { path = "common", features = ["test-utils"] } +# For the puppet worker, depend on ourselves with the test-utils feature. +polkadot-node-core-pvf = { path = ".", features = ["test-utils"] } + +adder = { package = "test-parachain-adder", path = "../../../parachain/test-parachains/adder" } +halt = { package = "test-parachain-halt", path = "../../../parachain/test-parachains/halt" } + +[features] +ci-only-tests = [] +# This feature is used to export test code to other crates without putting it in the production build. +# This is also used by the `puppet_worker` binary. +test-utils = ["polkadot-node-core-pvf-prepare-worker", "polkadot-node-core-pvf-execute-worker", "sp-tracing"] diff --git a/polkadot/node/core/pvf/bin/puppet_worker.rs b/polkadot/node/core/pvf/bin/puppet_worker.rs new file mode 100644 index 0000000000000000000000000000000000000000..7f93519d845400684a8e3a044ea5ecac50566ac5 --- /dev/null +++ b/polkadot/node/core/pvf/bin/puppet_worker.rs @@ -0,0 +1,17 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +polkadot_node_core_pvf::decl_puppet_worker_main!(); diff --git a/polkadot/node/core/pvf/common/Cargo.toml b/polkadot/node/core/pvf/common/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..dfb490455b3d70a55bf5406bd950b6dfdf2edc18 --- /dev/null +++ b/polkadot/node/core/pvf/common/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "polkadot-node-core-pvf-common" +description = "Polkadot crate that contains functionality related to PVFs that is shared by the PVF host and the PVF workers." +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +cpu-time = "1.0.0" +futures = "0.3.21" +gum = { package = "tracing-gum", path = "../../../gum" } +libc = "0.2.139" +tokio = { version = "1.24.2", features = ["fs", "process", "io-util"] } + +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } + +polkadot-parachain = { path = "../../../../parachain" } +polkadot-primitives = { path = "../../../../primitives" } + +sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-executor-common = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-executor-wasmtime = { git = "https://github.com/paritytech/substrate", branch = "master" } + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-externalities = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true } + +[target.'cfg(target_os = "linux")'.dependencies] +landlock = "0.2.0" + +[dev-dependencies] +assert_matches = "1.4.0" +tempfile = "3.3.0" + +[features] +# This feature is used to export test code to other crates without putting it in the production build. +# Also used for building the puppet worker. +test-utils = ["sp-tracing"] diff --git a/polkadot/node/core/pvf/common/src/error.rs b/polkadot/node/core/pvf/common/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..6eb0d9b7df42f7a25414d5d834a2b3e10d1bfa3a --- /dev/null +++ b/polkadot/node/core/pvf/common/src/error.rs @@ -0,0 +1,114 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::prepare::PrepareStats; +use parity_scale_codec::{Decode, Encode}; +use std::fmt; + +/// Result of PVF preparation performed by the validation host. Contains stats about the preparation +/// if successful +pub type PrepareResult = Result; + +/// An error that occurred during the prepare part of the PVF pipeline. +#[derive(Debug, Clone, Encode, Decode)] +pub enum PrepareError { + /// During the prevalidation stage of preparation an issue was found with the PVF. + Prevalidation(String), + /// Compilation failed for the given PVF. + Preparation(String), + /// Instantiation of the WASM module instance failed. + RuntimeConstruction(String), + /// An unexpected panic has occurred in the preparation worker. + Panic(String), + /// Failed to prepare the PVF due to the time limit. + TimedOut, + /// An IO error occurred. This state is reported by either the validation host or by the + /// worker. + IoErr(String), + /// The temporary file for the artifact could not be created at the given cache path. This + /// state is reported by the validation host (not by the worker). + CreateTmpFileErr(String), + /// The response from the worker is received, but the file cannot be renamed (moved) to the + /// final destination location. This state is reported by the validation host (not by the + /// worker). + RenameTmpFileErr(String), +} + +impl PrepareError { + /// Returns whether this is a deterministic error, i.e. one that should trigger reliably. Those + /// errors depend on the PVF itself and the sc-executor/wasmtime logic. + /// + /// Non-deterministic errors can happen spuriously. Typically, they occur due to resource + /// starvation, e.g. under heavy load or memory pressure. Those errors are typically transient + /// but may persist e.g. if the node is run by overwhelmingly underpowered machine. + pub fn is_deterministic(&self) -> bool { + use PrepareError::*; + match self { + Prevalidation(_) | Preparation(_) | Panic(_) => true, + TimedOut | IoErr(_) | CreateTmpFileErr(_) | RenameTmpFileErr(_) => false, + // Can occur due to issues with the PVF, but also due to local errors. + RuntimeConstruction(_) => false, + } + } +} + +impl fmt::Display for PrepareError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use PrepareError::*; + match self { + Prevalidation(err) => write!(f, "prevalidation: {}", err), + Preparation(err) => write!(f, "preparation: {}", err), + RuntimeConstruction(err) => write!(f, "runtime construction: {}", err), + Panic(err) => write!(f, "panic: {}", err), + TimedOut => write!(f, "prepare: timeout"), + IoErr(err) => write!(f, "prepare: io error while receiving response: {}", err), + CreateTmpFileErr(err) => write!(f, "prepare: error creating tmp file: {}", err), + RenameTmpFileErr(err) => write!(f, "prepare: error renaming tmp file: {}", err), + } + } +} + +/// Some internal error occurred. +/// +/// Should only ever be used for validation errors independent of the candidate and PVF, or for +/// errors we ruled out during pre-checking (so preparation errors are fine). +#[derive(Debug, Clone, Encode, Decode)] +pub enum InternalValidationError { + /// Some communication error occurred with the host. + HostCommunication(String), + /// Could not find or open compiled artifact file. + CouldNotOpenFile(String), + /// An error occurred in the CPU time monitor thread. Should be totally unrelated to + /// validation. + CpuTimeMonitorThread(String), + /// Some non-deterministic preparation error occurred. + NonDeterministicPrepareError(PrepareError), +} + +impl fmt::Display for InternalValidationError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use InternalValidationError::*; + match self { + HostCommunication(err) => + write!(f, "validation: some communication error occurred with the host: {}", err), + CouldNotOpenFile(err) => + write!(f, "validation: could not find or open compiled artifact file: {}", err), + CpuTimeMonitorThread(err) => + write!(f, "validation: an error occurred in the CPU time monitor thread: {}", err), + NonDeterministicPrepareError(err) => write!(f, "validation: prepare: {}", err), + } + } +} diff --git a/polkadot/node/core/pvf/common/src/execute.rs b/polkadot/node/core/pvf/common/src/execute.rs new file mode 100644 index 0000000000000000000000000000000000000000..de5ce39f78381dc87156dcbcd8fa0d68fb3b3c52 --- /dev/null +++ b/polkadot/node/core/pvf/common/src/execute.rs @@ -0,0 +1,60 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::error::InternalValidationError; +use parity_scale_codec::{Decode, Encode}; +use polkadot_parachain::primitives::ValidationResult; +use polkadot_primitives::ExecutorParams; +use std::time::Duration; + +/// The payload of the one-time handshake that is done when a worker process is created. Carries +/// data from the host to the worker. +#[derive(Encode, Decode)] +pub struct Handshake { + /// The executor parameters. + pub executor_params: ExecutorParams, +} + +/// The response from an execution job on the worker. +#[derive(Encode, Decode)] +pub enum Response { + /// The job completed successfully. + Ok { + /// The result of parachain validation. + result_descriptor: ValidationResult, + /// The amount of CPU time taken by the job. + duration: Duration, + }, + /// The candidate is invalid. + InvalidCandidate(String), + /// The job timed out. + TimedOut, + /// An unexpected panic has occurred in the execution worker. + Panic(String), + /// Some internal error occurred. + InternalError(InternalValidationError), +} + +impl Response { + /// Creates an invalid response from a context `ctx` and a message `msg` (which can be empty). + pub fn format_invalid(ctx: &'static str, msg: &str) -> Self { + if msg.is_empty() { + Self::InvalidCandidate(ctx.to_string()) + } else { + Self::InvalidCandidate(format!("{}: {}", ctx, msg)) + } + } +} diff --git a/polkadot/node/core/pvf/common/src/executor_intf.rs b/polkadot/node/core/pvf/common/src/executor_intf.rs new file mode 100644 index 0000000000000000000000000000000000000000..42ed4b79c76120320c1e6c823d236f30b40f1875 --- /dev/null +++ b/polkadot/node/core/pvf/common/src/executor_intf.rs @@ -0,0 +1,373 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Interface to the Substrate Executor + +use polkadot_primitives::{ExecutorParam, ExecutorParams}; +use sc_executor_common::{ + error::WasmError, + runtime_blob::RuntimeBlob, + wasm_runtime::{HeapAllocStrategy, InvokeMethod, WasmModule as _}, +}; +use sc_executor_wasmtime::{Config, DeterministicStackLimit, Semantics, WasmtimeRuntime}; +use sp_core::storage::{ChildInfo, TrackedStorageKey}; +use sp_externalities::MultiRemovalResults; +use std::any::{Any, TypeId}; + +// Memory configuration +// +// When Substrate Runtime is instantiated, a number of WASM pages are allocated for the Substrate +// Runtime instance's linear memory. The exact number of pages is a sum of whatever the WASM blob +// itself requests (by default at least enough to hold the data section as well as have some space +// left for the stack; this is, of course, overridable at link time when compiling the runtime) +// plus the number of pages specified in the `extra_heap_pages` passed to the executor. +// +// By default, rustc (or `lld` specifically) should allocate 1 MiB for the shadow stack, or 16 +// pages. The data section for runtimes are typically rather small and can fit in a single digit +// number of WASM pages, so let's say an extra 16 pages. Thus let's assume that 32 pages or 2 MiB +// are used for these needs by default. +const DEFAULT_HEAP_PAGES_ESTIMATE: u32 = 32; +const EXTRA_HEAP_PAGES: u32 = 2048; + +/// The number of bytes devoted for the stack during wasm execution of a PVF. +pub const NATIVE_STACK_MAX: u32 = 256 * 1024 * 1024; + +// VALUES OF THE DEFAULT CONFIGURATION SHOULD NEVER BE CHANGED +// They are used as base values for the execution environment parametrization. +// To overwrite them, add new ones to `EXECUTOR_PARAMS` in the `session_info` pallet and perform +// a runtime upgrade to make them active. +pub const DEFAULT_CONFIG: Config = Config { + allow_missing_func_imports: true, + cache_path: None, + semantics: Semantics { + heap_alloc_strategy: sc_executor_common::wasm_runtime::HeapAllocStrategy::Dynamic { + maximum_pages: Some(DEFAULT_HEAP_PAGES_ESTIMATE + EXTRA_HEAP_PAGES), + }, + + instantiation_strategy: + sc_executor_wasmtime::InstantiationStrategy::RecreateInstanceCopyOnWrite, + + // Enable deterministic stack limit to pin down the exact number of items the wasmtime stack + // can contain before it traps with stack overflow. + // + // Here is how the values below were chosen. + // + // At the moment of writing, the default native stack size limit is 1 MiB. Assuming a + // logical item (see the docs about the field and the instrumentation algorithm) is 8 bytes, + // 1 MiB can fit 2x 65536 logical items. + // + // Since reaching the native stack limit is undesirable, we halve the logical item limit and + // also increase the native 256x. This hopefully should preclude wasm code from reaching + // the stack limit set by the wasmtime. + deterministic_stack_limit: Some(DeterministicStackLimit { + logical_max: 65536, + native_stack_max: NATIVE_STACK_MAX, + }), + canonicalize_nans: true, + // Rationale for turning the multi-threaded compilation off is to make the preparation time + // easily reproducible and as deterministic as possible. + // + // Currently the prepare queue doesn't distinguish between precheck and prepare requests. + // On the one hand, it simplifies the code, on the other, however, slows down compile times + // for execute requests. This behavior may change in future. + parallel_compilation: false, + + // WASM extensions. Only those that are meaningful to us may be controlled here. By default, + // we're using WASM MVP, which means all the extensions are disabled. Nevertheless, some + // extensions (e.g., sign extension ops) are enabled by Wasmtime and cannot be disabled. + wasm_reference_types: false, + wasm_simd: false, + wasm_bulk_memory: false, + wasm_multi_value: false, + }, +}; + +pub fn params_to_wasmtime_semantics(par: &ExecutorParams) -> Result { + let mut sem = DEFAULT_CONFIG.semantics.clone(); + let mut stack_limit = if let Some(stack_limit) = sem.deterministic_stack_limit.clone() { + stack_limit + } else { + return Err("No default stack limit set".to_owned()) + }; + + for p in par.iter() { + match p { + ExecutorParam::MaxMemoryPages(max_pages) => + sem.heap_alloc_strategy = + HeapAllocStrategy::Dynamic { maximum_pages: Some(*max_pages) }, + ExecutorParam::StackLogicalMax(slm) => stack_limit.logical_max = *slm, + ExecutorParam::StackNativeMax(snm) => stack_limit.native_stack_max = *snm, + ExecutorParam::WasmExtBulkMemory => sem.wasm_bulk_memory = true, + // TODO: Not implemented yet; . + ExecutorParam::PrecheckingMaxMemory(_) => (), + ExecutorParam::PvfPrepTimeout(_, _) | ExecutorParam::PvfExecTimeout(_, _) => (), /* Not used here */ + } + } + sem.deterministic_stack_limit = Some(stack_limit); + Ok(sem) +} + +/// A WASM executor with a given configuration. It is instantiated once per execute worker and is +/// specific to that worker. +#[derive(Clone)] +pub struct Executor { + config: Config, +} + +impl Executor { + pub fn new(params: ExecutorParams) -> Result { + let mut config = DEFAULT_CONFIG.clone(); + config.semantics = params_to_wasmtime_semantics(¶ms)?; + + Ok(Self { config }) + } + + /// Executes the given PVF in the form of a compiled artifact and returns the result of + /// execution upon success. + /// + /// # Safety + /// + /// The caller must ensure that the compiled artifact passed here was: + /// 1) produced by [`prepare`], + /// 2) was not modified, + /// + /// Failure to adhere to these requirements might lead to crashes and arbitrary code execution. + pub unsafe fn execute( + &self, + compiled_artifact_blob: &[u8], + params: &[u8], + ) -> Result, String> { + let mut extensions = sp_externalities::Extensions::new(); + + extensions.register(sp_core::traits::ReadRuntimeVersionExt::new(ReadRuntimeVersion)); + + let mut ext = ValidationExternalities(extensions); + + match sc_executor::with_externalities_safe(&mut ext, || { + let runtime = self.create_runtime_from_bytes(compiled_artifact_blob)?; + runtime.new_instance()?.call(InvokeMethod::Export("validate_block"), params) + }) { + Ok(Ok(ok)) => Ok(ok), + Ok(Err(err)) | Err(err) => Err(err), + } + .map_err(|err| format!("execute error: {:?}", err)) + } + + /// Constructs the runtime for the given PVF, given the artifact bytes. + /// + /// # Safety + /// + /// The caller must ensure that the compiled artifact passed here was: + /// 1) produced by [`prepare`], + /// 2) was not modified, + /// + /// Failure to adhere to these requirements might lead to crashes and arbitrary code execution. + pub unsafe fn create_runtime_from_bytes( + &self, + compiled_artifact_blob: &[u8], + ) -> Result { + sc_executor_wasmtime::create_runtime_from_artifact_bytes::( + compiled_artifact_blob, + self.config.clone(), + ) + } +} + +/// Available host functions. We leave out: +/// +/// 1. storage related stuff (PVF doesn't have a notion of a persistent storage/trie) +/// 2. tracing +/// 3. off chain workers (PVFs do not have such a notion) +/// 4. runtime tasks +/// 5. sandbox +type HostFunctions = ( + sp_io::misc::HostFunctions, + sp_io::crypto::HostFunctions, + sp_io::hashing::HostFunctions, + sp_io::allocator::HostFunctions, + sp_io::logging::HostFunctions, + sp_io::trie::HostFunctions, +); + +/// The validation externalities that will panic on any storage related access. (PVFs should not +/// have a notion of a persistent storage/trie.) +struct ValidationExternalities(sp_externalities::Extensions); + +impl sp_externalities::Externalities for ValidationExternalities { + fn storage(&self, _: &[u8]) -> Option> { + panic!("storage: unsupported feature for parachain validation") + } + + fn storage_hash(&self, _: &[u8]) -> Option> { + panic!("storage_hash: unsupported feature for parachain validation") + } + + fn child_storage_hash(&self, _: &ChildInfo, _: &[u8]) -> Option> { + panic!("child_storage_hash: unsupported feature for parachain validation") + } + + fn child_storage(&self, _: &ChildInfo, _: &[u8]) -> Option> { + panic!("child_storage: unsupported feature for parachain validation") + } + + fn kill_child_storage( + &mut self, + _child_info: &ChildInfo, + _maybe_limit: Option, + _maybe_cursor: Option<&[u8]>, + ) -> MultiRemovalResults { + panic!("kill_child_storage: unsupported feature for parachain validation") + } + + fn clear_prefix( + &mut self, + _prefix: &[u8], + _maybe_limit: Option, + _maybe_cursor: Option<&[u8]>, + ) -> MultiRemovalResults { + panic!("clear_prefix: unsupported feature for parachain validation") + } + + fn clear_child_prefix( + &mut self, + _child_info: &ChildInfo, + _prefix: &[u8], + _maybe_limit: Option, + _maybe_cursor: Option<&[u8]>, + ) -> MultiRemovalResults { + panic!("clear_child_prefix: unsupported feature for parachain validation") + } + + fn place_storage(&mut self, _: Vec, _: Option>) { + panic!("place_storage: unsupported feature for parachain validation") + } + + fn place_child_storage(&mut self, _: &ChildInfo, _: Vec, _: Option>) { + panic!("place_child_storage: unsupported feature for parachain validation") + } + + fn storage_root(&mut self, _: sp_core::storage::StateVersion) -> Vec { + panic!("storage_root: unsupported feature for parachain validation") + } + + fn child_storage_root(&mut self, _: &ChildInfo, _: sp_core::storage::StateVersion) -> Vec { + panic!("child_storage_root: unsupported feature for parachain validation") + } + + fn next_child_storage_key(&self, _: &ChildInfo, _: &[u8]) -> Option> { + panic!("next_child_storage_key: unsupported feature for parachain validation") + } + + fn next_storage_key(&self, _: &[u8]) -> Option> { + panic!("next_storage_key: unsupported feature for parachain validation") + } + + fn storage_append(&mut self, _key: Vec, _value: Vec) { + panic!("storage_append: unsupported feature for parachain validation") + } + + fn storage_start_transaction(&mut self) { + panic!("storage_start_transaction: unsupported feature for parachain validation") + } + + fn storage_rollback_transaction(&mut self) -> Result<(), ()> { + panic!("storage_rollback_transaction: unsupported feature for parachain validation") + } + + fn storage_commit_transaction(&mut self) -> Result<(), ()> { + panic!("storage_commit_transaction: unsupported feature for parachain validation") + } + + fn wipe(&mut self) { + panic!("wipe: unsupported feature for parachain validation") + } + + fn commit(&mut self) { + panic!("commit: unsupported feature for parachain validation") + } + + fn read_write_count(&self) -> (u32, u32, u32, u32) { + panic!("read_write_count: unsupported feature for parachain validation") + } + + fn reset_read_write_count(&mut self) { + panic!("reset_read_write_count: unsupported feature for parachain validation") + } + + fn get_whitelist(&self) -> Vec { + panic!("get_whitelist: unsupported feature for parachain validation") + } + + fn set_whitelist(&mut self, _: Vec) { + panic!("set_whitelist: unsupported feature for parachain validation") + } + + fn set_offchain_storage(&mut self, _: &[u8], _: std::option::Option<&[u8]>) { + panic!("set_offchain_storage: unsupported feature for parachain validation") + } + + fn get_read_and_written_keys(&self) -> Vec<(Vec, u32, u32, bool)> { + panic!("get_read_and_written_keys: unsupported feature for parachain validation") + } +} + +impl sp_externalities::ExtensionStore for ValidationExternalities { + fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any> { + self.0.get_mut(type_id) + } + + fn register_extension_with_type_id( + &mut self, + type_id: TypeId, + extension: Box, + ) -> Result<(), sp_externalities::Error> { + self.0.register_with_type_id(type_id, extension) + } + + fn deregister_extension_by_type_id( + &mut self, + type_id: TypeId, + ) -> Result<(), sp_externalities::Error> { + if self.0.deregister(type_id) { + Ok(()) + } else { + Err(sp_externalities::Error::ExtensionIsNotRegistered(type_id)) + } + } +} + +struct ReadRuntimeVersion; + +impl sp_core::traits::ReadRuntimeVersion for ReadRuntimeVersion { + fn read_runtime_version( + &self, + wasm_code: &[u8], + _ext: &mut dyn sp_externalities::Externalities, + ) -> Result, String> { + let blob = RuntimeBlob::uncompress_if_needed(wasm_code) + .map_err(|e| format!("Failed to read the PVF runtime blob: {:?}", e))?; + + match sc_executor::read_embedded_version(&blob) + .map_err(|e| format!("Failed to read the static section from the PVF blob: {:?}", e))? + { + Some(version) => { + use parity_scale_codec::Encode; + Ok(version.encode()) + }, + None => Err("runtime version section is not found".to_string()), + } + } +} diff --git a/polkadot/node/core/pvf/common/src/lib.rs b/polkadot/node/core/pvf/common/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..8ff9757a07a022120bc34f17943afe416b5fafb9 --- /dev/null +++ b/polkadot/node/core/pvf/common/src/lib.rs @@ -0,0 +1,61 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Contains functionality related to PVFs that is shared by the PVF host and the PVF workers. + +pub mod error; +pub mod execute; +pub mod executor_intf; +pub mod prepare; +pub mod pvf; +pub mod worker; + +pub use cpu_time::ProcessTime; + +// Used by `decl_worker_main!`. +#[cfg(feature = "test-utils")] +pub use sp_tracing; + +const LOG_TARGET: &str = "parachain::pvf-common"; + +use std::mem; +use tokio::io::{self, AsyncRead, AsyncReadExt as _, AsyncWrite, AsyncWriteExt as _}; + +#[cfg(feature = "test-utils")] +pub mod tests { + use std::time::Duration; + + pub const TEST_EXECUTION_TIMEOUT: Duration = Duration::from_secs(3); + pub const TEST_PREPARATION_TIMEOUT: Duration = Duration::from_secs(30); +} + +/// Write some data prefixed by its length into `w`. +pub async fn framed_send(w: &mut (impl AsyncWrite + Unpin), buf: &[u8]) -> io::Result<()> { + let len_buf = buf.len().to_le_bytes(); + w.write_all(&len_buf).await?; + w.write_all(buf).await?; + Ok(()) +} + +/// Read some data prefixed by its length from `r`. +pub async fn framed_recv(r: &mut (impl AsyncRead + Unpin)) -> io::Result> { + let mut len_buf = [0u8; mem::size_of::()]; + r.read_exact(&mut len_buf).await?; + let len = usize::from_le_bytes(len_buf); + let mut buf = vec![0; len]; + r.read_exact(&mut buf).await?; + Ok(buf) +} diff --git a/polkadot/node/core/pvf/common/src/prepare.rs b/polkadot/node/core/pvf/common/src/prepare.rs new file mode 100644 index 0000000000000000000000000000000000000000..c205eddfb8b1fbeaf5842d8b468ca94f4806f23a --- /dev/null +++ b/polkadot/node/core/pvf/common/src/prepare.rs @@ -0,0 +1,57 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use parity_scale_codec::{Decode, Encode}; + +/// Preparation statistics, including the CPU time and memory taken. +#[derive(Debug, Clone, Default, Encode, Decode)] +pub struct PrepareStats { + /// The CPU time that elapsed for the preparation job. + pub cpu_time_elapsed: std::time::Duration, + /// The observed memory statistics for the preparation job. + pub memory_stats: MemoryStats, +} + +/// Helper struct to contain all the memory stats, including `MemoryAllocationStats` and, if +/// supported by the OS, `ru_maxrss`. +#[derive(Clone, Debug, Default, Encode, Decode)] +pub struct MemoryStats { + /// Memory stats from `tikv_jemalloc_ctl`. + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + pub memory_tracker_stats: Option, + /// `ru_maxrss` from `getrusage`. `None` if an error occurred. + #[cfg(target_os = "linux")] + pub max_rss: Option, +} + +/// Statistics of collected memory metrics. +#[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] +#[derive(Clone, Debug, Default, Encode, Decode)] +pub struct MemoryAllocationStats { + /// Total resident memory, in bytes. + pub resident: u64, + /// Total allocated memory, in bytes. + pub allocated: u64, +} + +/// The kind of prepare job. +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub enum PrepareJobKind { + /// Compilation triggered by a candidate validation request. + Compilation, + /// A prechecking job. + Prechecking, +} diff --git a/polkadot/node/core/pvf/common/src/pvf.rs b/polkadot/node/core/pvf/common/src/pvf.rs new file mode 100644 index 0000000000000000000000000000000000000000..e31264713a571587f718e049c56b06a4e4a6b54b --- /dev/null +++ b/polkadot/node/core/pvf/common/src/pvf.rs @@ -0,0 +1,131 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::prepare::PrepareJobKind; +use parity_scale_codec::{Decode, Encode}; +use polkadot_parachain::primitives::ValidationCodeHash; +use polkadot_primitives::ExecutorParams; +use sp_core::blake2_256; +use std::{ + cmp::{Eq, PartialEq}, + fmt, + sync::Arc, + time::Duration, +}; + +/// A struct that carries the exhaustive set of data to prepare an artifact out of plain +/// Wasm binary +/// +/// Should be cheap to clone. +#[derive(Clone, Encode, Decode)] +pub struct PvfPrepData { + /// Wasm code (uncompressed) + code: Arc>, + /// Wasm code hash + code_hash: ValidationCodeHash, + /// Executor environment parameters for the session for which artifact is prepared + executor_params: Arc, + /// Preparation timeout + prep_timeout: Duration, + /// The kind of preparation job. + prep_kind: PrepareJobKind, +} + +impl PvfPrepData { + /// Returns an instance of the PVF out of the given PVF code and executor params. + pub fn from_code( + code: Vec, + executor_params: ExecutorParams, + prep_timeout: Duration, + prep_kind: PrepareJobKind, + ) -> Self { + let code = Arc::new(code); + let code_hash = blake2_256(&code).into(); + let executor_params = Arc::new(executor_params); + Self { code, code_hash, executor_params, prep_timeout, prep_kind } + } + + /// Returns validation code hash for the PVF + pub fn code_hash(&self) -> ValidationCodeHash { + self.code_hash + } + + /// Returns PVF code + pub fn code(&self) -> Arc> { + self.code.clone() + } + + /// Returns executor params + pub fn executor_params(&self) -> Arc { + self.executor_params.clone() + } + + /// Returns preparation timeout. + pub fn prep_timeout(&self) -> Duration { + self.prep_timeout + } + + /// Returns preparation kind. + pub fn prep_kind(&self) -> PrepareJobKind { + self.prep_kind + } + + /// Creates a structure for tests. + #[cfg(feature = "test-utils")] + pub fn from_discriminator_and_timeout(num: u32, timeout: Duration) -> Self { + let descriminator_buf = num.to_le_bytes().to_vec(); + Self::from_code( + descriminator_buf, + ExecutorParams::default(), + timeout, + PrepareJobKind::Compilation, + ) + } + + /// Creates a structure for tests. + #[cfg(feature = "test-utils")] + pub fn from_discriminator(num: u32) -> Self { + Self::from_discriminator_and_timeout(num, crate::tests::TEST_PREPARATION_TIMEOUT) + } + + /// Creates a structure for tests. + #[cfg(feature = "test-utils")] + pub fn from_discriminator_precheck(num: u32) -> Self { + let mut pvf = + Self::from_discriminator_and_timeout(num, crate::tests::TEST_PREPARATION_TIMEOUT); + pvf.prep_kind = PrepareJobKind::Prechecking; + pvf + } +} + +impl fmt::Debug for PvfPrepData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "Pvf {{ code, code_hash: {:?}, executor_params: {:?}, prep_timeout: {:?} }}", + self.code_hash, self.executor_params, self.prep_timeout + ) + } +} + +impl PartialEq for PvfPrepData { + fn eq(&self, other: &Self) -> bool { + self.code_hash == other.code_hash && + self.executor_params.hash() == other.executor_params.hash() + } +} + +impl Eq for PvfPrepData {} diff --git a/polkadot/node/core/pvf/common/src/worker/mod.rs b/polkadot/node/core/pvf/common/src/worker/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..8b41cb82f73bfca4e3b04ec3c31396da5ca0873b --- /dev/null +++ b/polkadot/node/core/pvf/common/src/worker/mod.rs @@ -0,0 +1,480 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Functionality common to both prepare and execute workers. + +pub mod security; + +use crate::LOG_TARGET; +use cpu_time::ProcessTime; +use futures::never::Never; +use std::{ + any::Any, + path::PathBuf, + sync::mpsc::{Receiver, RecvTimeoutError}, + time::Duration, +}; +use tokio::{io, net::UnixStream, runtime::Runtime}; + +/// Use this macro to declare a `fn main() {}` that will create an executable that can be used for +/// spawning the desired worker. +#[macro_export] +macro_rules! decl_worker_main { + ($expected_command:expr, $entrypoint:expr, $worker_version:expr) => { + fn print_help(expected_command: &str) { + println!("{} {}", expected_command, $worker_version); + println!(); + println!("PVF worker that is called by polkadot."); + } + + fn main() { + $crate::sp_tracing::try_init_simple(); + + let args = std::env::args().collect::>(); + if args.len() == 1 { + print_help($expected_command); + return + } + + match args[1].as_ref() { + "--help" | "-h" => { + print_help($expected_command); + return + }, + "--version" | "-v" => { + println!("{}", $worker_version); + return + }, + subcommand => { + // Must be passed for compatibility with the single-binary test workers. + if subcommand != $expected_command { + panic!( + "trying to run {} binary with the {} subcommand", + $expected_command, subcommand + ) + } + }, + } + + let mut node_version = None; + let mut socket_path: &str = ""; + + for i in (2..args.len()).step_by(2) { + match args[i].as_ref() { + "--socket-path" => socket_path = args[i + 1].as_str(), + "--node-impl-version" => node_version = Some(args[i + 1].as_str()), + arg => panic!("Unexpected argument found: {}", arg), + } + } + + $entrypoint(&socket_path, node_version, Some($worker_version)); + } + }; +} + +/// Some allowed overhead that we account for in the "CPU time monitor" thread's sleeps, on the +/// child process. +pub const JOB_TIMEOUT_OVERHEAD: Duration = Duration::from_millis(50); + +/// Interprets the given bytes as a path. Returns `None` if the given bytes do not constitute a +/// a proper utf-8 string. +pub fn bytes_to_path(bytes: &[u8]) -> Option { + std::str::from_utf8(bytes).ok().map(PathBuf::from) +} + +// The worker version must be passed in so that we accurately get the version of the worker, and not +// the version that this crate was compiled with. +pub fn worker_event_loop( + debug_id: &'static str, + socket_path: &str, + node_version: Option<&str>, + worker_version: Option<&str>, + mut event_loop: F, +) where + F: FnMut(UnixStream) -> Fut, + Fut: futures::Future>, +{ + let worker_pid = std::process::id(); + gum::debug!(target: LOG_TARGET, %worker_pid, "starting pvf worker ({})", debug_id); + + // Check for a mismatch between the node and worker versions. + if let (Some(node_version), Some(worker_version)) = (node_version, worker_version) { + if node_version != worker_version { + gum::error!( + target: LOG_TARGET, + %worker_pid, + %node_version, + %worker_version, + "Node and worker version mismatch, node needs restarting, forcing shutdown", + ); + kill_parent_node_in_emergency(); + let err = io::Error::new(io::ErrorKind::Unsupported, "Version mismatch"); + worker_shutdown_message(debug_id, worker_pid, err); + return + } + } + + remove_env_vars(debug_id); + + // Run the main worker loop. + let rt = Runtime::new().expect("Creates tokio runtime. If this panics the worker will die and the host will detect that and deal with it."); + let err = rt + .block_on(async move { + let stream = UnixStream::connect(socket_path).await?; + let _ = tokio::fs::remove_file(socket_path).await; + + let result = event_loop(stream).await; + + result + }) + // It's never `Ok` because it's `Ok(Never)`. + .unwrap_err(); + + worker_shutdown_message(debug_id, worker_pid, err); + + // We don't want tokio to wait for the tasks to finish. We want to bring down the worker as fast + // as possible and not wait for stalled validation to finish. This isn't strictly necessary now, + // but may be in the future. + rt.shutdown_background(); +} + +/// Delete all env vars to prevent malicious code from accessing them. +fn remove_env_vars(debug_id: &'static str) { + for (key, value) in std::env::vars_os() { + // TODO: *theoretically* the value (or mere presence) of `RUST_LOG` can be a source of + // randomness for malicious code. In the future we can remove it also and log in the host; + // see . + if key == "RUST_LOG" { + continue + } + + // In case of a key or value that would cause [`env::remove_var` to + // panic](https://doc.rust-lang.org/std/env/fn.remove_var.html#panics), we first log a + // warning and then proceed to attempt to remove the env var. + let mut err_reasons = vec![]; + let (key_str, value_str) = (key.to_str(), value.to_str()); + if key.is_empty() { + err_reasons.push("key is empty"); + } + if key_str.is_some_and(|s| s.contains('=')) { + err_reasons.push("key contains '='"); + } + if key_str.is_some_and(|s| s.contains('\0')) { + err_reasons.push("key contains null character"); + } + if value_str.is_some_and(|s| s.contains('\0')) { + err_reasons.push("value contains null character"); + } + if !err_reasons.is_empty() { + gum::warn!( + target: LOG_TARGET, + %debug_id, + ?key, + ?value, + "Attempting to remove badly-formatted env var, this may cause the PVF worker to crash. Please remove it yourself. Reasons: {:?}", + err_reasons + ); + } + + std::env::remove_var(key); + } +} + +/// Provide a consistent message on worker shutdown. +fn worker_shutdown_message(debug_id: &'static str, worker_pid: u32, err: io::Error) { + gum::debug!(target: LOG_TARGET, %worker_pid, "quitting pvf worker ({}): {:?}", debug_id, err); +} + +/// Loop that runs in the CPU time monitor thread on prepare and execute jobs. Continuously wakes up +/// and then either blocks for the remaining CPU time, or returns if we exceed the CPU timeout. +/// +/// Returning `Some` indicates that we should send a `TimedOut` error to the host. Will return +/// `None` if the other thread finishes first, without us timing out. +/// +/// NOTE: Sending a `TimedOut` error to the host will cause the worker, whether preparation or +/// execution, to be killed by the host. We do not kill the process here because it would interfere +/// with the proper handling of this error. +pub fn cpu_time_monitor_loop( + cpu_time_start: ProcessTime, + timeout: Duration, + finished_rx: Receiver<()>, +) -> Option { + loop { + let cpu_time_elapsed = cpu_time_start.elapsed(); + + // Treat the timeout as CPU time, which is less subject to variance due to load. + if cpu_time_elapsed <= timeout { + // Sleep for the remaining CPU time, plus a bit to account for overhead. (And we don't + // want to wake up too often -- so, since we just want to halt the worker thread if it + // stalled, we can sleep longer than necessary.) Note that the sleep is wall clock time. + // The CPU clock may be slower than the wall clock. + let sleep_interval = timeout.saturating_sub(cpu_time_elapsed) + JOB_TIMEOUT_OVERHEAD; + match finished_rx.recv_timeout(sleep_interval) { + // Received finish signal. + Ok(()) => return None, + // Timed out, restart loop. + Err(RecvTimeoutError::Timeout) => continue, + Err(RecvTimeoutError::Disconnected) => return None, + } + } + + return Some(cpu_time_elapsed) + } +} + +/// Attempt to convert an opaque panic payload to a string. +/// +/// This is a best effort, and is not guaranteed to provide the most accurate value. +pub fn stringify_panic_payload(payload: Box) -> String { + match payload.downcast::<&'static str>() { + Ok(msg) => msg.to_string(), + Err(payload) => match payload.downcast::() { + Ok(msg) => *msg, + // At least we tried... + Err(_) => "unknown panic payload".to_string(), + }, + } +} + +/// In case of node and worker version mismatch (as a result of in-place upgrade), send `SIGTERM` +/// to the node to tear it down and prevent it from raising disputes on valid candidates. Node +/// restart should be handled by the node owner. As node exits, Unix sockets opened to workers +/// get closed by the OS and other workers receive error on socket read and also exit. Preparation +/// jobs are written to the temporary files that are renamed to real artifacts on the node side, so +/// no leftover artifacts are possible. +fn kill_parent_node_in_emergency() { + unsafe { + // SAFETY: `getpid()` never fails but may return "no-parent" (0) or "parent-init" (1) in + // some corner cases, which is checked. `kill()` never fails. + let ppid = libc::getppid(); + if ppid > 1 { + libc::kill(ppid, libc::SIGTERM); + } + } +} + +/// Functionality related to threads spawned by the workers. +/// +/// The motivation for this module is to coordinate worker threads without using async Rust. +pub mod thread { + use std::{ + panic, + sync::{Arc, Condvar, Mutex}, + thread, + time::Duration, + }; + + /// Contains the outcome of waiting on threads, or `Pending` if none are ready. + #[derive(Debug, Clone, Copy)] + pub enum WaitOutcome { + Finished, + TimedOut, + Pending, + } + + impl WaitOutcome { + pub fn is_pending(&self) -> bool { + matches!(self, Self::Pending) + } + } + + /// Helper type. + pub type Cond = Arc<(Mutex, Condvar)>; + + /// Gets a condvar initialized to `Pending`. + pub fn get_condvar() -> Cond { + Arc::new((Mutex::new(WaitOutcome::Pending), Condvar::new())) + } + + /// Runs a worker thread. Will first enable security features, and afterwards notify the threads + /// waiting on the condvar. Catches panics during execution and resumes the panics after + /// triggering the condvar, so that the waiting thread is notified on panics. + /// + /// # Returns + /// + /// Returns the thread's join handle. Calling `.join()` on it returns the result of executing + /// `f()`, as well as whether we were able to enable sandboxing. + pub fn spawn_worker_thread( + name: &str, + f: F, + cond: Cond, + outcome: WaitOutcome, + ) -> std::io::Result> + where + F: FnOnce() -> R, + F: Send + 'static + panic::UnwindSafe, + R: Send + 'static, + { + thread::Builder::new() + .name(name.into()) + .spawn(move || cond_notify_on_done(f, cond, outcome)) + } + + /// Runs a worker thread with the given stack size. See [`spawn_worker_thread`]. + pub fn spawn_worker_thread_with_stack_size( + name: &str, + f: F, + cond: Cond, + outcome: WaitOutcome, + stack_size: usize, + ) -> std::io::Result> + where + F: FnOnce() -> R, + F: Send + 'static + panic::UnwindSafe, + R: Send + 'static, + { + thread::Builder::new() + .name(name.into()) + .stack_size(stack_size) + .spawn(move || cond_notify_on_done(f, cond, outcome)) + } + + /// Runs a function, afterwards notifying the threads waiting on the condvar. Catches panics and + /// resumes them after triggering the condvar, so that the waiting thread is notified on panics. + fn cond_notify_on_done(f: F, cond: Cond, outcome: WaitOutcome) -> R + where + F: FnOnce() -> R, + F: panic::UnwindSafe, + { + let result = panic::catch_unwind(|| f()); + cond_notify_all(cond, outcome); + match result { + Ok(inner) => return inner, + Err(err) => panic::resume_unwind(err), + } + } + + /// Helper function to notify all threads waiting on this condvar. + fn cond_notify_all(cond: Cond, outcome: WaitOutcome) { + let (lock, cvar) = &*cond; + let mut flag = lock.lock().unwrap(); + if !flag.is_pending() { + // Someone else already triggered the condvar. + return + } + *flag = outcome; + cvar.notify_all(); + } + + /// Block the thread while it waits on the condvar. + pub fn wait_for_threads(cond: Cond) -> WaitOutcome { + let (lock, cvar) = &*cond; + let guard = cvar.wait_while(lock.lock().unwrap(), |flag| flag.is_pending()).unwrap(); + *guard + } + + /// Block the thread while it waits on the condvar or on a timeout. If the timeout is hit, + /// returns `None`. + #[cfg_attr(not(any(target_os = "linux", feature = "jemalloc-allocator")), allow(dead_code))] + pub fn wait_for_threads_with_timeout(cond: &Cond, dur: Duration) -> Option { + let (lock, cvar) = &**cond; + let result = cvar + .wait_timeout_while(lock.lock().unwrap(), dur, |flag| flag.is_pending()) + .unwrap(); + if result.1.timed_out() { + None + } else { + Some(*result.0) + } + } + + #[cfg(test)] + mod tests { + use super::*; + use assert_matches::assert_matches; + + #[test] + fn get_condvar_should_be_pending() { + let condvar = get_condvar(); + let outcome = *condvar.0.lock().unwrap(); + assert!(outcome.is_pending()); + } + + #[test] + fn wait_for_threads_with_timeout_return_none_on_time_out() { + let condvar = Arc::new((Mutex::new(WaitOutcome::Pending), Condvar::new())); + let outcome = wait_for_threads_with_timeout(&condvar, Duration::from_millis(100)); + assert!(outcome.is_none()); + } + + #[test] + fn wait_for_threads_with_timeout_returns_outcome() { + let condvar = Arc::new((Mutex::new(WaitOutcome::Pending), Condvar::new())); + let condvar2 = condvar.clone(); + cond_notify_all(condvar2, WaitOutcome::Finished); + let outcome = wait_for_threads_with_timeout(&condvar, Duration::from_secs(2)); + assert_matches!(outcome.unwrap(), WaitOutcome::Finished); + } + + #[test] + fn spawn_worker_thread_should_notify_on_done() { + let condvar = Arc::new((Mutex::new(WaitOutcome::Pending), Condvar::new())); + let response = + spawn_worker_thread("thread", || 2, condvar.clone(), WaitOutcome::TimedOut); + let (lock, _) = &*condvar; + let r = response.unwrap().join().unwrap(); + assert_eq!(r, 2); + assert_matches!(*lock.lock().unwrap(), WaitOutcome::TimedOut); + } + + #[test] + fn spawn_worker_should_not_change_finished_outcome() { + let condvar = Arc::new((Mutex::new(WaitOutcome::Finished), Condvar::new())); + let response = + spawn_worker_thread("thread", move || 2, condvar.clone(), WaitOutcome::TimedOut); + + let r = response.unwrap().join().unwrap(); + assert_eq!(r, 2); + assert_matches!(*condvar.0.lock().unwrap(), WaitOutcome::Finished); + } + + #[test] + fn cond_notify_on_done_should_update_wait_outcome_when_panic() { + let condvar = Arc::new((Mutex::new(WaitOutcome::Pending), Condvar::new())); + let err = panic::catch_unwind(panic::AssertUnwindSafe(|| { + cond_notify_on_done(|| panic!("test"), condvar.clone(), WaitOutcome::Finished) + })); + + assert_matches!(*condvar.0.lock().unwrap(), WaitOutcome::Finished); + assert!(err.is_err()); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::mpsc::channel; + + #[test] + fn cpu_time_monitor_loop_should_return_time_elapsed() { + let cpu_time_start = ProcessTime::now(); + let timeout = Duration::from_secs(0); + let (_tx, rx) = channel(); + let result = cpu_time_monitor_loop(cpu_time_start, timeout, rx); + assert_ne!(result, None); + } + + #[test] + fn cpu_time_monitor_loop_should_return_none() { + let cpu_time_start = ProcessTime::now(); + let timeout = Duration::from_secs(10); + let (tx, rx) = channel(); + tx.send(()).unwrap(); + let result = cpu_time_monitor_loop(cpu_time_start, timeout, rx); + assert_eq!(result, None); + } +} diff --git a/polkadot/node/core/pvf/common/src/worker/security.rs b/polkadot/node/core/pvf/common/src/worker/security.rs new file mode 100644 index 0000000000000000000000000000000000000000..6c5f96e0b5dbb3289dc237c91cc003e3b2aa37c5 --- /dev/null +++ b/polkadot/node/core/pvf/common/src/worker/security.rs @@ -0,0 +1,188 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Functionality for securing workers. +//! +//! This is needed because workers are used to compile and execute untrusted code (PVFs). + +/// To what degree landlock is enabled. It's a separate struct from `RulesetStatus` because that is +/// only available on Linux, plus this has a nicer name. +pub enum LandlockStatus { + FullyEnforced, + PartiallyEnforced, + NotEnforced, + /// Thread panicked, we don't know what the status is. + Unavailable, +} + +impl LandlockStatus { + #[cfg(target_os = "linux")] + pub fn from_ruleset_status(ruleset_status: ::landlock::RulesetStatus) -> Self { + use ::landlock::RulesetStatus::*; + match ruleset_status { + FullyEnforced => LandlockStatus::FullyEnforced, + PartiallyEnforced => LandlockStatus::PartiallyEnforced, + NotEnforced => LandlockStatus::NotEnforced, + } + } +} + +/// The [landlock] docs say it best: +/// +/// > "Landlock is a security feature available since Linux 5.13. The goal is to enable to restrict +/// ambient rights (e.g., global filesystem access) for a set of processes by creating safe security +/// sandboxes as new security layers in addition to the existing system-wide access-controls. This +/// kind of sandbox is expected to help mitigate the security impact of bugs, unexpected or +/// malicious behaviors in applications. Landlock empowers any process, including unprivileged ones, +/// to securely restrict themselves." +/// +/// [landlock]: https://docs.rs/landlock/latest/landlock/index.html +#[cfg(target_os = "linux")] +pub mod landlock { + use landlock::{Access, AccessFs, Ruleset, RulesetAttr, RulesetError, RulesetStatus, ABI}; + + /// Landlock ABI version. We use ABI V1 because: + /// + /// 1. It is supported by our reference kernel version. + /// 2. Later versions do not (yet) provide additional security. + /// + /// # Versions (June 2023) + /// + /// - Polkadot reference kernel version: 5.16+ + /// - ABI V1: 5.13 - introduces landlock, including full restrictions on file reads + /// - ABI V2: 5.19 - adds ability to configure file renaming (not used by us) + /// + /// # Determinism + /// + /// You may wonder whether we could always use the latest ABI instead of only the ABI supported + /// by the reference kernel version. It seems plausible, since landlock provides a best-effort + /// approach to enabling sandboxing. For example, if the reference version only supported V1 and + /// we were on V2, then landlock would use V2 if it was supported on the current machine, and + /// just fall back to V1 if not. + /// + /// The issue with this is indeterminacy. If half of validators were on V2 and half were on V1, + /// they may have different semantics on some PVFs. So a malicious PVF now has a new attack + /// vector: they can exploit this indeterminism between landlock ABIs! + /// + /// On the other hand we do want validators to be as secure as possible and protect their keys + /// from attackers. And, the risk with indeterminacy is low and there are other indeterminacy + /// vectors anyway. So we will only upgrade to a new ABI if either the reference kernel version + /// supports it or if it introduces some new feature that is beneficial to security. + pub const LANDLOCK_ABI: ABI = ABI::V1; + + // TODO: + /// Returns to what degree landlock is enabled with the given ABI on the current Linux + /// environment. + pub fn get_status() -> Result> { + match std::thread::spawn(|| try_restrict_thread()).join() { + Ok(Ok(status)) => Ok(status), + Ok(Err(ruleset_err)) => Err(ruleset_err.into()), + Err(_err) => Err("a panic occurred in try_restrict_thread".into()), + } + } + + /// Based on the given `status`, returns a single bool indicating whether the given landlock + /// ABI is fully enabled on the current Linux environment. + pub fn status_is_fully_enabled( + status: &Result>, + ) -> bool { + matches!(status, Ok(RulesetStatus::FullyEnforced)) + } + + /// Runs a check for landlock and returns a single bool indicating whether the given landlock + /// ABI is fully enabled on the current Linux environment. + pub fn check_is_fully_enabled() -> bool { + status_is_fully_enabled(&get_status()) + } + + /// Tries to restrict the current thread with the following landlock access controls: + /// + /// 1. all global filesystem access + /// 2. ... more may be supported in the future. + /// + /// If landlock is not supported in the current environment this is simply a noop. + /// + /// # Returns + /// + /// The status of the restriction (whether it was fully, partially, or not-at-all enforced). + pub fn try_restrict_thread() -> Result { + let status = Ruleset::new() + .handle_access(AccessFs::from_all(LANDLOCK_ABI))? + .create()? + .restrict_self()?; + Ok(status.ruleset) + } + + #[cfg(test)] + mod tests { + use super::*; + use std::{fs, io::ErrorKind, thread}; + + #[test] + fn restricted_thread_cannot_access_fs() { + // TODO: This would be nice: . + if !check_is_fully_enabled() { + return + } + + // Restricted thread cannot read from FS. + let handle = thread::spawn(|| { + // Write to a tmp file, this should succeed before landlock is applied. + let text = "foo"; + let tmpfile = tempfile::NamedTempFile::new().unwrap(); + let path = tmpfile.path(); + fs::write(path, text).unwrap(); + let s = fs::read_to_string(path).unwrap(); + assert_eq!(s, text); + + let status = try_restrict_thread().unwrap(); + if !matches!(status, RulesetStatus::FullyEnforced) { + panic!("Ruleset should be enforced since we checked if landlock is enabled"); + } + + // Try to read from the tmp file after landlock. + let result = fs::read_to_string(path); + assert!(matches!( + result, + Err(err) if matches!(err.kind(), ErrorKind::PermissionDenied) + )); + }); + + assert!(handle.join().is_ok()); + + // Restricted thread cannot write to FS. + let handle = thread::spawn(|| { + let text = "foo"; + let tmpfile = tempfile::NamedTempFile::new().unwrap(); + let path = tmpfile.path(); + + let status = try_restrict_thread().unwrap(); + if !matches!(status, RulesetStatus::FullyEnforced) { + panic!("Ruleset should be enforced since we checked if landlock is enabled"); + } + + // Try to write to the tmp file after landlock. + let result = fs::write(path, text); + assert!(matches!( + result, + Err(err) if matches!(err.kind(), ErrorKind::PermissionDenied) + )); + }); + + assert!(handle.join().is_ok()); + } + } +} diff --git a/polkadot/node/core/pvf/execute-worker/Cargo.toml b/polkadot/node/core/pvf/execute-worker/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..931ea6951a68a920660136173c028dad6a39b5d0 --- /dev/null +++ b/polkadot/node/core/pvf/execute-worker/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "polkadot-node-core-pvf-execute-worker" +description = "Polkadot crate that contains the logic for executing PVFs. Used by the polkadot-execute-worker binary." +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +cpu-time = "1.0.0" +futures = "0.3.21" +gum = { package = "tracing-gum", path = "../../../gum" } +rayon = "1.5.1" +tikv-jemalloc-ctl = { version = "0.5.0", optional = true } +tokio = { version = "1.24.2", features = ["fs", "process"] } + +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } + +polkadot-node-core-pvf-common = { path = "../common" } +polkadot-parachain = { path = "../../../../parachain" } +polkadot-primitives = { path = "../../../../primitives" } + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-maybe-compressed-blob = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[target.'cfg(target_os = "linux")'.dependencies] +tikv-jemalloc-ctl = "0.5.0" + +[features] +builder = [] diff --git a/polkadot/node/core/pvf/execute-worker/src/lib.rs b/polkadot/node/core/pvf/execute-worker/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..7a14de18a82fa392e55e91897bc9e49cc4fb7ca4 --- /dev/null +++ b/polkadot/node/core/pvf/execute-worker/src/lib.rs @@ -0,0 +1,303 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Contains the logic for executing PVFs. Used by the polkadot-execute-worker binary. + +pub use polkadot_node_core_pvf_common::executor_intf::Executor; + +// NOTE: Initializing logging in e.g. tests will not have an effect in the workers, as they are +// separate spawned processes. Run with e.g. `RUST_LOG=parachain::pvf-execute-worker=trace`. +const LOG_TARGET: &str = "parachain::pvf-execute-worker"; + +use cpu_time::ProcessTime; +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_core_pvf_common::{ + error::InternalValidationError, + execute::{Handshake, Response}, + executor_intf::NATIVE_STACK_MAX, + framed_recv, framed_send, + worker::{ + bytes_to_path, cpu_time_monitor_loop, + security::LandlockStatus, + stringify_panic_payload, + thread::{self, WaitOutcome}, + worker_event_loop, + }, +}; +use polkadot_parachain::primitives::ValidationResult; +use std::{ + path::PathBuf, + sync::{mpsc::channel, Arc}, + time::Duration, +}; +use tokio::{io, net::UnixStream}; + +// Wasmtime powers the Substrate Executor. It compiles the wasm bytecode into native code. +// That native code does not create any stacks and just reuses the stack of the thread that +// wasmtime was invoked from. +// +// Also, we configure the executor to provide the deterministic stack and that requires +// supplying the amount of the native stack space that wasm is allowed to use. This is +// realized by supplying the limit into `wasmtime::Config::max_wasm_stack`. +// +// There are quirks to that configuration knob: +// +// 1. It only limits the amount of stack space consumed by wasm but does not ensure nor check that +// the stack space is actually available. +// +// That means, if the calling thread has 1 MiB of stack space left and the wasm code consumes +// more, then the wasmtime limit will **not** trigger. Instead, the wasm code will hit the +// guard page and the Rust stack overflow handler will be triggered. That leads to an +// **abort**. +// +// 2. It cannot and does not limit the stack space consumed by Rust code. +// +// Meaning that if the wasm code leaves no stack space for Rust code, then the Rust code +// will abort and that will abort the process as well. +// +// Typically on Linux the main thread gets the stack size specified by the `ulimit` and +// typically it's configured to 8 MiB. Rust's spawned threads are 2 MiB. OTOH, the +// NATIVE_STACK_MAX is set to 256 MiB. Not nearly enough. +// +// Hence we need to increase it. The simplest way to fix that is to spawn a thread with the desired +// stack limit. +// +// The reasoning why we pick this particular size is: +// +// The default Rust thread stack limit 2 MiB + 256 MiB wasm stack. +/// The stack size for the execute thread. +pub const EXECUTE_THREAD_STACK_SIZE: usize = 2 * 1024 * 1024 + NATIVE_STACK_MAX as usize; + +async fn recv_handshake(stream: &mut UnixStream) -> io::Result { + let handshake_enc = framed_recv(stream).await?; + let handshake = Handshake::decode(&mut &handshake_enc[..]).map_err(|_| { + io::Error::new( + io::ErrorKind::Other, + "execute pvf recv_handshake: failed to decode Handshake".to_owned(), + ) + })?; + Ok(handshake) +} + +async fn recv_request(stream: &mut UnixStream) -> io::Result<(PathBuf, Vec, Duration)> { + let artifact_path = framed_recv(stream).await?; + let artifact_path = bytes_to_path(&artifact_path).ok_or_else(|| { + io::Error::new( + io::ErrorKind::Other, + "execute pvf recv_request: non utf-8 artifact path".to_string(), + ) + })?; + let params = framed_recv(stream).await?; + let execution_timeout = framed_recv(stream).await?; + let execution_timeout = Duration::decode(&mut &execution_timeout[..]).map_err(|_| { + io::Error::new( + io::ErrorKind::Other, + "execute pvf recv_request: failed to decode duration".to_string(), + ) + })?; + Ok((artifact_path, params, execution_timeout)) +} + +async fn send_response(stream: &mut UnixStream, response: Response) -> io::Result<()> { + framed_send(stream, &response.encode()).await +} + +/// The entrypoint that the spawned execute worker should start with. +/// +/// # Parameters +/// +/// The `socket_path` specifies the path to the socket used to communicate with the host. The +/// `node_version`, if `Some`, is checked against the worker version. A mismatch results in +/// immediate worker termination. `None` is used for tests and in other situations when version +/// check is not necessary. +pub fn worker_entrypoint( + socket_path: &str, + node_version: Option<&str>, + worker_version: Option<&str>, +) { + worker_event_loop( + "execute", + socket_path, + node_version, + worker_version, + |mut stream| async move { + let worker_pid = std::process::id(); + + let handshake = recv_handshake(&mut stream).await?; + let executor = Executor::new(handshake.executor_params).map_err(|e| { + io::Error::new(io::ErrorKind::Other, format!("cannot create executor: {}", e)) + })?; + + loop { + let (artifact_path, params, execution_timeout) = recv_request(&mut stream).await?; + gum::debug!( + target: LOG_TARGET, + %worker_pid, + "worker: validating artifact {}", + artifact_path.display(), + ); + + // Get the artifact bytes. + // + // We do this outside the thread so that we can lock down filesystem access there. + let compiled_artifact_blob = match std::fs::read(artifact_path) { + Ok(bytes) => bytes, + Err(err) => { + let response = Response::InternalError( + InternalValidationError::CouldNotOpenFile(err.to_string()), + ); + send_response(&mut stream, response).await?; + continue + }, + }; + + // Conditional variable to notify us when a thread is done. + let condvar = thread::get_condvar(); + + let cpu_time_start = ProcessTime::now(); + + // Spawn a new thread that runs the CPU time monitor. + let (cpu_time_monitor_tx, cpu_time_monitor_rx) = channel::<()>(); + let cpu_time_monitor_thread = thread::spawn_worker_thread( + "cpu time monitor thread", + move || { + cpu_time_monitor_loop( + cpu_time_start, + execution_timeout, + cpu_time_monitor_rx, + ) + }, + Arc::clone(&condvar), + WaitOutcome::TimedOut, + )?; + let executor_2 = executor.clone(); + let execute_thread = thread::spawn_worker_thread_with_stack_size( + "execute thread", + move || { + // Try to enable landlock. + #[cfg(target_os = "linux")] + let landlock_status = polkadot_node_core_pvf_common::worker::security::landlock::try_restrict_thread() + .map(LandlockStatus::from_ruleset_status) + .map_err(|e| e.to_string()); + #[cfg(not(target_os = "linux"))] + let landlock_status: Result = Ok(LandlockStatus::NotEnforced); + + ( + validate_using_artifact( + &compiled_artifact_blob, + ¶ms, + executor_2, + cpu_time_start, + ), + landlock_status, + ) + }, + Arc::clone(&condvar), + WaitOutcome::Finished, + EXECUTE_THREAD_STACK_SIZE, + )?; + + let outcome = thread::wait_for_threads(condvar); + + let response = match outcome { + WaitOutcome::Finished => { + let _ = cpu_time_monitor_tx.send(()); + let (result, landlock_status) = execute_thread.join().unwrap_or_else(|e| { + ( + Response::Panic(stringify_panic_payload(e)), + Ok(LandlockStatus::Unavailable), + ) + }); + + // Log if landlock threw an error. + if let Err(err) = landlock_status { + gum::warn!( + target: LOG_TARGET, + %worker_pid, + "error enabling landlock: {}", + err + ); + } + + result + }, + // If the CPU thread is not selected, we signal it to end, the join handle is + // dropped and the thread will finish in the background. + WaitOutcome::TimedOut => { + match cpu_time_monitor_thread.join() { + Ok(Some(cpu_time_elapsed)) => { + // Log if we exceed the timeout and the other thread hasn't + // finished. + gum::warn!( + target: LOG_TARGET, + %worker_pid, + "execute job took {}ms cpu time, exceeded execute timeout {}ms", + cpu_time_elapsed.as_millis(), + execution_timeout.as_millis(), + ); + Response::TimedOut + }, + Ok(None) => Response::InternalError( + InternalValidationError::CpuTimeMonitorThread( + "error communicating over finished channel".into(), + ), + ), + Err(e) => Response::InternalError( + InternalValidationError::CpuTimeMonitorThread( + stringify_panic_payload(e), + ), + ), + } + }, + WaitOutcome::Pending => unreachable!( + "we run wait_while until the outcome is no longer pending; qed" + ), + }; + + send_response(&mut stream, response).await?; + } + }, + ); +} + +fn validate_using_artifact( + compiled_artifact_blob: &[u8], + params: &[u8], + executor: Executor, + cpu_time_start: ProcessTime, +) -> Response { + let descriptor_bytes = match unsafe { + // SAFETY: this should be safe since the compiled artifact passed here comes from the + // file created by the prepare workers. These files are obtained by calling + // [`executor_intf::prepare`]. + executor.execute(compiled_artifact_blob, params) + } { + Err(err) => return Response::format_invalid("execute", &err), + Ok(d) => d, + }; + + let result_descriptor = match ValidationResult::decode(&mut &descriptor_bytes[..]) { + Err(err) => + return Response::format_invalid("validation result decoding failed", &err.to_string()), + Ok(r) => r, + }; + + // Include the decoding in the measured time, to prevent any potential attacks exploiting some + // bug in decoding. + let duration = cpu_time_start.elapsed(); + + Response::Ok { result_descriptor, duration } +} diff --git a/polkadot/node/core/pvf/prepare-worker/Cargo.toml b/polkadot/node/core/pvf/prepare-worker/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..9ee009de44bb95f9da22f4e146bc2ca497967caf --- /dev/null +++ b/polkadot/node/core/pvf/prepare-worker/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "polkadot-node-core-pvf-prepare-worker" +description = "Polkadot crate that contains the logic for preparing PVFs. Used by the polkadot-prepare-worker binary." +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +gum = { package = "tracing-gum", path = "../../../gum" } +libc = "0.2.139" +rayon = "1.5.1" +tikv-jemalloc-ctl = { version = "0.5.0", optional = true } +tokio = { version = "1.24.2", features = ["fs", "process"] } + +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } + +polkadot-node-core-pvf-common = { path = "../common" } +polkadot-parachain = { path = "../../../../parachain" } +polkadot-primitives = { path = "../../../../primitives" } + +sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-executor-common = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-executor-wasmtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-maybe-compressed-blob = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[target.'cfg(target_os = "linux")'.dependencies] +tikv-jemalloc-ctl = "0.5.0" + +[features] +builder = [] +jemalloc-allocator = ["dep:tikv-jemalloc-ctl"] diff --git a/polkadot/node/core/pvf/prepare-worker/src/executor_intf.rs b/polkadot/node/core/pvf/prepare-worker/src/executor_intf.rs new file mode 100644 index 0000000000000000000000000000000000000000..1f88f6a6dd6e9a07b99c4832bd3f4dda1a71cf20 --- /dev/null +++ b/polkadot/node/core/pvf/prepare-worker/src/executor_intf.rs @@ -0,0 +1,42 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Interface to the Substrate Executor + +use polkadot_node_core_pvf_common::executor_intf::params_to_wasmtime_semantics; +use polkadot_primitives::ExecutorParams; +use sc_executor_common::runtime_blob::RuntimeBlob; + +/// Runs the prevalidation on the given code. Returns a [`RuntimeBlob`] if it succeeds. +pub fn prevalidate(code: &[u8]) -> Result { + let blob = RuntimeBlob::new(code)?; + // It's assumed this function will take care of any prevalidation logic + // that needs to be done. + // + // Do nothing for now. + Ok(blob) +} + +/// Runs preparation on the given runtime blob. If successful, it returns a serialized compiled +/// artifact which can then be used to pass into `Executor::execute` after writing it to the disk. +pub fn prepare( + blob: RuntimeBlob, + executor_params: &ExecutorParams, +) -> Result, sc_executor_common::error::WasmError> { + let semantics = params_to_wasmtime_semantics(executor_params) + .map_err(|e| sc_executor_common::error::WasmError::Other(e))?; + sc_executor_wasmtime::prepare_runtime_artifact(blob, &semantics) +} diff --git a/polkadot/node/core/pvf/prepare-worker/src/lib.rs b/polkadot/node/core/pvf/prepare-worker/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..caa7d33df12adfc67440caf3a9d68a65257edf99 --- /dev/null +++ b/polkadot/node/core/pvf/prepare-worker/src/lib.rs @@ -0,0 +1,338 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Contains the logic for preparing PVFs. Used by the polkadot-prepare-worker binary. + +mod executor_intf; +mod memory_stats; + +pub use executor_intf::{prepare, prevalidate}; + +// NOTE: Initializing logging in e.g. tests will not have an effect in the workers, as they are +// separate spawned processes. Run with e.g. `RUST_LOG=parachain::pvf-prepare-worker=trace`. +const LOG_TARGET: &str = "parachain::pvf-prepare-worker"; + +#[cfg(target_os = "linux")] +use crate::memory_stats::max_rss_stat::{extract_max_rss_stat, get_max_rss_thread}; +#[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] +use crate::memory_stats::memory_tracker::{get_memory_tracker_loop_stats, memory_tracker_loop}; +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_core_pvf_common::{ + error::{PrepareError, PrepareResult}, + executor_intf::Executor, + framed_recv, framed_send, + prepare::{MemoryStats, PrepareJobKind, PrepareStats}, + pvf::PvfPrepData, + worker::{ + bytes_to_path, cpu_time_monitor_loop, + security::LandlockStatus, + stringify_panic_payload, + thread::{self, WaitOutcome}, + worker_event_loop, + }, + ProcessTime, +}; +use polkadot_primitives::ExecutorParams; +use std::{ + path::PathBuf, + sync::{mpsc::channel, Arc}, + time::Duration, +}; +use tokio::{io, net::UnixStream}; + +/// Contains the bytes for a successfully compiled artifact. +pub struct CompiledArtifact(Vec); + +impl CompiledArtifact { + /// Creates a `CompiledArtifact`. + pub fn new(code: Vec) -> Self { + Self(code) + } +} + +impl AsRef<[u8]> for CompiledArtifact { + fn as_ref(&self) -> &[u8] { + self.0.as_slice() + } +} + +async fn recv_request(stream: &mut UnixStream) -> io::Result<(PvfPrepData, PathBuf)> { + let pvf = framed_recv(stream).await?; + let pvf = PvfPrepData::decode(&mut &pvf[..]).map_err(|e| { + io::Error::new( + io::ErrorKind::Other, + format!("prepare pvf recv_request: failed to decode PvfPrepData: {}", e), + ) + })?; + let tmp_file = framed_recv(stream).await?; + let tmp_file = bytes_to_path(&tmp_file).ok_or_else(|| { + io::Error::new( + io::ErrorKind::Other, + "prepare pvf recv_request: non utf-8 artifact path".to_string(), + ) + })?; + Ok((pvf, tmp_file)) +} + +async fn send_response(stream: &mut UnixStream, result: PrepareResult) -> io::Result<()> { + framed_send(stream, &result.encode()).await +} + +/// The entrypoint that the spawned prepare worker should start with. +/// +/// # Parameters +/// +/// The `socket_path` specifies the path to the socket used to communicate with the host. The +/// `node_version`, if `Some`, is checked against the worker version. A mismatch results in +/// immediate worker termination. `None` is used for tests and in other situations when version +/// check is not necessary. +/// +/// # Flow +/// +/// This runs the following in a loop: +/// +/// 1. Get the code and parameters for preparation from the host. +/// +/// 2. Start a memory tracker in a separate thread. +/// +/// 3. Start the CPU time monitor loop and the actual preparation in two separate threads. +/// +/// 4. Wait on the two threads created in step 3. +/// +/// 5. Stop the memory tracker and get the stats. +/// +/// 6. If compilation succeeded, write the compiled artifact into a temporary file. +/// +/// 7. Send the result of preparation back to the host. If any error occurred in the above steps, we +/// send that in the `PrepareResult`. +pub fn worker_entrypoint( + socket_path: &str, + node_version: Option<&str>, + worker_version: Option<&str>, +) { + worker_event_loop( + "prepare", + socket_path, + node_version, + worker_version, + |mut stream| async move { + let worker_pid = std::process::id(); + + loop { + let (pvf, temp_artifact_dest) = recv_request(&mut stream).await?; + gum::debug!( + target: LOG_TARGET, + %worker_pid, + "worker: preparing artifact", + ); + + let preparation_timeout = pvf.prep_timeout(); + let prepare_job_kind = pvf.prep_kind(); + let executor_params = (*pvf.executor_params()).clone(); + + // Conditional variable to notify us when a thread is done. + let condvar = thread::get_condvar(); + + // Run the memory tracker in a regular, non-worker thread. + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + let condvar_memory = Arc::clone(&condvar); + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + let memory_tracker_thread = std::thread::spawn(|| memory_tracker_loop(condvar_memory)); + + let cpu_time_start = ProcessTime::now(); + + // Spawn a new thread that runs the CPU time monitor. + let (cpu_time_monitor_tx, cpu_time_monitor_rx) = channel::<()>(); + let cpu_time_monitor_thread = thread::spawn_worker_thread( + "cpu time monitor thread", + move || { + cpu_time_monitor_loop( + cpu_time_start, + preparation_timeout, + cpu_time_monitor_rx, + ) + }, + Arc::clone(&condvar), + WaitOutcome::TimedOut, + )?; + // Spawn another thread for preparation. + let prepare_thread = thread::spawn_worker_thread( + "prepare thread", + move || { + // Try to enable landlock. + #[cfg(target_os = "linux")] + let landlock_status = polkadot_node_core_pvf_common::worker::security::landlock::try_restrict_thread() + .map(LandlockStatus::from_ruleset_status) + .map_err(|e| e.to_string()); + #[cfg(not(target_os = "linux"))] + let landlock_status: Result = Ok(LandlockStatus::NotEnforced); + + #[allow(unused_mut)] + let mut result = prepare_artifact(pvf, cpu_time_start); + + // Get the `ru_maxrss` stat. If supported, call getrusage for the thread. + #[cfg(target_os = "linux")] + let mut result = result + .map(|(artifact, elapsed)| (artifact, elapsed, get_max_rss_thread())); + + // If we are pre-checking, check for runtime construction errors. + // + // As pre-checking is more strict than just preparation in terms of memory + // and time, it is okay to do extra checks here. This takes negligible time + // anyway. + if let PrepareJobKind::Prechecking = prepare_job_kind { + result = result.and_then(|output| { + runtime_construction_check(output.0.as_ref(), executor_params)?; + Ok(output) + }); + } + + (result, landlock_status) + }, + Arc::clone(&condvar), + WaitOutcome::Finished, + )?; + + let outcome = thread::wait_for_threads(condvar); + + let result = match outcome { + WaitOutcome::Finished => { + let _ = cpu_time_monitor_tx.send(()); + + match prepare_thread.join().unwrap_or_else(|err| { + ( + Err(PrepareError::Panic(stringify_panic_payload(err))), + Ok(LandlockStatus::Unavailable), + ) + }) { + (Err(err), _) => { + // Serialized error will be written into the socket. + Err(err) + }, + (Ok(ok), landlock_status) => { + #[cfg(not(target_os = "linux"))] + let (artifact, cpu_time_elapsed) = ok; + #[cfg(target_os = "linux")] + let (artifact, cpu_time_elapsed, max_rss) = ok; + + // Stop the memory stats worker and get its observed memory stats. + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + let memory_tracker_stats = get_memory_tracker_loop_stats(memory_tracker_thread, worker_pid) + .await; + let memory_stats = MemoryStats { + #[cfg(any( + target_os = "linux", + feature = "jemalloc-allocator" + ))] + memory_tracker_stats, + #[cfg(target_os = "linux")] + max_rss: extract_max_rss_stat(max_rss, worker_pid), + }; + + // Log if landlock threw an error. + if let Err(err) = landlock_status { + gum::warn!( + target: LOG_TARGET, + %worker_pid, + "error enabling landlock: {}", + err + ); + } + + // Write the serialized artifact into a temp file. + // + // PVF host only keeps artifacts statuses in its memory, + // successfully compiled code gets stored on the disk (and + // consequently deserialized by execute-workers). The prepare worker + // is only required to send `Ok` to the pool to indicate the + // success. + + gum::debug!( + target: LOG_TARGET, + %worker_pid, + "worker: writing artifact to {}", + temp_artifact_dest.display(), + ); + tokio::fs::write(&temp_artifact_dest, &artifact).await?; + + Ok(PrepareStats { cpu_time_elapsed, memory_stats }) + }, + } + }, + // If the CPU thread is not selected, we signal it to end, the join handle is + // dropped and the thread will finish in the background. + WaitOutcome::TimedOut => { + match cpu_time_monitor_thread.join() { + Ok(Some(cpu_time_elapsed)) => { + // Log if we exceed the timeout and the other thread hasn't + // finished. + gum::warn!( + target: LOG_TARGET, + %worker_pid, + "prepare job took {}ms cpu time, exceeded prepare timeout {}ms", + cpu_time_elapsed.as_millis(), + preparation_timeout.as_millis(), + ); + Err(PrepareError::TimedOut) + }, + Ok(None) => Err(PrepareError::IoErr( + "error communicating over closed channel".into(), + )), + // Errors in this thread are independent of the PVF. + Err(err) => Err(PrepareError::IoErr(stringify_panic_payload(err))), + } + }, + WaitOutcome::Pending => unreachable!( + "we run wait_while until the outcome is no longer pending; qed" + ), + }; + + send_response(&mut stream, result).await?; + } + }, + ); +} + +fn prepare_artifact( + pvf: PvfPrepData, + cpu_time_start: ProcessTime, +) -> Result<(CompiledArtifact, Duration), PrepareError> { + let blob = match prevalidate(&pvf.code()) { + Err(err) => return Err(PrepareError::Prevalidation(format!("{:?}", err))), + Ok(b) => b, + }; + + match prepare(blob, &pvf.executor_params()) { + Ok(compiled_artifact) => Ok(CompiledArtifact::new(compiled_artifact)), + Err(err) => Err(PrepareError::Preparation(format!("{:?}", err))), + } + .map(|artifact| (artifact, cpu_time_start.elapsed())) +} + +/// Try constructing the runtime to catch any instantiation errors during pre-checking. +fn runtime_construction_check( + artifact_bytes: &[u8], + executor_params: ExecutorParams, +) -> Result<(), PrepareError> { + let executor = Executor::new(executor_params) + .map_err(|e| PrepareError::RuntimeConstruction(format!("cannot create executor: {}", e)))?; + + // SAFETY: We just compiled this artifact. + let result = unsafe { executor.create_runtime_from_bytes(&artifact_bytes) }; + result + .map(|_runtime| ()) + .map_err(|err| PrepareError::RuntimeConstruction(format!("{:?}", err))) +} diff --git a/polkadot/node/core/pvf/prepare-worker/src/memory_stats.rs b/polkadot/node/core/pvf/prepare-worker/src/memory_stats.rs new file mode 100644 index 0000000000000000000000000000000000000000..7904dfa9cb8857d34c1d0f84040caec3692e16bf --- /dev/null +++ b/polkadot/node/core/pvf/prepare-worker/src/memory_stats.rs @@ -0,0 +1,196 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Memory stats for preparation. +//! +//! Right now we gather three measurements: +//! +//! - `ru_maxrss` (resident set size) from `getrusage`. +//! - `resident` memory stat provided by `tikv-malloc-ctl`. +//! - `allocated` memory stat also from `tikv-malloc-ctl`. +//! +//! Currently we are only logging these for the purposes of gathering data. In the future, we may +//! use these stats to reject PVFs during pre-checking. See +//! for more +//! background. + +/// Module for the memory tracker. The memory tracker runs in its own thread, where it polls memory +/// usage at an interval. +/// +/// NOTE: Requires jemalloc enabled. +#[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] +pub mod memory_tracker { + use crate::LOG_TARGET; + use polkadot_node_core_pvf_common::{ + prepare::MemoryAllocationStats, + worker::{stringify_panic_payload, thread}, + }; + use std::{thread::JoinHandle, time::Duration}; + use tikv_jemalloc_ctl::{epoch, stats, Error}; + + #[derive(Clone)] + struct MemoryAllocationTracker { + epoch: tikv_jemalloc_ctl::epoch_mib, + allocated: stats::allocated_mib, + resident: stats::resident_mib, + } + + impl MemoryAllocationTracker { + pub fn new() -> Result { + Ok(Self { + epoch: epoch::mib()?, + allocated: stats::allocated::mib()?, + resident: stats::resident::mib()?, + }) + } + + pub fn snapshot(&self) -> Result { + // update stats by advancing the allocation epoch + self.epoch.advance()?; + + // Convert to `u64`, as `usize` is not `Encode`able. + let allocated = self.allocated.read()? as u64; + let resident = self.resident.read()? as u64; + Ok(MemoryAllocationStats { allocated, resident }) + } + } + + /// Runs a thread in the background that observes memory statistics. The goal is to try to get + /// accurate stats during preparation. + /// + /// # Algorithm + /// + /// 1. Create the memory tracker. + /// + /// 2. Sleep for some short interval. Whenever we wake up, take a snapshot by updating the + /// allocation epoch. + /// + /// 3. When we are notified that preparation has completed, take one last snapshot and return + /// the maximum observed values. + /// + /// # Errors + /// + /// For simplicity, any errors are returned as a string. As this is not a critical component, + /// errors are used for informational purposes (logging) only. + pub fn memory_tracker_loop(condvar: thread::Cond) -> Result { + // NOTE: This doesn't need to be too fine-grained since preparation currently takes 3-10s or + // more. Apart from that, there is not really a science to this number. + const POLL_INTERVAL: Duration = Duration::from_millis(100); + + let tracker = MemoryAllocationTracker::new().map_err(|err| err.to_string())?; + let mut max_stats = MemoryAllocationStats::default(); + + let mut update_stats = || -> Result<(), String> { + let current_stats = tracker.snapshot().map_err(|err| err.to_string())?; + if current_stats.resident > max_stats.resident { + max_stats.resident = current_stats.resident; + } + if current_stats.allocated > max_stats.allocated { + max_stats.allocated = current_stats.allocated; + } + Ok(()) + }; + + loop { + // Take a snapshot and update the max stats. + update_stats()?; + + // Sleep for the poll interval, or wake up if the condvar is triggered. Note that + // `wait_timeout_while` is documented as not being very precise or reliable, which is + // fine here -- see note above. + match thread::wait_for_threads_with_timeout(&condvar, POLL_INTERVAL) { + Some(_outcome) => { + update_stats()?; + return Ok(max_stats) + }, + None => continue, + } + } + } + + /// Helper function to get the stats from the memory tracker. Helps isolate this error handling. + pub async fn get_memory_tracker_loop_stats( + thread: JoinHandle>, + worker_pid: u32, + ) -> Option { + match thread.join() { + Ok(Ok(stats)) => Some(stats), + Ok(Err(err)) => { + gum::warn!( + target: LOG_TARGET, + %worker_pid, + "worker: error occurred in the memory tracker thread: {}", err + ); + None + }, + Err(err) => { + gum::warn!( + target: LOG_TARGET, + %worker_pid, + "worker: error joining on memory tracker thread: {}", stringify_panic_payload(err) + ); + None + }, + } + } +} + +/// Module for dealing with the `ru_maxrss` (peak resident memory) stat from `getrusage`. +/// +/// NOTE: `getrusage` with the `RUSAGE_THREAD` parameter is only supported on Linux. `RUSAGE_SELF` +/// works on MacOS, but we need to get the max rss only for the preparation thread. Gettng it for +/// the current process would conflate the stats of previous jobs run by the process. +#[cfg(target_os = "linux")] +pub mod max_rss_stat { + use crate::LOG_TARGET; + use core::mem::MaybeUninit; + use libc::{getrusage, rusage, RUSAGE_THREAD}; + use std::io; + + /// Get the rusage stats for the current thread. + fn getrusage_thread() -> io::Result { + let mut result: MaybeUninit = MaybeUninit::zeroed(); + + // SAFETY: `result` is a valid pointer, so calling this is safe. + if unsafe { getrusage(RUSAGE_THREAD, result.as_mut_ptr()) } == -1 { + return Err(io::Error::last_os_error()) + } + + // SAFETY: `result` was successfully initialized by `getrusage`. + unsafe { Ok(result.assume_init()) } + } + + /// Gets the `ru_maxrss` for the current thread. + pub fn get_max_rss_thread() -> io::Result { + // `c_long` is either `i32` or `i64` depending on architecture. `i64::from` always works. + getrusage_thread().map(|rusage| i64::from(rusage.ru_maxrss)) + } + + /// Extracts the max_rss stat and logs any error. + pub fn extract_max_rss_stat(max_rss: io::Result, worker_pid: u32) -> Option { + max_rss + .map_err(|err| { + gum::warn!( + target: LOG_TARGET, + %worker_pid, + "error getting `ru_maxrss` in preparation thread: {}", + err + ); + err + }) + .ok() + } +} diff --git a/polkadot/node/core/pvf/src/artifacts.rs b/polkadot/node/core/pvf/src/artifacts.rs new file mode 100644 index 0000000000000000000000000000000000000000..a180af15db27763542e318753f016a9645a2726a --- /dev/null +++ b/polkadot/node/core/pvf/src/artifacts.rs @@ -0,0 +1,319 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! PVF artifacts (final compiled code blobs). +//! +//! # Lifecycle of an artifact +//! +//! 1. During node start-up, the artifacts cache is cleaned up. This means that all local artifacts +//! stored on-disk are cleared, and we start with an empty [`Artifacts`] table. +//! +//! 2. In order to be executed, a PVF should be prepared first. This means that artifacts should +//! have an [`ArtifactState::Prepared`] entry for that artifact in the table. If not, the +//! preparation process kicks in. The execution request is stashed until after the preparation is +//! done, and the artifact state in the host is set to [`ArtifactState::Preparing`]. Preparation +//! goes through the preparation queue and the pool. +//! +//! 1. If the artifact is already being processed, we add another execution request to the +//! existing preparation job, without starting a new one. +//! +//! 2. Note that if the state is [`ArtifactState::FailedToProcess`], we usually do not retry +//! preparation, though we may under certain conditions. +//! +//! 3. The pool gets an available worker and instructs it to work on the given PVF. The worker +//! starts compilation. When the worker finishes successfully, it writes the serialized artifact +//! into a temporary file and notifies the host that it's done. The host atomically moves +//! (renames) the temporary file to the destination filename of the artifact. +//! +//! 4. If the worker concluded successfully or returned an error, then the pool notifies the queue. +//! In both cases, the queue reports to the host that the result is ready. +//! +//! 5. The host will react by changing the artifact state to either [`ArtifactState::Prepared`] or +//! [`ArtifactState::FailedToProcess`] for the PVF in question. On success, the +//! `last_time_needed` will be set to the current time. It will also dispatch the pending +//! execution requests. +//! +//! 6. On success, the execution request will come through the execution queue and ultimately be +//! processed by an execution worker. When this worker receives the request, it will read the +//! requested artifact. If it doesn't exist it reports an internal error. A request for execution +//! will bump the `last_time_needed` to the current time. +//! +//! 7. There is a separate process for pruning the prepared artifacts whose `last_time_needed` is +//! older by a predefined parameter. This process is run very rarely (say, once a day). Once the +//! artifact is expired it is removed from disk eagerly atomically. + +use crate::host::PrepareResultSender; +use always_assert::always; +use polkadot_node_core_pvf_common::{error::PrepareError, prepare::PrepareStats, pvf::PvfPrepData}; +use polkadot_parachain::primitives::ValidationCodeHash; +use polkadot_primitives::ExecutorParamsHash; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, + time::{Duration, SystemTime}, +}; + +/// Identifier of an artifact. Encodes a code hash of the PVF and a hash of executor parameter set. +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ArtifactId { + pub(crate) code_hash: ValidationCodeHash, + pub(crate) executor_params_hash: ExecutorParamsHash, +} + +impl ArtifactId { + const PREFIX: &'static str = "wasmtime_"; + + /// Creates a new artifact ID with the given hash. + pub fn new(code_hash: ValidationCodeHash, executor_params_hash: ExecutorParamsHash) -> Self { + Self { code_hash, executor_params_hash } + } + + /// Returns an artifact ID that corresponds to the PVF with given executor params. + pub fn from_pvf_prep_data(pvf: &PvfPrepData) -> Self { + Self::new(pvf.code_hash(), pvf.executor_params().hash()) + } + + /// Tries to recover the artifact id from the given file name. + #[cfg(test)] + pub fn from_file_name(file_name: &str) -> Option { + use polkadot_core_primitives::Hash; + use std::str::FromStr as _; + + let file_name = file_name.strip_prefix(Self::PREFIX)?; + let (code_hash_str, executor_params_hash_str) = file_name.split_once('_')?; + let code_hash = Hash::from_str(code_hash_str).ok()?.into(); + let executor_params_hash = + ExecutorParamsHash::from_hash(Hash::from_str(executor_params_hash_str).ok()?); + + Some(Self { code_hash, executor_params_hash }) + } + + /// Returns the expected path to this artifact given the root of the cache. + pub fn path(&self, cache_path: &Path) -> PathBuf { + let file_name = + format!("{}{:#x}_{:#x}", Self::PREFIX, self.code_hash, self.executor_params_hash); + cache_path.join(file_name) + } +} + +/// A bundle of the artifact ID and the path. +/// +/// Rationale for having this is two-fold: +/// +/// - While we can derive the artifact path from the artifact id, it makes sense to carry it around +/// sometimes to avoid extra work. +/// - At the same time, carrying only path limiting the ability for logging. +#[derive(Debug, Clone)] +pub struct ArtifactPathId { + pub(crate) id: ArtifactId, + pub(crate) path: PathBuf, +} + +impl ArtifactPathId { + pub(crate) fn new(artifact_id: ArtifactId, cache_path: &Path) -> Self { + Self { path: artifact_id.path(cache_path), id: artifact_id } + } +} + +pub enum ArtifactState { + /// The artifact is ready to be used by the executor. + /// + /// That means that the artifact should be accessible through the path obtained by the artifact + /// id (unless, it was removed externally). + Prepared { + /// The time when the artifact was last needed. + /// + /// This is updated when we get the heads up for this artifact or when we just discover + /// this file. + last_time_needed: SystemTime, + /// Stats produced by successful preparation. + prepare_stats: PrepareStats, + }, + /// A task to prepare this artifact is scheduled. + Preparing { + /// List of result senders that are waiting for a response. + waiting_for_response: Vec, + /// The number of times this artifact has failed to prepare. + num_failures: u32, + }, + /// The code couldn't be compiled due to an error. Such artifacts + /// never reach the executor and stay in the host's memory. + FailedToProcess { + /// Keep track of the last time that processing this artifact failed. + last_time_failed: SystemTime, + /// The number of times this artifact has failed to prepare. + num_failures: u32, + /// The last error encountered for preparation. + error: PrepareError, + }, +} + +/// A container of all known artifact ids and their states. +pub struct Artifacts { + artifacts: HashMap, +} + +impl Artifacts { + /// Initialize a blank cache at the given path. This will clear everything present at the + /// given path, to be populated over time. + /// + /// The recognized artifacts will be filled in the table and unrecognized will be removed. + pub async fn new(cache_path: &Path) -> Self { + // Make sure that the cache path directory and all its parents are created. + // First delete the entire cache. Nodes are long-running so this should populate shortly. + let _ = tokio::fs::remove_dir_all(cache_path).await; + let _ = tokio::fs::create_dir_all(cache_path).await; + + Self { artifacts: HashMap::new() } + } + + #[cfg(test)] + pub(crate) fn empty() -> Self { + Self { artifacts: HashMap::new() } + } + + /// Returns the state of the given artifact by its ID. + pub fn artifact_state_mut(&mut self, artifact_id: &ArtifactId) -> Option<&mut ArtifactState> { + self.artifacts.get_mut(artifact_id) + } + + /// Inform the table about the artifact with the given ID. The state will be set to "preparing". + /// + /// This function must be used only for brand-new artifacts and should never be used for + /// replacing existing ones. + pub fn insert_preparing( + &mut self, + artifact_id: ArtifactId, + waiting_for_response: Vec, + ) { + // See the precondition. + always!(self + .artifacts + .insert(artifact_id, ArtifactState::Preparing { waiting_for_response, num_failures: 0 }) + .is_none()); + } + + /// Insert an artifact with the given ID as "prepared". + /// + /// This function must be used only for brand-new artifacts and should never be used for + /// replacing existing ones. + #[cfg(test)] + pub fn insert_prepared( + &mut self, + artifact_id: ArtifactId, + last_time_needed: SystemTime, + prepare_stats: PrepareStats, + ) { + // See the precondition. + always!(self + .artifacts + .insert(artifact_id, ArtifactState::Prepared { last_time_needed, prepare_stats }) + .is_none()); + } + + /// Remove and retrieve the artifacts from the table that are older than the supplied + /// Time-To-Live. + pub fn prune(&mut self, artifact_ttl: Duration) -> Vec { + let now = SystemTime::now(); + + let mut to_remove = vec![]; + for (k, v) in self.artifacts.iter() { + if let ArtifactState::Prepared { last_time_needed, .. } = *v { + if now + .duration_since(last_time_needed) + .map(|age| age > artifact_ttl) + .unwrap_or(false) + { + to_remove.push(k.clone()); + } + } + } + + for artifact in &to_remove { + self.artifacts.remove(artifact); + } + + to_remove + } +} + +#[cfg(test)] +mod tests { + use super::{ArtifactId, Artifacts}; + use polkadot_primitives::ExecutorParamsHash; + use sp_core::H256; + use std::{path::Path, str::FromStr}; + + #[test] + fn from_file_name() { + assert!(ArtifactId::from_file_name("").is_none()); + assert!(ArtifactId::from_file_name("junk").is_none()); + + assert_eq!( + ArtifactId::from_file_name( + "wasmtime_0x0022800000000000000000000000000000000000000000000000000000000000_0x0033900000000000000000000000000000000000000000000000000000000000" + ), + Some(ArtifactId::new( + hex_literal::hex![ + "0022800000000000000000000000000000000000000000000000000000000000" + ] + .into(), + ExecutorParamsHash::from_hash(sp_core::H256(hex_literal::hex![ + "0033900000000000000000000000000000000000000000000000000000000000" + ])), + )), + ); + } + + #[test] + fn path() { + let path = Path::new("/test"); + let hash = + H256::from_str("1234567890123456789012345678901234567890123456789012345678901234") + .unwrap(); + + assert_eq!( + ArtifactId::new(hash.into(), ExecutorParamsHash::from_hash(hash)).path(path).to_str(), + Some( + "/test/wasmtime_0x1234567890123456789012345678901234567890123456789012345678901234_0x1234567890123456789012345678901234567890123456789012345678901234" + ), + ); + } + + #[tokio::test] + async fn artifacts_removes_cache_on_startup() { + let fake_cache_path = crate::worker_intf::tmpfile("test-cache").await.unwrap(); + let fake_artifact_path = { + let mut p = fake_cache_path.clone(); + p.push("wasmtime_0x1234567890123456789012345678901234567890123456789012345678901234"); + p + }; + + // create a tmp cache with 1 artifact. + + std::fs::create_dir_all(&fake_cache_path).unwrap(); + std::fs::File::create(fake_artifact_path).unwrap(); + + // this should remove it and re-create. + + let p = &fake_cache_path; + Artifacts::new(p).await; + + assert_eq!(std::fs::read_dir(&fake_cache_path).unwrap().count(), 0); + + std::fs::remove_dir_all(fake_cache_path).unwrap(); + } +} diff --git a/polkadot/node/core/pvf/src/error.rs b/polkadot/node/core/pvf/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..cb35ec9e9d9a4d360513869279d8b6d032e3e0a6 --- /dev/null +++ b/polkadot/node/core/pvf/src/error.rs @@ -0,0 +1,84 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_core_pvf_common::error::{InternalValidationError, PrepareError}; + +/// A error raised during validation of the candidate. +#[derive(Debug, Clone)] +pub enum ValidationError { + /// The error was raised because the candidate is invalid. + /// + /// Whenever we are unsure if the error was due to the candidate or not, we must vote invalid. + InvalidCandidate(InvalidCandidate), + /// Some internal error occurred. + InternalError(InternalValidationError), +} + +/// A description of an error raised during executing a PVF and can be attributed to the combination +/// of the candidate [`polkadot_parachain::primitives::ValidationParams`] and the PVF. +#[derive(Debug, Clone)] +pub enum InvalidCandidate { + /// PVF preparation ended up with a deterministic error. + PrepareError(String), + /// The failure is reported by the execution worker. The string contains the error message. + WorkerReportedError(String), + /// The worker has died during validation of a candidate. That may fall in one of the following + /// categories, which we cannot distinguish programmatically: + /// + /// (a) Some sort of transient glitch caused the worker process to abort. An example would be + /// that the host machine ran out of free memory and the OOM killer started killing the + /// processes, and in order to save the parent it will "sacrifice child" first. + /// + /// (b) The candidate triggered a code path that has lead to the process death. For example, + /// the PVF found a way to consume unbounded amount of resources and then it either + /// exceeded an `rlimit` (if set) or, again, invited OOM killer. Another possibility is a + /// bug in wasmtime allowed the PVF to gain control over the execution worker. + /// + /// We attribute such an event to an *invalid candidate* in either case. + /// + /// The rationale for this is that a glitch may lead to unfair rejecting candidate by a single + /// validator. If the glitch is somewhat more persistent the validator will reject all + /// candidate thrown at it and hopefully the operator notices it by decreased reward + /// performance of the validator. On the other hand, if the worker died because of (b) we would + /// have better chances to stop the attack. + AmbiguousWorkerDeath, + /// PVF execution (compilation is not included) took more time than was allotted. + HardTimeout, + /// A panic occurred and we can't be sure whether the candidate is really invalid or some + /// internal glitch occurred. Whenever we are unsure, we can never treat an error as internal + /// as we would abstain from voting. This is bad because if the issue was due to the candidate, + /// then all validators would abstain, stalling finality on the chain. So we will first retry + /// the candidate, and if the issue persists we are forced to vote invalid. + Panic(String), +} + +impl From for ValidationError { + fn from(error: InternalValidationError) -> Self { + Self::InternalError(error) + } +} + +impl From for ValidationError { + fn from(error: PrepareError) -> Self { + // Here we need to classify the errors into two errors: deterministic and non-deterministic. + // See [`PrepareError::is_deterministic`]. + if error.is_deterministic() { + Self::InvalidCandidate(InvalidCandidate::PrepareError(error.to_string())) + } else { + Self::InternalError(InternalValidationError::NonDeterministicPrepareError(error)) + } + } +} diff --git a/polkadot/node/core/pvf/src/execute/mod.rs b/polkadot/node/core/pvf/src/execute/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..669b9dc04d7c518d06791536462b2c8bdbcd91ea --- /dev/null +++ b/polkadot/node/core/pvf/src/execute/mod.rs @@ -0,0 +1,26 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Execution part of the pipeline. +//! +//! The validation host [runs the queue][`start`] communicating with it by sending [`ToQueue`] +//! messages. The queue will spawn workers in new processes. Those processes should jump to +//! `polkadot_node_core_pvf_worker::execute_worker_entrypoint`. + +mod queue; +mod worker_intf; + +pub use queue::{start, PendingExecutionRequest, ToQueue}; diff --git a/polkadot/node/core/pvf/src/execute/queue.rs b/polkadot/node/core/pvf/src/execute/queue.rs new file mode 100644 index 0000000000000000000000000000000000000000..acb260e256931686c15dadb64341e2155b56ee2e --- /dev/null +++ b/polkadot/node/core/pvf/src/execute/queue.rs @@ -0,0 +1,514 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A queue that handles requests for PVF execution. + +use super::worker_intf::Outcome; +use crate::{ + artifacts::{ArtifactId, ArtifactPathId}, + host::ResultSender, + metrics::Metrics, + worker_intf::{IdleWorker, WorkerHandle}, + InvalidCandidate, ValidationError, LOG_TARGET, +}; +use futures::{ + channel::mpsc, + future::BoxFuture, + stream::{FuturesUnordered, StreamExt as _}, + Future, FutureExt, +}; +use polkadot_primitives::{ExecutorParams, ExecutorParamsHash}; +use slotmap::HopSlotMap; +use std::{ + collections::VecDeque, + fmt, + path::PathBuf, + time::{Duration, Instant}, +}; + +/// The amount of time a job for which the queue does not have a compatible worker may wait in the +/// queue. After that time passes, the queue will kill the first worker which becomes idle to +/// re-spawn a new worker to execute the job immediately. +/// To make any sense and not to break things, the value should be greater than minimal execution +/// timeout in use, and less than the block time. +const MAX_KEEP_WAITING: Duration = Duration::from_secs(4); + +slotmap::new_key_type! { struct Worker; } + +#[derive(Debug)] +pub enum ToQueue { + Enqueue { artifact: ArtifactPathId, pending_execution_request: PendingExecutionRequest }, +} + +/// An execution request that should execute the PVF (known in the context) and send the results +/// to the given result sender. +#[derive(Debug)] +pub struct PendingExecutionRequest { + pub exec_timeout: Duration, + pub params: Vec, + pub executor_params: ExecutorParams, + pub result_tx: ResultSender, +} + +struct ExecuteJob { + artifact: ArtifactPathId, + exec_timeout: Duration, + params: Vec, + executor_params: ExecutorParams, + result_tx: ResultSender, + waiting_since: Instant, +} + +struct WorkerData { + idle: Option, + handle: WorkerHandle, + executor_params_hash: ExecutorParamsHash, +} + +impl fmt::Debug for WorkerData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "WorkerData(pid={})", self.handle.id()) + } +} + +struct Workers { + /// The registry of running workers. + running: HopSlotMap, + + /// The number of spawning but not yet spawned workers. + spawn_inflight: usize, + + /// The maximum number of workers queue can have at once. + capacity: usize, +} + +impl Workers { + fn can_afford_one_more(&self) -> bool { + self.spawn_inflight + self.running.len() < self.capacity + } + + fn find_available(&self, executor_params_hash: ExecutorParamsHash) -> Option { + self.running.iter().find_map(|d| { + if d.1.idle.is_some() && d.1.executor_params_hash == executor_params_hash { + Some(d.0) + } else { + None + } + }) + } + + fn find_idle(&self) -> Option { + self.running + .iter() + .find_map(|d| if d.1.idle.is_some() { Some(d.0) } else { None }) + } + + /// Find the associated data by the worker token and extract it's [`IdleWorker`] token. + /// + /// Returns `None` if either worker is not recognized or idle token is absent. + fn claim_idle(&mut self, worker: Worker) -> Option { + self.running.get_mut(worker)?.idle.take() + } +} + +enum QueueEvent { + Spawn(IdleWorker, WorkerHandle, ExecuteJob), + StartWork(Worker, Outcome, ArtifactId, ResultSender), +} + +type Mux = FuturesUnordered>; + +struct Queue { + metrics: Metrics, + + /// The receiver that receives messages to the pool. + to_queue_rx: mpsc::Receiver, + + // Some variables related to the current session. + program_path: PathBuf, + spawn_timeout: Duration, + node_version: Option, + + /// The queue of jobs that are waiting for a worker to pick up. + queue: VecDeque, + workers: Workers, + mux: Mux, +} + +impl Queue { + fn new( + metrics: Metrics, + program_path: PathBuf, + worker_capacity: usize, + spawn_timeout: Duration, + node_version: Option, + to_queue_rx: mpsc::Receiver, + ) -> Self { + Self { + metrics, + program_path, + spawn_timeout, + node_version, + to_queue_rx, + queue: VecDeque::new(), + mux: Mux::new(), + workers: Workers { + running: HopSlotMap::with_capacity_and_key(10), + spawn_inflight: 0, + capacity: worker_capacity, + }, + } + } + + async fn run(mut self) { + loop { + futures::select! { + to_queue = self.to_queue_rx.next() => { + if let Some(to_queue) = to_queue { + handle_to_queue(&mut self, to_queue); + } else { + break; + } + } + ev = self.mux.select_next_some() => handle_mux(&mut self, ev).await, + } + + purge_dead(&self.metrics, &mut self.workers).await; + } + } + + /// Tries to assign a job in the queue to a worker. If an idle worker is provided, it does its + /// best to find a job with a compatible execution environment unless there are jobs in the + /// queue waiting too long. In that case, it kills an existing idle worker and spawns a new + /// one. It may spawn an additional worker if that is affordable. + /// If all the workers are busy or the queue is empty, it does nothing. + /// Should be called every time a new job arrives to the queue or a job finishes. + fn try_assign_next_job(&mut self, finished_worker: Option) { + // New jobs are always pushed to the tail of the queue; the one at its head is always + // the eldest one. + let eldest = if let Some(eldest) = self.queue.get(0) { eldest } else { return }; + + // By default, we're going to execute the eldest job on any worker slot available, even if + // we have to kill and re-spawn a worker + let mut worker = None; + let mut job_index = 0; + + // But if we're not pressed for time, we can try to find a better job-worker pair not + // requiring the expensive kill-spawn operation + if eldest.waiting_since.elapsed() < MAX_KEEP_WAITING { + if let Some(finished_worker) = finished_worker { + if let Some(worker_data) = self.workers.running.get(finished_worker) { + for (i, job) in self.queue.iter().enumerate() { + if worker_data.executor_params_hash == job.executor_params.hash() { + (worker, job_index) = (Some(finished_worker), i); + break + } + } + } + } + } + + if worker.is_none() { + // Try to obtain a worker for the job + worker = self.workers.find_available(self.queue[job_index].executor_params.hash()); + } + + if worker.is_none() { + if let Some(idle) = self.workers.find_idle() { + // No available workers of required type but there are some idle ones of other + // types, have to kill one and re-spawn with the correct type + if self.workers.running.remove(idle).is_some() { + self.metrics.execute_worker().on_retired(); + } + } + } + + if worker.is_none() && !self.workers.can_afford_one_more() { + // Bad luck, no worker slot can be used to execute the job + return + } + + let job = self.queue.remove(job_index).expect("Job is just checked to be in queue; qed"); + + if let Some(worker) = worker { + assign(self, worker, job); + } else { + spawn_extra_worker(self, job); + } + } +} + +async fn purge_dead(metrics: &Metrics, workers: &mut Workers) { + let mut to_remove = vec![]; + for (worker, data) in workers.running.iter_mut() { + if futures::poll!(&mut data.handle).is_ready() { + // a resolved future means that the worker has terminated. Weed it out. + to_remove.push(worker); + } + } + for w in to_remove { + if workers.running.remove(w).is_some() { + metrics.execute_worker().on_retired(); + } + } +} + +fn handle_to_queue(queue: &mut Queue, to_queue: ToQueue) { + let ToQueue::Enqueue { artifact, pending_execution_request } = to_queue; + let PendingExecutionRequest { exec_timeout, params, executor_params, result_tx } = + pending_execution_request; + gum::debug!( + target: LOG_TARGET, + validation_code_hash = ?artifact.id.code_hash, + "enqueueing an artifact for execution", + ); + queue.metrics.execute_enqueued(); + let job = ExecuteJob { + artifact, + exec_timeout, + params, + executor_params, + result_tx, + waiting_since: Instant::now(), + }; + queue.queue.push_back(job); + queue.try_assign_next_job(None); +} + +async fn handle_mux(queue: &mut Queue, event: QueueEvent) { + match event { + QueueEvent::Spawn(idle, handle, job) => { + handle_worker_spawned(queue, idle, handle, job); + }, + QueueEvent::StartWork(worker, outcome, artifact_id, result_tx) => { + handle_job_finish(queue, worker, outcome, artifact_id, result_tx); + }, + } +} + +fn handle_worker_spawned( + queue: &mut Queue, + idle: IdleWorker, + handle: WorkerHandle, + job: ExecuteJob, +) { + queue.metrics.execute_worker().on_spawned(); + queue.workers.spawn_inflight -= 1; + let worker = queue.workers.running.insert(WorkerData { + idle: Some(idle), + handle, + executor_params_hash: job.executor_params.hash(), + }); + + gum::debug!(target: LOG_TARGET, ?worker, "execute worker spawned"); + + assign(queue, worker, job); +} + +/// If there are pending jobs in the queue, schedules the next of them onto the just freed up +/// worker. Otherwise, puts back into the available workers list. +fn handle_job_finish( + queue: &mut Queue, + worker: Worker, + outcome: Outcome, + artifact_id: ArtifactId, + result_tx: ResultSender, +) { + let (idle_worker, result, duration) = match outcome { + Outcome::Ok { result_descriptor, duration, idle_worker } => { + // TODO: propagate the soft timeout + + (Some(idle_worker), Ok(result_descriptor), Some(duration)) + }, + Outcome::InvalidCandidate { err, idle_worker } => ( + Some(idle_worker), + Err(ValidationError::InvalidCandidate(InvalidCandidate::WorkerReportedError(err))), + None, + ), + Outcome::InternalError { err } => (None, Err(ValidationError::InternalError(err)), None), + Outcome::HardTimeout => + (None, Err(ValidationError::InvalidCandidate(InvalidCandidate::HardTimeout)), None), + // "Maybe invalid" errors (will retry). + Outcome::IoErr => ( + None, + Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbiguousWorkerDeath)), + None, + ), + Outcome::Panic { err } => + (None, Err(ValidationError::InvalidCandidate(InvalidCandidate::Panic(err))), None), + }; + + queue.metrics.execute_finished(); + if let Err(ref err) = result { + gum::warn!( + target: LOG_TARGET, + ?artifact_id, + ?worker, + worker_rip = idle_worker.is_none(), + "execution worker concluded, error occurred: {:?}", + err + ); + } else { + gum::trace!( + target: LOG_TARGET, + ?artifact_id, + ?worker, + worker_rip = idle_worker.is_none(), + ?duration, + "execute worker concluded successfully", + ); + } + + // First we send the result. It may fail due to the other end of the channel being dropped, + // that's legitimate and we don't treat that as an error. + let _ = result_tx.send(result); + + // Then, we should deal with the worker: + // + // - if the `idle_worker` token was returned we should either schedule the next task or just put + // it back so that the next incoming job will be able to claim it + // + // - if the `idle_worker` token was consumed, all the metadata pertaining to that worker should + // be removed. + if let Some(idle_worker) = idle_worker { + if let Some(data) = queue.workers.running.get_mut(worker) { + data.idle = Some(idle_worker); + return queue.try_assign_next_job(Some(worker)) + } + } else { + // Note it's possible that the worker was purged already by `purge_dead` + if queue.workers.running.remove(worker).is_some() { + queue.metrics.execute_worker().on_retired(); + } + } + + queue.try_assign_next_job(None); +} + +fn spawn_extra_worker(queue: &mut Queue, job: ExecuteJob) { + queue.metrics.execute_worker().on_begin_spawn(); + gum::debug!(target: LOG_TARGET, "spawning an extra worker"); + + queue.mux.push( + spawn_worker_task( + queue.program_path.clone(), + job, + queue.spawn_timeout, + queue.node_version.clone(), + ) + .boxed(), + ); + queue.workers.spawn_inflight += 1; +} + +/// Spawns a new worker to execute a pre-assigned job. +/// A worker is never spawned as idle; a job to be executed by the worker has to be determined +/// beforehand. In such a way, a race condition is avoided: during the worker being spawned, +/// another job in the queue, with an incompatible execution environment, may become stale, and +/// the queue would have to kill a newly started worker and spawn another one. +/// Nevertheless, if the worker finishes executing the job, it becomes idle and may be used to +/// execute other jobs with a compatible execution environment. +async fn spawn_worker_task( + program_path: PathBuf, + job: ExecuteJob, + spawn_timeout: Duration, + node_version: Option, +) -> QueueEvent { + use futures_timer::Delay; + + loop { + match super::worker_intf::spawn( + &program_path, + job.executor_params.clone(), + spawn_timeout, + node_version.as_deref(), + ) + .await + { + Ok((idle, handle)) => break QueueEvent::Spawn(idle, handle, job), + Err(err) => { + gum::warn!(target: LOG_TARGET, "failed to spawn an execute worker: {:?}", err); + + // Assume that the failure is intermittent and retry after a delay. + Delay::new(Duration::from_secs(3)).await; + }, + } + } +} + +/// Ask the given worker to perform the given job. +/// +/// The worker must be running and idle. The job and the worker must share the same execution +/// environment parameter set. +fn assign(queue: &mut Queue, worker: Worker, job: ExecuteJob) { + gum::debug!( + target: LOG_TARGET, + validation_code_hash = ?job.artifact.id, + ?worker, + "assigning the execute worker", + ); + + debug_assert_eq!( + queue + .workers + .running + .get(worker) + .expect("caller must provide existing worker; qed") + .executor_params_hash, + job.executor_params.hash() + ); + + let idle = queue.workers.claim_idle(worker).expect( + "this caller must supply a worker which is idle and running; + thus claim_idle cannot return None; + qed.", + ); + let execution_timer = queue.metrics.time_execution(); + queue.mux.push( + async move { + let _timer = execution_timer; + let outcome = super::worker_intf::start_work( + idle, + job.artifact.clone(), + job.exec_timeout, + job.params, + ) + .await; + QueueEvent::StartWork(worker, outcome, job.artifact.id, job.result_tx) + } + .boxed(), + ); +} + +pub fn start( + metrics: Metrics, + program_path: PathBuf, + worker_capacity: usize, + spawn_timeout: Duration, + node_version: Option, +) -> (mpsc::Sender, impl Future) { + let (to_queue_tx, to_queue_rx) = mpsc::channel(20); + let run = Queue::new( + metrics, + program_path, + worker_capacity, + spawn_timeout, + node_version, + to_queue_rx, + ) + .run(); + (to_queue_tx, run) +} diff --git a/polkadot/node/core/pvf/src/execute/worker_intf.rs b/polkadot/node/core/pvf/src/execute/worker_intf.rs new file mode 100644 index 0000000000000000000000000000000000000000..948abd2261d720e14e4f691d626febdf48dbf743 --- /dev/null +++ b/polkadot/node/core/pvf/src/execute/worker_intf.rs @@ -0,0 +1,215 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Host interface to the execute worker. + +use crate::{ + artifacts::ArtifactPathId, + worker_intf::{ + path_to_bytes, spawn_with_program_path, IdleWorker, SpawnErr, WorkerHandle, + JOB_TIMEOUT_WALL_CLOCK_FACTOR, + }, + LOG_TARGET, +}; +use futures::FutureExt; +use futures_timer::Delay; +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_core_pvf_common::{ + error::InternalValidationError, + execute::{Handshake, Response}, + framed_recv, framed_send, +}; +use polkadot_parachain::primitives::ValidationResult; +use polkadot_primitives::ExecutorParams; +use std::{path::Path, time::Duration}; +use tokio::{io, net::UnixStream}; + +/// Spawns a new worker with the given program path that acts as the worker and the spawn timeout. +/// Sends a handshake message to the worker as soon as it is spawned. +/// +/// The program should be able to handle ` execute-worker ` invocation. +pub async fn spawn( + program_path: &Path, + executor_params: ExecutorParams, + spawn_timeout: Duration, + node_version: Option<&str>, +) -> Result<(IdleWorker, WorkerHandle), SpawnErr> { + let mut extra_args = vec!["execute-worker"]; + if let Some(node_version) = node_version { + extra_args.extend_from_slice(&["--node-impl-version", node_version]); + } + let (mut idle_worker, worker_handle) = + spawn_with_program_path("execute", program_path, &extra_args, spawn_timeout).await?; + send_handshake(&mut idle_worker.stream, Handshake { executor_params }) + .await + .map_err(|error| { + gum::warn!( + target: LOG_TARGET, + worker_pid = %idle_worker.pid, + ?error, + "failed to send a handshake to the spawned worker", + ); + SpawnErr::Handshake + })?; + Ok((idle_worker, worker_handle)) +} + +/// Outcome of PVF execution. +/// +/// If the idle worker token is not returned, it means the worker must be terminated. +pub enum Outcome { + /// PVF execution completed successfully and the result is returned. The worker is ready for + /// another job. + Ok { result_descriptor: ValidationResult, duration: Duration, idle_worker: IdleWorker }, + /// The candidate validation failed. It may be for example because the wasm execution triggered + /// a trap. Errors related to the preparation process are not expected to be encountered by the + /// execution workers. + InvalidCandidate { err: String, idle_worker: IdleWorker }, + /// An internal error happened during the validation. Such an error is most likely related to + /// some transient glitch. + /// + /// Should only ever be used for errors independent of the candidate and PVF. Therefore it may + /// be a problem with the worker, so we terminate it. + InternalError { err: InternalValidationError }, + /// The execution time exceeded the hard limit. The worker is terminated. + HardTimeout, + /// An I/O error happened during communication with the worker. This may mean that the worker + /// process already died. The token is not returned in any case. + IoErr, + /// An unexpected panic has occurred in the execution worker. + Panic { err: String }, +} + +/// Given the idle token of a worker and parameters of work, communicates with the worker and +/// returns the outcome. +/// +/// NOTE: Not returning the idle worker token in `Outcome` will trigger the child process being +/// killed. +pub async fn start_work( + worker: IdleWorker, + artifact: ArtifactPathId, + execution_timeout: Duration, + validation_params: Vec, +) -> Outcome { + let IdleWorker { mut stream, pid } = worker; + + gum::debug!( + target: LOG_TARGET, + worker_pid = %pid, + validation_code_hash = ?artifact.id.code_hash, + "starting execute for {}", + artifact.path.display(), + ); + + if let Err(error) = + send_request(&mut stream, &artifact.path, &validation_params, execution_timeout).await + { + gum::warn!( + target: LOG_TARGET, + worker_pid = %pid, + validation_code_hash = ?artifact.id.code_hash, + ?error, + "failed to send an execute request", + ); + return Outcome::IoErr + } + + // We use a generous timeout here. This is in addition to the one in the child process, in + // case the child stalls. We have a wall clock timeout here in the host, but a CPU timeout + // in the child. We want to use CPU time because it varies less than wall clock time under + // load, but the CPU resources of the child can only be measured from the parent after the + // child process terminates. + let timeout = execution_timeout * JOB_TIMEOUT_WALL_CLOCK_FACTOR; + let response = futures::select! { + response = recv_response(&mut stream).fuse() => { + match response { + Err(error) => { + gum::warn!( + target: LOG_TARGET, + worker_pid = %pid, + validation_code_hash = ?artifact.id.code_hash, + ?error, + "failed to recv an execute response", + ); + return Outcome::IoErr + }, + Ok(response) => { + if let Response::Ok{duration, ..} = response { + if duration > execution_timeout { + // The job didn't complete within the timeout. + gum::warn!( + target: LOG_TARGET, + worker_pid = %pid, + "execute job took {}ms cpu time, exceeded execution timeout {}ms.", + duration.as_millis(), + execution_timeout.as_millis(), + ); + + // Return a timeout error. + return Outcome::HardTimeout; + } + } + + response + }, + } + }, + _ = Delay::new(timeout).fuse() => { + gum::warn!( + target: LOG_TARGET, + worker_pid = %pid, + validation_code_hash = ?artifact.id.code_hash, + "execution worker exceeded lenient timeout for execution, child worker likely stalled", + ); + Response::TimedOut + }, + }; + + match response { + Response::Ok { result_descriptor, duration } => + Outcome::Ok { result_descriptor, duration, idle_worker: IdleWorker { stream, pid } }, + Response::InvalidCandidate(err) => + Outcome::InvalidCandidate { err, idle_worker: IdleWorker { stream, pid } }, + Response::TimedOut => Outcome::HardTimeout, + Response::Panic(err) => Outcome::Panic { err }, + Response::InternalError(err) => Outcome::InternalError { err }, + } +} + +async fn send_handshake(stream: &mut UnixStream, handshake: Handshake) -> io::Result<()> { + framed_send(stream, &handshake.encode()).await +} + +async fn send_request( + stream: &mut UnixStream, + artifact_path: &Path, + validation_params: &[u8], + execution_timeout: Duration, +) -> io::Result<()> { + framed_send(stream, path_to_bytes(artifact_path)).await?; + framed_send(stream, validation_params).await?; + framed_send(stream, &execution_timeout.encode()).await +} + +async fn recv_response(stream: &mut UnixStream) -> io::Result { + let response_bytes = framed_recv(stream).await?; + Response::decode(&mut &response_bytes[..]).map_err(|e| { + io::Error::new( + io::ErrorKind::Other, + format!("execute pvf recv_response: decode error: {:?}", e), + ) + }) +} diff --git a/polkadot/node/core/pvf/src/host.rs b/polkadot/node/core/pvf/src/host.rs new file mode 100644 index 0000000000000000000000000000000000000000..9f3b7e23fd89e419350329bd2226242a51b5628e --- /dev/null +++ b/polkadot/node/core/pvf/src/host.rs @@ -0,0 +1,1728 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Validation host - is the primary interface for this crate. It allows the clients to enqueue +//! jobs for PVF execution or preparation. +//! +//! The validation host is represented by a future/task that runs an event-loop and by a handle, +//! [`ValidationHost`], that allows communication with that event-loop. + +use crate::{ + artifacts::{ArtifactId, ArtifactPathId, ArtifactState, Artifacts}, + execute::{self, PendingExecutionRequest}, + metrics::Metrics, + prepare, Priority, ValidationError, LOG_TARGET, +}; +use always_assert::never; +use futures::{ + channel::{mpsc, oneshot}, + Future, FutureExt, SinkExt, StreamExt, +}; +use polkadot_node_core_pvf_common::{ + error::{PrepareError, PrepareResult}, + pvf::PvfPrepData, +}; +use polkadot_parachain::primitives::ValidationResult; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, + time::{Duration, SystemTime}, +}; + +/// The time period after which a failed preparation artifact is considered ready to be retried. +/// Note that we will only retry if another request comes in after this cooldown has passed. +#[cfg(not(test))] +pub const PREPARE_FAILURE_COOLDOWN: Duration = Duration::from_secs(15 * 60); +#[cfg(test)] +pub const PREPARE_FAILURE_COOLDOWN: Duration = Duration::from_millis(200); + +/// The amount of times we will retry failed prepare jobs. +pub const NUM_PREPARE_RETRIES: u32 = 5; + +/// The name of binary spawned to prepare a PVF artifact +pub const PREPARE_BINARY_NAME: &str = "polkadot-prepare-worker"; + +/// The name of binary spawned to execute a PVF +pub const EXECUTE_BINARY_NAME: &str = "polkadot-execute-worker"; + +/// An alias to not spell the type for the oneshot sender for the PVF execution result. +pub(crate) type ResultSender = oneshot::Sender>; + +/// Transmission end used for sending the PVF preparation result. +pub(crate) type PrepareResultSender = oneshot::Sender; + +/// A handle to the async process serving the validation host requests. +#[derive(Clone)] +pub struct ValidationHost { + to_host_tx: mpsc::Sender, +} + +impl ValidationHost { + /// Precheck PVF with the given code, i.e. verify that it compiles within a reasonable time + /// limit. This will prepare the PVF. The result of preparation will be sent to the provided + /// result sender. + /// + /// This is async to accommodate the possibility of back-pressure. In the vast majority of + /// situations this function should return immediately. + /// + /// Returns an error if the request cannot be sent to the validation host, i.e. if it shut down. + pub async fn precheck_pvf( + &mut self, + pvf: PvfPrepData, + result_tx: PrepareResultSender, + ) -> Result<(), String> { + self.to_host_tx + .send(ToHost::PrecheckPvf { pvf, result_tx }) + .await + .map_err(|_| "the inner loop hung up".to_string()) + } + + /// Execute PVF with the given code, execution timeout, parameters and priority. + /// The result of execution will be sent to the provided result sender. + /// + /// This is async to accommodate the possibility of back-pressure. In the vast majority of + /// situations this function should return immediately. + /// + /// Returns an error if the request cannot be sent to the validation host, i.e. if it shut down. + pub async fn execute_pvf( + &mut self, + pvf: PvfPrepData, + exec_timeout: Duration, + params: Vec, + priority: Priority, + result_tx: ResultSender, + ) -> Result<(), String> { + self.to_host_tx + .send(ToHost::ExecutePvf(ExecutePvfInputs { + pvf, + exec_timeout, + params, + priority, + result_tx, + })) + .await + .map_err(|_| "the inner loop hung up".to_string()) + } + + /// Sends a signal to the validation host requesting to prepare a list of the given PVFs. + /// + /// This is async to accommodate the possibility of back-pressure. In the vast majority of + /// situations this function should return immediately. + /// + /// Returns an error if the request cannot be sent to the validation host, i.e. if it shut down. + pub async fn heads_up(&mut self, active_pvfs: Vec) -> Result<(), String> { + self.to_host_tx + .send(ToHost::HeadsUp { active_pvfs }) + .await + .map_err(|_| "the inner loop hung up".to_string()) + } +} + +enum ToHost { + PrecheckPvf { pvf: PvfPrepData, result_tx: PrepareResultSender }, + ExecutePvf(ExecutePvfInputs), + HeadsUp { active_pvfs: Vec }, +} + +struct ExecutePvfInputs { + pvf: PvfPrepData, + exec_timeout: Duration, + params: Vec, + priority: Priority, + result_tx: ResultSender, +} + +/// Configuration for the validation host. +#[derive(Debug)] +pub struct Config { + /// The root directory where the prepared artifacts can be stored. + pub cache_path: PathBuf, + /// The version of the node. `None` can be passed to skip the version check (only for tests). + pub node_version: Option, + /// The path to the program that can be used to spawn the prepare workers. + pub prepare_worker_program_path: PathBuf, + /// The time allotted for a prepare worker to spawn and report to the host. + pub prepare_worker_spawn_timeout: Duration, + /// The maximum number of workers that can be spawned in the prepare pool for tasks with the + /// priority below critical. + pub prepare_workers_soft_max_num: usize, + /// The absolute number of workers that can be spawned in the prepare pool. + pub prepare_workers_hard_max_num: usize, + /// The path to the program that can be used to spawn the execute workers. + pub execute_worker_program_path: PathBuf, + /// The time allotted for an execute worker to spawn and report to the host. + pub execute_worker_spawn_timeout: Duration, + /// The maximum number of execute workers that can run at the same time. + pub execute_workers_max_num: usize, +} + +impl Config { + /// Create a new instance of the configuration. + pub fn new( + cache_path: PathBuf, + node_version: Option, + prepare_worker_program_path: PathBuf, + execute_worker_program_path: PathBuf, + ) -> Self { + Self { + cache_path, + node_version, + prepare_worker_program_path, + prepare_worker_spawn_timeout: Duration::from_secs(3), + prepare_workers_soft_max_num: 1, + prepare_workers_hard_max_num: 1, + execute_worker_program_path, + execute_worker_spawn_timeout: Duration::from_secs(3), + execute_workers_max_num: 2, + } + } +} + +/// Start the validation host. +/// +/// Returns a [handle][`ValidationHost`] to the started validation host and the future. The future +/// must be polled in order for validation host to function. +/// +/// The future should not return normally but if it does then that indicates an unrecoverable error. +/// In that case all pending requests will be canceled, dropping the result senders and new ones +/// will be rejected. +pub fn start(config: Config, metrics: Metrics) -> (ValidationHost, impl Future) { + gum::debug!(target: LOG_TARGET, ?config, "starting PVF validation host"); + + // Run checks for supported security features once per host startup. + warn_if_no_landlock(); + + let (to_host_tx, to_host_rx) = mpsc::channel(10); + + let validation_host = ValidationHost { to_host_tx }; + + let (to_prepare_pool, from_prepare_pool, run_prepare_pool) = prepare::start_pool( + metrics.clone(), + config.prepare_worker_program_path.clone(), + config.cache_path.clone(), + config.prepare_worker_spawn_timeout, + config.node_version.clone(), + ); + + let (to_prepare_queue_tx, from_prepare_queue_rx, run_prepare_queue) = prepare::start_queue( + metrics.clone(), + config.prepare_workers_soft_max_num, + config.prepare_workers_hard_max_num, + config.cache_path.clone(), + to_prepare_pool, + from_prepare_pool, + ); + + let (to_execute_queue_tx, run_execute_queue) = execute::start( + metrics, + config.execute_worker_program_path.to_owned(), + config.execute_workers_max_num, + config.execute_worker_spawn_timeout, + config.node_version, + ); + + let (to_sweeper_tx, to_sweeper_rx) = mpsc::channel(100); + let run_sweeper = sweeper_task(to_sweeper_rx); + + let run_host = async move { + let artifacts = Artifacts::new(&config.cache_path).await; + + run(Inner { + cache_path: config.cache_path, + cleanup_pulse_interval: Duration::from_secs(3600), + artifact_ttl: Duration::from_secs(3600 * 24), + artifacts, + to_host_rx, + to_prepare_queue_tx, + from_prepare_queue_rx, + to_execute_queue_tx, + to_sweeper_tx, + awaiting_prepare: AwaitingPrepare::default(), + }) + .await + }; + + let task = async move { + // Bundle the sub-components' tasks together into a single future. + futures::select! { + _ = run_host.fuse() => {}, + _ = run_prepare_queue.fuse() => {}, + _ = run_prepare_pool.fuse() => {}, + _ = run_execute_queue.fuse() => {}, + _ = run_sweeper.fuse() => {}, + }; + }; + + (validation_host, task) +} + +/// A mapping from an artifact ID which is in preparation state to the list of pending execution +/// requests that should be executed once the artifact's preparation is finished. +#[derive(Default)] +struct AwaitingPrepare(HashMap>); + +impl AwaitingPrepare { + fn add(&mut self, artifact_id: ArtifactId, pending_execution_request: PendingExecutionRequest) { + self.0.entry(artifact_id).or_default().push(pending_execution_request); + } + + fn take(&mut self, artifact_id: &ArtifactId) -> Vec { + self.0.remove(artifact_id).unwrap_or_default() + } +} + +struct Inner { + cache_path: PathBuf, + cleanup_pulse_interval: Duration, + artifact_ttl: Duration, + artifacts: Artifacts, + + to_host_rx: mpsc::Receiver, + + to_prepare_queue_tx: mpsc::Sender, + from_prepare_queue_rx: mpsc::UnboundedReceiver, + + to_execute_queue_tx: mpsc::Sender, + to_sweeper_tx: mpsc::Sender, + + awaiting_prepare: AwaitingPrepare, +} + +#[derive(Debug)] +struct Fatal; + +async fn run( + Inner { + cache_path, + cleanup_pulse_interval, + artifact_ttl, + mut artifacts, + to_host_rx, + from_prepare_queue_rx, + mut to_prepare_queue_tx, + mut to_execute_queue_tx, + mut to_sweeper_tx, + mut awaiting_prepare, + }: Inner, +) { + macro_rules! break_if_fatal { + ($expr:expr) => { + match $expr { + Err(Fatal) => { + gum::error!( + target: LOG_TARGET, + "Fatal error occurred, terminating the host. Line: {}", + line!(), + ); + break + }, + Ok(v) => v, + } + }; + } + + let cleanup_pulse = pulse_every(cleanup_pulse_interval).fuse(); + futures::pin_mut!(cleanup_pulse); + + let mut to_host_rx = to_host_rx.fuse(); + let mut from_prepare_queue_rx = from_prepare_queue_rx.fuse(); + + loop { + // biased to make it behave deterministically for tests. + futures::select_biased! { + () = cleanup_pulse.select_next_some() => { + // `select_next_some` because we don't expect this to fail, but if it does, we + // still don't fail. The trade-off is that the compiled cache will start growing + // in size. That is, however, rather a slow process and hopefully the operator + // will notice it. + + break_if_fatal!(handle_cleanup_pulse( + &cache_path, + &mut to_sweeper_tx, + &mut artifacts, + artifact_ttl, + ).await); + }, + to_host = to_host_rx.next() => { + let to_host = match to_host { + None => { + // The sending half of the channel has been closed, meaning the + // `ValidationHost` struct was dropped. Shutting down gracefully. + break; + }, + Some(to_host) => to_host, + }; + + // If the artifact failed before, it could be re-scheduled for preparation here if + // the preparation failure cooldown has elapsed. + break_if_fatal!(handle_to_host( + &cache_path, + &mut artifacts, + &mut to_prepare_queue_tx, + &mut to_execute_queue_tx, + &mut awaiting_prepare, + to_host, + ) + .await); + }, + from_prepare_queue = from_prepare_queue_rx.next() => { + let from_queue = break_if_fatal!(from_prepare_queue.ok_or(Fatal)); + + // Note that the preparation outcome is always reported as concluded. + // + // That's because the error conditions are written into the artifact and will be + // reported at the time of the execution. It potentially, but not necessarily, can + // be scheduled for execution as a result of this function call, in case there are + // pending executions. + // + // We could be eager in terms of reporting and plumb the result from the preparation + // worker but we don't for the sake of simplicity. + break_if_fatal!(handle_prepare_done( + &cache_path, + &mut artifacts, + &mut to_execute_queue_tx, + &mut awaiting_prepare, + from_queue, + ).await); + }, + } + } +} + +async fn handle_to_host( + cache_path: &Path, + artifacts: &mut Artifacts, + prepare_queue: &mut mpsc::Sender, + execute_queue: &mut mpsc::Sender, + awaiting_prepare: &mut AwaitingPrepare, + to_host: ToHost, +) -> Result<(), Fatal> { + match to_host { + ToHost::PrecheckPvf { pvf, result_tx } => { + handle_precheck_pvf(artifacts, prepare_queue, pvf, result_tx).await?; + }, + ToHost::ExecutePvf(inputs) => { + handle_execute_pvf( + cache_path, + artifacts, + prepare_queue, + execute_queue, + awaiting_prepare, + inputs, + ) + .await?; + }, + ToHost::HeadsUp { active_pvfs } => + handle_heads_up(artifacts, prepare_queue, active_pvfs).await?, + } + + Ok(()) +} + +/// Handles PVF prechecking requests. +/// +/// This tries to prepare the PVF by compiling the WASM blob within a timeout set in +/// `PvfPrepData`. +/// +/// If the prepare job failed previously, we may retry it under certain conditions. +async fn handle_precheck_pvf( + artifacts: &mut Artifacts, + prepare_queue: &mut mpsc::Sender, + pvf: PvfPrepData, + result_sender: PrepareResultSender, +) -> Result<(), Fatal> { + let artifact_id = ArtifactId::from_pvf_prep_data(&pvf); + + if let Some(state) = artifacts.artifact_state_mut(&artifact_id) { + match state { + ArtifactState::Prepared { last_time_needed, prepare_stats } => { + *last_time_needed = SystemTime::now(); + let _ = result_sender.send(Ok(prepare_stats.clone())); + }, + ArtifactState::Preparing { waiting_for_response, num_failures: _ } => + waiting_for_response.push(result_sender), + ArtifactState::FailedToProcess { error, .. } => { + // Do not retry failed preparation if another pre-check request comes in. We do not + // retry pre-checking, anyway. + let _ = result_sender.send(PrepareResult::Err(error.clone())); + }, + } + } else { + artifacts.insert_preparing(artifact_id, vec![result_sender]); + send_prepare(prepare_queue, prepare::ToQueue::Enqueue { priority: Priority::Normal, pvf }) + .await?; + } + Ok(()) +} + +/// Handles PVF execution. +/// +/// This will try to prepare the PVF, if a prepared artifact does not already exist. If there is +/// already a preparation job, we coalesce the two preparation jobs. +/// +/// If the prepare job succeeded previously, we will enqueue an execute job right away. +/// +/// If the prepare job failed previously, we may retry it under certain conditions. +/// +/// When preparing for execution, we use a more lenient timeout ([`LENIENT_PREPARATION_TIMEOUT`]) +/// than when prechecking. +async fn handle_execute_pvf( + cache_path: &Path, + artifacts: &mut Artifacts, + prepare_queue: &mut mpsc::Sender, + execute_queue: &mut mpsc::Sender, + awaiting_prepare: &mut AwaitingPrepare, + inputs: ExecutePvfInputs, +) -> Result<(), Fatal> { + let ExecutePvfInputs { pvf, exec_timeout, params, priority, result_tx } = inputs; + let artifact_id = ArtifactId::from_pvf_prep_data(&pvf); + let executor_params = (*pvf.executor_params()).clone(); + + if let Some(state) = artifacts.artifact_state_mut(&artifact_id) { + match state { + ArtifactState::Prepared { last_time_needed, .. } => { + let file_metadata = std::fs::metadata(artifact_id.path(cache_path)); + + if file_metadata.is_ok() { + *last_time_needed = SystemTime::now(); + + // This artifact has already been prepared, send it to the execute queue. + send_execute( + execute_queue, + execute::ToQueue::Enqueue { + artifact: ArtifactPathId::new(artifact_id, cache_path), + pending_execution_request: PendingExecutionRequest { + exec_timeout, + params, + executor_params, + result_tx, + }, + }, + ) + .await?; + } else { + gum::warn!( + target: LOG_TARGET, + ?pvf, + ?artifact_id, + "handle_execute_pvf: Re-queuing PVF preparation for prepared artifact with missing file." + ); + + // The artifact has been prepared previously but the file is missing, prepare it + // again. + *state = ArtifactState::Preparing { + waiting_for_response: Vec::new(), + num_failures: 0, + }; + enqueue_prepare_for_execute( + prepare_queue, + awaiting_prepare, + pvf, + priority, + artifact_id, + PendingExecutionRequest { + exec_timeout, + params, + executor_params, + result_tx, + }, + ) + .await?; + } + }, + ArtifactState::Preparing { .. } => { + awaiting_prepare.add( + artifact_id, + PendingExecutionRequest { exec_timeout, params, executor_params, result_tx }, + ); + }, + ArtifactState::FailedToProcess { last_time_failed, num_failures, error } => { + if can_retry_prepare_after_failure(*last_time_failed, *num_failures, error) { + gum::warn!( + target: LOG_TARGET, + ?pvf, + ?artifact_id, + ?last_time_failed, + %num_failures, + %error, + "handle_execute_pvf: Re-trying failed PVF preparation." + ); + + // If we are allowed to retry the failed prepare job, change the state to + // Preparing and re-queue this job. + *state = ArtifactState::Preparing { + waiting_for_response: Vec::new(), + num_failures: *num_failures, + }; + enqueue_prepare_for_execute( + prepare_queue, + awaiting_prepare, + pvf, + priority, + artifact_id, + PendingExecutionRequest { + exec_timeout, + params, + executor_params, + result_tx, + }, + ) + .await?; + } else { + let _ = result_tx.send(Err(ValidationError::from(error.clone()))); + } + }, + } + } else { + // Artifact is unknown: register it and enqueue a job with the corresponding priority and + // PVF. + artifacts.insert_preparing(artifact_id.clone(), Vec::new()); + enqueue_prepare_for_execute( + prepare_queue, + awaiting_prepare, + pvf, + priority, + artifact_id, + PendingExecutionRequest { exec_timeout, params, executor_params, result_tx }, + ) + .await?; + } + + Ok(()) +} + +async fn handle_heads_up( + artifacts: &mut Artifacts, + prepare_queue: &mut mpsc::Sender, + active_pvfs: Vec, +) -> Result<(), Fatal> { + let now = SystemTime::now(); + + for active_pvf in active_pvfs { + let artifact_id = ArtifactId::from_pvf_prep_data(&active_pvf); + if let Some(state) = artifacts.artifact_state_mut(&artifact_id) { + match state { + ArtifactState::Prepared { last_time_needed, .. } => { + *last_time_needed = now; + }, + ArtifactState::Preparing { .. } => { + // The artifact is already being prepared, so we don't need to do anything. + }, + ArtifactState::FailedToProcess { last_time_failed, num_failures, error } => { + if can_retry_prepare_after_failure(*last_time_failed, *num_failures, error) { + gum::warn!( + target: LOG_TARGET, + ?active_pvf, + ?artifact_id, + ?last_time_failed, + %num_failures, + %error, + "handle_heads_up: Re-trying failed PVF preparation." + ); + + // If we are allowed to retry the failed prepare job, change the state to + // Preparing and re-queue this job. + *state = ArtifactState::Preparing { + waiting_for_response: vec![], + num_failures: *num_failures, + }; + send_prepare( + prepare_queue, + prepare::ToQueue::Enqueue { + priority: Priority::Normal, + pvf: active_pvf, + }, + ) + .await?; + } + }, + } + } else { + // It's not in the artifacts, so we need to enqueue a job to prepare it. + artifacts.insert_preparing(artifact_id.clone(), Vec::new()); + + send_prepare( + prepare_queue, + prepare::ToQueue::Enqueue { priority: Priority::Normal, pvf: active_pvf }, + ) + .await?; + } + } + + Ok(()) +} + +async fn handle_prepare_done( + cache_path: &Path, + artifacts: &mut Artifacts, + execute_queue: &mut mpsc::Sender, + awaiting_prepare: &mut AwaitingPrepare, + from_queue: prepare::FromQueue, +) -> Result<(), Fatal> { + let prepare::FromQueue { artifact_id, result } = from_queue; + + // Make some sanity checks and extract the current state. + let state = match artifacts.artifact_state_mut(&artifact_id) { + None => { + // before sending request to prepare, the artifact is inserted with `preparing` state; + // the requests are deduplicated for the same artifact id; + // there is only one possible state change: prepare is done; + // thus the artifact cannot be unknown, only preparing; + // qed. + never!("an unknown artifact was prepared: {:?}", artifact_id); + return Ok(()) + }, + Some(ArtifactState::Prepared { .. }) => { + // before sending request to prepare, the artifact is inserted with `preparing` state; + // the requests are deduplicated for the same artifact id; + // there is only one possible state change: prepare is done; + // thus the artifact cannot be prepared, only preparing; + // qed. + never!("the artifact is already prepared: {:?}", artifact_id); + return Ok(()) + }, + Some(ArtifactState::FailedToProcess { .. }) => { + // The reasoning is similar to the above, the artifact cannot be + // processed at this point. + never!("the artifact is already processed unsuccessfully: {:?}", artifact_id); + return Ok(()) + }, + Some(state @ ArtifactState::Preparing { .. }) => state, + }; + + let num_failures = if let ArtifactState::Preparing { waiting_for_response, num_failures } = + state + { + for result_sender in waiting_for_response.drain(..) { + let _ = result_sender.send(result.clone()); + } + num_failures + } else { + never!("The reasoning is similar to the above, the artifact can only be preparing at this point; qed"); + return Ok(()) + }; + + // It's finally time to dispatch all the execution requests that were waiting for this artifact + // to be prepared. + let pending_requests = awaiting_prepare.take(&artifact_id); + for PendingExecutionRequest { exec_timeout, params, executor_params, result_tx } in + pending_requests + { + if result_tx.is_canceled() { + // Preparation could've taken quite a bit of time and the requester may be not + // interested in execution anymore, in which case we just skip the request. + continue + } + + // Don't send failed artifacts to the execution's queue. + if let Err(ref error) = result { + let _ = result_tx.send(Err(ValidationError::from(error.clone()))); + continue + } + + send_execute( + execute_queue, + execute::ToQueue::Enqueue { + artifact: ArtifactPathId::new(artifact_id.clone(), cache_path), + pending_execution_request: PendingExecutionRequest { + exec_timeout, + params, + executor_params, + result_tx, + }, + }, + ) + .await?; + } + + *state = match result { + Ok(prepare_stats) => + ArtifactState::Prepared { last_time_needed: SystemTime::now(), prepare_stats }, + Err(error) => { + let last_time_failed = SystemTime::now(); + let num_failures = *num_failures + 1; + + gum::warn!( + target: LOG_TARGET, + ?artifact_id, + time_failed = ?last_time_failed, + %num_failures, + "artifact preparation failed: {}", + error + ); + ArtifactState::FailedToProcess { last_time_failed, num_failures, error } + }, + }; + + Ok(()) +} + +async fn send_prepare( + prepare_queue: &mut mpsc::Sender, + to_queue: prepare::ToQueue, +) -> Result<(), Fatal> { + prepare_queue.send(to_queue).await.map_err(|_| Fatal) +} + +async fn send_execute( + execute_queue: &mut mpsc::Sender, + to_queue: execute::ToQueue, +) -> Result<(), Fatal> { + execute_queue.send(to_queue).await.map_err(|_| Fatal) +} + +/// Sends a job to the preparation queue, and adds an execution request that will wait to run after +/// this prepare job has finished. +async fn enqueue_prepare_for_execute( + prepare_queue: &mut mpsc::Sender, + awaiting_prepare: &mut AwaitingPrepare, + pvf: PvfPrepData, + priority: Priority, + artifact_id: ArtifactId, + pending_execution_request: PendingExecutionRequest, +) -> Result<(), Fatal> { + send_prepare(prepare_queue, prepare::ToQueue::Enqueue { priority, pvf }).await?; + + // Add an execution request that will wait to run after this prepare job has finished. + awaiting_prepare.add(artifact_id, pending_execution_request); + + Ok(()) +} + +async fn handle_cleanup_pulse( + cache_path: &Path, + sweeper_tx: &mut mpsc::Sender, + artifacts: &mut Artifacts, + artifact_ttl: Duration, +) -> Result<(), Fatal> { + let to_remove = artifacts.prune(artifact_ttl); + gum::debug!( + target: LOG_TARGET, + "PVF pruning: {} artifacts reached their end of life", + to_remove.len(), + ); + for artifact_id in to_remove { + gum::debug!( + target: LOG_TARGET, + validation_code_hash = ?artifact_id.code_hash, + "pruning artifact", + ); + let artifact_path = artifact_id.path(cache_path); + sweeper_tx.send(artifact_path).await.map_err(|_| Fatal)?; + } + + Ok(()) +} + +/// A simple task which sole purpose is to delete files thrown at it. +async fn sweeper_task(mut sweeper_rx: mpsc::Receiver) { + loop { + match sweeper_rx.next().await { + None => break, + Some(condemned) => { + let result = tokio::fs::remove_file(&condemned).await; + gum::trace!( + target: LOG_TARGET, + ?result, + "Sweeping the artifact file {}", + condemned.display(), + ); + }, + } + } +} + +/// Check if the conditions to retry a prepare job have been met. +fn can_retry_prepare_after_failure( + last_time_failed: SystemTime, + num_failures: u32, + error: &PrepareError, +) -> bool { + if error.is_deterministic() { + // This error is considered deterministic, so it will probably be reproducible. Don't retry. + return false + } + + // Retry if the retry cooldown has elapsed and if we have already retried less than + // `NUM_PREPARE_RETRIES` times. IO errors may resolve themselves. + SystemTime::now() >= last_time_failed + PREPARE_FAILURE_COOLDOWN && + num_failures <= NUM_PREPARE_RETRIES +} + +/// A stream that yields a pulse continuously at a given interval. +fn pulse_every(interval: std::time::Duration) -> impl futures::Stream { + futures::stream::unfold(interval, { + |interval| async move { + futures_timer::Delay::new(interval).await; + Some(((), interval)) + } + }) + .map(|_| ()) +} + +/// Check if landlock is supported and emit a warning if not. +fn warn_if_no_landlock() { + #[cfg(target_os = "linux")] + { + use polkadot_node_core_pvf_common::worker::security::landlock; + let status = landlock::get_status(); + if !landlock::status_is_fully_enabled(&status) { + let abi = landlock::LANDLOCK_ABI as u8; + gum::warn!( + target: LOG_TARGET, + ?status, + %abi, + "Cannot fully enable landlock, a Linux kernel security feature. Running validation of malicious PVF code has a higher risk of compromising this machine. Consider upgrading the kernel version for maximum security." + ); + } + } + + #[cfg(not(target_os = "linux"))] + gum::warn!( + target: LOG_TARGET, + "Cannot enable landlock, a Linux kernel security feature. Running validation of malicious PVF code has a higher risk of compromising this machine. Consider running on Linux with landlock support for maximum security." + ); +} + +#[cfg(test)] +pub(crate) mod tests { + use super::*; + use crate::InvalidCandidate; + use assert_matches::assert_matches; + use futures::future::BoxFuture; + use polkadot_node_core_pvf_common::{error::PrepareError, prepare::PrepareStats}; + + const TEST_EXECUTION_TIMEOUT: Duration = Duration::from_secs(3); + pub(crate) const TEST_PREPARATION_TIMEOUT: Duration = Duration::from_secs(30); + + #[tokio::test] + async fn pulse_test() { + let pulse = pulse_every(Duration::from_millis(100)); + futures::pin_mut!(pulse); + + for _ in 0..5 { + let start = std::time::Instant::now(); + let _ = pulse.next().await.unwrap(); + + let el = start.elapsed().as_millis(); + assert!(el > 50 && el < 150, "{}", el); + } + } + + /// Creates a new PVF which artifact id can be uniquely identified by the given number. + fn artifact_id(descriminator: u32) -> ArtifactId { + ArtifactId::from_pvf_prep_data(&PvfPrepData::from_discriminator(descriminator)) + } + + fn artifact_path(descriminator: u32) -> PathBuf { + artifact_id(descriminator).path(&PathBuf::from(std::env::temp_dir())).to_owned() + } + + struct Builder { + cleanup_pulse_interval: Duration, + artifact_ttl: Duration, + artifacts: Artifacts, + } + + impl Builder { + fn default() -> Self { + Self { + // these are selected high to not interfere in tests in which pruning is irrelevant. + cleanup_pulse_interval: Duration::from_secs(3600), + artifact_ttl: Duration::from_secs(3600), + + artifacts: Artifacts::empty(), + } + } + + fn build(self) -> Test { + Test::new(self) + } + } + + struct Test { + to_host_tx: Option>, + + to_prepare_queue_rx: mpsc::Receiver, + from_prepare_queue_tx: mpsc::UnboundedSender, + to_execute_queue_rx: mpsc::Receiver, + to_sweeper_rx: mpsc::Receiver, + + run: BoxFuture<'static, ()>, + } + + impl Test { + fn new(Builder { cleanup_pulse_interval, artifact_ttl, artifacts }: Builder) -> Self { + let cache_path = PathBuf::from(std::env::temp_dir()); + + let (to_host_tx, to_host_rx) = mpsc::channel(10); + let (to_prepare_queue_tx, to_prepare_queue_rx) = mpsc::channel(10); + let (from_prepare_queue_tx, from_prepare_queue_rx) = mpsc::unbounded(); + let (to_execute_queue_tx, to_execute_queue_rx) = mpsc::channel(10); + let (to_sweeper_tx, to_sweeper_rx) = mpsc::channel(10); + + let run = run(Inner { + cache_path, + cleanup_pulse_interval, + artifact_ttl, + artifacts, + to_host_rx, + to_prepare_queue_tx, + from_prepare_queue_rx, + to_execute_queue_tx, + to_sweeper_tx, + awaiting_prepare: AwaitingPrepare::default(), + }) + .boxed(); + + Self { + to_host_tx: Some(to_host_tx), + to_prepare_queue_rx, + from_prepare_queue_tx, + to_execute_queue_rx, + to_sweeper_rx, + run, + } + } + + fn host_handle(&mut self) -> ValidationHost { + let to_host_tx = self.to_host_tx.take().unwrap(); + ValidationHost { to_host_tx } + } + + async fn poll_and_recv_result(&mut self, result_rx: oneshot::Receiver) -> T + where + T: Send, + { + run_until(&mut self.run, async { result_rx.await.unwrap() }.boxed()).await + } + + async fn poll_and_recv_to_prepare_queue(&mut self) -> prepare::ToQueue { + let to_prepare_queue_rx = &mut self.to_prepare_queue_rx; + run_until(&mut self.run, async { to_prepare_queue_rx.next().await.unwrap() }.boxed()) + .await + } + + async fn poll_and_recv_to_execute_queue(&mut self) -> execute::ToQueue { + let to_execute_queue_rx = &mut self.to_execute_queue_rx; + run_until(&mut self.run, async { to_execute_queue_rx.next().await.unwrap() }.boxed()) + .await + } + + async fn poll_ensure_to_prepare_queue_is_empty(&mut self) { + use futures_timer::Delay; + + let to_prepare_queue_rx = &mut self.to_prepare_queue_rx; + run_until( + &mut self.run, + async { + futures::select! { + _ = Delay::new(Duration::from_millis(500)).fuse() => (), + _ = to_prepare_queue_rx.next().fuse() => { + panic!("the prepare queue is supposed to be empty") + } + } + } + .boxed(), + ) + .await + } + + async fn poll_ensure_to_execute_queue_is_empty(&mut self) { + use futures_timer::Delay; + + let to_execute_queue_rx = &mut self.to_execute_queue_rx; + run_until( + &mut self.run, + async { + futures::select! { + _ = Delay::new(Duration::from_millis(500)).fuse() => (), + _ = to_execute_queue_rx.next().fuse() => { + panic!("the execute queue is supposed to be empty") + } + } + } + .boxed(), + ) + .await + } + + async fn poll_ensure_to_sweeper_is_empty(&mut self) { + use futures_timer::Delay; + + let to_sweeper_rx = &mut self.to_sweeper_rx; + run_until( + &mut self.run, + async { + futures::select! { + _ = Delay::new(Duration::from_millis(500)).fuse() => (), + msg = to_sweeper_rx.next().fuse() => { + panic!("the sweeper is supposed to be empty, but received: {:?}", msg) + } + } + } + .boxed(), + ) + .await + } + } + + async fn run_until( + task: &mut (impl Future + Unpin), + mut fut: (impl Future + Unpin), + ) -> R { + use std::task::Poll; + + let start = std::time::Instant::now(); + let fut = &mut fut; + loop { + if start.elapsed() > std::time::Duration::from_secs(2) { + // We expect that this will take only a couple of iterations and thus to take way + // less than a second. + panic!("timeout"); + } + + if let Poll::Ready(r) = futures::poll!(&mut *fut) { + break r + } + + if futures::poll!(&mut *task).is_ready() { + panic!() + } + } + } + + #[tokio::test] + async fn shutdown_on_handle_drop() { + let test = Builder::default().build(); + + let join_handle = tokio::task::spawn(test.run); + + // Dropping the handle will lead to conclusion of the read part and thus will make the event + // loop to stop, which in turn will resolve the join handle. + drop(test.to_host_tx); + join_handle.await.unwrap(); + } + + #[tokio::test] + async fn pruning() { + let mock_now = SystemTime::now() - Duration::from_millis(1000); + + let mut builder = Builder::default(); + builder.cleanup_pulse_interval = Duration::from_millis(100); + builder.artifact_ttl = Duration::from_millis(500); + builder + .artifacts + .insert_prepared(artifact_id(1), mock_now, PrepareStats::default()); + builder + .artifacts + .insert_prepared(artifact_id(2), mock_now, PrepareStats::default()); + let mut test = builder.build(); + let mut host = test.host_handle(); + + host.heads_up(vec![PvfPrepData::from_discriminator(1)]).await.unwrap(); + + let to_sweeper_rx = &mut test.to_sweeper_rx; + run_until( + &mut test.run, + async { + assert_eq!(to_sweeper_rx.next().await.unwrap(), artifact_path(2)); + } + .boxed(), + ) + .await; + + // Extend TTL for the first artifact and make sure we don't receive another file removal + // request. + host.heads_up(vec![PvfPrepData::from_discriminator(1)]).await.unwrap(); + test.poll_ensure_to_sweeper_is_empty().await; + } + + #[tokio::test] + async fn execute_pvf_requests() { + let mut test = Builder::default().build(); + let mut host = test.host_handle(); + + let (result_tx, result_rx_pvf_1_1) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(1), + TEST_EXECUTION_TIMEOUT, + b"pvf1".to_vec(), + Priority::Normal, + result_tx, + ) + .await + .unwrap(); + + let (result_tx, result_rx_pvf_1_2) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(1), + TEST_EXECUTION_TIMEOUT, + b"pvf1".to_vec(), + Priority::Critical, + result_tx, + ) + .await + .unwrap(); + + let (result_tx, result_rx_pvf_2) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(2), + TEST_EXECUTION_TIMEOUT, + b"pvf2".to_vec(), + Priority::Normal, + result_tx, + ) + .await + .unwrap(); + + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(1), + result: Ok(PrepareStats::default()), + }) + .await + .unwrap(); + let result_tx_pvf_1_1 = assert_matches!( + test.poll_and_recv_to_execute_queue().await, + execute::ToQueue::Enqueue { pending_execution_request: PendingExecutionRequest { result_tx, .. }, .. } => result_tx + ); + let result_tx_pvf_1_2 = assert_matches!( + test.poll_and_recv_to_execute_queue().await, + execute::ToQueue::Enqueue { pending_execution_request: PendingExecutionRequest { result_tx, .. }, .. } => result_tx + ); + + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(2), + result: Ok(PrepareStats::default()), + }) + .await + .unwrap(); + let result_tx_pvf_2 = assert_matches!( + test.poll_and_recv_to_execute_queue().await, + execute::ToQueue::Enqueue { pending_execution_request: PendingExecutionRequest { result_tx, .. }, .. } => result_tx + ); + + result_tx_pvf_1_1 + .send(Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbiguousWorkerDeath))) + .unwrap(); + assert_matches!( + result_rx_pvf_1_1.now_or_never().unwrap().unwrap(), + Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbiguousWorkerDeath)) + ); + + result_tx_pvf_1_2 + .send(Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbiguousWorkerDeath))) + .unwrap(); + assert_matches!( + result_rx_pvf_1_2.now_or_never().unwrap().unwrap(), + Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbiguousWorkerDeath)) + ); + + result_tx_pvf_2 + .send(Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbiguousWorkerDeath))) + .unwrap(); + assert_matches!( + result_rx_pvf_2.now_or_never().unwrap().unwrap(), + Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbiguousWorkerDeath)) + ); + } + + #[tokio::test] + async fn precheck_pvf() { + let mut test = Builder::default().build(); + let mut host = test.host_handle(); + + // First, test a simple precheck request. + let (result_tx, result_rx) = oneshot::channel(); + host.precheck_pvf(PvfPrepData::from_discriminator_precheck(1), result_tx) + .await + .unwrap(); + + // The queue received the prepare request. + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + // Send `Ok` right away and poll the host. + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(1), + result: Ok(PrepareStats::default()), + }) + .await + .unwrap(); + // No pending execute requests. + test.poll_ensure_to_execute_queue_is_empty().await; + // Received the precheck result. + assert_matches!(result_rx.now_or_never().unwrap().unwrap(), Ok(_)); + + // Send multiple requests for the same PVF. + let mut precheck_receivers = Vec::new(); + for _ in 0..3 { + let (result_tx, result_rx) = oneshot::channel(); + host.precheck_pvf(PvfPrepData::from_discriminator_precheck(2), result_tx) + .await + .unwrap(); + precheck_receivers.push(result_rx); + } + // Received prepare request. + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(2), + result: Err(PrepareError::TimedOut), + }) + .await + .unwrap(); + test.poll_ensure_to_execute_queue_is_empty().await; + for result_rx in precheck_receivers { + assert_matches!( + result_rx.now_or_never().unwrap().unwrap(), + Err(PrepareError::TimedOut) + ); + } + } + + #[tokio::test] + async fn test_prepare_done() { + let mut test = Builder::default().build(); + let mut host = test.host_handle(); + + // Test mixed cases of receiving execute and precheck requests + // for the same PVF. + + // Send PVF for the execution and request the prechecking for it. + let (result_tx, result_rx_execute) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(1), + TEST_EXECUTION_TIMEOUT, + b"pvf2".to_vec(), + Priority::Critical, + result_tx, + ) + .await + .unwrap(); + + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + + let (result_tx, result_rx) = oneshot::channel(); + host.precheck_pvf(PvfPrepData::from_discriminator_precheck(1), result_tx) + .await + .unwrap(); + + // Suppose the preparation failed, the execution queue is empty and both + // "clients" receive their results. + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(1), + result: Err(PrepareError::TimedOut), + }) + .await + .unwrap(); + test.poll_ensure_to_execute_queue_is_empty().await; + assert_matches!(result_rx.now_or_never().unwrap().unwrap(), Err(PrepareError::TimedOut)); + assert_matches!( + result_rx_execute.now_or_never().unwrap().unwrap(), + Err(ValidationError::InternalError(_)) + ); + + // Reversed case: first send multiple precheck requests, then ask for an execution. + let mut precheck_receivers = Vec::new(); + for _ in 0..3 { + let (result_tx, result_rx) = oneshot::channel(); + host.precheck_pvf(PvfPrepData::from_discriminator_precheck(2), result_tx) + .await + .unwrap(); + precheck_receivers.push(result_rx); + } + + let (result_tx, _result_rx_execute) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(2), + TEST_EXECUTION_TIMEOUT, + b"pvf2".to_vec(), + Priority::Critical, + result_tx, + ) + .await + .unwrap(); + // Received prepare request. + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(2), + result: Ok(PrepareStats::default()), + }) + .await + .unwrap(); + // The execute queue receives new request, preckecking is finished and we can + // fetch results. + assert_matches!( + test.poll_and_recv_to_execute_queue().await, + execute::ToQueue::Enqueue { .. } + ); + for result_rx in precheck_receivers { + assert_matches!(result_rx.now_or_never().unwrap().unwrap(), Ok(_)); + } + } + + // Test that multiple prechecking requests do not trigger preparation retries if the first one + // failed. + #[tokio::test] + async fn test_precheck_prepare_no_retry() { + let mut test = Builder::default().build(); + let mut host = test.host_handle(); + + // Submit a precheck request that fails. + let (result_tx, result_rx) = oneshot::channel(); + host.precheck_pvf(PvfPrepData::from_discriminator_precheck(1), result_tx) + .await + .unwrap(); + + // The queue received the prepare request. + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + // Send a PrepareError. + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(1), + result: Err(PrepareError::TimedOut), + }) + .await + .unwrap(); + + // The result should contain the error. + let result = test.poll_and_recv_result(result_rx).await; + assert_matches!(result, Err(PrepareError::TimedOut)); + + // Submit another precheck request. + let (result_tx_2, result_rx_2) = oneshot::channel(); + host.precheck_pvf(PvfPrepData::from_discriminator_precheck(1), result_tx_2) + .await + .unwrap(); + + // Assert the prepare queue is empty. + test.poll_ensure_to_prepare_queue_is_empty().await; + + // The result should contain the original error. + let result = test.poll_and_recv_result(result_rx_2).await; + assert_matches!(result, Err(PrepareError::TimedOut)); + + // Pause for enough time to reset the cooldown for this failed prepare request. + futures_timer::Delay::new(PREPARE_FAILURE_COOLDOWN).await; + + // Submit another precheck request. + let (result_tx_3, result_rx_3) = oneshot::channel(); + host.precheck_pvf(PvfPrepData::from_discriminator_precheck(1), result_tx_3) + .await + .unwrap(); + + // Assert the prepare queue is empty - we do not retry for precheck requests. + test.poll_ensure_to_prepare_queue_is_empty().await; + + // The result should still contain the original error. + let result = test.poll_and_recv_result(result_rx_3).await; + assert_matches!(result, Err(PrepareError::TimedOut)); + } + + // Test that multiple execution requests trigger preparation retries if the first one failed due + // to a potentially non-reproducible error. + #[tokio::test] + async fn test_execute_prepare_retry() { + let mut test = Builder::default().build(); + let mut host = test.host_handle(); + + // Submit a execute request that fails. + let (result_tx, result_rx) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(1), + TEST_EXECUTION_TIMEOUT, + b"pvf".to_vec(), + Priority::Critical, + result_tx, + ) + .await + .unwrap(); + + // The queue received the prepare request. + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + // Send a PrepareError. + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(1), + result: Err(PrepareError::TimedOut), + }) + .await + .unwrap(); + + // The result should contain the error. + let result = test.poll_and_recv_result(result_rx).await; + assert_matches!(result, Err(ValidationError::InternalError(_))); + + // Submit another execute request. We shouldn't try to prepare again, yet. + let (result_tx_2, result_rx_2) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(1), + TEST_EXECUTION_TIMEOUT, + b"pvf".to_vec(), + Priority::Critical, + result_tx_2, + ) + .await + .unwrap(); + + // Assert the prepare queue is empty. + test.poll_ensure_to_prepare_queue_is_empty().await; + + // The result should contain the original error. + let result = test.poll_and_recv_result(result_rx_2).await; + assert_matches!(result, Err(ValidationError::InternalError(_))); + + // Pause for enough time to reset the cooldown for this failed prepare request. + futures_timer::Delay::new(PREPARE_FAILURE_COOLDOWN).await; + + // Submit another execute request. + let (result_tx_3, result_rx_3) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(1), + TEST_EXECUTION_TIMEOUT, + b"pvf".to_vec(), + Priority::Critical, + result_tx_3, + ) + .await + .unwrap(); + + // Assert the prepare queue contains the request. + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(1), + result: Ok(PrepareStats::default()), + }) + .await + .unwrap(); + + // Preparation should have been retried and succeeded this time. + let result_tx_3 = assert_matches!( + test.poll_and_recv_to_execute_queue().await, + execute::ToQueue::Enqueue { pending_execution_request: PendingExecutionRequest { result_tx, .. }, .. } => result_tx + ); + + // Send an error for the execution here, just so we can check the result receiver is still + // alive. + result_tx_3 + .send(Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbiguousWorkerDeath))) + .unwrap(); + assert_matches!( + result_rx_3.now_or_never().unwrap().unwrap(), + Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbiguousWorkerDeath)) + ); + } + + // Test that multiple execution requests don't trigger preparation retries if the first one + // failed due to a reproducible error (e.g. Prevalidation). + #[tokio::test] + async fn test_execute_prepare_no_retry() { + let mut test = Builder::default().build(); + let mut host = test.host_handle(); + + // Submit an execute request that fails. + let (result_tx, result_rx) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(1), + TEST_EXECUTION_TIMEOUT, + b"pvf".to_vec(), + Priority::Critical, + result_tx, + ) + .await + .unwrap(); + + // The queue received the prepare request. + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + // Send a PrepareError. + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(1), + result: Err(PrepareError::Prevalidation("reproducible error".into())), + }) + .await + .unwrap(); + + // The result should contain the error. + let result = test.poll_and_recv_result(result_rx).await; + assert_matches!( + result, + Err(ValidationError::InvalidCandidate(InvalidCandidate::PrepareError(_))) + ); + + // Submit another execute request. + let (result_tx_2, result_rx_2) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(1), + TEST_EXECUTION_TIMEOUT, + b"pvf".to_vec(), + Priority::Critical, + result_tx_2, + ) + .await + .unwrap(); + + // Assert the prepare queue is empty. + test.poll_ensure_to_prepare_queue_is_empty().await; + + // The result should contain the original error. + let result = test.poll_and_recv_result(result_rx_2).await; + assert_matches!( + result, + Err(ValidationError::InvalidCandidate(InvalidCandidate::PrepareError(_))) + ); + + // Pause for enough time to reset the cooldown for this failed prepare request. + futures_timer::Delay::new(PREPARE_FAILURE_COOLDOWN).await; + + // Submit another execute request. + let (result_tx_3, result_rx_3) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(1), + TEST_EXECUTION_TIMEOUT, + b"pvf".to_vec(), + Priority::Critical, + result_tx_3, + ) + .await + .unwrap(); + + // Assert the prepare queue is empty - we do not retry for prevalidation errors. + test.poll_ensure_to_prepare_queue_is_empty().await; + + // The result should still contain the original error. + let result = test.poll_and_recv_result(result_rx_3).await; + assert_matches!( + result, + Err(ValidationError::InvalidCandidate(InvalidCandidate::PrepareError(_))) + ); + } + + // Test that multiple heads-up requests trigger preparation retries if the first one failed. + #[tokio::test] + async fn test_heads_up_prepare_retry() { + let mut test = Builder::default().build(); + let mut host = test.host_handle(); + + // Submit a heads-up request that fails. + host.heads_up(vec![PvfPrepData::from_discriminator(1)]).await.unwrap(); + + // The queue received the prepare request. + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + // Send a PrepareError. + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(1), + result: Err(PrepareError::TimedOut), + }) + .await + .unwrap(); + + // Submit another heads-up request. + host.heads_up(vec![PvfPrepData::from_discriminator(1)]).await.unwrap(); + + // Assert the prepare queue is empty. + test.poll_ensure_to_prepare_queue_is_empty().await; + + // Pause for enough time to reset the cooldown for this failed prepare request. + futures_timer::Delay::new(PREPARE_FAILURE_COOLDOWN).await; + + // Submit another heads-up request. + host.heads_up(vec![PvfPrepData::from_discriminator(1)]).await.unwrap(); + + // Assert the prepare queue contains the request. + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + } + + #[tokio::test] + async fn cancellation() { + let mut test = Builder::default().build(); + let mut host = test.host_handle(); + + let (result_tx, result_rx) = oneshot::channel(); + host.execute_pvf( + PvfPrepData::from_discriminator(1), + TEST_EXECUTION_TIMEOUT, + b"pvf1".to_vec(), + Priority::Normal, + result_tx, + ) + .await + .unwrap(); + + assert_matches!( + test.poll_and_recv_to_prepare_queue().await, + prepare::ToQueue::Enqueue { .. } + ); + + test.from_prepare_queue_tx + .send(prepare::FromQueue { + artifact_id: artifact_id(1), + result: Ok(PrepareStats::default()), + }) + .await + .unwrap(); + + drop(result_rx); + + test.poll_ensure_to_execute_queue_is_empty().await; + } +} diff --git a/polkadot/node/core/pvf/src/lib.rs b/polkadot/node/core/pvf/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..1da0593835fb403b36d126cb948fd41247a71742 --- /dev/null +++ b/polkadot/node/core/pvf/src/lib.rs @@ -0,0 +1,127 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![warn(missing_docs)] + +//! The PVF validation host. Responsible for coordinating preparation and execution of PVFs. +//! +//! For more background, refer to the Implementer's Guide: [PVF +//! Pre-checking](https://paritytech.github.io/polkadot/book/pvf-prechecking.html) and [Candidate +//! Validation](https://paritytech.github.io/polkadot/book/node/utility/candidate-validation.html#pvf-host). +//! +//! # Entrypoint +//! +//! This crate provides a simple API. You first [`start`] the validation host, which gives you the +//! [handle][`ValidationHost`] and the future you need to poll. +//! +//! Then using the handle the client can send three types of requests: +//! +//! (a) PVF pre-checking. This takes the `Pvf` code and tries to prepare it (verify and +//! compile) in order to pre-check its validity. +//! +//! (b) PVF execution. This accepts the PVF +//! [`params`][`polkadot_parachain::primitives::ValidationParams`] and the `Pvf` code, prepares +//! (verifies and compiles) the code, and then executes PVF with the `params`. +//! +//! (c) Heads up. This request allows to signal that the given PVF may be needed soon and that it +//! should be prepared for execution. +//! +//! The preparation results are cached for some time after they either used or was signaled in heads +//! up. All requests that depends on preparation of the same PVF are bundled together and will be +//! executed as soon as the artifact is prepared. +//! +//! # Priority +//! +//! PVF execution requests can specify the [priority][`Priority`] with which the given request +//! should be handled. Different priority levels have different effects. This is discussed below. +//! +//! Preparation started by a heads up signal always starts with the background priority. If there +//! is already a request for that PVF preparation under way the priority is inherited. If after +//! heads up, a new PVF execution request comes in with a higher priority, then the original task's +//! priority will be adjusted to match the new one if it's larger. +//! +//! Priority can never go down, only up. +//! +//! # Under the hood +//! +//! ## The flow +//! +//! Under the hood, the validation host is built using a bunch of communicating processes, not +//! dissimilar to actors. Each of such "processes" is a future task that contains an event loop that +//! processes incoming messages, potentially delegating sub-tasks to other "processes". +//! +//! Two of these processes are queues. The first one is for preparation jobs and the second one is +//! for execution. Both of the queues are backed by separate pools of workers of different kind. +//! +//! Preparation workers handle preparation requests by prevalidating and instrumenting PVF wasm +//! code, and then passing it into the compiler, to prepare the artifact. +//! +//! ## Artifacts +//! +//! An artifact is the final product of preparation. If the preparation succeeded, then the artifact +//! will contain the compiled code usable for quick execution by a worker later on. If the +//! preparation failed, then no artifact is created. +//! +//! The artifact is saved on disk and is also tracked by an in memory table. This in memory table +//! doesn't contain the artifact contents though, only a flag for the state of the given artifact +//! and some associated data. If the artifact failed to process, this also includes the error. +//! +//! A pruning task will run at a fixed interval of time. This task will remove all artifacts that +//! weren't used or received a heads up signal for a while. +//! +//! ## Execution +//! +//! The execute workers will be fed by the requests from the execution queue, which is basically a +//! combination of a path to the compiled artifact and the +//! [`params`][`polkadot_parachain::primitives::ValidationParams`]. + +mod artifacts; +mod error; +mod execute; +mod host; +mod metrics; +mod prepare; +mod priority; +mod worker_intf; + +#[cfg(feature = "test-utils")] +pub mod testing; + +// Used by `decl_puppet_worker_main!`. +#[cfg(feature = "test-utils")] +pub use sp_tracing; + +pub use error::{InvalidCandidate, ValidationError}; +pub use host::{start, Config, ValidationHost, EXECUTE_BINARY_NAME, PREPARE_BINARY_NAME}; +pub use metrics::Metrics; +pub use priority::Priority; +pub use worker_intf::{framed_recv, framed_send, JOB_TIMEOUT_WALL_CLOCK_FACTOR}; + +// Re-export some common types. +pub use polkadot_node_core_pvf_common::{ + error::{InternalValidationError, PrepareError}, + prepare::{PrepareJobKind, PrepareStats}, + pvf::PvfPrepData, +}; + +// Re-export worker entrypoints. +#[cfg(feature = "test-utils")] +pub use polkadot_node_core_pvf_execute_worker::worker_entrypoint as execute_worker_entrypoint; +#[cfg(feature = "test-utils")] +pub use polkadot_node_core_pvf_prepare_worker::worker_entrypoint as prepare_worker_entrypoint; + +/// The log target for this crate. +pub const LOG_TARGET: &str = "parachain::pvf"; diff --git a/polkadot/node/core/pvf/src/metrics.rs b/polkadot/node/core/pvf/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..3d792793498b5ef69967a4337c4adc8425623fee --- /dev/null +++ b/polkadot/node/core/pvf/src/metrics.rs @@ -0,0 +1,319 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Prometheus metrics related to the validation host. + +use polkadot_node_core_pvf_common::prepare::MemoryStats; +use polkadot_node_metrics::metrics::{self, prometheus}; + +/// Validation host metrics. +#[derive(Default, Clone)] +pub struct Metrics(Option); + +impl Metrics { + /// Returns a handle to submit prepare workers metrics. + pub(crate) fn prepare_worker(&'_ self) -> WorkerRelatedMetrics<'_> { + WorkerRelatedMetrics { metrics: self, flavor: WorkerFlavor::Prepare } + } + + /// Returns a handle to submit execute workers metrics. + pub(crate) fn execute_worker(&'_ self) -> WorkerRelatedMetrics<'_> { + WorkerRelatedMetrics { metrics: self, flavor: WorkerFlavor::Execute } + } + + /// When preparation pipeline had a new item enqueued. + pub(crate) fn prepare_enqueued(&self) { + if let Some(metrics) = &self.0 { + metrics.prepare_enqueued.inc(); + } + } + + /// When preparation pipeline concluded working on an item. + pub(crate) fn prepare_concluded(&self) { + if let Some(metrics) = &self.0 { + metrics.prepare_concluded.inc(); + } + } + + /// When execution pipeline had a new item enqueued. + pub(crate) fn execute_enqueued(&self) { + if let Some(metrics) = &self.0 { + metrics.execute_enqueued.inc(); + } + } + + /// When execution pipeline finished executing a request. + pub(crate) fn execute_finished(&self) { + if let Some(metrics) = &self.0 { + metrics.execute_finished.inc(); + } + } + + /// Time between sending preparation request to a worker to having the response. + pub(crate) fn time_preparation( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.preparation_time.start_timer()) + } + + /// Time between sending execution request to a worker to having the response. + pub(crate) fn time_execution(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.execution_time.start_timer()) + } + + /// Observe memory stats for preparation. + #[allow(unused_variables)] + pub(crate) fn observe_preparation_memory_metrics(&self, memory_stats: MemoryStats) { + if let Some(metrics) = &self.0 { + #[cfg(target_os = "linux")] + if let Some(max_rss) = memory_stats.max_rss { + metrics.preparation_max_rss.observe(max_rss as f64); + } + + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + if let Some(tracker_stats) = memory_stats.memory_tracker_stats { + // We convert these stats from B to KB to match the unit of `ru_maxrss` from + // `getrusage`. + let max_resident_kb = (tracker_stats.resident / 1024) as f64; + let max_allocated_kb = (tracker_stats.allocated / 1024) as f64; + + metrics.preparation_max_resident.observe(max_resident_kb); + metrics.preparation_max_allocated.observe(max_allocated_kb); + } + } + } +} + +#[derive(Clone)] +struct MetricsInner { + worker_spawning: prometheus::CounterVec, + worker_spawned: prometheus::CounterVec, + worker_retired: prometheus::CounterVec, + prepare_enqueued: prometheus::Counter, + prepare_concluded: prometheus::Counter, + execute_enqueued: prometheus::Counter, + execute_finished: prometheus::Counter, + preparation_time: prometheus::Histogram, + execution_time: prometheus::Histogram, + #[cfg(target_os = "linux")] + preparation_max_rss: prometheus::Histogram, + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + preparation_max_allocated: prometheus::Histogram, + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + preparation_max_resident: prometheus::Histogram, +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let inner = MetricsInner { + worker_spawning: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_pvf_worker_spawning", + "The total number of workers began to spawn", + ), + &["flavor"], + )?, + registry, + )?, + worker_spawned: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_pvf_worker_spawned", + "The total number of workers spawned successfully", + ), + &["flavor"], + )?, + registry, + )?, + worker_retired: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_pvf_worker_retired", + "The total number of workers retired, either killed by the host or died on duty", + ), + &["flavor"], + )?, + registry, + )?, + prepare_enqueued: prometheus::register( + prometheus::Counter::new( + "polkadot_pvf_prepare_enqueued", + "The total number of jobs enqueued into the preparation pipeline" + )?, + registry, + )?, + prepare_concluded: prometheus::register( + prometheus::Counter::new( + "polkadot_pvf_prepare_concluded", + "The total number of jobs concluded in the preparation pipeline" + )?, + registry, + )?, + execute_enqueued: prometheus::register( + prometheus::Counter::new( + "polkadot_pvf_execute_enqueued", + "The total number of jobs enqueued into the execution pipeline" + )?, + registry, + )?, + execute_finished: prometheus::register( + prometheus::Counter::new( + "polkadot_pvf_execute_finished", + "The total number of jobs done in the execution pipeline" + )?, + registry, + )?, + preparation_time: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_pvf_preparation_time", + "Time spent in preparing PVF artifacts in seconds", + ) + .buckets(vec![ + // This is synchronized with the `DEFAULT_PRECHECK_PREPARATION_TIMEOUT=60s` + // and `DEFAULT_LENIENT_PREPARATION_TIMEOUT=360s` constants found in + // node/core/candidate-validation/src/lib.rs + 0.1, + 0.5, + 1.0, + 2.0, + 3.0, + 10.0, + 20.0, + 30.0, + 60.0, + 120.0, + 240.0, + 360.0, + 480.0, + ]), + )?, + registry, + )?, + execution_time: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_pvf_execution_time", + "Time spent in executing PVFs", + ).buckets(vec![ + // This is synchronized with `DEFAULT_APPROVAL_EXECUTION_TIMEOUT` and + // `DEFAULT_BACKING_EXECUTION_TIMEOUT` constants in + // node/core/candidate-validation/src/lib.rs + 0.01, + 0.025, + 0.05, + 0.1, + 0.25, + 0.5, + 1.0, + 2.0, + 3.0, + 4.0, + 5.0, + 6.0, + 8.0, + 10.0, + 12.0, + ]), + )?, + registry, + )?, + #[cfg(target_os = "linux")] + preparation_max_rss: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_pvf_preparation_max_rss", + "ru_maxrss (maximum resident set size) observed for preparation (in kilobytes)", + ).buckets( + prometheus::exponential_buckets(8192.0, 2.0, 10) + .expect("arguments are always valid; qed"), + ), + )?, + registry, + )?, + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + preparation_max_resident: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_pvf_preparation_max_resident", + "max resident memory observed for preparation (in kilobytes)", + ).buckets( + prometheus::exponential_buckets(8192.0, 2.0, 10) + .expect("arguments are always valid; qed"), + ), + )?, + registry, + )?, + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + preparation_max_allocated: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_pvf_preparation_max_allocated", + "max allocated memory observed for preparation (in kilobytes)", + ).buckets( + prometheus::exponential_buckets(8192.0, 2.0, 10) + .expect("arguments are always valid; qed"), + ), + )?, + registry, + )?, + }; + Ok(Metrics(Some(inner))) + } +} + +enum WorkerFlavor { + Prepare, + Execute, +} + +impl WorkerFlavor { + fn as_label(&self) -> &'static str { + match *self { + WorkerFlavor::Prepare => "prepare", + WorkerFlavor::Execute => "execute", + } + } +} + +pub(crate) struct WorkerRelatedMetrics<'a> { + metrics: &'a Metrics, + flavor: WorkerFlavor, +} + +impl<'a> WorkerRelatedMetrics<'a> { + /// When the spawning of a worker started. + pub(crate) fn on_begin_spawn(&self) { + if let Some(metrics) = &self.metrics.0 { + metrics.worker_spawning.with_label_values(&[self.flavor.as_label()]).inc(); + } + } + + /// When the worker successfully spawned. + pub(crate) fn on_spawned(&self) { + if let Some(metrics) = &self.metrics.0 { + metrics.worker_spawned.with_label_values(&[self.flavor.as_label()]).inc(); + } + } + + /// When the worker was killed or died. + pub(crate) fn on_retired(&self) { + if let Some(metrics) = &self.metrics.0 { + metrics.worker_retired.with_label_values(&[self.flavor.as_label()]).inc(); + } + } +} diff --git a/polkadot/node/core/pvf/src/prepare/mod.rs b/polkadot/node/core/pvf/src/prepare/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..580f67f73fa0c126994395ce5a2129234fca51a3 --- /dev/null +++ b/polkadot/node/core/pvf/src/prepare/mod.rs @@ -0,0 +1,30 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Preparation part of pipeline +//! +//! The validation host spins up two processes: the queue (by running [`start_queue`]) and the pool +//! (by running [`start_pool`]). +//! +//! The pool will spawn workers in new processes and those should execute pass control to +//! `polkadot_node_core_pvf_worker::prepare_worker_entrypoint`. + +mod pool; +mod queue; +mod worker_intf; + +pub use pool::start as start_pool; +pub use queue::{start as start_queue, FromQueue, ToQueue}; diff --git a/polkadot/node/core/pvf/src/prepare/pool.rs b/polkadot/node/core/pvf/src/prepare/pool.rs new file mode 100644 index 0000000000000000000000000000000000000000..92aa4896c263ce5c4e6aac507ed2eee61a3cdd3b --- /dev/null +++ b/polkadot/node/core/pvf/src/prepare/pool.rs @@ -0,0 +1,454 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::worker_intf::{self, Outcome}; +use crate::{ + metrics::Metrics, + worker_intf::{IdleWorker, WorkerHandle}, + LOG_TARGET, +}; +use always_assert::never; +use futures::{ + channel::mpsc, future::BoxFuture, stream::FuturesUnordered, Future, FutureExt, StreamExt, +}; +use polkadot_node_core_pvf_common::{ + error::{PrepareError, PrepareResult}, + pvf::PvfPrepData, +}; +use slotmap::HopSlotMap; +use std::{ + fmt, + path::{Path, PathBuf}, + task::Poll, + time::Duration, +}; + +slotmap::new_key_type! { pub struct Worker; } + +/// Messages that the pool handles. +#[derive(Debug, PartialEq, Eq)] +pub enum ToPool { + /// Request a new worker to spawn. + /// + /// This request won't fail in case if the worker cannot be created. Instead, we consider + /// the failures transient and we try to spawn a worker after a delay. + /// + /// [`FromPool::Spawned`] will be returned as soon as the worker is spawned. + /// + /// The client should anticipate a [`FromPool::Rip`] message, in case the spawned worker was + /// stopped for some reason. + Spawn, + + /// Kill the given worker. No-op if the given worker is not running. + /// + /// [`FromPool::Rip`] won't be sent in this case. However, the client should be prepared to + /// receive [`FromPool::Rip`] nonetheless, since the worker may be have been ripped before + /// this message is processed. + Kill(Worker), + + /// Request the given worker to start working on the given code. + /// + /// Once the job either succeeded or failed, a [`FromPool::Concluded`] message will be sent + /// back. It's also possible that the worker dies before handling the message in which case + /// [`FromPool::Rip`] will be sent back. + /// + /// In either case, the worker is considered busy and no further `StartWork` messages should be + /// sent until either `Concluded` or `Rip` message is received. + StartWork { worker: Worker, pvf: PvfPrepData, artifact_path: PathBuf }, +} + +/// A message sent from pool to its client. +#[derive(Debug)] +pub enum FromPool { + /// The given worker was just spawned and is ready to be used. + Spawned(Worker), + + /// The given worker either succeeded or failed the given job. + Concluded { + /// A key for retrieving the worker data from the pool. + worker: Worker, + /// Indicates whether the worker process was killed. + rip: bool, + /// [`Ok`] indicates that compiled artifact is successfully stored on disk. + /// Otherwise, an [error](PrepareError) is supplied. + result: PrepareResult, + }, + + /// The given worker ceased to exist. + Rip(Worker), +} + +struct WorkerData { + idle: Option, + handle: WorkerHandle, +} + +impl fmt::Debug for WorkerData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "WorkerData(pid={})", self.handle.id()) + } +} + +enum PoolEvent { + Spawn(IdleWorker, WorkerHandle), + StartWork(Worker, Outcome), +} + +type Mux = FuturesUnordered>; + +struct Pool { + program_path: PathBuf, + cache_path: PathBuf, + spawn_timeout: Duration, + node_version: Option, + + to_pool: mpsc::Receiver, + from_pool: mpsc::UnboundedSender, + spawned: HopSlotMap, + mux: Mux, + + metrics: Metrics, +} + +/// A fatal error that warrants stopping the event loop of the pool. +struct Fatal; + +async fn run( + Pool { + program_path, + cache_path, + spawn_timeout, + node_version, + to_pool, + mut from_pool, + mut spawned, + mut mux, + metrics, + }: Pool, +) { + macro_rules! break_if_fatal { + ($expr:expr) => { + match $expr { + Err(Fatal) => break, + Ok(v) => v, + } + }; + } + + let mut to_pool = to_pool.fuse(); + + loop { + futures::select! { + to_pool = to_pool.next() => { + let to_pool = break_if_fatal!(to_pool.ok_or(Fatal)); + handle_to_pool( + &metrics, + &program_path, + &cache_path, + spawn_timeout, + node_version.clone(), + &mut spawned, + &mut mux, + to_pool, + ) + } + ev = mux.select_next_some() => { + break_if_fatal!(handle_mux(&metrics, &mut from_pool, &mut spawned, ev)) + } + } + + break_if_fatal!(purge_dead(&metrics, &mut from_pool, &mut spawned).await); + } +} + +async fn purge_dead( + metrics: &Metrics, + from_pool: &mut mpsc::UnboundedSender, + spawned: &mut HopSlotMap, +) -> Result<(), Fatal> { + let mut to_remove = vec![]; + for (worker, data) in spawned.iter_mut() { + if data.idle.is_none() { + // The idle token is missing, meaning this worker is now occupied: skip it. This is + // because the worker process is observed by the work task and should it reach the + // deadline or be terminated it will be handled by the corresponding mux event. + continue + } + + if let Poll::Ready(()) = futures::poll!(&mut data.handle) { + // a resolved future means that the worker has terminated. Weed it out. + to_remove.push(worker); + } + } + for w in to_remove { + if attempt_retire(metrics, spawned, w) { + reply(from_pool, FromPool::Rip(w))?; + } + } + Ok(()) +} + +fn handle_to_pool( + metrics: &Metrics, + program_path: &Path, + cache_path: &Path, + spawn_timeout: Duration, + node_version: Option, + spawned: &mut HopSlotMap, + mux: &mut Mux, + to_pool: ToPool, +) { + match to_pool { + ToPool::Spawn => { + gum::debug!(target: LOG_TARGET, "spawning a new prepare worker"); + metrics.prepare_worker().on_begin_spawn(); + mux.push( + spawn_worker_task(program_path.to_owned(), spawn_timeout, node_version).boxed(), + ); + }, + ToPool::StartWork { worker, pvf, artifact_path } => { + if let Some(data) = spawned.get_mut(worker) { + if let Some(idle) = data.idle.take() { + let preparation_timer = metrics.time_preparation(); + mux.push( + start_work_task( + metrics.clone(), + worker, + idle, + pvf, + cache_path.to_owned(), + artifact_path, + preparation_timer, + ) + .boxed(), + ); + } else { + // idle token is present after spawn and after a job is concluded; + // the precondition for `StartWork` is it should be sent only if all previous + // work items concluded; + // thus idle token is Some; + // qed. + never!("unexpected absence of the idle token in prepare pool"); + } + } else { + // That's a relatively normal situation since the queue may send `start_work` and + // before receiving it the pool would report that the worker died. + } + }, + ToPool::Kill(worker) => { + gum::debug!(target: LOG_TARGET, ?worker, "killing prepare worker"); + // It may be absent if it were previously already removed by `purge_dead`. + let _ = attempt_retire(metrics, spawned, worker); + }, + } +} + +async fn spawn_worker_task( + program_path: PathBuf, + spawn_timeout: Duration, + node_version: Option, +) -> PoolEvent { + use futures_timer::Delay; + + loop { + match worker_intf::spawn(&program_path, spawn_timeout, node_version.as_deref()).await { + Ok((idle, handle)) => break PoolEvent::Spawn(idle, handle), + Err(err) => { + gum::warn!(target: LOG_TARGET, "failed to spawn a prepare worker: {:?}", err); + + // Assume that the failure intermittent and retry after a delay. + Delay::new(Duration::from_secs(3)).await; + }, + } + } +} + +async fn start_work_task( + metrics: Metrics, + worker: Worker, + idle: IdleWorker, + pvf: PvfPrepData, + cache_path: PathBuf, + artifact_path: PathBuf, + _preparation_timer: Option, +) -> PoolEvent { + let outcome = worker_intf::start_work(&metrics, idle, pvf, &cache_path, artifact_path).await; + PoolEvent::StartWork(worker, outcome) +} + +fn handle_mux( + metrics: &Metrics, + from_pool: &mut mpsc::UnboundedSender, + spawned: &mut HopSlotMap, + event: PoolEvent, +) -> Result<(), Fatal> { + match event { + PoolEvent::Spawn(idle, handle) => { + metrics.prepare_worker().on_spawned(); + + let worker = spawned.insert(WorkerData { idle: Some(idle), handle }); + + reply(from_pool, FromPool::Spawned(worker))?; + + Ok(()) + }, + PoolEvent::StartWork(worker, outcome) => { + // If we receive an outcome that the worker is unreachable or that an error occurred on + // the worker, we attempt to kill the worker process. + match outcome { + Outcome::Concluded { worker: idle, result } => + handle_concluded_no_rip(from_pool, spawned, worker, idle, result), + // Return `Concluded`, but do not kill the worker since the error was on the host + // side. + Outcome::CreateTmpFileErr { worker: idle, err } => handle_concluded_no_rip( + from_pool, + spawned, + worker, + idle, + Err(PrepareError::CreateTmpFileErr(err)), + ), + // Return `Concluded`, but do not kill the worker since the error was on the host + // side. + Outcome::RenameTmpFileErr { worker: idle, result: _, err } => + handle_concluded_no_rip( + from_pool, + spawned, + worker, + idle, + Err(PrepareError::RenameTmpFileErr(err)), + ), + Outcome::Unreachable => { + if attempt_retire(metrics, spawned, worker) { + reply(from_pool, FromPool::Rip(worker))?; + } + + Ok(()) + }, + Outcome::IoErr(err) => { + if attempt_retire(metrics, spawned, worker) { + reply( + from_pool, + FromPool::Concluded { + worker, + rip: true, + result: Err(PrepareError::IoErr(err)), + }, + )?; + } + + Ok(()) + }, + Outcome::TimedOut => { + if attempt_retire(metrics, spawned, worker) { + reply( + from_pool, + FromPool::Concluded { + worker, + rip: true, + result: Err(PrepareError::TimedOut), + }, + )?; + } + + Ok(()) + }, + } + }, + } +} + +fn reply(from_pool: &mut mpsc::UnboundedSender, m: FromPool) -> Result<(), Fatal> { + from_pool.unbounded_send(m).map_err(|_| Fatal) +} + +/// Removes the given worker from the registry if it there. This will lead to dropping and hence +/// to killing the worker process. +/// +/// Returns `true` if the worker exists and was removed and the process was killed. +/// +/// This function takes care about counting the retired workers metric. +fn attempt_retire( + metrics: &Metrics, + spawned: &mut HopSlotMap, + worker: Worker, +) -> bool { + if spawned.remove(worker).is_some() { + metrics.prepare_worker().on_retired(); + true + } else { + false + } +} + +/// Handles the case where we received a response. There potentially was an error, but not the fault +/// of the worker as far as we know, so the worker should not be killed. +/// +/// This function tries to put the idle worker back into the pool and then replies with +/// `FromPool::Concluded` with `rip: false`. +fn handle_concluded_no_rip( + from_pool: &mut mpsc::UnboundedSender, + spawned: &mut HopSlotMap, + worker: Worker, + idle: IdleWorker, + result: PrepareResult, +) -> Result<(), Fatal> { + let data = match spawned.get_mut(worker) { + None => { + // Perhaps the worker was killed meanwhile and the result is no longer relevant. We + // already send `Rip` when purging if we detect that the worker is dead. + return Ok(()) + }, + Some(data) => data, + }; + + // We just replace the idle worker that was loaned from this option during + // the work starting. + let old = data.idle.replace(idle); + never!( + old.is_some(), + "old idle worker was taken out when starting work; we only replace it here; qed" + ); + + reply(from_pool, FromPool::Concluded { worker, rip: false, result })?; + + Ok(()) +} + +/// Spins up the pool and returns the future that should be polled to make the pool functional. +pub fn start( + metrics: Metrics, + program_path: PathBuf, + cache_path: PathBuf, + spawn_timeout: Duration, + node_version: Option, +) -> (mpsc::Sender, mpsc::UnboundedReceiver, impl Future) { + let (to_pool_tx, to_pool_rx) = mpsc::channel(10); + let (from_pool_tx, from_pool_rx) = mpsc::unbounded(); + + let run = run(Pool { + metrics, + program_path, + cache_path, + spawn_timeout, + node_version, + to_pool: to_pool_rx, + from_pool: from_pool_tx, + spawned: HopSlotMap::with_capacity_and_key(20), + mux: Mux::new(), + }); + + (to_pool_tx, from_pool_rx, run) +} diff --git a/polkadot/node/core/pvf/src/prepare/queue.rs b/polkadot/node/core/pvf/src/prepare/queue.rs new file mode 100644 index 0000000000000000000000000000000000000000..c38012d745482e66fa4d74647e34663447b8f0d5 --- /dev/null +++ b/polkadot/node/core/pvf/src/prepare/queue.rs @@ -0,0 +1,796 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A queue that handles requests for PVF preparation. + +use super::pool::{self, Worker}; +use crate::{artifacts::ArtifactId, metrics::Metrics, Priority, LOG_TARGET}; +use always_assert::{always, never}; +use futures::{channel::mpsc, stream::StreamExt as _, Future, SinkExt}; +use polkadot_node_core_pvf_common::{error::PrepareResult, pvf::PvfPrepData}; +use std::{ + collections::{HashMap, VecDeque}, + path::PathBuf, +}; + +#[cfg(test)] +use std::time::Duration; + +/// A request to pool. +#[derive(Debug)] +pub enum ToQueue { + /// This schedules preparation of the given PVF. + /// + /// Note that it is incorrect to enqueue the same PVF again without first receiving the + /// [`FromQueue`] response. + Enqueue { priority: Priority, pvf: PvfPrepData }, +} + +/// A response from queue. +#[derive(Debug)] +pub struct FromQueue { + /// Identifier of an artifact. + pub(crate) artifact_id: ArtifactId, + /// Outcome of the PVF processing. [`Ok`] indicates that compiled artifact + /// is successfully stored on disk. Otherwise, an [error](crate::error::PrepareError) + /// is supplied. + pub(crate) result: PrepareResult, +} + +#[derive(Default)] +struct Limits { + /// The maximum number of workers this pool can ever host. This is expected to be a small + /// number, e.g. within a dozen. + hard_capacity: usize, + + /// The number of workers we want aim to have. If there is a critical job and we are already + /// at `soft_capacity`, we are allowed to grow up to `hard_capacity`. Thus this should be equal + /// or smaller than `hard_capacity`. + soft_capacity: usize, +} + +impl Limits { + /// Returns `true` if the queue is allowed to request one more worker. + fn can_afford_one_more(&self, spawned_num: usize, critical: bool) -> bool { + let cap = if critical { self.hard_capacity } else { self.soft_capacity }; + spawned_num < cap + } + + /// Offer the worker back to the pool. The passed worker ID must be considered unusable unless + /// it wasn't taken by the pool, in which case it will be returned as `Some`. + fn should_cull(&mut self, spawned_num: usize) -> bool { + spawned_num > self.soft_capacity + } +} + +slotmap::new_key_type! { pub struct Job; } + +struct JobData { + /// The priority of this job. Can be bumped. + priority: Priority, + pvf: PvfPrepData, + worker: Option, +} + +#[derive(Default)] +struct WorkerData { + job: Option, +} + +impl WorkerData { + fn is_idle(&self) -> bool { + self.job.is_none() + } +} + +/// A queue structured like this is prone to starving, however, we don't care that much since we +/// expect there is going to be a limited number of critical jobs and we don't really care if +/// background starve. +#[derive(Default)] +struct Unscheduled { + normal: VecDeque, + critical: VecDeque, +} + +impl Unscheduled { + fn queue_mut(&mut self, prio: Priority) -> &mut VecDeque { + match prio { + Priority::Normal => &mut self.normal, + Priority::Critical => &mut self.critical, + } + } + + fn add(&mut self, prio: Priority, job: Job) { + self.queue_mut(prio).push_back(job); + } + + fn readd(&mut self, prio: Priority, job: Job) { + self.queue_mut(prio).push_front(job); + } + + fn is_empty(&self) -> bool { + self.normal.is_empty() && self.critical.is_empty() + } + + fn next(&mut self) -> Option { + let mut check = |prio: Priority| self.queue_mut(prio).pop_front(); + check(Priority::Critical).or_else(|| check(Priority::Normal)) + } +} + +struct Queue { + metrics: Metrics, + + to_queue_rx: mpsc::Receiver, + from_queue_tx: mpsc::UnboundedSender, + + to_pool_tx: mpsc::Sender, + from_pool_rx: mpsc::UnboundedReceiver, + + cache_path: PathBuf, + limits: Limits, + + jobs: slotmap::SlotMap, + + /// A mapping from artifact id to a job. + artifact_id_to_job: HashMap, + /// The registry of all workers. + workers: slotmap::SparseSecondaryMap, + /// The number of workers requested to spawn but not yet spawned. + spawn_inflight: usize, + + /// The jobs that are not yet scheduled. These are waiting until the next `poll` where they are + /// processed all at once. + unscheduled: Unscheduled, +} + +/// A fatal error that warrants stopping the queue. +struct Fatal; + +impl Queue { + fn new( + metrics: Metrics, + soft_capacity: usize, + hard_capacity: usize, + cache_path: PathBuf, + to_queue_rx: mpsc::Receiver, + from_queue_tx: mpsc::UnboundedSender, + to_pool_tx: mpsc::Sender, + from_pool_rx: mpsc::UnboundedReceiver, + ) -> Self { + Self { + metrics, + to_queue_rx, + from_queue_tx, + to_pool_tx, + from_pool_rx, + cache_path, + spawn_inflight: 0, + limits: Limits { hard_capacity, soft_capacity }, + jobs: slotmap::SlotMap::with_key(), + unscheduled: Unscheduled::default(), + artifact_id_to_job: HashMap::new(), + workers: slotmap::SparseSecondaryMap::new(), + } + } + + async fn run(mut self) { + macro_rules! break_if_fatal { + ($expr:expr) => { + if let Err(Fatal) = $expr { + break + } + }; + } + + loop { + // biased to make it behave deterministically for tests. + futures::select_biased! { + to_queue = self.to_queue_rx.select_next_some() => + break_if_fatal!(handle_to_queue(&mut self, to_queue).await), + from_pool = self.from_pool_rx.select_next_some() => + break_if_fatal!(handle_from_pool(&mut self, from_pool).await), + } + } + } +} + +async fn handle_to_queue(queue: &mut Queue, to_queue: ToQueue) -> Result<(), Fatal> { + match to_queue { + ToQueue::Enqueue { priority, pvf } => { + handle_enqueue(queue, priority, pvf).await?; + }, + } + Ok(()) +} + +async fn handle_enqueue( + queue: &mut Queue, + priority: Priority, + pvf: PvfPrepData, +) -> Result<(), Fatal> { + gum::debug!( + target: LOG_TARGET, + validation_code_hash = ?pvf.code_hash(), + ?priority, + preparation_timeout = ?pvf.prep_timeout(), + "PVF is enqueued for preparation.", + ); + queue.metrics.prepare_enqueued(); + + let artifact_id = ArtifactId::from_pvf_prep_data(&pvf); + if never!( + queue.artifact_id_to_job.contains_key(&artifact_id), + "second Enqueue sent for a known artifact" + ) { + // This function is called in response to a `Enqueue` message; + // Precondition for `Enqueue` is that it is sent only once for a PVF; + // Thus this should always be `false`; + // qed. + gum::warn!( + target: LOG_TARGET, + "duplicate `enqueue` command received for {:?}", + artifact_id, + ); + return Ok(()) + } + + let job = queue.jobs.insert(JobData { priority, pvf, worker: None }); + queue.artifact_id_to_job.insert(artifact_id, job); + + if let Some(available) = find_idle_worker(queue) { + // This may seem not fair (w.r.t priority) on the first glance, but it should be. This is + // because as soon as a worker finishes with the job it's immediately given the next one. + assign(queue, available, job).await?; + } else { + spawn_extra_worker(queue, priority.is_critical()).await?; + queue.unscheduled.add(priority, job); + } + + Ok(()) +} + +fn find_idle_worker(queue: &mut Queue) -> Option { + queue.workers.iter().filter(|(_, data)| data.is_idle()).map(|(k, _)| k).next() +} + +async fn handle_from_pool(queue: &mut Queue, from_pool: pool::FromPool) -> Result<(), Fatal> { + use pool::FromPool::*; + match from_pool { + Spawned(worker) => handle_worker_spawned(queue, worker).await?, + Concluded { worker, rip, result } => + handle_worker_concluded(queue, worker, rip, result).await?, + Rip(worker) => handle_worker_rip(queue, worker).await?, + } + Ok(()) +} + +async fn handle_worker_spawned(queue: &mut Queue, worker: Worker) -> Result<(), Fatal> { + queue.workers.insert(worker, WorkerData::default()); + queue.spawn_inflight -= 1; + + if let Some(job) = queue.unscheduled.next() { + assign(queue, worker, job).await?; + } + + Ok(()) +} + +async fn handle_worker_concluded( + queue: &mut Queue, + worker: Worker, + rip: bool, + result: PrepareResult, +) -> Result<(), Fatal> { + queue.metrics.prepare_concluded(); + + macro_rules! never_none { + ($expr:expr) => { + match $expr { + Some(v) => v, + None => { + // Precondition of calling this is that the `$expr` is never none; + // Assume the conditions holds, then this never is not hit; + // qed. + never!("never_none, {}", stringify!($expr)); + return Ok(()) + }, + } + }; + } + + // Find out on which artifact was the worker working. + + // workers are registered upon spawn and removed in one of the following cases: + // 1. received rip signal + // 2. received concluded signal with rip=true; + // concluded signal only comes from a spawned worker and only once; + // rip signal is not sent after conclusion with rip=true; + // the worker should be registered; + // this can't be None; + // qed. + let worker_data = never_none!(queue.workers.get_mut(worker)); + + // worker_data.job is set only by `assign` and removed only here for a worker; + // concluded signal only comes for a worker that was previously assigned and only once; + // the worker should have the job; + // this can't be None; + // qed. + let job = never_none!(worker_data.job.take()); + + // job_data is inserted upon enqueue and removed only here; + // as was established above, this worker was previously `assign`ed to the job; + // that implies that the job was enqueued; + // conclude signal only comes once; + // we are just to remove the job for the first and the only time; + // this can't be None; + // qed. + let job_data = never_none!(queue.jobs.remove(job)); + let artifact_id = ArtifactId::from_pvf_prep_data(&job_data.pvf); + + queue.artifact_id_to_job.remove(&artifact_id); + + gum::debug!( + target: LOG_TARGET, + validation_code_hash = ?artifact_id.code_hash, + ?worker, + ?rip, + "prepare worker concluded", + ); + + reply(&mut queue.from_queue_tx, FromQueue { artifact_id, result })?; + + // Figure out what to do with the worker. + if rip { + let worker_data = queue.workers.remove(worker); + // worker should exist, it's asserted above; + // qed. + always!(worker_data.is_some()); + + if !queue.unscheduled.is_empty() { + // That is unconditionally not critical just to not accidentally fill up + // the pool up to the hard cap. + spawn_extra_worker(queue, false).await?; + } + } else if queue.limits.should_cull(queue.workers.len() + queue.spawn_inflight) { + // We no longer need services of this worker. Kill it. + queue.workers.remove(worker); + send_pool(&mut queue.to_pool_tx, pool::ToPool::Kill(worker)).await?; + } else { + // see if there are more work available and schedule it. + if let Some(job) = queue.unscheduled.next() { + assign(queue, worker, job).await?; + } + } + + Ok(()) +} + +async fn handle_worker_rip(queue: &mut Queue, worker: Worker) -> Result<(), Fatal> { + gum::debug!(target: LOG_TARGET, ?worker, "prepare worker ripped"); + + let worker_data = queue.workers.remove(worker); + if let Some(WorkerData { job: Some(job), .. }) = worker_data { + // This is an edge case where the worker ripped after we sent assignment but before it + // was received by the pool. + let priority = queue.jobs.get(job).map(|data| data.priority).unwrap_or_else(|| { + // job is inserted upon enqueue and removed on concluded signal; + // this is enclosed in the if statement that narrows the situation to before + // conclusion; + // that means that the job still exists and is known; + // this path cannot be hit; + // qed. + never!("the job of the ripped worker must be known but it is not"); + Priority::Normal + }); + queue.unscheduled.readd(priority, job); + } + + // If there are still jobs left, spawn another worker to replace the ripped one (but only if it + // was indeed removed). That is unconditionally not critical just to not accidentally fill up + // the pool up to the hard cap. + if worker_data.is_some() && !queue.unscheduled.is_empty() { + spawn_extra_worker(queue, false).await?; + } + Ok(()) +} + +/// Spawns an extra worker if possible. +async fn spawn_extra_worker(queue: &mut Queue, critical: bool) -> Result<(), Fatal> { + if queue + .limits + .can_afford_one_more(queue.workers.len() + queue.spawn_inflight, critical) + { + queue.spawn_inflight += 1; + send_pool(&mut queue.to_pool_tx, pool::ToPool::Spawn).await?; + } + + Ok(()) +} + +/// Attaches the work to the given worker telling the poll about the job. +async fn assign(queue: &mut Queue, worker: Worker, job: Job) -> Result<(), Fatal> { + let job_data = &mut queue.jobs[job]; + + let artifact_id = ArtifactId::from_pvf_prep_data(&job_data.pvf); + let artifact_path = artifact_id.path(&queue.cache_path); + + job_data.worker = Some(worker); + + queue.workers[worker].job = Some(job); + + send_pool( + &mut queue.to_pool_tx, + pool::ToPool::StartWork { worker, pvf: job_data.pvf.clone(), artifact_path }, + ) + .await?; + + Ok(()) +} + +fn reply(from_queue_tx: &mut mpsc::UnboundedSender, m: FromQueue) -> Result<(), Fatal> { + from_queue_tx.unbounded_send(m).map_err(|_| { + // The host has hung up and thus it's fatal and we should shutdown ourselves. + Fatal + }) +} + +async fn send_pool( + to_pool_tx: &mut mpsc::Sender, + m: pool::ToPool, +) -> Result<(), Fatal> { + to_pool_tx.send(m).await.map_err(|_| { + // The pool has hung up and thus we are no longer are able to fulfill our duties. Shutdown. + Fatal + }) +} + +/// Spins up the queue and returns the future that should be polled to make the queue functional. +pub fn start( + metrics: Metrics, + soft_capacity: usize, + hard_capacity: usize, + cache_path: PathBuf, + to_pool_tx: mpsc::Sender, + from_pool_rx: mpsc::UnboundedReceiver, +) -> (mpsc::Sender, mpsc::UnboundedReceiver, impl Future) { + let (to_queue_tx, to_queue_rx) = mpsc::channel(150); + let (from_queue_tx, from_queue_rx) = mpsc::unbounded(); + + let run = Queue::new( + metrics, + soft_capacity, + hard_capacity, + cache_path, + to_queue_rx, + from_queue_tx, + to_pool_tx, + from_pool_rx, + ) + .run(); + + (to_queue_tx, from_queue_rx, run) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::host::tests::TEST_PREPARATION_TIMEOUT; + use assert_matches::assert_matches; + use futures::{future::BoxFuture, FutureExt}; + use polkadot_node_core_pvf_common::{error::PrepareError, prepare::PrepareStats}; + use slotmap::SlotMap; + use std::task::Poll; + + /// Creates a new PVF which artifact id can be uniquely identified by the given number. + fn pvf(discriminator: u32) -> PvfPrepData { + PvfPrepData::from_discriminator(discriminator) + } + + async fn run_until( + task: &mut (impl Future + Unpin), + mut fut: (impl Future + Unpin), + ) -> R { + let start = std::time::Instant::now(); + let fut = &mut fut; + loop { + if start.elapsed() > std::time::Duration::from_secs(1) { + // We expect that this will take only a couple of iterations and thus to take way + // less than a second. + panic!("timeout"); + } + + if let Poll::Ready(r) = futures::poll!(&mut *fut) { + break r + } + + if futures::poll!(&mut *task).is_ready() { + panic!() + } + } + } + + struct Test { + _tempdir: tempfile::TempDir, + run: BoxFuture<'static, ()>, + workers: SlotMap, + from_pool_tx: mpsc::UnboundedSender, + to_pool_rx: mpsc::Receiver, + to_queue_tx: mpsc::Sender, + from_queue_rx: mpsc::UnboundedReceiver, + } + + impl Test { + fn new(soft_capacity: usize, hard_capacity: usize) -> Self { + let tempdir = tempfile::tempdir().unwrap(); + + let (to_pool_tx, to_pool_rx) = mpsc::channel(10); + let (from_pool_tx, from_pool_rx) = mpsc::unbounded(); + + let workers: SlotMap = SlotMap::with_key(); + + let (to_queue_tx, from_queue_rx, run) = start( + Metrics::default(), + soft_capacity, + hard_capacity, + tempdir.path().to_owned().into(), + to_pool_tx, + from_pool_rx, + ); + + Self { + _tempdir: tempdir, + run: run.boxed(), + workers, + from_pool_tx, + to_pool_rx, + to_queue_tx, + from_queue_rx, + } + } + + fn send_queue(&mut self, to_queue: ToQueue) { + self.to_queue_tx.send(to_queue).now_or_never().unwrap().unwrap(); + } + + async fn poll_and_recv_from_queue(&mut self) -> FromQueue { + let from_queue_rx = &mut self.from_queue_rx; + run_until(&mut self.run, async { from_queue_rx.next().await.unwrap() }.boxed()).await + } + + fn send_from_pool(&mut self, from_pool: pool::FromPool) { + self.from_pool_tx.send(from_pool).now_or_never().unwrap().unwrap(); + } + + async fn poll_and_recv_to_pool(&mut self) -> pool::ToPool { + let to_pool_rx = &mut self.to_pool_rx; + run_until(&mut self.run, async { to_pool_rx.next().await.unwrap() }.boxed()).await + } + + async fn poll_ensure_to_pool_is_empty(&mut self) { + use futures_timer::Delay; + + let to_pool_rx = &mut self.to_pool_rx; + run_until( + &mut self.run, + async { + futures::select! { + _ = Delay::new(Duration::from_millis(500)).fuse() => (), + _ = to_pool_rx.next().fuse() => { + panic!("to pool supposed to be empty") + } + } + } + .boxed(), + ) + .await + } + } + + #[tokio::test] + async fn properly_concludes() { + let mut test = Test::new(2, 2); + + test.send_queue(ToQueue::Enqueue { priority: Priority::Normal, pvf: pvf(1) }); + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + + let w = test.workers.insert(()); + test.send_from_pool(pool::FromPool::Spawned(w)); + test.send_from_pool(pool::FromPool::Concluded { + worker: w, + rip: false, + result: Ok(PrepareStats::default()), + }); + + assert_eq!( + test.poll_and_recv_from_queue().await.artifact_id, + ArtifactId::from_pvf_prep_data(&pvf(1)) + ); + } + + #[tokio::test] + async fn dont_spawn_over_soft_limit_unless_critical() { + let mut test = Test::new(2, 3); + + let priority = Priority::Normal; + test.send_queue(ToQueue::Enqueue { priority, pvf: PvfPrepData::from_discriminator(1) }); + test.send_queue(ToQueue::Enqueue { priority, pvf: PvfPrepData::from_discriminator(2) }); + // Start a non-precheck preparation for this one. + test.send_queue(ToQueue::Enqueue { + priority, + pvf: PvfPrepData::from_discriminator_and_timeout(3, TEST_PREPARATION_TIMEOUT * 3), + }); + + // Receive only two spawns. + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + + let w1 = test.workers.insert(()); + let w2 = test.workers.insert(()); + + test.send_from_pool(pool::FromPool::Spawned(w1)); + test.send_from_pool(pool::FromPool::Spawned(w2)); + + // Get two start works. + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); + + test.send_from_pool(pool::FromPool::Concluded { + worker: w1, + rip: false, + result: Ok(PrepareStats::default()), + }); + + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); + + // Enqueue a critical job. + test.send_queue(ToQueue::Enqueue { + priority: Priority::Critical, + pvf: PvfPrepData::from_discriminator(4), + }); + + // 2 out of 2 are working, but there is a critical job incoming. That means that spawning + // another worker is warranted. + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + } + + #[tokio::test] + async fn cull_unwanted() { + let mut test = Test::new(1, 2); + + test.send_queue(ToQueue::Enqueue { + priority: Priority::Normal, + pvf: PvfPrepData::from_discriminator(1), + }); + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + let w1 = test.workers.insert(()); + test.send_from_pool(pool::FromPool::Spawned(w1)); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); + + // Enqueue a critical job, which warrants spawning over the soft limit. + test.send_queue(ToQueue::Enqueue { + priority: Priority::Critical, + pvf: PvfPrepData::from_discriminator(2), + }); + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + + // However, before the new worker had a chance to spawn, the first worker finishes with its + // job. The old worker will be killed while the new worker will be let live, even though + // it's not instantiated. + // + // That's a bit silly in this context, but in production there will be an entire pool up + // to the `soft_capacity` of workers and it doesn't matter which one to cull. Either way, + // we just check that edge case of an edge case works. + test.send_from_pool(pool::FromPool::Concluded { + worker: w1, + rip: false, + result: Ok(PrepareStats::default()), + }); + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Kill(w1)); + } + + #[tokio::test] + async fn worker_mass_die_out_doesnt_stall_queue() { + let mut test = Test::new(2, 2); + + let priority = Priority::Normal; + test.send_queue(ToQueue::Enqueue { priority, pvf: PvfPrepData::from_discriminator(1) }); + test.send_queue(ToQueue::Enqueue { priority, pvf: PvfPrepData::from_discriminator(2) }); + // Start a non-precheck preparation for this one. + test.send_queue(ToQueue::Enqueue { + priority, + pvf: PvfPrepData::from_discriminator_and_timeout(3, TEST_PREPARATION_TIMEOUT * 3), + }); + + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + + let w1 = test.workers.insert(()); + let w2 = test.workers.insert(()); + + test.send_from_pool(pool::FromPool::Spawned(w1)); + test.send_from_pool(pool::FromPool::Spawned(w2)); + + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); + + // Conclude worker 1 and rip it. + test.send_from_pool(pool::FromPool::Concluded { + worker: w1, + rip: true, + result: Ok(PrepareStats::default()), + }); + + // Since there is still work, the queue requested one extra worker to spawn to handle the + // remaining enqueued work items. + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + assert_eq!( + test.poll_and_recv_from_queue().await.artifact_id, + ArtifactId::from_pvf_prep_data(&pvf(1)) + ); + } + + #[tokio::test] + async fn doesnt_resurrect_ripped_worker_if_no_work() { + let mut test = Test::new(2, 2); + + test.send_queue(ToQueue::Enqueue { + priority: Priority::Normal, + pvf: PvfPrepData::from_discriminator(1), + }); + + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + + let w1 = test.workers.insert(()); + test.send_from_pool(pool::FromPool::Spawned(w1)); + + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); + + test.send_from_pool(pool::FromPool::Concluded { + worker: w1, + rip: true, + result: Err(PrepareError::IoErr("test".into())), + }); + test.poll_ensure_to_pool_is_empty().await; + } + + #[tokio::test] + async fn rip_for_start_work() { + let mut test = Test::new(2, 2); + + test.send_queue(ToQueue::Enqueue { + priority: Priority::Normal, + pvf: PvfPrepData::from_discriminator(1), + }); + + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + + let w1 = test.workers.insert(()); + test.send_from_pool(pool::FromPool::Spawned(w1)); + + // Now, to the interesting part. After the queue normally issues the `start_work` command to + // the pool, before receiving the command the queue may report that the worker ripped. + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); + test.send_from_pool(pool::FromPool::Rip(w1)); + + // In this case, the pool should spawn a new worker and request it to work on the item. + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); + + let w2 = test.workers.insert(()); + test.send_from_pool(pool::FromPool::Spawned(w2)); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); + } +} diff --git a/polkadot/node/core/pvf/src/prepare/worker_intf.rs b/polkadot/node/core/pvf/src/prepare/worker_intf.rs new file mode 100644 index 0000000000000000000000000000000000000000..5280ab6b42a235b441fe9d9e25bc415b46ecfa2f --- /dev/null +++ b/polkadot/node/core/pvf/src/prepare/worker_intf.rs @@ -0,0 +1,298 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Host interface to the prepare worker. + +use crate::{ + metrics::Metrics, + worker_intf::{ + path_to_bytes, spawn_with_program_path, tmpfile_in, IdleWorker, SpawnErr, WorkerHandle, + JOB_TIMEOUT_WALL_CLOCK_FACTOR, + }, + LOG_TARGET, +}; +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_core_pvf_common::{ + error::{PrepareError, PrepareResult}, + framed_recv, framed_send, + prepare::PrepareStats, + pvf::PvfPrepData, +}; + +use sp_core::hexdisplay::HexDisplay; +use std::{ + path::{Path, PathBuf}, + time::Duration, +}; +use tokio::{io, net::UnixStream}; + +/// Spawns a new worker with the given program path that acts as the worker and the spawn timeout. +/// +/// The program should be able to handle ` prepare-worker ` invocation. +pub async fn spawn( + program_path: &Path, + spawn_timeout: Duration, + node_version: Option<&str>, +) -> Result<(IdleWorker, WorkerHandle), SpawnErr> { + let mut extra_args = vec!["prepare-worker"]; + if let Some(node_version) = node_version { + extra_args.extend_from_slice(&["--node-impl-version", node_version]); + } + spawn_with_program_path("prepare", program_path, &extra_args, spawn_timeout).await +} + +pub enum Outcome { + /// The worker has finished the work assigned to it. + Concluded { worker: IdleWorker, result: PrepareResult }, + /// The host tried to reach the worker but failed. This is most likely because the worked was + /// killed by the system. + Unreachable, + /// The temporary file for the artifact could not be created at the given cache path. + CreateTmpFileErr { worker: IdleWorker, err: String }, + /// The response from the worker is received, but the file cannot be renamed (moved) to the + /// final destination location. + RenameTmpFileErr { worker: IdleWorker, result: PrepareResult, err: String }, + /// The worker failed to finish the job until the given deadline. + /// + /// The worker is no longer usable and should be killed. + TimedOut, + /// An IO error occurred while receiving the result from the worker process. + /// + /// This doesn't return an idle worker instance, thus this worker is no longer usable. + IoErr(String), +} + +/// Given the idle token of a worker and parameters of work, communicates with the worker and +/// returns the outcome. +/// +/// NOTE: Returning the `TimedOut`, `IoErr` or `Unreachable` outcomes will trigger the child process +/// being killed. +pub async fn start_work( + metrics: &Metrics, + worker: IdleWorker, + pvf: PvfPrepData, + cache_path: &Path, + artifact_path: PathBuf, +) -> Outcome { + let IdleWorker { stream, pid } = worker; + + gum::debug!( + target: LOG_TARGET, + worker_pid = %pid, + "starting prepare for {}", + artifact_path.display(), + ); + + with_tmp_file(stream, pid, cache_path, |tmp_file, mut stream| async move { + let preparation_timeout = pvf.prep_timeout(); + if let Err(err) = send_request(&mut stream, pvf, &tmp_file).await { + gum::warn!( + target: LOG_TARGET, + worker_pid = %pid, + "failed to send a prepare request: {:?}", + err, + ); + return Outcome::Unreachable + } + + // Wait for the result from the worker, keeping in mind that there may be a timeout, the + // worker may get killed, or something along these lines. In that case we should propagate + // the error to the pool. + // + // We use a generous timeout here. This is in addition to the one in the child process, in + // case the child stalls. We have a wall clock timeout here in the host, but a CPU timeout + // in the child. We want to use CPU time because it varies less than wall clock time under + // load, but the CPU resources of the child can only be measured from the parent after the + // child process terminates. + let timeout = preparation_timeout * JOB_TIMEOUT_WALL_CLOCK_FACTOR; + let result = tokio::time::timeout(timeout, recv_response(&mut stream, pid)).await; + + match result { + // Received bytes from worker within the time limit. + Ok(Ok(prepare_result)) => + handle_response( + metrics, + IdleWorker { stream, pid }, + prepare_result, + pid, + tmp_file, + artifact_path, + preparation_timeout, + ) + .await, + Ok(Err(err)) => { + // Communication error within the time limit. + gum::warn!( + target: LOG_TARGET, + worker_pid = %pid, + "failed to recv a prepare response: {:?}", + err, + ); + Outcome::IoErr(err.to_string()) + }, + Err(_) => { + // Timed out here on the host. + gum::warn!( + target: LOG_TARGET, + worker_pid = %pid, + "did not recv a prepare response within the time limit", + ); + Outcome::TimedOut + }, + } + }) + .await +} + +/// Handles the case where we successfully received response bytes on the host from the child. +/// +/// NOTE: Here we know the artifact exists, but is still located in a temporary file which will be +/// cleared by `with_tmp_file`. +async fn handle_response( + metrics: &Metrics, + worker: IdleWorker, + result: PrepareResult, + worker_pid: u32, + tmp_file: PathBuf, + artifact_path: PathBuf, + preparation_timeout: Duration, +) -> Outcome { + let PrepareStats { cpu_time_elapsed, memory_stats } = match result.clone() { + Ok(result) => result, + // Timed out on the child. This should already be logged by the child. + Err(PrepareError::TimedOut) => return Outcome::TimedOut, + Err(_) => return Outcome::Concluded { worker, result }, + }; + + if cpu_time_elapsed > preparation_timeout { + // The job didn't complete within the timeout. + gum::warn!( + target: LOG_TARGET, + %worker_pid, + "prepare job took {}ms cpu time, exceeded preparation timeout {}ms. Clearing WIP artifact {}", + cpu_time_elapsed.as_millis(), + preparation_timeout.as_millis(), + tmp_file.display(), + ); + return Outcome::TimedOut + } + + gum::debug!( + target: LOG_TARGET, + %worker_pid, + "promoting WIP artifact {} to {}", + tmp_file.display(), + artifact_path.display(), + ); + + let outcome = match tokio::fs::rename(&tmp_file, &artifact_path).await { + Ok(()) => Outcome::Concluded { worker, result }, + Err(err) => { + gum::warn!( + target: LOG_TARGET, + %worker_pid, + "failed to rename the artifact from {} to {}: {:?}", + tmp_file.display(), + artifact_path.display(), + err, + ); + Outcome::RenameTmpFileErr { worker, result, err: format!("{:?}", err) } + }, + }; + + // If there were no errors up until now, log the memory stats for a successful preparation, if + // available. + metrics.observe_preparation_memory_metrics(memory_stats); + + outcome +} + +/// Create a temporary file for an artifact at the given cache path and execute the given +/// future/closure passing the file path in. +/// +/// The function will try best effort to not leave behind the temporary file. +async fn with_tmp_file(stream: UnixStream, pid: u32, cache_path: &Path, f: F) -> Outcome +where + Fut: futures::Future, + F: FnOnce(PathBuf, UnixStream) -> Fut, +{ + let tmp_file = match tmpfile_in("prepare-artifact-", cache_path).await { + Ok(f) => f, + Err(err) => { + gum::warn!( + target: LOG_TARGET, + worker_pid = %pid, + "failed to create a temp file for the artifact: {:?}", + err, + ); + return Outcome::CreateTmpFileErr { + worker: IdleWorker { stream, pid }, + err: format!("{:?}", err), + } + }, + }; + + let outcome = f(tmp_file.clone(), stream).await; + + // The function called above is expected to move `tmp_file` to a new location upon success. + // However, the function may as well fail and in that case we should remove the tmp file here. + // + // In any case, we try to remove the file here so that there are no leftovers. We only report + // errors that are different from the `NotFound`. + match tokio::fs::remove_file(tmp_file).await { + Ok(()) => (), + Err(err) if err.kind() == std::io::ErrorKind::NotFound => (), + Err(err) => { + gum::warn!( + target: LOG_TARGET, + worker_pid = %pid, + "failed to remove the tmp file: {:?}", + err, + ); + }, + } + + outcome +} + +async fn send_request( + stream: &mut UnixStream, + pvf: PvfPrepData, + tmp_file: &Path, +) -> io::Result<()> { + framed_send(stream, &pvf.encode()).await?; + framed_send(stream, path_to_bytes(tmp_file)).await?; + Ok(()) +} + +async fn recv_response(stream: &mut UnixStream, pid: u32) -> io::Result { + let result = framed_recv(stream).await?; + let result = PrepareResult::decode(&mut &result[..]).map_err(|e| { + // We received invalid bytes from the worker. + let bound_bytes = &result[..result.len().min(4)]; + gum::warn!( + target: LOG_TARGET, + worker_pid = %pid, + "received unexpected response from the prepare worker: {}", + HexDisplay::from(&bound_bytes), + ); + io::Error::new( + io::ErrorKind::Other, + format!("prepare pvf recv_response: failed to decode result: {:?}", e), + ) + })?; + Ok(result) +} diff --git a/polkadot/node/core/pvf/src/priority.rs b/polkadot/node/core/pvf/src/priority.rs new file mode 100644 index 0000000000000000000000000000000000000000..d4bd49eaee84037043a46f6645612627b081c0f4 --- /dev/null +++ b/polkadot/node/core/pvf/src/priority.rs @@ -0,0 +1,36 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +/// A priority assigned to execution of a PVF. +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum Priority { + /// Normal priority for things that do not require immediate response, but still need to be + /// done pretty quick. + /// + /// Approvals and disputes fall into this category. + Normal, + /// This priority is used for requests that are required to be processed as soon as possible. + /// + /// For example, backing is on a critical path and requires execution as soon as possible. + Critical, +} + +impl Priority { + /// Returns `true` if `self` is `Crticial` + pub fn is_critical(self) -> bool { + self == Priority::Critical + } +} diff --git a/polkadot/node/core/pvf/src/testing.rs b/polkadot/node/core/pvf/src/testing.rs new file mode 100644 index 0000000000000000000000000000000000000000..980a28c01566ce7e5b79af5200989b399af654c3 --- /dev/null +++ b/polkadot/node/core/pvf/src/testing.rs @@ -0,0 +1,91 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Various things for testing other crates. +//! +//! N.B. This is not guarded with some feature flag. Overexposing items here may affect the final +//! artifact even for production builds. + +pub use crate::worker_intf::{spawn_with_program_path, SpawnErr}; + +use polkadot_primitives::ExecutorParams; + +/// A function that emulates the stitches together behaviors of the preparation and the execution +/// worker in a single synchronous function. +pub fn validate_candidate( + code: &[u8], + params: &[u8], +) -> Result, Box> { + use polkadot_node_core_pvf_execute_worker::Executor; + use polkadot_node_core_pvf_prepare_worker::{prepare, prevalidate}; + + let code = sp_maybe_compressed_blob::decompress(code, 10 * 1024 * 1024) + .expect("Decompressing code failed"); + + let blob = prevalidate(&code)?; + let compiled_artifact_blob = prepare(blob, &ExecutorParams::default())?; + + let executor = Executor::new(ExecutorParams::default())?; + let result = unsafe { + // SAFETY: This is trivially safe since the artifact is obtained by calling `prepare` + // and is written into a temporary directory in an unmodified state. + executor.execute(&compiled_artifact_blob, params)? + }; + + Ok(result) +} + +/// Use this macro to declare a `fn main() {}` that will check the arguments and dispatch them to +/// the appropriate worker, making the executable that can be used for spawning workers. +#[macro_export] +macro_rules! decl_puppet_worker_main { + () => { + fn main() { + $crate::sp_tracing::try_init_simple(); + + let args = std::env::args().collect::>(); + if args.len() == 1 { + panic!("wrong number of arguments"); + } + + let entrypoint = match args[1].as_ref() { + "exit" => { + std::process::exit(1); + }, + "sleep" => { + std::thread::sleep(std::time::Duration::from_secs(5)); + return + }, + "prepare-worker" => $crate::prepare_worker_entrypoint, + "execute-worker" => $crate::execute_worker_entrypoint, + other => panic!("unknown subcommand: {}", other), + }; + + let mut node_version = None; + let mut socket_path: &str = ""; + + for i in (2..args.len()).step_by(2) { + match args[i].as_ref() { + "--socket-path" => socket_path = args[i + 1].as_str(), + "--node-impl-version" => node_version = Some(args[i + 1].as_str()), + arg => panic!("Unexpected argument found: {}", arg), + } + } + + entrypoint(&socket_path, node_version, None); + } + }; +} diff --git a/polkadot/node/core/pvf/src/worker_intf.rs b/polkadot/node/core/pvf/src/worker_intf.rs new file mode 100644 index 0000000000000000000000000000000000000000..795ad4524443bcf1032a40d5931520c110219055 --- /dev/null +++ b/polkadot/node/core/pvf/src/worker_intf.rs @@ -0,0 +1,335 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Common logic for implementation of worker processes. + +use crate::LOG_TARGET; +use futures::FutureExt as _; +use futures_timer::Delay; +use pin_project::pin_project; +use rand::Rng; +use std::{ + fmt, mem, + path::{Path, PathBuf}, + pin::Pin, + task::{Context, Poll}, + time::Duration, +}; +use tokio::{ + io::{self, AsyncRead, AsyncReadExt as _, AsyncWrite, AsyncWriteExt as _, ReadBuf}, + net::{UnixListener, UnixStream}, + process, +}; + +/// A multiple of the job timeout (in CPU time) for which we are willing to wait on the host (in +/// wall clock time). This is lenient because CPU time may go slower than wall clock time. +pub const JOB_TIMEOUT_WALL_CLOCK_FACTOR: u32 = 4; + +/// This is publicly exposed only for integration tests. +#[doc(hidden)] +pub async fn spawn_with_program_path( + debug_id: &'static str, + program_path: impl Into, + extra_args: &[&str], + spawn_timeout: Duration, +) -> Result<(IdleWorker, WorkerHandle), SpawnErr> { + let program_path = program_path.into(); + with_transient_socket_path(debug_id, |socket_path| { + let socket_path = socket_path.to_owned(); + let extra_args: Vec = extra_args.iter().map(|arg| arg.to_string()).collect(); + + async move { + let listener = UnixListener::bind(&socket_path).map_err(|err| { + gum::warn!( + target: LOG_TARGET, + %debug_id, + ?program_path, + ?extra_args, + "cannot bind unix socket: {:?}", + err, + ); + SpawnErr::Bind + })?; + + let handle = + WorkerHandle::spawn(&program_path, &extra_args, socket_path).map_err(|err| { + gum::warn!( + target: LOG_TARGET, + %debug_id, + ?program_path, + ?extra_args, + "cannot spawn a worker: {:?}", + err, + ); + SpawnErr::ProcessSpawn + })?; + + futures::select! { + accept_result = listener.accept().fuse() => { + let (stream, _) = accept_result.map_err(|err| { + gum::warn!( + target: LOG_TARGET, + %debug_id, + ?program_path, + ?extra_args, + "cannot accept a worker: {:?}", + err, + ); + SpawnErr::Accept + })?; + Ok((IdleWorker { stream, pid: handle.id() }, handle)) + } + _ = Delay::new(spawn_timeout).fuse() => { + gum::warn!( + target: LOG_TARGET, + %debug_id, + ?program_path, + ?extra_args, + ?spawn_timeout, + "spawning and connecting to socket timed out", + ); + Err(SpawnErr::AcceptTimeout) + } + } + } + }) + .await +} + +async fn with_transient_socket_path(debug_id: &'static str, f: F) -> Result +where + F: FnOnce(&Path) -> Fut, + Fut: futures::Future> + 'static, +{ + let socket_path = tmpfile(&format!("pvf-host-{}", debug_id)) + .await + .map_err(|_| SpawnErr::TmpFile)?; + let result = f(&socket_path).await; + + // Best effort to remove the socket file. Under normal circumstances the socket will be removed + // by the worker. We make sure that it is removed here, just in case a failed rendezvous. + let _ = tokio::fs::remove_file(socket_path).await; + + result +} + +/// Returns a path under the given `dir`. The file name will start with the given prefix. +/// +/// There is only a certain number of retries. If exceeded this function will give up and return an +/// error. +pub async fn tmpfile_in(prefix: &str, dir: &Path) -> io::Result { + fn tmppath(prefix: &str, dir: &Path) -> PathBuf { + use rand::distributions::Alphanumeric; + + const DESCRIMINATOR_LEN: usize = 10; + + let mut buf = Vec::with_capacity(prefix.len() + DESCRIMINATOR_LEN); + buf.extend(prefix.as_bytes()); + buf.extend(rand::thread_rng().sample_iter(&Alphanumeric).take(DESCRIMINATOR_LEN)); + + let s = std::str::from_utf8(&buf) + .expect("the string is collected from a valid utf-8 sequence; qed"); + + let mut file = dir.to_owned(); + file.push(s); + file + } + + const NUM_RETRIES: usize = 50; + + for _ in 0..NUM_RETRIES { + let candidate_path = tmppath(prefix, dir); + if !candidate_path.exists() { + return Ok(candidate_path) + } + } + + Err(io::Error::new(io::ErrorKind::Other, "failed to create a temporary file")) +} + +/// The same as [`tmpfile_in`], but uses [`std::env::temp_dir`] as the directory. +pub async fn tmpfile(prefix: &str) -> io::Result { + let temp_dir = PathBuf::from(std::env::temp_dir()); + tmpfile_in(prefix, &temp_dir).await +} + +/// A struct that represents an idle worker. +/// +/// This struct is supposed to be used as a token that is passed by move into a subroutine that +/// initiates a job. If the worker dies on the duty, then the token is not returned. +#[derive(Debug)] +pub struct IdleWorker { + /// The stream to which the child process is connected. + pub stream: UnixStream, + + /// The identifier of this process. Used to reset the niceness. + pub pid: u32, +} + +/// An error happened during spawning a worker process. +#[derive(Clone, Debug)] +pub enum SpawnErr { + /// Cannot obtain a temporary file location. + TmpFile, + /// Cannot bind the socket to the given path. + Bind, + /// An error happened during accepting a connection to the socket. + Accept, + /// An error happened during spawning the process. + ProcessSpawn, + /// The deadline allotted for the worker spawning and connecting to the socket has elapsed. + AcceptTimeout, + /// Failed to send handshake after successful spawning was signaled + Handshake, +} + +/// This is a representation of a potentially running worker. Drop it and the process will be +/// killed. +/// +/// A worker's handle is also a future that resolves when it's detected that the worker's process +/// has been terminated. Since the worker is running in another process it is obviously not +/// necessary to poll this future to make the worker run, it's only for termination detection. +/// +/// This future relies on the fact that a child process's stdout `fd` is closed upon it's +/// termination. +#[pin_project] +pub struct WorkerHandle { + child: process::Child, + child_id: u32, + #[pin] + stdout: process::ChildStdout, + program: PathBuf, + drop_box: Box<[u8]>, +} + +impl WorkerHandle { + fn spawn( + program: impl AsRef, + extra_args: &[String], + socket_path: impl AsRef, + ) -> io::Result { + let mut child = process::Command::new(program.as_ref()) + .args(extra_args) + .arg("--socket-path") + .arg(socket_path.as_ref().as_os_str()) + .stdout(std::process::Stdio::piped()) + .kill_on_drop(true) + .spawn()?; + + let child_id = child + .id() + .ok_or(io::Error::new(io::ErrorKind::Other, "could not get id of spawned process"))?; + let stdout = child + .stdout + .take() + .expect("the process spawned with piped stdout should have the stdout handle"); + + Ok(WorkerHandle { + child, + child_id, + stdout, + program: program.as_ref().to_path_buf(), + // We don't expect the bytes to be ever read. But in case we do, we should not use a + // buffer of a small size, because otherwise if the child process does return any data + // we will end up issuing a syscall for each byte. We also prefer not to do allocate + // that on the stack, since each poll the buffer will be allocated and initialized (and + // that's due `poll_read` takes &mut [u8] and there are no guarantees that a `poll_read` + // won't ever read from there even though that's unlikely). + // + // OTOH, we also don't want to be super smart here and we could just afford to allocate + // a buffer for that here. + drop_box: vec![0; 8192].into_boxed_slice(), + }) + } + + /// Returns the process id of this worker. + pub fn id(&self) -> u32 { + self.child_id + } +} + +impl futures::Future for WorkerHandle { + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let me = self.project(); + // Create a `ReadBuf` here instead of storing it in `WorkerHandle` to avoid a lifetime + // parameter on `WorkerHandle`. Creating the `ReadBuf` is fairly cheap. + let mut read_buf = ReadBuf::new(&mut *me.drop_box); + match futures::ready!(AsyncRead::poll_read(me.stdout, cx, &mut read_buf)) { + Ok(()) => { + if read_buf.filled().len() > 0 { + // weird, we've read something. Pretend that never happened and reschedule + // ourselves. + cx.waker().wake_by_ref(); + Poll::Pending + } else { + // Nothing read means `EOF` means the child was terminated. Resolve. + Poll::Ready(()) + } + }, + Err(err) => { + // The implementation is guaranteed to not to return `WouldBlock` and Interrupted. + // This leaves us with legit errors which we suppose were due to termination. + + // Log the status code. + gum::debug!( + target: LOG_TARGET, + worker_pid = %me.child_id, + status_code = ?me.child.try_wait().ok().flatten().map(|c| c.to_string()), + "pvf worker ({}): {:?}", + me.program.display(), + err, + ); + Poll::Ready(()) + }, + } + } +} + +impl fmt::Debug for WorkerHandle { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "WorkerHandle(pid={})", self.id()) + } +} + +/// Convert the given path into a byte buffer. +pub fn path_to_bytes(path: &Path) -> &[u8] { + // Ideally, we take the `OsStr` of the path, send that and reconstruct this on the other side. + // However, libstd doesn't provide us with such an option. There are crates out there that + // allow for extraction of a path, but TBH it doesn't seem to be a real issue. + // + // However, should be there reports we can incorporate such a crate here. + path.to_str().expect("non-UTF-8 path").as_bytes() +} + +/// Write some data prefixed by its length into `w`. +pub async fn framed_send(w: &mut (impl AsyncWrite + Unpin), buf: &[u8]) -> io::Result<()> { + let len_buf = buf.len().to_le_bytes(); + w.write_all(&len_buf).await?; + w.write_all(buf).await?; + Ok(()) +} + +/// Read some data prefixed by its length from `r`. +pub async fn framed_recv(r: &mut (impl AsyncRead + Unpin)) -> io::Result> { + let mut len_buf = [0u8; mem::size_of::()]; + r.read_exact(&mut len_buf).await?; + let len = usize::from_le_bytes(len_buf); + let mut buf = vec![0; len]; + r.read_exact(&mut buf).await?; + Ok(buf) +} diff --git a/polkadot/node/core/pvf/tests/it/adder.rs b/polkadot/node/core/pvf/tests/it/adder.rs new file mode 100644 index 0000000000000000000000000000000000000000..a4c2e21bdeaa7638dcdfa52ae00e128c789d654f --- /dev/null +++ b/polkadot/node/core/pvf/tests/it/adder.rs @@ -0,0 +1,147 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::TestHost; +use adder::{hash_state, BlockData, HeadData}; +use parity_scale_codec::{Decode, Encode}; +use polkadot_parachain::primitives::{ + BlockData as GenericBlockData, HeadData as GenericHeadData, RelayChainBlockNumber, + ValidationParams, +}; + +#[tokio::test] +async fn execute_good_block_on_parent() { + let parent_head = HeadData { number: 0, parent_hash: [0; 32], post_state: hash_state(0) }; + + let block_data = BlockData { state: 0, add: 512 }; + + let host = TestHost::new(); + + let ret = host + .validate_candidate( + adder::wasm_binary_unwrap(), + ValidationParams { + parent_head: GenericHeadData(parent_head.encode()), + block_data: GenericBlockData(block_data.encode()), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ) + .await + .unwrap(); + + let new_head = HeadData::decode(&mut &ret.head_data.0[..]).unwrap(); + + assert_eq!(new_head.number, 1); + assert_eq!(new_head.parent_hash, parent_head.hash()); + assert_eq!(new_head.post_state, hash_state(512)); +} + +#[tokio::test] +async fn execute_good_chain_on_parent() { + let mut parent_hash = [0; 32]; + let mut last_state = 0; + + let host = TestHost::new(); + + for (number, add) in (0..10).enumerate() { + let parent_head = + HeadData { number: number as u64, parent_hash, post_state: hash_state(last_state) }; + + let block_data = BlockData { state: last_state, add }; + + let ret = host + .validate_candidate( + adder::wasm_binary_unwrap(), + ValidationParams { + parent_head: GenericHeadData(parent_head.encode()), + block_data: GenericBlockData(block_data.encode()), + relay_parent_number: number as RelayChainBlockNumber + 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ) + .await + .unwrap(); + + let new_head = HeadData::decode(&mut &ret.head_data.0[..]).unwrap(); + + assert_eq!(new_head.number, number as u64 + 1); + assert_eq!(new_head.parent_hash, parent_head.hash()); + assert_eq!(new_head.post_state, hash_state(last_state + add)); + + parent_hash = new_head.hash(); + last_state += add; + } +} + +#[tokio::test] +async fn execute_bad_block_on_parent() { + let parent_head = HeadData { number: 0, parent_hash: [0; 32], post_state: hash_state(0) }; + + let block_data = BlockData { + state: 256, // start state is wrong. + add: 256, + }; + + let host = TestHost::new(); + + let _ret = host + .validate_candidate( + adder::wasm_binary_unwrap(), + ValidationParams { + parent_head: GenericHeadData(parent_head.encode()), + block_data: GenericBlockData(block_data.encode()), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn stress_spawn() { + let host = std::sync::Arc::new(TestHost::new()); + + async fn execute(host: std::sync::Arc) { + let parent_head = HeadData { number: 0, parent_hash: [0; 32], post_state: hash_state(0) }; + let block_data = BlockData { state: 0, add: 512 }; + let ret = host + .validate_candidate( + adder::wasm_binary_unwrap(), + ValidationParams { + parent_head: GenericHeadData(parent_head.encode()), + block_data: GenericBlockData(block_data.encode()), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ) + .await + .unwrap(); + + let new_head = HeadData::decode(&mut &ret.head_data.0[..]).unwrap(); + + assert_eq!(new_head.number, 1); + assert_eq!(new_head.parent_hash, parent_head.hash()); + assert_eq!(new_head.post_state, hash_state(512)); + } + + futures::future::join_all((0..100).map(|_| execute(host.clone()))).await; +} diff --git a/polkadot/node/core/pvf/tests/it/main.rs b/polkadot/node/core/pvf/tests/it/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..72c459c2f63214cd1ab5c9708fc9f87cb46dcc5b --- /dev/null +++ b/polkadot/node/core/pvf/tests/it/main.rs @@ -0,0 +1,310 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#[cfg(feature = "ci-only-tests")] +use assert_matches::assert_matches; +use parity_scale_codec::Encode as _; +use polkadot_node_core_pvf::{ + start, Config, InvalidCandidate, Metrics, PrepareJobKind, PvfPrepData, ValidationError, + ValidationHost, JOB_TIMEOUT_WALL_CLOCK_FACTOR, +}; +use polkadot_parachain::primitives::{BlockData, ValidationParams, ValidationResult}; +use polkadot_primitives::ExecutorParams; + +#[cfg(feature = "ci-only-tests")] +use polkadot_primitives::ExecutorParam; + +use std::time::Duration; +use tokio::sync::Mutex; + +mod adder; +mod worker_common; + +const PUPPET_EXE: &str = env!("CARGO_BIN_EXE_puppet_worker"); +const TEST_EXECUTION_TIMEOUT: Duration = Duration::from_secs(3); +const TEST_PREPARATION_TIMEOUT: Duration = Duration::from_secs(3); + +struct TestHost { + cache_dir: tempfile::TempDir, + host: Mutex, +} + +impl TestHost { + fn new() -> Self { + Self::new_with_config(|_| ()) + } + + fn new_with_config(f: F) -> Self + where + F: FnOnce(&mut Config), + { + let cache_dir = tempfile::tempdir().unwrap(); + let program_path = std::path::PathBuf::from(PUPPET_EXE); + let mut config = + Config::new(cache_dir.path().to_owned(), None, program_path.clone(), program_path); + f(&mut config); + let (host, task) = start(config, Metrics::default()); + let _ = tokio::task::spawn(task); + Self { cache_dir, host: Mutex::new(host) } + } + + async fn validate_candidate( + &self, + code: &[u8], + params: ValidationParams, + executor_params: ExecutorParams, + ) -> Result { + let (result_tx, result_rx) = futures::channel::oneshot::channel(); + + let code = sp_maybe_compressed_blob::decompress(code, 16 * 1024 * 1024) + .expect("Compression works"); + + self.host + .lock() + .await + .execute_pvf( + PvfPrepData::from_code( + code.into(), + executor_params, + TEST_PREPARATION_TIMEOUT, + PrepareJobKind::Compilation, + ), + TEST_EXECUTION_TIMEOUT, + params.encode(), + polkadot_node_core_pvf::Priority::Normal, + result_tx, + ) + .await + .unwrap(); + result_rx.await.unwrap() + } +} + +#[tokio::test] +async fn terminates_on_timeout() { + let host = TestHost::new(); + + let start = std::time::Instant::now(); + let result = host + .validate_candidate( + halt::wasm_binary_unwrap(), + ValidationParams { + block_data: BlockData(Vec::new()), + parent_head: Default::default(), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ) + .await; + + match result { + Err(ValidationError::InvalidCandidate(InvalidCandidate::HardTimeout)) => {}, + r => panic!("{:?}", r), + } + + let duration = std::time::Instant::now().duration_since(start); + assert!(duration >= TEST_EXECUTION_TIMEOUT); + assert!(duration < TEST_EXECUTION_TIMEOUT * JOB_TIMEOUT_WALL_CLOCK_FACTOR); +} + +#[cfg(feature = "ci-only-tests")] +#[tokio::test] +async fn ensure_parallel_execution() { + // Run some jobs that do not complete, thus timing out. + let host = TestHost::new(); + let execute_pvf_future_1 = host.validate_candidate( + halt::wasm_binary_unwrap(), + ValidationParams { + block_data: BlockData(Vec::new()), + parent_head: Default::default(), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ); + let execute_pvf_future_2 = host.validate_candidate( + halt::wasm_binary_unwrap(), + ValidationParams { + block_data: BlockData(Vec::new()), + parent_head: Default::default(), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ); + + let start = std::time::Instant::now(); + let (res1, res2) = futures::join!(execute_pvf_future_1, execute_pvf_future_2); + assert_matches!( + (res1, res2), + ( + Err(ValidationError::InvalidCandidate(InvalidCandidate::HardTimeout)), + Err(ValidationError::InvalidCandidate(InvalidCandidate::HardTimeout)) + ) + ); + + // Total time should be < 2 x TEST_EXECUTION_TIMEOUT (two workers run in parallel). + let duration = std::time::Instant::now().duration_since(start); + let max_duration = 2 * TEST_EXECUTION_TIMEOUT; + assert!( + duration < max_duration, + "Expected duration {}ms to be less than {}ms", + duration.as_millis(), + max_duration.as_millis() + ); +} + +#[tokio::test] +async fn execute_queue_doesnt_stall_if_workers_died() { + let host = TestHost::new_with_config(|cfg| { + cfg.execute_workers_max_num = 5; + }); + + // Here we spawn 8 validation jobs for the `halt` PVF and share those between 5 workers. The + // first five jobs should timeout and the workers killed. For the next 3 jobs a new batch of + // workers should be spun up. + let start = std::time::Instant::now(); + futures::future::join_all((0u8..=8).map(|_| { + host.validate_candidate( + halt::wasm_binary_unwrap(), + ValidationParams { + block_data: BlockData(Vec::new()), + parent_head: Default::default(), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ) + })) + .await; + + // Total time should be >= 2 x TEST_EXECUTION_TIMEOUT (two separate sets of workers that should + // both timeout). + let duration = std::time::Instant::now().duration_since(start); + let max_duration = 2 * TEST_EXECUTION_TIMEOUT; + assert!( + duration >= max_duration, + "Expected duration {}ms to be greater than or equal to {}ms", + duration.as_millis(), + max_duration.as_millis() + ); +} + +#[cfg(feature = "ci-only-tests")] +#[tokio::test] +async fn execute_queue_doesnt_stall_with_varying_executor_params() { + let host = TestHost::new_with_config(|cfg| { + cfg.execute_workers_max_num = 2; + }); + + let executor_params_1 = ExecutorParams::default(); + let executor_params_2 = ExecutorParams::from(&[ExecutorParam::StackLogicalMax(1024)][..]); + + // Here we spawn 6 validation jobs for the `halt` PVF and share those between 2 workers. Every + // 3rd job will have different set of executor parameters. All the workers should be killed + // and in this case the queue should respawn new workers with needed executor environment + // without waiting. The jobs will be executed in 3 batches, each running two jobs in parallel, + // and execution time would be roughly 3 * TEST_EXECUTION_TIMEOUT + let start = std::time::Instant::now(); + futures::future::join_all((0u8..6).map(|i| { + host.validate_candidate( + halt::wasm_binary_unwrap(), + ValidationParams { + block_data: BlockData(Vec::new()), + parent_head: Default::default(), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + match i % 3 { + 0 => executor_params_1.clone(), + _ => executor_params_2.clone(), + }, + ) + })) + .await; + + let duration = std::time::Instant::now().duration_since(start); + let min_duration = 3 * TEST_EXECUTION_TIMEOUT; + let max_duration = 4 * TEST_EXECUTION_TIMEOUT; + assert!( + duration >= min_duration, + "Expected duration {}ms to be greater than or equal to {}ms", + duration.as_millis(), + min_duration.as_millis() + ); + assert!( + duration <= max_duration, + "Expected duration {}ms to be less than or equal to {}ms", + duration.as_millis(), + max_duration.as_millis() + ); +} + +// Test that deleting a prepared artifact does not lead to a dispute when we try to execute it. +#[tokio::test] +async fn deleting_prepared_artifact_does_not_dispute() { + let host = TestHost::new(); + let cache_dir = host.cache_dir.path().clone(); + + let result = host + .validate_candidate( + halt::wasm_binary_unwrap(), + ValidationParams { + block_data: BlockData(Vec::new()), + parent_head: Default::default(), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ) + .await; + + match result { + Err(ValidationError::InvalidCandidate(InvalidCandidate::HardTimeout)) => {}, + r => panic!("{:?}", r), + } + + // Delete the prepared artifact. + { + // Get the artifact path (asserting it exists). + let mut cache_dir: Vec<_> = std::fs::read_dir(cache_dir).unwrap().collect(); + assert_eq!(cache_dir.len(), 1); + let artifact_path = cache_dir.pop().unwrap().unwrap(); + + // Delete the artifact. + std::fs::remove_file(artifact_path.path()).unwrap(); + } + + // Try to validate again, artifact should get recreated. + let result = host + .validate_candidate( + halt::wasm_binary_unwrap(), + ValidationParams { + block_data: BlockData(Vec::new()), + parent_head: Default::default(), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ) + .await; + + match result { + Err(ValidationError::InvalidCandidate(InvalidCandidate::HardTimeout)) => {}, + r => panic!("{:?}", r), + } +} diff --git a/polkadot/node/core/pvf/tests/it/worker_common.rs b/polkadot/node/core/pvf/tests/it/worker_common.rs new file mode 100644 index 0000000000000000000000000000000000000000..a3bf552e894a5321b6755ccb3f70dc2385df5bf1 --- /dev/null +++ b/polkadot/node/core/pvf/tests/it/worker_common.rs @@ -0,0 +1,50 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::time::Duration; + +use polkadot_node_core_pvf::testing::{spawn_with_program_path, SpawnErr}; + +use crate::PUPPET_EXE; + +// Test spawning a program that immediately exits with a failure code. +#[tokio::test] +async fn spawn_immediate_exit() { + let result = + spawn_with_program_path("integration-test", PUPPET_EXE, &["exit"], Duration::from_secs(2)) + .await; + assert!(matches!(result, Err(SpawnErr::AcceptTimeout))); +} + +#[tokio::test] +async fn spawn_timeout() { + let result = + spawn_with_program_path("integration-test", PUPPET_EXE, &["sleep"], Duration::from_secs(2)) + .await; + assert!(matches!(result, Err(SpawnErr::AcceptTimeout))); +} + +#[tokio::test] +async fn should_connect() { + let _ = spawn_with_program_path( + "integration-test", + PUPPET_EXE, + &["prepare-worker"], + Duration::from_secs(2), + ) + .await + .unwrap(); +} diff --git a/polkadot/node/core/runtime-api/Cargo.toml b/polkadot/node/core/runtime-api/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..30ba781216d04d4c866125322391f44c429b8a5e --- /dev/null +++ b/polkadot/node/core/runtime-api/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "polkadot-node-core-runtime-api" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +gum = { package = "tracing-gum", path = "../../gum" } +lru = "0.11.0" + +sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } + +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-metrics = { path = "../../metrics" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-subsystem-types = { path = "../../subsystem-types" } + +[dev-dependencies] +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +async-trait = "0.1.57" +futures = { version = "0.3.21", features = ["thread-pool"] } +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +polkadot-node-primitives = { path = "../../primitives" } +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/core/runtime-api/src/cache.rs b/polkadot/node/core/runtime-api/src/cache.rs new file mode 100644 index 0000000000000000000000000000000000000000..26aaf3fb6ec891b77b6d714dbf5c680a9c33b7a1 --- /dev/null +++ b/polkadot/node/core/runtime-api/src/cache.rs @@ -0,0 +1,518 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{collections::btree_map::BTreeMap, num::NonZeroUsize}; + +use lru::LruCache; +use sp_consensus_babe::Epoch; + +use polkadot_primitives::{ + vstaging, AuthorityDiscoveryId, BlockNumber, CandidateCommitments, CandidateEvent, + CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, + GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, + OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, + SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, + ValidatorSignature, +}; + +/// For consistency we have the same capacity for all caches. We use 128 as we'll only need that +/// much if finality stalls (we only query state for unfinalized blocks + maybe latest finalized). +/// In any case, a cache is an optimization. We should avoid a situation where having a large cache +/// leads to OOM or puts pressure on other important stuff like PVF execution/preparation. +const DEFAULT_CACHE_CAP: NonZeroUsize = match NonZeroUsize::new(128) { + Some(cap) => cap, + None => panic!("lru capacity must be non-zero"), +}; + +pub(crate) struct RequestResultCache { + authorities: LruCache>, + validators: LruCache>, + validator_groups: LruCache>, GroupRotationInfo)>, + availability_cores: LruCache>, + persisted_validation_data: + LruCache<(Hash, ParaId, OccupiedCoreAssumption), Option>, + assumed_validation_data: + LruCache<(ParaId, Hash), Option<(PersistedValidationData, ValidationCodeHash)>>, + check_validation_outputs: LruCache<(Hash, ParaId, CandidateCommitments), bool>, + session_index_for_child: LruCache, + validation_code: LruCache<(Hash, ParaId, OccupiedCoreAssumption), Option>, + validation_code_by_hash: LruCache>, + candidate_pending_availability: LruCache<(Hash, ParaId), Option>, + candidate_events: LruCache>, + session_executor_params: LruCache>, + session_info: LruCache, + dmq_contents: LruCache<(Hash, ParaId), Vec>>, + inbound_hrmp_channels_contents: + LruCache<(Hash, ParaId), BTreeMap>>>, + current_babe_epoch: LruCache, + on_chain_votes: LruCache>, + pvfs_require_precheck: LruCache>, + validation_code_hash: + LruCache<(Hash, ParaId, OccupiedCoreAssumption), Option>, + version: LruCache, + disputes: LruCache)>>, + unapplied_slashes: + LruCache>, + key_ownership_proof: + LruCache<(Hash, ValidatorId), Option>, + + staging_para_backing_state: LruCache<(Hash, ParaId), Option>, + staging_async_backing_params: LruCache, +} + +impl Default for RequestResultCache { + fn default() -> Self { + Self { + authorities: LruCache::new(DEFAULT_CACHE_CAP), + validators: LruCache::new(DEFAULT_CACHE_CAP), + validator_groups: LruCache::new(DEFAULT_CACHE_CAP), + availability_cores: LruCache::new(DEFAULT_CACHE_CAP), + persisted_validation_data: LruCache::new(DEFAULT_CACHE_CAP), + assumed_validation_data: LruCache::new(DEFAULT_CACHE_CAP), + check_validation_outputs: LruCache::new(DEFAULT_CACHE_CAP), + session_index_for_child: LruCache::new(DEFAULT_CACHE_CAP), + validation_code: LruCache::new(DEFAULT_CACHE_CAP), + validation_code_by_hash: LruCache::new(DEFAULT_CACHE_CAP), + candidate_pending_availability: LruCache::new(DEFAULT_CACHE_CAP), + candidate_events: LruCache::new(DEFAULT_CACHE_CAP), + session_executor_params: LruCache::new(DEFAULT_CACHE_CAP), + session_info: LruCache::new(DEFAULT_CACHE_CAP), + dmq_contents: LruCache::new(DEFAULT_CACHE_CAP), + inbound_hrmp_channels_contents: LruCache::new(DEFAULT_CACHE_CAP), + current_babe_epoch: LruCache::new(DEFAULT_CACHE_CAP), + on_chain_votes: LruCache::new(DEFAULT_CACHE_CAP), + pvfs_require_precheck: LruCache::new(DEFAULT_CACHE_CAP), + validation_code_hash: LruCache::new(DEFAULT_CACHE_CAP), + version: LruCache::new(DEFAULT_CACHE_CAP), + disputes: LruCache::new(DEFAULT_CACHE_CAP), + unapplied_slashes: LruCache::new(DEFAULT_CACHE_CAP), + key_ownership_proof: LruCache::new(DEFAULT_CACHE_CAP), + + staging_para_backing_state: LruCache::new(DEFAULT_CACHE_CAP), + staging_async_backing_params: LruCache::new(DEFAULT_CACHE_CAP), + } + } +} + +impl RequestResultCache { + pub(crate) fn authorities( + &mut self, + relay_parent: &Hash, + ) -> Option<&Vec> { + self.authorities.get(relay_parent) + } + + pub(crate) fn cache_authorities( + &mut self, + relay_parent: Hash, + authorities: Vec, + ) { + self.authorities.put(relay_parent, authorities); + } + + pub(crate) fn validators(&mut self, relay_parent: &Hash) -> Option<&Vec> { + self.validators.get(relay_parent) + } + + pub(crate) fn cache_validators(&mut self, relay_parent: Hash, validators: Vec) { + self.validators.put(relay_parent, validators); + } + + pub(crate) fn validator_groups( + &mut self, + relay_parent: &Hash, + ) -> Option<&(Vec>, GroupRotationInfo)> { + self.validator_groups.get(relay_parent) + } + + pub(crate) fn cache_validator_groups( + &mut self, + relay_parent: Hash, + groups: (Vec>, GroupRotationInfo), + ) { + self.validator_groups.put(relay_parent, groups); + } + + pub(crate) fn availability_cores(&mut self, relay_parent: &Hash) -> Option<&Vec> { + self.availability_cores.get(relay_parent) + } + + pub(crate) fn cache_availability_cores(&mut self, relay_parent: Hash, cores: Vec) { + self.availability_cores.put(relay_parent, cores); + } + + pub(crate) fn persisted_validation_data( + &mut self, + key: (Hash, ParaId, OccupiedCoreAssumption), + ) -> Option<&Option> { + self.persisted_validation_data.get(&key) + } + + pub(crate) fn cache_persisted_validation_data( + &mut self, + key: (Hash, ParaId, OccupiedCoreAssumption), + data: Option, + ) { + self.persisted_validation_data.put(key, data); + } + + pub(crate) fn assumed_validation_data( + &mut self, + key: (Hash, ParaId, Hash), + ) -> Option<&Option<(PersistedValidationData, ValidationCodeHash)>> { + self.assumed_validation_data.get(&(key.1, key.2)) + } + + pub(crate) fn cache_assumed_validation_data( + &mut self, + key: (ParaId, Hash), + data: Option<(PersistedValidationData, ValidationCodeHash)>, + ) { + self.assumed_validation_data.put(key, data); + } + + pub(crate) fn check_validation_outputs( + &mut self, + key: (Hash, ParaId, CandidateCommitments), + ) -> Option<&bool> { + self.check_validation_outputs.get(&key) + } + + pub(crate) fn cache_check_validation_outputs( + &mut self, + key: (Hash, ParaId, CandidateCommitments), + value: bool, + ) { + self.check_validation_outputs.put(key, value); + } + + pub(crate) fn session_index_for_child(&mut self, relay_parent: &Hash) -> Option<&SessionIndex> { + self.session_index_for_child.get(relay_parent) + } + + pub(crate) fn cache_session_index_for_child( + &mut self, + relay_parent: Hash, + index: SessionIndex, + ) { + self.session_index_for_child.put(relay_parent, index); + } + + pub(crate) fn validation_code( + &mut self, + key: (Hash, ParaId, OccupiedCoreAssumption), + ) -> Option<&Option> { + self.validation_code.get(&key) + } + + pub(crate) fn cache_validation_code( + &mut self, + key: (Hash, ParaId, OccupiedCoreAssumption), + value: Option, + ) { + self.validation_code.put(key, value); + } + + // the actual key is `ValidationCodeHash` (`Hash` is ignored), + // but we keep the interface that way to keep the macro simple + pub(crate) fn validation_code_by_hash( + &mut self, + key: (Hash, ValidationCodeHash), + ) -> Option<&Option> { + self.validation_code_by_hash.get(&key.1) + } + + pub(crate) fn cache_validation_code_by_hash( + &mut self, + key: ValidationCodeHash, + value: Option, + ) { + self.validation_code_by_hash.put(key, value); + } + + pub(crate) fn candidate_pending_availability( + &mut self, + key: (Hash, ParaId), + ) -> Option<&Option> { + self.candidate_pending_availability.get(&key) + } + + pub(crate) fn cache_candidate_pending_availability( + &mut self, + key: (Hash, ParaId), + value: Option, + ) { + self.candidate_pending_availability.put(key, value); + } + + pub(crate) fn candidate_events(&mut self, relay_parent: &Hash) -> Option<&Vec> { + self.candidate_events.get(relay_parent) + } + + pub(crate) fn cache_candidate_events( + &mut self, + relay_parent: Hash, + events: Vec, + ) { + self.candidate_events.put(relay_parent, events); + } + + pub(crate) fn session_info(&mut self, key: SessionIndex) -> Option<&SessionInfo> { + self.session_info.get(&key) + } + + pub(crate) fn cache_session_info(&mut self, key: SessionIndex, value: SessionInfo) { + self.session_info.put(key, value); + } + + pub(crate) fn session_executor_params( + &mut self, + session_index: SessionIndex, + ) -> Option<&Option> { + self.session_executor_params.get(&session_index) + } + + pub(crate) fn cache_session_executor_params( + &mut self, + session_index: SessionIndex, + value: Option, + ) { + self.session_executor_params.put(session_index, value); + } + + pub(crate) fn dmq_contents( + &mut self, + key: (Hash, ParaId), + ) -> Option<&Vec>> { + self.dmq_contents.get(&key) + } + + pub(crate) fn cache_dmq_contents( + &mut self, + key: (Hash, ParaId), + value: Vec>, + ) { + self.dmq_contents.put(key, value); + } + + pub(crate) fn inbound_hrmp_channels_contents( + &mut self, + key: (Hash, ParaId), + ) -> Option<&BTreeMap>>> { + self.inbound_hrmp_channels_contents.get(&key) + } + + pub(crate) fn cache_inbound_hrmp_channel_contents( + &mut self, + key: (Hash, ParaId), + value: BTreeMap>>, + ) { + self.inbound_hrmp_channels_contents.put(key, value); + } + + pub(crate) fn current_babe_epoch(&mut self, relay_parent: &Hash) -> Option<&Epoch> { + self.current_babe_epoch.get(relay_parent) + } + + pub(crate) fn cache_current_babe_epoch(&mut self, relay_parent: Hash, epoch: Epoch) { + self.current_babe_epoch.put(relay_parent, epoch); + } + + pub(crate) fn on_chain_votes( + &mut self, + relay_parent: &Hash, + ) -> Option<&Option> { + self.on_chain_votes.get(relay_parent) + } + + pub(crate) fn cache_on_chain_votes( + &mut self, + relay_parent: Hash, + scraped: Option, + ) { + self.on_chain_votes.put(relay_parent, scraped); + } + + pub(crate) fn pvfs_require_precheck( + &mut self, + relay_parent: &Hash, + ) -> Option<&Vec> { + self.pvfs_require_precheck.get(relay_parent) + } + + pub(crate) fn cache_pvfs_require_precheck( + &mut self, + relay_parent: Hash, + pvfs: Vec, + ) { + self.pvfs_require_precheck.put(relay_parent, pvfs); + } + + pub(crate) fn validation_code_hash( + &mut self, + key: (Hash, ParaId, OccupiedCoreAssumption), + ) -> Option<&Option> { + self.validation_code_hash.get(&key) + } + + pub(crate) fn cache_validation_code_hash( + &mut self, + key: (Hash, ParaId, OccupiedCoreAssumption), + value: Option, + ) { + self.validation_code_hash.put(key, value); + } + + pub(crate) fn version(&mut self, relay_parent: &Hash) -> Option<&u32> { + self.version.get(relay_parent) + } + + pub(crate) fn cache_version(&mut self, key: Hash, value: u32) { + self.version.put(key, value); + } + + pub(crate) fn disputes( + &mut self, + relay_parent: &Hash, + ) -> Option<&Vec<(SessionIndex, CandidateHash, DisputeState)>> { + self.disputes.get(relay_parent) + } + + pub(crate) fn cache_disputes( + &mut self, + relay_parent: Hash, + value: Vec<(SessionIndex, CandidateHash, DisputeState)>, + ) { + self.disputes.put(relay_parent, value); + } + + pub(crate) fn unapplied_slashes( + &mut self, + relay_parent: &Hash, + ) -> Option<&Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>> { + self.unapplied_slashes.get(relay_parent) + } + + pub(crate) fn cache_unapplied_slashes( + &mut self, + relay_parent: Hash, + value: Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>, + ) { + self.unapplied_slashes.put(relay_parent, value); + } + + pub(crate) fn key_ownership_proof( + &mut self, + key: (Hash, ValidatorId), + ) -> Option<&Option> { + self.key_ownership_proof.get(&key) + } + + pub(crate) fn cache_key_ownership_proof( + &mut self, + key: (Hash, ValidatorId), + value: Option, + ) { + self.key_ownership_proof.put(key, value); + } + + // This request is never cached, hence always returns `None`. + pub(crate) fn submit_report_dispute_lost( + &mut self, + _key: (Hash, vstaging::slashing::DisputeProof, vstaging::slashing::OpaqueKeyOwnershipProof), + ) -> Option<&Option<()>> { + None + } + + pub(crate) fn staging_para_backing_state( + &mut self, + key: (Hash, ParaId), + ) -> Option<&Option> { + self.staging_para_backing_state.get(&key) + } + + pub(crate) fn cache_staging_para_backing_state( + &mut self, + key: (Hash, ParaId), + value: Option, + ) { + self.staging_para_backing_state.put(key, value); + } + + pub(crate) fn staging_async_backing_params( + &mut self, + key: &Hash, + ) -> Option<&vstaging::AsyncBackingParams> { + self.staging_async_backing_params.get(key) + } + + pub(crate) fn cache_staging_async_backing_params( + &mut self, + key: Hash, + value: vstaging::AsyncBackingParams, + ) { + self.staging_async_backing_params.put(key, value); + } +} + +pub(crate) enum RequestResult { + // The structure of each variant is (relay_parent, [params,]*, result) + Authorities(Hash, Vec), + Validators(Hash, Vec), + ValidatorGroups(Hash, (Vec>, GroupRotationInfo)), + AvailabilityCores(Hash, Vec), + PersistedValidationData(Hash, ParaId, OccupiedCoreAssumption, Option), + AssumedValidationData( + Hash, + ParaId, + Hash, + Option<(PersistedValidationData, ValidationCodeHash)>, + ), + CheckValidationOutputs(Hash, ParaId, CandidateCommitments, bool), + SessionIndexForChild(Hash, SessionIndex), + ValidationCode(Hash, ParaId, OccupiedCoreAssumption, Option), + ValidationCodeByHash(Hash, ValidationCodeHash, Option), + CandidatePendingAvailability(Hash, ParaId, Option), + CandidateEvents(Hash, Vec), + SessionExecutorParams(Hash, SessionIndex, Option), + SessionInfo(Hash, SessionIndex, Option), + DmqContents(Hash, ParaId, Vec>), + InboundHrmpChannelsContents( + Hash, + ParaId, + BTreeMap>>, + ), + CurrentBabeEpoch(Hash, Epoch), + FetchOnChainVotes(Hash, Option), + PvfsRequirePrecheck(Hash, Vec), + // This is a request with side-effects and no result, hence (). + SubmitPvfCheckStatement(Hash, PvfCheckStatement, ValidatorSignature, ()), + ValidationCodeHash(Hash, ParaId, OccupiedCoreAssumption, Option), + Version(Hash, u32), + Disputes(Hash, Vec<(SessionIndex, CandidateHash, DisputeState)>), + UnappliedSlashes(Hash, Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>), + KeyOwnershipProof(Hash, ValidatorId, Option), + // This is a request with side-effects. + SubmitReportDisputeLost( + Hash, + vstaging::slashing::DisputeProof, + vstaging::slashing::OpaqueKeyOwnershipProof, + Option<()>, + ), + + StagingParaBackingState(Hash, ParaId, Option), + StagingAsyncBackingParams(Hash, vstaging::AsyncBackingParams), +} diff --git a/polkadot/node/core/runtime-api/src/lib.rs b/polkadot/node/core/runtime-api/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..78531d41272b58483661a5fd628d49347939aa43 --- /dev/null +++ b/polkadot/node/core/runtime-api/src/lib.rs @@ -0,0 +1,572 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implements the Runtime API Subsystem +//! +//! This provides a clean, ownerless wrapper around the parachain-related runtime APIs. This crate +//! can also be used to cache responses from heavy runtime APIs. + +#![deny(unused_crate_dependencies)] +#![warn(missing_docs)] + +use polkadot_node_subsystem::{ + errors::RuntimeApiError, + messages::{RuntimeApiMessage, RuntimeApiRequest as Request}, + overseer, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, SubsystemResult, +}; +use polkadot_node_subsystem_types::RuntimeApiSubsystemClient; +use polkadot_primitives::Hash; + +use cache::{RequestResult, RequestResultCache}; +use futures::{channel::oneshot, prelude::*, select, stream::FuturesUnordered}; +use std::sync::Arc; + +mod cache; + +mod metrics; +use self::metrics::Metrics; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &str = "parachain::runtime-api"; + +/// The number of maximum runtime API requests can be executed in parallel. +/// Further requests will backpressure the bounded channel. +const MAX_PARALLEL_REQUESTS: usize = 4; + +/// The name of the blocking task that executes a runtime API request. +const API_REQUEST_TASK_NAME: &str = "polkadot-runtime-api-request"; + +/// The `RuntimeApiSubsystem`. See module docs for more details. +pub struct RuntimeApiSubsystem { + client: Arc, + metrics: Metrics, + spawn_handle: Box, + /// All the active runtime API requests that are currently being executed. + active_requests: FuturesUnordered>>, + /// Requests results cache + requests_cache: RequestResultCache, +} + +impl RuntimeApiSubsystem { + /// Create a new Runtime API subsystem wrapping the given client and metrics. + pub fn new( + client: Arc, + metrics: Metrics, + spawner: impl overseer::gen::Spawner + 'static, + ) -> Self { + RuntimeApiSubsystem { + client, + metrics, + spawn_handle: Box::new(spawner), + active_requests: Default::default(), + requests_cache: RequestResultCache::default(), + } + } +} + +#[overseer::subsystem(RuntimeApi, error = SubsystemError, prefix = self::overseer)] +impl RuntimeApiSubsystem +where + Client: RuntimeApiSubsystemClient + Send + Sync + 'static, +{ + fn start(self, ctx: Context) -> SpawnedSubsystem { + SpawnedSubsystem { future: run(ctx, self).boxed(), name: "runtime-api-subsystem" } + } +} + +impl RuntimeApiSubsystem +where + Client: RuntimeApiSubsystemClient + Send + 'static + Sync, +{ + fn store_cache(&mut self, result: RequestResult) { + use RequestResult::*; + + match result { + Authorities(relay_parent, authorities) => + self.requests_cache.cache_authorities(relay_parent, authorities), + Validators(relay_parent, validators) => + self.requests_cache.cache_validators(relay_parent, validators), + ValidatorGroups(relay_parent, groups) => + self.requests_cache.cache_validator_groups(relay_parent, groups), + AvailabilityCores(relay_parent, cores) => + self.requests_cache.cache_availability_cores(relay_parent, cores), + PersistedValidationData(relay_parent, para_id, assumption, data) => self + .requests_cache + .cache_persisted_validation_data((relay_parent, para_id, assumption), data), + AssumedValidationData( + _relay_parent, + para_id, + expected_persisted_validation_data_hash, + data, + ) => self.requests_cache.cache_assumed_validation_data( + (para_id, expected_persisted_validation_data_hash), + data, + ), + CheckValidationOutputs(relay_parent, para_id, commitments, b) => self + .requests_cache + .cache_check_validation_outputs((relay_parent, para_id, commitments), b), + SessionIndexForChild(relay_parent, session_index) => + self.requests_cache.cache_session_index_for_child(relay_parent, session_index), + ValidationCode(relay_parent, para_id, assumption, code) => self + .requests_cache + .cache_validation_code((relay_parent, para_id, assumption), code), + ValidationCodeByHash(_relay_parent, validation_code_hash, code) => + self.requests_cache.cache_validation_code_by_hash(validation_code_hash, code), + CandidatePendingAvailability(relay_parent, para_id, candidate) => self + .requests_cache + .cache_candidate_pending_availability((relay_parent, para_id), candidate), + CandidateEvents(relay_parent, events) => + self.requests_cache.cache_candidate_events(relay_parent, events), + SessionExecutorParams(_relay_parent, session_index, index) => + self.requests_cache.cache_session_executor_params(session_index, index), + SessionInfo(_relay_parent, session_index, info) => + if let Some(info) = info { + self.requests_cache.cache_session_info(session_index, info); + }, + DmqContents(relay_parent, para_id, messages) => + self.requests_cache.cache_dmq_contents((relay_parent, para_id), messages), + InboundHrmpChannelsContents(relay_parent, para_id, contents) => self + .requests_cache + .cache_inbound_hrmp_channel_contents((relay_parent, para_id), contents), + CurrentBabeEpoch(relay_parent, epoch) => + self.requests_cache.cache_current_babe_epoch(relay_parent, epoch), + FetchOnChainVotes(relay_parent, scraped) => + self.requests_cache.cache_on_chain_votes(relay_parent, scraped), + PvfsRequirePrecheck(relay_parent, pvfs) => + self.requests_cache.cache_pvfs_require_precheck(relay_parent, pvfs), + SubmitPvfCheckStatement(_, _, _, ()) => {}, + ValidationCodeHash(relay_parent, para_id, assumption, hash) => self + .requests_cache + .cache_validation_code_hash((relay_parent, para_id, assumption), hash), + Version(relay_parent, version) => + self.requests_cache.cache_version(relay_parent, version), + Disputes(relay_parent, disputes) => + self.requests_cache.cache_disputes(relay_parent, disputes), + UnappliedSlashes(relay_parent, unapplied_slashes) => + self.requests_cache.cache_unapplied_slashes(relay_parent, unapplied_slashes), + KeyOwnershipProof(relay_parent, validator_id, key_ownership_proof) => self + .requests_cache + .cache_key_ownership_proof((relay_parent, validator_id), key_ownership_proof), + SubmitReportDisputeLost(_, _, _, _) => {}, + + StagingParaBackingState(relay_parent, para_id, constraints) => self + .requests_cache + .cache_staging_para_backing_state((relay_parent, para_id), constraints), + StagingAsyncBackingParams(relay_parent, params) => + self.requests_cache.cache_staging_async_backing_params(relay_parent, params), + } + } + + fn query_cache(&mut self, relay_parent: Hash, request: Request) -> Option { + macro_rules! query { + // Just query by relay parent + ($cache_api_name:ident (), $sender:expr) => {{ + let sender = $sender; + if let Some(value) = self.requests_cache.$cache_api_name(&relay_parent) { + let _ = sender.send(Ok(value.clone())); + self.metrics.on_cached_request(); + None + } else { + Some(sender) + } + }}; + // Query by relay parent + additional parameters + ($cache_api_name:ident ($($param:expr),+), $sender:expr) => {{ + let sender = $sender; + if let Some(value) = self.requests_cache.$cache_api_name((relay_parent.clone(), $($param.clone()),+)) { + self.metrics.on_cached_request(); + let _ = sender.send(Ok(value.clone())); + None + } else { + Some(sender) + } + }} + } + + match request { + Request::Version(sender) => + query!(version(), sender).map(|sender| Request::Version(sender)), + Request::Authorities(sender) => + query!(authorities(), sender).map(|sender| Request::Authorities(sender)), + Request::Validators(sender) => + query!(validators(), sender).map(|sender| Request::Validators(sender)), + Request::ValidatorGroups(sender) => + query!(validator_groups(), sender).map(|sender| Request::ValidatorGroups(sender)), + Request::AvailabilityCores(sender) => query!(availability_cores(), sender) + .map(|sender| Request::AvailabilityCores(sender)), + Request::PersistedValidationData(para, assumption, sender) => + query!(persisted_validation_data(para, assumption), sender) + .map(|sender| Request::PersistedValidationData(para, assumption, sender)), + Request::AssumedValidationData( + para, + expected_persisted_validation_data_hash, + sender, + ) => query!( + assumed_validation_data(para, expected_persisted_validation_data_hash), + sender + ) + .map(|sender| { + Request::AssumedValidationData( + para, + expected_persisted_validation_data_hash, + sender, + ) + }), + Request::CheckValidationOutputs(para, commitments, sender) => + query!(check_validation_outputs(para, commitments), sender) + .map(|sender| Request::CheckValidationOutputs(para, commitments, sender)), + Request::SessionIndexForChild(sender) => query!(session_index_for_child(), sender) + .map(|sender| Request::SessionIndexForChild(sender)), + Request::ValidationCode(para, assumption, sender) => + query!(validation_code(para, assumption), sender) + .map(|sender| Request::ValidationCode(para, assumption, sender)), + Request::ValidationCodeByHash(validation_code_hash, sender) => + query!(validation_code_by_hash(validation_code_hash), sender) + .map(|sender| Request::ValidationCodeByHash(validation_code_hash, sender)), + Request::CandidatePendingAvailability(para, sender) => + query!(candidate_pending_availability(para), sender) + .map(|sender| Request::CandidatePendingAvailability(para, sender)), + Request::CandidateEvents(sender) => + query!(candidate_events(), sender).map(|sender| Request::CandidateEvents(sender)), + Request::SessionExecutorParams(session_index, sender) => { + if let Some(executor_params) = + self.requests_cache.session_executor_params(session_index) + { + self.metrics.on_cached_request(); + let _ = sender.send(Ok(executor_params.clone())); + None + } else { + Some(Request::SessionExecutorParams(session_index, sender)) + } + }, + Request::SessionInfo(index, sender) => { + if let Some(info) = self.requests_cache.session_info(index) { + self.metrics.on_cached_request(); + let _ = sender.send(Ok(Some(info.clone()))); + None + } else { + Some(Request::SessionInfo(index, sender)) + } + }, + Request::DmqContents(id, sender) => + query!(dmq_contents(id), sender).map(|sender| Request::DmqContents(id, sender)), + Request::InboundHrmpChannelsContents(id, sender) => + query!(inbound_hrmp_channels_contents(id), sender) + .map(|sender| Request::InboundHrmpChannelsContents(id, sender)), + Request::CurrentBabeEpoch(sender) => + query!(current_babe_epoch(), sender).map(|sender| Request::CurrentBabeEpoch(sender)), + Request::FetchOnChainVotes(sender) => + query!(on_chain_votes(), sender).map(|sender| Request::FetchOnChainVotes(sender)), + Request::PvfsRequirePrecheck(sender) => query!(pvfs_require_precheck(), sender) + .map(|sender| Request::PvfsRequirePrecheck(sender)), + request @ Request::SubmitPvfCheckStatement(_, _, _) => { + // This request is side-effecting and thus cannot be cached. + Some(request) + }, + Request::ValidationCodeHash(para, assumption, sender) => + query!(validation_code_hash(para, assumption), sender) + .map(|sender| Request::ValidationCodeHash(para, assumption, sender)), + Request::Disputes(sender) => + query!(disputes(), sender).map(|sender| Request::Disputes(sender)), + Request::UnappliedSlashes(sender) => + query!(unapplied_slashes(), sender).map(|sender| Request::UnappliedSlashes(sender)), + Request::KeyOwnershipProof(validator_id, sender) => + query!(key_ownership_proof(validator_id), sender) + .map(|sender| Request::KeyOwnershipProof(validator_id, sender)), + Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) => + query!(submit_report_dispute_lost(dispute_proof, key_ownership_proof), sender).map( + |sender| { + Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) + }, + ), + + Request::StagingParaBackingState(para, sender) => + query!(staging_para_backing_state(para), sender) + .map(|sender| Request::StagingParaBackingState(para, sender)), + Request::StagingAsyncBackingParams(sender) => + query!(staging_async_backing_params(), sender) + .map(|sender| Request::StagingAsyncBackingParams(sender)), + } + } + + /// Spawn a runtime API request. + fn spawn_request(&mut self, relay_parent: Hash, request: Request) { + let client = self.client.clone(); + let metrics = self.metrics.clone(); + let (sender, receiver) = oneshot::channel(); + + // TODO: make the cache great again https://github.com/paritytech/polkadot/issues/5546 + let request = match self.query_cache(relay_parent, request) { + Some(request) => request, + None => return, + }; + + let request = async move { + let result = make_runtime_api_request(client, metrics, relay_parent, request).await; + let _ = sender.send(result); + } + .boxed(); + + self.spawn_handle + .spawn_blocking(API_REQUEST_TASK_NAME, Some("runtime-api"), request); + self.active_requests.push(receiver); + } + + /// Poll the active runtime API requests. + async fn poll_requests(&mut self) { + // If there are no active requests, this future should be pending forever. + if self.active_requests.len() == 0 { + return futures::pending!() + } + + // If there are active requests, this will always resolve to `Some(_)` when a request is + // finished. + if let Some(Ok(Some(result))) = self.active_requests.next().await { + self.store_cache(result); + } + } + + /// Returns true if our `active_requests` queue is full. + fn is_busy(&self) -> bool { + self.active_requests.len() >= MAX_PARALLEL_REQUESTS + } +} + +#[overseer::contextbounds(RuntimeApi, prefix = self::overseer)] +async fn run( + mut ctx: Context, + mut subsystem: RuntimeApiSubsystem, +) -> SubsystemResult<()> +where + Client: RuntimeApiSubsystemClient + Send + Sync + 'static, +{ + loop { + // Let's add some back pressure when the subsystem is running at `MAX_PARALLEL_REQUESTS`. + // This can never block forever, because `active_requests` is owned by this task and any + // mutations happen either in `poll_requests` or `spawn_request` - so if `is_busy` returns + // true, then even if all of the requests finish before us calling `poll_requests` the + // `active_requests` length remains invariant. + if subsystem.is_busy() { + // Since we are not using any internal waiting queues, we need to wait for exactly + // one request to complete before we can read the next one from the overseer channel. + let _ = subsystem.poll_requests().await; + } + + select! { + req = ctx.recv().fuse() => match req? { + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(_)) => {}, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {}, + FromOrchestra::Communication { msg } => match msg { + RuntimeApiMessage::Request(relay_parent, request) => { + subsystem.spawn_request(relay_parent, request); + }, + } + }, + _ = subsystem.poll_requests().fuse() => {}, + } + } +} + +async fn make_runtime_api_request( + client: Arc, + metrics: Metrics, + relay_parent: Hash, + request: Request, +) -> Option +where + Client: RuntimeApiSubsystemClient + 'static, +{ + let _timer = metrics.time_make_runtime_api_request(); + + macro_rules! query { + ($req_variant:ident, $api_name:ident ($($param:expr),*), ver = $version:expr, $sender:expr) => {{ + let sender = $sender; + let version: u32 = $version; // enforce type for the version expression + let runtime_version = client.api_version_parachain_host(relay_parent).await + .unwrap_or_else(|e| { + gum::warn!( + target: LOG_TARGET, + "cannot query the runtime API version: {}", + e, + ); + Some(0) + }) + .unwrap_or_else(|| { + gum::warn!( + target: LOG_TARGET, + "no runtime version is reported" + ); + 0 + }); + + let res = if runtime_version >= version { + client.$api_name(relay_parent $(, $param.clone() )*).await + .map_err(|e| RuntimeApiError::Execution { + runtime_api_name: stringify!($api_name), + source: std::sync::Arc::new(e), + }) + } else { + Err(RuntimeApiError::NotSupported { + runtime_api_name: stringify!($api_name), + }) + }; + metrics.on_request(res.is_ok()); + let _ = sender.send(res.clone()); + + res.ok().map(|res| RequestResult::$req_variant(relay_parent, $( $param, )* res)) + }} + } + + match request { + Request::Version(sender) => { + let runtime_version = match client.api_version_parachain_host(relay_parent).await { + Ok(Some(v)) => Ok(v), + Ok(None) => Err(RuntimeApiError::NotSupported { runtime_api_name: "api_version" }), + Err(e) => Err(RuntimeApiError::Execution { + runtime_api_name: "api_version", + source: std::sync::Arc::new(e), + }), + }; + + let _ = sender.send(runtime_version.clone()); + runtime_version.ok().map(|v| RequestResult::Version(relay_parent, v)) + }, + + Request::Authorities(sender) => query!(Authorities, authorities(), ver = 1, sender), + Request::Validators(sender) => query!(Validators, validators(), ver = 1, sender), + Request::ValidatorGroups(sender) => { + query!(ValidatorGroups, validator_groups(), ver = 1, sender) + }, + Request::AvailabilityCores(sender) => { + query!(AvailabilityCores, availability_cores(), ver = 1, sender) + }, + Request::PersistedValidationData(para, assumption, sender) => query!( + PersistedValidationData, + persisted_validation_data(para, assumption), + ver = 1, + sender + ), + Request::AssumedValidationData(para, expected_persisted_validation_data_hash, sender) => { + query!( + AssumedValidationData, + assumed_validation_data(para, expected_persisted_validation_data_hash), + ver = 1, + sender + ) + }, + Request::CheckValidationOutputs(para, commitments, sender) => query!( + CheckValidationOutputs, + check_validation_outputs(para, commitments), + ver = 1, + sender + ), + Request::SessionIndexForChild(sender) => { + query!(SessionIndexForChild, session_index_for_child(), ver = 1, sender) + }, + Request::ValidationCode(para, assumption, sender) => { + query!(ValidationCode, validation_code(para, assumption), ver = 1, sender) + }, + Request::ValidationCodeByHash(validation_code_hash, sender) => query!( + ValidationCodeByHash, + validation_code_by_hash(validation_code_hash), + ver = 1, + sender + ), + Request::CandidatePendingAvailability(para, sender) => query!( + CandidatePendingAvailability, + candidate_pending_availability(para), + ver = 1, + sender + ), + Request::CandidateEvents(sender) => { + query!(CandidateEvents, candidate_events(), ver = 1, sender) + }, + Request::SessionInfo(index, sender) => { + query!(SessionInfo, session_info(index), ver = 2, sender) + }, + Request::SessionExecutorParams(session_index, sender) => query!( + SessionExecutorParams, + session_executor_params(session_index), + ver = Request::EXECUTOR_PARAMS_RUNTIME_REQUIREMENT, + sender + ), + Request::DmqContents(id, sender) => query!(DmqContents, dmq_contents(id), ver = 1, sender), + Request::InboundHrmpChannelsContents(id, sender) => { + query!(InboundHrmpChannelsContents, inbound_hrmp_channels_contents(id), ver = 1, sender) + }, + Request::CurrentBabeEpoch(sender) => { + query!(CurrentBabeEpoch, current_epoch(), ver = 1, sender) + }, + Request::FetchOnChainVotes(sender) => { + query!(FetchOnChainVotes, on_chain_votes(), ver = 1, sender) + }, + Request::SubmitPvfCheckStatement(stmt, signature, sender) => { + query!( + SubmitPvfCheckStatement, + submit_pvf_check_statement(stmt, signature), + ver = 2, + sender + ) + }, + Request::PvfsRequirePrecheck(sender) => { + query!(PvfsRequirePrecheck, pvfs_require_precheck(), ver = 2, sender) + }, + Request::ValidationCodeHash(para, assumption, sender) => { + query!(ValidationCodeHash, validation_code_hash(para, assumption), ver = 2, sender) + }, + Request::Disputes(sender) => { + query!(Disputes, disputes(), ver = Request::DISPUTES_RUNTIME_REQUIREMENT, sender) + }, + Request::UnappliedSlashes(sender) => query!( + UnappliedSlashes, + unapplied_slashes(), + ver = Request::UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT, + sender + ), + Request::KeyOwnershipProof(validator_id, sender) => query!( + KeyOwnershipProof, + key_ownership_proof(validator_id), + ver = Request::KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT, + sender + ), + Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) => query!( + SubmitReportDisputeLost, + submit_report_dispute_lost(dispute_proof, key_ownership_proof), + ver = Request::SUBMIT_REPORT_DISPUTE_LOST_RUNTIME_REQUIREMENT, + sender + ), + + Request::StagingParaBackingState(para, sender) => { + query!( + StagingParaBackingState, + staging_para_backing_state(para), + ver = Request::STAGING_BACKING_STATE, + sender + ) + }, + Request::StagingAsyncBackingParams(sender) => { + query!( + StagingAsyncBackingParams, + staging_async_backing_params(), + ver = Request::STAGING_BACKING_STATE, + sender + ) + }, + } +} diff --git a/polkadot/node/core/runtime-api/src/metrics.rs b/polkadot/node/core/runtime-api/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..dc9103897781e9f801b90b52729b12b574e0c203 --- /dev/null +++ b/polkadot/node/core/runtime-api/src/metrics.rs @@ -0,0 +1,77 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_metrics::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) chain_api_requests: prometheus::CounterVec, + pub(crate) make_runtime_api_request: prometheus::Histogram, +} + +/// Runtime API metrics. +#[derive(Default, Clone)] +pub struct Metrics(pub(crate) Option); + +impl Metrics { + pub fn on_request(&self, succeeded: bool) { + if let Some(metrics) = &self.0 { + if succeeded { + metrics.chain_api_requests.with_label_values(&["succeeded"]).inc(); + } else { + metrics.chain_api_requests.with_label_values(&["failed"]).inc(); + } + } + } + + pub fn on_cached_request(&self) { + self.0 + .as_ref() + .map(|metrics| metrics.chain_api_requests.with_label_values(&["cached"]).inc()); + } + + /// Provide a timer for `make_runtime_api_request` which observes on drop. + pub fn time_make_runtime_api_request( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.make_runtime_api_request.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + chain_api_requests: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_runtime_api_requests_total", + "Number of Runtime API requests served.", + ), + &["success"], + )?, + registry, + )?, + make_runtime_api_request: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_runtime_api_make_runtime_api_request", + "Time spent within `runtime_api::make_runtime_api_request`", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/core/runtime-api/src/tests.rs b/polkadot/node/core/runtime-api/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..c3f8108312be13508fff8abcfe80d44ea17b8577 --- /dev/null +++ b/polkadot/node/core/runtime-api/src/tests.rs @@ -0,0 +1,1115 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use polkadot_node_primitives::{BabeAllowedSlots, BabeEpoch, BabeEpochConfiguration}; +use polkadot_node_subsystem::SpawnGlue; +use polkadot_node_subsystem_test_helpers::make_subsystem_context; +use polkadot_primitives::{ + vstaging, AuthorityDiscoveryId, BlockNumber, CandidateCommitments, CandidateEvent, + CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, + GroupRotationInfo, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, + OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, + SessionIndex, SessionInfo, Slot, ValidationCode, ValidationCodeHash, ValidatorId, + ValidatorIndex, ValidatorSignature, +}; +use sp_api::ApiError; +use sp_core::testing::TaskExecutor; +use std::{ + collections::{BTreeMap, HashMap}, + sync::{Arc, Mutex}, +}; +use test_helpers::{dummy_committed_candidate_receipt, dummy_validation_code}; + +#[derive(Default)] +struct MockSubsystemClient { + submitted_pvf_check_statement: Arc>>, + authorities: Vec, + validators: Vec, + validator_groups: Vec>, + availability_cores: Vec, + validation_data: HashMap, + validation_code: HashMap, + validation_outputs_results: HashMap, + session_index_for_child: SessionIndex, + candidate_pending_availability: HashMap, + dmq_contents: HashMap>, + hrmp_channels: HashMap>>, + validation_code_by_hash: HashMap, + availability_cores_wait: Arc>, + babe_epoch: Option, + pvfs_require_precheck: Vec, + validation_code_hash: HashMap, + session_info: HashMap, + candidate_events: Vec, +} + +#[async_trait::async_trait] +impl RuntimeApiSubsystemClient for MockSubsystemClient { + async fn api_version_parachain_host(&self, _: Hash) -> Result, ApiError> { + Ok(Some(5)) + } + + async fn validators(&self, _: Hash) -> Result, ApiError> { + Ok(self.validators.clone()) + } + + async fn validator_groups( + &self, + _: Hash, + ) -> Result<(Vec>, GroupRotationInfo), ApiError> { + Ok(( + self.validator_groups.clone(), + GroupRotationInfo { session_start_block: 1, group_rotation_frequency: 100, now: 10 }, + )) + } + + async fn availability_cores( + &self, + _: Hash, + ) -> Result>, ApiError> { + let _lock = self.availability_cores_wait.lock().unwrap(); + Ok(self.availability_cores.clone()) + } + + async fn persisted_validation_data( + &self, + _: Hash, + para_id: ParaId, + _: OccupiedCoreAssumption, + ) -> Result>, ApiError> { + Ok(self.validation_data.get(¶_id).cloned()) + } + + async fn assumed_validation_data( + &self, + _: Hash, + para_id: ParaId, + expected_persisted_validation_data_hash: Hash, + ) -> Result, ValidationCodeHash)>, ApiError> + { + Ok(self + .validation_data + .get(¶_id) + .cloned() + .filter(|data| data.hash() == expected_persisted_validation_data_hash) + .zip(self.validation_code.get(¶_id).map(|code| code.hash()))) + } + + async fn check_validation_outputs( + &self, + _: Hash, + para_id: ParaId, + _: CandidateCommitments, + ) -> Result { + Ok(self.validation_outputs_results.get(¶_id).copied().unwrap()) + } + + async fn session_index_for_child(&self, _: Hash) -> Result { + Ok(self.session_index_for_child) + } + + async fn validation_code( + &self, + _: Hash, + para_id: ParaId, + _: OccupiedCoreAssumption, + ) -> Result, ApiError> { + Ok(self.validation_code.get(¶_id).cloned()) + } + + async fn candidate_pending_availability( + &self, + _: Hash, + para_id: ParaId, + ) -> Result>, ApiError> { + Ok(self.candidate_pending_availability.get(¶_id).cloned()) + } + + async fn candidate_events(&self, _: Hash) -> Result>, ApiError> { + Ok(self.candidate_events.clone()) + } + + async fn dmq_contents( + &self, + _: Hash, + para_id: ParaId, + ) -> Result>, ApiError> { + Ok(self.dmq_contents.get(¶_id).cloned().unwrap()) + } + + async fn inbound_hrmp_channels_contents( + &self, + _: Hash, + para_id: ParaId, + ) -> Result>>, ApiError> { + Ok(self.hrmp_channels.get(¶_id).cloned().unwrap()) + } + + async fn validation_code_by_hash( + &self, + _: Hash, + hash: ValidationCodeHash, + ) -> Result, ApiError> { + Ok(self.validation_code_by_hash.get(&hash).cloned()) + } + + async fn on_chain_votes(&self, _: Hash) -> Result>, ApiError> { + todo!("Not required for tests") + } + + async fn session_info( + &self, + _: Hash, + index: SessionIndex, + ) -> Result, ApiError> { + Ok(self.session_info.get(&index).cloned()) + } + + async fn submit_pvf_check_statement( + &self, + _: Hash, + stmt: PvfCheckStatement, + sig: ValidatorSignature, + ) -> Result<(), ApiError> { + self.submitted_pvf_check_statement.lock().unwrap().push((stmt, sig)); + Ok(()) + } + + async fn pvfs_require_precheck(&self, _: Hash) -> Result, ApiError> { + Ok(self.pvfs_require_precheck.clone()) + } + + async fn validation_code_hash( + &self, + _: Hash, + para_id: ParaId, + _: OccupiedCoreAssumption, + ) -> Result, ApiError> { + Ok(self.validation_code_hash.get(¶_id).cloned()) + } + + async fn disputes( + &self, + _: Hash, + ) -> Result)>, ApiError> { + todo!("Not required for tests") + } + + async fn unapplied_slashes( + &self, + _: Hash, + ) -> Result, ApiError> { + todo!("Not required for tests") + } + + async fn key_ownership_proof( + &self, + _: Hash, + _: ValidatorId, + ) -> Result, ApiError> { + todo!("Not required for tests") + } + + async fn submit_report_dispute_lost( + &self, + _: Hash, + _: vstaging::slashing::DisputeProof, + _: vstaging::slashing::OpaqueKeyOwnershipProof, + ) -> Result, ApiError> { + todo!("Not required for tests") + } + + async fn session_executor_params( + &self, + _: Hash, + _: SessionIndex, + ) -> Result, ApiError> { + todo!("Not required for tests") + } + + async fn current_epoch(&self, _: Hash) -> Result { + Ok(self.babe_epoch.as_ref().unwrap().clone()) + } + + async fn authorities(&self, _: Hash) -> Result, ApiError> { + Ok(self.authorities.clone()) + } + + async fn staging_async_backing_params( + &self, + _: Hash, + ) -> Result { + todo!("Not required for tests") + } + + async fn staging_para_backing_state( + &self, + _: Hash, + _: ParaId, + ) -> Result, ApiError> { + todo!("Not required for tests") + } +} + +#[test] +fn requests_authorities() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let substem_client = Arc::new(MockSubsystemClient::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); + + let subsystem = + RuntimeApiSubsystem::new(substem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::Authorities(tx)), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), substem_client.authorities); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_validators() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let subsystem_client = Arc::new(MockSubsystemClient::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::Validators(tx)), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), subsystem_client.validators); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_validator_groups() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let subsystem_client = Arc::new(MockSubsystemClient::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::ValidatorGroups(tx)), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap().0, subsystem_client.validator_groups); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_availability_cores() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let subsystem_client = Arc::new(MockSubsystemClient::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::AvailabilityCores(tx)), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), subsystem_client.availability_cores); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_persisted_validation_data() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let relay_parent = [1; 32].into(); + let para_a = ParaId::from(5_u32); + let para_b = ParaId::from(6_u32); + let spawner = sp_core::testing::TaskExecutor::new(); + + let mut subsystem_client = MockSubsystemClient::default(); + subsystem_client.validation_data.insert(para_a, Default::default()); + let subsystem_client = Arc::new(subsystem_client); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::PersistedValidationData(para_a, OccupiedCoreAssumption::Included, tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); + + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::PersistedValidationData(para_b, OccupiedCoreAssumption::Included, tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), None); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_assumed_validation_data() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let relay_parent = [1; 32].into(); + let para_a = ParaId::from(5_u32); + let para_b = ParaId::from(6_u32); + let spawner = sp_core::testing::TaskExecutor::new(); + + let validation_code = ValidationCode(vec![1, 2, 3]); + let expected_data_hash = ::default().hash(); + let expected_code_hash = validation_code.hash(); + + let mut subsystem_client = MockSubsystemClient::default(); + subsystem_client.validation_data.insert(para_a, Default::default()); + subsystem_client.validation_code.insert(para_a, validation_code); + subsystem_client.validation_data.insert(para_b, Default::default()); + let subsystem_client = Arc::new(subsystem_client); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::AssumedValidationData(para_a, expected_data_hash, tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), Some((Default::default(), expected_code_hash))); + + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::AssumedValidationData(para_a, Hash::zero(), tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), None); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_check_validation_outputs() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let mut subsystem_client = MockSubsystemClient::default(); + let relay_parent = [1; 32].into(); + let para_a = ParaId::from(5_u32); + let para_b = ParaId::from(6_u32); + let commitments = polkadot_primitives::CandidateCommitments::default(); + let spawner = sp_core::testing::TaskExecutor::new(); + + subsystem_client.validation_outputs_results.insert(para_a, false); + subsystem_client.validation_outputs_results.insert(para_b, true); + + let subsystem_client = Arc::new(subsystem_client); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CheckValidationOutputs(para_a, commitments.clone(), tx), + ), + }) + .await; + assert_eq!( + rx.await.unwrap().unwrap(), + subsystem_client.validation_outputs_results[¶_a] + ); + + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CheckValidationOutputs(para_b, commitments, tx), + ), + }) + .await; + assert_eq!( + rx.await.unwrap().unwrap(), + subsystem_client.validation_outputs_results[¶_b] + ); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_session_index_for_child() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let subsystem_client = Arc::new(MockSubsystemClient::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::SessionIndexForChild(tx)), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), subsystem_client.session_index_for_child); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +fn dummy_session_info() -> SessionInfo { + SessionInfo { + validators: Default::default(), + discovery_keys: vec![], + assignment_keys: vec![], + validator_groups: Default::default(), + n_cores: 4u32, + zeroth_delay_tranche_width: 0u32, + relay_vrf_modulo_samples: 0u32, + n_delay_tranches: 2u32, + no_show_slots: 0u32, + needed_approvals: 1u32, + active_validator_indices: vec![], + dispute_period: 6, + random_seed: [0u8; 32], + } +} +#[test] +fn requests_session_info() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let mut subsystem_client = MockSubsystemClient::default(); + let session_index = 1; + subsystem_client.session_info.insert(session_index, dummy_session_info()); + let subsystem_client = Arc::new(subsystem_client); + let spawner = sp_core::testing::TaskExecutor::new(); + + let relay_parent = [1; 32].into(); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::SessionInfo(session_index, tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), Some(dummy_session_info())); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_validation_code() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + + let relay_parent = [1; 32].into(); + let para_a = ParaId::from(5_u32); + let para_b = ParaId::from(6_u32); + let spawner = sp_core::testing::TaskExecutor::new(); + let validation_code = dummy_validation_code(); + + let mut subsystem_client = MockSubsystemClient::default(); + subsystem_client.validation_code.insert(para_a, validation_code.clone()); + let subsystem_client = Arc::new(subsystem_client); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::ValidationCode(para_a, OccupiedCoreAssumption::Included, tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), Some(validation_code)); + + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::ValidationCode(para_b, OccupiedCoreAssumption::Included, tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), None); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_candidate_pending_availability() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let relay_parent = [1; 32].into(); + let para_a = ParaId::from(5_u32); + let para_b = ParaId::from(6_u32); + let spawner = sp_core::testing::TaskExecutor::new(); + let candidate_receipt = dummy_committed_candidate_receipt(relay_parent); + + let mut subsystem_client = MockSubsystemClient::default(); + subsystem_client + .candidate_pending_availability + .insert(para_a, candidate_receipt.clone()); + let subsystem_client = Arc::new(subsystem_client); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CandidatePendingAvailability(para_a, tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), Some(candidate_receipt)); + + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CandidatePendingAvailability(para_b, tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), None); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_candidate_events() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let subsystem_client = Arc::new(MockSubsystemClient::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::CandidateEvents(tx)), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), subsystem_client.candidate_events); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_dmq_contents() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + + let relay_parent = [1; 32].into(); + let para_a = ParaId::from(5_u32); + let para_b = ParaId::from(6_u32); + let spawner = sp_core::testing::TaskExecutor::new(); + + let subsystem_client = Arc::new({ + let mut subsystem_client = MockSubsystemClient::default(); + + subsystem_client.dmq_contents.insert(para_a, vec![]); + subsystem_client.dmq_contents.insert( + para_b, + vec![InboundDownwardMessage { sent_at: 228, msg: b"Novus Ordo Seclorum".to_vec() }], + ); + + subsystem_client + }); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::DmqContents(para_a, tx)), + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), vec![]); + + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::DmqContents(para_b, tx)), + }) + .await; + assert_eq!( + rx.await.unwrap().unwrap(), + vec![InboundDownwardMessage { sent_at: 228, msg: b"Novus Ordo Seclorum".to_vec() }] + ); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_inbound_hrmp_channels_contents() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + + let relay_parent = [1; 32].into(); + let para_a = ParaId::from(99_u32); + let para_b = ParaId::from(66_u32); + let para_c = ParaId::from(33_u32); + let spawner = sp_core::testing::TaskExecutor::new(); + + let para_b_inbound_channels = [ + (para_a, vec![]), + (para_c, vec![InboundHrmpMessage { sent_at: 1, data: "𝙀=𝙈𝘾²".as_bytes().to_owned() }]), + ] + .into_iter() + .collect::>(); + + let subsystem_client = Arc::new({ + let mut subsystem_client = MockSubsystemClient::default(); + + subsystem_client.hrmp_channels.insert(para_a, BTreeMap::new()); + subsystem_client.hrmp_channels.insert(para_b, para_b_inbound_channels.clone()); + + subsystem_client + }); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::InboundHrmpChannelsContents(para_a, tx), + ), + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), BTreeMap::new()); + + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::InboundHrmpChannelsContents(para_b, tx), + ), + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), para_b_inbound_channels); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_validation_code_by_hash() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let spawner = sp_core::testing::TaskExecutor::new(); + + let (subsystem_client, validation_code) = { + let mut subsystem_client = MockSubsystemClient::default(); + let mut validation_code = Vec::new(); + + for n in 0..5 { + let code = ValidationCode::from(vec![n; 32]); + subsystem_client.validation_code_by_hash.insert(code.hash(), code.clone()); + validation_code.push(code); + } + + (Arc::new(subsystem_client), validation_code) + }; + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + + let relay_parent = [1; 32].into(); + let test_task = async move { + for code in validation_code { + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::ValidationCodeByHash(code.hash(), tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), Some(code)); + } + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn multiple_requests_in_parallel_are_working() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let subsystem_client = Arc::new(MockSubsystemClient::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); + let mutex = subsystem_client.availability_cores_wait.clone(); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + // Make all requests block until we release this mutex. + let lock = mutex.lock().unwrap(); + + let mut receivers = Vec::new(); + for _ in 0..MAX_PARALLEL_REQUESTS { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::AvailabilityCores(tx)), + }) + .await; + receivers.push(rx); + } + + // The backpressure from reaching `MAX_PARALLEL_REQUESTS` will make the test block, we need + // to drop the lock. + drop(lock); + + for _ in 0..MAX_PARALLEL_REQUESTS * 100 { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::AvailabilityCores(tx)), + }) + .await; + receivers.push(rx); + } + + let join = future::join_all(receivers); + + join.await + .into_iter() + .for_each(|r| assert_eq!(r.unwrap().unwrap(), subsystem_client.availability_cores)); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_babe_epoch() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let mut subsystem_client = MockSubsystemClient::default(); + let epoch = BabeEpoch { + epoch_index: 100, + start_slot: Slot::from(1000), + duration: 10, + authorities: Vec::new(), + randomness: [1u8; 32], + config: BabeEpochConfiguration { c: (1, 4), allowed_slots: BabeAllowedSlots::PrimarySlots }, + }; + subsystem_client.babe_epoch = Some(epoch.clone()); + let subsystem_client = Arc::new(subsystem_client); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::CurrentBabeEpoch(tx)), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), epoch); + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_submit_pvf_check_statement() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let spawner = sp_core::testing::TaskExecutor::new(); + let subsystem_client = Arc::new(MockSubsystemClient::default()); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + + let relay_parent = [1; 32].into(); + let test_task = async move { + let (stmt, sig) = fake_statement(); + + // Send the same statement twice. + // + // Here we just want to ensure that those requests do not go through the cache. + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::SubmitPvfCheckStatement(stmt.clone(), sig.clone(), tx), + ), + }) + .await; + let _ = rx.await.unwrap().unwrap(); + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::SubmitPvfCheckStatement(stmt.clone(), sig.clone(), tx), + ), + }) + .await; + let _ = rx.await.unwrap().unwrap(); + + assert_eq!( + &*subsystem_client.submitted_pvf_check_statement.lock().expect("poisened mutex"), + &[(stmt.clone(), sig.clone()), (stmt.clone(), sig.clone())] + ); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); + + fn fake_statement() -> (PvfCheckStatement, ValidatorSignature) { + let stmt = PvfCheckStatement { + accept: true, + subject: [1; 32].into(), + session_index: 1, + validator_index: 1.into(), + }; + let sig = sp_keyring::Sr25519Keyring::Alice.sign(&stmt.signing_payload()).into(); + (stmt, sig) + } +} + +#[test] +fn requests_pvfs_require_precheck() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + let spawner = sp_core::testing::TaskExecutor::new(); + + let subsystem_client = Arc::new({ + let mut subsystem_client = MockSubsystemClient::default(); + subsystem_client.pvfs_require_precheck = vec![[1; 32].into(), [2; 32].into()]; + subsystem_client + }); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + + let relay_parent = [1; 32].into(); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::PvfsRequirePrecheck(tx)), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), vec![[1; 32].into(), [2; 32].into()]); + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} + +#[test] +fn requests_validation_code_hash() { + let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new()); + + let relay_parent = [1; 32].into(); + let para_a = ParaId::from(5_u32); + let para_b = ParaId::from(6_u32); + let spawner = sp_core::testing::TaskExecutor::new(); + let validation_code_hash = dummy_validation_code().hash(); + + let mut subsystem_client = MockSubsystemClient::default(); + subsystem_client.validation_code_hash.insert(para_a, validation_code_hash); + let subsystem_client = Arc::new(subsystem_client); + + let subsystem = + RuntimeApiSubsystem::new(subsystem_client.clone(), Metrics(None), SpawnGlue(spawner)); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); + let test_task = async move { + let (tx, rx) = oneshot::channel(); + + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::ValidationCodeHash(para_a, OccupiedCoreAssumption::Included, tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), Some(validation_code_hash)); + + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOrchestra::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::ValidationCodeHash(para_b, OccupiedCoreAssumption::Included, tx), + ), + }) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), None); + + ctx_handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::executor::block_on(future::join(subsystem_task, test_task)); +} diff --git a/polkadot/node/gum/Cargo.toml b/polkadot/node/gum/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..9e9e784502926ca4fa9a7943643d6e6538371b60 --- /dev/null +++ b/polkadot/node/gum/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "tracing-gum" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +description = "Stick logs together with the TraceID as provided by tempo" + +[dependencies] +coarsetime = "0.1.22" +tracing = "0.1.35" +jaeger = { path = "../jaeger", package = "polkadot-node-jaeger" } +gum-proc-macro = { path = "./proc-macro", package = "tracing-gum-proc-macro" } +polkadot-primitives = { path = "../../primitives", features = ["std"] } diff --git a/polkadot/node/gum/README.md b/polkadot/node/gum/README.md new file mode 100644 index 0000000000000000000000000000000000000000..739ce3066ecb33bcb4dcc4143917f02465400e85 --- /dev/null +++ b/polkadot/node/gum/README.md @@ -0,0 +1,57 @@ +# tracing-gum + +"gum" to make `tracing::{warn,info,..}` and `mick-jaeger` stick together, to be +cross referenced in grafana with zero additional loc in the source code. + +## Usage + +See the crate docs (e.g. run `cargo doc --open`) for usage information! + +## Architecture Decision Record (ADR) + +### Context + +For cross referencing spans and logs in grafana loki and tempo, a shared +`traceID` or `TraceIdentifier` is required. All logs must be annotated with such +meta information. + +In most cases `CandidateHash` is the primary identifier of the `jaeger::Span` +and hence the source from which the `traceID` is derived. For cases where it is +_not_ the primary identifier, a helper tag named `traceID` is added to those +spans (out of scope, this is already present as a convenience measure). + +Log lines on the other hand side, use `warn!,info!,debug!,trace!,..` API +provided by the `tracing` crate. Many of these, contain a `candidate_hash`, +which is _not_ equivalent to the `traceID` (256bits vs 128bits), and hence must +be derived. + +To achieve the cross ref, either all instances of `candidate_hash` could be +added or this could be approached more systematically by providing a `macro` to +automatically do so. + +Related issues: + +* + +### Decision + +Adding approx. 2 lines per tracing line including a `candidate_hash` reference, +to derive the `TraceIdentifier` from that, and printing that as part of the +key-value section in the `tracing::*` macros. The visual overhead and friction +and required diligence to keep the 100s of `tracing::{warn!,info!,debug!,..}` up +is unreasonably high in the mid/long run. This is especially true, in the +context of more people joining the team. Hence a proc-macro is introduced +which abstracts this away, and does so automagically at the cost of +one-more-proc-macro in the codebase. + +### Consequences + +Minimal training/impact is required to name `CandidateHash` as `candidate_hash` +when providing to any of the log macros (`warn!`, `info!`, etc.). + +The crate has to be used throughout the entire codebase to work consistently, to +disambiguate, the prefix `gum::` is used. + +Feature parity with `tracing::{warn!,..}` is not desired. We want consistency +more than anything. All currently used features _are_ supported with _gum_ as +well. diff --git a/polkadot/node/gum/proc-macro/Cargo.toml b/polkadot/node/gum/proc-macro/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..e7262008499b5666a7beeaecd635fbcfbaf918ca --- /dev/null +++ b/polkadot/node/gum/proc-macro/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "tracing-gum-proc-macro" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +description = "Generate an overseer including builder pattern and message wrapper from a single annotated struct definition." + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +proc-macro = true + +[dependencies] +syn = { version = "2.0.15", features = ["full", "extra-traits"] } +quote = "1.0.28" +proc-macro2 = "1.0.56" +proc-macro-crate = "1.1.3" +expander = "2.0.0" + +[dev-dependencies] +assert_matches = "1.5.0" + + +[features] +default = [] +# write the expanded version to a `gum.[a-f0-9]{10}.rs` +# in the `OUT_DIR` as defined by `cargo` for the `expander` crate. +expand = [] diff --git a/polkadot/node/gum/proc-macro/src/lib.rs b/polkadot/node/gum/proc-macro/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..e8b6b599172d5eae93c928198ac9fc6bd7a42edc --- /dev/null +++ b/polkadot/node/gum/proc-macro/src/lib.rs @@ -0,0 +1,195 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![deny(unused_crate_dependencies)] +#![deny(missing_docs)] +#![deny(clippy::dbg_macro)] + +//! Generative part of `tracing-gum`. See `tracing-gum` for usage documentation. + +use proc_macro2::{Ident, Span, TokenStream}; +use quote::{quote, ToTokens}; +use syn::{parse2, parse_quote, punctuated::Punctuated, Result, Token}; + +mod types; + +use self::types::*; + +#[cfg(test)] +mod tests; + +/// Print an error message. +#[proc_macro] +pub fn error(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + gum(item, Level::Error) +} + +/// Print a warning level message. +#[proc_macro] +pub fn warn(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + gum(item, Level::Warn) +} + +/// Print a warning or debug level message depending on their frequency +#[proc_macro] +pub fn warn_if_frequent(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + let ArgsIfFrequent { freq, max_rate, rest } = parse2(item.into()).unwrap(); + + let freq_expr = freq.expr; + let max_rate_expr = max_rate.expr; + let debug: proc_macro2::TokenStream = gum(rest.clone().into(), Level::Debug).into(); + let warn: proc_macro2::TokenStream = gum(rest.into(), Level::Warn).into(); + + let stream = quote! { + if #freq_expr .is_frequent(#max_rate_expr) { + #warn + } else { + #debug + } + }; + + stream.into() +} + +/// Print a info level message. +#[proc_macro] +pub fn info(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + gum(item, Level::Info) +} + +/// Print a debug level message. +#[proc_macro] +pub fn debug(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + gum(item, Level::Debug) +} + +/// Print a trace level message. +#[proc_macro] +pub fn trace(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + gum(item, Level::Trace) +} + +/// One-size-fits all internal implementation that produces the actual code. +pub(crate) fn gum(item: proc_macro::TokenStream, level: Level) -> proc_macro::TokenStream { + let item: TokenStream = item.into(); + + let res = expander::Expander::new("gum") + .add_comment("Generated overseer code by `gum::warn!(..)`".to_owned()) + // `dry=true` until rust-analyzer can selectively disable features so it's + // not all red squiggles. Originally: `!cfg!(feature = "expand")` + // ISSUE: + .dry(true) + .verbose(false) + .fmt(expander::Edition::_2021) + .maybe_write_to_out_dir(impl_gum2(item, level)) + .expect("Expander does not fail due to IO in OUT_DIR. qed"); + + res.unwrap_or_else(|err| err.to_compile_error()).into() +} + +/// Does the actual parsing and token generation based on `proc_macro2` types. +/// +/// Required for unit tests. +pub(crate) fn impl_gum2(orig: TokenStream, level: Level) -> Result { + let args: Args = parse2(orig)?; + + let krate = support_crate(); + let span = Span::call_site(); + + let Args { target, comma, mut values, fmt } = args; + + // find a value or alias called `candidate_hash`. + let maybe_candidate_hash = values.iter_mut().find(|value| value.as_ident() == "candidate_hash"); + + if let Some(kv) = maybe_candidate_hash { + let (ident, rhs_expr, replace_with) = match kv { + Value::Alias(alias) => { + let ValueWithAliasIdent { alias, marker, expr, .. } = alias.clone(); + ( + alias.clone(), + expr.to_token_stream(), + Some(Value::Value(ValueWithFormatMarker { + marker, + ident: alias, + dot: None, + inner: Punctuated::new(), + })), + ) + }, + Value::Value(value) => (value.ident.clone(), value.ident.to_token_stream(), None), + }; + + // we generate a local value with the same alias name + // so replace the expr with just a value + if let Some(replace_with) = replace_with { + let _old = std::mem::replace(kv, replace_with); + }; + + // Inject the addition `traceID = % trace_id` identifier + // while maintaining trailing comma semantics. + let had_trailing_comma = values.trailing_punct(); + if !had_trailing_comma { + values.push_punct(Token![,](span)); + } + + values.push_value(parse_quote! { + traceID = % trace_id + }); + if had_trailing_comma { + values.push_punct(Token![,](span)); + } + + Ok(quote! { + if #krate :: enabled!(#target #comma #level) { + use ::std::ops::Deref; + + // create a scoped let binding of something that `deref`s to + // `Hash`. + let value = #rhs_expr; + let value = &value; + let value: & #krate:: Hash = value.deref(); + // Do the `deref` to `Hash` and convert to a `TraceIdentifier`. + let #ident: #krate:: Hash = * value; + let trace_id = #krate:: hash_to_trace_identifier ( #ident ); + #krate :: event!( + #target #comma #level, #values #fmt + ) + } + }) + } else { + Ok(quote! { + #krate :: event!( + #target #comma #level, #values #fmt + ) + }) + } +} + +/// Extract the support crate path. +fn support_crate() -> TokenStream { + let support_crate_name = if cfg!(test) { + quote! {crate} + } else { + use proc_macro_crate::{crate_name, FoundCrate}; + let crate_name = crate_name("tracing-gum") + .expect("Support crate `tracing-gum` is present in `Cargo.toml`. qed"); + match crate_name { + FoundCrate::Itself => quote! {crate}, + FoundCrate::Name(name) => Ident::new(&name, Span::call_site()).to_token_stream(), + } + }; + support_crate_name +} diff --git a/polkadot/node/gum/proc-macro/src/tests.rs b/polkadot/node/gum/proc-macro/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..6cf04c59d970d9d8f80448523bcb08d647d4da34 --- /dev/null +++ b/polkadot/node/gum/proc-macro/src/tests.rs @@ -0,0 +1,208 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![allow(clippy::dbg_macro)] + +use super::*; + +use assert_matches::assert_matches; +use quote::quote; + +#[test] +fn smoke() { + assert_matches!( + impl_gum2( + quote! { + target: "xyz", + x = Foo::default(), + z = ?Game::new(), + "Foo {p} x {q}", + p, + q, + }, + Level::Warn + ), + Ok(_) + ); +} + +mod roundtrip { + use super::*; + + macro_rules! roundtrip { + ($whatty:ty | $ts:expr) => { + let input = $ts; + assert_matches!( + ::syn::parse2::<$whatty>(input), + Ok(typed) => { + let downgraded = dbg!(typed.to_token_stream()); + assert_matches!(::syn::parse2::<$whatty>(downgraded), + Ok(reparsed) => { + assert_eq!( + dbg!(typed.into_token_stream().to_string()), + reparsed.into_token_stream().to_string(), + ) + }); + } + ); + } + } + + #[test] + fn u_target() { + roundtrip! {Target | quote! {target: "foo" } }; + } + + #[test] + fn u_format_marker() { + roundtrip! {FormatMarker | quote! {?} }; + roundtrip! {FormatMarker | quote! {%} }; + roundtrip! {FormatMarker | quote! {} }; + } + + #[test] + fn u_value_w_alias() { + roundtrip! {Value | quote! {x = y} }; + roundtrip! {Value | quote! {f = f} }; + roundtrip! {Value | quote! {ff = ?ff} }; + roundtrip! {Value | quote! {fff = %fff} }; + } + + #[test] + fn u_value_bare_w_format_marker() { + roundtrip! {Value | quote! {?q} }; + roundtrip! {Value | quote! {%etcpp} }; + + roundtrip! {ValueWithFormatMarker | quote! {?q} }; + roundtrip! {ValueWithFormatMarker | quote! {%etcpp} }; + } + + #[test] + fn u_value_bare_w_field_access() { + roundtrip! {ValueWithFormatMarker | quote! {a.b} }; + roundtrip! {ValueWithFormatMarker | quote! {a.b.cdef.ghij} }; + roundtrip! {ValueWithFormatMarker | quote! {?a.b.c} }; + } + + #[test] + fn u_args() { + roundtrip! {Args | quote! {target: "yes", k=?v, candidate_hash, "But why? {a}", a} }; + roundtrip! {Args | quote! {target: "also", candidate_hash = ?c_hash, "But why?"} }; + roundtrip! {Args | quote! {"Nope? {}", candidate_hash} }; + } + + #[test] + fn e2e() { + roundtrip! {Args | quote! {target: "yes", k=?v, candidate_hash, "But why? {a}", a} }; + roundtrip! {Args | quote! {target: "also", candidate_hash = ?c_hash, "But why?"} }; + roundtrip! {Args | quote! { "Nope? But yes {}", candidate_hash} }; + } + + #[test] + fn sample_w_candidate_hash_aliased() { + dbg!(impl_gum2( + quote! { + target: "bar", + a = a, + candidate_hash = %Hash::repeat_byte(0xF0), + b = ?Y::default(), + c = ?a, + "xxx" + }, + Level::Info + ) + .unwrap() + .to_string()); + } + + #[test] + fn sample_w_candidate_hash_aliased_unnecessary() { + assert_matches!(impl_gum2( + quote! { + "bar", + a = a, + candidate_hash = ?candidate_hash, + b = ?Y::default(), + c = ?a, + "xxx {} {}", + a, + a, + }, + Level::Info + ), Ok(x) => { + dbg!(x.to_string()) + }); + } + + #[test] + fn no_fmt_str_args() { + assert_matches!(impl_gum2( + quote! { + target: "bar", + a = a, + candidate_hash = ?candidate_hash, + b = ?Y::default(), + c = a, + "xxx", + }, + Level::Trace + ), Ok(x) => { + dbg!(x.to_string()) + }); + } + + #[test] + fn no_fmt_str() { + assert_matches!(impl_gum2( + quote! { + target: "bar", + a = a, + candidate_hash = ?candidate_hash, + b = ?Y::default(), + c = a, + }, + Level::Trace + ), Ok(x) => { + dbg!(x.to_string()) + }); + } + + #[test] + fn field_member_as_kv() { + assert_matches!(impl_gum2( + quote! { + target: "z", + ?y.x, + }, + Level::Info + ), Ok(x) => { + dbg!(x.to_string()) + }); + } + + #[test] + fn nested_field_member_as_kv() { + assert_matches!(impl_gum2( + quote! { + target: "z", + ?a.b.c.d.e.f.g, + }, + Level::Info + ), Ok(x) => { + dbg!(x.to_string()) + }); + } +} diff --git a/polkadot/node/gum/proc-macro/src/types.rs b/polkadot/node/gum/proc-macro/src/types.rs new file mode 100644 index 0000000000000000000000000000000000000000..635347a875e0001844936c4439d8ddd063be0449 --- /dev/null +++ b/polkadot/node/gum/proc-macro/src/types.rs @@ -0,0 +1,382 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use syn::{ + parse::{Parse, ParseStream}, + Token, +}; + +pub(crate) mod kw { + syn::custom_keyword!(target); + syn::custom_keyword!(freq); + syn::custom_keyword!(max_rate); +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) struct Target { + kw: kw::target, + colon: Token![:], + expr: syn::Expr, +} + +impl Parse for Target { + fn parse(input: ParseStream) -> Result { + Ok(Self { kw: input.parse()?, colon: input.parse()?, expr: input.parse()? }) + } +} + +impl ToTokens for Target { + fn to_tokens(&self, tokens: &mut TokenStream) { + let kw = &self.kw; + let colon = &self.colon; + let expr = &self.expr; + tokens.extend(quote! { + #kw #colon #expr + }) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum FormatMarker { + Questionmark(Token![?]), + Percentage(Token![%]), + None, +} + +impl Parse for FormatMarker { + fn parse(input: ParseStream) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(Token![?]) { + input.parse().map(Self::Questionmark) + } else if lookahead.peek(Token![%]) { + input.parse().map(Self::Percentage) + } else { + Ok(Self::None) + } + } +} + +impl ToTokens for FormatMarker { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.extend(match self { + Self::Percentage(p) => p.to_token_stream(), + Self::Questionmark(q) => q.to_token_stream(), + Self::None => TokenStream::new(), + }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) struct ValueWithAliasIdent { + pub alias: Ident, + pub eq: Token![=], + pub marker: FormatMarker, + pub expr: syn::Expr, +} + +impl Parse for ValueWithAliasIdent { + fn parse(input: ParseStream) -> Result { + Ok(Self { + alias: input.parse()?, + eq: input.parse()?, + marker: input.parse()?, + expr: input.parse()?, + }) + } +} + +impl ToTokens for ValueWithAliasIdent { + fn to_tokens(&self, tokens: &mut TokenStream) { + let alias = &self.alias; + let eq = &self.eq; + let marker = &self.marker; + let expr = &self.expr; + tokens.extend(quote! { + #alias #eq #marker #expr + }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] + +pub(crate) struct ValueWithFormatMarker { + pub marker: FormatMarker, + pub ident: Ident, + pub dot: Option, + pub inner: Punctuated, +} + +impl Parse for ValueWithFormatMarker { + fn parse(input: ParseStream) -> Result { + let marker = input.parse::()?; + let ident = input.parse::()?; + + let mut inner = Punctuated::::new(); + + let lookahead = input.lookahead1(); + let dot = if lookahead.peek(Token![.]) { + let dot = Some(input.parse::()?); + + loop { + let member = input.parse::()?; + inner.push_value(member); + + let lookahead = input.lookahead1(); + if !lookahead.peek(Token![.]) { + break + } + + let token = input.parse::()?; + inner.push_punct(token); + } + + dot + } else { + None + }; + Ok(Self { marker, ident, dot, inner }) + } +} + +impl ToTokens for ValueWithFormatMarker { + fn to_tokens(&self, tokens: &mut TokenStream) { + let marker = &self.marker; + let ident = &self.ident; + let dot = &self.dot; + let inner = &self.inner; + tokens.extend(quote! { + #marker #ident #dot #inner + }) + } +} + +/// A value as passed to the macro, appearing _before_ the format string. +#[derive(Debug, Clone, PartialEq, Eq)] + +pub(crate) enum Value { + Alias(ValueWithAliasIdent), + Value(ValueWithFormatMarker), +} + +impl Value { + pub fn as_ident(&self) -> &Ident { + match self { + Self::Alias(alias) => &alias.alias, + Self::Value(value) => &value.ident, + } + } +} + +impl Parse for Value { + fn parse(input: ParseStream) -> Result { + if input.fork().parse::().is_ok() { + input.parse().map(Self::Alias) + } else if input.fork().parse::().is_ok() { + input.parse().map(Self::Value) + } else { + Err(syn::Error::new(Span::call_site(), "Neither value nor aliased value.")) + } + } +} + +impl ToTokens for Value { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.extend(match self { + Self::Alias(alias) => quote! { #alias }, + Self::Value(value) => quote! { #value }, + }) + } +} + +/// Defines the token stream consisting of a format string and it's arguments. +/// +/// Attention: Currently the correctness of the arguments is not checked as part +/// of the parsing logic. +/// It would be possible to use `parse_fmt_str:2.0.0` +/// to do so and possibly improve the error message here - for the time being +/// it's not clear if this yields any practical benefits, and is hence +/// left for future consideration. +#[derive(Debug, Clone)] +pub(crate) struct FmtGroup { + pub format_str: syn::LitStr, + pub maybe_comma: Option, + pub rest: TokenStream, +} + +impl Parse for FmtGroup { + fn parse(input: ParseStream) -> Result { + let format_str = input + .parse() + .map_err(|e| syn::Error::new(e.span(), "Expected format specifier"))?; + + let (maybe_comma, rest) = if input.peek(Token![,]) { + let comma = input.parse::()?; + let rest = input.parse()?; + (Some(comma), rest) + } else { + (None, TokenStream::new()) + }; + + if !input.is_empty() { + return Err(syn::Error::new(input.span(), "Unexpected data, expected closing `)`.")) + } + + Ok(Self { format_str, maybe_comma, rest }) + } +} + +impl ToTokens for FmtGroup { + fn to_tokens(&self, tokens: &mut TokenStream) { + let format_str = &self.format_str; + let maybe_comma = &self.maybe_comma; + let rest = &self.rest; + + tokens.extend(quote! { #format_str #maybe_comma #rest }); + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) struct Freq { + kw: kw::freq, + colon: Token![:], + pub expr: syn::Expr, +} + +impl Parse for Freq { + fn parse(input: ParseStream) -> Result { + Ok(Self { kw: input.parse()?, colon: input.parse()?, expr: input.parse()? }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) struct MaxRate { + kw: kw::max_rate, + colon: Token![:], + pub expr: syn::Expr, +} + +impl Parse for MaxRate { + fn parse(input: ParseStream) -> Result { + Ok(Self { kw: input.parse()?, colon: input.parse()?, expr: input.parse()? }) + } +} + +pub(crate) struct ArgsIfFrequent { + pub freq: Freq, + pub max_rate: MaxRate, + pub rest: TokenStream, +} + +impl Parse for ArgsIfFrequent { + fn parse(input: ParseStream) -> Result { + let freq = input.parse()?; + let _: Token![,] = input.parse()?; + let max_rate = input.parse()?; + let _: Token![,] = input.parse()?; + let rest = input.parse()?; + + Ok(Self { freq, max_rate, rest }) + } +} + +/// Full set of arguments as provided to the `gum::warn!` call. +#[derive(Debug, Clone)] +pub(crate) struct Args { + pub target: Option, + pub comma: Option, + pub values: Punctuated, + pub fmt: Option, +} + +impl Parse for Args { + fn parse(input: ParseStream) -> Result { + let lookahead = input.lookahead1(); + let (target, comma) = if lookahead.peek(kw::target) { + let target = input.parse()?; + let comma = input.parse::()?; + (Some(target), Some(comma)) + } else { + (None, None) + }; + + let mut values = Punctuated::new(); + loop { + if input.fork().parse::().is_ok() { + values.push_value(input.parse::()?); + } else { + break + } + if input.peek(Token![,]) { + values.push_punct(input.parse::()?); + } else { + break + } + } + + let fmt = if values.empty_or_trailing() && !input.is_empty() { + let fmt = input.parse::()?; + Some(fmt) + } else { + None + }; + + Ok(Self { target, comma, values, fmt }) + } +} + +impl ToTokens for Args { + fn to_tokens(&self, tokens: &mut TokenStream) { + let target = &self.target; + let comma = &self.comma; + let values = &self.values; + let fmt = &self.fmt; + tokens.extend(quote! { + #target #comma #values #fmt + }) + } +} + +/// Support tracing levels, passed to `tracing::event!` +/// +/// Note: Not parsed from the input stream, but implicitly defined +/// by the macro name, i.e. `level::debug!` is `Level::Debug`. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum Level { + Error, + Warn, + Info, + Debug, + Trace, +} + +impl ToTokens for Level { + fn to_tokens(&self, tokens: &mut TokenStream) { + let span = Span::call_site(); + let variant = match self { + Self::Error => Ident::new("ERROR", span), + Self::Warn => Ident::new("WARN", span), + Self::Info => Ident::new("INFO", span), + Self::Debug => Ident::new("DEBUG", span), + Self::Trace => Ident::new("TRACE", span), + }; + let krate = support_crate(); + tokens.extend(quote! { + #krate :: Level :: #variant + }) + } +} diff --git a/polkadot/node/gum/src/lib.rs b/polkadot/node/gum/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..1cc4d8dec1cbf7ad477e50edf4f57ac92de3c894 --- /dev/null +++ b/polkadot/node/gum/src/lib.rs @@ -0,0 +1,194 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![deny(unused_crate_dependencies)] +#![deny(missing_docs)] +#![deny(clippy::dbg_macro)] + +//! A wrapper around `tracing` macros, to provide semi automatic +//! `traceID` annotation without codebase turnover. +//! +//! # Usage +//! +//! The API follows the [`tracing` +//! API](https://docs.rs/tracing/latest/tracing/index.html), but the docs contain +//! more detail than you probably need to know, so here's the quick version. +//! +//! Most common usage is of the form: +//! +//! ```rs +//! gum::warn!( +//! target: LOG_TARGET, +//! worker_pid = %idle_worker.pid, +//! ?error, +//! "failed to send a handshake to the spawned worker", +//! ); +//! ``` +//! +//! ### Log levels +//! +//! All of the the [`tracing` macros](https://docs.rs/tracing/latest/tracing/index.html#macros) are available. +//! In decreasing order of priority they are: +//! +//! - `error!` +//! - `warn!` +//! - `info!` +//! - `debug!` +//! - `trace!` +//! +//! ### `target` +//! +//! The `LOG_TARGET` should be defined once per crate, e.g.: +//! +//! ```rs +//! const LOG_TARGET: &str = "parachain::pvf"; +//! ``` +//! +//! This should be of the form `::`, where the `::` is optional. +//! +//! The target and subtarget are used when debugging by specializing the Grafana Loki query to +//! filter specific subsystem logs. The more specific the query is the better when approaching the +//! query response limit. +//! +//! ### Fields +//! +//! Here's the rundown on how fields work: +//! +//! - Fields on spans and events are specified using the `syntax field_name = field_value`. +//! - Local variables may be used as field values without an assignment, similar to struct +//! initializers. +//! - The `?` sigil is shorthand that specifies a field should be recorded using its `fmt::Debug` +//! implementation. +//! - The `%` sigil operates similarly, but indicates that the value should be recorded using its +//! `fmt::Display` implementation. +//! +//! For full details, again see [the tracing +//! docs](https://docs.rs/tracing/latest/tracing/index.html#recording-fields). +//! +//! ### Viewing traces +//! +//! When testing, +//! +//! ```rs +//! sp_tracing::init_for_tests(); +//! ``` +//! +//! should enable all trace logs. +//! +//! Alternatively, you can do: +//! +//! ```rs +//! sp_tracing::try_init_simple(); +//! ``` +//! +//! On the command line you specify `RUST_LOG` with the desired target and trace level: +//! +//! ```sh +//! RUST_LOG=parachain::pvf=trace cargo test +//! ``` +//! +//! On the other hand if you want all `parachain` logs, specify `parachain=trace`, which will also +//! include logs from `parachain::pvf` and other subtargets. + +pub use tracing::{enabled, event, Level}; + +#[doc(hidden)] +pub use jaeger::hash_to_trace_identifier; + +#[doc(hidden)] +pub use polkadot_primitives::{CandidateHash, Hash}; + +pub use gum_proc_macro::{debug, error, info, trace, warn, warn_if_frequent}; + +#[cfg(test)] +mod tests; + +const FREQ_SMOOTHING_FACTOR: f32 = 0.5; + +/// Exponential moving average +#[derive(Debug, Default)] +struct EmaBucket { + current: f32, + count: u32, +} + +impl EmaBucket { + fn update(&mut self, value: f32, alpha: f32) { + if self.count == 0 { + self.current = value; + } else { + self.current += alpha * (value - self.current); + } + self.count += 1; + } +} + +/// Utility struct to compare the rate of its own calls. +pub struct Freq { + ema: EmaBucket, + last: u64, +} + +impl Freq { + /// Initiates a new instance + pub fn new() -> Self { + Self { ema: Default::default(), last: Default::default() } + } + + /// Compares the rate of its own calls with the passed one. + pub fn is_frequent(&mut self, max_rate: Times) -> bool { + self.record(); + + // Two attempts is not enough to call something as frequent. + if self.ema.count < 3 { + return false + } + + let rate = 1000.0 / self.ema.current; // Current EMA represents interval in ms + rate > max_rate.into() + } + + fn record(&mut self) { + let now = coarsetime::Clock::now_since_epoch().as_millis() as u64; + if self.last > 0 { + self.ema.update((now - self.last) as f32, FREQ_SMOOTHING_FACTOR); + } + self.last = now; + } +} + +/// Represents frequency per second, minute, hour and day +pub enum Times { + /// Per second + PerSecond(u32), + /// Per minute + PerMinute(u32), + /// Per hour + PerHour(u32), + /// Per day + PerDay(u32), +} + +impl From for f32 { + fn from(value: Times) -> Self { + match value { + Times::PerSecond(v) => v as f32, + Times::PerMinute(v) => v as f32 / 60.0, + Times::PerHour(v) => v as f32 / (60.0 * 60.0), + Times::PerDay(v) => v as f32 / (60.0 * 60.0 * 24.0), + } + } +} diff --git a/polkadot/node/gum/src/tests.rs b/polkadot/node/gum/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..3883239d62cd491b130c54785fe95f7e362069c2 --- /dev/null +++ b/polkadot/node/gum/src/tests.rs @@ -0,0 +1,166 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +pub use polkadot_primitives::{CandidateHash, Hash}; + +#[derive(Default, Debug)] +struct Y { + #[allow(dead_code)] + x: u8, +} + +#[test] +fn plain() { + error!("plain"); +} + +#[test] +fn wo_alias() { + let a: i32 = 7; + error!(target: "foo", + "Something something {}, {b:?}, or maybe {c}", + a, + b = Y::default(), + c = a + ); +} + +#[test] +fn wo_unnecessary() { + let a: i32 = 7; + warn!(target: "bar", + a = a, + b = ?Y::default(), + "fff {c}", + c = a, + ); +} + +#[test] +fn if_frequent() { + let a: i32 = 7; + let mut f = Freq::new(); + warn_if_frequent!( + freq: f, + max_rate: Times::PerSecond(1), + target: "bar", + a = a, + b = ?Y::default(), + "fff {c}", + c = a, + ); +} + +#[test] +fn w_candidate_hash_value_assignment() { + let a: i32 = 7; + info!(target: "bar", + a = a, + // ad-hoc value + candidate_hash = %CandidateHash(Hash::repeat_byte(0xF0)), + b = ?Y::default(), + c = ?a, + "xxx", + ); +} + +#[test] +fn w_candidate_hash_from_scope() { + let a: i32 = 7; + let candidate_hash = CandidateHash(Hash::repeat_byte(0xF1)); + debug!(target: "bar", + a = a, + ?candidate_hash, + b = ?Y::default(), + c = ?a, + "xxx", + ); +} + +#[test] +fn w_candidate_hash_aliased() { + let a: i32 = 7; + let c_hash = Hash::repeat_byte(0xFA); + trace!(target: "bar", + a = a, + candidate_hash = ?c_hash, + b = ?Y::default(), + c = a, + "xxx", + ); +} + +#[test] +fn w_candidate_hash_aliased_unnecessary() { + let a: i32 = 7; + let candidate_hash = CandidateHash(Hash::repeat_byte(0xFA)); + info!( + target: "bar", + a = a, + candidate_hash = ?candidate_hash, + b = ?Y::default(), + c = a, + "xxx", + ); +} + +#[test] +fn frequent_at_fourth_time() { + let mut freq = Freq::new(); + + assert!(!freq.is_frequent(Times::PerSecond(1))); + assert!(!freq.is_frequent(Times::PerSecond(1))); + assert!(!freq.is_frequent(Times::PerSecond(1))); + + assert!(freq.is_frequent(Times::PerSecond(1))); +} + +#[test] +fn not_frequent_at_fourth_time_if_slow() { + let mut freq = Freq::new(); + + assert!(!freq.is_frequent(Times::PerSecond(1000))); + assert!(!freq.is_frequent(Times::PerSecond(1000))); + assert!(!freq.is_frequent(Times::PerSecond(1000))); + + std::thread::sleep(std::time::Duration::from_millis(10)); + assert!(!freq.is_frequent(Times::PerSecond(1000))); +} + +#[test] +fn calculate_rate_per_second() { + let rate: f32 = Times::PerSecond(100).into(); + assert_eq!(rate, 100.0) +} + +#[test] +fn calculate_rate_per_minute() { + let rate: f32 = Times::PerMinute(100).into(); + assert_eq!(rate, 1.6666666) +} + +#[test] +fn calculate_rate_per_hour() { + let rate: f32 = Times::PerHour(100).into(); + assert_eq!(rate, 0.027777778) +} + +#[test] +fn calculate_rate_per_day() { + let rate: f32 = Times::PerDay(100).into(); + assert_eq!(rate, 0.0011574074) +} diff --git a/polkadot/node/jaeger/Cargo.toml b/polkadot/node/jaeger/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..b563b33842b56583b9728a9b201a1d5e52dc9998 --- /dev/null +++ b/polkadot/node/jaeger/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "polkadot-node-jaeger" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +description = "Polkadot Jaeger primitives, but equally useful for Grafana/Tempo" + +[dependencies] +mick-jaeger = "0.1.8" +lazy_static = "1.4" +parking_lot = "0.12.0" +polkadot-primitives = { path = "../../primitives" } +polkadot-node-primitives = { path = "../primitives" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +thiserror = "1.0.31" +tokio = "1.24.2" +log = "0.4.17" +parity-scale-codec = { version = "3.6.1", default-features = false } diff --git a/polkadot/node/jaeger/src/config.rs b/polkadot/node/jaeger/src/config.rs new file mode 100644 index 0000000000000000000000000000000000000000..702a22e1245c8ecb628d11c95b879bc5bf88db7e --- /dev/null +++ b/polkadot/node/jaeger/src/config.rs @@ -0,0 +1,73 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot Jaeger configuration. + +/// Configuration for the jaeger tracing. +#[derive(Clone)] +pub struct JaegerConfig { + pub(crate) node_name: String, + pub(crate) agent_addr: std::net::SocketAddr, +} + +impl std::default::Default for JaegerConfig { + fn default() -> Self { + Self { + node_name: "unknown_".to_owned(), + agent_addr: "127.0.0.1:6831" + .parse() + .expect(r#"Static "127.0.0.1:6831" is a valid socket address string. qed"#), + } + } +} + +impl JaegerConfig { + /// Use the builder pattern to construct a configuration. + pub fn builder() -> JaegerConfigBuilder { + JaegerConfigBuilder::default() + } +} + +/// Jaeger configuration builder. +#[derive(Default)] +pub struct JaegerConfigBuilder { + inner: JaegerConfig, +} + +impl JaegerConfigBuilder { + /// Set the name for this node. + pub fn named(mut self, name: S) -> Self + where + S: AsRef, + { + self.inner.node_name = name.as_ref().to_owned(); + self + } + + /// Set the agent address to send the collected spans to. + pub fn agent(mut self, addr: U) -> Self + where + U: Into, + { + self.inner.agent_addr = addr.into(); + self + } + + /// Construct the configuration. + pub fn build(self) -> JaegerConfig { + self.inner + } +} diff --git a/polkadot/node/jaeger/src/errors.rs b/polkadot/node/jaeger/src/errors.rs new file mode 100644 index 0000000000000000000000000000000000000000..adedda34c7fc46ec6303b65bbfa328e1a960967f --- /dev/null +++ b/polkadot/node/jaeger/src/errors.rs @@ -0,0 +1,28 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot Jaeger error definitions. + +/// A description of an error during jaeger initialization. +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum JaegerError { + #[error("Already launched the collector thread")] + AlreadyLaunched, + + #[error("Missing jaeger configuration")] + MissingConfiguration, +} diff --git a/polkadot/node/jaeger/src/lib.rs b/polkadot/node/jaeger/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..7de4586068166f28a1d69d1787d2a960d298cf92 --- /dev/null +++ b/polkadot/node/jaeger/src/lib.rs @@ -0,0 +1,168 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot Jaeger related primitives +//! +//! Provides primitives used by Polkadot for interfacing with Jaeger. +//! +//! # Integration +//! +//! See for an introduction. +//! +//! The easiest way to try Jaeger is: +//! +//! - Start a docker container with the all-in-one docker image (see below). +//! - Open your browser and navigate to to access the UI. +//! +//! The all-in-one image can be started with: +//! +//! ```not_rust +//! podman login docker.io +//! podman run -d --name jaeger \ +//! -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \ +//! -p 5775:5775/udp \ +//! -p 6831:6831/udp \ +//! -p 6832:6832/udp \ +//! -p 5778:5778 \ +//! -p 16686:16686 \ +//! -p 14268:14268 \ +//! -p 14250:14250 \ +//! -p 9411:9411 \ +//! docker.io/jaegertracing/all-in-one:1.21 +//! ``` + +#![forbid(unused_imports)] + +mod config; +mod errors; +mod spans; + +pub use self::{ + config::{JaegerConfig, JaegerConfigBuilder}, + errors::JaegerError, + spans::{hash_to_trace_identifier, PerLeafSpan, Span, Stage}, +}; + +use self::spans::TraceIdentifier; + +use sp_core::traits::SpawnNamed; + +use parking_lot::RwLock; +use std::{result, sync::Arc}; + +lazy_static::lazy_static! { + static ref INSTANCE: RwLock = RwLock::new(Jaeger::None); +} + +/// Stateful convenience wrapper around [`mick_jaeger`]. +pub enum Jaeger { + /// Launched and operational state. + Launched { + /// [`mick_jaeger`] provided API to record spans to. + traces_in: Arc, + }, + /// Preparation state with the necessary config to launch the collector. + Prep(JaegerConfig), + /// Uninitialized, suggests wrong API usage if encountered. + None, +} + +impl Jaeger { + /// Spawn the jaeger instance. + pub fn new(cfg: JaegerConfig) -> Self { + Jaeger::Prep(cfg) + } + + /// Spawn the background task in order to send the tracing information out via UDP + #[cfg(target_os = "unknown")] + pub fn launch(self, _spawner: S) -> result::Result<(), JaegerError> { + Ok(()) + } + + /// Provide a no-thrills test setup helper. + #[cfg(test)] + pub fn test_setup() { + let mut instance = INSTANCE.write(); + match *instance { + Self::Launched { .. } => {}, + _ => { + let (traces_in, _traces_out) = mick_jaeger::init(mick_jaeger::Config { + service_name: "polkadot-jaeger-test".to_owned(), + }); + *instance = Self::Launched { traces_in }; + }, + } + } + + /// Spawn the background task in order to send the tracing information out via UDP + #[cfg(not(target_os = "unknown"))] + pub fn launch(self, spawner: S) -> result::Result<(), JaegerError> { + let cfg = match self { + Self::Prep(cfg) => Ok(cfg), + Self::Launched { .. } => return Err(JaegerError::AlreadyLaunched), + Self::None => Err(JaegerError::MissingConfiguration), + }?; + + let jaeger_agent = cfg.agent_addr; + + log::info!("🐹 Collecting jaeger spans for {:?}", &jaeger_agent); + + let (traces_in, mut traces_out) = mick_jaeger::init(mick_jaeger::Config { + service_name: format!("polkadot-{}", cfg.node_name), + }); + + // Spawn a background task that pulls span information and sends them on the network. + spawner.spawn( + "jaeger-collector", + Some("jaeger"), + Box::pin(async move { + match tokio::net::UdpSocket::bind("0.0.0.0:0").await { + Ok(udp_socket) => loop { + let buf = traces_out.next().await; + // UDP sending errors happen only either if the API is misused or in case of + // missing privilege. + if let Err(e) = udp_socket.send_to(&buf, jaeger_agent).await { + log::debug!(target: "jaeger", "UDP send error: {}", e); + } + }, + Err(e) => { + log::warn!(target: "jaeger", "UDP socket open error: {}", e); + }, + } + }), + ); + + *INSTANCE.write() = Self::Launched { traces_in }; + Ok(()) + } + + /// Create a span, but defer the evaluation/transformation into a `TraceIdentifier`. + /// + /// The deferral allows to avoid the additional CPU runtime cost in case of + /// items that are not a pre-computed hash by themselves. + pub(crate) fn span(&self, lazy_hash: F, span_name: &'static str) -> Option + where + F: Fn() -> TraceIdentifier, + { + if let Self::Launched { traces_in, .. } = self { + let ident = lazy_hash(); + let trace_id = std::num::NonZeroU128::new(ident)?; + Some(traces_in.span(trace_id, span_name)) + } else { + None + } + } +} diff --git a/polkadot/node/jaeger/src/spans.rs b/polkadot/node/jaeger/src/spans.rs new file mode 100644 index 0000000000000000000000000000000000000000..4038d41344f2db09908fc50c82ddd787d374f505 --- /dev/null +++ b/polkadot/node/jaeger/src/spans.rs @@ -0,0 +1,518 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot Jaeger span definitions. +//! +//! ```rust +//! # use polkadot_primitives::{CandidateHash, Hash}; +//! # fn main() { +//! use polkadot_node_jaeger as jaeger; +//! +//! let relay_parent = Hash::default(); +//! let candidate = CandidateHash::default(); +//! +//! #[derive(Debug, Default)] +//! struct Foo { +//! a: u8, +//! b: u16, +//! c: u32, +//! }; +//! +//! let foo = Foo::default(); +//! +//! let span = +//! jaeger::Span::new(relay_parent, "root_of_aaall_spans") +//! // explicit well defined items +//! .with_candidate(candidate) +//! // anything that implements `trait std::fmt::Debug` +//! .with_string_fmt_debug_tag("foo", foo) +//! // anything that implements `trait std::str::ToString` +//! .with_string_tag("again", 1337_u32) +//! // add a `Stage` for [`dot-jaeger`](https://github.com/paritytech/dot-jaeger) +//! .with_stage(jaeger::Stage::CandidateBacking); +//! // complete by design, no completion required +//! # } +//! ``` +//! +//! In a few cases additional annotations might want to be added +//! over the course of a function, for this purpose use the non-consuming +//! `fn` variants, i.e. +//! ```rust +//! # use polkadot_primitives::{CandidateHash, Hash}; +//! # fn main() { +//! # use polkadot_node_jaeger as jaeger; +//! +//! # let relay_parent = Hash::default(); +//! # let candidate = CandidateHash::default(); +//! +//! # #[derive(Debug, Default)] +//! # struct Foo { +//! # a: u8, +//! # b: u16, +//! # c: u32, +//! # }; +//! # +//! # let foo = Foo::default(); +//! +//! let root_span = +//! jaeger::Span::new(relay_parent, "root_of_aaall_spans"); +//! +//! // the prefered way of adding additional delayed information: +//! let span = root_span.child("inner"); +//! +//! // ... more operations ... +//! +//! // but this is also possible: +//! +//! let mut root_span = root_span; +//! root_span.add_string_fmt_debug_tag("foo_constructed", &foo); +//! root_span.add_string_tag("bar", true); +//! # } +//! ``` + +use parity_scale_codec::Encode; +use polkadot_node_primitives::PoV; +use polkadot_primitives::{BlakeTwo256, CandidateHash, Hash, HashT, Id as ParaId, ValidatorIndex}; +use sc_network::PeerId; + +use std::{fmt, sync::Arc}; + +use super::INSTANCE; + +/// A special "per leaf span". +/// +/// Essentially this span wraps two spans: +/// +/// 1. The span that is created per leaf in the overseer. +/// 2. Some child span of the per-leaf span. +/// +/// This just works as auxiliary structure to easily store both. +#[derive(Debug)] +pub struct PerLeafSpan { + leaf_span: Arc, + span: Span, +} + +impl PerLeafSpan { + /// Creates a new instance. + /// + /// Takes the `leaf_span` that is created by the overseer per leaf and a name for a child span. + /// Both will be stored in this object, while the child span is implicitly accessible by using + /// the [`Deref`](std::ops::Deref) implementation. + pub fn new(leaf_span: Arc, name: &'static str) -> Self { + let span = leaf_span.child(name); + + Self { span, leaf_span } + } + + /// Returns the leaf span. + pub fn leaf_span(&self) -> &Arc { + &self.leaf_span + } +} + +/// Returns a reference to the child span. +impl std::ops::Deref for PerLeafSpan { + type Target = Span; + + fn deref(&self) -> &Span { + &self.span + } +} + +/// A helper to annotate the stage with a numerical value +/// to ease the life of the tooling team creating viable +/// statistical metrics for which stage of the inclusion +/// pipeline drops a significant amount of candidates, +/// statistically speaking. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u8)] +#[non_exhaustive] +pub enum Stage { + CandidateBacking = 2, + StatementDistribution = 3, + PoVDistribution = 4, + AvailabilityDistribution = 5, + AvailabilityRecovery = 6, + BitfieldDistribution = 7, + ApprovalChecking = 8, + ApprovalDistribution = 9, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + // in [the path of a para chain block] + // (https://polkadot.network/the-path-of-a-parachain-block/) + // see [issue](https://github.com/paritytech/polkadot/issues/2389) +} + +/// A wrapper type for a span. +/// +/// Handles running with and without jaeger. +pub enum Span { + /// Running with jaeger being enabled. + Enabled(mick_jaeger::Span), + /// Running with jaeger disabled. + Disabled, +} + +/// Alias for the 16 byte unique identifier used with jaeger. +pub(crate) type TraceIdentifier = u128; + +/// A helper to convert the hash to the fixed size representation +/// needed for jaeger. +#[inline] +pub fn hash_to_trace_identifier(hash: Hash) -> TraceIdentifier { + let mut buf = [0u8; 16]; + buf.copy_from_slice(&hash.as_ref()[0..16]); + // The slice bytes are copied in reading order, so if interpreted + // in string form by a human, that means lower indices have higher + // values and hence corresponds to BIG endian ordering of the individual + // bytes. + u128::from_be_bytes(buf) as TraceIdentifier +} + +/// Helper to unify lazy proxy evaluation. +pub trait LazyIdent { + /// Evaluate the type to a unique trace identifier. + /// Called lazily on demand. + fn eval(&self) -> TraceIdentifier; + + /// Annotate a new root item with these additional spans + /// at construction. + fn extra_tags(&self, _span: &mut Span) {} +} + +impl<'a> LazyIdent for &'a [u8] { + fn eval(&self) -> TraceIdentifier { + hash_to_trace_identifier(BlakeTwo256::hash_of(self)) + } +} + +impl LazyIdent for &PoV { + fn eval(&self) -> TraceIdentifier { + hash_to_trace_identifier(self.hash()) + } + + fn extra_tags(&self, span: &mut Span) { + span.add_pov(self) + } +} + +impl LazyIdent for Hash { + fn eval(&self) -> TraceIdentifier { + hash_to_trace_identifier(*self) + } + + fn extra_tags(&self, span: &mut Span) { + span.add_string_fmt_debug_tag("relay-parent", self); + } +} + +impl LazyIdent for &Hash { + fn eval(&self) -> TraceIdentifier { + hash_to_trace_identifier(**self) + } + + fn extra_tags(&self, span: &mut Span) { + span.add_string_fmt_debug_tag("relay-parent", self); + } +} + +impl LazyIdent for CandidateHash { + fn eval(&self) -> TraceIdentifier { + hash_to_trace_identifier(self.0) + } + + fn extra_tags(&self, span: &mut Span) { + span.add_string_fmt_debug_tag("candidate-hash", &self.0); + // A convenience for usage with the grafana tempo UI, + // not a technical requirement. It merely provides an easy anchor + // where the true trace identifier of the span is not based on + // a candidate hash (which it should be!), but is required to + // continue investigating. + span.add_string_tag("traceID", self.eval().to_string()); + } +} + +impl Span { + /// Creates a new span builder based on anything that can be lazily evaluated + /// to and identifier. + /// + /// Attention: The primary identifier will be used for identification + /// and as such should be + pub fn new(identifier: I, span_name: &'static str) -> Span { + let mut span = INSTANCE + .read_recursive() + .span(|| ::eval(&identifier), span_name) + .into(); + ::extra_tags(&identifier, &mut span); + span + } + + /// Creates a new span builder based on an encodable type. + /// The encoded bytes are then used to derive the true trace identifier. + pub fn from_encodable(identifier: I, span_name: &'static str) -> Span { + INSTANCE + .read_recursive() + .span( + move || { + let bytes = identifier.encode(); + LazyIdent::eval(&bytes.as_slice()) + }, + span_name, + ) + .into() + } + + /// Derive a child span from `self`. + pub fn child(&self, name: &str) -> Self { + match self { + Self::Enabled(inner) => Self::Enabled(inner.child(name)), + Self::Disabled => Self::Disabled, + } + } + + /// Attach a 'traceID' tag set to the decimal representation of the candidate hash. + #[inline(always)] + pub fn with_trace_id(mut self, candidate_hash: CandidateHash) -> Self { + self.add_string_tag("traceID", hash_to_trace_identifier(candidate_hash.0)); + self + } + + #[inline(always)] + pub fn with_string_tag(mut self, tag: &'static str, val: V) -> Self { + self.add_string_tag::(tag, val); + self + } + + /// Attach a peer-id tag to the span. + #[inline(always)] + pub fn with_peer_id(self, peer: &PeerId) -> Self { + self.with_string_tag("peer-id", &peer.to_base58()) + } + + /// Attach a `peer-id` tag to the span when peer is present. + #[inline(always)] + pub fn with_optional_peer_id(self, peer: Option<&PeerId>) -> Self { + if let Some(peer) = peer { + self.with_peer_id(peer) + } else { + self + } + } + + /// Attach a candidate hash to the span. + #[inline(always)] + pub fn with_candidate(self, candidate_hash: CandidateHash) -> Self { + self.with_string_fmt_debug_tag("candidate-hash", &candidate_hash.0) + } + + /// Attach a para-id to the span. + #[inline(always)] + pub fn with_para_id(self, para_id: ParaId) -> Self { + self.with_int_tag("para-id", u32::from(para_id) as i64) + } + + /// Attach a candidate stage. + /// Should always come with a `CandidateHash`. + #[inline(always)] + pub fn with_stage(self, stage: Stage) -> Self { + self.with_string_tag("candidate-stage", stage as u8) + } + + #[inline(always)] + pub fn with_validator_index(self, validator: ValidatorIndex) -> Self { + self.with_string_tag("validator-index", &validator.0) + } + + #[inline(always)] + pub fn with_chunk_index(self, chunk_index: u32) -> Self { + self.with_string_tag("chunk-index", chunk_index) + } + + #[inline(always)] + pub fn with_relay_parent(self, relay_parent: Hash) -> Self { + self.with_string_fmt_debug_tag("relay-parent", relay_parent) + } + + #[inline(always)] + pub fn with_claimed_validator_index(self, claimed_validator_index: ValidatorIndex) -> Self { + self.with_string_tag("claimed-validator", &claimed_validator_index.0) + } + + #[inline(always)] + pub fn with_pov(mut self, pov: &PoV) -> Self { + self.add_pov(pov); + self + } + + /// Add an additional int tag to the span without consuming. + /// + /// Should be used sparingly, introduction of new types is preferred. + #[inline(always)] + pub fn with_int_tag(mut self, tag: &'static str, i: i64) -> Self { + self.add_int_tag(tag, i); + self + } + + #[inline(always)] + pub fn with_uint_tag(mut self, tag: &'static str, u: u64) -> Self { + self.add_uint_tag(tag, u); + self + } + + #[inline(always)] + pub fn with_string_fmt_debug_tag(mut self, tag: &'static str, val: V) -> Self { + self.add_string_tag(tag, format!("{:?}", val)); + self + } + + /// Adds the `FollowsFrom` relationship to this span with respect to the given one. + #[inline(always)] + pub fn add_follows_from(&mut self, other: &Self) { + match (self, other) { + (Self::Enabled(ref mut inner), Self::Enabled(ref other_inner)) => + inner.add_follows_from(&other_inner), + _ => {}, + } + } + + /// Add a PoV hash meta tag with lazy hash evaluation, without consuming the span. + #[inline(always)] + pub fn add_pov(&mut self, pov: &PoV) { + if self.is_enabled() { + // avoid computing the PoV hash if jaeger is not enabled + self.add_string_fmt_debug_tag("pov", pov.hash()); + } + } + + #[inline(always)] + pub fn add_para_id(&mut self, para_id: ParaId) { + self.add_int_tag("para-id", u32::from(para_id) as i64); + } + + /// Add a string tag, without consuming the span. + pub fn add_string_tag(&mut self, tag: &'static str, val: V) { + match self { + Self::Enabled(ref mut inner) => inner.add_string_tag(tag, val.to_string().as_str()), + Self::Disabled => {}, + } + } + + /// Add a string tag, without consuming the span. + pub fn add_string_fmt_debug_tag(&mut self, tag: &'static str, val: V) { + match self { + Self::Enabled(ref mut inner) => + inner.add_string_tag(tag, format!("{:?}", val).as_str()), + Self::Disabled => {}, + } + } + + pub fn add_int_tag(&mut self, tag: &'static str, value: i64) { + match self { + Self::Enabled(ref mut inner) => inner.add_int_tag(tag, value), + Self::Disabled => {}, + } + } + + pub fn add_uint_tag(&mut self, tag: &'static str, value: u64) { + match self { + Self::Enabled(ref mut inner) => inner.add_int_tag(tag, value as i64), + Self::Disabled => {}, + } + } + + /// Check whether jaeger is enabled + /// in order to avoid computational overhead. + pub const fn is_enabled(&self) -> bool { + match self { + Span::Enabled(_) => true, + _ => false, + } + } + + /// Obtain the trace identifier for this set of spans. + pub fn trace_id(&self) -> Option { + match self { + Span::Enabled(inner) => Some(inner.trace_id().get()), + _ => None, + } + } +} + +impl std::fmt::Debug for Span { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "") + } +} + +impl From> for Span { + fn from(src: Option) -> Self { + if let Some(span) = src { + Self::Enabled(span) + } else { + Self::Disabled + } + } +} + +impl From for Span { + fn from(src: mick_jaeger::Span) -> Self { + Self::Enabled(src) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::Jaeger; + + // make sure to not use `::repeat_*()` based samples, since this does not verify endianness + const RAW: [u8; 32] = [ + 0xFF, 0xAA, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x78, 0x89, 0x9A, 0xAB, 0xBC, 0xCD, 0xDE, + 0xEF, 0x00, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0E, 0x0F, + ]; + + #[test] + fn hash_derived_identifier_is_leading_16bytes() { + let candidate_hash = dbg!(Hash::from(&RAW)); + let trace_id = dbg!(hash_to_trace_identifier(candidate_hash)); + for (idx, (a, b)) in candidate_hash + .as_bytes() + .iter() + .take(16) + .zip(trace_id.to_be_bytes().iter()) + .enumerate() + { + assert_eq!(*a, *b, "Index [{}] does not match: {} != {}", idx, a, b); + } + } + + #[test] + fn extra_tags_do_not_change_trace_id() { + Jaeger::test_setup(); + let candidate_hash = dbg!(Hash::from(&RAW)); + let trace_id = hash_to_trace_identifier(candidate_hash); + + let span = Span::new(candidate_hash, "foo"); + + assert_eq!(span.trace_id(), Some(trace_id)); + + let span = span.with_int_tag("tag", 7i64); + + assert_eq!(span.trace_id(), Some(trace_id)); + } +} diff --git a/polkadot/node/malus/Cargo.toml b/polkadot/node/malus/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..0c99881595165dbb2604fafd13bc498c9b3579dc --- /dev/null +++ b/polkadot/node/malus/Cargo.toml @@ -0,0 +1,65 @@ +[package] +name = "polkadot-test-malus" +description = "Misbehaving nodes for local testnets, system and Simnet tests." +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +readme = "README.md" +publish = false + +[[bin]] +name = "malus" +path = "src/malus.rs" + +# Use artifact dependencies once stable. +# See https://github.com/rust-lang/cargo/issues/9096. +[[bin]] +name = "polkadot-execute-worker" +path = "../../src/bin/execute-worker.rs" +# Prevent rustdoc error. Already documented from top-level Cargo.toml. +doc = false +[[bin]] +name = "polkadot-prepare-worker" +path = "../../src/bin/prepare-worker.rs" +# Prevent rustdoc error. Already documented from top-level Cargo.toml. +doc = false + +[dependencies] +polkadot-cli = { path = "../../cli", features = [ "malus", "rococo-native", "kusama-native", "westend-native", "polkadot-native" ] } +polkadot-node-subsystem = { path = "../subsystem" } +polkadot-node-subsystem-util = { path = "../subsystem-util" } +polkadot-node-subsystem-types = { path = "../subsystem-types" } +polkadot-node-core-dispute-coordinator = { path = "../core/dispute-coordinator" } +polkadot-node-core-candidate-validation = { path = "../core/candidate-validation" } +polkadot-node-core-backing = { path = "../core/backing" } +polkadot-node-primitives = { path = "../primitives" } +polkadot-primitives = { path = "../../primitives" } +color-eyre = { version = "0.6.1", default-features = false } +assert_matches = "1.5" +async-trait = "0.1.57" +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +clap = { version = "4.0.9", features = ["derive"] } +futures = "0.3.21" +futures-timer = "3.0.2" +gum = { package = "tracing-gum", path = "../gum/" } +erasure = { package = "polkadot-erasure-coding", path = "../../erasure-coding" } +rand = "0.8.5" + +# Required for worker binaries to build. +polkadot-node-core-pvf-common = { path = "../core/pvf/common", features = ["test-utils"] } +polkadot-node-core-pvf-execute-worker = { path = "../core/pvf/execute-worker" } +polkadot-node-core-pvf-prepare-worker = { path = "../core/pvf/prepare-worker" } + +[dev-dependencies] +polkadot-node-subsystem-test-helpers = { path = "../subsystem-test-helpers" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures = { version = "0.3.21", features = ["thread-pool"] } + +[build-dependencies] +substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = [] +fast-runtime = ["polkadot-cli/fast-runtime"] diff --git a/polkadot/node/malus/README.md b/polkadot/node/malus/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fb4bb0cd272fa7b89db995ebaaefa41f6a1ac37c --- /dev/null +++ b/polkadot/node/malus/README.md @@ -0,0 +1,59 @@ +# malus + +Create nemesis nodes with alternate, at best faulty, at worst intentionally destructive behavior traits. + +The first argument determines the behavior strain. The currently supported are: + +* `suggest-garbage-candidate` +* `back-garbage-candidate` +* `dispute-ancestor` + +## Integration test cases + +To define integration tests create file +in the toml format as used with [zombienet][zombienet] +under `./integrationtests` describing the network to spawn and +also the `zndsl` file (with `.zndsl` extension ) using the format +defined in the [(DSL[(**D**omain **S**pecific **L**anguage)]) doc](https://paritytech.github.io/zombienet/cli/test-dsl-definition-spec.html). + +## Usage + +> Assumes you already gained permissiones, ping in element @javier:matrix.parity.io to get access. +> and you have cloned the [zombienet][zombienet] repo. + +To launch a test case in the development cluster use (e.g. for the ./node/malus/integrationtests/0001-dispute-valid-block.toml): + +```sh +# declare the containers pulled in by zombie-net test definitions +export MALUS_IMAGE=docker.io/paritypr/malus:4131-ccd09bbf +export ZOMBIENET_INTEGRATION_TEST_IMAGE=docker.io/paritypr/synth-wave:4131-0.9.12-ccd09bbf-29a1ac18 +export COL_IMAGE=docker.io/paritypr/colander:4131-ccd09bbf + +# login chore, once, with the values as provided in the above guide +gcloud auth login +gcloud config set project "parity-zombienet" +gcloud container clusters get-credentials "parity-zombienet" --zone "europe-west3-b" --project parity-zombienet + +# launching the actual test +cd zombienet +npm run build +node dist/cli.js test /node/malus/integrationtests/0001-dispute-valid-block.zndsl + +# Access logs (in google cloud storage) +gsutil ls gs://zombienet-logs/zombie-/logs/ +``` + +This will also teardown the namespace after completion. + +## Container Image Building Note + +In order to build the container image you need to have the latest changes from +polkadot and substrate master branches. + +```sh +pwd # run this from the current dir +podman build -t paritypr/malus:v1 -f Containerfile ../../.. +``` + +[zombienet]: https://github.com/paritytech/zombienet +[gke]: (https://github.com/paritytech/gurke/blob/main/docs/How-to-setup-access-to-gke-k8s-cluster.md) diff --git a/polkadot/node/malus/build.rs b/polkadot/node/malus/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..84fe22e23ed6f1a2e1d68a0194c41d23eb75b76c --- /dev/null +++ b/polkadot/node/malus/build.rs @@ -0,0 +1,22 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +fn main() { + substrate_build_script_utils::generate_cargo_keys(); + // For the node/worker version check, make sure we always rebuild the node and binary workers + // when the version changes. + substrate_build_script_utils::rerun_if_git_head_changed(); +} diff --git a/polkadot/node/malus/container/Containerfile-cargo-chef b/polkadot/node/malus/container/Containerfile-cargo-chef new file mode 100644 index 0000000000000000000000000000000000000000..65fd1d1ae27e8fadd82ac155c35ab0d8dd72ef61 --- /dev/null +++ b/polkadot/node/malus/container/Containerfile-cargo-chef @@ -0,0 +1,155 @@ +# +### Builder stage +# + +FROM rust as builder + +WORKDIR /usr/src/polkadot-malus +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + ca-certificates \ + clang \ + curl \ + cmake \ + libssl1.1 \ + libssl-dev \ + pkg-config + +RUN export PATH="$PATH:$HOME/.cargo/bin" && \ + rustup toolchain install nightly && \ + rustup target add wasm32-unknown-unknown --toolchain nightly && \ + rustup default stable + +COPY polkadot/ /usr/src/polkadot-malus/polkadot/ +COPY substrate/ /usr/src/polkadot-malus/substrate/ + +WORKDIR /usr/src/polkadot-malus/polkadot + +RUN cargo build -p polkadot-test-malus --release +RUN cp -v /usr/src/polkadot-malus/polkadot/target/release/malus /usr/local/bin + +# check if executable works in this container +RUN /usr/local/bin/malus $VARIANT --version + +# +### Runtime +# + +FROM debian:buster-slim as runtime +RUN apt-get update && \ + apt-get install -y curl tini + +COPY --from=builder /usr/src/polkadot-malus/polkadot/target/release/malus /usr/local/bin +# Non-root user for security purposes. +# +# UIDs below 10,000 are a security risk, as a container breakout could result +# in the container being ran as a more privileged user on the host kernel with +# the same UID. +# +# Static GID/UID is also useful for chown'ing files outside the container where +# such a user does not exist. +RUN groupadd --gid 10001 nonroot && \ + useradd --home-dir /home/nonroot \ + --create-home \ + --shell /bin/bash \ + --gid nonroot \ + --groups nonroot \ + --uid 10000 nonroot +WORKDIR /home/nonroot/polkadot-malus + +RUN chown -R nonroot. /home/nonroot + +# Use the non-root user to run our application +# Tell run test script that it runs in container +USER nonroot +# check if executable works in this container +RUN /usr/local/bin/malus --version +# Tini allows us to avoid several Docker edge cases, see https://github.com/krallin/tini. +ENTRYPOINT ["tini", "--", "/usr/local/bin/malus"] + + + + +FROM rust:1.54.0 as planner +WORKDIR /usr/src/polkadot-malus +# We only pay the installation cost once, +# it will be cached from the second build onwards +RUN cargo install cargo-chef +COPY polkadot/ /usr/src/polkadot-malus/polkadot/ +COPY substrate/ /usr/src/polkadot-malus/substrate/ +WORKDIR /usr/src/polkadot-malus/polkadot +RUN cargo chef prepare --recipe-path recipe.json + + +FROM rust:1.54.0 as cacher +WORKDIR /usr/src/polkadot-malus/polkadot +RUN cargo install cargo-chef +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + ca-certificates \ + clang \ + curl \ + cmake \ + libssl1.1 \ + libssl-dev \ + pkg-config +RUN export PATH="$PATH:$HOME/.cargo/bin" && \ + rustup toolchain install nightly && \ + rustup target add wasm32-unknown-unknown --toolchain nightly && \ + rustup default stable +COPY --from=planner /usr/src/polkadot-malus/polkadot/recipe.json recipe.json +RUN cargo chef cook --release --recipe-path recipe.json + + +FROM rust:1.54.0 as builder +WORKDIR /usr/src/polkadot-malus +COPY polkadot/ /usr/src/polkadot-malus/polkadot/ +COPY substrate/ /usr/src/polkadot-malus/substrate/ +# Copy over the cached dependencies +WORKDIR /usr/src/polkadot-malus/polkadot +COPY --from=cacher /usr/src/polkadot-malus/polkadot/target target +COPY --from=cacher $CARGO_HOME $CARGO_HOME +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + ca-certificates \ + clang \ + curl \ + cmake \ + libssl1.1 \ + libssl-dev \ + pkg-config +RUN export PATH="$PATH:$HOME/.cargo/bin" && \ + rustup toolchain install nightly && \ + rustup target add wasm32-unknown-unknown --toolchain nightly && \ + rustup default stable +RUN cargo build -p polkadot-test-malus --release + + +FROM debian:buster-slim as runtime +RUN apt-get update && \ + apt-get install -y curl tini +COPY --from=builder /usr/src/polkadot-malus/polkadot/target/release/malus /usr/local/bin +# Non-root user for security purposes. +# +# UIDs below 10,000 are a security risk, as a container breakout could result +# in the container being ran as a more privileged user on the host kernel with +# the same UID. +# +# Static GID/UID is also useful for chown'ing files outside the container where +# such a user does not exist. +RUN groupadd --gid 10001 nonroot && \ + useradd --home-dir /home/nonroot \ + --create-home \ + --shell /bin/bash \ + --gid nonroot \ + --groups nonroot \ + --uid 10000 nonroot +WORKDIR /home/nonroot/polkadot-malus +RUN chown -R nonroot. /home/nonroot +# Use the non-root user to run our application +# Tell run test script that it runs in container +USER nonroot +# check if executable works in this container +RUN /usr/local/bin/malus --version +# Tini allows us to avoid several Docker edge cases, see https://github.com/krallin/tini. +ENTRYPOINT ["/usr/local/bin/malus"] diff --git a/polkadot/node/malus/container/build.sh b/polkadot/node/malus/container/build.sh new file mode 100755 index 0000000000000000000000000000000000000000..a277ac5ddab45c8822dfa807ec39a9e91a8acbfb --- /dev/null +++ b/polkadot/node/malus/container/build.sh @@ -0,0 +1 @@ +podman build -t paritypr/malus:v1 -f Containerfile ../../../.. diff --git a/polkadot/node/malus/container/malus-local-build.Containerfile b/polkadot/node/malus/container/malus-local-build.Containerfile new file mode 100644 index 0000000000000000000000000000000000000000..ee91e98b23dd3c40f310b876efe813e7af2cf3db --- /dev/null +++ b/polkadot/node/malus/container/malus-local-build.Containerfile @@ -0,0 +1,66 @@ +# +### Builder stage +# + +FROM rust as builder + +WORKDIR /usr/src/polkadot-malus +COPY polkadot/ /usr/src/polkadot-malus/polkadot/ +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + ca-certificates \ + clang \ + curl \ + cmake \ + libssl1.1 \ + libssl-dev \ + pkg-config + +RUN export PATH="$PATH:$HOME/.cargo/bin" && \ + rustup toolchain install nightly && \ + rustup target add wasm32-unknown-unknown --toolchain nightly && \ + rustup default stable + + +WORKDIR /usr/src/polkadot-malus/polkadot + +RUN cargo build -p polkadot-test-malus --release --verbose +RUN cp -v /usr/src/polkadot-malus/polkadot/target/release/malus /usr/local/bin + +# check if executable works in this container +RUN /usr/local/bin/malus --version + +# +### Runtime +# + +FROM debian:buster-slim as runtime +RUN apt-get update && \ + apt-get install -y curl tini + +COPY --from=builder /usr/src/polkadot-malus/polkadot/target/release/malus /usr/local/bin +# Non-root user for security purposes. +# +# UIDs below 10,000 are a security risk, as a container breakout could result +# in the container being ran as a more privileged user on the host kernel with +# the same UID. +# +# Static GID/UID is also useful for chown'ing files outside the container where +# such a user does not exist. +RUN groupadd --gid 10001 nonroot && \ + useradd --home-dir /home/nonroot \ + --create-home \ + --shell /bin/bash \ + --gid nonroot \ + --groups nonroot \ + --uid 10000 nonroot +WORKDIR /home/nonroot/polkadot-malus + +RUN chown -R nonroot. /home/nonroot + +# Use the non-root user to run our application +USER nonroot +# check if executable works in this container +RUN /usr/local/bin/malus --version +# Tini allows us to avoid several Docker edge cases, see https://github.com/krallin/tini. +ENTRYPOINT ["tini", "--", "/usr/local/bin/malus"] diff --git a/polkadot/node/malus/container/polkadot-local-build.Containerfile b/polkadot/node/malus/container/polkadot-local-build.Containerfile new file mode 100644 index 0000000000000000000000000000000000000000..7a7e26a03c06cd37e07e620dca60abe5826693a9 --- /dev/null +++ b/polkadot/node/malus/container/polkadot-local-build.Containerfile @@ -0,0 +1,66 @@ +# +### Builder stage +# + +FROM rust as builder + +WORKDIR /usr/src/polkadot +COPY polkadot/ /usr/src/polkadot +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + ca-certificates \ + clang \ + curl \ + cmake \ + libssl1.1 \ + libssl-dev \ + pkg-config + +RUN export PATH="$PATH:$HOME/.cargo/bin" && \ + rustup toolchain install nightly && \ + rustup target add wasm32-unknown-unknown --toolchain nightly && \ + rustup default stable + + +WORKDIR /usr/src/polkadot + +RUN cargo build --release --bin polkadot --features disputes --verbose +RUN cp -v /usr/src/polkadot/target/release/polkadot /usr/local/bin + +# check if executable works in this container +RUN /usr/local/bin/polkadot --version + +# +### Runtime +# + +FROM debian:buster-slim as runtime +RUN apt-get update && \ + apt-get install -y curl tini + +COPY --from=builder /usr/src/polkadot/target/release/polkadot /usr/local/bin +# Non-root user for security purposes. +# +# UIDs below 10,000 are a security risk, as a container breakout could result +# in the container being ran as a more privileged user on the host kernel with +# the same UID. +# +# Static GID/UID is also useful for chown'ing files outside the container where +# such a user does not exist. +RUN groupadd --gid 10001 nonroot && \ + useradd --home-dir /home/nonroot \ + --create-home \ + --shell /bin/bash \ + --gid nonroot \ + --groups nonroot \ + --uid 10000 nonroot +WORKDIR /home/nonroot/polkadot + +RUN chown -R nonroot. /home/nonroot + +# Use the non-root user to run our application +USER nonroot +# check if executable works in this container +RUN /usr/local/bin/polkadot --version +# Tini allows us to avoid several Docker edge cases, see https://github.com/krallin/tini. +ENTRYPOINT ["tini", "--", "/usr/local/bin/polkadot"] diff --git a/polkadot/node/malus/integrationtests/0001-dispute-valid-block.toml b/polkadot/node/malus/integrationtests/0001-dispute-valid-block.toml new file mode 100644 index 0000000000000000000000000000000000000000..43e55402e68c42fe43b7b2f02f6dd517eedb8281 --- /dev/null +++ b/polkadot/node/malus/integrationtests/0001-dispute-valid-block.toml @@ -0,0 +1,39 @@ +[settings] +timeout = 1000 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "wococo-local" +command = "polkadot" + + [[relaychain.nodes]] + name = "alice" + validator = true + extra_args = [ "--alice", "-lparachain=debug" ] + + [[relaychain.nodes]] + name = "bob" + validator = true + extra_args = [ "--bob", "-lparachain=debug" ] + + [[relaychain.nodes]] + name = "charlie" + validator = true + extra_args = [ "--charlie", "-lparachain=debug" ] + + [[relaychain.nodes]] + name = "dave" + validator = true + command = "malus dispute-ancestor" + extra_args = ["--dave", "-lparachain=debug"] + image = "{{MALUS_IMAGE}}" + autoConnectApi = false + +[[parachains]] +id = 100 + + [parachains.collator] + name = "collator01" + image = "{{COL_IMAGE}}" + command = "adder-collator" + args = ["-lparachain=debug"] diff --git a/polkadot/node/malus/integrationtests/0001-dispute-valid-block.zndsl b/polkadot/node/malus/integrationtests/0001-dispute-valid-block.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..737cd4ebd521d9cc80729326698ceeb68a7d0b9f --- /dev/null +++ b/polkadot/node/malus/integrationtests/0001-dispute-valid-block.zndsl @@ -0,0 +1,29 @@ +Description: Disputes +Network: ./0001-dispute-valid-block.toml +Creds: config + + +alice: is up +bob: is up +charlie: is up +dave: is up +alice: reports node_roles is 4 +bob: reports node_roles is 4 +alice: reports sub_libp2p_is_major_syncing is 0 +alice: reports block height is at least 2 within 15 seconds +alice: reports peers count is at least 2 +bob: reports block height is at least 2 +bob: reports peers count is at least 2 +charlie: reports block height is at least 2 +charlie: reports peers count is at least 2 +alice: reports polkadot_parachain_candidate_disputes_total is at least 1 within 250 seconds +bob: reports polkadot_parachain_candidate_disputes_total is at least 1 within 90 seconds +charlie: reports polkadot_parachain_candidate_disputes_total is at least 1 within 90 seconds +alice: reports polkadot_parachain_candidate_dispute_votes{validity="valid"} is at least 1 within 90 seconds +bob: reports polkadot_parachain_candidate_dispute_votes{validity="valid"} is at least 2 within 90 seconds +charlie: reports polkadot_parachain_candidate_dispute_votes{validity="valid"} is at least 2 within 90 seconds +alice: reports polkadot_parachain_candidate_dispute_concluded{validity="valid"} is at least 1 within 90 seconds +alice: reports polkadot_parachain_candidate_dispute_concluded{validity="invalid"} is 0 within 90 seconds +bob: reports polkadot_parachain_candidate_dispute_concluded{validity="valid"} is at least 1 within 90 seconds +charlie: reports polkadot_parachain_candidate_dispute_concluded{validity="valid"} is at least 1 within 90 seconds +charlie: reports polkadot_parachain_candidate_dispute_concluded{validity="valid"} is at least 1 within 90 seconds diff --git a/polkadot/node/malus/src/interceptor.rs b/polkadot/node/malus/src/interceptor.rs new file mode 100644 index 0000000000000000000000000000000000000000..cbf39bccd16027e9b0dbe59745ed2dc28b283968 --- /dev/null +++ b/polkadot/node/malus/src/interceptor.rs @@ -0,0 +1,261 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A small set of wrapping types to cover most of our adversary test cases. +//! +//! This allows types with internal mutability to synchronize across +//! multiple subsystems and intercept or replace incoming and outgoing +//! messages on the overseer level. + +use polkadot_node_subsystem::*; +pub use polkadot_node_subsystem::{messages, messages::*, overseer, FromOrchestra}; +use std::{future::Future, pin::Pin}; + +/// Filter incoming and outgoing messages. +pub trait MessageInterceptor: Send + Sync + Clone + 'static +where + Sender: overseer::SubsystemSender<::OutgoingMessages> + + Clone + + 'static, +{ + /// The message type the original subsystem handles incoming. + type Message: overseer::AssociateOutgoing + Send + 'static; + + /// Filter messages that are to be received by + /// the subsystem. + /// + /// For non-trivial cases, the `sender` can be used to send + /// multiple messages after doing some additional processing. + fn intercept_incoming( + &self, + _sender: &mut Sender, + msg: FromOrchestra, + ) -> Option> { + Some(msg) + } + + /// Modify outgoing messages. + fn intercept_outgoing( + &self, + msg: ::OutgoingMessages, + ) -> Option<::OutgoingMessages> { + Some(msg) + } +} + +/// A sender with the outgoing messages filtered. +#[derive(Clone)] +pub struct InterceptedSender { + inner: Sender, + message_filter: Fil, +} + +#[async_trait::async_trait] +impl overseer::SubsystemSender for InterceptedSender +where + OutgoingMessage: overseer::AssociateOutgoing + Send + 'static, + Sender: overseer::SubsystemSender + + overseer::SubsystemSender< + < + >::Message as overseer::AssociateOutgoing + >::OutgoingMessages + >, + Fil: MessageInterceptor, + >::Message: overseer::AssociateOutgoing, + < + >::Message as overseer::AssociateOutgoing + >::OutgoingMessages: + From, +{ + async fn send_message(&mut self, msg: OutgoingMessage) { + let msg = < + <>::Message as overseer::AssociateOutgoing + >::OutgoingMessages as From>::from(msg); + if let Some(msg) = self.message_filter.intercept_outgoing(msg) { + self.inner.send_message(msg).await; + } + } + + async fn send_messages(&mut self, msgs: T) + where + T: IntoIterator + Send, + T::IntoIter: Send, + { + for msg in msgs { + self.send_message(msg).await; + } + } + + fn send_unbounded_message(&mut self, msg: OutgoingMessage) { + let msg = < + <>::Message as overseer::AssociateOutgoing + >::OutgoingMessages as From>::from(msg); + if let Some(msg) = self.message_filter.intercept_outgoing(msg) { + self.inner.send_unbounded_message(msg); + } + } +} + +/// A subsystem context, that filters the outgoing messages. +pub struct InterceptedContext +where + Context: overseer::SubsystemContext, + Fil: MessageInterceptor<::Sender>, + ::Sender: + overseer::SubsystemSender< + < + < + Fil as MessageInterceptor<::Sender> + >::Message as overseer::AssociateOutgoing + >::OutgoingMessages, + >, +{ + inner: Context, + message_filter: Fil, + sender: InterceptedSender<::Sender, Fil>, +} + +impl InterceptedContext +where + Context: overseer::SubsystemContext, + Fil: MessageInterceptor< + ::Sender, + Message = ::Message, + >, + ::Message: overseer::AssociateOutgoing, + ::Sender: overseer::SubsystemSender< + <::Message as overseer::AssociateOutgoing>::OutgoingMessages + > +{ + pub fn new(mut inner: Context, message_filter: Fil) -> Self { + let sender = InterceptedSender::<::Sender, Fil> { + inner: inner.sender().clone(), + message_filter: message_filter.clone(), + }; + Self { inner, message_filter, sender } + } +} + +#[async_trait::async_trait] +impl overseer::SubsystemContext for InterceptedContext +where + Context: overseer::SubsystemContext, + ::Message: + overseer::AssociateOutgoing, + ::Sender: + overseer::SubsystemSender< + <::Message as overseer::AssociateOutgoing>::OutgoingMessages + >, + InterceptedSender<::Sender, Fil>: + overseer::SubsystemSender< + <::Message as overseer::AssociateOutgoing>::OutgoingMessages + >, + Fil: MessageInterceptor< + ::Sender, + Message = ::Message, + >, +{ + type Message = ::Message; + type Sender = InterceptedSender<::Sender, Fil>; + type Error = SubsystemError; + type OutgoingMessages = <::Message as overseer::AssociateOutgoing>::OutgoingMessages; + type Signal = OverseerSignal; + + async fn try_recv(&mut self) -> Result>, ()> { + loop { + match self.inner.try_recv().await? { + None => return Ok(None), + Some(msg) => + if let Some(msg) = + self.message_filter.intercept_incoming(self.inner.sender(), msg) + { + return Ok(Some(msg)) + }, + } + } + } + + async fn recv(&mut self) -> SubsystemResult> { + loop { + let msg = self.inner.recv().await?; + if let Some(msg) = self.message_filter.intercept_incoming(self.inner.sender(), msg) { + return Ok(msg) + } + } + } + + fn spawn( + &mut self, + name: &'static str, + s: Pin + Send>>, + ) -> SubsystemResult<()> { + self.inner.spawn(name, s) + } + + fn spawn_blocking( + &mut self, + name: &'static str, + s: Pin + Send>>, + ) -> SubsystemResult<()> { + self.inner.spawn_blocking(name, s) + } + + fn sender(&mut self) -> &mut Self::Sender { + &mut self.sender + } +} + +/// A subsystem to which incoming and outgoing filters are applied. +pub struct InterceptedSubsystem { + pub subsystem: Sub, + pub message_interceptor: Interceptor, +} + +impl InterceptedSubsystem { + pub fn new(subsystem: Sub, message_interceptor: Interceptor) -> Self { + Self { subsystem, message_interceptor } + } +} + +impl overseer::Subsystem for InterceptedSubsystem +where + Context: + overseer::SubsystemContext + Sync + Send, + InterceptedContext: + overseer::SubsystemContext, + Sub: + overseer::Subsystem, SubsystemError>, + Interceptor: + MessageInterceptor< + ::Sender, + Message = ::Message, + >, + ::Message: + overseer::AssociateOutgoing, + ::Sender: + overseer::SubsystemSender< + <::Message as overseer::AssociateOutgoing + >::OutgoingMessages + >, +{ + fn start(self, ctx: Context) -> SpawnedSubsystem { + let ctx = InterceptedContext::new(ctx, self.message_interceptor); + overseer::Subsystem::, SubsystemError>::start( + self.subsystem, + ctx, + ) + } +} diff --git a/polkadot/node/malus/src/malus.rs b/polkadot/node/malus/src/malus.rs new file mode 100644 index 0000000000000000000000000000000000000000..69dd7c869fc0d4720026998db36e59d063cb9bd8 --- /dev/null +++ b/polkadot/node/malus/src/malus.rs @@ -0,0 +1,187 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A malus or nemesis node launch code. + +use clap::Parser; +use color_eyre::eyre; + +pub(crate) mod interceptor; +pub(crate) mod shared; + +mod variants; + +use variants::*; + +/// Define the different variants of behavior. +#[derive(Debug, Parser)] +#[command(about = "Malus - the nemesis of polkadot.", version, rename_all = "kebab-case")] +enum NemesisVariant { + /// Suggest a candidate with an invalid proof of validity. + SuggestGarbageCandidate(SuggestGarbageCandidateOptions), + /// Back a candidate with a specifically crafted proof of validity. + BackGarbageCandidate(BackGarbageCandidateOptions), + /// Delayed disputing of ancestors that are perfectly fine. + DisputeAncestor(DisputeAncestorOptions), +} + +#[derive(Debug, Parser)] +#[allow(missing_docs)] +struct MalusCli { + #[command(subcommand)] + pub variant: NemesisVariant, + /// Sets the minimum delay between the best and finalized block. + pub finality_delay: Option, +} + +impl MalusCli { + /// Launch a malus node. + fn launch(self) -> eyre::Result<()> { + let finality_delay = self.finality_delay; + match self.variant { + NemesisVariant::BackGarbageCandidate(opts) => { + let BackGarbageCandidateOptions { percentage, cli } = opts; + + polkadot_cli::run_node(cli, BackGarbageCandidates { percentage }, finality_delay)? + }, + NemesisVariant::SuggestGarbageCandidate(opts) => { + let SuggestGarbageCandidateOptions { percentage, cli } = opts; + + polkadot_cli::run_node( + cli, + SuggestGarbageCandidates { percentage }, + finality_delay, + )? + }, + NemesisVariant::DisputeAncestor(opts) => { + let DisputeAncestorOptions { + fake_validation, + fake_validation_error, + percentage, + cli, + } = opts; + + polkadot_cli::run_node( + cli, + DisputeValidCandidates { fake_validation, fake_validation_error, percentage }, + finality_delay, + )? + }, + } + Ok(()) + } +} + +fn main() -> eyre::Result<()> { + color_eyre::install()?; + let cli = MalusCli::parse(); + cli.launch()?; + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn subcommand_works() { + let cli = MalusCli::try_parse_from(IntoIterator::into_iter([ + "malus", + "dispute-ancestor", + "--bob", + ])) + .unwrap(); + assert_matches::assert_matches!(cli, MalusCli { + variant: NemesisVariant::DisputeAncestor(run), + .. + } => { + assert!(run.cli.run.base.bob); + }); + } + + #[test] + fn percentage_works_suggest_garbage() { + let cli = MalusCli::try_parse_from(IntoIterator::into_iter([ + "malus", + "suggest-garbage-candidate", + "--percentage", + "100", + "--bob", + ])) + .unwrap(); + assert_matches::assert_matches!(cli, MalusCli { + variant: NemesisVariant::SuggestGarbageCandidate(run), + .. + } => { + assert!(run.cli.run.base.bob); + }); + } + + #[test] + fn percentage_works_dispute_ancestor() { + let cli = MalusCli::try_parse_from(IntoIterator::into_iter([ + "malus", + "dispute-ancestor", + "--percentage", + "100", + "--bob", + ])) + .unwrap(); + assert_matches::assert_matches!(cli, MalusCli { + variant: NemesisVariant::DisputeAncestor(run), + .. + } => { + assert!(run.cli.run.base.bob); + }); + } + + #[test] + fn percentage_works_back_garbage() { + let cli = MalusCli::try_parse_from(IntoIterator::into_iter([ + "malus", + "back-garbage-candidate", + "--percentage", + "100", + "--bob", + ])) + .unwrap(); + assert_matches::assert_matches!(cli, MalusCli { + variant: NemesisVariant::BackGarbageCandidate(run), + .. + } => { + assert!(run.cli.run.base.bob); + }); + } + + #[test] + #[should_panic] + fn validate_range_for_percentage() { + let cli = MalusCli::try_parse_from(IntoIterator::into_iter([ + "malus", + "suggest-garbage-candidate", + "--percentage", + "101", + "--bob", + ])) + .unwrap(); + assert_matches::assert_matches!(cli, MalusCli { + variant: NemesisVariant::DisputeAncestor(run), + .. + } => { + assert!(run.cli.run.base.bob); + }); + } +} diff --git a/polkadot/node/malus/src/shared.rs b/polkadot/node/malus/src/shared.rs new file mode 100644 index 0000000000000000000000000000000000000000..28666e400aa9b622ee03a69f8a1359812d33be46 --- /dev/null +++ b/polkadot/node/malus/src/shared.rs @@ -0,0 +1,49 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use futures::prelude::*; +use sp_core::traits::SpawnNamed; + +pub const MALUS: &str = "MALUS"; + +#[allow(unused)] +pub(crate) const MALICIOUS_POV: &[u8] = "😈😈pov_looks_valid_to_me😈😈".as_bytes(); + +/// Launch a service task for each item in the provided queue. +#[allow(unused)] +pub(crate) fn launch_processing_task(spawner: &S, queue: Q, action: F) +where + F: Fn(X) -> U + Send + 'static, + U: Future + Send + 'static, + Q: Stream + Send + 'static, + X: Send, + S: 'static + SpawnNamed + Clone + Unpin, +{ + let spawner2: S = spawner.clone(); + spawner.spawn( + "nemesis-queue-processor", + Some("malus"), + Box::pin(async move { + let spawner3 = spawner2.clone(); + queue + .for_each(move |input| { + spawner3.spawn("nemesis-task", Some("malus"), Box::pin(action(input))); + async move { () } + }) + .await; + }), + ); +} diff --git a/polkadot/node/malus/src/tests.rs b/polkadot/node/malus/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..1cf0698babcc4443cae10dde0e6b1e7b99ab24c3 --- /dev/null +++ b/polkadot/node/malus/src/tests.rs @@ -0,0 +1,140 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use polkadot_node_subsystem_test_helpers::*; + +use polkadot_node_subsystem::{ + messages::AvailabilityStoreMessage, + overseer::{dummy::DummySubsystem, gen::TimeoutExt, Subsystem, AssociateOutgoing}, + SubsystemError, +}; + +#[derive(Clone, Debug)] +struct BlackHoleInterceptor; + +impl MessageInterceptor for BlackHoleInterceptor +where + Sender: overseer::AvailabilityStoreSenderTrait + + Clone + + 'static, +{ + type Message = AvailabilityStoreMessage; + fn intercept_incoming( + &self, + _sender: &mut Sender, + msg: FromOrchestra, + ) -> Option> { + match msg { + FromOrchestra::Communication { msg: _msg } => None, + // to conclude the test cleanly + sig => Some(sig), + } + } +} + +#[derive(Clone, Debug)] +struct PassInterceptor; + +impl MessageInterceptor for PassInterceptor +where + Sender: overseer::AvailabilityStoreSenderTrait + + Clone + + 'static, +{ + type Message = AvailabilityStoreMessage; +} + +async fn overseer_send>(overseer: &mut TestSubsystemContextHandle, msg: T) { + overseer.send(FromOrchestra::Communication { msg }).await; +} + +use sp_core::testing::TaskExecutor; + +fn launch_harness(test_gen: G) +where + F: Future> + Send, + M: AssociateOutgoing + std::fmt::Debug + Send + 'static, + // ::OutgoingMessages: From, + Sub: Subsystem>, SubsystemError>, + G: Fn(TestSubsystemContextHandle) -> (F, Sub), +{ + let pool = TaskExecutor::new(); + let (context, overseer) = make_subsystem_context(pool); + + let (test_fut, subsystem) = test_gen(overseer); + let subsystem = async move { + subsystem.start(context).future.await.unwrap(); + }; + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + futures::executor::block_on(futures::future::join( + async move { + let mut overseer = test_fut.await; + overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }, + subsystem, + )) + .1; +} + +#[test] +fn integrity_test_intercept() { + launch_harness(|mut overseer| { + let sub = DummySubsystem; + + let sub_intercepted = InterceptedSubsystem::new(sub, BlackHoleInterceptor); + + ( + async move { + let (tx, rx) = futures::channel::oneshot::channel(); + overseer_send( + &mut overseer, + AvailabilityStoreMessage::QueryChunk(Default::default(), 0.into(), tx), + ) + .await; + let _ = rx.timeout(std::time::Duration::from_millis(100)).await.unwrap(); + overseer + }, + sub_intercepted, + ) + }) +} + +#[test] +fn integrity_test_pass() { + launch_harness(|mut overseer| { + let sub = DummySubsystem; + + let sub_intercepted = InterceptedSubsystem::new(sub, PassInterceptor); + + ( + async move { + let (tx, rx) = futures::channel::oneshot::channel(); + overseer_send( + &mut overseer, + AvailabilityStoreMessage::QueryChunk(Default::default(), 0.into(), tx), + ) + .await; + let _ = rx.timeout(std::time::Duration::from_millis(100)).await.unwrap(); + overseer + }, + sub_intercepted, + ) + }) +} diff --git a/polkadot/node/malus/src/variants/back_garbage_candidate.rs b/polkadot/node/malus/src/variants/back_garbage_candidate.rs new file mode 100644 index 0000000000000000000000000000000000000000..aa904c37b80a59c9a77dfdb682c3d0e00b7ff833 --- /dev/null +++ b/polkadot/node/malus/src/variants/back_garbage_candidate.rs @@ -0,0 +1,90 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This variant of Malus backs/approves all malicious candidates crafted by +//! `suggest-garbage-candidate` variant and behaves honestly with other +//! candidates. + +use polkadot_cli::{ + prepared_overseer_builder, + service::{ + AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, HeaderBackend, Overseer, + OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, ParachainHost, + ProvideRuntimeApi, + }, + Cli, +}; +use polkadot_node_subsystem::SpawnGlue; +use polkadot_node_subsystem_types::DefaultSubsystemClient; +use sp_core::traits::SpawnNamed; + +use crate::{ + interceptor::*, + variants::{FakeCandidateValidation, FakeCandidateValidationError, ReplaceValidationResult}, +}; + +use std::sync::Arc; + +#[derive(Debug, clap::Parser)] +#[clap(rename_all = "kebab-case")] +#[allow(missing_docs)] +pub struct BackGarbageCandidateOptions { + /// Determines the percentage of garbage candidates that should be backed. + /// Defaults to 100% of garbage candidates being backed. + #[clap(short, long, ignore_case = true, default_value_t = 100, value_parser = clap::value_parser!(u8).range(0..=100))] + pub percentage: u8, + + #[clap(flatten)] + pub cli: Cli, +} + +/// Generates an overseer that replaces the candidate validation subsystem with our malicious +/// variant. +pub(crate) struct BackGarbageCandidates { + /// The probability of behaving maliciously. + pub percentage: u8, +} + +impl OverseerGen for BackGarbageCandidates { + fn generate( + &self, + connector: OverseerConnector, + args: OverseerGenArgs<'_, Spawner, RuntimeClient>, + ) -> Result< + (Overseer, Arc>>, OverseerHandle), + Error, + > + where + RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, + RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + Spawner: 'static + SpawnNamed + Clone + Unpin, + { + let spawner = args.spawner.clone(); + let validation_filter = ReplaceValidationResult::new( + FakeCandidateValidation::BackingAndApprovalValid, + FakeCandidateValidationError::InvalidOutputs, + f64::from(self.percentage), + SpawnGlue(spawner), + ); + + prepared_overseer_builder(args)? + .replace_candidate_validation(move |cv_subsystem| { + InterceptedSubsystem::new(cv_subsystem, validation_filter) + }) + .build_with_connector(connector) + .map_err(|e| e.into()) + } +} diff --git a/polkadot/node/malus/src/variants/common.rs b/polkadot/node/malus/src/variants/common.rs new file mode 100644 index 0000000000000000000000000000000000000000..475ca8f314520958e0677e232632abe59731fc0d --- /dev/null +++ b/polkadot/node/malus/src/variants/common.rs @@ -0,0 +1,498 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implements common code for nemesis. Currently, only `FakeValidationResult` +//! interceptor is implemented. +use crate::{ + interceptor::*, + shared::{MALICIOUS_POV, MALUS}, +}; + +use polkadot_node_core_candidate_validation::find_validation_data; +use polkadot_node_primitives::{InvalidCandidate, ValidationResult}; +use polkadot_node_subsystem::{ + messages::{CandidateValidationMessage, ValidationFailed}, + overseer, +}; + +use polkadot_primitives::{ + CandidateCommitments, CandidateDescriptor, CandidateReceipt, PersistedValidationData, + PvfExecTimeoutKind, +}; + +use futures::channel::oneshot; +use rand::distributions::{Bernoulli, Distribution}; + +#[derive(clap::ValueEnum, Clone, Copy, Debug, PartialEq)] +#[value(rename_all = "kebab-case")] +#[non_exhaustive] +pub enum FakeCandidateValidation { + Disabled, + BackingInvalid, + ApprovalInvalid, + BackingAndApprovalInvalid, + BackingValid, + ApprovalValid, + BackingAndApprovalValid, +} + +impl FakeCandidateValidation { + fn misbehaves_valid(&self) -> bool { + use FakeCandidateValidation::*; + + match *self { + BackingValid | ApprovalValid | BackingAndApprovalValid => true, + _ => false, + } + } + + fn misbehaves_invalid(&self) -> bool { + use FakeCandidateValidation::*; + + match *self { + BackingInvalid | ApprovalInvalid | BackingAndApprovalInvalid => true, + _ => false, + } + } + + fn includes_backing(&self) -> bool { + use FakeCandidateValidation::*; + + match *self { + BackingInvalid | BackingAndApprovalInvalid | BackingValid | BackingAndApprovalValid => + true, + _ => false, + } + } + + fn includes_approval(&self) -> bool { + use FakeCandidateValidation::*; + + match *self { + ApprovalInvalid | + BackingAndApprovalInvalid | + ApprovalValid | + BackingAndApprovalValid => true, + _ => false, + } + } + + fn should_misbehave(&self, timeout: PvfExecTimeoutKind) -> bool { + match timeout { + PvfExecTimeoutKind::Backing => self.includes_backing(), + PvfExecTimeoutKind::Approval => self.includes_approval(), + } + } +} + +/// Candidate invalidity details +#[derive(clap::ValueEnum, Clone, Copy, Debug, PartialEq)] +#[value(rename_all = "kebab-case")] +pub enum FakeCandidateValidationError { + /// Validation outputs check doesn't pass. + InvalidOutputs, + /// Failed to execute.`validate_block`. This includes function panicking. + ExecutionError, + /// Execution timeout. + Timeout, + /// Validation input is over the limit. + ParamsTooLarge, + /// Code size is over the limit. + CodeTooLarge, + /// PoV does not decompress correctly. + POVDecompressionFailure, + /// Validation function returned invalid data. + BadReturn, + /// Invalid relay chain parent. + BadParent, + /// POV hash does not match. + POVHashMismatch, + /// Bad collator signature. + BadSignature, + /// Para head hash does not match. + ParaHeadHashMismatch, + /// Validation code hash does not match. + CodeHashMismatch, +} + +impl Into for FakeCandidateValidationError { + fn into(self) -> InvalidCandidate { + match self { + FakeCandidateValidationError::ExecutionError => + InvalidCandidate::ExecutionError("Malus".into()), + FakeCandidateValidationError::InvalidOutputs => InvalidCandidate::InvalidOutputs, + FakeCandidateValidationError::Timeout => InvalidCandidate::Timeout, + FakeCandidateValidationError::ParamsTooLarge => InvalidCandidate::ParamsTooLarge(666), + FakeCandidateValidationError::CodeTooLarge => InvalidCandidate::CodeTooLarge(666), + FakeCandidateValidationError::POVDecompressionFailure => + InvalidCandidate::PoVDecompressionFailure, + FakeCandidateValidationError::BadReturn => InvalidCandidate::BadReturn, + FakeCandidateValidationError::BadParent => InvalidCandidate::BadParent, + FakeCandidateValidationError::POVHashMismatch => InvalidCandidate::PoVHashMismatch, + FakeCandidateValidationError::BadSignature => InvalidCandidate::BadSignature, + FakeCandidateValidationError::ParaHeadHashMismatch => + InvalidCandidate::ParaHeadHashMismatch, + FakeCandidateValidationError::CodeHashMismatch => InvalidCandidate::CodeHashMismatch, + } + } +} + +#[derive(Clone, Debug)] +/// An interceptor which fakes validation result with a preconfigured result. +/// Replaces `CandidateValidationSubsystem`. +pub struct ReplaceValidationResult { + fake_validation: FakeCandidateValidation, + fake_validation_error: FakeCandidateValidationError, + distribution: Bernoulli, + spawner: Spawner, +} + +impl ReplaceValidationResult +where + Spawner: overseer::gen::Spawner, +{ + pub fn new( + fake_validation: FakeCandidateValidation, + fake_validation_error: FakeCandidateValidationError, + percentage: f64, + spawner: Spawner, + ) -> Self { + let distribution = Bernoulli::new(percentage / 100.0) + .expect("Invalid probability! Percentage must be in range [0..=100]."); + Self { fake_validation, fake_validation_error, distribution, spawner } + } + + /// Creates and sends the validation response for a given candidate. Queries the runtime to + /// obtain the validation data for the given candidate. + pub fn send_validation_response( + &self, + candidate_descriptor: CandidateDescriptor, + subsystem_sender: Sender, + response_sender: oneshot::Sender>, + ) where + Sender: overseer::CandidateValidationSenderTrait + Clone + Send + 'static, + { + let _candidate_descriptor = candidate_descriptor.clone(); + let mut subsystem_sender = subsystem_sender.clone(); + let (sender, receiver) = std::sync::mpsc::channel(); + self.spawner.spawn_blocking( + "malus-get-validation-data", + Some("malus"), + Box::pin(async move { + match find_validation_data(&mut subsystem_sender, &_candidate_descriptor).await { + Ok(Some((validation_data, validation_code))) => { + sender + .send((validation_data, validation_code)) + .expect("channel is still open"); + }, + _ => { + panic!("Unable to fetch validation data"); + }, + } + }), + ); + let (validation_data, _) = receiver.recv().unwrap(); + create_validation_response(validation_data, candidate_descriptor, response_sender); + } +} + +pub fn create_fake_candidate_commitments( + persisted_validation_data: &PersistedValidationData, +) -> CandidateCommitments { + // Backing rejects candidates which output the same head as the parent, + // therefore we must create a new head which is not equal to the parent. + let mut head_data = persisted_validation_data.parent_head.clone(); + if head_data.0.is_empty() { + head_data.0.push(0); + } else { + head_data.0[0] = head_data.0[0].wrapping_add(1); + }; + + CandidateCommitments { + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + head_data, + processed_downward_messages: 0, + hrmp_watermark: persisted_validation_data.relay_parent_number, + } +} + +// Create and send validation response. This function needs the persistent validation data. +fn create_validation_response( + persisted_validation_data: PersistedValidationData, + descriptor: CandidateDescriptor, + response_sender: oneshot::Sender>, +) { + let commitments = create_fake_candidate_commitments(&persisted_validation_data); + + // Craft the new malicious candidate. + let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: commitments.hash() }; + + let result = Ok(ValidationResult::Valid(commitments, persisted_validation_data)); + + gum::debug!( + target: MALUS, + para_id = ?candidate_receipt.descriptor.para_id, + candidate_hash = ?candidate_receipt.hash(), + "ValidationResult: {:?}", + &result + ); + + response_sender.send(result).unwrap(); +} + +impl MessageInterceptor for ReplaceValidationResult +where + Sender: overseer::CandidateValidationSenderTrait + Clone + Send + 'static, + Spawner: overseer::gen::Spawner + Clone + 'static, +{ + type Message = CandidateValidationMessage; + + // Capture all (approval and backing) candidate validation requests and depending on + // configuration fail them. + fn intercept_incoming( + &self, + subsystem_sender: &mut Sender, + msg: FromOrchestra, + ) -> Option> { + match msg { + // Message sent by the approval voting subsystem + FromOrchestra::Communication { + msg: + CandidateValidationMessage::ValidateFromExhaustive( + validation_data, + validation_code, + candidate_receipt, + pov, + timeout, + sender, + ), + } => { + match self.fake_validation { + x if x.misbehaves_valid() && x.should_misbehave(timeout) => { + // Behave normally if the `PoV` is not known to be malicious. + if pov.block_data.0.as_slice() != MALICIOUS_POV { + return Some(FromOrchestra::Communication { + msg: CandidateValidationMessage::ValidateFromExhaustive( + validation_data, + validation_code, + candidate_receipt, + pov, + timeout, + sender, + ), + }) + } + // Create the fake response with probability `p` if the `PoV` is malicious, + // where 'p' defaults to 100% for suggest-garbage-candidate variant. + let behave_maliciously = self.distribution.sample(&mut rand::thread_rng()); + match behave_maliciously { + true => { + gum::info!( + target: MALUS, + ?behave_maliciously, + "😈 Creating malicious ValidationResult::Valid message with fake candidate commitments.", + ); + + create_validation_response( + validation_data, + candidate_receipt.descriptor, + sender, + ); + None + }, + false => { + // Behave normally with probability `(1-p)` for a malicious `PoV`. + gum::info!( + target: MALUS, + ?behave_maliciously, + "😈 Passing CandidateValidationMessage::ValidateFromExhaustive to the candidate validation subsystem.", + ); + + Some(FromOrchestra::Communication { + msg: CandidateValidationMessage::ValidateFromExhaustive( + validation_data, + validation_code, + candidate_receipt, + pov, + timeout, + sender, + ), + }) + }, + } + }, + x if x.misbehaves_invalid() && x.should_misbehave(timeout) => { + // Set the validation result to invalid with probability `p` and trigger a + // dispute + let behave_maliciously = self.distribution.sample(&mut rand::thread_rng()); + match behave_maliciously { + true => { + let validation_result = + ValidationResult::Invalid(InvalidCandidate::InvalidOutputs); + + gum::info!( + target: MALUS, + ?behave_maliciously, + para_id = ?candidate_receipt.descriptor.para_id, + "😈 Maliciously sending invalid validation result: {:?}.", + &validation_result, + ); + + // We're not even checking the candidate, this makes us appear + // faster than honest validators. + sender.send(Ok(validation_result)).unwrap(); + None + }, + false => { + // Behave normally with probability `(1-p)` + gum::info!(target: MALUS, "😈 'Decided' to not act maliciously.",); + + Some(FromOrchestra::Communication { + msg: CandidateValidationMessage::ValidateFromExhaustive( + validation_data, + validation_code, + candidate_receipt, + pov, + timeout, + sender, + ), + }) + }, + } + }, + // Handle FakeCandidateValidation::Disabled + _ => Some(FromOrchestra::Communication { + msg: CandidateValidationMessage::ValidateFromExhaustive( + validation_data, + validation_code, + candidate_receipt, + pov, + timeout, + sender, + ), + }), + } + }, + // Behaviour related to the backing subsystem + FromOrchestra::Communication { + msg: + CandidateValidationMessage::ValidateFromChainState( + candidate_receipt, + pov, + timeout, + response_sender, + ), + } => { + match self.fake_validation { + x if x.misbehaves_valid() && x.should_misbehave(timeout) => { + // Behave normally if the `PoV` is not known to be malicious. + if pov.block_data.0.as_slice() != MALICIOUS_POV { + return Some(FromOrchestra::Communication { + msg: CandidateValidationMessage::ValidateFromChainState( + candidate_receipt, + pov, + timeout, + response_sender, + ), + }) + } + // If the `PoV` is malicious, back the candidate with some probability `p`, + // where 'p' defaults to 100% for suggest-garbage-candidate variant. + let behave_maliciously = self.distribution.sample(&mut rand::thread_rng()); + match behave_maliciously { + true => { + gum::info!( + target: MALUS, + ?behave_maliciously, + "😈 Backing candidate with malicious PoV.", + ); + + self.send_validation_response( + candidate_receipt.descriptor, + subsystem_sender.clone(), + response_sender, + ); + None + }, + // If the `PoV` is malicious, we behave normally with some probability + // `(1-p)` + false => Some(FromOrchestra::Communication { + msg: CandidateValidationMessage::ValidateFromChainState( + candidate_receipt, + pov, + timeout, + response_sender, + ), + }), + } + }, + x if x.misbehaves_invalid() && x.should_misbehave(timeout) => { + // Maliciously set the validation result to invalid for a valid candidate + // with probability `p` + let behave_maliciously = self.distribution.sample(&mut rand::thread_rng()); + match behave_maliciously { + true => { + let validation_result = + ValidationResult::Invalid(self.fake_validation_error.into()); + gum::info!( + target: MALUS, + para_id = ?candidate_receipt.descriptor.para_id, + "😈 Maliciously sending invalid validation result: {:?}.", + &validation_result, + ); + // We're not even checking the candidate, this makes us appear + // faster than honest validators. + response_sender.send(Ok(validation_result)).unwrap(); + None + }, + // With some probability `(1-p)` we behave normally + false => { + gum::info!(target: MALUS, "😈 'Decided' to not act maliciously.",); + + Some(FromOrchestra::Communication { + msg: CandidateValidationMessage::ValidateFromChainState( + candidate_receipt, + pov, + timeout, + response_sender, + ), + }) + }, + } + }, + _ => Some(FromOrchestra::Communication { + msg: CandidateValidationMessage::ValidateFromChainState( + candidate_receipt, + pov, + timeout, + response_sender, + ), + }), + } + }, + msg => Some(msg), + } + } + + fn intercept_outgoing( + &self, + msg: overseer::CandidateValidationOutgoingMessages, + ) -> Option { + Some(msg) + } +} diff --git a/polkadot/node/malus/src/variants/dispute_valid_candidates.rs b/polkadot/node/malus/src/variants/dispute_valid_candidates.rs new file mode 100644 index 0000000000000000000000000000000000000000..fa3b0c38bc2f456580fdc41822a47c9f395946a0 --- /dev/null +++ b/polkadot/node/malus/src/variants/dispute_valid_candidates.rs @@ -0,0 +1,107 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A malicious node that replaces approvals with invalid disputes +//! against valid candidates. Additionally, the malus node can be configured to +//! fake candidate validation and return a static result for candidate checking. +//! +//! Attention: For usage with `zombienet` only! + +#![allow(missing_docs)] + +use polkadot_cli::{ + prepared_overseer_builder, + service::{ + AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, HeaderBackend, Overseer, + OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, ParachainHost, + ProvideRuntimeApi, + }, + Cli, +}; +use polkadot_node_subsystem::SpawnGlue; +use polkadot_node_subsystem_types::DefaultSubsystemClient; +use sp_core::traits::SpawnNamed; + +// Filter wrapping related types. +use super::common::{FakeCandidateValidation, FakeCandidateValidationError}; +use crate::{interceptor::*, variants::ReplaceValidationResult}; + +use std::sync::Arc; + +#[derive(Debug, clap::Parser)] +#[command(rename_all = "kebab-case")] +#[allow(missing_docs)] +pub struct DisputeAncestorOptions { + /// Malicious candidate validation subsystem configuration. When enabled, node PVF execution is + /// skipped during backing and/or approval and it's result can by specified by this option and + /// `--fake-validation-error` for invalid candidate outcomes. + #[arg(long, value_enum, ignore_case = true, default_value_t = FakeCandidateValidation::BackingAndApprovalInvalid)] + pub fake_validation: FakeCandidateValidation, + + /// Applies only when `--fake-validation` is configured to reject candidates as invalid. It + /// allows to specify the exact error to return from the malicious candidate validation + /// subsystem. + #[arg(long, value_enum, ignore_case = true, default_value_t = FakeCandidateValidationError::InvalidOutputs)] + pub fake_validation_error: FakeCandidateValidationError, + + /// Determines the percentage of candidates that should be disputed. Allows for fine-tuning + /// the intensity of the behavior of the malicious node. Value must be in the range [0..=100]. + #[clap(short, long, ignore_case = true, default_value_t = 100, value_parser = clap::value_parser!(u8).range(0..=100))] + pub percentage: u8, + + #[clap(flatten)] + pub cli: Cli, +} + +pub(crate) struct DisputeValidCandidates { + /// Fake validation config (applies to disputes as well). + pub fake_validation: FakeCandidateValidation, + /// Fake validation error config. + pub fake_validation_error: FakeCandidateValidationError, + /// The probability of behaving maliciously. + pub percentage: u8, +} + +impl OverseerGen for DisputeValidCandidates { + fn generate( + &self, + connector: OverseerConnector, + args: OverseerGenArgs<'_, Spawner, RuntimeClient>, + ) -> Result< + (Overseer, Arc>>, OverseerHandle), + Error, + > + where + RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, + RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + Spawner: 'static + SpawnNamed + Clone + Unpin, + { + let spawner = args.spawner.clone(); + let validation_filter = ReplaceValidationResult::new( + self.fake_validation, + self.fake_validation_error, + f64::from(self.percentage), + SpawnGlue(spawner.clone()), + ); + + prepared_overseer_builder(args)? + .replace_candidate_validation(move |cv_subsystem| { + InterceptedSubsystem::new(cv_subsystem, validation_filter) + }) + .build_with_connector(connector) + .map_err(|e| e.into()) + } +} diff --git a/polkadot/node/malus/src/variants/mod.rs b/polkadot/node/malus/src/variants/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..3789f33ac98be40d979e331dc67956a48711d4e4 --- /dev/null +++ b/polkadot/node/malus/src/variants/mod.rs @@ -0,0 +1,29 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Collection of behavior variants. + +mod back_garbage_candidate; +mod common; +mod dispute_valid_candidates; +mod suggest_garbage_candidate; + +pub(crate) use self::{ + back_garbage_candidate::{BackGarbageCandidateOptions, BackGarbageCandidates}, + dispute_valid_candidates::{DisputeAncestorOptions, DisputeValidCandidates}, + suggest_garbage_candidate::{SuggestGarbageCandidateOptions, SuggestGarbageCandidates}, +}; +pub(crate) use common::*; diff --git a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs new file mode 100644 index 0000000000000000000000000000000000000000..cf0ff5f809d8c31df07a13fb3eac0661f8486917 --- /dev/null +++ b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs @@ -0,0 +1,304 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A malicious node that stores bogus availability chunks, preventing others from +//! doing approval voting. This should lead to disputes depending if the validator +//! has fetched a malicious chunk. +//! +//! Attention: For usage with `zombienet` only! + +#![allow(missing_docs)] + +use polkadot_cli::{ + prepared_overseer_builder, + service::{ + AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, HeaderBackend, Overseer, + OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, ParachainHost, + ProvideRuntimeApi, + }, + Cli, +}; +use polkadot_node_core_candidate_validation::find_validation_data; +use polkadot_node_primitives::{AvailableData, BlockData, PoV}; +use polkadot_node_subsystem_types::DefaultSubsystemClient; +use polkadot_primitives::{CandidateDescriptor, CandidateReceipt}; + +use polkadot_node_subsystem_util::request_validators; +use sp_core::traits::SpawnNamed; + +use rand::distributions::{Bernoulli, Distribution}; + +// Filter wrapping related types. +use crate::{ + interceptor::*, + shared::{MALICIOUS_POV, MALUS}, + variants::{ + create_fake_candidate_commitments, FakeCandidateValidation, FakeCandidateValidationError, + ReplaceValidationResult, + }, +}; + +// Import extra types relevant to the particular +// subsystem. +use polkadot_node_subsystem::{messages::CandidateBackingMessage, SpawnGlue}; + +use std::sync::Arc; + +/// Replace outgoing approval messages with disputes. +#[derive(Clone)] +struct NoteCandidate { + spawner: Spawner, + percentage: f64, +} + +impl MessageInterceptor for NoteCandidate +where + Sender: overseer::CandidateBackingSenderTrait + Clone + Send + 'static, + Spawner: overseer::gen::Spawner + Clone + 'static, +{ + type Message = CandidateBackingMessage; + + /// Intercept incoming `Second` requests from the `collator-protocol` subsystem. + fn intercept_incoming( + &self, + subsystem_sender: &mut Sender, + msg: FromOrchestra, + ) -> Option> { + match msg { + FromOrchestra::Communication { + msg: + CandidateBackingMessage::Second( + relay_parent, + ref candidate, + ref _validation_data, + ref _pov, + ), + } => { + gum::debug!( + target: MALUS, + candidate_hash = ?candidate.hash(), + ?relay_parent, + "Received request to second candidate", + ); + + // Need to draw value from Bernoulli distribution with given probability of success + // defined by the clap parameter. Note that clap parameter must be f64 since this is + // expected by the Bernoulli::new() function. It must be converted from u8, due to + // the lack of support for the .range() call on u64 in the clap crate. + let distribution = Bernoulli::new(self.percentage / 100.0) + .expect("Invalid probability! Percentage must be in range [0..=100]."); + + // Draw a random boolean from the Bernoulli distribution with probability of true + // equal to `p`. We use `rand::thread_rng` as the source of randomness. + let generate_malicious_candidate = distribution.sample(&mut rand::thread_rng()); + + if generate_malicious_candidate { + gum::debug!(target: MALUS, "😈 Suggesting malicious candidate.",); + + let pov = PoV { block_data: BlockData(MALICIOUS_POV.into()) }; + + let (sender, receiver) = std::sync::mpsc::channel(); + let mut new_sender = subsystem_sender.clone(); + let _candidate = candidate.clone(); + self.spawner.spawn_blocking( + "malus-get-validation-data", + Some("malus"), + Box::pin(async move { + gum::trace!(target: MALUS, "Requesting validators"); + let n_validators = request_validators(relay_parent, &mut new_sender) + .await + .await + .unwrap() + .unwrap() + .len(); + gum::trace!(target: MALUS, "Validators {}", n_validators); + match find_validation_data(&mut new_sender, &_candidate.descriptor()) + .await + { + Ok(Some((validation_data, validation_code))) => { + sender + .send(Some(( + validation_data, + validation_code, + n_validators, + ))) + .expect("channel is still open"); + }, + _ => { + sender.send(None).expect("channel is still open"); + }, + } + }), + ); + + let (validation_data, validation_code, n_validators) = + receiver.recv().unwrap()?; + + let validation_data_hash = validation_data.hash(); + let validation_code_hash = validation_code.hash(); + let validation_data_relay_parent_number = validation_data.relay_parent_number; + + gum::trace!( + target: MALUS, + candidate_hash = ?candidate.hash(), + ?relay_parent, + ?n_validators, + ?validation_data_hash, + ?validation_code_hash, + ?validation_data_relay_parent_number, + "Fetched validation data." + ); + + let malicious_available_data = AvailableData { + pov: Arc::new(pov.clone()), + validation_data: validation_data.clone(), + }; + + let pov_hash = pov.hash(); + let erasure_root = { + let chunks = erasure::obtain_chunks_v1( + n_validators as usize, + &malicious_available_data, + ) + .unwrap(); + + let branches = erasure::branches(chunks.as_ref()); + branches.root() + }; + + let (collator_id, collator_signature) = { + use polkadot_primitives::CollatorPair; + use sp_core::crypto::Pair; + + let collator_pair = CollatorPair::generate().0; + let signature_payload = polkadot_primitives::collator_signature_payload( + &relay_parent, + &candidate.descriptor().para_id, + &validation_data_hash, + &pov_hash, + &validation_code_hash, + ); + + (collator_pair.public(), collator_pair.sign(&signature_payload)) + }; + + let malicious_commitments = create_fake_candidate_commitments( + &malicious_available_data.validation_data, + ); + + let malicious_candidate = CandidateReceipt { + descriptor: CandidateDescriptor { + para_id: candidate.descriptor().para_id, + relay_parent, + collator: collator_id, + persisted_validation_data_hash: validation_data_hash, + pov_hash, + erasure_root, + signature: collator_signature, + para_head: malicious_commitments.head_data.hash(), + validation_code_hash, + }, + commitments_hash: malicious_commitments.hash(), + }; + let malicious_candidate_hash = malicious_candidate.hash(); + + let message = FromOrchestra::Communication { + msg: CandidateBackingMessage::Second( + relay_parent, + malicious_candidate, + validation_data, + pov, + ), + }; + + gum::info!( + target: MALUS, + candidate_hash = ?candidate.hash(), + "😈 Intercepted CandidateBackingMessage::Second and created malicious candidate with hash: {:?}", + &malicious_candidate_hash + ); + Some(message) + } else { + Some(msg) + } + }, + FromOrchestra::Communication { msg } => Some(FromOrchestra::Communication { msg }), + FromOrchestra::Signal(signal) => Some(FromOrchestra::Signal(signal)), + } + } +} + +#[derive(Debug, clap::Parser)] +#[clap(rename_all = "kebab-case")] +#[allow(missing_docs)] +pub struct SuggestGarbageCandidateOptions { + /// Determines the percentage of malicious candidates that are suggested by malus, + /// based on the total number of intercepted CandidateBacking + /// Must be in the range [0..=100]. + #[clap(short, long, ignore_case = true, default_value_t = 100, value_parser = clap::value_parser!(u8).range(0..=100))] + pub percentage: u8, + + #[clap(flatten)] + pub cli: Cli, +} + +/// Garbage candidate implementation wrapper which implements `OverseerGen` glue. +pub(crate) struct SuggestGarbageCandidates { + /// The probability of behaving maliciously. + pub percentage: u8, +} + +impl OverseerGen for SuggestGarbageCandidates { + fn generate( + &self, + connector: OverseerConnector, + args: OverseerGenArgs<'_, Spawner, RuntimeClient>, + ) -> Result< + (Overseer, Arc>>, OverseerHandle), + Error, + > + where + RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, + RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + Spawner: 'static + SpawnNamed + Clone + Unpin, + { + gum::info!( + target: MALUS, + "😈 Started Malus node with a {:?} percent chance of behaving maliciously for a given candidate.", + &self.percentage, + ); + + let note_candidate = NoteCandidate { + spawner: SpawnGlue(args.spawner.clone()), + percentage: f64::from(self.percentage), + }; + let fake_valid_probability = 100.0; + let validation_filter = ReplaceValidationResult::new( + FakeCandidateValidation::BackingAndApprovalValid, + FakeCandidateValidationError::InvalidOutputs, + fake_valid_probability, + SpawnGlue(args.spawner.clone()), + ); + + prepared_overseer_builder(args)? + .replace_candidate_backing(move |cb| InterceptedSubsystem::new(cb, note_candidate)) + .replace_candidate_validation(move |cb| { + InterceptedSubsystem::new(cb, validation_filter) + }) + .build_with_connector(connector) + .map_err(|e| e.into()) + } +} diff --git a/polkadot/node/metrics/Cargo.toml b/polkadot/node/metrics/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..fdb42a1dcde02905317f2aae8349021f1255f765 --- /dev/null +++ b/polkadot/node/metrics/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "polkadot-node-metrics" +description = "Subsystem metric helpers" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +futures-timer = "3.0.2" +gum = { package = "tracing-gum", path = "../gum" } + +metered = { package = "prioritized-metered-channel", version = "0.2.0" } + +# Both `sc-service` and `sc-cli` are required by runtime metrics `logger_hook()`. +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } + +substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +codec = { package = "parity-scale-codec", version = "3.6.1" } +primitives = { package = "polkadot-primitives", path = "../../primitives/" } +bs58 = { version = "0.4.0", features = ["alloc"] } +log = "0.4.17" + +[dev-dependencies] +assert_cmd = "2.0.4" +tempfile = "3.2.0" +hyper = { version = "0.14.20", default-features = false, features = ["http1", "tcp"] } +tokio = "1.24.2" +polkadot-test-service = { path = "../test/service", features=["runtime-metrics"]} +substrate-test-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +prometheus-parse = {version = "0.2.2"} + +[features] +default = [] +runtime-metrics = [] +runtime-benchmarks = [] diff --git a/polkadot/node/metrics/README.md b/polkadot/node/metrics/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cc88884f21422317b4e5ecb02b9f0c8555a523f7 --- /dev/null +++ b/polkadot/node/metrics/README.md @@ -0,0 +1,9 @@ +# polkadot-node-metrics + +## Testing + +Before running `cargo test` in this crate, make sure the worker binaries are built first. This can be done with: + +```sh +cargo build --bin polkadot-execute-worker --bin polkadot-prepare-worker +``` diff --git a/polkadot/node/metrics/src/lib.rs b/polkadot/node/metrics/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..9cb0f289a580ccadc68d2dd8197c46f162845b22 --- /dev/null +++ b/polkadot/node/metrics/src/lib.rs @@ -0,0 +1,86 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Metrics helpers +//! +//! Collects a bunch of metrics providers and related features such as +//! `Metronome` for usage with metrics collections. +//! +//! This crate also reexports Prometheus metric types which are expected to be implemented by +//! subsystems. + +#![deny(missing_docs)] +#![deny(unused_imports)] + +pub use metered; + +/// Cyclic metric collection support. +pub mod metronome; +pub use self::metronome::Metronome; + +#[cfg(feature = "runtime-metrics")] +pub mod runtime; +#[cfg(feature = "runtime-metrics")] +pub use self::runtime::logger_hook; + +/// Export a dummy logger hook when the `runtime-metrics` feature is not enabled. +#[cfg(not(feature = "runtime-metrics"))] +pub fn logger_hook() -> impl FnOnce(&mut sc_cli::LoggerBuilder, &sc_service::Configuration) { + |_logger_builder, _config| {} +} + +/// This module reexports Prometheus types and defines the [`Metrics`](metrics::Metrics) trait. +pub mod metrics { + /// Reexport Substrate Prometheus types. + pub use substrate_prometheus_endpoint as prometheus; + + /// Subsystem- or job-specific Prometheus metrics. + /// + /// Usually implemented as a wrapper for `Option` + /// to ensure `Default` bounds or as a dummy type (). + /// Prometheus metrics internally hold an `Arc` reference, so cloning them is fine. + pub trait Metrics: Default + Clone { + /// Try to register metrics in the Prometheus registry. + fn try_register( + registry: &prometheus::Registry, + ) -> Result; + + /// Convenience method to register metrics in the optional Prometheus registry. + /// + /// If no registry is provided, returns `Default::default()`. Otherwise, returns the same + /// thing that `try_register` does. + fn register( + registry: Option<&prometheus::Registry>, + ) -> Result { + match registry { + None => Ok(Self::default()), + Some(registry) => Self::try_register(registry), + } + } + } + + // dummy impl + impl Metrics for () { + fn try_register( + _registry: &prometheus::Registry, + ) -> Result<(), prometheus::PrometheusError> { + Ok(()) + } + } +} + +#[cfg(all(feature = "runtime-metrics", not(feature = "runtime-benchmarks"), test))] +mod tests; diff --git a/polkadot/node/metrics/src/metronome.rs b/polkadot/node/metrics/src/metronome.rs new file mode 100644 index 0000000000000000000000000000000000000000..a379062c9cb1fcf2c0e5d20e5d77a3025dd55f63 --- /dev/null +++ b/polkadot/node/metrics/src/metronome.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use futures::prelude::*; +use futures_timer::Delay; +use std::{ + pin::Pin, + task::{Context, Poll}, + time::Duration, +}; + +#[derive(Copy, Clone)] +enum MetronomeState { + Snooze, + SetAlarm, +} + +/// Create a stream of ticks with a defined cycle duration. +pub struct Metronome { + delay: Delay, + period: Duration, + state: MetronomeState, +} + +impl Metronome { + /// Create a new metronome source with a defined cycle duration. + pub fn new(cycle: Duration) -> Self { + let period = cycle.into(); + Self { period, delay: Delay::new(period), state: MetronomeState::Snooze } + } +} + +impl futures::Stream for Metronome { + type Item = (); + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + loop { + match self.state { + MetronomeState::SetAlarm => { + let val = self.period; + self.delay.reset(val); + self.state = MetronomeState::Snooze; + }, + MetronomeState::Snooze => { + if !Pin::new(&mut self.delay).poll(cx).is_ready() { + break + } + self.state = MetronomeState::SetAlarm; + return Poll::Ready(Some(())) + }, + } + } + Poll::Pending + } +} diff --git a/polkadot/node/metrics/src/runtime/mod.rs b/polkadot/node/metrics/src/runtime/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..7cd24b01c117f24d9c4c41f367ab3b53f8aa504c --- /dev/null +++ b/polkadot/node/metrics/src/runtime/mod.rs @@ -0,0 +1,226 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Runtime Metrics helpers. +//! +//! A runtime metric provider implementation that builds on top of Substrate wasm +//! tracing support. This requires that the custom profiler (`TraceHandler`) to be +//! registered in substrate via a `logger_hook()`. Events emitted from runtime are +//! then captured/processed by the `TraceHandler` implementation. +//! +//! Don't add logs in this file because it gets executed before the logger is +//! initialized and they won't be delivered. Add println! statements if you need +//! to debug this code. + +#![cfg(feature = "runtime-metrics")] + +use codec::Decode; +use primitives::{ + metric_definitions::{CounterDefinition, CounterVecDefinition, HistogramDefinition}, + RuntimeMetricLabelValues, RuntimeMetricOp, RuntimeMetricUpdate, +}; +use std::{ + collections::hash_map::HashMap, + sync::{Arc, Mutex, MutexGuard}, +}; +use substrate_prometheus_endpoint::{ + register, Counter, CounterVec, Histogram, HistogramOpts, Opts, PrometheusError, Registry, U64, +}; +mod parachain; + +/// Holds the registered Prometheus metric collections. +#[derive(Clone, Default)] +pub struct Metrics { + counter_vecs: Arc>>>, + counters: Arc>>>, + histograms: Arc>>, +} + +/// Runtime metrics wrapper. +#[derive(Clone)] +pub struct RuntimeMetricsProvider(Registry, Metrics); + +impl RuntimeMetricsProvider { + /// Creates new instance. + pub fn new(metrics_registry: Registry) -> Self { + Self(metrics_registry, Metrics::default()) + } + + /// Register a counter vec metric. + pub fn register_countervec(&self, countervec: CounterVecDefinition) { + self.with_counter_vecs_lock_held(|mut hashmap| { + hashmap.entry(countervec.name.to_owned()).or_insert(register( + CounterVec::new( + Opts::new(countervec.name, countervec.description), + countervec.labels, + )?, + &self.0, + )?); + Ok(()) + }) + } + + /// Register a counter metric. + pub fn register_counter(&self, counter: CounterDefinition) { + self.with_counters_lock_held(|mut hashmap| { + hashmap + .entry(counter.name.to_owned()) + .or_insert(register(Counter::new(counter.name, counter.description)?, &self.0)?); + return Ok(()) + }) + } + + /// Register a histogram metric + pub fn register_histogram(&self, hist: HistogramDefinition) { + self.with_histograms_lock_held(|mut hashmap| { + hashmap.entry(hist.name.to_owned()).or_insert(register( + Histogram::with_opts( + HistogramOpts::new(hist.name, hist.description).buckets(hist.buckets.to_vec()), + )?, + &self.0, + )?); + return Ok(()) + }) + } + + /// Increment a counter with labels by a value + pub fn inc_counter_vec_by(&self, name: &str, value: u64, labels: &RuntimeMetricLabelValues) { + self.with_counter_vecs_lock_held(|mut hashmap| { + hashmap.entry(name.to_owned()).and_modify(|counter_vec| { + counter_vec.with_label_values(&labels.as_str_vec()).inc_by(value) + }); + + Ok(()) + }); + } + + /// Increment a counter by a value. + pub fn inc_counter_by(&self, name: &str, value: u64) { + self.with_counters_lock_held(|mut hashmap| { + hashmap + .entry(name.to_owned()) + .and_modify(|counter_vec| counter_vec.inc_by(value)); + Ok(()) + }) + } + + /// Observe a histogram. `value` should be in `ns`. + pub fn observe_histogram(&self, name: &str, value: u128) { + self.with_histograms_lock_held(|mut hashmap| { + hashmap + .entry(name.to_owned()) + .and_modify(|histogram| histogram.observe(value as f64 / 1_000_000_000.0)); // ns to sec + Ok(()) + }) + } + + fn with_counters_lock_held(&self, do_something: F) + where + F: FnOnce(MutexGuard<'_, HashMap>>) -> Result<(), PrometheusError>, + { + let _ = self.1.counters.lock().map(do_something).or_else(|error| Err(error)); + } + + fn with_counter_vecs_lock_held(&self, do_something: F) + where + F: FnOnce(MutexGuard<'_, HashMap>>) -> Result<(), PrometheusError>, + { + let _ = self.1.counter_vecs.lock().map(do_something).or_else(|error| Err(error)); + } + + fn with_histograms_lock_held(&self, do_something: F) + where + F: FnOnce(MutexGuard<'_, HashMap>) -> Result<(), PrometheusError>, + { + let _ = self.1.histograms.lock().map(do_something).or_else(|error| Err(error)); + } +} + +impl sc_tracing::TraceHandler for RuntimeMetricsProvider { + fn handle_span(&self, _span: &sc_tracing::SpanDatum) {} + fn handle_event(&self, event: &sc_tracing::TraceEvent) { + if event + .values + .string_values + .get("target") + .unwrap_or(&String::default()) + .ne("metrics") + { + return + } + + if let Some(update_op_bs58) = event.values.string_values.get("params") { + // Deserialize the metric update struct. + match RuntimeMetricUpdate::decode( + &mut RuntimeMetricsProvider::parse_event_params(&update_op_bs58) + .unwrap_or_default() + .as_slice(), + ) { + Ok(update_op) => { + self.parse_metric_update(update_op); + }, + Err(_) => { + // do nothing + }, + } + } + } +} + +impl RuntimeMetricsProvider { + // Parse end execute the update operation. + fn parse_metric_update(&self, update: RuntimeMetricUpdate) { + match update.op { + RuntimeMetricOp::IncrementCounterVec(value, ref labels) => + self.inc_counter_vec_by(update.metric_name(), value, labels), + RuntimeMetricOp::IncrementCounter(value) => + self.inc_counter_by(update.metric_name(), value), + RuntimeMetricOp::ObserveHistogram(value) => + self.observe_histogram(update.metric_name(), value), + } + } + + // Returns the `bs58` encoded metric update operation. + fn parse_event_params(event_params: &str) -> Option> { + // Shave " }" suffix. + let new_len = event_params.len().saturating_sub(2); + let event_params = &event_params[..new_len]; + + // Shave " { update_op: " prefix. + const SKIP_CHARS: &'static str = " { update_op: "; + if SKIP_CHARS.len() < event_params.len() { + if SKIP_CHARS.eq_ignore_ascii_case(&event_params[..SKIP_CHARS.len()]) { + return bs58::decode(&event_params[SKIP_CHARS.len()..].as_bytes()).into_vec().ok() + } + } + + // No event was parsed + None + } +} + +/// Returns the custom profiling closure that we'll apply to the `LoggerBuilder`. +pub fn logger_hook() -> impl FnOnce(&mut sc_cli::LoggerBuilder, &sc_service::Configuration) -> () { + |logger_builder, config| { + if config.prometheus_registry().is_none() { + return + } + let registry = config.prometheus_registry().cloned().unwrap(); + let metrics_provider = RuntimeMetricsProvider::new(registry); + parachain::register_metrics(&metrics_provider); + logger_builder.with_custom_profiling(Box::new(metrics_provider)); + } +} diff --git a/polkadot/node/metrics/src/runtime/parachain.rs b/polkadot/node/metrics/src/runtime/parachain.rs new file mode 100644 index 0000000000000000000000000000000000000000..becc7c64d59d08b4896ee102d5c27a72e61cfd08 --- /dev/null +++ b/polkadot/node/metrics/src/runtime/parachain.rs @@ -0,0 +1,38 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Client side declaration and registration of the parachain Prometheus metrics. +//! All of the metrics have a correspondent runtime metric definition. + +use crate::runtime::RuntimeMetricsProvider; +use primitives::metric_definitions::{ + PARACHAIN_CREATE_INHERENT_BITFIELDS_SIGNATURE_CHECKS, + PARACHAIN_INHERENT_DATA_BITFIELDS_PROCESSED, PARACHAIN_INHERENT_DATA_CANDIDATES_PROCESSED, + PARACHAIN_INHERENT_DATA_DISPUTE_SETS_PROCESSED, PARACHAIN_INHERENT_DATA_WEIGHT, + PARACHAIN_VERIFY_DISPUTE_SIGNATURE, +}; + +/// Register the parachain runtime metrics. +pub fn register_metrics(runtime_metrics_provider: &RuntimeMetricsProvider) { + runtime_metrics_provider.register_counter(PARACHAIN_INHERENT_DATA_BITFIELDS_PROCESSED); + + runtime_metrics_provider.register_countervec(PARACHAIN_INHERENT_DATA_WEIGHT); + runtime_metrics_provider.register_countervec(PARACHAIN_INHERENT_DATA_DISPUTE_SETS_PROCESSED); + runtime_metrics_provider.register_countervec(PARACHAIN_INHERENT_DATA_CANDIDATES_PROCESSED); + runtime_metrics_provider + .register_countervec(PARACHAIN_CREATE_INHERENT_BITFIELDS_SIGNATURE_CHECKS); + runtime_metrics_provider.register_histogram(PARACHAIN_VERIFY_DISPUTE_SIGNATURE); +} diff --git a/polkadot/node/metrics/src/tests.rs b/polkadot/node/metrics/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..68abfeebc12446e080a5b24d1460f4e54f12e044 --- /dev/null +++ b/polkadot/node/metrics/src/tests.rs @@ -0,0 +1,92 @@ +// Copyright (C) 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 . + +//! Polkadot runtime metrics integration test. + +use hyper::{Client, Uri}; +use polkadot_test_service::{node_config, run_validator_node, test_prometheus_config}; +use primitives::metric_definitions::PARACHAIN_INHERENT_DATA_BITFIELDS_PROCESSED; +use sp_keyring::AccountKeyring::*; +use std::collections::HashMap; + +const DEFAULT_PROMETHEUS_PORT: u16 = 9616; + +#[substrate_test_utils::test(flavor = "multi_thread")] +async fn runtime_can_publish_metrics() { + let mut alice_config = + node_config(|| {}, tokio::runtime::Handle::current(), Alice, Vec::new(), true); + + // Enable Prometheus metrics for Alice. + alice_config.prometheus_config = Some(test_prometheus_config(DEFAULT_PROMETHEUS_PORT)); + + let mut builder = sc_cli::LoggerBuilder::new(""); + + // Enable profiling with `wasm_tracing` target. + builder.with_profiling(Default::default(), String::from("wasm_tracing=trace")); + + // Setup the runtime metrics provider. + crate::logger_hook()(&mut builder, &alice_config); + + builder.init().expect("Failed to set up the logger"); + + // Start validator Alice. + let alice = run_validator_node(alice_config, None); + + let bob_config = + node_config(|| {}, tokio::runtime::Handle::current(), Bob, vec![alice.addr.clone()], true); + + // Start validator Bob. + let _bob = run_validator_node(bob_config, None); + + // Wait for Alice to see two finalized blocks. + alice.wait_for_finalized_blocks(2).await; + + let metrics_uri = format!("http://localhost:{}/metrics", DEFAULT_PROMETHEUS_PORT); + let metrics = scrape_prometheus_metrics(&metrics_uri).await; + + // There should be at least 1 bitfield processed by now. + assert!( + *metrics + .get(&PARACHAIN_INHERENT_DATA_BITFIELDS_PROCESSED.name.to_owned()) + .unwrap() > 1 + ); +} + +async fn scrape_prometheus_metrics(metrics_uri: &str) -> HashMap { + let res = Client::new() + .get(Uri::try_from(metrics_uri).expect("bad URI")) + .await + .expect("GET request failed"); + + // Retrieve the `HTTP` response body. + let body = String::from_utf8( + hyper::body::to_bytes(res).await.expect("can't get body as bytes").to_vec(), + ) + .expect("body is not an UTF8 string"); + + let lines: Vec<_> = body.lines().map(|s| Ok(s.to_owned())).collect(); + prometheus_parse::Scrape::parse(lines.into_iter()) + .expect("Scraper failed to parse Prometheus metrics") + .samples + .into_iter() + .filter_map(|prometheus_parse::Sample { metric, value, .. }| match value { + prometheus_parse::Value::Counter(value) => Some((metric, value as u64)), + prometheus_parse::Value::Gauge(value) => Some((metric, value as u64)), + prometheus_parse::Value::Untyped(value) => Some((metric, value as u64)), + _ => None, + }) + .collect() +} diff --git a/polkadot/node/network/README.md b/polkadot/node/network/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e035485b85ec8cbf854251d870960ff36500e10e --- /dev/null +++ b/polkadot/node/network/README.md @@ -0,0 +1 @@ +This folder holds all networking subsystem implementations, each with their own crate. diff --git a/polkadot/node/network/approval-distribution/Cargo.toml b/polkadot/node/network/approval-distribution/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..bd683b3202856c8301af09dfa67a89a1aa420f4e --- /dev/null +++ b/polkadot/node/network/approval-distribution/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "polkadot-approval-distribution" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +polkadot-node-metrics = { path = "../../metrics" } +polkadot-node-network-protocol = { path = "../protocol" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-jaeger = { path = "../../jaeger" } +rand = "0.8" + +futures = "0.3.21" +futures-timer = "3.0.2" +gum = { package = "tracing-gum", path = "../../gum" } + +[dev-dependencies] +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["std"] } + +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +polkadot-primitives-test-helpers = { path = "../../../primitives/test-helpers" } + +assert_matches = "1.4.0" +schnorrkel = { version = "0.9.1", default-features = false } +rand_core = "0.5.1" # should match schnorrkel +rand_chacha = "0.3.1" +env_logger = "0.9.0" +log = "0.4.17" diff --git a/polkadot/node/network/approval-distribution/src/lib.rs b/polkadot/node/network/approval-distribution/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..ac525ea6faf3b77956c9ecd90a8b1de5466b7674 --- /dev/null +++ b/polkadot/node/network/approval-distribution/src/lib.rs @@ -0,0 +1,2127 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! [`ApprovalDistributionSubsystem`] implementation. +//! +//! https://w3f.github.io/parachain-implementers-guide/node/approval/approval-distribution.html + +#![warn(missing_docs)] + +use futures::{channel::oneshot, select, FutureExt as _}; +use polkadot_node_jaeger as jaeger; +use polkadot_node_network_protocol::{ + self as net_protocol, + grid_topology::{RandomRouting, RequiredRouting, SessionGridTopologies, SessionGridTopology}, + peer_set::{ValidationVersion, MAX_NOTIFICATION_SIZE}, + v1 as protocol_v1, vstaging as protocol_vstaging, PeerId, UnifiedReputationChange as Rep, + Versioned, VersionedValidationProtocol, View, +}; +use polkadot_node_primitives::approval::{ + AssignmentCert, BlockApprovalMeta, IndirectAssignmentCert, IndirectSignedApprovalVote, +}; +use polkadot_node_subsystem::{ + messages::{ + ApprovalCheckResult, ApprovalDistributionMessage, ApprovalVotingMessage, + AssignmentCheckResult, NetworkBridgeEvent, NetworkBridgeTxMessage, + }, + overseer, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, +}; +use polkadot_node_subsystem_util::reputation::{ReputationAggregator, REPUTATION_CHANGE_INTERVAL}; +use polkadot_primitives::{ + BlockNumber, CandidateIndex, Hash, SessionIndex, ValidatorIndex, ValidatorSignature, +}; +use rand::{CryptoRng, Rng, SeedableRng}; +use std::{ + collections::{hash_map, BTreeMap, HashMap, HashSet, VecDeque}, + time::Duration, +}; + +use self::metrics::Metrics; + +mod metrics; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &str = "parachain::approval-distribution"; + +const COST_UNEXPECTED_MESSAGE: Rep = + Rep::CostMinor("Peer sent an out-of-view assignment or approval"); +const COST_DUPLICATE_MESSAGE: Rep = Rep::CostMinorRepeated("Peer sent identical messages"); +const COST_ASSIGNMENT_TOO_FAR_IN_THE_FUTURE: Rep = + Rep::CostMinor("The vote was valid but too far in the future"); +const COST_INVALID_MESSAGE: Rep = Rep::CostMajor("The vote was bad"); + +const BENEFIT_VALID_MESSAGE: Rep = Rep::BenefitMinor("Peer sent a valid message"); +const BENEFIT_VALID_MESSAGE_FIRST: Rep = + Rep::BenefitMinorFirst("Valid message with new information"); + +/// The Approval Distribution subsystem. +pub struct ApprovalDistribution { + metrics: Metrics, +} + +/// Contains recently finalized +/// or those pruned due to finalization. +#[derive(Default)] +struct RecentlyOutdated { + buf: VecDeque, +} + +impl RecentlyOutdated { + fn note_outdated(&mut self, hash: Hash) { + const MAX_BUF_LEN: usize = 20; + + self.buf.push_back(hash); + + while self.buf.len() > MAX_BUF_LEN { + let _ = self.buf.pop_front(); + } + } + + fn is_recent_outdated(&self, hash: &Hash) -> bool { + self.buf.contains(hash) + } +} + +// In case the original gtid topology mechanisms don't work on their own, we need to trade bandwidth +// for protocol liveliness by introducing aggression. +// +// Aggression has 3 levels: +// +// * Aggression Level 0: The basic behaviors described above. +// * Aggression Level 1: The originator of a message sends to all peers. Other peers follow the +// rules above. +// * Aggression Level 2: All peers send all messages to all their row and column neighbors. This +// means that each validator will, on average, receive each message approximately `2*sqrt(n)` +// times. +// The aggression level of messages pertaining to a block increases when that block is unfinalized +// and is a child of the finalized block. +// This means that only one block at a time has its messages propagated with aggression > 0. +// +// A note on aggression thresholds: changes in propagation apply only to blocks which are the +// _direct descendants_ of the finalized block which are older than the given threshold, +// not to all blocks older than the threshold. Most likely, a few assignments struggle to +// be propagated in a single block and this holds up all of its descendants blocks. +// Accordingly, we only step on the gas for the block which is most obviously holding up finality. + +/// Aggression configuration representation +#[derive(Clone)] +struct AggressionConfig { + /// Aggression level 1: all validators send all their own messages to all peers. + l1_threshold: Option, + /// Aggression level 2: level 1 + all validators send all messages to all peers in the X and Y + /// dimensions. + l2_threshold: Option, + /// How often to re-send messages to all targeted recipients. + /// This applies to all unfinalized blocks. + resend_unfinalized_period: Option, +} + +impl AggressionConfig { + /// Returns `true` if lag is past threshold depending on the aggression level + fn should_trigger_aggression(&self, approval_checking_lag: BlockNumber) -> bool { + if let Some(t) = self.l1_threshold { + approval_checking_lag >= t + } else if let Some(t) = self.resend_unfinalized_period { + approval_checking_lag > 0 && approval_checking_lag % t == 0 + } else { + false + } + } +} + +impl Default for AggressionConfig { + fn default() -> Self { + AggressionConfig { + l1_threshold: Some(13), + l2_threshold: Some(28), + resend_unfinalized_period: Some(8), + } + } +} + +#[derive(PartialEq)] +enum Resend { + Yes, + No, +} + +/// Data stored on a per-peer basis. +#[derive(Debug)] +struct PeerData { + /// The peer's view. + view: View, + /// The peer's protocol version. + version: ValidationVersion, +} + +/// The [`State`] struct is responsible for tracking the overall state of the subsystem. +/// +/// It tracks metadata about our view of the unfinalized chain, +/// which assignments and approvals we have seen, and our peers' views. +#[derive(Default)] +struct State { + /// These two fields are used in conjunction to construct a view over the unfinalized chain. + blocks_by_number: BTreeMap>, + blocks: HashMap, + + /// Our view updates to our peers can race with `NewBlocks` updates. We store messages received + /// against the directly mentioned blocks in our view in this map until `NewBlocks` is + /// received. + /// + /// As long as the parent is already in the `blocks` map and `NewBlocks` messages aren't + /// delayed by more than a block length, this strategy will work well for mitigating the race. + /// This is also a race that occurs typically on local networks. + pending_known: HashMap>, + + /// Peer data is partially stored here, and partially inline within the [`BlockEntry`]s + peer_data: HashMap, + + /// Keeps a topology for various different sessions. + topologies: SessionGridTopologies, + + /// Tracks recently finalized blocks. + recent_outdated_blocks: RecentlyOutdated, + + /// Config for aggression. + aggression_config: AggressionConfig, + + /// `HashMap` from active leaves to spans + spans: HashMap, + + /// Current approval checking finality lag. + approval_checking_lag: BlockNumber, + + /// Aggregated reputation change + reputation: ReputationAggregator, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum MessageKind { + Assignment, + Approval, +} + +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +struct MessageSubject(Hash, CandidateIndex, ValidatorIndex); + +#[derive(Debug, Clone, Default)] +struct Knowledge { + // When there is no entry, this means the message is unknown + // When there is an entry with `MessageKind::Assignment`, the assignment is known. + // When there is an entry with `MessageKind::Approval`, the assignment and approval are known. + known_messages: HashMap, +} + +impl Knowledge { + fn contains(&self, message: &MessageSubject, kind: MessageKind) -> bool { + match (kind, self.known_messages.get(message)) { + (_, None) => false, + (MessageKind::Assignment, Some(_)) => true, + (MessageKind::Approval, Some(MessageKind::Assignment)) => false, + (MessageKind::Approval, Some(MessageKind::Approval)) => true, + } + } + + fn insert(&mut self, message: MessageSubject, kind: MessageKind) -> bool { + match self.known_messages.entry(message) { + hash_map::Entry::Vacant(vacant) => { + vacant.insert(kind); + true + }, + hash_map::Entry::Occupied(mut occupied) => match (*occupied.get(), kind) { + (MessageKind::Assignment, MessageKind::Assignment) => false, + (MessageKind::Approval, MessageKind::Approval) => false, + (MessageKind::Approval, MessageKind::Assignment) => false, + (MessageKind::Assignment, MessageKind::Approval) => { + *occupied.get_mut() = MessageKind::Approval; + true + }, + }, + } + } +} + +/// Information that has been circulated to and from a peer. +#[derive(Debug, Clone, Default)] +struct PeerKnowledge { + /// The knowledge we've sent to the peer. + sent: Knowledge, + /// The knowledge we've received from the peer. + received: Knowledge, +} + +impl PeerKnowledge { + fn contains(&self, message: &MessageSubject, kind: MessageKind) -> bool { + self.sent.contains(message, kind) || self.received.contains(message, kind) + } +} + +/// Information about blocks in our current view as well as whether peers know of them. +struct BlockEntry { + /// Peers who we know are aware of this block and thus, the candidates within it. + /// This maps to their knowledge of messages. + known_by: HashMap, + /// The number of the block. + number: BlockNumber, + /// The parent hash of the block. + parent_hash: Hash, + /// Our knowledge of messages. + knowledge: Knowledge, + /// A votes entry for each candidate indexed by [`CandidateIndex`]. + candidates: Vec, + /// The session index of this block. + session: SessionIndex, +} + +#[derive(Debug)] +enum ApprovalState { + Assigned(AssignmentCert), + Approved(AssignmentCert, ValidatorSignature), +} + +impl ApprovalState { + fn assignment_cert(&self) -> &AssignmentCert { + match *self { + ApprovalState::Assigned(ref cert) => cert, + ApprovalState::Approved(ref cert, _) => cert, + } + } + + fn approval_signature(&self) -> Option { + match *self { + ApprovalState::Assigned(_) => None, + ApprovalState::Approved(_, ref sig) => Some(sig.clone()), + } + } +} + +// routing state bundled with messages for the candidate. Corresponding assignments +// and approvals are stored together and should be routed in the same way, with +// assignments preceding approvals in all cases. +#[derive(Debug)] +struct MessageState { + required_routing: RequiredRouting, + local: bool, + random_routing: RandomRouting, + approval_state: ApprovalState, +} + +/// Information about candidates in the context of a particular block they are included in. +/// In other words, multiple `CandidateEntry`s may exist for the same candidate, +/// if it is included by multiple blocks - this is likely the case when there are forks. +#[derive(Debug, Default)] +struct CandidateEntry { + messages: HashMap, +} + +#[derive(Debug, Clone, PartialEq)] +enum MessageSource { + Peer(PeerId), + Local, +} + +impl MessageSource { + fn peer_id(&self) -> Option { + match self { + Self::Peer(id) => Some(*id), + Self::Local => None, + } + } +} + +enum PendingMessage { + Assignment(IndirectAssignmentCert, CandidateIndex), + Approval(IndirectSignedApprovalVote), +} + +#[overseer::contextbounds(ApprovalDistribution, prefix = self::overseer)] +impl State { + async fn handle_network_msg( + &mut self, + ctx: &mut Context, + metrics: &Metrics, + event: NetworkBridgeEvent, + rng: &mut (impl CryptoRng + Rng), + ) { + match event { + NetworkBridgeEvent::PeerConnected(peer_id, role, version, _) => { + // insert a blank view if none already present + gum::trace!(target: LOG_TARGET, ?peer_id, ?role, "Peer connected"); + let version = match ValidationVersion::try_from(version).ok() { + Some(v) => v, + None => { + // sanity: network bridge is supposed to detect this already. + gum::error!( + target: LOG_TARGET, + ?peer_id, + ?version, + "Unsupported protocol version" + ); + return + }, + }; + + self.peer_data + .entry(peer_id) + .or_insert_with(|| PeerData { version, view: Default::default() }); + }, + NetworkBridgeEvent::PeerDisconnected(peer_id) => { + gum::trace!(target: LOG_TARGET, ?peer_id, "Peer disconnected"); + self.peer_data.remove(&peer_id); + self.blocks.iter_mut().for_each(|(_hash, entry)| { + entry.known_by.remove(&peer_id); + }) + }, + NetworkBridgeEvent::NewGossipTopology(topology) => { + self.handle_new_session_topology( + ctx, + topology.session, + topology.topology, + topology.local_index, + ) + .await; + }, + NetworkBridgeEvent::PeerViewChange(peer_id, view) => { + self.handle_peer_view_change(ctx, metrics, peer_id, view, rng).await; + }, + NetworkBridgeEvent::OurViewChange(view) => { + gum::trace!(target: LOG_TARGET, ?view, "Own view change"); + for head in view.iter() { + if !self.blocks.contains_key(head) { + self.pending_known.entry(*head).or_default(); + } + } + + self.pending_known.retain(|h, _| { + let live = view.contains(h); + if !live { + gum::trace!( + target: LOG_TARGET, + block_hash = ?h, + "Cleaning up stale pending messages", + ); + } + live + }); + }, + NetworkBridgeEvent::PeerMessage(peer_id, msg) => { + self.process_incoming_peer_message(ctx, metrics, peer_id, msg, rng).await; + }, + NetworkBridgeEvent::UpdatedAuthorityIds { .. } => { + // The approval-distribution subsystem doesn't deal with `AuthorityDiscoveryId`s. + }, + } + } + + async fn handle_new_blocks( + &mut self, + ctx: &mut Context, + metrics: &Metrics, + metas: Vec, + rng: &mut (impl CryptoRng + Rng), + ) { + let mut new_hashes = HashSet::new(); + for meta in &metas { + let mut span = self + .spans + .get(&meta.hash) + .map(|span| span.child(&"handle-new-blocks")) + .unwrap_or_else(|| jaeger::Span::new(meta.hash, &"handle-new-blocks")) + .with_string_tag("block-hash", format!("{:?}", meta.hash)) + .with_stage(jaeger::Stage::ApprovalDistribution); + + match self.blocks.entry(meta.hash) { + hash_map::Entry::Vacant(entry) => { + let candidates_count = meta.candidates.len(); + span.add_uint_tag("candidates-count", candidates_count as u64); + let mut candidates = Vec::with_capacity(candidates_count); + candidates.resize_with(candidates_count, Default::default); + + entry.insert(BlockEntry { + known_by: HashMap::new(), + number: meta.number, + parent_hash: meta.parent_hash, + knowledge: Knowledge::default(), + candidates, + session: meta.session, + }); + + self.topologies.inc_session_refs(meta.session); + + new_hashes.insert(meta.hash); + + // In case there are duplicates, we should only set this if the entry + // was vacant. + self.blocks_by_number.entry(meta.number).or_default().push(meta.hash); + }, + _ => continue, + } + } + + gum::debug!( + target: LOG_TARGET, + "Got new blocks {:?}", + metas.iter().map(|m| (m.hash, m.number)).collect::>(), + ); + + { + let sender = ctx.sender(); + for (peer_id, data) in self.peer_data.iter() { + let intersection = data.view.iter().filter(|h| new_hashes.contains(h)); + let view_intersection = + View::new(intersection.cloned(), data.view.finalized_number); + Self::unify_with_peer( + sender, + metrics, + &mut self.blocks, + &self.topologies, + self.peer_data.len(), + *peer_id, + data.version, + view_intersection, + rng, + ) + .await; + } + + let pending_now_known = self + .pending_known + .keys() + .filter(|k| self.blocks.contains_key(k)) + .copied() + .collect::>(); + + let to_import = pending_now_known + .into_iter() + .inspect(|h| { + gum::trace!( + target: LOG_TARGET, + block_hash = ?h, + "Extracting pending messages for new block" + ) + }) + .filter_map(|k| self.pending_known.remove(&k)) + .flatten() + .collect::>(); + + if !to_import.is_empty() { + gum::debug!( + target: LOG_TARGET, + num = to_import.len(), + "Processing pending assignment/approvals", + ); + + let _timer = metrics.time_import_pending_now_known(); + + for (peer_id, message) in to_import { + match message { + PendingMessage::Assignment(assignment, claimed_index) => { + self.import_and_circulate_assignment( + ctx, + metrics, + MessageSource::Peer(peer_id), + assignment, + claimed_index, + rng, + ) + .await; + }, + PendingMessage::Approval(approval_vote) => { + self.import_and_circulate_approval( + ctx, + metrics, + MessageSource::Peer(peer_id), + approval_vote, + ) + .await; + }, + } + } + } + } + + self.enable_aggression(ctx, Resend::Yes, metrics).await; + } + + async fn handle_new_session_topology( + &mut self, + ctx: &mut Context, + session: SessionIndex, + topology: SessionGridTopology, + local_index: Option, + ) { + if local_index.is_none() { + // this subsystem only matters to validators. + return + } + + self.topologies.insert_topology(session, topology, local_index); + let topology = self.topologies.get_topology(session).expect("just inserted above; qed"); + + adjust_required_routing_and_propagate( + ctx, + &self.peer_data, + &mut self.blocks, + &self.topologies, + |block_entry| block_entry.session == session, + |required_routing, local, validator_index| { + if *required_routing == RequiredRouting::PendingTopology { + *required_routing = topology + .local_grid_neighbors() + .required_routing_by_index(*validator_index, local); + } + }, + ) + .await; + } + + async fn process_incoming_peer_message( + &mut self, + ctx: &mut Context, + metrics: &Metrics, + peer_id: PeerId, + msg: net_protocol::ApprovalDistributionMessage, + rng: &mut R, + ) where + R: CryptoRng + Rng, + { + match msg { + Versioned::V1(protocol_v1::ApprovalDistributionMessage::Assignments(assignments)) | + Versioned::VStaging(protocol_vstaging::ApprovalDistributionMessage::Assignments( + assignments, + )) => { + gum::trace!( + target: LOG_TARGET, + peer_id = %peer_id, + num = assignments.len(), + "Processing assignments from a peer", + ); + for (assignment, claimed_index) in assignments.into_iter() { + if let Some(pending) = self.pending_known.get_mut(&assignment.block_hash) { + let message_subject = MessageSubject( + assignment.block_hash, + claimed_index, + assignment.validator, + ); + + gum::trace!( + target: LOG_TARGET, + %peer_id, + ?message_subject, + "Pending assignment", + ); + + pending + .push((peer_id, PendingMessage::Assignment(assignment, claimed_index))); + + continue + } + + self.import_and_circulate_assignment( + ctx, + metrics, + MessageSource::Peer(peer_id), + assignment, + claimed_index, + rng, + ) + .await; + } + }, + Versioned::V1(protocol_v1::ApprovalDistributionMessage::Approvals(approvals)) | + Versioned::VStaging(protocol_vstaging::ApprovalDistributionMessage::Approvals( + approvals, + )) => { + gum::trace!( + target: LOG_TARGET, + peer_id = %peer_id, + num = approvals.len(), + "Processing approvals from a peer", + ); + for approval_vote in approvals.into_iter() { + if let Some(pending) = self.pending_known.get_mut(&approval_vote.block_hash) { + let message_subject = MessageSubject( + approval_vote.block_hash, + approval_vote.candidate_index, + approval_vote.validator, + ); + + gum::trace!( + target: LOG_TARGET, + %peer_id, + ?message_subject, + "Pending approval", + ); + + pending.push((peer_id, PendingMessage::Approval(approval_vote))); + + continue + } + + self.import_and_circulate_approval( + ctx, + metrics, + MessageSource::Peer(peer_id), + approval_vote, + ) + .await; + } + }, + } + } + + // handle a peer view change: requires that the peer is already connected + // and has an entry in the `PeerData` struct. + async fn handle_peer_view_change( + &mut self, + ctx: &mut Context, + metrics: &Metrics, + peer_id: PeerId, + view: View, + rng: &mut R, + ) where + R: CryptoRng + Rng, + { + gum::trace!(target: LOG_TARGET, ?view, "Peer view change"); + let finalized_number = view.finalized_number; + let (peer_protocol_version, old_finalized_number) = match self + .peer_data + .get_mut(&peer_id) + .map(|d| (d.version, std::mem::replace(&mut d.view, view.clone()))) + { + Some((v, view)) => (v, view.finalized_number), + None => return, // unknown peer + }; + + // we want to prune every block known_by peer up to (including) view.finalized_number + let blocks = &mut self.blocks; + // the `BTreeMap::range` is constrained by stored keys + // so the loop won't take ages if the new finalized_number skyrockets + // but we need to make sure the range is not empty, otherwise it will panic + // it shouldn't be, we make sure of this in the network bridge + let range = old_finalized_number..=finalized_number; + if !range.is_empty() && !blocks.is_empty() { + self.blocks_by_number + .range(range) + .flat_map(|(_number, hashes)| hashes) + .for_each(|hash| { + if let Some(entry) = blocks.get_mut(hash) { + entry.known_by.remove(&peer_id); + } + }); + } + + Self::unify_with_peer( + ctx.sender(), + metrics, + &mut self.blocks, + &self.topologies, + self.peer_data.len(), + peer_id, + peer_protocol_version, + view, + rng, + ) + .await; + } + + async fn handle_block_finalized( + &mut self, + ctx: &mut Context, + metrics: &Metrics, + finalized_number: BlockNumber, + ) { + // we want to prune every block up to (including) finalized_number + // why +1 here? + // split_off returns everything after the given key, including the key + let split_point = finalized_number.saturating_add(1); + let mut old_blocks = self.blocks_by_number.split_off(&split_point); + + // after split_off old_blocks actually contains new blocks, we need to swap + std::mem::swap(&mut self.blocks_by_number, &mut old_blocks); + + // now that we pruned `self.blocks_by_number`, let's clean up `self.blocks` too + old_blocks.values().flatten().for_each(|relay_block| { + self.recent_outdated_blocks.note_outdated(*relay_block); + if let Some(block_entry) = self.blocks.remove(relay_block) { + self.topologies.dec_session_refs(block_entry.session); + } + self.spans.remove(&relay_block); + }); + + // If a block was finalized, this means we may need to move our aggression + // forward to the now oldest block(s). + self.enable_aggression(ctx, Resend::No, metrics).await; + } + + async fn import_and_circulate_assignment( + &mut self, + ctx: &mut Context, + metrics: &Metrics, + source: MessageSource, + assignment: IndirectAssignmentCert, + claimed_candidate_index: CandidateIndex, + rng: &mut R, + ) where + R: CryptoRng + Rng, + { + let _span = self + .spans + .get(&assignment.block_hash) + .map(|span| { + span.child(if source.peer_id().is_some() { + "peer-import-and-distribute-assignment" + } else { + "local-import-and-distribute-assignment" + }) + }) + .unwrap_or_else(|| jaeger::Span::new(&assignment.block_hash, "distribute-assignment")) + .with_string_tag("block-hash", format!("{:?}", assignment.block_hash)) + .with_optional_peer_id(source.peer_id().as_ref()) + .with_stage(jaeger::Stage::ApprovalDistribution); + + let block_hash = assignment.block_hash; + let validator_index = assignment.validator; + + let entry = match self.blocks.get_mut(&block_hash) { + Some(entry) => entry, + None => { + if let Some(peer_id) = source.peer_id() { + gum::trace!( + target: LOG_TARGET, + ?peer_id, + hash = ?block_hash, + ?validator_index, + "Unexpected assignment", + ); + if !self.recent_outdated_blocks.is_recent_outdated(&block_hash) { + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + COST_UNEXPECTED_MESSAGE, + ) + .await; + } + } + return + }, + }; + + // compute metadata on the assignment. + let message_subject = MessageSubject(block_hash, claimed_candidate_index, validator_index); + let message_kind = MessageKind::Assignment; + + if let Some(peer_id) = source.peer_id() { + // check if our knowledge of the peer already contains this assignment + match entry.known_by.entry(peer_id) { + hash_map::Entry::Occupied(mut peer_knowledge) => { + let peer_knowledge = peer_knowledge.get_mut(); + if peer_knowledge.contains(&message_subject, message_kind) { + // wasn't included before + if !peer_knowledge.received.insert(message_subject.clone(), message_kind) { + gum::debug!( + target: LOG_TARGET, + ?peer_id, + ?message_subject, + "Duplicate assignment", + ); + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + COST_DUPLICATE_MESSAGE, + ) + .await; + } + return + } + }, + hash_map::Entry::Vacant(_) => { + gum::debug!( + target: LOG_TARGET, + ?peer_id, + ?message_subject, + "Assignment from a peer is out of view", + ); + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + COST_UNEXPECTED_MESSAGE, + ) + .await; + }, + } + + // if the assignment is known to be valid, reward the peer + if entry.knowledge.contains(&message_subject, message_kind) { + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + BENEFIT_VALID_MESSAGE, + ) + .await; + if let Some(peer_knowledge) = entry.known_by.get_mut(&peer_id) { + gum::trace!(target: LOG_TARGET, ?peer_id, ?message_subject, "Known assignment"); + peer_knowledge.received.insert(message_subject, message_kind); + } + return + } + + let (tx, rx) = oneshot::channel(); + + ctx.send_message(ApprovalVotingMessage::CheckAndImportAssignment( + assignment.clone(), + claimed_candidate_index, + tx, + )) + .await; + + let timer = metrics.time_awaiting_approval_voting(); + let result = match rx.await { + Ok(result) => result, + Err(_) => { + gum::debug!(target: LOG_TARGET, "The approval voting subsystem is down"); + return + }, + }; + drop(timer); + + gum::trace!( + target: LOG_TARGET, + ?source, + ?message_subject, + ?result, + "Checked assignment", + ); + match result { + AssignmentCheckResult::Accepted => { + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + BENEFIT_VALID_MESSAGE_FIRST, + ) + .await; + entry.knowledge.known_messages.insert(message_subject.clone(), message_kind); + if let Some(peer_knowledge) = entry.known_by.get_mut(&peer_id) { + peer_knowledge.received.insert(message_subject.clone(), message_kind); + } + }, + AssignmentCheckResult::AcceptedDuplicate => { + // "duplicate" assignments aren't necessarily equal. + // There is more than one way each validator can be assigned to each core. + // cf. https://github.com/paritytech/polkadot/pull/2160#discussion_r557628699 + if let Some(peer_knowledge) = entry.known_by.get_mut(&peer_id) { + peer_knowledge.received.insert(message_subject.clone(), message_kind); + } + gum::debug!( + target: LOG_TARGET, + hash = ?block_hash, + ?peer_id, + "Got an `AcceptedDuplicate` assignment", + ); + return + }, + AssignmentCheckResult::TooFarInFuture => { + gum::debug!( + target: LOG_TARGET, + hash = ?block_hash, + ?peer_id, + "Got an assignment too far in the future", + ); + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + COST_ASSIGNMENT_TOO_FAR_IN_THE_FUTURE, + ) + .await; + return + }, + AssignmentCheckResult::Bad(error) => { + gum::info!( + target: LOG_TARGET, + hash = ?block_hash, + ?peer_id, + %error, + "Got a bad assignment from peer", + ); + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + COST_INVALID_MESSAGE, + ) + .await; + return + }, + } + } else { + if !entry.knowledge.insert(message_subject.clone(), message_kind) { + // if we already imported an assignment, there is no need to distribute it again + gum::warn!( + target: LOG_TARGET, + ?message_subject, + "Importing locally an already known assignment", + ); + return + } else { + gum::debug!( + target: LOG_TARGET, + ?message_subject, + "Importing locally a new assignment", + ); + } + } + + // Invariant: to our knowledge, none of the peers except for the `source` know about the + // assignment. + metrics.on_assignment_imported(); + + let topology = self.topologies.get_topology(entry.session); + let local = source == MessageSource::Local; + + let required_routing = topology.map_or(RequiredRouting::PendingTopology, |t| { + t.local_grid_neighbors().required_routing_by_index(validator_index, local) + }); + + let message_state = match entry.candidates.get_mut(claimed_candidate_index as usize) { + Some(candidate_entry) => { + // set the approval state for validator_index to Assigned + // unless the approval state is set already + candidate_entry.messages.entry(validator_index).or_insert_with(|| MessageState { + required_routing, + local, + random_routing: Default::default(), + approval_state: ApprovalState::Assigned(assignment.cert.clone()), + }) + }, + None => { + gum::warn!( + target: LOG_TARGET, + hash = ?block_hash, + ?claimed_candidate_index, + "Expected a candidate entry on import_and_circulate_assignment", + ); + + return + }, + }; + + // Dispatch the message to all peers in the routing set which + // know the block. + // + // If the topology isn't known yet (race with networking subsystems) + // then messages will be sent when we get it. + + let assignments = vec![(assignment, claimed_candidate_index)]; + let n_peers_total = self.peer_data.len(); + let source_peer = source.peer_id(); + + let mut peer_filter = move |peer| { + if Some(peer) == source_peer.as_ref() { + return false + } + + if let Some(true) = topology + .as_ref() + .map(|t| t.local_grid_neighbors().route_to_peer(required_routing, peer)) + { + return true + } + + // Note: at this point, we haven't received the message from any peers + // other than the source peer, and we just got it, so we haven't sent it + // to any peers either. + let route_random = message_state.random_routing.sample(n_peers_total, rng); + + if route_random { + message_state.random_routing.inc_sent(); + } + + route_random + }; + + let (v1_peers, vstaging_peers) = { + let peer_data = &self.peer_data; + let peers = entry + .known_by + .keys() + .filter_map(|p| peer_data.get_key_value(p)) + .filter(|(p, _)| peer_filter(p)) + .map(|(p, peer_data)| (*p, peer_data.version)) + .collect::>(); + + // Add the metadata of the assignment to the knowledge of each peer. + for (peer, _) in peers.iter() { + // we already filtered peers above, so this should always be Some + if let Some(peer_knowledge) = entry.known_by.get_mut(peer) { + peer_knowledge.sent.insert(message_subject.clone(), message_kind); + } + } + + if !peers.is_empty() { + gum::trace!( + target: LOG_TARGET, + ?block_hash, + ?claimed_candidate_index, + local = source.peer_id().is_none(), + num_peers = peers.len(), + "Sending an assignment to peers", + ); + } + + let v1_peers = filter_peers_by_version(&peers, ValidationVersion::V1); + let vstaging_peers = filter_peers_by_version(&peers, ValidationVersion::VStaging); + + (v1_peers, vstaging_peers) + }; + + if !v1_peers.is_empty() { + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + v1_peers, + versioned_assignments_packet(ValidationVersion::V1, assignments.clone()), + )) + .await; + } + + if !vstaging_peers.is_empty() { + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + vstaging_peers, + versioned_assignments_packet(ValidationVersion::VStaging, assignments.clone()), + )) + .await; + } + } + + async fn import_and_circulate_approval( + &mut self, + ctx: &mut Context, + metrics: &Metrics, + source: MessageSource, + vote: IndirectSignedApprovalVote, + ) { + let _span = self + .spans + .get(&vote.block_hash) + .map(|span| { + span.child(if source.peer_id().is_some() { + "peer-import-and-distribute-approval" + } else { + "local-import-and-distribute-approval" + }) + }) + .unwrap_or_else(|| jaeger::Span::new(&vote.block_hash, "distribute-approval")) + .with_string_tag("block-hash", format!("{:?}", vote.block_hash)) + .with_optional_peer_id(source.peer_id().as_ref()) + .with_stage(jaeger::Stage::ApprovalDistribution); + + let block_hash = vote.block_hash; + let validator_index = vote.validator; + let candidate_index = vote.candidate_index; + + let entry = match self.blocks.get_mut(&block_hash) { + Some(entry) if entry.candidates.get(candidate_index as usize).is_some() => entry, + _ => { + if let Some(peer_id) = source.peer_id() { + if !self.recent_outdated_blocks.is_recent_outdated(&block_hash) { + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + COST_UNEXPECTED_MESSAGE, + ) + .await; + } + } + return + }, + }; + + // compute metadata on the assignment. + let message_subject = MessageSubject(block_hash, candidate_index, validator_index); + let message_kind = MessageKind::Approval; + + if let Some(peer_id) = source.peer_id() { + if !entry.knowledge.contains(&message_subject, MessageKind::Assignment) { + gum::debug!( + target: LOG_TARGET, + ?peer_id, + ?message_subject, + "Unknown approval assignment", + ); + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + COST_UNEXPECTED_MESSAGE, + ) + .await; + return + } + + // check if our knowledge of the peer already contains this approval + match entry.known_by.entry(peer_id) { + hash_map::Entry::Occupied(mut knowledge) => { + let peer_knowledge = knowledge.get_mut(); + if peer_knowledge.contains(&message_subject, message_kind) { + if !peer_knowledge.received.insert(message_subject.clone(), message_kind) { + gum::debug!( + target: LOG_TARGET, + ?peer_id, + ?message_subject, + "Duplicate approval", + ); + + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + COST_DUPLICATE_MESSAGE, + ) + .await; + } + return + } + }, + hash_map::Entry::Vacant(_) => { + gum::debug!( + target: LOG_TARGET, + ?peer_id, + ?message_subject, + "Approval from a peer is out of view", + ); + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + COST_UNEXPECTED_MESSAGE, + ) + .await; + }, + } + + // if the approval is known to be valid, reward the peer + if entry.knowledge.contains(&message_subject, message_kind) { + gum::trace!(target: LOG_TARGET, ?peer_id, ?message_subject, "Known approval"); + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + BENEFIT_VALID_MESSAGE, + ) + .await; + if let Some(peer_knowledge) = entry.known_by.get_mut(&peer_id) { + peer_knowledge.received.insert(message_subject.clone(), message_kind); + } + return + } + + let (tx, rx) = oneshot::channel(); + + ctx.send_message(ApprovalVotingMessage::CheckAndImportApproval(vote.clone(), tx)) + .await; + + let timer = metrics.time_awaiting_approval_voting(); + let result = match rx.await { + Ok(result) => result, + Err(_) => { + gum::debug!(target: LOG_TARGET, "The approval voting subsystem is down"); + return + }, + }; + drop(timer); + + gum::trace!( + target: LOG_TARGET, + ?peer_id, + ?message_subject, + ?result, + "Checked approval", + ); + match result { + ApprovalCheckResult::Accepted => { + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + BENEFIT_VALID_MESSAGE_FIRST, + ) + .await; + + entry.knowledge.insert(message_subject.clone(), message_kind); + if let Some(peer_knowledge) = entry.known_by.get_mut(&peer_id) { + peer_knowledge.received.insert(message_subject.clone(), message_kind); + } + }, + ApprovalCheckResult::Bad(error) => { + modify_reputation( + &mut self.reputation, + ctx.sender(), + peer_id, + COST_INVALID_MESSAGE, + ) + .await; + gum::info!( + target: LOG_TARGET, + ?peer_id, + %error, + "Got a bad approval from peer", + ); + return + }, + } + } else { + if !entry.knowledge.insert(message_subject.clone(), message_kind) { + // if we already imported an approval, there is no need to distribute it again + gum::warn!( + target: LOG_TARGET, + ?message_subject, + "Importing locally an already known approval", + ); + return + } else { + gum::debug!( + target: LOG_TARGET, + ?message_subject, + "Importing locally a new approval", + ); + } + } + + // Invariant: to our knowledge, none of the peers except for the `source` know about the + // approval. + metrics.on_approval_imported(); + + let required_routing = match entry.candidates.get_mut(candidate_index as usize) { + Some(candidate_entry) => { + // set the approval state for validator_index to Approved + // it should be in assigned state already + match candidate_entry.messages.remove(&validator_index) { + Some(MessageState { + approval_state: ApprovalState::Assigned(cert), + required_routing, + local, + random_routing, + }) => { + candidate_entry.messages.insert( + validator_index, + MessageState { + approval_state: ApprovalState::Approved( + cert, + vote.signature.clone(), + ), + required_routing, + local, + random_routing, + }, + ); + + required_routing + }, + Some(_) => { + unreachable!( + "we only insert it after the metadata, checked the metadata above; qed" + ); + }, + None => { + // this would indicate a bug in approval-voting + gum::warn!( + target: LOG_TARGET, + hash = ?block_hash, + ?candidate_index, + ?validator_index, + "Importing an approval we don't have an assignment for", + ); + + return + }, + } + }, + None => { + gum::warn!( + target: LOG_TARGET, + hash = ?block_hash, + ?candidate_index, + ?validator_index, + "Expected a candidate entry on import_and_circulate_approval", + ); + + return + }, + }; + + // Dispatch a ApprovalDistributionV1Message::Approval(vote) + // to all peers required by the topology, with the exception of the source peer. + + let topology = self.topologies.get_topology(entry.session); + let source_peer = source.peer_id(); + + let message_subject = &message_subject; + let peer_filter = move |peer, knowledge: &PeerKnowledge| { + if Some(peer) == source_peer.as_ref() { + return false + } + + // Here we're leaning on a few behaviors of assignment propagation: + // 1. At this point, the only peer we're aware of which has the approval message is + // the source peer. + // 2. We have sent the assignment message to every peer in the required routing which + // is aware of this block _unless_ the peer we originally received the assignment + // from was part of the required routing. In that case, we've sent the assignment + // to all aware peers in the required routing _except_ the original source of the + // assignment. Hence the `in_topology_check`. + // 3. Any randomly selected peers have been sent the assignment already. + let in_topology = topology + .map_or(false, |t| t.local_grid_neighbors().route_to_peer(required_routing, peer)); + in_topology || knowledge.sent.contains(message_subject, MessageKind::Assignment) + }; + + let (v1_peers, vstaging_peers) = { + let peer_data = &self.peer_data; + let peers = entry + .known_by + .iter() + .filter_map(|(p, k)| peer_data.get(&p).map(|pd| (p, k, pd.version))) + .filter(|(p, k, _)| peer_filter(p, k)) + .map(|(p, _, v)| (*p, v)) + .collect::>(); + + // Add the metadata of the assignment to the knowledge of each peer. + for (peer, _) in peers.iter() { + // we already filtered peers above, so this should always be Some + if let Some(peer_knowledge) = entry.known_by.get_mut(peer) { + peer_knowledge.sent.insert(message_subject.clone(), message_kind); + } + } + + if !peers.is_empty() { + gum::trace!( + target: LOG_TARGET, + ?block_hash, + ?candidate_index, + local = source.peer_id().is_none(), + num_peers = peers.len(), + "Sending an approval to peers", + ); + } + + let v1_peers = filter_peers_by_version(&peers, ValidationVersion::V1); + let vstaging_peers = filter_peers_by_version(&peers, ValidationVersion::VStaging); + + (v1_peers, vstaging_peers) + }; + + let approvals = vec![vote]; + + if !v1_peers.is_empty() { + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + v1_peers, + versioned_approvals_packet(ValidationVersion::V1, approvals.clone()), + )) + .await; + } + + if !vstaging_peers.is_empty() { + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + vstaging_peers, + versioned_approvals_packet(ValidationVersion::VStaging, approvals), + )) + .await; + } + } + + /// Retrieve approval signatures from state for the given relay block/indices: + fn get_approval_signatures( + &mut self, + indices: HashSet<(Hash, CandidateIndex)>, + ) -> HashMap { + let mut all_sigs = HashMap::new(); + for (hash, index) in indices { + let _span = self + .spans + .get(&hash) + .map(|span| span.child("get-approval-signatures")) + .unwrap_or_else(|| jaeger::Span::new(&hash, "get-approval-signatures")) + .with_string_tag("block-hash", format!("{:?}", hash)) + .with_stage(jaeger::Stage::ApprovalDistribution); + + let block_entry = match self.blocks.get(&hash) { + None => { + gum::debug!( + target: LOG_TARGET, + ?hash, + "`get_approval_signatures`: could not find block entry for given hash!" + ); + continue + }, + Some(e) => e, + }; + + let candidate_entry = match block_entry.candidates.get(index as usize) { + None => { + gum::debug!( + target: LOG_TARGET, + ?hash, + ?index, + "`get_approval_signatures`: could not find candidate entry for given hash and index!" + ); + continue + }, + Some(e) => e, + }; + let sigs = + candidate_entry.messages.iter().filter_map(|(validator_index, message_state)| { + match &message_state.approval_state { + ApprovalState::Approved(_, sig) => Some((*validator_index, sig.clone())), + ApprovalState::Assigned(_) => None, + } + }); + all_sigs.extend(sigs); + } + all_sigs + } + + async fn unify_with_peer( + sender: &mut impl overseer::ApprovalDistributionSenderTrait, + metrics: &Metrics, + entries: &mut HashMap, + topologies: &SessionGridTopologies, + total_peers: usize, + peer_id: PeerId, + peer_protocol_version: ValidationVersion, + view: View, + rng: &mut (impl CryptoRng + Rng), + ) { + metrics.on_unify_with_peer(); + let _timer = metrics.time_unify_with_peer(); + + let mut assignments_to_send = Vec::new(); + let mut approvals_to_send = Vec::new(); + + let view_finalized_number = view.finalized_number; + for head in view.into_iter() { + let mut block = head; + loop { + let entry = match entries.get_mut(&block) { + Some(entry) if entry.number > view_finalized_number => entry, + _ => break, + }; + + // Any peer which is in the `known_by` set has already been + // sent all messages it's meant to get for that block and all + // in-scope prior blocks. + if entry.known_by.contains_key(&peer_id) { + break + } + + let peer_knowledge = entry.known_by.entry(peer_id).or_default(); + + let topology = topologies.get_topology(entry.session); + + // Iterate all messages in all candidates. + for (candidate_index, validator, message_state) in + entry.candidates.iter_mut().enumerate().flat_map(|(c_i, c)| { + c.messages.iter_mut().map(move |(k, v)| (c_i as _, k, v)) + }) { + // Propagate the message to all peers in the required routing set OR + // randomly sample peers. + { + let random_routing = &mut message_state.random_routing; + let required_routing = message_state.required_routing; + let rng = &mut *rng; + let mut peer_filter = move |peer_id| { + let in_topology = topology.as_ref().map_or(false, |t| { + t.local_grid_neighbors().route_to_peer(required_routing, peer_id) + }); + in_topology || { + let route_random = random_routing.sample(total_peers, rng); + if route_random { + random_routing.inc_sent(); + } + + route_random + } + }; + + if !peer_filter(&peer_id) { + continue + } + } + + let message_subject = MessageSubject(block, candidate_index, *validator); + + let assignment_message = ( + IndirectAssignmentCert { + block_hash: block, + validator: *validator, + cert: message_state.approval_state.assignment_cert().clone(), + }, + candidate_index, + ); + + let approval_message = + message_state.approval_state.approval_signature().map(|signature| { + IndirectSignedApprovalVote { + block_hash: block, + validator: *validator, + candidate_index, + signature, + } + }); + + if !peer_knowledge.contains(&message_subject, MessageKind::Assignment) { + peer_knowledge + .sent + .insert(message_subject.clone(), MessageKind::Assignment); + assignments_to_send.push(assignment_message); + } + + if let Some(approval_message) = approval_message { + if !peer_knowledge.contains(&message_subject, MessageKind::Approval) { + peer_knowledge + .sent + .insert(message_subject.clone(), MessageKind::Approval); + approvals_to_send.push(approval_message); + } + } + } + + block = entry.parent_hash; + } + } + + if !assignments_to_send.is_empty() { + gum::trace!( + target: LOG_TARGET, + ?peer_id, + num = assignments_to_send.len(), + "Sending assignments to unified peer", + ); + + send_assignments_batched(sender, assignments_to_send, peer_id, peer_protocol_version) + .await; + } + + if !approvals_to_send.is_empty() { + gum::trace!( + target: LOG_TARGET, + ?peer_id, + num = approvals_to_send.len(), + "Sending approvals to unified peer", + ); + + send_approvals_batched(sender, approvals_to_send, peer_id, peer_protocol_version).await; + } + } + + async fn enable_aggression( + &mut self, + ctx: &mut Context, + resend: Resend, + metrics: &Metrics, + ) { + let config = self.aggression_config.clone(); + + if !self.aggression_config.should_trigger_aggression(self.approval_checking_lag) { + gum::trace!( + target: LOG_TARGET, + approval_checking_lag = self.approval_checking_lag, + "Aggression not enabled", + ); + return + } + + let max_age = self.blocks_by_number.iter().rev().next().map(|(num, _)| num); + + let max_age = match max_age { + Some(max) => *max, + _ => return, // empty. + }; + + // Since we have the approval checking lag, we need to set the `min_age` accordingly to + // enable aggresion for the oldest block that is not approved. + let min_age = max_age.saturating_sub(self.approval_checking_lag); + + gum::debug!(target: LOG_TARGET, min_age, max_age, "Aggression enabled",); + + adjust_required_routing_and_propagate( + ctx, + &self.peer_data, + &mut self.blocks, + &self.topologies, + |block_entry| { + let block_age = max_age - block_entry.number; + + if resend == Resend::Yes && + config + .resend_unfinalized_period + .as_ref() + .map_or(false, |p| block_age > 0 && block_age % p == 0) + { + // Retry sending to all peers. + for (_, knowledge) in block_entry.known_by.iter_mut() { + knowledge.sent = Knowledge::default(); + } + + true + } else { + false + } + }, + |_, _, _| {}, + ) + .await; + + adjust_required_routing_and_propagate( + ctx, + &self.peer_data, + &mut self.blocks, + &self.topologies, + |block_entry| { + // Ramp up aggression only for the very oldest block(s). + // Approval voting can get stuck on a single block preventing + // its descendants from being finalized. Waste minimal bandwidth + // this way. Also, disputes might prevent finality - again, nothing + // to waste bandwidth on newer blocks for. + block_entry.number == min_age + }, + |required_routing, local, _| { + // It's a bit surprising not to have a topology at this age. + if *required_routing == RequiredRouting::PendingTopology { + gum::debug!( + target: LOG_TARGET, + lag = ?self.approval_checking_lag, + "Encountered old block pending gossip topology", + ); + return + } + + if config.l1_threshold.as_ref().map_or(false, |t| &self.approval_checking_lag >= t) + { + // Message originator sends to everyone. + if local && *required_routing != RequiredRouting::All { + metrics.on_aggression_l1(); + *required_routing = RequiredRouting::All; + } + } + + if config.l2_threshold.as_ref().map_or(false, |t| &self.approval_checking_lag >= t) + { + // Message originator sends to everyone. Everyone else sends to XY. + if !local && *required_routing != RequiredRouting::GridXY { + metrics.on_aggression_l2(); + *required_routing = RequiredRouting::GridXY; + } + } + }, + ) + .await; + } +} + +// This adjusts the required routing of messages in blocks that pass the block filter +// according to the modifier function given. +// +// The modifier accepts as inputs the current required-routing state, whether +// the message is locally originating, and the validator index of the message issuer. +// +// Then, if the topology is known, this progates messages to all peers in the required +// routing set which are aware of the block. Peers which are unaware of the block +// will have the message sent when it enters their view in `unify_with_peer`. +// +// Note that the required routing of a message can be modified even if the +// topology is unknown yet. +#[overseer::contextbounds(ApprovalDistribution, prefix = self::overseer)] +async fn adjust_required_routing_and_propagate( + ctx: &mut Context, + peer_data: &HashMap, + blocks: &mut HashMap, + topologies: &SessionGridTopologies, + block_filter: BlockFilter, + routing_modifier: RoutingModifier, +) where + BlockFilter: Fn(&mut BlockEntry) -> bool, + RoutingModifier: Fn(&mut RequiredRouting, bool, &ValidatorIndex), +{ + let mut peer_assignments = HashMap::new(); + let mut peer_approvals = HashMap::new(); + + // Iterate all blocks in the session, producing payloads + // for each connected peer. + for (block_hash, block_entry) in blocks { + if !block_filter(block_entry) { + continue + } + + // Iterate all messages in all candidates. + for (candidate_index, validator, message_state) in block_entry + .candidates + .iter_mut() + .enumerate() + .flat_map(|(c_i, c)| c.messages.iter_mut().map(move |(k, v)| (c_i as _, k, v))) + { + routing_modifier(&mut message_state.required_routing, message_state.local, validator); + + if message_state.required_routing.is_empty() { + continue + } + + let topology = match topologies.get_topology(block_entry.session) { + Some(t) => t, + None => continue, + }; + + // Propagate the message to all peers in the required routing set. + let message_subject = MessageSubject(*block_hash, candidate_index, *validator); + + let assignment_message = ( + IndirectAssignmentCert { + block_hash: *block_hash, + validator: *validator, + cert: message_state.approval_state.assignment_cert().clone(), + }, + candidate_index, + ); + let approval_message = + message_state.approval_state.approval_signature().map(|signature| { + IndirectSignedApprovalVote { + block_hash: *block_hash, + validator: *validator, + candidate_index, + signature, + } + }); + + for (peer, peer_knowledge) in &mut block_entry.known_by { + if !topology + .local_grid_neighbors() + .route_to_peer(message_state.required_routing, peer) + { + continue + } + + if !peer_knowledge.contains(&message_subject, MessageKind::Assignment) { + peer_knowledge.sent.insert(message_subject.clone(), MessageKind::Assignment); + peer_assignments + .entry(*peer) + .or_insert_with(Vec::new) + .push(assignment_message.clone()); + } + + if let Some(approval_message) = approval_message.as_ref() { + if !peer_knowledge.contains(&message_subject, MessageKind::Approval) { + peer_knowledge.sent.insert(message_subject.clone(), MessageKind::Approval); + peer_approvals + .entry(*peer) + .or_insert_with(Vec::new) + .push(approval_message.clone()); + } + } + } + } + } + + // Send messages in accumulated packets, assignments preceding approvals. + + for (peer, assignments_packet) in peer_assignments { + let peer_protocol_version = match peer_data.get(&peer).map(|pd| pd.version) { + None => continue, + Some(v) => v, + }; + + send_assignments_batched(ctx.sender(), assignments_packet, peer, peer_protocol_version) + .await; + } + + for (peer, approvals_packet) in peer_approvals { + let peer_protocol_version = match peer_data.get(&peer).map(|pd| pd.version) { + None => continue, + Some(v) => v, + }; + + send_approvals_batched(ctx.sender(), approvals_packet, peer, peer_protocol_version).await; + } +} + +/// Modify the reputation of a peer based on its behavior. +async fn modify_reputation( + reputation: &mut ReputationAggregator, + sender: &mut impl overseer::ApprovalDistributionSenderTrait, + peer_id: PeerId, + rep: Rep, +) { + gum::trace!( + target: LOG_TARGET, + reputation = ?rep, + ?peer_id, + "Reputation change for peer", + ); + reputation.modify(sender, peer_id, rep).await; +} + +#[overseer::contextbounds(ApprovalDistribution, prefix = self::overseer)] +impl ApprovalDistribution { + /// Create a new instance of the [`ApprovalDistribution`] subsystem. + pub fn new(metrics: Metrics) -> Self { + Self { metrics } + } + + async fn run(self, ctx: Context) { + let mut state = State::default(); + + // According to the docs of `rand`, this is a ChaCha12 RNG in practice + // and will always be chosen for strong performance and security properties. + let mut rng = rand::rngs::StdRng::from_entropy(); + self.run_inner(ctx, &mut state, REPUTATION_CHANGE_INTERVAL, &mut rng).await + } + + /// Used for testing. + async fn run_inner( + self, + mut ctx: Context, + state: &mut State, + reputation_interval: Duration, + rng: &mut (impl CryptoRng + Rng), + ) { + let new_reputation_delay = || futures_timer::Delay::new(reputation_interval).fuse(); + let mut reputation_delay = new_reputation_delay(); + + loop { + select! { + _ = reputation_delay => { + state.reputation.send(ctx.sender()).await; + reputation_delay = new_reputation_delay(); + }, + message = ctx.recv().fuse() => { + let message = match message { + Ok(message) => message, + Err(e) => { + gum::debug!(target: LOG_TARGET, err = ?e, "Failed to receive a message from Overseer, exiting"); + return + }, + }; + match message { + FromOrchestra::Communication { msg } => + Self::handle_incoming(&mut ctx, state, msg, &self.metrics, rng).await, + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => { + gum::trace!(target: LOG_TARGET, "active leaves signal (ignored)"); + // the relay chain blocks relevant to the approval subsystems + // are those that are available, but not finalized yet + // actived and deactivated heads hence are irrelevant to this subsystem, other than + // for tracing purposes. + if let Some(activated) = update.activated { + let head = activated.hash; + let approval_distribution_span = + jaeger::PerLeafSpan::new(activated.span, "approval-distribution"); + state.spans.insert(head, approval_distribution_span); + } + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(_hash, number)) => { + gum::trace!(target: LOG_TARGET, number = %number, "finalized signal"); + state.handle_block_finalized(&mut ctx, &self.metrics, number).await; + }, + FromOrchestra::Signal(OverseerSignal::Conclude) => return, + } + }, + } + } + } + + async fn handle_incoming( + ctx: &mut Context, + state: &mut State, + msg: ApprovalDistributionMessage, + metrics: &Metrics, + rng: &mut (impl CryptoRng + Rng), + ) { + match msg { + ApprovalDistributionMessage::NetworkBridgeUpdate(event) => { + state.handle_network_msg(ctx, metrics, event, rng).await; + }, + ApprovalDistributionMessage::NewBlocks(metas) => { + state.handle_new_blocks(ctx, metrics, metas, rng).await; + }, + ApprovalDistributionMessage::DistributeAssignment(cert, candidate_index) => { + gum::debug!( + target: LOG_TARGET, + "Distributing our assignment on candidate (block={}, index={})", + cert.block_hash, + candidate_index, + ); + + state + .import_and_circulate_assignment( + ctx, + &metrics, + MessageSource::Local, + cert, + candidate_index, + rng, + ) + .await; + }, + ApprovalDistributionMessage::DistributeApproval(vote) => { + gum::debug!( + target: LOG_TARGET, + "Distributing our approval vote on candidate (block={}, index={})", + vote.block_hash, + vote.candidate_index, + ); + + state + .import_and_circulate_approval(ctx, metrics, MessageSource::Local, vote) + .await; + }, + ApprovalDistributionMessage::GetApprovalSignatures(indices, tx) => { + let sigs = state.get_approval_signatures(indices); + if let Err(_) = tx.send(sigs) { + gum::debug!( + target: LOG_TARGET, + "Sending back approval signatures failed, oneshot got closed" + ); + } + }, + ApprovalDistributionMessage::ApprovalCheckingLagUpdate(lag) => { + gum::debug!(target: LOG_TARGET, lag, "Received `ApprovalCheckingLagUpdate`"); + state.approval_checking_lag = lag; + }, + } + } +} + +fn versioned_approvals_packet( + version: ValidationVersion, + approvals: Vec, +) -> VersionedValidationProtocol { + match version { + ValidationVersion::V1 => + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(approvals), + )), + ValidationVersion::VStaging => + Versioned::VStaging(protocol_vstaging::ValidationProtocol::ApprovalDistribution( + protocol_vstaging::ApprovalDistributionMessage::Approvals(approvals), + )), + } +} + +fn versioned_assignments_packet( + version: ValidationVersion, + assignments: Vec<(IndirectAssignmentCert, CandidateIndex)>, +) -> VersionedValidationProtocol { + match version { + ValidationVersion::V1 => + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(assignments), + )), + ValidationVersion::VStaging => + Versioned::VStaging(protocol_vstaging::ValidationProtocol::ApprovalDistribution( + protocol_vstaging::ApprovalDistributionMessage::Assignments(assignments), + )), + } +} + +fn filter_peers_by_version( + peers: &[(PeerId, ValidationVersion)], + version: ValidationVersion, +) -> Vec { + peers + .iter() + .filter(|(_, v)| v == &version) + .map(|(peer_id, _)| *peer_id) + .collect() +} + +#[overseer::subsystem(ApprovalDistribution, error=SubsystemError, prefix=self::overseer)] +impl ApprovalDistribution { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = self.run(ctx).map(|_| Ok(())).boxed(); + + SpawnedSubsystem { name: "approval-distribution-subsystem", future } + } +} + +/// Ensures the batch size is always at least 1 element. +const fn ensure_size_not_zero(size: usize) -> usize { + if 0 == size { + panic!("Batch size must be at least 1 (MAX_NOTIFICATION_SIZE constant is too low)",); + } + + size +} + +/// The maximum amount of assignments per batch is 33% of maximum allowed by protocol. +/// This is an arbitrary value. Bumping this up increases the maximum amount of approvals or +/// assignments we send in a single message to peers. Exceeding `MAX_NOTIFICATION_SIZE` will violate +/// the protocol configuration. +pub const MAX_ASSIGNMENT_BATCH_SIZE: usize = ensure_size_not_zero( + MAX_NOTIFICATION_SIZE as usize / + std::mem::size_of::<(IndirectAssignmentCert, CandidateIndex)>() / + 3, +); + +/// The maximum amount of approvals per batch is 33% of maximum allowed by protocol. +pub const MAX_APPROVAL_BATCH_SIZE: usize = ensure_size_not_zero( + MAX_NOTIFICATION_SIZE as usize / std::mem::size_of::() / 3, +); + +/// Send assignments while honoring the `max_notification_size` of the protocol. +/// +/// Splitting the messages into multiple notifications allows more granular processing at the +/// destination, such that the subsystem doesn't get stuck for long processing a batch +/// of assignments and can `select!` other tasks. +pub(crate) async fn send_assignments_batched( + sender: &mut impl overseer::ApprovalDistributionSenderTrait, + assignments: Vec<(IndirectAssignmentCert, CandidateIndex)>, + peer: PeerId, + protocol_version: ValidationVersion, +) { + let mut batches = assignments.into_iter().peekable(); + + while batches.peek().is_some() { + let batch: Vec<_> = batches.by_ref().take(MAX_ASSIGNMENT_BATCH_SIZE).collect(); + let versioned = versioned_assignments_packet(protocol_version, batch); + + sender + .send_message(NetworkBridgeTxMessage::SendValidationMessage(vec![peer], versioned)) + .await; + } +} + +/// Send approvals while honoring the `max_notification_size` of the protocol. +pub(crate) async fn send_approvals_batched( + sender: &mut impl overseer::ApprovalDistributionSenderTrait, + approvals: Vec, + peer: PeerId, + protocol_version: ValidationVersion, +) { + let mut batches = approvals.into_iter().peekable(); + + while batches.peek().is_some() { + let batch: Vec<_> = batches.by_ref().take(MAX_APPROVAL_BATCH_SIZE).collect(); + let versioned = versioned_approvals_packet(protocol_version, batch); + + sender + .send_message(NetworkBridgeTxMessage::SendValidationMessage(vec![peer], versioned)) + .await; + } +} diff --git a/polkadot/node/network/approval-distribution/src/metrics.rs b/polkadot/node/network/approval-distribution/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..896866ce099a18c993540877a73144fc194a9a81 --- /dev/null +++ b/polkadot/node/network/approval-distribution/src/metrics.rs @@ -0,0 +1,150 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_metrics::metrics::{prometheus, Metrics as MetricsTrait}; + +/// Approval Distribution metrics. +#[derive(Default, Clone)] +pub struct Metrics(Option); + +#[derive(Clone)] +struct MetricsInner { + assignments_imported_total: prometheus::Counter, + approvals_imported_total: prometheus::Counter, + unified_with_peer_total: prometheus::Counter, + aggression_l1_messages_total: prometheus::Counter, + aggression_l2_messages_total: prometheus::Counter, + + time_unify_with_peer: prometheus::Histogram, + time_import_pending_now_known: prometheus::Histogram, + time_awaiting_approval_voting: prometheus::Histogram, +} + +impl Metrics { + pub(crate) fn on_assignment_imported(&self) { + if let Some(metrics) = &self.0 { + metrics.assignments_imported_total.inc(); + } + } + + pub(crate) fn on_approval_imported(&self) { + if let Some(metrics) = &self.0 { + metrics.approvals_imported_total.inc(); + } + } + + pub(crate) fn on_unify_with_peer(&self) { + if let Some(metrics) = &self.0 { + metrics.unified_with_peer_total.inc(); + } + } + + pub(crate) fn time_unify_with_peer(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.time_unify_with_peer.start_timer()) + } + + pub(crate) fn time_import_pending_now_known( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.time_import_pending_now_known.start_timer()) + } + + pub(crate) fn time_awaiting_approval_voting( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.time_awaiting_approval_voting.start_timer()) + } + + pub(crate) fn on_aggression_l1(&self) { + if let Some(metrics) = &self.0 { + metrics.aggression_l1_messages_total.inc(); + } + } + + pub(crate) fn on_aggression_l2(&self) { + if let Some(metrics) = &self.0 { + metrics.aggression_l2_messages_total.inc(); + } + } +} + +impl MetricsTrait for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + assignments_imported_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_assignments_imported_total", + "Number of valid assignments imported locally or from other peers.", + )?, + registry, + )?, + approvals_imported_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_approvals_imported_total", + "Number of valid approvals imported locally or from other peers.", + )?, + registry, + )?, + unified_with_peer_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_unified_with_peer_total", + "Number of times `unify_with_peer` is called.", + )?, + registry, + )?, + aggression_l1_messages_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_approval_distribution_aggression_l1_messages_total", + "Number of messages in approval distribution for which aggression L1 has been triggered", + )?, + registry, + )?, + aggression_l2_messages_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_approval_distribution_aggression_l2_messages_total", + "Number of messages in approval distribution for which aggression L2 has been triggered", + )?, + registry, + )?, + time_unify_with_peer: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_time_unify_with_peer", + "Time spent within fn `unify_with_peer`.", + ).buckets(vec![0.000625, 0.00125,0.0025, 0.005, 0.0075, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0,]))?, + registry, + )?, + time_import_pending_now_known: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_time_import_pending_now_known", + "Time spent on importing pending assignments and approvals.", + ).buckets(vec![0.0001, 0.0004, 0.0016, 0.0064, 0.0256, 0.1024, 0.4096, 1.6384, 3.2768, 4.9152, 6.5536,]))?, + registry, + )?, + time_awaiting_approval_voting: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_time_awaiting_approval_voting", + "Time spent awaiting a reply from the Approval Voting Subsystem.", + ).buckets(vec![0.0001, 0.0004, 0.0016, 0.0064, 0.0256, 0.1024, 0.4096, 1.6384, 3.2768, 4.9152, 6.5536,]))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/network/approval-distribution/src/tests.rs b/polkadot/node/network/approval-distribution/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..1e9ae7b620072939b81a13949fbc7299333210ad --- /dev/null +++ b/polkadot/node/network/approval-distribution/src/tests.rs @@ -0,0 +1,2642 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use assert_matches::assert_matches; +use futures::{executor, future, Future}; +use polkadot_node_network_protocol::{ + grid_topology::{SessionGridTopology, TopologyPeerInfo}, + our_view, + peer_set::ValidationVersion, + view, ObservedRole, +}; +use polkadot_node_primitives::approval::{ + AssignmentCertKind, VrfOutput, VrfProof, VrfSignature, RELAY_VRF_MODULO_CONTEXT, +}; +use polkadot_node_subsystem::messages::{ + network_bridge_event, AllMessages, ApprovalCheckError, ReportPeerMessage, +}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_node_subsystem_util::{reputation::add_reputation, TimeoutExt as _}; +use polkadot_primitives::{AuthorityDiscoveryId, BlakeTwo256, HashT}; +use polkadot_primitives_test_helpers::dummy_signature; +use rand::SeedableRng; +use sp_authority_discovery::AuthorityPair as AuthorityDiscoveryPair; +use sp_core::crypto::Pair as PairT; +use std::time::Duration; + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; + +fn test_harness>( + mut state: State, + test_fn: impl FnOnce(VirtualOverseer) -> T, +) -> State { + let _ = env_logger::builder() + .is_test(true) + .filter(Some(LOG_TARGET), log::LevelFilter::Trace) + .try_init(); + + let pool = sp_core::testing::TaskExecutor::new(); + let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); + + let subsystem = ApprovalDistribution::new(Default::default()); + { + let mut rng = rand_chacha::ChaCha12Rng::seed_from_u64(12345); + + let subsystem = + subsystem.run_inner(context, &mut state, REPUTATION_CHANGE_TEST_INTERVAL, &mut rng); + + let test_fut = test_fn(virtual_overseer); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer + .send(FromOrchestra::Signal(OverseerSignal::Conclude)) + .timeout(TIMEOUT) + .await + .expect("Conclude send timeout"); + }, + subsystem, + )); + } + + state +} + +const TIMEOUT: Duration = Duration::from_millis(200); +const REPUTATION_CHANGE_TEST_INTERVAL: Duration = Duration::from_millis(1); + +async fn overseer_send(overseer: &mut VirtualOverseer, msg: ApprovalDistributionMessage) { + gum::trace!(msg = ?msg, "Sending message"); + overseer + .send(FromOrchestra::Communication { msg }) + .timeout(TIMEOUT) + .await + .expect("msg send timeout"); +} + +async fn overseer_signal_block_finalized(overseer: &mut VirtualOverseer, number: BlockNumber) { + gum::trace!(?number, "Sending a finalized signal"); + // we don't care about the block hash + overseer + .send(FromOrchestra::Signal(OverseerSignal::BlockFinalized(Hash::zero(), number))) + .timeout(TIMEOUT) + .await + .expect("signal send timeout"); +} + +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { + gum::trace!("Waiting for a message"); + let msg = overseer.recv().timeout(TIMEOUT).await.expect("msg recv timeout"); + + gum::trace!(msg = ?msg, "Received message"); + + msg +} + +fn make_peers_and_authority_ids(n: usize) -> Vec<(PeerId, AuthorityDiscoveryId)> { + (0..n) + .map(|_| { + let peer_id = PeerId::random(); + let authority_id = AuthorityDiscoveryPair::generate().0.public(); + + (peer_id, authority_id) + }) + .collect() +} + +fn make_gossip_topology( + session: SessionIndex, + all_peers: &[(PeerId, AuthorityDiscoveryId)], + neighbors_x: &[usize], + neighbors_y: &[usize], +) -> network_bridge_event::NewGossipTopology { + // This builds a grid topology which is a square matrix. + // The local validator occupies the top left-hand corner. + // The X peers occupy the same row and the Y peers occupy + // the same column. + + let local_index = 1; + + assert_eq!( + neighbors_x.len(), + neighbors_y.len(), + "mocking grid topology only implemented for squares", + ); + + let d = neighbors_x.len() + 1; + + let grid_size = d * d; + assert!(grid_size > 0); + assert!(all_peers.len() >= grid_size); + + let peer_info = |i: usize| TopologyPeerInfo { + peer_ids: vec![all_peers[i].0], + validator_index: ValidatorIndex::from(i as u32), + discovery_id: all_peers[i].1.clone(), + }; + + let mut canonical_shuffling: Vec<_> = (0..) + .filter(|i| local_index != *i) + .filter(|i| !neighbors_x.contains(i)) + .filter(|i| !neighbors_y.contains(i)) + .take(grid_size) + .map(peer_info) + .collect(); + + // filled with junk except for own. + let mut shuffled_indices = vec![d + 1; grid_size]; + shuffled_indices[local_index] = 0; + canonical_shuffling[0] = peer_info(local_index); + + for (x_pos, v) in neighbors_x.iter().enumerate() { + let pos = 1 + x_pos; + canonical_shuffling[pos] = peer_info(*v); + } + + for (y_pos, v) in neighbors_y.iter().enumerate() { + let pos = d * (1 + y_pos); + canonical_shuffling[pos] = peer_info(*v); + } + + let topology = SessionGridTopology::new(shuffled_indices, canonical_shuffling); + + // sanity check. + { + let g_n = topology + .compute_grid_neighbors_for(ValidatorIndex(local_index as _)) + .expect("topology just constructed with this validator index"); + + assert_eq!(g_n.validator_indices_x.len(), neighbors_x.len()); + assert_eq!(g_n.validator_indices_y.len(), neighbors_y.len()); + + for i in neighbors_x { + assert!(g_n.validator_indices_x.contains(&ValidatorIndex(*i as _))); + } + + for i in neighbors_y { + assert!(g_n.validator_indices_y.contains(&ValidatorIndex(*i as _))); + } + } + + network_bridge_event::NewGossipTopology { + session, + topology, + local_index: Some(ValidatorIndex(local_index as _)), + } +} + +async fn setup_gossip_topology( + virtual_overseer: &mut VirtualOverseer, + gossip_topology: network_bridge_event::NewGossipTopology, +) { + overseer_send( + virtual_overseer, + ApprovalDistributionMessage::NetworkBridgeUpdate(NetworkBridgeEvent::NewGossipTopology( + gossip_topology, + )), + ) + .await; +} + +async fn setup_peer_with_view( + virtual_overseer: &mut VirtualOverseer, + peer_id: &PeerId, + validation_version: ValidationVersion, + view: View, +) { + overseer_send( + virtual_overseer, + ApprovalDistributionMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerConnected( + *peer_id, + ObservedRole::Full, + validation_version.into(), + None, + )), + ) + .await; + overseer_send( + virtual_overseer, + ApprovalDistributionMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerViewChange( + *peer_id, view, + )), + ) + .await; +} + +async fn send_message_from_peer( + virtual_overseer: &mut VirtualOverseer, + peer_id: &PeerId, + msg: net_protocol::ApprovalDistributionMessage, +) { + overseer_send( + virtual_overseer, + ApprovalDistributionMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerMessage( + *peer_id, msg, + )), + ) + .await; +} + +fn fake_assignment_cert(block_hash: Hash, validator: ValidatorIndex) -> IndirectAssignmentCert { + let ctx = schnorrkel::signing_context(RELAY_VRF_MODULO_CONTEXT); + let msg = b"WhenParachains?"; + let mut prng = rand_core::OsRng; + let keypair = schnorrkel::Keypair::generate_with(&mut prng); + let (inout, proof, _) = keypair.vrf_sign(ctx.bytes(msg)); + let out = inout.to_output(); + + IndirectAssignmentCert { + block_hash, + validator, + cert: AssignmentCert { + kind: AssignmentCertKind::RelayVRFModulo { sample: 1 }, + vrf: VrfSignature { output: VrfOutput(out), proof: VrfProof(proof) }, + }, + } +} + +async fn expect_reputation_change( + virtual_overseer: &mut VirtualOverseer, + peer_id: &PeerId, + rep: Rep, +) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer( + ReportPeerMessage::Single(p, r), + )) => { + assert_eq!(p, *peer_id); + assert_eq!(r, rep.into()); + } + ); +} + +async fn expect_reputation_changes( + virtual_overseer: &mut VirtualOverseer, + peer_id: &PeerId, + reps: Vec, +) { + let mut acc = HashMap::new(); + for rep in reps { + add_reputation(&mut acc, *peer_id, rep); + } + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer( + ReportPeerMessage::Batch(v), + )) => { + assert_eq!(v, acc); + } + ); +} + +fn state_without_reputation_delay() -> State { + State { reputation: ReputationAggregator::new(|_| true), ..Default::default() } +} + +fn state_with_reputation_delay() -> State { + State { reputation: ReputationAggregator::new(|_| false), ..Default::default() } +} + +/// import an assignment +/// connect a new peer +/// the new peer sends us the same assignment +#[test] +fn try_import_the_same_assignment() { + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let _ = test_harness(state_without_reputation_delay(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + // setup peers + setup_peer_with_view(overseer, &peer_a, ValidationVersion::V1, view![]).await; + setup_peer_with_view(overseer, &peer_b, ValidationVersion::V1, view![hash]).await; + setup_peer_with_view(overseer, &peer_c, ValidationVersion::V1, view![hash]).await; + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 2, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + // send the assignment related to `hash` + let validator_index = ValidatorIndex(0); + let cert = fake_assignment_cert(hash, validator_index); + let assignments = vec![(cert.clone(), 0u32)]; + + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments.clone()); + send_message_from_peer(overseer, &peer_a, Versioned::V1(msg)).await; + + expect_reputation_change(overseer, &peer_a, COST_UNEXPECTED_MESSAGE).await; + + // send an `Accept` message from the Approval Voting subsystem + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportAssignment( + assignment, + 0u32, + tx, + )) => { + assert_eq!(assignment, cert); + tx.send(AssignmentCheckResult::Accepted).unwrap(); + } + ); + + expect_reputation_change(overseer, &peer_a, BENEFIT_VALID_MESSAGE_FIRST).await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(assignments) + )) + )) => { + assert_eq!(peers.len(), 2); + assert_eq!(assignments.len(), 1); + } + ); + + // setup new peer + setup_peer_with_view(overseer, &peer_d, ValidationVersion::V1, view![]).await; + + // send the same assignment from peer_d + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments); + send_message_from_peer(overseer, &peer_d, Versioned::V1(msg)).await; + + expect_reputation_change(overseer, &peer_d, COST_UNEXPECTED_MESSAGE).await; + expect_reputation_change(overseer, &peer_d, BENEFIT_VALID_MESSAGE).await; + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }); +} + +/// import an assignment +/// connect a new peer +/// state sends aggregated reputation change +#[test] +fn delay_reputation_change() { + let peer = PeerId::random(); + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let _ = test_harness(state_with_reputation_delay(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + + // Setup peers + setup_peer_with_view(overseer, &peer, ValidationVersion::V1, view![]).await; + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 2, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + // send the assignment related to `hash` + let validator_index = ValidatorIndex(0); + let cert = fake_assignment_cert(hash, validator_index); + let assignments = vec![(cert.clone(), 0u32)]; + + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments.clone()); + send_message_from_peer(overseer, &peer, Versioned::V1(msg)).await; + + // send an `Accept` message from the Approval Voting subsystem + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportAssignment( + assignment, + 0u32, + tx, + )) => { + assert_eq!(assignment, cert); + tx.send(AssignmentCheckResult::Accepted).unwrap(); + } + ); + expect_reputation_changes( + overseer, + &peer, + vec![COST_UNEXPECTED_MESSAGE, BENEFIT_VALID_MESSAGE_FIRST], + ) + .await; + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + + virtual_overseer + }); +} + +/// +/// +/// 1. Send a view update that removes block B from their view. +/// 2. Send a message from B that they incur `COST_UNEXPECTED_MESSAGE` for, but then they receive +/// `BENEFIT_VALID_MESSAGE`. +/// 3. Send all other messages related to B. +#[test] +fn spam_attack_results_in_negative_reputation_change() { + let parent_hash = Hash::repeat_byte(0xFF); + let peer_a = PeerId::random(); + let hash_b = Hash::repeat_byte(0xBB); + + let _ = test_harness(state_without_reputation_delay(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + let peer = &peer_a; + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![]).await; + + // new block `hash_b` with 20 candidates + let candidates_count = 20; + let meta = BlockApprovalMeta { + hash: hash_b, + parent_hash, + number: 2, + candidates: vec![Default::default(); candidates_count], + slot: 1.into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + // send 20 assignments related to `hash_b` + // to populate our knowledge + let assignments: Vec<_> = (0..candidates_count) + .map(|candidate_index| { + let validator_index = ValidatorIndex(candidate_index as u32); + let cert = fake_assignment_cert(hash_b, validator_index); + (cert, candidate_index as u32) + }) + .collect(); + + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments.clone()); + send_message_from_peer(overseer, peer, Versioned::V1(msg.clone())).await; + + for i in 0..candidates_count { + expect_reputation_change(overseer, peer, COST_UNEXPECTED_MESSAGE).await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportAssignment( + assignment, + claimed_candidate_index, + tx, + )) => { + assert_eq!(assignment, assignments[i].0); + assert_eq!(claimed_candidate_index, assignments[i].1); + tx.send(AssignmentCheckResult::Accepted).unwrap(); + } + ); + + expect_reputation_change(overseer, peer, BENEFIT_VALID_MESSAGE_FIRST).await; + } + + // send a view update that removes block B from peer's view by bumping the finalized_number + overseer_send( + overseer, + ApprovalDistributionMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerViewChange( + *peer, + View::with_finalized(2), + )), + ) + .await; + + // send the assignments again + send_message_from_peer(overseer, peer, Versioned::V1(msg.clone())).await; + + // each of them will incur `COST_UNEXPECTED_MESSAGE`, not only the first one + for _ in 0..candidates_count { + expect_reputation_change(overseer, peer, COST_UNEXPECTED_MESSAGE).await; + expect_reputation_change(overseer, peer, BENEFIT_VALID_MESSAGE).await; + } + virtual_overseer + }); +} + +/// Imagine we send a message to peer A and peer B. +/// Upon receiving them, they both will try to send the message each other. +/// This test makes sure they will not punish each other for such duplicate messages. +/// +/// See . +#[test] +fn peer_sending_us_the_same_we_just_sent_them_is_ok() { + let parent_hash = Hash::repeat_byte(0xFF); + let peer_a = PeerId::random(); + let hash = Hash::repeat_byte(0xAA); + + let _ = test_harness(state_without_reputation_delay(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + let peer = &peer_a; + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![]).await; + + // new block `hash` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + // import an assignment related to `hash` locally + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + let cert = fake_assignment_cert(hash, validator_index); + overseer_send( + overseer, + ApprovalDistributionMessage::DistributeAssignment(cert.clone(), candidate_index), + ) + .await; + + // update peer view to include the hash + overseer_send( + overseer, + ApprovalDistributionMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerViewChange( + *peer, + view![hash], + )), + ) + .await; + + // we should send them the assignment + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(assignments) + )) + )) => { + assert_eq!(peers.len(), 1); + assert_eq!(assignments.len(), 1); + } + ); + + // but if someone else is sending it the same assignment + // the peer could send us it as well + let assignments = vec![(cert, candidate_index)]; + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments); + send_message_from_peer(overseer, peer, Versioned::V1(msg.clone())).await; + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "we should not punish the peer"); + + // send the assignments again + send_message_from_peer(overseer, peer, Versioned::V1(msg)).await; + + // now we should + expect_reputation_change(overseer, peer, COST_DUPLICATE_MESSAGE).await; + virtual_overseer + }); +} + +#[test] +fn import_approval_happy_path() { + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let _ = test_harness(state_without_reputation_delay(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + // setup peers + setup_peer_with_view(overseer, &peer_a, ValidationVersion::V1, view![]).await; + setup_peer_with_view(overseer, &peer_b, ValidationVersion::V1, view![hash]).await; + setup_peer_with_view(overseer, &peer_c, ValidationVersion::V1, view![hash]).await; + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + // import an assignment related to `hash` locally + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + let cert = fake_assignment_cert(hash, validator_index); + overseer_send( + overseer, + ApprovalDistributionMessage::DistributeAssignment(cert, candidate_index), + ) + .await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(assignments) + )) + )) => { + assert_eq!(peers.len(), 2); + assert_eq!(assignments.len(), 1); + } + ); + + // send the an approval from peer_b + let approval = IndirectSignedApprovalVote { + block_hash: hash, + candidate_index, + validator: validator_index, + signature: dummy_signature(), + }; + let msg = protocol_v1::ApprovalDistributionMessage::Approvals(vec![approval.clone()]); + send_message_from_peer(overseer, &peer_b, Versioned::V1(msg)).await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportApproval( + vote, + tx, + )) => { + assert_eq!(vote, approval); + tx.send(ApprovalCheckResult::Accepted).unwrap(); + } + ); + + expect_reputation_change(overseer, &peer_b, BENEFIT_VALID_MESSAGE_FIRST).await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(approvals) + )) + )) => { + assert_eq!(peers.len(), 1); + assert_eq!(approvals.len(), 1); + } + ); + virtual_overseer + }); +} + +#[test] +fn import_approval_bad() { + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let _ = test_harness(state_without_reputation_delay(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + // setup peers + setup_peer_with_view(overseer, &peer_a, ValidationVersion::V1, view![]).await; + setup_peer_with_view(overseer, &peer_b, ValidationVersion::V1, view![hash]).await; + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + let cert = fake_assignment_cert(hash, validator_index); + + // send the an approval from peer_b, we don't have an assignment yet + let approval = IndirectSignedApprovalVote { + block_hash: hash, + candidate_index, + validator: validator_index, + signature: dummy_signature(), + }; + let msg = protocol_v1::ApprovalDistributionMessage::Approvals(vec![approval.clone()]); + send_message_from_peer(overseer, &peer_b, Versioned::V1(msg)).await; + + expect_reputation_change(overseer, &peer_b, COST_UNEXPECTED_MESSAGE).await; + + // now import an assignment from peer_b + let assignments = vec![(cert.clone(), candidate_index)]; + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments); + send_message_from_peer(overseer, &peer_b, Versioned::V1(msg)).await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportAssignment( + assignment, + i, + tx, + )) => { + assert_eq!(assignment, cert); + assert_eq!(i, candidate_index); + tx.send(AssignmentCheckResult::Accepted).unwrap(); + } + ); + + expect_reputation_change(overseer, &peer_b, BENEFIT_VALID_MESSAGE_FIRST).await; + + // and try again + let msg = protocol_v1::ApprovalDistributionMessage::Approvals(vec![approval.clone()]); + send_message_from_peer(overseer, &peer_b, Versioned::V1(msg)).await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportApproval( + vote, + tx, + )) => { + assert_eq!(vote, approval); + tx.send(ApprovalCheckResult::Bad(ApprovalCheckError::UnknownBlock(hash))).unwrap(); + } + ); + + expect_reputation_change(overseer, &peer_b, COST_INVALID_MESSAGE).await; + virtual_overseer + }); +} + +/// make sure we clean up the state on block finalized +#[test] +fn update_our_view() { + let parent_hash = Hash::repeat_byte(0xFF); + let hash_a = Hash::repeat_byte(0xAA); + let hash_b = Hash::repeat_byte(0xBB); + let hash_c = Hash::repeat_byte(0xCC); + + let state = test_harness(State::default(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + // new block `hash_a` with 1 candidates + let meta_a = BlockApprovalMeta { + hash: hash_a, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let meta_b = BlockApprovalMeta { + hash: hash_b, + parent_hash: hash_a, + number: 2, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let meta_c = BlockApprovalMeta { + hash: hash_c, + parent_hash: hash_b, + number: 3, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta_a, meta_b, meta_c]); + overseer_send(overseer, msg).await; + virtual_overseer + }); + + assert!(state.blocks_by_number.get(&1).is_some()); + assert!(state.blocks_by_number.get(&2).is_some()); + assert!(state.blocks_by_number.get(&3).is_some()); + assert!(state.blocks.get(&hash_a).is_some()); + assert!(state.blocks.get(&hash_b).is_some()); + assert!(state.blocks.get(&hash_c).is_some()); + + let state = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + // finalize a block + overseer_signal_block_finalized(overseer, 2).await; + virtual_overseer + }); + + assert!(state.blocks_by_number.get(&1).is_none()); + assert!(state.blocks_by_number.get(&2).is_none()); + assert!(state.blocks_by_number.get(&3).is_some()); + assert!(state.blocks.get(&hash_a).is_none()); + assert!(state.blocks.get(&hash_b).is_none()); + assert!(state.blocks.get(&hash_c).is_some()); + + let state = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + // finalize a very high block + overseer_signal_block_finalized(overseer, 4_000_000_000).await; + virtual_overseer + }); + + assert!(state.blocks_by_number.get(&3).is_none()); + assert!(state.blocks.get(&hash_c).is_none()); +} + +/// make sure we unify with peers and clean up the state +#[test] +fn update_peer_view() { + let parent_hash = Hash::repeat_byte(0xFF); + let hash_a = Hash::repeat_byte(0xAA); + let hash_b = Hash::repeat_byte(0xBB); + let hash_c = Hash::repeat_byte(0xCC); + let hash_d = Hash::repeat_byte(0xDD); + let peer_a = PeerId::random(); + let peer = &peer_a; + + let state = test_harness(State::default(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + // new block `hash_a` with 1 candidates + let meta_a = BlockApprovalMeta { + hash: hash_a, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let meta_b = BlockApprovalMeta { + hash: hash_b, + parent_hash: hash_a, + number: 2, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let meta_c = BlockApprovalMeta { + hash: hash_c, + parent_hash: hash_b, + number: 3, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta_a, meta_b, meta_c]); + overseer_send(overseer, msg).await; + + let cert_a = fake_assignment_cert(hash_a, ValidatorIndex(0)); + let cert_b = fake_assignment_cert(hash_b, ValidatorIndex(0)); + + overseer_send(overseer, ApprovalDistributionMessage::DistributeAssignment(cert_a, 0)).await; + + overseer_send(overseer, ApprovalDistributionMessage::DistributeAssignment(cert_b, 0)).await; + + // connect a peer + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash_a]).await; + + // we should send relevant assignments to the peer + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(assignments) + )) + )) => { + assert_eq!(peers.len(), 1); + assert_eq!(assignments.len(), 1); + } + ); + virtual_overseer + }); + + assert_eq!(state.peer_data.get(peer).map(|data| data.view.finalized_number), Some(0)); + assert_eq!( + state + .blocks + .get(&hash_a) + .unwrap() + .known_by + .get(peer) + .unwrap() + .sent + .known_messages + .len(), + 1, + ); + + let state = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + // update peer's view + overseer_send( + overseer, + ApprovalDistributionMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerViewChange( + *peer, + View::new(vec![hash_b, hash_c, hash_d], 2), + )), + ) + .await; + + let cert_c = fake_assignment_cert(hash_c, ValidatorIndex(0)); + + overseer_send( + overseer, + ApprovalDistributionMessage::DistributeAssignment(cert_c.clone(), 0), + ) + .await; + + // we should send relevant assignments to the peer + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(assignments) + )) + )) => { + assert_eq!(peers.len(), 1); + assert_eq!(assignments.len(), 1); + assert_eq!(assignments[0].0, cert_c); + } + ); + virtual_overseer + }); + + assert_eq!(state.peer_data.get(peer).map(|data| data.view.finalized_number), Some(2)); + assert_eq!( + state + .blocks + .get(&hash_c) + .unwrap() + .known_by + .get(peer) + .unwrap() + .sent + .known_messages + .len(), + 1, + ); + + let finalized_number = 4_000_000_000; + let state = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + // update peer's view + overseer_send( + overseer, + ApprovalDistributionMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerViewChange( + *peer, + View::with_finalized(finalized_number), + )), + ) + .await; + virtual_overseer + }); + + assert_eq!( + state.peer_data.get(peer).map(|data| data.view.finalized_number), + Some(finalized_number) + ); + assert!(state.blocks.get(&hash_c).unwrap().known_by.get(peer).is_none()); +} + +/// E.g. if someone copies the keys... +#[test] +fn import_remotely_then_locally() { + let peer_a = PeerId::random(); + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + let peer = &peer_a; + + let _ = test_harness(state_without_reputation_delay(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + // setup the peer + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash]).await; + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + // import the assignment remotely first + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + let cert = fake_assignment_cert(hash, validator_index); + let assignments = vec![(cert.clone(), candidate_index)]; + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments.clone()); + send_message_from_peer(overseer, peer, Versioned::V1(msg)).await; + + // send an `Accept` message from the Approval Voting subsystem + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportAssignment( + assignment, + i, + tx, + )) => { + assert_eq!(assignment, cert); + assert_eq!(i, candidate_index); + tx.send(AssignmentCheckResult::Accepted).unwrap(); + } + ); + + expect_reputation_change(overseer, peer, BENEFIT_VALID_MESSAGE_FIRST).await; + + // import the same assignment locally + overseer_send( + overseer, + ApprovalDistributionMessage::DistributeAssignment(cert, candidate_index), + ) + .await; + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + + // send the approval remotely + let approval = IndirectSignedApprovalVote { + block_hash: hash, + candidate_index, + validator: validator_index, + signature: dummy_signature(), + }; + let msg = protocol_v1::ApprovalDistributionMessage::Approvals(vec![approval.clone()]); + send_message_from_peer(overseer, peer, Versioned::V1(msg)).await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportApproval( + vote, + tx, + )) => { + assert_eq!(vote, approval); + tx.send(ApprovalCheckResult::Accepted).unwrap(); + } + ); + expect_reputation_change(overseer, peer, BENEFIT_VALID_MESSAGE_FIRST).await; + + // import the same approval locally + overseer_send(overseer, ApprovalDistributionMessage::DistributeApproval(approval)).await; + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }); +} + +#[test] +fn sends_assignments_even_when_state_is_approved() { + let peer_a = PeerId::random(); + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + let peer = &peer_a; + + let _ = test_harness(State::default(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + + // import an assignment and approval locally. + let cert = fake_assignment_cert(hash, validator_index); + let approval = IndirectSignedApprovalVote { + block_hash: hash, + candidate_index, + validator: validator_index, + signature: dummy_signature(), + }; + + overseer_send( + overseer, + ApprovalDistributionMessage::DistributeAssignment(cert.clone(), candidate_index), + ) + .await; + + overseer_send(overseer, ApprovalDistributionMessage::DistributeApproval(approval.clone())) + .await; + + // connect the peer. + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash]).await; + + let assignments = vec![(cert.clone(), candidate_index)]; + let approvals = vec![approval.clone()]; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + assert_eq!(peers, vec![*peer]); + assert_eq!(sent_assignments, assignments); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(sent_approvals) + )) + )) => { + assert_eq!(peers, vec![*peer]); + assert_eq!(sent_approvals, approvals); + } + ); + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }); +} + +/// +/// +/// 1. Receive remote peer view update with an unknown head +/// 2. Receive assignments for that unknown head +/// 3. Update our view and import the new block +/// 4. Expect that no reputation with `COST_UNEXPECTED_MESSAGE` is applied +#[test] +fn race_condition_in_local_vs_remote_view_update() { + let parent_hash = Hash::repeat_byte(0xFF); + let peer_a = PeerId::random(); + let hash_b = Hash::repeat_byte(0xBB); + + let _ = test_harness(state_without_reputation_delay(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + let peer = &peer_a; + + // Test a small number of candidates + let candidates_count = 1; + let meta = BlockApprovalMeta { + hash: hash_b, + parent_hash, + number: 2, + candidates: vec![Default::default(); candidates_count], + slot: 1.into(), + session: 1, + }; + + // This will send a peer view that is ahead of our view + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash_b]).await; + + // Send our view update to include a new head + overseer_send( + overseer, + ApprovalDistributionMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view![hash_b], + )), + ) + .await; + + // send assignments related to `hash_b` but they will come to the MessagesPending + let assignments: Vec<_> = (0..candidates_count) + .map(|candidate_index| { + let validator_index = ValidatorIndex(candidate_index as u32); + let cert = fake_assignment_cert(hash_b, validator_index); + (cert, candidate_index as u32) + }) + .collect(); + + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments.clone()); + send_message_from_peer(overseer, peer, Versioned::V1(msg.clone())).await; + + // This will handle pending messages being processed + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + for i in 0..candidates_count { + // Previously, this has caused out-of-view assignments/approvals + //expect_reputation_change(overseer, peer, COST_UNEXPECTED_MESSAGE).await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportAssignment( + assignment, + claimed_candidate_index, + tx, + )) => { + assert_eq!(assignment, assignments[i].0); + assert_eq!(claimed_candidate_index, assignments[i].1); + tx.send(AssignmentCheckResult::Accepted).unwrap(); + } + ); + + // Since we have a valid statement pending, this should always occur + expect_reputation_change(overseer, peer, BENEFIT_VALID_MESSAGE_FIRST).await; + } + virtual_overseer + }); +} + +// Tests that local messages propagate to both dimensions. +#[test] +fn propagates_locally_generated_assignment_to_both_dimensions() { + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let peers = make_peers_and_authority_ids(100); + + let _ = test_harness(State::default(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + + // Connect all peers. + for (peer, _) in &peers { + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash]).await; + } + + // Set up a gossip topology. + setup_gossip_topology( + overseer, + make_gossip_topology(1, &peers, &[0, 10, 20, 30], &[50, 51, 52, 53]), + ) + .await; + + let expected_indices = [ + // Both dimensions in the gossip topology + 0, 10, 20, 30, 50, 51, 52, 53, + ]; + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + + // import an assignment and approval locally. + let cert = fake_assignment_cert(hash, validator_index); + let approval = IndirectSignedApprovalVote { + block_hash: hash, + candidate_index, + validator: validator_index, + signature: dummy_signature(), + }; + + overseer_send( + overseer, + ApprovalDistributionMessage::DistributeAssignment(cert.clone(), candidate_index), + ) + .await; + + overseer_send(overseer, ApprovalDistributionMessage::DistributeApproval(approval.clone())) + .await; + + let assignments = vec![(cert.clone(), candidate_index)]; + let approvals = vec![approval.clone()]; + + let assignment_sent_peers = assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + assert_eq!(sent_peers.len(), expected_indices.len() + 4); + for &i in &expected_indices { + assert!( + sent_peers.contains(&peers[i].0), + "Message not sent to expected peer {}", + i, + ); + } + assert_eq!(sent_assignments, assignments); + sent_peers + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(sent_approvals) + )) + )) => { + // Random sampling is reused from the assignment. + assert_eq!(sent_peers, assignment_sent_peers); + assert_eq!(sent_approvals, approvals); + } + ); + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }); +} + +// Tests that messages propagate to the unshared dimension. +#[test] +fn propagates_assignments_along_unshared_dimension() { + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let peers = make_peers_and_authority_ids(100); + + let _ = test_harness(state_without_reputation_delay(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + + // Connect all peers. + for (peer, _) in &peers { + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash]).await; + } + + // Set up a gossip topology. + setup_gossip_topology( + overseer, + make_gossip_topology(1, &peers, &[0, 10, 20, 30], &[50, 51, 52, 53]), + ) + .await; + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + // Test messages from X direction go to Y peers + { + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + + // import an assignment and approval locally. + let cert = fake_assignment_cert(hash, validator_index); + let assignments = vec![(cert.clone(), candidate_index)]; + + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments.clone()); + + // Issuer of the message is important, not the peer we receive from. + // 99 deliberately chosen because it's not in X or Y. + send_message_from_peer(overseer, &peers[99].0, Versioned::V1(msg)).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportAssignment( + _, + _, + tx, + )) => { + tx.send(AssignmentCheckResult::Accepted).unwrap(); + } + ); + expect_reputation_change(overseer, &peers[99].0, BENEFIT_VALID_MESSAGE_FIRST).await; + + let expected_y = [50, 51, 52, 53]; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + assert_eq!(sent_peers.len(), expected_y.len() + 4); + for &i in &expected_y { + assert!( + sent_peers.contains(&peers[i].0), + "Message not sent to expected peer {}", + i, + ); + } + assert_eq!(sent_assignments, assignments); + } + ); + }; + + // Test messages from X direction go to Y peers + { + let validator_index = ValidatorIndex(50); + let candidate_index = 0u32; + + // import an assignment and approval locally. + let cert = fake_assignment_cert(hash, validator_index); + let assignments = vec![(cert.clone(), candidate_index)]; + + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments.clone()); + + // Issuer of the message is important, not the peer we receive from. + // 99 deliberately chosen because it's not in X or Y. + send_message_from_peer(overseer, &peers[99].0, Versioned::V1(msg)).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportAssignment( + _, + _, + tx, + )) => { + tx.send(AssignmentCheckResult::Accepted).unwrap(); + } + ); + expect_reputation_change(overseer, &peers[99].0, BENEFIT_VALID_MESSAGE_FIRST).await; + + let expected_x = [0, 10, 20, 30]; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + assert_eq!(sent_peers.len(), expected_x.len() + 4); + for &i in &expected_x { + assert!( + sent_peers.contains(&peers[i].0), + "Message not sent to expected peer {}", + i, + ); + } + assert_eq!(sent_assignments, assignments); + } + ); + }; + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }); +} + +// tests that messages are propagated to necessary peers after they connect +#[test] +fn propagates_to_required_after_connect() { + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let peers = make_peers_and_authority_ids(100); + + let _ = test_harness(State::default(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + + let omitted = [0, 10, 50, 51]; + + // Connect all peers except omitted. + for (i, (peer, _)) in peers.iter().enumerate() { + if !omitted.contains(&i) { + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash]).await; + } + } + + // Set up a gossip topology. + setup_gossip_topology( + overseer, + make_gossip_topology(1, &peers, &[0, 10, 20, 30], &[50, 51, 52, 53]), + ) + .await; + + let expected_indices = [ + // Both dimensions in the gossip topology, minus omitted. + 20, 30, 52, 53, + ]; + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + + // import an assignment and approval locally. + let cert = fake_assignment_cert(hash, validator_index); + let approval = IndirectSignedApprovalVote { + block_hash: hash, + candidate_index, + validator: validator_index, + signature: dummy_signature(), + }; + + overseer_send( + overseer, + ApprovalDistributionMessage::DistributeAssignment(cert.clone(), candidate_index), + ) + .await; + + overseer_send(overseer, ApprovalDistributionMessage::DistributeApproval(approval.clone())) + .await; + + let assignments = vec![(cert.clone(), candidate_index)]; + let approvals = vec![approval.clone()]; + + let assignment_sent_peers = assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + assert_eq!(sent_peers.len(), expected_indices.len() + 4); + for &i in &expected_indices { + assert!( + sent_peers.contains(&peers[i].0), + "Message not sent to expected peer {}", + i, + ); + } + assert_eq!(sent_assignments, assignments); + sent_peers + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(sent_approvals) + )) + )) => { + // Random sampling is reused from the assignment. + assert_eq!(sent_peers, assignment_sent_peers); + assert_eq!(sent_approvals, approvals); + } + ); + + for i in omitted.iter().copied() { + setup_peer_with_view(overseer, &peers[i].0, ValidationVersion::V1, view![hash]).await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + assert_eq!(sent_peers.len(), 1); + assert_eq!(&sent_peers[0], &peers[i].0); + assert_eq!(sent_assignments, assignments); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(sent_approvals) + )) + )) => { + assert_eq!(sent_peers.len(), 1); + assert_eq!(&sent_peers[0], &peers[i].0); + assert_eq!(sent_approvals, approvals); + } + ); + } + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }); +} + +// test that new gossip topology triggers send of messages. +#[test] +fn sends_to_more_peers_after_getting_topology() { + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let peers = make_peers_and_authority_ids(100); + + let _ = test_harness(State::default(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + + // Connect all peers except omitted. + for (peer, _) in &peers { + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash]).await; + } + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + + // import an assignment and approval locally. + let cert = fake_assignment_cert(hash, validator_index); + let approval = IndirectSignedApprovalVote { + block_hash: hash, + candidate_index, + validator: validator_index, + signature: dummy_signature(), + }; + + overseer_send( + overseer, + ApprovalDistributionMessage::DistributeAssignment(cert.clone(), candidate_index), + ) + .await; + + overseer_send(overseer, ApprovalDistributionMessage::DistributeApproval(approval.clone())) + .await; + + let assignments = vec![(cert.clone(), candidate_index)]; + let approvals = vec![approval.clone()]; + + let mut expected_indices = vec![0, 10, 20, 30, 50, 51, 52, 53]; + let assignment_sent_peers = assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + // Only sends to random peers. + assert_eq!(sent_peers.len(), 4); + for peer in &sent_peers { + let i = peers.iter().position(|p| peer == &p.0).unwrap(); + // Random gossip before topology can send to topology-targeted peers. + // Remove them from the expected indices so we don't expect + // them to get the messages again after the assignment. + expected_indices.retain(|&i2| i2 != i); + } + assert_eq!(sent_assignments, assignments); + sent_peers + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(sent_approvals) + )) + )) => { + // Random sampling is reused from the assignment. + assert_eq!(sent_peers, assignment_sent_peers); + assert_eq!(sent_approvals, approvals); + } + ); + + // Set up a gossip topology. + setup_gossip_topology( + overseer, + make_gossip_topology(1, &peers, &[0, 10, 20, 30], &[50, 51, 52, 53]), + ) + .await; + + let mut expected_indices_assignments = expected_indices.clone(); + let mut expected_indices_approvals = expected_indices.clone(); + + for _ in 0..expected_indices_assignments.len() { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + // Sends to all expected peers. + assert_eq!(sent_peers.len(), 1); + assert_eq!(sent_assignments, assignments); + + let pos = expected_indices_assignments.iter() + .position(|i| &peers[*i].0 == &sent_peers[0]) + .unwrap(); + expected_indices_assignments.remove(pos); + } + ); + } + + for _ in 0..expected_indices_approvals.len() { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(sent_approvals) + )) + )) => { + // Sends to all expected peers. + assert_eq!(sent_peers.len(), 1); + assert_eq!(sent_approvals, approvals); + + let pos = expected_indices_approvals.iter() + .position(|i| &peers[*i].0 == &sent_peers[0]) + .unwrap(); + + expected_indices_approvals.remove(pos); + } + ); + } + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }); +} + +// test aggression L1 +#[test] +fn originator_aggression_l1() { + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let peers = make_peers_and_authority_ids(100); + + let mut state = State::default(); + state.aggression_config.resend_unfinalized_period = None; + let aggression_l1_threshold = state.aggression_config.l1_threshold.unwrap(); + + let _ = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + + // Connect all peers except omitted. + for (peer, _) in &peers { + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash]).await; + } + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + + // import an assignment and approval locally. + let cert = fake_assignment_cert(hash, validator_index); + let approval = IndirectSignedApprovalVote { + block_hash: hash, + candidate_index, + validator: validator_index, + signature: dummy_signature(), + }; + + // Set up a gossip topology. + setup_gossip_topology( + overseer, + make_gossip_topology(1, &peers, &[0, 10, 20, 30], &[50, 51, 52, 53]), + ) + .await; + + overseer_send( + overseer, + ApprovalDistributionMessage::DistributeAssignment(cert.clone(), candidate_index), + ) + .await; + + overseer_send(overseer, ApprovalDistributionMessage::DistributeApproval(approval.clone())) + .await; + + let assignments = vec![(cert.clone(), candidate_index)]; + let approvals = vec![approval.clone()]; + + let prev_sent_indices = assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(_) + )) + )) => { + sent_peers.into_iter() + .filter_map(|sp| peers.iter().position(|p| &p.0 == &sp)) + .collect::>() + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + _, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(_) + )) + )) => { } + ); + + // Add blocks until aggression L1 is triggered. + { + let mut parent_hash = hash; + for level in 0..aggression_l1_threshold { + let number = 1 + level + 1; // first block had number 1 + let hash = BlakeTwo256::hash_of(&(parent_hash, number)); + let meta = BlockApprovalMeta { + hash, + parent_hash, + number, + candidates: vec![], + slot: (level as u64).into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::ApprovalCheckingLagUpdate(level + 1); + overseer_send(overseer, msg).await; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + parent_hash = hash; + } + } + + let unsent_indices = + (0..peers.len()).filter(|i| !prev_sent_indices.contains(&i)).collect::>(); + + for _ in 0..unsent_indices.len() { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + // Sends to all expected peers. + assert_eq!(sent_peers.len(), 1); + assert_eq!(sent_assignments, assignments); + + assert!(unsent_indices.iter() + .any(|i| &peers[*i].0 == &sent_peers[0])); + } + ); + } + + for _ in 0..unsent_indices.len() { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(sent_approvals) + )) + )) => { + // Sends to all expected peers. + assert_eq!(sent_peers.len(), 1); + assert_eq!(sent_approvals, approvals); + + assert!(unsent_indices.iter() + .any(|i| &peers[*i].0 == &sent_peers[0])); + } + ); + } + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }); +} + +// test aggression L1 +#[test] +fn non_originator_aggression_l1() { + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let peers = make_peers_and_authority_ids(100); + + let mut state = state_without_reputation_delay(); + state.aggression_config.resend_unfinalized_period = None; + let aggression_l1_threshold = state.aggression_config.l1_threshold.unwrap(); + + let _ = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + + // Connect all peers except omitted. + for (peer, _) in &peers { + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash]).await; + } + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + + // import an assignment and approval locally. + let cert = fake_assignment_cert(hash, validator_index); + + // Set up a gossip topology. + setup_gossip_topology( + overseer, + make_gossip_topology(1, &peers, &[0, 10, 20, 30], &[50, 51, 52, 53]), + ) + .await; + + let assignments = vec![(cert.clone(), candidate_index)]; + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments.clone()); + + // Issuer of the message is important, not the peer we receive from. + // 99 deliberately chosen because it's not in X or Y. + send_message_from_peer(overseer, &peers[99].0, Versioned::V1(msg)).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportAssignment( + _, + _, + tx, + )) => { + tx.send(AssignmentCheckResult::Accepted).unwrap(); + } + ); + + expect_reputation_change(overseer, &peers[99].0, BENEFIT_VALID_MESSAGE_FIRST).await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + _, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(_) + )) + )) => { } + ); + + // Add blocks until aggression L1 is triggered. + { + let mut parent_hash = hash; + for level in 0..aggression_l1_threshold { + let number = 1 + level + 1; // first block had number 1 + let hash = BlakeTwo256::hash_of(&(parent_hash, number)); + let meta = BlockApprovalMeta { + hash, + parent_hash, + number, + candidates: vec![], + slot: (level as u64).into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + parent_hash = hash; + } + } + + // No-op on non-originator + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }); +} + +// test aggression L2 on non-originator +#[test] +fn non_originator_aggression_l2() { + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let peers = make_peers_and_authority_ids(100); + + let mut state = state_without_reputation_delay(); + state.aggression_config.resend_unfinalized_period = None; + + let aggression_l1_threshold = state.aggression_config.l1_threshold.unwrap(); + let aggression_l2_threshold = state.aggression_config.l2_threshold.unwrap(); + let _ = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + + // Connect all peers except omitted. + for (peer, _) in &peers { + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash]).await; + } + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + + // import an assignment and approval locally. + let cert = fake_assignment_cert(hash, validator_index); + + // Set up a gossip topology. + setup_gossip_topology( + overseer, + make_gossip_topology(1, &peers, &[0, 10, 20, 30], &[50, 51, 52, 53]), + ) + .await; + + let assignments = vec![(cert.clone(), candidate_index)]; + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments.clone()); + + // Issuer of the message is important, not the peer we receive from. + // 99 deliberately chosen because it's not in X or Y. + send_message_from_peer(overseer, &peers[99].0, Versioned::V1(msg)).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportAssignment( + _, + _, + tx, + )) => { + tx.send(AssignmentCheckResult::Accepted).unwrap(); + } + ); + + expect_reputation_change(overseer, &peers[99].0, BENEFIT_VALID_MESSAGE_FIRST).await; + + let prev_sent_indices = assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(_) + )) + )) => { + sent_peers.into_iter() + .filter_map(|sp| peers.iter().position(|p| &p.0 == &sp)) + .collect::>() + } + ); + + // Add blocks until aggression L1 is triggered. + let chain_head = { + let mut parent_hash = hash; + for level in 0..aggression_l1_threshold { + let number = 1 + level + 1; // first block had number 1 + let hash = BlakeTwo256::hash_of(&(parent_hash, number)); + let meta = BlockApprovalMeta { + hash, + parent_hash, + number, + candidates: vec![], + slot: (level as u64).into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::ApprovalCheckingLagUpdate(level + 1); + overseer_send(overseer, msg).await; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + parent_hash = hash; + } + + parent_hash + }; + + // No-op on non-originator + + // Add blocks until aggression L2 is triggered. + { + let mut parent_hash = chain_head; + for level in 0..aggression_l2_threshold - aggression_l1_threshold { + let number = aggression_l1_threshold + level + 1 + 1; // first block had number 1 + let hash = BlakeTwo256::hash_of(&(parent_hash, number)); + let meta = BlockApprovalMeta { + hash, + parent_hash, + number, + candidates: vec![], + slot: (level as u64).into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::ApprovalCheckingLagUpdate( + aggression_l1_threshold + level + 1, + ); + overseer_send(overseer, msg).await; + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + parent_hash = hash; + } + } + + // XY dimension - previously sent. + let unsent_indices = [0, 10, 20, 30, 50, 51, 52, 53] + .iter() + .cloned() + .filter(|i| !prev_sent_indices.contains(&i)) + .collect::>(); + + for _ in 0..unsent_indices.len() { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + // Sends to all expected peers. + assert_eq!(sent_peers.len(), 1); + assert_eq!(sent_assignments, assignments); + + assert!(unsent_indices.iter() + .any(|i| &peers[*i].0 == &sent_peers[0])); + } + ); + } + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }); +} + +// Tests that messages propagate to the unshared dimension. +#[test] +fn resends_messages_periodically() { + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let peers = make_peers_and_authority_ids(100); + + let mut state = state_without_reputation_delay(); + state.aggression_config.l1_threshold = None; + state.aggression_config.l2_threshold = None; + state.aggression_config.resend_unfinalized_period = Some(2); + let _ = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + + // Connect all peers. + for (peer, _) in &peers { + setup_peer_with_view(overseer, peer, ValidationVersion::V1, view![hash]).await; + } + + // Set up a gossip topology. + setup_gossip_topology( + overseer, + make_gossip_topology(1, &peers, &[0, 10, 20, 30], &[50, 51, 52, 53]), + ) + .await; + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + + // import an assignment and approval locally. + let cert = fake_assignment_cert(hash, validator_index); + let assignments = vec![(cert.clone(), candidate_index)]; + + { + let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments.clone()); + + // Issuer of the message is important, not the peer we receive from. + // 99 deliberately chosen because it's not in X or Y. + send_message_from_peer(overseer, &peers[99].0, Versioned::V1(msg)).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportAssignment( + _, + _, + tx, + )) => { + tx.send(AssignmentCheckResult::Accepted).unwrap(); + } + ); + expect_reputation_change(overseer, &peers[99].0, BENEFIT_VALID_MESSAGE_FIRST).await; + + let expected_y = [50, 51, 52, 53]; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + assert_eq!(sent_peers.len(), expected_y.len() + 4); + for &i in &expected_y { + assert!( + sent_peers.contains(&peers[i].0), + "Message not sent to expected peer {}", + i, + ); + } + assert_eq!(sent_assignments, assignments); + } + ); + }; + + let mut number = 1; + for _ in 0..10 { + // Add blocks until resend is done. + { + let mut parent_hash = hash; + for level in 0..2 { + number = number + 1; + let hash = BlakeTwo256::hash_of(&(parent_hash, number)); + let meta = BlockApprovalMeta { + hash, + parent_hash, + number, + candidates: vec![], + slot: (level as u64).into(), + session: 1, + }; + + let msg = ApprovalDistributionMessage::ApprovalCheckingLagUpdate(2); + overseer_send(overseer, msg).await; + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + parent_hash = hash; + } + } + + let mut expected_y = vec![50, 51, 52, 53]; + + // Expect messages sent only to topology peers, one by one. + for _ in 0..expected_y.len() { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + sent_peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + assert_eq!(sent_peers.len(), 1); + let expected_pos = expected_y.iter() + .position(|&i| &peers[i].0 == &sent_peers[0]) + .unwrap(); + + expected_y.remove(expected_pos); + assert_eq!(sent_assignments, assignments); + } + ); + } + } + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }); +} + +/// Tests that peers correctly receive versioned messages. +#[test] +fn import_versioned_approval() { + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let state = state_without_reputation_delay(); + let _ = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + // All peers are aware of relay parent. + setup_peer_with_view(overseer, &peer_a, ValidationVersion::VStaging, view![hash]).await; + setup_peer_with_view(overseer, &peer_b, ValidationVersion::V1, view![hash]).await; + setup_peer_with_view(overseer, &peer_c, ValidationVersion::VStaging, view![hash]).await; + + // new block `hash_a` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + }; + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + // import an assignment related to `hash` locally + let validator_index = ValidatorIndex(0); + let candidate_index = 0u32; + let cert = fake_assignment_cert(hash, validator_index); + overseer_send( + overseer, + ApprovalDistributionMessage::DistributeAssignment(cert, candidate_index), + ) + .await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(assignments) + )) + )) => { + assert_eq!(peers, vec![peer_b]); + assert_eq!(assignments.len(), 1); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::ApprovalDistribution( + protocol_vstaging::ApprovalDistributionMessage::Assignments(assignments) + )) + )) => { + assert_eq!(peers.len(), 2); + assert!(peers.contains(&peer_a)); + assert!(peers.contains(&peer_c)); + + assert_eq!(assignments.len(), 1); + } + ); + + // send the an approval from peer_a + let approval = IndirectSignedApprovalVote { + block_hash: hash, + candidate_index, + validator: validator_index, + signature: dummy_signature(), + }; + let msg = protocol_vstaging::ApprovalDistributionMessage::Approvals(vec![approval.clone()]); + send_message_from_peer(overseer, &peer_a, Versioned::VStaging(msg)).await; + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::CheckAndImportApproval( + vote, + tx, + )) => { + assert_eq!(vote, approval); + tx.send(ApprovalCheckResult::Accepted).unwrap(); + } + ); + + expect_reputation_change(overseer, &peer_a, BENEFIT_VALID_MESSAGE_FIRST).await; + + // Peers b and c receive versioned approval messages. + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(approvals) + )) + )) => { + assert_eq!(peers, vec![peer_b]); + assert_eq!(approvals.len(), 1); + } + ); + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::ApprovalDistribution( + protocol_vstaging::ApprovalDistributionMessage::Approvals(approvals) + )) + )) => { + assert_eq!(peers, vec![peer_c]); + assert_eq!(approvals.len(), 1); + } + ); + virtual_overseer + }); +} + +fn batch_test_round(message_count: usize) { + use polkadot_node_subsystem::SubsystemContext; + let pool = sp_core::testing::TaskExecutor::new(); + let mut state = State::default(); + + let (mut context, mut virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); + let subsystem = ApprovalDistribution::new(Default::default()); + let mut rng = rand_chacha::ChaCha12Rng::seed_from_u64(12345); + let mut sender = context.sender().clone(); + let subsystem = + subsystem.run_inner(context, &mut state, REPUTATION_CHANGE_TEST_INTERVAL, &mut rng); + + let test_fut = async move { + let overseer = &mut virtual_overseer; + let validators = 0..message_count; + let assignments: Vec<_> = validators + .clone() + .map(|index| (fake_assignment_cert(Hash::zero(), ValidatorIndex(index as u32)), 0)) + .collect(); + + let approvals: Vec<_> = validators + .map(|index| IndirectSignedApprovalVote { + block_hash: Hash::zero(), + candidate_index: 0, + validator: ValidatorIndex(index as u32), + signature: dummy_signature(), + }) + .collect(); + + let peer = PeerId::random(); + send_assignments_batched(&mut sender, assignments.clone(), peer, ValidationVersion::V1) + .await; + send_approvals_batched(&mut sender, approvals.clone(), peer, ValidationVersion::V1).await; + + // Check expected assignments batches. + for assignment_index in (0..assignments.len()).step_by(super::MAX_ASSIGNMENT_BATCH_SIZE) { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Assignments(sent_assignments) + )) + )) => { + // Last batch should cover all remaining messages. + if sent_assignments.len() < super::MAX_ASSIGNMENT_BATCH_SIZE { + assert_eq!(sent_assignments.len() + assignment_index, assignments.len()); + } else { + assert_eq!(sent_assignments.len(), super::MAX_ASSIGNMENT_BATCH_SIZE); + } + + assert_eq!(peers.len(), 1); + + for (message_index, assignment) in sent_assignments.iter().enumerate() { + assert_eq!(assignment.0, assignments[assignment_index + message_index].0); + assert_eq!(assignment.1, 0); + } + } + ); + } + + // Check approval vote batching. + for approval_index in (0..approvals.len()).step_by(super::MAX_APPROVAL_BATCH_SIZE) { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V1(protocol_v1::ValidationProtocol::ApprovalDistribution( + protocol_v1::ApprovalDistributionMessage::Approvals(sent_approvals) + )) + )) => { + // Last batch should cover all remaining messages. + if sent_approvals.len() < super::MAX_APPROVAL_BATCH_SIZE { + assert_eq!(sent_approvals.len() + approval_index, approvals.len()); + } else { + assert_eq!(sent_approvals.len(), super::MAX_APPROVAL_BATCH_SIZE); + } + + assert_eq!(peers.len(), 1); + + for (message_index, approval) in sent_approvals.iter().enumerate() { + assert_eq!(approval, &approvals[approval_index + message_index]); + } + } + ); + } + virtual_overseer + }; + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer + .send(FromOrchestra::Signal(OverseerSignal::Conclude)) + .timeout(TIMEOUT) + .await + .expect("Conclude send timeout"); + }, + subsystem, + )); +} + +#[test] +fn batch_sending_1_msg() { + batch_test_round(1); +} + +#[test] +fn batch_sending_exactly_one_batch() { + batch_test_round(super::MAX_APPROVAL_BATCH_SIZE); + batch_test_round(super::MAX_ASSIGNMENT_BATCH_SIZE); +} + +#[test] +fn batch_sending_partial_batch() { + batch_test_round(super::MAX_APPROVAL_BATCH_SIZE * 2 + 4); + batch_test_round(super::MAX_ASSIGNMENT_BATCH_SIZE * 2 + 4); +} + +#[test] +fn batch_sending_multiple_same_len() { + batch_test_round(super::MAX_APPROVAL_BATCH_SIZE * 10); + batch_test_round(super::MAX_ASSIGNMENT_BATCH_SIZE * 10); +} + +#[test] +fn batch_sending_half_batch() { + batch_test_round(super::MAX_APPROVAL_BATCH_SIZE / 2); + batch_test_round(super::MAX_ASSIGNMENT_BATCH_SIZE / 2); +} + +#[test] +#[should_panic] +fn const_batch_size_panics_if_zero() { + crate::ensure_size_not_zero(0); +} + +#[test] +fn const_ensure_size_not_zero() { + crate::ensure_size_not_zero(super::MAX_ASSIGNMENT_BATCH_SIZE); + crate::ensure_size_not_zero(super::MAX_APPROVAL_BATCH_SIZE); +} diff --git a/polkadot/node/network/availability-distribution/Cargo.toml b/polkadot/node/network/availability-distribution/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..823439f1fd65d6dbd7a30d88f9df152668370a6e --- /dev/null +++ b/polkadot/node/network/availability-distribution/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "polkadot-availability-distribution" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +gum = { package = "tracing-gum", path = "../../gum" } +parity-scale-codec = { version = "3.6.1", features = ["std"] } +polkadot-primitives = { path = "../../../primitives" } +polkadot-erasure-coding = { path = "../../../erasure-coding" } +polkadot-node-network-protocol = { path = "../../network/protocol" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-node-primitives = { path = "../../primitives" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["std"] } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +thiserror = "1.0.31" +rand = "0.8.5" +derive_more = "0.99.17" +lru = "0.11.0" +fatality = "0.0.6" + +[dev-dependencies] +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["std"] } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures-timer = "3.0.2" +assert_matches = "1.4.0" +polkadot-primitives-test-helpers = { path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/network/availability-distribution/src/error.rs b/polkadot/node/network/availability-distribution/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..c547a1abbc27604862cebef2790223a0b54fac37 --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/error.rs @@ -0,0 +1,117 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +// + +//! Error handling related code and Error/Result definitions. + +use fatality::Nested; +use polkadot_node_network_protocol::request_response::outgoing::RequestError; +use polkadot_primitives::SessionIndex; + +use futures::channel::oneshot; + +use polkadot_node_subsystem::{ChainApiError, SubsystemError}; +use polkadot_node_subsystem_util::runtime; + +use crate::LOG_TARGET; + +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + #[fatal] + #[error("Spawning subsystem task failed: {0}")] + SpawnTask(#[source] SubsystemError), + + #[fatal] + #[error("Erasure chunk requester stream exhausted")] + RequesterExhausted, + + #[fatal] + #[error("Receive channel closed: {0}")] + IncomingMessageChannel(#[source] SubsystemError), + + #[fatal(forward)] + #[error("Error while accessing runtime information: {0}")] + Runtime(#[from] runtime::Error), + + #[fatal] + #[error("Oneshot for receiving response from Chain API got cancelled")] + ChainApiSenderDropped(#[source] oneshot::Canceled), + + #[fatal] + #[error("Retrieving response from Chain API unexpectedly failed with error: {0}")] + ChainApi(#[from] ChainApiError), + + // av-store will drop the sender on any error that happens. + #[error("Response channel to obtain chunk failed")] + QueryChunkResponseChannel(#[source] oneshot::Canceled), + + // av-store will drop the sender on any error that happens. + #[error("Response channel to obtain available data failed")] + QueryAvailableDataResponseChannel(#[source] oneshot::Canceled), + + // We tried accessing a session that was not cached. + #[error("Session {missing_session} is not cached, cached sessions: {available_sessions:?}.")] + NoSuchCachedSession { available_sessions: Vec, missing_session: SessionIndex }, + + // Sending request response failed (Can happen on timeouts for example). + #[error("Sending a request's response failed.")] + SendResponse, + + #[error("FetchPoV request error: {0}")] + FetchPoV(#[source] RequestError), + + #[error("Fetched PoV does not match expected hash")] + UnexpectedPoV, + + #[error("Remote responded with `NoSuchPoV`")] + NoSuchPoV, + + #[error("Given validator index could not be found in current session")] + InvalidValidatorIndex, +} + +/// General result abbreviation type alias. +pub type Result = std::result::Result; + +/// Utility for eating top level errors and log them. +/// +/// We basically always want to try and continue on error. This utility function is meant to +/// consume top-level errors by simply logging them +pub fn log_error( + result: Result<()>, + ctx: &'static str, + warn_freq: &mut gum::Freq, +) -> std::result::Result<(), FatalError> { + match result.into_nested()? { + Ok(()) => Ok(()), + Err(jfyi) => { + match jfyi { + JfyiError::UnexpectedPoV | + JfyiError::InvalidValidatorIndex | + JfyiError::NoSuchCachedSession { .. } | + JfyiError::QueryAvailableDataResponseChannel(_) | + JfyiError::QueryChunkResponseChannel(_) => gum::warn!(target: LOG_TARGET, error = %jfyi, ctx), + JfyiError::FetchPoV(_) | + JfyiError::SendResponse | + JfyiError::NoSuchPoV | + JfyiError::Runtime(_) => + gum::warn_if_frequent!(freq: warn_freq, max_rate: gum::Times::PerHour(100), target: LOG_TARGET, error = ?jfyi, ctx), + } + Ok(()) + }, + } +} diff --git a/polkadot/node/network/availability-distribution/src/lib.rs b/polkadot/node/network/availability-distribution/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..c62ce1dd981a9ce8c4fe6e2b7c451a401e609b25 --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/lib.rs @@ -0,0 +1,199 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use futures::{future::Either, FutureExt, StreamExt, TryFutureExt}; + +use sp_keystore::KeystorePtr; + +use polkadot_node_network_protocol::request_response::{v1, IncomingRequestReceiver}; +use polkadot_node_subsystem::{ + jaeger, messages::AvailabilityDistributionMessage, overseer, FromOrchestra, OverseerSignal, + SpawnedSubsystem, SubsystemError, +}; +use polkadot_primitives::Hash; +use std::collections::HashMap; + +/// Error and [`Result`] type for this subsystem. +mod error; +use error::{log_error, FatalError, Result}; + +use polkadot_node_subsystem_util::runtime::RuntimeInfo; + +/// `Requester` taking care of requesting chunks for candidates pending availability. +mod requester; +use requester::Requester; + +/// Handing requests for PoVs during backing. +mod pov_requester; + +/// Responding to erasure chunk requests: +mod responder; +use responder::{run_chunk_receiver, run_pov_receiver}; + +mod metrics; +/// Prometheus `Metrics` for availability distribution. +pub use metrics::Metrics; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &'static str = "parachain::availability-distribution"; + +/// The availability distribution subsystem. +pub struct AvailabilityDistributionSubsystem { + /// Easy and efficient runtime access for this subsystem. + runtime: RuntimeInfo, + /// Receivers to receive messages from. + recvs: IncomingRequestReceivers, + /// Prometheus metrics. + metrics: Metrics, +} + +/// Receivers to be passed into availability distribution. +pub struct IncomingRequestReceivers { + /// Receiver for incoming PoV requests. + pub pov_req_receiver: IncomingRequestReceiver, + /// Receiver for incoming availability chunk requests. + pub chunk_req_receiver: IncomingRequestReceiver, +} + +#[overseer::subsystem(AvailabilityDistribution, error=SubsystemError, prefix=self::overseer)] +impl AvailabilityDistributionSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = self + .run(ctx) + .map_err(|e| SubsystemError::with_origin("availability-distribution", e)) + .boxed(); + + SpawnedSubsystem { name: "availability-distribution-subsystem", future } + } +} + +#[overseer::contextbounds(AvailabilityDistribution, prefix = self::overseer)] +impl AvailabilityDistributionSubsystem { + /// Create a new instance of the availability distribution. + pub fn new(keystore: KeystorePtr, recvs: IncomingRequestReceivers, metrics: Metrics) -> Self { + let runtime = RuntimeInfo::new(Some(keystore)); + Self { runtime, recvs, metrics } + } + + /// Start processing work as passed on from the Overseer. + async fn run(self, mut ctx: Context) -> std::result::Result<(), FatalError> { + let Self { mut runtime, recvs, metrics } = self; + let mut spans: HashMap = HashMap::new(); + + let IncomingRequestReceivers { pov_req_receiver, chunk_req_receiver } = recvs; + let mut requester = Requester::new(metrics.clone()).fuse(); + let mut warn_freq = gum::Freq::new(); + + { + let sender = ctx.sender().clone(); + ctx.spawn( + "pov-receiver", + run_pov_receiver(sender.clone(), pov_req_receiver, metrics.clone()).boxed(), + ) + .map_err(FatalError::SpawnTask)?; + + ctx.spawn( + "chunk-receiver", + run_chunk_receiver(sender, chunk_req_receiver, metrics.clone()).boxed(), + ) + .map_err(FatalError::SpawnTask)?; + } + + loop { + let action = { + let mut subsystem_next = ctx.recv().fuse(); + futures::select! { + subsystem_msg = subsystem_next => Either::Left(subsystem_msg), + from_task = requester.next() => Either::Right(from_task), + } + }; + + // Handle task messages sending: + let message = match action { + Either::Left(subsystem_msg) => + subsystem_msg.map_err(|e| FatalError::IncomingMessageChannel(e))?, + Either::Right(from_task) => { + let from_task = from_task.ok_or(FatalError::RequesterExhausted)?; + ctx.send_message(from_task).await; + continue + }, + }; + match message { + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => { + let cloned_leaf = match update.activated.clone() { + Some(activated) => activated, + None => continue, + }; + let span = + jaeger::PerLeafSpan::new(cloned_leaf.span, "availability-distribution"); + spans.insert(cloned_leaf.hash, span); + log_error( + requester + .get_mut() + .update_fetching_heads(&mut ctx, &mut runtime, update, &spans) + .await, + "Error in Requester::update_fetching_heads", + &mut warn_freq, + )?; + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(hash, _)) => { + spans.remove(&hash); + }, + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), + FromOrchestra::Communication { + msg: + AvailabilityDistributionMessage::FetchPoV { + relay_parent, + from_validator, + para_id, + candidate_hash, + pov_hash, + tx, + }, + } => { + let span = spans + .get(&relay_parent) + .map(|span| span.child("fetch-pov")) + .unwrap_or_else(|| jaeger::Span::new(&relay_parent, "fetch-pov")) + .with_trace_id(candidate_hash) + .with_candidate(candidate_hash) + .with_relay_parent(relay_parent) + .with_stage(jaeger::Stage::AvailabilityDistribution); + + log_error( + pov_requester::fetch_pov( + &mut ctx, + &mut runtime, + relay_parent, + from_validator, + para_id, + candidate_hash, + pov_hash, + tx, + metrics.clone(), + &span, + ) + .await, + "pov_requester::fetch_pov", + &mut warn_freq, + )?; + }, + } + } + } +} diff --git a/polkadot/node/network/availability-distribution/src/metrics.rs b/polkadot/node/network/availability-distribution/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..bc724be10d9b7654d8592045704966cf0bae62f1 --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/metrics.rs @@ -0,0 +1,156 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::{ + metrics, + metrics::{ + prometheus, + prometheus::{Counter, CounterVec, Opts, PrometheusError, Registry, U64}, + }, +}; + +/// Label for success counters. +pub const SUCCEEDED: &'static str = "succeeded"; + +/// Label for fail counters. +pub const FAILED: &'static str = "failed"; + +/// Label for chunks/PoVs that could not be served, because they were not available. +pub const NOT_FOUND: &'static str = "not-found"; + +/// Availability Distribution metrics. +#[derive(Clone, Default)] +pub struct Metrics(Option); + +#[derive(Clone)] +struct MetricsInner { + /// Number of chunks fetched. + /// + /// Note: The failed count gets incremented, when we were not able to fetch the chunk at all. + /// For times, where we failed downloading, but succeeded on the next try (with different + /// backers), see `retries`. + fetched_chunks: CounterVec, + + /// Number of chunks served. + served_chunks: CounterVec, + + /// Number of received fetch PoV responses. + fetched_povs: CounterVec, + + /// Number of PoVs served. + served_povs: CounterVec, + + /// Number of times our first set of validators did not provide the needed chunk and we had to + /// query further validators. + retries: Counter, +} + +impl Metrics { + /// Create new dummy metrics, not reporting anything. + pub fn new_dummy() -> Self { + Metrics(None) + } + + /// Increment counter on fetched labels. + pub fn on_fetch(&self, label: &'static str) { + if let Some(metrics) = &self.0 { + metrics.fetched_chunks.with_label_values(&[label]).inc() + } + } + + /// Increment counter on served chunks. + pub fn on_served_chunk(&self, label: &'static str) { + if let Some(metrics) = &self.0 { + metrics.served_chunks.with_label_values(&[label]).inc() + } + } + + /// Increment counter on fetched PoVs. + pub fn on_fetched_pov(&self, label: &'static str) { + if let Some(metrics) = &self.0 { + metrics.fetched_povs.with_label_values(&[label]).inc() + } + } + + /// Increment counter on served PoVs. + pub fn on_served_pov(&self, label: &'static str) { + if let Some(metrics) = &self.0 { + metrics.served_povs.with_label_values(&[label]).inc() + } + } + + /// Increment retry counter. + pub fn on_retry(&self) { + if let Some(metrics) = &self.0 { + metrics.retries.inc() + } + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &Registry) -> Result { + let metrics = MetricsInner { + fetched_chunks: prometheus::register( + CounterVec::new( + Opts::new( + "polkadot_parachain_fetched_chunks_total", + "Total number of fetched chunks.", + ), + &["success"] + )?, + registry, + )?, + served_chunks: prometheus::register( + CounterVec::new( + Opts::new( + "polkadot_parachain_served_chunks_total", + "Total number of chunks served by this backer.", + ), + &["success"] + )?, + registry, + )?, + fetched_povs: prometheus::register( + CounterVec::new( + Opts::new( + "polkadot_parachain_fetched_povs_total", + "Total number of povs fetches by this backer.", + ), + &["success"] + )?, + registry, + )?, + served_povs: prometheus::register( + CounterVec::new( + Opts::new( + "polkadot_parachain_served_povs_total", + "Total number of povs served by this backer.", + ), + &["success"] + )?, + registry, + )?, + retries: prometheus::register( + Counter::new( + "polkadot_parachain_fetch_retries_total", + "Number of times we did not succeed in fetching a chunk and needed to try more backers.", + )?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/network/availability-distribution/src/pov_requester/mod.rs b/polkadot/node/network/availability-distribution/src/pov_requester/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..8fc9fa82153e2035d8c037b8b6b86caf638bf5cc --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/pov_requester/mod.rs @@ -0,0 +1,237 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! PoV requester takes care of requesting PoVs from validators of a backing group. + +use futures::{channel::oneshot, future::BoxFuture, FutureExt}; + +use polkadot_node_network_protocol::request_response::{ + outgoing::{RequestError, Requests}, + v1::{PoVFetchingRequest, PoVFetchingResponse}, + OutgoingRequest, Recipient, +}; +use polkadot_node_primitives::PoV; +use polkadot_node_subsystem::{ + jaeger, + messages::{IfDisconnected, NetworkBridgeTxMessage}, + overseer, +}; +use polkadot_node_subsystem_util::runtime::RuntimeInfo; +use polkadot_primitives::{ + AuthorityDiscoveryId, CandidateHash, Hash, Id as ParaId, ValidatorIndex, +}; + +use crate::{ + error::{Error, FatalError, JfyiError, Result}, + metrics::{FAILED, NOT_FOUND, SUCCEEDED}, + Metrics, LOG_TARGET, +}; + +/// Start background worker for taking care of fetching the requested `PoV` from the network. +#[overseer::contextbounds(AvailabilityDistribution, prefix = self::overseer)] +pub async fn fetch_pov( + ctx: &mut Context, + runtime: &mut RuntimeInfo, + parent: Hash, + from_validator: ValidatorIndex, + para_id: ParaId, + candidate_hash: CandidateHash, + pov_hash: Hash, + tx: oneshot::Sender, + metrics: Metrics, + span: &jaeger::Span, +) -> Result<()> { + let _span = span + .child("fetch-pov") + .with_trace_id(candidate_hash) + .with_validator_index(from_validator) + .with_candidate(candidate_hash) + .with_para_id(para_id) + .with_relay_parent(parent) + .with_string_tag("pov-hash", format!("{:?}", pov_hash)) + .with_stage(jaeger::Stage::AvailabilityDistribution); + + let info = &runtime.get_session_info(ctx.sender(), parent).await?.session_info; + let authority_id = info + .discovery_keys + .get(from_validator.0 as usize) + .ok_or(JfyiError::InvalidValidatorIndex)? + .clone(); + let (req, pending_response) = OutgoingRequest::new( + Recipient::Authority(authority_id.clone()), + PoVFetchingRequest { candidate_hash }, + ); + let full_req = Requests::PoVFetchingV1(req); + + ctx.send_message(NetworkBridgeTxMessage::SendRequests( + vec![full_req], + IfDisconnected::ImmediateError, + )) + .await; + + ctx.spawn( + "pov-fetcher", + fetch_pov_job(para_id, pov_hash, authority_id, pending_response.boxed(), tx, metrics) + .boxed(), + ) + .map_err(|e| FatalError::SpawnTask(e))?; + Ok(()) +} + +/// Future to be spawned for taking care of handling reception and sending of PoV. +async fn fetch_pov_job( + para_id: ParaId, + pov_hash: Hash, + authority_id: AuthorityDiscoveryId, + pending_response: BoxFuture<'static, std::result::Result>, + tx: oneshot::Sender, + metrics: Metrics, +) { + if let Err(err) = do_fetch_pov(pov_hash, pending_response, tx, metrics).await { + gum::warn!(target: LOG_TARGET, ?err, ?para_id, ?pov_hash, ?authority_id, "fetch_pov_job"); + } +} + +/// Do the actual work of waiting for the response. +async fn do_fetch_pov( + pov_hash: Hash, + pending_response: BoxFuture<'static, std::result::Result>, + tx: oneshot::Sender, + metrics: Metrics, +) -> Result<()> { + let response = pending_response.await.map_err(Error::FetchPoV); + let pov = match response { + Ok(PoVFetchingResponse::PoV(pov)) => pov, + Ok(PoVFetchingResponse::NoSuchPoV) => { + metrics.on_fetched_pov(NOT_FOUND); + return Err(Error::NoSuchPoV) + }, + Err(err) => { + metrics.on_fetched_pov(FAILED); + return Err(err) + }, + }; + if pov.hash() == pov_hash { + metrics.on_fetched_pov(SUCCEEDED); + tx.send(pov).map_err(|_| Error::SendResponse) + } else { + metrics.on_fetched_pov(FAILED); + Err(Error::UnexpectedPoV) + } +} + +#[cfg(test)] +mod tests { + use assert_matches::assert_matches; + use futures::{executor, future}; + + use parity_scale_codec::Encode; + use sp_core::testing::TaskExecutor; + + use polkadot_node_primitives::BlockData; + use polkadot_node_subsystem::messages::{ + AllMessages, AvailabilityDistributionMessage, RuntimeApiMessage, RuntimeApiRequest, + }; + use polkadot_node_subsystem_test_helpers as test_helpers; + use polkadot_primitives::{CandidateHash, Hash, ValidatorIndex}; + use test_helpers::mock::make_ferdie_keystore; + + use super::*; + use crate::{tests::mock::make_session_info, LOG_TARGET}; + + #[test] + fn rejects_invalid_pov() { + sp_tracing::try_init_simple(); + let pov = PoV { block_data: BlockData(vec![1, 2, 3, 4, 5, 6]) }; + test_run(Hash::default(), pov); + } + + #[test] + fn accepts_valid_pov() { + sp_tracing::try_init_simple(); + let pov = PoV { block_data: BlockData(vec![1, 2, 3, 4, 5, 6]) }; + test_run(pov.hash(), pov); + } + + fn test_run(pov_hash: Hash, pov: PoV) { + let pool = TaskExecutor::new(); + let (mut context, mut virtual_overseer) = test_helpers::make_subsystem_context::< + AvailabilityDistributionMessage, + TaskExecutor, + >(pool.clone()); + let keystore = make_ferdie_keystore(); + let mut runtime = polkadot_node_subsystem_util::runtime::RuntimeInfo::new(Some(keystore)); + + let (tx, rx) = oneshot::channel(); + let testee = async { + fetch_pov( + &mut context, + &mut runtime, + Hash::default(), + ValidatorIndex(0), + ParaId::default(), + CandidateHash::default(), + pov_hash, + tx, + Metrics::new_dummy(), + &jaeger::Span::Disabled, + ) + .await + .expect("Should succeed"); + }; + + let tester = async move { + loop { + match virtual_overseer.recv().await { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + tx.send(Ok(0)).unwrap(); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionInfo(_, tx), + )) => { + tx.send(Ok(Some(make_session_info()))).unwrap(); + }, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendRequests( + mut reqs, + _, + )) => { + let req = assert_matches!( + reqs.pop(), + Some(Requests::PoVFetchingV1(outgoing)) => {outgoing} + ); + req.pending_response + .send(Ok(PoVFetchingResponse::PoV(pov.clone()).encode())) + .unwrap(); + break + }, + msg => gum::debug!(target: LOG_TARGET, msg = ?msg, "Received msg"), + } + } + if pov.hash() == pov_hash { + assert_eq!(rx.await, Ok(pov)); + } else { + assert_eq!(rx.await, Err(oneshot::Canceled)); + } + }; + futures::pin_mut!(testee); + futures::pin_mut!(tester); + executor::block_on(future::join(testee, tester)); + } +} diff --git a/polkadot/node/network/availability-distribution/src/requester/fetch_task/mod.rs b/polkadot/node/network/availability-distribution/src/requester/fetch_task/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..191ee2acd973b2391773a8ca8e5fdcf7032009e5 --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/requester/fetch_task/mod.rs @@ -0,0 +1,502 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::collections::HashSet; + +use futures::{ + channel::{mpsc, oneshot}, + future::select, + FutureExt, SinkExt, +}; + +use polkadot_erasure_coding::branch_hash; +use polkadot_node_network_protocol::request_response::{ + outgoing::{OutgoingRequest, Recipient, RequestError, Requests}, + v1::{ChunkFetchingRequest, ChunkFetchingResponse}, +}; +use polkadot_node_primitives::ErasureChunk; +use polkadot_node_subsystem::{ + jaeger, + messages::{AvailabilityStoreMessage, IfDisconnected, NetworkBridgeTxMessage}, + overseer, +}; +use polkadot_primitives::{ + AuthorityDiscoveryId, BlakeTwo256, CandidateHash, GroupIndex, Hash, HashT, OccupiedCore, + SessionIndex, +}; + +use crate::{ + error::{FatalError, Result}, + metrics::{Metrics, FAILED, SUCCEEDED}, + requester::session_cache::{BadValidators, SessionInfo}, + LOG_TARGET, +}; + +#[cfg(test)] +mod tests; + +/// Configuration for a `FetchTask` +/// +/// This exists to separate preparation of a `FetchTask` from actual starting it, which is +/// beneficial as this allows as for taking session info by reference. +pub struct FetchTaskConfig { + prepared_running: Option, + live_in: HashSet, +} + +/// Information about a task fetching an erasure chunk. +pub struct FetchTask { + /// For what relay parents this task is relevant. + /// + /// In other words, for which relay chain parents this candidate is considered live. + /// This is updated on every `ActiveLeavesUpdate` and enables us to know when we can safely + /// stop keeping track of that candidate/chunk. + pub(crate) live_in: HashSet, + + /// We keep the task around in until `live_in` becomes empty, to make + /// sure we won't re-fetch an already fetched candidate. + state: FetchedState, +} + +/// State of a particular candidate chunk fetching process. +enum FetchedState { + /// Chunk fetch has started. + /// + /// Once the contained `Sender` is dropped, any still running task will be canceled. + Started(oneshot::Sender<()>), + /// All relevant `live_in` have been removed, before we were able to get our chunk. + Canceled, +} + +/// Messages sent from `FetchTask`s to be handled/forwarded. +pub enum FromFetchTask { + /// Message to other subsystem. + Message(overseer::AvailabilityDistributionOutgoingMessages), + + /// Concluded with result. + /// + /// In case of `None` everything was fine, in case of `Some`, some validators in the group + /// did not serve us our chunk as expected. + Concluded(Option), + + /// We were not able to fetch the desired chunk for the given `CandidateHash`. + Failed(CandidateHash), +} + +/// Information a running task needs. +struct RunningTask { + /// For what session we have been spawned. + session_index: SessionIndex, + + /// Index of validator group to fetch the chunk from. + /// + /// Needed for reporting bad validators. + group_index: GroupIndex, + + /// Validators to request the chunk from. + /// + /// This vector gets drained during execution of the task (it will be empty afterwards). + group: Vec, + + /// The request to send. + request: ChunkFetchingRequest, + + /// Root hash, for verifying the chunks validity. + erasure_root: Hash, + + /// Relay parent of the candidate to fetch. + relay_parent: Hash, + + /// Sender for communicating with other subsystems and reporting results. + sender: mpsc::Sender, + + /// Prometheus metrics for reporting results. + metrics: Metrics, + + /// Span tracking the fetching of this chunk. + span: jaeger::Span, +} + +impl FetchTaskConfig { + /// Create a new configuration for a [`FetchTask`]. + /// + /// The result of this function can be passed into [`FetchTask::start`]. + pub fn new( + leaf: Hash, + core: &OccupiedCore, + sender: mpsc::Sender, + metrics: Metrics, + session_info: &SessionInfo, + span: jaeger::Span, + ) -> Self { + let span = span + .child("fetch-task-config") + .with_trace_id(core.candidate_hash) + .with_string_tag("leaf", format!("{:?}", leaf)) + .with_validator_index(session_info.our_index) + .with_uint_tag("group-index", core.group_responsible.0 as u64) + .with_relay_parent(core.candidate_descriptor.relay_parent) + .with_string_tag("pov-hash", format!("{:?}", core.candidate_descriptor.pov_hash)) + .with_stage(jaeger::Stage::AvailabilityDistribution); + + let live_in = vec![leaf].into_iter().collect(); + + // Don't run tasks for our backing group: + if session_info.our_group == Some(core.group_responsible) { + return FetchTaskConfig { live_in, prepared_running: None } + } + + let prepared_running = RunningTask { + session_index: session_info.session_index, + group_index: core.group_responsible, + group: session_info.validator_groups.get(core.group_responsible.0 as usize) + .expect("The responsible group of a candidate should be available in the corresponding session. qed.") + .clone(), + request: ChunkFetchingRequest { + candidate_hash: core.candidate_hash, + index: session_info.our_index, + }, + erasure_root: core.candidate_descriptor.erasure_root, + relay_parent: core.candidate_descriptor.relay_parent, + metrics, + sender, + span, + }; + FetchTaskConfig { live_in, prepared_running: Some(prepared_running) } + } +} + +#[overseer::contextbounds(AvailabilityDistribution, prefix = self::overseer)] +impl FetchTask { + /// Start fetching a chunk. + /// + /// A task handling the fetching of the configured chunk will be spawned. + pub async fn start(config: FetchTaskConfig, ctx: &mut Context) -> Result { + let FetchTaskConfig { prepared_running, live_in } = config; + + if let Some(running) = prepared_running { + let (handle, kill) = oneshot::channel(); + + ctx.spawn("chunk-fetcher", running.run(kill).boxed()) + .map_err(|e| FatalError::SpawnTask(e))?; + + Ok(FetchTask { live_in, state: FetchedState::Started(handle) }) + } else { + Ok(FetchTask { live_in, state: FetchedState::Canceled }) + } + } + + /// Add the given leaf to the relay parents which are making this task relevant. + /// + /// This is for book keeping, so we know we are already fetching a given chunk. + pub fn add_leaf(&mut self, leaf: Hash) { + self.live_in.insert(leaf); + } + + /// Remove leaves and cancel the task, if it was the last one and the task has still been + /// fetching. + pub fn remove_leaves(&mut self, leaves: &HashSet) { + for leaf in leaves { + self.live_in.remove(leaf); + } + if self.live_in.is_empty() && !self.is_finished() { + self.state = FetchedState::Canceled + } + } + + /// Whether there are still relay parents around with this candidate pending + /// availability. + pub fn is_live(&self) -> bool { + !self.live_in.is_empty() + } + + /// Whether this task can be considered finished. + /// + /// That is, it is either canceled, succeeded or failed. + pub fn is_finished(&self) -> bool { + match &self.state { + FetchedState::Canceled => true, + FetchedState::Started(sender) => sender.is_canceled(), + } + } +} + +/// Things that can go wrong in task execution. +#[derive(Debug)] +enum TaskError { + /// The peer failed to deliver a correct chunk for some reason (has been reported as + /// appropriate). + PeerError, + /// This very node is seemingly shutting down (sending of message failed). + ShuttingDown, +} + +impl RunningTask { + async fn run(self, kill: oneshot::Receiver<()>) { + // Wait for completion/or cancel. + let run_it = self.run_inner(); + futures::pin_mut!(run_it); + let _ = select(run_it, kill).await; + } + + /// Fetch and store chunk. + /// + /// Try validators in backing group in order. + async fn run_inner(mut self) { + let mut bad_validators = Vec::new(); + let mut succeeded = false; + let mut count: u32 = 0; + let mut span = self.span.child("run-fetch-chunk-task").with_relay_parent(self.relay_parent); + let mut network_error_freq = gum::Freq::new(); + let mut canceled_freq = gum::Freq::new(); + // Try validators in reverse order: + while let Some(validator) = self.group.pop() { + // Report retries: + if count > 0 { + self.metrics.on_retry(); + } + count += 1; + let _chunk_fetch_span = span + .child("fetch-chunk-request") + .with_chunk_index(self.request.index.0) + .with_stage(jaeger::Stage::AvailabilityDistribution); + // Send request: + let resp = match self + .do_request(&validator, &mut network_error_freq, &mut canceled_freq) + .await + { + Ok(resp) => resp, + Err(TaskError::ShuttingDown) => { + gum::info!( + target: LOG_TARGET, + "Node seems to be shutting down, canceling fetch task" + ); + self.metrics.on_fetch(FAILED); + return + }, + Err(TaskError::PeerError) => { + bad_validators.push(validator); + continue + }, + }; + // We drop the span here, so that the span is not active while we recombine the chunk. + drop(_chunk_fetch_span); + let _chunk_recombine_span = span + .child("recombine-chunk") + .with_chunk_index(self.request.index.0) + .with_stage(jaeger::Stage::AvailabilityDistribution); + let chunk = match resp { + ChunkFetchingResponse::Chunk(resp) => resp.recombine_into_chunk(&self.request), + ChunkFetchingResponse::NoSuchChunk => { + gum::debug!( + target: LOG_TARGET, + validator = ?validator, + relay_parent = ?self.relay_parent, + group_index = ?self.group_index, + session_index = ?self.session_index, + chunk_index = ?self.request.index, + candidate_hash = ?self.request.candidate_hash, + "Validator did not have our chunk" + ); + bad_validators.push(validator); + continue + }, + }; + // We drop the span so that the span is not active whilst we validate and store the + // chunk. + drop(_chunk_recombine_span); + let _chunk_validate_and_store_span = span + .child("validate-and-store-chunk") + .with_chunk_index(self.request.index.0) + .with_stage(jaeger::Stage::AvailabilityDistribution); + + // Data genuine? + if !self.validate_chunk(&validator, &chunk) { + bad_validators.push(validator); + continue + } + + // Ok, let's store it and be happy: + self.store_chunk(chunk).await; + succeeded = true; + break + } + span.add_int_tag("tries", count as _); + if succeeded { + self.metrics.on_fetch(SUCCEEDED); + self.conclude(bad_validators).await; + } else { + self.metrics.on_fetch(FAILED); + self.conclude_fail().await + } + } + + /// Do request and return response, if successful. + async fn do_request( + &mut self, + validator: &AuthorityDiscoveryId, + nerwork_error_freq: &mut gum::Freq, + canceled_freq: &mut gum::Freq, + ) -> std::result::Result { + gum::trace!( + target: LOG_TARGET, + origin = ?validator, + relay_parent = ?self.relay_parent, + group_index = ?self.group_index, + session_index = ?self.session_index, + chunk_index = ?self.request.index, + candidate_hash = ?self.request.candidate_hash, + "Starting chunk request", + ); + + let (full_request, response_recv) = + OutgoingRequest::new(Recipient::Authority(validator.clone()), self.request); + let requests = Requests::ChunkFetchingV1(full_request); + + self.sender + .send(FromFetchTask::Message( + NetworkBridgeTxMessage::SendRequests( + vec![requests], + IfDisconnected::ImmediateError, + ) + .into(), + )) + .await + .map_err(|_| TaskError::ShuttingDown)?; + + match response_recv.await { + Ok(resp) => Ok(resp), + Err(RequestError::InvalidResponse(err)) => { + gum::warn!( + target: LOG_TARGET, + origin = ?validator, + relay_parent = ?self.relay_parent, + group_index = ?self.group_index, + session_index = ?self.session_index, + chunk_index = ?self.request.index, + candidate_hash = ?self.request.candidate_hash, + err = ?err, + "Peer sent us invalid erasure chunk data" + ); + Err(TaskError::PeerError) + }, + Err(RequestError::NetworkError(err)) => { + gum::warn_if_frequent!( + freq: nerwork_error_freq, + max_rate: gum::Times::PerHour(100), + target: LOG_TARGET, + origin = ?validator, + relay_parent = ?self.relay_parent, + group_index = ?self.group_index, + session_index = ?self.session_index, + chunk_index = ?self.request.index, + candidate_hash = ?self.request.candidate_hash, + err = ?err, + "Some network error occurred when fetching erasure chunk" + ); + Err(TaskError::PeerError) + }, + Err(RequestError::Canceled(oneshot::Canceled)) => { + gum::warn_if_frequent!( + freq: canceled_freq, + max_rate: gum::Times::PerHour(100), + target: LOG_TARGET, + origin = ?validator, + relay_parent = ?self.relay_parent, + group_index = ?self.group_index, + session_index = ?self.session_index, + chunk_index = ?self.request.index, + candidate_hash = ?self.request.candidate_hash, + "Erasure chunk request got canceled" + ); + Err(TaskError::PeerError) + }, + } + } + + fn validate_chunk(&self, validator: &AuthorityDiscoveryId, chunk: &ErasureChunk) -> bool { + let anticipated_hash = + match branch_hash(&self.erasure_root, chunk.proof(), chunk.index.0 as usize) { + Ok(hash) => hash, + Err(e) => { + gum::warn!( + target: LOG_TARGET, + candidate_hash = ?self.request.candidate_hash, + origin = ?validator, + error = ?e, + "Failed to calculate chunk merkle proof", + ); + return false + }, + }; + let erasure_chunk_hash = BlakeTwo256::hash(&chunk.chunk); + if anticipated_hash != erasure_chunk_hash { + gum::warn!(target: LOG_TARGET, origin = ?validator, "Received chunk does not match merkle tree"); + return false + } + true + } + + /// Store given chunk and log any error. + async fn store_chunk(&mut self, chunk: ErasureChunk) { + let (tx, rx) = oneshot::channel(); + let r = self + .sender + .send(FromFetchTask::Message( + AvailabilityStoreMessage::StoreChunk { + candidate_hash: self.request.candidate_hash, + chunk, + tx, + } + .into(), + )) + .await; + if let Err(err) = r { + gum::error!(target: LOG_TARGET, err= ?err, "Storing erasure chunk failed, system shutting down?"); + } + + if let Err(oneshot::Canceled) = rx.await { + gum::error!(target: LOG_TARGET, "Storing erasure chunk failed"); + } + } + + /// Tell subsystem we are done. + async fn conclude(&mut self, bad_validators: Vec) { + let payload = if bad_validators.is_empty() { + None + } else { + Some(BadValidators { + session_index: self.session_index, + group_index: self.group_index, + bad_validators, + }) + }; + if let Err(err) = self.sender.send(FromFetchTask::Concluded(payload)).await { + gum::warn!( + target: LOG_TARGET, + err= ?err, + "Sending concluded message for task failed" + ); + } + } + + async fn conclude_fail(&mut self) { + if let Err(err) = self.sender.send(FromFetchTask::Failed(self.request.candidate_hash)).await + { + gum::warn!(target: LOG_TARGET, ?err, "Sending `Failed` message for task failed"); + } + } +} diff --git a/polkadot/node/network/availability-distribution/src/requester/fetch_task/tests.rs b/polkadot/node/network/availability-distribution/src/requester/fetch_task/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..460f20499ed59b0c7207354067b944759b794bc7 --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/requester/fetch_task/tests.rs @@ -0,0 +1,298 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::collections::HashMap; + +use parity_scale_codec::Encode; + +use futures::{ + channel::{mpsc, oneshot}, + executor, select, + task::{noop_waker, Context, Poll}, + Future, FutureExt, StreamExt, +}; + +use sc_network as network; +use sp_keyring::Sr25519Keyring; + +use polkadot_node_network_protocol::request_response::{v1, Recipient}; +use polkadot_node_primitives::{BlockData, PoV, Proof}; +use polkadot_node_subsystem::messages::AllMessages; +use polkadot_primitives::{CandidateHash, ValidatorIndex}; + +use super::*; +use crate::{metrics::Metrics, tests::mock::get_valid_chunk_data}; + +#[test] +fn task_can_be_canceled() { + let (task, _rx) = get_test_running_task(); + let (handle, kill) = oneshot::channel(); + std::mem::drop(handle); + let running_task = task.run(kill); + futures::pin_mut!(running_task); + let waker = noop_waker(); + let mut ctx = Context::from_waker(&waker); + assert!(running_task.poll(&mut ctx) == Poll::Ready(()), "Task is immediately finished"); +} + +/// Make sure task won't accept a chunk that has is invalid. +#[test] +fn task_does_not_accept_invalid_chunk() { + let (mut task, rx) = get_test_running_task(); + let validators = vec![Sr25519Keyring::Alice.public().into()]; + task.group = validators; + let test = TestRun { + chunk_responses: { + let mut m = HashMap::new(); + m.insert( + Recipient::Authority(Sr25519Keyring::Alice.public().into()), + ChunkFetchingResponse::Chunk(v1::ChunkResponse { + chunk: vec![1, 2, 3], + proof: Proof::try_from(vec![vec![9, 8, 2], vec![2, 3, 4]]).unwrap(), + }), + ); + m + }, + valid_chunks: HashSet::new(), + }; + test.run(task, rx); +} + +#[test] +fn task_stores_valid_chunk() { + let (mut task, rx) = get_test_running_task(); + let pov = PoV { block_data: BlockData(vec![45, 46, 47]) }; + let (root_hash, chunk) = get_valid_chunk_data(pov); + task.erasure_root = root_hash; + task.request.index = chunk.index; + + let validators = vec![Sr25519Keyring::Alice.public().into()]; + task.group = validators; + + let test = TestRun { + chunk_responses: { + let mut m = HashMap::new(); + m.insert( + Recipient::Authority(Sr25519Keyring::Alice.public().into()), + ChunkFetchingResponse::Chunk(v1::ChunkResponse { + chunk: chunk.chunk.clone(), + proof: chunk.proof, + }), + ); + m + }, + valid_chunks: { + let mut s = HashSet::new(); + s.insert(chunk.chunk); + s + }, + }; + test.run(task, rx); +} + +#[test] +fn task_does_not_accept_wrongly_indexed_chunk() { + let (mut task, rx) = get_test_running_task(); + let pov = PoV { block_data: BlockData(vec![45, 46, 47]) }; + let (root_hash, chunk) = get_valid_chunk_data(pov); + task.erasure_root = root_hash; + task.request.index = ValidatorIndex(chunk.index.0 + 1); + + let validators = vec![Sr25519Keyring::Alice.public().into()]; + task.group = validators; + + let test = TestRun { + chunk_responses: { + let mut m = HashMap::new(); + m.insert( + Recipient::Authority(Sr25519Keyring::Alice.public().into()), + ChunkFetchingResponse::Chunk(v1::ChunkResponse { + chunk: chunk.chunk.clone(), + proof: chunk.proof, + }), + ); + m + }, + valid_chunks: HashSet::new(), + }; + test.run(task, rx); +} + +/// Task stores chunk, if there is at least one validator having a valid chunk. +#[test] +fn task_stores_valid_chunk_if_there_is_one() { + let (mut task, rx) = get_test_running_task(); + let pov = PoV { block_data: BlockData(vec![45, 46, 47]) }; + let (root_hash, chunk) = get_valid_chunk_data(pov); + task.erasure_root = root_hash; + task.request.index = chunk.index; + + let validators = [ + // Only Alice has valid chunk - should succeed, even though she is tried last. + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + ] + .iter() + .map(|v| v.public().into()) + .collect::>(); + task.group = validators; + + let test = TestRun { + chunk_responses: { + let mut m = HashMap::new(); + m.insert( + Recipient::Authority(Sr25519Keyring::Alice.public().into()), + ChunkFetchingResponse::Chunk(v1::ChunkResponse { + chunk: chunk.chunk.clone(), + proof: chunk.proof, + }), + ); + m.insert( + Recipient::Authority(Sr25519Keyring::Bob.public().into()), + ChunkFetchingResponse::NoSuchChunk, + ); + m.insert( + Recipient::Authority(Sr25519Keyring::Charlie.public().into()), + ChunkFetchingResponse::Chunk(v1::ChunkResponse { + chunk: vec![1, 2, 3], + proof: Proof::try_from(vec![vec![9, 8, 2], vec![2, 3, 4]]).unwrap(), + }), + ); + + m + }, + valid_chunks: { + let mut s = HashSet::new(); + s.insert(chunk.chunk); + s + }, + }; + test.run(task, rx); +} + +struct TestRun { + /// Response to deliver for a given validator index. + /// None means, answer with `NetworkError`. + chunk_responses: HashMap, + /// Set of chunks that should be considered valid: + valid_chunks: HashSet>, +} + +impl TestRun { + fn run(self, task: RunningTask, rx: mpsc::Receiver) { + sp_tracing::try_init_simple(); + let mut rx = rx.fuse(); + let task = task.run_inner().fuse(); + futures::pin_mut!(task); + executor::block_on(async { + let mut end_ok = false; + loop { + let msg = select!( + from_task = rx.next() => { + match from_task { + Some(msg) => msg, + None => break, + } + }, + () = task => + break, + ); + match msg { + FromFetchTask::Concluded(_) => break, + FromFetchTask::Failed(_) => break, + FromFetchTask::Message(msg) => end_ok = self.handle_message(msg).await, + } + } + if !end_ok { + panic!("Task ended prematurely (failed to store valid chunk)!"); + } + }); + } + + /// Returns true, if after processing of the given message it would be OK for the stream to + /// end. + async fn handle_message( + &self, + msg: overseer::AvailabilityDistributionOutgoingMessages, + ) -> bool { + let msg = AllMessages::from(msg); + match msg { + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendRequests( + reqs, + IfDisconnected::ImmediateError, + )) => { + let mut valid_responses = 0; + for req in reqs { + let req = match req { + Requests::ChunkFetchingV1(req) => req, + _ => panic!("Unexpected request"), + }; + let response = + self.chunk_responses.get(&req.peer).ok_or(network::RequestFailure::Refused); + + if let Ok(ChunkFetchingResponse::Chunk(resp)) = &response { + if self.valid_chunks.contains(&resp.chunk) { + valid_responses += 1; + } + } + req.pending_response + .send(response.map(Encode::encode)) + .expect("Sending response should succeed"); + } + return (valid_responses == 0) && self.valid_chunks.is_empty() + }, + AllMessages::AvailabilityStore(AvailabilityStoreMessage::StoreChunk { + chunk, + tx, + .. + }) => { + assert!(self.valid_chunks.contains(&chunk.chunk)); + tx.send(Ok(())).expect("Answering fetching task should work"); + return true + }, + _ => { + gum::debug!(target: LOG_TARGET, "Unexpected message"); + return false + }, + } + } +} + +/// Get a `RunningTask` filled with dummy values. +fn get_test_running_task() -> (RunningTask, mpsc::Receiver) { + let (tx, rx) = mpsc::channel(0); + + ( + RunningTask { + session_index: 0, + group_index: GroupIndex(0), + group: Vec::new(), + request: ChunkFetchingRequest { + candidate_hash: CandidateHash([43u8; 32].into()), + index: ValidatorIndex(0), + }, + erasure_root: Hash::repeat_byte(99), + relay_parent: Hash::repeat_byte(71), + sender: tx, + metrics: Metrics::new_dummy(), + span: jaeger::Span::Disabled, + }, + rx, + ) +} diff --git a/polkadot/node/network/availability-distribution/src/requester/mod.rs b/polkadot/node/network/availability-distribution/src/requester/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..446988f7cc0dd72797f4e804a7e9fdc31290befc --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/requester/mod.rs @@ -0,0 +1,351 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Requester takes care of requesting erasure chunks for candidates that are pending +//! availability. + +use std::{ + collections::{ + hash_map::{Entry, HashMap}, + hash_set::HashSet, + }, + iter::IntoIterator, + pin::Pin, +}; + +use futures::{ + channel::{mpsc, oneshot}, + task::{Context, Poll}, + Stream, +}; + +use polkadot_node_subsystem::{ + jaeger, + messages::{ChainApiMessage, RuntimeApiMessage}, + overseer, ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, +}; +use polkadot_node_subsystem_util::runtime::{get_occupied_cores, RuntimeInfo}; +use polkadot_primitives::{CandidateHash, Hash, OccupiedCore, SessionIndex}; + +use super::{FatalError, Metrics, Result, LOG_TARGET}; + +#[cfg(test)] +mod tests; + +/// Cache for session information. +mod session_cache; +use session_cache::SessionCache; + +/// A task fetching a particular chunk. +mod fetch_task; +use fetch_task::{FetchTask, FetchTaskConfig, FromFetchTask}; + +/// Requester takes care of requesting erasure chunks from backing groups and stores them in the +/// av store. +/// +/// It implements a stream that needs to be advanced for it making progress. +pub struct Requester { + /// Candidates we need to fetch our chunk for. + /// + /// We keep those around as long as a candidate is pending availability on some leaf, so we + /// won't fetch chunks multiple times. + /// + /// We remove them on failure, so we get retries on the next block still pending availability. + fetches: HashMap, + + /// Localized information about sessions we are currently interested in. + session_cache: SessionCache, + + /// Sender to be cloned for `FetchTask`s. + tx: mpsc::Sender, + + /// Receive messages from `FetchTask`. + rx: mpsc::Receiver, + + /// Prometheus Metrics + metrics: Metrics, +} + +#[overseer::contextbounds(AvailabilityDistribution, prefix = self::overseer)] +impl Requester { + /// How many ancestors of the leaf should we consider along with it. + pub(crate) const LEAF_ANCESTRY_LEN_WITHIN_SESSION: usize = 3; + + /// Create a new `Requester`. + /// + /// You must feed it with `ActiveLeavesUpdate` via `update_fetching_heads` and make it progress + /// by advancing the stream. + pub fn new(metrics: Metrics) -> Self { + let (tx, rx) = mpsc::channel(1); + Requester { fetches: HashMap::new(), session_cache: SessionCache::new(), tx, rx, metrics } + } + + /// Update heads that need availability distribution. + /// + /// For all active heads we will be fetching our chunks for availability distribution. + pub async fn update_fetching_heads( + &mut self, + ctx: &mut Context, + runtime: &mut RuntimeInfo, + update: ActiveLeavesUpdate, + spans: &HashMap, + ) -> Result<()> { + gum::trace!(target: LOG_TARGET, ?update, "Update fetching heads"); + let ActiveLeavesUpdate { activated, deactivated } = update; + // Stale leaves happen after a reversion - we don't want to re-run availability there. + if let Some(leaf) = activated.filter(|leaf| leaf.status == LeafStatus::Fresh) { + let span = spans + .get(&leaf.hash) + .map(|span| span.child("update-fetching-heads")) + .unwrap_or_else(|| jaeger::Span::new(&leaf.hash, "update-fetching-heads")) + .with_string_tag("leaf", format!("{:?}", leaf.hash)) + .with_stage(jaeger::Stage::AvailabilityDistribution); + + // Order important! We need to handle activated, prior to deactivated, otherwise we + // might cancel still needed jobs. + self.start_requesting_chunks(ctx, runtime, leaf, &span).await?; + } + + self.stop_requesting_chunks(deactivated.into_iter()); + Ok(()) + } + + /// Start requesting chunks for newly imported head. + /// + /// This will also request [`SESSION_ANCESTRY_LEN`] leaf ancestors from the same session + /// and start requesting chunks for them too. + async fn start_requesting_chunks( + &mut self, + ctx: &mut Context, + runtime: &mut RuntimeInfo, + new_head: ActivatedLeaf, + span: &jaeger::Span, + ) -> Result<()> { + let mut span = span + .child("request-chunks-new-head") + .with_string_tag("leaf", format!("{:?}", new_head.hash)) + .with_stage(jaeger::Stage::AvailabilityDistribution); + + let sender = &mut ctx.sender().clone(); + let ActivatedLeaf { hash: leaf, .. } = new_head; + let (leaf_session_index, ancestors_in_session) = get_block_ancestors_in_same_session( + sender, + runtime, + leaf, + Self::LEAF_ANCESTRY_LEN_WITHIN_SESSION, + ) + .await?; + span.add_uint_tag("ancestors-in-session", ancestors_in_session.len() as u64); + + // Also spawn or bump tasks for candidates in ancestry in the same session. + for hash in std::iter::once(leaf).chain(ancestors_in_session) { + let span = span + .child("request-chunks-ancestor") + .with_string_tag("leaf", format!("{:?}", hash.clone())) + .with_stage(jaeger::Stage::AvailabilityDistribution); + + let cores = get_occupied_cores(sender, hash).await?; + gum::trace!( + target: LOG_TARGET, + occupied_cores = ?cores, + "Query occupied core" + ); + // Important: + // We mark the whole ancestry as live in the **leaf** hash, so we don't need to track + // any tasks separately. + // + // The next time the subsystem receives leaf update, some of spawned task will be bumped + // to be live in fresh relay parent, while some might get dropped due to the current + // leaf being deactivated. + self.add_cores(ctx, runtime, leaf, leaf_session_index, cores, span).await?; + } + + Ok(()) + } + + /// Stop requesting chunks for obsolete heads. + fn stop_requesting_chunks(&mut self, obsolete_leaves: impl Iterator) { + let obsolete_leaves: HashSet<_> = obsolete_leaves.collect(); + self.fetches.retain(|_, task| { + task.remove_leaves(&obsolete_leaves); + task.is_live() + }) + } + + /// Add candidates corresponding for a particular relay parent. + /// + /// Starting requests where necessary. + /// + /// Note: The passed in `leaf` is not the same as `CandidateDescriptor::relay_parent` in the + /// given cores. The latter is the `relay_parent` this candidate considers its parent, while the + /// passed in leaf might be some later block where the candidate is still pending availability. + async fn add_cores( + &mut self, + context: &mut Context, + runtime: &mut RuntimeInfo, + leaf: Hash, + leaf_session_index: SessionIndex, + cores: impl IntoIterator, + span: jaeger::Span, + ) -> Result<()> { + for core in cores { + let mut span = span + .child("check-fetch-candidate") + .with_trace_id(core.candidate_hash) + .with_string_tag("leaf", format!("{:?}", leaf)) + .with_candidate(core.candidate_hash) + .with_stage(jaeger::Stage::AvailabilityDistribution); + match self.fetches.entry(core.candidate_hash) { + Entry::Occupied(mut e) => + // Just book keeping - we are already requesting that chunk: + { + span.add_string_tag("already-requested-chunk", "true"); + e.get_mut().add_leaf(leaf); + }, + Entry::Vacant(e) => { + span.add_string_tag("already-requested-chunk", "false"); + let tx = self.tx.clone(); + let metrics = self.metrics.clone(); + + let task_cfg = self + .session_cache + .with_session_info( + context, + runtime, + // We use leaf here, the relay_parent must be in the same session as + // the leaf. This is guaranteed by runtime which ensures that cores are + // cleared at session boundaries. At the same time, only leaves are + // guaranteed to be fetchable by the state trie. + leaf, + leaf_session_index, + |info| FetchTaskConfig::new(leaf, &core, tx, metrics, info, span), + ) + .await + .map_err(|err| { + gum::warn!( + target: LOG_TARGET, + error = ?err, + "Failed to spawn a fetch task" + ); + err + }); + + if let Ok(Some(task_cfg)) = task_cfg { + e.insert(FetchTask::start(task_cfg, context).await?); + } + // Not a validator, nothing to do. + }, + } + } + Ok(()) + } +} + +impl Stream for Requester { + type Item = overseer::AvailabilityDistributionOutgoingMessages; + + fn poll_next(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll> { + loop { + match Pin::new(&mut self.rx).poll_next(ctx) { + Poll::Ready(Some(FromFetchTask::Message(m))) => return Poll::Ready(Some(m)), + Poll::Ready(Some(FromFetchTask::Concluded(Some(bad_boys)))) => { + self.session_cache.report_bad_log(bad_boys); + continue + }, + Poll::Ready(Some(FromFetchTask::Concluded(None))) => continue, + Poll::Ready(Some(FromFetchTask::Failed(candidate_hash))) => { + // Make sure we retry on next block still pending availability. + self.fetches.remove(&candidate_hash); + }, + Poll::Ready(None) => return Poll::Ready(None), + Poll::Pending => return Poll::Pending, + } + } + } +} + +/// Requests up to `limit` ancestor hashes of relay parent in the same session. +/// +/// Also returns session index of the `head`. +async fn get_block_ancestors_in_same_session( + sender: &mut Sender, + runtime: &mut RuntimeInfo, + head: Hash, + limit: usize, +) -> Result<(SessionIndex, Vec)> +where + Sender: + overseer::SubsystemSender + overseer::SubsystemSender, +{ + // The order is parent, grandparent, ... + // + // `limit + 1` since a session index for the last element in ancestry + // is obtained through its parent. It always gets truncated because + // `session_ancestry_len` can only be incremented `ancestors.len() - 1` times. + let mut ancestors = get_block_ancestors(sender, head, limit + 1).await?; + let mut ancestors_iter = ancestors.iter(); + + // `head` is the child of the first block in `ancestors`, request its session index. + let head_session_index = match ancestors_iter.next() { + Some(parent) => runtime.get_session_index_for_child(sender, *parent).await?, + None => { + // No first element, i.e. empty. + return Ok((0, ancestors)) + }, + }; + + let mut session_ancestry_len = 0; + // The first parent is skipped. + for parent in ancestors_iter { + // Parent is the i-th ancestor, request session index for its child -- (i-1)th element. + let session_index = runtime.get_session_index_for_child(sender, *parent).await?; + if session_index == head_session_index { + session_ancestry_len += 1; + } else { + break + } + } + + // Drop the rest. + ancestors.truncate(session_ancestry_len); + + Ok((head_session_index, ancestors)) +} + +/// Request up to `limit` ancestor hashes of relay parent from the Chain API. +async fn get_block_ancestors( + sender: &mut Sender, + relay_parent: Hash, + limit: usize, +) -> Result> +where + Sender: overseer::SubsystemSender, +{ + let (tx, rx) = oneshot::channel(); + sender + .send_message(ChainApiMessage::Ancestors { + hash: relay_parent, + k: limit, + response_channel: tx, + }) + .await; + + let ancestors = rx + .await + .map_err(FatalError::ChainApiSenderDropped)? + .map_err(FatalError::ChainApi)?; + Ok(ancestors) +} diff --git a/polkadot/node/network/availability-distribution/src/requester/session_cache.rs b/polkadot/node/network/availability-distribution/src/requester/session_cache.rs new file mode 100644 index 0000000000000000000000000000000000000000..e9311fb220382396762a1a801a4f26a588d85053 --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/requester/session_cache.rs @@ -0,0 +1,216 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{collections::HashSet, num::NonZeroUsize}; + +use lru::LruCache; +use rand::{seq::SliceRandom, thread_rng}; + +use polkadot_node_subsystem::overseer; +use polkadot_node_subsystem_util::runtime::RuntimeInfo; +use polkadot_primitives::{AuthorityDiscoveryId, GroupIndex, Hash, SessionIndex, ValidatorIndex}; + +use crate::{ + error::{Error, Result}, + LOG_TARGET, +}; + +/// Caching of session info as needed by availability chunk distribution. +/// +/// It should be ensured that a cached session stays live in the cache as long as we might need it. +pub struct SessionCache { + /// Look up cached sessions by `SessionIndex`. + /// + /// Note: Performance of fetching is really secondary here, but we need to ensure we are going + /// to get any existing cache entry, before fetching new information, as we should not mess up + /// the order of validators in `SessionInfo::validator_groups`. + session_info_cache: LruCache, +} + +/// Localized session information, tailored for the needs of availability distribution. +#[derive(Clone)] +pub struct SessionInfo { + /// The index of this session. + pub session_index: SessionIndex, + + /// Validator groups of the current session. + /// + /// Each group's order is randomized. This way we achieve load balancing when requesting + /// chunks, as the validators in a group will be tried in that randomized order. Each node + /// should arrive at a different order, therefore we distribute the load on individual + /// validators. + pub validator_groups: Vec>, + + /// Information about ourselves: + pub our_index: ValidatorIndex, + + /// Remember to which group we belong, so we won't start fetching chunks for candidates with + /// our group being responsible. (We should have that chunk already.) + /// + /// `None`, if we are not in fact part of any group. + pub our_group: Option, +} + +/// Report of bad validators. +/// +/// Fetching tasks will report back validators that did not respond as expected, so we can re-order +/// them. +pub struct BadValidators { + /// The session index that was used. + pub session_index: SessionIndex, + /// The group, the not properly responding validators belong to. + pub group_index: GroupIndex, + /// The list of bad validators. + pub bad_validators: Vec, +} + +#[overseer::contextbounds(AvailabilityDistribution, prefix = self::overseer)] +impl SessionCache { + /// Create a new `SessionCache`. + pub fn new() -> Self { + SessionCache { + // We need to cache the current and the last session the most: + session_info_cache: LruCache::new(NonZeroUsize::new(2).unwrap()), + } + } + + /// Tries to retrieve `SessionInfo` and calls `with_info` if successful. + /// + /// If this node is not a validator, the function will return `None`. + /// + /// Use this function over any `fetch_session_info` if all you need is a reference to + /// `SessionInfo`, as it avoids an expensive clone. + pub async fn with_session_info( + &mut self, + ctx: &mut Context, + runtime: &mut RuntimeInfo, + parent: Hash, + session_index: SessionIndex, + with_info: F, + ) -> Result> + where + F: FnOnce(&SessionInfo) -> R, + { + if let Some(o_info) = self.session_info_cache.get(&session_index) { + gum::trace!(target: LOG_TARGET, session_index, "Got session from lru"); + return Ok(Some(with_info(o_info))) + } + + if let Some(info) = + self.query_info_from_runtime(ctx, runtime, parent, session_index).await? + { + gum::trace!(target: LOG_TARGET, session_index, "Calling `with_info`"); + let r = with_info(&info); + gum::trace!(target: LOG_TARGET, session_index, "Storing session info in lru!"); + self.session_info_cache.put(session_index, info); + Ok(Some(r)) + } else { + Ok(None) + } + } + + /// Variant of `report_bad` that never fails, but just logs errors. + /// + /// Not being able to report bad validators is not fatal, so we should not shutdown the + /// subsystem on this. + pub fn report_bad_log(&mut self, report: BadValidators) { + if let Err(err) = self.report_bad(report) { + gum::warn!( + target: LOG_TARGET, + err = ?err, + "Reporting bad validators failed with error" + ); + } + } + + /// Make sure we try unresponsive or misbehaving validators last. + /// + /// We assume validators in a group are tried in reverse order, so the reported bad validators + /// will be put at the beginning of the group. + pub fn report_bad(&mut self, report: BadValidators) -> Result<()> { + let available_sessions = self.session_info_cache.iter().map(|(k, _)| *k).collect(); + let session = self.session_info_cache.get_mut(&report.session_index).ok_or( + Error::NoSuchCachedSession { + available_sessions, + missing_session: report.session_index, + }, + )?; + let group = session.validator_groups.get_mut(report.group_index.0 as usize).expect( + "A bad validator report must contain a valid group for the reported session. qed.", + ); + let bad_set = report.bad_validators.iter().collect::>(); + + // Get rid of bad boys: + group.retain(|v| !bad_set.contains(v)); + + // We are trying validators in reverse order, so bad ones should be first: + let mut new_group = report.bad_validators; + new_group.append(group); + *group = new_group; + Ok(()) + } + + /// Query needed information from runtime. + /// + /// We need to pass in the relay parent for our call to `request_session_info`. We should + /// actually don't need that: I suppose it is used for internal caching based on relay parents, + /// which we don't use here. It should not do any harm though. + /// + /// Returns: `None` if not a validator. + async fn query_info_from_runtime( + &self, + ctx: &mut Context, + runtime: &mut RuntimeInfo, + relay_parent: Hash, + session_index: SessionIndex, + ) -> Result> { + let info = runtime + .get_session_info_by_index(ctx.sender(), relay_parent, session_index) + .await?; + + let discovery_keys = info.session_info.discovery_keys.clone(); + let mut validator_groups = info.session_info.validator_groups.clone(); + + if let Some(our_index) = info.validator_info.our_index { + // Get our group index: + let our_group = info.validator_info.our_group; + + // Shuffle validators in groups: + let mut rng = thread_rng(); + for g in validator_groups.iter_mut() { + g.shuffle(&mut rng) + } + // Look up `AuthorityDiscoveryId`s right away: + let validator_groups: Vec> = validator_groups + .into_iter() + .map(|group| { + group + .into_iter() + .map(|index| { + discovery_keys.get(index.0 as usize) + .expect("There should be a discovery key for each validator of each validator group. qed.") + .clone() + }) + .collect() + }) + .collect(); + + let info = SessionInfo { validator_groups, our_index, session_index, our_group }; + return Ok(Some(info)) + } + return Ok(None) + } +} diff --git a/polkadot/node/network/availability-distribution/src/requester/tests.rs b/polkadot/node/network/availability-distribution/src/requester/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..b74a69ea0769b2dec61c4b3ef1ddb0120ff17f5f --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/requester/tests.rs @@ -0,0 +1,343 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::collections::HashMap; + +use std::{future::Future, sync::Arc}; + +use futures::FutureExt; + +use polkadot_node_network_protocol::jaeger; +use polkadot_node_primitives::{BlockData, ErasureChunk, PoV}; +use polkadot_node_subsystem_util::runtime::RuntimeInfo; +use polkadot_primitives::{ + BlockNumber, CoreState, GroupIndex, Hash, Id as ParaId, ScheduledCore, SessionIndex, + SessionInfo, +}; +use sp_core::traits::SpawnNamed; + +use polkadot_node_subsystem::{ + messages::{ + AllMessages, AvailabilityDistributionMessage, AvailabilityStoreMessage, ChainApiMessage, + NetworkBridgeTxMessage, RuntimeApiMessage, RuntimeApiRequest, + }, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, SpawnGlue, +}; +use polkadot_node_subsystem_test_helpers::{ + make_subsystem_context, mock::make_ferdie_keystore, TestSubsystemContext, + TestSubsystemContextHandle, +}; + +use sp_core::testing::TaskExecutor; + +use crate::tests::mock::{get_valid_chunk_data, make_session_info, OccupiedCoreBuilder}; + +use super::Requester; + +fn get_erasure_chunk() -> ErasureChunk { + let pov = PoV { block_data: BlockData(vec![45, 46, 47]) }; + get_valid_chunk_data(pov).1 +} + +#[derive(Clone)] +struct TestState { + /// Simulated relay chain heads. For each block except genesis + /// there exists a single corresponding candidate, handled in [`spawn_virtual_overseer`]. + pub relay_chain: Vec, + pub session_info: SessionInfo, + // Defines a way to compute a session index for the block with + // a given number. Returns 1 for all blocks by default. + pub session_index_for_block: fn(BlockNumber) -> SessionIndex, +} + +impl TestState { + fn new() -> Self { + let relay_chain: Vec<_> = (0u8..10).map(Hash::repeat_byte).collect(); + let session_info = make_session_info(); + let session_index_for_block = |_| 1; + Self { relay_chain, session_info, session_index_for_block } + } +} + +fn spawn_virtual_overseer( + pool: TaskExecutor, + test_state: TestState, + mut ctx_handle: TestSubsystemContextHandle, +) { + pool.spawn( + "virtual-overseer", + None, + async move { + loop { + let msg = ctx_handle.try_recv().await; + if msg.is_none() { + break + } + match msg.unwrap() { + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendRequests(..)) => {}, + AllMessages::AvailabilityStore(AvailabilityStoreMessage::QueryChunk( + .., + tx, + )) => { + let chunk = get_erasure_chunk(); + tx.send(Some(chunk)).expect("Receiver is expected to be alive"); + }, + AllMessages::AvailabilityStore(AvailabilityStoreMessage::StoreChunk { + tx, + .. + }) => { + // Silently accept it. + tx.send(Ok(())).expect("Receiver is expected to be alive"); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(hash, req)) => { + match req { + RuntimeApiRequest::SessionIndexForChild(tx) => { + let chain = &test_state.relay_chain; + let block_number = chain + .iter() + .position(|h| *h == hash) + .expect("Invalid session index request"); + // Compute session index. + let session_index_for_block = test_state.session_index_for_block; + + tx.send(Ok(session_index_for_block(block_number as u32 + 1))) + .expect("Receiver should still be alive"); + }, + RuntimeApiRequest::SessionInfo(_, tx) => { + tx.send(Ok(Some(test_state.session_info.clone()))) + .expect("Receiver should be alive."); + }, + RuntimeApiRequest::AvailabilityCores(tx) => { + let para_id = ParaId::from(1_u32); + let maybe_block_position = + test_state.relay_chain.iter().position(|h| *h == hash); + let cores = match maybe_block_position { + Some(block_num) => { + let core = if block_num == 0 { + CoreState::Scheduled(ScheduledCore { + para_id, + collator: None, + }) + } else { + CoreState::Occupied( + OccupiedCoreBuilder { + group_responsible: GroupIndex(1), + para_id, + relay_parent: hash, + } + .build() + .0, + ) + }; + vec![core] + }, + None => Vec::new(), + }; + tx.send(Ok(cores)).expect("Receiver should be alive.") + }, + _ => { + panic!("Unexpected runtime request: {:?}", req); + }, + } + }, + AllMessages::ChainApi(ChainApiMessage::Ancestors { + hash, + k, + response_channel, + }) => { + let chain = &test_state.relay_chain; + let maybe_block_position = chain.iter().position(|h| *h == hash); + let ancestors = maybe_block_position + .map(|idx| chain[..idx].iter().rev().take(k).copied().collect()) + .unwrap_or_default(); + response_channel + .send(Ok(ancestors)) + .expect("Receiver is expected to be alive"); + }, + msg => panic!("Unexpected overseer message: {:?}", msg), + } + } + } + .boxed(), + ); +} + +fn test_harness>( + test_state: TestState, + test_fx: impl FnOnce( + TestSubsystemContext>, + ) -> T, +) { + let pool = TaskExecutor::new(); + let (ctx, ctx_handle) = make_subsystem_context(pool.clone()); + + spawn_virtual_overseer(pool, test_state, ctx_handle); + + futures::executor::block_on(test_fx(ctx)); +} + +#[test] +fn check_ancestry_lookup_in_same_session() { + let test_state = TestState::new(); + let mut requester = Requester::new(Default::default()); + let keystore = make_ferdie_keystore(); + let mut runtime = RuntimeInfo::new(Some(keystore)); + + test_harness(test_state.clone(), |mut ctx| async move { + let chain = &test_state.relay_chain; + let spans: HashMap = HashMap::new(); + let block_number = 1; + let update = ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: chain[block_number], + number: block_number as u32, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + deactivated: Vec::new().into(), + }; + + requester + .update_fetching_heads(&mut ctx, &mut runtime, update, &spans) + .await + .expect("Leaf processing failed"); + let fetch_tasks = &requester.fetches; + assert_eq!(fetch_tasks.len(), 1); + let block_1_candidate = + *fetch_tasks.keys().next().expect("A task is checked to be present; qed"); + + let block_number = 2; + let update = ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: chain[block_number], + number: block_number as u32, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + deactivated: Vec::new().into(), + }; + + requester + .update_fetching_heads(&mut ctx, &mut runtime, update, &spans) + .await + .expect("Leaf processing failed"); + let fetch_tasks = &requester.fetches; + assert_eq!(fetch_tasks.len(), 2); + let task = fetch_tasks.get(&block_1_candidate).expect("Leaf hasn't been deactivated yet"); + // The task should be live in both blocks 1 and 2. + assert_eq!(task.live_in.len(), 2); + let block_2_candidate = *fetch_tasks + .keys() + .find(|hash| **hash != block_1_candidate) + .expect("Two tasks are present, the first one corresponds to block 1 candidate; qed"); + + // Deactivate both blocks but keep the second task as a + // part of ancestry. + let block_number = 2 + Requester::LEAF_ANCESTRY_LEN_WITHIN_SESSION; + let update = ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: test_state.relay_chain[block_number], + number: block_number as u32, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + deactivated: vec![chain[1], chain[2]].into(), + }; + requester + .update_fetching_heads(&mut ctx, &mut runtime, update, &spans) + .await + .expect("Leaf processing failed"); + let fetch_tasks = &requester.fetches; + // The leaf + K its ancestors. + assert_eq!(fetch_tasks.len(), Requester::LEAF_ANCESTRY_LEN_WITHIN_SESSION + 1); + + let block_2_task = fetch_tasks + .get(&block_2_candidate) + .expect("Expected to be live as a part of ancestry"); + assert_eq!(block_2_task.live_in.len(), 1); + }); +} + +#[test] +fn check_ancestry_lookup_in_different_sessions() { + let mut test_state = TestState::new(); + let mut requester = Requester::new(Default::default()); + let keystore = make_ferdie_keystore(); + let mut runtime = RuntimeInfo::new(Some(keystore)); + + test_state.session_index_for_block = |block_number| match block_number { + 0..=3 => 1, + _ => 2, + }; + + test_harness(test_state.clone(), |mut ctx| async move { + let chain = &test_state.relay_chain; + let spans: HashMap = HashMap::new(); + let block_number = 3; + let update = ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: chain[block_number], + number: block_number as u32, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + deactivated: Vec::new().into(), + }; + + requester + .update_fetching_heads(&mut ctx, &mut runtime, update, &spans) + .await + .expect("Leaf processing failed"); + let fetch_tasks = &requester.fetches; + assert_eq!(fetch_tasks.len(), 3.min(Requester::LEAF_ANCESTRY_LEN_WITHIN_SESSION + 1)); + + let block_number = 4; + let update = ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: chain[block_number], + number: block_number as u32, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + deactivated: vec![chain[1], chain[2], chain[3]].into(), + }; + + requester + .update_fetching_heads(&mut ctx, &mut runtime, update, &spans) + .await + .expect("Leaf processing failed"); + let fetch_tasks = &requester.fetches; + assert_eq!(fetch_tasks.len(), 1); + + let block_number = 5; + let update = ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: chain[block_number], + number: block_number as u32, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + deactivated: vec![chain[4]].into(), + }; + + requester + .update_fetching_heads(&mut ctx, &mut runtime, update, &spans) + .await + .expect("Leaf processing failed"); + let fetch_tasks = &requester.fetches; + assert_eq!(fetch_tasks.len(), 2.min(Requester::LEAF_ANCESTRY_LEN_WITHIN_SESSION + 1)); + }); +} diff --git a/polkadot/node/network/availability-distribution/src/responder.rs b/polkadot/node/network/availability-distribution/src/responder.rs new file mode 100644 index 0000000000000000000000000000000000000000..54b188f7f01fc7e22b4ea7679be0a67f8d9d0d37 --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/responder.rs @@ -0,0 +1,260 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Answer requests for availability chunks. + +use std::sync::Arc; + +use futures::channel::oneshot; + +use fatality::Nested; +use polkadot_node_network_protocol::{ + request_response::{v1, IncomingRequest, IncomingRequestReceiver}, + UnifiedReputationChange as Rep, +}; +use polkadot_node_primitives::{AvailableData, ErasureChunk}; +use polkadot_node_subsystem::{jaeger, messages::AvailabilityStoreMessage, SubsystemSender}; +use polkadot_primitives::{CandidateHash, ValidatorIndex}; + +use crate::{ + error::{JfyiError, Result}, + metrics::{Metrics, FAILED, NOT_FOUND, SUCCEEDED}, + LOG_TARGET, +}; + +const COST_INVALID_REQUEST: Rep = Rep::CostMajor("Received message could not be decoded."); + +/// Receiver task to be forked as a separate task to handle PoV requests. +pub async fn run_pov_receiver( + mut sender: Sender, + mut receiver: IncomingRequestReceiver, + metrics: Metrics, +) where + Sender: SubsystemSender, +{ + loop { + match receiver.recv(|| vec![COST_INVALID_REQUEST]).await.into_nested() { + Ok(Ok(msg)) => { + answer_pov_request_log(&mut sender, msg, &metrics).await; + }, + Err(fatal) => { + gum::debug!( + target: LOG_TARGET, + error = ?fatal, + "Shutting down POV receiver." + ); + return + }, + Ok(Err(jfyi)) => { + gum::debug!(target: LOG_TARGET, error = ?jfyi, "Error decoding incoming PoV request."); + }, + } + } +} + +/// Receiver task to be forked as a separate task to handle chunk requests. +pub async fn run_chunk_receiver( + mut sender: Sender, + mut receiver: IncomingRequestReceiver, + metrics: Metrics, +) where + Sender: SubsystemSender, +{ + loop { + match receiver.recv(|| vec![COST_INVALID_REQUEST]).await.into_nested() { + Ok(Ok(msg)) => { + answer_chunk_request_log(&mut sender, msg, &metrics).await; + }, + Err(fatal) => { + gum::debug!( + target: LOG_TARGET, + error = ?fatal, + "Shutting down chunk receiver." + ); + return + }, + Ok(Err(jfyi)) => { + gum::debug!( + target: LOG_TARGET, + error = ?jfyi, + "Error decoding incoming chunk request." + ); + }, + } + } +} + +/// Variant of `answer_pov_request` that does Prometheus metric and logging on errors. +/// +/// Any errors of `answer_pov_request` will simply be logged. +pub async fn answer_pov_request_log( + sender: &mut Sender, + req: IncomingRequest, + metrics: &Metrics, +) where + Sender: SubsystemSender, +{ + let res = answer_pov_request(sender, req).await; + match res { + Ok(result) => metrics.on_served_pov(if result { SUCCEEDED } else { NOT_FOUND }), + Err(err) => { + gum::warn!( + target: LOG_TARGET, + err= ?err, + "Serving PoV failed with error" + ); + metrics.on_served_pov(FAILED); + }, + } +} + +/// Variant of `answer_chunk_request` that does Prometheus metric and logging on errors. +/// +/// Any errors of `answer_request` will simply be logged. +pub async fn answer_chunk_request_log( + sender: &mut Sender, + req: IncomingRequest, + metrics: &Metrics, +) -> () +where + Sender: SubsystemSender, +{ + let res = answer_chunk_request(sender, req).await; + match res { + Ok(result) => metrics.on_served_chunk(if result { SUCCEEDED } else { NOT_FOUND }), + Err(err) => { + gum::warn!( + target: LOG_TARGET, + err= ?err, + "Serving chunk failed with error" + ); + metrics.on_served_chunk(FAILED); + }, + } +} + +/// Answer an incoming PoV fetch request by querying the av store. +/// +/// Returns: `Ok(true)` if chunk was found and served. +pub async fn answer_pov_request( + sender: &mut Sender, + req: IncomingRequest, +) -> Result +where + Sender: SubsystemSender, +{ + let _span = jaeger::Span::new(req.payload.candidate_hash, "answer-pov-request"); + + let av_data = query_available_data(sender, req.payload.candidate_hash).await?; + + let result = av_data.is_some(); + + let response = match av_data { + None => v1::PoVFetchingResponse::NoSuchPoV, + Some(av_data) => { + let pov = Arc::try_unwrap(av_data.pov).unwrap_or_else(|a| (&*a).clone()); + v1::PoVFetchingResponse::PoV(pov) + }, + }; + + req.send_response(response).map_err(|_| JfyiError::SendResponse)?; + Ok(result) +} + +/// Answer an incoming chunk request by querying the av store. +/// +/// Returns: `Ok(true)` if chunk was found and served. +pub async fn answer_chunk_request( + sender: &mut Sender, + req: IncomingRequest, +) -> Result +where + Sender: SubsystemSender, +{ + let span = jaeger::Span::new(req.payload.candidate_hash, "answer-chunk-request"); + + let _child_span = span + .child("answer-chunk-request") + .with_trace_id(req.payload.candidate_hash) + .with_chunk_index(req.payload.index.0); + + let chunk = query_chunk(sender, req.payload.candidate_hash, req.payload.index).await?; + + let result = chunk.is_some(); + + gum::trace!( + target: LOG_TARGET, + hash = ?req.payload.candidate_hash, + index = ?req.payload.index, + peer = ?req.peer, + has_data = ?chunk.is_some(), + "Serving chunk", + ); + + let response = match chunk { + None => v1::ChunkFetchingResponse::NoSuchChunk, + Some(chunk) => v1::ChunkFetchingResponse::Chunk(chunk.into()), + }; + + req.send_response(response).map_err(|_| JfyiError::SendResponse)?; + Ok(result) +} + +/// Query chunk from the availability store. +async fn query_chunk( + sender: &mut Sender, + candidate_hash: CandidateHash, + validator_index: ValidatorIndex, +) -> std::result::Result, JfyiError> +where + Sender: SubsystemSender, +{ + let (tx, rx) = oneshot::channel(); + sender + .send_message( + AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx).into(), + ) + .await; + + let result = rx.await.map_err(|e| { + gum::trace!( + target: LOG_TARGET, + ?validator_index, + ?candidate_hash, + error = ?e, + "Error retrieving chunk", + ); + JfyiError::QueryChunkResponseChannel(e) + })?; + Ok(result) +} + +/// Query PoV from the availability store. +async fn query_available_data( + sender: &mut Sender, + candidate_hash: CandidateHash, +) -> Result> +where + Sender: SubsystemSender, +{ + let (tx, rx) = oneshot::channel(); + sender + .send_message(AvailabilityStoreMessage::QueryAvailableData(candidate_hash, tx).into()) + .await; + + let result = rx.await.map_err(JfyiError::QueryAvailableDataResponseChannel)?; + Ok(result) +} diff --git a/polkadot/node/network/availability-distribution/src/tests/mock.rs b/polkadot/node/network/availability-distribution/src/tests/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..3df662fe546c07f7a7f58d02d0ceafd98a7e1b6c --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/tests/mock.rs @@ -0,0 +1,158 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Helper functions and tools to generate mock data useful for testing this subsystem. + +use std::sync::Arc; + +use sp_keyring::Sr25519Keyring; + +use polkadot_erasure_coding::{branches, obtain_chunks_v1 as obtain_chunks}; +use polkadot_node_primitives::{AvailableData, BlockData, ErasureChunk, PoV, Proof}; +use polkadot_primitives::{ + CandidateCommitments, CandidateDescriptor, CandidateHash, CommittedCandidateReceipt, + GroupIndex, Hash, HeadData, Id as ParaId, IndexedVec, OccupiedCore, PersistedValidationData, + SessionInfo, ValidatorIndex, +}; +use polkadot_primitives_test_helpers::{ + dummy_collator, dummy_collator_signature, dummy_hash, dummy_validation_code, +}; + +/// Create dummy session info with two validator groups. +pub fn make_session_info() -> SessionInfo { + let validators = vec![ + Sr25519Keyring::Ferdie, // <- this node, role: validator + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + Sr25519Keyring::One, + ]; + + let validator_groups: IndexedVec> = + [vec![5, 0, 3], vec![1, 6, 2, 4]] + .iter() + .map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect()) + .collect(); + + SessionInfo { + discovery_keys: validators.iter().map(|k| k.public().into()).collect(), + // Not used: + n_cores: validator_groups.len() as u32, + validator_groups, + // Not used values: + validators: validators.iter().map(|k| k.public().into()).collect(), + assignment_keys: Vec::new(), + zeroth_delay_tranche_width: 0, + relay_vrf_modulo_samples: 0, + n_delay_tranches: 0, + no_show_slots: 0, + needed_approvals: 0, + active_validator_indices: Vec::new(), + dispute_period: 6, + random_seed: [0u8; 32], + } +} + +/// Builder for constructing occupied cores. +/// +/// Takes all the values we care about and fills the rest with dummy values on `build`. +pub struct OccupiedCoreBuilder { + pub group_responsible: GroupIndex, + pub para_id: ParaId, + pub relay_parent: Hash, +} + +impl OccupiedCoreBuilder { + pub fn build(self) -> (OccupiedCore, (CandidateHash, ErasureChunk)) { + let pov = PoV { block_data: BlockData(vec![45, 46, 47]) }; + let pov_hash = pov.hash(); + let (erasure_root, chunk) = get_valid_chunk_data(pov.clone()); + let candidate_receipt = TestCandidateBuilder { + para_id: self.para_id, + pov_hash, + relay_parent: self.relay_parent, + erasure_root, + ..Default::default() + } + .build(); + let core = OccupiedCore { + next_up_on_available: None, + occupied_since: 0, + time_out_at: 0, + next_up_on_time_out: None, + availability: Default::default(), + group_responsible: self.group_responsible, + candidate_hash: candidate_receipt.hash(), + candidate_descriptor: candidate_receipt.descriptor().clone(), + }; + (core, (candidate_receipt.hash(), chunk)) + } +} + +#[derive(Default)] +pub struct TestCandidateBuilder { + para_id: ParaId, + head_data: HeadData, + pov_hash: Hash, + relay_parent: Hash, + erasure_root: Hash, +} + +impl TestCandidateBuilder { + pub fn build(self) -> CommittedCandidateReceipt { + CommittedCandidateReceipt { + descriptor: CandidateDescriptor { + para_id: self.para_id, + pov_hash: self.pov_hash, + relay_parent: self.relay_parent, + erasure_root: self.erasure_root, + collator: dummy_collator(), + persisted_validation_data_hash: dummy_hash(), + signature: dummy_collator_signature(), + para_head: dummy_hash(), + validation_code_hash: dummy_validation_code().hash(), + }, + commitments: CandidateCommitments { head_data: self.head_data, ..Default::default() }, + } + } +} + +// Get chunk for index 0 +pub fn get_valid_chunk_data(pov: PoV) -> (Hash, ErasureChunk) { + let fake_validator_count = 10; + let persisted = PersistedValidationData { + parent_head: HeadData(vec![7, 8, 9]), + relay_parent_number: Default::default(), + max_pov_size: 1024, + relay_parent_storage_root: Default::default(), + }; + let available_data = AvailableData { validation_data: persisted, pov: Arc::new(pov) }; + let chunks = obtain_chunks(fake_validator_count, &available_data).unwrap(); + let branches = branches(chunks.as_ref()); + let root = branches.root(); + let chunk = branches + .enumerate() + .map(|(index, (proof, chunk))| ErasureChunk { + chunk: chunk.to_vec(), + index: ValidatorIndex(index as _), + proof: Proof::try_from(proof).unwrap(), + }) + .next() + .expect("There really should be 10 chunks."); + (root, chunk) +} diff --git a/polkadot/node/network/availability-distribution/src/tests/mod.rs b/polkadot/node/network/availability-distribution/src/tests/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..d0aee7e5e010499db55ed78b7b9627cd7cab6e9b --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/tests/mod.rs @@ -0,0 +1,125 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::collections::HashSet; + +use futures::{executor, future, Future}; + +use polkadot_node_network_protocol::request_response::{IncomingRequest, ReqProtocolNames}; +use polkadot_primitives::{CoreState, Hash}; +use sp_keystore::KeystorePtr; + +use polkadot_node_subsystem_test_helpers as test_helpers; + +use super::*; + +mod state; +/// State for test harnesses. +use state::{TestHarness, TestState}; + +/// Mock data useful for testing. +pub(crate) mod mock; + +fn test_harness>( + keystore: KeystorePtr, + test_fx: impl FnOnce(TestHarness) -> T, +) { + sp_tracing::try_init_simple(); + + let pool = sp_core::testing::TaskExecutor::new(); + let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); + let genesis_hash = Hash::repeat_byte(0xff); + let req_protocol_names = ReqProtocolNames::new(&genesis_hash, None); + + let (pov_req_receiver, pov_req_cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); + let (chunk_req_receiver, chunk_req_cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + let subsystem = AvailabilityDistributionSubsystem::new( + keystore, + IncomingRequestReceivers { pov_req_receiver, chunk_req_receiver }, + Default::default(), + ); + let subsystem = subsystem.run(context); + + let test_fut = test_fx(TestHarness { virtual_overseer, pov_req_cfg, chunk_req_cfg, pool }); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + executor::block_on(future::join(test_fut, subsystem)).1.unwrap(); +} + +/// Simple basic check, whether the subsystem works as expected. +/// +/// Exceptional cases are tested as unit tests in `fetch_task`. +#[test] +fn check_basic() { + let state = TestState::default(); + test_harness(state.keystore.clone(), move |harness| state.run(harness)); +} + +/// Check whether requester tries all validators in group. +#[test] +fn check_fetch_tries_all() { + let mut state = TestState::default(); + for (_, v) in state.chunks.iter_mut() { + // 4 validators in group, so this should still succeed: + v.push(None); + v.push(None); + v.push(None); + } + test_harness(state.keystore.clone(), move |harness| state.run(harness)); +} + +/// Check whether requester tries all validators in group +/// +/// Check that requester will retry the fetch on error on the next block still pending +/// availability. +#[test] +fn check_fetch_retry() { + let mut state = TestState::default(); + state + .cores + .insert(state.relay_chain[2], state.cores.get(&state.relay_chain[1]).unwrap().clone()); + // We only care about the first three blocks. + // 1. scheduled + // 2. occupied + // 3. still occupied + state.relay_chain.truncate(3); + + // Get rid of unused valid chunks: + let valid_candidate_hashes: HashSet<_> = state + .cores + .get(&state.relay_chain[1]) + .iter() + .flat_map(|v| v.iter()) + .filter_map(|c| match c { + CoreState::Occupied(core) => Some(core.candidate_hash), + _ => None, + }) + .collect(); + state.valid_chunks.retain(|(ch, _)| valid_candidate_hashes.contains(ch)); + + for (_, v) in state.chunks.iter_mut() { + // This should still succeed as cores are still pending availability on next block. + v.push(None); + v.push(None); + v.push(None); + v.push(None); + v.push(None); + } + test_harness(state.keystore.clone(), move |harness| state.run(harness)); +} diff --git a/polkadot/node/network/availability-distribution/src/tests/state.rs b/polkadot/node/network/availability-distribution/src/tests/state.rs new file mode 100644 index 0000000000000000000000000000000000000000..706ec13a3e9b3dc19dfb3208b924bd6d231414da --- /dev/null +++ b/polkadot/node/network/availability-distribution/src/tests/state.rs @@ -0,0 +1,342 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{ + collections::{HashMap, HashSet}, + sync::Arc, + time::Duration, +}; + +use polkadot_node_subsystem_test_helpers::TestSubsystemContextHandle; +use polkadot_node_subsystem_util::TimeoutExt; + +use futures::{ + channel::{mpsc, oneshot}, + FutureExt, SinkExt, StreamExt, +}; +use futures_timer::Delay; + +use sc_network as network; +use sc_network::{config as netconfig, config::RequestResponseConfig, IfDisconnected}; +use sp_core::{testing::TaskExecutor, traits::SpawnNamed}; +use sp_keystore::KeystorePtr; + +use polkadot_node_network_protocol::{ + jaeger, + request_response::{v1, IncomingRequest, OutgoingRequest, Requests}, +}; +use polkadot_node_primitives::ErasureChunk; +use polkadot_node_subsystem::{ + messages::{ + AllMessages, AvailabilityDistributionMessage, AvailabilityStoreMessage, ChainApiMessage, + NetworkBridgeTxMessage, RuntimeApiMessage, RuntimeApiRequest, + }, + ActivatedLeaf, ActiveLeavesUpdate, FromOrchestra, LeafStatus, OverseerSignal, +}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_primitives::{ + CandidateHash, CoreState, GroupIndex, Hash, Id as ParaId, ScheduledCore, SessionInfo, + ValidatorIndex, +}; +use test_helpers::mock::make_ferdie_keystore; + +use super::mock::{make_session_info, OccupiedCoreBuilder}; +use crate::LOG_TARGET; + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; +pub struct TestHarness { + pub virtual_overseer: VirtualOverseer, + pub pov_req_cfg: RequestResponseConfig, + pub chunk_req_cfg: RequestResponseConfig, + pub pool: TaskExecutor, +} + +/// `TestState` for mocking execution of this subsystem. +/// +/// The `Default` instance provides data, which makes the system succeed by providing a couple of +/// valid occupied cores. You can tune the data before calling `TestState::run`. E.g. modify some +/// chunks to be invalid, the test will then still pass if you remove that chunk from +/// `valid_chunks`. +#[derive(Clone)] +pub struct TestState { + /// Simulated relay chain heads: + pub relay_chain: Vec, + /// Whenever the subsystem tries to fetch an erasure chunk one item of the given vec will be + /// popped. So you can experiment with serving invalid chunks or no chunks on request and see + /// whether the subsystem still succeeds with its goal. + pub chunks: HashMap<(CandidateHash, ValidatorIndex), Vec>>, + /// All chunks that are valid and should be accepted. + pub valid_chunks: HashSet<(CandidateHash, ValidatorIndex)>, + pub session_info: SessionInfo, + /// Cores per relay chain block. + pub cores: HashMap>, + pub keystore: KeystorePtr, +} + +impl Default for TestState { + fn default() -> Self { + let relay_chain: Vec<_> = (1u8..10).map(Hash::repeat_byte).collect(); + let chain_a = ParaId::from(1); + let chain_b = ParaId::from(2); + + let chain_ids = vec![chain_a, chain_b]; + + let keystore = make_ferdie_keystore(); + + let session_info = make_session_info(); + + let (cores, chunks) = { + let mut cores = HashMap::new(); + let mut chunks = HashMap::new(); + + cores.insert( + relay_chain[0], + vec![ + CoreState::Scheduled(ScheduledCore { para_id: chain_ids[0], collator: None }), + CoreState::Scheduled(ScheduledCore { para_id: chain_ids[1], collator: None }), + ], + ); + + let heads = { + let mut advanced = relay_chain.iter(); + advanced.next(); + relay_chain.iter().zip(advanced) + }; + for (relay_parent, relay_child) in heads { + let (p_cores, p_chunks): (Vec<_>, Vec<_>) = chain_ids + .iter() + .enumerate() + .map(|(i, para_id)| { + let (core, chunk) = OccupiedCoreBuilder { + group_responsible: GroupIndex(i as _), + para_id: *para_id, + relay_parent: *relay_parent, + } + .build(); + (CoreState::Occupied(core), chunk) + }) + .unzip(); + cores.insert(*relay_child, p_cores); + // Skip chunks for our own group (won't get fetched): + let mut chunks_other_groups = p_chunks.into_iter(); + chunks_other_groups.next(); + for (validator_index, chunk) in chunks_other_groups { + chunks.insert((validator_index, chunk.index), vec![Some(chunk)]); + } + } + (cores, chunks) + }; + Self { + relay_chain, + valid_chunks: chunks.clone().keys().map(Clone::clone).collect(), + chunks, + session_info, + cores, + keystore, + } + } +} + +impl TestState { + /// Run, but fail after some timeout. + pub async fn run(self, harness: TestHarness) { + // Make sure test won't run forever. + let f = self.run_inner(harness).timeout(Duration::from_secs(10)); + assert!(f.await.is_some(), "Test ran into timeout"); + } + + /// Run tests with the given mock values in `TestState`. + /// + /// This will simply advance through the simulated chain and examines whether the subsystem + /// behaves as expected: It will succeed if all valid chunks of other backing groups get stored + /// and no other. + /// + /// We try to be as agnostic about details as possible, how the subsystem achieves those goals + /// should not be a matter to this test suite. + async fn run_inner(mut self, mut harness: TestHarness) { + // We skip genesis here (in reality ActiveLeavesUpdate can also skip a block): + let updates = { + let mut advanced = self.relay_chain.iter(); + advanced.next(); + self.relay_chain + .iter() + .zip(advanced) + .map(|(old, new)| ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: *new, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + deactivated: vec![*old].into(), + }) + .collect::>() + }; + + // We should be storing all valid chunks during execution: + // + // Test will fail if this does not happen until timeout. + let mut remaining_stores = self.valid_chunks.len(); + + let TestSubsystemContextHandle { tx, mut rx } = harness.virtual_overseer; + + // Spawning necessary as incoming queue can only hold a single item, we don't want to dead + // lock ;-) + let update_tx = tx.clone(); + harness.pool.spawn( + "sending-active-leaves-updates", + None, + async move { + for update in updates { + overseer_signal(update_tx.clone(), OverseerSignal::ActiveLeaves(update)).await; + // We need to give the subsystem a little time to do its job, otherwise it will + // cancel jobs as obsolete: + Delay::new(Duration::from_millis(100)).await; + } + } + .boxed(), + ); + + while remaining_stores > 0 { + gum::trace!(target: LOG_TARGET, remaining_stores, "Stores left to go"); + let msg = overseer_recv(&mut rx).await; + match msg { + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendRequests( + reqs, + IfDisconnected::ImmediateError, + )) => { + for req in reqs { + // Forward requests: + let in_req = to_incoming_req(&harness.pool, req); + harness + .chunk_req_cfg + .inbound_queue + .as_mut() + .unwrap() + .send(in_req.into_raw()) + .await + .unwrap(); + } + }, + AllMessages::AvailabilityStore(AvailabilityStoreMessage::QueryChunk( + candidate_hash, + validator_index, + tx, + )) => { + let chunk = self + .chunks + .get_mut(&(candidate_hash, validator_index)) + .and_then(Vec::pop) + .flatten(); + tx.send(chunk).expect("Receiver is expected to be alive"); + }, + AllMessages::AvailabilityStore(AvailabilityStoreMessage::StoreChunk { + candidate_hash, + chunk, + tx, + .. + }) => { + assert!( + self.valid_chunks.contains(&(candidate_hash, chunk.index)), + "Only valid chunks should ever get stored." + ); + tx.send(Ok(())).expect("Receiver is expected to be alive"); + gum::trace!(target: LOG_TARGET, "'Stored' fetched chunk."); + remaining_stores -= 1; + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(hash, req)) => { + match req { + RuntimeApiRequest::SessionIndexForChild(tx) => { + // Always session index 1 for now: + tx.send(Ok(1)).expect("Receiver should still be alive"); + }, + RuntimeApiRequest::SessionInfo(_, tx) => { + tx.send(Ok(Some(self.session_info.clone()))) + .expect("Receiver should be alive."); + }, + RuntimeApiRequest::AvailabilityCores(tx) => { + gum::trace!(target: LOG_TARGET, cores= ?self.cores[&hash], hash = ?hash, "Sending out cores for hash"); + tx.send(Ok(self.cores[&hash].clone())) + .expect("Receiver should still be alive"); + }, + _ => { + panic!("Unexpected runtime request: {:?}", req); + }, + } + }, + AllMessages::ChainApi(ChainApiMessage::Ancestors { hash, k, response_channel }) => { + let chain = &self.relay_chain; + let maybe_block_position = chain.iter().position(|h| *h == hash); + let ancestors = maybe_block_position + .map(|idx| chain[..idx].iter().rev().take(k).copied().collect()) + .unwrap_or_default(); + response_channel.send(Ok(ancestors)).expect("Receiver is expected to be alive"); + }, + _ => {}, + } + } + + overseer_signal(tx, OverseerSignal::Conclude).await; + } +} + +async fn overseer_signal( + mut tx: mpsc::Sender>, + msg: impl Into, +) { + let msg = msg.into(); + gum::trace!(target: LOG_TARGET, msg = ?msg, "sending message"); + tx.send(FromOrchestra::Signal(msg)) + .await + .expect("Test subsystem no longer live"); +} + +async fn overseer_recv(rx: &mut mpsc::UnboundedReceiver) -> AllMessages { + gum::trace!(target: LOG_TARGET, "waiting for message ..."); + rx.next().await.expect("Test subsystem no longer live") +} + +fn to_incoming_req( + executor: &TaskExecutor, + outgoing: Requests, +) -> IncomingRequest { + match outgoing { + Requests::ChunkFetchingV1(OutgoingRequest { payload, pending_response, .. }) => { + let (tx, rx): (oneshot::Sender, oneshot::Receiver<_>) = + oneshot::channel(); + executor.spawn( + "message-forwarding", + None, + async { + let response = rx.await; + let payload = response.expect("Unexpected canceled request").result; + pending_response + .send(payload.map_err(|_| network::RequestFailure::Refused)) + .expect("Sending response is expected to work"); + } + .boxed(), + ); + + IncomingRequest::new( + // We don't really care: + network::PeerId::random(), + payload, + tx, + ) + }, + _ => panic!("Unexpected request!"), + } +} diff --git a/polkadot/node/network/availability-recovery/Cargo.toml b/polkadot/node/network/availability-recovery/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..f601b8aedc4646a554d89bfddd9303ec51136c6b --- /dev/null +++ b/polkadot/node/network/availability-recovery/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "polkadot-availability-recovery" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +lru = "0.11.0" +rand = "0.8.5" +fatality = "0.0.6" +thiserror = "1.0.31" +gum = { package = "tracing-gum", path = "../../gum" } + +polkadot-erasure-coding = { path = "../../../erasure-coding" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem = {path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-node-network-protocol = { path = "../../network/protocol" } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[dev-dependencies] +assert_matches = "1.4.0" +env_logger = "0.9.0" +futures-timer = "3.0.2" +log = "0.4.17" + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } + +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +polkadot-primitives-test-helpers = { path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/network/availability-recovery/src/error.rs b/polkadot/node/network/availability-recovery/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..47277a521b81ee72261ab8d71ff9f0cf97bf56ad --- /dev/null +++ b/polkadot/node/network/availability-recovery/src/error.rs @@ -0,0 +1,47 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The `Error` and `Result` types used by the subsystem. + +use futures::channel::oneshot; +use thiserror::Error; + +/// Error type used by the Availability Recovery subsystem. +#[derive(Debug, Error)] +pub enum Error { + #[error(transparent)] + Subsystem(#[from] polkadot_node_subsystem::SubsystemError), + + #[error("failed to query full data from store")] + CanceledQueryFullData(#[source] oneshot::Canceled), + + #[error("failed to query session info")] + CanceledSessionInfo(#[source] oneshot::Canceled), + + #[error("failed to send response")] + CanceledResponseSender, + + #[error(transparent)] + Runtime(#[from] polkadot_node_subsystem::errors::RuntimeApiError), + + #[error(transparent)] + Erasure(#[from] polkadot_erasure_coding::Error), + + #[error(transparent)] + Util(#[from] polkadot_node_subsystem_util::Error), +} + +pub type Result = std::result::Result; diff --git a/polkadot/node/network/availability-recovery/src/futures_undead.rs b/polkadot/node/network/availability-recovery/src/futures_undead.rs new file mode 100644 index 0000000000000000000000000000000000000000..04ef3e749399fa2da24f7870d692d9e480dc42bf --- /dev/null +++ b/polkadot/node/network/availability-recovery/src/futures_undead.rs @@ -0,0 +1,236 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! FuturesUndead: A `FuturesUnordered` with support for semi canceled futures. Those undead +//! futures will still get polled, but will not count towards length. So length will only count +//! futures, which are still considered live. +//! +//! Use case: If futures take longer than we would like them too, we may be able to request the data +//! from somewhere else as well. We don't really want to cancel the old future, because maybe it +//! was almost done, thus we would have wasted time with our impatience. By simply making them +//! not count towards length, we can make sure to have enough "live" requests ongoing, while at the +//! same time taking advantage of some maybe "late" response from the undead. + +use std::{ + pin::Pin, + task::{Context, Poll}, + time::Duration, +}; + +use futures::{future::BoxFuture, stream::FuturesUnordered, Future, Stream, StreamExt}; +use polkadot_node_subsystem_util::TimeoutExt; + +/// FuturesUndead - `FuturesUnordered` with semi canceled (undead) futures. +/// +/// Limitations: Keeps track of undead futures by means of a counter, which is limited to 64 +/// bits, so after `1.8*10^19` pushed futures, this implementation will panic. +pub struct FuturesUndead { + /// Actual `FuturesUnordered`. + inner: FuturesUnordered>, + /// Next sequence number to assign to the next future that gets pushed. + next_sequence: SequenceNumber, + /// Sequence number of first future considered live. + first_live: Option, + /// How many undead are there right now. + undead: usize, +} + +/// All futures get a number, to determine which are live. +#[derive(Eq, PartialEq, Copy, Clone, Debug, PartialOrd)] +struct SequenceNumber(usize); + +struct Undead { + inner: BoxFuture<'static, Output>, + our_sequence: SequenceNumber, +} + +impl FuturesUndead { + pub fn new() -> Self { + Self { + inner: FuturesUnordered::new(), + next_sequence: SequenceNumber(0), + first_live: None, + undead: 0, + } + } + + pub fn push(&mut self, f: BoxFuture<'static, Output>) { + self.inner.push(Undead { inner: f, our_sequence: self.next_sequence }); + self.next_sequence.inc(); + } + + /// Make all contained futures undead. + /// + /// They will no longer be counted on a call to `len`. + pub fn soft_cancel(&mut self) { + self.undead = self.inner.len(); + self.first_live = Some(self.next_sequence); + } + + /// Number of contained futures minus undead. + pub fn len(&self) -> usize { + self.inner.len() - self.undead + } + + /// Total number of futures, including undead. + pub fn total_len(&self) -> usize { + self.inner.len() + } + + /// Wait for next future to return with timeout. + /// + /// When timeout passes, return `None` and make all currently contained futures undead. + pub async fn next_with_timeout(&mut self, timeout: Duration) -> Option { + match self.next().timeout(timeout).await { + // Timeout: + None => { + self.soft_cancel(); + None + }, + Some(inner) => inner, + } + } +} + +impl Stream for FuturesUndead { + type Item = Output; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.inner.poll_next_unpin(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(None) => Poll::Ready(None), + Poll::Ready(Some((sequence, v))) => { + // Cleanup in case we became completely empty: + if self.inner.len() == 0 { + *self = Self::new(); + return Poll::Ready(Some(v)) + } + + let first_live = match self.first_live { + None => return Poll::Ready(Some(v)), + Some(first_live) => first_live, + }; + // An undead came back: + if sequence < first_live { + self.undead = self.undead.saturating_sub(1); + } + Poll::Ready(Some(v)) + }, + } + } +} + +impl SequenceNumber { + pub fn inc(&mut self) { + self.0 = self.0.checked_add(1).expect( + "We don't expect an `UndeadFuture` to live long enough for 2^64 entries ever getting inserted." + ); + } +} + +impl Future for Undead { + type Output = (SequenceNumber, T); + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match self.inner.as_mut().poll(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(v) => Poll::Ready((self.our_sequence, v)), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use futures::{executor, pending, FutureExt}; + + #[test] + fn cancel_sets_len_to_zero() { + let mut undead = FuturesUndead::new(); + undead.push((async { () }).boxed()); + assert_eq!(undead.len(), 1); + undead.soft_cancel(); + assert_eq!(undead.len(), 0); + } + + #[test] + fn finished_undead_does_not_change_len() { + executor::block_on(async { + let mut undead = FuturesUndead::new(); + undead.push(async { 1_i32 }.boxed()); + undead.push(async { 2_i32 }.boxed()); + assert_eq!(undead.len(), 2); + undead.soft_cancel(); + assert_eq!(undead.len(), 0); + undead.push( + async { + pending!(); + 0_i32 + } + .boxed(), + ); + undead.next().await; + assert_eq!(undead.len(), 1); + undead.push(async { 9_i32 }.boxed()); + undead.soft_cancel(); + assert_eq!(undead.len(), 0); + }); + } + + #[test] + fn len_stays_correct_when_live_future_ends() { + executor::block_on(async { + let mut undead = FuturesUndead::new(); + undead.push( + async { + pending!(); + 1_i32 + } + .boxed(), + ); + undead.push( + async { + pending!(); + 2_i32 + } + .boxed(), + ); + assert_eq!(undead.len(), 2); + undead.soft_cancel(); + assert_eq!(undead.len(), 0); + undead.push(async { 0_i32 }.boxed()); + undead.push(async { 1_i32 }.boxed()); + undead.next().await; + assert_eq!(undead.len(), 1); + undead.next().await; + assert_eq!(undead.len(), 0); + undead.push(async { 9_i32 }.boxed()); + assert_eq!(undead.len(), 1); + }); + } + + #[test] + fn cleanup_works() { + executor::block_on(async { + let mut undead = FuturesUndead::new(); + undead.push(async { 1_i32 }.boxed()); + undead.soft_cancel(); + undead.push(async { 2_i32 }.boxed()); + undead.next().await; + undead.next().await; + assert_eq!(undead.first_live, None); + }); + } +} diff --git a/polkadot/node/network/availability-recovery/src/lib.rs b/polkadot/node/network/availability-recovery/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..fb0cdb7205710623af2ad90dabd5ef4febcfb90f --- /dev/null +++ b/polkadot/node/network/availability-recovery/src/lib.rs @@ -0,0 +1,1435 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Availability Recovery Subsystem of Polkadot. + +#![warn(missing_docs)] + +use std::{ + collections::{HashMap, VecDeque}, + iter::Iterator, + num::NonZeroUsize, + pin::Pin, + time::Duration, +}; + +use futures::{ + channel::oneshot::{self, channel}, + future::{Future, FutureExt, RemoteHandle}, + pin_mut, + prelude::*, + sink::SinkExt, + stream::{FuturesUnordered, StreamExt}, + task::{Context, Poll}, +}; +use lru::LruCache; +use rand::seq::SliceRandom; + +use fatality::Nested; +use polkadot_erasure_coding::{ + branch_hash, branches, obtain_chunks_v1, recovery_threshold, Error as ErasureEncodingError, +}; +#[cfg(not(test))] +use polkadot_node_network_protocol::request_response::CHUNK_REQUEST_TIMEOUT; +use polkadot_node_network_protocol::{ + request_response::{ + self as req_res, outgoing::RequestError, v1 as request_v1, IncomingRequestReceiver, + OutgoingRequest, Recipient, Requests, + }, + IfDisconnected, UnifiedReputationChange as Rep, +}; +use polkadot_node_primitives::{AvailableData, ErasureChunk}; +use polkadot_node_subsystem::{ + errors::RecoveryError, + jaeger, + messages::{AvailabilityRecoveryMessage, AvailabilityStoreMessage, NetworkBridgeTxMessage}, + overseer, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, + SubsystemResult, +}; +use polkadot_node_subsystem_util::request_session_info; +use polkadot_primitives::{ + AuthorityDiscoveryId, BlakeTwo256, BlockNumber, CandidateHash, CandidateReceipt, GroupIndex, + Hash, HashT, IndexedVec, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, +}; + +mod error; +mod futures_undead; +mod metrics; +use metrics::Metrics; + +use futures_undead::FuturesUndead; +use sc_network::{OutboundFailure, RequestFailure}; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &str = "parachain::availability-recovery"; + +// How many parallel recovery tasks should be running at once. +const N_PARALLEL: usize = 50; + +// Size of the LRU cache where we keep recovered data. +const LRU_SIZE: NonZeroUsize = match NonZeroUsize::new(16) { + Some(cap) => cap, + None => panic!("Availability-recovery cache size must be non-zero."), +}; + +const COST_INVALID_REQUEST: Rep = Rep::CostMajor("Peer sent unparsable request"); + +/// Time after which we consider a request to have failed +/// +/// and we should try more peers. Note in theory the request times out at the network level, +/// measurements have shown, that in practice requests might actually take longer to fail in +/// certain occasions. (The very least, authority discovery is not part of the timeout.) +/// +/// For the time being this value is the same as the timeout on the networking layer, but as this +/// timeout is more soft than the networking one, it might make sense to pick different values as +/// well. +#[cfg(not(test))] +const TIMEOUT_START_NEW_REQUESTS: Duration = CHUNK_REQUEST_TIMEOUT; +#[cfg(test)] +const TIMEOUT_START_NEW_REQUESTS: Duration = Duration::from_millis(100); + +/// PoV size limit in bytes for which prefer fetching from backers. +const SMALL_POV_LIMIT: usize = 128 * 1024; + +#[derive(Clone, PartialEq)] +/// The strategy we use to recover the PoV. +pub enum RecoveryStrategy { + /// We always try the backing group first, then fallback to validator chunks. + BackersFirstAlways, + /// We try the backing group first if PoV size is lower than specified, then fallback to + /// validator chunks. + BackersFirstIfSizeLower(usize), + /// We always recover using validator chunks. + ChunksAlways, + /// Do not request data from the availability store. + /// This is the useful for nodes where the + /// availability-store subsystem is not expected to run, + /// such as collators. + BypassAvailabilityStore, +} + +impl RecoveryStrategy { + /// Returns true if the strategy needs backing group index. + pub fn needs_backing_group(&self) -> bool { + match self { + RecoveryStrategy::BackersFirstAlways | RecoveryStrategy::BackersFirstIfSizeLower(_) => + true, + _ => false, + } + } + + /// Returns the PoV size limit in bytes for `BackersFirstIfSizeLower` strategy, otherwise + /// `None`. + pub fn pov_size_limit(&self) -> Option { + match *self { + RecoveryStrategy::BackersFirstIfSizeLower(limit) => Some(limit), + _ => None, + } + } +} +/// The Availability Recovery Subsystem. +pub struct AvailabilityRecoverySubsystem { + /// PoV recovery strategy to use. + recovery_strategy: RecoveryStrategy, + /// Receiver for available data requests. + req_receiver: IncomingRequestReceiver, + /// Metrics for this subsystem. + metrics: Metrics, +} + +struct RequestFromBackers { + // a random shuffling of the validators from the backing group which indicates the order + // in which we connect to them and request the chunk. + shuffled_backers: Vec, + // channel to the erasure task handler. + erasure_task_tx: futures::channel::mpsc::Sender, +} + +struct RequestChunksFromValidators { + /// How many request have been unsuccessful so far. + error_count: usize, + /// Total number of responses that have been received. + /// + /// including failed ones. + total_received_responses: usize, + /// a random shuffling of the validators which indicates the order in which we connect to the + /// validators and request the chunk from them. + shuffling: VecDeque, + /// Chunks received so far. + received_chunks: HashMap, + /// Pending chunk requests with soft timeout. + requesting_chunks: FuturesUndead, (ValidatorIndex, RequestError)>>, + // channel to the erasure task handler. + erasure_task_tx: futures::channel::mpsc::Sender, +} + +struct RecoveryParams { + /// Discovery ids of `validators`. + validator_authority_keys: Vec, + + /// Validators relevant to this `RecoveryTask`. + validators: IndexedVec, + + /// The number of pieces needed. + threshold: usize, + + /// A hash of the relevant candidate. + candidate_hash: CandidateHash, + + /// The root of the erasure encoding of the para block. + erasure_root: Hash, + + /// Metrics to report + metrics: Metrics, + + /// Do not request data from availability-store + bypass_availability_store: bool, +} + +/// Source the availability data either by means +/// of direct request response protocol to +/// backers (a.k.a. fast-path), or recover from chunks. +enum Source { + RequestFromBackers(RequestFromBackers), + RequestChunks(RequestChunksFromValidators), +} + +/// Expensive erasure coding computations that we want to run on a blocking thread. +enum ErasureTask { + /// Reconstructs `AvailableData` from chunks given `n_validators`. + Reconstruct( + usize, + HashMap, + oneshot::Sender>, + ), + /// Re-encode `AvailableData` into erasure chunks in order to verify the provided root hash of + /// the Merkle tree. + Reencode(usize, Hash, AvailableData, oneshot::Sender>), +} + +/// A stateful reconstruction of availability data in reference to +/// a candidate hash. +struct RecoveryTask { + sender: Sender, + + /// The parameters of the recovery process. + params: RecoveryParams, + + /// The source to obtain the availability data from. + source: Source, + + // channel to the erasure task handler. + erasure_task_tx: futures::channel::mpsc::Sender, +} + +impl RequestFromBackers { + fn new( + mut backers: Vec, + erasure_task_tx: futures::channel::mpsc::Sender, + ) -> Self { + backers.shuffle(&mut rand::thread_rng()); + + RequestFromBackers { shuffled_backers: backers, erasure_task_tx } + } + + // Run this phase to completion. + async fn run( + &mut self, + params: &RecoveryParams, + sender: &mut impl overseer::AvailabilityRecoverySenderTrait, + ) -> Result { + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + erasure_root = ?params.erasure_root, + "Requesting from backers", + ); + loop { + // Pop the next backer, and proceed to next phase if we're out. + let validator_index = + self.shuffled_backers.pop().ok_or_else(|| RecoveryError::Unavailable)?; + + // Request data. + let (req, response) = OutgoingRequest::new( + Recipient::Authority( + params.validator_authority_keys[validator_index.0 as usize].clone(), + ), + req_res::v1::AvailableDataFetchingRequest { candidate_hash: params.candidate_hash }, + ); + + sender + .send_message(NetworkBridgeTxMessage::SendRequests( + vec![Requests::AvailableDataFetchingV1(req)], + IfDisconnected::ImmediateError, + )) + .await; + + match response.await { + Ok(req_res::v1::AvailableDataFetchingResponse::AvailableData(data)) => { + let (reencode_tx, reencode_rx) = channel(); + self.erasure_task_tx + .send(ErasureTask::Reencode( + params.validators.len(), + params.erasure_root, + data, + reencode_tx, + )) + .await + .map_err(|_| RecoveryError::ChannelClosed)?; + + let reencode_response = + reencode_rx.await.map_err(|_| RecoveryError::ChannelClosed)?; + + if let Some(data) = reencode_response { + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + "Received full data", + ); + + return Ok(data) + } else { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + ?validator_index, + "Invalid data response", + ); + + // it doesn't help to report the peer with req/res. + } + }, + Ok(req_res::v1::AvailableDataFetchingResponse::NoSuchData) => {}, + Err(e) => gum::debug!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + ?validator_index, + err = ?e, + "Error fetching full available data." + ), + } + } + } +} + +impl RequestChunksFromValidators { + fn new( + n_validators: u32, + erasure_task_tx: futures::channel::mpsc::Sender, + ) -> Self { + let mut shuffling: Vec<_> = (0..n_validators).map(ValidatorIndex).collect(); + shuffling.shuffle(&mut rand::thread_rng()); + + RequestChunksFromValidators { + error_count: 0, + total_received_responses: 0, + shuffling: shuffling.into(), + received_chunks: HashMap::new(), + requesting_chunks: FuturesUndead::new(), + erasure_task_tx, + } + } + + fn is_unavailable(&self, params: &RecoveryParams) -> bool { + is_unavailable( + self.chunk_count(), + self.requesting_chunks.total_len(), + self.shuffling.len(), + params.threshold, + ) + } + + fn chunk_count(&self) -> usize { + self.received_chunks.len() + } + + fn insert_chunk(&mut self, validator_index: ValidatorIndex, chunk: ErasureChunk) { + self.received_chunks.insert(validator_index, chunk); + } + + fn can_conclude(&self, params: &RecoveryParams) -> bool { + self.chunk_count() >= params.threshold || self.is_unavailable(params) + } + + /// Desired number of parallel requests. + /// + /// For the given threshold (total required number of chunks) get the desired number of + /// requests we want to have running in parallel at this time. + fn get_desired_request_count(&self, threshold: usize) -> usize { + // Upper bound for parallel requests. + // We want to limit this, so requests can be processed within the timeout and we limit the + // following feedback loop: + // 1. Requests fail due to timeout + // 2. We request more chunks to make up for it + // 3. Bandwidth is spread out even more, so we get even more timeouts + // 4. We request more chunks to make up for it ... + let max_requests_boundary = std::cmp::min(N_PARALLEL, threshold); + // How many chunks are still needed? + let remaining_chunks = threshold.saturating_sub(self.chunk_count()); + // What is the current error rate, so we can make up for it? + let inv_error_rate = + self.total_received_responses.checked_div(self.error_count).unwrap_or(0); + // Actual number of requests we want to have in flight in parallel: + std::cmp::min( + max_requests_boundary, + remaining_chunks + remaining_chunks.checked_div(inv_error_rate).unwrap_or(0), + ) + } + + async fn launch_parallel_requests( + &mut self, + params: &RecoveryParams, + sender: &mut Sender, + ) where + Sender: overseer::AvailabilityRecoverySenderTrait, + { + let num_requests = self.get_desired_request_count(params.threshold); + let candidate_hash = ¶ms.candidate_hash; + let already_requesting_count = self.requesting_chunks.len(); + + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + ?num_requests, + error_count= ?self.error_count, + total_received = ?self.total_received_responses, + threshold = ?params.threshold, + ?already_requesting_count, + "Requesting availability chunks for a candidate", + ); + let mut requests = Vec::with_capacity(num_requests - already_requesting_count); + + while self.requesting_chunks.len() < num_requests { + if let Some(validator_index) = self.shuffling.pop_back() { + let validator = params.validator_authority_keys[validator_index.0 as usize].clone(); + gum::trace!( + target: LOG_TARGET, + ?validator, + ?validator_index, + ?candidate_hash, + "Requesting chunk", + ); + + // Request data. + let raw_request = req_res::v1::ChunkFetchingRequest { + candidate_hash: params.candidate_hash, + index: validator_index, + }; + + let (req, res) = OutgoingRequest::new(Recipient::Authority(validator), raw_request); + requests.push(Requests::ChunkFetchingV1(req)); + + params.metrics.on_chunk_request_issued(); + let timer = params.metrics.time_chunk_request(); + + self.requesting_chunks.push(Box::pin(async move { + let _timer = timer; + match res.await { + Ok(req_res::v1::ChunkFetchingResponse::Chunk(chunk)) => + Ok(Some(chunk.recombine_into_chunk(&raw_request))), + Ok(req_res::v1::ChunkFetchingResponse::NoSuchChunk) => Ok(None), + Err(e) => Err((validator_index, e)), + } + })); + } else { + break + } + } + + sender + .send_message(NetworkBridgeTxMessage::SendRequests( + requests, + IfDisconnected::TryConnect, + )) + .await; + } + + /// Wait for a sufficient amount of chunks to reconstruct according to the provided `params`. + async fn wait_for_chunks(&mut self, params: &RecoveryParams) { + let metrics = ¶ms.metrics; + + // Wait for all current requests to conclude or time-out, or until we reach enough chunks. + // We also declare requests undead, once `TIMEOUT_START_NEW_REQUESTS` is reached and will + // return in that case for `launch_parallel_requests` to fill up slots again. + while let Some(request_result) = + self.requesting_chunks.next_with_timeout(TIMEOUT_START_NEW_REQUESTS).await + { + self.total_received_responses += 1; + + match request_result { + Ok(Some(chunk)) => + if is_chunk_valid(params, &chunk) { + metrics.on_chunk_request_succeeded(); + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + validator_index = ?chunk.index, + "Received valid chunk", + ); + self.insert_chunk(chunk.index, chunk); + } else { + metrics.on_chunk_request_invalid(); + self.error_count += 1; + }, + Ok(None) => { + metrics.on_chunk_request_no_such_chunk(); + self.error_count += 1; + }, + Err((validator_index, e)) => { + self.error_count += 1; + + gum::trace!( + target: LOG_TARGET, + candidate_hash= ?params.candidate_hash, + err = ?e, + ?validator_index, + "Failure requesting chunk", + ); + + match e { + RequestError::InvalidResponse(_) => { + metrics.on_chunk_request_invalid(); + + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + err = ?e, + ?validator_index, + "Chunk fetching response was invalid", + ); + }, + RequestError::NetworkError(err) => { + // No debug logs on general network errors - that became very spammy + // occasionally. + if let RequestFailure::Network(OutboundFailure::Timeout) = err { + metrics.on_chunk_request_timeout(); + } else { + metrics.on_chunk_request_error(); + } + + self.shuffling.push_front(validator_index); + }, + RequestError::Canceled(_) => { + metrics.on_chunk_request_error(); + + self.shuffling.push_front(validator_index); + }, + } + }, + } + + // Stop waiting for requests when we either can already recover the data + // or have gotten firm 'No' responses from enough validators. + if self.can_conclude(params) { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + received_chunks_count = ?self.chunk_count(), + requested_chunks_count = ?self.requesting_chunks.len(), + threshold = ?params.threshold, + "Can conclude availability for a candidate", + ); + break + } + } + } + + async fn run( + &mut self, + params: &RecoveryParams, + sender: &mut Sender, + ) -> Result + where + Sender: overseer::AvailabilityRecoverySenderTrait, + { + let metrics = ¶ms.metrics; + + // First query the store for any chunks we've got. + if !params.bypass_availability_store { + let (tx, rx) = oneshot::channel(); + sender + .send_message(AvailabilityStoreMessage::QueryAllChunks(params.candidate_hash, tx)) + .await; + + match rx.await { + Ok(chunks) => { + // This should either be length 1 or 0. If we had the whole data, + // we wouldn't have reached this stage. + let chunk_indices: Vec<_> = chunks.iter().map(|c| c.index).collect(); + self.shuffling.retain(|i| !chunk_indices.contains(i)); + + for chunk in chunks { + if is_chunk_valid(params, &chunk) { + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + validator_index = ?chunk.index, + "Found valid chunk on disk" + ); + self.insert_chunk(chunk.index, chunk); + } else { + gum::error!( + target: LOG_TARGET, + "Loaded invalid chunk from disk! Disk/Db corruption _very_ likely - please fix ASAP!" + ); + }; + } + }, + Err(oneshot::Canceled) => { + gum::warn!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + "Failed to reach the availability store" + ); + }, + } + } + + let _recovery_timer = metrics.time_full_recovery(); + + loop { + if self.is_unavailable(¶ms) { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + erasure_root = ?params.erasure_root, + received = %self.chunk_count(), + requesting = %self.requesting_chunks.len(), + total_requesting = %self.requesting_chunks.total_len(), + n_validators = %params.validators.len(), + "Data recovery is not possible", + ); + + metrics.on_recovery_failed(); + + return Err(RecoveryError::Unavailable) + } + + self.launch_parallel_requests(params, sender).await; + self.wait_for_chunks(params).await; + + // If received_chunks has more than threshold entries, attempt to recover the data. + // If that fails, or a re-encoding of it doesn't match the expected erasure root, + // return Err(RecoveryError::Invalid) + if self.chunk_count() >= params.threshold { + let recovery_duration = metrics.time_erasure_recovery(); + + // Send request to reconstruct available data from chunks. + let (avilable_data_tx, available_data_rx) = channel(); + self.erasure_task_tx + .send(ErasureTask::Reconstruct( + params.validators.len(), + std::mem::take(&mut self.received_chunks), + avilable_data_tx, + )) + .await + .map_err(|_| RecoveryError::ChannelClosed)?; + + let available_data_response = + available_data_rx.await.map_err(|_| RecoveryError::ChannelClosed)?; + + return match available_data_response { + Ok(data) => { + // Send request to re-encode the chunks and check merkle root. + let (reencode_tx, reencode_rx) = channel(); + self.erasure_task_tx + .send(ErasureTask::Reencode( + params.validators.len(), + params.erasure_root, + data, + reencode_tx, + )) + .await + .map_err(|_| RecoveryError::ChannelClosed)?; + + let reencode_response = + reencode_rx.await.map_err(|_| RecoveryError::ChannelClosed)?; + + if let Some(data) = reencode_response { + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + erasure_root = ?params.erasure_root, + "Data recovery complete", + ); + metrics.on_recovery_succeeded(); + + Ok(data) + } else { + recovery_duration.map(|rd| rd.stop_and_discard()); + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + erasure_root = ?params.erasure_root, + "Data recovery - root mismatch", + ); + metrics.on_recovery_invalid(); + + Err(RecoveryError::Invalid) + } + }, + Err(err) => { + recovery_duration.map(|rd| rd.stop_and_discard()); + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + erasure_root = ?params.erasure_root, + ?err, + "Data recovery error ", + ); + metrics.on_recovery_invalid(); + + Err(RecoveryError::Invalid) + }, + } + } + } + } +} + +const fn is_unavailable( + received_chunks: usize, + requesting_chunks: usize, + unrequested_validators: usize, + threshold: usize, +) -> bool { + received_chunks + requesting_chunks + unrequested_validators < threshold +} + +/// Check validity of a chunk. +fn is_chunk_valid(params: &RecoveryParams, chunk: &ErasureChunk) -> bool { + let anticipated_hash = + match branch_hash(¶ms.erasure_root, chunk.proof(), chunk.index.0 as usize) { + Ok(hash) => hash, + Err(e) => { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + validator_index = ?chunk.index, + error = ?e, + "Invalid Merkle proof", + ); + return false + }, + }; + let erasure_chunk_hash = BlakeTwo256::hash(&chunk.chunk); + if anticipated_hash != erasure_chunk_hash { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?params.candidate_hash, + validator_index = ?chunk.index, + "Merkle proof mismatch" + ); + return false + } + true +} + +/// Re-encode the data into erasure chunks in order to verify +/// the root hash of the provided Merkle tree, which is built +/// on-top of the encoded chunks. +/// +/// This (expensive) check is necessary, as otherwise we can't be sure that some chunks won't have +/// been tampered with by the backers, which would result in some validators considering the data +/// valid and some invalid as having fetched different set of chunks. The checking of the Merkle +/// proof for individual chunks only gives us guarantees, that we have fetched a chunk belonging to +/// a set the backers have committed to. +/// +/// NOTE: It is fine to do this check with already decoded data, because if the decoding failed for +/// some validators, we can be sure that chunks have been tampered with (by the backers) or the +/// data was invalid to begin with. In the former case, validators fetching valid chunks will see +/// invalid data as well, because the root won't match. In the latter case the situation is the +/// same for anyone anyways. +fn reconstructed_data_matches_root( + n_validators: usize, + expected_root: &Hash, + data: &AvailableData, + metrics: &Metrics, +) -> bool { + let _timer = metrics.time_reencode_chunks(); + + let chunks = match obtain_chunks_v1(n_validators, data) { + Ok(chunks) => chunks, + Err(e) => { + gum::debug!( + target: LOG_TARGET, + err = ?e, + "Failed to obtain chunks", + ); + return false + }, + }; + + let branches = branches(&chunks); + + branches.root() == *expected_root +} + +impl RecoveryTask +where + Sender: overseer::AvailabilityRecoverySenderTrait, +{ + async fn run(mut self) -> Result { + // First just see if we have the data available locally. + if !self.params.bypass_availability_store { + let (tx, rx) = oneshot::channel(); + self.sender + .send_message(AvailabilityStoreMessage::QueryAvailableData( + self.params.candidate_hash, + tx, + )) + .await; + + match rx.await { + Ok(Some(data)) => return Ok(data), + Ok(None) => {}, + Err(oneshot::Canceled) => { + gum::warn!( + target: LOG_TARGET, + candidate_hash = ?self.params.candidate_hash, + "Failed to reach the availability store", + ) + }, + } + } + + self.params.metrics.on_recovery_started(); + + loop { + // These only fail if we cannot reach the underlying subsystem, which case there is + // nothing meaningful we can do. + match self.source { + Source::RequestFromBackers(ref mut from_backers) => { + match from_backers.run(&self.params, &mut self.sender).await { + Ok(data) => break Ok(data), + Err(RecoveryError::Invalid) => break Err(RecoveryError::Invalid), + Err(RecoveryError::ChannelClosed) => + break Err(RecoveryError::ChannelClosed), + Err(RecoveryError::Unavailable) => + self.source = Source::RequestChunks(RequestChunksFromValidators::new( + self.params.validators.len() as _, + self.erasure_task_tx.clone(), + )), + } + }, + Source::RequestChunks(ref mut from_all) => + break from_all.run(&self.params, &mut self.sender).await, + } + } + } +} + +/// Accumulate all awaiting sides for some particular `AvailableData`. +struct RecoveryHandle { + candidate_hash: CandidateHash, + remote: RemoteHandle>, + awaiting: Vec>>, +} + +impl Future for RecoveryHandle { + type Output = Option<(CandidateHash, Result)>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut indices_to_remove = Vec::new(); + for (i, awaiting) in self.awaiting.iter_mut().enumerate().rev() { + if let Poll::Ready(()) = awaiting.poll_canceled(cx) { + indices_to_remove.push(i); + } + } + + // these are reverse order, so remove is fine. + for index in indices_to_remove { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?self.candidate_hash, + "Receiver for available data dropped.", + ); + + self.awaiting.swap_remove(index); + } + + if self.awaiting.is_empty() { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?self.candidate_hash, + "All receivers for available data dropped.", + ); + + return Poll::Ready(None) + } + + let remote = &mut self.remote; + futures::pin_mut!(remote); + let result = futures::ready!(remote.poll(cx)); + + for awaiting in self.awaiting.drain(..) { + let _ = awaiting.send(result.clone()); + } + + Poll::Ready(Some((self.candidate_hash, result))) + } +} + +/// Cached result of an availability recovery operation. +#[derive(Debug, Clone)] +enum CachedRecovery { + /// Availability was successfully retrieved before. + Valid(AvailableData), + /// Availability was successfully retrieved before, but was found to be invalid. + Invalid, +} + +impl CachedRecovery { + /// Convert back to `Result` to deliver responses. + fn into_result(self) -> Result { + match self { + Self::Valid(d) => Ok(d), + Self::Invalid => Err(RecoveryError::Invalid), + } + } +} + +impl TryFrom> for CachedRecovery { + type Error = (); + fn try_from(o: Result) -> Result { + match o { + Ok(d) => Ok(Self::Valid(d)), + Err(RecoveryError::Invalid) => Ok(Self::Invalid), + // We don't want to cache unavailable state, as that state might change, so if + // requested again we want to try again! + Err(RecoveryError::Unavailable) => Err(()), + Err(RecoveryError::ChannelClosed) => Err(()), + } + } +} + +struct State { + /// Each recovery task is implemented as its own async task, + /// and these handles are for communicating with them. + ongoing_recoveries: FuturesUnordered, + + /// A recent block hash for which state should be available. + live_block: (BlockNumber, Hash), + + /// An LRU cache of recently recovered data. + availability_lru: LruCache, +} + +impl Default for State { + fn default() -> Self { + Self { + ongoing_recoveries: FuturesUnordered::new(), + live_block: (0, Hash::default()), + availability_lru: LruCache::new(LRU_SIZE), + } + } +} + +#[overseer::subsystem(AvailabilityRecovery, error=SubsystemError, prefix=self::overseer)] +impl AvailabilityRecoverySubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = self + .run(ctx) + .map_err(|e| SubsystemError::with_origin("availability-recovery", e)) + .boxed(); + SpawnedSubsystem { name: "availability-recovery-subsystem", future } + } +} + +/// Handles a signal from the overseer. +async fn handle_signal(state: &mut State, signal: OverseerSignal) -> SubsystemResult { + match signal { + OverseerSignal::Conclude => Ok(true), + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { activated, .. }) => { + // if activated is non-empty, set state.live_block to the highest block in `activated` + if let Some(activated) = activated { + if activated.number > state.live_block.0 { + state.live_block = (activated.number, activated.hash) + } + } + + Ok(false) + }, + OverseerSignal::BlockFinalized(_, _) => Ok(false), + } +} + +/// Machinery around launching recovery tasks into the background. +#[overseer::contextbounds(AvailabilityRecovery, prefix = self::overseer)] +async fn launch_recovery_task( + state: &mut State, + ctx: &mut Context, + session_info: SessionInfo, + receipt: CandidateReceipt, + mut backing_group: Option, + response_sender: oneshot::Sender>, + metrics: &Metrics, + recovery_strategy: &RecoveryStrategy, + erasure_task_tx: futures::channel::mpsc::Sender, +) -> error::Result<()> { + let candidate_hash = receipt.hash(); + let params = RecoveryParams { + validator_authority_keys: session_info.discovery_keys.clone(), + validators: session_info.validators.clone(), + threshold: recovery_threshold(session_info.validators.len())?, + candidate_hash, + erasure_root: receipt.descriptor.erasure_root, + metrics: metrics.clone(), + bypass_availability_store: recovery_strategy == &RecoveryStrategy::BypassAvailabilityStore, + }; + + if let Some(small_pov_limit) = recovery_strategy.pov_size_limit() { + // Get our own chunk size to get an estimate of the PoV size. + let chunk_size: Result, error::Error> = + query_chunk_size(ctx, candidate_hash).await; + if let Ok(Some(chunk_size)) = chunk_size { + let pov_size_estimate = chunk_size.saturating_mul(session_info.validators.len()) / 3; + let prefer_backing_group = pov_size_estimate < small_pov_limit; + + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + pov_size_estimate, + small_pov_limit, + enabled = prefer_backing_group, + "Prefer fetch from backing group", + ); + + backing_group = backing_group.filter(|_| { + // We keep the backing group only if `1/3` of chunks sum up to less than + // `small_pov_limit`. + prefer_backing_group + }); + } + } + + let phase = backing_group + .and_then(|g| session_info.validator_groups.get(g)) + .map(|group| { + Source::RequestFromBackers(RequestFromBackers::new( + group.clone(), + erasure_task_tx.clone(), + )) + }) + .unwrap_or_else(|| { + Source::RequestChunks(RequestChunksFromValidators::new( + params.validators.len() as _, + erasure_task_tx.clone(), + )) + }); + + let recovery_task = + RecoveryTask { sender: ctx.sender().clone(), params, source: phase, erasure_task_tx }; + + let (remote, remote_handle) = recovery_task.run().remote_handle(); + + state.ongoing_recoveries.push(RecoveryHandle { + candidate_hash, + remote: remote_handle, + awaiting: vec![response_sender], + }); + + if let Err(e) = ctx.spawn("recovery-task", Box::pin(remote)) { + gum::warn!( + target: LOG_TARGET, + err = ?e, + "Failed to spawn a recovery task", + ); + } + + Ok(()) +} + +/// Handles an availability recovery request. +#[overseer::contextbounds(AvailabilityRecovery, prefix = self::overseer)] +async fn handle_recover( + state: &mut State, + ctx: &mut Context, + receipt: CandidateReceipt, + session_index: SessionIndex, + backing_group: Option, + response_sender: oneshot::Sender>, + metrics: &Metrics, + recovery_strategy: &RecoveryStrategy, + erasure_task_tx: futures::channel::mpsc::Sender, +) -> error::Result<()> { + let candidate_hash = receipt.hash(); + + let span = jaeger::Span::new(candidate_hash, "availbility-recovery") + .with_stage(jaeger::Stage::AvailabilityRecovery); + + if let Some(result) = + state.availability_lru.get(&candidate_hash).cloned().map(|v| v.into_result()) + { + if let Err(e) = response_sender.send(result) { + gum::warn!( + target: LOG_TARGET, + err = ?e, + "Error responding with an availability recovery result", + ); + } + return Ok(()) + } + + if let Some(i) = + state.ongoing_recoveries.iter_mut().find(|i| i.candidate_hash == candidate_hash) + { + i.awaiting.push(response_sender); + return Ok(()) + } + + let _span = span.child("not-cached"); + let session_info = request_session_info(state.live_block.1, session_index, ctx.sender()) + .await + .await + .map_err(error::Error::CanceledSessionInfo)??; + + let _span = span.child("session-info-ctx-received"); + match session_info { + Some(session_info) => + launch_recovery_task( + state, + ctx, + session_info, + receipt, + backing_group, + response_sender, + metrics, + recovery_strategy, + erasure_task_tx, + ) + .await, + None => { + gum::warn!(target: LOG_TARGET, "SessionInfo is `None` at {:?}", state.live_block); + response_sender + .send(Err(RecoveryError::Unavailable)) + .map_err(|_| error::Error::CanceledResponseSender)?; + Ok(()) + }, + } +} + +/// Queries a chunk from av-store. +#[overseer::contextbounds(AvailabilityRecovery, prefix = self::overseer)] +async fn query_full_data( + ctx: &mut Context, + candidate_hash: CandidateHash, +) -> error::Result> { + let (tx, rx) = oneshot::channel(); + ctx.send_message(AvailabilityStoreMessage::QueryAvailableData(candidate_hash, tx)) + .await; + + rx.await.map_err(error::Error::CanceledQueryFullData) +} + +/// Queries a chunk from av-store. +#[overseer::contextbounds(AvailabilityRecovery, prefix = self::overseer)] +async fn query_chunk_size( + ctx: &mut Context, + candidate_hash: CandidateHash, +) -> error::Result> { + let (tx, rx) = oneshot::channel(); + ctx.send_message(AvailabilityStoreMessage::QueryChunkSize(candidate_hash, tx)) + .await; + + rx.await.map_err(error::Error::CanceledQueryFullData) +} + +#[overseer::contextbounds(AvailabilityRecovery, prefix = self::overseer)] +impl AvailabilityRecoverySubsystem { + /// Create a new instance of `AvailabilityRecoverySubsystem` which never requests the + /// `AvailabilityStoreSubsystem` subsystem. + pub fn with_availability_store_skip( + req_receiver: IncomingRequestReceiver, + metrics: Metrics, + ) -> Self { + Self { recovery_strategy: RecoveryStrategy::BypassAvailabilityStore, req_receiver, metrics } + } + + /// Create a new instance of `AvailabilityRecoverySubsystem` which starts with a fast path to + /// request data from backers. + pub fn with_fast_path( + req_receiver: IncomingRequestReceiver, + metrics: Metrics, + ) -> Self { + Self { recovery_strategy: RecoveryStrategy::BackersFirstAlways, req_receiver, metrics } + } + + /// Create a new instance of `AvailabilityRecoverySubsystem` which requests only chunks + pub fn with_chunks_only( + req_receiver: IncomingRequestReceiver, + metrics: Metrics, + ) -> Self { + Self { recovery_strategy: RecoveryStrategy::ChunksAlways, req_receiver, metrics } + } + + /// Create a new instance of `AvailabilityRecoverySubsystem` which requests chunks if PoV is + /// above a threshold. + pub fn with_chunks_if_pov_large( + req_receiver: IncomingRequestReceiver, + metrics: Metrics, + ) -> Self { + Self { + recovery_strategy: RecoveryStrategy::BackersFirstIfSizeLower(SMALL_POV_LIMIT), + req_receiver, + metrics, + } + } + + async fn run(self, mut ctx: Context) -> SubsystemResult<()> { + let mut state = State::default(); + let Self { recovery_strategy, mut req_receiver, metrics } = self; + + let (erasure_task_tx, erasure_task_rx) = futures::channel::mpsc::channel(16); + let mut erasure_task_rx = erasure_task_rx.fuse(); + + // `ThreadPoolBuilder` spawns the tasks using `spawn_blocking`. For each worker there will + // be a `mpsc` channel created. Each of these workers take the `Receiver` and poll it in an + // infinite loop. All of the sender ends of the channel are sent as a vec which we then use + // to create a `Cycle` iterator. We use this iterator to assign work in a round-robin + // fashion to the workers in the pool. + // + // How work is dispatched to the pool from the recovery tasks: + // - Once a recovery task finishes retrieving the availability data, it needs to reconstruct + // from chunks and/or + // re-encode the data which are heavy CPU computations. + // To do so it sends an `ErasureTask` to the main loop via the `erasure_task` channel, and + // waits for the results over a `oneshot` channel. + // - In the subsystem main loop we poll the `erasure_task_rx` receiver. + // - We forward the received `ErasureTask` to the `next()` sender yielded by the `Cycle` + // iterator. + // - Some worker thread handles it and sends the response over the `oneshot` channel. + + // Create a thread pool with 2 workers. + let mut to_pool = ThreadPoolBuilder::build( + // Pool is guaranteed to have at least 1 worker thread. + NonZeroUsize::new(2).expect("There are 2 threads; qed"), + metrics.clone(), + &mut ctx, + ) + .into_iter() + .cycle(); + + loop { + let recv_req = req_receiver.recv(|| vec![COST_INVALID_REQUEST]).fuse(); + pin_mut!(recv_req); + futures::select! { + erasure_task = erasure_task_rx.next() => { + match erasure_task { + Some(task) => { + let send_result = to_pool + .next() + .expect("Pool size is `NonZeroUsize`; qed") + .send(task) + .await + .map_err(|_| RecoveryError::ChannelClosed); + + if let Err(err) = send_result { + gum::warn!( + target: LOG_TARGET, + ?err, + "Failed to send erasure coding task", + ); + } + }, + None => { + gum::debug!( + target: LOG_TARGET, + "Erasure task channel closed", + ); + + return Err(SubsystemError::with_origin("availability-recovery", RecoveryError::ChannelClosed)) + } + } + } + v = ctx.recv().fuse() => { + match v? { + FromOrchestra::Signal(signal) => if handle_signal( + &mut state, + signal, + ).await? { + return Ok(()); + } + FromOrchestra::Communication { msg } => { + match msg { + AvailabilityRecoveryMessage::RecoverAvailableData( + receipt, + session_index, + maybe_backing_group, + response_sender, + ) => { + if let Err(e) = handle_recover( + &mut state, + &mut ctx, + receipt, + session_index, + maybe_backing_group.filter(|_| recovery_strategy.needs_backing_group()), + response_sender, + &metrics, + &recovery_strategy, + erasure_task_tx.clone(), + ).await { + gum::warn!( + target: LOG_TARGET, + err = ?e, + "Error handling a recovery request", + ); + } + } + } + } + } + } + in_req = recv_req => { + match in_req.into_nested().map_err(|fatal| SubsystemError::with_origin("availability-recovery", fatal))? { + Ok(req) => { + if recovery_strategy == RecoveryStrategy::BypassAvailabilityStore { + gum::debug!( + target: LOG_TARGET, + "Skipping request to availability-store.", + ); + let _ = req.send_response(None.into()); + continue + } + match query_full_data(&mut ctx, req.payload.candidate_hash).await { + Ok(res) => { + let _ = req.send_response(res.into()); + } + Err(e) => { + gum::debug!( + target: LOG_TARGET, + err = ?e, + "Failed to query available data.", + ); + + let _ = req.send_response(None.into()); + } + } + } + Err(jfyi) => { + gum::debug!( + target: LOG_TARGET, + error = ?jfyi, + "Decoding incoming request failed" + ); + continue + } + } + } + output = state.ongoing_recoveries.select_next_some() => { + if let Some((candidate_hash, result)) = output { + if let Ok(recovery) = CachedRecovery::try_from(result) { + state.availability_lru.put(candidate_hash, recovery); + } + } + } + } + } + } +} + +// A simple thread pool implementation using `spawn_blocking` threads. +struct ThreadPoolBuilder; + +const MAX_THREADS: NonZeroUsize = match NonZeroUsize::new(4) { + Some(max_threads) => max_threads, + None => panic!("MAX_THREADS must be non-zero"), +}; + +impl ThreadPoolBuilder { + // Creates a pool of `size` workers, where 1 <= `size` <= `MAX_THREADS`. + // + // Each worker is created by `spawn_blocking` and takes the receiver side of a channel + // while all of the senders are returned to the caller. Each worker runs `erasure_task_thread` + // that polls the `Receiver` for an `ErasureTask` which is expected to be CPU intensive. The + // larger the input (more or larger chunks/availability data), the more CPU cycles will be + // spent. + // + // For example, for 32KB PoVs, we'd expect re-encode to eat as much as 90ms and 500ms for + // 2.5MiB. + // + // After executing such a task, the worker sends the response via a provided `oneshot` sender. + // + // The caller is responsible for routing work to the workers. + #[overseer::contextbounds(AvailabilityRecovery, prefix = self::overseer)] + pub fn build( + size: NonZeroUsize, + metrics: Metrics, + ctx: &mut Context, + ) -> Vec> { + // At least 1 task, at most `MAX_THREADS. + let size = std::cmp::min(size, MAX_THREADS); + let mut senders = Vec::new(); + + for index in 0..size.into() { + let (tx, rx) = futures::channel::mpsc::channel(8); + senders.push(tx); + + if let Err(e) = ctx + .spawn_blocking("erasure-task", Box::pin(erasure_task_thread(metrics.clone(), rx))) + { + gum::warn!( + target: LOG_TARGET, + err = ?e, + index, + "Failed to spawn a erasure task", + ); + } + } + senders + } +} + +// Handles CPU intensive operation on a dedicated blocking thread. +async fn erasure_task_thread( + metrics: Metrics, + mut ingress: futures::channel::mpsc::Receiver, +) { + loop { + match ingress.next().await { + Some(ErasureTask::Reconstruct(n_validators, chunks, sender)) => { + let _ = sender.send(polkadot_erasure_coding::reconstruct_v1( + n_validators, + chunks.values().map(|c| (&c.chunk[..], c.index.0 as usize)), + )); + }, + Some(ErasureTask::Reencode(n_validators, root, available_data, sender)) => { + let metrics = metrics.clone(); + + let maybe_data = if reconstructed_data_matches_root( + n_validators, + &root, + &available_data, + &metrics, + ) { + Some(available_data) + } else { + None + }; + + let _ = sender.send(maybe_data); + }, + None => { + gum::debug!( + target: LOG_TARGET, + "Erasure task channel closed. Node shutting down ?", + ); + }, + } + } +} diff --git a/polkadot/node/network/availability-recovery/src/metrics.rs b/polkadot/node/network/availability-recovery/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..aa7216739507668c758f3c335e00da2772311789 --- /dev/null +++ b/polkadot/node/network/availability-recovery/src/metrics.rs @@ -0,0 +1,232 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{ + self, + prometheus::{self, Counter, CounterVec, Histogram, Opts, PrometheusError, Registry, U64}, +}; + +/// Availability Distribution metrics. +#[derive(Clone, Default)] +pub struct Metrics(Option); + +#[derive(Clone)] +struct MetricsInner { + /// Number of sent chunk requests. + /// + /// Gets incremented on each sent chunk requests. + chunk_requests_issued: Counter, + + /// A counter for finished chunk requests. + /// + /// Split by result: + /// - `no_such_chunk` ... peer did not have the requested chunk + /// - `timeout` ... request timed out. + /// - `network_error` ... Some networking issue except timeout + /// - `invalid` ... Chunk was received, but not valid. + /// - `success` + chunk_requests_finished: CounterVec, + + /// The duration of request to response. + time_chunk_request: Histogram, + + /// The duration between the pure recovery and verification. + time_erasure_recovery: Histogram, + + /// How much time it takes to re-encode the data into erasure chunks in order to verify + /// the root hash of the provided Merkle tree. See `reconstructed_data_matches_root`. + time_reencode_chunks: Histogram, + + /// Time of a full recovery, including erasure decoding or until we gave + /// up. + time_full_recovery: Histogram, + + /// Number of full recoveries that have been finished one way or the other. + full_recoveries_finished: CounterVec, + + /// Number of full recoveries that have been started on this subsystem. + /// + /// Note: Those are only recoveries which could not get served locally already - so in other + /// words: Only real recoveries. + full_recoveries_started: Counter, +} + +impl Metrics { + /// Create new dummy metrics, not reporting anything. + pub fn new_dummy() -> Self { + Metrics(None) + } + + /// Increment counter on fetched labels. + pub fn on_chunk_request_issued(&self) { + if let Some(metrics) = &self.0 { + metrics.chunk_requests_issued.inc() + } + } + + /// A chunk request timed out. + pub fn on_chunk_request_timeout(&self) { + if let Some(metrics) = &self.0 { + metrics.chunk_requests_finished.with_label_values(&["timeout"]).inc() + } + } + + /// A chunk request failed because validator did not have its chunk. + pub fn on_chunk_request_no_such_chunk(&self) { + if let Some(metrics) = &self.0 { + metrics.chunk_requests_finished.with_label_values(&["no_such_chunk"]).inc() + } + } + + /// A chunk request failed for some non timeout related network error. + pub fn on_chunk_request_error(&self) { + if let Some(metrics) = &self.0 { + metrics.chunk_requests_finished.with_label_values(&["error"]).inc() + } + } + + /// A chunk request succeeded, but was not valid. + pub fn on_chunk_request_invalid(&self) { + if let Some(metrics) = &self.0 { + metrics.chunk_requests_finished.with_label_values(&["invalid"]).inc() + } + } + + /// A chunk request succeeded. + pub fn on_chunk_request_succeeded(&self) { + if let Some(metrics) = &self.0 { + metrics.chunk_requests_finished.with_label_values(&["success"]).inc() + } + } + + /// Get a timer to time request/response duration. + pub fn time_chunk_request(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.time_chunk_request.start_timer()) + } + + /// Get a timer to time erasure code recover. + pub fn time_erasure_recovery(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.time_erasure_recovery.start_timer()) + } + + /// Get a timer to time chunk encoding. + pub fn time_reencode_chunks(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.time_reencode_chunks.start_timer()) + } + + /// Get a timer to measure the time of the complete recovery process. + pub fn time_full_recovery(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.time_full_recovery.start_timer()) + } + + /// A full recovery succeeded. + pub fn on_recovery_succeeded(&self) { + if let Some(metrics) = &self.0 { + metrics.full_recoveries_finished.with_label_values(&["success"]).inc() + } + } + + /// A full recovery failed (data not available). + pub fn on_recovery_failed(&self) { + if let Some(metrics) = &self.0 { + metrics.full_recoveries_finished.with_label_values(&["failure"]).inc() + } + } + + /// A full recovery failed (data was recovered, but invalid). + pub fn on_recovery_invalid(&self) { + if let Some(metrics) = &self.0 { + metrics.full_recoveries_finished.with_label_values(&["invalid"]).inc() + } + } + + /// A recover was started. + pub fn on_recovery_started(&self) { + if let Some(metrics) = &self.0 { + metrics.full_recoveries_started.inc() + } + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &Registry) -> Result { + let metrics = MetricsInner { + chunk_requests_issued: prometheus::register( + Counter::new( + "polkadot_parachain_availability_recovery_chunk_requests_issued", + "Total number of issued chunk requests.", + )?, + registry, + )?, + chunk_requests_finished: prometheus::register( + CounterVec::new( + Opts::new( + "polkadot_parachain_availability_recovery_chunk_requests_finished", + "Total number of chunk requests finished.", + ), + &["result"], + )?, + registry, + )?, + time_chunk_request: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_availability_recovery_time_chunk_request", + "Time spent waiting for a response to a chunk request", + ))?, + registry, + )?, + time_erasure_recovery: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_availability_recovery_time_erasure_recovery", + "Time spent to recover the erasure code and verify the merkle root by re-encoding as erasure chunks", + ))?, + registry, + )?, + time_reencode_chunks: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_availability_reencode_chunks", + "Time spent re-encoding the data as erasure chunks", + ))?, + registry, + )?, + time_full_recovery: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_availability_recovery_time_total", + "Time a full recovery process took, either until failure or successful erasure decoding.", + ))?, + registry, + )?, + full_recoveries_finished: prometheus::register( + CounterVec::new( + Opts::new( + "polkadot_parachain_availability_recovery_recoveries_finished", + "Total number of recoveries that finished.", + ), + &["result"], + )?, + registry, + )?, + full_recoveries_started: prometheus::register( + Counter::new( + "polkadot_parachain_availability_recovery_recovieries_started", + "Total number of started recoveries.", + )?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/network/availability-recovery/src/tests.rs b/polkadot/node/network/availability-recovery/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..de923f5967e5fd919d76ede2fc38e69d25f160e7 --- /dev/null +++ b/polkadot/node/network/availability-recovery/src/tests.rs @@ -0,0 +1,1615 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{sync::Arc, time::Duration}; + +use assert_matches::assert_matches; +use futures::{executor, future}; +use futures_timer::Delay; + +use parity_scale_codec::Encode; +use polkadot_node_network_protocol::request_response::{IncomingRequest, ReqProtocolNames}; + +use super::*; + +use sc_network::config::RequestResponseConfig; + +use polkadot_erasure_coding::{branches, obtain_chunks_v1 as obtain_chunks}; +use polkadot_node_primitives::{BlockData, PoV, Proof}; +use polkadot_node_subsystem::{ + jaeger, + messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}, + ActivatedLeaf, LeafStatus, +}; +use polkadot_node_subsystem_test_helpers::{make_subsystem_context, TestSubsystemContextHandle}; +use polkadot_node_subsystem_util::TimeoutExt; +use polkadot_primitives::{ + AuthorityDiscoveryId, Hash, HeadData, IndexedVec, PersistedValidationData, ValidatorId, +}; +use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_hash}; + +type VirtualOverseer = TestSubsystemContextHandle; + +// Deterministic genesis hash for protocol names +const GENESIS_HASH: Hash = Hash::repeat_byte(0xff); + +fn test_harness_fast_path>( + test: impl FnOnce(VirtualOverseer, RequestResponseConfig) -> T, +) { + let _ = env_logger::builder() + .is_test(true) + .filter(Some("polkadot_availability_recovery"), log::LevelFilter::Trace) + .try_init(); + + let pool = sp_core::testing::TaskExecutor::new(); + + let (context, virtual_overseer) = make_subsystem_context(pool.clone()); + + let (collation_req_receiver, req_cfg) = + IncomingRequest::get_config_receiver(&ReqProtocolNames::new(&GENESIS_HASH, None)); + let subsystem = + AvailabilityRecoverySubsystem::with_fast_path(collation_req_receiver, Metrics::new_dummy()); + let subsystem = async { + subsystem.run(context).await.unwrap(); + }; + + let test_fut = test(virtual_overseer, req_cfg); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + executor::block_on(future::join( + async move { + let (mut overseer, _req_cfg) = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )) + .1 +} + +fn test_harness_chunks_only>( + test: impl FnOnce(VirtualOverseer, RequestResponseConfig) -> T, +) { + let _ = env_logger::builder() + .is_test(true) + .filter(Some("polkadot_availability_recovery"), log::LevelFilter::Trace) + .try_init(); + + let pool = sp_core::testing::TaskExecutor::new(); + + let (context, virtual_overseer) = make_subsystem_context(pool.clone()); + + let (collation_req_receiver, req_cfg) = + IncomingRequest::get_config_receiver(&ReqProtocolNames::new(&GENESIS_HASH, None)); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_only( + collation_req_receiver, + Metrics::new_dummy(), + ); + let subsystem = subsystem.run(context); + + let test_fut = test(virtual_overseer, req_cfg); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + executor::block_on(future::join( + async move { + let (mut overseer, _req_cfg) = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )) + .1 + .unwrap(); +} + +fn test_harness_chunks_if_pov_large< + T: Future, +>( + test: impl FnOnce(VirtualOverseer, RequestResponseConfig) -> T, +) { + let _ = env_logger::builder() + .is_test(true) + .filter(Some("polkadot_availability_recovery"), log::LevelFilter::Trace) + .try_init(); + + let pool = sp_core::testing::TaskExecutor::new(); + + let (context, virtual_overseer) = make_subsystem_context(pool.clone()); + + let (collation_req_receiver, req_cfg) = + IncomingRequest::get_config_receiver(&ReqProtocolNames::new(&GENESIS_HASH, None)); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_if_pov_large( + collation_req_receiver, + Metrics::new_dummy(), + ); + let subsystem = subsystem.run(context); + + let test_fut = test(virtual_overseer, req_cfg); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + executor::block_on(future::join( + async move { + let (mut overseer, _req_cfg) = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )) + .1 + .unwrap(); +} + +const TIMEOUT: Duration = Duration::from_millis(300); + +macro_rules! delay { + ($delay:expr) => { + Delay::new(Duration::from_millis($delay)).await; + }; +} + +async fn overseer_signal( + overseer: &mut TestSubsystemContextHandle, + signal: OverseerSignal, +) { + delay!(50); + overseer + .send(FromOrchestra::Signal(signal)) + .timeout(TIMEOUT) + .await + .unwrap_or_else(|| { + panic!("{}ms is more than enough for sending signals.", TIMEOUT.as_millis()) + }); +} + +async fn overseer_send( + overseer: &mut TestSubsystemContextHandle, + msg: AvailabilityRecoveryMessage, +) { + gum::trace!(msg = ?msg, "sending message"); + overseer + .send(FromOrchestra::Communication { msg }) + .timeout(TIMEOUT) + .await + .unwrap_or_else(|| { + panic!("{}ms is more than enough for sending messages.", TIMEOUT.as_millis()) + }); +} + +async fn overseer_recv( + overseer: &mut TestSubsystemContextHandle, +) -> AllMessages { + gum::trace!("waiting for message ..."); + let msg = overseer.recv().timeout(TIMEOUT).await.expect("TIMEOUT is enough to recv."); + gum::trace!(msg = ?msg, "received message"); + msg +} + +use sp_keyring::Sr25519Keyring; + +#[derive(Debug)] +enum Has { + No, + Yes, + NetworkError(sc_network::RequestFailure), + /// Make request not return at all, instead the sender is returned from the function. + /// + /// Note, if you use `DoesNotReturn` you have to keep the returned senders alive, otherwise the + /// subsystem will receive a cancel event and the request actually does return. + DoesNotReturn, +} + +impl Has { + fn timeout() -> Self { + Has::NetworkError(sc_network::RequestFailure::Network(sc_network::OutboundFailure::Timeout)) + } +} + +#[derive(Clone)] +struct TestState { + validators: Vec, + validator_public: IndexedVec, + validator_authority_id: Vec, + current: Hash, + candidate: CandidateReceipt, + session_index: SessionIndex, + + persisted_validation_data: PersistedValidationData, + + available_data: AvailableData, + chunks: Vec, + invalid_chunks: Vec, +} + +impl TestState { + fn threshold(&self) -> usize { + recovery_threshold(self.validators.len()).unwrap() + } + + fn impossibility_threshold(&self) -> usize { + self.validators.len() - self.threshold() + 1 + } + + async fn test_runtime_api(&self, virtual_overseer: &mut VirtualOverseer) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionInfo( + session_index, + tx, + ) + )) => { + assert_eq!(relay_parent, self.current); + assert_eq!(session_index, self.session_index); + + tx.send(Ok(Some(SessionInfo { + validators: self.validator_public.clone(), + discovery_keys: self.validator_authority_id.clone(), + // all validators in the same group. + validator_groups: IndexedVec::>::from(vec![(0..self.validators.len()).map(|i| ValidatorIndex(i as _)).collect()]), + assignment_keys: vec![], + n_cores: 0, + zeroth_delay_tranche_width: 0, + relay_vrf_modulo_samples: 0, + n_delay_tranches: 0, + no_show_slots: 0, + needed_approvals: 0, + active_validator_indices: vec![], + dispute_period: 6, + random_seed: [0u8; 32], + }))).unwrap(); + } + ); + } + + async fn respond_to_available_data_query( + &self, + virtual_overseer: &mut VirtualOverseer, + with_data: bool, + ) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::QueryAvailableData(_, tx) + ) => { + let _ = tx.send(if with_data { + Some(self.available_data.clone()) + } else { + gum::debug!("Sending None"); + None + }); + } + ) + } + + async fn respond_to_query_all_request( + &self, + virtual_overseer: &mut VirtualOverseer, + send_chunk: impl Fn(usize) -> bool, + ) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::QueryAllChunks(_, tx) + ) => { + let v = self.chunks.iter() + .filter(|c| send_chunk(c.index.0 as usize)) + .cloned() + .collect(); + + let _ = tx.send(v); + } + ) + } + + async fn respond_to_query_all_request_invalid( + &self, + virtual_overseer: &mut VirtualOverseer, + send_chunk: impl Fn(usize) -> bool, + ) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::QueryAllChunks(_, tx) + ) => { + let v = self.invalid_chunks.iter() + .filter(|c| send_chunk(c.index.0 as usize)) + .cloned() + .collect(); + + let _ = tx.send(v); + } + ) + } + + async fn test_chunk_requests( + &self, + candidate_hash: CandidateHash, + virtual_overseer: &mut VirtualOverseer, + n: usize, + who_has: impl Fn(usize) -> Has, + ) -> Vec, RequestFailure>>> { + // arbitrary order. + let mut i = 0; + let mut senders = Vec::new(); + while i < n { + // Receive a request for a chunk. + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + requests, + _if_disconnected, + ) + ) => { + for req in requests { + i += 1; + assert_matches!( + req, + Requests::ChunkFetchingV1(req) => { + assert_eq!(req.payload.candidate_hash, candidate_hash); + + let validator_index = req.payload.index.0 as usize; + let available_data = match who_has(validator_index) { + Has::No => Ok(None), + Has::Yes => Ok(Some(self.chunks[validator_index].clone().into())), + Has::NetworkError(e) => Err(e), + Has::DoesNotReturn => { + senders.push(req.pending_response); + continue + } + }; + + let _ = req.pending_response.send( + available_data.map(|r| + req_res::v1::ChunkFetchingResponse::from(r).encode() + ) + ); + } + ) + } + } + ); + } + senders + } + + async fn test_full_data_requests( + &self, + candidate_hash: CandidateHash, + virtual_overseer: &mut VirtualOverseer, + who_has: impl Fn(usize) -> Has, + ) -> Vec, sc_network::RequestFailure>>> { + let mut senders = Vec::new(); + for _ in 0..self.validators.len() { + // Receive a request for a chunk. + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut requests, + IfDisconnected::ImmediateError, + ) + ) => { + assert_eq!(requests.len(), 1); + + assert_matches!( + requests.pop().unwrap(), + Requests::AvailableDataFetchingV1(req) => { + assert_eq!(req.payload.candidate_hash, candidate_hash); + let validator_index = self.validator_authority_id + .iter() + .position(|a| Recipient::Authority(a.clone()) == req.peer) + .unwrap(); + + let available_data = match who_has(validator_index) { + Has::No => Ok(None), + Has::Yes => Ok(Some(self.available_data.clone())), + Has::NetworkError(e) => Err(e), + Has::DoesNotReturn => { + senders.push(req.pending_response); + continue + } + }; + + let done = available_data.as_ref().ok().map_or(false, |x| x.is_some()); + + let _ = req.pending_response.send( + available_data.map(|r| + req_res::v1::AvailableDataFetchingResponse::from(r).encode() + ) + ); + + if done { break } + } + ) + } + ); + } + senders + } +} + +fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> IndexedVec { + val_ids.iter().map(|v| v.public().into()).collect() +} + +fn validator_authority_id(val_ids: &[Sr25519Keyring]) -> Vec { + val_ids.iter().map(|v| v.public().into()).collect() +} + +fn derive_erasure_chunks_with_proofs_and_root( + n_validators: usize, + available_data: &AvailableData, + alter_chunk: impl Fn(usize, &mut Vec), +) -> (Vec, Hash) { + let mut chunks: Vec> = obtain_chunks(n_validators, available_data).unwrap(); + + for (i, chunk) in chunks.iter_mut().enumerate() { + alter_chunk(i, chunk) + } + + // create proofs for each erasure chunk + let branches = branches(chunks.as_ref()); + + let root = branches.root(); + let erasure_chunks = branches + .enumerate() + .map(|(index, (proof, chunk))| ErasureChunk { + chunk: chunk.to_vec(), + index: ValidatorIndex(index as _), + proof: Proof::try_from(proof).unwrap(), + }) + .collect::>(); + + (erasure_chunks, root) +} + +impl Default for TestState { + fn default() -> Self { + let validators = vec![ + Sr25519Keyring::Ferdie, // <- this node, role: validator + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + ]; + + let validator_public = validator_pubkeys(&validators); + let validator_authority_id = validator_authority_id(&validators); + + let current = Hash::repeat_byte(1); + + let mut candidate = dummy_candidate_receipt(dummy_hash()); + + let session_index = 10; + + let persisted_validation_data = PersistedValidationData { + parent_head: HeadData(vec![7, 8, 9]), + relay_parent_number: Default::default(), + max_pov_size: 1024, + relay_parent_storage_root: Default::default(), + }; + + let pov = PoV { block_data: BlockData(vec![42; 64]) }; + + let available_data = AvailableData { + validation_data: persisted_validation_data.clone(), + pov: Arc::new(pov), + }; + + let (chunks, erasure_root) = derive_erasure_chunks_with_proofs_and_root( + validators.len(), + &available_data, + |_, _| {}, + ); + // Mess around: + let invalid_chunks = chunks + .iter() + .cloned() + .map(|mut chunk| { + if chunk.chunk.len() >= 2 && chunk.chunk[0] != chunk.chunk[1] { + chunk.chunk[0] = chunk.chunk[1]; + } else if chunk.chunk.len() >= 1 { + chunk.chunk[0] = !chunk.chunk[0]; + } else { + chunk.proof = Proof::dummy_proof(); + } + chunk + }) + .collect(); + debug_assert_ne!(chunks, invalid_chunks); + + candidate.descriptor.erasure_root = erasure_root; + candidate.descriptor.relay_parent = Hash::repeat_byte(10); + + Self { + validators, + validator_public, + validator_authority_id, + current, + candidate, + session_index, + persisted_validation_data, + available_data, + chunks, + invalid_chunks, + } + } +} + +#[test] +fn availability_is_recovered_from_chunks_if_no_group_provided() { + let test_state = TestState::default(); + + test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + None, + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + let candidate_hash = test_state.candidate.hash(); + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold(), + |_| Has::Yes, + ) + .await; + + // Recovered data should match the original one. + assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); + + let (tx, rx) = oneshot::channel(); + + // Test another candidate, send no chunks. + let mut new_candidate = dummy_candidate_receipt(dummy_hash()); + + new_candidate.descriptor.relay_parent = test_state.candidate.descriptor.relay_parent; + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + new_candidate.clone(), + test_state.session_index, + None, + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + test_state + .test_chunk_requests( + new_candidate.hash(), + &mut virtual_overseer, + test_state.impossibility_threshold(), + |_| Has::No, + ) + .await; + + // A request times out with `Unavailable` error. + assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn availability_is_recovered_from_chunks_even_if_backing_group_supplied_if_chunks_only() { + let test_state = TestState::default(); + + test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + Some(GroupIndex(0)), + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + let candidate_hash = test_state.candidate.hash(); + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold(), + |_| Has::Yes, + ) + .await; + + // Recovered data should match the original one. + assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); + + let (tx, rx) = oneshot::channel(); + + // Test another candidate, send no chunks. + let mut new_candidate = dummy_candidate_receipt(dummy_hash()); + + new_candidate.descriptor.relay_parent = test_state.candidate.descriptor.relay_parent; + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + new_candidate.clone(), + test_state.session_index, + None, + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + test_state + .test_chunk_requests( + new_candidate.hash(), + &mut virtual_overseer, + test_state.impossibility_threshold(), + |_| Has::No, + ) + .await; + + // A request times out with `Unavailable` error. + assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn bad_merkle_path_leads_to_recovery_error() { + let mut test_state = TestState::default(); + + test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + None, + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + let candidate_hash = test_state.candidate.hash(); + + // Create some faulty chunks. + test_state.chunks[0].chunk = vec![0; 32]; + test_state.chunks[1].chunk = vec![1; 32]; + test_state.chunks[2].chunk = vec![2; 32]; + test_state.chunks[3].chunk = vec![3; 32]; + test_state.chunks[4].chunk = vec![4; 32]; + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.impossibility_threshold(), + |_| Has::Yes, + ) + .await; + + // A request times out with `Unavailable` error. + assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn wrong_chunk_index_leads_to_recovery_error() { + let mut test_state = TestState::default(); + + test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + None, + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + let candidate_hash = test_state.candidate.hash(); + + // These chunks should fail the index check as they don't have the correct index for + // validator. + test_state.chunks[1] = test_state.chunks[0].clone(); + test_state.chunks[2] = test_state.chunks[0].clone(); + test_state.chunks[3] = test_state.chunks[0].clone(); + test_state.chunks[4] = test_state.chunks[0].clone(); + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.impossibility_threshold(), + |_| Has::No, + ) + .await; + + // A request times out with `Unavailable` error as there are no good peers. + assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn invalid_erasure_coding_leads_to_invalid_error() { + let mut test_state = TestState::default(); + + test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + let pov = PoV { block_data: BlockData(vec![69; 64]) }; + + let (bad_chunks, bad_erasure_root) = derive_erasure_chunks_with_proofs_and_root( + test_state.chunks.len(), + &AvailableData { + validation_data: test_state.persisted_validation_data.clone(), + pov: Arc::new(pov), + }, + |i, chunk| *chunk = vec![i as u8; 32], + ); + + test_state.chunks = bad_chunks; + test_state.candidate.descriptor.erasure_root = bad_erasure_root; + + let candidate_hash = test_state.candidate.hash(); + + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + None, + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold(), + |_| Has::Yes, + ) + .await; + + // f+1 'valid' chunks can't produce correct data. + assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Invalid); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn fast_path_backing_group_recovers() { + let test_state = TestState::default(); + + test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + Some(GroupIndex(0)), + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + let candidate_hash = test_state.candidate.hash(); + + let who_has = |i| match i { + 3 => Has::Yes, + _ => Has::No, + }; + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + + test_state + .test_full_data_requests(candidate_hash, &mut virtual_overseer, who_has) + .await; + + // Recovered data should match the original one. + assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn recovers_from_only_chunks_if_pov_large() { + let test_state = TestState::default(); + + test_harness_chunks_if_pov_large(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + Some(GroupIndex(0)), + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + let candidate_hash = test_state.candidate.hash(); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::QueryChunkSize(_, tx) + ) => { + let _ = tx.send(Some(1000000)); + } + ); + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold(), + |_| Has::Yes, + ) + .await; + + // Recovered data should match the original one. + assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); + + let (tx, rx) = oneshot::channel(); + + // Test another candidate, send no chunks. + let mut new_candidate = dummy_candidate_receipt(dummy_hash()); + + new_candidate.descriptor.relay_parent = test_state.candidate.descriptor.relay_parent; + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + new_candidate.clone(), + test_state.session_index, + None, + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::QueryChunkSize(_, tx) + ) => { + let _ = tx.send(Some(1000000)); + } + ); + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + test_state + .test_chunk_requests( + new_candidate.hash(), + &mut virtual_overseer, + test_state.impossibility_threshold(), + |_| Has::No, + ) + .await; + + // A request times out with `Unavailable` error. + assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn fast_path_backing_group_recovers_if_pov_small() { + let test_state = TestState::default(); + + test_harness_chunks_if_pov_large(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + Some(GroupIndex(0)), + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + let candidate_hash = test_state.candidate.hash(); + + let who_has = |i| match i { + 3 => Has::Yes, + _ => Has::No, + }; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::QueryChunkSize(_, tx) + ) => { + let _ = tx.send(Some(100)); + } + ); + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + + test_state + .test_full_data_requests(candidate_hash, &mut virtual_overseer, who_has) + .await; + + // Recovered data should match the original one. + assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn no_answers_in_fast_path_causes_chunk_requests() { + let test_state = TestState::default(); + + test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + Some(GroupIndex(0)), + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + let candidate_hash = test_state.candidate.hash(); + + // mix of timeout and no. + let who_has = |i| match i { + 0 | 3 => Has::No, + _ => Has::timeout(), + }; + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + + test_state + .test_full_data_requests(candidate_hash, &mut virtual_overseer, who_has) + .await; + + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold(), + |_| Has::Yes, + ) + .await; + + // Recovered data should match the original one. + assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn task_canceled_when_receivers_dropped() { + let test_state = TestState::default(); + + test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, _) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + None, + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + for _ in 0..test_state.validators.len() { + match virtual_overseer.recv().timeout(TIMEOUT).await { + None => return (virtual_overseer, req_cfg), + Some(_) => continue, + } + } + + panic!("task requested all validators without concluding") + }); +} + +#[test] +fn chunks_retry_until_all_nodes_respond() { + let test_state = TestState::default(); + + test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + Some(GroupIndex(0)), + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + let candidate_hash = test_state.candidate.hash(); + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.validators.len() - test_state.threshold(), + |_| Has::timeout(), + ) + .await; + + // we get to go another round! + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.impossibility_threshold(), + |_| Has::No, + ) + .await; + + // Recovered data should match the original one. + assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn not_returning_requests_wont_stall_retrieval() { + let test_state = TestState::default(); + + test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + Some(GroupIndex(0)), + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + let candidate_hash = test_state.candidate.hash(); + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + // How many validators should not respond at all: + let not_returning_count = 1; + + // Not returning senders won't cause the retrieval to stall: + let _senders = test_state + .test_chunk_requests(candidate_hash, &mut virtual_overseer, not_returning_count, |_| { + Has::DoesNotReturn + }) + .await; + + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + // Should start over: + test_state.validators.len() + 3, + |_| Has::timeout(), + ) + .await; + + // we get to go another round! + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold(), + |_| Has::Yes, + ) + .await; + + // Recovered data should match the original one: + assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn all_not_returning_requests_still_recovers_on_return() { + let test_state = TestState::default(); + + test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + Some(GroupIndex(0)), + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + + let candidate_hash = test_state.candidate.hash(); + + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; + + let senders = test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.validators.len(), + |_| Has::DoesNotReturn, + ) + .await; + + future::join( + async { + Delay::new(Duration::from_millis(10)).await; + // Now retrieval should be able to recover. + std::mem::drop(senders); + }, + test_state.test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + // Should start over: + test_state.validators.len() + 3, + |_| Has::timeout(), + ), + ) + .await; + + // we get to go another round! + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold(), + |_| Has::Yes, + ) + .await; + + // Recovered data should match the original one: + assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn returns_early_if_we_have_the_data() { + let test_state = TestState::default(); + + test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + None, + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + test_state.respond_to_available_data_query(&mut virtual_overseer, true).await; + + assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn does_not_query_local_validator() { + let test_state = TestState::default(); + + test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + None, + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state.respond_to_query_all_request(&mut virtual_overseer, |i| i == 0).await; + + let candidate_hash = test_state.candidate.hash(); + + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.validators.len(), + |i| if i == 0 { panic!("requested from local validator") } else { Has::timeout() }, + ) + .await; + + // second round, make sure it uses the local chunk. + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold() - 1, + |i| if i == 0 { panic!("requested from local validator") } else { Has::Yes }, + ) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn invalid_local_chunk_is_ignored() { + let test_state = TestState::default(); + + test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + overseer_signal( + &mut virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.current, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + let (tx, rx) = oneshot::channel(); + + overseer_send( + &mut virtual_overseer, + AvailabilityRecoveryMessage::RecoverAvailableData( + test_state.candidate.clone(), + test_state.session_index, + None, + tx, + ), + ) + .await; + + test_state.test_runtime_api(&mut virtual_overseer).await; + test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; + test_state + .respond_to_query_all_request_invalid(&mut virtual_overseer, |i| i == 0) + .await; + + let candidate_hash = test_state.candidate.hash(); + + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold() - 1, + |i| if i == 0 { panic!("requested from local validator") } else { Has::Yes }, + ) + .await; + + assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); + (virtual_overseer, req_cfg) + }); +} + +#[test] +fn parallel_request_calculation_works_as_expected() { + let num_validators = 100; + let threshold = recovery_threshold(num_validators).unwrap(); + let (erasure_task_tx, _erasure_task_rx) = futures::channel::mpsc::channel(16); + + let mut phase = RequestChunksFromValidators::new(100, erasure_task_tx); + assert_eq!(phase.get_desired_request_count(threshold), threshold); + phase.error_count = 1; + phase.total_received_responses = 1; + // We saturate at threshold (34): + assert_eq!(phase.get_desired_request_count(threshold), threshold); + + let dummy_chunk = + ErasureChunk { chunk: Vec::new(), index: ValidatorIndex(0), proof: Proof::dummy_proof() }; + phase.insert_chunk(ValidatorIndex(0), dummy_chunk.clone()); + phase.total_received_responses = 2; + // With given error rate - still saturating: + assert_eq!(phase.get_desired_request_count(threshold), threshold); + for i in 1..9 { + phase.insert_chunk(ValidatorIndex(i), dummy_chunk.clone()); + } + phase.total_received_responses += 8; + // error rate: 1/10 + // remaining chunks needed: threshold (34) - 9 + // expected: 24 * (1+ 1/10) = (next greater integer) = 27 + assert_eq!(phase.get_desired_request_count(threshold), 27); + phase.insert_chunk(ValidatorIndex(9), dummy_chunk.clone()); + phase.error_count = 0; + // With error count zero - we should fetch exactly as needed: + assert_eq!(phase.get_desired_request_count(threshold), threshold - phase.chunk_count()); +} diff --git a/polkadot/node/network/bitfield-distribution/Cargo.toml b/polkadot/node/network/bitfield-distribution/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..9dd5d9bbf0443e01a1c724fddb6006ff421af3ea --- /dev/null +++ b/polkadot/node/network/bitfield-distribution/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "polkadot-availability-bitfield-distribution" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +always-assert = "0.1" +futures = "0.3.21" +futures-timer = "3.0.2" +gum = { package = "tracing-gum", path = "../../gum" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-subsystem = {path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-node-network-protocol = { path = "../../network/protocol" } +rand = "0.8" + +[dev-dependencies] +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +maplit = "1.0.2" +log = "0.4.17" +env_logger = "0.9.0" +assert_matches = "1.4.0" +rand_chacha = "0.3.1" diff --git a/polkadot/node/network/bitfield-distribution/src/lib.rs b/polkadot/node/network/bitfield-distribution/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..c85d874bc4db6edad95d15cdfcdd01820948b0bc --- /dev/null +++ b/polkadot/node/network/bitfield-distribution/src/lib.rs @@ -0,0 +1,965 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The bitfield distribution +//! +//! In case this node is a validator, gossips its own signed availability bitfield +//! for a particular relay parent. +//! Independently of that, gossips on received messages from peers to other interested peers. + +#![deny(unused_crate_dependencies)] + +use always_assert::never; +use futures::{channel::oneshot, FutureExt}; + +use polkadot_node_network_protocol::{ + self as net_protocol, + grid_topology::{ + GridNeighbors, RandomRouting, RequiredRouting, SessionBoundGridTopologyStorage, + }, + peer_set::{ProtocolVersion, ValidationVersion}, + v1 as protocol_v1, vstaging as protocol_vstaging, OurView, PeerId, + UnifiedReputationChange as Rep, Versioned, View, +}; +use polkadot_node_subsystem::{ + jaeger, messages::*, overseer, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, PerLeafSpan, + SpawnedSubsystem, SubsystemError, SubsystemResult, +}; +use polkadot_node_subsystem_util::{ + self as util, + reputation::{ReputationAggregator, REPUTATION_CHANGE_INTERVAL}, +}; + +use futures::select; +use polkadot_primitives::{Hash, SignedAvailabilityBitfield, SigningContext, ValidatorId}; +use rand::{CryptoRng, Rng, SeedableRng}; +use std::{ + collections::{HashMap, HashSet}, + time::Duration, +}; + +use self::metrics::Metrics; + +mod metrics; + +#[cfg(test)] +mod tests; + +const COST_SIGNATURE_INVALID: Rep = Rep::CostMajor("Bitfield signature invalid"); +const COST_VALIDATOR_INDEX_INVALID: Rep = Rep::CostMajor("Bitfield validator index invalid"); +const COST_MISSING_PEER_SESSION_KEY: Rep = Rep::CostMinor("Missing peer session key"); +const COST_NOT_IN_VIEW: Rep = Rep::CostMinor("Not interested in that parent hash"); +const COST_PEER_DUPLICATE_MESSAGE: Rep = + Rep::CostMinorRepeated("Peer sent the same message multiple times"); +const BENEFIT_VALID_MESSAGE_FIRST: Rep = + Rep::BenefitMinorFirst("Valid message with new information"); +const BENEFIT_VALID_MESSAGE: Rep = Rep::BenefitMinor("Valid message"); + +/// Checked signed availability bitfield that is distributed +/// to other peers. +#[derive(Debug, Clone, PartialEq, Eq)] +struct BitfieldGossipMessage { + /// The relay parent this message is relative to. + relay_parent: Hash, + /// The actual signed availability bitfield. + signed_availability: SignedAvailabilityBitfield, +} + +impl BitfieldGossipMessage { + fn into_validation_protocol( + self, + recipient_version: ProtocolVersion, + ) -> net_protocol::VersionedValidationProtocol { + self.into_network_message(recipient_version).into() + } + + fn into_network_message( + self, + recipient_version: ProtocolVersion, + ) -> net_protocol::BitfieldDistributionMessage { + match ValidationVersion::try_from(recipient_version).ok() { + Some(ValidationVersion::V1) => + Versioned::V1(protocol_v1::BitfieldDistributionMessage::Bitfield( + self.relay_parent, + self.signed_availability.into(), + )), + Some(ValidationVersion::VStaging) => + Versioned::VStaging(protocol_vstaging::BitfieldDistributionMessage::Bitfield( + self.relay_parent, + self.signed_availability.into(), + )), + None => { + never!("Peers should only have supported protocol versions."); + + gum::warn!( + target: LOG_TARGET, + version = ?recipient_version, + "Unknown protocol version provided for message recipient" + ); + + // fall back to v1 to avoid + Versioned::V1(protocol_v1::BitfieldDistributionMessage::Bitfield( + self.relay_parent, + self.signed_availability.into(), + )) + }, + } + } +} + +/// Data stored on a per-peer basis. +#[derive(Debug)] +pub struct PeerData { + /// The peer's view. + view: View, + /// The peer's protocol version. + version: ProtocolVersion, +} + +/// Data used to track information of peers and relay parents the +/// overseer ordered us to work on. +#[derive(Default, Debug)] +struct ProtocolState { + /// Track all active peers and their views + /// to determine what is relevant to them. + peer_data: HashMap, + + /// The current and previous gossip topologies + topologies: SessionBoundGridTopologyStorage, + + /// Our current view. + view: OurView, + + /// Additional data particular to a relay parent. + per_relay_parent: HashMap, + + /// Aggregated reputation change + reputation: ReputationAggregator, +} + +/// Data for a particular relay parent. +#[derive(Debug)] +struct PerRelayParentData { + /// Signing context for a particular relay parent. + signing_context: SigningContext, + + /// Set of validators for a particular relay parent. + validator_set: Vec, + + /// Set of validators for a particular relay parent for which we + /// received a valid `BitfieldGossipMessage`. + /// Also serves as the list of known messages for peers connecting + /// after bitfield gossips were already received. + one_per_validator: HashMap, + + /// Avoid duplicate message transmission to our peers. + message_sent_to_peer: HashMap>, + + /// Track messages that were already received by a peer + /// to prevent flooding. + message_received_from_peer: HashMap>, + + /// The span for this leaf/relay parent. + span: PerLeafSpan, +} + +impl PerRelayParentData { + /// Create a new instance. + fn new( + signing_context: SigningContext, + validator_set: Vec, + span: PerLeafSpan, + ) -> Self { + Self { + signing_context, + validator_set, + span, + one_per_validator: Default::default(), + message_sent_to_peer: Default::default(), + message_received_from_peer: Default::default(), + } + } + + /// Determines if that particular message signed by a + /// validator is needed by the given peer. + fn message_from_validator_needed_by_peer( + &self, + peer: &PeerId, + signed_by: &ValidatorId, + ) -> bool { + self.message_sent_to_peer + .get(peer) + .map(|pubkeys| !pubkeys.contains(signed_by)) + .unwrap_or(true) && + self.message_received_from_peer + .get(peer) + .map(|pubkeys| !pubkeys.contains(signed_by)) + .unwrap_or(true) + } +} + +const LOG_TARGET: &str = "parachain::bitfield-distribution"; + +/// The bitfield distribution subsystem. +pub struct BitfieldDistribution { + metrics: Metrics, +} + +#[overseer::contextbounds(BitfieldDistribution, prefix = self::overseer)] +impl BitfieldDistribution { + /// Create a new instance of the `BitfieldDistribution` subsystem. + pub fn new(metrics: Metrics) -> Self { + Self { metrics } + } + + /// Start processing work as passed on from the Overseer. + async fn run(self, ctx: Context) { + let mut state = ProtocolState::default(); + let mut rng = rand::rngs::StdRng::from_entropy(); + self.run_inner(ctx, &mut state, REPUTATION_CHANGE_INTERVAL, &mut rng).await + } + + async fn run_inner( + self, + mut ctx: Context, + state: &mut ProtocolState, + reputation_interval: Duration, + rng: &mut (impl CryptoRng + Rng), + ) { + // work: process incoming messages from the overseer and process accordingly. + + let new_reputation_delay = || futures_timer::Delay::new(reputation_interval).fuse(); + let mut reputation_delay = new_reputation_delay(); + + loop { + select! { + _ = reputation_delay => { + state.reputation.send(ctx.sender()).await; + reputation_delay = new_reputation_delay(); + }, + message = ctx.recv().fuse() => { + let message = match message { + Ok(message) => message, + Err(err) => { + gum::error!( + target: LOG_TARGET, + ?err, + "Failed to receive a message from Overseer, exiting" + ); + return + }, + }; + match message { + FromOrchestra::Communication { + msg: + BitfieldDistributionMessage::DistributeBitfield( + relay_parent, + signed_availability, + ), + } => { + gum::trace!(target: LOG_TARGET, ?relay_parent, "Processing DistributeBitfield"); + handle_bitfield_distribution( + &mut ctx, + state, + &self.metrics, + relay_parent, + signed_availability, + rng, + ) + .await; + }, + FromOrchestra::Communication { + msg: BitfieldDistributionMessage::NetworkBridgeUpdate(event), + } => { + gum::trace!(target: LOG_TARGET, "Processing NetworkMessage"); + // a network message was received + handle_network_msg(&mut ctx, state, &self.metrics, event, rng).await; + }, + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated, + .. + })) => { + let _timer = self.metrics.time_active_leaves_update(); + + if let Some(activated) = activated { + let relay_parent = activated.hash; + + gum::trace!(target: LOG_TARGET, ?relay_parent, "activated"); + let span = PerLeafSpan::new(activated.span, "bitfield-distribution"); + let _span = span.child("query-basics"); + + // query validator set and signing context per relay_parent once only + match query_basics(&mut ctx, relay_parent).await { + Ok(Some((validator_set, signing_context))) => { + // If our runtime API fails, we don't take down the node, + // but we might alter peers' reputations erroneously as a result + // of not having the correct bookkeeping. If we have lost a race + // with state pruning, it is unlikely that peers will be sending + // us anything to do with this relay-parent anyway. + let _ = state.per_relay_parent.insert( + relay_parent, + PerRelayParentData::new(signing_context, validator_set, span), + ); + }, + Err(err) => { + gum::warn!(target: LOG_TARGET, ?err, "query_basics has failed"); + }, + _ => {}, + } + } + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(hash, number)) => { + gum::trace!(target: LOG_TARGET, ?hash, %number, "block finalized"); + }, + FromOrchestra::Signal(OverseerSignal::Conclude) => { + gum::info!(target: LOG_TARGET, "Conclude"); + return + }, + } + } + } + } + } +} + +/// Modify the reputation of a peer based on its behavior. +async fn modify_reputation( + reputation: &mut ReputationAggregator, + sender: &mut impl overseer::BitfieldDistributionSenderTrait, + relay_parent: Hash, + peer: PeerId, + rep: Rep, +) { + gum::trace!(target: LOG_TARGET, ?relay_parent, ?rep, %peer, "reputation change"); + + reputation.modify(sender, peer, rep).await; +} +/// Distribute a given valid and signature checked bitfield message. +/// +/// For this variant the source is this node. +#[overseer::contextbounds(BitfieldDistribution, prefix=self::overseer)] +async fn handle_bitfield_distribution( + ctx: &mut Context, + state: &mut ProtocolState, + metrics: &Metrics, + relay_parent: Hash, + signed_availability: SignedAvailabilityBitfield, + rng: &mut (impl CryptoRng + Rng), +) { + let _timer = metrics.time_handle_bitfield_distribution(); + + // Ignore anything the overseer did not tell this subsystem to work on + let mut job_data = state.per_relay_parent.get_mut(&relay_parent); + let job_data: &mut _ = if let Some(ref mut job_data) = job_data { + job_data + } else { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + "Not supposed to work on relay parent related data", + ); + + return + }; + + let session_idx = job_data.signing_context.session_index; + let validator_set = &job_data.validator_set; + if validator_set.is_empty() { + gum::debug!(target: LOG_TARGET, ?relay_parent, "validator set is empty"); + return + } + + let validator_index = signed_availability.validator_index(); + let validator = if let Some(validator) = validator_set.get(validator_index.0 as usize) { + validator.clone() + } else { + gum::debug!(target: LOG_TARGET, validator_index = ?validator_index.0, "Could not find a validator for index"); + return + }; + + let msg = BitfieldGossipMessage { relay_parent, signed_availability }; + let topology = state.topologies.get_topology_or_fallback(session_idx).local_grid_neighbors(); + let required_routing = topology.required_routing_by_index(validator_index, true); + + relay_message( + ctx, + job_data, + topology, + &mut state.peer_data, + validator, + msg, + required_routing, + rng, + ) + .await; + + metrics.on_own_bitfield_sent(); +} + +/// Distribute a given valid and signature checked bitfield message. +/// +/// Can be originated by another subsystem or received via network from another peer. +#[overseer::contextbounds(BitfieldDistribution, prefix=self::overseer)] +async fn relay_message( + ctx: &mut Context, + job_data: &mut PerRelayParentData, + topology_neighbors: &GridNeighbors, + peers: &mut HashMap, + validator: ValidatorId, + message: BitfieldGossipMessage, + required_routing: RequiredRouting, + rng: &mut (impl CryptoRng + Rng), +) { + let relay_parent = message.relay_parent; + let span = job_data.span.child("relay-msg"); + + let _span = span.child("provisionable"); + // notify the overseer about a new and valid signed bitfield + ctx.send_message(ProvisionerMessage::ProvisionableData( + relay_parent, + ProvisionableData::Bitfield(relay_parent, message.signed_availability.clone()), + )) + .await; + + drop(_span); + let total_peers = peers.len(); + let mut random_routing: RandomRouting = Default::default(); + + let _span = span.child("interested-peers"); + // pass on the bitfield distribution to all interested peers + let interested_peers = peers + .iter() + .filter_map(|(peer, data)| { + // check interest in the peer in this message's relay parent + if data.view.contains(&message.relay_parent) { + let message_needed = + job_data.message_from_validator_needed_by_peer(&peer, &validator); + if message_needed { + let in_topology = topology_neighbors.route_to_peer(required_routing, &peer); + let need_routing = in_topology || { + let route_random = random_routing.sample(total_peers, rng); + if route_random { + random_routing.inc_sent(); + } + + route_random + }; + + if need_routing { + Some((*peer, data.version)) + } else { + None + } + } else { + None + } + } else { + None + } + }) + .collect::>(); + + interested_peers.iter().for_each(|(peer, _)| { + // track the message as sent for this peer + job_data + .message_sent_to_peer + .entry(*peer) + .or_default() + .insert(validator.clone()); + }); + + drop(_span); + + if interested_peers.is_empty() { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + "no peers are interested in gossip for relay parent", + ); + } else { + let _span = span.child("gossip"); + + let filter_by_version = |peers: &[(PeerId, ProtocolVersion)], + version: ValidationVersion| { + peers + .iter() + .filter(|(_, v)| v == &version.into()) + .map(|(peer_id, _)| *peer_id) + .collect::>() + }; + + let v1_interested_peers = filter_by_version(&interested_peers, ValidationVersion::V1); + let vstaging_interested_peers = + filter_by_version(&interested_peers, ValidationVersion::VStaging); + + if !v1_interested_peers.is_empty() { + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + v1_interested_peers, + message.clone().into_validation_protocol(ValidationVersion::V1.into()), + )) + .await; + } + + if !vstaging_interested_peers.is_empty() { + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + vstaging_interested_peers, + message.into_validation_protocol(ValidationVersion::VStaging.into()), + )) + .await + } + } +} + +/// Handle an incoming message from a peer. +#[overseer::contextbounds(BitfieldDistribution, prefix=self::overseer)] +async fn process_incoming_peer_message( + ctx: &mut Context, + state: &mut ProtocolState, + metrics: &Metrics, + origin: PeerId, + message: net_protocol::BitfieldDistributionMessage, + rng: &mut (impl CryptoRng + Rng), +) { + let (relay_parent, bitfield) = match message { + Versioned::V1(protocol_v1::BitfieldDistributionMessage::Bitfield( + relay_parent, + bitfield, + )) => (relay_parent, bitfield), + Versioned::VStaging(protocol_vstaging::BitfieldDistributionMessage::Bitfield( + relay_parent, + bitfield, + )) => (relay_parent, bitfield), + }; + + gum::trace!( + target: LOG_TARGET, + peer = %origin, + ?relay_parent, + "received bitfield gossip from peer" + ); + // we don't care about this, not part of our view. + if !state.view.contains(&relay_parent) { + modify_reputation( + &mut state.reputation, + ctx.sender(), + relay_parent, + origin, + COST_NOT_IN_VIEW, + ) + .await; + return + } + + // Ignore anything the overseer did not tell this subsystem to work on. + let mut job_data = state.per_relay_parent.get_mut(&relay_parent); + let job_data: &mut _ = if let Some(ref mut job_data) = job_data { + job_data + } else { + modify_reputation( + &mut state.reputation, + ctx.sender(), + relay_parent, + origin, + COST_NOT_IN_VIEW, + ) + .await; + return + }; + + let validator_index = bitfield.unchecked_validator_index(); + + let mut _span = job_data + .span + .child("msg-received") + .with_peer_id(&origin) + .with_relay_parent(relay_parent) + .with_claimed_validator_index(validator_index) + .with_stage(jaeger::Stage::BitfieldDistribution); + + let validator_set = &job_data.validator_set; + if validator_set.is_empty() { + gum::trace!(target: LOG_TARGET, ?relay_parent, ?origin, "Validator set is empty",); + modify_reputation( + &mut state.reputation, + ctx.sender(), + relay_parent, + origin, + COST_MISSING_PEER_SESSION_KEY, + ) + .await; + return + } + + // Use the (untrusted) validator index provided by the signed payload + // and see if that one actually signed the availability bitset. + let signing_context = job_data.signing_context.clone(); + let validator = if let Some(validator) = validator_set.get(validator_index.0 as usize) { + validator.clone() + } else { + modify_reputation( + &mut state.reputation, + ctx.sender(), + relay_parent, + origin, + COST_VALIDATOR_INDEX_INVALID, + ) + .await; + return + }; + + // Check if the peer already sent us a message for the validator denoted in the message earlier. + // Must be done after validator index verification, in order to avoid storing an unbounded + // number of set entries. + let received_set = job_data.message_received_from_peer.entry(origin).or_default(); + + if !received_set.contains(&validator) { + received_set.insert(validator.clone()); + } else { + gum::trace!(target: LOG_TARGET, ?validator_index, ?origin, "Duplicate message"); + modify_reputation( + &mut state.reputation, + ctx.sender(), + relay_parent, + origin, + COST_PEER_DUPLICATE_MESSAGE, + ) + .await; + return + }; + + let one_per_validator = &mut (job_data.one_per_validator); + + // relay a message received from a validator at most _once_ + if let Some(old_message) = one_per_validator.get(&validator) { + gum::trace!( + target: LOG_TARGET, + ?validator_index, + "already received a message for validator", + ); + if old_message.signed_availability.as_unchecked() == &bitfield { + modify_reputation( + &mut state.reputation, + ctx.sender(), + relay_parent, + origin, + BENEFIT_VALID_MESSAGE, + ) + .await; + } + return + } + let signed_availability = match bitfield.try_into_checked(&signing_context, &validator) { + Err(_) => { + modify_reputation( + &mut state.reputation, + ctx.sender(), + relay_parent, + origin, + COST_SIGNATURE_INVALID, + ) + .await; + return + }, + Ok(bitfield) => bitfield, + }; + + let message = BitfieldGossipMessage { relay_parent, signed_availability }; + + let topology = state + .topologies + .get_topology_or_fallback(job_data.signing_context.session_index) + .local_grid_neighbors(); + let required_routing = topology.required_routing_by_index(validator_index, false); + + metrics.on_bitfield_received(); + one_per_validator.insert(validator.clone(), message.clone()); + + relay_message( + ctx, + job_data, + topology, + &mut state.peer_data, + validator, + message, + required_routing, + rng, + ) + .await; + + modify_reputation( + &mut state.reputation, + ctx.sender(), + relay_parent, + origin, + BENEFIT_VALID_MESSAGE_FIRST, + ) + .await +} + +/// Deal with network bridge updates and track what needs to be tracked +/// which depends on the message type received. +#[overseer::contextbounds(BitfieldDistribution, prefix=self::overseer)] +async fn handle_network_msg( + ctx: &mut Context, + state: &mut ProtocolState, + metrics: &Metrics, + bridge_message: NetworkBridgeEvent, + rng: &mut (impl CryptoRng + Rng), +) { + let _timer = metrics.time_handle_network_msg(); + + match bridge_message { + NetworkBridgeEvent::PeerConnected(peer, role, version, _) => { + gum::trace!(target: LOG_TARGET, ?peer, ?role, "Peer connected"); + // insert if none already present + state + .peer_data + .entry(peer) + .or_insert_with(|| PeerData { view: View::default(), version }); + }, + NetworkBridgeEvent::PeerDisconnected(peer) => { + gum::trace!(target: LOG_TARGET, ?peer, "Peer disconnected"); + // get rid of superfluous data + state.peer_data.remove(&peer); + }, + NetworkBridgeEvent::NewGossipTopology(gossip_topology) => { + let session_index = gossip_topology.session; + let new_topology = gossip_topology.topology; + let prev_neighbors = + state.topologies.get_current_topology().local_grid_neighbors().clone(); + + state.topologies.update_topology( + session_index, + new_topology, + gossip_topology.local_index, + ); + let current_topology = state.topologies.get_current_topology(); + + let newly_added = current_topology.local_grid_neighbors().peers_diff(&prev_neighbors); + + gum::debug!( + target: LOG_TARGET, + ?session_index, + newly_added_peers = ?newly_added.len(), + "New gossip topology received", + ); + + for new_peer in newly_added { + let old_view = match state.peer_data.get_mut(&new_peer) { + Some(d) => { + // in case we already knew that peer in the past + // it might have had an existing view, we use to initialize + // and minimize the delta on `PeerViewChange` to be sent + std::mem::replace(&mut d.view, Default::default()) + }, + None => { + // For peers which are currently unknown, we'll send topology-related + // messages to them when they connect and send their first view update. + continue + }, + }; + + handle_peer_view_change(ctx, state, new_peer, old_view, rng).await; + } + }, + NetworkBridgeEvent::PeerViewChange(peerid, new_view) => { + gum::trace!(target: LOG_TARGET, ?peerid, ?new_view, "Peer view change"); + handle_peer_view_change(ctx, state, peerid, new_view, rng).await; + }, + NetworkBridgeEvent::OurViewChange(new_view) => { + gum::trace!(target: LOG_TARGET, ?new_view, "Our view change"); + handle_our_view_change(state, new_view); + }, + NetworkBridgeEvent::PeerMessage(remote, message) => + process_incoming_peer_message(ctx, state, metrics, remote, message, rng).await, + NetworkBridgeEvent::UpdatedAuthorityIds { .. } => { + // The bitfield-distribution subsystem doesn't deal with `AuthorityDiscoveryId`s. + }, + } +} + +/// Handle the changes necessary when our view changes. +fn handle_our_view_change(state: &mut ProtocolState, view: OurView) { + let old_view = std::mem::replace(&mut (state.view), view); + + for added in state.view.difference(&old_view) { + if !state.per_relay_parent.contains_key(&added) { + // Is guaranteed to be handled in `ActiveHead` update + // so this should never happen. + gum::error!( + target: LOG_TARGET, + %added, + "Our view contains {}, but not in active heads", + &added + ); + } + } + for removed in old_view.difference(&state.view) { + // cleanup relay parents we are not interested in any more + let _ = state.per_relay_parent.remove(&removed); + } +} + +// Send the difference between two views which were not sent +// to that particular peer. +// +// This requires that there is an entry in the `peer_data` field for the +// peer. +#[overseer::contextbounds(BitfieldDistribution, prefix=self::overseer)] +async fn handle_peer_view_change( + ctx: &mut Context, + state: &mut ProtocolState, + origin: PeerId, + view: View, + rng: &mut (impl CryptoRng + Rng), +) { + let peer_data = match state.peer_data.get_mut(&origin) { + None => { + gum::warn!( + target: LOG_TARGET, + peer = ?origin, + "Attempted to update peer view for unknown peer." + ); + + return + }, + Some(pd) => pd, + }; + + let added = peer_data.view.replace_difference(view).cloned().collect::>(); + + let topology = state.topologies.get_current_topology().local_grid_neighbors(); + let is_gossip_peer = topology.route_to_peer(RequiredRouting::GridXY, &origin); + let lucky = is_gossip_peer || + util::gen_ratio_rng( + util::MIN_GOSSIP_PEERS.saturating_sub(topology.len()), + util::MIN_GOSSIP_PEERS, + rng, + ); + + if !lucky { + gum::trace!(target: LOG_TARGET, ?origin, "Peer view change is ignored"); + return + } + + // Send all messages we've seen before and the peer is now interested + // in to that peer. + let delta_set: Vec<(ValidatorId, BitfieldGossipMessage)> = added + .into_iter() + .filter_map(|new_relay_parent_interest| { + if let Some(job_data) = state.per_relay_parent.get(&new_relay_parent_interest) { + // Send all jointly known messages for a validator (given the current relay parent) + // to the peer `origin`... + let one_per_validator = job_data.one_per_validator.clone(); + Some(one_per_validator.into_iter().filter(move |(validator, _message)| { + // ..except for the ones the peer already has. + job_data.message_from_validator_needed_by_peer(&origin, validator) + })) + } else { + // A relay parent is in the peers view, which is not in ours, ignore those. + None + } + }) + .flatten() + .collect(); + + for (validator, message) in delta_set.into_iter() { + send_tracked_gossip_message(ctx, state, origin, validator, message).await; + } +} + +/// Send a gossip message and track it in the per relay parent data. +#[overseer::contextbounds(BitfieldDistribution, prefix=self::overseer)] +async fn send_tracked_gossip_message( + ctx: &mut Context, + state: &mut ProtocolState, + dest: PeerId, + validator: ValidatorId, + message: BitfieldGossipMessage, +) { + let job_data = if let Some(job_data) = state.per_relay_parent.get_mut(&message.relay_parent) { + job_data + } else { + return + }; + + let _span = job_data.span.child("gossip"); + gum::trace!( + target: LOG_TARGET, + ?dest, + ?validator, + relay_parent = ?message.relay_parent, + "Sending gossip message" + ); + + let version = + if let Some(peer_data) = state.peer_data.get(&dest) { peer_data.version } else { return }; + + job_data.message_sent_to_peer.entry(dest).or_default().insert(validator.clone()); + + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + vec![dest], + message.into_validation_protocol(version), + )) + .await; +} + +#[overseer::subsystem(BitfieldDistribution, error=SubsystemError, prefix=self::overseer)] +impl BitfieldDistribution { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = self.run(ctx).map(|_| Ok(())).boxed(); + + SpawnedSubsystem { name: "bitfield-distribution-subsystem", future } + } +} + +/// Query our validator set and signing context for a particular relay parent. +#[overseer::contextbounds(BitfieldDistribution, prefix=self::overseer)] +async fn query_basics( + ctx: &mut Context, + relay_parent: Hash, +) -> SubsystemResult, SigningContext)>> { + let (validators_tx, validators_rx) = oneshot::channel(); + let (session_tx, session_rx) = oneshot::channel(); + + // query validators + ctx.send_message(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Validators(validators_tx), + )) + .await; + + // query signing context + ctx.send_message(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionIndexForChild(session_tx), + )) + .await; + + match (validators_rx.await?, session_rx.await?) { + (Ok(validators), Ok(session_index)) => + Ok(Some((validators, SigningContext { parent_hash: relay_parent, session_index }))), + (Err(err), _) | (_, Err(err)) => { + gum::warn!( + target: LOG_TARGET, + ?relay_parent, + ?err, + "Failed to fetch basics from runtime API" + ); + Ok(None) + }, + } +} diff --git a/polkadot/node/network/bitfield-distribution/src/metrics.rs b/polkadot/node/network/bitfield-distribution/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..71d8a01300f25aea09099b882a00ff5df9cba491 --- /dev/null +++ b/polkadot/node/network/bitfield-distribution/src/metrics.rs @@ -0,0 +1,108 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{prometheus, Metrics as MetricsTrait}; + +#[derive(Clone)] +struct MetricsInner { + sent_own_availability_bitfields: prometheus::Counter, + received_availability_bitfields: prometheus::Counter, + active_leaves_update: prometheus::Histogram, + handle_bitfield_distribution: prometheus::Histogram, + handle_network_msg: prometheus::Histogram, +} + +/// Bitfield Distribution metrics. +#[derive(Default, Clone)] +pub struct Metrics(Option); + +impl Metrics { + pub(crate) fn on_own_bitfield_sent(&self) { + if let Some(metrics) = &self.0 { + metrics.sent_own_availability_bitfields.inc(); + } + } + + pub(crate) fn on_bitfield_received(&self) { + if let Some(metrics) = &self.0 { + metrics.received_availability_bitfields.inc(); + } + } + + /// Provide a timer for `active_leaves_update` which observes on drop. + pub(crate) fn time_active_leaves_update( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.active_leaves_update.start_timer()) + } + + /// Provide a timer for `handle_bitfield_distribution` which observes on drop. + pub(crate) fn time_handle_bitfield_distribution( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.handle_bitfield_distribution.start_timer()) + } + + /// Provide a timer for `handle_network_msg` which observes on drop. + pub(crate) fn time_handle_network_msg(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.handle_network_msg.start_timer()) + } +} + +impl MetricsTrait for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + sent_own_availability_bitfields: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_sent_own_availabilty_bitfields_total", + "Number of own availability bitfields sent to other peers.", + )?, + registry, + )?, + received_availability_bitfields: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_received_availabilty_bitfields_total", + "Number of valid availability bitfields received from other peers.", + )?, + registry, + )?, + active_leaves_update: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_bitfield_distribution_active_leaves_update", + "Time spent within `bitfield_distribution::active_leaves_update`", + ))?, + registry, + )?, + handle_bitfield_distribution: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_bitfield_distribution_handle_bitfield_distribution", + "Time spent within `bitfield_distribution::handle_bitfield_distribution`", + ))?, + registry, + )?, + handle_network_msg: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_bitfield_distribution_handle_network_msg", + "Time spent within `bitfield_distribution::handle_network_msg`", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/network/bitfield-distribution/src/tests.rs b/polkadot/node/network/bitfield-distribution/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..d6795247e7866f4bb160d941161f114316c3633d --- /dev/null +++ b/polkadot/node/network/bitfield-distribution/src/tests.rs @@ -0,0 +1,1226 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use assert_matches::assert_matches; +use bitvec::bitvec; +use futures::executor; +use maplit::hashmap; +use polkadot_node_network_protocol::{ + grid_topology::{SessionBoundGridTopologyStorage, SessionGridTopology, TopologyPeerInfo}, + our_view, + peer_set::ValidationVersion, + view, ObservedRole, +}; +use polkadot_node_subsystem::{ + jaeger, + jaeger::{PerLeafSpan, Span}, + messages::ReportPeerMessage, +}; +use polkadot_node_subsystem_test_helpers::make_subsystem_context; +use polkadot_node_subsystem_util::TimeoutExt; +use polkadot_primitives::{AvailabilityBitfield, Signed, ValidatorIndex}; +use rand_chacha::ChaCha12Rng; +use sp_application_crypto::AppCrypto; +use sp_authority_discovery::AuthorityPair as AuthorityDiscoveryPair; +use sp_core::Pair as PairT; +use sp_keyring::Sr25519Keyring; +use sp_keystore::{testing::MemoryKeystore, Keystore, KeystorePtr}; + +use std::{iter::FromIterator as _, sync::Arc, time::Duration}; + +const TIMEOUT: Duration = Duration::from_millis(50); +macro_rules! launch { + ($fut:expr) => { + $fut.timeout(TIMEOUT).await.unwrap_or_else(|| { + panic!("{}ms is more than enough for sending messages.", TIMEOUT.as_millis()) + }); + }; +} + +/// Pre-seeded `crypto` random numbers generator for testing purposes +fn dummy_rng() -> ChaCha12Rng { + rand_chacha::ChaCha12Rng::seed_from_u64(12345) +} + +fn peer_data_v1(view: View) -> PeerData { + PeerData { view, version: ValidationVersion::V1.into() } +} + +/// A very limited state, only interested in the relay parent of the +/// given message, which must be signed by `validator` and a set of peers +/// which are also only interested in that relay parent. +fn prewarmed_state( + validator: ValidatorId, + signing_context: SigningContext, + known_message: BitfieldGossipMessage, + peers: Vec, +) -> ProtocolState { + let relay_parent = known_message.relay_parent; + let mut topologies = SessionBoundGridTopologyStorage::default(); + topologies.update_topology(0_u32, SessionGridTopology::new(Vec::new(), Vec::new()), None); + topologies.get_current_topology_mut().local_grid_neighbors_mut().peers_x = + peers.iter().cloned().collect(); + + ProtocolState { + per_relay_parent: hashmap! { + relay_parent => + PerRelayParentData { + signing_context, + validator_set: vec![validator.clone()], + one_per_validator: hashmap! { + validator.clone() => known_message.clone(), + }, + message_received_from_peer: hashmap!{}, + message_sent_to_peer: hashmap!{}, + span: PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"), + }, + }, + peer_data: peers + .iter() + .cloned() + .map(|peer| (peer, peer_data_v1(view![relay_parent]))) + .collect(), + topologies, + view: our_view!(relay_parent), + reputation: ReputationAggregator::new(|_| true), + } +} + +fn state_with_view( + view: OurView, + relay_parent: Hash, + reputation: ReputationAggregator, +) -> (ProtocolState, SigningContext, KeystorePtr, ValidatorId) { + let mut state = ProtocolState { reputation, ..Default::default() }; + + let signing_context = SigningContext { session_index: 1, parent_hash: relay_parent }; + + let keystore: KeystorePtr = Arc::new(MemoryKeystore::new()); + let validator = Keystore::sr25519_generate_new(&*keystore, ValidatorId::ID, None) + .expect("generating sr25519 key not to fail"); + + state.per_relay_parent = view + .iter() + .map(|relay_parent| { + ( + *relay_parent, + PerRelayParentData { + signing_context: signing_context.clone(), + validator_set: vec![validator.into()], + one_per_validator: hashmap! {}, + message_received_from_peer: hashmap! {}, + message_sent_to_peer: hashmap! {}, + span: PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"), + }, + ) + }) + .collect(); + + state.view = view; + + (state, signing_context, keystore, validator.into()) +} + +#[test] +fn receive_invalid_signature() { + let _ = env_logger::builder() + .filter(None, log::LevelFilter::Trace) + .is_test(true) + .try_init(); + + let hash_a: Hash = [0; 32].into(); + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + assert_ne!(peer_a, peer_b); + + let signing_context = SigningContext { session_index: 1, parent_hash: hash_a }; + + // another validator not part of the validatorset + let keystore: KeystorePtr = Arc::new(MemoryKeystore::new()); + let malicious = Keystore::sr25519_generate_new(&*keystore, ValidatorId::ID, None) + .expect("Malicious key created"); + let validator_0 = + Keystore::sr25519_generate_new(&*keystore, ValidatorId::ID, None).expect("key created"); + let validator_1 = + Keystore::sr25519_generate_new(&*keystore, ValidatorId::ID, None).expect("key created"); + + let payload = AvailabilityBitfield(bitvec![u8, bitvec::order::Lsb0; 1u8; 32]); + let invalid_signed = Signed::::sign( + &keystore, + payload.clone(), + &signing_context, + ValidatorIndex(0), + &malicious.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + let invalid_signed_2 = Signed::::sign( + &keystore, + payload.clone(), + &signing_context, + ValidatorIndex(1), + &malicious.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let valid_signed = Signed::::sign( + &keystore, + payload, + &signing_context, + ValidatorIndex(0), + &validator_0.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let invalid_msg = + BitfieldGossipMessage { relay_parent: hash_a, signed_availability: invalid_signed.clone() }; + let invalid_msg_2 = BitfieldGossipMessage { + relay_parent: hash_a, + signed_availability: invalid_signed_2.clone(), + }; + let valid_msg = + BitfieldGossipMessage { relay_parent: hash_a, signed_availability: valid_signed.clone() }; + + let pool = sp_core::testing::TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::(pool); + + let mut state = + prewarmed_state(validator_0.into(), signing_context.clone(), valid_msg, vec![peer_b]); + state + .per_relay_parent + .get_mut(&hash_a) + .unwrap() + .validator_set + .push(validator_1.into()); + let mut rng = dummy_rng(); + + executor::block_on(async move { + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peer_b, + invalid_msg.into_network_message(ValidationVersion::V1.into()) + ), + &mut rng, + )); + + // reputation doesn't change due to one_job_per_validator check + assert!(handle.recv().timeout(TIMEOUT).await.is_none()); + + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peer_b, + invalid_msg_2.into_network_message(ValidationVersion::V1.into()) + ), + &mut rng, + )); + // reputation change due to invalid signature + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) + ) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, COST_SIGNATURE_INVALID.cost_or_benefit()) + } + ); + }); +} + +#[test] +fn receive_invalid_validator_index() { + let _ = env_logger::builder() + .filter(None, log::LevelFilter::Trace) + .is_test(true) + .try_init(); + + let hash_a: Hash = [0; 32].into(); + let hash_b: Hash = [1; 32].into(); // other + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + assert_ne!(peer_a, peer_b); + + // validator 0 key pair + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash_a, hash_b], hash_a, ReputationAggregator::new(|_| true)); + + state.peer_data.insert(peer_b, peer_data_v1(view![hash_a])); + + let payload = AvailabilityBitfield(bitvec![u8, bitvec::order::Lsb0; 1u8; 32]); + let signed = Signed::::sign( + &keystore, + payload, + &signing_context, + ValidatorIndex(42), + &validator, + ) + .ok() + .flatten() + .expect("should be signed"); + + let msg = BitfieldGossipMessage { relay_parent: hash_a, signed_availability: signed.clone() }; + + let pool = sp_core::testing::TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::(pool); + let mut rng = dummy_rng(); + + executor::block_on(async move { + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peer_b, + msg.into_network_message(ValidationVersion::V1.into()) + ), + &mut rng, + )); + + // reputation change due to invalid validator index + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) + ) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, COST_VALIDATOR_INDEX_INVALID.cost_or_benefit()) + } + ); + }); +} + +#[test] +fn receive_duplicate_messages() { + let _ = env_logger::builder() + .filter(None, log::LevelFilter::Trace) + .is_test(true) + .try_init(); + + let hash_a: Hash = [0; 32].into(); + let hash_b: Hash = [1; 32].into(); + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + assert_ne!(peer_a, peer_b); + + // validator 0 key pair + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash_a, hash_b], hash_a, ReputationAggregator::new(|_| true)); + + // create a signed message by validator 0 + let payload = AvailabilityBitfield(bitvec![u8, bitvec::order::Lsb0; 1u8; 32]); + let signed_bitfield = Signed::::sign( + &keystore, + payload, + &signing_context, + ValidatorIndex(0), + &validator, + ) + .ok() + .flatten() + .expect("should be signed"); + + let msg = BitfieldGossipMessage { + relay_parent: hash_a, + signed_availability: signed_bitfield.clone(), + }; + + let pool = sp_core::testing::TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::(pool); + let mut rng = dummy_rng(); + + executor::block_on(async move { + // send a first message + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peer_b, + msg.clone().into_network_message(ValidationVersion::V1.into()), + ), + &mut rng, + )); + + // none of our peers has any interest in any messages + // so we do not receive a network send type message here + // but only the one for the next subsystem + assert_matches!( + handle.recv().await, + AllMessages::Provisioner(ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::Bitfield(hash, signed) + )) => { + assert_eq!(hash, hash_a); + assert_eq!(signed, signed_bitfield) + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) + ) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, BENEFIT_VALID_MESSAGE_FIRST.cost_or_benefit()) + } + ); + + // let peer A send the same message again + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peer_a, + msg.clone().into_network_message(ValidationVersion::V1.into()), + ), + &mut rng, + )); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) + ) => { + assert_eq!(peer, peer_a); + assert_eq!(rep.value, BENEFIT_VALID_MESSAGE.cost_or_benefit()) + } + ); + + // let peer B send the initial message again + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peer_b, + msg.clone().into_network_message(ValidationVersion::V1.into()), + ), + &mut rng, + )); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) + ) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, COST_PEER_DUPLICATE_MESSAGE.cost_or_benefit()) + } + ); + }); +} + +#[test] +fn delay_reputation_change() { + use polkadot_node_subsystem_util::reputation::add_reputation; + + let _ = env_logger::builder() + .filter(None, log::LevelFilter::Trace) + .is_test(true) + .try_init(); + + let hash_a: Hash = [0; 32].into(); + let hash_b: Hash = [1; 32].into(); + + let peer = PeerId::random(); + + // validator 0 key pair + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash_a, hash_b], hash_a, ReputationAggregator::new(|_| false)); + + // create a signed message by validator 0 + let payload = AvailabilityBitfield(bitvec![u8, bitvec::order::Lsb0; 1u8; 32]); + let signed_bitfield = Signed::::sign( + &keystore, + payload, + &signing_context, + ValidatorIndex(0), + &validator, + ) + .ok() + .flatten() + .expect("should be signed"); + + let msg = BitfieldGossipMessage { + relay_parent: hash_a, + signed_availability: signed_bitfield.clone(), + }; + + let pool = sp_core::testing::TaskExecutor::new(); + let (ctx, mut handle) = make_subsystem_context::(pool); + let mut rng = dummy_rng(); + let reputation_interval = Duration::from_millis(100); + + let bg = async move { + let subsystem = BitfieldDistribution::new(Default::default()); + subsystem.run_inner(ctx, &mut state, reputation_interval, &mut rng).await; + }; + + let test_fut = async move { + // send a first message + handle + .send(FromOrchestra::Communication { + msg: BitfieldDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer, + msg.clone().into_network_message(ValidationVersion::V1.into()), + ), + ), + }) + .await; + + // none of our peers has any interest in any messages + // so we do not receive a network send type message here + // but only the one for the next subsystem + assert_matches!( + handle.recv().await, + AllMessages::Provisioner(ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::Bitfield(hash, signed) + )) => { + assert_eq!(hash, hash_a); + assert_eq!(signed, signed_bitfield) + } + ); + + // let peer send the initial message again + handle + .send(FromOrchestra::Communication { + msg: BitfieldDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer, + msg.clone().into_network_message(ValidationVersion::V1.into()), + ), + ), + }) + .await; + + // Wait enough to fire reputation delay + futures_timer::Delay::new(reputation_interval).await; + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Batch(v)) + ) => { + let mut expected_change = HashMap::new(); + for rep in vec![BENEFIT_VALID_MESSAGE_FIRST, COST_PEER_DUPLICATE_MESSAGE] { + add_reputation(&mut expected_change, peer, rep) + } + assert_eq!(v, expected_change) + } + ); + + handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::pin_mut!(bg); + futures::pin_mut!(test_fut); + + executor::block_on(futures::future::join(bg, test_fut)); +} + +#[test] +fn do_not_relay_message_twice() { + let _ = env_logger::builder() + .filter(None, log::LevelFilter::Trace) + .is_test(true) + .try_init(); + + let hash = Hash::random(); + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + assert_ne!(peer_a, peer_b); + + // validator 0 key pair + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash], hash, ReputationAggregator::new(|_| true)); + + // create a signed message by validator 0 + let payload = AvailabilityBitfield(bitvec![u8, bitvec::order::Lsb0; 1u8; 32]); + let signed_bitfield = Signed::::sign( + &keystore, + payload, + &signing_context, + ValidatorIndex(0), + &validator, + ) + .ok() + .flatten() + .expect("should be signed"); + + state.peer_data.insert(peer_b, peer_data_v1(view![hash])); + state.peer_data.insert(peer_a, peer_data_v1(view![hash])); + + let msg = + BitfieldGossipMessage { relay_parent: hash, signed_availability: signed_bitfield.clone() }; + + let pool = sp_core::testing::TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::(pool); + let mut rng = dummy_rng(); + + executor::block_on(async move { + let mut gossip_peers = GridNeighbors::empty(); + gossip_peers.peers_x = HashSet::from_iter(vec![peer_a, peer_b].into_iter()); + + relay_message( + &mut ctx, + state.per_relay_parent.get_mut(&hash).unwrap(), + &gossip_peers, + &mut state.peer_data, + validator.clone(), + msg.clone(), + RequiredRouting::GridXY, + &mut rng, + ) + .await; + + assert_matches!( + handle.recv().await, + AllMessages::Provisioner(ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::Bitfield(h, signed) + )) => { + assert_eq!(h, hash); + assert_eq!(signed, signed_bitfield) + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage(peers, send_msg), + ) => { + assert_eq!(2, peers.len()); + assert!(peers.contains(&peer_a)); + assert!(peers.contains(&peer_b)); + assert_eq!(send_msg, msg.clone().into_validation_protocol(ValidationVersion::V1.into())); + } + ); + + // Relaying the message a second time shouldn't work. + relay_message( + &mut ctx, + state.per_relay_parent.get_mut(&hash).unwrap(), + &gossip_peers, + &mut state.peer_data, + validator.clone(), + msg.clone(), + RequiredRouting::GridXY, + &mut rng, + ) + .await; + + assert_matches!( + handle.recv().await, + AllMessages::Provisioner(ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::Bitfield(h, signed) + )) => { + assert_eq!(h, hash); + assert_eq!(signed, signed_bitfield) + } + ); + + // There shouldn't be any other message + assert!(handle.recv().timeout(TIMEOUT).await.is_none()); + }); +} + +#[test] +fn changing_view() { + let _ = env_logger::builder() + .filter(None, log::LevelFilter::Trace) + .is_test(true) + .try_init(); + + let hash_a: Hash = [0; 32].into(); + let hash_b: Hash = [1; 32].into(); + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + assert_ne!(peer_a, peer_b); + + // validator 0 key pair + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash_a, hash_b], hash_a, ReputationAggregator::new(|_| true)); + + // create a signed message by validator 0 + let payload = AvailabilityBitfield(bitvec![u8, bitvec::order::Lsb0; 1u8; 32]); + let signed_bitfield = Signed::::sign( + &keystore, + payload, + &signing_context, + ValidatorIndex(0), + &validator, + ) + .ok() + .flatten() + .expect("should be signed"); + + let msg = BitfieldGossipMessage { + relay_parent: hash_a, + signed_availability: signed_bitfield.clone(), + }; + + let pool = sp_core::testing::TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::(pool); + let mut rng = dummy_rng(); + + executor::block_on(async move { + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerConnected( + peer_b, + ObservedRole::Full, + ValidationVersion::V1.into(), + None + ), + &mut rng, + )); + + // make peer b interested + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerViewChange(peer_b, view![hash_a, hash_b]), + &mut rng, + )); + + assert!(state.peer_data.contains_key(&peer_b)); + + // recv a first message from the network + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peer_b, + msg.clone().into_network_message(ValidationVersion::V1.into()), + ), + &mut rng, + )); + + // gossip to the overseer + assert_matches!( + handle.recv().await, + AllMessages::Provisioner(ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::Bitfield(hash, signed) + )) => { + assert_eq!(hash, hash_a); + assert_eq!(signed, signed_bitfield) + } + ); + + // reputation change for peer B + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) + ) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, BENEFIT_VALID_MESSAGE_FIRST.cost_or_benefit()) + } + ); + + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerViewChange(peer_b, view![]), + &mut rng, + )); + + assert!(state.peer_data.contains_key(&peer_b)); + assert_eq!( + &state.peer_data.get(&peer_b).expect("Must contain value for peer B").view, + &view![] + ); + + // on rx of the same message, since we are not interested, + // should give penalty + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peer_b, + msg.clone().into_network_message(ValidationVersion::V1.into()), + ), + &mut rng, + )); + + // reputation change for peer B + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) + ) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, COST_PEER_DUPLICATE_MESSAGE.cost_or_benefit()) + } + ); + + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerDisconnected(peer_b), + &mut rng, + )); + + // we are not interested in any peers at all anymore + state.view = our_view![]; + + // on rx of the same message, since we are not interested, + // should give penalty + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peer_a, + msg.clone().into_network_message(ValidationVersion::V1.into()), + ), + &mut rng, + )); + + // reputation change for peer B + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) + ) => { + assert_eq!(peer, peer_a); + assert_eq!(rep.value, COST_NOT_IN_VIEW.cost_or_benefit()) + } + ); + }); +} + +#[test] +fn do_not_send_message_back_to_origin() { + let _ = env_logger::builder() + .filter(None, log::LevelFilter::Trace) + .is_test(true) + .try_init(); + + let hash: Hash = [0; 32].into(); + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + assert_ne!(peer_a, peer_b); + + // validator 0 key pair + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash], hash, ReputationAggregator::new(|_| true)); + + // create a signed message by validator 0 + let payload = AvailabilityBitfield(bitvec![u8, bitvec::order::Lsb0; 1u8; 32]); + let signed_bitfield = Signed::::sign( + &keystore, + payload, + &signing_context, + ValidatorIndex(0), + &validator, + ) + .ok() + .flatten() + .expect("should be signed"); + + state.peer_data.insert(peer_b, peer_data_v1(view![hash])); + state.peer_data.insert(peer_a, peer_data_v1(view![hash])); + + let msg = + BitfieldGossipMessage { relay_parent: hash, signed_availability: signed_bitfield.clone() }; + + let pool = sp_core::testing::TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::(pool); + let mut rng = dummy_rng(); + + executor::block_on(async move { + // send a first message + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peer_b, + msg.clone().into_network_message(ValidationVersion::V1.into()), + ), + &mut rng, + )); + + assert_matches!( + handle.recv().await, + AllMessages::Provisioner(ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::Bitfield(hash, signed) + )) => { + assert_eq!(hash, hash); + assert_eq!(signed, signed_bitfield) + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage(peers, send_msg), + ) => { + assert_eq!(1, peers.len()); + assert!(peers.contains(&peer_a)); + assert_eq!(send_msg, msg.clone().into_validation_protocol(ValidationVersion::V1.into())); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) + ) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, BENEFIT_VALID_MESSAGE_FIRST.cost_or_benefit()) + } + ); + }); +} + +#[test] +fn topology_test() { + let _ = env_logger::builder() + .filter(None, log::LevelFilter::Trace) + .is_test(true) + .try_init(); + + let hash: Hash = [0; 32].into(); + + // validator 0 key pair + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash], hash, ReputationAggregator::new(|_| true)); + + // Create a simple grid without any shuffling. We occupy position 1. + let topology_peer_info: Vec<_> = (0..49) + .map(|i| TopologyPeerInfo { + peer_ids: vec![PeerId::random()], + validator_index: ValidatorIndex(i as _), + discovery_id: AuthorityDiscoveryPair::generate().0.public(), + }) + .collect(); + + let topology = SessionGridTopology::new((0usize..49).collect(), topology_peer_info.clone()); + state.topologies.update_topology(0_u32, topology, Some(ValidatorIndex(1))); + + let peers_x: Vec<_> = [0, 2, 3, 4, 5, 6] + .iter() + .cloned() + .map(|i| topology_peer_info[i].peer_ids[0]) + .collect(); + + let peers_y: Vec<_> = [8, 15, 22, 29, 36, 43] + .iter() + .cloned() + .map(|i| topology_peer_info[i].peer_ids[0]) + .collect(); + + { + let t = state.topologies.get_current_topology().local_grid_neighbors(); + for p_x in &peers_x { + assert!(t.peers_x.contains(p_x)); + } + for p_y in &peers_y { + assert!(t.peers_y.contains(p_y)); + } + } + + // create a signed message by validator 0 + let payload = AvailabilityBitfield(bitvec![u8, bitvec::order::Lsb0; 1u8; 32]); + let signed_bitfield = Signed::::sign( + &keystore, + payload, + &signing_context, + ValidatorIndex(0), + &validator, + ) + .ok() + .flatten() + .expect("should be signed"); + + peers_x.iter().chain(peers_y.iter()).for_each(|peer| { + state.peer_data.insert(*peer, peer_data_v1(view![hash])); + }); + + let msg = + BitfieldGossipMessage { relay_parent: hash, signed_availability: signed_bitfield.clone() }; + + let pool = sp_core::testing::TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::(pool); + let mut rng = dummy_rng(); + + executor::block_on(async move { + // send a first message + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peers_x[0], + msg.clone().into_network_message(ValidationVersion::V1.into()), + ), + &mut rng, + )); + + assert_matches!( + handle.recv().await, + AllMessages::Provisioner(ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::Bitfield(hash, signed) + )) => { + assert_eq!(hash, hash); + assert_eq!(signed, signed_bitfield) + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage(peers, send_msg), + ) => { + let topology = state.topologies.get_current_topology().local_grid_neighbors(); + // It should send message to all peers in y direction and to 4 random peers in x direction + assert_eq!(peers_y.len() + 4, peers.len()); + assert!(topology.peers_y.iter().all(|peer| peers.contains(&peer))); + assert!(topology.peers_x.iter().filter(|peer| peers.contains(&peer)).count() == 4); + // Must never include originator + assert!(!peers.contains(&peers_x[0])); + assert_eq!(send_msg, msg.clone().into_validation_protocol(ValidationVersion::V1.into())); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) + ) => { + assert_eq!(peer, peers_x[0]); + assert_eq!(rep.value, BENEFIT_VALID_MESSAGE_FIRST.cost_or_benefit()) + } + ); + }); +} + +#[test] +fn need_message_works() { + let validators = vec![Sr25519Keyring::Alice.pair(), Sr25519Keyring::Bob.pair()]; + + let validator_set = Vec::from_iter(validators.iter().map(|k| ValidatorId::from(k.public()))); + + let signing_context = SigningContext { session_index: 1, parent_hash: Hash::repeat_byte(0x00) }; + let mut state = PerRelayParentData::new( + signing_context, + validator_set.clone(), + PerLeafSpan::new(Arc::new(Span::Disabled), "foo"), + ); + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + assert_ne!(peer_a, peer_b); + + let pretend_send = + |state: &mut PerRelayParentData, dest_peer: PeerId, signed_by: &ValidatorId| -> bool { + if state.message_from_validator_needed_by_peer(&dest_peer, signed_by) { + state + .message_sent_to_peer + .entry(dest_peer) + .or_default() + .insert(signed_by.clone()); + true + } else { + false + } + }; + + let pretend_receive = + |state: &mut PerRelayParentData, source_peer: PeerId, signed_by: &ValidatorId| { + state + .message_received_from_peer + .entry(source_peer) + .or_default() + .insert(signed_by.clone()); + }; + + assert!(pretend_send(&mut state, peer_a, &validator_set[0])); + assert!(pretend_send(&mut state, peer_b, &validator_set[1])); + // sending the same thing must not be allowed + assert!(!pretend_send(&mut state, peer_a, &validator_set[0])); + + // receive by Alice + pretend_receive(&mut state, peer_a, &validator_set[0]); + // must be marked as not needed by Alice, so attempt to send to Alice must be false + assert!(!pretend_send(&mut state, peer_a, &validator_set[0])); + // but ok for Bob + assert!(!pretend_send(&mut state, peer_b, &validator_set[1])); + + // receive by Bob + pretend_receive(&mut state, peer_a, &validator_set[0]); + // not ok for Alice + assert!(!pretend_send(&mut state, peer_a, &validator_set[0])); + // also not ok for Bob + assert!(!pretend_send(&mut state, peer_b, &validator_set[1])); +} + +#[test] +fn network_protocol_versioning() { + let hash_a: Hash = [0; 32].into(); + let hash_b: Hash = [1; 32].into(); + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + + let peers = [ + (peer_a, ValidationVersion::VStaging), + (peer_b, ValidationVersion::V1), + (peer_c, ValidationVersion::VStaging), + ]; + + // validator 0 key pair + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash_a, hash_b], hash_a, ReputationAggregator::new(|_| true)); + + let pool = sp_core::testing::TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::(pool); + let mut rng = dummy_rng(); + + executor::block_on(async move { + // create a signed message by validator 0 + let payload = AvailabilityBitfield(bitvec![u8, bitvec::order::Lsb0; 1u8; 32]); + let signed_bitfield = Signed::::sign( + &keystore, + payload, + &signing_context, + ValidatorIndex(0), + &validator, + ) + .ok() + .flatten() + .expect("should be signed"); + let msg = BitfieldGossipMessage { + relay_parent: hash_a, + signed_availability: signed_bitfield.clone(), + }; + + for (peer, protocol_version) in peers { + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Full, + protocol_version.into(), + None + ), + &mut rng, + )); + + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerViewChange(peer, view![hash_a, hash_b]), + &mut rng, + )); + + assert!(state.peer_data.contains_key(&peer)); + } + + launch!(handle_network_msg( + &mut ctx, + &mut state, + &Default::default(), + NetworkBridgeEvent::PeerMessage( + peer_a, + msg.clone().into_network_message(ValidationVersion::VStaging.into()), + ), + &mut rng, + )); + + // gossip to the overseer + assert_matches!( + handle.recv().await, + AllMessages::Provisioner(ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::Bitfield(hash, signed) + )) => { + assert_eq!(hash, hash_a); + assert_eq!(signed, signed_bitfield) + } + ); + + // v1 gossip + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage(peers, send_msg), + ) => { + assert_eq!(peers, vec![peer_b]); + assert_eq!(send_msg, msg.clone().into_validation_protocol(ValidationVersion::V1.into())); + } + ); + + // vstaging gossip + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage(peers, send_msg), + ) => { + assert_eq!(peers, vec![peer_c]); + assert_eq!(send_msg, msg.clone().into_validation_protocol(ValidationVersion::VStaging.into())); + } + ); + + // reputation change + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) + ) => { + assert_eq!(peer, peer_a); + assert_eq!(rep, BENEFIT_VALID_MESSAGE_FIRST.into()) + } + ); + }); +} diff --git a/polkadot/node/network/bridge/Cargo.toml b/polkadot/node/network/bridge/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..4f3d6306aa8e33791d56b97cabe29d0de713aae7 --- /dev/null +++ b/polkadot/node/network/bridge/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "polkadot-network-bridge" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +always-assert = "0.1" +async-trait = "0.1.57" +futures = "0.3.21" +gum = { package = "tracing-gum", path = "../../gum" } +polkadot-primitives = { path = "../../../primitives" } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot-node-metrics = { path = "../../metrics"} +polkadot-node-network-protocol = { path = "../protocol" } +polkadot-node-subsystem = {path = "../../subsystem" } +polkadot-overseer = { path = "../../overseer" } +parking_lot = "0.12.0" +bytes = "1" +fatality = "0.0.6" +thiserror = "1" + +[dev-dependencies] +assert_matches = "1.4.0" +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +polkadot-node-subsystem-util = { path = "../../subsystem-util"} +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures-timer = "3" +polkadot-primitives-test-helpers = { path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/network/bridge/src/errors.rs b/polkadot/node/network/bridge/src/errors.rs new file mode 100644 index 0000000000000000000000000000000000000000..1234bd9190025637acf0689a479d88280b145d65 --- /dev/null +++ b/polkadot/node/network/bridge/src/errors.rs @@ -0,0 +1,36 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem::SubsystemError; +pub(crate) use polkadot_overseer::OverseerError; + +#[fatality::fatality(splitable)] +pub(crate) enum Error { + /// Received error from overseer: + #[fatal] + #[error(transparent)] + SubsystemError(#[from] SubsystemError), + /// The stream of incoming events concluded. + #[fatal] + #[error("Event stream closed unexpectedly")] + EventStreamConcluded, +} + +impl From for Error { + fn from(e: OverseerError) -> Self { + Error::SubsystemError(SubsystemError::from(e)) + } +} diff --git a/polkadot/node/network/bridge/src/lib.rs b/polkadot/node/network/bridge/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..46d4a00faace6344cbfcfd16ea702f1dcf3ee907 --- /dev/null +++ b/polkadot/node/network/bridge/src/lib.rs @@ -0,0 +1,107 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Network Bridge Subsystem - protocol multiplexer for Polkadot. +//! +//! Split into incoming (`..In`) and outgoing (`..Out`) subsystems. + +#![deny(unused_crate_dependencies)] +#![warn(missing_docs)] + +use futures::prelude::*; +use parity_scale_codec::{Decode, Encode}; +use parking_lot::Mutex; + +use sp_consensus::SyncOracle; + +use polkadot_node_network_protocol::{ + peer_set::{PeerSet, ProtocolVersion}, + PeerId, UnifiedReputationChange as Rep, View, +}; + +/// Peer set info for network initialization. +/// +/// To be passed to [`FullNetworkConfiguration::add_notification_protocol`](). +pub use polkadot_node_network_protocol::peer_set::{peer_sets_info, IsAuthority}; + +use std::{collections::HashMap, sync::Arc}; + +mod validator_discovery; + +/// Actual interfacing to the network based on the `Network` trait. +/// +/// Defines the `Network` trait with an implementation for an `Arc`. +mod network; +use self::network::Network; + +mod metrics; +pub use self::metrics::Metrics; + +mod errors; +pub(crate) use self::errors::Error; + +mod tx; +pub use self::tx::*; + +mod rx; +pub use self::rx::*; + +/// The maximum amount of heads a peer is allowed to have in their view at any time. +/// +/// We use the same limit to compute the view sent to peers locally. +pub(crate) const MAX_VIEW_HEADS: usize = 5; + +pub(crate) const MALFORMED_MESSAGE_COST: Rep = Rep::CostMajor("Malformed Network-bridge message"); +pub(crate) const UNCONNECTED_PEERSET_COST: Rep = + Rep::CostMinor("Message sent to un-connected peer-set"); +pub(crate) const MALFORMED_VIEW_COST: Rep = Rep::CostMajor("Malformed view"); +pub(crate) const EMPTY_VIEW_COST: Rep = Rep::CostMajor("Peer sent us an empty view"); + +/// Messages from and to the network. +/// +/// As transmitted to and received from subsystems. +#[derive(Debug, Encode, Decode, Clone)] +pub(crate) enum WireMessage { + /// A message from a peer on a specific protocol. + #[codec(index = 1)] + ProtocolMessage(M), + /// A view update from a peer. + #[codec(index = 2)] + ViewUpdate(View), +} + +pub(crate) struct PeerData { + /// The Latest view sent by the peer. + view: View, + version: ProtocolVersion, +} + +/// Shared state between incoming and outgoing. + +#[derive(Default, Clone)] +pub(crate) struct Shared(Arc>); + +#[derive(Default)] +struct SharedInner { + local_view: Option, + validation_peers: HashMap, + collation_peers: HashMap, +} + +pub(crate) enum Mode { + Syncing(Box), + Active, +} diff --git a/polkadot/node/network/bridge/src/metrics.rs b/polkadot/node/network/bridge/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..bb90daad56761d24d5d68995580e893a4d773e8c --- /dev/null +++ b/polkadot/node/network/bridge/src/metrics.rs @@ -0,0 +1,224 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::{PeerSet, ProtocolVersion}; +use polkadot_node_metrics::metrics::{self, prometheus}; + +/// Metrics for the network bridge. +#[derive(Clone, Default)] +pub struct Metrics(pub(crate) Option); + +fn peer_set_label(peer_set: PeerSet, version: ProtocolVersion) -> &'static str { + // Higher level code is meant to protect against this ever happening. + peer_set.get_protocol_label(version).unwrap_or("") +} + +#[allow(missing_docs)] +impl Metrics { + pub fn on_peer_connected(&self, peer_set: PeerSet, version: ProtocolVersion) { + self.0.as_ref().map(|metrics| { + metrics + .connected_events + .with_label_values(&[peer_set_label(peer_set, version)]) + .inc() + }); + } + + pub fn on_peer_disconnected(&self, peer_set: PeerSet, version: ProtocolVersion) { + self.0.as_ref().map(|metrics| { + metrics + .disconnected_events + .with_label_values(&[peer_set_label(peer_set, version)]) + .inc() + }); + } + + pub fn note_peer_count(&self, peer_set: PeerSet, version: ProtocolVersion, count: usize) { + self.0.as_ref().map(|metrics| { + metrics + .peer_count + .with_label_values(&[peer_set_label(peer_set, version)]) + .set(count as u64) + }); + } + + pub fn on_notification_received( + &self, + peer_set: PeerSet, + version: ProtocolVersion, + size: usize, + ) { + if let Some(metrics) = self.0.as_ref() { + metrics + .notifications_received + .with_label_values(&[peer_set_label(peer_set, version)]) + .inc(); + + metrics + .bytes_received + .with_label_values(&[peer_set_label(peer_set, version)]) + .inc_by(size as u64); + } + } + + pub fn on_notification_sent( + &self, + peer_set: PeerSet, + version: ProtocolVersion, + size: usize, + to_peers: usize, + ) { + if let Some(metrics) = self.0.as_ref() { + metrics + .notifications_sent + .with_label_values(&[peer_set_label(peer_set, version)]) + .inc_by(to_peers as u64); + + metrics + .bytes_sent + .with_label_values(&[peer_set_label(peer_set, version)]) + .inc_by((size * to_peers) as u64); + } + } + + pub fn note_desired_peer_count(&self, peer_set: PeerSet, size: usize) { + self.0.as_ref().map(|metrics| { + metrics + .desired_peer_count + .with_label_values(&[peer_set.get_label()]) + .set(size as u64) + }); + } + + pub fn on_report_event(&self) { + if let Some(metrics) = self.0.as_ref() { + metrics.report_events.inc() + } + } +} + +#[derive(Clone)] +pub(crate) struct MetricsInner { + peer_count: prometheus::GaugeVec, + connected_events: prometheus::CounterVec, + disconnected_events: prometheus::CounterVec, + desired_peer_count: prometheus::GaugeVec, + report_events: prometheus::Counter, + + notifications_received: prometheus::CounterVec, + notifications_sent: prometheus::CounterVec, + + bytes_received: prometheus::CounterVec, + bytes_sent: prometheus::CounterVec, +} + +impl metrics::Metrics for Metrics { + fn try_register( + registry: &prometheus::Registry, + ) -> std::result::Result { + let metrics = MetricsInner { + peer_count: prometheus::register( + prometheus::GaugeVec::new( + prometheus::Opts::new( + "polkadot_parachain_peer_count", + "The number of peers on a parachain-related peer-set", + ), + &["protocol"] + )?, + registry, + )?, + connected_events: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_peer_connect_events_total", + "The number of peer connect events on a parachain notifications protocol", + ), + &["protocol"] + )?, + registry, + )?, + disconnected_events: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_peer_disconnect_events_total", + "The number of peer disconnect events on a parachain notifications protocol", + ), + &["protocol"] + )?, + registry, + )?, + desired_peer_count: prometheus::register( + prometheus::GaugeVec::new( + prometheus::Opts::new( + "polkadot_parachain_desired_peer_count", + "The number of peers that the local node is expected to connect to on a parachain-related peer-set (either including or not including unresolvable authorities, depending on whether `ConnectToValidators` or `ConnectToValidatorsResolved` was used.)", + ), + &["protocol"] + )?, + registry, + )?, + report_events: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_network_report_events_total", + "The amount of reputation changes issued by subsystems", + )?, + registry, + )?, + notifications_received: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_notifications_received_total", + "The number of notifications received on a parachain protocol", + ), + &["protocol"] + )?, + registry, + )?, + notifications_sent: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_notifications_sent_total", + "The number of notifications sent on a parachain protocol", + ), + &["protocol"] + )?, + registry, + )?, + bytes_received: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_notification_bytes_received_total", + "The number of bytes received on a parachain notification protocol", + ), + &["protocol"] + )?, + registry, + )?, + bytes_sent: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_notification_bytes_sent_total", + "The number of bytes sent on a parachain notification protocol", + ), + &["protocol"] + )?, + registry, + )?, + }; + + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/network/bridge/src/network.rs b/polkadot/node/network/bridge/src/network.rs new file mode 100644 index 0000000000000000000000000000000000000000..4f21212dcb64a76e25396de94b35204d53682aaa --- /dev/null +++ b/polkadot/node/network/bridge/src/network.rs @@ -0,0 +1,248 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{collections::HashSet, sync::Arc}; + +use async_trait::async_trait; +use futures::{prelude::*, stream::BoxStream}; + +use parity_scale_codec::Encode; + +use sc_network::{ + config::parse_addr, multiaddr::Multiaddr, types::ProtocolName, Event as NetworkEvent, + IfDisconnected, NetworkEventStream, NetworkNotification, NetworkPeers, NetworkRequest, + NetworkService, OutboundFailure, ReputationChange, RequestFailure, +}; + +use polkadot_node_network_protocol::{ + peer_set::{PeerSet, PeerSetProtocolNames, ProtocolVersion}, + request_response::{OutgoingRequest, Recipient, ReqProtocolNames, Requests}, + PeerId, +}; +use polkadot_primitives::{AuthorityDiscoveryId, Block, Hash}; + +use crate::validator_discovery::AuthorityDiscovery; + +// network bridge network abstraction log target +const LOG_TARGET: &'static str = "parachain::network-bridge-net"; + +/// Send a message to the network. +/// +/// This function is only used internally by the network-bridge, which is responsible to only send +/// messages that are compatible with the passed peer set, as that is currently not enforced by +/// this function. These are messages of type `WireMessage` parameterized on the matching type. +pub(crate) fn send_message( + net: &mut impl Network, + mut peers: Vec, + peer_set: PeerSet, + version: ProtocolVersion, + protocol_names: &PeerSetProtocolNames, + message: M, + metrics: &super::Metrics, +) where + M: Encode + Clone, +{ + if peers.is_empty() { + return + } + let message = { + let encoded = message.encode(); + metrics.on_notification_sent(peer_set, version, encoded.len(), peers.len()); + encoded + }; + + // optimization: avoid cloning the message for the last peer in the + // list. The message payload can be quite large. If the underlying + // network used `Bytes` this would not be necessary. + let last_peer = peers.pop(); + + // We always send messages on the "main" name even when a negotiated + // fallback is used. The libp2p implementation handles the fallback + // under the hood. + let protocol_name = protocol_names.get_main_name(peer_set); + peers.into_iter().for_each(|peer| { + net.write_notification(peer, protocol_name.clone(), message.clone()); + }); + if let Some(peer) = last_peer { + net.write_notification(peer, protocol_name, message); + } +} + +/// An abstraction over networking for the purposes of this subsystem. +#[async_trait] +pub trait Network: Clone + Send + 'static { + /// Get a stream of all events occurring on the network. This may include events unrelated + /// to the Polkadot protocol - the user of this function should filter only for events related + /// to the [`VALIDATION_PROTOCOL_NAME`](VALIDATION_PROTOCOL_NAME) + /// or [`COLLATION_PROTOCOL_NAME`](COLLATION_PROTOCOL_NAME) + fn event_stream(&mut self) -> BoxStream<'static, NetworkEvent>; + + /// Ask the network to keep a substream open with these nodes and not disconnect from them + /// until removed from the protocol's peer set. + /// Note that `out_peers` setting has no effect on this. + async fn set_reserved_peers( + &mut self, + protocol: ProtocolName, + multiaddresses: HashSet, + ) -> Result<(), String>; + + /// Removes the peers for the protocol's peer set (both reserved and non-reserved). + async fn remove_from_peers_set( + &mut self, + protocol: ProtocolName, + peers: Vec, + ) -> Result<(), String>; + + /// Send a request to a remote peer. + async fn start_request( + &self, + authority_discovery: &mut AD, + req: Requests, + req_protocol_names: &ReqProtocolNames, + if_disconnected: IfDisconnected, + ); + + /// Report a given peer as either beneficial (+) or costly (-) according to the given scalar. + fn report_peer(&self, who: PeerId, rep: ReputationChange); + + /// Disconnect a given peer from the protocol specified without harming reputation. + fn disconnect_peer(&self, who: PeerId, protocol: ProtocolName); + + /// Write a notification to a peer on the given protocol. + fn write_notification(&self, who: PeerId, protocol: ProtocolName, message: Vec); +} + +#[async_trait] +impl Network for Arc> { + fn event_stream(&mut self) -> BoxStream<'static, NetworkEvent> { + NetworkService::event_stream(self, "polkadot-network-bridge").boxed() + } + + async fn set_reserved_peers( + &mut self, + protocol: ProtocolName, + multiaddresses: HashSet, + ) -> Result<(), String> { + NetworkService::set_reserved_peers(&**self, protocol, multiaddresses) + } + + async fn remove_from_peers_set( + &mut self, + protocol: ProtocolName, + peers: Vec, + ) -> Result<(), String> { + NetworkService::remove_peers_from_reserved_set(&**self, protocol, peers) + } + + fn report_peer(&self, who: PeerId, rep: ReputationChange) { + NetworkService::report_peer(&**self, who, rep); + } + + fn disconnect_peer(&self, who: PeerId, protocol: ProtocolName) { + NetworkService::disconnect_peer(&**self, who, protocol); + } + + fn write_notification(&self, who: PeerId, protocol: ProtocolName, message: Vec) { + NetworkService::write_notification(&**self, who, protocol, message); + } + + async fn start_request( + &self, + authority_discovery: &mut AD, + req: Requests, + req_protocol_names: &ReqProtocolNames, + if_disconnected: IfDisconnected, + ) { + let (protocol, OutgoingRequest { peer, payload, pending_response }) = req.encode_request(); + + let peer_id = match peer { + Recipient::Peer(peer_id) => Some(peer_id), + Recipient::Authority(authority) => { + gum::trace!( + target: LOG_TARGET, + ?authority, + "Searching for peer id to connect to authority", + ); + + let mut found_peer_id = None; + // Note: `get_addresses_by_authority_id` searched in a cache, and it thus expected + // to be very quick. + for addr in authority_discovery + .get_addresses_by_authority_id(authority) + .await + .into_iter() + .flat_map(|list| list.into_iter()) + { + let (peer_id, addr) = match parse_addr(addr) { + Ok(v) => v, + Err(_) => continue, + }; + NetworkService::add_known_address(self, peer_id, addr); + found_peer_id = Some(peer_id); + } + found_peer_id + }, + }; + + let peer_id = match peer_id { + None => { + gum::debug!(target: LOG_TARGET, "Discovering authority failed"); + match pending_response + .send(Err(RequestFailure::Network(OutboundFailure::DialFailure))) + { + Err(_) => { + gum::debug!(target: LOG_TARGET, "Sending failed request response failed.") + }, + Ok(_) => {}, + } + return + }, + Some(peer_id) => peer_id, + }; + + gum::trace!( + target: LOG_TARGET, + %peer_id, + protocol = %req_protocol_names.get_name(protocol), + ?if_disconnected, + "Starting request", + ); + + NetworkService::start_request( + self, + peer_id, + req_protocol_names.get_name(protocol), + payload, + pending_response, + if_disconnected, + ); + } +} + +/// We assume one `peer_id` per `authority_id`. +pub async fn get_peer_id_by_authority_id( + authority_discovery: &mut AD, + authority: AuthorityDiscoveryId, +) -> Option { + // Note: `get_addresses_by_authority_id` searched in a cache, and it thus expected + // to be very quick. + authority_discovery + .get_addresses_by_authority_id(authority) + .await + .into_iter() + .flat_map(|list| list.into_iter()) + .find_map(|addr| parse_addr(addr).ok().map(|(p, _)| p)) +} diff --git a/polkadot/node/network/bridge/src/rx/mod.rs b/polkadot/node/network/bridge/src/rx/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..002919c5b0e50d1ae6da8f807900b545eb0a7e0d --- /dev/null +++ b/polkadot/node/network/bridge/src/rx/mod.rs @@ -0,0 +1,1070 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Network Bridge Subsystem - handles _incoming_ messages from the network, forwarded to the +//! relevant subsystems. +use super::*; + +use always_assert::never; +use bytes::Bytes; +use futures::stream::BoxStream; +use parity_scale_codec::{Decode, DecodeAll}; + +use sc_network::Event as NetworkEvent; +use sp_consensus::SyncOracle; + +use polkadot_node_network_protocol::{ + self as net_protocol, + grid_topology::{SessionGridTopology, TopologyPeerInfo}, + peer_set::{ + CollationVersion, PeerSet, PeerSetProtocolNames, PerPeerSet, ProtocolVersion, + ValidationVersion, + }, + v1 as protocol_v1, vstaging as protocol_vstaging, ObservedRole, OurView, PeerId, + UnifiedReputationChange as Rep, View, +}; + +use polkadot_node_subsystem::{ + errors::SubsystemError, + messages::{ + network_bridge_event::NewGossipTopology, ApprovalDistributionMessage, + BitfieldDistributionMessage, CollatorProtocolMessage, GossipSupportMessage, + NetworkBridgeEvent, NetworkBridgeRxMessage, StatementDistributionMessage, + }, + overseer, ActivatedLeaf, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, SpawnedSubsystem, +}; + +use polkadot_primitives::{AuthorityDiscoveryId, BlockNumber, Hash, ValidatorIndex}; + +/// Peer set info for network initialization. +/// +/// To be passed to [`FullNetworkConfiguration::add_notification_protocol`](). +pub use polkadot_node_network_protocol::peer_set::{peer_sets_info, IsAuthority}; + +use std::{ + collections::{hash_map, HashMap}, + iter::ExactSizeIterator, +}; + +use super::validator_discovery; + +/// Actual interfacing to the network based on the `Network` trait. +/// +/// Defines the `Network` trait with an implementation for an `Arc`. +use crate::network::{send_message, Network}; + +use crate::network::get_peer_id_by_authority_id; + +use super::metrics::Metrics; + +#[cfg(test)] +mod tests; + +// network bridge log target +const LOG_TARGET: &'static str = "parachain::network-bridge-rx"; + +/// The network bridge subsystem - network receiving side. +pub struct NetworkBridgeRx { + /// `Network` trait implementing type. + network_service: N, + authority_discovery_service: AD, + sync_oracle: Box, + shared: Shared, + metrics: Metrics, + peerset_protocol_names: PeerSetProtocolNames, +} + +impl NetworkBridgeRx { + /// Create a new network bridge subsystem with underlying network service and authority + /// discovery service. + /// + /// This assumes that the network service has had the notifications protocol for the network + /// bridge already registered. See [`peers_sets_info`](peers_sets_info). + pub fn new( + network_service: N, + authority_discovery_service: AD, + sync_oracle: Box, + metrics: Metrics, + peerset_protocol_names: PeerSetProtocolNames, + ) -> Self { + let shared = Shared::default(); + Self { + network_service, + authority_discovery_service, + sync_oracle, + shared, + metrics, + peerset_protocol_names, + } + } +} + +#[overseer::subsystem(NetworkBridgeRx, error = SubsystemError, prefix = self::overseer)] +impl NetworkBridgeRx +where + Net: Network + Sync, + AD: validator_discovery::AuthorityDiscovery + Clone + Sync, +{ + fn start(mut self, ctx: Context) -> SpawnedSubsystem { + // The stream of networking events has to be created at initialization, otherwise the + // networking might open connections before the stream of events has been grabbed. + let network_stream = self.network_service.event_stream(); + + // Swallow error because failure is fatal to the node and we log with more precision + // within `run_network`. + let future = run_network_in(self, ctx, network_stream) + .map_err(|e| SubsystemError::with_origin("network-bridge", e)) + .boxed(); + SpawnedSubsystem { name: "network-bridge-rx-subsystem", future } + } +} + +async fn handle_network_messages( + mut sender: impl overseer::NetworkBridgeRxSenderTrait, + mut network_service: impl Network, + network_stream: BoxStream<'static, NetworkEvent>, + mut authority_discovery_service: AD, + metrics: Metrics, + shared: Shared, + peerset_protocol_names: PeerSetProtocolNames, +) -> Result<(), Error> +where + AD: validator_discovery::AuthorityDiscovery + Send, +{ + let mut network_stream = network_stream.fuse(); + loop { + match network_stream.next().await { + None => return Err(Error::EventStreamConcluded), + Some(NetworkEvent::Dht(_)) => {}, + Some(NetworkEvent::NotificationStreamOpened { + remote: peer, + protocol, + role, + negotiated_fallback, + received_handshake: _, + }) => { + let role = ObservedRole::from(role); + let (peer_set, version) = { + let (peer_set, version) = + match peerset_protocol_names.try_get_protocol(&protocol) { + None => continue, + Some(p) => p, + }; + + if let Some(fallback) = negotiated_fallback { + match peerset_protocol_names.try_get_protocol(&fallback) { + None => { + gum::debug!( + target: LOG_TARGET, + fallback = &*fallback, + ?peer, + ?peer_set, + "Unknown fallback", + ); + + continue + }, + Some((p2, v2)) => { + if p2 != peer_set { + gum::debug!( + target: LOG_TARGET, + fallback = &*fallback, + fallback_peerset = ?p2, + protocol = &*protocol, + peerset = ?peer_set, + "Fallback mismatched peer-set", + ); + + continue + } + + (p2, v2) + }, + } + } else { + (peer_set, version) + } + }; + + gum::debug!( + target: LOG_TARGET, + action = "PeerConnected", + peer_set = ?peer_set, + version = %version, + peer = ?peer, + role = ?role + ); + + let local_view = { + let mut shared = shared.0.lock(); + let peer_map = match peer_set { + PeerSet::Validation => &mut shared.validation_peers, + PeerSet::Collation => &mut shared.collation_peers, + }; + + match peer_map.entry(peer) { + hash_map::Entry::Occupied(_) => continue, + hash_map::Entry::Vacant(vacant) => { + vacant.insert(PeerData { view: View::default(), version }); + }, + } + + metrics.on_peer_connected(peer_set, version); + metrics.note_peer_count(peer_set, version, peer_map.len()); + + shared.local_view.clone().unwrap_or(View::default()) + }; + + let maybe_authority = + authority_discovery_service.get_authority_ids_by_peer_id(peer).await; + + match peer_set { + PeerSet::Validation => { + dispatch_validation_events_to_all( + vec![ + NetworkBridgeEvent::PeerConnected( + peer, + role, + version, + maybe_authority, + ), + NetworkBridgeEvent::PeerViewChange(peer, View::default()), + ], + &mut sender, + ) + .await; + + match ValidationVersion::try_from(version) + .expect("try_get_protocol has already checked version is known; qed") + { + ValidationVersion::V1 => send_message( + &mut network_service, + vec![peer], + PeerSet::Validation, + version, + &peerset_protocol_names, + WireMessage::::ViewUpdate( + local_view, + ), + &metrics, + ), + ValidationVersion::VStaging => send_message( + &mut network_service, + vec![peer], + PeerSet::Validation, + version, + &peerset_protocol_names, + WireMessage::::ViewUpdate( + local_view, + ), + &metrics, + ), + } + }, + PeerSet::Collation => { + dispatch_collation_events_to_all( + vec![ + NetworkBridgeEvent::PeerConnected( + peer, + role, + version, + maybe_authority, + ), + NetworkBridgeEvent::PeerViewChange(peer, View::default()), + ], + &mut sender, + ) + .await; + + match CollationVersion::try_from(version) + .expect("try_get_protocol has already checked version is known; qed") + { + CollationVersion::V1 => send_message( + &mut network_service, + vec![peer], + PeerSet::Collation, + version, + &peerset_protocol_names, + WireMessage::::ViewUpdate( + local_view, + ), + &metrics, + ), + CollationVersion::VStaging => send_message( + &mut network_service, + vec![peer], + PeerSet::Collation, + version, + &peerset_protocol_names, + WireMessage::::ViewUpdate( + local_view, + ), + &metrics, + ), + } + }, + } + }, + Some(NetworkEvent::NotificationStreamClosed { remote: peer, protocol }) => { + let (peer_set, version) = match peerset_protocol_names.try_get_protocol(&protocol) { + None => continue, + Some(peer_set) => peer_set, + }; + + gum::debug!( + target: LOG_TARGET, + action = "PeerDisconnected", + peer_set = ?peer_set, + peer = ?peer + ); + + let was_connected = { + let mut shared = shared.0.lock(); + let peer_map = match peer_set { + PeerSet::Validation => &mut shared.validation_peers, + PeerSet::Collation => &mut shared.collation_peers, + }; + + let w = peer_map.remove(&peer).is_some(); + + metrics.on_peer_disconnected(peer_set, version); + metrics.note_peer_count(peer_set, version, peer_map.len()); + + w + }; + + if was_connected && version == peer_set.get_main_version() { + match peer_set { + PeerSet::Validation => + dispatch_validation_event_to_all( + NetworkBridgeEvent::PeerDisconnected(peer), + &mut sender, + ) + .await, + PeerSet::Collation => + dispatch_collation_event_to_all( + NetworkBridgeEvent::PeerDisconnected(peer), + &mut sender, + ) + .await, + } + } + }, + Some(NetworkEvent::NotificationsReceived { remote, messages }) => { + let expected_versions = { + let mut versions = PerPeerSet::>::default(); + let shared = shared.0.lock(); + if let Some(peer_data) = shared.validation_peers.get(&remote) { + versions[PeerSet::Validation] = Some(peer_data.version); + } + + if let Some(peer_data) = shared.collation_peers.get(&remote) { + versions[PeerSet::Collation] = Some(peer_data.version); + } + + versions + }; + + // non-decoded, but version-checked validation messages. + let v_messages: Result, _> = messages + .iter() + .filter_map(|(protocol, msg_bytes)| { + // version doesn't matter because we always receive on the 'correct' + // protocol name, not the negotiated fallback. + let (peer_set, _version) = + peerset_protocol_names.try_get_protocol(protocol)?; + if peer_set == PeerSet::Validation { + if expected_versions[PeerSet::Validation].is_none() { + return Some(Err(UNCONNECTED_PEERSET_COST)) + } + + Some(Ok(msg_bytes.clone())) + } else { + None + } + }) + .collect(); + + let v_messages = match v_messages { + Err(rep) => { + gum::debug!(target: LOG_TARGET, action = "ReportPeer"); + network_service.report_peer(remote, rep.into()); + + continue + }, + Ok(v) => v, + }; + + // non-decoded, but version-checked collation messages. + let c_messages: Result, _> = messages + .iter() + .filter_map(|(protocol, msg_bytes)| { + // version doesn't matter because we always receive on the 'correct' + // protocol name, not the negotiated fallback. + let (peer_set, _version) = + peerset_protocol_names.try_get_protocol(protocol)?; + + if peer_set == PeerSet::Collation { + if expected_versions[PeerSet::Collation].is_none() { + return Some(Err(UNCONNECTED_PEERSET_COST)) + } + + Some(Ok(msg_bytes.clone())) + } else { + None + } + }) + .collect(); + + let c_messages = match c_messages { + Err(rep) => { + gum::debug!(target: LOG_TARGET, action = "ReportPeer"); + network_service.report_peer(remote, rep.into()); + + continue + }, + Ok(v) => v, + }; + + if v_messages.is_empty() && c_messages.is_empty() { + continue + } + + gum::trace!( + target: LOG_TARGET, + action = "PeerMessages", + peer = ?remote, + num_validation_messages = %v_messages.len(), + num_collation_messages = %c_messages.len() + ); + + if !v_messages.is_empty() { + let (events, reports) = if expected_versions[PeerSet::Validation] == + Some(ValidationVersion::V1.into()) + { + handle_peer_messages::( + remote, + PeerSet::Validation, + &mut shared.0.lock().validation_peers, + v_messages, + &metrics, + ) + } else if expected_versions[PeerSet::Validation] == + Some(ValidationVersion::VStaging.into()) + { + handle_peer_messages::( + remote, + PeerSet::Validation, + &mut shared.0.lock().validation_peers, + v_messages, + &metrics, + ) + } else { + gum::warn!( + target: LOG_TARGET, + version = ?expected_versions[PeerSet::Validation], + "Major logic bug. Peer somehow has unsupported validation protocol version." + ); + + never!("Only versions 1 and 2 are supported; peer set connection checked above; qed"); + + // If a peer somehow triggers this, we'll disconnect them + // eventually. + (Vec::new(), vec![UNCONNECTED_PEERSET_COST]) + }; + + for report in reports { + network_service.report_peer(remote, report.into()); + } + + dispatch_validation_events_to_all(events, &mut sender).await; + } + + if !c_messages.is_empty() { + let (events, reports) = if expected_versions[PeerSet::Collation] == + Some(CollationVersion::V1.into()) + { + handle_peer_messages::( + remote, + PeerSet::Collation, + &mut shared.0.lock().collation_peers, + c_messages, + &metrics, + ) + } else if expected_versions[PeerSet::Collation] == + Some(CollationVersion::VStaging.into()) + { + handle_peer_messages::( + remote, + PeerSet::Collation, + &mut shared.0.lock().collation_peers, + c_messages, + &metrics, + ) + } else { + gum::warn!( + target: LOG_TARGET, + version = ?expected_versions[PeerSet::Collation], + "Major logic bug. Peer somehow has unsupported collation protocol version." + ); + + never!("Only versions 1 and 2 are supported; peer set connection checked above; qed"); + + // If a peer somehow triggers this, we'll disconnect them + // eventually. + (Vec::new(), vec![UNCONNECTED_PEERSET_COST]) + }; + + for report in reports { + network_service.report_peer(remote, report.into()); + } + + dispatch_collation_events_to_all(events, &mut sender).await; + } + }, + } + } +} + +async fn flesh_out_topology_peers(ads: &mut AD, neighbors: N) -> Vec +where + AD: validator_discovery::AuthorityDiscovery, + N: IntoIterator, + N::IntoIter: std::iter::ExactSizeIterator, +{ + let neighbors = neighbors.into_iter(); + let mut peers = Vec::with_capacity(neighbors.len()); + for (discovery_id, validator_index) in neighbors { + let addr = get_peer_id_by_authority_id(ads, discovery_id.clone()).await; + peers.push(TopologyPeerInfo { + peer_ids: addr.into_iter().collect(), + validator_index, + discovery_id, + }); + } + + peers +} + +#[overseer::contextbounds(NetworkBridgeRx, prefix = self::overseer)] +async fn run_incoming_orchestra_signals( + mut ctx: Context, + mut network_service: N, + mut authority_discovery_service: AD, + shared: Shared, + sync_oracle: Box, + metrics: Metrics, + peerset_protocol_names: PeerSetProtocolNames, +) -> Result<(), Error> +where + N: Network, + AD: validator_discovery::AuthorityDiscovery + Clone, +{ + // This is kept sorted, descending, by block number. + let mut live_heads: Vec = Vec::with_capacity(MAX_VIEW_HEADS); + let mut finalized_number = 0; + + let mut mode = Mode::Syncing(sync_oracle); + loop { + match ctx.recv().fuse().await? { + FromOrchestra::Communication { + msg: + NetworkBridgeRxMessage::NewGossipTopology { + session, + local_index, + canonical_shuffling, + shuffled_indices, + }, + } => { + gum::debug!( + target: LOG_TARGET, + action = "NewGossipTopology", + ?session, + ?local_index, + "Gossip topology has changed", + ); + + let topology_peers = + flesh_out_topology_peers(&mut authority_discovery_service, canonical_shuffling) + .await; + + dispatch_validation_event_to_all_unbounded( + NetworkBridgeEvent::NewGossipTopology(NewGossipTopology { + session, + topology: SessionGridTopology::new(shuffled_indices, topology_peers), + local_index, + }), + ctx.sender(), + ); + }, + FromOrchestra::Communication { + msg: NetworkBridgeRxMessage::UpdatedAuthorityIds { peer_id, authority_ids }, + } => { + gum::debug!( + target: LOG_TARGET, + action = "UpdatedAuthorityIds", + ?peer_id, + ?authority_ids, + "`AuthorityDiscoveryId`s have changed", + ); + // using unbounded send to avoid cycles + // the messages are sent only once per session up to one per peer + dispatch_collation_event_to_all_unbounded( + NetworkBridgeEvent::UpdatedAuthorityIds(peer_id, authority_ids.clone()), + ctx.sender(), + ); + dispatch_validation_event_to_all_unbounded( + NetworkBridgeEvent::UpdatedAuthorityIds(peer_id, authority_ids), + ctx.sender(), + ); + }, + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(active_leaves)) => { + let ActiveLeavesUpdate { activated, deactivated } = active_leaves; + gum::trace!( + target: LOG_TARGET, + action = "ActiveLeaves", + has_activated = activated.is_some(), + num_deactivated = %deactivated.len(), + ); + + if let Some(activated) = activated { + let pos = live_heads + .binary_search_by(|probe| probe.number.cmp(&activated.number).reverse()) + .unwrap_or_else(|i| i); + + live_heads.insert(pos, activated); + } + live_heads.retain(|h| !deactivated.contains(&h.hash)); + + // if we're done syncing, set the mode to `Mode::Active`. + // Otherwise, we don't need to send view updates. + { + let is_done_syncing = match mode { + Mode::Active => true, + Mode::Syncing(ref mut sync_oracle) => !sync_oracle.is_major_syncing(), + }; + + if is_done_syncing { + mode = Mode::Active; + + update_our_view( + &mut network_service, + &mut ctx, + &live_heads, + &shared, + finalized_number, + &metrics, + &peerset_protocol_names, + ); + } + } + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(_hash, number)) => { + gum::trace!(target: LOG_TARGET, action = "BlockFinalized"); + + debug_assert!(finalized_number < number); + + // we don't send the view updates here, but delay them until the next `ActiveLeaves` + // otherwise it might break assumptions of some of the subsystems + // that we never send the same `ActiveLeavesUpdate` + finalized_number = number; + }, + } + } +} + +/// Main driver, processing network events and overseer signals. +/// +/// THIS IS A HACK. We need to ensure we never hold the mutex across an `.await` boundary +/// and `parking_lot` currently does not provide `Send`, which helps us enforce that. +/// If this breaks, we need to find another way to protect ourselves. +/// +/// ```compile_fail +/// #use parking_lot::MutexGuard; +/// #fn is_send(); +/// #is_send::(); +/// ``` +#[overseer::contextbounds(NetworkBridgeRx, prefix = self::overseer)] +async fn run_network_in( + bridge: NetworkBridgeRx, + mut ctx: Context, + network_stream: BoxStream<'static, NetworkEvent>, +) -> Result<(), Error> +where + N: Network, + AD: validator_discovery::AuthorityDiscovery + Clone, +{ + let NetworkBridgeRx { + network_service, + authority_discovery_service, + metrics, + sync_oracle, + shared, + peerset_protocol_names, + } = bridge; + + let (task, network_event_handler) = handle_network_messages( + ctx.sender().clone(), + network_service.clone(), + network_stream, + authority_discovery_service.clone(), + metrics.clone(), + shared.clone(), + peerset_protocol_names.clone(), + ) + .remote_handle(); + + ctx.spawn_blocking("network-bridge-in-network-worker", Box::pin(task))?; + futures::pin_mut!(network_event_handler); + + let orchestra_signal_handler = run_incoming_orchestra_signals( + ctx, + network_service, + authority_discovery_service, + shared, + sync_oracle, + metrics, + peerset_protocol_names, + ); + + futures::pin_mut!(orchestra_signal_handler); + + futures::future::select(orchestra_signal_handler, network_event_handler) + .await + .factor_first() + .0?; + Ok(()) +} + +fn construct_view( + live_heads: impl DoubleEndedIterator, + finalized_number: BlockNumber, +) -> View { + View::new(live_heads.take(MAX_VIEW_HEADS), finalized_number) +} + +#[overseer::contextbounds(NetworkBridgeRx, prefix = self::overseer)] +fn update_our_view( + net: &mut Net, + ctx: &mut Context, + live_heads: &[ActivatedLeaf], + shared: &Shared, + finalized_number: BlockNumber, + metrics: &Metrics, + peerset_protocol_names: &PeerSetProtocolNames, +) where + Net: Network, +{ + let new_view = construct_view(live_heads.iter().map(|v| v.hash), finalized_number); + + let (validation_peers, collation_peers) = { + let mut shared = shared.0.lock(); + + // We only want to send a view update when the heads changed. + // A change in finalized block number only is _not_ sufficient. + // + // If this is the first view update since becoming active, but our view is empty, + // there is no need to send anything. + match shared.local_view { + Some(ref v) if v.check_heads_eq(&new_view) => return, + None if live_heads.is_empty() => { + shared.local_view = Some(new_view); + return + }, + _ => { + shared.local_view = Some(new_view.clone()); + }, + } + + ( + shared + .validation_peers + .iter() + .map(|(peer_id, data)| (*peer_id, data.version)) + .collect::>(), + shared + .collation_peers + .iter() + .map(|(peer_id, data)| (*peer_id, data.version)) + .collect::>(), + ) + }; + + let filter_by_version = |peers: &[(PeerId, ProtocolVersion)], version| { + peers.iter().filter(|(_, v)| v == &version).map(|(p, _)| *p).collect::>() + }; + + let v1_validation_peers = filter_by_version(&validation_peers, ValidationVersion::V1.into()); + let v1_collation_peers = filter_by_version(&collation_peers, CollationVersion::V1.into()); + + let vstaging_validation_peers = + filter_by_version(&validation_peers, ValidationVersion::VStaging.into()); + let vstaging_collation_peers = + filter_by_version(&collation_peers, ValidationVersion::VStaging.into()); + + send_validation_message_v1( + net, + v1_validation_peers, + peerset_protocol_names, + WireMessage::ViewUpdate(new_view.clone()), + metrics, + ); + + send_collation_message_v1( + net, + v1_collation_peers, + peerset_protocol_names, + WireMessage::ViewUpdate(new_view.clone()), + metrics, + ); + + send_validation_message_vstaging( + net, + vstaging_validation_peers, + peerset_protocol_names, + WireMessage::ViewUpdate(new_view.clone()), + metrics, + ); + + send_collation_message_vstaging( + net, + vstaging_collation_peers, + peerset_protocol_names, + WireMessage::ViewUpdate(new_view), + metrics, + ); + + let our_view = OurView::new( + live_heads.iter().take(MAX_VIEW_HEADS).cloned().map(|a| (a.hash, a.span)), + finalized_number, + ); + + dispatch_validation_event_to_all_unbounded( + NetworkBridgeEvent::OurViewChange(our_view.clone()), + ctx.sender(), + ); + + dispatch_collation_event_to_all_unbounded( + NetworkBridgeEvent::OurViewChange(our_view), + ctx.sender(), + ); +} + +// Handle messages on a specific v1 peer-set. The peer is expected to be connected on that +// peer-set. +fn handle_peer_messages>( + peer: PeerId, + peer_set: PeerSet, + peers: &mut HashMap, + messages: Vec, + metrics: &Metrics, +) -> (Vec>, Vec) { + let peer_data = match peers.get_mut(&peer) { + None => return (Vec::new(), vec![UNCONNECTED_PEERSET_COST]), + Some(d) => d, + }; + + let mut outgoing_events = Vec::with_capacity(messages.len()); + let mut reports = Vec::new(); + + for message in messages { + metrics.on_notification_received(peer_set, peer_data.version, message.len()); + let message = match WireMessage::::decode_all(&mut message.as_ref()) { + Err(_) => { + reports.push(MALFORMED_MESSAGE_COST); + continue + }, + Ok(m) => m, + }; + + outgoing_events.push(match message { + WireMessage::ViewUpdate(new_view) => { + if new_view.len() > MAX_VIEW_HEADS || + new_view.finalized_number < peer_data.view.finalized_number + { + reports.push(MALFORMED_VIEW_COST); + continue + } else if new_view.is_empty() { + reports.push(EMPTY_VIEW_COST); + continue + } else if new_view == peer_data.view { + continue + } else { + peer_data.view = new_view; + + NetworkBridgeEvent::PeerViewChange(peer, peer_data.view.clone()) + } + }, + WireMessage::ProtocolMessage(message) => + NetworkBridgeEvent::PeerMessage(peer, message.into()), + }) + } + + (outgoing_events, reports) +} + +fn send_validation_message_v1( + net: &mut impl Network, + peers: Vec, + peerset_protocol_names: &PeerSetProtocolNames, + message: WireMessage, + metrics: &Metrics, +) { + send_message( + net, + peers, + PeerSet::Validation, + ValidationVersion::V1.into(), + peerset_protocol_names, + message, + metrics, + ); +} + +fn send_collation_message_v1( + net: &mut impl Network, + peers: Vec, + peerset_protocol_names: &PeerSetProtocolNames, + message: WireMessage, + metrics: &Metrics, +) { + send_message( + net, + peers, + PeerSet::Collation, + CollationVersion::V1.into(), + peerset_protocol_names, + message, + metrics, + ); +} + +fn send_validation_message_vstaging( + net: &mut impl Network, + peers: Vec, + protocol_names: &PeerSetProtocolNames, + message: WireMessage, + metrics: &Metrics, +) { + send_message( + net, + peers, + PeerSet::Validation, + ValidationVersion::VStaging.into(), + protocol_names, + message, + metrics, + ); +} + +fn send_collation_message_vstaging( + net: &mut impl Network, + peers: Vec, + protocol_names: &PeerSetProtocolNames, + message: WireMessage, + metrics: &Metrics, +) { + send_message( + net, + peers, + PeerSet::Collation, + CollationVersion::VStaging.into(), + protocol_names, + message, + metrics, + ); +} + +async fn dispatch_validation_event_to_all( + event: NetworkBridgeEvent, + ctx: &mut impl overseer::NetworkBridgeRxSenderTrait, +) { + dispatch_validation_events_to_all(std::iter::once(event), ctx).await +} + +async fn dispatch_collation_event_to_all( + event: NetworkBridgeEvent, + ctx: &mut impl overseer::NetworkBridgeRxSenderTrait, +) { + dispatch_collation_events_to_all(std::iter::once(event), ctx).await +} + +fn dispatch_validation_event_to_all_unbounded( + event: NetworkBridgeEvent, + sender: &mut impl overseer::NetworkBridgeRxSenderTrait, +) { + event + .focus() + .ok() + .map(StatementDistributionMessage::from) + .and_then(|msg| Some(sender.send_unbounded_message(msg))); + event + .focus() + .ok() + .map(BitfieldDistributionMessage::from) + .and_then(|msg| Some(sender.send_unbounded_message(msg))); + event + .focus() + .ok() + .map(ApprovalDistributionMessage::from) + .and_then(|msg| Some(sender.send_unbounded_message(msg))); + event + .focus() + .ok() + .map(GossipSupportMessage::from) + .and_then(|msg| Some(sender.send_unbounded_message(msg))); +} + +fn dispatch_collation_event_to_all_unbounded( + event: NetworkBridgeEvent, + sender: &mut impl overseer::NetworkBridgeRxSenderTrait, +) { + if let Ok(msg) = event.focus() { + sender.send_unbounded_message(CollatorProtocolMessage::NetworkBridgeUpdate(msg)) + } +} + +async fn dispatch_validation_events_to_all( + events: I, + sender: &mut impl overseer::NetworkBridgeRxSenderTrait, +) where + I: IntoIterator>, + I::IntoIter: Send, +{ + for event in events { + sender + .send_messages(event.focus().map(StatementDistributionMessage::from)) + .await; + sender.send_messages(event.focus().map(BitfieldDistributionMessage::from)).await; + sender.send_messages(event.focus().map(ApprovalDistributionMessage::from)).await; + sender.send_messages(event.focus().map(GossipSupportMessage::from)).await; + } +} + +async fn dispatch_collation_events_to_all( + events: I, + ctx: &mut impl overseer::NetworkBridgeRxSenderTrait, +) where + I: IntoIterator>, + I::IntoIter: Send, +{ + let messages_for = |event: NetworkBridgeEvent| { + event.focus().ok().map(|m| CollatorProtocolMessage::NetworkBridgeUpdate(m)) + }; + + ctx.send_messages(events.into_iter().flat_map(messages_for)).await +} diff --git a/polkadot/node/network/bridge/src/rx/tests.rs b/polkadot/node/network/bridge/src/rx/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..88a4b247fdc6f6d7d24d4facceea7a558b53c31c --- /dev/null +++ b/polkadot/node/network/bridge/src/rx/tests.rs @@ -0,0 +1,1410 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use futures::{channel::oneshot, executor, stream::BoxStream}; +use polkadot_node_network_protocol::{self as net_protocol, OurView}; +use polkadot_node_subsystem::{messages::NetworkBridgeEvent, ActivatedLeaf}; + +use assert_matches::assert_matches; +use async_trait::async_trait; +use parking_lot::Mutex; +use std::{ + collections::HashSet, + sync::atomic::{AtomicBool, Ordering}, + task::Poll, +}; + +use sc_network::{Event as NetworkEvent, IfDisconnected, ProtocolName, ReputationChange}; + +use polkadot_node_network_protocol::{ + peer_set::PeerSetProtocolNames, + request_response::{outgoing::Requests, ReqProtocolNames}, + view, ObservedRole, Versioned, +}; +use polkadot_node_subsystem::{ + jaeger, + messages::{ + AllMessages, ApprovalDistributionMessage, BitfieldDistributionMessage, + GossipSupportMessage, StatementDistributionMessage, + }, + ActiveLeavesUpdate, FromOrchestra, LeafStatus, OverseerSignal, +}; +use polkadot_node_subsystem_test_helpers::{ + SingleItemSink, SingleItemStream, TestSubsystemContextHandle, +}; +use polkadot_node_subsystem_util::metered; +use polkadot_primitives::{AuthorityDiscoveryId, CandidateHash, Hash}; + +use sc_network::Multiaddr; +use sp_keyring::Sr25519Keyring; + +use crate::{network::Network, validator_discovery::AuthorityDiscovery}; + +#[derive(Debug, PartialEq)] +pub enum NetworkAction { + /// Note a change in reputation for a peer. + ReputationChange(PeerId, ReputationChange), + /// Disconnect a peer from the given peer-set. + DisconnectPeer(PeerId, PeerSet), + /// Write a notification to a given peer on the given peer-set. + WriteNotification(PeerId, PeerSet, Vec), +} + +// The subsystem's view of the network - only supports a single call to `event_stream`. +#[derive(Clone)] +struct TestNetwork { + net_events: Arc>>>, + action_tx: Arc>>, + protocol_names: Arc, +} + +#[derive(Clone, Debug)] +struct TestAuthorityDiscovery; + +// The test's view of the network. This receives updates from the subsystem in the form +// of `NetworkAction`s. +struct TestNetworkHandle { + action_rx: metered::UnboundedMeteredReceiver, + net_tx: SingleItemSink, + protocol_names: PeerSetProtocolNames, +} + +fn new_test_network( + protocol_names: PeerSetProtocolNames, +) -> (TestNetwork, TestNetworkHandle, TestAuthorityDiscovery) { + let (net_tx, net_rx) = polkadot_node_subsystem_test_helpers::single_item_sink(); + let (action_tx, action_rx) = metered::unbounded(); + + ( + TestNetwork { + net_events: Arc::new(Mutex::new(Some(net_rx))), + action_tx: Arc::new(Mutex::new(action_tx)), + protocol_names: Arc::new(protocol_names.clone()), + }, + TestNetworkHandle { action_rx, net_tx, protocol_names }, + TestAuthorityDiscovery, + ) +} + +#[async_trait] +impl Network for TestNetwork { + fn event_stream(&mut self) -> BoxStream<'static, NetworkEvent> { + self.net_events + .lock() + .take() + .expect("Subsystem made more than one call to `event_stream`") + .boxed() + } + + async fn set_reserved_peers( + &mut self, + _protocol: ProtocolName, + _: HashSet, + ) -> Result<(), String> { + Ok(()) + } + + async fn remove_from_peers_set( + &mut self, + _protocol: ProtocolName, + _: Vec, + ) -> Result<(), String> { + Ok(()) + } + + async fn start_request( + &self, + _: &mut AD, + _: Requests, + _: &ReqProtocolNames, + _: IfDisconnected, + ) { + } + + fn report_peer(&self, who: PeerId, rep: ReputationChange) { + self.action_tx + .lock() + .unbounded_send(NetworkAction::ReputationChange(who, rep)) + .unwrap(); + } + + fn disconnect_peer(&self, who: PeerId, protocol: ProtocolName) { + let (peer_set, _) = self.protocol_names.try_get_protocol(&protocol).unwrap(); + + self.action_tx + .lock() + .unbounded_send(NetworkAction::DisconnectPeer(who, peer_set)) + .unwrap(); + } + + fn write_notification(&self, who: PeerId, protocol: ProtocolName, message: Vec) { + let (peer_set, _) = self.protocol_names.try_get_protocol(&protocol).unwrap(); + + self.action_tx + .lock() + .unbounded_send(NetworkAction::WriteNotification(who, peer_set, message)) + .unwrap(); + } +} + +#[async_trait] +impl validator_discovery::AuthorityDiscovery for TestAuthorityDiscovery { + async fn get_addresses_by_authority_id( + &mut self, + _authority: AuthorityDiscoveryId, + ) -> Option> { + None + } + + async fn get_authority_ids_by_peer_id( + &mut self, + _peer_id: PeerId, + ) -> Option> { + None + } +} + +impl TestNetworkHandle { + // Get the next network action. + async fn next_network_action(&mut self) -> NetworkAction { + self.action_rx.next().await.expect("subsystem concluded early") + } + + // Wait for the next N network actions. + async fn next_network_actions(&mut self, n: usize) -> Vec { + let mut v = Vec::with_capacity(n); + for _ in 0..n { + v.push(self.next_network_action().await); + } + + v + } + + async fn connect_peer( + &mut self, + peer: PeerId, + protocol_version: ValidationVersion, + peer_set: PeerSet, + role: ObservedRole, + ) { + let protocol_version = ProtocolVersion::from(protocol_version); + self.send_network_event(NetworkEvent::NotificationStreamOpened { + remote: peer, + protocol: self.protocol_names.get_name(peer_set, protocol_version), + negotiated_fallback: None, + role: role.into(), + received_handshake: vec![], + }) + .await; + } + + async fn disconnect_peer(&mut self, peer: PeerId, peer_set: PeerSet) { + self.send_network_event(NetworkEvent::NotificationStreamClosed { + remote: peer, + protocol: self.protocol_names.get_main_name(peer_set), + }) + .await; + } + + async fn peer_message(&mut self, peer: PeerId, peer_set: PeerSet, message: Vec) { + self.send_network_event(NetworkEvent::NotificationsReceived { + remote: peer, + messages: vec![(self.protocol_names.get_main_name(peer_set), message.into())], + }) + .await; + } + + async fn send_network_event(&mut self, event: NetworkEvent) { + self.net_tx.send(event).await.expect("subsystem concluded early"); + } +} + +/// Assert that the given actions contain the given `action`. +fn assert_network_actions_contains(actions: &[NetworkAction], action: &NetworkAction) { + if !actions.iter().any(|x| x == action) { + panic!("Could not find `{:?}` in `{:?}`", action, actions); + } +} + +#[derive(Clone)] +struct TestSyncOracle { + is_major_syncing: Arc, + done_syncing_sender: Arc>>>, +} + +struct TestSyncOracleHandle { + done_syncing_receiver: oneshot::Receiver<()>, + is_major_syncing: Arc, +} + +impl TestSyncOracleHandle { + fn set_done(&self) { + self.is_major_syncing.store(false, Ordering::SeqCst); + } + + async fn await_mode_switch(self) { + let _ = self.done_syncing_receiver.await; + } +} + +impl SyncOracle for TestSyncOracle { + fn is_major_syncing(&self) -> bool { + let is_major_syncing = self.is_major_syncing.load(Ordering::SeqCst); + + if !is_major_syncing { + if let Some(sender) = self.done_syncing_sender.lock().take() { + let _ = sender.send(()); + } + } + + is_major_syncing + } + + fn is_offline(&self) -> bool { + unimplemented!("not used in network bridge") + } +} + +// val - result of `is_major_syncing`. +fn make_sync_oracle(is_major_syncing: bool) -> (TestSyncOracle, TestSyncOracleHandle) { + let (tx, rx) = oneshot::channel(); + let is_major_syncing = Arc::new(AtomicBool::new(is_major_syncing)); + + ( + TestSyncOracle { + is_major_syncing: is_major_syncing.clone(), + done_syncing_sender: Arc::new(Mutex::new(Some(tx))), + }, + TestSyncOracleHandle { is_major_syncing, done_syncing_receiver: rx }, + ) +} + +fn done_syncing_oracle() -> Box { + let (oracle, _) = make_sync_oracle(false); + Box::new(oracle) +} + +type VirtualOverseer = TestSubsystemContextHandle; + +struct TestHarness { + network_handle: TestNetworkHandle, + virtual_overseer: VirtualOverseer, + shared: Shared, +} + +// wait until all needed validation and collation peers have connected. +async fn await_peer_connections( + shared: &Shared, + num_validation_peers: usize, + num_collation_peers: usize, +) { + loop { + { + let shared = shared.0.lock(); + if shared.validation_peers.len() == num_validation_peers && + shared.collation_peers.len() == num_collation_peers + { + break + } + } + + futures_timer::Delay::new(std::time::Duration::from_millis(100)).await; + } +} + +fn test_harness>( + sync_oracle: Box, + test: impl FnOnce(TestHarness) -> T, +) { + let genesis_hash = Hash::repeat_byte(0xff); + let fork_id = None; + let peerset_protocol_names = PeerSetProtocolNames::new(genesis_hash, fork_id); + + let pool = sp_core::testing::TaskExecutor::new(); + let (mut network, network_handle, discovery) = new_test_network(peerset_protocol_names.clone()); + let (context, virtual_overseer) = + polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); + let network_stream = network.event_stream(); + let shared = Shared::default(); + + let bridge = NetworkBridgeRx { + network_service: network, + authority_discovery_service: discovery, + metrics: Metrics(None), + sync_oracle, + shared: shared.clone(), + peerset_protocol_names, + }; + + let network_bridge = run_network_in(bridge, context, network_stream) + .map_err(|_| panic!("subsystem execution failed")) + .map(|_| ()); + + let test_fut = test(TestHarness { network_handle, virtual_overseer, shared }); + + futures::pin_mut!(test_fut); + futures::pin_mut!(network_bridge); + + let _ = executor::block_on(future::join( + async move { + let mut virtual_overseer = test_fut.await; + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }, + network_bridge, + )); +} + +async fn assert_sends_validation_event_to_all( + event: NetworkBridgeEvent, + virtual_overseer: &mut TestSubsystemContextHandle, +) { + // Ordering must be consistent across: + // `fn dispatch_validation_event_to_all_unbounded` + // `dispatch_validation_events_to_all` + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::NetworkBridgeUpdate(e) + ) if e == event.focus().expect("could not focus message") + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::BitfieldDistribution( + BitfieldDistributionMessage::NetworkBridgeUpdate(e) + ) if e == event.focus().expect("could not focus message") + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ApprovalDistribution( + ApprovalDistributionMessage::NetworkBridgeUpdate(e) + ) if e == event.focus().expect("could not focus message") + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::GossipSupport( + GossipSupportMessage::NetworkBridgeUpdate(e) + ) if e == event.focus().expect("could not focus message") + ); +} + +async fn assert_sends_collation_event_to_all( + event: NetworkBridgeEvent, + virtual_overseer: &mut TestSubsystemContextHandle, +) { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol( + CollatorProtocolMessage::NetworkBridgeUpdate(e) + ) if e == event.focus().expect("could not focus message") + ) +} + +#[test] +fn send_our_view_upon_connection() { + let (oracle, handle) = make_sync_oracle(false); + test_harness(Box::new(oracle), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, shared } = test_harness; + + let peer = PeerId::random(); + + let head = Hash::repeat_byte(1); + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: head, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + handle.await_mode_switch().await; + + network_handle + .connect_peer(peer, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer, ValidationVersion::V1, PeerSet::Collation, ObservedRole::Full) + .await; + + await_peer_connections(&shared, 1, 1).await; + + let view = view![head]; + let actions = network_handle.next_network_actions(2).await; + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification( + peer, + PeerSet::Validation, + WireMessage::::ViewUpdate(view.clone()).encode(), + ), + ); + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification( + peer, + PeerSet::Collation, + WireMessage::::ViewUpdate(view.clone()).encode(), + ), + ); + virtual_overseer + }); +} + +#[test] +fn sends_view_updates_to_peers() { + let (oracle, handle) = make_sync_oracle(false); + test_harness(Box::new(oracle), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, shared } = test_harness; + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated: Default::default(), + deactivated: Default::default(), + }))) + .await; + + handle.await_mode_switch().await; + + network_handle + .connect_peer(peer_a, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer_b, ValidationVersion::V1, PeerSet::Collation, ObservedRole::Full) + .await; + + await_peer_connections(&shared, 1, 1).await; + + let actions = network_handle.next_network_actions(2).await; + let wire_message = + WireMessage::::ViewUpdate(View::default()).encode(); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification(peer_a, PeerSet::Validation, wire_message.clone()), + ); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification(peer_b, PeerSet::Collation, wire_message.clone()), + ); + + let hash_a = Hash::repeat_byte(1); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + let actions = network_handle.next_network_actions(2).await; + let wire_message = + WireMessage::::ViewUpdate(view![hash_a]).encode(); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification(peer_a, PeerSet::Validation, wire_message.clone()), + ); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification(peer_b, PeerSet::Collation, wire_message.clone()), + ); + virtual_overseer + }); +} + +#[test] +fn do_not_send_view_update_until_synced() { + let (oracle, handle) = make_sync_oracle(true); + test_harness(Box::new(oracle), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, shared } = test_harness; + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + assert_ne!(peer_a, peer_b); + + network_handle + .connect_peer(peer_a, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer_b, ValidationVersion::V1, PeerSet::Collation, ObservedRole::Full) + .await; + + await_peer_connections(&shared, 1, 1).await; + + { + let actions = network_handle.next_network_actions(2).await; + let wire_message = + WireMessage::::ViewUpdate(View::default()) + .encode(); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification( + peer_a, + PeerSet::Validation, + wire_message.clone(), + ), + ); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification(peer_b, PeerSet::Collation, wire_message.clone()), + ); + } + + let hash_a = Hash::repeat_byte(1); + let hash_b = Hash::repeat_byte(1); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + // delay until the previous update has certainly been processed. + futures_timer::Delay::new(std::time::Duration::from_millis(100)).await; + + handle.set_done(); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_b, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + handle.await_mode_switch().await; + + // There should be a mode switch only for the second view update. + { + let actions = network_handle.next_network_actions(2).await; + let wire_message = + WireMessage::::ViewUpdate(view![hash_a, hash_b]) + .encode(); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification( + peer_a, + PeerSet::Validation, + wire_message.clone(), + ), + ); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification(peer_b, PeerSet::Collation, wire_message.clone()), + ); + } + virtual_overseer + }); +} + +#[test] +fn do_not_send_view_update_when_only_finalized_block_changed() { + test_harness(done_syncing_oracle(), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, shared } = test_harness; + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + + network_handle + .connect_peer(peer_a, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer_b, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + + await_peer_connections(&shared, 2, 0).await; + + let hash_a = Hash::repeat_byte(1); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::BlockFinalized(Hash::random(), 5))) + .await; + + // Send some empty active leaves update + // + // This should not trigger a view update to our peers. + virtual_overseer + .send(FromOrchestra::Signal( + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::default()), + )) + .await; + + // This should trigger the view update to our peers. + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + let actions = network_handle.next_network_actions(4).await; + let wire_message = + WireMessage::::ViewUpdate(View::new(vec![hash_a], 5)) + .encode(); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification(peer_a, PeerSet::Validation, wire_message.clone()), + ); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification(peer_b, PeerSet::Validation, wire_message.clone()), + ); + virtual_overseer + }); +} + +#[test] +fn peer_view_updates_sent_via_overseer() { + test_harness(done_syncing_oracle(), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, shared } = test_harness; + + let peer = PeerId::random(); + + network_handle + .connect_peer(peer, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + + await_peer_connections(&shared, 1, 0).await; + + let view = view![Hash::repeat_byte(1)]; + + // bridge will inform about all connected peers. + { + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + &mut virtual_overseer, + ) + .await; + + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer, View::default()), + &mut virtual_overseer, + ) + .await; + } + + network_handle + .peer_message( + peer, + PeerSet::Validation, + WireMessage::::ViewUpdate(view.clone()).encode(), + ) + .await; + + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer, view), + &mut virtual_overseer, + ) + .await; + virtual_overseer + }); +} + +#[test] +fn peer_messages_sent_via_overseer() { + test_harness(done_syncing_oracle(), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, shared } = test_harness; + + let peer = PeerId::random(); + + network_handle + .connect_peer(peer, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + + await_peer_connections(&shared, 1, 0).await; + + // bridge will inform about all connected peers. + { + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + &mut virtual_overseer, + ) + .await; + + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer, View::default()), + &mut virtual_overseer, + ) + .await; + } + + let approval_distribution_message = + protocol_v1::ApprovalDistributionMessage::Approvals(Vec::new()); + + let message_v1 = protocol_v1::ValidationProtocol::ApprovalDistribution( + approval_distribution_message.clone(), + ); + + network_handle + .peer_message( + peer, + PeerSet::Validation, + WireMessage::ProtocolMessage(message_v1.clone()).encode(), + ) + .await; + + network_handle.disconnect_peer(peer, PeerSet::Validation).await; + + // Approval distribution message comes first, and the message is only sent to that + // subsystem. then a disconnection event arises that is sent to all validation networking + // subsystems. + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ApprovalDistribution( + ApprovalDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage(p, Versioned::V1(m)) + ) + ) => { + assert_eq!(p, peer); + assert_eq!(m, approval_distribution_message); + } + ); + + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerDisconnected(peer), + &mut virtual_overseer, + ) + .await; + virtual_overseer + }); +} + +#[test] +fn peer_disconnect_from_just_one_peerset() { + test_harness(done_syncing_oracle(), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, shared } = test_harness; + + let peer = PeerId::random(); + + network_handle + .connect_peer(peer, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer, ValidationVersion::V1, PeerSet::Collation, ObservedRole::Full) + .await; + + await_peer_connections(&shared, 1, 1).await; + + // bridge will inform about all connected peers. + { + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + &mut virtual_overseer, + ) + .await; + + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer, View::default()), + &mut virtual_overseer, + ) + .await; + } + + { + assert_sends_collation_event_to_all( + NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + &mut virtual_overseer, + ) + .await; + + assert_sends_collation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer, View::default()), + &mut virtual_overseer, + ) + .await; + } + + network_handle.disconnect_peer(peer, PeerSet::Validation).await; + + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerDisconnected(peer), + &mut virtual_overseer, + ) + .await; + + // to show that we're still connected on the collation protocol, send a view update. + + let hash_a = Hash::repeat_byte(1); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + let actions = network_handle.next_network_actions(3).await; + let wire_message = + WireMessage::::ViewUpdate(view![hash_a]).encode(); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification(peer, PeerSet::Collation, wire_message.clone()), + ); + virtual_overseer + }); +} + +#[test] +fn relays_collation_protocol_messages() { + test_harness(done_syncing_oracle(), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, shared } = test_harness; + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + + network_handle + .connect_peer(peer_a, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer_b, ValidationVersion::V1, PeerSet::Collation, ObservedRole::Full) + .await; + + await_peer_connections(&shared, 1, 1).await; + + // bridge will inform about all connected peers. + { + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerConnected( + peer_a, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + &mut virtual_overseer, + ) + .await; + + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer_a, View::default()), + &mut virtual_overseer, + ) + .await; + } + + { + assert_sends_collation_event_to_all( + NetworkBridgeEvent::PeerConnected( + peer_b, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + &mut virtual_overseer, + ) + .await; + + assert_sends_collation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer_b, View::default()), + &mut virtual_overseer, + ) + .await; + } + + // peer A gets reported for sending a collation message. + + let collator_protocol_message = protocol_v1::CollatorProtocolMessage::Declare( + Sr25519Keyring::Alice.public().into(), + Default::default(), + sp_core::crypto::UncheckedFrom::unchecked_from([1u8; 64]), + ); + + let message_v1 = + protocol_v1::CollationProtocol::CollatorProtocol(collator_protocol_message.clone()); + + network_handle + .peer_message( + peer_a, + PeerSet::Collation, + WireMessage::ProtocolMessage(message_v1.clone()).encode(), + ) + .await; + + let actions = network_handle.next_network_actions(3).await; + assert_network_actions_contains( + &actions, + &NetworkAction::ReputationChange(peer_a, UNCONNECTED_PEERSET_COST.into()), + ); + + // peer B has the message relayed. + + network_handle + .peer_message( + peer_b, + PeerSet::Collation, + WireMessage::ProtocolMessage(message_v1.clone()).encode(), + ) + .await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CollatorProtocol( + CollatorProtocolMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage(p, Versioned::V1(m)) + ) + ) => { + assert_eq!(p, peer_b); + assert_eq!(m, collator_protocol_message); + } + ); + virtual_overseer + }); +} + +#[test] +fn different_views_on_different_peer_sets() { + test_harness(done_syncing_oracle(), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, shared } = test_harness; + + let peer = PeerId::random(); + + network_handle + .connect_peer(peer, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer, ValidationVersion::V1, PeerSet::Collation, ObservedRole::Full) + .await; + + await_peer_connections(&shared, 1, 1).await; + + // bridge will inform about all connected peers. + { + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + &mut virtual_overseer, + ) + .await; + + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer, View::default()), + &mut virtual_overseer, + ) + .await; + } + + { + assert_sends_collation_event_to_all( + NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + &mut virtual_overseer, + ) + .await; + + assert_sends_collation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer, View::default()), + &mut virtual_overseer, + ) + .await; + } + + let view_a = view![Hash::repeat_byte(1)]; + let view_b = view![Hash::repeat_byte(2)]; + + network_handle + .peer_message( + peer, + PeerSet::Validation, + WireMessage::::ViewUpdate(view_a.clone()).encode(), + ) + .await; + + network_handle + .peer_message( + peer, + PeerSet::Collation, + WireMessage::::ViewUpdate(view_b.clone()).encode(), + ) + .await; + + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer, view_a.clone()), + &mut virtual_overseer, + ) + .await; + + assert_sends_collation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer, view_b.clone()), + &mut virtual_overseer, + ) + .await; + virtual_overseer + }); +} + +#[test] +fn sent_views_include_finalized_number_update() { + test_harness(done_syncing_oracle(), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, shared } = test_harness; + + let peer_a = PeerId::random(); + + network_handle + .connect_peer(peer_a, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + + await_peer_connections(&shared, 1, 0).await; + + let hash_a = Hash::repeat_byte(1); + let hash_b = Hash::repeat_byte(2); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::BlockFinalized(hash_a, 1))) + .await; + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_b, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + let actions = network_handle.next_network_actions(2).await; + let wire_message = + WireMessage::::ViewUpdate(View::new(vec![hash_b], 1)) + .encode(); + + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification(peer_a, PeerSet::Validation, wire_message.clone()), + ); + virtual_overseer + }); +} + +#[test] +fn view_finalized_number_can_not_go_down() { + test_harness(done_syncing_oracle(), |test_harness| async move { + let TestHarness { mut network_handle, virtual_overseer, shared } = test_harness; + + let peer_a = PeerId::random(); + + network_handle + .connect_peer(peer_a, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .await; + + await_peer_connections(&shared, 1, 0).await; + + network_handle + .peer_message( + peer_a, + PeerSet::Validation, + WireMessage::::ViewUpdate(View::new( + vec![Hash::repeat_byte(0x01)], + 1, + )) + .encode(), + ) + .await; + + network_handle + .peer_message( + peer_a, + PeerSet::Validation, + WireMessage::::ViewUpdate(View::new(vec![], 0)) + .encode(), + ) + .await; + + let actions = network_handle.next_network_actions(2).await; + assert_network_actions_contains( + &actions, + &NetworkAction::ReputationChange(peer_a, MALFORMED_VIEW_COST.into()), + ); + virtual_overseer + }); +} + +#[test] +fn our_view_updates_decreasing_order_and_limited_to_max() { + test_harness(done_syncing_oracle(), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + // to show that we're still connected on the collation protocol, send a view update. + + let hashes = (0..MAX_VIEW_HEADS + 1).map(|i| Hash::repeat_byte(i as u8)); + + for (i, hash) in hashes.enumerate().rev() { + // These are in reverse order, so the subsystem must sort internally to + // get the correct view. + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash, + number: i as _, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + } + + let our_views = (1..=MAX_VIEW_HEADS).rev().map(|start| { + OurView::new( + (start..=MAX_VIEW_HEADS) + .rev() + .map(|i| (Hash::repeat_byte(i as u8), Arc::new(jaeger::Span::Disabled))), + 0, + ) + }); + + for our_view in our_views { + assert_sends_validation_event_to_all( + NetworkBridgeEvent::OurViewChange(our_view.clone()), + &mut virtual_overseer, + ) + .await; + + assert_sends_collation_event_to_all( + NetworkBridgeEvent::OurViewChange(our_view), + &mut virtual_overseer, + ) + .await; + } + + virtual_overseer + }); +} + +#[test] +fn network_protocol_versioning_view_update() { + let (oracle, handle) = make_sync_oracle(false); + test_harness(Box::new(oracle), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, .. } = test_harness; + + let peer_ids: Vec<_> = (0..4).map(|_| PeerId::random()).collect(); + let peers = [ + (peer_ids[0], PeerSet::Validation, ValidationVersion::VStaging), + (peer_ids[1], PeerSet::Collation, ValidationVersion::V1), + (peer_ids[2], PeerSet::Validation, ValidationVersion::V1), + (peer_ids[3], PeerSet::Collation, ValidationVersion::VStaging), + ]; + + let head = Hash::repeat_byte(1); + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: head, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + handle.await_mode_switch().await; + + for &(peer_id, peer_set, version) in &peers { + network_handle + .connect_peer(peer_id, version, peer_set, ObservedRole::Full) + .await; + } + + let view = view![head]; + let actions = network_handle.next_network_actions(4).await; + + for &(peer_id, peer_set, version) in &peers { + let wire_msg = match version { + ValidationVersion::V1 => + WireMessage::::ViewUpdate(view.clone()) + .encode(), + ValidationVersion::VStaging => + WireMessage::::ViewUpdate(view.clone()) + .encode(), + }; + assert_network_actions_contains( + &actions, + &NetworkAction::WriteNotification(peer_id, peer_set, wire_msg), + ); + } + + virtual_overseer + }); +} + +#[test] +fn network_protocol_versioning_subsystem_msg() { + let (oracle, _handle) = make_sync_oracle(false); + test_harness(Box::new(oracle), |test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer, .. } = test_harness; + + let peer = PeerId::random(); + + network_handle + .connect_peer( + peer, + ValidationVersion::VStaging, + PeerSet::Validation, + ObservedRole::Full, + ) + .await; + + // bridge will inform about all connected peers. + { + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Full, + ValidationVersion::VStaging.into(), + None, + ), + &mut virtual_overseer, + ) + .await; + + assert_sends_validation_event_to_all( + NetworkBridgeEvent::PeerViewChange(peer, View::default()), + &mut virtual_overseer, + ) + .await; + } + + let approval_distribution_message = + protocol_vstaging::ApprovalDistributionMessage::Approvals(Vec::new()); + + let msg = protocol_vstaging::ValidationProtocol::ApprovalDistribution( + approval_distribution_message.clone(), + ); + + network_handle + .peer_message( + peer, + PeerSet::Validation, + WireMessage::ProtocolMessage(msg.clone()).encode(), + ) + .await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ApprovalDistribution( + ApprovalDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage(p, Versioned::VStaging(m)) + ) + ) => { + assert_eq!(p, peer); + assert_eq!(m, approval_distribution_message); + } + ); + + let metadata = protocol_v1::StatementMetadata { + relay_parent: Hash::zero(), + candidate_hash: CandidateHash::default(), + signed_by: ValidatorIndex(0), + signature: sp_core::crypto::UncheckedFrom::unchecked_from([1u8; 64]), + }; + let statement_distribution_message = + protocol_vstaging::StatementDistributionMessage::V1Compatibility( + protocol_v1::StatementDistributionMessage::LargeStatement(metadata), + ); + let msg = protocol_vstaging::ValidationProtocol::StatementDistribution( + statement_distribution_message.clone(), + ); + + network_handle + .peer_message( + peer, + PeerSet::Validation, + WireMessage::ProtocolMessage(msg.clone()).encode(), + ) + .await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage(p, Versioned::VStaging(m)) + ) + ) => { + assert_eq!(p, peer); + assert_eq!(m, statement_distribution_message); + } + ); + + // No more messages. + assert_matches!(futures::poll!(virtual_overseer.recv().boxed()), Poll::Pending); + + virtual_overseer + }); +} diff --git a/polkadot/node/network/bridge/src/tx/mod.rs b/polkadot/node/network/bridge/src/tx/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e0ca633547f4c0be8a7273f7688a3a5e75eafc9a --- /dev/null +++ b/polkadot/node/network/bridge/src/tx/mod.rs @@ -0,0 +1,447 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Network Bridge Subsystem - handles _outgoing_ messages, from subsystem to the network. +use super::*; + +use polkadot_node_network_protocol::{ + peer_set::{CollationVersion, PeerSet, PeerSetProtocolNames, ValidationVersion}, + request_response::ReqProtocolNames, + v1 as protocol_v1, vstaging as protocol_vstaging, PeerId, Versioned, +}; + +use polkadot_node_subsystem::{ + errors::SubsystemError, + messages::{NetworkBridgeTxMessage, ReportPeerMessage}, + overseer, FromOrchestra, OverseerSignal, SpawnedSubsystem, +}; + +/// Peer set info for network initialization. +/// +/// To be passed to [`FullNetworkConfiguration::add_notification_protocol`](). +pub use polkadot_node_network_protocol::peer_set::{peer_sets_info, IsAuthority}; +use sc_network::ReputationChange; + +use crate::validator_discovery; + +/// Actual interfacing to the network based on the `Network` trait. +/// +/// Defines the `Network` trait with an implementation for an `Arc`. +use crate::network::{send_message, Network}; + +use crate::metrics::Metrics; + +#[cfg(test)] +mod tests; + +// network bridge log target +const LOG_TARGET: &'static str = "parachain::network-bridge-tx"; + +/// The network bridge subsystem. +pub struct NetworkBridgeTx { + /// `Network` trait implementing type. + network_service: N, + authority_discovery_service: AD, + metrics: Metrics, + req_protocol_names: ReqProtocolNames, + peerset_protocol_names: PeerSetProtocolNames, +} + +impl NetworkBridgeTx { + /// Create a new network bridge subsystem with underlying network service and authority + /// discovery service. + /// + /// This assumes that the network service has had the notifications protocol for the network + /// bridge already registered. See [`peers_sets_info`](peers_sets_info). + pub fn new( + network_service: N, + authority_discovery_service: AD, + metrics: Metrics, + req_protocol_names: ReqProtocolNames, + peerset_protocol_names: PeerSetProtocolNames, + ) -> Self { + Self { + network_service, + authority_discovery_service, + metrics, + req_protocol_names, + peerset_protocol_names, + } + } +} + +#[overseer::subsystem(NetworkBridgeTx, error = SubsystemError, prefix = self::overseer)] +impl NetworkBridgeTx +where + Net: Network + Sync, + AD: validator_discovery::AuthorityDiscovery + Clone + Sync, +{ + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = run_network_out(self, ctx) + .map_err(|e| SubsystemError::with_origin("network-bridge", e)) + .boxed(); + SpawnedSubsystem { name: "network-bridge-tx-subsystem", future } + } +} + +#[overseer::contextbounds(NetworkBridgeTx, prefix = self::overseer)] +async fn handle_subsystem_messages( + mut ctx: Context, + mut network_service: N, + mut authority_discovery_service: AD, + metrics: Metrics, + req_protocol_names: ReqProtocolNames, + peerset_protocol_names: PeerSetProtocolNames, +) -> Result<(), Error> +where + N: Network, + AD: validator_discovery::AuthorityDiscovery + Clone, +{ + let mut validator_discovery = + validator_discovery::Service::::new(peerset_protocol_names.clone()); + + loop { + match ctx.recv().fuse().await? { + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), + FromOrchestra::Signal(_) => { /* handled by incoming */ }, + FromOrchestra::Communication { msg } => { + (network_service, authority_discovery_service) = + handle_incoming_subsystem_communication( + &mut ctx, + network_service, + &mut validator_discovery, + authority_discovery_service.clone(), + msg, + &metrics, + &req_protocol_names, + &peerset_protocol_names, + ) + .await; + }, + } + } +} + +#[overseer::contextbounds(NetworkBridgeTx, prefix = self::overseer)] +async fn handle_incoming_subsystem_communication( + _ctx: &mut Context, + mut network_service: N, + validator_discovery: &mut validator_discovery::Service, + mut authority_discovery_service: AD, + msg: NetworkBridgeTxMessage, + metrics: &Metrics, + req_protocol_names: &ReqProtocolNames, + peerset_protocol_names: &PeerSetProtocolNames, +) -> (N, AD) +where + N: Network, + AD: validator_discovery::AuthorityDiscovery + Clone, +{ + match msg { + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)) => { + if !rep.value.is_positive() { + gum::debug!(target: LOG_TARGET, ?peer, ?rep, action = "ReportPeer"); + } + + metrics.on_report_event(); + network_service.report_peer(peer, rep); + }, + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Batch(batch)) => { + for (peer, score) in batch { + let rep = ReputationChange::new(score, "Aggregated reputation change"); + if !rep.value.is_positive() { + gum::debug!(target: LOG_TARGET, ?peer, ?rep, action = "ReportPeer"); + } + + metrics.on_report_event(); + network_service.report_peer(peer, rep); + } + }, + NetworkBridgeTxMessage::DisconnectPeer(peer, peer_set) => { + gum::trace!( + target: LOG_TARGET, + action = "DisconnectPeer", + ?peer, + peer_set = ?peer_set, + ); + + // [`NetworkService`] keeps track of the protocols by their main name. + let protocol = peerset_protocol_names.get_main_name(peer_set); + network_service.disconnect_peer(peer, protocol); + }, + NetworkBridgeTxMessage::SendValidationMessage(peers, msg) => { + gum::trace!( + target: LOG_TARGET, + action = "SendValidationMessages", + num_messages = 1usize, + ); + + match msg { + Versioned::V1(msg) => send_validation_message_v1( + &mut network_service, + peers, + peerset_protocol_names, + WireMessage::ProtocolMessage(msg), + &metrics, + ), + Versioned::VStaging(msg) => send_validation_message_vstaging( + &mut network_service, + peers, + peerset_protocol_names, + WireMessage::ProtocolMessage(msg), + &metrics, + ), + } + }, + NetworkBridgeTxMessage::SendValidationMessages(msgs) => { + gum::trace!( + target: LOG_TARGET, + action = "SendValidationMessages", + num_messages = %msgs.len(), + ); + + for (peers, msg) in msgs { + match msg { + Versioned::V1(msg) => send_validation_message_v1( + &mut network_service, + peers, + peerset_protocol_names, + WireMessage::ProtocolMessage(msg), + &metrics, + ), + Versioned::VStaging(msg) => send_validation_message_vstaging( + &mut network_service, + peers, + peerset_protocol_names, + WireMessage::ProtocolMessage(msg), + &metrics, + ), + } + } + }, + NetworkBridgeTxMessage::SendCollationMessage(peers, msg) => { + gum::trace!( + target: LOG_TARGET, + action = "SendCollationMessages", + num_messages = 1usize, + ); + + match msg { + Versioned::V1(msg) => send_collation_message_v1( + &mut network_service, + peers, + peerset_protocol_names, + WireMessage::ProtocolMessage(msg), + &metrics, + ), + Versioned::VStaging(msg) => send_collation_message_vstaging( + &mut network_service, + peers, + peerset_protocol_names, + WireMessage::ProtocolMessage(msg), + &metrics, + ), + } + }, + NetworkBridgeTxMessage::SendCollationMessages(msgs) => { + gum::trace!( + target: LOG_TARGET, + action = "SendCollationMessages", + num_messages = %msgs.len(), + ); + + for (peers, msg) in msgs { + match msg { + Versioned::V1(msg) => send_collation_message_v1( + &mut network_service, + peers, + peerset_protocol_names, + WireMessage::ProtocolMessage(msg), + &metrics, + ), + Versioned::VStaging(msg) => send_collation_message_vstaging( + &mut network_service, + peers, + peerset_protocol_names, + WireMessage::ProtocolMessage(msg), + &metrics, + ), + } + } + }, + NetworkBridgeTxMessage::SendRequests(reqs, if_disconnected) => { + gum::trace!( + target: LOG_TARGET, + action = "SendRequests", + num_requests = %reqs.len(), + ); + + for req in reqs { + network_service + .start_request( + &mut authority_discovery_service, + req, + req_protocol_names, + if_disconnected, + ) + .await; + } + }, + NetworkBridgeTxMessage::ConnectToValidators { validator_ids, peer_set, failed } => { + gum::trace!( + target: LOG_TARGET, + action = "ConnectToValidators", + peer_set = ?peer_set, + ids = ?validator_ids, + "Received a validator connection request", + ); + + metrics.note_desired_peer_count(peer_set, validator_ids.len()); + + let (network_service, ads) = validator_discovery + .on_request( + validator_ids, + peer_set, + failed, + network_service, + authority_discovery_service, + ) + .await; + + return (network_service, ads) + }, + NetworkBridgeTxMessage::ConnectToResolvedValidators { validator_addrs, peer_set } => { + gum::trace!( + target: LOG_TARGET, + action = "ConnectToPeers", + peer_set = ?peer_set, + ?validator_addrs, + "Received a resolved validator connection request", + ); + + metrics.note_desired_peer_count(peer_set, validator_addrs.len()); + + let all_addrs = validator_addrs.into_iter().flatten().collect(); + let network_service = validator_discovery + .on_resolved_request(all_addrs, peer_set, network_service) + .await; + return (network_service, authority_discovery_service) + }, + } + (network_service, authority_discovery_service) +} + +#[overseer::contextbounds(NetworkBridgeTx, prefix = self::overseer)] +async fn run_network_out( + bridge: NetworkBridgeTx, + ctx: Context, +) -> Result<(), Error> +where + N: Network, + AD: validator_discovery::AuthorityDiscovery + Clone + Sync, +{ + let NetworkBridgeTx { + network_service, + authority_discovery_service, + metrics, + req_protocol_names, + peerset_protocol_names, + } = bridge; + + handle_subsystem_messages( + ctx, + network_service, + authority_discovery_service, + metrics, + req_protocol_names, + peerset_protocol_names, + ) + .await?; + + Ok(()) +} + +fn send_validation_message_v1( + net: &mut impl Network, + peers: Vec, + protocol_names: &PeerSetProtocolNames, + message: WireMessage, + metrics: &Metrics, +) { + send_message( + net, + peers, + PeerSet::Validation, + ValidationVersion::V1.into(), + protocol_names, + message, + metrics, + ); +} + +fn send_collation_message_v1( + net: &mut impl Network, + peers: Vec, + protocol_names: &PeerSetProtocolNames, + message: WireMessage, + metrics: &Metrics, +) { + send_message( + net, + peers, + PeerSet::Collation, + CollationVersion::V1.into(), + protocol_names, + message, + metrics, + ); +} + +fn send_validation_message_vstaging( + net: &mut impl Network, + peers: Vec, + protocol_names: &PeerSetProtocolNames, + message: WireMessage, + metrics: &Metrics, +) { + send_message( + net, + peers, + PeerSet::Validation, + ValidationVersion::VStaging.into(), + protocol_names, + message, + metrics, + ); +} + +fn send_collation_message_vstaging( + net: &mut impl Network, + peers: Vec, + protocol_names: &PeerSetProtocolNames, + message: WireMessage, + metrics: &Metrics, +) { + send_message( + net, + peers, + PeerSet::Collation, + CollationVersion::VStaging.into(), + protocol_names, + message, + metrics, + ); +} diff --git a/polkadot/node/network/bridge/src/tx/tests.rs b/polkadot/node/network/bridge/src/tx/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..21cd134c54f2141af111c5dd41ed5cf6038b58fe --- /dev/null +++ b/polkadot/node/network/bridge/src/tx/tests.rs @@ -0,0 +1,439 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use futures::{executor, stream::BoxStream}; +use polkadot_node_subsystem_util::TimeoutExt; + +use async_trait::async_trait; +use parking_lot::Mutex; +use std::collections::HashSet; + +use sc_network::{Event as NetworkEvent, IfDisconnected, ProtocolName, ReputationChange}; + +use polkadot_node_network_protocol::{ + peer_set::PeerSetProtocolNames, + request_response::{outgoing::Requests, ReqProtocolNames}, + ObservedRole, Versioned, +}; +use polkadot_node_subsystem::{FromOrchestra, OverseerSignal}; +use polkadot_node_subsystem_test_helpers::TestSubsystemContextHandle; +use polkadot_node_subsystem_util::metered; +use polkadot_primitives::{AuthorityDiscoveryId, Hash}; +use polkadot_primitives_test_helpers::dummy_collator_signature; +use sc_network::Multiaddr; +use sp_keyring::Sr25519Keyring; + +const TIMEOUT: std::time::Duration = polkadot_node_subsystem_test_helpers::TestSubsystemContextHandle::::TIMEOUT; + +use crate::{network::Network, validator_discovery::AuthorityDiscovery}; + +#[derive(Debug, PartialEq)] +pub enum NetworkAction { + /// Note a change in reputation for a peer. + ReputationChange(PeerId, ReputationChange), + /// Disconnect a peer from the given peer-set. + DisconnectPeer(PeerId, PeerSet), + /// Write a notification to a given peer on the given peer-set. + WriteNotification(PeerId, PeerSet, Vec), +} + +// The subsystem's view of the network - only supports a single call to `event_stream`. +#[derive(Clone)] +struct TestNetwork { + net_events: Arc>>>, + action_tx: Arc>>, + peerset_protocol_names: Arc, +} + +#[derive(Clone, Debug)] +struct TestAuthorityDiscovery; + +// The test's view of the network. This receives updates from the subsystem in the form +// of `NetworkAction`s. +struct TestNetworkHandle { + action_rx: metered::UnboundedMeteredReceiver, + net_tx: metered::MeteredSender, + peerset_protocol_names: PeerSetProtocolNames, +} + +fn new_test_network( + peerset_protocol_names: PeerSetProtocolNames, +) -> (TestNetwork, TestNetworkHandle, TestAuthorityDiscovery) { + let (net_tx, net_rx) = metered::channel(10); + let (action_tx, action_rx) = metered::unbounded(); + + ( + TestNetwork { + net_events: Arc::new(Mutex::new(Some(net_rx))), + action_tx: Arc::new(Mutex::new(action_tx)), + peerset_protocol_names: Arc::new(peerset_protocol_names.clone()), + }, + TestNetworkHandle { action_rx, net_tx, peerset_protocol_names }, + TestAuthorityDiscovery, + ) +} + +#[async_trait] +impl Network for TestNetwork { + fn event_stream(&mut self) -> BoxStream<'static, NetworkEvent> { + self.net_events + .lock() + .take() + .expect("Subsystem made more than one call to `event_stream`") + .boxed() + } + + async fn set_reserved_peers( + &mut self, + _protocol: ProtocolName, + _: HashSet, + ) -> Result<(), String> { + Ok(()) + } + + async fn remove_from_peers_set( + &mut self, + _protocol: ProtocolName, + _: Vec, + ) -> Result<(), String> { + Ok(()) + } + + async fn start_request( + &self, + _: &mut AD, + _: Requests, + _: &ReqProtocolNames, + _: IfDisconnected, + ) { + } + + fn report_peer(&self, who: PeerId, rep: ReputationChange) { + self.action_tx + .lock() + .unbounded_send(NetworkAction::ReputationChange(who, rep)) + .unwrap(); + } + + fn disconnect_peer(&self, who: PeerId, protocol: ProtocolName) { + let (peer_set, _) = self.peerset_protocol_names.try_get_protocol(&protocol).unwrap(); + + self.action_tx + .lock() + .unbounded_send(NetworkAction::DisconnectPeer(who, peer_set)) + .unwrap(); + } + + fn write_notification(&self, who: PeerId, protocol: ProtocolName, message: Vec) { + let (peer_set, _) = self.peerset_protocol_names.try_get_protocol(&protocol).unwrap(); + + self.action_tx + .lock() + .unbounded_send(NetworkAction::WriteNotification(who, peer_set, message)) + .unwrap(); + } +} + +#[async_trait] +impl validator_discovery::AuthorityDiscovery for TestAuthorityDiscovery { + async fn get_addresses_by_authority_id( + &mut self, + _authority: AuthorityDiscoveryId, + ) -> Option> { + None + } + + async fn get_authority_ids_by_peer_id( + &mut self, + _peer_id: PeerId, + ) -> Option> { + None + } +} + +impl TestNetworkHandle { + // Get the next network action. + async fn next_network_action(&mut self) -> NetworkAction { + self.action_rx.next().await.expect("subsystem concluded early") + } + + async fn connect_peer( + &mut self, + peer: PeerId, + protocol_version: ValidationVersion, + peer_set: PeerSet, + role: ObservedRole, + ) { + let protocol_version = ProtocolVersion::from(protocol_version); + self.send_network_event(NetworkEvent::NotificationStreamOpened { + remote: peer, + protocol: self.peerset_protocol_names.get_name(peer_set, protocol_version), + negotiated_fallback: None, + role: role.into(), + received_handshake: vec![], + }) + .await; + } + + async fn send_network_event(&mut self, event: NetworkEvent) { + self.net_tx.send(event).await.expect("subsystem concluded early"); + } +} + +type VirtualOverseer = TestSubsystemContextHandle; + +struct TestHarness { + network_handle: TestNetworkHandle, + virtual_overseer: VirtualOverseer, +} + +fn test_harness>(test: impl FnOnce(TestHarness) -> T) { + let genesis_hash = Hash::repeat_byte(0xff); + let fork_id = None; + let req_protocol_names = ReqProtocolNames::new(genesis_hash, fork_id); + let peerset_protocol_names = PeerSetProtocolNames::new(genesis_hash, fork_id); + + let pool = sp_core::testing::TaskExecutor::new(); + let (network, network_handle, discovery) = new_test_network(peerset_protocol_names.clone()); + + let (context, virtual_overseer) = + polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); + + let bridge_out = NetworkBridgeTx::new( + network, + discovery, + Metrics(None), + req_protocol_names, + peerset_protocol_names, + ); + + let network_bridge_out_fut = run_network_out(bridge_out, context) + .map_err(|e| panic!("bridge-out subsystem execution failed {:?}", e)) + .map(|_| ()); + + let test_fut = test(TestHarness { network_handle, virtual_overseer }); + + futures::pin_mut!(test_fut); + futures::pin_mut!(network_bridge_out_fut); + + let _ = executor::block_on(future::join( + async move { + let mut virtual_overseer = test_fut.await; + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }, + network_bridge_out_fut, + )); +} + +#[test] +fn send_messages_to_peers() { + test_harness(|test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer } = test_harness; + + let peer = PeerId::random(); + + network_handle + .connect_peer(peer, ValidationVersion::V1, PeerSet::Validation, ObservedRole::Full) + .timeout(TIMEOUT) + .await + .expect("Timeout does not occur"); + + // the outgoing side does not consume network messages + // so the single item sink has to be free explicitly + + network_handle + .connect_peer(peer, ValidationVersion::V1, PeerSet::Collation, ObservedRole::Full) + .timeout(TIMEOUT) + .await + .expect("Timeout does not occur"); + + // send a validation protocol message. + + { + let approval_distribution_message = + protocol_v1::ApprovalDistributionMessage::Approvals(Vec::new()); + + let message_v1 = protocol_v1::ValidationProtocol::ApprovalDistribution( + approval_distribution_message.clone(), + ); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: NetworkBridgeTxMessage::SendValidationMessage( + vec![peer], + Versioned::V1(message_v1.clone()), + ), + }) + .timeout(TIMEOUT) + .await + .expect("Timeout does not occur"); + + assert_eq!( + network_handle + .next_network_action() + .timeout(TIMEOUT) + .await + .expect("Timeout does not occur"), + NetworkAction::WriteNotification( + peer, + PeerSet::Validation, + WireMessage::ProtocolMessage(message_v1).encode(), + ) + ); + } + + // send a collation protocol message. + + { + let collator_protocol_message = protocol_v1::CollatorProtocolMessage::Declare( + Sr25519Keyring::Alice.public().into(), + 0_u32.into(), + dummy_collator_signature(), + ); + + let message_v1 = + protocol_v1::CollationProtocol::CollatorProtocol(collator_protocol_message.clone()); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: NetworkBridgeTxMessage::SendCollationMessage( + vec![peer], + Versioned::V1(message_v1.clone()), + ), + }) + .await; + + assert_eq!( + network_handle + .next_network_action() + .timeout(TIMEOUT) + .await + .expect("Timeout does not occur"), + NetworkAction::WriteNotification( + peer, + PeerSet::Collation, + WireMessage::ProtocolMessage(message_v1).encode(), + ) + ); + } + virtual_overseer + }); +} + +#[test] +fn network_protocol_versioning_send() { + test_harness(|test_harness| async move { + let TestHarness { mut network_handle, mut virtual_overseer } = test_harness; + + let peer_ids: Vec<_> = (0..4).map(|_| PeerId::random()).collect(); + let peers = [ + (peer_ids[0], PeerSet::Validation, ValidationVersion::VStaging), + (peer_ids[1], PeerSet::Collation, ValidationVersion::V1), + (peer_ids[2], PeerSet::Validation, ValidationVersion::V1), + (peer_ids[3], PeerSet::Collation, ValidationVersion::VStaging), + ]; + + for &(peer_id, peer_set, version) in &peers { + network_handle + .connect_peer(peer_id, version, peer_set, ObservedRole::Full) + .timeout(TIMEOUT) + .await + .expect("Timeout does not occur"); + } + + // send a validation protocol message. + + { + let approval_distribution_message = + protocol_vstaging::ApprovalDistributionMessage::Approvals(Vec::new()); + + let msg = protocol_vstaging::ValidationProtocol::ApprovalDistribution( + approval_distribution_message.clone(), + ); + + // Note that bridge doesn't ensure neither peer's protocol version + // or peer set match the message. + let receivers = vec![peer_ids[0], peer_ids[3]]; + virtual_overseer + .send(FromOrchestra::Communication { + msg: NetworkBridgeTxMessage::SendValidationMessage( + receivers.clone(), + Versioned::VStaging(msg.clone()), + ), + }) + .timeout(TIMEOUT) + .await + .expect("Timeout does not occur"); + + for peer in &receivers { + assert_eq!( + network_handle + .next_network_action() + .timeout(TIMEOUT) + .await + .expect("Timeout does not occur"), + NetworkAction::WriteNotification( + *peer, + PeerSet::Validation, + WireMessage::ProtocolMessage(msg.clone()).encode(), + ) + ); + } + } + + // send a collation protocol message. + + { + let collator_protocol_message = protocol_vstaging::CollatorProtocolMessage::Declare( + Sr25519Keyring::Alice.public().into(), + 0_u32.into(), + dummy_collator_signature(), + ); + + let msg = protocol_vstaging::CollationProtocol::CollatorProtocol( + collator_protocol_message.clone(), + ); + + let receivers = vec![peer_ids[1], peer_ids[2]]; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: NetworkBridgeTxMessage::SendCollationMessages(vec![( + receivers.clone(), + Versioned::VStaging(msg.clone()), + )]), + }) + .await; + + for peer in &receivers { + assert_eq!( + network_handle + .next_network_action() + .timeout(TIMEOUT) + .await + .expect("Timeout does not occur"), + NetworkAction::WriteNotification( + *peer, + PeerSet::Collation, + WireMessage::ProtocolMessage(msg.clone()).encode(), + ) + ); + } + } + virtual_overseer + }); +} diff --git a/polkadot/node/network/bridge/src/validator_discovery.rs b/polkadot/node/network/bridge/src/validator_discovery.rs new file mode 100644 index 0000000000000000000000000000000000000000..86e861fbc5b5c1cc4159a86c47fcf88cc6a6953d --- /dev/null +++ b/polkadot/node/network/bridge/src/validator_discovery.rs @@ -0,0 +1,377 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A validator discovery service for the Network Bridge. + +use crate::Network; + +use core::marker::PhantomData; +use std::collections::HashSet; + +use futures::channel::oneshot; + +use sc_network::multiaddr::{self, Multiaddr}; + +pub use polkadot_node_network_protocol::authority_discovery::AuthorityDiscovery; +use polkadot_node_network_protocol::{ + peer_set::{PeerSet, PeerSetProtocolNames, PerPeerSet}, + PeerId, +}; +use polkadot_primitives::AuthorityDiscoveryId; + +const LOG_TARGET: &str = "parachain::validator-discovery"; + +pub(super) struct Service { + state: PerPeerSet, + peerset_protocol_names: PeerSetProtocolNames, + // PhantomData used to make the struct generic instead of having generic methods + _phantom: PhantomData<(N, AD)>, +} + +#[derive(Default)] +struct StatePerPeerSet { + previously_requested: HashSet, +} + +impl Service { + pub fn new(peerset_protocol_names: PeerSetProtocolNames) -> Self { + Self { state: Default::default(), peerset_protocol_names, _phantom: PhantomData } + } + + /// Connect to already resolved addresses. + pub async fn on_resolved_request( + &mut self, + newly_requested: HashSet, + peer_set: PeerSet, + mut network_service: N, + ) -> N { + let state = &mut self.state[peer_set]; + let new_peer_ids: HashSet = extract_peer_ids(newly_requested.iter().cloned()); + let num_peers = new_peer_ids.len(); + + let peers_to_remove: Vec = + state.previously_requested.difference(&new_peer_ids).cloned().collect(); + let removed = peers_to_remove.len(); + state.previously_requested = new_peer_ids; + + gum::debug!( + target: LOG_TARGET, + ?peer_set, + ?num_peers, + ?removed, + "New ConnectToValidators resolved request", + ); + // ask the network to connect to these nodes and not disconnect + // from them until removed from the set + // + // for peer-set management, the main protocol name should be used regardless of + // the negotiated version. + if let Err(e) = network_service + .set_reserved_peers( + self.peerset_protocol_names.get_main_name(peer_set), + newly_requested, + ) + .await + { + gum::warn!(target: LOG_TARGET, err = ?e, "AuthorityDiscoveryService returned an invalid multiaddress"); + } + // the addresses are known to be valid + // + // for peer-set management, the main protocol name should be used regardless of + // the negotiated version. + let _ = network_service + .remove_from_peers_set( + self.peerset_protocol_names.get_main_name(peer_set), + peers_to_remove, + ) + .await; + + network_service + } + + /// On a new connection request, a peer set update will be issued. + /// It will ask the network to connect to the validators and not disconnect + /// from them at least until the next request is issued for the same peer set. + /// + /// This method will also disconnect from previously connected validators not in the + /// `validator_ids` set. it takes `network_service` and `authority_discovery_service` by value + /// and returns them as a workaround for the Future: Send requirement imposed by async function + /// implementation. + pub async fn on_request( + &mut self, + validator_ids: Vec, + peer_set: PeerSet, + failed: oneshot::Sender, + network_service: N, + mut authority_discovery_service: AD, + ) -> (N, AD) { + // collect multiaddress of validators + let mut failed_to_resolve: usize = 0; + let mut newly_requested = HashSet::new(); + let requested = validator_ids.len(); + for authority in validator_ids.into_iter() { + let result = authority_discovery_service + .get_addresses_by_authority_id(authority.clone()) + .await; + if let Some(addresses) = result { + newly_requested.extend(addresses); + } else { + failed_to_resolve += 1; + gum::debug!( + target: LOG_TARGET, + "Authority Discovery couldn't resolve {:?}", + authority + ); + } + } + + gum::debug!( + target: LOG_TARGET, + ?peer_set, + ?requested, + ?failed_to_resolve, + "New ConnectToValidators request", + ); + + let r = self.on_resolved_request(newly_requested, peer_set, network_service).await; + + let _ = failed.send(failed_to_resolve); + + (r, authority_discovery_service) + } +} + +fn extract_peer_ids(multiaddr: impl Iterator) -> HashSet { + multiaddr + .filter_map(|mut addr| match addr.pop() { + Some(multiaddr::Protocol::P2p(key)) => PeerId::from_multihash(key).ok(), + _ => None, + }) + .collect() +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::network::Network; + + use async_trait::async_trait; + use futures::stream::BoxStream; + use polkadot_node_network_protocol::{ + request_response::{outgoing::Requests, ReqProtocolNames}, + PeerId, + }; + use polkadot_primitives::Hash; + use sc_network::{Event as NetworkEvent, IfDisconnected, ProtocolName, ReputationChange}; + use sp_keyring::Sr25519Keyring; + use std::collections::{HashMap, HashSet}; + + fn new_service() -> Service { + let genesis_hash = Hash::repeat_byte(0xff); + let fork_id = None; + let protocol_names = PeerSetProtocolNames::new(genesis_hash, fork_id); + + Service::new(protocol_names) + } + + fn new_network() -> (TestNetwork, TestAuthorityDiscovery) { + (TestNetwork::default(), TestAuthorityDiscovery::new()) + } + + #[derive(Default, Clone)] + struct TestNetwork { + peers_set: HashSet, + } + + #[derive(Default, Clone, Debug)] + struct TestAuthorityDiscovery { + by_authority_id: HashMap>, + by_peer_id: HashMap>, + } + + impl TestAuthorityDiscovery { + fn new() -> Self { + let peer_ids = known_peer_ids(); + let authorities = known_authorities(); + let multiaddr = known_multiaddr().into_iter().zip(peer_ids.iter().cloned()).map( + |(mut addr, peer_id)| { + addr.push(multiaddr::Protocol::P2p(peer_id.into())); + HashSet::from([addr]) + }, + ); + Self { + by_authority_id: authorities.iter().cloned().zip(multiaddr).collect(), + by_peer_id: peer_ids + .into_iter() + .zip(authorities.into_iter().map(|a| HashSet::from([a]))) + .collect(), + } + } + } + + #[async_trait] + impl Network for TestNetwork { + fn event_stream(&mut self) -> BoxStream<'static, NetworkEvent> { + panic!() + } + + async fn set_reserved_peers( + &mut self, + _protocol: ProtocolName, + multiaddresses: HashSet, + ) -> Result<(), String> { + self.peers_set = extract_peer_ids(multiaddresses.into_iter()); + Ok(()) + } + + async fn remove_from_peers_set( + &mut self, + _protocol: ProtocolName, + peers: Vec, + ) -> Result<(), String> { + self.peers_set.retain(|elem| !peers.contains(elem)); + Ok(()) + } + + async fn start_request( + &self, + _: &mut AD, + _: Requests, + _: &ReqProtocolNames, + _: IfDisconnected, + ) { + } + + fn report_peer(&self, _: PeerId, _: ReputationChange) { + panic!() + } + + fn disconnect_peer(&self, _: PeerId, _: ProtocolName) { + panic!() + } + + fn write_notification(&self, _: PeerId, _: ProtocolName, _: Vec) { + panic!() + } + } + + #[async_trait] + impl AuthorityDiscovery for TestAuthorityDiscovery { + async fn get_addresses_by_authority_id( + &mut self, + authority: AuthorityDiscoveryId, + ) -> Option> { + self.by_authority_id.get(&authority).cloned() + } + + async fn get_authority_ids_by_peer_id( + &mut self, + peer_id: PeerId, + ) -> Option> { + self.by_peer_id.get(&peer_id).cloned() + } + } + + fn known_authorities() -> Vec { + [Sr25519Keyring::Alice, Sr25519Keyring::Bob, Sr25519Keyring::Charlie] + .iter() + .map(|k| k.public().into()) + .collect() + } + + fn known_peer_ids() -> Vec { + (0..3).map(|_| PeerId::random()).collect() + } + + fn known_multiaddr() -> Vec { + vec![ + "/ip4/127.0.0.1/tcp/1234".parse().unwrap(), + "/ip4/127.0.0.1/tcp/1235".parse().unwrap(), + "/ip4/127.0.0.1/tcp/1236".parse().unwrap(), + ] + } + // Test cleanup works. + #[test] + fn old_multiaddrs_are_removed_on_new_request() { + let mut service = new_service(); + + let (ns, ads) = new_network(); + + let authority_ids: Vec<_> = + ads.by_peer_id.values().flat_map(|v| v.iter()).cloned().collect(); + + futures::executor::block_on(async move { + let (failed, _) = oneshot::channel(); + let (ns, ads) = service + .on_request(vec![authority_ids[0].clone()], PeerSet::Validation, failed, ns, ads) + .await; + + let (failed, _) = oneshot::channel(); + let (_, ads) = service + .on_request(vec![authority_ids[1].clone()], PeerSet::Validation, failed, ns, ads) + .await; + + let state = &service.state[PeerSet::Validation]; + assert_eq!(state.previously_requested.len(), 1); + let peer_1 = extract_peer_ids( + ads.by_authority_id.get(&authority_ids[1]).unwrap().clone().into_iter(), + ) + .iter() + .cloned() + .next() + .unwrap(); + assert!(state.previously_requested.contains(&peer_1)); + }); + } + + #[test] + fn failed_resolution_is_reported_properly() { + let mut service = new_service(); + + let (ns, ads) = new_network(); + + let authority_ids: Vec<_> = + ads.by_peer_id.values().flat_map(|v| v.iter()).cloned().collect(); + + futures::executor::block_on(async move { + let (failed, failed_rx) = oneshot::channel(); + let unknown = Sr25519Keyring::Ferdie.public().into(); + let (_, ads) = service + .on_request( + vec![authority_ids[0].clone(), unknown], + PeerSet::Validation, + failed, + ns, + ads, + ) + .await; + + let state = &service.state[PeerSet::Validation]; + assert_eq!(state.previously_requested.len(), 1); + let peer_0 = extract_peer_ids( + ads.by_authority_id.get(&authority_ids[0]).unwrap().clone().into_iter(), + ) + .iter() + .cloned() + .next() + .unwrap(); + assert!(state.previously_requested.contains(&peer_0)); + + let failed = failed_rx.await.unwrap(); + assert_eq!(failed, 1); + }); + } +} diff --git a/polkadot/node/network/collator-protocol/Cargo.toml b/polkadot/node/network/collator-protocol/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..e73de15d1ecbac9ccce565670b9a7e8e19f06e20 --- /dev/null +++ b/polkadot/node/network/collator-protocol/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "polkadot-collator-protocol" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +bitvec = { version = "1.0.1", default-features = false, features = ["alloc"] } +futures = "0.3.21" +futures-timer = "3" +gum = { package = "tracing-gum", path = "../../gum" } + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } + +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-network-protocol = { path = "../../network/protocol" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-node-subsystem = {path = "../../subsystem" } +fatality = "0.0.6" +thiserror = "1.0.31" +tokio-util = "0.7.1" + +[dev-dependencies] +log = "0.4.17" +env_logger = "0.9.0" +assert_matches = "1.4.0" + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["std"] } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +parity-scale-codec = { version = "3.6.1", features = ["std"] } + +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +polkadot-primitives-test-helpers = { path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/network/collator-protocol/src/collator_side/collation.rs b/polkadot/node/network/collator-protocol/src/collator_side/collation.rs new file mode 100644 index 0000000000000000000000000000000000000000..28dd9e0a959e73b5ff660b169b3857ebf890a6b0 --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/collator_side/collation.rs @@ -0,0 +1,162 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Primitives for tracking collations-related data. + +use std::collections::{HashSet, VecDeque}; + +use futures::{future::BoxFuture, stream::FuturesUnordered}; + +use polkadot_node_network_protocol::{ + request_response::{ + incoming::OutgoingResponse, v1 as protocol_v1, vstaging as protocol_vstaging, + IncomingRequest, + }, + PeerId, +}; +use polkadot_node_primitives::PoV; +use polkadot_primitives::{CandidateHash, CandidateReceipt, Hash, Id as ParaId}; + +/// The status of a collation as seen from the collator. +pub enum CollationStatus { + /// The collation was created, but we did not advertise it to any validator. + Created, + /// The collation was advertised to at least one validator. + Advertised, + /// The collation was requested by at least one validator. + Requested, +} + +impl CollationStatus { + /// Advance to the [`Self::Advertised`] status. + /// + /// This ensures that `self` isn't already [`Self::Requested`]. + pub fn advance_to_advertised(&mut self) { + if !matches!(self, Self::Requested) { + *self = Self::Advertised; + } + } + + /// Advance to the [`Self::Requested`] status. + pub fn advance_to_requested(&mut self) { + *self = Self::Requested; + } +} + +/// A collation built by the collator. +pub struct Collation { + /// Candidate receipt. + pub receipt: CandidateReceipt, + /// Parent head-data hash. + pub parent_head_data_hash: Hash, + /// Proof to verify the state transition of the parachain. + pub pov: PoV, + /// Collation status. + pub status: CollationStatus, +} + +/// Stores the state for waiting collation fetches per relay parent. +#[derive(Default)] +pub struct WaitingCollationFetches { + /// A flag indicating that we have an ongoing request. + /// This limits the number of collations being sent at any moment + /// of time to 1 for each relay parent. + /// + /// If set to `true`, any new request will be queued. + pub collation_fetch_active: bool, + /// The collation fetches waiting to be fulfilled. + pub req_queue: VecDeque, + /// All peers that are waiting or actively uploading. + /// + /// We will not accept multiple requests from the same peer, otherwise our DoS protection of + /// moving on to the next peer after `MAX_UNSHARED_UPLOAD_TIME` would be pointless. + pub waiting_peers: HashSet<(PeerId, CandidateHash)>, +} + +/// Backwards-compatible wrapper for incoming collations requests. +pub enum VersionedCollationRequest { + V1(IncomingRequest), + VStaging(IncomingRequest), +} + +impl From> for VersionedCollationRequest { + fn from(req: IncomingRequest) -> Self { + Self::V1(req) + } +} + +impl From> + for VersionedCollationRequest +{ + fn from(req: IncomingRequest) -> Self { + Self::VStaging(req) + } +} + +impl VersionedCollationRequest { + /// Returns parachain id from the request payload. + pub fn para_id(&self) -> ParaId { + match self { + VersionedCollationRequest::V1(req) => req.payload.para_id, + VersionedCollationRequest::VStaging(req) => req.payload.para_id, + } + } + + /// Returns relay parent from the request payload. + pub fn relay_parent(&self) -> Hash { + match self { + VersionedCollationRequest::V1(req) => req.payload.relay_parent, + VersionedCollationRequest::VStaging(req) => req.payload.relay_parent, + } + } + + /// Returns id of the peer the request was received from. + pub fn peer_id(&self) -> PeerId { + match self { + VersionedCollationRequest::V1(req) => req.peer, + VersionedCollationRequest::VStaging(req) => req.peer, + } + } + + /// Sends the response back to requester. + pub fn send_outgoing_response( + self, + response: OutgoingResponse, + ) -> Result<(), ()> { + match self { + VersionedCollationRequest::V1(req) => req.send_outgoing_response(response), + VersionedCollationRequest::VStaging(req) => req.send_outgoing_response(response), + } + } +} + +/// Result of the finished background send-collation task. +/// +/// Note that if the timeout was hit the request doesn't get +/// aborted, it only indicates that we should start processing +/// the next one from the queue. +pub struct CollationSendResult { + /// Candidate's relay parent. + pub relay_parent: Hash, + /// Candidate hash. + pub candidate_hash: CandidateHash, + /// Peer id. + pub peer_id: PeerId, + /// Whether the max unshared timeout was hit. + pub timed_out: bool, +} + +pub type ActiveCollationFetches = FuturesUnordered>; diff --git a/polkadot/node/network/collator-protocol/src/collator_side/metrics.rs b/polkadot/node/network/collator-protocol/src/collator_side/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..589c19b4f90d8ddb6bb12dac61a49c6d314ae71e --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/collator_side/metrics.rs @@ -0,0 +1,123 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone, Default)] +pub struct Metrics(Option); + +impl Metrics { + pub fn on_advertisement_made(&self) { + if let Some(metrics) = &self.0 { + metrics.advertisements_made.inc(); + } + } + + pub fn on_collation_sent_requested(&self) { + if let Some(metrics) = &self.0 { + metrics.collations_send_requested.inc(); + } + } + + pub fn on_collation_sent(&self) { + if let Some(metrics) = &self.0 { + metrics.collations_sent.inc(); + } + } + + /// Provide a timer for `process_msg` which observes on drop. + pub fn time_process_msg(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.process_msg.start_timer()) + } + + /// Provide a timer for `distribute_collation` which observes on drop. + pub fn time_collation_distribution( + &self, + label: &'static str, + ) -> Option { + self.0.as_ref().map(|metrics| { + metrics.collation_distribution_time.with_label_values(&[label]).start_timer() + }) + } +} + +#[derive(Clone)] +struct MetricsInner { + advertisements_made: prometheus::Counter, + collations_sent: prometheus::Counter, + collations_send_requested: prometheus::Counter, + process_msg: prometheus::Histogram, + collation_distribution_time: prometheus::HistogramVec, +} + +impl metrics::Metrics for Metrics { + fn try_register( + registry: &prometheus::Registry, + ) -> std::result::Result { + let metrics = MetricsInner { + advertisements_made: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_collation_advertisements_made_total", + "A number of collation advertisements sent to validators.", + )?, + registry, + )?, + collations_send_requested: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_collations_sent_requested_total", + "A number of collations requested to be sent to validators.", + )?, + registry, + )?, + collations_sent: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_collations_sent_total", + "A number of collations sent to validators.", + )?, + registry, + )?, + process_msg: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collator_protocol_collator_process_msg", + "Time spent within `collator_protocol_collator::process_msg`", + ) + .buckets(vec![ + 0.001, 0.002, 0.005, 0.01, 0.025, 0.05, 0.1, 0.15, 0.25, 0.35, 0.5, 0.75, + 1.0, + ]), + )?, + registry, + )?, + collation_distribution_time: prometheus::register( + prometheus::HistogramVec::new( + prometheus::HistogramOpts::new( + "polkadot_parachain_collator_protocol_collator_distribution_time", + "Time spent within `collator_protocol_collator::distribute_collation`", + ) + .buckets(vec![ + 0.001, 0.002, 0.005, 0.01, 0.025, 0.05, 0.1, 0.15, 0.25, 0.35, 0.5, 0.75, + 1.0, + ]), + &["state"], + )?, + registry, + )?, + }; + + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/network/collator-protocol/src/collator_side/mod.rs b/polkadot/node/network/collator-protocol/src/collator_side/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..96978f39a5328bc3f2c6935c1598a6f5c0ea85a0 --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/collator_side/mod.rs @@ -0,0 +1,1458 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{ + collections::{HashMap, HashSet}, + convert::TryInto, + time::Duration, +}; + +use bitvec::{bitvec, vec::BitVec}; +use futures::{ + channel::oneshot, future::Fuse, pin_mut, select, stream::FuturesUnordered, FutureExt, StreamExt, +}; +use sp_core::Pair; + +use polkadot_node_network_protocol::{ + self as net_protocol, + peer_set::{CollationVersion, PeerSet}, + request_response::{ + incoming::{self, OutgoingResponse}, + v1 as request_v1, vstaging as request_vstaging, IncomingRequestReceiver, + }, + v1 as protocol_v1, vstaging as protocol_vstaging, OurView, PeerId, + UnifiedReputationChange as Rep, Versioned, View, +}; +use polkadot_node_primitives::{CollationSecondedSignal, PoV, Statement}; +use polkadot_node_subsystem::{ + jaeger, + messages::{ + CollatorProtocolMessage, NetworkBridgeEvent, NetworkBridgeTxMessage, RuntimeApiMessage, + }, + overseer, CollatorProtocolSenderTrait, FromOrchestra, OverseerSignal, PerLeafSpan, +}; +use polkadot_node_subsystem_util::{ + backing_implicit_view::View as ImplicitView, + reputation::{ReputationAggregator, REPUTATION_CHANGE_INTERVAL}, + runtime::{ + get_availability_cores, get_group_rotation_info, prospective_parachains_mode, + ProspectiveParachainsMode, RuntimeInfo, + }, + TimeoutExt, +}; +use polkadot_primitives::{ + AuthorityDiscoveryId, CandidateHash, CandidateReceipt, CollatorPair, CoreIndex, CoreState, + GroupIndex, Hash, Id as ParaId, SessionIndex, +}; + +use super::LOG_TARGET; +use crate::{ + error::{log_error, Error, FatalError, Result}, + modify_reputation, +}; + +mod collation; +mod metrics; +#[cfg(test)] +mod tests; +mod validators_buffer; + +use collation::{ + ActiveCollationFetches, Collation, CollationSendResult, CollationStatus, + VersionedCollationRequest, WaitingCollationFetches, +}; +use validators_buffer::{ + ResetInterestTimeout, ValidatorGroupsBuffer, RESET_INTEREST_TIMEOUT, VALIDATORS_BUFFER_CAPACITY, +}; + +pub use metrics::Metrics; + +const COST_INVALID_REQUEST: Rep = Rep::CostMajor("Peer sent unparsable request"); +const COST_UNEXPECTED_MESSAGE: Rep = Rep::CostMinor("An unexpected message"); +const COST_APPARENT_FLOOD: Rep = + Rep::CostMinor("Message received when previous one was still being processed"); + +/// Time after starting an upload to a validator we will start another one to the next validator, +/// even if the upload was not finished yet. +/// +/// This is to protect from a single slow validator preventing collations from happening. +/// +/// For considerations on this value, see: https://github.com/paritytech/polkadot/issues/4386 +const MAX_UNSHARED_UPLOAD_TIME: Duration = Duration::from_millis(150); + +/// Ensure that collator issues a connection request at least once every this many seconds. +/// Usually it's done when advertising new collation. However, if the core stays occupied or +/// it's not our turn to produce a candidate, it's important to disconnect from previous +/// peers. +/// +/// Validators are obtained from [`ValidatorGroupsBuffer::validators_to_connect`]. +const RECONNECT_TIMEOUT: Duration = Duration::from_secs(12); + +/// Future that when resolved indicates that we should update reserved peer-set +/// of validators we want to be connected to. +/// +/// `Pending` variant never finishes and should be used when there're no peers +/// connected. +type ReconnectTimeout = Fuse; + +/// Info about validators we are currently connected to. +/// +/// It keeps track to which validators we advertised our collation. +#[derive(Debug, Default)] +struct ValidatorGroup { + /// Validators discovery ids. Lazily initialized when first + /// distributing a collation. + validators: Vec, + + /// Bits indicating which validators have already seen the announcement + /// per candidate. + advertised_to: HashMap, +} + +impl ValidatorGroup { + /// Returns `true` if we should advertise our collation to the given peer. + fn should_advertise_to( + &self, + candidate_hash: &CandidateHash, + peer_ids: &HashMap>, + peer: &PeerId, + ) -> bool { + let authority_ids = match peer_ids.get(peer) { + Some(authority_ids) => authority_ids, + None => return false, + }; + + for id in authority_ids { + // One peer id may correspond to different discovery ids across sessions, + // having a non-empty intersection is sufficient to assume that this peer + // belongs to this particular validator group. + let validator_index = match self.validators.iter().position(|v| v == id) { + Some(idx) => idx, + None => continue, + }; + + // Either the candidate is unseen by this validator group + // or the corresponding bit is not set. + if self + .advertised_to + .get(candidate_hash) + .map_or(true, |advertised| !advertised[validator_index]) + { + return true + } + } + + false + } + + /// Should be called after we advertised our collation to the given `peer` to keep track of it. + fn advertised_to_peer( + &mut self, + candidate_hash: &CandidateHash, + peer_ids: &HashMap>, + peer: &PeerId, + ) { + if let Some(authority_ids) = peer_ids.get(peer) { + for id in authority_ids { + let validator_index = match self.validators.iter().position(|v| v == id) { + Some(idx) => idx, + None => continue, + }; + self.advertised_to + .entry(*candidate_hash) + .or_insert_with(|| bitvec![0; self.validators.len()]) + .set(validator_index, true); + } + } + } +} + +#[derive(Debug)] +struct PeerData { + /// Peer's view. + view: View, + /// Network protocol version. + version: CollationVersion, +} + +struct PerRelayParent { + prospective_parachains_mode: ProspectiveParachainsMode, + /// Validators group responsible for backing candidates built + /// on top of this relay parent. + validator_group: ValidatorGroup, + /// Distributed collations. + collations: HashMap, +} + +impl PerRelayParent { + fn new(mode: ProspectiveParachainsMode) -> Self { + Self { + prospective_parachains_mode: mode, + validator_group: ValidatorGroup::default(), + collations: HashMap::new(), + } + } +} + +struct State { + /// Our network peer id. + local_peer_id: PeerId, + + /// Our collator pair. + collator_pair: CollatorPair, + + /// The para this collator is collating on. + /// Starts as `None` and is updated with every `CollateOn` message. + collating_on: Option, + + /// Track all active peers and their views + /// to determine what is relevant to them. + peer_data: HashMap, + + /// Leaves that do support asynchronous backing along with + /// implicit ancestry. Leaves from the implicit view are present in + /// `active_leaves`, the opposite doesn't hold true. + /// + /// Relay-chain blocks which don't support prospective parachains are + /// never included in the fragment trees of active leaves which do. In + /// particular, this means that if a given relay parent belongs to implicit + /// ancestry of some active leaf, then it does support prospective parachains. + implicit_view: ImplicitView, + + /// All active leaves observed by us, including both that do and do not + /// support prospective parachains. This mapping works as a replacement for + /// [`polkadot_node_network_protocol::View`] and can be dropped once the transition + /// to asynchronous backing is done. + active_leaves: HashMap, + + /// Validators and distributed collations tracked for each relay parent from + /// our view, including both leaves and implicit ancestry. + per_relay_parent: HashMap, + + /// Span per relay parent. + span_per_relay_parent: HashMap, + + /// The result senders per collation. + collation_result_senders: HashMap>, + + /// The mapping from [`PeerId`] to [`HashSet`]. This is filled over time + /// as we learn the [`PeerId`]'s by `PeerConnected` events. + peer_ids: HashMap>, + + /// Tracks which validators we want to stay connected to. + validator_groups_buf: ValidatorGroupsBuffer, + + /// Timeout-future that enforces collator to update the peer-set at least once + /// every [`RECONNECT_TIMEOUT`] seconds. + reconnect_timeout: ReconnectTimeout, + + /// Metrics. + metrics: Metrics, + + /// All collation fetching requests that are still waiting to be answered. + /// + /// They are stored per relay parent, when our view changes and the relay parent moves out, we + /// will cancel the fetch request. + waiting_collation_fetches: HashMap, + + /// Active collation fetches. + /// + /// Each future returns the relay parent of the finished collation fetch. + active_collation_fetches: ActiveCollationFetches, + + /// Time limits for validators to fetch the collation once the advertisement + /// was sent. + /// + /// Given an implicit view a collation may stay in memory for significant amount + /// of time, if we don't timeout validators the node will keep attempting to connect + /// to unneeded peers. + advertisement_timeouts: FuturesUnordered, + + /// Aggregated reputation change + reputation: ReputationAggregator, +} + +impl State { + /// Creates a new `State` instance with the given parameters and setting all remaining + /// state fields to their default values (i.e. empty). + fn new( + local_peer_id: PeerId, + collator_pair: CollatorPair, + metrics: Metrics, + reputation: ReputationAggregator, + ) -> State { + State { + local_peer_id, + collator_pair, + metrics, + collating_on: Default::default(), + peer_data: Default::default(), + implicit_view: Default::default(), + active_leaves: Default::default(), + per_relay_parent: Default::default(), + span_per_relay_parent: Default::default(), + collation_result_senders: Default::default(), + peer_ids: Default::default(), + validator_groups_buf: ValidatorGroupsBuffer::with_capacity(VALIDATORS_BUFFER_CAPACITY), + reconnect_timeout: Fuse::terminated(), + waiting_collation_fetches: Default::default(), + active_collation_fetches: Default::default(), + advertisement_timeouts: Default::default(), + reputation, + } + } +} + +/// Distribute a collation. +/// +/// Figure out the core our para is assigned to and the relevant validators. +/// Issue a connection request to these validators. +/// If the para is not scheduled or next up on any core, at the relay-parent, +/// or the relay-parent isn't in the active-leaves set, we ignore the message +/// as it must be invalid in that case - although this indicates a logic error +/// elsewhere in the node. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn distribute_collation( + ctx: &mut Context, + runtime: &mut RuntimeInfo, + state: &mut State, + id: ParaId, + receipt: CandidateReceipt, + parent_head_data_hash: Hash, + pov: PoV, + result_sender: Option>, +) -> Result<()> { + let candidate_relay_parent = receipt.descriptor.relay_parent; + let candidate_hash = receipt.hash(); + + let per_relay_parent = match state.per_relay_parent.get_mut(&candidate_relay_parent) { + Some(per_relay_parent) => per_relay_parent, + None => { + gum::debug!( + target: LOG_TARGET, + para_id = %id, + candidate_relay_parent = %candidate_relay_parent, + candidate_hash = ?candidate_hash, + "Candidate relay parent is out of our view", + ); + return Ok(()) + }, + }; + let relay_parent_mode = per_relay_parent.prospective_parachains_mode; + + let collations_limit = match relay_parent_mode { + ProspectiveParachainsMode::Disabled => 1, + ProspectiveParachainsMode::Enabled { max_candidate_depth, .. } => max_candidate_depth + 1, + }; + + if per_relay_parent.collations.len() >= collations_limit { + gum::debug!( + target: LOG_TARGET, + ?candidate_relay_parent, + ?relay_parent_mode, + "The limit of {} collations per relay parent is already reached", + collations_limit, + ); + return Ok(()) + } + + // We have already seen collation for this relay parent. + if per_relay_parent.collations.contains_key(&candidate_hash) { + gum::debug!( + target: LOG_TARGET, + ?candidate_relay_parent, + ?candidate_hash, + "Already seen this candidate", + ); + return Ok(()) + } + + // Determine which core the para collated-on is assigned to. + // If it is not scheduled then ignore the message. + let (our_core, num_cores) = + match determine_core(ctx.sender(), id, candidate_relay_parent, relay_parent_mode).await? { + Some(core) => core, + None => { + gum::warn!( + target: LOG_TARGET, + para_id = %id, + "looks like no core is assigned to {} at {}", id, candidate_relay_parent, + ); + + return Ok(()) + }, + }; + + // Determine the group on that core. + // + // When prospective parachains are disabled, candidate relay parent here is + // guaranteed to be an active leaf. + let GroupValidators { validators, session_index, group_index } = + determine_our_validators(ctx, runtime, our_core, num_cores, candidate_relay_parent).await?; + + if validators.is_empty() { + gum::warn!( + target: LOG_TARGET, + core = ?our_core, + "there are no validators assigned to core", + ); + + return Ok(()) + } + + // It's important to insert new collation interests **before** + // issuing a connection request. + // + // If a validator managed to fetch all the relevant collations + // but still assigned to our core, we keep the connection alive. + state.validator_groups_buf.note_collation_advertised( + candidate_hash, + session_index, + group_index, + &validators, + ); + + gum::debug!( + target: LOG_TARGET, + para_id = %id, + candidate_relay_parent = %candidate_relay_parent, + relay_parent_mode = ?relay_parent_mode, + ?candidate_hash, + pov_hash = ?pov.hash(), + core = ?our_core, + current_validators = ?validators, + "Accepted collation, connecting to validators." + ); + + let validators_at_relay_parent = &mut per_relay_parent.validator_group.validators; + if validators_at_relay_parent.is_empty() { + *validators_at_relay_parent = validators; + } + + // Update a set of connected validators if necessary. + state.reconnect_timeout = connect_to_validators(ctx, &state.validator_groups_buf).await; + + if let Some(result_sender) = result_sender { + state.collation_result_senders.insert(candidate_hash, result_sender); + } + + per_relay_parent.collations.insert( + candidate_hash, + Collation { receipt, parent_head_data_hash, pov, status: CollationStatus::Created }, + ); + + // If prospective parachains are disabled, a leaf should be known to peer. + // Otherwise, it should be present in allowed ancestry of some leaf. + // + // It's collation-producer responsibility to verify that there exists + // a hypothetical membership in a fragment tree for candidate. + let interested = + state + .peer_data + .iter() + .filter(|(_, PeerData { view: v, .. })| match relay_parent_mode { + ProspectiveParachainsMode::Disabled => v.contains(&candidate_relay_parent), + ProspectiveParachainsMode::Enabled { .. } => v.iter().any(|block_hash| { + state + .implicit_view + .known_allowed_relay_parents_under(block_hash, Some(id)) + .unwrap_or_default() + .contains(&candidate_relay_parent) + }), + }); + + // Make sure already connected peers get collations: + for (peer_id, peer_data) in interested { + advertise_collation( + ctx, + candidate_relay_parent, + per_relay_parent, + peer_id, + peer_data.version, + &state.peer_ids, + &mut state.advertisement_timeouts, + &state.metrics, + ) + .await; + } + + Ok(()) +} + +/// Get the Id of the Core that is assigned to the para being collated on if any +/// and the total number of cores. +async fn determine_core( + sender: &mut impl overseer::SubsystemSender, + para_id: ParaId, + relay_parent: Hash, + relay_parent_mode: ProspectiveParachainsMode, +) -> Result> { + let cores = get_availability_cores(sender, relay_parent).await?; + + for (idx, core) in cores.iter().enumerate() { + let core_para_id = match core { + CoreState::Scheduled(scheduled) => Some(scheduled.para_id), + CoreState::Occupied(occupied) => + if relay_parent_mode.is_enabled() { + // With async backing we don't care about the core state, + // it is only needed for figuring our validators group. + Some(occupied.candidate_descriptor.para_id) + } else { + None + }, + CoreState::Free => None, + }; + + if core_para_id == Some(para_id) { + return Ok(Some(((idx as u32).into(), cores.len()))) + } + } + + Ok(None) +} + +/// Validators of a particular group index. +#[derive(Debug)] +struct GroupValidators { + /// The validators of above group (their discovery keys). + validators: Vec, + + session_index: SessionIndex, + group_index: GroupIndex, +} + +/// Figure out current group of validators assigned to the para being collated on. +/// +/// Returns [`ValidatorId`]'s of current group as determined based on the `relay_parent`. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn determine_our_validators( + ctx: &mut Context, + runtime: &mut RuntimeInfo, + core_index: CoreIndex, + cores: usize, + relay_parent: Hash, +) -> Result { + let session_index = runtime.get_session_index_for_child(ctx.sender(), relay_parent).await?; + let info = &runtime + .get_session_info_by_index(ctx.sender(), relay_parent, session_index) + .await? + .session_info; + gum::debug!(target: LOG_TARGET, ?session_index, "Received session info"); + let groups = &info.validator_groups; + let rotation_info = get_group_rotation_info(ctx.sender(), relay_parent).await?; + + let current_group_index = rotation_info.group_for_core(core_index, cores); + let current_validators = + groups.get(current_group_index).map(|v| v.as_slice()).unwrap_or_default(); + + let validators = &info.discovery_keys; + + let current_validators = + current_validators.iter().map(|i| validators[i.0 as usize].clone()).collect(); + + let current_validators = GroupValidators { + validators: current_validators, + session_index, + group_index: current_group_index, + }; + + Ok(current_validators) +} + +/// Construct the declare message to be sent to validator depending on its +/// network protocol version. +fn declare_message( + state: &mut State, + version: CollationVersion, +) -> Option> { + let para_id = state.collating_on?; + Some(match version { + CollationVersion::V1 => { + let declare_signature_payload = + protocol_v1::declare_signature_payload(&state.local_peer_id); + let wire_message = protocol_v1::CollatorProtocolMessage::Declare( + state.collator_pair.public(), + para_id, + state.collator_pair.sign(&declare_signature_payload), + ); + Versioned::V1(protocol_v1::CollationProtocol::CollatorProtocol(wire_message)) + }, + CollationVersion::VStaging => { + let declare_signature_payload = + protocol_vstaging::declare_signature_payload(&state.local_peer_id); + let wire_message = protocol_vstaging::CollatorProtocolMessage::Declare( + state.collator_pair.public(), + para_id, + state.collator_pair.sign(&declare_signature_payload), + ); + Versioned::VStaging(protocol_vstaging::CollationProtocol::CollatorProtocol( + wire_message, + )) + }, + }) +} + +/// Issue versioned `Declare` collation message to the given `peer`. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn declare( + ctx: &mut Context, + state: &mut State, + peer: &PeerId, + version: CollationVersion, +) { + if let Some(wire_message) = declare_message(state, version) { + ctx.send_message(NetworkBridgeTxMessage::SendCollationMessage(vec![*peer], wire_message)) + .await; + } +} + +/// Updates a set of connected validators based on their advertisement-bits +/// in a validators buffer. +/// +/// Should be called again once a returned future resolves. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn connect_to_validators( + ctx: &mut Context, + validator_groups_buf: &ValidatorGroupsBuffer, +) -> ReconnectTimeout { + let validator_ids = validator_groups_buf.validators_to_connect(); + let is_disconnect = validator_ids.is_empty(); + + // ignore address resolution failure + // will reissue a new request on new collation + let (failed, _) = oneshot::channel(); + ctx.send_message(NetworkBridgeTxMessage::ConnectToValidators { + validator_ids, + peer_set: PeerSet::Collation, + failed, + }) + .await; + + if is_disconnect { + gum::trace!(target: LOG_TARGET, "Disconnecting from all peers"); + // Never resolves. + Fuse::terminated() + } else { + futures_timer::Delay::new(RECONNECT_TIMEOUT).fuse() + } +} + +/// Advertise collation to the given `peer`. +/// +/// This will only advertise a collation if there exists at least one for the given +/// `relay_parent` and the given `peer` is set as validator for our para at the given +/// `relay_parent`. +/// +/// We also make sure not to advertise the same collation multiple times to the same validator. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn advertise_collation( + ctx: &mut Context, + relay_parent: Hash, + per_relay_parent: &mut PerRelayParent, + peer: &PeerId, + protocol_version: CollationVersion, + peer_ids: &HashMap>, + advertisement_timeouts: &mut FuturesUnordered, + metrics: &Metrics, +) { + for (candidate_hash, collation) in per_relay_parent.collations.iter_mut() { + // Check that peer will be able to request the collation. + if let CollationVersion::V1 = protocol_version { + if per_relay_parent.prospective_parachains_mode.is_enabled() { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + peer_id = %peer, + "Skipping advertising to validator, incorrect network protocol version", + ); + return + } + } + + let should_advertise = + per_relay_parent + .validator_group + .should_advertise_to(candidate_hash, peer_ids, &peer); + + if !should_advertise { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + peer_id = %peer, + "Not advertising collation since validator is not interested", + ); + continue + } + + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + peer_id = %peer, + "Advertising collation.", + ); + collation.status.advance_to_advertised(); + + let collation_message = match protocol_version { + CollationVersion::VStaging => { + let wire_message = protocol_vstaging::CollatorProtocolMessage::AdvertiseCollation { + relay_parent, + candidate_hash: *candidate_hash, + parent_head_data_hash: collation.parent_head_data_hash, + }; + Versioned::VStaging(protocol_vstaging::CollationProtocol::CollatorProtocol( + wire_message, + )) + }, + CollationVersion::V1 => { + let wire_message = + protocol_v1::CollatorProtocolMessage::AdvertiseCollation(relay_parent); + Versioned::V1(protocol_v1::CollationProtocol::CollatorProtocol(wire_message)) + }, + }; + + ctx.send_message(NetworkBridgeTxMessage::SendCollationMessage( + vec![*peer], + collation_message, + )) + .await; + + per_relay_parent + .validator_group + .advertised_to_peer(candidate_hash, &peer_ids, peer); + + advertisement_timeouts.push(ResetInterestTimeout::new( + *candidate_hash, + *peer, + RESET_INTEREST_TIMEOUT, + )); + + metrics.on_advertisement_made(); + } +} + +/// The main incoming message dispatching switch. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn process_msg( + ctx: &mut Context, + runtime: &mut RuntimeInfo, + state: &mut State, + msg: CollatorProtocolMessage, +) -> Result<()> { + use CollatorProtocolMessage::*; + + match msg { + CollateOn(id) => { + state.collating_on = Some(id); + }, + DistributeCollation(receipt, parent_head_data_hash, pov, result_sender) => { + let _span1 = state + .span_per_relay_parent + .get(&receipt.descriptor.relay_parent) + .map(|s| s.child("distributing-collation")); + let _span2 = jaeger::Span::new(&pov, "distributing-collation"); + + match state.collating_on { + Some(id) if receipt.descriptor.para_id != id => { + // If the ParaId of a collation requested to be distributed does not match + // the one we expect, we ignore the message. + gum::warn!( + target: LOG_TARGET, + para_id = %receipt.descriptor.para_id, + collating_on = %id, + "DistributeCollation for unexpected para_id", + ); + }, + Some(id) => { + let _ = state.metrics.time_collation_distribution("distribute"); + distribute_collation( + ctx, + runtime, + state, + id, + receipt, + parent_head_data_hash, + pov, + result_sender, + ) + .await?; + }, + None => { + gum::warn!( + target: LOG_TARGET, + para_id = %receipt.descriptor.para_id, + "DistributeCollation message while not collating on any", + ); + }, + } + }, + NetworkBridgeUpdate(event) => { + // We should count only this shoulder in the histogram, as other shoulders are just + // introducing noise + let _ = state.metrics.time_process_msg(); + + if let Err(e) = handle_network_msg(ctx, runtime, state, event).await { + gum::warn!( + target: LOG_TARGET, + err = ?e, + "Failed to handle incoming network message", + ); + } + }, + msg @ (ReportCollator(..) | Invalid(..) | Seconded(..) | Backed { .. }) => { + gum::warn!( + target: LOG_TARGET, + "{:?} message is not expected on the collator side of the protocol", + msg, + ); + }, + } + + Ok(()) +} + +/// Issue a response to a previously requested collation. +async fn send_collation( + state: &mut State, + request: VersionedCollationRequest, + receipt: CandidateReceipt, + pov: PoV, +) { + let (tx, rx) = oneshot::channel(); + + let relay_parent = request.relay_parent(); + let peer_id = request.peer_id(); + let candidate_hash = receipt.hash(); + + // The response payload is the same for both versions of protocol + // and doesn't have vstaging alias for simplicity. + let response = OutgoingResponse { + result: Ok(request_v1::CollationFetchingResponse::Collation(receipt, pov)), + reputation_changes: Vec::new(), + sent_feedback: Some(tx), + }; + + if let Err(_) = request.send_outgoing_response(response) { + gum::warn!(target: LOG_TARGET, "Sending collation response failed"); + } + + state.active_collation_fetches.push( + async move { + let r = rx.timeout(MAX_UNSHARED_UPLOAD_TIME).await; + let timed_out = r.is_none(); + + CollationSendResult { relay_parent, candidate_hash, peer_id, timed_out } + } + .boxed(), + ); + + state.metrics.on_collation_sent(); +} + +/// A networking messages switch. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn handle_incoming_peer_message( + ctx: &mut Context, + runtime: &mut RuntimeInfo, + state: &mut State, + origin: PeerId, + msg: Versioned< + protocol_v1::CollatorProtocolMessage, + protocol_vstaging::CollatorProtocolMessage, + >, +) -> Result<()> { + use protocol_v1::CollatorProtocolMessage as V1; + use protocol_vstaging::CollatorProtocolMessage as VStaging; + + match msg { + Versioned::V1(V1::Declare(..)) | Versioned::VStaging(VStaging::Declare(..)) => { + gum::trace!( + target: LOG_TARGET, + ?origin, + "Declare message is not expected on the collator side of the protocol", + ); + + // If we are declared to, this is another collator, and we should disconnect. + ctx.send_message(NetworkBridgeTxMessage::DisconnectPeer(origin, PeerSet::Collation)) + .await; + }, + Versioned::V1(V1::AdvertiseCollation(_)) | + Versioned::VStaging(VStaging::AdvertiseCollation { .. }) => { + gum::trace!( + target: LOG_TARGET, + ?origin, + "AdvertiseCollation message is not expected on the collator side of the protocol", + ); + + modify_reputation(&mut state.reputation, ctx.sender(), origin, COST_UNEXPECTED_MESSAGE) + .await; + + // If we are advertised to, this is another collator, and we should disconnect. + ctx.send_message(NetworkBridgeTxMessage::DisconnectPeer(origin, PeerSet::Collation)) + .await; + }, + Versioned::V1(V1::CollationSeconded(relay_parent, statement)) | + Versioned::VStaging(VStaging::CollationSeconded(relay_parent, statement)) => { + if !matches!(statement.unchecked_payload(), Statement::Seconded(_)) { + gum::warn!( + target: LOG_TARGET, + ?statement, + ?origin, + "Collation seconded message received with none-seconded statement.", + ); + } else { + let statement = runtime + .check_signature(ctx.sender(), relay_parent, statement) + .await? + .map_err(Error::InvalidStatementSignature)?; + + let removed = + state.collation_result_senders.remove(&statement.payload().candidate_hash()); + + if let Some(sender) = removed { + gum::trace!( + target: LOG_TARGET, + ?statement, + ?origin, + "received a valid `CollationSeconded`", + ); + let _ = sender.send(CollationSecondedSignal { statement, relay_parent }); + } else { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?&statement.payload().candidate_hash(), + ?origin, + "received an unexpected `CollationSeconded`: unknown statement", + ); + } + } + }, + } + + Ok(()) +} + +/// Process an incoming network request for a collation. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn handle_incoming_request( + ctx: &mut Context, + state: &mut State, + req: std::result::Result, +) -> Result<()> { + let req = req?; + let relay_parent = req.relay_parent(); + let peer_id = req.peer_id(); + let para_id = req.para_id(); + + let _span = state + .span_per_relay_parent + .get(&relay_parent) + .map(|s| s.child("request-collation")); + + match state.collating_on { + Some(our_para_id) if our_para_id == para_id => { + let per_relay_parent = match state.per_relay_parent.get_mut(&relay_parent) { + Some(per_relay_parent) => per_relay_parent, + None => { + gum::debug!( + target: LOG_TARGET, + relay_parent = %relay_parent, + "received a `RequestCollation` for a relay parent out of our view", + ); + + return Ok(()) + }, + }; + let mode = per_relay_parent.prospective_parachains_mode; + + let collation = match &req { + VersionedCollationRequest::V1(_) if !mode.is_enabled() => + per_relay_parent.collations.values_mut().next(), + VersionedCollationRequest::VStaging(req) => + per_relay_parent.collations.get_mut(&req.payload.candidate_hash), + _ => { + gum::warn!( + target: LOG_TARGET, + relay_parent = %relay_parent, + prospective_parachains_mode = ?mode, + ?peer_id, + "Collation request version is invalid", + ); + + return Ok(()) + }, + }; + let (receipt, pov) = if let Some(collation) = collation { + collation.status.advance_to_requested(); + (collation.receipt.clone(), collation.pov.clone()) + } else { + gum::warn!( + target: LOG_TARGET, + relay_parent = %relay_parent, + "received a `RequestCollation` for a relay parent we don't have collation stored.", + ); + + return Ok(()) + }; + + state.metrics.on_collation_sent_requested(); + + let _span = _span.as_ref().map(|s| s.child("sending")); + + let waiting = state.waiting_collation_fetches.entry(relay_parent).or_default(); + let candidate_hash = receipt.hash(); + + if !waiting.waiting_peers.insert((peer_id, candidate_hash)) { + gum::debug!( + target: LOG_TARGET, + "Dropping incoming request as peer has a request in flight already." + ); + modify_reputation( + &mut state.reputation, + ctx.sender(), + peer_id, + COST_APPARENT_FLOOD.into(), + ) + .await; + return Ok(()) + } + + if waiting.collation_fetch_active { + waiting.req_queue.push_back(req); + } else { + waiting.collation_fetch_active = true; + // Obtain a timer for sending collation + let _ = state.metrics.time_collation_distribution("send"); + send_collation(state, req, receipt, pov).await; + } + }, + Some(our_para_id) => { + gum::warn!( + target: LOG_TARGET, + for_para_id = %para_id, + our_para_id = %our_para_id, + "received a `CollationFetchingRequest` for unexpected para_id", + ); + }, + None => { + gum::warn!( + target: LOG_TARGET, + for_para_id = %para_id, + "received a `RequestCollation` while not collating on any para", + ); + }, + } + Ok(()) +} + +/// Peer's view has changed. Send advertisements for new relay parents +/// if there're any. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn handle_peer_view_change( + ctx: &mut Context, + state: &mut State, + peer_id: PeerId, + view: View, +) { + let PeerData { view: current, version } = match state.peer_data.get_mut(&peer_id) { + Some(peer_data) => peer_data, + None => return, + }; + + let added: Vec = view.difference(&*current).cloned().collect(); + + *current = view; + + for added in added.into_iter() { + let block_hashes = match state + .per_relay_parent + .get(&added) + .map(|per_relay_parent| per_relay_parent.prospective_parachains_mode) + { + Some(ProspectiveParachainsMode::Disabled) => std::slice::from_ref(&added), + Some(ProspectiveParachainsMode::Enabled { .. }) => state + .implicit_view + .known_allowed_relay_parents_under(&added, state.collating_on) + .unwrap_or_default(), + None => { + gum::trace!( + target: LOG_TARGET, + ?peer_id, + new_leaf = ?added, + "New leaf in peer's view is unknown", + ); + continue + }, + }; + + for block_hash in block_hashes { + let per_relay_parent = match state.per_relay_parent.get_mut(block_hash) { + Some(per_relay_parent) => per_relay_parent, + None => continue, + }; + advertise_collation( + ctx, + *block_hash, + per_relay_parent, + &peer_id, + *version, + &state.peer_ids, + &mut state.advertisement_timeouts, + &state.metrics, + ) + .await; + } + } +} + +/// Bridge messages switch. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn handle_network_msg( + ctx: &mut Context, + runtime: &mut RuntimeInfo, + state: &mut State, + bridge_message: NetworkBridgeEvent, +) -> Result<()> { + use NetworkBridgeEvent::*; + + match bridge_message { + PeerConnected(peer_id, observed_role, protocol_version, maybe_authority) => { + // If it is possible that a disconnected validator would attempt a reconnect + // it should be handled here. + gum::trace!(target: LOG_TARGET, ?peer_id, ?observed_role, "Peer connected"); + + let version = match protocol_version.try_into() { + Ok(version) => version, + Err(err) => { + // Network bridge is expected to handle this. + gum::error!( + target: LOG_TARGET, + ?peer_id, + ?observed_role, + ?err, + "Unsupported protocol version" + ); + return Ok(()) + }, + }; + state + .peer_data + .entry(peer_id) + .or_insert_with(|| PeerData { view: View::default(), version }); + + if let Some(authority_ids) = maybe_authority { + gum::trace!( + target: LOG_TARGET, + ?authority_ids, + ?peer_id, + "Connected to requested validator" + ); + state.peer_ids.insert(peer_id, authority_ids); + + declare(ctx, state, &peer_id, version).await; + } + }, + PeerViewChange(peer_id, view) => { + gum::trace!(target: LOG_TARGET, ?peer_id, ?view, "Peer view change"); + handle_peer_view_change(ctx, state, peer_id, view).await; + }, + PeerDisconnected(peer_id) => { + gum::trace!(target: LOG_TARGET, ?peer_id, "Peer disconnected"); + state.peer_data.remove(&peer_id); + state.peer_ids.remove(&peer_id); + }, + OurViewChange(view) => { + gum::trace!(target: LOG_TARGET, ?view, "Own view change"); + handle_our_view_change(ctx.sender(), state, view).await?; + }, + PeerMessage(remote, msg) => { + handle_incoming_peer_message(ctx, runtime, state, remote, msg).await?; + }, + UpdatedAuthorityIds(peer_id, authority_ids) => { + gum::trace!(target: LOG_TARGET, ?peer_id, ?authority_ids, "Updated authority ids"); + state.peer_ids.insert(peer_id, authority_ids); + }, + NewGossipTopology { .. } => { + // impossible! + }, + } + + Ok(()) +} + +/// Handles our view changes. +async fn handle_our_view_change( + sender: &mut Sender, + state: &mut State, + view: OurView, +) -> Result<()> +where + Sender: CollatorProtocolSenderTrait, +{ + let current_leaves = state.active_leaves.clone(); + + let removed = current_leaves.iter().filter(|(h, _)| !view.contains(h)); + let added = view.iter().filter(|h| !current_leaves.contains_key(h)); + + for leaf in added { + let mode = prospective_parachains_mode(sender, *leaf).await?; + + if let Some(span) = view.span_per_head().get(leaf).cloned() { + let per_leaf_span = PerLeafSpan::new(span, "collator-side"); + state.span_per_relay_parent.insert(*leaf, per_leaf_span); + } + + state.active_leaves.insert(*leaf, mode); + state.per_relay_parent.insert(*leaf, PerRelayParent::new(mode)); + + if mode.is_enabled() { + state + .implicit_view + .activate_leaf(sender, *leaf) + .await + .map_err(Error::ImplicitViewFetchError)?; + + let allowed_ancestry = state + .implicit_view + .known_allowed_relay_parents_under(leaf, state.collating_on) + .unwrap_or_default(); + for block_hash in allowed_ancestry { + state + .per_relay_parent + .entry(*block_hash) + .or_insert_with(|| PerRelayParent::new(mode)); + } + } + } + + for (leaf, mode) in removed { + state.active_leaves.remove(leaf); + // If the leaf is deactivated it still may stay in the view as a part + // of implicit ancestry. Only update the state after the hash is actually + // pruned from the block info storage. + let pruned = if mode.is_enabled() { + state.implicit_view.deactivate_leaf(*leaf) + } else { + vec![*leaf] + }; + + for removed in &pruned { + gum::debug!(target: LOG_TARGET, relay_parent = ?removed, "Removing relay parent because our view changed."); + + let collations = state + .per_relay_parent + .remove(removed) + .map(|per_relay_parent| per_relay_parent.collations) + .unwrap_or_default(); + for collation in collations.into_values() { + let candidate_hash = collation.receipt.hash(); + state.collation_result_senders.remove(&candidate_hash); + state.validator_groups_buf.remove_candidate(&candidate_hash); + + match collation.status { + CollationStatus::Created => gum::warn!( + target: LOG_TARGET, + candidate_hash = ?collation.receipt.hash(), + pov_hash = ?collation.pov.hash(), + "Collation wasn't advertised to any validator.", + ), + CollationStatus::Advertised => gum::debug!( + target: LOG_TARGET, + candidate_hash = ?collation.receipt.hash(), + pov_hash = ?collation.pov.hash(), + "Collation was advertised but not requested by any validator.", + ), + CollationStatus::Requested => gum::debug!( + target: LOG_TARGET, + candidate_hash = ?collation.receipt.hash(), + pov_hash = ?collation.pov.hash(), + "Collation was requested.", + ), + } + } + state.span_per_relay_parent.remove(removed); + state.waiting_collation_fetches.remove(removed); + } + } + Ok(()) +} + +/// The collator protocol collator side main loop. +#[overseer::contextbounds(CollatorProtocol, prefix = crate::overseer)] +pub(crate) async fn run( + ctx: Context, + local_peer_id: PeerId, + collator_pair: CollatorPair, + req_v1_receiver: IncomingRequestReceiver, + req_v2_receiver: IncomingRequestReceiver, + metrics: Metrics, +) -> std::result::Result<(), FatalError> { + run_inner( + ctx, + local_peer_id, + collator_pair, + req_v1_receiver, + req_v2_receiver, + metrics, + ReputationAggregator::default(), + REPUTATION_CHANGE_INTERVAL, + ) + .await +} + +#[overseer::contextbounds(CollatorProtocol, prefix = crate::overseer)] +async fn run_inner( + mut ctx: Context, + local_peer_id: PeerId, + collator_pair: CollatorPair, + mut req_v1_receiver: IncomingRequestReceiver, + mut req_v2_receiver: IncomingRequestReceiver, + metrics: Metrics, + reputation: ReputationAggregator, + reputation_interval: Duration, +) -> std::result::Result<(), FatalError> { + use OverseerSignal::*; + + let new_reputation_delay = || futures_timer::Delay::new(reputation_interval).fuse(); + let mut reputation_delay = new_reputation_delay(); + + let mut state = State::new(local_peer_id, collator_pair, metrics, reputation); + let mut runtime = RuntimeInfo::new(None); + + loop { + let reputation_changes = || vec![COST_INVALID_REQUEST]; + let recv_req_v1 = req_v1_receiver.recv(reputation_changes).fuse(); + let recv_req_v2 = req_v2_receiver.recv(reputation_changes).fuse(); + pin_mut!(recv_req_v1); + pin_mut!(recv_req_v2); + + let mut reconnect_timeout = &mut state.reconnect_timeout; + select! { + _ = reputation_delay => { + state.reputation.send(ctx.sender()).await; + reputation_delay = new_reputation_delay(); + }, + msg = ctx.recv().fuse() => match msg.map_err(FatalError::SubsystemReceive)? { + FromOrchestra::Communication { msg } => { + log_error( + process_msg(&mut ctx, &mut runtime, &mut state, msg).await, + "Failed to process message" + )?; + }, + FromOrchestra::Signal(ActiveLeaves(_update)) => {} + FromOrchestra::Signal(BlockFinalized(..)) => {} + FromOrchestra::Signal(Conclude) => return Ok(()), + }, + CollationSendResult { relay_parent, candidate_hash, peer_id, timed_out } = + state.active_collation_fetches.select_next_some() => { + let next = if let Some(waiting) = state.waiting_collation_fetches.get_mut(&relay_parent) { + if timed_out { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + ?peer_id, + ?candidate_hash, + "Sending collation to validator timed out, carrying on with next validator." + ); + // We try to throttle requests per relay parent to give validators + // more bandwidth, but if the collation is not received within the + // timeout, we simply start processing next request. + // The request it still alive, it should be kept in a waiting queue. + } else { + for authority_id in state.peer_ids.get(&peer_id).into_iter().flatten() { + // Timeout not hit, this peer is no longer interested in this relay parent. + state.validator_groups_buf.reset_validator_interest(candidate_hash, authority_id); + } + waiting.waiting_peers.remove(&(peer_id, candidate_hash)); + } + + if let Some(next) = waiting.req_queue.pop_front() { + next + } else { + waiting.collation_fetch_active = false; + continue + } + } else { + // No waiting collation fetches means we already removed the relay parent from our view. + continue + }; + + let next_collation = { + let per_relay_parent = match state.per_relay_parent.get(&relay_parent) { + Some(per_relay_parent) => per_relay_parent, + None => continue, + }; + + match (per_relay_parent.prospective_parachains_mode, &next) { + (ProspectiveParachainsMode::Disabled, VersionedCollationRequest::V1(_)) => { + per_relay_parent.collations.values().next() + }, + (ProspectiveParachainsMode::Enabled { .. }, VersionedCollationRequest::VStaging(req)) => { + per_relay_parent.collations.get(&req.payload.candidate_hash) + }, + _ => { + // Request version is checked in `handle_incoming_request`. + continue + }, + } + }; + + if let Some(collation) = next_collation { + let receipt = collation.receipt.clone(); + let pov = collation.pov.clone(); + + send_collation(&mut state, next, receipt, pov).await; + } + }, + (candidate_hash, peer_id) = state.advertisement_timeouts.select_next_some() => { + // NOTE: it doesn't necessarily mean that a validator gets disconnected, + // it only will if there're no other advertisements we want to send. + // + // No-op if the collation was already fetched or went out of view. + for authority_id in state.peer_ids.get(&peer_id).into_iter().flatten() { + state + .validator_groups_buf + .reset_validator_interest(candidate_hash, &authority_id); + } + } + _ = reconnect_timeout => { + state.reconnect_timeout = + connect_to_validators(&mut ctx, &state.validator_groups_buf).await; + + gum::trace!( + target: LOG_TARGET, + timeout = ?RECONNECT_TIMEOUT, + "Peer-set updated due to a timeout" + ); + }, + in_req = recv_req_v1 => { + let request = in_req.map(VersionedCollationRequest::from); + + log_error( + handle_incoming_request(&mut ctx, &mut state, request).await, + "Handling incoming collation fetch request V1" + )?; + } + in_req = recv_req_v2 => { + let request = in_req.map(VersionedCollationRequest::from); + + log_error( + handle_incoming_request(&mut ctx, &mut state, request).await, + "Handling incoming collation fetch request VStaging" + )?; + } + } + } +} diff --git a/polkadot/node/network/collator-protocol/src/collator_side/tests/mod.rs b/polkadot/node/network/collator-protocol/src/collator_side/tests/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..fae719b2b4a1faf9202a93c0c43f843783981a71 --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/collator_side/tests/mod.rs @@ -0,0 +1,1507 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use std::{collections::HashSet, sync::Arc, time::Duration}; + +use assert_matches::assert_matches; +use futures::{executor, future, Future}; +use futures_timer::Delay; + +use parity_scale_codec::{Decode, Encode}; + +use sc_network::config::IncomingRequest as RawIncomingRequest; +use sp_core::crypto::Pair; +use sp_keyring::Sr25519Keyring; +use sp_runtime::traits::AppVerify; + +use polkadot_node_network_protocol::{ + our_view, + peer_set::CollationVersion, + request_response::{IncomingRequest, ReqProtocolNames}, + view, +}; +use polkadot_node_primitives::BlockData; +use polkadot_node_subsystem::{ + errors::RuntimeApiError, + jaeger, + messages::{AllMessages, ReportPeerMessage, RuntimeApiMessage, RuntimeApiRequest}, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, +}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_node_subsystem_util::{reputation::add_reputation, TimeoutExt}; +use polkadot_primitives::{ + AuthorityDiscoveryId, CollatorPair, GroupIndex, GroupRotationInfo, IndexedVec, ScheduledCore, + SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, +}; +use polkadot_primitives_test_helpers::TestCandidateBuilder; + +mod prospective_parachains; + +const REPUTATION_CHANGE_TEST_INTERVAL: Duration = Duration::from_millis(10); + +const ASYNC_BACKING_DISABLED_ERROR: RuntimeApiError = + RuntimeApiError::NotSupported { runtime_api_name: "test-runtime" }; + +#[derive(Clone)] +struct TestState { + para_id: ParaId, + session_info: SessionInfo, + group_rotation_info: GroupRotationInfo, + validator_peer_id: Vec, + relay_parent: Hash, + availability_cores: Vec, + local_peer_id: PeerId, + collator_pair: CollatorPair, + session_index: SessionIndex, +} + +fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> IndexedVec { + val_ids.iter().map(|v| v.public().into()).collect() +} + +fn validator_authority_id(val_ids: &[Sr25519Keyring]) -> Vec { + val_ids.iter().map(|v| v.public().into()).collect() +} + +impl Default for TestState { + fn default() -> Self { + let para_id = ParaId::from(1); + + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + + let validator_public = validator_pubkeys(&validators); + let discovery_keys = validator_authority_id(&validators); + + let validator_peer_id = + std::iter::repeat_with(|| PeerId::random()).take(discovery_keys.len()).collect(); + + let validator_groups = vec![vec![2, 0, 4], vec![1, 3]] + .into_iter() + .map(|g| g.into_iter().map(ValidatorIndex).collect()) + .collect(); + let group_rotation_info = + GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 100, now: 1 }; + + let availability_cores = + vec![CoreState::Scheduled(ScheduledCore { para_id, collator: None }), CoreState::Free]; + + let relay_parent = Hash::random(); + + let local_peer_id = PeerId::random(); + let collator_pair = CollatorPair::generate().0; + + Self { + para_id, + session_info: SessionInfo { + validators: validator_public, + discovery_keys, + validator_groups, + assignment_keys: vec![], + n_cores: 0, + zeroth_delay_tranche_width: 0, + relay_vrf_modulo_samples: 0, + n_delay_tranches: 0, + no_show_slots: 0, + needed_approvals: 0, + active_validator_indices: vec![], + dispute_period: 6, + random_seed: [0u8; 32], + }, + group_rotation_info, + validator_peer_id, + relay_parent, + availability_cores, + local_peer_id, + collator_pair, + session_index: 1, + } + } +} + +impl TestState { + fn current_group_validator_indices(&self) -> &[ValidatorIndex] { + let core_num = self.availability_cores.len(); + let GroupIndex(group_idx) = self.group_rotation_info.group_for_core(CoreIndex(0), core_num); + &self.session_info.validator_groups.get(GroupIndex::from(group_idx)).unwrap() + } + + fn current_session_index(&self) -> SessionIndex { + self.session_index + } + + fn current_group_validator_peer_ids(&self) -> Vec { + self.current_group_validator_indices() + .iter() + .map(|i| self.validator_peer_id[i.0 as usize]) + .collect() + } + + fn current_group_validator_authority_ids(&self) -> Vec { + self.current_group_validator_indices() + .iter() + .map(|i| self.session_info.discovery_keys[i.0 as usize].clone()) + .collect() + } + + /// Generate a new relay parent and inform the subsystem about the new view. + /// + /// If `merge_views == true` it means the subsystem will be informed that we are working on the + /// old `relay_parent` and the new one. + async fn advance_to_new_round( + &mut self, + virtual_overseer: &mut VirtualOverseer, + merge_views: bool, + ) { + let old_relay_parent = self.relay_parent; + + while self.relay_parent == old_relay_parent { + self.relay_parent.randomize(); + } + + let our_view = if merge_views { + our_view![old_relay_parent, self.relay_parent] + } else { + our_view![self.relay_parent] + }; + + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view, + )), + ) + .await; + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::StagingAsyncBackingParams(tx) + )) => { + assert_eq!(relay_parent, self.relay_parent); + tx.send(Err(ASYNC_BACKING_DISABLED_ERROR)).unwrap(); + } + ); + } +} + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; + +struct TestHarness { + virtual_overseer: VirtualOverseer, + req_v1_cfg: sc_network::config::RequestResponseConfig, + req_vstaging_cfg: sc_network::config::RequestResponseConfig, +} + +fn test_harness>( + local_peer_id: PeerId, + collator_pair: CollatorPair, + reputation: ReputationAggregator, + test: impl FnOnce(TestHarness) -> T, +) { + let _ = env_logger::builder() + .is_test(true) + .filter(Some("polkadot_collator_protocol"), log::LevelFilter::Trace) + .filter(Some(LOG_TARGET), log::LevelFilter::Trace) + .try_init(); + + let pool = sp_core::testing::TaskExecutor::new(); + + let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); + + let genesis_hash = Hash::repeat_byte(0xff); + let req_protocol_names = ReqProtocolNames::new(&genesis_hash, None); + + let (collation_req_receiver, req_v1_cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + let (collation_req_vstaging_receiver, req_vstaging_cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + let subsystem = async { + run_inner( + context, + local_peer_id, + collator_pair, + collation_req_receiver, + collation_req_vstaging_receiver, + Default::default(), + reputation, + REPUTATION_CHANGE_TEST_INTERVAL, + ) + .await + .unwrap(); + }; + + let test_fut = test(TestHarness { virtual_overseer, req_v1_cfg, req_vstaging_cfg }); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + executor::block_on(future::join( + async move { + let mut test_harness = test_fut.await; + overseer_signal(&mut test_harness.virtual_overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )) + .1 +} + +const TIMEOUT: Duration = Duration::from_millis(100); + +async fn overseer_send(overseer: &mut VirtualOverseer, msg: CollatorProtocolMessage) { + gum::trace!(?msg, "sending message"); + overseer + .send(FromOrchestra::Communication { msg }) + .timeout(TIMEOUT) + .await + .expect(&format!("{:?} is more than enough for sending messages.", TIMEOUT)); +} + +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { + let msg = overseer_recv_with_timeout(overseer, TIMEOUT) + .await + .expect(&format!("{:?} is more than enough to receive messages", TIMEOUT)); + + gum::trace!(?msg, "received message"); + + msg +} + +async fn overseer_recv_with_timeout( + overseer: &mut VirtualOverseer, + timeout: Duration, +) -> Option { + gum::trace!("waiting for message..."); + overseer.recv().timeout(timeout).await +} + +async fn overseer_signal(overseer: &mut VirtualOverseer, signal: OverseerSignal) { + overseer + .send(FromOrchestra::Signal(signal)) + .timeout(TIMEOUT) + .await + .expect(&format!("{:?} is more than enough for sending signals.", TIMEOUT)); +} + +// Setup the system by sending the `CollateOn`, `ActiveLeaves` and `OurViewChange` messages. +async fn setup_system(virtual_overseer: &mut VirtualOverseer, test_state: &TestState) { + overseer_send(virtual_overseer, CollatorProtocolMessage::CollateOn(test_state.para_id)).await; + + overseer_signal( + virtual_overseer, + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: test_state.relay_parent, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })), + ) + .await; + + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange(our_view![ + test_state.relay_parent + ])), + ) + .await; + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::StagingAsyncBackingParams(tx) + )) => { + assert_eq!(relay_parent, test_state.relay_parent); + tx.send(Err(ASYNC_BACKING_DISABLED_ERROR)).unwrap(); + } + ); +} + +/// Result of [`distribute_collation`] +struct DistributeCollation { + candidate: CandidateReceipt, + pov_block: PoV, +} + +async fn distribute_collation_with_receipt( + virtual_overseer: &mut VirtualOverseer, + test_state: &TestState, + relay_parent: Hash, + should_connect: bool, + candidate: CandidateReceipt, + pov: PoV, + parent_head_data_hash: Hash, +) -> DistributeCollation { + overseer_send( + virtual_overseer, + CollatorProtocolMessage::DistributeCollation( + candidate.clone(), + parent_head_data_hash, + pov.clone(), + None, + ), + ) + .await; + + // obtain the availability cores. + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _relay_parent, + RuntimeApiRequest::AvailabilityCores(tx) + )) => { + assert_eq!(relay_parent, _relay_parent); + tx.send(Ok(test_state.availability_cores.clone())).unwrap(); + } + ); + + // We don't know precisely what is going to come as session info might be cached: + loop { + match overseer_recv(virtual_overseer).await { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + assert_eq!(relay_parent, relay_parent); + tx.send(Ok(test_state.current_session_index())).unwrap(); + }, + + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionInfo(index, tx), + )) => { + assert_eq!(relay_parent, relay_parent); + assert_eq!(index, test_state.current_session_index()); + + tx.send(Ok(Some(test_state.session_info.clone()))).unwrap(); + }, + + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _relay_parent, + RuntimeApiRequest::ValidatorGroups(tx), + )) => { + assert_eq!(_relay_parent, relay_parent); + tx.send(Ok(( + test_state.session_info.validator_groups.to_vec(), + test_state.group_rotation_info.clone(), + ))) + .unwrap(); + // This call is mandatory - we are done: + break + }, + other => panic!("Unexpected message received: {:?}", other), + } + } + + if should_connect { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ConnectToValidators { + .. + } + ) => {} + ); + } + + DistributeCollation { candidate, pov_block: pov } +} + +/// Create some PoV and distribute it. +async fn distribute_collation( + virtual_overseer: &mut VirtualOverseer, + test_state: &TestState, + relay_parent: Hash, + // whether or not we expect a connection request or not. + should_connect: bool, +) -> DistributeCollation { + // Now we want to distribute a `PoVBlock` + let pov_block = PoV { block_data: BlockData(vec![42, 43, 44]) }; + + let pov_hash = pov_block.hash(); + let parent_head_data_hash = Hash::zero(); + + let candidate = TestCandidateBuilder { + para_id: test_state.para_id, + relay_parent, + pov_hash, + ..Default::default() + } + .build(); + + distribute_collation_with_receipt( + virtual_overseer, + test_state, + relay_parent, + should_connect, + candidate, + pov_block, + parent_head_data_hash, + ) + .await +} + +/// Connect a peer +async fn connect_peer( + virtual_overseer: &mut VirtualOverseer, + peer: PeerId, + version: CollationVersion, + authority_id: Option, +) { + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerConnected( + peer, + polkadot_node_network_protocol::ObservedRole::Authority, + version.into(), + authority_id.map(|v| HashSet::from([v])), + )), + ) + .await; + + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerViewChange( + peer, + view![], + )), + ) + .await; +} + +/// Disconnect a peer +async fn disconnect_peer(virtual_overseer: &mut VirtualOverseer, peer: PeerId) { + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerDisconnected(peer)), + ) + .await; +} + +/// Check that the next received message is a `Declare` message. +async fn expect_declare_msg( + virtual_overseer: &mut VirtualOverseer, + test_state: &TestState, + peer: &PeerId, +) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendCollationMessage( + to, + Versioned::V1(protocol_v1::CollationProtocol::CollatorProtocol(wire_message)), + ) + ) => { + assert_eq!(to[0], *peer); + assert_matches!( + wire_message, + protocol_v1::CollatorProtocolMessage::Declare( + collator_id, + para_id, + signature, + ) => { + assert!(signature.verify( + &*protocol_v1::declare_signature_payload(&test_state.local_peer_id), + &collator_id), + ); + assert_eq!(collator_id, test_state.collator_pair.public()); + assert_eq!(para_id, test_state.para_id); + } + ); + } + ); +} + +/// Check that the next received message is a collation advertisement message. +/// +/// Expects vstaging message if `expected_candidate_hashes` is `Some`, v1 otherwise. +async fn expect_advertise_collation_msg( + virtual_overseer: &mut VirtualOverseer, + peer: &PeerId, + expected_relay_parent: Hash, + expected_candidate_hashes: Option>, +) { + let mut candidate_hashes: Option> = + expected_candidate_hashes.map(|hashes| hashes.into_iter().collect()); + let iter_num = candidate_hashes.as_ref().map(|hashes| hashes.len()).unwrap_or(1); + + for _ in 0..iter_num { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendCollationMessage( + to, + wire_message, + ) + ) => { + assert_eq!(to[0], *peer); + match (candidate_hashes.as_mut(), wire_message) { + (None, Versioned::V1(protocol_v1::CollationProtocol::CollatorProtocol(wire_message))) => { + assert_matches!( + wire_message, + protocol_v1::CollatorProtocolMessage::AdvertiseCollation( + relay_parent, + ) => { + assert_eq!(relay_parent, expected_relay_parent); + } + ); + }, + ( + Some(candidate_hashes), + Versioned::VStaging(protocol_vstaging::CollationProtocol::CollatorProtocol( + wire_message, + )), + ) => { + assert_matches!( + wire_message, + protocol_vstaging::CollatorProtocolMessage::AdvertiseCollation { + relay_parent, + candidate_hash, + .. + } => { + assert_eq!(relay_parent, expected_relay_parent); + assert!(candidate_hashes.contains(&candidate_hash)); + + // Drop the hash we've already seen. + candidate_hashes.remove(&candidate_hash); + } + ); + }, + _ => panic!("Invalid advertisement"), + } + } + ); + } +} + +/// Send a message that the given peer's view changed. +async fn send_peer_view_change( + virtual_overseer: &mut VirtualOverseer, + peer: &PeerId, + hashes: Vec, +) { + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerViewChange( + *peer, + View::new(hashes, 0), + )), + ) + .await; +} + +#[test] +fn advertise_and_send_collation() { + let mut test_state = TestState::default(); + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |test_harness| async move { + let mut virtual_overseer = test_harness.virtual_overseer; + let mut req_v1_cfg = test_harness.req_v1_cfg; + let req_vstaging_cfg = test_harness.req_vstaging_cfg; + + setup_system(&mut virtual_overseer, &test_state).await; + + let DistributeCollation { candidate, pov_block } = distribute_collation( + &mut virtual_overseer, + &test_state, + test_state.relay_parent, + true, + ) + .await; + + for (val, peer) in test_state + .current_group_validator_authority_ids() + .into_iter() + .zip(test_state.current_group_validator_peer_ids()) + { + connect_peer(&mut virtual_overseer, peer, CollationVersion::V1, Some(val.clone())) + .await; + } + + // We declare to the connected validators that we are a collator. + // We need to catch all `Declare` messages to the validators we've + // previously connected to. + for peer_id in test_state.current_group_validator_peer_ids() { + expect_declare_msg(&mut virtual_overseer, &test_state, &peer_id).await; + } + + let peer = test_state.current_group_validator_peer_ids()[0]; + + // Send info about peer's view. + send_peer_view_change(&mut virtual_overseer, &peer, vec![test_state.relay_parent]) + .await; + + // The peer is interested in a leaf that we have a collation for; + // advertise it. + expect_advertise_collation_msg( + &mut virtual_overseer, + &peer, + test_state.relay_parent, + None, + ) + .await; + + // Request a collation. + let (pending_response, rx) = oneshot::channel(); + req_v1_cfg + .inbound_queue + .as_mut() + .unwrap() + .send(RawIncomingRequest { + peer, + payload: request_v1::CollationFetchingRequest { + relay_parent: test_state.relay_parent, + para_id: test_state.para_id, + } + .encode(), + pending_response, + }) + .await + .unwrap(); + // Second request by same validator should get dropped and peer reported: + { + let (pending_response, rx) = oneshot::channel(); + + req_v1_cfg + .inbound_queue + .as_mut() + .unwrap() + .send(RawIncomingRequest { + peer, + payload: request_v1::CollationFetchingRequest { + relay_parent: test_state.relay_parent, + para_id: test_state.para_id, + } + .encode(), + pending_response, + }) + .await + .unwrap(); + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(bad_peer, _))) => { + assert_eq!(bad_peer, peer); + } + ); + assert_matches!( + rx.await, + Err(_), + "Multiple concurrent requests by the same validator should get dropped." + ); + } + + assert_matches!( + rx.await, + Ok(full_response) => { + let request_v1::CollationFetchingResponse::Collation(receipt, pov): request_v1::CollationFetchingResponse + = request_v1::CollationFetchingResponse::decode( + &mut full_response.result + .expect("We should have a proper answer").as_ref() + ) + .expect("Decoding should work"); + assert_eq!(receipt, candidate); + assert_eq!(pov, pov_block); + } + ); + + let old_relay_parent = test_state.relay_parent; + test_state.advance_to_new_round(&mut virtual_overseer, false).await; + + let peer = test_state.validator_peer_id[2]; + + // Re-request a collation. + let (pending_response, rx) = oneshot::channel(); + + req_v1_cfg + .inbound_queue + .as_mut() + .unwrap() + .send(RawIncomingRequest { + peer, + payload: request_v1::CollationFetchingRequest { + relay_parent: old_relay_parent, + para_id: test_state.para_id, + } + .encode(), + pending_response, + }) + .await + .unwrap(); + // Re-requesting collation should fail: + rx.await.unwrap_err(); + + assert!(overseer_recv_with_timeout(&mut virtual_overseer, TIMEOUT).await.is_none()); + + distribute_collation(&mut virtual_overseer, &test_state, test_state.relay_parent, true) + .await; + + // Send info about peer's view. + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerViewChange( + peer, + view![test_state.relay_parent], + )), + ) + .await; + + expect_advertise_collation_msg( + &mut virtual_overseer, + &peer, + test_state.relay_parent, + None, + ) + .await; + TestHarness { virtual_overseer, req_v1_cfg, req_vstaging_cfg } + }, + ); +} + +#[test] +fn delay_reputation_change() { + let test_state = TestState::default(); + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| false), + |test_harness| async move { + let mut virtual_overseer = test_harness.virtual_overseer; + let mut req_v1_cfg = test_harness.req_v1_cfg; + let req_vstaging_cfg = test_harness.req_vstaging_cfg; + + setup_system(&mut virtual_overseer, &test_state).await; + + let _ = distribute_collation( + &mut virtual_overseer, + &test_state, + test_state.relay_parent, + true, + ) + .await; + + for (val, peer) in test_state + .current_group_validator_authority_ids() + .into_iter() + .zip(test_state.current_group_validator_peer_ids()) + { + connect_peer(&mut virtual_overseer, peer, CollationVersion::V1, Some(val.clone())) + .await; + } + + // We declare to the connected validators that we are a collator. + // We need to catch all `Declare` messages to the validators we've + // previously connected to. + for peer_id in test_state.current_group_validator_peer_ids() { + expect_declare_msg(&mut virtual_overseer, &test_state, &peer_id).await; + } + + let peer = test_state.current_group_validator_peer_ids()[0]; + + // Send info about peer's view. + send_peer_view_change(&mut virtual_overseer, &peer, vec![test_state.relay_parent]) + .await; + + // The peer is interested in a leaf that we have a collation for; + // advertise it. + expect_advertise_collation_msg( + &mut virtual_overseer, + &peer, + test_state.relay_parent, + None, + ) + .await; + + // Request a collation. + let (pending_response, _rx) = oneshot::channel(); + req_v1_cfg + .inbound_queue + .as_mut() + .unwrap() + .send(RawIncomingRequest { + peer, + payload: request_v1::CollationFetchingRequest { + relay_parent: test_state.relay_parent, + para_id: test_state.para_id, + } + .encode(), + pending_response, + }) + .await + .unwrap(); + // Second request by same validator should get dropped and peer reported: + { + let (pending_response, _rx) = oneshot::channel(); + + req_v1_cfg + .inbound_queue + .as_mut() + .unwrap() + .send(RawIncomingRequest { + peer, + payload: request_v1::CollationFetchingRequest { + relay_parent: test_state.relay_parent, + para_id: test_state.para_id, + } + .encode(), + pending_response, + }) + .await + .unwrap(); + + // Wait enough to fire reputation delay + futures_timer::Delay::new(REPUTATION_CHANGE_TEST_INTERVAL).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Batch(v))) => { + let mut expected_change = HashMap::new(); + for rep in vec![COST_APPARENT_FLOOD] { + add_reputation(&mut expected_change, peer, rep); + } + assert_eq!(v, expected_change); + } + ); + } + + TestHarness { virtual_overseer, req_v1_cfg, req_vstaging_cfg } + }, + ); +} + +/// Tests that collator side works with vstaging network protocol +/// before async backing is enabled. +#[test] +fn advertise_collation_vstaging_protocol() { + let test_state = TestState::default(); + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |mut test_harness| async move { + let virtual_overseer = &mut test_harness.virtual_overseer; + + setup_system(virtual_overseer, &test_state).await; + + let DistributeCollation { candidate, .. } = + distribute_collation(virtual_overseer, &test_state, test_state.relay_parent, true) + .await; + + let validators = test_state.current_group_validator_authority_ids(); + assert!(validators.len() >= 2); + let peer_ids = test_state.current_group_validator_peer_ids(); + + // Connect first peer with v1. + connect_peer( + virtual_overseer, + peer_ids[0], + CollationVersion::V1, + Some(validators[0].clone()), + ) + .await; + // The rest with vstaging. + for (val, peer) in validators.iter().zip(peer_ids.iter()).skip(1) { + connect_peer( + virtual_overseer, + *peer, + CollationVersion::VStaging, + Some(val.clone()), + ) + .await; + } + + // Declare messages. + expect_declare_msg(virtual_overseer, &test_state, &peer_ids[0]).await; + for peer_id in peer_ids.iter().skip(1) { + prospective_parachains::expect_declare_msg_vstaging( + virtual_overseer, + &test_state, + &peer_id, + ) + .await; + } + + // Send info about peers view. + for peer in peer_ids.iter() { + send_peer_view_change(virtual_overseer, peer, vec![test_state.relay_parent]).await; + } + + // Versioned advertisements work. + expect_advertise_collation_msg( + virtual_overseer, + &peer_ids[0], + test_state.relay_parent, + None, + ) + .await; + for peer_id in peer_ids.iter().skip(1) { + expect_advertise_collation_msg( + virtual_overseer, + peer_id, + test_state.relay_parent, + Some(vec![candidate.hash()]), // This is `Some`, advertisement is vstaging. + ) + .await; + } + + test_harness + }, + ); +} + +#[test] +#[allow(clippy::async_yields_async)] +fn send_only_one_collation_per_relay_parent_at_a_time() { + test_validator_send_sequence(|mut second_response_receiver, feedback_first_tx| async move { + Delay::new(Duration::from_millis(100)).await; + assert!( + second_response_receiver.try_recv().unwrap().is_none(), + "We should not have send the collation yet to the second validator", + ); + + // Signal that the collation fetch is finished + feedback_first_tx.send(()).expect("Sending collation fetch finished"); + second_response_receiver + }); +} + +#[test] +#[allow(clippy::async_yields_async)] +fn send_next_collation_after_max_unshared_upload_time() { + test_validator_send_sequence(|second_response_receiver, _| async move { + Delay::new(MAX_UNSHARED_UPLOAD_TIME + Duration::from_millis(50)).await; + second_response_receiver + }); +} + +#[test] +fn collators_declare_to_connected_peers() { + let test_state = TestState::default(); + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |mut test_harness| async move { + let peer = test_state.validator_peer_id[0]; + let validator_id = test_state.current_group_validator_authority_ids()[0].clone(); + + setup_system(&mut test_harness.virtual_overseer, &test_state).await; + + // A validator connected to us + connect_peer( + &mut test_harness.virtual_overseer, + peer, + CollationVersion::V1, + Some(validator_id), + ) + .await; + expect_declare_msg(&mut test_harness.virtual_overseer, &test_state, &peer).await; + test_harness + }, + ) +} + +#[test] +fn collations_are_only_advertised_to_validators_with_correct_view() { + let test_state = TestState::default(); + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |mut test_harness| async move { + let virtual_overseer = &mut test_harness.virtual_overseer; + + let peer = test_state.current_group_validator_peer_ids()[0]; + let validator_id = test_state.current_group_validator_authority_ids()[0].clone(); + + let peer2 = test_state.current_group_validator_peer_ids()[1]; + let validator_id2 = test_state.current_group_validator_authority_ids()[1].clone(); + + setup_system(virtual_overseer, &test_state).await; + + // A validator connected to us + connect_peer(virtual_overseer, peer, CollationVersion::V1, Some(validator_id)).await; + + // Connect the second validator + connect_peer(virtual_overseer, peer2, CollationVersion::V1, Some(validator_id2)).await; + + expect_declare_msg(virtual_overseer, &test_state, &peer).await; + expect_declare_msg(virtual_overseer, &test_state, &peer2).await; + + // And let it tell us that it is has the same view. + send_peer_view_change(virtual_overseer, &peer2, vec![test_state.relay_parent]).await; + + distribute_collation(virtual_overseer, &test_state, test_state.relay_parent, true) + .await; + + expect_advertise_collation_msg(virtual_overseer, &peer2, test_state.relay_parent, None) + .await; + + // The other validator announces that it changed its view. + send_peer_view_change(virtual_overseer, &peer, vec![test_state.relay_parent]).await; + + // After changing the view we should receive the advertisement + expect_advertise_collation_msg(virtual_overseer, &peer, test_state.relay_parent, None) + .await; + test_harness + }, + ) +} + +#[test] +fn collate_on_two_different_relay_chain_blocks() { + let mut test_state = TestState::default(); + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |mut test_harness| async move { + let virtual_overseer = &mut test_harness.virtual_overseer; + + let peer = test_state.current_group_validator_peer_ids()[0]; + let validator_id = test_state.current_group_validator_authority_ids()[0].clone(); + + let peer2 = test_state.current_group_validator_peer_ids()[1]; + let validator_id2 = test_state.current_group_validator_authority_ids()[1].clone(); + + setup_system(virtual_overseer, &test_state).await; + + // A validator connected to us + connect_peer(virtual_overseer, peer, CollationVersion::V1, Some(validator_id)).await; + + // Connect the second validator + connect_peer(virtual_overseer, peer2, CollationVersion::V1, Some(validator_id2)).await; + + expect_declare_msg(virtual_overseer, &test_state, &peer).await; + expect_declare_msg(virtual_overseer, &test_state, &peer2).await; + + distribute_collation(virtual_overseer, &test_state, test_state.relay_parent, true) + .await; + + let old_relay_parent = test_state.relay_parent; + + // Advance to a new round, while informing the subsystem that the old and the new relay + // parent are active. + test_state.advance_to_new_round(virtual_overseer, true).await; + + distribute_collation(virtual_overseer, &test_state, test_state.relay_parent, true) + .await; + + send_peer_view_change(virtual_overseer, &peer, vec![old_relay_parent]).await; + expect_advertise_collation_msg(virtual_overseer, &peer, old_relay_parent, None).await; + + send_peer_view_change(virtual_overseer, &peer2, vec![test_state.relay_parent]).await; + + expect_advertise_collation_msg(virtual_overseer, &peer2, test_state.relay_parent, None) + .await; + test_harness + }, + ) +} + +#[test] +fn validator_reconnect_does_not_advertise_a_second_time() { + let test_state = TestState::default(); + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |mut test_harness| async move { + let virtual_overseer = &mut test_harness.virtual_overseer; + + let peer = test_state.current_group_validator_peer_ids()[0]; + let validator_id = test_state.current_group_validator_authority_ids()[0].clone(); + + setup_system(virtual_overseer, &test_state).await; + + // A validator connected to us + connect_peer(virtual_overseer, peer, CollationVersion::V1, Some(validator_id.clone())) + .await; + expect_declare_msg(virtual_overseer, &test_state, &peer).await; + + distribute_collation(virtual_overseer, &test_state, test_state.relay_parent, true) + .await; + + send_peer_view_change(virtual_overseer, &peer, vec![test_state.relay_parent]).await; + expect_advertise_collation_msg(virtual_overseer, &peer, test_state.relay_parent, None) + .await; + + // Disconnect and reconnect directly + disconnect_peer(virtual_overseer, peer).await; + connect_peer(virtual_overseer, peer, CollationVersion::V1, Some(validator_id)).await; + expect_declare_msg(virtual_overseer, &test_state, &peer).await; + + send_peer_view_change(virtual_overseer, &peer, vec![test_state.relay_parent]).await; + + assert!(overseer_recv_with_timeout(virtual_overseer, TIMEOUT).await.is_none()); + test_harness + }, + ) +} + +#[test] +fn collators_reject_declare_messages() { + let test_state = TestState::default(); + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + let collator_pair2 = CollatorPair::generate().0; + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |mut test_harness| async move { + let virtual_overseer = &mut test_harness.virtual_overseer; + + let peer = test_state.current_group_validator_peer_ids()[0]; + let validator_id = test_state.current_group_validator_authority_ids()[0].clone(); + + setup_system(virtual_overseer, &test_state).await; + + // A validator connected to us + connect_peer(virtual_overseer, peer, CollationVersion::V1, Some(validator_id)).await; + expect_declare_msg(virtual_overseer, &test_state, &peer).await; + + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerMessage( + peer, + Versioned::V1(protocol_v1::CollatorProtocolMessage::Declare( + collator_pair2.public(), + ParaId::from(5), + collator_pair2.sign(b"garbage"), + )), + )), + ) + .await; + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::DisconnectPeer( + p, + PeerSet::Collation, + )) if p == peer + ); + test_harness + }, + ) +} + +/// Run tests on validator response sequence. +/// +/// After the first response is done, the passed in lambda will be called with the receiver for the +/// next response and a sender for giving feedback on the response of the first transmission. After +/// the lambda has passed it is assumed that the second response is sent, which is checked by this +/// function. +/// +/// The lambda can trigger occasions on which the second response should be sent, like timeouts, +/// successful completion. +fn test_validator_send_sequence(handle_first_response: T) +where + T: FnOnce(oneshot::Receiver, oneshot::Sender<()>) -> F, + F: Future>, +{ + let test_state = TestState::default(); + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |mut test_harness| async move { + let virtual_overseer = &mut test_harness.virtual_overseer; + let req_cfg = &mut test_harness.req_v1_cfg; + + setup_system(virtual_overseer, &test_state).await; + + let DistributeCollation { candidate, pov_block } = + distribute_collation(virtual_overseer, &test_state, test_state.relay_parent, true) + .await; + + for (val, peer) in test_state + .current_group_validator_authority_ids() + .into_iter() + .zip(test_state.current_group_validator_peer_ids()) + { + connect_peer(virtual_overseer, peer, CollationVersion::V1, Some(val.clone())).await; + } + + // We declare to the connected validators that we are a collator. + // We need to catch all `Declare` messages to the validators we've + // previously connected to. + for peer_id in test_state.current_group_validator_peer_ids() { + expect_declare_msg(virtual_overseer, &test_state, &peer_id).await; + } + + let validator_0 = test_state.current_group_validator_peer_ids()[0]; + let validator_1 = test_state.current_group_validator_peer_ids()[1]; + + // Send info about peer's view. + send_peer_view_change(virtual_overseer, &validator_0, vec![test_state.relay_parent]) + .await; + send_peer_view_change(virtual_overseer, &validator_1, vec![test_state.relay_parent]) + .await; + + // The peer is interested in a leaf that we have a collation for; + // advertise it. + expect_advertise_collation_msg( + virtual_overseer, + &validator_0, + test_state.relay_parent, + None, + ) + .await; + expect_advertise_collation_msg( + virtual_overseer, + &validator_1, + test_state.relay_parent, + None, + ) + .await; + + // Request a collation. + let (pending_response, rx) = oneshot::channel(); + req_cfg + .inbound_queue + .as_mut() + .unwrap() + .send(RawIncomingRequest { + peer: validator_0, + payload: request_v1::CollationFetchingRequest { + relay_parent: test_state.relay_parent, + para_id: test_state.para_id, + } + .encode(), + pending_response, + }) + .await + .unwrap(); + + // Keep the feedback channel alive because we need to use it to inform about the + // finished transfer. + let feedback_tx = assert_matches!( + rx.await, + Ok(full_response) => { + let request_v1::CollationFetchingResponse::Collation(receipt, pov): request_v1::CollationFetchingResponse + = request_v1::CollationFetchingResponse::decode( + &mut full_response.result + .expect("We should have a proper answer").as_ref() + ) + .expect("Decoding should work"); + assert_eq!(receipt, candidate); + assert_eq!(pov, pov_block); + + full_response.sent_feedback.expect("Feedback channel is always set") + } + ); + + // Let the second validator request the collation. + let (pending_response, rx) = oneshot::channel(); + req_cfg + .inbound_queue + .as_mut() + .unwrap() + .send(RawIncomingRequest { + peer: validator_1, + payload: request_v1::CollationFetchingRequest { + relay_parent: test_state.relay_parent, + para_id: test_state.para_id, + } + .encode(), + pending_response, + }) + .await + .unwrap(); + + let rx = handle_first_response(rx, feedback_tx).await; + + // Now we should send it to the second validator + assert_matches!( + rx.await, + Ok(full_response) => { + let request_v1::CollationFetchingResponse::Collation(receipt, pov): request_v1::CollationFetchingResponse + = request_v1::CollationFetchingResponse::decode( + &mut full_response.result + .expect("We should have a proper answer").as_ref() + ) + .expect("Decoding should work"); + assert_eq!(receipt, candidate); + assert_eq!(pov, pov_block); + + full_response.sent_feedback.expect("Feedback channel is always set") + } + ); + + test_harness + }, + ); +} + +#[test] +fn connect_to_buffered_groups() { + let mut test_state = TestState::default(); + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |test_harness| async move { + let mut virtual_overseer = test_harness.virtual_overseer; + let mut req_cfg = test_harness.req_v1_cfg; + let req_vstaging_cfg = test_harness.req_vstaging_cfg; + + setup_system(&mut virtual_overseer, &test_state).await; + + let group_a = test_state.current_group_validator_authority_ids(); + let peers_a = test_state.current_group_validator_peer_ids(); + assert!(group_a.len() > 1); + + distribute_collation( + &mut virtual_overseer, + &test_state, + test_state.relay_parent, + false, + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ConnectToValidators { validator_ids, .. } + ) => { + assert_eq!(group_a, validator_ids); + } + ); + + let head_a = test_state.relay_parent; + + for (val, peer) in group_a.iter().zip(&peers_a) { + connect_peer(&mut virtual_overseer, *peer, CollationVersion::V1, Some(val.clone())) + .await; + } + + for peer_id in &peers_a { + expect_declare_msg(&mut virtual_overseer, &test_state, peer_id).await; + } + + // Update views. + for peed_id in &peers_a { + send_peer_view_change(&mut virtual_overseer, peed_id, vec![head_a]).await; + expect_advertise_collation_msg(&mut virtual_overseer, peed_id, head_a, None).await; + } + + let peer = peers_a[0]; + // Peer from the group fetches the collation. + let (pending_response, rx) = oneshot::channel(); + req_cfg + .inbound_queue + .as_mut() + .unwrap() + .send(RawIncomingRequest { + peer, + payload: request_v1::CollationFetchingRequest { + relay_parent: head_a, + para_id: test_state.para_id, + } + .encode(), + pending_response, + }) + .await + .unwrap(); + assert_matches!( + rx.await, + Ok(full_response) => { + let request_v1::CollationFetchingResponse::Collation(..) = + request_v1::CollationFetchingResponse::decode( + &mut full_response.result.expect("We should have a proper answer").as_ref(), + ) + .expect("Decoding should work"); + } + ); + + // Let the subsystem process process the collation event. + test_helpers::Yield::new().await; + + test_state.advance_to_new_round(&mut virtual_overseer, true).await; + test_state.group_rotation_info = test_state.group_rotation_info.bump_rotation(); + + let head_b = test_state.relay_parent; + let group_b = test_state.current_group_validator_authority_ids(); + assert_ne!(head_a, head_b); + assert_ne!(group_a, group_b); + + distribute_collation( + &mut virtual_overseer, + &test_state, + test_state.relay_parent, + false, + ) + .await; + + // Should be connected to both groups except for the validator that fetched advertised + // collation. + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ConnectToValidators { validator_ids, .. } + ) => { + assert!(!validator_ids.contains(&group_a[0])); + + for validator in group_a[1..].iter().chain(&group_b) { + assert!(validator_ids.contains(validator)); + } + } + ); + + TestHarness { virtual_overseer, req_v1_cfg: req_cfg, req_vstaging_cfg } + }, + ); +} diff --git a/polkadot/node/network/collator-protocol/src/collator_side/tests/prospective_parachains.rs b/polkadot/node/network/collator-protocol/src/collator_side/tests/prospective_parachains.rs new file mode 100644 index 0000000000000000000000000000000000000000..02e8d0a7a81da8833f14f2f2464df78fc8ff559f --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/collator_side/tests/prospective_parachains.rs @@ -0,0 +1,575 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests for the collator side with enabled prospective parachains. + +use super::*; + +use polkadot_node_subsystem::messages::{ChainApiMessage, ProspectiveParachainsMessage}; +use polkadot_primitives::{vstaging as vstaging_primitives, Header, OccupiedCore}; + +const ASYNC_BACKING_PARAMETERS: vstaging_primitives::AsyncBackingParams = + vstaging_primitives::AsyncBackingParams { max_candidate_depth: 4, allowed_ancestry_len: 3 }; + +fn get_parent_hash(hash: Hash) -> Hash { + Hash::from_low_u64_be(hash.to_low_u64_be() + 1) +} + +/// Handle a view update. +async fn update_view( + virtual_overseer: &mut VirtualOverseer, + test_state: &TestState, + new_view: Vec<(Hash, u32)>, // Hash and block number. + activated: u8, // How many new heads does this update contain? +) { + let new_view: HashMap = HashMap::from_iter(new_view); + + let our_view = + OurView::new(new_view.keys().map(|hash| (*hash, Arc::new(jaeger::Span::Disabled))), 0); + + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange(our_view)), + ) + .await; + + let mut next_overseer_message = None; + for _ in 0..activated { + let (leaf_hash, leaf_number) = assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + parent, + RuntimeApiRequest::StagingAsyncBackingParams(tx), + )) => { + tx.send(Ok(ASYNC_BACKING_PARAMETERS)).unwrap(); + (parent, new_view.get(&parent).copied().expect("Unknown parent requested")) + } + ); + + let min_number = leaf_number.saturating_sub(ASYNC_BACKING_PARAMETERS.allowed_ancestry_len); + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetMinimumRelayParents(parent, tx), + ) if parent == leaf_hash => { + tx.send(vec![(test_state.para_id, min_number)]).unwrap(); + } + ); + + let ancestry_len = leaf_number + 1 - min_number; + let ancestry_hashes = std::iter::successors(Some(leaf_hash), |h| Some(get_parent_hash(*h))) + .take(ancestry_len as usize); + let ancestry_numbers = (min_number..=leaf_number).rev(); + let mut ancestry_iter = ancestry_hashes.clone().zip(ancestry_numbers).peekable(); + + while let Some((hash, number)) = ancestry_iter.next() { + // May be `None` for the last element. + let parent_hash = + ancestry_iter.peek().map(|(h, _)| *h).unwrap_or_else(|| get_parent_hash(hash)); + + let msg = match next_overseer_message.take() { + Some(msg) => Some(msg), + None => + overseer_recv_with_timeout(virtual_overseer, Duration::from_millis(50)).await, + }; + + let msg = match msg { + Some(msg) => msg, + None => { + // We're done. + return + }, + }; + + if !matches!( + &msg, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(_hash, ..)) + if *_hash == hash + ) { + // Ancestry has already been cached for this leaf. + next_overseer_message.replace(msg); + break + } + + assert_matches!( + msg, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(.., tx)) => { + let header = Header { + parent_hash, + number, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + }; + + tx.send(Ok(Some(header))).unwrap(); + } + ); + } + } +} + +/// Check that the next received message is a `Declare` message. +pub(super) async fn expect_declare_msg_vstaging( + virtual_overseer: &mut VirtualOverseer, + test_state: &TestState, + peer: &PeerId, +) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendCollationMessage( + to, + Versioned::VStaging(protocol_vstaging::CollationProtocol::CollatorProtocol( + wire_message, + )), + )) => { + assert_eq!(to[0], *peer); + assert_matches!( + wire_message, + protocol_vstaging::CollatorProtocolMessage::Declare( + collator_id, + para_id, + signature, + ) => { + assert!(signature.verify( + &*protocol_vstaging::declare_signature_payload(&test_state.local_peer_id), + &collator_id), + ); + assert_eq!(collator_id, test_state.collator_pair.public()); + assert_eq!(para_id, test_state.para_id); + } + ); + } + ); +} + +/// Test that a collator distributes a collation from the allowed ancestry +/// to correct validators group. +#[test] +fn distribute_collation_from_implicit_view() { + let head_a = Hash::from_low_u64_be(126); + let head_a_num: u32 = 66; + + // Grandparent of head `a`. + let head_b = Hash::from_low_u64_be(128); + let head_b_num: u32 = 64; + + // Grandparent of head `b`. + let head_c = Hash::from_low_u64_be(130); + let head_c_num = 62; + + let group_rotation_info = GroupRotationInfo { + session_start_block: head_c_num - 2, + group_rotation_frequency: 3, + now: head_c_num, + }; + + let mut test_state = TestState::default(); + test_state.group_rotation_info = group_rotation_info; + + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |mut test_harness| async move { + let virtual_overseer = &mut test_harness.virtual_overseer; + + // Set collating para id. + overseer_send(virtual_overseer, CollatorProtocolMessage::CollateOn(test_state.para_id)) + .await; + // Activated leaf is `b`, but the collation will be based on `c`. + update_view(virtual_overseer, &test_state, vec![(head_b, head_b_num)], 1).await; + + let validator_peer_ids = test_state.current_group_validator_peer_ids(); + for (val, peer) in test_state + .current_group_validator_authority_ids() + .into_iter() + .zip(validator_peer_ids.clone()) + { + connect_peer(virtual_overseer, peer, CollationVersion::VStaging, Some(val.clone())) + .await; + } + + // Collator declared itself to each peer. + for peer_id in &validator_peer_ids { + expect_declare_msg_vstaging(virtual_overseer, &test_state, peer_id).await; + } + + let pov = PoV { block_data: BlockData(vec![1, 2, 3]) }; + let parent_head_data_hash = Hash::repeat_byte(0xAA); + let candidate = TestCandidateBuilder { + para_id: test_state.para_id, + relay_parent: head_c, + pov_hash: pov.hash(), + ..Default::default() + } + .build(); + let DistributeCollation { candidate, pov_block: _ } = + distribute_collation_with_receipt( + virtual_overseer, + &test_state, + head_c, + false, // Check the group manually. + candidate, + pov, + parent_head_data_hash, + ) + .await; + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ConnectToValidators { validator_ids, .. } + ) => { + let expected_validators = test_state.current_group_validator_authority_ids(); + + assert_eq!(expected_validators, validator_ids); + } + ); + + let candidate_hash = candidate.hash(); + + // Update peer views. + for peed_id in &validator_peer_ids { + send_peer_view_change(virtual_overseer, peed_id, vec![head_b]).await; + expect_advertise_collation_msg( + virtual_overseer, + peed_id, + head_c, + Some(vec![candidate_hash]), + ) + .await; + } + + // Head `c` goes out of view. + // Build a different candidate for this relay parent and attempt to distribute it. + update_view(virtual_overseer, &test_state, vec![(head_a, head_a_num)], 1).await; + + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; + let parent_head_data_hash = Hash::repeat_byte(0xBB); + let candidate = TestCandidateBuilder { + para_id: test_state.para_id, + relay_parent: head_c, + pov_hash: pov.hash(), + ..Default::default() + } + .build(); + overseer_send( + virtual_overseer, + CollatorProtocolMessage::DistributeCollation( + candidate.clone(), + parent_head_data_hash, + pov.clone(), + None, + ), + ) + .await; + + // Parent out of view, nothing happens. + assert!(overseer_recv_with_timeout(virtual_overseer, Duration::from_millis(100)) + .await + .is_none()); + + test_harness + }, + ) +} + +/// Tests that collator can distribute up to `MAX_CANDIDATE_DEPTH + 1` candidates +/// per relay parent. +#[test] +fn distribute_collation_up_to_limit() { + let test_state = TestState::default(); + + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |mut test_harness| async move { + let virtual_overseer = &mut test_harness.virtual_overseer; + + let head_a = Hash::from_low_u64_be(128); + let head_a_num: u32 = 64; + + // Grandparent of head `a`. + let head_b = Hash::from_low_u64_be(130); + + // Set collating para id. + overseer_send(virtual_overseer, CollatorProtocolMessage::CollateOn(test_state.para_id)) + .await; + // Activated leaf is `a`, but the collation will be based on `b`. + update_view(virtual_overseer, &test_state, vec![(head_a, head_a_num)], 1).await; + + for i in 0..(ASYNC_BACKING_PARAMETERS.max_candidate_depth + 1) { + let pov = PoV { block_data: BlockData(vec![i as u8]) }; + let parent_head_data_hash = Hash::repeat_byte(0xAA); + let candidate = TestCandidateBuilder { + para_id: test_state.para_id, + relay_parent: head_b, + pov_hash: pov.hash(), + ..Default::default() + } + .build(); + distribute_collation_with_receipt( + virtual_overseer, + &test_state, + head_b, + true, + candidate, + pov, + parent_head_data_hash, + ) + .await; + } + + let pov = PoV { block_data: BlockData(vec![10, 12, 6]) }; + let parent_head_data_hash = Hash::repeat_byte(0xBB); + let candidate = TestCandidateBuilder { + para_id: test_state.para_id, + relay_parent: head_b, + pov_hash: pov.hash(), + ..Default::default() + } + .build(); + overseer_send( + virtual_overseer, + CollatorProtocolMessage::DistributeCollation( + candidate.clone(), + parent_head_data_hash, + pov.clone(), + None, + ), + ) + .await; + + // Limit has been reached. + assert!(overseer_recv_with_timeout(virtual_overseer, Duration::from_millis(100)) + .await + .is_none()); + + test_harness + }, + ) +} + +/// Tests that collator correctly handles peer V2 requests. +#[test] +fn advertise_and_send_collation_by_hash() { + let test_state = TestState::default(); + + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |test_harness| async move { + let mut virtual_overseer = test_harness.virtual_overseer; + let req_v1_cfg = test_harness.req_v1_cfg; + let mut req_vstaging_cfg = test_harness.req_vstaging_cfg; + + let head_a = Hash::from_low_u64_be(128); + let head_a_num: u32 = 64; + + // Parent of head `a`. + let head_b = Hash::from_low_u64_be(129); + let head_b_num: u32 = 63; + + // Set collating para id. + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::CollateOn(test_state.para_id), + ) + .await; + update_view(&mut virtual_overseer, &test_state, vec![(head_b, head_b_num)], 1).await; + update_view(&mut virtual_overseer, &test_state, vec![(head_a, head_a_num)], 1).await; + + let candidates: Vec<_> = (0..2) + .map(|i| { + let pov = PoV { block_data: BlockData(vec![i as u8]) }; + let candidate = TestCandidateBuilder { + para_id: test_state.para_id, + relay_parent: head_b, + pov_hash: pov.hash(), + ..Default::default() + } + .build(); + (candidate, pov) + }) + .collect(); + for (candidate, pov) in &candidates { + distribute_collation_with_receipt( + &mut virtual_overseer, + &test_state, + head_b, + true, + candidate.clone(), + pov.clone(), + Hash::zero(), + ) + .await; + } + + let peer = test_state.validator_peer_id[0]; + let validator_id = test_state.current_group_validator_authority_ids()[0].clone(); + connect_peer( + &mut virtual_overseer, + peer, + CollationVersion::VStaging, + Some(validator_id.clone()), + ) + .await; + expect_declare_msg_vstaging(&mut virtual_overseer, &test_state, &peer).await; + + // Head `b` is not a leaf, but both advertisements are still relevant. + send_peer_view_change(&mut virtual_overseer, &peer, vec![head_b]).await; + let hashes: Vec<_> = candidates.iter().map(|(candidate, _)| candidate.hash()).collect(); + expect_advertise_collation_msg(&mut virtual_overseer, &peer, head_b, Some(hashes)) + .await; + + for (candidate, pov_block) in candidates { + let (pending_response, rx) = oneshot::channel(); + req_vstaging_cfg + .inbound_queue + .as_mut() + .unwrap() + .send(RawIncomingRequest { + peer, + payload: request_vstaging::CollationFetchingRequest { + relay_parent: head_b, + para_id: test_state.para_id, + candidate_hash: candidate.hash(), + } + .encode(), + pending_response, + }) + .await + .unwrap(); + + assert_matches!( + rx.await, + Ok(full_response) => { + // Response is the same for vstaging. + let request_v1::CollationFetchingResponse::Collation(receipt, pov): request_v1::CollationFetchingResponse + = request_v1::CollationFetchingResponse::decode( + &mut full_response.result + .expect("We should have a proper answer").as_ref() + ) + .expect("Decoding should work"); + assert_eq!(receipt, candidate); + assert_eq!(pov, pov_block); + } + ); + } + + TestHarness { virtual_overseer, req_v1_cfg, req_vstaging_cfg } + }, + ) +} + +/// Tests that collator distributes collation built on top of occupied core. +#[test] +fn advertise_core_occupied() { + let mut test_state = TestState::default(); + let candidate = + TestCandidateBuilder { para_id: test_state.para_id, ..Default::default() }.build(); + test_state.availability_cores[0] = CoreState::Occupied(OccupiedCore { + next_up_on_available: None, + occupied_since: 0, + time_out_at: 0, + next_up_on_time_out: None, + availability: BitVec::default(), + group_responsible: GroupIndex(0), + candidate_hash: candidate.hash(), + candidate_descriptor: candidate.descriptor, + }); + + let local_peer_id = test_state.local_peer_id; + let collator_pair = test_state.collator_pair.clone(); + + test_harness( + local_peer_id, + collator_pair, + ReputationAggregator::new(|_| true), + |mut test_harness| async move { + let virtual_overseer = &mut test_harness.virtual_overseer; + + let head_a = Hash::from_low_u64_be(128); + let head_a_num: u32 = 64; + + // Grandparent of head `a`. + let head_b = Hash::from_low_u64_be(130); + + // Set collating para id. + overseer_send(virtual_overseer, CollatorProtocolMessage::CollateOn(test_state.para_id)) + .await; + // Activated leaf is `a`, but the collation will be based on `b`. + update_view(virtual_overseer, &test_state, vec![(head_a, head_a_num)], 1).await; + + let pov = PoV { block_data: BlockData(vec![1, 2, 3]) }; + let candidate = TestCandidateBuilder { + para_id: test_state.para_id, + relay_parent: head_b, + pov_hash: pov.hash(), + ..Default::default() + } + .build(); + let candidate_hash = candidate.hash(); + distribute_collation_with_receipt( + virtual_overseer, + &test_state, + head_b, + true, + candidate, + pov, + Hash::zero(), + ) + .await; + + let validators = test_state.current_group_validator_authority_ids(); + let peer_ids = test_state.current_group_validator_peer_ids(); + + connect_peer( + virtual_overseer, + peer_ids[0], + CollationVersion::VStaging, + Some(validators[0].clone()), + ) + .await; + expect_declare_msg_vstaging(virtual_overseer, &test_state, &peer_ids[0]).await; + // Peer is aware of the leaf. + send_peer_view_change(virtual_overseer, &peer_ids[0], vec![head_a]).await; + + // Collation is advertised. + expect_advertise_collation_msg( + virtual_overseer, + &peer_ids[0], + head_b, + Some(vec![candidate_hash]), + ) + .await; + + test_harness + }, + ) +} diff --git a/polkadot/node/network/collator-protocol/src/collator_side/validators_buffer.rs b/polkadot/node/network/collator-protocol/src/collator_side/validators_buffer.rs new file mode 100644 index 0000000000000000000000000000000000000000..cfa7627038481264e942ae5fb60e13e437713e23 --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/collator_side/validators_buffer.rs @@ -0,0 +1,349 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Validator groups buffer for connection managements. +//! +//! Solves 2 problems: +//! 1. A collator may want to stay connected to multiple groups on rotation boundaries. +//! 2. It's important to disconnect from validator when there're no collations to be fetched. +//! +//! We keep a simple FIFO buffer of N validator groups and a bitvec for each advertisement, +//! 1 indicating we want to be connected to i-th validator in a buffer, 0 otherwise. +//! +//! The bit is set to 1 for the whole **group** whenever it's inserted into the buffer. Given a +//! relay parent, one can reset a bit back to 0 for particular **validator**. For example, if a +//! collation was fetched or some timeout has been hit. +//! +//! The bitwise OR over known advertisements gives us validators indices for connection request. + +use std::{ + collections::{HashMap, VecDeque}, + future::Future, + num::NonZeroUsize, + ops::Range, + pin::Pin, + task::{Context, Poll}, + time::Duration, +}; + +use bitvec::{bitvec, vec::BitVec}; +use futures::FutureExt; + +use polkadot_node_network_protocol::PeerId; +use polkadot_primitives::{AuthorityDiscoveryId, CandidateHash, GroupIndex, SessionIndex}; + +/// The ring buffer stores at most this many unique validator groups. +/// +/// This value should be chosen in way that all groups assigned to our para +/// in the view can fit into the buffer. +pub const VALIDATORS_BUFFER_CAPACITY: NonZeroUsize = match NonZeroUsize::new(3) { + Some(cap) => cap, + None => panic!("buffer capacity must be non-zero"), +}; + +/// Unique identifier of a validators group. +#[derive(Debug)] +struct ValidatorsGroupInfo { + /// Number of validators in the group. + len: usize, + session_index: SessionIndex, + group_index: GroupIndex, +} + +/// Ring buffer of validator groups. +/// +/// Tracks which peers we want to be connected to with respect to advertised collations. +#[derive(Debug)] +pub struct ValidatorGroupsBuffer { + /// Validator groups identifiers we **had** advertisements for. + group_infos: VecDeque, + /// Continuous buffer of validators discovery keys. + validators: VecDeque, + /// Mapping from candidate hashes to bit-vectors with bits for all `validators`. + /// Invariants kept: All bit-vectors are guaranteed to have the same size. + should_be_connected: HashMap, + /// Buffer capacity, limits the number of **groups** tracked. + cap: NonZeroUsize, +} + +impl ValidatorGroupsBuffer { + /// Creates a new buffer with a non-zero capacity. + pub fn with_capacity(cap: NonZeroUsize) -> Self { + Self { + group_infos: VecDeque::new(), + validators: VecDeque::new(), + should_be_connected: HashMap::new(), + cap, + } + } + + /// Returns discovery ids of validators we have at least one advertised-but-not-fetched + /// collation for. + pub fn validators_to_connect(&self) -> Vec { + let validators_num = self.validators.len(); + let bits = self + .should_be_connected + .values() + .fold(bitvec![0; validators_num], |acc, next| acc | next); + + self.validators + .iter() + .enumerate() + .filter_map(|(idx, authority_id)| bits[idx].then_some(authority_id.clone())) + .collect() + } + + /// Note a new advertisement, marking that we want to be connected to validators + /// from this group. + /// + /// If max capacity is reached and the group is new, drops validators from the back + /// of the buffer. + pub fn note_collation_advertised( + &mut self, + candidate_hash: CandidateHash, + session_index: SessionIndex, + group_index: GroupIndex, + validators: &[AuthorityDiscoveryId], + ) { + if validators.is_empty() { + return + } + + match self.group_infos.iter().enumerate().find(|(_, group)| { + group.session_index == session_index && group.group_index == group_index + }) { + Some((idx, group)) => { + let group_start_idx = self.group_lengths_iter().take(idx).sum(); + self.set_bits(candidate_hash, group_start_idx..(group_start_idx + group.len)); + }, + None => self.push(candidate_hash, session_index, group_index, validators), + } + } + + /// Note that a validator is no longer interested in a given relay parent. + pub fn reset_validator_interest( + &mut self, + candidate_hash: CandidateHash, + authority_id: &AuthorityDiscoveryId, + ) { + let bits = match self.should_be_connected.get_mut(&candidate_hash) { + Some(bits) => bits, + None => return, + }; + + for (idx, auth_id) in self.validators.iter().enumerate() { + if auth_id == authority_id { + bits.set(idx, false); + } + } + } + + /// Remove advertised candidate from the buffer. + /// + /// The buffer will no longer track which validators are interested in a corresponding + /// advertisement. + pub fn remove_candidate(&mut self, candidate_hash: &CandidateHash) { + self.should_be_connected.remove(candidate_hash); + } + + /// Pushes a new group to the buffer along with advertisement, setting all validators + /// bits to 1. + /// + /// If the buffer is full, drops group from the tail. + fn push( + &mut self, + candidate_hash: CandidateHash, + session_index: SessionIndex, + group_index: GroupIndex, + validators: &[AuthorityDiscoveryId], + ) { + let new_group_info = + ValidatorsGroupInfo { len: validators.len(), session_index, group_index }; + + let buf = &mut self.group_infos; + let cap = self.cap.get(); + + if buf.len() >= cap { + let pruned_group = buf.pop_front().expect("buf is not empty; qed"); + self.validators.drain(..pruned_group.len); + + self.should_be_connected.values_mut().for_each(|bits| { + bits.as_mut_bitslice().shift_left(pruned_group.len); + }); + } + + self.validators.extend(validators.iter().cloned()); + buf.push_back(new_group_info); + let buf_len = buf.len(); + let group_start_idx = self.group_lengths_iter().take(buf_len - 1).sum(); + + let new_len = self.validators.len(); + self.should_be_connected + .values_mut() + .for_each(|bits| bits.resize(new_len, false)); + self.set_bits(candidate_hash, group_start_idx..(group_start_idx + validators.len())); + } + + /// Sets advertisement bits to 1 in a given range (usually corresponding to some group). + /// If the relay parent is unknown, inserts 0-initialized bitvec first. + /// + /// The range must be ensured to be within bounds. + fn set_bits(&mut self, candidate_hash: CandidateHash, range: Range) { + let bits = self + .should_be_connected + .entry(candidate_hash) + .or_insert_with(|| bitvec![0; self.validators.len()]); + + bits[range].fill(true); + } + + /// Returns iterator over numbers of validators in groups. + /// + /// Useful for getting an index of the first validator in i-th group. + fn group_lengths_iter(&self) -> impl Iterator + '_ { + self.group_infos.iter().map(|group| group.len) + } +} + +/// A timeout for resetting validators' interests in collations. +pub const RESET_INTEREST_TIMEOUT: Duration = Duration::from_secs(6); + +/// A future that returns a candidate hash along with validator discovery +/// keys once a timeout hit. +/// +/// If a validator doesn't manage to fetch a collation within this timeout +/// we should reset its interest in this advertisement in a buffer. For example, +/// when the PoV was already requested from another peer. +pub struct ResetInterestTimeout { + fut: futures_timer::Delay, + candidate_hash: CandidateHash, + peer_id: PeerId, +} + +impl ResetInterestTimeout { + /// Returns new `ResetInterestTimeout` that resolves after given timeout. + pub fn new(candidate_hash: CandidateHash, peer_id: PeerId, delay: Duration) -> Self { + Self { fut: futures_timer::Delay::new(delay), candidate_hash, peer_id } + } +} + +impl Future for ResetInterestTimeout { + type Output = (CandidateHash, PeerId); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.fut.poll_unpin(cx).map(|_| (self.candidate_hash, self.peer_id)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use polkadot_primitives::Hash; + use sp_keyring::Sr25519Keyring; + + #[test] + fn one_capacity_buffer() { + let cap = NonZeroUsize::new(1).unwrap(); + let mut buf = ValidatorGroupsBuffer::with_capacity(cap); + + let hash_a = CandidateHash(Hash::repeat_byte(0x1)); + let hash_b = CandidateHash(Hash::repeat_byte(0x2)); + + let validators: Vec<_> = [ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ] + .into_iter() + .map(|key| AuthorityDiscoveryId::from(key.public())) + .collect(); + + assert!(buf.validators_to_connect().is_empty()); + + buf.note_collation_advertised(hash_a, 0, GroupIndex(0), &validators[..2]); + assert_eq!(buf.validators_to_connect(), validators[..2].to_vec()); + + buf.reset_validator_interest(hash_a, &validators[1]); + assert_eq!(buf.validators_to_connect(), vec![validators[0].clone()]); + + buf.note_collation_advertised(hash_b, 0, GroupIndex(1), &validators[2..]); + assert_eq!(buf.validators_to_connect(), validators[2..].to_vec()); + + for validator in &validators[2..] { + buf.reset_validator_interest(hash_b, validator); + } + assert!(buf.validators_to_connect().is_empty()); + } + + #[test] + fn buffer_works() { + let cap = NonZeroUsize::new(3).unwrap(); + let mut buf = ValidatorGroupsBuffer::with_capacity(cap); + + let hashes: Vec<_> = (0..5).map(|i| CandidateHash(Hash::repeat_byte(i))).collect(); + + let validators: Vec<_> = [ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ] + .into_iter() + .map(|key| AuthorityDiscoveryId::from(key.public())) + .collect(); + + buf.note_collation_advertised(hashes[0], 0, GroupIndex(0), &validators[..2]); + buf.note_collation_advertised(hashes[1], 0, GroupIndex(0), &validators[..2]); + buf.note_collation_advertised(hashes[2], 0, GroupIndex(1), &validators[2..4]); + buf.note_collation_advertised(hashes[2], 0, GroupIndex(1), &validators[2..4]); + + assert_eq!(buf.validators_to_connect(), validators[..4].to_vec()); + + for validator in &validators[2..4] { + buf.reset_validator_interest(hashes[2], validator); + } + + buf.reset_validator_interest(hashes[1], &validators[0]); + assert_eq!(buf.validators_to_connect(), validators[..2].to_vec()); + + buf.reset_validator_interest(hashes[0], &validators[0]); + assert_eq!(buf.validators_to_connect(), vec![validators[1].clone()]); + + buf.note_collation_advertised(hashes[3], 0, GroupIndex(1), &validators[2..4]); + buf.note_collation_advertised( + hashes[4], + 0, + GroupIndex(2), + std::slice::from_ref(&validators[4]), + ); + + buf.reset_validator_interest(hashes[3], &validators[2]); + buf.note_collation_advertised( + hashes[4], + 0, + GroupIndex(3), + std::slice::from_ref(&validators[0]), + ); + + assert_eq!( + buf.validators_to_connect(), + vec![validators[3].clone(), validators[4].clone(), validators[0].clone()] + ); + } +} diff --git a/polkadot/node/network/collator-protocol/src/error.rs b/polkadot/node/network/collator-protocol/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..9348198e70853de3ab954dd51d9c17836f8d8dd6 --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/error.rs @@ -0,0 +1,133 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +// + +//! Error handling related code and Error/Result definitions. + +use futures::channel::oneshot; + +use polkadot_node_network_protocol::request_response::incoming; +use polkadot_node_primitives::UncheckedSignedFullStatement; +use polkadot_node_subsystem::{errors::SubsystemError, RuntimeApiError}; +use polkadot_node_subsystem_util::{backing_implicit_view, runtime}; + +use crate::LOG_TARGET; + +/// General result. +pub type Result = std::result::Result; + +use fatality::Nested; + +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + #[fatal] + #[error("Receiving message from overseer failed")] + SubsystemReceive(#[from] SubsystemError), + + #[fatal(forward)] + #[error("Retrieving next incoming request failed")] + IncomingRequest(#[from] incoming::Error), + + #[fatal(forward)] + #[error("Error while accessing runtime information")] + Runtime(#[from] runtime::Error), + + #[error("Error while accessing Runtime API")] + RuntimeApi(#[from] RuntimeApiError), + + #[error(transparent)] + ImplicitViewFetchError(backing_implicit_view::FetchError), + + #[error("Response receiver for active validators request cancelled")] + CancelledActiveValidators(oneshot::Canceled), + + #[error("Response receiver for validator groups request cancelled")] + CancelledValidatorGroups(oneshot::Canceled), + + #[error("Response receiver for availability cores request cancelled")] + CancelledAvailabilityCores(oneshot::Canceled), + + #[error("CollationSeconded contained statement with invalid signature")] + InvalidStatementSignature(UncheckedSignedFullStatement), +} + +/// An error happened on the validator side of the protocol when attempting +/// to start seconding a candidate. +#[derive(Debug, thiserror::Error)] +pub enum SecondingError { + #[error("Error while accessing Runtime API")] + RuntimeApi(#[from] RuntimeApiError), + + #[error("Response receiver for persisted validation data request cancelled")] + CancelledRuntimePersistedValidationData(oneshot::Canceled), + + #[error("Response receiver for prospective validation data request cancelled")] + CancelledProspectiveValidationData(oneshot::Canceled), + + #[error("Persisted validation data is not available")] + PersistedValidationDataNotFound, + + #[error("Persisted validation data hash doesn't match one in the candidate receipt.")] + PersistedValidationDataMismatch, + + #[error("Candidate hash doesn't match the advertisement")] + CandidateHashMismatch, + + #[error("Received duplicate collation from the peer")] + Duplicate, +} + +impl SecondingError { + /// Returns true if an error indicates that a peer is malicious. + pub fn is_malicious(&self) -> bool { + use SecondingError::*; + matches!(self, PersistedValidationDataMismatch | CandidateHashMismatch | Duplicate) + } +} + +/// A validator failed to request a collation due to an error. +#[derive(Debug, thiserror::Error)] +pub enum FetchError { + #[error("Collation was not previously advertised")] + NotAdvertised, + + #[error("Peer is unknown")] + UnknownPeer, + + #[error("Collation was already requested")] + AlreadyRequested, + + #[error("Relay parent went out of view")] + RelayParentOutOfView, + + #[error("Peer's protocol doesn't match the advertisement")] + ProtocolMismatch, +} + +/// Utility for eating top level errors and log them. +/// +/// We basically always want to try and continue on error. This utility function is meant to +/// consume top-level errors by simply logging them. +pub fn log_error(result: Result<()>, ctx: &'static str) -> std::result::Result<(), FatalError> { + match result.into_nested()? { + Ok(()) => Ok(()), + Err(jfyi) => { + gum::warn!(target: LOG_TARGET, error = ?jfyi, ctx); + Ok(()) + }, + } +} diff --git a/polkadot/node/network/collator-protocol/src/lib.rs b/polkadot/node/network/collator-protocol/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..62c033954f75a00fb2c1b50a3afb0b858b977c5f --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/lib.rs @@ -0,0 +1,178 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Collator Protocol allows collators and validators talk to each other. +//! This subsystem implements both sides of the collator protocol. + +#![deny(missing_docs)] +#![deny(unused_crate_dependencies)] +#![recursion_limit = "256"] + +use std::time::{Duration, Instant}; + +use futures::{ + stream::{FusedStream, StreamExt}, + FutureExt, TryFutureExt, +}; + +use polkadot_node_subsystem_util::reputation::ReputationAggregator; +use sp_keystore::KeystorePtr; + +use polkadot_node_network_protocol::{ + request_response::{v1 as request_v1, vstaging as protocol_vstaging, IncomingRequestReceiver}, + PeerId, UnifiedReputationChange as Rep, +}; +use polkadot_primitives::CollatorPair; + +use polkadot_node_subsystem::{errors::SubsystemError, overseer, DummySubsystem, SpawnedSubsystem}; + +mod error; + +mod collator_side; +mod validator_side; + +const LOG_TARGET: &'static str = "parachain::collator-protocol"; + +/// A collator eviction policy - how fast to evict collators which are inactive. +#[derive(Debug, Clone, Copy)] +pub struct CollatorEvictionPolicy { + /// How fast to evict collators who are inactive. + pub inactive_collator: Duration, + /// How fast to evict peers which don't declare their para. + pub undeclared: Duration, +} + +impl Default for CollatorEvictionPolicy { + fn default() -> Self { + CollatorEvictionPolicy { + inactive_collator: Duration::from_secs(24), + undeclared: Duration::from_secs(1), + } + } +} + +/// What side of the collator protocol is being engaged +pub enum ProtocolSide { + /// Validators operate on the relay chain. + Validator { + /// The keystore holding validator keys. + keystore: KeystorePtr, + /// An eviction policy for inactive peers or validators. + eviction_policy: CollatorEvictionPolicy, + /// Prometheus metrics for validators. + metrics: validator_side::Metrics, + }, + /// Collators operate on a parachain. + Collator { + /// Local peer id. + peer_id: PeerId, + /// Parachain collator pair. + collator_pair: CollatorPair, + /// Receiver for v1 collation fetching requests. + request_receiver_v1: IncomingRequestReceiver, + /// Receiver for vstaging collation fetching requests. + request_receiver_vstaging: + IncomingRequestReceiver, + /// Metrics. + metrics: collator_side::Metrics, + }, + /// No protocol side, just disable it. + None, +} + +/// The collator protocol subsystem. +pub struct CollatorProtocolSubsystem { + protocol_side: ProtocolSide, +} + +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +impl CollatorProtocolSubsystem { + /// Start the collator protocol. + /// If `id` is `Some` this is a collator side of the protocol. + /// If `id` is `None` this is a validator side of the protocol. + /// Caller must provide a registry for prometheus metrics. + pub fn new(protocol_side: ProtocolSide) -> Self { + Self { protocol_side } + } +} + +#[overseer::subsystem(CollatorProtocol, error=SubsystemError, prefix=self::overseer)] +impl CollatorProtocolSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = match self.protocol_side { + ProtocolSide::Validator { keystore, eviction_policy, metrics } => + validator_side::run(ctx, keystore, eviction_policy, metrics) + .map_err(|e| SubsystemError::with_origin("collator-protocol", e)) + .boxed(), + ProtocolSide::Collator { + peer_id, + collator_pair, + request_receiver_v1, + request_receiver_vstaging, + metrics, + } => collator_side::run( + ctx, + peer_id, + collator_pair, + request_receiver_v1, + request_receiver_vstaging, + metrics, + ) + .map_err(|e| SubsystemError::with_origin("collator-protocol", e)) + .boxed(), + ProtocolSide::None => return DummySubsystem.start(ctx), + }; + + SpawnedSubsystem { name: "collator-protocol-subsystem", future } + } +} + +/// Modify the reputation of a peer based on its behavior. +async fn modify_reputation( + reputation: &mut ReputationAggregator, + sender: &mut impl overseer::CollatorProtocolSenderTrait, + peer: PeerId, + rep: Rep, +) { + gum::trace!( + target: LOG_TARGET, + rep = ?rep, + peer_id = %peer, + "reputation change for peer", + ); + + reputation.modify(sender, peer, rep).await; +} + +/// Wait until tick and return the timestamp for the following one. +async fn wait_until_next_tick(last_poll: Instant, period: Duration) -> Instant { + let now = Instant::now(); + let next_poll = last_poll + period; + + if next_poll > now { + futures_timer::Delay::new(next_poll - now).await + } + + Instant::now() +} + +/// Returns an infinite stream that yields with an interval of `period`. +fn tick_stream(period: Duration) -> impl FusedStream { + futures::stream::unfold(Instant::now(), move |next_check| async move { + Some(((), wait_until_next_tick(next_check, period).await)) + }) + .fuse() +} diff --git a/polkadot/node/network/collator-protocol/src/validator_side/collation.rs b/polkadot/node/network/collator-protocol/src/validator_side/collation.rs new file mode 100644 index 0000000000000000000000000000000000000000..ba59cce56b60aa454b5fc00abf99d39efa0cb971 --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/validator_side/collation.rs @@ -0,0 +1,366 @@ +// Copyright 2017-2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Primitives for tracking collations-related data. +//! +//! Usually a path of collations is as follows: +//! 1. First, collation must be advertised by collator. +//! 2. If the advertisement was accepted, it's queued for fetch (per relay parent). +//! 3. Once it's requested, the collation is said to be Pending. +//! 4. Pending collation becomes Fetched once received, we send it to backing for validation. +//! 5. If it turns to be invalid or async backing allows seconding another candidate, carry on +//! with the next advertisement, otherwise we're done with this relay parent. +//! +//! ┌──────────────────────────────────────────┐ +//! └─▶Advertised ─▶ Pending ─▶ Fetched ─▶ Validated + +use std::{collections::VecDeque, future::Future, pin::Pin, task::Poll}; + +use futures::{future::BoxFuture, FutureExt}; +use polkadot_node_network_protocol::{ + request_response::{outgoing::RequestError, v1 as request_v1, OutgoingResult}, + PeerId, +}; +use polkadot_node_primitives::PoV; +use polkadot_node_subsystem::jaeger; +use polkadot_node_subsystem_util::{ + metrics::prometheus::prometheus::HistogramTimer, runtime::ProspectiveParachainsMode, +}; +use polkadot_primitives::{ + CandidateHash, CandidateReceipt, CollatorId, Hash, Id as ParaId, PersistedValidationData, +}; +use tokio_util::sync::CancellationToken; + +use crate::{error::SecondingError, LOG_TARGET}; + +/// Candidate supplied with a para head it's built on top of. +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] +pub struct ProspectiveCandidate { + /// Candidate hash. + pub candidate_hash: CandidateHash, + /// Parent head-data hash as supplied in advertisement. + pub parent_head_data_hash: Hash, +} + +impl ProspectiveCandidate { + pub fn candidate_hash(&self) -> CandidateHash { + self.candidate_hash + } +} + +/// Identifier of a fetched collation. +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +pub struct FetchedCollation { + /// Candidate's relay parent. + pub relay_parent: Hash, + /// Parachain id. + pub para_id: ParaId, + /// Candidate hash. + pub candidate_hash: CandidateHash, + /// Id of the collator the collation was fetched from. + pub collator_id: CollatorId, +} + +impl From<&CandidateReceipt> for FetchedCollation { + fn from(receipt: &CandidateReceipt) -> Self { + let descriptor = receipt.descriptor(); + Self { + relay_parent: descriptor.relay_parent, + para_id: descriptor.para_id, + candidate_hash: receipt.hash(), + collator_id: descriptor.collator.clone(), + } + } +} + +/// Identifier of a collation being requested. +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] +pub struct PendingCollation { + /// Candidate's relay parent. + pub relay_parent: Hash, + /// Parachain id. + pub para_id: ParaId, + /// Peer that advertised this collation. + pub peer_id: PeerId, + /// Optional candidate hash and parent head-data hash if were + /// supplied in advertisement. + pub prospective_candidate: Option, + /// Hash of the candidate's commitments. + pub commitments_hash: Option, +} + +impl PendingCollation { + pub fn new( + relay_parent: Hash, + para_id: ParaId, + peer_id: &PeerId, + prospective_candidate: Option, + ) -> Self { + Self { + relay_parent, + para_id, + peer_id: *peer_id, + prospective_candidate, + commitments_hash: None, + } + } +} + +/// vstaging advertisement that was rejected by the backing +/// subsystem. Validator may fetch it later if its fragment +/// membership gets recognized before relay parent goes out of view. +#[derive(Debug, Clone)] +pub struct BlockedAdvertisement { + /// Peer that advertised the collation. + pub peer_id: PeerId, + /// Collator id. + pub collator_id: CollatorId, + /// The relay-parent of the candidate. + pub candidate_relay_parent: Hash, + /// Hash of the candidate. + pub candidate_hash: CandidateHash, +} + +/// Performs a sanity check between advertised and fetched collations. +/// +/// Since the persisted validation data is constructed using the advertised +/// parent head data hash, the latter doesn't require an additional check. +pub fn fetched_collation_sanity_check( + advertised: &PendingCollation, + fetched: &CandidateReceipt, + persisted_validation_data: &PersistedValidationData, +) -> Result<(), SecondingError> { + if persisted_validation_data.hash() != fetched.descriptor().persisted_validation_data_hash { + Err(SecondingError::PersistedValidationDataMismatch) + } else if advertised + .prospective_candidate + .map_or(false, |pc| pc.candidate_hash() != fetched.hash()) + { + Err(SecondingError::CandidateHashMismatch) + } else { + Ok(()) + } +} + +/// Identifier for a requested collation and the respective collator that advertised it. +#[derive(Debug, Clone)] +pub struct CollationEvent { + /// Collator id. + pub collator_id: CollatorId, + /// The requested collation data. + pub pending_collation: PendingCollation, +} + +/// Fetched collation data. +#[derive(Debug, Clone)] +pub struct PendingCollationFetch { + /// Collation identifier. + pub collation_event: CollationEvent, + /// Candidate receipt. + pub candidate_receipt: CandidateReceipt, + /// Proof of validity. + pub pov: PoV, +} + +/// The status of the collations in [`CollationsPerRelayParent`]. +#[derive(Debug, Clone, Copy)] +pub enum CollationStatus { + /// We are waiting for a collation to be advertised to us. + Waiting, + /// We are currently fetching a collation. + Fetching, + /// We are waiting that a collation is being validated. + WaitingOnValidation, + /// We have seconded a collation. + Seconded, +} + +impl Default for CollationStatus { + fn default() -> Self { + Self::Waiting + } +} + +impl CollationStatus { + /// Downgrades to `Waiting`, but only if `self != Seconded`. + fn back_to_waiting(&mut self, relay_parent_mode: ProspectiveParachainsMode) { + match self { + Self::Seconded => + if relay_parent_mode.is_enabled() { + // With async backing enabled it's allowed to + // second more candidates. + *self = Self::Waiting + }, + _ => *self = Self::Waiting, + } + } +} + +/// Information about collations per relay parent. +#[derive(Default)] +pub struct Collations { + /// What is the current status in regards to a collation for this relay parent? + pub status: CollationStatus, + /// Collator we're fetching from, optionally which candidate was requested. + /// + /// This is the currently last started fetch, which did not exceed `MAX_UNSHARED_DOWNLOAD_TIME` + /// yet. + pub fetching_from: Option<(CollatorId, Option)>, + /// Collation that were advertised to us, but we did not yet fetch. + pub waiting_queue: VecDeque<(PendingCollation, CollatorId)>, + /// How many collations have been seconded. + pub seconded_count: usize, +} + +impl Collations { + /// Note a seconded collation for a given para. + pub(super) fn note_seconded(&mut self) { + self.seconded_count += 1 + } + + /// Returns the next collation to fetch from the `waiting_queue`. + /// + /// This will reset the status back to `Waiting` using [`CollationStatus::back_to_waiting`]. + /// + /// Returns `Some(_)` if there is any collation to fetch, the `status` is not `Seconded` and + /// the passed in `finished_one` is the currently `waiting_collation`. + pub(super) fn get_next_collation_to_fetch( + &mut self, + finished_one: &(CollatorId, Option), + relay_parent_mode: ProspectiveParachainsMode, + ) -> Option<(PendingCollation, CollatorId)> { + // If finished one does not match waiting_collation, then we already dequeued another fetch + // to replace it. + if let Some((collator_id, maybe_candidate_hash)) = self.fetching_from.as_ref() { + // If a candidate hash was saved previously, `finished_one` must include this too. + if collator_id != &finished_one.0 && + maybe_candidate_hash.map_or(true, |hash| Some(&hash) != finished_one.1.as_ref()) + { + gum::trace!( + target: LOG_TARGET, + waiting_collation = ?self.fetching_from, + ?finished_one, + "Not proceeding to the next collation - has already been done." + ); + return None + } + } + self.status.back_to_waiting(relay_parent_mode); + + match self.status { + // We don't need to fetch any other collation when we already have seconded one. + CollationStatus::Seconded => None, + CollationStatus::Waiting => + if !self.is_seconded_limit_reached(relay_parent_mode) { + None + } else { + self.waiting_queue.pop_front() + }, + CollationStatus::WaitingOnValidation | CollationStatus::Fetching => + unreachable!("We have reset the status above!"), + } + } + + /// Checks the limit of seconded candidates for a given para. + pub(super) fn is_seconded_limit_reached( + &self, + relay_parent_mode: ProspectiveParachainsMode, + ) -> bool { + let seconded_limit = + if let ProspectiveParachainsMode::Enabled { max_candidate_depth, .. } = + relay_parent_mode + { + max_candidate_depth + 1 + } else { + 1 + }; + self.seconded_count < seconded_limit + } +} + +// Any error that can occur when awaiting a collation fetch response. +#[derive(Debug, thiserror::Error)] +pub(super) enum CollationFetchError { + #[error("Future was cancelled.")] + Cancelled, + #[error("{0}")] + Request(#[from] RequestError), +} + +/// Future that concludes when the collator has responded to our collation fetch request +/// or the request was cancelled by the validator. +pub(super) struct CollationFetchRequest { + /// Info about the requested collation. + pub pending_collation: PendingCollation, + /// Collator id. + pub collator_id: CollatorId, + /// Responses from collator. + pub from_collator: BoxFuture<'static, OutgoingResult>, + /// Handle used for checking if this request was cancelled. + pub cancellation_token: CancellationToken, + /// A jaeger span corresponding to the lifetime of the request. + pub span: Option, + /// A metric histogram for the lifetime of the request + pub _lifetime_timer: Option, +} + +impl Future for CollationFetchRequest { + type Output = ( + CollationEvent, + std::result::Result, + ); + + fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { + // First check if this fetch request was cancelled. + let cancelled = match std::pin::pin!(self.cancellation_token.cancelled()).poll(cx) { + Poll::Ready(()) => true, + Poll::Pending => false, + }; + + if cancelled { + self.span.as_mut().map(|s| s.add_string_tag("success", "false")); + return Poll::Ready(( + CollationEvent { + collator_id: self.collator_id.clone(), + pending_collation: self.pending_collation, + }, + Err(CollationFetchError::Cancelled), + )) + } + + let res = self.from_collator.poll_unpin(cx).map(|res| { + ( + CollationEvent { + collator_id: self.collator_id.clone(), + pending_collation: self.pending_collation, + }, + res.map_err(CollationFetchError::Request), + ) + }); + + match &res { + Poll::Ready((_, Ok(request_v1::CollationFetchingResponse::Collation(..)))) => { + self.span.as_mut().map(|s| s.add_string_tag("success", "true")); + }, + Poll::Ready((_, Err(_))) => { + self.span.as_mut().map(|s| s.add_string_tag("success", "false")); + }, + _ => {}, + }; + + res + } +} diff --git a/polkadot/node/network/collator-protocol/src/validator_side/metrics.rs b/polkadot/node/network/collator-protocol/src/validator_side/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..d898a5e7cefdfd3d7de5b0a338aca2b65f682ac3 --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/validator_side/metrics.rs @@ -0,0 +1,142 @@ +// Copyright 2017-2023 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone, Default)] +pub struct Metrics(Option); + +impl Metrics { + pub fn on_request(&self, succeeded: std::result::Result<(), ()>) { + if let Some(metrics) = &self.0 { + match succeeded { + Ok(()) => metrics.collation_requests.with_label_values(&["succeeded"]).inc(), + Err(()) => metrics.collation_requests.with_label_values(&["failed"]).inc(), + } + } + } + + /// Provide a timer for `process_msg` which observes on drop. + pub fn time_process_msg(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.process_msg.start_timer()) + } + + /// Provide a timer for `handle_collation_request_result` which observes on drop. + pub fn time_handle_collation_request_result( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.handle_collation_request_result.start_timer()) + } + + /// Note the current number of collator peers. + pub fn note_collator_peer_count(&self, collator_peers: usize) { + self.0 + .as_ref() + .map(|metrics| metrics.collator_peer_count.set(collator_peers as u64)); + } + + /// Provide a timer for `CollationFetchRequest` structure which observes on drop. + pub fn time_collation_request_duration( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.collation_request_duration.start_timer()) + } + + /// Provide a timer for `request_unblocked_collations` which observes on drop. + pub fn time_request_unblocked_collations( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.request_unblocked_collations.start_timer()) + } +} + +#[derive(Clone)] +struct MetricsInner { + collation_requests: prometheus::CounterVec, + process_msg: prometheus::Histogram, + handle_collation_request_result: prometheus::Histogram, + collator_peer_count: prometheus::Gauge, + collation_request_duration: prometheus::Histogram, + request_unblocked_collations: prometheus::Histogram, +} + +impl metrics::Metrics for Metrics { + fn try_register( + registry: &prometheus::Registry, + ) -> std::result::Result { + let metrics = MetricsInner { + collation_requests: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_collation_requests_total", + "Number of collations requested from Collators.", + ), + &["success"], + )?, + registry, + )?, + process_msg: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collator_protocol_validator_process_msg", + "Time spent within `collator_protocol_validator::process_msg`", + ) + )?, + registry, + )?, + handle_collation_request_result: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collator_protocol_validator_handle_collation_request_result", + "Time spent within `collator_protocol_validator::handle_collation_request_result`", + ) + )?, + registry, + )?, + collator_peer_count: prometheus::register( + prometheus::Gauge::new( + "polkadot_parachain_collator_peer_count", + "Amount of collator peers connected", + )?, + registry, + )?, + collation_request_duration: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collator_protocol_validator_collation_request_duration", + "Lifetime of the `CollationFetchRequest` structure", + ).buckets(vec![0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.75, 0.9, 1.0, 1.2, 1.5, 1.75]), + )?, + registry, + )?, + request_unblocked_collations: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collator_protocol_validator_request_unblocked_collations", + "Time spent within `collator_protocol_validator::request_unblocked_collations`", + ) + )?, + registry, + )?, + }; + + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/network/collator-protocol/src/validator_side/mod.rs b/polkadot/node/network/collator-protocol/src/validator_side/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e8cf769d2e5f336f17053cc6471366ae18d694a9 --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/validator_side/mod.rs @@ -0,0 +1,1993 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use futures::{ + channel::oneshot, future::BoxFuture, select, stream::FuturesUnordered, FutureExt, StreamExt, +}; +use futures_timer::Delay; +use std::{ + collections::{hash_map::Entry, HashMap, HashSet}, + convert::TryInto, + future::Future, + iter::FromIterator, + time::{Duration, Instant}, +}; +use tokio_util::sync::CancellationToken; + +use sp_keystore::KeystorePtr; + +use polkadot_node_network_protocol::{ + self as net_protocol, + peer_set::{CollationVersion, PeerSet}, + request_response::{ + outgoing::{Recipient, RequestError}, + v1 as request_v1, vstaging as request_vstaging, OutgoingRequest, Requests, + }, + v1 as protocol_v1, vstaging as protocol_vstaging, OurView, PeerId, + UnifiedReputationChange as Rep, Versioned, View, +}; +use polkadot_node_primitives::{SignedFullStatement, Statement}; +use polkadot_node_subsystem::{ + jaeger, + messages::{ + CanSecondRequest, CandidateBackingMessage, CollatorProtocolMessage, IfDisconnected, + NetworkBridgeEvent, NetworkBridgeTxMessage, ProspectiveParachainsMessage, + ProspectiveValidationDataRequest, + }, + overseer, CollatorProtocolSenderTrait, FromOrchestra, OverseerSignal, PerLeafSpan, +}; +use polkadot_node_subsystem_util::{ + backing_implicit_view::View as ImplicitView, + reputation::{ReputationAggregator, REPUTATION_CHANGE_INTERVAL}, + runtime::{prospective_parachains_mode, ProspectiveParachainsMode}, +}; +use polkadot_primitives::{ + CandidateHash, CollatorId, CoreState, Hash, Id as ParaId, OccupiedCoreAssumption, + PersistedValidationData, +}; + +use crate::error::{Error, FetchError, Result, SecondingError}; + +use super::{modify_reputation, tick_stream, LOG_TARGET}; + +mod collation; +mod metrics; + +use collation::{ + fetched_collation_sanity_check, BlockedAdvertisement, CollationEvent, CollationFetchError, + CollationFetchRequest, CollationStatus, Collations, FetchedCollation, PendingCollation, + PendingCollationFetch, ProspectiveCandidate, +}; + +#[cfg(test)] +mod tests; + +pub use metrics::Metrics; + +const COST_UNEXPECTED_MESSAGE: Rep = Rep::CostMinor("An unexpected message"); +/// Message could not be decoded properly. +const COST_CORRUPTED_MESSAGE: Rep = Rep::CostMinor("Message was corrupt"); +/// Network errors that originated at the remote host should have same cost as timeout. +const COST_NETWORK_ERROR: Rep = Rep::CostMinor("Some network error"); +const COST_INVALID_SIGNATURE: Rep = Rep::Malicious("Invalid network message signature"); +const COST_REPORT_BAD: Rep = Rep::Malicious("A collator was reported by another subsystem"); +const COST_WRONG_PARA: Rep = Rep::Malicious("A collator provided a collation for the wrong para"); +const COST_UNNEEDED_COLLATOR: Rep = Rep::CostMinor("An unneeded collator connected"); +const BENEFIT_NOTIFY_GOOD: Rep = + Rep::BenefitMinor("A collator was noted good by another subsystem"); + +/// Time after starting a collation download from a collator we will start another one from the +/// next collator even if the upload was not finished yet. +/// +/// This is to protect from a single slow collator preventing collations from happening. +/// +/// With a collation size of 5MB and bandwidth of 500Mbit/s (requirement for Kusama validators), +/// the transfer should be possible within 0.1 seconds. 400 milliseconds should therefore be +/// plenty, even with multiple heads and should be low enough for later collators to still be able +/// to finish on time. +/// +/// There is debug logging output, so we can adjust this value based on production results. +#[cfg(not(test))] +const MAX_UNSHARED_DOWNLOAD_TIME: Duration = Duration::from_millis(400); + +// How often to check all peers with activity. +#[cfg(not(test))] +const ACTIVITY_POLL: Duration = Duration::from_secs(1); + +#[cfg(test)] +const MAX_UNSHARED_DOWNLOAD_TIME: Duration = Duration::from_millis(100); + +#[cfg(test)] +const ACTIVITY_POLL: Duration = Duration::from_millis(10); + +#[derive(Debug)] +struct CollatingPeerState { + collator_id: CollatorId, + para_id: ParaId, + /// Collations advertised by peer per relay parent. + /// + /// V1 network protocol doesn't include candidate hash in + /// advertisements, we store an empty set in this case to occupy + /// a slot in map. + advertisements: HashMap>, + last_active: Instant, +} + +#[derive(Debug)] +enum PeerState { + // The peer has connected at the given instant. + Connected(Instant), + // Peer is collating. + Collating(CollatingPeerState), +} + +#[derive(Debug)] +enum InsertAdvertisementError { + /// Advertisement is already known. + Duplicate, + /// Collation relay parent is out of our view. + OutOfOurView, + /// No prior declare message received. + UndeclaredCollator, + /// A limit for announcements per peer is reached. + PeerLimitReached, + /// Mismatch of relay parent mode and advertisement arguments. + /// An internal error that should not happen. + ProtocolMismatch, +} + +#[derive(Debug)] +struct PeerData { + view: View, + state: PeerState, + version: CollationVersion, +} + +impl PeerData { + /// Update the view, clearing all advertisements that are no longer in the + /// current view. + fn update_view( + &mut self, + implicit_view: &ImplicitView, + active_leaves: &HashMap, + per_relay_parent: &HashMap, + new_view: View, + ) { + let old_view = std::mem::replace(&mut self.view, new_view); + if let PeerState::Collating(ref mut peer_state) = self.state { + for removed in old_view.difference(&self.view) { + // Remove relay parent advertisements if it went out + // of our (implicit) view. + let keep = per_relay_parent + .get(removed) + .map(|s| { + is_relay_parent_in_implicit_view( + removed, + s.prospective_parachains_mode, + implicit_view, + active_leaves, + peer_state.para_id, + ) + }) + .unwrap_or(false); + + if !keep { + peer_state.advertisements.remove(&removed); + } + } + } + } + + /// Prune old advertisements relative to our view. + fn prune_old_advertisements( + &mut self, + implicit_view: &ImplicitView, + active_leaves: &HashMap, + per_relay_parent: &HashMap, + ) { + if let PeerState::Collating(ref mut peer_state) = self.state { + peer_state.advertisements.retain(|hash, _| { + // Either + // - Relay parent is an active leaf + // - It belongs to allowed ancestry under some leaf + // Discard otherwise. + per_relay_parent.get(hash).map_or(false, |s| { + is_relay_parent_in_implicit_view( + hash, + s.prospective_parachains_mode, + implicit_view, + active_leaves, + peer_state.para_id, + ) + }) + }); + } + } + + /// Note an advertisement by the collator. Returns `true` if the advertisement was imported + /// successfully. Fails if the advertisement is duplicate, out of view, or the peer has not + /// declared itself a collator. + fn insert_advertisement( + &mut self, + on_relay_parent: Hash, + relay_parent_mode: ProspectiveParachainsMode, + candidate_hash: Option, + implicit_view: &ImplicitView, + active_leaves: &HashMap, + ) -> std::result::Result<(CollatorId, ParaId), InsertAdvertisementError> { + match self.state { + PeerState::Connected(_) => Err(InsertAdvertisementError::UndeclaredCollator), + PeerState::Collating(ref mut state) => { + if !is_relay_parent_in_implicit_view( + &on_relay_parent, + relay_parent_mode, + implicit_view, + active_leaves, + state.para_id, + ) { + return Err(InsertAdvertisementError::OutOfOurView) + } + + match (relay_parent_mode, candidate_hash) { + (ProspectiveParachainsMode::Disabled, candidate_hash) => { + if state.advertisements.contains_key(&on_relay_parent) { + return Err(InsertAdvertisementError::Duplicate) + } + state + .advertisements + .insert(on_relay_parent, HashSet::from_iter(candidate_hash)); + }, + ( + ProspectiveParachainsMode::Enabled { max_candidate_depth, .. }, + Some(candidate_hash), + ) => { + if state + .advertisements + .get(&on_relay_parent) + .map_or(false, |candidates| candidates.contains(&candidate_hash)) + { + return Err(InsertAdvertisementError::Duplicate) + } + let candidates = state.advertisements.entry(on_relay_parent).or_default(); + + if candidates.len() > max_candidate_depth { + return Err(InsertAdvertisementError::PeerLimitReached) + } + candidates.insert(candidate_hash); + }, + _ => return Err(InsertAdvertisementError::ProtocolMismatch), + } + + state.last_active = Instant::now(); + Ok((state.collator_id.clone(), state.para_id)) + }, + } + } + + /// Whether a peer is collating. + fn is_collating(&self) -> bool { + match self.state { + PeerState::Connected(_) => false, + PeerState::Collating(_) => true, + } + } + + /// Note that a peer is now collating with the given collator and para id. + /// + /// This will overwrite any previous call to `set_collating` and should only be called + /// if `is_collating` is false. + fn set_collating(&mut self, collator_id: CollatorId, para_id: ParaId) { + self.state = PeerState::Collating(CollatingPeerState { + collator_id, + para_id, + advertisements: HashMap::new(), + last_active: Instant::now(), + }); + } + + fn collator_id(&self) -> Option<&CollatorId> { + match self.state { + PeerState::Connected(_) => None, + PeerState::Collating(ref state) => Some(&state.collator_id), + } + } + + fn collating_para(&self) -> Option { + match self.state { + PeerState::Connected(_) => None, + PeerState::Collating(ref state) => Some(state.para_id), + } + } + + /// Whether the peer has advertised the given collation. + fn has_advertised( + &self, + relay_parent: &Hash, + maybe_candidate_hash: Option, + ) -> bool { + let collating_state = match self.state { + PeerState::Connected(_) => return false, + PeerState::Collating(ref state) => state, + }; + + if let Some(ref candidate_hash) = maybe_candidate_hash { + collating_state + .advertisements + .get(relay_parent) + .map_or(false, |candidates| candidates.contains(candidate_hash)) + } else { + collating_state.advertisements.contains_key(relay_parent) + } + } + + /// Whether the peer is now inactive according to the current instant and the eviction policy. + fn is_inactive(&self, policy: &crate::CollatorEvictionPolicy) -> bool { + match self.state { + PeerState::Connected(connected_at) => connected_at.elapsed() >= policy.undeclared, + PeerState::Collating(ref state) => + state.last_active.elapsed() >= policy.inactive_collator, + } + } +} + +#[derive(Debug)] +struct GroupAssignments { + /// Current assignment. + current: Option, +} + +struct PerRelayParent { + prospective_parachains_mode: ProspectiveParachainsMode, + assignment: GroupAssignments, + collations: Collations, +} + +impl PerRelayParent { + fn new(mode: ProspectiveParachainsMode) -> Self { + Self { + prospective_parachains_mode: mode, + assignment: GroupAssignments { current: None }, + collations: Collations::default(), + } + } +} + +/// All state relevant for the validator side of the protocol lives here. +#[derive(Default)] +struct State { + /// Leaves that do support asynchronous backing along with + /// implicit ancestry. Leaves from the implicit view are present in + /// `active_leaves`, the opposite doesn't hold true. + /// + /// Relay-chain blocks which don't support prospective parachains are + /// never included in the fragment trees of active leaves which do. In + /// particular, this means that if a given relay parent belongs to implicit + /// ancestry of some active leaf, then it does support prospective parachains. + implicit_view: ImplicitView, + + /// All active leaves observed by us, including both that do and do not + /// support prospective parachains. This mapping works as a replacement for + /// [`polkadot_node_network_protocol::View`] and can be dropped once the transition + /// to asynchronous backing is done. + active_leaves: HashMap, + + /// State tracked per relay parent. + per_relay_parent: HashMap, + + /// Track all active collators and their data. + peer_data: HashMap, + + /// Parachains we're currently assigned to. With async backing enabled + /// this includes assignments from the implicit view. + current_assignments: HashMap, + + /// The collations we have requested from collators. + collation_requests: FuturesUnordered, + + /// Cancellation handles for the collation fetch requests. + collation_requests_cancel_handles: HashMap, + + /// Metrics. + metrics: Metrics, + + /// Span per relay parent. + span_per_relay_parent: HashMap, + + /// Advertisements that were accepted as valid by collator protocol but rejected by backing. + /// + /// It's only legal to fetch collations that are either built on top of the root + /// of some fragment tree or have a parent node which represents backed candidate. + /// Otherwise, a validator will keep such advertisement in the memory and re-trigger + /// requests to backing on new backed candidates and activations. + blocked_advertisements: HashMap<(ParaId, Hash), Vec>, + + /// When a timer in this `FuturesUnordered` triggers, we should dequeue the next request + /// attempt in the corresponding `collations_per_relay_parent`. + /// + /// A triggering timer means that the fetching took too long for our taste and we should give + /// another collator the chance to be faster (dequeue next fetch request as well). + collation_fetch_timeouts: + FuturesUnordered, Hash)>>, + + /// Collations that we have successfully requested from peers and waiting + /// on validation. + fetched_candidates: HashMap, + + /// Aggregated reputation change + reputation: ReputationAggregator, +} + +fn is_relay_parent_in_implicit_view( + relay_parent: &Hash, + relay_parent_mode: ProspectiveParachainsMode, + implicit_view: &ImplicitView, + active_leaves: &HashMap, + para_id: ParaId, +) -> bool { + match relay_parent_mode { + ProspectiveParachainsMode::Disabled => active_leaves.contains_key(relay_parent), + ProspectiveParachainsMode::Enabled { .. } => active_leaves.iter().any(|(hash, mode)| { + mode.is_enabled() && + implicit_view + .known_allowed_relay_parents_under(hash, Some(para_id)) + .unwrap_or_default() + .contains(relay_parent) + }), + } +} + +async fn assign_incoming( + sender: &mut Sender, + group_assignment: &mut GroupAssignments, + current_assignments: &mut HashMap, + keystore: &KeystorePtr, + relay_parent: Hash, + relay_parent_mode: ProspectiveParachainsMode, +) -> Result<()> +where + Sender: CollatorProtocolSenderTrait, +{ + let validators = polkadot_node_subsystem_util::request_validators(relay_parent, sender) + .await + .await + .map_err(Error::CancelledActiveValidators)??; + + let (groups, rotation_info) = + polkadot_node_subsystem_util::request_validator_groups(relay_parent, sender) + .await + .await + .map_err(Error::CancelledValidatorGroups)??; + + let cores = polkadot_node_subsystem_util::request_availability_cores(relay_parent, sender) + .await + .await + .map_err(Error::CancelledAvailabilityCores)??; + + let para_now = match polkadot_node_subsystem_util::signing_key_and_index(&validators, keystore) + .and_then(|(_, index)| polkadot_node_subsystem_util::find_validator_group(&groups, index)) + { + Some(group) => { + let core_now = rotation_info.core_for_group(group, cores.len()); + + cores.get(core_now.0 as usize).and_then(|c| match c { + CoreState::Occupied(core) if relay_parent_mode.is_enabled() => Some(core.para_id()), + CoreState::Scheduled(core) => Some(core.para_id), + CoreState::Occupied(_) | CoreState::Free => None, + }) + }, + None => { + gum::trace!(target: LOG_TARGET, ?relay_parent, "Not a validator"); + + return Ok(()) + }, + }; + + // This code won't work well, if at all for on-demand parachains. For on-demand we'll + // have to be aware of which core the on-demand claim is going to be multiplexed + // onto. The on-demand claim will also have a known collator, and we should always + // allow an incoming connection from that collator. If not even connecting to them + // directly. + // + // However, this'll work fine for parachains, as each parachain gets a dedicated + // core. + if let Some(para_id) = para_now.as_ref() { + let entry = current_assignments.entry(*para_id).or_default(); + *entry += 1; + if *entry == 1 { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + para_id = ?para_id, + "Assigned to a parachain", + ); + } + } + + *group_assignment = GroupAssignments { current: para_now }; + + Ok(()) +} + +fn remove_outgoing( + current_assignments: &mut HashMap, + per_relay_parent: PerRelayParent, +) { + let GroupAssignments { current, .. } = per_relay_parent.assignment; + + if let Some(cur) = current { + if let Entry::Occupied(mut occupied) = current_assignments.entry(cur) { + *occupied.get_mut() -= 1; + if *occupied.get() == 0 { + occupied.remove_entry(); + gum::debug!( + target: LOG_TARGET, + para_id = ?cur, + "Unassigned from a parachain", + ); + } + } + } +} + +// O(n) search for collator ID by iterating through the peers map. This should be fast enough +// unless a large amount of peers is expected. +fn collator_peer_id( + peer_data: &HashMap, + collator_id: &CollatorId, +) -> Option { + peer_data + .iter() + .find_map(|(peer, data)| data.collator_id().filter(|c| c == &collator_id).map(|_| *peer)) +} + +async fn disconnect_peer(sender: &mut impl overseer::CollatorProtocolSenderTrait, peer_id: PeerId) { + sender + .send_message(NetworkBridgeTxMessage::DisconnectPeer(peer_id, PeerSet::Collation)) + .await +} + +/// Another subsystem has requested to fetch collations on a particular leaf for some para. +async fn fetch_collation( + sender: &mut impl overseer::CollatorProtocolSenderTrait, + state: &mut State, + pc: PendingCollation, + id: CollatorId, +) -> std::result::Result<(), FetchError> { + let PendingCollation { relay_parent, peer_id, prospective_candidate, .. } = pc; + let candidate_hash = prospective_candidate.as_ref().map(ProspectiveCandidate::candidate_hash); + + let peer_data = state.peer_data.get(&peer_id).ok_or(FetchError::UnknownPeer)?; + + if peer_data.has_advertised(&relay_parent, candidate_hash) { + request_collation(sender, state, pc, id.clone(), peer_data.version).await?; + let timeout = |collator_id, candidate_hash, relay_parent| async move { + Delay::new(MAX_UNSHARED_DOWNLOAD_TIME).await; + (collator_id, candidate_hash, relay_parent) + }; + state + .collation_fetch_timeouts + .push(timeout(id.clone(), candidate_hash, relay_parent).boxed()); + + Ok(()) + } else { + Err(FetchError::NotAdvertised) + } +} + +/// Report a collator for some malicious actions. +async fn report_collator( + reputation: &mut ReputationAggregator, + sender: &mut impl overseer::CollatorProtocolSenderTrait, + peer_data: &HashMap, + id: CollatorId, +) { + if let Some(peer_id) = collator_peer_id(peer_data, &id) { + modify_reputation(reputation, sender, peer_id, COST_REPORT_BAD).await; + } +} + +/// Some other subsystem has reported a collator as a good one, bump reputation. +async fn note_good_collation( + reputation: &mut ReputationAggregator, + sender: &mut impl overseer::CollatorProtocolSenderTrait, + peer_data: &HashMap, + id: CollatorId, +) { + if let Some(peer_id) = collator_peer_id(peer_data, &id) { + modify_reputation(reputation, sender, peer_id, BENEFIT_NOTIFY_GOOD).await; + } +} + +/// Notify a collator that its collation got seconded. +async fn notify_collation_seconded( + sender: &mut impl overseer::CollatorProtocolSenderTrait, + peer_id: PeerId, + version: CollationVersion, + relay_parent: Hash, + statement: SignedFullStatement, +) { + let statement = statement.into(); + let wire_message = match version { + CollationVersion::V1 => Versioned::V1(protocol_v1::CollationProtocol::CollatorProtocol( + protocol_v1::CollatorProtocolMessage::CollationSeconded(relay_parent, statement), + )), + CollationVersion::VStaging => + Versioned::VStaging(protocol_vstaging::CollationProtocol::CollatorProtocol( + protocol_vstaging::CollatorProtocolMessage::CollationSeconded( + relay_parent, + statement, + ), + )), + }; + sender + .send_message(NetworkBridgeTxMessage::SendCollationMessage(vec![peer_id], wire_message)) + .await; +} + +/// A peer's view has changed. A number of things should be done: +/// - Ongoing collation requests have to be canceled. +/// - Advertisements by this peer that are no longer relevant have to be removed. +fn handle_peer_view_change(state: &mut State, peer_id: PeerId, view: View) { + let peer_data = match state.peer_data.get_mut(&peer_id) { + Some(peer_data) => peer_data, + None => return, + }; + + peer_data.update_view( + &state.implicit_view, + &state.active_leaves, + &state.per_relay_parent, + view, + ); + state.collation_requests_cancel_handles.retain(|pc, handle| { + let keep = pc.peer_id != peer_id || peer_data.has_advertised(&pc.relay_parent, None); + if !keep { + handle.cancel(); + } + keep + }); +} + +/// Request a collation from the network. +/// This function will +/// - Check for duplicate requests. +/// - Check if the requested collation is in our view. +/// And as such invocations of this function may rely on that. +async fn request_collation( + sender: &mut impl overseer::CollatorProtocolSenderTrait, + state: &mut State, + pending_collation: PendingCollation, + collator_id: CollatorId, + peer_protocol_version: CollationVersion, +) -> std::result::Result<(), FetchError> { + if state.collation_requests_cancel_handles.contains_key(&pending_collation) { + return Err(FetchError::AlreadyRequested) + } + + let PendingCollation { relay_parent, para_id, peer_id, prospective_candidate, .. } = + pending_collation; + let per_relay_parent = state + .per_relay_parent + .get_mut(&relay_parent) + .ok_or(FetchError::RelayParentOutOfView)?; + + // Relay parent mode is checked in `handle_advertisement`. + let (requests, response_recv) = match (peer_protocol_version, prospective_candidate) { + (CollationVersion::V1, _) => { + let (req, response_recv) = OutgoingRequest::new( + Recipient::Peer(peer_id), + request_v1::CollationFetchingRequest { relay_parent, para_id }, + ); + let requests = Requests::CollationFetchingV1(req); + (requests, response_recv.boxed()) + }, + (CollationVersion::VStaging, Some(ProspectiveCandidate { candidate_hash, .. })) => { + let (req, response_recv) = OutgoingRequest::new( + Recipient::Peer(peer_id), + request_vstaging::CollationFetchingRequest { + relay_parent, + para_id, + candidate_hash, + }, + ); + let requests = Requests::CollationFetchingVStaging(req); + (requests, response_recv.boxed()) + }, + _ => return Err(FetchError::ProtocolMismatch), + }; + + let cancellation_token = CancellationToken::new(); + let collation_request = CollationFetchRequest { + pending_collation, + collator_id: collator_id.clone(), + from_collator: response_recv.boxed(), + cancellation_token: cancellation_token.clone(), + span: state + .span_per_relay_parent + .get(&relay_parent) + .map(|s| s.child("collation-request").with_para_id(para_id)), + _lifetime_timer: state.metrics.time_collation_request_duration(), + }; + + state.collation_requests.push(collation_request); + state + .collation_requests_cancel_handles + .insert(pending_collation, cancellation_token); + + gum::debug!( + target: LOG_TARGET, + peer_id = %peer_id, + %para_id, + ?relay_parent, + "Requesting collation", + ); + + let maybe_candidate_hash = + prospective_candidate.as_ref().map(ProspectiveCandidate::candidate_hash); + per_relay_parent.collations.status = CollationStatus::Fetching; + per_relay_parent + .collations + .fetching_from + .replace((collator_id, maybe_candidate_hash)); + + sender + .send_message(NetworkBridgeTxMessage::SendRequests( + vec![requests], + IfDisconnected::ImmediateError, + )) + .await; + Ok(()) +} + +/// Networking message has been received. +#[overseer::contextbounds(CollatorProtocol, prefix = overseer)] +async fn process_incoming_peer_message( + ctx: &mut Context, + state: &mut State, + origin: PeerId, + msg: Versioned< + protocol_v1::CollatorProtocolMessage, + protocol_vstaging::CollatorProtocolMessage, + >, +) { + use protocol_v1::CollatorProtocolMessage as V1; + use protocol_vstaging::CollatorProtocolMessage as VStaging; + use sp_runtime::traits::AppVerify; + + match msg { + Versioned::V1(V1::Declare(collator_id, para_id, signature)) | + Versioned::VStaging(VStaging::Declare(collator_id, para_id, signature)) => { + if collator_peer_id(&state.peer_data, &collator_id).is_some() { + modify_reputation( + &mut state.reputation, + ctx.sender(), + origin, + COST_UNEXPECTED_MESSAGE, + ) + .await; + return + } + + let peer_data = match state.peer_data.get_mut(&origin) { + Some(p) => p, + None => { + gum::debug!( + target: LOG_TARGET, + peer_id = ?origin, + ?para_id, + "Unknown peer", + ); + modify_reputation( + &mut state.reputation, + ctx.sender(), + origin, + COST_UNEXPECTED_MESSAGE, + ) + .await; + return + }, + }; + + if peer_data.is_collating() { + gum::debug!( + target: LOG_TARGET, + peer_id = ?origin, + ?para_id, + "Peer is already in the collating state", + ); + modify_reputation( + &mut state.reputation, + ctx.sender(), + origin, + COST_UNEXPECTED_MESSAGE, + ) + .await; + return + } + + if !signature.verify(&*protocol_v1::declare_signature_payload(&origin), &collator_id) { + gum::debug!( + target: LOG_TARGET, + peer_id = ?origin, + ?para_id, + "Signature verification failure", + ); + modify_reputation( + &mut state.reputation, + ctx.sender(), + origin, + COST_INVALID_SIGNATURE, + ) + .await; + return + } + + if state.current_assignments.contains_key(¶_id) { + gum::debug!( + target: LOG_TARGET, + peer_id = ?origin, + ?collator_id, + ?para_id, + "Declared as collator for current para", + ); + + peer_data.set_collating(collator_id, para_id); + } else { + gum::debug!( + target: LOG_TARGET, + peer_id = ?origin, + ?collator_id, + ?para_id, + "Declared as collator for unneeded para", + ); + + modify_reputation( + &mut state.reputation, + ctx.sender(), + origin, + COST_UNNEEDED_COLLATOR, + ) + .await; + gum::trace!(target: LOG_TARGET, "Disconnecting unneeded collator"); + disconnect_peer(ctx.sender(), origin).await; + } + }, + Versioned::V1(V1::AdvertiseCollation(relay_parent)) => + if let Err(err) = + handle_advertisement(ctx.sender(), state, relay_parent, origin, None).await + { + gum::debug!( + target: LOG_TARGET, + peer_id = ?origin, + ?relay_parent, + error = ?err, + "Rejected v1 advertisement", + ); + + if let Some(rep) = err.reputation_changes() { + modify_reputation(&mut state.reputation, ctx.sender(), origin, rep).await; + } + }, + Versioned::VStaging(VStaging::AdvertiseCollation { + relay_parent, + candidate_hash, + parent_head_data_hash, + }) => + if let Err(err) = handle_advertisement( + ctx.sender(), + state, + relay_parent, + origin, + Some((candidate_hash, parent_head_data_hash)), + ) + .await + { + gum::debug!( + target: LOG_TARGET, + peer_id = ?origin, + ?relay_parent, + ?candidate_hash, + error = ?err, + "Rejected vstaging advertisement", + ); + + if let Some(rep) = err.reputation_changes() { + modify_reputation(&mut state.reputation, ctx.sender(), origin, rep).await; + } + }, + Versioned::V1(V1::CollationSeconded(..)) | + Versioned::VStaging(VStaging::CollationSeconded(..)) => { + gum::warn!( + target: LOG_TARGET, + peer_id = ?origin, + "Unexpected `CollationSeconded` message, decreasing reputation", + ); + + modify_reputation(&mut state.reputation, ctx.sender(), origin, COST_UNEXPECTED_MESSAGE) + .await; + }, + } +} + +#[derive(Debug)] +enum AdvertisementError { + /// Relay parent is unknown. + RelayParentUnknown, + /// Peer is not present in the subsystem state. + UnknownPeer, + /// Peer has not declared its para id. + UndeclaredCollator, + /// We're assigned to a different para at the given relay parent. + InvalidAssignment, + /// An advertisement format doesn't match the relay parent. + ProtocolMismatch, + /// Para reached a limit of seconded candidates for this relay parent. + SecondedLimitReached, + /// Advertisement is invalid. + Invalid(InsertAdvertisementError), +} + +impl AdvertisementError { + fn reputation_changes(&self) -> Option { + use AdvertisementError::*; + match self { + InvalidAssignment => Some(COST_WRONG_PARA), + RelayParentUnknown | UndeclaredCollator | Invalid(_) => Some(COST_UNEXPECTED_MESSAGE), + UnknownPeer | ProtocolMismatch | SecondedLimitReached => None, + } + } +} + +// Requests backing to sanity check the advertisement. +async fn can_second( + sender: &mut Sender, + candidate_para_id: ParaId, + candidate_relay_parent: Hash, + candidate_hash: CandidateHash, + parent_head_data_hash: Hash, +) -> bool +where + Sender: CollatorProtocolSenderTrait, +{ + let request = CanSecondRequest { + candidate_para_id, + candidate_relay_parent, + candidate_hash, + parent_head_data_hash, + }; + let (tx, rx) = oneshot::channel(); + sender.send_message(CandidateBackingMessage::CanSecond(request, tx)).await; + + rx.await.unwrap_or_else(|err| { + gum::warn!( + target: LOG_TARGET, + ?err, + ?candidate_relay_parent, + ?candidate_para_id, + ?candidate_hash, + "CanSecond-request responder was dropped", + ); + + false + }) +} + +/// Checks whether any of the advertisements are unblocked and attempts to fetch them. +async fn request_unblocked_collations(sender: &mut Sender, state: &mut State, blocked: I) +where + Sender: CollatorProtocolSenderTrait, + I: IntoIterator)>, +{ + let _timer = state.metrics.time_request_unblocked_collations(); + + for (key, mut value) in blocked { + let (para_id, para_head) = key; + let blocked = std::mem::take(&mut value); + for blocked in blocked { + let is_seconding_allowed = can_second( + sender, + para_id, + blocked.candidate_relay_parent, + blocked.candidate_hash, + para_head, + ) + .await; + + if is_seconding_allowed { + let result = enqueue_collation( + sender, + state, + blocked.candidate_relay_parent, + para_id, + blocked.peer_id, + blocked.collator_id, + Some((blocked.candidate_hash, para_head)), + ) + .await; + if let Err(fetch_error) = result { + gum::debug!( + target: LOG_TARGET, + relay_parent = ?blocked.candidate_relay_parent, + para_id = ?para_id, + peer_id = ?blocked.peer_id, + error = %fetch_error, + "Failed to request unblocked collation", + ); + } + } else { + // Keep the advertisement. + value.push(blocked); + } + } + + if !value.is_empty() { + state.blocked_advertisements.insert(key, value); + } + } +} + +async fn handle_advertisement( + sender: &mut Sender, + state: &mut State, + relay_parent: Hash, + peer_id: PeerId, + prospective_candidate: Option<(CandidateHash, Hash)>, +) -> std::result::Result<(), AdvertisementError> +where + Sender: CollatorProtocolSenderTrait, +{ + let _span = state + .span_per_relay_parent + .get(&relay_parent) + .map(|s| s.child("advertise-collation")); + + let per_relay_parent = state + .per_relay_parent + .get(&relay_parent) + .ok_or(AdvertisementError::RelayParentUnknown)?; + + let relay_parent_mode = per_relay_parent.prospective_parachains_mode; + let assignment = &per_relay_parent.assignment; + + let peer_data = state.peer_data.get_mut(&peer_id).ok_or(AdvertisementError::UnknownPeer)?; + let collator_para_id = + peer_data.collating_para().ok_or(AdvertisementError::UndeclaredCollator)?; + + match assignment.current { + Some(id) if id == collator_para_id => { + // Our assignment. + }, + _ => return Err(AdvertisementError::InvalidAssignment), + }; + + if relay_parent_mode.is_enabled() && prospective_candidate.is_none() { + // Expected vstaging advertisement. + return Err(AdvertisementError::ProtocolMismatch) + } + + // Always insert advertisements that pass all the checks for spam protection. + let candidate_hash = prospective_candidate.map(|(hash, ..)| hash); + let (collator_id, para_id) = peer_data + .insert_advertisement( + relay_parent, + relay_parent_mode, + candidate_hash, + &state.implicit_view, + &state.active_leaves, + ) + .map_err(AdvertisementError::Invalid)?; + if !per_relay_parent.collations.is_seconded_limit_reached(relay_parent_mode) { + return Err(AdvertisementError::SecondedLimitReached) + } + + if let Some((candidate_hash, parent_head_data_hash)) = prospective_candidate { + let is_seconding_allowed = !relay_parent_mode.is_enabled() || + can_second( + sender, + collator_para_id, + relay_parent, + candidate_hash, + parent_head_data_hash, + ) + .await; + + if !is_seconding_allowed { + gum::debug!( + target: LOG_TARGET, + relay_parent = ?relay_parent, + para_id = ?para_id, + ?candidate_hash, + "Seconding is not allowed by backing, queueing advertisement", + ); + state + .blocked_advertisements + .entry((collator_para_id, parent_head_data_hash)) + .or_default() + .push(BlockedAdvertisement { + peer_id, + collator_id: collator_id.clone(), + candidate_relay_parent: relay_parent, + candidate_hash, + }); + + return Ok(()) + } + } + + let result = enqueue_collation( + sender, + state, + relay_parent, + para_id, + peer_id, + collator_id, + prospective_candidate, + ) + .await; + if let Err(fetch_error) = result { + gum::debug!( + target: LOG_TARGET, + relay_parent = ?relay_parent, + para_id = ?para_id, + peer_id = ?peer_id, + error = %fetch_error, + "Failed to request advertised collation", + ); + } + + Ok(()) +} + +/// Enqueue collation for fetching. The advertisement is expected to be +/// validated. +async fn enqueue_collation( + sender: &mut Sender, + state: &mut State, + relay_parent: Hash, + para_id: ParaId, + peer_id: PeerId, + collator_id: CollatorId, + prospective_candidate: Option<(CandidateHash, Hash)>, +) -> std::result::Result<(), FetchError> +where + Sender: CollatorProtocolSenderTrait, +{ + gum::debug!( + target: LOG_TARGET, + peer_id = ?peer_id, + %para_id, + ?relay_parent, + "Received advertise collation", + ); + let per_relay_parent = match state.per_relay_parent.get_mut(&relay_parent) { + Some(rp_state) => rp_state, + None => { + // Race happened, not an error. + gum::trace!( + target: LOG_TARGET, + peer_id = ?peer_id, + %para_id, + ?relay_parent, + ?prospective_candidate, + "Candidate relay parent went out of view for valid advertisement", + ); + return Ok(()) + }, + }; + let relay_parent_mode = per_relay_parent.prospective_parachains_mode; + let prospective_candidate = + prospective_candidate.map(|(candidate_hash, parent_head_data_hash)| ProspectiveCandidate { + candidate_hash, + parent_head_data_hash, + }); + + let collations = &mut per_relay_parent.collations; + if !collations.is_seconded_limit_reached(relay_parent_mode) { + gum::trace!( + target: LOG_TARGET, + peer_id = ?peer_id, + %para_id, + ?relay_parent, + "Limit of seconded collations reached for valid advertisement", + ); + return Ok(()) + } + + let pending_collation = + PendingCollation::new(relay_parent, para_id, &peer_id, prospective_candidate); + + match collations.status { + CollationStatus::Fetching | CollationStatus::WaitingOnValidation => { + gum::trace!( + target: LOG_TARGET, + peer_id = ?peer_id, + %para_id, + ?relay_parent, + "Added collation to the pending list" + ); + collations.waiting_queue.push_back((pending_collation, collator_id)); + }, + CollationStatus::Waiting => { + fetch_collation(sender, state, pending_collation, collator_id).await?; + }, + CollationStatus::Seconded if relay_parent_mode.is_enabled() => { + // Limit is not reached, it's allowed to second another + // collation. + fetch_collation(sender, state, pending_collation, collator_id).await?; + }, + CollationStatus::Seconded => { + gum::trace!( + target: LOG_TARGET, + peer_id = ?peer_id, + %para_id, + ?relay_parent, + ?relay_parent_mode, + "A collation has already been seconded", + ); + }, + } + + Ok(()) +} + +/// Our view has changed. +async fn handle_our_view_change( + sender: &mut Sender, + state: &mut State, + keystore: &KeystorePtr, + view: OurView, +) -> Result<()> +where + Sender: CollatorProtocolSenderTrait, +{ + let current_leaves = state.active_leaves.clone(); + + let removed = current_leaves.iter().filter(|(h, _)| !view.contains(h)); + let added = view.iter().filter(|h| !current_leaves.contains_key(h)); + + for leaf in added { + let mode = prospective_parachains_mode(sender, *leaf).await?; + + if let Some(span) = view.span_per_head().get(leaf).cloned() { + let per_leaf_span = PerLeafSpan::new(span, "validator-side"); + state.span_per_relay_parent.insert(*leaf, per_leaf_span); + } + + let mut per_relay_parent = PerRelayParent::new(mode); + assign_incoming( + sender, + &mut per_relay_parent.assignment, + &mut state.current_assignments, + keystore, + *leaf, + mode, + ) + .await?; + + state.active_leaves.insert(*leaf, mode); + state.per_relay_parent.insert(*leaf, per_relay_parent); + + if mode.is_enabled() { + state + .implicit_view + .activate_leaf(sender, *leaf) + .await + .map_err(Error::ImplicitViewFetchError)?; + + // Order is always descending. + let allowed_ancestry = state + .implicit_view + .known_allowed_relay_parents_under(leaf, None) + .unwrap_or_default(); + for block_hash in allowed_ancestry { + if let Entry::Vacant(entry) = state.per_relay_parent.entry(*block_hash) { + let mut per_relay_parent = PerRelayParent::new(mode); + assign_incoming( + sender, + &mut per_relay_parent.assignment, + &mut state.current_assignments, + keystore, + *block_hash, + mode, + ) + .await?; + + entry.insert(per_relay_parent); + } + } + } + } + + for (removed, mode) in removed { + state.active_leaves.remove(removed); + // If the leaf is deactivated it still may stay in the view as a part + // of implicit ancestry. Only update the state after the hash is actually + // pruned from the block info storage. + let pruned = if mode.is_enabled() { + state.implicit_view.deactivate_leaf(*removed) + } else { + vec![*removed] + }; + + for removed in pruned { + if let Some(per_relay_parent) = state.per_relay_parent.remove(&removed) { + remove_outgoing(&mut state.current_assignments, per_relay_parent); + } + + state.collation_requests_cancel_handles.retain(|pc, handle| { + let keep = pc.relay_parent != removed; + if !keep { + handle.cancel(); + } + keep + }); + state.fetched_candidates.retain(|k, _| k.relay_parent != removed); + state.span_per_relay_parent.remove(&removed); + } + } + // Remove blocked advertisements that left the view. + state.blocked_advertisements.retain(|_, ads| { + ads.retain(|ad| state.per_relay_parent.contains_key(&ad.candidate_relay_parent)); + + !ads.is_empty() + }); + // Re-trigger previously failed requests again. + // + // This makes sense for several reasons, one simple example: if a hypothetical depth + // for an advertisement initially exceeded the limit and the candidate was included + // in a new leaf. + let maybe_unblocked = std::mem::take(&mut state.blocked_advertisements); + // Could be optimized to only sanity check new leaves. + request_unblocked_collations(sender, state, maybe_unblocked).await; + + for (peer_id, peer_data) in state.peer_data.iter_mut() { + peer_data.prune_old_advertisements( + &state.implicit_view, + &state.active_leaves, + &state.per_relay_parent, + ); + + // Disconnect peers who are not relevant to our current or next para. + // + // If the peer hasn't declared yet, they will be disconnected if they do not + // declare. + if let Some(para_id) = peer_data.collating_para() { + if !state.current_assignments.contains_key(¶_id) { + gum::trace!( + target: LOG_TARGET, + ?peer_id, + ?para_id, + "Disconnecting peer on view change (not current parachain id)" + ); + disconnect_peer(sender, *peer_id).await; + } + } + } + + Ok(()) +} + +/// Bridge event switch. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn handle_network_msg( + ctx: &mut Context, + state: &mut State, + keystore: &KeystorePtr, + bridge_message: NetworkBridgeEvent, +) -> Result<()> { + use NetworkBridgeEvent::*; + + match bridge_message { + PeerConnected(peer_id, observed_role, protocol_version, _) => { + let version = match protocol_version.try_into() { + Ok(version) => version, + Err(err) => { + // Network bridge is expected to handle this. + gum::error!( + target: LOG_TARGET, + ?peer_id, + ?observed_role, + ?err, + "Unsupported protocol version" + ); + return Ok(()) + }, + }; + state.peer_data.entry(peer_id).or_insert_with(|| PeerData { + view: View::default(), + state: PeerState::Connected(Instant::now()), + version, + }); + state.metrics.note_collator_peer_count(state.peer_data.len()); + }, + PeerDisconnected(peer_id) => { + state.peer_data.remove(&peer_id); + state.metrics.note_collator_peer_count(state.peer_data.len()); + }, + NewGossipTopology { .. } => { + // impossible! + }, + PeerViewChange(peer_id, view) => { + handle_peer_view_change(state, peer_id, view); + }, + OurViewChange(view) => { + handle_our_view_change(ctx.sender(), state, keystore, view).await?; + }, + PeerMessage(remote, msg) => { + process_incoming_peer_message(ctx, state, remote, msg).await; + }, + UpdatedAuthorityIds { .. } => { + // The validator side doesn't deal with `AuthorityDiscoveryId`s. + }, + } + + Ok(()) +} + +/// The main message receiver switch. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn process_msg( + ctx: &mut Context, + keystore: &KeystorePtr, + msg: CollatorProtocolMessage, + state: &mut State, +) { + use CollatorProtocolMessage::*; + + let _timer = state.metrics.time_process_msg(); + + match msg { + CollateOn(id) => { + gum::warn!( + target: LOG_TARGET, + para_id = %id, + "CollateOn message is not expected on the validator side of the protocol", + ); + }, + DistributeCollation(..) => { + gum::warn!( + target: LOG_TARGET, + "DistributeCollation message is not expected on the validator side of the protocol", + ); + }, + ReportCollator(id) => { + report_collator(&mut state.reputation, ctx.sender(), &state.peer_data, id).await; + }, + NetworkBridgeUpdate(event) => { + if let Err(e) = handle_network_msg(ctx, state, keystore, event).await { + gum::warn!( + target: LOG_TARGET, + err = ?e, + "Failed to handle incoming network message", + ); + } + }, + Seconded(parent, stmt) => { + let receipt = match stmt.payload() { + Statement::Seconded(receipt) => receipt, + Statement::Valid(_) => { + gum::warn!( + target: LOG_TARGET, + ?stmt, + relay_parent = %parent, + "Seconded message received with a `Valid` statement", + ); + return + }, + }; + let fetched_collation = FetchedCollation::from(&receipt.to_plain()); + if let Some(CollationEvent { collator_id, pending_collation }) = + state.fetched_candidates.remove(&fetched_collation) + { + let PendingCollation { relay_parent, peer_id, prospective_candidate, .. } = + pending_collation; + note_good_collation( + &mut state.reputation, + ctx.sender(), + &state.peer_data, + collator_id.clone(), + ) + .await; + if let Some(peer_data) = state.peer_data.get(&peer_id) { + notify_collation_seconded( + ctx.sender(), + peer_id, + peer_data.version, + relay_parent, + stmt, + ) + .await; + } + + if let Some(rp_state) = state.per_relay_parent.get_mut(&parent) { + rp_state.collations.status = CollationStatus::Seconded; + rp_state.collations.note_seconded(); + } + // If async backing is enabled, make an attempt to fetch next collation. + let maybe_candidate_hash = + prospective_candidate.as_ref().map(ProspectiveCandidate::candidate_hash); + dequeue_next_collation_and_fetch( + ctx, + state, + parent, + (collator_id, maybe_candidate_hash), + ) + .await; + } else { + gum::debug!( + target: LOG_TARGET, + relay_parent = ?parent, + "Collation has been seconded, but the relay parent is deactivated", + ); + } + }, + Backed { para_id, para_head } => { + let maybe_unblocked = state.blocked_advertisements.remove_entry(&(para_id, para_head)); + request_unblocked_collations(ctx.sender(), state, maybe_unblocked).await; + }, + Invalid(parent, candidate_receipt) => { + let fetched_collation = FetchedCollation::from(&candidate_receipt); + let candidate_hash = fetched_collation.candidate_hash; + let id = match state.fetched_candidates.entry(fetched_collation) { + Entry::Occupied(entry) + if entry.get().pending_collation.commitments_hash == + Some(candidate_receipt.commitments_hash) => + entry.remove().collator_id, + Entry::Occupied(_) => { + gum::error!( + target: LOG_TARGET, + relay_parent = ?parent, + candidate = ?candidate_receipt.hash(), + "Reported invalid candidate for unknown `pending_candidate`!", + ); + return + }, + Entry::Vacant(_) => return, + }; + + report_collator(&mut state.reputation, ctx.sender(), &state.peer_data, id.clone()) + .await; + + dequeue_next_collation_and_fetch(ctx, state, parent, (id, Some(candidate_hash))).await; + }, + } +} + +/// The main run loop. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +pub(crate) async fn run( + ctx: Context, + keystore: KeystorePtr, + eviction_policy: crate::CollatorEvictionPolicy, + metrics: Metrics, +) -> std::result::Result<(), crate::error::FatalError> { + run_inner( + ctx, + keystore, + eviction_policy, + metrics, + ReputationAggregator::default(), + REPUTATION_CHANGE_INTERVAL, + ) + .await +} + +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn run_inner( + mut ctx: Context, + keystore: KeystorePtr, + eviction_policy: crate::CollatorEvictionPolicy, + metrics: Metrics, + reputation: ReputationAggregator, + reputation_interval: Duration, +) -> std::result::Result<(), crate::error::FatalError> { + let new_reputation_delay = || futures_timer::Delay::new(reputation_interval).fuse(); + let mut reputation_delay = new_reputation_delay(); + + let mut state = State { metrics, reputation, ..Default::default() }; + + let next_inactivity_stream = tick_stream(ACTIVITY_POLL); + futures::pin_mut!(next_inactivity_stream); + + let mut network_error_freq = gum::Freq::new(); + let mut canceled_freq = gum::Freq::new(); + + loop { + select! { + _ = reputation_delay => { + state.reputation.send(ctx.sender()).await; + reputation_delay = new_reputation_delay(); + }, + res = ctx.recv().fuse() => { + match res { + Ok(FromOrchestra::Communication { msg }) => { + gum::trace!(target: LOG_TARGET, msg = ?msg, "received a message"); + process_msg( + &mut ctx, + &keystore, + msg, + &mut state, + ).await; + } + Ok(FromOrchestra::Signal(OverseerSignal::Conclude)) | Err(_) => break, + Ok(FromOrchestra::Signal(_)) => continue, + } + } + _ = next_inactivity_stream.next() => { + disconnect_inactive_peers(ctx.sender(), &eviction_policy, &state.peer_data).await; + } + + resp = state.collation_requests.select_next_some() => { + let res = match handle_collation_fetch_response( + &mut state, + resp, + &mut network_error_freq, + &mut canceled_freq, + ).await { + Err(Some((peer_id, rep))) => { + modify_reputation(&mut state.reputation, ctx.sender(), peer_id, rep).await; + continue + }, + Err(None) => { + continue + }, + Ok(res) => res + }; + + let CollationEvent {collator_id, pending_collation} = res.collation_event.clone(); + if let Err(err) = kick_off_seconding(&mut ctx, &mut state, res).await { + gum::warn!( + target: LOG_TARGET, + relay_parent = ?pending_collation.relay_parent, + para_id = ?pending_collation.para_id, + peer_id = ?pending_collation.peer_id, + error = %err, + "Seconding aborted due to an error", + ); + + if err.is_malicious() { + // Report malicious peer. + modify_reputation(&mut state.reputation, ctx.sender(), pending_collation.peer_id, COST_REPORT_BAD).await; + } + let maybe_candidate_hash = + pending_collation.prospective_candidate.as_ref().map(ProspectiveCandidate::candidate_hash); + dequeue_next_collation_and_fetch( + &mut ctx, + &mut state, + pending_collation.relay_parent, + (collator_id, maybe_candidate_hash), + ) + .await; + } + } + res = state.collation_fetch_timeouts.select_next_some() => { + let (collator_id, maybe_candidate_hash, relay_parent) = res; + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + ?collator_id, + "Timeout hit - already seconded?" + ); + dequeue_next_collation_and_fetch( + &mut ctx, + &mut state, + relay_parent, + (collator_id, maybe_candidate_hash), + ) + .await; + } + } + } + + Ok(()) +} + +/// Dequeue another collation and fetch. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn dequeue_next_collation_and_fetch( + ctx: &mut Context, + state: &mut State, + relay_parent: Hash, + // The collator we tried to fetch from last, optionally which candidate. + previous_fetch: (CollatorId, Option), +) { + while let Some((next, id)) = state.per_relay_parent.get_mut(&relay_parent).and_then(|state| { + state + .collations + .get_next_collation_to_fetch(&previous_fetch, state.prospective_parachains_mode) + }) { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + ?id, + "Successfully dequeued next advertisement - fetching ..." + ); + if let Err(err) = fetch_collation(ctx.sender(), state, next, id).await { + gum::debug!( + target: LOG_TARGET, + relay_parent = ?next.relay_parent, + para_id = ?next.para_id, + peer_id = ?next.peer_id, + error = %err, + "Failed to request a collation, dequeueing next one", + ); + } else { + break + } + } +} + +async fn request_persisted_validation_data( + sender: &mut Sender, + relay_parent: Hash, + para_id: ParaId, +) -> std::result::Result, SecondingError> +where + Sender: CollatorProtocolSenderTrait, +{ + // The core is guaranteed to be scheduled since we accepted the advertisement. + polkadot_node_subsystem_util::request_persisted_validation_data( + relay_parent, + para_id, + OccupiedCoreAssumption::Free, + sender, + ) + .await + .await + .map_err(SecondingError::CancelledRuntimePersistedValidationData)? + .map_err(SecondingError::RuntimeApi) +} + +async fn request_prospective_validation_data( + sender: &mut Sender, + candidate_relay_parent: Hash, + parent_head_data_hash: Hash, + para_id: ParaId, +) -> std::result::Result, SecondingError> +where + Sender: CollatorProtocolSenderTrait, +{ + let (tx, rx) = oneshot::channel(); + + let request = + ProspectiveValidationDataRequest { para_id, candidate_relay_parent, parent_head_data_hash }; + + sender + .send_message(ProspectiveParachainsMessage::GetProspectiveValidationData(request, tx)) + .await; + + rx.await.map_err(SecondingError::CancelledProspectiveValidationData) +} + +/// Handle a fetched collation result. +#[overseer::contextbounds(CollatorProtocol, prefix = self::overseer)] +async fn kick_off_seconding( + ctx: &mut Context, + state: &mut State, + PendingCollationFetch { mut collation_event, candidate_receipt, pov }: PendingCollationFetch, +) -> std::result::Result<(), SecondingError> { + let pending_collation = collation_event.pending_collation; + let relay_parent = pending_collation.relay_parent; + + let per_relay_parent = match state.per_relay_parent.get_mut(&relay_parent) { + Some(state) => state, + None => { + // Relay parent went out of view, not an error. + gum::trace!( + target: LOG_TARGET, + relay_parent = ?relay_parent, + "Fetched collation for a parent out of view", + ); + return Ok(()) + }, + }; + let collations = &mut per_relay_parent.collations; + let relay_parent_mode = per_relay_parent.prospective_parachains_mode; + + let fetched_collation = FetchedCollation::from(&candidate_receipt); + if let Entry::Vacant(entry) = state.fetched_candidates.entry(fetched_collation) { + collation_event.pending_collation.commitments_hash = + Some(candidate_receipt.commitments_hash); + + let pvd = + match (relay_parent_mode, collation_event.pending_collation.prospective_candidate) { + ( + ProspectiveParachainsMode::Enabled { .. }, + Some(ProspectiveCandidate { parent_head_data_hash, .. }), + ) => + request_prospective_validation_data( + ctx.sender(), + relay_parent, + parent_head_data_hash, + pending_collation.para_id, + ) + .await?, + (ProspectiveParachainsMode::Disabled, _) => + request_persisted_validation_data( + ctx.sender(), + candidate_receipt.descriptor().relay_parent, + candidate_receipt.descriptor().para_id, + ) + .await?, + _ => { + // `handle_advertisement` checks for protocol mismatch. + return Ok(()) + }, + } + .ok_or(SecondingError::PersistedValidationDataNotFound)?; + + fetched_collation_sanity_check( + &collation_event.pending_collation, + &candidate_receipt, + &pvd, + )?; + + ctx.send_message(CandidateBackingMessage::Second( + relay_parent, + candidate_receipt, + pvd, + pov, + )) + .await; + // There's always a single collation being fetched at any moment of time. + // In case of a failure, we reset the status back to waiting. + collations.status = CollationStatus::WaitingOnValidation; + + entry.insert(collation_event); + Ok(()) + } else { + Err(SecondingError::Duplicate) + } +} + +// This issues `NetworkBridge` notifications to disconnect from all inactive peers at the +// earliest possible point. This does not yet clean up any metadata, as that will be done upon +// receipt of the `PeerDisconnected` event. +async fn disconnect_inactive_peers( + sender: &mut impl overseer::CollatorProtocolSenderTrait, + eviction_policy: &crate::CollatorEvictionPolicy, + peers: &HashMap, +) { + for (peer, peer_data) in peers { + if peer_data.is_inactive(&eviction_policy) { + gum::trace!(target: LOG_TARGET, "Disconnecting inactive peer"); + disconnect_peer(sender, *peer).await; + } + } +} + +/// Handle a collation fetch response. +async fn handle_collation_fetch_response( + state: &mut State, + response: ::Output, + network_error_freq: &mut gum::Freq, + canceled_freq: &mut gum::Freq, +) -> std::result::Result> { + let (CollationEvent { collator_id, pending_collation }, response) = response; + // Remove the cancellation handle, as the future already completed. + state.collation_requests_cancel_handles.remove(&pending_collation); + + let response = match response { + Err(CollationFetchError::Cancelled) => { + gum::debug!( + target: LOG_TARGET, + hash = ?pending_collation.relay_parent, + para_id = ?pending_collation.para_id, + peer_id = ?pending_collation.peer_id, + "Request was cancelled from the validator side" + ); + return Err(None) + }, + Err(CollationFetchError::Request(req_error)) => Err(req_error), + Ok(resp) => Ok(resp), + }; + + let _span = state + .span_per_relay_parent + .get(&pending_collation.relay_parent) + .map(|s| s.child("received-collation")); + let _timer = state.metrics.time_handle_collation_request_result(); + + let mut metrics_result = Err(()); + + let result = match response { + Err(RequestError::InvalidResponse(err)) => { + gum::warn!( + target: LOG_TARGET, + hash = ?pending_collation.relay_parent, + para_id = ?pending_collation.para_id, + peer_id = ?pending_collation.peer_id, + err = ?err, + "Collator provided response that could not be decoded" + ); + Err(Some((pending_collation.peer_id, COST_CORRUPTED_MESSAGE))) + }, + Err(err) if err.is_timed_out() => { + gum::debug!( + target: LOG_TARGET, + hash = ?pending_collation.relay_parent, + para_id = ?pending_collation.para_id, + peer_id = ?pending_collation.peer_id, + "Request timed out" + ); + // For now we don't want to change reputation on timeout, to mitigate issues like + // this: https://github.com/paritytech/polkadot/issues/4617 + Err(None) + }, + Err(RequestError::NetworkError(err)) => { + gum::warn_if_frequent!( + freq: network_error_freq, + max_rate: gum::Times::PerHour(100), + target: LOG_TARGET, + hash = ?pending_collation.relay_parent, + para_id = ?pending_collation.para_id, + peer_id = ?pending_collation.peer_id, + err = ?err, + "Fetching collation failed due to network error" + ); + // A minor decrease in reputation for any network failure seems + // sensible. In theory this could be exploited, by DoSing this node, + // which would result in reduced reputation for proper nodes, but the + // same can happen for penalties on timeouts, which we also have. + Err(Some((pending_collation.peer_id, COST_NETWORK_ERROR))) + }, + Err(RequestError::Canceled(err)) => { + gum::warn_if_frequent!( + freq: canceled_freq, + max_rate: gum::Times::PerHour(100), + target: LOG_TARGET, + hash = ?pending_collation.relay_parent, + para_id = ?pending_collation.para_id, + peer_id = ?pending_collation.peer_id, + err = ?err, + "Canceled should be handled by `is_timed_out` above - this is a bug!" + ); + Err(None) + }, + Ok(request_v1::CollationFetchingResponse::Collation(receipt, _)) + if receipt.descriptor().para_id != pending_collation.para_id => + { + gum::debug!( + target: LOG_TARGET, + expected_para_id = ?pending_collation.para_id, + got_para_id = ?receipt.descriptor().para_id, + peer_id = ?pending_collation.peer_id, + "Got wrong para ID for requested collation." + ); + + Err(Some((pending_collation.peer_id, COST_WRONG_PARA))) + }, + Ok(request_v1::CollationFetchingResponse::Collation(candidate_receipt, pov)) => { + gum::debug!( + target: LOG_TARGET, + para_id = %pending_collation.para_id, + hash = ?pending_collation.relay_parent, + candidate_hash = ?candidate_receipt.hash(), + "Received collation", + ); + let _span = jaeger::Span::new(&pov, "received-collation"); + + metrics_result = Ok(()); + Ok(PendingCollationFetch { + collation_event: CollationEvent { collator_id, pending_collation }, + candidate_receipt, + pov, + }) + }, + }; + state.metrics.on_request(metrics_result); + result +} diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..1cb656e325d325e6e824a3ea9ec5669f78d35424 --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs @@ -0,0 +1,1414 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use assert_matches::assert_matches; +use futures::{executor, future, Future}; +use sp_core::{crypto::Pair, Encode}; +use sp_keyring::Sr25519Keyring; +use sp_keystore::Keystore; +use std::{iter, sync::Arc, time::Duration}; + +use polkadot_node_network_protocol::{ + our_view, + peer_set::CollationVersion, + request_response::{Requests, ResponseSender}, + ObservedRole, +}; +use polkadot_node_primitives::{BlockData, PoV}; +use polkadot_node_subsystem::{ + errors::RuntimeApiError, + messages::{AllMessages, ReportPeerMessage, RuntimeApiMessage, RuntimeApiRequest}, +}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_node_subsystem_util::{reputation::add_reputation, TimeoutExt}; +use polkadot_primitives::{ + CandidateReceipt, CollatorPair, CoreState, GroupIndex, GroupRotationInfo, HeadData, + OccupiedCore, PersistedValidationData, ScheduledCore, ValidatorId, ValidatorIndex, +}; +use polkadot_primitives_test_helpers::{ + dummy_candidate_descriptor, dummy_candidate_receipt_bad_sig, dummy_hash, +}; + +mod prospective_parachains; + +const ACTIVITY_TIMEOUT: Duration = Duration::from_millis(500); +const DECLARE_TIMEOUT: Duration = Duration::from_millis(25); +const REPUTATION_CHANGE_TEST_INTERVAL: Duration = Duration::from_millis(10); + +const ASYNC_BACKING_DISABLED_ERROR: RuntimeApiError = + RuntimeApiError::NotSupported { runtime_api_name: "test-runtime" }; + +fn dummy_pvd() -> PersistedValidationData { + PersistedValidationData { + parent_head: HeadData(vec![7, 8, 9]), + relay_parent_number: 5, + max_pov_size: 1024, + relay_parent_storage_root: Default::default(), + } +} + +#[derive(Clone)] +struct TestState { + chain_ids: Vec, + relay_parent: Hash, + collators: Vec, + validator_public: Vec, + validator_groups: Vec>, + group_rotation_info: GroupRotationInfo, + cores: Vec, +} + +impl Default for TestState { + fn default() -> Self { + let chain_a = ParaId::from(1); + let chain_b = ParaId::from(2); + + let chain_ids = vec![chain_a, chain_b]; + let relay_parent = Hash::repeat_byte(0x05); + let collators = iter::repeat(()).map(|_| CollatorPair::generate().0).take(5).collect(); + + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + ]; + + let validator_public = validators.iter().map(|k| k.public().into()).collect(); + let validator_groups = vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2), ValidatorIndex(3)], + vec![ValidatorIndex(4)], + ]; + + let group_rotation_info = + GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 1, now: 0 }; + + let cores = vec![ + CoreState::Scheduled(ScheduledCore { para_id: chain_ids[0], collator: None }), + CoreState::Free, + CoreState::Occupied(OccupiedCore { + next_up_on_available: None, + occupied_since: 0, + time_out_at: 1, + next_up_on_time_out: None, + availability: Default::default(), + group_responsible: GroupIndex(0), + candidate_hash: Default::default(), + candidate_descriptor: { + let mut d = dummy_candidate_descriptor(dummy_hash()); + d.para_id = chain_ids[1]; + + d + }, + }), + ]; + + Self { + chain_ids, + relay_parent, + collators, + validator_public, + validator_groups, + group_rotation_info, + cores, + } + } +} + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; + +struct TestHarness { + virtual_overseer: VirtualOverseer, + keystore: KeystorePtr, +} + +fn test_harness>( + reputation: ReputationAggregator, + test: impl FnOnce(TestHarness) -> T, +) { + let _ = env_logger::builder() + .is_test(true) + .filter(Some("polkadot_collator_protocol"), log::LevelFilter::Trace) + .filter(Some(LOG_TARGET), log::LevelFilter::Trace) + .try_init(); + + let pool = sp_core::testing::TaskExecutor::new(); + + let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); + + let keystore = Arc::new(sc_keystore::LocalKeystore::in_memory()); + Keystore::sr25519_generate_new( + &*keystore, + polkadot_primitives::PARACHAIN_KEY_TYPE_ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .expect("Insert key into keystore"); + + let subsystem = run_inner( + context, + keystore.clone(), + crate::CollatorEvictionPolicy { + inactive_collator: ACTIVITY_TIMEOUT, + undeclared: DECLARE_TIMEOUT, + }, + Metrics::default(), + reputation, + REPUTATION_CHANGE_TEST_INTERVAL, + ); + + let test_fut = test(TestHarness { virtual_overseer, keystore }); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )) + .1 + .unwrap(); +} + +const TIMEOUT: Duration = Duration::from_millis(200); + +async fn overseer_send(overseer: &mut VirtualOverseer, msg: CollatorProtocolMessage) { + gum::trace!("Sending message:\n{:?}", &msg); + overseer + .send(FromOrchestra::Communication { msg }) + .timeout(TIMEOUT) + .await + .expect(&format!("{:?} is enough for sending messages.", TIMEOUT)); +} + +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { + let msg = overseer_recv_with_timeout(overseer, TIMEOUT) + .await + .expect(&format!("{:?} is enough to receive messages.", TIMEOUT)); + + gum::trace!("Received message:\n{:?}", &msg); + + msg +} + +async fn overseer_recv_with_timeout( + overseer: &mut VirtualOverseer, + timeout: Duration, +) -> Option { + gum::trace!("Waiting for message..."); + overseer.recv().timeout(timeout).await +} + +async fn overseer_signal(overseer: &mut VirtualOverseer, signal: OverseerSignal) { + overseer + .send(FromOrchestra::Signal(signal)) + .timeout(TIMEOUT) + .await + .expect(&format!("{:?} is more than enough for sending signals.", TIMEOUT)); +} + +async fn respond_to_core_info_queries( + virtual_overseer: &mut VirtualOverseer, + test_state: &TestState, +) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::Validators(tx), + )) => { + let _ = tx.send(Ok(test_state.validator_public.clone())); + } + ); + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::ValidatorGroups(tx), + )) => { + let _ = tx.send(Ok(( + test_state.validator_groups.clone(), + test_state.group_rotation_info.clone(), + ))); + } + ); + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::AvailabilityCores(tx), + )) => { + let _ = tx.send(Ok(test_state.cores.clone())); + } + ); +} + +/// Assert that the next message is a `CandidateBacking(Second())`. +async fn assert_candidate_backing_second( + virtual_overseer: &mut VirtualOverseer, + expected_relay_parent: Hash, + expected_para_id: ParaId, + expected_pov: &PoV, + mode: ProspectiveParachainsMode, +) -> CandidateReceipt { + let pvd = dummy_pvd(); + + // Depending on relay parent mode pvd will be either requested + // from the Runtime API or Prospective Parachains. + let msg = overseer_recv(virtual_overseer).await; + match mode { + ProspectiveParachainsMode::Disabled => assert_matches!( + msg, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::PersistedValidationData(para_id, assumption, tx), + )) => { + assert_eq!(expected_relay_parent, hash); + assert_eq!(expected_para_id, para_id); + assert_eq!(OccupiedCoreAssumption::Free, assumption); + tx.send(Ok(Some(pvd.clone()))).unwrap(); + } + ), + ProspectiveParachainsMode::Enabled { .. } => assert_matches!( + msg, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetProspectiveValidationData(request, tx), + ) => { + assert_eq!(expected_relay_parent, request.candidate_relay_parent); + assert_eq!(expected_para_id, request.para_id); + tx.send(Some(pvd.clone())).unwrap(); + } + ), + } + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::CandidateBacking(CandidateBackingMessage::Second( + relay_parent, + candidate_receipt, + received_pvd, + incoming_pov, + )) => { + assert_eq!(expected_relay_parent, relay_parent); + assert_eq!(expected_para_id, candidate_receipt.descriptor.para_id); + assert_eq!(*expected_pov, incoming_pov); + assert_eq!(pvd, received_pvd); + candidate_receipt + } + ) +} + +/// Assert that a collator got disconnected. +async fn assert_collator_disconnect(virtual_overseer: &mut VirtualOverseer, expected_peer: PeerId) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::DisconnectPeer( + peer, + peer_set, + )) => { + assert_eq!(expected_peer, peer); + assert_eq!(PeerSet::Collation, peer_set); + } + ); +} + +/// Assert that a fetch collation request was send. +async fn assert_fetch_collation_request( + virtual_overseer: &mut VirtualOverseer, + relay_parent: Hash, + para_id: ParaId, + candidate_hash: Option, +) -> ResponseSender { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendRequests(reqs, IfDisconnected::ImmediateError) + ) => { + let req = reqs.into_iter().next() + .expect("There should be exactly one request"); + match candidate_hash { + None => assert_matches!( + req, + Requests::CollationFetchingV1(req) => { + let payload = req.payload; + assert_eq!(payload.relay_parent, relay_parent); + assert_eq!(payload.para_id, para_id); + req.pending_response + } + ), + Some(candidate_hash) => assert_matches!( + req, + Requests::CollationFetchingVStaging(req) => { + let payload = req.payload; + assert_eq!(payload.relay_parent, relay_parent); + assert_eq!(payload.para_id, para_id); + assert_eq!(payload.candidate_hash, candidate_hash); + req.pending_response + } + ), + } + }) +} + +/// Connect and declare a collator +async fn connect_and_declare_collator( + virtual_overseer: &mut VirtualOverseer, + peer: PeerId, + collator: CollatorPair, + para_id: ParaId, + version: CollationVersion, +) { + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Full, + version.into(), + None, + )), + ) + .await; + + let wire_message = match version { + CollationVersion::V1 => Versioned::V1(protocol_v1::CollatorProtocolMessage::Declare( + collator.public(), + para_id, + collator.sign(&protocol_v1::declare_signature_payload(&peer)), + )), + CollationVersion::VStaging => + Versioned::VStaging(protocol_vstaging::CollatorProtocolMessage::Declare( + collator.public(), + para_id, + collator.sign(&protocol_v1::declare_signature_payload(&peer)), + )), + }; + + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerMessage( + peer, + wire_message, + )), + ) + .await; +} + +/// Advertise a collation. +async fn advertise_collation( + virtual_overseer: &mut VirtualOverseer, + peer: PeerId, + relay_parent: Hash, + candidate: Option<(CandidateHash, Hash)>, // Candidate hash + parent head data hash. +) { + let wire_message = match candidate { + Some((candidate_hash, parent_head_data_hash)) => + Versioned::VStaging(protocol_vstaging::CollatorProtocolMessage::AdvertiseCollation { + relay_parent, + candidate_hash, + parent_head_data_hash, + }), + None => + Versioned::V1(protocol_v1::CollatorProtocolMessage::AdvertiseCollation(relay_parent)), + }; + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerMessage( + peer, + wire_message, + )), + ) + .await; +} + +async fn assert_async_backing_params_request(virtual_overseer: &mut VirtualOverseer, hash: Hash) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::StagingAsyncBackingParams(tx) + )) => { + assert_eq!(relay_parent, hash); + tx.send(Err(ASYNC_BACKING_DISABLED_ERROR)).unwrap(); + } + ); +} + +// As we receive a relevant advertisement act on it and issue a collation request. +#[test] +fn act_on_advertisement() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair = CollatorPair::generate().0; + gum::trace!("activating"); + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; + + assert_async_backing_params_request(&mut virtual_overseer, test_state.relay_parent).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + + let peer_b = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + pair.clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + advertise_collation(&mut virtual_overseer, peer_b, test_state.relay_parent, None).await; + + assert_fetch_collation_request( + &mut virtual_overseer, + test_state.relay_parent, + test_state.chain_ids[0], + None, + ) + .await; + + virtual_overseer + }); +} + +/// Tests that validator side works with vstaging network protocol +/// before async backing is enabled. +#[test] +fn act_on_advertisement_vstaging() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair = CollatorPair::generate().0; + gum::trace!("activating"); + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; + + assert_async_backing_params_request(&mut virtual_overseer, test_state.relay_parent).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + + let peer_b = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + pair.clone(), + test_state.chain_ids[0], + CollationVersion::VStaging, + ) + .await; + + let candidate_hash = CandidateHash::default(); + let parent_head_data_hash = Hash::zero(); + // vstaging advertisement. + advertise_collation( + &mut virtual_overseer, + peer_b, + test_state.relay_parent, + Some((candidate_hash, parent_head_data_hash)), + ) + .await; + + assert_fetch_collation_request( + &mut virtual_overseer, + test_state.relay_parent, + test_state.chain_ids[0], + Some(candidate_hash), + ) + .await; + + virtual_overseer + }); +} + +// Test that other subsystems may modify collators' reputations. +#[test] +fn collator_reporting_works() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; + + assert_async_backing_params_request(&mut virtual_overseer, test_state.relay_parent).await; + + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + test_state.collators[0].clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + connect_and_declare_collator( + &mut virtual_overseer, + peer_c, + test_state.collators[1].clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::ReportCollator(test_state.collators[0].public()), + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)), + ) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, COST_REPORT_BAD.cost_or_benefit()); + } + ); + + virtual_overseer + }); +} + +// Test that we verify the signatures on `Declare` and `AdvertiseCollation` messages. +#[test] +fn collator_authentication_verification_works() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let peer_b = PeerId::random(); + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerConnected( + peer_b, + ObservedRole::Full, + CollationVersion::V1.into(), + None, + )), + ) + .await; + + // the peer sends a declare message but sign the wrong payload + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerMessage( + peer_b, + Versioned::V1(protocol_v1::CollatorProtocolMessage::Declare( + test_state.collators[0].public(), + test_state.chain_ids[0], + test_state.collators[0].sign(&[42]), + )), + )), + ) + .await; + + // it should be reported for sending a message with an invalid signature + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer, rep)), + ) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, COST_INVALID_SIGNATURE.cost_or_benefit()); + } + ); + virtual_overseer + }); +} + +/// Tests that a validator fetches only one collation at any moment of time +/// per relay parent and ignores other advertisements once a candidate gets +/// seconded. +#[test] +fn fetch_one_collation_at_a_time() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + let second = Hash::random(); + + let our_view = our_view![test_state.relay_parent, second]; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view.clone(), + )), + ) + .await; + + // Iter over view since the order may change due to sorted invariant. + for hash in our_view.iter() { + assert_async_backing_params_request(&mut virtual_overseer, *hash).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + } + + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + test_state.collators[0].clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + connect_and_declare_collator( + &mut virtual_overseer, + peer_c, + test_state.collators[1].clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + advertise_collation(&mut virtual_overseer, peer_b, test_state.relay_parent, None).await; + advertise_collation(&mut virtual_overseer, peer_c, test_state.relay_parent, None).await; + + let response_channel = assert_fetch_collation_request( + &mut virtual_overseer, + test_state.relay_parent, + test_state.chain_ids[0], + None, + ) + .await; + + assert!( + overseer_recv_with_timeout(&mut &mut virtual_overseer, Duration::from_millis(30)).await.is_none(), + "There should not be sent any other PoV request while the first one wasn't finished or timed out.", + ); + + let pov = PoV { block_data: BlockData(vec![]) }; + let mut candidate_a = + dummy_candidate_receipt_bad_sig(dummy_hash(), Some(Default::default())); + candidate_a.descriptor.para_id = test_state.chain_ids[0]; + candidate_a.descriptor.relay_parent = test_state.relay_parent; + candidate_a.descriptor.persisted_validation_data_hash = dummy_pvd().hash(); + response_channel + .send(Ok(request_v1::CollationFetchingResponse::Collation( + candidate_a.clone(), + pov.clone(), + ) + .encode())) + .expect("Sending response should succeed"); + + assert_candidate_backing_second( + &mut virtual_overseer, + test_state.relay_parent, + test_state.chain_ids[0], + &pov, + ProspectiveParachainsMode::Disabled, + ) + .await; + + // Ensure the subsystem is polled. + test_helpers::Yield::new().await; + + // Second collation is not requested since there's already seconded one. + assert_matches!(virtual_overseer.recv().now_or_never(), None); + + virtual_overseer + }) +} + +/// Tests that a validator starts fetching next queued collations on [`MAX_UNSHARED_DOWNLOAD_TIME`] +/// timeout and in case of an error. +#[test] +fn fetches_next_collation() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let second = Hash::random(); + + let our_view = our_view![test_state.relay_parent, second]; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view.clone(), + )), + ) + .await; + + for hash in our_view.iter() { + assert_async_backing_params_request(&mut virtual_overseer, *hash).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + } + + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + test_state.collators[2].clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + connect_and_declare_collator( + &mut virtual_overseer, + peer_c, + test_state.collators[3].clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + connect_and_declare_collator( + &mut virtual_overseer, + peer_d, + test_state.collators[4].clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + advertise_collation(&mut virtual_overseer, peer_b, second, None).await; + advertise_collation(&mut virtual_overseer, peer_c, second, None).await; + advertise_collation(&mut virtual_overseer, peer_d, second, None).await; + + // Dropping the response channel should lead to fetching the second collation. + assert_fetch_collation_request( + &mut virtual_overseer, + second, + test_state.chain_ids[0], + None, + ) + .await; + + let response_channel_non_exclusive = assert_fetch_collation_request( + &mut virtual_overseer, + second, + test_state.chain_ids[0], + None, + ) + .await; + + // Third collator should receive response after that timeout: + Delay::new(MAX_UNSHARED_DOWNLOAD_TIME + Duration::from_millis(50)).await; + + let response_channel = assert_fetch_collation_request( + &mut virtual_overseer, + second, + test_state.chain_ids[0], + None, + ) + .await; + + let pov = PoV { block_data: BlockData(vec![1]) }; + let mut candidate_a = + dummy_candidate_receipt_bad_sig(dummy_hash(), Some(Default::default())); + candidate_a.descriptor.para_id = test_state.chain_ids[0]; + candidate_a.descriptor.relay_parent = second; + candidate_a.descriptor.persisted_validation_data_hash = dummy_pvd().hash(); + + // First request finishes now: + response_channel_non_exclusive + .send(Ok(request_v1::CollationFetchingResponse::Collation( + candidate_a.clone(), + pov.clone(), + ) + .encode())) + .expect("Sending response should succeed"); + + response_channel + .send(Ok(request_v1::CollationFetchingResponse::Collation( + candidate_a.clone(), + pov.clone(), + ) + .encode())) + .expect("Sending response should succeed"); + + assert_candidate_backing_second( + &mut virtual_overseer, + second, + test_state.chain_ids[0], + &pov, + ProspectiveParachainsMode::Disabled, + ) + .await; + + virtual_overseer + }); +} + +#[test] +fn reject_connection_to_next_group() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; + + assert_async_backing_params_request(&mut virtual_overseer, test_state.relay_parent).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + + let peer_b = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + test_state.collators[0].clone(), + test_state.chain_ids[1], // next, not current `para_id` + CollationVersion::V1, + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer( + ReportPeerMessage::Single(peer, rep), + )) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, COST_UNNEEDED_COLLATOR.cost_or_benefit()); + } + ); + + assert_collator_disconnect(&mut virtual_overseer, peer_b).await; + + virtual_overseer + }) +} + +// Ensure that we fetch a second collation, after the first checked collation was found to be +// invalid. +#[test] +fn fetch_next_collation_on_invalid_collation() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let second = Hash::random(); + + let our_view = our_view![test_state.relay_parent, second]; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view.clone(), + )), + ) + .await; + + for hash in our_view.iter() { + assert_async_backing_params_request(&mut virtual_overseer, *hash).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + } + + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + test_state.collators[0].clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + connect_and_declare_collator( + &mut virtual_overseer, + peer_c, + test_state.collators[1].clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + advertise_collation(&mut virtual_overseer, peer_b, test_state.relay_parent, None).await; + advertise_collation(&mut virtual_overseer, peer_c, test_state.relay_parent, None).await; + + let response_channel = assert_fetch_collation_request( + &mut virtual_overseer, + test_state.relay_parent, + test_state.chain_ids[0], + None, + ) + .await; + + let pov = PoV { block_data: BlockData(vec![]) }; + let mut candidate_a = + dummy_candidate_receipt_bad_sig(dummy_hash(), Some(Default::default())); + candidate_a.descriptor.para_id = test_state.chain_ids[0]; + candidate_a.descriptor.relay_parent = test_state.relay_parent; + candidate_a.descriptor.persisted_validation_data_hash = dummy_pvd().hash(); + response_channel + .send(Ok(request_v1::CollationFetchingResponse::Collation( + candidate_a.clone(), + pov.clone(), + ) + .encode())) + .expect("Sending response should succeed"); + + let receipt = assert_candidate_backing_second( + &mut virtual_overseer, + test_state.relay_parent, + test_state.chain_ids[0], + &pov, + ProspectiveParachainsMode::Disabled, + ) + .await; + + // Inform that the candidate was invalid. + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::Invalid(test_state.relay_parent, receipt), + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer( + ReportPeerMessage::Single(peer, rep), + )) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, COST_REPORT_BAD.cost_or_benefit()); + } + ); + + // We should see a request for another collation. + assert_fetch_collation_request( + &mut virtual_overseer, + test_state.relay_parent, + test_state.chain_ids[0], + None, + ) + .await; + + virtual_overseer + }); +} + +#[test] +fn inactive_disconnected() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair = CollatorPair::generate().0; + + let hash_a = test_state.relay_parent; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view![hash_a], + )), + ) + .await; + + assert_async_backing_params_request(&mut virtual_overseer, hash_a).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + + let peer_b = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + pair.clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + advertise_collation(&mut virtual_overseer, peer_b, test_state.relay_parent, None).await; + + assert_fetch_collation_request( + &mut virtual_overseer, + test_state.relay_parent, + test_state.chain_ids[0], + None, + ) + .await; + + Delay::new(ACTIVITY_TIMEOUT * 3).await; + + assert_collator_disconnect(&mut virtual_overseer, peer_b).await; + virtual_overseer + }); +} + +#[test] +fn activity_extends_life() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair = CollatorPair::generate().0; + + let hash_a = test_state.relay_parent; + let hash_b = Hash::repeat_byte(1); + let hash_c = Hash::repeat_byte(2); + + let our_view = our_view![hash_a, hash_b, hash_c]; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view.clone(), + )), + ) + .await; + + for hash in our_view.iter() { + assert_async_backing_params_request(&mut virtual_overseer, *hash).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + } + + let peer_b = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + pair.clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await; + + advertise_collation(&mut virtual_overseer, peer_b, hash_a, None).await; + + assert_fetch_collation_request( + &mut virtual_overseer, + hash_a, + test_state.chain_ids[0], + None, + ) + .await; + + Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await; + + advertise_collation(&mut virtual_overseer, peer_b, hash_b, None).await; + + assert_fetch_collation_request( + &mut virtual_overseer, + hash_b, + test_state.chain_ids[0], + None, + ) + .await; + + Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await; + + advertise_collation(&mut virtual_overseer, peer_b, hash_c, None).await; + + assert_fetch_collation_request( + &mut virtual_overseer, + hash_c, + test_state.chain_ids[0], + None, + ) + .await; + + Delay::new(ACTIVITY_TIMEOUT * 3 / 2).await; + + assert_collator_disconnect(&mut virtual_overseer, peer_b).await; + + virtual_overseer + }); +} + +#[test] +fn disconnect_if_no_declare() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; + + assert_async_backing_params_request(&mut virtual_overseer, test_state.relay_parent).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + + let peer_b = PeerId::random(); + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerConnected( + peer_b, + ObservedRole::Full, + CollationVersion::V1.into(), + None, + )), + ) + .await; + + assert_collator_disconnect(&mut virtual_overseer, peer_b).await; + + virtual_overseer + }) +} + +#[test] +fn disconnect_if_wrong_declare() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair = CollatorPair::generate().0; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; + + assert_async_backing_params_request(&mut virtual_overseer, test_state.relay_parent).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + + let peer_b = PeerId::random(); + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerConnected( + peer_b, + ObservedRole::Full, + CollationVersion::V1.into(), + None, + )), + ) + .await; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerMessage( + peer_b, + Versioned::V1(protocol_v1::CollatorProtocolMessage::Declare( + pair.public(), + ParaId::from(69), + pair.sign(&protocol_v1::declare_signature_payload(&peer_b)), + )), + )), + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer( + ReportPeerMessage::Single(peer, rep), + )) => { + assert_eq!(peer, peer_b); + assert_eq!(rep.value, COST_UNNEEDED_COLLATOR.cost_or_benefit()); + } + ); + + assert_collator_disconnect(&mut virtual_overseer, peer_b).await; + + virtual_overseer + }) +} + +#[test] +fn delay_reputation_change() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| false), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair = CollatorPair::generate().0; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; + + assert_async_backing_params_request(&mut virtual_overseer, test_state.relay_parent).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + + let peer_b = PeerId::random(); + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerConnected( + peer_b, + ObservedRole::Full, + CollationVersion::V1.into(), + None, + )), + ) + .await; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerMessage( + peer_b, + Versioned::V1(protocol_v1::CollatorProtocolMessage::Declare( + pair.public(), + ParaId::from(69), + pair.sign(&protocol_v1::declare_signature_payload(&peer_b)), + )), + )), + ) + .await; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerMessage( + peer_b, + Versioned::V1(protocol_v1::CollatorProtocolMessage::Declare( + pair.public(), + ParaId::from(69), + pair.sign(&protocol_v1::declare_signature_payload(&peer_b)), + )), + )), + ) + .await; + + // Wait enough to fire reputation delay + futures_timer::Delay::new(REPUTATION_CHANGE_TEST_INTERVAL).await; + + loop { + match overseer_recv(&mut virtual_overseer).await { + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::DisconnectPeer(_, _)) => { + gum::trace!("`Disconnecting inactive peer` message skipped"); + continue + }, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer( + ReportPeerMessage::Batch(v), + )) => { + let mut expected_change = HashMap::new(); + for rep in vec![COST_UNNEEDED_COLLATOR, COST_UNNEEDED_COLLATOR] { + add_reputation(&mut expected_change, peer_b, rep); + } + assert_eq!(v, expected_change); + break + }, + _ => panic!("Message should be either `DisconnectPeer` or `ReportPeer`"), + } + } + + virtual_overseer + }) +} + +#[test] +fn view_change_clears_old_collators() { + let mut test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair = CollatorPair::generate().0; + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; + + assert_async_backing_params_request(&mut virtual_overseer, test_state.relay_parent).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + + let peer_b = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + pair.clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + let hash_b = Hash::repeat_byte(69); + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange( + our_view![hash_b], + )), + ) + .await; + + test_state.group_rotation_info = test_state.group_rotation_info.bump_rotation(); + assert_async_backing_params_request(&mut virtual_overseer, hash_b).await; + respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; + + assert_collator_disconnect(&mut virtual_overseer, peer_b).await; + + virtual_overseer + }) +} diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs new file mode 100644 index 0000000000000000000000000000000000000000..a803827792d8b6ed51c17e13d5d238b6809d0097 --- /dev/null +++ b/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs @@ -0,0 +1,988 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests for the validator side with enabled prospective parachains. + +use super::*; + +use polkadot_node_subsystem::messages::ChainApiMessage; +use polkadot_primitives::{ + vstaging as vstaging_primitives, BlockNumber, CandidateCommitments, CommittedCandidateReceipt, + Header, SigningContext, ValidatorId, +}; + +const ASYNC_BACKING_PARAMETERS: vstaging_primitives::AsyncBackingParams = + vstaging_primitives::AsyncBackingParams { max_candidate_depth: 4, allowed_ancestry_len: 3 }; + +fn get_parent_hash(hash: Hash) -> Hash { + Hash::from_low_u64_be(hash.to_low_u64_be() + 1) +} + +async fn assert_assign_incoming( + virtual_overseer: &mut VirtualOverseer, + test_state: &TestState, + hash: Hash, + number: BlockNumber, + next_msg: &mut Option, +) { + let msg = match next_msg.take() { + Some(msg) => msg, + None => overseer_recv(virtual_overseer).await, + }; + assert_matches!( + msg, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::Validators(tx)) + ) if parent == hash => { + tx.send(Ok(test_state.validator_public.clone())).unwrap(); + } + ); + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::ValidatorGroups(tx)) + ) if parent == hash => { + let validator_groups = test_state.validator_groups.clone(); + let mut group_rotation_info = test_state.group_rotation_info.clone(); + group_rotation_info.now = number; + tx.send(Ok((validator_groups, group_rotation_info))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::AvailabilityCores(tx)) + ) if parent == hash => { + tx.send(Ok(test_state.cores.clone())).unwrap(); + } + ); +} + +/// Handle a view update. +async fn update_view( + virtual_overseer: &mut VirtualOverseer, + test_state: &TestState, + new_view: Vec<(Hash, u32)>, // Hash and block number. + activated: u8, // How many new heads does this update contain? +) -> Option { + let new_view: HashMap = HashMap::from_iter(new_view); + + let our_view = + OurView::new(new_view.keys().map(|hash| (*hash, Arc::new(jaeger::Span::Disabled))), 0); + + overseer_send( + virtual_overseer, + CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange(our_view)), + ) + .await; + + let mut next_overseer_message = None; + for _ in 0..activated { + let (leaf_hash, leaf_number) = assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + parent, + RuntimeApiRequest::StagingAsyncBackingParams(tx), + )) => { + tx.send(Ok(ASYNC_BACKING_PARAMETERS)).unwrap(); + (parent, new_view.get(&parent).copied().expect("Unknown parent requested")) + } + ); + + assert_assign_incoming( + virtual_overseer, + test_state, + leaf_hash, + leaf_number, + &mut next_overseer_message, + ) + .await; + + let min_number = leaf_number.saturating_sub(ASYNC_BACKING_PARAMETERS.allowed_ancestry_len); + + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetMinimumRelayParents(parent, tx), + ) if parent == leaf_hash => { + tx.send(test_state.chain_ids.iter().map(|para_id| (*para_id, min_number)).collect()).unwrap(); + } + ); + + let ancestry_len = leaf_number + 1 - min_number; + let ancestry_hashes = std::iter::successors(Some(leaf_hash), |h| Some(get_parent_hash(*h))) + .take(ancestry_len as usize); + let ancestry_numbers = (min_number..=leaf_number).rev(); + let ancestry_iter = ancestry_hashes.clone().zip(ancestry_numbers).peekable(); + + // How many blocks were actually requested. + let mut requested_len: usize = 0; + { + let mut ancestry_iter = ancestry_iter.clone(); + while let Some((hash, number)) = ancestry_iter.next() { + // May be `None` for the last element. + let parent_hash = + ancestry_iter.peek().map(|(h, _)| *h).unwrap_or_else(|| get_parent_hash(hash)); + + let msg = match next_overseer_message.take() { + Some(msg) => msg, + None => overseer_recv(virtual_overseer).await, + }; + + if !matches!(&msg, AllMessages::ChainApi(ChainApiMessage::BlockHeader(..))) { + // Ancestry has already been cached for this leaf. + next_overseer_message.replace(msg); + break + } + + assert_matches!( + msg, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(.., tx)) => { + let header = Header { + parent_hash, + number, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + }; + + tx.send(Ok(Some(header))).unwrap(); + } + ); + + requested_len += 1; + } + } + + // Skip the leaf. + for (hash, number) in ancestry_iter.skip(1).take(requested_len.saturating_sub(1)) { + assert_assign_incoming( + virtual_overseer, + test_state, + hash, + number, + &mut next_overseer_message, + ) + .await; + } + } + next_overseer_message +} + +async fn send_seconded_statement( + virtual_overseer: &mut VirtualOverseer, + keystore: KeystorePtr, + candidate: &CommittedCandidateReceipt, +) { + let signing_context = SigningContext { session_index: 0, parent_hash: Hash::zero() }; + let stmt = SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate.clone()), + &signing_context, + ValidatorIndex(0), + &ValidatorId::from(Sr25519Keyring::Alice.public()), + ) + .ok() + .flatten() + .expect("should be signed"); + + overseer_send( + virtual_overseer, + CollatorProtocolMessage::Seconded(candidate.descriptor.relay_parent, stmt), + ) + .await; +} + +async fn assert_collation_seconded( + virtual_overseer: &mut VirtualOverseer, + relay_parent: Hash, + peer_id: PeerId, +) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer( + ReportPeerMessage::Single(peer, rep) + )) => { + assert_eq!(peer_id, peer); + assert_eq!(rep.value, BENEFIT_NOTIFY_GOOD.cost_or_benefit()); + } + ); + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendCollationMessage( + peers, + Versioned::VStaging(protocol_vstaging::CollationProtocol::CollatorProtocol( + protocol_vstaging::CollatorProtocolMessage::CollationSeconded( + _relay_parent, + .., + ), + )), + )) => { + assert_eq!(peers, vec![peer_id]); + assert_eq!(relay_parent, _relay_parent); + } + ); +} + +#[test] +fn v1_advertisement_rejected() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair_a = CollatorPair::generate().0; + + let head_b = Hash::from_low_u64_be(128); + let head_b_num: u32 = 0; + + update_view(&mut virtual_overseer, &test_state, vec![(head_b, head_b_num)], 1).await; + + let peer_a = PeerId::random(); + + // Accept both collators from the implicit view. + connect_and_declare_collator( + &mut virtual_overseer, + peer_a, + pair_a.clone(), + test_state.chain_ids[0], + CollationVersion::V1, + ) + .await; + + advertise_collation(&mut virtual_overseer, peer_a, head_b, None).await; + + // Not reported. + test_helpers::Yield::new().await; + assert_matches!(virtual_overseer.recv().now_or_never(), None); + + virtual_overseer + }); +} + +#[test] +fn accept_advertisements_from_implicit_view() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair_a = CollatorPair::generate().0; + let pair_b = CollatorPair::generate().0; + + let head_b = Hash::from_low_u64_be(128); + let head_b_num: u32 = 2; + + let head_c = get_parent_hash(head_b); + // Grandparent of head `b`. + // Group rotation frequency is 1 by default, at `d` we're assigned + // to the first para. + let head_d = get_parent_hash(head_c); + + // Activated leaf is `b`, but the collation will be based on `c`. + update_view(&mut virtual_overseer, &test_state, vec![(head_b, head_b_num)], 1).await; + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + + // Accept both collators from the implicit view. + connect_and_declare_collator( + &mut virtual_overseer, + peer_a, + pair_a.clone(), + test_state.chain_ids[0], + CollationVersion::VStaging, + ) + .await; + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + pair_b.clone(), + test_state.chain_ids[1], + CollationVersion::VStaging, + ) + .await; + + let candidate_hash = CandidateHash::default(); + let parent_head_data_hash = Hash::zero(); + advertise_collation( + &mut virtual_overseer, + peer_b, + head_c, + Some((candidate_hash, parent_head_data_hash)), + ) + .await; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidate_hash); + assert_eq!(request.candidate_para_id, test_state.chain_ids[1]); + assert_eq!(request.parent_head_data_hash, parent_head_data_hash); + tx.send(true).expect("receiving side should be alive"); + } + ); + + assert_fetch_collation_request( + &mut virtual_overseer, + head_c, + test_state.chain_ids[1], + Some(candidate_hash), + ) + .await; + // Advertise with different para. + advertise_collation( + &mut virtual_overseer, + peer_a, + head_d, // Note different relay parent. + Some((candidate_hash, parent_head_data_hash)), + ) + .await; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidate_hash); + assert_eq!(request.candidate_para_id, test_state.chain_ids[0]); + assert_eq!(request.parent_head_data_hash, parent_head_data_hash); + tx.send(true).expect("receiving side should be alive"); + } + ); + + assert_fetch_collation_request( + &mut virtual_overseer, + head_d, + test_state.chain_ids[0], + Some(candidate_hash), + ) + .await; + + virtual_overseer + }); +} + +#[test] +fn second_multiple_candidates_per_relay_parent() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, keystore } = test_harness; + + let pair = CollatorPair::generate().0; + + // Grandparent of head `a`. + let head_b = Hash::from_low_u64_be(128); + let head_b_num: u32 = 2; + + // Grandparent of head `b`. + // Group rotation frequency is 1 by default, at `c` we're assigned + // to the first para. + let head_c = Hash::from_low_u64_be(130); + + // Activated leaf is `b`, but the collation will be based on `c`. + update_view(&mut virtual_overseer, &test_state, vec![(head_b, head_b_num)], 1).await; + + let peer_a = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_a, + pair.clone(), + test_state.chain_ids[0], + CollationVersion::VStaging, + ) + .await; + + for i in 0..(ASYNC_BACKING_PARAMETERS.max_candidate_depth + 1) { + let mut candidate = dummy_candidate_receipt_bad_sig(head_c, Some(Default::default())); + candidate.descriptor.para_id = test_state.chain_ids[0]; + candidate.descriptor.persisted_validation_data_hash = dummy_pvd().hash(); + let commitments = CandidateCommitments { + head_data: HeadData(vec![i as u8]), + horizontal_messages: Default::default(), + upward_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0, + }; + candidate.commitments_hash = commitments.hash(); + + let candidate_hash = candidate.hash(); + let parent_head_data_hash = Hash::zero(); + + advertise_collation( + &mut virtual_overseer, + peer_a, + head_c, + Some((candidate_hash, parent_head_data_hash)), + ) + .await; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidate_hash); + assert_eq!(request.candidate_para_id, test_state.chain_ids[0]); + assert_eq!(request.parent_head_data_hash, parent_head_data_hash); + tx.send(true).expect("receiving side should be alive"); + } + ); + + let response_channel = assert_fetch_collation_request( + &mut virtual_overseer, + head_c, + test_state.chain_ids[0], + Some(candidate_hash), + ) + .await; + + let pov = PoV { block_data: BlockData(vec![1]) }; + + response_channel + .send(Ok(request_vstaging::CollationFetchingResponse::Collation( + candidate.clone(), + pov.clone(), + ) + .encode())) + .expect("Sending response should succeed"); + + assert_candidate_backing_second( + &mut virtual_overseer, + head_c, + test_state.chain_ids[0], + &pov, + ProspectiveParachainsMode::Enabled { + max_candidate_depth: ASYNC_BACKING_PARAMETERS.max_candidate_depth as _, + allowed_ancestry_len: ASYNC_BACKING_PARAMETERS.allowed_ancestry_len as _, + }, + ) + .await; + + let candidate = + CommittedCandidateReceipt { descriptor: candidate.descriptor, commitments }; + + send_seconded_statement(&mut virtual_overseer, keystore.clone(), &candidate).await; + + assert_collation_seconded(&mut virtual_overseer, head_c, peer_a).await; + } + + // No more advertisements can be made for this relay parent. + let candidate_hash = CandidateHash(Hash::repeat_byte(0xAA)); + advertise_collation( + &mut virtual_overseer, + peer_a, + head_c, + Some((candidate_hash, Hash::zero())), + ) + .await; + + // Reported because reached the limit of advertisements per relay parent. + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer_id, rep)), + ) => { + assert_eq!(peer_a, peer_id); + assert_eq!(rep.value, COST_UNEXPECTED_MESSAGE.cost_or_benefit()); + } + ); + + // By different peer too (not reported). + let pair_b = CollatorPair::generate().0; + let peer_b = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + pair_b.clone(), + test_state.chain_ids[0], + CollationVersion::VStaging, + ) + .await; + + let candidate_hash = CandidateHash(Hash::repeat_byte(0xFF)); + advertise_collation( + &mut virtual_overseer, + peer_b, + head_c, + Some((candidate_hash, Hash::zero())), + ) + .await; + + test_helpers::Yield::new().await; + assert_matches!(virtual_overseer.recv().now_or_never(), None); + + virtual_overseer + }); +} + +#[test] +fn fetched_collation_sanity_check() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair = CollatorPair::generate().0; + + // Grandparent of head `a`. + let head_b = Hash::from_low_u64_be(128); + let head_b_num: u32 = 2; + + // Grandparent of head `b`. + // Group rotation frequency is 1 by default, at `c` we're assigned + // to the first para. + let head_c = Hash::from_low_u64_be(130); + + // Activated leaf is `b`, but the collation will be based on `c`. + update_view(&mut virtual_overseer, &test_state, vec![(head_b, head_b_num)], 1).await; + + let peer_a = PeerId::random(); + + connect_and_declare_collator( + &mut virtual_overseer, + peer_a, + pair.clone(), + test_state.chain_ids[0], + CollationVersion::VStaging, + ) + .await; + + let mut candidate = dummy_candidate_receipt_bad_sig(head_c, Some(Default::default())); + candidate.descriptor.para_id = test_state.chain_ids[0]; + let commitments = CandidateCommitments { + head_data: HeadData(vec![1, 2, 3]), + horizontal_messages: Default::default(), + upward_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0, + }; + candidate.commitments_hash = commitments.hash(); + + let candidate_hash = CandidateHash(Hash::zero()); + let parent_head_data_hash = Hash::zero(); + + advertise_collation( + &mut virtual_overseer, + peer_a, + head_c, + Some((candidate_hash, parent_head_data_hash)), + ) + .await; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidate_hash); + assert_eq!(request.candidate_para_id, test_state.chain_ids[0]); + assert_eq!(request.parent_head_data_hash, parent_head_data_hash); + tx.send(true).expect("receiving side should be alive"); + } + ); + + let response_channel = assert_fetch_collation_request( + &mut virtual_overseer, + head_c, + test_state.chain_ids[0], + Some(candidate_hash), + ) + .await; + + let pov = PoV { block_data: BlockData(vec![1]) }; + + response_channel + .send(Ok(request_vstaging::CollationFetchingResponse::Collation( + candidate.clone(), + pov.clone(), + ) + .encode())) + .expect("Sending response should succeed"); + + // PVD request. + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetProspectiveValidationData(request, tx), + ) => { + assert_eq!(head_c, request.candidate_relay_parent); + assert_eq!(test_state.chain_ids[0], request.para_id); + tx.send(Some(dummy_pvd())).unwrap(); + } + ); + + // Reported malicious. + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer_id, rep)), + ) => { + assert_eq!(peer_a, peer_id); + assert_eq!(rep.value, COST_REPORT_BAD.cost_or_benefit()); + } + ); + + virtual_overseer + }); +} + +#[test] +fn advertisement_spam_protection() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair_a = CollatorPair::generate().0; + + let head_b = Hash::from_low_u64_be(128); + let head_b_num: u32 = 2; + + let head_c = get_parent_hash(head_b); + + // Activated leaf is `b`, but the collation will be based on `c`. + update_view(&mut virtual_overseer, &test_state, vec![(head_b, head_b_num)], 1).await; + + let peer_a = PeerId::random(); + connect_and_declare_collator( + &mut virtual_overseer, + peer_a, + pair_a.clone(), + test_state.chain_ids[1], + CollationVersion::VStaging, + ) + .await; + + let candidate_hash = CandidateHash::default(); + let parent_head_data_hash = Hash::zero(); + advertise_collation( + &mut virtual_overseer, + peer_a, + head_c, + Some((candidate_hash, parent_head_data_hash)), + ) + .await; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidate_hash); + assert_eq!(request.candidate_para_id, test_state.chain_ids[1]); + assert_eq!(request.parent_head_data_hash, parent_head_data_hash); + // Reject it. + tx.send(false).expect("receiving side should be alive"); + } + ); + + // Send the same advertisement again. + advertise_collation( + &mut virtual_overseer, + peer_a, + head_c, + Some((candidate_hash, parent_head_data_hash)), + ) + .await; + // Reported. + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(peer_id, rep)), + ) => { + assert_eq!(peer_a, peer_id); + assert_eq!(rep.value, COST_UNEXPECTED_MESSAGE.cost_or_benefit()); + } + ); + + virtual_overseer + }); +} + +#[test] +fn backed_candidate_unblocks_advertisements() { + let test_state = TestState::default(); + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let pair_a = CollatorPair::generate().0; + let pair_b = CollatorPair::generate().0; + + let head_b = Hash::from_low_u64_be(128); + let head_b_num: u32 = 2; + + let head_c = get_parent_hash(head_b); + // Grandparent of head `b`. + // Group rotation frequency is 1 by default, at `d` we're assigned + // to the first para. + let head_d = get_parent_hash(head_c); + + // Activated leaf is `b`, but the collation will be based on `c`. + update_view(&mut virtual_overseer, &test_state, vec![(head_b, head_b_num)], 1).await; + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + + // Accept both collators from the implicit view. + connect_and_declare_collator( + &mut virtual_overseer, + peer_a, + pair_a.clone(), + test_state.chain_ids[0], + CollationVersion::VStaging, + ) + .await; + connect_and_declare_collator( + &mut virtual_overseer, + peer_b, + pair_b.clone(), + test_state.chain_ids[1], + CollationVersion::VStaging, + ) + .await; + + let candidate_hash = CandidateHash::default(); + let parent_head_data_hash = Hash::zero(); + advertise_collation( + &mut virtual_overseer, + peer_b, + head_c, + Some((candidate_hash, parent_head_data_hash)), + ) + .await; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidate_hash); + assert_eq!(request.candidate_para_id, test_state.chain_ids[1]); + assert_eq!(request.parent_head_data_hash, parent_head_data_hash); + // Reject it. + tx.send(false).expect("receiving side should be alive"); + } + ); + + // Advertise with different para. + advertise_collation( + &mut virtual_overseer, + peer_a, + head_d, // Note different relay parent. + Some((candidate_hash, parent_head_data_hash)), + ) + .await; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidate_hash); + assert_eq!(request.candidate_para_id, test_state.chain_ids[0]); + assert_eq!(request.parent_head_data_hash, parent_head_data_hash); + tx.send(false).expect("receiving side should be alive"); + } + ); + + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::Backed { + para_id: test_state.chain_ids[0], + para_head: parent_head_data_hash, + }, + ) + .await; + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidate_hash); + assert_eq!(request.candidate_para_id, test_state.chain_ids[0]); + assert_eq!(request.parent_head_data_hash, parent_head_data_hash); + tx.send(true).expect("receiving side should be alive"); + } + ); + assert_fetch_collation_request( + &mut virtual_overseer, + head_d, + test_state.chain_ids[0], + Some(candidate_hash), + ) + .await; + virtual_overseer + }); +} + +#[test] +fn active_leave_unblocks_advertisements() { + let mut test_state = TestState::default(); + test_state.group_rotation_info.group_rotation_frequency = 100; + + test_harness(ReputationAggregator::new(|_| true), |test_harness| async move { + let TestHarness { mut virtual_overseer, .. } = test_harness; + + let head_b = Hash::from_low_u64_be(128); + let head_b_num: u32 = 0; + + update_view(&mut virtual_overseer, &test_state, vec![(head_b, head_b_num)], 1).await; + + let peers: Vec = (0..3).map(|_| CollatorPair::generate().0).collect(); + let peer_ids: Vec = (0..3).map(|_| PeerId::random()).collect(); + let candidates: Vec = + (0u8..3).map(|i| CandidateHash(Hash::repeat_byte(i))).collect(); + + for (peer, peer_id) in peers.iter().zip(&peer_ids) { + connect_and_declare_collator( + &mut virtual_overseer, + *peer_id, + peer.clone(), + test_state.chain_ids[0], + CollationVersion::VStaging, + ) + .await; + } + + let parent_head_data_hash = Hash::zero(); + for (peer, candidate) in peer_ids.iter().zip(&candidates).take(2) { + advertise_collation( + &mut virtual_overseer, + *peer, + head_b, + Some((*candidate, parent_head_data_hash)), + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, *candidate); + assert_eq!(request.candidate_para_id, test_state.chain_ids[0]); + assert_eq!(request.parent_head_data_hash, parent_head_data_hash); + // Send false. + tx.send(false).expect("receiving side should be alive"); + } + ); + } + + let head_c = Hash::from_low_u64_be(127); + let head_c_num: u32 = 1; + + let next_overseer_message = + update_view(&mut virtual_overseer, &test_state, vec![(head_c, head_c_num)], 1) + .await + .expect("should've sent request to backing"); + + // Unblock first request. + assert_matches!( + next_overseer_message, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidates[0]); + assert_eq!(request.candidate_para_id, test_state.chain_ids[0]); + assert_eq!(request.parent_head_data_hash, parent_head_data_hash); + tx.send(true).expect("receiving side should be alive"); + } + ); + + assert_fetch_collation_request( + &mut virtual_overseer, + head_b, + test_state.chain_ids[0], + Some(candidates[0]), + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidates[1]); + assert_eq!(request.candidate_para_id, test_state.chain_ids[0]); + assert_eq!(request.parent_head_data_hash, parent_head_data_hash); + tx.send(false).expect("receiving side should be alive"); + } + ); + + // Collation request was discarded. + test_helpers::Yield::new().await; + assert_matches!(virtual_overseer.recv().now_or_never(), None); + + advertise_collation( + &mut virtual_overseer, + peer_ids[2], + head_c, + Some((candidates[2], parent_head_data_hash)), + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidates[2]); + tx.send(false).expect("receiving side should be alive"); + } + ); + + let head_d = Hash::from_low_u64_be(126); + let head_d_num: u32 = 2; + + let next_overseer_message = + update_view(&mut virtual_overseer, &test_state, vec![(head_d, head_d_num)], 1) + .await + .expect("should've sent request to backing"); + + // Reject 2, accept 3. + assert_matches!( + next_overseer_message, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidates[1]); + tx.send(false).expect("receiving side should be alive"); + } + ); + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateBacking( + CandidateBackingMessage::CanSecond(request, tx), + ) => { + assert_eq!(request.candidate_hash, candidates[2]); + tx.send(true).expect("receiving side should be alive"); + } + ); + assert_fetch_collation_request( + &mut virtual_overseer, + head_c, + test_state.chain_ids[0], + Some(candidates[2]), + ) + .await; + + virtual_overseer + }); +} diff --git a/polkadot/node/network/dispute-distribution/Cargo.toml b/polkadot/node/network/dispute-distribution/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..dd2b81cb14587287d517444ca6e2e2dd1e473d46 --- /dev/null +++ b/polkadot/node/network/dispute-distribution/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "polkadot-dispute-distribution" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +futures-timer = "3.0.2" +gum = { package = "tracing-gum", path = "../../gum" } +derive_more = "0.99.17" +parity-scale-codec = { version = "3.6.1", features = ["std"] } +polkadot-primitives = { path = "../../../primitives" } +polkadot-erasure-coding = { path = "../../../erasure-coding" } +polkadot-node-subsystem = {path = "../../subsystem" } +polkadot-node-network-protocol = { path = "../../network/protocol" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-node-primitives = { path = "../../primitives" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +thiserror = "1.0.31" +fatality = "0.0.6" +lru = "0.11.0" +indexmap = "1.9.1" + +[dev-dependencies] +async-channel = "1.8.0" +async-trait = "0.1.57" +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures-timer = "3.0.2" +assert_matches = "1.4.0" +lazy_static = "1.4.0" +polkadot-primitives-test-helpers = { path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/network/dispute-distribution/src/error.rs b/polkadot/node/network/dispute-distribution/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..a2fdae96ef01600b7f752360af2355f63a38219f --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/error.rs @@ -0,0 +1,72 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +// + +//! Error handling related code and Error/Result definitions. + +use polkadot_node_subsystem::SubsystemError; +use polkadot_node_subsystem_util::runtime; + +use crate::{sender, LOG_TARGET}; + +use fatality::Nested; + +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + /// Receiving subsystem message from overseer failed. + #[fatal] + #[error("Receiving message from overseer failed")] + SubsystemReceive(#[source] SubsystemError), + + /// Spawning a running task failed. + #[fatal] + #[error("Spawning subsystem task failed")] + SpawnTask(#[source] SubsystemError), + + /// `DisputeSender` mpsc receiver exhausted. + #[fatal] + #[error("Erasure chunk requester stream exhausted")] + SenderExhausted, + + /// Errors coming from `runtime::Runtime`. + #[fatal(forward)] + #[error("Error while accessing runtime information")] + Runtime(#[from] runtime::Error), + + /// Errors coming from `DisputeSender` + #[fatal(forward)] + #[error("Error while accessing runtime information")] + Sender(#[from] sender::Error), +} + +pub type Result = std::result::Result; + +pub type FatalResult = std::result::Result; + +/// Utility for eating top level errors and log them. +/// +/// We basically always want to try and continue on error. This utility function is meant to +/// consume top-level errors by simply logging them +pub fn log_error(result: Result<()>, ctx: &'static str) -> std::result::Result<(), FatalError> { + match result.into_nested()? { + Err(jfyi) => { + gum::warn!(target: LOG_TARGET, error = ?jfyi, ctx); + Ok(()) + }, + Ok(()) => Ok(()), + } +} diff --git a/polkadot/node/network/dispute-distribution/src/lib.rs b/polkadot/node/network/dispute-distribution/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..ad99bc41fa64d772b29f149e3c8de32834692395 --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/lib.rs @@ -0,0 +1,298 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! # Sending and receiving of `DisputeRequest`s. +//! +//! This subsystem essentially consists of two parts: +//! +//! - a sender +//! - and a receiver +//! +//! The sender is responsible for getting our vote out, see [`sender`]. The receiver handles +//! incoming [`DisputeRequest`]s and offers spam protection, see [`receiver`]. + +use std::{num::NonZeroUsize, time::Duration}; + +use futures::{channel::mpsc, FutureExt, StreamExt, TryFutureExt}; + +use polkadot_node_network_protocol::authority_discovery::AuthorityDiscovery; +use polkadot_node_subsystem_util::nesting_sender::NestingSender; +use sp_keystore::KeystorePtr; + +use polkadot_node_network_protocol::request_response::{incoming::IncomingRequestReceiver, v1}; +use polkadot_node_primitives::DISPUTE_WINDOW; +use polkadot_node_subsystem::{ + messages::DisputeDistributionMessage, overseer, FromOrchestra, OverseerSignal, + SpawnedSubsystem, SubsystemError, +}; +use polkadot_node_subsystem_util::{runtime, runtime::RuntimeInfo}; + +/// ## The sender [`DisputeSender`] +/// +/// The sender (`DisputeSender`) keeps track of live disputes and makes sure our vote gets out for +/// each one of those. The sender is responsible for sending our vote to each validator +/// participating in the dispute and to each authority currently authoring blocks. The sending can +/// be initiated by sending `DisputeDistributionMessage::SendDispute` message to this subsystem. +/// +/// In addition the `DisputeSender` will query the coordinator for active disputes on each +/// [`DisputeSender::update_leaves`] call and will initiate sending (start a `SendTask`) for every, +/// to this subsystem, unknown dispute. This is to make sure, we get our vote out, even on +/// restarts. +/// +/// The actual work of sending and keeping track of transmission attempts to each validator for a +/// particular dispute are done by [`SendTask`]. The purpose of the `DisputeSender` is to keep +/// track of all ongoing disputes and start and clean up `SendTask`s accordingly. +mod sender; +use self::sender::{DisputeSender, DisputeSenderMessage}; + +/// ## The receiver [`DisputesReceiver`] +/// +/// The receiving side is implemented as `DisputesReceiver` and is run as a separate long running +/// task within this subsystem ([`DisputesReceiver::run`]). +/// +/// Conceptually all the receiver has to do, is waiting for incoming requests which are passed in +/// via a dedicated channel and forwarding them to the dispute coordinator via +/// `DisputeCoordinatorMessage::ImportStatements`. Being the interface to the network and untrusted +/// nodes, the reality is not that simple of course. Before importing statements the receiver will +/// batch up imports as well as possible for efficient imports while maintaining timely dispute +/// resolution and handling of spamming validators: +/// +/// - Drop all messages from non validator nodes, for this it requires the [`AuthorityDiscovery`] +/// service. +/// - Drop messages from a node, if it sends at a too high rate. +/// - Filter out duplicate messages (over some period of time). +/// - Drop any obviously invalid votes (invalid signatures for example). +/// - Ban peers whose votes were deemed invalid. +/// +/// In general dispute-distribution works on limiting the work the dispute-coordinator will have to +/// do, while at the same time making it aware of new disputes as fast as possible. +/// +/// For successfully imported votes, we will confirm the receipt of the message back to the sender. +/// This way a received confirmation guarantees, that the vote has been stored to disk by the +/// receiver. +mod receiver; +use self::receiver::DisputesReceiver; + +/// Error and [`Result`] type for this subsystem. +mod error; +use error::{log_error, Error, FatalError, FatalResult, Result}; + +#[cfg(test)] +mod tests; + +mod metrics; +//// Prometheus `Metrics` for dispute distribution. +pub use metrics::Metrics; + +const LOG_TARGET: &'static str = "parachain::dispute-distribution"; + +/// Rate limit on the `receiver` side. +/// +/// If messages from one peer come in at a higher rate than every `RECEIVE_RATE_LIMIT` on average, +/// we start dropping messages from that peer to enforce that limit. +pub const RECEIVE_RATE_LIMIT: Duration = Duration::from_millis(100); + +/// Rate limit on the `sender` side. +/// +/// In order to not hit the `RECEIVE_RATE_LIMIT` on the receiving side, we limit out sending rate as +/// well. +/// +/// We add 50ms extra, just to have some save margin to the `RECEIVE_RATE_LIMIT`. +pub const SEND_RATE_LIMIT: Duration = RECEIVE_RATE_LIMIT.saturating_add(Duration::from_millis(50)); + +/// The dispute distribution subsystem. +pub struct DisputeDistributionSubsystem { + /// Easy and efficient runtime access for this subsystem. + runtime: RuntimeInfo, + + /// Sender for our dispute requests. + disputes_sender: DisputeSender, + + /// Receive messages from `DisputeSender` background tasks. + sender_rx: mpsc::Receiver, + + /// Receiver for incoming requests. + req_receiver: Option>, + + /// Authority discovery service. + authority_discovery: AD, + + /// Metrics for this subsystem. + metrics: Metrics, +} + +#[overseer::subsystem(DisputeDistribution, error = SubsystemError, prefix = self::overseer)] +impl DisputeDistributionSubsystem +where + ::Sender: + overseer::DisputeDistributionSenderTrait + Sync + Send, + AD: AuthorityDiscovery + Clone, +{ + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = self + .run(ctx) + .map_err(|e| SubsystemError::with_origin("dispute-distribution", e)) + .boxed(); + + SpawnedSubsystem { name: "dispute-distribution-subsystem", future } + } +} + +#[overseer::contextbounds(DisputeDistribution, prefix = self::overseer)] +impl DisputeDistributionSubsystem +where + AD: AuthorityDiscovery + Clone, +{ + /// Create a new instance of the dispute distribution. + pub fn new( + keystore: KeystorePtr, + req_receiver: IncomingRequestReceiver, + authority_discovery: AD, + metrics: Metrics, + ) -> Self { + let runtime = RuntimeInfo::new_with_config(runtime::Config { + keystore: Some(keystore), + session_cache_lru_size: NonZeroUsize::new(DISPUTE_WINDOW.get() as usize) + .expect("Dispute window can not be 0; qed"), + }); + let (tx, sender_rx) = NestingSender::new_root(1); + let disputes_sender = DisputeSender::new(tx, metrics.clone()); + Self { + runtime, + disputes_sender, + sender_rx, + req_receiver: Some(req_receiver), + authority_discovery, + metrics, + } + } + + /// Start processing work as passed on from the Overseer. + async fn run(mut self, mut ctx: Context) -> std::result::Result<(), FatalError> { + let receiver = DisputesReceiver::new( + ctx.sender().clone(), + self.req_receiver + .take() + .expect("Must be provided on `new` and we take ownership here. qed."), + self.authority_discovery.clone(), + self.metrics.clone(), + ); + ctx.spawn("disputes-receiver", receiver.run().boxed()) + .map_err(FatalError::SpawnTask)?; + + // Process messages for sending side. + // + // Note: We want the sender to be rate limited and we are currently taking advantage of the + // fact that the root task of this subsystem is only concerned with sending: Functions of + // `DisputeSender` might back pressure if the rate limit is hit, which will slow down this + // loop. If this fact ever changes, we will likely need another task. + loop { + let message = MuxedMessage::receive(&mut ctx, &mut self.sender_rx).await; + match message { + MuxedMessage::Subsystem(result) => { + let result = match result? { + FromOrchestra::Signal(signal) => { + match self.handle_signals(&mut ctx, signal).await { + Ok(SignalResult::Conclude) => return Ok(()), + Ok(SignalResult::Continue) => Ok(()), + Err(f) => Err(f), + } + }, + FromOrchestra::Communication { msg } => + self.handle_subsystem_message(&mut ctx, msg).await, + }; + log_error(result, "on FromOrchestra")?; + }, + MuxedMessage::Sender(result) => { + let result = self + .disputes_sender + .on_message( + &mut ctx, + &mut self.runtime, + result.ok_or(FatalError::SenderExhausted)?, + ) + .await + .map_err(Error::Sender); + log_error(result, "on_message")?; + }, + } + } + } + + /// Handle overseer signals. + async fn handle_signals( + &mut self, + ctx: &mut Context, + signal: OverseerSignal, + ) -> Result { + match signal { + OverseerSignal::Conclude => return Ok(SignalResult::Conclude), + OverseerSignal::ActiveLeaves(update) => { + self.disputes_sender.update_leaves(ctx, &mut self.runtime, update).await?; + }, + OverseerSignal::BlockFinalized(_, _) => {}, + }; + Ok(SignalResult::Continue) + } + + /// Handle `DisputeDistributionMessage`s. + async fn handle_subsystem_message( + &mut self, + ctx: &mut Context, + msg: DisputeDistributionMessage, + ) -> Result<()> { + match msg { + DisputeDistributionMessage::SendDispute(dispute_msg) => + self.disputes_sender.start_sender(ctx, &mut self.runtime, dispute_msg).await?, + } + Ok(()) + } +} + +/// Messages to be handled in this subsystem. +#[derive(Debug)] +enum MuxedMessage { + /// Messages from other subsystems. + Subsystem(FatalResult>), + /// Messages from spawned sender background tasks. + Sender(Option), +} + +#[overseer::contextbounds(DisputeDistribution, prefix = self::overseer)] +impl MuxedMessage { + async fn receive( + ctx: &mut Context, + from_sender: &mut mpsc::Receiver, + ) -> Self { + // We are only fusing here to make `select` happy, in reality we will quit if the stream + // ends. + let from_overseer = ctx.recv().fuse(); + futures::pin_mut!(from_overseer, from_sender); + // We select biased to make sure we finish up loose ends, before starting new work. + futures::select_biased!( + msg = from_sender.next() => MuxedMessage::Sender(msg), + msg = from_overseer => MuxedMessage::Subsystem(msg.map_err(FatalError::SubsystemReceive)), + ) + } +} + +/// Result of handling signal from overseer. +enum SignalResult { + /// Overseer asked us to conclude. + Conclude, + /// We can continue processing events. + Continue, +} diff --git a/polkadot/node/network/dispute-distribution/src/metrics.rs b/polkadot/node/network/dispute-distribution/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..3c04758b8bab2fdba9c13f3cda81b4d64da0089a --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/metrics.rs @@ -0,0 +1,130 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::{ + metrics, + metrics::{ + prometheus, + prometheus::{Counter, CounterVec, Opts, PrometheusError, Registry, U64}, + }, +}; + +/// Label for success counters. +pub const SUCCEEDED: &'static str = "succeeded"; + +/// Label for fail counters. +pub const FAILED: &'static str = "failed"; + +/// Dispute Distribution metrics. +#[derive(Clone, Default)] +pub struct Metrics(Option); + +#[derive(Clone)] +struct MetricsInner { + /// Number of sent dispute requests (succeeded and failed). + sent_requests: CounterVec, + + /// Number of requests received. + /// + /// This is all requests coming in, regardless of whether they are processed or dropped. + received_requests: Counter, + + /// Number of requests for which `ImportStatements` returned. + /// + /// We both have successful imports and failed imports here. + imported_requests: CounterVec, + + /// The duration of issued dispute request to response. + time_dispute_request: prometheus::Histogram, +} + +impl Metrics { + /// Create new dummy metrics, not reporting anything. + pub fn new_dummy() -> Self { + Metrics(None) + } + + /// Increment counter on finished request sending. + pub fn on_sent_request(&self, label: &'static str) { + if let Some(metrics) = &self.0 { + metrics.sent_requests.with_label_values(&[label]).inc() + } + } + + /// Increment counter on served disputes. + pub fn on_received_request(&self) { + if let Some(metrics) = &self.0 { + metrics.received_requests.inc() + } + } + + /// Statements have been imported. + pub fn on_imported(&self, label: &'static str, num_requests: usize) { + if let Some(metrics) = &self.0 { + metrics + .imported_requests + .with_label_values(&[label]) + .inc_by(num_requests as u64) + } + } + + /// Get a timer to time request/response duration. + pub fn time_dispute_request(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.time_dispute_request.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &Registry) -> Result { + let metrics = MetricsInner { + sent_requests: prometheus::register( + CounterVec::new( + Opts::new( + "polkadot_parachain_dispute_distribution_sent_requests", + "Total number of sent requests.", + ), + &["success"], + )?, + registry, + )?, + received_requests: prometheus::register( + Counter::new( + "polkadot_parachain_dispute_distribution_received_requests", + "Total number of received dispute requests.", + )?, + registry, + )?, + imported_requests: prometheus::register( + CounterVec::new( + Opts::new( + "polkadot_parachain_dispute_distribution_imported_requests", + "Total number of imported requests.", + ), + &["success"], + )?, + registry, + )?, + time_dispute_request: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_dispute_distribution_time_dispute_request", + "Time needed for dispute votes to get confirmed/fail getting transmitted.", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/network/dispute-distribution/src/receiver/batches/batch.rs b/polkadot/node/network/dispute-distribution/src/receiver/batches/batch.rs new file mode 100644 index 0000000000000000000000000000000000000000..11380b7c072ee75b2a48e21bc20ed33abeee2365 --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/receiver/batches/batch.rs @@ -0,0 +1,209 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{collections::HashMap, time::Instant}; + +use gum::CandidateHash; +use polkadot_node_network_protocol::{ + request_response::{incoming::OutgoingResponseSender, v1::DisputeRequest}, + PeerId, +}; +use polkadot_node_primitives::SignedDisputeStatement; +use polkadot_primitives::{CandidateReceipt, ValidatorIndex}; + +use crate::receiver::{BATCH_COLLECTING_INTERVAL, MIN_KEEP_BATCH_ALIVE_VOTES}; + +use super::MAX_BATCH_LIFETIME; + +/// A batch of votes to be imported into the `dispute-coordinator`. +/// +/// Vote imports are way more efficient when performed in batches, hence we batch together incoming +/// votes until the rate of incoming votes falls below a threshold, then we import into the dispute +/// coordinator. +/// +/// A `Batch` keeps track of the votes to be imported and the current incoming rate, on rate update +/// it will "flush" in case the incoming rate dropped too low, preparing the import. +pub struct Batch { + /// The actual candidate this batch is concerned with. + candidate_receipt: CandidateReceipt, + + /// Cache of `CandidateHash` (candidate_receipt.hash()). + candidate_hash: CandidateHash, + + /// All valid votes received in this batch so far. + /// + /// We differentiate between valid and invalid votes, so we can detect (and drop) duplicates, + /// while still allowing validators to equivocate. + /// + /// Detecting and rejecting duplicates is crucial in order to effectively enforce + /// `MIN_KEEP_BATCH_ALIVE_VOTES` per `BATCH_COLLECTING_INTERVAL`. If we would count duplicates + /// here, the mechanism would be broken. + valid_votes: HashMap, + + /// All invalid votes received in this batch so far. + invalid_votes: HashMap, + + /// How many votes have been batched since the last tick/creation. + votes_batched_since_last_tick: u32, + + /// Expiry time for the batch. + /// + /// By this time the latest this batch will get flushed. + best_before: Instant, + + /// Requesters waiting for a response. + requesters: Vec<(PeerId, OutgoingResponseSender)>, +} + +/// Result of checking a batch every `BATCH_COLLECTING_INTERVAL`. +pub(super) enum TickResult { + /// Batch is still alive, please call `tick` again at the given `Instant`. + Alive(Batch, Instant), + /// Batch is done, ready for import! + Done(PreparedImport), +} + +/// Ready for import. +pub struct PreparedImport { + pub candidate_receipt: CandidateReceipt, + pub statements: Vec<(SignedDisputeStatement, ValidatorIndex)>, + /// Information about original requesters. + pub requesters: Vec<(PeerId, OutgoingResponseSender)>, +} + +impl From for PreparedImport { + fn from(batch: Batch) -> Self { + let Batch { + candidate_receipt, + valid_votes, + invalid_votes, + requesters: pending_responses, + .. + } = batch; + + let statements = valid_votes + .into_iter() + .chain(invalid_votes.into_iter()) + .map(|(index, statement)| (statement, index)) + .collect(); + + Self { candidate_receipt, statements, requesters: pending_responses } + } +} + +impl Batch { + /// Create a new empty batch based on the given `CandidateReceipt`. + /// + /// To create a `Batch` use Batches::find_batch`. + /// + /// Arguments: + /// + /// * `candidate_receipt` - The candidate this batch is meant to track votes for. + /// * `now` - current time stamp for calculating the first tick. + /// + /// Returns: A batch and the first `Instant` you are supposed to call `tick`. + pub(super) fn new(candidate_receipt: CandidateReceipt, now: Instant) -> (Self, Instant) { + let s = Self { + candidate_hash: candidate_receipt.hash(), + candidate_receipt, + valid_votes: HashMap::new(), + invalid_votes: HashMap::new(), + votes_batched_since_last_tick: 0, + best_before: Instant::now() + MAX_BATCH_LIFETIME, + requesters: Vec::new(), + }; + let next_tick = s.calculate_next_tick(now); + (s, next_tick) + } + + /// Receipt of the candidate this batch is batching votes for. + pub fn candidate_receipt(&self) -> &CandidateReceipt { + &self.candidate_receipt + } + + /// Add votes from a validator into the batch. + /// + /// The statements are supposed to be the valid and invalid statements received in a + /// `DisputeRequest`. + /// + /// The given `pending_response` is the corresponding response sender for responding to `peer`. + /// If at least one of the votes is new as far as this batch is concerned we record the + /// pending_response, for later use. In case both votes are known already, we return the + /// response sender as an `Err` value. + pub fn add_votes( + &mut self, + valid_vote: (SignedDisputeStatement, ValidatorIndex), + invalid_vote: (SignedDisputeStatement, ValidatorIndex), + peer: PeerId, + pending_response: OutgoingResponseSender, + ) -> Result<(), OutgoingResponseSender> { + debug_assert!(valid_vote.0.candidate_hash() == invalid_vote.0.candidate_hash()); + debug_assert!(valid_vote.0.candidate_hash() == &self.candidate_hash); + + let mut duplicate = true; + + if self.valid_votes.insert(valid_vote.1, valid_vote.0).is_none() { + self.votes_batched_since_last_tick += 1; + duplicate = false; + } + if self.invalid_votes.insert(invalid_vote.1, invalid_vote.0).is_none() { + self.votes_batched_since_last_tick += 1; + duplicate = false; + } + + if duplicate { + Err(pending_response) + } else { + self.requesters.push((peer, pending_response)); + Ok(()) + } + } + + /// Check batch for liveness. + /// + /// This function is supposed to be called at instants given at construction and as returned as + /// part of `TickResult`. + pub(super) fn tick(mut self, now: Instant) -> TickResult { + if self.votes_batched_since_last_tick >= MIN_KEEP_BATCH_ALIVE_VOTES && + now < self.best_before + { + // Still good: + let next_tick = self.calculate_next_tick(now); + // Reset counter: + self.votes_batched_since_last_tick = 0; + TickResult::Alive(self, next_tick) + } else { + TickResult::Done(PreparedImport::from(self)) + } + } + + /// Calculate when the next tick should happen. + /// + /// This will usually return `now + BATCH_COLLECTING_INTERVAL`, except if the lifetime of this + /// batch would exceed `MAX_BATCH_LIFETIME`. + /// + /// # Arguments + /// + /// * `now` - The current time. + fn calculate_next_tick(&self, now: Instant) -> Instant { + let next_tick = now + BATCH_COLLECTING_INTERVAL; + if next_tick < self.best_before { + next_tick + } else { + self.best_before + } + } +} diff --git a/polkadot/node/network/dispute-distribution/src/receiver/batches/mod.rs b/polkadot/node/network/dispute-distribution/src/receiver/batches/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..76c7683d1574ac3c1631e77b5afe6ce8a6113532 --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/receiver/batches/mod.rs @@ -0,0 +1,170 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{ + collections::{hash_map, HashMap}, + time::{Duration, Instant}, +}; + +use futures::future::pending; + +use polkadot_node_network_protocol::request_response::DISPUTE_REQUEST_TIMEOUT; +use polkadot_primitives::{CandidateHash, CandidateReceipt}; + +use crate::{ + receiver::batches::{batch::TickResult, waiting_queue::PendingWake}, + LOG_TARGET, +}; + +pub use self::batch::{Batch, PreparedImport}; +use self::waiting_queue::WaitingQueue; + +use super::{ + error::{JfyiError, JfyiResult}, + BATCH_COLLECTING_INTERVAL, +}; + +/// A single batch (per candidate) as managed by `Batches`. +mod batch; + +/// Queue events in time and wait for them to become ready. +mod waiting_queue; + +/// Safe-guard in case votes trickle in real slow. +/// +/// If the batch life time exceeded the time the sender is willing to wait for a confirmation, we +/// would trigger pointless re-sends. +const MAX_BATCH_LIFETIME: Duration = DISPUTE_REQUEST_TIMEOUT.saturating_sub(Duration::from_secs(2)); + +/// Limit the number of batches that can be alive at any given time. +/// +/// Reasoning for this number, see guide. +pub const MAX_BATCHES: usize = 1000; + +/// Manage batches. +/// +/// - Batches can be found via `find_batch()` in order to add votes to them/check they exist. +/// - Batches can be checked for being ready for flushing in order to import contained votes. +pub struct Batches { + /// The batches we manage. + /// + /// Kept invariants: + /// For each entry in `batches`, there exists an entry in `waiting_queue` as well - we wait on + /// all batches! + batches: HashMap, + /// Waiting queue for waiting for batches to become ready for `tick`. + /// + /// Kept invariants by `Batches`: + /// For each entry in the `waiting_queue` there exists a corresponding entry in `batches`. + waiting_queue: WaitingQueue, +} + +/// A found batch is either really found or got created so it can be found. +pub enum FoundBatch<'a> { + /// Batch just got created. + Created(&'a mut Batch), + /// Batch already existed. + Found(&'a mut Batch), +} + +impl Batches { + /// Create new empty `Batches`. + pub fn new() -> Self { + debug_assert!( + MAX_BATCH_LIFETIME > BATCH_COLLECTING_INTERVAL, + "Unexpectedly low `MAX_BATCH_LIFETIME`, please check parameters." + ); + Self { batches: HashMap::new(), waiting_queue: WaitingQueue::new() } + } + + /// Find a particular batch. + /// + /// That is either find it, or we create it as reflected by the result `FoundBatch`. + pub fn find_batch( + &mut self, + candidate_hash: CandidateHash, + candidate_receipt: CandidateReceipt, + ) -> JfyiResult { + if self.batches.len() >= MAX_BATCHES { + return Err(JfyiError::MaxBatchLimitReached) + } + debug_assert!(candidate_hash == candidate_receipt.hash()); + let result = match self.batches.entry(candidate_hash) { + hash_map::Entry::Vacant(vacant) => { + let now = Instant::now(); + let (created, ready_at) = Batch::new(candidate_receipt, now); + let pending_wake = PendingWake { payload: candidate_hash, ready_at }; + self.waiting_queue.push(pending_wake); + FoundBatch::Created(vacant.insert(created)) + }, + hash_map::Entry::Occupied(occupied) => FoundBatch::Found(occupied.into_mut()), + }; + Ok(result) + } + + /// Wait for the next `tick` to check for ready batches. + /// + /// This function blocks (returns `Poll::Pending`) until at least one batch can be + /// checked for readiness meaning that `BATCH_COLLECTING_INTERVAL` has passed since the last + /// check for that batch or it reached end of life. + /// + /// If this `Batches` instance is empty (does not actually contain any batches), then this + /// function will always return `Poll::Pending`. + /// + /// Returns: A `Vec` of all `PreparedImport`s from batches that became ready. + pub async fn check_batches(&mut self) -> Vec { + let now = Instant::now(); + + let mut imports = Vec::new(); + + // Wait for at least one batch to become ready: + self.waiting_queue.wait_ready(now).await; + + // Process all ready entries: + while let Some(wake) = self.waiting_queue.pop_ready(now) { + let batch = self.batches.remove(&wake.payload); + debug_assert!( + batch.is_some(), + "Entries referenced in `waiting_queue` are supposed to exist!" + ); + let batch = match batch { + None => return pending().await, + Some(batch) => batch, + }; + match batch.tick(now) { + TickResult::Done(import) => { + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?wake.payload, + "Batch became ready." + ); + imports.push(import); + }, + TickResult::Alive(old_batch, next_tick) => { + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?wake.payload, + "Batch found to be still alive on check." + ); + let pending_wake = PendingWake { payload: wake.payload, ready_at: next_tick }; + self.waiting_queue.push(pending_wake); + self.batches.insert(wake.payload, old_batch); + }, + } + } + imports + } +} diff --git a/polkadot/node/network/dispute-distribution/src/receiver/batches/waiting_queue.rs b/polkadot/node/network/dispute-distribution/src/receiver/batches/waiting_queue.rs new file mode 100644 index 0000000000000000000000000000000000000000..9a5e665a5756046d070338ef3874f91bb7c34f59 --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/receiver/batches/waiting_queue.rs @@ -0,0 +1,204 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{cmp::Ordering, collections::BinaryHeap, time::Instant}; + +use futures::future::pending; +use futures_timer::Delay; + +/// Wait asynchronously for given `Instant`s one after the other. +/// +/// `PendingWake`s can be inserted and `WaitingQueue` makes `wait_ready()` to always wait for the +/// next `Instant` in the queue. +pub struct WaitingQueue { + /// All pending wakes we are supposed to wait on in order. + pending_wakes: BinaryHeap>, + /// Wait for next `PendingWake`. + timer: Option, +} + +/// Represents some event waiting to be processed at `ready_at`. +/// +/// This is an event in `WaitingQueue`. It provides an `Ord` instance, that sorts descending with +/// regard to `Instant` (so we get a `min-heap` with the earliest `Instant` at the top). +#[derive(Eq, PartialEq)] +pub struct PendingWake { + pub payload: Payload, + pub ready_at: Instant, +} + +impl WaitingQueue { + /// Get a new empty `WaitingQueue`. + /// + /// If you call `pop` on this queue immediately, it will always return `Poll::Pending`. + pub fn new() -> Self { + Self { pending_wakes: BinaryHeap::new(), timer: None } + } + + /// Push a `PendingWake`. + /// + /// The next call to `wait_ready` will make sure to wake soon enough to process that new event + /// in a timely manner. + pub fn push(&mut self, wake: PendingWake) { + self.pending_wakes.push(wake); + // Reset timer as it is potentially obsolete now: + self.timer = None; + } + + /// Pop the next ready item. + /// + /// This function does not wait, if nothing is ready right now as determined by the passed + /// `now` time stamp, this function simply returns `None`. + pub fn pop_ready(&mut self, now: Instant) -> Option> { + let is_ready = self.pending_wakes.peek().map_or(false, |p| p.ready_at <= now); + if is_ready { + Some(self.pending_wakes.pop().expect("We just peeked. qed.")) + } else { + None + } + } + + /// Don't pop, just wait until something is ready. + /// + /// Once this function returns `Poll::Ready(())` `pop_ready()` will return `Some`, if passed + /// the same `Instant`. + /// + /// Whether ready or not is determined based on the passed time stamp `now` which should be the + /// current time as returned by `Instant::now()` + /// + /// This function waits asynchronously for an item to become ready. If there is no more item, + /// this call will wait forever (return Poll::Pending without scheduling a wake). + pub async fn wait_ready(&mut self, now: Instant) { + if let Some(timer) = &mut self.timer { + // Previous timer was not done yet. + timer.await + } + + let next_waiting = self.pending_wakes.peek(); + let is_ready = next_waiting.map_or(false, |p| p.ready_at <= now); + if is_ready { + return + } + + self.timer = next_waiting.map(|p| Delay::new(p.ready_at.duration_since(now))); + match &mut self.timer { + None => return pending().await, + Some(timer) => timer.await, + } + } +} + +impl PartialOrd> for PendingWake { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for PendingWake { + fn cmp(&self, other: &Self) -> Ordering { + // Reverse order for min-heap: + match other.ready_at.cmp(&self.ready_at) { + Ordering::Equal => other.payload.cmp(&self.payload), + o => o, + } + } +} +#[cfg(test)] +mod tests { + use std::{ + task::Poll, + time::{Duration, Instant}, + }; + + use assert_matches::assert_matches; + use futures::{future::poll_fn, pin_mut, Future}; + + use crate::LOG_TARGET; + + use super::{PendingWake, WaitingQueue}; + + #[test] + fn wait_ready_waits_for_earliest_event_always() { + sp_tracing::try_init_simple(); + let mut queue = WaitingQueue::new(); + let now = Instant::now(); + let start = now; + queue.push(PendingWake { payload: 1u32, ready_at: now + Duration::from_millis(3) }); + // Push another one in order: + queue.push(PendingWake { payload: 2u32, ready_at: now + Duration::from_millis(5) }); + // Push one out of order: + queue.push(PendingWake { payload: 0u32, ready_at: now + Duration::from_millis(1) }); + // Push another one at same timestamp (should become ready at the same time) + queue.push(PendingWake { payload: 10u32, ready_at: now + Duration::from_millis(1) }); + + futures::executor::block_on(async move { + // No time passed yet - nothing should be ready. + assert!(queue.pop_ready(now).is_none(), "No time has passed, nothing should be ready"); + + // Receive them in order at expected times: + queue.wait_ready(now).await; + gum::trace!(target: LOG_TARGET, "After first wait."); + + let now = start + Duration::from_millis(1); + assert!(Instant::now() - start >= Duration::from_millis(1)); + assert_eq!(queue.pop_ready(now).map(|p| p.payload), Some(0u32)); + // One more should be ready: + assert_eq!(queue.pop_ready(now).map(|p| p.payload), Some(10u32)); + assert!(queue.pop_ready(now).is_none(), "No more entry expected to be ready."); + + queue.wait_ready(now).await; + gum::trace!(target: LOG_TARGET, "After second wait."); + let now = start + Duration::from_millis(3); + assert!(Instant::now() - start >= Duration::from_millis(3)); + assert_eq!(queue.pop_ready(now).map(|p| p.payload), Some(1u32)); + assert!(queue.pop_ready(now).is_none(), "No more entry expected to be ready."); + + // Push in between wait: + poll_fn(|cx| { + let fut = queue.wait_ready(now); + pin_mut!(fut); + assert_matches!(fut.poll(cx), Poll::Pending); + Poll::Ready(()) + }) + .await; + queue.push(PendingWake { payload: 3u32, ready_at: start + Duration::from_millis(4) }); + + queue.wait_ready(now).await; + // Newly pushed element should have become ready: + gum::trace!(target: LOG_TARGET, "After third wait."); + let now = start + Duration::from_millis(4); + assert!(Instant::now() - start >= Duration::from_millis(4)); + assert_eq!(queue.pop_ready(now).map(|p| p.payload), Some(3u32)); + assert!(queue.pop_ready(now).is_none(), "No more entry expected to be ready."); + + queue.wait_ready(now).await; + gum::trace!(target: LOG_TARGET, "After fourth wait."); + let now = start + Duration::from_millis(5); + assert!(Instant::now() - start >= Duration::from_millis(5)); + assert_eq!(queue.pop_ready(now).map(|p| p.payload), Some(2u32)); + assert!(queue.pop_ready(now).is_none(), "No more entry expected to be ready."); + + // queue empty - should wait forever now: + poll_fn(|cx| { + let fut = queue.wait_ready(now); + pin_mut!(fut); + assert_matches!(fut.poll(cx), Poll::Pending); + Poll::Ready(()) + }) + .await; + }); + } +} diff --git a/polkadot/node/network/dispute-distribution/src/receiver/error.rs b/polkadot/node/network/dispute-distribution/src/receiver/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..f1f27ea275a6a5325e4b010a437498e64ed6bf51 --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/receiver/error.rs @@ -0,0 +1,97 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +// + +//! Error handling related code and Error/Result definitions. + +use fatality::Nested; + +use gum::CandidateHash; +use polkadot_node_network_protocol::{request_response::incoming, PeerId}; +use polkadot_node_subsystem_util::runtime; +use polkadot_primitives::AuthorityDiscoveryId; + +use crate::LOG_TARGET; + +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + #[fatal(forward)] + #[error("Error while accessing runtime information")] + Runtime(#[from] runtime::Error), + + #[fatal(forward)] + #[error("Retrieving next incoming request failed.")] + IncomingRequest(#[from] incoming::Error), + + #[error("Sending back response to peers {0:#?} failed.")] + SendResponses(Vec), + + #[error("Changing peer's ({0}) reputation failed.")] + SetPeerReputation(PeerId), + + #[error("Dispute request with invalid signatures, from peer {0}.")] + InvalidSignature(PeerId), + + #[error("Received votes from peer {0} have been completely redundant.")] + RedundantMessage(PeerId), + + #[error("Import of dispute got canceled for candidate {0} - import failed for some reason.")] + ImportCanceled(CandidateHash), + + #[error("Peer {0} attempted to participate in dispute and is not a validator.")] + NotAValidator(PeerId), + + #[error("Force flush for batch that could not be found attempted, candidate hash: {0}")] + ForceFlushBatchDoesNotExist(CandidateHash), + + // Should never happen in practice: + #[error("We needed to drop messages, because we reached limit on concurrent batches.")] + MaxBatchLimitReached, + + #[error("Authority {0} sent messages at a too high rate.")] + AuthorityFlooding(AuthorityDiscoveryId), +} + +pub type Result = std::result::Result; + +pub type JfyiResult = std::result::Result; + +/// Utility for eating top level errors and log them. +/// +/// We basically always want to try and continue on error. This utility function is meant to +/// consume top-level errors by simply logging them. +pub fn log_error(result: Result<()>) -> std::result::Result<(), FatalError> { + match result.into_nested()? { + Err(error @ JfyiError::ImportCanceled(_)) => { + gum::debug!(target: LOG_TARGET, error = ?error); + Ok(()) + }, + Err(JfyiError::NotAValidator(peer)) => { + gum::debug!( + target: LOG_TARGET, + ?peer, + "Dropping message from peer (unknown authority id)" + ); + Ok(()) + }, + Err(error) => { + gum::warn!(target: LOG_TARGET, error = ?error); + Ok(()) + }, + Ok(()) => Ok(()), + } +} diff --git a/polkadot/node/network/dispute-distribution/src/receiver/mod.rs b/polkadot/node/network/dispute-distribution/src/receiver/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..827a77281ccb3c78b36429370df801bdfcf160e2 --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/receiver/mod.rs @@ -0,0 +1,527 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{ + num::NonZeroUsize, + pin::Pin, + task::{Context, Poll}, + time::Duration, +}; + +use futures::{ + channel::oneshot, + future::poll_fn, + pin_mut, + stream::{FuturesUnordered, StreamExt}, + Future, +}; + +use gum::CandidateHash; +use polkadot_node_network_protocol::{ + authority_discovery::AuthorityDiscovery, + request_response::{ + incoming::{self, OutgoingResponse, OutgoingResponseSender}, + v1::{DisputeRequest, DisputeResponse}, + IncomingRequest, IncomingRequestReceiver, + }, + PeerId, UnifiedReputationChange as Rep, +}; +use polkadot_node_primitives::DISPUTE_WINDOW; +use polkadot_node_subsystem::{ + messages::{DisputeCoordinatorMessage, ImportStatementsResult}, + overseer, +}; +use polkadot_node_subsystem_util::{runtime, runtime::RuntimeInfo}; + +use crate::{ + metrics::{FAILED, SUCCEEDED}, + Metrics, LOG_TARGET, +}; + +mod error; + +/// Rate limiting queues for incoming requests by peers. +mod peer_queues; + +/// Batch imports together. +mod batches; + +use self::{ + batches::{Batches, FoundBatch, PreparedImport}, + error::{log_error, JfyiError, JfyiResult, Result}, + peer_queues::PeerQueues, +}; + +const COST_INVALID_REQUEST: Rep = Rep::CostMajor("Received message could not be decoded."); +const COST_INVALID_SIGNATURE: Rep = Rep::Malicious("Signatures were invalid."); +const COST_INVALID_IMPORT: Rep = + Rep::Malicious("Import was deemed invalid by dispute-coordinator."); +const COST_NOT_A_VALIDATOR: Rep = Rep::CostMajor("Reporting peer was not a validator."); +/// Mildly punish peers exceeding their rate limit. +/// +/// For honest peers this should rarely happen, but if it happens we would not want to disconnect +/// too quickly. Minor cost should suffice for disconnecting any real flooder. +const COST_APPARENT_FLOOD: Rep = Rep::CostMinor("Peer exceeded the rate limit."); + +/// How many votes must have arrived in the last `BATCH_COLLECTING_INTERVAL` +/// +/// in order for a batch to stay alive and not get flushed/imported to the dispute-coordinator. +/// +/// This ensures a timely import of batches. +#[cfg(not(test))] +pub const MIN_KEEP_BATCH_ALIVE_VOTES: u32 = 10; +#[cfg(test)] +pub const MIN_KEEP_BATCH_ALIVE_VOTES: u32 = 2; + +/// Time we allow to pass for new votes to trickle in. +/// +/// See `MIN_KEEP_BATCH_ALIVE_VOTES` above. +/// Should be greater or equal to `RECEIVE_RATE_LIMIT` (there is no point in checking any faster). +pub const BATCH_COLLECTING_INTERVAL: Duration = Duration::from_millis(500); + +/// State for handling incoming `DisputeRequest` messages. +pub struct DisputesReceiver { + /// Access to session information. + runtime: RuntimeInfo, + + /// Subsystem sender for communication with other subsystems. + sender: Sender, + + /// Channel to retrieve incoming requests from. + receiver: IncomingRequestReceiver, + + /// Rate limiting queue for each peer (only authorities). + peer_queues: PeerQueues, + + /// Currently active batches of imports per candidate. + batches: Batches, + + /// Authority discovery service: + authority_discovery: AD, + + /// Imports currently being processed by the `dispute-coordinator`. + pending_imports: FuturesUnordered, + + /// Log received requests. + metrics: Metrics, +} + +/// Messages as handled by this receiver internally. +enum MuxedMessage { + /// An import got confirmed by the coordinator. + /// + /// We need to handle those for two reasons: + /// + /// - We need to make sure responses are actually sent (therefore we need to await futures + /// promptly). + /// - We need to punish peers whose import got rejected. + ConfirmedImport(ImportResult), + + /// A new request has arrived and should be handled. + NewRequest(IncomingRequest), + + /// Rate limit timer hit - is is time to process one row of messages. + /// + /// This is the result of calling `self.peer_queues.pop_reqs()`. + WakePeerQueuesPopReqs(Vec>), + + /// It is time to check batches. + /// + /// Every `BATCH_COLLECTING_INTERVAL` we check whether less than `MIN_KEEP_BATCH_ALIVE_VOTES` + /// new votes arrived, if so the batch is ready for import. + /// + /// This is the result of calling `self.batches.check_batches()`. + WakeCheckBatches(Vec), +} + +impl DisputesReceiver +where + AD: AuthorityDiscovery, + Sender: overseer::DisputeDistributionSenderTrait, +{ + /// Create a new receiver which can be `run`. + pub fn new( + sender: Sender, + receiver: IncomingRequestReceiver, + authority_discovery: AD, + metrics: Metrics, + ) -> Self { + let runtime = RuntimeInfo::new_with_config(runtime::Config { + keystore: None, + session_cache_lru_size: NonZeroUsize::new(DISPUTE_WINDOW.get() as usize) + .expect("Dispute window can not be 0; qed"), + }); + Self { + runtime, + sender, + receiver, + peer_queues: PeerQueues::new(), + batches: Batches::new(), + authority_discovery, + pending_imports: FuturesUnordered::new(), + metrics, + } + } + + /// Get that receiver started. + /// + /// This is an endless loop and should be spawned into its own task. + pub async fn run(mut self) { + loop { + match log_error(self.run_inner().await) { + Ok(()) => {}, + Err(fatal) => { + gum::debug!( + target: LOG_TARGET, + error = ?fatal, + "Shutting down" + ); + return + }, + } + } + } + + /// Actual work happening here in three phases: + /// + /// 1. Receive and queue incoming messages until the rate limit timer hits. + /// 2. Do import/batching for the head of all queues. + /// 3. Check and flush any ready batches. + async fn run_inner(&mut self) -> Result<()> { + let msg = self.receive_message().await?; + + match msg { + MuxedMessage::NewRequest(req) => { + // Phase 1: + self.metrics.on_received_request(); + self.dispatch_to_queues(req).await?; + }, + MuxedMessage::WakePeerQueuesPopReqs(reqs) => { + // Phase 2: + for req in reqs { + // No early return - we cannot cancel imports of one peer, because the import of + // another failed: + match log_error(self.start_import_or_batch(req).await) { + Ok(()) => {}, + Err(fatal) => return Err(fatal.into()), + } + } + }, + MuxedMessage::WakeCheckBatches(ready_imports) => { + // Phase 3: + self.import_ready_batches(ready_imports).await; + }, + MuxedMessage::ConfirmedImport(import_result) => { + self.update_imported_requests_metrics(&import_result); + // Confirm imports to requesters/punish them on invalid imports: + send_responses_to_requesters(import_result).await?; + }, + } + + Ok(()) + } + + /// Receive one `MuxedMessage`. + /// + /// + /// Dispatching events to messages as they happen. + async fn receive_message(&mut self) -> Result { + poll_fn(|ctx| { + // In case of Ready(None), we want to wait for pending requests: + if let Poll::Ready(Some(v)) = self.pending_imports.poll_next_unpin(ctx) { + return Poll::Ready(Ok(MuxedMessage::ConfirmedImport(v?))) + } + + let rate_limited = self.peer_queues.pop_reqs(); + pin_mut!(rate_limited); + // We poll rate_limit before batches, so we don't unnecessarily delay importing to + // batches. + if let Poll::Ready(reqs) = rate_limited.poll(ctx) { + return Poll::Ready(Ok(MuxedMessage::WakePeerQueuesPopReqs(reqs))) + } + + let ready_batches = self.batches.check_batches(); + pin_mut!(ready_batches); + if let Poll::Ready(ready_batches) = ready_batches.poll(ctx) { + return Poll::Ready(Ok(MuxedMessage::WakeCheckBatches(ready_batches))) + } + + let next_req = self.receiver.recv(|| vec![COST_INVALID_REQUEST]); + pin_mut!(next_req); + if let Poll::Ready(r) = next_req.poll(ctx) { + return match r { + Err(e) => Poll::Ready(Err(incoming::Error::from(e).into())), + Ok(v) => Poll::Ready(Ok(MuxedMessage::NewRequest(v))), + } + } + Poll::Pending + }) + .await + } + + /// Process incoming requests. + /// + /// - Check sender is authority + /// - Dispatch message to corresponding queue in `peer_queues`. + /// - If queue is full, drop message and change reputation of sender. + async fn dispatch_to_queues(&mut self, req: IncomingRequest) -> JfyiResult<()> { + let peer = req.peer; + // Only accept messages from validators, in case there are multiple `AuthorityId`s, we + // just take the first one. On session boundaries this might allow validators to double + // their rate limit for a short period of time, which seems acceptable. + let authority_id = match self + .authority_discovery + .get_authority_ids_by_peer_id(peer) + .await + .and_then(|s| s.into_iter().next()) + { + None => { + req.send_outgoing_response(OutgoingResponse { + result: Err(()), + reputation_changes: vec![COST_NOT_A_VALIDATOR], + sent_feedback: None, + }) + .map_err(|_| JfyiError::SendResponses(vec![peer]))?; + return Err(JfyiError::NotAValidator(peer).into()) + }, + Some(auth_id) => auth_id, + }; + + // Queue request: + if let Err((authority_id, req)) = self.peer_queues.push_req(authority_id, req) { + gum::debug!( + target: LOG_TARGET, + ?authority_id, + ?peer, + "Peer hit the rate limit - dropping message." + ); + req.send_outgoing_response(OutgoingResponse { + result: Err(()), + reputation_changes: vec![COST_APPARENT_FLOOD], + sent_feedback: None, + }) + .map_err(|_| JfyiError::SendResponses(vec![peer]))?; + return Err(JfyiError::AuthorityFlooding(authority_id)) + } + Ok(()) + } + + /// Start importing votes for the given request or batch. + /// + /// Signature check and in case we already have an existing batch we import to that batch, + /// otherwise import to `dispute-coordinator` directly and open a batch. + async fn start_import_or_batch( + &mut self, + incoming: IncomingRequest, + ) -> Result<()> { + let IncomingRequest { peer, payload, pending_response } = incoming; + + let info = self + .runtime + .get_session_info_by_index( + &mut self.sender, + payload.0.candidate_receipt.descriptor.relay_parent, + payload.0.session_index, + ) + .await?; + + let votes_result = payload.0.try_into_signed_votes(&info.session_info); + + let (candidate_receipt, valid_vote, invalid_vote) = match votes_result { + Err(()) => { + // Signature invalid: + pending_response + .send_outgoing_response(OutgoingResponse { + result: Err(()), + reputation_changes: vec![COST_INVALID_SIGNATURE], + sent_feedback: None, + }) + .map_err(|_| JfyiError::SetPeerReputation(peer))?; + + return Err(From::from(JfyiError::InvalidSignature(peer))) + }, + Ok(votes) => votes, + }; + + let candidate_hash = *valid_vote.0.candidate_hash(); + + match self.batches.find_batch(candidate_hash, candidate_receipt)? { + FoundBatch::Created(batch) => { + // There was no entry yet - start import immediately: + gum::trace!( + target: LOG_TARGET, + ?candidate_hash, + ?peer, + "No batch yet - triggering immediate import" + ); + let import = PreparedImport { + candidate_receipt: batch.candidate_receipt().clone(), + statements: vec![valid_vote, invalid_vote], + requesters: vec![(peer, pending_response)], + }; + self.start_import(import).await; + }, + FoundBatch::Found(batch) => { + gum::trace!(target: LOG_TARGET, ?candidate_hash, "Batch exists - batching request"); + let batch_result = + batch.add_votes(valid_vote, invalid_vote, peer, pending_response); + + if let Err(pending_response) = batch_result { + // We don't expect honest peers to send redundant votes within a single batch, + // as the timeout for retry is much higher. Still we don't want to punish the + // node as it might not be the node's fault. Some other (malicious) node could + // have been faster sending the same votes in order to harm the reputation of + // that honest node. Given that we already have a rate limit, if a validator + // chooses to waste available rate with redundant votes - so be it. The actual + // dispute resolution is unaffected. + gum::debug!( + target: LOG_TARGET, + ?peer, + "Peer sent completely redundant votes within a single batch - that looks fishy!", + ); + pending_response + .send_outgoing_response(OutgoingResponse { + // While we have seen duplicate votes, we cannot confirm as we don't + // know yet whether the batch is going to be confirmed, so we assume + // the worst. We don't want to push the pending response to the batch + // either as that would be unbounded, only limited by the rate limit. + result: Err(()), + reputation_changes: Vec::new(), + sent_feedback: None, + }) + .map_err(|_| JfyiError::SendResponses(vec![peer]))?; + return Err(From::from(JfyiError::RedundantMessage(peer))) + } + }, + } + + Ok(()) + } + + /// Trigger import into the dispute-coordinator of ready batches (`PreparedImport`s). + async fn import_ready_batches(&mut self, ready_imports: Vec) { + for import in ready_imports { + self.start_import(import).await; + } + } + + /// Start import and add response receiver to `pending_imports`. + async fn start_import(&mut self, import: PreparedImport) { + let PreparedImport { candidate_receipt, statements, requesters } = import; + let (session_index, candidate_hash) = match statements.iter().next() { + None => { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?candidate_receipt.hash(), + "Not importing empty batch" + ); + return + }, + Some(vote) => (vote.0.session_index(), *vote.0.candidate_hash()), + }; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + self.sender + .send_message(DisputeCoordinatorMessage::ImportStatements { + candidate_receipt, + session: session_index, + statements, + pending_confirmation: Some(pending_confirmation), + }) + .await; + + let pending = + PendingImport { candidate_hash, requesters, pending_response: confirmation_rx }; + + self.pending_imports.push(pending); + } + + fn update_imported_requests_metrics(&self, result: &ImportResult) { + let label = match result.result { + ImportStatementsResult::ValidImport => SUCCEEDED, + ImportStatementsResult::InvalidImport => FAILED, + }; + self.metrics.on_imported(label, result.requesters.len()); + } +} + +async fn send_responses_to_requesters(import_result: ImportResult) -> JfyiResult<()> { + let ImportResult { requesters, result } = import_result; + + let mk_response = match result { + ImportStatementsResult::ValidImport => || OutgoingResponse { + result: Ok(DisputeResponse::Confirmed), + reputation_changes: Vec::new(), + sent_feedback: None, + }, + ImportStatementsResult::InvalidImport => || OutgoingResponse { + result: Err(()), + reputation_changes: vec![COST_INVALID_IMPORT], + sent_feedback: None, + }, + }; + + let mut sending_failed_for = Vec::new(); + for (peer, pending_response) in requesters { + if let Err(()) = pending_response.send_outgoing_response(mk_response()) { + sending_failed_for.push(peer); + } + } + + if !sending_failed_for.is_empty() { + Err(JfyiError::SendResponses(sending_failed_for)) + } else { + Ok(()) + } +} + +/// A future that resolves into an `ImportResult` when ready. +/// +/// This future is used on `dispute-coordinator` import messages for the oneshot response receiver +/// to: +/// - Keep track of concerned `CandidateHash` for reporting errors. +/// - Keep track of requesting peers so we can confirm the import/punish them on invalid imports. +struct PendingImport { + candidate_hash: CandidateHash, + requesters: Vec<(PeerId, OutgoingResponseSender)>, + pending_response: oneshot::Receiver, +} + +/// A `PendingImport` becomes an `ImportResult` once done. +struct ImportResult { + /// Requesters of that import. + requesters: Vec<(PeerId, OutgoingResponseSender)>, + /// Actual result of the import. + result: ImportStatementsResult, +} + +impl PendingImport { + async fn wait_for_result(&mut self) -> JfyiResult { + let result = (&mut self.pending_response) + .await + .map_err(|_| JfyiError::ImportCanceled(self.candidate_hash))?; + Ok(ImportResult { requesters: std::mem::take(&mut self.requesters), result }) + } +} + +impl Future for PendingImport { + type Output = JfyiResult; + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let fut = self.wait_for_result(); + pin_mut!(fut); + fut.poll(cx) + } +} diff --git a/polkadot/node/network/dispute-distribution/src/receiver/peer_queues.rs b/polkadot/node/network/dispute-distribution/src/receiver/peer_queues.rs new file mode 100644 index 0000000000000000000000000000000000000000..bc58c019713b537437e44f752cfaf859d629e409 --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/receiver/peer_queues.rs @@ -0,0 +1,141 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::collections::{hash_map::Entry, HashMap, VecDeque}; + +use futures::future::pending; +use futures_timer::Delay; +use polkadot_node_network_protocol::request_response::{v1::DisputeRequest, IncomingRequest}; +use polkadot_primitives::AuthorityDiscoveryId; + +use crate::RECEIVE_RATE_LIMIT; + +/// How many messages we are willing to queue per peer (validator). +/// +/// The larger this value is, the larger bursts are allowed to be without us dropping messages. On +/// the flip side this gets allocated per validator, so for a size of 10 this will result +/// in `10_000 * size_of(IncomingRequest)` in the worst case. +/// +/// `PEER_QUEUE_CAPACITY` must not be 0 for obvious reasons. +#[cfg(not(test))] +pub const PEER_QUEUE_CAPACITY: usize = 10; +#[cfg(test)] +pub const PEER_QUEUE_CAPACITY: usize = 2; + +/// Queues for messages from authority peers for rate limiting. +/// +/// Invariants ensured: +/// +/// 1. No queue will ever have more than `PEER_QUEUE_CAPACITY` elements. +/// 2. There are no empty queues. Whenever a queue gets empty, it is removed. This way checking +/// whether there are any messages queued is cheap. +/// 3. As long as not empty, `pop_reqs` will, if called in sequence, not return `Ready` more often +/// than once for every `RECEIVE_RATE_LIMIT`, but it will always return Ready eventually. +/// 4. If empty `pop_reqs` will never return `Ready`, but will always be `Pending`. +pub struct PeerQueues { + /// Actual queues. + queues: HashMap>>, + + /// Delay timer for establishing the rate limit. + rate_limit_timer: Option, +} + +impl PeerQueues { + /// New empty `PeerQueues`. + pub fn new() -> Self { + Self { queues: HashMap::new(), rate_limit_timer: None } + } + + /// Push an incoming request for a given authority. + /// + /// Returns: `Ok(())` if succeeded, `Err((args))` if capacity is reached. + pub fn push_req( + &mut self, + peer: AuthorityDiscoveryId, + req: IncomingRequest, + ) -> Result<(), (AuthorityDiscoveryId, IncomingRequest)> { + let queue = match self.queues.entry(peer) { + Entry::Vacant(vacant) => vacant.insert(VecDeque::new()), + Entry::Occupied(occupied) => { + if occupied.get().len() >= PEER_QUEUE_CAPACITY { + return Err((occupied.key().clone(), req)) + } + occupied.into_mut() + }, + }; + queue.push_back(req); + + // We have at least one element to process - rate limit `timer` needs to exist now: + self.ensure_timer(); + Ok(()) + } + + /// Pop all heads and return them for processing. + /// + /// This gets one message from each peer that has sent at least one. + /// + /// This function is rate limited, if called in sequence it will not return more often than + /// every `RECEIVE_RATE_LIMIT`. + /// + /// NOTE: If empty this function will not return `Ready` at all, but will always be `Pending`. + pub async fn pop_reqs(&mut self) -> Vec> { + self.wait_for_timer().await; + + let mut heads = Vec::with_capacity(self.queues.len()); + let old_queues = std::mem::replace(&mut self.queues, HashMap::new()); + for (k, mut queue) in old_queues.into_iter() { + let front = queue.pop_front(); + debug_assert!(front.is_some(), "Invariant that queues are never empty is broken."); + + if let Some(front) = front { + heads.push(front); + } + if !queue.is_empty() { + self.queues.insert(k, queue); + } + } + + if !self.is_empty() { + // Still not empty - we should get woken at some point. + self.ensure_timer(); + } + + heads + } + + /// Whether or not all queues are empty. + pub fn is_empty(&self) -> bool { + self.queues.is_empty() + } + + /// Ensure there is an active `timer`. + /// + /// Checks whether one exists and if not creates one. + fn ensure_timer(&mut self) -> &mut Delay { + self.rate_limit_timer.get_or_insert(Delay::new(RECEIVE_RATE_LIMIT)) + } + + /// Wait for `timer` if it exists, or be `Pending` forever. + /// + /// Afterwards it gets set back to `None`. + async fn wait_for_timer(&mut self) { + match self.rate_limit_timer.as_mut() { + None => pending().await, + Some(timer) => timer.await, + } + self.rate_limit_timer = None; + } +} diff --git a/polkadot/node/network/dispute-distribution/src/sender/error.rs b/polkadot/node/network/dispute-distribution/src/sender/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..348a4083c9c42db14262fcfc7ebe342cc19cab02 --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/sender/error.rs @@ -0,0 +1,73 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +// + +//! Error handling related code and Error/Result definitions. + +use polkadot_node_primitives::disputes::DisputeMessageCheckError; +use polkadot_node_subsystem::SubsystemError; +use polkadot_node_subsystem_util::runtime; + +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + #[fatal] + #[error("Spawning subsystem task failed")] + SpawnTask(#[source] SubsystemError), + + #[fatal(forward)] + #[error("Error while accessing runtime information")] + Runtime(#[from] runtime::Error), + + /// We need available active heads for finding relevant authorities. + #[error("No active heads available - needed for finding relevant authorities.")] + NoActiveHeads, + + /// This error likely indicates a bug in the coordinator. + #[error("Oneshot for asking dispute coordinator for active disputes got canceled.")] + AskActiveDisputesCanceled, + + /// This error likely indicates a bug in the coordinator. + #[error("Oneshot for asking dispute coordinator for candidate votes got canceled.")] + AskCandidateVotesCanceled, + + /// This error does indicate a bug in the coordinator. + /// + /// We were not able to successfully construct a `DisputeMessage` from disputes votes. + #[error("Invalid dispute encountered")] + InvalidDisputeFromCoordinator(#[source] DisputeMessageCheckError), + + /// This error does indicate a bug in the coordinator. + /// + /// We did not receive votes on both sides for `CandidateVotes` received from the coordinator. + #[error("Missing votes for valid dispute")] + MissingVotesFromCoordinator, + + /// This error does indicate a bug in the coordinator. + /// + /// `SignedDisputeStatement` could not be reconstructed from recorded statements. + #[error("Invalid statements from coordinator")] + InvalidStatementFromCoordinator, + + /// This error does indicate a bug in the coordinator. + /// + /// A statement's `ValidatorIndex` could not be looked up. + #[error("ValidatorIndex of statement could not be found")] + InvalidValidatorIndexFromCoordinator, +} + +pub type Result = std::result::Result; +pub type JfyiErrorResult = std::result::Result; diff --git a/polkadot/node/network/dispute-distribution/src/sender/mod.rs b/polkadot/node/network/dispute-distribution/src/sender/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..f4acc72318ad448b99a106b460b84eefabd5c96d --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/sender/mod.rs @@ -0,0 +1,391 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{ + collections::{HashMap, HashSet}, + pin::Pin, + task::Poll, + time::Duration, +}; + +use futures::{channel::oneshot, future::poll_fn, Future}; + +use futures_timer::Delay; +use indexmap::{map::Entry, IndexMap}; +use polkadot_node_network_protocol::request_response::v1::DisputeRequest; +use polkadot_node_primitives::{DisputeMessage, DisputeStatus}; +use polkadot_node_subsystem::{ + messages::DisputeCoordinatorMessage, overseer, ActiveLeavesUpdate, SubsystemSender, +}; +use polkadot_node_subsystem_util::{nesting_sender::NestingSender, runtime::RuntimeInfo}; +use polkadot_primitives::{CandidateHash, Hash, SessionIndex}; + +/// For each ongoing dispute we have a `SendTask` which takes care of it. +/// +/// It is going to spawn real tasks as it sees fit for getting the votes of the particular dispute +/// out. +/// +/// As we assume disputes have a priority, we start sending for disputes in the order +/// `start_sender` got called. +mod send_task; +use send_task::SendTask; +pub use send_task::TaskFinish; + +/// Error and [`Result`] type for sender. +mod error; +pub use error::{Error, FatalError, JfyiError, Result}; + +use self::error::JfyiErrorResult; +use crate::{Metrics, LOG_TARGET, SEND_RATE_LIMIT}; + +/// Messages as sent by background tasks. +#[derive(Debug)] +pub enum DisputeSenderMessage { + /// A task finished. + TaskFinish(TaskFinish), + /// A request for active disputes to the dispute-coordinator finished. + ActiveDisputesReady(JfyiErrorResult>), +} + +/// The `DisputeSender` keeps track of all ongoing disputes we need to send statements out. +/// +/// For each dispute a `SendTask` is responsible for sending to the concerned validators for that +/// particular dispute. The `DisputeSender` keeps track of those tasks, informs them about new +/// sessions/validator sets and cleans them up when they become obsolete. +/// +/// The unit of work for the `DisputeSender` is a dispute, represented by `SendTask`s. +pub struct DisputeSender { + /// All heads we currently consider active. + active_heads: Vec, + + /// List of currently active sessions. + /// + /// Value is the hash that was used for the query. + active_sessions: HashMap, + + /// All ongoing dispute sendings this subsystem is aware of. + /// + /// Using an `IndexMap` so items can be iterated in the order of insertion. + disputes: IndexMap>, + + /// Sender to be cloned for `SendTask`s. + tx: NestingSender, + + /// `Some` if we are waiting for a response `DisputeCoordinatorMessage::ActiveDisputes`. + waiting_for_active_disputes: Option, + + /// Future for delaying too frequent creation of dispute sending tasks. + rate_limit: RateLimit, + + /// Metrics for reporting stats about sent requests. + metrics: Metrics, +} + +/// State we keep while waiting for active disputes. +/// +/// When we send `DisputeCoordinatorMessage::ActiveDisputes`, this is the state we keep while +/// waiting for the response. +struct WaitForActiveDisputesState { + /// Have we seen any new sessions since last refresh? + have_new_sessions: bool, +} + +#[overseer::contextbounds(DisputeDistribution, prefix = self::overseer)] +impl DisputeSender { + /// Create a new `DisputeSender` which can be used to start dispute sendings. + pub fn new(tx: NestingSender, metrics: Metrics) -> Self { + Self { + active_heads: Vec::new(), + active_sessions: HashMap::new(), + disputes: IndexMap::new(), + tx, + waiting_for_active_disputes: None, + rate_limit: RateLimit::new(), + metrics, + } + } + + /// Create a `SendTask` for a particular new dispute. + /// + /// This function is rate-limited by `SEND_RATE_LIMIT`. It will block if called too frequently + /// in order to maintain the limit. + pub async fn start_sender( + &mut self, + ctx: &mut Context, + runtime: &mut RuntimeInfo, + msg: DisputeMessage, + ) -> Result<()> { + let req: DisputeRequest = msg.into(); + let candidate_hash = req.0.candidate_receipt.hash(); + match self.disputes.entry(candidate_hash) { + Entry::Occupied(_) => { + gum::trace!(target: LOG_TARGET, ?candidate_hash, "Dispute sending already active."); + return Ok(()) + }, + Entry::Vacant(vacant) => { + self.rate_limit.limit("in start_sender", candidate_hash).await; + + let send_task = SendTask::new( + ctx, + runtime, + &self.active_sessions, + NestingSender::new(self.tx.clone(), DisputeSenderMessage::TaskFinish), + req, + &self.metrics, + ) + .await?; + vacant.insert(send_task); + }, + } + Ok(()) + } + + /// Receive message from a background task. + pub async fn on_message( + &mut self, + ctx: &mut Context, + runtime: &mut RuntimeInfo, + msg: DisputeSenderMessage, + ) -> Result<()> { + match msg { + DisputeSenderMessage::TaskFinish(msg) => { + let TaskFinish { candidate_hash, receiver, result } = msg; + + self.metrics.on_sent_request(result.as_metrics_label()); + + let task = match self.disputes.get_mut(&candidate_hash) { + None => { + // Can happen when a dispute ends, with messages still in queue: + gum::trace!( + target: LOG_TARGET, + ?result, + "Received `FromSendingTask::Finished` for non existing dispute." + ); + return Ok(()) + }, + Some(task) => task, + }; + task.on_finished_send(&receiver, result); + }, + DisputeSenderMessage::ActiveDisputesReady(result) => { + let state = self.waiting_for_active_disputes.take(); + let have_new_sessions = state.map(|s| s.have_new_sessions).unwrap_or(false); + let active_disputes = result?; + self.handle_new_active_disputes(ctx, runtime, active_disputes, have_new_sessions) + .await?; + }, + } + Ok(()) + } + + /// Take care of a change in active leaves. + /// + /// Update our knowledge on sessions and initiate fetching for new active disputes. + pub async fn update_leaves( + &mut self, + ctx: &mut Context, + runtime: &mut RuntimeInfo, + update: ActiveLeavesUpdate, + ) -> Result<()> { + let ActiveLeavesUpdate { activated, deactivated } = update; + let deactivated: HashSet<_> = deactivated.into_iter().collect(); + self.active_heads.retain(|h| !deactivated.contains(h)); + self.active_heads.extend(activated.into_iter().map(|l| l.hash)); + + let have_new_sessions = self.refresh_sessions(ctx, runtime).await?; + + // Not yet waiting for data, request an update: + match self.waiting_for_active_disputes.take() { + None => { + self.waiting_for_active_disputes = + Some(WaitForActiveDisputesState { have_new_sessions }); + let mut sender = ctx.sender().clone(); + let mut tx = self.tx.clone(); + + let get_active_disputes_task = async move { + let result = get_active_disputes(&mut sender).await; + let result = + tx.send_message(DisputeSenderMessage::ActiveDisputesReady(result)).await; + if let Err(err) = result { + gum::debug!( + target: LOG_TARGET, + ?err, + "Sending `DisputeSenderMessage` from background task failed." + ); + } + }; + + ctx.spawn("get_active_disputes", Box::pin(get_active_disputes_task)) + .map_err(FatalError::SpawnTask)?; + }, + Some(state) => { + let have_new_sessions = state.have_new_sessions || have_new_sessions; + let new_state = WaitForActiveDisputesState { have_new_sessions }; + self.waiting_for_active_disputes = Some(new_state); + gum::debug!( + target: LOG_TARGET, + "Dispute coordinator slow? We are still waiting for data on next active leaves update." + ); + }, + } + Ok(()) + } + + /// Handle new active disputes response. + /// + /// - Initiate a retry of failed sends which are still active. + /// - Get new authorities to send messages to. + /// - Get rid of obsolete tasks and disputes. + /// + /// This function ensures the `SEND_RATE_LIMIT`, therefore it might block. + async fn handle_new_active_disputes( + &mut self, + ctx: &mut Context, + runtime: &mut RuntimeInfo, + active_disputes: Vec<(SessionIndex, CandidateHash, DisputeStatus)>, + have_new_sessions: bool, + ) -> Result<()> { + let active_disputes: HashSet<_> = active_disputes.into_iter().map(|(_, c, _)| c).collect(); + + // Cleanup obsolete senders (retain keeps order of remaining elements): + self.disputes + .retain(|candidate_hash, _| active_disputes.contains(candidate_hash)); + + // Iterates in order of insertion: + let mut should_rate_limit = true; + for (candidate_hash, dispute) in self.disputes.iter_mut() { + if have_new_sessions || dispute.has_failed_sends() { + if should_rate_limit { + self.rate_limit + .limit("while going through new sessions/failed sends", *candidate_hash) + .await; + } + let sends_happened = dispute + .refresh_sends(ctx, runtime, &self.active_sessions, &self.metrics) + .await?; + // Only rate limit if we actually sent something out _and_ it was not just because + // of errors on previous sends. + // + // Reasoning: It would not be acceptable to slow down the whole subsystem, just + // because of a few bad peers having problems. It is actually better to risk + // running into their rate limit in that case and accept a minor reputation change. + should_rate_limit = sends_happened && have_new_sessions; + } + } + Ok(()) + } + + /// Make active sessions correspond to currently active heads. + /// + /// Returns: true if sessions changed. + async fn refresh_sessions( + &mut self, + ctx: &mut Context, + runtime: &mut RuntimeInfo, + ) -> Result { + let new_sessions = get_active_session_indices(ctx, runtime, &self.active_heads).await?; + let new_sessions_raw: HashSet<_> = new_sessions.keys().collect(); + let old_sessions_raw: HashSet<_> = self.active_sessions.keys().collect(); + let updated = new_sessions_raw != old_sessions_raw; + // Update in any case, so we use current heads for queries: + self.active_sessions = new_sessions; + Ok(updated) + } +} + +/// Rate limiting logic. +/// +/// Suitable for the sending side. +struct RateLimit { + limit: Delay, +} + +impl RateLimit { + /// Create new `RateLimit` that is immediately ready. + fn new() -> Self { + // Start with an empty duration, as there has not been any previous call. + Self { limit: Delay::new(Duration::new(0, 0)) } + } + + /// Initialized with actual `SEND_RATE_LIMIT` duration. + fn new_limit() -> Self { + Self { limit: Delay::new(SEND_RATE_LIMIT) } + } + + /// Wait until ready and prepare for next call. + /// + /// String given as occasion and candidate hash are logged in case the rate limit hit. + async fn limit(&mut self, occasion: &'static str, candidate_hash: CandidateHash) { + // Wait for rate limit and add some logging: + let mut num_wakes: u32 = 0; + poll_fn(|cx| { + let old_limit = Pin::new(&mut self.limit); + match old_limit.poll(cx) { + Poll::Pending => { + gum::debug!( + target: LOG_TARGET, + ?occasion, + ?candidate_hash, + ?num_wakes, + "Sending rate limit hit, slowing down requests" + ); + num_wakes += 1; + Poll::Pending + }, + Poll::Ready(()) => Poll::Ready(()), + } + }) + .await; + *self = Self::new_limit(); + } +} + +/// Retrieve the currently active sessions. +/// +/// List is all indices of all active sessions together with the head that was used for the query. +#[overseer::contextbounds(DisputeDistribution, prefix = self::overseer)] +async fn get_active_session_indices( + ctx: &mut Context, + runtime: &mut RuntimeInfo, + active_heads: &Vec, +) -> Result> { + let mut indeces = HashMap::new(); + // Iterate all heads we track as active and fetch the child' session indices. + for head in active_heads { + let session_index = runtime.get_session_index_for_child(ctx.sender(), *head).await?; + // Cache session info + if let Err(err) = + runtime.get_session_info_by_index(ctx.sender(), *head, session_index).await + { + gum::debug!(target: LOG_TARGET, ?err, ?session_index, "Can't cache SessionInfo"); + } + indeces.insert(session_index, *head); + } + Ok(indeces) +} + +/// Retrieve Set of active disputes from the dispute coordinator. +async fn get_active_disputes( + sender: &mut Sender, +) -> JfyiErrorResult> +where + Sender: SubsystemSender, +{ + let (tx, rx) = oneshot::channel(); + + sender.send_message(DisputeCoordinatorMessage::ActiveDisputes(tx)).await; + rx.await.map_err(|_| JfyiError::AskActiveDisputesCanceled) +} diff --git a/polkadot/node/network/dispute-distribution/src/sender/send_task.rs b/polkadot/node/network/dispute-distribution/src/sender/send_task.rs new file mode 100644 index 0000000000000000000000000000000000000000..18c66066d162ec16880b9391aa2e59e1f6b0ea1a --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/sender/send_task.rs @@ -0,0 +1,331 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::collections::{HashMap, HashSet}; + +use futures::{future::RemoteHandle, Future, FutureExt}; + +use polkadot_node_network_protocol::{ + request_response::{ + outgoing::RequestError, + v1::{DisputeRequest, DisputeResponse}, + OutgoingRequest, OutgoingResult, Recipient, Requests, + }, + IfDisconnected, +}; +use polkadot_node_subsystem::{messages::NetworkBridgeTxMessage, overseer}; +use polkadot_node_subsystem_util::{metrics, nesting_sender::NestingSender, runtime::RuntimeInfo}; +use polkadot_primitives::{ + AuthorityDiscoveryId, CandidateHash, Hash, SessionIndex, ValidatorIndex, +}; + +use super::error::{FatalError, Result}; + +use crate::{ + metrics::{FAILED, SUCCEEDED}, + Metrics, LOG_TARGET, +}; + +/// Delivery status for a particular dispute. +/// +/// Keeps track of all the validators that have to be reached for a dispute. +/// +/// The unit of work for a `SendTask` is an authority/validator. +pub struct SendTask { + /// The request we are supposed to get out to all `parachain` validators of the dispute's + /// session and to all current authorities. + request: DisputeRequest, + + /// The set of authorities we need to send our messages to. This set will change at session + /// boundaries. It will always be at least the `parachain` validators of the session where the + /// dispute happened and the authorities of the current sessions as determined by active heads. + deliveries: HashMap, + + /// Whether we have any tasks failed since the last refresh. + has_failed_sends: bool, + + /// Sender to be cloned for tasks. + tx: NestingSender, +} + +/// Status of a particular vote/statement delivery to a particular validator. +enum DeliveryStatus { + /// Request is still in flight. + Pending(RemoteHandle<()>), + /// Succeeded - no need to send request to this peer anymore. + Succeeded, +} + +/// A sending task finishes with this result: +#[derive(Debug)] +pub struct TaskFinish { + /// The candidate this task was running for. + pub candidate_hash: CandidateHash, + /// The authority the request was sent to. + pub receiver: AuthorityDiscoveryId, + /// The result of the delivery attempt. + pub result: TaskResult, +} + +#[derive(Debug)] +pub enum TaskResult { + /// Task succeeded in getting the request to its peer. + Succeeded, + /// Task was not able to get the request out to its peer. + /// + /// It should be retried in that case. + Failed(RequestError), +} + +impl TaskResult { + pub fn as_metrics_label(&self) -> &'static str { + match self { + Self::Succeeded => SUCCEEDED, + Self::Failed(_) => FAILED, + } + } +} + +#[overseer::contextbounds(DisputeDistribution, prefix = self::overseer)] +impl SendTask { + /// Initiates sending a dispute message to peers. + /// + /// Creation of new `SendTask`s is subject to rate limiting. As each `SendTask` will trigger + /// sending a message to each validator, hence for employing a per-peer rate limit, we need to + /// limit the construction of new `SendTask`s. + pub async fn new( + ctx: &mut Context, + runtime: &mut RuntimeInfo, + active_sessions: &HashMap, + tx: NestingSender, + request: DisputeRequest, + metrics: &Metrics, + ) -> Result { + let mut send_task = + Self { request, deliveries: HashMap::new(), has_failed_sends: false, tx }; + send_task.refresh_sends(ctx, runtime, active_sessions, metrics).await?; + Ok(send_task) + } + + /// Make sure we are sending to all relevant authorities. + /// + /// This function is called at construction and should also be called whenever a session change + /// happens and on a regular basis to ensure we are retrying failed attempts. + /// + /// This might resend to validators and is thus subject to any rate limiting we might want. + /// Calls to this function for different instances should be rate limited according to + /// `SEND_RATE_LIMIT`. + /// + /// Returns: `True` if this call resulted in new requests. + pub async fn refresh_sends( + &mut self, + ctx: &mut Context, + runtime: &mut RuntimeInfo, + active_sessions: &HashMap, + metrics: &Metrics, + ) -> Result { + let new_authorities = self.get_relevant_validators(ctx, runtime, active_sessions).await?; + + // Note this will also contain all authorities for which sending failed previously: + let add_authorities: Vec<_> = new_authorities + .iter() + .filter(|a| !self.deliveries.contains_key(a)) + .map(Clone::clone) + .collect(); + + // Get rid of dead/irrelevant tasks/statuses: + gum::trace!( + target: LOG_TARGET, + already_running_deliveries = ?self.deliveries.len(), + "Cleaning up deliveries" + ); + self.deliveries.retain(|k, _| new_authorities.contains(k)); + + // Start any new tasks that are needed: + gum::trace!( + target: LOG_TARGET, + new_and_failed_authorities = ?add_authorities.len(), + overall_authority_set_size = ?new_authorities.len(), + already_running_deliveries = ?self.deliveries.len(), + "Starting new send requests for authorities." + ); + let new_statuses = + send_requests(ctx, self.tx.clone(), add_authorities, self.request.clone(), metrics) + .await?; + + let was_empty = new_statuses.is_empty(); + gum::trace!( + target: LOG_TARGET, + sent_requests = ?new_statuses.len(), + "Requests dispatched." + ); + + self.has_failed_sends = false; + self.deliveries.extend(new_statuses.into_iter()); + Ok(!was_empty) + } + + /// Whether any sends have failed since the last refresh. + pub fn has_failed_sends(&self) -> bool { + self.has_failed_sends + } + + /// Handle a finished response waiting task. + /// + /// Called by `DisputeSender` upon reception of the corresponding message from our spawned + /// `wait_response_task`. + pub fn on_finished_send(&mut self, authority: &AuthorityDiscoveryId, result: TaskResult) { + match result { + TaskResult::Failed(err) => { + gum::trace!( + target: LOG_TARGET, + ?authority, + candidate_hash = %self.request.0.candidate_receipt.hash(), + %err, + "Error sending dispute statements to node." + ); + + self.has_failed_sends = true; + // Remove state, so we know what to try again: + self.deliveries.remove(authority); + }, + TaskResult::Succeeded => { + let status = match self.deliveries.get_mut(&authority) { + None => { + // Can happen when a sending became irrelevant while the response was + // already queued. + gum::debug!( + target: LOG_TARGET, + candidate = ?self.request.0.candidate_receipt.hash(), + ?authority, + ?result, + "Received `FromSendingTask::Finished` for non existing task." + ); + return + }, + Some(status) => status, + }; + // We are done here: + *status = DeliveryStatus::Succeeded; + }, + } + } + + /// Determine all validators that should receive the given dispute requests. + /// + /// This is all `parachain` validators of the session the candidate occurred and all authorities + /// of all currently active sessions, determined by currently active heads. + async fn get_relevant_validators( + &self, + ctx: &mut Context, + runtime: &mut RuntimeInfo, + active_sessions: &HashMap, + ) -> Result> { + let ref_head = self.request.0.candidate_receipt.descriptor.relay_parent; + // Retrieve all authorities which participated in the parachain consensus of the session + // in which the candidate was backed. + let info = runtime + .get_session_info_by_index(ctx.sender(), ref_head, self.request.0.session_index) + .await?; + let session_info = &info.session_info; + let validator_count = session_info.validators.len(); + let mut authorities: HashSet<_> = session_info + .discovery_keys + .iter() + .take(validator_count) + .enumerate() + .filter(|(i, _)| Some(ValidatorIndex(*i as _)) != info.validator_info.our_index) + .map(|(_, v)| v.clone()) + .collect(); + + // Retrieve all authorities for the current session as indicated by the active + // heads we are tracking. + for (session_index, head) in active_sessions.iter() { + let info = + runtime.get_session_info_by_index(ctx.sender(), *head, *session_index).await?; + let session_info = &info.session_info; + let new_set = session_info + .discovery_keys + .iter() + .enumerate() + .filter(|(i, _)| Some(ValidatorIndex(*i as _)) != info.validator_info.our_index) + .map(|(_, v)| v.clone()); + authorities.extend(new_set); + } + Ok(authorities) + } +} + +/// Start sending of the given message to all given authorities. +/// +/// And spawn tasks for handling the response. +#[overseer::contextbounds(DisputeDistribution, prefix = self::overseer)] +async fn send_requests( + ctx: &mut Context, + tx: NestingSender, + receivers: Vec, + req: DisputeRequest, + metrics: &Metrics, +) -> Result> { + let mut statuses = HashMap::with_capacity(receivers.len()); + let mut reqs = Vec::with_capacity(receivers.len()); + + for receiver in receivers { + let (outgoing, pending_response) = + OutgoingRequest::new(Recipient::Authority(receiver.clone()), req.clone()); + + reqs.push(Requests::DisputeSendingV1(outgoing)); + + let fut = wait_response_task( + pending_response, + req.0.candidate_receipt.hash(), + receiver.clone(), + tx.clone(), + metrics.time_dispute_request(), + ); + + let (remote, remote_handle) = fut.remote_handle(); + ctx.spawn("dispute-sender", remote.boxed()).map_err(FatalError::SpawnTask)?; + statuses.insert(receiver, DeliveryStatus::Pending(remote_handle)); + } + + let msg = NetworkBridgeTxMessage::SendRequests(reqs, IfDisconnected::ImmediateError); + ctx.send_message(msg).await; + Ok(statuses) +} + +/// Future to be spawned in a task for awaiting a response. +async fn wait_response_task( + pending_response: impl Future>, + candidate_hash: CandidateHash, + receiver: AuthorityDiscoveryId, + mut tx: NestingSender, + _timer: Option, +) { + let result = pending_response.await; + let msg = match result { + Err(err) => TaskFinish { candidate_hash, receiver, result: TaskResult::Failed(err) }, + Ok(DisputeResponse::Confirmed) => + TaskFinish { candidate_hash, receiver, result: TaskResult::Succeeded }, + }; + if let Err(err) = tx.send_message(msg).await { + gum::debug!( + target: LOG_TARGET, + %err, + "Failed to notify subsystem about dispute sending result." + ); + } +} diff --git a/polkadot/node/network/dispute-distribution/src/tests/mock.rs b/polkadot/node/network/dispute-distribution/src/tests/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..e6a49f14c094c9ce98030dda76f1ea2baf88ec87 --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/tests/mock.rs @@ -0,0 +1,235 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +// + +//! Mock data and utility functions for unit tests in this subsystem. + +use std::{ + collections::{HashMap, HashSet}, + sync::Arc, + time::Instant, +}; + +use async_trait::async_trait; +use lazy_static::lazy_static; + +use polkadot_node_network_protocol::{authority_discovery::AuthorityDiscovery, PeerId}; +use sc_keystore::LocalKeystore; +use sp_application_crypto::AppCrypto; +use sp_keyring::Sr25519Keyring; +use sp_keystore::{Keystore, KeystorePtr}; + +use polkadot_node_primitives::{DisputeMessage, SignedDisputeStatement}; +use polkadot_primitives::{ + AuthorityDiscoveryId, CandidateHash, CandidateReceipt, Hash, SessionIndex, SessionInfo, + ValidatorId, ValidatorIndex, +}; +use polkadot_primitives_test_helpers::dummy_candidate_descriptor; + +use crate::LOG_TARGET; + +pub const MOCK_SESSION_INDEX: SessionIndex = 1; +pub const MOCK_NEXT_SESSION_INDEX: SessionIndex = 2; +pub const MOCK_VALIDATORS: [Sr25519Keyring; 6] = [ + Sr25519Keyring::Ferdie, + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, +]; + +pub const MOCK_AUTHORITIES_NEXT_SESSION: [Sr25519Keyring; 2] = + [Sr25519Keyring::One, Sr25519Keyring::Two]; + +pub const FERDIE_INDEX: ValidatorIndex = ValidatorIndex(0); +pub const ALICE_INDEX: ValidatorIndex = ValidatorIndex(1); +pub const BOB_INDEX: ValidatorIndex = ValidatorIndex(2); +pub const CHARLIE_INDEX: ValidatorIndex = ValidatorIndex(3); + +lazy_static! { + +/// Mocked `AuthorityDiscovery` service. +pub static ref MOCK_AUTHORITY_DISCOVERY: MockAuthorityDiscovery = MockAuthorityDiscovery::new(); +// Creating an innocent looking `SessionInfo` is really expensive in a debug build. Around +// 700ms on my machine, We therefore cache those keys here: +pub static ref MOCK_VALIDATORS_DISCOVERY_KEYS: HashMap = + MOCK_VALIDATORS + .iter() + .chain(MOCK_AUTHORITIES_NEXT_SESSION.iter()) + .map(|v| (*v, v.public().into())) + .collect() +; +pub static ref FERDIE_DISCOVERY_KEY: AuthorityDiscoveryId = + MOCK_VALIDATORS_DISCOVERY_KEYS.get(&Sr25519Keyring::Ferdie).unwrap().clone(); + +pub static ref MOCK_SESSION_INFO: SessionInfo = + SessionInfo { + validators: MOCK_VALIDATORS.iter().take(4).map(|k| k.public().into()).collect(), + discovery_keys: MOCK_VALIDATORS + .iter() + .map(|k| MOCK_VALIDATORS_DISCOVERY_KEYS.get(&k).unwrap().clone()) + .collect(), + assignment_keys: vec![], + validator_groups: Default::default(), + n_cores: 0, + zeroth_delay_tranche_width: 0, + relay_vrf_modulo_samples: 0, + n_delay_tranches: 0, + no_show_slots: 0, + needed_approvals: 0, + active_validator_indices: vec![], + dispute_period: 6, + random_seed: [0u8; 32], + }; + +/// `SessionInfo` for the second session. (No more validators, but two more authorities. +pub static ref MOCK_NEXT_SESSION_INFO: SessionInfo = + SessionInfo { + discovery_keys: + MOCK_AUTHORITIES_NEXT_SESSION + .iter() + .map(|k| MOCK_VALIDATORS_DISCOVERY_KEYS.get(&k).unwrap().clone()) + .collect(), + validators: Default::default(), + assignment_keys: vec![], + validator_groups: Default::default(), + n_cores: 0, + zeroth_delay_tranche_width: 0, + relay_vrf_modulo_samples: 0, + n_delay_tranches: 0, + no_show_slots: 0, + needed_approvals: 0, + active_validator_indices: vec![], + dispute_period: 6, + random_seed: [0u8; 32], + }; +} + +pub fn make_candidate_receipt(relay_parent: Hash) -> CandidateReceipt { + CandidateReceipt { + descriptor: dummy_candidate_descriptor(relay_parent), + commitments_hash: Hash::random(), + } +} + +pub fn make_explicit_signed( + validator: Sr25519Keyring, + candidate_hash: CandidateHash, + valid: bool, +) -> SignedDisputeStatement { + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + Keystore::sr25519_generate_new(&*keystore, ValidatorId::ID, Some(&validator.to_seed())) + .expect("Insert key into keystore"); + + SignedDisputeStatement::sign_explicit( + &keystore, + valid, + candidate_hash, + MOCK_SESSION_INDEX, + validator.public().into(), + ) + .expect("Keystore should be fine.") + .expect("Signing should work.") +} + +pub fn make_dispute_message( + candidate: CandidateReceipt, + valid_validator: ValidatorIndex, + invalid_validator: ValidatorIndex, +) -> DisputeMessage { + let candidate_hash = candidate.hash(); + let before_request = Instant::now(); + let valid_vote = + make_explicit_signed(MOCK_VALIDATORS[valid_validator.0 as usize], candidate_hash, true); + gum::trace!( + "Passed time for valid vote: {:#?}", + Instant::now().saturating_duration_since(before_request) + ); + let before_request = Instant::now(); + let invalid_vote = + make_explicit_signed(MOCK_VALIDATORS[invalid_validator.0 as usize], candidate_hash, false); + gum::trace!( + "Passed time for invald vote: {:#?}", + Instant::now().saturating_duration_since(before_request) + ); + DisputeMessage::from_signed_statements( + valid_vote, + valid_validator, + invalid_vote, + invalid_validator, + candidate, + &MOCK_SESSION_INFO, + ) + .expect("DisputeMessage construction should work.") +} + +/// Dummy `AuthorityDiscovery` service. +#[derive(Debug, Clone)] +pub struct MockAuthorityDiscovery { + peer_ids: HashMap, +} + +impl MockAuthorityDiscovery { + pub fn new() -> Self { + let mut peer_ids = HashMap::new(); + peer_ids.insert(Sr25519Keyring::Alice, PeerId::random()); + peer_ids.insert(Sr25519Keyring::Bob, PeerId::random()); + peer_ids.insert(Sr25519Keyring::Ferdie, PeerId::random()); + peer_ids.insert(Sr25519Keyring::Charlie, PeerId::random()); + peer_ids.insert(Sr25519Keyring::Dave, PeerId::random()); + peer_ids.insert(Sr25519Keyring::Eve, PeerId::random()); + peer_ids.insert(Sr25519Keyring::One, PeerId::random()); + peer_ids.insert(Sr25519Keyring::Two, PeerId::random()); + + Self { peer_ids } + } + + pub fn get_peer_id_by_authority(&self, authority: Sr25519Keyring) -> PeerId { + *self.peer_ids.get(&authority).expect("Tester only picks valid authorities") + } +} + +#[async_trait] +impl AuthorityDiscovery for MockAuthorityDiscovery { + async fn get_addresses_by_authority_id( + &mut self, + _authority: polkadot_primitives::AuthorityDiscoveryId, + ) -> Option> { + panic!("Not implemented"); + } + + async fn get_authority_ids_by_peer_id( + &mut self, + peer_id: polkadot_node_network_protocol::PeerId, + ) -> Option> { + for (a, p) in self.peer_ids.iter() { + if p == &peer_id { + let result = + HashSet::from([MOCK_VALIDATORS_DISCOVERY_KEYS.get(&a).unwrap().clone()]); + gum::trace!( + target: LOG_TARGET, + %peer_id, + ?result, + "Returning authority ids for peer id" + ); + return Some(result) + } + } + + None + } +} diff --git a/polkadot/node/network/dispute-distribution/src/tests/mod.rs b/polkadot/node/network/dispute-distribution/src/tests/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..bc8e8e8be16059ddd3c4a9ae1bda4b5aa449dbff --- /dev/null +++ b/polkadot/node/network/dispute-distribution/src/tests/mod.rs @@ -0,0 +1,867 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +// + +//! Subsystem unit tests + +use std::{ + collections::HashSet, + sync::Arc, + task::Poll, + time::{Duration, Instant}, +}; + +use assert_matches::assert_matches; +use futures::{ + channel::oneshot, + future::{poll_fn, ready}, + pin_mut, Future, +}; +use futures_timer::Delay; +use parity_scale_codec::{Decode, Encode}; + +use sc_network::config::RequestResponseConfig; + +use polkadot_node_network_protocol::{ + request_response::{v1::DisputeRequest, IncomingRequest, ReqProtocolNames}, + PeerId, +}; +use sp_keyring::Sr25519Keyring; + +use polkadot_node_network_protocol::{ + request_response::{v1::DisputeResponse, Recipient, Requests}, + IfDisconnected, +}; +use polkadot_node_primitives::DisputeStatus; +use polkadot_node_subsystem::{ + messages::{ + AllMessages, DisputeCoordinatorMessage, DisputeDistributionMessage, ImportStatementsResult, + NetworkBridgeTxMessage, RuntimeApiMessage, RuntimeApiRequest, + }, + ActivatedLeaf, ActiveLeavesUpdate, FromOrchestra, LeafStatus, OverseerSignal, Span, +}; +use polkadot_node_subsystem_test_helpers::{ + mock::make_ferdie_keystore, subsystem_test_harness, TestSubsystemContextHandle, +}; +use polkadot_primitives::{ + AuthorityDiscoveryId, CandidateHash, CandidateReceipt, Hash, SessionIndex, SessionInfo, +}; + +use self::mock::{ + make_candidate_receipt, make_dispute_message, ALICE_INDEX, FERDIE_DISCOVERY_KEY, FERDIE_INDEX, + MOCK_AUTHORITY_DISCOVERY, MOCK_NEXT_SESSION_INDEX, MOCK_NEXT_SESSION_INFO, MOCK_SESSION_INDEX, + MOCK_SESSION_INFO, +}; +use crate::{ + receiver::BATCH_COLLECTING_INTERVAL, + tests::mock::{BOB_INDEX, CHARLIE_INDEX}, + DisputeDistributionSubsystem, Metrics, LOG_TARGET, SEND_RATE_LIMIT, +}; + +/// Useful mock providers. +pub mod mock; + +#[test] +fn send_dispute_sends_dispute() { + let test = |mut handle: TestSubsystemContextHandle, _req_cfg| async move { + let _ = handle_subsystem_startup(&mut handle, None).await; + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + send_dispute(&mut handle, candidate).await; + conclude(&mut handle).await; + }; + test_harness(test); +} + +#[test] +fn send_honors_rate_limit() { + sp_tracing::try_init_simple(); + let test = |mut handle: TestSubsystemContextHandle, _req_cfg| async move { + let _ = handle_subsystem_startup(&mut handle, None).await; + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + let before_request = Instant::now(); + send_dispute(&mut handle, candidate).await; + // First send should not be rate limited: + gum::trace!("Passed time: {:#?}", Instant::now().saturating_duration_since(before_request)); + // This test would likely be flaky on CI: + //assert!(Instant::now().saturating_duration_since(before_request) < SEND_RATE_LIMIT); + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + send_dispute(&mut handle, candidate).await; + // Second send should be rate limited: + gum::trace!( + "Passed time for send_dispute: {:#?}", + Instant::now().saturating_duration_since(before_request) + ); + assert!(Instant::now() - before_request >= SEND_RATE_LIMIT); + conclude(&mut handle).await; + }; + test_harness(test); +} + +/// Helper for sending a new dispute to dispute-distribution sender and handling resulting messages. +async fn send_dispute( + handle: &mut TestSubsystemContextHandle, + candidate: CandidateReceipt, +) { + let before_request = Instant::now(); + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX); + gum::trace!( + "Passed time for making message: {:#?}", + Instant::now().saturating_duration_since(before_request) + ); + let before_request = Instant::now(); + handle + .send(FromOrchestra::Communication { + msg: DisputeDistributionMessage::SendDispute(message.clone()), + }) + .await; + gum::trace!( + "Passed time for sending message: {:#?}", + Instant::now().saturating_duration_since(before_request) + ); + + let expected_receivers = { + let info = &MOCK_SESSION_INFO; + info.discovery_keys + .clone() + .into_iter() + .filter(|a| a != &Sr25519Keyring::Ferdie.public().into()) + .collect() + // All validators are also authorities in the first session, so we are + // done here. + }; + check_sent_requests(handle, expected_receivers, true).await; +} + +// Things to test: +// x Request triggers import +// x Subsequent imports get batched +// x Batch gets flushed. +// x Batch gets renewed. +// x Non authority requests get dropped. +// x Sending rate limit is honored. +// x Receiving rate limit is honored. +// x Duplicate requests on batch are dropped + +#[test] +fn received_non_authorities_are_dropped() { + let test = |mut handle: TestSubsystemContextHandle, + mut req_cfg: RequestResponseConfig| async move { + let req_tx = req_cfg.inbound_queue.as_mut().unwrap(); + let _ = handle_subsystem_startup(&mut handle, None).await; + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX); + + // Non validator request should get dropped: + let rx_response = + send_network_dispute_request(req_tx, PeerId::random(), message.clone().into()).await; + + assert_matches!( + rx_response.await, + Ok(resp) => { + let sc_network::config::OutgoingResponse { + result: _, + reputation_changes, + sent_feedback: _, + } = resp; + // Peer should get punished: + assert_eq!(reputation_changes.len(), 1); + } + ); + conclude(&mut handle).await; + }; + test_harness(test); +} + +#[test] +fn received_request_triggers_import() { + let test = |mut handle: TestSubsystemContextHandle, + mut req_cfg: RequestResponseConfig| async move { + let req_tx = req_cfg.inbound_queue.as_mut().unwrap(); + let _ = handle_subsystem_startup(&mut handle, None).await; + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX); + + nested_network_dispute_request( + &mut handle, + req_tx, + MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Alice), + message.clone().into(), + ImportStatementsResult::ValidImport, + true, + move |_handle, _req_tx, _message| ready(()), + ) + .await; + + gum::trace!(target: LOG_TARGET, "Concluding."); + conclude(&mut handle).await; + }; + test_harness(test); +} + +#[test] +fn batching_works() { + let test = |mut handle: TestSubsystemContextHandle, + mut req_cfg: RequestResponseConfig| async move { + let req_tx = req_cfg.inbound_queue.as_mut().unwrap(); + let _ = handle_subsystem_startup(&mut handle, None).await; + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX); + + // Initial request should get forwarded immediately: + nested_network_dispute_request( + &mut handle, + req_tx, + MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Alice), + message.clone().into(), + ImportStatementsResult::ValidImport, + true, + move |_handle, _req_tx, _message| ready(()), + ) + .await; + + let mut rx_responses = Vec::new(); + + let message = make_dispute_message(candidate.clone(), BOB_INDEX, FERDIE_INDEX); + let peer = MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Bob); + rx_responses.push(send_network_dispute_request(req_tx, peer, message.clone().into()).await); + + let message = make_dispute_message(candidate.clone(), CHARLIE_INDEX, FERDIE_INDEX); + let peer = MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Charlie); + rx_responses.push(send_network_dispute_request(req_tx, peer, message.clone().into()).await); + gum::trace!("Imported 3 votes into batch"); + + Delay::new(BATCH_COLLECTING_INTERVAL); + gum::trace!("Batch should still be alive"); + // Batch should still be alive (2 new votes): + // Let's import two more votes, but fully duplicates - should not extend batch live. + gum::trace!("Importing duplicate votes"); + let mut rx_responses_duplicate = Vec::new(); + let message = make_dispute_message(candidate.clone(), BOB_INDEX, FERDIE_INDEX); + let peer = MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Bob); + rx_responses_duplicate + .push(send_network_dispute_request(req_tx, peer, message.clone().into()).await); + + let message = make_dispute_message(candidate.clone(), CHARLIE_INDEX, FERDIE_INDEX); + let peer = MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Charlie); + rx_responses_duplicate + .push(send_network_dispute_request(req_tx, peer, message.clone().into()).await); + + for rx_response in rx_responses_duplicate { + assert_matches!( + rx_response.await, + Ok(resp) => { + let sc_network::config::OutgoingResponse { + result, + reputation_changes, + sent_feedback: _, + } = resp; + gum::trace!( + target: LOG_TARGET, + ?reputation_changes, + "Received reputation changes." + ); + // We don't punish on that. + assert_eq!(reputation_changes.len(), 0); + + assert_matches!(result, Err(())); + } + ); + } + + Delay::new(BATCH_COLLECTING_INTERVAL).await; + gum::trace!("Batch should be ready now (only duplicates have been added)"); + + let pending_confirmation = assert_matches!( + handle.recv().await, + AllMessages::DisputeCoordinator( + DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: _, + session, + statements, + pending_confirmation: Some(pending_confirmation), + } + ) => { + assert_eq!(session, MOCK_SESSION_INDEX); + assert_eq!(statements.len(), 3); + pending_confirmation + } + ); + pending_confirmation.send(ImportStatementsResult::ValidImport).unwrap(); + + for rx_response in rx_responses { + assert_matches!( + rx_response.await, + Ok(resp) => { + let sc_network::config::OutgoingResponse { + result, + reputation_changes: _, + sent_feedback, + } = resp; + + let result = result.unwrap(); + let decoded = + ::decode(&mut result.as_slice()).unwrap(); + + assert!(decoded == DisputeResponse::Confirmed); + if let Some(sent_feedback) = sent_feedback { + sent_feedback.send(()).unwrap(); + } + gum::trace!( + target: LOG_TARGET, + "Valid import happened." + ); + + } + ); + } + + gum::trace!(target: LOG_TARGET, "Concluding."); + conclude(&mut handle).await; + }; + test_harness(test); +} + +#[test] +fn receive_rate_limit_is_enforced() { + let test = |mut handle: TestSubsystemContextHandle, + mut req_cfg: RequestResponseConfig| async move { + let req_tx = req_cfg.inbound_queue.as_mut().unwrap(); + let _ = handle_subsystem_startup(&mut handle, None).await; + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX); + + // Initial request should get forwarded immediately: + nested_network_dispute_request( + &mut handle, + req_tx, + MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Alice), + message.clone().into(), + ImportStatementsResult::ValidImport, + true, + move |_handle, _req_tx, _message| ready(()), + ) + .await; + + let mut rx_responses = Vec::new(); + + let peer = MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Bob); + + let message = make_dispute_message(candidate.clone(), BOB_INDEX, FERDIE_INDEX); + rx_responses.push(send_network_dispute_request(req_tx, peer, message.clone().into()).await); + + let message = make_dispute_message(candidate.clone(), CHARLIE_INDEX, FERDIE_INDEX); + rx_responses.push(send_network_dispute_request(req_tx, peer, message.clone().into()).await); + + gum::trace!("Import one too much:"); + + let message = make_dispute_message(candidate.clone(), CHARLIE_INDEX, ALICE_INDEX); + let rx_response_flood = + send_network_dispute_request(req_tx, peer, message.clone().into()).await; + + assert_matches!( + rx_response_flood.await, + Ok(resp) => { + let sc_network::config::OutgoingResponse { + result: _, + reputation_changes, + sent_feedback: _, + } = resp; + gum::trace!( + target: LOG_TARGET, + ?reputation_changes, + "Received reputation changes." + ); + // Received punishment for flood: + assert_eq!(reputation_changes.len(), 1); + } + ); + gum::trace!("Need to wait 2 patch intervals:"); + Delay::new(BATCH_COLLECTING_INTERVAL).await; + Delay::new(BATCH_COLLECTING_INTERVAL).await; + + gum::trace!("Batch should be ready now"); + + let pending_confirmation = assert_matches!( + handle.recv().await, + AllMessages::DisputeCoordinator( + DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: _, + session, + statements, + pending_confirmation: Some(pending_confirmation), + } + ) => { + assert_eq!(session, MOCK_SESSION_INDEX); + // Only 3 as fourth was flood: + assert_eq!(statements.len(), 3); + pending_confirmation + } + ); + pending_confirmation.send(ImportStatementsResult::ValidImport).unwrap(); + + for rx_response in rx_responses { + assert_matches!( + rx_response.await, + Ok(resp) => { + let sc_network::config::OutgoingResponse { + result, + reputation_changes: _, + sent_feedback, + } = resp; + + let result = result.unwrap(); + let decoded = + ::decode(&mut result.as_slice()).unwrap(); + + assert!(decoded == DisputeResponse::Confirmed); + if let Some(sent_feedback) = sent_feedback { + sent_feedback.send(()).unwrap(); + } + gum::trace!( + target: LOG_TARGET, + "Valid import happened." + ); + + } + ); + } + + gum::trace!(target: LOG_TARGET, "Concluding."); + conclude(&mut handle).await; + }; + test_harness(test); +} + +#[test] +fn send_dispute_gets_cleaned_up() { + let test = |mut handle: TestSubsystemContextHandle, _| async move { + let old_head = handle_subsystem_startup(&mut handle, None).await; + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX); + handle + .send(FromOrchestra::Communication { + msg: DisputeDistributionMessage::SendDispute(message.clone()), + }) + .await; + + let expected_receivers = { + let info = &MOCK_SESSION_INFO; + info.discovery_keys + .clone() + .into_iter() + .filter(|a| a != &Sr25519Keyring::Ferdie.public().into()) + .collect() + // All validators are also authorities in the first session, so we are + // done here. + }; + check_sent_requests(&mut handle, expected_receivers, false).await; + + // Give tasks a chance to finish: + Delay::new(Duration::from_millis(20)).await; + + activate_leaf( + &mut handle, + Hash::random(), + Some(old_head), + MOCK_SESSION_INDEX, + None, + // No disputes any more: + Vec::new(), + ) + .await; + + // Yield, so subsystem can make progress: + Delay::new(Duration::from_millis(2)).await; + + conclude(&mut handle).await; + }; + test_harness(test); +} + +#[test] +fn dispute_retries_and_works_across_session_boundaries() { + sp_tracing::try_init_simple(); + let test = |mut handle: TestSubsystemContextHandle, _| async move { + let old_head = handle_subsystem_startup(&mut handle, None).await; + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX); + handle + .send(FromOrchestra::Communication { + msg: DisputeDistributionMessage::SendDispute(message.clone()), + }) + .await; + + let expected_receivers: HashSet<_> = { + let info = &MOCK_SESSION_INFO; + info.discovery_keys + .clone() + .into_iter() + .filter(|a| a != &Sr25519Keyring::Ferdie.public().into()) + .collect() + // All validators are also authorities in the first session, so we are + // done here. + }; + // Requests don't get confirmed - dispute is carried over to next session. + check_sent_requests(&mut handle, expected_receivers.clone(), false).await; + + // Give tasks a chance to finish: + Delay::new(Duration::from_millis(20)).await; + + // Trigger retry: + let old_head2 = Hash::random(); + activate_leaf( + &mut handle, + old_head2, + Some(old_head), + MOCK_SESSION_INDEX, + None, + vec![(MOCK_SESSION_INDEX, candidate.hash(), DisputeStatus::Active)], + ) + .await; + + check_sent_requests(&mut handle, expected_receivers.clone(), false).await; + // Give tasks a chance to finish: + Delay::new(Duration::from_millis(20)).await; + + // Session change: + activate_leaf( + &mut handle, + Hash::random(), + Some(old_head2), + MOCK_NEXT_SESSION_INDEX, + Some(MOCK_NEXT_SESSION_INFO.clone()), + vec![(MOCK_SESSION_INDEX, candidate.hash(), DisputeStatus::Active)], + ) + .await; + + let expected_receivers = { + let validator_count = MOCK_SESSION_INFO.validators.len(); + let old_validators = MOCK_SESSION_INFO + .discovery_keys + .clone() + .into_iter() + .take(validator_count) + .filter(|a| *a != *FERDIE_DISCOVERY_KEY); + + MOCK_NEXT_SESSION_INFO + .discovery_keys + .clone() + .into_iter() + .filter(|a| *a != *FERDIE_DISCOVERY_KEY) + .chain(old_validators) + .collect() + }; + check_sent_requests(&mut handle, expected_receivers, true).await; + + conclude(&mut handle).await; + }; + test_harness(test); +} + +async fn send_network_dispute_request( + req_tx: &mut async_channel::Sender, + peer: PeerId, + message: DisputeRequest, +) -> oneshot::Receiver { + let (pending_response, rx_response) = oneshot::channel(); + let req = + sc_network::config::IncomingRequest { peer, payload: message.encode(), pending_response }; + req_tx.send(req).await.unwrap(); + rx_response +} + +/// Send request and handle its reactions. +/// +/// Passed in function will be called while votes are still being imported. +async fn nested_network_dispute_request<'a, F, O>( + handle: &'a mut TestSubsystemContextHandle, + req_tx: &'a mut async_channel::Sender, + peer: PeerId, + message: DisputeRequest, + import_result: ImportStatementsResult, + need_session_info: bool, + inner: F, +) where + F: FnOnce( + &'a mut TestSubsystemContextHandle, + &'a mut async_channel::Sender, + DisputeRequest, + ) -> O + + 'a, + O: Future + 'a, +{ + let rx_response = send_network_dispute_request(req_tx, peer, message.clone().into()).await; + + if need_session_info { + // Subsystem might need `SessionInfo` for determining indices: + match handle.recv().await { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionInfo(_, tx), + )) => { + tx.send(Ok(Some(MOCK_SESSION_INFO.clone()))) + .expect("Receiver should stay alive."); + }, + unexpected => panic!("Unexpected message {:?}", unexpected), + } + } + + // Import should get initiated: + let pending_confirmation = assert_matches!( + handle.recv().await, + AllMessages::DisputeCoordinator( + DisputeCoordinatorMessage::ImportStatements { + candidate_receipt, + session, + statements, + pending_confirmation: Some(pending_confirmation), + } + ) => { + let candidate_hash = candidate_receipt.hash(); + assert_eq!(session, MOCK_SESSION_INDEX); + assert_eq!(candidate_hash, message.0.candidate_receipt.hash()); + assert_eq!(statements.len(), 2); + pending_confirmation + } + ); + + // Do the inner thing: + inner(handle, req_tx, message).await; + + // Confirm import + pending_confirmation.send(import_result).unwrap(); + + assert_matches!( + rx_response.await, + Ok(resp) => { + let sc_network::config::OutgoingResponse { + result, + reputation_changes, + sent_feedback, + } = resp; + + match import_result { + ImportStatementsResult::ValidImport => { + let result = result.unwrap(); + let decoded = + ::decode(&mut result.as_slice()).unwrap(); + + assert!(decoded == DisputeResponse::Confirmed); + if let Some(sent_feedback) = sent_feedback { + sent_feedback.send(()).unwrap(); + } + gum::trace!( + target: LOG_TARGET, + "Valid import happened." + ); + + } + ImportStatementsResult::InvalidImport => { + // Peer should get punished: + assert_eq!(reputation_changes.len(), 1); + } + } + } + ); +} + +async fn conclude(handle: &mut TestSubsystemContextHandle) { + // No more messages should be in the queue: + poll_fn(|ctx| { + let fut = handle.recv(); + pin_mut!(fut); + // No requests should be initiated, as there is no longer any dispute active: + assert_matches!(fut.poll(ctx), Poll::Pending, "No requests expected"); + Poll::Ready(()) + }) + .await; + + handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; +} + +/// Pass a `new_session` if you expect the subsystem to retrieve `SessionInfo` when given the +/// `session_index`. +async fn activate_leaf( + handle: &mut TestSubsystemContextHandle, + activate: Hash, + deactivate: Option, + session_index: SessionIndex, + // New session if we expect the subsystem to request it. + new_session: Option, + // Currently active disputes to send to the subsystem. + active_disputes: Vec<(SessionIndex, CandidateHash, DisputeStatus)>, +) { + handle + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: activate, + number: 10, + status: LeafStatus::Fresh, + span: Arc::new(Span::Disabled), + }), + deactivated: deactivate.into_iter().collect(), + }))) + .await; + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::SessionIndexForChild(tx) + )) => { + assert_eq!(h, activate); + tx.send(Ok(session_index)).expect("Receiver should stay alive."); + } + ); + + if let Some(session_info) = new_session { + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + h, + RuntimeApiRequest::SessionInfo(session_idx, tx) + )) => { + assert_eq!(h, activate); + assert_eq!(session_index, session_idx); + tx.send(Ok(Some(session_info))).expect("Receiver should stay alive."); + }); + } + + assert_matches!( + handle.recv().await, + AllMessages::DisputeCoordinator(DisputeCoordinatorMessage::ActiveDisputes(tx)) => { + tx.send(active_disputes).expect("Receiver should stay alive."); + } + ); +} + +/// Check whether sent network bridge requests match the expectation. +async fn check_sent_requests( + handle: &mut TestSubsystemContextHandle, + expected_receivers: HashSet, + confirm_receive: bool, +) { + let expected_receivers: HashSet<_> = + expected_receivers.into_iter().map(Recipient::Authority).collect(); + + // Sends to concerned validators: + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests(reqs, IfDisconnected::ImmediateError) + ) => { + let reqs: Vec<_> = reqs.into_iter().map(|r| + assert_matches!( + r, + Requests::DisputeSendingV1(req) => {req} + ) + ) + .collect(); + + let receivers_raw: Vec<_> = reqs.iter().map(|r| r.peer.clone()).collect(); + let receivers: HashSet<_> = receivers_raw.clone().clone().into_iter().collect(); + assert_eq!(receivers_raw.len(), receivers.len(), "No duplicates are expected."); + assert_eq!(receivers.len(), expected_receivers.len()); + assert_eq!(receivers, expected_receivers); + if confirm_receive { + for req in reqs { + req.pending_response.send( + Ok(DisputeResponse::Confirmed.encode()) + ) + .expect("Subsystem should be listening for a response."); + } + } + } + ); +} + +/// Initialize subsystem and return request sender needed for sending incoming requests to the +/// subsystem. +async fn handle_subsystem_startup( + handle: &mut TestSubsystemContextHandle, + ongoing_dispute: Option, +) -> Hash { + let relay_parent = Hash::random(); + activate_leaf( + handle, + relay_parent, + None, + MOCK_SESSION_INDEX, + Some(MOCK_SESSION_INFO.clone()), + ongoing_dispute + .into_iter() + .map(|c| (MOCK_SESSION_INDEX, c, DisputeStatus::Active)) + .collect(), + ) + .await; + relay_parent +} + +/// Launch subsystem and provided test function +/// +/// which simulates the overseer. +fn test_harness(test: TestFn) +where + TestFn: FnOnce( + TestSubsystemContextHandle, + RequestResponseConfig, + ) -> Fut, + Fut: Future, +{ + sp_tracing::try_init_simple(); + let keystore = make_ferdie_keystore(); + + let genesis_hash = Hash::repeat_byte(0xff); + let req_protocol_names = ReqProtocolNames::new(&genesis_hash, None); + let (req_receiver, req_cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); + let subsystem = DisputeDistributionSubsystem::new( + keystore, + req_receiver, + MOCK_AUTHORITY_DISCOVERY.clone(), + Metrics::new_dummy(), + ); + + let subsystem = |ctx| async { + match subsystem.run(ctx).await { + Ok(()) => {}, + Err(fatal) => { + gum::debug!( + target: LOG_TARGET, + ?fatal, + "Dispute distribution exited with fatal error." + ); + }, + } + }; + subsystem_test_harness(|handle| test(handle, req_cfg), subsystem); +} diff --git a/polkadot/node/network/gossip-support/Cargo.toml b/polkadot/node/network/gossip-support/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..782213f622cc64b09bdc0b4b8258031e85b5d2f8 --- /dev/null +++ b/polkadot/node/network/gossip-support/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "polkadot-gossip-support" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network-common = { git = "https://github.com/paritytech/substrate", branch = "master" } + +polkadot-node-network-protocol = { path = "../protocol" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-primitives = { path = "../../../primitives" } + +futures = "0.3.21" +futures-timer = "3.0.2" +rand = { version = "0.8.5", default-features = false } +rand_chacha = { version = "0.3.1", default-features = false } +gum = { package = "tracing-gum", path = "../../gum" } + +[dev-dependencies] +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } + +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } + +assert_matches = "1.4.0" +async-trait = "0.1.57" +lazy_static = "1.4.0" diff --git a/polkadot/node/network/gossip-support/src/lib.rs b/polkadot/node/network/gossip-support/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..c5dc1ba14bd35b5127ff27c0c3d0732e0e56178c --- /dev/null +++ b/polkadot/node/network/gossip-support/src/lib.rs @@ -0,0 +1,640 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This subsystem is responsible for keeping track of session changes +//! and issuing a connection request to the relevant validators +//! on every new session. +//! +//! In addition to that, it creates a gossip overlay topology +//! which limits the amount of messages sent and received +//! to be an order of sqrt of the validators. Our neighbors +//! in this graph will be forwarded to the network bridge with +//! the `NetworkBridgeRxMessage::NewGossipTopology` message. + +use std::{ + collections::{HashMap, HashSet}, + fmt, + time::{Duration, Instant}, +}; + +use futures::{channel::oneshot, select, FutureExt as _}; +use futures_timer::Delay; +use rand::{seq::SliceRandom as _, SeedableRng}; +use rand_chacha::ChaCha20Rng; + +use sc_network::{config::parse_addr, Multiaddr}; +use sp_application_crypto::{AppCrypto, ByteArray}; +use sp_keystore::{Keystore, KeystorePtr}; + +use polkadot_node_network_protocol::{ + authority_discovery::AuthorityDiscovery, peer_set::PeerSet, GossipSupportNetworkMessage, + PeerId, Versioned, +}; +use polkadot_node_subsystem::{ + messages::{ + GossipSupportMessage, NetworkBridgeEvent, NetworkBridgeRxMessage, NetworkBridgeTxMessage, + RuntimeApiMessage, RuntimeApiRequest, + }, + overseer, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, +}; +use polkadot_node_subsystem_util as util; +use polkadot_primitives::{AuthorityDiscoveryId, Hash, SessionIndex, SessionInfo, ValidatorIndex}; + +#[cfg(test)] +mod tests; + +mod metrics; + +use metrics::Metrics; + +const LOG_TARGET: &str = "parachain::gossip-support"; +// How much time should we wait to reissue a connection request +// since the last authority discovery resolution failure. +const BACKOFF_DURATION: Duration = Duration::from_secs(5); + +/// Duration after which we consider low connectivity a problem. +/// +/// Especially at startup low connectivity is expected (authority discovery cache needs to be +/// populated). Authority discovery on Kusama takes around 8 minutes, so warning after 10 minutes +/// should be fine: +/// +/// https://github.com/paritytech/substrate/blob/fc49802f263529160635471c8a17888846035f5d/client/authority-discovery/src/lib.rs#L88 +const LOW_CONNECTIVITY_WARN_DELAY: Duration = Duration::from_secs(600); + +/// If connectivity is lower than this in percent, issue warning in logs. +const LOW_CONNECTIVITY_WARN_THRESHOLD: usize = 90; + +/// The Gossip Support subsystem. +pub struct GossipSupport { + keystore: KeystorePtr, + + last_session_index: Option, + // Some(timestamp) if we failed to resolve + // at least a third of authorities the last time. + // `None` otherwise. + last_failure: Option, + + /// First time we did not reach our connectivity threshold. + /// + /// This is the time of the first failed attempt to connect to >2/3 of all validators in a + /// potential sequence of failed attempts. It will be cleared once we reached >2/3 + /// connectivity. + failure_start: Option, + + /// Successfully resolved connections + /// + /// waiting for actual connection. + resolved_authorities: HashMap>, + + /// Actually connected authorities. + connected_authorities: HashMap, + /// By `PeerId`. + /// + /// Needed for efficient handling of disconnect events. + connected_authorities_by_peer_id: HashMap>, + /// Authority discovery service. + authority_discovery: AD, + + /// Subsystem metrics. + metrics: Metrics, +} + +#[overseer::contextbounds(GossipSupport, prefix = self::overseer)] +impl GossipSupport +where + AD: AuthorityDiscovery, +{ + /// Create a new instance of the [`GossipSupport`] subsystem. + pub fn new(keystore: KeystorePtr, authority_discovery: AD, metrics: Metrics) -> Self { + // Initialize metrics to `0`. + metrics.on_is_not_authority(); + metrics.on_is_not_parachain_validator(); + + Self { + keystore, + last_session_index: None, + last_failure: None, + failure_start: None, + resolved_authorities: HashMap::new(), + connected_authorities: HashMap::new(), + connected_authorities_by_peer_id: HashMap::new(), + authority_discovery, + metrics, + } + } + + async fn run(mut self, mut ctx: Context) -> Self { + fn get_connectivity_check_delay() -> Delay { + Delay::new(LOW_CONNECTIVITY_WARN_DELAY) + } + let mut next_connectivity_check = get_connectivity_check_delay().fuse(); + loop { + let message = select!( + _ = next_connectivity_check => { + self.check_connectivity(); + next_connectivity_check = get_connectivity_check_delay().fuse(); + continue + } + result = ctx.recv().fuse() => + match result { + Ok(message) => message, + Err(e) => { + gum::debug!( + target: LOG_TARGET, + err = ?e, + "Failed to receive a message from Overseer, exiting", + ); + return self + }, + } + ); + match message { + FromOrchestra::Communication { + msg: GossipSupportMessage::NetworkBridgeUpdate(ev), + } => self.handle_connect_disconnect(ev), + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated, + .. + })) => { + gum::trace!(target: LOG_TARGET, "active leaves signal"); + + let leaves = activated.into_iter().map(|a| a.hash); + if let Err(e) = self.handle_active_leaves(ctx.sender(), leaves).await { + gum::debug!(target: LOG_TARGET, error = ?e); + } + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(_hash, _number)) => {}, + FromOrchestra::Signal(OverseerSignal::Conclude) => return self, + } + } + } + + /// 1. Determine if the current session index has changed. + /// 2. If it has, determine relevant validators and issue a connection request. + async fn handle_active_leaves( + &mut self, + sender: &mut impl overseer::GossipSupportSenderTrait, + leaves: impl Iterator, + ) -> Result<(), util::Error> { + for leaf in leaves { + let current_index = util::request_session_index_for_child(leaf, sender).await.await??; + let since_failure = self.last_failure.map(|i| i.elapsed()).unwrap_or_default(); + let force_request = since_failure >= BACKOFF_DURATION; + let leaf_session = Some((current_index, leaf)); + let maybe_new_session = match self.last_session_index { + Some(i) if current_index <= i => None, + _ => leaf_session, + }; + + let maybe_issue_connection = + if force_request { leaf_session } else { maybe_new_session }; + + if let Some((session_index, relay_parent)) = maybe_issue_connection { + let session_info = + util::request_session_info(leaf, session_index, sender).await.await??; + + let session_info = match session_info { + Some(s) => s, + None => { + gum::warn!( + relay_parent = ?leaf, + session_index = self.last_session_index, + "Failed to get session info.", + ); + + continue + }, + }; + + // Note: we only update `last_session_index` once we've + // successfully gotten the `SessionInfo`. + let is_new_session = maybe_new_session.is_some(); + if is_new_session { + gum::debug!( + target: LOG_TARGET, + %session_index, + "New session detected", + ); + self.last_session_index = Some(session_index); + } + + // Connect to authorities from the past/present/future. + // + // This is maybe not the right place for this logic to live, + // but at the moment we're limited by the network bridge's ability + // to handle connection requests (it only allows one, globally). + // + // Certain network protocols - mostly req/res, but some gossip, + // will require being connected to past/future validators as well + // as current. That is, the old authority sets are not made obsolete + // by virtue of a new session being entered. Therefore we maintain + // connections to a much broader set of validators. + { + let mut connections = authorities_past_present_future(sender, leaf).await?; + + // Remove all of our locally controlled validator indices so we don't connect to + // ourself. + let connections = + if remove_all_controlled(&self.keystore, &mut connections) != 0 { + connections + } else { + // If we control none of them, issue an empty connection request + // to clean up all connections. + Vec::new() + }; + self.issue_connection_request(sender, connections).await; + } + + if is_new_session { + // Gossip topology is only relevant for authorities in the current session. + let our_index = self.get_key_index_and_update_metrics(&session_info)?; + + update_gossip_topology( + sender, + our_index, + session_info.discovery_keys.clone(), + relay_parent, + session_index, + ) + .await?; + + self.update_authority_ids(sender, session_info.discovery_keys).await; + } + } + } + Ok(()) + } + + // Checks if the node is an authority and also updates `polkadot_node_is_authority` and + // `polkadot_node_is_parachain_validator` metrics accordingly. + // On success, returns the index of our keys in `session_info.discovery_keys`. + fn get_key_index_and_update_metrics( + &mut self, + session_info: &SessionInfo, + ) -> Result { + let authority_check_result = + ensure_i_am_an_authority(&self.keystore, &session_info.discovery_keys); + + match authority_check_result.as_ref() { + Ok(index) => { + gum::trace!(target: LOG_TARGET, "We are now an authority",); + self.metrics.on_is_authority(); + + // The subset of authorities participating in parachain consensus. + let parachain_validators_this_session = session_info.validators.len(); + + // First `maxValidators` entries are the parachain validators. We'll check + // if our index is in this set to avoid searching for the keys. + // https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148 + if *index < parachain_validators_this_session { + gum::trace!(target: LOG_TARGET, "We are now a parachain validator",); + self.metrics.on_is_parachain_validator(); + } else { + gum::trace!(target: LOG_TARGET, "We are no longer a parachain validator",); + self.metrics.on_is_not_parachain_validator(); + } + }, + Err(util::Error::NotAValidator) => { + gum::trace!(target: LOG_TARGET, "We are no longer an authority",); + self.metrics.on_is_not_authority(); + self.metrics.on_is_not_parachain_validator(); + }, + // Don't update on runtime errors. + Err(_) => {}, + }; + + authority_check_result + } + + async fn issue_connection_request( + &mut self, + sender: &mut Sender, + authorities: Vec, + ) where + Sender: overseer::GossipSupportSenderTrait, + { + let num = authorities.len(); + let mut validator_addrs = Vec::with_capacity(authorities.len()); + let mut failures = 0; + let mut resolved = HashMap::with_capacity(authorities.len()); + for authority in authorities { + if let Some(addrs) = + self.authority_discovery.get_addresses_by_authority_id(authority.clone()).await + { + validator_addrs.push(addrs.clone()); + resolved.insert(authority, addrs); + } else { + failures += 1; + gum::debug!( + target: LOG_TARGET, + "Couldn't resolve addresses of authority: {:?}", + authority + ); + } + } + self.resolved_authorities = resolved; + gum::debug!(target: LOG_TARGET, %num, "Issuing a connection request"); + + sender + .send_message(NetworkBridgeTxMessage::ConnectToResolvedValidators { + validator_addrs, + peer_set: PeerSet::Validation, + }) + .await; + + // issue another request for the same session + // if at least a third of the authorities were not resolved. + if num != 0 && 3 * failures >= num { + let timestamp = Instant::now(); + match self.failure_start { + None => self.failure_start = Some(timestamp), + Some(first) if first.elapsed() >= LOW_CONNECTIVITY_WARN_DELAY => { + gum::warn!( + target: LOG_TARGET, + connected = ?(num - failures), + target = ?num, + "Low connectivity - authority lookup failed for too many validators." + ); + }, + Some(_) => { + gum::debug!( + target: LOG_TARGET, + connected = ?(num - failures), + target = ?num, + "Low connectivity (due to authority lookup failures) - expected on startup." + ); + }, + } + self.last_failure = Some(timestamp); + } else { + self.last_failure = None; + self.failure_start = None; + }; + } + + async fn update_authority_ids( + &mut self, + sender: &mut Sender, + authorities: Vec, + ) where + Sender: overseer::GossipSupportSenderTrait, + { + let mut authority_ids: HashMap> = HashMap::new(); + for authority in authorities { + let peer_id = self + .authority_discovery + .get_addresses_by_authority_id(authority.clone()) + .await + .into_iter() + .flat_map(|list| list.into_iter()) + .find_map(|addr| parse_addr(addr).ok().map(|(p, _)| p)); + + if let Some(p) = peer_id { + authority_ids.entry(p).or_default().insert(authority); + } + } + + for (peer_id, auths) in authority_ids { + if self.connected_authorities_by_peer_id.get(&peer_id) != Some(&auths) { + sender + .send_message(NetworkBridgeRxMessage::UpdatedAuthorityIds { + peer_id, + authority_ids: auths.clone(), + }) + .await; + + auths.iter().for_each(|a| { + self.connected_authorities.insert(a.clone(), peer_id); + }); + self.connected_authorities_by_peer_id.insert(peer_id, auths); + } + } + } + + fn handle_connect_disconnect(&mut self, ev: NetworkBridgeEvent) { + match ev { + NetworkBridgeEvent::PeerConnected(peer_id, _, _, o_authority) => { + if let Some(authority_ids) = o_authority { + authority_ids.iter().for_each(|a| { + self.connected_authorities.insert(a.clone(), peer_id); + }); + self.connected_authorities_by_peer_id.insert(peer_id, authority_ids); + } + }, + NetworkBridgeEvent::PeerDisconnected(peer_id) => { + if let Some(authority_ids) = self.connected_authorities_by_peer_id.remove(&peer_id) + { + authority_ids.into_iter().for_each(|a| { + self.connected_authorities.remove(&a); + }); + } + }, + NetworkBridgeEvent::UpdatedAuthorityIds(_, _) => { + // The `gossip-support` subsystem itself issues these messages. + }, + NetworkBridgeEvent::OurViewChange(_) => {}, + NetworkBridgeEvent::PeerViewChange(_, _) => {}, + NetworkBridgeEvent::NewGossipTopology { .. } => {}, + NetworkBridgeEvent::PeerMessage(_, message) => { + // match void -> LLVM unreachable + match message { + Versioned::V1(m) => match m {}, + Versioned::VStaging(m) => match m {}, + } + }, + } + } + + /// Check connectivity and report on it in logs. + fn check_connectivity(&mut self) { + let absolute_connected = self.connected_authorities.len(); + let absolute_resolved = self.resolved_authorities.len(); + let connected_ratio = + (100 * absolute_connected).checked_div(absolute_resolved).unwrap_or(100); + let unconnected_authorities = self + .resolved_authorities + .iter() + .filter(|(a, _)| !self.connected_authorities.contains_key(a)); + // TODO: Make that warning once connectivity issues are fixed (no point in warning, if + // we already know it is broken. + // https://github.com/paritytech/polkadot/issues/3921 + if connected_ratio <= LOW_CONNECTIVITY_WARN_THRESHOLD { + gum::debug!( + target: LOG_TARGET, + "Connectivity seems low, we are only connected to {}% of available validators (see debug logs for details)", connected_ratio + ); + } + let pretty = PrettyAuthorities(unconnected_authorities); + gum::debug!( + target: LOG_TARGET, + ?connected_ratio, + ?absolute_connected, + ?absolute_resolved, + unconnected_authorities = %pretty, + "Connectivity Report" + ); + } +} + +// Get the authorities of the past, present, and future. +async fn authorities_past_present_future( + sender: &mut impl overseer::GossipSupportSenderTrait, + relay_parent: Hash, +) -> Result, util::Error> { + let authorities = util::request_authorities(relay_parent, sender).await.await??; + gum::debug!( + target: LOG_TARGET, + authority_count = ?authorities.len(), + "Determined past/present/future authorities", + ); + Ok(authorities) +} + +/// Return an error if we're not a validator in the given set (do not have keys). +/// Otherwise, returns the index of our keys in `authorities`. +fn ensure_i_am_an_authority( + keystore: &KeystorePtr, + authorities: &[AuthorityDiscoveryId], +) -> Result { + for (i, v) in authorities.iter().enumerate() { + if Keystore::has_keys(&**keystore, &[(v.to_raw_vec(), AuthorityDiscoveryId::ID)]) { + return Ok(i) + } + } + Err(util::Error::NotAValidator) +} + +/// Filter out all controlled keys in the given set. Returns the number of keys removed. +fn remove_all_controlled( + keystore: &KeystorePtr, + authorities: &mut Vec, +) -> usize { + let mut to_remove = Vec::new(); + for (i, v) in authorities.iter().enumerate() { + if Keystore::has_keys(&**keystore, &[(v.to_raw_vec(), AuthorityDiscoveryId::ID)]) { + to_remove.push(i); + } + } + + for i in to_remove.iter().rev().copied() { + authorities.remove(i); + } + + to_remove.len() +} + +/// We partition the list of all sorted `authorities` into `sqrt(len)` groups of `sqrt(len)` size +/// and form a matrix where each validator is connected to all validators in its row and column. +/// This is similar to `[web3]` research proposed topology, except for the groups are not parachain +/// groups (because not all validators are parachain validators and the group size is small), +/// but formed randomly via BABE randomness from two epochs ago. +/// This limits the amount of gossip peers to 2 * `sqrt(len)` and ensures the diameter of 2. +/// +/// [web3]: https://research.web3.foundation/en/latest/polkadot/networking/3-avail-valid.html#topology +async fn update_gossip_topology( + sender: &mut impl overseer::GossipSupportSenderTrait, + our_index: usize, + authorities: Vec, + relay_parent: Hash, + session_index: SessionIndex, +) -> Result<(), util::Error> { + // retrieve BABE randomness + let random_seed = { + let (tx, rx) = oneshot::channel(); + + // TODO https://github.com/paritytech/polkadot/issues/5316: + // get the random seed from the `SessionInfo` instead. + sender + .send_message(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::CurrentBabeEpoch(tx), + )) + .await; + + let randomness = rx.await??.randomness; + let mut subject = [0u8; 40]; + subject[..8].copy_from_slice(b"gossipsu"); + subject[8..].copy_from_slice(&randomness); + sp_core::blake2_256(&subject) + }; + + // shuffle the validators and create the index mapping + let (shuffled_indices, canonical_shuffling) = { + let mut rng: ChaCha20Rng = SeedableRng::from_seed(random_seed); + let len = authorities.len(); + let mut shuffled_indices = vec![0; len]; + let mut canonical_shuffling: Vec<_> = authorities + .iter() + .enumerate() + .map(|(i, a)| (a.clone(), ValidatorIndex(i as _))) + .collect(); + + canonical_shuffling.shuffle(&mut rng); + for (i, (_, validator_index)) in canonical_shuffling.iter().enumerate() { + shuffled_indices[validator_index.0 as usize] = i; + } + + (shuffled_indices, canonical_shuffling) + }; + + sender + .send_message(NetworkBridgeRxMessage::NewGossipTopology { + session: session_index, + local_index: Some(ValidatorIndex(our_index as _)), + canonical_shuffling, + shuffled_indices, + }) + .await; + + Ok(()) +} + +#[overseer::subsystem(GossipSupport, error = SubsystemError, prefix = self::overseer)] +impl GossipSupport +where + AD: AuthorityDiscovery + Clone, +{ + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = self.run(ctx).map(|_| Ok(())).boxed(); + + SpawnedSubsystem { name: "gossip-support-subsystem", future } + } +} + +/// Helper struct to get a nice rendering of unreachable authorities. +struct PrettyAuthorities(I); + +impl<'a, I> fmt::Display for PrettyAuthorities +where + I: Iterator)> + Clone, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut authorities = self.0.clone().peekable(); + if authorities.peek().is_none() { + write!(f, "None")?; + } else { + write!(f, "\n")?; + } + for (authority, addrs) in authorities { + write!(f, "{}:\n", authority)?; + for addr in addrs { + write!(f, " {}\n", addr)?; + } + write!(f, "\n")?; + } + Ok(()) + } +} diff --git a/polkadot/node/network/gossip-support/src/metrics.rs b/polkadot/node/network/gossip-support/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..6cec0523f7554e46e43f9e4259f213854415ae47 --- /dev/null +++ b/polkadot/node/network/gossip-support/src/metrics.rs @@ -0,0 +1,91 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_node_subsystem_util::{ + metrics, + metrics::{ + prometheus, + prometheus::{Gauge, PrometheusError, Registry, U64}, + }, +}; + +/// Dispute Distribution metrics. +#[derive(Clone, Default)] +pub struct Metrics(Option); + +#[derive(Clone)] +struct MetricsInner { + /// Tracks authority status for producing relay chain blocks. + is_authority: Gauge, + /// Tracks authority status for parachain approval checking. + is_parachain_validator: Gauge, +} + +impl Metrics { + /// Dummy constructor for testing. + #[cfg(test)] + pub fn new_dummy() -> Self { + Self(None) + } + + /// Set the `relaychain validator` metric. + pub fn on_is_authority(&self) { + if let Some(metrics) = &self.0 { + metrics.is_authority.set(1); + } + } + + /// Unset the `relaychain validator` metric. + pub fn on_is_not_authority(&self) { + if let Some(metrics) = &self.0 { + metrics.is_authority.set(0); + } + } + + /// Set the `parachain validator` metric. + pub fn on_is_parachain_validator(&self) { + if let Some(metrics) = &self.0 { + metrics.is_parachain_validator.set(1); + } + } + + /// Unset the `parachain validator` metric. + pub fn on_is_not_parachain_validator(&self) { + if let Some(metrics) = &self.0 { + metrics.is_parachain_validator.set(0); + } + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &Registry) -> Result { + let metrics = MetricsInner { + is_authority: prometheus::register( + Gauge::new("polkadot_node_is_active_validator", "Tracks if the validator is in the active set. \ + Updates at session boundary.")?, + registry, + )?, + is_parachain_validator: prometheus::register( + Gauge::new("polkadot_node_is_parachain_validator", + "Tracks if the validator participates in parachain consensus. Parachain validators are a \ + subset of the active set validators that perform approval checking of all parachain candidates in a session.\ + Updates at session boundary.")?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/network/gossip-support/src/tests.rs b/polkadot/node/network/gossip-support/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..20f550514157d7c542805fcc26db06b672ce8194 --- /dev/null +++ b/polkadot/node/network/gossip-support/src/tests.rs @@ -0,0 +1,721 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Unit tests for Gossip Support Subsystem. + +use std::{collections::HashSet, sync::Arc, time::Duration}; + +use assert_matches::assert_matches; +use async_trait::async_trait; +use futures::{executor, future, Future}; +use lazy_static::lazy_static; + +use sc_network::multiaddr::Protocol; +use sp_authority_discovery::AuthorityPair as AuthorityDiscoveryPair; +use sp_consensus_babe::{AllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch}; +use sp_core::crypto::Pair as PairT; +use sp_keyring::Sr25519Keyring; + +use polkadot_node_network_protocol::grid_topology::{SessionGridTopology, TopologyPeerInfo}; +use polkadot_node_subsystem::{ + jaeger, + messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}, + ActivatedLeaf, LeafStatus, +}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_node_subsystem_util::TimeoutExt as _; +use polkadot_primitives::{GroupIndex, IndexedVec}; +use test_helpers::mock::make_ferdie_keystore; + +use super::*; + +const AUTHORITY_KEYRINGS: &[Sr25519Keyring] = &[ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Eve, + Sr25519Keyring::One, + Sr25519Keyring::Two, + Sr25519Keyring::Ferdie, +]; + +lazy_static! { + static ref MOCK_AUTHORITY_DISCOVERY: MockAuthorityDiscovery = MockAuthorityDiscovery::new(); + static ref AUTHORITIES: Vec = + AUTHORITY_KEYRINGS.iter().map(|k| k.public().into()).collect(); + + static ref AUTHORITIES_WITHOUT_US: Vec = { + let mut a = AUTHORITIES.clone(); + a.pop(); // remove FERDIE. + a + }; + + static ref PAST_PRESENT_FUTURE_AUTHORITIES: Vec = { + (0..50) + .map(|_| AuthorityDiscoveryPair::generate().0.public()) + .chain(AUTHORITIES.clone()) + .collect() + }; + + // [2 6] + // [4 5] + // [1 3] + // [0 ] + + static ref EXPECTED_SHUFFLING: Vec = vec![6, 4, 0, 5, 2, 3, 1]; + + static ref ROW_NEIGHBORS: Vec = vec![ + ValidatorIndex::from(2), + ]; + + static ref COLUMN_NEIGHBORS: Vec = vec![ + ValidatorIndex::from(3), + ValidatorIndex::from(5), + ]; +} + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; + +#[derive(Debug, Clone)] +struct MockAuthorityDiscovery { + addrs: HashMap>, + authorities: HashMap>, +} + +impl MockAuthorityDiscovery { + fn new() -> Self { + let authorities: HashMap<_, _> = PAST_PRESENT_FUTURE_AUTHORITIES + .clone() + .into_iter() + .map(|a| (PeerId::random(), a)) + .collect(); + let addrs = authorities + .clone() + .into_iter() + .map(|(p, a)| { + let multiaddr = Multiaddr::empty().with(Protocol::P2p(p.into())); + (a, HashSet::from([multiaddr])) + }) + .collect(); + Self { + addrs, + authorities: authorities.into_iter().map(|(p, a)| (p, HashSet::from([a]))).collect(), + } + } +} + +#[async_trait] +impl AuthorityDiscovery for MockAuthorityDiscovery { + async fn get_addresses_by_authority_id( + &mut self, + authority: polkadot_primitives::AuthorityDiscoveryId, + ) -> Option> { + self.addrs.get(&authority).cloned() + } + async fn get_authority_ids_by_peer_id( + &mut self, + peer_id: polkadot_node_network_protocol::PeerId, + ) -> Option> { + self.authorities.get(&peer_id).cloned() + } +} + +async fn get_multiaddrs(authorities: Vec) -> Vec> { + let mut addrs = Vec::with_capacity(authorities.len()); + let mut discovery = MOCK_AUTHORITY_DISCOVERY.clone(); + for authority in authorities.into_iter() { + if let Some(addr) = discovery.get_addresses_by_authority_id(authority).await { + addrs.push(addr); + } + } + addrs +} + +async fn get_address_map( + authorities: Vec, +) -> HashMap> { + let mut addrs = HashMap::with_capacity(authorities.len()); + let mut discovery = MOCK_AUTHORITY_DISCOVERY.clone(); + for authority in authorities.into_iter() { + if let Some(addr) = discovery.get_addresses_by_authority_id(authority.clone()).await { + addrs.insert(authority, addr); + } + } + addrs +} + +fn make_subsystem() -> GossipSupport { + GossipSupport::new( + make_ferdie_keystore(), + MOCK_AUTHORITY_DISCOVERY.clone(), + Metrics::new_dummy(), + ) +} + +fn test_harness, AD: AuthorityDiscovery>( + subsystem: GossipSupport, + test_fn: impl FnOnce(VirtualOverseer) -> T, +) -> GossipSupport { + let pool = sp_core::testing::TaskExecutor::new(); + let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); + + let subsystem = subsystem.run(context); + + let test_fut = test_fn(virtual_overseer); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + + let (_, subsystem) = executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer + .send(FromOrchestra::Signal(OverseerSignal::Conclude)) + .timeout(TIMEOUT) + .await + .expect("Conclude send timeout"); + }, + subsystem, + )); + subsystem +} + +const TIMEOUT: Duration = Duration::from_millis(100); + +async fn overseer_signal_active_leaves(overseer: &mut VirtualOverseer, leaf: Hash) { + let leaf = ActivatedLeaf { + hash: leaf, + number: 0xdeadcafe, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( + leaf, + )))) + .timeout(TIMEOUT) + .await + .expect("signal send timeout"); +} + +fn make_session_info() -> SessionInfo { + let all_validator_indices: Vec<_> = (0..6).map(ValidatorIndex::from).collect(); + SessionInfo { + active_validator_indices: all_validator_indices.clone(), + random_seed: [0; 32], + dispute_period: 6, + validators: AUTHORITY_KEYRINGS.iter().map(|k| k.public().into()).collect(), + discovery_keys: AUTHORITIES.clone(), + assignment_keys: AUTHORITY_KEYRINGS.iter().map(|k| k.public().into()).collect(), + validator_groups: IndexedVec::>::from(vec![ + all_validator_indices, + ]), + n_cores: 1, + zeroth_delay_tranche_width: 1, + relay_vrf_modulo_samples: 1, + n_delay_tranches: 1, + no_show_slots: 1, + needed_approvals: 1, + } +} + +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { + let msg = overseer.recv().timeout(TIMEOUT).await.expect("msg recv timeout"); + + msg +} + +async fn test_neighbors(overseer: &mut VirtualOverseer, expected_session: SessionIndex) { + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::CurrentBabeEpoch(tx), + )) => { + let _ = tx.send(Ok(BabeEpoch { + epoch_index: 2 as _, + start_slot: 0.into(), + duration: 200, + authorities: vec![(Sr25519Keyring::Alice.public().into(), 1)], + randomness: [0u8; 32], + config: BabeEpochConfiguration { + c: (1, 4), + allowed_slots: AllowedSlots::PrimarySlots, + }, + })).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeRx(NetworkBridgeRxMessage::NewGossipTopology { + session: got_session, + local_index, + canonical_shuffling, + shuffled_indices, + }) => { + assert_eq!(expected_session, got_session); + assert_eq!(local_index, Some(ValidatorIndex(6))); + assert_eq!(shuffled_indices, EXPECTED_SHUFFLING.clone()); + + let grid_topology = SessionGridTopology::new( + shuffled_indices, + canonical_shuffling.into_iter() + .map(|(a, v)| TopologyPeerInfo { + validator_index: v, + discovery_id: a, + peer_ids: Vec::new(), + }) + .collect(), + ); + + let grid_neighbors = grid_topology + .compute_grid_neighbors_for(local_index.unwrap()) + .unwrap(); + + let mut got_row: Vec<_> = grid_neighbors.validator_indices_x.into_iter().collect(); + let mut got_column: Vec<_> = grid_neighbors.validator_indices_y.into_iter().collect(); + got_row.sort(); + got_column.sort(); + assert_eq!(got_row, ROW_NEIGHBORS.clone()); + assert_eq!(got_column, COLUMN_NEIGHBORS.clone()); + } + ); +} + +#[test] +fn issues_a_connection_request_on_new_session() { + let hash = Hash::repeat_byte(0xAA); + let state = test_harness(make_subsystem(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + overseer_signal_active_leaves(overseer, hash).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(1)).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionInfo(s, tx), + )) => { + assert_eq!(relay_parent, hash); + assert_eq!(s, 1); + tx.send(Ok(Some(make_session_info()))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Authorities(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(AUTHORITIES.clone())).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ConnectToResolvedValidators { + validator_addrs, + peer_set, + }) => { + assert_eq!(validator_addrs, get_multiaddrs(AUTHORITIES_WITHOUT_US.clone()).await); + assert_eq!(peer_set, PeerSet::Validation); + } + ); + + test_neighbors(overseer, 1).await; + + virtual_overseer + }); + + assert_eq!(state.last_session_index, Some(1)); + assert!(state.last_failure.is_none()); + + // does not issue on the same session + let hash = Hash::repeat_byte(0xBB); + let state = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + overseer_signal_active_leaves(overseer, hash).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(1)).unwrap(); + } + ); + virtual_overseer + }); + + assert_eq!(state.last_session_index, Some(1)); + assert!(state.last_failure.is_none()); + + // does on the new one + let hash = Hash::repeat_byte(0xCC); + let state = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + overseer_signal_active_leaves(overseer, hash).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(2)).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionInfo(s, tx), + )) => { + assert_eq!(relay_parent, hash); + assert_eq!(s, 2); + tx.send(Ok(Some(make_session_info()))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Authorities(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(AUTHORITIES.clone())).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ConnectToResolvedValidators { + validator_addrs, + peer_set, + }) => { + assert_eq!(validator_addrs, get_multiaddrs(AUTHORITIES_WITHOUT_US.clone()).await); + assert_eq!(peer_set, PeerSet::Validation); + } + ); + + test_neighbors(overseer, 2).await; + + virtual_overseer + }); + assert_eq!(state.last_session_index, Some(2)); + assert!(state.last_failure.is_none()); +} + +#[test] +fn issues_connection_request_to_past_present_future() { + let hash = Hash::repeat_byte(0xAA); + test_harness(make_subsystem(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + overseer_signal_active_leaves(overseer, hash).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(1)).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionInfo(s, tx), + )) => { + assert_eq!(relay_parent, hash); + assert_eq!(s, 1); + tx.send(Ok(Some(make_session_info()))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Authorities(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(PAST_PRESENT_FUTURE_AUTHORITIES.clone())).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ConnectToResolvedValidators { + validator_addrs, + peer_set, + }) => { + let all_without_ferdie: Vec<_> = PAST_PRESENT_FUTURE_AUTHORITIES + .iter() + .cloned() + .filter(|p| p != &Sr25519Keyring::Ferdie.public().into()) + .collect(); + + let addrs = get_multiaddrs(all_without_ferdie).await; + + assert_eq!(validator_addrs, addrs); + assert_eq!(peer_set, PeerSet::Validation); + } + ); + + // Ensure neighbors are unaffected + test_neighbors(overseer, 1).await; + + virtual_overseer + }); +} + +#[test] +fn disconnect_when_not_in_past_present_future() { + sp_tracing::try_init_simple(); + let hash = Hash::repeat_byte(0xAA); + test_harness(make_subsystem(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + overseer_signal_active_leaves(overseer, hash).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(1)).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionInfo(s, tx), + )) => { + assert_eq!(relay_parent, hash); + assert_eq!(s, 1); + let mut heute_leider_nicht = make_session_info(); + heute_leider_nicht.discovery_keys = AUTHORITIES_WITHOUT_US.clone(); + tx.send(Ok(Some(heute_leider_nicht))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Authorities(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(AUTHORITIES_WITHOUT_US.clone())).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ConnectToResolvedValidators { + validator_addrs, + peer_set, + }) => { + assert!(validator_addrs.is_empty()); + assert_eq!(peer_set, PeerSet::Validation); + } + ); + + virtual_overseer + }); +} + +#[test] +fn test_log_output() { + sp_tracing::try_init_simple(); + let alice: AuthorityDiscoveryId = Sr25519Keyring::Alice.public().into(); + let bob = Sr25519Keyring::Bob.public().into(); + let unconnected_authorities = { + let mut m = HashMap::new(); + let peer_id = PeerId::random(); + let addr = Multiaddr::empty().with(Protocol::P2p(peer_id.into())); + let addrs = HashSet::from([addr.clone(), addr]); + m.insert(alice, addrs); + let peer_id = PeerId::random(); + let addr = Multiaddr::empty().with(Protocol::P2p(peer_id.into())); + let addrs = HashSet::from([addr.clone(), addr]); + m.insert(bob, addrs); + m + }; + let pretty = PrettyAuthorities(unconnected_authorities.iter()); + gum::debug!( + target: LOG_TARGET, + unconnected_authorities = %pretty, + "Connectivity Report" + ); +} + +#[test] +fn issues_a_connection_request_when_last_request_was_mostly_unresolved() { + let hash = Hash::repeat_byte(0xAA); + let mut state = make_subsystem(); + // There will be two lookup failures: + let alice = Sr25519Keyring::Alice.public().into(); + let bob = Sr25519Keyring::Bob.public().into(); + let alice_addr = state.authority_discovery.addrs.remove(&alice); + state.authority_discovery.addrs.remove(&bob); + + let mut state = { + let alice = alice.clone(); + let bob = bob.clone(); + + test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + overseer_signal_active_leaves(overseer, hash).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(1)).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionInfo(s, tx), + )) => { + assert_eq!(relay_parent, hash); + assert_eq!(s, 1); + tx.send(Ok(Some(make_session_info()))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Authorities(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(AUTHORITIES.clone())).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ConnectToResolvedValidators { + validator_addrs, + peer_set, + }) => { + let mut expected = get_address_map(AUTHORITIES_WITHOUT_US.clone()).await; + expected.remove(&alice); + expected.remove(&bob); + let expected: HashSet = expected.into_values().flat_map(|v| v.into_iter()).collect(); + assert_eq!(validator_addrs.into_iter().flat_map(|v| v.into_iter()).collect::>(), expected); + assert_eq!(peer_set, PeerSet::Validation); + } + ); + + test_neighbors(overseer, 1).await; + + virtual_overseer + }) + }; + + assert_eq!(state.last_session_index, Some(1)); + assert!(state.last_failure.is_some()); + state.last_failure = state.last_failure.and_then(|i| i.checked_sub(BACKOFF_DURATION)); + // One error less: + state.authority_discovery.addrs.insert(alice, alice_addr.unwrap()); + + let hash = Hash::repeat_byte(0xBB); + let state = test_harness(state, |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + overseer_signal_active_leaves(overseer, hash).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(1)).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionInfo(s, tx), + )) => { + assert_eq!(relay_parent, hash); + assert_eq!(s, 1); + tx.send(Ok(Some(make_session_info()))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Authorities(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(AUTHORITIES.clone())).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ConnectToResolvedValidators { + validator_addrs, + peer_set, + }) => { + let mut expected = get_address_map(AUTHORITIES_WITHOUT_US.clone()).await; + expected.remove(&bob); + let expected: HashSet = expected.into_values().flat_map(|v| v.into_iter()).collect(); + assert_eq!(validator_addrs.into_iter().flat_map(|v| v.into_iter()).collect::>(), expected); + assert_eq!(peer_set, PeerSet::Validation); + } + ); + + virtual_overseer + }); + + assert_eq!(state.last_session_index, Some(1)); + assert!(state.last_failure.is_none()); +} diff --git a/polkadot/node/network/protocol/Cargo.toml b/polkadot/node/network/protocol/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..207d740f32e524e174658bcd83bd59a39ac1d08f --- /dev/null +++ b/polkadot/node/network/protocol/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "polkadot-node-network-protocol" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +description = "Primitives types for the Node-side" + +[dependencies] +async-channel = "1.8.0" +async-trait = "0.1.57" +hex = "0.4.3" +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-jaeger = { path = "../../jaeger" } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } +strum = { version = "0.24", features = ["derive"] } +futures = "0.3.21" +thiserror = "1.0.31" +fatality = "0.0.6" +rand = "0.8" +derive_more = "0.99" +gum = { package = "tracing-gum", path = "../../gum" } +bitvec = "1" + +[dev-dependencies] +rand_chacha = "0.3.1" + +[features] +network-protocol-staging = [] diff --git a/polkadot/node/network/protocol/src/authority_discovery.rs b/polkadot/node/network/protocol/src/authority_discovery.rs new file mode 100644 index 0000000000000000000000000000000000000000..0cf11b93d18439ae400f967540d4a926d3ba553d --- /dev/null +++ b/polkadot/node/network/protocol/src/authority_discovery.rs @@ -0,0 +1,60 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Authority discovery service interfacing. + +use std::{collections::HashSet, fmt::Debug}; + +use async_trait::async_trait; + +use sc_authority_discovery::Service as AuthorityDiscoveryService; + +use polkadot_primitives::AuthorityDiscoveryId; +use sc_network::{Multiaddr, PeerId}; + +/// An abstraction over the authority discovery service. +/// +/// Needed for mocking in tests mostly. +#[async_trait] +pub trait AuthorityDiscovery: Send + Debug + 'static { + /// Get the addresses for the given [`AuthorityId`] from the local address cache. + async fn get_addresses_by_authority_id( + &mut self, + authority: AuthorityDiscoveryId, + ) -> Option>; + /// Get the [`AuthorityId`] for the given [`PeerId`] from the local address cache. + async fn get_authority_ids_by_peer_id( + &mut self, + peer_id: PeerId, + ) -> Option>; +} + +#[async_trait] +impl AuthorityDiscovery for AuthorityDiscoveryService { + async fn get_addresses_by_authority_id( + &mut self, + authority: AuthorityDiscoveryId, + ) -> Option> { + AuthorityDiscoveryService::get_addresses_by_authority_id(self, authority).await + } + + async fn get_authority_ids_by_peer_id( + &mut self, + peer_id: PeerId, + ) -> Option> { + AuthorityDiscoveryService::get_authority_ids_by_peer_id(self, peer_id).await + } +} diff --git a/polkadot/node/network/protocol/src/grid_topology.rs b/polkadot/node/network/protocol/src/grid_topology.rs new file mode 100644 index 0000000000000000000000000000000000000000..99dd513c4d7909012162a075f6bbc7ce041377fb --- /dev/null +++ b/polkadot/node/network/protocol/src/grid_topology.rs @@ -0,0 +1,577 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Grid topology support implementation +//! The basic operation of the 2D grid topology is that: +//! * A validator producing a message sends it to its row-neighbors and its column-neighbors +//! * A validator receiving a message originating from one of its row-neighbors sends it to its +//! column-neighbors +//! * A validator receiving a message originating from one of its column-neighbors sends it to its +//! row-neighbors +//! +//! This grid approach defines 2 unique paths for every validator to reach every other validator in +//! at most 2 hops. +//! +//! However, we also supplement this with some degree of random propagation: +//! every validator, upon seeing a message for the first time, propagates it to 8 random peers. +//! This inserts some redundancy in case the grid topology isn't working or is being attacked - +//! an adversary doesn't know which peers a validator will send to. +//! This is combined with the property that the adversary doesn't know which validators will elect +//! to check a block. + +use crate::PeerId; +use polkadot_primitives::{AuthorityDiscoveryId, SessionIndex, ValidatorIndex}; +use rand::{CryptoRng, Rng}; +use std::{ + collections::{hash_map, HashMap, HashSet}, + fmt::Debug, +}; + +const LOG_TARGET: &str = "parachain::grid-topology"; + +/// The sample rate for randomly propagating messages. This +/// reduces the left tail of the binomial distribution but also +/// introduces a bias towards peers who we sample before others +/// (i.e. those who get a block before others). +pub const DEFAULT_RANDOM_SAMPLE_RATE: usize = crate::MIN_GOSSIP_PEERS; + +/// The number of peers to randomly propagate messages to. +pub const DEFAULT_RANDOM_CIRCULATION: usize = 4; + +/// Information about a peer in the gossip topology for a session. +#[derive(Debug, Clone, PartialEq)] +pub struct TopologyPeerInfo { + /// The validator's known peer IDs. + pub peer_ids: Vec, + /// The index of the validator in the discovery keys of the corresponding + /// `SessionInfo`. This can extend _beyond_ the set of active parachain validators. + pub validator_index: ValidatorIndex, + /// The authority discovery public key of the validator in the corresponding + /// `SessionInfo`. + pub discovery_id: AuthorityDiscoveryId, +} + +/// Topology representation for a session. +#[derive(Default, Clone, Debug, PartialEq)] +pub struct SessionGridTopology { + /// An array mapping validator indices to their indices in the + /// shuffling itself. This has the same size as the number of validators + /// in the session. + shuffled_indices: Vec, + /// The canonical shuffling of validators for the session. + canonical_shuffling: Vec, +} + +impl SessionGridTopology { + /// Create a new session grid topology. + pub fn new(shuffled_indices: Vec, canonical_shuffling: Vec) -> Self { + SessionGridTopology { shuffled_indices, canonical_shuffling } + } + + /// Produces the outgoing routing logic for a particular peer. + /// + /// Returns `None` if the validator index is out of bounds. + pub fn compute_grid_neighbors_for(&self, v: ValidatorIndex) -> Option { + if self.shuffled_indices.len() != self.canonical_shuffling.len() { + return None + } + let shuffled_val_index = *self.shuffled_indices.get(v.0 as usize)?; + + let neighbors = matrix_neighbors(shuffled_val_index, self.shuffled_indices.len())?; + + let mut grid_subset = GridNeighbors::empty(); + for r_n in neighbors.row_neighbors { + let n = &self.canonical_shuffling[r_n]; + grid_subset.validator_indices_x.insert(n.validator_index); + for p in &n.peer_ids { + grid_subset.peers_x.insert(*p); + } + } + + for c_n in neighbors.column_neighbors { + let n = &self.canonical_shuffling[c_n]; + grid_subset.validator_indices_y.insert(n.validator_index); + for p in &n.peer_ids { + grid_subset.peers_y.insert(*p); + } + } + + Some(grid_subset) + } +} + +struct MatrixNeighbors { + row_neighbors: R, + column_neighbors: C, +} + +/// Compute the row and column neighbors of `val_index` in a matrix +fn matrix_neighbors( + val_index: usize, + len: usize, +) -> Option, impl Iterator>> { + if val_index >= len { + return None + } + + // e.g. for size 11 the matrix would be + // + // 0 1 2 + // 3 4 5 + // 6 7 8 + // 9 10 + // + // and for index 10, the neighbors would be 1, 4, 7, 9 + + let sqrt = (len as f64).sqrt() as usize; + let our_row = val_index / sqrt; + let our_column = val_index % sqrt; + let row_neighbors = our_row * sqrt..std::cmp::min(our_row * sqrt + sqrt, len); + let column_neighbors = (our_column..len).step_by(sqrt); + + Some(MatrixNeighbors { + row_neighbors: row_neighbors.filter(move |i| *i != val_index), + column_neighbors: column_neighbors.filter(move |i| *i != val_index), + }) +} + +/// Information about the grid neighbors for a particular node in the topology. +#[derive(Debug, Clone, PartialEq)] +pub struct GridNeighbors { + /// Represent peers in the X axis + pub peers_x: HashSet, + /// Represent validators in the X axis + pub validator_indices_x: HashSet, + /// Represent peers in the Y axis + pub peers_y: HashSet, + /// Represent validators in the Y axis + pub validator_indices_y: HashSet, +} + +impl GridNeighbors { + /// Utility function for creating an empty set of grid neighbors. + /// Useful for testing. + pub fn empty() -> Self { + GridNeighbors { + peers_x: HashSet::new(), + validator_indices_x: HashSet::new(), + peers_y: HashSet::new(), + validator_indices_y: HashSet::new(), + } + } + + /// Given the originator of a message as a validator index, indicates the part of the topology + /// we're meant to send the message to. + pub fn required_routing_by_index( + &self, + originator: ValidatorIndex, + local: bool, + ) -> RequiredRouting { + if local { + return RequiredRouting::GridXY + } + + let grid_x = self.validator_indices_x.contains(&originator); + let grid_y = self.validator_indices_y.contains(&originator); + + match (grid_x, grid_y) { + (false, false) => RequiredRouting::None, + (true, false) => RequiredRouting::GridY, // messages from X go to Y + (false, true) => RequiredRouting::GridX, // messages from Y go to X + (true, true) => RequiredRouting::GridXY, /* if the grid works as expected, this + * shouldn't happen. */ + } + } + + /// Given the originator of a message as a peer index, indicates the part of the topology + /// we're meant to send the message to. + pub fn required_routing_by_peer_id(&self, originator: PeerId, local: bool) -> RequiredRouting { + if local { + return RequiredRouting::GridXY + } + + let grid_x = self.peers_x.contains(&originator); + let grid_y = self.peers_y.contains(&originator); + + match (grid_x, grid_y) { + (false, false) => RequiredRouting::None, + (true, false) => RequiredRouting::GridY, // messages from X go to Y + (false, true) => RequiredRouting::GridX, // messages from Y go to X + (true, true) => { + gum::debug!( + target: LOG_TARGET, + ?originator, + "Grid topology is unexpected, play it safe and send to X AND Y" + ); + RequiredRouting::GridXY + }, /* if the grid works as expected, this + * shouldn't happen. */ + } + } + + /// Get a filter function based on this topology and the required routing + /// which returns `true` for peers that are within the required routing set + /// and false otherwise. + pub fn route_to_peer(&self, required_routing: RequiredRouting, peer: &PeerId) -> bool { + match required_routing { + RequiredRouting::All => true, + RequiredRouting::GridX => self.peers_x.contains(peer), + RequiredRouting::GridY => self.peers_y.contains(peer), + RequiredRouting::GridXY => self.peers_x.contains(peer) || self.peers_y.contains(peer), + RequiredRouting::None | RequiredRouting::PendingTopology => false, + } + } + + /// Returns the difference between this and the `other` topology as a vector of peers + pub fn peers_diff(&self, other: &Self) -> Vec { + self.peers_x + .iter() + .chain(self.peers_y.iter()) + .filter(|peer_id| !(other.peers_x.contains(peer_id) || other.peers_y.contains(peer_id))) + .cloned() + .collect::>() + } + + /// A convenience method that returns total number of peers in the topology + pub fn len(&self) -> usize { + self.peers_x.len().saturating_add(self.peers_y.len()) + } +} + +/// An entry tracking a session grid topology and some cached local neighbors. +#[derive(Debug)] +pub struct SessionGridTopologyEntry { + topology: SessionGridTopology, + local_neighbors: GridNeighbors, +} + +impl SessionGridTopologyEntry { + /// Access the local grid neighbors. + pub fn local_grid_neighbors(&self) -> &GridNeighbors { + &self.local_neighbors + } + + /// Access the local grid neighbors mutably. + pub fn local_grid_neighbors_mut(&mut self) -> &mut GridNeighbors { + &mut self.local_neighbors + } + + /// Access the underlying topology. + pub fn get(&self) -> &SessionGridTopology { + &self.topology + } +} + +/// A set of topologies indexed by session +#[derive(Default)] +pub struct SessionGridTopologies { + inner: HashMap, usize)>, +} + +impl SessionGridTopologies { + /// Returns a topology for the specific session index + pub fn get_topology(&self, session: SessionIndex) -> Option<&SessionGridTopologyEntry> { + self.inner.get(&session).and_then(|val| val.0.as_ref()) + } + + /// Increase references counter for a specific topology + pub fn inc_session_refs(&mut self, session: SessionIndex) { + self.inner.entry(session).or_insert((None, 0)).1 += 1; + } + + /// Decrease references counter for a specific topology + pub fn dec_session_refs(&mut self, session: SessionIndex) { + if let hash_map::Entry::Occupied(mut occupied) = self.inner.entry(session) { + occupied.get_mut().1 = occupied.get().1.saturating_sub(1); + if occupied.get().1 == 0 { + let _ = occupied.remove(); + } + } + } + + /// Insert a new topology, no-op if already present. + pub fn insert_topology( + &mut self, + session: SessionIndex, + topology: SessionGridTopology, + local_index: Option, + ) { + let entry = self.inner.entry(session).or_insert((None, 0)); + if entry.0.is_none() { + let local_neighbors = local_index + .and_then(|l| topology.compute_grid_neighbors_for(l)) + .unwrap_or_else(GridNeighbors::empty); + + entry.0 = Some(SessionGridTopologyEntry { topology, local_neighbors }); + } + } +} + +/// A simple storage for a topology and the corresponding session index +#[derive(Debug)] +struct GridTopologySessionBound { + entry: SessionGridTopologyEntry, + session_index: SessionIndex, +} + +/// A storage for the current and maybe previous topology +#[derive(Debug)] +pub struct SessionBoundGridTopologyStorage { + current_topology: GridTopologySessionBound, + prev_topology: Option, +} + +impl Default for SessionBoundGridTopologyStorage { + fn default() -> Self { + // having this struct be `Default` is objectively stupid + // but used in a few places + SessionBoundGridTopologyStorage { + current_topology: GridTopologySessionBound { + // session 0 is valid so we should use the upper bound + // as the default instead of the lower bound. + session_index: SessionIndex::max_value(), + entry: SessionGridTopologyEntry { + topology: SessionGridTopology { + shuffled_indices: Vec::new(), + canonical_shuffling: Vec::new(), + }, + local_neighbors: GridNeighbors::empty(), + }, + }, + prev_topology: None, + } + } +} + +impl SessionBoundGridTopologyStorage { + /// Return a grid topology based on the session index: + /// If we need a previous session and it is registered in the storage, then return that session. + /// Otherwise, return a current session to have some grid topology in any case + pub fn get_topology_or_fallback(&self, idx: SessionIndex) -> &SessionGridTopologyEntry { + self.get_topology(idx).unwrap_or(&self.current_topology.entry) + } + + /// Return the grid topology for the specific session index, if no such a session is stored + /// returns `None`. + pub fn get_topology(&self, idx: SessionIndex) -> Option<&SessionGridTopologyEntry> { + if let Some(prev_topology) = &self.prev_topology { + if idx == prev_topology.session_index { + return Some(&prev_topology.entry) + } + } + if self.current_topology.session_index == idx { + return Some(&self.current_topology.entry) + } + + None + } + + /// Update the current topology preserving the previous one + pub fn update_topology( + &mut self, + session_index: SessionIndex, + topology: SessionGridTopology, + local_index: Option, + ) { + let local_neighbors = local_index + .and_then(|l| topology.compute_grid_neighbors_for(l)) + .unwrap_or_else(GridNeighbors::empty); + + let old_current = std::mem::replace( + &mut self.current_topology, + GridTopologySessionBound { + entry: SessionGridTopologyEntry { topology, local_neighbors }, + session_index, + }, + ); + self.prev_topology.replace(old_current); + } + + /// Returns a current grid topology + pub fn get_current_topology(&self) -> &SessionGridTopologyEntry { + &self.current_topology.entry + } + + /// Access the current grid topology mutably. Dangerous and intended + /// to be used in tests. + pub fn get_current_topology_mut(&mut self) -> &mut SessionGridTopologyEntry { + &mut self.current_topology.entry + } +} + +/// A representation of routing based on sample +#[derive(Debug, Clone, Copy)] +pub struct RandomRouting { + /// The number of peers to target. + target: usize, + /// The number of peers this has been sent to. + sent: usize, + /// Sampling rate + sample_rate: usize, +} + +impl Default for RandomRouting { + fn default() -> Self { + RandomRouting { + target: DEFAULT_RANDOM_CIRCULATION, + sent: 0_usize, + sample_rate: DEFAULT_RANDOM_SAMPLE_RATE, + } + } +} + +impl RandomRouting { + /// Perform random sampling for a specific peer + /// Returns `true` for a lucky peer + pub fn sample(&self, n_peers_total: usize, rng: &mut (impl CryptoRng + Rng)) -> bool { + if n_peers_total == 0 || self.sent >= self.target { + false + } else if self.sample_rate > n_peers_total { + true + } else { + rng.gen_ratio(self.sample_rate as _, n_peers_total as _) + } + } + + /// Increase number of messages being sent + pub fn inc_sent(&mut self) { + self.sent += 1 + } +} + +/// Routing mode +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum RequiredRouting { + /// We don't know yet, because we're waiting for topology info + /// (race condition between learning about the first blocks in a new session + /// and getting the topology for that session) + PendingTopology, + /// Propagate to all peers of any kind. + All, + /// Propagate to all peers sharing either the X or Y dimension of the grid. + GridXY, + /// Propagate to all peers sharing the X dimension of the grid. + GridX, + /// Propagate to all peers sharing the Y dimension of the grid. + GridY, + /// No required propagation. + None, +} + +impl RequiredRouting { + /// Whether the required routing set is definitely empty. + pub fn is_empty(self) -> bool { + match self { + RequiredRouting::PendingTopology | RequiredRouting::None => true, + _ => false, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use rand::SeedableRng; + use rand_chacha::ChaCha12Rng; + + fn dummy_rng() -> ChaCha12Rng { + rand_chacha::ChaCha12Rng::seed_from_u64(12345) + } + + #[test] + fn test_random_routing_sample() { + // This test is fragile as it relies on a specific ChaCha12Rng + // sequence that might be implementation defined even for a static seed + let mut rng = dummy_rng(); + let mut random_routing = RandomRouting { target: 4, sent: 0, sample_rate: 8 }; + + assert_eq!(random_routing.sample(16, &mut rng), true); + random_routing.inc_sent(); + assert_eq!(random_routing.sample(16, &mut rng), false); + assert_eq!(random_routing.sample(16, &mut rng), false); + assert_eq!(random_routing.sample(16, &mut rng), true); + random_routing.inc_sent(); + assert_eq!(random_routing.sample(16, &mut rng), true); + random_routing.inc_sent(); + assert_eq!(random_routing.sample(16, &mut rng), false); + assert_eq!(random_routing.sample(16, &mut rng), false); + assert_eq!(random_routing.sample(16, &mut rng), false); + assert_eq!(random_routing.sample(16, &mut rng), true); + random_routing.inc_sent(); + + for _ in 0..16 { + assert_eq!(random_routing.sample(16, &mut rng), false); + } + } + + fn run_random_routing( + random_routing: &mut RandomRouting, + rng: &mut (impl CryptoRng + Rng), + npeers: usize, + iters: usize, + ) -> usize { + let mut ret = 0_usize; + + for _ in 0..iters { + if random_routing.sample(npeers, rng) { + random_routing.inc_sent(); + ret += 1; + } + } + + ret + } + + #[test] + fn test_random_routing_distribution() { + let mut rng = dummy_rng(); + + let mut random_routing = RandomRouting { target: 4, sent: 0, sample_rate: 8 }; + assert_eq!(run_random_routing(&mut random_routing, &mut rng, 100, 10000), 4); + + let mut random_routing = RandomRouting { target: 8, sent: 0, sample_rate: 100 }; + assert_eq!(run_random_routing(&mut random_routing, &mut rng, 100, 10000), 8); + + let mut random_routing = RandomRouting { target: 0, sent: 0, sample_rate: 100 }; + assert_eq!(run_random_routing(&mut random_routing, &mut rng, 100, 10000), 0); + + let mut random_routing = RandomRouting { target: 10, sent: 0, sample_rate: 10 }; + assert_eq!(run_random_routing(&mut random_routing, &mut rng, 10, 100), 10); + } + + #[test] + fn test_matrix_neighbors() { + for (our_index, len, expected_row, expected_column) in vec![ + (0usize, 1usize, vec![], vec![]), + (1, 2, vec![], vec![0usize]), + (0, 9, vec![1, 2], vec![3, 6]), + (9, 10, vec![], vec![0, 3, 6]), + (10, 11, vec![9], vec![1, 4, 7]), + (7, 11, vec![6, 8], vec![1, 4, 10]), + ] + .into_iter() + { + let matrix = matrix_neighbors(our_index, len).unwrap(); + let mut row_result: Vec<_> = matrix.row_neighbors.collect(); + let mut column_result: Vec<_> = matrix.column_neighbors.collect(); + row_result.sort(); + column_result.sort(); + + assert_eq!(row_result, expected_row); + assert_eq!(column_result, expected_column); + } + } +} diff --git a/polkadot/node/network/protocol/src/lib.rs b/polkadot/node/network/protocol/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..1bed2c12fe202ce51ae07d50b0d07ca6282b669d --- /dev/null +++ b/polkadot/node/network/protocol/src/lib.rs @@ -0,0 +1,843 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Network protocol types for parachains. + +#![deny(unused_crate_dependencies)] +#![warn(missing_docs)] + +use parity_scale_codec::{Decode, Encode}; +use polkadot_primitives::{BlockNumber, Hash}; +use std::{collections::HashMap, fmt}; + +#[doc(hidden)] +pub use polkadot_node_jaeger as jaeger; +pub use sc_network::{IfDisconnected, PeerId}; +#[doc(hidden)] +pub use std::sync::Arc; + +mod reputation; +pub use self::reputation::{ReputationChange, UnifiedReputationChange}; + +/// Peer-sets and protocols used for parachains. +pub mod peer_set; + +/// Request/response protocols used in Polkadot. +pub mod request_response; + +/// Accessing authority discovery service +pub mod authority_discovery; +/// Grid topology support module +pub mod grid_topology; + +/// The minimum amount of peers to send gossip messages to. +pub const MIN_GOSSIP_PEERS: usize = 25; + +/// An error indicating that this the over-arching message type had the wrong variant +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct WrongVariant; + +impl fmt::Display for WrongVariant { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(formatter, "Wrong message variant") + } +} + +impl std::error::Error for WrongVariant {} + +/// The advertised role of a node. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum ObservedRole { + /// A light node. + Light, + /// A full node. + Full, + /// A node claiming to be an authority (unauthenticated) + Authority, +} + +impl From for ObservedRole { + fn from(role: sc_network::ObservedRole) -> ObservedRole { + match role { + sc_network::ObservedRole::Light => ObservedRole::Light, + sc_network::ObservedRole::Authority => ObservedRole::Authority, + sc_network::ObservedRole::Full => ObservedRole::Full, + } + } +} + +impl Into for ObservedRole { + fn into(self) -> sc_network::ObservedRole { + match self { + ObservedRole::Light => sc_network::ObservedRole::Light, + ObservedRole::Full => sc_network::ObservedRole::Full, + ObservedRole::Authority => sc_network::ObservedRole::Authority, + } + } +} + +/// Specialized wrapper around [`View`]. +/// +/// Besides the access to the view itself, it also gives access to the [`jaeger::Span`] per +/// leave/head. +#[derive(Debug, Clone, Default)] +pub struct OurView { + view: View, + span_per_head: HashMap>, +} + +impl OurView { + /// Creates a new instance. + pub fn new( + heads: impl IntoIterator)>, + finalized_number: BlockNumber, + ) -> Self { + let state_per_head = heads.into_iter().collect::>(); + let view = View::new(state_per_head.keys().cloned(), finalized_number); + Self { view, span_per_head: state_per_head } + } + + /// Returns the span per head map. + /// + /// For each head there exists one span in this map. + pub fn span_per_head(&self) -> &HashMap> { + &self.span_per_head + } +} + +impl PartialEq for OurView { + fn eq(&self, other: &Self) -> bool { + self.view == other.view + } +} + +impl std::ops::Deref for OurView { + type Target = View; + + fn deref(&self) -> &View { + &self.view + } +} + +/// Construct a new [`OurView`] with the given chain heads, finalized number 0 and disabled +/// [`jaeger::Span`]'s. +/// +/// NOTE: Use for tests only. +/// +/// # Example +/// +/// ``` +/// # use polkadot_node_network_protocol::our_view; +/// # use polkadot_primitives::Hash; +/// let our_view = our_view![Hash::repeat_byte(1), Hash::repeat_byte(2)]; +/// ``` +#[macro_export] +macro_rules! our_view { + ( $( $hash:expr ),* $(,)? ) => { + $crate::OurView::new( + vec![ $( $hash.clone() ),* ].into_iter().map(|h| (h, $crate::Arc::new($crate::jaeger::Span::Disabled))), + 0, + ) + }; +} + +/// A succinct representation of a peer's view. This consists of a bounded amount of chain heads +/// and the highest known finalized block number. +/// +/// Up to `N` (5?) chain heads. +#[derive(Default, Debug, Clone, PartialEq, Eq, Encode, Decode)] +pub struct View { + /// A bounded amount of chain heads. + /// Invariant: Sorted. + heads: Vec, + /// The highest known finalized block number. + pub finalized_number: BlockNumber, +} + +/// Construct a new view with the given chain heads and finalized number 0. +/// +/// NOTE: Use for tests only. +/// +/// # Example +/// +/// ``` +/// # use polkadot_node_network_protocol::view; +/// # use polkadot_primitives::Hash; +/// let view = view![Hash::repeat_byte(1), Hash::repeat_byte(2)]; +/// ``` +#[macro_export] +macro_rules! view { + ( $( $hash:expr ),* $(,)? ) => { + $crate::View::new(vec![ $( $hash.clone() ),* ], 0) + }; +} + +impl View { + /// Construct a new view based on heads and a finalized block number. + pub fn new(heads: impl IntoIterator, finalized_number: BlockNumber) -> Self { + let mut heads = heads.into_iter().collect::>(); + heads.sort(); + Self { heads, finalized_number } + } + + /// Start with no heads, but only a finalized block number. + pub fn with_finalized(finalized_number: BlockNumber) -> Self { + Self { heads: Vec::new(), finalized_number } + } + + /// Obtain the number of heads that are in view. + pub fn len(&self) -> usize { + self.heads.len() + } + + /// Check if the number of heads contained, is null. + pub fn is_empty(&self) -> bool { + self.heads.is_empty() + } + + /// Obtain an iterator over all heads. + pub fn iter(&self) -> impl Iterator { + self.heads.iter() + } + + /// Obtain an iterator over all heads. + pub fn into_iter(self) -> impl Iterator { + self.heads.into_iter() + } + + /// Replace `self` with `new`. + /// + /// Returns an iterator that will yield all elements of `new` that were not part of `self`. + pub fn replace_difference(&mut self, new: View) -> impl Iterator { + let old = std::mem::replace(self, new); + + self.heads.iter().filter(move |h| !old.contains(h)) + } + + /// Returns an iterator of the hashes present in `Self` but not in `other`. + pub fn difference<'a>(&'a self, other: &'a View) -> impl Iterator + 'a { + self.heads.iter().filter(move |h| !other.contains(h)) + } + + /// An iterator containing hashes present in both `Self` and in `other`. + pub fn intersection<'a>(&'a self, other: &'a View) -> impl Iterator + 'a { + self.heads.iter().filter(move |h| other.contains(h)) + } + + /// Whether the view contains a given hash. + pub fn contains(&self, hash: &Hash) -> bool { + self.heads.contains(hash) + } + + /// Check if two views have the same heads. + /// + /// Equivalent to the `PartialEq` function, + /// but ignores the `finalized_number` field. + pub fn check_heads_eq(&self, other: &Self) -> bool { + self.heads == other.heads + } +} + +/// A protocol-versioned type. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Versioned { + /// V1 type. + V1(V1), + /// VStaging type. + VStaging(VStaging), +} + +impl Versioned<&'_ V1, &'_ VStaging> { + /// Convert to a fully-owned version of the message. + pub fn clone_inner(&self) -> Versioned { + match *self { + Versioned::V1(inner) => Versioned::V1(inner.clone()), + Versioned::VStaging(inner) => Versioned::VStaging(inner.clone()), + } + } +} + +/// All supported versions of the validation protocol message. +pub type VersionedValidationProtocol = + Versioned; + +impl From for VersionedValidationProtocol { + fn from(v1: v1::ValidationProtocol) -> Self { + VersionedValidationProtocol::V1(v1) + } +} + +impl From for VersionedValidationProtocol { + fn from(vstaging: vstaging::ValidationProtocol) -> Self { + VersionedValidationProtocol::VStaging(vstaging) + } +} + +/// All supported versions of the collation protocol message. +pub type VersionedCollationProtocol = Versioned; + +impl From for VersionedCollationProtocol { + fn from(v1: v1::CollationProtocol) -> Self { + VersionedCollationProtocol::V1(v1) + } +} + +impl From for VersionedCollationProtocol { + fn from(vstaging: vstaging::CollationProtocol) -> Self { + VersionedCollationProtocol::VStaging(vstaging) + } +} + +macro_rules! impl_versioned_full_protocol_from { + ($from:ty, $out:ty, $variant:ident) => { + impl From<$from> for $out { + fn from(versioned_from: $from) -> $out { + match versioned_from { + Versioned::V1(x) => Versioned::V1(x.into()), + Versioned::VStaging(x) => Versioned::VStaging(x.into()), + } + } + } + }; +} + +/// Implement `TryFrom` for one versioned enum variant into the inner type. +/// `$m_ty::$variant(inner) -> Ok(inner)` +macro_rules! impl_versioned_try_from { + ( + $from:ty, + $out:ty, + $v1_pat:pat => $v1_out:expr, + $vstaging_pat:pat => $vstaging_out:expr + ) => { + impl TryFrom<$from> for $out { + type Error = crate::WrongVariant; + + fn try_from(x: $from) -> Result<$out, Self::Error> { + #[allow(unreachable_patterns)] // when there is only one variant + match x { + Versioned::V1($v1_pat) => Ok(Versioned::V1($v1_out)), + Versioned::VStaging($vstaging_pat) => Ok(Versioned::VStaging($vstaging_out)), + _ => Err(crate::WrongVariant), + } + } + } + + impl<'a> TryFrom<&'a $from> for $out { + type Error = crate::WrongVariant; + + fn try_from(x: &'a $from) -> Result<$out, Self::Error> { + #[allow(unreachable_patterns)] // when there is only one variant + match x { + Versioned::V1($v1_pat) => Ok(Versioned::V1($v1_out.clone())), + Versioned::VStaging($vstaging_pat) => + Ok(Versioned::VStaging($vstaging_out.clone())), + _ => Err(crate::WrongVariant), + } + } + } + }; +} + +/// Version-annotated messages used by the bitfield distribution subsystem. +pub type BitfieldDistributionMessage = + Versioned; +impl_versioned_full_protocol_from!( + BitfieldDistributionMessage, + VersionedValidationProtocol, + BitfieldDistribution +); +impl_versioned_try_from!( + VersionedValidationProtocol, + BitfieldDistributionMessage, + v1::ValidationProtocol::BitfieldDistribution(x) => x, + vstaging::ValidationProtocol::BitfieldDistribution(x) => x +); + +/// Version-annotated messages used by the statement distribution subsystem. +pub type StatementDistributionMessage = + Versioned; +impl_versioned_full_protocol_from!( + StatementDistributionMessage, + VersionedValidationProtocol, + StatementDistribution +); +impl_versioned_try_from!( + VersionedValidationProtocol, + StatementDistributionMessage, + v1::ValidationProtocol::StatementDistribution(x) => x, + vstaging::ValidationProtocol::StatementDistribution(x) => x +); + +/// Version-annotated messages used by the approval distribution subsystem. +pub type ApprovalDistributionMessage = + Versioned; +impl_versioned_full_protocol_from!( + ApprovalDistributionMessage, + VersionedValidationProtocol, + ApprovalDistribution +); +impl_versioned_try_from!( + VersionedValidationProtocol, + ApprovalDistributionMessage, + v1::ValidationProtocol::ApprovalDistribution(x) => x, + vstaging::ValidationProtocol::ApprovalDistribution(x) => x + +); + +/// Version-annotated messages used by the gossip-support subsystem (this is void). +pub type GossipSupportNetworkMessage = + Versioned; +// This is a void enum placeholder, so never gets sent over the wire. +impl TryFrom for GossipSupportNetworkMessage { + type Error = WrongVariant; + fn try_from(_: VersionedValidationProtocol) -> Result { + Err(WrongVariant) + } +} + +impl<'a> TryFrom<&'a VersionedValidationProtocol> for GossipSupportNetworkMessage { + type Error = WrongVariant; + fn try_from(_: &'a VersionedValidationProtocol) -> Result { + Err(WrongVariant) + } +} + +/// Version-annotated messages used by the bitfield distribution subsystem. +pub type CollatorProtocolMessage = + Versioned; +impl_versioned_full_protocol_from!( + CollatorProtocolMessage, + VersionedCollationProtocol, + CollatorProtocol +); +impl_versioned_try_from!( + VersionedCollationProtocol, + CollatorProtocolMessage, + v1::CollationProtocol::CollatorProtocol(x) => x, + vstaging::CollationProtocol::CollatorProtocol(x) => x +); + +/// v1 notification protocol types. +pub mod v1 { + use parity_scale_codec::{Decode, Encode}; + + use polkadot_primitives::{ + CandidateHash, CandidateIndex, CollatorId, CollatorSignature, CompactStatement, Hash, + Id as ParaId, UncheckedSignedAvailabilityBitfield, ValidatorIndex, ValidatorSignature, + }; + + use polkadot_node_primitives::{ + approval::{IndirectAssignmentCert, IndirectSignedApprovalVote}, + UncheckedSignedFullStatement, + }; + + /// Network messages used by the bitfield distribution subsystem. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] + pub enum BitfieldDistributionMessage { + /// A signed availability bitfield for a given relay-parent hash. + #[codec(index = 0)] + Bitfield(Hash, UncheckedSignedAvailabilityBitfield), + } + + /// Network messages used by the statement distribution subsystem. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] + pub enum StatementDistributionMessage { + /// A signed full statement under a given relay-parent. + #[codec(index = 0)] + Statement(Hash, UncheckedSignedFullStatement), + /// Seconded statement with large payload (e.g. containing a runtime upgrade). + /// + /// We only gossip the hash in that case, actual payloads can be fetched from sending node + /// via request/response. + #[codec(index = 1)] + LargeStatement(StatementMetadata), + } + + /// Data that makes a statement unique. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, Hash)] + pub struct StatementMetadata { + /// Relay parent this statement is relevant under. + pub relay_parent: Hash, + /// Hash of the candidate that got validated. + pub candidate_hash: CandidateHash, + /// Validator that attested the validity. + pub signed_by: ValidatorIndex, + /// Signature of seconding validator. + pub signature: ValidatorSignature, + } + + impl StatementDistributionMessage { + /// Get fingerprint describing the contained statement uniquely. + pub fn get_fingerprint(&self) -> (CompactStatement, ValidatorIndex) { + match self { + Self::Statement(_, statement) => ( + statement.unchecked_payload().to_compact(), + statement.unchecked_validator_index(), + ), + Self::LargeStatement(meta) => + (CompactStatement::Seconded(meta.candidate_hash), meta.signed_by), + } + } + + /// Get the signature from the statement. + pub fn get_signature(&self) -> ValidatorSignature { + match self { + Self::Statement(_, statement) => statement.unchecked_signature().clone(), + Self::LargeStatement(metadata) => metadata.signature.clone(), + } + } + + /// Get contained relay parent. + pub fn get_relay_parent(&self) -> Hash { + match self { + Self::Statement(r, _) => *r, + Self::LargeStatement(meta) => meta.relay_parent, + } + } + + /// Whether this message contains a large statement. + pub fn is_large_statement(&self) -> bool { + if let Self::LargeStatement(_) = self { + true + } else { + false + } + } + } + + /// Network messages used by the approval distribution subsystem. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] + pub enum ApprovalDistributionMessage { + /// Assignments for candidates in recent, unfinalized blocks. + /// + /// Actually checking the assignment may yield a different result. + #[codec(index = 0)] + Assignments(Vec<(IndirectAssignmentCert, CandidateIndex)>), + /// Approvals for candidates in some recent, unfinalized block. + #[codec(index = 1)] + Approvals(Vec), + } + + /// Dummy network message type, so we will receive connect/disconnect events. + #[derive(Debug, Clone, PartialEq, Eq)] + pub enum GossipSupportNetworkMessage {} + + /// Network messages used by the collator protocol subsystem + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] + pub enum CollatorProtocolMessage { + /// Declare the intent to advertise collations under a collator ID, attaching a + /// signature of the `PeerId` of the node using the given collator ID key. + #[codec(index = 0)] + Declare(CollatorId, ParaId, CollatorSignature), + /// Advertise a collation to a validator. Can only be sent once the peer has + /// declared that they are a collator with given ID. + #[codec(index = 1)] + AdvertiseCollation(Hash), + /// A collation sent to a validator was seconded. + #[codec(index = 4)] + CollationSeconded(Hash, UncheckedSignedFullStatement), + } + + /// All network messages on the validation peer-set. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, derive_more::From)] + pub enum ValidationProtocol { + /// Bitfield distribution messages + #[codec(index = 1)] + #[from] + BitfieldDistribution(BitfieldDistributionMessage), + /// Statement distribution messages + #[codec(index = 3)] + #[from] + StatementDistribution(StatementDistributionMessage), + /// Approval distribution messages + #[codec(index = 4)] + #[from] + ApprovalDistribution(ApprovalDistributionMessage), + } + + /// All network messages on the collation peer-set. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, derive_more::From)] + pub enum CollationProtocol { + /// Collator protocol messages + #[codec(index = 0)] + #[from] + CollatorProtocol(CollatorProtocolMessage), + } + + /// Get the payload that should be signed and included in a `Declare` message. + /// + /// The payload is the local peer id of the node, which serves to prove that it + /// controls the collator key it is declaring an intention to collate under. + pub fn declare_signature_payload(peer_id: &sc_network::PeerId) -> Vec { + let mut payload = peer_id.to_bytes(); + payload.extend_from_slice(b"COLL"); + payload + } +} + +/// vstaging network protocol types. +pub mod vstaging { + use bitvec::{order::Lsb0, slice::BitSlice, vec::BitVec}; + use parity_scale_codec::{Decode, Encode}; + + use polkadot_primitives::vstaging::{ + CandidateHash, CandidateIndex, CollatorId, CollatorSignature, GroupIndex, Hash, + Id as ParaId, UncheckedSignedAvailabilityBitfield, UncheckedSignedStatement, + }; + + use polkadot_node_primitives::{ + approval::{IndirectAssignmentCert, IndirectSignedApprovalVote}, + UncheckedSignedFullStatement, + }; + + /// Network messages used by the bitfield distribution subsystem. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] + pub enum BitfieldDistributionMessage { + /// A signed availability bitfield for a given relay-parent hash. + #[codec(index = 0)] + Bitfield(Hash, UncheckedSignedAvailabilityBitfield), + } + + /// Bitfields indicating the statements that are known or undesired + /// about a candidate. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] + pub struct StatementFilter { + /// Seconded statements. '1' is known or undesired. + pub seconded_in_group: BitVec, + /// Valid statements. '1' is known or undesired. + pub validated_in_group: BitVec, + } + + impl StatementFilter { + /// Create a new blank filter with the given group size. + pub fn blank(group_size: usize) -> Self { + StatementFilter { + seconded_in_group: BitVec::repeat(false, group_size), + validated_in_group: BitVec::repeat(false, group_size), + } + } + + /// Create a new full filter with the given group size. + pub fn full(group_size: usize) -> Self { + StatementFilter { + seconded_in_group: BitVec::repeat(true, group_size), + validated_in_group: BitVec::repeat(true, group_size), + } + } + + /// Whether the filter has a specific expected length, consistent across both + /// bitfields. + pub fn has_len(&self, len: usize) -> bool { + self.seconded_in_group.len() == len && self.validated_in_group.len() == len + } + + /// Determine the number of backing validators in the statement filter. + pub fn backing_validators(&self) -> usize { + self.seconded_in_group + .iter() + .by_vals() + .zip(self.validated_in_group.iter().by_vals()) + .filter(|&(s, v)| s || v) // no double-counting + .count() + } + + /// Whether the statement filter has at least one seconded statement. + pub fn has_seconded(&self) -> bool { + self.seconded_in_group.iter().by_vals().any(|x| x) + } + + /// Mask out `Seconded` statements in `self` according to the provided + /// bitvec. Bits appearing in `mask` will not appear in `self` afterwards. + pub fn mask_seconded(&mut self, mask: &BitSlice) { + for (mut x, mask) in self + .seconded_in_group + .iter_mut() + .zip(mask.iter().by_vals().chain(std::iter::repeat(false))) + { + // (x, mask) => x + // (true, true) => false + // (true, false) => true + // (false, true) => false + // (false, false) => false + *x = *x && !mask; + } + } + + /// Mask out `Valid` statements in `self` according to the provided + /// bitvec. Bits appearing in `mask` will not appear in `self` afterwards. + pub fn mask_valid(&mut self, mask: &BitSlice) { + for (mut x, mask) in self + .validated_in_group + .iter_mut() + .zip(mask.iter().by_vals().chain(std::iter::repeat(false))) + { + // (x, mask) => x + // (true, true) => false + // (true, false) => true + // (false, true) => false + // (false, false) => false + *x = *x && !mask; + } + } + } + + /// A manifest of a known backed candidate, along with a description + /// of the statements backing it. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] + pub struct BackedCandidateManifest { + /// The relay-parent of the candidate. + pub relay_parent: Hash, + /// The hash of the candidate. + pub candidate_hash: CandidateHash, + /// The group index backing the candidate at the relay-parent. + pub group_index: GroupIndex, + /// The para ID of the candidate. It is illegal for this to + /// be a para ID which is not assigned to the group indicated + /// in this manifest. + pub para_id: ParaId, + /// The head-data corresponding to the candidate. + pub parent_head_data_hash: Hash, + /// A statement filter which indicates which validators in the + /// para's group at the relay-parent have validated this candidate + /// and issued statements about it, to the advertiser's knowledge. + /// + /// This MUST have exactly the minimum amount of bytes + /// necessary to represent the number of validators in the assigned + /// backing group as-of the relay-parent. + pub statement_knowledge: StatementFilter, + } + + /// An acknowledgement of a backed candidate being known. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] + pub struct BackedCandidateAcknowledgement { + /// The hash of the candidate. + pub candidate_hash: CandidateHash, + /// A statement filter which indicates which validators in the + /// para's group at the relay-parent have validated this candidate + /// and issued statements about it, to the advertiser's knowledge. + /// + /// This MUST have exactly the minimum amount of bytes + /// necessary to represent the number of validators in the assigned + /// backing group as-of the relay-parent. + pub statement_knowledge: StatementFilter, + } + + /// Network messages used by the statement distribution subsystem. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] + pub enum StatementDistributionMessage { + /// A notification of a signed statement in compact form, for a given relay parent. + #[codec(index = 0)] + Statement(Hash, UncheckedSignedStatement), + + /// A notification of a backed candidate being known by the + /// sending node, for the purpose of being requested by the receiving node + /// if needed. + #[codec(index = 1)] + BackedCandidateManifest(BackedCandidateManifest), + + /// A notification of a backed candidate being known by the sending node, + /// for the purpose of informing a receiving node which already has the candidate. + #[codec(index = 2)] + BackedCandidateKnown(BackedCandidateAcknowledgement), + + /// All messages for V1 for compatibility with the statement distribution + /// protocol, for relay-parents that don't support asynchronous backing. + /// + /// These are illegal to send to V1 peers, and illegal to send concerning relay-parents + /// which support asynchronous backing. This backwards compatibility should be + /// considered immediately deprecated and can be removed once the node software + /// is not required to support logic from before asynchronous backing anymore. + #[codec(index = 255)] + V1Compatibility(crate::v1::StatementDistributionMessage), + } + + /// Network messages used by the approval distribution subsystem. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] + pub enum ApprovalDistributionMessage { + /// Assignments for candidates in recent, unfinalized blocks. + /// + /// Actually checking the assignment may yield a different result. + #[codec(index = 0)] + Assignments(Vec<(IndirectAssignmentCert, CandidateIndex)>), + /// Approvals for candidates in some recent, unfinalized block. + #[codec(index = 1)] + Approvals(Vec), + } + + /// Dummy network message type, so we will receive connect/disconnect events. + #[derive(Debug, Clone, PartialEq, Eq)] + pub enum GossipSupportNetworkMessage {} + + /// Network messages used by the collator protocol subsystem + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] + pub enum CollatorProtocolMessage { + /// Declare the intent to advertise collations under a collator ID, attaching a + /// signature of the `PeerId` of the node using the given collator ID key. + #[codec(index = 0)] + Declare(CollatorId, ParaId, CollatorSignature), + /// Advertise a collation to a validator. Can only be sent once the peer has + /// declared that they are a collator with given ID. + #[codec(index = 1)] + AdvertiseCollation { + /// Hash of the relay parent advertised collation is based on. + relay_parent: Hash, + /// Candidate hash. + candidate_hash: CandidateHash, + /// Parachain head data hash before candidate execution. + parent_head_data_hash: Hash, + }, + /// A collation sent to a validator was seconded. + #[codec(index = 4)] + CollationSeconded(Hash, UncheckedSignedFullStatement), + } + + /// All network messages on the validation peer-set. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, derive_more::From)] + pub enum ValidationProtocol { + /// Bitfield distribution messages + #[codec(index = 1)] + #[from] + BitfieldDistribution(BitfieldDistributionMessage), + /// Statement distribution messages + #[codec(index = 3)] + #[from] + StatementDistribution(StatementDistributionMessage), + /// Approval distribution messages + #[codec(index = 4)] + #[from] + ApprovalDistribution(ApprovalDistributionMessage), + } + + /// All network messages on the collation peer-set. + #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, derive_more::From)] + pub enum CollationProtocol { + /// Collator protocol messages + #[codec(index = 0)] + #[from] + CollatorProtocol(CollatorProtocolMessage), + } + + /// Get the payload that should be signed and included in a `Declare` message. + /// + /// The payload is the local peer id of the node, which serves to prove that it + /// controls the collator key it is declaring an intention to collate under. + pub fn declare_signature_payload(peer_id: &sc_network::PeerId) -> Vec { + let mut payload = peer_id.to_bytes(); + payload.extend_from_slice(b"COLL"); + payload + } +} diff --git a/polkadot/node/network/protocol/src/peer_set.rs b/polkadot/node/network/protocol/src/peer_set.rs new file mode 100644 index 0000000000000000000000000000000000000000..b6f8c9dec2318791d863286ea3ed72e37224cbde --- /dev/null +++ b/polkadot/node/network/protocol/src/peer_set.rs @@ -0,0 +1,587 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! All peersets and protocols used for parachains. + +use derive_more::Display; +use polkadot_primitives::Hash; +use sc_network::{ + config::{NonDefaultSetConfig, SetConfig}, + types::ProtocolName, +}; +use std::{ + collections::{hash_map::Entry, HashMap}, + ops::{Index, IndexMut}, +}; +use strum::{EnumIter, IntoEnumIterator}; + +/// The legacy protocol names. Only supported on version = 1. +const LEGACY_VALIDATION_PROTOCOL_V1: &str = "/polkadot/validation/1"; +const LEGACY_COLLATION_PROTOCOL_V1: &str = "/polkadot/collation/1"; + +/// The legacy protocol version. Is always 1 for both validation & collation. +const LEGACY_PROTOCOL_VERSION_V1: u32 = 1; + +/// Max notification size is currently constant. +pub const MAX_NOTIFICATION_SIZE: u64 = 100 * 1024; + +/// The peer-sets and thus the protocols which are used for the network. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)] +pub enum PeerSet { + /// The validation peer-set is responsible for all messages related to candidate validation and + /// communication among validators. + Validation, + /// The collation peer-set is used for validator<>collator communication. + Collation, +} + +/// Whether a node is an authority or not. +/// +/// Peer set configuration gets adjusted accordingly. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum IsAuthority { + /// Node is authority. + Yes, + /// Node is not an authority. + No, +} + +impl PeerSet { + /// Get `sc_network` peer set configurations for each peerset on the default version. + /// + /// Those should be used in the network configuration to register the protocols with the + /// network service. + pub fn get_info( + self, + is_authority: IsAuthority, + peerset_protocol_names: &PeerSetProtocolNames, + ) -> NonDefaultSetConfig { + // Networking layer relies on `get_main_name()` being the main name of the protocol + // for peersets and connection management. + let protocol = peerset_protocol_names.get_main_name(self); + let fallback_names = PeerSetProtocolNames::get_fallback_names(self); + let max_notification_size = self.get_max_notification_size(is_authority); + + match self { + PeerSet::Validation => NonDefaultSetConfig { + notifications_protocol: protocol, + fallback_names, + max_notification_size, + handshake: None, + set_config: SetConfig { + // we allow full nodes to connect to validators for gossip + // to ensure any `MIN_GOSSIP_PEERS` always include reserved peers + // we limit the amount of non-reserved slots to be less + // than `MIN_GOSSIP_PEERS` in total + in_peers: super::MIN_GOSSIP_PEERS as u32 / 2 - 1, + out_peers: super::MIN_GOSSIP_PEERS as u32 / 2 - 1, + reserved_nodes: Vec::new(), + non_reserved_mode: sc_network::config::NonReservedPeerMode::Accept, + }, + }, + PeerSet::Collation => NonDefaultSetConfig { + notifications_protocol: protocol, + fallback_names, + max_notification_size, + handshake: None, + set_config: SetConfig { + // Non-authority nodes don't need to accept incoming connections on this peer + // set: + in_peers: if is_authority == IsAuthority::Yes { 100 } else { 0 }, + out_peers: 0, + reserved_nodes: Vec::new(), + non_reserved_mode: if is_authority == IsAuthority::Yes { + sc_network::config::NonReservedPeerMode::Accept + } else { + sc_network::config::NonReservedPeerMode::Deny + }, + }, + }, + } + } + + /// Get the main protocol version for this peer set. + /// + /// Networking layer relies on `get_main_version()` being the version + /// of the main protocol name reported by [`PeerSetProtocolNames::get_main_name()`]. + pub fn get_main_version(self) -> ProtocolVersion { + #[cfg(not(feature = "network-protocol-staging"))] + match self { + PeerSet::Validation => ValidationVersion::V1.into(), + PeerSet::Collation => CollationVersion::V1.into(), + } + + #[cfg(feature = "network-protocol-staging")] + match self { + PeerSet::Validation => ValidationVersion::VStaging.into(), + PeerSet::Collation => CollationVersion::VStaging.into(), + } + } + + /// Get the max notification size for this peer set. + pub fn get_max_notification_size(self, _: IsAuthority) -> u64 { + MAX_NOTIFICATION_SIZE + } + + /// Get the peer set label for metrics reporting. + pub fn get_label(self) -> &'static str { + match self { + PeerSet::Validation => "validation", + PeerSet::Collation => "collation", + } + } + + /// Get the protocol label for metrics reporting. + pub fn get_protocol_label(self, version: ProtocolVersion) -> Option<&'static str> { + // Unfortunately, labels must be static strings, so we must manually cover them + // for all protocol versions here. + match self { + PeerSet::Validation => + if version == ValidationVersion::V1.into() { + Some("validation/1") + } else if version == ValidationVersion::VStaging.into() { + Some("validation/2") + } else { + None + }, + PeerSet::Collation => + if version == CollationVersion::V1.into() { + Some("collation/1") + } else if version == CollationVersion::VStaging.into() { + Some("collation/2") + } else { + None + }, + } + } +} + +/// A small and nifty collection that allows to store data pertaining to each peer set. +#[derive(Debug, Default)] +pub struct PerPeerSet { + validation: T, + collation: T, +} + +impl Index for PerPeerSet { + type Output = T; + fn index(&self, index: PeerSet) -> &T { + match index { + PeerSet::Validation => &self.validation, + PeerSet::Collation => &self.collation, + } + } +} + +impl IndexMut for PerPeerSet { + fn index_mut(&mut self, index: PeerSet) -> &mut T { + match index { + PeerSet::Validation => &mut self.validation, + PeerSet::Collation => &mut self.collation, + } + } +} + +/// Get `NonDefaultSetConfig`s for all available peer sets, at their default versions. +/// +/// Should be used during network configuration (added to [`NetworkConfiguration::extra_sets`]) +/// or shortly after startup to register the protocols with the network service. +pub fn peer_sets_info( + is_authority: IsAuthority, + peerset_protocol_names: &PeerSetProtocolNames, +) -> Vec { + PeerSet::iter() + .map(|s| s.get_info(is_authority, &peerset_protocol_names)) + .collect() +} + +/// A generic version of the protocol. This struct must not be created directly. +#[derive(Debug, Clone, Copy, Display, PartialEq, Eq, Hash)] +pub struct ProtocolVersion(u32); + +impl From for u32 { + fn from(version: ProtocolVersion) -> u32 { + version.0 + } +} + +/// Supported validation protocol versions. Only versions defined here must be used in the codebase. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)] +pub enum ValidationVersion { + /// The first version. + V1 = 1, + /// The staging version. + VStaging = 2, +} + +/// Supported collation protocol versions. Only versions defined here must be used in the codebase. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)] +pub enum CollationVersion { + /// The first version. + V1 = 1, + /// The staging version. + VStaging = 2, +} + +/// Marker indicating the version is unknown. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct UnknownVersion; + +impl TryFrom for ValidationVersion { + type Error = UnknownVersion; + + fn try_from(p: ProtocolVersion) -> Result { + for v in Self::iter() { + if v as u32 == p.0 { + return Ok(v) + } + } + + Err(UnknownVersion) + } +} + +impl TryFrom for CollationVersion { + type Error = UnknownVersion; + + fn try_from(p: ProtocolVersion) -> Result { + for v in Self::iter() { + if v as u32 == p.0 { + return Ok(v) + } + } + + Err(UnknownVersion) + } +} + +impl From for ProtocolVersion { + fn from(version: ValidationVersion) -> ProtocolVersion { + ProtocolVersion(version as u32) + } +} + +impl From for ProtocolVersion { + fn from(version: CollationVersion) -> ProtocolVersion { + ProtocolVersion(version as u32) + } +} + +/// On the wire protocol name to [`PeerSet`] mapping. +#[derive(Clone)] +pub struct PeerSetProtocolNames { + protocols: HashMap, + names: HashMap<(PeerSet, ProtocolVersion), ProtocolName>, +} + +impl PeerSetProtocolNames { + /// Construct [`PeerSetProtocols`] using `genesis_hash` and `fork_id`. + pub fn new(genesis_hash: Hash, fork_id: Option<&str>) -> Self { + let mut protocols = HashMap::new(); + let mut names = HashMap::new(); + for protocol in PeerSet::iter() { + match protocol { + PeerSet::Validation => + for version in ValidationVersion::iter() { + Self::register_main_protocol( + &mut protocols, + &mut names, + protocol, + version.into(), + &genesis_hash, + fork_id, + ); + }, + PeerSet::Collation => + for version in CollationVersion::iter() { + Self::register_main_protocol( + &mut protocols, + &mut names, + protocol, + version.into(), + &genesis_hash, + fork_id, + ); + }, + } + Self::register_legacy_protocol(&mut protocols, protocol); + } + Self { protocols, names } + } + + /// Helper function to register main protocol. + fn register_main_protocol( + protocols: &mut HashMap, + names: &mut HashMap<(PeerSet, ProtocolVersion), ProtocolName>, + protocol: PeerSet, + version: ProtocolVersion, + genesis_hash: &Hash, + fork_id: Option<&str>, + ) { + let protocol_name = Self::generate_name(genesis_hash, fork_id, protocol, version); + names.insert((protocol, version), protocol_name.clone()); + Self::insert_protocol_or_panic(protocols, protocol_name, protocol, version); + } + + /// Helper function to register legacy protocol. + fn register_legacy_protocol( + protocols: &mut HashMap, + protocol: PeerSet, + ) { + Self::insert_protocol_or_panic( + protocols, + Self::get_legacy_name(protocol), + protocol, + ProtocolVersion(LEGACY_PROTOCOL_VERSION_V1), + ) + } + + /// Helper function to make sure no protocols have the same name. + fn insert_protocol_or_panic( + protocols: &mut HashMap, + name: ProtocolName, + protocol: PeerSet, + version: ProtocolVersion, + ) { + match protocols.entry(name) { + Entry::Vacant(entry) => { + entry.insert((protocol, version)); + }, + Entry::Occupied(entry) => { + panic!( + "Protocol {:?} (version {}) has the same on-the-wire name as protocol {:?} (version {}): `{}`.", + protocol, + version, + entry.get().0, + entry.get().1, + entry.key(), + ); + }, + } + } + + /// Lookup the protocol using its on the wire name. + pub fn try_get_protocol(&self, name: &ProtocolName) -> Option<(PeerSet, ProtocolVersion)> { + self.protocols.get(name).map(ToOwned::to_owned) + } + + /// Get the main protocol name. It's used by the networking for keeping track + /// of peersets and connections. + pub fn get_main_name(&self, protocol: PeerSet) -> ProtocolName { + self.get_name(protocol, protocol.get_main_version()) + } + + /// Get the protocol name for specific version. + pub fn get_name(&self, protocol: PeerSet, version: ProtocolVersion) -> ProtocolName { + self.names + .get(&(protocol, version)) + .expect("Protocols & versions are specified via enums defined above, and they are all registered in `new()`; qed") + .clone() + } + + /// The protocol name of this protocol based on `genesis_hash` and `fork_id`. + fn generate_name( + genesis_hash: &Hash, + fork_id: Option<&str>, + protocol: PeerSet, + version: ProtocolVersion, + ) -> ProtocolName { + let prefix = if let Some(fork_id) = fork_id { + format!("/{}/{}", hex::encode(genesis_hash), fork_id) + } else { + format!("/{}", hex::encode(genesis_hash)) + }; + + let short_name = match protocol { + PeerSet::Validation => "validation", + PeerSet::Collation => "collation", + }; + + format!("{}/{}/{}", prefix, short_name, version).into() + } + + /// Get the legacy protocol name, only `LEGACY_PROTOCOL_VERSION` = 1 is supported. + fn get_legacy_name(protocol: PeerSet) -> ProtocolName { + match protocol { + PeerSet::Validation => LEGACY_VALIDATION_PROTOCOL_V1, + PeerSet::Collation => LEGACY_COLLATION_PROTOCOL_V1, + } + .into() + } + + /// Get the protocol fallback names. Currently only holds the legacy name + /// for `LEGACY_PROTOCOL_VERSION` = 1. + fn get_fallback_names(protocol: PeerSet) -> Vec { + std::iter::once(Self::get_legacy_name(protocol)).collect() + } +} + +#[cfg(test)] +mod tests { + use super::{ + CollationVersion, Hash, PeerSet, PeerSetProtocolNames, ProtocolVersion, ValidationVersion, + }; + use strum::IntoEnumIterator; + + struct TestVersion(u32); + + impl From for ProtocolVersion { + fn from(version: TestVersion) -> ProtocolVersion { + ProtocolVersion(version.0) + } + } + + #[test] + fn protocol_names_are_correctly_generated() { + let genesis_hash = Hash::from([ + 122, 200, 116, 29, 232, 183, 20, 109, 138, 86, 23, 253, 70, 41, 20, 85, 127, 230, 60, + 38, 90, 127, 28, 16, 231, 218, 227, 40, 88, 238, 187, 128, + ]); + let name = PeerSetProtocolNames::generate_name( + &genesis_hash, + None, + PeerSet::Validation, + TestVersion(3).into(), + ); + let expected = + "/7ac8741de8b7146d8a5617fd462914557fe63c265a7f1c10e7dae32858eebb80/validation/3"; + assert_eq!(name, expected.into()); + + let name = PeerSetProtocolNames::generate_name( + &genesis_hash, + None, + PeerSet::Collation, + TestVersion(5).into(), + ); + let expected = + "/7ac8741de8b7146d8a5617fd462914557fe63c265a7f1c10e7dae32858eebb80/collation/5"; + assert_eq!(name, expected.into()); + + let fork_id = Some("test-fork"); + let name = PeerSetProtocolNames::generate_name( + &genesis_hash, + fork_id, + PeerSet::Validation, + TestVersion(7).into(), + ); + let expected = + "/7ac8741de8b7146d8a5617fd462914557fe63c265a7f1c10e7dae32858eebb80/test-fork/validation/7"; + assert_eq!(name, expected.into()); + + let name = PeerSetProtocolNames::generate_name( + &genesis_hash, + fork_id, + PeerSet::Collation, + TestVersion(11).into(), + ); + let expected = + "/7ac8741de8b7146d8a5617fd462914557fe63c265a7f1c10e7dae32858eebb80/test-fork/collation/11"; + assert_eq!(name, expected.into()); + } + + #[test] + fn all_protocol_names_are_known() { + let genesis_hash = Hash::from([ + 122, 200, 116, 29, 232, 183, 20, 109, 138, 86, 23, 253, 70, 41, 20, 85, 127, 230, 60, + 38, 90, 127, 28, 16, 231, 218, 227, 40, 88, 238, 187, 128, + ]); + let protocol_names = PeerSetProtocolNames::new(genesis_hash, None); + + let validation_main = + "/7ac8741de8b7146d8a5617fd462914557fe63c265a7f1c10e7dae32858eebb80/validation/1"; + assert_eq!( + protocol_names.try_get_protocol(&validation_main.into()), + Some((PeerSet::Validation, TestVersion(1).into())), + ); + + let validation_legacy = "/polkadot/validation/1"; + assert_eq!( + protocol_names.try_get_protocol(&validation_legacy.into()), + Some((PeerSet::Validation, TestVersion(1).into())), + ); + + let collation_main = + "/7ac8741de8b7146d8a5617fd462914557fe63c265a7f1c10e7dae32858eebb80/collation/1"; + assert_eq!( + protocol_names.try_get_protocol(&collation_main.into()), + Some((PeerSet::Collation, TestVersion(1).into())), + ); + + let collation_legacy = "/polkadot/collation/1"; + assert_eq!( + protocol_names.try_get_protocol(&collation_legacy.into()), + Some((PeerSet::Collation, TestVersion(1).into())), + ); + } + + #[test] + fn all_protocol_versions_are_registered() { + let genesis_hash = Hash::from([ + 122, 200, 116, 29, 232, 183, 20, 109, 138, 86, 23, 253, 70, 41, 20, 85, 127, 230, 60, + 38, 90, 127, 28, 16, 231, 218, 227, 40, 88, 238, 187, 128, + ]); + let protocol_names = PeerSetProtocolNames::new(genesis_hash, None); + + for protocol in PeerSet::iter() { + match protocol { + PeerSet::Validation => + for version in ValidationVersion::iter() { + assert_eq!( + protocol_names.get_name(protocol, version.into()), + PeerSetProtocolNames::generate_name( + &genesis_hash, + None, + protocol, + version.into(), + ), + ); + }, + PeerSet::Collation => + for version in CollationVersion::iter() { + assert_eq!( + protocol_names.get_name(protocol, version.into()), + PeerSetProtocolNames::generate_name( + &genesis_hash, + None, + protocol, + version.into(), + ), + ); + }, + } + } + } + + #[test] + fn all_protocol_versions_have_labels() { + for protocol in PeerSet::iter() { + match protocol { + PeerSet::Validation => + for version in ValidationVersion::iter() { + protocol + .get_protocol_label(version.into()) + .expect("All validation protocol versions must have a label."); + }, + PeerSet::Collation => + for version in CollationVersion::iter() { + protocol + .get_protocol_label(version.into()) + .expect("All collation protocol versions must have a label."); + }, + } + } + } +} diff --git a/polkadot/node/network/protocol/src/reputation.rs b/polkadot/node/network/protocol/src/reputation.rs new file mode 100644 index 0000000000000000000000000000000000000000..55bd96b4e4a3210a74f67d10b04226b3c650ef24 --- /dev/null +++ b/polkadot/node/network/protocol/src/reputation.rs @@ -0,0 +1,90 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +pub use sc_network::ReputationChange; + +/// Unified annoyance cost and good behavior benefits. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[allow(missing_docs)] +pub enum UnifiedReputationChange { + CostMajor(&'static str), + CostMinor(&'static str), + CostMajorRepeated(&'static str), + CostMinorRepeated(&'static str), + Malicious(&'static str), + BenefitMinorFirst(&'static str), + BenefitMinor(&'static str), + BenefitMajorFirst(&'static str), + BenefitMajor(&'static str), +} + +impl UnifiedReputationChange { + /// Obtain the cost or benefit associated with + /// the enum variant. + /// + /// Order of magnitude rationale: + /// + /// * the peerset will not connect to a peer whose reputation is below a fixed value + /// * `max(2% *$rep, 1)` is the delta of convergence towards a reputation of 0 + /// + /// The whole range of an `i32` should be used, so order of magnitude of + /// something malicious should be `1<<20` (give or take). + pub const fn cost_or_benefit(&self) -> i32 { + match self { + Self::CostMinor(_) => -100_000, + Self::CostMajor(_) => -300_000, + Self::CostMinorRepeated(_) => -200_000, + Self::CostMajorRepeated(_) => -600_000, + Self::Malicious(_) => i32::MIN, + Self::BenefitMajorFirst(_) => 300_000, + Self::BenefitMajor(_) => 200_000, + Self::BenefitMinorFirst(_) => 15_000, + Self::BenefitMinor(_) => 10_000, + } + } + + /// Extract the static description. + pub const fn description(&self) -> &'static str { + match self { + Self::CostMinor(description) => description, + Self::CostMajor(description) => description, + Self::CostMinorRepeated(description) => description, + Self::CostMajorRepeated(description) => description, + Self::Malicious(description) => description, + Self::BenefitMajorFirst(description) => description, + Self::BenefitMajor(description) => description, + Self::BenefitMinorFirst(description) => description, + Self::BenefitMinor(description) => description, + } + } + + /// Whether the reputation change is for good behavior. + pub const fn is_benefit(&self) -> bool { + match self { + Self::BenefitMajorFirst(_) | + Self::BenefitMajor(_) | + Self::BenefitMinorFirst(_) | + Self::BenefitMinor(_) => true, + _ => false, + } + } +} + +impl From for ReputationChange { + fn from(value: UnifiedReputationChange) -> Self { + ReputationChange::new(value.cost_or_benefit(), value.description()) + } +} diff --git a/polkadot/node/network/protocol/src/request_response/incoming/error.rs b/polkadot/node/network/protocol/src/request_response/incoming/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..efc3d8ecfcd4f6ab341a28dbfdf660f53190f7ff --- /dev/null +++ b/polkadot/node/network/protocol/src/request_response/incoming/error.rs @@ -0,0 +1,41 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Error handling related code and Error/Result definitions. + +use sc_network::PeerId; + +use parity_scale_codec::Error as DecodingError; + +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + // Incoming request stream exhausted. Should only happen on shutdown. + #[fatal] + #[error("Incoming request channel got closed.")] + RequestChannelExhausted, + + /// Decoding failed, we were able to change the peer's reputation accordingly. + #[error("Decoding request failed for peer {0}.")] + DecodingError(PeerId, #[source] DecodingError), + + /// Decoding failed, but sending reputation change failed. + #[error("Decoding request failed for peer {0}, and changing reputation failed.")] + DecodingErrorNoReputationChange(PeerId, #[source] DecodingError), +} + +/// General result based on above `Error`. +pub type Result = std::result::Result; diff --git a/polkadot/node/network/protocol/src/request_response/incoming/mod.rs b/polkadot/node/network/protocol/src/request_response/incoming/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..4455448386728e2fdc7188f35841947ca8ddd985 --- /dev/null +++ b/polkadot/node/network/protocol/src/request_response/incoming/mod.rs @@ -0,0 +1,230 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::marker::PhantomData; + +use futures::{channel::oneshot, StreamExt}; + +use parity_scale_codec::{Decode, Encode}; + +use sc_network::{config as netconfig, config::RequestResponseConfig, PeerId}; + +use super::{IsRequest, ReqProtocolNames}; +use crate::UnifiedReputationChange; + +mod error; +pub use error::{Error, FatalError, JfyiError, Result}; + +/// A request coming in, including a sender for sending responses. +/// +/// Typed `IncomingRequest`s, see `IncomingRequest::get_config_receiver` and substrate +/// `NetworkConfiguration` for more information. +#[derive(Debug)] +pub struct IncomingRequest { + /// `PeerId` of sending peer. + pub peer: PeerId, + /// The sent request. + pub payload: Req, + /// Sender for sending response back. + pub pending_response: OutgoingResponseSender, +} + +impl IncomingRequest +where + Req: IsRequest + Decode + Encode, + Req::Response: Encode, +{ + /// Create configuration for `NetworkConfiguration::request_response_porotocols` and a + /// corresponding typed receiver. + /// + /// This Register that config with substrate networking and receive incoming requests via the + /// returned `IncomingRequestReceiver`. + pub fn get_config_receiver( + req_protocol_names: &ReqProtocolNames, + ) -> (IncomingRequestReceiver, RequestResponseConfig) { + let (raw, cfg) = Req::PROTOCOL.get_config(req_protocol_names); + (IncomingRequestReceiver { raw, phantom: PhantomData {} }, cfg) + } + + /// Create new `IncomingRequest`. + pub fn new( + peer: PeerId, + payload: Req, + pending_response: oneshot::Sender, + ) -> Self { + Self { + peer, + payload, + pending_response: OutgoingResponseSender { pending_response, phantom: PhantomData {} }, + } + } + + /// Try building from raw substrate request. + /// + /// This function will fail if the request cannot be decoded and will apply passed in + /// reputation changes in that case. + /// + /// Params: + /// - The raw request to decode + /// - Reputation changes to apply for the peer in case decoding fails. + fn try_from_raw( + raw: sc_network::config::IncomingRequest, + reputation_changes: Vec, + ) -> std::result::Result { + let sc_network::config::IncomingRequest { payload, peer, pending_response } = raw; + let payload = match Req::decode(&mut payload.as_ref()) { + Ok(payload) => payload, + Err(err) => { + let reputation_changes = reputation_changes.into_iter().map(|r| r.into()).collect(); + let response = sc_network::config::OutgoingResponse { + result: Err(()), + reputation_changes, + sent_feedback: None, + }; + + if let Err(_) = pending_response.send(response) { + return Err(JfyiError::DecodingErrorNoReputationChange(peer, err)) + } + return Err(JfyiError::DecodingError(peer, err)) + }, + }; + Ok(Self::new(peer, payload, pending_response)) + } + + /// Convert into raw untyped substrate `IncomingRequest`. + /// + /// This is mostly useful for testing. + pub fn into_raw(self) -> sc_network::config::IncomingRequest { + sc_network::config::IncomingRequest { + peer: self.peer, + payload: self.payload.encode(), + pending_response: self.pending_response.pending_response, + } + } + + /// Send the response back. + /// + /// Calls [`OutgoingResponseSender::send_response`]. + pub fn send_response(self, resp: Req::Response) -> std::result::Result<(), Req::Response> { + self.pending_response.send_response(resp) + } + + /// Send response with additional options. + /// + /// Calls [`OutgoingResponseSender::send_outgoing_response`]. + pub fn send_outgoing_response( + self, + resp: OutgoingResponse<::Response>, + ) -> std::result::Result<(), ()> { + self.pending_response.send_outgoing_response(resp) + } +} + +/// Sender for sending back responses on an `IncomingRequest`. +#[derive(Debug)] +pub struct OutgoingResponseSender { + pending_response: oneshot::Sender, + phantom: PhantomData, +} + +impl OutgoingResponseSender +where + Req: IsRequest + Decode, + Req::Response: Encode, +{ + /// Send the response back. + /// + /// On success we return `Ok(())`, on error we return the not sent `Response`. + /// + /// `netconfig::OutgoingResponse` exposes a way of modifying the peer's reputation. If needed we + /// can change this function to expose this feature as well. + pub fn send_response(self, resp: Req::Response) -> std::result::Result<(), Req::Response> { + self.pending_response + .send(netconfig::OutgoingResponse { + result: Ok(resp.encode()), + reputation_changes: Vec::new(), + sent_feedback: None, + }) + .map_err(|_| resp) + } + + /// Send response with additional options. + /// + /// This variant allows for waiting for the response to be sent out, allows for changing peer's + /// reputation and allows for not sending a response at all (for only changing the peer's + /// reputation). + pub fn send_outgoing_response( + self, + resp: OutgoingResponse<::Response>, + ) -> std::result::Result<(), ()> { + let OutgoingResponse { result, reputation_changes, sent_feedback } = resp; + + let response = netconfig::OutgoingResponse { + result: result.map(|v| v.encode()), + reputation_changes: reputation_changes.into_iter().map(|c| c.into()).collect(), + sent_feedback, + }; + + self.pending_response.send(response).map_err(|_| ()) + } +} + +/// Typed variant of [`netconfig::OutgoingResponse`]. +/// +/// Responses to `IncomingRequest`s. +pub struct OutgoingResponse { + /// The payload of the response. + /// + /// `Err(())` if none is available e.g. due to an error while handling the request. + pub result: std::result::Result, + + /// Reputation changes accrued while handling the request. To be applied to the reputation of + /// the peer sending the request. + pub reputation_changes: Vec, + + /// If provided, the `oneshot::Sender` will be notified when the request has been sent to the + /// peer. + pub sent_feedback: Option>, +} + +/// Receiver for incoming requests. +/// +/// Takes care of decoding and handling of invalid encoded requests. +pub struct IncomingRequestReceiver { + raw: async_channel::Receiver, + phantom: PhantomData, +} + +impl IncomingRequestReceiver +where + Req: IsRequest + Decode + Encode, + Req::Response: Encode, +{ + /// Try to receive the next incoming request. + /// + /// Any received request will be decoded, on decoding errors the provided reputation changes + /// will be applied and an error will be reported. + pub async fn recv(&mut self, reputation_changes: F) -> Result> + where + F: FnOnce() -> Vec, + { + let req = match self.raw.next().await { + None => return Err(FatalError::RequestChannelExhausted.into()), + Some(raw) => IncomingRequest::::try_from_raw(raw, reputation_changes())?, + }; + Ok(req) + } +} diff --git a/polkadot/node/network/protocol/src/request_response/mod.rs b/polkadot/node/network/protocol/src/request_response/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..baed4b8463160451231d3cbfc11e32337dbd9fec --- /dev/null +++ b/polkadot/node/network/protocol/src/request_response/mod.rs @@ -0,0 +1,411 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Overview over request/responses as used in `Polkadot`. +//! +//! `enum Protocol` .... List of all supported protocols. +//! +//! `enum Requests` .... List of all supported requests, each entry matches one in protocols, but +//! has the actual request as payload. +//! +//! `struct IncomingRequest` .... wrapper for incoming requests, containing a sender for sending +//! responses. +//! +//! `struct OutgoingRequest` .... wrapper for outgoing requests, containing a sender used by the +//! networking code for delivering responses/delivery errors. +//! +//! `trait IsRequest` .... A trait describing a particular request. It is used for gathering meta +//! data, like what is the corresponding response type. +//! +//! Versioned (v1 module): The actual requests and responses as sent over the network. + +use std::{collections::HashMap, time::Duration, u64}; + +use polkadot_primitives::{MAX_CODE_SIZE, MAX_POV_SIZE}; +use strum::{EnumIter, IntoEnumIterator}; + +pub use sc_network::{config as network, config::RequestResponseConfig, ProtocolName}; + +/// Everything related to handling of incoming requests. +pub mod incoming; +/// Everything related to handling of outgoing requests. +pub mod outgoing; + +pub use incoming::{IncomingRequest, IncomingRequestReceiver}; + +pub use outgoing::{OutgoingRequest, OutgoingResult, Recipient, Requests, ResponseSender}; + +///// Multiplexer for incoming requests. +// pub mod multiplexer; + +/// Actual versioned requests and responses that are sent over the wire. +pub mod v1; + +/// Actual versioned requests and responses that are sent over the wire. +pub mod vstaging; + +/// A protocol per subsystem seems to make the most sense, this way we don't need any dispatching +/// within protocols. +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, EnumIter)] +pub enum Protocol { + /// Protocol for chunk fetching, used by availability distribution and availability recovery. + ChunkFetchingV1, + /// Protocol for fetching collations from collators. + CollationFetchingV1, + /// Protocol for fetching collations from collators when async backing is enabled. + CollationFetchingVStaging, + /// Protocol for fetching seconded PoVs from validators of the same group. + PoVFetchingV1, + /// Protocol for fetching available data. + AvailableDataFetchingV1, + /// Fetching of statements that are too large for gossip. + StatementFetchingV1, + /// Sending of dispute statements with application level confirmations. + DisputeSendingV1, + + /// Protocol for requesting candidates with attestations in statement distribution + /// when async backing is enabled. + AttestedCandidateVStaging, +} + +/// Minimum bandwidth we expect for validators - 500Mbit/s is the recommendation, so approximately +/// 50MB per second: +const MIN_BANDWIDTH_BYTES: u64 = 50 * 1024 * 1024; + +/// Default request timeout in seconds. +/// +/// When decreasing this value, take into account that the very first request might need to open a +/// connection, which can be slow. If this causes problems, we should ensure connectivity via peer +/// sets. +#[allow(dead_code)] +const DEFAULT_REQUEST_TIMEOUT: Duration = Duration::from_secs(3); + +/// Request timeout where we can assume the connection is already open (e.g. we have peers in a +/// peer set as well). +const DEFAULT_REQUEST_TIMEOUT_CONNECTED: Duration = Duration::from_secs(1); + +/// Timeout for requesting availability chunks. +pub const CHUNK_REQUEST_TIMEOUT: Duration = DEFAULT_REQUEST_TIMEOUT_CONNECTED; + +/// This timeout is based on what seems sensible from a time budget perspective, considering 6 +/// second block time. This is going to be tough, if we have multiple forks and large PoVs, but we +/// only have so much time. +const POV_REQUEST_TIMEOUT_CONNECTED: Duration = Duration::from_millis(1200); + +/// We want timeout statement requests fast, so we don't waste time on slow nodes. Responders will +/// try their best to either serve within that timeout or return an error immediately. (We need to +/// fit statement distribution within a block of 6 seconds.) +const STATEMENTS_TIMEOUT: Duration = Duration::from_secs(1); + +/// We want attested candidate requests to time out relatively fast, +/// because slow requests will bottleneck the backing system. Ideally, we'd have +/// an adaptive timeout based on the candidate size, because there will be a lot of variance +/// in candidate sizes: candidates with no code and no messages vs candidates with code +/// and messages. +/// +/// We supply leniency because there are often large candidates and asynchronous +/// backing allows them to be included over a longer window of time. Exponential back-off +/// up to a maximum of 10 seconds would be ideal, but isn't supported by the +/// infrastructure here yet: see https://github.com/paritytech/polkadot/issues/6009 +const ATTESTED_CANDIDATE_TIMEOUT: Duration = Duration::from_millis(2500); + +/// We don't want a slow peer to slow down all the others, at the same time we want to get out the +/// data quickly in full to at least some peers (as this will reduce load on us as they then can +/// start serving the data). So this value is a trade-off. 3 seems to be sensible. So we would need +/// to have 3 slow nodes connected, to delay transfer for others by `STATEMENTS_TIMEOUT`. +pub const MAX_PARALLEL_STATEMENT_REQUESTS: u32 = 3; + +/// We don't want a slow peer to slow down all the others, at the same time we want to get out the +/// data quickly in full to at least some peers (as this will reduce load on us as they then can +/// start serving the data). So this value is a tradeoff. 5 seems to be sensible. So we would need +/// to have 5 slow nodes connected, to delay transfer for others by `ATTESTED_CANDIDATE_TIMEOUT`. +pub const MAX_PARALLEL_ATTESTED_CANDIDATE_REQUESTS: u32 = 5; + +/// Response size limit for responses of POV like data. +/// +/// This is larger than `MAX_POV_SIZE` to account for protocol overhead and for additional data in +/// `CollationFetchingV1` or `AvailableDataFetchingV1` for example. We try to err on larger limits +/// here as a too large limit only allows an attacker to waste our bandwidth some more, a too low +/// limit might have more severe effects. +const POV_RESPONSE_SIZE: u64 = MAX_POV_SIZE as u64 + 10_000; + +/// Maximum response sizes for `StatementFetchingV1`. +/// +/// This is `MAX_CODE_SIZE` plus some additional space for protocol overhead. +const STATEMENT_RESPONSE_SIZE: u64 = MAX_CODE_SIZE as u64 + 10_000; + +/// Maximum response sizes for `AttestedCandidateVStaging`. +/// +/// This is `MAX_CODE_SIZE` plus some additional space for protocol overhead and +/// additional backing statements. +const ATTESTED_CANDIDATE_RESPONSE_SIZE: u64 = MAX_CODE_SIZE as u64 + 100_000; + +/// We can have relative large timeouts here, there is no value of hitting a +/// timeout as we want to get statements through to each node in any case. +pub const DISPUTE_REQUEST_TIMEOUT: Duration = Duration::from_secs(12); + +impl Protocol { + /// Get a configuration for a given Request response protocol. + /// + /// Returns a `ProtocolConfig` for this protocol. + /// Use this if you plan only to send requests for this protocol. + pub fn get_outbound_only_config( + self, + req_protocol_names: &ReqProtocolNames, + ) -> RequestResponseConfig { + self.create_config(req_protocol_names, None) + } + + /// Get a configuration for a given Request response protocol. + /// + /// Returns a receiver for messages received on this protocol and the requested + /// `ProtocolConfig`. + pub fn get_config( + self, + req_protocol_names: &ReqProtocolNames, + ) -> (async_channel::Receiver, RequestResponseConfig) { + let (tx, rx) = async_channel::bounded(self.get_channel_size()); + let cfg = self.create_config(req_protocol_names, Some(tx)); + (rx, cfg) + } + + fn create_config( + self, + req_protocol_names: &ReqProtocolNames, + tx: Option>, + ) -> RequestResponseConfig { + let name = req_protocol_names.get_name(self); + let fallback_names = self.get_fallback_names(); + match self { + Protocol::ChunkFetchingV1 => RequestResponseConfig { + name, + fallback_names, + max_request_size: 1_000, + max_response_size: POV_RESPONSE_SIZE as u64 * 3, + // We are connected to all validators: + request_timeout: CHUNK_REQUEST_TIMEOUT, + inbound_queue: tx, + }, + Protocol::CollationFetchingV1 | Protocol::CollationFetchingVStaging => + RequestResponseConfig { + name, + fallback_names, + max_request_size: 1_000, + max_response_size: POV_RESPONSE_SIZE, + // Taken from initial implementation in collator protocol: + request_timeout: POV_REQUEST_TIMEOUT_CONNECTED, + inbound_queue: tx, + }, + Protocol::PoVFetchingV1 => RequestResponseConfig { + name, + fallback_names, + max_request_size: 1_000, + max_response_size: POV_RESPONSE_SIZE, + request_timeout: POV_REQUEST_TIMEOUT_CONNECTED, + inbound_queue: tx, + }, + Protocol::AvailableDataFetchingV1 => RequestResponseConfig { + name, + fallback_names, + max_request_size: 1_000, + // Available data size is dominated by the PoV size. + max_response_size: POV_RESPONSE_SIZE, + request_timeout: POV_REQUEST_TIMEOUT_CONNECTED, + inbound_queue: tx, + }, + Protocol::StatementFetchingV1 => RequestResponseConfig { + name, + fallback_names, + max_request_size: 1_000, + // Available data size is dominated code size. + max_response_size: STATEMENT_RESPONSE_SIZE, + // We need statement fetching to be fast and will try our best at the responding + // side to answer requests within that timeout, assuming a bandwidth of 500Mbit/s + // - which is the recommended minimum bandwidth for nodes on Kusama as of April + // 2021. + // Responders will reject requests, if it is unlikely they can serve them within + // the timeout, so the requester can immediately try another node, instead of + // waiting for timeout on an overloaded node. Fetches from slow nodes will likely + // fail, but this is desired, so we can quickly move on to a faster one - we should + // also decrease its reputation. + request_timeout: Duration::from_secs(1), + inbound_queue: tx, + }, + Protocol::DisputeSendingV1 => RequestResponseConfig { + name, + fallback_names, + max_request_size: 1_000, + /// Responses are just confirmation, in essence not even a bit. So 100 seems + /// plenty. + max_response_size: 100, + request_timeout: DISPUTE_REQUEST_TIMEOUT, + inbound_queue: tx, + }, + Protocol::AttestedCandidateVStaging => RequestResponseConfig { + name, + fallback_names, + max_request_size: 1_000, + max_response_size: ATTESTED_CANDIDATE_RESPONSE_SIZE, + request_timeout: ATTESTED_CANDIDATE_TIMEOUT, + inbound_queue: tx, + }, + } + } + + // Channel sizes for the supported protocols. + fn get_channel_size(self) -> usize { + match self { + // Hundreds of validators will start requesting their chunks once they see a candidate + // awaiting availability on chain. Given that they will see that block at different + // times (due to network delays), 100 seems big enough to accomodate for "bursts", + // assuming we can service requests relatively quickly, which would need to be measured + // as well. + Protocol::ChunkFetchingV1 => 100, + // 10 seems reasonable, considering group sizes of max 10 validators. + Protocol::CollationFetchingV1 | Protocol::CollationFetchingVStaging => 10, + // 10 seems reasonable, considering group sizes of max 10 validators. + Protocol::PoVFetchingV1 => 10, + // Validators are constantly self-selecting to request available data which may lead + // to constant load and occasional burstiness. + Protocol::AvailableDataFetchingV1 => 100, + // Our queue size approximation is how many blocks of the size of + // a runtime we can transfer within a statements timeout, minus the requests we handle + // in parallel. + Protocol::StatementFetchingV1 => { + // We assume we can utilize up to 70% of the available bandwidth for statements. + // This is just a guess/estimate, with the following considerations: If we are + // faster than that, queue size will stay low anyway, even if not - requesters will + // get an immediate error, but if we are slower, requesters will run in a timeout - + // wasting precious time. + let available_bandwidth = 7 * MIN_BANDWIDTH_BYTES / 10; + let size = u64::saturating_sub( + STATEMENTS_TIMEOUT.as_millis() as u64 * available_bandwidth / + (1000 * MAX_CODE_SIZE as u64), + MAX_PARALLEL_STATEMENT_REQUESTS as u64, + ); + debug_assert!( + size > 0, + "We should have a channel size greater zero, otherwise we won't accept any requests." + ); + size as usize + }, + // Incoming requests can get bursty, we should also be able to handle them fast on + // average, so something in the ballpark of 100 should be fine. Nodes will retry on + // failure, so having a good value here is mostly about performance tuning. + Protocol::DisputeSendingV1 => 100, + + Protocol::AttestedCandidateVStaging => { + // We assume we can utilize up to 70% of the available bandwidth for statements. + // This is just a guess/estimate, with the following considerations: If we are + // faster than that, queue size will stay low anyway, even if not - requesters will + // get an immediate error, but if we are slower, requesters will run in a timeout - + // wasting precious time. + let available_bandwidth = 7 * MIN_BANDWIDTH_BYTES / 10; + let size = u64::saturating_sub( + ATTESTED_CANDIDATE_TIMEOUT.as_millis() as u64 * available_bandwidth / + (1000 * MAX_CODE_SIZE as u64), + MAX_PARALLEL_ATTESTED_CANDIDATE_REQUESTS as u64, + ); + debug_assert!( + size > 0, + "We should have a channel size greater zero, otherwise we won't accept any requests." + ); + size as usize + }, + } + } + + /// Fallback protocol names of this protocol, as understood by substrate networking. + fn get_fallback_names(self) -> Vec { + self.get_legacy_name().into_iter().map(Into::into).collect() + } + + /// Legacy protocol name associated with each peer set, if any. + const fn get_legacy_name(self) -> Option<&'static str> { + match self { + Protocol::ChunkFetchingV1 => Some("/polkadot/req_chunk/1"), + Protocol::CollationFetchingV1 => Some("/polkadot/req_collation/1"), + Protocol::PoVFetchingV1 => Some("/polkadot/req_pov/1"), + Protocol::AvailableDataFetchingV1 => Some("/polkadot/req_available_data/1"), + Protocol::StatementFetchingV1 => Some("/polkadot/req_statement/1"), + Protocol::DisputeSendingV1 => Some("/polkadot/send_dispute/1"), + + // Introduced after legacy names became legacy. + Protocol::AttestedCandidateVStaging => None, + Protocol::CollationFetchingVStaging => None, + } + } +} + +/// Common properties of any `Request`. +pub trait IsRequest { + /// Each request has a corresponding `Response`. + type Response; + + /// What protocol this `Request` implements. + const PROTOCOL: Protocol; +} + +/// Type for getting on the wire [`Protocol`] names using genesis hash & fork id. +pub struct ReqProtocolNames { + names: HashMap, +} + +impl ReqProtocolNames { + /// Construct [`ReqProtocolNames`] from `genesis_hash` and `fork_id`. + pub fn new>(genesis_hash: Hash, fork_id: Option<&str>) -> Self { + let mut names = HashMap::new(); + for protocol in Protocol::iter() { + names.insert(protocol, Self::generate_name(protocol, &genesis_hash, fork_id)); + } + Self { names } + } + + /// Get on the wire [`Protocol`] name. + pub fn get_name(&self, protocol: Protocol) -> ProtocolName { + self.names + .get(&protocol) + .expect("All `Protocol` enum variants are added above via `strum`; qed") + .clone() + } + + /// Protocol name of this protocol based on `genesis_hash` and `fork_id`. + fn generate_name>( + protocol: Protocol, + genesis_hash: &Hash, + fork_id: Option<&str>, + ) -> ProtocolName { + let prefix = if let Some(fork_id) = fork_id { + format!("/{}/{}", hex::encode(genesis_hash), fork_id) + } else { + format!("/{}", hex::encode(genesis_hash)) + }; + + let short_name = match protocol { + Protocol::ChunkFetchingV1 => "/req_chunk/1", + Protocol::CollationFetchingV1 => "/req_collation/1", + Protocol::PoVFetchingV1 => "/req_pov/1", + Protocol::AvailableDataFetchingV1 => "/req_available_data/1", + Protocol::StatementFetchingV1 => "/req_statement/1", + Protocol::DisputeSendingV1 => "/send_dispute/1", + + Protocol::CollationFetchingVStaging => "/req_collation/2", + Protocol::AttestedCandidateVStaging => "/req_attested_candidate/2", + }; + + format!("{}{}", prefix, short_name).into() + } +} diff --git a/polkadot/node/network/protocol/src/request_response/outgoing.rs b/polkadot/node/network/protocol/src/request_response/outgoing.rs new file mode 100644 index 0000000000000000000000000000000000000000..ddc6b85645bbb1dd457731a0b43f6628d4bf4c29 --- /dev/null +++ b/polkadot/node/network/protocol/src/request_response/outgoing.rs @@ -0,0 +1,191 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use futures::{channel::oneshot, prelude::Future}; + +use parity_scale_codec::{Decode, Encode, Error as DecodingError}; + +use sc_network as network; +use sc_network::PeerId; + +use polkadot_primitives::AuthorityDiscoveryId; + +use super::{v1, vstaging, IsRequest, Protocol}; + +/// All requests that can be sent to the network bridge via `NetworkBridgeTxMessage::SendRequest`. +#[derive(Debug)] +pub enum Requests { + /// Request an availability chunk from a node. + ChunkFetchingV1(OutgoingRequest), + /// Fetch a collation from a collator which previously announced it. + CollationFetchingV1(OutgoingRequest), + /// Fetch a PoV from a validator which previously sent out a seconded statement. + PoVFetchingV1(OutgoingRequest), + /// Request full available data from a node. + AvailableDataFetchingV1(OutgoingRequest), + /// Requests for fetching large statements as part of statement distribution. + StatementFetchingV1(OutgoingRequest), + /// Requests for notifying about an ongoing dispute. + DisputeSendingV1(OutgoingRequest), + + /// Request a candidate and attestations. + AttestedCandidateVStaging(OutgoingRequest), + /// Fetch a collation from a collator which previously announced it. + /// Compared to V1 it requires specifying which candidate is requested by its hash. + CollationFetchingVStaging(OutgoingRequest), +} + +impl Requests { + /// Get the protocol this request conforms to. + pub fn get_protocol(&self) -> Protocol { + match self { + Self::ChunkFetchingV1(_) => Protocol::ChunkFetchingV1, + Self::CollationFetchingV1(_) => Protocol::CollationFetchingV1, + Self::CollationFetchingVStaging(_) => Protocol::CollationFetchingVStaging, + Self::PoVFetchingV1(_) => Protocol::PoVFetchingV1, + Self::AvailableDataFetchingV1(_) => Protocol::AvailableDataFetchingV1, + Self::StatementFetchingV1(_) => Protocol::StatementFetchingV1, + Self::DisputeSendingV1(_) => Protocol::DisputeSendingV1, + Self::AttestedCandidateVStaging(_) => Protocol::AttestedCandidateVStaging, + } + } + + /// Encode the request. + /// + /// The corresponding protocol is returned as well, as we are now leaving typed territory. + /// + /// Note: `Requests` is just an enum collecting all supported requests supported by network + /// bridge, it is never sent over the wire. This function just encodes the individual requests + /// contained in the `enum`. + pub fn encode_request(self) -> (Protocol, OutgoingRequest>) { + match self { + Self::ChunkFetchingV1(r) => r.encode_request(), + Self::CollationFetchingV1(r) => r.encode_request(), + Self::CollationFetchingVStaging(r) => r.encode_request(), + Self::PoVFetchingV1(r) => r.encode_request(), + Self::AvailableDataFetchingV1(r) => r.encode_request(), + Self::StatementFetchingV1(r) => r.encode_request(), + Self::DisputeSendingV1(r) => r.encode_request(), + Self::AttestedCandidateVStaging(r) => r.encode_request(), + } + } +} + +/// Used by the network to send us a response to a request. +pub type ResponseSender = oneshot::Sender, network::RequestFailure>>; + +/// Any error that can occur when sending a request. +#[derive(Debug, thiserror::Error)] +pub enum RequestError { + /// Response could not be decoded. + #[error("Response could not be decoded: {0}")] + InvalidResponse(#[from] DecodingError), + + /// Some error in substrate/libp2p happened. + #[error("{0}")] + NetworkError(#[from] network::RequestFailure), + + /// Response got canceled by networking. + #[error("Response channel got canceled")] + Canceled(#[from] oneshot::Canceled), +} + +impl RequestError { + /// Whether the error represents some kind of timeout condition. + pub fn is_timed_out(&self) -> bool { + match self { + Self::Canceled(_) | + Self::NetworkError(network::RequestFailure::Obsolete) | + Self::NetworkError(network::RequestFailure::Network( + network::OutboundFailure::Timeout, + )) => true, + _ => false, + } + } +} + +/// A request to be sent to the network bridge, including a sender for sending responses/failures. +/// +/// The network implementation will make use of that sender for informing the requesting subsystem +/// about responses/errors. +/// +/// When using `Recipient::Peer`, keep in mind that no address (as in IP address and port) might +/// be known for that specific peer. You are encouraged to use `Peer` for peers that you are +/// expected to be already connected to. +/// When using `Recipient::Authority`, the addresses can be found thanks to the authority +/// discovery system. +#[derive(Debug)] +pub struct OutgoingRequest { + /// Intended recipient of this request. + pub peer: Recipient, + /// The actual request to send over the wire. + pub payload: Req, + /// Sender which is used by networking to get us back a response. + pub pending_response: ResponseSender, +} + +/// Potential recipients of an outgoing request. +#[derive(Debug, Eq, Hash, PartialEq, Clone)] +pub enum Recipient { + /// Recipient is a regular peer and we know its peer id. + Peer(PeerId), + /// Recipient is a validator, we address it via this `AuthorityDiscoveryId`. + Authority(AuthorityDiscoveryId), +} + +/// Responses received for an `OutgoingRequest`. +pub type OutgoingResult = Result; + +impl OutgoingRequest +where + Req: IsRequest + Encode, + Req::Response: Decode, +{ + /// Create a new `OutgoingRequest`. + /// + /// It will contain a sender that is used by the networking for sending back responses. The + /// connected receiver is returned as the second element in the returned tuple. + pub fn new( + peer: Recipient, + payload: Req, + ) -> (Self, impl Future>) { + let (tx, rx) = oneshot::channel(); + let r = Self { peer, payload, pending_response: tx }; + (r, receive_response::(rx)) + } + + /// Encode a request into a `Vec`. + /// + /// As this throws away type information, we also return the `Protocol` this encoded request + /// adheres to. + pub fn encode_request(self) -> (Protocol, OutgoingRequest>) { + let OutgoingRequest { peer, payload, pending_response } = self; + let encoded = OutgoingRequest { peer, payload: payload.encode(), pending_response }; + (Req::PROTOCOL, encoded) + } +} + +/// Future for actually receiving a typed response for an `OutgoingRequest`. +async fn receive_response( + rec: oneshot::Receiver, network::RequestFailure>>, +) -> OutgoingResult +where + Req: IsRequest, + Req::Response: Decode, +{ + let raw = rec.await??; + Ok(Decode::decode(&mut raw.as_ref())?) +} diff --git a/polkadot/node/network/protocol/src/request_response/v1.rs b/polkadot/node/network/protocol/src/request_response/v1.rs new file mode 100644 index 0000000000000000000000000000000000000000..0832593a6a3d938cc4349c57972b850023ae02f6 --- /dev/null +++ b/polkadot/node/network/protocol/src/request_response/v1.rs @@ -0,0 +1,217 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Requests and responses as sent over the wire for the individual protocols. + +use parity_scale_codec::{Decode, Encode}; + +use polkadot_node_primitives::{ + AvailableData, DisputeMessage, ErasureChunk, PoV, Proof, UncheckedDisputeMessage, +}; +use polkadot_primitives::{ + CandidateHash, CandidateReceipt, CommittedCandidateReceipt, Hash, Id as ParaId, ValidatorIndex, +}; + +use super::{IsRequest, Protocol}; + +/// Request an availability chunk. +#[derive(Debug, Copy, Clone, Encode, Decode)] +pub struct ChunkFetchingRequest { + /// Hash of candidate we want a chunk for. + pub candidate_hash: CandidateHash, + /// The index of the chunk to fetch. + pub index: ValidatorIndex, +} + +/// Receive a requested erasure chunk. +#[derive(Debug, Clone, Encode, Decode)] +pub enum ChunkFetchingResponse { + /// The requested chunk data. + #[codec(index = 0)] + Chunk(ChunkResponse), + /// Node was not in possession of the requested chunk. + #[codec(index = 1)] + NoSuchChunk, +} + +impl From> for ChunkFetchingResponse { + fn from(x: Option) -> Self { + match x { + Some(c) => ChunkFetchingResponse::Chunk(c), + None => ChunkFetchingResponse::NoSuchChunk, + } + } +} + +/// Skimmed down variant of `ErasureChunk`. +/// +/// Instead of transmitting a full `ErasureChunk` we transmit `ChunkResponse` in +/// `ChunkFetchingResponse`, which omits the chunk's index. The index is already known by +/// the requester and by not transmitting it, we ensure the requester is going to use his index +/// value for validating the response, thus making sure he got what he requested. +#[derive(Debug, Clone, Encode, Decode)] +pub struct ChunkResponse { + /// The erasure-encoded chunk of data belonging to the candidate block. + pub chunk: Vec, + /// Proof for this chunk's branch in the Merkle tree. + pub proof: Proof, +} + +impl From for ChunkResponse { + fn from(ErasureChunk { chunk, index: _, proof }: ErasureChunk) -> Self { + ChunkResponse { chunk, proof } + } +} + +impl ChunkResponse { + /// Re-build an `ErasureChunk` from response and request. + pub fn recombine_into_chunk(self, req: &ChunkFetchingRequest) -> ErasureChunk { + ErasureChunk { chunk: self.chunk, proof: self.proof, index: req.index } + } +} + +impl IsRequest for ChunkFetchingRequest { + type Response = ChunkFetchingResponse; + const PROTOCOL: Protocol = Protocol::ChunkFetchingV1; +} + +/// Request the advertised collation at that relay-parent. +#[derive(Debug, Clone, Encode, Decode)] +pub struct CollationFetchingRequest { + /// Relay parent we want a collation for. + pub relay_parent: Hash, + /// The `ParaId` of the collation. + pub para_id: ParaId, +} + +/// Responses as sent by collators. +#[derive(Debug, Clone, Encode, Decode)] +pub enum CollationFetchingResponse { + /// Deliver requested collation. + #[codec(index = 0)] + Collation(CandidateReceipt, PoV), +} + +impl IsRequest for CollationFetchingRequest { + type Response = CollationFetchingResponse; + const PROTOCOL: Protocol = Protocol::CollationFetchingV1; +} + +/// Request the advertised collation at that relay-parent. +#[derive(Debug, Clone, Encode, Decode)] +pub struct PoVFetchingRequest { + /// Candidate we want a PoV for. + pub candidate_hash: CandidateHash, +} + +/// Responses to `PoVFetchingRequest`. +#[derive(Debug, Clone, Encode, Decode)] +pub enum PoVFetchingResponse { + /// Deliver requested PoV. + #[codec(index = 0)] + PoV(PoV), + /// PoV was not found in store. + #[codec(index = 1)] + NoSuchPoV, +} + +impl IsRequest for PoVFetchingRequest { + type Response = PoVFetchingResponse; + const PROTOCOL: Protocol = Protocol::PoVFetchingV1; +} + +/// Request the entire available data for a candidate. +#[derive(Debug, Clone, Encode, Decode)] +pub struct AvailableDataFetchingRequest { + /// The candidate hash to get the available data for. + pub candidate_hash: CandidateHash, +} + +/// Receive a requested available data. +#[derive(Debug, Clone, Encode, Decode)] +pub enum AvailableDataFetchingResponse { + /// The requested data. + #[codec(index = 0)] + AvailableData(AvailableData), + /// Node was not in possession of the requested data. + #[codec(index = 1)] + NoSuchData, +} + +impl From> for AvailableDataFetchingResponse { + fn from(x: Option) -> Self { + match x { + Some(data) => AvailableDataFetchingResponse::AvailableData(data), + None => AvailableDataFetchingResponse::NoSuchData, + } + } +} + +impl IsRequest for AvailableDataFetchingRequest { + type Response = AvailableDataFetchingResponse; + const PROTOCOL: Protocol = Protocol::AvailableDataFetchingV1; +} + +/// Request for fetching a large statement via request/response. +#[derive(Debug, Clone, Encode, Decode)] +pub struct StatementFetchingRequest { + /// Data needed to locate and identify the needed statement. + pub relay_parent: Hash, + /// Hash of candidate that was used create the `CommitedCandidateRecept`. + pub candidate_hash: CandidateHash, +} + +/// Respond with found full statement. +/// +/// In this protocol the requester will only request data it was previously notified about, +/// therefore not having the data is not really an option and would just result in a +/// `RequestFailure`. +#[derive(Debug, Clone, Encode, Decode)] +pub enum StatementFetchingResponse { + /// Data missing to reconstruct the full signed statement. + #[codec(index = 0)] + Statement(CommittedCandidateReceipt), +} + +impl IsRequest for StatementFetchingRequest { + type Response = StatementFetchingResponse; + const PROTOCOL: Protocol = Protocol::StatementFetchingV1; +} + +/// A dispute request. +/// +/// Contains an invalid vote a valid one for a particular candidate in a given session. +#[derive(Clone, Encode, Decode, Debug)] +pub struct DisputeRequest(pub UncheckedDisputeMessage); + +impl From for DisputeRequest { + fn from(msg: DisputeMessage) -> Self { + Self(msg.into()) + } +} + +/// Possible responses to a `DisputeRequest`. +#[derive(Encode, Decode, Debug, PartialEq, Eq)] +pub enum DisputeResponse { + /// Recipient successfully processed the dispute request. + #[codec(index = 0)] + Confirmed, +} + +impl IsRequest for DisputeRequest { + type Response = DisputeResponse; + const PROTOCOL: Protocol = Protocol::DisputeSendingV1; +} diff --git a/polkadot/node/network/protocol/src/request_response/vstaging.rs b/polkadot/node/network/protocol/src/request_response/vstaging.rs new file mode 100644 index 0000000000000000000000000000000000000000..f84de9505534aa35f43217ada837ce4184d51d72 --- /dev/null +++ b/polkadot/node/network/protocol/src/request_response/vstaging.rs @@ -0,0 +1,80 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Requests and responses as sent over the wire for the individual protocols. + +use parity_scale_codec::{Decode, Encode}; + +use polkadot_primitives::vstaging::{ + CandidateHash, CommittedCandidateReceipt, Hash, Id as ParaId, PersistedValidationData, + UncheckedSignedStatement, +}; + +use super::{IsRequest, Protocol}; +use crate::vstaging::StatementFilter; + +/// Request a candidate with statements. +#[derive(Debug, Clone, Encode, Decode)] +pub struct AttestedCandidateRequest { + /// Hash of the candidate we want to request. + pub candidate_hash: CandidateHash, + /// Statement filter with 'OR' semantics, indicating which validators + /// not to send statements for. + /// + /// The filter must have exactly the minimum size required to + /// fit all validators from the backing group. + /// + /// The response may not contain any statements masked out by this mask. + pub mask: StatementFilter, +} + +/// Response to an `AttestedCandidateRequest`. +#[derive(Debug, Clone, Encode, Decode)] +pub struct AttestedCandidateResponse { + /// The candidate receipt, with commitments. + pub candidate_receipt: CommittedCandidateReceipt, + /// The [`PersistedValidationData`] corresponding to the candidate. + pub persisted_validation_data: PersistedValidationData, + /// All known statements about the candidate, in compact form, + /// omitting `Seconded` statements which were intended to be masked + /// out. + pub statements: Vec, +} + +impl IsRequest for AttestedCandidateRequest { + type Response = AttestedCandidateResponse; + const PROTOCOL: Protocol = Protocol::AttestedCandidateVStaging; +} + +/// Responses as sent by collators. +pub type CollationFetchingResponse = super::v1::CollationFetchingResponse; + +/// Request the advertised collation at that relay-parent. +#[derive(Debug, Clone, Encode, Decode)] +pub struct CollationFetchingRequest { + /// Relay parent collation is built on top of. + pub relay_parent: Hash, + /// The `ParaId` of the collation. + pub para_id: ParaId, + /// Candidate hash. + pub candidate_hash: CandidateHash, +} + +impl IsRequest for CollationFetchingRequest { + // The response is the same as for V1. + type Response = CollationFetchingResponse; + const PROTOCOL: Protocol = Protocol::CollationFetchingVStaging; +} diff --git a/polkadot/node/network/statement-distribution/Cargo.toml b/polkadot/node/network/statement-distribution/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..b9d52bda5706f133e98e7adc5888d0dc6612c12b --- /dev/null +++ b/polkadot/node/network/statement-distribution/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "polkadot-statement-distribution" +description = "Statement Distribution Subsystem" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +futures-timer = "3.0.2" +gum = { package = "tracing-gum", path = "../../gum" } +polkadot-primitives = { path = "../../../primitives" } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot-node-subsystem = {path = "../../subsystem" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-node-subsystem-util = { path = "../../subsystem-util" } +polkadot-node-network-protocol = { path = "../../network/protocol" } +arrayvec = "0.7.4" +indexmap = "1.9.1" +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +thiserror = "1.0.31" +fatality = "0.0.6" +bitvec = "1" + +[dev-dependencies] +async-channel = "1.8.0" +assert_matches = "1.4.0" +polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures-timer = "3.0.2" +polkadot-primitives-test-helpers = { path = "../../../primitives/test-helpers" } +rand_chacha = "0.3" +polkadot-node-subsystem-types = { path = "../../subsystem-types" } diff --git a/polkadot/node/network/statement-distribution/src/error.rs b/polkadot/node/network/statement-distribution/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..b676e5b6a223540fb3e93abc82dc7a94e861e7e5 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/error.rs @@ -0,0 +1,131 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +// + +//! Error handling related code and Error/Result definitions. + +use polkadot_node_network_protocol::PeerId; +use polkadot_node_subsystem::{RuntimeApiError, SubsystemError}; +use polkadot_node_subsystem_util::{ + backing_implicit_view::FetchError as ImplicitViewFetchError, runtime, +}; +use polkadot_primitives::{CandidateHash, Hash, Id as ParaId}; + +use futures::channel::oneshot; + +use crate::LOG_TARGET; + +/// General result. +pub type Result = std::result::Result; +/// Result for non-fatal only failures. +pub type JfyiErrorResult = std::result::Result; +/// Result for fatal only failures. +pub type FatalResult = std::result::Result; + +use fatality::Nested; + +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + #[fatal] + #[error("Requester receiver stream finished")] + RequesterReceiverFinished, + + #[fatal] + #[error("Responder receiver stream finished")] + ResponderReceiverFinished, + + #[fatal] + #[error("Spawning subsystem task failed")] + SpawnTask(#[source] SubsystemError), + + #[fatal] + #[error("Receiving message from overseer failed")] + SubsystemReceive(#[source] SubsystemError), + + #[fatal(forward)] + #[error("Error while accessing runtime information")] + Runtime(#[from] runtime::Error), + + #[error("RuntimeAPISubsystem channel closed before receipt")] + RuntimeApiUnavailable(#[source] oneshot::Canceled), + + #[error("Fetching persisted validation data for para {0:?}, {1:?}")] + FetchPersistedValidationData(ParaId, RuntimeApiError), + + #[error("Fetching session index failed {0:?}")] + FetchSessionIndex(RuntimeApiError), + + #[error("Fetching session info failed {0:?}")] + FetchSessionInfo(RuntimeApiError), + + #[error("Fetching availability cores failed {0:?}")] + FetchAvailabilityCores(RuntimeApiError), + + #[error("Fetching validator groups failed {0:?}")] + FetchValidatorGroups(RuntimeApiError), + + #[error("Attempted to share statement when not a validator or not assigned")] + InvalidShare, + + #[error("Relay parent could not be found in active heads")] + NoSuchHead(Hash), + + #[error("Message from not connected peer")] + NoSuchPeer(PeerId), + + #[error("Peer requested data for candidate it never received a notification for (malicious?)")] + RequestedUnannouncedCandidate(PeerId, CandidateHash), + + // A large statement status was requested, which could not be found. + #[error("Statement status does not exist")] + NoSuchLargeStatementStatus(Hash, CandidateHash), + + // A fetched large statement was requested, but could not be found. + #[error("Fetched large statement does not exist")] + NoSuchFetchedLargeStatement(Hash, CandidateHash), + + // Responder no longer waits for our data. (Should not happen right now.) + #[error("Oneshot `GetData` channel closed")] + ResponderGetDataCanceled, + + // Failed to activate leaf due to a fetch error. + #[error("Implicit view failure while activating leaf")] + ActivateLeafFailure(ImplicitViewFetchError), +} + +/// Utility for eating top level errors and log them. +/// +/// We basically always want to try and continue on error. This utility function is meant to +/// consume top-level errors by simply logging them. +pub fn log_error( + result: Result<()>, + ctx: &'static str, + warn_freq: &mut gum::Freq, +) -> std::result::Result<(), FatalError> { + match result.into_nested()? { + Err(jfyi) => { + match jfyi { + JfyiError::RequestedUnannouncedCandidate(_, _) => + gum::warn!(target: LOG_TARGET, error = %jfyi, ctx), + _ => + gum::warn_if_frequent!(freq: warn_freq, max_rate: gum::Times::PerHour(100), target: LOG_TARGET, error = %jfyi, ctx), + } + Ok(()) + }, + Ok(()) => Ok(()), + } +} diff --git a/polkadot/node/network/statement-distribution/src/legacy_v1/mod.rs b/polkadot/node/network/statement-distribution/src/legacy_v1/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..b5895cb9f65ba270cc2acd09c58d4e9af1b73a99 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/legacy_v1/mod.rs @@ -0,0 +1,2177 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use parity_scale_codec::Encode; + +use polkadot_node_network_protocol::{ + self as net_protocol, + grid_topology::{GridNeighbors, RequiredRouting, SessionBoundGridTopologyStorage}, + peer_set::{IsAuthority, PeerSet, ValidationVersion}, + v1::{self as protocol_v1, StatementMetadata}, + vstaging as protocol_vstaging, IfDisconnected, PeerId, UnifiedReputationChange as Rep, + Versioned, View, +}; +use polkadot_node_primitives::{ + SignedFullStatement, Statement, StatementWithPVD, UncheckedSignedFullStatement, +}; +use polkadot_node_subsystem_util::{ + self as util, rand, reputation::ReputationAggregator, MIN_GOSSIP_PEERS, +}; + +use polkadot_node_subsystem::{ + jaeger, + messages::{CandidateBackingMessage, NetworkBridgeEvent, NetworkBridgeTxMessage}, + overseer, ActivatedLeaf, PerLeafSpan, StatementDistributionSenderTrait, +}; +use polkadot_primitives::{ + AuthorityDiscoveryId, CandidateHash, CommittedCandidateReceipt, CompactStatement, Hash, + Id as ParaId, IndexedVec, OccupiedCoreAssumption, PersistedValidationData, SignedStatement, + SigningContext, UncheckedSignedStatement, ValidatorId, ValidatorIndex, ValidatorSignature, +}; + +use futures::{ + channel::{mpsc, oneshot}, + future::RemoteHandle, + prelude::*, +}; +use indexmap::{map::Entry as IEntry, IndexMap}; +use rand::Rng; +use sp_keystore::KeystorePtr; +use util::runtime::RuntimeInfo; + +use std::collections::{hash_map::Entry, HashMap, HashSet, VecDeque}; + +use crate::error::{Error, JfyiError, JfyiErrorResult, Result}; + +/// Background task logic for requesting of large statements. +mod requester; +use requester::fetch; + +/// Background task logic for responding for large statements. +mod responder; + +use crate::{metrics::Metrics, LOG_TARGET}; + +pub use requester::RequesterMessage; +pub use responder::{respond, ResponderMessage}; + +#[cfg(test)] +mod tests; + +const COST_UNEXPECTED_STATEMENT: Rep = Rep::CostMinor("Unexpected Statement"); +const COST_UNEXPECTED_STATEMENT_MISSING_KNOWLEDGE: Rep = + Rep::CostMinor("Unexpected Statement, missing knowlege for relay parent"); +const COST_UNEXPECTED_STATEMENT_UNKNOWN_CANDIDATE: Rep = + Rep::CostMinor("Unexpected Statement, unknown candidate"); +const COST_UNEXPECTED_STATEMENT_REMOTE: Rep = + Rep::CostMinor("Unexpected Statement, remote not allowed"); + +const COST_FETCH_FAIL: Rep = + Rep::CostMinor("Requesting `CommittedCandidateReceipt` from peer failed"); +const COST_INVALID_SIGNATURE: Rep = Rep::CostMajor("Invalid Statement Signature"); +const COST_WRONG_HASH: Rep = Rep::CostMajor("Received candidate had wrong hash"); +const COST_DUPLICATE_STATEMENT: Rep = + Rep::CostMajorRepeated("Statement sent more than once by peer"); +const COST_APPARENT_FLOOD: Rep = Rep::Malicious("Peer appears to be flooding us with statements"); + +const BENEFIT_VALID_STATEMENT: Rep = Rep::BenefitMajor("Peer provided a valid statement"); +const BENEFIT_VALID_STATEMENT_FIRST: Rep = + Rep::BenefitMajorFirst("Peer was the first to provide a valid statement"); +const BENEFIT_VALID_RESPONSE: Rep = + Rep::BenefitMajor("Peer provided a valid large statement response"); + +/// The maximum amount of candidates each validator is allowed to second at any relay-parent. +/// Short for "Validator Candidate Threshold". +/// +/// This is the amount of candidates we keep per validator at any relay-parent. +/// Typically we will only keep 1, but when a validator equivocates we will need to track 2. +const VC_THRESHOLD: usize = 2; + +/// Large statements should be rare. +const MAX_LARGE_STATEMENTS_PER_SENDER: usize = 20; + +/// Overall state of the legacy-v1 portion of the subsystem. +pub(crate) struct State { + peers: HashMap, + topology_storage: SessionBoundGridTopologyStorage, + authorities: HashMap, + active_heads: HashMap, + recent_outdated_heads: RecentOutdatedHeads, + runtime: RuntimeInfo, +} + +impl State { + /// Create a new state. + pub(crate) fn new(keystore: KeystorePtr) -> Self { + State { + peers: HashMap::new(), + topology_storage: Default::default(), + authorities: HashMap::new(), + active_heads: HashMap::new(), + recent_outdated_heads: RecentOutdatedHeads::default(), + runtime: RuntimeInfo::new(Some(keystore)), + } + } + + /// Query whether the state contains some relay-parent. + pub(crate) fn contains_relay_parent(&self, relay_parent: &Hash) -> bool { + self.active_heads.contains_key(relay_parent) + } +} + +#[derive(Default)] +struct RecentOutdatedHeads { + buf: VecDeque, +} + +impl RecentOutdatedHeads { + fn note_outdated(&mut self, hash: Hash) { + const MAX_BUF_LEN: usize = 10; + + self.buf.push_back(hash); + + while self.buf.len() > MAX_BUF_LEN { + let _ = self.buf.pop_front(); + } + } + + fn is_recent_outdated(&self, hash: &Hash) -> bool { + self.buf.contains(hash) + } +} + +/// Tracks our impression of a single peer's view of the candidates a validator has seconded +/// for a given relay-parent. +/// +/// It is expected to receive at most `VC_THRESHOLD` from us and be aware of at most `VC_THRESHOLD` +/// via other means. +#[derive(Default)] +struct VcPerPeerTracker { + local_observed: arrayvec::ArrayVec, + remote_observed: arrayvec::ArrayVec, +} + +impl VcPerPeerTracker { + /// Note that the remote should now be aware that a validator has seconded a given candidate (by + /// hash) based on a message that we have sent it from our local pool. + fn note_local(&mut self, h: CandidateHash) { + if !note_hash(&mut self.local_observed, h) { + gum::warn!( + target: LOG_TARGET, + "Statement distribution is erroneously attempting to distribute more \ + than {} candidate(s) per validator index. Ignoring", + VC_THRESHOLD, + ); + } + } + + /// Note that the remote should now be aware that a validator has seconded a given candidate (by + /// hash) based on a message that it has sent us. + /// + /// Returns `true` if the peer was allowed to send us such a message, `false` otherwise. + fn note_remote(&mut self, h: CandidateHash) -> bool { + note_hash(&mut self.remote_observed, h) + } + + /// Returns `true` if the peer is allowed to send us such a message, `false` otherwise. + fn is_wanted_candidate(&self, h: &CandidateHash) -> bool { + !self.remote_observed.contains(h) && !self.remote_observed.is_full() + } +} + +fn note_hash( + observed: &mut arrayvec::ArrayVec, + h: CandidateHash, +) -> bool { + if observed.contains(&h) { + return true + } + + observed.try_push(h).is_ok() +} + +/// knowledge that a peer has about goings-on in a relay parent. +#[derive(Default)] +struct PeerRelayParentKnowledge { + /// candidates that the peer is aware of because we sent statements to it. This indicates that + /// we can send other statements pertaining to that candidate. + sent_candidates: HashSet, + /// candidates that peer is aware of, because we received statements from it. + received_candidates: HashSet, + /// fingerprints of all statements a peer should be aware of: those that + /// were sent to the peer by us. + sent_statements: HashSet<(CompactStatement, ValidatorIndex)>, + /// fingerprints of all statements a peer should be aware of: those that + /// were sent to us by the peer. + received_statements: HashSet<(CompactStatement, ValidatorIndex)>, + /// How many candidates this peer is aware of for each given validator index. + seconded_counts: HashMap, + /// How many statements we've received for each candidate that we're aware of. + received_message_count: HashMap, + + /// How many large statements this peer already sent us. + /// + /// Flood protection for large statements is rather hard and as soon as we get + /// `https://github.com/paritytech/polkadot/issues/2979` implemented also no longer necessary. + /// Reason: We keep messages around until we fetched the payload, but if a node makes up + /// statements and never provides the data, we will keep it around for the slot duration. Not + /// even signature checking would help, as the sender, if a validator, can just sign arbitrary + /// invalid statements and will not face any consequences as long as it won't provide the + /// payload. + /// + /// Quick and temporary fix, only accept `MAX_LARGE_STATEMENTS_PER_SENDER` per connected node. + /// + /// Large statements should be rare, if they were not, we would run into problems anyways, as + /// we would not be able to distribute them in a timely manner. Therefore + /// `MAX_LARGE_STATEMENTS_PER_SENDER` can be set to a relatively small number. It is also not + /// per candidate hash, but in total as candidate hashes can be made up, as illustrated above. + /// + /// An attacker could still try to fill up our memory, by repeatedly disconnecting and + /// connecting again with new peer ids, but we assume that the resulting effective bandwidth + /// for such an attack would be too low. + large_statement_count: usize, + + /// We have seen a message that that is unexpected from this peer, so note this fact + /// and stop subsequent logging and peer reputation flood. + unexpected_count: usize, +} + +impl PeerRelayParentKnowledge { + /// Updates our view of the peer's knowledge with this statement's fingerprint based + /// on something that we would like to send to the peer. + /// + /// NOTE: assumes `self.can_send` returned true before this call. + /// + /// Once the knowledge has incorporated a statement, it cannot be incorporated again. + /// + /// This returns `true` if this is the first time the peer has become aware of a + /// candidate with the given hash. + fn send(&mut self, fingerprint: &(CompactStatement, ValidatorIndex)) -> bool { + debug_assert!( + self.can_send(fingerprint), + "send is only called after `can_send` returns true; qed", + ); + + let new_known = match fingerprint.0 { + CompactStatement::Seconded(ref h) => { + self.seconded_counts.entry(fingerprint.1).or_default().note_local(*h); + + let was_known = self.is_known_candidate(h); + self.sent_candidates.insert(*h); + !was_known + }, + CompactStatement::Valid(_) => false, + }; + + self.sent_statements.insert(fingerprint.clone()); + + new_known + } + + /// This returns `true` if the peer cannot accept this statement, without altering internal + /// state, `false` otherwise. + fn can_send(&self, fingerprint: &(CompactStatement, ValidatorIndex)) -> bool { + let already_known = self.sent_statements.contains(fingerprint) || + self.received_statements.contains(fingerprint); + + if already_known { + return false + } + + match fingerprint.0 { + CompactStatement::Valid(ref h) => { + // The peer can only accept Valid statements for which it is aware + // of the corresponding candidate. + self.is_known_candidate(h) + }, + CompactStatement::Seconded(_) => true, + } + } + + /// Attempt to update our view of the peer's knowledge with this statement's fingerprint based + /// on a message we are receiving from the peer. + /// + /// Provide the maximum message count that we can receive per candidate. In practice we should + /// not receive more statements for any one candidate than there are members in the group + /// assigned to that para, but this maximum needs to be lenient to account for equivocations + /// that may be cross-group. As such, a maximum of 2 * `n_validators` is recommended. + /// + /// This returns an error if the peer should not have sent us this message according to protocol + /// rules for flood protection. + /// + /// If this returns `Ok`, the internal state has been altered. After `receive`ing a new + /// candidate, we are then cleared to send the peer further statements about that candidate. + /// + /// This returns `Ok(true)` if this is the first time the peer has become aware of a + /// candidate with given hash. + fn receive( + &mut self, + fingerprint: &(CompactStatement, ValidatorIndex), + max_message_count: usize, + ) -> std::result::Result { + // We don't check `sent_statements` because a statement could be in-flight from both + // sides at the same time. + if self.received_statements.contains(fingerprint) { + return Err(COST_DUPLICATE_STATEMENT) + } + + let (candidate_hash, fresh) = match fingerprint.0 { + CompactStatement::Seconded(ref h) => { + let allowed_remote = self + .seconded_counts + .entry(fingerprint.1) + .or_insert_with(Default::default) + .note_remote(*h); + + if !allowed_remote { + return Err(COST_UNEXPECTED_STATEMENT_REMOTE) + } + + (h, !self.is_known_candidate(h)) + }, + CompactStatement::Valid(ref h) => { + if !self.is_known_candidate(h) { + return Err(COST_UNEXPECTED_STATEMENT_UNKNOWN_CANDIDATE) + } + + (h, false) + }, + }; + + { + let received_per_candidate = + self.received_message_count.entry(*candidate_hash).or_insert(0); + + if *received_per_candidate >= max_message_count { + return Err(COST_APPARENT_FLOOD) + } + + *received_per_candidate += 1; + } + + self.received_statements.insert(fingerprint.clone()); + self.received_candidates.insert(*candidate_hash); + Ok(fresh) + } + + /// Note a received large statement metadata. + fn receive_large_statement(&mut self) -> std::result::Result<(), Rep> { + if self.large_statement_count >= MAX_LARGE_STATEMENTS_PER_SENDER { + return Err(COST_APPARENT_FLOOD) + } + self.large_statement_count += 1; + Ok(()) + } + + /// This method does the same checks as `receive` without modifying the internal state. + /// Returns an error if the peer should not have sent us this message according to protocol + /// rules for flood protection. + fn check_can_receive( + &self, + fingerprint: &(CompactStatement, ValidatorIndex), + max_message_count: usize, + ) -> std::result::Result<(), Rep> { + // We don't check `sent_statements` because a statement could be in-flight from both + // sides at the same time. + if self.received_statements.contains(fingerprint) { + return Err(COST_DUPLICATE_STATEMENT) + } + + let candidate_hash = match fingerprint.0 { + CompactStatement::Seconded(ref h) => { + let allowed_remote = self + .seconded_counts + .get(&fingerprint.1) + .map_or(true, |r| r.is_wanted_candidate(h)); + + if !allowed_remote { + return Err(COST_UNEXPECTED_STATEMENT_REMOTE) + } + + h + }, + CompactStatement::Valid(ref h) => { + if !self.is_known_candidate(&h) { + return Err(COST_UNEXPECTED_STATEMENT_UNKNOWN_CANDIDATE) + } + + h + }, + }; + + let received_per_candidate = self.received_message_count.get(candidate_hash).unwrap_or(&0); + + if *received_per_candidate >= max_message_count { + Err(COST_APPARENT_FLOOD) + } else { + Ok(()) + } + } + + /// Check for candidates that the peer is aware of. This indicates that we can + /// send other statements pertaining to that candidate. + fn is_known_candidate(&self, candidate: &CandidateHash) -> bool { + self.sent_candidates.contains(candidate) || self.received_candidates.contains(candidate) + } +} + +pub struct PeerData { + view: View, + protocol_version: ValidationVersion, + view_knowledge: HashMap, + /// Peer might be known as authority with the given ids. + maybe_authority: Option>, +} + +impl PeerData { + /// Updates our view of the peer's knowledge with this statement's fingerprint based + /// on something that we would like to send to the peer. + /// + /// NOTE: assumes `self.can_send` returned true before this call. + /// + /// Once the knowledge has incorporated a statement, it cannot be incorporated again. + /// + /// This returns `true` if this is the first time the peer has become aware of a + /// candidate with the given hash. + fn send( + &mut self, + relay_parent: &Hash, + fingerprint: &(CompactStatement, ValidatorIndex), + ) -> bool { + debug_assert!( + self.can_send(relay_parent, fingerprint), + "send is only called after `can_send` returns true; qed", + ); + self.view_knowledge + .get_mut(relay_parent) + .expect("send is only called after `can_send` returns true; qed") + .send(fingerprint) + } + + /// This returns `None` if the peer cannot accept this statement, without altering internal + /// state. + fn can_send( + &self, + relay_parent: &Hash, + fingerprint: &(CompactStatement, ValidatorIndex), + ) -> bool { + self.view_knowledge.get(relay_parent).map_or(false, |k| k.can_send(fingerprint)) + } + + /// Attempt to update our view of the peer's knowledge with this statement's fingerprint based + /// on a message we are receiving from the peer. + /// + /// Provide the maximum message count that we can receive per candidate. In practice we should + /// not receive more statements for any one candidate than there are members in the group + /// assigned to that para, but this maximum needs to be lenient to account for equivocations + /// that may be cross-group. As such, a maximum of 2 * `n_validators` is recommended. + /// + /// This returns an error if the peer should not have sent us this message according to protocol + /// rules for flood protection. + /// + /// If this returns `Ok`, the internal state has been altered. After `receive`ing a new + /// candidate, we are then cleared to send the peer further statements about that candidate. + /// + /// This returns `Ok(true)` if this is the first time the peer has become aware of a + /// candidate with given hash. + fn receive( + &mut self, + relay_parent: &Hash, + fingerprint: &(CompactStatement, ValidatorIndex), + max_message_count: usize, + ) -> std::result::Result { + self.view_knowledge + .get_mut(relay_parent) + .ok_or(COST_UNEXPECTED_STATEMENT_MISSING_KNOWLEDGE)? + .receive(fingerprint, max_message_count) + } + + /// This method does the same checks as `receive` without modifying the internal state. + /// Returns an error if the peer should not have sent us this message according to protocol + /// rules for flood protection. + fn check_can_receive( + &self, + relay_parent: &Hash, + fingerprint: &(CompactStatement, ValidatorIndex), + max_message_count: usize, + ) -> std::result::Result<(), Rep> { + self.view_knowledge + .get(relay_parent) + .ok_or(COST_UNEXPECTED_STATEMENT_MISSING_KNOWLEDGE)? + .check_can_receive(fingerprint, max_message_count) + } + + /// Receive a notice about out of view statement and returns the value of the old flag + fn receive_unexpected(&mut self, relay_parent: &Hash) -> usize { + self.view_knowledge + .get_mut(relay_parent) + .map_or(0_usize, |relay_parent_peer_knowledge| { + let old = relay_parent_peer_knowledge.unexpected_count; + relay_parent_peer_knowledge.unexpected_count += 1_usize; + old + }) + } + + /// Basic flood protection for large statements. + fn receive_large_statement(&mut self, relay_parent: &Hash) -> std::result::Result<(), Rep> { + self.view_knowledge + .get_mut(relay_parent) + .ok_or(COST_UNEXPECTED_STATEMENT_MISSING_KNOWLEDGE)? + .receive_large_statement() + } +} + +// A statement stored while a relay chain head is active. +#[derive(Debug, Copy, Clone)] +struct StoredStatement<'a> { + comparator: &'a StoredStatementComparator, + statement: &'a SignedFullStatement, +} + +// A value used for comparison of stored statements to each other. +// +// The compact version of the statement, the validator index, and the signature of the validator +// is enough to differentiate between all types of equivocations, as long as the signature is +// actually checked to be valid. The same statement with 2 signatures and 2 statements with +// different (or same) signatures wll all be correctly judged to be unequal with this comparator. +#[derive(PartialEq, Eq, Hash, Clone, Debug)] +struct StoredStatementComparator { + compact: CompactStatement, + validator_index: ValidatorIndex, + signature: ValidatorSignature, +} + +impl<'a> From<(&'a StoredStatementComparator, &'a SignedFullStatement)> for StoredStatement<'a> { + fn from( + (comparator, statement): (&'a StoredStatementComparator, &'a SignedFullStatement), + ) -> Self { + Self { comparator, statement } + } +} + +impl<'a> StoredStatement<'a> { + fn compact(&self) -> &'a CompactStatement { + &self.comparator.compact + } + + fn fingerprint(&self) -> (CompactStatement, ValidatorIndex) { + (self.comparator.compact.clone(), self.statement.validator_index()) + } +} + +#[derive(Debug)] +enum NotedStatement<'a> { + NotUseful, + Fresh(StoredStatement<'a>), + UsefulButKnown, +} + +/// Large statement fetching status. +enum LargeStatementStatus { + /// We are currently fetching the statement data from a remote peer. We keep a list of other + /// nodes claiming to have that data and will fallback on them. + Fetching(FetchingInfo), + /// Statement data is fetched or we got it locally via `StatementDistributionMessage::Share`. + FetchedOrShared(CommittedCandidateReceipt), +} + +/// Info about a fetch in progress. +struct FetchingInfo { + /// All peers that send us a `LargeStatement` or a `Valid` statement for the given + /// `CandidateHash`, together with their originally sent messages. + /// + /// We use an `IndexMap` here to preserve the ordering of peers sending us messages. This is + /// desirable because we reward first sending peers with reputation. + available_peers: IndexMap>, + /// Peers left to try in case the background task needs it. + peers_to_try: Vec, + /// Sender for sending fresh peers to the fetching task in case of failure. + peer_sender: Option>>, + /// Task taking care of the request. + /// + /// Will be killed once dropped. + #[allow(dead_code)] + fetching_task: RemoteHandle<()>, +} + +#[derive(Debug, PartialEq, Eq)] +enum DeniedStatement { + NotUseful, + UsefulButKnown, +} + +pub(crate) struct ActiveHeadData { + /// All candidates we are aware of for this head, keyed by hash. + candidates: HashSet, + /// Persisted validation data cache. + cached_validation_data: HashMap, + /// Stored statements for circulation to peers. + /// + /// These are iterable in insertion order, and `Seconded` statements are always + /// accepted before dependent statements. + statements: IndexMap, + /// Large statements we are waiting for with associated meta data. + waiting_large_statements: HashMap, + /// The parachain validators at the head's child session index. + validators: IndexedVec, + /// The current session index of this fork. + session_index: sp_staking::SessionIndex, + /// How many `Seconded` statements we've seen per validator. + seconded_counts: HashMap, + /// A Jaeger span for this head, so we can attach data to it. + span: PerLeafSpan, +} + +impl ActiveHeadData { + fn new( + validators: IndexedVec, + session_index: sp_staking::SessionIndex, + span: PerLeafSpan, + ) -> Self { + ActiveHeadData { + candidates: Default::default(), + cached_validation_data: Default::default(), + statements: Default::default(), + waiting_large_statements: Default::default(), + validators, + session_index, + seconded_counts: Default::default(), + span, + } + } + + /// Fetches the `PersistedValidationData` from the runtime, assuming + /// that the core is free. The relay parent must match that of the active + /// head. + async fn fetch_persisted_validation_data( + &mut self, + sender: &mut Sender, + relay_parent: Hash, + para_id: ParaId, + ) -> Result> + where + Sender: StatementDistributionSenderTrait, + { + if let Entry::Vacant(entry) = self.cached_validation_data.entry(para_id) { + let persisted_validation_data = + polkadot_node_subsystem_util::request_persisted_validation_data( + relay_parent, + para_id, + OccupiedCoreAssumption::Free, + sender, + ) + .await + .await + .map_err(Error::RuntimeApiUnavailable)? + .map_err(|err| Error::FetchPersistedValidationData(para_id, err))?; + + match persisted_validation_data { + Some(pvd) => entry.insert(pvd), + None => return Ok(None), + }; + } + + Ok(self.cached_validation_data.get(¶_id)) + } + + /// Note the given statement. + /// + /// If it was not already known and can be accepted, returns `NotedStatement::Fresh`, + /// with a handle to the statement. + /// + /// If it can be accepted, but we already know it, returns `NotedStatement::UsefulButKnown`. + /// + /// We accept up to `VC_THRESHOLD` (2 at time of writing) `Seconded` statements + /// per validator. These will be the first ones we see. The statement is assumed + /// to have been checked, including that the validator index is not out-of-bounds and + /// the signature is valid. + /// + /// Any other statements or those that reference a candidate we are not aware of cannot be + /// accepted and will return `NotedStatement::NotUseful`. + fn note_statement(&mut self, statement: SignedFullStatement) -> NotedStatement { + let validator_index = statement.validator_index(); + let comparator = StoredStatementComparator { + compact: statement.payload().to_compact(), + validator_index, + signature: statement.signature().clone(), + }; + + match comparator.compact { + CompactStatement::Seconded(h) => { + let seconded_so_far = self.seconded_counts.entry(validator_index).or_insert(0); + if *seconded_so_far >= VC_THRESHOLD { + gum::trace!( + target: LOG_TARGET, + ?validator_index, + ?statement, + "Extra statement is ignored" + ); + return NotedStatement::NotUseful + } + + self.candidates.insert(h); + if let Some(old) = self.statements.insert(comparator.clone(), statement) { + gum::trace!( + target: LOG_TARGET, + ?validator_index, + statement = ?old, + "Known statement" + ); + NotedStatement::UsefulButKnown + } else { + *seconded_so_far += 1; + + gum::trace!( + target: LOG_TARGET, + ?validator_index, + statement = ?self.statements.last().expect("Just inserted").1, + "Noted new statement" + ); + // This will always return `Some` because it was just inserted. + let key_value = self + .statements + .get_key_value(&comparator) + .expect("Statement was just inserted; qed"); + + NotedStatement::Fresh(key_value.into()) + } + }, + CompactStatement::Valid(h) => { + if !self.candidates.contains(&h) { + gum::trace!( + target: LOG_TARGET, + ?validator_index, + ?statement, + "Statement for unknown candidate" + ); + return NotedStatement::NotUseful + } + + if let Some(old) = self.statements.insert(comparator.clone(), statement) { + gum::trace!( + target: LOG_TARGET, + ?validator_index, + statement = ?old, + "Known statement" + ); + NotedStatement::UsefulButKnown + } else { + gum::trace!( + target: LOG_TARGET, + ?validator_index, + statement = ?self.statements.last().expect("Just inserted").1, + "Noted new statement" + ); + // This will always return `Some` because it was just inserted. + NotedStatement::Fresh( + self.statements + .get_key_value(&comparator) + .expect("Statement was just inserted; qed") + .into(), + ) + } + }, + } + } + + /// Returns an error if the statement is already known or not useful + /// without modifying the internal state. + fn check_useful_or_unknown( + &self, + statement: &UncheckedSignedStatement, + ) -> std::result::Result<(), DeniedStatement> { + let validator_index = statement.unchecked_validator_index(); + let compact = statement.unchecked_payload(); + let comparator = StoredStatementComparator { + compact: compact.clone(), + validator_index, + signature: statement.unchecked_signature().clone(), + }; + + match compact { + CompactStatement::Seconded(_) => { + let seconded_so_far = self.seconded_counts.get(&validator_index).unwrap_or(&0); + if *seconded_so_far >= VC_THRESHOLD { + gum::trace!( + target: LOG_TARGET, + ?validator_index, + ?statement, + "Extra statement is ignored", + ); + return Err(DeniedStatement::NotUseful) + } + + if self.statements.contains_key(&comparator) { + gum::trace!( + target: LOG_TARGET, + ?validator_index, + ?statement, + "Known statement", + ); + return Err(DeniedStatement::UsefulButKnown) + } + }, + CompactStatement::Valid(h) => { + if !self.candidates.contains(&h) { + gum::trace!( + target: LOG_TARGET, + ?validator_index, + ?statement, + "Statement for unknown candidate", + ); + return Err(DeniedStatement::NotUseful) + } + + if self.statements.contains_key(&comparator) { + gum::trace!( + target: LOG_TARGET, + ?validator_index, + ?statement, + "Known statement", + ); + return Err(DeniedStatement::UsefulButKnown) + } + }, + } + Ok(()) + } + + /// Get an iterator over all statements for the active head. Seconded statements come first. + fn statements(&self) -> impl Iterator> + '_ { + self.statements.iter().map(Into::into) + } + + /// Get an iterator over all statements for the active head that are for a particular candidate. + fn statements_about( + &self, + candidate_hash: CandidateHash, + ) -> impl Iterator> + '_ { + self.statements() + .filter(move |s| s.compact().candidate_hash() == &candidate_hash) + } +} + +/// Check a statement signature under this parent hash. +fn check_statement_signature( + head: &ActiveHeadData, + relay_parent: Hash, + statement: UncheckedSignedStatement, +) -> std::result::Result { + let signing_context = + SigningContext { session_index: head.session_index, parent_hash: relay_parent }; + + head.validators + .get(statement.unchecked_validator_index()) + .ok_or_else(|| statement.clone()) + .and_then(|v| statement.try_into_checked(&signing_context, v)) +} + +/// Places the statement in storage if it is new, and then +/// circulates the statement to all peers who have not seen it yet, and +/// sends all statements dependent on that statement to peers who could previously not receive +/// them but now can. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn circulate_statement_and_dependents( + topology_store: &SessionBoundGridTopologyStorage, + peers: &mut HashMap, + active_heads: &mut HashMap, + ctx: &mut Context, + relay_parent: Hash, + statement: SignedFullStatement, + priority_peers: Vec, + metrics: &Metrics, + rng: &mut impl rand::Rng, +) { + let active_head = match active_heads.get_mut(&relay_parent) { + Some(res) => res, + None => return, + }; + + let _span = active_head + .span + .child("circulate-statement") + .with_candidate(statement.payload().candidate_hash()) + .with_stage(jaeger::Stage::StatementDistribution); + + let topology = topology_store + .get_topology_or_fallback(active_head.session_index) + .local_grid_neighbors(); + // First circulate the statement directly to all peers needing it. + // The borrow of `active_head` needs to encompass only this (Rust) statement. + let outputs: Option<(CandidateHash, Vec)> = { + match active_head.note_statement(statement) { + NotedStatement::Fresh(stored) => Some(( + *stored.compact().candidate_hash(), + circulate_statement( + RequiredRouting::GridXY, + topology, + peers, + ctx, + relay_parent, + stored, + priority_peers, + metrics, + rng, + ) + .await, + )), + _ => None, + } + }; + + let _span = _span.child("send-to-peers"); + // Now send dependent statements to all peers needing them, if any. + if let Some((candidate_hash, peers_needing_dependents)) = outputs { + for peer in peers_needing_dependents { + if let Some(peer_data) = peers.get_mut(&peer) { + let _span_loop = _span.child("to-peer").with_peer_id(&peer); + // defensive: the peer data should always be some because the iterator + // of peers is derived from the set of peers. + send_statements_about( + peer, + peer_data, + ctx, + relay_parent, + candidate_hash, + &*active_head, + metrics, + ) + .await; + } + } + } +} + +/// Create a network message from a given statement. +fn v1_statement_message( + relay_parent: Hash, + statement: SignedFullStatement, + metrics: &Metrics, +) -> protocol_v1::StatementDistributionMessage { + let (is_large, size) = is_statement_large(&statement); + if let Some(size) = size { + metrics.on_created_message(size); + } + + if is_large { + protocol_v1::StatementDistributionMessage::LargeStatement(StatementMetadata { + relay_parent, + candidate_hash: statement.payload().candidate_hash(), + signed_by: statement.validator_index(), + signature: statement.signature().clone(), + }) + } else { + protocol_v1::StatementDistributionMessage::Statement(relay_parent, statement.into()) + } +} + +/// Check whether a statement should be treated as large statement. +/// +/// Also report size of statement - if it is a `Seconded` statement, otherwise `None`. +fn is_statement_large(statement: &SignedFullStatement) -> (bool, Option) { + match &statement.payload() { + Statement::Seconded(committed) => { + let size = statement.as_unchecked().encoded_size(); + // Runtime upgrades will always be large and even if not - no harm done. + if committed.commitments.new_validation_code.is_some() { + return (true, Some(size)) + } + + // Half max size seems to be a good threshold to start not using notifications: + let threshold = + PeerSet::Validation.get_max_notification_size(IsAuthority::Yes) as usize / 2; + + (size >= threshold, Some(size)) + }, + Statement::Valid(_) => (false, None), + } +} + +/// Circulates a statement to all peers who have not seen it yet, and returns +/// an iterator over peers who need to have dependent statements sent. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn circulate_statement<'a, Context>( + required_routing: RequiredRouting, + topology: &GridNeighbors, + peers: &mut HashMap, + ctx: &mut Context, + relay_parent: Hash, + stored: StoredStatement<'a>, + mut priority_peers: Vec, + metrics: &Metrics, + rng: &mut impl rand::Rng, +) -> Vec { + let fingerprint = stored.fingerprint(); + + let mut peers_to_send: Vec = peers + .iter() + .filter_map( + |(peer, data)| { + if data.can_send(&relay_parent, &fingerprint) { + Some(*peer) + } else { + None + } + }, + ) + .collect(); + + let good_peers: HashSet<&PeerId> = peers_to_send.iter().collect(); + // Only take priority peers we can send data to: + priority_peers.retain(|p| good_peers.contains(p)); + + // Avoid duplicates: + let priority_set: HashSet<&PeerId> = priority_peers.iter().collect(); + peers_to_send.retain(|p| !priority_set.contains(p)); + + util::choose_random_subset_with_rng( + |e| topology.route_to_peer(required_routing, e), + &mut peers_to_send, + rng, + MIN_GOSSIP_PEERS, + ); + + // We don't want to use less peers, than we would without any priority peers: + let min_size = std::cmp::max(peers_to_send.len(), MIN_GOSSIP_PEERS); + // Make set full: + let needed_peers = min_size as i64 - priority_peers.len() as i64; + if needed_peers > 0 { + peers_to_send.truncate(needed_peers as usize); + // Order important here - priority peers are placed first, so will be sent first. + // This gives backers a chance to be among the first in requesting any large statement + // data. + priority_peers.append(&mut peers_to_send); + } + peers_to_send = priority_peers; + // We must not have duplicates: + debug_assert!( + peers_to_send.len() == peers_to_send.clone().into_iter().collect::>().len(), + "We filter out duplicates above. qed.", + ); + + let (v1_peers_to_send, vstaging_peers_to_send) = peers_to_send + .into_iter() + .map(|peer_id| { + let peer_data = + peers.get_mut(&peer_id).expect("a subset is taken above, so it exists; qed"); + + let new = peer_data.send(&relay_parent, &fingerprint); + + (peer_id, new, peer_data.protocol_version) + }) + .partition::, _>(|(_, _, version)| match version { + ValidationVersion::V1 => true, + ValidationVersion::VStaging => false, + }); // partition is handy here but not if we add more protocol versions + + let payload = v1_statement_message(relay_parent, stored.statement.clone(), metrics); + + // Send all these peers the initial statement. + if !v1_peers_to_send.is_empty() { + gum::trace!( + target: LOG_TARGET, + ?v1_peers_to_send, + ?relay_parent, + statement = ?stored.statement, + "Sending statement to v1 peers", + ); + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + v1_peers_to_send.iter().map(|(p, _, _)| *p).collect(), + compatible_v1_message(ValidationVersion::V1, payload.clone()).into(), + )) + .await; + } + if !vstaging_peers_to_send.is_empty() { + gum::trace!( + target: LOG_TARGET, + ?vstaging_peers_to_send, + ?relay_parent, + statement = ?stored.statement, + "Sending statement to vstaging peers", + ); + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + vstaging_peers_to_send.iter().map(|(p, _, _)| *p).collect(), + compatible_v1_message(ValidationVersion::VStaging, payload.clone()).into(), + )) + .await; + } + + v1_peers_to_send + .into_iter() + .chain(vstaging_peers_to_send) + .filter_map(|(peer, needs_dependent, _)| if needs_dependent { Some(peer) } else { None }) + .collect() +} + +/// Send all statements about a given candidate hash to a peer. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn send_statements_about( + peer: PeerId, + peer_data: &mut PeerData, + ctx: &mut Context, + relay_parent: Hash, + candidate_hash: CandidateHash, + active_head: &ActiveHeadData, + metrics: &Metrics, +) { + for statement in active_head.statements_about(candidate_hash) { + let fingerprint = statement.fingerprint(); + if !peer_data.can_send(&relay_parent, &fingerprint) { + continue + } + peer_data.send(&relay_parent, &fingerprint); + let payload = v1_statement_message(relay_parent, statement.statement.clone(), metrics); + + gum::trace!( + target: LOG_TARGET, + ?peer, + ?relay_parent, + ?candidate_hash, + statement = ?statement.statement, + "Sending statement", + ); + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + vec![peer], + compatible_v1_message(peer_data.protocol_version, payload).into(), + )) + .await; + + metrics.on_statement_distributed(); + } +} + +/// Send all statements at a given relay-parent to a peer. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn send_statements( + peer: PeerId, + peer_data: &mut PeerData, + ctx: &mut Context, + relay_parent: Hash, + active_head: &ActiveHeadData, + metrics: &Metrics, +) { + for statement in active_head.statements() { + let fingerprint = statement.fingerprint(); + if !peer_data.can_send(&relay_parent, &fingerprint) { + continue + } + peer_data.send(&relay_parent, &fingerprint); + let payload = v1_statement_message(relay_parent, statement.statement.clone(), metrics); + + gum::trace!( + target: LOG_TARGET, + ?peer, + ?relay_parent, + statement = ?statement.statement, + "Sending statement" + ); + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + vec![peer], + compatible_v1_message(peer_data.protocol_version, payload).into(), + )) + .await; + + metrics.on_statement_distributed(); + } +} + +/// Modify the reputation of a peer based on its behavior. +async fn modify_reputation( + reputation: &mut ReputationAggregator, + sender: &mut impl overseer::StatementDistributionSenderTrait, + peer: PeerId, + rep: Rep, +) { + reputation.modify(sender, peer, rep).await; +} + +/// If message contains a statement, then retrieve it, otherwise fork task to fetch it. +/// +/// This function will also return `None` if the message did not pass some basic checks, in that +/// case no statement will be requested, on the flipside you get `ActiveHeadData` in addition to +/// your statement. +/// +/// If the message was large, but the result has been fetched already that one is returned. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn retrieve_statement_from_message<'a, Context>( + peer: PeerId, + peer_version: ValidationVersion, + message: protocol_v1::StatementDistributionMessage, + active_head: &'a mut ActiveHeadData, + ctx: &mut Context, + req_sender: &mpsc::Sender, + metrics: &Metrics, +) -> Option { + let fingerprint = message.get_fingerprint(); + let candidate_hash = *fingerprint.0.candidate_hash(); + + // Immediately return any Seconded statement: + let message = if let protocol_v1::StatementDistributionMessage::Statement(h, s) = message { + if let Statement::Seconded(_) = s.unchecked_payload() { + return Some(s) + } + protocol_v1::StatementDistributionMessage::Statement(h, s) + } else { + message + }; + + match active_head.waiting_large_statements.entry(candidate_hash) { + Entry::Occupied(mut occupied) => { + match occupied.get_mut() { + LargeStatementStatus::Fetching(info) => { + let is_large_statement = message.is_large_statement(); + + let is_new_peer = match info.available_peers.entry(peer) { + IEntry::Occupied(mut occupied) => { + occupied.get_mut().push(compatible_v1_message(peer_version, message)); + false + }, + IEntry::Vacant(vacant) => { + vacant.insert(vec![compatible_v1_message(peer_version, message)]); + true + }, + }; + + if is_new_peer & is_large_statement { + info.peers_to_try.push(peer); + // Answer any pending request for more peers: + if let Some(sender) = info.peer_sender.take() { + let to_send = std::mem::take(&mut info.peers_to_try); + if let Err(peers) = sender.send(to_send) { + // Requester no longer interested for now, might want them + // later: + info.peers_to_try = peers; + } + } + } + }, + LargeStatementStatus::FetchedOrShared(committed) => { + match message { + protocol_v1::StatementDistributionMessage::Statement(_, s) => { + // We can now immediately return any statements (should only be + // `Statement::Valid` ones, but we don't care at this point.) + return Some(s) + }, + protocol_v1::StatementDistributionMessage::LargeStatement(metadata) => + return Some(UncheckedSignedFullStatement::new( + Statement::Seconded(committed.clone()), + metadata.signed_by, + metadata.signature.clone(), + )), + } + }, + } + }, + Entry::Vacant(vacant) => { + match message { + protocol_v1::StatementDistributionMessage::LargeStatement(metadata) => { + if let Some(new_status) = launch_request( + metadata, + peer, + peer_version, + req_sender.clone(), + ctx, + metrics, + ) + .await + { + vacant.insert(new_status); + } + }, + protocol_v1::StatementDistributionMessage::Statement(_, s) => { + // No fetch in progress, safe to return any statement immediately (we don't + // bother about normal network jitter which might cause `Valid` statements to + // arrive early for now.). + return Some(s) + }, + } + }, + } + None +} + +/// Launch request for a large statement and get tracking status. +/// +/// Returns `None` if spawning task failed. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn launch_request( + meta: StatementMetadata, + peer: PeerId, + peer_version: ValidationVersion, + req_sender: mpsc::Sender, + ctx: &mut Context, + metrics: &Metrics, +) -> Option { + let (task, handle) = + fetch(meta.relay_parent, meta.candidate_hash, vec![peer], req_sender, metrics.clone()) + .remote_handle(); + + let result = ctx.spawn("large-statement-fetcher", task.boxed()); + if let Err(err) = result { + gum::error!(target: LOG_TARGET, ?err, "Spawning task failed."); + return None + } + let available_peers = { + let mut m = IndexMap::new(); + m.insert( + peer, + vec![compatible_v1_message( + peer_version, + protocol_v1::StatementDistributionMessage::LargeStatement(meta), + )], + ); + m + }; + Some(LargeStatementStatus::Fetching(FetchingInfo { + available_peers, + peers_to_try: Vec::new(), + peer_sender: None, + fetching_task: handle, + })) +} + +/// Handle incoming message and circulate it to peers, if we did not know it already. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn handle_incoming_message_and_circulate<'a, Context, R>( + peer: PeerId, + topology_storage: &SessionBoundGridTopologyStorage, + peers: &mut HashMap, + active_heads: &'a mut HashMap, + recent_outdated_heads: &RecentOutdatedHeads, + ctx: &mut Context, + message: net_protocol::StatementDistributionMessage, + req_sender: &mpsc::Sender, + metrics: &Metrics, + runtime: &mut RuntimeInfo, + rng: &mut R, + reputation: &mut ReputationAggregator, +) where + R: rand::Rng, +{ + let handled_incoming = match peers.get_mut(&peer) { + Some(data) => + handle_incoming_message( + peer, + data, + active_heads, + recent_outdated_heads, + ctx, + message, + req_sender, + metrics, + reputation, + ) + .await, + None => None, + }; + + // if we got a fresh message, we need to circulate it to all peers. + if let Some((relay_parent, statement)) = handled_incoming { + // we can ignore the set of peers who this function returns as now expecting + // dependent statements. + // + // we have the invariant in this subsystem that we never store a `Valid` or `Invalid` + // statement before a `Seconded` statement. `Seconded` statements are the only ones + // that require dependents. Thus, if this is a `Seconded` statement for a candidate we + // were not aware of before, we cannot have any dependent statements from the candidate. + let _ = metrics.time_network_bridge_update("circulate_statement"); + + let session_index = runtime.get_session_index_for_child(ctx.sender(), relay_parent).await; + let topology = match session_index { + Ok(session_index) => + topology_storage.get_topology_or_fallback(session_index).local_grid_neighbors(), + Err(e) => { + gum::debug!( + target: LOG_TARGET, + %relay_parent, + "cannot get session index for the specific relay parent: {:?}", + e + ); + + topology_storage.get_current_topology().local_grid_neighbors() + }, + }; + let required_routing = + topology.required_routing_by_index(statement.statement.validator_index(), false); + + let _ = circulate_statement( + required_routing, + topology, + peers, + ctx, + relay_parent, + statement, + Vec::new(), + metrics, + rng, + ) + .await; + } +} + +// Handle a statement. Returns a reference to a newly-stored statement +// if we were not already aware of it, along with the corresponding relay-parent. +// +// This function checks the signature and ensures the statement is compatible with our +// view. It also notifies candidate backing if the statement was previously unknown. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn handle_incoming_message<'a, Context>( + peer: PeerId, + peer_data: &mut PeerData, + active_heads: &'a mut HashMap, + recent_outdated_heads: &RecentOutdatedHeads, + ctx: &mut Context, + message: net_protocol::StatementDistributionMessage, + req_sender: &mpsc::Sender, + metrics: &Metrics, + reputation: &mut ReputationAggregator, +) -> Option<(Hash, StoredStatement<'a>)> { + let _ = metrics.time_network_bridge_update("handle_incoming_message"); + + let message = match message { + Versioned::V1(m) => m, + Versioned::VStaging(protocol_vstaging::StatementDistributionMessage::V1Compatibility( + m, + )) => m, + Versioned::VStaging(_) => { + // The higher-level subsystem code is supposed to filter out + // all non v1 messages. + gum::debug!( + target: LOG_TARGET, + "Legacy statement-distribution code received unintended v2 message" + ); + + return None + }, + }; + + let relay_parent = message.get_relay_parent(); + + let active_head = match active_heads.get_mut(&relay_parent) { + Some(h) => h, + None => { + gum::debug!( + target: LOG_TARGET, + %relay_parent, + "our view out-of-sync with active heads; head not found", + ); + + if !recent_outdated_heads.is_recent_outdated(&relay_parent) { + modify_reputation(reputation, ctx.sender(), peer, COST_UNEXPECTED_STATEMENT).await; + } + + return None + }, + }; + + if let protocol_v1::StatementDistributionMessage::LargeStatement(_) = message { + if let Err(rep) = peer_data.receive_large_statement(&relay_parent) { + gum::debug!(target: LOG_TARGET, ?peer, ?message, ?rep, "Unexpected large statement.",); + modify_reputation(reputation, ctx.sender(), peer, rep).await; + return None + } + } + + let fingerprint = message.get_fingerprint(); + let candidate_hash = *fingerprint.0.candidate_hash(); + let handle_incoming_span = active_head + .span + .child("handle-incoming") + .with_candidate(candidate_hash) + .with_peer_id(&peer); + + let max_message_count = active_head.validators.len() * 2; + + // perform only basic checks before verifying the signature + // as it's more computationally heavy + if let Err(rep) = peer_data.check_can_receive(&relay_parent, &fingerprint, max_message_count) { + // This situation can happen when a peer's Seconded message was lost + // but we have received the Valid statement. + // So we check it once and then ignore repeated violation to avoid + // reputation change flood. + let unexpected_count = peer_data.receive_unexpected(&relay_parent); + + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + ?peer, + ?message, + ?rep, + ?unexpected_count, + "Error inserting received statement" + ); + + match rep { + // This happens when a Valid statement has been received but there is no corresponding + // Seconded + COST_UNEXPECTED_STATEMENT_UNKNOWN_CANDIDATE => { + metrics.on_unexpected_statement_valid(); + // Report peer merely if this is not a duplicate out-of-view statement that + // was caused by a missing Seconded statement from this peer + if unexpected_count == 0_usize { + modify_reputation(reputation, ctx.sender(), peer, rep).await; + } + }, + // This happens when we have an unexpected remote peer that announced Seconded + COST_UNEXPECTED_STATEMENT_REMOTE => { + metrics.on_unexpected_statement_seconded(); + modify_reputation(reputation, ctx.sender(), peer, rep).await; + }, + _ => { + modify_reputation(reputation, ctx.sender(), peer, rep).await; + }, + } + + return None + } + + let checked_compact = { + let (compact, validator_index) = message.get_fingerprint(); + let signature = message.get_signature(); + + let unchecked_compact = UncheckedSignedStatement::new(compact, validator_index, signature); + + match active_head.check_useful_or_unknown(&unchecked_compact) { + Ok(()) => {}, + Err(DeniedStatement::NotUseful) => return None, + Err(DeniedStatement::UsefulButKnown) => { + // Note a received statement in the peer data + peer_data + .receive(&relay_parent, &fingerprint, max_message_count) + .expect("checked in `check_can_receive` above; qed"); + modify_reputation(reputation, ctx.sender(), peer, BENEFIT_VALID_STATEMENT).await; + + return None + }, + } + + // check the signature on the statement. + match check_statement_signature(&active_head, relay_parent, unchecked_compact) { + Err(statement) => { + gum::debug!(target: LOG_TARGET, ?peer, ?statement, "Invalid statement signature"); + modify_reputation(reputation, ctx.sender(), peer, COST_INVALID_SIGNATURE).await; + return None + }, + Ok(statement) => statement, + } + }; + + // Fetch from the network only after signature and usefulness checks are completed. + let is_large_statement = message.is_large_statement(); + let statement = retrieve_statement_from_message( + peer, + peer_data.protocol_version, + message, + active_head, + ctx, + req_sender, + metrics, + ) + .await?; + + let payload = statement.unchecked_into_payload(); + + // Upgrade the `Signed` wrapper from the compact payload to the full payload. + // This fails if the payload doesn't encode correctly. + let statement: SignedFullStatement = match checked_compact.convert_to_superpayload(payload) { + Err((compact, _)) => { + gum::debug!( + target: LOG_TARGET, + ?peer, + ?compact, + is_large_statement, + "Full statement had bad payload." + ); + modify_reputation(reputation, ctx.sender(), peer, COST_WRONG_HASH).await; + return None + }, + Ok(statement) => statement, + }; + + // Ensure the statement is stored in the peer data. + // + // Note that if the peer is sending us something that is not within their view, + // it will not be kept within their log. + match peer_data.receive(&relay_parent, &fingerprint, max_message_count) { + Err(_) => { + unreachable!("checked in `check_can_receive` above; qed"); + }, + Ok(true) => { + gum::trace!(target: LOG_TARGET, ?peer, ?statement, "Statement accepted"); + // Send the peer all statements concerning the candidate that we have, + // since it appears to have just learned about the candidate. + send_statements_about( + peer, + peer_data, + ctx, + relay_parent, + candidate_hash, + &*active_head, + metrics, + ) + .await; + }, + Ok(false) => {}, + } + + // For `Seconded` statements `None` or `Err` means we couldn't fetch the PVD, which + // means the statement shouldn't be accepted. + // + // In case of `Valid` we should have it cached prior, therefore this performs + // no Runtime API calls and always returns `Ok(Some(_))`. + let pvd = if let Statement::Seconded(receipt) = statement.payload() { + let para_id = receipt.descriptor.para_id; + // Either call the Runtime API or check that validation data is cached. + let result = active_head + .fetch_persisted_validation_data(ctx.sender(), relay_parent, para_id) + .await; + + match result { + Ok(Some(pvd)) => Some(pvd.clone()), + Ok(None) | Err(_) => return None, + } + } else { + None + }; + + // Extend the payload with persisted validation data required by the backing + // subsystem. + // + // Do it in advance before noting the statement because we don't want to borrow active + // head mutable and use the cache. + let statement_with_pvd = statement + .clone() + .convert_to_superpayload_with(move |statement| match statement { + Statement::Seconded(receipt) => { + let persisted_validation_data = pvd + .expect("PVD is ensured to be `Some` for all `Seconded` messages above; qed"); + StatementWithPVD::Seconded(receipt, persisted_validation_data) + }, + Statement::Valid(candidate_hash) => StatementWithPVD::Valid(candidate_hash), + }) + .expect("payload was checked with conversion from compact; qed"); + + // Note: `peer_data.receive` already ensures that the statement is not an unbounded equivocation + // or unpinned to a seconded candidate. So it is safe to place it into the storage. + match active_head.note_statement(statement) { + NotedStatement::NotUseful | NotedStatement::UsefulButKnown => { + unreachable!("checked in `is_useful_or_unknown` above; qed"); + }, + NotedStatement::Fresh(statement) => { + modify_reputation(reputation, ctx.sender(), peer, BENEFIT_VALID_STATEMENT_FIRST).await; + + let mut _span = handle_incoming_span.child("notify-backing"); + + // When we receive a new message from a peer, we forward it to the + // candidate backing subsystem. + ctx.send_message(CandidateBackingMessage::Statement(relay_parent, statement_with_pvd)) + .await; + + Some((relay_parent, statement)) + }, + } +} + +/// Update a peer's view. Sends all newly unlocked statements based on the previous +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn update_peer_view_and_maybe_send_unlocked( + peer: PeerId, + topology: &GridNeighbors, + peer_data: &mut PeerData, + ctx: &mut Context, + active_heads: &HashMap, + new_view: View, + metrics: &Metrics, + rng: &mut R, +) where + R: rand::Rng, +{ + let old_view = std::mem::replace(&mut peer_data.view, new_view); + + // Remove entries for all relay-parents in the old view but not the new. + for removed in old_view.difference(&peer_data.view) { + let _ = peer_data.view_knowledge.remove(removed); + } + + // Use both grid directions + let is_gossip_peer = topology.route_to_peer(RequiredRouting::GridXY, &peer); + let lucky = is_gossip_peer || + util::gen_ratio_rng( + util::MIN_GOSSIP_PEERS.saturating_sub(topology.len()), + util::MIN_GOSSIP_PEERS, + rng, + ); + + // Add entries for all relay-parents in the new view but not the old. + // Furthermore, send all statements we have for those relay parents. + let new_view = peer_data.view.difference(&old_view).copied().collect::>(); + for new in new_view.iter().copied() { + peer_data.view_knowledge.insert(new, Default::default()); + if !lucky { + continue + } + if let Some(active_head) = active_heads.get(&new) { + send_statements(peer, peer_data, ctx, new, active_head, metrics).await; + } + } +} + +/// Handle a local network update. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +pub(crate) async fn handle_network_update( + ctx: &mut Context, + state: &mut State, + req_sender: &mpsc::Sender, + update: NetworkBridgeEvent, + rng: &mut R, + metrics: &Metrics, + reputation: &mut ReputationAggregator, +) where + R: rand::Rng, +{ + let peers = &mut state.peers; + let topology_storage = &mut state.topology_storage; + let authorities = &mut state.authorities; + let active_heads = &mut state.active_heads; + let recent_outdated_heads = &state.recent_outdated_heads; + let runtime = &mut state.runtime; + + match update { + NetworkBridgeEvent::PeerConnected(peer, role, protocol_version, maybe_authority) => { + gum::trace!(target: LOG_TARGET, ?peer, ?role, ?protocol_version, "Peer connected"); + + let protocol_version = match ValidationVersion::try_from(protocol_version).ok() { + Some(v) => v, + None => { + gum::trace!( + target: LOG_TARGET, + ?peer, + ?protocol_version, + "unknown protocol version, ignoring" + ); + return + }, + }; + + peers.insert( + peer, + PeerData { + view: Default::default(), + protocol_version, + view_knowledge: Default::default(), + maybe_authority: maybe_authority.clone(), + }, + ); + if let Some(authority_ids) = maybe_authority { + authority_ids.into_iter().for_each(|a| { + authorities.insert(a, peer); + }); + } + }, + NetworkBridgeEvent::PeerDisconnected(peer) => { + gum::trace!(target: LOG_TARGET, ?peer, "Peer disconnected"); + if let Some(auth_ids) = peers.remove(&peer).and_then(|p| p.maybe_authority) { + auth_ids.into_iter().for_each(|a| { + authorities.remove(&a); + }); + } + }, + NetworkBridgeEvent::NewGossipTopology(topology) => { + let _ = metrics.time_network_bridge_update("new_gossip_topology"); + + let new_session_index = topology.session; + let new_topology = topology.topology; + let old_topology = + topology_storage.get_current_topology().local_grid_neighbors().clone(); + topology_storage.update_topology(new_session_index, new_topology, topology.local_index); + + let newly_added = topology_storage + .get_current_topology() + .local_grid_neighbors() + .peers_diff(&old_topology); + + for peer in newly_added { + if let Some(data) = peers.get_mut(&peer) { + let view = std::mem::take(&mut data.view); + update_peer_view_and_maybe_send_unlocked( + peer, + topology_storage.get_current_topology().local_grid_neighbors(), + data, + ctx, + &*active_heads, + view, + metrics, + rng, + ) + .await + } + } + }, + NetworkBridgeEvent::PeerMessage(peer, message) => { + handle_incoming_message_and_circulate( + peer, + topology_storage, + peers, + active_heads, + recent_outdated_heads, + ctx, + message, + req_sender, + metrics, + runtime, + rng, + reputation, + ) + .await; + }, + NetworkBridgeEvent::PeerViewChange(peer, view) => { + let _ = metrics.time_network_bridge_update("peer_view_change"); + gum::trace!(target: LOG_TARGET, ?peer, ?view, "Peer view change"); + match peers.get_mut(&peer) { + Some(data) => + update_peer_view_and_maybe_send_unlocked( + peer, + topology_storage.get_current_topology().local_grid_neighbors(), + data, + ctx, + &*active_heads, + view, + metrics, + rng, + ) + .await, + None => (), + } + }, + NetworkBridgeEvent::OurViewChange(_view) => { + // handled by `ActiveLeavesUpdate` + }, + NetworkBridgeEvent::UpdatedAuthorityIds(peer, authority_ids) => { + gum::trace!( + target: LOG_TARGET, + ?peer, + ?authority_ids, + "Updated `AuthorityDiscoveryId`s" + ); + + // Remove the authority IDs which were previously mapped to the peer + // but aren't part of the new set. + authorities.retain(|a, p| p != &peer || authority_ids.contains(a)); + + // Map the new authority IDs to the peer. + for a in authority_ids.iter().cloned() { + authorities.insert(a, peer); + } + + if let Some(data) = peers.get_mut(&peer) { + data.maybe_authority = Some(authority_ids); + } + }, + } +} + +/// Handle messages from responder background task. +pub(crate) async fn handle_responder_message( + state: &mut State, + message: ResponderMessage, +) -> JfyiErrorResult<()> { + let peers = &state.peers; + let active_heads = &mut state.active_heads; + + match message { + ResponderMessage::GetData { requesting_peer, relay_parent, candidate_hash, tx } => { + if !requesting_peer_knows_about_candidate( + peers, + &requesting_peer, + &relay_parent, + &candidate_hash, + )? { + return Err(JfyiError::RequestedUnannouncedCandidate( + requesting_peer, + candidate_hash, + )) + } + + let active_head = + active_heads.get(&relay_parent).ok_or(JfyiError::NoSuchHead(relay_parent))?; + + let committed = match active_head.waiting_large_statements.get(&candidate_hash) { + Some(LargeStatementStatus::FetchedOrShared(committed)) => committed.clone(), + _ => + return Err(JfyiError::NoSuchFetchedLargeStatement(relay_parent, candidate_hash)), + }; + + tx.send(committed).map_err(|_| JfyiError::ResponderGetDataCanceled)?; + }, + } + Ok(()) +} + +#[overseer::contextbounds(StatementDistribution, prefix = self::overseer)] +pub(crate) async fn handle_requester_message( + ctx: &mut Context, + state: &mut State, + req_sender: &mpsc::Sender, + rng: &mut R, + message: RequesterMessage, + metrics: &Metrics, + reputation: &mut ReputationAggregator, +) -> JfyiErrorResult<()> { + let topology_storage = &state.topology_storage; + let peers = &mut state.peers; + let active_heads = &mut state.active_heads; + let recent_outdated_heads = &state.recent_outdated_heads; + let runtime = &mut state.runtime; + + match message { + RequesterMessage::Finished { + relay_parent, + candidate_hash, + from_peer, + response, + bad_peers, + } => { + for bad in bad_peers { + modify_reputation(reputation, ctx.sender(), bad, COST_FETCH_FAIL).await; + } + modify_reputation(reputation, ctx.sender(), from_peer, BENEFIT_VALID_RESPONSE).await; + + let active_head = + active_heads.get_mut(&relay_parent).ok_or(JfyiError::NoSuchHead(relay_parent))?; + + let status = active_head.waiting_large_statements.remove(&candidate_hash); + + let info = match status { + Some(LargeStatementStatus::Fetching(info)) => info, + Some(LargeStatementStatus::FetchedOrShared(_)) => { + // We are no longer interested in the data. + return Ok(()) + }, + None => + return Err(JfyiError::NoSuchLargeStatementStatus(relay_parent, candidate_hash)), + }; + + active_head + .waiting_large_statements + .insert(candidate_hash, LargeStatementStatus::FetchedOrShared(response)); + + // Cache is now populated, send all messages: + for (peer, messages) in info.available_peers { + for message in messages { + handle_incoming_message_and_circulate( + peer, + topology_storage, + peers, + active_heads, + recent_outdated_heads, + ctx, + message, + req_sender, + &metrics, + runtime, + rng, + reputation, + ) + .await; + } + } + }, + RequesterMessage::SendRequest(req) => { + ctx.send_message(NetworkBridgeTxMessage::SendRequests( + vec![req], + IfDisconnected::ImmediateError, + )) + .await; + }, + RequesterMessage::GetMorePeers { relay_parent, candidate_hash, tx } => { + let active_head = + active_heads.get_mut(&relay_parent).ok_or(JfyiError::NoSuchHead(relay_parent))?; + + let status = active_head.waiting_large_statements.get_mut(&candidate_hash); + + let info = match status { + Some(LargeStatementStatus::Fetching(info)) => info, + Some(LargeStatementStatus::FetchedOrShared(_)) => { + // This task is going to die soon - no need to send it anything. + gum::debug!(target: LOG_TARGET, "Zombie task wanted more peers."); + return Ok(()) + }, + None => + return Err(JfyiError::NoSuchLargeStatementStatus(relay_parent, candidate_hash)), + }; + + if info.peers_to_try.is_empty() { + info.peer_sender = Some(tx); + } else { + let peers_to_try = std::mem::take(&mut info.peers_to_try); + if let Err(peers) = tx.send(peers_to_try) { + // No longer interested for now - might want them later: + info.peers_to_try = peers; + } + } + }, + RequesterMessage::ReportPeer(peer, rep) => + modify_reputation(reputation, ctx.sender(), peer, rep).await, + } + Ok(()) +} + +/// Handle a deactivated leaf. +pub(crate) fn handle_deactivate_leaf(state: &mut State, deactivated: Hash) { + if state.active_heads.remove(&deactivated).is_some() { + gum::trace!( + target: LOG_TARGET, + hash = ?deactivated, + "Deactivating leaf", + ); + + state.recent_outdated_heads.note_outdated(deactivated); + } +} + +/// Handle a new activated leaf. This assumes that the leaf does not +/// support prospective parachains. +#[overseer::contextbounds(StatementDistribution, prefix = self::overseer)] +pub(crate) async fn handle_activated_leaf( + ctx: &mut Context, + state: &mut State, + activated: ActivatedLeaf, +) -> Result<()> { + let relay_parent = activated.hash; + let span = PerLeafSpan::new(activated.span, "statement-distribution-legacy"); + gum::trace!( + target: LOG_TARGET, + hash = ?relay_parent, + "New active leaf", + ); + + // Retrieve the parachain validators at the child of the head we track. + let session_index = + state.runtime.get_session_index_for_child(ctx.sender(), relay_parent).await?; + let info = state + .runtime + .get_session_info_by_index(ctx.sender(), relay_parent, session_index) + .await?; + let session_info = &info.session_info; + + state.active_heads.entry(relay_parent).or_insert(ActiveHeadData::new( + session_info.validators.clone(), + session_index, + span, + )); + + Ok(()) +} + +/// Share a local statement with the rest of the network. +#[overseer::contextbounds(StatementDistribution, prefix = self::overseer)] +pub(crate) async fn share_local_statement( + ctx: &mut Context, + state: &mut State, + relay_parent: Hash, + statement: SignedFullStatement, + rng: &mut R, + metrics: &Metrics, +) -> Result<()> { + // Make sure we have data in cache: + if is_statement_large(&statement).0 { + if let Statement::Seconded(committed) = &statement.payload() { + let active_head = state + .active_heads + .get_mut(&relay_parent) + // This should never be out-of-sync with our view if the view + // updates correspond to actual `StartWork` messages. + .ok_or(JfyiError::NoSuchHead(relay_parent))?; + active_head.waiting_large_statements.insert( + statement.payload().candidate_hash(), + LargeStatementStatus::FetchedOrShared(committed.clone()), + ); + } + } + + let info = state.runtime.get_session_info(ctx.sender(), relay_parent).await?; + let session_info = &info.session_info; + let validator_info = &info.validator_info; + + // Get peers in our group, so we can make sure they get our statement + // directly: + let group_peers = { + if let Some(our_group) = validator_info.our_group { + let our_group = &session_info + .validator_groups + .get(our_group) + .expect("`our_group` is derived from `validator_groups`; qed"); + + our_group + .into_iter() + .filter_map(|i| { + if Some(*i) == validator_info.our_index { + return None + } + let authority_id = &session_info.discovery_keys[i.0 as usize]; + state.authorities.get(authority_id).map(|p| *p) + }) + .collect() + } else { + Vec::new() + } + }; + circulate_statement_and_dependents( + &mut state.topology_storage, + &mut state.peers, + &mut state.active_heads, + ctx, + relay_parent, + statement, + group_peers, + metrics, + rng, + ) + .await; + + Ok(()) +} + +/// Check whether a peer knows about a candidate from us. +/// +/// If not, it is deemed illegal for it to request corresponding data from us. +fn requesting_peer_knows_about_candidate( + peers: &HashMap, + requesting_peer: &PeerId, + relay_parent: &Hash, + candidate_hash: &CandidateHash, +) -> JfyiErrorResult { + let peer_data = peers + .get(requesting_peer) + .ok_or_else(|| JfyiError::NoSuchPeer(*requesting_peer))?; + let knowledge = peer_data + .view_knowledge + .get(relay_parent) + .ok_or_else(|| JfyiError::NoSuchHead(*relay_parent))?; + Ok(knowledge.sent_candidates.get(&candidate_hash).is_some()) +} + +fn compatible_v1_message( + version: ValidationVersion, + message: protocol_v1::StatementDistributionMessage, +) -> net_protocol::StatementDistributionMessage { + match version { + ValidationVersion::V1 => Versioned::V1(message), + ValidationVersion::VStaging => Versioned::VStaging( + protocol_vstaging::StatementDistributionMessage::V1Compatibility(message), + ), + } +} diff --git a/polkadot/node/network/statement-distribution/src/legacy_v1/requester.rs b/polkadot/node/network/statement-distribution/src/legacy_v1/requester.rs new file mode 100644 index 0000000000000000000000000000000000000000..8a8a8f3d624a8d713fb1572cfef9b74a7d9aadc0 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/legacy_v1/requester.rs @@ -0,0 +1,233 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Large statement requesting background task logic. + +use std::time::Duration; + +use futures::{ + channel::{mpsc, oneshot}, + SinkExt, +}; + +use polkadot_node_network_protocol::{ + request_response::{ + v1::{StatementFetchingRequest, StatementFetchingResponse}, + OutgoingRequest, Recipient, Requests, + }, + PeerId, UnifiedReputationChange, +}; +use polkadot_node_subsystem::{Span, Stage}; +use polkadot_node_subsystem_util::TimeoutExt; +use polkadot_primitives::{CandidateHash, CommittedCandidateReceipt, Hash}; + +use crate::{ + legacy_v1::{COST_WRONG_HASH, LOG_TARGET}, + metrics::Metrics, +}; + +// In case we failed fetching from our known peers, how long we should wait before attempting a +// retry, even though we have not yet discovered any new peers. Or in other words how long to +// wait before retrying peers that already failed. +const RETRY_TIMEOUT: Duration = Duration::from_millis(500); + +/// Messages coming from a background task. +pub enum RequesterMessage { + /// Get an update of available peers to try for fetching a given statement. + GetMorePeers { + relay_parent: Hash, + candidate_hash: CandidateHash, + tx: oneshot::Sender>, + }, + /// Fetching finished, ask for verification. If verification fails, task will continue asking + /// peers for data. + Finished { + /// Relay parent this candidate is in the context of. + relay_parent: Hash, + /// The candidate we fetched data for. + candidate_hash: CandidateHash, + /// Data was fetched from this peer. + from_peer: PeerId, + /// Response we received from above peer. + response: CommittedCandidateReceipt, + /// Peers which failed providing the data. + bad_peers: Vec, + }, + /// Report a peer which behaved worse than just not providing data: + ReportPeer(PeerId, UnifiedReputationChange), + /// Ask subsystem to send a request for us. + SendRequest(Requests), +} + +/// A fetching task, taking care of fetching large statements via request/response. +/// +/// A fetch task does not know about a particular `Statement` instead it just tries fetching a +/// `CommittedCandidateReceipt` from peers, whether this can be used to re-assemble one ore +/// many `SignedFullStatement`s needs to be verified by the caller. +pub async fn fetch( + relay_parent: Hash, + candidate_hash: CandidateHash, + peers: Vec, + mut sender: mpsc::Sender, + metrics: Metrics, +) { + let span = Span::new(candidate_hash, "fetch-large-statement") + .with_relay_parent(relay_parent) + .with_stage(Stage::StatementDistribution); + + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + ?relay_parent, + "Fetch for large statement started", + ); + + // Peers we already tried (and failed). + let mut tried_peers = Vec::new(); + // Peers left for trying out. + let mut new_peers = peers; + + let req = StatementFetchingRequest { relay_parent, candidate_hash }; + + // We retry endlessly (with sleep periods), and rely on the subsystem to kill us eventually. + loop { + let span = span.child("try-available-peers"); + + while let Some(peer) = new_peers.pop() { + let _span = span.child("try-peer").with_peer_id(&peer); + + let (outgoing, pending_response) = + OutgoingRequest::new(Recipient::Peer(peer), req.clone()); + if let Err(err) = sender + .feed(RequesterMessage::SendRequest(Requests::StatementFetchingV1(outgoing))) + .await + { + gum::info!( + target: LOG_TARGET, + ?err, + "Sending request failed, node might be shutting down - exiting." + ); + return + } + + metrics.on_sent_request(); + + match pending_response.await { + Ok(StatementFetchingResponse::Statement(statement)) => { + if statement.hash() != candidate_hash { + metrics.on_received_response(false); + metrics.on_unexpected_statement_large(); + + if let Err(err) = + sender.feed(RequesterMessage::ReportPeer(peer, COST_WRONG_HASH)).await + { + gum::warn!( + target: LOG_TARGET, + ?err, + "Sending reputation change failed: This should not happen." + ); + } + // We want to get rid of this peer: + continue + } + + if let Err(err) = sender + .feed(RequesterMessage::Finished { + relay_parent, + candidate_hash, + from_peer: peer, + response: statement, + bad_peers: tried_peers, + }) + .await + { + gum::warn!( + target: LOG_TARGET, + ?err, + "Sending task response failed: This should not happen." + ); + } + + metrics.on_received_response(true); + + // We are done now. + return + }, + Err(err) => { + gum::debug!( + target: LOG_TARGET, + ?err, + "Receiving response failed with error - trying next peer." + ); + + metrics.on_received_response(false); + metrics.on_unexpected_statement_large(); + }, + } + + tried_peers.push(peer); + } + + new_peers = std::mem::take(&mut tried_peers); + + // All our peers failed us - try getting new ones before trying again: + match try_get_new_peers(relay_parent, candidate_hash, &mut sender, &span).await { + Ok(Some(mut peers)) => { + gum::trace!(target: LOG_TARGET, ?peers, "Received new peers."); + // New arrivals will be tried first: + new_peers.append(&mut peers); + }, + // No new peers, try the old ones again (if we have any): + Ok(None) => { + // Note: In case we don't have any more peers, we will just keep asking for new + // peers, which is exactly what we want. + }, + Err(()) => return, + } + } +} + +/// Try getting new peers from subsystem. +/// +/// If there are non, we will return after a timeout with `None`. +async fn try_get_new_peers( + relay_parent: Hash, + candidate_hash: CandidateHash, + sender: &mut mpsc::Sender, + span: &Span, +) -> Result>, ()> { + let _span = span.child("wait-for-peers"); + + let (tx, rx) = oneshot::channel(); + + if let Err(err) = sender + .send(RequesterMessage::GetMorePeers { relay_parent, candidate_hash, tx }) + .await + { + gum::debug!( + target: LOG_TARGET, + ?err, + "Failed sending background task message, subsystem probably moved on." + ); + return Err(()) + } + + match rx.timeout(RETRY_TIMEOUT).await.transpose() { + Err(_) => { + gum::debug!(target: LOG_TARGET, "Failed fetching more peers."); + Err(()) + }, + Ok(val) => Ok(val), + } +} diff --git a/polkadot/node/network/statement-distribution/src/legacy_v1/responder.rs b/polkadot/node/network/statement-distribution/src/legacy_v1/responder.rs new file mode 100644 index 0000000000000000000000000000000000000000..81e226c4ff8950d8edc9b18d8a3ddef0e0b76d93 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/legacy_v1/responder.rs @@ -0,0 +1,121 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Large statement responding background task logic. + +use futures::{ + channel::{mpsc, oneshot}, + stream::FuturesUnordered, + SinkExt, StreamExt, +}; + +use fatality::Nested; +use polkadot_node_network_protocol::{ + request_response::{ + incoming::OutgoingResponse, + v1::{StatementFetchingRequest, StatementFetchingResponse}, + IncomingRequestReceiver, MAX_PARALLEL_STATEMENT_REQUESTS, + }, + PeerId, UnifiedReputationChange as Rep, +}; +use polkadot_primitives::{CandidateHash, CommittedCandidateReceipt, Hash}; + +use crate::LOG_TARGET; + +const COST_INVALID_REQUEST: Rep = Rep::CostMajor("Peer sent unparsable request"); + +/// Messages coming from a background task. +pub enum ResponderMessage { + /// Get an update of available peers to try for fetching a given statement. + GetData { + requesting_peer: PeerId, + relay_parent: Hash, + candidate_hash: CandidateHash, + tx: oneshot::Sender, + }, +} + +/// A fetching task, taking care of fetching large statements via request/response. +/// +/// A fetch task does not know about a particular `Statement`, instead it just tries fetching a +/// `CommittedCandidateReceipt` from peers, whether this can be used to re-assemble one or +/// many `SignedFullStatement`s needs to be verified by the caller. +pub async fn respond( + mut receiver: IncomingRequestReceiver, + mut sender: mpsc::Sender, +) { + let mut pending_out = FuturesUnordered::new(); + loop { + // Ensure we are not handling too many requests in parallel. + // We do this for three reasons: + // + // 1. We want some requesters to have full data fast, rather then lots of them having them + // late, as each requester having the data will help distributing it. + // 2. If we take too long, the requests timing out will not yet have had any data sent, thus + // we wasted no bandwidth. + // 3. If the queue is full, requestes will get an immediate error instead of running in a + // timeout, thus requesters can immediately try another peer and be faster. + // + // From this perspective we would not want parallel response sending at all, but we don't + // want a single slow requester slowing everyone down, so we want some parallelism for that + // reason. + if pending_out.len() >= MAX_PARALLEL_STATEMENT_REQUESTS as usize { + // Wait for one to finish: + pending_out.next().await; + } + + let req = match receiver.recv(|| vec![COST_INVALID_REQUEST]).await.into_nested() { + Ok(Ok(v)) => v, + Err(fatal) => { + gum::debug!(target: LOG_TARGET, error = ?fatal, "Shutting down request responder"); + return + }, + Ok(Err(jfyi)) => { + gum::debug!(target: LOG_TARGET, error = ?jfyi, "Decoding request failed"); + continue + }, + }; + + let (tx, rx) = oneshot::channel(); + if let Err(err) = sender + .feed(ResponderMessage::GetData { + requesting_peer: req.peer, + relay_parent: req.payload.relay_parent, + candidate_hash: req.payload.candidate_hash, + tx, + }) + .await + { + gum::debug!(target: LOG_TARGET, ?err, "Shutting down responder"); + return + } + let response = match rx.await { + Err(err) => { + gum::debug!(target: LOG_TARGET, ?err, "Requested data not found."); + Err(()) + }, + Ok(v) => Ok(StatementFetchingResponse::Statement(v)), + }; + let (pending_sent_tx, pending_sent_rx) = oneshot::channel(); + let response = OutgoingResponse { + result: response, + reputation_changes: Vec::new(), + sent_feedback: Some(pending_sent_tx), + }; + pending_out.push(pending_sent_rx); + if let Err(_) = req.send_outgoing_response(response) { + gum::debug!(target: LOG_TARGET, "Sending response failed"); + } + } +} diff --git a/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs b/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..a8ce65f2986118c9b0c432ce8bb3821026019a57 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs @@ -0,0 +1,2971 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![allow(clippy::clone_on_copy)] + +use super::*; +use crate::{metrics::Metrics, *}; + +use assert_matches::assert_matches; +use futures::executor; +use futures_timer::Delay; +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_network_protocol::{ + grid_topology::{SessionGridTopology, TopologyPeerInfo}, + peer_set::ValidationVersion, + request_response::{ + v1::{StatementFetchingRequest, StatementFetchingResponse}, + IncomingRequest, Recipient, ReqProtocolNames, Requests, + }, + view, ObservedRole, VersionedValidationProtocol, +}; +use polkadot_node_primitives::{ + SignedFullStatementWithPVD, Statement, UncheckedSignedFullStatement, +}; +use polkadot_node_subsystem::{ + jaeger, + messages::{ + network_bridge_event, AllMessages, ReportPeerMessage, RuntimeApiMessage, RuntimeApiRequest, + }, + ActivatedLeaf, LeafStatus, RuntimeApiError, +}; +use polkadot_node_subsystem_test_helpers::mock::make_ferdie_keystore; +use polkadot_primitives::{ + GroupIndex, Hash, HeadData, Id as ParaId, IndexedVec, SessionInfo, ValidationCode, +}; +use polkadot_primitives_test_helpers::{ + dummy_committed_candidate_receipt, dummy_hash, AlwaysZeroRng, +}; +use sc_keystore::LocalKeystore; +use sp_application_crypto::{sr25519::Pair, AppCrypto, Pair as TraitPair}; +use sp_authority_discovery::AuthorityPair; +use sp_keyring::Sr25519Keyring; +use sp_keystore::{Keystore, KeystorePtr}; +use std::{iter::FromIterator as _, sync::Arc, time::Duration}; +use util::reputation::add_reputation; + +// Some deterministic genesis hash for protocol names +const GENESIS_HASH: Hash = Hash::repeat_byte(0xff); + +const ASYNC_BACKING_DISABLED_ERROR: RuntimeApiError = + RuntimeApiError::NotSupported { runtime_api_name: "test-runtime" }; + +fn dummy_pvd() -> PersistedValidationData { + PersistedValidationData { + parent_head: HeadData(vec![7, 8, 9]), + relay_parent_number: 5, + max_pov_size: 1024, + relay_parent_storage_root: Default::default(), + } +} + +fn extend_statement_with_pvd( + statement: SignedFullStatement, + pvd: PersistedValidationData, +) -> SignedFullStatementWithPVD { + statement + .convert_to_superpayload_with(|statement| match statement { + Statement::Seconded(receipt) => StatementWithPVD::Seconded(receipt, pvd), + Statement::Valid(candidate_hash) => StatementWithPVD::Valid(candidate_hash), + }) + .unwrap() +} + +#[test] +fn active_head_accepts_only_2_seconded_per_validator() { + let validators = vec![ + Sr25519Keyring::Alice.public().into(), + Sr25519Keyring::Bob.public().into(), + Sr25519Keyring::Charlie.public().into(), + ]; + let parent_hash: Hash = [1; 32].into(); + + let session_index = 1; + let signing_context = SigningContext { parent_hash, session_index }; + + let candidate_a = { + let mut c = dummy_committed_candidate_receipt(dummy_hash()); + c.descriptor.relay_parent = parent_hash; + c.descriptor.para_id = 1.into(); + c + }; + + let candidate_b = { + let mut c = dummy_committed_candidate_receipt(dummy_hash()); + c.descriptor.relay_parent = parent_hash; + c.descriptor.para_id = 2.into(); + c + }; + + let candidate_c = { + let mut c = dummy_committed_candidate_receipt(dummy_hash()); + c.descriptor.relay_parent = parent_hash; + c.descriptor.para_id = 3.into(); + c + }; + + let mut head_data = ActiveHeadData::new( + IndexedVec::::from(validators), + session_index, + PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"), + ); + + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + let alice_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); + let bob_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Bob.to_seed()), + ) + .unwrap(); + + // note A + let a_seconded_val_0 = SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate_a.clone()), + &signing_context, + ValidatorIndex(0), + &alice_public.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + assert!(head_data + .check_useful_or_unknown(&a_seconded_val_0.clone().convert_payload().into()) + .is_ok()); + let noted = head_data.note_statement(a_seconded_val_0.clone()); + + assert_matches!(noted, NotedStatement::Fresh(_)); + + // note A (duplicate) + assert_eq!( + head_data.check_useful_or_unknown(&a_seconded_val_0.clone().convert_payload().into()), + Err(DeniedStatement::UsefulButKnown), + ); + let noted = head_data.note_statement(a_seconded_val_0); + + assert_matches!(noted, NotedStatement::UsefulButKnown); + + // note B + let statement = SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate_b.clone()), + &signing_context, + ValidatorIndex(0), + &alice_public.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + assert!(head_data + .check_useful_or_unknown(&statement.clone().convert_payload().into()) + .is_ok()); + let noted = head_data.note_statement(statement); + assert_matches!(noted, NotedStatement::Fresh(_)); + + // note C (beyond 2 - ignored) + let statement = SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate_c.clone()), + &signing_context, + ValidatorIndex(0), + &alice_public.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + assert_eq!( + head_data.check_useful_or_unknown(&statement.clone().convert_payload().into()), + Err(DeniedStatement::NotUseful), + ); + let noted = head_data.note_statement(statement); + assert_matches!(noted, NotedStatement::NotUseful); + + // note B (new validator) + let statement = SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate_b.clone()), + &signing_context, + ValidatorIndex(1), + &bob_public.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + assert!(head_data + .check_useful_or_unknown(&statement.clone().convert_payload().into()) + .is_ok()); + let noted = head_data.note_statement(statement); + assert_matches!(noted, NotedStatement::Fresh(_)); + + // note C (new validator) + let statement = SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate_c.clone()), + &signing_context, + ValidatorIndex(1), + &bob_public.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + assert!(head_data + .check_useful_or_unknown(&statement.clone().convert_payload().into()) + .is_ok()); + let noted = head_data.note_statement(statement); + assert_matches!(noted, NotedStatement::Fresh(_)); +} + +#[test] +fn note_local_works() { + let hash_a = CandidateHash([1; 32].into()); + let hash_b = CandidateHash([2; 32].into()); + + let mut per_peer_tracker = VcPerPeerTracker::default(); + per_peer_tracker.note_local(hash_a); + per_peer_tracker.note_local(hash_b); + + assert!(per_peer_tracker.local_observed.contains(&hash_a)); + assert!(per_peer_tracker.local_observed.contains(&hash_b)); + + assert!(!per_peer_tracker.remote_observed.contains(&hash_a)); + assert!(!per_peer_tracker.remote_observed.contains(&hash_b)); +} + +#[test] +fn note_remote_works() { + let hash_a = CandidateHash([1; 32].into()); + let hash_b = CandidateHash([2; 32].into()); + let hash_c = CandidateHash([3; 32].into()); + + let mut per_peer_tracker = VcPerPeerTracker::default(); + assert!(per_peer_tracker.note_remote(hash_a)); + assert!(per_peer_tracker.note_remote(hash_b)); + assert!(!per_peer_tracker.note_remote(hash_c)); + + assert!(per_peer_tracker.remote_observed.contains(&hash_a)); + assert!(per_peer_tracker.remote_observed.contains(&hash_b)); + assert!(!per_peer_tracker.remote_observed.contains(&hash_c)); + + assert!(!per_peer_tracker.local_observed.contains(&hash_a)); + assert!(!per_peer_tracker.local_observed.contains(&hash_b)); + assert!(!per_peer_tracker.local_observed.contains(&hash_c)); +} + +#[test] +fn per_peer_relay_parent_knowledge_send() { + let mut knowledge = PeerRelayParentKnowledge::default(); + + let hash_a = CandidateHash([1; 32].into()); + + // Sending an un-pinned statement should not work and should have no effect. + assert!(!knowledge.can_send(&(CompactStatement::Valid(hash_a), ValidatorIndex(0)))); + assert!(!knowledge.is_known_candidate(&hash_a)); + assert!(knowledge.sent_statements.is_empty()); + assert!(knowledge.received_statements.is_empty()); + assert!(knowledge.seconded_counts.is_empty()); + assert!(knowledge.received_message_count.is_empty()); + + // Make the peer aware of the candidate. + assert_eq!(knowledge.send(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0))), true); + assert_eq!(knowledge.send(&(CompactStatement::Seconded(hash_a), ValidatorIndex(1))), false); + assert!(knowledge.is_known_candidate(&hash_a)); + assert_eq!(knowledge.sent_statements.len(), 2); + assert!(knowledge.received_statements.is_empty()); + assert_eq!(knowledge.seconded_counts.len(), 2); + assert!(knowledge.received_message_count.get(&hash_a).is_none()); + + // And now it should accept the dependent message. + assert_eq!(knowledge.send(&(CompactStatement::Valid(hash_a), ValidatorIndex(0))), false); + assert!(knowledge.is_known_candidate(&hash_a)); + assert_eq!(knowledge.sent_statements.len(), 3); + assert!(knowledge.received_statements.is_empty()); + assert_eq!(knowledge.seconded_counts.len(), 2); + assert!(knowledge.received_message_count.get(&hash_a).is_none()); +} + +#[test] +fn cant_send_after_receiving() { + let mut knowledge = PeerRelayParentKnowledge::default(); + + let hash_a = CandidateHash([1; 32].into()); + assert!(knowledge + .check_can_receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3) + .is_ok()); + assert!(knowledge + .receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3) + .unwrap()); + assert!(!knowledge.can_send(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)))); +} + +#[test] +fn per_peer_relay_parent_knowledge_receive() { + let mut knowledge = PeerRelayParentKnowledge::default(); + + let hash_a = CandidateHash([1; 32].into()); + + assert_eq!( + knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(0)), 3), + Err(COST_UNEXPECTED_STATEMENT_UNKNOWN_CANDIDATE), + ); + assert_eq!( + knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(0)), 3), + Err(COST_UNEXPECTED_STATEMENT_UNKNOWN_CANDIDATE), + ); + + assert!(knowledge + .check_can_receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3) + .is_ok()); + assert_eq!( + knowledge.receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3), + Ok(true), + ); + + // Push statements up to the flood limit. + assert!(knowledge + .check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(1)), 3) + .is_ok()); + assert_eq!( + knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(1)), 3), + Ok(false), + ); + + assert!(knowledge.is_known_candidate(&hash_a)); + assert_eq!(*knowledge.received_message_count.get(&hash_a).unwrap(), 2); + + assert!(knowledge + .check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3) + .is_ok()); + assert_eq!( + knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3), + Ok(false), + ); + + assert_eq!(*knowledge.received_message_count.get(&hash_a).unwrap(), 3); + + assert_eq!( + knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(7)), 3), + Err(COST_APPARENT_FLOOD), + ); + assert_eq!( + knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(7)), 3), + Err(COST_APPARENT_FLOOD), + ); + + assert_eq!(*knowledge.received_message_count.get(&hash_a).unwrap(), 3); + assert_eq!(knowledge.received_statements.len(), 3); // number of prior `Ok`s. + + // Now make sure that the seconding limit is respected. + let hash_b = CandidateHash([2; 32].into()); + let hash_c = CandidateHash([3; 32].into()); + + assert!(knowledge + .check_can_receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3) + .is_ok()); + assert_eq!( + knowledge.receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3), + Ok(true), + ); + + assert_eq!( + knowledge.check_can_receive(&(CompactStatement::Seconded(hash_c), ValidatorIndex(0)), 3), + Err(COST_UNEXPECTED_STATEMENT_REMOTE), + ); + assert_eq!( + knowledge.receive(&(CompactStatement::Seconded(hash_c), ValidatorIndex(0)), 3), + Err(COST_UNEXPECTED_STATEMENT_REMOTE), + ); + + // Last, make sure that already-known statements are disregarded. + assert_eq!( + knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3), + Err(COST_DUPLICATE_STATEMENT), + ); + assert_eq!( + knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3), + Err(COST_DUPLICATE_STATEMENT), + ); + + assert_eq!( + knowledge.check_can_receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3), + Err(COST_DUPLICATE_STATEMENT), + ); + assert_eq!( + knowledge.receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3), + Err(COST_DUPLICATE_STATEMENT), + ); +} + +#[test] +fn peer_view_update_sends_messages() { + let hash_a = Hash::repeat_byte(1); + let hash_b = Hash::repeat_byte(2); + let hash_c = Hash::repeat_byte(3); + + let candidate = { + let mut c = dummy_committed_candidate_receipt(dummy_hash()); + c.descriptor.relay_parent = hash_c; + c.descriptor.para_id = ParaId::from(1_u32); + c + }; + let candidate_hash = candidate.hash(); + + let old_view = view![hash_a, hash_b]; + let new_view = view![hash_b, hash_c]; + + let mut active_heads = HashMap::new(); + let validators = vec![ + Sr25519Keyring::Alice.public().into(), + Sr25519Keyring::Bob.public().into(), + Sr25519Keyring::Charlie.public().into(), + ]; + + let session_index = 1; + let signing_context = SigningContext { parent_hash: hash_c, session_index }; + + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + + let alice_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); + let bob_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Bob.to_seed()), + ) + .unwrap(); + let charlie_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Charlie.to_seed()), + ) + .unwrap(); + + let new_head_data = { + let mut data = ActiveHeadData::new( + IndexedVec::::from(validators), + session_index, + PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"), + ); + + let statement = SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate.clone()), + &signing_context, + ValidatorIndex(0), + &alice_public.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + assert!(data + .check_useful_or_unknown(&statement.clone().convert_payload().into()) + .is_ok()); + let noted = data.note_statement(statement); + + assert_matches!(noted, NotedStatement::Fresh(_)); + + let statement = SignedFullStatement::sign( + &keystore, + Statement::Valid(candidate_hash), + &signing_context, + ValidatorIndex(1), + &bob_public.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + assert!(data + .check_useful_or_unknown(&statement.clone().convert_payload().into()) + .is_ok()); + let noted = data.note_statement(statement); + + assert_matches!(noted, NotedStatement::Fresh(_)); + + let statement = SignedFullStatement::sign( + &keystore, + Statement::Valid(candidate_hash), + &signing_context, + ValidatorIndex(2), + &charlie_public.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + assert!(data + .check_useful_or_unknown(&statement.clone().convert_payload().into()) + .is_ok()); + let noted = data.note_statement(statement); + assert_matches!(noted, NotedStatement::Fresh(_)); + + data + }; + + active_heads.insert(hash_c, new_head_data); + + let mut peer_data = PeerData { + view: old_view, + protocol_version: ValidationVersion::V1, + view_knowledge: { + let mut k = HashMap::new(); + + k.insert(hash_a, Default::default()); + k.insert(hash_b, Default::default()); + + k + }, + maybe_authority: None, + }; + + let pool = sp_core::testing::TaskExecutor::new(); + let (mut ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context::< + StatementDistributionMessage, + _, + >(pool); + let peer = PeerId::random(); + + executor::block_on(async move { + let mut topology = GridNeighbors::empty(); + topology.peers_x = HashSet::from_iter(vec![peer].into_iter()); + update_peer_view_and_maybe_send_unlocked( + peer, + &topology, + &mut peer_data, + &mut ctx, + &active_heads, + new_view.clone(), + &Default::default(), + &mut AlwaysZeroRng, + ) + .await; + + assert_eq!(peer_data.view, new_view); + assert!(!peer_data.view_knowledge.contains_key(&hash_a)); + assert!(peer_data.view_knowledge.contains_key(&hash_b)); + + let c_knowledge = peer_data.view_knowledge.get(&hash_c).unwrap(); + + assert!(c_knowledge.is_known_candidate(&candidate_hash)); + assert!(c_knowledge + .sent_statements + .contains(&(CompactStatement::Seconded(candidate_hash), ValidatorIndex(0)))); + assert!(c_knowledge + .sent_statements + .contains(&(CompactStatement::Valid(candidate_hash), ValidatorIndex(1)))); + assert!(c_knowledge + .sent_statements + .contains(&(CompactStatement::Valid(candidate_hash), ValidatorIndex(2)))); + + // now see if we got the 3 messages from the active head data. + let active_head = active_heads.get(&hash_c).unwrap(); + + // semi-fragile because hashmap iterator ordering is undefined, but in practice + // it will not change between runs of the program. + for statement in active_head.statements_about(candidate_hash) { + let message = handle.recv().await; + let expected_to = vec![peer]; + let expected_payload = VersionedValidationProtocol::from(Versioned::V1( + v1_statement_message(hash_c, statement.statement.clone(), &Metrics::default()), + )); + + assert_matches!( + message, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + to, + payload, + )) => { + assert_eq!(to, expected_to); + assert_eq!(payload, expected_payload) + } + ) + } + }); +} + +#[test] +fn circulated_statement_goes_to_all_peers_with_view() { + let hash_a = Hash::repeat_byte(1); + let hash_b = Hash::repeat_byte(2); + let hash_c = Hash::repeat_byte(3); + + let candidate = { + let mut c = dummy_committed_candidate_receipt(dummy_hash()); + c.descriptor.relay_parent = hash_b; + c.descriptor.para_id = ParaId::from(1_u32); + c + }; + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + + let peer_a_view = view![hash_a]; + let peer_b_view = view![hash_a, hash_b]; + let peer_c_view = view![hash_b, hash_c]; + + let session_index = 1; + + let peer_data_from_view = |view: View| PeerData { + view: view.clone(), + protocol_version: ValidationVersion::V1, + view_knowledge: view.iter().map(|v| (*v, Default::default())).collect(), + maybe_authority: None, + }; + + let mut peer_data: HashMap<_, _> = vec![ + (peer_a, peer_data_from_view(peer_a_view)), + (peer_b, peer_data_from_view(peer_b_view)), + (peer_c, peer_data_from_view(peer_c_view)), + ] + .into_iter() + .collect(); + + let pool = sp_core::testing::TaskExecutor::new(); + let (mut ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context::< + StatementDistributionMessage, + _, + >(pool); + + executor::block_on(async move { + let signing_context = SigningContext { parent_hash: hash_b, session_index }; + + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + let alice_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); + + let statement = SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate), + &signing_context, + ValidatorIndex(0), + &alice_public.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let comparator = StoredStatementComparator { + compact: statement.payload().to_compact(), + validator_index: ValidatorIndex(0), + signature: statement.signature().clone(), + }; + let statement = StoredStatement { comparator: &comparator, statement: &statement }; + + let mut topology = GridNeighbors::empty(); + topology.peers_x = HashSet::from_iter(vec![peer_a, peer_b, peer_c].into_iter()); + let needs_dependents = circulate_statement( + RequiredRouting::GridXY, + &topology, + &mut peer_data, + &mut ctx, + hash_b, + statement, + Vec::new(), + &Metrics::default(), + &mut AlwaysZeroRng, + ) + .await; + + { + assert_eq!(needs_dependents.len(), 2); + assert!(needs_dependents.contains(&peer_b)); + assert!(needs_dependents.contains(&peer_c)); + } + + let fingerprint = (statement.compact().clone(), ValidatorIndex(0)); + + assert!(peer_data + .get(&peer_b) + .unwrap() + .view_knowledge + .get(&hash_b) + .unwrap() + .sent_statements + .contains(&fingerprint)); + + assert!(peer_data + .get(&peer_c) + .unwrap() + .view_knowledge + .get(&hash_b) + .unwrap() + .sent_statements + .contains(&fingerprint)); + + let message = handle.recv().await; + assert_matches!( + message, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + to, + payload, + )) => { + assert_eq!(to.len(), 2); + assert!(to.contains(&peer_b)); + assert!(to.contains(&peer_c)); + + assert_eq!( + payload, + VersionedValidationProtocol::from(Versioned::V1(v1_statement_message(hash_b, statement.statement.clone(), &Metrics::default()))), + ); + } + ) + }); +} + +#[test] +fn receiving_from_one_sends_to_another_and_to_candidate_backing() { + const PARA_ID: ParaId = ParaId::new(1); + let hash_a = Hash::repeat_byte(1); + let pvd = dummy_pvd(); + + let candidate = { + let mut c = dummy_committed_candidate_receipt(dummy_hash()); + c.descriptor.relay_parent = hash_a; + c.descriptor.para_id = PARA_ID; + c + }; + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + + let validators = vec![ + Sr25519Keyring::Alice.pair(), + Sr25519Keyring::Bob.pair(), + Sr25519Keyring::Charlie.pair(), + ]; + + let session_info = make_session_info(validators, vec![]); + + let session_index = 1; + + let pool = sp_core::testing::TaskExecutor::new(); + let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); + + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); + let (candidate_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); + + let bg = async move { + let s = StatementDistributionSubsystem { + keystore: Arc::new(LocalKeystore::in_memory()), + v1_req_receiver: Some(statement_req_receiver), + req_receiver: Some(candidate_req_receiver), + metrics: Default::default(), + rng: AlwaysZeroRng, + reputation: ReputationAggregator::new(|_| true), + }; + s.run(ctx).await.unwrap(); + }; + + let test_fut = async move { + // register our active heads. + handle + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) + if r == hash_a + => { + let _ = tx.send(Err(ASYNC_BACKING_DISABLED_ERROR)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx)) + ) + if r == hash_a + => { + let _ = tx.send(Ok(session_index)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx)) + ) + if r == hash_a && sess_index == session_index + => { + let _ = tx.send(Ok(Some(session_info))); + } + ); + + // notify of peers and view + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_a, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_b, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_a, view![hash_a]), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_b, view![hash_a]), + ), + }) + .await; + + // receive a seconded statement from peer A. it should be propagated onwards to peer B and + // to candidate backing. + let statement = { + let signing_context = SigningContext { parent_hash: hash_a, session_index }; + + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + let alice_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); + + SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate), + &signing_context, + ValidatorIndex(0), + &alice_public.into(), + ) + .ok() + .flatten() + .expect("should be signed") + }; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_a, + Versioned::V1(protocol_v1::StatementDistributionMessage::Statement( + hash_a, + statement.clone().into(), + )), + ), + ), + }) + .await; + + let statement_with_pvd = extend_statement_with_pvd(statement.clone(), pvd.clone()); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::PersistedValidationData(para_id, assumption, tx), + )) if para_id == PARA_ID && + assumption == OccupiedCoreAssumption::Free && + hash == hash_a => + { + tx.send(Ok(Some(pvd))).unwrap(); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r)) + ) if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => {} + ); + assert_matches!( + handle.recv().await, + AllMessages::CandidateBacking( + CandidateBackingMessage::Statement(r, s) + ) if r == hash_a && s == statement_with_pvd => {} + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + recipients, + Versioned::V1(protocol_v1::ValidationProtocol::StatementDistribution( + protocol_v1::StatementDistributionMessage::Statement(r, s) + )), + ) + ) => { + assert_eq!(recipients, vec![peer_b]); + assert_eq!(r, hash_a); + assert_eq!(s, statement.into()); + } + ); + handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::pin_mut!(test_fut); + futures::pin_mut!(bg); + + executor::block_on(future::join(test_fut, bg)); +} + +#[test] +fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing() { + const PARA_ID: ParaId = ParaId::new(1); + let pvd = dummy_pvd(); + + sp_tracing::try_init_simple(); + let hash_a = Hash::repeat_byte(1); + let hash_b = Hash::repeat_byte(2); + + let candidate = { + let mut c = dummy_committed_candidate_receipt(dummy_hash()); + c.descriptor.relay_parent = hash_a; + c.descriptor.para_id = PARA_ID; + c.commitments.new_validation_code = Some(ValidationCode(vec![1, 2, 3])); + c + }; + + let peer_a = PeerId::random(); // Alice + let peer_b = PeerId::random(); // Bob + let peer_c = PeerId::random(); // Charlie + let peer_bad = PeerId::random(); // No validator + + let validators = vec![ + Sr25519Keyring::Alice.pair(), + Sr25519Keyring::Bob.pair(), + Sr25519Keyring::Charlie.pair(), + // We: + Sr25519Keyring::Ferdie.pair(), + ]; + + let session_info = make_session_info(validators, vec![vec![0, 1, 2, 4], vec![3]]); + + let session_index = 1; + + let pool = sp_core::testing::TaskExecutor::new(); + let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); + + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, mut req_cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + let (candidate_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); + + let bg = async move { + let s = StatementDistributionSubsystem { + keystore: make_ferdie_keystore(), + v1_req_receiver: Some(statement_req_receiver), + req_receiver: Some(candidate_req_receiver), + metrics: Default::default(), + rng: AlwaysZeroRng, + reputation: ReputationAggregator::new(|_| true), + }; + s.run(ctx).await.unwrap(); + }; + + let test_fut = async move { + // register our active heads. + handle + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) + if r == hash_a + => { + let _ = tx.send(Err(ASYNC_BACKING_DISABLED_ERROR)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx)) + ) + if r == hash_a + => { + let _ = tx.send(Ok(session_index)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx)) + ) + if r == hash_a && sess_index == session_index + => { + let _ = tx.send(Ok(Some(session_info))); + } + ); + + // notify of peers and view + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_a, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([Sr25519Keyring::Alice.public().into()])), + ), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_b, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([Sr25519Keyring::Bob.public().into()])), + ), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_c, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([Sr25519Keyring::Charlie.public().into()])), + ), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_bad, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_a, view![hash_a]), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_b, view![hash_a]), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_c, view![hash_a]), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_bad, view![hash_a]), + ), + }) + .await; + + // receive a seconded statement from peer A, which does not provide the request data, + // then get that data from peer C. It should be propagated onwards to peer B and to + // candidate backing. + let statement = { + let signing_context = SigningContext { parent_hash: hash_a, session_index }; + + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + let alice_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); + + SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate.clone()), + &signing_context, + ValidatorIndex(0), + &alice_public.into(), + ) + .ok() + .flatten() + .expect("should be signed") + }; + + let metadata = derive_metadata_assuming_seconded(hash_a, statement.clone().into()); + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_a, + Versioned::V1(protocol_v1::StatementDistributionMessage::LargeStatement( + metadata.clone(), + )), + ), + ), + }) + .await; + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + assert_eq!(outgoing.peer, Recipient::Peer(peer_a)); + // Just drop request - should trigger error. + } + ); + + // There is a race between request handler asking for more peers and processing of the + // coming `PeerMessage`s, we want the request handler to ask first here for better test + // coverage: + Delay::new(Duration::from_millis(20)).await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_c, + Versioned::V1(protocol_v1::StatementDistributionMessage::LargeStatement( + metadata.clone(), + )), + ), + ), + }) + .await; + + // Malicious peer: + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_bad, + Versioned::V1(protocol_v1::StatementDistributionMessage::LargeStatement( + metadata.clone(), + )), + ), + ), + }) + .await; + + // Let c fail once too: + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + assert_eq!(outgoing.peer, Recipient::Peer(peer_c)); + } + ); + + // a fails again: + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + // On retry, we should have reverse order: + assert_eq!(outgoing.peer, Recipient::Peer(peer_a)); + } + ); + + // Send invalid response (all other peers have been tried now): + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + assert_eq!(outgoing.peer, Recipient::Peer(peer_bad)); + let bad_candidate = { + let mut bad = candidate.clone(); + bad.descriptor.para_id = 0xeadbeaf.into(); + bad + }; + let response = StatementFetchingResponse::Statement(bad_candidate); + outgoing.pending_response.send(Ok(response.encode())).unwrap(); + } + ); + + // Should get punished and never tried again: + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r)) + ) if p == peer_bad && r == COST_WRONG_HASH.into() => {} + ); + + // a is tried again (retried in reverse order): + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + // On retry, we should have reverse order: + assert_eq!(outgoing.peer, Recipient::Peer(peer_a)); + } + ); + + // c succeeds now: + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + // On retry, we should have reverse order: + assert_eq!(outgoing.peer, Recipient::Peer(peer_c)); + let response = StatementFetchingResponse::Statement(candidate.clone()); + outgoing.pending_response.send(Ok(response.encode())).unwrap(); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r)) + ) if p == peer_a && r == COST_FETCH_FAIL.into() => {} + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r)) + ) if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() => {} + ); + + let statement_with_pvd = extend_statement_with_pvd(statement.clone(), pvd.clone()); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::PersistedValidationData(para_id, assumption, tx), + )) if para_id == PARA_ID && + assumption == OccupiedCoreAssumption::Free && + hash == hash_a => + { + tx.send(Ok(Some(pvd))).unwrap(); + } + ); + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r)) + ) if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => {} + ); + + assert_matches!( + handle.recv().await, + AllMessages::CandidateBacking( + CandidateBackingMessage::Statement(r, s) + ) if r == hash_a && s == statement_with_pvd => {} + ); + + // Now messages should go out: + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + mut recipients, + Versioned::V1(protocol_v1::ValidationProtocol::StatementDistribution( + protocol_v1::StatementDistributionMessage::LargeStatement(meta) + )), + ) + ) => { + gum::debug!( + target: LOG_TARGET, + ?recipients, + "Recipients received" + ); + recipients.sort(); + let mut expected = vec![peer_b, peer_c, peer_bad]; + expected.sort(); + assert_eq!(recipients, expected); + assert_eq!(meta.relay_parent, hash_a); + assert_eq!(meta.candidate_hash, statement.payload().candidate_hash()); + assert_eq!(meta.signed_by, statement.validator_index()); + assert_eq!(&meta.signature, statement.signature()); + } + ); + + // Now that it has the candidate it should answer requests accordingly (even after a + // failed request): + + // Failing request first (wrong relay parent hash): + let (pending_response, response_rx) = oneshot::channel(); + let inner_req = StatementFetchingRequest { + relay_parent: hash_b, + candidate_hash: metadata.candidate_hash, + }; + let req = sc_network::config::IncomingRequest { + peer: peer_b, + payload: inner_req.encode(), + pending_response, + }; + req_cfg.inbound_queue.as_mut().unwrap().send(req).await.unwrap(); + assert_matches!( + response_rx.await.unwrap().result, + Err(()) => {} + ); + + // Another failing request (peer_a never received a statement from us, so it is not + // allowed to request the data): + let (pending_response, response_rx) = oneshot::channel(); + let inner_req = StatementFetchingRequest { + relay_parent: metadata.relay_parent, + candidate_hash: metadata.candidate_hash, + }; + let req = sc_network::config::IncomingRequest { + peer: peer_a, + payload: inner_req.encode(), + pending_response, + }; + req_cfg.inbound_queue.as_mut().unwrap().send(req).await.unwrap(); + assert_matches!( + response_rx.await.unwrap().result, + Err(()) => {} + ); + + // And now the succeding request from peer_b: + let (pending_response, response_rx) = oneshot::channel(); + let inner_req = StatementFetchingRequest { + relay_parent: metadata.relay_parent, + candidate_hash: metadata.candidate_hash, + }; + let req = sc_network::config::IncomingRequest { + peer: peer_b, + payload: inner_req.encode(), + pending_response, + }; + req_cfg.inbound_queue.as_mut().unwrap().send(req).await.unwrap(); + let StatementFetchingResponse::Statement(committed) = + Decode::decode(&mut response_rx.await.unwrap().result.unwrap().as_ref()).unwrap(); + assert_eq!(committed, candidate); + + handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::pin_mut!(test_fut); + futures::pin_mut!(bg); + + executor::block_on(future::join(test_fut, bg)); +} + +#[test] +fn delay_reputation_changes() { + sp_tracing::try_init_simple(); + let hash_a = Hash::repeat_byte(1); + let pvd = dummy_pvd(); + + let candidate = { + let mut c = dummy_committed_candidate_receipt(dummy_hash()); + c.descriptor.relay_parent = hash_a; + c.descriptor.para_id = 1.into(); + c.commitments.new_validation_code = Some(ValidationCode(vec![1, 2, 3])); + c + }; + + let peer_a = PeerId::random(); // Alice + let peer_b = PeerId::random(); // Bob + let peer_c = PeerId::random(); // Charlie + let peer_bad = PeerId::random(); // No validator + + let validators = vec![ + Sr25519Keyring::Alice.pair(), + Sr25519Keyring::Bob.pair(), + Sr25519Keyring::Charlie.pair(), + // We: + Sr25519Keyring::Ferdie.pair(), + ]; + + let session_info = make_session_info(validators, vec![vec![0, 1, 2, 4], vec![3]]); + + let session_index = 1; + + let pool = sp_core::testing::TaskExecutor::new(); + let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); + + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); + let (candidate_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); + + let reputation_interval = Duration::from_millis(100); + + let bg = async move { + let s = StatementDistributionSubsystem { + keystore: make_ferdie_keystore(), + v1_req_receiver: Some(statement_req_receiver), + req_receiver: Some(candidate_req_receiver), + metrics: Default::default(), + rng: AlwaysZeroRng, + reputation: ReputationAggregator::new(|_| false), + }; + s.run_inner(ctx, reputation_interval).await.unwrap(); + }; + + let test_fut = async move { + // register our active heads. + handle + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) + if r == hash_a + => { + let _ = tx.send(Err(ASYNC_BACKING_DISABLED_ERROR)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx)) + ) + if r == hash_a + => { + let _ = tx.send(Ok(session_index)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx)) + ) + if r == hash_a && sess_index == session_index + => { + let _ = tx.send(Ok(Some(session_info))); + } + ); + + // notify of peers and view + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_a, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([Sr25519Keyring::Alice.public().into()])), + ), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_b, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([Sr25519Keyring::Bob.public().into()])), + ), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_c, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([Sr25519Keyring::Charlie.public().into()])), + ), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_bad, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_a, view![hash_a]), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_b, view![hash_a]), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_c, view![hash_a]), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_bad, view![hash_a]), + ), + }) + .await; + + // receive a seconded statement from peer A, which does not provide the request data, + // then get that data from peer C. It should be propagated onwards to peer B and to + // candidate backing. + let statement = { + let signing_context = SigningContext { parent_hash: hash_a, session_index }; + + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + let alice_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); + + SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate.clone()), + &signing_context, + ValidatorIndex(0), + &alice_public.into(), + ) + .ok() + .flatten() + .expect("should be signed") + }; + + let metadata = derive_metadata_assuming_seconded(hash_a, statement.clone().into()); + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_a, + Versioned::V1(protocol_v1::StatementDistributionMessage::LargeStatement( + metadata.clone(), + )), + ), + ), + }) + .await; + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + assert_eq!(outgoing.peer, Recipient::Peer(peer_a)); + // Just drop request - should trigger error. + } + ); + + // There is a race between request handler asking for more peers and processing of the + // coming `PeerMessage`s, we want the request handler to ask first here for better test + // coverage: + Delay::new(Duration::from_millis(20)).await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_c, + Versioned::V1(protocol_v1::StatementDistributionMessage::LargeStatement( + metadata.clone(), + )), + ), + ), + }) + .await; + + // Malicious peer: + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_bad, + Versioned::V1(protocol_v1::StatementDistributionMessage::LargeStatement( + metadata.clone(), + )), + ), + ), + }) + .await; + + // Let c fail once too: + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + assert_eq!(outgoing.peer, Recipient::Peer(peer_c)); + } + ); + + // a fails again: + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + // On retry, we should have reverse order: + assert_eq!(outgoing.peer, Recipient::Peer(peer_a)); + } + ); + + // Send invalid response (all other peers have been tried now): + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + assert_eq!(outgoing.peer, Recipient::Peer(peer_bad)); + let bad_candidate = { + let mut bad = candidate.clone(); + bad.descriptor.para_id = 0xeadbeaf.into(); + bad + }; + let response = StatementFetchingResponse::Statement(bad_candidate); + outgoing.pending_response.send(Ok(response.encode())).unwrap(); + } + ); + + // a is tried again (retried in reverse order): + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + // On retry, we should have reverse order: + assert_eq!(outgoing.peer, Recipient::Peer(peer_a)); + } + ); + + // c succeeds now: + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendRequests( + mut reqs, IfDisconnected::ImmediateError + ) + ) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + // On retry, we should have reverse order: + assert_eq!(outgoing.peer, Recipient::Peer(peer_c)); + let response = StatementFetchingResponse::Statement(candidate.clone()); + outgoing.pending_response.send(Ok(response.encode())).unwrap(); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::PersistedValidationData(_, assumption, tx), + )) if assumption == OccupiedCoreAssumption::Free && hash == hash_a => + { + tx.send(Ok(Some(pvd))).unwrap(); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::CandidateBacking(CandidateBackingMessage::Statement(..)) + ); + + // Now messages should go out: + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + mut recipients, + Versioned::V1(protocol_v1::ValidationProtocol::StatementDistribution( + protocol_v1::StatementDistributionMessage::LargeStatement(meta) + )), + ) + ) => { + gum::debug!( + target: LOG_TARGET, + ?recipients, + "Recipients received" + ); + recipients.sort(); + let mut expected = vec![peer_b, peer_c, peer_bad]; + expected.sort(); + assert_eq!(recipients, expected); + assert_eq!(meta.relay_parent, hash_a); + assert_eq!(meta.candidate_hash, statement.payload().candidate_hash()); + assert_eq!(meta.signed_by, statement.validator_index()); + assert_eq!(&meta.signature, statement.signature()); + } + ); + + // Wait enough to fire reputation delay + futures_timer::Delay::new(reputation_interval).await; + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Batch(v)) + ) => { + let mut expected_change = HashMap::new(); + for rep in vec![COST_FETCH_FAIL, BENEFIT_VALID_STATEMENT_FIRST] { + add_reputation(&mut expected_change, peer_a, rep) + } + for rep in vec![BENEFIT_VALID_RESPONSE, BENEFIT_VALID_STATEMENT] { + add_reputation(&mut expected_change, peer_c, rep) + } + for rep in vec![COST_WRONG_HASH, BENEFIT_VALID_STATEMENT] { + add_reputation(&mut expected_change, peer_bad, rep) + } + assert_eq!(v, expected_change); + } + ); + + handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::pin_mut!(test_fut); + futures::pin_mut!(bg); + + executor::block_on(future::join(test_fut, bg)); +} + +#[test] +fn share_prioritizes_backing_group() { + sp_tracing::try_init_simple(); + let hash_a = Hash::repeat_byte(1); + + let candidate = { + let mut c = dummy_committed_candidate_receipt(dummy_hash()); + c.descriptor.relay_parent = hash_a; + c.descriptor.para_id = 1.into(); + c.commitments.new_validation_code = Some(ValidationCode(vec![1, 2, 3])); + c + }; + + let peer_a = PeerId::random(); // Alice + let peer_b = PeerId::random(); // Bob + let peer_c = PeerId::random(); // Charlie + let peer_bad = PeerId::random(); // No validator + let peer_other_group = PeerId::random(); //Ferdie + + let mut validators = vec![ + Sr25519Keyring::Alice.pair(), + Sr25519Keyring::Bob.pair(), + Sr25519Keyring::Charlie.pair(), + // other group + Sr25519Keyring::Dave.pair(), + // We: + Sr25519Keyring::Ferdie.pair(), + ]; + + // Strictly speaking we only need MIN_GOSSIP_PEERS - 3 to make sure only priority peers + // will be served, but by using a larger value we test for overflow errors: + let dummy_count = MIN_GOSSIP_PEERS; + + // We artificially inflate our group, so there won't be any free slots for other peers. (We + // want to test that our group is prioritized): + let dummy_pairs: Vec<_> = + std::iter::repeat_with(|| Pair::generate().0).take(dummy_count).collect(); + let dummy_peers: Vec<_> = + std::iter::repeat_with(|| PeerId::random()).take(dummy_count).collect(); + + validators = validators.into_iter().chain(dummy_pairs.clone()).collect(); + + let mut first_group = vec![0, 1, 2, 4]; + first_group.append(&mut (0..dummy_count as u32).map(|v| v + 5).collect()); + let session_info = make_session_info(validators, vec![first_group, vec![3]]); + + let session_index = 1; + + let pool = sp_core::testing::TaskExecutor::new(); + let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); + + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, mut req_cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + let (candidate_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); + + let bg = async move { + let s = StatementDistributionSubsystem { + keystore: make_ferdie_keystore(), + v1_req_receiver: Some(statement_req_receiver), + req_receiver: Some(candidate_req_receiver), + metrics: Default::default(), + rng: AlwaysZeroRng, + reputation: ReputationAggregator::new(|_| true), + }; + s.run(ctx).await.unwrap(); + }; + + let test_fut = async move { + // register our active heads. + handle + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) + if r == hash_a + => { + let _ = tx.send(Err(ASYNC_BACKING_DISABLED_ERROR)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx)) + ) + if r == hash_a + => { + let _ = tx.send(Ok(session_index)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx)) + ) + if r == hash_a && sess_index == session_index + => { + let _ = tx.send(Ok(Some(session_info))); + } + ); + + // notify of dummy peers and view + for (peer, pair) in dummy_peers.clone().into_iter().zip(dummy_pairs) { + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([pair.public().into()])), + ), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer, view![hash_a]), + ), + }) + .await; + } + + // notify of peers and view + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_a, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([Sr25519Keyring::Alice.public().into()])), + ), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_b, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([Sr25519Keyring::Bob.public().into()])), + ), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_c, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([Sr25519Keyring::Charlie.public().into()])), + ), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_bad, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_other_group, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([Sr25519Keyring::Dave.public().into()])), + ), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_a, view![hash_a]), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_b, view![hash_a]), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_c, view![hash_a]), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_bad, view![hash_a]), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_other_group, view![hash_a]), + ), + }) + .await; + + // receive a seconded statement from peer A, which does not provide the request data, + // then get that data from peer C. It should be propagated onwards to peer B and to + // candidate backing. + let statement = { + let signing_context = SigningContext { parent_hash: hash_a, session_index }; + + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + let ferdie_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Ferdie.to_seed()), + ) + .unwrap(); + + // note: this is ignored by legacy-v1 code. + let pvd = PersistedValidationData { + parent_head: HeadData::from(vec![1, 2, 3]), + relay_parent_number: 0, + relay_parent_storage_root: Hash::repeat_byte(42), + max_pov_size: 100, + }; + + SignedFullStatementWithPVD::sign( + &keystore, + Statement::Seconded(candidate.clone()).supply_pvd(pvd), + &signing_context, + ValidatorIndex(4), + &ferdie_public.into(), + ) + .ok() + .flatten() + .expect("should be signed") + }; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(hash_a, statement.clone()), + }) + .await; + + let statement = StatementWithPVD::drop_pvd_from_signed(statement); + let metadata = derive_metadata_assuming_seconded(hash_a, statement.clone().into()); + + // Messages should go out: + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + mut recipients, + Versioned::V1(protocol_v1::ValidationProtocol::StatementDistribution( + protocol_v1::StatementDistributionMessage::LargeStatement(meta) + )), + ) + ) => { + gum::debug!( + target: LOG_TARGET, + ?recipients, + "Recipients received" + ); + recipients.sort(); + // We expect only our backing group to be the recipients, du to the inflated + // test group above: + let mut expected: Vec<_> = vec![peer_a, peer_b, peer_c].into_iter().chain(dummy_peers).collect(); + expected.sort(); + assert_eq!(recipients.len(), expected.len()); + assert_eq!(recipients, expected); + assert_eq!(meta.relay_parent, hash_a); + assert_eq!(meta.candidate_hash, statement.payload().candidate_hash()); + assert_eq!(meta.signed_by, statement.validator_index()); + assert_eq!(&meta.signature, statement.signature()); + } + ); + + // Now that it has the candidate it should answer requests accordingly: + + let (pending_response, response_rx) = oneshot::channel(); + let inner_req = StatementFetchingRequest { + relay_parent: metadata.relay_parent, + candidate_hash: metadata.candidate_hash, + }; + let req = sc_network::config::IncomingRequest { + peer: peer_b, + payload: inner_req.encode(), + pending_response, + }; + req_cfg.inbound_queue.as_mut().unwrap().send(req).await.unwrap(); + let StatementFetchingResponse::Statement(committed) = + Decode::decode(&mut response_rx.await.unwrap().result.unwrap().as_ref()).unwrap(); + assert_eq!(committed, candidate); + + handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::pin_mut!(test_fut); + futures::pin_mut!(bg); + + executor::block_on(future::join(test_fut, bg)); +} + +#[test] +fn peer_cant_flood_with_large_statements() { + sp_tracing::try_init_simple(); + let hash_a = Hash::repeat_byte(1); + + let candidate = { + let mut c = dummy_committed_candidate_receipt(dummy_hash()); + c.descriptor.relay_parent = hash_a; + c.descriptor.para_id = 1.into(); + c.commitments.new_validation_code = Some(ValidationCode(vec![1, 2, 3])); + c + }; + + let peer_a = PeerId::random(); // Alice + + let validators = vec![ + Sr25519Keyring::Alice.pair(), + Sr25519Keyring::Bob.pair(), + Sr25519Keyring::Charlie.pair(), + // other group + Sr25519Keyring::Dave.pair(), + // We: + Sr25519Keyring::Ferdie.pair(), + ]; + + let first_group = vec![0, 1, 2, 4]; + let session_info = make_session_info(validators, vec![first_group, vec![3]]); + + let session_index = 1; + + let pool = sp_core::testing::TaskExecutor::new(); + let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); + + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); + let (candidate_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); + let bg = async move { + let s = StatementDistributionSubsystem { + keystore: make_ferdie_keystore(), + v1_req_receiver: Some(statement_req_receiver), + req_receiver: Some(candidate_req_receiver), + metrics: Default::default(), + rng: AlwaysZeroRng, + reputation: ReputationAggregator::new(|_| true), + }; + s.run(ctx).await.unwrap(); + }; + + let test_fut = async move { + // register our active heads. + handle + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) + if r == hash_a + => { + let _ = tx.send(Err(ASYNC_BACKING_DISABLED_ERROR)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx)) + ) + if r == hash_a + => { + let _ = tx.send(Ok(session_index)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx)) + ) + if r == hash_a && sess_index == session_index + => { + let _ = tx.send(Ok(Some(session_info))); + } + ); + + // notify of peers and view + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer_a, + ObservedRole::Full, + ValidationVersion::V1.into(), + Some(HashSet::from([Sr25519Keyring::Alice.public().into()])), + ), + ), + }) + .await; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer_a, view![hash_a]), + ), + }) + .await; + + // receive a seconded statement from peer A. + let statement = { + let signing_context = SigningContext { parent_hash: hash_a, session_index }; + + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + let alice_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); + + SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate.clone()), + &signing_context, + ValidatorIndex(0), + &alice_public.into(), + ) + .ok() + .flatten() + .expect("should be signed") + }; + + let metadata = derive_metadata_assuming_seconded(hash_a, statement.clone().into()); + + for _ in 0..MAX_LARGE_STATEMENTS_PER_SENDER + 1 { + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_a, + Versioned::V1( + protocol_v1::StatementDistributionMessage::LargeStatement( + metadata.clone(), + ), + ), + ), + ), + }) + .await; + } + + // We should try to fetch the data and punish the peer (but we don't know what comes + // first): + let mut requested = false; + let mut punished = false; + for _ in 0..2 { + match handle.recv().await { + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendRequests( + mut reqs, + IfDisconnected::ImmediateError, + )) => { + let reqs = reqs.pop().unwrap(); + let outgoing = match reqs { + Requests::StatementFetchingV1(outgoing) => outgoing, + _ => panic!("Unexpected request"), + }; + let req = outgoing.payload; + assert_eq!(req.relay_parent, metadata.relay_parent); + assert_eq!(req.candidate_hash, metadata.candidate_hash); + assert_eq!(outgoing.peer, Recipient::Peer(peer_a)); + // Just drop request - should trigger error. + requested = true; + }, + + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer( + ReportPeerMessage::Single(p, r), + )) if p == peer_a && r == COST_APPARENT_FLOOD.into() => { + punished = true; + }, + + m => panic!("Unexpected message: {:?}", m), + } + } + assert!(requested, "large data has not been requested."); + assert!(punished, "Peer should have been punished for flooding."); + + handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::pin_mut!(test_fut); + futures::pin_mut!(bg); + + executor::block_on(future::join(test_fut, bg)); +} + +// This test addresses an issue when received knowledge is not updated on a +// subsequent `Seconded` statements +// See https://github.com/paritytech/polkadot/pull/5177 +#[test] +fn handle_multiple_seconded_statements() { + let relay_parent_hash = Hash::repeat_byte(1); + let pvd = dummy_pvd(); + + let candidate = dummy_committed_candidate_receipt(relay_parent_hash); + let candidate_hash = candidate.hash(); + + // We want to ensure that our peers are not lucky + let mut all_peers: Vec = Vec::with_capacity(MIN_GOSSIP_PEERS + 4); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + assert_ne!(peer_a, peer_b); + + for _ in 0..MIN_GOSSIP_PEERS + 2 { + all_peers.push(PeerId::random()); + } + all_peers.push(peer_a); + all_peers.push(peer_b); + + let mut lucky_peers = all_peers.clone(); + util::choose_random_subset_with_rng( + |_| false, + &mut lucky_peers, + &mut AlwaysZeroRng, + MIN_GOSSIP_PEERS, + ); + lucky_peers.sort(); + assert_eq!(lucky_peers.len(), MIN_GOSSIP_PEERS); + assert!(!lucky_peers.contains(&peer_a)); + assert!(!lucky_peers.contains(&peer_b)); + + let validators = vec![ + Sr25519Keyring::Alice.pair(), + Sr25519Keyring::Bob.pair(), + Sr25519Keyring::Charlie.pair(), + ]; + + let session_info = make_session_info(validators, vec![]); + + let session_index = 1; + + let pool = sp_core::testing::TaskExecutor::new(); + let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); + + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); + let (candidate_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); + + let virtual_overseer_fut = async move { + let s = StatementDistributionSubsystem { + keystore: Arc::new(LocalKeystore::in_memory()), + v1_req_receiver: Some(statement_req_receiver), + req_receiver: Some(candidate_req_receiver), + metrics: Default::default(), + rng: AlwaysZeroRng, + reputation: ReputationAggregator::new(|_| true), + }; + s.run(ctx).await.unwrap(); + }; + + let test_fut = async move { + // register our active heads. + handle + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: relay_parent_hash, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) + if r == relay_parent_hash + => { + let _ = tx.send(Err(ASYNC_BACKING_DISABLED_ERROR)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx)) + ) + if r == relay_parent_hash + => { + let _ = tx.send(Ok(session_index)); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx)) + ) + if r == relay_parent_hash && sess_index == session_index + => { + let _ = tx.send(Ok(Some(session_info))); + } + ); + + // notify of peers and view + for peer in all_peers.iter() { + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + *peer, + ObservedRole::Full, + ValidationVersion::V1.into(), + None, + ), + ), + }) + .await; + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(*peer, view![relay_parent_hash]), + ), + }) + .await; + } + + // Set up a topology which puts peers a & b in a column together. + let gossip_topology = { + // create a lucky_peers+1 * lucky_peers+1 grid topology where we are at index 2, sharing + // a row with peer_a (0) and peer_b (1) and a column with all the lucky peers. + // the rest is filled with junk. + // This is an absolute garbage hack depending on quirks of the implementation + // and not on sound architecture. + + let n_lucky = lucky_peers.len(); + let dim = n_lucky + 1; + let grid_size = dim * dim; + let topology_peer_info: Vec<_> = (0..grid_size) + .map(|i| { + if i == 0 { + TopologyPeerInfo { + peer_ids: vec![peer_a], + validator_index: ValidatorIndex(0), + discovery_id: AuthorityPair::generate().0.public(), + } + } else if i == 1 { + TopologyPeerInfo { + peer_ids: vec![peer_b], + validator_index: ValidatorIndex(1), + discovery_id: AuthorityPair::generate().0.public(), + } + } else if i == 2 { + TopologyPeerInfo { + peer_ids: vec![], + validator_index: ValidatorIndex(2), + discovery_id: AuthorityPair::generate().0.public(), + } + } else if (i - 2) % dim == 0 { + let lucky_index = ((i - 2) / dim) - 1; + TopologyPeerInfo { + peer_ids: vec![lucky_peers[lucky_index]], + validator_index: ValidatorIndex(i as _), + discovery_id: AuthorityPair::generate().0.public(), + } + } else { + TopologyPeerInfo { + peer_ids: vec![PeerId::random()], + validator_index: ValidatorIndex(i as _), + discovery_id: AuthorityPair::generate().0.public(), + } + } + }) + .collect(); + + // also a hack: this is only required to be accurate for + // the validator indices we compute grid neighbors for. + let mut shuffled_indices = vec![0; grid_size]; + shuffled_indices[2] = 2; + + // Some sanity checking to make sure this hack is set up correctly. + let topology = SessionGridTopology::new(shuffled_indices, topology_peer_info); + let grid_neighbors = topology.compute_grid_neighbors_for(ValidatorIndex(2)).unwrap(); + assert_eq!(grid_neighbors.peers_x.len(), 25); + assert!(grid_neighbors.peers_x.contains(&peer_a)); + assert!(grid_neighbors.peers_x.contains(&peer_b)); + assert!(!grid_neighbors.peers_y.contains(&peer_b)); + assert!(!grid_neighbors.route_to_peer(RequiredRouting::GridY, &peer_b)); + assert_eq!(grid_neighbors.peers_y.len(), lucky_peers.len()); + for lucky in &lucky_peers { + assert!(grid_neighbors.peers_y.contains(lucky)); + } + + network_bridge_event::NewGossipTopology { + session: 1, + topology, + local_index: Some(ValidatorIndex(2)), + } + }; + + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::NewGossipTopology(gossip_topology), + ), + }) + .await; + + // receive a seconded statement from peer A. it should be propagated onwards to peer B and + // to candidate backing. + let statement = { + let signing_context = SigningContext { parent_hash: relay_parent_hash, session_index }; + + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + let alice_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); + + SignedFullStatement::sign( + &keystore, + Statement::Seconded(candidate.clone()), + &signing_context, + ValidatorIndex(0), + &alice_public.into(), + ) + .ok() + .flatten() + .expect("should be signed") + }; + + // `PeerA` sends a `Seconded` message + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_a, + Versioned::V1(protocol_v1::StatementDistributionMessage::Statement( + relay_parent_hash, + statement.clone().into(), + )), + ), + ), + }) + .await; + + let statement_with_pvd = extend_statement_with_pvd(statement.clone(), pvd.clone()); + + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::PersistedValidationData(_, assumption, tx), + )) if assumption == OccupiedCoreAssumption::Free => { + tx.send(Ok(Some(pvd.clone()))).unwrap(); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r)) + ) => { + assert_eq!(p, peer_a); + assert_eq!(r, BENEFIT_VALID_STATEMENT_FIRST.into()); + } + ); + + // After the first valid statement, we expect messages to be circulated + assert_matches!( + handle.recv().await, + AllMessages::CandidateBacking( + CandidateBackingMessage::Statement(r, s) + ) => { + assert_eq!(r, relay_parent_hash); + assert_eq!(s, statement_with_pvd); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + recipients, + Versioned::V1(protocol_v1::ValidationProtocol::StatementDistribution( + protocol_v1::StatementDistributionMessage::Statement(r, s) + )), + ) + ) => { + assert!(!recipients.contains(&peer_b)); + assert_eq!(r, relay_parent_hash); + assert_eq!(s, statement.clone().into()); + } + ); + + // `PeerB` sends a `Seconded` message: valid but known + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_b, + Versioned::V1(protocol_v1::StatementDistributionMessage::Statement( + relay_parent_hash, + statement.clone().into(), + )), + ), + ), + }) + .await; + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r)) + ) => { + assert_eq!(p, peer_b); + assert_eq!(r, BENEFIT_VALID_STATEMENT.into()); + } + ); + + // Create a `Valid` statement + let statement = { + let signing_context = SigningContext { parent_hash: relay_parent_hash, session_index }; + + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + let alice_public = Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); + + SignedFullStatement::sign( + &keystore, + Statement::Valid(candidate_hash), + &signing_context, + ValidatorIndex(0), + &alice_public.into(), + ) + .ok() + .flatten() + .expect("should be signed") + }; + + // `PeerA` sends a `Valid` message + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_a, + Versioned::V1(protocol_v1::StatementDistributionMessage::Statement( + relay_parent_hash, + statement.clone().into(), + )), + ), + ), + }) + .await; + + let statement_with_pvd = extend_statement_with_pvd(statement.clone(), pvd.clone()); + + // Persisted validation data is cached. + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r)) + ) => { + assert_eq!(p, peer_a); + assert_eq!(r, BENEFIT_VALID_STATEMENT_FIRST.into()); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::CandidateBacking( + CandidateBackingMessage::Statement(r, s) + ) => { + assert_eq!(r, relay_parent_hash); + assert_eq!(s, statement_with_pvd); + } + ); + + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + recipients, + Versioned::V1(protocol_v1::ValidationProtocol::StatementDistribution( + protocol_v1::StatementDistributionMessage::Statement(r, s) + )), + ) + ) => { + assert!(!recipients.contains(&peer_b)); + assert_eq!(r, relay_parent_hash); + assert_eq!(s, statement.clone().into()); + } + ); + + // `PeerB` sends a `Valid` message + handle + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage( + peer_b, + Versioned::V1(protocol_v1::StatementDistributionMessage::Statement( + relay_parent_hash, + statement.clone().into(), + )), + ), + ), + }) + .await; + + // We expect that this is still valid despite the fact that `PeerB` was not + // the first when sending `Seconded` + assert_matches!( + handle.recv().await, + AllMessages::NetworkBridgeTx( + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r)) + ) => { + assert_eq!(p, peer_b); + assert_eq!(r, BENEFIT_VALID_STATEMENT.into()); + } + ); + + handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }; + + futures::pin_mut!(test_fut); + futures::pin_mut!(virtual_overseer_fut); + + executor::block_on(future::join(test_fut, virtual_overseer_fut)); +} + +fn make_session_info(validators: Vec, groups: Vec>) -> SessionInfo { + let validator_groups: IndexedVec> = groups + .iter() + .map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect()) + .collect(); + + SessionInfo { + discovery_keys: validators.iter().map(|k| k.public().into()).collect(), + // Not used: + n_cores: validator_groups.len() as u32, + validator_groups, + validators: validators.iter().map(|k| k.public().into()).collect(), + // Not used values: + assignment_keys: Vec::new(), + zeroth_delay_tranche_width: 0, + relay_vrf_modulo_samples: 0, + n_delay_tranches: 0, + no_show_slots: 0, + needed_approvals: 0, + active_validator_indices: Vec::new(), + dispute_period: 6, + random_seed: [0u8; 32], + } +} + +fn derive_metadata_assuming_seconded( + hash: Hash, + statement: UncheckedSignedFullStatement, +) -> protocol_v1::StatementMetadata { + protocol_v1::StatementMetadata { + relay_parent: hash, + candidate_hash: statement.unchecked_payload().candidate_hash(), + signed_by: statement.unchecked_validator_index(), + signature: statement.unchecked_signature().clone(), + } +} + +// TODO [now]: adapt most tests to v2 messages. +// TODO [now]: test that v2 peers send v1 messages to v1 peers +// TODO [now]: test that v2 peers handle v1 messages from v1 peers. +// TODO [now]: test that v2 peers send v2 messages to v2 peers. diff --git a/polkadot/node/network/statement-distribution/src/lib.rs b/polkadot/node/network/statement-distribution/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..b2eb9cccced4de0b607d4a4dcd9142d98c80f7ab --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/lib.rs @@ -0,0 +1,438 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Statement Distribution Subsystem. +//! +//! This is responsible for distributing signed statements about candidate +//! validity among validators. + +// #![deny(unused_crate_dependencies)] +#![warn(missing_docs)] + +use error::{log_error, FatalResult}; +use std::time::Duration; + +use polkadot_node_network_protocol::{ + request_response::{ + v1 as request_v1, vstaging::AttestedCandidateRequest, IncomingRequestReceiver, + }, + vstaging as protocol_vstaging, Versioned, +}; +use polkadot_node_primitives::StatementWithPVD; +use polkadot_node_subsystem::{ + messages::{NetworkBridgeEvent, StatementDistributionMessage}, + overseer, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, +}; +use polkadot_node_subsystem_util::{ + rand, + reputation::{ReputationAggregator, REPUTATION_CHANGE_INTERVAL}, + runtime::{prospective_parachains_mode, ProspectiveParachainsMode}, +}; + +use futures::{channel::mpsc, prelude::*}; +use sp_keystore::KeystorePtr; + +use fatality::Nested; + +mod error; +pub use error::{Error, FatalError, JfyiError, Result}; + +/// Metrics for the statement distribution +pub(crate) mod metrics; +use metrics::Metrics; + +mod legacy_v1; +use legacy_v1::{ + respond as v1_respond_task, RequesterMessage as V1RequesterMessage, + ResponderMessage as V1ResponderMessage, +}; + +mod vstaging; + +const LOG_TARGET: &str = "parachain::statement-distribution"; + +/// The statement distribution subsystem. +pub struct StatementDistributionSubsystem { + /// Pointer to a keystore, which is required for determining this node's validator index. + keystore: KeystorePtr, + /// Receiver for incoming large statement requests. + v1_req_receiver: Option>, + /// Receiver for incoming candidate requests. + req_receiver: Option>, + /// Prometheus metrics + metrics: Metrics, + /// Pseudo-random generator for peers selection logic + rng: R, + /// Aggregated reputation change + reputation: ReputationAggregator, +} + +#[overseer::subsystem(StatementDistribution, error=SubsystemError, prefix=self::overseer)] +impl StatementDistributionSubsystem { + fn start(self, ctx: Context) -> SpawnedSubsystem { + // Swallow error because failure is fatal to the node and we log with more precision + // within `run`. + SpawnedSubsystem { + name: "statement-distribution-subsystem", + future: self + .run(ctx) + .map_err(|e| SubsystemError::with_origin("statement-distribution", e)) + .boxed(), + } + } +} + +/// Messages to be handled in this subsystem. +enum MuxedMessage { + /// Messages from other subsystems. + Subsystem(FatalResult>), + /// Messages from spawned v1 (legacy) requester background tasks. + V1Requester(Option), + /// Messages from spawned v1 (legacy) responder background task. + V1Responder(Option), + /// Messages from candidate responder background task. + Responder(Option), + /// Messages from answered requests. + Response(vstaging::UnhandledResponse), + /// Message that a request is ready to be retried. This just acts as a signal that we should + /// dispatch all pending requests again. + RetryRequest(()), +} + +#[overseer::contextbounds(StatementDistribution, prefix = self::overseer)] +impl MuxedMessage { + async fn receive( + ctx: &mut Context, + state: &mut vstaging::State, + from_v1_requester: &mut mpsc::Receiver, + from_v1_responder: &mut mpsc::Receiver, + from_responder: &mut mpsc::Receiver, + ) -> MuxedMessage { + let (request_manager, response_manager) = state.request_and_response_managers(); + // We are only fusing here to make `select` happy, in reality we will quit if one of those + // streams end: + let from_orchestra = ctx.recv().fuse(); + let from_v1_requester = from_v1_requester.next(); + let from_v1_responder = from_v1_responder.next(); + let from_responder = from_responder.next(); + let receive_response = vstaging::receive_response(response_manager).fuse(); + let retry_request = vstaging::next_retry(request_manager).fuse(); + futures::pin_mut!( + from_orchestra, + from_v1_requester, + from_v1_responder, + from_responder, + receive_response, + retry_request, + ); + futures::select! { + msg = from_orchestra => MuxedMessage::Subsystem(msg.map_err(FatalError::SubsystemReceive)), + msg = from_v1_requester => MuxedMessage::V1Requester(msg), + msg = from_v1_responder => MuxedMessage::V1Responder(msg), + msg = from_responder => MuxedMessage::Responder(msg), + msg = receive_response => MuxedMessage::Response(msg), + msg = retry_request => MuxedMessage::RetryRequest(msg), + } + } +} + +#[overseer::contextbounds(StatementDistribution, prefix = self::overseer)] +impl StatementDistributionSubsystem { + /// Create a new Statement Distribution Subsystem + pub fn new( + keystore: KeystorePtr, + v1_req_receiver: IncomingRequestReceiver, + req_receiver: IncomingRequestReceiver, + metrics: Metrics, + rng: R, + ) -> Self { + Self { + keystore, + v1_req_receiver: Some(v1_req_receiver), + req_receiver: Some(req_receiver), + metrics, + rng, + reputation: Default::default(), + } + } + + async fn run(self, ctx: Context) -> std::result::Result<(), FatalError> { + self.run_inner(ctx, REPUTATION_CHANGE_INTERVAL).await + } + + async fn run_inner( + mut self, + mut ctx: Context, + reputation_interval: Duration, + ) -> std::result::Result<(), FatalError> { + let new_reputation_delay = || futures_timer::Delay::new(reputation_interval).fuse(); + let mut reputation_delay = new_reputation_delay(); + + let mut legacy_v1_state = crate::legacy_v1::State::new(self.keystore.clone()); + let mut state = crate::vstaging::State::new(self.keystore.clone()); + + // Sender/Receiver for getting news from our statement fetching tasks. + let (v1_req_sender, mut v1_req_receiver) = mpsc::channel(1); + // Sender/Receiver for getting news from our responder task. + let (v1_res_sender, mut v1_res_receiver) = mpsc::channel(1); + + let mut warn_freq = gum::Freq::new(); + + ctx.spawn( + "large-statement-responder", + v1_respond_task( + self.v1_req_receiver.take().expect("Mandatory argument to new. qed"), + v1_res_sender.clone(), + ) + .boxed(), + ) + .map_err(FatalError::SpawnTask)?; + + // Sender/receiver for getting news from our candidate responder task. + let (res_sender, mut res_receiver) = mpsc::channel(1); + + ctx.spawn( + "candidate-responder", + vstaging::respond_task( + self.req_receiver.take().expect("Mandatory argument to new. qed"), + res_sender.clone(), + ) + .boxed(), + ) + .map_err(FatalError::SpawnTask)?; + + loop { + // Wait for the next message. + let message = futures::select! { + _ = reputation_delay => { + self.reputation.send(ctx.sender()).await; + reputation_delay = new_reputation_delay(); + continue + }, + message = MuxedMessage::receive( + &mut ctx, + &mut state, + &mut v1_req_receiver, + &mut v1_res_receiver, + &mut res_receiver, + ).fuse() => { + message + } + }; + + match message { + MuxedMessage::Subsystem(result) => { + let result = self + .handle_subsystem_message( + &mut ctx, + &mut state, + &mut legacy_v1_state, + &v1_req_sender, + result?, + ) + .await; + match result.into_nested()? { + Ok(true) => break, + Ok(false) => {}, + Err(jfyi) => gum::debug!(target: LOG_TARGET, error = ?jfyi), + } + }, + MuxedMessage::V1Requester(result) => { + let result = crate::legacy_v1::handle_requester_message( + &mut ctx, + &mut legacy_v1_state, + &v1_req_sender, + &mut self.rng, + result.ok_or(FatalError::RequesterReceiverFinished)?, + &self.metrics, + &mut self.reputation, + ) + .await; + log_error( + result.map_err(From::from), + "handle_requester_message", + &mut warn_freq, + )?; + }, + MuxedMessage::V1Responder(result) => { + let result = crate::legacy_v1::handle_responder_message( + &mut legacy_v1_state, + result.ok_or(FatalError::ResponderReceiverFinished)?, + ) + .await; + log_error( + result.map_err(From::from), + "handle_responder_message", + &mut warn_freq, + )?; + }, + MuxedMessage::Responder(result) => { + vstaging::answer_request( + &mut state, + result.ok_or(FatalError::RequesterReceiverFinished)?, + ); + }, + MuxedMessage::Response(result) => { + vstaging::handle_response(&mut ctx, &mut state, result, &mut self.reputation) + .await; + }, + MuxedMessage::RetryRequest(()) => { + // A pending request is ready to retry. This is only a signal to call + // `dispatch_requests` again. + () + }, + }; + + vstaging::dispatch_requests(&mut ctx, &mut state).await; + } + Ok(()) + } + + async fn handle_subsystem_message( + &mut self, + ctx: &mut Context, + state: &mut vstaging::State, + legacy_v1_state: &mut legacy_v1::State, + v1_req_sender: &mpsc::Sender, + message: FromOrchestra, + ) -> Result { + let metrics = &self.metrics; + + match message { + FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated, + deactivated, + })) => { + let _timer = metrics.time_active_leaves_update(); + + // vstaging should handle activated first because of implicit view. + if let Some(ref activated) = activated { + let mode = prospective_parachains_mode(ctx.sender(), activated.hash).await?; + if let ProspectiveParachainsMode::Enabled { .. } = mode { + vstaging::handle_active_leaves_update(ctx, state, activated, mode).await?; + } else if let ProspectiveParachainsMode::Disabled = mode { + for deactivated in &deactivated { + crate::legacy_v1::handle_deactivate_leaf(legacy_v1_state, *deactivated); + } + + crate::legacy_v1::handle_activated_leaf( + ctx, + legacy_v1_state, + activated.clone(), + ) + .await?; + } + } else { + for deactivated in &deactivated { + crate::legacy_v1::handle_deactivate_leaf(legacy_v1_state, *deactivated); + } + vstaging::handle_deactivate_leaves(state, &deactivated); + } + }, + FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => { + // do nothing + }, + FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(true), + FromOrchestra::Communication { msg } => match msg { + StatementDistributionMessage::Share(relay_parent, statement) => { + let _timer = metrics.time_share(); + + // pass to legacy if legacy state contains head. + if legacy_v1_state.contains_relay_parent(&relay_parent) { + crate::legacy_v1::share_local_statement( + ctx, + legacy_v1_state, + relay_parent, + StatementWithPVD::drop_pvd_from_signed(statement), + &mut self.rng, + metrics, + ) + .await?; + } else { + vstaging::share_local_statement( + ctx, + state, + relay_parent, + statement, + &mut self.reputation, + ) + .await?; + } + }, + StatementDistributionMessage::NetworkBridgeUpdate(event) => { + // pass all events to both protocols except for messages, + // which are filtered. + enum VersionTarget { + Legacy, + Current, + Both, + } + + impl VersionTarget { + fn targets_legacy(&self) -> bool { + match self { + &VersionTarget::Legacy | &VersionTarget::Both => true, + _ => false, + } + } + + fn targets_current(&self) -> bool { + match self { + &VersionTarget::Current | &VersionTarget::Both => true, + _ => false, + } + } + } + + let target = match &event { + NetworkBridgeEvent::PeerMessage(_, message) => match message { + Versioned::VStaging( + protocol_vstaging::StatementDistributionMessage::V1Compatibility(_), + ) => VersionTarget::Legacy, + Versioned::V1(_) => VersionTarget::Legacy, + Versioned::VStaging(_) => VersionTarget::Current, + }, + _ => VersionTarget::Both, + }; + + if target.targets_legacy() { + crate::legacy_v1::handle_network_update( + ctx, + legacy_v1_state, + v1_req_sender, + event.clone(), + &mut self.rng, + metrics, + &mut self.reputation, + ) + .await; + } + + if target.targets_current() { + // pass to vstaging. + vstaging::handle_network_update(ctx, state, event, &mut self.reputation) + .await; + } + }, + StatementDistributionMessage::Backed(candidate_hash) => { + crate::vstaging::handle_backed_candidate_message(ctx, state, candidate_hash) + .await; + }, + }, + } + Ok(false) + } +} diff --git a/polkadot/node/network/statement-distribution/src/metrics.rs b/polkadot/node/network/statement-distribution/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..b9a51dc89d61afd9d2805f294b208f92572dd754 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/metrics.rs @@ -0,0 +1,199 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Metrics for the statement distribution module + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +/// Buckets more suitable for checking the typical latency values +const HISTOGRAM_LATENCY_BUCKETS: &[f64] = &[ + 0.000025, 0.00005, 0.000075, 0.0001, 0.0003125, 0.000625, 0.00125, 0.0025, 0.005, 0.01, 0.025, + 0.05, 0.1, +]; + +#[derive(Clone)] +struct MetricsInner { + statements_distributed: prometheus::Counter, + sent_requests: prometheus::Counter, + received_responses: prometheus::CounterVec, + active_leaves_update: prometheus::Histogram, + share: prometheus::Histogram, + network_bridge_update: prometheus::HistogramVec, + statements_unexpected: prometheus::CounterVec, + created_message_size: prometheus::Gauge, +} + +/// Statement Distribution metrics. +#[derive(Default, Clone)] +pub struct Metrics(Option); + +impl Metrics { + /// Update statements distributed counter + pub fn on_statement_distributed(&self) { + if let Some(metrics) = &self.0 { + metrics.statements_distributed.inc(); + } + } + + /// Update sent requests counter + /// This counter is updated merely for the statements sent via request/response method, + /// meaning that it counts large statements only + pub fn on_sent_request(&self) { + if let Some(metrics) = &self.0 { + metrics.sent_requests.inc(); + } + } + + /// Update counters for the received responses with `succeeded` or `failed` labels + /// These counters are updated merely for the statements received via request/response method, + /// meaning that they count large statements only + pub fn on_received_response(&self, success: bool) { + if let Some(metrics) = &self.0 { + let label = if success { "succeeded" } else { "failed" }; + metrics.received_responses.with_label_values(&[label]).inc(); + } + } + + /// Provide a timer for `active_leaves_update` which observes on drop. + pub fn time_active_leaves_update( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.active_leaves_update.start_timer()) + } + + /// Provide a timer for `share` which observes on drop. + pub fn time_share(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.share.start_timer()) + } + + /// Provide a timer for `network_bridge_update` which observes on drop. + pub fn time_network_bridge_update( + &self, + message_type: &'static str, + ) -> Option { + self.0.as_ref().map(|metrics| { + metrics.network_bridge_update.with_label_values(&[message_type]).start_timer() + }) + } + + /// Update the out-of-view statements counter for unexpected valid statements + pub fn on_unexpected_statement_valid(&self) { + if let Some(metrics) = &self.0 { + metrics.statements_unexpected.with_label_values(&["valid"]).inc(); + } + } + + /// Update the out-of-view statements counter for unexpected seconded statements + pub fn on_unexpected_statement_seconded(&self) { + if let Some(metrics) = &self.0 { + metrics.statements_unexpected.with_label_values(&["seconded"]).inc(); + } + } + + /// Update the out-of-view statements counter for unexpected large statements + pub fn on_unexpected_statement_large(&self) { + if let Some(metrics) = &self.0 { + metrics.statements_unexpected.with_label_values(&["large"]).inc(); + } + } + + /// Report size of a created message. + pub fn on_created_message(&self, size: usize) { + if let Some(metrics) = &self.0 { + metrics.created_message_size.set(size as u64); + } + } +} + +impl metrics::Metrics for Metrics { + fn try_register( + registry: &prometheus::Registry, + ) -> std::result::Result { + let metrics = MetricsInner { + statements_distributed: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_statements_distributed_total", + "Number of candidate validity statements distributed to other peers.", + )?, + registry, + )?, + sent_requests: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_statement_distribution_sent_requests_total", + "Number of large statement fetching requests sent.", + )?, + registry, + )?, + received_responses: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_statement_distribution_received_responses_total", + "Number of received responses for large statement data.", + ), + &["success"], + )?, + registry, + )?, + active_leaves_update: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_statement_distribution_active_leaves_update", + "Time spent within `statement_distribution::active_leaves_update`", + ) + .buckets(HISTOGRAM_LATENCY_BUCKETS.into()), + )?, + registry, + )?, + share: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_statement_distribution_share", + "Time spent within `statement_distribution::share`", + ) + .buckets(HISTOGRAM_LATENCY_BUCKETS.into()), + )?, + registry, + )?, + network_bridge_update: prometheus::register( + prometheus::HistogramVec::new( + prometheus::HistogramOpts::new( + "polkadot_parachain_statement_distribution_network_bridge_update", + "Time spent within `statement_distribution::network_bridge_update`", + ) + .buckets(HISTOGRAM_LATENCY_BUCKETS.into()), + &["message_type"], + )?, + registry, + )?, + statements_unexpected: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_statement_distribution_statements_unexpected", + "Number of statements that were not expected to be received.", + ), + &["type"], + )?, + registry, + )?, + created_message_size: prometheus::register( + prometheus::Gauge::with_opts(prometheus::Opts::new( + "polkadot_parachain_statement_distribution_created_message_size", + "Size of created messages containing Seconded statements.", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/polkadot/node/network/statement-distribution/src/vstaging/candidates.rs b/polkadot/node/network/statement-distribution/src/vstaging/candidates.rs new file mode 100644 index 0000000000000000000000000000000000000000..42d243614506974566bab52665dee61f9aa2add6 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/vstaging/candidates.rs @@ -0,0 +1,1298 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The [`Candidates`] store tracks information about advertised candidates +//! as well as which peers have advertised them. +//! +//! Due to the request-oriented nature of this protocol, we often learn +//! about candidates just as a hash, alongside claimed properties that the +//! receipt would commit to. However, it is only later on that we can +//! confirm those claimed properties. This store lets us keep track of +//! all candidates which are currently 'relevant' after spam-protection, and +//! gives us the ability to detect mis-advertisements after the fact +//! and punish them accordingly. + +use polkadot_node_network_protocol::PeerId; +use polkadot_node_subsystem::messages::HypotheticalCandidate; +use polkadot_primitives::vstaging::{ + CandidateHash, CommittedCandidateReceipt, GroupIndex, Hash, Id as ParaId, + PersistedValidationData, +}; + +use std::{ + collections::{ + hash_map::{Entry, HashMap}, + HashSet, + }, + sync::Arc, +}; + +/// This encapsulates the correct and incorrect advertisers +/// post-confirmation of a candidate. +#[derive(Debug, Default, PartialEq)] +pub struct PostConfirmationReckoning { + /// Peers which advertised correctly. + pub correct: HashSet, + /// Peers which advertised the candidate incorrectly. + pub incorrect: HashSet, +} + +/// Outputs generated by initial confirmation of a candidate. +#[derive(Debug, PartialEq)] +pub struct PostConfirmation { + /// The hypothetical candidate used to determine importability and membership + /// in the hypothetical frontier. + pub hypothetical: HypotheticalCandidate, + /// A "reckoning" of peers who have advertised the candidate previously, + /// either accurately or inaccurately. + pub reckoning: PostConfirmationReckoning, +} + +/// A tracker for all known candidates in the view. +/// +/// See module docs for more info. +#[derive(Default)] +pub struct Candidates { + candidates: HashMap, + by_parent: HashMap<(Hash, ParaId), HashSet>, +} + +impl Candidates { + /// Insert an advertisement. + /// + /// This should be invoked only after performing + /// spam protection and only for advertisements that + /// are valid within the current view. [`Candidates`] never prunes + /// candidate by peer ID, to avoid peers skirting misbehavior + /// reports by disconnecting intermittently. Therefore, this presumes + /// that spam protection limits the peers which can send advertisements + /// about unconfirmed candidates. + /// + /// It returns either `Ok(())` or an immediate error in the + /// case that the candidate is already known and reality conflicts + /// with the advertisement. + pub fn insert_unconfirmed( + &mut self, + peer: PeerId, + candidate_hash: CandidateHash, + claimed_relay_parent: Hash, + claimed_group_index: GroupIndex, + claimed_parent_hash_and_id: Option<(Hash, ParaId)>, + ) -> Result<(), BadAdvertisement> { + let entry = self.candidates.entry(candidate_hash).or_insert_with(|| { + CandidateState::Unconfirmed(UnconfirmedCandidate { + claims: Vec::new(), + parent_claims: HashMap::new(), + unconfirmed_importable_under: HashSet::new(), + }) + }); + + match entry { + CandidateState::Confirmed(ref c) => { + if c.relay_parent() != claimed_relay_parent { + return Err(BadAdvertisement) + } + + if c.group_index() != claimed_group_index { + return Err(BadAdvertisement) + } + + if let Some((claimed_parent_hash, claimed_id)) = claimed_parent_hash_and_id { + if c.parent_head_data_hash() != claimed_parent_hash { + return Err(BadAdvertisement) + } + + if c.para_id() != claimed_id { + return Err(BadAdvertisement) + } + } + }, + CandidateState::Unconfirmed(ref mut c) => { + c.add_claims( + peer, + CandidateClaims { + relay_parent: claimed_relay_parent, + group_index: claimed_group_index, + parent_hash_and_id: claimed_parent_hash_and_id, + }, + ); + + if let Some(parent_claims) = claimed_parent_hash_and_id { + self.by_parent.entry(parent_claims).or_default().insert(candidate_hash); + } + }, + } + + Ok(()) + } + + /// Note that a candidate has been confirmed. If the candidate has just been + /// confirmed (previous state was `Unconfirmed`), then this returns `Some`. Otherwise, `None`. + /// + /// If we are confirming for the first time, then remove any outdated claims, and generate a + /// reckoning of which peers advertised correctly and incorrectly. + /// + /// This does no sanity-checking of input data, and will overwrite already-confirmed candidates. + pub fn confirm_candidate( + &mut self, + candidate_hash: CandidateHash, + candidate_receipt: CommittedCandidateReceipt, + persisted_validation_data: PersistedValidationData, + assigned_group: GroupIndex, + ) -> Option { + let parent_hash = persisted_validation_data.parent_head.hash(); + let relay_parent = candidate_receipt.descriptor().relay_parent; + let para_id = candidate_receipt.descriptor().para_id; + + let prev_state = self.candidates.insert( + candidate_hash, + CandidateState::Confirmed(ConfirmedCandidate { + receipt: Arc::new(candidate_receipt), + persisted_validation_data, + assigned_group, + parent_hash, + importable_under: HashSet::new(), + }), + ); + let new_confirmed = + match self.candidates.get_mut(&candidate_hash).expect("just inserted; qed") { + CandidateState::Confirmed(x) => x, + _ => panic!("just inserted as confirmed; qed"), + }; + + self.by_parent.entry((parent_hash, para_id)).or_default().insert(candidate_hash); + + match prev_state { + None => Some(PostConfirmation { + reckoning: Default::default(), + hypothetical: new_confirmed.to_hypothetical(candidate_hash), + }), + Some(CandidateState::Confirmed(_)) => None, + Some(CandidateState::Unconfirmed(u)) => Some({ + let mut reckoning = PostConfirmationReckoning::default(); + + for (leaf_hash, x) in u.unconfirmed_importable_under { + if x.relay_parent == relay_parent && + x.parent_hash == parent_hash && + x.para_id == para_id + { + new_confirmed.importable_under.insert(leaf_hash); + } + } + + for (peer, claims) in u.claims { + // Update the by-parent-hash index not to store any outdated + // claims. + if let Some((claimed_parent_hash, claimed_id)) = claims.parent_hash_and_id { + if claimed_parent_hash != parent_hash || claimed_id != para_id { + if let Entry::Occupied(mut e) = + self.by_parent.entry((claimed_parent_hash, claimed_id)) + { + e.get_mut().remove(&candidate_hash); + if e.get().is_empty() { + e.remove(); + } + } + } + } + + if claims.check(relay_parent, assigned_group, parent_hash, para_id) { + reckoning.correct.insert(peer); + } else { + reckoning.incorrect.insert(peer); + } + } + + PostConfirmation { + reckoning, + hypothetical: new_confirmed.to_hypothetical(candidate_hash), + } + }), + } + } + + /// Whether a candidate is confirmed. + pub fn is_confirmed(&self, candidate_hash: &CandidateHash) -> bool { + match self.candidates.get(candidate_hash) { + Some(CandidateState::Confirmed(_)) => true, + _ => false, + } + } + + /// Get a reference to the candidate, if it's known and confirmed. + pub fn get_confirmed(&self, candidate_hash: &CandidateHash) -> Option<&ConfirmedCandidate> { + match self.candidates.get(candidate_hash) { + Some(CandidateState::Confirmed(ref c)) => Some(c), + _ => None, + } + } + + /// Whether statements from a candidate are importable. + /// + /// This is only true when the candidate is known, confirmed, + /// and is importable in a fragment tree. + pub fn is_importable(&self, candidate_hash: &CandidateHash) -> bool { + self.get_confirmed(candidate_hash).map_or(false, |c| c.is_importable(None)) + } + + /// Note that a candidate is importable in a fragment tree indicated by the given + /// leaf hash. + pub fn note_importable_under(&mut self, candidate: &HypotheticalCandidate, leaf_hash: Hash) { + match candidate { + HypotheticalCandidate::Incomplete { + candidate_hash, + candidate_para, + parent_head_data_hash, + candidate_relay_parent, + } => { + let u = UnconfirmedImportable { + relay_parent: *candidate_relay_parent, + parent_hash: *parent_head_data_hash, + para_id: *candidate_para, + }; + + if let Some(&mut CandidateState::Unconfirmed(ref mut c)) = + self.candidates.get_mut(&candidate_hash) + { + c.note_maybe_importable_under(leaf_hash, u); + } + }, + HypotheticalCandidate::Complete { candidate_hash, .. } => { + if let Some(&mut CandidateState::Confirmed(ref mut c)) = + self.candidates.get_mut(&candidate_hash) + { + c.importable_under.insert(leaf_hash); + } + }, + } + } + + /// Get all hypothetical candidates which should be tested + /// for inclusion in the frontier. + /// + /// Provide optional parent parablock information to filter hypotheticals to only + /// potential children of that parent. + pub fn frontier_hypotheticals( + &self, + parent: Option<(Hash, ParaId)>, + ) -> Vec { + fn extend_hypotheticals<'a>( + v: &mut Vec, + i: impl IntoIterator, + maybe_required_parent: Option<(Hash, ParaId)>, + ) { + for (c_hash, candidate) in i { + match candidate { + CandidateState::Unconfirmed(u) => + u.extend_hypotheticals(*c_hash, v, maybe_required_parent), + CandidateState::Confirmed(c) => v.push(c.to_hypothetical(*c_hash)), + } + } + } + + let mut v = Vec::new(); + if let Some(parent) = parent { + let maybe_children = self.by_parent.get(&parent); + let i = maybe_children + .into_iter() + .flatten() + .filter_map(|c_hash| self.candidates.get_key_value(c_hash)); + + extend_hypotheticals(&mut v, i, Some(parent)); + } else { + extend_hypotheticals(&mut v, self.candidates.iter(), None); + } + v + } + + /// Prune all candidates according to the relay-parent predicate + /// provided. + pub fn on_deactivate_leaves( + &mut self, + leaves: &[Hash], + relay_parent_live: impl Fn(&Hash) -> bool, + ) { + let by_parent = &mut self.by_parent; + let mut remove_parent_claims = |c_hash, parent_hash, id| { + if let Entry::Occupied(mut e) = by_parent.entry((parent_hash, id)) { + e.get_mut().remove(&c_hash); + if e.get().is_empty() { + e.remove(); + } + } + }; + self.candidates.retain(|c_hash, state| match state { + CandidateState::Confirmed(ref mut c) => + if !relay_parent_live(&c.relay_parent()) { + remove_parent_claims(*c_hash, c.parent_head_data_hash(), c.para_id()); + false + } else { + for leaf_hash in leaves { + c.importable_under.remove(leaf_hash); + } + true + }, + CandidateState::Unconfirmed(ref mut c) => { + c.on_deactivate_leaves( + leaves, + |parent_hash, id| remove_parent_claims(*c_hash, parent_hash, id), + &relay_parent_live, + ); + c.has_claims() + }, + }) + } +} + +/// A bad advertisement was recognized. +#[derive(Debug, PartialEq)] +pub struct BadAdvertisement; + +#[derive(Debug, PartialEq)] +enum CandidateState { + Unconfirmed(UnconfirmedCandidate), + Confirmed(ConfirmedCandidate), +} + +/// Claims made alongside the advertisement of a candidate. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +struct CandidateClaims { + /// The relay-parent committed to by the candidate. + relay_parent: Hash, + /// The group index assigned to this candidate. + group_index: GroupIndex, + /// The hash of the parent head-data and the ParaId. This is optional, + /// as only some types of advertisements include this data. + parent_hash_and_id: Option<(Hash, ParaId)>, +} + +impl CandidateClaims { + fn check( + &self, + relay_parent: Hash, + group_index: GroupIndex, + parent_hash: Hash, + para_id: ParaId, + ) -> bool { + self.relay_parent == relay_parent && + self.group_index == group_index && + self.parent_hash_and_id.map_or(true, |p| p == (parent_hash, para_id)) + } +} + +// properties of an unconfirmed but hypothetically importable candidate. +#[derive(Debug, Hash, PartialEq, Eq)] +struct UnconfirmedImportable { + relay_parent: Hash, + parent_hash: Hash, + para_id: ParaId, +} + +// An unconfirmed candidate may have have been advertised under +// multiple identifiers. We track here, on the basis of unique identifier, +// the peers which advertised each candidate in a specific way. +#[derive(Debug, PartialEq)] +struct UnconfirmedCandidate { + claims: Vec<(PeerId, CandidateClaims)>, + // ref-counted + parent_claims: HashMap<(Hash, ParaId), Vec<(Hash, usize)>>, + unconfirmed_importable_under: HashSet<(Hash, UnconfirmedImportable)>, +} + +impl UnconfirmedCandidate { + fn add_claims(&mut self, peer: PeerId, claims: CandidateClaims) { + // This does no deduplication, but this is only called after + // spam prevention is already done. In practice we expect that + // each peer will be able to announce the same candidate about 1 time per live relay-parent, + // but in doing so it limits the amount of other candidates it can advertise. on balance, + // memory consumption is bounded in the same way. + if let Some(parent_claims) = claims.parent_hash_and_id { + let sub_claims = self.parent_claims.entry(parent_claims).or_default(); + match sub_claims.iter().position(|x| x.0 == claims.relay_parent) { + Some(p) => sub_claims[p].1 += 1, + None => sub_claims.push((claims.relay_parent, 1)), + } + } + self.claims.push((peer, claims)); + } + + fn note_maybe_importable_under( + &mut self, + active_leaf: Hash, + unconfirmed_importable: UnconfirmedImportable, + ) { + self.unconfirmed_importable_under.insert((active_leaf, unconfirmed_importable)); + } + + fn on_deactivate_leaves( + &mut self, + leaves: &[Hash], + mut remove_parent_index: impl FnMut(Hash, ParaId), + relay_parent_live: impl Fn(&Hash) -> bool, + ) { + self.claims.retain(|c| { + if relay_parent_live(&c.1.relay_parent) { + true + } else { + if let Some(parent_claims) = c.1.parent_hash_and_id { + if let Entry::Occupied(mut e) = self.parent_claims.entry(parent_claims) { + if let Some(p) = e.get().iter().position(|x| x.0 == c.1.relay_parent) { + let sub_claims = e.get_mut(); + sub_claims[p].1 -= 1; + if sub_claims[p].1 == 0 { + sub_claims.remove(p); + } + }; + + if e.get().is_empty() { + remove_parent_index(parent_claims.0, parent_claims.1); + e.remove(); + } + } + } + + false + } + }); + + self.unconfirmed_importable_under + .retain(|(l, props)| leaves.contains(l) && relay_parent_live(&props.relay_parent)); + } + + fn extend_hypotheticals( + &self, + candidate_hash: CandidateHash, + v: &mut Vec, + required_parent: Option<(Hash, ParaId)>, + ) { + fn extend_hypotheticals_inner<'a>( + candidate_hash: CandidateHash, + v: &mut Vec, + i: impl IntoIterator)>, + ) { + for ((parent_head_hash, para_id), possible_relay_parents) in i { + for (relay_parent, _rc) in possible_relay_parents { + v.push(HypotheticalCandidate::Incomplete { + candidate_hash, + candidate_para: *para_id, + parent_head_data_hash: *parent_head_hash, + candidate_relay_parent: *relay_parent, + }); + } + } + } + + match required_parent { + Some(parent) => extend_hypotheticals_inner( + candidate_hash, + v, + self.parent_claims.get_key_value(&parent), + ), + None => extend_hypotheticals_inner(candidate_hash, v, self.parent_claims.iter()), + } + } + + fn has_claims(&self) -> bool { + !self.claims.is_empty() + } +} + +/// A confirmed candidate. +#[derive(Debug, PartialEq)] +pub struct ConfirmedCandidate { + receipt: Arc, + persisted_validation_data: PersistedValidationData, + assigned_group: GroupIndex, + parent_hash: Hash, + // active leaves statements about this candidate are importable under. + importable_under: HashSet, +} + +impl ConfirmedCandidate { + /// Get the relay-parent of the candidate. + pub fn relay_parent(&self) -> Hash { + self.receipt.descriptor().relay_parent + } + + /// Get the para-id of the candidate. + pub fn para_id(&self) -> ParaId { + self.receipt.descriptor().para_id + } + + /// Get the underlying candidate receipt. + pub fn candidate_receipt(&self) -> &Arc { + &self.receipt + } + + /// Get the persisted validation data. + pub fn persisted_validation_data(&self) -> &PersistedValidationData { + &self.persisted_validation_data + } + + /// Whether the candidate is importable. + pub fn is_importable<'a>(&self, under_active_leaf: impl Into>) -> bool { + match under_active_leaf.into() { + Some(h) => self.importable_under.contains(h), + None => !self.importable_under.is_empty(), + } + } + + /// Get the parent head data hash. + pub fn parent_head_data_hash(&self) -> Hash { + self.parent_hash + } + + /// Get the group index of the assigned group. Note that this is in the context + /// of the state of the chain at the candidate's relay parent and its para-id. + pub fn group_index(&self) -> GroupIndex { + self.assigned_group + } + + fn to_hypothetical(&self, candidate_hash: CandidateHash) -> HypotheticalCandidate { + HypotheticalCandidate::Complete { + candidate_hash, + receipt: self.receipt.clone(), + persisted_validation_data: self.persisted_validation_data.clone(), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use polkadot_primitives::HeadData; + use polkadot_primitives_test_helpers::make_candidate; + + #[test] + fn inserting_unconfirmed_rejects_on_incompatible_claims() { + let relay_head_data_a = HeadData(vec![1, 2, 3]); + let relay_head_data_b = HeadData(vec![4, 5, 6]); + let relay_hash_a = relay_head_data_a.hash(); + let relay_hash_b = relay_head_data_b.hash(); + + let para_id_a = 1.into(); + let para_id_b = 2.into(); + + let (candidate_a, pvd_a) = make_candidate( + relay_hash_a, + 1, + para_id_a, + relay_head_data_a, + HeadData(vec![1]), + Hash::from_low_u64_be(1000).into(), + ); + + let candidate_hash_a = candidate_a.hash(); + + let peer = PeerId::random(); + + let group_index_a = 100.into(); + let group_index_b = 200.into(); + + let mut candidates = Candidates::default(); + + // Confirm a candidate first. + candidates.confirm_candidate(candidate_hash_a, candidate_a, pvd_a, group_index_a); + + // Relay parent does not match. + assert_eq!( + candidates.insert_unconfirmed( + peer, + candidate_hash_a, + relay_hash_b, + group_index_a, + Some((relay_hash_a, para_id_a)), + ), + Err(BadAdvertisement) + ); + + // Group index does not match. + assert_eq!( + candidates.insert_unconfirmed( + peer, + candidate_hash_a, + relay_hash_a, + group_index_b, + Some((relay_hash_a, para_id_a)), + ), + Err(BadAdvertisement) + ); + + // Parent head data does not match. + assert_eq!( + candidates.insert_unconfirmed( + peer, + candidate_hash_a, + relay_hash_a, + group_index_a, + Some((relay_hash_b, para_id_a)), + ), + Err(BadAdvertisement) + ); + + // Para ID does not match. + assert_eq!( + candidates.insert_unconfirmed( + peer, + candidate_hash_a, + relay_hash_a, + group_index_a, + Some((relay_hash_a, para_id_b)), + ), + Err(BadAdvertisement) + ); + + // Everything matches. + assert_eq!( + candidates.insert_unconfirmed( + peer, + candidate_hash_a, + relay_hash_a, + group_index_a, + Some((relay_hash_a, para_id_a)), + ), + Ok(()) + ); + } + + // Tests that: + // + // - When the advertisement matches, confirming does not change the parent hash index. + // - When it doesn't match, confirming updates the index. Specifically, confirming should prune + // unconfirmed claims. + #[test] + fn confirming_maintains_parent_hash_index() { + let relay_head_data = HeadData(vec![1, 2, 3]); + let relay_hash = relay_head_data.hash(); + + let candidate_head_data_a = HeadData(vec![1]); + let candidate_head_data_b = HeadData(vec![2]); + let candidate_head_data_c = HeadData(vec![3]); + let candidate_head_data_d = HeadData(vec![4]); + let candidate_head_data_hash_a = candidate_head_data_a.hash(); + let candidate_head_data_hash_b = candidate_head_data_b.hash(); + let candidate_head_data_hash_c = candidate_head_data_c.hash(); + + let (candidate_a, pvd_a) = make_candidate( + relay_hash, + 1, + 1.into(), + relay_head_data, + candidate_head_data_a.clone(), + Hash::from_low_u64_be(1000).into(), + ); + let (candidate_b, pvd_b) = make_candidate( + relay_hash, + 1, + 1.into(), + candidate_head_data_a, + candidate_head_data_b.clone(), + Hash::from_low_u64_be(2000).into(), + ); + let (candidate_c, _) = make_candidate( + relay_hash, + 1, + 1.into(), + candidate_head_data_b.clone(), + candidate_head_data_c.clone(), + Hash::from_low_u64_be(3000).into(), + ); + let (candidate_d, pvd_d) = make_candidate( + relay_hash, + 1, + 1.into(), + candidate_head_data_c.clone(), + candidate_head_data_d, + Hash::from_low_u64_be(4000).into(), + ); + + let candidate_hash_a = candidate_a.hash(); + let candidate_hash_b = candidate_b.hash(); + let candidate_hash_c = candidate_c.hash(); + let candidate_hash_d = candidate_d.hash(); + + let peer = PeerId::random(); + let group_index = 100.into(); + + let mut candidates = Candidates::default(); + + // Insert some unconfirmed candidates. + + // Advertise A without parent hash. + candidates + .insert_unconfirmed(peer, candidate_hash_a, relay_hash, group_index, None) + .ok() + .unwrap(); + assert_eq!(candidates.by_parent, HashMap::default()); + + // Advertise A with parent hash and ID. + candidates + .insert_unconfirmed( + peer, + candidate_hash_a, + relay_hash, + group_index, + Some((relay_hash, 1.into())), + ) + .ok() + .unwrap(); + assert_eq!( + candidates.by_parent, + HashMap::from([((relay_hash, 1.into()), HashSet::from([candidate_hash_a]))]) + ); + + // Advertise B with parent A. + candidates + .insert_unconfirmed( + peer, + candidate_hash_b, + relay_hash, + group_index, + Some((candidate_head_data_hash_a, 1.into())), + ) + .ok() + .unwrap(); + assert_eq!( + candidates.by_parent, + HashMap::from([ + ((relay_hash, 1.into()), HashSet::from([candidate_hash_a])), + ((candidate_head_data_hash_a, 1.into()), HashSet::from([candidate_hash_b])) + ]) + ); + + // Advertise C with parent A. + candidates + .insert_unconfirmed( + peer, + candidate_hash_c, + relay_hash, + group_index, + Some((candidate_head_data_hash_a, 1.into())), + ) + .ok() + .unwrap(); + assert_eq!( + candidates.by_parent, + HashMap::from([ + ((relay_hash, 1.into()), HashSet::from([candidate_hash_a])), + ( + (candidate_head_data_hash_a, 1.into()), + HashSet::from([candidate_hash_b, candidate_hash_c]) + ) + ]) + ); + + // Advertise D with parent A. + candidates + .insert_unconfirmed( + peer, + candidate_hash_d, + relay_hash, + group_index, + Some((candidate_head_data_hash_a, 1.into())), + ) + .ok() + .unwrap(); + assert_eq!( + candidates.by_parent, + HashMap::from([ + ((relay_hash, 1.into()), HashSet::from([candidate_hash_a])), + ( + (candidate_head_data_hash_a, 1.into()), + HashSet::from([candidate_hash_b, candidate_hash_c, candidate_hash_d]) + ) + ]) + ); + + // Insert confirmed candidates and check parent hash index. + + // Confirmation matches advertisement. Index should be unchanged. + candidates.confirm_candidate(candidate_hash_a, candidate_a, pvd_a, group_index); + assert_eq!( + candidates.by_parent, + HashMap::from([ + ((relay_hash, 1.into()), HashSet::from([candidate_hash_a])), + ( + (candidate_head_data_hash_a, 1.into()), + HashSet::from([candidate_hash_b, candidate_hash_c, candidate_hash_d]) + ) + ]) + ); + candidates.confirm_candidate(candidate_hash_b, candidate_b, pvd_b, group_index); + assert_eq!( + candidates.by_parent, + HashMap::from([ + ((relay_hash, 1.into()), HashSet::from([candidate_hash_a])), + ( + (candidate_head_data_hash_a, 1.into()), + HashSet::from([candidate_hash_b, candidate_hash_c, candidate_hash_d]) + ) + ]) + ); + + // Confirmation does not match advertisement. Index should be updated. + candidates.confirm_candidate(candidate_hash_d, candidate_d, pvd_d, group_index); + assert_eq!( + candidates.by_parent, + HashMap::from([ + ((relay_hash, 1.into()), HashSet::from([candidate_hash_a])), + ( + (candidate_head_data_hash_a, 1.into()), + HashSet::from([candidate_hash_b, candidate_hash_c]) + ), + ((candidate_head_data_hash_c, 1.into()), HashSet::from([candidate_hash_d])) + ]) + ); + + // Make a new candidate for C with a different para ID. + let (new_candidate_c, new_pvd_c) = make_candidate( + relay_hash, + 1, + 2.into(), + candidate_head_data_b, + candidate_head_data_c.clone(), + Hash::from_low_u64_be(3000).into(), + ); + candidates.confirm_candidate(candidate_hash_c, new_candidate_c, new_pvd_c, group_index); + assert_eq!( + candidates.by_parent, + HashMap::from([ + ((relay_hash, 1.into()), HashSet::from([candidate_hash_a])), + ((candidate_head_data_hash_a, 1.into()), HashSet::from([candidate_hash_b])), + ((candidate_head_data_hash_b, 2.into()), HashSet::from([candidate_hash_c])), + ((candidate_head_data_hash_c, 1.into()), HashSet::from([candidate_hash_d])) + ]) + ); + } + + #[test] + fn test_returned_post_confirmation() { + let relay_head_data = HeadData(vec![1, 2, 3]); + let relay_hash = relay_head_data.hash(); + + let candidate_head_data_a = HeadData(vec![1]); + let candidate_head_data_b = HeadData(vec![2]); + let candidate_head_data_c = HeadData(vec![3]); + let candidate_head_data_d = HeadData(vec![4]); + let candidate_head_data_hash_a = candidate_head_data_a.hash(); + let candidate_head_data_hash_b = candidate_head_data_b.hash(); + + let (candidate_a, pvd_a) = make_candidate( + relay_hash, + 1, + 1.into(), + relay_head_data, + candidate_head_data_a.clone(), + Hash::from_low_u64_be(1000).into(), + ); + let (candidate_b, pvd_b) = make_candidate( + relay_hash, + 1, + 1.into(), + candidate_head_data_a.clone(), + candidate_head_data_b.clone(), + Hash::from_low_u64_be(2000).into(), + ); + let (candidate_c, _) = make_candidate( + relay_hash, + 1, + 1.into(), + candidate_head_data_a.clone(), + candidate_head_data_c.clone(), + Hash::from_low_u64_be(3000).into(), + ); + let (candidate_d, pvd_d) = make_candidate( + relay_hash, + 1, + 1.into(), + candidate_head_data_b.clone(), + candidate_head_data_d, + Hash::from_low_u64_be(4000).into(), + ); + + let candidate_hash_a = candidate_a.hash(); + let candidate_hash_b = candidate_b.hash(); + let candidate_hash_c = candidate_c.hash(); + let candidate_hash_d = candidate_d.hash(); + + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + let group_index = 100.into(); + + let mut candidates = Candidates::default(); + + // Insert some unconfirmed candidates. + + // Advertise A without parent hash. + candidates + .insert_unconfirmed(peer_a, candidate_hash_a, relay_hash, group_index, None) + .ok() + .unwrap(); + + // Advertise A with parent hash and ID. + candidates + .insert_unconfirmed( + peer_a, + candidate_hash_a, + relay_hash, + group_index, + Some((relay_hash, 1.into())), + ) + .ok() + .unwrap(); + + // (Correctly) advertise B with parent A. Do it from a couple of peers. + candidates + .insert_unconfirmed( + peer_a, + candidate_hash_b, + relay_hash, + group_index, + Some((candidate_head_data_hash_a, 1.into())), + ) + .ok() + .unwrap(); + candidates + .insert_unconfirmed( + peer_b, + candidate_hash_b, + relay_hash, + group_index, + Some((candidate_head_data_hash_a, 1.into())), + ) + .ok() + .unwrap(); + + // (Wrongly) advertise C with parent A. Do it from a couple peers. + candidates + .insert_unconfirmed( + peer_b, + candidate_hash_c, + relay_hash, + group_index, + Some((candidate_head_data_hash_a, 1.into())), + ) + .ok() + .unwrap(); + candidates + .insert_unconfirmed( + peer_c, + candidate_hash_c, + relay_hash, + group_index, + Some((candidate_head_data_hash_a, 1.into())), + ) + .ok() + .unwrap(); + + // Advertise D. Do it correctly from one peer (parent B) and wrongly from another (parent + // A). + candidates + .insert_unconfirmed( + peer_c, + candidate_hash_d, + relay_hash, + group_index, + Some((candidate_head_data_hash_b, 1.into())), + ) + .ok() + .unwrap(); + candidates + .insert_unconfirmed( + peer_d, + candidate_hash_d, + relay_hash, + group_index, + Some((candidate_head_data_hash_a, 1.into())), + ) + .ok() + .unwrap(); + + assert_eq!( + candidates.by_parent, + HashMap::from([ + ((relay_hash, 1.into()), HashSet::from([candidate_hash_a])), + ( + (candidate_head_data_hash_a, 1.into()), + HashSet::from([candidate_hash_b, candidate_hash_c, candidate_hash_d]) + ), + ((candidate_head_data_hash_b, 1.into()), HashSet::from([candidate_hash_d])) + ]) + ); + + // Insert confirmed candidates and check parent hash index. + + // Confirmation matches advertisement. + let post_confirmation = candidates.confirm_candidate( + candidate_hash_a, + candidate_a.clone(), + pvd_a.clone(), + group_index, + ); + assert_eq!( + post_confirmation, + Some(PostConfirmation { + hypothetical: HypotheticalCandidate::Complete { + candidate_hash: candidate_hash_a, + receipt: Arc::new(candidate_a), + persisted_validation_data: pvd_a, + }, + reckoning: PostConfirmationReckoning { + correct: HashSet::from([peer_a]), + incorrect: HashSet::from([]), + }, + }) + ); + + let post_confirmation = candidates.confirm_candidate( + candidate_hash_b, + candidate_b.clone(), + pvd_b.clone(), + group_index, + ); + assert_eq!( + post_confirmation, + Some(PostConfirmation { + hypothetical: HypotheticalCandidate::Complete { + candidate_hash: candidate_hash_b, + receipt: Arc::new(candidate_b), + persisted_validation_data: pvd_b, + }, + reckoning: PostConfirmationReckoning { + correct: HashSet::from([peer_a, peer_b]), + incorrect: HashSet::from([]), + }, + }) + ); + + // Confirm candidate with two wrong peers (different group index). + let (new_candidate_c, new_pvd_c) = make_candidate( + relay_hash, + 1, + 2.into(), + candidate_head_data_b, + candidate_head_data_c.clone(), + Hash::from_low_u64_be(3000).into(), + ); + let post_confirmation = candidates.confirm_candidate( + candidate_hash_c, + new_candidate_c.clone(), + new_pvd_c.clone(), + group_index, + ); + assert_eq!( + post_confirmation, + Some(PostConfirmation { + hypothetical: HypotheticalCandidate::Complete { + candidate_hash: candidate_hash_c, + receipt: Arc::new(new_candidate_c), + persisted_validation_data: new_pvd_c, + }, + reckoning: PostConfirmationReckoning { + correct: HashSet::from([]), + incorrect: HashSet::from([peer_b, peer_c]), + }, + }) + ); + + // Confirm candidate with one wrong peer (different parent head data). + let post_confirmation = candidates.confirm_candidate( + candidate_hash_d, + candidate_d.clone(), + pvd_d.clone(), + group_index, + ); + assert_eq!( + post_confirmation, + Some(PostConfirmation { + hypothetical: HypotheticalCandidate::Complete { + candidate_hash: candidate_hash_d, + receipt: Arc::new(candidate_d), + persisted_validation_data: pvd_d, + }, + reckoning: PostConfirmationReckoning { + correct: HashSet::from([peer_c]), + incorrect: HashSet::from([peer_d]), + }, + }) + ); + } + + #[test] + fn test_hypothetical_frontiers() { + let relay_head_data = HeadData(vec![1, 2, 3]); + let relay_hash = relay_head_data.hash(); + + let candidate_head_data_a = HeadData(vec![1]); + let candidate_head_data_b = HeadData(vec![2]); + let candidate_head_data_c = HeadData(vec![3]); + let candidate_head_data_d = HeadData(vec![4]); + let candidate_head_data_hash_a = candidate_head_data_a.hash(); + let candidate_head_data_hash_b = candidate_head_data_b.hash(); + let candidate_head_data_hash_d = candidate_head_data_d.hash(); + + let (candidate_a, pvd_a) = make_candidate( + relay_hash, + 1, + 1.into(), + relay_head_data, + candidate_head_data_a.clone(), + Hash::from_low_u64_be(1000).into(), + ); + let (candidate_b, _) = make_candidate( + relay_hash, + 1, + 1.into(), + candidate_head_data_a.clone(), + candidate_head_data_b.clone(), + Hash::from_low_u64_be(2000).into(), + ); + let (candidate_c, _) = make_candidate( + relay_hash, + 1, + 1.into(), + candidate_head_data_a.clone(), + candidate_head_data_c.clone(), + Hash::from_low_u64_be(3000).into(), + ); + let (candidate_d, _) = make_candidate( + relay_hash, + 1, + 1.into(), + candidate_head_data_b.clone(), + candidate_head_data_d, + Hash::from_low_u64_be(4000).into(), + ); + + let candidate_hash_a = candidate_a.hash(); + let candidate_hash_b = candidate_b.hash(); + let candidate_hash_c = candidate_c.hash(); + let candidate_hash_d = candidate_d.hash(); + + let peer = PeerId::random(); + let group_index = 100.into(); + + let mut candidates = Candidates::default(); + + // Confirm A. + candidates.confirm_candidate( + candidate_hash_a, + candidate_a.clone(), + pvd_a.clone(), + group_index, + ); + + // Advertise B with parent A. + candidates + .insert_unconfirmed( + peer, + candidate_hash_b, + relay_hash, + group_index, + Some((candidate_head_data_hash_a, 1.into())), + ) + .ok() + .unwrap(); + + // Advertise C with parent A. + candidates + .insert_unconfirmed( + peer, + candidate_hash_c, + relay_hash, + group_index, + Some((candidate_head_data_hash_a, 1.into())), + ) + .ok() + .unwrap(); + + // Advertise D with parent B. + candidates + .insert_unconfirmed( + peer, + candidate_hash_d, + relay_hash, + group_index, + Some((candidate_head_data_hash_b, 1.into())), + ) + .ok() + .unwrap(); + + assert_eq!( + candidates.by_parent, + HashMap::from([ + ((relay_hash, 1.into()), HashSet::from([candidate_hash_a])), + ( + (candidate_head_data_hash_a, 1.into()), + HashSet::from([candidate_hash_b, candidate_hash_c]) + ), + ((candidate_head_data_hash_b, 1.into()), HashSet::from([candidate_hash_d])) + ]) + ); + + let hypothetical_a = HypotheticalCandidate::Complete { + candidate_hash: candidate_hash_a, + receipt: Arc::new(candidate_a), + persisted_validation_data: pvd_a, + }; + let hypothetical_b = HypotheticalCandidate::Incomplete { + candidate_hash: candidate_hash_b, + candidate_para: 1.into(), + parent_head_data_hash: candidate_head_data_hash_a, + candidate_relay_parent: relay_hash, + }; + let hypothetical_c = HypotheticalCandidate::Incomplete { + candidate_hash: candidate_hash_c, + candidate_para: 1.into(), + parent_head_data_hash: candidate_head_data_hash_a, + candidate_relay_parent: relay_hash, + }; + let hypothetical_d = HypotheticalCandidate::Incomplete { + candidate_hash: candidate_hash_d, + candidate_para: 1.into(), + parent_head_data_hash: candidate_head_data_hash_b, + candidate_relay_parent: relay_hash, + }; + + let hypotheticals = candidates.frontier_hypotheticals(Some((relay_hash, 1.into()))); + assert_eq!(hypotheticals.len(), 1); + assert!(hypotheticals.contains(&hypothetical_a)); + + let hypotheticals = + candidates.frontier_hypotheticals(Some((candidate_head_data_hash_a, 2.into()))); + assert_eq!(hypotheticals.len(), 0); + + let hypotheticals = + candidates.frontier_hypotheticals(Some((candidate_head_data_hash_a, 1.into()))); + assert_eq!(hypotheticals.len(), 2); + assert!(hypotheticals.contains(&hypothetical_b)); + assert!(hypotheticals.contains(&hypothetical_c)); + + let hypotheticals = + candidates.frontier_hypotheticals(Some((candidate_head_data_hash_d, 1.into()))); + assert_eq!(hypotheticals.len(), 0); + + let hypotheticals = candidates.frontier_hypotheticals(None); + assert_eq!(hypotheticals.len(), 4); + assert!(hypotheticals.contains(&hypothetical_a)); + assert!(hypotheticals.contains(&hypothetical_b)); + assert!(hypotheticals.contains(&hypothetical_c)); + assert!(hypotheticals.contains(&hypothetical_d)); + } +} diff --git a/polkadot/node/network/statement-distribution/src/vstaging/cluster.rs b/polkadot/node/network/statement-distribution/src/vstaging/cluster.rs new file mode 100644 index 0000000000000000000000000000000000000000..3214507407aa5bacb78f16cbc244ed59ac10241c --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/vstaging/cluster.rs @@ -0,0 +1,1203 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Direct distribution of statements within a cluster, +//! even those concerning candidates which are not yet backed. +//! +//! Members of a validation group assigned to a para at a given relay-parent +//! always distribute statements directly to each other. +//! +//! The main way we limit the amount of candidates that have to be handled by +//! the system is to limit the amount of `Seconded` messages that we allow +//! each validator to issue at each relay-parent. Since the amount of relay-parents +//! that we have to deal with at any time is itself bounded, this lets us bound +//! the memory and work that we have here. Bounding `Seconded` statements is enough +//! because they imply a bounded amount of `Valid` statements about the same candidate +//! which may follow. +//! +//! The motivation for this piece of code is that the statements that each validator +//! sees may differ. i.e. even though a validator is allowed to issue X `Seconded` +//! statements at a relay-parent, they may in fact issue X*2 and issue one set to +//! one partition of the backing group and one set to another. Of course, in practice +//! these types of partitions will not exist, but in the worst case each validator in the +//! group would see an entirely different set of X `Seconded` statements from some validator +//! and each validator is in its own partition. After that partition resolves, we'd have to +//! deal with up to `limit*group_size` `Seconded` statements from that validator. And then +//! if every validator in the group does the same thing, we're dealing with something like +//! `limit*group_size^2` `Seconded` statements in total. +//! +//! Given that both our group sizes and our limits per relay-parent are small, this is +//! quite manageable, and the utility here lets us deal with it in only a few kilobytes +//! of memory. +//! +//! It's also worth noting that any case where a validator issues more than the legal limit +//! of `Seconded` statements at a relay parent is trivially slashable on-chain, which means +//! the 'worst case' adversary that this code defends against is effectively lighting money +//! on fire. Nevertheless, we handle the case here to ensure that the behavior of the +//! system is well-defined even if an adversary is willing to be slashed. +//! +//! More concretely, this module exposes a [`ClusterTracker`] utility which allows us to determine +//! whether to accept or reject messages from other validators in the same group as we +//! are in, based on _the most charitable possible interpretation of our protocol rules_, +//! and to keep track of what we have sent to other validators in the group and what we may +//! continue to send them. + +use polkadot_primitives::vstaging::{CandidateHash, CompactStatement, ValidatorIndex}; + +use std::collections::{HashMap, HashSet}; + +#[derive(Hash, PartialEq, Eq)] +struct ValidStatementManifest { + remote: ValidatorIndex, + originator: ValidatorIndex, + candidate_hash: CandidateHash, +} + +// A piece of knowledge about a candidate +#[derive(Hash, Clone, PartialEq, Eq)] +enum Knowledge { + // General knowledge. + General(CandidateHash), + // Specific knowledge of a given statement (with its originator) + Specific(CompactStatement, ValidatorIndex), +} + +// Knowledge paired with its source. +#[derive(Hash, Clone, PartialEq, Eq)] +enum TaggedKnowledge { + // Knowledge we have received from the validator on the p2p layer. + IncomingP2P(Knowledge), + // Knowledge we have sent to the validator on the p2p layer. + OutgoingP2P(Knowledge), + // Knowledge of candidates the validator has seconded. + // This is limited only to `Seconded` statements we have accepted + // _without prejudice_. + Seconded(CandidateHash), +} + +/// Utility for keeping track of limits on direct statements within a group. +/// +/// See module docs for more details. +pub struct ClusterTracker { + validators: Vec, + seconding_limit: usize, + knowledge: HashMap>, + // Statements known locally which haven't been sent to particular validators. + // maps target validator to (originator, statement) pairs. + pending: HashMap>, +} + +impl ClusterTracker { + /// Instantiate a new `ClusterTracker` tracker. Fails if `cluster_validators` is empty + pub fn new(cluster_validators: Vec, seconding_limit: usize) -> Option { + if cluster_validators.is_empty() { + return None + } + Some(ClusterTracker { + validators: cluster_validators, + seconding_limit, + knowledge: HashMap::new(), + pending: HashMap::new(), + }) + } + + /// Query whether we can receive some statement from the given validator. + /// + /// This does no deduplication of `Valid` statements. + pub fn can_receive( + &self, + sender: ValidatorIndex, + originator: ValidatorIndex, + statement: CompactStatement, + ) -> Result { + if !self.is_in_group(sender) || !self.is_in_group(originator) { + return Err(RejectIncoming::NotInGroup) + } + + if self.they_sent(sender, Knowledge::Specific(statement.clone(), originator)) { + return Err(RejectIncoming::Duplicate) + } + + match statement { + CompactStatement::Seconded(candidate_hash) => { + // check whether the sender has not sent too many seconded statements for the + // originator. we know by the duplicate check above that this iterator doesn't + // include the statement itself. + let other_seconded_for_orig_from_remote = self + .knowledge + .get(&sender) + .into_iter() + .flat_map(|v_knowledge| v_knowledge.iter()) + .filter(|k| match k { + TaggedKnowledge::IncomingP2P(Knowledge::Specific( + CompactStatement::Seconded(_), + orig, + )) if orig == &originator => true, + _ => false, + }) + .count(); + + if other_seconded_for_orig_from_remote == self.seconding_limit { + return Err(RejectIncoming::ExcessiveSeconded) + } + + // at this point, it doesn't seem like the remote has done anything wrong. + if self.seconded_already_or_within_limit(originator, candidate_hash) { + Ok(Accept::Ok) + } else { + Ok(Accept::WithPrejudice) + } + }, + CompactStatement::Valid(candidate_hash) => { + if !self.knows_candidate(sender, candidate_hash) { + return Err(RejectIncoming::CandidateUnknown) + } + + Ok(Accept::Ok) + }, + } + } + + /// Note that we issued a statement. This updates internal structures. + pub fn note_issued(&mut self, originator: ValidatorIndex, statement: CompactStatement) { + for cluster_member in &self.validators { + if !self.they_know_statement(*cluster_member, originator, statement.clone()) { + // add the statement to pending knowledge for all peers + // which don't know the statement. + self.pending + .entry(*cluster_member) + .or_default() + .insert((originator, statement.clone())); + } + } + } + + /// Note that we accepted an incoming statement. This updates internal structures. + /// + /// Should only be called after a successful `can_receive` call. + pub fn note_received( + &mut self, + sender: ValidatorIndex, + originator: ValidatorIndex, + statement: CompactStatement, + ) { + for cluster_member in &self.validators { + if cluster_member == &sender { + if let Some(pending) = self.pending.get_mut(&sender) { + pending.remove(&(originator, statement.clone())); + } + } else if !self.they_know_statement(*cluster_member, originator, statement.clone()) { + // add the statement to pending knowledge for all peers + // which don't know the statement. + self.pending + .entry(*cluster_member) + .or_default() + .insert((originator, statement.clone())); + } + } + + { + let sender_knowledge = self.knowledge.entry(sender).or_default(); + sender_knowledge.insert(TaggedKnowledge::IncomingP2P(Knowledge::Specific( + statement.clone(), + originator, + ))); + + if let CompactStatement::Seconded(candidate_hash) = statement.clone() { + sender_knowledge + .insert(TaggedKnowledge::IncomingP2P(Knowledge::General(candidate_hash))); + } + } + + if let CompactStatement::Seconded(candidate_hash) = statement { + // since we accept additional `Seconded` statements beyond the limits + // 'with prejudice', we must respect the limit here. + if self.seconded_already_or_within_limit(originator, candidate_hash) { + let originator_knowledge = self.knowledge.entry(originator).or_default(); + originator_knowledge.insert(TaggedKnowledge::Seconded(candidate_hash)); + } + } + } + + /// Query whether we can send a statement to a given validator. + pub fn can_send( + &self, + target: ValidatorIndex, + originator: ValidatorIndex, + statement: CompactStatement, + ) -> Result<(), RejectOutgoing> { + if !self.is_in_group(target) || !self.is_in_group(originator) { + return Err(RejectOutgoing::NotInGroup) + } + + if self.they_know_statement(target, originator, statement.clone()) { + return Err(RejectOutgoing::Known) + } + + match statement { + CompactStatement::Seconded(candidate_hash) => { + // we send the same `Seconded` statements to all our peers, and only the first `k` + // from each originator. + if !self.seconded_already_or_within_limit(originator, candidate_hash) { + return Err(RejectOutgoing::ExcessiveSeconded) + } + + Ok(()) + }, + CompactStatement::Valid(candidate_hash) => { + if !self.knows_candidate(target, candidate_hash) { + return Err(RejectOutgoing::CandidateUnknown) + } + + Ok(()) + }, + } + } + + /// Note that we sent an outgoing statement to a peer in the group. + /// This must be preceded by a successful `can_send` call. + pub fn note_sent( + &mut self, + target: ValidatorIndex, + originator: ValidatorIndex, + statement: CompactStatement, + ) { + { + let target_knowledge = self.knowledge.entry(target).or_default(); + target_knowledge.insert(TaggedKnowledge::OutgoingP2P(Knowledge::Specific( + statement.clone(), + originator, + ))); + + if let CompactStatement::Seconded(candidate_hash) = statement.clone() { + target_knowledge + .insert(TaggedKnowledge::OutgoingP2P(Knowledge::General(candidate_hash))); + } + } + + if let CompactStatement::Seconded(candidate_hash) = statement { + let originator_knowledge = self.knowledge.entry(originator).or_default(); + originator_knowledge.insert(TaggedKnowledge::Seconded(candidate_hash)); + } + + if let Some(pending) = self.pending.get_mut(&target) { + pending.remove(&(originator, statement)); + } + } + + /// Get all targets as validator-indices. This doesn't attempt to filter + /// out the local validator index. + pub fn targets(&self) -> &[ValidatorIndex] { + &self.validators + } + + /// Get all possible senders for the given originator. + /// Returns the empty slice in the case that the originator + /// is not part of the cluster. + // note: this API is future-proofing for a case where we may + // extend clusters beyond just the assigned group, for optimization + // purposes. + pub fn senders_for_originator(&self, originator: ValidatorIndex) -> &[ValidatorIndex] { + if self.validators.contains(&originator) { + &self.validators[..] + } else { + &[] + } + } + + /// Whether a validator knows the candidate is `Seconded`. + pub fn knows_candidate( + &self, + validator: ValidatorIndex, + candidate_hash: CandidateHash, + ) -> bool { + // we sent, they sent, or they signed and we received from someone else. + + self.we_sent_seconded(validator, candidate_hash) || + self.they_sent_seconded(validator, candidate_hash) || + self.validator_seconded(validator, candidate_hash) + } + + /// Returns a Vec of pending statements to be sent to a particular validator + /// index. `Seconded` statements are sorted to the front of the vector. + /// + /// Pending statements have the form (originator, compact statement). + pub fn pending_statements_for( + &self, + target: ValidatorIndex, + ) -> Vec<(ValidatorIndex, CompactStatement)> { + let mut v = self + .pending + .get(&target) + .map(|x| x.iter().cloned().collect::>()) + .unwrap_or_default(); + + v.sort_by_key(|(_, s)| match s { + CompactStatement::Seconded(_) => 0u8, + CompactStatement::Valid(_) => 1u8, + }); + + v + } + + // returns true if it's legal to accept a new `Seconded` message from this validator. + // This is either + // 1. because we've already accepted it. + // 2. because there's space for more seconding. + fn seconded_already_or_within_limit( + &self, + validator: ValidatorIndex, + candidate_hash: CandidateHash, + ) -> bool { + let seconded_other_candidates = self + .knowledge + .get(&validator) + .into_iter() + .flat_map(|v_knowledge| v_knowledge.iter()) + .filter(|k| match k { + TaggedKnowledge::Seconded(c) if c != &candidate_hash => true, + _ => false, + }) + .count(); + + // This fulfills both properties by under-counting when the validator is at the limit + // but _has_ seconded the candidate already. + seconded_other_candidates < self.seconding_limit + } + + fn they_know_statement( + &self, + validator: ValidatorIndex, + originator: ValidatorIndex, + statement: CompactStatement, + ) -> bool { + let knowledge = Knowledge::Specific(statement, originator); + self.we_sent(validator, knowledge.clone()) || self.they_sent(validator, knowledge) + } + + fn they_sent(&self, validator: ValidatorIndex, knowledge: Knowledge) -> bool { + self.knowledge + .get(&validator) + .map_or(false, |k| k.contains(&TaggedKnowledge::IncomingP2P(knowledge))) + } + + fn we_sent(&self, validator: ValidatorIndex, knowledge: Knowledge) -> bool { + self.knowledge + .get(&validator) + .map_or(false, |k| k.contains(&TaggedKnowledge::OutgoingP2P(knowledge))) + } + + fn we_sent_seconded(&self, validator: ValidatorIndex, candidate_hash: CandidateHash) -> bool { + self.we_sent(validator, Knowledge::General(candidate_hash)) + } + + fn they_sent_seconded(&self, validator: ValidatorIndex, candidate_hash: CandidateHash) -> bool { + self.they_sent(validator, Knowledge::General(candidate_hash)) + } + + fn validator_seconded(&self, validator: ValidatorIndex, candidate_hash: CandidateHash) -> bool { + self.knowledge + .get(&validator) + .map_or(false, |k| k.contains(&TaggedKnowledge::Seconded(candidate_hash))) + } + + fn is_in_group(&self, validator: ValidatorIndex) -> bool { + self.validators.contains(&validator) + } +} + +/// Incoming statement was accepted. +#[derive(Debug, PartialEq)] +pub enum Accept { + /// Neither the peer nor the originator have apparently exceeded limits. + /// Candidate or statement may already be known. + Ok, + /// Accept the message; the peer hasn't exceeded limits but the originator has. + WithPrejudice, +} + +/// Incoming statement was rejected. +#[derive(Debug, PartialEq)] +pub enum RejectIncoming { + /// Peer sent excessive `Seconded` statements. + ExcessiveSeconded, + /// Sender or originator is not in the group. + NotInGroup, + /// Candidate is unknown to us. Only applies to `Valid` statements. + CandidateUnknown, + /// Statement is duplicate. + Duplicate, +} + +/// Outgoing statement was rejected. +#[derive(Debug, PartialEq)] +pub enum RejectOutgoing { + /// Candidate was unknown. Only applies to `Valid` statements. + CandidateUnknown, + /// We attempted to send excessive `Seconded` statements. + /// indicates a bug on the local node's code. + ExcessiveSeconded, + /// The statement was already known to the peer. + Known, + /// Target or originator not in the group. + NotInGroup, +} + +#[cfg(test)] +mod tests { + use super::*; + use polkadot_primitives::vstaging::Hash; + + #[test] + fn rejects_incoming_outside_of_group() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 2; + + let tracker = ClusterTracker::new(group.clone(), seconding_limit).expect("not empty"); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(100), + ValidatorIndex(5), + CompactStatement::Seconded(CandidateHash(Hash::repeat_byte(1))), + ), + Err(RejectIncoming::NotInGroup), + ); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(100), + CompactStatement::Seconded(CandidateHash(Hash::repeat_byte(1))), + ), + Err(RejectIncoming::NotInGroup), + ); + } + + #[test] + fn begrudgingly_accepts_too_many_seconded_from_multiple_peers() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 2; + let hash_a = CandidateHash(Hash::repeat_byte(1)); + let hash_b = CandidateHash(Hash::repeat_byte(2)); + let hash_c = CandidateHash(Hash::repeat_byte(3)); + + let mut tracker = ClusterTracker::new(group.clone(), seconding_limit).expect("not empty"); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ), + Ok(Accept::Ok), + ); + tracker.note_received( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_b), + ), + Ok(Accept::Ok), + ); + tracker.note_received( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_b), + ); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_c), + ), + Err(RejectIncoming::ExcessiveSeconded), + ); + } + + #[test] + fn rejects_too_many_seconded_from_sender() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 2; + let hash_a = CandidateHash(Hash::repeat_byte(1)); + let hash_b = CandidateHash(Hash::repeat_byte(2)); + let hash_c = CandidateHash(Hash::repeat_byte(3)); + + let mut tracker = ClusterTracker::new(group.clone(), seconding_limit).expect("not empty"); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ), + Ok(Accept::Ok), + ); + tracker.note_received( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_b), + ), + Ok(Accept::Ok), + ); + tracker.note_received( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_b), + ); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_c), + ), + Ok(Accept::WithPrejudice), + ); + } + + #[test] + fn rejects_duplicates() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 2; + let hash_a = CandidateHash(Hash::repeat_byte(1)); + + let mut tracker = ClusterTracker::new(group, seconding_limit).expect("not empty"); + + tracker.note_received( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ); + + tracker.note_received( + ValidatorIndex(5), + ValidatorIndex(200), + CompactStatement::Valid(hash_a), + ); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ), + Err(RejectIncoming::Duplicate), + ); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(200), + CompactStatement::Valid(hash_a), + ), + Err(RejectIncoming::Duplicate), + ); + } + + #[test] + fn rejects_incoming_valid_without_seconded() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 2; + + let tracker = ClusterTracker::new(group, seconding_limit).expect("not empty"); + + let hash_a = CandidateHash(Hash::repeat_byte(1)); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Valid(hash_a), + ), + Err(RejectIncoming::CandidateUnknown), + ); + } + + #[test] + fn accepts_incoming_valid_after_receiving_seconded() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 2; + + let mut tracker = ClusterTracker::new(group.clone(), seconding_limit).expect("not empty"); + let hash_a = CandidateHash(Hash::repeat_byte(1)); + + tracker.note_received( + ValidatorIndex(5), + ValidatorIndex(200), + CompactStatement::Seconded(hash_a), + ); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Valid(hash_a), + ), + Ok(Accept::Ok) + ); + } + + #[test] + fn accepts_incoming_valid_after_outgoing_seconded() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 2; + + let mut tracker = ClusterTracker::new(group.clone(), seconding_limit).expect("not empty"); + let hash_a = CandidateHash(Hash::repeat_byte(1)); + + tracker.note_sent( + ValidatorIndex(5), + ValidatorIndex(200), + CompactStatement::Seconded(hash_a), + ); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Valid(hash_a), + ), + Ok(Accept::Ok) + ); + } + + #[test] + fn cannot_send_too_many_seconded_even_to_multiple_peers() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 2; + + let mut tracker = ClusterTracker::new(group.clone(), seconding_limit).expect("not empty"); + let hash_a = CandidateHash(Hash::repeat_byte(1)); + let hash_b = CandidateHash(Hash::repeat_byte(2)); + let hash_c = CandidateHash(Hash::repeat_byte(3)); + + tracker.note_sent( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ); + + tracker.note_sent( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_b), + ); + + assert_eq!( + tracker.can_send( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_c), + ), + Err(RejectOutgoing::ExcessiveSeconded), + ); + + assert_eq!( + tracker.can_send( + ValidatorIndex(24), + ValidatorIndex(5), + CompactStatement::Seconded(hash_c), + ), + Err(RejectOutgoing::ExcessiveSeconded), + ); + } + + #[test] + fn cannot_send_duplicate() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 2; + + let mut tracker = ClusterTracker::new(group.clone(), seconding_limit).expect("not empty"); + let hash_a = CandidateHash(Hash::repeat_byte(1)); + + tracker.note_sent( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ); + + assert_eq!( + tracker.can_send( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ), + Err(RejectOutgoing::Known), + ); + } + + #[test] + fn cannot_send_what_was_received() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 2; + + let mut tracker = ClusterTracker::new(group.clone(), seconding_limit).expect("not empty"); + let hash_a = CandidateHash(Hash::repeat_byte(1)); + + tracker.note_received( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ); + + assert_eq!( + tracker.can_send( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ), + Err(RejectOutgoing::Known), + ); + } + + // Ensure statements received with prejudice don't prevent sending later. + #[test] + fn can_send_statements_received_with_prejudice() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 1; + + let mut tracker = ClusterTracker::new(group.clone(), seconding_limit).expect("not empty"); + let hash_a = CandidateHash(Hash::repeat_byte(1)); + let hash_b = CandidateHash(Hash::repeat_byte(2)); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ), + Ok(Accept::Ok), + ); + + tracker.note_received( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ); + + assert_eq!( + tracker.can_receive( + ValidatorIndex(24), + ValidatorIndex(5), + CompactStatement::Seconded(hash_b), + ), + Ok(Accept::WithPrejudice), + ); + + tracker.note_received( + ValidatorIndex(24), + ValidatorIndex(5), + CompactStatement::Seconded(hash_b), + ); + + assert_eq!( + tracker.can_send( + ValidatorIndex(24), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ), + Ok(()), + ); + } + + // Test that the `pending_statements` are set whenever we receive a fresh statement. + // + // Also test that pending statements are sorted, with `Seconded` statements in the front. + #[test] + fn pending_statements_set_when_receiving_fresh_statements() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 1; + + let mut tracker = ClusterTracker::new(group.clone(), seconding_limit).expect("not empty"); + let hash_a = CandidateHash(Hash::repeat_byte(1)); + let hash_b = CandidateHash(Hash::repeat_byte(2)); + + // Receive a 'Seconded' statement for candidate A. + { + assert_eq!( + tracker.can_receive( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ), + Ok(Accept::Ok), + ); + tracker.note_received( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ); + + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(5)), + vec![(ValidatorIndex(5), CompactStatement::Seconded(hash_a))] + ); + assert_eq!(tracker.pending_statements_for(ValidatorIndex(200)), vec![]); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(24)), + vec![(ValidatorIndex(5), CompactStatement::Seconded(hash_a))] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(146)), + vec![(ValidatorIndex(5), CompactStatement::Seconded(hash_a))] + ); + } + + // Receive a 'Valid' statement for candidate A. + { + // First, send a `Seconded` statement for the candidate. + assert_eq!( + tracker.can_send( + ValidatorIndex(24), + ValidatorIndex(200), + CompactStatement::Seconded(hash_a) + ), + Ok(()) + ); + tracker.note_sent( + ValidatorIndex(24), + ValidatorIndex(200), + CompactStatement::Seconded(hash_a), + ); + + // We have to see that the candidate is known by the sender, e.g. we sent them + // 'Seconded' above. + assert_eq!( + tracker.can_receive( + ValidatorIndex(24), + ValidatorIndex(200), + CompactStatement::Valid(hash_a), + ), + Ok(Accept::Ok), + ); + tracker.note_received( + ValidatorIndex(24), + ValidatorIndex(200), + CompactStatement::Valid(hash_a), + ); + + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(5)), + vec![ + (ValidatorIndex(5), CompactStatement::Seconded(hash_a)), + (ValidatorIndex(200), CompactStatement::Valid(hash_a)) + ] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(200)), + vec![(ValidatorIndex(200), CompactStatement::Valid(hash_a))] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(24)), + vec![(ValidatorIndex(5), CompactStatement::Seconded(hash_a))] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(146)), + vec![ + (ValidatorIndex(5), CompactStatement::Seconded(hash_a)), + (ValidatorIndex(200), CompactStatement::Valid(hash_a)) + ] + ); + } + + // Receive a 'Seconded' statement for candidate B. + { + assert_eq!( + tracker.can_receive( + ValidatorIndex(5), + ValidatorIndex(146), + CompactStatement::Seconded(hash_b), + ), + Ok(Accept::Ok), + ); + tracker.note_received( + ValidatorIndex(5), + ValidatorIndex(146), + CompactStatement::Seconded(hash_b), + ); + + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(5)), + vec![ + (ValidatorIndex(5), CompactStatement::Seconded(hash_a)), + (ValidatorIndex(200), CompactStatement::Valid(hash_a)) + ] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(200)), + vec![ + (ValidatorIndex(146), CompactStatement::Seconded(hash_b)), + (ValidatorIndex(200), CompactStatement::Valid(hash_a)), + ] + ); + { + let mut pending_statements = tracker.pending_statements_for(ValidatorIndex(24)); + pending_statements.sort(); + assert_eq!( + pending_statements, + vec![ + (ValidatorIndex(5), CompactStatement::Seconded(hash_a)), + (ValidatorIndex(146), CompactStatement::Seconded(hash_b)) + ], + ); + } + { + let mut pending_statements = tracker.pending_statements_for(ValidatorIndex(146)); + pending_statements.sort(); + assert_eq!( + pending_statements, + vec![ + (ValidatorIndex(5), CompactStatement::Seconded(hash_a)), + (ValidatorIndex(146), CompactStatement::Seconded(hash_b)), + (ValidatorIndex(200), CompactStatement::Valid(hash_a)), + ] + ); + } + } + } + + // Test that the `pending_statements` are updated when we send or receive statements from others + // in the cluster. + #[test] + fn pending_statements_updated_when_sending_statements() { + let group = + vec![ValidatorIndex(5), ValidatorIndex(200), ValidatorIndex(24), ValidatorIndex(146)]; + + let seconding_limit = 1; + + let mut tracker = ClusterTracker::new(group.clone(), seconding_limit).expect("not empty"); + let hash_a = CandidateHash(Hash::repeat_byte(1)); + let hash_b = CandidateHash(Hash::repeat_byte(2)); + + // Receive a 'Seconded' statement for candidate A. + { + assert_eq!( + tracker.can_receive( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ), + Ok(Accept::Ok), + ); + tracker.note_received( + ValidatorIndex(200), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ); + + // Pending statements should be updated. + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(5)), + vec![(ValidatorIndex(5), CompactStatement::Seconded(hash_a))] + ); + assert_eq!(tracker.pending_statements_for(ValidatorIndex(200)), vec![]); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(24)), + vec![(ValidatorIndex(5), CompactStatement::Seconded(hash_a))] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(146)), + vec![(ValidatorIndex(5), CompactStatement::Seconded(hash_a))] + ); + } + + // Receive a 'Valid' statement for candidate B. + { + // First, send a `Seconded` statement for the candidate. + assert_eq!( + tracker.can_send( + ValidatorIndex(24), + ValidatorIndex(200), + CompactStatement::Seconded(hash_b) + ), + Ok(()) + ); + tracker.note_sent( + ValidatorIndex(24), + ValidatorIndex(200), + CompactStatement::Seconded(hash_b), + ); + + // We have to see the candidate is known by the sender, e.g. we sent them 'Seconded'. + assert_eq!( + tracker.can_receive( + ValidatorIndex(24), + ValidatorIndex(200), + CompactStatement::Valid(hash_b), + ), + Ok(Accept::Ok), + ); + tracker.note_received( + ValidatorIndex(24), + ValidatorIndex(200), + CompactStatement::Valid(hash_b), + ); + + // Pending statements should be updated. + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(5)), + vec![ + (ValidatorIndex(5), CompactStatement::Seconded(hash_a)), + (ValidatorIndex(200), CompactStatement::Valid(hash_b)) + ] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(200)), + vec![(ValidatorIndex(200), CompactStatement::Valid(hash_b))] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(24)), + vec![(ValidatorIndex(5), CompactStatement::Seconded(hash_a))] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(146)), + vec![ + (ValidatorIndex(5), CompactStatement::Seconded(hash_a)), + (ValidatorIndex(200), CompactStatement::Valid(hash_b)) + ] + ); + } + + // Send a 'Seconded' statement. + { + assert_eq!( + tracker.can_send( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a) + ), + Ok(()) + ); + tracker.note_sent( + ValidatorIndex(5), + ValidatorIndex(5), + CompactStatement::Seconded(hash_a), + ); + + // Pending statements should be updated. + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(5)), + vec![(ValidatorIndex(200), CompactStatement::Valid(hash_b))] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(200)), + vec![(ValidatorIndex(200), CompactStatement::Valid(hash_b))] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(24)), + vec![(ValidatorIndex(5), CompactStatement::Seconded(hash_a))] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(146)), + vec![ + (ValidatorIndex(5), CompactStatement::Seconded(hash_a)), + (ValidatorIndex(200), CompactStatement::Valid(hash_b)) + ] + ); + } + + // Send a 'Valid' statement. + { + // First, send a `Seconded` statement for the candidate. + assert_eq!( + tracker.can_send( + ValidatorIndex(5), + ValidatorIndex(200), + CompactStatement::Seconded(hash_b) + ), + Ok(()) + ); + tracker.note_sent( + ValidatorIndex(5), + ValidatorIndex(200), + CompactStatement::Seconded(hash_b), + ); + + // We have to see that the candidate is known by the sender, e.g. we sent them + // 'Seconded' above. + assert_eq!( + tracker.can_send( + ValidatorIndex(5), + ValidatorIndex(200), + CompactStatement::Valid(hash_b) + ), + Ok(()) + ); + tracker.note_sent( + ValidatorIndex(5), + ValidatorIndex(200), + CompactStatement::Valid(hash_b), + ); + + // Pending statements should be updated. + assert_eq!(tracker.pending_statements_for(ValidatorIndex(5)), vec![]); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(200)), + vec![(ValidatorIndex(200), CompactStatement::Valid(hash_b))] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(24)), + vec![(ValidatorIndex(5), CompactStatement::Seconded(hash_a))] + ); + assert_eq!( + tracker.pending_statements_for(ValidatorIndex(146)), + vec![ + (ValidatorIndex(5), CompactStatement::Seconded(hash_a)), + (ValidatorIndex(200), CompactStatement::Valid(hash_b)) + ] + ); + } + } +} diff --git a/polkadot/node/network/statement-distribution/src/vstaging/grid.rs b/polkadot/node/network/statement-distribution/src/vstaging/grid.rs new file mode 100644 index 0000000000000000000000000000000000000000..c6c73f8bae529cc29c1345ee88b4b7f744612f64 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/vstaging/grid.rs @@ -0,0 +1,2252 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Utilities for handling distribution of backed candidates along the grid (outside the group to +//! the rest of the network). +//! +//! The grid uses the gossip topology defined in [`polkadot_node_network_protocol::grid_topology`]. +//! It defines how messages and statements are forwarded between validators. +//! +//! # Protocol +//! +//! - Once the candidate is backed, produce a 'backed candidate packet' `(CommittedCandidateReceipt, +//! Statements)`. +//! - Members of a backing group produce an announcement of a fully-backed candidate (aka "full +//! manifest") when they are finished. +//! - `BackedCandidateManifest` +//! - Manifests are sent along the grid topology to peers who have the relay-parent in their +//! implicit view. +//! - Only sent by 1st-hop nodes after downloading the backed candidate packet. +//! - The grid topology is a 2-dimensional grid that provides either a 1 or 2-hop path from any +//! originator to any recipient - 1st-hop nodes are those which share either a row or column +//! with the originator, and 2nd-hop nodes are those which share a column or row with that +//! 1st-hop node. +//! - Note that for the purposes of statement distribution, we actually take the union of the +//! routing paths from each validator in a group to the local node to determine the sending +//! and receiving paths. +//! - Ignored when received out-of-topology +//! - On every local view change, members of the backing group rebroadcast the manifest for all +//! candidates under every new relay-parent across the grid. +//! - Nodes should send a `BackedCandidateAcknowledgement(CandidateHash, StatementFilter)` +//! notification to any peer which has sent a manifest, and the candidate has been acquired by +//! other means. +//! - Request/response for the candidate + votes. +//! - Ignore if they are inconsistent with the manifest. +//! - A malicious backing group is capable of producing an unbounded number of backed candidates. +//! - We request the candidate only if the candidate has a hypothetical depth in any of our +//! fragment trees, and: +//! - the seconding validators have not seconded any other candidates at that depth in any of +//! those fragment trees +//! - All members of the group attempt to circulate all statements (in compact form) from the rest +//! of the group on candidates that have already been backed. +//! - They do this via the grid topology. +//! - They add the statements to their backed candidate packet for future requestors, and also: +//! - send the statement to any peer, which: +//! - we advertised the backed candidate to (sent manifest), and: +//! - has previously & successfully requested the backed candidate packet, or: +//! - which has sent a `BackedCandidateAcknowledgement` +//! - 1st-hop nodes do the same thing + +use polkadot_node_network_protocol::{ + grid_topology::SessionGridTopology, vstaging::StatementFilter, +}; +use polkadot_primitives::vstaging::{ + CandidateHash, CompactStatement, GroupIndex, Hash, ValidatorIndex, +}; + +use std::collections::{ + hash_map::{Entry, HashMap}, + HashSet, +}; + +use bitvec::{order::Lsb0, slice::BitSlice}; + +use super::{groups::Groups, LOG_TARGET}; + +/// Our local view of a subset of the grid topology organized around a specific validator +/// group. +/// +/// This tracks which authorities we expect to communicate with concerning +/// candidates from the group. This includes both the authorities we are +/// expected to send to as well as the authorities we expect to receive from. +/// +/// In the case that this group is the group that we are locally assigned to, +/// the 'receiving' side will be empty. +#[derive(Debug, PartialEq)] +struct GroupSubView { + // validators we are 'sending' to. + sending: HashSet, + // validators we are 'receiving' from. + receiving: HashSet, +} + +/// Our local view of the topology for a session, as it pertains to backed +/// candidate distribution. +#[derive(Debug)] +pub struct SessionTopologyView { + group_views: HashMap, +} + +impl SessionTopologyView { + /// Returns an iterator over all validator indices from the group who are allowed to + /// send us manifests of the given kind. + pub fn iter_sending_for_group( + &self, + group: GroupIndex, + kind: ManifestKind, + ) -> impl Iterator + '_ { + self.group_views.get(&group).into_iter().flat_map(move |sub| match kind { + ManifestKind::Full => sub.receiving.iter().cloned(), + ManifestKind::Acknowledgement => sub.sending.iter().cloned(), + }) + } +} + +/// Build a view of the topology for the session. +/// For groups that we are part of: we receive from nobody and send to our X/Y peers. +/// For groups that we are not part of: we receive from any validator in the group we share a slice +/// with and send to the corresponding X/Y slice in the other dimension. +/// For any validators we don't share a slice with, we receive from the nodes +/// which share a slice with them. +pub fn build_session_topology<'a>( + groups: impl IntoIterator>, + topology: &SessionGridTopology, + our_index: Option, +) -> SessionTopologyView { + let mut view = SessionTopologyView { group_views: HashMap::new() }; + + let our_index = match our_index { + None => return view, + Some(i) => i, + }; + + let our_neighbors = match topology.compute_grid_neighbors_for(our_index) { + None => { + gum::warn!(target: LOG_TARGET, ?our_index, "our index unrecognized in topology?"); + + return view + }, + Some(n) => n, + }; + + for (i, group) in groups.into_iter().enumerate() { + let mut sub_view = GroupSubView { sending: HashSet::new(), receiving: HashSet::new() }; + + if group.contains(&our_index) { + sub_view.sending.extend(our_neighbors.validator_indices_x.iter().cloned()); + sub_view.sending.extend(our_neighbors.validator_indices_y.iter().cloned()); + + // remove all other same-group validators from this set, they are + // in the cluster. + // TODO [now]: test this behavior. + for v in group { + sub_view.sending.remove(v); + } + } else { + for &group_val in group { + // If the validator shares a slice with us, we expect to + // receive from them and send to our neighbors in the other + // dimension. + + if our_neighbors.validator_indices_x.contains(&group_val) { + sub_view.receiving.insert(group_val); + sub_view.sending.extend( + our_neighbors + .validator_indices_y + .iter() + .filter(|v| !group.contains(v)) + .cloned(), + ); + + continue + } + + if our_neighbors.validator_indices_y.contains(&group_val) { + sub_view.receiving.insert(group_val); + sub_view.sending.extend( + our_neighbors + .validator_indices_x + .iter() + .filter(|v| !group.contains(v)) + .cloned(), + ); + + continue + } + + // If they don't share a slice with us, we don't send to anybody + // but receive from any peers sharing a dimension with both of us + let their_neighbors = match topology.compute_grid_neighbors_for(group_val) { + None => { + gum::warn!( + target: LOG_TARGET, + index = ?group_val, + "validator index unrecognized in topology?" + ); + + continue + }, + Some(n) => n, + }; + + // their X, our Y + for potential_link in &their_neighbors.validator_indices_x { + if our_neighbors.validator_indices_y.contains(potential_link) { + sub_view.receiving.insert(*potential_link); + break // one max + } + } + + // their Y, our X + for potential_link in &their_neighbors.validator_indices_y { + if our_neighbors.validator_indices_x.contains(potential_link) { + sub_view.receiving.insert(*potential_link); + break // one max + } + } + } + } + + view.group_views.insert(GroupIndex(i as _), sub_view); + } + + view +} + +/// The kind of backed candidate manifest we should send to a remote peer. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum ManifestKind { + /// Full manifests contain information about the candidate and should be sent + /// to peers which aren't guaranteed to have the candidate already. + Full, + /// Acknowledgement manifests omit information which is implicit in the candidate + /// itself, and should be sent to peers which are guaranteed to have the candidate + /// already. + Acknowledgement, +} + +/// A tracker of knowledge from authorities within the grid for a particular +/// relay-parent. +#[derive(Default)] +pub struct GridTracker { + received: HashMap, + confirmed_backed: HashMap, + unconfirmed: HashMap>, + pending_manifests: HashMap>, + + // maps target to (originator, statement) pairs. + pending_statements: HashMap>, +} + +impl GridTracker { + /// Attempt to import a manifest advertised by a remote peer. + /// + /// This checks whether the peer is allowed to send us manifests + /// about this group at this relay-parent. This also does sanity + /// checks on the format of the manifest and the amount of votes + /// it contains. It has effects on the stored state only when successful. + /// + /// This returns a `bool` on success, which if true indicates that an acknowledgement is + /// to be sent in response to the received manifest. This only occurs when the + /// candidate is already known to be confirmed and backed. + pub fn import_manifest( + &mut self, + session_topology: &SessionTopologyView, + groups: &Groups, + candidate_hash: CandidateHash, + seconding_limit: usize, + manifest: ManifestSummary, + kind: ManifestKind, + sender: ValidatorIndex, + ) -> Result { + let claimed_group_index = manifest.claimed_group_index; + + let group_topology = match session_topology.group_views.get(&manifest.claimed_group_index) { + None => return Err(ManifestImportError::Disallowed), + Some(g) => g, + }; + + let receiving_from = group_topology.receiving.contains(&sender); + let sending_to = group_topology.sending.contains(&sender); + let manifest_allowed = match kind { + // Peers can send manifests _if_: + // * They are in the receiving set for the group AND the manifest is full OR + // * They are in the sending set for the group AND we have sent them a manifest AND + // the received manifest is partial. + ManifestKind::Full => receiving_from, + ManifestKind::Acknowledgement => + sending_to && + self.confirmed_backed + .get(&candidate_hash) + .map_or(false, |c| c.has_sent_manifest_to(sender)), + }; + + if !manifest_allowed { + return Err(ManifestImportError::Disallowed) + } + + let (group_size, backing_threshold) = + match groups.get_size_and_backing_threshold(manifest.claimed_group_index) { + Some(x) => x, + None => return Err(ManifestImportError::Malformed), + }; + + let remote_knowledge = manifest.statement_knowledge.clone(); + + if !remote_knowledge.has_len(group_size) { + return Err(ManifestImportError::Malformed) + } + + if !remote_knowledge.has_seconded() { + return Err(ManifestImportError::Malformed) + } + + // ensure votes are sufficient to back. + let votes = remote_knowledge.backing_validators(); + + if votes < backing_threshold { + return Err(ManifestImportError::Insufficient) + } + + self.received.entry(sender).or_default().import_received( + group_size, + seconding_limit, + candidate_hash, + manifest, + )?; + + let mut ack = false; + if let Some(confirmed) = self.confirmed_backed.get_mut(&candidate_hash) { + if receiving_from && !confirmed.has_sent_manifest_to(sender) { + // due to checks above, the manifest `kind` is guaranteed to be `Full` + self.pending_manifests + .entry(sender) + .or_default() + .insert(candidate_hash, ManifestKind::Acknowledgement); + + ack = true; + } + + // add all statements in local_knowledge & !remote_knowledge + // to `pending_statements` for this validator. + confirmed.manifest_received_from(sender, remote_knowledge); + if let Some(pending_statements) = confirmed.pending_statements(sender) { + self.pending_statements.entry(sender).or_default().extend( + decompose_statement_filter( + groups, + claimed_group_index, + candidate_hash, + &pending_statements, + ), + ); + } + } else { + // `received` prevents conflicting manifests so this is max 1 per validator. + self.unconfirmed + .entry(candidate_hash) + .or_default() + .push((sender, claimed_group_index)) + } + + Ok(ack) + } + + /// Add a new backed candidate to the tracker. This yields + /// a list of validators which we should either advertise to + /// or signal that we know the candidate, along with the corresponding + /// type of manifest we should send. + pub fn add_backed_candidate( + &mut self, + session_topology: &SessionTopologyView, + candidate_hash: CandidateHash, + group_index: GroupIndex, + local_knowledge: StatementFilter, + ) -> Vec<(ValidatorIndex, ManifestKind)> { + let c = match self.confirmed_backed.entry(candidate_hash) { + Entry::Occupied(_) => return Vec::new(), + Entry::Vacant(v) => v.insert(KnownBackedCandidate { + group_index, + mutual_knowledge: HashMap::new(), + local_knowledge, + }), + }; + + // Populate the entry with previously unconfirmed manifests. + for (v, claimed_group_index) in + self.unconfirmed.remove(&candidate_hash).into_iter().flatten() + { + if claimed_group_index != group_index { + // This is misbehavior, but is handled more comprehensively elsewhere + continue + } + + let statement_filter = self + .received + .get(&v) + .and_then(|r| r.candidate_statement_filter(&candidate_hash)) + .expect("unconfirmed is only populated by validators who have sent manifest; qed"); + + // No need to send direct statements, because our local knowledge is `None` + c.manifest_received_from(v, statement_filter); + } + + let group_topology = match session_topology.group_views.get(&group_index) { + None => return Vec::new(), + Some(g) => g, + }; + + // advertise onwards and accept received advertisements + + let sending_group_manifests = + group_topology.sending.iter().map(|v| (*v, ManifestKind::Full)); + + let receiving_group_manifests = group_topology.receiving.iter().filter_map(|v| { + if c.has_received_manifest_from(*v) { + Some((*v, ManifestKind::Acknowledgement)) + } else { + None + } + }); + + // Note that order is important: if a validator is part of both the sending + // and receiving groups, we may overwrite a `Full` manifest with a `Acknowledgement` + // one. + for (v, manifest_mode) in sending_group_manifests.chain(receiving_group_manifests) { + gum::trace!( + target: LOG_TARGET, + validator_index = ?v, + ?manifest_mode, + "Preparing to send manifest/acknowledgement" + ); + + self.pending_manifests + .entry(v) + .or_default() + .insert(candidate_hash, manifest_mode); + } + + self.pending_manifests + .iter() + .filter_map(|(v, x)| x.get(&candidate_hash).map(|k| (*v, *k))) + .collect() + } + + /// Note that a backed candidate has been advertised to a + /// given validator. + pub fn manifest_sent_to( + &mut self, + groups: &Groups, + validator_index: ValidatorIndex, + candidate_hash: CandidateHash, + local_knowledge: StatementFilter, + ) { + if let Some(c) = self.confirmed_backed.get_mut(&candidate_hash) { + c.manifest_sent_to(validator_index, local_knowledge); + + if let Some(pending_statements) = c.pending_statements(validator_index) { + self.pending_statements.entry(validator_index).or_default().extend( + decompose_statement_filter( + groups, + c.group_index, + candidate_hash, + &pending_statements, + ), + ); + } + } + + if let Some(x) = self.pending_manifests.get_mut(&validator_index) { + x.remove(&candidate_hash); + } + } + + /// Returns a vector of all candidates pending manifests for the specific validator, and + /// the type of manifest we should send. + pub fn pending_manifests_for( + &self, + validator_index: ValidatorIndex, + ) -> Vec<(CandidateHash, ManifestKind)> { + self.pending_manifests + .get(&validator_index) + .into_iter() + .flat_map(|pending| pending.iter().map(|(c, m)| (*c, *m))) + .collect() + } + + /// Returns a statement filter indicating statements that a given peer + /// is awaiting concerning the given candidate, constrained by the statements + /// we have ourselves. + pub fn pending_statements_for( + &self, + validator_index: ValidatorIndex, + candidate_hash: CandidateHash, + ) -> Option { + self.confirmed_backed + .get(&candidate_hash) + .and_then(|x| x.pending_statements(validator_index)) + } + + /// Returns a vector of all pending statements to the validator, sorted with + /// `Seconded` statements at the front. + /// + /// Statements are in the form `(Originator, Statement Kind)`. + pub fn all_pending_statements_for( + &self, + validator_index: ValidatorIndex, + ) -> Vec<(ValidatorIndex, CompactStatement)> { + let mut v = self + .pending_statements + .get(&validator_index) + .map(|x| x.iter().cloned().collect()) + .unwrap_or(Vec::new()); + + v.sort_by_key(|(_, s)| match s { + CompactStatement::Seconded(_) => 0u32, + CompactStatement::Valid(_) => 1u32, + }); + + v + } + + /// Whether a validator can request a manifest from us. + pub fn can_request(&self, validator: ValidatorIndex, candidate_hash: CandidateHash) -> bool { + self.confirmed_backed.get(&candidate_hash).map_or(false, |c| { + c.has_sent_manifest_to(validator) && !c.has_received_manifest_from(validator) + }) + } + + /// Determine the validators which can send a statement to us by direct broadcast. + pub fn direct_statement_providers( + &self, + groups: &Groups, + originator: ValidatorIndex, + statement: &CompactStatement, + ) -> Vec { + let (g, c_h, kind, in_group) = + match extract_statement_and_group_info(groups, originator, statement) { + None => return Vec::new(), + Some(x) => x, + }; + + self.confirmed_backed + .get(&c_h) + .map(|k| k.direct_statement_senders(g, in_group, kind)) + .unwrap_or_default() + } + + /// Determine the validators which can receive a statement from us by direct + /// broadcast. + pub fn direct_statement_targets( + &self, + groups: &Groups, + originator: ValidatorIndex, + statement: &CompactStatement, + ) -> Vec { + let (g, c_h, kind, in_group) = + match extract_statement_and_group_info(groups, originator, statement) { + None => return Vec::new(), + Some(x) => x, + }; + + self.confirmed_backed + .get(&c_h) + .map(|k| k.direct_statement_recipients(g, in_group, kind)) + .unwrap_or_default() + } + + /// Note that we have learned about a statement. This will update + /// `pending_statements_for` for any relevant validators if actually + /// fresh. + pub fn learned_fresh_statement( + &mut self, + groups: &Groups, + session_topology: &SessionTopologyView, + originator: ValidatorIndex, + statement: &CompactStatement, + ) { + let (g, c_h, kind, in_group) = + match extract_statement_and_group_info(groups, originator, statement) { + None => return, + Some(x) => x, + }; + + let known = match self.confirmed_backed.get_mut(&c_h) { + None => return, + Some(x) => x, + }; + + if !known.note_fresh_statement(in_group, kind) { + return + } + + // Add to `pending_statements` for all validators we communicate with + // who have exchanged manifests. + let all_group_validators = session_topology + .group_views + .get(&g) + .into_iter() + .flat_map(|g| g.sending.iter().chain(g.receiving.iter())); + + for v in all_group_validators { + if known.is_pending_statement(*v, in_group, kind) { + self.pending_statements + .entry(*v) + .or_default() + .insert((originator, statement.clone())); + } + } + } + + /// Note that a direct statement about a given candidate was sent to or + /// received from the given validator. + pub fn sent_or_received_direct_statement( + &mut self, + groups: &Groups, + originator: ValidatorIndex, + counterparty: ValidatorIndex, + statement: &CompactStatement, + ) { + if let Some((_, c_h, kind, in_group)) = + extract_statement_and_group_info(groups, originator, statement) + { + if let Some(known) = self.confirmed_backed.get_mut(&c_h) { + known.sent_or_received_direct_statement(counterparty, in_group, kind); + + if let Some(pending) = self.pending_statements.get_mut(&counterparty) { + pending.remove(&(originator, statement.clone())); + } + } + } + } + + /// Get the advertised statement filter of a validator for a candidate. + pub fn advertised_statements( + &self, + validator: ValidatorIndex, + candidate_hash: &CandidateHash, + ) -> Option { + self.received.get(&validator)?.candidate_statement_filter(candidate_hash) + } + + #[cfg(test)] + fn is_manifest_pending_for( + &self, + validator: ValidatorIndex, + candidate_hash: &CandidateHash, + ) -> Option { + self.pending_manifests + .get(&validator) + .and_then(|m| m.get(candidate_hash)) + .map(|x| *x) + } +} + +fn extract_statement_and_group_info( + groups: &Groups, + originator: ValidatorIndex, + statement: &CompactStatement, +) -> Option<(GroupIndex, CandidateHash, StatementKind, usize)> { + let (statement_kind, candidate_hash) = match statement { + CompactStatement::Seconded(h) => (StatementKind::Seconded, h), + CompactStatement::Valid(h) => (StatementKind::Valid, h), + }; + + let group = match groups.by_validator_index(originator) { + None => return None, + Some(g) => g, + }; + + let index_in_group = groups.get(group)?.iter().position(|v| v == &originator)?; + + Some((group, *candidate_hash, statement_kind, index_in_group)) +} + +fn decompose_statement_filter<'a>( + groups: &'a Groups, + group_index: GroupIndex, + candidate_hash: CandidateHash, + statement_filter: &'a StatementFilter, +) -> impl Iterator + 'a { + groups.get(group_index).into_iter().flat_map(move |g| { + let s = statement_filter + .seconded_in_group + .iter_ones() + .map(|i| g[i]) + .map(move |i| (i, CompactStatement::Seconded(candidate_hash))); + + let v = statement_filter + .validated_in_group + .iter_ones() + .map(|i| g[i]) + .map(move |i| (i, CompactStatement::Valid(candidate_hash))); + + s.chain(v) + }) +} + +/// A summary of a manifest being sent by a counterparty. +#[derive(Debug, Clone)] +pub struct ManifestSummary { + /// The claimed parent head data hash of the candidate. + pub claimed_parent_hash: Hash, + /// The claimed group index assigned to the candidate. + pub claimed_group_index: GroupIndex, + /// A statement filter sent alongisde the candidate, communicating + /// knowledge. + pub statement_knowledge: StatementFilter, +} + +/// Errors in importing a manifest. +#[derive(Debug, Clone)] +pub enum ManifestImportError { + /// The manifest conflicts with another, previously sent manifest. + Conflicting, + /// The manifest has overflowed beyond the limits of what the + /// counterparty was allowed to send us. + Overflow, + /// The manifest claims insufficient attestations to achieve the backing + /// threshold. + Insufficient, + /// The manifest is malformed. + Malformed, + /// The manifest was not allowed to be sent. + Disallowed, +} + +/// The knowledge we are aware of counterparties having of manifests. +#[derive(Default)] +struct ReceivedManifests { + received: HashMap, + // group -> seconded counts. + seconded_counts: HashMap>, +} + +impl ReceivedManifests { + fn candidate_statement_filter( + &self, + candidate_hash: &CandidateHash, + ) -> Option { + self.received.get(candidate_hash).map(|m| m.statement_knowledge.clone()) + } + + /// Attempt to import a received manifest from a counterparty. + /// + /// This will reject manifests which are either duplicate, conflicting, + /// or imply an irrational amount of `Seconded` statements. + /// + /// This assumes that the manifest has already been checked for + /// validity - i.e. that the bitvecs match the claimed group in size + /// and that the manifest includes at least one `Seconded` + /// attestation and includes enough attestations for the candidate + /// to be backed. + /// + /// This also should only be invoked when we are intended to track + /// the knowledge of this peer as determined by the [`SessionTopology`]. + fn import_received( + &mut self, + group_size: usize, + seconding_limit: usize, + candidate_hash: CandidateHash, + manifest_summary: ManifestSummary, + ) -> Result<(), ManifestImportError> { + match self.received.entry(candidate_hash) { + Entry::Occupied(mut e) => { + // occupied entry. + + // filter out clearly conflicting data. + { + let prev = e.get(); + if prev.claimed_group_index != manifest_summary.claimed_group_index { + return Err(ManifestImportError::Conflicting) + } + + if prev.claimed_parent_hash != manifest_summary.claimed_parent_hash { + return Err(ManifestImportError::Conflicting) + } + + if !manifest_summary + .statement_knowledge + .seconded_in_group + .contains(&prev.statement_knowledge.seconded_in_group) + { + return Err(ManifestImportError::Conflicting) + } + + if !manifest_summary + .statement_knowledge + .validated_in_group + .contains(&prev.statement_knowledge.validated_in_group) + { + return Err(ManifestImportError::Conflicting) + } + + let mut fresh_seconded = + manifest_summary.statement_knowledge.seconded_in_group.clone(); + fresh_seconded |= &prev.statement_knowledge.seconded_in_group; + + let within_limits = updating_ensure_within_seconding_limit( + &mut self.seconded_counts, + manifest_summary.claimed_group_index, + group_size, + seconding_limit, + &fresh_seconded, + ); + + if !within_limits { + return Err(ManifestImportError::Overflow) + } + } + + // All checks passed. Overwrite: guaranteed to be + // superset. + *e.get_mut() = manifest_summary; + Ok(()) + }, + Entry::Vacant(e) => { + let within_limits = updating_ensure_within_seconding_limit( + &mut self.seconded_counts, + manifest_summary.claimed_group_index, + group_size, + seconding_limit, + &manifest_summary.statement_knowledge.seconded_in_group, + ); + + if within_limits { + e.insert(manifest_summary); + Ok(()) + } else { + Err(ManifestImportError::Overflow) + } + }, + } + } +} + +// updates validator-seconded records but only if the new statements +// are OK. returns `true` if alright and `false` otherwise. +// +// The seconding limit is a per-validator limit. It ensures an upper bound on the total number of +// candidates entering the system. +fn updating_ensure_within_seconding_limit( + seconded_counts: &mut HashMap>, + group_index: GroupIndex, + group_size: usize, + seconding_limit: usize, + new_seconded: &BitSlice, +) -> bool { + if seconding_limit == 0 { + return false + } + + // due to the check above, if this was non-existent this function will + // always return `true`. + let counts = seconded_counts.entry(group_index).or_insert_with(|| vec![0; group_size]); + + for i in new_seconded.iter_ones() { + if counts[i] == seconding_limit { + return false + } + } + + for i in new_seconded.iter_ones() { + counts[i] += 1; + } + + true +} + +#[derive(Debug, Clone, Copy)] +enum StatementKind { + Seconded, + Valid, +} + +trait FilterQuery { + fn contains(&self, index: usize, statement_kind: StatementKind) -> bool; + fn set(&mut self, index: usize, statement_kind: StatementKind); +} + +impl FilterQuery for StatementFilter { + fn contains(&self, index: usize, statement_kind: StatementKind) -> bool { + match statement_kind { + StatementKind::Seconded => self.seconded_in_group.get(index).map_or(false, |x| *x), + StatementKind::Valid => self.validated_in_group.get(index).map_or(false, |x| *x), + } + } + + fn set(&mut self, index: usize, statement_kind: StatementKind) { + let b = match statement_kind { + StatementKind::Seconded => self.seconded_in_group.get_mut(index), + StatementKind::Valid => self.validated_in_group.get_mut(index), + }; + + if let Some(mut b) = b { + *b = true; + } + } +} + +/// Knowledge that we have about a remote peer concerning a candidate, and that they have about us +/// concerning the candidate. +#[derive(Debug, Clone)] +struct MutualKnowledge { + /// Knowledge the remote peer has about the candidate, as far as we're aware. + /// `Some` only if they have advertised, acknowledged, or requested the candidate. + remote_knowledge: Option, + /// Knowledge we have indicated to the remote peer about the candidate. + /// `Some` only if we have advertised, acknowledged, or requested the candidate + /// from them. + local_knowledge: Option, +} + +// A utility struct for keeping track of metadata about candidates +// we have confirmed as having been backed. +#[derive(Debug, Clone)] +struct KnownBackedCandidate { + group_index: GroupIndex, + local_knowledge: StatementFilter, + mutual_knowledge: HashMap, +} + +impl KnownBackedCandidate { + fn has_received_manifest_from(&self, validator: ValidatorIndex) -> bool { + self.mutual_knowledge + .get(&validator) + .map_or(false, |k| k.remote_knowledge.is_some()) + } + + fn has_sent_manifest_to(&self, validator: ValidatorIndex) -> bool { + self.mutual_knowledge + .get(&validator) + .map_or(false, |k| k.local_knowledge.is_some()) + } + + fn manifest_sent_to(&mut self, validator: ValidatorIndex, local_knowledge: StatementFilter) { + let k = self + .mutual_knowledge + .entry(validator) + .or_insert_with(|| MutualKnowledge { remote_knowledge: None, local_knowledge: None }); + + k.local_knowledge = Some(local_knowledge); + } + + fn manifest_received_from( + &mut self, + validator: ValidatorIndex, + remote_knowledge: StatementFilter, + ) { + let k = self + .mutual_knowledge + .entry(validator) + .or_insert_with(|| MutualKnowledge { remote_knowledge: None, local_knowledge: None }); + + k.remote_knowledge = Some(remote_knowledge); + } + + fn direct_statement_senders( + &self, + group_index: GroupIndex, + originator_index_in_group: usize, + statement_kind: StatementKind, + ) -> Vec { + if group_index != self.group_index { + return Vec::new() + } + + self.mutual_knowledge + .iter() + .filter(|(_, k)| k.remote_knowledge.is_some()) + .filter(|(_, k)| { + k.local_knowledge + .as_ref() + .map_or(false, |r| !r.contains(originator_index_in_group, statement_kind)) + }) + .map(|(v, _)| *v) + .collect() + } + + fn direct_statement_recipients( + &self, + group_index: GroupIndex, + originator_index_in_group: usize, + statement_kind: StatementKind, + ) -> Vec { + if group_index != self.group_index { + return Vec::new() + } + + self.mutual_knowledge + .iter() + .filter(|(_, k)| k.local_knowledge.is_some()) + .filter(|(_, k)| { + k.remote_knowledge + .as_ref() + .map_or(false, |r| !r.contains(originator_index_in_group, statement_kind)) + }) + .map(|(v, _)| *v) + .collect() + } + + fn note_fresh_statement( + &mut self, + statement_index_in_group: usize, + statement_kind: StatementKind, + ) -> bool { + let really_fresh = !self.local_knowledge.contains(statement_index_in_group, statement_kind); + self.local_knowledge.set(statement_index_in_group, statement_kind); + + really_fresh + } + + fn sent_or_received_direct_statement( + &mut self, + validator: ValidatorIndex, + statement_index_in_group: usize, + statement_kind: StatementKind, + ) { + if let Some(k) = self.mutual_knowledge.get_mut(&validator) { + if let (Some(r), Some(l)) = (k.remote_knowledge.as_mut(), k.local_knowledge.as_mut()) { + r.set(statement_index_in_group, statement_kind); + l.set(statement_index_in_group, statement_kind); + } + } + } + + fn is_pending_statement( + &self, + validator: ValidatorIndex, + statement_index_in_group: usize, + statement_kind: StatementKind, + ) -> bool { + // existence of both remote & local knowledge indicate we have exchanged + // manifests. + // then, everything that is not in the remote knowledge is pending + self.mutual_knowledge + .get(&validator) + .filter(|k| k.local_knowledge.is_some()) + .and_then(|k| k.remote_knowledge.as_ref()) + .map(|k| !k.contains(statement_index_in_group, statement_kind)) + .unwrap_or(false) + } + + fn pending_statements(&self, validator: ValidatorIndex) -> Option { + // existence of both remote & local knowledge indicate we have exchanged + // manifests. + // then, everything that is not in the remote knowledge is pending, and we + // further limit this by what is in the local knowledge itself. we use the + // full local knowledge, as the local knowledge stored here may be outdated. + let full_local = &self.local_knowledge; + + self.mutual_knowledge + .get(&validator) + .filter(|k| k.local_knowledge.is_some()) + .and_then(|k| k.remote_knowledge.as_ref()) + .map(|remote| StatementFilter { + seconded_in_group: full_local.seconded_in_group.clone() & + !remote.seconded_in_group.clone(), + validated_in_group: full_local.validated_in_group.clone() & + !remote.validated_in_group.clone(), + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use assert_matches::assert_matches; + use polkadot_node_network_protocol::grid_topology::TopologyPeerInfo; + use sp_authority_discovery::AuthorityPair as AuthorityDiscoveryPair; + use sp_core::crypto::Pair as PairT; + + fn dummy_groups(group_size: usize) -> Groups { + let groups = vec![(0..(group_size as u32)).map(ValidatorIndex).collect()].into(); + + Groups::new(groups) + } + + #[test] + fn topology_empty_for_no_index() { + let base_topology = SessionGridTopology::new( + vec![0, 1, 2], + vec![ + TopologyPeerInfo { + peer_ids: Vec::new(), + validator_index: ValidatorIndex(0), + discovery_id: AuthorityDiscoveryPair::generate().0.public(), + }, + TopologyPeerInfo { + peer_ids: Vec::new(), + validator_index: ValidatorIndex(1), + discovery_id: AuthorityDiscoveryPair::generate().0.public(), + }, + TopologyPeerInfo { + peer_ids: Vec::new(), + validator_index: ValidatorIndex(2), + discovery_id: AuthorityDiscoveryPair::generate().0.public(), + }, + ], + ); + + let t = build_session_topology( + &[vec![ValidatorIndex(0)], vec![ValidatorIndex(1)], vec![ValidatorIndex(2)]], + &base_topology, + None, + ); + + assert!(t.group_views.is_empty()); + } + + #[test] + fn topology_setup() { + let base_topology = SessionGridTopology::new( + (0..9).collect(), + (0..9) + .map(|i| TopologyPeerInfo { + peer_ids: Vec::new(), + validator_index: ValidatorIndex(i), + discovery_id: AuthorityDiscoveryPair::generate().0.public(), + }) + .collect(), + ); + + let t = build_session_topology( + &[ + vec![ValidatorIndex(0), ValidatorIndex(3), ValidatorIndex(6)], + vec![ValidatorIndex(4), ValidatorIndex(2), ValidatorIndex(7)], + vec![ValidatorIndex(8), ValidatorIndex(5), ValidatorIndex(1)], + ], + &base_topology, + Some(ValidatorIndex(0)), + ); + + assert_eq!(t.group_views.len(), 3); + + // 0 1 2 + // 3 4 5 + // 6 7 8 + + // our group: we send to all row/column neighbors which are not in our + // group and receive nothing. + assert_eq!( + t.group_views.get(&GroupIndex(0)).unwrap().sending, + vec![1, 2].into_iter().map(ValidatorIndex).collect::>(), + ); + assert_eq!(t.group_views.get(&GroupIndex(0)).unwrap().receiving, HashSet::new(),); + + // we share a row with '2' and have indirect connections to '4' and '7'. + + assert_eq!( + t.group_views.get(&GroupIndex(1)).unwrap().sending, + vec![3, 6].into_iter().map(ValidatorIndex).collect::>(), + ); + assert_eq!( + t.group_views.get(&GroupIndex(1)).unwrap().receiving, + vec![1, 2, 3, 6].into_iter().map(ValidatorIndex).collect::>(), + ); + + // we share a row with '1' and have indirect connections to '5' and '8'. + + assert_eq!( + t.group_views.get(&GroupIndex(2)).unwrap().sending, + vec![3, 6].into_iter().map(ValidatorIndex).collect::>(), + ); + assert_eq!( + t.group_views.get(&GroupIndex(2)).unwrap().receiving, + vec![1, 2, 3, 6].into_iter().map(ValidatorIndex).collect::>(), + ); + } + + #[test] + fn knowledge_rejects_conflicting_manifest() { + let mut knowledge = ReceivedManifests::default(); + + let expected_manifest_summary = ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(2), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + }, + }; + + knowledge + .import_received( + 3, + 2, + CandidateHash(Hash::repeat_byte(1)), + expected_manifest_summary.clone(), + ) + .unwrap(); + + // conflicting group + + let mut s = expected_manifest_summary.clone(); + s.claimed_group_index = GroupIndex(1); + assert_matches!( + knowledge.import_received(3, 2, CandidateHash(Hash::repeat_byte(1)), s,), + Err(ManifestImportError::Conflicting) + ); + + // conflicting parent hash + + let mut s = expected_manifest_summary.clone(); + s.claimed_parent_hash = Hash::repeat_byte(3); + assert_matches!( + knowledge.import_received(3, 2, CandidateHash(Hash::repeat_byte(1)), s,), + Err(ManifestImportError::Conflicting) + ); + + // conflicting seconded statements bitfield + + let mut s = expected_manifest_summary.clone(); + s.statement_knowledge.seconded_in_group = bitvec::bitvec![u8, Lsb0; 0, 1, 0]; + assert_matches!( + knowledge.import_received(3, 2, CandidateHash(Hash::repeat_byte(1)), s,), + Err(ManifestImportError::Conflicting) + ); + + // conflicting valid statements bitfield + + let mut s = expected_manifest_summary.clone(); + s.statement_knowledge.validated_in_group = bitvec::bitvec![u8, Lsb0; 0, 1, 0]; + assert_matches!( + knowledge.import_received(3, 2, CandidateHash(Hash::repeat_byte(1)), s,), + Err(ManifestImportError::Conflicting) + ); + } + + // Make sure we don't import manifests that would put a validator in a group over the limit of + // candidates they are allowed to second (aka seconding limit). + #[test] + fn reject_overflowing_manifests() { + let mut knowledge = ReceivedManifests::default(); + knowledge + .import_received( + 3, + 2, + CandidateHash(Hash::repeat_byte(1)), + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0xA), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + }, + }, + ) + .unwrap(); + + knowledge + .import_received( + 3, + 2, + CandidateHash(Hash::repeat_byte(2)), + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0xB), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + }, + }, + ) + .unwrap(); + + // Reject a seconding validator that is already at the seconding limit. Seconding counts for + // the validators should not be applied. + assert_matches!( + knowledge.import_received( + 3, + 2, + CandidateHash(Hash::repeat_byte(3)), + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0xC), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + } + }, + ), + Err(ManifestImportError::Overflow) + ); + + // Don't reject validators that have seconded less than the limit so far. + knowledge + .import_received( + 3, + 2, + CandidateHash(Hash::repeat_byte(3)), + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0xC), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + }, + }, + ) + .unwrap(); + } + + #[test] + fn reject_disallowed_manifest() { + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::new(), + receiving: vec![ValidatorIndex(0)].into_iter().collect(), + }, + )] + .into_iter() + .collect(), + }; + + let groups = dummy_groups(3); + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + + assert_eq!(groups.get_size_and_backing_threshold(GroupIndex(0)), Some((3, 2)),); + + // Known group, disallowed receiving validator. + + assert_matches!( + tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + } + }, + ManifestKind::Full, + ValidatorIndex(1), + ), + Err(ManifestImportError::Disallowed) + ); + + // Unknown group + + assert_matches!( + tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: GroupIndex(1), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + } + }, + ManifestKind::Full, + ValidatorIndex(0), + ), + Err(ManifestImportError::Disallowed) + ); + } + + #[test] + fn reject_malformed_wrong_group_size() { + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::new(), + receiving: vec![ValidatorIndex(0)].into_iter().collect(), + }, + )] + .into_iter() + .collect(), + }; + + let groups = dummy_groups(3); + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + + assert_eq!(groups.get_size_and_backing_threshold(GroupIndex(0)), Some((3, 2)),); + + assert_matches!( + tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + } + }, + ManifestKind::Full, + ValidatorIndex(0), + ), + Err(ManifestImportError::Malformed) + ); + + assert_matches!( + tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1, 0], + } + }, + ManifestKind::Full, + ValidatorIndex(0), + ), + Err(ManifestImportError::Malformed) + ); + } + + #[test] + fn reject_malformed_no_seconders() { + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::new(), + receiving: vec![ValidatorIndex(0)].into_iter().collect(), + }, + )] + .into_iter() + .collect(), + }; + + let groups = dummy_groups(3); + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + + assert_eq!(groups.get_size_and_backing_threshold(GroupIndex(0)), Some((3, 2)),); + + assert_matches!( + tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + } + }, + ManifestKind::Full, + ValidatorIndex(0), + ), + Err(ManifestImportError::Malformed) + ); + } + + #[test] + fn reject_insufficient_below_threshold() { + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::new(), + receiving: HashSet::from([ValidatorIndex(0)]), + }, + )] + .into_iter() + .collect(), + }; + + let groups = dummy_groups(3); + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + + assert_eq!(groups.get_size_and_backing_threshold(GroupIndex(0)), Some((3, 2)),); + + // only one vote + + assert_matches!( + tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + } + }, + ManifestKind::Full, + ValidatorIndex(0), + ), + Err(ManifestImportError::Insufficient) + ); + + // seconding + validating still not enough to reach '2' threshold + + assert_matches!( + tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 1], + } + }, + ManifestKind::Full, + ValidatorIndex(0), + ), + Err(ManifestImportError::Insufficient) + ); + + // finally good. + + assert_matches!( + tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: GroupIndex(0), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + } + }, + ManifestKind::Full, + ValidatorIndex(0), + ), + Ok(false) + ); + } + + // Test that when we add a candidate as backed and advertise it to the sending group, they can + // provide an acknowledgement manifest in response. + #[test] + fn senders_can_provide_manifests_in_acknowledgement() { + let validator_index = ValidatorIndex(0); + + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::from([validator_index]), + receiving: HashSet::from([ValidatorIndex(1)]), + }, + )] + .into_iter() + .collect(), + }; + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + let group_index = GroupIndex(0); + let group_size = 3; + let local_knowledge = StatementFilter::blank(group_size); + + let groups = dummy_groups(group_size); + + // Add the candidate as backed. + let receivers = tracker.add_backed_candidate( + &session_topology, + candidate_hash, + group_index, + local_knowledge.clone(), + ); + // Validator 0 is in the sending group. Advertise onward to it. + // + // Validator 1 is in the receiving group, but we have not received from it, so we're not + // expected to send it an acknowledgement. + assert_eq!(receivers, vec![(validator_index, ManifestKind::Full)]); + + // Note the manifest as 'sent' to validator 0. + tracker.manifest_sent_to(&groups, validator_index, candidate_hash, local_knowledge); + + // Import manifest of kind `Acknowledgement` from validator 0. + let ack = tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: group_index, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + }, + }, + ManifestKind::Acknowledgement, + validator_index, + ); + assert_matches!(ack, Ok(false)); + } + + // Check that pending communication is set correctly when receiving a manifest on a confirmed + // candidate. + // + // It should also overwrite any existing `Full` ManifestKind. + #[test] + fn pending_communication_receiving_manifest_on_confirmed_candidate() { + let validator_index = ValidatorIndex(0); + + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::from([validator_index]), + receiving: HashSet::from([ValidatorIndex(1)]), + }, + )] + .into_iter() + .collect(), + }; + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + let group_index = GroupIndex(0); + let group_size = 3; + let local_knowledge = StatementFilter::blank(group_size); + + let groups = dummy_groups(group_size); + + // Manifest should not be pending yet. + let pending_manifest = tracker.is_manifest_pending_for(validator_index, &candidate_hash); + assert_eq!(pending_manifest, None); + + // Add the candidate as backed. + tracker.add_backed_candidate( + &session_topology, + candidate_hash, + group_index, + local_knowledge.clone(), + ); + + // Manifest should be pending as `Full`. + let pending_manifest = tracker.is_manifest_pending_for(validator_index, &candidate_hash); + assert_eq!(pending_manifest, Some(ManifestKind::Full)); + + // Note the manifest as 'sent' to validator 0. + tracker.manifest_sent_to(&groups, validator_index, candidate_hash, local_knowledge); + + // Import manifest. + // + // Should overwrite existing `Full` manifest. + let ack = tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: group_index, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + }, + }, + ManifestKind::Acknowledgement, + validator_index, + ); + assert_matches!(ack, Ok(false)); + + let pending_manifest = tracker.is_manifest_pending_for(validator_index, &candidate_hash); + assert_eq!(pending_manifest, None); + } + + // Check that pending communication is cleared correctly in `manifest_sent_to` + // + // Also test a scenario where manifest import returns `Ok(true)` (should acknowledge). + #[test] + fn pending_communication_is_cleared() { + let validator_index = ValidatorIndex(0); + + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::new(), + receiving: HashSet::from([validator_index]), + }, + )] + .into_iter() + .collect(), + }; + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + let group_index = GroupIndex(0); + let group_size = 3; + let local_knowledge = StatementFilter::blank(group_size); + + let groups = dummy_groups(group_size); + + // Add the candidate as backed. + tracker.add_backed_candidate( + &session_topology, + candidate_hash, + group_index, + local_knowledge.clone(), + ); + + // Manifest should not be pending yet. + let pending_manifest = tracker.is_manifest_pending_for(validator_index, &candidate_hash); + assert_eq!(pending_manifest, None); + + // Import manifest. The candidate is confirmed backed and we are expected to receive from + // validator 0, so send it an acknowledgement. + let ack = tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: group_index, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + }, + }, + ManifestKind::Full, + validator_index, + ); + assert_matches!(ack, Ok(true)); + + // Acknowledgement manifest should be pending. + let pending_manifest = tracker.is_manifest_pending_for(validator_index, &candidate_hash); + assert_eq!(pending_manifest, Some(ManifestKind::Acknowledgement)); + + // Note the candidate as advertised. + tracker.manifest_sent_to(&groups, validator_index, candidate_hash, local_knowledge); + + // Pending manifest should be cleared. + let pending_manifest = tracker.is_manifest_pending_for(validator_index, &candidate_hash); + assert_eq!(pending_manifest, None); + } + + /// A manifest exchange means that both `manifest_sent_to` and `manifest_received_from` have + /// been invoked. + /// + /// In practice, it means that one of three things have happened: + /// + /// - They announced, we acknowledged + /// + /// - We announced, they acknowledged + /// + /// - We announced, they announced (not sure if this can actually happen; it would happen if 2 + /// nodes had each other in their sending set and they sent manifests at the same time. The + /// code accounts for this anyway) + #[test] + fn pending_statements_are_updated_after_manifest_exchange() { + let send_to = ValidatorIndex(0); + let receive_from = ValidatorIndex(1); + + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::from([send_to]), + receiving: HashSet::from([receive_from]), + }, + )] + .into_iter() + .collect(), + }; + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + let group_index = GroupIndex(0); + let group_size = 3; + let local_knowledge = StatementFilter::blank(group_size); + + let groups = dummy_groups(group_size); + + // Confirm the candidate. + let receivers = tracker.add_backed_candidate( + &session_topology, + candidate_hash, + group_index, + local_knowledge.clone(), + ); + assert_eq!(receivers, vec![(send_to, ManifestKind::Full)]); + + // Learn a statement from a different validator. + tracker.learned_fresh_statement( + &groups, + &session_topology, + ValidatorIndex(2), + &CompactStatement::Seconded(candidate_hash), + ); + + // Test receiving followed by sending an ack. + { + // Should start with no pending statements. + assert_eq!(tracker.pending_statements_for(receive_from, candidate_hash), None); + assert_eq!(tracker.all_pending_statements_for(receive_from), vec![]); + let ack = tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: group_index, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + }, + }, + ManifestKind::Full, + receive_from, + ); + assert_matches!(ack, Ok(true)); + + // Send ack now. + tracker.manifest_sent_to( + &groups, + receive_from, + candidate_hash, + local_knowledge.clone(), + ); + + // There should be pending statements now. + assert_eq!( + tracker.pending_statements_for(receive_from, candidate_hash), + Some(StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }) + ); + assert_eq!( + tracker.all_pending_statements_for(receive_from), + vec![(ValidatorIndex(2), CompactStatement::Seconded(candidate_hash))] + ); + } + + // Test sending followed by receiving an ack. + { + // Should start with no pending statements. + assert_eq!(tracker.pending_statements_for(send_to, candidate_hash), None); + assert_eq!(tracker.all_pending_statements_for(send_to), vec![]); + + tracker.manifest_sent_to(&groups, send_to, candidate_hash, local_knowledge.clone()); + let ack = tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: group_index, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 1], + }, + }, + ManifestKind::Acknowledgement, + send_to, + ); + assert_matches!(ack, Ok(false)); + + // There should be pending statements now. + assert_eq!( + tracker.pending_statements_for(send_to, candidate_hash), + Some(StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }) + ); + assert_eq!( + tracker.all_pending_statements_for(send_to), + vec![(ValidatorIndex(2), CompactStatement::Seconded(candidate_hash))] + ); + } + } + + #[test] + fn invalid_fresh_statement_import() { + let validator_index = ValidatorIndex(0); + + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::new(), + receiving: HashSet::from([validator_index]), + }, + )] + .into_iter() + .collect(), + }; + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + let group_index = GroupIndex(0); + let group_size = 3; + let local_knowledge = StatementFilter::blank(group_size); + + let groups = dummy_groups(group_size); + + // Should start with no pending statements. + assert_eq!(tracker.pending_statements_for(validator_index, candidate_hash), None); + assert_eq!(tracker.all_pending_statements_for(validator_index), vec![]); + + // Try to import fresh statement. Candidate not backed. + let statement = CompactStatement::Seconded(candidate_hash); + tracker.learned_fresh_statement(&groups, &session_topology, validator_index, &statement); + + assert_eq!(tracker.pending_statements_for(validator_index, candidate_hash), None); + assert_eq!(tracker.all_pending_statements_for(validator_index), vec![]); + + // Add the candidate as backed. + tracker.add_backed_candidate( + &session_topology, + candidate_hash, + group_index, + local_knowledge.clone(), + ); + + // Try to import fresh statement. Unknown group for validator index. + let statement = CompactStatement::Seconded(candidate_hash); + tracker.learned_fresh_statement(&groups, &session_topology, ValidatorIndex(1), &statement); + + assert_eq!(tracker.pending_statements_for(validator_index, candidate_hash), None); + assert_eq!(tracker.all_pending_statements_for(validator_index), vec![]); + } + + #[test] + fn pending_statements_updated_when_importing_fresh_statement() { + let validator_index = ValidatorIndex(0); + + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::new(), + receiving: HashSet::from([validator_index]), + }, + )] + .into_iter() + .collect(), + }; + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + let group_index = GroupIndex(0); + let group_size = 3; + let local_knowledge = StatementFilter::blank(group_size); + + let groups = dummy_groups(group_size); + + // Should start with no pending statements. + assert_eq!(tracker.pending_statements_for(validator_index, candidate_hash), None); + assert_eq!(tracker.all_pending_statements_for(validator_index), vec![]); + + // Add the candidate as backed. + tracker.add_backed_candidate( + &session_topology, + candidate_hash, + group_index, + local_knowledge.clone(), + ); + + // Import fresh statement. + + let ack = tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: group_index, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + }, + }, + ManifestKind::Full, + validator_index, + ); + assert_matches!(ack, Ok(true)); + tracker.manifest_sent_to(&groups, validator_index, candidate_hash, local_knowledge); + let statement = CompactStatement::Seconded(candidate_hash); + tracker.learned_fresh_statement(&groups, &session_topology, validator_index, &statement); + + // There should be pending statements now. + let statements = StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }; + assert_eq!( + tracker.pending_statements_for(validator_index, candidate_hash), + Some(statements.clone()) + ); + assert_eq!( + tracker.all_pending_statements_for(validator_index), + vec![(ValidatorIndex(0), CompactStatement::Seconded(candidate_hash))] + ); + + // After successful import, try importing again. Nothing should change. + + tracker.learned_fresh_statement(&groups, &session_topology, validator_index, &statement); + assert_eq!( + tracker.pending_statements_for(validator_index, candidate_hash), + Some(statements) + ); + assert_eq!( + tracker.all_pending_statements_for(validator_index), + vec![(ValidatorIndex(0), CompactStatement::Seconded(candidate_hash))] + ); + } + + // After learning fresh statements, we should not generate pending statements for knowledge that + // the validator already has. + #[test] + fn pending_statements_respect_remote_knowledge() { + let validator_index = ValidatorIndex(0); + + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::new(), + receiving: HashSet::from([validator_index]), + }, + )] + .into_iter() + .collect(), + }; + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + let group_index = GroupIndex(0); + let group_size = 3; + let local_knowledge = StatementFilter::blank(group_size); + + let groups = dummy_groups(group_size); + + // Should start with no pending statements. + assert_eq!(tracker.pending_statements_for(validator_index, candidate_hash), None); + assert_eq!(tracker.all_pending_statements_for(validator_index), vec![]); + + // Add the candidate as backed. + tracker.add_backed_candidate( + &session_topology, + candidate_hash, + group_index, + local_knowledge.clone(), + ); + + // Import fresh statement. + let ack = tracker.import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: group_index, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }, + ManifestKind::Full, + validator_index, + ); + assert_matches!(ack, Ok(true)); + tracker.manifest_sent_to(&groups, validator_index, candidate_hash, local_knowledge); + tracker.learned_fresh_statement( + &groups, + &session_topology, + validator_index, + &CompactStatement::Seconded(candidate_hash), + ); + tracker.learned_fresh_statement( + &groups, + &session_topology, + validator_index, + &CompactStatement::Valid(candidate_hash), + ); + + // The pending statements should respect the remote knowledge (meaning the Seconded + // statement is ignored, but not the Valid statement). + let statements = StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 0], + }; + assert_eq!( + tracker.pending_statements_for(validator_index, candidate_hash), + Some(statements.clone()) + ); + assert_eq!( + tracker.all_pending_statements_for(validator_index), + vec![(ValidatorIndex(0), CompactStatement::Valid(candidate_hash))] + ); + } + + #[test] + fn pending_statements_cleared_when_sending() { + let validator_index = ValidatorIndex(0); + let counterparty = ValidatorIndex(1); + + let mut tracker = GridTracker::default(); + let session_topology = SessionTopologyView { + group_views: vec![( + GroupIndex(0), + GroupSubView { + sending: HashSet::new(), + receiving: HashSet::from([validator_index, counterparty]), + }, + )] + .into_iter() + .collect(), + }; + + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + let group_index = GroupIndex(0); + let group_size = 3; + let local_knowledge = StatementFilter::blank(group_size); + + let groups = dummy_groups(group_size); + + // Should start with no pending statements. + assert_eq!(tracker.pending_statements_for(validator_index, candidate_hash), None); + assert_eq!(tracker.all_pending_statements_for(validator_index), vec![]); + + // Add the candidate as backed. + tracker.add_backed_candidate( + &session_topology, + candidate_hash, + group_index, + local_knowledge.clone(), + ); + + // Import statement for originator. + tracker + .import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: group_index, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + }, + }, + ManifestKind::Full, + validator_index, + ) + .ok() + .unwrap(); + tracker.manifest_sent_to(&groups, validator_index, candidate_hash, local_knowledge.clone()); + let statement = CompactStatement::Seconded(candidate_hash); + tracker.learned_fresh_statement(&groups, &session_topology, validator_index, &statement); + + // Import statement for counterparty. + tracker + .import_manifest( + &session_topology, + &groups, + candidate_hash, + 3, + ManifestSummary { + claimed_parent_hash: Hash::repeat_byte(0), + claimed_group_index: group_index, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + }, + }, + ManifestKind::Full, + counterparty, + ) + .ok() + .unwrap(); + tracker.manifest_sent_to(&groups, counterparty, candidate_hash, local_knowledge); + let statement = CompactStatement::Seconded(candidate_hash); + tracker.learned_fresh_statement(&groups, &session_topology, counterparty, &statement); + + // There should be pending statements now. + let statements = StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }; + assert_eq!( + tracker.pending_statements_for(validator_index, candidate_hash), + Some(statements.clone()) + ); + assert_eq!( + tracker.all_pending_statements_for(validator_index), + vec![(ValidatorIndex(0), CompactStatement::Seconded(candidate_hash))] + ); + assert_eq!( + tracker.pending_statements_for(counterparty, candidate_hash), + Some(statements.clone()) + ); + assert_eq!( + tracker.all_pending_statements_for(counterparty), + vec![(ValidatorIndex(0), CompactStatement::Seconded(candidate_hash))] + ); + + tracker.learned_fresh_statement(&groups, &session_topology, validator_index, &statement); + tracker.sent_or_received_direct_statement( + &groups, + validator_index, + counterparty, + &statement, + ); + + // There should be no pending statements now (for the counterparty). + assert_eq!( + tracker.pending_statements_for(counterparty, candidate_hash), + Some(StatementFilter::blank(group_size)) + ); + assert_eq!(tracker.all_pending_statements_for(counterparty), vec![]); + } +} diff --git a/polkadot/node/network/statement-distribution/src/vstaging/groups.rs b/polkadot/node/network/statement-distribution/src/vstaging/groups.rs new file mode 100644 index 0000000000000000000000000000000000000000..86321b30f220ebdeadab74c7c0164458bcf46e9a --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/vstaging/groups.rs @@ -0,0 +1,70 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A utility for tracking groups and their members within a session. + +use polkadot_node_primitives::minimum_votes; +use polkadot_primitives::vstaging::{GroupIndex, IndexedVec, ValidatorIndex}; + +use std::collections::HashMap; + +/// Validator groups within a session, plus some helpful indexing for +/// looking up groups by validator indices or authority discovery ID. +#[derive(Debug, Clone)] +pub struct Groups { + groups: IndexedVec>, + by_validator_index: HashMap, +} + +impl Groups { + /// Create a new [`Groups`] tracker with the groups and discovery keys + /// from the session. + pub fn new(groups: IndexedVec>) -> Self { + let mut by_validator_index = HashMap::new(); + + for (i, group) in groups.iter().enumerate() { + let index = GroupIndex(i as _); + for v in group { + by_validator_index.insert(*v, index); + } + } + + Groups { groups, by_validator_index } + } + + /// Access all the underlying groups. + pub fn all(&self) -> &IndexedVec> { + &self.groups + } + + /// Get the underlying group validators by group index. + pub fn get(&self, group_index: GroupIndex) -> Option<&[ValidatorIndex]> { + self.groups.get(group_index).map(|x| &x[..]) + } + + /// Get the backing group size and backing threshold. + pub fn get_size_and_backing_threshold( + &self, + group_index: GroupIndex, + ) -> Option<(usize, usize)> { + self.get(group_index).map(|g| (g.len(), minimum_votes(g.len()))) + } + + /// Get the group index for a validator by index. + pub fn by_validator_index(&self, validator_index: ValidatorIndex) -> Option { + self.by_validator_index.get(&validator_index).map(|x| *x) + } +} diff --git a/polkadot/node/network/statement-distribution/src/vstaging/mod.rs b/polkadot/node/network/statement-distribution/src/vstaging/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..03af4ce81598eaf79ab985c7fb85cdf9232553d0 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/vstaging/mod.rs @@ -0,0 +1,2810 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implementation of the v2 statement distribution protocol, +//! designed for asynchronous backing. + +use polkadot_node_network_protocol::{ + self as net_protocol, + grid_topology::SessionGridTopology, + peer_set::ValidationVersion, + request_response::{ + incoming::OutgoingResponse, + vstaging::{AttestedCandidateRequest, AttestedCandidateResponse}, + IncomingRequest, IncomingRequestReceiver, Requests, + MAX_PARALLEL_ATTESTED_CANDIDATE_REQUESTS, + }, + vstaging::{self as protocol_vstaging, StatementFilter}, + IfDisconnected, PeerId, UnifiedReputationChange as Rep, Versioned, View, +}; +use polkadot_node_primitives::{ + SignedFullStatementWithPVD, StatementWithPVD as FullStatementWithPVD, +}; +use polkadot_node_subsystem::{ + messages::{ + CandidateBackingMessage, HypotheticalCandidate, HypotheticalFrontierRequest, + NetworkBridgeEvent, NetworkBridgeTxMessage, ProspectiveParachainsMessage, + }, + overseer, ActivatedLeaf, +}; +use polkadot_node_subsystem_util::{ + backing_implicit_view::View as ImplicitView, reputation::ReputationAggregator, + runtime::ProspectiveParachainsMode, +}; +use polkadot_primitives::vstaging::{ + AuthorityDiscoveryId, CandidateHash, CompactStatement, CoreIndex, CoreState, GroupIndex, + GroupRotationInfo, Hash, Id as ParaId, IndexedVec, SessionIndex, SessionInfo, SignedStatement, + SigningContext, UncheckedSignedStatement, ValidatorId, ValidatorIndex, +}; + +use sp_keystore::KeystorePtr; + +use fatality::Nested; +use futures::{ + channel::{mpsc, oneshot}, + stream::FuturesUnordered, + SinkExt, StreamExt, +}; + +use std::{ + collections::{ + hash_map::{Entry, HashMap}, + HashSet, + }, + time::{Duration, Instant}, +}; + +use crate::{ + error::{JfyiError, JfyiErrorResult}, + LOG_TARGET, +}; +use candidates::{BadAdvertisement, Candidates, PostConfirmation}; +use cluster::{Accept as ClusterAccept, ClusterTracker, RejectIncoming as ClusterRejectIncoming}; +use grid::GridTracker; +use groups::Groups; +use requests::{CandidateIdentifier, RequestProperties}; +use statement_store::{StatementOrigin, StatementStore}; + +pub use requests::{RequestManager, ResponseManager, UnhandledResponse}; + +mod candidates; +mod cluster; +mod grid; +mod groups; +mod requests; +mod statement_store; + +#[cfg(test)] +mod tests; + +const COST_UNEXPECTED_STATEMENT: Rep = Rep::CostMinor("Unexpected Statement"); +const COST_UNEXPECTED_STATEMENT_MISSING_KNOWLEDGE: Rep = + Rep::CostMinor("Unexpected Statement, missing knowledge for relay parent"); +const COST_EXCESSIVE_SECONDED: Rep = Rep::CostMinor("Sent Excessive `Seconded` Statements"); + +const COST_UNEXPECTED_MANIFEST_MISSING_KNOWLEDGE: Rep = + Rep::CostMinor("Unexpected Manifest, missing knowlege for relay parent"); +const COST_UNEXPECTED_MANIFEST_DISALLOWED: Rep = + Rep::CostMinor("Unexpected Manifest, Peer Disallowed"); +const COST_CONFLICTING_MANIFEST: Rep = Rep::CostMajor("Manifest conflicts with previous"); +const COST_INSUFFICIENT_MANIFEST: Rep = + Rep::CostMajor("Manifest statements insufficient to back candidate"); +const COST_MALFORMED_MANIFEST: Rep = Rep::CostMajor("Manifest is malformed"); +const COST_UNEXPECTED_ACKNOWLEDGEMENT_UNKNOWN_CANDIDATE: Rep = + Rep::CostMinor("Unexpected acknowledgement, unknown candidate"); + +const COST_INVALID_SIGNATURE: Rep = Rep::CostMajor("Invalid Statement Signature"); +const COST_IMPROPERLY_DECODED_RESPONSE: Rep = + Rep::CostMajor("Improperly Encoded Candidate Response"); +const COST_INVALID_RESPONSE: Rep = Rep::CostMajor("Invalid Candidate Response"); +const COST_UNREQUESTED_RESPONSE_STATEMENT: Rep = + Rep::CostMajor("Un-requested Statement In Response"); +const COST_INACCURATE_ADVERTISEMENT: Rep = + Rep::CostMajor("Peer advertised a candidate inaccurately"); + +const COST_INVALID_REQUEST: Rep = Rep::CostMajor("Peer sent unparsable request"); +const COST_INVALID_REQUEST_BITFIELD_SIZE: Rep = + Rep::CostMajor("Attested candidate request bitfields have wrong size"); +const COST_UNEXPECTED_REQUEST: Rep = Rep::CostMajor("Unexpected attested candidate request"); + +const BENEFIT_VALID_RESPONSE: Rep = Rep::BenefitMajor("Peer Answered Candidate Request"); +const BENEFIT_VALID_STATEMENT: Rep = Rep::BenefitMajor("Peer provided a valid statement"); +const BENEFIT_VALID_STATEMENT_FIRST: Rep = + Rep::BenefitMajorFirst("Peer was the first to provide a given valid statement"); + +/// The amount of time to wait before retrying when the node sends a request and it is dropped. +pub(crate) const REQUEST_RETRY_DELAY: Duration = Duration::from_secs(1); + +struct PerRelayParentState { + local_validator: Option, + statement_store: StatementStore, + availability_cores: Vec, + group_rotation_info: GroupRotationInfo, + seconding_limit: usize, + session: SessionIndex, +} + +// per-relay-parent local validator state. +struct LocalValidatorState { + // The index of the validator. + index: ValidatorIndex, + // our validator group + group: GroupIndex, + // the assignment of our validator group, if any. + assignment: Option, + // the 'direct-in-group' communication at this relay-parent. + cluster_tracker: ClusterTracker, + // the grid-level communication at this relay-parent. + grid_tracker: GridTracker, +} + +#[derive(Debug)] +struct PerSessionState { + session_info: SessionInfo, + groups: Groups, + authority_lookup: HashMap, + // is only `None` in the time between seeing a session and + // getting the topology from the gossip-support subsystem + grid_view: Option, + local_validator: Option, +} + +impl PerSessionState { + fn new(session_info: SessionInfo, keystore: &KeystorePtr) -> Self { + let groups = Groups::new(session_info.validator_groups.clone()); + let mut authority_lookup = HashMap::new(); + for (i, ad) in session_info.discovery_keys.iter().cloned().enumerate() { + authority_lookup.insert(ad, ValidatorIndex(i as _)); + } + + let local_validator = polkadot_node_subsystem_util::signing_key_and_index( + session_info.validators.iter(), + keystore, + ); + + PerSessionState { + session_info, + groups, + authority_lookup, + grid_view: None, + local_validator: local_validator.map(|(_key, index)| index), + } + } + + fn supply_topology(&mut self, topology: &SessionGridTopology) { + let grid_view = grid::build_session_topology( + self.session_info.validator_groups.iter(), + topology, + self.local_validator, + ); + + self.grid_view = Some(grid_view); + } +} + +pub(crate) struct State { + /// The utility for managing the implicit and explicit views in a consistent way. + /// + /// We only feed leaves which have prospective parachains enabled to this view. + implicit_view: ImplicitView, + candidates: Candidates, + per_relay_parent: HashMap, + per_session: HashMap, + peers: HashMap, + keystore: KeystorePtr, + authorities: HashMap, + request_manager: RequestManager, + response_manager: ResponseManager, +} + +impl State { + /// Create a new state. + pub(crate) fn new(keystore: KeystorePtr) -> Self { + State { + implicit_view: Default::default(), + candidates: Default::default(), + per_relay_parent: HashMap::new(), + per_session: HashMap::new(), + peers: HashMap::new(), + keystore, + authorities: HashMap::new(), + request_manager: RequestManager::new(), + response_manager: ResponseManager::new(), + } + } + + pub(crate) fn request_and_response_managers( + &mut self, + ) -> (&mut RequestManager, &mut ResponseManager) { + (&mut self.request_manager, &mut self.response_manager) + } +} + +// For the provided validator index, if there is a connected peer controlling the given authority +// ID, then return that peer's `PeerId`. +fn connected_validator_peer( + authorities: &HashMap, + per_session: &PerSessionState, + validator_index: ValidatorIndex, +) -> Option { + per_session + .session_info + .discovery_keys + .get(validator_index.0 as usize) + .and_then(|k| authorities.get(k)) + .map(|p| *p) +} + +struct PeerState { + view: View, + implicit_view: HashSet, + discovery_ids: Option>, +} + +impl PeerState { + // Update the view, returning a vector of implicit relay-parents which weren't previously + // part of the view. + fn update_view(&mut self, new_view: View, local_implicit: &ImplicitView) -> Vec { + let next_implicit = new_view + .iter() + .flat_map(|x| local_implicit.known_allowed_relay_parents_under(x, None)) + .flatten() + .cloned() + .collect::>(); + + let fresh_implicit = next_implicit + .iter() + .filter(|x| !self.implicit_view.contains(x)) + .cloned() + .collect(); + + self.view = new_view; + self.implicit_view = next_implicit; + + fresh_implicit + } + + // Attempt to reconcile the view with new information about the implicit relay parents + // under an active leaf. + fn reconcile_active_leaf(&mut self, leaf_hash: Hash, implicit: &[Hash]) -> Vec { + if !self.view.contains(&leaf_hash) { + return Vec::new() + } + + let mut v = Vec::with_capacity(implicit.len()); + for i in implicit { + if self.implicit_view.insert(*i) { + v.push(*i); + } + } + v + } + + // Whether we know that a peer knows a relay-parent. + // The peer knows the relay-parent if it is either implicit or explicit + // in their view. However, if it is implicit via an active-leaf we don't + // recognize, we will not accurately be able to recognize them as 'knowing' + // the relay-parent. + fn knows_relay_parent(&self, relay_parent: &Hash) -> bool { + self.implicit_view.contains(relay_parent) || self.view.contains(relay_parent) + } + + fn is_authority(&self, authority_id: &AuthorityDiscoveryId) -> bool { + self.discovery_ids.as_ref().map_or(false, |x| x.contains(authority_id)) + } + + fn iter_known_discovery_ids(&self) -> impl Iterator { + self.discovery_ids.as_ref().into_iter().flatten() + } +} + +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +pub(crate) async fn handle_network_update( + ctx: &mut Context, + state: &mut State, + update: NetworkBridgeEvent, + reputation: &mut ReputationAggregator, +) { + match update { + NetworkBridgeEvent::PeerConnected(peer_id, role, protocol_version, mut authority_ids) => { + gum::trace!(target: LOG_TARGET, ?peer_id, ?role, ?protocol_version, "Peer connected"); + + if protocol_version != ValidationVersion::VStaging.into() { + return + } + + if let Some(ref mut authority_ids) = authority_ids { + authority_ids.retain(|a| match state.authorities.entry(a.clone()) { + Entry::Vacant(e) => { + e.insert(peer_id); + true + }, + Entry::Occupied(e) => { + gum::trace!( + target: LOG_TARGET, + authority_id = ?a, + existing_peer = ?e.get(), + new_peer = ?peer_id, + "Ignoring new peer with duplicate authority ID as a bearer of that identity" + ); + + false + }, + }); + } + + state.peers.insert( + peer_id, + PeerState { + view: View::default(), + implicit_view: HashSet::new(), + discovery_ids: authority_ids, + }, + ); + }, + NetworkBridgeEvent::PeerDisconnected(peer_id) => { + if let Some(p) = state.peers.remove(&peer_id) { + for discovery_key in p.discovery_ids.into_iter().flatten() { + state.authorities.remove(&discovery_key); + } + } + }, + NetworkBridgeEvent::NewGossipTopology(topology) => { + let new_session_index = topology.session; + let new_topology = topology.topology; + + if let Some(per_session) = state.per_session.get_mut(&new_session_index) { + per_session.supply_topology(&new_topology); + } + + // TODO [https://github.com/paritytech/polkadot/issues/6194] + // technically, we should account for the fact that the session topology might + // come late, and for all relay-parents with this session, send all grid peers + // any `BackedCandidateInv` messages they might need. + // + // in practice, this is a small issue & the API of receiving topologies could + // be altered to fix it altogether. + }, + NetworkBridgeEvent::PeerMessage(peer_id, message) => match message { + net_protocol::StatementDistributionMessage::V1(_) => return, + net_protocol::StatementDistributionMessage::VStaging( + protocol_vstaging::StatementDistributionMessage::V1Compatibility(_), + ) => return, + net_protocol::StatementDistributionMessage::VStaging( + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) => + handle_incoming_statement(ctx, state, peer_id, relay_parent, statement, reputation) + .await, + net_protocol::StatementDistributionMessage::VStaging( + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(inner), + ) => handle_incoming_manifest(ctx, state, peer_id, inner, reputation).await, + net_protocol::StatementDistributionMessage::VStaging( + protocol_vstaging::StatementDistributionMessage::BackedCandidateKnown(inner), + ) => handle_incoming_acknowledgement(ctx, state, peer_id, inner, reputation).await, + }, + NetworkBridgeEvent::PeerViewChange(peer_id, view) => + handle_peer_view_update(ctx, state, peer_id, view).await, + NetworkBridgeEvent::OurViewChange(_view) => { + // handled by `handle_activated_leaf` + }, + NetworkBridgeEvent::UpdatedAuthorityIds(peer_id, authority_ids) => { + gum::trace!( + target: LOG_TARGET, + ?peer_id, + ?authority_ids, + "Updated `AuthorityDiscoveryId`s" + ); + + // Remove the authority IDs which were previously mapped to the peer + // but aren't part of the new set. + state.authorities.retain(|a, p| p != &peer_id || authority_ids.contains(a)); + + // Map the new authority IDs to the peer. + for a in authority_ids.iter().cloned() { + state.authorities.insert(a, peer_id); + } + + if let Some(peer_state) = state.peers.get_mut(&peer_id) { + peer_state.discovery_ids = Some(authority_ids); + } + }, + } +} + +/// If there is a new leaf, this should only be called for leaves which support +/// prospective parachains. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +pub(crate) async fn handle_active_leaves_update( + ctx: &mut Context, + state: &mut State, + activated: &ActivatedLeaf, + leaf_mode: ProspectiveParachainsMode, +) -> JfyiErrorResult<()> { + let seconding_limit = match leaf_mode { + ProspectiveParachainsMode::Disabled => return Ok(()), + ProspectiveParachainsMode::Enabled { max_candidate_depth, .. } => max_candidate_depth + 1, + }; + + state + .implicit_view + .activate_leaf(ctx.sender(), activated.hash) + .await + .map_err(JfyiError::ActivateLeafFailure)?; + + let new_relay_parents = + state.implicit_view.all_allowed_relay_parents().cloned().collect::>(); + for new_relay_parent in new_relay_parents.iter().cloned() { + if state.per_relay_parent.contains_key(&new_relay_parent) { + continue + } + + // New leaf: fetch info from runtime API and initialize + // `per_relay_parent`. + + let session_index = polkadot_node_subsystem_util::request_session_index_for_child( + new_relay_parent, + ctx.sender(), + ) + .await + .await + .map_err(JfyiError::RuntimeApiUnavailable)? + .map_err(JfyiError::FetchSessionIndex)?; + + let availability_cores = polkadot_node_subsystem_util::request_availability_cores( + new_relay_parent, + ctx.sender(), + ) + .await + .await + .map_err(JfyiError::RuntimeApiUnavailable)? + .map_err(JfyiError::FetchAvailabilityCores)?; + + let group_rotation_info = + polkadot_node_subsystem_util::request_validator_groups(new_relay_parent, ctx.sender()) + .await + .await + .map_err(JfyiError::RuntimeApiUnavailable)? + .map_err(JfyiError::FetchValidatorGroups)? + .1; + + if !state.per_session.contains_key(&session_index) { + let session_info = polkadot_node_subsystem_util::request_session_info( + new_relay_parent, + session_index, + ctx.sender(), + ) + .await + .await + .map_err(JfyiError::RuntimeApiUnavailable)? + .map_err(JfyiError::FetchSessionInfo)?; + + let session_info = match session_info { + None => { + gum::warn!( + target: LOG_TARGET, + relay_parent = ?new_relay_parent, + "No session info available for current session" + ); + + continue + }, + Some(s) => s, + }; + + state + .per_session + .insert(session_index, PerSessionState::new(session_info, &state.keystore)); + } + + let per_session = state + .per_session + .get(&session_index) + .expect("either existed or just inserted; qed"); + + let local_validator = per_session.local_validator.and_then(|v| { + find_local_validator_state( + v, + &per_session.groups, + &availability_cores, + &group_rotation_info, + seconding_limit, + ) + }); + + state.per_relay_parent.insert( + new_relay_parent, + PerRelayParentState { + local_validator, + statement_store: StatementStore::new(&per_session.groups), + availability_cores, + group_rotation_info, + seconding_limit, + session: session_index, + }, + ); + } + + // Reconcile all peers' views with the active leaf and any relay parents + // it implies. If they learned about the block before we did, this reconciliation will give + // non-empty results and we should send them messages concerning all activated relay-parents. + { + let mut update_peers = Vec::new(); + for (peer, peer_state) in state.peers.iter_mut() { + let fresh = peer_state.reconcile_active_leaf(activated.hash, &new_relay_parents); + if !fresh.is_empty() { + update_peers.push((*peer, fresh)); + } + } + + for (peer, fresh) in update_peers { + for fresh_relay_parent in fresh { + send_peer_messages_for_relay_parent(ctx, state, peer, fresh_relay_parent).await; + } + } + } + + new_leaf_fragment_tree_updates(ctx, state, activated.hash).await; + + Ok(()) +} + +fn find_local_validator_state( + validator_index: ValidatorIndex, + groups: &Groups, + availability_cores: &[CoreState], + group_rotation_info: &GroupRotationInfo, + seconding_limit: usize, +) -> Option { + if groups.all().is_empty() { + return None + } + + let our_group = groups.by_validator_index(validator_index)?; + + // note: this won't work well for on-demand parachains because it only works + // when core assignments to paras are static throughout the session. + + let core = group_rotation_info.core_for_group(our_group, availability_cores.len()); + let para = availability_cores.get(core.0 as usize).and_then(|c| c.para_id()); + let group_validators = groups.get(our_group)?.to_owned(); + + Some(LocalValidatorState { + index: validator_index, + group: our_group, + assignment: para, + cluster_tracker: ClusterTracker::new(group_validators, seconding_limit) + .expect("group is non-empty because we are in it; qed"), + grid_tracker: GridTracker::default(), + }) +} + +pub(crate) fn handle_deactivate_leaves(state: &mut State, leaves: &[Hash]) { + // deactivate the leaf in the implicit view. + for leaf in leaves { + state.implicit_view.deactivate_leaf(*leaf); + } + + let relay_parents = state.implicit_view.all_allowed_relay_parents().collect::>(); + + // fast exit for no-op. + if relay_parents.len() == state.per_relay_parent.len() { + return + } + + // clean up per-relay-parent data based on everything removed. + state.per_relay_parent.retain(|r, _| relay_parents.contains(r)); + + // Clean up all requests + for leaf in leaves { + state.request_manager.remove_by_relay_parent(*leaf); + } + + state.candidates.on_deactivate_leaves(&leaves, |h| relay_parents.contains(h)); + + // clean up sessions based on everything remaining. + let sessions: HashSet<_> = state.per_relay_parent.values().map(|r| r.session).collect(); + state.per_session.retain(|s, _| sessions.contains(s)); +} + +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn handle_peer_view_update( + ctx: &mut Context, + state: &mut State, + peer: PeerId, + new_view: View, +) { + let fresh_implicit = { + let peer_data = match state.peers.get_mut(&peer) { + None => return, + Some(p) => p, + }; + + peer_data.update_view(new_view, &state.implicit_view) + }; + + for new_relay_parent in fresh_implicit { + send_peer_messages_for_relay_parent(ctx, state, peer, new_relay_parent).await; + } +} + +// Returns an iterator over known validator indices, given an iterator over discovery IDs +// and a mapping from discovery IDs to validator indices. +fn find_validator_ids<'a>( + known_discovery_ids: impl IntoIterator, + discovery_mapping: impl Fn(&AuthorityDiscoveryId) -> Option<&'a ValidatorIndex>, +) -> impl Iterator { + known_discovery_ids.into_iter().filter_map(discovery_mapping).cloned() +} + +/// Send a peer, apparently just becoming aware of a relay-parent, all messages +/// concerning that relay-parent. +/// +/// In particular, we send all statements pertaining to our common cluster, +/// as well as all manifests, acknowledgements, or other grid statements. +/// +/// Note that due to the way we handle views, our knowledge of peers' relay parents +/// may "oscillate" with relay parents repeatedly leaving and entering the +/// view of a peer based on the implicit view of active leaves. +/// +/// This function is designed to be cheap and not to send duplicate messages in repeated +/// cases. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn send_peer_messages_for_relay_parent( + ctx: &mut Context, + state: &mut State, + peer: PeerId, + relay_parent: Hash, +) { + let peer_data = match state.peers.get_mut(&peer) { + None => return, + Some(p) => p, + }; + + let relay_parent_state = match state.per_relay_parent.get_mut(&relay_parent) { + None => return, + Some(s) => s, + }; + + let per_session_state = match state.per_session.get(&relay_parent_state.session) { + None => return, + Some(s) => s, + }; + + for validator_id in find_validator_ids(peer_data.iter_known_discovery_ids(), |a| { + per_session_state.authority_lookup.get(a) + }) { + if let Some(local_validator_state) = relay_parent_state.local_validator.as_mut() { + send_pending_cluster_statements( + ctx, + relay_parent, + &peer, + validator_id, + &mut local_validator_state.cluster_tracker, + &state.candidates, + &relay_parent_state.statement_store, + ) + .await; + } + + send_pending_grid_messages( + ctx, + relay_parent, + &peer, + validator_id, + &per_session_state.groups, + relay_parent_state, + &state.candidates, + ) + .await; + } +} + +fn pending_statement_network_message( + statement_store: &StatementStore, + relay_parent: Hash, + peer: &PeerId, + originator: ValidatorIndex, + compact: CompactStatement, +) -> Option<(Vec, net_protocol::VersionedValidationProtocol)> { + statement_store + .validator_statement(originator, compact) + .map(|s| s.as_unchecked().clone()) + .map(|signed| { + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, signed) + }) + .map(|msg| (vec![*peer], Versioned::VStaging(msg).into())) +} + +/// Send a peer all pending cluster statements for a relay parent. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn send_pending_cluster_statements( + ctx: &mut Context, + relay_parent: Hash, + peer_id: &PeerId, + peer_validator_id: ValidatorIndex, + cluster_tracker: &mut ClusterTracker, + candidates: &Candidates, + statement_store: &StatementStore, +) { + let pending_statements = cluster_tracker.pending_statements_for(peer_validator_id); + let network_messages = pending_statements + .into_iter() + .filter_map(|(originator, compact)| { + if !candidates.is_confirmed(compact.candidate_hash()) { + return None + } + + let res = pending_statement_network_message( + &statement_store, + relay_parent, + peer_id, + originator, + compact.clone(), + ); + + if res.is_some() { + cluster_tracker.note_sent(peer_validator_id, originator, compact); + } + + res + }) + .collect::>(); + + if network_messages.is_empty() { + return + } + + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessages(network_messages)) + .await; +} + +/// Send a peer all pending grid messages / acknowledgements / follow up statements +/// upon learning about a new relay parent. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn send_pending_grid_messages( + ctx: &mut Context, + relay_parent: Hash, + peer_id: &PeerId, + peer_validator_id: ValidatorIndex, + groups: &Groups, + relay_parent_state: &mut PerRelayParentState, + candidates: &Candidates, +) { + let pending_manifests = { + let local_validator = match relay_parent_state.local_validator.as_mut() { + None => return, + Some(l) => l, + }; + + let grid_tracker = &mut local_validator.grid_tracker; + grid_tracker.pending_manifests_for(peer_validator_id) + }; + + let mut messages: Vec<(Vec, net_protocol::VersionedValidationProtocol)> = Vec::new(); + for (candidate_hash, kind) in pending_manifests { + let confirmed_candidate = match candidates.get_confirmed(&candidate_hash) { + None => continue, // sanity + Some(c) => c, + }; + + let group_index = confirmed_candidate.group_index(); + + let local_knowledge = { + let group_size = match groups.get(group_index) { + None => return, // sanity + Some(x) => x.len(), + }; + + local_knowledge_filter( + group_size, + group_index, + candidate_hash, + &relay_parent_state.statement_store, + ) + }; + + match kind { + grid::ManifestKind::Full => { + let manifest = protocol_vstaging::BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index, + para_id: confirmed_candidate.para_id(), + parent_head_data_hash: confirmed_candidate.parent_head_data_hash(), + statement_knowledge: local_knowledge.clone(), + }; + + let grid = &mut relay_parent_state + .local_validator + .as_mut() + .expect("determined to be some earlier in this function; qed") + .grid_tracker; + + grid.manifest_sent_to( + groups, + peer_validator_id, + candidate_hash, + local_knowledge.clone(), + ); + + messages.push(( + vec![*peer_id], + Versioned::VStaging( + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest, + ), + ) + .into(), + )); + }, + grid::ManifestKind::Acknowledgement => { + messages.extend(acknowledgement_and_statement_messages( + *peer_id, + peer_validator_id, + groups, + relay_parent_state, + relay_parent, + group_index, + candidate_hash, + local_knowledge, + )); + }, + } + } + + // Send all remaining pending grid statements for a validator, not just + // those for the acknowledgements we've sent. + // + // otherwise, we might receive statements while the grid peer is "out of view" and then + // not send them when they get back "in view". problem! + { + let grid_tracker = &mut relay_parent_state + .local_validator + .as_mut() + .expect("checked earlier; qed") + .grid_tracker; + + let pending_statements = grid_tracker.all_pending_statements_for(peer_validator_id); + + let extra_statements = + pending_statements.into_iter().filter_map(|(originator, compact)| { + let res = pending_statement_network_message( + &relay_parent_state.statement_store, + relay_parent, + peer_id, + originator, + compact.clone(), + ); + + if res.is_some() { + grid_tracker.sent_or_received_direct_statement( + groups, + originator, + peer_validator_id, + &compact, + ); + } + + res + }); + + messages.extend(extra_statements); + } + + if messages.is_empty() { + return + } + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessages(messages)).await; +} + +// Imports a locally originating statement and distributes it to peers. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +pub(crate) async fn share_local_statement( + ctx: &mut Context, + state: &mut State, + relay_parent: Hash, + statement: SignedFullStatementWithPVD, + reputation: &mut ReputationAggregator, +) -> JfyiErrorResult<()> { + let per_relay_parent = match state.per_relay_parent.get_mut(&relay_parent) { + None => return Err(JfyiError::InvalidShare), + Some(x) => x, + }; + + gum::debug!( + target: LOG_TARGET, + statement = ?statement.payload().to_compact(), + "Sharing Statement", + ); + + let per_session = match state.per_session.get(&per_relay_parent.session) { + Some(s) => s, + None => return Ok(()), + }; + + let (local_index, local_assignment, local_group) = + match per_relay_parent.local_validator.as_ref() { + None => return Err(JfyiError::InvalidShare), + Some(l) => (l.index, l.assignment, l.group), + }; + + // Two possibilities: either the statement is `Seconded` or we already + // have the candidate. Sanity: check the para-id is valid. + let expected = match statement.payload() { + FullStatementWithPVD::Seconded(ref c, _) => + Some((c.descriptor().para_id, c.descriptor().relay_parent)), + FullStatementWithPVD::Valid(hash) => + state.candidates.get_confirmed(&hash).map(|c| (c.para_id(), c.relay_parent())), + }; + + let is_seconded = match statement.payload() { + FullStatementWithPVD::Seconded(_, _) => true, + FullStatementWithPVD::Valid(_) => false, + }; + + let (expected_para, expected_relay_parent) = match expected { + None => return Err(JfyiError::InvalidShare), + Some(x) => x, + }; + + if local_index != statement.validator_index() { + return Err(JfyiError::InvalidShare) + } + + if is_seconded && + per_relay_parent.statement_store.seconded_count(&local_index) == + per_relay_parent.seconding_limit + { + gum::warn!( + target: LOG_TARGET, + limit = ?per_relay_parent.seconding_limit, + "Local node has issued too many `Seconded` statements", + ); + return Err(JfyiError::InvalidShare) + } + + if local_assignment != Some(expected_para) || relay_parent != expected_relay_parent { + return Err(JfyiError::InvalidShare) + } + + let mut post_confirmation = None; + + // Insert candidate if unknown + more sanity checks. + let compact_statement = { + let compact_statement = FullStatementWithPVD::signed_to_compact(statement.clone()); + let candidate_hash = CandidateHash(*statement.payload().candidate_hash()); + + if let FullStatementWithPVD::Seconded(ref c, ref pvd) = statement.payload() { + post_confirmation = state.candidates.confirm_candidate( + candidate_hash, + c.clone(), + pvd.clone(), + local_group, + ); + }; + + match per_relay_parent.statement_store.insert( + &per_session.groups, + compact_statement.clone(), + StatementOrigin::Local, + ) { + Ok(false) | Err(_) => { + gum::warn!( + target: LOG_TARGET, + statement = ?compact_statement.payload(), + "Candidate backing issued redundant statement?", + ); + return Err(JfyiError::InvalidShare) + }, + Ok(true) => {}, + } + + { + let l = per_relay_parent.local_validator.as_mut().expect("checked above; qed"); + l.cluster_tracker.note_issued(local_index, compact_statement.payload().clone()); + } + + if let Some(ref session_topology) = per_session.grid_view { + let l = per_relay_parent.local_validator.as_mut().expect("checked above; qed"); + l.grid_tracker.learned_fresh_statement( + &per_session.groups, + session_topology, + local_index, + &compact_statement.payload(), + ); + } + + compact_statement + }; + + // send the compact version of the statement to any peers which need it. + circulate_statement( + ctx, + relay_parent, + per_relay_parent, + per_session, + &state.candidates, + &state.authorities, + &state.peers, + compact_statement, + ) + .await; + + if let Some(post_confirmation) = post_confirmation { + apply_post_confirmation(ctx, state, post_confirmation, reputation).await; + } + + Ok(()) +} + +// two kinds of targets: those in our 'cluster' (currently just those in the same group), +// and those we are propagating to through the grid. +#[derive(Debug)] +enum DirectTargetKind { + Cluster, + Grid, +} + +// Circulates a compact statement to all peers who need it: those in the current group of the +// local validator and grid peers which have already indicated that they know the candidate as +// backed. +// +// We only circulate statements for which we have the confirmed candidate, even to the local group. +// +// The group index which is _canonically assigned_ to this parachain must be +// specified already. This function should not be used when the candidate receipt and +// therefore the canonical group for the parachain is unknown. +// +// preconditions: the candidate entry exists in the state under the relay parent +// and the statement has already been imported into the entry. If this is a `Valid` +// statement, then there must be at least one `Seconded` statement. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn circulate_statement( + ctx: &mut Context, + relay_parent: Hash, + relay_parent_state: &mut PerRelayParentState, + per_session: &PerSessionState, + candidates: &Candidates, + authorities: &HashMap, + peers: &HashMap, + statement: SignedStatement, +) { + let session_info = &per_session.session_info; + + let candidate_hash = *statement.payload().candidate_hash(); + + let compact_statement = statement.payload().clone(); + let is_confirmed = candidates.is_confirmed(&candidate_hash); + + let originator = statement.validator_index(); + let (local_validator, targets) = { + let local_validator = match relay_parent_state.local_validator.as_mut() { + Some(v) => v, + None => return, // sanity: nothing to propagate if not a validator. + }; + + let statement_group = per_session.groups.by_validator_index(originator); + + // We're not meant to circulate statements in the cluster until we have the confirmed + // candidate. + let cluster_relevant = Some(local_validator.group) == statement_group; + let cluster_targets = if is_confirmed && cluster_relevant { + Some( + local_validator + .cluster_tracker + .targets() + .iter() + .filter(|&&v| { + local_validator + .cluster_tracker + .can_send(v, originator, compact_statement.clone()) + .is_ok() + }) + .filter(|&v| v != &local_validator.index) + .map(|v| (*v, DirectTargetKind::Cluster)), + ) + } else { + None + }; + + let grid_targets = local_validator + .grid_tracker + .direct_statement_targets(&per_session.groups, originator, &compact_statement) + .into_iter() + .filter(|v| !cluster_relevant || !local_validator.cluster_tracker.targets().contains(v)) + .map(|v| (v, DirectTargetKind::Grid)); + + let targets = cluster_targets + .into_iter() + .flatten() + .chain(grid_targets) + .filter_map(|(v, k)| { + session_info.discovery_keys.get(v.0 as usize).map(|a| (v, a.clone(), k)) + }) + .collect::>(); + + (local_validator, targets) + }; + + let mut statement_to = Vec::new(); + for (target, authority_id, kind) in targets { + // Find peer ID based on authority ID, and also filter to connected. + let peer_id: PeerId = match authorities.get(&authority_id) { + Some(p) if peers.get(p).map_or(false, |p| p.knows_relay_parent(&relay_parent)) => *p, + None | Some(_) => continue, + }; + + match kind { + DirectTargetKind::Cluster => { + // At this point, all peers in the cluster should 'know' + // the candidate, so we don't expect for this to fail. + if let Ok(()) = local_validator.cluster_tracker.can_send( + target, + originator, + compact_statement.clone(), + ) { + local_validator.cluster_tracker.note_sent( + target, + originator, + compact_statement.clone(), + ); + statement_to.push(peer_id); + } + }, + DirectTargetKind::Grid => { + statement_to.push(peer_id); + local_validator.grid_tracker.sent_or_received_direct_statement( + &per_session.groups, + originator, + target, + &compact_statement, + ); + }, + } + } + + // ship off the network messages to the network bridge. + if !statement_to.is_empty() { + gum::debug!( + target: LOG_TARGET, + ?compact_statement, + n_peers = ?statement_to.len(), + "Sending statement to peers", + ); + + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + statement_to, + Versioned::VStaging(protocol_vstaging::StatementDistributionMessage::Statement( + relay_parent, + statement.as_unchecked().clone(), + )) + .into(), + )) + .await; + } +} +/// Check a statement signature under this parent hash. +fn check_statement_signature( + session_index: SessionIndex, + validators: &IndexedVec, + relay_parent: Hash, + statement: UncheckedSignedStatement, +) -> std::result::Result { + let signing_context = SigningContext { session_index, parent_hash: relay_parent }; + + validators + .get(statement.unchecked_validator_index()) + .ok_or_else(|| statement.clone()) + .and_then(|v| statement.try_into_checked(&signing_context, v)) +} + +/// Modify the reputation of a peer based on its behavior. +async fn modify_reputation( + reputation: &mut ReputationAggregator, + sender: &mut impl overseer::StatementDistributionSenderTrait, + peer: PeerId, + rep: Rep, +) { + reputation.modify(sender, peer, rep).await; +} + +/// Handle an incoming statement. +/// +/// This checks whether the sender is allowed to send the statement, +/// either via the cluster or the grid. +/// +/// This also checks the signature of the statement. +/// If the statement is fresh, this function guarantees that after completion +/// - The statement is re-circulated to all relevant peers in both the cluster and the grid +/// - If the candidate is out-of-cluster and is backable and importable, all statements about the +/// candidate have been sent to backing +/// - If the candidate is in-cluster and is importable, the statement has been sent to backing +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn handle_incoming_statement( + ctx: &mut Context, + state: &mut State, + peer: PeerId, + relay_parent: Hash, + statement: UncheckedSignedStatement, + reputation: &mut ReputationAggregator, +) { + let peer_state = match state.peers.get(&peer) { + None => { + // sanity: should be impossible. + return + }, + Some(p) => p, + }; + + // Ensure we know the relay parent. + let per_relay_parent = match state.per_relay_parent.get_mut(&relay_parent) { + None => { + modify_reputation( + reputation, + ctx.sender(), + peer, + COST_UNEXPECTED_STATEMENT_MISSING_KNOWLEDGE, + ) + .await; + return + }, + Some(p) => p, + }; + + let per_session = match state.per_session.get(&per_relay_parent.session) { + None => { + gum::warn!( + target: LOG_TARGET, + session = ?per_relay_parent.session, + "Missing expected session info.", + ); + + return + }, + Some(s) => s, + }; + let session_info = &per_session.session_info; + + let local_validator = match per_relay_parent.local_validator.as_mut() { + None => { + // we shouldn't be receiving statements unless we're a validator + // this session. + modify_reputation(reputation, ctx.sender(), peer, COST_UNEXPECTED_STATEMENT).await; + return + }, + Some(l) => l, + }; + + let originator_group = + match per_session.groups.by_validator_index(statement.unchecked_validator_index()) { + Some(g) => g, + None => { + modify_reputation(reputation, ctx.sender(), peer, COST_UNEXPECTED_STATEMENT).await; + return + }, + }; + + let cluster_sender_index = { + // This block of code only returns `Some` when both the originator and + // the sending peer are in the cluster. + + let allowed_senders = local_validator + .cluster_tracker + .senders_for_originator(statement.unchecked_validator_index()); + + allowed_senders + .iter() + .filter_map(|i| session_info.discovery_keys.get(i.0 as usize).map(|ad| (*i, ad))) + .filter(|(_, ad)| peer_state.is_authority(ad)) + .map(|(i, _)| i) + .next() + }; + + let checked_statement = if let Some(cluster_sender_index) = cluster_sender_index { + match handle_cluster_statement( + relay_parent, + &mut local_validator.cluster_tracker, + per_relay_parent.session, + &per_session.session_info, + statement, + cluster_sender_index, + ) { + Ok(Some(s)) => s, + Ok(None) => return, + Err(rep) => { + modify_reputation(reputation, ctx.sender(), peer, rep).await; + return + }, + } + } else { + let grid_sender_index = local_validator + .grid_tracker + .direct_statement_providers( + &per_session.groups, + statement.unchecked_validator_index(), + statement.unchecked_payload(), + ) + .into_iter() + .filter_map(|i| session_info.discovery_keys.get(i.0 as usize).map(|ad| (i, ad))) + .filter(|(_, ad)| peer_state.is_authority(ad)) + .map(|(i, _)| i) + .next(); + + if let Some(grid_sender_index) = grid_sender_index { + match handle_grid_statement( + relay_parent, + &mut local_validator.grid_tracker, + per_relay_parent.session, + &per_session, + statement, + grid_sender_index, + ) { + Ok(s) => s, + Err(rep) => { + modify_reputation(reputation, ctx.sender(), peer, rep).await; + return + }, + } + } else { + // Not a cluster or grid peer. + modify_reputation(reputation, ctx.sender(), peer, COST_UNEXPECTED_STATEMENT).await; + return + } + }; + + let statement = checked_statement.payload().clone(); + let originator_index = checked_statement.validator_index(); + let candidate_hash = *checked_statement.payload().candidate_hash(); + + // Insert an unconfirmed candidate entry if needed. Note that if the candidate is already + // confirmed, this ensures that the assigned group of the originator matches the expected group + // of the parachain. + { + let res = state.candidates.insert_unconfirmed( + peer, + candidate_hash, + relay_parent, + originator_group, + None, + ); + + if let Err(BadAdvertisement) = res { + modify_reputation(reputation, ctx.sender(), peer, COST_UNEXPECTED_STATEMENT).await; + return + } + } + + let confirmed = state.candidates.get_confirmed(&candidate_hash); + let is_confirmed = state.candidates.is_confirmed(&candidate_hash); + if !is_confirmed { + // If the candidate is not confirmed, note that we should attempt + // to request it from the given peer. + let mut request_entry = + state + .request_manager + .get_or_insert(relay_parent, candidate_hash, originator_group); + + request_entry.add_peer(peer); + + // We only successfully accept statements from the grid on confirmed + // candidates, therefore this check only passes if the statement is from the cluster + request_entry.set_cluster_priority(); + } + + let was_fresh = match per_relay_parent.statement_store.insert( + &per_session.groups, + checked_statement.clone(), + StatementOrigin::Remote, + ) { + Err(statement_store::ValidatorUnknown) => { + // sanity: should never happen. + gum::warn!( + target: LOG_TARGET, + ?relay_parent, + validator_index = ?originator_index, + "Error - accepted message from unknown validator." + ); + + return + }, + Ok(known) => known, + }; + + if was_fresh { + modify_reputation(reputation, ctx.sender(), peer, BENEFIT_VALID_STATEMENT_FIRST).await; + let is_importable = state.candidates.is_importable(&candidate_hash); + + if let Some(ref session_topology) = per_session.grid_view { + local_validator.grid_tracker.learned_fresh_statement( + &per_session.groups, + session_topology, + local_validator.index, + &statement, + ); + } + + if let (true, &Some(confirmed)) = (is_importable, &confirmed) { + send_backing_fresh_statements( + ctx, + candidate_hash, + originator_group, + &relay_parent, + &mut *per_relay_parent, + confirmed, + per_session, + ) + .await; + } + + // We always circulate statements at this point. + circulate_statement( + ctx, + relay_parent, + per_relay_parent, + per_session, + &state.candidates, + &state.authorities, + &state.peers, + checked_statement, + ) + .await; + } else { + modify_reputation(reputation, ctx.sender(), peer, BENEFIT_VALID_STATEMENT).await; + } +} + +/// Checks whether a statement is allowed, whether the signature is accurate, +/// and importing into the cluster tracker if successful. +/// +/// if successful, this returns a checked signed statement if it should be imported +/// or otherwise an error indicating a reputational fault. +fn handle_cluster_statement( + relay_parent: Hash, + cluster_tracker: &mut ClusterTracker, + session: SessionIndex, + session_info: &SessionInfo, + statement: UncheckedSignedStatement, + cluster_sender_index: ValidatorIndex, +) -> Result, Rep> { + // additional cluster checks. + let should_import = { + match cluster_tracker.can_receive( + cluster_sender_index, + statement.unchecked_validator_index(), + statement.unchecked_payload().clone(), + ) { + Ok(ClusterAccept::Ok) => true, + Ok(ClusterAccept::WithPrejudice) => false, + Err(ClusterRejectIncoming::ExcessiveSeconded) => return Err(COST_EXCESSIVE_SECONDED), + Err(ClusterRejectIncoming::CandidateUnknown | ClusterRejectIncoming::Duplicate) => + return Err(COST_UNEXPECTED_STATEMENT), + Err(ClusterRejectIncoming::NotInGroup) => { + // sanity: shouldn't be possible; we already filtered this + // out above. + return Err(COST_UNEXPECTED_STATEMENT) + }, + } + }; + + // Ensure the statement is correctly signed. + let checked_statement = + match check_statement_signature(session, &session_info.validators, relay_parent, statement) + { + Ok(s) => s, + Err(_) => return Err(COST_INVALID_SIGNATURE), + }; + + cluster_tracker.note_received( + cluster_sender_index, + checked_statement.validator_index(), + checked_statement.payload().clone(), + ); + + Ok(if should_import { Some(checked_statement) } else { None }) +} + +/// Checks whether the signature is accurate, +/// importing into the grid tracker if successful. +/// +/// if successful, this returns a checked signed statement if it should be imported +/// or otherwise an error indicating a reputational fault. +fn handle_grid_statement( + relay_parent: Hash, + grid_tracker: &mut GridTracker, + session: SessionIndex, + per_session: &PerSessionState, + statement: UncheckedSignedStatement, + grid_sender_index: ValidatorIndex, +) -> Result { + // Ensure the statement is correctly signed. + let checked_statement = match check_statement_signature( + session, + &per_session.session_info.validators, + relay_parent, + statement, + ) { + Ok(s) => s, + Err(_) => return Err(COST_INVALID_SIGNATURE), + }; + + grid_tracker.sent_or_received_direct_statement( + &per_session.groups, + checked_statement.validator_index(), + grid_sender_index, + &checked_statement.payload(), + ); + + Ok(checked_statement) +} + +/// Send backing fresh statements. This should only be performed on importable & confirmed +/// candidates. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn send_backing_fresh_statements( + ctx: &mut Context, + candidate_hash: CandidateHash, + group_index: GroupIndex, + relay_parent: &Hash, + relay_parent_state: &mut PerRelayParentState, + confirmed: &candidates::ConfirmedCandidate, + per_session: &PerSessionState, +) { + let group_validators = per_session.groups.get(group_index).unwrap_or(&[]); + let mut imported = Vec::new(); + + for statement in relay_parent_state + .statement_store + .fresh_statements_for_backing(group_validators, candidate_hash) + { + let v = statement.validator_index(); + let compact = statement.payload().clone(); + imported.push((v, compact)); + let carrying_pvd = statement + .clone() + .convert_to_superpayload_with(|statement| match statement { + CompactStatement::Seconded(_) => FullStatementWithPVD::Seconded( + (&**confirmed.candidate_receipt()).clone(), + confirmed.persisted_validation_data().clone(), + ), + CompactStatement::Valid(c_hash) => FullStatementWithPVD::Valid(c_hash), + }) + .expect("statements refer to same candidate; qed"); + + ctx.send_message(CandidateBackingMessage::Statement(*relay_parent, carrying_pvd)) + .await; + } + + for (v, s) in imported { + relay_parent_state.statement_store.note_known_by_backing(v, s); + } +} + +fn local_knowledge_filter( + group_size: usize, + group_index: GroupIndex, + candidate_hash: CandidateHash, + statement_store: &StatementStore, +) -> StatementFilter { + let mut f = StatementFilter::blank(group_size); + statement_store.fill_statement_filter(group_index, candidate_hash, &mut f); + f +} + +// This provides a backable candidate to the grid and dispatches backable candidate announcements +// and acknowledgements via the grid topology. If the session topology is not yet +// available, this will be a no-op. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn provide_candidate_to_grid( + ctx: &mut Context, + candidate_hash: CandidateHash, + relay_parent_state: &mut PerRelayParentState, + confirmed_candidate: &candidates::ConfirmedCandidate, + per_session: &PerSessionState, + authorities: &HashMap, + peers: &HashMap, +) { + let local_validator = match relay_parent_state.local_validator { + Some(ref mut v) => v, + None => return, + }; + + let relay_parent = confirmed_candidate.relay_parent(); + let group_index = confirmed_candidate.group_index(); + + let grid_view = match per_session.grid_view { + Some(ref t) => t, + None => { + gum::debug!( + target: LOG_TARGET, + session = relay_parent_state.session, + "Cannot handle backable candidate due to lack of topology", + ); + + return + }, + }; + + let group_size = match per_session.groups.get(group_index) { + None => { + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + ?relay_parent, + ?group_index, + session = relay_parent_state.session, + "Handled backed candidate with unknown group?", + ); + + return + }, + Some(g) => g.len(), + }; + + let filter = local_knowledge_filter( + group_size, + group_index, + candidate_hash, + &relay_parent_state.statement_store, + ); + + let actions = local_validator.grid_tracker.add_backed_candidate( + grid_view, + candidate_hash, + group_index, + filter.clone(), + ); + + let manifest = protocol_vstaging::BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index, + para_id: confirmed_candidate.para_id(), + parent_head_data_hash: confirmed_candidate.parent_head_data_hash(), + statement_knowledge: filter.clone(), + }; + let acknowledgement = protocol_vstaging::BackedCandidateAcknowledgement { + candidate_hash, + statement_knowledge: filter.clone(), + }; + + let manifest_message = Versioned::VStaging( + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(manifest), + ); + let ack_message = Versioned::VStaging( + protocol_vstaging::StatementDistributionMessage::BackedCandidateKnown(acknowledgement), + ); + + let mut manifest_peers = Vec::new(); + let mut ack_peers = Vec::new(); + + let mut post_statements = Vec::new(); + for (v, action) in actions { + let p = match connected_validator_peer(authorities, per_session, v) { + None => continue, + Some(p) => + if peers.get(&p).map_or(false, |d| d.knows_relay_parent(&relay_parent)) { + p + } else { + continue + }, + }; + + match action { + grid::ManifestKind::Full => manifest_peers.push(p), + grid::ManifestKind::Acknowledgement => ack_peers.push(p), + } + + local_validator.grid_tracker.manifest_sent_to( + &per_session.groups, + v, + candidate_hash, + filter.clone(), + ); + post_statements.extend( + post_acknowledgement_statement_messages( + v, + relay_parent, + &mut local_validator.grid_tracker, + &relay_parent_state.statement_store, + &per_session.groups, + group_index, + candidate_hash, + ) + .into_iter() + .map(|m| (vec![p], m)), + ); + } + + if !manifest_peers.is_empty() { + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + n_peers = manifest_peers.len(), + "Sending manifest to peers" + ); + + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + manifest_peers, + manifest_message.into(), + )) + .await; + } + + if !ack_peers.is_empty() { + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + n_peers = ack_peers.len(), + "Sending acknowledgement to peers" + ); + + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage( + ack_peers, + ack_message.into(), + )) + .await; + } + + if !post_statements.is_empty() { + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessages(post_statements)) + .await; + } +} + +fn group_for_para( + availability_cores: &[CoreState], + group_rotation_info: &GroupRotationInfo, + para_id: ParaId, +) -> Option { + // Note: this won't work well for on-demand parachains as it assumes that core assignments are + // fixed across blocks. + let core_index = availability_cores.iter().position(|c| c.para_id() == Some(para_id)); + + core_index + .map(|c| group_rotation_info.group_for_core(CoreIndex(c as _), availability_cores.len())) +} + +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn fragment_tree_update_inner( + ctx: &mut Context, + state: &mut State, + active_leaf_hash: Option, + required_parent_info: Option<(Hash, ParaId)>, + known_hypotheticals: Option>, +) { + // 1. get hypothetical candidates + let hypotheticals = match known_hypotheticals { + None => state.candidates.frontier_hypotheticals(required_parent_info), + Some(h) => h, + }; + + // 2. find out which are in the frontier + let frontier = { + let (tx, rx) = oneshot::channel(); + ctx.send_message(ProspectiveParachainsMessage::GetHypotheticalFrontier( + HypotheticalFrontierRequest { + candidates: hypotheticals, + fragment_tree_relay_parent: active_leaf_hash, + backed_in_path_only: false, + }, + tx, + )) + .await; + + match rx.await { + Ok(frontier) => frontier, + Err(oneshot::Canceled) => return, + } + }; + // 3. note that they are importable under a given leaf hash. + for (hypo, membership) in frontier { + // skip parablocks outside of the frontier + if membership.is_empty() { + continue + } + + for (leaf_hash, _) in membership { + state.candidates.note_importable_under(&hypo, leaf_hash); + } + + // 4. for confirmed candidates, send all statements which are new to backing. + if let HypotheticalCandidate::Complete { + candidate_hash, + receipt, + persisted_validation_data: _, + } = hypo + { + let confirmed_candidate = state.candidates.get_confirmed(&candidate_hash); + let prs = state.per_relay_parent.get_mut(&receipt.descriptor().relay_parent); + if let (Some(confirmed), Some(prs)) = (confirmed_candidate, prs) { + let group_index = group_for_para( + &prs.availability_cores, + &prs.group_rotation_info, + receipt.descriptor().para_id, + ); + + let per_session = state.per_session.get(&prs.session); + if let (Some(per_session), Some(group_index)) = (per_session, group_index) { + send_backing_fresh_statements( + ctx, + candidate_hash, + group_index, + &receipt.descriptor().relay_parent, + prs, + confirmed, + per_session, + ) + .await; + } + } + } + } +} + +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn new_leaf_fragment_tree_updates( + ctx: &mut Context, + state: &mut State, + leaf_hash: Hash, +) { + fragment_tree_update_inner(ctx, state, Some(leaf_hash), None, None).await +} + +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn prospective_backed_notification_fragment_tree_updates( + ctx: &mut Context, + state: &mut State, + para_id: ParaId, + para_head: Hash, +) { + fragment_tree_update_inner(ctx, state, None, Some((para_head, para_id)), None).await +} + +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn new_confirmed_candidate_fragment_tree_updates( + ctx: &mut Context, + state: &mut State, + candidate: HypotheticalCandidate, +) { + fragment_tree_update_inner(ctx, state, None, None, Some(vec![candidate])).await +} + +struct ManifestImportSuccess<'a> { + relay_parent_state: &'a mut PerRelayParentState, + per_session: &'a PerSessionState, + acknowledge: bool, + sender_index: ValidatorIndex, +} + +/// Handles the common part of incoming manifests of both types (full & acknowledgement) +/// +/// Basic sanity checks around data, importing the manifest into the grid tracker, finding the +/// sending peer's validator index, reporting the peer for any misbehavior, etc. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn handle_incoming_manifest_common<'a, Context>( + ctx: &mut Context, + peer: PeerId, + peers: &HashMap, + per_relay_parent: &'a mut HashMap, + per_session: &'a HashMap, + candidates: &mut Candidates, + candidate_hash: CandidateHash, + relay_parent: Hash, + para_id: ParaId, + manifest_summary: grid::ManifestSummary, + manifest_kind: grid::ManifestKind, + reputation: &mut ReputationAggregator, +) -> Option> { + // 1. sanity checks: peer is connected, relay-parent in state, para ID matches group index. + let peer_state = match peers.get(&peer) { + None => return None, + Some(p) => p, + }; + + let relay_parent_state = match per_relay_parent.get_mut(&relay_parent) { + None => { + modify_reputation( + reputation, + ctx.sender(), + peer, + COST_UNEXPECTED_MANIFEST_MISSING_KNOWLEDGE, + ) + .await; + return None + }, + Some(s) => s, + }; + + let per_session = match per_session.get(&relay_parent_state.session) { + None => return None, + Some(s) => s, + }; + + let local_validator = match relay_parent_state.local_validator.as_mut() { + None => { + modify_reputation( + reputation, + ctx.sender(), + peer, + COST_UNEXPECTED_MANIFEST_MISSING_KNOWLEDGE, + ) + .await; + return None + }, + Some(x) => x, + }; + + let expected_group = group_for_para( + &relay_parent_state.availability_cores, + &relay_parent_state.group_rotation_info, + para_id, + ); + + if expected_group != Some(manifest_summary.claimed_group_index) { + modify_reputation(reputation, ctx.sender(), peer, COST_MALFORMED_MANIFEST).await; + return None + } + + let grid_topology = match per_session.grid_view.as_ref() { + None => return None, + Some(x) => x, + }; + + let sender_index = grid_topology + .iter_sending_for_group(manifest_summary.claimed_group_index, manifest_kind) + .filter_map(|i| per_session.session_info.discovery_keys.get(i.0 as usize).map(|ad| (i, ad))) + .filter(|(_, ad)| peer_state.is_authority(ad)) + .map(|(i, _)| i) + .next(); + + let sender_index = match sender_index { + None => { + modify_reputation(reputation, ctx.sender(), peer, COST_UNEXPECTED_MANIFEST_DISALLOWED) + .await; + return None + }, + Some(s) => s, + }; + + // 2. sanity checks: peer is validator, bitvec size, import into grid tracker + let group_index = manifest_summary.claimed_group_index; + let claimed_parent_hash = manifest_summary.claimed_parent_hash; + let acknowledge = match local_validator.grid_tracker.import_manifest( + grid_topology, + &per_session.groups, + candidate_hash, + relay_parent_state.seconding_limit, + manifest_summary, + manifest_kind, + sender_index, + ) { + Ok(x) => x, + Err(grid::ManifestImportError::Conflicting) => { + modify_reputation(reputation, ctx.sender(), peer, COST_CONFLICTING_MANIFEST).await; + return None + }, + Err(grid::ManifestImportError::Overflow) => { + modify_reputation(reputation, ctx.sender(), peer, COST_EXCESSIVE_SECONDED).await; + return None + }, + Err(grid::ManifestImportError::Insufficient) => { + modify_reputation(reputation, ctx.sender(), peer, COST_INSUFFICIENT_MANIFEST).await; + return None + }, + Err(grid::ManifestImportError::Malformed) => { + modify_reputation(reputation, ctx.sender(), peer, COST_MALFORMED_MANIFEST).await; + return None + }, + Err(grid::ManifestImportError::Disallowed) => { + modify_reputation(reputation, ctx.sender(), peer, COST_UNEXPECTED_MANIFEST_DISALLOWED) + .await; + return None + }, + }; + + // 3. if accepted by grid, insert as unconfirmed. + if let Err(BadAdvertisement) = candidates.insert_unconfirmed( + peer, + candidate_hash, + relay_parent, + group_index, + Some((claimed_parent_hash, para_id)), + ) { + modify_reputation(reputation, ctx.sender(), peer, COST_INACCURATE_ADVERTISEMENT).await; + return None + } + + Some(ManifestImportSuccess { relay_parent_state, per_session, acknowledge, sender_index }) +} + +/// Produce a list of network messages to send to a peer, following acknowledgement of a manifest. +/// This notes the messages as sent within the grid state. +fn post_acknowledgement_statement_messages( + recipient: ValidatorIndex, + relay_parent: Hash, + grid_tracker: &mut GridTracker, + statement_store: &StatementStore, + groups: &Groups, + group_index: GroupIndex, + candidate_hash: CandidateHash, +) -> Vec { + let sending_filter = match grid_tracker.pending_statements_for(recipient, candidate_hash) { + None => return Vec::new(), + Some(f) => f, + }; + + let mut messages = Vec::new(); + for statement in + statement_store.group_statements(groups, group_index, candidate_hash, &sending_filter) + { + grid_tracker.sent_or_received_direct_statement( + groups, + statement.validator_index(), + recipient, + statement.payload(), + ); + + messages.push(Versioned::VStaging( + protocol_vstaging::StatementDistributionMessage::Statement( + relay_parent, + statement.as_unchecked().clone(), + ) + .into(), + )); + } + + messages +} + +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn handle_incoming_manifest( + ctx: &mut Context, + state: &mut State, + peer: PeerId, + manifest: net_protocol::vstaging::BackedCandidateManifest, + reputation: &mut ReputationAggregator, +) { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?manifest.candidate_hash, + ?peer, + "Received incoming manifest", + ); + + let x = match handle_incoming_manifest_common( + ctx, + peer, + &state.peers, + &mut state.per_relay_parent, + &state.per_session, + &mut state.candidates, + manifest.candidate_hash, + manifest.relay_parent, + manifest.para_id, + grid::ManifestSummary { + claimed_parent_hash: manifest.parent_head_data_hash, + claimed_group_index: manifest.group_index, + statement_knowledge: manifest.statement_knowledge, + }, + grid::ManifestKind::Full, + reputation, + ) + .await + { + Some(x) => x, + None => return, + }; + + let ManifestImportSuccess { relay_parent_state, per_session, acknowledge, sender_index } = x; + + if acknowledge { + // 4. if already known within grid (confirmed & backed), acknowledge candidate + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?manifest.candidate_hash, + "Known candidate - acknowledging manifest", + ); + + let local_knowledge = { + let group_size = match per_session.groups.get(manifest.group_index) { + None => return, // sanity + Some(x) => x.len(), + }; + + local_knowledge_filter( + group_size, + manifest.group_index, + manifest.candidate_hash, + &relay_parent_state.statement_store, + ) + }; + + let messages = acknowledgement_and_statement_messages( + peer, + sender_index, + &per_session.groups, + relay_parent_state, + manifest.relay_parent, + manifest.group_index, + manifest.candidate_hash, + local_knowledge, + ); + + if !messages.is_empty() { + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessages(messages)).await; + } + } else if !state.candidates.is_confirmed(&manifest.candidate_hash) { + // 5. if unconfirmed, add request entry + gum::trace!( + target: LOG_TARGET, + candidate_hash = ?manifest.candidate_hash, + "Unknown candidate - requesting", + ); + + state + .request_manager + .get_or_insert(manifest.relay_parent, manifest.candidate_hash, manifest.group_index) + .add_peer(peer); + } +} + +/// Produces acknowledgement and statement messages to be sent over the network, +/// noting that they have been sent within the grid topology tracker as well. +fn acknowledgement_and_statement_messages( + peer: PeerId, + validator_index: ValidatorIndex, + groups: &Groups, + relay_parent_state: &mut PerRelayParentState, + relay_parent: Hash, + group_index: GroupIndex, + candidate_hash: CandidateHash, + local_knowledge: StatementFilter, +) -> Vec<(Vec, net_protocol::VersionedValidationProtocol)> { + let local_validator = match relay_parent_state.local_validator.as_mut() { + None => return Vec::new(), + Some(l) => l, + }; + + let acknowledgement = protocol_vstaging::BackedCandidateAcknowledgement { + candidate_hash, + statement_knowledge: local_knowledge.clone(), + }; + + let msg = Versioned::VStaging( + protocol_vstaging::StatementDistributionMessage::BackedCandidateKnown(acknowledgement), + ); + + let mut messages = vec![(vec![peer], msg.into())]; + + local_validator.grid_tracker.manifest_sent_to( + groups, + validator_index, + candidate_hash, + local_knowledge.clone(), + ); + + let statement_messages = post_acknowledgement_statement_messages( + validator_index, + relay_parent, + &mut local_validator.grid_tracker, + &relay_parent_state.statement_store, + &groups, + group_index, + candidate_hash, + ); + + messages.extend(statement_messages.into_iter().map(|m| (vec![peer], m))); + + messages +} + +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn handle_incoming_acknowledgement( + ctx: &mut Context, + state: &mut State, + peer: PeerId, + acknowledgement: net_protocol::vstaging::BackedCandidateAcknowledgement, + reputation: &mut ReputationAggregator, +) { + // The key difference between acknowledgments and full manifests is that only + // the candidate hash is included alongside the bitfields, so the candidate + // must be confirmed for us to even process it. + + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?acknowledgement.candidate_hash, + ?peer, + "Received incoming acknowledgement", + ); + + let candidate_hash = acknowledgement.candidate_hash; + let (relay_parent, parent_head_data_hash, group_index, para_id) = { + match state.candidates.get_confirmed(&candidate_hash) { + Some(c) => (c.relay_parent(), c.parent_head_data_hash(), c.group_index(), c.para_id()), + None => { + modify_reputation( + reputation, + ctx.sender(), + peer, + COST_UNEXPECTED_ACKNOWLEDGEMENT_UNKNOWN_CANDIDATE, + ) + .await; + return + }, + } + }; + + let x = match handle_incoming_manifest_common( + ctx, + peer, + &state.peers, + &mut state.per_relay_parent, + &state.per_session, + &mut state.candidates, + candidate_hash, + relay_parent, + para_id, + grid::ManifestSummary { + claimed_parent_hash: parent_head_data_hash, + claimed_group_index: group_index, + statement_knowledge: acknowledgement.statement_knowledge, + }, + grid::ManifestKind::Acknowledgement, + reputation, + ) + .await + { + Some(x) => x, + None => return, + }; + + let ManifestImportSuccess { relay_parent_state, per_session, sender_index, .. } = x; + + let local_validator = match relay_parent_state.local_validator.as_mut() { + None => return, + Some(l) => l, + }; + + let messages = post_acknowledgement_statement_messages( + sender_index, + relay_parent, + &mut local_validator.grid_tracker, + &relay_parent_state.statement_store, + &per_session.groups, + group_index, + candidate_hash, + ); + + if !messages.is_empty() { + ctx.send_message(NetworkBridgeTxMessage::SendValidationMessages( + messages.into_iter().map(|m| (vec![peer], m)).collect(), + )) + .await; + } +} + +/// Handle a notification of a candidate being backed. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +pub(crate) async fn handle_backed_candidate_message( + ctx: &mut Context, + state: &mut State, + candidate_hash: CandidateHash, +) { + // If the candidate is unknown or unconfirmed, it's a race (pruned before receiving message) + // or a bug. Ignore if so + let confirmed = match state.candidates.get_confirmed(&candidate_hash) { + None => { + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + "Received backed candidate notification for unknown or unconfirmed", + ); + + return + }, + Some(c) => c, + }; + + let relay_parent_state = match state.per_relay_parent.get_mut(&confirmed.relay_parent()) { + None => return, + Some(s) => s, + }; + + let per_session = match state.per_session.get(&relay_parent_state.session) { + None => return, + Some(s) => s, + }; + + gum::debug!( + target: LOG_TARGET, + ?candidate_hash, + group_index = ?confirmed.group_index(), + "Candidate Backed - initiating grid distribution & child fetches" + ); + + provide_candidate_to_grid( + ctx, + candidate_hash, + relay_parent_state, + confirmed, + per_session, + &state.authorities, + &state.peers, + ) + .await; + + // Search for children of the backed candidate to request. + prospective_backed_notification_fragment_tree_updates( + ctx, + state, + confirmed.para_id(), + confirmed.candidate_receipt().descriptor().para_head, + ) + .await; +} + +/// Sends all messages about a candidate to all peers in the cluster, +/// with `Seconded` statements first. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn send_cluster_candidate_statements( + ctx: &mut Context, + state: &mut State, + candidate_hash: CandidateHash, + relay_parent: Hash, +) { + let relay_parent_state = match state.per_relay_parent.get_mut(&relay_parent) { + None => return, + Some(s) => s, + }; + + let per_session = match state.per_session.get(&relay_parent_state.session) { + None => return, + Some(s) => s, + }; + + let local_group = match relay_parent_state.local_validator.as_mut() { + None => return, + Some(v) => v.group, + }; + + let group_size = match per_session.groups.get(local_group) { + None => return, + Some(g) => g.len(), + }; + + let statements: Vec<_> = relay_parent_state + .statement_store + .group_statements( + &per_session.groups, + local_group, + candidate_hash, + &StatementFilter::full(group_size), + ) + .map(|x| x.clone()) + .collect(); + + for statement in statements { + circulate_statement( + ctx, + relay_parent, + relay_parent_state, + per_session, + &state.candidates, + &state.authorities, + &state.peers, + statement, + ) + .await; + } +} + +/// Applies state & p2p updates as a result of a newly confirmed candidate. +/// +/// This punishes peers which advertised the candidate incorrectly, as well as +/// doing an importability analysis of the confirmed candidate and providing +/// statements to the backing subsystem if importable. It also cleans up +/// any pending requests for the candidate. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +async fn apply_post_confirmation( + ctx: &mut Context, + state: &mut State, + post_confirmation: PostConfirmation, + reputation: &mut ReputationAggregator, +) { + for peer in post_confirmation.reckoning.incorrect { + modify_reputation(reputation, ctx.sender(), peer, COST_INACCURATE_ADVERTISEMENT).await; + } + + let candidate_hash = post_confirmation.hypothetical.candidate_hash(); + state.request_manager.remove_for(candidate_hash); + + send_cluster_candidate_statements( + ctx, + state, + candidate_hash, + post_confirmation.hypothetical.relay_parent(), + ) + .await; + new_confirmed_candidate_fragment_tree_updates(ctx, state, post_confirmation.hypothetical).await; +} + +/// Dispatch pending requests for candidate data & statements. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +pub(crate) async fn dispatch_requests(ctx: &mut Context, state: &mut State) { + if !state.request_manager.has_pending_requests() { + return + } + + let peers = &state.peers; + let peer_advertised = |identifier: &CandidateIdentifier, peer: &_| { + let peer_data = peers.get(peer)?; + + let relay_parent_state = state.per_relay_parent.get(&identifier.relay_parent)?; + let per_session = state.per_session.get(&relay_parent_state.session)?; + + let local_validator = relay_parent_state.local_validator.as_ref()?; + + for validator_id in find_validator_ids(peer_data.iter_known_discovery_ids(), |a| { + per_session.authority_lookup.get(a) + }) { + // For cluster members, they haven't advertised any statements in particular, + // but have surely sent us some. + if local_validator + .cluster_tracker + .knows_candidate(validator_id, identifier.candidate_hash) + { + return Some(StatementFilter::blank(local_validator.cluster_tracker.targets().len())) + } + + let filter = local_validator + .grid_tracker + .advertised_statements(validator_id, &identifier.candidate_hash); + + if let Some(f) = filter { + return Some(f) + } + } + + None + }; + let request_props = |identifier: &CandidateIdentifier| { + let &CandidateIdentifier { relay_parent, group_index, .. } = identifier; + + let relay_parent_state = state.per_relay_parent.get(&relay_parent)?; + let per_session = state.per_session.get(&relay_parent_state.session)?; + let group = per_session.groups.get(group_index)?; + let seconding_limit = relay_parent_state.seconding_limit; + + // Request nothing which would be an 'over-seconded' statement. + let mut unwanted_mask = StatementFilter::blank(group.len()); + for (i, v) in group.iter().enumerate() { + if relay_parent_state.statement_store.seconded_count(v) >= seconding_limit { + unwanted_mask.seconded_in_group.set(i, true); + } + } + + // don't require a backing threshold for cluster candidates. + let require_backing = relay_parent_state.local_validator.as_ref()?.group != group_index; + + Some(RequestProperties { + unwanted_mask, + backing_threshold: if require_backing { + Some(polkadot_node_primitives::minimum_votes(group.len())) + } else { + None + }, + }) + }; + + while let Some(request) = state.request_manager.next_request( + &mut state.response_manager, + request_props, + peer_advertised, + ) { + // Peer is supposedly connected. + ctx.send_message(NetworkBridgeTxMessage::SendRequests( + vec![Requests::AttestedCandidateVStaging(request)], + IfDisconnected::ImmediateError, + )) + .await; + } +} + +/// Wait on the next incoming response. If there are no requests pending, this +/// future never resolves. It is the responsibility of the user of this API +/// to interrupt the future. +pub(crate) async fn receive_response(response_manager: &mut ResponseManager) -> UnhandledResponse { + match response_manager.incoming().await { + Some(r) => r, + None => futures::future::pending().await, + } +} + +/// Wait on the next soonest retry on a pending request. If there are no retries pending, this +/// future never resolves. Note that this only signals that a request is ready to retry; the user of +/// this API must call `dispatch_requests`. +pub(crate) async fn next_retry(request_manager: &mut RequestManager) { + match request_manager.next_retry_time() { + Some(instant) => + futures_timer::Delay::new(instant.saturating_duration_since(Instant::now())).await, + None => futures::future::pending().await, + } +} + +/// Handles an incoming response. This does the actual work of validating the response, +/// importing statements, sending acknowledgements, etc. +#[overseer::contextbounds(StatementDistribution, prefix=self::overseer)] +pub(crate) async fn handle_response( + ctx: &mut Context, + state: &mut State, + response: UnhandledResponse, + reputation: &mut ReputationAggregator, +) { + let &requests::CandidateIdentifier { relay_parent, candidate_hash, group_index } = + response.candidate_identifier(); + + let post_confirmation = { + let relay_parent_state = match state.per_relay_parent.get_mut(&relay_parent) { + None => return, + Some(s) => s, + }; + + let per_session = match state.per_session.get(&relay_parent_state.session) { + None => return, + Some(s) => s, + }; + + let group = match per_session.groups.get(group_index) { + None => return, + Some(g) => g, + }; + + let res = response.validate_response( + &mut state.request_manager, + group, + relay_parent_state.session, + |v| per_session.session_info.validators.get(v).map(|x| x.clone()), + |para, g_index| { + let expected_group = group_for_para( + &relay_parent_state.availability_cores, + &relay_parent_state.group_rotation_info, + para, + ); + + Some(g_index) == expected_group + }, + ); + + for (peer, rep) in res.reputation_changes { + modify_reputation(reputation, ctx.sender(), peer, rep).await; + } + + let (candidate, pvd, statements) = match res.request_status { + requests::CandidateRequestStatus::Outdated => return, + requests::CandidateRequestStatus::Incomplete => return, + requests::CandidateRequestStatus::Complete { + candidate, + persisted_validation_data, + statements, + } => (candidate, persisted_validation_data, statements), + }; + + for statement in statements { + let _ = relay_parent_state.statement_store.insert( + &per_session.groups, + statement, + StatementOrigin::Remote, + ); + } + + if let Some(post_confirmation) = + state.candidates.confirm_candidate(candidate_hash, candidate, pvd, group_index) + { + post_confirmation + } else { + gum::warn!( + target: LOG_TARGET, + ?candidate_hash, + "Candidate re-confirmed by request/response: logic error", + ); + + return + } + }; + + // Note that this implicitly circulates all statements via the cluster. + apply_post_confirmation(ctx, state, post_confirmation, reputation).await; + + let confirmed = state.candidates.get_confirmed(&candidate_hash).expect("just confirmed; qed"); + + // Although the candidate is confirmed, it isn't yet on the + // hypothetical frontier of the fragment tree. Later, when it is, + // we will import statements. + if !confirmed.is_importable(None) { + return + } + + let relay_parent_state = match state.per_relay_parent.get_mut(&relay_parent) { + None => return, + Some(s) => s, + }; + + let per_session = match state.per_session.get(&relay_parent_state.session) { + None => return, + Some(s) => s, + }; + + send_backing_fresh_statements( + ctx, + candidate_hash, + group_index, + &relay_parent, + relay_parent_state, + confirmed, + per_session, + ) + .await; + + // we don't need to send acknowledgement yet because + // 1. the candidate is not known yet, so cannot be backed. any previous confirmation is a bug, + // because `apply_post_confirmation` is meant to clear requests. + // 2. providing the statements to backing will lead to 'Backed' message. + // 3. on 'Backed' we will send acknowledgements/follow up statements when this becomes + // includable. +} + +/// Answer an incoming request for a candidate. +pub(crate) fn answer_request(state: &mut State, message: ResponderMessage) { + let ResponderMessage { request, sent_feedback } = message; + let AttestedCandidateRequest { candidate_hash, ref mask } = &request.payload; + + // Signal to the responder that we started processing this request. + let _ = sent_feedback.send(()); + + let confirmed = match state.candidates.get_confirmed(&candidate_hash) { + None => return, // drop request, candidate not known. + Some(c) => c, + }; + + let relay_parent_state = match state.per_relay_parent.get(&confirmed.relay_parent()) { + None => return, + Some(s) => s, + }; + + let local_validator = match relay_parent_state.local_validator.as_ref() { + None => return, + Some(s) => s, + }; + + let per_session = match state.per_session.get(&relay_parent_state.session) { + None => return, + Some(s) => s, + }; + + let peer_data = match state.peers.get(&request.peer) { + None => return, + Some(d) => d, + }; + + let group_size = per_session + .groups + .get(confirmed.group_index()) + .expect("group from session's candidate always known; qed") + .len(); + + // check request bitfields are right size. + if mask.seconded_in_group.len() != group_size || mask.validated_in_group.len() != group_size { + let _ = request.send_outgoing_response(OutgoingResponse { + result: Err(()), + reputation_changes: vec![COST_INVALID_REQUEST_BITFIELD_SIZE], + sent_feedback: None, + }); + + return + } + + // check peer is allowed to request the candidate (i.e. we've sent them a manifest) + { + let mut can_request = false; + for validator_id in find_validator_ids(peer_data.iter_known_discovery_ids(), |a| { + per_session.authority_lookup.get(a) + }) { + if local_validator.grid_tracker.can_request(validator_id, *candidate_hash) { + can_request = true; + break + } + } + + if !can_request { + let _ = request.send_outgoing_response(OutgoingResponse { + result: Err(()), + reputation_changes: vec![COST_UNEXPECTED_REQUEST], + sent_feedback: None, + }); + + return + } + } + + // Transform mask with 'OR' semantics into one with 'AND' semantics for the API used + // below. + let and_mask = StatementFilter { + seconded_in_group: !mask.seconded_in_group.clone(), + validated_in_group: !mask.validated_in_group.clone(), + }; + + let response = AttestedCandidateResponse { + candidate_receipt: (&**confirmed.candidate_receipt()).clone(), + persisted_validation_data: confirmed.persisted_validation_data().clone(), + statements: relay_parent_state + .statement_store + .group_statements( + &per_session.groups, + confirmed.group_index(), + *candidate_hash, + &and_mask, + ) + .map(|s| s.as_unchecked().clone()) + .collect(), + }; + + let _ = request.send_response(response); +} + +/// Messages coming from the background respond task. +pub(crate) struct ResponderMessage { + request: IncomingRequest, + sent_feedback: oneshot::Sender<()>, +} + +/// A fetching task, taking care of fetching candidates via request/response. +/// +/// Runs in a background task and feeds request to [`answer_request`] through [`MuxedMessage`]. +pub(crate) async fn respond_task( + mut receiver: IncomingRequestReceiver, + mut sender: mpsc::Sender, +) { + let mut pending_out = FuturesUnordered::new(); + loop { + // Ensure we are not handling too many requests in parallel. + if pending_out.len() >= MAX_PARALLEL_ATTESTED_CANDIDATE_REQUESTS as usize { + // Wait for one to finish: + pending_out.next().await; + } + + let req = match receiver.recv(|| vec![COST_INVALID_REQUEST]).await.into_nested() { + Ok(Ok(v)) => v, + Err(fatal) => { + gum::debug!(target: LOG_TARGET, error = ?fatal, "Shutting down request responder"); + return + }, + Ok(Err(jfyi)) => { + gum::debug!(target: LOG_TARGET, error = ?jfyi, "Decoding request failed"); + continue + }, + }; + + let (pending_sent_tx, pending_sent_rx) = oneshot::channel(); + if let Err(err) = sender + .feed(ResponderMessage { request: req, sent_feedback: pending_sent_tx }) + .await + { + gum::debug!(target: LOG_TARGET, ?err, "Shutting down responder"); + return + } + pending_out.push(pending_sent_rx); + } +} diff --git a/polkadot/node/network/statement-distribution/src/vstaging/requests.rs b/polkadot/node/network/statement-distribution/src/vstaging/requests.rs new file mode 100644 index 0000000000000000000000000000000000000000..2593d81ba0b2c795f354eaa07765ad7f662cc3f9 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/vstaging/requests.rs @@ -0,0 +1,1248 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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. + +//! A requester for full information on candidates. +//! +//! 1. We use `RequestManager::get_or_insert().get_mut()` to add and mutate [`RequestedCandidate`]s, +//! either setting the +//! priority or adding a peer we know has the candidate. We currently prioritize "cluster" +//! candidates (those from our own group, although the cluster mechanism could be made to include +//! multiple groups in the future) over "grid" candidates (those from other groups). +//! +//! 2. The main loop of the module will invoke [`RequestManager::next_request`] in a loop until it +//! returns `None`, +//! dispatching all requests with the `NetworkBridgeTxMessage`. The receiving half of the channel is +//! owned by the [`RequestManager`]. +//! +//! 3. The main loop of the module will also select over [`RequestManager::await_incoming`] to +//! receive +//! [`UnhandledResponse`]s, which it then validates using [`UnhandledResponse::validate_response`] +//! (which requires state not owned by the request manager). + +use super::{ + BENEFIT_VALID_RESPONSE, BENEFIT_VALID_STATEMENT, COST_IMPROPERLY_DECODED_RESPONSE, + COST_INVALID_RESPONSE, COST_INVALID_SIGNATURE, COST_UNREQUESTED_RESPONSE_STATEMENT, + REQUEST_RETRY_DELAY, +}; +use crate::LOG_TARGET; + +use polkadot_node_network_protocol::{ + request_response::{ + outgoing::{Recipient as RequestRecipient, RequestError}, + vstaging::{AttestedCandidateRequest, AttestedCandidateResponse}, + OutgoingRequest, OutgoingResult, MAX_PARALLEL_ATTESTED_CANDIDATE_REQUESTS, + }, + vstaging::StatementFilter, + PeerId, UnifiedReputationChange as Rep, +}; +use polkadot_primitives::vstaging::{ + CandidateHash, CommittedCandidateReceipt, CompactStatement, GroupIndex, Hash, ParaId, + PersistedValidationData, SessionIndex, SignedStatement, SigningContext, ValidatorId, + ValidatorIndex, +}; + +use futures::{future::BoxFuture, prelude::*, stream::FuturesUnordered}; + +use std::{ + collections::{ + hash_map::{Entry as HEntry, HashMap}, + HashSet, VecDeque, + }, + time::Instant, +}; + +/// An identifier for a candidate. +/// +/// In this module, we are requesting candidates +/// for which we have no information other than the candidate hash and statements signed +/// by validators. It is possible for validators for multiple groups to abuse this lack of +/// information: until we actually get the preimage of this candidate we cannot confirm +/// anything other than the candidate hash. +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct CandidateIdentifier { + /// The relay-parent this candidate is ostensibly under. + pub relay_parent: Hash, + /// The hash of the candidate. + pub candidate_hash: CandidateHash, + /// The index of the group claiming to be assigned to the candidate's + /// para. + pub group_index: GroupIndex, +} + +struct TaggedResponse { + identifier: CandidateIdentifier, + requested_peer: PeerId, + props: RequestProperties, + response: OutgoingResult, +} + +/// A pending request. +#[derive(Debug)] +pub struct RequestedCandidate { + priority: Priority, + known_by: VecDeque, + /// Has the request been sent out and a response not yet received? + in_flight: bool, + /// The timestamp for the next time we should retry, if the response failed. + next_retry_time: Option, +} + +impl RequestedCandidate { + fn is_pending(&self) -> bool { + if self.in_flight { + return false + } + + if let Some(next_retry_time) = self.next_retry_time { + let can_retry = Instant::now() >= next_retry_time; + if !can_retry { + return false + } + } + + true + } +} + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +enum Origin { + Cluster = 0, + Unspecified = 1, +} + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +struct Priority { + origin: Origin, + attempts: usize, +} + +/// An entry for manipulating a requested candidate. +pub struct Entry<'a> { + prev_index: usize, + identifier: CandidateIdentifier, + by_priority: &'a mut Vec<(Priority, CandidateIdentifier)>, + requested: &'a mut RequestedCandidate, +} + +impl<'a> Entry<'a> { + /// Add a peer to the set of known peers. + pub fn add_peer(&mut self, peer: PeerId) { + if !self.requested.known_by.contains(&peer) { + self.requested.known_by.push_back(peer); + } + } + + /// Note that the candidate is required for the cluster. + pub fn set_cluster_priority(&mut self) { + self.requested.priority.origin = Origin::Cluster; + + insert_or_update_priority( + &mut *self.by_priority, + Some(self.prev_index), + self.identifier.clone(), + self.requested.priority.clone(), + ); + } +} + +/// A manager for outgoing requests. +pub struct RequestManager { + requests: HashMap, + // sorted by priority. + by_priority: Vec<(Priority, CandidateIdentifier)>, + // all unique identifiers for the candidate. + unique_identifiers: HashMap>, +} + +impl RequestManager { + /// Create a new [`RequestManager`]. + pub fn new() -> Self { + RequestManager { + requests: HashMap::new(), + by_priority: Vec::new(), + unique_identifiers: HashMap::new(), + } + } + + /// Gets an [`Entry`] for mutating a request and inserts it if the + /// manager doesn't store this request already. + pub fn get_or_insert( + &mut self, + relay_parent: Hash, + candidate_hash: CandidateHash, + group_index: GroupIndex, + ) -> Entry { + let identifier = CandidateIdentifier { relay_parent, candidate_hash, group_index }; + + let (candidate, fresh) = match self.requests.entry(identifier.clone()) { + HEntry::Occupied(e) => (e.into_mut(), false), + HEntry::Vacant(e) => ( + e.insert(RequestedCandidate { + priority: Priority { attempts: 0, origin: Origin::Unspecified }, + known_by: VecDeque::new(), + in_flight: false, + next_retry_time: None, + }), + true, + ), + }; + + let priority_index = if fresh { + self.unique_identifiers + .entry(candidate_hash) + .or_default() + .insert(identifier.clone()); + + insert_or_update_priority( + &mut self.by_priority, + None, + identifier.clone(), + candidate.priority.clone(), + ) + } else { + match self + .by_priority + .binary_search(&(candidate.priority.clone(), identifier.clone())) + { + Ok(i) => i, + Err(_) => unreachable!("requested candidates always have a priority entry; qed"), + } + }; + + Entry { + prev_index: priority_index, + identifier, + by_priority: &mut self.by_priority, + requested: candidate, + } + } + + /// Remove all pending requests for the given candidate. + pub fn remove_for(&mut self, candidate: CandidateHash) { + if let Some(identifiers) = self.unique_identifiers.remove(&candidate) { + self.by_priority.retain(|(_priority, id)| !identifiers.contains(&id)); + for id in identifiers { + self.requests.remove(&id); + } + } + } + + /// Remove based on relay-parent. + pub fn remove_by_relay_parent(&mut self, relay_parent: Hash) { + let mut candidate_hashes = HashSet::new(); + + // Remove from `by_priority` and `requests`. + self.by_priority.retain(|(_priority, id)| { + let retain = relay_parent != id.relay_parent; + if !retain { + self.requests.remove(id); + candidate_hashes.insert(id.candidate_hash); + } + retain + }); + + // Remove from `unique_identifiers`. + for candidate_hash in candidate_hashes { + match self.unique_identifiers.entry(candidate_hash) { + HEntry::Occupied(mut entry) => { + entry.get_mut().retain(|id| relay_parent != id.relay_parent); + if entry.get().is_empty() { + entry.remove(); + } + }, + // We can expect to encounter vacant entries, but only if nodes are misbehaving and + // we don't use a deduplicating collection; there are no issues from ignoring it. + HEntry::Vacant(_) => (), + } + } + } + + /// Returns true if there are pending requests that are dispatchable. + pub fn has_pending_requests(&self) -> bool { + for (_id, entry) in &self.requests { + if entry.is_pending() { + return true + } + } + + false + } + + /// Returns an instant at which the next request to be retried will be ready. + pub fn next_retry_time(&mut self) -> Option { + let mut next = None; + for (_id, request) in &self.requests { + if let Some(next_retry_time) = request.next_retry_time { + if next.map_or(true, |next| next_retry_time < next) { + next = Some(next_retry_time); + } + } + } + next + } + + /// Yields the next request to dispatch, if there is any. + /// + /// This function accepts two closures as an argument. + /// + /// The first closure is used to gather information about the desired + /// properties of a response, which is used to select targets and validate + /// the response later on. + /// + /// The second closure is used to determine the specific advertised + /// statements by a peer, to be compared against the mask and backing + /// threshold and returns `None` if the peer is no longer connected. + pub fn next_request( + &mut self, + response_manager: &mut ResponseManager, + request_props: impl Fn(&CandidateIdentifier) -> Option, + peer_advertised: impl Fn(&CandidateIdentifier, &PeerId) -> Option, + ) -> Option> { + if response_manager.len() >= MAX_PARALLEL_ATTESTED_CANDIDATE_REQUESTS as usize { + return None + } + + let mut res = None; + + // loop over all requests, in order of priority. + // do some active maintenance of the connected peers. + // dispatch the first request which is not in-flight already. + + let mut cleanup_outdated = Vec::new(); + for (i, (_priority, id)) in self.by_priority.iter().enumerate() { + let entry = match self.requests.get_mut(&id) { + None => { + gum::error!( + target: LOG_TARGET, + identifier = ?id, + "Missing entry for priority queue member", + ); + + continue + }, + Some(e) => e, + }; + + if !entry.is_pending() { + continue + } + + let props = match request_props(&id) { + None => { + cleanup_outdated.push((i, id.clone())); + continue + }, + Some(s) => s, + }; + + let target = match find_request_target_with_update( + &mut entry.known_by, + id, + &props, + &peer_advertised, + ) { + None => continue, + Some(t) => t, + }; + + let (request, response_fut) = OutgoingRequest::new( + RequestRecipient::Peer(target), + AttestedCandidateRequest { + candidate_hash: id.candidate_hash, + mask: props.unwanted_mask.clone(), + }, + ); + + let stored_id = id.clone(); + response_manager.push(Box::pin(async move { + TaggedResponse { + identifier: stored_id, + requested_peer: target, + props, + response: response_fut.await, + } + })); + + entry.in_flight = true; + + res = Some(request); + break + } + + for (priority_index, identifier) in cleanup_outdated.into_iter().rev() { + self.by_priority.remove(priority_index); + self.requests.remove(&identifier); + if let HEntry::Occupied(mut e) = + self.unique_identifiers.entry(identifier.candidate_hash) + { + e.get_mut().remove(&identifier); + if e.get().is_empty() { + e.remove(); + } + } + } + + res + } +} + +/// A manager for pending responses. +pub struct ResponseManager { + pending_responses: FuturesUnordered>, +} + +impl ResponseManager { + pub fn new() -> Self { + Self { pending_responses: FuturesUnordered::new() } + } + + /// Await the next incoming response to a sent request, or immediately + /// return `None` if there are no pending responses. + pub async fn incoming(&mut self) -> Option { + self.pending_responses + .next() + .await + .map(|response| UnhandledResponse { response }) + } + + fn len(&self) -> usize { + self.pending_responses.len() + } + + fn push(&mut self, response: BoxFuture<'static, TaggedResponse>) { + self.pending_responses.push(response); + } +} + +/// Properties used in target selection and validation of a request. +#[derive(Clone)] +pub struct RequestProperties { + /// A mask for limiting the statements the response is allowed to contain. + /// The mask has `OR` semantics: statements by validators corresponding to bits + /// in the mask are not desired. It also returns the required backing threshold + /// for the candidate. + pub unwanted_mask: StatementFilter, + /// The required backing threshold, if any. If this is `Some`, then requests will only + /// be made to peers which can provide enough statements to back the candidate, when + /// taking into account the `unwanted_mask`, and a response will only be validated + /// in the case of those statements. + /// + /// If this is `None`, it is assumed that only the candidate itself is needed. + pub backing_threshold: Option, +} + +/// Finds a valid request target, returning `None` if none exists. +/// Cleans up disconnected peers and places the returned peer at the back of the queue. +fn find_request_target_with_update( + known_by: &mut VecDeque, + candidate_identifier: &CandidateIdentifier, + props: &RequestProperties, + peer_advertised: impl Fn(&CandidateIdentifier, &PeerId) -> Option, +) -> Option { + let mut prune = Vec::new(); + let mut target = None; + for (i, p) in known_by.iter().enumerate() { + let mut filter = match peer_advertised(candidate_identifier, p) { + None => { + prune.push(i); + continue + }, + Some(f) => f, + }; + + filter.mask_seconded(&props.unwanted_mask.seconded_in_group); + filter.mask_valid(&props.unwanted_mask.validated_in_group); + if seconded_and_sufficient(&filter, props.backing_threshold) { + target = Some((i, *p)); + break + } + } + + let prune_count = prune.len(); + for i in prune { + known_by.remove(i); + } + + if let Some((i, p)) = target { + known_by.remove(i - prune_count); + known_by.push_back(p); + Some(p) + } else { + None + } +} + +fn seconded_and_sufficient(filter: &StatementFilter, backing_threshold: Option) -> bool { + backing_threshold.map_or(true, |t| filter.has_seconded() && filter.backing_validators() >= t) +} + +/// A response to a request, which has not yet been handled. +pub struct UnhandledResponse { + response: TaggedResponse, +} + +impl UnhandledResponse { + /// Get the candidate identifier which the corresponding request + /// was classified under. + pub fn candidate_identifier(&self) -> &CandidateIdentifier { + &self.response.identifier + } + + /// Validate the response. If the response is valid, this will yield the + /// candidate, the [`PersistedValidationData`] of the candidate, and requested + /// checked statements. + /// + /// Valid responses are defined as those which provide a valid candidate + /// and signatures which match the identifier, and provide enough statements to back the + /// candidate. + /// + /// This will also produce a record of misbehaviors by peers: + /// * If the response is partially valid, misbehavior by the responding peer. + /// * If there are other peers which have advertised the same candidate for different + /// relay-parents or para-ids, misbehavior reports for those peers will also be generated. + /// + /// Finally, in the case that the response is either valid or partially valid, + /// this will clean up all remaining requests for the candidate in the manager. + /// + /// As parameters, the user should supply the canonical group array as well + /// as a mapping from validator index to validator ID. The validator pubkey mapping + /// will not be queried except for validator indices in the group. + pub fn validate_response( + self, + manager: &mut RequestManager, + group: &[ValidatorIndex], + session: SessionIndex, + validator_key_lookup: impl Fn(ValidatorIndex) -> Option, + allowed_para_lookup: impl Fn(ParaId, GroupIndex) -> bool, + ) -> ResponseValidationOutput { + let UnhandledResponse { + response: TaggedResponse { identifier, requested_peer, props, response }, + } = self; + + // handle races if the candidate is no longer known. + // this could happen if we requested the candidate under two + // different identifiers at the same time, and received a valid + // response on the other. + // + // it could also happen in the case that we had a request in-flight + // and the request entry was garbage-collected on outdated relay parent. + let entry = match manager.requests.get_mut(&identifier) { + None => + return ResponseValidationOutput { + requested_peer, + reputation_changes: Vec::new(), + request_status: CandidateRequestStatus::Outdated, + }, + Some(e) => e, + }; + + let priority_index = match manager + .by_priority + .binary_search(&(entry.priority.clone(), identifier.clone())) + { + Ok(i) => i, + Err(_) => unreachable!("requested candidates always have a priority entry; qed"), + }; + + // Set the next retry time before clearing the `in_flight` flag. + entry.next_retry_time = Some(Instant::now() + REQUEST_RETRY_DELAY); + entry.in_flight = false; + entry.priority.attempts += 1; + + // update the location in the priority queue. + insert_or_update_priority( + &mut manager.by_priority, + Some(priority_index), + identifier.clone(), + entry.priority.clone(), + ); + + let complete_response = match response { + Err(RequestError::InvalidResponse(e)) => { + gum::trace!( + target: LOG_TARGET, + err = ?e, + peer = ?requested_peer, + "Improperly encoded response" + ); + + return ResponseValidationOutput { + requested_peer, + reputation_changes: vec![(requested_peer, COST_IMPROPERLY_DECODED_RESPONSE)], + request_status: CandidateRequestStatus::Incomplete, + } + }, + Err(RequestError::NetworkError(_) | RequestError::Canceled(_)) => + return ResponseValidationOutput { + requested_peer, + reputation_changes: vec![], + request_status: CandidateRequestStatus::Incomplete, + }, + Ok(response) => response, + }; + + let output = validate_complete_response( + &identifier, + props, + complete_response, + requested_peer, + group, + session, + validator_key_lookup, + allowed_para_lookup, + ); + + if let CandidateRequestStatus::Complete { .. } = output.request_status { + manager.remove_for(identifier.candidate_hash); + } + + output + } +} + +fn validate_complete_response( + identifier: &CandidateIdentifier, + props: RequestProperties, + response: AttestedCandidateResponse, + requested_peer: PeerId, + group: &[ValidatorIndex], + session: SessionIndex, + validator_key_lookup: impl Fn(ValidatorIndex) -> Option, + allowed_para_lookup: impl Fn(ParaId, GroupIndex) -> bool, +) -> ResponseValidationOutput { + let RequestProperties { backing_threshold, mut unwanted_mask } = props; + + // sanity check bitmask size. this is based entirely on + // local logic here. + if !unwanted_mask.has_len(group.len()) { + gum::error!( + target: LOG_TARGET, + group_len = group.len(), + "Logic bug: group size != sent bitmask len" + ); + + // resize and attempt to continue. + unwanted_mask.seconded_in_group.resize(group.len(), true); + unwanted_mask.validated_in_group.resize(group.len(), true); + } + + let invalid_candidate_output = || ResponseValidationOutput { + request_status: CandidateRequestStatus::Incomplete, + reputation_changes: vec![(requested_peer, COST_INVALID_RESPONSE)], + requested_peer, + }; + + // sanity-check candidate response. + // note: roughly ascending cost of operations + { + if response.candidate_receipt.descriptor.relay_parent != identifier.relay_parent { + return invalid_candidate_output() + } + + if response.candidate_receipt.descriptor.persisted_validation_data_hash != + response.persisted_validation_data.hash() + { + return invalid_candidate_output() + } + + if !allowed_para_lookup( + response.candidate_receipt.descriptor.para_id, + identifier.group_index, + ) { + return invalid_candidate_output() + } + + if response.candidate_receipt.hash() != identifier.candidate_hash { + return invalid_candidate_output() + } + } + + // statement checks. + let mut rep_changes = Vec::new(); + let statements = { + let mut statements = + Vec::with_capacity(std::cmp::min(response.statements.len(), group.len() * 2)); + + let mut received_filter = StatementFilter::blank(group.len()); + + let index_in_group = |v: ValidatorIndex| group.iter().position(|x| &v == x); + + let signing_context = + SigningContext { parent_hash: identifier.relay_parent, session_index: session }; + + for unchecked_statement in response.statements.into_iter().take(group.len() * 2) { + // ensure statement is from a validator in the group. + let i = match index_in_group(unchecked_statement.unchecked_validator_index()) { + Some(i) => i, + None => { + rep_changes.push((requested_peer, COST_UNREQUESTED_RESPONSE_STATEMENT)); + continue + }, + }; + + // ensure statement is on the correct candidate hash. + if unchecked_statement.unchecked_payload().candidate_hash() != + &identifier.candidate_hash + { + rep_changes.push((requested_peer, COST_UNREQUESTED_RESPONSE_STATEMENT)); + continue + } + + // filter out duplicates or statements outside the mask. + // note on indexing: we have ensured that the bitmask and the + // duplicate trackers have the correct size for the group. + match unchecked_statement.unchecked_payload() { + CompactStatement::Seconded(_) => { + if unwanted_mask.seconded_in_group[i] { + rep_changes.push((requested_peer, COST_UNREQUESTED_RESPONSE_STATEMENT)); + continue + } + + if received_filter.seconded_in_group[i] { + rep_changes.push((requested_peer, COST_UNREQUESTED_RESPONSE_STATEMENT)); + continue + } + }, + CompactStatement::Valid(_) => { + if unwanted_mask.validated_in_group[i] { + rep_changes.push((requested_peer, COST_UNREQUESTED_RESPONSE_STATEMENT)); + continue + } + + if received_filter.validated_in_group[i] { + rep_changes.push((requested_peer, COST_UNREQUESTED_RESPONSE_STATEMENT)); + continue + } + }, + } + + let validator_public = + match validator_key_lookup(unchecked_statement.unchecked_validator_index()) { + None => { + rep_changes.push((requested_peer, COST_INVALID_SIGNATURE)); + continue + }, + Some(p) => p, + }; + + let checked_statement = + match unchecked_statement.try_into_checked(&signing_context, &validator_public) { + Err(_) => { + rep_changes.push((requested_peer, COST_INVALID_SIGNATURE)); + continue + }, + Ok(checked) => checked, + }; + + match checked_statement.payload() { + CompactStatement::Seconded(_) => { + received_filter.seconded_in_group.set(i, true); + }, + CompactStatement::Valid(_) => { + received_filter.validated_in_group.set(i, true); + }, + } + + statements.push(checked_statement); + rep_changes.push((requested_peer, BENEFIT_VALID_STATEMENT)); + } + + // Only accept responses which are sufficient, according to our + // required backing threshold. + if !seconded_and_sufficient(&received_filter, backing_threshold) { + return invalid_candidate_output() + } + + statements + }; + + rep_changes.push((requested_peer, BENEFIT_VALID_RESPONSE)); + + ResponseValidationOutput { + requested_peer, + request_status: CandidateRequestStatus::Complete { + candidate: response.candidate_receipt, + persisted_validation_data: response.persisted_validation_data, + statements, + }, + reputation_changes: rep_changes, + } +} + +/// The status of the candidate request after the handling of a response. +#[derive(Debug, PartialEq)] +pub enum CandidateRequestStatus { + /// The request was outdated at the point of receiving the response. + Outdated, + /// The response either did not arrive or was invalid. + Incomplete, + /// The response completed the request. Statements sent beyond the + /// mask have been ignored. + Complete { + candidate: CommittedCandidateReceipt, + persisted_validation_data: PersistedValidationData, + statements: Vec, + }, +} + +/// Output of the response validation. +#[derive(Debug, PartialEq)] +pub struct ResponseValidationOutput { + /// The peer we requested from. + pub requested_peer: PeerId, + /// The status of the request. + pub request_status: CandidateRequestStatus, + /// Any reputation changes as a result of validating the response. + pub reputation_changes: Vec<(PeerId, Rep)>, +} + +fn insert_or_update_priority( + priority_sorted: &mut Vec<(Priority, CandidateIdentifier)>, + prev_index: Option, + candidate_identifier: CandidateIdentifier, + new_priority: Priority, +) -> usize { + if let Some(prev_index) = prev_index { + // GIGO: this behaves strangely if prev-index is not for the + // expected identifier. + if priority_sorted[prev_index].0 == new_priority { + // unchanged. + return prev_index + } else { + priority_sorted.remove(prev_index); + } + } + + let item = (new_priority, candidate_identifier); + match priority_sorted.binary_search(&item) { + Ok(i) => i, // ignore if already present. + Err(i) => { + priority_sorted.insert(i, item); + i + }, + } +} + +#[cfg(test)] +mod tests { + use super::*; + use polkadot_primitives::HeadData; + use polkadot_primitives_test_helpers as test_helpers; + + fn dummy_pvd() -> PersistedValidationData { + PersistedValidationData { + parent_head: HeadData(vec![7, 8, 9]), + relay_parent_number: 5, + max_pov_size: 1024, + relay_parent_storage_root: Default::default(), + } + } + + #[test] + fn test_remove_by_relay_parent() { + let parent_a = Hash::from_low_u64_le(1); + let parent_b = Hash::from_low_u64_le(2); + let parent_c = Hash::from_low_u64_le(3); + + let candidate_a1 = CandidateHash(Hash::from_low_u64_le(11)); + let candidate_a2 = CandidateHash(Hash::from_low_u64_le(12)); + let candidate_b1 = CandidateHash(Hash::from_low_u64_le(21)); + let candidate_b2 = CandidateHash(Hash::from_low_u64_le(22)); + let candidate_c1 = CandidateHash(Hash::from_low_u64_le(31)); + let duplicate_hash = CandidateHash(Hash::from_low_u64_le(31)); + + let mut request_manager = RequestManager::new(); + request_manager.get_or_insert(parent_a, candidate_a1, 1.into()); + request_manager.get_or_insert(parent_a, candidate_a2, 1.into()); + request_manager.get_or_insert(parent_b, candidate_b1, 1.into()); + request_manager.get_or_insert(parent_b, candidate_b2, 2.into()); + request_manager.get_or_insert(parent_c, candidate_c1, 2.into()); + request_manager.get_or_insert(parent_a, duplicate_hash, 1.into()); + + assert_eq!(request_manager.requests.len(), 6); + assert_eq!(request_manager.by_priority.len(), 6); + assert_eq!(request_manager.unique_identifiers.len(), 5); + + request_manager.remove_by_relay_parent(parent_a); + + assert_eq!(request_manager.requests.len(), 3); + assert_eq!(request_manager.by_priority.len(), 3); + assert_eq!(request_manager.unique_identifiers.len(), 3); + + assert!(!request_manager.unique_identifiers.contains_key(&candidate_a1)); + assert!(!request_manager.unique_identifiers.contains_key(&candidate_a2)); + // Duplicate hash should still be there (under a different parent). + assert!(request_manager.unique_identifiers.contains_key(&duplicate_hash)); + + request_manager.remove_by_relay_parent(parent_b); + + assert_eq!(request_manager.requests.len(), 1); + assert_eq!(request_manager.by_priority.len(), 1); + assert_eq!(request_manager.unique_identifiers.len(), 1); + + assert!(!request_manager.unique_identifiers.contains_key(&candidate_b1)); + assert!(!request_manager.unique_identifiers.contains_key(&candidate_b2)); + + request_manager.remove_by_relay_parent(parent_c); + + assert!(request_manager.requests.is_empty()); + assert!(request_manager.by_priority.is_empty()); + assert!(request_manager.unique_identifiers.is_empty()); + } + + #[test] + fn test_priority_ordering() { + let parent_a = Hash::from_low_u64_le(1); + let parent_b = Hash::from_low_u64_le(2); + let parent_c = Hash::from_low_u64_le(3); + + let candidate_a1 = CandidateHash(Hash::from_low_u64_le(11)); + let candidate_a2 = CandidateHash(Hash::from_low_u64_le(12)); + let candidate_b1 = CandidateHash(Hash::from_low_u64_le(21)); + let candidate_b2 = CandidateHash(Hash::from_low_u64_le(22)); + let candidate_c1 = CandidateHash(Hash::from_low_u64_le(31)); + + let mut request_manager = RequestManager::new(); + + // Add some entries, set a couple of them to cluster (high) priority. + let identifier_a1 = request_manager + .get_or_insert(parent_a, candidate_a1, 1.into()) + .identifier + .clone(); + let identifier_a2 = { + let mut entry = request_manager.get_or_insert(parent_a, candidate_a2, 1.into()); + entry.set_cluster_priority(); + entry.identifier.clone() + }; + let identifier_b1 = request_manager + .get_or_insert(parent_b, candidate_b1, 1.into()) + .identifier + .clone(); + let identifier_b2 = request_manager + .get_or_insert(parent_b, candidate_b2, 2.into()) + .identifier + .clone(); + let identifier_c1 = { + let mut entry = request_manager.get_or_insert(parent_c, candidate_c1, 2.into()); + entry.set_cluster_priority(); + entry.identifier.clone() + }; + + let attempts = 0; + assert_eq!( + request_manager.by_priority, + vec![ + (Priority { origin: Origin::Cluster, attempts }, identifier_a2), + (Priority { origin: Origin::Cluster, attempts }, identifier_c1), + (Priority { origin: Origin::Unspecified, attempts }, identifier_a1), + (Priority { origin: Origin::Unspecified, attempts }, identifier_b1), + (Priority { origin: Origin::Unspecified, attempts }, identifier_b2), + ] + ); + } + + // Test case where candidate is requested under two different identifiers at the same time. + // Should result in `Outdated` error. + #[test] + fn handle_outdated_response_due_to_requests_for_different_identifiers() { + let mut request_manager = RequestManager::new(); + let mut response_manager = ResponseManager::new(); + + let relay_parent = Hash::from_low_u64_le(1); + let mut candidate_receipt = test_helpers::dummy_committed_candidate_receipt(relay_parent); + let persisted_validation_data = dummy_pvd(); + candidate_receipt.descriptor.persisted_validation_data_hash = + persisted_validation_data.hash(); + let candidate = candidate_receipt.hash(); + let requested_peer = PeerId::random(); + + let identifier1 = request_manager + .get_or_insert(relay_parent, candidate, 1.into()) + .identifier + .clone(); + request_manager + .get_or_insert(relay_parent, candidate, 1.into()) + .add_peer(requested_peer); + let identifier2 = request_manager + .get_or_insert(relay_parent, candidate, 2.into()) + .identifier + .clone(); + request_manager + .get_or_insert(relay_parent, candidate, 2.into()) + .add_peer(requested_peer); + + assert_ne!(identifier1, identifier2); + assert_eq!(request_manager.requests.len(), 2); + + let group_size = 3; + let group = &[ValidatorIndex(0), ValidatorIndex(1), ValidatorIndex(2)]; + + let unwanted_mask = StatementFilter::blank(group_size); + let request_properties = RequestProperties { unwanted_mask, backing_threshold: None }; + + // Get requests. + { + let request_props = + |_identifier: &CandidateIdentifier| Some((&request_properties).clone()); + let peer_advertised = |_identifier: &CandidateIdentifier, _peer: &_| { + Some(StatementFilter::full(group_size)) + }; + let outgoing = request_manager + .next_request(&mut response_manager, request_props, peer_advertised) + .unwrap(); + assert_eq!(outgoing.payload.candidate_hash, candidate); + let outgoing = request_manager + .next_request(&mut response_manager, request_props, peer_advertised) + .unwrap(); + assert_eq!(outgoing.payload.candidate_hash, candidate); + } + + // Validate first response. + { + let statements = vec![]; + let response = UnhandledResponse { + response: TaggedResponse { + identifier: identifier1, + requested_peer, + props: request_properties.clone(), + response: Ok(AttestedCandidateResponse { + candidate_receipt: candidate_receipt.clone(), + persisted_validation_data: persisted_validation_data.clone(), + statements, + }), + }, + }; + let validator_key_lookup = |_v| None; + let allowed_para_lookup = |_para, _g_index| true; + let statements = vec![]; + let output = response.validate_response( + &mut request_manager, + group, + 0, + validator_key_lookup, + allowed_para_lookup, + ); + assert_eq!( + output, + ResponseValidationOutput { + requested_peer, + request_status: CandidateRequestStatus::Complete { + candidate: candidate_receipt.clone(), + persisted_validation_data: persisted_validation_data.clone(), + statements, + }, + reputation_changes: vec![(requested_peer, BENEFIT_VALID_RESPONSE)], + } + ); + } + + // Try to validate second response. + { + let statements = vec![]; + let response = UnhandledResponse { + response: TaggedResponse { + identifier: identifier2, + requested_peer, + props: request_properties, + response: Ok(AttestedCandidateResponse { + candidate_receipt: candidate_receipt.clone(), + persisted_validation_data: persisted_validation_data.clone(), + statements, + }), + }, + }; + let validator_key_lookup = |_v| None; + let allowed_para_lookup = |_para, _g_index| true; + let output = response.validate_response( + &mut request_manager, + group, + 0, + validator_key_lookup, + allowed_para_lookup, + ); + assert_eq!( + output, + ResponseValidationOutput { + requested_peer, + request_status: CandidateRequestStatus::Outdated, + reputation_changes: vec![], + } + ); + } + } + + // Test case where we had a request in-flight and the request entry was garbage-collected on + // outdated relay parent. + #[test] + fn handle_outdated_response_due_to_garbage_collection() { + let mut request_manager = RequestManager::new(); + let mut response_manager = ResponseManager::new(); + + let relay_parent = Hash::from_low_u64_le(1); + let mut candidate_receipt = test_helpers::dummy_committed_candidate_receipt(relay_parent); + let persisted_validation_data = dummy_pvd(); + candidate_receipt.descriptor.persisted_validation_data_hash = + persisted_validation_data.hash(); + let candidate = candidate_receipt.hash(); + let requested_peer = PeerId::random(); + + let identifier = request_manager + .get_or_insert(relay_parent, candidate, 1.into()) + .identifier + .clone(); + request_manager + .get_or_insert(relay_parent, candidate, 1.into()) + .add_peer(requested_peer); + + let group_size = 3; + let group = &[ValidatorIndex(0), ValidatorIndex(1), ValidatorIndex(2)]; + + let unwanted_mask = StatementFilter::blank(group_size); + let request_properties = RequestProperties { unwanted_mask, backing_threshold: None }; + let peer_advertised = + |_identifier: &CandidateIdentifier, _peer: &_| Some(StatementFilter::full(group_size)); + + // Get request once successfully. + { + let request_props = + |_identifier: &CandidateIdentifier| Some((&request_properties).clone()); + let outgoing = request_manager + .next_request(&mut response_manager, request_props, peer_advertised) + .unwrap(); + assert_eq!(outgoing.payload.candidate_hash, candidate); + } + + // Garbage collect based on relay parent. + request_manager.remove_by_relay_parent(relay_parent); + + // Try to validate response. + { + let statements = vec![]; + let response = UnhandledResponse { + response: TaggedResponse { + identifier, + requested_peer, + props: request_properties, + response: Ok(AttestedCandidateResponse { + candidate_receipt: candidate_receipt.clone(), + persisted_validation_data: persisted_validation_data.clone(), + statements, + }), + }, + }; + let validator_key_lookup = |_v| None; + let allowed_para_lookup = |_para, _g_index| true; + let output = response.validate_response( + &mut request_manager, + group, + 0, + validator_key_lookup, + allowed_para_lookup, + ); + assert_eq!( + output, + ResponseValidationOutput { + requested_peer, + request_status: CandidateRequestStatus::Outdated, + reputation_changes: vec![], + } + ); + } + } + + #[test] + fn should_clean_up_after_successful_requests() { + let mut request_manager = RequestManager::new(); + let mut response_manager = ResponseManager::new(); + + let relay_parent = Hash::from_low_u64_le(1); + let mut candidate_receipt = test_helpers::dummy_committed_candidate_receipt(relay_parent); + let persisted_validation_data = dummy_pvd(); + candidate_receipt.descriptor.persisted_validation_data_hash = + persisted_validation_data.hash(); + let candidate = candidate_receipt.hash(); + let requested_peer = PeerId::random(); + + let identifier = request_manager + .get_or_insert(relay_parent, candidate, 1.into()) + .identifier + .clone(); + request_manager + .get_or_insert(relay_parent, candidate, 1.into()) + .add_peer(requested_peer); + + assert_eq!(request_manager.requests.len(), 1); + assert_eq!(request_manager.by_priority.len(), 1); + + let group_size = 3; + let group = &[ValidatorIndex(0), ValidatorIndex(1), ValidatorIndex(2)]; + + let unwanted_mask = StatementFilter::blank(group_size); + let request_properties = RequestProperties { unwanted_mask, backing_threshold: None }; + let peer_advertised = + |_identifier: &CandidateIdentifier, _peer: &_| Some(StatementFilter::full(group_size)); + + // Get request once successfully. + { + let request_props = + |_identifier: &CandidateIdentifier| Some((&request_properties).clone()); + let outgoing = request_manager + .next_request(&mut response_manager, request_props, peer_advertised) + .unwrap(); + assert_eq!(outgoing.payload.candidate_hash, candidate); + } + + // Validate response. + { + let statements = vec![]; + let response = UnhandledResponse { + response: TaggedResponse { + identifier, + requested_peer, + props: request_properties.clone(), + response: Ok(AttestedCandidateResponse { + candidate_receipt: candidate_receipt.clone(), + persisted_validation_data: persisted_validation_data.clone(), + statements, + }), + }, + }; + let validator_key_lookup = |_v| None; + let allowed_para_lookup = |_para, _g_index| true; + let statements = vec![]; + let output = response.validate_response( + &mut request_manager, + group, + 0, + validator_key_lookup, + allowed_para_lookup, + ); + assert_eq!( + output, + ResponseValidationOutput { + requested_peer, + request_status: CandidateRequestStatus::Complete { + candidate: candidate_receipt.clone(), + persisted_validation_data: persisted_validation_data.clone(), + statements, + }, + reputation_changes: vec![(requested_peer, BENEFIT_VALID_RESPONSE)], + } + ); + } + + // Ensure that cleanup occurred. + assert_eq!(request_manager.requests.len(), 0); + assert_eq!(request_manager.by_priority.len(), 0); + } +} diff --git a/polkadot/node/network/statement-distribution/src/vstaging/statement_store.rs b/polkadot/node/network/statement-distribution/src/vstaging/statement_store.rs new file mode 100644 index 0000000000000000000000000000000000000000..50ac99d0a8135482d7c4d70d2c089c58a0084b83 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/vstaging/statement_store.rs @@ -0,0 +1,283 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A store of all statements under a given relay-parent. +//! +//! This structure doesn't attempt to do any spam protection, which must +//! be provided at a higher level. +//! +//! This keeps track of statements submitted with a number of different of +//! views into this data: views based on the candidate, views based on the validator +//! groups, and views based on the validators themselves. + +use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; +use polkadot_node_network_protocol::vstaging::StatementFilter; +use polkadot_primitives::vstaging::{ + CandidateHash, CompactStatement, GroupIndex, SignedStatement, ValidatorIndex, +}; +use std::collections::hash_map::{Entry as HEntry, HashMap}; + +use super::groups::Groups; + +/// Possible origins of a statement. +pub enum StatementOrigin { + /// The statement originated locally. + Local, + /// The statement originated from a remote peer. + Remote, +} + +impl StatementOrigin { + fn is_local(&self) -> bool { + match *self { + StatementOrigin::Local => true, + StatementOrigin::Remote => false, + } + } +} + +struct StoredStatement { + statement: SignedStatement, + known_by_backing: bool, +} + +/// Storage for statements. Intended to be used for statements signed under +/// the same relay-parent. See module docs for more details. +pub struct StatementStore { + validator_meta: HashMap, + + // we keep statements per-group because even though only one group _should_ be + // producing statements about a candidate, until we have the candidate receipt + // itself, we can't tell which group that is. + group_statements: HashMap<(GroupIndex, CandidateHash), GroupStatements>, + known_statements: HashMap, +} + +impl StatementStore { + /// Create a new [`StatementStore`] + pub fn new(groups: &Groups) -> Self { + let mut validator_meta = HashMap::new(); + for (g, group) in groups.all().iter().enumerate() { + for (i, v) in group.iter().enumerate() { + validator_meta.insert( + *v, + ValidatorMeta { + seconded_count: 0, + within_group_index: i, + group: GroupIndex(g as _), + }, + ); + } + } + + StatementStore { + validator_meta, + group_statements: HashMap::new(), + known_statements: HashMap::new(), + } + } + + /// Insert a statement. Returns `true` if was not known already, `false` if it was. + /// Ignores statements by unknown validators and returns an error. + pub fn insert( + &mut self, + groups: &Groups, + statement: SignedStatement, + origin: StatementOrigin, + ) -> Result { + let validator_index = statement.validator_index(); + let validator_meta = match self.validator_meta.get_mut(&validator_index) { + None => return Err(ValidatorUnknown), + Some(m) => m, + }; + + let compact = statement.payload().clone(); + let fingerprint = (validator_index, compact.clone()); + match self.known_statements.entry(fingerprint) { + HEntry::Occupied(mut e) => { + if let StatementOrigin::Local = origin { + e.get_mut().known_by_backing = true; + } + + return Ok(false) + }, + HEntry::Vacant(e) => { + e.insert(StoredStatement { statement, known_by_backing: origin.is_local() }); + }, + } + + let candidate_hash = *compact.candidate_hash(); + let seconded = if let CompactStatement::Seconded(_) = compact { true } else { false }; + + // cross-reference updates. + { + let group_index = validator_meta.group; + let group = match groups.get(group_index) { + Some(g) => g, + None => { + gum::error!( + target: crate::LOG_TARGET, + ?group_index, + "groups passed into `insert` differ from those used at store creation" + ); + + return Err(ValidatorUnknown) + }, + }; + + let group_statements = self + .group_statements + .entry((group_index, candidate_hash)) + .or_insert_with(|| GroupStatements::with_group_size(group.len())); + + if seconded { + validator_meta.seconded_count += 1; + group_statements.note_seconded(validator_meta.within_group_index); + } else { + group_statements.note_validated(validator_meta.within_group_index); + } + } + + Ok(true) + } + + /// Fill a `StatementFilter` to be used in the grid topology with all statements + /// we are already aware of. + pub fn fill_statement_filter( + &self, + group_index: GroupIndex, + candidate_hash: CandidateHash, + statement_filter: &mut StatementFilter, + ) { + if let Some(statements) = self.group_statements.get(&(group_index, candidate_hash)) { + statement_filter.seconded_in_group |= statements.seconded.as_bitslice(); + statement_filter.validated_in_group |= statements.valid.as_bitslice(); + } + } + + /// Get an iterator over stored signed statements by the group conforming to the + /// given filter. + /// + /// Seconded statements are provided first. + pub fn group_statements<'a>( + &'a self, + groups: &'a Groups, + group_index: GroupIndex, + candidate_hash: CandidateHash, + filter: &'a StatementFilter, + ) -> impl Iterator + 'a { + let group_validators = groups.get(group_index); + + let seconded_statements = filter + .seconded_in_group + .iter_ones() + .filter_map(move |i| group_validators.as_ref().and_then(|g| g.get(i))) + .filter_map(move |v| { + self.known_statements.get(&(*v, CompactStatement::Seconded(candidate_hash))) + }) + .map(|s| &s.statement); + + let valid_statements = filter + .validated_in_group + .iter_ones() + .filter_map(move |i| group_validators.as_ref().and_then(|g| g.get(i))) + .filter_map(move |v| { + self.known_statements.get(&(*v, CompactStatement::Valid(candidate_hash))) + }) + .map(|s| &s.statement); + + seconded_statements.chain(valid_statements) + } + + /// Get the full statement of this kind issued by this validator, if it is known. + pub fn validator_statement( + &self, + validator_index: ValidatorIndex, + statement: CompactStatement, + ) -> Option<&SignedStatement> { + self.known_statements.get(&(validator_index, statement)).map(|s| &s.statement) + } + + /// Get an iterator over all statements marked as being unknown by the backing subsystem. + pub fn fresh_statements_for_backing<'a>( + &'a self, + validators: &'a [ValidatorIndex], + candidate_hash: CandidateHash, + ) -> impl Iterator + 'a { + let s_st = CompactStatement::Seconded(candidate_hash); + let v_st = CompactStatement::Valid(candidate_hash); + + validators + .iter() + .flat_map(move |v| { + let a = self.known_statements.get(&(*v, s_st.clone())); + let b = self.known_statements.get(&(*v, v_st.clone())); + + a.into_iter().chain(b) + }) + .filter(|stored| !stored.known_by_backing) + .map(|stored| &stored.statement) + } + + /// Get the amount of known `Seconded` statements by the given validator index. + pub fn seconded_count(&self, validator_index: &ValidatorIndex) -> usize { + self.validator_meta.get(validator_index).map_or(0, |m| m.seconded_count) + } + + /// Note that a statement is known by the backing subsystem. + pub fn note_known_by_backing( + &mut self, + validator_index: ValidatorIndex, + statement: CompactStatement, + ) { + if let Some(stored) = self.known_statements.get_mut(&(validator_index, statement)) { + stored.known_by_backing = true; + } + } +} + +/// Error indicating that the validator was unknown. +pub struct ValidatorUnknown; + +type Fingerprint = (ValidatorIndex, CompactStatement); + +struct ValidatorMeta { + group: GroupIndex, + within_group_index: usize, + seconded_count: usize, +} + +struct GroupStatements { + seconded: BitVec, + valid: BitVec, +} + +impl GroupStatements { + fn with_group_size(group_size: usize) -> Self { + GroupStatements { + seconded: BitVec::repeat(false, group_size), + valid: BitVec::repeat(false, group_size), + } + } + + fn note_seconded(&mut self, within_group_index: usize) { + self.seconded.set(within_group_index, true); + } + + fn note_validated(&mut self, within_group_index: usize) { + self.valid.set(within_group_index, true); + } +} diff --git a/polkadot/node/network/statement-distribution/src/vstaging/tests/cluster.rs b/polkadot/node/network/statement-distribution/src/vstaging/tests/cluster.rs new file mode 100644 index 0000000000000000000000000000000000000000..1ff53d3fd99eed1937faa4fbd8fd4e46f39d3bb4 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/vstaging/tests/cluster.rs @@ -0,0 +1,1257 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use polkadot_primitives_test_helpers::make_candidate; + +#[test] +fn share_seconded_circulated_to_cluster() { + let config = TestConfig { + validator_count: 20, + group_size: 3, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + { + let other_group_validators = state.group_validators(local_validator.group_index, true); + + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(other_group_validators[1])].into_iter().collect()), + ) + .await; + + connect_peer(&mut overseer, peer_c.clone(), None).await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + let full_signed = state + .sign_statement( + local_validator.validator_index, + CompactStatement::Seconded(candidate_hash), + &SigningContext { session_index: 1, parent_hash: relay_parent }, + ) + .convert_to_superpayload(StatementWithPVD::Seconded(candidate.clone(), pvd.clone())) + .unwrap(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, full_signed), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::Statement( + r, + s, + ) + )) + )) => { + assert_eq!(peers, vec![peer_a.clone()]); + assert_eq!(r, relay_parent); + assert_eq!(s.unchecked_payload(), &CompactStatement::Seconded(candidate_hash)); + assert_eq!(s.unchecked_validator_index(), local_validator.validator_index); + } + ); + + // sharing a `Seconded` message confirms a candidate, which leads to new + // fragment tree updates. + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + + overseer + }); +} + +#[test] +fn cluster_valid_statement_before_seconded_ignored() { + let config = TestConfig { + validator_count: 20, + group_size: 3, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + // peer A is in group, has relay parent in view. + let other_group_validators = state.group_validators(local_validator.group_index, true); + let v_a = other_group_validators[0]; + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + let signed_valid = state.sign_statement( + v_a, + CompactStatement::Valid(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement( + relay_parent, + signed_valid.as_unchecked().clone(), + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) => { + assert_eq!(p, peer_a); + assert_eq!(r, COST_UNEXPECTED_STATEMENT.into()); + } + ); + + overseer + }); +} + +#[test] +fn cluster_statement_bad_signature() { + let config = TestConfig { + validator_count: 20, + group_size: 3, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + // peer A is in group, has relay parent in view. + let other_group_validators = state.group_validators(local_validator.group_index, true); + let v_a = other_group_validators[0]; + let v_b = other_group_validators[1]; + + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // sign statements with wrong signing context, leading to bad signature. + let statements = vec![ + (v_a, CompactStatement::Seconded(candidate_hash)), + (v_b, CompactStatement::Seconded(candidate_hash)), + ] + .into_iter() + .map(|(v, s)| { + state.sign_statement( + v, + s, + &SigningContext { parent_hash: Hash::repeat_byte(69), session_index: 1 }, + ) + }) + .map(|s| s.as_unchecked().clone()); + + for statement in statements { + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement( + relay_parent, + statement.clone(), + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == COST_INVALID_SIGNATURE.into() => { }, + "{:?}", + statement + ); + } + + overseer + }); +} + +#[test] +fn useful_cluster_statement_from_non_cluster_peer_rejected() { + let config = TestConfig { + validator_count: 20, + group_size: 3, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + // peer A is not in group, has relay parent in view. + let not_our_group = + if local_validator.group_index.0 == 0 { GroupIndex(1) } else { GroupIndex(0) }; + + let that_group_validators = state.group_validators(not_our_group, false); + let v_non = that_group_validators[0]; + + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_non)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + let statement = state + .sign_statement( + v_non, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == COST_UNEXPECTED_STATEMENT.into() => { } + ); + + overseer + }); +} + +#[test] +fn statement_from_non_cluster_originator_unexpected() { + let config = TestConfig { + validator_count: 20, + group_size: 3, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let candidate_hash = CandidateHash(Hash::repeat_byte(42)); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + // peer A is not in group, has relay parent in view. + let other_group_validators = state.group_validators(local_validator.group_index, true); + let v_a = other_group_validators[0]; + + connect_peer(&mut overseer, peer_a.clone(), None).await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + let statement = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == COST_UNEXPECTED_STATEMENT.into() => { } + ); + + overseer + }); +} + +#[test] +fn seconded_statement_leads_to_request() { + let group_size = 3; + let config = TestConfig { + validator_count: 20, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + // peer A is in group, has relay parent in view. + let other_group_validators = state.group_validators(local_validator.group_index, true); + let v_a = other_group_validators[0]; + + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + let statement = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + + handle_sent_request( + &mut overseer, + peer_a, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + vec![], + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + + overseer + }); +} + +#[test] +fn cluster_statements_shared_seconded_first() { + let config = TestConfig { + validator_count: 20, + group_size: 3, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + // peer A is in group, no relay parent in view. + { + let other_group_validators = state.group_validators(local_validator.group_index, true); + + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), + ) + .await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + let full_signed = state + .sign_statement( + local_validator.validator_index, + CompactStatement::Seconded(candidate_hash), + &SigningContext { session_index: 1, parent_hash: relay_parent }, + ) + .convert_to_superpayload(StatementWithPVD::Seconded(candidate.clone(), pvd.clone())) + .unwrap(); + + let valid_signed = state + .sign_statement( + local_validator.validator_index, + CompactStatement::Valid(candidate_hash), + &SigningContext { session_index: 1, parent_hash: relay_parent }, + ) + .convert_to_superpayload(StatementWithPVD::Valid(candidate_hash)) + .unwrap(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, full_signed), + }) + .await; + + // result of new confirmed candidate. + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, valid_signed), + }) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessages(messages)) => { + assert_eq!(messages.len(), 2); + + assert_eq!(messages[0].0, vec![peer_a]); + assert_eq!(messages[1].0, vec![peer_a]); + + assert_matches!( + &messages[0].1, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::Statement( + r, + s, + ) + )) if r == &relay_parent + && s.unchecked_payload() == &CompactStatement::Seconded(candidate_hash) => {} + ); + + assert_matches!( + &messages[1].1, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::Statement( + r, + s, + ) + )) if r == &relay_parent + && s.unchecked_payload() == &CompactStatement::Valid(candidate_hash) => {} + ); + } + ); + + overseer + }); +} + +#[test] +fn cluster_accounts_for_implicit_view() { + let config = TestConfig { + validator_count: 20, + group_size: 3, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + { + let other_group_validators = state.group_validators(local_validator.group_index, true); + + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(other_group_validators[1])].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + let full_signed = state + .sign_statement( + local_validator.validator_index, + CompactStatement::Seconded(candidate_hash), + &SigningContext { session_index: 1, parent_hash: relay_parent }, + ) + .convert_to_superpayload(StatementWithPVD::Seconded(candidate.clone(), pvd.clone())) + .unwrap(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, full_signed), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::Statement( + r, + s, + ) + )) + )) => { + assert_eq!(peers, vec![peer_a.clone()]); + assert_eq!(r, relay_parent); + assert_eq!(s.unchecked_payload(), &CompactStatement::Seconded(candidate_hash)); + assert_eq!(s.unchecked_validator_index(), local_validator.validator_index); + } + ); + + // sharing a `Seconded` message confirms a candidate, which leads to new + // fragment tree updates. + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + + // activate new leaf, which has relay-parent in implicit view. + let next_relay_parent = Hash::repeat_byte(2); + let mut next_test_leaf = state.make_dummy_leaf(next_relay_parent); + next_test_leaf.parent_hash = relay_parent; + next_test_leaf.number = 2; + + activate_leaf(&mut overseer, &next_test_leaf, &state, false).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(next_relay_parent), + false, + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![next_relay_parent]).await; + send_peer_view_change(&mut overseer, peer_b.clone(), view![next_relay_parent]).await; + + // peer B never had the relay parent in its view, so this tests that + // the implicit view is working correctly for B. + // + // the fact that the statement isn't sent again to A also indicates that it works + // it's working. + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessages(messages)) => { + assert_eq!(messages.len(), 1); + assert_matches!( + &messages[0], + ( + peers, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::Statement( + r, + s, + ) + )) + ) => { + assert_eq!(peers, &vec![peer_b.clone()]); + assert_eq!(r, &relay_parent); + assert_eq!(s.unchecked_payload(), &CompactStatement::Seconded(candidate_hash)); + assert_eq!(s.unchecked_validator_index(), local_validator.validator_index); + } + ) + } + ); + + overseer + }); +} + +#[test] +fn cluster_messages_imported_after_confirmed_candidate_importable_check() { + let group_size = 3; + let config = TestConfig { + validator_count: 20, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + // peer A is in group, has relay parent in view. + let other_group_validators = state.group_validators(local_validator.group_index, true); + let v_a = other_group_validators[0]; + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Peer sends `Seconded` statement. + { + let a_seconded = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement( + relay_parent, + a_seconded, + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send a request to peer and mock its response. + { + handle_sent_request( + &mut overseer, + peer_a, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + vec![], + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() + ); + } + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![( + HypotheticalCandidate::Complete { + candidate_hash, + receipt: Arc::new(candidate.clone()), + persisted_validation_data: pvd.clone(), + }, + vec![(relay_parent, vec![0])], + )], + None, + false, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::CandidateBacking(CandidateBackingMessage::Statement( + r, + s, + )) if r == relay_parent => { + assert_matches!( + s.payload(), + FullStatementWithPVD::Seconded(c, p) + if c == &candidate && p == &pvd => {} + ); + assert_eq!(s.validator_index(), v_a); + } + ); + + overseer + }); +} + +#[test] +fn cluster_messages_imported_after_new_leaf_importable_check() { + let group_size = 3; + let config = TestConfig { + validator_count: 20, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + // peer A is in group, has relay parent in view. + let other_group_validators = state.group_validators(local_validator.group_index, true); + let v_a = other_group_validators[0]; + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Peer sends `Seconded` statement. + { + let a_seconded = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement( + relay_parent, + a_seconded, + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send a request to peer and mock its response. + { + handle_sent_request( + &mut overseer, + peer_a, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + vec![], + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { } + ); + } + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + + let next_relay_parent = Hash::repeat_byte(2); + let mut next_test_leaf = state.make_dummy_leaf(next_relay_parent); + next_test_leaf.parent_hash = relay_parent; + next_test_leaf.number = 2; + + activate_leaf(&mut overseer, &next_test_leaf, &state, false).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![( + HypotheticalCandidate::Complete { + candidate_hash, + receipt: Arc::new(candidate.clone()), + persisted_validation_data: pvd.clone(), + }, + vec![(relay_parent, vec![0])], + )], + Some(next_relay_parent), + false, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::CandidateBacking(CandidateBackingMessage::Statement( + r, + s, + )) if r == relay_parent => { + assert_matches!( + s.payload(), + FullStatementWithPVD::Seconded(c, p) + if c == &candidate && p == &pvd + ); + assert_eq!(s.validator_index(), v_a); + } + ); + + overseer + }); +} + +#[test] +fn ensure_seconding_limit_is_respected() { + // `max_candidate_depth: 1` for a `seconding_limit` of 2. + let config = TestConfig { + validator_count: 20, + group_size: 4, + local_validator: true, + async_backing_params: Some(AsyncBackingParams { + max_candidate_depth: 1, + allowed_ancestry_len: 3, + }), + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate_1, pvd_1) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let (candidate_2, pvd_2) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![7, 8, 9].into(), + Hash::repeat_byte(43).into(), + ); + let (candidate_3, _pvd_3) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![10, 11, 12].into(), + Hash::repeat_byte(44).into(), + ); + let candidate_hash_1 = candidate_1.hash(); + let candidate_hash_2 = candidate_2.hash(); + let candidate_hash_3 = candidate_3.hash(); + + let other_group_validators = state.group_validators(local_validator.group_index, true); + let v_a = other_group_validators[0]; + + // peers A,B,C are in group, have relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Confirm the candidates locally so that we don't send out requests. + + // Candidate 1. + { + let validator_index = state.local.as_ref().unwrap().validator_index; + let statement = state + .sign_full_statement( + validator_index, + Statement::Seconded(candidate_1), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + pvd_1, + ) + .clone(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, statement), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Candidate 2. + { + let validator_index = state.local.as_ref().unwrap().validator_index; + let statement = state + .sign_full_statement( + validator_index, + Statement::Seconded(candidate_2), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + pvd_2, + ) + .clone(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, statement), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Send first statement from peer A. + { + let statement = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash_1), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send second statement from peer A. + { + let statement = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash_2), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send third statement from peer A. + { + let statement = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash_3), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == COST_EXCESSIVE_SECONDED.into() => { } + ); + } + + overseer + }); +} diff --git a/polkadot/node/network/statement-distribution/src/vstaging/tests/grid.rs b/polkadot/node/network/statement-distribution/src/vstaging/tests/grid.rs new file mode 100644 index 0000000000000000000000000000000000000000..0c9fa60ed2e608ea86abfad3e85d59704157ca52 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/vstaging/tests/grid.rs @@ -0,0 +1,2455 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use bitvec::order::Lsb0; +use polkadot_node_network_protocol::vstaging::{ + BackedCandidateAcknowledgement, BackedCandidateManifest, +}; +use polkadot_node_subsystem::messages::CandidateBackingMessage; +use polkadot_primitives_test_helpers::make_candidate; + +// Backed candidate leads to advertisement to relevant validators with relay-parent. +#[test] +fn backed_candidate_leads_to_advertisement() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let other_group_validators = state.group_validators(local_validator.group_index, true); + let target_group_validators = + state.group_validators((local_validator.group_index.0 + 1).into(), true); + let v_a = other_group_validators[0]; + let v_b = other_group_validators[1]; + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + // peer D is not in group, has no relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(v_b)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + // Confirm the candidate locally so that we don't send out requests. + { + let statement = state + .sign_full_statement( + local_validator.validator_index, + Statement::Seconded(candidate.clone()), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + pvd.clone(), + ) + .clone(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, statement), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Send enough statements to make candidate backable, make sure announcements are sent. + + // Send statement from peer A. + { + let statement = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send statement from peer B. + { + let statement = state + .sign_statement( + v_b, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_b.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_b && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + } + + // Send Backed notification. + { + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Backed(candidate_hash), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging( + protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(manifest), + ), + ), + ) + ) => { + assert_eq!(peers, vec![peer_c]); + assert_eq!(manifest, BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: local_validator.group_index, + para_id: local_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }); + } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + overseer + }); +} + +#[test] +fn received_advertisement_before_confirmation_leads_to_request() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let other_group_validators = state.group_validators(local_validator.group_index, true); + let target_group_validators = state.group_validators(other_group, true); + let v_a = other_group_validators[0]; + let v_b = other_group_validators[1]; + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + // peer D is not in group, has relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(v_b)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_d.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + // Receive an advertisement from C on an unconfirmed candidate. + { + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(manifest), + ) + .await; + + let statements = vec![ + state + .sign_statement( + v_c, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + state + .sign_statement( + v_d, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + ]; + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + statements, + ) + .await; + + // C provided two statements we're seeing for the first time. + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() => { } + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() => { } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + overseer + }); +} + +// 1. We receive manifest from grid peer, request, pass votes to backing, then receive Backed +// message. Only then should we send an acknowledgement to the grid peer. +// +// 2. (starting from end state of (1)) we receive a manifest about the same candidate from another +// grid peer and instantaneously acknowledge. +// +// Bit more context about this design choice: Statement-distribution doesn't fully emulate the +// statement logic of backing and only focuses on the number of statements. That means that we might +// request a manifest and for some reason the backing subsystem would still not consider the +// candidate as backed. So, in particular, we don't want to advertise such an unbacked candidate +// along the grid & increase load on ourselves and our peers for serving & importing such a +// candidate. +#[test] +fn received_advertisement_after_backing_leads_to_acknowledgement() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + let peer_e = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let target_group_validators = state.group_validators(other_group, true); + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + let v_e = target_group_validators[2]; + + // Connect C, D, E + { + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_e.clone(), + Some(vec![state.discovery_id(v_e)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_d.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + let statement_c = state + .sign_statement( + v_c, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + let statement_d = state + .sign_statement( + v_d, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + // Receive an advertisement from C. + { + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + // Should send a request to C. + let statements = vec![ + statement_c.clone(), + statement_d.clone(), + state + .sign_statement( + v_e, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + ]; + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + statements, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Receive Backed message. + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Backed(candidate_hash), + }) + .await; + + // Should send an acknowledgement back to C. + { + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging( + protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::BackedCandidateKnown(ack), + ), + ), + ) + ) => { + assert_eq!(peers, vec![peer_c]); + assert_eq!(ack, BackedCandidateAcknowledgement { + candidate_hash, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }); + } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Receive a manifest about the same candidate from peer D. + { + send_peer_message( + &mut overseer, + peer_d.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + let expected_ack = BackedCandidateAcknowledgement { + candidate_hash, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + // Instantaneously acknowledge. + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessages(messages) + ) => { + assert_eq!(messages.len(), 1); + assert_eq!(messages[0].0, vec![peer_d]); + + assert_matches!( + &messages[0].1, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::BackedCandidateKnown(ack) + )) if *ack == expected_ack + ); + } + ); + } + + overseer + }); +} + +// Received advertisement after confirmation but before backing leads to nothing. +#[test] +fn received_advertisement_after_confirmation_before_backing() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + let peer_e = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let target_group_validators = state.group_validators(other_group, true); + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + let v_e = target_group_validators[2]; + + // Connect C, D, E + { + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_e.clone(), + Some(vec![state.discovery_id(v_e)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_d.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + let statement_c = state + .sign_statement( + v_c, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + let statement_d = state + .sign_statement( + v_d, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + // Receive an advertisement from C. + { + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + // Should send a request to C. + let statements = vec![ + statement_c.clone(), + statement_d.clone(), + state + .sign_statement( + v_e, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + ]; + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + statements, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Receive advertisement from peer D (after confirmation but before backing). + { + send_peer_message( + &mut overseer, + peer_d.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + } + + overseer + }); +} + +#[test] +fn additional_statements_are_shared_after_manifest_exchange() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + let peer_e = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let target_group_validators = state.group_validators(other_group, true); + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + let v_e = target_group_validators[2]; + + // Connect C, D, E + { + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_e.clone(), + Some(vec![state.discovery_id(v_e)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_d.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + // Receive an advertisement from C. + { + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + } + + // Should send a request to C. + { + let statements = vec![ + state + .sign_statement( + v_d, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + state + .sign_statement( + v_e, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + ]; + + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + statements, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() + ); + } + + let hypothetical = HypotheticalCandidate::Complete { + candidate_hash, + receipt: Arc::new(candidate.clone()), + persisted_validation_data: pvd.clone(), + }; + let membership = vec![(relay_parent, vec![0])]; + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![(hypothetical, membership)], + None, + false, + ) + .await; + + // Statements are sent to the Backing subsystem. + { + assert_matches!( + overseer.recv().await, + AllMessages::CandidateBacking( + CandidateBackingMessage::Statement(hash, statement) + ) => { + assert_eq!(hash, relay_parent); + assert_matches!( + statement.payload(), + FullStatementWithPVD::Seconded(c, p) + if c == &candidate && p == &pvd + ); + } + ); + assert_matches!( + overseer.recv().await, + AllMessages::CandidateBacking( + CandidateBackingMessage::Statement(hash, statement) + ) => { + assert_eq!(hash, relay_parent); + assert_matches!( + statement.payload(), + FullStatementWithPVD::Seconded(c, p) + if c == &candidate && p == &pvd + ); + } + ); + } + + // Receive Backed message. + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Backed(candidate_hash), + }) + .await; + + // Should send an acknowledgement back to C. + { + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging( + protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::BackedCandidateKnown(ack), + ), + ), + ) + ) => { + assert_eq!(peers, vec![peer_c]); + assert_eq!(ack, BackedCandidateAcknowledgement { + candidate_hash, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }); + } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Receive a manifest about the same candidate from peer D. Contains different statements. + { + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + send_peer_message( + &mut overseer, + peer_d.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + let expected_ack = BackedCandidateAcknowledgement { + candidate_hash, + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + // Instantaneously acknowledge. + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessages(messages) + ) => { + assert_eq!(messages.len(), 2); + assert_eq!(messages[0].0, vec![peer_d]); + assert_eq!(messages[1].0, vec![peer_d]); + + assert_matches!( + &messages[0].1, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::BackedCandidateKnown(ack) + )) if *ack == expected_ack + ); + + assert_matches!( + &messages[1].1, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::Statement(r, s) + )) if *r == relay_parent && s.unchecked_payload() == &CompactStatement::Seconded(candidate_hash) && s.unchecked_validator_index() == v_e + ); + } + ); + } + + overseer + }); +} + +// Grid-sending validator view entering relay-parent leads to advertisement. +#[test] +fn advertisement_sent_when_peer_enters_relay_parent_view() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let other_group_validators = state.group_validators(local_validator.group_index, true); + let target_group_validators = + state.group_validators((local_validator.group_index.0 + 1).into(), true); + let v_a = other_group_validators[0]; + let v_b = other_group_validators[1]; + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + // peer D is not in group, has no relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(v_b)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + // Confirm the candidate locally so that we don't send out requests. + { + let statement = state + .sign_full_statement( + local_validator.validator_index, + Statement::Seconded(candidate.clone()), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + pvd.clone(), + ) + .clone(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, statement), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Send enough statements to make candidate backable, make sure announcements are sent. + + // Send statement from peer A. + { + let statement = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send statement from peer B. + { + let statement = state + .sign_statement( + v_b, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_b.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_b && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + } + + // Send Backed notification. + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Backed(candidate_hash), + }) + .await; + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + + // Relay parent enters view of peer C. + { + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + + let expected_manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: local_validator.group_index, + para_id: local_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessages(messages) + ) => { + assert_eq!(messages.len(), 1); + assert_eq!(messages[0].0, vec![peer_c]); + + assert_matches!( + &messages[0].1, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(manifest) + )) => { + assert_eq!(*manifest, expected_manifest); + } + ); + } + ); + } + + overseer + }); +} + +// Advertisement not re-sent after re-entering relay parent (view oscillation). +#[test] +fn advertisement_not_re_sent_when_peer_re_enters_view() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let other_group_validators = state.group_validators(local_validator.group_index, true); + let target_group_validators = + state.group_validators((local_validator.group_index.0 + 1).into(), true); + let v_a = other_group_validators[0]; + let v_b = other_group_validators[1]; + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + // peer D is not in group, has no relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(v_b)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + // Confirm the candidate locally so that we don't send out requests. + { + let statement = state + .sign_full_statement( + local_validator.validator_index, + Statement::Seconded(candidate.clone()), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + pvd.clone(), + ) + .clone(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, statement), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Send enough statements to make candidate backable, make sure announcements are sent. + + // Send statement from peer A. + { + let statement = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send statement from peer B. + { + let statement = state + .sign_statement( + v_b, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_b.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_b && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + } + + // Send Backed notification. + { + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Backed(candidate_hash), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging( + protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(manifest), + ), + ), + ) + ) => { + assert_eq!(peers, vec![peer_c]); + assert_eq!(manifest, BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: local_validator.group_index, + para_id: local_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }); + } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Peer leaves view. + send_peer_view_change(&mut overseer, peer_c.clone(), view![]).await; + + // Peer re-enters view. + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + + overseer + }); +} + +// Grid statements imported to backing once candidate enters hypothetical frontier. +#[test] +fn grid_statements_imported_to_backing() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + let peer_e = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let target_group_validators = state.group_validators(other_group, true); + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + let v_e = target_group_validators[2]; + + // Connect C, D, E + { + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_e.clone(), + Some(vec![state.discovery_id(v_e)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_d.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + // Receive an advertisement from C. + { + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + } + + // Should send a request to C. + { + let statements = vec![ + state + .sign_statement( + v_d, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + state + .sign_statement( + v_e, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + ]; + + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + statements, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() + ); + } + + let hypothetical = HypotheticalCandidate::Complete { + candidate_hash, + receipt: Arc::new(candidate.clone()), + persisted_validation_data: pvd.clone(), + }; + let membership = vec![(relay_parent, vec![0])]; + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![(hypothetical, membership)], + None, + false, + ) + .await; + + // Receive messages from Backing subsystem. + { + assert_matches!( + overseer.recv().await, + AllMessages::CandidateBacking( + CandidateBackingMessage::Statement(hash, statement) + ) => { + assert_eq!(hash, relay_parent); + assert_matches!( + statement.payload(), + FullStatementWithPVD::Seconded(c, p) + if c == &candidate && p == &pvd + ); + } + ); + assert_matches!( + overseer.recv().await, + AllMessages::CandidateBacking( + CandidateBackingMessage::Statement(hash, statement) + ) => { + assert_eq!(hash, relay_parent); + assert_matches!( + statement.payload(), + FullStatementWithPVD::Seconded(c, p) + if c == &candidate && p == &pvd + ); + } + ); + } + + overseer + }); +} + +#[test] +fn advertisements_rejected_from_incorrect_peers() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let other_group_validators = state.group_validators(local_validator.group_index, true); + let target_group_validators = state.group_validators(other_group, true); + let v_a = other_group_validators[0]; + let v_b = other_group_validators[1]; + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + // peer D is not in group, has no relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(v_b)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + // Receive an advertisement from A (our group). + { + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == COST_UNEXPECTED_MANIFEST_DISALLOWED.into() => { } + ); + } + + // Receive an advertisement from B (our group). + { + send_peer_message( + &mut overseer, + peer_b.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(manifest), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_b && r == COST_UNEXPECTED_MANIFEST_DISALLOWED.into() => { } + ); + } + + overseer + }); +} + +#[test] +fn manifest_rejected_with_unknown_relay_parent() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let unknown_parent = Hash::repeat_byte(2); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + unknown_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let target_group_validators = state.group_validators(other_group, true); + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + + // peer C is not in group, has relay parent in view. + // peer D is not in group, has no relay parent in view. + { + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + let manifest = BackedCandidateManifest { + relay_parent: unknown_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + // Receive an advertisement from C. + { + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == COST_UNEXPECTED_MANIFEST_MISSING_KNOWLEDGE.into() => { } + ); + } + + overseer + }); +} + +#[test] +fn manifest_rejected_when_not_a_validator() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: false, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let other_group = GroupIndex::from(0); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let target_group_validators = state.group_validators(other_group, true); + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + + // peer C is not in group, has relay parent in view. + // peer D is not in group, has no relay parent in view. + { + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + // Receive an advertisement from C. + { + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == COST_UNEXPECTED_MANIFEST_MISSING_KNOWLEDGE.into() => { } + ); + } + + overseer + }); +} + +#[test] +fn manifest_rejected_when_group_does_not_match_para() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + // Create a mismatch between group and para. + let other_para = next_group_index(other_group, validator_count, group_size); + let other_para = ParaId::from(other_para.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let target_group_validators = state.group_validators(other_group, true); + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + + // peer C is not in group, has relay parent in view. + // peer D is not in group, has no relay parent in view. + { + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + // Receive an advertisement from C. + { + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == COST_MALFORMED_MANIFEST.into() => { } + ); + } + + overseer + }); +} + +#[test] +fn peer_reported_for_advertisement_conflicting_with_confirmed_candidate() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + let peer_e = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let target_group_validators = state.group_validators(other_group, true); + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + let v_e = target_group_validators[2]; + + // Connect C, D, E + { + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_e.clone(), + Some(vec![state.discovery_id(v_e)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_d.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 0], + }, + }; + + let statement_c = state + .sign_statement( + v_c, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + let statement_d = state + .sign_statement( + v_d, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + // Receive an advertisement from C. + { + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + // Should send a request to C. + let statements = vec![ + statement_c.clone(), + statement_d.clone(), + state + .sign_statement( + v_e, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + ]; + + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + statements, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Receive conflicting advertisement from peer C after confirmation. + // + // NOTE: This causes a conflict because we track received manifests on a per-validator + // basis, and this is the second time we're getting a manifest from C. + { + let mut manifest = manifest.clone(); + manifest.statement_knowledge = StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }; + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(manifest), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == COST_CONFLICTING_MANIFEST.into() + ); + } + + overseer + }); +} diff --git a/polkadot/node/network/statement-distribution/src/vstaging/tests/mod.rs b/polkadot/node/network/statement-distribution/src/vstaging/tests/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..f5f4c8443257b2b5ffe8ce32af77843b7fb9349e --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/vstaging/tests/mod.rs @@ -0,0 +1,606 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![allow(clippy::clone_on_copy)] + +use super::*; +use crate::*; +use polkadot_node_network_protocol::{ + grid_topology::TopologyPeerInfo, + request_response::{outgoing::Recipient, ReqProtocolNames}, + view, ObservedRole, +}; +use polkadot_node_primitives::Statement; +use polkadot_node_subsystem::messages::{ + network_bridge_event::NewGossipTopology, AllMessages, ChainApiMessage, FragmentTreeMembership, + HypotheticalCandidate, NetworkBridgeEvent, ProspectiveParachainsMessage, ReportPeerMessage, + RuntimeApiMessage, RuntimeApiRequest, +}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_node_subsystem_types::{jaeger, ActivatedLeaf, LeafStatus}; +use polkadot_node_subsystem_util::TimeoutExt; +use polkadot_primitives::vstaging::{ + AssignmentPair, AsyncBackingParams, BlockNumber, CommittedCandidateReceipt, CoreState, + GroupRotationInfo, HeadData, Header, IndexedVec, PersistedValidationData, ScheduledCore, + SessionIndex, SessionInfo, ValidatorPair, +}; +use sc_keystore::LocalKeystore; +use sp_application_crypto::Pair as PairT; +use sp_authority_discovery::AuthorityPair as AuthorityDiscoveryPair; +use sp_keyring::Sr25519Keyring; + +use assert_matches::assert_matches; +use futures::Future; +use parity_scale_codec::Encode; +use rand::{Rng, SeedableRng}; + +use std::sync::Arc; + +mod cluster; +mod grid; +mod requests; + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; + +const DEFAULT_ASYNC_BACKING_PARAMETERS: AsyncBackingParams = + AsyncBackingParams { max_candidate_depth: 4, allowed_ancestry_len: 3 }; + +// Some deterministic genesis hash for req/res protocol names +const GENESIS_HASH: Hash = Hash::repeat_byte(0xff); + +struct TestConfig { + validator_count: usize, + // how many validators to place in each group. + group_size: usize, + // whether the local node should be a validator + local_validator: bool, + async_backing_params: Option, +} + +#[derive(Debug, Clone)] +struct TestLocalValidator { + validator_index: ValidatorIndex, + group_index: GroupIndex, +} + +struct TestState { + config: TestConfig, + local: Option, + validators: Vec, + session_info: SessionInfo, + req_sender: async_channel::Sender, +} + +impl TestState { + fn from_config( + config: TestConfig, + req_sender: async_channel::Sender, + rng: &mut impl Rng, + ) -> Self { + if config.group_size == 0 { + panic!("group size cannot be 0"); + } + + let mut validators = Vec::new(); + let mut discovery_keys = Vec::new(); + let mut assignment_keys = Vec::new(); + let mut validator_groups = Vec::new(); + + let local_validator_pos = if config.local_validator { + // ensure local validator is always in a full group. + Some(rng.gen_range(0..config.validator_count).saturating_sub(config.group_size - 1)) + } else { + None + }; + + for i in 0..config.validator_count { + let validator_pair = if Some(i) == local_validator_pos { + // Note: the specific key is used to ensure the keystore holds + // this key and the subsystem can detect that it is a validator. + Sr25519Keyring::Ferdie.pair().into() + } else { + ValidatorPair::generate().0 + }; + let assignment_id = AssignmentPair::generate().0.public(); + let discovery_id = AuthorityDiscoveryPair::generate().0.public(); + + let group_index = i / config.group_size; + validators.push(validator_pair); + discovery_keys.push(discovery_id); + assignment_keys.push(assignment_id); + if validator_groups.len() == group_index { + validator_groups.push(vec![ValidatorIndex(i as _)]); + } else { + validator_groups.last_mut().unwrap().push(ValidatorIndex(i as _)); + } + } + + let local = if let Some(local_pos) = local_validator_pos { + Some(TestLocalValidator { + validator_index: ValidatorIndex(local_pos as _), + group_index: GroupIndex((local_pos / config.group_size) as _), + }) + } else { + None + }; + + let validator_public = validator_pubkeys(&validators); + let session_info = SessionInfo { + validators: validator_public, + discovery_keys, + validator_groups: IndexedVec::from(validator_groups), + assignment_keys, + n_cores: 0, + zeroth_delay_tranche_width: 0, + relay_vrf_modulo_samples: 0, + n_delay_tranches: 0, + no_show_slots: 0, + needed_approvals: 0, + active_validator_indices: vec![], + dispute_period: 6, + random_seed: [0u8; 32], + }; + + TestState { config, local, validators, session_info, req_sender } + } + + fn make_dummy_leaf(&self, relay_parent: Hash) -> TestLeaf { + TestLeaf { + number: 1, + hash: relay_parent, + parent_hash: Hash::repeat_byte(0), + session: 1, + availability_cores: self.make_availability_cores(|i| { + CoreState::Scheduled(ScheduledCore { + para_id: ParaId::from(i as u32), + collator: None, + }) + }), + para_data: (0..self.session_info.validator_groups.len()) + .map(|i| (ParaId::from(i as u32), PerParaData::new(1, vec![1, 2, 3].into()))) + .collect(), + } + } + + fn make_availability_cores(&self, f: impl Fn(usize) -> CoreState) -> Vec { + (0..self.session_info.validator_groups.len()).map(f).collect() + } + + fn make_dummy_topology(&self) -> NewGossipTopology { + let validator_count = self.config.validator_count; + NewGossipTopology { + session: 1, + topology: SessionGridTopology::new( + (0..validator_count).collect(), + (0..validator_count) + .map(|i| TopologyPeerInfo { + peer_ids: Vec::new(), + validator_index: ValidatorIndex(i as u32), + discovery_id: AuthorityDiscoveryPair::generate().0.public(), + }) + .collect(), + ), + local_index: self.local.as_ref().map(|local| local.validator_index), + } + } + + fn group_validators( + &self, + group_index: GroupIndex, + exclude_local: bool, + ) -> Vec { + self.session_info + .validator_groups + .get(group_index) + .unwrap() + .iter() + .cloned() + .filter(|&i| { + self.local.as_ref().map_or(true, |l| !exclude_local || l.validator_index != i) + }) + .collect() + } + + fn discovery_id(&self, validator_index: ValidatorIndex) -> AuthorityDiscoveryId { + self.session_info.discovery_keys[validator_index.0 as usize].clone() + } + + fn sign_statement( + &self, + validator_index: ValidatorIndex, + statement: CompactStatement, + context: &SigningContext, + ) -> SignedStatement { + let payload = statement.signing_payload(context); + let pair = &self.validators[validator_index.0 as usize]; + let signature = pair.sign(&payload[..]); + + SignedStatement::new(statement, validator_index, signature, context, &pair.public()) + .unwrap() + } + + fn sign_full_statement( + &self, + validator_index: ValidatorIndex, + statement: Statement, + context: &SigningContext, + pvd: PersistedValidationData, + ) -> SignedFullStatementWithPVD { + let payload = statement.to_compact().signing_payload(context); + let pair = &self.validators[validator_index.0 as usize]; + let signature = pair.sign(&payload[..]); + + SignedFullStatementWithPVD::new( + statement.supply_pvd(pvd), + validator_index, + signature, + context, + &pair.public(), + ) + .unwrap() + } + + // send a request out, returning a future which expects a response. + async fn send_request( + &mut self, + peer: PeerId, + request: AttestedCandidateRequest, + ) -> impl Future { + let (tx, rx) = futures::channel::oneshot::channel(); + let req = sc_network::config::IncomingRequest { + peer, + payload: request.encode(), + pending_response: tx, + }; + self.req_sender.send(req).await.unwrap(); + + rx.map(|r| r.unwrap()) + } +} + +fn test_harness>( + config: TestConfig, + test: impl FnOnce(TestState, VirtualOverseer) -> T, +) { + let pool = sp_core::testing::TaskExecutor::new(); + let keystore = if config.local_validator { + test_helpers::mock::make_ferdie_keystore() + } else { + Arc::new(LocalKeystore::in_memory()) as KeystorePtr + }; + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); + let (candidate_req_receiver, req_cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(0); + + let test_state = TestState::from_config(config, req_cfg.inbound_queue.unwrap(), &mut rng); + + let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); + let subsystem = async move { + let subsystem = crate::StatementDistributionSubsystem { + keystore, + v1_req_receiver: Some(statement_req_receiver), + req_receiver: Some(candidate_req_receiver), + metrics: Default::default(), + rng, + reputation: ReputationAggregator::new(|_| true), + }; + + if let Err(e) = subsystem.run(context).await { + panic!("Fatal error: {:?}", e); + } + }; + + let test_fut = test(test_state, virtual_overseer); + + futures::pin_mut!(test_fut); + futures::pin_mut!(subsystem); + futures::executor::block_on(future::join( + async move { + let mut virtual_overseer = test_fut.await; + // Ensure we have handled all responses. + if let Ok(Some(msg)) = virtual_overseer.rx.try_next() { + panic!("Did not handle all responses: {:?}", msg); + } + // Conclude. + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + }, + subsystem, + )); +} + +struct PerParaData { + min_relay_parent: BlockNumber, + head_data: HeadData, +} + +impl PerParaData { + pub fn new(min_relay_parent: BlockNumber, head_data: HeadData) -> Self { + Self { min_relay_parent, head_data } + } +} + +struct TestLeaf { + number: BlockNumber, + hash: Hash, + parent_hash: Hash, + session: SessionIndex, + availability_cores: Vec, + para_data: Vec<(ParaId, PerParaData)>, +} + +impl TestLeaf { + pub fn para_data(&self, para_id: ParaId) -> &PerParaData { + self.para_data + .iter() + .find_map(|(p_id, data)| if *p_id == para_id { Some(data) } else { None }) + .unwrap() + } +} + +async fn activate_leaf( + virtual_overseer: &mut VirtualOverseer, + leaf: &TestLeaf, + test_state: &TestState, + expect_session_info_request: bool, +) { + let activated = ActivatedLeaf { + hash: leaf.hash, + number: leaf.number, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }; + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( + activated, + )))) + .await; + + handle_leaf_activation(virtual_overseer, leaf, test_state, expect_session_info_request).await; +} + +async fn handle_leaf_activation( + virtual_overseer: &mut VirtualOverseer, + leaf: &TestLeaf, + test_state: &TestState, + expect_session_info_request: bool, +) { + let TestLeaf { number, hash, parent_hash, para_data, session, availability_cores } = leaf; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::StagingAsyncBackingParams(tx)) + ) if parent == *hash => { + tx.send(Ok(test_state.config.async_backing_params.unwrap_or(DEFAULT_ASYNC_BACKING_PARAMETERS))).unwrap(); + } + ); + + let mrp_response: Vec<(ParaId, BlockNumber)> = para_data + .iter() + .map(|(para_id, data)| (*para_id, data.min_relay_parent)) + .collect(); + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetMinimumRelayParents(parent, tx) + ) if parent == *hash => { + tx.send(mrp_response).unwrap(); + } + ); + + let header = Header { + parent_hash: *parent_hash, + number: *number, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + }; + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ChainApi( + ChainApiMessage::BlockHeader(parent, tx) + ) if parent == *hash => { + tx.send(Ok(Some(header))).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx))) if parent == *hash => { + tx.send(Ok(*session)).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::AvailabilityCores(tx))) if parent == *hash => { + tx.send(Ok(availability_cores.clone())).unwrap(); + } + ); + + let validator_groups = test_state.session_info.validator_groups.to_vec(); + let group_rotation_info = + GroupRotationInfo { session_start_block: 1, group_rotation_frequency: 12, now: 1 }; + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::ValidatorGroups(tx))) if parent == *hash => { + tx.send(Ok((validator_groups, group_rotation_info))).unwrap(); + } + ); + + if expect_session_info_request { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionInfo(s, tx))) if parent == *hash && s == *session => { + tx.send(Ok(Some(test_state.session_info.clone()))).unwrap(); + } + ); + } +} + +/// Intercepts an outgoing request, checks the fields, and sends the response. +async fn handle_sent_request( + virtual_overseer: &mut VirtualOverseer, + peer: PeerId, + candidate_hash: CandidateHash, + mask: StatementFilter, + candidate_receipt: CommittedCandidateReceipt, + persisted_validation_data: PersistedValidationData, + statements: Vec, +) { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendRequests(mut requests, IfDisconnected::ImmediateError)) => { + assert_eq!(requests.len(), 1); + assert_matches!( + requests.pop().unwrap(), + Requests::AttestedCandidateVStaging(outgoing) => { + assert_eq!(outgoing.peer, Recipient::Peer(peer)); + assert_eq!(outgoing.payload.candidate_hash, candidate_hash); + assert_eq!(outgoing.payload.mask, mask); + + let res = AttestedCandidateResponse { + candidate_receipt, + persisted_validation_data, + statements, + }; + outgoing.pending_response.send(Ok(res.encode())).unwrap(); + } + ); + } + ); +} + +async fn answer_expected_hypothetical_depth_request( + virtual_overseer: &mut VirtualOverseer, + responses: Vec<(HypotheticalCandidate, FragmentTreeMembership)>, + expected_leaf_hash: Option, + expected_backed_in_path_only: bool, +) { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetHypotheticalFrontier(req, tx) + ) => { + assert_eq!(req.fragment_tree_relay_parent, expected_leaf_hash); + assert_eq!(req.backed_in_path_only, expected_backed_in_path_only); + for (i, (candidate, _)) in responses.iter().enumerate() { + assert!( + req.candidates.iter().any(|c| &c == &candidate), + "did not receive request for hypothetical candidate {}", + i, + ); + } + + tx.send(responses).unwrap(); + } + ) +} + +fn validator_pubkeys(val_ids: &[ValidatorPair]) -> IndexedVec { + val_ids.iter().map(|v| v.public().into()).collect() +} + +async fn connect_peer( + virtual_overseer: &mut VirtualOverseer, + peer: PeerId, + authority_ids: Option>, +) { + virtual_overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Authority, + ValidationVersion::VStaging.into(), + authority_ids, + ), + ), + }) + .await; +} + +// TODO: Add some tests using this? +#[allow(dead_code)] +async fn disconnect_peer(virtual_overseer: &mut VirtualOverseer, peer: PeerId) { + virtual_overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerDisconnected(peer), + ), + }) + .await; +} + +async fn send_peer_view_change(virtual_overseer: &mut VirtualOverseer, peer: PeerId, view: View) { + virtual_overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(peer, view), + ), + }) + .await; +} + +async fn send_peer_message( + virtual_overseer: &mut VirtualOverseer, + peer: PeerId, + message: protocol_vstaging::StatementDistributionMessage, +) { + virtual_overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerMessage(peer, Versioned::VStaging(message)), + ), + }) + .await; +} + +async fn send_new_topology(virtual_overseer: &mut VirtualOverseer, topology: NewGossipTopology) { + virtual_overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::NewGossipTopology(topology), + ), + }) + .await; +} + +async fn overseer_recv_with_timeout( + overseer: &mut VirtualOverseer, + timeout: Duration, +) -> Option { + gum::trace!("waiting for message..."); + overseer.recv().timeout(timeout).await +} + +fn next_group_index( + group_index: GroupIndex, + validator_count: usize, + group_size: usize, +) -> GroupIndex { + let next_group = group_index.0 + 1; + let num_groups = + validator_count / group_size + if validator_count % group_size > 0 { 1 } else { 0 }; + GroupIndex::from(next_group % num_groups as u32) +} diff --git a/polkadot/node/network/statement-distribution/src/vstaging/tests/requests.rs b/polkadot/node/network/statement-distribution/src/vstaging/tests/requests.rs new file mode 100644 index 0000000000000000000000000000000000000000..a86ef97f780787d101789290fe931067dba4c330 --- /dev/null +++ b/polkadot/node/network/statement-distribution/src/vstaging/tests/requests.rs @@ -0,0 +1,1871 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use bitvec::order::Lsb0; +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_network_protocol::{ + request_response::vstaging as request_vstaging, vstaging::BackedCandidateManifest, +}; +use polkadot_primitives_test_helpers::make_candidate; +use sc_network::config::{ + IncomingRequest as RawIncomingRequest, OutgoingResponse as RawOutgoingResponse, +}; + +#[test] +fn cluster_peer_allowed_to_send_incomplete_statements() { + let group_size = 3; + let config = TestConfig { + validator_count: 20, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let other_group_validators = state.group_validators(local_validator.group_index, true); + let v_a = other_group_validators[0]; + let v_b = other_group_validators[1]; + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(other_group_validators[1])].into_iter().collect()), + ) + .await; + + connect_peer(&mut overseer, peer_c.clone(), None).await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Peer in cluster sends a statement, triggering a request. + { + let a_seconded = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement( + relay_parent, + a_seconded, + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send a request to peer and mock its response to include just one statement. + { + let b_seconded = state + .sign_statement( + v_b, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + let statements = vec![b_seconded.clone()]; + // `1` indicates statements NOT to request. + let mask = StatementFilter::blank(group_size); + handle_sent_request( + &mut overseer, + peer_a, + candidate_hash, + mask, + candidate.clone(), + pvd.clone(), + statements, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging( + protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::Statement(hash, statement), + ), + ), + ) + ) => { + assert_eq!(peers, vec![peer_a]); + assert_eq!(hash, relay_parent); + assert_eq!(statement, b_seconded); + } + ); + } + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + + overseer + }); +} + +#[test] +fn peer_reported_for_providing_statements_meant_to_be_masked_out() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: Some(AsyncBackingParams { + // Makes `seconding_limit: 2` (easier to hit the limit). + max_candidate_depth: 1, + allowed_ancestry_len: 3, + }), + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + let peer_e = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate_1, pvd_1) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let (candidate_2, pvd_2) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![7, 8, 9].into(), + Hash::repeat_byte(43).into(), + ); + let (candidate_3, pvd_3) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![10, 11, 12].into(), + Hash::repeat_byte(44).into(), + ); + let candidate_hash_1 = candidate_1.hash(); + let candidate_hash_2 = candidate_2.hash(); + let candidate_hash_3 = candidate_3.hash(); + + let target_group_validators = state.group_validators(other_group, true); + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + let v_e = target_group_validators[2]; + + // Connect C, D, E + { + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_e.clone(), + Some(vec![state.discovery_id(v_e)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_d.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + // Peer C advertises candidate 1. + { + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash: candidate_hash_1, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd_1.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 0], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + let statements = vec![ + state + .sign_statement( + v_c, + CompactStatement::Seconded(candidate_hash_1), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + state + .sign_statement( + v_d, + CompactStatement::Seconded(candidate_hash_1), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + ]; + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash_1, + StatementFilter::blank(group_size), + candidate_1.clone(), + pvd_1.clone(), + statements, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Peer C advertises candidate 2. + { + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash: candidate_hash_2, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd_2.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + let statements = vec![ + state + .sign_statement( + v_d, + CompactStatement::Seconded(candidate_hash_2), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + state + .sign_statement( + v_e, + CompactStatement::Seconded(candidate_hash_2), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + ]; + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash_2, + StatementFilter::blank(group_size), + candidate_2.clone(), + pvd_2.clone(), + statements, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Peer C sends an announcement for candidate 3. Should hit seconding limit for validator 1. + // + // NOTE: The manifest is immediately rejected before a request is made due to + // "over-seconding" validator 1. On the other hand, if the manifest does not include + // validator 1 as a seconder, then including its Second statement in the response instead + // would fail with "Un-requested Statement In Response". + { + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash: candidate_hash_3, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd_3.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }; + + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == COST_EXCESSIVE_SECONDED.into() + ); + } + + overseer + }); +} + +// Peer reported for not providing enough statements, request retried. +#[test] +fn peer_reported_for_not_enough_statements() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + let peer_e = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let target_group_validators = state.group_validators(other_group, true); + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + let v_e = target_group_validators[2]; + + // Connect C, D, E + { + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_e.clone(), + Some(vec![state.discovery_id(v_e)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_d.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 0], + }, + }; + + // Peer sends an announcement. + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + let c_seconded = state + .sign_statement( + v_c, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + let statements = vec![c_seconded.clone()]; + // `1` indicates statements NOT to request. + let mask = StatementFilter::blank(group_size); + + // We send a request to peer. Mock its response to include just one statement. + { + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash, + mask.clone(), + candidate.clone(), + pvd.clone(), + statements.clone(), + ) + .await; + + // The peer is reported for only sending one statement. + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == COST_INVALID_RESPONSE.into() => { } + ); + } + + // We re-try the request. + { + let statements = vec![ + c_seconded, + state + .sign_statement( + v_d, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + state + .sign_statement( + v_e, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + ]; + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash, + mask, + candidate.clone(), + pvd.clone(), + statements.clone(), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + overseer + }); +} + +// Test that a peer answering an `AttestedCandidateRequest` with duplicate statements is punished. +#[test] +fn peer_reported_for_duplicate_statements() { + let group_size = 3; + let config = TestConfig { + validator_count: 20, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let other_group_validators = state.group_validators(local_validator.group_index, true); + let v_a = other_group_validators[0]; + let v_b = other_group_validators[1]; + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(other_group_validators[1])].into_iter().collect()), + ) + .await; + + connect_peer(&mut overseer, peer_c.clone(), None).await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Peer in cluster sends a statement, triggering a request. + { + let a_seconded = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement( + relay_parent, + a_seconded, + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send a request to peer and mock its response to include two identical statements. + { + let b_seconded = state + .sign_statement( + v_b, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + let statements = vec![b_seconded.clone(), b_seconded.clone()]; + + handle_sent_request( + &mut overseer, + peer_a, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + statements, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == COST_UNREQUESTED_RESPONSE_STATEMENT.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging( + protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::Statement(hash, statement), + ), + ), + ) + ) => { + assert_eq!(peers, vec![peer_a]); + assert_eq!(hash, relay_parent); + assert_eq!(statement, b_seconded); + } + ); + } + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + + overseer + }); +} + +#[test] +fn peer_reported_for_providing_statements_with_invalid_signatures() { + let group_size = 3; + let config = TestConfig { + validator_count: 20, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let other_group_validators = state.group_validators(local_validator.group_index, true); + state.group_validators((local_validator.group_index.0 + 1).into(), true); + let v_a = other_group_validators[0]; + let v_b = other_group_validators[1]; + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(other_group_validators[1])].into_iter().collect()), + ) + .await; + + connect_peer(&mut overseer, peer_c.clone(), None).await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Peer in cluster sends a statement, triggering a request. + { + let a_seconded = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement( + relay_parent, + a_seconded, + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send a request to peer and mock its response to include invalid statements. + { + // Sign statement with wrong signing context, leading to bad signature. + let b_seconded_invalid = state + .sign_statement( + v_b, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: Hash::repeat_byte(42), session_index: 1 }, + ) + .as_unchecked() + .clone(); + let statements = vec![b_seconded_invalid.clone()]; + + handle_sent_request( + &mut overseer, + peer_a, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + statements, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == COST_INVALID_SIGNATURE.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + overseer + }); +} + +#[test] +fn peer_reported_for_providing_statements_with_wrong_validator_id() { + let group_size = 3; + let config = TestConfig { + validator_count: 20, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let other_group_validators = state.group_validators(local_validator.group_index, true); + let next_group_validators = + state.group_validators((local_validator.group_index.0 + 1).into(), true); + let v_a = other_group_validators[0]; + let v_c = next_group_validators[0]; + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(other_group_validators[1])].into_iter().collect()), + ) + .await; + + connect_peer(&mut overseer, peer_c.clone(), None).await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Peer in cluster sends a statement, triggering a request. + { + let a_seconded = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement( + relay_parent, + a_seconded, + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send a request to peer and mock its response to include a wrong validator ID. + { + let c_seconded_invalid = state + .sign_statement( + v_c, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + let statements = vec![c_seconded_invalid.clone()]; + + handle_sent_request( + &mut overseer, + peer_a, + candidate_hash, + StatementFilter::blank(group_size), + candidate.clone(), + pvd.clone(), + statements, + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == COST_UNREQUESTED_RESPONSE_STATEMENT.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + overseer + }); +} + +#[test] +fn local_node_sanity_checks_incoming_requests() { + let config = TestConfig { + validator_count: 20, + group_size: 3, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + test_harness(config, |mut state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + { + let other_group_validators = state.group_validators(local_validator.group_index, true); + + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(other_group_validators[1])].into_iter().collect()), + ) + .await; + + connect_peer(&mut overseer, peer_c.clone(), None).await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + let mask = StatementFilter::blank(state.config.group_size); + + // Should drop requests for unknown candidates. + { + let (pending_response, rx) = oneshot::channel(); + state + .req_sender + .send(RawIncomingRequest { + // Request from peer that received manifest. + peer: peer_c, + payload: request_vstaging::AttestedCandidateRequest { + candidate_hash: candidate.hash(), + mask: mask.clone(), + } + .encode(), + pending_response, + }) + .await + .unwrap(); + + assert_matches!(rx.await, Err(oneshot::Canceled)); + } + + // Confirm candidate. + { + let full_signed = state + .sign_statement( + local_validator.validator_index, + CompactStatement::Seconded(candidate_hash), + &SigningContext { session_index: 1, parent_hash: relay_parent }, + ) + .convert_to_superpayload(StatementWithPVD::Seconded(candidate.clone(), pvd.clone())) + .unwrap(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, full_signed), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging(protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::Statement( + r, + s, + ) + )) + )) => { + assert_eq!(peers, vec![peer_a.clone()]); + assert_eq!(r, relay_parent); + assert_eq!(s.unchecked_payload(), &CompactStatement::Seconded(candidate_hash)); + assert_eq!(s.unchecked_validator_index(), local_validator.validator_index); + } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Should drop requests from unknown peers. + { + let (pending_response, rx) = oneshot::channel(); + state + .req_sender + .send(RawIncomingRequest { + // Request from peer that received manifest. + peer: peer_d, + payload: request_vstaging::AttestedCandidateRequest { + candidate_hash: candidate.hash(), + mask: mask.clone(), + } + .encode(), + pending_response, + }) + .await + .unwrap(); + + assert_matches!(rx.await, Err(oneshot::Canceled)); + } + + // Should drop requests with bitfields of the wrong size. + { + let mask = StatementFilter::blank(state.config.group_size + 1); + let response = state + .send_request( + peer_c, + request_vstaging::AttestedCandidateRequest { + candidate_hash: candidate.hash(), + mask, + }, + ) + .await + .await; + + assert_matches!( + response, + RawOutgoingResponse { + result, + reputation_changes, + sent_feedback + } => { + assert_matches!(result, Err(())); + assert_eq!(reputation_changes, vec![COST_INVALID_REQUEST_BITFIELD_SIZE.into()]); + assert_matches!(sent_feedback, None); + } + ); + } + + // Local node should reject requests if we did not send a manifest to that peer. + { + let response = state + .send_request( + peer_c, + request_vstaging::AttestedCandidateRequest { + candidate_hash: candidate.hash(), + mask: mask.clone(), + }, + ) + .await + .await; + + // Should get `COST_UNEXPECTED_REQUEST` response. + assert_matches!( + response, + RawOutgoingResponse { + result, + reputation_changes, + sent_feedback + } => { + assert_matches!(result, Err(())); + assert_eq!(reputation_changes, vec![COST_UNEXPECTED_REQUEST.into()]); + assert_matches!(sent_feedback, None); + } + ); + } + + overseer + }); +} + +#[test] +fn local_node_respects_statement_mask() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + test_harness(config, |mut state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_para = ParaId::from(local_validator.group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let other_group_validators = state.group_validators(local_validator.group_index, true); + let target_group_validators = + state.group_validators((local_validator.group_index.0 + 1).into(), true); + let v_a = other_group_validators[0]; + let v_b = other_group_validators[1]; + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + // peer D is not in group, has no relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(v_b)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + // Confirm the candidate locally so that we don't send out requests. + { + let statement = state + .sign_full_statement( + local_validator.validator_index, + Statement::Seconded(candidate.clone()), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + pvd.clone(), + ) + .clone(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, statement), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Send enough statements to make candidate backable, make sure announcements are sent. + + // Send statement from peer A. + { + let statement = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send statement from peer B. + let statement_b = state + .sign_statement( + v_b, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + { + send_peer_message( + &mut overseer, + peer_b.clone(), + protocol_vstaging::StatementDistributionMessage::Statement( + relay_parent, + statement_b.clone(), + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_b && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + } + + // Send Backed notification. + { + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Backed(candidate_hash), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::VStaging( + protocol_vstaging::ValidationProtocol::StatementDistribution( + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(manifest), + ), + ), + ) + ) => { + assert_eq!(peers, vec![peer_c]); + assert_eq!(manifest, BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: local_validator.group_index, + para_id: local_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }); + } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // `1` indicates statements NOT to request. + let mask = StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }; + + // Incoming request to local node. Local node should send statements, respecting mask. + { + let response = state + .send_request( + peer_c, + request_vstaging::AttestedCandidateRequest { + candidate_hash: candidate.hash(), + mask, + }, + ) + .await + .await; + + let expected_statements = vec![statement_b]; + assert_matches!(response, full_response => { + // Response is the same for vstaging. + let request_vstaging::AttestedCandidateResponse { candidate_receipt, persisted_validation_data, statements } = + request_vstaging::AttestedCandidateResponse::decode( + &mut full_response.result.expect("We should have a proper answer").as_ref(), + ).expect("Decoding should work"); + assert_eq!(candidate_receipt, candidate); + assert_eq!(persisted_validation_data, pvd); + assert_eq!(statements, expected_statements); + }); + } + + overseer + }); +} + +#[test] +fn should_delay_before_retrying_dropped_requests() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: true, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + let peer_e = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + + let other_group = + next_group_index(local_validator.group_index, validator_count, group_size); + let other_para = ParaId::from(other_group.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate_1, pvd_1) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let (candidate_2, pvd_2) = make_candidate( + relay_parent, + 1, + other_para, + test_leaf.para_data(other_para).head_data.clone(), + vec![7, 8, 9].into(), + Hash::repeat_byte(43).into(), + ); + let candidate_hash_1 = candidate_1.hash(); + let candidate_hash_2 = candidate_2.hash(); + + let target_group_validators = state.group_validators(other_group, true); + let v_c = target_group_validators[0]; + let v_d = target_group_validators[1]; + let v_e = target_group_validators[2]; + + // Connect C, D, E + { + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_d.clone(), + Some(vec![state.discovery_id(v_d)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_e.clone(), + Some(vec![state.discovery_id(v_e)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_d.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true).await; + + answer_expected_hypothetical_depth_request( + &mut overseer, + vec![], + Some(relay_parent), + false, + ) + .await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + // `1` indicates statements NOT to request. + let mask = StatementFilter::blank(group_size); + + // Send a request about a candidate. + { + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash: candidate_hash_1, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd_1.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 0], + }, + }; + + // Peer sends an announcement. + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + // We send a request to peer. Drop the request without sending a response. + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendRequests(mut requests, IfDisconnected::ImmediateError)) => { + assert_eq!(requests.len(), 1); + assert_matches!( + requests.pop().unwrap(), + Requests::AttestedCandidateVStaging(outgoing) => { + assert_eq!(outgoing.peer, Recipient::Peer(peer_c)); + assert_eq!(outgoing.payload.candidate_hash, candidate_hash_1); + assert_eq!(outgoing.payload.mask, mask); + } + ); + } + ); + + assert_matches!( + overseer_recv_with_timeout(&mut overseer, Duration::from_millis(100)).await, + None + ); + } + + // We still send requests about different candidates as per usual. + { + let manifest = BackedCandidateManifest { + relay_parent, + candidate_hash: candidate_hash_2, + group_index: other_group, + para_id: other_para, + parent_head_data_hash: pvd_2.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 0], + }, + }; + + // Peer sends an announcement. + send_peer_message( + &mut overseer, + peer_c.clone(), + protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest( + manifest.clone(), + ), + ) + .await; + + let statements = vec![ + state + .sign_statement( + v_c, + CompactStatement::Seconded(candidate_hash_2), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + state + .sign_statement( + v_d, + CompactStatement::Seconded(candidate_hash_2), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + state + .sign_statement( + v_e, + CompactStatement::Seconded(candidate_hash_2), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + ]; + + // Don't drop this request. + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash_2, + mask.clone(), + candidate_2.clone(), + pvd_2.clone(), + statements.clone(), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + // Sleep for the given amount of time. This should reset the delay for the first candidate. + futures_timer::Delay::new(REQUEST_RETRY_DELAY).await; + + // We re-try the first request. + { + let statements = vec![ + state + .sign_statement( + v_c, + CompactStatement::Seconded(candidate_hash_1), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + state + .sign_statement( + v_d, + CompactStatement::Seconded(candidate_hash_1), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + state + .sign_statement( + v_e, + CompactStatement::Seconded(candidate_hash_1), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(), + ]; + handle_sent_request( + &mut overseer, + peer_c, + candidate_hash_1, + mask, + candidate_1.clone(), + pvd_1.clone(), + statements.clone(), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_STATEMENT.into() + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + } + + overseer + }); +} diff --git a/polkadot/node/overseer/Cargo.toml b/polkadot/node/overseer/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..2e601a46a744d977f56403739e09a83593bbae7b --- /dev/null +++ b/polkadot/node/overseer/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "polkadot-overseer" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +client = { package = "sc-client-api", git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures = "0.3.21" +futures-timer = "3.0.2" +parking_lot = "0.12.0" +polkadot-node-network-protocol = { path = "../network/protocol" } +polkadot-node-primitives = { path = "../primitives" } +polkadot-node-subsystem-types = { path = "../subsystem-types" } +polkadot-node-metrics = { path = "../metrics" } +polkadot-primitives = { path = "../../primitives" } +orchestra = "0.0.5" +gum = { package = "tracing-gum", path = "../gum" } +lru = "0.11.0" +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +async-trait = "0.1.57" +tikv-jemalloc-ctl = { version = "0.5.0", optional = true } + +[dev-dependencies] +metered = { package = "prioritized-metered-channel", version = "0.2.0" } + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures = { version = "0.3.21", features = ["thread-pool"] } +femme = "2.2.1" +assert_matches = "1.4.0" +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../primitives/test-helpers" } + +[target.'cfg(target_os = "linux")'.dependencies] +tikv-jemalloc-ctl = "0.5.0" + +[features] +default = [] +expand = ["orchestra/expand"] +dotgraph = ["orchestra/dotgraph"] +jemalloc-allocator = ["dep:tikv-jemalloc-ctl"] diff --git a/polkadot/node/overseer/examples/minimal-example.rs b/polkadot/node/overseer/examples/minimal-example.rs new file mode 100644 index 0000000000000000000000000000000000000000..a823b1d3961ec9549cc9a01dff3814b387611321 --- /dev/null +++ b/polkadot/node/overseer/examples/minimal-example.rs @@ -0,0 +1,180 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Shows a basic usage of the `Overseer`: +//! * Spawning subsystems and subsystem child jobs +//! * Establishing message passing + +use futures::{channel::oneshot, pending, pin_mut, select, stream, FutureExt, StreamExt}; +use futures_timer::Delay; +use orchestra::async_trait; +use std::time::Duration; + +use ::test_helpers::{dummy_candidate_descriptor, dummy_hash}; +use polkadot_node_primitives::{BlockData, PoV}; +use polkadot_node_subsystem_types::messages::CandidateValidationMessage; +use polkadot_overseer::{ + self as overseer, + dummy::dummy_overseer_builder, + gen::{FromOrchestra, SpawnedSubsystem}, + HeadSupportsParachains, SubsystemError, +}; +use polkadot_primitives::{CandidateReceipt, Hash, PvfExecTimeoutKind}; + +struct AlwaysSupportsParachains; + +#[async_trait] +impl HeadSupportsParachains for AlwaysSupportsParachains { + async fn head_supports_parachains(&self, _head: &Hash) -> bool { + true + } +} + +//////// + +struct Subsystem1; + +#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)] +impl Subsystem1 { + async fn run(mut ctx: Context) { + 'louy: loop { + match ctx.try_recv().await { + Ok(Some(msg)) => { + if let FromOrchestra::Communication { msg } = msg { + gum::info!("msg {:?}", msg); + } + continue 'louy + }, + Ok(None) => (), + Err(_) => { + gum::info!("exiting"); + break 'louy + }, + } + + Delay::new(Duration::from_secs(1)).await; + let (tx, _) = oneshot::channel(); + + let candidate_receipt = CandidateReceipt { + descriptor: dummy_candidate_descriptor(dummy_hash()), + commitments_hash: Hash::zero(), + }; + + let msg = CandidateValidationMessage::ValidateFromChainState( + candidate_receipt, + PoV { block_data: BlockData(Vec::new()) }.into(), + PvfExecTimeoutKind::Backing, + tx, + ); + ctx.send_message(msg).await; + } + () + } +} + +#[overseer::subsystem(CandidateBacking, error = SubsystemError, prefix = self::overseer)] +impl Subsystem1 { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = Box::pin(async move { + Self::run(ctx).await; + Ok(()) + }); + + SpawnedSubsystem { name: "subsystem-1", future } + } +} + +////////////////// + +struct Subsystem2; + +#[overseer::contextbounds(CandidateValidation, prefix = self::overseer)] +impl Subsystem2 { + async fn run(mut ctx: Context) -> () { + ctx.spawn( + "subsystem-2-job", + Box::pin(async { + loop { + gum::info!("Job tick"); + Delay::new(Duration::from_secs(1)).await; + } + }), + ) + .unwrap(); + + loop { + match ctx.try_recv().await { + Ok(Some(msg)) => { + gum::info!("Subsystem2 received message {:?}", msg); + continue + }, + Ok(None) => { + pending!(); + }, + Err(_) => { + gum::info!("exiting"); + return + }, + } + } + } +} + +#[overseer::subsystem(CandidateValidation, error = SubsystemError, prefix = self::overseer)] +impl Subsystem2 { + fn start(self, ctx: Context) -> SpawnedSubsystem { + let future = Box::pin(async move { + Self::run(ctx).await; + Ok(()) + }); + + SpawnedSubsystem { name: "subsystem-2", future } + } +} + +fn main() { + femme::with_level(femme::LevelFilter::Trace); + let spawner = sp_core::testing::TaskExecutor::new(); + futures::executor::block_on(async { + let timer_stream = stream::repeat(()).then(|_| async { + Delay::new(Duration::from_secs(1)).await; + }); + + let (overseer, _handle) = dummy_overseer_builder(spawner, AlwaysSupportsParachains, None) + .unwrap() + .replace_candidate_validation(|_| Subsystem2) + .replace_candidate_backing(|orig| orig) + .replace_candidate_backing(|_orig| Subsystem1) + .build() + .unwrap(); + + let overseer_fut = overseer.run().fuse(); + let timer_stream = timer_stream; + + pin_mut!(timer_stream); + pin_mut!(overseer_fut); + + loop { + select! { + _ = overseer_fut => break, + _ = timer_stream.next() => { + gum::info!("tick"); + } + complete => break, + } + } + }); +} diff --git a/polkadot/node/overseer/src/dummy.rs b/polkadot/node/overseer/src/dummy.rs new file mode 100644 index 0000000000000000000000000000000000000000..79daba1406769f8e256b5e435daf34163d345bbf --- /dev/null +++ b/polkadot/node/overseer/src/dummy.rs @@ -0,0 +1,201 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::{ + prometheus::Registry, HeadSupportsParachains, InitializedOverseerBuilder, MetricsTrait, + Overseer, OverseerMetrics, OverseerSignal, OverseerSubsystemContext, SpawnGlue, + KNOWN_LEAVES_CACHE_SIZE, +}; +use lru::LruCache; +use orchestra::{FromOrchestra, SpawnedSubsystem, Subsystem, SubsystemContext}; +use polkadot_node_subsystem_types::{errors::SubsystemError, messages::*}; +// Generated dummy messages +use crate::messages::*; + +/// A dummy subsystem that implements [`Subsystem`] for all +/// types of messages. Used for tests or as a placeholder. +#[derive(Clone, Copy, Debug)] +pub struct DummySubsystem; + +impl Subsystem for DummySubsystem +where + Context: SubsystemContext, +{ + fn start(self, mut ctx: Context) -> SpawnedSubsystem { + let future = Box::pin(async move { + loop { + match ctx.recv().await { + Err(_) => return Ok(()), + Ok(FromOrchestra::Signal(OverseerSignal::Conclude)) => return Ok(()), + Ok(overseer_msg) => { + gum::debug!( + target: "dummy-subsystem", + "Discarding a message sent from overseer {:?}", + overseer_msg + ); + continue + }, + } + } + }); + + SpawnedSubsystem { name: "dummy-subsystem", future } + } +} + +/// Create an overseer with all subsystem being `Sub`. +/// +/// Preferred way of initializing a dummy overseer for subsystem tests. +pub fn dummy_overseer_builder( + spawner: Spawner, + supports_parachains: SupportsParachains, + registry: Option<&Registry>, +) -> Result< + InitializedOverseerBuilder< + SpawnGlue, + SupportsParachains, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + >, + SubsystemError, +> +where + SpawnGlue: orchestra::Spawner + 'static, + SupportsParachains: HeadSupportsParachains, +{ + one_for_all_overseer_builder(spawner, supports_parachains, DummySubsystem, registry) +} + +/// Create an overseer with all subsystem being `Sub`. +pub fn one_for_all_overseer_builder( + spawner: Spawner, + supports_parachains: SupportsParachains, + subsystem: Sub, + registry: Option<&Registry>, +) -> Result< + InitializedOverseerBuilder< + SpawnGlue, + SupportsParachains, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + Sub, + >, + SubsystemError, +> +where + SpawnGlue: orchestra::Spawner + 'static, + SupportsParachains: HeadSupportsParachains, + Sub: Clone + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError> + + Subsystem, SubsystemError>, +{ + let metrics = ::register(registry)?; + + let builder = Overseer::builder() + .availability_distribution(subsystem.clone()) + .availability_recovery(subsystem.clone()) + .availability_store(subsystem.clone()) + .bitfield_distribution(subsystem.clone()) + .bitfield_signing(subsystem.clone()) + .candidate_backing(subsystem.clone()) + .candidate_validation(subsystem.clone()) + .pvf_checker(subsystem.clone()) + .chain_api(subsystem.clone()) + .collation_generation(subsystem.clone()) + .collator_protocol(subsystem.clone()) + .network_bridge_tx(subsystem.clone()) + .network_bridge_rx(subsystem.clone()) + .provisioner(subsystem.clone()) + .runtime_api(subsystem.clone()) + .statement_distribution(subsystem.clone()) + .approval_distribution(subsystem.clone()) + .approval_voting(subsystem.clone()) + .gossip_support(subsystem.clone()) + .dispute_coordinator(subsystem.clone()) + .dispute_distribution(subsystem.clone()) + .chain_selection(subsystem.clone()) + .prospective_parachains(subsystem.clone()) + .activation_external_listeners(Default::default()) + .span_per_active_leaf(Default::default()) + .active_leaves(Default::default()) + .known_leaves(LruCache::new(KNOWN_LEAVES_CACHE_SIZE)) + .spawner(SpawnGlue(spawner)) + .metrics(metrics) + .supports_parachains(supports_parachains); + Ok(builder) +} diff --git a/polkadot/node/overseer/src/lib.rs b/polkadot/node/overseer/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..5655a3ef79c17ca2183c6077daf3bff9a39e0e8f --- /dev/null +++ b/polkadot/node/overseer/src/lib.rs @@ -0,0 +1,949 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! # Overseer +//! +//! `overseer` implements the Overseer architecture described in the +//! [implementers-guide](https://w3f.github.io/parachain-implementers-guide/node/index.html). +//! For the motivations behind implementing the overseer itself you should +//! check out that guide, documentation in this crate will be mostly discussing +//! technical stuff. +//! +//! An `Overseer` is something that allows spawning/stopping and overseeing +//! asynchronous tasks as well as establishing a well-defined and easy to use +//! protocol that the tasks can use to communicate with each other. It is desired +//! that this protocol is the only way tasks communicate with each other, however +//! at this moment there are no foolproof guards against other ways of communication. +//! +//! The `Overseer` is instantiated with a pre-defined set of `Subsystems` that +//! share the same behavior from `Overseer`'s point of view. +//! +//! ```text +//! +-----------------------------+ +//! | Overseer | +//! +-----------------------------+ +//! +//! ................| Overseer "holds" these and uses |.............. +//! . them to (re)start things . +//! . . +//! . +-------------------+ +---------------------+ . +//! . | Subsystem1 | | Subsystem2 | . +//! . +-------------------+ +---------------------+ . +//! . | | . +//! .................................................................. +//! | | +//! start() start() +//! V V +//! ..................| Overseer "runs" these |....................... +//! . +--------------------+ +---------------------+ . +//! . | SubsystemInstance1 | | SubsystemInstance2 | . +//! . +--------------------+ +---------------------+ . +//! .................................................................. +//! ``` + +// #![deny(unused_results)] +// unused dependencies can not work for test and examples at the same time +// yielding false positives +#![warn(missing_docs)] + +use std::{ + collections::{hash_map, HashMap}, + fmt::{self, Debug}, + num::NonZeroUsize, + pin::Pin, + sync::Arc, + time::Duration, +}; + +use futures::{channel::oneshot, future::BoxFuture, select, Future, FutureExt, StreamExt}; +use lru::LruCache; + +use client::{BlockImportNotification, BlockchainEvents, FinalityNotification}; +use polkadot_primitives::{Block, BlockNumber, Hash}; + +use self::messages::{BitfieldSigningMessage, PvfCheckerMessage}; +use polkadot_node_subsystem_types::messages::{ + ApprovalDistributionMessage, ApprovalVotingMessage, AvailabilityDistributionMessage, + AvailabilityRecoveryMessage, AvailabilityStoreMessage, BitfieldDistributionMessage, + CandidateBackingMessage, CandidateValidationMessage, ChainApiMessage, ChainSelectionMessage, + CollationGenerationMessage, CollatorProtocolMessage, DisputeCoordinatorMessage, + DisputeDistributionMessage, GossipSupportMessage, NetworkBridgeRxMessage, + NetworkBridgeTxMessage, ProspectiveParachainsMessage, ProvisionerMessage, RuntimeApiMessage, + StatementDistributionMessage, +}; + +pub use polkadot_node_subsystem_types::{ + errors::{SubsystemError, SubsystemResult}, + jaeger, ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, OverseerSignal, + RuntimeApiSubsystemClient, +}; + +pub mod metrics; +pub use self::metrics::Metrics as OverseerMetrics; + +/// A dummy subsystem, mostly useful for placeholders and tests. +pub mod dummy; +pub use self::dummy::DummySubsystem; + +pub use polkadot_node_metrics::{ + metrics::{prometheus, Metrics as MetricsTrait}, + Metronome, +}; + +pub use orchestra as gen; +pub use orchestra::{ + contextbounds, orchestra, subsystem, FromOrchestra, MapSubsystem, MessagePacket, + OrchestraError as OverseerError, SignalsReceived, Spawner, Subsystem, SubsystemContext, + SubsystemIncomingMessages, SubsystemInstance, SubsystemMeterReadouts, SubsystemMeters, + SubsystemSender, TimeoutExt, ToOrchestra, +}; + +/// Store 2 days worth of blocks, not accounting for forks, +/// in the LRU cache. Assumes a 6-second block time. +pub const KNOWN_LEAVES_CACHE_SIZE: NonZeroUsize = match NonZeroUsize::new(2 * 24 * 3600 / 6) { + Some(cap) => cap, + None => panic!("Known leaves cache size must be non-zero"), +}; + +#[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] +mod memory_stats; +#[cfg(test)] +mod tests; + +use sp_core::traits::SpawnNamed; + +/// Glue to connect `trait orchestra::Spawner` and `SpawnNamed` from `substrate`. +pub struct SpawnGlue(pub S); + +impl AsRef for SpawnGlue { + fn as_ref(&self) -> &S { + &self.0 + } +} + +impl Clone for SpawnGlue { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl crate::gen::Spawner for SpawnGlue { + fn spawn_blocking( + &self, + name: &'static str, + group: Option<&'static str>, + future: futures::future::BoxFuture<'static, ()>, + ) { + SpawnNamed::spawn_blocking(&self.0, name, group, future) + } + fn spawn( + &self, + name: &'static str, + group: Option<&'static str>, + future: futures::future::BoxFuture<'static, ()>, + ) { + SpawnNamed::spawn(&self.0, name, group, future) + } +} + +/// Whether a header supports parachain consensus or not. +#[async_trait::async_trait] +pub trait HeadSupportsParachains { + /// Return true if the given header supports parachain consensus. Otherwise, false. + async fn head_supports_parachains(&self, head: &Hash) -> bool; +} + +#[async_trait::async_trait] +impl HeadSupportsParachains for Arc +where + Client: RuntimeApiSubsystemClient + Sync + Send, +{ + async fn head_supports_parachains(&self, head: &Hash) -> bool { + // Check that the `ParachainHost` runtime api is at least with version 1 present on chain. + self.api_version_parachain_host(*head).await.ok().flatten().unwrap_or(0) >= 1 + } +} + +/// A handle used to communicate with the [`Overseer`]. +/// +/// [`Overseer`]: struct.Overseer.html +#[derive(Clone)] +pub struct Handle(OverseerHandle); + +impl Handle { + /// Create a new [`Handle`]. + pub fn new(raw: OverseerHandle) -> Self { + Self(raw) + } + + /// Inform the `Overseer` that that some block was imported. + pub async fn block_imported(&mut self, block: BlockInfo) { + self.send_and_log_error(Event::BlockImported(block)).await + } + + /// Send some message to one of the `Subsystem`s. + pub async fn send_msg(&mut self, msg: impl Into, origin: &'static str) { + self.send_and_log_error(Event::MsgToSubsystem { msg: msg.into(), origin }).await + } + + /// Send a message not providing an origin. + #[inline(always)] + pub async fn send_msg_anon(&mut self, msg: impl Into) { + self.send_msg(msg, "").await + } + + /// Inform the `Overseer` that some block was finalized. + pub async fn block_finalized(&mut self, block: BlockInfo) { + self.send_and_log_error(Event::BlockFinalized(block)).await + } + + /// Wait for a block with the given hash to be in the active-leaves set. + /// + /// The response channel responds if the hash was activated and is closed if the hash was + /// deactivated. Note that due the fact the overseer doesn't store the whole active-leaves set, + /// only deltas, the response channel may never return if the hash was deactivated before this + /// call. In this case, it's the caller's responsibility to ensure a timeout is set. + pub async fn wait_for_activation( + &mut self, + hash: Hash, + response_channel: oneshot::Sender>, + ) { + self.send_and_log_error(Event::ExternalRequest(ExternalRequest::WaitForActivation { + hash, + response_channel, + })) + .await; + } + + /// Tell `Overseer` to shutdown. + pub async fn stop(&mut self) { + self.send_and_log_error(Event::Stop).await; + } + + /// Most basic operation, to stop a server. + async fn send_and_log_error(&mut self, event: Event) { + if self.0.send(event).await.is_err() { + gum::info!(target: LOG_TARGET, "Failed to send an event to Overseer"); + } + } +} + +/// An event telling the `Overseer` on the particular block +/// that has been imported or finalized. +/// +/// This structure exists solely for the purposes of decoupling +/// `Overseer` code from the client code and the necessity to call +/// `HeaderBackend::block_number_from_id()`. +#[derive(Debug, Clone)] +pub struct BlockInfo { + /// hash of the block. + pub hash: Hash, + /// hash of the parent block. + pub parent_hash: Hash, + /// block's number. + pub number: BlockNumber, +} + +impl From> for BlockInfo { + fn from(n: BlockImportNotification) -> Self { + BlockInfo { hash: n.hash, parent_hash: n.header.parent_hash, number: n.header.number } + } +} + +impl From> for BlockInfo { + fn from(n: FinalityNotification) -> Self { + BlockInfo { hash: n.hash, parent_hash: n.header.parent_hash, number: n.header.number } + } +} + +/// An event from outside the overseer scope, such +/// as the substrate framework or user interaction. +pub enum Event { + /// A new block was imported. + BlockImported(BlockInfo), + /// A block was finalized with i.e. babe or another consensus algorithm. + BlockFinalized(BlockInfo), + /// Message as sent to a subsystem. + MsgToSubsystem { + /// The actual message. + msg: AllMessages, + /// The originating subsystem name. + origin: &'static str, + }, + /// A request from the outer world. + ExternalRequest(ExternalRequest), + /// Stop the overseer on i.e. a UNIX signal. + Stop, +} + +/// Some request from outer world. +pub enum ExternalRequest { + /// Wait for the activation of a particular hash + /// and be notified by means of the return channel. + WaitForActivation { + /// The relay parent for which activation to wait for. + hash: Hash, + /// Response channel to await on. + response_channel: oneshot::Sender>, + }, +} + +/// Glues together the [`Overseer`] and `BlockchainEvents` by forwarding +/// import and finality notifications into the [`OverseerHandle`]. +pub async fn forward_events>(client: Arc

, mut handle: Handle) { + let mut finality = client.finality_notification_stream(); + let mut imports = client.import_notification_stream(); + + loop { + select! { + f = finality.next() => { + match f { + Some(block) => { + handle.block_finalized(block.into()).await; + } + None => break, + } + }, + i = imports.next() => { + match i { + Some(block) => { + handle.block_imported(block.into()).await; + } + None => break, + } + }, + complete => break, + } + } +} + +/// Create a new instance of the [`Overseer`] with a fixed set of [`Subsystem`]s. +/// +/// This returns the overseer along with an [`OverseerHandle`] which can +/// be used to send messages from external parts of the codebase. +/// +/// The [`OverseerHandle`] returned from this function is connected to +/// the returned [`Overseer`]. +/// +/// ```text +/// +------------------------------------+ +/// | Overseer | +/// +------------------------------------+ +/// / | | \ +/// ................. subsystems................................... +/// . +-----------+ +-----------+ +----------+ +---------+ . +/// . | | | | | | | | . +/// . +-----------+ +-----------+ +----------+ +---------+ . +/// ............................................................... +/// | +/// probably `spawn` +/// a `job` +/// | +/// V +/// +-----------+ +/// | | +/// +-----------+ +/// ``` +/// +/// [`Subsystem`]: trait.Subsystem.html +/// +/// # Example +/// +/// The [`Subsystems`] may be any type as long as they implement an expected interface. +/// Here, we create a mock validation subsystem and a few dummy ones and start the `Overseer` with +/// them. For the sake of simplicity the termination of the example is done with a timeout. +/// ``` +/// # use std::time::Duration; +/// # use futures::{executor, pin_mut, select, FutureExt}; +/// # use futures_timer::Delay; +/// # use polkadot_primitives::Hash; +/// # use polkadot_overseer::{ +/// # self as overseer, +/// # OverseerSignal, +/// # SubsystemSender as _, +/// # AllMessages, +/// # HeadSupportsParachains, +/// # Overseer, +/// # SubsystemError, +/// # gen::{ +/// # SubsystemContext, +/// # FromOrchestra, +/// # SpawnedSubsystem, +/// # }, +/// # }; +/// # use polkadot_node_subsystem_types::messages::{ +/// # CandidateValidationMessage, CandidateBackingMessage, +/// # NetworkBridgeTxMessage, +/// # }; +/// +/// struct ValidationSubsystem; +/// +/// impl overseer::Subsystem for ValidationSubsystem +/// where +/// Ctx: overseer::SubsystemContext< +/// Message=CandidateValidationMessage, +/// AllMessages=AllMessages, +/// Signal=OverseerSignal, +/// Error=SubsystemError, +/// >, +/// { +/// fn start( +/// self, +/// mut ctx: Ctx, +/// ) -> SpawnedSubsystem { +/// SpawnedSubsystem { +/// name: "validation-subsystem", +/// future: Box::pin(async move { +/// loop { +/// Delay::new(Duration::from_secs(1)).await; +/// } +/// }), +/// } +/// } +/// } +/// +/// # fn main() { executor::block_on(async move { +/// +/// struct AlwaysSupportsParachains; +/// +/// #[async_trait::async_trait] +/// impl HeadSupportsParachains for AlwaysSupportsParachains { +/// async fn head_supports_parachains(&self, _head: &Hash) -> bool { true } +/// } +/// +/// let spawner = sp_core::testing::TaskExecutor::new(); +/// let (overseer, _handle) = dummy_overseer_builder(spawner, AlwaysSupportsParachains, None) +/// .unwrap() +/// .replace_candidate_validation(|_| ValidationSubsystem) +/// .build() +/// .unwrap(); +/// +/// let timer = Delay::new(Duration::from_millis(50)).fuse(); +/// +/// let overseer_fut = overseer.run().fuse(); +/// pin_mut!(timer); +/// pin_mut!(overseer_fut); +/// +/// select! { +/// _ = overseer_fut => (), +/// _ = timer => (), +/// } +/// # +/// # }); +/// # } +/// ``` +#[orchestra( + gen=AllMessages, + event=Event, + signal=OverseerSignal, + error=SubsystemError, + message_capacity=2048, +)] +pub struct Overseer { + #[subsystem(CandidateValidationMessage, sends: [ + RuntimeApiMessage, + ])] + candidate_validation: CandidateValidation, + + #[subsystem(sends: [ + CandidateValidationMessage, + RuntimeApiMessage, + ])] + pvf_checker: PvfChecker, + + #[subsystem(CandidateBackingMessage, sends: [ + CandidateValidationMessage, + CollatorProtocolMessage, + ChainApiMessage, + AvailabilityDistributionMessage, + AvailabilityStoreMessage, + StatementDistributionMessage, + ProvisionerMessage, + RuntimeApiMessage, + ProspectiveParachainsMessage, + ])] + candidate_backing: CandidateBacking, + + #[subsystem(StatementDistributionMessage, sends: [ + NetworkBridgeTxMessage, + CandidateBackingMessage, + RuntimeApiMessage, + ProspectiveParachainsMessage, + ChainApiMessage, + ])] + statement_distribution: StatementDistribution, + + #[subsystem(AvailabilityDistributionMessage, sends: [ + AvailabilityStoreMessage, + AvailabilityRecoveryMessage, + ChainApiMessage, + RuntimeApiMessage, + NetworkBridgeTxMessage, + ])] + availability_distribution: AvailabilityDistribution, + + #[subsystem(AvailabilityRecoveryMessage, sends: [ + NetworkBridgeTxMessage, + RuntimeApiMessage, + AvailabilityStoreMessage, + ])] + availability_recovery: AvailabilityRecovery, + + #[subsystem(blocking, sends: [ + AvailabilityStoreMessage, + RuntimeApiMessage, + BitfieldDistributionMessage, + ])] + bitfield_signing: BitfieldSigning, + + #[subsystem(BitfieldDistributionMessage, sends: [ + RuntimeApiMessage, + NetworkBridgeTxMessage, + ProvisionerMessage, + ])] + bitfield_distribution: BitfieldDistribution, + + #[subsystem(ProvisionerMessage, sends: [ + RuntimeApiMessage, + CandidateBackingMessage, + ChainApiMessage, + DisputeCoordinatorMessage, + ProspectiveParachainsMessage, + ])] + provisioner: Provisioner, + + #[subsystem(blocking, RuntimeApiMessage, sends: [])] + runtime_api: RuntimeApi, + + #[subsystem(blocking, AvailabilityStoreMessage, sends: [ + ChainApiMessage, + RuntimeApiMessage, + ])] + availability_store: AvailabilityStore, + + #[subsystem(blocking, NetworkBridgeRxMessage, sends: [ + BitfieldDistributionMessage, + StatementDistributionMessage, + ApprovalDistributionMessage, + GossipSupportMessage, + DisputeDistributionMessage, + CollationGenerationMessage, + CollatorProtocolMessage, + ])] + network_bridge_rx: NetworkBridgeRx, + + #[subsystem(blocking, NetworkBridgeTxMessage, sends: [])] + network_bridge_tx: NetworkBridgeTx, + + #[subsystem(blocking, ChainApiMessage, sends: [])] + chain_api: ChainApi, + + #[subsystem(CollationGenerationMessage, sends: [ + RuntimeApiMessage, + CollatorProtocolMessage, + ])] + collation_generation: CollationGeneration, + + #[subsystem(CollatorProtocolMessage, sends: [ + NetworkBridgeTxMessage, + RuntimeApiMessage, + CandidateBackingMessage, + ChainApiMessage, + ProspectiveParachainsMessage, + ])] + collator_protocol: CollatorProtocol, + + #[subsystem(blocking, message_capacity: 64000, ApprovalDistributionMessage, sends: [ + NetworkBridgeTxMessage, + ApprovalVotingMessage, + ])] + approval_distribution: ApprovalDistribution, + + #[subsystem(blocking, ApprovalVotingMessage, sends: [ + ApprovalDistributionMessage, + AvailabilityRecoveryMessage, + CandidateValidationMessage, + ChainApiMessage, + ChainSelectionMessage, + DisputeCoordinatorMessage, + RuntimeApiMessage, + ])] + approval_voting: ApprovalVoting, + + #[subsystem(GossipSupportMessage, sends: [ + NetworkBridgeTxMessage, + NetworkBridgeRxMessage, // TODO + RuntimeApiMessage, + ChainSelectionMessage, + ])] + gossip_support: GossipSupport, + + #[subsystem(blocking, message_capacity: 32000, DisputeCoordinatorMessage, sends: [ + RuntimeApiMessage, + ChainApiMessage, + DisputeDistributionMessage, + CandidateValidationMessage, + ApprovalVotingMessage, + AvailabilityStoreMessage, + AvailabilityRecoveryMessage, + ChainSelectionMessage, + ])] + dispute_coordinator: DisputeCoordinator, + + #[subsystem(DisputeDistributionMessage, sends: [ + RuntimeApiMessage, + DisputeCoordinatorMessage, + NetworkBridgeTxMessage, + ])] + dispute_distribution: DisputeDistribution, + + #[subsystem(blocking, ChainSelectionMessage, sends: [ChainApiMessage])] + chain_selection: ChainSelection, + + #[subsystem(ProspectiveParachainsMessage, sends: [ + RuntimeApiMessage, + ChainApiMessage, + ])] + prospective_parachains: ProspectiveParachains, + + /// External listeners waiting for a hash to be in the active-leave set. + pub activation_external_listeners: HashMap>>>, + + /// Stores the [`jaeger::Span`] per active leaf. + pub span_per_active_leaf: HashMap>, + + /// The set of the "active leaves". + pub active_leaves: HashMap, + + /// An implementation for checking whether a header supports parachain consensus. + pub supports_parachains: SupportsParachains, + + /// An LRU cache for keeping track of relay-chain heads that have already been seen. + pub known_leaves: LruCache, + + /// Various Prometheus metrics. + pub metrics: OverseerMetrics, +} + +/// Spawn the metrics metronome task. +pub fn spawn_metronome_metrics( + overseer: &mut Overseer, + metronome_metrics: OverseerMetrics, +) -> Result<(), SubsystemError> +where + S: Spawner, + SupportsParachains: HeadSupportsParachains, +{ + struct ExtractNameAndMeters; + + impl<'a, T: 'a> MapSubsystem<&'a OrchestratedSubsystem> for ExtractNameAndMeters { + type Output = Option<(&'static str, SubsystemMeters)>; + + fn map_subsystem(&self, subsystem: &'a OrchestratedSubsystem) -> Self::Output { + subsystem + .instance + .as_ref() + .map(|instance| (instance.name, instance.meters.clone())) + } + } + let subsystem_meters = overseer.map_subsystems(ExtractNameAndMeters); + + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + let collect_memory_stats: Box = + match memory_stats::MemoryAllocationTracker::new() { + Ok(memory_stats) => + Box::new(move |metrics: &OverseerMetrics| match memory_stats.snapshot() { + Ok(memory_stats_snapshot) => { + gum::trace!( + target: LOG_TARGET, + "memory_stats: {:?}", + &memory_stats_snapshot + ); + metrics.memory_stats_snapshot(memory_stats_snapshot); + }, + Err(e) => + gum::debug!(target: LOG_TARGET, "Failed to obtain memory stats: {:?}", e), + }), + Err(_) => { + gum::debug!( + target: LOG_TARGET, + "Memory allocation tracking is not supported by the allocator.", + ); + + Box::new(|_| {}) + }, + }; + + #[cfg(not(any(target_os = "linux", feature = "jemalloc-allocator")))] + let collect_memory_stats: Box = Box::new(|_| {}); + + let metronome = Metronome::new(std::time::Duration::from_millis(950)).for_each(move |_| { + collect_memory_stats(&metronome_metrics); + + // We combine the amount of messages from subsystems to the overseer + // as well as the amount of messages from external sources to the overseer + // into one `to_overseer` value. + metronome_metrics.channel_metrics_snapshot( + subsystem_meters + .iter() + .cloned() + .flatten() + .map(|(name, ref meters)| (name, meters.read())), + ); + + futures::future::ready(()) + }); + overseer + .spawner() + .spawn("metrics-metronome", Some("overseer"), Box::pin(metronome)); + + Ok(()) +} + +impl Overseer +where + SupportsParachains: HeadSupportsParachains, + S: Spawner, +{ + /// Stop the `Overseer`. + async fn stop(mut self) { + let _ = self.wait_terminate(OverseerSignal::Conclude, Duration::from_secs(1_u64)).await; + } + + /// Run the `Overseer`. + /// + /// Logging any errors. + pub async fn run(self) { + if let Err(err) = self.run_inner().await { + gum::error!(target: LOG_TARGET, ?err, "Overseer exited with error"); + } + } + + async fn run_inner(mut self) -> SubsystemResult<()> { + let metrics = self.metrics.clone(); + spawn_metronome_metrics(&mut self, metrics)?; + + loop { + select! { + msg = self.events_rx.select_next_some() => { + match msg { + Event::MsgToSubsystem { msg, origin } => { + self.route_message(msg.into(), origin).await?; + self.metrics.on_message_relayed(); + } + Event::Stop => { + self.stop().await; + return Ok(()); + } + Event::BlockImported(block) => { + self.block_imported(block).await?; + } + Event::BlockFinalized(block) => { + self.block_finalized(block).await?; + } + Event::ExternalRequest(request) => { + self.handle_external_request(request); + } + } + }, + msg = self.to_orchestra_rx.select_next_some() => { + match msg { + ToOrchestra::SpawnJob { name, subsystem, s } => { + self.spawn_job(name, subsystem, s); + } + ToOrchestra::SpawnBlockingJob { name, subsystem, s } => { + self.spawn_blocking_job(name, subsystem, s); + } + } + }, + res = self.running_subsystems.select_next_some() => { + gum::error!( + target: LOG_TARGET, + subsystem = ?res, + "subsystem finished unexpectedly", + ); + self.stop().await; + return res; + }, + } + } + } + + async fn block_imported(&mut self, block: BlockInfo) -> SubsystemResult<()> { + match self.active_leaves.entry(block.hash) { + hash_map::Entry::Vacant(entry) => entry.insert(block.number), + hash_map::Entry::Occupied(entry) => { + debug_assert_eq!(*entry.get(), block.number); + return Ok(()) + }, + }; + + let mut update = match self.on_head_activated(&block.hash, Some(block.parent_hash)).await { + Some((span, status)) => ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: block.hash, + number: block.number, + status, + span, + }), + None => ActiveLeavesUpdate::default(), + }; + + if let Some(number) = self.active_leaves.remove(&block.parent_hash) { + debug_assert_eq!(block.number.saturating_sub(1), number); + update.deactivated.push(block.parent_hash); + self.on_head_deactivated(&block.parent_hash); + } + + self.clean_up_external_listeners(); + + if !update.is_empty() { + self.broadcast_signal(OverseerSignal::ActiveLeaves(update)).await?; + } + Ok(()) + } + + async fn block_finalized(&mut self, block: BlockInfo) -> SubsystemResult<()> { + let mut update = ActiveLeavesUpdate::default(); + + self.active_leaves.retain(|h, n| { + // prune all orphaned leaves, but don't prune + // the finalized block if it is itself a leaf. + if *n <= block.number && *h != block.hash { + update.deactivated.push(*h); + false + } else { + true + } + }); + + for deactivated in &update.deactivated { + self.on_head_deactivated(deactivated) + } + + self.broadcast_signal(OverseerSignal::BlockFinalized(block.hash, block.number)) + .await?; + + // If there are no leaves being deactivated, we don't need to send an update. + // + // Our peers will be informed about our finalized block the next time we + // activating/deactivating some leaf. + if !update.is_empty() { + self.broadcast_signal(OverseerSignal::ActiveLeaves(update)).await?; + } + + Ok(()) + } + + /// Handles a header activation. If the header's state doesn't support the parachains API, + /// this returns `None`. + async fn on_head_activated( + &mut self, + hash: &Hash, + parent_hash: Option, + ) -> Option<(Arc, LeafStatus)> { + if !self.supports_parachains.head_supports_parachains(hash).await { + return None + } + + self.metrics.on_head_activated(); + if let Some(listeners) = self.activation_external_listeners.remove(hash) { + gum::trace!( + target: LOG_TARGET, + relay_parent = ?hash, + "Leaf got activated, notifying exterinal listeners" + ); + for listener in listeners { + // it's fine if the listener is no longer interested + let _ = listener.send(Ok(())); + } + } + + let mut span = jaeger::Span::new(*hash, "leaf-activated"); + + if let Some(parent_span) = parent_hash.and_then(|h| self.span_per_active_leaf.get(&h)) { + span.add_follows_from(parent_span); + } + + let span = Arc::new(span); + self.span_per_active_leaf.insert(*hash, span.clone()); + + let status = if let Some(_) = self.known_leaves.put(*hash, ()) { + LeafStatus::Stale + } else { + LeafStatus::Fresh + }; + + Some((span, status)) + } + + fn on_head_deactivated(&mut self, hash: &Hash) { + self.metrics.on_head_deactivated(); + self.activation_external_listeners.remove(hash); + self.span_per_active_leaf.remove(hash); + } + + fn clean_up_external_listeners(&mut self) { + self.activation_external_listeners.retain(|_, v| { + // remove dead listeners + v.retain(|c| !c.is_canceled()); + !v.is_empty() + }) + } + + fn handle_external_request(&mut self, request: ExternalRequest) { + match request { + ExternalRequest::WaitForActivation { hash, response_channel } => { + if self.active_leaves.get(&hash).is_some() { + gum::trace!( + target: LOG_TARGET, + relay_parent = ?hash, + "Leaf was already ready - answering `WaitForActivation`" + ); + // it's fine if the listener is no longer interested + let _ = response_channel.send(Ok(())); + } else { + gum::trace!( + target: LOG_TARGET, + relay_parent = ?hash, + "Leaf not yet ready - queuing `WaitForActivation` sender" + ); + self.activation_external_listeners + .entry(hash) + .or_default() + .push(response_channel); + } + }, + } + } + + fn spawn_job( + &mut self, + task_name: &'static str, + subsystem_name: Option<&'static str>, + j: BoxFuture<'static, ()>, + ) { + self.spawner.spawn(task_name, subsystem_name, j); + } + + fn spawn_blocking_job( + &mut self, + task_name: &'static str, + subsystem_name: Option<&'static str>, + j: BoxFuture<'static, ()>, + ) { + self.spawner.spawn_blocking(task_name, subsystem_name, j); + } +} diff --git a/polkadot/node/overseer/src/memory_stats.rs b/polkadot/node/overseer/src/memory_stats.rs new file mode 100644 index 0000000000000000000000000000000000000000..0287021a9ac0b5670224d210a9fcbfbb8f8b66cc --- /dev/null +++ b/polkadot/node/overseer/src/memory_stats.rs @@ -0,0 +1,53 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use tikv_jemalloc_ctl::stats; + +#[derive(Clone)] +pub struct MemoryAllocationTracker { + epoch: tikv_jemalloc_ctl::epoch_mib, + allocated: stats::allocated_mib, + resident: stats::resident_mib, +} + +impl MemoryAllocationTracker { + pub fn new() -> Result { + Ok(Self { + epoch: tikv_jemalloc_ctl::epoch::mib()?, + allocated: stats::allocated::mib()?, + resident: stats::resident::mib()?, + }) + } + + pub fn snapshot(&self) -> Result { + // update stats by advancing the allocation epoch + self.epoch.advance()?; + + let allocated = self.allocated.read()?; + let resident = self.resident.read()?; + Ok(MemoryAllocationSnapshot { allocated, resident }) + } +} + +/// Snapshot of collected memory metrics. +#[non_exhaustive] +#[derive(Debug, Clone)] +pub struct MemoryAllocationSnapshot { + /// Total resident memory, in bytes. + pub resident: usize, + /// Total allocated memory, in bytes. + pub allocated: usize, +} diff --git a/polkadot/node/overseer/src/metrics.rs b/polkadot/node/overseer/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..9b6053ccf769b038ba7fff2012d0ef8b28aff1fc --- /dev/null +++ b/polkadot/node/overseer/src/metrics.rs @@ -0,0 +1,286 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Prometheus metrics related to the overseer and its channels. + +use super::*; +pub use polkadot_node_metrics::metrics::{self, prometheus, Metrics as MetricsTrait}; + +/// Overseer Prometheus metrics. +#[derive(Clone)] +struct MetricsInner { + activated_heads_total: prometheus::Counter, + deactivated_heads_total: prometheus::Counter, + messages_relayed_total: prometheus::Counter, + + to_subsystem_bounded_tof: prometheus::HistogramVec, + to_subsystem_bounded_sent: prometheus::GaugeVec, + to_subsystem_bounded_received: prometheus::GaugeVec, + to_subsystem_bounded_blocked: prometheus::GaugeVec, + + to_subsystem_unbounded_tof: prometheus::HistogramVec, + to_subsystem_unbounded_sent: prometheus::GaugeVec, + to_subsystem_unbounded_received: prometheus::GaugeVec, + + signals_sent: prometheus::GaugeVec, + signals_received: prometheus::GaugeVec, + + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + memory_stats_resident: prometheus::Gauge, + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + memory_stats_allocated: prometheus::Gauge, +} + +/// A shareable metrics type for usage with the overseer. +#[derive(Default, Clone)] +pub struct Metrics(Option); + +impl Metrics { + pub(crate) fn on_head_activated(&self) { + if let Some(metrics) = &self.0 { + metrics.activated_heads_total.inc(); + } + } + + pub(crate) fn on_head_deactivated(&self) { + if let Some(metrics) = &self.0 { + metrics.deactivated_heads_total.inc(); + } + } + + pub(crate) fn on_message_relayed(&self) { + if let Some(metrics) = &self.0 { + metrics.messages_relayed_total.inc(); + } + } + + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + pub(crate) fn memory_stats_snapshot( + &self, + memory_stats: memory_stats::MemoryAllocationSnapshot, + ) { + if let Some(metrics) = &self.0 { + metrics.memory_stats_allocated.set(memory_stats.allocated as u64); + metrics.memory_stats_resident.set(memory_stats.resident as u64); + } + } + + pub(crate) fn channel_metrics_snapshot( + &self, + collection: impl IntoIterator, + ) { + if let Some(metrics) = &self.0 { + collection + .into_iter() + .for_each(|(name, readouts): (_, SubsystemMeterReadouts)| { + metrics + .to_subsystem_bounded_sent + .with_label_values(&[name]) + .set(readouts.bounded.sent as u64); + + metrics + .to_subsystem_bounded_received + .with_label_values(&[name]) + .set(readouts.bounded.received as u64); + + metrics + .to_subsystem_bounded_blocked + .with_label_values(&[name]) + .set(readouts.bounded.blocked as u64); + + metrics + .to_subsystem_unbounded_sent + .with_label_values(&[name]) + .set(readouts.unbounded.sent as u64); + + metrics + .to_subsystem_unbounded_received + .with_label_values(&[name]) + .set(readouts.unbounded.received as u64); + + metrics + .signals_sent + .with_label_values(&[name]) + .set(readouts.signals.sent as u64); + + metrics + .signals_received + .with_label_values(&[name]) + .set(readouts.signals.received as u64); + + let hist_bounded = metrics.to_subsystem_bounded_tof.with_label_values(&[name]); + for tof in readouts.bounded.tof { + hist_bounded.observe(tof.as_f64()); + } + + let hist_unbounded = + metrics.to_subsystem_unbounded_tof.with_label_values(&[name]); + for tof in readouts.unbounded.tof { + hist_unbounded.observe(tof.as_f64()); + } + }); + } + } +} + +impl MetricsTrait for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + activated_heads_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_activated_heads_total", + "Number of activated heads.", + )?, + registry, + )?, + deactivated_heads_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_deactivated_heads_total", + "Number of deactivated heads.", + )?, + registry, + )?, + messages_relayed_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_messages_relayed_total", + "Number of messages relayed by Overseer.", + )?, + registry, + )?, + to_subsystem_bounded_tof: prometheus::register( + prometheus::HistogramVec::new( + prometheus::HistogramOpts::new( + "polkadot_parachain_subsystem_bounded_tof", + "Duration spent in a particular channel from entrance to removal", + ) + .buckets(vec![ + 0.0001, 0.0004, 0.0016, 0.0064, 0.0256, 0.1024, 0.4096, 1.6384, 3.2768, + 4.9152, 6.5536, + ]), + &["subsystem_name"], + )?, + registry, + )?, + to_subsystem_bounded_sent: prometheus::register( + prometheus::GaugeVec::::new( + prometheus::Opts::new( + "polkadot_parachain_subsystem_bounded_sent", + "Number of elements sent to subsystems' bounded queues", + ), + &["subsystem_name"], + )?, + registry, + )?, + to_subsystem_bounded_received: prometheus::register( + prometheus::GaugeVec::::new( + prometheus::Opts::new( + "polkadot_parachain_subsystem_bounded_received", + "Number of elements received by subsystems' bounded queues", + ), + &["subsystem_name"], + )?, + registry, + )?, + to_subsystem_bounded_blocked: prometheus::register( + prometheus::GaugeVec::::new( + prometheus::Opts::new( + "polkadot_parachain_subsystem_bounded_blocked", + "Number of times senders blocked while sending messages to a subsystem", + ), + &["subsystem_name"], + )?, + registry, + )?, + to_subsystem_unbounded_tof: prometheus::register( + prometheus::HistogramVec::new( + prometheus::HistogramOpts::new( + "polkadot_parachain_subsystem_unbounded_tof", + "Duration spent in a particular channel from entrance to removal", + ) + .buckets(vec![ + 0.0001, 0.0004, 0.0016, 0.0064, 0.0256, 0.1024, 0.4096, 1.6384, 3.2768, + 4.9152, 6.5536, + ]), + &["subsystem_name"], + )?, + registry, + )?, + to_subsystem_unbounded_sent: prometheus::register( + prometheus::GaugeVec::::new( + prometheus::Opts::new( + "polkadot_parachain_subsystem_unbounded_sent", + "Number of elements sent to subsystems' unbounded queues", + ), + &["subsystem_name"], + )?, + registry, + )?, + to_subsystem_unbounded_received: prometheus::register( + prometheus::GaugeVec::::new( + prometheus::Opts::new( + "polkadot_parachain_subsystem_unbounded_received", + "Number of elements received by subsystems' unbounded queues", + ), + &["subsystem_name"], + )?, + registry, + )?, + signals_sent: prometheus::register( + prometheus::GaugeVec::::new( + prometheus::Opts::new( + "polkadot_parachain_overseer_signals_sent", + "Number of signals sent by overseer to subsystems", + ), + &["subsystem_name"], + )?, + registry, + )?, + signals_received: prometheus::register( + prometheus::GaugeVec::::new( + prometheus::Opts::new( + "polkadot_parachain_overseer_signals_received", + "Number of signals received by subsystems from overseer", + ), + &["subsystem_name"], + )?, + registry, + )?, + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + memory_stats_allocated: prometheus::register( + prometheus::Gauge::::new( + "polkadot_memory_allocated", + "Total bytes allocated by the node", + )?, + registry, + )?, + #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] + memory_stats_resident: prometheus::register( + prometheus::Gauge::::new( + "polkadot_memory_resident", + "Bytes allocated by the node, and held in RAM", + )?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} + +impl fmt::Debug for Metrics { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Metrics {{...}}") + } +} diff --git a/polkadot/node/overseer/src/tests.rs b/polkadot/node/overseer/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..4ac538a7fd3a26bf1be149c11d2c53d132ec9235 --- /dev/null +++ b/polkadot/node/overseer/src/tests.rs @@ -0,0 +1,1195 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use async_trait::async_trait; +use futures::{executor, pending, pin_mut, poll, select, stream, FutureExt}; +use std::{collections::HashMap, sync::atomic, task::Poll}; + +use ::test_helpers::{dummy_candidate_descriptor, dummy_candidate_receipt, dummy_hash}; +use polkadot_node_network_protocol::{PeerId, UnifiedReputationChange}; +use polkadot_node_primitives::{ + BlockData, CollationGenerationConfig, CollationResult, DisputeMessage, InvalidDisputeVote, PoV, + UncheckedDisputeMessage, ValidDisputeVote, +}; +use polkadot_node_subsystem_types::{ + jaeger, + messages::{NetworkBridgeEvent, ReportPeerMessage, RuntimeApiRequest}, + ActivatedLeaf, LeafStatus, +}; +use polkadot_primitives::{ + CandidateHash, CandidateReceipt, CollatorPair, Id as ParaId, InvalidDisputeStatementKind, + PvfExecTimeoutKind, SessionIndex, ValidDisputeStatementKind, ValidatorIndex, +}; + +use crate::{ + self as overseer, + dummy::{dummy_overseer_builder, one_for_all_overseer_builder}, + gen::Delay, + HeadSupportsParachains, +}; +use metered; + +use assert_matches::assert_matches; +use sp_core::crypto::Pair as _; + +use super::*; + +type SpawnedSubsystem = crate::gen::SpawnedSubsystem; + +struct TestSubsystem1(metered::MeteredSender); + +impl overseer::Subsystem for TestSubsystem1 +where + C: overseer::SubsystemContext, +{ + fn start(self, mut ctx: C) -> SpawnedSubsystem { + let mut sender = self.0; + SpawnedSubsystem { + name: "test-subsystem-1", + future: Box::pin(async move { + let mut i = 0; + loop { + match ctx.recv().await { + Ok(FromOrchestra::Communication { .. }) => { + let _ = sender.send(i).await; + i += 1; + continue + }, + Ok(FromOrchestra::Signal(OverseerSignal::Conclude)) => return Ok(()), + Err(_) => return Ok(()), + _ => (), + } + } + }), + } + } +} + +struct TestSubsystem2(metered::MeteredSender); + +impl overseer::Subsystem for TestSubsystem2 +where + C: overseer::SubsystemContext< + Message = CandidateBackingMessage, + OutgoingMessages = ::OutgoingMessages, + Signal = OverseerSignal, + >, +{ + fn start(self, mut ctx: C) -> SpawnedSubsystem { + let sender = self.0.clone(); + SpawnedSubsystem { + name: "test-subsystem-2", + future: Box::pin(async move { + let _sender = sender; + let mut c: usize = 0; + loop { + if c < 10 { + let candidate_receipt = CandidateReceipt { + descriptor: dummy_candidate_descriptor(dummy_hash()), + commitments_hash: Hash::zero(), + }; + + let (tx, _) = oneshot::channel(); + ctx.send_message(CandidateValidationMessage::ValidateFromChainState( + candidate_receipt, + PoV { block_data: BlockData(Vec::new()) }.into(), + PvfExecTimeoutKind::Backing, + tx, + )) + .await; + c += 1; + continue + } + match ctx.try_recv().await { + Ok(Some(FromOrchestra::Signal(OverseerSignal::Conclude))) => break, + Ok(Some(_)) => continue, + Err(_) => return Ok(()), + _ => (), + } + pending!(); + } + + Ok(()) + }), + } + } +} + +struct ReturnOnStart; + +impl overseer::Subsystem for ReturnOnStart +where + C: overseer::SubsystemContext, +{ + fn start(self, mut _ctx: C) -> SpawnedSubsystem { + SpawnedSubsystem { + name: "test-subsystem-4", + future: Box::pin(async move { + // Do nothing and exit. + Ok(()) + }), + } + } +} + +struct MockSupportsParachains; + +#[async_trait] +impl HeadSupportsParachains for MockSupportsParachains { + async fn head_supports_parachains(&self, _head: &Hash) -> bool { + true + } +} + +// Checks that a minimal configuration of two jobs can run and exchange messages. +#[test] +fn overseer_works() { + let spawner = sp_core::testing::TaskExecutor::new(); + + executor::block_on(async move { + let (s1_tx, s1_rx) = metered::channel::(64); + let (s2_tx, s2_rx) = metered::channel::(64); + + let mut s1_rx = s1_rx.fuse(); + let mut s2_rx = s2_rx.fuse(); + let (overseer, handle) = dummy_overseer_builder(spawner, MockSupportsParachains, None) + .unwrap() + .replace_candidate_validation(move |_| TestSubsystem1(s1_tx)) + .replace_candidate_backing(move |_| TestSubsystem2(s2_tx)) + .build() + .unwrap(); + let mut handle = Handle::new(handle); + let overseer_fut = overseer.run().fuse(); + + pin_mut!(overseer_fut); + + let mut s1_results = Vec::new(); + let mut s2_results = Vec::new(); + + loop { + select! { + _ = overseer_fut => break, + s1_next = s1_rx.next() => { + match s1_next { + Some(msg) => { + s1_results.push(msg); + if s1_results.len() == 10 { + handle.stop().await; + } + } + None => break, + } + }, + s2_next = s2_rx.next() => { + match s2_next { + Some(_) => s2_results.push(s2_next), + None => break, + } + }, + complete => break, + } + } + + assert_eq!(s1_results, (0..10).collect::>()); + }); +} + +// Checks activated/deactivated metrics are updated properly. +#[test] +fn overseer_metrics_work() { + let spawner = sp_core::testing::TaskExecutor::new(); + + executor::block_on(async move { + let first_block_hash = [1; 32].into(); + let second_block_hash = [2; 32].into(); + + let first_block = + BlockInfo { hash: first_block_hash, parent_hash: [0; 32].into(), number: 1 }; + let second_block = + BlockInfo { hash: second_block_hash, parent_hash: first_block_hash, number: 2 }; + + let registry = prometheus::Registry::new(); + let (overseer, handle) = + dummy_overseer_builder(spawner, MockSupportsParachains, Some(®istry)) + .unwrap() + .build() + .unwrap(); + + let mut handle = Handle::new(handle); + let overseer_fut = overseer.run_inner().fuse(); + + pin_mut!(overseer_fut); + + handle.block_imported(first_block).await; + handle.block_imported(second_block).await; + handle + .send_msg_anon(AllMessages::CandidateValidation(test_candidate_validation_msg())) + .await; + handle.stop().await; + + select! { + res = overseer_fut => { + assert!(res.is_ok()); + let metrics = extract_metrics(®istry); + assert_eq!(metrics["activated"], 2); + assert_eq!(metrics["deactivated"], 1); + assert_eq!(metrics["relayed"], 1); + }, + complete => (), + } + }); +} + +fn extract_metrics(registry: &prometheus::Registry) -> HashMap<&'static str, u64> { + let gather = registry.gather(); + assert!(!gather.is_empty(), "Gathered metrics are not empty. qed"); + let extract = |name: &str| -> u64 { + gather + .iter() + .find(|&mf| dbg!(mf.get_name()) == dbg!(name)) + .expect(&format!("Must contain `{}` metric", name)) + .get_metric()[0] + .get_counter() + .get_value() as u64 + }; + + let activated = extract("polkadot_parachain_activated_heads_total"); + let deactivated = extract("polkadot_parachain_deactivated_heads_total"); + let relayed = extract("polkadot_parachain_messages_relayed_total"); + let mut result = HashMap::new(); + result.insert("activated", activated); + result.insert("deactivated", deactivated); + result.insert("relayed", relayed); + result +} + +// Spawn a subsystem that immediately exits. +// +// Should immediately conclude the overseer itself. +#[test] +fn overseer_ends_on_subsystem_exit() { + let spawner = sp_core::testing::TaskExecutor::new(); + + executor::block_on(async move { + let (overseer, _handle) = dummy_overseer_builder(spawner, MockSupportsParachains, None) + .unwrap() + .replace_candidate_backing(|_| ReturnOnStart) + .build() + .unwrap(); + + overseer.run_inner().await.unwrap(); + }) +} + +struct TestSubsystem5(metered::MeteredSender); + +impl overseer::Subsystem for TestSubsystem5 +where + C: overseer::SubsystemContext, +{ + fn start(self, mut ctx: C) -> SpawnedSubsystem { + let mut sender = self.0.clone(); + + SpawnedSubsystem { + name: "test-subsystem-5", + future: Box::pin(async move { + loop { + match ctx.try_recv().await { + Ok(Some(FromOrchestra::Signal(OverseerSignal::Conclude))) => break, + Ok(Some(FromOrchestra::Signal(s))) => { + sender.send(s).await.unwrap(); + continue + }, + Ok(Some(_)) => continue, + Err(_) => break, + _ => (), + } + pending!(); + } + + Ok(()) + }), + } + } +} + +struct TestSubsystem6(metered::MeteredSender); + +impl Subsystem for TestSubsystem6 +where + C: overseer::SubsystemContext, +{ + fn start(self, mut ctx: C) -> SpawnedSubsystem { + let mut sender = self.0.clone(); + + SpawnedSubsystem { + name: "test-subsystem-6", + future: Box::pin(async move { + loop { + match ctx.try_recv().await { + Ok(Some(FromOrchestra::Signal(OverseerSignal::Conclude))) => break, + Ok(Some(FromOrchestra::Signal(s))) => { + sender.send(s).await.unwrap(); + continue + }, + Ok(Some(_)) => continue, + Err(_) => break, + _ => (), + } + pending!(); + } + + Ok(()) + }), + } + } +} + +// Tests that starting with a defined set of leaves and receiving +// notifications on imported blocks triggers expected `StartWork` and `StopWork` heartbeats. +#[test] +fn overseer_start_stop_works() { + let spawner = sp_core::testing::TaskExecutor::new(); + + executor::block_on(async move { + let first_block_hash = [1; 32].into(); + let second_block_hash = [2; 32].into(); + + let first_block = + BlockInfo { hash: first_block_hash, parent_hash: [0; 32].into(), number: 1 }; + let second_block = + BlockInfo { hash: second_block_hash, parent_hash: first_block_hash, number: 2 }; + + let (tx_5, mut rx_5) = metered::channel(64); + let (tx_6, mut rx_6) = metered::channel(64); + + let (overseer, handle) = dummy_overseer_builder(spawner, MockSupportsParachains, None) + .unwrap() + .replace_candidate_validation(move |_| TestSubsystem5(tx_5)) + .replace_candidate_backing(move |_| TestSubsystem6(tx_6)) + .build() + .unwrap(); + let mut handle = Handle::new(handle); + + let overseer_fut = overseer.run_inner().fuse(); + pin_mut!(overseer_fut); + + let mut ss5_results = Vec::new(); + let mut ss6_results = Vec::new(); + + handle.block_imported(first_block).await; + handle.block_imported(second_block).await; + + let expected_heartbeats = vec![ + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: first_block_hash, + number: 1, + span: Arc::new(jaeger::Span::Disabled), + status: LeafStatus::Fresh, + }), + deactivated: Default::default(), + }), + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: second_block_hash, + number: 2, + span: Arc::new(jaeger::Span::Disabled), + status: LeafStatus::Fresh, + }), + deactivated: [first_block_hash].as_ref().into(), + }), + ]; + + loop { + select! { + res = overseer_fut => { + assert!(res.is_ok()); + break; + }, + res = rx_5.next() => { + if let Some(res) = res { + ss5_results.push(res); + } + } + res = rx_6.next() => { + if let Some(res) = res { + ss6_results.push(res); + } + } + complete => break, + } + + if ss5_results.len() == expected_heartbeats.len() && + ss6_results.len() == expected_heartbeats.len() + { + handle.stop().await; + } + } + + assert_eq!(ss5_results, expected_heartbeats); + assert_eq!(ss6_results, expected_heartbeats); + }); +} + +// Tests that starting with a defined set of leaves and receiving +// notifications on imported blocks triggers expected `StartWork` and `StopWork` heartbeats. +#[test] +fn overseer_finalize_works() { + let spawner = sp_core::testing::TaskExecutor::new(); + + executor::block_on(async move { + let first_block_hash = [1; 32].into(); + let second_block_hash = [2; 32].into(); + let third_block_hash = [3; 32].into(); + + let first_block = + BlockInfo { hash: first_block_hash, parent_hash: [0; 32].into(), number: 1 }; + let second_block = + BlockInfo { hash: second_block_hash, parent_hash: [42; 32].into(), number: 2 }; + let third_block = + BlockInfo { hash: third_block_hash, parent_hash: second_block_hash, number: 3 }; + + let (tx_5, mut rx_5) = metered::channel(64); + let (tx_6, mut rx_6) = metered::channel(64); + + // start with two forks of different height. + + let (overseer, handle) = dummy_overseer_builder(spawner, MockSupportsParachains, None) + .unwrap() + .replace_candidate_validation(move |_| TestSubsystem5(tx_5)) + .replace_candidate_backing(move |_| TestSubsystem6(tx_6)) + .build() + .unwrap(); + let mut handle = Handle::new(handle); + + let overseer_fut = overseer.run_inner().fuse(); + pin_mut!(overseer_fut); + + let mut ss5_results = Vec::new(); + let mut ss6_results = Vec::new(); + + // activate two blocks + handle.block_imported(first_block).await; + handle.block_imported(second_block).await; + + // this should stop work on both forks we started with earlier. + handle.block_finalized(third_block).await; + + let expected_heartbeats = vec![ + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: first_block_hash, + number: 1, + span: Arc::new(jaeger::Span::Disabled), + status: LeafStatus::Fresh, + }), + deactivated: Default::default(), + }), + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: second_block_hash, + number: 2, + span: Arc::new(jaeger::Span::Disabled), + status: LeafStatus::Fresh, + }), + deactivated: Default::default(), + }), + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + deactivated: [first_block_hash, second_block_hash].as_ref().into(), + ..Default::default() + }), + OverseerSignal::BlockFinalized(third_block_hash, 3), + ]; + + loop { + select! { + res = overseer_fut => { + assert!(res.is_ok()); + break; + }, + res = rx_5.next() => { + if let Some(res) = res { + ss5_results.push(res); + } + } + res = rx_6.next() => { + if let Some(res) = res { + ss6_results.push(res); + } + } + complete => break, + } + + if ss5_results.len() == expected_heartbeats.len() && + ss6_results.len() == expected_heartbeats.len() + { + handle.stop().await; + } + } + + assert_eq!(ss5_results.len(), expected_heartbeats.len()); + assert_eq!(ss6_results.len(), expected_heartbeats.len()); + + // Notifications on finality for multiple blocks at once + // may be received in different orders. + for expected in expected_heartbeats { + assert!(ss5_results.contains(&expected)); + assert!(ss6_results.contains(&expected)); + } + }); +} + +// Tests that finalization of an active leaf doesn't remove it from +// the leaves set. +#[test] +fn overseer_finalize_leaf_preserves_it() { + let spawner = sp_core::testing::TaskExecutor::new(); + + executor::block_on(async move { + let first_block_hash = [1; 32].into(); + let second_block_hash = [2; 32].into(); + + let first_block = + BlockInfo { hash: first_block_hash, parent_hash: [0; 32].into(), number: 1 }; + let second_block = + BlockInfo { hash: second_block_hash, parent_hash: [42; 32].into(), number: 1 }; + + let (tx_5, mut rx_5) = metered::channel(64); + let (tx_6, mut rx_6) = metered::channel(64); + + // start with two forks at height 1. + + let (overseer, handle) = dummy_overseer_builder(spawner, MockSupportsParachains, None) + .unwrap() + .replace_candidate_validation(move |_| TestSubsystem5(tx_5)) + .replace_candidate_backing(move |_| TestSubsystem6(tx_6)) + .build() + .unwrap(); + let mut handle = Handle::new(handle); + + let overseer_fut = overseer.run_inner().fuse(); + pin_mut!(overseer_fut); + + let mut ss5_results = Vec::new(); + let mut ss6_results = Vec::new(); + + handle.block_imported(first_block.clone()).await; + handle.block_imported(second_block).await; + // This should stop work on the second block, but only the + // second block. + handle.block_finalized(first_block).await; + + let expected_heartbeats = vec![ + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: first_block_hash, + number: 1, + span: Arc::new(jaeger::Span::Disabled), + status: LeafStatus::Fresh, + })), + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: second_block_hash, + number: 1, + span: Arc::new(jaeger::Span::Disabled), + status: LeafStatus::Fresh, + })), + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + deactivated: [second_block_hash].as_ref().into(), + ..Default::default() + }), + OverseerSignal::BlockFinalized(first_block_hash, 1), + ]; + + loop { + select! { + res = overseer_fut => { + assert!(res.is_ok()); + break; + }, + res = rx_5.next() => { + if let Some(res) = res { + ss5_results.push(res); + } + } + res = rx_6.next() => { + if let Some(res) = res { + ss6_results.push(res); + } + } + complete => break, + } + + if ss5_results.len() == expected_heartbeats.len() && + ss6_results.len() == expected_heartbeats.len() + { + handle.stop().await; + } + } + + assert_eq!(ss5_results.len(), expected_heartbeats.len()); + assert_eq!(ss6_results.len(), expected_heartbeats.len()); + + // Notifications on finality for multiple blocks at once + // may be received in different orders. + for expected in expected_heartbeats { + assert!(ss5_results.contains(&expected)); + assert!(ss6_results.contains(&expected)); + } + }); +} + +#[test] +fn do_not_send_empty_leaves_update_on_block_finalization() { + let spawner = sp_core::testing::TaskExecutor::new(); + + executor::block_on(async move { + let imported_block = + BlockInfo { hash: Hash::random(), parent_hash: Hash::random(), number: 1 }; + + let finalized_block = + BlockInfo { hash: Hash::random(), parent_hash: Hash::random(), number: 1 }; + + let (tx_5, mut rx_5) = metered::channel(64); + + let (overseer, handle) = dummy_overseer_builder(spawner, MockSupportsParachains, None) + .unwrap() + .replace_candidate_backing(move |_| TestSubsystem6(tx_5)) + .build() + .unwrap(); + + let mut handle = Handle::new(handle); + + let overseer_fut = overseer.run_inner().fuse(); + pin_mut!(overseer_fut); + + let mut ss5_results = Vec::new(); + + handle.block_finalized(finalized_block.clone()).await; + handle.block_imported(imported_block.clone()).await; + + let expected_heartbeats = vec![ + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: imported_block.hash, + number: imported_block.number, + span: Arc::new(jaeger::Span::Disabled), + status: LeafStatus::Fresh, + })), + OverseerSignal::BlockFinalized(finalized_block.hash, 1), + ]; + + loop { + select! { + res = overseer_fut => { + assert!(res.is_ok()); + break; + }, + res = rx_5.next() => { + if let Some(res) = dbg!(res) { + ss5_results.push(res); + } + } + } + + if ss5_results.len() == expected_heartbeats.len() { + handle.stop().await; + } + } + + assert_eq!(ss5_results.len(), expected_heartbeats.len()); + + for expected in expected_heartbeats { + assert!(ss5_results.contains(&expected)); + } + }); +} + +#[derive(Clone)] +struct CounterSubsystem { + stop_signals_received: Arc, + signals_received: Arc, + msgs_received: Arc, +} + +impl CounterSubsystem { + fn new( + stop_signals_received: Arc, + signals_received: Arc, + msgs_received: Arc, + ) -> Self { + Self { stop_signals_received, signals_received, msgs_received } + } +} + +impl Subsystem for CounterSubsystem +where + C: overseer::SubsystemContext, + M: Send, +{ + fn start(self, mut ctx: C) -> SpawnedSubsystem { + SpawnedSubsystem { + name: "counter-subsystem", + future: Box::pin(async move { + loop { + match ctx.try_recv().await { + Ok(Some(FromOrchestra::Signal(OverseerSignal::Conclude))) => { + self.stop_signals_received.fetch_add(1, atomic::Ordering::SeqCst); + break + }, + Ok(Some(FromOrchestra::Signal(_))) => { + self.signals_received.fetch_add(1, atomic::Ordering::SeqCst); + continue + }, + Ok(Some(FromOrchestra::Communication { .. })) => { + self.msgs_received.fetch_add(1, atomic::Ordering::SeqCst); + continue + }, + Err(_) => (), + _ => (), + } + pending!(); + } + + Ok(()) + }), + } + } +} + +fn test_candidate_validation_msg() -> CandidateValidationMessage { + let (sender, _) = oneshot::channel(); + let pov = Arc::new(PoV { block_data: BlockData(Vec::new()) }); + let candidate_receipt = CandidateReceipt { + descriptor: dummy_candidate_descriptor(dummy_hash()), + commitments_hash: Hash::zero(), + }; + + CandidateValidationMessage::ValidateFromChainState( + candidate_receipt, + pov, + PvfExecTimeoutKind::Backing, + sender, + ) +} + +fn test_candidate_backing_msg() -> CandidateBackingMessage { + let (sender, _) = oneshot::channel(); + CandidateBackingMessage::GetBackedCandidates(Vec::new(), sender) +} + +fn test_chain_api_msg() -> ChainApiMessage { + let (sender, _) = oneshot::channel(); + ChainApiMessage::FinalizedBlockNumber(sender) +} + +fn test_collator_generation_msg() -> CollationGenerationMessage { + CollationGenerationMessage::Initialize(CollationGenerationConfig { + key: CollatorPair::generate().0, + collator: Some(Box::new(|_, _| TestCollator.boxed())), + para_id: Default::default(), + }) +} +struct TestCollator; + +impl Future for TestCollator { + type Output = Option; + + fn poll(self: Pin<&mut Self>, _cx: &mut futures::task::Context) -> Poll { + panic!("at the Disco") + } +} + +impl Unpin for TestCollator {} + +fn test_collator_protocol_msg() -> CollatorProtocolMessage { + CollatorProtocolMessage::CollateOn(Default::default()) +} + +fn test_network_bridge_event() -> NetworkBridgeEvent { + NetworkBridgeEvent::PeerDisconnected(PeerId::random()) +} + +fn test_statement_distribution_msg() -> StatementDistributionMessage { + StatementDistributionMessage::NetworkBridgeUpdate(test_network_bridge_event()) +} + +fn test_availability_recovery_msg() -> AvailabilityRecoveryMessage { + let (sender, _) = oneshot::channel(); + AvailabilityRecoveryMessage::RecoverAvailableData( + dummy_candidate_receipt(dummy_hash()), + Default::default(), + None, + sender, + ) +} + +fn test_bitfield_distribution_msg() -> BitfieldDistributionMessage { + BitfieldDistributionMessage::NetworkBridgeUpdate(test_network_bridge_event()) +} + +fn test_provisioner_msg() -> ProvisionerMessage { + let (sender, _) = oneshot::channel(); + ProvisionerMessage::RequestInherentData(Default::default(), sender) +} + +fn test_runtime_api_msg() -> RuntimeApiMessage { + let (sender, _) = oneshot::channel(); + RuntimeApiMessage::Request(Default::default(), RuntimeApiRequest::Validators(sender)) +} + +fn test_availability_store_msg() -> AvailabilityStoreMessage { + let (sender, _) = oneshot::channel(); + AvailabilityStoreMessage::QueryAvailableData(CandidateHash(Default::default()), sender) +} + +fn test_network_bridge_tx_msg() -> NetworkBridgeTxMessage { + NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single( + PeerId::random(), + UnifiedReputationChange::BenefitMinor("").into(), + )) +} + +fn test_network_bridge_rx_msg() -> NetworkBridgeRxMessage { + NetworkBridgeRxMessage::NewGossipTopology { + session: SessionIndex::from(0_u32), + local_index: None, + canonical_shuffling: Vec::new(), + shuffled_indices: Vec::new(), + } +} + +fn test_approval_distribution_msg() -> ApprovalDistributionMessage { + ApprovalDistributionMessage::NewBlocks(Default::default()) +} + +fn test_approval_voting_msg() -> ApprovalVotingMessage { + let (sender, _) = oneshot::channel(); + ApprovalVotingMessage::ApprovedAncestor(Default::default(), 0, sender) +} + +fn test_dispute_coordinator_msg() -> DisputeCoordinatorMessage { + let (sender, _) = oneshot::channel(); + DisputeCoordinatorMessage::RecentDisputes(sender) +} + +fn test_dispute_distribution_msg() -> DisputeDistributionMessage { + let dummy_dispute_message = UncheckedDisputeMessage { + candidate_receipt: dummy_candidate_receipt(dummy_hash()), + session_index: 0, + invalid_vote: InvalidDisputeVote { + validator_index: ValidatorIndex(0), + signature: sp_core::crypto::UncheckedFrom::unchecked_from([1u8; 64]), + kind: InvalidDisputeStatementKind::Explicit, + }, + valid_vote: ValidDisputeVote { + validator_index: ValidatorIndex(0), + signature: sp_core::crypto::UncheckedFrom::unchecked_from([2u8; 64]), + kind: ValidDisputeStatementKind::Explicit, + }, + }; + + DisputeDistributionMessage::SendDispute( + // We just need dummy data here: + unsafe { + std::mem::transmute::(dummy_dispute_message) + }, + ) +} + +fn test_chain_selection_msg() -> ChainSelectionMessage { + ChainSelectionMessage::Approved(Default::default()) +} + +fn test_prospective_parachains_msg() -> ProspectiveParachainsMessage { + ProspectiveParachainsMessage::CandidateBacked( + ParaId::from(5), + CandidateHash(Hash::repeat_byte(0)), + ) +} + +// Checks that `stop`, `broadcast_signal` and `broadcast_message` are implemented correctly. +#[test] +fn overseer_all_subsystems_receive_signals_and_messages() { + const NUM_SUBSYSTEMS: usize = 23; + // -4 for BitfieldSigning, GossipSupport, AvailabilityDistribution and PvfCheckerSubsystem. + const NUM_SUBSYSTEMS_MESSAGED: usize = NUM_SUBSYSTEMS - 4; + + let spawner = sp_core::testing::TaskExecutor::new(); + executor::block_on(async move { + let stop_signals_received = Arc::new(atomic::AtomicUsize::new(0)); + let signals_received = Arc::new(atomic::AtomicUsize::new(0)); + let msgs_received = Arc::new(atomic::AtomicUsize::new(0)); + + let subsystem = CounterSubsystem::new( + stop_signals_received.clone(), + signals_received.clone(), + msgs_received.clone(), + ); + + let (overseer, handle) = + one_for_all_overseer_builder(spawner, MockSupportsParachains, subsystem, None) + .unwrap() + .build() + .unwrap(); + + let mut handle = Handle::new(handle); + let overseer_fut = overseer.run_inner().fuse(); + + pin_mut!(overseer_fut); + + // send a signal to each subsystem + handle + .block_imported(BlockInfo { + hash: Default::default(), + parent_hash: Default::default(), + number: Default::default(), + }) + .await; + + // send a msg to each subsystem + // except for BitfieldSigning and GossipSupport as the messages are not instantiable + handle + .send_msg_anon(AllMessages::CandidateValidation(test_candidate_validation_msg())) + .await; + handle + .send_msg_anon(AllMessages::CandidateBacking(test_candidate_backing_msg())) + .await; + handle + .send_msg_anon(AllMessages::CollationGeneration(test_collator_generation_msg())) + .await; + handle + .send_msg_anon(AllMessages::CollatorProtocol(test_collator_protocol_msg())) + .await; + handle + .send_msg_anon(AllMessages::StatementDistribution(test_statement_distribution_msg())) + .await; + handle + .send_msg_anon(AllMessages::AvailabilityRecovery(test_availability_recovery_msg())) + .await; + // handle.send_msg_anon(AllMessages::BitfieldSigning(test_bitfield_signing_msg())).await; + // handle.send_msg_anon(AllMessages::GossipSupport(test_bitfield_signing_msg())).await; + handle + .send_msg_anon(AllMessages::BitfieldDistribution(test_bitfield_distribution_msg())) + .await; + handle.send_msg_anon(AllMessages::Provisioner(test_provisioner_msg())).await; + handle.send_msg_anon(AllMessages::RuntimeApi(test_runtime_api_msg())).await; + handle + .send_msg_anon(AllMessages::AvailabilityStore(test_availability_store_msg())) + .await; + handle + .send_msg_anon(AllMessages::NetworkBridgeTx(test_network_bridge_tx_msg())) + .await; + handle + .send_msg_anon(AllMessages::NetworkBridgeRx(test_network_bridge_rx_msg())) + .await; + handle.send_msg_anon(AllMessages::ChainApi(test_chain_api_msg())).await; + handle + .send_msg_anon(AllMessages::ApprovalDistribution(test_approval_distribution_msg())) + .await; + handle + .send_msg_anon(AllMessages::ApprovalVoting(test_approval_voting_msg())) + .await; + handle + .send_msg_anon(AllMessages::DisputeCoordinator(test_dispute_coordinator_msg())) + .await; + handle + .send_msg_anon(AllMessages::DisputeDistribution(test_dispute_distribution_msg())) + .await; + handle + .send_msg_anon(AllMessages::ChainSelection(test_chain_selection_msg())) + .await; + handle + .send_msg_anon(AllMessages::ProspectiveParachains(test_prospective_parachains_msg())) + .await; + // handle.send_msg_anon(AllMessages::PvfChecker(test_pvf_checker_msg())).await; + + // Wait until all subsystems have received. Otherwise the messages might race against + // the conclude signal. + loop { + match (&mut overseer_fut).timeout(Duration::from_millis(100)).await { + None => { + let r = msgs_received.load(atomic::Ordering::SeqCst); + if r < NUM_SUBSYSTEMS_MESSAGED { + Delay::new(Duration::from_millis(100)).await; + } else if r > NUM_SUBSYSTEMS_MESSAGED { + panic!("too many messages received??"); + } else { + break + } + }, + Some(_) => panic!("exited too early"), + } + } + + // send a stop signal to each subsystems + handle.stop().await; + + let res = overseer_fut.await; + assert_eq!(stop_signals_received.load(atomic::Ordering::SeqCst), NUM_SUBSYSTEMS); + assert_eq!(signals_received.load(atomic::Ordering::SeqCst), NUM_SUBSYSTEMS); + assert_eq!(msgs_received.load(atomic::Ordering::SeqCst), NUM_SUBSYSTEMS_MESSAGED); + + assert!(res.is_ok()); + }); +} + +#[test] +fn context_holds_onto_message_until_enough_signals_received() { + let (candidate_validation_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (candidate_backing_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (statement_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (availability_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (availability_recovery_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (bitfield_signing_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (bitfield_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (provisioner_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (runtime_api_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (availability_store_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (network_bridge_rx_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (network_bridge_tx_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (chain_api_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (collator_protocol_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (collation_generation_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (approval_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (approval_voting_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (gossip_support_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (dispute_coordinator_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (dispute_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (chain_selection_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (pvf_checker_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + let (prospective_parachains_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY); + + let (candidate_validation_unbounded_tx, _) = metered::unbounded(); + let (candidate_backing_unbounded_tx, _) = metered::unbounded(); + let (statement_distribution_unbounded_tx, _) = metered::unbounded(); + let (availability_distribution_unbounded_tx, _) = metered::unbounded(); + let (availability_recovery_unbounded_tx, _) = metered::unbounded(); + let (bitfield_signing_unbounded_tx, _) = metered::unbounded(); + let (bitfield_distribution_unbounded_tx, _) = metered::unbounded(); + let (provisioner_unbounded_tx, _) = metered::unbounded(); + let (runtime_api_unbounded_tx, _) = metered::unbounded(); + let (availability_store_unbounded_tx, _) = metered::unbounded(); + let (network_bridge_tx_unbounded_tx, _) = metered::unbounded(); + let (network_bridge_rx_unbounded_tx, _) = metered::unbounded(); + let (chain_api_unbounded_tx, _) = metered::unbounded(); + let (collator_protocol_unbounded_tx, _) = metered::unbounded(); + let (collation_generation_unbounded_tx, _) = metered::unbounded(); + let (approval_distribution_unbounded_tx, _) = metered::unbounded(); + let (approval_voting_unbounded_tx, _) = metered::unbounded(); + let (gossip_support_unbounded_tx, _) = metered::unbounded(); + let (dispute_coordinator_unbounded_tx, _) = metered::unbounded(); + let (dispute_distribution_unbounded_tx, _) = metered::unbounded(); + let (chain_selection_unbounded_tx, _) = metered::unbounded(); + let (pvf_checker_unbounded_tx, _) = metered::unbounded(); + let (prospective_parachains_unbounded_tx, _) = metered::unbounded(); + + let channels_out = ChannelsOut { + candidate_validation: candidate_validation_bounded_tx.clone(), + candidate_backing: candidate_backing_bounded_tx.clone(), + statement_distribution: statement_distribution_bounded_tx.clone(), + availability_distribution: availability_distribution_bounded_tx.clone(), + availability_recovery: availability_recovery_bounded_tx.clone(), + bitfield_signing: bitfield_signing_bounded_tx.clone(), + bitfield_distribution: bitfield_distribution_bounded_tx.clone(), + provisioner: provisioner_bounded_tx.clone(), + runtime_api: runtime_api_bounded_tx.clone(), + availability_store: availability_store_bounded_tx.clone(), + network_bridge_tx: network_bridge_tx_bounded_tx.clone(), + network_bridge_rx: network_bridge_rx_bounded_tx.clone(), + chain_api: chain_api_bounded_tx.clone(), + collator_protocol: collator_protocol_bounded_tx.clone(), + collation_generation: collation_generation_bounded_tx.clone(), + approval_distribution: approval_distribution_bounded_tx.clone(), + approval_voting: approval_voting_bounded_tx.clone(), + gossip_support: gossip_support_bounded_tx.clone(), + dispute_coordinator: dispute_coordinator_bounded_tx.clone(), + dispute_distribution: dispute_distribution_bounded_tx.clone(), + chain_selection: chain_selection_bounded_tx.clone(), + pvf_checker: pvf_checker_bounded_tx.clone(), + prospective_parachains: prospective_parachains_bounded_tx.clone(), + + candidate_validation_unbounded: candidate_validation_unbounded_tx.clone(), + candidate_backing_unbounded: candidate_backing_unbounded_tx.clone(), + statement_distribution_unbounded: statement_distribution_unbounded_tx.clone(), + availability_distribution_unbounded: availability_distribution_unbounded_tx.clone(), + availability_recovery_unbounded: availability_recovery_unbounded_tx.clone(), + bitfield_signing_unbounded: bitfield_signing_unbounded_tx.clone(), + bitfield_distribution_unbounded: bitfield_distribution_unbounded_tx.clone(), + provisioner_unbounded: provisioner_unbounded_tx.clone(), + runtime_api_unbounded: runtime_api_unbounded_tx.clone(), + availability_store_unbounded: availability_store_unbounded_tx.clone(), + network_bridge_tx_unbounded: network_bridge_tx_unbounded_tx.clone(), + network_bridge_rx_unbounded: network_bridge_rx_unbounded_tx.clone(), + chain_api_unbounded: chain_api_unbounded_tx.clone(), + collator_protocol_unbounded: collator_protocol_unbounded_tx.clone(), + collation_generation_unbounded: collation_generation_unbounded_tx.clone(), + approval_distribution_unbounded: approval_distribution_unbounded_tx.clone(), + approval_voting_unbounded: approval_voting_unbounded_tx.clone(), + gossip_support_unbounded: gossip_support_unbounded_tx.clone(), + dispute_coordinator_unbounded: dispute_coordinator_unbounded_tx.clone(), + dispute_distribution_unbounded: dispute_distribution_unbounded_tx.clone(), + chain_selection_unbounded: chain_selection_unbounded_tx.clone(), + pvf_checker_unbounded: pvf_checker_unbounded_tx.clone(), + prospective_parachains_unbounded: prospective_parachains_unbounded_tx.clone(), + }; + + let (mut signal_tx, signal_rx) = metered::channel(CHANNEL_CAPACITY); + let (mut bounded_tx, bounded_rx) = metered::channel(CHANNEL_CAPACITY); + let (unbounded_tx, unbounded_rx) = metered::unbounded(); + let (to_overseer_tx, _to_overseer_rx) = metered::unbounded(); + + let mut ctx = OverseerSubsystemContext::new( + signal_rx, + stream::select_with_strategy( + bounded_rx, + unbounded_rx, + orchestra::select_message_channel_strategy, + ), + channels_out, + to_overseer_tx, + "test", + ); + + assert_eq!(ctx.signals_received.load(), 0); + + let test_fut = async move { + signal_tx.send(OverseerSignal::Conclude).await.unwrap(); + assert_matches!(ctx.recv().await.unwrap(), FromOrchestra::Signal(OverseerSignal::Conclude)); + + assert_eq!(ctx.signals_received.load(), 1); + bounded_tx + .send(MessagePacket { signals_received: 2, message: () }) + .await + .unwrap(); + unbounded_tx + .unbounded_send(MessagePacket { signals_received: 2, message: () }) + .unwrap(); + + match poll!(ctx.recv()) { + Poll::Pending => {}, + Poll::Ready(_) => panic!("ready too early"), + }; + + assert!(ctx.pending_incoming.is_some()); + + signal_tx.send(OverseerSignal::Conclude).await.unwrap(); + assert_matches!(ctx.recv().await.unwrap(), FromOrchestra::Signal(OverseerSignal::Conclude)); + assert_matches!(ctx.recv().await.unwrap(), FromOrchestra::Communication { msg: () }); + assert_matches!(ctx.recv().await.unwrap(), FromOrchestra::Communication { msg: () }); + assert!(ctx.pending_incoming.is_none()); + }; + + futures::executor::block_on(test_fut); +} diff --git a/polkadot/node/primitives/Cargo.toml b/polkadot/node/primitives/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..fbd85c1a05511b9d7f2992dbd027ae2c3136fc1c --- /dev/null +++ b/polkadot/node/primitives/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "polkadot-node-primitives" +description = "Primitives types for the Node-side" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +bounded-vec = "0.7" +futures = "0.3.21" +polkadot-primitives = { path = "../../primitives" } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-maybe-compressed-blob = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot-parachain = { path = "../../parachain", default-features = false } +schnorrkel = "0.9.1" +thiserror = "1.0.31" +serde = { version = "1.0.163", features = ["derive"] } + +[target.'cfg(not(target_os = "unknown"))'.dependencies] +zstd = { version = "0.11.2", default-features = false } + +[dev-dependencies] +polkadot-erasure-coding = { path = "../../erasure-coding" } diff --git a/polkadot/node/primitives/src/approval.rs b/polkadot/node/primitives/src/approval.rs new file mode 100644 index 0000000000000000000000000000000000000000..01f45a20787461c2cf6a0f39f88c6d082ac87468 --- /dev/null +++ b/polkadot/node/primitives/src/approval.rs @@ -0,0 +1,205 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Types relevant for approval. + +pub use sp_consensus_babe::{Randomness, Slot, VrfOutput, VrfProof, VrfSignature, VrfTranscript}; + +use parity_scale_codec::{Decode, Encode}; +use polkadot_primitives::{ + BlockNumber, CandidateHash, CandidateIndex, CoreIndex, Hash, Header, SessionIndex, + ValidatorIndex, ValidatorSignature, +}; +use sp_application_crypto::ByteArray; +use sp_consensus_babe as babe_primitives; + +/// Validators assigning to check a particular candidate are split up into tranches. +/// Earlier tranches of validators check first, with later tranches serving as backup. +pub type DelayTranche = u32; + +/// A static context used to compute the Relay VRF story based on the +/// VRF output included in the header-chain. +pub const RELAY_VRF_STORY_CONTEXT: &[u8] = b"A&V RC-VRF"; + +/// A static context used for all relay-vrf-modulo VRFs. +pub const RELAY_VRF_MODULO_CONTEXT: &[u8] = b"A&V MOD"; + +/// A static context used for all relay-vrf-modulo VRFs. +pub const RELAY_VRF_DELAY_CONTEXT: &[u8] = b"A&V DELAY"; + +/// A static context used for transcripts indicating assigned availability core. +pub const ASSIGNED_CORE_CONTEXT: &[u8] = b"A&V ASSIGNED"; + +/// A static context associated with producing randomness for a core. +pub const CORE_RANDOMNESS_CONTEXT: &[u8] = b"A&V CORE"; + +/// A static context associated with producing randomness for a tranche. +pub const TRANCHE_RANDOMNESS_CONTEXT: &[u8] = b"A&V TRANCHE"; + +/// random bytes derived from the VRF submitted within the block by the +/// block author as a credential and used as input to approval assignment criteria. +#[derive(Debug, Clone, Encode, Decode, PartialEq)] +pub struct RelayVRFStory(pub [u8; 32]); + +/// Different kinds of input data or criteria that can prove a validator's assignment +/// to check a particular parachain. +#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] +pub enum AssignmentCertKind { + /// An assignment story based on the VRF that authorized the relay-chain block where the + /// candidate was included combined with a sample number. + /// + /// The context used to produce bytes is [`RELAY_VRF_MODULO_CONTEXT`] + RelayVRFModulo { + /// The sample number used in this cert. + sample: u32, + }, + /// An assignment story based on the VRF that authorized the relay-chain block where the + /// candidate was included combined with the index of a particular core. + /// + /// The context is [`RELAY_VRF_DELAY_CONTEXT`] + RelayVRFDelay { + /// The core index chosen in this cert. + core_index: CoreIndex, + }, +} + +/// A certification of assignment. +#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] +pub struct AssignmentCert { + /// The criterion which is claimed to be met by this cert. + pub kind: AssignmentCertKind, + /// The VRF signature showing the criterion is met. + pub vrf: VrfSignature, +} + +/// An assignment criterion which refers to the candidate under which the assignment is +/// relevant by block hash. +#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] +pub struct IndirectAssignmentCert { + /// A block hash where the candidate appears. + pub block_hash: Hash, + /// The validator index. + pub validator: ValidatorIndex, + /// The cert itself. + pub cert: AssignmentCert, +} + +/// A signed approval vote which references the candidate indirectly via the block. +/// +/// In practice, we have a look-up from block hash and candidate index to candidate hash, +/// so this can be transformed into a `SignedApprovalVote`. +#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] +pub struct IndirectSignedApprovalVote { + /// A block hash where the candidate appears. + pub block_hash: Hash, + /// The index of the candidate in the list of candidates fully included as-of the block. + pub candidate_index: CandidateIndex, + /// The validator index. + pub validator: ValidatorIndex, + /// The signature by the validator. + pub signature: ValidatorSignature, +} + +/// Metadata about a block which is now live in the approval protocol. +#[derive(Debug)] +pub struct BlockApprovalMeta { + /// The hash of the block. + pub hash: Hash, + /// The number of the block. + pub number: BlockNumber, + /// The hash of the parent block. + pub parent_hash: Hash, + /// The candidates included by the block. + /// Note that these are not the same as the candidates that appear within the block body. + pub candidates: Vec, + /// The consensus slot of the block. + pub slot: Slot, + /// The session of the block. + pub session: SessionIndex, +} + +/// Errors that can occur during the approvals protocol. +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum ApprovalError { + #[error("Schnorrkel signature error")] + SchnorrkelSignature(schnorrkel::errors::SignatureError), + #[error("Authority index {0} out of bounds")] + AuthorityOutOfBounds(usize), +} + +/// An unsafe VRF output. Provide BABE Epoch info to create a `RelayVRFStory`. +pub struct UnsafeVRFOutput { + vrf_output: VrfOutput, + slot: Slot, + authority_index: u32, +} + +impl UnsafeVRFOutput { + /// Get the slot. + pub fn slot(&self) -> Slot { + self.slot + } + + /// Compute the randomness associated with this VRF output. + pub fn compute_randomness( + self, + authorities: &[(babe_primitives::AuthorityId, babe_primitives::BabeAuthorityWeight)], + randomness: &babe_primitives::Randomness, + epoch_index: u64, + ) -> Result { + let author = match authorities.get(self.authority_index as usize) { + None => return Err(ApprovalError::AuthorityOutOfBounds(self.authority_index as _)), + Some(x) => &x.0, + }; + + let pubkey = schnorrkel::PublicKey::from_bytes(author.as_slice()) + .map_err(ApprovalError::SchnorrkelSignature)?; + + let transcript = sp_consensus_babe::make_vrf_transcript(randomness, self.slot, epoch_index); + + let inout = self + .vrf_output + .0 + .attach_input_hash(&pubkey, transcript.0) + .map_err(ApprovalError::SchnorrkelSignature)?; + Ok(RelayVRFStory(inout.make_bytes(RELAY_VRF_STORY_CONTEXT))) + } +} + +/// Extract the slot number and relay VRF from a header. +/// +/// This fails if either there is no BABE `PreRuntime` digest or +/// the digest has type `SecondaryPlain`, which Substrate nodes do +/// not produce or accept anymore. +pub fn babe_unsafe_vrf_info(header: &Header) -> Option { + use babe_primitives::digests::CompatibleDigestItem; + + for digest in &header.digest.logs { + if let Some(pre) = digest.as_babe_pre_digest() { + let slot = pre.slot(); + let authority_index = pre.authority_index(); + + return pre.vrf_signature().map(|sig| UnsafeVRFOutput { + vrf_output: sig.output.clone(), + slot, + authority_index, + }) + } + } + + None +} diff --git a/polkadot/node/primitives/src/disputes/message.rs b/polkadot/node/primitives/src/disputes/message.rs new file mode 100644 index 0000000000000000000000000000000000000000..89d3ea6c0af9023ad74fba97f4f2abd73cf84ad8 --- /dev/null +++ b/polkadot/node/primitives/src/disputes/message.rs @@ -0,0 +1,267 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! `DisputeMessage` and associated types. +//! +//! A `DisputeMessage` is a message that indicates a node participating in a dispute and is used +//! for interfacing with `DisputeDistribution` to send out our vote in a spam detectable way. + +use thiserror::Error; + +use parity_scale_codec::{Decode, Encode}; + +use super::{InvalidDisputeVote, SignedDisputeStatement, ValidDisputeVote}; +use polkadot_primitives::{ + CandidateReceipt, DisputeStatement, SessionIndex, SessionInfo, ValidatorIndex, +}; + +/// A dispute initiating/participating message that have been built from signed +/// statements. +/// +/// And most likely has been constructed correctly. This is used with +/// `DisputeDistributionMessage::SendDispute` for sending out votes. +/// +/// NOTE: This is sent over the wire, any changes are a change in protocol and need to be +/// versioned. +#[derive(Debug, Clone)] +pub struct DisputeMessage(UncheckedDisputeMessage); + +/// A `DisputeMessage` where signatures of statements have not yet been checked. +#[derive(Clone, Encode, Decode, Debug)] +pub struct UncheckedDisputeMessage { + /// The candidate being disputed. + pub candidate_receipt: CandidateReceipt, + + /// The session the candidate appears in. + pub session_index: SessionIndex, + + /// The invalid vote data that makes up this dispute. + pub invalid_vote: InvalidDisputeVote, + + /// The valid vote that makes this dispute request valid. + pub valid_vote: ValidDisputeVote, +} + +/// Things that can go wrong when constructing a `DisputeMessage`. +#[derive(Error, Debug)] +pub enum Error { + /// The statements concerned different candidates. + #[error("Candidate hashes of the two votes did not match up")] + CandidateHashMismatch, + + /// The statements concerned different sessions. + #[error("Session indices of the two votes did not match up")] + SessionIndexMismatch, + + /// The valid statement validator key did not correspond to passed in `SessionInfo`. + #[error("Valid statement validator key did not match session information")] + InvalidValidKey, + + /// The invalid statement validator key did not correspond to passed in `SessionInfo`. + #[error("Invalid statement validator key did not match session information")] + InvalidInvalidKey, + + /// Provided receipt had different hash than the `CandidateHash` in the signed statements. + #[error("Hash of candidate receipt did not match provided hash")] + InvalidCandidateReceipt, + + /// Valid statement should have `ValidDisputeStatementKind`. + #[error("Valid statement has kind `invalid`")] + ValidStatementHasInvalidKind, + + /// Invalid statement should have `InvalidDisputeStatementKind`. + #[error("Invalid statement has kind `valid`")] + InvalidStatementHasValidKind, + + /// Provided index could not be found in `SessionInfo`. + #[error("The valid statement had an invalid validator index")] + ValidStatementInvalidValidatorIndex, + + /// Provided index could not be found in `SessionInfo`. + #[error("The invalid statement had an invalid validator index")] + InvalidStatementInvalidValidatorIndex, +} + +impl DisputeMessage { + /// Build a `SignedDisputeMessage` and check what can be checked. + /// + /// This function checks that: + /// + /// - both statements concern the same candidate + /// - both statements concern the same session + /// - the invalid statement is indeed an invalid one + /// - the valid statement is indeed a valid one + /// - The passed `CandidateReceipt` has the correct hash (as signed in the statements). + /// - the given validator indices match with the given `ValidatorId`s in the statements, given a + /// `SessionInfo`. + /// + /// We don't check whether the given `SessionInfo` matches the `SessionIndex` in the + /// statements, because we can't without doing a runtime query. Nevertheless this smart + /// constructor gives relative strong guarantees that the resulting `SignedDisputeStatement` is + /// valid and good. Even the passed `SessionInfo` is most likely right if this function + /// returns `Some`, because otherwise the passed `ValidatorId`s in the `SessionInfo` at + /// their given index would very likely not match the `ValidatorId`s in the statements. + /// + /// So in summary, this smart constructor should be smart enough to prevent from almost all + /// programming errors that one could realistically make here. + pub fn from_signed_statements( + valid_statement: SignedDisputeStatement, + valid_index: ValidatorIndex, + invalid_statement: SignedDisputeStatement, + invalid_index: ValidatorIndex, + candidate_receipt: CandidateReceipt, + session_info: &SessionInfo, + ) -> Result { + let candidate_hash = *valid_statement.candidate_hash(); + // Check statements concern same candidate: + if candidate_hash != *invalid_statement.candidate_hash() { + return Err(Error::CandidateHashMismatch) + } + + let session_index = valid_statement.session_index(); + if session_index != invalid_statement.session_index() { + return Err(Error::SessionIndexMismatch) + } + + let valid_id = session_info + .validators + .get(valid_index) + .ok_or(Error::ValidStatementInvalidValidatorIndex)?; + let invalid_id = session_info + .validators + .get(invalid_index) + .ok_or(Error::InvalidStatementInvalidValidatorIndex)?; + + if valid_id != valid_statement.validator_public() { + return Err(Error::InvalidValidKey) + } + + if invalid_id != invalid_statement.validator_public() { + return Err(Error::InvalidInvalidKey) + } + + if candidate_receipt.hash() != candidate_hash { + return Err(Error::InvalidCandidateReceipt) + } + + let valid_kind = match valid_statement.statement() { + DisputeStatement::Valid(v) => v, + _ => return Err(Error::ValidStatementHasInvalidKind), + }; + + let invalid_kind = match invalid_statement.statement() { + DisputeStatement::Invalid(v) => v, + _ => return Err(Error::InvalidStatementHasValidKind), + }; + + let valid_vote = ValidDisputeVote { + validator_index: valid_index, + signature: valid_statement.validator_signature().clone(), + kind: *valid_kind, + }; + + let invalid_vote = InvalidDisputeVote { + validator_index: invalid_index, + signature: invalid_statement.validator_signature().clone(), + kind: *invalid_kind, + }; + + Ok(DisputeMessage(UncheckedDisputeMessage { + candidate_receipt, + session_index, + valid_vote, + invalid_vote, + })) + } + + /// Read only access to the candidate receipt. + pub fn candidate_receipt(&self) -> &CandidateReceipt { + &self.0.candidate_receipt + } + + /// Read only access to the `SessionIndex`. + pub fn session_index(&self) -> SessionIndex { + self.0.session_index + } + + /// Read only access to the invalid vote. + pub fn invalid_vote(&self) -> &InvalidDisputeVote { + &self.0.invalid_vote + } + + /// Read only access to the valid vote. + pub fn valid_vote(&self) -> &ValidDisputeVote { + &self.0.valid_vote + } +} + +impl UncheckedDisputeMessage { + /// Try to recover the two signed dispute votes from an `UncheckedDisputeMessage`. + pub fn try_into_signed_votes( + self, + session_info: &SessionInfo, + ) -> Result< + ( + CandidateReceipt, + (SignedDisputeStatement, ValidatorIndex), + (SignedDisputeStatement, ValidatorIndex), + ), + (), + > { + let Self { candidate_receipt, session_index, valid_vote, invalid_vote } = self; + let candidate_hash = candidate_receipt.hash(); + + let vote_valid = { + let ValidDisputeVote { validator_index, signature, kind } = valid_vote; + let validator_public = session_info.validators.get(validator_index).ok_or(())?.clone(); + + ( + SignedDisputeStatement::new_checked( + DisputeStatement::Valid(kind), + candidate_hash, + session_index, + validator_public, + signature, + )?, + validator_index, + ) + }; + + let vote_invalid = { + let InvalidDisputeVote { validator_index, signature, kind } = invalid_vote; + let validator_public = session_info.validators.get(validator_index).ok_or(())?.clone(); + + ( + SignedDisputeStatement::new_checked( + DisputeStatement::Invalid(kind), + candidate_hash, + session_index, + validator_public, + signature, + )?, + validator_index, + ) + }; + + Ok((candidate_receipt, vote_valid, vote_invalid)) + } +} + +impl From for UncheckedDisputeMessage { + fn from(message: DisputeMessage) -> Self { + message.0 + } +} diff --git a/polkadot/node/primitives/src/disputes/mod.rs b/polkadot/node/primitives/src/disputes/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..ae8602dd5fc4d81aec63e493b2735887851224a7 --- /dev/null +++ b/polkadot/node/primitives/src/disputes/mod.rs @@ -0,0 +1,330 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::collections::{ + btree_map::{Entry as Bentry, Keys as Bkeys}, + BTreeMap, BTreeSet, +}; + +use parity_scale_codec::{Decode, Encode}; + +use sp_application_crypto::AppCrypto; +use sp_keystore::{Error as KeystoreError, KeystorePtr}; + +use polkadot_primitives::{ + CandidateHash, CandidateReceipt, CompactStatement, DisputeStatement, EncodeAs, + InvalidDisputeStatementKind, SessionIndex, SigningContext, UncheckedSigned, + ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorSignature, +}; + +/// `DisputeMessage` and related types. +mod message; +pub use message::{DisputeMessage, Error as DisputeMessageCheckError, UncheckedDisputeMessage}; +mod status; +pub use status::{dispute_is_inactive, DisputeStatus, Timestamp, ACTIVE_DURATION_SECS}; + +/// A checked dispute statement from an associated validator. +#[derive(Debug, Clone)] +pub struct SignedDisputeStatement { + dispute_statement: DisputeStatement, + candidate_hash: CandidateHash, + validator_public: ValidatorId, + validator_signature: ValidatorSignature, + session_index: SessionIndex, +} + +/// Tracked votes on candidates, for the purposes of dispute resolution. +#[derive(Debug, Clone)] +pub struct CandidateVotes { + /// The receipt of the candidate itself. + pub candidate_receipt: CandidateReceipt, + /// Votes of validity, sorted by validator index. + pub valid: ValidCandidateVotes, + /// Votes of invalidity, sorted by validator index. + pub invalid: BTreeMap, +} + +/// Type alias for retrieving valid votes from `CandidateVotes` +pub type ValidVoteData = (ValidatorIndex, (ValidDisputeStatementKind, ValidatorSignature)); + +/// Type alias for retrieving invalid votes from `CandidateVotes` +pub type InvalidVoteData = (ValidatorIndex, (InvalidDisputeStatementKind, ValidatorSignature)); + +impl CandidateVotes { + /// Get the set of all validators who have votes in the set, ascending. + pub fn voted_indices(&self) -> BTreeSet { + let mut keys: BTreeSet<_> = self.valid.keys().cloned().collect(); + keys.extend(self.invalid.keys().cloned()); + keys + } +} + +#[derive(Debug, Clone)] +/// Valid candidate votes. +/// +/// Prefere backing votes over other votes. +pub struct ValidCandidateVotes { + votes: BTreeMap, +} + +impl ValidCandidateVotes { + /// Create new empty `ValidCandidateVotes` + pub fn new() -> Self { + Self { votes: BTreeMap::new() } + } + /// Insert a vote, replacing any already existing vote. + /// + /// Except, for backing votes: Backing votes are always kept, and will never get overridden. + /// Import of other king of `valid` votes, will be ignored if a backing vote is already + /// present. Any already existing `valid` vote, will be overridden by any given backing vote. + /// + /// Returns: true, if the insert had any effect. + pub fn insert_vote( + &mut self, + validator_index: ValidatorIndex, + kind: ValidDisputeStatementKind, + sig: ValidatorSignature, + ) -> bool { + match self.votes.entry(validator_index) { + Bentry::Vacant(vacant) => { + vacant.insert((kind, sig)); + true + }, + Bentry::Occupied(mut occupied) => match occupied.get().0 { + ValidDisputeStatementKind::BackingValid(_) | + ValidDisputeStatementKind::BackingSeconded(_) => false, + ValidDisputeStatementKind::Explicit | + ValidDisputeStatementKind::ApprovalChecking => { + occupied.insert((kind, sig)); + kind != occupied.get().0 + }, + }, + } + } + + /// Retain any votes that match the given criteria. + pub fn retain(&mut self, f: F) + where + F: FnMut(&ValidatorIndex, &mut (ValidDisputeStatementKind, ValidatorSignature)) -> bool, + { + self.votes.retain(f) + } + + /// Get all the validator indeces we have votes for. + pub fn keys( + &self, + ) -> Bkeys<'_, ValidatorIndex, (ValidDisputeStatementKind, ValidatorSignature)> { + self.votes.keys() + } + + /// Get read only direct access to underlying map. + pub fn raw( + &self, + ) -> &BTreeMap { + &self.votes + } +} + +impl FromIterator<(ValidatorIndex, (ValidDisputeStatementKind, ValidatorSignature))> + for ValidCandidateVotes +{ + fn from_iter(iter: T) -> Self + where + T: IntoIterator, + { + Self { votes: BTreeMap::from_iter(iter) } + } +} + +impl From + for BTreeMap +{ + fn from(wrapped: ValidCandidateVotes) -> Self { + wrapped.votes + } +} +impl IntoIterator for ValidCandidateVotes { + type Item = (ValidatorIndex, (ValidDisputeStatementKind, ValidatorSignature)); + type IntoIter = as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.votes.into_iter() + } +} + +impl SignedDisputeStatement { + /// Create a new `SignedDisputeStatement` from information + /// that is available on-chain, and hence already can be trusted. + /// + /// Attention: Not to be used other than with guaranteed fetches. + pub fn new_unchecked_from_trusted_source( + dispute_statement: DisputeStatement, + candidate_hash: CandidateHash, + session_index: SessionIndex, + validator_public: ValidatorId, + validator_signature: ValidatorSignature, + ) -> Self { + SignedDisputeStatement { + dispute_statement, + candidate_hash, + validator_public, + validator_signature, + session_index, + } + } + + /// Create a new `SignedDisputeStatement`, which is only possible by checking the signature. + pub fn new_checked( + dispute_statement: DisputeStatement, + candidate_hash: CandidateHash, + session_index: SessionIndex, + validator_public: ValidatorId, + validator_signature: ValidatorSignature, + ) -> Result { + dispute_statement + .check_signature(&validator_public, candidate_hash, session_index, &validator_signature) + .map(|_| SignedDisputeStatement { + dispute_statement, + candidate_hash, + validator_public, + validator_signature, + session_index, + }) + } + + /// Sign this statement with the given keystore and key. Pass `valid = true` to + /// indicate validity of the candidate, and `valid = false` to indicate invalidity. + pub fn sign_explicit( + keystore: &KeystorePtr, + valid: bool, + candidate_hash: CandidateHash, + session_index: SessionIndex, + validator_public: ValidatorId, + ) -> Result, KeystoreError> { + let dispute_statement = if valid { + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit) + } else { + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit) + }; + + let data = dispute_statement.payload_data(candidate_hash, session_index); + let signature = keystore + .sr25519_sign(ValidatorId::ID, validator_public.as_ref(), &data)? + .map(|sig| Self { + dispute_statement, + candidate_hash, + validator_public, + validator_signature: sig.into(), + session_index, + }); + Ok(signature) + } + + /// Access the underlying dispute statement + pub fn statement(&self) -> &DisputeStatement { + &self.dispute_statement + } + + /// Access the underlying candidate hash. + pub fn candidate_hash(&self) -> &CandidateHash { + &self.candidate_hash + } + + /// Access the underlying validator public key. + pub fn validator_public(&self) -> &ValidatorId { + &self.validator_public + } + + /// Access the underlying validator signature. + pub fn validator_signature(&self) -> &ValidatorSignature { + &self.validator_signature + } + + /// Consume self to return the signature. + pub fn into_validator_signature(self) -> ValidatorSignature { + self.validator_signature + } + + /// Access the underlying session index. + pub fn session_index(&self) -> SessionIndex { + self.session_index + } + + /// Convert a [`SignedFullStatement`] to a [`SignedDisputeStatement`] + /// + /// As [`SignedFullStatement`] contains only the validator index and + /// not the validator public key, the public key must be passed as well, + /// along with the signing context. + /// + /// This does signature checks again with the data provided. + pub fn from_backing_statement( + backing_statement: &UncheckedSigned, + signing_context: SigningContext, + validator_public: ValidatorId, + ) -> Result + where + for<'a> &'a T: Into, + T: EncodeAs, + { + let (statement_kind, candidate_hash) = match backing_statement.unchecked_payload().into() { + CompactStatement::Seconded(candidate_hash) => ( + ValidDisputeStatementKind::BackingSeconded(signing_context.parent_hash), + candidate_hash, + ), + CompactStatement::Valid(candidate_hash) => ( + ValidDisputeStatementKind::BackingValid(signing_context.parent_hash), + candidate_hash, + ), + }; + + let dispute_statement = DisputeStatement::Valid(statement_kind); + Self::new_checked( + dispute_statement, + candidate_hash, + signing_context.session_index, + validator_public, + backing_statement.unchecked_signature().clone(), + ) + } +} + +/// Any invalid vote (currently only explicit). +#[derive(Clone, Encode, Decode, Debug)] +pub struct InvalidDisputeVote { + /// The voting validator index. + pub validator_index: ValidatorIndex, + + /// The validator signature, that can be verified when constructing a + /// `SignedDisputeStatement`. + pub signature: ValidatorSignature, + + /// Kind of dispute statement. + pub kind: InvalidDisputeStatementKind, +} + +/// Any valid vote (backing, approval, explicit). +#[derive(Clone, Encode, Decode, Debug)] +pub struct ValidDisputeVote { + /// The voting validator index. + pub validator_index: ValidatorIndex, + + /// The validator signature, that can be verified when constructing a + /// `SignedDisputeStatement`. + pub signature: ValidatorSignature, + + /// Kind of dispute statement. + pub kind: ValidDisputeStatementKind, +} diff --git a/polkadot/node/primitives/src/disputes/status.rs b/polkadot/node/primitives/src/disputes/status.rs new file mode 100644 index 0000000000000000000000000000000000000000..d93c3ec846ce6f45392e3baeb325afd56dccf9d9 --- /dev/null +++ b/polkadot/node/primitives/src/disputes/status.rs @@ -0,0 +1,145 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use parity_scale_codec::{Decode, Encode}; + +/// Timestamp based on the 1 Jan 1970 UNIX base, which is persistent across node restarts and OS +/// reboots. +pub type Timestamp = u64; + +/// The status of dispute. +/// +/// As managed by the dispute coordinator. +/// +/// NOTE: This status is persisted to the database, any changes have to be versioned and a db +/// migration will be needed. +#[derive(Debug, Clone, Copy, Encode, Decode, PartialEq)] +pub enum DisputeStatus { + /// The dispute is active and unconcluded. + #[codec(index = 0)] + Active, + /// The dispute has been concluded in favor of the candidate + /// since the given timestamp. + #[codec(index = 1)] + ConcludedFor(Timestamp), + /// The dispute has been concluded against the candidate + /// since the given timestamp. + /// + /// This takes precedence over `ConcludedFor` in the case that + /// both are true, which is impossible unless a large amount of + /// validators are participating on both sides. + #[codec(index = 2)] + ConcludedAgainst(Timestamp), + /// Dispute has been confirmed (more than `byzantine_threshold` have already participated/ or + /// we have seen the candidate included already/participated successfully ourselves). + #[codec(index = 3)] + Confirmed, +} + +impl DisputeStatus { + /// Initialize the status to the active state. + pub fn active() -> DisputeStatus { + DisputeStatus::Active + } + + /// Move status to confirmed status, if not yet concluded/confirmed already. + pub fn confirm(self) -> DisputeStatus { + match self { + DisputeStatus::Active => DisputeStatus::Confirmed, + DisputeStatus::Confirmed => DisputeStatus::Confirmed, + DisputeStatus::ConcludedFor(_) | DisputeStatus::ConcludedAgainst(_) => self, + } + } + + /// Check whether the dispute is not a spam dispute. + pub fn is_confirmed_concluded(&self) -> bool { + match self { + &DisputeStatus::Confirmed | + &DisputeStatus::ConcludedFor(_) | + DisputeStatus::ConcludedAgainst(_) => true, + &DisputeStatus::Active => false, + } + } + + /// Concluded valid? + pub fn has_concluded_for(&self) -> bool { + match self { + &DisputeStatus::ConcludedFor(_) => true, + _ => false, + } + } + /// Concluded invalid? + pub fn has_concluded_against(&self) -> bool { + match self { + &DisputeStatus::ConcludedAgainst(_) => true, + _ => false, + } + } + + /// Transition the status to a new status after observing the dispute has concluded for the + /// candidate. This may be a no-op if the status was already concluded. + pub fn conclude_for(self, now: Timestamp) -> DisputeStatus { + match self { + DisputeStatus::Active | DisputeStatus::Confirmed => DisputeStatus::ConcludedFor(now), + DisputeStatus::ConcludedFor(at) => DisputeStatus::ConcludedFor(std::cmp::min(at, now)), + against => against, + } + } + + /// Transition the status to a new status after observing the dispute has concluded against the + /// candidate. This may be a no-op if the status was already concluded. + pub fn conclude_against(self, now: Timestamp) -> DisputeStatus { + match self { + DisputeStatus::Active | DisputeStatus::Confirmed => + DisputeStatus::ConcludedAgainst(now), + DisputeStatus::ConcludedFor(at) => + DisputeStatus::ConcludedAgainst(std::cmp::min(at, now)), + DisputeStatus::ConcludedAgainst(at) => + DisputeStatus::ConcludedAgainst(std::cmp::min(at, now)), + } + } + + /// Whether the disputed candidate is possibly invalid. + pub fn is_possibly_invalid(&self) -> bool { + match self { + DisputeStatus::Active | + DisputeStatus::Confirmed | + DisputeStatus::ConcludedAgainst(_) => true, + DisputeStatus::ConcludedFor(_) => false, + } + } + + /// Yields the timestamp this dispute concluded at, if any. + pub fn concluded_at(&self) -> Option { + match self { + DisputeStatus::Active | DisputeStatus::Confirmed => None, + DisputeStatus::ConcludedFor(at) | DisputeStatus::ConcludedAgainst(at) => Some(*at), + } + } +} + +/// The choice here is fairly arbitrary. But any dispute that concluded more than a few minutes ago +/// is not worth considering anymore. Changing this value has little to no bearing on consensus, +/// and really only affects the work that the node might do on startup during periods of many +/// disputes. +pub const ACTIVE_DURATION_SECS: Timestamp = 180; + +/// Returns true if the dispute has concluded for longer than [`ACTIVE_DURATION_SECS`]. +pub fn dispute_is_inactive(status: &DisputeStatus, now: &Timestamp) -> bool { + let at = status.concluded_at(); + + at.is_some() && at.unwrap() + ACTIVE_DURATION_SECS < *now +} diff --git a/polkadot/node/primitives/src/lib.rs b/polkadot/node/primitives/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..392781783319e25a095c8fc08b36d4c30cd8cacf --- /dev/null +++ b/polkadot/node/primitives/src/lib.rs @@ -0,0 +1,664 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Primitive types used on the node-side. +//! +//! Unlike the `polkadot-primitives` crate, these primitives are only used on the node-side, +//! not shared between the node and the runtime. This crate builds on top of the primitives defined +//! there. + +#![deny(missing_docs)] + +use std::{num::NonZeroUsize, pin::Pin}; + +use bounded_vec::BoundedVec; +use futures::Future; +use parity_scale_codec::{Decode, Encode, Error as CodecError, Input}; +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; + +use polkadot_primitives::{ + BlakeTwo256, BlockNumber, CandidateCommitments, CandidateHash, CollatorPair, + CommittedCandidateReceipt, CompactStatement, EncodeAs, Hash, HashT, HeadData, Id as ParaId, + PersistedValidationData, SessionIndex, Signed, UncheckedSigned, ValidationCode, + ValidationCodeHash, ValidatorIndex, MAX_CODE_SIZE, MAX_POV_SIZE, +}; +pub use sp_consensus_babe::{ + AllowedSlots as BabeAllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch, +}; + +pub use polkadot_parachain::primitives::{BlockData, HorizontalMessages, UpwardMessages}; + +pub mod approval; + +/// Disputes related types. +pub mod disputes; +pub use disputes::{ + dispute_is_inactive, CandidateVotes, DisputeMessage, DisputeMessageCheckError, DisputeStatus, + InvalidDisputeVote, SignedDisputeStatement, Timestamp, UncheckedDisputeMessage, + ValidDisputeVote, ACTIVE_DURATION_SECS, +}; + +// For a 16-ary Merkle Prefix Trie, we can expect at most 16 32-byte hashes per node +// plus some overhead: +// header 1 + bitmap 2 + max partial_key 8 + children 16 * (32 + len 1) + value 32 + value len 1 +const MERKLE_NODE_MAX_SIZE: usize = 512 + 100; +// 16-ary Merkle Prefix Trie for 32-bit ValidatorIndex has depth at most 8. +const MERKLE_PROOF_MAX_DEPTH: usize = 8; + +/// The bomb limit for decompressing code blobs. +pub const VALIDATION_CODE_BOMB_LIMIT: usize = (MAX_CODE_SIZE * 4u32) as usize; + +/// The bomb limit for decompressing PoV blobs. +pub const POV_BOMB_LIMIT: usize = (MAX_POV_SIZE * 4u32) as usize; + +/// How many blocks after finalization an information about backed/included candidate should be +/// pre-loaded (when scraoing onchain votes) and kept locally (when pruning). +/// +/// We don't want to remove scraped candidates on finalization because we want to +/// be sure that disputes will conclude on abandoned forks. +/// Removing the candidate on finalization creates a possibility for an attacker to +/// avoid slashing. If a bad fork is abandoned too quickly because another +/// better one gets finalized the entries for the bad fork will be pruned and we +/// might never participate in a dispute for it. +/// +/// Why pre-load finalized blocks? I dispute might be raised against finalized candidate. In most +/// of the cases it will conclude valid (otherwise we are in big trouble) but never the less the +/// node must participate. It's possible to see a vote for such dispute onchain before we have it +/// imported by `dispute-distribution`. In this case we won't have `CandidateReceipt` and the import +/// will fail unless we keep them preloaded. +/// +/// This value should consider the timeout we allow for participation in approval-voting. In +/// particular, the following condition should hold: +/// +/// slot time * `DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION` > `APPROVAL_EXECUTION_TIMEOUT` +/// + slot time +pub const DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION: BlockNumber = 10; + +/// Linked to `MAX_FINALITY_LAG` in relay chain selection, +/// `MAX_HEADS_LOOK_BACK` in `approval-voting` and +/// `MAX_BATCH_SCRAPE_ANCESTORS` in `dispute-coordinator` +pub const MAX_FINALITY_LAG: u32 = 500; + +/// Type of a session window size. +/// +/// We are not using `NonZeroU32` here because `expect` and `unwrap` are not yet const, so global +/// constants of `SessionWindowSize` would require `lazy_static` in that case. +/// +/// See: +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] +pub struct SessionWindowSize(SessionIndex); + +#[macro_export] +/// Create a new checked `SessionWindowSize` which cannot be 0. +macro_rules! new_session_window_size { + (0) => { + compile_error!("Must be non zero"); + }; + (0_u32) => { + compile_error!("Must be non zero"); + }; + (0 as u32) => { + compile_error!("Must be non zero"); + }; + (0 as _) => { + compile_error!("Must be non zero"); + }; + ($l:literal) => { + SessionWindowSize::unchecked_new($l as _) + }; +} + +/// It would be nice to draw this from the chain state, but we have no tools for it right now. +/// On Polkadot this is 1 day, and on Kusama it's 6 hours. +/// +/// Number of sessions we want to consider in disputes. +pub const DISPUTE_WINDOW: SessionWindowSize = new_session_window_size!(6); + +impl SessionWindowSize { + /// Get the value as `SessionIndex` for doing comparisons with those. + pub fn get(self) -> SessionIndex { + self.0 + } + + /// Helper function for `new_session_window_size`. + /// + /// Don't use it. The only reason it is public, is because otherwise the + /// `new_session_window_size` macro would not work outside of this module. + #[doc(hidden)] + pub const fn unchecked_new(size: SessionIndex) -> Self { + Self(size) + } +} + +impl From for NonZeroUsize { + fn from(value: SessionWindowSize) -> Self { + NonZeroUsize::new(value.get() as usize).expect("SessionWindowSize can't be 0. qed.") + } +} + +/// The cumulative weight of a block in a fork-choice rule. +pub type BlockWeight = u32; + +/// A statement, where the candidate receipt is included in the `Seconded` variant. +/// +/// This is the committed candidate receipt instead of the bare candidate receipt. As such, +/// it gives access to the commitments to validators who have not executed the candidate. This +/// is necessary to allow a block-producing validator to include candidates from outside the para +/// it is assigned to. +#[derive(Clone, PartialEq, Eq, Encode, Decode)] +pub enum Statement { + /// A statement that a validator seconds a candidate. + #[codec(index = 1)] + Seconded(CommittedCandidateReceipt), + /// A statement that a validator has deemed a candidate valid. + #[codec(index = 2)] + Valid(CandidateHash), +} + +impl std::fmt::Debug for Statement { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Statement::Seconded(seconded) => write!(f, "Seconded: {:?}", seconded.descriptor), + Statement::Valid(hash) => write!(f, "Valid: {:?}", hash), + } + } +} + +impl Statement { + /// Get the candidate hash referenced by this statement. + /// + /// If this is a `Statement::Seconded`, this does hash the candidate receipt, which may be + /// expensive for large candidates. + pub fn candidate_hash(&self) -> CandidateHash { + match *self { + Statement::Valid(ref h) => *h, + Statement::Seconded(ref c) => c.hash(), + } + } + + /// Transform this statement into its compact version, which references only the hash + /// of the candidate. + pub fn to_compact(&self) -> CompactStatement { + match *self { + Statement::Seconded(ref c) => CompactStatement::Seconded(c.hash()), + Statement::Valid(hash) => CompactStatement::Valid(hash), + } + } + + /// Add the [`PersistedValidationData`] to the statement, if seconded. + pub fn supply_pvd(self, pvd: PersistedValidationData) -> StatementWithPVD { + match self { + Statement::Seconded(c) => StatementWithPVD::Seconded(c, pvd), + Statement::Valid(hash) => StatementWithPVD::Valid(hash), + } + } +} + +impl From<&'_ Statement> for CompactStatement { + fn from(stmt: &Statement) -> Self { + stmt.to_compact() + } +} + +impl EncodeAs for Statement { + fn encode_as(&self) -> Vec { + self.to_compact().encode() + } +} + +/// A statement, exactly the same as [`Statement`] but where seconded messages carry +/// the [`PersistedValidationData`]. +#[derive(Clone, PartialEq, Eq)] +pub enum StatementWithPVD { + /// A statement that a validator seconds a candidate. + Seconded(CommittedCandidateReceipt, PersistedValidationData), + /// A statement that a validator has deemed a candidate valid. + Valid(CandidateHash), +} + +impl std::fmt::Debug for StatementWithPVD { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + StatementWithPVD::Seconded(seconded, _) => + write!(f, "Seconded: {:?}", seconded.descriptor), + StatementWithPVD::Valid(hash) => write!(f, "Valid: {:?}", hash), + } + } +} + +impl StatementWithPVD { + /// Get the candidate hash referenced by this statement. + /// + /// If this is a `Statement::Seconded`, this does hash the candidate receipt, which may be + /// expensive for large candidates. + pub fn candidate_hash(&self) -> CandidateHash { + match *self { + StatementWithPVD::Valid(ref h) => *h, + StatementWithPVD::Seconded(ref c, _) => c.hash(), + } + } + + /// Transform this statement into its compact version, which references only the hash + /// of the candidate. + pub fn to_compact(&self) -> CompactStatement { + match *self { + StatementWithPVD::Seconded(ref c, _) => CompactStatement::Seconded(c.hash()), + StatementWithPVD::Valid(hash) => CompactStatement::Valid(hash), + } + } + + /// Drop the [`PersistedValidationData`] from the statement. + pub fn drop_pvd(self) -> Statement { + match self { + StatementWithPVD::Seconded(c, _) => Statement::Seconded(c), + StatementWithPVD::Valid(c_h) => Statement::Valid(c_h), + } + } + + /// Drop the [`PersistedValidationData`] from the statement in a signed + /// variant. + pub fn drop_pvd_from_signed(signed: SignedFullStatementWithPVD) -> SignedFullStatement { + signed + .convert_to_superpayload_with(|s| s.drop_pvd()) + .expect("persisted_validation_data doesn't affect encode_as; qed") + } + + /// Converts the statement to a compact signed statement by dropping the + /// [`CommittedCandidateReceipt`] and the [`PersistedValidationData`]. + pub fn signed_to_compact(signed: SignedFullStatementWithPVD) -> Signed { + signed + .convert_to_superpayload_with(|s| s.to_compact()) + .expect("doesn't affect encode_as; qed") + } +} + +impl From<&'_ StatementWithPVD> for CompactStatement { + fn from(stmt: &StatementWithPVD) -> Self { + stmt.to_compact() + } +} + +impl EncodeAs for StatementWithPVD { + fn encode_as(&self) -> Vec { + self.to_compact().encode() + } +} + +/// A statement, the corresponding signature, and the index of the sender. +/// +/// Signing context and validator set should be apparent from context. +/// +/// This statement is "full" in the sense that the `Seconded` variant includes the candidate +/// receipt. Only the compact `SignedStatement` is suitable for submission to the chain. +pub type SignedFullStatement = Signed; + +/// Variant of `SignedFullStatement` where the signature has not yet been verified. +pub type UncheckedSignedFullStatement = UncheckedSigned; + +/// A statement, the corresponding signature, and the index of the sender. +/// +/// Seconded statements are accompanied by the [`PersistedValidationData`] +/// +/// Signing context and validator set should be apparent from context. +pub type SignedFullStatementWithPVD = Signed; + +/// Candidate invalidity details +#[derive(Debug)] +pub enum InvalidCandidate { + /// Failed to execute `validate_block`. This includes function panicking. + ExecutionError(String), + /// Validation outputs check doesn't pass. + InvalidOutputs, + /// Execution timeout. + Timeout, + /// Validation input is over the limit. + ParamsTooLarge(u64), + /// Code size is over the limit. + CodeTooLarge(u64), + /// PoV does not decompress correctly. + PoVDecompressionFailure, + /// Validation function returned invalid data. + BadReturn, + /// Invalid relay chain parent. + BadParent, + /// POV hash does not match. + PoVHashMismatch, + /// Bad collator signature. + BadSignature, + /// Para head hash does not match. + ParaHeadHashMismatch, + /// Validation code hash does not match. + CodeHashMismatch, + /// Validation has generated different candidate commitments. + CommitmentsHashMismatch, +} + +/// Result of the validation of the candidate. +#[derive(Debug)] +pub enum ValidationResult { + /// Candidate is valid. The validation process yields these outputs and the persisted + /// validation data used to form inputs. + Valid(CandidateCommitments, PersistedValidationData), + /// Candidate is invalid. + Invalid(InvalidCandidate), +} + +/// A Proof-of-Validity +#[derive(PartialEq, Eq, Clone, Encode, Decode, Debug)] +pub struct PoV { + /// The block witness data. + pub block_data: BlockData, +} + +impl PoV { + /// Get the blake2-256 hash of the PoV. + pub fn hash(&self) -> Hash { + BlakeTwo256::hash_of(self) + } +} + +/// A type that represents a maybe compressed [`PoV`]. +#[derive(Clone, Encode, Decode)] +#[cfg(not(target_os = "unknown"))] +pub enum MaybeCompressedPoV { + /// A raw [`PoV`], aka not compressed. + Raw(PoV), + /// The given [`PoV`] is already compressed. + Compressed(PoV), +} + +#[cfg(not(target_os = "unknown"))] +impl std::fmt::Debug for MaybeCompressedPoV { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let (variant, size) = match self { + MaybeCompressedPoV::Raw(pov) => ("Raw", pov.block_data.0.len()), + MaybeCompressedPoV::Compressed(pov) => ("Compressed", pov.block_data.0.len()), + }; + + write!(f, "{} PoV ({} bytes)", variant, size) + } +} + +#[cfg(not(target_os = "unknown"))] +impl MaybeCompressedPoV { + /// Convert into a compressed [`PoV`]. + /// + /// If `self == Raw` it is compressed using [`maybe_compress_pov`]. + pub fn into_compressed(self) -> PoV { + match self { + Self::Raw(raw) => maybe_compress_pov(raw), + Self::Compressed(compressed) => compressed, + } + } +} + +/// The output of a collator. +/// +/// This differs from `CandidateCommitments` in two ways: +/// +/// - does not contain the erasure root; that's computed at the Polkadot level, not at Cumulus +/// - contains a proof of validity. +#[derive(Debug, Clone, Encode, Decode)] +#[cfg(not(target_os = "unknown"))] +pub struct Collation { + /// Messages destined to be interpreted by the Relay chain itself. + pub upward_messages: UpwardMessages, + /// The horizontal messages sent by the parachain. + pub horizontal_messages: HorizontalMessages, + /// New validation code. + pub new_validation_code: Option, + /// The head-data produced as a result of execution. + pub head_data: HeadData, + /// Proof to verify the state transition of the parachain. + pub proof_of_validity: MaybeCompressedPoV, + /// The number of messages processed from the DMQ. + pub processed_downward_messages: u32, + /// The mark which specifies the block number up to which all inbound HRMP messages are + /// processed. + pub hrmp_watermark: BlockNumber, +} + +/// Signal that is being returned when a collation was seconded by a validator. +#[derive(Debug)] +#[cfg(not(target_os = "unknown"))] +pub struct CollationSecondedSignal { + /// The hash of the relay chain block that was used as context to sign [`Self::statement`]. + pub relay_parent: Hash, + /// The statement about seconding the collation. + /// + /// Anything else than [`Statement::Seconded`](Statement::Seconded) is forbidden here. + pub statement: SignedFullStatement, +} + +/// Result of the [`CollatorFn`] invocation. +#[cfg(not(target_os = "unknown"))] +pub struct CollationResult { + /// The collation that was build. + pub collation: Collation, + /// An optional result sender that should be informed about a successfully seconded collation. + /// + /// There is no guarantee that this sender is informed ever about any result, it is completely + /// okay to just drop it. However, if it is called, it should be called with the signed + /// statement of a parachain validator seconding the collation. + pub result_sender: Option>, +} + +#[cfg(not(target_os = "unknown"))] +impl CollationResult { + /// Convert into the inner values. + pub fn into_inner( + self, + ) -> (Collation, Option>) { + (self.collation, self.result_sender) + } +} + +/// Collation function. +/// +/// Will be called with the hash of the relay chain block the parachain block should be build on and +/// the [`ValidationData`] that provides information about the state of the parachain on the relay +/// chain. +/// +/// Returns an optional [`CollationResult`]. +#[cfg(not(target_os = "unknown"))] +pub type CollatorFn = Box< + dyn Fn( + Hash, + &PersistedValidationData, + ) -> Pin> + Send>> + + Send + + Sync, +>; + +/// Configuration for the collation generator +#[cfg(not(target_os = "unknown"))] +pub struct CollationGenerationConfig { + /// Collator's authentication key, so it can sign things. + pub key: CollatorPair, + /// Collation function. See [`CollatorFn`] for more details. + /// + /// If this is `None`, it implies that collations are intended to be submitted + /// out-of-band and not pulled out of the function. + pub collator: Option, + /// The parachain that this collator collates for + pub para_id: ParaId, +} + +#[cfg(not(target_os = "unknown"))] +impl std::fmt::Debug for CollationGenerationConfig { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "CollationGenerationConfig {{ ... }}") + } +} + +/// Parameters for [`CollationGenerationMessage::SubmitCollation`]. +#[derive(Debug)] +pub struct SubmitCollationParams { + /// The relay-parent the collation is built against. + pub relay_parent: Hash, + /// The collation itself (PoV and commitments) + pub collation: Collation, + /// The parent block's head-data. + pub parent_head: HeadData, + /// The hash of the validation code the collation was created against. + pub validation_code_hash: ValidationCodeHash, + /// An optional result sender that should be informed about a successfully seconded collation. + /// + /// There is no guarantee that this sender is informed ever about any result, it is completely + /// okay to just drop it. However, if it is called, it should be called with the signed + /// statement of a parachain validator seconding the collation. + pub result_sender: Option>, +} + +/// This is the data we keep available for each candidate included in the relay chain. +#[derive(Clone, Encode, Decode, PartialEq, Eq, Debug)] +pub struct AvailableData { + /// The Proof-of-Validation of the candidate. + pub pov: std::sync::Arc, + /// The persisted validation data needed for approval checks. + pub validation_data: PersistedValidationData, +} + +/// This is a convenience type to allow the Erasure chunk proof to Decode into a nested BoundedVec +#[derive(PartialEq, Eq, Clone, Debug, Hash)] +pub struct Proof(BoundedVec, 1, MERKLE_PROOF_MAX_DEPTH>); + +impl Proof { + /// This function allows to convert back to the standard nested Vec format + pub fn iter(&self) -> impl Iterator { + self.0.iter().map(|v| v.as_slice()) + } + + /// Construct an invalid dummy proof + /// + /// Useful for testing, should absolutely not be used in production. + pub fn dummy_proof() -> Proof { + Proof(BoundedVec::from_vec(vec![BoundedVec::from_vec(vec![0]).unwrap()]).unwrap()) + } +} + +/// Possible errors when converting from `Vec>` into [`Proof`]. +#[derive(thiserror::Error, Debug)] +pub enum MerkleProofError { + #[error("Merkle max proof depth exceeded {0} > {} .", MERKLE_PROOF_MAX_DEPTH)] + /// This error signifies that the Proof length exceeds the trie's max depth + MerkleProofDepthExceeded(usize), + + #[error("Merkle node max size exceeded {0} > {} .", MERKLE_NODE_MAX_SIZE)] + /// This error signifies that a Proof node exceeds the 16-ary max node size + MerkleProofNodeSizeExceeded(usize), +} + +impl TryFrom>> for Proof { + type Error = MerkleProofError; + + fn try_from(input: Vec>) -> Result { + if input.len() > MERKLE_PROOF_MAX_DEPTH { + return Err(Self::Error::MerkleProofDepthExceeded(input.len())) + } + let mut out = Vec::new(); + for element in input.into_iter() { + let length = element.len(); + let data: BoundedVec = BoundedVec::from_vec(element) + .map_err(|_| Self::Error::MerkleProofNodeSizeExceeded(length))?; + out.push(data); + } + Ok(Proof(BoundedVec::from_vec(out).expect("Buffer size is deterined above. qed"))) + } +} + +impl Decode for Proof { + fn decode(value: &mut I) -> Result { + let temp: Vec> = Decode::decode(value)?; + let mut out = Vec::new(); + for element in temp.into_iter() { + let bounded_temp: Result, CodecError> = + BoundedVec::from_vec(element) + .map_err(|_| "Inner node exceeds maximum node size.".into()); + out.push(bounded_temp?); + } + BoundedVec::from_vec(out) + .map(Self) + .map_err(|_| "Merkle proof depth exceeds maximum trie depth".into()) + } +} + +impl Encode for Proof { + fn size_hint(&self) -> usize { + MERKLE_NODE_MAX_SIZE * MERKLE_PROOF_MAX_DEPTH + } + + fn using_encoded R>(&self, f: F) -> R { + let temp = self.0.iter().map(|v| v.as_vec()).collect::>(); + temp.using_encoded(f) + } +} + +impl Serialize for Proof { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(&self.encode()) + } +} + +impl<'de> Deserialize<'de> for Proof { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // Deserialize the string and get individual components + let s = Vec::::deserialize(deserializer)?; + let mut slice = s.as_slice(); + Decode::decode(&mut slice).map_err(de::Error::custom) + } +} + +/// A chunk of erasure-encoded block data. +#[derive(PartialEq, Eq, Clone, Encode, Decode, Serialize, Deserialize, Debug, Hash)] +pub struct ErasureChunk { + /// The erasure-encoded chunk of data belonging to the candidate block. + pub chunk: Vec, + /// The index of this erasure-encoded chunk of data. + pub index: ValidatorIndex, + /// Proof for this chunk's branch in the Merkle tree. + pub proof: Proof, +} + +impl ErasureChunk { + /// Convert bounded Vec Proof to regular Vec> + pub fn proof(&self) -> &Proof { + &self.proof + } +} + +/// Compress a PoV, unless it exceeds the [`POV_BOMB_LIMIT`]. +#[cfg(not(target_os = "unknown"))] +pub fn maybe_compress_pov(pov: PoV) -> PoV { + let PoV { block_data: BlockData(raw) } = pov; + let raw = sp_maybe_compressed_blob::compress(&raw, POV_BOMB_LIMIT).unwrap_or(raw); + + let pov = PoV { block_data: BlockData(raw) }; + pov +} + +/// How many votes we need to consider a candidate backed. +/// +/// WARNING: This has to be kept in sync with the runtime check in the inclusion module. +pub fn minimum_votes(n_validators: usize) -> usize { + std::cmp::min(2, n_validators) +} diff --git a/polkadot/node/service/Cargo.toml b/polkadot/node/service/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..6cb9dc4ba58e79617fb183c6cc4d300123f4ae36 --- /dev/null +++ b/polkadot/node/service/Cargo.toml @@ -0,0 +1,226 @@ +[package] +name = "polkadot-service" +rust-version = "1.60" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +# Substrate Client +sc-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } +babe = { package = "sc-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master" } +beefy = { package = "sc-consensus-beefy", git = "https://github.com/paritytech/substrate", branch = "master" } +grandpa = { package = "sc-consensus-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" } +mmr-gadget = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master"} +sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network-common = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network-sync = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-sync-state-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-offchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-sysinfo = { git = "https://github.com/paritytech/substrate", branch = "master" } +service = { package = "sc-service", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +telemetry = { package = "sc-telemetry", git = "https://github.com/paritytech/substrate", branch = "master" } + +# Substrate Primitives +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } +consensus_common = { package = "sp-consensus", git = "https://github.com/paritytech/substrate", branch = "master" } +beefy-primitives = { package = "sp-consensus-beefy", git = "https://github.com/paritytech/substrate", branch = "master" } +grandpa_primitives = { package = "sp-consensus-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-offchain = { package = "sp-offchain", git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-weights = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" } + +# Substrate Pallets +pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-im-online = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } + +# Substrate Other +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", git = "https://github.com/paritytech/substrate", branch = "master" } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master" } + +# External Crates +futures = "0.3.21" +hex-literal = "0.4.1" +gum = { package = "tracing-gum", path = "../gum/" } +serde = { version = "1.0.163", features = ["derive"] } +serde_json = "1.0.96" +thiserror = "1.0.31" +kvdb = "0.13.0" +kvdb-rocksdb = { version = "0.19.0", optional = true } +parity-db = { version = "0.4.8", optional = true } +codec = { package = "parity-scale-codec", version = "3.6.1" } + +async-trait = "0.1.57" +lru = "0.11.0" +log = "0.4.17" +is_executable = "1.0.1" + +# Polkadot +polkadot-core-primitives = { path = "../../core-primitives" } +polkadot-node-core-parachains-inherent = { path = "../core/parachains-inherent" } +polkadot-overseer = { path = "../overseer" } +polkadot-parachain = { path = "../../parachain" } +polkadot-primitives = { path = "../../primitives" } +polkadot-node-primitives = { path = "../primitives" } +polkadot-rpc = { path = "../../rpc" } +polkadot-node-subsystem = {path = "../subsystem" } +polkadot-node-subsystem-util = { path = "../subsystem-util" } +polkadot-node-subsystem-types = { path = "../subsystem-types" } +polkadot-runtime-parachains = { path = "../../runtime/parachains" } +polkadot-node-network-protocol = { path = "../network/protocol" } +polkadot-runtime-common = { path = "../../runtime/common" } + +# Polkadot Runtime Constants +polkadot-runtime-constants = { path = "../../runtime/polkadot/constants", optional = true } +kusama-runtime-constants = { path = "../../runtime/kusama/constants", optional = true } +rococo-runtime-constants = { path = "../../runtime/rococo/constants", optional = true } +westend-runtime-constants = { path = "../../runtime/westend/constants", optional = true } + +# Polkadot Runtimes +polkadot-runtime = { path = "../../runtime/polkadot", optional = true } +kusama-runtime = { path = "../../runtime/kusama", optional = true } +westend-runtime = { path = "../../runtime/westend", optional = true } +rococo-runtime = { path = "../../runtime/rococo", optional = true } + +# Polkadot Subsystems +polkadot-approval-distribution = { path = "../network/approval-distribution", optional = true } +polkadot-availability-bitfield-distribution = { path = "../network/bitfield-distribution", optional = true } +polkadot-availability-distribution = { path = "../network/availability-distribution", optional = true } +polkadot-availability-recovery = { path = "../network/availability-recovery", optional = true } +polkadot-collator-protocol = { path = "../network/collator-protocol", optional = true } +polkadot-dispute-distribution = { path = "../network/dispute-distribution", optional = true } +polkadot-gossip-support = { path = "../network/gossip-support", optional = true } +polkadot-network-bridge = { path = "../network/bridge", optional = true } +polkadot-node-collation-generation = { path = "../collation-generation", optional = true } +polkadot-node-core-approval-voting = { path = "../core/approval-voting", optional = true } +polkadot-node-core-av-store = { path = "../core/av-store", optional = true } +polkadot-node-core-backing = { path = "../core/backing", optional = true } +polkadot-node-core-bitfield-signing = { path = "../core/bitfield-signing", optional = true } +polkadot-node-core-candidate-validation = { path = "../core/candidate-validation", optional = true } +polkadot-node-core-chain-api = { path = "../core/chain-api", optional = true } +polkadot-node-core-chain-selection = { path = "../core/chain-selection", optional = true } +polkadot-node-core-dispute-coordinator = { path = "../core/dispute-coordinator", optional = true } +polkadot-node-core-prospective-parachains = { path = "../core/prospective-parachains", optional = true } +polkadot-node-core-provisioner = { path = "../core/provisioner", optional = true } +polkadot-node-core-pvf = { path = "../core/pvf", optional = true } +polkadot-node-core-pvf-checker = { path = "../core/pvf-checker", optional = true } +polkadot-node-core-runtime-api = { path = "../core/runtime-api", optional = true } +polkadot-statement-distribution = { path = "../network/statement-distribution", optional = true } + +[dev-dependencies] +polkadot-test-client = { path = "../test/client" } +polkadot-node-subsystem-test-helpers = { path = "../subsystem-test-helpers" } +env_logger = "0.9.0" +assert_matches = "1.5.0" +serial_test = "2.0.0" +tempfile = "3.2" + +[features] +default = ["db", "full-node"] + +db = [ + "service/rocksdb" +] + +full-node = [ + "polkadot-node-core-av-store", + "polkadot-node-core-approval-voting", + "polkadot-availability-bitfield-distribution", + "polkadot-availability-distribution", + "polkadot-availability-recovery", + "polkadot-collator-protocol", + "polkadot-dispute-distribution", + "polkadot-gossip-support", + "polkadot-network-bridge", + "polkadot-node-collation-generation", + "polkadot-node-core-backing", + "polkadot-node-core-bitfield-signing", + "polkadot-node-core-candidate-validation", + "polkadot-node-core-chain-api", + "polkadot-node-core-chain-selection", + "polkadot-node-core-dispute-coordinator", + "polkadot-node-core-prospective-parachains", + "polkadot-node-core-provisioner", + "polkadot-node-core-runtime-api", + "polkadot-statement-distribution", + "polkadot-approval-distribution", + "polkadot-node-core-pvf", + "polkadot-node-core-pvf-checker", + "kvdb-rocksdb", + "parity-db", +] + +# Configure the native runtimes to use. Polkadot is enabled by default. +# +# Validators require the native runtime currently +polkadot-native = [ "polkadot-runtime", "polkadot-runtime-constants" ] +kusama-native = [ "kusama-runtime", "kusama-runtime-constants" ] +westend-native = [ "westend-runtime", "westend-runtime-constants" ] +rococo-native = [ "rococo-runtime", "rococo-runtime-constants" ] + +runtime-benchmarks = [ + "polkadot-runtime?/runtime-benchmarks", + "kusama-runtime?/runtime-benchmarks", + "westend-runtime?/runtime-benchmarks", + "rococo-runtime?/runtime-benchmarks", + + "service/runtime-benchmarks", +] +try-runtime = [ + "polkadot-runtime?/try-runtime", + "kusama-runtime?/try-runtime", + "westend-runtime?/try-runtime", + "rococo-runtime?/try-runtime", +] +fast-runtime = [ + "polkadot-runtime?/fast-runtime", + "kusama-runtime?/fast-runtime", + "westend-runtime?/fast-runtime", + "rococo-runtime?/fast-runtime", +] + +malus = ["full-node"] +runtime-metrics = [ + "rococo-runtime?/runtime-metrics", + "westend-runtime?/runtime-metrics", + "kusama-runtime?/runtime-metrics", + "polkadot-runtime?/runtime-metrics", + "polkadot-runtime-parachains/runtime-metrics" +] + +network-protocol-staging = ["polkadot-node-network-protocol/network-protocol-staging"] diff --git a/polkadot/node/service/README.adoc b/polkadot/node/service/README.adoc new file mode 100644 index 0000000000000000000000000000000000000000..2196d5467806cd63751c89c6ab63674c554a5e87 --- /dev/null +++ b/polkadot/node/service/README.adoc @@ -0,0 +1,5 @@ + += Polkadot Service + +placeholder +//TODO Write content :) (https://github.com/paritytech/polkadot/issues/159) diff --git a/polkadot/node/service/chain-specs/.gitignore b/polkadot/node/service/chain-specs/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..11a43e289a21092f1b8779f1dccd315d80dafc17 --- /dev/null +++ b/polkadot/node/service/chain-specs/.gitignore @@ -0,0 +1 @@ +!/*.json diff --git a/polkadot/node/service/chain-specs/kusama.json b/polkadot/node/service/chain-specs/kusama.json new file mode 100644 index 0000000000000000000000000000000000000000..3d16e3aab2831036b473a9fe5804e64d491ceffa --- /dev/null +++ b/polkadot/node/service/chain-specs/kusama.json @@ -0,0 +1,3491 @@ +{ + "name": "Kusama", + "id": "ksmcc3", + "bootNodes": [ + "/dns/kusama-connect-0.parity.io/tcp/443/wss/p2p/12D3KooWBjxpFhVNM9poSsMEfdnXJaSWSZQ7otK9aV1SPA9zJp5W", + "/dns/kusama-connect-1.parity.io/tcp/443/wss/p2p/12D3KooWAJRVca93jLm4zft4rtTLLxNV4ZrHPMBkbGy5XkXooBFt", + "/dns/kusama-connect-2.parity.io/tcp/443/wss/p2p/12D3KooWLn22TSPR3HXMRSSmWoK4pkDtspdCVi5j86QyyUNViDeL", + "/dns/kusama-connect-3.parity.io/tcp/443/wss/p2p/12D3KooWSwnJSP3QJ6cnFCTpcXq4EEFotVEiQuCWVprzCnWj5e4G", + "/dns/kusama-connect-4.parity.io/tcp/443/wss/p2p/12D3KooWHi7zHUev7n1zs9kSQwh4KMPJcS8Jky2JN58cNabcXGvK", + "/dns/kusama-connect-5.parity.io/tcp/443/wss/p2p/12D3KooWMBF6DXADrNLg6kNt1A1zmKzw478gJw79NmTQhSDxuZvR", + "/dns/kusama-connect-6.parity.io/tcp/443/wss/p2p/12D3KooWNnG7YqYB9eEoACRuSEax8qhuPQzRn878AWKN4vUUtQXd", + "/dns/kusama-connect-7.parity.io/tcp/443/wss/p2p/12D3KooWMmtoLnkVCGyuCpsWw4zoNtWPH4nsVLn92mutvjQknEqR", + "/dns/p2p.0.kusama.network/tcp/30333/p2p/12D3KooWJDohybWd7FvRmyeGjgi56yy36mRWLHmgRprFdUadUt6b", + "/dns/p2p.1.kusama.network/tcp/30333/p2p/12D3KooWC7dnTvDY97afoLrvQSBrh7dDFEkWniTwyxAsBjfpaZk6", + "/dns/p2p.2.kusama.network/tcp/30333/p2p/12D3KooWGGK6Mj1pWF1bk4R1HjBQ4E7bgkfSJ5gmEfVRuwRZapT5", + "/dns/p2p.3.kusama.network/tcp/30333/p2p/12D3KooWRp4qgusMiUobJ9Uw1XAwtsokqx9YwgHDv5wQXjxqETji", + "/dns/p2p.4.kusama.network/tcp/30333/p2p/12D3KooWMVXPbqWR1erNKRSWDVPjcAQ9XtxqLTVzV4ccox9Y8KNL", + "/dns/p2p.5.kusama.network/tcp/30333/p2p/12D3KooWBsJKGJFuv83ixryzMsUS53A8JzEVeTA8PGi4U6T2dnif", + "/dns/kusama-bootnode-0.paritytech.net/tcp/30333/p2p/12D3KooWSueCPH3puP2PcvqPJdNaDNF3jMZjtJtDiSy35pWrbt5h", + "/dns/kusama-bootnode-0.paritytech.net/tcp/30334/ws/p2p/12D3KooWSueCPH3puP2PcvqPJdNaDNF3jMZjtJtDiSy35pWrbt5h", + "/dns/kusama-bootnode-1.paritytech.net/tcp/30333/p2p/12D3KooWQKqane1SqWJNWMQkbia9qiMWXkcHtAdfW5eVF8hbwEDw", + "/dns/kusama-boot.dwellir.com/tcp/30333/ws/p2p/12D3KooWFj2ndawdYyk2spc42Y2arYwb2TUoHLHFAsKuHRzWXwoJ", + "/dns/kusama-boot.dwellir.com/tcp/443/wss/p2p/12D3KooWFj2ndawdYyk2spc42Y2arYwb2TUoHLHFAsKuHRzWXwoJ", + "/dns/boot.stake.plus/tcp/31333/p2p/12D3KooWLa1UyG5xLPds2GbiRBCTJjpsVwRWHWN7Dff14yiNJRpR", + "/dns/boot.stake.plus/tcp/31334/wss/p2p/12D3KooWLa1UyG5xLPds2GbiRBCTJjpsVwRWHWN7Dff14yiNJRpR", + "/dns/boot-node.helikon.io/tcp/7060/p2p/12D3KooWL4KPqfAsPE2aY1g5Zo1CxsDwcdJ7mmAghK7cg6M2fdbD", + "/dns/boot-node.helikon.io/tcp/7062/wss/p2p/12D3KooWL4KPqfAsPE2aY1g5Zo1CxsDwcdJ7mmAghK7cg6M2fdbD", + "/dns/kusama.bootnode.amforc.com/tcp/30333/p2p/12D3KooWLx6nsj6Fpd8biP1VDyuCUjazvRiGWyBam8PsqRJkbUb9", + "/dns/kusama.bootnode.amforc.com/tcp/30334/wss/p2p/12D3KooWLx6nsj6Fpd8biP1VDyuCUjazvRiGWyBam8PsqRJkbUb9", + "/dns/kusama-bootnode.polkadotters.com/tcp/30333/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG", + "/dns/kusama-bootnode.polkadotters.com/tcp/30334/wss/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG", + "/dns/boot-cr.gatotech.network/tcp/33200/p2p/12D3KooWRNZXf99BfzQDE1C8YhuBbuy7Sj18UEf7FNpD8egbURYD", + "/dns/boot-cr.gatotech.network/tcp/35200/wss/p2p/12D3KooWRNZXf99BfzQDE1C8YhuBbuy7Sj18UEf7FNpD8egbURYD", + "/dns/boot-kusama.metaspan.io/tcp/23012/p2p/12D3KooWE1tq9ZL9AAxMiUBBqy1ENmh5pwfWabnoBPMo8gFPXhn6", + "/dns/boot-kusama.metaspan.io/tcp/23015/ws/p2p/12D3KooWE1tq9ZL9AAxMiUBBqy1ENmh5pwfWabnoBPMo8gFPXhn6", + "/dns/boot-kusama.metaspan.io/tcp/23016/wss/p2p/12D3KooWE1tq9ZL9AAxMiUBBqy1ENmh5pwfWabnoBPMo8gFPXhn6", + "/dns/kusama-bootnode.turboflakes.io/tcp/30305/p2p/12D3KooWR6cMhCYRhbJdqYZfzWZT6bcck3unpRLk8GBQGmHBgPwu", + "/dns/kusama-bootnode.turboflakes.io/tcp/30405/wss/p2p/12D3KooWR6cMhCYRhbJdqYZfzWZT6bcck3unpRLk8GBQGmHBgPwu", + "/dns/kusama-boot-ng.dwellir.com/tcp/443/wss/p2p/12D3KooWLswepVYVdCNduvWRTyNTaDMXEBcmvJdZ9Bhw3u2Jhad2", + "/dns/kusama-boot-ng.dwellir.com/tcp/30334/p2p/12D3KooWLswepVYVdCNduvWRTyNTaDMXEBcmvJdZ9Bhw3u2Jhad2", + "/dns/kusama-bootnode.radiumblock.com/tcp/30335/wss/p2p/12D3KooWGzKffWe7JSXeKMQeSQC5xfBafZtgBDCuBVxmwe2TJRuc", + "/dns/kusama-bootnode.radiumblock.com/tcp/30333/p2p/12D3KooWGzKffWe7JSXeKMQeSQC5xfBafZtgBDCuBVxmwe2TJRuc", + "/dns/ksm-bootnode.stakeworld.io/tcp/30300/p2p/12D3KooWFRin7WWVS6RgUsSpkfUHSv4tfGKnr2zJPmf1pbMv118H", + "/dns/ksm-bootnode.stakeworld.io/tcp/30301/ws/p2p/12D3KooWFRin7WWVS6RgUsSpkfUHSv4tfGKnr2zJPmf1pbMv118H", + "/dns/ksm-bootnode.stakeworld.io/tcp/30302/wss/p2p/12D3KooWFRin7WWVS6RgUsSpkfUHSv4tfGKnr2zJPmf1pbMv118H" + ], + "telemetryEndpoints": [ + [ + "wss://telemetry.polkadot.io/submit/", + 0 + ] + ], + "protocolId": "ksmcc3", + "properties": { + "ss58Format": 2, + "tokenDecimals": 12, + "tokenSymbol": "KSM" + }, + "consensusEngine": null, + "forkBlocks": null, + "badBlocks": [ + "0x15b1b925b0aa5cfe43c88cd024f74258cb5cfe3af424882c901014e8acd0d241", + "0x2563260209012232649ab9dc003f62e274c684037de499a23062f8e0e816c605" + ], + "genesis": { + "raw": [ + { + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397974a8f6e094002e424b603628718939b060c4c6305a73d36a014468c29b8b7d7": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397997f7003f78328f30c57e6ce10b1956c77d2187fe08441845cc0c18273852039": "0x00703874580800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41a7b36634518c4bd258451d3afca781ef41c43e2cc13767ade6d58216bb4b54e": "0x0000c52ebca2b1000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f1f621ca0c3b5528d881122bde90e1b827b4cf30e43a6ae6992990aece379759": "0x003aac1de83100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339770172b12d479580b3200b65e470a74b301403e004dede5291371b4a6bf56f75c": "0x00301a45ba2900000000000000000000", + "0x3fba98689ebed1138735e0e7a5a790ab0b76934f4cc08dee01012d059e1b83ee": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e6fca7ae4b2bdba3bcf530e3ac30f406c684c98a715c7677eff8435fcc63667": "0x00f022a88c2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d02912bd748b4a3fffe3895a192330666e76812a79ce9c5603a1e801fe0e7835": "0x00920d70945f06000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b458ad08561bd8f502d2ba488697d10b58aaa7c4097d4abb1c8861495348fd6970": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973bfd7d57d0af52453054536bd75561fff89c21e4c6c3ab4176749649ce3730cc": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6e6e15195495b9f45f5eb6c1a25ead6c5e55e89fa4df899a90017c726f6e009": "0x0066497f817f07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339741729cf5ccc6e78bada8a3aa4ee8b0be1c301f8940e2a802060a243e141bbf26": "0x0090abc6635300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3d5078eb15a7c55ac1c9a7fa8c9477c1366019254190a89532d8f409f880bf5": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e828d3681c05e5b3d05a2dd796e2181d0494268719a65431f4739324cf46f68d": "0x00c0af01f46809000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f5c9c45d99505e974266122ed319959d5a83056b47a39b2be2fc61de416c5b4a": "0x008ace1a761902000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44a73cc327e8dd9d815b75faf8562eaf386c553988f2301c833b0499374c722fd": "0x0010d454955324000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339729dd8b37c40d54bc1a5689953a012fb1a0c87c90a525191b26029aa294ba42a9": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1922ce8b85461eba96590da85abb24d7b0c6fc5e45be1d4649d0bf06587c7dd": "0x000e760ff72301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fae3a1d0125f219c434a804bf7bcf8ef325828c8867d124454c57340163b7da8": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fa41f9c794f8a8d146e1718da84032c0de8dbb719f3f612410af88aec4d5a4e": "0x004ac18c1b6500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339779e8bd48f5982c1b708c9ed6e21d84676744194ae3ccc71d121d913afa0bbe00": "0x000620e7ad0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dcbcdfa57483f63b3d483712d8ab90389e7c58a118004af3cd338a0661e37a88": "0x00ba1ae7383a03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e4cdea903ea0345006c772579a6701839634ad756b04cfb27513721f356879a": "0x0094bcba878500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b85307d4e3bf44c953c4d908bb16bca7c150ab259cdc7c27e4abc6e2a88b0da": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b5c2b93c7484f200a29d0afe11d3385d232db85399794fd95f11e010b2d1734d": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397789c577644ce1638f28532b6e3c933204ee95ea3eba4a2231cb174e7954f498a": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a70073f6a4313f86ec574fc4f59ae10a5a0fcd4498b44fe1931bd5792b00ca82": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397754d4cee53776905c849cd201ca56292ea3f1d3ed2360f8ede3f380bb1fedb4c": "0x007274b1750100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339754379caf721a3c90b76521f29b4e3f28a33cbd73f85d2092ce9cebfaf006a3fd": "0x00ee853eab0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ca6ba022f6bac3be96d8f735dbc086a10287a1bab66d847e3d83c3bc64ee4e9f": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397052a7c59281721b1a40e2f586925a0b1767151bb100c458151c7f56270b3f5d7": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972dc2f9578bbe9dd3fb8ba0738523960abbecff4afd648d56a80132e2163f83f3": "0x0094dd8dd8a400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ad78517765d2a0a421f61fe196497805cc5f43a1b5fd8a826524e2b775f5319": "0x00e69d55840b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d33e5781c49c9c746b2e131b9cff6fb78904d9e7bf24ee7892196ddd1632eecd": "0x009e86e7d71100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799ab88eff5e24ed56030f881123207fa2f62c4c365ee2f7c3b4856ef2e320b7b": "0x007465c1f55500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ad1578ed6e6b827a9fc09893cfe78624c7b93de6c45b6c06d3f1ce2f16d0b523": "0x0034a8c5180900000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579733de9bb3e2b5cdc4c62897bbb89b90cb7cd4f88d3fd74f75b9e2287f8a688fbb2": "0x2280483e7614020101d7e03e0019d5d0c082ba9e23fc43a2a36b261bcfa5cc3b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767707643450e6414713f1a209956d1a8a3c017638a62b089196a201f831e867d": "0x00de0af1581922000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976be50ac8ed1b058edcff2da0258f9889fd94623b2de76e4014f12f4a65f74256": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff4c96fd615086a7582e09747547294f94f01a1c1b96cf9a3ff416b5ab9be05e": "0x004ed7a1c0bf03000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44520e3e74c0b8ee4bebb68dcdd5682bbb448f5f23eca33e44d815c7184fd0a5c": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcdc525a4440d717d18fb6336df540e601e4e27825c1b3db2c1e5ce2000521e7": "0x0050be534a1700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d77e2cd53251d7768d3266d193a967a8e232116e221a6cca7563ae548b11c34a": "0x007e84c4358901000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ba1ba137f951df73983d306bb783236caeb9420de73544761d9cc5908df98dec": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e6d721da930ac167a1e7d12abca9ab8e9f845cd3eb429af032d14e67c4f894a": "0x006c9bea403b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397067c9380a294fa0728d3be3dc810771972ee69ccb575a8b860760246ce3a3578": "0x0062b4f104d248000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397204dc87cf6847e48faf6b4fa494554988bf17416549ba38f3238b4820426c545": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730218c717b1fc594ffa846b27a4c215aae934219d804fa2f74a845ac0cb50cfe": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d90cd396f1a6384b0fddf41d93617ba1170c1da431c959df6b7b5a6c1e8a69b": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1735a3fc5e7f4e72f6d7b9b7c16c1679140f9c7e61b578cd5218d49b89d6d80": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcb14d8270187870723fd212870b79a003c6635fe1b876f80ed7295b5a187d26": "0x009ea4c3e42800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ceff548f87c2755fd1944f1d2666347dfd1eda6ae32f9793c9bffac1924c1b2a": "0x00a8b5d34bc800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339741f5e2d0ceb8587b5c293e028135bb1e3abd2ac7f7d931872b9cf7dff845564d": "0x009cb26e1c2100000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973aea5831caa7a6398ec3db4a14da0e8b8581c5a7ef73696fcd6b6d3106dfae129": "0x7ce21330f614e9f11065cf3e7e96207fec4086b7cb83584daccf6bac6d35d16c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339710ac69ce999dcdb321d47c111dde561e0e868109cc545b2c9ac7406fd9557954": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397745abd91bdffdfa88cd35b300f1c414a7ce04adbc46c22b40503776d5263c480": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b4655b53a0769c2e6956a1df10c8c9135cbf7acc2b09fbf9b569590bb17a98a0": "0x0012fd6a7f1500000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e922ce7fa58efcf807e3653bc7b03d14507704042251611d15a7b004a407b4d9": "0x0050a795168301000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243dea3ffc2e7aa5c5b6d6831d2cad7782d8da64a543ce26678c125c61022369a13": "0x00f45658a0d7480000000000000000002029f5c202000000000000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a3a59829e59a4cfc32f5ce21b45d1c06c2e0fa883df5e8f261c0add2ca8fc792": "0x008032b03281ca000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b424b1cffe3c67b4fa4fac0de9c461c26445222ccee3bd2f9026cc44e907699495": "0x0040763a6b0bde000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973fe5adc9e97722f9dce228015d3f7bfe9d51e6cb62cb5ba50a24de8d0ded8744": "0x007ebb5c423f0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d58666e3bb47d5457964ecbe97528e53f1de01399f1bb9ed0a53af5ab6bda669": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d78ff82e686f83dae1e8b24e4a1ede7d1c62b481f791d59ae2ee58d21818efe": "0x00e0e6a5d93411000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba02d42c0bcabb479f9f045e31ff7c9a22621e048b609196b3eea05421d1ed9f": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971322ac4e3a23a5c23f17712dbf14691b7c72958c2f74ed442f977060ac58b837": "0x001242a3973e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397822340b1e940c2975f00edd96ebd8c82f9b5a1eaa1b83f1133b5f028f330ee4d": "0x005ecf6db84c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a03d38d5c398b22dfd48cdb59c1d4d875a13b742f833558868b2455a12211a78": "0x00d6de0f830800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733799c5c462e17b01355b89cf4f4f54a4e056aaea1f52cabad063a87b1492263": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f89a780b1339e04925d09322877157ffe42e26662488a9dd3f80e84bd4ce63b9": "0x00d6c280a42800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972941f4915b68d9d76470f34bdc1d32655a1e7dc016715d07e4174a9455284545": "0x003644e1317705000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a266abdfb072f3c5feac53966a1349f33dca4aed4785b2700aa7395cbb530b8": "0x008e804bf80700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339753b81957ac67b7566d6ac5c4968f98b99bee8d28b75fe84d8d6aea149bd2e076": "0x0024a0d50d5d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6e998558892d6e155a9e08d4d470d9a26ae666d5c351c947ca507e7c83b057b": "0x0044c061f50800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f980ff1f6395141a6d33d4300e72d0c3d2bfd71afb8b7e6fafd0d586c950945": "0x00fc7e05c71200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8c0b4a5c3c2090684d60accb45b33076ffe96c512d2c93ea4f77dd798ae4b3d": "0x004e99ec4e3705000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397332f19a7c772fc929cf3e6858d7bcddec594def82f95ffda9fa39a70b95ec6d4": "0x0036e9591cef02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e331dc123c692c6fa8fc0cd5c83f3a28d9013ed90266ef14a1b418f2454197a4": "0x008234c2fa5801000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c00fa65e05a83080147cce317492a0e666a1c78bfddfe6d51b46d0db25b54cc5": "0x00a29994f40300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa9545512900538bc6ffbdd43f9b69938a43f5073795bfab2de9df840aa4347b": "0x00ace901606903000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4b0dfd2227de2f1b0588b27fb63a5aeea396b7fd21f51f5e61be7cf0e311797": "0x009268fea65208000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973cfcaf4e0903d8db4125a2f2d29810a08af34556fa01c201b913132cd16356ce": "0x00ee853eab0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a69383b523d6131828456403fc270357768525ef7f0dec8c17e38936d62458f2": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794e26bd60d5401eeeb593664c906a4260794b653da1a63911ee41e011df81e49": "0x00703874580800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4eb5a80d3f6499d0fd58861912f5adfff048b42fd057e6cfeae0add8a360a95cf": "0x007ae6d4678500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c2a82a7ca7c78f90553ebcc61e889d7e4f3488953d6e1c5552b93dc62ffa3ad": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971eb6d94274fa7bc01759df096c9d1f3fb465521b8b84e8685efa9f43136b19cf": "0x000484564a1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ec30caabee77a4a9ce9bd60c8e96a8661ccca76be5bc2c24301ffb9d7a09926": "0x00de9804010b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dea1062b95a1ff932a7569ed813f11468f457bf2ff0150657a5dbdb8a677f3f1": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f724485f4ab5308fb16482200dde5684b0e0146836c2b03f03c1c0056f667bd": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c341e6645b1317451d5ea6e1f735eb00e1d63bd71020725237684d06f060a60e": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e8835f23f30bf64485525782f19b70eda5c22dd35afac03e128e564513b66a10": "0x008c0d35660200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339704a8b2517a75b8dbc8bfeb7aed28fad5f8f23315e3f90433cbd1ef357c60daa1": "0x00865401b47f04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c3512369f689cbec16974ec77f6fdf5541bfe6726d8f745905d35dc1a2e7da2f": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5208cbdba231edd4f04daa745a321b1c31b8ab825d02b361ef852750cd53ef1": "0x0076e6a2f50000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c11874611da6d1f761ddf9bdb4c9d6e5303ebd41f61858d0a5647a1a7bfe089bf921be9": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab0af96c9d94350c72015a59f3bf17c8a682e1009120026ab04d605b19cad232": "0x003a6373de8800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785dcc8d184bc511fe6653e1981fbd0666c5d14b16e6c720e3d313ee0f9d90535": "0x007ceafac42900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974faa8a59d4dc6db203199ec3677375d168946b033e0f1c404d31ca95fe7a4be7": "0x0010b4426f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a5b2821c132430e22c7fc76d8baf93f29346c79855d0a3241575e5abbe7ffff": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973398dad16f5305521e1e3380f67a8c06d0c0c03de197cab91c8bfe7d01d124e0": "0x00747465e12500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397370672289ba510a03758a226e3168237a2a3ed4050b732c202cf26d24aed3eab": "0x002caf1a406500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a437dcc0b229de3ffb8288984c6433377ff074367e39c9bf881b91f48939f14": "0x00aac947aa0d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ac527cac1cd33c6c873d70069434757b8dbf06274ee4bacedfb0be7db757170": "0x003e3ea46d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397247b4d30bbb2a911d8806e2c5203c8a236eed8d2bc636dc0d3ea227bab946df5": "0x00009791882600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397354df7167eafd48698755862192ae0b37aee48a686206711497ba4416f638bbf": "0x00ea6c66a4cf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6312ce2f4e48653f666f9c944828ed65959d9f0644e47318ad699a4ed3eaab7": "0x0074e2759bf100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd66a982c7a0626195bc52619a34a09478f5ae3231f6ceb9b1e02a100a6c3790": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9e0cd7b294115092be477193f1c3b31b71e18ab9612822c5916c7f3165046af": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778c98ca3b99346fe215a33131b2bf9f6824f904a48cd715f5b11716453cf7def": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972fd4b96ef6543fa8bb66ec982db68418467d5d2a5334e86dff53d1c88d76592a": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397220cfdd38475e3e5d451c5dc5158eb704abafe2bd9be13ce7de31a2ea1689971": "0x0018dc4ea44500000000000000000000", + "0x3a65787472696e7369635f696e646578": "0x00000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d06cbf065af0fc33efb57ddadf42d19dba5e17b32d0df1073df994783b63ab2": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973257e712280e9d1fb0b6f6d548a9005d065628973dbe342f5fa97c7879bedcb5": "0x0094adb1ce9700000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973c86ae114840e37d825672c2bec7ac6f8f89a419ed5d0dd5103bffa73d923dcb9": "0xfcdeb580add093f3b5f06603032c2fe89d329ba372147c100aa0391a44a51601", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c0ba7f983b8dd3bdfa2e5ac1d582063d75183b49f3ac7cd0f17350e6fb4ad717": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339788227ca9bc76f0f72d22a2609a87988589c288f1c05bc74f4528c4c4d1156690": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c0a824df4457348a140dfe24017db194f233640e99ec2763d93b08ccf21fa3d5": "0x00c029f73d5405000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d2563bc02213b8451f5e068530a2843dd7abc6417e29e67178e8eae3b5e78cc": "0x0078ca2c506300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397995e43c001a9f6ebe8ea2eb6dcc6177df5693d5207da9c223c8d3d8ad00498dc": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720798289dc984aa716a2784d8b8ccb4f9413e9349cad67412ba8942446134276": "0x00e45615d51b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b48b110bf4ba7b91a18ebdf61c146ad49c8e05668e5b8e3dbefcbf519adf0f32": "0x0086985bd4a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397339115f62e0a5f0702de68f262266de196470a62228a7987df67f81c96238a8c": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1c95c5a320a8afceb1e04c073f7f31035d9ccd37105575c251365a56508223e": "0x00e26fad98e612000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ece4f70b3cefa862644a5725c11c08c247b2835d6252f28038ec19b0bb9ab20a": "0x00d6c0fd102d00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e49e9344ad7601a3591e06a19ac8b9c420f38d78afc7aada469d0d714aa54797": "0x00246fa6c1c601000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243381b5bd9b04a62616c14b718a534b6cbdc303df70f4a1ffe5c65cee67f955361": "0x009071177792b4000000000000000000409682d806000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397829ad0a116ab8a11380353da58affc5ce4c0ff1c781659c43ed61b3dee8e3d2f": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339757ec21ab6695ab295d17684e75453c487312befafe2d26b93d155f893dafb942": "0x00a030937f8901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764875eb01bc6af788c3c31d26fc5e4e8787378a4eae04a00d795cad1f81adf82": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798bd9508a53aa1bb688972851bf0424a1530baca911a2250fb7f4a064f557721": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978b87024e52bb095a2083cae78771c38202f742214c69237fb98bc6764e051983": "0x00cc6fa527a006000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339710a8ab45e9b45a8c21686c5513ab7dcfa5f664f6dae36e7f3b53cff0f5d4fabe": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c7d8f5be66c2b4b70532c287ab16c0ffbad0c2ef6e0b160aec3db34acf414ed": "0x00828a13987702000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973722f024c8c23dba42c4239f27469279d5017d5b769d01b35d769e04239022dbb": "0x7ce21330f614e9f11065cf3e7e96207fec4086b7cb83584daccf6bac6d35d16c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979d583ed371e8169c890cd663ff695710d6fb853c34d6722f172135594b99a729": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b429a1871d8a2faba2d97a0a0718446d183c369590c64c8c513572a1268ab76095": "0x004c9749858e05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6458eb8d26660af37c2faea09a11599ca89b85f9e3c2107b134a5578b555ea9": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707ab9dd594f4dbf2c191da3651968cb34d5151497dc4b124a8376bfa39f54fcf": "0x00341a7e291900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718ebec30e87e22b66f38451d845720e58bbf851147b4200924ee28e3f22ff948": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce7e20b990a459a8443e0b3670ede0c1a92781285a93bbbc1cdcd481ca4444eb": "0x0088515494a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b338b0ad71aa9de326d890546d6138d5307d5e67909c7a446fc8fb7a3be700e8": "0x004cc5b2780900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e5454f3364bab53e88a03b781ef5830939ab7febd729453cb1085ab4dfa9b88": "0x00c0e1d0612100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282430def09fdffb7bd58bb75d518d2249595980d1cc1bf2dc93d937c237869a8f1f0": "0x00b072e0e023200000000000000000001f2fee3701000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973308654661e24d83a269e88eb8982eecca4971f8af63ac7dbe6016e33e7febfa": "0x00da02e30fe310000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d7e38c71716c0de7a18f08802575a5785b319ad2b2b7a9e3e3f9722682b7838": "0x00ca91bb010500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a3d8f06212bf3ce7ff91c8bd512b1165029b3c1a080fdaf174772c41c375607": "0x00c0d0d335a51a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac694ee8d96a0c6bdd326d674a53f4cc39e5f10bd7adf331f604022b04ad4f3d": "0x00aa63d0763c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b23da41df1a59bc8ff0087355ae5a165235a85140df3a2705ba33c4a4562c04c": "0x0004f52ee08d00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b470490cb6ec60dc6b19173b661b8cd3092307f849ae2648554c2874b55ad11374": "0x00c06e31d91001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f64a3bb27db1537ac602507c29b91156971f1fd3c5d4d6487c4a7773db6b0b85": "0x00f4fb4e8b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf8d3b3d2143653fc8819c06758165b46d58ba4dc341a5aea9133ceed2a69c17": "0x0042224efe1700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243004def926cde2699f236c59fa11909a2aee554f0fe56fb88b9a9604669a200a9": "0x0044aba9fe9a18000000000000000000ccc0cdee00000000000000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c35e845c54d8010c8eff4ccab96cfab69a229cc701584c09f668f9a6ae9311cb": "0x00741a684c6926000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339754d731dd1079e9d06d41ee942f6ca5dd511a052e59ab4672cd9ccbc771bcce4e": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9c38f3cb67ad389da1fea02b50934044c8942b235076a2733615be45696e2d4": "0x007ef911b4c709000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971372cf7ad7d5fbbf810e611df7f7eebf31e82de6b19cdbc06d913b2cbdd49878": "0x0044135e7e6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3b5ef48ee1b70d183dd75d55e962e7aee8d2cf86efee716b94e8942b77a2e75": "0x00769ce20bfe00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397982e792cd0b86e3573f32d4e83cac5d3a7af33d5dc32952742122e3e58c01e7d": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397171164e36c6ae5461e56a6e9b052623f3d84ba8166d5ef7bf1f36c21c93795db": "0x005ebeb2030a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397782573037266ead3a88b370a9178a50d8ffbf73e92b386d998666201edb2b3f6": "0x00769f7b7f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9b73a54869acaefd3ffcaed30fdad0d7c1ae6b67f28afa9e65b92197d1fe8b6": "0x0094a032a61000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b44e2aa4f43b1e7480b75e951cc9367626f75f8403bc9d70f8eaa13d552d2dd": "0x00724f344b0a05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768759212e8924e5e295195452fd08a3d1caba0b182590e0b0d1e9a32ea841057": "0x00f2bf116e4100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794d38658f722ad8c9e3fdf95527698a1cc8b77b36fb8c1527da15593a30ec378": "0x003e3ea46d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b95ce3677f1d0f62f0f65f43b693a4f52ec1a3d31112d550590d92df03412bb0": "0x00a0ed86271400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb1f28fe192cb557d4b1bcbea1da02b6f8b5fdfd7d705c44a1f21dae311f15da": "0x00d44d82b10900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397229c4b0d50e65af496b3306472337a93ed36c69413e935cc240fb00023564007": "0x0064befdaed000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f932ff39814a267614a8ab7c9e755ae4f1058e4cc415c58cbf154c7e4f70907": "0x000ec19d5bbf09000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975bf02156495e978eb8ed406023f4cc77cc77d7095abed7a0ec70faff06e8e14a": "0x00d616f8da0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972054580f8eaef85b62f26ecc78f8aa9b74a07632a700983c0dcd27adfceb7b7a": "0x00be6c373c2000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a3b010f7e0b3d115b8200220a679a8f3335a91b48ba574ab94bd24fa4c725af": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d742cf2731edeacd2d1baf6df78afb6321b22fb511463acc1b1a76d7169e1c94": "0x00d26a9b6f0d00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e75122c088bf3b4e7853c99e49636d9e7c9a351918d70bd6cdf6148b81e68f5706f68": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532140a5f09cf809733cce35f1e7c955aec37d1cc921354afd09761dfe53cb973de8788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455321288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532119f86e142266f7792e51697db6bb58a6a791096b533e2196c7a00f2c6bcdaa09e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320f2a3fa40b4085d8adf7dddf3e3073d45d43cc9e55de72822990fa2d84b18faf2088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320c1e85a736bc96d03373ecee63582d6395f0072537b645ed6310d15523c098906188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320aa4242d7ddc8058699e8d9ab1f810f623827db979c509b6376846b8520196031388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320274996f6e635ee65e9f3cf43e61001b20dafc62ce52407ec51c9b16ca9ec9a57f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455320088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ff88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531fe88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531fd88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531fc88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531fb88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531fa88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531f988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531f888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531f788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531f688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531f588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531f488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531f388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531f288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531f188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531f088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ef88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ee88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ed88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ec", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397896422f5233646e6d8bc797b65565527a8d7e0f542465afcee1611612d13f8fe": "0x00407a10f35a00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4da2f35c114e20fb2cbd91fc405b01b55351f52d67b07ece1098a99a87fea47f2": "0x001e0f9c057b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f81d492aec4ea43c63935d2f751a13e1b7a3e8a4e630771fd3a8d86cba351b8": "0x004810e3f90a10000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970dee46171653cac09b2d1a2c9837a7c5186c5703b8573163120dc3d7241cefeb": "0x00a0325a721f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970cab17f38e77eebe85314e92ddae79d2700aa6741407e57f1b0792c1b7b3c3fa": "0x00a81d21e0b50a000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b484dd0841a25608fd02380415d38d197c86e52a283ac20ad7a81af41d86aec634": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6777b222c262269dac0c0827a1f9dfa1aaf612c04b0a5abd6161ed0a70635ad": "0x0058692a7db81f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b173661cfecc5e1f85c941d089dd9de22f20d3e03a0c0f63e47b7af40ef44fa": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f5124afd69644bd34ed0200f2d8517a264a9b4f675474924a2867424006a5e6e": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc9ac3cc9b683af33c32050cefd0537c96c771931d798d6858b8e5c252e5b21f": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c660feb22fa22977a5d9b631db428315ce49cb7afeb3b154a5c0967f23e99a01": "0x00defe0f6a5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339752fd2c21f385a37fb1d87d501f2e88d5cd5f9ca9e0773b67e3c4dcce2e05a8ba": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f39c1422cc4dc706e2c6f94f9ddf1c3d91c18011d027fc732b92a29ccb8083ac": "0x000620e7ad0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc104196ef44beecbdaa8e10362a09d79ef8971a0618729ee10583a05eee822e": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397533d597f2adc9d49d811f43791770dd9dfb20e4a174fc682cf495ab40075d7b5": "0x0008711b0c0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eab4b1bd47696057bde71475818281cd44c69dfec55ad3ad41dbb8b90afc23d9": "0x0040b10baf682c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793077e5016b943743b2d61870baf68d5b53386dedd3abf30970c7686e610d48b": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397996613041f3f0e70cfa79a798dd9bb49be0daa10c0b3c8bfbf600bd24241e151": "0x00f424648f0c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d228d43339f8a0079374f79c73208a869c3d9a14d17a2597d132022617a289ba": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977810ab558742e904081bf499861a76ad7609566d4243ad39febb66a46a4bfa2c": "0x0012a3c85efa00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b436d2aac8ef5db749006e32aa850ee6cd732276ddc239a1a7d39a1abdd9003090": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b9eaee18fa03d2a8d852e58f35244ac4f15d38d42377be65125a73493f75c02": "0x0052f09cb80800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973d56a060dbc7fab1ba55722fef90cb348328bbb736a77cf01b8f19c24f56d099": "0x00a630de2a5002000000000000000000", + "0x3a636f6465": "0x0061736d0100000001a4022b60037f7f7f017f60027f7f017f60027f7f0060017f0060017f017e60037f7e7e0060017e017f60027e7e0060017e017e60017e006000017e60037f7e7f017f6000017f60027f7e017e60047f7e7e7e017f60027f7e017f60037e7e7f017e60017f017f60037f7f7e017e60027f7f017e60000060037f7f7f0060047f7f7f7f0060027e7f017f60057f7f7f7f7f017f60047f7f7f7f017f60027f7e0060067f7f7f7f7f7f0060057f7f7f7f7f0060047f7f7e7e0060067f7f7e7e7f7f0060027e7f0060077f7e7e7e7e7e7e0060087e7e7e7e7e7e7e7e017f60057f7f7f7e7e0060067f7f7f7e7e7f0060067f7f7f7f7e7e0060047f7e7e7e0060077f7f7f7f7f7e7e0060057f7e7e7f7f0060047f7e7e7f0060057f7e7e7e7e0060067f7e7e7e7e7f0002ca0a2103656e76196578745f6c6f6767696e675f6c6f675f76657273696f6e5f31000503656e76206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f31000603656e76196578745f73746f726167655f7365745f76657273696f6e5f31000703656e761e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f31000603656e76196578745f73746f726167655f6765745f76657273696f6e5f31000803656e761b6578745f73746f726167655f636c6561725f76657273696f6e5f31000903656e761a6578745f73746f726167655f726f6f745f76657273696f6e5f31000a03656e76226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f31000803656e761d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f31000903656e76236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f31000b03656e76226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f31000903656e76206578745f68617368696e675f6b656363616b5f3235365f76657273696f6e5f31000603656e761d6578745f68617368696e675f74776f785f36345f76657273696f6e5f31000603656e76236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f31000b03656e761c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f31000903656e761c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f31000903656e76236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f31000c03656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f31000d03656e76346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f31000e03656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f31000503656e76256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f31000f03656e76206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f31000603656e762a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f31000603656e761a6578745f73746f726167655f726561645f76657273696f6e5f31001003656e76296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f31000803656e76246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f31000a03656e761e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f31001103656e761c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f31000303656e76286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f31000403656e76216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f31001203656e762c6578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f76657273696f6e5f31001303656e76376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f31001303656e76256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f31000f03c604c4041111030300001111131403021500140216030001010201021703041819020016010101110101010101020116030103000101000101000100010102021502010201000101010203021602020302020202020202020202010202030202020202021101110215020202021503021503151a021503010303020202140302021501020215020215020215020203020c020202020203150202011b010215021402021502020202151c030303150202021615150202020311021c1102030302150502021c0302030203030202020302020202151d19151502031e151502150303021502030202021615021e15151515150303030215030202021d030202110202021515030302020201030302021f16030202150319111603021511030302020202140203022021011c161d07050703140202021502021503031502020503050322020202021d0303020302110302030303020302021903030302020202010101020214231511020224050303030202020215030302160202011602020102030202030203020202251515151115151515020215021502021602150203030202151414020302030302030202021102161602030303020202151503020202260303030303030303030303030303030303030303021502140303030303030303020202020213130302160213131302131313131315071302031c001313131313131313131315131300010103030215150303030302020202031d02270202031403021502020202020302152202020303020303030315151101010205011c010000000028282929292a0407017001b601b60105030100120619037f01418080c0000b7f0041f8bec6000b7f0041f8bec6000b0795061c066d656d6f72790200195f5f696e6469726563745f66756e6374696f6e5f7461626c6501000a5f5f646174615f656e6403010b5f5f686561705f62617365030209686173685f7465737400290c436f72655f76657273696f6e00810412436f72655f657865637574655f626c6f636b00820415436f72655f696e697469616c697a655f626c6f636b008704114d657461646174615f6d657461646174610088041c426c6f636b4275696c6465725f6170706c795f65787472696e7369630089041b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b008b0420426c6f636b4275696c6465725f696e686572656e745f65787472696e73696373008c041c426c6f636b4275696c6465725f636865636b5f696e686572656e7473008d0418426c6f636b4275696c6465725f72616e646f6d5f73656564008e042b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e008f04214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b65720092041850617261636861696e486f73745f76616c696461746f72730097041950617261636861696e486f73745f647574795f726f737465720098041f50617261636861696e486f73745f6163746976655f70617261636861696e730099041e50617261636861696e486f73745f70617261636861696e5f737461747573009a041c50617261636861696e486f73745f70617261636861696e5f636f6465009b041550617261636861696e486f73745f696e6772657373009c041e4772616e6470614170695f6772616e6470615f617574686f726974696573009d0415426162654170695f636f6e66696775726174696f6e009e0421417574686f72697479446973636f766572794170695f617574686f726974696573009f042153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b65797300a0041d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e636500a204205472616e73616374696f6e5061796d656e744170695f71756572795f696e666f00a30409ce02010041010bb50137464b41d8044243618201594e9f0157940177fc02fb02b90149323334358f025a3b4f5051525354555f60676263646566fd029901f1029801ea019701e602ff03e901e801ef01ee01ed01ec01ad02da0483028202aa02da03a902af02ae02b002b602a302e802fe03ef02c203fa02f902f802f7028e038d038b039203a003a303a203c503d504d903d80396019501e003b902b301cd049f03a103f403f503f603b903e103ed02ec02e203ee0290039103a804a704bc04ba04e303c404f002e403e502e402e503e702ca04cb04a802a702e603c901c701e703e701e601e803eb01d103cf03e903d003f502f402ea03f602f703f803de0389038803eb038a03c103c303ec03c40381028e02ce04cf04d703dc03ed03b502ba02ee03a202a102ef03f903fa03df03fb03fd03fc038004a404a504a604c304c204c104c004bf04bd04c504cc0447480af39638c4040600200010220b06002000101a0b0600200010240b06002000101b0b0a0020002001200210260b2801017f02402002101a2203450d002003200020022001200120024b1b10dc041a2000101b0b20030b0600200010280b1c01017f02402000101a2201450d0020014100200010db041a0b20010bff0202017f037e230041206b220224002001ad42adfed5e4d485fda8d8007e42b9e0007c210302400240024002400240200141084b0d00200141014b0d0120010d02420021040c030b0240200141104b0d00200241106a2000290000200385420042adfed5e4d485fda8d800420010e104200241186a29030020022903107c200120006a41786a2900008521040c040b200120006a41786a2900002105200321040340200029000020048542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e2003852103200041086a2100200442cf829ebbefefde82147c2104200141786a220141084b0d000b200320058521040c030b0240200141034b0d00200120006a417e6a33000042108620003300008420038521040c030b200120006a417c6a35000042208620003500008420038521040c020b200031000021040b200420038521040b20022004420042adfed5e4d485fda8d800420010e104200241086a290300210420022903002103200241206a2400200420037c42c300850b0a00418080c000102b000b5b02017f037e230041306b220124002000290208210220002902102103200029020021042001420437031020014201370204200120043703182001200141186a36020020012003370328200120023703202001200141206a1038000b870301067f230041306b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240024002400240200141146a2802000d00200621070c010b024020040d0041c080c00041004100102d000b024002402006410f4b0d002003280204450d010b200620066a220720064f0d010b4101210541002107200241086a21060c010b2007417f4c0d01200241086a2106024020070d0041012105410021070c010b200710212205450d020b200241003602102002200736020c200220053602082002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241146a41d080c000200241186a102e0d0220002006290200370200200041086a200641086a280200360200200241306a24000f0b102f000b200741011030000b41e880c0004133200241186a419c81c0001031000b6c01017f230041306b2203240020032002360204200320013602002003411c6a41023602002003412c6a41013602002003420237020c200341f881c000360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a20001038000bbd0801087f230041c0006b22032400200341246a2001360200200341346a200241146a2802002204360200200341033a00382003412c6a2002280210220520044103746a36020020034280808080800437030820032000360220410021062003410036021820034100360210200320053602302003200536022802400240024002400240200228020822070d0020022802002108200228020422092004200420094b1b220a450d0141012104200020082802002008280204200128020c1100000d04200841086a210241012106034002402005280200200341086a200541046a280200110100450d00410121040c060b2006200a4f0d02200241046a210020022802002101200541086a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110000450d000c050b0b20022802002108200228020422092002410c6a2802002205200520094b1b220a450d0041012104200020082802002008280204200128020c1100000d03200741106a2105200841086a21024101210603402003200541786a28020036020c2003200541106a2d00003a003820032005417c6a28020036020841002101410021040240024002400240200541086a2802000e0400010203000b2005410c6a2802002100410121040c020b02402005410c6a2802002207200328023422044f0d0041002104200328023020074103746a22072802044102470d0220072802002802002100410121040c020b41b087c00020072004102d000b4100210420032802282207200328022c460d002003200741086a3602284100210420072802044102470d0020072802002802002100410121040b2003200036021420032004360210024002400240024002400240024020052802000e0404010006040b20032802282200200328022c470d010c050b200541046a2802002200200328023422044f0d01200328023020004103746a22002802044102470d04200028020028020021040c030b2003200041086a36022820002802044102470d03200028020028020021040c020b41b087c00020002004102d000b200541046a28020021040b410121010b2003200436021c2003200136021802400240200541706a2802004101460d0020032802282204200328022c460d042003200441086a3602280c010b200541746a2802002204200328023422004f0d04200328023020044103746a21040b02402004280200200341086a200441046a280200110100450d00410121040c050b2006200a4f0d01200241046a210020022802002101200541246a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110000450d000c040b0b0240200920064d0d00410121042003280220200820064103746a22052802002005280204200328022428020c1100000d030b410021040c020b418086c000102b000b41c087c00020042000102d000b200341c0006a240020040b0500102a000b2400410041bcb8c600ad4280808080f0008441c4b8c600ad4280808080a00484100000000b810101017f230041c0006b220424002004200136020c2004200036020820042003360214200420023602102004412c6a41023602002004413c6a41033602002004420237021c200441f8a9c500360218200441043602342004200441306a3602282004200441106a3602382004200441086a360230200441186a4190adc0001038000b02000bb10101037f0240024002400240200028020022002802042203200028020822046b2002490d00200028020021030c010b200420026a22052004490d02200341017422042005200420054b1b22044100480d020240024020030d002004102121030c010b200028020020032004102521030b2003450d012000200436020420002003360200200028020821040b2000200420026a360208200320046a2001200210dc041a41000f0b200441011030000b102a000ba70401047f230041106b220224002000280200210002400240024002400240024002402001418001490d002002410036020c2001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c040b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c030b0240200028020822032000280204470d00200341016a22042003490d06200341017422052004200520044b1b22044100480d060240024020030d002004102121030c010b200028020020032004102521030b2003450d022000200436020420002003360200200028020821030b200028020020036a20013a00002000200028020841016a3602080c030b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b200441011030000b0240024020002802042204200028020822036b2001490d00200028020021040c010b200320016a22052003490d03200441017422032005200320054b1b22034100480d030240024020040d002003102121040c010b200028020020042003102521040b2004450d022000200336020420002004360200200028020821030b2000200320016a360208200420036a2002410c6a200110dc041a0b200241106a240041000f0b200341011030000b102a000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41d080c000200241086a102e2101200241206a240020010b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c2002419484c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41a484c0001038000b0b002000350200200110390b4702017f017e230041206b2202240020012902002103200241146a20012902083702002002200337020c200220003602082002418882c000360204200241013602002002103a000bd20203027f017e037f230041306b22022400412721030240024020004290ce005a0d00200021040c010b412721030340200241096a20036a2205417c6a200020004290ce0080220442f0b17f7e7ca7220641ffff037141e4006e220741017441ca82c0006a2f00003b00002005417e6a2007419c7f6c20066a41ffff037141017441ca82c0006a2f00003b00002003417c6a2103200042ffc1d72f5621052004210020050d000b0b02402004a7220541e3004c0d00200241096a2003417e6a22036a2004a7220641ffff037141e4006e2205419c7f6c20066a41ffff037141017441ca82c0006a2f00003b00000b024002402005410a480d00200241096a2003417e6a22036a200541017441ca82c0006a2f00003b00000c010b200241096a2003417f6a22036a200541306a3a00000b200141c4b8c6004100200241096a20036a412720036b103c2103200241306a240020030b6f01017f230041c0006b220124002001200036020c200141346a410136020020014201370224200141b4b8c6003602202001410536023c2001200141386a36023020012001410c6a360238200141106a200141206a102c410141bcb8c60041072001280210200128021810d90400000b0d0042e7d9f4a2e3fcafadee000bc50501067f20002802002205410171220620046a21070240024020054104710d00410021010c010b4100210802402002450d00200221092001210a03402008200a2d000041c00171418001466a2108200a41016a210a2009417f6a22090d000b0b200720026a20086b21070b412b418080c40020061b21080240024020002802084101460d004101210a2000200820012002103d0d012000280218200320042000411c6a28020028020c1100000f0b02402000410c6a280200220920074b0d004101210a2000200820012002103d0d012000280218200320042000411c6a28020028020c1100000f0b0240024020054108710d00200920076b21094100210a024002400240410120002d0030220720074103461b0e0402000100020b2009210a410021090c010b2009410176210a200941016a41017621090b200a41016a210a0340200a417f6a220a450d0220002802182000280204200028021c280210110100450d000b41010f0b4101210a200041013a0030200041303602042000200820012002103d0d01200920076b21084100210a024002400240410120002d0030220920094103461b0e0402000100020b2008210a410021080c010b2008410176210a200841016a41017621080b200a41016a210a02400340200a417f6a220a450d0120002802182000280204200028021c280210110100450d000b41010f0b200028020421094101210a200028021820032004200028021c28020c1100000d01200841016a2108200028021c210220002802182100034002402008417f6a22080d0041000f0b4101210a200020092002280210110100450d000c020b0b200028020421074101210a2000200820012002103d0d00200028021820032004200028021c28020c1100000d00200941016a2108200028021c210920002802182100034002402008417f6a22080d0041000f0b4101210a200020072009280210110100450d000b0b200a0b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101101000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11000021040b20040b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c200241dc84c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41ec84c0001038000b8307010c7f200028021021030240024002400240200028020822044101460d0020030d012000280218200120022000411c6a28020028020c11000021030c030b2003450d010b0240024020020d00410021020c010b200120026a2105200041146a28020041016a21064100210720012103200121080340200341016a210902400240024020032c0000220a417f4a0d000240024020092005470d004100210b200521030c010b20032d0001413f71210b200341026a220921030b200a411f71210c0240200a41ff0171220a41df014b0d00200b200c41067472210a0c020b0240024020032005470d004100210d2005210e0c010b20032d0000413f71210d200341016a2209210e0b200d200b41067472210b0240200a41f0014f0d00200b200c410c7472210a0c020b02400240200e2005470d004100210a200921030c010b200e41016a2103200e2d0000413f71210a0b200b410674200c411274418080f0007172200a72220a418080c400470d020c040b200a41ff0171210a0b200921030b02402006417f6a2206450d00200720086b20036a21072003210820052003470d010c020b0b200a418080c400460d00024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20040d002000280218200120022000411c6a28020028020c1100000f0b4100210902402002450d002002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b0240200220096b200028020c2206490d002000280218200120022000411c6a28020028020c1100000f0b410021074100210902402002450d00410021092002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b200920026b20066a210a024002400240410020002d0030220320034103461b0e0402000100020b200a21074100210a0c010b200a4101762107200a41016a410176210a0b200741016a2103024003402003417f6a2203450d0120002802182000280204200028021c280210110100450d000b41010f0b2000280204210941012103200028021820012002200028021c28020c1100000d00200a41016a2103200028021c210a20002802182100034002402003417f6a22030d0041000f0b20002009200a280210110100450d000b41010f0b20030bcd0801067f230041f0006b220424002004200336020c20042002360208410121052001210602402001418102490d00410020016b2107418002210803400240200820014f0d00200020086a2c000041bf7f4c0d0041002105200821060c020b2008417f6a21064100210520084101460d01200720086a21092006210820094101470d000b0b200420063602142004200036021020044100410520051b36021c200441c4b8c60041a285c00020051b3602180240024002400240200220014b22080d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200420023602202002450d0220022001460d02200141016a210903400240200220014f0d00200020026a2c000041404e0d040b2002417f6a210820024101460d0420092002462106200821022006450d000c040b0b20042002200320081b360228200441306a41146a4103360200200441c8006a41146a4104360200200441d4006a410436020020044203370234200441a885c0003602302004410136024c2004200441c8006a3602402004200441186a3602582004200441106a3602502004200441286a360248200441306a41c085c0001038000b200441e4006a4104360200200441c8006a41146a4104360200200441d4006a4101360200200441306a41146a410436020020044204370234200441d085c0003602302004410136024c2004200441c8006a3602402004200441186a3602602004200441106a36025820042004410c6a3602502004200441086a360248200441306a41f085c0001038000b200221080b024020082001460d00410121060240024002400240200020086a22092c00002202417f4a0d0041002105200020016a220621010240200941016a2006460d00200941026a210120092d0001413f7121050b2002411f712109200241ff017141df014b0d01200520094106747221010c020b2004200241ff0171360224200441286a21020c020b4100210020062107024020012006460d00200141016a210720012d0000413f7121000b200020054106747221010240200241ff017141f0014f0d0020012009410c747221010c010b41002102024020072006460d0020072d0000413f7121020b20014106742009411274418080f00071722002722201418080c400460d020b2004200136022441012106200441286a21022001418001490d00410221062001418010490d0041034104200141808004491b21060b200420083602282004200620086a36022c200441306a41146a4105360200200441ec006a4104360200200441e4006a4104360200200441c8006a41146a4106360200200441d4006a4107360200200442053702342004419886c000360230200420023602582004410136024c2004200441c8006a3602402004200441186a3602682004200441106a3602602004200441246a3602502004200441206a360248200441306a41c086c0001038000b418086c000102b000b1000200120002802002000280204103f0b6f01037f230041206b2202240002402000280200200110450d002001411c6a280200210320012802182104200242043703182002420137020c200241a887c00036020820042003200241086a102e0d002000280204200110452101200241206a240020010f0b200241206a240041010bd90a02077f017e410121020240200128021841272001411c6a2802002802101101000d0041022103024002400240024002402000280200220241776a2200411e4d0d00200241dc00470d010c020b41f40021040240024020000e1f05010202000202020202020202020202020202020202020202030202020203050b41f20021040c040b41ee0021040c030b0240024002400240024002400240200210440d00024002400240024002400240200241808004490d00200241808008490d0120024190fc476a4190fc0b490d0a200241e28b746a41e28d2c490d0a2002419fa8746a419f18490d0a200241dee2746a410e490d0a200241feffff0071419ef00a460d0a200241a9b2756a4129490d0a200241cb91756a410a4d0d0a410121030c0e0b20024180fe0371410876210541e093c000210041002106200241ff017121040340200041026a2107200620002d000122036a2108024020002d000022002005460d00200020054b0d092008210620072100200741b294c000470d010c090b20082006490d02200841a5024b0d03200641b294c0006a2100024003402003450d012003417f6a210320002d00002106200041016a210020062004470d000c0c0b0b2008210620072100200741b294c000470d000c080b0b20024180fe03714108762105419199c000210041002106200241ff017121040340200041026a2107200620002d000122036a2108024020002d000022002005460d00200020054b0d072008210620072100200741d799c000470d010c070b20082006490d03200841a6014b0d04200641d799c0006a2100024003402003450d012003417f6a210320002d00002106200041016a210020062004470d000c0b0b0b2008210620072100200741d799c000470d000c060b0b20062008103e000b200841a5021036000b20062008103e000b200841a6011036000b200241017267410276410773ad4280808080d0008421090c040b200241ffff0371210441fd9ac00021034101210002400340200341016a21080240024020032d0000220641187441187522074100480d00200821030c010b200841959ec000460d02200741ff007141087420032d0001722106200341026a21030b200420066b22044100480d0320004101732100200341959ec000470d000c030b0b418086c000102b000b200241ffff0371210441d796c0002103410121000340200341016a21080240024020032d0000220641187441187522074100480d00200821030c010b2008419199c000460d05200741ff007141087420032d0001722106200341026a21030b200420066b22044100480d01200041017321002003419199c000470d000b0b4101210320004101710d030b200241017267410276410773ad4280808080d0008421090b410321030c020b418086c000102b000b0b200221040b03402003210641dc0021004101210241012103024002400240024020060e0401020300010b024002400240024002402009422088a741ff01710e06050403020100050b200942ffffffff8f60834280808080c000842109410321030c060b200942ffffffff8f608342808080803084210941f5002100410321030c050b200942ffffffff8f608342808080802084210941fb002100410321030c040b20042009a72206410274411c7176410f712203413072200341d7006a2003410a491b210002402006450d002009427f7c42ffffffff0f83200942808080807083842109410321030c040b200942ffffffff8f6083428080808010842109410321030c030b200942ffffffff8f6083210941fd002100410321030c020b20012802184127200128021c2802101101000f0b41002103200421000b20012802182000200128021c280210110100450d000b0b20020b950201017f024002402000418010490d00024002400240024002400240200041808004490d002000410c7641706a2201418002490d0141b89ec0002001418002102d000b200041067641606a220141df074b0d01200141808ac0006a2d0000220141c9004b0d02200141037441909fc0006a21010c060b200141e091c0006a2d00004106742000410676413f7172220141ff034b0d02200141e0a3c0006a2d0000220141394b0d03200141037441e0a7c0006a21010c050b41989ec000200141e007102d000b41a89ec000200141ca00102d000b41c89ec0002001418004102d000b41d89ec0002001413a102d000b200041037641f8ffffff017141e887c0006a21010b200129030042012000413f71ad86834200520b9b0201037f23004180016b2202240002400240024002400240200128020022034110710d0020034120710d012000ad2001103921000c020b410021030340200220036a41ff006a2000410f712204413072200441d7006a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d02200141a085c0004102200220036a4180016a410020036b103c21000c010b410021030340200220036a41ff006a2000410f712204413072200441376a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d02200141a085c0004102200220036a4180016a410020036b103c21000b20024180016a240020000f0b2000418001103e000b2000418001103e000b0b002000350200200110390b1c00200128021841a8acc000410b2001411c6a28020028020c1100000b1c00200128021841b3acc000410e2001411c6a28020028020c1100000b15002001200028020022002802002000280204103f0b5e01017f230041306b220224002002200136020c20022000360208200241246a410136020020024201370214200241b4b8c6003602102002410436022c2002200241286a3602202002200241086a360228200241106a4180adc0001038000b140020002802002001200028020428020c1101000bf30201067f410021040240024020024103712205450d00410420056b2205450d0020032005200520034b1b210441002105200141ff01712106034020042005460d01200220056a2107200541016a210520072d000022072006470d000b410121032007200141ff01714641016a41017120056a417f6a21050c010b200141ff017121060240024020034108490d002004200341786a22084b0d00200641818284086c210502400340200220046a220741046a2802002005732209417f73200941fffdfb776a7120072802002005732207417f73200741fffdfb776a7172418081828478710d01200441086a220420084d0d000b0b200420034b0d010b200220046a2109200320046b210241002103410021050240034020022005460d01200920056a2107200541016a210520072d000022072006470d000b410121032007200141ff01714641016a41017120056a417f6a21050b200520046a21050c010b20042003103e000b20002005360204200020033602000b2601017f200028020022012802002001280204200028020428020020002802082802001040000b0b002000310000200110390b02000ba20401077f230041306b220324000240024020020d00410021040c010b200341286a210502400240024002400340024020002802082d0000450d00200028020041ecadc0004104200028020428020c1100000d050b2003410a3602282003428a808080103703202003200236021c200341003602182003200236021420032001360210200341086a410a20012002104c024002400240024020032802084101470d00200328020c210403402003200420032802186a41016a2204360218024002402004200328022422064f0d00200328021421070c010b200328021422072004490d00200641054f0d072003280210200420066b22086a22092005460d0420092005200610de04450d040b200328021c22092004490d0220072009490d0220032006200341106a6a41176a2d0000200328021020046a200920046b104c2003280204210420032802004101460d000b0b2003200328021c3602180b200028020841003a0000200221040c010b200028020841013a0000200841016a21040b2000280204210920002802002106024020044520022004467222070d00200220044d0d03200120046a2c000041bf7f4c0d030b200620012004200928020c1100000d04024020070d00200220044d0d04200120046a2c000041bf7f4c0d040b200120046a2101200220046b22020d000b410021040c040b200641041036000b20012002410020041040000b20012002200420021040000b410121040b200341306a240020040bf90101017f230041106b220224002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110502101200241106a240020010b6001017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41d4adc000200241086a102e2101200241206a240020010b0d0020002802002001200210500b800201017f230041106b22022400200028020021002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110502101200241106a240020010b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41d4adc000200241086a102e2101200241206a240020010bf40202037f057e230041d0006b2203240041012104024020002d00040d0020002d000521040240200028020022052d00004104710d000240200441ff0171450d0041012104200528021841d2adc00041022005411c6a28020028020c1100000d02200028020021050b20012005200228020c11010021040c010b0240200441ff01710d0041012104200528021841b7adc00041012005411c6a28020028020c1100000d01200028020021050b41012104200341013a00172003200341176a3602102005290208210620052902102107200341346a41b8adc000360200200320052902183703082005290220210820052902282109200320052d00303a00482005290200210a200320093703402003200837033820032007370328200320063703202003200a3703182003200341086a3602302001200341186a200228020c1101000d00200328023041d0adc0004102200328023428020c11000021040b200041013a0005200020043a0004200341d0006a240020000b6401027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a102e2100200241206a240020000bb50f020d7f017e230041206b220324004101210402400240200228021841222002411c6a2802002802101101000d000240024020010d00410021050c010b200020016a21062000210741002105410021080240034020072109200741016a210a02400240024020072c0000220b417f4a0d0002400240200a2006470d004100210c200621070c010b20072d0001413f71210c200741026a220a21070b200b411f7121040240200b41ff0171220b41df014b0d00200c200441067472210b0c020b0240024020072006470d004100210d2006210e0c010b20072d0000413f71210d200741016a220a210e0b200d200c41067472210c0240200b41f0014f0d00200c2004410c7472210b0c020b02400240200e2006470d004100210b200a21070c010b200e41016a2107200e2d0000413f71210b0b200c4106742004411274418080f0007172200b72220b418080c400470d020c040b200b41ff0171210b0b200a21070b4102210a024002400240024002400240200b41776a220c411e4d0d00200b41dc00470d010c020b41f400210e02400240200c0e1f05010202000202020202020202020202020202020202020202030202020203050b41f200210e0c040b41ee00210e0c030b02400240200b10440d00024002400240024002400240024002400240200b41808004490d00200b41808008490d01200b4190fc476a4190fc0b490d09200b41e28b746a41e28d2c490d09200b419fa8746a419f18490d09200b41dee2746a410e490d09200b41feffff0071419ef00a460d09200b41a9b2756a4129490d09200b41cb91756a410a4d0d090c0e0b200b4180fe0371410876210f41e093c000210c410021040340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d08200e2104200d210c200d41b294c000470d010c080b200e2004490d02200e41a5024b0d03200441b294c0006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c0b0b0b200e2104200d210c200d41b294c000470d000c070b0b200b4180fe0371410876210f419199c000210c410021040340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d06200e2104200d210c200d41d799c000470d010c060b200e2004490d03200e41a6014b0d04200441d799c0006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c0a0b0b200e2104200d210c200d41d799c000470d000c050b0b2004200e103e000b200e41a5021036000b2004200e103e000b200e41a6011036000b200b41ffff0371210e41fd9ac000210a4101210c02400340200a41016a210d02400240200a2d00002204411874411875220f4100480d00200d210a0c010b200d41959ec000460d02200f41ff0071410874200a2d0001722104200a41026a210a0b200e20046b220e4100480d03200c410173210c200a41959ec000470d000c030b0b418086c000102b000b200b41ffff0371210e41d796c000210a4101210c0340200a41016a210d02400240200a2d00002204411874411875220f4100480d00200d210a0c010b200d419199c000460d04200f41ff0071410874200a2d0001722104200a41026a210a0b200e20046b220e4100480d01200c410173210c200a419199c000470d000b0b200c4101710d050b200b41017267410276410773ad4280808080d0008421104103210a0c020b418086c000102b000b0b200b210e0b2003200136020420032000360200200320053602082003200836020c0240024020082005490d0002402005450d0020052001460d00200520014f0d01200020056a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020056a200820056b200228021c28020c110000450d01410121040c060b20032003410c6a3602182003200341086a36021420032003360210200341106a104d000b0340200a210c4101210441dc0021054101210a024002400240024002400240200c0e0402010500020b02400240024002402010422088a741ff01710e06050302010006050b201042ffffffff8f60834280808080308421104103210a41f50021050c070b201042ffffffff8f60834280808080208421104103210a41fb0021050c060b200e2010a7220c410274411c7176410f71220a413072200a41d7006a200a410a491b21050240200c450d002010427f7c42ffffffff0f832010428080808070838421100c050b201042ffffffff8f60834280808080108421100c040b201042ffffffff8f608321104103210a41fd0021050c040b4100210a200e21050c030b4101210a0240200b418001490d004102210a200b418010490d0041034104200b41808004491b210a0b200a20086a21050c040b201042ffffffff8f60834280808080c0008421100b4103210a0b20022802182005200228021c2802101101000d050c000b0b200820096b20076a210820062007470d000b0b2005450d0020052001460d00200520014f0d02200020056a2c000041bf7f4c0d020b410121042002280218200020056a200120056b200228021c28020c1100000d0020022802184122200228021c28021011010021040b200341206a240020040f0b20002001200520011040000b8b0101037f23004180016b2202240020002802002103410021000340200220006a41ff006a2003410f712204413072200441376a2004410a491b3a00002000417f6a2100200341047622030d000b024020004180016a2203418101490d002003418001103e000b200141a085c0004102200220006a4180016a410020006b103c210020024180016a240020000b1c00200128021841b1bac00041052001411c6a28020028020c1100000b800401087f200028020421020240024002400240024020002802004101460d00200041086a28020022002001105c20004103742200450d01200220006a2103200141086a2104034020022802002105200241046a28020022002001105c02400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d06200741017422082009200820094b1b22084100480d060240024020070d002008102121070c010b200128020020072008102521070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a2005200010dc041a200241086a22022003470d000c020b0b2000410c6a28020022002001105c20004103742200450d00200220006a2103200141086a2104034020022802002105200241046a28020022002001105c02400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d05200741017422082009200820094b1b22084100480d050240024020070d002008102121070c010b200128020020072008102521070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a2005200010dc041a200241086a22022003470d000b0b0f0b200841011030000b200841011030000b102a000b920701037f0240024002400240024002402000413f4b0d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d06200241017422042003200420034b1b22044100480d060240024020020d002004102121030c010b200128020020022004102521030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20004102743a00000f0b200041808001490d032000418080808004490d020c010b200441011030000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d05200241017422042003200420034b1b22044100480d050240024020020d002004102121030c010b200128020020022004102521030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a000002400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d05200341017422022004200220044b1b22024100480d050240024020030d002002102121030c010b200128020020032002102521030b2003450d0220012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20003600000f0b200441011030000b200241011030000b024002400240200141046a2802002203200141086a28020022026b4104490d00200128020021030c010b200241046a22042002490d03200341017422022004200220044b1b22024100480d030240024020030d002002102121030c010b200128020020032002102521030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20004102744102723600000f0b200241011030000b024002400240200141046a2802002203200141086a28020022026b4102490d00200128020021030c010b200241026a22042002490d02200341017422022004200220044b1b22024100480d020240024020030d002002102121030c010b200128020020032002102521030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241026a360200200320026a20004102744101723b00000f0b200241011030000b102a000b951d010a7f230041106b2203240020012002105c024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d00200141d8006c2104410021050340200020056a220641046a2802002107200641086a28020022082002105c02400240200241046a2209280200220a200241086a2201280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d18200a410174220b200c200b200c4b1b220b4100480d1802400240200a0d00200b1021210a0c010b2002280200200a200b1025210a0b200a450d032002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810dc041a200641d4006a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1820084101742207200b2007200b4b1b22074100480d180240024020080d0020071021210b0c010b2002280200200820071025210b0b200b450d042002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a000002402006410c6a2d0000220841024b0d0002400240024020080e03000102000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200a200b4b1b220a4100480d1b0240024020080d00200a1021210b0c010b20022802002008200a1025210b0b200b450d082002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a0000200641146a2802002107200641186a28020022082002105c024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1b200a410174220b200c200b200c4b1b220b4100480d1b02400240200a0d00200b1021210a0c010b2002280200200a200b1025210a0b200a450d092002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810dc041a0c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200a200b4b1b220a4100480d1a0240024020080d00200a1021210b0c010b20022802002008200a1025210b0b200b450d092002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a20084101742207200b2007200b4b1b22074100480d1a0240024020080d0020071021210b0c010b2002280200200820071025210b0b200b450d0a2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a28020022082002105c024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200b200c4b1b220b4100480d1a02400240200a0d00200b1021210a0c010b2002280200200a200b1025210a0b200a450d0b2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810dc041a200641206a2802002107200641246a28020022082002105c024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200b200c4b1b220b4100480d1a02400240200a0d00200b1021210a0c010b2002280200200a200b1025210a0b200a450d0c2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810dc041a2006410e6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a20084101742207200b2007200b4b1b22074100480d1a0240024020080d0020071021210b0c010b2002280200200820071025210b0b200b450d0d2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200a200b4b1b220a4100480d190240024020080d00200a1021210b0c010b20022802002008200a1025210b0b200b450d0d2002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1920084101742207200b2007200b4b1b22074100480d190240024020080d0020071021210b0c010b2002280200200820071025210b0b200b450d0e2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a28020022082002105c024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1021210a0c010b2002280200200a200b1025210a0b200a450d0f2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810dc041a200641206a2802002107200641246a28020022082002105c024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1021210a0c010b2002280200200a200b1025210a0b200a450d102002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810dc041a2006412c6a2802002107200641306a28020022082002105c024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1021210a0c010b2002280200200a200b1025210a0b200a450d112002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810dc041a2006410e6a2d0000220841044b0d000240024002400240024020080e050001020304000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1d2008410174220a200b200a200b4b1b220a4100480d1d0240024020080d00200a1021210b0c010b20022802002008200a1025210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a00000c040b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1c2008410174220a200b200a200b4b1b220a4100480d1c0240024020080d00200a1021210b0c010b20022802002008200a1025210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00000c030b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200a200b4b1b220a4100480d1b0240024020080d00200a1021210b0c010b20022802002008200a1025210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00000c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200a200b4b1b220a4100480d1a0240024020080d00200a1021210b0c010b20022802002008200a1025210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41033a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200a200b4b1b220a4100480d190240024020080d00200a1021210b0c010b20022802002008200a1025210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41043a00000b02400240200641346a2802004101460d002003200641386a2802002006413c6a28020028020c11020020032802002107200328020822082002105c024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200b200c4b1b220b4100480d1a02400240200a0d00200b1021210a0c010b2002280200200a200b1025210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810dc041a2003280204450d01200710230c010b200641386a2802002107200641c0006a28020022082002105c024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1021210a0c010b2002280200200a200b1025210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810dc041a0b200641c4006a2002105b2004200541d8006a2205470d000b0b200341106a24000f0b200b41011030000b200741011030000b200a41011030000b200b41011030000b200a41011030000b200741011030000b200b41011030000b200b41011030000b200741011030000b200a41011030000b200741011030000b200b41011030000b200b41011030000b200b41011030000b200a41011030000b200a41011030000b200a41011030000b200a41011030000b200a41011030000b200b41011030000b200b41011030000b102a000bfe0601087f20002802042102024002400240024002400240024020002802004101460d00200041086a28020022002001105c2000450d01200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a28020022062001105c0240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d08200741017422082009200820094b1b22084100480d080240024020070d002008102121070c010b200128020020072008102521070b2007450d042001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610dc041a2000417c6a2802002105200028020022062001105c0240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d08200741017422082009200820094b1b22084100480d080240024020070d002008102121070c010b200128020020072008102521070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610dc041a200041186a2100200341686a22030d000c020b0b2000410c6a28020022002001105c2000450d00200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a28020022062001105c0240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d07200741017422082009200820094b1b22084100480d070240024020070d002008102121070c010b200128020020072008102521070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610dc041a2000417c6a2802002105200028020022062001105c0240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d07200741017422082009200820094b1b22084100480d070240024020070d002008102121070c010b200128020020072008102521070b2007450d062001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610dc041a200041186a2100200341686a22030d000b0b0f0b200841011030000b200841011030000b200841011030000b200841011030000b102a000b040041010bb60101017f230041c0006b2202240020024100360210200242013703082002410836021c20022001410c6a3602202002200241206a3602182002200241086a3602242002413c6a41013602002002420137022c200241b4b8c6003602282002200241186a360238200241246a4188aec000200241286a102e1a20012d0000417f6a41ff0171200141046a290200200235021042208620023502088410000240200228020c450d00200228020810230b200241c0006a24000b6901037f230041206b220224002001411c6a280200210320012802182104200241086a41106a2000280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a102e2101200241206a240020010bc00101037f02400240024002402000280200220041046a2802002203200041086a28020022046b2002490d00200028020021030c010b200420026a22052004490d02200341017422042005200420054b1b22044100480d020240024020030d002004102121030c010b200028020020032004102521030b2003450d0120002003360200200041046a2004360200200041086a28020021040b200041086a200420026a360200200320046a2001200210dc041a41000f0b200441011030000b102a000bab0301047f230041106b22022400200028020021002002410036020c02400240200141ff004b0d00200220013a000c410121010c010b0240200141ff0f4b0d0020022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b0240200141ffff034b0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b0240024002400240200041046a2802002203200041086a28020022046b2001490d00200028020021030c010b200420016a22052004490d02200341017422042005200420054b1b22044100480d020240024020030d002004102121030c010b200028020020032004102521030b2003450d0120002003360200200041046a2004360200200041086a28020021040b200041086a200420016a360200200320046a2002410c6a200110dc041a200241106a240041000f0b200441011030000b102a000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a4188aec000200241086a102e2101200241206a240020010b040041000b02000b02000bf00101067f2001280204210202400240024003402001280200220341086a210420032f01062205410374210141002106024003402001450d0141d8b9c0002004410810de042207450d03200141786a2101200641016a2106200441086a21042007417f4a0d000b2006417f6a21050b02402002450d002002417f6a2102200320054102746a41e4016a21010c010b0b200041e0b9c000360204200041086a41283602000c010b200341e0006a2006410c6c6a220128020841074b0d0120004188bac000360204200041086a41293602000b200041013602000f0b200041086a2001280200290000370300200041003602000bd40201027f0240024002402002450d002002417f6a2104024020012d0000220241037122054103460d000240024020050e03040001040b2004450d0220012d0001410874200272220241ffff0371418002490d02200241fcff037141027621020c040b20044103490d0120012f0001200141036a2d000041107472410874200272220241808004490d01200241027621020c030b200241034b0d0020044104490d002001280001220241ffffffff034b0d020b200041013602000f0b200241027621020b0240200220036a220120024f0d00200041013602000f0b41012103410121050240200241c000490d0041022105200241808001490d00410441052002418080808004491b21050b0240200141c000490d0041022103200141808001490d00410441052001418080808004491b21030b20002001360204200041003602002000410c6a2003360200200041086a20053602000bc43102077f027e230041306b220224002002410036021820024201370310200128021021030240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410410212204450d0020024284808080c000370214200220043602102004200336000020012d0038210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0220022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0039210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0320022006360214200220033602100b2002200441016a360218200320046a20053a000020012d003a210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0420022006360214200220033602100b2002200441016a360218200320046a20053a000020012d003b210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0520022006360214200220033602100b2002200441016a360218200320046a20053a000020012d003c210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0620022006360214200220033602100b2002200441016a360218200320046a20053a000020012d003d210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0720022006360214200220033602100b2002200441016a360218200320046a20053a000020012d003e210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0820022006360214200220033602100b2002200441016a360218200320046a20053a000020012d003f210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0920022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0040210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0a20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0041210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0b20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0042210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0c20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0043210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0d20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0044210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0e20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0045210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d0f20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0046210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1020022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0047210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1120022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0048210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1220022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0049210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1320022006360214200220033602100b2002200441016a360218200320046a20053a000020012d004a210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1420022006360214200220033602100b2002200441016a360218200320046a20053a000020012d004b210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1520022006360214200220033602100b2002200441016a360218200320046a20053a000020012d004c210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1620022006360214200220033602100b2002200441016a360218200320046a20053a000020012d004d210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1720022006360214200220033602100b2002200441016a360218200320046a20053a000020012d004e210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1820022006360214200220033602100b2002200441016a360218200320046a20053a000020012d004f210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1920022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0050210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1a20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0051210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1b20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0052210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1c20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0053210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1d20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0054210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1e20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0055210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d1f20022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0056210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d2020022006360214200220033602100b2002200441016a360218200320046a20053a000020012d0057210502400240200228021420022802182204460d00200228021021030c010b200441016a22032004490d28200441017422062003200620034b1b22064100480d280240024020040d002006102121030c010b200228021020042006102521030b2003450d2120022006360214200220033602100b2002200441016a360218200320046a20053a0000200141d8006a2107410021030340200720036a2d0000210602400240200228021420022802182204460d00200228021021050c010b200441016a22052004490d29200441017422082005200820054b1b22084100480d290240024020040d002008102121050c010b200228021020042008102521050b2005450d2320022008360214200220053602100b2002200441016a360218200520046a20063a0000200341016a220341c000470d000b200128021421062001411c6a2802002204200241106a105c0240024020022802142205200228021822036b2004490d00200228021021050c010b200320046a22082003490d28200541017422072008200720084b1b22084100480d280240024020050d002008102121050c010b200228021020052008102521050b2005450d2320022008360214200220053602100b2002200320046a360218200520036a2006200410dc041a20012802202103200141286a2802002204200241106a105c02402004450d002003200441246c6a21070340200328020021060240024020022802142205200228021822046b4104490d00200228021021050c010b200441046a22082004490d2a200541017422042008200420084b1b22044100480d2a0240024020050d002004102121050c010b200228021020052004102521050b2005450d262002200436021420022005360210200228021821040b2002200441046a360218200520046a20063600002002200241106a36020c200341046a2002410c6a106b200341246a22032007470d000b0b200141086a29030021092001290300210a0240024020022802142203200228021822046b4110490d00200228021021030c010b200441106a22052004490d28200341017422042005200420054b1b22044100480d280240024020030d002004102121030c010b200228021020032004102521030b2003450d252002200436021420022003360210200228021821040b200320046a220320093700082003200a3700002002200441106a3602182002200241106a36020c20014198016a2002410c6a106b200128022c2104200141346a2802002203200241106a105c02402003450d0020034104742108034002402004410c6a2d000022034103714103460d004100210602400240024020030e03020001020b410121060c010b410221060b02400240200228021420022802182203460d00200228021021050c010b200341016a22052003490d2b200341017422012005200120054b1b22014100480d2b0240024020030d002001102121050c010b200228021020032001102521050b2005450d292002200136021420022005360210200228021821030b2002200341016a360218200520036a20063a00000b20042802002101200441086a2802002203200241106a105c0240024020022802142206200228021822056b2003490d00200228021021060c010b200520036a22072005490d2a200641017422052007200520074b1b22054100480d2a0240024020060d002005102121060c010b200228021020062005102521060b2006450d292002200536021420022006360210200228021821050b200441106a21042002200520036a360218200620056a2001200310dc041a200841706a22080d000b0b20022802142103200241106a41186a2205200235021842208620022802102201ad841001220441186a290000370300200241106a41106a2206200441106a290000370300200241106a41086a2208200441086a2900003703002002200429000037031020041023200041186a2005290300370000200041106a2006290300370000200041086a20082903003700002000200229031037000002402003450d00200110230b200241306a24000f0b410441011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200841011030000b200841011030000b200441011030000b200441011030000b200141011030000b200541011030000b102a000bd20501037f20002d0000210202400240024002400240024002400240410110212203450d00200320023a000020002d0001210220034101410210252203450d01200320023a000120002d0002210220034102410410252203450d02200320023a0002200320002d00033a000320002d0004210220034104410810252203450d03200320023a0004200320002d00053a0005200320002d00063a0006200320002d00073a000720002d0008210220034108411010252203450d04200320023a0008200320002d00093a0009200320002d000a3a000a200320002d000b3a000b200320002d000c3a000c200320002d000d3a000d200320002d000e3a000e200320002d000f3a000f20002d0010210220034110412010252203450d05200320023a0010200320002d00113a0011200320002d00123a0012200320002d00133a0013200320002d00143a0014200320002d00153a0015200320002d00163a0016200320002d00173a0017200320002d00183a0018200320002d00193a0019200320002d001a3a001a200320002d001b3a001b200320002d001c3a001c200320002d001d3a001d200320002d001e3a001e200320002d001f3a001f024002402001280200220041046a2802002202200041086a28020022016b4120490d00200028020021020c010b200141206a22042001490d08200241017422012004200120044b1b22014100480d080240024020020d002001102121020c010b200028020020022001102521020b2002450d0720002002360200200041046a2001360200200041086a28020021010b200041086a200141206a360200200220016a220041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a29000037000020002003290000370000200310230f0b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000b200141011030000b102a000bce0101027f0240200041186a280200450d00200028021410230b0240200041246a280200450d00200028022010230b0240200041346a2802002201450d00200028022c21022001410474210103400240200241046a280200450d00200228020010230b200241106a2102200141706a22010d000b0b0240200041306a280200450d00200028022c10230b0240200041bc016a280200450d0020002802b80110230b200041c8016a410036020020002802c4012102200041013602c4010240200041cc016a280200450d00200210230b0bb005020c7f047e230041f0006b2202240020022001106e0240024002400240024020022802000d00200128020441286e220341286c2204417f4c0d02200228020421050240024020040d00410821060c010b200410212206450d040b02402005450d00410021070340200241003a00682007220841016a210720012802042109417f210a410021040240024002400240034020092004460d01200241c8006a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a0068200a417f6a210a200c2104200c4120470d000b200241286a41186a2204200241c8006a41186a290300370300200241286a41106a220a200241c8006a41106a290300370300200241286a41086a220d200241c8006a41086a290300370300200220022903483703282009200c6b220c4108490d01200b290001210e2001200b41096a3602002001200c41786a360204200241086a41086a220c200d290300370300200241086a41106a2209200a290300370300200241086a41186a220a20042903003703002002200229032837030820032008470d030240200841017422042007200420074b1b2203ad42287e220f422088a70d00200fa7220441004e0d030b102a000b200441ff0171450d00200241003a00680b200041003602002003450d05200610230c050b0240024020080d002004102121060c010b2006200841286c2004102521060b2006450d070b2006200841286c6a22042002290308370300200c290300210f20092903002110200a29030021112004200e370320200441186a2011370300200441106a2010370300200441086a200f37030020072005470d000b0b2000200336020420002006360200200041086a20053602000c010b200041003602000b200241f0006a24000f0b102f000b200441081030000b200441081030000bcf0201067f0240024020012802042202450d00200128020022032d0000210420012002417f6a2205360204410121062001200341016a3602000240200441037122074103460d0002400240024020070e03000102000b20044102762107410021060c040b41012106024020050d000c040b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d03200141fcff03714102762107410021060c030b20054103490d01200341036a2d0000210620032f0001210720012002417c6a3602042001200341046a3602002007200641107472410874200472220141808004492106200141027621070c020b0240200441034d0d000c020b20054104490d012003280001210720012002417b6a3602042001200341056a36020020074180808080044921060c010b410121060b20002007360204200020063602000b960301097f230041106b2202240002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002006450d0020042d0001210720012003417e6a22063602042001200441026a3602002006450d0020042d0002210820012003417d6a22063602042001200441036a3602002006450d0020042d0003210620012003417c6a3602042001200441046a360200200241086a2001106e20022802080d022001280204200228020c2204490d022004417f4c0d0302400240024020040d004101210341010d010c050b200410272203450d0120012802042004490d0320032001280200200410dc0421092001280204220a2004490d062001200a20046b3602042001200128020020046a3602002009450d040b20002004360208200020033602042000410c6a2004360200200020074108742005722008411074722006411874723602000c060b200441011030000b200041003602040c040b200310230b200041003602040c020b102f000b2004200a103e000b200241106a24000bdd0203037f017e027f230041106b22022400024002400240410110212203450d00200242818080801037020420022003360200200320002d00003a0000200028020422002802002103200028020822002002105c02402000450d002003200041286c6a21040340200320021071200341206a29030021050240024020022802042206200228020822006b4108490d00200228020021060c010b200041086a22072000490d05200641017422002007200020074b1b22004100480d050240024020060d002000102121060c010b200228020020062000102521060b2006450d042002200036020420022006360200200228020821000b2002200041086a360208200620006a20053700002004200341286a2203470d000b0b200228020421002001290200200235020842208620022802002203ad84100202402000450d00200310230b200241106a24000f0b410141011030000b200041011030000b102a000b952901067f20002d0000210202400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2203280200200141086a22042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0120012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0001210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0220012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0002210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0320012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0003210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0420012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0004210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0520012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0005210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0620012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0006210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0720012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0007210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0820012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0008210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0920012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0009210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0a20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000a210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0b20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000b210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0c20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000c210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0d20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000d210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0e20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000e210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0f20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000f210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1020012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0010210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1120012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0011210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1220012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0012210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1320012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0013210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1420012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0014210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1520012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0015210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1620012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0016210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1720012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0017210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1820012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0018210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1920012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0019210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1a20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001a210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1b20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001b210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1c20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001c210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1d20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001d210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1e20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001e210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1f20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001f210502400240200328020020042802002200460d00200128020021030c010b200041016a22032000490d21200041017422062003200620034b1b22064100480d210240024020000d002006102121030c010b200128020020002006102521030b2003450d2020012003360200200141046a2006360200200141086a28020021000b2004200041016a360200200320006a20053a00000f0b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200641011030000b102a000bd70302077f027e230041106b22022400024002400240024002402000280208220341146a2204417f4c0d000240024020040d00410121050c010b200410212205450d02200028020821030b2002410036020820022004360204200220053602002000280200210620032002105c0240024020022802042205200228020822076b2003490d00200228020021040c010b200720036a22042007490d05200541017422082004200820044b1b22084100480d050240024020050d002008102121040c010b200228020020052008102521040b2004450d032002200836020420022004360200200821050b2002200720036a2208360208200420076a2006200310dc041a200041186a29030021092000290310210a02400240200520086b4110490d00200841106a21030c010b200841106a22032008490d05200541017422002003200020034b1b22004100480d050240024020050d002000102121040c010b200420052000102521040b2004450d042002200036020420022004360200200021050b200420086a220020093700082000200a37000020012902002003ad4220862004ad84100202402005450d00200410230b200241106a24000f0b102f000b200441011030000b200841011030000b200041011030000b102a000be80201087f230041106b220224002000280200210320002802082100200241003602082002420137030020002002105c0240024002402000450d0020032000410c6c6a2104034020032802002105200328020822002002105c02402000450d002005200041246c6a21060340200528020021070240024020022802042208200228020822006b4104490d00200228020021080c010b200041046a22092000490d06200841017422002009200020094b1b22004100480d060240024020080d002000102121080c010b200228020020082000102521080b2008450d052002200036020420022008360200200228020821000b2002200041046a360208200820006a2007360000200541046a20021071200541246a22052006470d000b0b2003410c6a22032004470d000b0b200228020421002001290200200235020842208620022802002205ad84100202402000450d00200510230b200241106a24000f0b200041011030000b102a000bbb03010b7f200041086a22022802002103410021042002410036020002402003450d00200128020421052001280200210641002107410021084100210441002101024003400240024002402004450d00200141246c21090340200120034f0d0220062802002000280200220a20096a220b280200220c460d032005280200200c460d030240200820016a220c20034f0d00200a20076a20096a220c200b290200370200200c41206a200b41206a280200360200200c41186a200b41186a290200370200200c41106a200b41106a290200370200200c41086a200b41086a290200370200200941246a2109200141016a22012003490d010c060b0b41c4bcc000200c2003102d000b2000280200200141246c6a210b0340200120034f0d012006280200200b280200220c460d022005280200200c460d02200b41246a210b200141016a22012003490d000b410021040c040b41f0bbc00020012003102d000b2007415c6a21072008417f6a2108200441016a2104200141016a22012003490d000b0b2004450d00200320014d0d002000280200200141246c6a220b410020046b41246c6a200b200320016b41246c10dd041a0b2002200320046b3602000b9d03010a7f200041086a220228020021034100210420024100360200024002402003450d00200128020021054100210641002107410021044100210102400340024002402004450d00200141246c21080340200120034f0d0620052802002000280200220920086a220a280200460d020240200720016a220b20034f0d00200920066a20086a2209200a290200370200200941206a200a41206a280200360200200941186a200a41186a290200370200200941106a200a41106a290200370200200941086a200a41086a290200370200200841246a2108200141016a22012003490d010c050b0b41c4bcc000200b2003102d000b2000280200200141246c6a210a0340200120034f0d052005280200200a280200460d01200a41246a210a200141016a22012003490d000b410021040c030b2006415c6a21062007417f6a2107200441016a2104200141016a22012003490d000b0b2004450d00200320014d0d002000280200200141246c6a220a410020046b41246c6a200a200320016b41246c10dd041a0b2002200320046b3602000f0b41f0bbc00020012003102d000b9203010a7f200041086a220228020021034100210420024100360200024002402003450d004100210541002106410021044100210702400340024002402004450d00200741057421080340200720034f0d062001200028020022096b2008460d02200920086a220a2001412010de04450d020240200620076a220b20034f0d00200920056a20086a2209200a290000370000200941186a200a41186a290000370000200941106a200a41106a290000370000200941086a200a41086a290000370000200841206a2108200741016a22072003490d010c050b0b41c4bcc000200b2003102d000b200028020020074105746a21080340200720034f0d0520012008460d0120082001412010de04450d01200841206a2108200741016a22072003490d000b410021040c030b200541606a21052006417f6a2106200441016a2104200741016a22072003490d000b0b2004450d00200320074d0d00200028020020074105746a220820044105746b2008200320076b41057410dd041a0b2002200320046b3602000f0b41f0bbc00020072003102d000bbd0101047f230041106b22022400200028020821032000280200210041012104200128021841b5adc00041012001411c6a28020028020c1100002105200241003a0005200220053a00042002200136020002402003450d0003402002200036020c20022002410c6a41a0bdc00010561a200041016a21002003417f6a22030d000b20022d000421050b0240200541ff01710d002002280200220028021841b6adc00041012000411c6a28020028020c11000021040b200241106a240020040b850505027f017e0a7f037e037f230041206b2202240002400240024020012802082203ad42d0007e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410821070c010b200510212207450d020b0240024020030d00410021080c010b2006200341d0006c6a2109410021082007210a0340200241186a220b200641186a290300370300200241106a220c200641106a290300370300200241086a220d200641086a29030037030020022006290300370300200641c8006a280200220ead42307e2204422088a70d022004a72205417f4c0d02200641386a2903002104200641306a290300210f200641286a2903002110200641c0006a2802002101200629032021110240024020050d00410821120c010b200510212212450d050b200641d0006a210602400240200e0d00410021130c010b2001200e41306c6a211441002113201221050340200520012903003703002005200141086a290300370308200541106a200141106a290300370300200541186a200141186a290300370300200541206a200141206a290300370300200541286a200141286a290300370300200541306a2105201341016a2113200141306a22012014470d000b0b200a2011370320200a2002290300370300200a41386a2004370300200a41306a200f370300200a41286a2010370300200a41c8006a2013360200200a41c4006a200e360200200a41c0006a2012360200200a41186a200b290300370300200a41106a200c290300370300200a41086a200d290300370300200841016a2108200a41d0006a210a20062009470d000b0b200020083602082000200336020420002007360200200241206a24000f0b102f000b200541081030000b200541081030000beb02010b7f230041106b220224000240024002402001280208220341ffffffff00712003470d0020034104742204417f4c0d00200128020021050240024020040d00410421060c010b200410212206450d020b0240024020030d00410021070c010b20034104742108410021072002410f6a21092006210103404102210a0240024002402005410c6a2d00004103710e03000102000b4100210a0c010b4101210a0b200541086a2802002204417f4c0d022005280200210b0240024020040d004101210c0c010b20041021220c450d050b200541106a2105200c200b200410dc04210b2001410c6a200a3a0000200141086a2004360200200141046a20043602002001200b3602002001410d6a20022f000d3b00002001410f6a20092d00003a0000200141106a2101200741016a2107200841706a22080d000b0b200020073602082000200336020420002006360200200241106a24000f0b102f000b200441041030000b200441011030000be70201037f024020002802082201450d002000280200220020014188016c6a21020340024020002d0000417c6a220141074b0d000240024002400240024020010e080005010203050504000b200041086a280200450d04200041046a28020010230c040b200041046a2802000d032000410c6a280200450d03200041086a28020010230c030b200041046a2d00004102490d020240200041106a2802002201450d00200141d0006c2103200041086a28020041c0006a210103400240200141046a280200450d00200128020010230b200141d0006a2101200341b07f6a22030d000b0b2000410c6a280200450d02200028020810230c020b200041086a2d00004101470d01200041146a280200450d01200041106a28020010230c010b200041046a2d00000d002000410c6a280200450d00200041086a28020010230b20004188016a21010240200041fc006a280200450d00200028027810230b2001210020012002470d000b0b0bf602010b7f230041106b22022400200241086a2001106e0240024002400240024020022802080d0020012802042203417c712204417f4c0d02200228020c210502400240200341027622060d00410421070c010b200410212207450d040b02402005450d0041002108410021094100210403400240024002402001280204220a4104490d00200441016a21032001280200220b280000210c2001200a417c6a3602042001200b41046a36020020042006470d02024020082003200820034b1b220641ffffffff03712006470d002006410274220a41004e0d020b102a000b200041003602002006450d05200710230c050b0240024020040d00200a102121070c010b20072009200a102521070b2007450d070b200720096a200c360200200841026a2108200941046a21092003210420052003470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241106a24000f0b102f000b200441041030000b200a41041030000b990a02137f017e230041e0006b22022400200241086a2001106e0240024020022802080d000240200128020441246e220341246c2204417f4c0d00200228020c210502400240024020040d00410421060c010b200410212206450d010b02400240024020050d00410021040c010b2002412d6a2107200241cb006a220841056a21094100210a4100210b0340024002402001280204220c450d002001280200220d2d000021042001200c417f6a220e3602042001200d41016a360200200441064b0d00024002400240024002400240024020040e0700070107030402000b20022001106e20022802000d0620012802042002280204220c490d06200c417f4c0d0c024002400240200c0d004101210441010d010c090b200c10272204450d012001280204200c490d0620042001280200200c10dc04210f2001280204220d200c490d072001200d200c6b36020420012001280200200c6a360200200f450d080b200241206a41086a200241386a41086a290200370300200220022902383703202004410876210f4104210d200c210e201041ffffff0771200441187472221021110c080b200c41011030000b41002104200241003a0058200c417e6a210c03400240200e2004470d00200441ff0171450d07200241003a00580c070b200241386a20046a200d20046a220f41016a2d00003a00002001200c3602042001200f41026a3602002002200441016a220f3a0058200c417f6a210c200f2104200f4120470d000b2002200829000037032020022009290000370025200228004721122002280043210e200228003f210c2002280238211120022f013c210420022d003e210f200741026a200241356a41026a2d00003a0000200720022f00353b00002004200f41107472210f4100210d0c060b200241386a2001106f200228023c220c450d04200228024421122002280240210e200228023821114101210d0c050b200241386a2001106f200228023c220c450d03200228024421122002280240210e200228023821114102210d0c040b200241386a2001106f200228023c220c450d02200228024421122002280240210e200228023821114103210d0c030b200410230c010b200c200d103e000b200041003602000240200b450d002006210403400240024020042d0000220141034b0d0002400240024020010e0404000102040b2004410c6a280200450d03200441086a28020010230c030b2004410c6a280200450d02200441086a28020010230c020b2004410c6a280200450d01200441086a28020010230c010b200441086a280200450d00200441046a28020010230b200441246a2104200a415c6a220a0d000b0b2003450d07200610230c070b200241106a41086a2213200241206a41086a290300370300200220022903203703100240200b2003470d0002400240200341016a22042003490d00200341017422142004201420044b1b2204ad42247e2215422088a70d002015a7221441004e0d010b102a000b0240024020030d002014102121060c010b2006200341246c2014102521060b2006450d03200421030b2006200b41246c6a220420123600102004200e36000c2004200c3600082004200f3b0005200420113600012004200d3a0000200441076a200f4110763a0000200420022903103700142004411c6a2013290300370000200a41246a210a200b41016a2204210b20042005470d000b0b2000200336020420002006360200200041086a20043602000c040b201441041030000b200441041030000b102f000b200041003602000b200241e0006a24000be304020c7f017e230041d0006b2202240020022001106e024002400240024002400240024020022802000d00200128020441246e220341246c2204417f4c0d01200228020421050240024020040d00410421060c010b200410212206450d030b02402005450d00410021070340200128020422084104490d07200741016a21092001280200220a280000210b20012008417c6a220c3602042001200a41046a36020041002104200241003a00482008417b6a210803400240200c2004470d00200441ff0171450d09200241003a00480c090b200241286a20046a200a20046a220d41046a2d00003a0000200120083602042001200d41056a3602002002200441016a220d3a00482008417f6a2108200d2104200d4120470d000b200241086a41186a2208200241286a41186a290300370300200241086a41106a220d200241286a41106a290300370300200241086a41086a220a200241286a41086a29030037030020022002290328370308024020032007470d00200741017422042009200420094b1b2203ad42247e220e422088a70d07200ea722044100480d070240024020070d002004102121060c010b2006200741246c2004102521060b2006450d060b2006200741246c6a2204200b360200200420022903083702042004410c6a200a290300370200200441146a200d2903003702002004411c6a20082903003702002009210720092005470d000b0b2000200336020420002006360200200041086a20053602000c060b200041003602000c050b102f000b200441041030000b200441041030000b102a000b200041003602002003450d00200610230b200241d0006a24000baf04010a7f230041d0006b2202240020022001106e0240024002400240024020022802000d00200128020422034160712204417f4c0d022002280204210502400240200341057622060d00410121070c010b200410212207450d040b02402005450d00410021080340200241003a00482008220941016a21082001280204417f6a21034100210402400240024003402003417f460d01200241286a20046a2001280200220a2d00003a0000200120033602042001200a41016a3602002002200441016a220a3a00482003417f6a2103200a2104200a4120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a220a200241286a41106a290300370300200241086a41086a220b200241286a41086a2903003703002002200229032837030820062009470d020240200941017422032008200320084b1b220641ffffff3f712006470d002006410574220341004e0d020b102a000b0240200441ff0171450d00200241003a00480b200041003602002006450d05200710230c050b0240024020090d002003102121070c010b200720094105742003102521070b2007450d070b200720094105746a22032002290308370000200341186a2004290300370000200341106a200a290300370000200341086a200b29030037000020082005470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241d0006a24000f0b102f000b200441011030000b200341011030000b9e2905257f027e0c7f077e057f23004190076b22022400200241206a2001106e02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022802200d00200128020441d0016e220341d0016c2204417f4c0d01200228022421050240024020040d00410821060c010b200410212206450d030b02402005450d0020024188046a2107200241a8036a41206a2108410021094100210a03402001280204220b4104490d1d200a41016a210c2001280200220d280000210e2001200b417c6a220f3602042001200d41046a36020041002110200241003a00a805417b211103400240200f20102204470d00200441ff0171450d1f200241003a00a8050c1f0b20024188056a20046a200d20046a221041046a2d00003a00002001200b20116a3602042001201041056a3602002002200441016a22103a00a8052011417f6a211120104120470d000b200241c8046a41086a221220024188056a41086a2213290300370300200241c8046a41106a221420024188056a41106a2215290300370300200241c8046a41186a221620024188056a41186a221729030037030020022002290388053703c80441002111200241003a00c805200d20106a210f2010200b6b41046a210d200b20046b417a6a210403400240200d20116a0d00201141ff0171450d1f200241003a00c8050c1f0b20024188056a20116a200f20116a221041046a2d00003a0000200120043602042001201041056a3602002002201141016a22103a00c8052004417f6a210420102111201041c000470d000b200241d0066a41386a221820024188056a41386a2219290300370300200241d0066a41306a221a20024188056a41306a221b290300370300200241d0066a41286a221c20024188056a41286a221d290300370300200241d0066a41206a221e20024188056a41206a221f290300370300200241d0066a41186a22202017290300370300200241d0066a41106a22212015290300370300200241d0066a41086a2222201329030037030020022002290388053703d006200241186a2001106e20022802180d1d2001280204200228021c220f490d1d200f417f4c0d0302400240200f0d00410121230c010b200f10272223450d202001280204200f490d1d20232001280200200f10dc041a20012802042204200f490d0620012004200f6b36020420012001280200200f6a3602000b2023450d1d20024188056a2001107d2002280288052224450d1b200228028c052125200128020422104110490d1a20022802900521262001280200220b41086a2900002127200b29000021282001200b41106a3602002001201041706a220d36020441002104200241003a00a8052010416f6a211003400240200d2004470d000240200441ff0171450d00200241003a00a8050b02402025450d00202410230b200f450d1f202310230c1f0b20024188056a20046a200b20046a221141106a2d00003a0000200120103602042001201141116a3602002002200441016a22113a00a8052010417f6a21102011210420114120470d000b200241e8046a41086a22042013290300370300200241e8046a41106a22102015290300370300200241e8046a41186a2211201729030037030020022002290388053703e80420024188056a2001108001024020022802880522290d0002402025450d00202410230b200f450d1e202310230c1e0b200241a8036a41086a222a2012290300370300200241a8036a41106a222b2014290300370300200241a8036a41186a222c201629030037030020024190066a41086a2215202229030037030020024190066a41106a2216202129030037030020024190066a41186a222d202029030037030020024190066a41206a222e201e29030037030020024190066a41286a222f201c29030037030020024190066a41306a2230201a29030037030020024190066a41386a22312018290300370300200220022903c8043703a803200220022903d006370390062002280290052132200228028c052133200241a8046a41186a220b2011290300370300200241a8046a41106a22112010290300370300200241a8046a41086a22102004290300370300200220022903e8043703a804200841386a2031290300370300200841306a2030290300370300200841286a202f290300370300200841206a202e290300370300200841186a202d290300370300200841106a2016290300370300200841086a20152903003703002008200229039006370300200720022903a804370300200741086a2010290300370300200741106a2011290300370300200741186a200b290300370300200241a8026a200241a8036a41800110dc041a200241106a2001106e20022802100d18200128020441c1006e223441c1006c2204417f4c0d03200228021421140240024020040d00410121120c010b200410212212450d070b02402014450d0041002113034020012802042210450d192001280200220b2d0000210420012010417f6a220d3602042001200b41016a3602002004417f6a220441014b0d1902400240024020040e020001000b41002104200241003a00e8032010417e6a211003400240200d2004470d00200441ff0171450d1d200241003a00e8030c1d0b200241a8036a20046a200b20046a221141016a2d00003a0000200120103602042001201141026a3602002002200441016a22113a00e8032010417f6a211020112104201141c000470d000b2019200241a8036a41386a2903002235370300201b200241a8036a41306a2903002236370300201d200241a8036a41286a2903002237370300201f200829030022383703002017202c29030022393703002022202a2903003703002021202b29030037030020202039370300201e2038370300201c2037370300201a203637030020182035370300200220022903a8033703d006410021110c010b41002104200241003a00e8032010417e6a211003400240200d2004470d00200441ff0171450d1c200241003a00e8030c1c0b200241a8036a20046a200b20046a221141016a2d00003a0000200120103602042001201141026a3602002002200441016a22113a00e8032010417f6a211020112104201141c000470d000b2019200241a8036a41386a2903002235370300201b200241a8036a41306a2903002236370300201d200241a8036a41286a2903002237370300201f200829030022383703002017202c29030022393703002022202a2903003703002021202b29030037030020202039370300201e2038370300201c2037370300201a203637030020182035370300200220022903a8033703d006410121110b201341016a21102031201829030022353703002030201a2903002236370300202f201c2903002237370300202e201e2903002238370300202d2020290300223937030020162021290300223a37030020152022290300223b370300200241d0056a41086a220b203b370300200241d0056a41106a220d203a370300200241d0056a41186a223c2039370300200241d0056a41206a223d2038370300200241d0056a41286a223e2037370300200241d0056a41306a223f2036370300200241d0056a41386a22402035370300200220022903d006223537039006200220353703d005024020342013470d00201341017422042010200420104b1b2234ad42c1007e2235422088a70d142035a722044100480d140240024020130d002004102121120c010b2012201341c1006c2004102521120b2012450d150b2012201341c1006c6a220420113a0000200420022903d005370001200441096a200b290300370000200441116a200d290300370000200441196a203c290300370000200441216a203d290300370000200441296a203e290300370000200441316a203f290300370000200441396a20402903003700002010211320102014470d000b0b2012450d18200241086a2001106e20022802080d1602400240200228020c221841076a221041037622160d004101211a0c010b20161027221a450d1420012802042016490d16201a2001280200201610dc041a200128020422042016490d082001200420166b3602042001200128020020166a3602000b200220163602c80420104188808080024f0d082002201041787122043602e804024002400240200441ffffffff014b0d00201a410120161b210b20040d01410021110c020b20024194056a4101360200200241bc036a4102360200200242023702ac03200241d4d3c4003602a803200241d0d3c400360290052002410136028c05200220024188056a3602b8032002200241e8046a36028805200241a8036a41e4d3c4001038000b4101211120044109490d00200441786a41037641016a21110b200220113602d0052002200b20116a2211360290062011200b490d092004410374210d4100210402400240201041f8ffffff017122100d0041012117410021110c010b410121110240200d41c800490d00201041786a41037641016a21110b201110212217450d0b0b2002200d3602d4062002200b3602d0060240200241d0066a10810141ff017122134102460d00410021104100210403404100210b0240024020044108490d002004410376220d20046a410771220b45410374200b724108470d014101210b200d410820044107716b22154d0d00200d20156b220b410376200b410771456b41026a210b0b0240200b2011470d00201141016a220b2011490d152011410174220d200b200d200b4b1b220d4100480d150240024020110d00200d102121170c010b20172011200d102521170b2017450d182011210b200d21110b2017200b6a41003a00000b200220103602d00520022004200441086a200441774b1b2204410376220b36029006024002400240200b20104d0d0002400240201020044107716a22104108490d002010410771210d201041037621150c010b410021152010210d0b20024107200d6b22103a00e804201041ff017141084f0d104100201720044108491b20156a210d410120104107717421102013410171450d01200d2d000020107221100c020b20024194056a4101360200200241bc036a4102360200200242023702ac03200241989dc6003602a8032002410136028c05200220024188056a3602b803200220024190066a360290052002200241d0056a36028805200241a8036a41c09dc6001038000b200d2d00002010417f737121100b200d20103a0000200b2110200241d0066a10810141ff017122134102470d000b0b20044103762018490d0f2002201836029006201841ffffffff014b0d0d201141ffffffff01712011470d0c20114103742018490d0e02402016450d00201a10230b2017450d16200241a8016a200241a8026a41800110dc041a2023450d1d200241286a200241a8016a41800110dc041a02402003200a470d00200a4101742210200c2010200c4b1b2203ad42d0017e2235422088a70d122035a722104100480d1202400240200a0d002010102121060c010b2006200a41d0016c2010102521060b2006450d110b2006200a41d0016c6a22102027370308201020283703002010202936022c20102024360220201020233602142010200e360210201041346a2032360200201041306a2033360200201041286a2026360200201041246a20253602002010411c6a200f360200201041186a200f360200201041386a200241286a41800110dc041a201041c8016a2011ad4220862004410771201841037472ad84370200201020173602c401201041c0016a2014360200201041bc016a2034360200201020123602b801200941d0016a2109200c210a200c2005470d000b0b2000200336020420002006360200200041086a20053602000c1c0b200041003602000c1b0b102f000b200441081030000b200f2004103e000b200441011030000b20162004103e000b200241bc036a4101360200200242023702ac03200241fc9bc6003602a8032002410136028c05200220024188056a3602b8032002200241c8046a36028805200241a8036a41b09cc6001038000b200241a8036a41146a4109360200200241a8036a410c6a410a36020020024188056a41146a410336020020024188056a410c6a41033602002002418cd4c400360290052002410336028c05200241f4d3c40036028805200241093602ac032002200b3602d0062002200241a8036a36029805200220024190066a3602b8032002200241d0056a3602b0032002200241d0066a3602a80320024188056a41f8d4c4001038000b201141011030000b20024194056a4104360200200241bc036a4102360200200242023702ac03200241b8a4c5003602a803200241d8a3c500360290052002410b36028c05200220024188056a3602b8032002200241e8046a36028805200241a8036a41eca4c5001038000b41f3f0c2004118104a000b20024194056a4101360200200241bc036a4102360200200242023702ac032002418cf1c2003602a803200241d0d3c400360290052002410136028c05200220024188056a3602b803200220024190066a36028805200241a8036a419cf1c2001038000b2011108301210120024194056a4101360200200241bc036a41023602002002410136028c05200220013602d006200242023702ac03200241acf1c2003602a8032002200241d0066a36029005200220024190066a36028805200220024188056a3602b803200241a8036a41bcf1c2001038000b41ccf1c200102b000b201041081030000b102a000b200441011030000b201641011030000b200d41011030000b201a10230b02402034450d00201210230b0240200f450d00202310230b02402025450d00202410230b02402032450d00203241047421042029210103400240200141046a280200450d00200128020010230b200141106a2101200441706a22040d000b0b2033450d060c020b2034450d00201210230b0240200f450d00202310230b02402025450d00202410230b02402032450d00203241047421042029210103400240200141046a280200450d00200128020010230b200141106a2101200441706a22040d000b0b2033450d040b202910230c030b02402025450d00202410230b200f450d02202310230c020b200f450d01202310230c010b202310230b200041003602000240200a450d002006210103402001106c200141d0016a2101200941b07e6a22090d000b0b2003450d00200610230b20024190076a24000f0b200f41011030000b9b05010d7f230041206b22022400200241106a2001106e02400240024002400240024020022802100d00200128020422034170712204417f4c0d022002280214210541042106024020034104762207450d00200410212206450d040b0240024002402005450d00410021084100210441002109034020012802042203450d032001280200220a2d0000210b20012003417f6a3602042001200a41016a360200200b41034f0d03200241086a2001106e20022802080d032001280204200228020c2203490d032003417f4c0d060240024002400240024020030d004101210c0c010b20031027220c450d0120012802042003490d06200c2001280200200310dc041a2001280204220a2003490d0c2001200a20036b3602042001200128020020036a3602000b200941016a210a2002411a6a41026a220d2002411d6a41026a2d00003a0000200220022f001d3b011a20092007470d0202402008200a2008200a4b1b220741ffffffff00712007470d002007410474220e41004e0d020b102a000b200341011030000b0240024020090d00200e102121060c010b20062004200e102521060b2006450d0a0b200620046a2209410c6a200b3a00002009200c360200200941086a2003360200200941046a20033602002009410d6a20022f011a3b00002009410f6a200d2d00003a0000200841026a2108200441106a2104200a21092005200a470d000b0b2000200736020420002006360200200041086a20053602000c030b200c10230b2000410036020002402009450d002006210103400240200141046a280200450d00200128020010230b200141106a2101200441706a22040d000b0b2007450d01200610230c010b200041003602000b200241206a24000f0b102f000b200441041030000b2003200a103e000b200e41041030000bfc0101067f230041306b220124004102210202400240200028020422034108490d0020002802002102200141003602002001200341037622043602042004450d012002410120031b22042d0000210520002003410771220641016a2202410771200341786a417871723602042000200241037622034100200241084922021b20044100200320021b6a72360200200541012006410773747141004721020b200141306a240020020f0b2001412c6a41013602002001411c6a41023602002001420237020c200141989dc600360208200141013602242001200141206a3602182001200141046a36022820012001360220200141086a41b4acc6001038000bec0101067f23004180016b220224002001410c6a28020021032001280208210420012802002205210602402005410471450d0020012005410872220636020020040d0020014281808080a0013702080b2001200641047236020020002802002100410021060340200220066a41ff006a2000410f712207413072200741d7006a2007410a491b3a00002006417f6a2106200041047622000d000b024020064180016a2200418101490d002000418001103e000b200141a085c0004102200220066a4180016a410020066b103c21062001200336020c200120043602082001200536020020024180016a240020060b22000240200041ffffffff01712000460d0041f3f0c2004118104a000b20004103740bc805020c7f067e230041f0006b2202240020022001106e0240024002400240024020022802000d00200128020441306e220341306c2204417f4c0d02200228020421050240024020040d00410821060c010b200410212206450d040b02402005450d00410021070340200241003a00682007220841016a210720012802042109417f210a410021040240024002400240034020092004460d01200241c8006a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a0068200a417f6a210a200c2104200c4120470d000b200241286a41186a2204200241c8006a41186a290300370300200241286a41106a220a200241c8006a41106a290300370300200241286a41086a220d200241c8006a41086a290300370300200220022903483703282009200c6b220c4110490d01200b41096a290000210e200b290001210f2001200c41706a3602042001200b41116a360200200241086a41086a220c200d290300370300200241086a41106a2209200a290300370300200241086a41186a220a20042903003703002002200229032837030820032008470d030240200841017422042007200420074b1b2203ad42307e2210422088a70d002010a7220441004e0d030b102a000b200441ff0171450d00200241003a00680b200041003602002003450d05200610230c050b0240024020080d002004102121060c010b2006200841306c2004102521060b2006450d070b200c290300211020092903002111200a2903002112200229030821132006200841306c6a2204200f37032020042013370300200441286a200e370300200441186a2012370300200441106a2011370300200441086a201037030020072005470d000b0b2000200336020420002006360200200041086a20053602000c010b200041003602000b200241f0006a24000f0b102f000b200441081030000b200441081030000bed0704067f017e0a7f027e230041f0006b22032400200341206a2001200228020c22041102000240024020032802200d002000410036020820004208370200200120022802001103002002280204450d01200110230c010b200341c8006a41106a200341206a41106a290300370300200341c8006a41086a200341206a41086a290300370300200341c8006a41186a200341206a41186a290300370300200341c8006a41206a200341206a41206a280200360200200341086a200341d4006a290200370300200341106a200341dc006a290200370300200341186a200341e4006a290200370300200320032903203703482003200329024c370300200341c8006a2001200228021022051102000240024002400240417f2003280248220641016a220720072006491b2208ad42287e2209422088a70d002009a72206417f4c0d000240024020060d004108210a4108210b0c010b20061021220a450d02200a210b0b200a2003290300370300200a41186a200341186a220c290300370300200a41106a200341106a220d290300370300200a41086a200341086a290300370300200b4201370320200341206a200120041102000240024020032802200d004101210e0c010b200341c8006a410472210641c800210f4101210e0340200341c8006a41206a200341206a41206a280200360200200341c8006a41186a2210200341206a41186a290300370300200341c8006a41106a2211200341206a41106a290300370300200341c8006a41086a2212200341206a41086a29030037030020032003290320370348200341086a2207200641086a290200370300200d200641106a290200370300200c200641186a290200370300200320062902003703002010200c2903003703002011200d29030037030020122007290300370300200320032903003703480240200e2008470d00200341206a200120051102002008417f2003280220220741016a221320132007491b6a22072008490d06200841017422132007201320074b1b2213ad42287e2209422088a70d062009a722074100480d060240024020080d0020071021210a0c010b200a200841286c20071025210a0b200a450d05200a210b201321080b200b200f6a221341606a2207200329034837030020122903002109201129030021142010290300211520134201370300200741186a2015370300200741106a2014370300200741086a2009370300200341206a20012004110200200f41286a210f200e41016a210e20032802200d000b0b2001200228020011030002402002280204450d00200110230b2000200e360208200020083602042000200b3602000c040b102f000b200641081030000b200741081030000b102a000b200341f0006a24000bad08040c7f017e057f037e23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d002001280210220628020021072006280208220841014b210903402003200441206a220a360200200241e0006a41186a200441186a290000370300200241e0006a41106a200441106a290000370300200241e0006a41086a200441086a29000037030020022004290000370360410021040240024020090d0020080e020401040b2008210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a412010de044101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a412010de040d02200a2104200a2005470d000b0b20004100360208200042013702002001280204450d01200128020010230c010b200241c0006a41086a2204200241e0006a41086a290300370300200241c0006a41106a220b200241e0006a41106a290300370300200241c0006a41186a220c200241e0006a41186a29030037030020022002290360220e3703002002200e370340024041201021220f450d00200f2002290340370000200f41186a200c290300370000200f41106a200b290300370000200f41086a2004290300370000200128020421102001280200211102400240200a2005470d0041012112410121130c010b41012112410121130340200628020821032006280200210702400340200241e0006a41186a2208200a41186a290000370300200241e0006a41106a2209200a41106a290000370300200241e0006a41086a2201200a41086a2900003703002002200a290000370360200a41206a210a4100210402400240200341014b0d0020030e020301030b2003210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a412010de044101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a412010de040d01200a2005470d000c030b0b200241c0006a41086a2001290300220e370300200241c0006a41106a20092903002214370300200241c0006a41186a20082903002215370300200220022903602216370340200241186a220b2015370300200241106a220c2014370300200241086a220d200e37030020022016370300024020132012470d000240201241016a22042012490d00201241017422072004200720044b1b221341ffffff3f712013470d00201341057422044100480d000240024020120d0020041021210f0c010b200f201241057420041025210f0b200f0d01200441011030000b102a000b200f20124105746a22042002290300370000200441186a200b290300370000200441106a200c290300370000200441086a200d290300370000201241016a2112200a2005470d000b0b02402010450d00201110230b20002012360208200020133602042000200f3602000c010b412041011030000b20024180016a24000bb00705077f037e097f017e017f23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d0020012802102106200241f4006a2107034020032004220841206a2204360200200841086a2903002109200841106a290300210a2008290300210b200241e0006a41186a200841186a290300370300200241e0006a41106a200a370300200241e0006a41086a20093703002002200b3703600240200aa720062802004d0d002001280214220c2007460d002007290000200c290000520d030b20052004470d000b0b20004100360208200042083702002001280204450d01200128020010230c010b200241086a2204200241e0006a41086a290300370300200241106a2203200241e0006a41106a290300370300200241186a2207200241e0006a41186a29030037030020022002290360220a3703202002200a3703000240024002400240024041201021220d450d00200d2002290300370300200d41186a2007290300370300200d41106a2003290300370300200d41086a20042903003703002001280204210e2001280200210f200541606a2008460d03200841206a2110200541606a2111200241f4006a21014101211241012113200d21140340200c2001460d042010210802400340200241e0006a41186a2204200841186a290300370300200241e0006a41106a2203200841106a290300220a370300200241e0006a41086a2207200841086a290300370300200220082903003703600240200aa720062802004d0d002001290000200c290000520d020b2005200841206a2208470d000c070b0b200241206a41086a2007290300220a370300200241206a41106a20032903002209370300200241206a41186a2004290300220b3703002002200229036022153703202004200b370300200320093703002007200a37030020022015370360024020132012470d00201241016a22132012490d04201241017422102013201020134b1b221341ffffff3f712013470d04201341057422104100480d040240024020120d002010102121140c010b201420124105742010102521140b2014450d030b200841206a2110201420124105746a22162002290360370300201641186a2004290300370300201641106a2003290300370300201641086a2007290300370300201241016a211220112008470d000c050b0b412041081030000b201041081030000b102a000b4101211241012113200d21140b0240200e450d00200f10230b2000201236020820002013360204200020143602000b20024180016a24000b9f0a03077f037e057f230041d0026b2202240041002103200241003a00c8022001280204417f6a210402400240024003402004417f460d01200241a8026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8022004417f6a21042005210320054120470d000b200241e8006a41086a200241a8026a41086a290300370300200241e8006a41106a200241a8026a41106a290300370300200241e8006a41186a200241a8026a41186a290300370300200220022903a80237036820022001106e2002280200450d01200041003602040c020b0240200341ff0171450d00200241003a00c8020b200041003602040c010b2002280204210641002104200241003a00c80220012802042107417f21030240034020072004460d01200241a8026a20046a200128020022082d00003a00002001200720036a3602042001200841016a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241a8016a41086a200241a8026a41086a2903002209370300200241a8016a41106a200241a8026a41106a290300220a370300200241a8016a41186a200241a8026a41186a290300220b37030020024188016a41086a200937030020024188016a41106a200a37030020024188016a41186a200b370300200220022903a80222093703a801200220093703880141002104200241003a00c802200720056b210c200720036a210303400240200c2004470d000240200441ff0171450d00200241003a00c8020b200041003602040c030b200241a8026a20046a200820046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241e8016a41086a200241a8026a41086a2903002209370300200241e8016a41106a200241a8026a41106a290300220a370300200241e8016a41186a200241a8026a41186a290300220b370300200241c8016a41086a22042009370300200241c8016a41106a2203200a370300200241c8016a41186a2205200b370300200220022903a80222093703e801200220093703c801200241a8026a2001107c024020022802a8022201450d00200241c8006a41086a2208200241e8006a41086a290300370300200241c8006a41106a2207200241e8006a41106a290300370300200241c8006a41186a220c200241e8006a41186a290300370300200241286a41086a220d20024188016a41086a290300370300200241286a41106a220e20024188016a41106a290300370300200241286a41186a220f20024188016a41186a29030037030020022002290368370348200220022903880137032820022902ac022109200241086a41186a22102005290300370300200241086a41106a22052003290300370300200241086a41086a22032004290300370300200220022903c801370308200020093702082000200136020420002006360200200041106a2002290348370200200041186a2008290300370200200041206a2007290300370200200041286a200c290300370200200041306a2002290328370200200041386a200d290300370200200041c0006a200e290300370200200041c8006a200f290300370200200041e8006a2010290300370200200041e0006a2005290300370200200041d8006a2003290300370200200041d0006a20022903083702000c020b200041003602040c010b0240200441ff0171450d00200241003a00c8020b200041003602040b200241d0026a24000bf40401067f230041f0006b22022400200241086a220341c4fbc400ad4280808080e000841003220441086a2900003703002002200429000037030020041023200241286a41086a2205200329030037030020022002290300370328200341f0bcc000ad42808080809001841003220441086a2900003703002002200429000037030020041023200241386a41086a22062003290300370300200220022903003703382002200136026c200241186a2201200241ec006aad4280808080c000841001220441186a290000370300200241106a2207200441106a2900003703002003200441086a2900003703002002200429000037030020041023200241c8006a41186a22042001290300370300200241c8006a41106a22012007290300370300200241c8006a41086a2207200329030037030020022002290300370348024041c00010212203450d00200320022903283700002003200229033837001020032002290348370020200341086a2005290300370000200341186a2006290300370000200341286a2007290300370000200341306a2001290300370000200341386a20042903003700002002200341c000108a012007200241096a2900003703002001200241116a2900003703002004200241196a290000370300200220022900013703480240024020022d00004101460d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002002290348370000200041186a200241c8006a41186a290300370000200041106a200241c8006a41106a290300370000200041086a200241c8006a41086a2903003700000b20031023200241f0006a24000f0b41c00041011030000bd50302047f047e230041f0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022040d00200041003a00000c010b200341186a28020021052003280214210641002101200341003a006802400340024020052001470d000240200141ff0171450d00200341003a00680b4100210120034100360228200342013703202003410c3602442003200341086a3602402003200341206a36026c200341dc006a41013602002003420137024c20034198c2c3003602482003200341c0006a360258200341ec006a41b8a3c500200341c8006a102e1a200335022842208620033502208410082003280224450d02200328022010230c020b200341c8006a20016a200420016a2d00003a00002003200141016a22023a00682002210120024120470d000b200341206a41186a200341c8006a41186a2903002207370300200341206a41106a200341c8006a41106a2903002208370300200341206a41086a200341c8006a41086a290300220937030020032003290348220a370320200041196a2007370000200041116a2008370000200041096a20093700002000200a370001410121010b200020013a00002006450d00200410230b200341f0006a24000bbc0806017f017e057f017e017f017e230041f0006b2201240042002102200141386a41186a22034200370300200141386a41106a22044200370300200141386a41086a2205420037030020014200370338200141e0006a41086a220641c4fbc400ad4280808080e000841003220741086a2900003703002001200729000037036020071023200520062903003703002001200129036037033820064197bdc000ad4280808080e000841003220741086a2900003703002001200729000037036020071023200420012903602208370300200141086a41086a2005290300370300200141086a41106a2008370300200141086a41186a20062903003703002001200837032820012001290338370308200141386a200141086a108c0102400240200128023822070d004104210741002106410021090c010b200129023c2202422088a721062002a721090b200141386a41206a200041206a2802003602002003200041186a2902003703002004200041106a2902003703002005200041086a2902003703002001200029020037033802400240024020062009470d00024020062002a7470d00200641016a22002006490d03200641017422052000200520004b1bad220842247e220a422088a70d03200aa722004100480d030240024020060d002000102121070c010b2007200641246c2000102521070b2007450d0220024280808080708320088421020b2002422088a721060b2007200641246c22096a22002001290338370200200041206a200141386a41206a280200360200200041186a200141386a41186a2205290300370200200041106a200141386a41106a2204290300370200200041086a200141386a41086a220029030037020020054200370300200442003703002000420037030020014200370338200141e0006a41086a220541c4fbc400ad4280808080e000841003220341086a2900003703002001200329000037036020031023200020052903003703002001200129036037033820054197bdc000ad4280808080e000841003220341086a2900003703002001200329000037036020031023200420012903602208370300200141086a41086a2000290300370300200141086a41106a2008370300200141086a41186a200529030037030020012008370328200120012903383703082001412036023c2001200141086a3602382007200641016a2200200141386a108d01024020002006490d00200941246a21002007210603400240024020062d0000220541034b0d0002400240024020050e0404000102040b2006410c6a280200450d03200641086a28020010230c030b2006410c6a280200450d02200641086a28020010230c020b2006410c6a280200450d01200641086a28020010230c010b200641086a280200450d00200641046a28020010230b200641246a21062000415c6a22000d000b0b02402002a7450d00200710230b200141f0006a24000f0b200041041030000b102a000bae0201037f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100410900102400240200228021022010d00200041003602000c010b200228021421032002200241186a28020036022420022001360220200241c8006a200241206a107c0240024020022802482204450d002000200229024c370204200020043602000c010b20024100360230200242013703282002410c36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c20024198c2c3003602482002200241386a360258200241c4006a41b8a3c500200241c8006a102e1a2002350230422086200235022884100820004100360200200228022c450d00200228022810230b2003450d00200110230b200241e0006a24000bd40201087f230041206b22032400200341003602082003420137030020012003105c024002400240024020010d002003280208210420032802042105200328020021060c010b200141246c210720032802042105200328020821010340200341106a200010b0012003280210210802400240200520016b20032802182209490d00200120096a2104200328020021060c010b200120096a22042001490d04200541017422062004200620044b1b220a4100480d040240024020050d00200a102121060c010b20032802002005200a102521060b2006450d032003200a36020420032006360200200a21050b20032004360208200620016a2008200910dc041a02402003280214450d00200810230b200041246a2100200421012007415c6a22070d000b0b20022902002004ad4220862006ad84100202402005450d00200610230b200341206a24000f0b200a41011030000b102a000bfb1005047f017e017f027e067f230041e0036b22012400200141186a41d4bcc0004110108f012001280218210220014194016a200128021c360200200120024536029001200141206a200041f00010dc041a200141a0016a41003602002001420137039801200141d0026a41186a22034200370300200141d0026a41106a22044200370300200141d0026a41086a22024200370300200142003703d002200141c0036a41086a220041c4fbc400ad4280808080e0008422051003220641086a290000370300200120062900003703c0032006102320022000290300370300200120012903c00322073703a803200120073703d002200041a4d0c000ad4280808080a0018422081003220641086a290000370300200120062900003703c00320061023200420012903c0032207370300200141b0026a41086a22062002290300370300200141b0026a41106a22092007370300200141b0026a41186a220a2000290300370300200120073703a803200120012903d0023703b002200141106a200141b0026a4120108f010240024002400240024002400240024002400240024002402001280214410020012802101b220b41016a220c200b490d00200342003703002004420037030020024200370300200142003703d002200020051003220b41086a2900003703002001200b2900003703c003200b102320022000290300370300200120012903c00322073703a803200120073703d002200020081003220b41086a2900003703002001200b2900003703c003200b1023200141a8036a41086a220d20002903002207370300200120012903c00322083703a80320042008370000200441086a220e20073700002006200229030037030020092004290300370300200a2003290300370300200120012903d0023703b0022001200c3602a801200141b0026aad42808080808004842207200141a8016aad4280808080c000841002200141a8016a200141206a41880110dc041a200342003703002004420037030020024200370300200142003703d002200020051003220b41086a2900003703002001200b2900003703c003200b102320022000290300370300200120012903c00322053703a803200120053703d002200041c0bdc000ad4280808080e000841003220b41086a2900003703002001200b2900003703c003200b1023200d20002903002205370300200120012903c00322083703a80320042008370000200e20053700002006200229030037030020092004290300370300200a2003290300370300200120012903d0023703b002200141a8036a200710041090010240024020012802a803450d00200141f0026a41086a200141a8036a41086a280200360200200120012903a8033703f0020c010b200141003602c803200142083703c003200141003602d802200142013703d0024100200141d0026a105c200141f8026a20012802d802360200200120012903d0023703f002200141c0036a107a0b20014180036a41086a200141f0026a41086a2802002200360200200120012903f00237038003024002402000450d00200141d0026a20012802800320004101106920012802d0024101470d01200128028403450d0b20012802800310230c0b0b410120014180036a105c200141a8016a20014180036a1091010c080b20012802d40221060240200141dc026a2802002200200141d0026a41086a2802002202460d00200128028803200020026b6a220341046a2209417f4c0d020240024020090d004101210a0c010b20091021220a450d040b20012009360294032001200a360290032001200336029803200120014190036a3602d0022006200141d0026a200010920120032000490d0420012802980322062003490d0520012802880322062002490d062001280290032109200128028003210a2001200320006b22033602a0032001200620026b22063602a40320032006470d07200920006a200a20026a200310dc041a200141a8016a20014190036a109101200128029803210220012802940321032001280290032100200128028403450d0920012802800310230c090b200120014180036a3602d0022006200141d0026a2002109201200141a8016a20014180036a1091010c070b200141206a1093010c0a0b102f000b200941011030000b20002003103e000b200320061036000b20022006103e000b200141c0036a41146a410d360200200141cc036a410e360200200141a8036a41146a4103360200200142033702ac03200141acb6c6003602a8032001410e3602c4032001200141a0036a3602d8032001200141a4036a3602dc03200142043703e002200142013702d40220014180b7c6003602d0022001200141c0036a3602b8032001200141d0026a3602d0032001200141dc036a3602c8032001200141d8036a3602c003200141a8036a41bcb7c6001038000b2001280288032102200128028403210320012802800321000b20000d010b200141a8016a1093010c010b20072002ad4220862000ad84100202402003450d00200010230b200141a8016a109301200141d0026a41186a22064200370300200141d0026a41106a22094200370300200141d0026a41086a22024200370300200142003703d002200141c0036a41086a220041c4fbc400ad4280808080e000841003220341086a290000370300200120032900003703c0032003102320022000290300370300200120012903c00322073703a803200120073703d002200041f9bcc000ad4280808080e000841003220341086a290000370300200120032900003703c00320031023200141a8036a41086a20002903002207370300200120012903c00322053703a80320042005370000200441086a2007370000200141b0026a41086a2002290300370300200141b0026a41106a2009290300370300200141b0026a41186a2006290300370300200120012903d0023703b002200141086a200141b0026a4120108f010b200141e0036a24000b8f0201037f230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100410900102400240200328020822040d00410021010c010b200328020c210502400240200341106a2802004104490d0020042800002102410121010c010b4100210120034100360220200342013703182003410c36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c20034198c2c3003602382003200341286a360248200341346a41b8a3c500200341386a102e1a200335022042208620033502188410080240200328021c450d00200328021810230b0b2005450d00200410230b2000200236020420002001360200200341d0006a24000b920201057f230041206b2202240020022001a7220336021020022001422088a7220436021402402004450d0020032d0000210520022004417f6a3602142002200341016a360210200541014b0d0041002103024002400240024020050e020100010b200241086a200241106a106e20022802080d0320022802142205200228020c2204490d032004417f4c0d010240024020040d00410121030c010b200410272203450d03200320022802102206200410dc041a2002200520046b3602142002200620046a3602100b2003450d032004ad220142208620018421010b2000200137020420002003360200200241206a24000f0b102f000b200441011030000b41f4b7c600412e200241186a41a4b8c6001031000bf90401057f230041106b2202240002400240024002400240024020002802704101460d0002400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d06200341017422052004200520044b1b22054100480d060240024020030d002005102121040c010b200128020020032005102521040b2004450d0320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280274210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d06200441017422032005200320054b1b22034100480d060240024020040d002003102121040c010b200128020020042003102521040b2004450d0420012004360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200420036a20063600000c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d05200341017422052004200520044b1b22054100480d050240024020030d002005102121040c010b200128020020032005102521040b2004450d0420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00000b2000200110b2012000280278210320004180016a28020022002001105c02402000450d002000410574210003402002200136020c20032002410c6a106b200341206a2103200041606a22000d000b0b200241106a24000f0b200541011030000b200341011030000b200541011030000b102a000b8d0301027f230041e0006b22032400200341003a0005024002402000413f4b0d0041012104200341013a0005200320004102743a00000c010b02400240200041808001490d0020004180808080044f0d0141042104200341043a0005200320004102744102723602000c020b41022104200341023a0005200320004102744101723b01000c010b41052104200341053a0005200341033a0000200320003600010b024002402001280200220028020822012002490d0020002802002100200320023602082003200436020c20042002470d0120002003200210dc041a200341e0006a24000f0b200220011036000b200341286a41146a410d360200200341346a410e360200200341106a41146a410336020020034203370214200341acb6c6003602102003410e36022c2003200341086a36024020032003410c6a360244200342043703582003420137024c20034180b7c6003602482003200341286a3602202003200341c8006a3602382003200341c4006a3602302003200341c0006a360228200341106a41bcb7c6001038000bb40201027f024020002d0000417c6a220141074b0d000240024002400240024020010e080005010203050504000b200041086a280200450d04200041046a28020010230c040b200041046a2802000d032000410c6a280200450d03200041086a28020010230c030b200041046a2d00004102490d020240200041106a2802002201450d00200141d0006c2102200041086a28020041c0006a210103400240200141046a280200450d00200128020010230b200141d0006a2101200241b07f6a22020d000b0b2000410c6a280200450d02200028020810230c020b200041086a2d00004101470d01200041146a280200450d01200041106a28020010230c010b200041046a2d00000d002000410c6a280200450d00200041086a28020010230b0240200041fc006a280200450d00200028027810230b0bb00201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210420034120710d012004ad2001103921000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141a085c0004102200220006a4180016a410020006b103c21000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141a085c0004102200220006a4180016a410020006b103c21000b20024180016a240020000f0b2004418001103e000b2004418001103e000b130020004107360204200041d4bdc0003602000b3400200041c4fbc40036020420004100360200200041146a410d360200200041106a4180c5c000360200200041086a42063702000b5401017f230041206b22022400200241003602082002420837030020024100360218200242013703104100200241106a105c200041086a2002280218360200200020022903103702002002107a200241206a24000b7101017f230041306b22022400200241186a4200370300200241106a4200370300200241086a42003703002002420037030020024100360228200242013703202002200241206a36022c20022002412c6a106b200041086a200228022836020020002002290320370200200241306a24000b2f01017f02404101102122020d00410141011030000b200042818080801037020420002002360200200241003a00000bac0405057f017e017f027e047f230041f0006b22002400200041306a41186a22014200370300200041306a41106a22024200370300200041306a41086a2203420037030020004200370330200041e0006a41086a220441c4fbc400ad4280808080e0008422051003220641086a29000037030020002006290000370360200610232003200429030037030020002000290360220737035020002007370330200441a0cec000ad4280808080b0028422081003220641086a2900003703002000200629000037036020061023200220002903602207370300200041106a41086a22062003290300370300200041106a41106a22092007370300200041106a41186a220a20042903003703002000200737035020002000290330370310200041086a200041106a4120108f01200028020c210b2000280208210c20014200370300200242003703002003420037030020004200370330200420051003220241086a29000037030020002002290000370360200210232003200429030037030020002000290360220737035020002007370330200420081003220241086a290000370300200020022900003703602002102320012004290300220737030020062003290300370300200920002903602205370300200a200737030020002005370350200020002903303703102000200b4100200c1b2204418094ebdc032004418094ebdc03491b360230200041106aad4280808080800484200041306aad4280808080c000841002200041f0006a24000bfc1e09057f017e017f017e027f017e017f027e077f230041f0016b22012400200141a8016a41186a22024200370300200141a8016a41106a22034200370300200141a8016a41086a22044200370300200142003703a801200141c8016a41086a220541c4fbc400ad4280808080e0008422061003220741086a290000370300200120072900003703c8012007102320042005290300370300200120012903c801220837039801200120083703a80120054188cec000ad4280808080e001841003220741086a290000370300200120072900003703c80120071023200320012903c8012208370300200141f8006a41086a22072004290300370300200141f8006a41106a22092008370300200141f8006a41186a220a200529030037030020012008370350200120012903a801370378200141f8006aad220b428080808080048422081005200242003703002003420037030020044200370300200142003703a801200520061003220c41086a2900003703002001200c2900003703c801200c102320042005290300370300200120012903c801220d370398012001200d3703a801200541a0cec000ad4280808080b002841003220c41086a2900003703002001200c2900003703c801200c102320022005290300220d37030020072004290300370300200920012903c801220e370300200a200d3703002001200e370350200120012903a80137037820081005200242003703002003420037030020044200370300200142003703a801200520061003220c41086a2900003703002001200c2900003703c801200c102320042005290300370300200120012903c801220d370398012001200d3703a801200541c4cec000ad42808080808002841003220c41086a2900003703002001200c2900003703c801200c102320022005290300220d37030020072004290300370300200920012903c801220e370300200a200d3703002001200e370350200120012903a80137037820081005200242003703002003420037030020044200370300200142003703a801200520061003220c41086a2900003703002001200c2900003703c801200c102320042005290300370300200120012903c801220d370398012001200d3703a801200541f9bcc000ad4280808080e000841003220c41086a2900003703002001200c2900003703c801200c102320022005290300220d37030020072004290300370300200920012903c801220e370300200a200d3703002001200e370350200120012903a801370378200141086a200141f8006a4120108f01200128020c210f0240200128020822104101470d00200810050b200242003703002003420037030020044200370300200142003703a801200520061003220c41086a2900003703002001200c2900003703c801200c102320042005290300370300200120012903c801220637039801200120063703a801200541ffbcc000ad4280808080a001841003220c41086a2900003703002001200c2900003703c801200c1023200141d0006a41086a20052903002206370300200120012903c801220d3703502003200d370000200341086a20063700002007200429030037030020092003290300370300200a2002290300370300200120012903a801370378200141c8016a200141f8006a4120108a010240024020012d00c8014101460d00200141106a41086a4200370300200141106a41106a4200370300200141106a41186a4200370300200141a8016a41186a200141e1016a290000370300200141a8016a41106a200141d9016a290000370300200141a8016a41086a200141d1016a290000370300200120012900c9013703a801200142003703100c010b20081005200141a8016a41186a200141e1016a2900002206370300200141a8016a41106a200141d9016a290000220d370300200141a8016a41086a200141d1016a290000220e370300200141106a41086a200e370300200141106a41106a200d370300200141106a41186a2006370300200120012900c90122063703a801200120063703100b200141a8016a41186a22024200370300200141a8016a41106a22074200370300200141a8016a41086a22044200370300200142003703a801200141c8016a41086a220541c4fbc400ad4280808080e00084220d1003220941086a290000370300200120092900003703c8012009102320042005290300370300200120012903c801220637039801200120063703a80120054197bdc000ad4280808080e000841003220941086a290000370300200120092900003703c80120091023200141d0006a41086a221120052903002206370300200120012903c801220e3703502003200e370000200341086a22122006370000200141f8006a41086a22132004290300370300200141f8006a41106a22142007290300370300200141f8006a41186a22152002290300370300200120012903a801370378200141c8016a200141f8006a108c010240024020012802c80122090d0041042109420021060c010b2008100520012902cc0121060b200f410020101b210a200242003703002007420037030020044200370300200142003703a8012005200d1003220c41086a2900003703002001200c2900003703c801200c102320042005290300370300200120012903c801220d370398012001200d3703a80120054189bdc000ad4280808080e001841003220c41086a2900003703002001200c2900003703c801200c102320112005290300220d370300200120012903c801220e3703502003200e3700002012200d370000201320042903003703002014200729030037030020152002290300370300200120012903a801370378200141c8016a200141f8006a4120108a010240024020012d00c8014101460d00200141306a41086a4200370300200141306a41106a4200370300200141306a41186a4200370300200141a8016a41186a200141e1016a290000370300200141a8016a41106a200141d9016a290000370300200141a8016a41086a200141d1016a290000370300200120012900c9013703a801200142003703300c010b20081005200141a8016a41186a200141e1016a2900002208370300200141a8016a41106a200141d9016a290000220d370300200141a8016a41086a200141d1016a290000220e370300200141306a41086a200e370300200141306a41106a200d370300200141306a41186a2008370300200120012900c90122083703a801200120083703300b02400240024002400240200a41fb01490d00200a41857e6a2203450d00200141c8016a41086a220541c4fbc400ad4280808080e000841003220441086a290000370300200120042900003703c8012004102320014198016a41086a22022005290300370300200120012903c80137039801200541f0bcc000ad42808080809001841003220441086a290000370300200120042900003703c80120041023200141d0006a41086a22072005290300370300200120012903c80137035020012003360278200141c8016a41186a2203200b4280808080c000841001220441186a290000370300200141c8016a41106a220c200441106a2900003703002005200441086a290000370300200120042900003703c80120041023200141a8016a41186a22042003290300370300200141a8016a41106a2203200c290300370300200141a8016a41086a220c2005290300370300200120012903c8013703a80141c00010212205450d01200520012903980137000020052001290350370010200520012903a801370020200541086a2002290300370000200541186a2007290300370000200541286a200c290300370000200541306a2003290300370000200541386a20042903003700002005ad42808080808008841005200510230b1006210841002105200141003a00e8012008422088a721022008a722072104034020022005460d04200141c8016a20056a20042d00003a00002001200541016a22033a00e801200441016a21042003210520034120470d000b200141d0006a41086a200141c8016a41086a290300370300200141d0006a41106a200141c8016a41106a290300370300200141d0006a41186a200141c8016a41186a290300370300200120012903c80137035002402002450d00200710230b200141003602d001200142013703c8012001200141c8016a3602a801200141106a200141a8016a106b20012802cc01210520014198016a20013502d00142208620012802c8012204ad84100710900102402005450d00200410230b02402001280298012203450d00200141a0016a2802002102200128029c01210c41002105200141003a00e8010340024020022005470d000240200541ff0171450d00200141003a00e8010b419fdcc000412c200141c8016a41b0bdc0001031000b200141c8016a20056a200320056a2d00003a00002001200541016a22043a00e8012004210520044120470d000b200141f8006a41086a200141c8016a41086a22042903002208370300200141f8006a41106a200141c8016a41106a2202290300220d370300200141f8006a41186a200141c8016a41186a2207290300220e370300200120012903c801220b370378200420083703002002200d3703002007200e3703002001200b3703c801200141a8016a41026a220f200141f5006a41026a2d00003a0000200120012f00753b01a8010240024020064220882208a722052006a7460d002006210d0c010b200541016a22102005490d042008a74101742211201020102011491bad220d42247e2208422088a70d042008a722104100480d040240024020050d002010102121090c010b2009200541246c2010102521090b2009450d0320064220882208a721050b2009200541246c6a220541003a0000200520012903c801370001200541096a2004290300370000200541116a2002290300370000200541196a2007290300370000200520012f01a8013b0021200541236a200f2d00003a00002008422086200d42ffffffff0f83844280808080107c2106200c450d00200310230b200020012903103700102000200a36020020002001290350370030200041286a200141106a41186a290300370000200041206a200141106a41106a290300370000200041186a200141106a41086a290300370000200041386a200141d0006a41086a290300370000200041c0006a200141d0006a41106a290300370000200041c8006a200141d0006a41186a290300370000200041086a200637020020002009360204200041e8006a200141306a41186a290300370000200041e0006a200141306a41106a290300370000200041d8006a200141306a41086a29030037000020002001290330370050200141f0016a24000f0b41c00041011030000b201041041030000b102a000b0240200541ff0171450d00200141003a00e8010b419fdcc000412c200141c8016a41b0bdc0001031000b820803037f047e067f230022022103200241c0036b41607122022400200141186a22042900002105200420022903b80237000020012900102106200120022903b00237001020012900082107200120022903a802370008200241003a00a00220012900002108200120022903a002370000200220053703b801200220063703b001200220073703a801200220083703a001200141206a2d00002104200241a0026a41176a22092005370000200241a0026a41106a220a20022900b101370300200241a0026a41086a220b20022900a901370300200220022900a1013703a002024002402008a741ff01714101460d00200041073a00400c010b200241106a41176a2009290000370000200241106a41106a200a290300370300200241106a41086a200b290300370300200220022903a002370310200220043a002f20024190026a200241106a109d01200241a0026a2002280290022204200228029802109e01024020022d00c1024102470d00200241003602a0032002420137039803200241306a41146a410f3602002002413c6a410c360200200241093602ac03200241aefcc4003602a8032002410c3602342002410b3602b403200241b2edc0003602b003200220024190026a3602402002200241b0036a3602382002200241a8036a360230200220024198036a3602bc03200241d8006a41146a41033602002002420337025c200241ccdcc0003602582002200241306a360268200241bc036a41b8a3c500200241d8006a102e1a20023502a003422086200235029803841008200041073a00400240200228029c03450d0020022802980310230b200228029402450d012002280290021023200324000f0b200241a0016a200241a0026a41e30010dc041a0240200228029402450d00200410230b200241306a41206a2204200241a0026a41206a2d00003a0000200241306a41186a2209200241a0026a41186a220a290300370300200241306a41106a220b200241a0026a41106a220c290300370300200241306a41086a220d200241a0026a41086a220e290300370300200220022903a002370330200241d8006a200241c1016a41c20010dc041a200141206a200241d8006a41c1006a2d00003a0000200141186a20024191016a290000370000200141106a20024189016a290000370000200141086a20024181016a29000037000020012002290079370000200a200241106a41186a290300370300200c200241106a41106a290300370300200e200241106a41086a290300370300200220022903103703a002200241c8026a200d290300370300200241d0026a200b290300370300200241d8026a2009290300370300200241e0026a20042d00003a0000200220022903303703c0022000200241a0026a41c10010dc041a200324000f0b200324000bc20201057f230041c0006b22022400200241206a41086a220341aefcc400ad42808080809001841003220441086a2900003703002002200429000037032020041023200241086a2205200329030037030020022002290320370300200341b2edc000ad4280808080b001841003220441086a2900003703002002200429000037032020041023200241106a41086a2206200329030037030020022002290320370310200241206a200110ac01024041c000102122040d0041c00041011030000b200420022903003700002004200229031037001020042002290020370020200042c0808080800837020420002004360200200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241306a290000370000200441386a200241206a41186a290000370000200241c0006a24000bee0d03077f017e067f230041c0026b220324002003200236020420032001360200200341086a2002ad4220862001ad84100410900102400240200328020822040d00200041023a00210c010b200341106a2802002105200328020c210641002101200341003a00b8022005417e6a21070240024002400340024020052001470d00200141ff0171450d02200341003a00b8020c020b20034198026a20016a200420016a2d00003a00002003200141016a22023a00b8022007417f6a21072002210120024120470d000b200341f8016a41186a20034198026a41186a290300370300200341f8016a41106a20034198026a41106a290300370300200341f8016a41086a20034198026a41086a29030037030020032003290398023703f80120052002460d00200420026a22082d0000220941074f0d00200341f8006a41186a200341f8016a41186a290300370300200341f8006a41106a200341f8016a41106a290300370300200341f8006a41086a200341f8016a41086a290300370300200320032903f8013703782005417f6a2002460d00200841016a2d0000220141014b0d00200520026b210202400240024020010e020100010b41002101200341003a00b8022002417e6a21050340024020052001470d00200141ff0171450d04200341003a00b8020c040b20034198026a20016a200820016a41026a2d00003a00002003200141016a22023a00b8022002210120024120470d000b200341d8016a41086a20034198026a41086a290300220a370300200341b8016a41186a20034198026a41186a290300370300200341b8016a41106a20034198026a41106a290300370300200341b8016a41086a200a3703002003200329039802220a3703d8012003200a3703b801200720026b2107200820026a41026a2105410121010c010b200841026a21052002417e6a2107410021010b20034198016a41186a200341b8016a41186a29030037030020034198016a41106a200341b8016a41106a29030037030020034198016a41086a200341b8016a41086a290300370300200320032903b801370398012007450d0020052d0000220241014b0d00410021080240024020020e020100010b41002102200341003a00b802200541016a21082007417f6a21050340024020052002470d00200241ff0171450d03200341003a00b8020c030b20034198026a20026a200820026a2d00003a00002003200241016a22073a00b8022007210220074120470d000b200341d8016a41086a20034198026a41086a290300220a370300200341b8016a41186a20034198026a41186a290300370300200341b8016a41106a20034198026a41106a290300370300200341b8016a41086a200a3703002003200329039802220a3703d8012003200a3703b801410121080b200341186a41186a2202200341b8016a41186a290300370300200341186a41106a2207200341b8016a41106a290300370300200341186a41086a2205200341b8016a41086a290300370300200341386a41086a220b20034198016a41086a290300370300200341386a41106a220c20034198016a41106a290300370300200341386a41186a220d20034198016a41186a290300370300200320032903b8013703182003200329039801370338200341d8006a41186a220e200341f8006a41186a290300370300200341d8006a41106a220f200341f8006a41106a290300370300200341d8006a41086a2210200341f8006a41086a2903003703002003200329037837035820014102460d0120002003290358370000200020093a0020200041186a200e290300370000200041106a200f290300370000200041086a201029030037000020034198026a41086a2209200b29030037030020034198026a41106a220b200c29030037030020034198026a41186a220c200d2903003703002003200329033837039802200341f8016a41186a220d2002290300370300200341f8016a41106a22022007290300370300200341f8016a41086a22072005290300370300200320032903183703f8012000413a6a200c290300370000200041326a200b2903003700002000412a6a20092903003700002000200329039802370022200041c2006a20083a0000200041c3006a20032903f801370000200041cb006a2007290300370000200041d3006a2002290300370000200041db006a200d2903003700000c020b410221010b2003410036028002200342013703f8012003410c3602dc01200320033602d8012003200341f8016a3602b801200341ac026a41013602002003420137029c0220034198c2c300360298022003200341d8016a3602a802200341b8016a41b8a3c50020034198026a102e1a20033502800242208620033502f80184100820032802fc01450d0020032802f80110230b200020013a00212006450d00200410230b200341c0026a24000bbd0101047f230041106b22022400200028020421032000280200210041012104200128021841b5adc00041012001411c6a28020028020c1100002105200241003a0005200220053a00042002200136020002402003450d0003402002200036020c20022002410c6a41a0bdc00010561a200041016a21002003417f6a22030d000b20022d000421050b0240200541ff01710d002002280200220028021841b6adc00041012000411c6a28020028020c11000021040b200241106a240020040bbe0703037f047e037f23002202210320024180036b41607122022400200141186a22042900002105200420022903f80137000020012900102106200120022903f00137001020012900082107200120022903e801370008200241003a00e00120012900002108200120022903e0013700002002200537039801200220063703900120022007370388012002200837038001200141206a2d00002104200241e0016a41176a22092005370000200241e0016a41106a220a200229009101370300200241e0016a41086a220b20022900890137030020022002290081013703e001024002402008a741ff01714101460d00200041003602200c010b200241186a41176a2009290000370000200241186a41106a200a290300370300200241186a41086a200b290300370300200220022903e001370318200220043a0037200241d0016a200241186a10a101200241e0016a20022802d001220420022802d80110a201024020022d00ec014102470d00200241003602c802200242013703c002200241d0026a41146a410f360200200241dc026a410c360200200241103602ec022002419da0c2003602e8022002410c3602d402200241073602f402200241ada0c2003602f0022002200241d0016a3602e0022002200241f0026a3602d8022002200241e8026a3602d0022002200241c0026a3602fc02200241386a41146a41033602002002420337023c200241ccdcc0003602382002200241d0026a360248200241fc026a41b8a3c500200241386a102e1a20023502c80242208620023502c00284100820004100360220024020022802c402450d0020022802c00210230b20022802d401450d0120022802d0011023200324000f0b20024180016a200241e0016a41d00010dc041a024020022802d401450d00200410230b200241d0026a41086a220420024180016a41086a28020036020020022002290380013703d002200241386a2002418c016a41c20010dc041a200141206a200241f9006a2d00003a0000200141186a200241f1006a290000370000200141106a200241e9006a290000370000200141086a200241e1006a29000037000020012002290059370000200241e0016a41186a200241186a41186a2903002205370300200241e0016a41106a200241186a41106a2903002208370300200241e0016a41086a200241186a41086a2903002206370300200020022903182207370200200041086a2006370200200041106a2008370200200041186a2005370200200220073703e001200041206a20022903d002370200200041286a2004280200360200200324000f0b200324000bc20201057f230041c0006b22022400200241206a41086a2203419da0c200ad42808080808002841003220441086a2900003703002002200429000037032020041023200241086a2205200329030037030020022002290320370300200341ada0c200ad4280808080f000841003220441086a2900003703002002200429000037032020041023200241106a41086a2206200329030037030020022002290320370310200241206a200110ac01024041c000102122040d0041c00041011030000b200420022903003700002004200229031037001020042002290020370020200042c0808080800837020420002004360200200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241306a290000370000200441386a200241206a41186a290000370000200241c0006a24000be70b030a7f017e027f230041a0026b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022040d00200041023a000c0c010b200328021421052003200341106a41086a28020036026420032004360260200341e8006a200341e0006a107e02400240024020032802682206450d00200328026c2107024020032802642201450d00200341e8006a41086a280200210820032001417f6a220936026420032003280260220a41016a220b360260200a2d0000220141014b0d004100210c0240024020010e020100010b41002101200341003a0098020340024020092001470d0020034100360264200141ff0171450d03200341003a0098020c030b200341f8016a20016a200a20016a220241016a2d00003a00002003200241026a3602602003200141016a22023a0098022002210120024120470d000b200341b8016a41086a200341f8016a41086a290300220d37030020034198016a41186a200341f8016a41186a29030037030020034198016a41106a200341f8016a41106a29030037030020034198016a41086a200d3703002003200920026b2209360264200320032903f801220d3703b8012003200d370398014101210c200a20026a41016a210b0b200341f8006a41186a20034198016a41186a290300370300200341f8006a41106a20034198016a41106a290300370300200341f8006a41086a20034198016a41086a29030037030020032003290398013703782009450d0020032009417f6a22093602642003200b41016a360260200b2d0000220141014b0d00410021020240024020010e020100010b41002101200341003a0098020340024020092001470d0020034100360264200141ff0171450d03200341003a0098020c030b200341f8016a20016a200b20016a220241016a2d00003a00002003200241026a3602602003200141016a22023a0098022002210120024120470d000b200341b8016a41086a200341f8016a41086a290300220d37030020034198016a41186a200341f8016a41186a29030037030020034198016a41106a200341f8016a41106a29030037030020034198016a41086a200d3703002003200920026b360264200320032903f801220d3703b8012003200d37039801410121020b200341206a41186a220120034198016a41186a290300370300200341206a41106a220920034198016a41106a290300370300200341206a41086a220a20034198016a41086a290300370300200341c0006a41086a220b200341f8006a41086a290300370300200341c0006a41106a220e200341f8006a41106a290300370300200341c0006a41186a220f200341f8006a41186a290300370300200320032903980137032020032003290378370340200c4102460d02200020083602082000200736020420002006360200200341f8016a41086a2206200b290300370300200341f8016a41106a220b200e290300370300200341f8016a41186a2207200f290300370300200341d8016a41086a2208200a290300370300200341d8016a41106a220a2009290300370300200341d8016a41186a22092001290300370300200320032903403703f801200320032903203703d801200320032f011e3b01b801200041256a20072903003700002000411d6a200b290300370000200041156a2006290300370000200020032903f80137000d2000412d6a20023a00002000412e6a20032903d801370000200041366a20082903003700002000413e6a200a290300370000200041c6006a2009290300370000200041ce006a20032f01b8013b00000c030b2007450d00200610230b4102210c0b200341003602e001200342013703d8012003410c3602bc012003200341086a3602b8012003200341d8016a360298012003418c026a4101360200200342013702fc0120034198c2c3003602f8012003200341b8016a3602880220034198016a41b8a3c500200341f8016a102e1a20033502e00142208620033502d80184100820032802dc01450d0020032802d80110230b2000200c3a000c2005450d00200410230b200341a0026a24000baf0603037f047e037f230022022103200241a0026b41607122022400200141186a220429000021052004200229039801370000200129001021062001200229039001370010200129000821072001200229038801370008200241003a00800120012900002108200120022903800137000020022005370338200220063703302002200737032820022008370320200141206a2d0000210420024180016a41176a2209200537000020024180016a41106a220a200229003137030020024180016a41086a220b20022900293703002002200229002137038001024002402008a741ff01714101460d00200041003602000c010b200241176a2009290000370000200241106a200a290300370300200241086a200b2903003703002002200229038001370300200220043a001f200241f0006a200210a40120024180016a20022802702204200228027810a501024020022d0084014102470d00200241003602e801200242013703e001200241f0016a41146a410f360200200241fc016a410c3602002002410736028c02200241c6acc500360288022002410c3602f4012002410a36029402200241e7acc500360290022002200241f0006a36028002200220024190026a3602f801200220024188026a3602f0012002200241e0016a36029c02200241206a41146a410336020020024203370224200241ccdcc0003602202002200241f0016a3602302002419c026a41b8a3c500200241206a102e1a20023502e80142208620023502e00184100820004100360200024020022802e401450d0020022802e00110230b2002280274450d0120022802701023200324000f0b20024180016a4104722109200228028001210a02402002280274450d00200410230b200241206a200941c20010dc041a200141206a200241e1006a2d00003a0000200141186a200241d9006a290000370000200141106a200241d1006a290000370000200141086a200241c9006a29000037000020012002290041370000200020022903003700042000410c6a200241086a290300370000200041146a200241106a2903003700002000411c6a200241186a29030037000020004101360200200041246a200a360200200324000f0b200324000bc20201057f230041c0006b22022400200241206a41086a220341c6acc500ad4280808080f000841003220441086a2900003703002002200429000037032020041023200241086a2205200329030037030020022002290320370300200341e7acc500ad4280808080a001841003220441086a2900003703002002200429000037032020041023200241106a41086a2206200329030037030020022002290320370310200241206a200110ac01024041c000102122040d0041c00041011030000b200420022903003700002004200229031037001020042002290020370020200042c0808080800837020420002004360200200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241306a290000370000200441386a200241206a41186a290000370000200241c0006a24000bbc0b03097f017e027f23004190026b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022040d00200041023a00040c010b200328021421052003200341186a280200360264200320043602602003200341e0006a106e4102210602400240024020032802000d0020032802642201450d002003280204210720032001417f6a220836026420032003280260220941016a220a36026020092d0000220141014b0d004100210b0240024020010e020100010b41002101200341003a0088020340024020082001470d0020034100360264200141ff0171450d03200341003a0088020c030b200341e8016a20016a200920016a220241016a2d00003a00002003200241026a3602602003200141016a22023a0088022002210120024120470d000b200341a8016a41086a200341e8016a41086a290300220c37030020034188016a41186a200341e8016a41186a29030037030020034188016a41106a200341e8016a41106a29030037030020034188016a41086a200c3703002003200820026b2208360264200320032903e801220c3703a8012003200c370388014101210b200920026a41016a210a0b200341e8006a41186a20034188016a41186a290300370300200341e8006a41106a20034188016a41106a290300370300200341e8006a41086a20034188016a41086a29030037030020032003290388013703682008450d0020032008417f6a22083602642003200a41016a360260200a2d0000220141014b0d00410021020240024020010e020100010b41002101200341003a0088020340024020082001470d0020034100360264200141ff0171450d03200341003a0088020c030b200341e8016a20016a200a20016a220241016a2d00003a00002003200241026a3602602003200141016a22023a0088022002210120024120470d000b200341a8016a41086a200341e8016a41086a290300220c37030020034188016a41186a200341e8016a41186a29030037030020034188016a41106a200341e8016a41106a29030037030020034188016a41086a200c3703002003200820026b360264200320032903e801220c3703a8012003200c37038801410121020b200341206a41186a220120034188016a41186a290300370300200341206a41106a220620034188016a41106a290300370300200341206a41086a220820034188016a41086a290300370300200341c0006a41086a2209200341e8006a41086a290300370300200341c0006a41106a220a200341e8006a41106a290300370300200341c0006a41186a220d200341e8006a41186a290300370300200320032903880137032020032003290368370340200b4102470d01200b21060b200341003602d001200342013703c8012003410c3602ac012003200341086a3602a8012003200341c8016a36028801200341fc016a4101360200200342013702ec0120034198c2c3003602e8012003200341a8016a3602f80120034188016a41b8a3c500200341e8016a102e1a20033502d00142208620033502c80184100820032802cc01450d0120032802c80110230c010b200341e8016a41186a220e200d290300370300200341e8016a41106a220d200a290300370300200341e8016a41086a220a2009290300370300200341c8016a41086a22092008290300370300200341c8016a41106a22082006290300370300200341c8016a41186a22062001290300370300200320032903403703e801200320032903203703c801200320032f011e3b01a80120002007360200200020032903e8013700052000410d6a200a290300370000200041156a200d2903003700002000411d6a200e290300370000200041256a20023a0000200041266a20032903c8013700002000412e6a2009290300370000200041366a20082903003700002000413e6a2006290300370000200041c6006a20032f01a8013b0000200b21060b200020063a00042005450d00200410230b20034190026a24000be50703037f047e037f230022022103200241a0036b41607122022400200141186a220429000021052004200229039802370000200129001021062001200229039002370010200129000821072001200229038802370008200241003a0080022001290000210820012002290380023700002002200537039801200220063703900120022007370388012002200837038001200141206a2d0000210420024180026a41176a2209200537000020024180026a41106a220a20022900910137030020024180026a41086a220b200229008901370300200220022900810137038002024002402008a741ff01714101460d00200041023a00300c010b200241186a41176a2009290000370000200241186a41106a200a290300370300200241186a41086a200b2903003703002002200229038002370318200220043a0037200241f0016a200241186a10a70120024180026a20022802f001220420022802f80110a801024020022d0090024102470d00200241003602e802200242013703e002200241f0026a41146a410f360200200241fc026a410c3602002002410736028c03200241c6acc500360288032002410c3602f4022002410a36029403200241cdacc500360290032002200241f0016a36028003200220024190036a3602f802200220024188036a3602f0022002200241e0026a36029c03200241386a41146a41033602002002420337023c200241ccdcc0003602382002200241f0026a3602482002419c036a41b8a3c500200241386a102e1a20023502e80242208620023502e002841008200041023a0030024020022802e402450d0020022802e00210230b20022802f401450d0120022802f0011023200324000f0b20024180016a20024180026a41d80010dc041a024020022802f401450d00200410230b200241f0026a41106a220420024180016a41106a280200360200200241f0026a41086a220920024180016a41086a29030037030020022002290380013703f002200241386a20024194016a41c20010dc041a200141206a200241f9006a2d00003a0000200141186a200241f1006a290000370000200141106a200241e9006a290000370000200141086a200241e1006a2900003700002001200229005937000020024180026a41186a200241186a41186a290300220537030020024180026a41106a200241186a41106a290300220837030020024180026a41086a200241186a41086a2903002206370300200020022903182207370200200041086a2006370200200041106a2008370200200041186a20053702002002200737038002200041206a20022903f002370200200041286a2009290300370200200041306a2004280200360200200324000f0b200324000bc20201057f230041c0006b22022400200241206a41086a220341c6acc500ad4280808080f000841003220441086a2900003703002002200429000037032020041023200241086a2205200329030037030020022002290320370300200341cdacc500ad4280808080a001841003220441086a2900003703002002200429000037032020041023200241106a41086a2206200329030037030020022002290320370310200241206a200110ac01024041c000102122040d0041c00041011030000b200420022903003700002004200229031037001020042002290020370020200042c0808080800837020420002004360200200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241306a290000370000200441386a200241206a41186a290000370000200241c0006a24000b930e030c7f017e037f230041a0026b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022010d00200041023a00100c010b200328021421042003200341106a41086a28020036026c20032001360268200341f8016a200341e8006a107e02400240024020032802f8012205450d0020032802fc01210602400240200328026c22074104490d00200341f8016a41086a280200210820032007417c6a220236026c20032003280268220941046a220a3602680240024002402002450d002009280000210b20032007417b6a220c36026c2003200a41016a360268200a2d0000220d41014b0d0041002102200d0e020201020b2006450d040c030b410121020b200341f4006a41026a200341d8016a41026a2d00003a0000200320032f00d8013b01740240200c450d0020032007417a6a220c36026c2003200a41026a220d360268200a2d0001220a41014b0d004100210e02400240200a0e020100010b4100210a200341003a0098022007417a6a210e4179210c03400240200e200a470d00200a41ff0171450d03200341003a0098020c030b200341f8016a200a6a2009200a6a220d41066a2d00003a000020032007200c6a36026c2003200d41076a3602682003200a41016a220d3a009802200c417f6a210c200d210a200d4120470d000b200341b8016a41086a200341f8016a41086a290300220f37030020034198016a41186a200341f8016a41186a29030037030020034198016a41106a200341f8016a41106a29030037030020034198016a41086a200f370300200320032903f801220f3703b8012003200f370398012007200d6b417a6a210c2009200d6a41066a210d4101210e0b200341f8006a41186a20034198016a41186a290300370300200341f8006a41106a20034198016a41106a290300370300200341f8006a41086a20034198016a41086a2903003703002003200329039801370378200c450d002003200c417f6a36026c2003200d41016a360268200d2d0000220a41014b0d004100210702400240200a0e020100010b4100210a200341003a009802200c417f6a2109200c417e6a2107034002402009200a470d00200a41ff0171450d03200341003a00980220060d050c060b200341f8016a200a6a200d200a6a220c41016a2d00003a00002003200c41026a3602682003200a41016a220c3a0098022003200736026c2007417f6a2107200c210a200c4120470d000b200341b8016a41086a200341f8016a41086a290300220f37030020034198016a41186a200341f8016a41186a29030037030020034198016a41106a200341f8016a41106a29030037030020034198016a41086a200f370300200320032903f801220f3703b8012003200f37039801410121070b200341206a41186a220a20034198016a41186a290300370300200341206a41106a220c20034198016a41106a290300370300200341206a41086a220d20034198016a41086a290300370300200341c0006a41086a2209200341f8006a41086a290300370300200341c0006a41106a2210200341f8006a41106a290300370300200341c0006a41186a2211200341f8006a41186a290300370300200320032903980137032020032003290378370340200341e4006a41026a2212200341f4006a41026a2d00003a0000200320032f01743b016420024102460d042000200b36020c200020083602082000200636020420002005360200200341b8016a41026a220520122d00003a0000200341f8016a41086a22062009290300370300200341f8016a41106a22092010290300370300200341f8016a41186a22082011290300370300200341d8016a41086a220b200d290300370300200341d8016a41106a220d200c290300370300200341d8016a41186a220c200a290300370300200320032f01643b01b801200320032903403703f801200320032903203703d801200320032f011e3b019801200041136a20052d00003a0000200020032f01b8013b0011200041146a200e3a0000200041156a20032903f8013700002000411d6a2006290300370000200041256a20092903003700002000412d6a2008290300370000200041356a20073a0000200041366a20032903d8013700002000413e6a200b290300370000200041c6006a200d290300370000200041ce006a200c290300370000200041d6006a20032f0198013b00000c050b20060d010c020b2006450d010b200510230b410221020b200341003602e001200342013703d8012003410c3602bc012003200341086a3602b8012003200341d8016a360298012003418c026a4101360200200342013702fc0120034198c2c3003602f8012003200341b8016a3602880220034198016a41b8a3c500200341f8016a102e1a20033502e00142208620033502d80184100820032802dc01450d0020032802d80110230b200020023a00102004450d00200110230b200341a0026a24000bd50501037f024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d07200241017422042003200420034b1b22044100480d070240024020020d002004102121030c010b200128020020022004102521030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a00000c010b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d06200241017422042003200420034b1b22044100480d060240024020020d002004102121030c010b200128020020022004102521030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041016a200110710b024020002d00214101460d0002400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d06200041017422032002200320024b1b22034100480d060240024020000d002003102121020c010b200128020020002003102521020b2002450d0420012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41003a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d05200241017422042003200420034b1b22044100480d050240024020020d002004102121030c010b200128020020022004102521030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041226a200110710f0b200441011030000b200441011030000b200341011030000b200441011030000b102a000bc00501047f200141046a2802002102200141086a28020021030240024002400240024002400240200028020022040d000240024020022003460d00200128020021020c010b200341016a22022003490d07200341017422042002200420024b1b22044100480d070240024020030d002004102121020c010b200128020020032004102521020b2002450d0320012002360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200220036a41003a00000c010b0240024020022003460d00200128020021020c010b200341016a22022003490d06200341017422052002200520024b1b22054100480d060240024020030d002005102121020c010b200128020020032005102521020b2002450d0320012002360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200220036a41013a00002004280200200110710b200141046a2802002102200141086a28020021030240200028020422040d000240024020022003460d00200128020021000c010b200341016a22002003490d06200341017422022000200220004b1b22024100480d060240024020030d002002102121000c010b200128020020032002102521000b2000450d0420012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000f0b0240024020022003460d00200128020021000c010b200341016a22002003490d05200341017422022000200220004b1b22024100480d050240024020030d002002102121000c010b200128020020032002102521000b2000450d0420012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41013a00002004200110710f0b200441011030000b200541011030000b200241011030000b200241011030000b102a000bc00201057f230041c0006b22012400200141206a41086a220241c4fbc400ad4280808080e000841003220341086a2900003703002001200329000037032020031023200141086a2204200229030037030020012001290320370300200241e4bcc000ad4280808080c001841003220341086a2900003703002001200329000037032020031023200141106a41086a2205200229030037030020012001290320370310200141206a200010ac01024041c000102122030d0041c00041011030000b200320012903003700002003200129031037001020032001290020370020200341086a2004290300370000200341186a2005290300370000200341286a2002290000370000200341306a200141306a290000370000200341386a200141206a41186a2900003700002003ad4280808080800884100520031023200141c0006a24000bf90401057f230041206b2202240020012d00002103024002400240024002400240410110212204450d00200420033a000020012d0001210320044101410210252204450d01200420033a000120012d0002210320044102410410252204450d02200420033a0002200420012d00033a000320012d0004210320044104410810252204450d03200420033a0004200420012d00053a0005200420012d00063a0006200420012d00073a000720012d0008210320044108411010252204450d04200420033a0008200420012d00093a0009200420012d000a3a000a200420012d000b3a000b200420012d000c3a000c200420012d000d3a000d200420012d000e3a000e200420012d000f3a000f20012d0010210320044110412010252204450d05200420033a0010200420012d00113a0011200420012d00123a0012200420012d00133a0013200420012d00143a0014200420012d00153a0015200420012d00163a0016200420012d00173a0017200420012d00183a0018200420012d00193a0019200420012d001a3a001a200420012d001b3a001b200420012d001c3a001c200420012d001d3a001d200420012d001e3a001e200420012d001f3a001f200241186a22032004ad42808080808004841001220141186a290000370300200241106a2205200141106a290000370300200241086a2206200141086a2900003703002002200129000037030020011023200041186a2003290300370000200041106a2005290300370000200041086a20062903003700002000200229030037000020041023200241206a24000f0b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000b040041020b890401077f230041306b22022400200241003602082002420137030020022002360210200141106a200241106a106b2001200210af0120022002360210200141306a200241106a106b20022002360210200141d0006a200241106a106b200128020421032001410c6a28020022012002105c0240024002402001450d00200141246c21040340200241106a200310b001200228021021050240024020022802042206200228020822016b20022802182207490d00200228020021060c010b200120076a22082001490d04200641017422012008200120084b1b22014100480d040240024020060d002001102121060c010b200228020020062001102521060b2006450d032002200136020420022006360200200228020821010b2002200120076a360208200620016a2005200710dc041a02402002280214450d00200510230b200341246a21032004415c6a22040d000b0b20022802042107200241106a41186a2203200235020842208620022802002204ad841001220141186a290000370300200241106a41106a2206200141106a290000370300200241106a41086a2205200141086a2900003703002002200129000037031020011023200041186a2003290300370000200041106a2006290300370000200041086a20052903003700002000200229031037000002402007450d00200410230b200241306a24000f0b200141011030000b102a000b9e0701037f02400240024002400240024020002802002202413f4b0d0002400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d06200041017422042003200420034b1b22044100480d060240024020000d002004102121030c010b200128020020002004102521030b2003450d0220012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20024102743a00000f0b200241808001490d032002418080808004490d020c010b200441011030000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d05200241017422042003200420034b1b22044100480d050240024020020d002004102121030c010b200128020020022004102521030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280200210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d05200241017422002004200020044b1b22004100480d050240024020020d002000102121020c010b200128020020022000102521020b2002450d0220012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b200441011030000b200041011030000b024002400240200141046a2802002203200141086a28020022006b4104490d00200128020021030c010b200041046a22042000490d03200341017422002004200020044b1b22004100480d030240024020030d002000102121030c010b200128020020032000102521030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20024102744102723600000f0b200041011030000b024002400240200141046a2802002203200141086a28020022006b4102490d00200128020021030c010b200041026a22042000490d02200341017422002004200020044b1b22004100480d020240024020030d002000102121030c010b200128020020032000102521030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20024102744101723b00000f0b200041011030000b102a000bde1601067f230041106b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e050003010204000b2002410036020820024201370300410110212203450d05200242818080801037020420022003360200200341023a00002002200236020c200141016a2002410c6a106b0c040b2002410036020820024201370300410110212203450d05200242818080801037020420022003360200200341043a000020012d0001210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d1a200341017422062005200620054b1b22064100480d1a0240024020030d002006102121050c010b200228020020032006102521050b2005450d0720022006360204200220053602000b2002200341016a360208200520036a20043a000020012d0002210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d1a200341017422062005200620054b1b22064100480d1a0240024020030d002006102121050c010b200228020020032006102521050b2005450d0820022006360204200220053602000b2002200341016a360208200520036a20043a000020012d0003210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d1a200341017422062005200620054b1b22064100480d1a0240024020030d002006102121050c010b200228020020032006102521050b2005450d0920022006360204200220053602000b2002200341016a360208200520036a20043a000020012d0004210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d1a200341017422062005200620054b1b22064100480d1a0240024020030d002006102121050c010b200228020020032006102521050b2005450d0a20022006360204200220053602000b2002200341016a360208200520036a20043a000020012802082104200141106a28020022012002105c0240024020022802042205200228020822036b2001490d00200228020021050c010b200320016a22062003490d1a200541017422072006200720064b1b22064100480d1a0240024020050d002006102121050c010b200228020020052006102521050b2005450d0b20022006360204200220053602000b2002200320016a360208200520036a2004200110dc041a0c030b2002410036020820024201370300410110212203450d0a200242818080801037020420022003360200200341053a000020012d0001210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d19200341017422062005200620054b1b22064100480d190240024020030d002006102121050c010b200228020020032006102521050b2005450d0c20022006360204200220053602000b2002200341016a360208200520036a20043a000020012d0002210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d19200341017422062005200620054b1b22064100480d190240024020030d002006102121050c010b200228020020032006102521050b2005450d0d20022006360204200220053602000b2002200341016a360208200520036a20043a000020012d0003210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d19200341017422062005200620054b1b22064100480d190240024020030d002006102121050c010b200228020020032006102521050b2005450d0e20022006360204200220053602000b2002200341016a360208200520036a20043a000020012d0004210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d19200341017422062005200620054b1b22064100480d190240024020030d002006102121050c010b200228020020032006102521050b2005450d0f20022006360204200220053602000b2002200341016a360208200520036a20043a000020012802082104200141106a28020022012002105c0240024020022802042205200228020822036b2001490d00200228020021050c010b200320016a22062003490d19200541017422072006200720064b1b22064100480d190240024020050d002006102121050c010b200228020020052006102521050b2005450d1020022006360204200220053602000b2002200320016a360208200520036a2004200110dc041a0c020b2002410036020820024201370300410110212203450d0f200242818080801037020420022003360200200341063a000020012d0001210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d18200341017422062005200620054b1b22064100480d180240024020030d002006102121050c010b200228020020032006102521050b2005450d1120022006360204200220053602000b2002200341016a360208200520036a20043a000020012d0002210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d18200341017422062005200620054b1b22064100480d180240024020030d002006102121050c010b200228020020032006102521050b2005450d1220022006360204200220053602000b2002200341016a360208200520036a20043a000020012d0003210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d18200341017422062005200620054b1b22064100480d180240024020030d002006102121050c010b200228020020032006102521050b2005450d1320022006360204200220053602000b2002200341016a360208200520036a20043a000020012d0004210402400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d18200341017422062005200620054b1b22064100480d180240024020030d002006102121050c010b200228020020032006102521050b2005450d1420022006360204200220053602000b2002200341016a360208200520036a20043a000020012802082104200141106a28020022012002105c0240024020022802042205200228020822036b2001490d00200228020021050c010b200320016a22062003490d18200541017422072006200720064b1b22064100480d180240024020050d002006102121050c010b200228020020052006102521050b2005450d1520022006360204200220053602000b2002200320016a360208200520036a2004200110dc041a0c010b2002410036020820024201370300410110212203450d14200242818080801037020420022003360200200341003a0000200141046a28020021042001410c6a28020022012002105c0240024020022802042205200228020822036b2001490d00200228020021050c010b200320016a22062003490d17200541017422072006200720064b1b22064100480d170240024020050d002006102121050c010b200228020020052006102521050b2005450d1620022006360204200220053602000b2002200320016a360208200520036a2004200110dc041a0b200020022201290200370200200041086a200141086a280200360200200241106a24000f0b410141011030000b410141011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b410141011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b410141011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b410141011030000b200641011030000b102a000bea0b02097f027e230041106b22022400200028021021030240024002400240024002400240024002400240200141046a2802002204200141086a28020022056b4104490d00200128020021040c010b200541046a22062005490d08200441017422052006200520064b1b22054100480d080240024020040d002005102121040c010b200128020020042005102521040b2004450d0120012004360200200141046a2005360200200141086a28020021050b200141086a2206200541046a360200200420056a2003360000200041386a20011071200041d8006a2107410021040340200720046a2d0000210802400240200141046a220928020020062802002205460d00200128020021030c010b200541016a22032005490d092005410174220a2003200a20034b1b220a4100480d090240024020050d00200a102121030c010b20012802002005200a102521030b2003450d03200120033602002009200a360200200628020021050b2006200541016a360200200320056a20083a0000200441016a220441c000470d000b200028021421082000411c6a28020022052001105c02400240200141046a2802002203200141086a28020022046b2005490d00200128020021030c010b200420056a22062004490d08200341017422042006200420064b1b22044100480d080240024020030d002004102121030c010b200128020020032004102521030b2003450d0320012003360200200141046a2004360200200141086a28020021040b200141086a2206200420056a360200200320046a2008200510dc041a20002802202104200041286a28020022052001105c02402005450d002004200541246c6a210703402004280200210802400240200141046a22092802002203200628020022056b4104490d00200128020021030c010b200541046a220a2005490d0a20034101742205200a2005200a4b1b22054100480d0a0240024020030d002005102121030c010b200128020020032005102521030b2003450d062001200336020020092005360200200628020021050b2006200541046a360200200320056a200836000020022001360208200441046a200241086a106b200441246a22042007470d000b0b200041086a290300210b2000290300210c02400240200141046a2802002204200628020022056b4110490d00200128020021040c010b200541106a22032005490d08200441017422052003200520034b1b22054100480d080240024020040d002005102121040c010b200128020020042005102521040b2004450d0520012004360200200141046a2005360200200141086a28020021050b200141086a2206200541106a360200200420056a2205200b3700082005200c3700002002200136020c20004198016a2002410c6a106b200028022c2105200041346a28020022042001105c02402004450d0020044104742109034002402005410c6a2d000022044103714103460d004100210802400240024020040e03020001020b410121080c010b410221080b02400240200141046a220728020020062802002204460d00200128020021030c010b200441016a22032004490d0b2004410174220a2003200a20034b1b220a4100480d0b0240024020040d00200a102121030c010b20012802002004200a102521030b2003450d09200120033602002007200a360200200628020021040b2006200441016a360200200320046a20083a00000b2005280200210a200541086a28020022042001105c02400240200141046a22072802002208200628020022036b2004490d00200128020021080c010b200320046a22002003490d0a200841017422032000200320004b1b22034100480d0a0240024020080d002003102121080c010b200128020020082003102521080b2008450d092001200836020020072003360200200628020021030b200541106a21052006200320046a360200200820036a200a200410dc041a200941706a22090d000b0b200241106a24000f0b200541011030000b200a41011030000b200441011030000b200541011030000b200541011030000b200a41011030000b200341011030000b102a000bd9d20103067f027e017f230041106b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d0000220341124b0d00024002400240024002400240024002400240024002400240024002400240024002400240024020030e13000102030405060708090a0b0c0d0e0f101112000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f200341017422052004200520044b1b22054100480d5f0240024020030d002005102121040c010b200128020020032005102521040b2004450d1420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00000240024020002802044101460d00200241003a000c02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d61200341017422052004200520044b1b22054100480d610240024020030d002005102121040c010b200128020020032005102521040b2004450d1720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280208210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d61200441017422032005200320054b1b22034100480d610240024020040d002003102121040c010b200128020020042003102521040b2004450d1820012004360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200420036a20063600002000410c6a2103410721050c010b200241013a000c02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d60200341017422052004200520044b1b22054100480d600240024020030d002005102121040c010b200128020020032005102521040b2004450d1820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000410021040240200041106a2d00004101470d00200241013a000c02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d61200341017422062004200620044b1b22064100480d610240024020030d002006102121040c010b200128020020032006102521040b2004450d1a20012004360200200141046a2006360200200141086a28020021030b200141086a200341016a360200200420036a41013a000020002d001121040b200220043a000c02400240200141046a28020020052802002203460d00200128020021050c010b200341016a22052003490d60200341017422062005200620054b1b22064100480d600240024020030d002006102121050c010b200128020020032006102521050b2005450d1a20012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a20043a00002002200041126a2d000022053a000c02400240200141046a28020020062802002203460d00200128020021040c010b200341016a22042003490d60200341017422062004200620044b1b22064100480d600240024020030d002006102121040c010b200128020020032006102521040b2004450d1b20012004360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200420036a20053a00002000280214210502400240200141046a2802002204200628020022036b4104490d00200128020021040c010b200341046a22062003490d60200441017422032006200320064b1b22034100480d600240024020040d002003102121040c010b200128020020042003102521040b2004450d1c20012004360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200420036a2005360000200041186a2103411321050b200220032d000022063a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f200341017422072004200720044b1b22074100480d5f0240024020030d002007102121040c010b200128020020032007102521040b2004450d1c20012004360200200141046a2007360200200141086a28020021030b200141086a2207200341016a360200200420036a20063a00002002200020056a41066a2d000022043a000c02400240200141046a28020020072802002200460d00200128020021030c010b200041016a22032000490d5f200041017422052003200520034b1b22054100480d5f0240024020000d002005102121030c010b200128020020002005102521030b2003450d1d20012003360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200320006a20043a00000c120b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5e200341017422052004200520044b1b22054100480d5e0240024020030d002005102121040c010b200128020020032005102521040b2004450d1d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5e200341017422052004200520044b1b22054100480d5e0240024020030d002005102121040c010b200128020020032005102521040b2004450d1e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041086a200110712000280204210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5e200341017422002005200020054b1b22004100480d5e0240024020030d002000102121030c010b200128020020032000102521030b2003450d1f20012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c110b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5d200341017422052004200520044b1b22054100480d5d0240024020030d002005102121040c010b200128020020032005102521040b2004450d1f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a000020002d0008220341024b0d1002400240024020030e03000102000b200241003a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f200341017422052004200520044b1b22054100480d5f0240024020030d002005102121040c010b200128020020032005102521040b2004450d2220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041096a20011071200041386a29030021082000290330210902400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5f200341017422002004200020044b1b22004100480d5f0240024020030d002000102121030c010b200128020020032000102521030b2003450d2320012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012008370008200120093700000c120b200241013a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5e200341017422052004200520044b1b22054100480d5e0240024020030d002005102121040c010b200128020020032005102521040b2004450d2320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041096a200110710c110b200241023a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5d200341017422052004200520044b1b22054100480d5d0240024020030d002005102121040c010b200128020020032005102521040b2004450d2320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200041096a20011071200041296a20011071200041d8006a29030021082000290350210902400240200141046a2802002204200528020022036b4110490d00200128020021040c010b200341106a22052003490d5d200441017422032005200320054b1b22034100480d5d0240024020040d002003102121040c010b200128020020042003102521040b2004450d2420012004360200200141046a2003360200200141086a28020021030b200141086a2205200341106a360200200420036a2203200837000820032009370000200041e8006a29030021082000290360210902400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5d200341017422002004200020044b1b22004100480d5d0240024020030d002000102121030c010b200128020020032000102521030b2003450d2520012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012008370008200120093700000c100b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102121040c010b200128020020032005102521040b2004450d2520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002d0008220341024b0d0f02400240024020030e03000102000b200241003a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5e200341017422052004200520044b1b22054100480d5e0240024020030d002005102121040c010b200128020020032005102521040b2004450d2820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041186a29030021082000290310210902400240200141046a2802002204200528020022036b4110490d00200128020021040c010b200341106a22052003490d5e200441017422032005200320054b1b22034100480d5e0240024020040d002003102121040c010b200128020020042003102521040b2004450d2920012004360200200141046a2003360200200141086a28020021030b200141086a2205200341106a360200200420036a2203200837000820032009370000200041286a29030021082000290320210902400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5e200341017422002004200020044b1b22004100480d5e0240024020030d002000102121030c010b200128020020032000102521030b2003450d2a20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012008370008200120093700000c110b200241013a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5d200341017422052004200520044b1b22054100480d5d0240024020030d002005102121040c010b200128020020032005102521040b2004450d2a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041096a20011071200041386a29030021082000290330210902400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5d200341017422002004200020044b1b22004100480d5d0240024020030d002000102121030c010b200128020020032000102521030b2003450d2b20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012008370008200120093700000c100b200241023a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102121040c010b200128020020032005102521040b2004450d2b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5c200341017422002005200020054b1b22004100480d5c0240024020030d002000102121030c010b200128020020032000102521030b2003450d2c20012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0f0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102121040c010b200128020020032005102521040b2004450d2c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102121040c010b200128020020032005102521040b2004450d2d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041106a200110c201200028020421062000410c6a28020022002001105c02400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d5b200441017422032005200320054b1b22034100480d5b0240024020040d002003102121040c010b200128020020042003102521040b2004450d2e20012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010dc041a0c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a200341017422052004200520044b1b22054100480d5a0240024020030d002005102121040c010b200128020020032005102521040b2004450d2e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5a200341017422052004200520044b1b22054100480d5a0240024020030d002005102121040c010b200128020020032005102521040b2004450d2f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280204210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5a200341017422002005200020054b1b22004100480d5a0240024020030d002000102121030c010b200128020020032000102521030b2003450d3020012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d59200341017422052004200520044b1b22054100480d590240024020030d002005102121040c010b200128020020032005102521040b2004450d3020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a00002000280204220341024b0d0c02400240024020030e03000102000b200241003a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102121040c010b200128020020032005102521040b2004450d3320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000020002802082103200041106a28020022002001105c2000450d0e2003200041286c6a210a200141046a21060340200320011071200341206a29030021080240024020062802002204200528020022006b4108490d00200128020021040c010b200041086a22072000490d5c200441017422002007200020074b1b22004100480d5c0240024020040d002000102121040c010b200128020020042000102521040b2004450d352001200436020020062000360200200528020021000b2005200041086a360200200420006a2008370000200a200341286a2203470d000c0f0b0b200241013a000c02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d5a200041017422042003200420034b1b22044100480d5a0240024020000d002004102121030c010b200128020020002004102521030b2003450d3420012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c0d0b200241023a000c02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d59200041017422042003200420034b1b22044100480d590240024020000d002004102121030c010b200128020020002004102521030b2003450d3420012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41023a00000c0c0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102121040c010b200128020020032005102521040b2004450d3420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a000020002d0004220341024b0d0b02400240024020030e03000102000b200241003a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a200341017422052004200520044b1b22054100480d5a0240024020030d002005102121040c010b200128020020032005102521040b2004450d3720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041056a200110710c0d0b200241013a000c02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d59200041017422042003200420034b1b22044100480d590240024020000d002004102121030c010b200128020020002004102521030b2003450d3720012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c0c0b200241023a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102121040c010b200128020020032005102521040b2004450d3720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a000020002802082104200041106a28020022002001105c2000450d0b2004200041d0006c6a210503402004200110712002200441206a36020c2002410c6a200110c3012002200441306a36020c2002410c6a200110c30120042802402100200428024822032001105c200441d0006a210402402003450d00200341306c21030340200041106a200110712002200036020c2002410c6a200110c301200041306a2100200341506a22030d000b0b20052004470d000c0c0b0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d57200341017422072005200720054b1b22074100480d570240024020030d002007102121050c010b200128020020032007102521050b2005450d3720012005360200200141046a2007360200200141086a28020021030b2004200341016a360200200520036a41083a000020002d00082203410a4b0d0a0240024002400240024002400240024002400240024020030e0b000102030405060708090a000b200241003a000c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d61200341017422072005200720054b1b22074100480d610240024020030d002007102121050c010b200128020020032007102521050b2005450d4220012005360200200141046a2007360200200141086a28020021030b2004200341016a360200200520036a41003a0000200028020c21070240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d6120054101742203200a2003200a4b1b22034100480d610240024020050d002003102121050c010b200128020020052003102521050b2005450d4320012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2007360000200041186a2903002108200029031021090240024020062802002203200428020022006b4110490d00200128020021030c010b200041106a22052000490d61200341017422002005200020054b1b22004100480d610240024020030d002000102121030c010b200128020020032000102521030b2003450d4420012003360200200141046a2000360200200141086a28020021000b2004200041106a360200200320006a22012008370008200120093700000c140b200241013a000c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d60200341017422072005200720054b1b22074100480d600240024020030d002007102121050c010b200128020020032007102521050b2005450d4420012005360200200141046a2007360200200141086a28020021030b2004200341016a360200200520036a41013a0000200028020c21070240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d6020054101742203200a2003200a4b1b22034100480d600240024020050d002003102121050c010b200128020020052003102521050b2005450d4520012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2007360000200041286a2903002108200029032021090240024020062802002205200428020022036b4110490d00200128020021040c010b200341106a22042003490d60200541017422032004200320044b1b22034100480d600240024020050d002003102121040c010b200128020020052003102521040b2004450d4620012004360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200420036a220320083700082003200937000020002802102103200041186a28020022002001105c2000450d13200041057421000340200320011071200341206a2103200041606a22000d000c140b0b200241023a000c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5f200041017422052003200520034b1b22054100480d5f0240024020000d002005102121030c010b200128020020002005102521030b2003450d4620012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c120b200241033a000c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5e200341017422072005200720054b1b22074100480d5e0240024020030d002007102121050c010b200128020020032007102521050b2005450d4620012005360200200141046a2007360200200141086a28020021030b2004200341016a360200200520036a41033a0000200028020c21070240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5e20054101742203200a2003200a4b1b22034100480d5e0240024020050d002003102121050c010b200128020020052003102521050b2005450d4720012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200736000020002d0009220041024b0d1102400240024020000e03000102000b200241003a000c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d60200041017422052003200520034b1b22054100480d600240024020000d002005102121030c010b200128020020002005102521030b2003450d4a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41003a00000c130b200241013a000c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5f200041017422052003200520034b1b22054100480d5f0240024020000d002005102121030c010b200128020020002005102521030b2003450d4a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41013a00000c120b200241023a000c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5e200041017422052003200520034b1b22054100480d5e0240024020000d002005102121030c010b200128020020002005102521030b2003450d4a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c110b200241043a000c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5d200341017422072005200720054b1b22074100480d5d0240024020030d002007102121050c010b200128020020032007102521050b2005450d4a20012005360200200141046a2007360200200141086a28020021030b2004200341016a360200200520036a41043a0000200028020c21050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490d5d200341017422002006200020064b1b22004100480d5d0240024020030d002000102121030c010b200128020020032000102521030b2003450d4b20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c100b200241053a000c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5c200341017422072005200720054b1b22074100480d5c0240024020030d002007102121050c010b200128020020032007102521050b2005450d4b20012005360200200141046a2007360200200141086a28020021030b2004200341016a360200200520036a41053a0000200028020c21050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490d5c200341017422002006200020064b1b22004100480d5c0240024020030d002000102121030c010b200128020020032000102521030b2003450d4c20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0f0b200241063a000c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5b200341017422072005200720054b1b22074100480d5b0240024020030d002007102121050c010b200128020020032007102521050b2005450d4c20012005360200200141046a2007360200200141086a28020021030b2004200341016a360200200520036a41063a0000200028020c21050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490d5b200341017422002006200020064b1b22004100480d5b0240024020030d002000102121030c010b200128020020032000102521030b2003450d4d20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0e0b200241073a000c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5a200341017422072005200720054b1b22074100480d5a0240024020030d002007102121050c010b200128020020032007102521050b2005450d4d20012005360200200141046a2007360200200141086a28020021030b2004200341016a360200200520036a41073a0000200028020c21070240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5a20054101742203200a2003200a4b1b22034100480d5a0240024020050d002003102121050c010b200128020020052003102521050b2005450d4e20012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2007360000200220002d000922053a000c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5a200041017422062003200620034b1b22064100480d5a0240024020000d002006102121030c010b200128020020002006102521030b2003450d4f20012003360200200141046a2006360200200141086a28020021000b2004200041016a360200200320006a20053a00000c0d0b200241083a000c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d59200341017422052004200520044b1b22054100480d590240024020030d002005102121040c010b200128020020032005102521040b2004450d4f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a0000200041096a20011071200041296a200110710c0c0b200241093a000c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102121040c010b200128020020032005102521040b2004450d4f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041096a200110710c0b0b2002410a3a000c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d57200341017422062005200620054b1b22064100480d570240024020030d002006102121050c010b200128020020032006102521050b2005450d4f20012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a410a3a0000200041096a200110712002200136020c200041296a2002410c6a106b200028024c210502400240200141046a2802002203200628020022006b4104490d00200128020021030c010b200041046a22062000490d57200341017422002006200020064b1b22004100480d570240024020030d002000102121030c010b200128020020032000102521030b2003450d5020012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0a0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d56200341017422052004200520044b1b22054100480d560240024020030d002005102121040c010b200128020020032005102521040b2004450d5020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041046a200110d4030c090b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d55200341017422052004200520044b1b22054100480d550240024020030d002005102121040c010b200128020020032005102521040b2004450d5020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a0000200041046a200110d4030c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d54200341017422052004200520044b1b22054100480d540240024020030d002005102121040c010b200128020020032005102521040b2004450d5020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a000020002d0004220341044b0d070240024002400240024020030e050001020304000b200241003a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102121040c010b200128020020032005102521040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000020002802082103200041106a28020022002001105c2000450d0b2003200041306c6a210a200141046a21060340200320011071200341286a2903002108200341206a29030021090240024020062802002204200528020022006b4110490d00200128020021040c010b200041106a22072000490d59200441017422002007200020074b1b22004100480d590240024020040d002000102121040c010b200128020020042000102521040b2004450d572001200436020020062000360200200528020021000b2005200041106a360200200420006a2200200837000820002009370000200a200341306a2203470d000c0c0b0b200241013a000c02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d57200041017422042003200420034b1b22044100480d570240024020000d002004102121030c010b200128020020002004102521030b2003450d5620012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c0a0b200241023a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d01200341017422052004200520044b1b22054100480d9d010240024020030d002005102121040c010b200128020020032005102521040b2004450d5720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041056a200110710c090b200241033a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c01200341017422052004200520044b1b22054100480d9c010240024020030d002005102121040c010b200128020020032005102521040b2004450d5720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a0000200041056a200110710c080b200141086a2802002103200241043a000c024002402003200141046a280200460d00200128020021040c010b200341016a22042003490d9b01200341017422052004200520044b1b22054100480d9b010240024020030d002005102121040c010b200128020020032005102521040b2004450d5720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041056a20011071200041256a20011071200220002d004522043a000c02400240200141046a28020020052802002200460d00200128020021030c010b200041016a22032000490d9b01200041017422052003200520034b1b22054100480d9b010240024020000d002005102121030c010b200128020020002005102521030b2003450d5820012003360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200320006a20043a00000c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9a01200341017422052004200520044b1b22054100480d9a010240024020030d002005102121040c010b200128020020032005102521040b2004450d5820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a000020002d0001220041044b0d060240024002400240024020000e050001020304000b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d9e01200041017422042003200420034b1b22044100480d9e010240024020000d002004102121030c010b200128020020002004102521030b2003450d5d20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41003a00000c0a0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d9d01200041017422042003200420034b1b22044100480d9d010240024020000d002004102121030c010b200128020020002004102521030b2003450d5d20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c090b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d9c01200041017422042003200420034b1b22044100480d9c010240024020000d002004102121030c010b200128020020002004102521030b2003450d5d20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41023a00000c080b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d9b01200041017422042003200420034b1b22044100480d9b010240024020000d002004102121030c010b200128020020002004102521030b2003450d5d20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41033a00000c070b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d9a01200041017422042003200420034b1b22044100480d9a010240024020000d002004102121030c010b200128020020002004102521030b2003450d5d20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41043a00000c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9901200341017422052004200520044b1b22054100480d99010240024020030d002005102121040c010b200128020020032005102521040b2004450d5d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410d3a000020002d0008220341054b0d0502400240024002400240024020030e06000102030405000b200241003a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e01200341017422052004200520044b1b22054100480d9e010240024020030d002005102121040c010b200128020020032005102521040b2004450d6320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d9e01200341017422002005200020054b1b22004100480d9e010240024020030d002000102121030c010b200128020020032000102521030b2003450d6420012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0a0b200241013a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d01200341017422052004200520044b1b22054100480d9d010240024020030d002005102121040c010b200128020020032005102521040b2004450d6420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041186a29030021082000290310210902400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d9d01200341017422002004200020044b1b22004100480d9d010240024020030d002000102121030c010b200128020020032000102521030b2003450d6520012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012008370008200120093700000c090b200241023a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c01200341017422052004200520044b1b22054100480d9c010240024020030d002005102121040c010b200128020020032005102521040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200028022c210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d9c01200441017422032005200320054b1b22034100480d9c010240024020040d002003102121040c010b200128020020042003102521040b2004450d6620012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a2006360000200041386a29030021082000290330210902400240200141046a2802002204200528020022036b4110490d00200128020021040c010b200341106a22052003490d9c01200441017422032005200320054b1b22034100480d9c010240024020040d002003102121040c010b200128020020042003102521040b2004450d6720012004360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200420036a2203200837000820032009370000200041096a200110710c080b200241033a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b01200341017422052004200520044b1b22054100480d9b010240024020030d002005102121040c010b200128020020032005102521040b2004450d6720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200041186a29030021082000290310210902400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d9b01200341017422002004200020044b1b22004100480d9b010240024020030d002000102121030c010b200128020020032000102521030b2003450d6820012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012008370008200120093700000c070b200141086a2802002103200241043a000c024002402003200141046a280200460d00200128020021040c010b200341016a22042003490d9a01200341017422052004200520044b1b22054100480d9a010240024020030d002005102121040c010b200128020020032005102521040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041186a29030021082000290310210902400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d9a01200341017422002004200020044b1b22004100480d9a010240024020030d002000102121030c010b200128020020032000102521030b2003450d6920012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012008370008200120093700000c060b200241053a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9901200341017422052004200520044b1b22054100480d99010240024020030d002005102121040c010b200128020020032005102521040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a0000200041186a29030021082000290310210902400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d9901200341017422002004200020044b1b22004100480d99010240024020030d002000102121030c010b200128020020032000102521030b2003450d6a20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012008370008200120093700000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9801200341017422052004200520044b1b22054100480d98010240024020030d002005102121040c010b200128020020032005102521040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410e3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d9801200341017422052004200520044b1b22054100480d98010240024020030d002005102121040c010b200128020020032005102521040b2004450d6b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041186a20011071200041386a200110c003200041106a29030021082000290308210902400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d9801200341017422002004200020044b1b22004100480d98010240024020030d002000102121030c010b200128020020032000102521030b2003450d6c20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012008370008200120093700000c040b02400240200141046a2205280200200141086a22032802002204460d00200128020021060c010b200441016a22062004490d9701200441017422072006200720064b1b22074100480d97010240024020040d002007102121060c010b200128020020042007102521060b2006450d6c20012006360200200141046a2007360200200141086a28020021040b2003200441016a360200200620046a410f3a000020002d0008220441064b0d03024002400240024002400240024020040e0700010203040506000b02400240200528020020032802002204460d00200128020021060c010b200441016a22062004490d9d01200441017422072006200720064b1b22074100480d9d010240024020040d002007102121060c010b200128020020042007102521060b2006450d7320012006360200200141046a2007360200200141086a28020021040b2003200441016a360200200620046a41003a0000200028020c21060240024020052802002204200328020022006b4104490d00200128020021040c010b200041046a22052000490d9d01200441017422002005200020054b1b22004100480d9d010240024020040d002000102121040c010b200128020020042000102521040b2004450d7420012004360200200141046a2000360200200141086a28020021000b2003200041046a360200200420006a20063600000c090b02400240200528020020032802002204460d00200128020021060c010b200441016a22062004490d9c01200441017422072006200720064b1b22074100480d9c010240024020040d002007102121060c010b200128020020042007102521060b2006450d7420012006360200200141046a2007360200200141086a28020021040b2003200441016a360200200620046a41013a0000200028020c21070240024020052802002206200328020022046b4104490d00200128020021060c010b200441046a220a2004490d9c0120064101742204200a2004200a4b1b22044100480d9c010240024020060d002004102121060c010b200128020020062004102521060b2006450d7520012006360200200141046a2004360200200141086a28020021040b2003200441046a360200200620046a2007360000200028021021070240024020052802002206200328020022046b4104490d00200128020021060c010b200441046a220a2004490d9c0120064101742204200a2004200a4b1b22044100480d9c010240024020060d002004102121060c010b200128020020062004102521060b2006450d7620012006360200200141046a2004360200200141086a28020021040b2003200441046a360200200620046a2007360000200028021421060240024020052802002204200328020022006b4104490d00200128020021040c010b200041046a22052000490d9c01200441017422002005200020054b1b22004100480d9c010240024020040d002000102121040c010b200128020020042000102521040b2004450d7720012004360200200141046a2000360200200141086a28020021000b2003200041046a360200200420006a20063600000c080b02400240200528020020032802002204460d00200128020021060c010b200441016a22062004490d9b01200441017422072006200720064b1b22074100480d9b010240024020040d002007102121060c010b200128020020042007102521060b2006450d7720012006360200200141046a2007360200200141086a28020021040b2003200441016a360200200620046a41023a0000200028020c21060240024020052802002204200328020022006b4104490d00200128020021040c010b200041046a22052000490d9b01200441017422002005200020054b1b22004100480d9b010240024020040d002000102121040c010b200128020020042000102521040b2004450d7820012004360200200141046a2000360200200141086a28020021000b2003200041046a360200200420006a20063600000c070b02400240200528020020032802002204460d00200128020021060c010b200441016a22062004490d9a01200441017422072006200720064b1b22074100480d9a010240024020040d002007102121060c010b200128020020042007102521060b2006450d7820012006360200200141046a2007360200200141086a28020021040b200141086a2207200441016a360200200620046a41033a0000200041106a20011071200028020c210a02400240200141046a2802002206200728020022046b4104490d00200128020021060c010b200441046a22072004490d9a01200641017422042007200420074b1b22044100480d9a010240024020060d002004102121060c010b200128020020062004102521060b2006450d7920012006360200200141046a2004360200200141086a28020021040b2003200441046a360200200620046a200a360000024020002d00092204410f7141094b0d000240024002400240024002400240024002400240024020040e0a00010203040506070809000b410021060c090b410121060c080b410221060c070b410321060c060b410421060c050b410521060c040b410621060c030b410721060c020b410821060c010b410921060b200220063a000c02400240200528020020032802002204460d00200128020021070c010b200441016a22072004490d9b012004410174220a2007200a20074b1b220a4100480d9b010240024020040d00200a102121070c010b20012802002004200a102521070b2007450d7b20012007360200200141046a200a360200200141086a28020021040b2003200441016a360200200720046a20063a00000b200028023021070240024020052802002206200328020022046b4104490d00200128020021060c010b200441046a220a2004490d9a0120064101742204200a2004200a4b1b22044100480d9a010240024020060d002004102121060c010b200128020020062004102521060b2006450d7b20012006360200200141046a2004360200200141086a28020021040b2003200441046a360200200620046a2007360000200041c0006a2903002108200029033821090240024020052802002204200328020022006b4110490d00200128020021040c010b200041106a22052000490d9a01200441017422002005200020054b1b22004100480d9a010240024020040d002000102121040c010b200128020020042000102521040b2004450d7c20012004360200200141046a2000360200200141086a28020021000b2003200041106a360200200420006a22012008370008200120093700000c060b02400240200528020020032802002204460d00200128020021060c010b200441016a22062004490d9901200441017422072006200720064b1b22074100480d99010240024020040d002007102121060c010b200128020020042007102521060b2006450d7c20012006360200200141046a2007360200200141086a28020021040b2003200441016a360200200620046a41043a0000200028020c21070240024020052802002206200328020022046b4104490d00200128020021060c010b200441046a220a2004490d990120064101742204200a2004200a4b1b22044100480d99010240024020060d002004102121060c010b200128020020062004102521060b2006450d7d20012006360200200141046a2004360200200141086a28020021040b2003200441046a360200200620046a2007360000024020002d00092204410f7141094b0d000240024002400240024002400240024002400240024020040e0a00010203040506070809000b410021060c090b410121060c080b410221060c070b410321060c060b410421060c050b410521060c040b410621060c030b410721060c020b410821060c010b410921060b200220063a000c02400240200528020020032802002204460d00200128020021070c010b200441016a22072004490d9a012004410174220a2007200a20074b1b220a4100480d9a010240024020040d00200a102121070c010b20012802002004200a102521070b2007450d7f20012007360200200141046a200a360200200141086a28020021040b2003200441016a360200200720046a20063a00000b200041186a2903002108200029031021090240024020052802002206200328020022046b4110490d00200128020021060c010b200441106a22072004490d9901200641017422042007200420074b1b22044100480d99010240024020060d002004102121060c010b200128020020062004102521060b2006450d7f20012006360200200141046a2004360200200141086a28020021040b2003200441106a360200200620046a2204200837000820042009370000200041286a2903002108200029032021090240024020052802002204200328020022006b4110490d00200128020021040c010b200041106a22052000490d9901200441017422002005200020054b1b22004100480d99010240024020040d002000102121040c010b200128020020042000102521040b2004450d800120012004360200200141046a2000360200200141086a28020021000b2003200041106a360200200420006a22012008370008200120093700000c050b02400240200528020020032802002204460d00200128020021060c010b200441016a22062004490d9801200441017422072006200720064b1b22074100480d98010240024020040d002007102121060c010b200128020020042007102521060b2006450d800120012006360200200141046a2007360200200141086a28020021040b200141086a2207200441016a360200200620046a41053a0000200041096a20011071200041386a29030021082000290330210902400240200141046a2802002206200728020022046b4110490d00200128020021060c010b200441106a22072004490d9801200641017422042007200420074b1b22044100480d98010240024020060d002004102121060c010b200128020020062004102521060b2006450d810120012006360200200141046a2004360200200141086a28020021040b2003200441106a360200200620046a2204200837000820042009370000200041c8006a2903002108200029034021090240024020052802002204200328020022006b4110490d00200128020021040c010b200041106a22052000490d9801200441017422002005200020054b1b22004100480d98010240024020040d002000102121040c010b200128020020042000102521040b2004450d820120012004360200200141046a2000360200200141086a28020021000b2003200041106a360200200420006a22012008370008200120093700000c040b02400240200528020020032802002204460d00200128020021050c010b200441016a22052004490d9701200441017422062005200620054b1b22064100480d97010240024020040d002006102121050c010b200128020020042006102521050b2005450d820120012005360200200141046a2006360200200141086a28020021040b200141086a2206200441016a360200200520046a41063a0000200041096a20011071200041386a29030021082000290330210902400240200141046a2802002204200628020022006b4110490d00200128020021040c010b200041106a22052000490d9701200441017422002005200020054b1b22004100480d97010240024020040d002000102121040c010b200128020020042000102521040b2004450d830120012004360200200141046a2000360200200141086a28020021000b2003200041106a360200200420006a22012008370008200120093700000c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9601200341017422052004200520044b1b22054100480d96010240024020030d002005102121040c010b200128020020032005102521040b2004450d830120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41103a0000200141046a280200210420052802002103024020002802044101460d000240024020042003460d00200128020021040c010b200341016a22042003490d9701200341017422052004200520044b1b22054100480d97010240024020030d002005102121040c010b200128020020032005102521040b2004450d850120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280208210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d9701200341017422002005200020054b1b22004100480d97010240024020030d002000102121030c010b200128020020032000102521030b2003450d860120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c030b0240024020042003460d00200128020021040c010b200341016a22042003490d9601200341017422052004200520044b1b22054100480d96010240024020030d002005102121040c010b200128020020032005102521040b2004450d860120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a00002000280208210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d9601200341017422002005200020054b1b22004100480d96010240024020030d002000102121030c010b200128020020032000102521030b2003450d870120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9501200341017422052004200520044b1b22054100480d95010240024020030d002005102121040c010b200128020020032005102521040b2004450d870120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41113a000020002d0001220341024b0d0102400240024020030e03000102000b200241003a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9701200341017422052004200520044b1b22054100480d97010240024020030d002005102121040c010b200128020020032005102521040b2004450d8a0120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200220002d000222043a000c02400240200141046a28020020052802002200460d00200128020021030c010b200041016a22032000490d9701200041017422052003200520034b1b22054100480d97010240024020000d002005102121030c010b200128020020002005102521030b2003450d8b0120012003360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200320006a20043a00000c030b200241013a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9601200341017422052004200520044b1b22054100480d96010240024020030d002005102121040c010b200128020020032005102521040b2004450d8b0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041026a200110710c020b200241023a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9501200341017422052004200520044b1b22054100480d95010240024020030d002005102121040c010b200128020020032005102521040b2004450d8b0120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200220002d000222043a000c02400240200141046a28020020052802002200460d00200128020021030c010b200041016a22032000490d9501200041017422052003200520034b1b22054100480d95010240024020000d002005102121030c010b200128020020002005102521030b2003450d8c0120012003360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200320006a20043a00000c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9401200341017422052004200520044b1b22054100480d94010240024020030d002005102121040c010b200128020020032005102521040b2004450d8c0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41123a000020002d0008220341044b0d000240024002400240024020030e050001020304000b200241003a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9801200341017422052004200520044b1b22054100480d98010240024020030d002005102121040c010b200128020020032005102521040b2004450d910120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041096a200110710c040b200241013a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9701200341017422052004200520044b1b22054100480d97010240024020030d002005102121040c010b200128020020032005102521040b2004450d910120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041096a200110710c030b200241023a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9601200341017422052004200520044b1b22054100480d96010240024020030d002005102121040c010b200128020020032005102521040b2004450d910120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041096a200110710c020b200241033a000c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9501200341017422052004200520044b1b22054100480d95010240024020030d002005102121040c010b200128020020032005102521040b2004450d910120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200041096a20011071200041386a29030021082000290330210902400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d9501200341017422002004200020044b1b22004100480d95010240024020030d002000102121030c010b200128020020032000102521030b2003450d920120012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012008370008200120093700000c010b200141086a2802002103200241043a000c024002402003200141046a280200460d00200128020021040c010b200341016a22042003490d9401200341017422052004200520044b1b22054100480d94010240024020030d002005102121040c010b200128020020032005102521040b2004450d920120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041096a20011071200041386a29030021082000290330210902400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d9401200341017422002004200020044b1b22004100480d94010240024020030d002000102121030c010b200128020020032000102521030b2003450d930120012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012008370008200120093700000b200241106a24000f0b200541011030000b200541011030000b200341011030000b200541011030000b200641011030000b200641011030000b200641011030000b200341011030000b200741011030000b200541011030000b200541011030000b200541011030000b200041011030000b200541011030000b200541011030000b200041011030000b200541011030000b200541011030000b200341011030000b200041011030000b200541011030000b200541011030000b200341011030000b200041011030000b200541011030000b200041011030000b200541011030000b200041011030000b200541011030000b200541011030000b200341011030000b200541011030000b200541011030000b200041011030000b200541011030000b200541011030000b200041011030000b200441011030000b200441011030000b200541011030000b200541011030000b200441011030000b200541011030000b200741011030000b200741011030000b200341011030000b200041011030000b200741011030000b200341011030000b200341011030000b200541011030000b200741011030000b200341011030000b200541011030000b200541011030000b200541011030000b200741011030000b200041011030000b200741011030000b200041011030000b200741011030000b200041011030000b200741011030000b200341011030000b200641011030000b200541011030000b200541011030000b200641011030000b200041011030000b200541011030000b200541011030000b200541011030000b200541011030000b200041011030000b200441011030000b102a000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200441011030000b200441011030000b200441011030000b200441011030000b200441011030000b200541011030000b200541011030000b200041011030000b200541011030000b200041011030000b200541011030000b200341011030000b200341011030000b200541011030000b200041011030000b200541011030000b200041011030000b200541011030000b200041011030000b200541011030000b200541011030000b200041011030000b200741011030000b200741011030000b200041011030000b200741011030000b200441011030000b200441011030000b200041011030000b200741011030000b200041011030000b200741011030000b200441011030000b200a41011030000b200441011030000b200041011030000b200741011030000b200441011030000b200a41011030000b200441011030000b200041011030000b200741011030000b200441011030000b200041011030000b200641011030000b200041011030000b200541011030000b200541011030000b200041011030000b200541011030000b200041011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200041011030000b200541011030000b200041011030000b102a000b130020004103360204200041bcb0c0003602000bd90303027f017e027f02402001450d00034020002802e40121002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d0020002001410c6c6a220441e4006a2902002105200441e0006a2802002104200141016a21010c010b02400240200028020022010d002003ad210541002106410021010c010b20003301044220862003ad842105410121060b200010232005a72103024002402005422088a7220720012f01064f0d00200121040c010b034002400240200128020022040d002003ad2105410021040c010b200641016a210620013301044220862003ad8421050b200110232005a72103200421012005422088a7220720042f01064f0d000b0b200741027420046a41e8016a280200210020042007410c6c6a220141e4006a2902002105200141e0006a280200210402402006417f6a2201450d00034020002802e40121002001417f6a22010d000b0b410021010b2004450d012002417f6a210202402005a7450d00200410230b20020d000b0b0240200041d8a7c300460d0020002802002101200010232001450d0020012802002104200110232004450d00024020042802002201450d000340200410232001210420012802002200210120000d000b0b200410230b0bff0303067f017e027f230041206b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d012000200520034102746a41086a28020036020020052003410c6c6a2206413c6a2802002107200641346a29020021082001200341016a36020c2001200436020820012005360204200020083702042000410c6a20073602000c020b200041003602040c010b2001280200210602400240200528020022030d002004ad2108410021030c010b200641016a210620053301044220862004ad8421080b200510232008a72104024002402008422088a7220720032f01064f0d00200321050c010b034002400240200328020022050d002004ad2108410021050c010b200641016a210620033301044220862004ad8421080b200310232008a72104200521032008422088a7220720052f01064f0d000b0b200741027420056a220341086a2802002109200241106a41086a220a20052007410c6c6a2205413c6a2802003602002002200541346a290200370310200341bc016a280200210302402006417f6a2205450d00034020032802b80121032005417f6a22050d000b0b2001410036020c20012004360208200120033602042001410036020020002009360200200020022903103702042000410c6a200a2802003602000b200241206a24000bd308030d7f017e017f230041a0016b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2205200128020422062f01064f0d01200241186a2207200620054105746a220341206a290000370300200241106a2208200341186a290000370300200241086a2209200341106a2900003703002002200341086a290000370300200241206a41286a220a2006200541306c6a22034190036a290300370300200241206a41206a220b20034188036a290300370300200241206a41186a220c20034180036a290300370300200241206a41106a220d200341f8026a290300370300200241206a41086a220e200341f0026a290300370300200341e8026a290300210f2001200541016a36020c20012004360208200120063602042002200f370320200241d0006a41186a2007290300370300200241d0006a41106a2008290300370300200241d0006a41086a200929030037030020022002290300370350200241d0006a41286a200e290300370300200241d0006a41306a200d29030037030020024188016a200c29030037030020024190016a200b29030037030020024198016a200a290300370300200220022903203703702000200241d0006a41d00010dc041a0c020b200041003602400c010b2001280200210702400240200628020022030d002004ad210f410021030c010b200741016a210720063301044220862004ad84210f0b20061023200fa7210502400240200f422088a7220420032f01064f0d00200321060c010b034002400240200328020022060d002005ad210f410021060c010b200741016a210720033301044220862005ad84210f0b20031023200fa7210520062103200f422088a7220420062f01064f0d000b0b200241186a2208200620044105746a220341206a290000370300200241106a2209200341186a290000370300200241086a220a200341106a2900003703002002200341086a290000370300200241206a41286a220b2006200441306c6a22034190036a290300370300200241206a41206a220c20034188036a290300370300200241206a41186a220d20034180036a290300370300200241206a41106a220e200341f8026a290300370300200241206a41086a2210200341f0026a2903003703002002200341e8026a290300370320200441027420066a41fc066a280200210302402007417f6a2206450d00034020032802f80621032006417f6a22060d000b0b2001410036020c200120053602082001200336020420014100360200200241d0006a41186a2008290300370300200241d0006a41106a2009290300370300200241d0006a41086a200a290300370300200241d0006a41286a2010290300370300200241d0006a41306a200e29030037030020024188016a200d29030037030020024190016a200c29030037030020024198016a200b29030037030020022002290300370350200220022903203703702000200241d0006a41d00010dc041a0b200241a0016a24000b830c04067f017e067f017e23004190016b22022400200241206a41186a22034200370300200241206a41106a22044200370300200241206a41086a2205420037030020024200370320200241e0006a41086a220641f7fbc400ad4280808080f000841003220741086a2900003703002002200729000037036020071023200520062903003703002002200229036037032020064194b7c200ad4280808080c001841003220741086a2900003703002002200729000037036020071023200420022903602208370300200241f0006a41086a22072005290300370300200241f0006a41106a22092008370300200241f0006a41186a220a20062903003703002002200837034020022002290320370370200241186a200241f0006a4120108f01200228021c210b2002280218210c20064194fcc400ad42808080808001841003220d41086a2900003703002002200d290000370360200d1023200241d0006a41086a220e200629030037030020022002290360370350200641d8e9c000ad4280808080a002841003220d41086a2900003703002002200d290000370360200d1023200241c0006a41086a220d2006290300370300200220022903603703402002200b4100200c1b220b360260200a200241e0006aad220f4280808080c0008422081001220641186a2900003703002009200641106a2900003703002007200641086a29000037030020022006290000370370200610232003200a290300370300200420092903003703002005200729030037030020022002290370370320024002400240024041c00010212206450d00200620022903503700002006200229034037001020062002290320370020200641086a200e290300370000200641186a200d290300370000200641286a2005290300370000200641306a2004290300370000200641386a200329030037000020022000360260200a20081001220d41186a2900003703002009200d41106a2900003703002007200d41086a2900003703002002200d290000370370200d10232003200a290300370300200420092903003703002005200729030037030020022002290370370320200641c00041800110252206450d0120062002290320370040200641d8006a200241206a41186a2207290300370000200641d0006a200241206a41106a2209290300370000200641c8006a200241206a41086a220a29030037000041012105200241106a200641e00041014100410010b8012002280210210420061023024020044101460d00200241e0006a41086a22064194fcc400ad42808080808001841003220541086a2900003703002002200529000037036020051023200241c0006a41086a200629030037030020022002290360370340200641a9e4c000ad4280808080e001841003220541086a2900003703002002200529000037036020051023200241d0006a41086a2006290300370300200220022903603703502002200b360260200241f0006a41186a2205200f4280808080c000841001220641186a290000370300200241f0006a41106a2204200641106a290000370300200241f0006a41086a220d200641086a29000037030020022006290000370370200610232007200529030037030020092004290300370300200a200d2903003703002002200229037037032041c00010212206450d03200620022903403700002006200229035037001020062002290320370020200641086a200241c0006a41086a290300370000200641186a200241d0006a41086a290300370000200641286a200241206a41086a290300370000200641306a200241206a41106a290300370000200641386a200241206a41186a290300370000200241f0006a200110ac01200641c00041800110252206450d0420062002290070370040200641d8006a200241f0006a41186a290000370000200641d0006a200241f0006a41106a290000370000200641c8006a200241f0006a41086a290000370000200241086a200641e000108f01200228020c21052002280208210420061023200541004720044100477121050b20024190016a240020050f0b41c00041011030000b41800141011030000b41c00041011030000b41800141011030000b940102017f017e230041106b2206240002402002ad4220862001ad842004ad4220862003ad84200510172207422088a72203450d002007a722042d0000220241014b0d00410021050240024020020e020100010b2003417f6a4104490d0120042800012101410121050b2000200136020420002005360200200641106a24000f0b41f4b7c600412e200641086a41a4b8c6001031000ba90201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad2001103921000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141a085c0004102200220006a4180016a410020006b103c21000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141a085c0004102200220006a4180016a410020006b103c21000b20024180016a240020000f0b2004418001103e000b2004418001103e000bf31005067f017e017f017e067f230041f0006b2202240020012802202103200241306a41186a4200370300200241306a41106a22044200370300200241306a41086a2205420037030020024200370330200241e0006a41086a220641f7fbc400ad4280808080f000841003220741086a29000037030020022007290000370360200710232005200629030037030020022002290360370330200641e7acc500ad4280808080a001841003220741086a2900003703002002200729000037036020071023200420022903602208370300200241106a41086a2005290300370300200241106a41106a2008370300200241106a41186a20062903003703002002200837035020022002290330370310200241306a200241106a412010bb0120022802302206410120061b21050240024002400240024002400240024002400240024002400240024002400240024020032002290234420020061b2208422088a7490d002008a7450d01200510230c010b2003200520034105746a10b701210602402008a7450d00200510230b20060d010b200241306a41186a22054200370300200241306a41106a22074200370300200241306a41086a2203420037030020024200370330200241e0006a41086a220641f7fbc400ad4280808080f000841003220941086a2900003703002002200929000037036020091023200320062903003703002002200229036037033020064194b7c200ad4280808080c001841003220941086a2900003703002002200929000037036020091023200241d0006a41086a22092006290300220837030020022002290360220a3703502004200a370000200441086a220b2008370000200241106a41086a220c2003290300370300200241106a41106a220d2007290300370300200241106a41186a220e200529030037030020022002290330370310200241086a200241106a4120108f01200128021c200228020c410020022802081b220f470d012005420037030020074200370300200342003703002002420037033020064194fcc400ad42808080808001841003221041086a290000370300200220102900003703602010102320032006290300370300200220022903603703302006419ddfc000ad4280808080c000841003221041086a290000370300200220102900003703602010102320092006290300220837030020022002290360220a3703502004200a370000200b2008370000200c2003290300370300200d2007290300370300200e200529030037030020022002290330370310200241306a200241106a10bc0120022802302206410120061b210d200128022022032002290234420020061b2208422088a74f0d04200d20034105746a220e450d04200241003602382002420137033020012802002104410410212206450d0620024284808080c0003702342002200636023020062004360000200128020421072001410c6a2802002206200241306a105c20022802342205200228023822046b2006490d02200228023021050c030b20004180063b0001200041013a0000200041036a41003a00000c0d0b20004180063b0001200041013a0000200041036a41003a00000c0c0b200420066a22092004490d082005410174220b2009200b20094b1b22094100480d080240024020050d002009102121050c010b200228023020052009102521050b2005450d0420022009360234200220053602300b2002200420066a360238200520046a2007200610dc041a200141106a2802002104200141186a2802002206200241306a105c0240024020060d00200228023421052002280238210b200f21070c010b20042006410c6c6a210c034020042802002109200441086a2802002206200241306a105c0240024020022802342205200228023822036b2006490d00200228023021070c010b200320066a22072003490d0a2005410174220b2007200b20074b1b220b4100480d0a0240024020050d00200b102121070c010b20022802302005200b102521070b2007450d072002200b36023420022007360230200b21050b2002200320066a220b360238200720036a2009200610dc041a2004410c6a2204200c470d000b20012802202103200128021c21070b024002402005200b6b4104490d00200b41046a2104200228023021060c010b200b41046a2204200b490d08200541017422062004200620044b1b22094100480d080240024020050d002009102121060c010b200228023020052009102521060b2006450d062002200936023420022006360230200921050b200220043602382006200b6a200736000002400240200520046b41034d0d00200521070c010b200441046a22072004490d08200541017422092007200920074b1b22074100480d080240024020050d002007102121060c010b200620052007102521060b2006450d0720022007360234200220063602300b200620046a2003360000200141246a200441046aad4220862006ad84200e1009210402402007450d00200610230b20044101460d010b20004180083b0001200041013a0000200041036a41003a00002008a7450d09200d10230c090b410c10212206450d06410410212204450d0720024284808080c000370234200220043602302004200f360000200e200241306a1071200241106a41086a2002280238220436020020022002290330220a370310200641086a20043602002006200a370200200041306a41013a0000200041286a428180808010370200200041246a2006360200200041206a4100360200200041186a4204370300200041106a42ac02370300200041086a427f370300200041316a2002280030360000200041346a200241336a280000360000200041003a00002008a7450d08200d10230c080b410441011030000b200941011030000b200b41011030000b200941011030000b200741011030000b102a000b410c41041030000b410441011030000b200241f0006a24000bbb0201017f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022010d00200041003602000c010b200328021421022003200341106a41086a28020036022420032001360220200341c8006a200341206a107e024002402003280248450d0020002003290348370200200041086a200341c8006a41086a2802003602000c010b20034100360230200342013703282003410c36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034198c2c3003602482003200341386a360258200341c4006a41b8a3c500200341c8006a102e1a2003350230422086200335022884100820004100360200200328022c450d00200328022810230b2002450d00200110230b200341e0006a24000bf006010d7f23004190016b220224002002412036021420022001360210200241186a2001ad4280808080800484100410900102400240200228021822030d00200041003602000c010b200228021c21042002200241206a28020036023c20022003360238200241086a200241386a106e0240024002400240024020022802080d0002400240200228023c22014160712205417f4c0d00200228020c210602400240200141057622070d00410121080c010b200510212208450d020b02402006450d004100210903402001210a200241003a0088012009220b41016a2109410021010240024002400340200a2001460d01200241e8006a20016a200228023822052d00003a00002002200541016a3602382002200141016a22053a0088012005210120054120470d000b200241c8006a41186a220c200241e8006a41186a290300370300200241c8006a41106a220d200241e8006a41106a290300370300200241c8006a41086a220e200241e8006a41086a290300370300200220022903683703482007200b470d020240200b41017422012009200120094b1b220741ffffff3f712007470d002007410574220141004e0d020b102a000b2002410036023c0240200141ff0171450d00200241003a0088010b200241003602282007450d08200810230c080b02400240200b0d002001102121080c010b2008200b4105742001102521080b2008450d060b200a20056b21012008200b4105746a220b2002290348370000200b41186a200c290300370000200b41106a200d290300370000200b41086a200e29030037000020092006470d000b200241306a20063602002002200736022c200220083602282002200a20056b36023c0c060b200241306a20063602002002200736022c2002200836022820080d050c040b102f000b200541011030000b200241003602280c010b200141011030000b20024100360250200242013703482002410c36022c2002200241106a3602282002200241c8006a360244200241fc006a41013602002002420137026c20024198c2c3003602682002200241286a360278200241c4006a41b8a3c500200241e8006a102e1a2002350250422086200235024884100820004100360200200228024c450d01200228024810230c010b20002002290328370200200041086a200241286a41086a2802003602000b2004450d00200310230b20024190016a24000bbe7a0d067f017e017f017e057f017e017f017e0a7f017e167f037e057f230041f0056b2200240020004180056a41186a2201420037030020004180056a41106a220242003703004108210320004180056a41086a220442003703002000420037038005200041b0026a41086a220541f7fbc400ad4280808080f0008422061003220741086a290000370300200020072900003703b0022007102320042005290300370300200020002903b0023703800520054194b7c200ad4280808080c001841003220741086a290000370300200020072900003703b00220071023200220002903b0022208370300200041b0046a41086a22092004290300370300200041b0046a41106a220a2008370300200041b0046a41186a220b2005290300370300200020083703e00320002000290380053703b004200041286a200041b0046a4120108f01200028022c210c2000280228210d200142003703002002420037030020044200370300200042003703800520054194fcc400ad42808080808001841003220741086a290000370300200020072900003703b0022007102320042005290300370300200020002903b002370380052005419ddfc000ad4280808080c000841003220741086a290000370300200020072900003703b0022007102320012005290300220837030020092004290300370300200a20002903b002220e370300200b20083703002000200e3703e00320002000290380053703b00420004180056a200041b0046a10bc01200028028005210f20002902840521102001420037030020024200370300200442003703002000420037038005200520061003220741086a290000370300200020072900003703b0022007102320042005290300370300200020002903b00237038005200541e7acc500ad4280808080a001841003220741086a290000370300200020072900003703b0022007102320012005290300220837030020092004290300370300200a20002903b0022206370300200b2008370300200020063703e00320002000290380053703b00420004180056a200041b0046a412010bb012000280280052207410120071b2111200029028405420020071b2208a7211202400240024002402008422088a72207450d002011200741057422136a2114200041c4036a211520004180056a41206a2116200041f8026a4104722117200041d0026a410472211841022107410021190340200041e0016a41186a201120196a221a41186a2900002208370300200041e0016a41106a201a41106a2900002206370300200041e0016a41086a201a41086a290000220e3703002000201a290000221b3703e0012018201b370200201841086a200e370200201841106a2006370200201841186a200837020020002007417e6a221c3602d0024100211d0240201c201810b7010d00200041f8026a41206a200041d0026a41206a280200360200200041f8026a41186a200041d0026a41186a290300370300200041f8026a41106a200041d0026a41106a290300370300200041f8026a41086a200041d0026a41086a290300370300200020002903d0023703f80220004190026a41186a221d201741186a221c29000037030020004190026a41106a221e201741106a221f29000037030020004190026a41086a2220201741086a222129000037030020002017290000370390022001201c2900003703002002201f290000370300200420212900003703002000201729000037038005200041a0036a20004180056a10be01200041b0026a41186a221c201d290300370300200041b0026a41106a221f201e2903003703002005202029030037030020002000290390023703b00220002802c003221d450d00201620002903a003370300201641186a200041a0036a41186a290300370300201641106a200041a0036a41106a290300370300201641086a200041a0036a41086a2903003703002001201c2903003703002002201f2903003703002004200529030037030020004180026a41086a221c201541086a280200360200200020002903b002370380052000201529020037038002200041b0046a41386a221e20004180056a41386a290300370300200041b0046a41306a221f20004180056a41306a290300370300200041b0046a41286a222020004180056a41286a290300370300200041b0046a41206a22212016290300370300200b2001290300370300200a20022903003703002009200429030037030020002000290380053703b004200041e0036a41386a201e290300370300200041e0036a41306a201f290300370300200041e0036a41286a2020290300370300200041e0036a41206a2021290300370300200041e0036a41186a200b290300370300200041e0036a41106a200a290300370300200041e0036a41086a2009290300370300200020002903b0043703e003200041d0036a41086a201c28020036020020002000290380023703d0030b200041a0016a41086a200041e0036a41086a290300370300200041a0016a41106a200041e0036a41106a290300370300200041a0016a41186a200041e0036a41186a290300370300200041a0016a41206a200041e0036a41206a290300370300200041a0016a41286a200041e0036a41286a290300370300200041a0016a41306a200041e0036a41306a290300370300200041a0016a41386a200041e0036a41386a29030037030020004190016a41086a200041d0036a41086a280200360200200020002903e0033703a001200020002903d00337039001201d0d02200741016a21072013201941206a2219470d000b0b410021222000410036029801200042083703900102402012450d00201110230b4100211d0c010b200041c0006a41386a2218200041a0016a41386a290300370300200041c0006a41306a2217200041a0016a41306a290300370300200041c0006a41286a2204200041a0016a41286a290300370300200041c0006a41206a221c200041a0016a41206a290300370300200041c0006a41186a2205200041a0016a41186a290300370300200041c0006a41106a2201200041a0016a41106a290300370300200041c0006a41086a221e200041a0016a41086a29030037030020004180016a41086a221f20004190016a41086a280200360200200020002903a001370340200020002903900137038001200041306a41086a2220201f280200360200200020002903800137033020004180056a41086a221f201e29030037030020004180056a41106a221e200129030037030020004180056a41186a2201200529030037030020004180056a41206a2205201c29030037030020004180056a41286a221c200429030037030020004180056a41306a2204201729030037030020004180056a41386a221720182903003703002000200029034037038005200041b0046a41086a22182020280200360200200020002903303703b00402400240024041d00010212203450d0020032000290380053703002003201d360240200320002903b004370244200341386a2017290300370300200341306a2004290300370300200341286a201c290300370300200341206a2005290300370300200341186a2001290300370300200341106a201e290300370300200341086a201f290300370300200341cc006a2018280200360200024002400240201341606a2019470d004101211d0c010b201a41206a2118201320196b41606a2105200041c4036a2120200041f8026a4104722117200041d0026a410472211a0340200041e0016a41186a201841186a2219290000370300200041e0016a41106a201841106a221d290000370300200041e0016a41086a201841086a2204290000370300200020182900003703e00120002007417f6a221c3602d00220042900002108201d29000021062018290000210e201a41186a2019290000370000201a41106a2006370000201a41086a2008370000201a200e370000410021190240201c201a10b7010d00200041f8026a41206a200041d0026a41206a280200360200200041f8026a41186a200041d0026a41186a290300370300200041f8026a41106a200041d0026a41106a290300370300200041f8026a41086a200041d0026a41086a290300370300200020002903d0023703f80220004190026a41186a2219201741186a220429000037030020004190026a41106a2201201741106a221c29000037030020004190026a41086a2213201741086a221e290000370300200020172900003703900220004180056a41186a221d200429000037030020004180056a41106a2204201c29000037030020004180056a41086a221c201e2900003703002000201729000037038005200041a0036a20004180056a10be01200041b0026a41186a221e2019290300370300200041b0026a41106a221f2001290300370300200041b0026a41086a2201201329030037030020002000290390023703b00220002802c0032219450d00201620002903a003370300201641186a200041a0036a41186a290300370300201641106a200041a0036a41106a290300370300201641086a200041a0036a41086a290300370300201d201e2903003703002004201f290300370300201c200129030037030020004180026a41086a2201202041086a280200360200200020002903b002370380052000202029020037038002200041b0046a41386a221320004180056a41386a290300370300200041b0046a41306a221e20004180056a41306a290300370300200041b0046a41286a221f20004180056a41286a290300370300200041b0046a41206a222120004180056a41206a290300370300200041b0046a41186a2209201d290300370300200041b0046a41106a221d2004290300370300200041b0046a41086a2204201c29030037030020002000290380053703b004200041e0036a41386a2013290300370300200041e0036a41306a201e290300370300200041e0036a41286a201f290300370300200041e0036a41206a2021290300370300200041e0036a41186a2009290300370300200041e0036a41106a201d290300370300200041e0036a41086a2004290300370300200020002903b0043703e003200041d0036a41086a200128020036020020002000290380023703d0030b200041a0016a41086a200041e0036a41086a290300370300200041a0016a41106a200041e0036a41106a290300370300200041a0016a41186a200041e0036a41186a290300370300200041a0016a41206a200041e0036a41206a290300370300200041a0016a41286a200041e0036a41286a290300370300200041a0016a41306a200041e0036a41306a290300370300200041a0016a41386a200041e0036a41386a29030037030020004190016a41086a200041d0036a41086a280200360200200020002903e0033703a001200020002903d0033703900120190d02201841206a21184101211d200741016a2107200541606a22050d000b0b410121220c030b200041c0006a41386a2223200041a0016a41386a221e290300370300200041c0006a41306a2224200041a0016a41306a221f290300370300200041c0006a41286a2225200041a0016a41286a2220290300370300200041c0006a41206a2226200041a0016a41206a2221290300370300200041c0006a41186a2227200041a0016a41186a2209290300370300200041c0006a41106a2228200041a0016a41106a220a290300370300200041c0006a41086a2229200041a0016a41086a220b29030037030020004180016a41086a222a20004190016a41086a2215280200360200200020002903a001370340200020002903900137038001200041306a41086a222b202a2802003602002000200029038001370330201841206a2118200041c4036a212c200041f8026a4104722117200041d0026a410472211a4101211d41012122034020004180056a41086a2205202929030037030020004180056a41106a2201202829030037030020004180056a41186a2213202729030037030020004180056a41206a222d202629030037030020004180056a41286a222e202529030037030020004180056a41306a222f202429030037030020004180056a41386a223020232903003703002000200029034037038005200041b0046a41086a2231202b280200360200200020002903303703b00402402022201d470d00201d41016a2204201d490d06201d410174221c2004201c20044b1b2222ad42d0007e2208422088a70d062008a722044100480d0602400240201d0d002004102121030c010b2003201d41d0006c2004102521030b2003450d030b2003201d41d0006c6a22042000290380053703002001290300210820132903002106202d290300210e202e290300211b202f2903002132203029030021332005290300213420042019360240200441086a2034370300200441386a2033370300200441306a2032370300200441286a201b370300200441206a200e370300200441186a2006370300200441106a2008370300200420002903b004370244200441cc006a2031280200360200201d41016a211d20182014460d030340200041e0016a41186a201841186a2219290000370300200041e0016a41106a201841106a2204290000370300200041e0016a41086a201841086a221c290000370300200020182900003703e001200020073602d002201c2900002108200429000021062018290000210e201a41186a2019290000370000201a41106a2006370000201a41086a2008370000201a200e3700004100211902402007201a10b7010d00200041f8026a41206a200041d0026a41206a280200360200200041f8026a41186a200041d0026a41186a290300370300200041f8026a41106a200041d0026a41106a290300370300200041f8026a41086a200041d0026a41086a290300370300200020002903d0023703f80220004190026a41186a2219201741186a220429000037030020004190026a41106a221c201741106a223529000037030020004190026a41086a2236201741086a223729000037030020002017290000370390022013200429000037030020012035290000370300200520372900003703002000201729000037038005200041a0036a20004180056a10be01200041b0026a41186a22042019290300370300200041b0026a41106a2235201c290300370300200041b0026a41086a221c203629030037030020002000290390023703b00220002802c0032219450d00201620002903a003370300201641186a200041a0036a41186a290300370300201641106a200041a0036a41106a290300370300201641086a200041a0036a41086a29030037030020132004290300370300200120352903003703002005201c29030037030020004180026a41086a2204202c41086a280200360200200020002903b002370380052000202c29020037038002200041b0046a41386a221c2030290300370300200041b0046a41306a2235202f290300370300200041b0046a41286a2236202e290300370300200041b0046a41206a2237202d290300370300200041b0046a41186a22382013290300370300200041b0046a41106a223920012903003703002031200529030037030020002000290380053703b004200041e0036a41386a201c290300370300200041e0036a41306a2035290300370300200041e0036a41286a2036290300370300200041e0036a41206a2037290300370300200041e0036a41186a2038290300370300200041e0036a41106a2039290300370300200041e0036a41086a2031290300370300200020002903b0043703e003200041d0036a41086a200428020036020020002000290380023703d0030b200b200041e0036a41086a290300370300200a200041e0036a41106a2903003703002009200041e0036a41186a2903003703002021200041e0036a41206a2903003703002020200041e0036a41286a290300370300201f200041e0036a41306a290300370300201e200041e0036a41386a2903003703002015200041d0036a41086a280200360200200020002903e0033703a001200020002903d00337039001024020190d00200741016a21072014201841206a2218460d050c010b0b2023201e2903003703002024201f2903003703002025202029030037030020262021290300370300202720092903003703002028200a2903003703002029200b290300370300202a2015280200360200200020002903a001370340200020002903900137038001202b202a2802003602002000200029038001370330201841206a2118200741016a21070c000b0b41d00041081030000b200441081030000b02402012450d00201110230b2000201d36029801200020223602940120002003360290010b20004180056a41186a2219420037030020004180056a41106a2217420037030020004180056a41086a221a42003703002000420037038005200041b0026a41086a220741f7fbc400ad4280808080f0008422081003221841086a290000370300200020182900003703b00220181023201a2007290300370300200020002903b0023703800520074194b7c200ad4280808080c0018422061003221841086a290000370300200020182900003703b00220181023200041e0036a41086a22162007290300220e370300200020002903b002221b3703e0032002201b370000200241086a2201200e370000200041b0046a41086a2204201a290300370300200041b0046a41106a22112017290300370300200041b0046a41186a2213201929030037030020002000290380053703b004200041206a200041b0046a4120108f012000280224211c2000280220210520074194fcc400ad4280808080800184220e1003221841086a290000370300200020182900003703b0022018102320042007290300370300200020002903b0023703b004200741d8e9c000ad4280808080a002841003221841086a290000370300200020182900003703b0022018102320162007290300370300200020002903b0023703e0032000201c410020051b3602a001200041b0026a41186a221c200041a0016aad4280808080c00084221b1001221841186a290000370300200041b0026a41106a2205201841106a2900003703002007201841086a290000370300200020182900003703b002201810232019201c29030037030020172005290300370300201a2007290300370300200020002903b0023703800502400240024002400240024002400240024002400240024002400240024041c00010212218450d00201820002903b004370000201820002903e0033700102018200029038005370020201841086a2004290300370000201841186a2016290300370000201841286a201a290300370000201841306a2017290300370000201841386a20192903003700002018ad4280808080800884100a201810232019420037030020174200370300201a42003703002000420037038005200720081003221841086a290000370300200020182900003703b00220181023201a2007290300370300200020002903b00237038005200720061003221841086a290000370300200020182900003703b00220181023201620072903002208370300200020002903b00222063703e00320022006370000200120083700002004201a290300370300201120172903003703002013201929030037030020002000290380053703b004200041186a200041b0046a4120108f01200028021c2102200028021821012007200e1003221841086a290000370300200020182900003703b0022018102320162007290300370300200020002903b0023703e003200741a9e4c000ad4280808080e001841003221841086a290000370300200020182900003703b0022018102320042007290300370300200020002903b0023703b00420002002410020011b3602a001201c201b1001221841186a2900003703002005201841106a2900003703002007201841086a290000370300200020182900003703b002201810232019201c29030037030020172005290300370300201a2007290300370300200020002903b0023703800541c00010212207450d0120104200200f1b210e200720002903e003370000200720002903b0043700102007200029038005370020200741086a200041e0036a41086a290300370000200741186a200041b0046a41086a290300370000200741286a20004180056a41086a2218290300370000200741306a20004180056a41106a290300370000200741386a20004180056a41186a2903003700002007ad4280808080800884100a200710230240201d450d0020004180056a20004190016a1078200041bb046a201828020036000020002000290380053700b304200041073a0080052000418c056a200041b0046a41076a290000370000200041023a008405200020002900b0043700850520004180056a108e01200041f8026a41106a20004190016a41086a2802003602002000200e422088a722393602fc022000200c4100200d1b22173602f802200020002903900137038003200041d0036a200041f8026a41086a107820002802d803211c20002802d403213820002802d0032122410410212212450d032012201736000020004284808080c0003702a401200020123602a001200041b0026a41086a220741effbc400ad42808080808001841003221841086a290000370300200020182900003703b00220181023200041e0036a41086a221a2007290300370300200020002903b0023703e003200741e4ecc200ad4280808080a002841003221841086a290000370300200020182900003703b00220181023200041b0046a41086a22182007290300370300200020002903b0023703b00420004190026a4187f4c20010bf0141c00010212207450d04200720002903e003370000200720002903b0043700102007200029039002370020200741086a201a290300370000200741186a2018290300370000200741286a20004190026a41086a290300370000200741306a200041a0026a290300370000200741386a20004190026a41186a29030037000020004180056a200741c00010c001200029028405210820002802800521182007102320002008420020181b22064220883e02b40420002018410120181b22053602b004200041106a200041b0046a106e200028021421044100211620002802100d0920002802b404220741246e221d41246c2218417f4c0d050240024020180d00410421160c010b201810212216450d070b2004450d0941002102034020074104490d09200241016a210120002007417c6a221a3602b404200020002802b004221941046a3602b0042019280000211141002107200041003a00a00503400240201a2007470d00200041003602b404200741ff0171450d0b200041003a00a0050c0b0b20004180056a20076a201920076a221841046a2d00003a00002000201841056a3602b0042000200741016a22183a00a0052018210720184120470d000b200041b0026a41086a221920004180056a41086a290300370300200041b0026a41106a221320004180056a41106a290300370300200041b0026a41186a221e20004180056a41186a29030037030020002000290380053703b0022000201a20186b22073602b4040240201d2002470d00200241017422182001201820014b1b221dad42247e2208422088a70d122008a722184100480d120240024020020d002018102121160c010b2016200241246c2018102521160b2016450d090b2016200241246c6a22182011360200201820002903b0023702042018410c6a2019290300370200201841146a20132903003702002018411c6a201e2903003702002001210220012004470d000c0a0b0b200041013a008405200041073a00800520004180056a108e012022450d09200310230c090b41c00041011030000b41c00041011030000b410441011030000b41c00041011030000b102f000b201841041030000b201841041030000b0240201d0d00410021160c010b20161023410021160b20004180056a200041a0016a10c101200041b0046a200028028005221820002802880510bb0120002802b004210720002902b40421080240200028028405450d00201810230b2008420020071b210802402006a7450d00200510230b201d410020161b21312016410420161b211d2007410120071b21362008a721350240024002400240024002400240201c450d002004410020161b21042008422088a721012022201c41d0006c6a210320004180056a410c6a211120004180056a41306a211e20004180056a41206a211f200041e0036a41c4006a210a200041a8046a21374100212c2022211602400240034020004180056a41386a22182016220741386a290300370300201e200741306a29030037030020004180056a41286a221a200741286a290300370300201f200741206a29030037030020004180056a41186a221c200741186a29030037030020004180056a41106a2205200741106a29030037030020004180056a41086a2202200741086a29030037030020004180026a41086a2219200741cc006a28020036020020002007290300370380052000200741c4006a29020037038002200741d0006a2116200741c0006a2802002207450d04200041c0006a41386a22132018290300370300200041c0006a41306a2218201e290300370300200041c0006a41286a2220201a290300370300200041c0006a41206a221a201f290300370300200041c0006a41186a2221201c290300370300200041c0006a41106a22092005290300370300200041c0006a41086a220b200229030037030020004180016a41086a221520192802003602002000200029038005370340200020002903800237038001200041e0036a41386a2013290300370300200041e0036a41306a22192018290300370300200041e0036a41286a2020290300370300200041e0036a41206a2213201a290300370300200041e0036a41186a2021290300370300200041e0036a41106a2009290300370300200041e0036a41086a200b290300370300200020002903403703e003200020073602a004200a200029038001370200200a41086a201528020036020002400240024002400240024041041021221a450d00201a201736000020114100290087f442370000201141086a410029008ff44237000020004284808080c000370284052000201a360280052000200041e0036a36029c05410810212207450d01200042083702b404200020073602b0042011200041b0046a10c2014104200041b0046a105c0240024020002802b404221820002802b80422076b4104490d0020002802b00421180c010b200741046a22202007490d17201841017422072020200720204b1b22074100480d170240024020180d002007102121180c010b20002802b00420182007102521180b2018450d03200020073602b404200020183602b00420002802b80421070b2000200741046a3602b804201820076a201a280000360000200041e0036a200041b0046a1071200020133602a003200041a0036a200041b0046a10c301200020193602a003200041a0036a200041b0046a10c30120002802a004210720372802002218200041b0046a105c02402018450d00201841306c21180340200741106a200041b0046a1071200020073602a003200741306a2107200041a0036a200041b0046a10c301201841506a22180d000b0b20002802b4042119200041b0026a41186a221320003502b80442208620002802b0042221ad841001220741186a290000370300200041b0026a41106a2220200741106a290000370300200041b0026a41086a2218200741086a290000370300200020072900003703b00220071023200041a0016a41186a220b2013290300370300200041a0016a41106a22152020290300370300200041a0016a41086a22142018290300370300200020002903b0023703a00102402019450d00202110230b201a1023201841effbc400ad428080808080018422081003220741086a290000370300200020072900003703b00220071023200041d0026a41086a22192018290300370300200020002903b0023703d002201841c2a3c200ad4280808080f0008422061003220741086a290000370300200020072900003703b00220071023200041a0036a41086a22132018290300370300200020002903b0023703a003200041b0046a200041a0016a10ac0141c00010212207450d03200720002903d002370000200720002903a003370010200720002900b004370020200741086a2019290300370000200741186a2013290300370000200741286a200041b0046a41086a2220290000370000200741306a200041b0046a41106a2221290000370000200741386a200041b0046a41186a2209290000370000200041086a200741c00041014100410010b8012000280208211a20071023201a4101470d0420002802a404450d0520002802a00410230c050b410441011030000b410841011030000b200741011030000b41c00041011030000b200041b0046a200041e0036a41d00010dc041a20004180056a200041b0046a41d00010dc041a200041003602d805200042013703d005201820081003220741086a290000370300200020072900003703b0022007102320192018290300370300200020002903b0023703d002201820061003220741086a290000370300200020072900003703b0022007102320132018290300370300200020002903b0023703a003200041b0046a200041a0016a10ac0102400240024041c0001021221a450d00201a20002903d002370000201a20002903a003370010201a20002900b004370020201a41086a2019290300370000201a41186a2013290300370000201a41286a2020290000370000201a41306a2021290000370000201a41386a2009290000370000200041003602b804200042013703b00420004180056a200041b0046a10712000201f3602a003200041a0036a200041b0046a10c3012000201e3602a003200041a0036a200041b0046a10c30120002802c005210720002802c8052218200041b0046a105c02402018450d00201841306c21180340200741106a200041b0046a1071200020073602a003200741306a2107200041a0036a200041b0046a10c301201841506a22180d000b0b20002802d005210720002802d8052218200041b0046a105c02402018450d002018410574211803402007200041b0046a1071200741206a2107201841606a22180d000b0b20002802b4042107201aad428080808080088420003502b80442208620002802b0042218ad84100202402007450d00201810230b201a1023024020002802c405450d0020002802c00510230b024020002802d405450d0020002802d00510230b201c200b2903003703002005201529030037030020022014290300370300200020002903a00137038005410021070240200441014b0d00024020040e020003000b200041e0016a41186a201c290300370300200041e0016a41106a2005290300370300200041e0016a41086a200229030037030020002000290380053703e001410021070c030b20042118034020072018410176221a20076a2219201d201941246c6a28020020174b1b21072018201a6b221841014b0d000c020b0b41c00041011030000b0240201d200741246c6a28020022182017460d00200720182017496a21070b200041e0016a41186a201c290300370300200041e0016a41106a2005290300370300200041e0016a41086a200229030037030020002000290380053703e001200420074f0d004180bbc000102b000b024020042031470d00200441016a22182004490d122004410174221a2018201a20184b1b2231ad42247e2208422088a70d122008a722184100480d120240024020040d0020181021211d0c010b201d200441246c20181025211d0b201d450d030b201d200741246c6a221841246a2018200420076b41246c10dd041a201820173602002018411c6a200041e0016a41186a290300370200201841146a200041e0016a41106a2903003702002018410c6a200041e0016a41086a290300370200201820002903e0013702042009201c290300370300202120052903003703002020200229030037030020002000290380053703b004024020012035470d00200141016a22072001490d12200141017422182007201820074b1b223541ffffff3f712035470d12203541057422074100480d120240024020010d002007102121360c010b203620014105742007102521360b2036450d040b200441016a2104203620014105746a220720002903b004370000200741186a2009290300370000200741106a2021290300370000200741086a20202903003700004101212c200141016a21010b20162003470d000b200321160c030b201841041030000b200741011030000b2038450d01202210230c010b024020162003460d000340201641c0006a2802002218450d01201641d0006a21070240201641c4006a280200450d00201810230b2007211620032007470d000b0b02402038450d00202210230b202c410171450d0002402001450d002001410574211820362107034020004180056a200710c40120002802c005221a0d03200741206a2107201841606a22180d000b0b4108211c41002105410021020c020b2012102302402035450d00203610230b2031450d02201d10230c020b200041e0036a41386a221c20004180056a41386a2219290300370300200041e0036a41306a222020004180056a41306a2205290300370300200041e0036a41286a222120004180056a41286a2202290300370300200041e0036a41206a220920004180056a41206a2211290300370300200041e0036a41186a220a20004180056a41186a2213290300370300200041e0036a41106a220b20004180056a41106a221e290300370300200041e0036a41086a221520004180056a41086a221f290300370300200041a0036a41086a220320004180056a41cc006a290200370300200041a0036a41106a221420004180056a41d4006a290200370300200041a0036a41186a223720004180056a41dc006a28020036020020002000290380053703e0032000200041c4056a22162902003703a003200041c0006a41086a222c2015290300370300200041c0006a41106a2215200b290300370300200041c0006a41186a220b200a290300370300200041c0006a41206a220a2009290300370300200041c0006a41286a22092021290300370300200041c0006a41306a22212020290300370300200041c0006a41386a2220201c290300370300200041a0016a41086a221c2003290300370300200041a0016a41106a22032014290300370300200041a0016a41186a22142037280200360200200020002903e003370340200020002903a0033703a001201f202c290300370300201e20152903003703002013200b2903003703002011200a2903003703002002200929030037030020052021290300370300201920202903003703002000200029034037038005200041b0046a41086a2220201c290300370300200041b0046a41106a22212003290300370300200041b0046a41186a22092014280200360200200020002903a0013703b00441e0001021221c450d04201c200029038005370300201c201a360240201c20002903b004370244201c41386a2019290300370300201c41306a2005290300370300201c41286a2002290300370300201c41206a2011290300370300201c41186a2013290300370300201c41106a201e290300370300201c41086a201f290300370300201c41cc006a2020290300370200201c41d4006a2021290300370200201c41dc006a2009280200360200024020184120470d0041012105410121020c010b200741206a211f203620014105746a221a41606a211441012105410121020340201f21070240034020004180056a200710c40120002802c00522180d01201a200741206a2207470d000c030b0b200041e0036a41386a221920004180056a41386a2220290300370300200041e0036a41306a221f20004180056a41306a2221290300370300200041e0036a41286a223720004180056a41286a2209290300370300200041e0036a41206a222c20004180056a41206a220a290300370300200041e0036a41186a221120004180056a41186a220b290300370300200041e0036a41106a221320004180056a41106a2215290300370300200041e0036a41086a221e20004180056a41086a2203290300370300200041a0036a41086a2222201641086a290200370300200041a0036a41106a2238201641106a290200370300200041a0036a41186a220c201641186a28020036020020002000290380053703e003200020162902003703a003200041b0046a41086a220d201e290300370300200041b0046a41106a222d2013290300370300200041b0046a41186a222e2011290300370300200041b0046a41206a222f202c290300370300200041b0046a41286a222c2037290300370300200041b0046a41306a2237201f290300370300200041b0046a41386a221f2019290300370300200041a0016a41086a22192022290300370300200041a0016a41106a22222038290300370300200041a0016a41186a2238200c280200360200200020002903e0033703b004200020002903a0033703a0012003200d2903003703002015202d290300370300200b202e290300370300200a202f2903003703002009202c290300370300202120372903003703002020201f290300370300200020002903b00437038005201e20192903003703002013202229030037030020112038280200360200200020002903a0013703e003024020022005470d00200541016a22192005490d0b200541017422022019200220194b1b2202ad42e0007e2208422088a70d0b2008a722194100480d0b0240024020050d0020191021211c0c010b201c200541e0006c20191025211c0b201c450d070b200741206a211f201c200541e0006c6a2219200029038005370300201941106a2015290300370300201941086a200329030037030020212903002108202029030021062009290300211b200a2903002110200b2903002132201941c0006a2018360200201941186a2032370300201941206a2010370300201941286a201b370300201941386a2006370300201941306a2008370300201941c4006a20002903e003370200201941cc006a201e290300370200201941d4006a2013290300370200201941dc006a2011280200360200200541016a210520142007470d000b0b200041a0056a20043602002000419c056a203136020020004190056a2001ad4220862035ad843703002000203636028c0520004284808080c0003702840520002012360280052000201d36029805200041003602b804200042013703b0042004200041b0046a105c02402004450d00201d200441246c6a2104201d21180340201828020021190240024020002802b404221a20002802b80422076b4104490d0020002802b004211a0c010b200741046a22162007490d0b201a41017422072016200720164b1b22074100480d0b02400240201a0d0020071021211a0c010b20002802b004201a20071025211a0b201a450d08200020073602b4042000201a3602b00420002802b80421070b2000200741046a3602b804201a20076a20193600002000200041b0046a3602e003201841046a200041e0036a106b201841246a22182004470d000b0b20002802b804211920002802b404211620002802b004211a200041b0026a41086a220741effbc400ad42808080808001841003221841086a290000370300200020182900003703b00220181023200041e0036a41086a22042007290300370300200020002903b0023703e003200741e4ecc200ad4280808080a002841003221841086a290000370300200020182900003703b00220181023200041b0046a41086a22182007290300370300200020002903b0023703b00420004190026a4187f4c20010bf0141c00010212207450d06200720002903e003370000200720002903b0043700102007200029039002370020200741086a2004290300370000200741186a2018290300370000200741286a20004190026a41086a290300370000200741306a200041a0026a290300370000200741386a20004190026a41186a290300370000200041c0003602b404200020073602b004201a2019200041b0046a10c5012007102302402016450d00201a10230b200041e0036a20004180056a10c10120003502e803210820002802e003211a200041003602b804200042013703b0042001200041b0046a105c02402001450d00200141057421182036210703402000200041b0046a3602a0012007200041a0016a106b200741206a2107201841606a22180d000b0b20002802b40421072008422086201aad8420003502b80442208620002802b0042218ad84100202402007450d00201810230b024020002802e403450d00201a10230b2012102302402035450d00203610230b02402031450d00201d10230b201c0d010b200028028003211a024020004188036a2802002207450d00200741d0006c2118201a41c0006a210703400240200741046a280200450d00200728020010230b200741d0006a2107201841b07f6a22180d000b0b20004184036a280200450d01201a10230c010b410410212207450d052007201736000020004188056a4284808080c0003703004100211a20004190056a4100290087f44237030020004198056a410029008ff4423703002000200736028405200041043a00800520004180056a108e0102402039410a6e417f7320056a221820054b0d002000418094ebdc0336028405200020394101203941014b1b2207201841036c221820072018491b2007418094ebdc036e22184101201841014b1b22186ead428094ebdc037e200720186ead8042ffffffff0f834280bbb0217e428094ebdc0380a722073602800520004180056a2007418094ebdc034b4102746a280200211a0b0240024002402005450d00200541ffffffff03712005470d09200541027422074100480d092007102122190d01200741041030000b201c410041044100201710c6010c010b200521182019210703402007201a360200200741046a21072018417f6a22180d000b201c200520192005201710c60102402005450d00201910230b2005450d00200541e0006c2118201c41d4006a210703400240200741706a280200450d002007416c6a28020010230b02402007280200450d002007417c6a28020010230b200741e0006a2107201841a07f6a22180d000b0b02402002450d00201c10230b200028028003211a024020004188036a2802002207450d00200741d0006c2118201a41c0006a210703400240200741046a280200450d00200728020010230b200741d0006a2107201841b07f6a22180d000b0b20004184036a280200450d00201a10230b0240200ea7450d00200f4101200f1b10230b200041f0056a24000f0b41e00041081030000b201941081030000b200741011030000b41c00041011030000b410441011030000b102a000bc30701067f23004190016b22022400200241d0006a41086a220341c6acc500ad4280808080f000841003220441086a2900003703002002200429000037035020041023200241386a41086a2205200329030037030020022002290350370338200341fdacc500ad4280808080f000841003220441086a2900003703002002200429000037035020041023200241186a41086a2206200329030037030020022002290350370318200241d0006a200110ac01024041c00010212204450d00200420022903383700002004200229031837001020042002290050370020200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241d0006a41106a2205290000370000200441386a200241d0006a41186a2206290000370000200241c00036024c20022004360248200241386a2004ad4280808080800884100410900102400240200228023822010d00410021030c010b200228023c21072002200241386a41086a280200360284012002200136028001200241d0006a20024180016a10fe020240024020022802702203450d00200241186a41186a200241d0006a41186a290300370300200241186a41106a200241d0006a41106a290300370300200241186a41086a200241d0006a41086a290300370300200241086a41086a200241fc006a28020036020020022002290350370318200220022902743703080c010b4100210320024100360220200242013703182002410c36020c2002200241c8006a3602082002200241186a36028c01200241e4006a41013602002002420137025420024198c2c3003602502002200241086a3602602002418c016a41b8a3c500200241d0006a102e1a20023502204220862002350218841008200228021c450d00200228021810230b2007450d00200110230b200241d0006a41086a2201200241186a41086a2903003703002005200241186a41106a2903003703002006200241186a41186a290300370300200241386a41086a2205200241086a41086a2802003602002002200229031837035020022002290308370338024002402003450d002000200229035037030020002003360220200041246a2002290338370200200041186a200241d0006a41186a290300370300200041106a200241d0006a41106a290300370300200041086a20012903003703002000412c6a20052802003602000c010b2000420037030020004208370320200041186a4200370300200041106a4200370300200041086a4200370300200041286a41003602000b2004102320024190016a24000f0b41c00041011030000bbe0301057f230041206b2202240020012d0000210302400240024002400240410110212204450d00200420033a000020012d0001210320044101410210252204450d01200420033a000120012d0002210320044102410410252204450d02200420033a0002200420012d00033a000320012d0004210320044104410810252204450d03200420033a0004200420012d00053a0005200420012d00063a0006200420012d00073a000720012d0008210320044108411010252204450d04200420033a0008200420012d00093a0009200420012d000a3a000a200420012d000b3a000b200420012d000c3a000c200420012d000d3a000d200420012d000e3a000e200420012d000f3a000f200241186a22032004ad42808080808002841001220141186a290000370300200241106a2205200141106a290000370300200241086a2206200141086a2900003703002002200129000037030020011023200041186a2003290300370000200041106a2005290300370000200041086a20062903003700002000200229030037000020041023200241206a24000f0b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000bc00301057f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841004109001024002400240200328021022010d00200041003602000c010b200328021421022003200341186a280200360224200320013602202003200341206a106e024002400240024020032802000d002003280224220420032802042205490d0120054100480d0502400240024020050d00410121060c010b200510272206450d01200620032802202207200510dc041a2003200420056b3602242003200720056a3602200b200341c8006a41086a2005360200200041086a20053602002003200536024c20032006360248200020032903483702000c040b200541011030000b200341003602480c010b200341003602480b20034100360230200342013703282003410c36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034198c2c3003602482003200341386a360258200341c4006a41b8a3c500200341c8006a102e1a2003350230422086200335022884100820004100360200200328022c450d00200328022810230b2002450d00200110230b200341e0006a24000f0b102f000baf0601077f230041d0006b22022400200241306a41086a220341effbc400ad42808080808001841003220441086a2900003703002002200429000037033020041023200241206a41086a2205200329030037030020022002290330370320200341a0ecc200ad4280808080e002841003220441086a2900003703002002200429000037033020041023200241086a2206200329030037030020022002290330370300200241306a4187f4c20010bf0102400240024002400240024041c00010212204450d00200420022903203700002004200229030037001020042002290030370020200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241c0006a290000370000200441386a200241306a41186a2900003700002001280208220341046a2205417f4c0d01200128020021070240024020050d00410121010c010b200510212201450d030b2002410036023820022005360234200220013602302003200241306a105c0240024020022802342206200228023822016b2003490d00200228023021050c010b200120036a22052001490d05200641017422082005200820054b1b22084100480d050240024020060d002008102121050c010b200228023020062008102521050b2005450d042002200836023420022005360230200821060b200520016a2007200310dc041a200241306a41186a2207200120036aad4220862005ad841001220341186a290000370300200241306a41106a2201200341106a290000370300200241306a41086a2208200341086a2900003703002002200329000037033020031023200241186a2007290300370300200241106a2001290300370300200241086a20082903003703002002200229033037030002402006450d00200510230b200441c00041800110252204450d0520042002290300370040200441d8006a200241186a290300370000200441d0006a200241106a290300370000200441c8006a200241086a29030037000020004280818080800c37020420002004360200200241d0006a24000f0b41c00041011030000b102f000b200541011030000b200841011030000b102a000b41800141011030000bcc1501047f20002d000021020240024002400240024002400240024002400240024002400240024002400240024002400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0001210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0002210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0003210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0004210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0005210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0006210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0007210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0008210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0009210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000a210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000b210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000c210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000d210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000e210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000f210402400240200141046a28020020052802002200460d00200128020021030c010b200041016a22032000490d11200041017422022003200220034b1b22024100480d110240024020000d002002102121030c010b200128020020002002102521030b2003450d1020012003360200200141046a2002360200200141086a28020021000b200141086a200041016a360200200320006a20043a00000f0b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200241011030000b102a000b800a03017f027e057f230041e0006b2202240002400240024002400240024002400240024002400240200028020022002903002203423f56200041086a290300220442005220045022051b0d0002400240200141046a280200200141086a2802002200460d00200128020021050c010b200041016a22052000490d0b200041017422062005200620054b1b22064100480d0b0240024020000d002006102121050c010b200128020020002006102521050b2005450d0220012005360200200141046a2006360200200141086a28020021000b200141086a200041016a360200200520006a2003a74102743a00000c080b20034280800154410020051b0d06200342808080800454410020051b0d05411020047920037942c0007c20044200521ba741037622066b4104490d0402400240200141046a280200200141086a2802002205460d00200128020021070c010b200541016a22082005490d0a200541017422072008200720084b1b22084100480d0a0240024020050d002008102121070c010b200128020020052008102521070b2007450d0220012007360200200141046a2008360200200141086a28020021050b200141086a2208200541016a360200200720056a413320064102746b3a0000200029030021032002200041086a290300220437030820022003370300200641706a2105200141046a2107034002400240200728020020082802002200460d00200128020021060c010b200041016a22062000490d0b200041017422092006200920064b1b22094100480d0b0240024020000d002009102121060c010b200128020020002009102521060b2006450d042001200636020020072009360200200828020021000b2008200041016a360200200620006a2003a73a00002003420888200442388684210320044208882104200541016a22002005492106200021052006450d000b2002200337030020022004370308200320048450450d030c070b200641011030000b200841011030000b200941011030000b200241286a41146a410d360200200241346a4110360200200241106a41146a41033602002002200236024020024188a9c30036024420024203370214200241acb6c6003602102002411036022c200242043703582002420137024c200241e0a7c3003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a4198a9c3001038000b41eca8c300102b000b024002400240200141046a2802002205200141086a28020022006b4104490d00200128020021050c010b200041046a22062000490d05200541017422002006200020064b1b22004100480d050240024020050d002000102121050c010b200128020020052000102521050b2005450d0120012005360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200520006a2003a74102744102723600000c020b200041011030000b02400240200141046a2802002205200141086a28020022006b4102490d00200128020021050c010b200041026a22062000490d03200541017422002006200020064b1b22004100480d030240024020050d002000102121050c010b200128020020052000102521050b2005450d0220012005360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200520006a2003a74102744101723b00000b200241e0006a24000f0b200041011030000b102a000bf20c020e7f017e23004180026b22022400200241a0016a41086a220341effbc400ad42808080808001841003220441086a290000370300200220042900003703a00120041023200241086a22052003290300370300200220022903a001370300200341c2a3c200ad4280808080f000841003220441086a290000370300200220042900003703a00120041023200241e0006a41086a22042003290300370300200220022903a001370360200241a0016a200110ac01024041c00010212201450d002001200229030037000020012002290360370010200120022900a001370020200141086a2005290300370000200141186a2004290300370000200141286a2003290000370000200141306a200241a0016a41106a2206290000370000200141386a200241a0016a41186a2207290000370000200241c00036024420022001360240200241c8006a2001ad4280808080800884100410900102400240200228024822050d00410021030c010b200228024c21082002200241d0006a280200220936025c2002200536025841002103200241003a00200240024002400340024020092003470d002002410036025c200341ff0171450d02200241003a00200c020b200220036a200520036a22042d00003a00002002200441016a3602582002200341016a22043a00202004210320044120470d000b200241e0016a41086a220a200241086a220b290300370300200241e0016a41106a220c200241106a220d290300370300200241e0016a41186a220e200241186a220f290300370300200220022903003703e0012002200920046b36025c2002200241d8006a10fe0220022802202203450d00200241a0016a41186a2209200e290300370300200241a0016a41106a220e200c290300370300200241a0016a41086a220c200a290300370300200241a0016a41286a220a200b290300370300200241a0016a41306a220b200d290300370300200241a0016a41386a220d200f290300370300200220022903e0013703a001200220022903003703c001200241246a2802002104200241286a220f2903002110200241e0006a41086a200c290300370300200241e0006a41106a200e290300370300200241e0006a41186a2009290300370300200241e0006a41206a220920022903c001370300200241e0006a41286a220c200a290300370300200241e0006a41306a220a200b290300370300200241e0006a41386a220b200d290300370300200220022903a001370360200241a0016a200241d8006a107e20022802a0010d012004450d00200310230b4100210320024100360268200242013703602002410c3602042002200241c0006a3602002002200241e0006a3602e001200241b4016a4101360200200242013702a40120024198c2c3003602a001200220023602b001200241e0016a41b8a3c500200241a0016a102e1a2002350268422086200235026084100802402002280264450d00200228026010230b0c010b200241e0016a41086a200241a0016a41086a280200360200200241086a200241e0006a41086a290300370300200241106a200241e0006a41106a290300370300200241186a200241e0006a41186a290300370300200241206a2009290300370300200f200c290300370300200241306a200a290300370300200241386a200b290300370300200220022903a0013703e001200220022903603703000b2008450d00200510230b200241a0016a41086a2205200241086a2903003703002006200241106a2903003703002007200241186a290300370300200241a0016a41206a2209200241206a290300370300200241a0016a41286a200241286a290300370300200241a0016a41306a200241306a290300370300200241a0016a41386a200241386a290300370300200220022903003703a001200241e0006a41086a2206200241e0016a41086a280200360200200220022903e00137036002402003450d00200020022903a00137030020002004360244200041c8006a2010370200200041386a200241a0016a41386a290300370300200041306a200241a0016a41306a290300370300200041286a200241a0016a41286a290300370300200041206a2009290300370300200041186a200241a0016a41186a290300370300200041106a200241a0016a41106a290300370300200041086a2005290300370300200041d8006a2006280200360200200041d0006a20022903603702000b200020033602402001102320024180026a24000f0b41c00041011030000b9d0201057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410212205450d020b20034100360208200320043602042003200536020020012003105c0240024020032802042206200328020822056b2001490d00200328020021040c010b200520016a22042005490d04200641017422072004200720044b1b22074100480d040240024020060d002007102121040c010b200328020020062007102521040b2004450d032003200736020420032004360200200721060b200420056a2000200110dc041a2002290200200520016aad4220862004ad84100202402006450d00200410230b200341106a24000f0b102f000b200441011030000b200741011030000b102a000be94312057f017e017f017e027f027e047f017e067f017e067f027e027f017e067f027e017f027e230041f0036b22052400200541c8036a41186a22064200370300200541c8036a41106a22074200370300200541c8036a41086a22084200370300200542003703c80320054188036a41086a220941c6acc500ad4280808080f00084220a1003220b41086a2900003703002005200b29000037038803200b1023200820092903003703002005200529038803220c3703c8022005200c3703c80320094190fcc500ad4280808080b002841003220b41086a2900003703002005200b29000037038803200b10232007200529038803220c37030020054198036a41086a220b200829030037030020054198036a41106a220d200c37030020054198036a41186a220e20092903003703002005200c3703d802200520052903c80337039803200541203602ec01200520054198036a3602e80120054188026a20054198036aad220f4280808080800484221010041090010240024020052802880222110d00410021120c010b200528028c0221130240024020054188026a41086a2802004104490d0020112800002114410121120c010b41002112200541003602b002200542013703a8022005410c36028c032005200541e8016a360288032005200541a8026a3602d802200541dc036a4101360200200542013702cc0320054198c2c3003602c803200520054188036a3602d803200541d8026a41b8a3c500200541c8036a102e1a20053502b00242208620053502a802841008024020052802ac02450d0020052802a80210230b0b2013450d00201110230b200642003703002007420037030020084200370300200542003703c8032009200a1003221141086a290000370300200520112900003703880320111023200820092903003703002005200529038803220c3703c8022005200c3703c803200941b0fac500ad4280808080a001841003221141086a290000370300200520112900003703880320111023200541d8026a41086a22132009290300220c370300200520052903880322153703d80220072015370000200741086a2216200c370000200b2008290300370300200d2007290300370300200e2006290300370300200520052903c80337039803200541e0016a20054198036a4120108f0120052802e401211720052802e0012118200642003703002007420037030020084200370300200542003703c8032009200a1003221141086a290000370300200520112900003703880320111023200820092903003703002005200529038803220a3703c8022005200a3703c803200941e8fac500ad4280808080b003841003221141086a29000037030020052011290000370388032011102320132009290300220a3703002005200529038803220c3703d8022007200c3700002016200a370000200b2008290300370300200d2007290300370300200e2006290300370300200520052903c80337039803200541d8016a20054198036a4120108f012017410020181b2219211702400240024020052802dc01410020052802d8011b20044d0d00200541c8036a41186a220b4200370300200541c8036a41106a220d4200370300200541c8036a41086a22084200370300200542003703c80320054188036a41086a220941c6acc500ad4280808080f000841003220641086a290000370300200520062900003703880320061023200820092903003703002005200529038803220a3703c8022005200a3703c803200941d0fdc500ad4280808080a001841003220641086a290000370300200520062900003703880320061023200541d8026a41086a2009290300220a3703002005200529038803220c3703d8022007200c370000200741086a200a37000020054198036a41086a200829030037030020054198036a41106a200d29030037030020054198036a41186a200b290300370300200520052903c80337039803200541c8036a20054198036a10af0320052802c8032209410420091b220b20052902cc03420020091b220a422088a741037422096a210803402009450d02200941786a21092008417c6a2106200841786a2108200628020020044b0d000b200b20096a2802002117200aa7450d00200b10230b200541c8036a41186a22184200370300200541c8036a41106a221a4200370300200541c8036a41086a22164200370300200542003703c80320054188036a41086a221b41c6acc500ad4280808080f00084221c1003220941086a2900003703002005200929000037038803200910232016201b2903003703002005200529038803220a3703c8022005200a3703c803201b41f8ffc500ad4280808080e00284220a1003220941086a290000370300200520092900003703880320091023200541d8026a41086a221d201b290300220c370300200520052903880322153703d80220072015370000200741086a221e200c37000020054198036a41086a2213201629030037030020054198036a41106a221f201a29030037030020054198036a41186a22202018290300370300200520052903c80337039803200541d0016a20054198036a4120108f0120052802d401210820052802d001210620184200370300201a420037030020164200370300200542003703c803201b201c1003220941086a2900003703002005200929000037038803200910232016201b2903003703002005200529038803220c3703c8022005200c3703c803201b200a1003220941086a290000370300200520092900003703880320091023201d201b290300220a3703002005200529038803220c3703d8022007200c370000201e200a37000020132016290300370300201f201a29030037030020202018290300370300200520052903c8033703980320052008201920064101461b3602c8032010200541c8036aad4280808080c00084100220032001200120034b1b2221450d012014410020121b212220054188036aad4280808080c000842123200f42808080808002842124201941016a21252000211141002126024002400240024002400240034020184200370300201a420037030020164200370300200542003703c803201b201c1003220941086a2900003703002005200929000037038803200910232016201b2903003703002005200529038803220a3703c8022005200a3703c803201b41e4f7c500ad4280808080d001841003220941086a290000370300200520092900003703880320091023201d201b290300220a3703002005200529038803220c3703d8022007200c370000201e200a37000020132016290300370300201f201a29030037030020202018290300370300200520052903c80337039803200541c8036a20054198036a412010bb0120052902cc03420020052802c80322091b220a422088a741057421082026220641016a2126200220064102746a210e2000200641e0006c6a210b2009410120091b220d210902400340024020080d00410021040c020b4101210420112009460d012009200b412010de042106200841606a2108200941206a210920060d000b0b0240200aa7450d00200d10230b0240024020040d00200e2802002109200542003703d002200542003703c802200541c0016a200b290320220a200b41286a290300428094ebdc03420010e204200541a0016a200b290330220c200b41386a290300428094ebdc03420010e204200541b0016a20052903c0012210200541c0016a41086a290300220f4280ec94a37c427f10e104200541f0006a2010200f2009ad2215420010e10420054190016a20052903a0012210200541a0016a41086a290300220f4280ec94a37c427f10e10420054180016a2010200f2015420010e104200542003703e002200542003703d802200c2005290390017c20157e2210428094ebdc0380210c024002400240024002400240024002400240024020052903704200200a20052903b0017c20157e220a200a428094ebdc0380220a4280ec94a37c7e7c4280cab5ee0156200aa76a2208ad7d85200541f0006a41086a29030042002008410047ad7d8584500d00200529038001210a20054180016a41086a290300212720054188026a2017200b10aa042005280288022108200520052802900222063602ec01200520083602e801200541a8026a2006ad4220862008ad8410041090010240024020052802a80222060d004200210f0c010b20052802ac0221040240024020052802b002220d4104490d00200d417c6a410f4d0d00200628000021284201210f0c010b200541003602d003200542013703c8032005410c36028c032005200541e8016a360288032005200541c8036a3602ec03200541013602ac032005420137029c0320054198c2c30036029803200520054188036a3602a803200541ec036a41b8a3c50020054198036a102e1a20053502d00342208620053502c803841008024020052802cc03450d0020052802c80310230b4200210f0b2004450d00200610230b0240200528028c02450d00200810230b200920284100200f4200521b22034d0d0a20054198036a2017200b10aa0420053502a003210f2005280298032106411010212208450d042008200936000020084110412010252209450d052009200a2010200c4280ec94a37c7e7c4280cab5ee0156200ca76aad7c220c3700042009410c6a2027200c200a54ad7c220a370000200f4220862006ad842009ad4280808080c002841002200910230240200528029c03450d00200610230b200541a8026a200b10b20420052802b002450d0120054188026a41106a200541a8026a41106a28020036020020054188026a41086a200541a8026a41086a290300370300200520052903a802370388020c020b20054200370390032005420037038803200542003703f001200542003703e801200541a8026a200b10b2040240024020052802b002450d0020054188026a41106a200541a8026a41106a28020036020020054188026a41086a200541a8026a41086a290300370300200520052903a802370388020c010b200541003602d803200542043703d003200520193602cc03200541003602c803200b200541c8036a10b30420054188026a41106a20052802d80336020020054188026a41086a20052903d003370300200520052903c803370388020b2013200529038802370200201341086a20054188026a41086a290300370200201341106a20054188026a41106a280200360200200541003a00c0032005200b36029c032005201936029803200520223602bc032005200541e8016a3602b803200520054188036a3602b403200541c8036a20054198036a201710c604024020052802d0034102460d0020052802c803220d20052802a003470d00410021090240202520052802a40322064d0d00024020052802b003220820052802ac03470d00200841016a22092008490d13200841017422042009200420094b1b220941ffffffff03712009470d132009410274220e4100480d130240024020080d00200e102121040c010b20052802a8032008410274200e102521040b2004450d05200520093602ac03200520043602a8030b20052802a803220941046a2009200841027410dd041a2009202520066b360200200520253602a403410121092005200841016a3602b0032005200d41016a220d3602a0030b200520093a00c003200b10ac04200b10ae040240200b10e90241ff017122084102460d002008410171450d0010bb040b2009450d0020052802a403210e02400240024020052802b0032201450d0020052802a80321082001410274210441002106200e210902400340200920194d0d01200641016a2106200920082802006b2109200841046a21082004417c6a22040d000c020b0b200120064f0d010b2005200e2019200e20194b1b3602a4030c010b2005200e2019200e20194b1b3602a403200520063602b00341000d00200d20016b200d20066b4f0d00410020016b210903402016200b41086a290200370300201a200b41106a2902003703002018200b41186a2902003703002005200b2902003703c8032005200d20096a3602e803200541c8036a10b4042006200941016a22096a0d000b0b200b201310b3040b20052802ac03450d0920052802a80310230c090b200541003602d803200542043703d003200520193602cc03200541003602c803200b200541c8036a10b30420054188026a41106a20052802d80336020020054188026a41086a20052903d003370300200520052903c803370388020b2013200529038802370200201341086a222920054188026a41086a222a290300370200201341106a222b20054188026a41106a222c280200360200200541003a00c0032005200b36029c032005201936029803200520223602bc032005200541d8026a3602b8032005200541c8026a3602b403200541e8006a20054198036a2017200c200a10c70420052802a003210e0240024020052802684101470d00200528026c2208200e460d010b20052d00c00321090c070b202520052802a40322094d0d04024020052802b003220620052802ac03470d00200641016a22042006490d0f2006410174220d2004200d20044b1b220441ffffffff03712004470d0f2004410274220e4100480d0f0240024020060d00200e1021210d0c010b20052802a8032006410274200e1025210d0b200d450d04200520043602ac032005200d3602a8030b20052802a803220441046a2004200641027410dd041a2004202520096b360200200520253602a403410121092005200641016a3602b0032005200841016a22083602a0030c050b200e41041030000b411041011030000b412041011030000b200e41041030000b20052d00c00321090b200520093a00c003200b10ac04200b10ae040240200b10e90241ff017122064102460d002006410171450d0010bb040b2008210e0b0240200941ff0171450d0020052802a4032101200528029803210d02400240024020052802b0032212450d0020052802a8032108201241027421044100210620012109024003402009200d4d0d01200641016a2106200920082802006b2109200841046a21082004417c6a22040d000c020b0b201220064f0d010b20052001200d2001200d4b1b3602a4030c010b20052001200d2001200d4b1b3602a403200520063602b00341000d00200e20126b200e20066b4f0d00410020126b2108200528029c0321090340200941086a290000210a200941106a290000210c200929000021102018200941186a290000370300201a200c3703002016200a370300200520103703c8032005200e20086a3602e803200541c8036a10b4042006200841016a22086a0d000b0b200528029c03201310b3040b024020052802ac03450d0020052802a80310230b4200210a200542003703900320054200370388030240024002400240200b41c8006a220928020022080d00410821120c010b2008ad220a42307e220c422088a70d0a200ca722084100480d0a200810212212450d0b200928020022090d010b420021104200210f0c010b200b41c0006a2802002201200941306c6a212d2003ad212e0340200542003703f001200542003703e801200541c0006a2001290300220f200141086a290300428094ebdc03420010e204200541306a2005290340220c200541c0006a41086a29030022104280ec94a37c427f10e104200541206a200c2010202e420010e104200541106a200c20102015420010e10420054198036a2017200141106a220d10ab04200541d0006a200528029803220820052802a0031089024200200541106a41086a29030020052903102210200f20052903307c220f20157e220c200c428094ebdc0380220c4280ec94a37c7e7c4280cab5ee0156200ca76aad7c220c201054ad7c2210200541206a41086a29030020052903202227200f202e7e220f200f428094ebdc0380220f4280ec94a37c7e7c4280cab5ee0156200fa76aad7c220f202754ad7c7d200c200f54ad7d2227200c200f7d220f200c56202720105620272010511b22091b21104200200f20091b210c200541d0006a41106a290300210f20052903582127200528025021090240200528029c03450d00200810230b200541c8036a2017200d10ab0420052802c803210820053502d003212f20052027420020091b2227200c7c220c370398032005200f420020091b20107c200c202754ad7c22103703a003202f4220862008ad8420241002024020052802cc03450d00200810230b200541a8026a200d10b2040240024020052802b002450d00202c200541a8026a41106a280200360200202a200541a8026a41086a290300370300200520052903a802370388020c010b200541003602d803200542043703d003200520193602cc03200541003602c803200d200541c8036a10b304202c20052802d803360200202a20052903d003370300200520052903c803370388020b20132005290388023702002029202a290300370200202b202c280200360200200541003a00c0032005200d36029c032005201936029803200520223602bc032005200541e8016a3602b803200520054188036a3602b403200541086a20054198036a2017200c201010c70420052802a003210302400240024020052802084101470d00200528020c22062003460d010b20052d00c00321090c010b02400240202520052802a40322094d0d000240024020052802b003220820052802ac03470d00200841016a22042008490d0e2008410174220e2004200e20044b1b220441ffffffff03712004470d0e200441027422034100480d0e0240024020080d0020031021210e0c010b20052802a803200841027420031025210e0b200e450d01200520043602ac032005200e3602a8030b20052802a803220441046a2004200841027410dd041a2004202520096b360200200520253602a403410121092005200841016a3602b0032005200641016a22033602a0030c020b200341041030000b20052d00c0032109200621030b200520093a00c003200d10ac04200d10ae040b0240200941ff0171450d0020052802a4032114200528029803210e02400240024020052802b0032230450d0020052802a8032108203041027421044100210620142109024003402009200e4d0d01200641016a2106200920082802006b2109200841046a21082004417c6a22040d000c020b0b203020064f0d010b20052014200e2014200e4b1b3602a4030c010b20052014200e2014200e4b1b3602a403200520063602b00341000d00200320306b200320066b4f0d00410020306b2108200528029c0321090340200941086a290000210c200941106a29000021102009290000210f2018200941186a290000370300201a20103703002016200c3703002005200f3703c8032005200320086a3602e803200541c8036a10b4042006200841016a22086a0d000b0b200528029c03201310b3040b024020052802ac03450d0020052802a80310230b200d41086a290000210c200d29000021102020200d41186a290000370300201f200d41106a2900003703002013200c3703002005201037039803200541e8016a41086a290300210c20052903e801211002400240200a422088220fa72209200aa7460d00200921080c010b200941016a22062009490d0a200fa722084101742204200620062004491bad220a42307e220f422088a70d0a200fa722064100480d0a0240024020090d002006102121120c010b2012200941306c2006102521120b2012450d040b2013290300210f201f29030021272020290300212f20052903980321312012200841306c6a2209201037032020092031370300200941286a200c370300200941186a202f370300200941106a2027370300200941086a200f370300200a42ffffffff0f83200841016aad42208684210a200141306a2201202d470d000b201b290300210f20052903880321100b200541c8026a41086a2204290300212720052903c8022115200541e8016a41086a2209200b41086a290300370300200541e8016a41106a2208200b41106a290300370300200541e8016a41186a2206200b41186a2903003703002005200b2903003703e8012012450d00201d290300212e20052903d802212f20054188026a41186a220e2006290300370300202c2008290300370300202a2009290300370300200520052903e80137038802200b280258220d41ffffff3f71200d470d03200d4105742206417f4c0d03200b28025021090240024020060d004101210b0c010b20061021220b450d050b02400240200d0d00410021010c010b200b2108034020082009290000370000200841186a200941186a290000370000200841106a200941106a290000370000200841086a200941086a290000370000200841206a2108200941206a2109200641606a22060d000b200d41057441606a41057641016a21010b200541a8026a41186a2203200e290300370300200541a8026a41106a220e202c290300370300200541a8026a41086a2214202a29030037030020052005290388023703a802201b201c1003220941086a2900003703002005200929000037038803200910232004201b29030037030020052005290388033703c802201b419cb2c500ad42808080808002841003220941086a290000370300200520092900003703880320091023201d201b29030037030020052005290388033703d8022005201936028803202020231001220941186a290000370300201f200941106a2900003703002013200941086a29000037030020052009290000370398032009102320182020290300370300201a201f2903003703002016201329030037030020052005290398033703c80341c00010212206450d05200620052903c802370000200620052903d802370010200620052903c80337002041082104200641086a200541c8026a41086a290300370000200641186a200541d8026a41086a290300370000200641286a200541c8036a41086a290300370000200641306a201a290300370000200641386a201829030037000020054198036a200641c00010a80302400240200528029803222a0d00410021084200210c410021090c010b200529029c03220c422088a72108200ca72109202a21040b20202003290300370300201f200e29030037030020132014290300370300200520052903a80237039803024020082009470d0002402008200ca7470d00200841016a22092008490d092008410174220e2009200e20094b1bad223142d8007e2232422088a70d092032a722094100480d090240024020080d002009102121040c010b2004200841d8006c2009102521040b2004450d08200c42808080807083203184210c0b200c422088a721080b2004200841d8006c220e6a2209201520107c22103703102009202e3703082009202f3703002009200b36022c20092012360220200941186a2027200f7c2010201554ad7c370300200941346a2001360200200941306a200d360200200941246a200a3702002009200529039803370338200941c0006a2013290300370300200941c8006a201f290300370300200941d0006a20202903003703000240024020040d002006ad428080808080088410050c010b20054198036a2004200841016a220910be042006ad428080808080088420053502a0034220862005280298032208ad8410020240200528029c03450d00200810230b200ca7210b02402009450d00200441306a2109200e41d8006a210803400240200941746a280200450d00200941706a28020010230b02402009280200450d002009417c6a28020010230b200941d8006a2109200841a87f6a22080d000b0b200b450d00200410230b200610230b201141e0006a211120262021490d010c090b0b200641081030000b102f000b200641011030000b41c00041011030000b200941081030000b102a000b200841081030000b200aa7450d00200b10230b200541f0036a24000b13002000410136020420004188e5c0003602000ba40703067f017e057f230041a0016b2201240020014180016a41186a2202420037030020014180016a41106a2203420037030020014180016a41086a220442003703002001420037038001200141f0006a41086a220541f7fbc400ad4280808080f000841003220641086a290000370300200120062900003703702006102320042005290300370300200120012903703703800120054194b7c200ad4280808080c001841003220641086a2900003703002001200629000037037020061023200320012903702207370300200141d0006a41086a22062004290300370300200141d0006a41106a22082007370300200141d0006a41186a22092005290300370300200120073703102001200129038001370350200141086a200141d0006a4120108f01200128020c210a2001280208210b200141106a41186a200041186a290000370300200141106a41106a200041106a290000370300200141106a41086a200041086a2900003703002001200029000037031020054194fcc400ad42808080808001841003220041086a2900003703002001200029000037037020001023200141306a41086a220c200529030037030020012001290370370330200541a9e4c000ad4280808080e001841003220041086a2900003703002001200029000037037020001023200141c0006a41086a22002005290300370300200120012903703703402001200a4100200b1b3602702002200141f0006aad4280808080c000841001220541186a2900003703002003200541106a2900003703002004200541086a29000037030020012005290000370380012005102320092002290300370300200820032903003703002006200429030037030020012001290380013703500240024041c00010212205450d00200520012903303700002005200129034037001020052001290350370020200541086a200c290300370000200541186a2000290300370000200541286a2006290300370000200541306a2008290300370000200541386a200929030037000020014180016a200141106a10ac01200541c00041800110252205450d012005200129008001370040200541d8006a20014198016a290000370000200541d0006a20014190016a290000370000200541c8006a20014188016a2900003700002001200541e000108f012001200128020441016a410120012802001b360280012005ad4280808080800c8420014180016aad4280808080c00084100220051023200141a0016a24000f0b41c00041011030000b41800141011030000b340020004194fcc40036020420004100360200200041146a4104360200200041106a41c4e6c000360200200041086a42083702000bda0401057f230041106b22032400200341003602082003420137030020022003105c024002400240024002402002450d00200241b8016c210403402003280204210520032802082102024002402001280200411a470d000240024020052002460d00200328020021050c010b200241016a22052002490d08200241017422062005200620054b1b22064100480d080240024020020d002006102121050c010b200328020020022006102521050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b0240024020052002460d00200328020021050c010b200241016a22052002490d07200241017422062005200620054b1b22064100480d070240024020020d002006102121050c010b200328020020022006102521050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a00002001200310cb01200141b0016a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d07200541017422022007200220074b1b22024100480d070240024020050d002002102121050c010b200328020020052002102521050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000b200141b8016a2101200441c87e6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b200641011030000b200641011030000b200241011030000b102a000bb7fb0104057f017e067f017e230041e0006b220224000240024002402000280200220341194b0d000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e1a000102030405060708090a0b0c0d0e0f10111213141516171819000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dc401200341017422052004200520044b1b22054100480dc4010240024020030d002005102121040c010b200128020020032005102521040b2004450d1a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208417f6a220341064b0dc101024002400240024002400240024020030e0700010203040506000b200241003a003c02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490dca01200041017422042003200420034b1b22044100480dca010240024020000d002004102121030c010b200128020020002004102521030b2003450d2120012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41003a00000cc7010b200241013a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dc901200341017422052004200520044b1b22054100480dc9010240024020030d002005102121040c010b200128020020032005102521040b2004450d2120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200028020c2106200041146a28020022002001105c02400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490dc901200441017422032005200320054b1b22034100480dc9010240024020040d002003102121040c010b200128020020042003102521040b2004450d2220012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010dc041a0cc6010b200241023a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dc801200341017422052004200520044b1b22054100480dc8010240024020030d002005102121040c010b200128020020032005102521040b2004450d2220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000290310210702400240200141046a2802002203200528020022006b4108490d00200128020021030c010b200041086a22042000490dc801200341017422002004200020044b1b22004100480dc8010240024020030d002000102121030c010b200128020020032000102521030b2003450d2320012003360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200320006a20073700000cc5010b200241033a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dc701200341017422052004200520044b1b22054100480dc7010240024020030d002005102121040c010b200128020020032005102521040b2004450d2320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200028020c2106200041146a28020022002001105c02400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490dc701200441017422032005200320054b1b22034100480dc7010240024020040d002003102121040c010b200128020020042003102521040b2004450d2420012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010dc041a0cc4010b200141086a2802002103200241043a003c024002402003200141046a280200460d00200128020021050c010b200341016a22042003490dc601200341017422052004200520044b1b22044100480dc6010240024020030d002004102121050c010b200128020020032004102521050b2005450d2420012005360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200520036a41043a0000200028020c2103200041146a28020022002001105c2000450dc3012003200041186c6a2108200141046a2106034020032802002109200341086a28020022002001105c024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490dc701200a4101742205200b2005200b4b1b22054100480dc70102400240200a0d0020051021210a0c010b2001280200200a20051025210a0b200a450d262001200a36020020062005360200200428020021050b2004200520006a360200200a20056a2009200010dc041a2003410c6a2802002109200341146a28020022002001105c024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490dc701200a4101742205200b2005200b4b1b22054100480dc70102400240200a0d0020051021210a0c010b2001280200200a20051025210a0b200a450d272001200a36020020062005360200200428020021050b2004200520006a360200200a20056a2009200010dc041a200341186a22032008470d000cc4010b0b200241053a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dc501200341017422052004200520044b1b22054100480dc5010240024020030d002005102121040c010b200128020020032005102521040b2004450d2620012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41053a0000200028020c2104200041146a28020022002001105c2000450dc20120042000410c6c6a2108200141046a210903402004280200210a200441086a28020022002001105c0240024020092802002205200628020022036b2000490d00200128020021050c010b200320006a220b2003490dc60120054101742203200b2003200b4b1b22034100480dc6010240024020050d002003102121050c010b200128020020052003102521050b2005450d282001200536020020092003360200200628020021030b2006200320006a360200200520036a200a200010dc041a2004410c6a22042008470d000cc3010b0b200241063a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dc401200341017422052004200520044b1b22054100480dc4010240024020030d002005102121040c010b200128020020032005102521040b2004450d2720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41063a0000200028020c2106200041146a28020022002001105c02400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490dc401200441017422032005200320054b1b22034100480dc4010240024020040d002003102121040c010b200128020020042003102521040b2004450d2820012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010dc041a0cc1010b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490dc301200041017422042003200420034b1b22044100480dc3010240024020000d002004102121030c010b200128020020002004102521030b2003450d2820012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a0000200110ba030cc0010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dc201200341017422052004200520044b1b22054100480dc2010240024020030d002005102121040c010b200128020020032005102521040b2004450d2820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490dc201200341017422052004200520044b1b22054100480dc2010240024020030d002005102121040c010b200128020020032005102521040b2004450d2920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000024020002903082207423f560d0020022007a741027422043a003c02400240200141046a28020020052802002200460d00200128020021030c010b200041016a22032000490dc301200041017422052003200520034b1b22054100480dc3010240024020000d002005102121030c010b200128020020002005102521030b2003450d2b20012003360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200320006a20043a00000cc0010b200742808001540dbe012007428080808004540dbd014108200779a741037622046b4104490dbc012002411320044102746b220a3a003c02400240200141046a280200200141086a2802002203460d00200128020021060c010b200341016a22052003490dc201200341017422062005200620054b1b22054100480dc2010240024020030d002005102121060c010b200128020020032005102521060b2006450d2b20012006360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200620036a200a3a0000200220002903082207370300200441786a2103200141046a210a034020022007a722063a003c02400240200a28020020052802002200460d00200128020021040c010b200041016a22042000490dc301200041017422092004200920044b1b22094100480dc3010240024020000d002009102121040c010b200128020020002009102521040b2004450d2d20012004360200200a2009360200200528020021000b2005200041016a360200200420006a20063a000020074208882107200341016a22002003492104200021032004450d000b200220073703002007500dbf01200241206a41146a410d3602002002412c6a4111360200200241086a41146a41033602002002200236023c200241d8a7c30036025c2002420337020c200241acb6c600360208200241113602242002420437035020024201370244200241e0a7c3003602402002200241206a3602182002200241c0006a3602302002200241dc006a36022820022002413c6a360220200241086a41e8a7c3001038000b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490dc101200041017422042003200420034b1b22044100480dc1010240024020000d002004102121030c010b200128020020002004102521030b2003450d2c20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41033a0000200110ba030cbe010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dc001200341017422052004200520044b1b22054100480dc0010240024020030d002005102121040c010b200128020020032005102521040b2004450d2c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a00002000280208417f6a220341034b0dbd010240024002400240024020030e0400010203000b200241003a003c02400240200141046a280200200141086a2802002204460d00200128020021050c010b200441016a22032004490dc401200441017422052003200520034b1b22034100480dc4010240024020040d002003102121050c010b200128020020042003102521050b2005450d3120012005360200200141046a2003360200200141086a28020021040b200041306a2103200141086a200441016a360200200520046a41003a00002000410c6a200110d902200241dc006a21000c030b200241013a003c02400240200141046a280200200141086a2802002204460d00200128020021050c010b200441016a22032004490dc301200441017422052003200520034b1b22034100480dc3010240024020040d002003102121050c010b200128020020042003102521050b2005450d3120012005360200200141046a2003360200200141086a28020021040b200041c0006a2103200141086a200441016a360200200520046a41013a00002000410c6a200110d9022002200041306a3602002002200110c301200241086a21000c020b200241023a003c02400240200141046a280200200141086a2802002204460d00200128020021050c010b200441016a22032004490dc201200441017422052003200520034b1b22034100480dc2010240024020040d002003102121050c010b200128020020042003102521050b2005450d3120012005360200200141046a2003360200200141086a28020021040b200041d8006a2103200141086a200441016a360200200520046a41023a00002000410c6a200110d902200041306a200110d902200241206a21000c010b200241033a003c02400240200141046a280200200141086a2802002204460d00200128020021050c010b200441016a22032004490dc101200441017422052003200520034b1b22034100480dc1010240024020040d002003102121050c010b200128020020042003102521050b2005450d3120012005360200200141046a2003360200200141086a28020021040b200041306a2103200141086a200441016a360200200520046a41033a00002000410c6a200110d902200241c0006a21000b200020033602002000200110c3010cbd010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dbf01200341017422052004200520044b1b22054100480dbf010240024020030d002005102121040c010b200128020020032005102521040b2004450d3020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490dbf01200341017422052004200520044b1b22054100480dbf010240024020030d002005102121040c010b200128020020032005102521040b2004450d3120012004360200200141046a2005360200200141086a28020021030b200141086a220a200341016a360200200420036a41003a00002000280204210c2000410c6a28020022002001105c2000450dbc01200c200041f0006c6a210d200141046a210b034020022001360240200c41106a200241c0006a106b200c200110af0120022001360240200c41306a200241c0006a106b20022001360240200c41d0006a200241c0006a106b200c2802042104200c28020c22002001105c02402000450d00200041246c21090340200241c0006a200410b0012002280240210602400240200b2802002205200a28020022006b20022802482203490d00200128020021050c010b200020036a22082000490dc201200541017422002008200020084b1b22004100480dc2010240024020050d002000102121050c010b200128020020052000102521050b2005450d3520012005360200200b2000360200200a28020021000b200a200020036a360200200520006a2006200310dc041a02402002280244450d00200610230b200441246a21042009415c6a22090d000b0b200c41f0006a220c200d470d000cbd010b0b02400240200141046a2206280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490dbe012004410174220a2005200a20054b1b220a4100480dbe010240024020040d00200a102121050c010b20012802002004200a102521050b2005450d3220012005360200200141046a200a360200200141086a28020021040b2003200441016a360200200520046a41063a0000200041086a22052d0000417f6a2204410f4b0dbb01024002400240024002400240024002400240024002400240024002400240024020040e10000102030405060708090a0b0c0d0e0f000b200241003a003c02400240200628020020032802002204460d002001280200210a0c010b200441016a220a2004490dcd0120044101742209200a2009200a4b1b22094100480dcd010240024020040d0020091021210a0c010b2001280200200420091025210a0b200a450d422001200a360200200141046a2009360200200141086a28020021040b200141086a200441016a360200200a20046a41003a00002000410c6a200110d9022002200041306a360240200241c0006a200110c30120052d0001220041024b0dca0102400240024020000e03000102000b200241003a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dcf01200041017422052004200520044b1b22054100480dcf010240024020000d002005102121040c010b200128020020002005102521040b2004450d4520012004360200200141046a2005360200200141086a28020021000b2003200041016a360200200420006a41003a00000ccc010b200241013a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dce01200041017422052004200520044b1b22054100480dce010240024020000d002005102121040c010b200128020020002005102521040b2004450d4520012004360200200141046a2005360200200141086a28020021000b2003200041016a360200200420006a41013a00000ccb010b200241023a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dcd01200041017422052004200520044b1b22054100480dcd010240024020000d002005102121040c010b200128020020002005102521040b2004450d4520012004360200200141046a2005360200200141086a28020021000b2003200041016a360200200420006a41023a00000cca010b200241013a003c02400240200628020020032802002203460d00200128020021040c010b200341016a22042003490dcc01200341017422052004200520044b1b22054100480dcc010240024020030d002005102121040c010b200128020020032005102521040b2004450d4520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002002200041106a360240200241c0006a200110c3010cc9010b200241023a003c02400240200628020020032802002203460d00200128020021040c010b200341016a22042003490dcb01200341017422052004200520044b1b22054100480dcb010240024020030d002005102121040c010b200128020020032005102521040b2004450d4520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200041106a360240200241c0006a200110c3010cc8010b200241033a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dca01200041017422052004200520044b1b22054100480dca010240024020000d002005102121040c010b200128020020002005102521040b2004450d4520012004360200200141046a2005360200200141086a28020021000b2003200041016a360200200420006a41033a00000cc7010b200241043a003c02400240200628020020032802002203460d00200128020021040c010b200341016a22042003490dc901200341017422052004200520044b1b22054100480dc9010240024020030d002005102121040c010b200128020020032005102521040b2004450d4520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a00002000410c6a200110af010cc6010b200241053a003c02400240200628020020032802002203460d00200128020021040c010b200341016a22042003490dc801200341017422052004200520044b1b22054100480dc8010240024020030d002005102121040c010b200128020020032005102521040b2004450d4520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c2103200041146a28020022002001105c2000450dc501200041246c210003402003200110d902200341246a21032000415c6a22000d000cc6010b0b200241063a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dc701200041017422052004200520044b1b22054100480dc7010240024020000d002005102121040c010b200128020020002005102521040b2004450d4520012004360200200141046a2005360200200141086a28020021000b2003200041016a360200200420006a41063a00000cc4010b200241073a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dc6012000410174220a2004200a20044b1b220a4100480dc6010240024020000d00200a102121040c010b20012802002000200a102521040b2004450d4520012004360200200141046a200a360200200141086a28020021000b2003200041016a360200200420006a41073a000020052d0001220041024b0dc30102400240024020000e03000102000b200241003a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dc801200041017422052004200520044b1b22054100480dc8010240024020000d002005102121040c010b200128020020002005102521040b2004450d4820012004360200200141046a2005360200200141086a28020021000b2003200041016a360200200420006a41003a00000cc5010b200241013a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dc701200041017422052004200520044b1b22054100480dc7010240024020000d002005102121040c010b200128020020002005102521040b2004450d4820012004360200200141046a2005360200200141086a28020021000b2003200041016a360200200420006a41013a00000cc4010b200241023a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dc601200041017422052004200520044b1b22054100480dc6010240024020000d002005102121040c010b200128020020002005102521040b2004450d4820012004360200200141046a2005360200200141086a28020021000b2003200041016a360200200420006a41023a00000cc3010b200241083a003c02400240200628020020032802002203460d00200128020021040c010b200341016a22042003490dc501200341017422052004200520044b1b22054100480dc5010240024020030d002005102121040c010b200128020020032005102521040b2004450d4820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a200110d9020cc2010b200241093a003c02400240200628020020032802002203460d00200128020021040c010b200341016a22042003490dc401200341017422052004200520044b1b22054100480dc4010240024020030d002005102121040c010b200128020020032005102521040b2004450d4820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a200110af010cc1010b2002410a3a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dc301200041017422052004200520044b1b22054100480dc3010240024020000d002005102121040c010b200128020020002005102521040b2004450d4820012004360200200141046a2005360200200141086a28020021000b2003200041016a360200200420006a410a3a00000cc0010b2002410b3a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dc201200041017422052004200520044b1b22054100480dc2010240024020000d002005102121040c010b200128020020002005102521040b2004450d4820012004360200200141046a2005360200200141086a28020021000b2003200041016a360200200420006a410b3a00000cbf010b2002410c3a003c02400240200628020020032802002203460d00200128020021040c010b200341016a22042003490dc101200341017422052004200520044b1b22054100480dc1010240024020030d002005102121040c010b200128020020032005102521040b2004450d4820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a0000200028020c2103200041146a28020022002001105c2000450dbe01200041057421000340200320011071200341206a2103200041606a22000d000cbf010b0b2002410d3a003c02400240200628020020032802002200460d00200128020021030c010b200041016a22032000490dc001200041017422042003200420034b1b22044100480dc0010240024020000d002004102121030c010b200128020020002004102521030b2003450d4820012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a410d3a0000200541016a200110710cbd010b2002410e3a003c02400240200628020020032802002200460d00200128020021040c010b200041016a22042000490dbf01200041017422052004200520044b1b22054100480dbf010240024020000d002005102121040c010b200128020020002005102521040b2004450d4820012004360200200141046a2005360200200141086a28020021000b2003200041016a360200200420006a410e3a00000cbc010b2002410f3a003c02400240200628020020032802002204460d00200128020021050c010b200441016a22052004490dbe012004410174220a2005200a20054b1b220a4100480dbe010240024020040d00200a102121050c010b20012802002004200a102521050b2005450d4820012005360200200141046a200a360200200141086a28020021040b2003200441016a360200200520046a410f3a0000200028020c210a0240024020062802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490dbe01200541017422042009200420094b1b22044100480dbe010240024020050d002004102121050c010b200128020020052004102521050b2005450d4920012005360200200141046a2004360200200141086a28020021040b200141086a2208200441046a360200200520046a200a36000020002802102104200041186a28020022002001105c2000450dbb012000410274210a0340200428020021090240024020062802002205200328020022006b4104490d00200128020021050c010b200041046a220b2000490dbf0120054101742200200b2000200b4b1b22004100480dbf010240024020050d002000102121050c010b200128020020052000102521050b2005450d4b20012005360200200141046a2000360200200828020021000b200441046a21042003200041046a360200200520006a2009360000200a417c6a220a0d000cbc010b0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490dbd01200041017422042003200420034b1b22044100480dbd010240024020000d002004102121030c010b200128020020002004102521030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41073a0000200110ba030cba010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dbc01200341017422052004200520044b1b22054100480dbc010240024020030d002005102121040c010b200128020020032005102521040b2004450d4a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41083a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490dbc01200341017422052004200520044b1b22054100480dbc010240024020030d002005102121040c010b200128020020032005102521040b2004450d4b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041106a20011071200041306a20011071200041d0006a20011071200041f0006a2001107120004190016a20011071200028020421062000410c6a28020022002001105c02400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490dbc01200441017422032005200320054b1b22034100480dbc010240024020040d002003102121040c010b200128020020042003102521040b2004450d4c20012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010dc041a0cb9010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dbb01200341017422052004200520044b1b22054100480dbb010240024020030d002005102121040c010b200128020020032005102521040b2004450d4c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41093a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490dbb01200341017422052004200520044b1b22054100480dbb010240024020030d002005102121040c010b200128020020032005102521040b2004450d4d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041046a200110af010cb8010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dba01200341017422052004200520044b1b22054100480dba010240024020030d002005102121040c010b200128020020032005102521040b2004450d4d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410a3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490dba01200341017422052004200520044b1b22054100480dba010240024020030d002005102121040c010b200128020020032005102521040b2004450d4e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200028020421062000410c6a28020022002001105c02400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490dba01200441017422032005200320054b1b22034100480dba010240024020040d002003102121040c010b200128020020042003102521040b2004450d4f20012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010dc041a0cb7010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490db901200341017422052004200520044b1b22054100480db9010240024020030d002005102121040c010b200128020020032005102521040b2004450d4f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410b3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490db901200341017422052004200520044b1b22054100480db9010240024020030d002005102121040c010b200128020020032005102521040b2004450d5020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280204210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490db901200441017422032005200320054b1b22034100480db9010240024020040d002003102121040c010b200128020020042003102521040b2004450d5120012004360200200141046a2003360200200141086a28020021030b200141086a220a200341046a360200200420036a2006360000200041086a2802002106200041106a28020022032001105c02400240200141046a2802002205200a28020022046b2003490d00200128020021050c010b200420036a220a2004490db90120054101742204200a2004200a4b1b22044100480db9010240024020050d002004102121050c010b200128020020052004102521050b2005450d5220012005360200200141046a2004360200200141086a28020021040b200141086a220a200420036a360200200520046a2006200310dc041a200041146a28020021052000411c6a28020022032001105c02402003450d0020052003410c6c6a210c200141046a210b034020052802002109200541086a28020022032001105c02400240200b2802002206200a28020022046b2003490d00200128020021060c010b200420036a22082004490dbb01200641017422042008200420084b1b22044100480dbb010240024020060d002004102121060c010b200128020020062004102521060b2006450d5520012006360200200b2004360200200a28020021040b200a200420036a360200200620046a2009200310dc041a2005410c6a2205200c470d000b0b200041206a280200210502400240200141046a2802002204200a28020022036b4104490d00200128020021040c010b200341046a22062003490db901200441017422032006200320064b1b22034100480db9010240024020040d002003102121040c010b200128020020042003102521040b2004450d5420012004360200200141046a2003360200200141086a28020021030b200141086a2206200341046a360200200420036a2005360000200041246a280200210a02400240200141046a2802002204200628020022036b4104490d00200128020021040c010b200341046a22052003490db901200441017422032005200320054b1b22034100480db9010240024020040d002003102121040c010b200128020020042003102521040b2004450d5520012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a200a360000200041286a210b4100210303402002200b20036a2d000022063a003c02400240200141046a220a28020020052802002200460d00200128020021040c010b200041016a22042000490dba01200041017422092004200920044b1b22094100480dba010240024020000d002009102121040c010b200128020020002009102521040b2004450d5720012004360200200a2009360200200528020021000b2005200041016a360200200420006a20063a0000200341016a220341c000470d000cb7010b0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490da001200041017422042003200420034b1b22044100480da0010240024020000d002004102121030c010b200128020020002004102521030b2003450d5620012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a410c3a0000200110ba030cb5010b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d9f012003410174220a2005200a20054b1b220a4100480d9f010240024020030d00200a102121050c010b20012802002003200a102521050b2005450d5620012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a410d3a0000200041086a22052d0000417f6a220341104b0db4010240024002400240024002400240024002400240024002400240024002400240024020030e11000102030405060708090a0b0c0d0e0f10000b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490daf01200341017422052004200520044b1b22054100480daf010240024020030d002005102121040c010b200128020020032005102521040b2004450d6720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200028020c200110cb012002200041106a360240200241c0006a200110c3010cc4010b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490dae01200341017422052004200520044b1b22054100480dae010240024020030d002005102121040c010b200128020020032005102521040b2004450d6720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110af010cc3010b02400240200628020020042802002203460d00200128020021060c010b200341016a22062003490dad012003410174220a2006200a20064b1b220a4100480dad010240024020030d00200a102121060c010b20012802002003200a102521060b2006450d6720012006360200200141046a200a360200200141086a28020021030b200141086a220a200341016a360200200620036a41023a00002000410c6a200110af0120052d00012106200541026a2d0000210502400240200141046a280200200a2802002200460d00200128020021030c010b200041016a22032000490dad012000410174220a2003200a20034b1b220a4100480dad010240024020000d00200a102121030c010b20012802002000200a102521030b2003450d6820012003360200200141046a200a360200200141086a28020021000b2004200041016a360200200320006a20064100474107742005723a00000cc2010b02400240200628020020042802002203460d00200128020021060c010b200341016a22062003490dac012003410174220a2006200a20064b1b220a4100480dac010240024020030d00200a102121060c010b20012802002003200a102521060b2006450d6820012006360200200141046a200a360200200141086a28020021030b200141086a220a200341016a360200200620036a41033a00002000410c6a200110af0120052d00012106200541026a2d0000210502400240200141046a280200200a2802002200460d00200128020021030c010b200041016a22032000490dac012000410174220a2003200a20034b1b220a4100480dac010240024020000d00200a102121030c010b20012802002000200a102521030b2003450d6920012003360200200141046a200a360200200141086a28020021000b2004200041016a360200200320006a20064100474107742005723a00000cc1010b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490dab012003410174220a2005200a20054b1b220a4100480dab010240024020030d00200a102121050c010b20012802002003200a102521050b2005450d6920012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41043a0000200028020c21050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490dab01200341017422002006200020064b1b22004100480dab010240024020030d002000102121030c010b200128020020032000102521030b2003450d6a20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000cc0010b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490daa01200341017422052004200520044b1b22054100480daa010240024020030d002005102121040c010b200128020020032005102521040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c200110cb010cbf010b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490da901200341017422052004200520044b1b22054100480da9010240024020030d002005102121040c010b200128020020032005102521040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200028020c200110cb010cbe010b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490da801200341017422052004200520044b1b22054100480da8010240024020030d002005102121040c010b200128020020032005102521040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a0000200028020c200110cb010cbd010b02400240200628020020042802002203460d002001280200210a0c010b200341016a220a2003490da70120034101742209200a2009200a4b1b22094100480da7010240024020030d0020091021210a0c010b2001280200200320091025210a0b200a450d6a2001200a360200200141046a2009360200200141086a28020021030b200141086a2209200341016a360200200a20036a41083a000020022001360240200541016a200241c0006a106b200028022c210a02400240200141046a2802002205200928020022036b4104490d00200128020021050c010b200341046a22092003490da701200541017422032009200320094b1b22034100480da7010240024020050d002003102121050c010b200128020020052003102521050b2005450d6b20012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200a360000200028023021050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490da701200341017422002006200020064b1b22004100480da7010240024020030d002000102121030c010b200128020020032000102521030b2003450d6c20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000cbc010b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490da601200041017422042003200420034b1b22044100480da6010240024020000d002004102121030c010b200128020020002004102521030b2003450d6c20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41093a000020022001360240200541016a200241c0006a106b0cbb010b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490da501200341017422052004200520044b1b22054100480da5010240024020030d002005102121040c010b200128020020032005102521040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a00002000410c6a200110af010cba010b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490da401200341017422052004200520044b1b22054100480da4010240024020030d002005102121040c010b200128020020032005102521040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000410c6a200110af01200041106a200110af01200041146a200110af010cb9010b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490da301200041017422042003200420034b1b22044100480da3010240024020000d002004102121030c010b200128020020002004102521030b2003450d6c20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a410c3a0000200541016a200110710cb8010b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490da201200041017422052003200520034b1b22054100480da2010240024020000d002005102121030c010b200128020020002005102521030b2003450d6c20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a410d3a00000cb7010b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490da101200041017422042003200420034b1b22044100480da1010240024020000d002004102121030c010b200128020020002004102521030b2003450d6c20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a410e3a0000200541016a200110710cb6010b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490da0012000410174220a2003200a20034b1b220a4100480da0010240024020000d00200a102121030c010b20012802002000200a102521030b2003450d6c20012003360200200141046a200a360200200141086a28020021000b200141086a200041016a360200200320006a410f3a0000200541016a2001107120052d0021220041064b0db5010240024002400240024002400240024020000e0700010203040506000b410021050c060b410121050c050b410221050c040b410321050c030b410421050c020b410521050c010b410621050b200220053a003c02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490da001200041017422062003200620034b1b22064100480da0010240024020000d002006102121030c010b200128020020002006102521030b2003450d6d20012003360200200141046a2006360200200141086a28020021000b2004200041016a360200200320006a20053a00000cb5010b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d9f01200041017422052003200520034b1b22054100480d9f010240024020000d002005102121030c010b200128020020002005102521030b2003450d6d20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41103a00000cb4010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e01200341017422052004200520044b1b22054100480d9e010240024020030d002005102121040c010b200128020020032005102521040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410e3a0000200041046a200110d3030cb3010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d01200341017422052004200520044b1b22054100480d9d010240024020030d002005102121040c010b200128020020032005102521040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410f3a0000200041046a200110d3030cb2010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c01200341017422052004200520044b1b22054100480d9c010240024020030d002005102121040c010b200128020020032005102521040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41103a00002000280208417f6a220341054b0db10102400240024002400240024020030e06000102030405000b200241003a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da101200341017422052004200520044b1b22054100480da1010240024020030d002005102121040c010b200128020020032005102521040b2004450d7320012004360200200141046a2005360200200141086a28020021030b200041186a2105200141086a200341016a360200200420036a41003a0000200028020c2103200041146a28020022002001105c02402000450d00200041057421000340200320011071200341206a2103200041606a22000d000b0b20022005360240200241c0006a200110c3010cb6010b200241013a003c02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490da001200041017422042003200420034b1b22044100480da0010240024020000d002004102121030c010b200128020020002004102521030b2003450d7320012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000cb5010b200241023a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f01200341017422052004200520044b1b22054100480d9f010240024020030d002005102121040c010b200128020020032005102521040b2004450d7320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a200110d9020cb4010b200241033a003c02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d9e01200041017422042003200420034b1b22044100480d9e010240024020000d002004102121030c010b200128020020002004102521030b2003450d7320012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41033a00000cb3010b200141086a2802002100200241043a003c024002402000200141046a280200460d00200128020021030c010b200041016a22032000490d9d01200041017422042003200420034b1b22044100480d9d010240024020000d002004102121030c010b200128020020002004102521030b2003450d7320012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41043a00000cb2010b200241053a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c01200341017422052004200520044b1b22054100480d9c010240024020030d002005102121040c010b200128020020032005102521040b2004450d7320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000410c6a200110d9020cb1010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b01200341017422052004200520044b1b22054100480d9b010240024020030d002005102121040c010b200128020020032005102521040b2004450d7320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41113a0000200041046a22032d0000417f6a220441034b0db001024002400240024020040e0400010203000b200241003a003c02400240200141046a280200200141086a2802002200460d00200128020021040c010b200041016a22042000490d9e01200041017422052004200520044b1b22054100480d9e010240024020000d002005102121040c010b200128020020002005102521040b2004450d7720012004360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200420006a41003a0000200341016a200110710cb3010b200141086a2802002100200141046a2802002104200241013a003c0240024020042000460d00200128020021040c010b200041016a22042000490d9d01200041017422052004200520044b1b22054100480d9d010240024020000d002005102121040c010b200128020020002005102521040b2004450d7720012004360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200420006a41013a0000200341016a200110710cb2010b200241023a003c02400240200141046a280200200141086a2802002200460d00200128020021040c010b200041016a22042000490d9c01200041017422052004200520044b1b22054100480d9c010240024020000d002005102121040c010b200128020020002005102521040b2004450d7720012004360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200420006a41023a0000200341016a20011071200341216a200110710cb1010b200241033a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b01200341017422052004200520044b1b22054100480d9b010240024020030d002005102121040c010b200128020020032005102521040b2004450d7720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002802082103200041106a28020022002001105c2000450db001200041057421000340200320011071200341206a2103200041606a22000d000cb1010b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9a01200341017422052004200520044b1b22054100480d9a010240024020030d002005102121040c010b200128020020032005102521040b2004450d7720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41123a00002000280208417f6a220341024b0daf0102400240024020030e03000102000b200241003a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c01200341017422052004200520044b1b22054100480d9c010240024020030d002005102121040c010b200128020020032005102521040b2004450d7a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002002200041306a360240200241c0006a200110c3012000410c6a200110d9020cb1010b200241013a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b01200341017422052004200520044b1b22054100480d9b010240024020030d002005102121040c010b200128020020032005102521040b2004450d7a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110af010cb0010b200241023a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9a01200341017422052004200520044b1b22054100480d9a010240024020030d002005102121040c010b200128020020032005102521040b2004450d7a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a200110af010caf010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9901200341017422052004200520044b1b22054100480d99010240024020030d002005102121040c010b200128020020032005102521040b2004450d7a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41133a0000200041086a22042d0000417f6a220341014b0dae010240024020030e020001000b200241003a003c02400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22052003490d9a01200341017422062005200620054b1b22064100480d9a010240024020030d002006102121050c010b200128020020032006102521050b2005450d7c20012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41003a0000200441016a2001107141292104200141046a210903402002200020046a2d0000220a3a003c02400240200928020020062802002203460d00200128020021050c010b200341016a22052003490d9b012003410174220b2005200b20054b1b220b4100480d9b010240024020030d00200b102121050c010b20012802002003200b102521050b2005450d7e200120053602002009200b360200200628020021030b2006200341016a360200200520036a200a3a0000200441016a220441ea00470d000cb0010b0b200141086a2802002103200141046a2802002105200241013a003c0240024020052003460d00200128020021050c010b200341016a22052003490d9901200341017422062005200620054b1b22064100480d99010240024020030d002006102121050c010b200128020020032006102521050b2005450d7d20012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41013a0000200441016a200110c003200041286a29030021072000290320210e02400240200141046a2802002203200628020022006b4110490d00200128020021030c010b200041106a22042000490d9901200341017422002004200020044b1b22004100480d99010240024020030d002000102121030c010b200128020020032000102521030b2003450d7e20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a220020073700082000200e3700000cae010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9801200341017422052004200520044b1b22054100480d98010240024020030d002005102121040c010b200128020020032005102521040b2004450d7e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41143a000002400240200141046a28020020052802002204460d00200128020021050c010b200441016a22032004490d9801200441017422052003200520034b1b22034100480d98010240024020040d002003102121050c010b200128020020042003102521050b2005450d7f20012005360200200141046a2003360200200141086a28020021040b200141086a2203200441016a360200200520046a41003a00002000280204210c2000410c6a28020022002001105c2000450dad01200c200041d0016c6a210d200141046a21040340200c200110b101200c2802b801210a200c2802c00122002001105c02402000450d00200a200041c1006c6a2108034002400240200a2d00004101460d00200241013a003c02400240200428020020032802002200460d00200128020021060c010b200041016a22052000490d9d01200041017422062005200620054b1b22054100480d9d010240024020000d002005102121060c010b200128020020002005102521060b2006450d85012001200636020020042005360200200328020021000b410121052003200041016a360200200620006a41013a000003402002200a20056a2d000022093a003c02400240200428020020032802002200460d00200128020021060c010b200041016a22062000490d9e012000410174220b2006200b20064b1b220b4100480d9e010240024020000d00200b102121060c010b20012802002000200b102521060b2006450d8701200120063602002004200b360200200328020021000b2003200041016a360200200620006a20093a0000200541016a220541c100470d000c020b0b200241023a003c02400240200428020020032802002200460d00200128020021060c010b200041016a22052000490d9c01200041017422062005200620054b1b22054100480d9c010240024020000d002005102121060c010b200128020020002005102521060b2006450d86012001200636020020042005360200200328020021000b410121052003200041016a360200200620006a41023a000003402002200a20056a2d000022093a003c02400240200428020020032802002200460d00200128020021060c010b200041016a22062000490d9d012000410174220b2006200b20064b1b220b4100480d9d010240024020000d00200b102121060c010b20012802002000200b102521060b2006450d8801200120063602002004200b360200200328020021000b2003200041016a360200200620006a20093a0000200541016a220541c100470d000b0b200a41c1006a220a2008470d000b0b200c2802c4012109200c2802c801220641037622052001105c0240024020050d0020032802002105410021002001280200210a0c010b4101210002402005410820064107716b220a4d0d002005200a6b22004103762000410771456b41026a21000b02402004280200220a200328020022056b2000490d002001280200210a0c010b200520006a220b2005490d9901200a4101742205200b2005200b4b1b22054100480d990102400240200a0d0020051021210a0c010b2001280200200a20051025210a0b200a450d85012001200a36020020042005360200200328020021050b2003200520006a360200200a20056a2009410120061b200010dc041a200c41d0016a220c200d470d000cae010b0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d9701200041017422042003200420034b1b22044100480d97010240024020000d002004102121030c010b200128020020002004102521030b2003450d840120012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41153a000002400240200141046a28020020042802002200460d00200128020021030c010b200041016a22032000490d9701200041017422042003200420034b1b22044100480d97010240024020000d002004102121030c010b200128020020002004102521030b2003450d850120012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41003a00000cac010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9601200341017422052004200520044b1b22054100480d96010240024020030d002005102121040c010b200128020020032005102521040b2004450d850120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41163a0000200041086a22042d0000417f6a220341054b0dab0102400240024002400240024020030e06000102030405000b200241003a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b01200341017422052004200520044b1b22054100480d9b010240024020030d002005102121040c010b200128020020032005102521040b2004450d8b0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000410c6a200110af01200041106a200110af010cb0010b200241013a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9a01200341017422052004200520044b1b22054100480d9a010240024020030d002005102121040c010b200128020020032005102521040b2004450d8b0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110af01200041106a200110af01200041146a200110af01200041186a200110af012002200041206a360240200241c0006a200110c3010caf010b200241023a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9901200341017422052004200520044b1b22054100480d99010240024020030d002005102121040c010b200128020020032005102521040b2004450d8b0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a200110af01200041106a200110af01200041146a200110af012002200041186a360240200241c0006a200110c3010cae010b200241033a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9801200341017422052004200520044b1b22054100480d98010240024020030d002005102121040c010b200128020020032005102521040b2004450d8b0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002000410c6a200110d9020cad010b200141086a2802002103200241043a003c024002402003200141046a280200460d00200128020021050c010b200341016a22052003490d9701200341017422062005200620054b1b22064100480d97010240024020030d002006102121050c010b200128020020032006102521050b2005450d8b0120012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41043a00002000412c6a200110af01200041306a200110af0120022001360240200441016a200241c0006a106b200028023421052000413c6a28020022002001105c02400240200141046a2802002204200628020022036b2000490d00200128020021040c010b200320006a22062003490d9701200441017422032006200320064b1b22034100480d97010240024020040d002003102121040c010b200128020020042003102521040b2004450d8c0120012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2005200010dc041a0cac010b200241053a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9601200341017422052004200520044b1b22054100480d96010240024020030d002005102121040c010b200128020020032005102521040b2004450d8c0120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a00002000410c6a200110af0120002802102106200041186a28020022002001105c02400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d9601200441017422032005200320054b1b22034100480d96010240024020040d002003102121040c010b200128020020042003102521040b2004450d8d0120012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2006200010dc041a0cab010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9501200341017422052004200520044b1b22054100480d95010240024020030d002005102121040c010b200128020020032005102521040b2004450d8d0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41173a0000200041046a22042d0000417f6a220341064b0daa01024002400240024002400240024020030e0700010203040506000b200241003a003c02400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22052003490d9b01200341017422062005200620054b1b22064100480d9b010240024020030d002006102121050c010b200128020020032006102521050b2005450d940120012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41003a0000200041086a200110af01200220042d000141014622053a003c02400240200141046a28020020062802002203460d00200128020021040c010b200341016a22042003490d9b01200341017422062004200620044b1b22064100480d9b010240024020030d002006102121040c010b200128020020032006102521040b2004450d950120012004360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200420036a20053a0000200028020c210a200041146a28020022032001105c02400240200141046a2802002205200628020022046b2003490d00200128020021050c010b200420036a22062004490d9b01200541017422042006200420064b1b22044100480d9b010240024020050d002004102121050c010b200128020020052004102521050b2005450d960120012005360200200141046a2004360200200141086a28020021040b200141086a2206200420036a360200200520046a200a200310dc041a20002802182105200041206a28020022002001105c02400240200141046a2802002204200628020022036b2000490d00200128020021040c010b200320006a22062003490d9b01200441017422032006200320064b1b22034100480d9b010240024020040d002003102121040c010b200128020020042003102521040b2004450d970120012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2005200010dc041a0cb0010b200241013a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9a01200341017422052004200520044b1b22054100480d9a010240024020030d002005102121040c010b200128020020032005102521040b2004450d970120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041086a200110af010caf010b200241023a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9901200341017422052004200520044b1b22054100480d99010240024020030d002005102121040c010b200128020020032005102521040b2004450d970120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000280208210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d9901200341017422002005200020054b1b22004100480d99010240024020030d002000102121030c010b200128020020032000102521030b2003450d980120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000cae010b200241033a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490daa01200341017422052004200520044b1b22054100480daa010240024020030d002005102121040c010b200128020020032005102521040b2004450d990120012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41033a00002000280208210a200041106a28020022032001105c02400240200141046a2802002205200628020022046b2003490d00200128020021050c010b200420036a22062004490daa01200541017422042006200420064b1b22044100480daa010240024020050d002004102121050c010b200128020020052004102521050b2005450d9a0120012005360200200141046a2004360200200141086a28020021040b200141086a2206200420036a360200200520046a200a200310dc041a200028021421052000411c6a28020022002001105c02400240200141046a2802002204200628020022036b2000490d00200128020021040c010b200320006a22062003490daa01200441017422032006200320064b1b22034100480daa010240024020040d002003102121040c010b200128020020042003102521040b2004450d9b0120012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a2005200010dc041a0cad010b200141086a2802002103200241043a003c024002402003200141046a280200460d00200128020021050c010b200341016a22052003490da901200341017422062005200620054b1b22064100480da9010240024020030d002006102121050c010b200128020020032006102521050b2005450d9b0120012005360200200141046a2006360200200141086a28020021030b200141086a200341016a360200200520036a41043a0000200041c8006a200110af01200441016a2001107120022001360240200441216a200241c0006a106b0cac010b200241053a003c02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490da801200041017422042003200420034b1b22044100480da8010240024020000d002004102121030c010b200128020020002004102521030b2003450d9b0120012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41053a00000cab010b200241063a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da701200341017422052004200520044b1b22054100480da7010240024020030d002005102121040c010b200128020020032005102521040b2004450d9b0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200041086a200110af010caa010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da601200341017422052004200520044b1b22054100480da6010240024020030d002005102121040c010b200128020020032005102521040b2004450d9b0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41183a00002000280204417f6a220341024b0da90102400240024020030e03000102000b200241003a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da801200341017422052004200520044b1b22054100480da8010240024020030d002005102121040c010b200128020020032005102521040b2004450d9e0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208200110cb010cab010b200241013a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da701200341017422052004200520044b1b22054100480da7010240024020030d002005102121040c010b200128020020032005102521040b2004450d9e0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041086a200110d9020caa010b200241023a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da601200341017422052004200520044b1b22054100480da6010240024020030d002005102121040c010b200128020020032005102521040b2004450d9e0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041086a200110d902200028022c200110cb010ca9010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da501200341017422052004200520044b1b22054100480da5010240024020030d002005102121040c010b200128020020032005102521040b2004450d9e0120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41193a00002000280204417f6a220341034b0da801024002400240024020030e0400010203000b200241003a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da801200341017422052004200520044b1b22054100480da8010240024020030d002005102121040c010b200128020020032005102521040b2004450da20120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000020002802082106200041106a28020022032001105c02400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490da801200441017422002005200020054b1b22004100480da8010240024020040d002000102121040c010b200128020020042000102521040b2004450da30120012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310dc041a0cab010b200241013a003c02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490da701200041017422042003200420034b1b22044100480da7010240024020000d002004102121030c010b200128020020002004102521030b2003450da30120012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000caa010b200241023a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da601200341017422052004200520044b1b22054100480da6010240024020030d002005102121040c010b200128020020032005102521040b2004450da30120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041086a200110d9020ca9010b200241033a003c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da501200341017422052004200520044b1b22054100480da5010240024020030d002005102121040c010b200128020020032005102521040b2004450da30120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200041086a200110d902200028022c2106200041346a28020022032001105c02400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490da501200441017422002005200020054b1b22004100480da5010240024020040d002000102121040c010b200128020020042000102521040b2004450da40120012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310dc041a0ca8010b200541011030000b200441011030000b200541011030000b200341011030000b200541011030000b200041011030000b200541011030000b200341011030000b200441011030000b200541011030000b200541011030000b200541011030000b200341011030000b200541011030000b200341011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200941011030000b200441011030000b200541011030000b200341011030000b200341011030000b200341011030000b200341011030000b200541011030000b200541011030000b200041011030000b200a41011030000b200941011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200a41011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200441011030000b200541011030000b200a41011030000b200441011030000b200041011030000b200441011030000b200541011030000b200541011030000b200341011030000b200541011030000b200541011030000b200541011030000b200541011030000b200341011030000b200541011030000b200541011030000b200341011030000b200441011030000b200441011030000b200341011030000b200341011030000b200941011030000b200441011030000b200a41011030000b200541011030000b200541011030000b200a41011030000b200a41011030000b200a41011030000b200a41011030000b200a41011030000b200041011030000b200541011030000b200541011030000b200541011030000b200941011030000b200341011030000b200041011030000b200441011030000b200541011030000b200541011030000b200441011030000b200541011030000b200441011030000b200a41011030000b200641011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200441011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200641011030000b200b41011030000b200641011030000b200041011030000b200541011030000b200341011030000b200541011030000b200b41011030000b200541011030000b200b41011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200641011030000b200341011030000b200541011030000b200341011030000b200541011030000b200641011030000b200641011030000b200441011030000b200341011030000b200541011030000b200541011030000b200041011030000b102a000b200541011030000b200441011030000b200341011030000b200641011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200041011030000b200441011030000b200541011030000b200541011030000b200041011030000b102a000b41bca7c300102b000b024002400240200141046a2802002203200141086a28020022006b4104490d00200128020021030c010b200041046a22042000490d05200341017422002004200020044b1b22004100480d050240024020030d002000102121030c010b200128020020032000102521030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a2007a74102744102723600000c020b200041011030000b02400240200141046a2802002203200141086a28020022006b4102490d00200128020021030c010b200041026a22042000490d03200341017422002004200020044b1b22004100480d030240024020030d002000102121030c010b200128020020032000102521030b2003450d0220012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a2007a74102744101723b00000b200241e0006a24000f0b200041011030000b102a000b6801037f024041094101200128020022024101461b220310212204450d000240024020020d00200441003a0000410121010c010b200441013a000020042001290204370001410921010b2000200136020820002003360204200020043602000f0b200341011030000bfd5102057f027e230041106b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410110212203450d002002428180808010370204200220033602000240200128020022044103470d00200341003a00000c3f0b200341013a000020022802042105200228020821030240024020044102470d000240024020052003460d00200228020021040c010b200341016a22042003490d40200341017422052004200520044b1b22054100480d400240024020030d002005102121040c010b200228020020032005102521040b2004450d0420022005360204200220043602000b2002200341016a360208200420036a41003a0000200228020821030c010b0240024020052003460d00200228020021040c010b200341016a22042003490d3f200341017422052004200520044b1b22054100480d3f0240024020030d002005102121040c010b200228020020032005102521040b2004450d0420022005360204200220043602000b2002200341016a360208200420036a41013a00000240024020012802004101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d41200341017422052004200520044b1b22054100480d410240024020030d002005102121040c010b200228020020032005102521040b2004450d0720022005360204200220043602000b2002200341016a360208200420036a41003a0000200141086a2002107120022001280204220536020c2002410c6a21060c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d40200341017422052004200520044b1b22054100480d400240024020030d002005102121040c010b200228020020032005102521040b2004450d0720022005360204200220043602000b2002200341016a360208200420036a41013a000020022001280204220536020c2002410c6a21060b0240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22052003490d3f200441017422032005200320054b1b22034100480d3f0240024020040d002003102121040c010b200228020020042003102521040b2004450d07200220033602042002200436020020062802002105200228020821030b2002200341046a360208200420036a2005360000200141306a2903002107200129032821080240024020022802042204200228020822036b4110490d00200228020021040c010b200341106a22052003490d3f200441017422032005200320054b1b22034100480d3f0240024020040d002003102121040c010b200228020020042003102521040b2004450d082002200336020420022004360200200228020821030b200420036a22042007370008200420083700002002200341106a22033602080b200228020421040240024020012802384102460d000240024020042003460d00200228020021040c010b200341016a22042003490d40200341017422052004200520044b1b22054100480d400240024020030d002005102121040c010b200228020020032005102521040b2004450d0a2002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00000240024020012802384101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d42200341017422052004200520044b1b22054100480d420240024020030d002005102121040c010b200228020020032005102521040b2004450d0d2002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200141c0006a2002107120022001413c6a280200220536020c2002410c6a21060c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d41200341017422052004200520044b1b22054100480d410240024020030d002005102121040c010b200228020020032005102521040b2004450d0d2002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00002002200128023c220536020c2002410c6a21060b0240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d0d200220033602042002200436020020062802002105200228020821030b2002200341046a360208200420036a2005360000200141e8006a2903002107200129036021080240024020022802042204200228020822036b4110490d00200228020021040c010b200341106a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d0e2002200336020420022004360200200228020821030b200420036a22042007370008200420083700002002200341106a22033602080c010b0240024020042003460d00200228020021040c010b200341016a22042003490d3f200341017422052004200520044b1b22054100480d3f0240024020030d002005102121040c010b200228020020032005102521040b2004450d0e2002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200228020821030b200228020421040240024020012802704102460d000240024020042003460d00200228020021040c010b200341016a22042003490d40200341017422052004200520044b1b22054100480d400240024020030d002005102121040c010b200228020020032005102521040b2004450d102002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00000240024020012802704101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d42200341017422052004200520044b1b22054100480d420240024020030d002005102121040c010b200228020020032005102521040b2004450d132002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200141f8006a200210712002200141f4006a280200220536020c2002410c6a21060c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d41200341017422052004200520044b1b22054100480d410240024020030d002005102121040c010b200228020020032005102521040b2004450d132002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a000020022001280274220536020c2002410c6a21060b0240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d13200220033602042002200436020020062802002105200228020821030b2002200341046a360208200420036a2005360000200141a0016a290300210720012903980121080240024020022802042204200228020822036b4110490d00200228020021040c010b200341106a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d142002200336020420022004360200200228020821030b200420036a22042007370008200420083700002002200341106a22033602080c010b0240024020042003460d00200228020021040c010b200341016a22042003490d3f200341017422052004200520044b1b22054100480d3f0240024020030d002005102121040c010b200228020020032005102521040b2004450d142002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200228020821030b200228020421040240024020012802a8014102460d000240024020042003460d00200228020021040c010b200341016a22042003490d40200341017422052004200520044b1b22054100480d400240024020030d002005102121040c010b200228020020032005102521040b2004450d162002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00000240024020012802a8014101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d42200341017422052004200520044b1b22054100480d420240024020030d002005102121040c010b200228020020032005102521040b2004450d192002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200141b0016a200210712002200141ac016a280200220536020c2002410c6a21060c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d41200341017422052004200520044b1b22054100480d410240024020030d002005102121040c010b200228020020032005102521040b2004450d192002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a0000200220012802ac01220536020c2002410c6a21060b0240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d19200220033602042002200436020020062802002105200228020821030b2002200341046a360208200420036a2005360000200141d8016a290300210720012903d00121080240024020022802042204200228020822036b4110490d00200228020021040c010b200341106a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d1a2002200336020420022004360200200228020821030b200420036a22042007370008200420083700002002200341106a22033602080c010b0240024020042003460d00200228020021040c010b200341016a22042003490d3f200341017422052004200520044b1b22054100480d3f0240024020030d002005102121040c010b200228020020032005102521040b2004450d1a2002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200228020821030b200228020421040240024020012802e0014102460d000240024020042003460d00200228020021040c010b200341016a22042003490d40200341017422052004200520044b1b22054100480d400240024020030d002005102121040c010b200228020020032005102521040b2004450d1c2002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00000240024020012802e0014101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d42200341017422052004200520044b1b22054100480d420240024020030d002005102121040c010b200228020020032005102521040b2004450d1f2002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200141e8016a200210712002200141e4016a280200220536020c2002410c6a21060c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d41200341017422052004200520044b1b22054100480d410240024020030d002005102121040c010b200228020020032005102521040b2004450d1f2002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a0000200220012802e401220536020c2002410c6a21060b0240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d1f200220033602042002200436020020062802002105200228020821030b2002200341046a360208200420036a200536000020014190026a290300210720012903880221080240024020022802042204200228020822036b4110490d00200228020021040c010b200341106a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d202002200336020420022004360200200228020821030b200420036a22042007370008200420083700002002200341106a22033602080c010b0240024020042003460d00200228020021040c010b200341016a22042003490d3f200341017422052004200520044b1b22054100480d3f0240024020030d002005102121040c010b200228020020032005102521040b2004450d202002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200228020821030b20022802042104024002402001280298024102460d000240024020042003460d00200228020021040c010b200341016a22042003490d40200341017422052004200520044b1b22054100480d400240024020030d002005102121040c010b200228020020032005102521040b2004450d222002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a0000024002402001280298024101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d42200341017422052004200520044b1b22054100480d420240024020030d002005102121040c010b200228020020032005102521040b2004450d252002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200141a0026a2002107120022001419c026a280200220536020c2002410c6a21060c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d41200341017422052004200520044b1b22054100480d410240024020030d002005102121040c010b200228020020032005102521040b2004450d252002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00002002200128029c02220536020c2002410c6a21060b0240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d25200220033602042002200436020020062802002105200228020821030b2002200341046a360208200420036a2005360000200141c8026a290300210720012903c00221080240024020022802042204200228020822036b4110490d00200228020021040c010b200341106a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d262002200336020420022004360200200228020821030b200420036a22042007370008200420083700002002200341106a22033602080c010b0240024020042003460d00200228020021040c010b200341016a22042003490d3f200341017422052004200520044b1b22054100480d3f0240024020030d002005102121040c010b200228020020032005102521040b2004450d262002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200228020821030b200228020421040240024020012802d0024102460d000240024020042003460d00200228020021040c010b200341016a22042003490d40200341017422052004200520044b1b22054100480d400240024020030d002005102121040c010b200228020020032005102521040b2004450d282002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00000240024020012802d0024101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d42200341017422052004200520044b1b22054100480d420240024020030d002005102121040c010b200228020020032005102521040b2004450d2b2002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200141d8026a200210712002200141d4026a280200220536020c2002410c6a21060c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d41200341017422052004200520044b1b22054100480d410240024020030d002005102121040c010b200228020020032005102521040b2004450d2b2002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a0000200220012802d402220536020c2002410c6a21060b0240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d2b200220033602042002200436020020062802002105200228020821030b2002200341046a360208200420036a200536000020014180036a290300210720012903f80221080240024020022802042204200228020822036b4110490d00200228020021040c010b200341106a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d2c2002200336020420022004360200200228020821030b200420036a22042007370008200420083700002002200341106a22033602080c010b0240024020042003460d00200228020021040c010b200341016a22042003490d3f200341017422052004200520044b1b22054100480d3f0240024020030d002005102121040c010b200228020020032005102521040b2004450d2c2002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200228020821030b20022802042104024002402001280288034102460d000240024020042003460d00200228020021040c010b200341016a22042003490d40200341017422052004200520044b1b22054100480d400240024020030d002005102121040c010b200228020020032005102521040b2004450d2e2002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a0000024002402001280288034101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d42200341017422052004200520044b1b22054100480d420240024020030d002005102121040c010b200228020020032005102521040b2004450d312002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a000020014190036a2002107120022001418c036a280200220536020c2002410c6a21060c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d41200341017422052004200520044b1b22054100480d410240024020030d002005102121040c010b200228020020032005102521040b2004450d312002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00002002200128028c03220536020c2002410c6a21060b0240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d31200220033602042002200436020020062802002105200228020821030b2002200341046a360208200420036a2005360000200141b8036a290300210720012903b00321080240024020022802042204200228020822036b4110490d00200228020021040c010b200341106a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d322002200336020420022004360200200228020821030b200420036a22042007370008200420083700002002200341106a22033602080c010b0240024020042003460d00200228020021040c010b200341016a22042003490d3f200341017422052004200520044b1b22054100480d3f0240024020030d002005102121040c010b200228020020032005102521040b2004450d322002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200228020821030b200228020421040240024020012802c0034102460d000240024020042003460d00200228020021040c010b200341016a22042003490d40200341017422052004200520044b1b22054100480d400240024020030d002005102121040c010b200228020020032005102521040b2004450d342002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00000240024020012802c0034101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d42200341017422052004200520044b1b22054100480d420240024020030d002005102121040c010b200228020020032005102521040b2004450d372002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200141c8036a200210712002200141c4036a280200220536020c2002410c6a21060c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d41200341017422052004200520044b1b22054100480d410240024020030d002005102121040c010b200228020020032005102521040b2004450d372002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a0000200220012802c403220536020c2002410c6a21060b0240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d37200220033602042002200436020020062802002105200228020821030b2002200341046a360208200420036a2005360000200141f0036a290300210720012903e80321080240024020022802042204200228020822036b4110490d00200228020021040c010b200341106a22052003490d40200441017422032005200320054b1b22034100480d400240024020040d002003102121040c010b200228020020042003102521040b2004450d382002200336020420022004360200200228020821030b200420036a22042007370008200420083700002002200341106a22033602080c010b0240024020042003460d00200228020021040c010b200341016a22042003490d3f200341017422052004200520044b1b22054100480d3f0240024020030d002005102121040c010b200228020020032005102521040b2004450d382002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a0000200228020821030b20022802042104024020012802f8034102460d000240024020042003460d00200228020021040c010b200341016a22042003490d3f200341017422052004200520044b1b22054100480d3f0240024020030d002005102121040c010b200228020020032005102521040b2004450d392002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00000240024020012802f8034101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d41200341017422052004200520044b1b22054100480d410240024020030d002005102121040c010b200228020020032005102521040b2004450d3c2002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a000020014180046a200210712002200141fc036a280200220536020c2002410c6a21060c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d40200341017422052004200520044b1b22054100480d400240024020030d002005102121040c010b200228020020032005102521040b2004450d3c2002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a0000200220012802fc03220536020c2002410c6a21060b0240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22052003490d3f200441017422032005200320054b1b22034100480d3f0240024020040d002003102121040c010b200228020020042003102521040b2004450d3c200220033602042002200436020020062802002105200228020821030b2002200341046a360208200420036a2005360000200141a8046a290300210720012903a00421080240024020022802042203200228020822016b4110490d00200228020021030c010b200141106a22042001490d3f200341017422012004200120044b1b22014100480d3f0240024020030d002001102121030c010b200228020020032001102521030b2003450d3d2002200136020420022003360200200228020821010b200320016a22032007370008200320083700002002200141106a3602080c3f0b0240024020042003460d00200228020021010c010b200341016a22012003490d3e200341017422042001200420014b1b22044100480d3e0240024020030d002004102121010c010b200228020020032004102521010b2001450d3d2002200436020420022001360200200228020821030b2002200341016a360208200120036a41003a00000c3e0b410141011030000b200541011030000b200541011030000b200541011030000b200541011030000b200341011030000b200341011030000b200541011030000b200541011030000b200541011030000b200341011030000b200341011030000b200541011030000b200541011030000b200541011030000b200541011030000b200341011030000b200341011030000b200541011030000b200541011030000b200541011030000b200541011030000b200341011030000b200341011030000b200541011030000b200541011030000b200541011030000b200541011030000b200341011030000b200341011030000b200541011030000b200541011030000b200541011030000b200541011030000b200341011030000b200341011030000b200541011030000b200541011030000b200541011030000b200541011030000b200341011030000b200341011030000b200541011030000b200541011030000b200541011030000b200541011030000b200341011030000b200341011030000b200541011030000b200541011030000b200541011030000b200541011030000b200341011030000b200341011030000b200541011030000b200541011030000b200541011030000b200541011030000b200341011030000b200141011030000b200441011030000b102a000b20002002290300370200200041086a200241086a280200360200200241106a24000b9c2903087f057e277f230041d00c6b22042400200441e0016a41186a200241186a290000370300200441e0016a41106a200241106a290000370300200441e0016a41086a200241086a290000370300200420022900003703e0010240024002400240024002400240024002402001280200220541d8a7c300460d00200128020421060c010b41002106200441c0026a410041e00210db041a200441a8056a410041900410db041a41f80610212205450d01200541003b010620054100360200200541086a200441c0026a41e00210dc041a200541e8026a200441a8056a41900410dc041a20014100360204200120053602000b02400340200541086a2107200541066a210820052f0106220941057421024100210a0240024003402002450d01200441e0016a2007412010de04220b450d02200241606a2102200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200520094102746a41f8066a28020021050c010b0b2005200a41306c6a22024180036a2207290300210c2003290300210d2003290308210e2003290310210f2007200341186a290300370300200241f8026a220729030021102007200f370300200241f0026a2207290300210f2007200e370300200241e8026a2207290300210e2007200d370300200441a8056a41086a220720024190036a220a290300370300200420024188036a22022903003703a80520022003290320370300200a200341286a290300370300200441c0026a41086a22022007290300370300200420042903a805220d3703c002200041186a200c370300200020103703102000200f3703082000200e3703002000200d370320200041286a20022903003703000c060b200441186a2202200441e0016a41186a2207290300370300200441106a200441e0016a41106a220a290300220c370300200441086a200441e0016a41086a220b290300220d370300200420042903e001220e3703002001200128020841016a360208200441f8006a41106a2206200c370300200441f8006a41086a2211200d370300200441f8006a41186a221220022903003703002004200e370378200441e0016a41286a2213200341286a290300370300200441e0016a41206a2214200341206a2903003703002007200341186a290300370300200a200341106a290300370300200b200341086a290300370300200420032903003703e001024020082f01002203410b490d00200441c0026a410041e00210db041a200441a8056a410041900410db041a41f80610212215450d02201541003b010620154100360200201541086a200441c0026a41e00210dc042107201541e8026a200441a8056a41900410dc04210a200441a8056a41086a220b20054190056a290300370300200441a8056a41106a220320054198056a290300370300200441a8056a41186a2206200541a0056a290300370300200441a8056a41206a2211200541a8056a290300370300200441a8056a41286a2212200541b0056a290300370300200420052900db013703a8022004200541e0016a2900003700ad0220042005290388053703a805200420052f00c8013b01bc022004200541ca016a2d00003a00be02200541cb016a2800002116200541cf016a2800002117200541d3016a2800002118200541d7016a28000021192007200541e8016a20052f010641796a220241057410dc042107200a200541b8056a200241306c10dc04210a200541063b0106201520023b0106200420042f01bc023b01a402200420042d00be023a00a602200420042903a80237039002200420042900ad0237009502200441c0026a41286a2012290300370300200441c0026a41206a2011290300370300200441c0026a41186a2006290300370300200441c0026a41106a2003290300370300200441c0026a41086a200b290300370300200420042903a8053703c0020240024020094107490d00200941057420076a41c07e6a2007200941796a220b4105746a2207200241ffff0371200b6b41057410dd041a200741186a200441f8006a41186a290300370000200741106a200441f8006a41106a290300370000200741086a200441f8006a41086a29030037000020072004290378370000200941306c200a6a220241e07d6a200241b07d6a2202201541066a22082f0100200b6b41306c10dd041a200241286a200441e0016a41286a290300370300200241206a200441e0016a41206a290300370300200241186a200441e0016a41186a290300370300200241106a200441e0016a41106a290300370300200241086a200441e0016a41086a290300370300200220042903e0013703000c010b200541086a20094105746a220241206a200220082f010020096b41057410dd041a200241186a200441f8006a41186a290300370000200241106a200441f8006a41106a290300370000200241086a200441f8006a41086a29030037000020022004290378370000200541e8026a200941306c6a220241306a200220082f010020096b41306c10dd041a200241286a200441e0016a41286a290300370300200241206a200441e0016a41206a290300370300200241186a200441e0016a41186a290300370300200241106a200441e0016a41106a290300370300200241086a200441e0016a41086a290300370300200220042903e0013703000b200820082f010041016a3b0100200441c8016a41026a220220042d00a6023a000020044198016a41086a221a200441c0026a41086a221b29030037030020044198016a41106a221c200441c0026a41106a221d29030037030020044198016a41186a221e200441c0026a41186a221f29030037030020044198016a41206a2220200441c0026a41206a222129030037030020044198016a41286a2222200441c0026a41286a2223290300370300200420042f01a4023b01c8012004200429039002370368200420042900950237006d200420042903c00237039801200441386a41286a22242022290300370300200441386a41206a22252020290300370300200441386a41186a2226201e290300370300200441386a41106a2227201c290300370300200441386a41086a2228201a290300370300200441346a41026a222920022d00003a00002004200429039801370338200420042903683703202004200429006d370025200420042f01c8013b013420052802002203450d0420052f01042114200441a8056a410272212a0340200441dc016a41026a222b20292d00003a0000200420042f01343b01dc01200420042903203703682004200429002537006d200441e0016a41286a222c2024290300370300200441e0016a41206a222d2025290300370300200441e0016a41186a222e2026290300370300200441e0016a41106a222f2027290300370300200441e0016a41086a22302028290300370300200420042903383703e001201441ffff0371210502400240024020032f01062202410b490d00202a410041a20710db041a41a8071021220b450d07200b4100360200200b41046a200441a8056a41a40710dc041a200420032f00c8013b01bc022004200341ca016a2d00003a00be02200420032900db013703a8022004200341e0016a2900003700ad02200341cb016a2800002131200341cf016a2800002132200341d3016a2800002133200341d7016a2800002134200441a8056a41286a2209200341b0056a290300370300200441a8056a41206a2208200341a8056a290300370300200441a8056a41186a2211200341a0056a290300370300200441a8056a41106a221220034198056a290300370300200441a8056a41086a221320034190056a29030037030020042003290388053703a805200b41086a200341e8016a20032f0106220741796a220241057410dc042135200b41e8026a200341b8056a200241306c10dc042136200b41f8066a20034194076a2007417a6a220641027410dc042137200341063b0106200b20023b010602402006450d00410021022037210703402007280200220a20023b0104200a200b360200200741046a21072006200241016a2202470d000b0b2023200929030037030020212008290300370300201f2011290300370300201d2012290300370300201b2013290300370300200420042903a8053703c002200420042f01bc023b01a402200420042d00be023a00a602200420042903a80237039002200420042900ad0237009502200441a4056a41026a220620042d00a6023a0000200420042f01a4023b01a4052004200429039002370378200420042900950237007d20092023290300370300200820212903003703002011201f2903003703002012201d2903003703002013201b290300370300200420042903c0023703a805201441ffff037122074107490d0120352005417a6a220a4105746a2035200541796a22024105746a2207200b2f010620026b41057410dd041a200741186a200429006d3700002007201936000f2007201836000b2007201736000720072016360003200741026a202b2d00003a0000200720042f01dc013b000020072004290368370013200541306c20366a220741e07d6a200741b07d6a2207200b2f0106221420026b41306c10dd041a200741286a202c290300370300200741206a202d290300370300200741186a202e290300370300200741106a202f290300370300200741086a2030290300370300200720042903e001370300200b201441016a22073b01062005410274221620376a416c6a2037200a4102746a2214200741ffff03712205200a6b41027410dd041a201420153602002005200a490d02200b20166a41e0066a210703402007280200220a200241016a22023b0104200a200b360200200741046a210720022005490d000c030b0b200341086a2207200541016a220a4105746a200720054105746a2207200220056b220b41057410dd041a2007201936000f2007201836000b2007201736000720072016360003200741026a200441dc016a41026a2d00003a0000200720042f01dc013b000020072004290368370013200741186a200429006d3700002003200541306c6a22074198036a200741e8026a2206200b41306c10dd041a20074190036a20044188026a29030037030020074188036a20044180026a29030037030020074180036a200441e0016a41186a290300370300200741f8026a200441f0016a290300370300200741f0026a200441e0016a41086a290300370300200620042903e0013703002003200241016a22023b01062005410274200341f8066a22076a41086a2007200a4102746a2207200241ffff0371200a6b41027410dd041a20072015360200201441ffff037120032f010622024f0d082015200a3b010420152003360200200a20024f0d082002417f6a210b2003200a417f6a22024102746a4180076a210703402007280200220a200241026a3b0104200a2003360200200741046a2107200b200241016a2202470d000c090b0b200341086a2202200541016a220a4105746a200220054105746a220220032f0106221420056b223741057410dd041a2002201936000f2002201836000b2002201736000720022016360003200241026a202b2d00003a0000200220042f01dc013b000020022004290368370013200241186a200429006d370000200341e8026a200541306c6a220241306a2002203741306c10dd041a200241286a202c290300370300200241206a202d290300370300200241186a202e290300370300200241106a202f290300370300200241086a2030290300370300200220042903e0013703002003201441016a22023b010620054102742237200341f8066a22146a41086a2014200a4102746a2214200241ffff0371200a6b41027410dd041a20142015360200200720032f0106220a4f0d00200320376a41fc066a2102034020022802002207200541016a22053b010420072003360200200241046a2102200a2005470d000b0b200441d8016a41026a220220062d00003a0000201a2013290300370300201c2012290300370300201e20112903003703002020200829030037030020222009290300370300200420042f01a4053b01d801200420042903783703c8012004200429007d3700cd01200420042903a8053703980120242022290300370300202520202903003703002026201e2903003703002027201c2903003703002028201a290300370300202920022d00003a00002004200429039801370338200420042903c801370320200420042900cd01370025200420042f01d8013b01340240200328020022020d0020312116203421192033211820322117200b21150c060b20032f010421142031211620342119203321182032211720022103200b21150c000b0b200520094105746a220241286a200241086a2201200320096b41057410dd041a200241206a2012290300370000200241186a2006290300370000200241106a2011290300370000200120042903783700002005200941306c6a22024198036a200241e8026a220320052f010620096b41306c10dd041a20024190036a201329030037030020024188036a201429030037030020024180036a2007290300370300200241f8026a200a290300370300200241f0026a200b290300370300200320042903e001370300200520052f010641016a3b01060c040b41f80641081030000b41f80641081030000b41a80741081030000b200441a8056a410272410041a20710db041a41a80710212202450d0220024100360200200241046a200441a8056a41a40710dc041a2002200128020022073602f806200120023602002001200128020441016a360204200741003b010420072002360200200220022f0106220a4105746a220741086a20042f01343b00002007410a6a200441346a41026a2d00003a0000200741176a2019360000200741136a20183600002007410f6a20173600002007410b6a20163600002007411b6a2004290320370000200741206a20042900253700002002200a41306c6a220741e8026a2004290338370300200741f0026a200441386a41086a290300370300200741f8026a200441c8006a29030037030020074180036a200441d0006a29030037030020074188036a200441386a41206a29030037030020074190036a200441e0006a290300370300200241f8066a200a41016a22074102746a2015360200200220073b010620152002360200201520073b01040b200041003602200b200441d00c6a24000f0b41a80741081030000bd21b03087f047e107f23004180056b22032400200341d0006a41186a200141186a290000370300200341d0006a41106a200141106a290000370300200341d0006a41086a200141086a290000370300200320012900003703500240024002400240024002402000280200220441d8a7c300460d00200028020421050c010b41002105200341c0016a410041e00210db041a200341b8016a22014100360200200341b0016a2206420037030020034190016a41186a420037030020034190016a41106a420037030020034190016a41086a4200370300200342003703900141940310212204450d01200441003b010620044100360200200441086a200341c0016a41e00210dc041a20044190036a200128020036020020044188036a200629030037020020044180036a200341a8016a290300370200200441f8026a200341a0016a290300370200200441f0026a20034190016a41086a29030037020020042003290390013702e80220004100360204200020043602000b02400340200441086a2106200441066a210720042f010622084105742101410021090240024003402001450d01200341d0006a2006412010de04220a450d02200141606a2101200941016a2109200641206a2106200a417f4a0d000b2009417f6a21080b2005450d022005417f6a2105200420084102746a4194036a28020021040c010b0b200420094102746a41e8026a20023602000c030b200341086a41186a200341d0006a41186a2201290300220b370300200341086a41106a200341d0006a41106a2206290300220c370300200341086a41086a200341d0006a41086a2209290300220d37030020032003290350220e3703082000200028020841016a3602082001200b3703002006200c3703002009200d3703002003200e370350024002400240024020072f01002205410b490d00200341c0016a410041e00210db041a200341b8016a22014100360200200341b0016a2206420037030020034190016a41186a420037030020034190016a41106a420037030020034190016a41086a420037030020034200370390014194031021220f450d03200f41003b0106200f4100360200200f41086a200341c0016a41e00210dc042109200f4190036a2001280200360200200f4188036a2006290300370200200f4180036a20034190016a41186a290300370200200f41f8026a20034190016a41106a290300370200200f41f0026a20034190016a41086a290300370200200f2003290390013702e802200320042f00c8013b018c012003200441ca016a2d00003a008e01200441cb016a2800002110200441cf016a2800002111200441d3016a2800002112200441d7016a28000021132003200441e0016a29000037007d200320042900db0137037820042802800321142009200441e8016a20042f010641796a220141057410dc042109200f41e8026a20044184036a200141027410dc04210a200441063b0106200f20013b0106200320032f018c013b0174200320032d008e013a007620032003290378370390012003200329007d3700950120084107490d01200f41066a210720092008417a6a22054105746a2009200841796a22064105746a2209200141ffff037120066b41057410dd041a200941186a200341d0006a41186a290300370000200941106a200341d0006a41106a290300370000200941086a200341d0006a41086a29030037000020092003290350370000200a20054102746a2109200a20064102746a21010c020b200441086a220a200841016a22004105746a200a20084105746a220a200520086b41057410dd041a200a41186a2001290300370000200a41106a2006290300370000200a41086a2009290300370000200a2003290350370000200441e8026a220120004102746a200120084102746a220120042f010620086b41027410dd041a20012002360200200420042f010641016a3b01060c050b200441086a2201200841016a22064105746a200120084105746a220120072f010020086b41057410dd041a200141186a200341d0006a41186a290300370000200141106a200341d0006a41106a290300370000200141086a200341d0006a41086a29030037000020012003290350370000200441e8026a220920084102746a2101200920064102746a2109200821060b2009200120072f010020066b41027410dd041a20012002360200200720072f010041016a3b0100200341f0006a41026a221520032d007622013a00002003413c6a41026a221620013a000020032003290095013700452003200329039001370340200320032f017422013b01702003200329004537002d20032003290340370328200320013b013c20042802002205450d0220042f01042107200341c0016a41027221170340201520162d00003a0000200320032f013c3b0170200320032903283703502003200329002d370055200741ffff037121040240024002400240024020052f01062201410b490d002017410041be0310db041a41c4031021220a450d03200a4100360200200a41046a200341c0016a41c00310dc041a200320052f00c8013b018c012003200541ca016a2d00003a008e012003200541db016a2900003703782003200541e0016a29000037007d200541cb016a2800002118200541cf016a2800002119200541d3016a280000211a200541d7016a280000211b20054180036a280200211c200a41086a200541e8016a20052f0106220641796a220141057410dc04211d200a41e8026a20054184036a200141027410dc04211e200a4194036a200541b0036a2006417a6a220841027410dc042102200541063b0106200a20013b010602402008450d00410021012002210603402006280200220920013b01042009200a360200200641046a21062008200141016a2201470d000b0b200320032d008e0122013a0076200320032f018c0122063b017420032003290378370390012003200329007d37009501200341c0006a41026a220820013a0000200320063b014020032003290390013703c00120032003290095013700c501200741ffff037122064107490d01201d2004417a6a22094105746a201d200441796a22014105746a2206200a2f010620016b41057410dd041a200641186a20032900553700002006201336000f2006201236000b2006201136000720062010360003200641026a20152d00003a0000200620032f01703b000020062003290350370013201e200941027422066a201e20014102746a2207200a2f0106221020016b41027410dd041a20072014360200200a201041016a22073b01062004410274221020026a416c6a200220066a2206200741ffff0371220420096b41027410dd041a2006200f36020020042009490d02200a20106a41fc026a2106034020062802002209200141016a22013b01042009200a360200200641046a210620012004490d000c030b0b200541086a2206200441016a22094105746a200620044105746a2206200120046b41057410dd041a200641186a20032900553700002006201336000f2006201236000b2006201136000720062010360003200641026a200341f0006a41026a2d00003a0000200620032f01703b000020062003290350370013200541e8026a2201200941027422066a20012004410274220a6a220120052f0106220820046b41027410dd041a200120143602002005200841016a22013b0106200a20054194036a22046a41086a200420066a2206200141ffff0371220a20096b41027410dd041a2006200f360200200741ffff0371200a4f0d0820052009417f6a22014102746a4198036a2106034020062802002209200141016a22013b010420092005360200200641046a21062001200a490d000c090b0b200541086a2201200441016a22074105746a200120044105746a220120052f010620046b41057410dd041a200141186a20032900553700002001201336000f2001201236000b2001201136000720012010360003200141026a20152d00003a0000200120032f01703b000020012003290350370013200541e8026a2209200741027422026a2009200441027422016a220920052f0106221020046b41027410dd041a200920143602002005201041016a22093b0106200120054194036a22106a41086a201020026a2202200941ffff0371220920076b41027410dd041a2002200f360200200620094f0d00200520016a4198036a2101034020012802002206200441016a22043b010420062005360200200141046a210120092004470d000b0b201620082d00003a0000200320032f01403b013c200320032903c001370328200320032900c50137002d200528020022010d0120182110201b2113201a211220192111200a210f201c21140c050b41c40341041030000b20052f0104210720182110201b2113201a21122019211120012105201c2114200a210f0c000b0b41940341041030000b41940341041030000b200341c0016a410272410041be0310db041a41c40310212201450d0120014100360200200141046a200341c0016a41c00310dc041a20012000280200220636029403200020013602002000200028020441016a360204200641003b010420062001360200200120012f010622094105746a220641086a20032f013c3b00002006410a6a2003413c6a41026a2d00003a0000200641176a2013360000200641136a20123600002006410f6a20113600002006410b6a20103600002006411b6a2003290328370000200641206a200329002d37000020014194036a200941016a22064102746a200f360200200120094102746a41e8026a2014360200200120063b0106200f20063b0104200f20013602000b20034180056a24000f0b41c40341041030000b8b0303017f017e027f02402001450d00034020002802940321002001417f6a22010d000b0b02402002450d00410021034100210103402002417f6a210202400240200120002f01064f0d00200141016a21010c010b02400240200028020022010d002003ad210441002105410021010c010b20003301044220862003ad842104410121050b200010232004a72103024002402004422088a7220620012f01064f0d00200121000c010b034002400240200128020022000d002003ad2104410021000c010b200541016a210520013301044220862003ad8421040b200110232004a72103200021012004422088a7220620002f01064f0d000b0b200641027420006a4198036a280200210002402005417f6a2201450d00034020002802940321002001417f6a22010d000b0b410021010b20020d000b0b0240200041d8a7c300460d0020002802002101200010232001450d0020012802002100200110232000450d00024020002802002201450d000340200010232001210020012802002203210120030d000b0b200010230b0ba65002057f027e230041106b220224002002410036020820024201370300200028020021034101102121040240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020034102470d002004450d02200242818080801037020420022004360200200441003a0000200228020821040c010b2004450d02200242818080801037020420022004360200200441013a00000240024020002802004101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d40200441017422052003200520034b1b22054100480d400240024020040d002005102121030c010b200228020020042005102521030b2003450d0620022005360204200220033602000b2002200441016a360208200320046a41003a0000200041086a2002107120022000280204220536020c2002410c6a21060c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d3f200441017422052003200520034b1b22054100480d3f0240024020040d002005102121030c010b200228020020042005102521030b2003450d0620022005360204200220033602000b2002200441016a360208200320046a41013a000020022000280204220536020c2002410c6a21060b0240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d3e200341017422042005200420054b1b22044100480d3e0240024020030d002004102121030c010b200228020020032004102521030b2003450d06200220043602042002200336020020062802002105200228020821040b2002200441046a360208200320046a2005360000200041306a2903002107200029032821080240024020022802042203200228020822046b4110490d00200228020021030c010b200441106a22052004490d3e200341017422042005200420054b1b22044100480d3e0240024020030d002004102121030c010b200228020020032004102521030b2003450d072002200436020420022003360200200228020821040b200320046a22032007370008200320083700002002200441106a22043602080b200228020421030240024020002802384102460d000240024020032004460d00200228020021030c010b200441016a22032004490d3f200441017422052003200520034b1b22054100480d3f0240024020040d002005102121030c010b200228020020042005102521030b2003450d092002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a00000240024020002802384101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d41200441017422052003200520034b1b22054100480d410240024020040d002005102121030c010b200228020020042005102521030b2003450d0c2002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200041c0006a2002107120022000413c6a280200220536020c2002410c6a21060c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d40200441017422052003200520034b1b22054100480d400240024020040d002005102121030c010b200228020020042005102521030b2003450d0c2002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a00002002200028023c220536020c2002410c6a21060b0240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d0c200220043602042002200336020020062802002105200228020821040b2002200441046a360208200320046a2005360000200041e8006a2903002107200029036021080240024020022802042203200228020822046b4110490d00200228020021030c010b200441106a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d0d2002200436020420022003360200200228020821040b200320046a22032007370008200320083700002002200441106a22043602080c010b0240024020032004460d00200228020021030c010b200441016a22032004490d3e200441017422052003200520034b1b22054100480d3e0240024020040d002005102121030c010b200228020020042005102521030b2003450d0d2002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200228020821040b200228020421030240024020002802704102460d000240024020032004460d00200228020021030c010b200441016a22032004490d3f200441017422052003200520034b1b22054100480d3f0240024020040d002005102121030c010b200228020020042005102521030b2003450d0f2002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a00000240024020002802704101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d41200441017422052003200520034b1b22054100480d410240024020040d002005102121030c010b200228020020042005102521030b2003450d122002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200041f8006a200210712002200041f4006a280200220536020c2002410c6a21060c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d40200441017422052003200520034b1b22054100480d400240024020040d002005102121030c010b200228020020042005102521030b2003450d122002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a000020022000280274220536020c2002410c6a21060b0240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d12200220043602042002200336020020062802002105200228020821040b2002200441046a360208200320046a2005360000200041a0016a290300210720002903980121080240024020022802042203200228020822046b4110490d00200228020021030c010b200441106a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d132002200436020420022003360200200228020821040b200320046a22032007370008200320083700002002200441106a22043602080c010b0240024020032004460d00200228020021030c010b200441016a22032004490d3e200441017422052003200520034b1b22054100480d3e0240024020040d002005102121030c010b200228020020042005102521030b2003450d132002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200228020821040b200228020421030240024020002802a8014102460d000240024020032004460d00200228020021030c010b200441016a22032004490d3f200441017422052003200520034b1b22054100480d3f0240024020040d002005102121030c010b200228020020042005102521030b2003450d152002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a00000240024020002802a8014101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d41200441017422052003200520034b1b22054100480d410240024020040d002005102121030c010b200228020020042005102521030b2003450d182002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200041b0016a200210712002200041ac016a280200220536020c2002410c6a21060c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d40200441017422052003200520034b1b22054100480d400240024020040d002005102121030c010b200228020020042005102521030b2003450d182002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a0000200220002802ac01220536020c2002410c6a21060b0240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d18200220043602042002200336020020062802002105200228020821040b2002200441046a360208200320046a2005360000200041d8016a290300210720002903d00121080240024020022802042203200228020822046b4110490d00200228020021030c010b200441106a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d192002200436020420022003360200200228020821040b200320046a22032007370008200320083700002002200441106a22043602080c010b0240024020032004460d00200228020021030c010b200441016a22032004490d3e200441017422052003200520034b1b22054100480d3e0240024020040d002005102121030c010b200228020020042005102521030b2003450d192002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200228020821040b200228020421030240024020002802e0014102460d000240024020032004460d00200228020021030c010b200441016a22032004490d3f200441017422052003200520034b1b22054100480d3f0240024020040d002005102121030c010b200228020020042005102521030b2003450d1b2002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a00000240024020002802e0014101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d41200441017422052003200520034b1b22054100480d410240024020040d002005102121030c010b200228020020042005102521030b2003450d1e2002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200041e8016a200210712002200041e4016a280200220536020c2002410c6a21060c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d40200441017422052003200520034b1b22054100480d400240024020040d002005102121030c010b200228020020042005102521030b2003450d1e2002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a0000200220002802e401220536020c2002410c6a21060b0240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d1e200220043602042002200336020020062802002105200228020821040b2002200441046a360208200320046a200536000020004190026a290300210720002903880221080240024020022802042203200228020822046b4110490d00200228020021030c010b200441106a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d1f2002200436020420022003360200200228020821040b200320046a22032007370008200320083700002002200441106a22043602080c010b0240024020032004460d00200228020021030c010b200441016a22032004490d3e200441017422052003200520034b1b22054100480d3e0240024020040d002005102121030c010b200228020020042005102521030b2003450d1f2002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200228020821040b20022802042103024002402000280298024102460d000240024020032004460d00200228020021030c010b200441016a22032004490d3f200441017422052003200520034b1b22054100480d3f0240024020040d002005102121030c010b200228020020042005102521030b2003450d212002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a0000024002402000280298024101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d41200441017422052003200520034b1b22054100480d410240024020040d002005102121030c010b200228020020042005102521030b2003450d242002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200041a0026a2002107120022000419c026a280200220536020c2002410c6a21060c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d40200441017422052003200520034b1b22054100480d400240024020040d002005102121030c010b200228020020042005102521030b2003450d242002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a00002002200028029c02220536020c2002410c6a21060b0240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d24200220043602042002200336020020062802002105200228020821040b2002200441046a360208200320046a2005360000200041c8026a290300210720002903c00221080240024020022802042203200228020822046b4110490d00200228020021030c010b200441106a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d252002200436020420022003360200200228020821040b200320046a22032007370008200320083700002002200441106a22043602080c010b0240024020032004460d00200228020021030c010b200441016a22032004490d3e200441017422052003200520034b1b22054100480d3e0240024020040d002005102121030c010b200228020020042005102521030b2003450d252002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200228020821040b200228020421030240024020002802d0024102460d000240024020032004460d00200228020021030c010b200441016a22032004490d3f200441017422052003200520034b1b22054100480d3f0240024020040d002005102121030c010b200228020020042005102521030b2003450d272002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a00000240024020002802d0024101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d41200441017422052003200520034b1b22054100480d410240024020040d002005102121030c010b200228020020042005102521030b2003450d2a2002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200041d8026a200210712002200041d4026a280200220536020c2002410c6a21060c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d40200441017422052003200520034b1b22054100480d400240024020040d002005102121030c010b200228020020042005102521030b2003450d2a2002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a0000200220002802d402220536020c2002410c6a21060b0240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d2a200220043602042002200336020020062802002105200228020821040b2002200441046a360208200320046a200536000020004180036a290300210720002903f80221080240024020022802042203200228020822046b4110490d00200228020021030c010b200441106a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d2b2002200436020420022003360200200228020821040b200320046a22032007370008200320083700002002200441106a22043602080c010b0240024020032004460d00200228020021030c010b200441016a22032004490d3e200441017422052003200520034b1b22054100480d3e0240024020040d002005102121030c010b200228020020042005102521030b2003450d2b2002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200228020821040b20022802042103024002402000280288034102460d000240024020032004460d00200228020021030c010b200441016a22032004490d3f200441017422052003200520034b1b22054100480d3f0240024020040d002005102121030c010b200228020020042005102521030b2003450d2d2002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a0000024002402000280288034101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d41200441017422052003200520034b1b22054100480d410240024020040d002005102121030c010b200228020020042005102521030b2003450d302002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a000020004190036a2002107120022000418c036a280200220536020c2002410c6a21060c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d40200441017422052003200520034b1b22054100480d400240024020040d002005102121030c010b200228020020042005102521030b2003450d302002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a00002002200028028c03220536020c2002410c6a21060b0240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d30200220043602042002200336020020062802002105200228020821040b2002200441046a360208200320046a2005360000200041b8036a290300210720002903b00321080240024020022802042203200228020822046b4110490d00200228020021030c010b200441106a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d312002200436020420022003360200200228020821040b200320046a22032007370008200320083700002002200441106a22043602080c010b0240024020032004460d00200228020021030c010b200441016a22032004490d3e200441017422052003200520034b1b22054100480d3e0240024020040d002005102121030c010b200228020020042005102521030b2003450d312002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200228020821040b200228020421030240024020002802c0034102460d000240024020032004460d00200228020021030c010b200441016a22032004490d3f200441017422052003200520034b1b22054100480d3f0240024020040d002005102121030c010b200228020020042005102521030b2003450d332002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a00000240024020002802c0034101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d41200441017422052003200520034b1b22054100480d410240024020040d002005102121030c010b200228020020042005102521030b2003450d362002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200041c8036a200210712002200041c4036a280200220536020c2002410c6a21060c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d40200441017422052003200520034b1b22054100480d400240024020040d002005102121030c010b200228020020042005102521030b2003450d362002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a0000200220002802c403220536020c2002410c6a21060b0240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d36200220043602042002200336020020062802002105200228020821040b2002200441046a360208200320046a2005360000200041f0036a290300210720002903e80321080240024020022802042203200228020822046b4110490d00200228020021030c010b200441106a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d372002200436020420022003360200200228020821040b200320046a22032007370008200320083700002002200441106a22043602080c010b0240024020032004460d00200228020021030c010b200441016a22032004490d3e200441017422052003200520034b1b22054100480d3e0240024020040d002005102121030c010b200228020020042005102521030b2003450d372002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a0000200228020821040b200228020421030240024020002802f8034102460d000240024020032004460d00200228020021030c010b200441016a22032004490d3f200441017422052003200520034b1b22054100480d3f0240024020040d002005102121030c010b200228020020042005102521030b2003450d392002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a00000240024020002802f8034101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d41200441017422052003200520034b1b22054100480d410240024020040d002005102121030c010b200228020020042005102521030b2003450d3c2002200536020420022003360200200228020821040b2002200441016a360208200320046a41003a000020004180046a200210712002200041fc036a280200220536020c2002410c6a21060c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d40200441017422052003200520034b1b22054100480d400240024020040d002005102121030c010b200228020020042005102521030b2003450d3c2002200536020420022003360200200228020821040b2002200441016a360208200320046a41013a0000200220002802fc03220536020c2002410c6a21060b0240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d3f200341017422042005200420054b1b22044100480d3f0240024020030d002004102121030c010b200228020020032004102521030b2003450d3c200220043602042002200336020020062802002105200228020821040b2002200441046a360208200320046a2005360000200041a8046a290300210720002903a00421080240024020022802042204200228020822036b4110490d00200228020021000c010b200341106a22002003490d3f200441017422032000200320004b1b22054100480d3f0240024020040d002005102121000c010b200228020020042005102521000b2000450d3d200220053602042002200036020020022802082103200521040b200020036a22052007370008200520083700002002200341106a22033602080c010b0240024020032004460d00200228020021000c010b200441016a22002004490d3e200441017422032000200320004b1b22034100480d3e0240024020040d002003102121000c010b200228020020042003102521000b2000450d3d2002200336020420022000360200200228020821040b2002200441016a360208200020046a41003a00002002280208210320022802042104200228020021000b20012902002003ad4220862000ad84100220040d3d0c3e0b410141011030000b410141011030000b200541011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200441011030000b200541011030000b200341011030000b102a000b200010230b200241106a24000be71207027f017e057f027e017f017e0a7f230041b0036b2202240020002802102203200328020041016a36020020002902142104200028020c2103200028020821052000280200210620002802042100200241f0016a41086a2207200141086a280200360200200220012902003703f001024002400240024020002f01062201410b490d00200241d0026a410272410041da0010db041a200241386a410041840110db041a0240024041e40110212208450d0020084100360200200841046a200241d0026a41dc0010dc041a200841e0006a200241386a41840110dc042107200241386a41086a2209200041b0016a280200360200200220002902a8013703382000413c6a330000210a2000413e6a310000210b20002d003f210c2000350038210d200841086a200041c0006a20002f010641796a220141037410dc04210e2007200041b4016a2001410c6c10dc042107200041063b0106200820013b0106200241d0026a41086a2009280200360200200220022903383703d002200d200a200b4210868442208684210a0240024020034107490d002003410374200e6a41506a200e200341796a22094103746a220e200141ffff037120096b41037410dd041a200e20043700002003410c6c20076a220341b87f6a200341ac7f6a2203200841066a22012f010020096b410c6c10dd041a200341086a200241f0016a41086a280200360200200320022903f0013702000c010b200041086a20034103746a220741086a2007200041066a22012f010020036b41037410dd041a20072004370000200041e0006a2003410c6c6a2207410c6a200720012f010020036b410c6c10dd041a200741086a200241f0016a41086a280200360200200720022903f0013702000b200120012f010041016a3b0100200241286a41086a220f200241d0026a41086a22102802002203360200200241086a221120033602002002200c3a0017200220022903d00222043703282002200a3e02102002200a4230883c00162002200a4220883d011420022004370300200229031021042000280200220c450d0320002f01042112200241d0026a410272211303402002200641016a22063602202002200c360224200f201128020036020020022002290300370328201241ffff03712109024002400240200c2f01062200410b490d002013410041da0010db041a200241f0016a200241d0026a41dc0010dc041a200241386a410041b40110db041a41940210212207450d0520074100360200200741046a200241f0016a41dc0010dc041a200741e0006a200241386a41b40110dc042103200c41386a290000210a200241386a41086a2214200c41b0016a2802003602002002200c41a8016a290200370338200741086a200c41c0006a200c2f0106220141796a220041037410dc0421152003200c41b4016a2000410c6c10dc042116200741e4016a200c4180026a2001417a6a220e41027410dc042117200c41063b0106200720003b01060240200e450d00410021002017210303402003280200220120003b010420012007360200200341046a2103200e200041016a2200470d000b0b20102014280200220036020020022002290338220b3703d002201420003602002002200b370338201241ffff037122034107490d0120152009417a6a22034103746a2015200941796a22004103746a220120072f010620006b41037410dd041a200120043700002009410c6c20166a220141b87f6a200141ac7f6a220120072f0106220e20006b410c6c10dd041a200141086a200f280200360200200120022903283702002007200e41016a22013b01062009410274221220176a416c6a201720034102746a220e200141ffff0371220920036b41027410dd041a200e200836020020092003490d02200720126a41cc016a2103034020032802002201200041016a22003b010420012007360200200341046a210320002009490d000c030b0b200c41086a2201200941016a22034103746a200120094103746a2201200020096b220741037410dd041a20012004370000200c2009410c6c6a220141ec006a200141e0006a220e2007410c6c10dd041a200141e8006a200241286a41086a280200360200200e2002290328370200200c200041016a22003b01062009410274200c41e4016a22016a41086a200120034102746a2201200041ffff0371220720036b41027410dd041a20012008360200201241ffff037120074f0d07200c2003417f6a22004102746a41e8016a2103034020032802002201200041016a22003b01042001200c360200200341046a210320002007490d000c080b0b200c41086a2200200941016a220e4103746a200020094103746a2200200c2f0106220120096b221241037410dd041a20002004370000200c41e0006a2009410c6c6a2200410c6a20002012410c6c10dd041a200041086a200f28020036020020002002290328370200200c200141016a22003b010620094102742217200c41e4016a22016a41086a2001200e4102746a2212200041ffff03712201200e6b41027410dd041a20122008360200200320014f0d00200c20176a41e8016a2100034020002802002203200941016a22093b01042003200c360200200041046a210020012009470d000b0b200241106a41086a2014280200220036020020112000360200200220022903382204370310200220043703000240200c28020022000d0020072108200a21040c050b200c2f010421122000210c200a2104200721080c000b0b41e40141041030000b41940241041030000b200020034103746a220941106a200941086a2209200120036b41037410dd041a2009200437000020002003410c6c6a220141ec006a200141e0006a220920002f010620036b410c6c10dd041a200141e8006a2007280200360200200920022903f001370200200020002f010641016a3b01060c010b200241d0026a410272410041da0010db041a200241f0016a200241d0026a41dc0010dc041a200241386a410041b40110db041a41940210212200450d0120004100360200200041046a200241f0016a41dc0010dc041a200041e0006a200241386a41b40110dc0421012000200528020022033602e401200520003602002005200528020441016a360204200341003b010420032000360200200120002f01062203410c6c6a22012002290300370200200020034103746a41086a2004370000200141086a200241086a280200360200200041e4016a200341016a22034102746a2008360200200020033b0106200820033b0104200820003602000b200241b0036a24000f0b41940241041030000bea0601037f200141046a2802002102200141086a2802002103024002400240024002400240024020002802204102470d000240024020022003460d00200128020021000c010b200341016a22002003490d07200341017422022000200220004b1b22024100480d070240024020030d002002102121000c010b200128020020032002102521000b2000450d0220012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000f0b0240024020022003460d00200128020021020c010b200341016a22022003490d06200341017422042002200420024b1b22044100480d060240024020030d002004102121020c010b200128020020032004102521020b2002450d0220012002360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200220036a41013a0000200020011071024020002802204101460d0002400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d07200341017422022000200220004b1b22024100480d070240024020030d002002102121000c010b200128020020032002102521000b2000450d0420012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000f0b02400240200141046a28020020042802002203460d00200128020021020c010b200341016a22022003490d06200341017422042002200420024b1b22044100480d060240024020030d002004102121020c010b200128020020032004102521020b2002450d0420012002360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200220036a41013a00002000280224210202400240200141046a2802002200200428020022036b4104490d00200128020021000c010b200341046a22042003490d06200041017422032004200320044b1b22034100480d060240024020000d002003102121000c010b200128020020002003102521000b2000450d0520012000360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200020036a20023600000f0b200241011030000b200441011030000b200241011030000b200441011030000b200341011030000b102a000bab0101037f230041d0006b220124002001200010b6010240200141c0006a2802002202450d00034002402001280244450d00200210230b2001200010b601200128024022020d000b0b02402000280204220241d8a7c300460d0020022802002103200210232003450d0020032802002100200310232000450d00024020002802002202450d000340200010232002210020022802002203210220030d000b0b200010230b200141d0006a24000bf40506057f017e017f017e067f017e230041b0036b22012400200141d8016a41186a22024200370300200141d8016a41106a22034200370300200141d8016a41086a22044200370300200142003703d801200141a0036a41086a220541aefcc400ad428080808090018422061003220741086a290000370300200120072900003703a0032007102320042005290300370300200120012903a003220837039003200120083703d801200541a8f5c000ad4280808080c001841003220741086a290000370300200120072900003703a00320071023200320012903a0032208370300200141b8016a41086a22072004290300370300200141b8016a41106a22092008370300200141b8016a41186a220a20052903003703002001200837039003200120012903d8013703b801200141d8016a200141b8016a10d6010240024020012802d801220b411a470d0041b4f5c00021050c010b200141b8016aad4280808080800484220810052001410c6a200141d8016a410472220c41ac0110dc041a20014188036a2d0000210d200242003703002003420037030020044200370300200142003703d801200520061003220e41086a2900003703002001200e2900003703a003200e102320042005290300370300200120012903a003220637039003200120063703d801200541e8a1c100ad4280808080d002841003220e41086a2900003703002001200e2900003703a003200e102320014190036a41086a20052903002206370300200120012903a003220f370390032003200f370000200341086a20063700002007200429030037030020092003290300370300200a2002290300370300200120012903d8013703b801200141013a00d8012008200141d8016aad428080808010841002200441023a0000200141083a00d801200141d8016a108e012001200b3602d801200c2001410c6a41ac0110dc041a200141b8016a200041c093066a200141d8016a200d4180840710d7014100210520012802b8014101470d0020012802bc0121050b200141b0036a240020050baa0401057f230041c0046b220224002002412036020420022001360200200241086a2001ad4280808080800484100410900102400240200228020822010d002000411a3602000c010b200228020c21032002200241106a2802003602d401200220013602d00120024190036a200241d0016a10d90102400240200228029003411a460d00200241e0016a20024190036a41b00110dc041a0240024020022802d4012204450d0020022802d00122052d0000210620022004417f6a3602d4012002200541016a3602d00120064103490d010b200241e0016a10da010c010b20022802e0012104200241206a200241e0016a41047241ac0110dc041a200220022800d8013602182002200241d8016a41036a28000036001b2004411a460d0020024190036a200241206a41ac0110dc041a2002200228001b3600e301200220022802183602e001200041046a20024190036a41ac0110dc041a200041b0016a20063a0000200020022802e0013600b101200041b4016a20022800e3013600000c010b200241003602e801200242013703e0012002410c360224200220023602202002200241e0016a3602d801200241a4036a4101360200200242013702940320024198c2c300360290032002200241206a3602a003200241d8016a41b8a3c50020024190036a102e1a20023502e80142208620023502e001841008024020022802e401450d0020022802e00110230b411a21040b200020043602002003450d00200110230b200241c0046a24000b8a0e04057f017e037f027e230041d0036b22052400200541c8016a41186a4200370300200541c8016a41106a22064200370300200541c8016a41086a22074200370300200542003703c801200541086a41086a220841aefcc400ad42808080809001841003220941086a29000037030020052009290000370308200910232007200829030037030020052005290308220a3703e8012005200a3703c801200841ec9ec100ad4280808080f001841003220941086a290000370300200520092900003703082009102320062005290308220a37030020054188026a41086a200729030037030020054188026a41106a200a37030020054188026a41186a20082903003703002005200a3703f801200520052903c80137038802200520054188026a4120108f010240024002402005280204410020052802001b2207417f6a220820074d0d002005411a3602080c010b200541086a200810e5012005280208411a460d0020054188026a200541086a41c00110dc041a20052802b803210820054188026a10db01200820014d0d0020004194f4c00036020420004101360200200041086a41c700360200200210db010c010b200541c8016a41186a220b4200370300200541c8016a41106a220c4200370300200541c8016a41086a22094200370300200542003703c801200541086a41086a220841aefcc400ad4280808080900184220a1003220d41086a2900003703002005200d290000370308200d10232009200829030037030020052005290308220e3703e8012005200e3703c801200841ec9ec100ad4280808080f001841003220d41086a2900003703002005200d290000370308200d1023200541f8016a41086a220d2008290300220e37030020052005290308220f3703f8012006200f370000200641086a200e37000020054188026a41086a200929030037030020054188026a41106a200c29030037030020054188026a41186a200b290300370300200520052903c801370388022005200741016a36020820054188026aad4280808080800484200541086aad4280808080c00084100220054188026a200241b00110dc041a200520033a00c003200520043602bc03200520013602b8032008200a1003220641086a2900003703002005200629000037030820061023200541e8016a41086a22012008290300370300200520052903083703e801200841bcf3c000ad42808080808002841003220641086a2900003703002005200629000037030820061023200d2008290300370300200520052903083703f801200520073602cc03200541086a41186a2202200541cc036aad4280808080c000841001220641186a290000370300200541086a41106a2204200641106a2900003703002008200641086a2900003703002005200629000037030820061023200b2002290300370300200c200429030037030020092008290300370300200520052903083703c8010240024002400240024041c00010212208450d00200820052903e801370000200820052903f801370010200820052903c801370020200841086a2001290300370000200841186a200d290300370000200841386a200b290300370000200841306a200c290300370000200841286a2009290300370000200541003602102005420137030820052802b8032106410410212209450d012005410436020c20052005280210220b41046a360210200520093602082009200b6a200636000020054188026a200541086a10cb01024020052d00c003220941024b0d00024002400240024020090e03000102000b410021060c020b410121060c010b410221060b200520063a00c80102400240200528020c20052802102209460d002005280208210b0c010b200941016a220b2009490d062009410174220c200b200c200b4b1b220c4100480d060240024020090d00200c1021210b0c010b20052802082009200c1025210b0b200b450d042005200c36020c2005200b360208200528021021090b2005200941016a360210200b20096a20063a00000b20052802bc03210b02400240200528020c2206200528021022096b4104490d00200528020821060c010b200941046a220c2009490d0520064101742209200c2009200c4b1b22094100480d050240024020060d002009102121060c010b200528020820062009102521060b2006450d042005200936020c20052006360208200528021021090b2005200941046a360210200620096a200b360000200528020c21092008ad4280808080800884200535021042208620052802082206ad84100202402009450d00200610230b2008102320054188026a10db0120054194026a200736020020054191026a20033a0000200541083a00880220054188026a41086a41033a000020054188026a108e0120004100360200200020073602040c050b41c00041011030000b410441011030000b200c41011030000b200941011030000b102a000b200541d0036a24000ba72304057f027e0d7f1b7e230041c0076b22012400200141c8056a41186a4200370300200141c8056a41106a22024200370300200141c8056a41086a22034200370300200142003703c805200141e8026a41086a220441aefcc400ad42808080809001841003220541086a290000370300200120052900003703e8022005102320032004290300370300200120012903e802220637039807200120063703c805200441d5f3c000ad4280808080b001841003220541086a290000370300200120052900003703e80220051023200220012903e8022206370300200141286a41086a2003290300370300200141286a41106a2006370300200141286a41186a20042903003703002001200637039801200120012903c8053703282001412036024c2001200141286a360248200141d0006a200141286aad42808080808004842207100410900102400240024002400240024002400240200128025022080d00410021090c010b2001280254210a2001200141d0006a41086a28020036027420012008360270200141206a200141f0006a106e02400240024020012802200d00200128027441d8016e220b41d8016c2204417f4c0d042001280224210c0240024020040d00410821090c010b200410212209450d060b0240200c450d0020014198046a410472210d4100210e4100210f0340024002400240200128027422044104490d0020012802702203280000211020012004417c6a3602742001200341046a360270200141c8056a200141f0006a10d90120012802c805411a460d00200f41016a211120014198046a200141c8056a41b00110dc041a41002103200141003a00b8072001280274417f6a2104024003402004417f460d0120014198076a20036a200128027022052d00003a00002001200541016a3602702001200341016a22053a00b807200120043602742004417f6a21042005210320054120470d000b200141f8066a41186a220420014198076a41186a290300370300200141f8066a41106a220520014198076a41106a290300370300200141f8066a41086a221220014198076a41086a29030037030020012001290398073703f8062001280298042103200141e8026a200d41ac0110dc041a200141c8026a41086a22132012290300370300200141c8026a41106a22122005290300370300200141c8026a41186a22052004290300370300200120012903f8063703c8022003411a460d0120014198016a200141e8026a41ac0110dc041a200141f8006a41186a22142005290300370300200141f8006a41106a22052012290300370300200141f8006a41086a22122013290300370300200120012903c802370378200b200f470d03200f41017422042011200420114b1b220bad42d8017e2206422088a70d0f2006a7220441004e0d020c0f0b0240200341ff0171450d00200141003a00b8070b20014198046a10da010b200141003602600240200f450d00200921040340200410db01200441d8016a2104200e41a87e6a220e0d000b0b200b450d05200910230c050b02400240200f0d002004102121090c010b2009200f41d8016c2004102521090b2009450d090b2009200f41d8016c6a22042003360200200441046a20014198016a41ac0110dc041a200420103602b001200420012903783702b401200441bc016a2012290300370200200441c4016a2005290300370200200441cc016a2014290300370200200e41d8016a210e2011210f2011200c470d000b0b200141e8006a200c3602002001200b360264200120093602602009450d01200129026421060c020b200141003602600b41002109200141003602a00420014201370398042001410c3602ec022001200141c8006a3602e802200120014198046a36029801200141dc056a4101360200200142013702cc0520014198c2c3003602c8052001200141e8026a3602d80520014198016a41b8a3c500200141c8056a102e1a20013502a0044220862001350298048410080240200128029c04450d0020012802980410230b0b200a450d00200810230b2009410820091b210a02402006420020091b2215422088a7220f450d00200a200f41d8016c6a2108200141c8056a200a2802b00110dc01200a41d8016a21040240024020012802d80522030d0042002116420021060c010b200141106a20012903c805200141c8056a41086a290300200141e0056a350200420010e104200141106a41086a29030021062001290310211620012802dc05450d00200310230b024020042008470d004100210e0c050b4100210e200a2109410121050340200141c8056a200441b0016a28020010dc010240024020012802d80522030d0042002117420021180c010b200120012903c805200141c8056a41086a29030020013502e005420010e104200141086a29030021182001290300211720012802dc05450d00200310230b200620182016201756200620185620062018511b22031b21062016201720031b21162009200420031b2109200e200520031b210e200541016a2105200441d8016a22042008470d000b20090d04200f41d8016c2103200a21040340200410db01200441d8016a2104200341a87e6a22030d000b0b41f9f3c00021042015a7450d04200a10230c040b102f000b200441081030000b200441081030000b024002400240200e200f4f0d00200a200f417f6a220c41d8016c6a220441a0016a2903002116200441a8016a2903002117200441b0016a2903002119200441b8016a290300211a20044180016a290300211b20044188016a290300211c20044190016a290300211d20044198016a290300211e200441e0006a290300211f200441e8006a2903002120200441f0006a2903002121200441f8006a2903002122200441c0006a2903002123200441c8006a2903002124200441d0006a2903002125200441d8006a2903002126200441206a2903002127200441286a2903002128200441306a2903002129200441386a290300212a2004290300212b2004290308212c2004290310212d200441186a290300212e200441c0016a2903002106200441c8016a2903002118200141c8056a41106a2203200441d0016a290300370300200141c8056a41086a22052018370300200a200e41d8016c6a220441186a220e290300212f200e202e3703002004290310212e2004202d3703102004290308212d2004202c3703082004290300212c2004202b370300200441386a220e290200212b200e202a370200200441306a220e290200212a200e2029370200200441286a220e2902002129200e2028370200200441206a220e2902002128200e2027370200200441d8006a220e2902002127200e2026370200200441d0006a220e2902002126200e2025370200200441c8006a220e2902002125200e2024370200200441c0006a220e2902002124200e2023370200200441f8006a220e2902002123200e2022370200200441f0006a220e2902002122200e2021370200200441e8006a220e2902002121200e2020370200200441e0006a220e2902002120200e201f37020020044198016a220e290200211f200e201e37020020044190016a220e290200211e200e201d37020020044188016a220e290200211d200e201c37020020044180016a220e290200211c200e201b370200200441b8016a201a370200200441b0016a220e280200210b200e2019370200200441a8016a220e2902002119200e2017370200200441a0016a220e2902002117200e2016370200200120063703c805200441c0016a2006370200200441c8016a2018370200200441d0016a200329030037020020014198046a41a8016a201937030020014198046a41a0016a201737030020014198046a4198016a201f37030020014198046a4190016a201e37030020014198046a4188016a201d37030020014198046a4180016a201c37030020014198046a41f8006a202337030020014198046a41f0006a202237030020014198046a41e8006a202137030020014198046a41e0006a202037030020014198046a41d8006a202737030020014198046a41d0006a202637030020014198046a41c8006a202537030020014198046a41c0006a202437030020014198046a41386a202b37030020014198046a41306a202a37030020014198046a41286a202937030020014198046a41206a202837030020014198046a41186a202f3703002001202e3703a8042001202d3703a0042001202c37039804200141c8056a41186a220942003703002003420037030020054200370300200142003703c805200141e8026a41086a220441aefcc400ad42808080809001841003220e41086a2900003703002001200e2900003703e802200e102320052004290300370300200120012903e802220637039807200120063703c805200441d5f3c000ad4280808080b001841003220e41086a2900003703002001200e2900003703e802200e102320014198016a41086a20042903002206370300200120012903e80222183703980120022018370000200241086a2006370000200141286a41086a2005290300370300200141286a41106a2003290300370300200141286a41186a2009290300370300200120012903c805370328200141003602d005200142013703c805200c200141c8056a105c0240200c450d00200f41d8016c41a87e6a210e200a21040340200441b0016a28020021090240024020012802cc05220520012802d00522036b4104490d0020012802c80521050c010b200341046a22082003490d07200541017422032008200320084b1b22034100480d070240024020050d002003102121050c010b20012802c80520052003102521050b2005450d04200120033602cc05200120053602c80520012802d00521030b2001200341046a3602d005200520036a20093600002004200141c8056a10cb01200441b4016a200141c8056a1071200441d8016a2104200e41a87e6a220e0d000b0b20012802cc052104200720013502d00542208620012802c8052203ad84100202402004450d00200310230b0240200c450d00200f41d8016c41a87e6a2103200a21040340200410db01200441d8016a2104200341a87e6a22030d000b0b02402015a7450d00200a10230b200141e8026a41086a220441aefcc400ad42808080809001841003220341086a290000370300200120032900003703e8022003102320014198076a41086a22052004290300370300200120012903e80237039807200441f0f3c000ad42808080809001841003220341086a290000370300200120032900003703e8022003102320014198016a41086a22032004290300370300200120012903e802370398012001200b3602e802200141f8066a41186a220e200141e8026aad4280808080c000841001220441186a290000370300200141f8066a41106a2209200441106a290000370300200141f8066a41086a2208200441086a290000370300200120042900003703f80620041023200141c8056a41186a220a200e290300370300200141c8056a41106a220e2009290300370300200141c8056a41086a22092008290300370300200120012903f8063703c80541c00010212204450d0220042001290398073700002004200129039801370010200420012903c805370020200441086a2005290300370000200441186a2003290300370000200441286a2009290300370000200441306a200e290300370000200441386a200a290300370000200141c8056a200441c00010dd01024020012802d8052205450d002004ad428080808080088410050b200141d0056a2903002106200141e0056a280200210e20012903c805211820012802dc05210920041023024002402005450d000240200e4105742203450d0020052104034020042018200610de01200441206a2104200341606a22030d000b0b200141f0056a2006370300200141e8056a2018370300200141e0056a200e360200200141dc056a2009360200200141d8056a2005360200200141d4056a200b360200200141083a00c805200141c8056a41086a41013a0000200141c8056a108e01200141c8056a20014198046a41b00110dc041a200141e8026a200041c093066a200141c8056a41004180840710d70120012802e8024101470d0120012802ec0221040c050b20014198046a10db010b410021040c030b41e0f3c000200e200f102d000b200341011030000b41c00041011030000b200141c0076a240020040f0b102a000bd9ae0108087f017e067f067e037f037e017f017e230041f00b6b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541194b0d1b200141046a210720050e1a0102030405060708090a0b0c0d0e0f101112131415161718191a010b2000411a3602000c670b2006450d6320042d0001210620012003417e6a22083602042001200441026a360200200641064b0d634101210902400240024002400240024020060e076b0001020304056b0b20022001106e20022802000d68200128020420022802042204490d682004417f4c0d2802400240024020040d00410121050c010b200410272205450d0120072802002004490d6920052001280200200410dc041a200128020422032004490d2b2001200320046b3602042001200128020020046a3602000b2005450d692004ad220a422086200a84210a410221090c6b0b200441011030000b20084108490d672004290002210a2001200341766a36020420012004410a6a360200410321090c690b200241086a2001106e20022802080d662001280204200228020c2204490d662004417f4c0d2602400240024020040d00410121050c010b200410272205450d0120072802002004490d6720052001280200200410dc041a200128020422032004490d2a2001200320046b3602042001200128020020046a3602000b2005450d672004ad220a422086200a84210a410421090c690b200441011030000b200241206a2001106e20022802200d65200728020041186e220b41186c2204417f4c0d252002280224210c0240024020040d00410421050c010b200410212205450d290b0240200c450d004100210d41002106410021090340200241186a2001106e02400240024020022802180d002001280204200228021c2203490d002003417f4c0d2a02400240024020030d004101210e0c010b20031027220e450d4920072802002003490d01200e2001280200200310dc041a200128020422042003490d302001200420036b3602042001200128020020036a3602000b200241106a2001106e024020022802100d00200128020420022802142204490d002004417f4c0d2c024002400240024020040d004101210f0c010b20041027220f450d0120072802002004490d02200f2001280200200410dc041a200128020422082004490d342001200820046b3602042001200128020020046a3602000b200941016a21082009200b470d06200d2008200d20084b1b220bad42187e220a422088a70d6f200aa7221041004e0d050c6f0b200441011030000b200f10230b2003450d010b200e10230b02402009450d002005210103400240200141046a280200450d00200128020010230b0240200141106a280200450d002001410c6a28020010230b200141186a2101200641686a22060d000b0b200b450d690c680b0240024020090d002010102121050c010b200520062010102521050b2005450d2e0b200520066a2209200e360200200941146a2004360200200941106a20043602002009410c6a200f360200200941046a2003ad220a422086200a84370200200d41026a210d200641186a210620082109200c2008470d000b0b2005450d65200cad422086200bad84210a410521090c670b200241306a2001106e20022802300d642007280200410c6e220e410c6c2204417f4c0d242002280234210f0240024020040d00410421050c010b200410212205450d2c0b024002400240200f450d004100210841002103410021090340200241286a2001106e20022802280d032001280204200228022c2204490d032004417f4c0d280240024020040d004101210d0c010b20041027220d450d4720072802002004490d03200d2001280200200410dc041a200128020422062004490d312001200620046b3602042001200128020020046a3602000b200941016a210602402009200e470d0020082006200820064b1b220ead420c7e220a422088a70d6a200aa7220b4100480d6a0240024020090d00200b102121050c010b20052003200b102521050b2005450d320b200520036a2209200d360200200941086a2004360200200941046a2004360200200841026a21082003410c6a210320062109200f2006470d000b0b2005450d66200fad422086200ead84210a410621090c680b200d10230b02402009450d002005210103400240200141046a280200450d00200128020010230b2001410c6a2101200341746a22030d000b0b200e0d630c640b200241386a2001106e20022802380d632001280204200228023c2204490d632004417f4c0d2302400240024020040d00410121050c010b200410272205450d0120072802002004490d6420052001280200200410dc041a200128020422032004490d2f2001200320046b3602042001200128020020046a3602000b2005450d642004ad220a422086200a84210a410721090c660b200441011030000b02402006450d0020012003417e6a3602042001200441026a3602000b2000411a3602000c650b2006450d5f20042d0001210520012003417e6a22063602042001200441026a36020020050d5f2006450d5f20042d0002210520012003417d6a22073602042001200441036a360200024002400240200541037122064103460d000240024020060e03030001030b2007450d6320042d0003210620012003417c6a3602042001200441046a3602002006410874200572220141ffff0371418002490d63200141fcff0371410276ad210a0c030b20074103490d62200441056a2d0000210620042f0003210720012003417a6a3602042001200441066a3602002007200641107472410874200572220141808004490d622001410276ad210a0c020b02402005410276220941044b0d000240024020090e050002020201000b20074104490d63200428000321052001200341796a3602042001200441076a3602002005418080808004490d632005ad210a0c030b20074108490d622004290003210a2001200341756a36020420012004410b6a360200200a42ffffffffffffffff00560d020c620b200941046a220641084b0d612003417c6a2103200441046a2104410021054200210a03402003417f460d622004417f6a310000211120012003360204200120043602002003417f6a2103200441016a210420112005410374413871ad86200a84210a200541016a220541ff01712006490d000b200a427f412820094103746b413871ad88580d610c010b2005410276ad210a0b20004102360200200041086a200a370300200041106a200241c00a6a41a00110dc041a0c640b02402006450d0020012003417e6a3602042001200441026a3602000b2000411a3602000c630b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541034b0d00024002400240024020050e0400010203000b20024190096a200110d80220022d0090094102460d03200241f0066a41086a22032002419c096a290200370300200241f0066a41106a2205200241a4096a290200370300200241f0066a41186a2206200241ac096a29020037030020022002290294093703f0062002280290092104200241c0006a200110eb022002290340a70d03200241c0006a41106a290300210a20022903482111200241b8086a41186a2006290300370300200241b8086a41106a2005290300370300200241b8086a41086a2003290300370300200220022903f0063703b808410121010c600b20024190096a200110d80220022d0090094102460d02200241f8066a2002419c096a290200370300200241f0066a41106a200241a4096a29020037030020024188076a200241ac096a29020037030020022002290294093703f0062002280290092104200241f0006a200110eb022002290370a70d02200241f0006a41106a290300210a20022903782111200241d8006a200110eb022002290358a70d02200241d8006a41106a290300211220022903602113200241b8086a41186a200241f0066a41186a290300370300200241b8086a41106a200241f0066a41106a290300370300200241b8086a41086a200241f0066a41086a290300370300200220022903f0063703b808410221010c5f0b20024190096a200110d80220022d0090094102460d01200241d0056a41086a2002419c096a290200370300200241d0056a41106a200241a4096a290200370300200241d0056a41186a200241ac096a29020037030020022002290294093703d005200228029009210420024190096a200110d80220022d0090094102460d01200241f0066a41206a220320024190096a41206a280200360200200241f0066a41186a20024190096a41186a290300370300200241f0066a41106a20024190096a41106a290300370300200241f0066a41086a20024190096a41086a29030037030020022002290390093703f00620024188016a200110eb02200229038801a70d0120024188016a41106a29030021142002290390012115200241d8086a41186a200241d0056a41186a290300220a370300200241d8086a41106a200241d0056a41106a2903002211370300200241b8086a41086a200241d0056a41086a290300370300200241b8086a41106a2011370300200241b8086a41186a200a370300200220022903d0053703b808200241f0066a41086a290300210a200241f0066a41186a2903002112200241f0066a41106a29030021132003350200211620022903f0062111410321010c5e0b20024190096a200110d80220022d0090094102460d00200241f0066a41086a22032002419c096a290200370300200241f0066a41106a2205200241a4096a290200370300200241f0066a41186a2206200241ac096a29020037030020022002290294093703f0062002280290092104200241a0016a200110eb0220022903a001a70d00200241a0016a41106a290300210a20022903a8012111200241b8086a41086a2003290300370300200241b8086a41106a2005290300370300200241b8086a41186a2006290300370300200220022903f0063703b808410421010c5d0b2000411a3602000c620b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241b8016a2001106e20022802b8010d00200728020041f0006e220941f0006c2204417f4c0d1f20022802bc0121080240024020040d00410421070c010b200410212207450d2b0b024002402008450d00410021064100210541002103034020024190096a2001108801200228029409450d02200341016a2104200241f0066a20024190096a41f00010dc041a024020032009470d0020062004200620044b1b2209ad42f0007e220a422088a70d64200aa7220d4100480d640240024020030d00200d102121070c010b20072005200d102521070b2007450d2f0b200720056a200241f0066a41f00010dc041a200641026a2106200541f0006a21052004210320082004470d000b0b2007450d012000200736020420004105360200200041086a2008ad4220862009ad84370200200041106a200241c00a6a41a00110dc041a0c630b02402003450d00200720056a210620072105034002402005410c6a2802002204450d0020052802042101200441246c210403400240024020012d0000220341034b0d0002400240024020030e0404000102040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012004415c6a22040d000b0b200541f0006a21010240200541086a280200450d00200528020410230b2001210520062001470d000b0b2009450d00200710230b2000411a3602000c610b2006450d5920042d0001210520012003417e6a220b3602042001200441026a3602002005410f4b0d594104210d02400240024002400240024002400240024002400240024002400240024002400240024020050e1000010211030405060708090a0b0d0e0f000b20024190096a200110d80220022d0090094102460d6a2002419c096a2902002116200241ac096a2902002115200241a4096a290200211420022902940921112002280290092106200241c0016a200110eb0220022903c001a70d6a20072802002204450d6a200241d0016a290300211220022903c8012113200128020022032d0000210820012004417f6a3602044101210d2001200341016a360200200841024b0d6a2013423888201242088684210a2013421888a7210e2012423888a7210f2013a721090c100b200241d8016a200110eb0220022903d801a70d69200241e8016a290300211620022903e00121114102210d4200210a0c0e0b200241f0016a200110eb0220022903f001a70d6820024180026a290300211620022903f80121114103210d4100210e4200210a4100210f0c0d0b20024188026a2001106e2002280288020d67200228028c0221064105210d4100210e4200210a4100210f0c0c0b20024190026a2001106e2002280290020d66200728020041246e221041246c2204417f4c0d2a20022802940221170240024020040d00410421060c010b200410212206450d380b02402017450d0020024190096a4101722103410021094100210741002104034020024190096a200110d802200241f0066a41086a2208200341086a290000370300200241f0066a41106a220d200341106a290000370300200241f0066a41186a220e200341186a290000370300200241f0066a411f6a220f2003411f6a280000360000200220032900003703f006024020022d009009220b4102470d002010450d69200610230c690b200441016a2105200241d0056a411f6a220c200f280000360000200241d0056a41186a220f200e290300370300200241d0056a41106a220e200d290300370300200241d0056a41086a220d2008290300370300200220022903f0063703d005024020042010470d0020092005200920054b1b2210ad42247e220a422088a70d6e200aa722084100480d6e0240024020040d002008102121060c010b200620072008102521060b2006450d3b0b200620076a2204200b3a0000200441016a20022903d005370000200441096a200d290300370000200441116a200e290300370000200441196a200f290300370000200441206a200c280000360000200941026a2109200741246a21072005210420172005470d000b0b2006450d662017ad4220862010ad8421114200210a4106210d0c070b4107210d0c0a0b200b450d6420042d0002210820012003417d6a3602042001200441036a360200200841034f0d644108210d4100210e4200210a4100210f0c0a0b20024190096a200110d80220022d0090094102460d632002419c096a2902002116200241ac096a2902002115200241a4096a2902002114200229029409211120022802900921064109210d410021094200210a4100210e4100210f0c080b20024198026a2001106e2002280298020d62200228029c022106410a210d410021094200210a4100210e4100210f0c070b410b210d0c060b410c210d0c050b20024190096a2001107e2002280290092206450d5f20022902940921114200210a410d210d0b4100210e4100210f420021160c030b41002105200241003a00b0092003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d5f200241003a00b0090c5f0b20024190096a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00b0092003417f6a21032006210520064120470d000b200241e8056a2201200241af096a2d00003a00002002419f096a2900002116200241a7096a2900002114200228009309210620022f009109210920022d0090092108200229009709211120013100002115410e210d4100210e4200210a4100210f0c030b410f210d0c010b200b4104490d5b2004280002210620012003417a6a3602042001200441066a36020020024190096a2001107b200228029009450d5b20024198096a350200211620022903900921114110210d410021094200210a4100210e4100210f0b0b200020093b010a200020083a000920004106360200200041186a2016370200200041106a2011370200200041286a2015370200200041206a20143702002000410c6a2006360200200041086a200d3a0000200041386a200fad423886200a42088884370200200041306a200a423886200ead421886842009ad42ffffff078384370200200041c0006a200241c00a6a41f00010dc041a0c600b02402006450d0020012003417e6a3602042001200441026a3602000b2000411a3602000c5f0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241c00a6a200110ce0220022d00c00a4101460d0020024190096a200241c00a6a41017241a00110dc041a200241a0026a2001106e20022802a0020d00200128020420022802a4022204490d002004417f4c0d1c024002400240024020040d004101210341010d010c040b200410272203450d0120072802002004490d0220032001280200200410dc042105200128020422062004490d2e2001200620046b3602042001200128020020046a3602002005450d030b200241f0066a20024190096a41a00110dc041a200241d0056a200241f0066a41a00110dc041a2000410c6a2004360200200041086a20043602002000200336020420004108360200200041106a200241d0056a41a00110dc041a0c610b200441011030000b200310230b2000411a3602000c5e0b024002402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241a8026a2001106e20022802a802450d010b2000411a3602000c5e0b20022802ac0221012000410936020020002001360204200041086a200241c00a6a41a80110dc041a0c5d0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241b0026a2001106e20022802b0020d00200128020420022802b4022204490d002004417f4c0d1a024002400240024020040d00410121030c010b200410272203450d0120072802002004490d0220032001280200200410dc041a200128020422052004490d2d2001200520046b3602042001200128020020046a3602000b2003450d02200020033602042000410a360200200041086a2004ad220a422086200a84370200200041106a200241c00a6a41a00110dc041a0c5f0b200441011030000b200310230b2000411a3602000c5c0b2006450d5320042d0001210520012003417e6a22063602042001200441026a36020020050d5320064104490d532004280002210b20012003417a6a3602042001200441066a360200200241c8026a2001106e20022802c8020d53200128020420022802cc022205490d532005417f4c0d180240024002400240024020050d004101210c41010d010c580b20051027220c450d0120072802002005490d02200c2001280200200510dc042104200128020422032005490d2d2001200320056b3602042001200128020020056a3602002004450d570b200241c0026a2001106e20022802c002450d020c550b200541011030000b200c10230c540b2007280200410c6e220f410c6c2204417f4c0d1820022802c40221100240024020040d004104210e0c010b20041021220e450d2b0b0240024002400240024002402010450d004100210841002103410021090340200241b8026a2001106e20022802b8020d03200128020420022802bc022204490d032004417f4c0d1f0240024020040d004101210d0c010b20041027220d450d3f20072802002004490d03200d2001280200200410dc041a200128020422062004490d332001200620046b3602042001200128020020046a3602000b200941016a210602402009200f470d0020082006200820064b1b220fad420c7e220a422088a70d61200aa722174100480d610240024020090d0020171021210e0c010b200e200320171025210e0b200e450d340b200e20036a2209200d360200200941046a2004ad220a422086200a84370200200841026a21082003410c6a21032006210920102006470d000b0b200e450d57200c450d58200728020022034104490d0220012802002207280000210820012003417c6a22043602042001200741046a36020020044104490d032007280004210d2001200341786a22093602042001200741086a36020041002104200241003a00d009200341776a2103034020092004460d0520024190096a20046a200720046a220641086a2d00003a0000200120033602042001200641096a3602002002200441016a22063a00d0092003417f6a210320062104200641c000470d000b200641ff017141c000490d55200c450d58200241c8096a350200210a200241b0096a290300211120022903c009211620022903a809211520022802cc09210120022903b809211420022802a409210420022802a0092103200228029c0921062002280298092107200228029409210920022802900921172000200b3602042000410b360200200041e0006a200a3e0200200041d8006a2016370200200041c8006a2011370200200041c0006a2015370200200041e4006a2001360200200041d0006a20143702002000413c6a2004360200200041386a2003360200200041346a2006360200200041306a20073602002000412c6a2009360200200041286a2017360200200041246a200d360200200041206a20083602002000411c6a2010360200200041186a200f360200200041146a200e360200200041106a20053602002000410c6a2005360200200041086a200c360200200041e8006a200241c00a6a41c80010dc041a0c600b200d10230b02402009450d00200e210103400240200141046a280200450d00200128020010230b2001410c6a2101200341746a22030d000b0b200f450d55200e10230c550b02402005450d00200c10230b02402010450d002010410c6c2104200e210103400240200141046a280200450d00200128020010230b2001410c6a2101200441746a22040d000b0b200f0d530c550b02402005450d00200c10230b02402010450d002010410c6c2104200e210103400240200141046a280200450d00200128020010230b2001410c6a2101200441746a22040d000b0b200f0d520c540b200441ff0171450d50200241003a00d0090c500b02402006450d0020012003417e6a3602042001200441026a3602000b2000411a3602000c5a0b2006450d4d20042d0001210520012003417e6a22183602042001200441026a360200200541104b0d4d410e21100240024002400240024002400240024002400240024002400240024002400240024020050e11000102030405060708090a0c0d5d0e0f10000b20024190096a200110d901200228029009411a460d5d200241c00a6a20024190096a41b00110dc041a41b00110212206450d462006200241c00a6a41b00110dc042104200241d0026a200110eb02024020022903d002a7450d00200410db01200410230c5e0b200241e0026a290300210a20022903d8022211422088a721172011a7210b410121100c5c0b200241e8026a2001106e20022802e8020d5c20022802ec022106410221100c5a0b200241f0026a2001106e20022802f0020d5b20072802002204450d5b20022802f4022106200128020022052d0000210320012004417f6a3602042001200541016a360200200341ff0071220941064b0d5b2003410776210e410321100c580b200241f8026a2001106e20022802f8020d5a20072802002204450d5a20022802fc022106200128020022052d0000210320012004417f6a3602042001200541016a360200200341ff0071220941064b0d5a2003410776210e410421100c570b20184104490d592004280002210620012003417a6a3602042001200441066a360200410521100c570b20024190096a200110d901200228029009411a460d58200241c00a6a20024190096a41b00110dc041a41b00110212206450d422006200241c00a6a41b00110dc041a410621100c560b20024190096a200110d901200228029009411a460d57200241c00a6a20024190096a41b00110dc041a41b00110212206450d422006200241c00a6a41b00110dc041a410721100c550b20024190096a200110d901200228029009411a460d56200241c00a6a20024190096a41b00110dc041a41b00110212206450d422006200241c00a6a41b00110dc041a410821100c030b41002105200241003a00e00a2003417e6a2109417d21060340024020092005470d00200541ff0171450d57200241003a00e00a0c570b200241c00a6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00e00a2006417f6a21062007210520074120470d000b200241d0056a41086a200241cf0a6a290000220a370300200320076b2203417e6a4104490d5520022f00c10a2109200241d70a6a2900002111200241df0a6a2d0000210f20022800c30a210620022d00c00a210e20022900c70a2116200420076a220441026a280000210d20012003417a6a22053602042001200441066a220736020020054104490d552009410876210c200728000021192001200341766a36020420012004410a6a3602002016422088a721172016a7210b410921100c540b41002105200241003a00e00a2003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d56200241003a00e00a0c560b200241c00a6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00a2003417f6a21032006210520064120470d000b200241d0056a41086a200241cf0a6a290000220a37030020022f00c10a2209410876210c20022900c70a2216422088a72117200241d70a6a2900002111200241df0a6a2d0000210f20022800c30a210620022d00c00a210e2016a7210b410a21100c530b20024180036a2001106e2002280280030d532002280284032106410b21100b410021174200210a4100210b410021194100210d410021080c510b20024198036a2001106e2002280298030d51200228029c03210620024190036a2001106e2002280290030d51200228029403210b20024188036a2001106e2002280288030d51200228028c032117410c21100c500b41002105200241003a00e00a2003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d52200241003a00e00a0c520b200241c00a6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00a2003417f6a21032006210520064120470d000b200241d0056a41086a200241cf0a6a290000220a37030020022f00c10a2209410876210c20022900c70a2216422088a72117200241d70a6a2900002111200241df0a6a2d0000210f20022800c30a210620022d00c00a210e2016a7210b410d21100c4f0b41002105200241003a00e00a2003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d51200241003a00e00a0c510b200241c00a6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00a2003417f6a21032006210520064120470d000b200220022800c30a22063600bb08200220022f00c10a22093b00b908200220022d00c00a220e3a00b8082009410876210c20022900c70a2216422088a72117410f2110200241c00a6a410f6a290000210a200241d70a6a2900002111200241df0a6a2d0000210f2016a7210b0c4e0b41002105200241003a00e00a2003417e6a21092003417d6a21060340024020092005470d00200541ff0171450d50200241003a00e00a0c500b200241c00a6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00e00a2006417f6a21062007210520074120470d000b200241e8056a200241df0a6a2d00003a0000200241e0056a200241d70a6a290000370300200241d8056a200241c00a6a410f6a290000220a37030020024198086a410f6a200a3c0000200220022800c30a36009b08200220022f00c10a3b009908200220022d00c00a3a009808200220022900c70a37009f082003417e6a2007460d4e200241e1056a290000211620022900d905210a200420076a220441026a2d00002108200120063602042001200441036a360200200841064b0d4e200241d8086a41086a20024198086a41086a2903003703002002200a3e02e808200241ee086a200a4230883c0000200241ec086a200a4220883d0100200220022903980822153703d808200a4238882016420886220a8442ffffffff0f83200a428080808070838421112016423888a7210f20022900df082216422088a72117200241e7086a290000210a20022d00d908210920022d00da08210c20022800db0821062015a7210e2016a7210b411021100c4d0b411121100c4c0b20024190096a200110d20320022d0090094105470d0e2000411a3602000c580b20024190096a200110d20320022d0090094105470d0e2000411a3602000c570b2006450d4620042d0001210520012003417e6a360204410221032001200441026a360200200541054b0d460240024002400240024020050e06001401020304000b20024190096a2001107e2002280290092204450d4a20024198096a28020021072002280294092106200241a0036a200110eb0220022903a003a7450d122006450d4a200410230c4a0b20024190096a200110d80220022d0090094102460d49200220022902940922153703d8082002419c096a2902002111200241a4096a2902002116200241ac096a290200210a200228029009210420022802dc0821072015a72106410321030c120b410421030c110b410521030c100b20024190096a200110d80220022d0090094102460d46200220022902940922153703d8082002419c096a2902002111200241a4096a2902002116200241ac096a290200210a200228029009210420022802dc0821072015a72106410621030c0f0b2006450d4420042d0001210520012003417e6a3602042001200441026a360200200541034b0d440240024002400240024020050e0400010203000b41002105200241003a00f8082003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d4a200241003a00f8080c4a0b200241d8086a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00f8082003417f6a21032006210520064120470d000b200241b8086a41186a200241d8086a41186a290300220a37030020024190096a41086a200241d8086a41086a29030037030020024190096a41106a200241d8086a41106a29030037030020024190096a41186a200a370300200241cf096a200241ef056a280000360000200241c8096a200241d0056a41186a290000370300200241c0096a200241d0056a41106a290000370300200241b8096a200241d0056a41086a290000370300200220022903d80837039009200220022900d0053703b009410121010c030b41002105200241003a00f8082003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d49200241003a00f8080c490b200241d8086a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00f8082003417f6a21032006210520064120470d000b200241b8086a41186a200241d8086a41186a290300220a37030020024190096a41086a200241d8086a41086a29030037030020024190096a41106a200241d8086a41106a29030037030020024190096a41186a200a370300200241cf096a200241ef056a280000360000200241c8096a200241d0056a41186a290000370300200241c0096a200241d0056a41106a290000370300200241b8096a200241d0056a41086a290000370300200220022903d80837039009200220022900d0053703b009410221010c020b41002105200241003a00f005410220036b21092003417d6a210603400240200920056a0d00200541ff0171450d48200241003a00f0050c480b200241d0056a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00f0052006417f6a21062007210520074120470d000b200241d8086a41086a200241d0056a41086a290300370300200241d8086a41106a200241d0056a41106a290300370300200241d8086a41186a200241d0056a41186a290300370300200220022903d0053703d80841002105200241003a00f005200420076a2109200720036b41026a210303400240200320056a0d00200541ff0171450d48200241003a00f0050c480b200241d0056a20056a200920056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a00f0052006417f6a21062004210520044120470d000b200241b8086a41186a200241d0056a41186a290300220a37030020024198086a41086a2201200241d0056a41086a29030037030020024198086a41106a2204200241d0056a41106a29030037030020024198086a41186a2203200a37030020024190096a41186a200241d8086a41186a29030037030020024190096a41106a200241d8086a41106a29030037030020024190096a41086a200241d8086a41086a290300370300200220022903d00537039808200220022903d80837039009200241c8096a2003290300370300200241c0096a2004290300370300200241b8096a200129030037030020022002290398083703b009200241d2096a20024197086a2d00003a0000200220022f0095083b01d009410321010c010b200241b8086a2001107e20022802b808450d45200241e3086a200241b8086a41086a280200360000200241a7096a200241d0056a41086a290200370000200241af096a200241e0056a290200370000200241b7096a200241e8056a290200370000200241bf096a200241f0056a290200370000200241c7096a200241f8056a290200370000200241cf096a20024180066a280200360000200220022903b8083700db08200220022902d00537009f09200220022900d808370390092002200241df086a29000037009709410421010b200241f0066a20024190096a41c30010dc041a200020013a000420004111360200200041056a200241f0066a41c30010dc041a200041c8006a200241c00a6a41e80010dc041a0c550b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d0002400240024020050e03000102000b200241b8036a200110eb0220022903b803a70d02200241c8036a290300210a20022903c003211120024190096a200110d80220022d0090094102460d02200241f8066a2002419c096a29020037030020024180076a200241a4096a29020037030020024188076a200241ac096a29020037030020022002290294093703f0062002280290092101410121040c450b200241d0036a2001106e20022802d0030d0120022802d4032101200241f0066a41186a20024190096a41186a290300370300200241f0066a41106a20024190096a41106a290300370300200241f0066a41086a20024190096a41086a29030037030020022002290390093703f006410221040c440b200241d8036a2001106e20022802d8030d0020022802dc032101200241f0066a41186a20024190096a41186a290300370300200241f0066a41106a20024190096a41106a290300370300200241f0066a41086a20024190096a41086a29030037030020022002290390093703f006410321040c430b2000411a3602000c540b2006450d4020042d0001210520012003417e6a22063602042001200441026a360200200541014b0d4002400240024020050e020001000b41002105200241003a00e00a410220036b21092003417d6a210603400240200920056a0d00200541ff0171450d44200241003a00e00a0c440b200241c00a6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00e00a2006417f6a21062007210520074120470d000b200241d8056a200241cf0a6a290000370300200241e0056a200241d70a6a290000370300200241e8056a200241df0a6a2d00003a0000200220022900c70a3703d00520022800c30a210820022f00c10a210d20022d00c00a210e41002105200241003a00810b200420076a2109200720036b41026a210303400240200320056a0d00200541ff0171450d44200241003a00810b0c440b200241c00a6a20056a200920056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a00810b2006417f6a210620042105200441c100470d000b200241a7086a200241d0056a41086a2d00003a00002002200836009b082002200d3b0099082002200e3a009808200220022903d00537009f08200241ff0a6a3300002116200241e70a6a290000211520022900f70a211420022900df0a211320022900ef0a211220022800db0a210120022800d70a210420022800d30a210320022800cf0a210520022800cb0a210620022800c70a210720023502c00a211a20023301c40a211b20023100c60a211c200241e1056a290000211120022900d905210a200241d8086a41086a20024198086a41086a29030037030020022002290398083703d8082011423888201a201b201c421086844220868442088684211a200a4238882011420886842111410121090c010b200241003a00d40a2006450d4120042d0002210520012003417d6a22063602042001200441036a360200200241013a00d40a200220053a00c00a2006450d4020042d0003210520012003417c6a22063602042001200441046a360200200241023a00d40a200220053a00c10a2006450d4020042d0004210520012003417b6a22063602042001200441056a360200200241033a00d40a200220053a00c20a2006450d4020042d0005210520012003417a6a22063602042001200441066a360200200241043a00d40a200220053a00c30a2006450d4020042d000621052001200341796a22063602042001200441076a360200200241053a00d40a200220053a00c40a2006450d4020042d000721052001200341786a22063602042001200441086a360200200241063a00d40a200220053a00c50a2006450d4020042d000821052001200341776a22063602042001200441096a360200200241073a00d40a200220053a00c60a2006450d4020042d000921052001200341766a220636020420012004410a6a360200200241083a00d40a200220053a00c70a2006450d4020042d000a21052001200341756a220636020420012004410b6a360200200241093a00d40a200220053a00c80a2006450d4020042d000b21052001200341746a220636020420012004410c6a3602002002410a3a00d40a200220053a00c90a2006450d4020042d000c21052001200341736a220636020420012004410d6a3602002002410b3a00d40a200220053a00ca0a2006450d4020042d000d21052001200341726a220636020420012004410e6a3602002002410c3a00d40a200220053a00cb0a2006450d4020042d000e21052001200341716a220636020420012004410f6a3602002002410d3a00d40a200220053a00cc0a2006450d4020042d000f21052001200341706a22063602042001200441106a3602002002410e3a00d40a200220053a00cd0a2006450d4020042d0010210520012003416f6a22063602042001200441116a3602002002410f3a00d40a200220053a00ce0a2006450d4020042d0011210520012003416e6a22063602042001200441126a360200200241103a00d40a200220053a00cf0a2006450d4020042d0012210520012003416d6a22063602042001200441136a360200200241113a00d40a200220053a00d00a2006450d4020042d0013210520012003416c6a22063602042001200441146a360200200241123a00d40a200220053a00d10a2006450d4020042d0014210520012003416b6a22063602042001200441156a360200200241133a00d40a200220053a00d20a2006450d4020042d0015210520012003416a6a22063602042001200441166a360200200241f0066a41086a2207200241c00a6a41086a290300370300200220053a00d30a200220022903c00a3703f00620064110490d4120022802d00a21052004411e6a290000211a2004290016211120012003415a6a3602042001200441266a360200200241d8086a41086a2007290300370300200220022903f0063703d8082005ad210a410221090b200241b8086a41086a200241d8086a41086a290300221b370300200220022903d808221c3703b8082000411f6a200a4230883c00002000411d6a200a4220883d00002000200a3e0019200041e8006a20163e0200200041e0006a2014370200200041d0006a2015370200200041c8006a2013370200200041286a201a370200200041206a2011370200200041086a20093a0000200041133602002000201c370009200041116a201b370000200041d8006a2012370200200041c4006a2001360200200041c0006a20043602002000413c6a2003360200200041386a2005360200200041346a2006360200200041306a2007360200200041f0006a200229039009370300200041f8006a20024190096a41086a29030037030020004180016a200241a0096a29030037030020004188016a200241a8096a29030037030020004190016a20024190096a41206a29030037030020004198016a20024190096a41286a290300370300200041a0016a20024190096a41306a290300370300200041a8016a20024190096a41386a2903003703000c530b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d0020024190096a2001107f20022802900922010d0d0b2000411a3602000c520b024002402006450d0020042d0001210520012003417e6a3602042001200441026a3602002005450d010b2000411a3602000c520b20004115360200200041046a200241c00a6a41ac0110dc041a0c510b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541054b0d0002400240024002400240024020050e06000102030405000b200241e8036a2001106e20022802e8030d0520022802ec032104200241e0036a2001106e20022802e0030d0520022802e4032105410121010c410b200241a0046a2001106e20022802a0040d0420022802a404210420024198046a2001106e2002280298040d04200228029c04210520024190046a2001106e2002280290040d04200228029404210320024188046a2001106e2002280288040d04200228028c042106200241f0036a200110eb0220022903f003a70d0420022903f803210a200241f0066a41106a200241f0036a41106a2903003703002002200a3703f806200220063602f006410221010c400b200241d0046a2001106e20022802d0040d0320022802d4042104200241c8046a2001106e20022802c8040d0320022802cc042105200241c0046a2001106e20022802c0040d0320022802c4042103200241a8046a200110eb0220022903a804a70d03200241b8046a290300210a200220022903b0043703f0062002200a3703f80641032101410021074200210a410021090c3f0b20024190096a200110d80220022d0090094102460d022002200241ac096a290200370380072002200241a4096a2902003703f80620022002419c096a2902003703f006200229029409220a422088a721032002280290092104200aa72105410421010c3e0b200241e8046a2001106e20022802e8040d0120022802ec04210e200241e0046a2001106e20022802e0040d0120022802e404210941002103200241003a00b0092007280200417f6a21040240024002400240024003402004417f460d0120024190096a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00b0092004417f6a21042005210320054120470d000b200241d8056a2002419f096a290000370300200241e0056a200241a7096a290000370300200241e8056a200241af096a2d00003a000020022002290097093703d005200228009309210420022f009109210820022d009009210d200241d8046a2001106e20022802d8040d06200128020420022802dc042206490d062006417f4c0d1420060d01410121030c020b200341ff0171450d05200241003a00b0090c050b200610272203450d0120072802002006490d0220032001280200200610dc041a200128020422052006490d272001200520066b3602042001200128020020066a3602000b2003450d03200241f9066a200241e1056a2900003700002002200436009b08200220022903d005221137009f08200220022900d9053700f1062002200e36028407200241003b0182072002200241d0056a41086a2d00003a00f00620084180fe037141087621072006ad4220862003ad84210a20022800a30821032011a72105410521010c3f0b200641011030000b200310230c010b200241f8046a2001106e20022802f8040d0020022802fc042104200241f0046a2001106e20022802f0040d00200128020420022802f4042203490d002003417f4c0d0e024002400240024020030d004101210541010d010c040b200310272205450d0120072802002003490d0220052001280200200310dc042106200128020422072003490d272001200720036b3602042001200128020020036a3602002006450d030b200220033602f00641062101410021064200210a0c3e0b200341011030000b200510230b2000411a3602000c500b2006450d3920042d0001210520012003417e6a221d3602042001200441026a36020041062108200541064b0d3902400240024002400240024002400240024002400240024020050e0700010203043d05000b20024190056a2001106e2002280290050d4420072802002203450d442002280294052109200128020022052d0000210420012003417f6a3602042001200541016a360200200441014b0d444100210b0240024020040e020100010b4101210b0b20024188056a2001106e2002280288050d442001280204200228028c05220d490d44200d417f4c0d17024002400240200d0d004101210c41010d010c470b200d1027220c450d012007280200200d490d45200c2001280200200d10dc04210420012802042203200d490d3020012003200d6b36020420012001280200200d6a3602002004450d460b20024180056a2001106e2002280280050d4320012802042002280284052210490d432010417f4c0d1820100d06410121170c070b200d41011030000b20024198056a2001106e2002280298050d43200228029c052109410221080c3b0b201d4104490d422004280002210920012003417a6a3602042001200441066a360200410321080c3a0b200241a8056a2001106e20022802a8050d41200128020420022802ac052206490d412006417f4c0d1402400240024020060d004101210941010d010c440b200610272209450d0120072802002006490d3f20092001280200200610dc042104200128020422032006490d2e2001200320066b3602042001200128020020066a3602002004450d430b200241a0056a2001106e20022802a0050d3d200128020420022802a405220e490d3d200e417f4c0d15200e0d064101210d0c070b200641011030000b200241b0056a2001106e20022802b0050d4020022802b405210f41002104200241003a00b00920072802002107417f2103034020072004460d3a20024190096a20046a200128020022062d00003a00002001200720036a3602042001200641016a3602002002200441016a22053a00b0092003417f6a21032005210420054120470d000b200241e8056a200241af096a2d00003a0000200241e0056a200241a7096a290000370300200241d8056a20024190096a410f6a290000220a37030020024198086a410f6a200a3c0000200220022800930936009b08200220022f0091093b009908200220022d0090093a009808200220022900970937009f08200241e1056a290000211320022900d905211441002104200241003a00b009200720056b2109200720036a21030340024020092004470d00200441ff0171450d42200241003a00b0090c420b20024190096a20046a200620046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00b0092003417f6a21032005210420054120470d000b200241e8056a2201200241af096a2d00003a0000200241d8086a41086a20024198086a41086a29030037030020022002280093093600bb08200220022f0091093b00b908200220022d0090093a00b80820022002290097093700bf0820022002419f096a2900003700c70820022002290398083703d808200241a7096a290000211620013100002115200220143e02e808200241ee086a20144230883c0000200241ec086a20144220883d0100200241b8086a41086a350200200241c4086a330100200241c6086a310000421086844220868442088620022903b808220a4238888421112013423888200a42088684210a2014423888201342088684a7210e2014421888a721172013421888a7211020022800e708210d20022900c708211420022800e308210620022800df08210c20022800db08210920022d00da08211920022d00d908211820022d00d808210b410521080c380b200241b8056a2001106e20022802b8050d3f20022802bc052109410721080c370b201010272217450d0120072802002010490d3b20172001280200201010dc041a200128020422042010490d2a2001200420106b3602042001200128020020106a3602000b2017450d3b4200210a410121084100210f2010210e42002111200d21060c350b201041011030000b200e1027220d450d012007280200200e490d35200d2001280200200e10dc041a20012802042204200e490d2820012004200e6b36020420012001280200200e6a3602000b200d450d35420021164104210841002119200e2117420021152006210c0c320b200e41011030000b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d0002400240024020050e03000102000b20024190096a200110d901200228029009411a460d02200241c00a6a20024190096a41b00110dc041a41b001102122040d0c41b00141081030000b200241c00a6a200110d8024102210120022d00c00a4102460d01200241f0086a200241dc0a6a290200220a370300200241e8086a200241d40a6a2902002211370300200241cc0a6a290200211620022802c00a210420022902c40a21150c0c0b200241c00a6a200110d80220022d00c00a4102460d00200241d8056a200241cc0a6a290200370300200241e0056a200241d40a6a290200370300200241e8056a200241dc0a6a290200370300200220022902c40a3703d00520022802c00a210420024190096a200110d901200228029009411a460d00200241c00a6a20024190096a41b00110dc041a41b00110212203450d302003200241c00a6a41b00110dc041a200241d8086a41186a200241d0056a41186a290300220a370300200241d8086a41106a200241d0056a41106a2903002211370300200241d8056a290300211620022903d0052115410321010c0b0b2000411a3602000c4e0b2006450d0220042d0001210520012003417e6a360204410221092001200441026a360200200541034b0d020240024002400240024020050e0400030102000b200241c0056a2001106e20022802c0050d06200128020420022802c4052204490d062004417f4c0d0e024002400240024020040d00410121060c010b200410272206450d0120072802002004490d0220062001280200200410dc041a200128020422032004490d2c2001200320046b3602042001200128020020046a3602000b2006450d08200241d0056a41106a20024190096a41106a290200370300200241d0056a41086a20024190096a41086a29020037030020022002290290093703d00541012109200421080c040b200441011030000b200610230c060b20024190096a200110d80220022d0090094102460d05200241d0056a41086a200241a4096a290200370300200241e0056a200241ac096a29020037030020022002419c096a2902003703d00520024190096a41086a280200210420022802940921082002280290092106410321090c010b20024190096a200110d80220022d0090094102460d04200241f0066a41086a200241a4096a29020037030020024180076a200241ac096a29020037030020022002419c096a2902003703f00620024190096a41086a280200210420022802940921082002280290092106200241c8056a2001106e20022802c8050d04200128020420022802cc052203490d042003417f4c0d0c0240024020030d004101210d41010d010c060b20031027220d450d0220072802002003490d04200d2001280200200310dc042105200128020422072003490d292001200720036b3602042001200128020020036a3602002005450d050b200241d0056a41106a200241f0066a41106a290300370300200241d0056a41086a200241f0066a41086a290300370300200220022903f0063703d005410421090b200241d8086a41106a200241d0056a41106a290300220a370300200241d8086a41086a200241d0056a41086a2903002211370300200220022903d00522163703d808200041106a20043602002000410c6a2008360200200041086a20063602002000200936020420004119360200200041146a20163702002000411c6a2011370200200041246a200a370200200041346a2003360200200041306a20033602002000412c6a200d360200200041386a200241c00a6a41f80010dc041a0c4e0b200341011030000b2000411a3602000c4c0b200d10230b2000411a3602000c4a0b200241f0066a41206a20024190096a41206a290300220a370300200241f0066a41186a20024190096a41186a2903002211370300200241f0066a41106a20024190096a41106a2903002216370300200241f0066a41086a20024190096a41086a2903002215370300200220022903900922143703f0062000410e360200200020143702042000410c6a2015370200200041146a20163702002000411c6a2011370200200041246a200a3702002000412c6a200241c00a6a41840110dc041a0c490b200241f0066a41206a20024190096a41206a290300220a370300200241f0066a41186a20024190096a41186a2903002211370300200241f0066a41106a20024190096a41106a2903002216370300200241f0066a41086a20024190096a41086a2903002215370300200220022903900922143703f0062000410f360200200020143702042000410c6a2015370200200041146a20163702002000411c6a2011370200200041246a200a3702002000412c6a200241c00a6a41840110dc041a0c480b200241b0036a290300211620022903a8032111410121030b20004110360200200041206a2016370200200041186a2011370200200041286a200a370200200041146a2007360200200041106a20063602002000410c6a2004360200200041086a2003360200200041306a200241c00a6a41800110dc041a0c460b200041086a2002290294093702002000200136020420004114360200200041106a200241c00a6a41a00110dc041a0c450b2004200241c00a6a41b00110dc041a410121010b2000200136020420004118360200200041246a200a3702002000411c6a2011370200200041146a20163702002000410c6a20153702002000412c6a2003360200200041086a2004360200200041306a200241f0066a41800110dc041a0c430b102f000b20042003103e000b20042003103e000b200441041030000b20032004103e000b20042008103e000b201041041030000b200441041030000b20042006103e000b200b41041030000b20042003103e000b200441041030000b200d41041030000b200441041030000b200841041030000b20042006103e000b20042005103e000b20052003103e000b200441041030000b20042006103e000b201741041030000b20062005103e000b20032007103e000b200d2003103e000b20062003103e000b20102004103e000b200e2004103e000b20042003103e000b20032007103e000b200341011030000b200441011030000b200441011030000b41b00141081030000b41b00141081030000b41b00141081030000b41b00141081030000b41b00141081030000b200020193a0007200020183a00062000200b3a0005200020083a000420004117360200200041c4006a20153e02002000413c6a20163702002000412c6a2011370200200041246a200a370200200041c8006a200f360200200041346a2014370200200041206a20103602002000411c6a200e360200200041186a2017360200200041146a200d360200200041106a20063602002000410c6a200c360200200041086a2009360200200041cc006a200241c00a6a41e40010dc041a0c1d0b200441ff0171450d06200241003a00b0090c060b200d10230b2006450d040b200910230c030b201710230b200d450d010b200c10230b2000411a3602000c150b200241d8086a41106a200241f0066a41106a2903002211370300200241d8086a41086a200241f0066a41086a2903002216370300200220022903f00622153703d808200041146a2003360200200041106a20053602002000410c6a2004360200200020073a000b200020083a000a2000200d3a0009200041086a20013a000020004116360200200041186a2015370200200041206a2016370200200041286a20113702002000413c6a2006360200200041346a200a370200200041306a2009360200200041c0006a200241c00a6a41f00010dc041a0c140b200241003a00d40a0b2000411a3602000c120b200241d0056a41186a200241f0066a41186a2903002216370300200241d0056a41106a200241f0066a41106a2903002215370300200241d0056a41086a200241f0066a41086a2903002214370300200220022903f00622133703d005200041386a200a370200200041306a20113702002000410c6a2001360200200041086a200436020020004112360200200041106a2013370200200041186a2014370200200041206a2015370200200041286a2016370200200041c0006a200241c00a6a41f00010dc041a0c110b2000411a3602000c100b2000411a3602000c0f0b410021174200210a0c010b410021174200210a0b200041003b012a200020083a00292000200c3a000b200020093a000a2000200e3a00092000410d360200200041186a200a370200200041346a4100360200200041306a20193602002000412c6a200d360200200041286a200f3a0000200041206a20113702002000410c6a2006360200200041086a20103a0000200041106a2017ad422086200bad84370200200041386a200241f0066a41f80010dc041a0c0c0b2000411a3602000c0b0b02402005450d00200c10230b02402010450d002010410c6c2104200e210103400240200141046a280200450d00200128020010230b2001410c6a2101200441746a22040d000b0b200f450d020b200e10230c010b2005450d00200c10230b2000411a3602000c070b2000411a3602000c060b20024198086a41186a200241b8086a41186a290300221a37030020024198086a41106a200241b8086a41106a290300221b37030020024198086a41086a200241b8086a41086a290300221c370300200220022903b808221e37039808200041e0006a2014370200200041d8006a2015370200200041c8006a2012370200200041c0006a2013370200200041386a200a370200200041306a20113702002000410c6a2004360200200041086a200136020020004104360200200041106a201e370200200041186a201c370200200041206a201b370200200041286a201a370200200041d0006a2016370200200041e8006a200241c00a6a41c80010dc041a0c050b2000411a3602000c040b200510230b2000411a3602000c020b102a000b20004100360200200041106a200a3702002000410c6a2005360200200041086a2009360200200041186a200241c00a6a41980110dc041a0b200241f00b6a24000b930b01057f024002402000280200220141184b0d0002400240024002400240024002400240024002400240024002400240024020010e1900101010100102100310040510060708090a10100b100c0d0e000b200041086a10dd030f0b02402000410c6a2802002201450d0020002802042202200141f0006c6a2103034002402002410c6a2802002204450d0020022802042101200441246c210403400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012004415c6a22040d000b0b200241f0006a21010240200241086a280200450d00200228020410230b2001210220012003470d000b0b200041086a280200450d0e200028020410230f0b0240200041086a2d00002201410f4b0d00410120017441bfbf03710d0e024020014106470d00200041106a280200450d0f2000410c6a28020010230f0b200041106a280200450d0e2000410c6a28020010230f0b200041146a280200450d0d200041106a28020010230f0b200041086a280200450d0c200028020410230f0b200041086a280200450d0b200028020410230f0b02402000410c6a280200450d00200041086a28020010230b02402000411c6a2802002204450d00200041146a28020021012004410c6c210403400240200141046a280200450d00200128020010230b2001410c6a2101200441746a22040d000b0b200041186a280200450d0a200028021410230f0b200041086a2d0000417f6a220141074b0d09024002400240024020010e08000d0d0d0d010203000b2000410c6a220128020010da01200128020010230f0b2000410c6a220128020010da01200128020010230f0b2000410c6a220128020010da01200128020010230f0b2000410c6a220128020010da01200128020010230f0b20002d0004417f6a220141024b0d0802400240024020010e03000102000b2000410c6a280200450d0a200041086a28020010230f0b200041086a220128020010da01200128020010230f0b2000410c6a220128020010da01200128020010230f0b20002d0004417f6a220141024b0d0702400240024020010e03000102000b2000410c6a280200450d09200041086a28020010230f0b200041086a220128020010da01200128020010230f0b2000410c6a220128020010da01200128020010230f0b200041086a2802004101470d06200041106a280200450d062000410c6a28020010230f0b20002d00044104490d052000410c6a280200450d05200041086a28020010230f0b02402000410c6a2802002204450d0020002802042101200441d0016c210403402001106c200141d0016a2101200441b07e6a22040d000b0b200041086a280200450d04200028020410230f0b200041086a2d000022014105490d03024020014105470d00200041386a280200450d04200041346a28020010230f0b200041146a280200450d03200041106a28020010230f0b20002d0004417f6a220141034b0d020240024020010e0400040401000b0240200041106a280200450d002000410c6a28020010230b2000411c6a280200450d03200041186a28020010230c030b02402000410c6a280200450d00200041086a28020010230b200041186a280200450d02200041146a28020010230f0b02402000280204220141024b0d00024020010e03030003030b200041086a220128020010da01200128020010230f0b2000412c6a220128020010da01200128020010230f0b02402000280204220141034b0d00024020010e0402000202020b2000410c6a280200450d01200041086a28020010230f0b200041306a280200450d002000412c6a28020010230f0b0bc60d01057f024002402000280200220141184b0d0002400240024002400240024002400240024002400240024002400240024020010e1900101010100102100310040510060708090a10100b100c0d0e000b0240200041086a280200220141064b0d00024002400240024020010e0714140014010203140b200041106a280200450d132000410c6a28020010230f0b200041106a280200450d122000410c6a28020010230f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010230b0240200141106a280200450d002001410c6a28020010230b200141186a2101200241686a22020d000b0b200041106a280200450d11200028020c10230f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b200041106a280200450d10200028020c10230f0b200041106a280200450d0f2000410c6a28020010230f0b02402000410c6a2802002201450d0020002802042203200141f0006c6a2104034002402003410c6a2802002202450d0020032802042101200241246c210203400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012002415c6a22020d000b0b200341f0006a21010240200341086a280200450d00200328020410230b2001210320012004470d000b0b200041086a280200450d0e200028020410230f0b0240200041086a2d00002201410f4b0d00410120017441bfbf03710d0e024020014106470d00200041106a280200450d0f2000410c6a28020010230f0b200041106a280200450d0e2000410c6a28020010230f0b200041146a280200450d0d200041106a28020010230f0b200041086a280200450d0c200028020410230f0b200041086a280200450d0b200028020410230f0b02402000410c6a280200450d00200041086a28020010230b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b200041186a280200450d0a200028021410230f0b200041086a2d0000417f6a220141074b0d09024002400240024020010e08000d0d0d0d010203000b2000410c6a220128020010db01200128020010230f0b2000410c6a220128020010db01200128020010230f0b2000410c6a220128020010db01200128020010230f0b2000410c6a220128020010db01200128020010230f0b20002d0004417f6a220141024b0d0802400240024020010e03000102000b2000410c6a280200450d0a200041086a28020010230f0b200041086a220128020010db01200128020010230f0b2000410c6a220128020010db01200128020010230f0b20002d0004417f6a220141024b0d0702400240024020010e03000102000b2000410c6a280200450d09200041086a28020010230f0b200041086a220128020010db01200128020010230f0b2000410c6a220128020010db01200128020010230f0b200041086a2802004101470d06200041106a280200450d062000410c6a28020010230f0b20002d00044104490d052000410c6a280200450d05200041086a28020010230f0b02402000410c6a2802002202450d0020002802042101200241d0016c210203402001106c200141d0016a2101200241b07e6a22020d000b0b200041086a280200450d04200028020410230f0b200041086a2d000022014105490d03024020014105470d00200041386a280200450d04200041346a28020010230f0b200041146a280200450d03200041106a28020010230f0b20002d0004417f6a220141034b0d020240024020010e0400040401000b0240200041106a280200450d002000410c6a28020010230b2000411c6a280200450d03200041186a28020010230c030b02402000410c6a280200450d00200041086a28020010230b200041186a280200450d02200041146a28020010230f0b02402000280204220141024b0d00024020010e03030003030b200041086a220128020010db01200128020010230f0b2000412c6a220128020010db01200128020010230f0b02402000280204220141034b0d00024020010e0402000202020b2000410c6a280200450d01200041086a28020010230f0b200041306a280200450d002000412c6a28020010230f0b0bd00401087f230041f0006b22022400200241d0006a41086a220341aefcc400ad42808080809001841003220441086a2900003703002002200429000037035020041023200241086a41086a2205200329030037030020022002290350370308200341f0f3c000ad42808080809001841003220441086a2900003703002002200429000037035020041023200241186a41086a22062003290300370300200220022903503703182002200136024c200241d0006a41186a2201200241cc006aad4280808080c000841001220441186a290000370300200241d0006a41106a2207200441106a2900003703002003200441086a2900003703002002200429000037035020041023200241286a41186a22082001290300370300200241286a41106a22092007290300370300200241286a41086a2201200329030037030020022002290350370328024041c00010212204450d00200420022903083700002004200229031837001020042002290328370020200441086a2005290300370000200441186a2006290300370000200441286a2001290300370000200441306a2009290300370000200441386a2008290300370000200241d0006a200441c00010dd01200120032903003703002006200241d0006a411c6a2802003602002002200229035037032820022002290264370318024020022802602203450d002000200229032837030020002002290318370214200041086a200241286a41086a2903003703002000411c6a200241186a41086a2802003602000b2000200336021020041023200241f0006a24000f0b41c00041011030000bf20202027f037e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022010d00200041003602100c010b200328021421042003200341106a41086a2802002202360224200320013602200240024020024110490d002003200241706a3602242003200141106a360220200141086a290000210520012900002106200341c8006a200341206a107e20032802482202450d00200329024c2107200020053703082000200637030020002007370214200020023602100c010b20034100360230200342013703282003410c36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034198c2c3003602482003200341386a360258200341c4006a41b8a3c500200341c8006a102e1a2003350230422086200335022884100820004100360210200328022c450d00200328022810230b2004450d00200110230b200341e0006a24000b890606027f017e057f027e017f027e230041f0006b22032400200341d0006a41086a220441d5fbc400ad428080808080018422051003220641086a2900003703002003200629000037035020061023200341306a41086a2207200429030037030020032003290350370330200441eea0c200ad4280808080f001841003220641086a2900003703002003200629000037035020061023200341c0006a41086a2208200429030037030020032003290350370340200341d0006a200010ac010240024041c00010212206450d00200620032903303700002006200329034037001020062003290050370020200641086a2007290300370000200641186a2008290300370000200641286a2004290000370000200641306a200341d0006a41106a2209290000370000200641386a200341d0006a41186a220a290000370000200341186a200641c000108902200341186a41106a290300210b2003290320210c2003280218210d20061023200420051003220641086a29000037030020032006290000370350200610232007200429030037030020032003290350370330200441e3a0c200ad4280808080b001841003220641086a29000037030020032006290000370350200610232008200429030037030020032003290350370340200341d0006a200010ac0141c00010212206450d01200620032903303700002006200329034037001020062003290050370020200641086a200341306a41086a290300370000200641186a200341c0006a41086a290300370000200641286a200341d0006a41086a290000370000200641306a2009290000370000200641386a200a2900003700002003200641c000108902200341106a290300210e20032903082105200328020021042006102320002005420020041b220f2001200c4200200d1b22052005200156200b4200200d1b220b200256200b2002511b22061b22017c220c200e420020041b2002200b20061b22027c200c200f54ad7c10dc022000200520017d200b20027d2005200154ad7d10ca02200341f0006a24000f0b41c00041011030000b41c00041011030000b840401067f230041f0006b22022400200241d0006a41086a220341aefcc400ad42808080809001841003220441086a2900003703002002200429000037035020041023200241086a41086a2205200329030037030020022002290350370308200341ccf3c000ad42808080809001841003220441086a2900003703002002200429000037035020041023200241186a41086a22062003290300370300200220022903503703182002200136024c200241d0006a41186a2201200241cc006aad4280808080c000841001220441186a290000370300200241d0006a41106a2207200441106a2900003703002003200441086a2900003703002002200429000037035020041023200241286a41186a22042001290300370300200241286a41106a22012007290300370300200241286a41086a2207200329030037030020022002290350370328024041c00010212203450d00200320022903083700002003200229031837001020032002290328370020200341086a2005290300370000200341186a2006290300370000200341286a2007290300370000200341306a2001290300370000200341386a2004290300370000200241d0006a200341c00010bb010240024020022802502204450d0020002002290254370204200020043602000c010b20004100360208200042013702000b20031023200241f0006a24000f0b41c00041011030000b940701067f23004190016b22022400200241206a200141206a280200360200200241186a200141186a290200370300200241106a200141106a290200370300200241086a200141086a29020037030020022001290200370300200241e8006a41086a220141aefcc400ad42808080809001841003220341086a2900003703002002200329000037036820031023200241286a41086a200129030037030020022002290368370328200141bdedc000ad4280808080e000841003220341086a2900003703002002200329000037036820031023200241386a41086a20012903003703002002200229036837033802400240410410212203450d0020024284808080c00037026c20022003360268200320022802003600002002410472200241e8006a1071200228026c2104200241e8006a41186a2205200235027042208620022802682206ad841001220341186a290000370300200241e8006a41106a2207200341106a2900003703002001200341086a2900003703002002200329000037036820031023200241c8006a41186a2005290300370300200241c8006a41106a2007290300370300200241c8006a41086a20012903003703002002200229036837034802402004450d00200610230b41c00010212201450d01200120022903283700002001200229033837001020012002290348370020200141086a200241286a41086a290300370000200141186a200241386a41086a290300370000200141286a200241c8006a41086a2204290300370000200141306a200241d8006a290300370000200141386a200241c8006a41186a290300370000200241c00036022c20022001360228200241c8006a2001ad4280808080800884100410900102400240200228024822030d0041002103410021040c010b200228024c2107024002402004280200450d0020032d0000220441ff0071220541064b0d00200441077621040c010b20024100360270200242013703682002410c36023c2002200241286a3602382002200241e8006a36028c01200241146a41013602002002420137020420024198c2c3003602002002200241386a3602102002418c016a41b8a3c5002002102e1a200235027042208620023502688410080240200228026c450d00200228026810230b410221040b02402007450d00200310230b4100200520044102461b2103200441017121040b20011023200020033a0001200020043a000020024190016a24000f0b410441011030000b41c00041011030000bc50d04017f047e137f087e230041a0046b22052400024002400240024020040d00420021064200210742002108420021090c010b200541e8016a10e201200541b0026a20052802e801220a20052802f001108a01024020052802ec01450d00200a10230b20054198016a41086a200541b0026a41086a290300220637030020054198016a41106a200541b0026a41106a290300220737030020054198016a41186a200541b0026a41186a220b290300220837030020054198016a41206a200541b0026a41206a220c2d0000220a3a0000200520052903b002220937039801200541c0016a41206a200a3a0000200541c0016a41186a2008370300200541c0016a41106a2007370300200541c0016a41086a2006370300200520093703c001200541e8016a200541c0016a109c014200210842002109420021064200210720052d00a8024107460d002004417f6a210d20054198036a410472210e200541b0026a41c0006a210f420021064200210742002108420021090340200b2007370300200520063703c002200520083703b002200520093703b802200c200541e8016a41c10010dc04211002400240200f2002460d00200f2002412010de040d010b200e2010290200370200200e41086a201041086a2211290200370200200e41106a201041106a2212290200370200200e41186a201041186a2213290200370200200520013602980320054180046a41086a220a41aefcc400ad42808080809001841003220441086a290000370300200520042900003703800420041023200541c0036a41086a2214200a29030037030020052005290380043703c003200a41bdedc000ad4280808080e000841003220441086a290000370300200520042900003703800420041023200541d0036a41086a2215200a29030037030020052005290380043703d003410410212204450d0320054284808080c0003702840420052004360280042004200528029803360000200e20054180046a1071200528028404211620054180046a41186a22172005350288044220862005280280042218ad841001220441186a29000037030020054180046a41106a2219200441106a290000370300200a200441086a290000370300200520042900003703800420041023200541e0036a41186a221a2017290300370300200541e0036a41106a221b2019290300370300200541e0036a41086a221c200a29030037030020052005290380043703e00302402016450d00201810230b41c00010212204450d04200420052903c003370000200420052903d003370010200420052903e003370020200441086a2014290300370000200441186a2015290300370000200441286a201c290300370000200441306a201b290300370000200441386a201a29030037000020054190016a200441c00041014100410010b80120052802900121142004102320144101460d0020052d00900321042017201329000037030020192012290000370300200a2011290000370300200520102900003703800420054180016a20054180046a10e30120054180016a41086a290300211d200529038001211e02400240200420032004200341ff0171491b220441ff01710d002005201e201d420a420010e20420054198036a41186a201729030037030020054198036a41106a201929030037030020054198036a41086a200a290300370300200520052903800437039803200541106a200120054198036a4100200d10e101200541106a41186a290300211f200541106a41086a2903002120200529032021212005290310212220052903002223211e200541086a2903002224211d0c010b200541c0006a201d42002004ad42ff01832223420010e104200541d0006a201e42002023420010e10420054198036a41186a201729030037030020054198036a41106a201929030037030020054198036a41086a200a290300370300200520052903800437039803200541e0006a200120054198036a2004200d10e101200541306a42004200201e420010e104427f200541d0006a41086a2903002223200529034020052903307c7c221f2005290348200529033884420052201f2023547222041b2124427f200529035020041b2123200541e0006a41186a290300211f200541e0006a41086a290300212020052903702121200529036021220b201d20077c201e20067c2207201e54ad7c201f7c200720217c2206200754ad7c2107202420097c202320087c2209202354ad7c20207c200920227c2208200954ad7c21090b200541e8016a200541c0016a109c0120052d00a8024107470d000b0b2000200637031020002008370300200041186a200737030020002009370308200541a0046a24000f0b410441011030000b41c00041011030000bc60303047f017e017f230041d0006b22012400200141c0006a41086a220241aefcc400ad42808080809001841003220341086a2900003703002001200329000037034020031023200141206a41086a2204200229030037030020012001290340370320200241a1edc000ad42808080809002841003220341086a2900003703002001200329000037034020031023200141306a41086a20022903002205370300200141086a2004290300370300200141186a20053703002001200129034022053703302001200129032037030020012005370310024002404101450d004120210302400240024002404120450d004120102122020d01412041011030000b411021030240411010212202450d00200141106a210420022001290300370000200241086a200141086a2903003700000c020b411041011030000b20022001290300370000200241086a200141086a290300370000200141106a210441204110470d010b20022003200341017422064120200641204b1b220610252202450d02200621030b20022004290000370010200241186a200441086a290000370000200041203602082000200336020420002002360200200141d0006a24000f0b102f000b200641011030000bd50504027f017e057f047e230041f0006b22022400200241d0006a41086a220341d5fbc400ad428080808080018422041003220541086a2900003703002002200529000037035020051023200241306a41086a2206200329030037030020022002290350370330200341e3a0c200ad4280808080b001841003220541086a2900003703002002200529000037035020051023200241c0006a41086a2207200329030037030020022002290350370340200241d0006a200110ac010240024041c00010212205450d00200520022903303700002005200229034037001020052002290050370020200541086a2006290300370000200541186a2007290300370000200541286a2003290000370000200541306a200241d0006a41106a2208290000370000200541386a200241d0006a41186a2209290000370000200241186a200541c000108902200241186a41106a290300210a2002290320210b2002290318210c20051023200320041003220541086a29000037030020022005290000370350200510232006200329030037030020022002290350370330200341eea0c200ad4280808080f001841003220541086a29000037030020022005290000370350200510232007200329030037030020022002290350370340200241d0006a200110ac0141c00010212205450d01200520022903303700002005200229034037001020052002290050370020200541086a200241306a41086a290300370000200541186a200241c0006a41086a290300370000200541286a200241d0006a41086a290000370000200541306a2008290000370000200541386a20092900003700002002200541c000108902200241106a29030021042002290308210d20022802002103200510232000200d420020031b220d200b4200200ca722051b7c220b37030020002004420020031b200a420020051b7c200b200d54ad7c370308200241f0006a24000f0b41c00041011030000b41c00041011030000bbe0c07027f017e047f017e077f037e047f230041b0016b2201240020014190016a41086a220241aefcc400ad428080808090018422031003220441086a290000370300200120042900003703900120041023200141286a41086a220520022903003703002001200129039001370328200241bcf3c000ad42808080808002841003220441086a290000370300200120042900003703900120041023200141386a41086a2206200229030037030020012001290390013703382001200036029001200141e8006a41186a220720014190016aad4280808080c0008422081001220441186a290000370300200141e8006a41106a2209200441106a290000370300200141e8006a41086a220a200441086a2900003703002001200429000037036820041023200141c8006a41186a220b2007290300370300200141c8006a41106a220c2009290300370300200141c8006a41086a220d200a29030037030020012001290368370348024002400240024041c00010212204450d00200420012903283700002004200129033837001020042001290348370020200441086a2005290300370000200441186a2006290300370000200441286a200d290300370000200441306a200c290300370000200441386a200b2903003700002004ad4280808080800884100520041023200220031003220441086a290000370300200120042900003703900120041023200520022903003703002001200129039001370328200241ccf3c000ad42808080809001841003220441086a2900003703002001200429000037039001200410232006200229030037030020012001290390013703382001200036029001200720081001220441186a2900003703002009200441106a290000370300200a200441086a2900003703002001200429000037036820041023200b2007290300370300200c2009290300370300200d200a2903003703002001200129036837034841c00010212204450d01200420012903283700002004200129033837001020042001290348370020200441086a200141286a41086a220a290300370000200441186a200141386a41086a2205290300370000200441286a200141c8006a41086a2206290300370000200441306a200141c8006a41106a220b290300370000200441386a200141c8006a41186a220c2903003700002004ad4280808080800884100520041023200141e8006a200010df01200128026c210e2001280268210f024020012802702204450d002004410574210d200141e8006a410472210741aefcc400ad42808080809001842110200f21020340200141086a41186a200241186a2900002203370300200141086a41106a200241106a2900002208370300200141086a41086a200241086a290000221137030020012002290000221237030820072012370200200741086a2011370200200741106a2008370200200741186a20033702002001200036026820014190016a41086a220420101003220941086a290000370300200120092900003703900120091023200a20042903003703002001200129039001370328200441bdedc000ad4280808080e000841003220941086a290000370300200120092900003703900120091023200520042903003703002001200129039001370338410410212209450d0420014284808080c00037029401200120093602900120092001280268360000200720014190016a1071200128029401211320014190016a41186a22142001350298014220862001280290012215ad841001220941186a29000037030020014190016a41106a2216200941106a2900003703002004200941086a290000370300200120092900003703900120091023200c2014290300370300200b201629030037030020062004290300370300200120012903900137034802402013450d00201510230b41c00010212204450d05200241206a2102200420012903283700002004200129033837001020042001290348370020200441086a200a290300370000200441186a2005290300370000200441286a2006290300370000200441306a200b290300370000200441386a200c2903003700002004ad4280808080800884100520041023200d41606a220d0d000b0b0240200e450d00200f10230b200141b0016a24000f0b41c00041011030000b41c00041011030000b410441011030000b41c00041011030000b860901087f230041c0046b2202240020024190036a41086a220341aefcc400ad42808080809001841003220441086a290000370300200220042900003703900320041023200241086a220520032903003703002002200229039003370300200341bcf3c000ad42808080808002841003220441086a290000370300200220042900003703900320041023200241206a41086a220620032903003703002002200229039003370320200220013602d00120024190036a41186a2201200241d0016aad4280808080c000841001220441186a29000037030020024190036a41106a2207200441106a2900003703002003200441086a290000370300200220042900003703900320041023200241e0016a41186a22042001290300370300200241e0016a41106a22012007290300370300200241e0016a41086a2207200329030037030020022002290390033703e001024002400240024041c00010212203450d002003200229030037000020032002290320370010200320022903e001370020200341086a2005290300370000200341186a2006290300370000200341286a2007290300370000200341306a2001290300370000200341386a2004290300370000200241c0003602142002200336021020022003ad428080808080088410041090010240200228020022040d00411a21010c040b200228020421082002200241086a28020022013602d401200220043602d0010240024020014104490d002004280000210520022001417c6a3602d4012002200441046a3602d00120024190036a200241d0016a10d901200228029003411a460d00200241e0016a20024190036a41b00110dc041a024020022802d4012201450d0020022802d00122092d0000210620022001417f6a22073602d4012002200941016a3602d001200641034f0d00200741034b0d02200241e0016a10db010c010b200241e0016a10db010b411a21010c020b2009280001210720022001417b6a3602d4012002200941056a3602d00120022802e0012101200241206a200241e0016a41047241ac0110dc041a200220022800d8013602182002200241db016a28000036001b2001411a460d01200241e0016a200241206a41ac0110dc041a2002200228001b3600db01200220022802183602d8010c020b41c00041011030000b200241003602e801200242013703e0012002410c3602242002200241106a3602202002200241e0016a3602d801200241a4036a4101360200200242013702940320024198c2c300360290032002200241206a3602a003200241d8016a41b8a3c50020024190036a102e1a20023502e80142208620023502e00184100820022802e401450d0020022802e00110230b2008450d00200410230b20024190036a200241e0016a41ac0110dc041a200220022800db01360023200220022802d801360220024002402001411a470d002000411a3602000c010b20002001360200200041046a20024190036a41ac0110dc041a200041b8016a20063a0000200041b4016a2007360200200041b0016a2005360200200020022802203600b901200041bc016a20022800233600000b20031023200241c0046a24000b130020004111360204200041d0f5c0003602000b3400200041aefcc40036020420004100360200200041146a410f360200200041106a41bc93c100360200200041086a42093702000b5f01027f230041c0016b220224002002411a3602080240410110212203450d00200341003a000020004281808080103702042000200336020002402002280208411a460d00200241086a10db010b200241c0016a24000f0b410141011030000bfc0201057f230041c0006b22022400200241206a4200370300200241186a4200370300200241086a41086a4200370300200241003a0028200242003703082002410036023820024201370330200241086a200241306a107102400240024020022d0028220341064b0d000240024002400240024002400240024020030e0700010203040506000b410021040c060b410121040c050b410221040c040b410321040c030b410421040c020b410521040c010b410621040b200220043a003f02400240200228023420022802382203460d00200228023021050c010b200341016a22052003490d03200341017422062005200620054b1b22064100480d030240024020030d002006102121050c010b200228023020032006102521050b2005450d022002200636023420022005360230200228023821030b2002200341016a360238200520036a20043a00000b20002002290330370200200041086a200241306a41086a280200360200200241c0006a24000f0b200641011030000b102a000b3f01017f230041106b22022400200241003602082002420137030041002002105c200041086a200228020836020020002002290300370200200241106a24000b130020004106360204200041f8aec1003602000b3201017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200241c093063600000b3101017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200241d8043600000b3c01017f02404110102122020d00411041011030000b2002420037000820024280a094a58d1d370000200042908080808002370204200020023602000b3201017f02404104102122020d00410441011030000b20004284808080c000370204200020023602002002418084073600000ba9f40107017f027e017f017e137f027e027f23004190096b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e12000102030405060708090a0b0c0d0e111215000b200341ec046a4101360200200342013702dc04200341d09dc6003602d804200341043602dc01200341849ec6003602d8012003200341d8016a3602e804200341d8046a41a8b8c1001038000b200141106a2903002104200141086a2903002105200141046a28020021062002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241046a2d00002115200241026a2f0100211602400240024020022d0000450d00200320073702dc04200320083a00db04200320093a00da042003200a3b01d8040c010b200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703d80441002102201a41ff01714101460d010b410121024102211941002117410021180b200320073703b003200320083a00af03200320093a00ae032003200a3b01ac032003200b3a00ab032003200c3a00aa032003200d3b01a8032003200e3a00a7032003200f3a00a603200320103b01a403200320113a00a303200320123a00a203200320133b01a003200320143a009f03200320153a009a03200320163b0198032003201841ffff0371410874201741187472201941ff017172220a36009b0302402002450d00410f210841aab0c00021090240024002400240200a0e050001020363000b200328009f03210920032800a30321080c620b410e210841aabac60021090c610b411321084197b0c00021090c600b411121084186b0c00021090c5f0b20034198066a41186a20034198036a41186a29030037030020034198066a41106a20034198036a41106a29030037030020034198066a41086a20034198036a41086a290300370300200320032903980337039806024020054280a094a58d1d5441002004501b450d0041b8b8c1002109410d21080c5f0b200341086a20034198066a2005200410f10102402003280208450d0041c5b8c1002109411a21080c5f0b20034198016a41186a220a420037030020034198016a41106a2208420037030020034198016a41086a220942003703002003420037039801200341b0086a41086a220241aefcc400ad428080808090018422071003221741086a290000370300200320172900003703b0082017102320092002290300370300200320032903b008221b3703b8012003201b37039801200241e49dc100ad4280808080f00184221c1003221741086a290000370300200320172900003703b00820171023200820032903b008221b370300200341f8006a41086a22182009290300370300200341f8006a41106a2219201b370300200341f8006a41186a220b20022903003703002003201b3703c80120032003290398013703782003200341f8006a4120108f012003280204210c2003280200210d200a420037030020084200370300200942003703002003420037039801200220071003221741086a290000370300200320172900003703b0082017102320092002290300370300200320032903b008221b3703b8012003201b370398012002201c1003221741086a290000370300200320172900003703b00820171023200a2002290300221b37030020182009290300370300201920032903b008221c370300200b201b3703002003201c3703c80120032003290398013703782003200c4100200d1b221741016a3602d804200341f8006aad4280808080800484221b200341d8046aad4280808080c00084221c1002200320034198066a3602d801200220071003221841086a290000370300200320182900003703b00820181023200341b8016a41086a22192002290300370300200320032903b0083703b801200241f0f3c000ad42808080809001841003221841086a290000370300200320182900003703b00820181023200341c8016a41086a22182002290300370300200320032903b0083703c801200320173602d80420034198036a41186a220b201c1001220241186a29000037030020034198036a41106a220c200241106a29000037030020034198036a41086a220d200241086a290000370300200320022900003703980320021023200a200b2903003703002008200c2903003703002009200d29030037030020032003290398033703980141c00010212202450d17200220032903b801370000200241086a2019290300370000200220032903c801370010200241186a20182903003700002002200329039801370020200241286a2009290300370000200241306a2008290300370000200241386a200a290300370000411010212209450d1820092005370000200920043700082003429080808080023702dc04200320093602d8044101200341d8046a105c20032802d801200341d8046a107120032802dc0421092002ad428080808080088420033502e00442208620032802d804220aad84100202402009450d00200a10230b20021023200341d8016a41106a20034198066a41086a290300370300200341d8016a41186a20034198066a41106a290300370300200341f8016a20034198066a41186a290300370300200320063602dc01200320173602d80120032003290398063703e0012003200341d8016a3602e80820034198016a41186a220a420037030020034198016a41106a2218420037030020034198016a41086a220942003703002003420037039801200341b0086a41086a220241aefcc400ad42808080809001841003220641086a290000370300200320062900003703b0082006102320092002290300370300200320032903b00822073703b8012003200737039801200241d5f3c000ad4280808080b001841003220641086a290000370300200320062900003703b00820061023200341c8016a41086a20022903002207370300200320032903b008221c3703c8012008201c370000200841086a2007370000200341f8006a41086a2009290300370300200341f8006a41106a2018290300370300200341f8006a41186a200a290300370300200320032903980137037820034198036a201b1004109001024002402003280298032209450d0020034198036a41086a2802002102200328029c0321060c010b200341003602e004200342013703d8044100200341d8046a105c20032802e004210220032802dc04210620032802d80421090b200320023602d008200320063602cc08200320093602c808024002402002450d00200341d8046a200920024101106920032802d8044101470d0120032802cc08450d5c20032802c80810230c5c0b4101200341c8086a105c20032802e8082206280200210a0240024020032802cc08220920032802d00822026b4104490d0020032802c80821090c010b200241046a22182002490d5f200941017422022018200220184b1b22024100480d5f0240024020090d002002102121090c010b20032802c80820092002102521090b2009450d1b200320023602cc08200320093602c80820032802d00821020b2003200241046a3602d008200920026a200a3600002006280204200341c8086a10cb01200641086a200341c8086a10710c590b20032802dc04210a0240200341e4046a2802002202200341e0046a2802002209460d0020032802d008200220096b6a220641046a2218417f4c0d1b0240024020180d00410121190c010b201810212219450d1d0b200320183602ec07200320193602e807200320063602f0072003200341e8076a3602d804200a200341d8046a200210920120062002490d1d20032802f007220a2006490d1e20032802d008220a2009490d1f20032802e807211820032802c80821192003200620026b22063602c8012003200a20096b220a3602582006200a470d20201820026a201920096a200610dc041a20032802e8082209280200210a0240024020032802ec07220620032802f00722026b4104490d0020032802e80721060c010b200241046a22182002490d5f200641017422022018200220184b1b22024100480d5f0240024020060d002002102121060c010b20032802e80720062002102521060b2006450d22200320023602ec07200320063602e80720032802f00721020b2003200241046a3602f007200620026a200a3600002009280204200341e8076a10cb01200941086a200341e8076a107120032802f007210920032802ec07210620032802e807210220032802cc08450d5a20032802c80810230c5a0b2003200341c8086a3602d804200a200341d8046a200910920120032802e8082209280200210a0240024020032802cc08220620032802d00822026b4104490d0020032802c80821060c010b200241046a22182002490d5e200641017422022018200220184b1b22024100480d5e0240024020060d002002102121060c010b20032802c80820062002102521060b2006450d22200320023602cc08200320063602c80820032802d00821020b2003200241046a3602d008200620026a200a3600002009280204200341c8086a10cb01200941086a200341c8086a10710c580b200141046a28020021162002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f01002106200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d00200320073702dc04200320083a00db04200320093a00da04200320063b01d8040c010b200241086a2d0000210a200241066a2f01002117200241056a2d0000211820022d0001211a200320073703d80441002102201a41ff01714101460d010b41012102410221184100210a410021170b200320073703b003200320083a00af03200320093a00ae03200320063b01ac03200320193a00ab032003200b3a00aa032003200c3b01a8032003200d3a00a7032003200e3a00a6032003200f3b01a403200320103a00a303200320113a00a203200320123b01a003200320133a009f03200320143a009a03200320153b0198032003201741ffff0371410874200a41187472201841ff017172220636009b0302402002450d00410f210841aab0c0002109024020060e050015165556000b200328009f03210920032800a3032108410121060c560b200341d8016a41186a20034198036a41186a290300370300200341d8016a41106a20034198036a41106a290300370300200341d8016a41086a20034198036a41086a29030037030020032003290398033703d801200341d8046a201610dc01024020032802e80422060d0041dfb8c100210941242108410121060c560b200341d8046a41186a280200210820032802ec042102200341106a200341d8016a20032902dc04220742208620033502d804842204200341e4046a350200422086200742208884220710f10120032802100d52200341f8006a41186a200341d8016a41186a290300370300200341f8006a41106a2209200341d8016a41106a290300370300200341f8006a41086a2217200341d8016a41086a290300370300200320032903d8013703780240024020082002460d002002210a200821020c010b200241016a220a2002490d5d20024101742218200a2018200a4b1b220a41ffffff3f71200a470d5d200a41057422184100480d5d0240024020020d002018102121060c010b200620024105742018102521060b2006450d350b200620024105746a22022003290378370000200241186a200341f8006a41186a290300370000200241106a2009290300370000200241086a2017290300370000200341b0086a41086a220241aefcc400ad42808080809001841003220941086a290000370300200320092900003703b00820091023200341b8016a41086a2002290300370300200320032903b0083703b801200241f0f3c000ad42808080809001841003220941086a290000370300200320092900003703b00820091023200341c8016a41086a2002290300370300200320032903b0083703c801200320163602d80420034198036a41186a2209200341d8046aad4280808080c000841001220241186a29000037030020034198036a41106a2217200241106a29000037030020034198036a41086a2218200241086a29000037030020032002290000370398032002102320034198016a41186a2202200929030037030020034198016a41106a201729030037030020034198016a41086a201829030037030020032003290398033703980141c00010212209450d21200920032903b801370000200941086a200341b8016a41086a290300370000200920032903c801370010200941186a200341c8016a41086a2903003700002009200329039801370020200941286a20034198016a41086a290300370000200941306a20034198016a41106a290300370000200941386a2002290300370000411010212202450d2220022004370000200220073700082003429080808080023702dc04200320023602d804200841016a2202200341d8046a105c02402002450d00200841057441206a21082006210203402002200341d8046a1071200241206a2102200841606a22080d000b0b20032802dc0421022009ad428080808080088420033502e00442208620032802d8042208ad84100202402002450d00200810230b20091023200a450d50200610230c500b200141026a2d00002116200141046a280200211a20012d0001211d2002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f01002106200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d00200320073702dc04200320083a00db04200320093a00da04200320063b01d8040c010b200241086a2d0000210a200241066a2f01002117200241056a2d0000211820022d0001211e200320073703d80441002102201e41ff01714101460d010b41012102410221184100210a410021170b200320073703b001200320083a00af01200320093a00ae01200320063b01ac01200320193a00ab012003200b3a00aa012003200c3b01a8012003200d3a00a7012003200e3a00a6012003200f3b01a401200320103a00a301200320113a00a201200320123b01a001200320133a009f01200320143a009a01200320153b0198012003201741ffff0371410874200a41187472201841ff017172220636009b0102402002450d00410f210841aab0c000210920060e050c131453540c0b200341f8006a41186a20034198016a41186a2903002207370300200341f8006a41106a20034198016a41106a2903002204370300200341f8006a41086a20034198016a41086a29030022053703002003200329039801221b370378200341d8046a41186a2007370300200341d8046a41106a2004370300200341d8046a41086a20053703002003201b3703d804200341d8046a201a201d41ff0171410047201610f20121090c4e0b200141026a2d00002116200141046a280200211a20012d0001211d2002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f01002106200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d00200320073702dc04200320083a00db04200320093a00da04200320063b01d8040c010b200241086a2d0000210a200241066a2f01002117200241056a2d0000211820022d0001211e200320073703d80441002102201e41ff01714101460d010b41012102410221184100210a410021170b2003200737039001200320083a008f01200320093a008e01200320063b018c01200320193a008b012003200b3a008a012003200c3b0188012003200d3a0087012003200e3a0086012003200f3b018401200320103a008301200320113a008201200320123b018001200320133a007f200320143a007a200320153b01782003201741ffff0371410874200a41187472201841ff017172220636007b02402002450d00410f210841aab0c000210920060e050f121352530f0b200341d8046a41186a200341f8006a41186a290300370300200341d8046a41106a200341f8006a41106a290300370300200341d8046a41086a200341f8006a41086a290300370300200320032903783703d804200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b00820081023200341b8016a41086a2002290300370300200320032903b0083703b8012002418ca1c100ad4280808080d000841003220841086a290000370300200320082900003703b00820081023200341c8016a41086a2002290300370300200320032903b0083703c80120034198016a200341d8046a10ac0141c00010212202450d21200220032903b801370000200241086a200341b8016a41086a290300370000200220032903c801370010200241186a200341c8016a41086a2903003700002002200329039801370020200241286a20034198016a41086a2209290300370000200241306a20034198016a41106a2206290300370000200241386a20034198016a41186a2208290300370000200341d8046a200241c000108a012009200341e1046a2900003703002006200341e9046a2900003703002008200341f1046a290000370300200320032900d90437039801410121060240024020032d00d8044101460d004100210a0c010b200341da006a20032d009a013a0000200341c8076a41086a200341ab016a290000370300200341d5076a2008290000370000200320032f0198013b0158200320032900a3013703c8074101210a200328009f012108200328009b0121090b2002102302400240200a0d00410b2108419db9c10021090c010b200341e8086a41026a200341d8006a41026a2d00003a0000200341e8076a41086a200341c8076a41086a290300370300200341e8076a410d6a200341c8076a410d6a290000370000200320032f01583b01e808200320032903c8073703e807410021060b20034180096a41026a2202200341e8086a41026a2d00003a0000200341c8086a41086a220a200341e8076a41086a290300370300200341c8086a41106a200341e8076a41106a290300370300200320032f01e8083b018009200320032903e8073703c80820060d5220034198036a41026a20022d000022023a0000200341d8016a41086a2206200a290300370300200341d8016a410d6a220a200341c8086a410d6a290000370000200320032f01800922173b019803200320032903c8083703d801200341eb046a2006290300370000200341f0046a200a290000370000200320023a00da04200320173b01d804200320083600df04200320093600db04200320032903d8013700e304200341d8046a201a201d41ff0171410047201610f20121090c4d0b419cbac6002109410e210820022d0000417f6a221941034b0d51200141046a280200210b4101210641012117410121184101210a0240024020190e04005d5d01000b200241046a2d00000d524101210641012117410121184101210a200241086a28020041036c2002410c6a280200410174490d5c0b200341d8046a200b10e501024020032802d8042202411a470d00418ebbc1002109410d2108410121060c530b20034198036a200341d8046a41047241bc0110dc041a200320023602d801200341d8016a41047220034198036a41bc0110dc041a200341003602e004200342013703d804200341d8016a200341d8046a10cb0120032802dc04210820034198036a41186a220920033502e00442208620032802d8042217ad841001220241186a29000037030020034198036a41106a2206200241106a29000037030020034198036a41086a220a200241086a29000037030020032002290000370398032002102320034198066a41186a2202200929030037030020034198066a41106a2209200629030037030020034198066a41086a2206200a29030037030020032003290398033703980602402008450d00201710230b200341d8046a41186a2002290300370300200341d8046a41106a2009290300370300200341d8046a41086a200629030037030020032003290398063703d804200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b00820081023200341b8016a41086a2002290300370300200320032903b0083703b801200241a8a3c100ad4280808080d001841003220841086a290000370300200320082900003703b00820081023200341c8016a41086a2002290300370300200320032903b0083703c80120034198016a200341d8046a10ac0141c00010212202450d21200220032903b801370000200241086a200341b8016a41086a2209290300370000200220032903c801370010200241186a200341c8016a41086a220a2903003700002002200329039801370020200241286a20034198016a41086a290300370000200241306a20034198016a41106a290300370000200241386a20034198016a41186a29030037000041012106200341186a200241c00041014100410010b801200328021821082002102320084101470d4b200341d8016a10db01419bbbc1002109412521080c520b200141046a2802002106419cbac6002109410e210820022d0000417f6a220a41034b0d4902400240200a0e04004b4b01000b200241086a2802004101742002410c6a280200490d4a200241046a28020041ff01710d4a0b20034198016a41186a420037030020034198016a41106a220a420037030020034198016a41086a220842003703002003420037039801200341b0086a41086a220241aefcc400ad42808080809001841003220941086a290000370300200320092900003703b0082009102320082002290300370300200320032903b00822073703b8012003200737039801200241a8f5c000ad4280808080c001841003220941086a290000370300200320092900003703b00820091023200a20032903b0082207370300200341f8006a41086a2008290300370300200341f8006a41106a2007370300200341f8006a41186a2002290300370300200320073703c8012003200329039801370378200341286a200341f8006a412041014100410010b801024020032802284101470d0041c2b9c1002109411521080c4a0b200341003602e004200342013703d8042006200341d8046a10cb0120032802dc04210820034198036a41186a220920033502e00442208620032802d8042219ad841001220241186a29000037030020034198036a41106a2217200241106a29000037030020034198036a41086a2218200241086a290000370300200320022900003703980320021023200341d8016a41186a2009290300370300200341d8016a41106a2017290300370300200341d8016a41086a201829030037030020032003290398033703d80102402008450d00201910230b200341d8046a41186a200341d8016a41186a290300370300200341d8046a41106a200341d8016a41106a290300370300200341d8046a41086a200341d8016a41086a290300370300200320032903d8013703d804200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b00820081023200341b8016a41086a22092002290300370300200320032903b0083703b801200241dca2c100ad42808080809001841003220841086a290000370300200320082900003703b00820081023200341c8016a41086a22082002290300370300200320032903b0083703c80120034198016a200341d8046a10ac0141c00010212202450d21200220032903b801370000200241086a2009290300370000200220032903c801370010200241186a20082903003700002002200329039801370020200241286a20034198016a41086a290300370000200241306a20034198016a41106a290300370000200241386a20034198016a41186a290300370000200341d8046a200241c00010f30120032802d804211820032903e004210420032802dc0421082002102302402008450d00200341d8046a41186a4200370300200341d8046a41106a22194200370300200341d8046a41086a22094200370300200342003703d804200341b0086a41086a220241c4fbc400ad4280808080e000841003221741086a290000370300200320172900003703b0082017102320092002290300370300200320032903b0083703d804200241f9bcc000ad4280808080e000841003221741086a290000370300200320172900003703b00820171023201920032903b008220737030020034198036a41086a200929030037030020034198036a41106a200737030020034198036a41186a20022903003703002003200737039806200320032903d80437039803200341206a20034198036a4120108f012003280224410020032802201b210202402004a7450d00200810230b200220184f0d0041a8b9c1002109411a21080c4a0b200341d8046a200641b00110dd041a200341003a00880620034198016a41186a2217420037030020034198016a41106a2218420037030020034198016a41086a220842003703002003420037039801200341b0086a41086a220241aefcc400ad42808080809001841003220941086a290000370300200320092900003703b0082009102320082002290300370300200320032903b00822073703b8012003200737039801200241a8f5c000ad4280808080c001841003220941086a290000370300200320092900003703b00820091023200341c8016a41086a20022903002207370300200320032903b00822043703c801200a2004370000200a41086a2007370000200341f8006a41086a2008290300370300200341f8006a41106a2018290300370300200341f8006a41186a20172903003703002003200329039801370378200341003602a0032003420137039803200341d8046a20034198036a10cb01024020032d008806220241024b0d00024002400240024020020e03000102000b410021080c020b410121080c010b410221080b200320083a00b00802400240200328029c0320032802a0032202460d0020032802980321090c010b200241016a22082002490d5a200241017422092008200920084b1b22084100480d5a0240024020020d002008102121090c010b20032802980320022008102521090b2009450d242003200836029c03200320093602980320032d00b008210820032802a00321020b2003200241016a3602a003200920026a20083a00000b200328029c032102200341f8006aad428080808080048420033502a0034220862003280298032208ad84100202402002450d00200810230b200341d8046a10db012006102341002106410121170c470b200141046a28020021080240024020022d0000417f6a220941034b0d00024020090e0400010102000b200241086a2802004101742002410c6a280200490d00200241046a28020041ff0171450d010b200810db0120081023419cbac6002109410e21084100211741012106410121180c520b200341d8046a200841b00110dc041a200341023a00880620034198016a41186a420037030020034198016a41106a220a420037030020034198016a41086a220942003703002003420037039801200341b0086a41086a220241aefcc400ad42808080809001841003220641086a290000370300200320062900003703b0082006102320092002290300370300200320032903b00822073703b8012003200737039801200241a8f5c000ad4280808080c001841003220641086a290000370300200320062900003703b00820061023200a20032903b0082207370300200341f8006a41086a2009290300370300200341f8006a41106a2007370300200341f8006a41186a2002290300370300200320073703c8012003200329039801370378200341003602e001200342013703d801200341d8046a200341d8016a10cb01024020032d008806220241024b0d00024002400240024020020e03000102000b410021090c020b410121090c010b410221090b200320093a00b0080240024020032802dc0120032802e0012202460d0020032802d80121060c010b200241016a22092002490d59200241017422062009200620094b1b22094100480d590240024020020d002009102121060c010b20032802d80120022009102521060b2006450d24200320093602dc01200320063602d80120032d00b008210920032802e00121020b2003200241016a3602e001200620026a20093a00000b20032802dc012102200341f8006aad428080808080048420033502e00142208620032802d8012209ad84100202402002450d00200910230b200341d8046a10db012008102341002117410121060c460b200141046a28020021080240024020022d0000417f6a220941034b0d00024020090e0400010102000b200241086a2802002002410c6a280200490d00200241046a28020041ff0171450d010b200810db0120081023419cbac6002109410e21084100211841012106410121170c510b200341d8046a200841b00110dc041a200341013a00880620034198016a41186a420037030020034198016a41106a220a420037030020034198016a41086a220942003703002003420037039801200341b0086a41086a220241aefcc400ad42808080809001841003220641086a290000370300200320062900003703b0082006102320092002290300370300200320032903b00822073703b8012003200737039801200241a8f5c000ad4280808080c001841003220641086a290000370300200320062900003703b00820061023200a20032903b0082207370300200341f8006a41086a2009290300370300200341f8006a41106a2007370300200341f8006a41186a2002290300370300200320073703c8012003200329039801370378200341003602e001200342013703d801200341d8046a200341d8016a10cb01024020032d008806220241024b0d00024002400240024020020e03000102000b410021090c020b410121090c010b410221090b200320093a00b0080240024020032802dc0120032802e0012202460d0020032802d80121060c010b200241016a22092002490d58200241017422062009200620094b1b22094100480d580240024020020d002009102121060c010b20032802d80120022009102521060b2006450d24200320093602dc01200320063602d80120032d00b008210920032802e00121020b2003200241016a3602e001200620026a20093a00000b20032802dc012102200341f8006aad428080808080048420033502e00142208620032802d8012209ad84100202402002450d00200910230b200341d8046a10db01200810234100211841012106410121170c460b200141286a2802002117200141246a280200210a20034180086a200141196a290000370300200341f8076a200141116a290000370300200341e8076a41086a200141096a290000370300200320012900013703e807419cbac6002109410e210820022d0000417e6a220641024b0d4d0240024020060e03004f01000b200241046a2d00000d4e200241086a28020041036c2002410c6a280200410174490d4e0b20034198016a41186a42003703004110210820034198016a41106a2218420037030020034198016a41086a220942003703002003420037039801200341b0086a41086a220241aefcc400ad42808080809001841003220641086a290000370300200320062900003703b0082006102320092002290300370300200320032903b00822073703b8012003200737039801200241a8f5c000ad4280808080c001841003220641086a290000370300200320062900003703b00820061023201820032903b0082207370300200341f8006a41086a2009290300370300200341f8006a41106a2007370300200341f8006a41186a2002290300370300200320073703c8012003200329039801370378200341d8046a200341f8006a10d60120032802d804210220034198036a200341d8046a41047241ac0110dc041a20032003280089063602c80720032003418c066a2800003600cb0702402002411a470d00418dbac1002109410121060c4f0b20034188066a2d0000210820034198066a20034198036a41ac0110dc041a200320023602d801200341d8016a41047220034198066a41ac0110dc041a200841ff01710d4241e3b9c1002109412a21080c430b200341e0086a200141196a290000370300200341c8086a41106a200141116a290000370300200341c8086a41086a200141096a290000370300200320012900013703c808200241216a2f0000200241236a2d00004110747221082002411d6a2f00002002411f6a2d00004110747221092002410d6a2f00002002410f6a2d0000411074722106200241096a2f00002002410b6a2d000041107472210a200241056a2f0000200241076a2d0000411074722117200241206a2d0000210b200241106a2d0000210c2002410c6a2d0000210d200241086a2d0000210e0240024020022d00004102460d00410121180c010b200241246a2802002119200241116a2900002107200241046a2d0000210f2003200241196a2800003602e004200320073703d804410121180240200f4101460d000c010b2007421888a7210f2007a721024100211820032902dc0421070b200320083b01b403200341b6036a20084110763a0000200320093b01b00320034198036a411a6a20094110763a0000200320023b01a403410e210820034198036a410e6a20024110763a0000200320063b01a003200341a2036a20064110763a0000200320193a00b7032003200b3a00b303200320073703a8032003200f3a00a7032003200c3a00a3032003200d3a009f032003200e3a009b032003200a3b019c032003200a4110763a009e03200320173b019803200320174110763a009a0302402018450d00419cbac6002109410121060c4e0b200341e8076a41186a20034198036a41186a2206290300370300200341e8076a41106a20034198036a41106a2217290300370300200341e8076a41086a20034198036a41086a221829030037030020032003290398033703e80720034198016a41186a420037030020034198016a41106a220a420037030020034198016a41086a220842003703002003420037039801200341b0086a41086a220241aefcc400ad42808080809001841003220941086a290000370300200320092900003703b0082009102320082002290300370300200320032903b00822073703b8012003200737039801200241a8f5c000ad4280808080c001841003220941086a290000370300200320092900003703b00820091023200a20032903b0082207370300200341f8006a41086a2008290300370300200341f8006a41106a2007370300200341f8006a41186a2002290300370300200320073703c8012003200329039801370378200341d8046a200341f8006a10d60120032802d804210220034198036a200341d8046a410472220841ac0110dc041a20032003418c066a2800003600cb0720032003280089063602c80702402002411a460d00200341d8016a20034198036a41ac0110dc041a200320023602d8042008200341d8016a41ac0110dc041a200341003602a0032003420137039803200341d8046a20034198036a10cb01200328029c032108200620033502a0034220862003280298032209ad841001220241186a2900003703002017200241106a2900003703002018200241086a29000037030020032002290000370398032002102320034198066a41186a200629030037030020034198066a41106a201729030037030020034198066a41086a201829030037030020032003290398033703980602402008450d00200910230b200341c8086a20034198066a412010de042102200341d8046a10db0102402002450d0041102108419dbac1002109410121060c4f0b200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b00820081023200341b8016a41086a22092002290300370300200320032903b0083703b801200241dca2c100ad42808080809001841003220841086a290000370300200320082900003703b00820081023200341c8016a41086a22082002290300370300200320032903b0083703c80120034198016a200341c8086a10ac0141c00010212202450d22200220032903b801370000200241086a2009290300370000200220032903c801370010200241186a20082903003700002002200329039801370020200241286a20034198016a41086a290300370000200241306a20034198016a41106a290300370000200241386a20034198016a41186a290300370000200341d8046a200241c00010f30120032903e004210720032802e004211820032802dc042117200210234100210820170d364101211741002118410021190c370b4114210841adbac1002109410121060c4d0b4101210620022d000120022d0000720d33200141046a28020010e401410021090c480b4101210620022d000120022d0000720d322001410c6a280200210b200141086a2802002109200141046a2802002117200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b00820081023200341b8016a41086a2002290300370300200320032903b0083703b801200241aff3c000ad4280808080d001841003220841086a290000370300200320082900003703b00820081023200341c8016a41086a2002290300370300200320032903b0083703c801200320173602d80420034198036a41186a2208200341d8046aad22044280808080c000841001220241186a29000037030020034198036a41106a220a200241106a29000037030020034198036a41086a2218200241086a29000037030020032002290000370398032002102320034198016a41186a2219200829030037030020034198016a41106a2208200a29030037030020034198016a41086a201829030037030020032003290398033703980141c00010212202450d20200220032903b801370000200241086a200341b8016a41086a290300370000200220032903c801370010200241186a200341c8016a41086a2903003700002002200329039801370020200241286a20034198016a41086a290300370000200241306a2008290300370000200241386a2019290300370000200341d8046a200241c00010f40120032902dc04210720032802d8042108200210232008410820081b210a024002400240024020092007420020081b2207422088a722024f0d00200a200941b8016c6a2208450d002008280200411a460d01200a200941b8016c6a220941b0016a280200200b470d01200810db012008411a360200200941046a20034198036a41ac0110dc041a200941b4016a200341cb076a280000360000200941b1016a20032800c807360000200341b0086a41086a220841aefcc400ad42808080809001841003220941086a290000370300200320092900003703b00820091023200341b8016a41086a22182008290300370300200320032903b0083703b801200841aff3c000ad4280808080d001841003220941086a290000370300200320092900003703b00820091023200341c8016a41086a22092008290300370300200320032903b0083703c801200320173602d80420034198036a41186a221720044280808080c000841001220841186a29000037030020034198036a41106a2219200841106a29000037030020034198036a41086a220b200841086a29000037030020032008290000370398032008102320034198016a41186a220c201729030037030020034198016a41106a2217201929030037030020034198016a41086a2219200b29030037030020032003290398033703980141c00010212208450d25200820032903b801370000200841086a2018290300370000200820032903c801370010200841186a20092903003700002008200329039801370020200841286a2019290300370000200841306a2017290300370000200841386a200c290300370000200341d8046a200a200210ca012008ad428080808080088420033502e00442208620032802d8042209ad841002024020032802dc04450d00200910230b20081023200241b8016c2108200a2102034002402002280200411a460d00200210db010b200241b8016a2102200841c87e6a22080d000b410021092007a70d030c4b0b2002450d010b200241b8016c2108200a2102034002402002280200411a460d00200210db010b200241b8016a2102200841c87e6a22080d000b0b41c0bbc1002109411221082007a7450d4c200a10230c4c0b200a10230c470b20034198066a41186a200141196a29000037030020034198066a41106a200141116a29000037030020034198066a41086a200141096a29000037030020032001290001370398062002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f01002106200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d00200320073702dc04200320083a00db04200320093a00da04200320063b01d8040c010b200241086a2d0000210a200241066a2f01002117200241056a2d0000211820022d00012116200320073703d80441002102201641ff01714101460d010b4101210241002117410221184100210a0b2003200737039001200320083a008f01200320093a008e01200320063b018c01200320193a008b012003200b3a008a012003200c3b0188012003200d3a0087012003200e3a0086012003200f3b018401200320103a008301200320113a008201200320123b018001200320133a007f200320143a007a200320153b01782003201741ffff0371410874201841ff017172200a41187472220636007b02402002450d00410f210841aab0c000210920060e0506090a494a060b20034198036a41186a200341f8006a41186a29030037030020034198036a41106a200341f8006a41106a29030037030020034198036a41086a200341f8006a41086a2903003703002003200329037837039803200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b00820081023200341b8016a41086a2002290300370300200320032903b0083703b8012002418ca1c100ad4280808080d000841003220841086a290000370300200320082900003703b00820081023200341c8016a41086a2002290300370300200320032903b0083703c80120034198016a20034198066a10ac0141c00010212202450d21200220032903b801370000200241086a200341b8016a41086a2209290300370000200220032903c801370010200241186a200341c8016a41086a22062903003700002002200329039801370020200241286a20034198016a41086a290300370000200241306a20034198016a41106a290300370000200241386a20034198016a41186a290300370000200341c0006a200241c00041014100410010b8012003280240210820021023024020084101470d0041e7bac1002109410f2108410121060c4b0b200341d8016a41186a20034198036a41186a290300370300200341d8016a41106a20034198036a41106a290300370300200341d8016a41086a20034198036a41086a29030037030020032003290398033703d801200341d8046a41186a20034198066a41186a290300370300200341d8046a41106a20034198066a41106a290300370300200341d8046a41086a20034198066a41086a29030037030020032003290398063703d804200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b0082008102320092002290300370300200320032903b0083703b8012002418ca1c100ad4280808080d000841003220841086a290000370300200320082900003703b0082008102320062002290300370300200320032903b0083703c80120034198016a200341d8046a10ac0141c00010212202450d22200220032903b801370000200241086a200341b8016a41086a290300370000200220032903c801370010200241186a200341c8016a41086a2903003700002002200329039801370020200241286a20034198016a41086a290300370000200241306a20034198016a41106a290300370000200241386a20034198016a41186a290300370000200341c0003602dc04200320023602d804200341d8016a200341d8046a10f501200210230c390b2002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f01002106200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d00200320073702dc04200320083a00db04200320093a00da04200320063b01d8040c010b200241086a2d0000210a200241066a2f01002117200241056a2d0000211820022d00012116200320073703d80441002102201641ff01714101460d010b4101210241002117410221184100210a0b200320073703b001200320083a00af01200320093a00ae01200320063b01ac01200320193a00ab012003200b3a00aa012003200c3b01a8012003200d3a00a7012003200e3a00a6012003200f3b01a401200320103a00a301200320113a00a201200320123b01a001200320133a009f01200320143a009a01200320153b0198012003201741ffff0371410874201841ff017172200a41187472220636009b012002450d01410f210841aab0c000210920060e050007084748000b200328009f01210920032800a3012108410121060c480b200341f8006a41186a20034198016a41186a2903002207370300200341f8006a41106a20034198016a41106a2903002204370300200341f8006a41086a20034198016a41086a29030022053703002003200329039801221b370378200341d8046a41186a2007370300200341d8046a41106a2004370300200341d8046a41086a20053703002003201b3703d804200341d8046a10f6010c420b20034198066a41186a200141196a29000037030020034198066a41106a200141116a29000037030020034198066a41086a200141096a29000037030020032001290001370398062002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f01002106200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d00200320073702dc04200320083a00db04200320093a00da04200320063b01d8040c010b200241086a2d0000210a200241066a2f01002117200241056a2d0000211820022d00012116200320073703d80441002102201641ff01714101460d010b4101210241002117410221184100210a0b2003200737039001200320083a008f01200320093a008e01200320063b018c01200320193a008b012003200b3a008a012003200c3b0188012003200d3a0087012003200e3a0086012003200f3b018401200320103a008301200320113a008201200320123b018001200320133a007f200320143a007a200320153b01782003201741ffff0371410874201841ff017172200a41187472220636007b02402002450d00410f210841aab0c000210920060e050205064546020b20034198036a41186a200341f8006a41186a29030037030020034198036a41106a200341f8006a41106a29030037030020034198036a41086a200341f8006a41086a2903003703002003200329037837039803200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b00820081023200341b8016a41086a2002290300370300200320032903b0083703b8012002418ca1c100ad4280808080d000841003220841086a290000370300200320082900003703b00820081023200341c8016a41086a2002290300370300200320032903b0083703c80120034198016a20034198066a10ac0141c00010212202450d1f200220032903b801370000200241086a200341b8016a41086a290300370000200220032903c801370010200241186a200341c8016a41086a2903003700002002200329039801370020200241286a20034198016a41086a2209290300370000200241306a20034198016a41106a2206290300370000200241386a20034198016a41186a2208290300370000200341d8046a200241c000108a012009200341e1046a2900003703002006200341e9046a2900003703002008200341f1046a290000370300200320032900d90437039801410121060240024020032d00d8044101460d004100210a0c010b200341da006a20032d009a013a0000200341c8076a41086a200341ab016a290000370300200341d5076a2008290000370000200320032f0198013b0158200320032900a3013703c8074101210a200328009f012108200328009b0121090b2002102302400240200a0d00410b2108419db9c10021090c010b200341e8086a41026a200341d8006a41026a2d00003a0000200341e8076a41086a200341c8076a41086a290300370300200341e8076a410d6a200341c8076a410d6a290000370000200320032f01583b01e808200320032903c8073703e807410021060b20034180096a41026a2202200341e8086a41026a2d00003a0000200341c8086a41086a220a200341e8076a41086a290300370300200341c8086a41106a200341e8076a41106a290300370300200320032f01e8083b018009200320032903e8073703c80820060d45200341eb016a200a290300370000200341d8016a41186a200341d5086a290000370000200320032f0180093b01d801200320083600df01200320093600db01200320032903c8083700e301200320022d00003a00da010240200341d8016a20034198036a412010de04450d0041f6bac1002109410b2108410121060c470b200341d8046a41186a20034198066a41186a290300370300200341d8046a41106a20034198066a41106a290300370300200341d8046a41086a20034198066a41086a29030037030020032003290398063703d804200341d8046a10f6010c350b200141216a2d0000210a200341d8006a41186a200141196a290000370300200341d8006a41106a200141116a290000370300200341d8006a41086a200141096a290000370300200320012900013703582002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f01002106200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241046a2d00002115200241026a2f0100211602400240024020022d0000450d00200320073702dc04200320083a00db04200320093a00da04200320063b01d8040c010b200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703d80441002102201a41ff01714101460d010b410121024100211841022119410021170b2003200737039001200320083a008f01200320093a008e01200320063b018c012003200b3a008b012003200c3a008a012003200d3b0188012003200e3a0087012003200f3a008601200320103b018401200320113a008301200320123a008201200320133b018001200320143a007f200320153a007a200320163b01782003201841ffff0371410874201941ff017172201741187472220636007b2002450d01410f210841aab0c000210920060e050003044344000b200328007f21092003280083012108410121060c440b200341c8076a41186a200341f8006a41186a290300370300200341c8076a41106a200341f8006a41106a290300370300200341c8076a41086a200341f8006a41086a290300370300200320032903783703c807200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b00820081023200341b8016a41086a2002290300370300200320032903b0083703b801200241b2edc000ad4280808080b001841003220841086a290000370300200320082900003703b00820081023200341c8016a41086a2002290300370300200320032903b0083703c80120034198016a200341c8076a10ac0141c00010212202450d1d200220032903b801370000200241086a200341b8016a41086a290300370000200220032903c801370010200241186a200341c8016a41086a2903003700002002200329039801370020200241286a20034198016a41086a290300370000200241306a20034198016a41106a290300370000200241386a20034198016a41186a290300370000200341d8016a200241c000109e01024020032d00f90122084102470d002003200341c8076a36028009200341d8046a10e201200341e8076a20032802d804220820032802e004108a01024020032802dc04450d00200810230b024020032d00e8070d00200341d8046a10e20120032802d8042108200320032802e00436029c032003200836029803200341c8076a20034198036a10f50120032802dc04450d2a200810230c2a0b200341c8086a41186a20034181086a290000370300200341c8086a41106a200341f9076a290000370300200341c8086a41086a200341e8076a41096a290000370300200320032900e9073703c808200341f8006a200341c8086a109d01200341d8046a200328027822062003280280012217109e01024020032d00f9044102470d00200341003602a0062003420137039806200341b0086a41146a410f360200200341bc086a410c360200200341093602cc01200341aefcc4003602c8012003410c3602b4082003410b36029c01200341b2edc000360298012003200341f8006a3602c008200320034198016a3602b8082003200341c8016a3602b008200320034198066a3602b80120034198036a41146a41033602002003420337029c03200341e4ddc000360298032003200341b0086a3602a803200341b8016a41b8a3c50020034198036a102e1a20033502a006422086200335029806841008200328028009210920034198036a10e2012003280298032108200320032802a00336029c012003200836029801200920034198016a10f5010240200328029c03450d00200810230b0240200328029c06450d0020032802980610230b200328027c450d2a200328027810230c2a0b20034198036a200341f9046a41c20010dc041a20032d00b903210820034198066a41206a2209200341d8046a41206a2d00003a000020034198066a41186a200341d8046a41186a29030037030020034198066a41106a200341d8046a41106a29030037030020034198066a41086a200341d8046a41086a290300370300200341c0066a200341ba036a410020084101461b360200200320032903d80437039806200320034180096a3602bc06200341003602a001200342013703980120034198066a20034198016a1071024020092d0000220841064b0d000240024002400240024002400240024020080e0700010203040506000b410021090c060b410121090c050b410221090c040b410321090c030b410421090c020b410521090c010b410621090b200320093a00b00802400240200328029c0120032802a0012208460d0020032802980121180c010b200841016a22092008490d4d200841017422182009201820094b1b22094100480d4d0240024020080d002009102121180c010b20032802980120082009102521180b2018450d212003200936029c01200320183602980120032d00b008210920032802a00121080b2003200841016a3602a001201820086a20093a00000b200341bc066a20034198016a10aa01200328029c0121082017ad4220862006ad8420033502a0014220862003280298012209ad84100202402008450d00200910230b0240200328027c450d00200328027810230b2003280280092109200341d8046a10e20120032802d8042108200320032802e00436029c032003200836029803200920034198036a10f501024020032802dc04450d00200810230b20034198066a41086a200341c8086a41086a29030037030020034198066a41106a200341c8086a41106a29030037030020034198066a41186a200341c8086a41186a290300370300200320032903c8083703980641012109410021080c2a0b20034198036a41186a20034192026a29010037030020034198036a41106a2003418a026a29010037030020034198036a41086a20034182026a29010037030020034198066a41086a200341a3026a29000037030020034198066a41106a200341ab026a29000037030020034198066a41186a200341b3026a290000370300200320032901fa013703980320032003419b026a290000370398062003419a026a2d000021090c290b2002411a6a2901002107200241196a2d0000210a200241186a2d00002117200241166a2f01002118200241156a2d00002110200241146a2d00002111200241126a2f01002112200241116a2d00002113200241106a2d000021192002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241046a2d00002114200241026a2f0100211502400240024020022d0000450d00200320073702dc042003200a3a00db04200320173a00da04200320183b01d8040c010b200241086a2d00002108200241066a2f01002109200241056a2d0000210620022d00012116200320073703d80441002102201641ff01714101460d010b410121024100210941022106410021080b200941ffff0371410874200641ff01717220084118747221062002450d02410f210841aab0c0002109024020060e050001024142000b200e410874200f72200d411874722109200b410874200c722019411874722108410121060c420b410e210841aabac6002109410121060c410b411321084197b0c0002109410121060c400b200320073703e0072003200a3a00df07200320173a00de07200320183b01dc07200320103a00db07200320113a00da07200320123b01d807200320133a00d707200320193a00d6072003200b3b01d4072003200c3a00d3072003200d3a00d2072003200e3b01d0072003200f3a00cf07200320063600cb07200320143a00ca07200320153b01c807200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b00820081023200341b8016a41086a2002290300370300200320032903b0083703b801200241b2edc000ad4280808080b001841003220841086a290000370300200320082900003703b00820081023200341c8016a41086a2002290300370300200320032903b0083703c80120034198036a200341c8076a10ac0141c00010212202450d1b200220032903b801370000200241086a200341b8016a41086a2209290300370000200220032903c801370010200241186a200341c8016a41086a22062903003700002002200329029803370020200241286a20034198036a41086a290200370000200241306a200341a8036a290200370000200241386a20034198036a41186a290200370000200341d0006a200241c00041014100410010b8012003280250210820021023024020084101460d004181bbc1002109410d2108410121060c400b200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b0082008102320092002290300370300200320032903b0083703b801200241b2edc000ad4280808080b001841003220841086a290000370300200320082900003703b0082008102320062002290300370300200320032903b0083703c80120034198036a200341c8076a10ac0141c00010212202450d1c200220032903b801370000200241086a200341b8016a41086a290300370000200220032903c801370010200241186a200341c8016a41086a2903003700002002200329029803370020200241286a20034198036a41086a290200370000200241306a20034198036a41106a290200370000200241386a20034198036a41186a290200370000200341d8046a200241c000109e01024020032d00f904220841024622090d002002ad428080808080088410050b200341c8086a41186a2206200341d8046a41186a290300370300200341c8086a41106a220a200341d8046a41106a290300370300200341c8086a41086a2217200341d8046a41086a290300370300200320032903d8043703c80820032d00f8042118200341e8076a200341d8046a41226a41c10010dc041a20034198016a41086a201729030037030020034198016a41106a200a29030037030020034198016a41186a2006290300370300200320032903c8083703980120034198066a200341e8076a41c10010dc041a4107210620090d22200341f8006a41186a20034198016a41186a290300370300200341f8006a41106a20034198016a41106a290300370300200341f8006a41086a20034198016a41086a2903003703002003200329039801370378200320083a00980320034198036a41017220034198066a41c10010dc04210620034198036a41226a21090240024020032d00b9034101460d00200341003602e8080c010b200341e8086a2009109d0120032d00980321080b024002400240200841ff01714101460d00200341003602b8010c010b200341b8016a2006109d0120032802b8010d010b024020032d00b9034101460d00200341d8046a10e20120033502e00442208620032802d8042208ad84100520032802dc04450d22200810230c220b200341d8046a10e20120032802d8042108200320032802e0043602dc01200320083602d8012009200341d8016a10f50120032802dc04450d21200810230c210b200341c8016a41086a200341b8016a41086a2802002209360200200320032903b80122073703c801200341d8016a2007a7220a2009109e01024020032d00f9014102470d00200341003602b808200342013703b008200341d8006a41146a410f360200200341e4006a410c360200200341093602fc08200341aefcc4003602f8082003410c36025c2003410b36028409200341b2edc000360280092003200341c8016a360268200320034180096a3602602003200341f8086a3602582003200341b0086a36028c09200341d8046a41146a4103360200200342033702dc04200341a8ddc0003602d8042003200341d8006a3602e8042003418c096a41b8a3c500200341d8046a102e1a20033502b80842208620033502b00884100820032802b408450d2020032802b00810230c200b200341d8046a200341d8016a41c20010dc041a200341ba056a200341b9036a220841206a2d00003a0000200341b2056a200841186a290000370100200341aa056a200841106a290000370100200341a2056a200841086a290000370100200341d8046a41c2006a20082900003701002003410036026020034201370358200341d8046a200341d8006a1071024020032d00f804220841064b0d000240024002400240024002400240024020080e0700010203040506000b410021060c060b410121060c050b410221060c040b410321060c030b410421060c020b410521060c010b410621060b200320063a00b00802400240200328025c20032802602208460d00200328025821170c010b200841016a22062008490d48200841017422172006201720064b1b22064100480d480240024020080d002006102121170c010b200328025820082006102521170b2017450d1f2003200636025c2003201736025820032d00b0082106200328026021080b2003200841016a360260201720086a20063a00000b200341f9046a200341d8006a10a901200328025c21082009ad422086200aad84200335026042208620032802582209ad8410022008450d1f200910230c1f0b41c00041011030000b411041011030000b200241011030000b102f000b201841011030000b20022006103e000b2006200a1036000b2009200a103e000b200341b0086a41146a410d360200200341bc086a410e36020020034198036a41146a41033602002003420337029c03200341acb6c600360298032003410e3602b4082003200341c8016a360298012003200341d8006a3602c807200342043703e804200342013702dc0420034180b7c6003602d8042003200341b0086a3602a8032003200341d8046a3602c0082003200341c8076a3602b808200320034198016a3602b00820034198036a41bcb7c6001038000b200241011030000b200241011030000b41c00041011030000b411041011030000b41c00041011030000b41c00041011030000b41c00041011030000b200841011030000b200941011030000b200941011030000b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000b200941011030000b41c00041011030000b41c00041011030000b200641011030000b201841011030000b024020032802cc01450d0020032802c80110230b410121090c010b410021090b0240024020032802e80822080d00410021060c010b200341c8016a41086a200341e8086a41086a280200220a360200200320032903e80822073703c801200341d8016a2007a72219200a109e010240024020032d00f9014102470d002003410036026020034201370358200341b0086a41146a410f360200200341bc086a410c360200200341093602fc08200341aefcc4003602f8082003410c3602b4082003410b36028409200341b2edc000360280092003200341c8016a3602c008200320034180096a3602b8082003200341f8086a3602b0082003200341d8006a36028c09200341d8046a41146a4103360200200342033702dc04200341ccdcc0003602d8042003200341b0086a3602e8042003418c096a41b8a3c500200341d8046a102e1a20033502604220862003350258841008200328025c450d01200328025810230c010b200341d8046a200341d8016a41e30010dc041a20034199056a200341b8036a2d00003a000020034191056a200341b0036a29030037000020034189056a200341a8036a29030037000020034181056a20034198036a41086a29030037000020032003290398033700f9042003410036026020034201370358200341d8046a200341d8006a1071024020032d00f804220641064b0d000240024002400240024002400240024020060e0700010203040506000b410021170c060b410121170c050b410221170c040b410321170c030b410421170c020b410521170c010b410621170b200320173a00b00802400240200328025c20032802602206460d002003280258210b0c010b200641016a22172006490d282006410174220b2017200b20174b1b22174100480d280240024020060d0020171021210b0c010b2003280258200620171025210b0b200b450d052003201736025c2003200b36025820032d00b0082117200328026021060b2003200641016a360260200b20066a20173a00000b200341f9046a200341d8006a10a901200328025c2106200aad4220862019ad8420033502604220862003280258220aad8410022006450d00200a10230b024020032802cc01450d0020032802c80110230b410121060b0240200920032802b801220a45720d0020032802bc01450d00200a10230b02402006200845720d0020032802ec08450d00200810230b201821060b20021023200341d8046a41186a4200370300200341d8046a41106a220a4200370300200341d8046a41086a22024200370300200342003703d804200341b0086a41086a220841c4fbc400ad4280808080e000841003220941086a290000370300200320092900003703b0082009102320022008290300370300200320032903b0083703d804200841f9bcc000ad4280808080e000841003220941086a290000370300200320092900003703b00820091023200a20032903b008220737030020034198036a41086a200229030037030020034198036a41106a200737030020034198036a41186a20082903003703002003200737039806200320032903d80437039803200341c8006a20034198036a4120108f01200342e4cab5fbb6ccdcb0e3003703d80141002109200341d8016a200341c8076a427f427f41002006200641ff01714107461b41187441187541027441c0b1c0006a280200418084076c200328024c410020032802481b6a410210f701200241093a0000200341d8046a41096a20032903c807370000200341e9046a200341c8076a41086a290300370000200341f1046a200341c8076a41106a290300370000200341f9046a200341c8076a41186a290300370000200341083a00d804200341d8046a108e01410121060c1c0b201741011030000b41002109410021080b200341e1046a20032903980337000020034181056a20093a000020034182056a200329039806370100200341e9046a20034198036a41086a290300370000200341f1046a20034198036a41106a290300370000200341f9046a20034198036a41186a2903003700002003418a056a20034198066a41086a29030037010020034192056a20034198066a41106a2903003701002003419a056a20034198066a41186a290300370100200320083a00e0042003200a3a00dc042003200341d8006a3602d804200341003602e001200342013703d801200341d8006a200341d8016a107102400240200a41064b0d0002400240024002400240024002400240200a0e0700010203040506000b410021090c060b410121090c050b410221090c040b410321090c030b410421090c020b410521090c010b410621090b200320093a00b0080240024020032802dc0120032802e0012208460d0020032802d80121060c010b200841016a22092008490d23200841017422062009200620094b1b22094100480d230240024020080d002009102121060c010b20032802d80120082009102521060b2006450d02200320093602dc01200320063602d80120032d00b008210920032802e00121080b2003200841016a3602e001200620086a20093a00000b200341d8046a41086a200341d8016a10a90120032802dc0121082002ad428080808080088420033502e00142208620032802d8012209ad84100202402008450d00200910230b20021023200342e4cab5fbb6ccdcb0e3003703e808200341e8086a200341c8076a417f10f801200341d8046a41086a41083a0000200341e1046a20032903c807370000200341e9046a200341c8076a41086a290300370000200341f1046a200341c8076a41106a290300370000200341f9046a200341c8076a41186a29030037000020034181056a200329035837000020034189056a200341d8006a41086a29030037000020034191056a200341d8006a41106a29030037000020034199056a200341d8006a41186a290300370000200341083a00d804200341d8046a108e010c150b200941011030000b4186b0c0002109411121080c180b2007a7211941002102024002402007422088a7220b41014b0d00200b0e020201020b200b210803402008410176220920026a22062002201720064105746a200341e8076a412010de044101481b2102200820096b220841014b0d000b0b201720024105746a200341e8076a412010de042208450d0a0c010b200341d8046a41186a200341e8076a41186a290300370300200341d8046a41106a200341e8076a41106a290300370300200341d8046a41086a200341e8076a41086a290300370300200320032903e8073703d804200341d8046a2109410021060c010b200341d8046a41186a200341e8076a41186a290300370300200341d8046a41106a200341e8076a41106a290300370300200341d8046a41086a200341e8076a41086a290300370300200320032903e8073703d8042008411f7620026a2206200b4b0d01200341d8046a2109200b21080b20082019460d01201821190c020b4180bbc000102b000b024020182008460d00201821190c010b201841016a22022018490d19201841017422192002201920024b1b221941ffffff3f712019470d19201941057422024100480d190240024020180d002002102121170c010b201720184105742002102521170b2017450d020b201720064105746a220241206a2002200820066b41057410dd041a200241186a200941186a290000370000200241106a200941106a290000370000200241086a200941086a29000037000020022009290000370000200341d8046a41186a4200370300200341d8046a41106a22184200370300200341d8046a41086a22094200370300200342003703d804200341b0086a41086a220241c4fbc400ad4280808080e000841003220641086a290000370300200320062900003703b0082006102320092002290300370300200320032903b0083703d804200241f9bcc000ad4280808080e000841003220641086a290000370300200320062900003703b00820061023201820032903b008220737030020034198036a41086a200929030037030020034198036a41106a200737030020034198036a41186a20022903003703002003200737039806200320032903d80437039803200341386a20034198036a4120108f0120032802382106200328023c2118200241aefcc400ad42808080809001841003220941086a290000370300200320092900003703b00820091023200341b8016a41086a220b2002290300370300200320032903b0083703b801200241dca2c100ad42808080809001841003220941086a290000370300200320092900003703b00820091023200341c8016a41086a220c2002290300370300200320032903b0083703c80120034198016a200341c8086a10ac0141c00010212209450d02200920032903b801370000200941086a200b290300370000200920032903c801370010200941186a200c2903003700002009200329039801370020200941286a20034198016a41086a290300370000200941306a20034198016a41106a290300370000200941386a20034198016a41186a290300370000410410212202450d0320034284808080c0003702dc04200320023602d8042002201841c093066a41c0930620061b2206360000200841016a2202200341d8046a105c02402002450d00200841057441206a21082017210203402002200341d8046a1071200241206a2102200841606a22080d000b0b20032802dc0421022009ad428080808080088420033502e00442208620032802d8042208ad84100202402002450d00200810230b2009102302402019450d00201710230b200341e1046a20032903e80737000020034181056a20032903c808370000200341083a00d804200341d8046a41086a410a3a0000200341f1046a200341e8076a41106a290300370000200341f9046a200341e8076a41186a29030037000020034191056a200341c8086a41106a29030037000020034199056a200341c8086a41186a290300370000200341e9046a200341e8076a41086a29030037000020034189056a200341c8086a41086a290300370000200341a4056a2006360200200341d8046a108e0120034198016a41186a2206420037030020034198016a41106a2217420037030020034198016a41086a220842003703002003420037039801200341b0086a41086a220241aefcc400ad42808080809001841003220941086a290000370300200320092900003703b0082009102320082002290300370300200320032903b00822073703b8012003200737039801200241a8f5c000ad4280808080c001841003220941086a290000370300200320092900003703b00820091023200341c8016a41086a20022903002207370300200320032903b00822043703c801200a2004370000200a41086a2007370000200341f8006a41086a2008290300370300200341f8006a41106a2017290300370300200341f8006a41186a20062903003703002003200329039801370378200341f8006aad428080808080048410050b41002109410121060c100b200241011030000b41c00041011030000b410441011030000b41c1bac1002109412621082019450d0b20171023410121060c0c0b200341003602e004200342013703d804200341d8016a200341d8046a10cb0120032802dc04210920034198036a41186a220620033502e00442208620032802d804220cad841001220241186a29000037030020034198036a41106a2219200241106a29000037030020034198036a41086a220b200241086a290000370300200320022900003703980320021023200341d8046a41186a2006290300370300200341d8046a41106a2019290300370300200341d8046a41086a200b29030037030020032003290398033703d80402402009450d00200c10230b0240200341e8076a200341d8046a412010de04450d0041d7b9c1002109410c21080c010b20034198016a41186a2219420037030020034198016a41106a220b420037030020034198016a41086a220942003703002003420037039801200341b0086a41086a220241aefcc400ad42808080809001841003220641086a290000370300200320062900003703b0082006102320092002290300370300200320032903b00822073703b8012003200737039801200241a8f5c000ad4280808080c001841003220641086a290000370300200320062900003703b00820061023200341c8016a41086a20022903002207370300200320032903b00822043703c80120182004370000201841086a2007370000200341f8006a41086a2009290300370300200341f8006a41106a200b290300370300200341f8006a41186a20192903003703002003200329039801370378200341f8006aad42808080808004841005200341d8046a41186a4200370300200341d8046a41106a22184200370300200341d8046a41086a22094200370300200342003703d804200241c4fbc400ad4280808080e000841003220641086a290000370300200320062900003703b0082006102320092002290300370300200320032903b0083703d804200241f9bcc000ad4280808080e000841003220641086a290000370300200320062900003703b00820061023201820032903b008220737030020034198036a41086a2218200929030037030020034198036a41106a200737030020034198036a41186a20022903003703002003200737039806200320032903d80437039803200341306a20034198036a4120108f012003280234210220032802302106200341d8046a200341d8016a41b00110dc041a4100210920034198036a2002410020061b200a41d804200a41d8044b1b6a200341d8046a2008201710d70102402003280298034101470d00200328029c032202450d002018280200210820022109410121060c0c0b410121060c0b0b200341d8016a10db01410121060c0a0b410121180b4101210a410021090c110b200610db01200610234101211741002106410121180c080b200341d8046a41186a20034198066a41186a290300370300200341d8046a41106a20034198066a41106a290300370300200341d8046a41086a20034198066a41086a29030037030020032003290398063703d804200341b0086a41086a220241aefcc400ad42808080809001841003220841086a290000370300200320082900003703b0082008102320092002290300370300200320032903b0083703b801200241a8a3c100ad4280808080d001841003220841086a290000370300200320082900003703b00820081023200a2002290300370300200320032903b0083703c80120034198016a200341d8046a10ac01024041c00010212202450d00200220032903b801370000200241086a200341b8016a41086a290300370000200220032903c801370010200241186a200341c8016a41086a2903003700002002200329039801370020200241286a20034198016a41086a290300370000200241306a200341a8016a290300370000200241386a20034198016a41186a29030037000041012106200341013a00d8042002ad4280808080800884200341d8046aad42808080801084100220021023200b10e401200341d8016a10db01410021090c030b41c00041011030000b41222108410121060c050b41002109410121060b41012117410121184101210a0c0c0b4183b9c1002109411a21082002450d0120061023410121060c020b411121084186b0c00021090b410121060b41012117410121180b4101210a0c070b20032802d008210920032802cc08210620032802c80821020b2002450d00201b2009ad4220862002ad8410022006450d01200210230c010b20034198016a41186a220a420037030020034198016a41106a2218420037030020034198016a41086a220942003703002003420037039801200341b0086a41086a220241aefcc400ad42808080809001841003220641086a290000370300200320062900003703b0082006102320092002290300370300200320032903b00822073703b8012003200737039801200241d5f3c000ad4280808080b001841003220641086a290000370300200320062900003703b00820061023200341c8016a41086a20022903002207370300200320032903b008221c3703c8012008201c370000200841086a2007370000200341f8006a41086a2009290300370300200341f8006a41106a2018290300370300200341f8006a41186a200a2903003703002003200329039801370378200341003602e004200342013703d8044101200341d8046a105c20032802e808220828020021060240024020032802dc04220920032802e00422026b4104490d0020032802d80421090c010b200241046a220a2002490d0320094101742202200a2002200a4b1b22024100480d030240024020090d002002102121090c010b20032802d80420092002102521090b2009450d02200320023602dc04200320093602d80420032802e00421020b2003200241046a3602e004200920026a20063600002008280204200341d8046a10cb01200841086a200341d8046a107120032802dc042102201b20033502e00442208620032802d8042208ad8410022002450d00200810230b200341f0046a2004370300200341e8046a2005370300200341e4046a2017360200200341083a00d8044100210a200341d8046a41086a41003a0000200341d8046a108e0120032802dc0110db0120032802dc011023410121064101211741012118410021090c030b200241011030000b102a000b200610db01200610234100210a4101210641012117410121180b0240024020012d0000417f6a2202410f4b0d00024002400240024020020e1000040404040102030404040405040505000b200a450d04200141046a220228020010db01200228020010230c040b2006450d03200141046a220228020010db01200228020010230c030b2017450d02200141046a220228020010db01200228020010230c020b2018450d01200141046a220228020010db01200228020010230c010b200241074b0d00024002400240024020020e080004040404010203000b200141046a220228020010db01200228020010230c030b200141046a220228020010db01200228020010230c020b200141046a220228020010db01200228020010230c010b200141046a220228020010db01200228020010230b200020083602042000200936020020034190096a24000be40602057f047e23004180016b22042400200441e0006a41086a220541d5fbc400ad42808080808001841003220641086a2900003703002004200629000037036020061023200441c0006a41086a2207200529030037030020042004290360370340200541e3a0c200ad4280808080b001841003220641086a2900003703002004200629000037036020061023200441d0006a41086a2208200529030037030020042004290360370350200441e0006a200110ac01024002400240024041c00010212206450d00200620042903403700002006200429035037001020062004290060370020200641086a2007290300370000200641186a2008290300370000200641286a2005290000370000200641306a200441e0006a41106a290000370000200641386a200441e0006a41186a290000370000200441286a200641c000108902200441286a41106a29030021092004290330210a20042802282105200610230240200a420020051b220a20025422062009420020051b220920035420092003511b450d0041d6c0c2002106411521050c040b200441206a20014104200a20027d220a200920037d2006ad7d220910de02200428022022060d02200441e0006a41086a220541d5fbc400ad42808080808001841003220641086a2900003703002004200629000037036020061023200441c0006a41086a2207200529030037030020042004290360370340200541eea0c200ad4280808080f001841003220641086a2900003703002004200629000037036020061023200441d0006a41086a2208200529030037030020042004290360370350200441e0006a200110ac0141c00010212206450d01200620042903403700002006200429035037001020062004290060370020200641086a2007290300370000200641186a2008290300370000200641286a2005290000370000200641306a200441e0006a41106a290000370000200641386a200441e0006a41186a290000370000200441086a200641c000108902200441086a41106a290300210b2004290310210c20042802082105200610232001200c420020051b220c20027c2202200b420020051b20037c2002200c54ad7c10ca022001200a200910dc02410021060c030b41c00041011030000b41c00041011030000b200428022421050b200020053602042000200636020020044180016a24000be41a04067f017e047f017e230041a0016b2204240020044180016a41086a220541aefcc400ad42808080809001841003220641086a290000370300200420062900003703800120061023200441186a41086a220720052903003703002004200429038001370318200541bcf3c000ad42808080808002841003220641086a290000370300200420062900003703800120061023200441e0006a41086a2208200529030037030020042004290380013703602004200136024820044180016a41186a2209200441c8006aad220a4280808080c000841001220641186a29000037030020044180016a41106a220b200641106a2900003703002005200641086a290000370300200420062900003703800120061023200441286a41186a22062009290300370300200441286a41106a2209200b290300370300200441286a41086a220b20052903003703002004200429038001370328024002400240024002400240024002400240024002400240024002400240024002400240024041c00010212205450d00200520042903183700002005200429036037001020052004290328370020200541086a2007290300370000200541186a2008290300370000200541286a200b290300370000200541306a2009290300370000200541386a2006290300370000200441086a200541c00041014100410010b801200428020821072005102341d2bbc100210620074101470d0e20044180016a41086a220541aefcc400ad42808080809001841003220641086a290000370300200420062900003703800120061023200441186a41086a20052903003703002004200429038001370318200541bdedc000ad4280808080e000841003220641086a290000370300200420062900003703800120061023200441e0006a41086a20052903003703002004200429038001370360410410212206450d0120044284808080c00037028401200420063602800120062001360000200020044180016a1071200428028401210720044180016a41186a2208200435028801422086200428028001220bad841001220641186a29000037030020044180016a41106a2209200641106a2900003703002005200641086a290000370300200420062900003703800120061023200441286a41186a2008290300370300200441286a41106a2009290300370300200441286a41086a2005290300370300200420042903800137032802402007450d00200b10230b41c00010212205450d02200520042903183700002005200429036037001020052004290328370020200541086a200441186a41086a2207290300370000200541186a200441e0006a41086a2208290300370000200541286a200441286a41086a2209290300370000200541306a200441286a41106a220b290300370000200541386a200441286a41186a220c2903003700002004200541c00041014100410010b801200428020021062005102320064101460d0d2004200036021420044180016a41086a220541aefcc400ad42808080809001841003220641086a290000370300200420062900003703800120061023200720052903003703002004200429038001370318200541ccf3c000ad42808080809001841003220641086a2900003703002004200629000037038001200610232008200529030037030020042004290380013703602004200136024820044180016a41186a220d200a4280808080c000841001220641186a29000037030020044180016a41106a220e200641106a2900003703002005200641086a290000370300200420062900003703800120061023200c200d290300370300200b200e29030037030020092005290300370300200420042903800137032841c00010212205450d03200520042903183700002005200429036037001020052004290328370020200541086a200441186a41086a290300370000200541186a200441e0006a41086a290300370000200541286a200441286a41086a2206290300370000200541306a200441386a290300370000200541386a200441286a41186a290300370000200441286a2005ad4280808080800884220f10041090010240024020042802282209450d0020062802002106200428022c210b0c010b20044100360288012004420137038001410020044180016a105c2004280288012106200428028401210b20042802800121090b200420063602502004200b36024c20042009360248024002402006450d0020044180016a20092006410110692004280280014101470d01200428024c450d0e200428024810230c0e0b4101200441c8006a105c2004280214200441c8006a10710c0b0b200428028401210c02402004418c016a280200220620044188016a2802002209460d002004280250200620096b6a220b41046a220d417f4c0d0502400240200d0d004101210e0c010b200d1021220e450d070b2004200d36021c2004200e3602182004200b3602202004200441186a36028001200c20044180016a2006109201200b2006490d072004280220220c200b490d082004280250220c2009490d092004280218210d2004280248210e2004200b20066b220b3602582004200c20096b220c36025c200b200c470d0a200d20066a200e20096a200b10dc041a2004280214200441186a107120042802202109200428021c210b20042802182106200428024c450d0c200428024810230c0c0b2004200441c8006a36028001200c20044180016a20091092012004280214200441c8006a10710c0a0b41c00041011030000b410441011030000b41c00041011030000b41c00041011030000b102f000b200d41011030000b2006200b103e000b200b200c1036000b2009200c103e000b200441286a41146a410d360200200441346a410e360200200441e0006a41146a410336020020044203370264200441acb6c6003602602004410e36022c2004200441d8006a3602782004200441dc006a36027c2004420437039001200442013702840120044180b7c600360280012004200441286a360270200420044180016a3602382004200441fc006a3602302004200441f8006a360228200441e0006a41bcb7c6001038000b20042802502109200428024c210b200428024821060b2006450d00200f2009ad4220862006ad8410020240200b450d00200610230b200510230c010b2005102320044180016a41086a220541aefcc400ad42808080809001841003220641086a290000370300200420062900003703800120061023200441186a41086a220920052903003703002004200429038001370318200541ccf3c000ad42808080809001841003220641086a290000370300200420062900003703800120061023200441e0006a41086a220b200529030037030020042004290380013703602004200136024820044180016a41186a220c200a4280808080c000841001220641186a29000037030020044180016a41106a220d200641106a2900003703002005200641086a290000370300200420062900003703800120061023200441286a41186a2206200c290300370300200441286a41106a220c200d290300370300200441286a41086a220d2005290300370300200420042903800137032841c00010212205450d02200520042903183700002005200429036037001020052004290328370020200541086a2009290300370000200541186a200b290300370000200541286a200d290300370000200541306a200c290300370000200541386a200629030037000020044100360288012004420137038001410120044180016a105c200428021420044180016a107120042802840121062005ad42808080808008842004350288014220862004280280012209ad84100202402006450d00200910230b200510230b20044180016a41086a220541aefcc400ad42808080809001841003220641086a290000370300200420062900003703800120061023200720052903003703002004200429038001370318200541bdedc000ad4280808080e000841003220641086a290000370300200420062900003703800120061023200820052903003703002004200429038001370360410410212205450d0220044284808080c00037028401200420053602800120052001360000200020044180016a1071200428028401210620044180016a41186a22012004350288014220862004280280012208ad841001220541186a29000037030020044180016a41106a2200200541106a29000037030020044180016a41086a2207200541086a290000370300200420052900003703800120051023200441286a41186a2001290300370300200441286a41106a2000290300370300200441286a41086a2007290300370300200420042903800137032802402006450d00200810230b41c00010212205450d03200520042903183700002005200429036037001020052004290328370020200541086a200441186a41086a290300370000200541186a200441e0006a41086a290300370000200541286a200441286a41086a290300370000200541306a200441386a290300370000200541386a200441286a41186a290300370000410110212201450d0441002106200141807f410020021b2003723a00002005ad42808080808008842001ad42808080801084100220011023200510230b200441a0016a240020060f0b41c00041011030000b410441011030000b41c00041011030000b410141011030000bd80201037f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022010d00200041003602040c010b200328021421042003200341186a2802002202360224200320013602200240024020024104490d0020032002417c6a3602242003200141046a36022020012800002102200341c8006a200341206a107e20032802482205450d002000200329024c37020820002005360204200020023602000c010b20034100360230200342013703282003410c36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034198c2c3003602482003200341386a360258200341c4006a41b8a3c500200341c8006a102e1a2003350230422086200335022884100820004100360204200328022c450d00200328022810230b2004450d00200110230b200341e0006a24000bde07020c7f017e230041a0076b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022040d00200041003602000c010b200328021421052003200341186a280200360234200320043602302003200341306a106e0240024002400240024002400240024020032802000d002003280234220641b8016e220741b8016c2201417f4c0d03200328020421080240024020010d00410821090c010b200110212209450d050b2008450d01200341c0046a410472210a4100210b410121024100210103400240024002402006450d002003280230220c2d0000210d20032006417f6a3602342003200c41016a360230200d41014b0d00411a2106024002400240200d0e020100010b200341f0056a200341306a10d90120032802f005411a460d02200341c0046a200341f0056a41b00110dc041a200328023422064104490d012003280230220d280000210e20032006417c6a3602342003200d41046a36023020032802c004210620034190036a200a41ac0110dc041a2006411a460d02200341e4016a20034190036a41ac0110dc041a2006411b460d020b200341386a200341e4016a41ac0110dc041a2002417f6a2007470d030240200b2002200b20024b1b2207ad42b8017e220f422088a70d00200fa7220d41004e0d030b102a000b200341c0046a10da010b20034100360220024020024101460d0020092102034002402002280200411a460d00200210db010b200241b8016a2102200141c87e6a22010d000b0b2007450d05200910230c050b0240024020024101470d00200d102121090c010b20092001200d102521090b2009450d070b200920016a220d2006360200200d41046a200341386a41ac0110dc041a200d41b0016a200e360200024020082002470d00200341286a200836020020032007360224200320093602200c080b200b41026a210b200241016a2102200141b8016a2101200328023421060c000b0b200341003602200c010b200341286a2008360200200320073602242003200936022020090d040b200341003602c804200342013703c0042003410c360294032003200341086a360290032003200341c0046a3602e40120034184066a4101360200200342013702f40520034198c2c3003602f005200320034190036a36028006200341e4016a41b8a3c500200341f0056a102e1a20033502c80442208620033502c0048410082000410036020020032802c404450d0420032802c00410230c040b102f000b200141081030000b200d41081030000b20002003290320370200200041086a200341206a41086a2802003602000b2005450d00200410230b200341a0076a24000bf90301027f20002d00002102024002400240024002400240410110212203450d00200320023a000020002d0001210220034101410210252203450d01200320023a000120002d0002210220034102410410252203450d02200320023a0002200320002d00033a000320002d0004210220034104410810252203450d03200320023a0004200320002d00053a0005200320002d00063a0006200320002d00073a000720002d0008210220034108411010252203450d04200320023a0008200320002d00093a0009200320002d000a3a000a200320002d000b3a000b200320002d000c3a000c200320002d000d3a000d200320002d000e3a000e200320002d000f3a000f20002d0010210220034110412010252203450d05200320023a0010200320002d00113a0011200320002d00123a0012200320002d00133a0013200320002d00143a0014200320002d00153a0015200320002d00163a0016200320002d00173a0017200320002d00183a0018200320002d00193a0019200320002d001a3a001a200320002d001b3a001b200320002d001c3a001c200320002d001d3a001d200320002d001e3a001e200320002d001f3a001f20012902002003ad42808080808004841002200310230f0b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000b840301047f230041e0006b22012400200141186a200041186a290000370300200141106a200041106a290000370300200141086a200041086a29000037030020012000290000370300200141c0006a41086a220241aefcc400ad42808080809001841003220041086a2900003703002001200029000037034020001023200141206a41086a22032002290300370300200120012903403703202002418ca1c100ad4280808080d000841003220041086a2900003703002001200029000037034020001023200141306a41086a2204200229030037030020012001290340370330200141c0006a200110ac01024041c000102122000d0041c00041011030000b200020012903203700002000200129033037001020002001290040370020200041086a2003290300370000200041186a2004290300370000200041286a2002290000370000200041306a200141c0006a41106a290000370000200041386a200141c0006a41186a2900003700002000ad4280808080800884100520001023200141e0006a24000bfa0c06077f027e017f017e037f0b7e23002206210720064180016b41607122062400200641e0006a41186a22084200370300200641e0006a41106a22094200370300200641e0006a41086a220a420037030020064200370360200641d0006a41086a220b41c4fbc400ad4280808080e000841003220c41086a2900003703002006200c290000370350200c1023200a200b29030037030020062006290350370360200b41f9bcc000ad4280808080e000841003220c41086a2900003703002006200c290000370350200c102320092006290350220d370300200641206a41086a200a290300370300200641206a41106a200d370300200641206a41186a200b2903003703002006200d37034020062006290360370320200641186a200641206a4120108f01200628021c210b2006280218210c2006200337033020062002370328200620043602384201210e200642013703202006200028000036023c2000350004210d200641e0006a200110df024100210f200d2005ad42ff018342208684211020062802602111200628026421120240024002400240024020062802682205450d00200b4100200c1b210420112005410574220c6a2113200641f4006a21052006290320220e21022006290328221421152006290330221621172006290338221821192011210b0340200b41086a290300210d200b41106a2903002103200b290300211a2008200b41186a29030037030020092003370300200a200d3703002006201a3703600240024020052000460d0020052900002000290000510d000240200628027020044b0d002002210d420021020c020b2009290300211b2006290368211c2006290360211d2006290378211e2002210d420121020c010b4200210e4200211442002116420021184200210d2010211e2015211d2017211c2019211b0b20024201510d02200b41206a210b200d2102200c41606a220c0d000b2006200e3703202006201437032820062016370330200620183703380b2012450d01201110230c010b2006200d3703202006201537032820062017370330200620193703380240412010212205450d002005201e3703182005201d3703002005201c370308200541106a201b370300024002400240200c4120470d004101210f200d210e4101210a0c010b200b41206a210b200641f4006a2109200d210e4101210f4101210a03400240024020092000460d00200d21020340200641e0006a41186a200b41186a290300370300200641e0006a41106a220c200b41106a290300370300200641e0006a41086a200b41086a2903003703002006200b2903003703600240024020092900002000290000510d000240200628027020044b0d002002210d420021020c020b200c290300211e2006290368211a200629036021032006290378211d2002210d420121020c010b4200210e200642003703204200210d201521032017211a2019211e2010211d0b024020024201510d00200d21022013200b41206a220b470d010c050b0b200b41206a210b0c010b0240034020064200370320200d4201510d014200210d2013200b41206a220b470d000b4200210e0c030b200b41206a210b4200210e4200210d201521032017211a2019211e2010211d0b0240200a200f470d00200f41016a220c200f490d07200f410174220a200c200a200c4b1b220a41ffffff3f71200a470d07200a410574220c4100480d0702400240200f0d00200c102121050c010b2005200f410574200c102521050b2005450d030b2005200f4105746a220c201a370308200c2003370300200c41106a201e370300200c41186a201d370300200f41016a210f200b2013470d000b0b2012450d03201110230c030b200c41081030000b412041081030000b4100210a410821050b02400240200e4201520d00200641e0006a41106a2200200641206a410872220b41106a290300370300200641e0006a41086a220c200b41086a2903003703002006200b2903003703600240200f200a470d00200f41016a220b200f490d03200f4101742209200b2009200b4b1b220a41ffffff3f71200a470d03200a410574220b4100480d0302400240200f0d00200b102121050c010b2005200f410574200b102521050b2005450d020b2005200f4105746a220b2006290360370300200b41106a2000290300370300200b41086a200c290300370300200b41186a2010370300200f41016a210f0b2006200f3602682006200a360264200620053602602001200641e0006a10e002200724000f0b200b41081030000b102a000b830d0b077f017e017f017e067f027e017f027e027f017e017f230041f0006b22032400200341d0006a41186a22044200370300200341d0006a41106a2205420037030041082106200341d0006a41086a2207420037030020034200370350200341386a41086a220841c4fbc400ad4280808080e000841003220941086a29000037030020032009290000370338200910232007200829030037030020032003290338370350200841f9bcc000ad4280808080e000841003220941086a290000370300200320092900003703382009102320052003290338220a370300200341086a41086a2007290300370300200341086a41106a200a370300200341086a41186a20082903003703002003200a370328200320032903503703082003200341086a4120108f0120032802042108200328020021092000280000210b2000350004210c200341d0006a200110df024100210d2003280250210e2003280254210f02400240024002400240024002400240024020032802582210450d002008410020091b2111200e201041057422106a2112200341e4006a2109200e21080340200841086a290300210a200841106a2903002113200829030021142004200841186a290300370300200520133703002007200a3703002003201437035020092000460d0220092900002000290000510d0202402003280260221520114d0d002003410a6a200341ef006a2d00003a0000200320032f006d3b0108200341d8006a2903002114427f2113200329035021164201210a20032d006c2109200329026421170c040b200841206a2108201041606a22100d000b0b200f450d02200e10230c020b200328026022092002200920024b1b211520032d006c4102722109427f21164200211341002102200329026421174200210a4100210b427f21140b200341cc006a41026a220d200341086a41026a2d00003a0000200320032f01083b014c02400240412010212206450d0020062016370300200620093a001c2006201737021420062015360210200620032f014c3b001d200620143703082006411f6a200d2d00003a00000240024020104120470d004101210d20132114410121070c010b200841206a2104201241606a2115200341ed006a2118200341e4006a2109201321144101210d41012107034020042108024002400340200341d0006a41186a200841186a290300370300200341d0006a41106a200841106a290300370300200341d0006a41086a2210200841086a290300370300200320082903003703500240024020092000460d0020092900002000290000510d002003280260220520114d0d01200341086a41026a201841026a2d00003a0000200320182f00003b0108201029030021162003290350211720032d006c21192003290264211a0c040b200a4201510d024200211341002102420021144200210a4100210b0b2012200841206a2208470d000c040b0b2010290300220a201420032903502217201356200a201456200a2014511b22101b21162017201320101b2117200328026022102002201020024b1b210520032d006c410272211942002113410021022003290264211a420021144200210a4100210b0b200341286a41026a200341086a41026a2d000022103a0000200320032f010822043b0128200341d0006a41026a221b20103a0000200320043b015002402007200d470d00200d41016a2210200d490d0a200d41017422072010200720104b1b220741ffffff3f712007470d0a200741057422104100480d0a02400240200d0d002010102121060c010b2006200d4105742010102521060b2006450d040b200841206a21042006200d4105746a221020193a001c20102016370308201020173703002010201a37021420102005360210201020032f01503b001d2010411f6a201b2d00003a0000200d41016a210d20152008470d000b0b0240200f450d00200e10230b200a4201520d05200d2007470d040c030b412041081030000b201041081030000b427f2113427f21140b200d41016a2208200d490d03200d41017422002008200020084b1b220741ffffff3f712007470d03200741057422084100480d0302400240200d0d002008102121060c010b2006200d4105742008102521060b2006450d020b2006200d4105746a22082014370308200820133703002008200b36021420082002360210200841186a200c42808080802084370300200d41016a210d0b2003200d36025820032007360254200320063602502001200341d0006a10e002200341f0006a24000f0b200841081030000b102a000bb40602067f017e23004180016b22032400200341c8006a41086a22044182fdc400ad4280808080a001841003220541086a2900003703002003200529000037034820051023200341086a41086a200429030037030020032003290348370308200441fbbdc100ad4280808080f001841003220541086a2900003703002003200529000037034820051023200341186a41086a200429030037030020032003290348370318024002400240410410212204450d002004200236000020044104410810252205450d0120052001360004200341c8006a41186a22012005ad42808080808001841001220441186a290000370300200341c8006a41106a2206200441106a290000370300200341c8006a41086a2207200441086a2900003703002003200429000037034820041023200341286a41186a22082001290300370300200341286a41106a22012006290300370300200341286a41086a22062007290300370300200320032903483703282005102341c00010212204450d02200420032903083700002004200329031837001020042003290328370020200441086a200341086a41086a290300370000200441186a200341186a41086a290300370000200441286a2006290300370000200441306a2001290300370000200441386a2008290300370000200341c00036026c20032004360268200341186a2004ad4280808080800884100410900102400240200328021822010d00410021050c010b200328021c21062003200341206a28020036027420032001360270200341c8006a200341f0006a107d0240024020032802482205450d00200329024c21090c010b4100210520034100360230200342013703282003410c36020c2003200341e8006a3602082003200341286a36027c200341dc006a41013602002003420137024c20034198c2c3003602482003200341086a360258200341fc006a41b8a3c500200341c8006a102e1a200335023042208620033502288410080240200328022c450d00200328022810230b0b2006450d00200110230b2004102302402005450d0020002009370208200020023602000b2000200536020420034180016a24000f0b410441011030000b410841011030000b41c00041011030000bee1405177f017e017f027e047f230041206b220224000240024020014115490d0002402001410176220341ffffff3f712003470d0020034105742204417f4c0d0041012105024002402004450d00200410212205450d010b200041606a2106200041a07f6a210741002108410021094104210a4100210b2001210c034002400240200c220d417f6a220e0d004101210f4100210c0c010b0240024002400240024002402000200e4105746a200d410574221020006a41406a412010de044100480d004102200d6b210e200720106a21044101210f03400240200e200f6a4101470d004100210c200d210f0c080b200f41016a210f200441206a2004412010de042111200441606a21042011417f4a0d000b200d200f6b210e0c010b200720106a2104024003400240200e4101470d004100210e0c020b200e417f6a210e200441206a2004412010de042111200441606a210420114100480d000b0b200d200e490d01200d20014b0d03200d200e6b220f4101762212450d00200620106a21042000200e4105746a21110340200241186a2210201141186a2213290000370300200241106a2214201141106a2215290000370300200241086a2216201141086a221729000037030020022011290000370300200441086a22182900002119200441106a221a290000211b200441186a220c290000211c201120042900003700002013201c3700002015201b37000020172019370000200c2010290300370000201a20142903003700002018201629030037000020042002290300370000200441606a2104201141206a21112012417f6a22120d000b0b0240200e0d00200e210c0c050b0240200f41094d0d00200e210c0c050b200d20014b0d01200d200e6b21122000200e4105746a21100340200d200e417f6a220c490d040240200d200c6b220f4102490d002000200e4105746a22042000200c4105746a220e412010de04417f4a0d00200e2900002119200e2004290000370000200241186a2216200e41186a2211290000370300200241106a2217200e41106a2213290000370300200241086a2218200e41086a22142900003703002014200441086a2900003700002013200441106a2900003700002011200441186a29000037000020022019370300410121150240200f4103490d00200e41c0006a2002412010de04417f4a0d00410221112010210402400340200441186a200441386a290000370000200441106a200441306a290000370000200441086a200441286a2900003700002004200441206a221329000037000020122011460d01200441c0006a21142011211520132104201141016a211120142002412010de04417f4a0d020c000b0b201121150b200e20154105746a22042002290300370000200441186a2016290300370000200441106a2017290300370000200441086a20182903003700000b200c450d05201041606a2110201241016a2112200c210e200f410a4f0d050c000b0b200e200d103e000b200d200e417f6a220c490d010b200d20011036000b200c200d103e000b024002400240200b2009470d0002400240200941016a22042009490d00200941017422112004201120044b1b220441ffffffff01712004470d002004410374221141004e0d010b102a000b0240024020090d0020111021210a0c010b200a200941037420111025210a0b200a450d01200421092008210b0b200a200b4103746a2204200f3602042004200c360200200841016a220b2108200b4102490d01024003400240024002400240200a200b417f6a22084103746a2204280200450d00200b410374200a6a220f41746a280200220e200428020422114d0d000240200b41024b0d00200b21084102210b0c080b200a200b417d6a22164103746a28020422042011200e6a4d0d010240200b41034b0d00200b21084103210b0c080b200f41646a2802002004200e6a4d0d01200b21080c070b200b4103490d0120042802042111200a200b417d6a22164103746a28020421040b20042011490d010b200b417e6a21160b024002400240024002400240200b201641016a221d4b221e450d00200b20164b221f450d01200a20164103746a2217280204222020172802006a2204200a201d4103746a2218280200221a490d02200420014b0d032000201a4105746a22142018280204221541057422116a210f2004410574210e2004201a6b220d20156b220420154f0d042005200f2004410574221110dc04221320116a21120240024020154101480d00200441014e0d010b200f2104201321110c060b2006200e6a210e200f21040340200e200441606a220f201241606a220d200d200f412010de0441004822101b2211290000370000200e41186a201141186a290000370000200e41106a201141106a290000370000200e41086a201141086a2900003700002012200d20101b211202402014200f200420101b2204490d00201321110c070b200e41606a210e2013211120132012490d000c060b0b4198bfc100201d200b102d000b4198bfc1002016200b102d000b201a2004103e000b200420011036000b20052014201110dc04221320116a21120240024020154101480d00200d20154a0d010b20142104201321110c010b2000200e6a2110201321112014210403402004200f2011200f2011412010de04410048220d1b220e290000370000200441186a200e41186a290000370000200441106a200e41106a290000370000200441086a200e41086a2900003700002011201141206a200d1b2111200441206a2104200f41206a200f200d1b220f20104f0d01201220114b0d000b0b20042011201220116b41607110dc041a0240201f450d002017201a360200201741046a202020156a360200201e450d022018201841086a200b201d417f736a41037410dd041a2008210b200841014d0d040c010b0b41a8bfc1002016200b102d000b41b8bbc000102b000b201141041030000b200c0d000b02402009450d00200a10230b2003450d03200510230c030b200441011030000b102f000b20014102490d002001417f6a2111200141057420006a41206a2110410121120340024002400240024020112204417f6a221120014b0d00200120116b220e4102490d03200020044105746a2204200020114105746a220d412010de04417f4a0d03200d2900002119200d2004290000370000200241186a2214200d41186a220f290000370300200241106a220b200d41106a2213290000370300200241086a2215200d41086a220a290000370300200a200441086a2900003700002013200441106a290000370000200f200441186a2900003700002002201937030041012104200e4103490d02200d41c0006a2002412010de04417f4a0d0241002113201021040340200441406a220e200441606a220f290000370000200e41186a200f41186a290000370000200e41106a200f41106a290000370000200e41086a200f41086a29000037000020122013220e460d02200e417f6a211320042002412010de04210f200441206a2104200f417f4a0d020c000b0b20112001103e000b4102200e6b21040b200d20044105746a22042002290300370000200441186a2014290300370000200441106a200b290300370000200441086a20152903003700000b201041606a21102012417f6a211220110d000b0b200241206a24000be60401067f230041106b2203240020034100360208200342013703000240024002400240024020012d0000220441024b0d0002400240024020040e03000102000b410110212204450d03200342818080801037020420032004360200200441013a0000200141086a200310b1010c020b410110212204450d03200342818080801037020420032004360200200441023a00002003200336020c200141016a2003410c6a106b0c010b410110212204450d03200342818080801037020420032004360200200441033a00002003200336020c200141016a2003410c6a106b0b20032802002104024020032802042205200328020822066b4120490d00200641206a21070c040b0240200641206a22072006490d00200541017422082007200820074b1b22084100480d000240024020050d002008102121040c010b200420052008102521040b02402004450d00200821050c050b200841011030000b102a000b410141011030000b410141011030000b410141011030000b200420066a22062002290000370000200641186a200241186a290000370000200641106a200241106a290000370000200641086a200241086a290000370000200020073602082000200536020420002004360200024020012d00000d000240200141206a280200450d002001411c6a28020010230b02402001412c6a280200450d00200141286a28020010230b02402001413c6a2802002204450d00200141346a28020021022004410474210403400240200241046a280200450d00200228020010230b200241106a2102200441706a22040d000b0b200141386a280200450d00200128023410230b200341106a24000b980401067f230041e0006b22012400200141c0006a41086a22024182fdc400ad4280808080a001841003220341086a2900003703002001200329000037034020031023200141086a200229030037030020012001290340370300200241fbbdc100ad4280808080f001841003220341086a2900003703002001200329000037034020031023200141106a41086a200229030037030020012001290340370310024002400240410410212202450d00200220002802003600002000280204210320024104410810252200450d0120002003360004200141c0006a41186a22032000ad42808080808001841001220241186a290000370300200141c0006a41106a2204200241106a290000370300200141c0006a41086a2205200241086a2900003703002001200229000037034020021023200141206a41186a22062003290300370300200141206a41106a22032004290300370300200141206a41086a22042005290300370300200120012903403703202000102341c00010212202450d02200220012903003700002002200129031037001020022001290320370020200241086a200141086a290300370000200241186a200141106a41086a290300370000200241286a2004290300370000200241306a2003290300370000200241386a20062903003700002002ad4280808080800884100520021023200141e0006a24000f0b410441011030000b410841011030000b41c00041011030000bf70b07067f017e067f017e067f027e037f23004180016b22012400200141e0006a41186a22024200370300200141e0006a41106a22034200370300200141e0006a41086a2204420037030020014200370360200141086a22054191fdc400ad42808080809001841003220641086a2900003703002001200629000037030020061023200420052903003703002001200129030037036020054184ddc100ad4280808080e000841003220641086a2900003703002001200629000037030020061023200320012903002207370300200141206a41086a22082004290300370300200141206a41106a22092007370300200141206a41186a220a20052903003703002001200737034020012001290360370320200141e0006a200141206a10fe01024002402001280260220b0d004104210b4100210c4100210d0c010b20012902642207422088a7210c2007a7210d0b2002420037030020034200370300200442003703002001420037036020054182fdc400ad4280808080a001841003220641086a29000037030020012006290000370300200610232004200529030037030020012001290300370360200541fccfc300ad4280808080b001841003220641086a2900003703002001200629000037030020061023200141c0006a41086a2005290300220737030020012001290300220e3703402003200e370000200341086a20073700002008200429030037030020092003290300370300200a200229030037030020012001290360370320200141d0006a200141206a10bc0102400240200128025022050d00410021030c010b20012902542207422088a721032007a7450d00200510230b4100210f4100210a0240200c450d002003417f6a200c6e210a0b02400240024002400240024020030d0041042108410021050c010b02400240200341ffffffff01712003470d00200341037422054100480d002005102122080d01200541041030000b102a000b0240200a450d00200a200c6c210941002105200821040340410021020240200920054d0d00200c2005200a6e22024d0d04200b2002412c6c6a2802002106410121020b20042002360200200441046a2006360200200441086a21042003200541016a2205470d000b2003210f0c010b2003210420082105034020054100360200200541086a21052004417f6a22040d000b2003210f200321050b200141206a4188c0c100411410ff0141002104200141e0006a41186a220a41204100412020034102746b2202200241204b1b22026bad422086200141206a20026aad841001220241186a290000370300200141e0006a41106a2210200241106a290000370300200141e0006a41086a2211200241086a2900003703002001200229000037036020021023200141186a2212200a2903002207370300200141106a22132010290300220e370300200141086a221420112903002215370300200120012903602216370300200141206a41186a22172007370300200141206a41106a2218200e370300200141206a41086a221920153703002001201637032041002003417f6a2202200220034b1b2209450d032001ad4280808080800484210e034002402004411c71220241046a220641204d0d00200641201036000b200120026a2800002003410120031b220c70210602402002411c470d00200a200e1001220241186a2900003703002010200241106a2900003703002011200241086a29000037030020012002290000370360200210232012200a2903003703002013201029030037030020142011290300370300200120012903603703000b200c417f6a220220054f0d02200620054f0d03200820024103746a220229020021072002200820064103746a220629020037020020062007370200200441046a21042003417f6a21032009417f6a22090d000c040b0b41a0abc2002002200c102d000b419cc0c10020022005102d000b41acc0c10020062005102d000b200020053602082000200f360204200020083602002000200129032037000c200041146a20192903003700002000411c6a2018290300370000200041246a20172903003700000240200d450d00200b10230b20014180016a24000b900b02117f037e230041c0026b220224002002412036020c20022001360208200241106a2001ad4280808080800484100410900102400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360234200220033602302002200241306a106e02400240024002400240024020022802000d00024002400240024020022802342205412c6e2206412c6c2201417f4c0d00200228020421070240024020010d00410421080c010b200110212208450d020b02402007450d0041002109034020054104490d0920022005417c6a220a36023420022002280230220b41046a2201360230200a450d09200b280000210c20022005417b6a220d3602342002200141016a36023020012d0000220141014b0d094102210e0240024020010e020100010b41002101200241003a00b8022005417b6a210d417a210a03400240200d2001470d00200141ff0171450d0b200241003a00b8020c0b0b20024198026a20016a200b20016a220e41056a2d00003a000020022005200a6a3602342002200e41066a3602302002200141016a220e3a00b802200a417f6a210a200e2101200e4120470d000b200241f8016a41186a220f20024198026a41186a290300370300200241f8016a41106a221020024198026a41106a290300370300200241f8016a41086a221120024198026a41086a29030037030020022002290398023703f801200d200e460d0920022005200a6a220d3602342002200b200e6a220141066a220b360230200141056a2d0000220a41014b0d09024002400240200a0e020100010b200d4104490d0b20022005200e6b41766a220d36023420022001410a6a360230200b28000021124101210e0c010b4100210e0b200241b8016a41086a2011290300221337030020024198016a41186a200f29030037030020024198016a41106a201029030037030020024198016a41086a2013370300200220022903f80122133703b80120022013370398010b200941016a210a200241d8006a41086a20024198016a41086a2903002213370300200241d8006a41106a20024198016a41106a2903002214370300200241d8006a41186a20024198016a41186a2903002215370300200241386a41086a22052013370300200241386a41106a220b2014370300200241386a41186a220f20153703002002200229039801221337035820022013370338024020062009470d0020094101742201200a2001200a4b1b2206ad422c7e2213422088a70d062013a722014100480d060240024020090d002001102121080c010b20082009412c6c2001102521080b2008450d050b20082009412c6c6a2201200c360200200120022903383702042001410c6a2005290300370200200141146a200b2903003702002001411c6a200f290300370200200141286a2012360200200141246a200e360200200d2105200a2109200a2007470d000b200241286a200736020020022006360224200220083602200c060b200241286a2007360200200220063602242002200836022020080d050c080b102f000b200141041030000b200141041030000b102a000b200241003602200c030b20002002290320370200200041086a200241206a41086a2802003602000c030b200241b8016a41186a200241d8016a41186a290300370300200241b8016a41106a200241d8016a41106a2903003703000b200241003602202006450d00200810230b2002410036028002200242013703f8012002410c3602dc012002200241086a3602d8012002200241f8016a3602b801200241ac026a41013602002002420137029c0220024198c2c300360298022002200241d8016a3602a802200241b8016a41b8a3c50020024198026a102e1a20023502800242208620023502f8018410082000410036020020022802fc01450d0020022802f80110230b2004450d00200310230b200241c0026a24000bdb1b05047f017e047f017e277f230041c00d6b220324002003200236020c20032001360208200341206a41186a22024200370300200341206a41106a22044200370300200341206a41086a2201420037030020034200370320200341800d6a41086a220541c4fbc400ad4280808080e000841003220641086a290000370300200320062900003703800d2006102320012005290300370300200320032903800d370320200541f9bcc000ad4280808080e000841003220641086a290000370300200320062900003703800d20061023200420032903800d2207370300200341a00d6a41086a22082001290300370300200341a00d6a41106a22092007370300200341a00d6a41186a220a200529030037030020032007370310200320032903203703a00d2003200341a00d6a4120108f01200328020421062003280200210b20024200370300200442003703002001420037030020034200370320200541d899c600ad42808080808003841003220441086a290000370300200320042900003703800d2004102320012005290300370300200320032903800d370320200541f099c600ad4280808080e001841003220441086a290000370300200320042900003703800d2004102320022005290300220737030020082001290300370300200920032903800d220c370300200a20073703002003200c370310200320032903203703a00d200341206a200341a00d6a412010bb0120032802202201410120011b210d024002402003290224420020011b2207422088a722020d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b200341206a410041e00c10db041a2006417f6a41d100704130200b1b2101200d41206a210e200d20024105746a210f410021104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f410021204100212141002122410021234100212441002125410021264100212741002128410021294100212a4100212b4100212c4100212d4100212e4100212f200d210b4100213041d10021310240034020302104024002400240024002402001450d00200d450d03200141016a2102200b21010340024002402001200f470d00200e210b200e2101200d21060c010b20012106200141206a220b21010b2002417f6a22020d000c020b0b200b200f470d01200e210b200d21060b20060d020c040b200b2106200b41206a210b0c010b200b200f460d02200141016a210202400340200b41206a21012002417f6a2202450d012001210b200f2001460d040c000b0b200b21062001210b2006450d020b024002400240024002400240200328020c220141056a2202417f4c0d0020032802082132024002402002450d00200210212230450d0341002133200341003602a80d200320023602a40d200320303602a00d0c010b200341003602a80d200320023602a40d200341013602a00d410110212230450d03200341013602a40d200320303602a00d20032802a80d21330b2003203341016a3602a80d203020336a20043a00002001200341a00d6a105c0240024020032802a40d223320032802a80d22026b2001490d0020032802a00d21330c010b200220016a22302002490d05203341017422022030200220304b1b22024100480d050240024020330d002002102121330c010b20032802a00d20332002102521330b2033450d04200320023602a40d200320333602a00d20032802a80d21020b2003200220016a3602a80d203320026a2032200110dc041a2003200341a00d6a3602102006200341106a106b20032802a40d2102200a20033502a80d42208620032802a00d2230ad841001220141186a2900003703002009200141106a2900003703002008200141086a290000370300200320012900003703a00d20011023200341800d6a41186a2206200a290300370300200341800d6a41106a2233200929030037030020052008290300370300200320032903a00d3703800d02402002450d00203010230b2031417f6a2131200441016a2130200341206a20044103704105746a220120032903800d370000200141186a2006290300370000200141106a2033290300370000200141086a20052903003700004100210203402004200441036e2206417d6c6a4102470d06200341206a20026a220141df006a2d000022102001411f6a2d000022117120102011722001413f6a2d00007172212d200141de006a2d000022102001411e6a2d000022117120102011722001413e6a2d00007172212c200141dd006a2d000022102001411d6a2d000022117120102011722001413d6a2d00007172212b200141dc006a2d000022102001411c6a2d000022117120102011722001413c6a2d00007172212a200141db006a2d000022102001411b6a2d000022117120102011722001413b6a2d000071722129200141da006a2d000022102001411a6a2d000022117120102011722001413a6a2d000071722128200141d9006a2d00002210200141196a2d00002211712010201172200141396a2d000071722127200141d8006a2d00002210200141186a2d00002211712010201172200141386a2d000071722126200141d7006a2d00002210200141176a2d00002211712010201172200141376a2d000071722125200141d6006a2d00002210200141166a2d00002211712010201172200141366a2d000071722124200141d5006a2d00002210200141156a2d00002211712010201172200141356a2d000071722123200141d4006a2d00002210200141146a2d00002211712010201172200141346a2d000071722122200141d3006a2d00002210200141136a2d00002211712010201172200141336a2d000071722121200141d2006a2d00002210200141126a2d00002211712010201172200141326a2d000071722120200141d1006a2d00002210200141116a2d00002211712010201172200141316a2d00007172211f200141d0006a2d00002210200141106a2d00002211712010201172200141306a2d00007172211e200141cf006a2d000022102001410f6a2d000022117120102011722001412f6a2d00007172211d200141ce006a2d000022102001410e6a2d000022117120102011722001412e6a2d00007172211c200141cd006a2d000022102001410d6a2d000022117120102011722001412d6a2d00007172211b200141cc006a2d000022102001410c6a2d000022117120102011722001412c6a2d00007172211a200141cb006a2d000022102001410b6a2d000022117120102011722001412b6a2d000071722119200141ca006a2d000022102001410a6a2d000022117120102011722001412a6a2d000071722118200141c9006a2d00002210200141096a2d00002211712010201172200141296a2d000071722117200141c8006a2d00002210200141086a2d00002211712010201172200141286a2d000071722116200141c7006a2d00002210200141076a2d00002211712010201172200141276a2d000071722115200141c6006a2d00002210200141066a2d00002211712010201172200141266a2d000071722114200141c5006a2d00002210200141056a2d00002211712010201172200141256a2d000071722113200141c4006a2d00002210200141046a2d00002211712010201172200141246a2d000071722112200141c3006a2d00002210200141036a2d00002211712010201172200141236a2d000071722111200141c2006a2d00002210200141026a2d0000222e712010202e72200141226a2d000071722110200141c1006a2d0000222e200141016a2d0000222f71202e202f72200141216a2d00007172212e200141c0006a2d0000222f20012d0000223371202f203372200141206a2d00007172212f200241800c460d06200341206a20022006410574200441096e41e0006c6b6a6a220141ff006a202d3a0000200141fe006a202c3a0000200141fd006a202b3a0000200141fc006a202a3a0000200141fb006a20293a0000200141fa006a20283a0000200141f9006a20273a0000200141f8006a20263a0000200141f7006a20253a0000200141f6006a20243a0000200141f5006a20233a0000200141f4006a20223a0000200141f3006a20213a0000200141f2006a20203a0000200141f1006a201f3a0000200141f0006a201e3a0000200141ef006a201d3a0000200141ee006a201c3a0000200141ed006a201b3a0000200141ec006a201a3a0000200141eb006a20193a0000200141ea006a20183a0000200141e9006a20173a0000200141e8006a20163a0000200141e7006a20153a0000200141e6006a20143a0000200141e5006a20133a0000200141e4006a20123a0000200141e3006a20113a0000200141e2006a20103a0000200141e1006a202e3a0000200141e0006a202f3a000020062104200241e0006a220241e00c470d000c060b0b102f000b200241011030000b410141011030000b200241011030000b102a000b4100210120310d000b0b2000202d3a001f2000202c3a001e2000202b3a001d2000202a3a001c200020293a001b200020283a001a200020273a0019200020263a0018200020253a0017200020243a0016200020233a0015200020223a0014200020213a0013200020203a00122000201f3a00112000201e3a00102000201d3a000f2000201c3a000e2000201b3a000d2000201a3a000c200020193a000b200020183a000a200020173a0009200020163a0008200020153a0007200020143a0006200020133a0005200020123a0004200020113a0003200020103a00022000202e3a00012000202f3a00000b02402007a7450d00200d10230b200341c00d6a24000bfc0301067f230041f0006b22022400200241d0006a41086a22034182fdc400ad4280808080a001841003220441086a2900003703002002200429000037035020041023200241086a41086a2205200329030037030020022002290350370308200341ecbdc100ad4280808080d000841003220441086a2900003703002002200429000037035020041023200241186a41086a22062003290300370300200220022903503703182002200136024c200241d0006a41186a2201200241cc006aad4280808080c000841001220441186a290000370300200241d0006a41106a2207200441106a2900003703002003200441086a2900003703002002200429000037035020041023200241286a41186a22042001290300370300200241286a41106a22012007290300370300200241286a41086a2207200329030037030020022002290350370328024041c00010212203450d00200320022903083700002003200229031837001020032002290328370020200341086a2005290300370000200341186a2006290300370000200341286a2007290300370000200341306a2001290300370000200341386a2004290300370000200241d0006a200341c00010c00102400240200228025022040d00200041003602000c010b20002002290254370204200020043602000b20031023200241f0006a24000f0b41c00041011030000b340020004182fdc40036020420004100360200200041146a4109360200200041106a4194c1c100360200200041086a420a3702000b3001017f02404108102122020d00410841011030000b20024200370000200042888080808001370204200020023602000b2201017f230041106b220224002002410036020020002002108402200241106a24000b970301067f230041106b22022400024002400240024002400240024002400240200128020022030d00410121040c010b0240200141086a28020041056a2204417f4c0d0020040d0120024100360208200242013703000c020b102f000b200410212205450d03200241003602082002200436020420022005360200024020030d00200541003a0000200241013602080c030b20040d010b410110212205450d0320024101360204200220053602000b200541013a000020024101360208200141086a28020022042002105c0240024020022802042201200228020822056b2004490d00200228020021010c010b200520046a22062005490d05200141017422072006200720064b1b22064100480d050240024020010d002006102121010c010b200228020020012006102521010b2001450d0420022006360204200220013602000b2002200520046a360208200120056a2003200410dc041a0b20002002290300370200200041086a200241086a280200360200200241106a24000f0b200441011030000b410141011030000b200641011030000b102a000ba1b0010d057f017e037f017e117f037e027f027e097f017e027f027e167f230041c0076b2204240041aab0c0002105410f210602400240200141ff01710d00200241ff01714102470d00200441d8016a41186a4200370300200441d8016a41106a22074200370300200441d8016a41086a22024200370300200442003703d801200441b0076a41086a22014182fdc400ad4280808080a001841003220841086a290000370300200420082900003703b0072008102320022001290300370300200420042903b007220937038807200420093703d801200141b39fc600ad42808080809001841003220841086a290000370300200420082900003703b00720081023200720042903b0072209370300200441b8016a41086a2002290300370300200441b8016a41106a2009370300200441b8016a41186a20012903003703002004200937038804200420042903d8013703b801200441c0006a200441b8016a412041014100410010b801024020042802404101470d0041dbd3c1002105413621060c010b200441b8056a41186a4200370300200441b8056a41106a220a4200370300200441b8056a41086a22024200370300200442003703b80520014191fdc400ad42808080809001841003220841086a290000370300200420082900003703b0072008102320022001290300370300200420042903b0073703b80520014184ddc100ad4280808080e000841003220841086a290000370300200420082900003703b00720081023200a20042903b007220937030020044188046a41086a200229030037030020044188046a41106a200937030020044188046a41186a2001290300370300200420093703c802200420042903b80537038804200441c8026a20044188046a10fe0120042802c8022201410420011b210b02400240200341086a280200220c20042902cc02420020011b220d422088a7220e4d0d004191d4c1002105411d21060c010b02400240024002400240200c41ffffffff0371200c470d00200c4102742201417f4c0d00024002400240024002400240024020010d004104210f0c010b20011021220f450d010b200441003602502004200c36024c2004200f3602480240200e0d0041002102200f2108200c21100c090b20032802002211200c41d0016c6a2112200c450d02200441c8026aad4280808080c000842109200b200e412c6c6a2108200c2113200c21144100211541012101200b21162011211702400340201722182802102119200441c8006a211a024020014101710d0020022019490d004194d7c1002105411621060c060b201841d0016a2117201621010340024020082001470d0041ddd6c1002105412721060c070b200128020021022001412c6a2216210120022019470d000b0240201641786a2802004102460d00201841e0006a2016460d00201641586a201841386a412010de04450d004184d7c1002105411021060c060b0240201841346a280200221b450d00201828022c2110200441b0076a41086a22014182fdc400ad4280808080a001841003220241086a290000370300200420022900003703b0072002102320044188076a41086a22052001290300370300200420042903b00737038807200141acc9c100ad4280808080e002841003220241086a290000370300200420022900003703b0072002102320044188046a41086a22022001290300370300200420042903b00737038804200420193602c802200441b8056a41186a220620091001220141186a290000370300200441b8056a41106a221c200141106a290000370300200441b8056a41086a221d200141086a290000370300200420012900003703b80520011023200441d8016a41186a221e2006290300370300200441d8016a41106a2206201c290300370300200441d8016a41086a221c201d290300370300200420042903b8053703d80141c00010212201450d022001200429038807370000200141086a20052903003700002001200429038804370010200141186a2002290300370000200120042903d801370020200141286a201c290300370000200141306a2006290300370000200141386a201e290300370000200441c8026a200141c00010860220042802cc02210220042802d002211c20042802c8022105200110230240200241002005410146221d1b201b6a22014101460d0041bcd7c1002105411e2106200141e4004b0d07201c4100201d1b2102201b410474211c201041086a21010340200128020020026a2102200141106a2101201c41706a221c0d000b200241a09c014b0d070b201941e807490d00201b410474210103402001450d01200141706a210120102d000c2102201041106a211020024102470d000b41aad7c1002105411221060c060b024020182802282201450d0020182802202205200141246c6a211c41002101200b211903400240024020010d00200528020021010c010b200128020020052802002201490d004120210641ccd8c10021050c080b024020012018280210470d004119210641b3d8c10021050c080b200441d8016a41086a41002900e2d741221f370300200441d8016a41106a41002900ead7412220370300200441d8016a41186a41002900f2d7412221370300200441c8026a41086a201f370300200441c8026a41106a2020370300200441c8026a41186a2021370300200441002900dad741221f3703d8012004201f3703c802200441c8026a200541046a2201460d052001200441c8026a412010de04450d05200541246a2106201921010340024020082001470d00412121064192d8c10021050c090b200128020021022001412c6a2219210120022005280200470d000b20052101200621052006201c470d000b0b201828021021020240024020152014470d00024020132014460d00201321140c010b201341016a22012013490d0d201341017422052001200520014b1b221441ffffffff03712014470d0d201441027422014100480d0d0240024020130d0020011021210f0c010b200f201341027420011025210f0b200f450d012004201436024c2004200f360248201421130b200f20154102746a20023602002004201541016a22153602504100210120172012470d010c050b0b200141041030000b41c00041011030000b200141041030000b4118210641fad7c10021050c010b200441b8056a41186a22164200370300200441b8056a41106a22054200370300200441b8056a41086a22024200370300200442003703b805200441b0076a41086a22014182fdc400ad4280808080a001841003220841086a290000370300200420082900003703b0072008102320022001290300370300200420042903b0073703b805200141fccfc300ad4280808080b001841003220841086a290000370300200420082900003703b00720081023200441c8026a41086a20012903002209370300200420042903b007221f3703c802200a201f370000200a41086a200937000020044188046a41086a200229030037030020044188046a41106a200529030037030020044188046a41186a2016290300370300200420042903b80537038804200441c8026a20044188046a10bc0120042802c802211a20042902cc022109200441c8026a10fd0120042802cc02212220042802c802211320042802d002210f200441f8016a41186a200441ec026a290200370300200441f8016a41106a200441e4026a290200370300200441f8016a41086a200441dc026a290200370300200420042902d4023703f801200f200f41ffffffff0171470d02200f4103742201417f4c0d02024002400240024020010d00410421190c010b200110212219450d010b024002400240200f41037422010d00410021080c010b201320016a2118410021082013211c4100211003400240201c2802004101470d00024002400240200841014b0d000240024020080e020001000b201c2802042106410021010c030b201c2802042106410021010c010b201c28020421064100210120082102034020012002410176221620016a2205201920054103746a28020420064b1b2101200220166b220241014b0d000b0b0240201920014103746a28020422022006460d00200120022006496a21010b200820014f0d004180bbc000102b000b02402008200f470d00200f41016a2202200f490d0d200f41017422162002201620024b1b220241ffffffff01712002470d0d200241037422164100480d0d02400240200f0d002016102121190c010b2019200f4103742016102521190b2019450d042002210f0b201920014103746a220241086a2002200820016b41037410dd041a2002200636020420022010360200200841016a21080b201041016a2110201c41086a221c2018470d000b0b200441b8056a41186a22164200370300200441b8056a41106a22054200370300200441b8056a41086a22014200370300200442003703b805200441b0076a41086a220241c4fbc400ad4280808080e000841003220641086a290000370300200420062900003703b0072006102320012002290300370300200420042903b0073703b805200241ffbcc000ad4280808080a001841003220641086a290000370300200420062900003703b00720061023200441c8026a41086a2002290300221f370300200420042903b00722203703c802200a2020370000200a41086a201f37000020044188046a41086a200129030037030020044188046a41106a200529030037030020044188046a41186a2016290300370300200420042903b80537038804200441c8026a20044188046a4120108a0120042d00c80221022016200441e1026a2900003703002005200441d9026a2900003703002001200441d1026a290000370300200420042900c9023703b8050240024020024101460d00200441e8066a41186a4200370300200441e8066a41106a4200370300200441e8066a41086a4200370300200442003703e8060c010b200441e8066a41186a2016290300370300200441e8066a41106a2005290300370300200441e8066a41086a2001290300370300200420042903b8053703e8060b20094200201a1b2109201a4101201a1b21230240200c0d004101211e4100211b4100211d0c050b2019410c6a2117200441b8056aad42808080808002842124200441c8026aad428080808080048421252009422088a72126200441c8026a4101722127200441b8056a41106a2114200441e8036a2128200441a8036a212920044188036a212a200441fc026a212b412021064100211b4100211d4101211e4100210203402011211541aed4c100210520022008460d03201541d0016a2111201528021021182002211c024002400240024002400240024002400240034002400240201c20084f0d002019201c41037422106a221a28020421162008201c41016a22024d0d01201720106a2101034020012802002016470d02200141086a21012008200241016a2202470d000b200821020c010b41bcc0c100201c2008102d000b2002201c490d010240200820024f0d00200220081036000b024020162018460d002002211c20022008460d0e0c010b0b201a450d0c0240201541c0016a222c28020022162002201c6b220141017620014101716a4f0d0041ced4c10021050c0d0b0240201620264d0d00413c210641eed4c10021050c0d0b201541086a220c290300211f20152903002120200420183602b80220044188046a200441b8026a10870220044188076a20044188046a2020201f4108410010880202402004280288074101470d002004280290072106200428028c0721050c0d0b20044188076a41106a222d2903002121200429039007211f200441b8056a41186a222e420037030020144200370300200441b8056a41086a22184200370300200442003703b805200441b0076a41086a221641d5fbc400ad428080808080018422201003220141086a290000370300200420012900003703b0072001102320182016290300370300200420042903b007222f3703b8012004202f3703b805200441d8016a41086a223041d6a0c200ad4280808080d00184222f1003220141086a290000370300200420012900003703d80120011023200441b8016a41086a223120302903002232370300200420042903d80122333703b80120142033370000201441086a22052032370000200441c8026a41086a22342018290300370300200441c8026a41106a22352014290300370300200441c8026a41186a2236202e290300370300200420042903b8053703c802200441286a200441c8026a4120108902200441286a41106a29030021322004290330213320042802282101202e42003703002014420037030020184200370300200442003703b805203020201003221641086a290000370300200420162900003703d8012016102320182030290300370300200420042903d80122203703b801200420203703b8052030202f1003221641086a290000370300200420162900003703d80120161023203120302903002220370300200420042903d801222f3703b8012014202f3700002005202037000020342018290300370300203520142903003703002036202e290300370300200420042903b8053703c802200442002032420020011b222020217d2033420020011b2221201f54ad7d222f2021201f7d221f202156202f202056202f2020511b22011b3703c00520044200201f20011b3703b805202520241002410021372004410036029802200441003602a80220152902c401211f200442003703b8072004201f3703b007200241037420106b2138201541386a21392015412c6a213a20154198016a213b201541d8006a213c4100213d410021104100213e4100213f41002140034002400240200441b0076a10810141ff017122014102460d00200420042802b807221641016a3602b8072001410171450d02200420042802bc07220141016a22403602bc07202c28020020014b0d014119210641e2d5c10021050c090b203620044188076a41186a2903003703002035202d290300370300203420044188076a41086a29030037030020042004290388073703c802203741ff01714101470d06202e20362903003703002014203529030037030020182034290300370300200420042903c8023703b8050c070b20152802b801200141c1006c6a214120382101201a21050340024020010d004138210641aad5c10021050c090b200141786a21012005280200211c200541086a2105201c2016470d000b0240024020412d00004101460d0020044198026a2101203f0d012030203941086a2903003703002015280210213d200441d8016a41186a223e203941186a290300370300200441d8016a41106a2242203941106a290300370300200441b8056a41306a2243203c41306a290000370300200441b8056a41286a2244203c41286a290000370300200441b8056a41206a2245203c41206a290000370300202e203c41186a2900003703002014203c41106a2900003703002018203c41086a2900003703002039290300211f200441b8056a41386a2246203c41386a2900003703002004201f3703d8012004203c2900003703b805201528021c2205417f4c0d122015280214211c0240024020050d004101213f0c010b20051021223f450d050b203f201c200510dc0421472015280228223fad42247e221f422088a70d12201fa7221c417f4c0d122015280220214802400240201c0d00410421490c010b201c10212249450d060b20492048201c10dc04211c200c290300211f20152903002120200441b8016a41186a2248203b41186a290000370300200441b8016a41106a2249203b41106a2900003703002031203b41086a2900003703002004203b2900003703b801200441b8026a203a10792035201f370300202b20042903b802370000202b41086a200441b8026a41086a280200360000202a20042903d801370000202a41086a2030290300370000202a41106a2042290300370000202a41186a203e290300370000200420203703d0022004203f3602f8022004203f3602f4022004201c3602f002200420053602ec02200420053602e802200420473602e4022004203d3602e002200441003a00c802202941386a2046290300370000202941306a2043290300370000202941286a2044290300370000202941206a2045290300370000202941186a202e290300370000202941106a2014290300370000202941086a2018290300370000202920042903b805370000202820042903b801370000202841086a2031290300370000202841106a2049290300370000202841186a204829030037000020044188046a41186a200441e8066a41186a29030037030020044188046a41106a200441e8066a41106a29030037030020044188046a41086a200441e8066a41086a290300370300200420042903e8063703880420044198026a200441c8026a20044188046a10fb01200428029802223d213e203d213f0c010b0240203741ff01710d00200441d8016a2015106a20044188076a41186a200441d8016a41186a290300370300202d200441d8016a41106a29030037030020044188076a41086a2030290300370300200420042903d80137038807410121370b20044188046a41186a220120044188076a41186a29030037030020044188046a41106a2205202d29030037030020044188046a41086a221c20044188076a41086a290300370300200420042903880737038804024020100d002027200429038804370000202741086a201c290300370000202741106a2005290300370000202741186a2001290300370000200441013a00c802202e200441e8066a41186a2903003703002014200441e8066a41106a2903003703002018200441e8066a41086a290300370300200420042903e8063703b805200441a8026a200441c8026a200441b8056a10fb0120042802a80221100b200441a8026a21010b201620264f0d04204141016a2001350208422086200135020084202320164105746a10094101460d000b4130210641fbd5c10021050c060b201c2002103e000b200541011030000b201c41041030000b4198bfc10020162026102d000b200441b8056a2015106a0b0240201b201d470d00201b4101742201201b41016a2216200120164b1b221d41ffffff3f71201d470d0e201d41057422014100480d0e02400240201b0d0020011021211e0c010b201e201b41057420011025211e0b201e450d030b201e201b4105746a220120042903b805370000200141186a202e290300370000200141106a2014290300370000200141086a2018290300370000202c2802002040460d014132210641abd6c10021050b02402010450d0020042802ac02450d00201010230b203f450d05200428029c02450d05203e10230c050b02402010450d0020042802ac02450d00201010230b0240203f450d00200428029c02450d00203d10230b201b41016a211b20112012460d060c010b0b200141011030000b201641041030000b200141041030000b0240201d450d00201e10230b0240200f450d00201910230b02402022450d00201310230b02402009a7450d00202310230b200441f8006a41186a20044198016a41186a290200370300200441f8006a41106a20044198016a41106a290200370300200441c8006a211a0b201a41046a280200450d06201a28020010230c060b200441b8056a41186a22084200370300200441b8056a41106a22164200370300200441b8056a41086a22024200370300200442003703b805200441b0076a41086a220141c4fbc400ad4280808080e000841003220541086a290000370300200420052900003703b0072005102320022001290300370300200420042903b0073703b805200141f9bcc000ad4280808080e000841003220541086a290000370300200420052900003703b00720051023200441c8026a41086a22062001290300221f370300200420042903b00722203703c802200a2020370000200a41086a221c201f37000020044188046a41086a2210200229030037030020044188046a41106a2218201629030037030020044188046a41186a221a2008290300370300200420042903b80537038804200441206a20044188046a4120108f012004280224211720042802202111200842003703002016420037030020024200370300200442003703b805200141f7fbc400ad4280808080f000841003220541086a290000370300200420052900003703b0072005102320022001290300370300200420042903b0073703b80520014194b7c200ad4280808080c001841003220541086a290000370300200420052900003703b0072005102320062001290300221f370300200420042903b00722203703c802200a2020370000201c201f3700002010200229030037030020182016290300370300201a2008290300370300200420042903b80537038804200441186a20044188046a4120108f0120042802182102200428021c2116200e412c6c2208412c6e2101410421064100211c024002402008450d002001410274220510212206450d012001211c0b2017410020111b21102016410020021b21184100211620062101200b2102034020012002280200360200201641016a2116200141046a21012002412c6a2102200841546a22080d000b20044198016a41186a200441f8016a41186a29030037030020044198016a41106a200441f8016a41106a29030037030020044198016a41086a200441f8016a41086a290300370300200420042903f801370398010240200f450d00201910230b02402022450d00201310230b02402009a7450d00202310230b200441d8006a41086a220f20044198016a41086a2228290300370300200441d8006a41106a220e20044198016a41106a290300370300200441d8006a41186a221a20044198016a41186a290300370300200420042903980137035842002121200441b8056a41186a22084200370300200441b8056a41106a22054200370300200441b8056a41086a22024200370300200442003703b805200441b0076a41086a220141c4fbc400ad4280808080e000841003221941086a290000370300200420192900003703b0072019102320022001290300370300200420042903b0073703b805200141f9bcc000ad4280808080e000841003221941086a290000370300200420192900003703b00720191023200441c8026a41086a221920012903002209370300200420042903b007221f3703c802200a201f370000200a41086a2217200937000020044188046a41086a2211200229030037030020044188046a41106a2215200529030037030020044188046a41186a22142008290300370300200420042903b80537038804200441106a20044188046a4120108f012004280214211220042802102113200341086a280200210c2003280200213c200441e4026a201b360200200441c8026a41186a201d360200200441c8026a41106a2016360200200441d4026a201c360200200441f0026a200f290300370300200441f8026a200e29030037030020044180036a201a2903003703002004201e3602dc02200420063602d002200420183602cc02200420103602c802200420042903583703e802203c200c200441c8026a108a022004420037029c01200441d8a7c30036029801200842003703002005420037030020024200370300200442003703b80520014182fdc400ad4280808080a001841003221641086a290000370300200420162900003703b0072016102320022001290300370300200420042903b0073703b805200141f4c9c100ad4280808080d001841003221641086a290000370300200420162900003703b00720161023201920012903002209370300200420042903b007221f3703c802200a201f37000020172009370000201120022903003703002015200529030037030020142008290300370300200420042903b80537038804200441c8026a20044188046a4120108b020240024020042802c802223d0d004104213d41002101410021100c010b20042902cc022221422088a721012021a721100b2012410020131b213a200c450d034100203a417f6a22012001203a4b1b2138203c200c41d0016c6a2142200441c8026aad4280808080c00084211f20044188076a41186a214320044188076a41086a213e20044188076a41146a212a20044188076a410472212d200441c8026a4104722144200441b8056a410272221241266a212e201241206a21230340203c2802102131200441b0076a41086a222b4182fdc400ad4280808080a0018422201003220141086a290000370300200420012900003703b00720011023203e202b290300370300200420042903b00737038807202b41ecbdc100ad4280808080d000841003220141086a290000370300200420012900003703b0072001102320044188046a41086a2211202b290300370300200420042903b00737038804200420313602c802200441b8056a41186a2230201f1001220141186a290000370300200441b8056a41106a2222200141106a290000370300200441b8056a41086a221a200141086a290000370300200420012900003703b80520011023200441b8016a41186a22392030290300370300200441b8016a41106a223b2022290300370300200441b8016a41086a2241201a290300370300200420042903b8053703b8010240024041c00010212201450d002001200429038807370000200141086a203e2903003700002001200429038804370010200141186a2011290300370000200120042903b801370020200141286a2041290300370000200141306a203b290300370000200141386a2039290300370000200420013602c802203c411c6a2802002102200441c0003602cc02203c2802142002200441c8026a10c50120011023202b20201003220141086a290000370300200420012900003703b00720011023203e202b290300370300200420042903b00737038807202b41f1bdc100ad4280808080a001841003220141086a290000370300200420012900003703b007200110232011202b290300370300200420042903b00737038804200420313602c8022030201f1001220141186a2900003703002022200141106a290000370300201a200141086a290000370300200420012900003703b8052001102320392030290300370300203b20222903003703002041201a290300370300200420042903b8053703b801024041c00010212202450d002002200429038807370000200241086a203e2903003700002002200429038804370010200241186a2011290300370000200220042903b801370020200241286a2041290300370000200241306a203b290300370000200241386a2039290300370000200441086a200241c000108f01200428020c210120042802082108200420383602c8022002ad4280808080800884201f100220021023024020084101470d00200120384f0d000340200420313602cc02200420013602c802200441c8026a10fc012038200141016a2201470d000b0b203c2802282201450d02203c2802202218200141246c6a212702400240034020182802002119200441f8016a41186a22402018411c6a290000370300200441f8016a41106a223f201841146a290000370300200441f8016a41086a22292018410c6a290000370300200420182900043703f801024002400240024002400240200428029801220141d8a7c300460d00200428029c0121060c010b202e420037010020234200370100201241186a4200370100201241106a4200370100201241086a420037010020124200370100200441c8026a410041840110db041a41b80110212201450d014100210620014100360200200120042903b8053702042001410c6a201a290300370200200141146a20222903003702002001411c6a2030290300370200200141246a200441b8056a41206a2903003702002001412c6a200441b8056a41286a290300370200200141346a200441c8026a41840110dc041a2004410036029c0120042001360298010b201841246a211802400340200141086a210820012f0106221c4102742102417f211602400340024020020d00201c21160c020b200828020021052002417c6a2102201641016a2116200841046a21080240417f2005201947200520194b1b41016a0e03020001020b0b41012108202a2105202d21020c020b02402006450d002006417f6a2106200120164102746a41b8016a28020021010c010b0b2004201936028c074100210620432105203e2102410021080b2002201636020c2002200136020420022006360200200220044198016a36020820052028360200200420083602880702402008450d00200428029007200428029807410c6c6a41346a210f0c040b20042802a0072201200128020041016a360200200428028c072108200428029c07210220042802940722012f01062216410b490d012004280298072137202e420037010020234200370100201241186a22264200370100201241106a22354200370100201241086a2234420037010020124200370100200441c8026a410041840110db041a024041b80110212210450d0020104100360200201020042903b8053702042010410c6a201a290300370200201041146a20222903003702002010411c6a2030290300370200201041246a200441b8056a41206a22362903003702002010412c6a200441b8056a41286a222c290300370200201041346a200441c8026a41840110dc042105200441c8026a41086a221c20014184016a2802003602002004200129027c3703c80220012802202114201041086a200141246a20012f010641796a221641027410dc042119200520014188016a2016410c6c10dc042105200141063b0106201020163b0106201a201c280200360200200420042903c8023703b8050240024020024107490d00200241027420196a41686a2019200241796a22064102746a2219201641ffff037120066b41027410dd041a201920083602002002410c6c20056a220241b87f6a200241ac7f6a220f201041066a22162f010020066b410c6c10dd041a0c010b200141086a20024102746a220541046a2005200141066a22162f010020026b41027410dd041a20052008360200200141346a2002410c6c6a220f410c6a200f20162f010020026b410c6c10dd041a0b200f4100360208200f4204370200201620162f010041016a3b01002011201a2802002202360200200441d8016a41086a22152002360200200420042903b805220937038804200420093703d80120012802002219450d0320012f0104210e0340200441e8066a41086a22132015280200360200200420042903d8013703e806200e41ffff037121050240024002400240024020192f01062201410b490d00202e420037010020234200370100202642003701002035420037010020344200370100201242003701002011201a29030037030020044188046a41106a2201202229030037030020044188046a41186a2202203029030037030020044188046a41206a2216203629030037030020044188046a41286a2206202c290300370300200420042903b80537038804200441c8026a410041b40110db041a41e80110212208450d032008410036020020082004290388043702042008410c6a2011290300370200200841146a20012903003702002008411c6a2002290300370200200841246a20162903003702002008412c6a2006290300370200200841346a200441c8026a41b40110dc042102201941206a280200211b201c20194184016a2802003602002004201941fc006a2902003703c802200841086a201941246a20192f0106221641796a220141027410dc04211d200220194188016a2001410c6c10dc04211e200841b8016a201941d4016a2016417a6a220641027410dc042117201941063b0106200820013b010602402006450d00410021012017210203402002280200221620013b010420162008360200200241046a21022006200141016a2201470d000b0b201a201c2802002201360200200420042903c80222093703b805201c2001360200200420093703c802200e41ffff037122024107490d01201d2005417a6a220241027422066a201d200541796a22014102746a221620082f010620016b41027410dd041a201620143602002005410c6c201e6a221641b87f6a201641ac7f6a221620082f010620016b410c6c10dd041a201641086a2013280200360200201620042903e806370200200820082f010641016a22163b01062005410274220e20176a416c6a201720066a2206201641ffff0371220520026b41027410dd041a2006201036020020052002490d022008200e6a41a0016a2102034020022802002216200141016a22013b010420162008360200200241046a210220012005490d000c030b0b201941086a2202200541016a220841027422166a2002200541027422066a2202200120056b221c41027410dd041a2002201436020020192005410c6c6a220241c0006a200241346a220e201c410c6c10dd041a2002413c6a2013280200360200200e20042903e8063702002019200141016a22013b01062006201941b8016a22026a41086a200220166a2202200141ffff0371221620086b41027410dd041a20022010360200200520164f0d0920192008417f6a22014102746a41bc016a2102034020022802002208200141016a22013b010420082019360200200241046a210220012016490d000c0a0b0b201941086a2201200541016a220e41027422166a2001200541027422066a220120192f0106221720056b221d41027410dd041a20012014360200201941346a2005410c6c6a2201410c6a2001201d410c6c10dd041a200141086a2013280200360200200120042903e8063702002019201741016a22013b01062006201941b8016a22176a41086a201720166a2217200141ffff03712216200e6b41027410dd041a20172010360200200220164f0d00201920066a41bc016a2101034020012802002202200541016a22053b010420022019360200200141046a210120162005470d000b0b2015201c280200360200200420042903c8023703d801201928020022010d0120082110201b21140c060b41e80141041030000b20192f0104210e20012119201b2114200821100c000b0b41b80141041030000b41b80141041030000b200120024102746a2205410c6a200541086a2205201620026b41027410dd041a2005200836020020012002410c6c6a220841c0006a200841346a220f20012f010620026b410c6c10dd041a2008413c6a4100360200200f4204370200200120012f010641016a3b01060c010b202e420037010020234200370100202642003701002035420037010020344200370100201242003701002011201a29030037030020044188046a41106a2202202229030037030020044188046a41186a2208203029030037030020044188046a41206a2216203629030037030020044188046a41286a2205202c290300370300200420042903b80537038804200441c8026a410041b40110db041a41e80110212201450d022001410036020020012004290388043702042001410c6a2011290300370200200141146a20022903003702002001411c6a2008290300370200200141246a20162903003702002001412c6a2005290300370200200141346a200441c8026a41b40110dc0421082001203728020022023602b801203720013602002037203728020441016a360204200241003b010420022001360200200820012f01062202410c6c6a220820042903d801370200200841086a2015280200360200200120024102746a41086a2014360200200141b8016a200241016a22024102746a2010360200200120023b0106201020023b0104201020013602000b200441c8026a41186a22022040290300370300200441c8026a41106a2208203f290300370300200441c8026a41086a22162029290300370300200420042903f8013703c8020240200f2802082201200f41046a2205280200470d00200141016a22192001490d0d200141017422062019200620194b1b2219ad42247e2209422088a70d0d2009a722064100480d0d0240024020010d002006102121010c010b200f280200200141246c2006102521010b2001450d03200f200136020020052019360200200f28020821010b200f280200200141246c6a220120042903c802370204200120313602002001410c6a2016290300370200200141146a20082903003702002001411c6a2002290300370200200f200f28020841016a36020820182027470d000c050b0b41e80141041030000b200641041030000b41c00041011030000b41c00041011030000b02400240203c41346a2802002206450d00203c28022c2101202b20201003220241086a290000370300200420022900003703b00720021023203e202b290300370300200420042903b00737038807202b41acc9c100ad4280808080e002841003220241086a290000370300200420022900003703b007200210232011202b290300370300200420042903b00737038804200420313602c8022030201f1001220241186a2900003703002022200241106a290000370300201a200241086a290000370300200420022900003703b8052002102320392030290300370300203b20222903003703002041201a290300370300200420042903b8053703b801024002400240024002400240024002400240024002400240024002400240024041c00010212219450d002019200429038807370000201941086a203e2903003700002019200429038804370010201941186a2011290300370000201920042903b801370020201941286a2041290300370000201941306a203b290300370000201941386a2039290300370000200441c8026a201941c000108602200141086a210220042802d002211c20042802cc02211020042802c802210f410021082006410474220521160340200228020020086a2108200241106a2102201641706a22160d000b200441013602c80220042008201c4100200f41014622021b6a3602d00220042010410020021b20066a3602cc02201941c0002044108c0220191023202b20201003220241086a290000370300200420022900003703b00720021023203e202b290300370300200420042903b00737038807202b41e8c8c100ad4280808080a002841003220241086a290000370300200420022900003703b007200210232011202b290300370300200420042903b00737038804200420313602c8022030201f1001220241186a2900003703002022200241106a290000370300201a200241086a290000370300200420022900003703b8052002102320392030290300370300203b20222903003703002041201a290300370300200420042903b8053703b80141c0001021221c450d01201c200429038807370000201c41086a203e290300370000201c200429038804370010201c41186a2011290300370000201c20042903b801370020201c41286a2041290300370000201c41306a203b290300370000201c41386a2039290300370000200441b8056a201cad4280808080800884220910041090010240024020042802b8050d00200441003602d002200442013703c8024100200441c8026a105c200441f8016a41086a20042802d002360200200420042903c8023703f8010c010b200441f8016a41086a201a280200360200200420042903b8053703f8010b200441e8066a41086a200441f8016a41086a2802002202360200200420042903f8013703e806024002400240024002402002450d00200441c8026a20042802e80620022006106920042802c8024101460d0420042802cc02211920042802d402220220042802d0022208460d0320042802f006200220086b6a221620064102746a2206417f4c0d1920060d01410121100c020b2006200441e8066a105c034002402001410c6a2d000022024103714103460d00024002400240024020020e03000102000b410021080c020b410121080c010b410221080b200420083a00c8020240024020042802ec0620042802f0062202460d0020042802e80621160c010b200241016a22082002490d1f200241017422162008201620084b1b22084100480d1f0240024020020d002008102121160c010b20042802e80620022008102521160b2016450d09200420083602ec06200420163602e80620042d00c802210820042802f00621020b2004200241016a3602f006201620026a20083a00000b20012802002119200141086a2802002202200441e8066a105c0240024020042802ec06221620042802f00622086b2002490d0020042802e80621160c010b200820026a22062008490d1e201641017422082006200820064b1b22084100480d1e0240024020160d002008102121160c010b20042802e80620162008102521160b2016450d09200420083602ec06200420163602e80620042802f00621080b200141106a21012004200820026a3602f006201620086a2019200210dc041a200541706a22050d000c120b0b200610212210450d070b2004200636028c0720042010360288072004201636029007200420044188076a3602c8022019200441c8026a200210920120162002490d0720042802900722192016490d0820042802f00622192008490d09200428028807210620042802e80621102004201620026b22163602b0072004201920086b221936027820162019470d0a200620026a201020086a201610dc041a034002402001410c6a2d000022024103714103460d00024002400240024020020e03000102000b410021080c020b410121080c010b410221080b200420083a00c80202400240200428028c072004280290072202460d0020042802880721160c010b200241016a22082002490d1d200241017422162008201620084b1b22084100480d1d0240024020020d002008102121160c010b20042802880720022008102521160b2016450d0e2004200836028c07200420163602880720042d00c802210820042802900721020b2004200241016a36029007201620026a20083a00000b20012802002119200141086a280200220220044188076a105c02400240200428028c07221620042802900722086b2002490d0020042802880721160c010b200820026a22062008490d1c201641017422082006200820064b1b22084100480d1c0240024020160d002008102121160c010b20042802880720162008102521160b2016450d0e2004200836028c07200420163602880720042802900721080b200141106a21012004200820026a36029007201620086a2019200210dc041a200541706a22050d000b2004280290072102200428028c072108200428028807210120042802ec06450d1020042802e80610230c100b2004200441e8066a3602c8022019200441c8026a2008109201034002402001410c6a2d000022024103714103460d00024002400240024020020e03000102000b410021080c020b410121080c010b410221080b200420083a00c8020240024020042802ec0620042802f0062202460d0020042802e80621160c010b200241016a22082002490d1c200241017422162008201620084b1b22084100480d1c0240024020020d002008102121160c010b20042802e80620022008102521160b2016450d0f200420083602ec06200420163602e80620042d00c802210820042802f00621020b2004200241016a3602f006201620026a20083a00000b20012802002119200141086a2802002202200441e8066a105c0240024020042802ec06221620042802f00622086b2002490d0020042802e80621160c010b200820026a22062008490d1b201641017422082006200820064b1b22084100480d1b0240024020160d002008102121160c010b20042802e80620162008102521160b2016450d0f200420083602ec06200420163602e80620042802f00621080b200141106a21012004200820026a3602f006201620086a2019200210dc041a200541706a2205450d0f0c000b0b20042802ec06450d0f20042802e80610230c0f0b41c00041011030000b41c00041011030000b200841011030000b200841011030000b200641011030000b20022016103e000b201620191036000b20082019103e000b200441b8056a41146a410d360200200441c4056a410e36020020044188046a41146a41033602002004420337028c04200441acb6c600360288042004410e3602bc052004200441b0076a3602b8012004200441f8006a3602d801200442043703d802200442013702cc0220044180b7c6003602c8022004200441b8056a360298042004200441c8026a3602c8052004200441d8016a3602c0052004200441b8016a3602b80520044188046a41bcb7c6001038000b200841011030000b200841011030000b200841011030000b200841011030000b20042802f006210220042802ec06210820042802e80621010b2001450d0020092002ad4220862001ad8410022008450d00200110230b201c1023410021010240024002400240024002402021422088a7220541014b0d0020050e020201020b20052102034020012002410176220820016a22162031203d20164102746a280200491b2101200220086b220241014b0d000b0b02402031203d20014102746a2802002202470d0041ecd8c100ad4280808080c0048410080c050b2001203120024b6a220120054b0d010b20052021a7460d01202121090c020b4180bbc000102b000b200541016a22022005490d0920054101742208200220022008491b220241ffffffff03712002470d09200241027422084100480d090240024020050d0020081021213d0c010b203d200541027420081025213d0b203d450d022002ad21090b203d20014102746a220241046a2002200520016b41027410dd041a20022031360200200942ffffffff0f8320214280808080107c428080808070838421210b203c41d0016a223c2042460d040c010b0b200841041030000b200541041030000b102f000b2021422088a721012021a721100b200441b8016a41186a4200370300200441b8016a41106a22264200370300200441b8016a41086a22084200370300200442003703b801200441b0076a41086a22024182fdc400ad4280808080a001841003221641086a290000370300200420162900003703b0072016102320082002290300370300200420042903b007220937038807200420093703b801200241f4c9c100ad4280808080d001841003221641086a290000370300200420162900003703b00720161023202620042903b0072209370300200441d8016a41086a2008290300370300200441d8016a41106a2009370300200441d8016a41186a20022903003703002004200937038804200420042903b8013703d801200441003602d002200442013703c8022001200441c8026a105c024002400240024002400240024002400240024020010d0020042802d002211920042802cc02210520042802c80221020c010b20014102742106410020042802d00222016b210820042802cc022105203d211603402016280200211c02400240200520086a4104490d0020042802c80221020c010b200141046a22022001490d0c200541017422192002201920024b1b22194100480d0c0240024020050d002019102121020c010b20042802c80220052019102521020b2002450d03200420193602cc02200420023602c802201921050b201641046a21162004200141046a22193602d002200220016a201c3600002008417c6a2108201921012006417c6a22060d000b0b200441d8016aad4280808080800484222f2019ad4220862002ad84100202402005450d00200210230b02402010450d00203d10230b20042802a0012105200428029801210102400240200428029c0122080d00200121020c010b2008211620012102034020022802b80121022016417f6a22160d000b0340200120012f01064102746a41b8016a28020021012008417f6a22080d000b0b200441e4026a20012f0106360200200441c8026a41186a4100360200200441dc026a2001360200200420053602e802200441003602d802200442003703d002200420023602cc02200441003602c802200441b8056a200441c8026a10b501024020042802bc05221c450d004182fdc400ad4280808080a00184210941fbbdc100ad4280808080f00184211f034020042802c405210820042802c005211020042802b8052116200441b0076a41086a220120091003220241086a290000370300200420022900003703b0072002102320044188076a41086a22052001290300370300200420042903b007370388072001201f1003220241086a290000370300200420022900003703b0072002102320044188046a41086a22192001290300370300200420042903b00737038804410410212201450d032001203a36000020014104410810252202450d0420022016360004200441b8056a41186a22162002ad42808080808001841001220141186a290000370300200441b8056a41106a2206200141106a290000370300200441b8056a41086a220f200141086a290000370300200420012900003703b80520011023200441b8016a41186a22012016290300370300200441b8016a41106a22162006290300370300200441b8016a41086a2218200f290300370300200420042903b8053703b8012002102341c00010212206450d052006200429038807370000200641086a20052903003700002006200429038804370010200641186a2019290300370000200620042903b801370020200641286a2018290300370000200641306a2016290300370000200641386a2001290300370000200441003602c005200442013703b8052008200441b8056a105c02402008450d00201c200841246c6a2119201c21020340200228020021160240024020042802bc05220820042802c00522016b4104490d0020042802b80521080c010b200141046a22052001490d0e200841017422012005200120054b1b22014100480d0e0240024020080d002001102121080c010b20042802b80520082001102521080b2008450d09200420013602bc05200420083602b80520042802c00521010b2004200141046a3602c005200820016a20163600002004200441b8056a36028804200241046a20044188046a106b200241246a22022019470d000b0b20042802bc0521012006ad428080808080088420043502c00542208620042802b8052202ad84100202402001450d00200210230b2006102302402010450d00201c10230b200441b8056a200441c8026a10b50120042802bc05221c0d000b0b200441b8056a200441c8026a10b5010240034020042802bc052201450d01024020042802c005450d00200110230b200441b8056a200441c8026a10b5010c000b0b20042802cc02220141d8a7c300460d0720012802002108200110232008450d0720082802002102200810232002450d07200228020022010d050c060b201941011030000b410441011030000b410841011030000b41c00041011030000b200141011030000b0340200210232001210220012802002208210120080d000b0b200210230b200441b8056a41186a22174200370300200441b8056a41106a22114200370300200441b8056a41086a220e4200370300200442003703b805200441b0076a41086a22104182fdc400ad4280808080a0018422091003220141086a290000370300200420012900003703b00720011023200e2010290300370300200420042903b0073703b805201041f4c9c100ad4280808080d0018422241003220141086a290000370300200420012900003703b00720011023200441c8026a41086a2010290300221f370300200420042903b00722203703c802200a2020370000200a41086a201f37000020044188046a41086a221a200e29030037030020044188046a41106a201129030037030020044188046a41186a2017290300370300200420042903b80537038804200441c8026a20044188046a4120108b0220042802c8022201410420011b21344100211b024020042902cc02420020011b2225422088a72235450d00203420354102746a212e200441c8026aad4280808080c00084211f20044188076a41086a2102200441c8026a41067221144100211b41002113410021302034211c02400340201b211e201020091003220141086a290000370300200420012900003703b0072001102320022010290300370300200420042903b00737038807201041acc9c100ad4280808080e0028422201003220141086a290000370300200420012900003703b00720011023201a2010290300370300200420042903b007370388042004201c2802003602c8022017201f1001220141186a2900003703002011200141106a290000370300200e200141086a290000370300200420012900003703b80520011023200441b8016a41186a22082017290300370300200441b8016a41106a22162011290300370300200441b8016a41086a2205200e290300370300200420042903b8053703b80102400240024002400240024041c00010212201450d002001200429038807370000200141086a20022903003700002001200429038804370010200141186a201a290300370000200120042903b801370020200141286a2005290300370000200141306a2016290300370000200141386a2008290300370000200441c8026a200141c00010860220042802d002211920042802cc02210620042802c802210f200110234101210120064100200f410146220f1b211220194100200f1b211d02402013450d00201220136a41e50049201d20306a41a19c01497121010b201e41016a211b2012450d052001450d05201020091003220141086a290000370300200420012900003703b0072001102320022010290300370300200420042903b00737038807201020201003220141086a290000370300200420012900003703b00720011023201a2010290300370300200420042903b007370388042004201c2802003602c8022017201f1001220141186a2900003703002011200141106a290000370300200e200141086a290000370300200420012900003703b8052001102320082017290300370300201620112903003703002005200e290300370300200420042903b8053703b80141c00010212201450d012001200429038807370000200141086a20022903003700002001200429038804370010200141186a201a290300370000200120042903b801370020200141286a2005290300370000200141306a2016290300370000200141386a20082903003700002001ad4280808080800884100520011023201020091003220141086a290000370300200420012900003703b0072001102320022010290300370300200420042903b00737038807201041e8c8c100ad4280808080a002841003220141086a290000370300200420012900003703b00720011023201a2010290300370300200420042903b007370388042004201c2802003602c8022017201f1001220141186a2900003703002011200141106a290000370300200e200141086a290000370300200420012900003703b8052001102320082017290300370300201620112903003703002005200e290300370300200420042903b8053703b80141c00010212201450d022001200429038807370000200141086a20022903003700002001200429038804370010200141186a201a290300370000200120042903b801370020200141286a2005290300370000200141306a2016290300370000200141386a2008290300370000200441c0003602fc01200420013602f80120044188046a2001ad4280808080800884222110041090010240024020042802880422160d00410021080c010b200428028c04210520042004280290043602ec06200420163602e806200441c8026a200441e8066a1080010240024020042802c8022208450d0020042902cc0221200c010b200441003602c005200442013703b8052004410c36028c072004200441f8016a360288072004200441b8056a3602d801200441013602dc02200442013702cc0220044198c2c3003602c802200420044188076a3602d802200441d8016a41b8a3c500200441c8026a102e1a20043502c00542208620043502b80584100820042802bc05450d0020042802b80510230b02402005450d00201610230b024020080d00410021080c010b202110050b200110232008410420081b22222020420020081b2220422088a722014104746a21192020a72123024020010d00202221010c040b20222101034002402001410c6a2d0000220f4103470d00200141106a21010c050b200141046a280200211620012802002108200141086a28020021052004201c28020022063602b801200420053602dc01200420083602d80120044188046a200441d8016a10d9010240200428028804411a460d00200441b8056a20044188046a41b00110dc041a41032105024002400240200f4103710e03010200010b41002105410021150c010b200441c8026a200441b8016a108702200441e8066a41086a201441086a290100370300200441e8066a41106a201441106a290100370300200441e8066a41186a201441186a2f01003b0100200420142901003703e80620042801ca02210620042f01c802211841012115410021050b200441c8026a200441b8056a41b00110dc041a200220042903e806370200200241086a200441e8066a41086a290300370200200241106a200441e8066a41106a290300370200200241186a200441e8066a41186a2903003702002004200636028c07200420183b018a07200420153a008907200420053a008807200441f8016a200441c8026a20044188076a108d020b02402016450d00200810230b200141106a22012019470d000c050b0b41c00041011030000b41c00041011030000b41c00041011030000b20012019460d0003402001410c6a2d00004103460d010240200141046a280200450d00200128020010230b200141106a22012019470d000b0b02402023450d00202210230b201220136a221341e3004b0d02201d20306a2230419f9c014b0d020b201c41046a221c202e470d000b0b201e2035490d00201b2035103e000b200441b8016a41186a22084200370300200441b8016a41106a22164200370300200441b8016a41086a22014200370300200442003703b801201020091003220241086a290000370300200420022900003703b0072002102320012010290300370300200420042903b007220937038807200420093703b801201020241003220241086a290000370300200420022900003703b00720021023201a20102903002209370300200420042903b007221f370388042026201f370000202641086a2009370000200441d8016a41086a2001290300370300200441d8016a41106a2016290300370300200441d8016a41186a2008290300370300200420042903b8013703d801200441003602d002200442013703c8022035201b6b2201200441c8026a105c02400240024020010d0020042802d002211920042802cc02210520042802c80221020c010b2035410274201b41027422026b2106410020042802d00222016b2108203420026a211620042802cc02210503402016280200211c02400240200520086a4104490d0020042802c80221020c010b200141046a22022001490d05200541017422192002201920024b1b22194100480d050240024020050d002019102121020c010b20042802c80220052019102521020b2002450d03200420193602cc02200420023602c802201921050b201641046a21162004200141046a22193602d002200220016a201c3600002008417c6a2108201921012006417c6a22060d000b0b202f2019ad4220862002ad84100202402005450d00200210230b02402025a7450d00203410230b20042802502102200428024c21102004280248220f21080c010b201941011030000b200441d8016a41186a22194200370300200441d8016a41106a22064200370300200441d8016a41086a22164200370300200442003703d801200441b0076a41086a22014182fdc400ad4280808080a001841003220541086a290000370300200420052900003703b0072005102320162001290300370300200420042903b007220937038807200420093703d801200141b39fc600ad42808080809001841003220541086a290000370300200420052900003703b0072005102320044188046a41086a20012903002209370300200420042903b007221f370388042007201f370000200741086a2009370000200441b8016a41086a2016290300370300200441b8016a41106a2006290300370300200441b8016a41186a2019290300370300200420042903d8013703b801200441003602d002200442013703c8022002200441c8026a105c02400240024020020d0020042802d002211920042802cc02210520042802c80221020c010b20024102742106410020042802d00222016b211620042802cc02210503402008280200211c02400240200520166a4104490d0020042802c80221020c010b200141046a22022001490d04200541017422192002201920024b1b22194100480d040240024020050d002019102121020c010b20042802c80220052019102521020b2002450d03200420193602cc02200420023602c802201921050b200841046a21082004200141046a22193602d002200220016a201c3600002016417c6a2116201921012006417c6a22060d000b0b200441b8016aad42808080808004842019ad4220862002ad84100202402005450d00200210230b02402010450d00200f10230b0240200da7450d00200b10230b200328020021080240200c450d00200c41d0016c21022008210103402001106c200141d0016a2101200241b07e6a22020d000b0b410021050240200341046a280200450d00200810230b0c040b201941011030000b102a000b200da7450d00200b10230b20032802002108024020032802082201450d00200141d0016c21022008210103402001106c200141d0016a2101200241b07e6a22020d000b0b200341046a280200450d00200810230b2000200636020420002005360200200441c0076a24000bb70201037f230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100410900102400240200328020822010d00200041003602000c010b200341106a2802002102200328020c2104200341003602380240024020024104490d0020012800002105200341003602382002417c714104460d00200041086a200128000436020020002005360204200041013602000c010b20034100360220200342013703182003410c36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c20034198c2c3003602382003200341286a360248200341346a41b8a3c500200341386a102e1a2003350220422086200335021884100820004100360200200328021c450d00200328021810230b2004450d00200110230b200341d0006a24000bbf0301067f230041d0006b22022400200241f0003a000802400240024002400240410110212203450d00200341f0003a0000200241e1003a000820034101410210252203450d01200341e1003a0001200241f2003a000820034102410410252204450d02200441f2003a0002200441e1003a0003200128020021014108210320044104410810252205450d0320052001360004200241003a004820052101410021060340200241003a0008200241086a20012003410047220410dc041a024020030d00200241003a00080b20032004490d05200241286a20066a20022d00083a00002002200641016a22073a0048200320046b2103200120046a21012007210620074120470d000b200241086a41186a2203200241286a41186a290300370300200241086a41106a2204200241286a41106a290300370300200241086a41086a2201200241286a41086a2903003703002002200229032837030820051023200041186a2003290300370000200041106a2004290300370000200041086a200129030037000020002002290308370000200241d0006a24000f0b410141011030000b410241011030000b410441011030000b410841011030000b20042003103e000be10402057f047e230041e0006b22062400200641c0006a41086a220741d5fbc400ad42808080808001841003220841086a2900003703002006200829000037034020081023200641206a41086a2209200729030037030020062006290340370320200741e3a0c200ad4280808080b001841003220841086a2900003703002006200829000037034020081023200641306a41086a220a200729030037030020062006290340370330200641c0006a200110ac010240024002400240024041c00010212208450d00200820062903203700002008200629033037001020082006290040370020200841086a2009290300370000200841186a200a290300370000200841286a2007290000370000200841306a200641c0006a41106a290000370000200841386a200641c0006a41186a290000370000200641086a200841c000108902200641086a41106a290300210b2006290310210c2006280208210720081023410121080240200c420020071b220c20027d220d200c56200b420020071b220b20037d200c200254ad7d220e200b56200e200b511b4101470d0020004196adc200360204200041086a411d3602000c050b20050d01200c4280c8afa025544100200b501b0d01200d42ffc7afa02556200e420052200e501b0d01200041b3adc200360204200041086a411a3602000c020b41c00041011030000b200620012004200d200e10de0220062802002208450d012006280204210720002008360204200041086a20073602000b410121080c010b2001200d200e10dc02200041106a2003370300200041086a2002370300410021080b20002008360200200641e0006a24000ba80202017f037e230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100410900102400240200328020822010d00420021040c010b200328020c210202400240200341086a41086a2802004110490d00200141086a290000210520012900002106420121040c010b20034100360220200342013703182003410c36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c20034198c2c3003602382003200341286a360248200341346a41b8a3c500200341386a102e1a200335022042208620033502188410080240200328021c450d00200328021810230b420021040b2002450d00200110230b2000200637030820002004370300200041106a2005370300200341d0006a24000bb8380b077f017e027f027e067f027e0c7f017e047f017e067f230041a0036b2203240020022802002104200341f0016a41086a220541a79fc600ad4280808080c001841003220641086a290000370300200320062900003703f00120061023200341d0026a41086a22072005290300370300200320032903f0013703d002200541d4acc600ad42808080808002841003220641086a290000370300200320062900003703f0012006102320034190026a41086a22082005290300370300200320032903f00137039002200320044132702209360220200341e0026a41186a2206200341206aad220a4280808080c000841001220541186a290000370300200341e0026a41106a2204200541106a290000370300200341e0026a41086a220b200541086a290000370300200320052900003703e0022005102320034180036a41186a2205200629030037030020034180036a41106a220c200429030037030020034180036a41086a2204200b290300370300200320032903e00237038003024002400240024002400240024002400240024041c00010212206450d00200620032903d00237000020062003290390023700102006200329038003370020200641086a2007290300370000200641186a2008290300370000200641286a2004290300370000200641306a200c290300370000200641386a2005290300370000200341c00036021420032006360210200341f0016a2006ad4280808080800884220d100410900120032802f0012207450d0320032802f401210b2003200341f8016a28020022053602d402200320073602d00220054104490d012003200741046a3602d00220032005417c6a22043602d40220044104490d012007350000210e2003200541786a22083602d4022003200741086a3602d00241002105200341003a00400340024020082005470d00200341003602d402200541ff0171450d03200341003a00400c030b200341206a20056a200720056a220441086a2d00003a00002003200441096a3602d0022003200541016a22043a00402004210520044120470d000b20034190026a41086a200341206a41086a29030037030020034190026a41106a200341206a41106a29030037030020034190026a41186a200341206a41186a2903003703002003200820046b3602d4022003200329032037039002200341206a200341d0026a107b20032802202204450d0120032802242108200341206a200341d0026a107e02402003280220220f0d002008450d02200410230c020b20034180036a41086a20034190026a41086a29030037030020034180036a41106a20034190026a41106a2903003703002003280224210c410021050c020b41c00041011030000b41002104200341003602980220034201370390022003410c360284032003200341106a36028003200320034190026a3602e00241012105200341346a41013602002003420137022420034198c2c300360220200320034180036a360230200341e0026a41b8a3c500200341206a102e1a2003350298024220862003350290028410080240200328029402450d0020032802900210230b0b0240200b450d00200710230b2005450d010b200610230c010b200d1005200610232004450d00200341f0016a41086a220541a79fc600ad4280808080c001841003220641086a290000370300200320062900003703f00120061023200341d0026a41086a22072005290300370300200320032903f0013703d002200541e4acc600ad4280808080d002841003220641086a290000370300200320062900003703f0012006102320034190026a41086a22062005290300370300200320032903f001370390022003200e3e0220200341e0026a41186a220b200a4280808080c000841001220541186a290000370300200341e0026a41106a2210200541106a290000370300200341e0026a41086a2211200541086a290000370300200320052900003703e0022005102320034180036a41186a2212200b29030037030020034180036a41106a220b201029030037030020034180036a41086a22102011290300370300200320032903e0023703800341c00010212205450d01200520032903d00237000020052003290390023700102005200329038003370020200541086a2007290300370000200541186a2006290300370000200541286a2010290300370000200541306a200b290300370000200541386a20122903003700002005ad4280808080800884100a2005102302402008450d00200410230b200c450d00200f10230b200341206a41186a4200370300200341206a41106a22074200370300200341206a41086a2206420037030020034200370320200341f0016a41086a220541f7fbc400ad4280808080f000841003220441086a290000370300200320042900003703f0012004102320062005290300370300200320032903f001370320200541e7acc500ad4280808080a001841003220441086a290000370300200320042900003703f00120041023200720032903f001220d37030020034190026a41086a200629030037030020034190026a41106a200d37030020034190026a41186a20052903003703002003200d370380032003200329032037039002200341206a20034190026a412010bb010240024020032802202205450d0020032003290224370204200320053602000c010b20034100360208200342013703000b2002411c6a2802002205200120052001491b2213450d0220022802142114200341f0016aad4280808080c000842115200a4280808080800484211620034180036a41106a210f200341e0026a41106a2117200341d8016a2118200341b8016a2119200341f8006a211a200341206a41386a211b200341206a412c6a211c20034190026a41286a211d20034190026a41306a211e4100211f0c010b41c00041011030000b0240024002400240024002400240024002400240024002400240034020034100360218200342013703102000201f41d0016c6a22082802c4012106200841c8016a2802002104200341e0026a41186a2220420037030020174200370300200341e0026a41086a22214200370300200342003703e002200341f0016a41086a221141c6acc500ad4280808080f00084220e1003220541086a290000370300200320052900003703f0012005102320212011290300370300200320032903f0013703e00220114185b2c500ad4280808080e001841003220541086a290000370300200320052900003703f00120051023200341206a41086a22222011290300220d370300200320032903f001222337032020172023370000201741086a200d37000020034190026a41086a2224202129030037030020034190026a41106a2225201729030037030020034190026a41186a22262020290300370300200320032903e0023703900220034180036a20034190026a412010bb010240024020032802800322050d00410021010c010b200329028403220d422088a72101200da7450d00200510230b201f41016a212720034180036a41186a22124200370300200f420037030020034180036a41086a2210420037030020034200370380032011200e1003220541086a290000370300200320052900003703f0012005102320102011290300370300200320032903f001220d370390022003200d370380032011418cfbc500ad4280808080e0028422281003220541086a290000370300200320052900003703f0012005102320242011290300220d370300200320032903f001222337039002200f2023370000200f41086a2229200d37000020222010290300370300200341206a41106a222a200f290300370300200341206a41186a222b2012290300370300200320032903800337032020034190026a200341206a10ae0320032802900221072003280294022105200329039802210d2003200436022420032006360220200d420020051b210d200341003602282007410020051b21072005410420051b210c2003200341106a3602302003200336022c02400340410221060240200341206a10810141ff017122044102460d0020032003280228220541016a3602282004410171450d0141012106200328022c220b28020820054d0d00200328023021042012200b28020020054105746a220b41186a290000370300200f200b41106a2900003703002010200b41086a2900003703002003200b2900003703800302402004280208220b200441046a222c280200470d00200b41016a222d200b490d13200b410174222e202d202e202d4b1b222d41ffffff3f71202d470d13202d410574222e4100480d1302400240200b0d00202e1021210b0c010b2004280200200b410574202e1025210b0b200b450d032004200b360200202c202d3602002004280208210b0b2004280200200b4105746a220b200329038003370000200b41186a2012290300370000200b41106a200f290300370000200b41086a20102903003700002004200428020841016a3602080b0240200641ff01714102460d00200520014f0d01200741146a22042007490d010240200541016a2207200d422088a722064d0d000240200da7220b20066b20072006200720064b1b222d20066b22074f0d00200620076a222c2006490d14200b410174222e202c202e202c4b1b222c41ffffffff0371202c470d14202c410274222e4100480d1402400240200b0d00202e1021210c0c010b200c200b410274202e1025210c0b200c450d06202cad210d0b200c20064102746a210b0240024020074102490d00200b4100202d2006417f736a220741027410db041a200c2006202d6a20066b4102746a417c6a210b200720066a21060c010b2007450d010b200b4100360200200641016a21060b200620054d0d05200c20054102746a2205200528020041146a360200200d42ffffffff0f832006ad42208684210d200421070c010b0b2003200c3602e402200320073602e0022003200d3703e80220124200370300200f42003703002010420037030020034200370380032011200e1003220541086a290000370300200320052900003703f0012005102320102011290300370300200320032903f001220e370390022003200e37038003201120281003220541086a290000370300200320052900003703f0012005102320242011290300220e370300200320032903f001222337039002200f20233700002029200e37000020222010290300370300202a200f290300370300202b2012290300370300200320032903800337032002400240200c0d00201610050c010b20034120360294022003200341206a36029002200341e0026a20034190026a10a904200c450d00200da7450d00200c10230b200828021021072012200841d0006a290000370300200f200841c8006a2900003703002010200841c0006a2900003703002024200841e0006a2903003703002025200841e8006a2903003703002026200841f0006a29030037030020034190026a41206a2201200841f8006a290300370300201d20084180016a290300370300201e20084188016a29030037030020034190026a41386a220b20084190016a290300370300200320082900383703800320032008290358370390022008411c6a2802002205417f4c0d04200828021421060240024020050d00410121040c010b200510212204450d060b20042006200510dc04210c200841286a2802002204ad42247e220d422088a70d04200da72206417f4c0d04200841206a280200212d0240024020060d004104212c0c010b20061021222c450d070b202c202d200610dc04212d2011200841a0016a290300370300200341f0016a41106a222c200841a8016a290300370300200341f0016a41186a222e200841b0016a29030037030020032008290398013703f001200841086a290300210d2008290300210e200341d0026a2008412c6a1079202020122903003703002017200f2903003703002021201029030037030020032003290380033703e002201c20032903d002370200201c41086a200341d0026a41086a22062802003602002003200d3703282003200e37032020032004360248200320043602442003202d3602402003200536023c200320053602382003200c36023420032007360230201b20032903e002370300201b41086a2021290300370300201b41106a2017290300370300201b41186a2020290300370300201a41386a200b290300370300201a41306a201e290300370300201a41286a201d290300370300201a41206a2001290300370300201a41186a2026290300370300201a41106a2025290300370300201a41086a2024290300370300201a200329039002370300201941186a202e290300370300201941106a202c290300370300201941086a2011290300370300201920032903f001370300201841086a200341106a41086a28020036020020182003290310370200200341003602ec01200342013702e401201141a79fc600ad4280808080c001841003220541086a290000370300200320052900003703f0012005102320062011290300370300200320032903f0013703d002201141e4acc600ad4280808080d002841003220541086a290000370300200320052900003703f0012005102320242011290300370300200320032903f00137039002200320022802003602f001202020151001220541186a2900003703002017200541106a2900003703002021200541086a290000370300200320052900003703e0022005102320122020290300370300200f201729030037030020102021290300370300200320032903e0023703800341c00010212204450d07200420032903d00237000020042003290390023700102004200329038003370020200441086a2006290300370000200441186a2024290300370000200441286a2010290300370000200441306a200f290300370000200441386a20122903003700002014201f4105746a22052d00002107410110212206450d08200620073a000020052d0001210720064101410210252206450d09200620073a000120052d0002210720064102410410252206450d0a200620073a0002200620052d00033a000320052d0004210720064104410810252206450d0b200620073a0004200620052d00053a0005200620052d00063a0006200620052d00073a000720052d0008210720064108411010252206450d0c200620073a0008200620052d00093a0009200620052d000a3a000a200620052d000b3a000b200620052d000c3a000c200620052d000d3a000d200620052d000e3a000e200620052d000f3a000f20052d0010210720064110412010252206450d0d200620073a0010200620052d00113a0011200620052d00123a0012200620052d00133a0013200620052d00143a0014200620052d00153a0015200620052d00163a0016200620052d00173a0017200620052d00183a0018200620052d00193a0019200620052d001a3a001a200620052d001b3a001b200620052d001c3a001c200620052d001d3a001d200620052d001e3a001e200620052d001f3a001f20112006ad42808080808004841015220541086a290000370300200320052900003703f0012005102320242011290300370300200320032903f0013703900220061023200441c00041800110252204450d0e2004200329039002370040200441c8006a202429030037000020034100360298022003420137039002200341206a20034190026a10b10120032802d801210520032802e001220620034190026a105c02402006450d00200641057421060340200520034190026a1071200541206a2105200641606a22060d000b0b20032802e401210520032802ec01220620034190026a105c02402006450d00200641057421060340200520034190026a1071200541206a2105200641606a22060d000b0b20032802940221052004ad4280808080800a842003350298024220862003280290022206ad84100202402005450d00200610230b2004102302402003280238450d00200328023410230b02402003280244450d00200328024010230b024020032802542206450d00200328024c21052006410474210603400240200541046a280200450d00200528020010230b200541106a2105200641706a22060d000b0b02402003280250450d00200328024c10230b024020032802dc01450d0020032802d80110230b024020032802e801450d0020032802e40110230b2027211f202720134f0d0f0c010b0b202e41011030000b202e41041030000b4180b9c00020052006102d000b102f000b200541011030000b200641041030000b41c00041011030000b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000b41800141011030000b200341f0016a41086a220541a79fc600ad4280808080c001841003220641086a290000370300200320062900003703f00120061023200341d0026a41086a22012005290300370300200320032903f0013703d002200541d4acc600ad42808080808002841003220641086a290000370300200320062900003703f0012006102320034190026a41086a22082005290300370300200320032903f0013703900220032009360220200341e0026a41186a2206200a4280808080c000841001220541186a290000370300200341e0026a41106a2204200541106a290000370300200341e0026a41086a2207200541086a290000370300200320052900003703e0022005102320034180036a41186a2205200629030037030020034180036a41106a2206200429030037030020034180036a41086a22042007290300370300200320032903e00237038003024002400240024041c0001021220b450d00200b20032903d002370000200b200329039002370010200b200329038003370020200b41086a2001290300370000200b41186a2008290300370000200b41286a2004290300370000200b41306a2006290300370000200b41386a2005290300370000200341003602282003420137032020022802002106410410212205450d012003410436022420032003280228220441046a36022820032005360220200520046a2006360000200228020421040240024020032802242206200328022822056b4104490d00200328022021060c010b200541046a22072005490d05200641017422052007200520074b1b22054100480d050240024020060d002005102121060c010b200328022020062005102521060b2006450d032003200536022420032006360220200328022821050b2003200541046a360228200620056a2004360000200241206a200341206a109e0320022802082106200241106a2802002205200341206a105c02402005450d00200541027421070340200628020021010240024020032802242204200328022822056b4104490d00200328022021040c010b200541046a22082005490d07200441017422052008200520084b1b22054100480d070240024020040d002005102121040c010b200328022020042005102521040b2004450d062003200536022420032004360220200328022821050b200641046a21062003200541046a360228200420056a20013600002007417c6a22070d000b0b20022802142105200228021c2206200341206a105c02402006450d002006410574210603402003200341206a36029002200520034190026a106b200541206a2105200641606a22060d000b0b20032802242105200bad4280808080800884200335022842208620032802202206ad84100202402005450d00200610230b200b102302402003280204450d00200328020010230b02402002410c6a280200450d00200228020810230b0240200241186a280200450d00200228021410230b200341a0036a24000f0b41c00041011030000b410441011030000b200541011030000b200541011030000b102a000bbb0201017f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022010d00200041003602000c010b200328021421022003200341106a41086a28020036022420032001360220200341c8006a200341206a107b024002402003280248450d0020002003290348370200200041086a200341c8006a41086a2802003602000c010b20034100360230200342013703282003410c36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034198c2c3003602482003200341386a360258200341c4006a41b8a3c500200341c8006a102e1a2003350230422086200335022884100820004100360200200328022c450d00200328022810230b2002450d00200110230b200341e0006a24000b4501017f02404108102122030d00410841011030000b20032002280200360000200320022802043600042001ad4220862000ad842003ad42808080808001841002200310230b8ced030b017f017e067f017e017f017e027f027e127f057e107f230041d00d6b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1a000102030405060708090a0b0c0d0e0f10111213141516171819000b200141106a29030021042001410c6a280200210520022d0001210620022d000021020240024002400240024002400240024002400240200141086a28020022070e080009010203040506000b200341b40c6a4101360200200342013702a40c200341d09dc6003602a00c200341043602cc09200341849ec6003602c8092003200341c8096a3602b00c200341a00c6a419cdec0001038000b2004a7210702400240200241ff01710d00200641ff01714101460d010b2007450d9d01200510230c9d010b2007450d9801200510230c98010b200220067241ff01710d9a01410810212202450d202002200437000041acdec000ad4280808080a001842002ad42808080808001841002200210230c97010b2004a721070240200220067241ff0171450d0020070d040c9a010b41b6dec000ad4280808080d000842004428080808070832005ad8410022007450d9601200510230c96010b2004422088a721082004a721090240200220067241ff0171450d0002402008450d00200841186c21062005210203400240200241046a280200450d00200228020010230b0240200241106a280200450d002002410c6a28020010230b200241186a2102200641686a22060d000b0b410121064100210a4103210820090d94010c95010b0240200841186c2202450d00200520026a2106200521020340200241086a350200422086200235020084200241146a3502004220862002410c6a350200841002200241186a22022006470d000b0b02402008450d00200841186c21062005210203400240200241046a280200450d00200228020010230b0240200241106a280200450d002002410c6a28020010230b200241186a2102200641686a22060d000b0b410121064100210a4105210820090d93010c94010b2004422088a721082004a721090240200220067241ff0171450d0002402008450d002008410c6c21062005210203400240200241046a280200450d00200228020010230b2002410c6a2102200641746a22060d000b0b410021064101210a410321082009450d94010c93010b02402008410c6c2202450d00200520026a2106200521020340200241086a35020042208620023502008410052002410c6a22022006470d000b0b02402008450d002008410c6c21062005210203400240200241046a280200450d00200228020010230b2002410c6a2102200641746a22060d000b0b410021064101210a4105210820090d92010c93010b2004a72107200220067241ff0171450d012007450d96010b200510230c95010b2004428080808070832005ad84100a2007450d9101200510230c91010b200220067241ff01710d93010c90010b10be03000b024020022d00000d0020022d000141ff01714102470d00200141086a290300210420034180076a41186a2207420037030020034180076a41106a2202420037030020034180076a41086a22064200370300200342003703800741be99c600ad4280808080900184220b100322052f0000210820052d0002210a2005280003210920052d0007210c2005290008210d200510232006200d3703002003200c3a00870720032009360083072003200a3a008207200320083b01800741b39fc600ad4280808080900184100322052d000221082005280003210a20052d000721092005290008210d20052f0000210c200510232002200c3b0100200341c0056a41186a220c200d370300200341c0056a41086a220e2006290300370300200320093a0097072003200a36009307200320083a009207200341c0056a41106a2208200229030037030020032003290380073703c005200341286a200341c0056a412041014100410010b80120032802284101460d192007420037030020024200370300200642003703002003420037038007200b100322052f0000210720052d0002210a2005280003210920052d0007210f2005290008210b200510232006200b3703002003200f3a00870720032009360083072003200a3a008207200320073b01800741f0cec400ad42808080803084220b100322052d000221072005280003210a20052d000721092005290008210d20052f0000210f200510232002200f3b0100200c200d370300200e2006290300370300200320093a0097072003200a36009307200320073a0092072008200229030037030020032003290380073703c005200341186a200341c0056a109c0202402003290320500d002003280218450d0020034180076a41186a420037030020034180076a41106a2206420037030020034180076a41086a22054200370300200342003703800741be99c600ad4280808080900184100322022f0000210720022d000221082002280003210a20022d000721092002290008210d200210232005200d370300200320093a0087072003200a36008307200320083a008207200320073b01800741f0cec400ad42808080803084100322022d000221072002280003210820022d0007210a2002290008210d20022f0000210920021023200620093b0100200341c0056a41186a200d370300200341c0056a41086a20052903003703002003200a3a0097072003200836009307200320073a009207200341c0056a41106a200629030037030020032003290380073703c005200341086a200341c0056a109c02200329031042b8177c42b81720032802081b2004560d1b0b20034180076a41186a2207420037030020034180076a41106a2202420037030020034180076a41086a22064200370300200342003703800741be99c600ad4280808080900184220d100322052f0000210820052d0002210a2005280003210920052d0007210c2005290008211020051023200620103703002003200c3a00870720032009360083072003200a3a008207200320083b018007200b100322052d000221082005280003210a20052d000721092005290008210b20052f0000210c200510232002200c3b0100200341c0056a41186a220c200b370300200341c0056a41086a220e2006290300370300200320093a0097072003200a36009307200320083a009207200341c0056a41106a2208200229030037030020032003290380073703c005200320043703a00c200341c0056aad42808080808004842204200341a00c6aad220b428080808080018410022007420037030020024200370300200642003703002003420037038007200d100322052f0000210720052d0002210a2005280003210920052d0007210f2005290008210d200510232006200d3703002003200f3a00870720032009360083072003200a3a008207200320073b01800741b39fc600ad4280808080900184100322052d000221072005280003210a20052d000721092005290008210d20052f0000210f200510232002200f3b0100200c200d370300200e2006290300370300200320093a0097072003200a36009307200320073a0092072008200229030037030020032003290380073703c00541012106200341013a00a00c2004200b428080808010841002200041023a0008410121080c96010b20004181043b01082000410f360204200041aab0c0003602002000410a6a41003a00000c8b010b10bf03000b200341e0066a41026a22072001410f6a2d00003a0000200341f00a6a41086a22082001411c6a290200370300200341f00a6a41106a220a200141246a290200370300200341f00a6a41186a22092001412c6a280200360200200320012f000d3b01e0062003200141146a2902003703f00a200141c8006a2903002110200141c0006a2903002111200141386a290300210b2002411a6a290100210d200241196a2d0000210f200241186a2d00002112200241166a2f01002113200241156a2d00002114200241146a2d00002115200241126a2f0100211641112106200241116a2d00002117200241106a2d000021182002410e6a2f010021192002410d6a2d0000211a2002410c6a2d0000211b2002410a6a2f0100211c200241096a2d0000211d200241086a2d0000211e200241066a2f0100211f200241056a2d00002120200241046a2d00002121200241026a2f01002122200141106a28020021052001410c6a2d00002123200141306a290300210420022d0001210c20022d0000210e0240024002400240024002400240024002400240200141086a2802000e050001020304000b200341a00c6a41146a4101360200200342013702a40c200341d09dc6003602a00c200341043602cc09200341849ec6003602c8092003200341c8096a3602b00c200341a00c6a41b49ac3001038000b200341a0086a41086a2008290300370300200341a0086a41106a200a290300370300200341a0086a41186a2009280200360200200320032f01e0063b01c005200320032903f00a3703a008200320072d00003a00c2052003200d370398072003200f3a009707200320123a009607200320133b019407200320143a009307200320153a009207200320163b019007200320173a008f07200320183a008e07200320193b018c072003201a3a008b072003201b3a008a072003201c3b0188072003201d3a00870720034102201f410874202072201e411874724102200c41ff017141014622061b200e41ff017122021b220736008307200320213a008207200320223b0180070240024020020d0020060d010b410f210641aab0c000210220070e05040506079101040b200341c8096a41186a20034180076a41186a290300370300200341c8096a41106a20034180076a41106a290300370300200341c8096a41086a20034180076a41086a29030037030020032003290380073703c8090240202341ff01714101460d0020032f01c00520032d00c205411074722102200341a0086a41106a290300210d20032903a808211020032802b808210620032903a00821110c8c010b20034180076a200541067610bc022003280280072108024002402003280288072005413f7122024b0d00410021070c010b200820024105746a22072f0000200741026a2d0000411074722102200729000f211020072d001f21062007290007211120072800032105200741176a290000210d410121070b0240200328028407450d00200810230b20070d8b01410121070c8c010b200341c8096a41086a2008290300370300200341c8096a41106a200a290300370300200341c8096a41186a2009280200360200200320032f01e0063b01c005200320032903f00a3703c809200320072d00003a00c2054186b0c0002102200c200e7241ff01710d8f0102400240202341ff01714101460d0020032f01c00520032d00c205411074722102200341c8096a41106a290300210d20032903d009212420032802e009210620032903c80921250c010b200341a0086a200541067610bc0220032802a00821080240024020032802a8082005413f7122024b0d00410021070c010b200820024105746a22072f0000200741026a2d0000411074722102200729000f212420072d001f21062007290007212520072800032105200741176a290000210d410121070b024020032802a408450d00200810230b2007450d8d010b200341b70c6a200d370000200320243700af0c200320063a00bf0c200320253700a70c200320053600a30c200320023b01a00c200320024110763a00a20c41d5fbc400ad4280808080800184100322022d000f210620022d000e210520022f000c210720022d000b210820022d000a210a20022f0008210920022d0007210c2002280003210e20022d0002210f20022f000021122002102341e3a0c200ad4280808080b00184100322022d000f211320022d000e211420022f000c211520022d000b211620022d000a211720022f0008211820022d000721192002280003211a20022d0002211b20022f0000211c2002102320034180076a200341a00c6a10ac0141c00010212202450d1f2002200c3a00072002200e3600032002200f3a0002200220123b0000200220063a000f200220053a000e200220073b000c200220083a000b2002200a3a000a200220093b0008200220193a00172002201a3600132002201b3a00122002201c3b0010200220133a001f200220143a001e200220153b001c200220163a001b200220173a001a200220183b0018200241386a20034180076a41186a290300370000200241306a20034180076a41106a290300370000200241286a20034180076a41086a2903003700002002200329038007370020200341b0016a200241c000108902200341b0016a41106a290300210d20032903b801212420032802b0012106200210232024420020061b22242004542207200d420020061b220d200b54200d200b5122021b0d202024200456200d200b5620021b450d8901200341a0056a41186a220a4200370300200341a0056a41106a22024200370300200341a0056a41086a22064200370300200342003703a00541d5fbc400ad42808080808001842225100322052f0000210820052d000221092005280003210c20052d0007210e2005290008212620051023200620263703002003200e3a00a7052003200c3600a305200320093a00a205200320083b01a00541d6a0c200ad4280808080d001842226100322052d000221082005280003210920052d0007210c2005290008212720052f0000210e200510232002200e3b010020034180056a41186a220e202737030020034180056a41086a220f20062903003703002003200c3a00b705200320093600b305200320083a00b20520034180056a41106a22092002290300370300200320032903a0053703800520034198016a20034180056a412010890220034198016a41106a290300212720032903a00121282003280298012108200a42003703002002420037030020064200370300200342003703a0052025100322052f0000210a20052d0002210c2005280003211220052d00072113200529000821252005102320062025370300200320133a00a705200320123600a3052003200c3a00a2052003200a3b01a0052026100322052d0002210a2005280003210c20052d000721122005290008212520052f0000211320051023200220133b0100200e2025370300200f2006290300370300200320123a00b7052003200c3600b3052003200a3a00b20520092002290300370300200320032903a00537038005200342002027420020081b22252007ad200b200d7d7c7c2028420020081b220d202420047d222654ad7d2224200d20267d2226200d56202420255620242025511b22021b3703a80820034200202620021b3703a008200341a0086a210220034180056a21060c88010b200141e0006a290300210d200141d8006a2903002124200141d0006a2903002125200341a0086a41086a2008290300370300200341a0086a41106a200a290300370300200341a0086a41186a2009280200360200200320032f01e0063b01c005200320072d00003a00c205200320032903f00a3703a0084186b0c0002102200c200e7241ff01710d8e010240202341ff01714101460d0020032f01c00520032d00c205411074722102200341a0086a41106a290300212620032903a808212720032802b808210620032903a00821280c86010b200341a00c6a200541067610bc0220032802a00c21080240024020032802a80c2005413f7122024b0d00410021070c010b200820024105746a22072f0000200741026a2d0000411074722102200729000f212720072d001f21062007290007212820072800032105200741176a2900002126410121070b024020032802a40c450d00200810230b20070d8501410121070c86010b200341a0086a41086a2008290300370300200341a0086a41106a200a290300370300200341a0086a41186a2009280200360200200320032f01e0063b01c005200320032903f00a3703a008200320072d00003a00c2052003200d370398072003200f3a009707200320123a009607200320133b019407200320143a009307200320153a009207200320163b019007200320173a008f07200320183a008e07200320193b018c072003201a3a008b072003201b3a008a072003201c3b0188072003201d3a00870720034102201f410874201e411874722020724102200c41ff017141014622061b200e41ff017122021b220736008307200320213a008207200320223b018007024020020d0020060d050b410f210641aab0c000210220070e05000102038d01000b2003280087072102200328008b0721060c8c010b410e210641aabac60021020c8b010b411321064197b0c00021020c8a010b411121064186b0c00021020c89010b200341c8096a41186a20034180076a41186a290300370300200341c8096a41106a20034180076a41106a290300370300200341c8096a41086a20034180076a41086a29030037030020032003290380073703c8090240202341ff01714101460d0020032f01c00520032d00c205411074722102200341a0086a41106a290300210d20032903a808211020032802b808210620032903a00821110c7e0b20034180076a200541067610bc022003280280072108024002402003280288072005413f7122024b0d00410021070c010b200820024105746a22072f0000200741026a2d0000411074722102200729000f211020072d001f21062007290007211120072800032105200741176a290000210d410121070b0240200328028407450d00200810230b20070d7d410121070c7e0b2001410c6a2802002107200141086a28020021142001280204210941aab0c000210e410f210f20022d00000d7a20022d000141ff01714102470d7a200341e0046a41186a22084200370300200341e0046a41106a22024200370300200341e0046a41086a22064200370300200342003703e00441a6a3c500ad4280808080a001842204100322052f0000210a20052d0002210c2005280003210e20052d0007210f2005290008210b200510232006200b3703002003200f3a00e7042003200e3600e3042003200c3a00e2042003200a3b01e0044184a9c500ad4280808080c00184220d100322052d0002210a2005280003210c20052d0007210e2005290008210b20052f0000210f200510232002200f3b010020034180076a41186a220f200b37030020034180076a41086a221220062903003703002003200e3a00f7042003200c3600f3042003200a3a00f20420034180076a41106a220a2002290300370300200320032903e00437038007024020034180076a109b02220541ff01714102460d002005410171450d00418aaac500210e411c210f0c7b0b200842003703002002420037030020064200370300200342003703e0042004100322052f0000210c20052d0002210e2005280003211320052d000721152005290008210b200510232006200b370300200320153a00e704200320133600e3042003200e3a00e2042003200c3b01e004200d100322052d0002210c2005280003210e20052d000721132005290008210b20052f0000211520051023200220153b0100200f200b37030020122006290300370300200320133a00f7042003200e3600f3042003200c3a00f204200a2002290300370300200320032903e00437038007200341013a00a00c20034180076aad42808080808004842211200341a00c6aad428080808010841002200341a0056a41186a4200370300200341a0056a41106a220c4200370300200341a0056a41086a220e4200370300200342003703a00541c4fbc400ad4280808080e00084100322052f0000211320052d000221152005280003211620052d000721172005290008210b20051023200e200b370300200320173a00a705200320163600a305200320153a00a205200320133b01a00541f9bcc000ad4280808080e00084100322052d000221132005280003211520052d000721162005290008210b20052f0000211720051023200c20173b010020034180056a41186a200b37030020034180056a41086a200e290300370300200320163a00b705200320153600b305200320133a00b20520034180056a41106a200c290300370300200320032903a00537038005200341e0016a20034180056a4120108f0120032802e401210c20032802e001210e200842003703002002420037030020064200370300200342003703e0042004100322052f0000210820052d000221132005280003211520052d00072116200529000821042005102320062004370300200320163a00e704200320153600e304200320133a00e204200320083b01e00441fca4c500ad4280808080e00084100322052d000221082005280003211320052d000721152005290008210420052f0000211620051023200220163b0100200f200437030020122006290300370300200320153a00f704200320133600f304200320083a00f204200a2002290300370300200320032903e00437038007200341a00c6a20034180076a10d3020240024020032802a00c22050d0041042105200341043602900c42002104200341a00c6a2106410021020c010b200320053602900c20032902a40c2204422088220ba722022004a7470d1a200341a00c6a21060b024020022004a7470d00200241016a22082002490d772002410174220a2008200a20084b1bad220b42c4007e220d422088a70d77200da722084100480d770240024020020d002008102121050c010b2005200241c4006c2008102521050b2005450d1b200320053602900c200442808080807083200b8421040b2004422088220ba721020c750b200341a00c6a41306a200141386a290300370300200341a00c6a41286a200141306a290300370300200341a00c6a41206a200141286a290300370300200341a00c6a41186a200141206a290300370300200341a00c6a41106a200141186a290300370300200341a00c6a41086a200141106a2903003703002003200141086a2903003703a00c200341c8096a41206a200241206a290200370300200341c8096a41186a200241186a290200370300200341c8096a41106a200241106a290200370300200341c8096a41086a200241086a290200370300200320022902003703c809200341e8016a200341a00c6a200341c8096a10f103024020032802e80122020d00200041023a0008410021050c740b20032802ec012106200041810c3b010820002002360200410021052000410a6a41003a0000200020063602040c730b108003000b200141086a280200211320012802042114200341a00c6a2001410c6a41a40110dc041a2002411a6a2901002104200241196a2d0000210f200241186a2d00002112200241166a2f01002115200241156a2d00002116200241146a2d00002117200241126a2f01002118200241116a2d00002119200241106a2d000021072002410e6a2f010021082002410d6a2d0000210a2002410c6a2d000021092002410a6a2f0100210c200241096a2d0000210e200241046a2d0000211a200241026a2f0100211b200241056a280000210520022d0000210620022d00012102200341c0056a200341a00c6a41046a41a00110dc041a410220054102200241014622021b20061b21050240024020060d0020020d010b410f210641aab0c0002102024002400240024020050e050001020373000b200c410874200e7220094118747221022008410874200a7220074118747221060c720b410e210641aabac60021020c710b411321064197b0c00021020c700b411121064186b0c00021020c6f0b200320043703880b2003200f3a00870b200320123a00860b200320153b01840b200320163a00830b200320173a00820b200320183b01800b200320193a00ff0a200320073a00fe0a200320083b01fc0a2003200a3a00fb0a200320093a00fa0a2003200c3b01f80a2003200e3a00f70a200320053600f30a2003201a3a00f20a2003201b3b01f00a200341c8096a200341f00a6a10f20320032802e8092202450d18200341a0086a41106a200341800a6a290300370300200341a0086a41086a200341f8096a290300370300200341a0086a41186a200341880a6a290300370300200341c0086a200341900a6a280200360200200341a0056a41086a2206200341ac086a290200370300200341a0056a41106a2205200341b4086a290200370300200341a0056a41186a2207200341bc086a2902003703002003200341f0096a2903003703a008200320032902a4083703a005024020032802ec09450d00200210230b200341e0066a41086a2006290300370300200341e0066a41106a2005290300370300200341e0066a41186a2007290300370300200320032903a0053703e00620034180076a200341c0056a41a00110dc041a200341a0056a200341e0066a10d002200341c8096a20032802a005220620032802a80510d10220032d00c8092102200341f00a6a200341c8096a41017241a00110dc041a0240024020024101460d00200341003a00a0080c010b200341013a00a008200341a0086a410172200341f00a6a41a00110dc041a0b024020032802a405450d00200610230b20034180076a41206a2115200341c0076a2116200341e0076a211720034180086a2118200341c1086a2119200341e1086a211a20034181096a211b200341a1096a211c200341a0086a410172211d200341c8096a4101722105416c2108034041002106024002400240024020084188d1c4006a280000220241e0ea91cb064a220f0d00200241f0c2c98b06460d0141012107200241e2c289ab06470d0341202106201521070c030b200241e1ea91cb06460d010240200241e9dabdf306460d0041012107200241e7e485f306470d034120210620034180076a21070c030b41202106201621070c020b41202106201721070c010b41202106201821070b200320063602f80a200320073602f40a200320023602f00a200341a0056a200341f00a6a10ff02200341c8096a20032802a005220a20032802a805108a0120034180056a41086a2209200541086a29000037030020034180056a41106a220c200541106a29000037030020034180056a41186a220e200541186a29000037030020032005290000370380050240024020032d00c8094101470d00200341e0046a41186a2212200e290300370300200341e0046a41106a220e200c290300370300200341e0046a41086a220c200929030037030020032003290380053703e004024020032802a405450d00200a10230b200341c8096a41186a2012290300370300200341c8096a41106a200e290300370300200341c8096a41086a200c290300370300200320032903e0043703c809200341c8096a200341e0066a412010de04450d01419b9ac3002102411821060c710b20032802a405450d00200a10230b0240024020032d00a0084101470d004100210a410121090240024002400240200f0d00200241f0c2c98b06460d01200241e2c289ab06470d034120210a201921090c030b200241e1ea91cb06460d010240200241e9dabdf306460d00200241e7e485f306470d034120210a201d21090c030b4120210a201a21090c020b4120210a201b21090c010b4120210a201c21090b02402006200a470d0020072009460d0220072009200610de04450d020b2003200a3602d009200320093602cc09200320023602c809200341f00a6a200341c8096a10ff0220033502f80a42208620032802f00a220aad84100520032802f40a450d00200a10230b200320063602d009200320073602cc09200320023602c809200341f00a6a200341c8096a10ff0220032802f00a2102200320032802f80a3602cc09200320023602c809200341e0066a200341c8096a10f50120032802f40a450d00200210230b200841046a22080d000b200341f00a6a200341e0066a10d00220032802f00a210220033502f80a2104200341003602d009200342013703c80920034180076a200341c8096a1071200341a0076a200341c8096a1071200341c0076a200341c8096a1071200341e0076a200341c8096a107120034180086a200341c8096a107120032802cc09210620044220862002ad8420033502d00942208620032802c8092205ad84100202402006450d00200510230b024020032802f40a450d00200210230b2013450d6f201410230c6f0b024020022d00000d0020022d000141ff01714102470d0020012802042106200341e0046a41186a4200370300200341e0046a41106a22054200370300200341e0046a41086a22074200370300200342003703e00441be99c600ad4280808080900184100322022f0000210820022d0002210a2002280003210920022d0007210c2002290008210420021023200720043703002003200c3a00e704200320093600e3042003200a3a00e204200320083b01e00441c799c600ad4280808080e00084100322022d000221082002280003210a20022d000721092002290008210420022f0000210c200210232005200c3b010020034180076a41186a200437030020034180076a41086a2007290300370300200320093a00f7042003200a3600f304200320083a00f20420034180076a41106a2005290300370300200320032903e00437038007200341f8016a20034180076a412041014100410010b80120032802f8014101460d19200341a0056a41186a4200370300200341a0056a41106a22054200370300200341a0056a41086a22074200370300200342003703a00541c4fbc400ad4280808080e00084100322022f0000210820022d0002210a2002280003210920022d0007210c2002290008210420021023200720043703002003200c3a00a705200320093600a3052003200a3a00a205200320083b01a00541f9bcc000ad4280808080e00084100322022d000221082002280003210a20022d000721092002290008210420022f0000210c200210232005200c3b010020034180056a41186a200437030020034180056a41086a2007290300370300200320093a00b7052003200a3600b305200320083a00b20520034180056a41106a2005290300370300200320032903a00537038005200341f0016a20034180056a4120108f0120032802f401410020032802f0011b2006490d1a200341e0046a41186a4200370300200341e0046a41106a22054200370300200341e0046a41086a22074200370300200342003703e00441be99c600ad4280808080900184100322022f0000210820022d0002210a2002280003210920022d0007210c2002290008210420021023200720043703002003200c3a00e704200320093600e3042003200a3a00e204200320083b01e00441c799c600ad4280808080e00084100322022d000221082002280003210a20022d000721092002290008210420022f0000210c200210232005200c3b010020034180076a41186a200437030020034180076a41086a2007290300370300200320093a00f7042003200a3600f304200320083a00f20420034180076a41106a2005290300370300200320032903e00437038007200320063602a00c20034180076aad4280808080800484200341a00c6aad4280808080c000841002200041023a00080c85010b20004181123b01082000410f360204200041aab0c0003602002000410a6a41003a00000c84010b200141086a28020021062001280204210502400240024020022d00000d0020022d000141ff01714101460d010b02402006450d00200510230b20004181143b01082000411336020420004197b0c0003602004100210a2000410a6a41003a00000c010b02402006450d00200510230b200041023a00084100210a0b410121064101210841012105410121070c90010b2001411c6a280200210e200141186a2802002112200141146a280200210f2001410c6a2802002113200141086a280200211441aab0c0002107410f210520022d00000d6920022d000141ff01714102470d69200141246a2802002115200141106a280200210c20034180056a41186a2209420037030020034180056a41106a2206420037030020034180056a41086a22054200370300200342003703800541f7fbc400ad4280808080f00084100322022f0000210720022d000221082002280003210a20022d00072116200229000821042002102320052004370300200320163a0087052003200a36008305200320083a008205200320073b0180054194b7c200ad4280808080c00184100322022d000221072002280003210820022d0007210a2002290008210420022f0000211620021023200620163b0100200341e0046a41186a2004370300200341e0046a41086a20052903003703002003200a3a0097052003200836009305200320073a009205200341e0046a41106a200629030037030020032003290380053703e00420034188026a200341e0046a4120108f01200328028c02210720032802880221084194fcc400ad4280808080800184100322022d000f211620022d000e211720022f000c211820022d000b211920022d000a211a20022f0008211b20022d0007211c2002280003211d20022d0002211e20022f0000211f2002102341d8e9c000ad4280808080a002841003220231000f2104200231000e210b200233000c210d200231000b2110200231000a21112002330008212420022d000721202002280003212120022d0002212220022f000021232002102320032007410020081b22293602a00c200341a0056a41186a2207200341a00c6aad22264280808080c0008422251001220241186a290000370300200341a0056a41106a2208200241106a290000370300200341a0056a41086a220a200241086a290000370300200320022900003703a0052002102320092007290300370300200620082903003703002005200a290300370300200320032903a0053703800541c00010212202450d182002201c3a00072002201d3600032002201e3a00022002201f3b0000200220163a000f200220173a000e200220183b000c200220193a000b2002201a3a000a2002201b3b0008200220203a001720022021360013200220223a0012200220233b001020022011421086202484201042188684200d42208684200b423086842004423886843700182002200329038005370020200241286a2005290300370000200241306a2006290300370000200241386a2009290300370000200320153602a00c200720251001220641186a2900003703002008200641106a290000370300200a200641086a290000370300200320062900003703a0052006102320034180076a41186a200729030037030020034180076a41106a200829030037030020034180076a41086a200a290300370300200320032903a00537038007200241c00041800110252202450d19200220032903800737004041182105200241d8006a20034180076a41186a290300370000200241d0006a20034180076a41106a290300370000200241c8006a20034180076a41086a29030037000020034180026a200241e00041014100410010b80120032802800221082002102320034180056a41186a420037030020034180056a41106a2206420037030020034180056a41086a2207420037030020034200370380054194fcc400ad4280808080800184100322022f0000210a20022d000221092002280003211620022d00072117200229000821042002102320072004370300200320173a0087052003201636008305200320093a0082052003200a3b018005419ddfc000ad4280808080c00084100322022d0002210a2002280003210920022d000721162002290008210420022f0000211720021023200620173b0100200341e0046a41186a2004370300200341e0046a41086a2007290300370300200320163a00970520032009360093052003200a3a009205200341e0046a41106a200629030037030020032003290380053703e004200341a00c6a200341e0046a10bc0120032802a00c2202410120021b211620032902a40c420020021b210402400240024020084101470d0041f4ecc0002107411521050c010b201620154105746a410020152004422088a7491b22020d014189edc00021070b2004a7450d6a201610230c6a0b20022f0000210620022d000221052002280003210720022d000721082002290008210b20022f0010210a20022d001221092002280013211720022d00172118200341bd0c6a2002290018370000200341bc0c6a20183a0000200341b80c6a2017360200200341b70c6a20093a0000200341b50c6a200a3b0000200341ad0c6a200b370000200341ac0c6a20083a0000200341a80c6a2007360200200320053a00a70c200320063b00a50c200341003a00a40c200341073a00a00c200341a00c6a108e01200341003602a80c200342013703a00c200c200341a00c6a105c0240024020032802a40c220620032802a80c22026b200c490d0020032802a00c21060c010b2002200c6a22052002490d71200641017422072005200720054b1b22054100480d710240024020060d002005102121060c010b20032802a00c20062005102521060b2006450d1b200320053602a40c200320063602a00c0b20032002200c6a3602a80c200620026a2014200c10dc041a200e200341a00c6a105c200e450d1b200f200e410c6c6a210c200f210603402006280200210a200641086a2802002202200341a00c6a105c0240024020032802a40c220820032802a80c22056b2002490d0020032802a00c21070c010b200520026a22072005490d72200841017422092007200920074b1b22094100480d720240024020080d002009102121070c010b20032802a00c20082009102521070b2007450d1e200320093602a40c200320073602a00c200921080b2003200520026a22093602a80c200720056a200a200210dc041a2006410c6a2206200c470d000c690b0b10f303000b200341a00c6a41286a200141306a290300370300200341a00c6a41206a200141286a290300370300200341a00c6a41186a200141206a290300370300200341a00c6a41106a200141186a290300370300200341a00c6a41086a200141106a2903003703002003200141086a2903003703a00c200341c8096a41206a200241206a290200370300200341c8096a41186a200241186a290200370300200341c8096a41106a200241106a290200370300200341c8096a41086a200241086a290200370300200320022902003703c80920034190026a200341a00c6a200341c8096a10f001024020032802900222020d00200041023a00084100210c0c660b2003280294022106200041811a3b0108200020023602004100210c2000410a6a41003a0000200020063602040c650b200341c8096a41206a200141246a290200370300200341c8096a41186a2001411c6a290200370300200341c8096a41106a200141146a290200370300200341c8096a41086a2001410c6a290200370300200320012902043703c809200341a00c6a41206a200241206a290200370300200341a00c6a41186a200241186a290200370300200341a00c6a41106a200241106a290200370300200341a00c6a41086a200241086a290200370300200320022902003703a00c20034198026a200341c8096a200341a00c6a10d603024020032802980222020d00200041023a00084100210e0c640b200328029c022106200041811c3b0108200020023602004100210e2000410a6a41003a0000200020063602040c630b200341c8096a41206a200141246a290200370300200341c8096a41186a2001411c6a290200370300200341c8096a41106a200141146a290200370300200341c8096a41086a2001410c6a290200370300200320012902043703c809200341a00c6a41206a200241206a290200370300200341a00c6a41186a200241186a290200370300200341a00c6a41106a200241106a290200370300200341a00c6a41086a200241086a290200370300200320022902003703a00c200341a0026a200341c8096a200341a00c6a10d503024020032802a00222020d00200041023a00084100210f0c620b20032802a4022106200041811e3b0108200020023602004100210f2000410a6a41003a0000200020063602040c610b200341c8096a41206a200141286a290300370300200341c8096a41186a200141206a290300370300200341c8096a41106a200141186a290300370300200341c8096a41086a200141106a2903003703002003200141086a2903003703c809200341a00c6a41206a200241206a290200370300200341a00c6a41186a200241186a290200370300200341a00c6a41106a200241106a290200370300200341a00c6a41086a200241086a290200370300200320022902003703a00c200341a8026a200341c8096a200341a00c6a108203024020032802a80222020d00200041023a0008410021120c600b20032802ac02210620004181203b010820002002360200410021122000410a6a41003a0000200020063602040c5f0b200341a2056a2205200141076a2d00003a0000200341c8096a41086a22072001411c6a290200370300200341c8096a41106a220a200141246a290200370300200341c8096a41186a2001412c6a290200370300200341e8096a200141346a290200370300200341f0096a2001413c6a290200370300200341f8096a200141c4006a2d00003a0000200320012f00053b01a0052003200141146a2902003703c809200141086a28020021082001410c6a2802002109200141106a280200210620022f0001200241036a2d000041107472210c2002410c6a2802002112200241086a2802002113200241046a280200210f20022d00002102024002400240024002400240024020012d0004220e0e050001020304000b200341a00c6a41146a4101360200200342013702a40c200341d09dc6003602a00c200341043602a408200341849ec6003602a0082003200341a0086a3602b00c200341a00c6a41e0dfc4001038000b200341b7086a2007290300370000200341bf086a200a2d00003a0000200320032f01a0053b01a008200320063600ab08200320093600a708200320083600a308200320032903c8093700af08200320052d00003a00a208024002402002417f6a220641034b0d00024020060e0400010102000b200f41ff01710d00201341017420124b0d010b2002200c7241ff01710d040b41f0dfc400ad4280808080b00284100322022f0000210620022d000221052002280003210720022d0007210a20022900082104200210234183e0c400ad4280808080f00084100322022f0000210c20022d0002210f2002280003211220022d000721132002290008210b200210232003200b3701b80c200320133a00b70c200320123600b30c2003200f3a00b20c2003200c3b01b00c200320043701a80c2003200a3a00a70c200320073600a30c200320053a00a20c200320063b01a00c200341f00a6a200341a00c6a412010bb01024020032802f00a220a0d004100210f200341003602e0064101210a2003410136028007410021120c5c0b2003200a360280072003200341f80a6a2802003602e00620032802f40a210f20032902f40a2204a7211241002102024002402004422088a7220c41014b0d00200c0e025d015d0b200c210603402006410176220520026a22072002200a20074105746a200341a0086a412010de044101481b2102200620056b220641014b0d000b0b0240200a20024105746a200341a0086a412010de0422060d00418ae0c400210c2012450d5e200a10234110210f0c5f0b200341a00c6a41186a200341a0086a41186a290300370300200341a00c6a41106a200341a0086a41106a290300370300200341a00c6a41086a200341a0086a41086a290300370300200320032903a0083703a00c02402006411f7620026a2205200c4b0d00200341a00c6a21060c5d0b4180bbc000102b000b200341b7086a2007290300370000200341bf086a200a2d00003a0000200320032f01a0053b01a008200320063600ab08200320093600a708200320083600a308200320032903c8093700af08200320052d00003a00a208024002402002417f6a220641034b0d00024020060e0400010102000b200f41ff01710d00201341017420124b0d010b2002200c7241ff01710d030b41f0dfc400ad4280808080b00284100322022f0000210620022d000221052002280003210720022d0007210a20022900082104200210234183e0c400ad4280808080f00084100322022f0000210c20022d0002210f2002280003211220022d000721132002290008210b200210232003200b3701b80c200320133a00b70c200320123600b30c2003200f3a00b20c2003200c3b01b00c200320043701a80c2003200a3a00a70c200320073600a30c200320053a00a20c200320063b01a00c200341f00a6a200341a00c6a412010bb0120032802f00a2206410120061b210a41002102024002400240024020032902f40a420020061b2204422088a7220c41014b0d00200c0e020201020b200c210603402006410176220520026a22072002200a20074105746a200341a0086a412010de044101481b2102200620056b220641014b0d000b0b200a20024105746a200341a0086a412010de04450d010b419ae0c400210c410c210f2004a7450d5e200a10230c5e0b2002200c4f0d1b200a20024105746a2206200641206a2002417f73200c6a41057410dd041a200341c0056a41186a4200370300200341c0056a41106a22064200370300200341c0056a41086a22054200370300200342003703c00541f0dfc400ad4280808080b00284100322022f0000210720022d0002210f2002280003211220022d000721132002290008210b200210232005200b370300200320133a00c705200320123600c3052003200f3a00c205200320073b01c0054183e0c400ad4280808080f00084100322022d000221072002280003210f20022d000721122002290008210b20022f0000211320021023200620133b0100200341a00c6a41186a200b370300200341a00c6a41086a2005290300370300200320123a00d7052003200f3600d305200320073a00d205200341a00c6a41106a2006290300370300200320032903c0053703a00c200341003602f80a200342013703f00a200c417f6a2205200341f00a6a105c02402005450d00200c41057441606a2106200a210203402002200341f00a6a1071200241206a2102200641606a22060d000b0b20032802f40a2102200341a00c6aad428080808080048420033502f80a42208620032802f00a2206ad84100202402002450d00200610230b200341a00c6a41186a200341a0086a41186a290300370300200341a00c6a41106a200341a0086a41106a290300370300200341a00c6a41086a200341a0086a41086a290300370300200320032903a0083703a00c200341a00c6a4101200a200510cd032003418c023b01a00c200341a00c6a108e014100210c2004a7450d59200a10230c590b200341870b6a20072903003700002003418f0b6a200a2d00003a0000200320032f01a0053b01f00a200320063600fb0a200320093600f70a200320083600f30a200320032903c8093700ff0a200320052d00003a00f20a200341a0086a41186a200341f1096a290000370300200341a0086a41106a200341e9096a290000370300200341a0086a41086a200341e1096a290000370300200320032900d9093703a008024002402002417f6a220641034b0d00024020060e0400010102000b200f41ff01710d00201341017420124b0d010b2002200c7241ff0171450d0041b696c600210c410a210f0c5d0b0240200341f00a6a200341a0086a412010de040d004100210c0c5d0b41f0dfc400ad4280808080b00284100322022f0000210620022d000221052002280003210720022d0007210a20022900082104200210234183e0c400ad4280808080f00084100322022f0000210c20022d0002210f2002280003211220022d000721132002290008210b200210232003200b3701b80c200320133a00b70c200320123600b30c2003200f3a00b20c2003200c3b01b00c200320043701a80c2003200a3a00a70c200320073600a30c200320053a00a20c200320063b01a00c20034180076a200341a00c6a412010bb012003280280072206410120061b210a419ae0c400210c410c210f4100210202400240200329028407420020061b2204422088a7221241014b0d0020120e025901590b2012210603402006410176220520026a22072002200a20074105746a200341f00a6a412010de044101481b2102200620056b220641014b0d000b0b200a20024105746a2206200341f00a6a412010de040d5720034180076a41186a2205200341a0086a41186a29030037030020034180076a41106a2207200341a0086a41106a29030037030020034180076a41086a220c200341a0086a41086a290300370300200320032903a00837038007200220124f0d1b2006200329038007370000200641186a2005290300370000200641106a2007290300370000200641086a200c29030037000041002102024020124101460d00410021022012210603402006410176220520026a22072002200a20074105746a200341a0086a412010de044101481b2102200620056b220641014b0d000b0b0240200a20024105746a200341a0086a412010de040d00418ae0c400210c4110210f0c580b200a201210fa01200341c0056a41186a4200370300200341c0056a41106a22064200370300200341c0056a41086a22054200370300200342003703c00541f0dfc400ad4280808080b00284100322022f0000210720022d0002210c2002280003210f20022d000721132002290008210b200210232005200b370300200320133a00c7052003200f3600c3052003200c3a00c205200320073b01c0054183e0c400ad4280808080f00084100322022d000221072002280003210c20022d0007210f2002290008210b20022f0000211320021023200620133b0100200341a00c6a41186a200b370300200341a00c6a41086a20052903003703002003200f3a00d7052003200c3600d305200320073a00d205200341a00c6a41106a2006290300370300200320032903c0053703a00c20034100360288072003420137038007201220034180076a105c02402012450d0020124105742106200a21020340200220034180076a1071200241206a2102200641606a22060d000b0b2003280284072102200341a00c6aad42808080808004842003350288074220862003280280072206ad84100202402002450d00200610230b200341a00c6a41186a200341f00a6a41186a290300370300200341a00c6a41106a200341f00a6a41106a290300370300200341a00c6a41086a200341f00a6a41086a290300370300200320032903f00a3703a00c200341a00c6a4101200a201210cd032003418c043b01a00c200341a00c6a108e014100210c2004a7450d58200a10230c5c0b02402002417f6a220541034b0d00024020050e0400010103000b200f41ff01710d00201341017420124b0d020b2002200c7241ff0171450d012009450d00200810230b41b696c600210c410a210f0c5d0b2008200610fa0141f0dfc400ad4280808080b002842204100322022f0000210520022d000221072002280003210a20022d0007210c2002290008210b200210234183e0c400ad4280808080f00084220d100322022f0000210e20022d0002210f2002280003211220022d000721132002290008211020021023200320103701b80c200320133a00b70c200320123600b30c2003200f3a00b20c2003200e3b01b00c2003200b3701a80c2003200c3a00a70c2003200a3600a30c200320073a00a20c200320053b01a00c200341a0086a200341a00c6a412010bb012008200620032802a0082202410120021b220520032902a408420020021b220b422088a710cc030240200ba7450d00200510230b200341c0056a41186a4200370300200341c0056a41106a22054200370300200341c0056a41086a22074200370300200342003703c0052004100322022f0000210a20022d0002210c2002280003210e20022d0007210f2002290008210420021023200720043703002003200f3a00c7052003200e3600c3052003200c3a00c2052003200a3b01c005200d100322022d0002210a2002280003210c20022d0007210e2002290008210420022f0000210f200210232005200f3b0100200341a00c6a41186a2004370300200341a00c6a41086a20072903003703002003200e3a00d7052003200c3600d3052003200a3a00d205200341a00c6a41106a2005290300370300200320032903c0053703a00c200341003602a808200342013703a0082006200341a0086a105c02402006450d00200641057421062008210203402002200341a0086a1071200241206a2102200641606a22060d000b0b20032802a4082102200341a00c6aad428080808080048420033502a80842208620032802a0082206ad84100202402002450d00200610230b02402009450d00200810230b2003418c063b01a00c200341a00c6a108e010c5a0b20034180076a41086a22082001411c6a29020037030020034180076a41106a220c200141246a29020037030020034180076a41186a220e2001412c6a2802003602002003200141146a290200370380072002410c6a2802002107200241086a28020021052001410c6a2802002109200241046a280200210a20022d000021060240024002400240024002400240200141086a2802000e0400010203000b200341a00c6a41146a4101360200200342013702a40c200341d09dc6003602a00c200341043602cc09200341849ec6003602c8092003200341c8096a3602b00c200341a00c6a41f8c0c3001038000b20074110762112200741087621132005411076211420054108762115200141386a290300210b200141306a29030021042002411a6a290100210d200241196a2d00002117200241186a2d00002118200241166a2f01002119200241156a2d0000211a200241146a2d0000211b200241126a2f0100211c200241116a2d0000211d200241106a2d00002116200241026a2f0100211e200141106a280200210f20022d00012102200341a0086a41186a200e280200360200200341a0086a41106a200c290300370300200341a0086a41086a200829030037030020032003290380073703a0084102200a4108762005411874724102200241014622021b20061b21050240024020060d0020020d010b410f210841aab0c0002102024002400240024020050e050001020357000b201541ff01712014410874722007411874722102201341ff017120124108747220164118747221080c560b410e210841aabac60021020c550b411321084197b0c00021020c540b411121084186b0c00021020c530b2003200d3703e009200320173a00df09200320183a00de09200320193b01dc092003201a3a00db092003201b3a00da092003201c3b01d8092003201d3a00d709200320163a00d609200320123b01d409200320133a00d309200320073a00d209200320143b01d009200320153a00cf09200320053600cb092003200a3a00ca092003201e3b01c8090240200941ff01714101460d0020094108762107200341b0086a290300211120032903a808212420032802b808210820032903a00821250c520b200341a00c6a200f41067610bc0220032802a00c21060240024020032802a80c200f413f7122024b0d00410021020c010b200620024105746a22022f0000200241026a2d0000411074722107200229000f212420022d001f2108200229000721252002280003210f200241176a2900002111410121020b024020032802a40c450d00200610230b20020d5141aabac6002102410e21080c520b419cbac6002102410e21082006417f6a220641034b0d520240024020060e0400545401000b200541017420074d0d53200a41ff01710d530b41f4fcc400ad42808080808001841003220231000f2104200231000e210b200233000c210d200231000b2110200231000a21112002330008212420022d000721062002280003210520022d0002210720022f000021082002102341f980c400ad4280808080900184100322022d000f210a20022d000e210c20022f000c210e20022d000b210f20022d000a211220022f0008211320022d000721142002280003211520022d0002211620022f0000211720021023200320093602a00c200341a0056a41186a2209200341a00c6aad4280808080c000841001220241186a290000370300200341a0056a41106a2218200241106a290000370300200341a0056a41086a2219200241086a290000370300200320022900003703a0052002102320034180056a41186a221a200929030037030020034180056a41106a2209201829030037030020034180056a41086a22182019290300370300200320032903a0053703800541c00010212202450d1c200220063a000720022005360003200220073a0002200220083b000020022011421086202484201042188684200d42208684200b42308684200442388684370008200220143a001720022015360013200220163a0012200220173b00102002200a3a001f2002200c3a001e2002200e3b001c2002200f3a001b200220123a001a200220133b00182002200329038005370020200241286a2018290300370000200241306a2009290300370000200241386a201a290300370000200341a00c6a200241c000108f03024020032903a00c22044201520d002002ad428080808080088410050b20032802a80c2106200341a0086a200341ac0c6a41dc0010dc041a200341a00c6a200341a0086a41dc0010dc041a20044201510d03200210230c010b419cbac6002102410e21082006417f6a220641034b0d510240024020060e0400535301000b200a41ff01710d52200541056c200741036c490d520b41f4fcc400ad42808080808001841003220231000f2104200231000e210b200233000c210d200231000b2110200231000a21112002330008212420022d000721062002280003210520022d0002210720022f000021082002102341f980c400ad4280808080900184100322022d000f210a20022d000e210c20022f000c210e20022d000b210f20022d000a211220022f0008211320022d000721142002280003211520022d0002211620022f0000211720021023200320093602a00c200341a0056a41186a2218200341a00c6aad4280808080c000841001220241186a290000370300200341a0056a41106a2219200241106a290000370300200341a0056a41086a221a200241086a290000370300200320022900003703a0052002102320034180056a41186a221b201829030037030020034180056a41106a2218201929030037030020034180056a41086a2219201a290300370300200320032903a0053703800541c00010212202450d1c200220063a000720022005360003200220073a0002200220083b000020022011421086202484201042188684200d42208684200b42308684200442388684370008200220143a001720022015360013200220163a0012200220173b00102002200a3a001f2002200c3a001e2002200e3b001c2002200f3a001b200220123a001a200220133b00182002200329038005370020200241286a2019290300370000200241306a2018290300370000200241386a201b29030037000020034180036a200241c00041014100410010b80120032802800321062002102320064101460d010b41a2c1c3002102411921080c500b20034180056a41186a2207420037030020034180056a41106a2202420037030020034180056a41086a22064200370300200342003703800541f4fcc400ad4280808080800184220d100322052f0000210820052d0002210a2005280003210c20052d0007210e2005290008210420051023200620043703002003200e3a0087052003200c360083052003200a3a008205200320083b0180054180b4c300ad42808080809001842210100322052d000221082005280003210a20052d0007210c2005290008210420052f0000210e200510232002200e3b0100200341e0046a41186a220f2004370300200341e0046a41086a221220062903003703002003200c3a0097052003200a36009305200320083a009205200341e0046a41106a2208200229030037030020032003290380053703e004200341a00c6a200341e0046a10950220032802a00c2205410420051b210e024020032902a40c420020051b2204422088220ba722052004a7470d00200541016a220a2005490d6b200ba72213410174220c200a200a200c491b220a41ffffffff0371200a470d6b200a410274220c4100480d6b0240024020050d00200c1021210e0c010b200e2013410274200c1025210e0b200e450d1c2004422088220ba72105200aad21040b200e20054102746a20093602002007420037030020024200370300200642003703002003420037038005200d100322052f0000210720052d0002210a2005280003210920052d0007210c2005290008210d200510232006200d3703002003200c3a00870520032009360083052003200a3a008205200320073b0180052010100322052d000221072005280003210a20052d000721092005290008210d20052f0000210c200510232002200c3b0100200f200d37030020122006290300370300200320093a0097052003200a36009305200320073a0092052008200229030037030020032003290380053703e0040240200e0d00200341e0046aad428080808080048410050c510b200341003602a80c200342013703a00c200ba741016a2206200341a00c6a105c0240024020060d0020032802a80c210a20032802a40c210820032802a00c21060c010b410020032802a80c22026b2105200e20064102746a210c20032802a40c2108200e210703402007280200210902400240200820056a4104490d0020032802a00c21060c010b200241046a22062002490d6d2008410174220a2006200a20064b1b220a4100480d6d0240024020080d00200a102121060c010b20032802a00c2008200a102521060b2006450d1f2003200a3602a40c200320063602a00c200a21080b2003200241046a220a3602a80c200620026a20093600002005417c6a2105200a2102200c200741046a2207470d000b0b2004a72102200341e0046aad4280808080800484200aad4220862006ad84100202402008450d00200610230b2002450d50200e10230c500b200341f00a6a200341a00c6a41dc0010dc041a20021023200320063602c809200341c8096a410472200341f00a6a41dc0010dc041a200341f0026a200341e8096a20032903d809200341e0096a29030010c80220032903f002200341f8026a29030010c9020c4f0b200341c0056a41086a2205200141116a290000370300410f2106200341c0056a410f6a220a200141186a290000370000200341a0086a41086a2209200141386a290300370300200341a0086a41106a220c200141c0006a290300370300200341a0086a41186a220e200141c8006a290300370300200341a0086a41206a220f200141d0006a290300370300200341a0086a41286a2212200141d8006a290300370300200341a0086a41306a2213200141e0006a290300370300200341a0086a41386a2214200141e8006a290300370300200320012900093703c0052003200141306a2903003703a008200141286a2903002104200141206a290300210b20022d0001210820022d00002107024002400240200141086a2d00000e03000102000b200341b40c6a4101360200200342013702a40c200341d09dc6003602a00c200341043602cc09200341849ec6003602c8092003200341c8096a3602b00c200341a00c6a41ace6c3001038000b200341f00a6a411f6a20043c0000200341f00a6a410f6a200a290000370000200341f00a6a41086a20052903003703002003200b3700870b200320032903c0053703f00a200341c8096a410f6a2009290300370000200341df096a200c290300370000200341c8096a411f6a200e290300370000200341ef096a200f290300370000200341f7096a2012290300370000200341ff096a2013290300370000200341870a6a20142f01003b0000200320044238883c00ce09200320044228883d01cc09200320044208883e02c809200320032903a0083700cf0941aab0c0002102200741ff01710d4b200841ff01714102470d4b200341900c6a200341f00a6a10b403200341a00c6a200341c8096a20032802900c220520032802980c10b503024020032d00a00c4101460d00411a210641bce6c30021020c4b0b20034180076a41086a2202200341b40c6a2d00003a0000200341f3066a20022802003a0000200320032d00a30c3a00e206200320032f00a10c3b01e006200320032902a40c3700e3062003200341ac0c6a2902003700eb0641fcfcc400ad4280808080e000842204100322022d000f210620022d000e210720022f000c210820022d000b210a20022d000a210920022f0008210c20022d0007210e2002280003210f20022d0002211220022f00002113200210232004100322022d000f211420022d000e211520022f000c211620022d000b211720022d000a211820022f0008211920022d0007211a2002280003211b20022d0002211c20022f0000211d20021023200341e0046a200341e0066a10b60341c00010212202450d1c2002200e3a00072002200f360003200220123a0002200220133b0000200220063a000f200220073a000e200220083b000c2002200a3a000b200220093a000a2002200c3b00082002201a3a00172002201b3600132002201c3a00122002201d3b0010200220143a001f200220153a001e200220163b001c200220173a001b200220183a001a200220193b0018200241386a200341f8046a290300370000200241306a200341e0046a41106a290300370000200241286a200341e0046a41086a290300370000200220032903e004370020200341c8036a200241c000108902200341c8036a41106a290300210420032903d003210b024020032903c803220d4201520d002002ad428080808080088410050b200210230240200da70d0041d6e6c3002102411d21060c4b0b200341e0046a41186a22074200370300200341e0046a41106a22024200370300200341e0046a41086a22064200370300200342003703e00441fcfcc400ad4280808080e000842211100322052f0000210820052d0002210a2005280003210920052d0007210c2005290008210d200510232006200d3703002003200c3a00e704200320093600e3042003200a3a00e204200320083b01e0044194e6c300ad4280808080d000842224100322052d000221082005280003210a20052d000721092005290008210d20052f0000210c200510232002200c3b010020034180076a41186a220c200d37030020034180076a41086a220e2006290300370300200320093a00f7042003200a3600f304200320083a00f20420034180076a41106a22082002290300370300200320032903e00437038007200341b0036a20034180076a412010890220032903b803420020032802b00322051b220d200b5a200341b0036a41106a290300420020051b221020045a20102004511b450d1d200742003703002002420037030020064200370300200342003703e0042011100322052f0000210720052d0002210a2005280003210920052d0007210f2005290008211120051023200620113703002003200f3a00e704200320093600e3042003200a3a00e204200320073b01e0042024100322052d000221072005280003210a20052d000721092005290008211120052f0000210f200510232002200f3b0100200c2011370300200e2006290300370300200320093a00f7042003200a3600f304200320073a00f20420082002290300370300200320032903e004370380072003201020047d200d200b54ad7d3703a80c2003200d200b7d3703a00c20034180076aad4280808080800484200341a00c6aad428080808080028422111002200341a0036a200341f00a6a200b2004109702200341a0036a41086a290300211020032903a0032124200341a0056a41186a22084200370300200341a0056a41106a22024200370300200341a0056a41086a22064200370300200342003703a00541d5fbc400ad4280808080800184220d100322052f0000210720052d0002210a2005280003210920052d0007210c2005290008212520051023200620253703002003200c3a00a705200320093600a3052003200a3a00a205200320073b01a00541d6a0c200ad4280808080d001842225100322052d000221072005280003210a20052d000721092005290008212620052f0000210c200510232002200c3b010020034180056a41186a220c202637030020034180056a41086a220e2006290300370300200320093a00b7052003200a3600b305200320073a00b20520034180056a41106a220a2002290300370300200320032903a0053703800520034188036a20034180056a412010890220034188036a41106a290300212620032903900321272003280288032107200842003703002002420037030020064200370300200342003703a005200d100322052f0000210820052d000221092005280003210f20052d000721122005290008210d200510232006200d370300200320123a00a7052003200f3600a305200320093a00a205200320083b01a0052025100322052d000221082005280003210920052d0007210f2005290008210d20052f0000211220051023200220123b0100200c200d370300200e20062903003703002003200f3a00b705200320093600b305200320083a00b205200a2002290300370300200320032903a005370380052003427f20102026420020071b220d7c20242027420020071b22107c22242010542202ad7c221020022010200d542010200d511b22021b3703a80c2003427f202420021b3703a00c20034180056aad428080808080048420111002200341a00c6a41106a2004370300200341a00c6a41086a200b370300200341a00c6a41186a20032903f00a370300200341a00c6a41206a200341f00a6a41086a290300370300200341c80c6a200341f00a6a41106a290300370300200341d00c6a200341f00a6a41186a290300370300200341d80c6a20032903e006370300200341e00c6a200341e0066a41086a290300370300200341e80c6a200341e0066a41106a2802003602002003410e3a00a00c200341a00c6a108e01024020032802940c450d0020032802900c10230b410021020c4b0b200341c8096a41106a200341c0056a41106a280200360200200341c8096a41086a2005290300370300200320032903c0053703c8094186b0c00021020240200820077241ff01710d0020034180076a41186a2207420037030020034180076a41106a2206420037030020034180076a41086a22054200370300200342003703800741fcfcc400ad4280808080e00084220d100322022f0000210820022d0002210a2002280003210920022d0007210c2002290008211020021023200520103703002003200c3a00870720032009360083072003200a3a008207200320083b0180074194e6c300ad4280808080d000842210100322022d000221082002280003210a20022d000721092002290008211120022f0000210c200210232006200c3b0100200341e0046a41186a220c2011370300200341e0046a41086a220e2005290300370300200320093a0097072003200a36009307200320083a009207200341e0046a41106a220a200629030037030020032003290380073703e004200341e0036a200341e0046a4120108902200341e0036a41106a290300211120032903e803212420032802e00321082007420037030020064200370300200542003703002003420037038007200d100322022f0000210920022d0002210f2002280003211220022d00072113200229000821252002102320052025370300200320133a00870720032012360083072003200f3a008207200320093b0180072010100322022d000221092002280003210f20022d000721122002290008211020022f0000211320021023200620133b0100200c2010370300200e2005290300370300200320123a0097072003200f36009307200320093a009207200a200629030037030020032003290380073703e00420032024420020081b2210200b7c22243703a00c20032011420020081b20047c2024201054ad7c3703a80c200341e0046aad4280808080800484200341a00c6aad428080808080028422101002200341a00c6a41106a200341c8096a41106a280200360200200341a00c6a41086a200341c8096a41086a290300370300200320032903c8093703a00c200d100322022d000f210820022d000e210a20022f000c210920022d000b210c20022d000a210e20022f0008210f20022d000721122002280003211320022d0002211420022f0000211520021023200d100322022d000f211620022d000e211720022f000c211820022d000b211920022d000a211a20022f0008211b20022d0007211c2002280003211d20022d0002211e20022f0000211f2002102320034180076a200341a00c6a10b60341c00010212202450d1e200220123a000720022013360003200220143a0002200220153b0000200220083a000f2002200a3a000e200220093b000c2002200c3a000b2002200e3a000a2002200f3b00082002201c3a00172002201d3600132002201e3a00122002201f3b0010200220163a001f200220173a001e200220183b001c200220193a001b2002201a3a001a2002201b3b0018200241386a2007290300370000200241306a2006290300370000200241286a20052903003700002002200329038007370020200320043703a80c2003200b3703a00c2002ad42808080808008842010100220021023410021020b411121060c4a0b20022d0001210620022d00002102200341a80c6a2001410c6a280200360200200320012902043703a00c200341f8036a20022006200341a00c6a108502024020032802f80322020d00200041023a0008410021170c480b20032802fc03210620004181283b010820002002360200410021172000410a6a41003a0000200020063602040c470b41aab0c0002106410f2105024020022d00000d0020022d000141ff01714102470d00200341a0056a41186a220c4200370300200341a0056a41106a22054200370300200341a0056a41086a22074200370300200342003703a00541a79fc600ad4280808080c00184220b100322022f0000210620022d000221082002280003210a20022d00072109200229000821042002102320072004370300200320093a00a7052003200a3600a305200320083a00a205200320063b01a00541b39fc600ad4280808080900184220d100322022d000221062002280003210820022d0007210a2002290008210420022f0000210920021023200520093b010020034180056a41186a2209200437030020034180056a41086a220e20072903003703002003200a3a00b705200320083600b305200320063a00b20520034180056a41106a22082005290300370300200320032903a005370380054101210620034180046a20034180056a412041014100410010b8012003280280044101470d1d41bc9fc6002106413421050b200041812a3b010820002005360204200020063602002000410a6a41003a00000c780b200341900c6a41026a22232001410b6a2d00003a0000200341c0056a41086a2218200141206a290300370300200341c0056a41106a2219200141286a290300370300200320012f00093b01900c2003200141186a2903003703c0052001410c6a28020021172002411a6a2901002104200241196a2d0000211a200241186a2d0000211b200241166a2f0100211c200241156a2d0000211d200241146a2d0000211e200241126a2f0100211f41112106200241116a2d00002120200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021122002410c6a2d000021132002410a6a2f01002114200241096a2d00002115200241086a2d00002108200241066a2f0100210a200241056a2d00002109200241046a2d00002121200241026a2f01002122200141146a2802002116200141106a280200210c20022d0001210520022d0000210702400240024002400240024002400240024002400240200141086a2d00000e070001020304090a000b200341a00c6a41146a4101360200200342013702a40c200341d09dc6003602a00c200341043602cc09200341849ec6003602c8092003200341c8096a3602b00c200341a00c6a41dcadc4001038000b4186b0c0002102200520077241ff01710d4c418cfdc400ad4280808080d00084100322022f0000210620022d000221052002280003210720022d00072108200229000821042002102341d8fdc300ad4280808080b00184100322022f0000210a20022d000221092002280003210e20022d0007210f2002290008210b200210232003200b3703880b2003200f3a00870b2003200e3600830b200320093a00820b2003200a3b01800b200320043703f80a200320083a00f70a200320073600f30a200320053a00f20a200320063b01f00a200341a0046a200341f00a6a412041014100410010b801024020032802a0044101470d00411b210641aaafc40021020c4d0b20034180056a41186a220e420037030020034180056a41106a2206420037030020034180056a41086a22054200370300200342003703800541c4fbc400ad4280808080e00084220b100322022f0000210720022d000221082002280003210a20022d00072109200229000821042002102320052004370300200320093a0087052003200a36008305200320083a008205200320073b01800541f9bcc000ad4280808080e00084220d100322022d000221072002280003210820022d0007210a2002290008210420022f0000210920021023200620093b0100200341e0046a41186a22092004370300200341e0046a41086a220f20052903003703002003200a3a0097052003200836009305200320073a009205200341e0046a41106a2207200629030037030020032003290380053703e00420034198046a200341e0046a4120108f010240200328029c0441a08d066e41002003280298041b200c4d0d004114210641c5afc40021020c4d0b418cfdc400ad4280808080d000842204100322022f0000210820022d0002210a2002280003211220022d000721132002290008211020021023419efec300ad4280808080e001842211100322022f0000211420022d000221152002280003211620022d000721182002290008212420021023200320243703880b200320183a00870b200320163600830b200320153a00820b200320143b01800b200320103703f80a200320133a00f70a200320123600f30a2003200a3a00f20a200320083b01f00a20034190046a200341f00a6a4120108f012003280290042108200328029404210a2004100322022f0000211220022d000221132002280003211420022d0007211520022900082110200210232011100322022f0000211620022d000221182002280003211920022d0007211a2002290008211120021023200320113703880b2003201a3a00870b200320193600830b200320183a00820b200320163b01800b200320103703f80a200320153a00f70a200320143600f30a200320133a00f20a200320123b01f00a2003200a41016a410120081b22083602a00c200341f00a6aad42808080808004842210200341a00c6aad4280808080c000841002200e420037030020064200370300200542003703002003420037038005200b100322022f0000210a20022d0002210e2002280003211220022d000721132002290008210b200210232005200b370300200320133a00870520032012360083052003200e3a0082052003200a3b018005200d100322022d0002210a2002280003210e20022d000721122002290008210b20022f0000211320021023200620133b01002009200b370300200f2005290300370300200320123a0097052003200e360093052003200a3a0092052007200629030037030020032003290380053703e00420034188046a200341e0046a4120108f01200328028c04210620032802880421052004100322022f0000210720022d0002210a2002280003210920022d0007210e200229000821042002102341d8fdc300ad4280808080b00184100322022f0000210f20022d000221122002280003211320022d000721142002290008210b200210232003200b3703880b200320143a00870b200320133600830b200320123a00820b2003200f3b01800b200320043703f80a2003200e3a00f70a200320093600f30a2003200a3a00f20a200320073b01f00a410810212202450d2520022006410020051b20176a22063600042002200c36000020102002ad4280808080800184100220021023200341b40c6a2006360200200341b00c6a200c360200200341ac0c6a2008360200200341a80c6a41013a00002003410f3a00a00c200341a00c6a108e010c4a0b4102200a4108742008411874722009724102200541ff017141014622061b200741ff017122021b21050240024020020d0020060d010b410f210641aab0c0002102024020050e05000405064a000b20144108742015722013411874722102200f410874201272200e4118747221060c490b2019290300210b20032903c805210d20032802c0052102200320153a00f70a200320053600f30a200320213a00f20a200320223b01f00a200320203a00ff0a2003200e3a00fe0a2003200f3b01fc0a200320123a00fb0a200320133a00fa0a200320143b01f80a2003201a3a00870b2003201e3a00820b2003201f3b01800b200320043703880b2003201b411874201c41087472201d723600830b200341a00c6a41086a20032903f00a370300200341b00c6a20032903f80a370300200341a00c6a41186a20032903800b370300200341c00c6a2004370300200320173602a40c200341003602a00c200341a8046a200341a00c6a200c20162002200d200b10db0320032802a8042202450d4920032802ac0421060c4b0b4102200a4108742008411874722009724102200541ff017141014622061b200741ff017122021b21050240024020020d0020060d010b410f210641aab0c0002102024020050e050003040549000b20144108742015722013411874722102200f410874201272200e4118747221060c480b2018290300210b20032903c005210d200320043703e0092003201a3a00df092003201e3a00da092003201f3b01d809200320203a00d7092003200e3a00d6092003200f3b01d409200320123a00d309200320133a00d209200320143b01d009200320153a00cf09200320053600cb09200320213a00ca09200320223b01c8092003201b411874201c41087472201d723600db09200341a00c6a200341c8096a10bb03024020032802a00c4101460d0041ecadc4002102411a21060c480b200320032802a40c3602a40c200341013602a00c200341b0046a200341a00c6a2017200c2016200d200b10db0320032802b0042202450d4820032802b40421060c470b200341a0086a410c6a2018290300370200200341a0086a41146a2019290300370200200320163602a008200320032903c0053702a4084102200a4108742009722008411874724102200541ff017141014622061b200741ff017122021b2105024020020d0020060d040b410f210641aab0c0002102024020050e050001020347000b20144108742015722013411874722102200f410874201272200e4118747221060c460b410e210641aabac60021020c450b411321064197b0c00021020c440b411121064186b0c00021020c430b200320043703e0092003201a3a00df092003201b3a00de092003201c3b01dc092003201d3a00db092003201e3a00da092003201f3b01d809200320203a00d7092003200e3a00d6092003200f3b01d409200320123a00d309200320133a00d209200320143b01d009200320153a00cf09200320053600cb09200320213a00ca09200320223b01c8090240201741ff01714101460d0020174108762102200341b0086a290300210420032903a808210b20032802b808210620032903a008210d0c3f0b200341a00c6a200c41067610bc0220032802a00c21070240024020032802a80c200c413f7122024b0d00410021050c010b200720024105746a22052f0000200541026a2d0000411074722102200529000f210b20052d001f21062005290007210d2005280003210c200541176a2900002104410121050b024020032802a40c450d00200710230b20050d3e410121050c3f0b2001413c6a280200212a200141386a2802002129200141346a280200212b200141306a280200212c20032802d405212d20034180056a41026a20232d00003a000020034180076a41086a201829030037030020034180076a41106a20192d00003a0000200320032f01900c3b018005200320032903c00537038007200320043703880b2003201a3a00870b2003201b3a00860b2003201c3b01840b2003201d3a00830b2003201e3a00820b2003201f3b01800b200320203a00ff0a2003200e3a00fe0a2003200f3b01fc0a200320123a00fb0a200320133a00fa0a200320143b01f80a200320153a00f70a20034102200a4108742009722008411874724102200541ff017141014622061b200741ff017122021b22053600f30a200320213a00f20a200320223b01f00a0240024020020d0020060d010b410f210641aab0c0002102024002400240024020050e050001020341000b20032800f70a210220032800fb0a21060c400b410e210641aabac60021020c3f0b411321064197b0c00021020c3e0b411121064186b0c00021020c3d0b200341a0086a41186a200341f00a6a41186a290300370300200341a0086a41106a200341f00a6a41106a290300370300200341a0086a41086a200341f00a6a41086a290300370300200320032903f00a3703a008418cfdc400ad4280808080d00084100322022d000f210520022d000e210720022f000c210820022d000b210a20022d000a210920022f0008210e20022d0007210f2002280003211220022d0002211320022f000021142002102341c7f3c300ad4280808080a00184100322022d000f211520022d000e211820022f000c211920022d000b211a20022d000a211b20022f0008211c20022d0007211d2002280003211e20022d0002211f20022f00002120200210232003202c3602c809200341a0056a41186a2221200341c8096aad4280808080c000841001220241186a290000370300200341a0056a41106a2222200241106a290000370300200341a0056a41086a2206200241086a290000370300200320022900003703a005200210232021290300210420222f0100212120062f0100212220032d00b705212320032800b305212e20032d00b205212f20032d00af05213020032d00ae05213120032f01ac05213220032d00ab05213320032d00aa05213420032d00a705213520032800a305213620032d00a205213720032f01a005213841c00010212202450d1e20022004370038200220233a00372002202e3600332002202f3a0032200220213b0030200220303a002f200220313a002e200220323b002c200220333a002b200220343a002a200220223b0028200220353a002720022036360023200220373a0022200220383b0020200220153a001f200220183a001e200220193b001c2002201a3a001b2002201b3a001a2002201c3b00182002201d3a00172002201e3600132002201f3a0012200220203b0010200220053a000f200220073a000e200220083b000c2002200a3a000b200220093a000a2002200e3b00082002200f3a000720022012360003200220133a0002200220143b0000200341a00c6a200241c00010aa032006200341a00c6a41246a2802003602002003200341bc0c6a2902003703a005024020032d00a40c22064103470d0020021023419caec4002102411e21060c3d0b20032d00a70c210f20032f00a50c2112200341a00c6a412c6a2802002107200341a00c6a41286a2802002109200341a00c6a41186a280200210a200341a00c6a41146a280200210e200341a00c6a41106a2802002113200341a00c6a410c6a2802002108200341a00c6a41086a280200210520032802a00c2118200341f00a6a41086a2214200341a0056a41086a280200360200200320032903a0053703f00a200341d00c6a280200211520021023200341e0066a41086a20142802002202360200200320032903f00a22043703e006200341c8096a41146a200a360200200341d8096a200e360200200341c8096a410c6a2013360200200341c8096a41086a22132008360200200341e0096a2004370300200341e8096a2002360200200341c8096a412c6a2015360200200341c8096a41286a2007360200200341c8096a41246a2009360200200320053602cc0920032012200f411074724108742006723602c809200641014b0d3920060e023b3a3b0b20032802c0052133418cfdc400ad4280808080d00084100322022d000f210620022d000e210520022f000c210720022d000b210820022d000a210a20022f0008210920022d0007210e2002280003210f20022d0002211220022f000021132002102341c7f3c300ad4280808080a00184100322022d000f211420022d000e211520022f000c211820022d000b211920022d000a211a20022f0008211b20022d0007211c2002280003211d20022d0002211e20022f0000211f20021023200320173602a008200341a0056a41186a2220200341a0086aad4280808080c000841001220241186a290000370300200341a0056a41106a2221200241106a290000370300200341a0056a41086a2222200241086a290000370300200320022900003703a005200210232020290300210420212f0100212020222f0100212120032d00b705212220032800b305212320032d00b205212920032d00af05212b20032d00ae05212c20032f01ac05212d20032d00ab05212a20032d00aa05212e20032d00a705212f20032800a305213020032d00a205213120032f01a005213241c00010212202450d1e20022004370038200220223a003720022023360033200220293a0032200220203b00302002202b3a002f2002202c3a002e2002202d3b002c2002202a3a002b2002202e3a002a200220213b00282002202f3a002720022030360023200220313a0022200220323b0020200220143a001f200220153a001e200220183b001c200220193a001b2002201a3a001a2002201b3b00182002201c3a00172002201d3600132002201e3a00122002201f3b0010200220063a000f200220053a000e200220073b000c200220083a000b2002200a3a000a200220093b00082002200e3a00072002200f360003200220123a0002200220133b0000200341a00c6a200241c00010aa03200341a0056a41086a2206200341c40c6a2802003602002003200341bc0c6a2902003703a005024020032d00a40c22054103470d0020021023419caec4002102411e21060c380b20032d00a70c211220032f00a50c2113200341d00c6a2802002119200341cc0c6a2802002114200341c80c6a2802002115200341b80c6a280200210a200341b40c6a280200210e200341a00c6a41106a280200210f200341ac0c6a2802002108200341a00c6a41086a280200210920032802a00c2118200341f00a6a41086a22072006280200360200200320032903a0053703f00a20021023200341c8096a41086a20072802002202360200200320032903f00a22043703c80920034180076a41086a2002360200200320043703800741eeaec4002102411921060240200541014b0d0020050e023837380b02402008450d00200910230b200a450d37200e10230c370b200341a00c6a200141046a41c80010dc041a200341c8096a41206a200241206a290200370300200341c8096a41186a200241186a290200370300200341c8096a41106a200241106a290200370300200341c8096a41086a200241086a290200370300200320022902003703c809200341c0046a200341a00c6a200341c8096a10b702024020032802c00422020d00200041023a0008410021150c350b20032802c4042106200041812e3b010820002002360200410021152000410a6a41003a0000200020063602040c340b2002411a6a2901002104200241196a2d00002114200241186a2d00002115200241166a2f01002116200241156a2d00002117200241146a2d00002118200241126a2f01002119200241116a2d0000211a200241106a2d000021092002410e6a2f0100210c2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002112200241096a2d00002113200241086a2d00002106200241066a2f01002105200241056a2d00002107200241046a2d0000211b200241026a2f0100211c200141216a290000210b200141206a2d0000211e2001411d6a2f0000211f2001411c6a2d00002120200141196a2f00002121200141186a2d00002122200141156a2f00002123200141146a2d00002129200141116a2f0000212b200141106a2d0000212c2001410c6a280200211d200141086a280200210a20022d0001210820022d0000210220012d001f212d20012d001b212a20012d0017212e20012d0013212f024002400240024020012802040e0400010203000b200341a00c6a41146a4101360200200342013702a40c200341d09dc6003602a00c200341043602cc09200341849ec6003602c8092003200341c8096a3602b00c200341a00c6a418cfac1001038000b410220054108742006411874722007724102200841ff017141014622061b200241ff017122021b21050240024020020d0020060d010b410f210641aab0c0002102024002400240024020050e050001020335000b2012410874201372200f411874722102200c410874200e7220094118747221060c340b410e210641aabac60021020c330b411321064197b0c00021020c320b411121064186b0c00021020c310b200320043703b808200320143a00b708200320153a00b608200320163b01b408200320173a00b308200320183a00b208200320193b01b0082003201a3a00af08200320093a00ae082003200c3b01ac082003200e3a00ab082003200f3a00aa08200320123b01a808200320133a00a708200320053600a3082003201b3a00a2082003201c3b01a008200341a0056a41186a22074200370300200341a0056a41106a22064200370300200341a0056a41086a22054200370300200342003703a00541e3e0c400ad4280808080c00084100322022f0000210820022d000221092002280003210c20022d0007210e2002290008210420021023200520043703002003200e3a00a7052003200c3600a305200320093a00a205200320083b01a00541e8e7c100ad42808080803084100322022d000221082002280003210920022d0007210c2002290008210420022f0000210e200210232006200e3b010020034180056a41186a200437030020034180056a41086a20052903003703002003200c3a00b705200320093600b305200320083a00b20520034180056a41106a2006290300370300200320032903a00537038005200341a00c6a20034180056a4120108a0120032d00a00c21022007200341b90c6a2900003703002006200341b10c6a2900003703002005200341a90c6a290000370300200320032900a10c3703a0050240024020024101460d00200341c8096a41186a4200370300200341c8096a41106a4200370300200341c8096a41086a4200370300200342003703c8090c010b200341c8096a41186a2007290300370300200341c8096a41106a2006290300370300200341c8096a41086a2005290300370300200320032903a0053703c8090b0240200341a0086a200341c8096a412010de04450d00419cfac1002102412221060c310b200341a00c6a200a41b00110dc041a200341003b01c809200341f00a6a200341a00c6a200341c8096a108d0241012102024020032d00f80a22064102460d00200341f90a6a310000210b20033100fa0a210420033502f40a210d20032802f00a210541b8bac600ad4280808080d00184100802402006450d00200b100e0b2004100e410021022005450d00200d4220862005ad8410080b200320023a00a20c200341113b01a00c200341a00c6a108e01200a10230c330b410220054108742006411874722007724102200841ff017141014622061b200241ff017122021b21050240024020020d0020060d010b410f210641aab0c0002102024002400240024020050e050001020335000b2012410874201372200f411874722102200c410874200e7220094118747221060c340b410e210641aabac60021020c330b411321064197b0c00021020c320b411121064186b0c00021020c310b200320043703b808200320143a00b708200320153a00b608200320163b01b408200320173a00b308200320183a00b208200320193b01b0082003201a3a00af08200320093a00ae082003200c3b01ac082003200e3a00ab082003200f3a00aa08200320123b01a808200320133a00a708200320053600a3082003201b3a00a2082003201c3b01a008200341a0056a41186a22074200370300200341a0056a41106a22064200370300200341a0056a41086a22054200370300200342003703a00541e3e0c400ad4280808080c00084100322022f0000210820022d000221092002280003210c20022d0007210e2002290008210420021023200520043703002003200e3a00a7052003200c3600a305200320093a00a205200320083b01a00541e8e7c100ad42808080803084100322022d000221082002280003210920022d0007210c2002290008210420022f0000210e200210232006200e3b010020034180056a41186a200437030020034180056a41086a20052903003703002003200c3a00b705200320093600b305200320083a00b20520034180056a41106a2006290300370300200320032903a00537038005200341a00c6a20034180056a4120108a0120032d00a00c21022007200341b90c6a2900003703002006200341b10c6a2900003703002005200341a90c6a290000370300200320032900a10c3703a0050240024020024101460d00200341c8096a41186a4200370300200341c8096a41106a4200370300200341c8096a41086a4200370300200342003703c8090c010b200341c8096a41186a2007290300370300200341c8096a41106a2006290300370300200341c8096a41086a2005290300370300200320032903a0053703c8090b0240200341a0086a200341c8096a412010de04450d0041befac1002102413121060c320b0240200a41ff01714101460d00200a4118762107200a41087621080c2f0b200341a00c6a201d41067610bc0220032802a00c21060240024020032802a80c201d413f7122024b0d00410021020c010b200620024105746a2202290018210b20022d0017211e20022d0016212d20022f0014211f20022d0013212020022d0012212a20022f0010212120022d000f212220022d000e212e20022f000c212320022d000b212920022d000a212f20022f0008212b20022d0007212c2002280003211d20022d0002210720022f00002108410121020b024020032802a40c450d00200610230b20020d2e41aabac6002102410e21060c310b2001412c6a2802002130410220054108742006411874722007724102200841ff017141014622061b200241ff017122021b21050240024020020d0020060d010b410f210641aab0c0002102024002400240024020050e050001020331000b2012410874201372200f411874722102200c410874200e7220094118747221060c300b410e210641aabac60021020c2f0b411321064197b0c00021020c2e0b411121064186b0c00021020c2d0b200320043703b808200320143a00b708200320153a00b608200320163b01b408200320173a00b308200320183a00b208200320193b01b0082003201a3a00af08200320093a00ae082003200c3b01ac082003200e3a00ab082003200f3a00aa08200320123b01a808200320133a00a708200320053600a3082003201b3a00a2082003201c3b01a008200341a0056a41186a22074200370300200341a0056a41106a22064200370300200341a0056a41086a22054200370300200342003703a00541e3e0c400ad4280808080c00084100322022f0000210820022d000221092002280003210c20022d0007210e2002290008210420021023200520043703002003200e3a00a7052003200c3600a305200320093a00a205200320083b01a00541e8e7c100ad42808080803084100322022d000221082002280003210920022d0007210c2002290008210420022f0000210e200210232006200e3b010020034180056a41186a200437030020034180056a41086a20052903003703002003200c3a00b705200320093600b305200320083a00b20520034180056a41106a2006290300370300200320032903a00537038005200341a00c6a20034180056a4120108a0120032d00a00c21022007200341b90c6a2900003703002006200341b10c6a2900003703002005200341a90c6a290000370300200320032900a10c3703a0050240024020024101460d00200341c8096a41186a4200370300200341c8096a41106a4200370300200341c8096a41086a4200370300200342003703c8090c010b200341c8096a41186a2007290300370300200341c8096a41106a2006290300370300200341c8096a41086a2005290300370300200320032903a0053703c8090b0240200341a0086a200341c8096a412010de04450d00419cfac1002102412221060c2d0b410121060240200a41ff01714101460d00200a4118762105200a41087621020c2c0b200341a00c6a201d41067610bc0220032802a00c21070240024020032802a80c201d413f7122024b0d00410021080c010b200720024105746a2202290018210b20022d0017211e20022d0016212d20022f0014211f20022d0013212020022d0012212a20022f0010212120022d000f212220022d000e212e20022f000c212320022d000b212920022d000a212f20022f0008212b20022d0007212c2002280003211d20022d0002210520022f00002102410121080b024020032802a40c450d00200710230b20080d2b41aabac6002102410e21060c2c0b200341e0066a41086a22122001411c6a290200370300200341e0066a41106a2213200141246a2902003703002003200141146a2902003703e0062002411a6a2901002104200241196a2d00002114200241186a2d00002115200241166a2f01002116200241156a2d00002117200241146a2d00002118200241126a2f01002119200241116a2d0000211a200241106a2d0000211b2002410e6a2f0100211c2002410d6a2d0000211d2002410c6a2d0000211e2002410a6a2f01002108200241096a2d00002106200241086a2d0000211f200241066a2f0100210a200241056a2d00002109200241046a2d0000210c200241026a2f01002120200141106a28020021072001410c6a2802002105200141086a280200210f20022d0001210e20022d000021020240024002400240024020012802040e050001020304000b200341a00c6a41146a4101360200200342013702a40c200341d09dc6003602a00c200341043602a408200341849ec6003602a0082003200341a0086a3602b00c200341a00c6a41b8e0c4001038000b200320043702b80c200320143a00b70c200320153a00b60c200320163b01b40c200320173a00b30c200320183a00b20c200320193b01b00c2003201a3a00af0c2003201b3a00ae0c2003201c3b01ac0c2003201d3a00ab0c2003201e3a00aa0c200320083b01a80c200320063a00a70c2003200c3a00a20c200320203b01a00c2003200a410874200972201f411874724102200241ff017145200e41ff01714101467122021b22083600a30c024020020d00410f210641aab0c0002102024002400240024020080e05000102032d000b20032800a70c210220032800ab0c21060c2c0b410e210641aabac60021020c2b0b411321064197b0c00021020c2a0b411121064186b0c00021020c290b200341c8096a41186a200341a00c6a41186a290200370300200341c8096a41106a200341a00c6a41106a290200370300200341c8096a41086a200341a00c6a41086a290200370300200320032902a00c3703c8090240200741034f0d0041c8e0c4002102410e21060c290b0240200741104d0d0041d6e0c4002102410d21060c290b41e3e0c400ad4280808080c00084100322022d000f210620022d000e210820022f000c210a20022d000b210920022d000a210c20022f0008210e20022d000721122002280003211320022d0002211420022f000021152002102341e7e0c400ad4280808080e00084100322022d000f211620022d000e211720022f000c211820022d000b211920022d000a211a20022f0008211b20022d0007211c2002280003211d20022d0002211e20022f0000211f20021023200341c0056a200341c8096a10ac0141c00010212202450d1f200220123a000720022013360003200220143a0002200220153b0000200220063a000f200220083a000e2002200a3b000c200220093a000b2002200c3a000a2002200e3b00082002201c3a00172002201d3600132002201e3a00122002201f3b0010200220163a001f200220173a001e200220183b001c200220193a001b2002201a3a001a2002201b3b0018200241386a200341c0056a41186a290200370000200241306a200341c0056a41106a290200370000200241286a200341c0056a41086a290200370000200220032902c005370020200341a00c6a200241c00010ac03024020032802a00c22060d0020021023420021044280c8afa025210b200341c8046a200341c8096a4280c8afa025420010f10120032802c8042202450d2120032802cc0421060c290b200341a00c6a41186a2903002104200341a00c6a41106a290300210b20032802a40c210820021023200341a00c6a41086a41003a0000200341a90c6a20032903c809370000200341b10c6a200341c8096a41086a290300370000200341b90c6a200341c8096a41106a290300370000200341c10c6a200341c8096a41186a290300370000200341123a00a00c200341a00c6a108e012008450d27200610230c270b200320043702d805200320143a00d705200320153a00d605200320163b01d405200320173a00d305200320183a00d205200320193b01d0052003201a3a00cf052003201b3a00ce052003201c3b01cc052003201d3a00cb052003201e3a00ca05200320083b01c805200320063a00c7052003200c3a00c205200320203b01c0052003200a410874200972201f411874724102200241ff017145200e41ff01714101467122021b22053600c305024020020d00410f210641aab0c0002102024002400240024020050e05000102032d000b20032800c705210220032800cb0521060c2c0b410e210641aabac60021020c2b0b411321064197b0c00021020c2a0b411121064186b0c00021020c290b200341c8096a41186a200341c0056a41186a290200370300200341c8096a41106a200341c0056a41106a290200370300200341c8096a41086a200341c0056a41086a290200370300200320032902c0053703c80941e3e0c400ad4280808080c00084100322022d000f210620022d000e210520022f000c210720022d000b210820022d000a210a20022f0008210920022d0007210c2002280003210e20022d0002210f20022f000021122002102341e7e0c400ad4280808080e00084100322022d000f211320022d000e211420022f000c211520022d000b211620022d000a211720022f0008211820022d000721192002280003211a20022d0002211b20022f0000211c2002102320034180076a200341c8096a10ac0141c00010212202450d202002200c3a00072002200e3600032002200f3a0002200220123b0000200220063a000f200220053a000e200220073b000c200220083a000b2002200a3a000a200220093b0008200220193a00172002201a3600132002201b3a00122002201c3b0010200220133a001f200220143a001e200220153b001c200220163a001b200220173a001a200220183b0018200241386a20034180076a41186a290100370000200241306a20034180076a41106a290100370000200241286a20034180076a41086a2901003700002002200329018007370020200341a00c6a200241c00010ac03024020032802a00c2206450d002002ad428080808080088410050b200341b80c6a2903002104200341b00c6a290300210b20032802a40c210520021023024020060d0041ede0c4002102410921060c2b0b02402005450d00200610230b200341c8096a200b200410de01200341d80c6a2004370300200341d00c6a200b370300200341a00c6a41086a41033a0000200341a90c6a20032903c809370000200341b10c6a200341c8096a41086a290300370000200341b90c6a200341d8096a290300370000200341c10c6a200341e0096a290300370000200341123a00a00c200341a00c6a108e010c290b200341f00a6a41106a2013290300370300200341f00a6a41086a2012290300370300200320032903e0063703f00a02400240200241ff01714101470d002008410874200641ff0171722108200c41ff01714101470d010c240b200a4108742009722108200e21060b200241ff01714104460d22200620027241ff0171450d2241b696c6002102410a21060c270b200141346a2802002116200141306a28020021142001412c6a2802002115200341f00a6a41106a2013290300370300200341f00a6a41086a2012290300370300200320032903e0063703f00a02400240200241ff01714101470d002008410874200641ff0171722108200c41ff01714101470d010c210b200a4108742009722108200e21060b200241ff01714104460d1f200620027241ff0171450d1f41b696c6002102410a21060c200b410841011030000b41b0dfc400102b000b41c8dfc400102b000b41c00041011030000b200341a0056a41186a22084200370300200341a0056a41106a22024200370300200341a0056a41086a22064200370300200342003703a00541d5fbc400ad42808080808001842225100322052f0000210720052d0002210a2005280003210920052d0007210c2005290008212620051023200620263703002003200c3a00a705200320093600a3052003200a3a00a205200320073b01a00541d6a0c200ad4280808080d001842226100322052d000221072005280003210a20052d000721092005290008212720052f0000210c200510232002200c3b010020034180056a41186a220c202737030020034180056a41086a220e2006290300370300200320093a00b7052003200a3600b305200320073a00b20520034180056a41106a220a2002290300370300200320032903a0053703800520034180016a20034180056a412010890220034180016a41106a290300212720032903880121282003280280012107200842003703002002420037030020064200370300200342003703a0052025100322052f0000210820052d000221092005280003210f20052d00072112200529000821252005102320062025370300200320123a00a7052003200f3600a305200320093a00a205200320083b01a0052026100322052d000221082005280003210920052d0007210f2005290008212520052f0000211220051023200220123b0100200c2025370300200e20062903003703002003200f3a00b705200320093600b305200320083a00b205200a2002290300370300200320032903a005370380052003427f2027420020071b2225200b200d7d2004202454ad7d7c2028420020071b220d200420247d7c2224200d542202ad7c220d2002200d202554200d2025511b22021b3703a8082003427f202420021b3703a008200341a0086a210220034180056a21060c670b200341a00c6a21060c5b0b200841041030000b41f499c3002102412721060c550b41809ac600102b000b41b09bc600102b000b41c00041011030000b41800141011030000b200541011030000b20032802a80c210920032802a40c210820032802a00c21070c4c0b200941011030000b41b8bbc000102b000b41a8e0c40020022012102d000b41c00041011030000b41c00041011030000b200c41041030000b200a41011030000b41c00041011030000b41f4e6c300102b000b41c00041011030000b200c42003703002005420037030020074200370300200342003703a005200b100322022f0000210a20022d0002210c2002280003210f20022d00072112200229000821042002102320072004370300200320123a00a7052003200f3600a3052003200c3a00a2052003200a3b01a005200d100322022d0002210a2002280003210c20022d0007210f2002290008210420022f0000211220021023200520123b010020092004370300200e20072903003703002003200f3a00b7052003200c3600b3052003200a3a00b20520082005290300370300200320032903a00537038005200341013a00a00c20034180056aad4280808080800484200341a00c6aad428080808010841002200041023a0008410121080c650b410841011030000b41c00041011030000b41c00041011030000b41c00041011030000b200341a00c6a41086a41023a0000200341a90c6a20032903c809370000200341b10c6a200341c8096a41086a290300370000200341b90c6a200341d8096a290300370000200341c10c6a200341e0096a290300370000200341123a00a00c200341a00c6a108e010c060b41c00041011030000b200341a0086a41106a200341f00a6a41106a290300370300200341a0086a41086a2202200341f00a6a41086a290300370300200320032903f00a3703a008024002400240200f41ff01714101460d0020034180076a410d6a200341a0086a410d6a29000037000020034180076a41086a2002290300370300200320032903a00837038007200f41087621080c010b200341c0056a200541067610bc0220032802c00521060240024020032802c8052005413f7122024b0d00410021020c010b20034188076a200620024105746a220241136a2900003703002003418d076a200241186a2900003700002003200229000b3703800720022f0000200241026a2d00004110747221082002280007210720022800032105410121020b024020032802c405450d00200610230b20020d00410121020c010b200341a0086a410d6a20034180076a410d6a290000370000200341a0086a41086a20034180076a41086a29030037030020032003290380073703a008410021020b200341b30c6a200341a0086a41086a290300370000200341a00c6a41186a2206200341ad086a290000370000200320073600a70c200320053600a30c200320032903a0083700ab0c200320083b01a00c200320084110763a00a20c02402002450d0041aabac6002102410e21060c010b200341c8096a41186a2006290200370300200341c8096a41106a200341a00c6a41106a290200370300200341c8096a41086a200341a00c6a41086a290200370300200320032902a00c3703c80941e3e0c400ad4280808080c00084100322022d000f210620022d000e210520022f000c210720022d000b210820022d000a210a20022f0008210920022d0007210c2002280003210e20022d0002210f20022f000021122002102341e7e0c400ad4280808080e00084100322022d000f211320022d000e211720022f000c211820022d000b211920022d000a211a20022f0008211b20022d0007211c2002280003211d20022d0002211e20022f0000211f2002102320034180076a200341c8096a10ac010240024041c00010212202450d002002200c3a00072002200e3600032002200f3a0002200220123b0000200220063a000f200220053a000e200220073b000c200220083a000b2002200a3a000a200220093b00082002201c3a00172002201d3600132002201e3a00122002201f3b0010200220133a001f200220173a001e200220183b001c200220193a001b2002201a3a001a2002201b3b0018200241386a20034180076a41186a290100370000200241306a20034180076a41106a290100370000200241286a20034188076a2901003700002002200329018007370020200341a00c6a200241c00010ac03200341a00c6a41186a22052903002104200341a00c6a41106a290300210b20032802a40c210720032802a00c2106200210230240024020060d004200210b420021040c010b2007450d00200610230b200520043703002003200b3703b00c200320163602a80c200320143602a40c200320153602a00c41e3e0c400ad4280808080c00084100322022d000f210620022d000e210520022f000c210720022d000b210820022d000a210a20022f0008210920022d0007210c2002280003210e20022d0002210f20022f000021122002102341e7e0c400ad4280808080e00084100322022d000f211320022d000e211620022f000c211720022d000b211820022d000a211920022f0008211a20022d0007211b2002280003211c20022d0002211d20022f0000211e20021023200341c0056a200341c8096a10ac0141c00010212202450d012002200c3a00072002200e3600032002200f3a0002200220123b0000200220063a000f200220053a000e200220073b000c200220083a000b2002200a3a000a200220093b00082002201b3a00172002201c3600132002201d3a00122002201e3b0010200220133a001f200220163a001e200220173b001c200220183a001b200220193a001a2002201a3b0018200241386a200341c0056a41186a290200370000200241306a200341c0056a41106a290200370000200241286a200341c0056a41086a290200370000200220032902c005370020200341c0003602a408200320023602a008200341a00c6a200341a0086a10722002102302402014450d00201510230b200341a00c6a41086a41013a0000200341a90c6a20032903c809370000200341b10c6a200341c8096a41086a290300370000200341b90c6a200341c8096a41106a290300370000200341c10c6a200341c8096a41186a290300370000200341123a00a00c200341a00c6a108e010c040b41c00041011030000b41c00041011030000b2014450d05201510230c050b200341a0086a41106a200341f00a6a41106a290300370300200341a0086a41086a2202200341f00a6a41086a290300370300200320032903f00a3703a008024002400240200f41ff01714101460d0020034180076a410d6a200341a0086a410d6a29000037000020034180076a41086a2002290300370300200320032903a00837038007200f41087621080c010b200341a00c6a200541067610bc0220032802a00c21060240024020032802a80c2005413f7122024b0d00410021020c010b20034188076a200620024105746a220241136a2900003703002003418d076a200241186a2900003700002003200229000b3703800720022f0000200241026a2d00004110747221082002280007210720022800032105410121020b024020032802a40c450d00200610230b20020d00410121020c010b200341a00c6a410d6a20034180076a410d6a290000370000200341a00c6a41086a20034180076a41086a29030037030020032003290380073703a00c410021020b200341d3056a200341a00c6a41086a290300370000200341c0056a41186a2206200341ad0c6a290000370000200320073600c705200320053600c305200320032903a00c3700cb05200320083b01c005200320084110763a00c20502402002450d0041aabac6002102410e21060c050b200341c8096a41186a2006290200370300200341c8096a41106a200341c0056a41106a290200370300200341c8096a41086a200341c0056a41086a290200370300200320032902c0053703c80941e3e0c400ad4280808080c00084100322022d000f210620022d000e210520022f000c210720022d000b210820022d000a210a20022f0008210920022d0007210c2002280003210e20022d0002210f20022f000021122002102341e7e0c400ad4280808080e00084100322022d000f211320022d000e211420022f000c211520022d000b211620022d000a211720022f0008211820022d000721192002280003211a20022d0002211b20022f0000211c2002102320034180076a200341c8096a10ac0141c00010212202450d012002200c3a00072002200e3600032002200f3a0002200220123b0000200220063a000f200220053a000e200220073b000c200220083a000b2002200a3a000a200220093b0008200220193a00172002201a3600132002201b3a00122002201c3b0010200220133a001f200220143a001e200220153b001c200220163a001b200220173a001a200220183b0018200241386a20034180076a41186a290100370000200241306a20034180076a41106a290100370000200241286a20034188076a2901003700002002200329018007370020200341a00c6a200241c00010ac03024020032802a00c2206450d002002ad428080808080088410050b200341a00c6a41186a2903002104200341a00c6a41106a290300210b20032802a40c210520021023024020060d0041ede0c4002102410921060c050b02402005450d00200610230b200341d0046a200341c8096a200b200410c80220032903d004200341d0046a41086a29030010c902200341d80c6a2004370300200341d00c6a200b370300200341a00c6a41086a41043a0000200341a90c6a20032903c809370000200341b10c6a200341c8096a41086a290300370000200341b90c6a200341d8096a290300370000200341c10c6a200341e0096a290300370000200341123a00a00c200341a00c6a108e010b410021020c030b41c00041011030000b200341a00c6a41186a20043703002003200b3703b00c200320073602a80c200320053602a40c2003200f3602a00c41e3e0c400ad4280808080c00084100322022d000f210620022d000e210720022f000c210820022d000b210a20022d000a210920022f0008210c20022d0007210e2002280003211220022d0002211320022f000021142002102341e7e0c400ad4280808080e00084100322022d000f211520022d000e211620022f000c211720022d000b211820022d000a211920022f0008211a20022d0007211b2002280003211c20022d0002211d20022f0000211e2002102320034180076a200341c8096a10ac01024041c00010212202450d002002200e3a000720022012360003200220133a0002200220143b0000200220063a000f200220073a000e200220083b000c2002200a3a000b200220093a000a2002200c3b00082002201b3a00172002201c3600132002201d3a00122002201e3b0010200220153a001f200220163a001e200220173b001c200220183a001b200220193a001a2002201a3b0018200241386a20034180076a41186a290100370000200241306a20034190076a290100370000200241286a20034188076a2901003700002002200329018007370020200341c0003602a408200320023602a008200341a00c6a200341a0086a1072200210232005450d03200f10230c030b41c00041011030000b2005450d00200f10230b20020d010b200041023a0008410021180c010b20004181323b01082000200636020420002002360200410021182000410a6a41003a00000b410121064101210841012105410121074101210a410121094101210c4101210e4101210f4101211241012113410121174101211441012115410121160c610b2003200b3702f8042003201e3a00f7042003202d3a00f6042003201f3b01f404200320203a00f3042003202a3a00f204200320213b01f004200320223a00ef042003202e3a00ee04200320233b01ec04200320293a00eb042003202f3a00ea042003202b3b01e8042003202c3a00e7042003201d3600e304200320053a00e204200320023b01e004200341a00c6a203041b00110dc041a200341d2096a20032902e804370100200341da096a20032902f004370100200341e2096a20032902f80437010020034180023b01c809200320032902e0043701ca09200341f00a6a200341a00c6a200341c8096a108d02024020032d00f80a22024102460d00200341f90a6a310000210b20033100fa0a210420033502f40a210d20032802f00a210541b8bac600ad4280808080d00184100802402002450d00200b100e0b2004100e410021062005450d00200d4220862005ad8410080b200320063a00a20c20034191043b01a00c200341a00c6a108e01203010230c050b203010b102203010230c020b42002104200341a0056a41186a220a4200370300200341a0056a41106a22064200370300200341a0056a41086a22054200370300200342003703a00541e3e0c400ad4280808080c00084220d100322022f0000210920022d0002210c2002280003210e20022d0007210f2002290008211020021023200520103703002003200f3a00a7052003200e3600a3052003200c3a00a205200320093b01a00541e8e7c100ad428080808030842210100322022d000221092002280003210c20022d0007210e2002290008211120022f0000210f200210232006200f3b010020034180056a41186a201137030020034180056a41086a20052903003703002003200e3a00b7052003200c3600b305200320093a00b20520034180056a41106a2006290300370300200320032903a00537038005200341a00c6a20034180056a4120108a0120032d00a00c2102200a200341b90c6a22092900003703002006200341b10c6a220a2900003703002005200341a90c6a2206290000370300200320032900a10c3703a0050240024020024101460d0041002102410021054100210c4100210e4100210f41002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c0c010b20032903b805210420032d00b705210220032d00b605210520032f01b405210c20032d00b305210e20032d00b205210f20032f01b005211220032d00af05211320032d00ae05211420032f01ac05211520032d00ab05211620032d00aa05211720032f01a805211820032d00a705211920032800a305211a20032d00a205211b20032f01a005211c0b200341ba0c6a2004370100200920023a0000200341a00c6a41186a20053a0000200341b60c6a200c3b0100200341b50c6a200e3a0000200341b40c6a200f3a0000200341b20c6a20123b0100200a20133a0000200341a00c6a41106a20143a0000200341ae0c6a20153b0100200341ad0c6a20163a0000200341ac0c6a20173a0000200341aa0c6a20183b0100200620193a00002003201a3600a50c2003201b3a00a40c2003201c3b01a20c20034191023b01a00c200341a00c6a108e012003200b3703b80c2003201e3a00b70c2003202d3a00b60c2003201f3b01b40c200320203a00b30c2003202a3a00b20c200320213b01b00c200320223a00af0c2003202e3a00ae0c200320233b01ac0c200320293a00ab0c2003202f3a00aa0c2003202b3b01a80c2003202c3a00a70c2003201d3600a30c200320073a00a20c200320083b01a00c200d100322022f0000210520022d000221072002280003210820022d0007210a20022900082104200210232010100322022f0000210920022d0002210c2002280003210620022d0007210e2002290008210b200210232003200b3702f8042003200e3a00f704200320064118763a00f604200320064108763b01f404200320063a00f3042003200c3a00f204200320093b01f004200320043702e8042003200a3a00e704200320083600e304200320073a00e204200320053b01e004200341203602cc092003200341e0046a3602c809200341a00c6a200341c8096a10f5010c030b200a10b102200a10230b2002450d010b20004181303b01082000200636020420002002360200410021162000410a6a41003a00000c010b200041023a0008410021160b410121064101210841012105410121074101210a410121094101210c4101210e4101210f41012112410121134101211741012114410121150c580b410121064101210841012105410121074101210a410121094101210c4101210e4101210f41012112410121134101211741012114410121160c570b200341e7096a20034180076a41086a2d00003a00002003200a3600db092003200e3600d7092003200f3600d309200320083600cf09200320093600cb0920032003290380073700df092003201320124110747222023b01c809200320024110763a00ca09200341a0056a41186a22062033ad422086200cad841001220241186a290000370300200341a0056a41106a2205200241106a290000370300200341a0056a41086a2207200241086a290000370300200320022900003703a00520021023200341a00c6a41186a2006290300370300200341a00c6a41106a2005290300370300200341a00c6a41086a2007290300370300200320032903a0053703a00c02400240200341a00c6a200341c8096a412010de040d0020034180056a41186a420037030020034180056a41106a2206420037030020034180056a41086a22054200370300200342003703800541c4fbc400ad4280808080e00084100322022f0000210720022d000221082002280003210a20022d00072109200229000821042002102320052004370300200320093a0087052003200a36008305200320083a008205200320073b01800541f9bcc000ad4280808080e00084100322022d000221072002280003210820022d0007210a2002290008210420022f0000210920021023200620093b0100200341e0046a41186a2004370300200341e0046a41086a20052903003703002003200a3a0097052003200836009305200320073a009205200341e0046a41106a200629030037030020032003290380053703e004200341b8046a200341e0046a4120108f014100210220032802bc0441a08d066e410020032802b8041b20184f0d01200341bc0c6a2019360200200341b80c6a2014360200200341b40c6a2015360200200341b00c6a2033360200200341ac0c6a2016360200200341a80c6a200c360200200341023a00a40c200320183602a00c2017200341a00c6a10c9030c0a0b02402014450d00201510230b4187afc4002102412321060c010b418cfdc400ad4280808080d00084100322022d000f210620022d000e210520022f000c210720022d000b210820022d000a210a20022f0008210920022d0007210e2002280003210f20022d0002211220022f000021132002102341c7f3c300ad4280808080a001841003220231000f2104200231000e210b200233000c210d200231000b2110200231000a21112002330008212420022d000721182002280003211a20022d0002211b20022f0000211c20021023200320173602a00c200341a0056a41186a221d200341a00c6aad4280808080c000841001220241186a290000370300200341a0056a41106a221e200241106a290000370300200341a0056a41086a221f200241086a290000370300200320022900003703a00520021023200341f00a6a41186a2220201d290300370300200341f00a6a41106a221d201e290300370300200341f00a6a41086a221e201f290300370300200320032903a0053703f00a024041c00010212202450d002002200e3a00072002200f360003200220123a0002200220133b0000200220063a000f200220053a000e200220073b000c200220083a000b2002200a3a000a200220093b0008200220183a00172002201a3600132002201b3a00122002201c3b001020022011421086202484201042188684200d42208684200b42308684200442388684370018200220032903f00a370020200241286a201e290300370000200241306a201d290300370000200241386a20202903003700002002ad4280808080800884100520021023200320333602a808200320163602a4082003200c3602a008200320193602a80c200320143602a40c200320153602a00c4100210220174100200341a0086a200341a00c6a10b2021a0c090b41c00041011030000b2016450d08200c10230c080b02402008450d00200510230b4112210641baaec4002102200a450d02200e10230c020b4112210641baaec40021022007450d01200910230c010b4122210641ccaec40021022013200341a0086a412010de040d002005202d470d00200341a00c6a41106a2016360200200341ac0c6a200c360200200341a00c6a41086a2017360200200341b40c6a200329038007370200200341d00c6a202a360200200341cc0c6a2029360200200341c80c6a202b360200200341bc0c6a20034180076a41086a290300370200200341c40c6a20034180076a41106a2d00003a0000200341013a00a40c200320183602a00c200320032f0180053b00a50c200320034182056a2d00003a00a70c202c200341a00c6a10c9030c030b2029450d04202b10230c040b410021050b200341870b6a20043700002003200b3700ff0a200320063a008f0b2003200d3700f70a2003200c3600f30a200320023b01f00a200320024110763a00f20a02402005450d0041aabac6002102410e21060c030b20034180076a41186a2202200341f00a6a41186a29030037030020034180076a41106a200341f00a6a41106a29030037030020034180076a41086a2206200341f00a6a41086a290300370300200320032903f00a37038007200341a00c6a200341c8096a10bb03024020032802a00c4101460d004186aec4002102411621060c030b20032802a40c2105200341a00c6a41186a2002290300370300200341a00c6a41106a20034180076a41106a290300370300200341a00c6a41086a200629030037030020032003290380073703a00c418cfdc400ad4280808080d00084100322022d000f210620022d000e210720022f000c210820022d000b210a20022d000a210920022f0008210c20022d0007210e2002280003210f20022d0002211220022f00002113200210234184ffc300ad4280808080b00184100322022d000f211420022d000e211520022f000c211620022d000b211720022d000a211820022f0008211920022d0007211a2002280003211b20022d0002211c20022f0000211d20021023200320053602f00a200341a0056a41186a2205200341f00a6aad4280808080c000841001220241186a290000370300200341a0056a41106a221e200241106a290000370300200341a0056a41086a221f200241086a290000370300200320022900003703a0052002102320052903002104201e2f01002105201f2f0100211e20032d00b705211f20032800b305212020032d00b205212120032d00af05212220032d00ae05212320032f01ac05212920032d00ab05212b20032d00aa05212c20032d00a705212d20032800a305212a20032d00a205212e20032f01a005212f41c00010212202450d04200220043700382002201f3a003720022020360033200220213a0032200220053b0030200220223a002f200220233a002e200220293b002c2002202b3a002b2002202c3a002a2002201e3b00282002202d3a00272002202a3600232002202e3a00222002202f3b0020200220143a001f200220153a001e200220163b001c200220173a001b200220183a001a200220193b00182002201a3a00172002201b3600132002201c3a00122002201d3b0010200220063a000f200220073a000e200220083b000c2002200a3a000b200220093a000a2002200c3b00082002200e3a00072002200f360003200220123a0002200220133b0000200341c0003602f40a200320023602f00a200341a00c6a200341f00a6a10f501200210230b410021020b0b20020d020b200041023a0008410021140c020b41c00041011030000b200041812c3b01082000200636020420002002360200410021142000410a6a41003a00000b410121064101210841012105410121074101210a410121094101210c4101210e4101210f4101211241012113410121170c470b410121064101210841012105410121074101210a410121094101210c4101210e4101210f41012112410121130c450b20032802940c450d00200510230b024020020d00200041023a00080c300b20004181263b010820002006360204200020023602002000410a6a41003a00000c2f0b200341d8026a2004200b42c0843d420010e204200341c8026a20032903d802220d200341d8026a41086a290300221042c0fb42427f10e104200341b8026a200d201042d08603420010e104200341e8026a200341c8096a20032903b8022210200420032903c8027c220d42d086037e200d421480220d42c0fb427e7c42a0c21e56200da76aad7c220d4280a094a58d1d200d4280a094a58d1d56200341b8026a41086a290300200d201054ad7c220d420052200d501b22021b2210200d420020021b220d10f101024020032802e802450d004188c1c3002102411a21080c010b200341e0046a41186a220a4200370300200341e0046a41106a22064200370300200341e0046a41086a22054200370300200342003703e00441f4fcc400ad42808080808001842226100322022f0000210920022d0002210c2002280003210e20022d00072112200229000821272002102320052027370300200320123a00e7042003200e3600e3042003200c3a00e204200320093b01e00441888ac400ad4280808080d001842227100322022d000221092002280003210c20022d0007210e2002290008212820022f0000211220021023200620123b010020034180056a41186a2212202837030020034180056a41086a221320052903003703002003200e3a00f7042003200c3600f304200320093a00f20420034180056a41106a22092006290300370300200320032903e00437038005200341b0026a20034180056a4120108f0120032802b402210c20032802b002210e200a42003703002006420037030020054200370300200342003703e0042026100322022f0000211420022d000221152002280003211620022d00072117200229000821282002102320052028370300200320173a00e704200320163600e304200320153a00e204200320143b01e0042027100322022d000221142002280003211520022d000721162002290008212720022f0000211720021023200620173b01002012202737030020132005290300370300200320163a00f704200320153600f304200320143a00f20420092006290300370300200320032903e004370380052003200c4100200e1b220941016a3602a00c20034180056aad4280808080800484200341a00c6aad4280808080c000841002200341f70c6a2011370000200341ef0c6a2024370000200341a00c6a41186a200d370300200341a00c6a41386a200341c8096a41186a290300370300200341a00c6a41306a200341c8096a41106a290300370300200341a00c6a41286a200341c8096a41086a290300370300200341ff0c6a20083a0000200341e70c6a2025370000200341e30c6a200f360000200320073b01e00c200341e20c6a20074110763a00002003200b3703a80c200320043703a00c200320103703b00c200320032903c8093703c00c20261003220231000f2104200231000e210b200233000c210d200231000b2110200231000a21112002330008212420022d000721072002280003210820022d0002210c20022f0000210e2002102341f980c400ad4280808080900184100322022d000f210f20022d000e211220022f000c211320022d000b211420022d000a211520022f0008211620022d000721172002280003211820022d0002211920022f0000211a20021023200320093602f00a200341a0056a41186a221b200341f00a6aad4280808080c000841001220241186a290000370300200341a0056a41106a221c200241106a290000370300200341a0056a41086a221d200241086a290000370300200320022900003703a00520021023200a201b2903003703002006201c2903003703002005201d290300370300200320032903a0053703e00441c00010212202450d03200220073a0007200220083600032002200c3a00022002200e3b000020022011421086202484201042188684200d42208684200b42308684200442388684370008200220173a001720022018360013200220193a00122002201a3b00102002200f3a001f200220123a001e200220133b001c200220143a001b200220153a001a200220163b0018200220032903e004370020200241286a200341e0046a41086a290300370000200241306a2006290300370000200241386a200a290300370000200341003602f80a200342013703f00a200341a00c6a41206a200341f00a6a1071200341a00c6a41086a290300210420032903a00c210b0240024020032802f40a220520032802f80a22066b4110490d0020032802f00a21050c010b200641106a22072006490d1d200541017422062007200620074b1b22064100480d1d0240024020050d002006102121050c010b20032802f00a20052006102521050b2005450d05200320063602f40a200320053602f00a20032802f80a21060b200520066a220520043700082005200b3700002003200641106a3602f80a200341a00c6a41c0006a200341f00a6a1071200341b80c6a290300210420032903b00c210b0240024020032802f40a220720032802f80a22056b4110490d0020032802f00a21060c010b200541106a22062005490d1d200741017422052006200520064b1b22084100480d1d0240024020070d002008102121060c010b20032802f00a20072008102521060b2006450d06200320083602f40a200320063602f00a20032802f80a2105200821070b200620056a220820043700082008200b3700002002ad4280808080800884200541106aad4220862006ad84100202402007450d00200610230b20021023200341ac0c6a200936020041002102200341a80c6a41003a00002003410d3a00a00c200341a00c6a108e010b2002450d010b20004181243b010820002008360204200020023602002000410a6a41003a00000c2c0b200041023a00080c2b0b41c00041011030000b200641011030000b200841011030000b2004a7450d04200a10230c040b0c030b200341a00c6a41186a200341a0086a41186a290300370300200341a00c6a41106a200341a0086a41106a290300370300200341a00c6a41086a200341a0086a41086a290300370300200320032903a0083703a00c4100210c200341a00c6a2106410021050b02400240200c2012460d00200f21070c010b0240200f200c460d00200f21070c010b200f41016a2202200f490d13200f41017422072002200720024b1b220741ffffff3f712007470d13200741057422024100480d1302400240200f0d0020021021210a0c010b200a200f41057420021025210a0b200a450d042003200a360280070b200a20054105746a220241206a2002200c20056b41057410dd041a200241186a200641186a290000370000200241106a200641106a290000370000200241086a200641086a290000370000200220062900003700002003200c41016a3602e006200341c0056a41186a4200370300200341c0056a41106a22064200370300200341c0056a41086a22054200370300200342003703c00541f0dfc400ad4280808080b00284100322022f0000210a20022d0002210c2002280003210f20022d00072112200229000821042002102320052004370300200320123a00c7052003200f3600c3052003200c3a00c2052003200a3b01c0054183e0c400ad4280808080f00084100322022d0002210a2002280003210c20022d0007210f2002290008210420022f0000211220021023200620123b0100200341a00c6a41186a2004370300200341a00c6a41086a20052903003703002003200f3a00d7052003200c3600d3052003200a3a00d205200341a00c6a41106a2006290300370300200320032903c0053703a00c200328028007210220032802e0062105200341003602f80a200342013703f00a2005200341f00a6a105c02402005450d002005410574210603402002200341f00a6a1071200241206a2102200641606a22060d000b0b20032802f40a2102200341a00c6aad428080808080048420033502f80a42208620032802f00a2206ad84100202402002450d00200610230b200341a00c6a41186a200341a0086a41186a290300370300200341a00c6a41106a200341a0086a41106a290300370300200341a00c6a41086a200341a0086a41086a290300370300200320032903a0083703a00c4100210c410141002003280280072202200510cd032003410c3b01a00c200341a00c6a108e012007450d00200210230b4110210f0b024002400240200e417f6a220241034b0d00024020020e0403030300030b20090d010c020b200e4104490d012009450d010b200810230b200c0d020b200041023a0008410021130c020b200241011030000b20004181223b01082000200f3602042000200c360200410021132000410a6a41003a00000b410121064101210841012105410121074101210a410121094101210c4101210e4101210f410121120c310b410121064101210841012105410121074101210a410121094101210c4101210e4101210f0c2f0b410121064101210841012105410121074101210a410121094101210c4101210e0c2d0b410121064101210841012105410121074101210a410121094101210c0c2b0b410121064101210841012105410121074101210a410121090c290b4194fcc400ad4280808080800184100322022d000f210620022d000e211720022f000c211820022d000b211920022d000a211a20022f0008211b20022d0007211c2002280003211d20022d0002211e20022f0000211f2002102341d8e9c000ad4280808080a002841003220231000f210b200231000e210d200233000c2110200231000b2111200231000a21242002330008212520022d000721202002280003212120022d0002212220022f0000212320021023200320293602a00c200341a0056a41186a220520264280808080c0008422261001220241186a290000370300200341a0056a41106a220a200241106a290000370300200341a0056a41086a220c200241086a290000370300200320022900003703a0052002102320034180056a41186a2229200529030037030020034180056a41106a222b200a29030037030020034180056a41086a222c200c290300370300200320032903a005370380050240024041c00010212202450d002002201c3a00072002201d3600032002201e3a00022002201f3b0000200220063a000f200220173a000e200220183b000c200220193a000b2002201a3a000a2002201b3b0008200220203a001720022021360013200220223a0012200220233b001020022024421086202584201142188684201042208684200d42308684200b423886843700182002200329038005370020200241286a202c290300370000200241306a202b290300370000200241386a2029290300370000200320153602a00c200520261001220641186a290000370300200a200641106a290000370300200c200641086a290000370300200320062900003703a0052006102320034180076a41186a200529030037030020034180076a41106a200a29030037030020034180076a41086a200c290300370300200320032903a00537038007200241c00041800110252202450d012002200329038007370040200241d8006a20034198076a290300370000200241d0006a20034190076a290300370000200241c8006a20034188076a290300370000200341e0003602a40c200320023602a00c20072009200341a00c6a10c5012002102302402008450d00200710230b02402004a7450d00201610230b02402013450d00201410230b0240200e450d00200e410c6c2106200f210203400240200241046a280200450d00200228020010230b2002410c6a2102200641746a22060d000b0b02402012450d00200f10230b200041023a0008410021090c030b41c00041011030000b41800141011030000b02402013450d00201410230b0240200e450d00200e410c6c2106200f210203400240200241046a280200450d00200228020010230b2002410c6a2102200641746a22060d000b0b02402012450d00200f10230b20004181163b01082000200536020420002007360200410021092000410a6a41003a00000b410121064101210841012105410121074101210a0c250b02402013450d00201410230b2002450d0020004181103b01082000200636020420002002360200410021072000410a6a41003a00000c010b200041023a0008410021070b4101210641012108410121050c200b41012106410121080c1e0b2005200241c4006c6a2202200c4100200e1b360204200241003a000020022006290200370208200241106a200641086a290200370200200241186a200641106a290200370200200241206a200641186a290200370200200241286a200641206a290200370200200241306a200641286a290200370200200241386a200641306a290200370200200241c0006a200641386a280200360200200b422086200442ffffffff0f83844280808080107c21042009200741f0006c6a210a024020070d00200921070c030b200341a00c6a41106a211f200341a00c6a41086a211e20092107024003402007280204210220072802002106200341a00c6a200741086a41e80010dc041a200741f0006a21072002450d04200341c8096a200341a00c6a41e80010dc041a200320023602a40c200320063602a00c201e200341c8096a41e80010dc041a20032802900c2105200341a0056a41186a22154200370300200341a0056a41106a22064200370300200341a0056a41086a220c4200370300200342003703a00541c4fbc400ad4280808080e00084100322022f0000210820022d0002210e2002280003210f20022d000721122002290008210b20021023200c200b370300200320123a00a7052003200f3600a3052003200e3a00a205200320083b01a00541f9bcc000ad4280808080e00084100322022d000221082002280003210e20022d0007210f2002290008210b20022f0000211220021023200620123b010020034180056a41186a2212200b37030020034180056a41086a2213200c2903003703002003200f3a00b7052003200e3600b305200320083a00b20520034180056a41106a2006290300370300200320032903a00537038005200341d8016a20034180056a4120108f0120032802d801210620032802dc012108200341f00a6a200341a00c6a10ae0102400240024020032802a00c22020d0041bcaac500210e4110210f0c010b024020022008410020061b22064d0d00411a210f41ccaac500210e0c010b200341a0086a2002417f6a1089010240200341a0086a201f412010de04450d004119210f41e6aac500210e0c010b024020032802a00c220e20064f0d004126210f41ffaac500210e0c010b02400240200520052004422088220ba7220841c4006c22066a460d00200541016a2102034002402002417f6a2d00004101470d0041012105200341f00a6a2002460d032002200341f00a6a412010de04450d030b200241c4006a2102200641bc7f6a22060d000b0b410021050b200341a0086a200e108901200341a0086a200341f00a6a412010de042102200341c0056a41086a220620034180076a41086a290200370300200341c0056a41106a20034180076a41106a29020037030020032003290280073703c00541a6aac500210e4116210f20050d0520020d010c050b200341c0056a41086a20034180076a41086a290200370300200341c0056a41106a20034180076a41106a29020037030020032003290280073703c0050c040b200341e0066a410e6a2205200341c0056a410e6a290100370100200341e0066a41086a220e2006290300370300200320032903c0053703e00620034180076a200341a00c6a10ae01200341f00a6a41186a22064200370300200341f00a6a41106a220f4200370300200341f00a6a41086a22164200370300200342003703f00a2012420037030020034180056a41106a22174200370300201342003703002003420037038005024041c80010212202450d00200341a0056a10d502200241186a2015290300370200200241106a200341a0056a41106a290300370200200241086a200c290300370200200220032903a005370200200241023602202002410136024420022003290380053701242002412c6a2013290300370100200241346a20172903003701002002413c6a2012290300370100200320023602a00820034282808080203702a408200341a0086a10d602200341a0086a41186a2006290300370300200341a0086a41106a200f290300370300200341a0086a41086a22062016290300370300200320032903f00a3703a008200341a0086a10c8012006200e290300370300200341a0086a410e6a220c2005290100370100200320032903e0063703a008200329039807210d20032d0097072105200328009307210e20032d009207210f20032f019007211220032d008f07211320032d008e07211520032f018c07211620032d008b07211720032d008a07211820032f018807211920032d008707211a200328008307211b20032d008207211c20032f018007211d0240024020082004a7460d00200421100c010b200841016a22022008490d04200ba74101742220200220022020491bad221042c4007e220b422088a70d04200ba722204100480d040240024020080d002020102121020c010b20032802900c200841c4006c2020102521020b2002450d03200320023602900c2004422088220ba721080b20032802900c200841c4006c6a22024116360028200241a6aac500360024200241003a00212002200d370019200220053a00182002200e3600142002200f3a0013200220123b0011200220133a0010200220153a000f200220163b000d200220173a000c200220183a000b200220193b00092002201a3a00082002201b3600042002201c3a00032002201d3b0001200241013a00002002413a6a200c290100370000200241346a2006290300370000200220032903a00837002c201042ffffffff0f832104200b422086210b024020032802ac0c2206450d0020032802a40c2102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a28020010230c030b2002410c6a280200450d02200241086a28020010230c020b2002410c6a280200450d01200241086a28020010230c010b200241086a280200450d00200241046a28020010230b200241246a21022006415c6a22060d000b0b200b2004842104024020032802a80c450d0020032802a40c10230b20044280808080107c21042007200a470d010c060b0b41c80041041030000b202041041030000b102a000b024020032802ac0c2206450d0020032802a40c2102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a28020010230c030b2002410c6a280200450d02200241086a28020010230c020b2002410c6a280200450d01200241086a28020010230c010b200241086a280200450d00200241046a28020010230b200241246a21022006415c6a22060d000b0b024020032802a80c450d0020032802a40c10230b02402007200a460d00034020072802042208450d01200741086a280200210c02402007410c6a2802002202450d00200241246c21062008210203400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a28020010230c030b2002410c6a280200450d02200241086a28020010230c020b2002410c6a280200450d01200241086a28020010230c010b200241086a280200450d00200241046a28020010230b200241246a21022006415c6a22060d000b0b200741f0006a21070240200c450d00200810230b2007200a470d000b0b02402014450d00200910230b2004a7450d0320032802900c10230c030b2007200a460d00034020072802042208450d01200741086a280200210c02402007410c6a2802002202450d00200241246c21062008210203400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a28020010230c030b2002410c6a280200450d02200241086a28020010230c020b2002410c6a280200450d01200241086a28020010230c010b200241086a280200450d00200241046a28020010230b200241246a21022006415c6a22060d000b0b200741f0006a21070240200c450d00200810230b2007200a470d000b0b02402014450d00200910230b200341e0046a41186a4200370300200341e0046a41106a22064200370300200341e0046a41086a22054200370300200342003703e00441a6a3c500ad4280808080a00184100322022f0000210720022d000221082002280003210a20022d000721092002290008210b200210232005200b370300200320093a00e7042003200a3600e304200320083a00e204200320073b01e00441fca4c500ad4280808080e00084100322022d000221072002280003210820022d0007210a2002290008210b20022f0000210920021023200620093b010020034180076a41186a200b37030020034180076a41086a20052903003703002003200a3a00f704200320083600f304200320073a00f20420034180076a41106a2006290300370300200320032903e00437038007200341a00c6a20032802900c22022004422088a710d402201120033502a80c42208620032802a00c2206ad841002024020032802a40c450d00200610230b02402004a7450d00200210230b200041023a000841002108410121060c180b02402007450d002009200741f0006c6a210820092107034002402007410c6a2802002206450d0020072802042102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a28020010230c030b2002410c6a280200450d02200241086a28020010230c020b2002410c6a280200450d01200241086a28020010230c010b200241086a280200450d00200241046a28020010230b200241246a21022006415c6a22060d000b0b200741f0006a21020240200741086a280200450d00200728020410230b2002210720022008470d000b0b2014450d00200910230b200041810a3b01082000200f3602042000200e360200410021082000410a6a41003a0000410121060c160b410021070b200341f7046a200d370000200320103700ef04200320063a00ff04200320113700e704200320053600e304200320023b01e004200320024110763a00e20420070d06200341a00c6a41186a200341e0046a41186a290300370300200341a00c6a41106a200341e0046a41106a290300370300200341a00c6a41086a200341e0046a41086a290300370300200320032903e0043703a00c200341d0016a200341c8096a200341a00c6a2004200b4100108103024020032802d0012202450d0020032802d40121060c0a0b410021020c090b410021070b20034197076a20263700002003202737008f07200320063a009f0720032028370087072003200536008307200320023b018007200320024110763a00820720070d042004422088a72105200341c8096a41186a20034180076a41186a290300370300200341c8096a41106a20034180076a41106a290300370300200341c8096a41086a20034180076a41086a29030037030020032003290380073703c8090240024002402004a741ff01714101460d002004420888a721022025a721060c010b20034180076a2004422688a710bc022003280280072108024002402003280288072005413f7122054b0d00410021072028210b20272111202621100c010b200820054105746a22072f0000200741026a2d0000411074722102200729000f211120072d001f21062007290007210b20072800032105200741176a2900002110410121070b0240200328028407450d00200810230b20070d00410121070c010b410021070b200341f7046a2010370000200320113700ef04200320063a00ff042003200b3700e704200320053600e304200320023b01e004200320024110763a00e20420070d04200341a00c6a41186a200341e0046a41186a290300370300200341a00c6a41106a200341e0046a41106a290300370300200341a00c6a41086a200341e0046a41086a290300370300200320032903e0043703a00c200341c8016a200341c8096a200341a00c6a2024200d410110810320032802c8012202450d0620032802cc0121060c070b2006ad42808080808004842002ad428080808080028410020b200341a00c6a2004200b10dc0241d5fbc400ad4280808080800184100322022d000f210620022d000e210520022f000c210720022d000b210820022d000a210a20022f0008210920022d0007210c2002280003210e20022d0002210f20022f000021122002102341eea0c200ad4280808080f00184100322022d000f211320022d000e211420022f000c211520022d000b211620022d000a211720022f0008211820022d000721192002280003211a20022d0002211b20022f0000211c20021023200341e0046a200341a00c6a10ac01024002400240024041c00010212202450d002002200c3a00072002200e3600032002200f3a0002200220123b0000200220063a000f200220053a000e200220073b000c200220083a000b2002200a3a000a200220093b0008200220193a00172002201a3600132002201b3a00122002201c3b0010200220133a001f200220143a001e200220153b001c200220163a001b200220173a001a200220183b0018200241386a200341e0046a41186a290300370000200241306a200341e0046a41106a290300370000200241286a200341e0046a41086a290300370000200220032903e004370020200341e8006a200241c000108902200341e8006a41106a29030021042003290370210b2003280268210620021023200b420020061b220b20115422072004420020061b2204201054200420105122021b0d01200b201156200420105620021b450d03200341a0056a41186a220a4200370300200341a0056a41106a22024200370300200341a0056a41086a22064200370300200342003703a00541d5fbc400ad4280808080800184220d100322052f0000210820052d000221092005280003210c20052d0007210e2005290008212420051023200620243703002003200e3a00a7052003200c3600a305200320093a00a205200320083b01a00541d6a0c200ad4280808080d001842224100322052d000221082005280003210920052d0007210c2005290008212520052f0000210e200510232002200e3b010020034180056a41186a220e202537030020034180056a41086a220f20062903003703002003200c3a00b705200320093600b305200320083a00b20520034180056a41106a22092002290300370300200320032903a00537038005200341d0006a20034180056a4120108902200341d0006a41106a29030021252003290358212620032802502108200a42003703002002420037030020064200370300200342003703a005200d100322052f0000210a20052d0002210c2005280003211220052d000721132005290008210d200510232006200d370300200320133a00a705200320123600a3052003200c3a00a2052003200a3b01a0052024100322052d0002210a2005280003210c20052d000721122005290008210d20052f0000211320051023200220133b0100200e200d370300200f2006290300370300200320123a00b7052003200c3600b3052003200a3a00b20520092002290300370300200320032903a00537038005200342002025420020081b220d2007ad201020047d7c7c2026420020081b2204200b20117d222454ad7d220b200420247d2224200456200b200d56200b200d511b22021b3703a80820034200202420021b3703a008200341a0086a210220034180056a21060c020b41c00041011030000b200341a0056a41186a22084200370300200341a0056a41106a22024200370300200341a0056a41086a22064200370300200342003703a00541d5fbc400ad4280808080800184220d100322052f0000210720052d0002210a2005280003210920052d0007210c2005290008212420051023200620243703002003200c3a00a705200320093600a3052003200a3a00a205200320073b01a00541d6a0c200ad4280808080d001842224100322052d000221072005280003210a20052d000721092005290008212520052f0000210c200510232002200c3b010020034180056a41186a220c202537030020034180056a41086a220e2006290300370300200320093a00b7052003200a3600b305200320073a00b20520034180056a41106a220a2002290300370300200320032903a00537038005200341386a20034180056a4120108902200341386a41106a29030021252003290340212620032802382107200842003703002002420037030020064200370300200342003703a005200d100322052f0000210820052d000221092005280003210f20052d000721122005290008210d200510232006200d370300200320123a00a7052003200f3600a305200320093a00a205200320083b01a0052024100322052d000221082005280003210920052d0007210f2005290008210d20052f0000211220051023200220123b0100200c200d370300200e20062903003703002003200f3a00b705200320093600b305200320083a00b205200a2002290300370300200320032903a005370380052003427f2025420020071b220d201020047d2011200b54ad7d7c2026420020071b22042011200b7d7c220b2004542202ad7c220420022004200d542004200d511b22021b3703a8082003427f200b20021b3703a008200341a0086a210220034180056a21060b2006ad42808080808004842002ad428080808080028410020b200341a00c6a2011201010ca020c040b410021070b200341f7046a200d370000200320103700ef04200320063a00ff04200320113700e704200320053600e304200320023b01e004200320024110763a00e2042007450d010b41aabac6002102410e21060c020b200341a00c6a41186a200341e0046a41186a290300370300200341a00c6a41106a200341e0046a41106a290300370300200341a00c6a41086a200341e0046a41086a290300370300200320032903e0043703a00c200341306a200341c8096a200341a00c6a2004200b410110810320032802302202450d00200328023421060c010b410021020b024020020d00200041023a00080c010b20004181083b010820002006360204200020023602002000410a6a41003a00000b41012106410121080c090b200510230b0240024002402007417f6a220241064b0d000240024002400240024020020e0707000701020304070b41000d062004a70d050c060b41000d052004a70d040c050b200a450d0402402004422088a72202450d00200241186c21062005210203400240200241046a280200450d00200228020010230b0240200241106a280200450d002002410c6a28020010230b200241186a2102200641686a22060d000b0b2004a70d030c040b2006450d0302402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d00200228020010230b2002410c6a2102200641746a22060d000b0b2004a70d020c030b41000d022004a70d010c020b2004a7450d010b200510230b410f210241aab0c00021064104210520080e06010204030500010b200041023a0008410121080c050b410021050c030b410e210241aabac6002106410121050c020b411121024186b0c0002106410321050c010b411321024197b0c0002106410221050b41012108200041013b010820002002360204200020063602002000410a6a20053a00000b410021060b410121050b410121070b4101210a0b410121090b4101210c0b4101210e0b4101210f0b410121120b410121130b410121170b410121140b41012115410121160b410121180b024002402001280200220241184b0d0002400240024002400240024002400240024002400240024002400240024020020e1900101010100102100310040510060708090a10100b100c0d0e000b2006450d0f200141086a10dd030c0f0b2008450d0e02402001410c6a2802002202450d0020012802042200200241f0006c6a2107034002402000410c6a2802002206450d0020002802042102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a28020010230c030b2002410c6a280200450d02200241086a28020010230c020b2002410c6a280200450d01200241086a28020010230c010b200241086a280200450d00200241046a28020010230b200241246a21022006415c6a22060d000b0b200041f0006a21020240200041086a280200450d00200028020410230b2002210020022007470d000b0b200141086a280200450d0e200128020410230c0e0b2005450d0d0240200141086a2d00002202410f4b0d00410120027441bfbf03710d0e024020024106470d00200141106a280200450d0f2001410c6a28020010230c0f0b200141106a280200450d0e2001410c6a28020010230c0e0b200141146a280200450d0d200141106a28020010230c0d0b2007450d0c200141086a280200450d0c200128020410230c0c0b200a450d0b200141086a280200450d0b200128020410230c0b0b2009450d0a02402001410c6a280200450d00200141086a28020010230b02402001411c6a2802002206450d00200141146a28020021022006410c6c210603400240200241046a280200450d00200228020010230b2002410c6a2102200641746a22060d000b0b200141186a280200450d0a200128021410230c0a0b200c450d09200141086a2d0000417f6a220241074b0d09024002400240024020020e08000d0d0d0d010203000b2001410c6a220228020010da01200228020010230c0c0b2001410c6a220228020010da01200228020010230c0b0b2001410c6a220228020010da01200228020010230c0a0b2001410c6a220228020010da01200228020010230c090b200e450d0820012d0004417f6a220241024b0d0802400240024020020e03000102000b2001410c6a280200450d0a200141086a28020010230c0a0b200141086a220228020010da01200228020010230c090b2001410c6a220228020010da01200228020010230c080b200f450d0720012d0004417f6a220241024b0d0702400240024020020e03000102000b2001410c6a280200450d09200141086a28020010230c090b200141086a220228020010da01200228020010230c080b2001410c6a220228020010da01200228020010230c070b2012450d06200141086a2802004101470d06200141106a280200450d062001410c6a28020010230c060b2013450d0520012d00044104490d052001410c6a280200450d05200141086a28020010230c050b2017450d0402402001410c6a2802002206450d0020012802042102200641d0016c210603402002106c200241d0016a2102200641b07e6a22060d000b0b200141086a280200450d04200128020410230c040b2014450d03200141086a2d000022024105490d03024020024105470d00200141386a280200450d04200141346a28020010230c040b200141146a280200450d03200141106a28020010230c030b2015450d0220012d0004417f6a220241034b0d020240024020020e0400040401000b0240200141106a280200450d002001410c6a28020010230b2001411c6a280200450d03200141186a28020010230c030b02402001410c6a280200450d00200141086a28020010230b200141186a280200450d02200141146a28020010230c020b2016450d0102402001280204220241024b0d00024020020e03030003030b200141086a220228020010da01200228020010230c020b2001412c6a220228020010da01200228020010230c010b2018450d0002402001280204220241034b0d00024020020e0402000202020b2001410c6a280200450d01200141086a28020010230c010b200141306a280200450d002001412c6a28020010230b200341d00d6a24000b13002000410136020420004190d9c1003602000b02000ba44b10057f017e017f017e077f017e017f017e057f017e037f017e027f027e057f027e230041f00b6b2201240020014188066a41186a420037030020014188066a41106a2202420037030020014188066a41086a220342003703002001420037038806200141c8016a41086a22044182fdc400ad4280808080a001841003220541086a290000370300200120052900003703c8012005102320032004290300370300200120012903c80137038806200441b39fc600ad42808080809001841003220541086a290000370300200120052900003703c80120051023200220012903c8012206370300200141d8016a41086a2003290300370300200141d8016a41106a2006370300200141d8016a41186a2004290300370300200120063703f80a20012001290388063703d801200141900b6a200141d8016a4120108b020240024002400240024002400240024020012802900b2207450d000240024020012902940b2208422088a722050d00410021092007210a0c010b200741046a210a2007280200210b410121090b20014188066a41186a220c420037030020014188066a41106a220d420037030020014188066a41086a220e42003703002001420037038806200141c8016a41086a220f4191fdc400ad428080808090018422101003220441086a290000370300200120042900003703c80120041023200e200f290300370300200120012903c80137038806200f4184ddc100ad4280808080e000841003220441086a290000370300200120042900003703c80120041023200141f80a6a41086a2211200f2903002206370300200120012903c80122123703f80a20022012370000200241086a22132006370000200141d8016a41086a2214200e290300370300200141d8016a41106a2215200d290300370300200141d8016a41186a2216200c29030037030020012001290388063703d80120014188066a200141d8016a10fe012001280288062204410420041b221721030240200129028c06420020041b2218422088a72219450d00200720054102746a211a20172019412c6c6a211b200141d8016aad4280808080800484211c201721030340200e20032204410c6a290200370300200d200441146a290200370300200c2004411c6a29020037030020012004290204370388062004412c6a2103200441246a28020022054103460d01200441286a280200211d2004280200211e200141a8016a41186a200c2903002206370300200141a8016a41106a200d2903002212370300200141a8016a41086a200e290300221f370300200120012903880622203703a801200141c80a6a41186a22042006370300200141c80a6a41106a22212012370300200141c80a6a41086a2222201f370300200120203703c80a0240024002400240024020094101470d00200b201e460d010b20054101470d03200141900b6a41186a22052004290300370300200141900b6a41106a22232021290300370300200141900b6a41086a22212022290300370300200120012903c80a3703900b201d41024b0d03200c4200370300200d4200370300200e42003703002001420037038806200f20101003220441086a290000370300200120042900003703c80120041023200e200f290300370300200120012903c80137038806200f419adfc100ad4280808080a0018422121003220441086a290000370300200120042900003703c801200410232011200f2903002206370300200120012903c801221f3703f80a2002201f370000201320063700002014200e2903003703002015200d2903003703002016200c29030037030020012001290388063703d80120014188066a200141d8016a1091022001280288062104200129028c062106201620052903003703002015202329030037030020142021290300370300200120012903900b3703d8012004410420041b21242006420020041b2206422088a722214103490d01024020214103460d002021417d6a210520242021410c6c6a41746a210403400240200441046a280200450d00200428020010230b200441746a21042005417f6a22050d000b0b200642ffffffff0f834280808080308421060c020b0240200a201a470d0041002109201a210a0c030b200a280200210b41012109200a41046a210a0c020b02402006a7220420216b410320216b22254f0d00202120256a22052021490d06200441017422222005202220054b1bad2206420c7e221f422088a70d06201fa722054100480d060240024020040d002005102121240c010b20242004410c6c2005102521240b2024450d0c0b20242021410c6c6a21040240024020254102490d002021417e6a2105034020044204370200200441086a41003602002004410c6a2104202141016a2121200541016a222220054f21232022210520230d000b2025450d010b2004410036020820044204370200200642ffffffff0f83202141016aad4220868421060c010b200642ffffffff0f832021ad4220868421060b201d2006422088a722224f0d09200c2016290300370300200d2015290300370300200e2014290300370300200120012903d801370388062024201d410c6c6a220541086a2121024020052802082204200541046a2223280200470d00200441016a221d2004490d0520044101742225201d2025201d4b1b221dad42247e221f422088a70d05201fa722254100480d050240024020040d002025102121040c010b2005280200200441246c2025102521040b2004450d092023201d36020020052004360200202128020021040b2005280200200441246c6a22042001290388063702042004201e3602002004410c6a200e290300370200200441146a200d2903003702002004411c6a200c2903003702002021202128020041016a360200200120243602e80a200120063702ec0a200c4200370300200d4200370300200e42003703002001420037038806200f20101003220441086a290000370300200120042900003703c80120041023200e200f290300370300200120012903c801221f3703f80a2001201f37038806200f20121003220441086a290000370300200120042900003703c801200410232011200f2903002212370300200120012903c801221f3703f80a200d201f370000200d41086a20123700002014200e2903003703002015200d2903003703002016200c29030037030020012001290388063703d801024020240d00201c10050c010b2006a721212001412036028c062022410c6c21052001200141d8016a36028806200141e80a6a20014188066a10732024210403400240200441046a280200450d00200428020010230b2004410c6a2104200541746a22050d000b2021450d00202410230b2003201b470d000b201b21030b2008a7210e2018a7210d2003410020196b412c6c6a21040240034020172004460d012004412c6a2104200341246a21052003412c6a210320052802004103470d000b0b0240200d450d00201710230b200e450d00200710230b20014188066a41186a420037030020014188066a41106a220e420037030020014188066a41086a220342003703002001420037038806200141b80a6a41086a2204418cfdc400ad4280808080d000841003220541086a290000370300200120052900003703b80a2005102320032004290300370300200120012903b80a37038806200441d8fdc300ad4280808080b001841003220541086a290000370300200120052900003703b80a20051023200e20012903b80a2206370300200141d8016a41086a2003290300370300200141d8016a41106a2006370300200141d8016a41186a2004290300370300200120063703900b20012001290388063703d801200141c80a6a200141d8016a4120108602024020012802c80a4101470d002000200141c80a6a41086a2802006b220341e7074b0d00200320004b0d00200141b80a6a41086a2204418cfdc400ad4280808080d000841003220541086a290000370300200120052900003703b80a20051023200141a8016a41086a220e2004290300370300200120012903b80a3703a801200441e3fdc300ad4280808080f000841003220541086a290000370300200120052900003703b80a20051023200141900b6a41086a22052004290300370300200120012903b80a3703900b200120033602d801200141c80a6a41186a220d200141d8016aad4280808080c000841001220441186a290000370300200141c80a6a41106a220c200441106a290000370300200141c80a6a41086a2221200441086a290000370300200120042900003703c80a2004102320014188066a41186a2222200d29030037030020014188066a41106a220d200c29030037030020014188066a41086a220c2021290300370300200120012903c80a3703880641c00010212204450d04200420012903a801370000200420012903900b3700102004200129038806370020200441086a200e290300370000200441186a2005290300370000200441286a200c290300370000200441306a200d290300370000200441386a2022290300370000200141a0016a200441c00041014100410010b80120012802a00121052004102320054101460d0020014188066a2003417f6a220420034d2004109202024002402001280288064103470d00200141023602d0052001410236029805200141023602e004200141023602a804200141023602f003200141023602b8032001410236028003200141023602c8022001410236029002200141023602d8010c010b200141d8016a20014188066a41b00410dc041a0b200141b80a6a41086a2204418cfdc400ad4280808080d000841003220541086a290000370300200120052900003703b80a20051023200141a8016a41086a220e2004290300370300200120012903b80a3703a801200441e3fdc300ad4280808080f000841003220541086a290000370300200120052900003703b80a20051023200141900b6a41086a22052004290300370300200120012903b80a3703900b200120033602f80a200141c80a6a41186a2203200141f80a6aad4280808080c000841001220441186a290000370300200141c80a6a41106a220d200441106a290000370300200141c80a6a41086a220c200441086a290000370300200120042900003703c80a2004102320014188066a41186a2221200329030037030020014188066a41106a2203200d29030037030020014188066a41086a220d200c290300370300200120012903c80a3703880641c00010212204450d03200420012903a801370000200420012903900b3700102004200129038806370020200441086a200e290300370000200441186a2005290300370000200441286a200d290300370000200441306a2003290300370000200441386a2021290300370000200141c00036028c062001200436028806200141d8016a20014188066a10d101200410230b20014188066a41186a220d420037030020014188066a41106a2205420037030020014188066a41086a220342003703002001420037038806200141e80a6a41086a220441a79fc600ad4280808080c001841003220e41086a2900003703002001200e2900003703e80a200e102320032004290300370300200120012903e80a37038806200441b39fc600ad428080808090018422121003220e41086a2900003703002001200e2900003703e80a200e1023200520012903e80a2206370300200141d8016a41086a220c2003290300370300200141d8016a41106a22212006370300200141d8016a41186a22222004290300370300200120063703900b20012001290388063703d801200141d8016aad221042808080808004841005200d42003703002005420037030020034200370300200142003703880620044182fdc400ad4280808080a001841003220e41086a2900003703002001200e2900003703e80a200e102320032004290300370300200120012903e80a37038806200420121003220e41086a2900003703002001200e2900003703e80a200e1023200520012903e80a2206370300200c20032903003703002021200637030020222004290300370300200120063703900b20012001290388063703d80120014198016a200141d8016a412041014100410010b8012001280298014101470d0102400240024020004180a305700d0020014188066a10930220014188016a20014188066a1094022001420020014188016a41086a290300221220012903880122064280c8afa02554ad7d221f20064280b8d0df5a7c2220200656201f201256200642ffc7afa025561b22041b22063703800b20014200202020041b22123703f80a20014188066a41186a2209200637030020014188066a41106a2223201237030020014188066a41086a221741013a00002001410d3a00880620014188066a108e014100211e200141003a008f0b200142003703b001200142003703a8012009420037030020234200370300201742003703002001420037038806200141c8016a41086a222241f4fcc400ad428080808080018422081003220441086a290000370300200120042900003703c8012004102320172022290300370300200120012903c80122063703900b200120063703880620224180b4c300ad428080808090018422181003220441086a290000370300200120042900003703c80120041023202320012903c8012206370300200141d8016a41086a220d2017290300370300200141d8016a41106a220b2006370300200141d8016a41186a221b2022290300370300200120063703900b20012001290388063703d80120014188066a200141d8016a1095022001280288062204410420041b210a0240200129028c06420020041b221c422088a72203450d00200141c8016aad4280808080c00084212620014191066a210f200141900b6a41c0006a211d200141b00b6a2124410021214100211e41002104024003400240024002400240201e450d00200a20044102746a2105200a200420216a4102746a210e0340200420034f0d02200141d8016a2005280200220c10960220012903d8014201520d04200141900b6a200d41e00010dc041a20012903f80a221f20012903900b222054200141f80a6a41086a2903002206200141900b6a41086a29030022125420062012511b450d03200141013a008f0b0240202120046a220c20034f0d00200e2005280200360200200541046a2105200e41046a210e200441016a22042003490d010c070b0b41c4bcc000200c2003102d000b200a20044102746a21050340200420034f0d01200141d8016a2005280200220c10960220012903d8014201520d03200141900b6a200d41e00010dc041a20012903f80a221f20012903900b22205a200141f80a6a41086a2903002206200141900b6a41086a29030022125a20062012511b0d02200541046a2105200141013a008f0b200441016a22042003490d000b4100211e0c050b41f0bbc00020042003102d000b2001201f20207d3703f80a2001200620127d201f202054ad7d3703800b202220081003220541086a290000370300200120052900003703c80120051023200141b80a6a41086a220e2022290300370300200120012903c8013703b80a202241f980c400ad42808080809001841003220541086a290000370300200120052900003703c80120051023200141e80a6a41086a221a2022290300370300200120012903c8013703e80a2001200c3602c801200141c80a6a41186a220220261001220541186a290000370300200141c80a6a41106a2214200541106a290000370300200141c80a6a41086a2215200541086a290000370300200120052900003703c80a20051023200920022903003703002023201429030037030020172015290300370300200120012903c80a3703880641c00010212205450d05200520012903b80a370000200541086a200e290300370000200520012903e80a370010200541186a201a2903003700002005200129038806370020200541286a2017290300370000200541306a2023290300370000200541386a20092903003700002005ad4280808080800884100520051023202420012903a00b200141900b6a41186a29030010de01200141f8006a201d20012903900b200141900b6a41086a2205290300109702200141a8016a41086a220e427f200e2903002206200141f8006a41086a2903007c20012903a801221220012903787c221f201254220ead7c2212200e201220065420122006511b220e1b3703002001427f201f200e1b3703a80120012903900b210620014188066a41386a2005290300370300200f201d290000370000200f41086a201d41086a290000370000200f41106a201d41106a290000370000200f41186a201d41186a290000370000200120063703b806200141023a0090062001410d3a0088062001200c3602b40620014188066a108e010b2021417f6a2121201e41016a211e200441016a22042003490d000b0b201e450d00200420034f0d00200a20044102746a2205201e4102746b2005200320046b41027410dd041a0b2009420037030020234200370300201742003703002001420037038806202220081003220441086a290000370300200120042900003703c8012004102320172022290300370300200120012903c80122063703900b2001200637038806202220181003220441086a290000370300200120042900003703c80120041023200141900b6a41086a20222903002206370300200120012903c80122123703900b20232012370000202341086a2006370000200d2017290300370300200b2023290300370300201b200929030037030020012001290388063703d80102400240200a0d002010428080808080048410050c010b200141003602900620014201370388062003201e6b220320014188066a105c0240024020030d00200128029006210c200128028c06210d20012802880621030c010b410020012802900622046b2105200a20034102746a2122200128028c06210d200a210e0340200e280200212102400240200d20056a4104490d0020012802880621030c010b200441046a22032004490d07200d410174220c2003200c20034b1b220c4100480d0702400240200d0d00200c102121030c010b200128028806200d200c102521030b2003450d062001200c36028c062001200336028806200c210d0b2001200441046a220c36029006200320046a20213600002005417c6a2105200c21042022200e41046a220e470d000b0b201ca7210420104280808080800484200cad4220862003ad8410020240200d450d00200310230b2004450d00200a10230b024020012d008f0b0d00200141d0006a20012903f80a2206200141f80a6a41086a2204290300221242c0843d420010e204200141c0006a2001290350221f200141d0006a41086a290300222042c0fb42427f10e104200141306a201f20204290ce00420010e104200420122012200141306a41086a2903002001290330221f200620012903407c22204290ce007e202042e40080222042c0fb427e7c42a0c21e562020a76aad7c2220201f54ad7c221f2020200656201f201256201f2012511b22031b221f7d20062006202020031b221254ad7d3703002001200620127d3703f80a20014188066a41186a2205420037030020014188066a41106a220e420037030020014188066a41086a220342003703002001420037038806200141c8016a41086a220441d5fbc400ad428080808080018422201003220d41086a2900003703002001200d2900003703c801200d102320032004290300370300200120012903c80122063703c80a2001200637038806200441d6a0c200ad4280808080d0018422081003220d41086a2900003703002001200d2900003703c801200d1023200e20012903c8012206370300200141d8016a41086a22212003290300370300200141d8016a41106a22222006370300200141d8016a41186a22232004290300370300200120063703c80a20012001290388063703d801200141e0006a200141d8016a4120108902200141e0006a41106a2903002106200129036821182001280260210d20054200370300200e4200370300200342003703002001420037038806200420201003220c41086a2900003703002001200c2900003703c801200c102320032004290300370300200120012903c80122203703c80a2001202037038806200420081003220c41086a2900003703002001200c2900003703c801200c102320052004290300222037030020212003290300370300202220012903c801220837030020232020370300200120083703c80a20012001290388063703d8012001420020064200200d1b2206201f7d20184200200d1b2220201254ad7d2208202020127d2218202056200820065620082006511b22041b3703900620014200201820041b370388062010428080808080048420014188066aad42808080808002841002200141a8016a41086a220d427f200d29030022082006201f20041b7c20012903a80122062020201220041b7c22202006542204ad7c22062004200620085420062008511b22041b3703002001427f202020041b3703a8012005201f370300200e2012370300200341033a00002001410d3a00880620014188066a108e010b200141900b6a109302200141d8016a200141900b6a20012903a8012206200141a8016a41086a2903002212410241001088020240024020012802d8010d00200141d8016a41106a290300212020012903e001211f200141c80a6a41186a22054200370300200141c80a6a41106a22044200370300200141c80a6a41086a220e4200370300200142003703c80a200141c8016a41086a220341d5fbc400ad4280808080800184221c1003220d41086a2900003703002001200d2900003703c801200d1023200e2003290300370300200120012903c80122103703b80a200120103703c80a200341d6a0c200ad4280808080d0018422261003220d41086a2900003703002001200d2900003703c801200d1023200420012903c801221037030020014188066a41086a200e29030037030020014188066a41106a220e201037030020014188066a41186a220d2003290300370300200120103703e80a200120012903c80a37038806200120014188066a4120108902201220207d2006201f54ad7d202020127d201f200654ad7d201f2006582020201258202020125122031b220c1b21272006201f7d201f20067d200c1b2118200141106a29030042002001280200220c1b211020012903084200200c1b210802400240201f200656202020125620031b0d002005420037030020044200370300200141c80a6a41086a220c4200370300200142003703c80a200141c8016a41086a2203201c1003222141086a290000370300200120212900003703c80120211023200c2003290300370300200120012903c80122063703b80a200120063703c80a200320261003222141086a290000370300200120212900003703c80120211023200141e80a6a41086a20032903002206370300200120012903c80122123703e80a20042012370000200441086a200637000020014188066a41086a200c290300370300200e2004290300370300200d2005290300370300200120012903c80a370388062001427f201020277c200820187c22122008542204ad7c22062004200620105420062010511b22041b3703d00a2001427f201220041b3703c80a200141c80a6a21040c010b2005420037030020044200370300200141c80a6a41086a220c4200370300200142003703c80a200141c8016a41086a2203201c1003222141086a290000370300200120212900003703c80120211023200c2003290300370300200120012903c80122063703b80a200120063703c80a200320261003222141086a290000370300200120212900003703c80120211023200141e80a6a41086a20032903002206370300200120012903c80122123703e80a20042012370000200441086a200637000020014188066a41086a200c290300370300200e2004290300370300200d2005290300370300200120012903c80a3703880620014200201020277d2008201854ad7d2206200820187d2212200856200620105620062010511b22041b3703d00a20014200201220041b3703c80a200141c80a6a21040b20014188066aad42808080808004842004ad428080808080028410020c010b41a8a9c300ad4280808080a00984100820014188066a41186a2205420037030020014188066a41106a220e420037030020014188066a41086a220342003703002001420037038806200141c8016a41086a220441d5fbc400ad428080808080018422201003220d41086a2900003703002001200d2900003703c801200d102320032004290300370300200120012903c801221f3703c80a2001201f37038806200441d6a0c200ad4280808080d0018422081003220d41086a2900003703002001200d2900003703c801200d1023200e20012903c801221f370300200141d8016a41086a220c2003290300370300200141d8016a41106a2221201f370300200141d8016a41186a222220042903003703002001201f3703c80a20012001290388063703d801200141186a200141d8016a4120108902200141186a41106a290300211f200129032021182001280218210d20054200370300200e4200370300200342003703002001420037038806200420201003220e41086a2900003703002001200e2900003703c801200e102320032004290300370300200120012903c80122203703c80a2001202037038806200420081003220e41086a2900003703002001200e2900003703c801200e1023200520042903002220370300200c2003290300370300202120012903c801220837030020222020370300200120083703c80a20012001290388063703d8012001427f201f4200200d1b221f20127c20184200200d1b221220067c22202012542204ad7c220620042006201f542006201f511b22041b370390062001427f202020041b370388062010428080808080048420014188066aad428080808080028410020b20012903f80a2106200141a0066a200141f80a6a41086a29030037030020014198066a200637030020014188066a41086a41043a00002001410d3a00880620014188066a108e010b2000109802200141f00b6a24000f0b41c00041011030000b200c41011030000b102a000b418cbec100102b000b41c00041011030000b41c00041011030000b202541041030000b41a4dfc100201d2022102d000b200541041030000bd00a050c7f017e037f037e037f230041d0016b220224002002412036021c20022001360218200241206a2001ad4280808080800484100410900102400240200228022022030d00200041003602000c010b200228022421042002200241286a28020036024420022003360240200241106a200241c0006a106e02400240024002400240024020022802100d000240024002400240024002402002280244410c6e2205410c6c2201417f4c0d00200228021421060240024020010d00410421070c010b200110212207450d020b02402006450d0041002108410021090340200241086a200241c0006a106e20022802080d0b2002280244220141246e220a41246c220b417f4c0d02200228020c210c02400240200b0d004104210d0c010b200b1021220d450d050b200aad210e02400240200c450d004100210f034020014104490d0d200f41016a210f20022001417c6a220a36024420022002280240221041046a3602402010280000211141002101200241003a00c80103400240200a2001470d0020024100360244200141ff0171450d0f200241003a00c8010c0f0b200241a8016a20016a201020016a220b41046a2d00003a00002002200b41056a3602402002200141016a220b3a00c801200b2101200b4120470d000b200241e8006a41086a200241a8016a41086a2903002212370300200241e8006a41106a200241a8016a41106a2903002213370300200241e8006a41186a200241a8016a41186a2903002214370300200241c8006a41086a22102012370300200241c8006a41106a22152013370300200241c8006a41186a221620143703002002200a200b6b2201360244200220022903a8012212370368200220123703480240200ea7200e422088a7220b470d00200b41016a220a200b490d0b200b4101742217200a200a2017491bad221242247e2213422088a70d0b2013a7220a4100480d0b02400240200b0d00200a1021210d0c010b200d200b41246c200a1025210d0b200d450d09200e42808080807083201284210e0b200d200b41246c6a220b2011360200200b2002290348370204200b410c6a2010290300370200200b41146a2015290300370200200b411c6a2016290300370200200e4280808080107c210e200f200c470d000c020b0b200d450d0c0b200941016a2101024020052009470d002009410174220b2001200b20014b1b2205ad420c7e2212422088a70d082012a7220b4100480d080240024020090d00200b102121070c010b20072009410c6c200b102521070b2007450d070b20072009410c6c6a220b200e370204200b200d3602002008410c6a21082001210920012006470d000b200241386a200636020020022005360234200220073602300c080b200241386a2006360200200220053602342002200736023020070d070c0a0b102f000b200141041030000b200b41041030000b200a41041030000b200b41041030000b102a000b200241003602300c030b20002002290330370200200041086a200241306a41086a2802003602000c030b200ea7450d00200d10230b2002410036023002402009450d002007210103400240200141046a280200450d00200128020010230b2001410c6a2101200841746a22080d000b0b2005450d00200710230b200241003602900120024201370388012002410c36026c2002200241186a360268200220024188016a360248200241bc016a4101360200200242013702ac0120024198c2c3003602a8012002200241e8006a3602b801200241c8006a41b8a3c500200241a8016a102e1a20023502900142208620023502880184100820004100360200200228028c01450d0020022802880110230b2004450d00200310230b200241d0016a24000bb90401057f23004190096b2203240002400240024020010d00200041033602000c010b200341086a41086a2201418cfdc400ad4280808080d000841003220441086a2900003703002003200429000037030820041023200341e8086a41086a22052001290300370300200320032903083703e808200141e3fdc300ad4280808080f000841003220441086a2900003703002003200429000037030820041023200341f8086a41086a22062001290300370300200320032903083703f8082003200236028c09200341086a41186a22022003418c096aad4280808080c000841001220441186a290000370300200341086a41106a2207200441106a2900003703002001200441086a2900003703002003200429000037030820041023200341b8046a41186a22042002290300370300200341b8046a41106a22022007290300370300200341b8046a41086a22072001290300370300200320032903083703b80441c00010212201450d01200120032903e808370000200120032903f808370010200120032903b804370020200141086a2005290300370000200141186a2006290300370000200141286a2007290300370000200141306a2002290300370000200141386a2004290300370000200341086a200141c00010a60320032802082104200341b8046a200341086a41047241ac0410dc041a0240024020044103470d00200041033602000c010b20002004360200200041046a200341b8046a41ac0410dc041a0b200110230b20034190096a24000f0b41c00041011030000bbf0301077f230041d0006b22012400024002400240024002400240410110212202450d00200241ed003a000020024101410210252202450d01200241ef003a000120024102410410252202450d02200241e4d8013b000220024104410810252202450d03200241f0f2bda10736000420024108411010252203450d04200341f2e6c9cb07360008200141003a0048410c210220032104410021050340200141003a0008200141086a20042002410047220610dc041a024020020d00200141003a00080b20022006490d06200141286a20056a20012d00083a00002001200541016a22073a0048200220066b2102200420066a21042007210520074120470d000b200141086a41186a2202200141286a41186a290300370300200141086a41106a2206200141286a41106a290300370300200141086a41086a2204200141286a41086a2903003703002001200129032837030820031023200041186a2002290300370000200041106a2006290300370000200041086a200429030037000020002001290308370000200141d0006a24000f0b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b20062002103e000bff0202057f027e230041e0006b22022400200241c0006a41086a220341d5fbc400ad42808080808001841003220441086a2900003703002002200429000037034020041023200241206a41086a2205200329030037030020022002290340370320200341e3a0c200ad4280808080b001841003220441086a2900003703002002200429000037034020041023200241306a41086a2206200329030037030020022002290340370330200241c0006a200110ac01024041c000102122040d0041c00041011030000b200420022903203700002004200229033037001020042002290040370020200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241c0006a41106a290000370000200441386a200241c0006a41186a290000370000200241086a200441c000108902200241086a41106a290300210720022903102108200228020821032004102320002007420020031b37030820002008420020031b370300200241e0006a24000bbc0201027f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100410900102400240200228021022010d00200041003602000c010b200228021421032002200241106a41086a28020036022420022001360220200241c8006a200241206a107b024002402002280248450d0020002002290348370200200041086a200241c8006a41086a2802003602000c010b20024100360230200242013703282002410c36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c20024198c2c3003602482002200241386a360258200241c4006a41b8a3c500200241c8006a102e1a2002350230422086200235022884100820004100360200200228022c450d00200228022810230b2003450d00200110230b200241e0006a24000b920402077f017e230041f0016b22022400200241086a220341f4fcc400ad42808080808001841003220441086a2900003703002002200429000037030020041023200241e8006a41086a2205200329030037030020022002290300370368200341f980c400ad42808080809001841003220441086a2900003703002002200429000037030020041023200241f8006a41086a2206200329030037030020022002290300370378200220013602ec01200241186a2201200241ec016aad4280808080c000841001220441186a290000370300200241106a2207200441106a2900003703002003200441086a290000370300200220042900003703002004102320024188016a41186a2208200129030037030020024188016a41106a2201200729030037030020024188016a41086a220720032903003703002002200229030037038801024041c00010212204450d0020042002290368370000200420022903783700102004200229038801370020200441086a2005290300370000200441186a2006290300370000200441286a2007290300370000200441306a2001290300370000200441386a20082903003700002002200441c000108f032002290300210920024188016a200341e00010dc041a0240024020094201510d00200042003703000c010b20004201370300200041086a20024188016a41e00010dc041a0b20041023200241f0016a24000f0b41c00041011030000bbb0f0a027f017e027f017e037f027e017f047e017f017e23004180026b22042400200441f0016a41086a220541d5fbc400ad428080808080018422061003220741086a290000370300200420072900003703f00120071023200441f0006a41086a22082005290300370300200420042903f001370370200541e3a0c200ad4280808080b0018422091003220741086a290000370300200420072900003703f00120071023200441d0006a41086a220a2005290300370300200420042903f00137035020044180016a200110ac0102400240024041c00010212207450d0020072004290370370000200720042903503700102007200429008001370020200741086a2008290300370000200741186a200a290300370000200741286a20044180016a41086a290000370000200741306a20044180016a41106a220b290000370000200741386a20044180016a41186a220c290000370000200441386a200741c000108902200441386a41106a290300210d2004290340210e2004280238210f20071023200520061003220741086a290000370300200420072900003703f0012007102320082005290300370300200420042903f001370370200520091003220741086a290000370300200420072900003703f00120071023200a2005290300370300200420042903f00137035020044180016a200110ac0141c00010212207450d014200211020072004290370370000200720042903503700102007200429008001370020200741086a200441f0006a41086a290300370000200741186a200441d0006a41086a290300370000200741286a20044180016a41086a290000370000200741306a200b290000370000200741386a200c290000370000200441206a200741c000108902200441206a41106a29030021062004290328211120042802202105200710232006420020051b21092011420020051b210602400240200e4200200f1b220e20027c220242ffc7afa02556200d4200200f1b20037c2002200e54ad7c220342005220035022071b0d004200210d2006200984500d010b024020024280c8afa02554410020071b0d00200441f0016a41086a220741d5fbc400ad42808080808001841003220541086a290000370300200420052900003703f00120051023200441f0006a41086a22082007290300370300200420042903f001370370200741e3a0c200ad4280808080b001841003220541086a290000370300200420052900003703f00120051023200441d0006a41086a22052007290300370300200420042903f00137035020044180016a200110ac0141c00010212207450d0420072004290370370000200720042903503700102007200429008001370020200741086a2008290300370000200741186a2005290300370000200741286a20044180016a41086a290000370000200741306a20044180016a41106a290000370000200741386a20044180016a41186a290000370000200441186a200741c00041014100410010b801200428021821052007102320054101460d00200110db0220044180016a41386a200337030020044180016a41306a200237030020044180016a41086a41003a000020044189016a200129000037000020044191016a200141086a29000037000020044199016a200141106a290000370000200441a1016a200141186a290000370000200441023a00800120044180016a108e010b200320097d2002200654ad7d210d200220067d211020012002200310dc022006200256200920035620092003511b2201450d00200620027d201020011b210e4200211020044180016a41186a2208420037030020044180016a41106a220a420037030020044180016a41086a220542003703002004420037038001200441f0016a41086a220741d5fbc400ad428080808080018422121003220f41086a2900003703002004200f2900003703f001200f102320052007290300370300200420042903f00122113703702004201137038001200741d6a0c200ad4280808080d0018422131003220f41086a2900003703002004200f2900003703f001200f1023200a20042903f0012211370300200441d0006a41086a220b2005290300370300200441d0006a41106a220c2011370300200441d0006a41186a221420072903003703002004201137037020042004290380013703502004200441d0006a4120108902200441106a2903002111200429030821152004280200210f20084200370300200a4200370300200542003703002004420037038001200720121003220a41086a2900003703002004200a2900003703f001200a102320052007290300370300200420042903f00122123703702004201237038001200720131003220a41086a2900003703002004200a2900003703f001200a1023200820072903002212370300200b2005290300370300200c20042903f0012213370300201420123703002004201337037020042004290380013703502004420020114200200f1b2211200920037d2006200254ad7d200d20011b7d20154200200f1b2202200e54ad7d22032002200e7d2206200256200320115620032011511b22071b3703880120044200200620071b37038001200441d0006aad428080808080048420044180016aad428080808080028410024200210d0b200020103703002000200d37030820044180026a24000f0b41c00041011030000b41c00041011030000b41c00041011030000bc86e05057f037e077f037e047f230041f0026b22012400200141e0006a41186a4200370300200141e0006a41106a22024200370300200141e0006a41086a2203420037030020014200370360200141d0016a41086a22044188e0c100ad4280808080f001841003220541086a290000370300200120052900003703d0012005102320032004290300370300200120012903d0012206370380022001200637036020044197e0c100ad4280808080d001841003220541086a290000370300200120052900003703d00120051023200220012903d0012206370300200141d0026a41086a2003290300370300200141d0026a41106a2006370300200141d0026a41186a20042903003703002001200637038002200120012903603703d002200141203602e4012001200141d0026a3602e00120014180026a200141d0026aad22074280808080800484220810041090010240024020012802800222030d0041022104200141023602c4020c010b2001280284022105200120014180026a41086a28020022043602d401200120033602d0010240024020044104490d002001200341046a3602d00120012004417c6a22093602d40120094104490d00200328000021092001200441786a3602d4012001200341086a3602d0012003280004210a200141e0006a200141d0016a106d2001280260220b450d002001290264210641002104200141003a006002400240024020012802d401220c450d002001200c417f6a220d3602d401200120012802d001220e41016a3602d001200e2d00004101460d010b0c010b200d4104490d002001200c417b6a3602d4012001200e41056a3602d001200e280001210f410121040b2001200f3602c802200120063702bc022001200b3602b8022001200a3602b402200120093602b0020c010b200141003602980220014201370390022001410c3602f4012001200141e0016a3602f001200120014190026a3602ec01200141f4006a41013602002001420137026420014198c2c3003602602001200141f0016a360270200141ec016a41b8a3c500200141e0006a102e1a2001350298024220862001350290028410080240200128029402450d0020012802900210230b410221040b200120043602c4022005450d00200310230b200141e0006a41106a2203200141b0026a41106a2205280200360200200141e0006a41086a2209200141b0026a41086a220a290300370300200120012903b002370360024002400240024002400240024020044102460d0020014190026a41106a2003280200220336020020014190026a41086a200929030022103703002001200129036022063703900220052003360200200a2010370300200141c8026a200f360200200120063703b002200120043602c40202402006a722032000470d000240024020044101460d00200141c0026a280200220fad42287e2206422088a70d042006a72203417f4c0d0420012802b802210420012802b402210b0240024020030d004108210a0c010b20031021220a450d060b410021050240200f450d00200f41286c210941002105200a21030340200441086a2903002106200441106a2903002110200441186a290300211120042903002112200341206a200441206a290300370300200341186a2011370300200341106a2010370300200341086a200637030020032012370300200341286a2103200541016a2105200441286a2104200941586a22090d000b0b200141e0026a200b360200200141d0026a410c6a2005360200200141d0026a41086a200f3602002001200a3602d402200141003602d002200141e0006a200141d0026a1099022001418b026a200141e0006a41086a2802003600002001200129036037008302200141e0006a410c6a20014187026a290000370000200141c6a4b9da04360061200141023a00602001200129008002370065200141e0006a108b01200f450d01200a10230c010b200141c0026a280200220aad42287e2206422088a70d032006a72203417f4c0d0320012802b802210420012802b402210c0240024020030d004108210b0c010b20031021220b450d060b02400240200a0d00410021050c010b200a41286c210941002105200b21030340200441086a2903002106200441106a2903002110200441186a290300211120042903002112200341206a200441206a290300370300200341186a2011370300200341106a2010370300200341086a200637030020032012370300200341286a2103200541016a2105200441286a2104200941586a22090d000b0b200141e4026a200c360200200141e0026a2005360200200141d0026a410c6a200a360200200141d0026a41086a200b3602002001200f3602d402200141013602d002200141e0006a200141d0026a1099022001418b026a200141e0006a41086a2802003600002001200129036037008302200141e0006a410c6a20014187026a290000370000200141c6a4b9da04360061200141023a00602001200129008002370065200141e0006a108b01200a450d00200b10230b20012802b00221030b024020012802b40220036a2000470d00200141143602d4022001418adcc1003602d002200141013a00602001200141b0026a41086a2203360264200141e0006a200141d0026a1070200141e0006a41086a22042003290000370300200141e0006a41106a2205200341086a28000036020020014100360264200141063a0060200141e0006a108e01200141e0006a41186a220f4200370300200542003703002004420037030020014200370360200141d0016a41086a22034188e0c100ad4280808080f001841003220941086a290000370300200120092900003703d0012009102320042003290300370300200120012903d0012206370380022001200637036020034197e0c100ad4280808080d001841003220941086a290000370300200120092900003703d0012009102320014180026a41086a20032903002206370300200120012903d00122103703800220022010370000200241086a2006370000200141d0026a41086a2004290300370300200141d0026a41106a2005290300370300200141d0026a41186a200f290300370300200120012903603703d002200810050c010b200141bc026a280200450d0020012802b80210230b200141e0006a41186a22094200370300200141e0006a41106a220f4200370300200141e0006a41086a2203420037030020014200370360200141d0016a41086a22044188e0c100ad4280808080f001841003220541086a290000370300200120052900003703d0012005102320032004290300370300200120012903d00122063703800220012006370360200441a4e0c100ad4280808080d000841003220541086a290000370300200120052900003703d0012005102320014180026a41086a20042903002206370300200120012903d00122103703800220022010370000200241086a2006370000200141d0026a41086a2003290300370300200141d0026a41106a200f290300370300200141d0026a41186a2009290300370300200120012903603703d00220014120360284022001200141d0026a3602800220014190026a200810041090012001280290022204450d0520014190026a41086a2802002105200128029402210941002103200141003a00600240024002402005450d0020042d0000220f41034b0d00024002400240200f0e0405000102050b2005417f6a4108490d0220042900012106410121030c040b410221030c020b2005417f6a4108490d0020042900012106410321030c020b200141003602b802200142013703b0022001410c3602f401200120014180026a3602f0012001200141b0026a3602d001200141f4006a41013602002001420137026420014198c2c3003602602001200141f0016a360270200141d0016a41b8a3c500200141e0006a102e1a20013502b80242208620013502b002841008024020012802b402450d0020012802b00210230b410421030b0b02402009450d00200410230b2003417f6a220441024b0d0520040e03040503040b102f000b200341081030000b200341081030000b2006422088a7210402402006a722032000470d00200141043602d002200120043602d402200141e0006a200141d0026a1099022001418b026a200141e8006a2802003600002001200129036037008302200141ec006a20014187026a290000370000200141c6a4b9da04360061200141023a00602001200129008002370065200141e0006a108b010b200420036a2000470d01200141003602b002200141e0006a41186a22094200370300200141e0006a41106a22004200370300200141e0006a41086a2203420037030020014200370360200141d0016a41086a22044188e0c100ad4280808080f001841003220541086a290000370300200120052900003703d0012005102320032004290300370300200120012903d00122063703800220012006370360200441a4e0c100ad4280808080d000841003220541086a290000370300200120052900003703d0012005102320014180026a41086a20042903002206370300200120012903d00122103703800220022010370000200241086a2006370000200141d0026a41086a2003290300370300200141d0026a41106a2000290300370300200141d0026a41186a2009290300370300200120012903603703d002200141e0006a200141b0026a109a022008200135026842208620012802602204ad84100202402001280264450d00200410230b20014102360264200141063a0060200141e0006a108e010c010b2006422088a7210402402006a722032000470d00200141033602d002200120043602d402200141e0006a200141d0026a1099022001418b026a200141e8006a2802003600002001200129036037008302200141ec006a20014187026a290000370000200141c6a4b9da04360061200141023a00602001200129008002370065200141e0006a108b010b200420036a2000470d00200141023602b002200141e0006a41186a22094200370300200141e0006a41106a22004200370300200141e0006a41086a2203420037030020014200370360200141d0016a41086a22044188e0c100ad4280808080f001841003220541086a290000370300200120052900003703d0012005102320032004290300370300200120012903d00122063703800220012006370360200441a4e0c100ad4280808080d000841003220541086a290000370300200120052900003703d0012005102320014180026a41086a20042903002206370300200120012903d00122103703800220022010370000200241086a2006370000200141d0026a41086a2003290300370300200141d0026a41106a2000290300370300200141d0026a41186a2009290300370300200120012903603703d002200141e0006a200141b0026a109a022008200135026842208620012802602204ad84100202402001280264450d00200410230b20014101360264200141063a0060200141e0006a108e010b200141e0006a41186a22054200370300200141e0006a41106a220e4200370300200141e0006a41086a2203420037030020014200370360200141b0026a41086a220441be99c600ad428080808090018422101003220941086a290000370300200120092900003703b0022009102320032004290300370300200120012903b00222063703900220012006370360200441c799c600ad4280808080e000841003220941086a290000370300200120092900003703b00220091023200e20012903b0022206370300200141d0026a41086a22022003290300370300200141d0026a41106a22002006370300200141d0026a41186a220f20042903003703002001200637039002200120012903603703d002200141d8006a200141d0026a4120108f01200128025c210d02402001280258220a4101470d002007428080808080048410050b20054200370300200e42003703002003420037030020014200370360200420101003220941086a290000370300200120092900003703b0022009102320032004290300370300200120012903b0022206370390022001200637036020044188d3c300ad4280808080b001841003220941086a290000370300200120092900003703b0022009102320014190026a41086a20042903002206370300200120012903b002221037039002200e2010370000200e41086a2006370000200220032903003703002000200e290300370300200f2005290300370300200120012903603703d00202400240024002400240024002400240024002400240200141d0026a109b02220441ff01714102460d0020044101710d010b410410212203450d0120034100360200200141e0006a41186a22024200370300200141e0006a41106a22004200370300200141e0006a41086a2205420037030020014200370360200141b0026a41086a220441be99c600ad42808080809001841003220941086a290000370300200120092900003703b0022009102320052004290300370300200120012903b00222063703900220012006370360200441cd99c600ad4280808080b001841003220941086a290000370300200120092900003703b0022009102320014190026a41086a20042903002206370300200120012903b002221037039002200e2010370000200e41086a2006370000200141d0026a41086a2005290300370300200141d0026a41106a2000290300370300200141d0026a41186a2002290300370300200120012903603703d00220014100360268200142013703604101200141e0006a105c200328020021020240024020012802642209200128026822056b4104490d00200128026021040c010b200541046a22042005490d0a200941017422002004200020044b1b22004100480d0a0240024020090d002000102121040c010b200128026020092000102521040b2004450d032001200036026420012004360260200021090b2001200541046a2200360268200420056a20023600002007428080808080048422062000ad4220862004ad84100202402009450d00200410230b20031023410410212203450d0320034100360200200141e0006a41186a22024200370300200141e0006a41106a22004200370300200141e0006a41086a2205420037030020014200370360200141b0026a41086a220441be99c600ad42808080809001841003220941086a290000370300200120092900003703b0022009102320052004290300370300200120012903b00222103703900220012010370360200441f09fc600ad4280808080c001841003220941086a290000370300200120092900003703b0022009102320014190026a41086a20042903002210370300200120012903b002221137039002200e2011370000200e41086a2010370000200141d0026a41086a2005290300370300200141d0026a41106a2000290300370300200141d0026a41186a2002290300370300200120012903603703d00220014100360268200142013703604101200141e0006a105c200328020021020240024020012802642209200128026822056b4104490d00200128026021040c010b200541046a22042005490d0a200941017422002004200020044b1b22004100480d0a0240024020090d002000102121040c010b200128026020092000102521040b2004450d052001200036026420012004360260200021090b2001200541046a2200360268200420056a200236000020062000ad4220862004ad84100202402009450d00200410230b20031023200141e0006a41186a22054200370300200141e0006a41106a22094200370300200141e0006a41086a2203420037030020014200370360200141b0026a41086a220441be99c600ad428080808090018422101003220241086a290000370300200120022900003703b0022002102320032004290300370300200120012903b00222113703900220012011370360200441fc9fc600ad4280808080e000841003220241086a290000370300200120022900003703b0022002102320014190026a41086a220020042903002211370300200120012903b002221237039002200e2012370000200e41086a220f2011370000200141d0026a41086a220b2003290300370300200141d0026a41106a220c2009290300370300200141d0026a41186a22132005290300370300200120012903603703d002200141003602602006200141e0006aad22114280808080c00084100220054200370300200942003703002003420037030020014200370360200420101003220241086a290000370300200120022900003703b0022002102320032004290300370300200120012903b0022210370390022001201037036020044188d3c300ad4280808080b001841003220241086a290000370300200120022900003703b00220021023200020042903002210370300200120012903b002221237039002200e2012370000200f2010370000200b2003290300370300200c200929030037030020132005290300370300200120012903603703d002200141013a0060200620114280808080108410020b200141e0006a41186a22054200370300200141e0006a41106a22144200370300200141e0006a41086a2203420037030020014200370360200141b0026a41086a220441be99c600ad428080808090018422101003220941086a290000370300200120092900003703b0022009102320032004290300370300200120012903b002370360200441cd99c600ad4280808080b001841003220941086a290000370300200120092900003703b00220091023201420012903b0022206370300200141d0026a41086a22022003290300370300200141d0026a41106a22002006370300200141d0026a41186a220f20042903003703002001200637039002200120012903603703d002200141e0006a200141d0026a10950202400240200128026022130d004104211341002115420021110c010b20012902642211422088a721150b20054200370300201442003703002003420037030020014200370360200420101003220941086a290000370300200120092900003703b0022009102320032004290300370300200120012903b00222063703900220012006370360200441f09fc600ad4280808080c001841003220941086a290000370300200120092900003703b0022009102320014190026a41086a20042903002206370300200120012903b002221037039002200e2010370000200e41086a20063700002002200329030037030020002014290300370300200f2005290300370300200120012903603703d002200141e0006a200141d0026a1095020240024020012802602202450d00200120023602800220012902642210422088a7210b0c010b4104210220014104360280024100210b420021100b0240200a0d002015417f6a220420154f0d05200420154b0d05201320044102746a280200210d0b201541002015419c7f6a22042004201541016a4b1b2216490d052016450d07201320164102746a210c200bad21062013210a0340200a2802002100024002400240024002402006a7220f41014b0d0041002104200f0e020201020b41002104200f2103034020042003410176220520046a22092000200220094102746a280200491b2104200320056b220341014b0d000b0b20002002200441027422036a2802002205460d022004200020054b6a21040c010b410021040b2001200436026041a8a0c600412e200141e0006a41d8a0c6001031000b20062004ad580d07200220036a2203200341046a2004417f73200f6a41027410dd041a201042ffffffff0f83200f417f6a220bad422086842110200a41046a220a200c460d082006427f7c210620012802800221020c000b0b410441041030000b200041011030000b410441041030000b200041011030000b4182a0c6004126104a000b41ccbac000102b000b41b8bbc000102b000b201142ffffffff0f8321060240201520166b2204450d0002402016450d002013201320164102746a200441027410dd041a2010422088a7210b0b20062004ad4220868421060b200128028002210241002104024002400240024002400240024002400240024002400240024002400240200b41014b0d00200b0e020201020b200b2103034020042003410176220520046a2209200d200220094102746a280200491b2104200320056b220341014b0d000b0b0240200d200220044102746a2802002203460d002004200d20034b6a21040b200b2004490d010b200b2010a7470d02200b41016a2203200b490d0c200b41017422052003200520034b1b220341ffffffff03712003470d0c2003410274220541004e0d010c0c0b4180bbc000102b000b02400240200b0d002005102121020c010b2002200b4102742005102521020b2002450d0120012002360280022003ad21100b200220044102746a220341046a2003200b20046b41027410dd041a2003200d360200024020064220882211a722032006a7470d00200341016a22042003490d0a2011a722094101742205200420042005491b220441ffffffff03712004470d0a200441027422054100480d0a0240024020030d002005102121130c010b201320094102742005102521130b2013450d022006422088a721032004ad21060b201320034102746a200d3602000240200b41016a220c0d0041e8a0c600102b000b200c200c41017622044d0d02200128028002220520044102746a280200210d0240200c4101710d00200c2004417f6a22044d0d04200520044102746a280200200d6a410176210d0b200141e0006a41186a22024200370300200141e0006a41106a22004200370300200141e0006a41086a2205420037030020014200370360200141b0026a41086a220441be99c600ad42808080809001841003220941086a290000370300200120092900003703b0022009102320052004290300370300200120012903b00222113703900220012011370360200441cd99c600ad4280808080b001841003220941086a290000370300200120092900003703b0022009102320014190026a41086a20042903002211370300200120012903b002221237039002200e2012370000200e41086a2011370000200141d0026a41086a2005290300370300200141d0026a41106a2000290300370300200141d0026a41186a2002290300370300200120012903603703d0022001410036026820014201370360200341016a2215200141e0006a105c0240024020150d002001280268210020012802642102200128026021030c010b4100200128026822046b2105200341027441046a210f200128026421022013210903402009280200210a02400240200220056a4104490d00200128026021030c010b200441046a22032004490d0c200241017422002003200020034b1b22004100480d0c0240024020020d002000102121030c010b200128026020022000102521030b2003450d072001200036026420012003360260200021020b200941046a21092001200441046a2200360268200320046a200a3600002005417c6a210520002104200f417c6a220f0d000b0b2006a721042007428080808080048422062000ad4220862003ad84100202402002450d00200310230b02402004450d00201310230b2001280280022113200141e0006a41186a22094200370300200141e0006a41106a22024200370300200141e0006a41086a2203420037030020014200370360200141b0026a41086a220441be99c600ad42808080809001841003220541086a290000370300200120052900003703b0022005102320032004290300370300200120012903b00222113703900220012011370360200441f09fc600ad4280808080c001841003220541086a290000370300200120052900003703b0022005102320014190026a41086a20042903002211370300200120012903b002221237039002200e2012370000200e41086a2011370000200141d0026a41086a2003290300370300200141d0026a41106a2002290300370300200141d0026a41186a2009290300370300200120012903603703d0022001420137036020014100360268200c200141e0006a105c200b41027441046a21004100200128026822046b21052010a7210b200128026421022013210903402009280200210a02400240200220056a4104490d00200128026021030c010b200441046a22032004490d0b2002410174220f2003200f20034b1b220f4100480d0b0240024020020d00200f102121030c010b20012802602002200f102521030b2003450d072001200f36026420012003360260200f21020b200941046a21092001200441046a220f360268200320046a200a3600002005417c6a2105200f21042000417c6a22000d000b2006200fad4220862003ad84100202402002450d00200310230b0240200b450d00201310230b200141e0006a41186a22094200370300200141e0006a41106a22034200370300200141e0006a41086a2204420037030020014200370360200141b0026a41086a220541be99c600ad42808080809001841003220241086a290000370300200120022900003703b0022002102320042005290300370300200120012903b00222103703900220012010370360200541fc9fc600ad4280808080e000841003220241086a290000370300200120022900003703b0022002102320014190026a41086a220a20052903002210370300200120012903b002221137039002200e2011370000200e41086a2010370000200141d0026a41086a22022004290300370300200141d0026a41106a22002003290300370300200141d0026a41186a220f2009290300370300200120012903603703d0022001200d3602602006200141e0006aad22104280808080c0008410020240201541e500470d0020094200370300200342003703002004420037030020014200370360200541c4fbc400ad4280808080e000841003220b41086a2900003703002001200b2900003703b002200b102320042005290300370300200120012903b002370360200541f9bcc000ad4280808080e000841003220b41086a2900003703002001200b2900003703b002200b1023200a20052903002206370300200120012903b00222113703900220142011370000201441086a20063700002002200429030037030020002003290300370300200f2009290300370300200120012903603703d002200141d0006a200141d0026a4120108f010b20094200370300200342003703002004420037030020014200370360200141f0016a41086a220541c6acc500ad4280808080f0008422111003220941086a290000370300200120092900003703f0012009102320042005290300370300200120012903f00122063703b0022001200637036020054184adc500ad4280808080f0018422121003220941086a290000370300200120092900003703f00120091023200320012903f00122063703002002200429030037030020002006370300200f2005290300370300200120063703b002200120012903603703d002200141c8006a200141d0026a412041014100410010b8010240024020012802484101470d00200141d0026a210a0c010b200141e0006a41186a22024200370300200141e0006a41106a22094200370300200141e0006a41086a2205420037030020014200370360200141f0016a41086a220441be99c600ad42808080809001841003220041086a290000370300200120002900003703f0012000102320052004290300370300200120012903f001370360200441f0cec400ad428080808030841003220041086a290000370300200120002900003703f00120001023200920012903f0012206370300200141d0026a41086a220f2005290300370300200141d0026a41106a220a2006370300200141d0026a41186a220b2004290300370300200120063703b002200120012903603703d002200141386a200141d0026a109c02200129034021062001280238210c20024200370300200942003703002005420037030020014200370360200420111003220041086a290000370300200120002900003703f0012000102320052004290300370300200120012903f00122113703b00220012011370360200420121003220041086a290000370300200120002900003703f00120001023200141b0026a41086a20042903002211370300200120012903f00122123703b00220032012370000200341086a2011370000200f2005290300370300200a2009290300370300200b2002290300370300200120012903603703d002200120064200200c1b37036020074280808080800484201042808080808001841002200141d0026a210a0b200141e0006a41186a22094200370300200141e0006a41106a22034200370300200141e0006a41086a2204420037030020014200370360200141f0016a41086a220541a6a3c500ad4280808080a0018422111003220241086a290000370300200120022900003703f0012002102320042005290300370300200120012903f001370360200541b0a3c500ad4280808080e000841003220241086a290000370300200120022900003703f00120021023200320012903f0012206370300200141d0026a41086a22022004290300370300200141d0026a41106a22002006370300200141d0026a41186a220f2005290300370300200120063703b002200120012903603703d002200aad42808080808004842206100520094200370300200342003703002004420037030020014200370360200520111003220a41086a2900003703002001200a2900003703f001200a102320042005290300370300200120012903f00137036020054184a9c500ad4280808080c001841003220a41086a2900003703002001200a2900003703f001200a102320092005290300221137030020022004290300370300200020012903f0012212370300200f2011370300200120123703b002200120012903603703d002200610052009420037030020034200370300200442003703002001420037036020014180026a41086a220541d5fbc400ad42808080808001841003220a41086a2900003703002001200a29000037038002200a102320042005290300370300200120012903800222063703b00220012006370360200541e8bbc300ad42808080809002841003220a41086a2900003703002001200a29000037038002200a1023200320012903800222063703002002200429030037030020002006370300200f2005290300370300200120063703b002200120012903603703d002200141286a200141d0026a109c02200129033021112001280228210f200141b0026a41186a4200370300200141b0026a41106a220a4200370300200141b0026a41086a22024200370300200142003703b002200541c4fbc400ad4280808080e000841003220041086a2900003703002001200029000037038002200010232002200529030037030020012001290380023703b002200541a0cec000ad4280808080b002841003220041086a290000370300200120002900003703800220001023200a2001290380022206370300200420022903003703002003200637030020092005290300370300200120063703d001200120012903b002370360200141206a200141e0006a4120108f01200141106a2001280224410020012802201b22044180e59af70020044180e59af7004b22051b4180e59af700200420051b6b2205ad220642002006420010e104200642a8c30180211242ffffffffffffffffff00428080808080808080807f20051b2001290310220620012903182006423f87521b42808090bbbad6adf00d7f210820114200200f1b210602400240200441ffe49af7004b0d0042ffffffffffffffffff00428080808080808080807f2006201220087d22127d22114200531b20112006427f5522042012427f554720042011427f5547711b22064280ec94a37c20064280ec94a37c551b21060c010b42ffffffffffffffffff00428080808080808080807f2006201220087c22127c22114200531b20112006427f5522042012427f554620042011427f5547711b21060b200141e0006a41186a22024200370300200141e0006a41106a22054200370300200141e0006a41086a220442003703002001420037036020014180026a41086a220941d5fbc400ad42808080808001841003220041086a29000037030020012000290000370380022000102320042009290300370300200120012903800222113703b00220012011370360200941e8bbc300ad42808080809002841003220041086a290000370300200120002900003703800220001023200141b0026a41086a20092903002211370300200120012903800222123703b00220032012370000200341086a2011370000200141d0026a41086a22002004290300370300200141d0026a41106a220f2005290300370300200141d0026a41186a220a2002290300370300200120012903603703d0022001200637036020074280808080800484221120104280808080800184100220024200370300200542003703002004420037030020014200370360200141f0016a41086a220341be99c600ad42808080809001841003220941086a290000370300200120092900003703f0012009102320042003290300370300200120012903f001370360200341b39fc600ad42808080809001841003220941086a290000370300200120092900003703f00120091023200520012903f001220637030020002004290300370300200f2006370300200a2003290300370300200120063703b002200120012903603703d002200141d0026a109b02220441ff01714102460d06201110052004410171450d06200141e0006a41186a4200370300200141e0006a41106a22094200370300200141e0006a41086a2203420037030020014200370360200141f0016a41086a220441cafbc400ad4280808080c000841003220541086a290000370300200120052900003703f0012005102320032004290300370300200120012903f00122063703d0012001200637036020044188d3c300ad4280808080b001841003220541086a290000370300200120052900003703f00120051023200920012903f0012206370300200141d0026a41086a2003290300370300200141d0026a41106a2006370300200141d0026a41186a20042903003703002001200637038002200120012903603703d002200141e0006a200141d0026a109d02024020012d006022044102460d0020074280808080800484100520014190026a41086a200141e9006a29000037030020014190026a41106a200141f1006a29000037030020014190026a41186a200141f9006a29000037030020012001290061370390020240200441037122044103460d0020040e03010001010b200141b0026a41186a20014190026a41186a290300370300200141b0026a41106a20014190026a41106a290300370300200141b0026a41086a20014190026a41086a29030037030020012001290390023703b002200141e0006a41186a22024200370300200141e0006a41106a22004200370300200141e0006a41086a2203420037030020014200370360200141f0016a41086a220441cafbc400ad4280808080c000841003220541086a290000370300200120052900003703f0012005102320032004290300370300200120012903f00122063703d0012001200637036020044184d2c300ad4280808080c001841003220541086a290000370300200120052900003703f0012005102320014180026a41086a20042903002206370300200120012903f00122113703800220092011370000200941086a2006370000200141d0026a41086a2003290300370300200141d0026a41106a2000290300370300200141d0026a41186a2002290300370300200120012903603703d002200141086a200141d0026a4120108f01200141e0006a200128020c410020012802081b2205109e02200141d0026a200128026022032001280268109f0220012902d402420020012802d00222041b210602402001280264450d00200310230b2004410120041b21030240024020064220882211a72204418002490d00412010212204450d0a200420012903b002370000200441186a200141b0026a41186a290300370000200441106a200141b0026a41106a290300370000200441086a200141b0026a41086a290300370000200141d0026a200541016a2200109e0220012802d002210520013502d8022111200141e0006a2004410110a00220114220862005ad84200135026842208620012802602202ad84100202402001280264450d00200210230b024020012802d402450d00200510230b20041023200141e0006a41186a220f4200370300200141e0006a41106a220a4200370300200141e0006a41086a2205420037030020014200370360200141f0016a41086a220441cafbc400ad4280808080c000841003220241086a290000370300200120022900003703f0012002102320052004290300370300200120012903f00122113703d0012001201137036020044184d2c300ad4280808080c001841003220241086a290000370300200120022900003703f0012002102320014180026a41086a20042903002211370300200120012903f00122123703800220092012370000200941086a2011370000200141d0026a41086a2005290300370300200141d0026a41106a200a290300370300200141d0026a41186a200f290300370300200120012903603703d002200120003602602007428080808080048420104280808080c0008410020c010b200141e0006a41186a2202200141b0026a41186a290300370300200141e0006a41106a2200200141b0026a41106a290300370300200141e0006a41086a220f200141b0026a41086a290300370300200120012903b002370360024020042006a7470d00200441016a22092004490d0c2011a7220b410174220a20092009200a491b220941ffffff3f712009470d0c2009410574220a4100480d0c0240024020040d00200a102121030c010b2003200b410574200a102521030b2003450d0b2006422088a721042009ad21060b200320044105746a22092001290360370000200941186a2002290300370000200941106a2000290300370000200941086a200f290300370000200141d0026a2005109e0220012802d002210520013502d8022110200141e0006a2003200441016a10a00220104220862005ad84200135026842208620012802602204ad84100202402001280264450d00200410230b024020012802d402450d00200510230b200642ffffffff0f8321060b2006a7450d00200310230b200141f0026a24000f0b200541041030000b200541041030000b4180a1c6002004200c102d000b4180a1c6002004200c102d000b200041011030000b200f41011030000b41d0cdc400102b000b412041011030000b200a41011030000b102a000bde0d03047f017e027f230041106b2202240020024100360208200242013703000240024002400240024002400240024002400240024002400240024002402001280200220341044b0d000240024002400240024020030e050001020304000b410110212203450d05200242818080801037020420022003360200200341013a0000200128020421042001410c6a28020022032002105c02402003450d002004200341286c6a21050340200420021071200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d15200741017422032008200320084b1b22034100480d150240024020070d002003102121070c010b200228020020072003102521070b2007450d092002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141106a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d13200441017422032008200320084b1b22034100480d130240024020040d002003102121040c010b200228020020042003102521040b2004450d082002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c040b410110212203450d07200242818080801037020420022003360200200341023a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d12200441017422052008200520084b1b22084100480d120240024020040d002008102121040c010b200228020020042008102521040b2004450d0920022008360204200220043602000b2002200341046a360208200420036a200736000020012802082104200141106a28020022032002105c02402003450d002004200341286c6a21050340200420021071200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d14200741017422032008200320084b1b22034100480d140240024020070d002003102121070c010b200228020020072003102521070b2007450d0c2002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141146a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d12200441017422032008200320084b1b22034100480d120240024020040d002003102121040c010b200228020020042003102521040b2004450d0b2002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c030b410110212203450d0a200242818080801037020420022003360200200341033a0000200141086a29030021060240024020022802042207200228020822036b4108490d00200341086a2104200228020021070c010b200341086a22042003490d11200741017422082004200820044b1b22084100480d110240024020070d002008102121070c010b200228020020072008102521070b2007450d0c20022008360204200220073602000b20022004360208200720036a20063700000c020b410110212203450d0b200242818080801037020420022003360200200341043a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d10200441017422012008200120084b1b22084100480d100240024020040d002008102121040c010b200228020020042008102521040b2004450d0d20022008360204200220043602000b2002200341046a360208200420036a20073600000c010b410110212203450d0c200242818080801037020420022003360200200341053a0000200128020421080240024020022802042207200228020822036b4104490d00200341046a2104200228020021070c010b200341046a22042003490d0f200741017422012004200120044b1b22014100480d0f0240024020070d002001102121070c010b200228020020072001102521070b2007450d0e20022001360204200220073602000b20022004360208200720036a20083600000b20002002290300370200200041086a200241086a280200360200200241106a24000f0b410141011030000b200341011030000b200341011030000b410141011030000b200841011030000b200341011030000b200341011030000b410141011030000b200841011030000b410141011030000b200841011030000b410141011030000b200141011030000b102a000bd60201037f0240024002400240024002400240024002400240024002400240024020012802000e0400010203000b41012102410110212201450d05200141003a0000410121030c040b410110212202450d05200241013a00002001280204210320024101410510252202450d062002200336000120012802082104410a210320024105410a10252201450d07200120043600050c020b41012102410110212201450d07200141023a0000410121030c020b410110212202450d07200241033a00002001280204210320024101410510252202450d082002200336000120012802082104410a210320024105410a10252201450d09200120043600050b410921020b2000200236020820002003360204200020013602000f0b410141011030000b410141011030000b410541011030000b410a41011030000b410141011030000b410141011030000b410541011030000b410a41011030000b950201047f230041d0006b220124002001412036020420012000360200200141086a2000ad4280808080800484100410900102400240200128020822020d00410221000c010b200128020c210302400240200141106a280200450d0020022d0000220441014b0d0041002100024020040e020200020b410121000c010b20014100360220200142013703182001410c36022c200120013602282001200141186a360234200141cc006a41013602002001420137023c20014198c2c3003602382001200141286a360248200141346a41b8a3c500200141386a102e1a200135022042208620013502188410080240200128021c450d00200128021810230b410221000b2003450d00200210230b200141d0006a240020000b990204017f017e017f017e230041d0006b220224002002412036020420022001360200200241086a2001ad4280808080800484100410900102400240200228020822010d00420021030c010b200228020c210402400240200241086a41086a2802004108490d0020012900002105420121030c010b20024100360220200242013703182002410c36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c20024198c2c3003602382002200241286a360248200241346a41b8a3c500200241386a102e1a200235022042208620023502188410080240200228021c450d00200228021810230b420021030b2004450d00200110230b2000200537030820002003370300200241d0006a24000bd80402067f047e230041f0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100410900102400240200228021022030d00200041023a00000c010b2002280214210402400240200241186a2802002205450d0020032d0000220641014b0d00410021010240024020060e020100010b41002101200241003a0068200341016a21072005417f6a21060340024020062001470d00200141ff0171450d03200241003a00680c030b200241c8006a20016a200720016a2d00003a00002002200141016a22053a00682005210120054120470d000b200241206a41186a200241c8006a41186a290300370300200241206a41106a200241c8006a41106a290300370300200241206a41086a200241c8006a41086a29030037030020022002290348370320410121010b200241c8006a41186a200241206a41186a2903002208370300200241c8006a41106a200241206a41106a2903002209370300200241c8006a41086a200241206a41086a290300220a37030020022002290320220b370348200041196a2008370000200041116a2009370000200041096a200a3700002000200b3700010c010b20024100360228200242013703202002410c3602442002200241086a3602402002200241206a36026c200241dc006a41013602002002420137024c20024198c2c3003602482002200241c0006a360258200241ec006a41b8a3c500200241c8006a102e1a2002350228422086200235022084100802402002280224450d00200228022010230b410221010b200020013a00002004450d00200310230b200241f0006a24000bd20301067f230041f0006b22022400200241d0006a41086a220341cafbc400ad4280808080c000841003220441086a2900003703002002200429000037035020041023200241086a41086a2205200329030037030020022002290350370308200341d8d2c300ad42808080809002841003220441086a2900003703002002200429000037035020041023200241186a41086a22062003290300370300200220022903503703182002200136024c200241d0006a41186a2201200241cc006aad4280808080c000841001220441186a290000370300200241d0006a41106a2207200441106a2900003703002003200441086a2900003703002002200429000037035020041023200241286a41186a22042001290300370300200241286a41106a22012007290300370300200241286a41086a2207200329030037030020022002290350370328024041c000102122030d0041c00041011030000b200320022903083700002003200229031837001020032002290328370020200042c0808080800837020420002003360200200341086a2005290300370000200341186a2006290300370000200341286a2007290300370000200341306a2001290300370000200341386a2004290300370000200241f0006a24000bef06010c7f23004190016b220324002003200236021420032001360210200341186a2002ad4220862001ad84100410900102400240200328021822040d00200041003602000c010b200328021c21052003200341206a28020036023c20032004360238200341086a200341386a106e0240024002400240024020032802080d0002400240200328023c22014160712202417f4c0d00200328020c210602400240200141057622070d00410121080c010b200210212208450d020b02402006450d004100210903402001210a200341003a0088012009220b41016a2109410021010240024002400340200a2001460d01200341e8006a20016a200328023822022d00003a00002003200241016a3602382003200141016a22023a0088012002210120024120470d000b200341c8006a41186a220c200341e8006a41186a290300370300200341c8006a41106a220d200341e8006a41106a290300370300200341c8006a41086a220e200341e8006a41086a290300370300200320032903683703482007200b470d020240200b41017422012009200120094b1b220741ffffff3f712007470d002007410574220141004e0d020b102a000b2003410036023c0240200141ff0171450d00200341003a0088010b200341003602282007450d08200810230c080b02400240200b0d002001102121080c010b2008200b4105742001102521080b2008450d060b200a20026b21012008200b4105746a220b2003290348370000200b41186a200c290300370000200b41106a200d290300370000200b41086a200e29030037000020092006470d000b200341306a20063602002003200736022c200320083602282003200a20026b36023c0c060b200341306a20063602002003200736022c2003200836022820080d050c040b102f000b200241011030000b200341003602280c010b200141011030000b20034100360250200342013703482003410c36022c2003200341106a3602282003200341c8006a360244200341fc006a41013602002003420137026c20034198c2c3003602682003200341286a360278200341c4006a41b8a3c500200341e8006a102e1a2003350250422086200335024884100820004100360200200328024c450d01200328024810230c010b20002003290328370200200041086a200341286a41086a2802003602000b2005450d00200410230b20034190016a24000ba72701057f230041106b22032400200341003602082003420137030020022003105c02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002450d00200120024105746a2104034020012d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0320032007360204200320063602000b2003200241016a360208200620026a20053a0000200141016a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0420032007360204200320063602000b2003200241016a360208200620026a20053a0000200141026a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0520032007360204200320063602000b2003200241016a360208200620026a20053a0000200141036a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0620032007360204200320063602000b2003200241016a360208200620026a20053a0000200141046a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0720032007360204200320063602000b2003200241016a360208200620026a20053a0000200141056a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0820032007360204200320063602000b2003200241016a360208200620026a20053a0000200141066a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0920032007360204200320063602000b2003200241016a360208200620026a20053a0000200141076a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0a20032007360204200320063602000b2003200241016a360208200620026a20053a0000200141086a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0b20032007360204200320063602000b2003200241016a360208200620026a20053a0000200141096a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0c20032007360204200320063602000b2003200241016a360208200620026a20053a00002001410a6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0d20032007360204200320063602000b2003200241016a360208200620026a20053a00002001410b6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0e20032007360204200320063602000b2003200241016a360208200620026a20053a00002001410c6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d0f20032007360204200320063602000b2003200241016a360208200620026a20053a00002001410d6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1020032007360204200320063602000b2003200241016a360208200620026a20053a00002001410e6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1120032007360204200320063602000b2003200241016a360208200620026a20053a00002001410f6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1220032007360204200320063602000b2003200241016a360208200620026a20053a0000200141106a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1320032007360204200320063602000b2003200241016a360208200620026a20053a0000200141116a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1420032007360204200320063602000b2003200241016a360208200620026a20053a0000200141126a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1520032007360204200320063602000b2003200241016a360208200620026a20053a0000200141136a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1620032007360204200320063602000b2003200241016a360208200620026a20053a0000200141146a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1720032007360204200320063602000b2003200241016a360208200620026a20053a0000200141156a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1820032007360204200320063602000b2003200241016a360208200620026a20053a0000200141166a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1920032007360204200320063602000b2003200241016a360208200620026a20053a0000200141176a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1a20032007360204200320063602000b2003200241016a360208200620026a20053a0000200141186a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1b20032007360204200320063602000b2003200241016a360208200620026a20053a0000200141196a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1c20032007360204200320063602000b2003200241016a360208200620026a20053a00002001411a6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1d20032007360204200320063602000b2003200241016a360208200620026a20053a00002001411b6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1e20032007360204200320063602000b2003200241016a360208200620026a20053a00002001411c6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d1f20032007360204200320063602000b2003200241016a360208200620026a20053a00002001411d6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d2020032007360204200320063602000b2003200241016a360208200620026a20053a00002001411e6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d2120032007360204200320063602000b2003200241016a360208200620026a20053a00002001411f6a2d0000210502400240200328020420032802082202460d00200328020021060c010b200241016a22062002490d23200241017422072006200720064b1b22074100480d230240024020020d002007102121060c010b200328020020022007102521060b2006450d2220032007360204200320063602000b2003200241016a360208200620026a20053a0000200141206a22012004470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b102a000b130020004103360204200041b8e0c1003602000b3400200041e3e0c40036020420004100360200200041146a4101360200200041106a4190e7c100360200200041086a42043702000b4001017f230041206b22022400200241186a4200370300200241106a4200370300200241086a4200370300200242003703002000200210a402200241206a24000bf60301027f20012d00002102024002400240024002400240410110212203450d00200320023a000020012d0001210220034101410210252203450d01200320023a000120012d0002210220034102410410252203450d02200320023a0002200320012d00033a000320012d0004210220034104410810252203450d03200320023a0004200320012d00053a0005200320012d00063a0006200320012d00073a000720012d0008210220034108411010252203450d04200320023a0008200320012d00093a0009200320012d000a3a000a200320012d000b3a000b200320012d000c3a000c200320012d000d3a000d200320012d000e3a000e200320012d000f3a000f20012d0010210220034110412010252203450d05200320023a0010200320012d00113a0011200320012d00123a0012200320012d00133a0013200320012d00143a0014200320012d00153a0015200320012d00163a0016200320012d00173a0017200320012d00183a0018200320012d00193a0019200320012d001a3a001a200320012d001b3a001b200320012d001c3a001c200320012d001d3a001d200320012d001e3a001e200320012d001f3a001f200042a08080808004370204200020033602000f0b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000bfc1804097f017e097f017e230041a0016b220224004104210302400240024002400240024002400240024020012802004117460d00410021040c010b41002104200141046a22052d00004105470d00200141c8006a280200210620024190016a41086a22044191fdc400ad42808080809001841003220341086a290000370300200220032900003703900120031023200241306a41086a22072004290300370300200220022903900137033020044198e9c100ad4280808080d000841003220341086a290000370300200220032900003703900120031023200241c0006a41086a22032004290300370300200220022903900137034020022006360210200241f0006a41186a2206200241106aad4280808080c000841001220441186a290000370300200241f0006a41106a2208200441106a290000370300200241f0006a41086a2209200441086a2900003703002002200429000037037020041023200241d0006a41186a220a2006290300370300200241d0006a41106a22062008290300370300200241d0006a41086a22082009290300370300200220022903703703500240024002400240024041c00010212204450d00200420022903303700002004200229034037001020042002290350370020200441086a2007290300370000200441186a2003290300370000200441286a2008290300370000200441306a2006290300370000200441386a200a290300370000200441c00010a60221032004102302400240200341ff017122044102460d0020044101710d010b200041800e3b0001200041013a0000200041036a41013a00000c0d0b200241f0006a41186a4200370300200241f0006a41106a22074200370300200241f0006a41086a220342003703002002420037037020024190016a41086a22044191fdc400ad42808080809001841003220641086a290000370300200220062900003703900120061023200320042903003703002002200229039001370370200441a9e0c100ad4280808080f001841003220641086a2900003703002002200629000037039001200610232007200229039001220b370300200241d0006a41086a2003290300370300200241d0006a41106a200b370300200241d0006a41186a20042903003703002002200b37031020022002290370370350200241c0006a200241d0006a10910202400240024002402002280240220a0d004100210c2002410036020c0c010b2002200241c0006a41086a280200220c36020c2002280244210d02402002290244220b422088a72204450d002004417f6a210e0c030b0240200ba7450d004100210c0c020b200d0d010b410c1021220a450d034101210d0b200a200c410c6c6a22044100360208200442043702002002200228020c220e41016a220c36020c200c200e490d030b200241d0006a41186a4200370300200241d0006a41106a220f4200370300200241d0006a41086a220342003703002002420037035020024190016a41086a22044191fdc400ad42808080809001841003220641086a290000370300200220062900003703900120061023200320042903003703002002200229039001220b3703302002200b3703502004419de9c100ad4280808080b001841003220641086a290000370300200220062900003703900120061023200f200229039001220b370300200241f0006a41086a2003290300370300200241f0006a41106a200b370300200241f0006a41186a20042903003703002002200b370340200220022903503703702002200241f0006a4120108f0102400240200a200e410c6c6a221041086a221128020022042002280204410020022802001b4f0d00201028020021090240200441014b0d00024020040e020300030b20012802482108410021030c060b2001280248210841002103034020032004410176220620036a220720082009200741246c6a280200491b2103200420066b220441014b0d000c060b0b200041800c3b0001200041013a0000200041036a41003a00000c0c0b20012802482108410021060c040b41c00041011030000b410c41041030000b41a4dfc100200e4100102d000b024020082009200341246c6a2802002204460d002003200820044b6a21060c010b200041800e3b0001200041013a0000200041036a41003a00000c070b200241f0006a20081080020240200228027022120d00200041800e3b0001200041013a0000200041036a41013a00000c070b20022802742113200241f0006a41186a2207200241f0006a41086a22033502004220862012ad841001220441186a290000370300200241f0006a41106a2208200441106a2900003703002003200441086a2900003703002002200429000037037020041023200241106a41186a2007290300370300200241106a41106a2008290300370300200241106a41086a2003290300370300200220022903703703100240200241106a200541216a2214460d00200241106a2014412010de04450d0020004180063b0001200041013a0000200041036a41003a00002013450d07201210230c070b2007200541196a2900003703002008200541116a2900003703002003200541096a29000037030020022005290001370370201128020022042006490d012001280248210302402004200a200e410c6c6a41046a2201280200470d00200441016a22072004490d05200441017422082007200820074b1b2208ad42247e220b422088a70d05200ba722094100480d050240024020040d002009102121070c010b2010280200200441246c2009102521070b2007450d0320012008360200201020073602000b2010280200200641246c6a220141246a2001200420066b41246c10dd041a20012003360200200120022903703702042001410c6a200241f0006a41086a2206290300370200200141146a200241f0006a41106a22072903003702002001411c6a200241f0006a41186a22082903003702002011200441016a360200200228020c210c200241d0006a41186a22094200370300200241d0006a41106a22054200370300200241d0006a41086a220442003703002002420037035020024190016a41086a22014191fdc400ad42808080809001841003220341086a290000370300200220032900003703900120031023200420012903003703002002200229039001220b3703302002200b370350200141a9e0c100ad4280808080f001841003220341086a290000370300200220032900003703900120031023200241c0006a41086a2001290300220b37030020022002290390012215370340200f2015370000200f41086a200b370000200620042903003703002007200529030037030020082009290300370300200220022903503703702002410036025820024201370350200c200241d0006a105c0240200c450d00200a200c410c6c6a2105200a210903402009280200210420092802082201200241d0006a105c02402001450d002004200141246c6a21080340200428020021060240024020022802542203200228025822016b4104490d00200228025021030c010b200141046a22072001490d09200341017422012007200120074b1b22014100480d090240024020030d002001102121030c010b200228025020032001102521030b2003450d082002200136025420022003360250200228025821010b2002200141046a360258200320016a2006360000200441046a200241d0006a1071200441246a22042008470d000b0b2009410c6a22092005470d000b0b20022802542101200241f0006aad4280808080800484200235025842208620022802502204ad84100202402001450d00200410230b0240200c450d00200c410c6c2104200a210103400240200141046a280200450d00200128020010230b2001410c6a2101200441746a22040d000b0b0240200d450d00200a10230b410c10212203450d0520024100360278200242013703702002200241f0006a36029001201420024190016a106b200241d0006a41086a2002280278220136020020022002290370220b370350200341086a20013602002003200b37020002402013450d00201210230b410121040b200041003a0000200041306a41013a00002000412c6a2004360200200041286a2004360200200041246a2003360200200041206a4100360200200041186a4204370300200041106a427f370300200041086a4200370300200041316a2002280070360000200041346a200241f3006a2800003600000c060b4180bbc000102b000b200941041030000b200141011030000b102a000b410c41041030000b0240200c450d00200c410c6c2104200a210103400240200141046a280200450d00200128020010230b2001410c6a2101200441746a22040d000b0b200d450d00200a10230b200241a0016a24000b940201037f230041d0006b220224002002200136020420022000360200200241086a2001ad4220862000ad84100410900102400240200228020822010d00410221000c010b200228020c210302400240200241106a280200450d0020012d0000220441014b0d0041002100024020040e020200020b410121000c010b20024100360220200242013703182002410c36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c20024198c2c3003602382002200241286a360248200241346a41b8a3c500200241386a102e1a200235022042208620023502188410080240200228021c450d00200228021810230b410221000b2003450d00200110230b200241d0006a240020000b130020004101360204200041a8e9c1003602000b340020004188e0c10036020420004100360200200041146a4107360200200041106a41a8eac100360200200041086a420f3702000b3001017f02404108102122020d00410841011030000b20004288808080800137020420002002360200200242003700000b2201017f230041106b220224002002410036020020002002109a02200241106a24000be60301077f230041f0006b22022400200241d0006a41086a22034188e0c100ad4280808080f001841003220441086a2900003703002002200429000037035020041023200241086a41086a2205200329030037030020022002290350370308200341a8f1c100ad4280808080c001841003220441086a2900003703002002200429000037035020041023200241186a41086a220620032903003703002002200229035037031820022000370348200241d0006a41186a2207200241c8006aad42808080808001841001220441186a290000370300200241d0006a41106a2208200441106a2900003703002003200441086a2900003703002002200429000037035020041023200241286a41186a22042007290300370300200241286a41106a22072008290300370300200241286a41086a2208200329030037030020022002290350370328024041c000102122030d0041c00041011030000b200320022903083700002003200229031837001020032002290328370020200341086a2005290300370000200341186a2006290300370000200341286a2008290300370000200341306a2007290300370000200341386a2004290300370000200220013602502003ad4280808080800884200241d0006aad4280808080c00084100220031023200241f0006a24000bba1305067f017e027f037e057f23004180016b22042400200441c0006a41186a22054200370300200441c0006a41106a22064200370300200441c0006a41086a2207420037030020044200370340200441f0006a41086a22084188e0c100ad4280808080f001841003220941086a29000037030020042009290000370370200910232007200829030037030020042004290370220a3703602004200a37034020084197e0c100ad4280808080d001841003220941086a290000370300200420092900003703702009102320062004290370220a370300200441206a41086a22092007290300370300200441206a41106a220b200a370300200441206a41186a220c20082903003703002004200a37036020042004290340370320200441186a200441206a412041014100410010b80102400240024020042802184101460d0020054200370300200642003703002007420037030020044200370340200841c4fbc400ad4280808080e000841003220541086a29000037030020042005290000370370200510232007200829030037030020042004290370370340200841f9bcc000ad4280808080e000841003220541086a290000370300200420052900003703702005102320062004290370220a37030020092007290300370300200b200a370300200c20082903003703002004200a37036020042004290340370320200441106a200441206a4120108f012004280214410020042802101b2109024020024101460d00200441206a210c0c020b200441c0006a41186a22054200370300200441c0006a41106a220b4200370300200441c0006a41086a2207420037030020044200370340200441f0006a41086a22084188e0c100ad4280808080f00184220d1003220c41086a2900003703002004200c290000370370200c10232007200829030037030020042004290370220a3703602004200a370340200841a0f0c100ad4280808080a00184220e1003220c41086a2900003703002004200c290000370370200c1023200441e0006a41086a220c2008290300220a37030020042004290370220f3703602006200f370000200641086a2210200a370000200441206a41086a22112007290300370300200441206a41106a2212200b290300370300200441206a41186a2213200529030037030020042004290340370320200441086a200441206a4120108f01024002402004280208450d00200428020c20094b0d010b20054200370300200b420037030020074200370300200442003703402008200d1003221441086a29000037030020042014290000370370201410232007200829030037030020042004290370220a3703602004200a3703402008200e1003221441086a2900003703002004201429000037037020141023200c2008290300220a37030020042004290370220f3703602006200f3700002010200a370000201120072903003703002012200b29030037030020132005290300370300200420042903403703202004200920014101746a360240200441206aad4280808080800484200441c0006aad4280808080c000841002200441206a210c0c020b200041046a280200450d02200028020010230c020b200041046a280200450d01200028020010230c010b20002802082107200028020421102000280200210b200441c0006a41186a22114200370300200441c0006a41106a22124200370300200441c0006a41086a2200420037030020044200370340200441f0006a41086a22084188e0c100ad4280808080f001841003220541086a29000037030020042005290000370370200510232000200829030037030020042004290370220a3703602004200a37034020084197e0c100ad4280808080d001841003220541086a2900003703002004200529000037037020051023200441e0006a41086a2008290300220a37030020042004290370220f3703602006200f370000200641086a200a370000200441206a41086a2000290300370300200441206a41106a2012290300370300200441206a41186a20112903003703002004200429034037032020044100360248200442013703400240024002400240024002400240410410212208450d002004410436024420042004280248220641046a36024820042008360240200820066a20093600000240024020042802442206200428024822086b4104490d00200428024021060c010b200841046a22002008490d07200641017422082000200820004b1b22084100480d070240024020060d002008102121060c010b200428024020062008102521060b2006450d022004200836024420042006360240200428024821080b2004200841046a360248200620086a20013600002007200441c0006a105c02402007450d00200b200741286c6a2109200b210703402007200441c0006a1071200741206a290300210a0240024020042802442206200428024822086b4108490d00200428024021060c010b200841086a22002008490d09200641017422082000200820004b1b22084100480d090240024020060d002008102121060c010b200428024020062008102521060b2006450d052004200836024420042006360240200428024821080b2004200841086a360248200620086a200a3700002009200741286a2207470d000b0b20042802442107200428024821080240024020024101460d000240024020072008460d00200428024021070c010b200841016a22072008490d09200841017422062007200620074b1b22064100480d090240024020080d002006102121070c010b200428024020082006102521070b2007450d062004200636024420042007360240200428024821080b2004200841016a360248200720086a41003a00000c010b0240024020072008460d00200428024021070c010b200841016a22072008490d08200841017422062007200620074b1b22064100480d080240024020080d002006102121070c010b200428024020082006102521070b2007450d062004200636024420042007360240200428024821080b2004200841016a360248200720086a41013a00000240024020042802442207200428024822086b4104490d00200428024021070c010b200841046a22062008490d08200741017422082006200820064b1b22084100480d080240024020070d002008102121070c010b200428024020072008102521070b2007450d072004200836024420042007360240200428024821080b2004200841046a360248200720086a20033600000b20042802442108200cad4280808080800484200435024842208620042802402207ad84100202402008450d00200710230b2010450d07200b10230c070b410441011030000b200841011030000b200841011030000b200641011030000b200641011030000b200841011030000b102a000b20044180016a24000b02000b290020004101360204200041086a200128020420012802006b41c0016e2201360200200020013602000bf40101047f230041d0006b21020240200128020022032001280204470d00200041003602000f0b2001200341c0016a3602002002200341c2006a29000037012a2002200341ca006a290000370132200241106a220120022903303703002002200341d2006a29000037013a200241186a220420022903383703002002200341da006a2800003601422002200341de006a2f00003b0146200241206a220520022903403703002002200341c0006a2f00003b01282002200229032837030820002003360200200020022903083700042000410c6a2001290300370000200041146a20042903003700002000411c6a20052903003700000b8406020e7f047e230041b0016b22032400024002402001280200220420012802042205460d002001200441c0016a22063602002003200429004237018a012003200429004a37019201200341e8006a41086a22072003290390013703002003200429005237019a01200341e8006a41106a22082003290398013703002003200428005a3601a201200320042f005e3b01a601200341e8006a41186a220920032903a001370300200320042f00403b0188012003200329038801370368200341c8006a41186a220a2009290300370300200341c8006a41106a220b2008290300370300200341c8006a41086a220c200729030037030020032003290368370348200341286a41186a220d200a290300370300200341286a41106a220e200b290300370300200341286a41086a220f200c29030037030020032003290348370328200541c07e6a211002400340200341086a41186a200d2903002211370300200341086a41106a200e2903002212370300200341086a41086a200f290300221337030020032003290328221437030820034188016a41186a201137030020034188016a41106a201237030020034188016a41086a201337030020032014370388012002450d0120102004460d022001200641c0016a22053602002003200629004237018a012003200629004a3701920120072003290390013703002003200629005237019a0120082003290398013703002003200628005a3601a201200320062f005e3b01a601200920032903a001370300200320062f00403b0188012003200329038801370368200a2009290300370300200b2008290300370300200c200729030037030020032003290368370348200d200a290300370300200e200b290300370300200f200c29030037030020032003290348370328200441c0016a21042002417f6a2102200521060c000b0b2000200436020020002003290388013702042000410c6a20034190016a290300370200200041146a20034198016a2903003702002000411c6a200341a0016a2903003702000c010b200041003602000b200341b0016a24000bc60d01057f024002402000280200220141184b0d0002400240024002400240024002400240024002400240024002400240024020010e1900101010100102100310040510060708090a10100b100c0d0e000b0240200041086a280200220141064b0d00024002400240024020010e0714140014010203140b200041106a280200450d132000410c6a28020010230f0b200041106a280200450d122000410c6a28020010230f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010230b0240200141106a280200450d002001410c6a28020010230b200141186a2101200241686a22020d000b0b200041106a280200450d11200028020c10230f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b200041106a280200450d10200028020c10230f0b200041106a280200450d0f2000410c6a28020010230f0b02402000410c6a2802002201450d0020002802042203200141f0006c6a2104034002402003410c6a2802002202450d0020032802042101200241246c210203400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012002415c6a22020d000b0b200341f0006a21010240200341086a280200450d00200328020410230b2001210320012004470d000b0b200041086a280200450d0e200028020410230f0b0240200041086a2d00002201410f4b0d00410120017441bfbf03710d0e024020014106470d00200041106a280200450d0f2000410c6a28020010230f0b200041106a280200450d0e2000410c6a28020010230f0b200041146a280200450d0d200041106a28020010230f0b200041086a280200450d0c200028020410230f0b200041086a280200450d0b200028020410230f0b02402000410c6a280200450d00200041086a28020010230b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b200041186a280200450d0a200028021410230f0b200041086a2d0000417f6a220141074b0d09024002400240024020010e08000d0d0d0d010203000b2000410c6a220128020010b102200128020010230f0b2000410c6a220128020010b102200128020010230f0b2000410c6a220128020010b102200128020010230f0b2000410c6a220128020010b102200128020010230f0b20002d0004417f6a220141024b0d0802400240024020010e03000102000b2000410c6a280200450d0a200041086a28020010230f0b200041086a220128020010b102200128020010230f0b2000410c6a220128020010b102200128020010230f0b20002d0004417f6a220141024b0d0702400240024020010e03000102000b2000410c6a280200450d09200041086a28020010230f0b200041086a220128020010b102200128020010230f0b2000410c6a220128020010b102200128020010230f0b200041086a2802004101470d06200041106a280200450d062000410c6a28020010230f0b20002d00044104490d052000410c6a280200450d05200041086a28020010230f0b02402000410c6a2802002202450d0020002802042101200241d0016c210203402001106c200141d0016a2101200241b07e6a22020d000b0b200041086a280200450d04200028020410230f0b200041086a2d000022014105490d03024020014105470d00200041386a280200450d04200041346a28020010230f0b200041146a280200450d03200041106a28020010230f0b20002d0004417f6a220141034b0d020240024020010e0400040401000b0240200041106a280200450d002000410c6a28020010230b2000411c6a280200450d03200041186a28020010230c030b02402000410c6a280200450d00200041086a28020010230b200041186a280200450d02200041146a28020010230f0b02402000280204220141024b0d00024020010e03030003030b200041086a220128020010b102200128020010230f0b2000412c6a220128020010b102200128020010230f0b02402000280204220141034b0d00024020010e0402000202020b2000410c6a280200450d01200041086a28020010230f0b200041306a280200450d002000412c6a28020010230f0b0b9e1f06057f017e047f017e037f017e230041b0016b22042400200441d0006a41086a22054191fdc400ad42808080809001841003220641086a2900003703002004200629000037035020061023200441186a41086a220720052903003703002004200429035037031820054198e9c100ad4280808080d000841003220641086a2900003703002004200629000037035020061023200441e0006a41086a22062005290300370300200420042903503703602004200036029001200441f0006a41186a220820044190016aad22094280808080c000841001220541186a290000370300200441f0006a41106a220a200541106a290000370300200441f0006a41086a220b200541086a2900003703002004200529000037037020051023200441286a41186a220c2008290300370300200441286a41106a2208200a290300370300200441286a41086a220a200b29030037030020042004290370370328024002400240024002400240024002400240024002400240024002400240024002400240024041c00010212205450d00200520042903183700002005200429036037001020052004290328370020200541086a2007290300370000200541186a2006290300370000200541286a200a290300370000200541306a2008290300370000200541386a200c290300370000200441106a200541c00041014100410010b801200428021021062005102341c7fbc100210d20064101460d1120010d0820044190016a41186a420037030020044190016a41106a2208420037030020044190016a41086a220642003703002004420037039001200441d0006a41086a22054191fdc400ad42808080809001841003220741086a290000370300200420072900003703502007102320062005290300370300200420042903503703900120054182fdc400ad4280808080a001841003220741086a290000370300200420072900003703502007102320082004290350220e370300200441f0006a41086a2006290300370300200441f0006a41106a200e370300200441f0006a41186a20052903003703002004200e3703282004200429039001370370200441e0006a200441f0006a4120108b0202402004280260220f0d004100210a2004410036024c4104210f410021054100210b0c040b20042004280264220b36024c2004290264220ea72110410021050240200e422088a7220a41014b0d00200a0e020302030b200a2106034020052006410176220720056a2208200f20084102746a28020020004b1b2105200620076b220641014b0d000c020b0b41c00041011030000b41c7fbc100210d200f20054102746a28020022062000460d05200520062000496a2205200a4b0d020b200a2010470d03200b200a470d030b200b41016a2206200b490d0c200b41017422072006200720064b1b220641ffffffff03712006470d0c2006410274220741004e0d010c0c0b4180bbc000102b000b02400240200b0d0020071021210f0c010b200f200b41027420071025210f0b200f450d032004200636024c0b200f20054102746a220641046a2006200a20056b41027410dd041a20062000360200200a41016a210a4100210d200428024c21100b200441286a41186a4200370300200441286a41106a22084200370300200441286a41086a2206420037030020044200370328200441d0006a41086a22054191fdc400ad42808080809001841003220741086a29000037030020042007290000370350200710232006200529030037030020042004290350220e3703182004200e37032820054182fdc400ad4280808080a001841003220741086a290000370300200420072900003703502007102320082004290350220e37030020044190016a41086a200629030037030020044190016a41106a200e37030020044190016a41186a20052903003703002004200e370360200420042903283703900102400240200f0d002009428080808080048410050c010b2004410036027820044201370370200a200441f0006a105c02400240200a0d002004280278210b2004280274210a200428027021060c010b200a410274210c4100200428027822056b21072004280274210a200f210803402008280200211102400240200a20076a4104490d00200428027021060c010b200541046a22062005490d0c200a410174220b2006200b20064b1b220b4100480d0c02400240200a0d00200b102121060c010b2004280270200a200b102521060b2006450d062004200b36027420042006360270200b210a0b200841046a21082004200541046a220b360278200620056a20113600002007417c6a2107200b2105200c417c6a220c0d000b0b20094280808080800484200bad4220862006ad8410020240200a450d00200610230b2010450d00200f10230b200d0d090b2003280208210a2003280204210b200328020021072002280208210c2002280204211120022802002108200441d0006a41086a22054182fdc400ad4280808080a001841003220641086a2900003703002004200629000037035020061023200441e0006a41086a2202200529030037030020042004290350370360200541e8bdc100ad4280808080c000841003220641086a2900003703002004200629000037035020061023200441286a41086a220620052903003703002004200429035037032820042000360250200441f0006a41186a2203200441d0006aad220e4280808080c000841001220541186a290000370300200441f0006a41106a220f200541106a290000370300200441f0006a41086a220d200541086a290000370300200420052900003703702005102320044190016a41186a2210200329030037030020044190016a41106a2203200f29030037030020044190016a41086a220f200d290300370300200420042903703703900141c00010212205450d0220052004290360370000200520042903283700102005200429039001370020200541086a2002290300370000200541186a2006290300370000200541286a200f290300370000200541306a2003290300370000200541386a2010290300370000200441c0003602940120042005360290012008200c20044190016a10c5012005102302402011450d00200810230b200441d0006a41086a22054182fdc400ad4280808080a001841003220641086a2900003703002004200629000037035020061023200441e0006a41086a2208200529030037030020042004290350370360200541ecbdc100ad4280808080d000841003220641086a2900003703002004200629000037035020061023200441286a41086a220620052903003703002004200429035037032820042000360250200441f0006a41186a220c200e4280808080c000841001220541186a290000370300200441f0006a41106a2211200541106a290000370300200441f0006a41086a2202200541086a290000370300200420052900003703702005102320044190016a41186a2203200c29030037030020044190016a41106a220c201129030037030020044190016a41086a22112002290300370300200420042903703703900141c00010212205450d0320052004290360370000200520042903283700102005200429039001370020200541086a2008290300370000200541186a2006290300370000200541286a2011290300370000200541306a200c290300370000200541386a2003290300370000200441c0003602940120042005360290012007200a20044190016a10c501200510230240200b450d00200710230b20044190016a41186a2211420037030020044190016a41106a220c420037030020044190016a41086a220742003703002004420037039001200441d0006a41086a220541c4fbc400ad4280808080e000841003220641086a2900003703002004200629000037035020061023200720052903003703002004200429035037039001200541f9bcc000ad4280808080e000841003220641086a2900003703002004200629000037035020061023200c20042903502212370300200441f0006a41086a22082007290300370300200441f0006a41106a220a2012370300200441f0006a41186a220b2005290300370300200420123703282004200429039001370370200441086a200441f0006a4120108f01200428020c210f2004280208210d20054182fdc400ad4280808080a001841003220641086a2900003703002004200629000037035020061023200441e0006a41086a2202200529030037030020042004290350370360200541f1bdc100ad4280808080a001841003220641086a2900003703002004200629000037035020061023200441286a41086a220320052903003703002004200429035037032820042000360250200b200e4280808080c000841001220641186a290000370300200a200641106a2900003703002008200641086a29000037030020042006290000370370200610232011200b290300370300200c200a29030037030020072008290300370300200420042903703703900141c00010212206450d0420062004290360370000200620042903283700102006200429039001370020200641086a2002290300370000200641186a2003290300370000200641286a2007290300370000200641306a200c290300370000200641386a201129030037000020044100200f4100200d1b2207417f6a220c200c20074b1b360290012006ad428080808080088420094280808080c00084220910022006102320054191fdc400ad42808080809001841003220641086a2900003703002004200629000037035020061023200441186a41086a20052903003703002004200429035037031820054198e9c100ad4280808080d000841003220641086a290000370300200420062900003703502006102320022005290300370300200420042903503703602004200036029001200b20091001220541186a290000370300200a200541106a2900003703002008200541086a2900003703002004200529000037037020051023200441286a41186a200b290300370300200441286a41106a200a290300370300200320082903003703002004200429037037032841c00010212205450d05200520042903183700002005200429036037001020052004290328370020200541086a200441186a41086a290300370000200541186a200441e0006a41086a290300370000200541286a200441286a41086a290300370000200541306a200441386a290300370000200541386a200441286a41186a290300370000410110212206450d06200620013a00002005ad42808080808008842006ad42808080801084100220061023200510234100210d0c090b200741041030000b200b41011030000b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000b410141011030000b102a000b0240200341046a280200450d00200328020010230b200241046a280200450d00200228020010230b200441b0016a2400200d0bfe1c08057f017e047f017e027f017e017f017e230041a0016b22012400200141c0006a41086a22024191fdc400ad42808080809001841003220341086a2900003703002001200329000037034020031023200141106a41086a220420022903003703002001200129034037031020024198e9c100ad4280808080d000841003220341086a2900003703002001200329000037034020031023200141d0006a41086a22032002290300370300200120012903403703502001200036028001200141e0006a41186a220520014180016aad22064280808080c000841001220241186a290000370300200141e0006a41106a2207200241106a290000370300200141e0006a41086a2208200241086a2900003703002001200229000037036020021023200141206a41186a22092005290300370300200141206a41106a22052007290300370300200141206a41086a220720082903003703002001200129036037032002400240024002400240024002400240024041c00010212202450d00200220012903103700002002200129035037001020022001290320370020200241086a2004290300370000200241186a2003290300370000200241286a2007290300370000200241306a2005290300370000200241386a200929030037000002400240024002400240200241c00010a60241ff017122034102460d002002ad42808080808008841005200210234101210a20034101710d0420014180016a41186a420037030020014180016a41106a2205420037030020014180016a41086a220342003703002001420037038001200141c0006a41086a22024191fdc400ad42808080809001841003220441086a290000370300200120042900003703402004102320032002290300370300200120012903403703800120024182fdc400ad4280808080a001841003220441086a290000370300200120042900003703402004102320052001290340220b370300200141e0006a41086a2003290300370300200141e0006a41106a200b370300200141e0006a41186a20022903003703002001200b370320200120012903800137036020014180016a200141e0006a4120108b022001280280012202410420021b210c41dffbc100210d200129028401420020021b220e422088a7220741014b0d014100210220070e020302030b2002102341dffbc100210d0c0c0b4100210220072103034020022003410176220420026a2205200c20054102746a28020020004b1b2102200320046b220341014b0d000b0b200c20024102746a2802002000470d00200220074f0d03200c20024102746a2203280200210d2003200341046a2002417f7320076a41027410dd041a200e4280808080707c210e4100210a0b200141206a41186a4200370300200141206a41106a22054200370300200141206a41086a2203420037030020014200370320200141c0006a41086a22024191fdc400ad42808080809001841003220441086a29000037030020012004290000370340200410232003200229030037030020012001290340220b3703102001200b37032020024182fdc400ad4280808080a001841003220441086a290000370300200120042900003703402004102320052001290340220b37030020014180016a41086a200329030037030020014180016a41106a200b37030020014180016a41186a20022903003703002001200b370350200120012903203703800102400240200c0d002006428080808080048410050c010b2001410036026820014201370360200e422088a72202200141e0006a105c0240024020020d002001280268210820012802642107200128026021030c010b200241027421094100200128026822026b210420012802642107200c210503402005280200210f02400240200720046a4104490d00200128026021030c010b200241046a22032002490d08200741017422082003200820034b1b22084100480d080240024020070d002008102121030c010b200128026020072008102521030b2003450d072001200836026420012003360260200821070b200541046a21052001200241046a2208360268200320026a200f3600002004417c6a2104200821022009417c6a22090d000b0b200642808080808004842008ad4220862003ad84100202402007450d00200310230b200ea7450d00200c10230b200a0d090b200141c0006a41086a22034182fdc400ad4280808080a00184220b1003220241086a2900003703002001200229000037034020021023200141d0006a41086a2208200329030037030020012001290340370350200341e8bdc100ad4280808080c000841003220241086a2900003703002001200229000037034020021023200141206a41086a220920032903003703002001200129034037032020012000360240200141e0006a41186a2204200141c0006aad220e4280808080c0008422101001220241186a290000370300200141e0006a41106a2205200241106a290000370300200141e0006a41086a2207200241086a290000370300200120022900003703602002102320014180016a41186a220f200429030037030020014180016a41106a220c200529030037030020014180016a41086a220d2007290300370300200120012903603703800141c00010212202450d0420022001290350370000200220012903203700102002200129038001370020200241086a2008290300370000200241186a2009290300370000200241286a200d290300370000200241306a200c290300370000200241386a200f2903003700002002ad42808080808008841005200210232003200b1003220241086a29000037030020012002290000370340200210232008200329030037030020012001290340370350200341ecbdc100ad4280808080d000841003220241086a2900003703002001200229000037034020021023200920032903003703002001200129034037032020012000360240200420101001220241186a2900003703002005200241106a2900003703002007200241086a2900003703002001200229000037036020021023200f2004290300370300200c2005290300370300200d2007290300370300200120012903603703800141c00010212202450d0520022001290350370000200220012903203700102002200129038001370020200241086a200141d0006a41086a2204290300370000200241186a200141206a41086a2205290300370000200241286a20014180016a41086a2207290300370000200241306a20014180016a41106a2208290300370000200241386a20014180016a41186a22092903003700002002ad4280808080800884100520021023200141c0006a41086a22024182fdc400ad4280808080a001841003220341086a29000037030020012003290000370340200310232004200229030037030020012001290340370350200241f1bdc100ad4280808080a001841003220341086a2900003703002001200329000037034020031023200520022903003703002001200129034037032020012000360240200141e0006a41186a2203200e4280808080c000841001220241186a290000370300200141e0006a41106a220f200241106a290000370300200141e0006a41086a220c200241086a2900003703002001200229000037036020021023200920032903003703002008200f2903003703002007200c290300370300200120012903603703800141c00010212203450d0620032001290350370000200320012903203700102003200129038001370020200341086a2004290300370000200341186a2005290300370000200341286a2007290300370000200341306a2008290300370000200341386a2009290300370000200141086a200341c000108f010240024020012802084101470d00200128020c21022003ad428080808080088410052003102320014180016a41186a420037030020014180016a41106a2207420037030020014180016a41086a220442003703002001420037038001200141c0006a41086a220341c4fbc400ad4280808080e000841003220541086a2900003703002001200529000037034020051023200420032903003703002001200129034037038001200341f9bcc000ad4280808080e000841003220541086a290000370300200120052900003703402005102320072001290340220b370300200141e0006a41086a2004290300370300200141e0006a41106a200b370300200141e0006a41186a20032903003703002001200b37032020012001290380013703602001200141e0006a4120108f0120022001280204410020012802001b22034f0d01034020012000360284012001200241016a22023602800120014180016a10fc0120032002470d000c020b0b200310230b200141c0006a41086a22024191fdc400ad42808080809001841003220341086a2900003703002001200329000037034020031023200141106a41086a220420022903003703002001200129034037031020024198e9c100ad4280808080d000841003220341086a2900003703002001200329000037034020031023200141d0006a41086a22032002290300370300200120012903403703502001200036028001200141e0006a41186a220520064280808080c000841001220241186a290000370300200141e0006a41106a2200200241106a290000370300200141e0006a41086a2207200241086a2900003703002001200229000037036020021023200141206a41186a22082005290300370300200141206a41106a22052000290300370300200141206a41086a220020072903003703002001200129036037032041c00010212202450d07200220012903103700002002200129035037001020022001290320370020200241086a2004290300370000200241186a2003290300370000200241286a2000290300370000200241306a2005290300370000200241386a20082903003700002002ad42808080808008841005200210234100210d0c080b41c00041011030000b41b8bbc000102b000b200841011030000b102a000b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000b200141a0016a2400200d0bb81101197f41002104024002400240200141014b0d0020010e020201020b20012105034020042005410176220620046a2207200020074102746a28020020024b1b2104200520066b220541014b0d000b0b4100210502400240200020044102746a28020022062002470d00410021080c010b200420062002496a2104410121080b41012109024002400240200141014b0d0020010e020201020b4100210520012106034020052006410176220720056a220a2000200a4102746a28020020034b1b2105200620076b220641014b0d000b0b0240200020054102746a28020022062003470d00410021090c010b200520062003496a21050b024002400240024020080d002009450d04200420014f0d0120042105200321020c030b2009450d010c030b41f4dcc10020042001102d000b20052001490d0041a0dcc10020052001102d000b200020054102746a2002360200024020014115490d0002402001410176220b41ffffffff0371200b470d00200b4102742204417f4c0d0002400240024020040d004104210c410421030c010b20041021220c450d01200c21030b2000417c6a210d200041746a210e4100210f4100211041042111410021082001211203402012210a41002112410121070240200a417f6a2213450d00024002400240024002400240200020134102746a280200200a410274221420006a41786a2802002205490d00200a417e6a2109200e20146a210641002112410021040340024020092004470d00200a21070c080b200441016a21042005200628020022074f21022006417c6a21062007210520020d000b200441016a21072004417f73200a6a21040c010b200e20146a21062013210402400340024020044101470d00410021040c020b2004417f6a21042005200628020022074921022006417c6a21062007210520020d000b0b200a2004490d01200a20014b0d03200a20046b22074101762202450d00200020044102746a2105200d20146a21060340200528020021092005200628020036020020062009360200200541046a21052006417c6a21062002417f6a22020d000b0b024020040d00200421120c050b0240200741094d0d00200421120c050b200a20014b0d01200020044102746a21140340200a2004417f6a2212490d040240200a20126b22074102490d00200020044102746a22062802002205200020124102746a220928020022154f0d0020092005360200024020074103490d0020132102201421052009280208220920154f0d00034020052009360200200541046a210620042002417f6a2202460d01200541086a210920062105200928020022092015490d000b0b200620153602000b2012450d052014417c6a2114201221042007410a4f0d050c000b0b2004200a103e000b200a2004417f6a2212490d010b200a20011036000b2012200a103e000b02400240024020082010470d0002400240201041016a22042010490d00201041017422052004200520044b1b220441ffffffff01712004470d002004410374220541004e0d010b102a000b0240024020100d002005102121110c010b201120104103742005102521110b2011450d0120042110200f21080b201120084103746a2204200736020420042012360200200f41016a2208210f20084102490d0102400340024002400240024020112008417f6a220f4103746a2204280200450d00200841037420116a220741746a2802002206200428020422054d0d000240200841024b0d002008210f410221080c080b20112008417d6a22134103746a2802042204200520066a4d0d010240200841034b0d002008210f410321080c080b200741646a280200200420066a4d0d012008210f0c070b20084103490d012004280204210520112008417d6a22134103746a28020421040b20042005490d010b2008417e6a21130b0240024002400240024002402008201341016a22164b2217450d00200820134b2218450d01201120134103746a2219280204221a20192802006a2204201120164103746a221b280200221c490d02200420014b0d032000201c4102746a2209201b280204221541027422056a21072004410274210a2004201c6b220220156b220420154f0d04200c20072004410274220510dc041a200320056a21060240024020154101480d00200441014e0d010b20072105200321040c060b200d200a6a210a200721050340200a2005417c6a22042006417c6a2207200728020020042802004922021b2802003602002006200720021b2106024020092004200520021b2205490d00200321040c070b200a417c6a210a2003210420032006490d000c060b0b4198bfc10020162008102d000b4198bfc10020132008102d000b201c2004103e000b200420011036000b200c2009200510dc041a200320056a21060240024020154101480d00200220154a0d010b20092105200321040c010b2000200a6a21142003210420092105034020052007280200220a20042802002202200a200249220a1b3602002004200441046a200a1b2104200541046a2105200741046a2007200a1b220720144f0d01200620044b0d000b0b20052004200620046b417c7110dc041a02402018450d002019201c360200201941046a201a20156a3602002017450d02201b201b41086a20082016417f736a41037410dd041a200f2108200f41014d0d040c010b0b41a8bfc10020132008102d000b41b8bbc000102b000b200541041030000b20120d000b02402010450d00201110230b200b450d03200c10230f0b200441041030000b102f000b20014102490d002001417f6a2104200020014102746a21074100210a034002400240024020042205417f6a220420014b0d00200120046b22064102490d02200020054102746a22052802002202200020044102746a220328020022094f0d022003200236020020064103490d01200a2106200721022003280208220320094f0d01034020022205417c6a20033602002006417f6a2206450d02200541046a2202280200220320094f0d020c000b0b20042001103e000b200520093602000b200a41016a210a2007417c6a210720040d000b0b0b340020004191fdc40036020420004100360200200041146a4109360200200041106a41ecfbc100360200200041086a42093702000b3101017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200241e8073600000bcd860104077f017e137f077e230022032104200341a0026b416071220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e080001020304050809000b20034194016a41013602002003420137028401200341d09dc600360280012003410436028402200341849ec60036028002200320034180026a3602900120034180016a41f08ac2001038000b41182105200141186a2802002106200141146a28020021072001410c6a2802002108200141086a280200210920022d000120022d000072450d0802402006450d00200710230b4186b0c00021024111210541012107410021062008450d20200910230c200b4101210620022d000120022d0000720d1e200141046a28020010b3022102410a2105410121070c1f0b4101210620022d000120022d0000720d1d200141046a2802002108200341306a4200370300200341286a22094200370300200341186a41086a2205420037030020034200370318200341f0016a41086a22024191fdc400ad42808080809001841003220741086a290000370300200320072900003703f0012007102320052002290300370300200320032903f001220a3703382003200a3703182002419de9c100ad4280808080b001841003220741086a290000370300200320072900003703f00120071023200920032903f001220a3703002003200a370348200320032903183703800220032005290300370388022003200a370390022003200229030037039802200320083602800120034180026aad428080808080048420034180016aad4280808080c0008410020c020b200141186a280200210b200141146a2802002107200141106a280200210c2001410c6a280200210d200141086a2802002108200141046a280200210e2002411a6a290100210a200241196a2d00002106200241186a2d00002109200241166a2f0100210f200241156a2d00002110200241146a2d00002111200241126a2f01002112200241116a2d00002113200241106a2d000021142002410e6a2f010021152002410d6a2d000021162002410c6a2d000021172002410a6a2f01002118200241096a2d00002119200241046a2d0000211a41022105200241026a2f0100211b0240024020022d00000d0020022d00014101470d00200241056a2d00002105200241066a2f0100211c200241086a2d000021024100211d0c010b4101211d410021024100211c0b2003200a37039802200320063a009702200320093a0096022003200f3b019402200320103a009302200320113a009202200320123b019002200320133a008f02200320143a008e02200320153b018c02200320163a008b02200320173a008a02200320183b018802200320193a0087022003201a3a0082022003201b3b0180022003201c41ffff0371410874200241187472200541ff0171722206360083020240201d450d00410f210541aab0c0002102024002400240024020060e050001020320000b2003280087022102200328008b0221050c1f0b410e210541aabac60021020c1e0b411321054197b0c00021020c1d0b411121054186b0c00021020c1c0b200341d8006a41186a200329039802370300200341d8006a41106a2211200329039002370300200341d8006a41086a2003290388023703002003200329038002370358200341086a200341d8006a4280a0e5b9c29101420010f101024020032802082202450d00200328020c21050c1c0b20034180016a41186a2209420037030020034180016a41106a220f420037030020034180016a41086a220542003703002003420037038001200341f0016a41086a22024191fdc400ad4280808080900184220a1003220641086a290000370300200320062900003703f0012006102320052002290300370300200320032903f001221e3703182003201e370380012002418addc100ad4280808080a00184221f1003220641086a290000370300200320062900003703f00120061023200f20032903f001221e37030020034180026a41086a2212200529030037030020034180026a41106a2213201e37030020034180026a41186a221420022903003703002003201e370318200320032903800137038002200320034180026a4120108f01200328020421102003280200211520094200370300200f42003703002005420037030020034200370380012002200a1003220641086a290000370300200320062900003703f0012006102320052002290300370300200320032903f001221e3703182003201e370380012002201f1003220641086a290000370300200320062900003703f0012006102320092002290300221e37030020122005290300370300201320032903f001221f3703002014201e3703002003201f370318200320032903800137038002410121062003201041e80720151b221041016a3602800120034180026aad428080808080048420034180016aad4280808080c0008410022003200d3602880220032008360284022003200e360280022003200b3602880120032007360284012003200c360280012010410120034180026a20034180016a10b2021a2014200341d8006a41186a290300370300201320112903003703002012200341d8006a41086a29030037030020032003290358370380022002200a1003220741086a290000370300200320072900003703f00120071023200341386a41086a22082002290300370300200320032903f001370338200241a884c200ad4280808080f000841003220741086a290000370300200320072900003703f00120071023200341c8006a41086a22072002290300370300200320032903f001370348200320103602f0012009200341f0016aad4280808080c000841001220241186a290000370300200f200241106a2900003703002005200241086a290000370300200320022900003703800120021023200341186a41186a22112009290300370300200341186a41106a200f290300370300200341186a41086a22092005290300370300200320032903800137031841c00010212202450d0620022003290338370000200241086a200829030037000020022003290348370010200241186a200729030037000020022003290318370020200241286a2009290300370000200241306a200341186a41106a290300370000200241386a2011290300370000200341c00036028401200320023602800120034180026a20034180016a10f5012002102320052010360200410021072003410036028401200341103a00800120034180016a108e01410021020c1d0b20022d00000d014101210620022d00014101470d010b41002102410121070c1b0b4197b0c0002102411321050c170b20022d00004103470d152003200241046a2802002206360278200341f0016a41086a22024191fdc400ad42808080809001841003220541086a290000370300200320052900003703f00120051023200341186a41086a22072002290300370300200320032903f00137031820024198e9c100ad4280808080d000841003220541086a290000370300200320052900003703f00120051023200341d8006a41086a22052002290300370300200320032903f001370358200320063602f00120034180016a41186a2206200341f0016aad4280808080c000841001220241186a29000037030020034180016a41106a2208200241106a29000037030020034180016a41086a2209200241086a29000037030020032002290000370380012002102320034180026a41186a220f200629030037030020034180026a41106a2206200829030037030020034180026a41086a2208200929030037030020032003290380013703800241c00010212202450d0320022003290318370000200220032903583700102002200329038002370020200241086a2007290300370000200241186a2005290300370000200241286a2008290300370000200241306a2006290300370000200241386a200f290300370000200241c00010a60221062002102341808bc2002102410a2105200641ff017122064102460d16024020064101710d00418a8bc2002102411521050c170b200328027810b30222020d162003200341f8006a36027c20034180016a41186a420037030020034180016a41106a2207420037030020034180016a41086a220242003703002003420037038001200341f0016a41086a22064191fdc400ad4280808080900184221f1003220541086a290000370300200320052900003703f0012005102320022006290300370300200320032903f001370380012006419adfc100ad4280808080a0018422201003220541086a290000370300200320052900003703f00120051023200720032903f001220a37030020034180026a41086a200229030037030020034180026a41106a200a37030020034180026a41186a20062903003703002003200a37031820032003290380013703800220034180016a20034180026a109102200329028401420020032802800122021b221e422088a7210902402002410420021b2208450d002009450d002009410c6c21052008210203402002200341fc006a10752002410c6a2102200541746a22050d000b0b20032008360280012003201e37028401200341186a41186a4200370300200341186a41106a220f4200370300200341186a41086a22024200370300200342003703182006201f1003220541086a290000370300200320052900003703f0012005102320022006290300370300200320032903f001220a3703382003200a370318200620201003220541086a290000370300200320052900003703f00120051023200f20032903f001220a3703002003200a370348200320032903183703800220032002290300370388022003200a3703900220032006290300370398022003412036025c200320034180026a36025820034180016a200341d8006a107302402008450d00201ea7210602402009450d002009410c6c21052008210203400240200241046a280200450d00200228020010230b2002410c6a2102200541746a22050d000b0b2006450d00200810230b20034180016a41186a2208420037030020034180016a41106a2209420037030020034180016a41086a220542003703002003420037038001200341f0016a41086a22024191fdc400ad42808080809001841003220641086a290000370300200320062900003703f0012006102320052002290300370300200320032903f00137038001200241a9e0c100ad4280808080f001841003220641086a290000370300200320062900003703f00120061023200341186a41086a2002290300220a370300200320032903f001221e3703182007201e370000200741086a200a37000020034180026a41086a200529030037030020034180026a41106a200929030037030020034180026a41186a200829030037030020032003290380013703800220034180016a20034180026a109102200329028401420020032802800122021b220a422088a7210802402002410420021b2206450d002008450d002008410c6c21052006210203402002200341fc006a10752002410c6a2102200541746a22050d000b0b20032006360280012003200a370284010240024020060d00200341306a4200370300200341286a22084200370300200341186a41086a2205420037030020034200370318200341f0016a41086a22024191fdc400ad42808080809001841003220641086a290000370300200320062900003703f0012006102320052002290300370300200320032903f001220a3703382003200a370318200241a9e0c100ad4280808080f001841003220641086a290000370300200320062900003703f00120061023200820032903f001220a3703002003200a370348200320032903183703800220032005290300370388022003200a37039002200320022903003703980220034180026aad428080808080048410050c010b200aa7210f200341306a4200370300200341286a22104200370300200341186a41086a2205420037030020034200370318200341f0016a41086a22024191fdc400ad42808080809001841003220941086a290000370300200320092900003703f0012009102320052002290300370300200320032903f001220a3703382003200a370318200241a9e0c100ad4280808080f001841003220941086a290000370300200320092900003703f00120091023201020032903f001220a3703002003200a370348200320032903183703800220032005290300370388022003200a3703900220032002290300370398022003412036025c200320034180026a36025820034180016a200341d8006a107302402008450d002008410c6c21052006210203400240200241046a280200450d00200228020010230b2002410c6a2102200541746a22050d000b0b200f450d00200610230b20034180016a41186a2206420037030020034180016a41106a220f420037030020034180016a41086a220242003703002003420037038001200341f0016a41086a22084191fdc400ad4280808080900184220a1003220541086a290000370300200320052900003703f0012005102320022008290300370300200320032903f0013703800120084184ddc100ad4280808080e00084221e1003220541086a290000370300200320052900003703f00120051023200341186a41086a22092008290300221f370300200320032903f001222037031820072020370000200741086a201f37000020034180026a41086a200229030037030020034180026a41106a200f29030037030020034180026a41186a200629030037030020032003290380013703800220034180016a20034180026a10fe01200329028401420020032802800122021b221f422088a7220f412c6c21112002410420021b21100240200f450d00200328027c210620112105201021020340024020022802002006280200470d00200241246a22072802004102460d00200741003602000b2002412c6a2102200541546a22050d000b0b200341186a41186a4200370300200341186a41106a2205420037030020094200370300200342003703182008200a1003220241086a290000370300200320022900003703f0012002102320092008290300370300200320032903f001220a3703382003200a3703182008201e1003220241086a290000370300200320022900003703f00120021023200520032903f001220a3703002003200a370348200320032903183703800220032009290300370388022003200a37039002200320082903003703980220034100360288012003420137038001200f20034180016a105c0240200f450d00201020116a21092010210503402005280200210702400240200328028401220620032802880122026b4104490d0020032802800121060c010b200241046a22082002490d17200641017422022008200220084b1b22024100480d170240024020060d002002102121060c010b20032802800120062002102521060b2006450d072003200236028401200320063602800120032802880121020b2003200241046a36028801200620026a2007360000200541046a20034180016a10d3012005412c6a22052009470d000b0b200328028401210220034180026aad220a42808080808004842003350288014220862003280280012205ad84100202402002450d00200510230b0240201fa7450d00201010230b20032802782106200341f0016a41086a22024191fdc400ad42808080809001841003220541086a290000370300200320052900003703f00120051023200341386a41086a22072002290300370300200320032903f001370338200241a884c200ad4280808080f000841003220541086a290000370300200320052900003703f00120051023200341c8006a41086a22052002290300370300200320032903f001370348200320063602800220034180016a41186a2206200a4280808080c000841001220241186a29000037030020034180016a41106a2208200241106a29000037030020034180016a41086a2209200241086a290000370300200320022900003703800120021023200341186a41186a220f2006290300370300200341186a41106a22062008290300370300200341186a41086a22082009290300370300200320032903800137031841c00010212202450d0520022003290338370000200241086a200729030037000020022003290348370010200241186a200529030037000020022003290318370020200241286a2008290300370000200241306a2006290300370000200241386a200f29030037000020034180016a200241c000108a010240024020032d0080014101470d002002ad4280808080800884100520034180026a41186a20034199016a290000220a37030020034180026a41106a20034191016a290000221e37030020034180026a41086a20034189016a290000221f370300200341d8006a41186a200a370300200341d8006a41106a201e370300200341d8006a41086a201f3703002003200329008101222037038002200341186a41186a200a370300200341186a41106a201e370300200341186a41086a201f37030020032020370358200320203703180c010b20034180026a41186a20034199016a290000220a37030020034180026a41106a20034191016a290000221e37030020034180026a41086a20034189016a290000221f370300200341d8006a41186a4200370300200341d8006a41106a4200370300200341d8006a41086a42003703002003200329008101222037038002200341186a41186a200a370300200341186a41106a201e370300200341186a41086a201f37030020034200370358200320203703180b20021023200341d8006a4280a0e5b9c29101420010de0120034188016a2003280278360200410021022003410036028401200341103a00800120034180016a108e0141012106410121070c190b2003200141046a280200220536027820022d00004103470d142003200241046a28020036027c200341f0016a41086a22024191fdc400ad42808080809001841003220641086a290000370300200320062900003703f00120061023200341386a41086a22072002290300370300200320032903f001370338200241cc83c200ad4280808080b001841003220641086a290000370300200320062900003703f00120061023200341c8006a41086a22062002290300370300200320032903f0013703482003200536025820034180016a41186a2205200341d8006aad220a4280808080c000841001220241186a29000037030020034180016a41106a2208200241106a29000037030020034180016a41086a2209200241086a29000037030020032002290000370380012002102320032005290300370398022003200829030037039002200320092903003703880220032003290380013703800241c00010212202450d0520022003290338370000200241086a200729030037000020022003290348370010200241186a20062903003700002002200329038002370020200241286a200329038802370000200241306a200329039002370000200241386a200329039802370000200341106a200241c000108f01200328021421082003280210210520021023200328027c210602400240024020054101460d00200328027821070c010b2003280278210720082006460d010b200341f0016a41086a22024191fdc400ad42808080809001841003220541086a290000370300200320052900003703f00120051023200341386a41086a22082002290300370300200320032903f001370338200241cc83c200ad4280808080b001841003220541086a290000370300200320052900003703f00120051023200341c8006a41086a22052002290300370300200320032903f0013703482003200636025820034180016a41186a2206200a4280808080c000841001220241186a29000037030020034180016a41106a2209200241106a29000037030020034180016a41086a220f200241086a290000370300200320022900003703800120021023200320062903003703980220032009290300370390022003200f2903003703880220032003290380013703800241c00010212202450d0720022003290338370000200241086a200829030037000020022003290348370010200241186a20052903003700002002200329038002370020200241286a200329038802370000200241306a200329039002370000200241386a20032903980237000020032007360280012002ad428080808080088420034180016aad4280808080c00084100220021023410021020c160b41a5f3c300210241222105200610b8020d15200710b8020d1520032802782106200341f0016a41086a22054191fdc400ad4280808080900184221e1003220241086a290000370300200320022900003703f00120021023200341386a41086a22082005290300370300200320032903f001370338200541cc83c200ad4280808080b001841003220241086a290000370300200320022900003703f00120021023200341c8006a41086a22092005290300370300200320032903f0013703482003200636025820034180016a41186a2207200a4280808080c000841001220241186a29000037030020034180016a41106a220f200241106a29000037030020034180016a41086a2206200241086a29000037030020032002290000370380012002102320032007290300370398022003200f29030037039002200320062903003703880220032003290380013703800241c00010212202450d0720022003290338370000200241086a200829030037000020022003290348370010200241186a20092903003700002002200329038002370020200241286a200329038802370000200241306a200329039002370000200241386a2003290398023700002002ad42808080808008841005200210232003200341f8006a36025c2003200341fc006a36025820074200370300200f42003703002006420037030020034200370380012005201e1003220241086a290000370300200320022900003703f0012002102320062005290300370300200320032903f001370380012005419adfc100ad4280808080a001841003220241086a290000370300200320022900003703f00120021023200f20032903f001221e37030020034180026a41086a200629030037030020034180026a41106a201e37030020034180026a41186a20052903003703002003201e37031820032003290380013703800220034180016a20034180026a109102200329028401420020032802800122021b221e422088a7210702402002410420021b2206450d002007450d002007410c6c21052006210203402002200341d8006a10742002410c6a2102200541746a22050d000b0b20032006360280012003201e370284010240024020060d002003420037039802200342003703900220034200370388022003420037038002200341f0016a41086a22024191fdc400ad42808080809001841003220541086a290000370300200320052900003703f00120051023200320032903f001221e3703382003201e3703800220032002290300370388022002419adfc100ad4280808080a001841003220541086a290000370300200320052900003703f00120051023200341186a41086a200329038802370300200341286a20032903f001221e370300200341306a20022903003703002003201e3703482003201e370390022003200329038002370318200341186aad428080808080048410050c010b201ea721082003420037039802200342003703900220034200370388022003420037038002200341f0016a41086a22024191fdc400ad42808080809001841003220541086a290000370300200320052900003703f00120051023200320032903f001221e3703382003201e3703800220032002290300370388022002419adfc100ad4280808080a001841003220541086a290000370300200320052900003703f00120051023200341186a41086a200329038802370300200341286a20032903f001221e370300200341306a20022903003703002003201e3703482003201e37039002200320032903800237031820034120360284022003200341186a3602800220034180016a20034180026a107302402007450d002007410c6c21052006210203400240200241046a280200450d00200228020010230b2002410c6a2102200541746a22050d000b0b2008450d00200610230b20034180016a41186a2207420037030020034180016a41106a2208420037030020034180016a41086a220542003703002003420037038001200341f0016a41086a22024191fdc400ad42808080809001841003220641086a290000370300200320062900003703f0012006102320052002290300370300200320032903f00137038001200241a9e0c100ad4280808080f001841003220641086a290000370300200320062900003703f00120061023200341186a41086a2002290300221e370300200320032903f001221f370318200f201f370000200f41086a201e37000020034180026a41086a200529030037030020034180026a41106a200829030037030020034180026a41186a200729030037030020032003290380013703800220034180016a20034180026a109102200329028401420020032802800122021b221e422088a7210702402002410420021b2206450d002007450d002007410c6c21052006210203402002200341d8006a10742002410c6a2102200541746a22050d000b0b20032006360280012003201e370284010240024020060d002003420037039802200342003703900220034200370388022003420037038002200341f0016a41086a22024191fdc400ad42808080809001841003220541086a290000370300200320052900003703f00120051023200320032903f001221e3703382003201e370380022003200229030037038802200241a9e0c100ad4280808080f001841003220541086a290000370300200320052900003703f00120051023200341186a41086a200329038802370300200341286a20032903f001221e370300200341306a20022903003703002003201e3703482003201e370390022003200329038002370318200341186aad428080808080048410050c010b201ea721082003420037039802200342003703900220034200370388022003420037038002200341f0016a41086a22024191fdc400ad42808080809001841003220541086a290000370300200320052900003703f00120051023200320032903f001221e3703382003201e370380022003200229030037038802200241a9e0c100ad4280808080f001841003220541086a290000370300200320052900003703f00120051023200341186a41086a200329038802370300200341286a20032903f001221e370300200341306a20022903003703002003201e3703482003201e37039002200320032903800237031820034120360284022003200341186a3602800220034180016a20034180026a107302402007450d002007410c6c21052006210203400240200241046a280200450d00200228020010230b2002410c6a2102200541746a22050d000b0b2008450d00200610230b20034180016a41186a2206420037030020034180016a41106a2207420037030020034180016a41086a220242003703002003420037038001200341f0016a41086a22094191fdc400ad4280808080900184221e1003220541086a290000370300200320052900003703f0012005102320022009290300370300200320032903f0013703800120094184ddc100ad4280808080e00084221f1003220541086a290000370300200320052900003703f00120051023200341186a41086a221320092903002220370300200320032903f0012221370318200f2021370000200f41086a202037000020034180026a41086a200229030037030020034180026a41106a200729030037030020034180026a41186a200629030037030020032003290380013703800220034180016a20034180026a10fe01200329028401420020032802800122021b2220422088a72210412c6c21122002410420021b211102402010450d00200328025c2108200328025821072012210520112102034002400240200228020022062007280200460d0020082802002006470d010b200241246a22062802004102460d00200641003602000b2002412c6a2102200541546a22050d000b0b20034200370398022003420037039002200342003703880220034200370380022009201e1003220241086a290000370300200320022900003703f00120021023200320032903f001221e3703382003201e3703800220032009290300370388022009201f1003220241086a290000370300200320022900003703f001200210232013200329038802370300200341186a41106a20032903f001221e370300200341186a41186a20092903003703002003201e3703482003201e37039002200320032903800237031820034100360288012003420137038001201020034180016a105c02402010450d00201120126a21092011210503402005280200210702400240200328028401220620032802880122026b4104490d0020032802800121060c010b200241046a22082002490d16200641017422022008200220084b1b22024100480d160240024020060d002002102121060c010b20032802800120062002102521060b2006450d0b2003200236028401200320063602800120032802880121020b2003200241046a36028801200620026a2007360000200541046a20034180016a10d3012005412c6a22052009470d000b0b2003280284012102200341186aad4280808080800484221e2003350288014220862003280280012205ad84100202402002450d00200510230b20034180026a411072210502402020a7450d00201110230b200328027c21082003280278210920034180016a41186a2210420037030020034180016a41106a2211420037030020034180016a41086a220642003703002003420037038001200341f0016a41086a22024191fdc400ad4280808080900184221f1003220741086a290000370300200320072900003703f0012007102320062002290300370300200320032903f0013703800120024182fdc400ad4280808080a0018422201003220741086a290000370300200320072900003703f00120071023200341186a41086a221220022903002221370300200320032903f0012222370318200f2022370000200f41086a202137000020034180026a41086a200629030037030020034180026a41106a201129030037030020034180026a41186a201029030037030020032003290380013703800220034180016a20034180026a4120108b022003280280012206410420061b2211200329028401420020061b2221422088a722072008200910b40220034200370398022003420037039002200342003703880220034200370380022002201f1003220641086a290000370300200320062900003703f00120061023200320032903f001221f3703382003201f370380022003200229030037038802200220201003220641086a290000370300200320062900003703f00120061023200341c8006a41086a2002290300221f370300200320032903f001222037034820052020370000200541086a201f3700002012200329038802370300200341186a41106a200329039002370300200341186a41186a20032903980237030020032003290380023703180240024020110d00201e10050c010b20034100360288012003420137038001200720034180016a105c0240024020070d002003280288012109200328028401210820032802800121050c010b2007410274210f410020032802880122026b210620032802840121082011210703402007280200211002400240200820066a4104490d0020032802800121050c010b200241046a22052002490d17200841017422092005200920054b1b22094100480d170240024020080d002009102121050c010b20032802800120082009102521050b2005450d0d20032009360284012003200536028001200921080b200741046a21072003200241046a220936028801200520026a20103600002006417c6a210620092102200f417c6a220f0d000b0b201e2009ad4220862005ad84100202402008450d00200510230b2021a7450d00201110230b20032802782111200328027c2106200341f0016a41086a22054191fdc400ad4280808080900184221e1003220241086a290000370300200320022900003703f00120021023200341386a41086a22092005290300370300200320032903f00137033820054198e9c100ad4280808080d00084221f1003220241086a290000370300200320022900003703f00120021023200341c8006a41086a220f2005290300370300200320032903f0013703482003200636025820034180016a41186a2206200a4280808080c0008422201001220241186a29000037030020034180016a41106a2207200241106a29000037030020034180016a41086a2208200241086a29000037030020032002290000370380012002102320032006290300370398022003200729030037039002200320082903003703880220032003290380013703800241c00010212202450d0a20022003290338370000200241086a200929030037000020022003290348370010200241186a200f2903003700002002200329038002370020200241286a200329038802370000200241306a200329039002370000200241386a200329039802370000200241c00010a60221122005201e1003221041086a290000370300200320102900003703f0012010102320092005290300370300200320032903f0013703382005201f1003220941086a290000370300200320092900003703f00120091023200f2005290300370300200320032903f00137034820032011360258200620201001220541186a2900003703002007200541106a2900003703002008200541086a29000037030020032005290000370380012005102320032006290300370398022003200729030037039002200320082903003703880220032003290380013703800241c00010212205450d0b20052003290338370000200541086a200341386a41086a29030037000020052003290348370010200541186a200341c8006a41086a2903003700002005200329038002370020200541286a200329038802370000200541306a200329039002370000200541386a200329039802370000200541c00010a602210602400240201241ff017122084102470d002005ad428080808080088410050c010b410110212207450d0d200720084101463a00002005ad42808080808008842007ad428080808010841002200710230b2005102302400240200641ff017122064102470d002002ad428080808080088410050c010b410110212205450d0e200520064101463a00002002ad42808080808008842005ad428080808010841002200510230b2002102320032802782114200328027c2106200341f0016a41086a22054191fdc400ad4280808080900184221e1003220241086a290000370300200320022900003703f00120021023200341386a41086a22112005290300370300200320032903f001370338200541a884c200ad4280808080f00084221f1003220241086a290000370300200320022900003703f00120021023200341c8006a41086a22122005290300370300200320032903f0013703482003200636025820034180016a41186a2206200a4280808080c00084220a1001220241186a29000037030020034180016a41106a2207200241106a29000037030020034180016a41086a2208200241086a29000037030020032002290000370380012002102320032006290300370398022003200729030037039002200320082903003703880220032003290380013703800241c00010212202450d0e20022003290338370000200241086a201129030037000020022003290348370010200241186a20122903003700002002200329038002370020200241286a200329038802370000200241306a200329039002370000200241386a20032903980237000020034180016a200241c000108a0120034189016a2209290000212020034191016a220f290000212120034199016a2210290000212220032d008001211520032900810121232005201e1003221341086a290000370300200320132900003703f0012013102320112005290300370300200320032903f0013703382005201f1003221141086a290000370300200320112900003703f0012011102320122005290300370300200320032903f001370348200320143602582006200a1001220541186a2900003703002007200541106a2900003703002008200541086a29000037030020032005290000370380012005102320032006290300370398022003200729030037039002200320082903003703880220032003290380013703800241c00010212205450d0f20052003290338370000200541086a200341386a41086a29030037000020052003290348370010200541186a200341c8006a41086a2903003700002005200329038002370020200541286a200329038802370000200541306a200329039002370000200541386a20032903980237000020034180016a200541c000108a012009290000210a200f290000211e2010290000211f200329008101212420032d0080012107201020224200201541ff017141014622061b370000200f2021420020061b37000020092020420020061b37000020032023420020061b37008101200341013a008001200341c00036028402200320053602800220034180016a410172220620034180026a10f501200510232010201f4200200741014622051b370000200f201e420020051b3700002009200a420020051b37000020032024420020051b37008101200341013a008001200341c000360284022003200236028002200620034180026a10f5012002102320032802782106200328027c2107200341f0016a41086a2205418cfdc400ad4280808080d00084220a1003220241086a290000370300200320022900003703f00120021023200341186a41086a22102005290300370300200320032903f00137031820054184ffc300ad4280808080b00184221e1003220241086a290000370300200320022900003703f00120021023200341d8006a41086a22112005290300370300200320032903f001370358200320073602f00120034180016a41186a2208200341f0016aad221f4280808080c0008422201001220241186a29000037030020034180016a41106a2209200241106a29000037030020034180016a41086a220f200241086a29000037030020032002290000370380012002102320034180026a41186a2212200829030037030020034180026a41106a2213200929030037030020034180026a41086a2214200f29030037030020032003290380013703800241c00010212202450d1020022003290318370000200220032903583700102002200329038002370020200241086a2010290300370000200241186a2011290300370000200241286a2014290300370000200241306a2013290300370000200241386a20122903003700002005200a1003221541086a290000370300200320152900003703f0012015102320102005290300370300200320032903f0013703182005201e1003221041086a290000370300200320102900003703f0012010102320112005290300370300200320032903f001370358200320063602f001200820201001220541186a2900003703002009200541106a290000370300200f200541086a29000037030020032005290000370380012005102320122008290300370300201320092903003703002014200f29030037030020032003290380013703800241c00010212205450d1120052003290318370000200520032903583700102005200329038002370020200541086a200341186a41086a290300370000200541186a200341d8006a41086a290300370000200541286a20034180026a41086a290300370000200541306a20034190026a290300370000200541386a20034180026a41186a29030037000020034180026a2002ad4280808080800884220a100410900120034180016a2005ad4280808080800884221e100410900102402003280280012208450d002003280284012109200a20034180016a41086a3502004220862008ad8410022009450d13200810230c130b200a10050c120b200141046a28020021022001411c6a280200210f20012d000121102003200141106a28020036028802200320083602840220032009360280022003200f36028801200320063602840120032007360280012002201020034180026a20034180016a10b202210241012107410021060c170b41c00041011030000b41c00041011030000b200241011030000b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000b200241011030000b200941011030000b41c00041011030000b41c00041011030000b410141011030000b410141011030000b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000b024002402003280280022208450d002003280284022109201e20034188026a3502004220862008ad8410022009450d01200810230c010b201e10050b2005102320021023200341f0016a41086a2205418cfdc400ad4280808080d00084220a1003220241086a290000370300200320022900003703f00120021023200341186a41086a22102005290300370300200320032903f001370318200541d0ffc300ad4280808080800184221e1003220241086a290000370300200320022900003703f00120021023200341d8006a41086a22112005290300370300200320032903f001370358200320073602f00120034180016a41186a2208201f4280808080c00084221f1001220241186a29000037030020034180016a41106a2209200241106a29000037030020034180016a41086a220f200241086a29000037030020032002290000370380012002102320034180026a41186a2212200829030037030020034180026a41106a2213200929030037030020034180026a41086a2214200f29030037030020032003290380013703800202400240024041c00010212202450d0020022003290318370000200220032903583700102002200329038002370020200241086a2010290300370000200241186a2011290300370000200241286a2014290300370000200241306a2013290300370000200241386a20122903003700002005200a1003221541086a290000370300200320152900003703f0012015102320102005290300370300200320032903f0013703182005201e1003221041086a290000370300200320102900003703f0012010102320112005290300370300200320032903f001370358200320063602f0012008201f1001220541186a2900003703002009200541106a290000370300200f200541086a29000037030020032005290000370380012005102320122008290300370300201320092903003703002014200f29030037030020032003290380013703800241c00010212205450d0120052003290318370000200520032903583700102005200329038002370020200541086a200341186a41086a290300370000200541186a200341d8006a41086a290300370000200541286a20034180026a41086a290300370000200541306a20034190026a290300370000200541386a20034180026a41186a29030037000020034180026a2002ad4280808080800884220a100410900120034180016a2005ad4280808080800884221e100410900102402003280280012208450d002003280284012109200a20034180016a41086a3502004220862008ad8410022009450d03200810230c030b200a10050c020b41c00041011030000b41c00041011030000b024002402003280280022208450d002003280284022109201e20034188026a3502004220862008ad8410022009450d01200810230c010b201e10050b200510232002102320034180016a41186a2212420037030020034180016a41106a2209420037030020034180016a41086a220542003703002003420037038001200341f0016a41086a2202418cfdc400ad4280808080d00084221e1003220841086a290000370300200320082900003703f0012008102320052002290300370300200320032903f00137038001200241acfec300ad4280808080a00184221f1003220841086a290000370300200320082900003703f00120081023200920032903f001220a37030020034180026a41086a2208200529030037030020034180026a41106a220f200a37030020034180026a41186a221320022903003703002003200a37035820032003290380013703800220034180016a20034180026a4120108b022003280280012210410420101b2211200329028401420020101b2220422088a722102007200610b40220134200370300200f42003703002008420037030020034200370380022002201e1003220641086a290000370300200320062900003703f0012006102320082002290300370300200320032903f001220a3703182003200a370380022002201f1003220641086a290000370300200320062900003703f00120061023200f20032903f001220a370300200520082903003703002009200a370300201220022903003703002003200a370358200320032903800237038001024020110d0020034180016aad42808080808004841005410021020c030b20034100360288022003420137038002201020034180026a105c02400240024020100d002003280288022109200328028402210820032802800221050c010b2010410274210f410020032802880222026b210620032802840221082011210703402007280200211002400240200820066a4104490d0020032802800221050c010b200241046a22052002490d04200841017422092005200920054b1b22094100480d040240024020080d002009102121050c010b20032802800220082009102521050b2005450d0320032009360284022003200536028002200921080b200741046a21072003200241046a220936028802200520026a20103600002006417c6a210620092102200f417c6a220f0d000b0b20034180016aad42808080808004842009ad4220862005ad84100202402008450d00200510230b4100210202402020a7450d00201110230b0c030b200941011030000b102a000b41bbbdc1002102412d21050b41012106410121070c020b02402007450d00200c10230b41002107410121062008450d01200e10230c010b4186b0c000210241112105410121070b024020012d0000417f6a220341034b0d000240024020030e0401020200010b2007450d010240200141086a280200450d00200141046a28020010230b200141146a280200450d01200141106a28020010230c010b2006450d0002402001410c6a280200450d00200141086a28020010230b200141186a280200450d00200141146a28020010230b2000200536020420002002360200200424000bdf0301067f230041f0006b22012400200141d0006a41086a2202418cfdc400ad4280808080d000841003220341086a2900003703002001200329000037035020031023200141086a41086a2204200229030037030020012001290350370308200241c7f3c300ad4280808080a001841003220341086a2900003703002001200329000037035020031023200141186a41086a22052002290300370300200120012903503703182001200036024c200141d0006a41186a2200200141cc006aad4280808080c000841001220341186a290000370300200141d0006a41106a2206200341106a2900003703002002200341086a2900003703002001200329000037035020031023200141286a41186a22032000290300370300200141286a41106a22002006290300370300200141286a41086a2206200229030037030020012001290350370328024041c000102122020d0041c00041011030000b200220012903083700002002200129031837001020022001290328370020200241086a2004290300370000200241186a2005290300370000200241286a2006290300370000200241306a2000290300370000200241386a20032903003700002001200241c00041014100410010b8012001280200210320021023200141f0006a240020034101460b0900200042043702000b130020004107360204200041e48bc2003602000bb60b01097f230041f0016b220224000240024020012802102203450d0020012802082204200128020c460d00200128021421052001200441246a3602082002413c6a41026a2206200441036a2d00003a0000200241206a41086a2207200441106a290000370300200241206a41106a2208200441186a290000370300200241206a41186a2209200441206a280000360200200220042f00013b013c2002200441086a29000037032020042d0000220a4102460d00200441046a280000210420012003417f6a360210200241dc016a41026a20062d00003a0000200241c0016a41086a2007290300370300200241c0016a41106a2008290300370300200241c0016a41186a2009280200360200200220022f013c3b01dc01200220022903203703c001024002400240200a4101460d00200241bc016a41026a200241dc016a41026a2d00003a0000200241a0016a41086a200241c0016a41086a290300370300200241a0016a41106a200241c0016a41106a290300370300200241a0016a41186a200241c0016a41186a2d00003a0000200220022f01dc013b01bc01200220022903c0013703a0010c010b200241e0016a200441067610bc0220022802e00121030240024020022802e8012004413f7122014b0d00410021010c010b200241bc016a41026a200320014105746a220141026a2d00003a0000200241a8016a2001410f6a290000370300200241b0016a200141176a290000370300200241b8016a2001411f6a2d00003a0000200220012f00003b01bc01200220012900073703a00120012800032104410121010b024020022802e401450d00200310230b20010d00410121010c010b2002419c016a41026a200241bc016a41026a2d00003a000020024180016a41086a200241a0016a41086a29030037030020024180016a41106a200241a0016a41106a29030037030020024180016a41186a200241a0016a41186a2d00003a0000200220022f01bc013b019c01200220022903a00137038001410021010b200241fc006a41026a22032002419c016a41026a2d00003a0000200241e0006a41086a220620024180016a41086a290300370300200241e0006a41106a220720024180016a41106a290300370300200241e0006a41186a220820024180016a41186a2d00003a0000200220022f019c013b017c2002200229038001370360024020010d00200241dc006a41026a20032d000022013a0000200241c0006a41086a22032006290300370300200241c0006a41106a22062007290300370300200241c0006a41186a220720082d00003a00002002411c6a41026a220820013a0000200220022f017c22013b015c20022002290360370340200220013b011c200241186a220120072d00003a0000200241106a22072006290300370300200241086a2206200329030037030020022002290340370300200241206a41026a220320082d00003a0000200220022f011c3b0120200241c0016a41186a220820012d00003a0000200241c0016a41106a22012007290300370300200241c0016a41086a22072006290300370300200220022903003703c001200041046a2004360000200041036a20032d00003a0000200020022f01203b0001200041086a20022903c001370000200041106a2007290300370000200041186a2001290300370000200041206a20082d00003a0000410121010c020b200541013a00002002411c6a41026a2201200241dc006a41026a2d00003a0000200241086a2204200241c0006a41086a290300370300200241106a2203200241c0006a41106a290300370300200241186a2206200241c0006a41186a2d00003a0000200220022f015c3b011c20022002290340370300200241206a41026a20012d00003a0000200220022f011c3b0120200241c0016a41186a20062d00003a0000200241c0016a41106a2003290300370300200241c0016a41086a2004290300370300200220022903003703c0010b410021010b200020013a0000200241f0016a24000b840401067f230041f0006b22022400200241d0006a41086a220341cefbc400ad4280808080f000841003220441086a2900003703002002200429000037035020041023200241086a41086a2205200329030037030020022002290350370308200341b5e1c300ad4280808080f000841003220441086a2900003703002002200429000037035020041023200241186a41086a22062003290300370300200220022903503703182002200136024c200241d0006a41186a2201200241cc006aad4280808080c000841001220441186a290000370300200241d0006a41106a2207200441106a2900003703002003200441086a2900003703002002200429000037035020041023200241286a41186a22042001290300370300200241286a41106a22012007290300370300200241286a41086a2207200329030037030020022002290350370328024041c00010212203450d00200320022903083700002003200229031837001020032002290328370020200341086a2005290300370000200341186a2006290300370000200341286a2007290300370000200341306a2001290300370000200341386a2004290300370000200241d0006a200341c00010bb010240024020022802502204450d0020002002290254370204200020043602000c010b20004100360208200042013702000b20031023200241f0006a24000f0b41c00041011030000bd50505067f017e047f017e027f23004180026b22022400024002400240024002402000280200220320002802044f0d00200028020c2104200141086a2105200241a0016a4102722106024003402000200341016a360200200241186a2000280208280200220710be0220022d00184101460d0120022900192108200241086a2007106e20022802080d012007280204200228020c2203490d012003417f4c0d0302400240024020030d00410121090c010b200310272209450d0820072802042003490d0120092007280200200310dc041a2007280204220a2003490d062007200a20036b3602042007200728020020036a3602000b20022008370310024002402001280200220b41d8a7c300460d002001280204210c0c010b2006410041da0010db041a200241186a410041840110db041a41e4011021220b450d074100210c200b4100360200200b41046a200241a0016a41dc0010dc041a200b41e0006a200241186a41840110dc041a200141003602042001200b3602000b2003ad220d422086200d84210d024002400340200b41086a2107200b2f0106220e41037421034100210a024003402003450d01200241106a2007410810de04220f450d03200341786a2103200a41016a210a200741086a2107200f417f4a0d000b200a417f6a210e0b0240200c450d00200c417f6a210c200b200e4102746a41e4016a280200210b0c010b0b2002200837022c200220053602282002200e360224200220013602202002200b36021c200241003602182002200d3702a401200220093602a001200241186a200241a0016a10d2010c010b200b200a410c6c6a220341e4006a2207280200210a2007200d370200200341e0006a22072802002103200720093602002003450d00200a450d00200310230b200028020022032000280204490d010c030b0b200910230b200441013a00000b20024180026a24000f0b102f000b2003200a103e000b41e40141041030000b200341011030000bf00204027f017e017f077e0240024020012802042202450d0020012802002203310000210420012002417f6a22053602042001200341016a3602002005450d012003310001210620012002417e6a22053602042001200341026a3602002005450d012003310002210720012002417d6a22053602042001200341036a3602002005450d012003310003210820012002417c6a22053602042001200341046a3602002005450d012003310004210920012002417b6a22053602042001200341056a3602002005450d012003310005210a20012002417a6a22053602042001200341066a3602002005450d012003310006210b2001200241796a22053602042001200341076a3602002005450d01200041003a00002003310007210c2001200241786a3602042001200341086a3602002000200c423886200b42308684200a422886842009422086842008421886842007421086842006420886842004843700010f0b200041013a00000f0b200041013a00000bc3b6010f017f017e047f017e077f017e027f017e037f017e027f017e177f027e127f230041e0056b2200240042002101200041b0036a41186a4200370300200041b0036a41106a22024200370300200041b0036a41086a22034200370300200042003703b003200041a0046a41086a2204419da0c200ad42808080808002841003220541086a290000370300200020052900003703a0042005102320032004290300370300200020002903a0043703b003200441e4acc200ad4280808080a001841003220541086a290000370300200020052900003703a00420051023200220002903a0042206370300200041b0056a41086a2003290300370300200041b0056a41106a2006370300200041b0056a41186a20042903003703002000200637038803200020002903b0033703b005200041b0036a200041b0056a412010bb010240024020002802b00322070d0041012107410021080c010b20002902b4032201422088a721080b024002400240024002400240200841ffffff3f712008470d0020084105742204417f4c0d0002400240024002400240024002400240024002400240024002400240024002400240024020040d00410121090c010b200410212209450d010b4100210a4100210b4100210c02402008450d00200841057421052009210420072103034020042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a290000370000200441206a2104200341206a2103200541606a22050d000b200841057441606a41057641016a210c2008210b0b200041b0036a41186a22084200370300200041b0036a41106a220d4200370300200041b0036a41086a22034200370300200042003703b003200041a0046a41086a2204419da0c200ad42808080808002841003220541086a290000370300200020052900003703a0042005102320032004290300370300200020002903a0043703b00320044183e0c400ad4280808080f000841003220541086a290000370300200020052900003703a0042005102320004188036a41086a20042903002206370300200020002903a004220e370388032002200e370000200241086a2006370000200041b0056a41086a2003290300370300200041b0056a41106a200d290300370300200041b0056a41186a2008290300370300200020002903b0033703b005200041b0036a200041b0056a10c00220002902b403420020002802b00322031b2206422088a7220541306c220841306d21040240024020080d004101210d0c010b200441ffffff3f712004470d16200441057422084100480d1620081021220d450d022004210a0b2006a7210f2003410820031b21100240024020050d00410021080c010b200541306c210541002108200d2104201021030340200341086a2900002106200341106a290000210e20032900002111200441186a200341186a290000370000200441106a200e370000200441086a200637000020042011370000200841016a2108200441206a2104200341306a2103200541506a22050d000b0b0240200f450d00201010230b02402001a722042001422088a722106b20084f0d00201020086a22032010490d16200441017422052003200520034b1b220341ffffff3f712003470d16200341057422054100480d160240024020040d002005102121070c010b200720044105742005102521070b2007450d032001422088a721102003ad21010b200720104105746a200d200841057410dc041a0240200a450d00200d10230b200041b0036a41186a220d4200370300200041b0036a41106a220a4200370300200041b0036a41086a22034200370300200042003703b003200041a0046a41086a2204419da0c200ad42808080808002841003220541086a290000370300200020052900003703a0042005102320032004290300370300200020002903a0043703b003200441eeacc200ad42808080809001841003220541086a290000370300200020052900003703a0042005102320004188036a41086a20042903002206370300200020002903a004220e370388032002200e370000200241086a2006370000200041b0056a41086a2003290300370300200041b0056a41106a200a290300370300200041b0056a41186a200d290300370300200020002903b0033703b005200041b0036a200041b0056a10c00220002902b403420020002802b00322041b2206422088a7220341306c220d41306d210a4100210502400240200d0d004101210f4100210a0c010b200a41ffffff3f71200a470d16200a410574220d4100480d16200d1021220f450d040b2006a721122004410820041b211302402003450d00200341306c210d41002105200f2104201321030340200341086a2900002106200341106a290000210e20032900002111200441186a200341186a290000370000200441106a200e370000200441086a200637000020042011370000200541016a2105200441206a2104200341306a2103200d41506a220d0d000b0b201020086a211402402012450d00201310230b024002402001a7220420146b2005490d00200142ffffffff0f8321150c010b201420056a22032014490d16200441017422082003200820034b1b220341ffffff3f712003470d16200341057422084100480d160240024020040d002008102121070c010b200720044105742008102521070b2007450d052003ad21150b200720144105746a200f200541057410dc041a0240200a450d00200f10230b200041b0036a10c102200041e0026a20002802b003220420002802b803108a01024020002802b403450d00200410230b20004188036a41206a200041e0026a41206a2d00003a000020004188036a41186a200041e0026a41186a29030037030020004188036a41106a200041e0026a41106a29030037030020004188036a41086a200041e0026a41086a290300370300200020002903e00237038803200041b0036a20004188036a10a0010240024020002802d00322040d004104211641002108410021170c010b200041b0056a41186a200041b0036a41186a290300370300200041b0056a41106a200041b0036a41106a290300370300200041b0056a41086a200041b0036a41086a290300370300200020002903b0033703b00520002902d4032106412c10212216450d06201620002903b0053702002016200637022420162004360220201641186a200041b0056a41186a2204290300370200201641106a200041b0056a41106a2203290300370200201641086a200041b0056a41086a2208290300370200200041b0056a41206a20004188036a41206a2d00003a0000200420004188036a41186a290300370300200320004188036a41106a290300370300200820004188036a41086a29030037030020002000290388033703b005200041b0036a200041b0056a10a001024020002802d00322100d0041012108410121170c010b4102210d412c210341012108410121170340200041b0046a41186a200041b0036a41186a2903002206370300200041b0046a41106a200041b0036a41106a290300220e370300200041b0046a41086a200041b0036a41086a2903002211370300200020002903b00322013703b00420002902d4032118200041d0046a41186a220a2006370300200041d0046a41106a220f200e370300200041d0046a41086a22132011370300200020013703d004024020082017470d00200841016a22042008490d18200d2004200d20044b1b2217ad422c7e2206422088a70d182006a722044100480d180240024020080d002004102121160c010b201620032004102521160b2016450d090b201620036a220420002903d004370200200441186a200a290300370200200441106a200f290300370200200441086a2013290300370200200441246a2018370200200441206a2010360200200d41026a210d2003412c6a2103200841016a2108200041b0036a200041b0056a10a00120002802d00322100d000b0b200042003702f404200041d8a7c3003602f0042008201420056a22046a2219ad42e0007e2206422088a70d102006a7221a417f4c0d104108211202400240201a0d004108211b4108211c0c010b201a1021221b450d08201b211c0b410021144100211d02402004410574220d450d00200d410575221dad42d8007e2206422088a70d162006a722034100480d16200310212212450d090b02402004450d00200d41606a211e200041e0036a2103200041d8036a211f2012211041002105200721040340200041e0026a41186a220a200441186a220f290000370300200041e0026a41106a2213200441106a2214290000370300200041e0026a41086a2220200441086a2221290000370300200020042900003703e002200041b0056a41186a200f290000370300200041b0056a41106a2014290000370300200041b0056a41086a2021290000370300200020042900003703b005200041f0046a200041b0056a200510cf01200041b0036a41086a4200370300200041b0036a41106a4200370300200041b0036a41186a4200370300200041b0036a41206a4200370300201f4200370300200341186a200a290300370000200341106a2013290300370000200341086a2020290300370000200320002903e002370000200042003703b0032010200041b0036a41d00010dc04221041d0006a41003a0000201041d8006a2110200441206a2104200541016a2105200d41606a220d0d000b201e41057641016a21140b02402015500d00200710230b0240024020192008412c6c2203412c6d2204490d00201921220c010b201941017422052004200520044b1b2222ad42e0007e2206422088a70d162006a722044100480d160240024020190d0020041021211b0c010b201b201a20041025211b0b201b450d0a201b211c0b201620036a2123024020080d0041002124201621250c0f0b200041d0046a41106a212020162104201b2126410021240340200041b0046a41186a2203200441186a290200370300200041b0046a41106a2205200441106a290200370300200041b0046a41086a2208200441086a290200370300200020042902003703b0042004412c6a212520042802202227450d0f200441286a2802002113200441246a2802002128200041e0026a41186a22292003290300370300200041e0026a41106a222a2005290300370300200041e0026a41086a222b2008290300370300200020002903b0043703e002200041d0026a200041e0026a10c2022013ad42c8007e2206422088a70d112006a72204417f4c0d11200041d0026a41086a290300211820002903d00221150240024020040d004108211f0c010b20041021221f450d0c0b0240024020130d0041002113410021210c010b202720134105746a211e41002121202721100340201041086a2900002106201041106a290000210e20102900002111200041b0036a41186a2207201041186a290000370300200041b0036a41106a2219200e370300200041b0036a41086a221a2006370300200020113703b003201041206a2110200041f0046a210420002802f404210a024003402004280200220d41086a2103200d2f0106220f4105742104410021050240024003402004450d01200041b0036a2003412010de042208450d02200441606a2104200541016a2105200341206a21032008417f4a0d000b2005417f6a210f0b200a450d02200a417f6a210a200d200f4102746a4194036a21040c010b0b2014200d20054102746a41e8026a220328020022044d0d0f2012200441d8006c6a22042903202106200441286a290300210e200041d0046a41186a220d420037030020204200370300200041d0046a41086a22054200370300200042003703d004200041a0046a41086a220441d5fbc400ad42808080808001841003220841086a290000370300200020082900003703a0042008102320052004290300370300200020002903a0043703d004200441d6a0c200ad4280808080d001841003220841086a290000370300200020082900003703a00420081023200041a0056a41086a20042903002211370300200020002903a00422013703a00520202001370000202041086a2011370000200041b0056a41086a2005290300370300200041b0056a41106a2020290300370300200041b0056a41186a200d290300370300200020002903d0043703b005200041b8026a200041b0056a4120108902200041a8026a20002903c002200041b8026a41106a290300427f420010e2042014200328020022044d0d1020004198026a2015201820002903a802420020002802b80222051b221142012011420156200041a8026a41086a290300420020051b22114200522011501b22051b2011420020051b10e2042012200441d8006c6a220441286a427f200e20062000290398027c22112006542205ad7c220120052001200e54201120065a1b22051b3703002004427f201120051b37032020004188036a41186a2205200729030037030020004188036a41106a2208201929030037030020004188036a41086a220d201a290300370300200020002903b00337038803200328020021030240024020212013460d00202121040c010b201341016a22042013490d1a2013410174220a2004200a20044b1b220aad42c8007e2206422088a70d1a2006a722044100480d1a0240024020130d0020041021211f0c010b201f201341c8006c20041025211f0b201f450d1220132104200a21130b201f200441c8006c6a2204420037030020042003360220200441186a4200370300200441106a4200370300200441086a420037030020042000290388033702242004412c6a200d290300370200200441346a20082903003702002004413c6a2005290300370200202141016a21210b2010201e470d000b0b02402028450d00202710230b20004180056a41186a2208202929030037030020004180056a41106a220d202a29030037030020004180056a41086a2210202b290300370300200020002903e00237038005200041d0046a41186a220a420037030020204200370300200041d0046a41086a22034200370300200042003703d004200041a0046a41086a220441d5fbc400ad42808080808001841003220541086a290000370300200020052900003703a0042005102320032004290300370300200020002903a0043703d004200441d6a0c200ad4280808080d001841003220541086a290000370300200020052900003703a00420051023200041a0056a41086a20042903002206370300200020002903a004220e3703a0052020200e370000202041086a2006370000200041b0056a41086a2003290300370300200041b0056a41106a2020290300370300200041b0056a41186a200a290300370300200020002903d0043703b00520004180026a200041b0056a4120108902200041f0016a20002903880220004180026a41106a290300427f420010e204200041e0016a2015201820002903f001420020002802800222041b220642012006420156200041f0016a41086a290300420020041b22064200522006501b22041b2006420020041b10e20420264200370308202620002903e00137030020264200370310202641186a4200370300202641286a42003703002026420137032020262021360238202620133602342026201f360230202620002903800537023c202641c4006a2010290300370200202641cc006a200d290300370200202641d4006a2008290300370200202441016a2124202641e0006a21262025210420252023470d000c100b0b200441011030000b200841011030000b200541011030000b200d41011030000b200841011030000b412c41041030000b200441041030000b201a41081030000b200341081030000b200441081030000b200441081030000b41a0abc20020042014102d000b41c8a1c30020042014102d000b200441081030000b20252023460d000340202541206a2802002203450d012025412c6a21040240202541246a280200450d00200310230b2004212520232004470d000b0b02402017450d00201610230b0240024041c00710212207450d00024041f0061021222c450d004100212d4114212e02402014411420144114491b22290d004114212f410021160c030b201241a87f6a2127201441d8006c2125201c202441e0006c6a21194114211e200041b0036a41186a2117200041b0036a41106a211f200041b0036a41086a21284100211641002126034002402014450d00202521032012210403400240200441d0006a2d00000d0002400240200441206a290300220e200441286a29030022118450450d0042002106427f210e427f21110c010b427f2106200041d0016a427f427f200e201110e204200041d0016a41086a290300211120002903d001210e0b2004200e37030020042011370308200441106a2006370300200441186a20063703000b200441d8006a2104200341a87f6a22030d000b0b201c210802402024450d0002400340024020082802382204450d00200441c8006c2105200828023041206a210403402014200428020022034d0d0302402012200341d8006c6a22032d00500d0020032903202206200341286a290300220e84500d00200041b0036a2008290310200841186a2903002008290300200841086a2903002006200e10c302200320032903002206427f2006427f20002903b80320002802b003410146220d1b22117c220e200e2006542210200341086a220a2903002206427f201f290300200d1b22017c2010ad7c220e200654200e2006511b220d1b20112001845022101b370300200a2006427f200e200d1b20101b3703000b200441c8006a2104200541b87f6a22050d000b0b200841e0006a22082019460d020c000b0b41e4ecc00020032014102d000b202641016a212620252104202721050340024020040d00201e212f0c050b200441a87f6a2104200541a8016a2108200541d8006a2203210520082d00000d000b02402004450d00200341d8006a2105200341086a2903002106200341186a290300210e200341106a2903002111200329030021014100210803400240200541d0006a2d00000d00200541086a29030022182006200120062011200e200529030022152018200541106a2903002230200541186a290300223110c40241ff0171410146220d1b210620152001200d1b21012031200e200d1b210e20302011200d1b211120052003200d1b21030b200541d8006a21052004200841d8006a2208470d000b20030d00201e212f0c040b200341013a005002402024450d002003410c6a2120200341306a2121201c21050340200541e0006a211a024020052802382208450d0020052802302104200841c8006c210803400240024020202004460d00200441246a2021412010de040d010b200541186a220d2903002101200341086a22102903002106200529031021112003290300210e20032903102118200441186a200341186a220a290300370300200441106a2018370300200420064200200620017d200e201154ad7d2218200e20117d2215200e56201820065620182006511b220f1b20112001845022131b3703082004200e42002015200f1b20131b37030020102903002106200a290300210e2003290300211120052003290310370320200541286a200e37030020052011370310200d20063703000b200441c8006a2104200841b87f6a22080d000b0b201a2105201a2019470d000b0b2017200341c8006a290000370300201f200341c0006a2900003703002028200341386a290000370300200020032900303703b003200341286a29030021062003290320210e0240024002402016201e460d00201e212f0c010b201e41016a2204201e490d0b201e41017422032004200320044b1b222fad42307e2211422088a70d0b2011a722044100480d0b02400240201e0d002004102121070c010b2007201e41306c2004102521070b2007450d01201e2116202f211e0b20282903002111201f29030021012017290300211820002903b00321152007201641306c6a2204200e37032020042015370300200441286a2006370300200441186a2018370300200441106a2001370300200441086a2011370300201641016a2116202620294f0d040c010b0b200441081030000b41f00641041030000b41c00741081030000b02402024450d00201c202441e0006c6a2125201641306c21194114212e200041b0056a41186a211a200041b0056a41106a211e200041b0056a41086a21264100212d201c21200340201a202041d4006a290000370300201e202041cc006a2900003703002026202041c4006a2900003703002000202029003c3703b005024020202802382204450d002020280230220f200441c8006c6a2121202041106a211f41002113410421144100210a02400240024002400340200f221041246a2105201041c8006a210f410021082019210320072104024003402003450d01024020052004460d0020042005412010de04210d200841016a2108200341506a2103200441306a2104200d0d010b0b418094ebdc0321040240201f201010c5020d004100210302402010290310202029032085201041186a290300202041286a29030085844200520d00200041b0036a428094ebdc0342002010290300201041086a290300201f290300201f41086a29030010c30220002802b0034101460d0120002903b803220e42ff93ebdc0356200041b0036a41106a29030022064200522006501b0d01200ea721030b200321040b200020043602b0032000418094ebdc033602b403200041b0036a2004418094ebdc034b4102746a2802002103200041b0036a41186a22052010413c6a290000370300200041b0036a41106a2208201041346a290000370300200041b0036a41086a220d2010412c6a290000370300200020102900243703b00302400240200a2013460d00200a21040c010b201341016a22042013490d0f201341017422102004201020044b1b2210ad42247e2206422088a70d0f2006a722044100480d0f0240024020130d002004102121140c010b2014201341246c2004102521140b2014450d0320132104201021130b2014200441246c6a220420002903b003370200200d29030021062008290300210e2005290300211120042003360220200441186a2011370200200441106a200e370200200441086a2006370200200a41016a210a0b200f2021470d000b0240200a450d0002400240200a41246c22050d00410021030c010b201441206a2104410021030340200428020020036a2103200441246a21042005415c6a22050d000b0b02404100418094ebdc0320036b22042004418094ebdc034b1b2210200a6e2204418094ebdc032004418094ebdc03491b220d450d00201441206a2104410021030340200a2003460d042000417f20042802002205200d6a220820082005491b22053602b0032000418094ebdc033602b4032004200041b0036a2005418094ebdc034b4102746a280200360200200441246a2104200a200341016a2203470d000b0b02402010200d200a6c6b220d450d00410021040340200a2004200a7022034d0d062000417f2014200341246c6a2203280220220541016a220820082005491b22053602b0032000418094ebdc033602b4032003200041b0036a2005418094ebdc034b4102746a280200360220200441016a2204200d490d000b0b200041b0036a41186a2203201a290300370300200041b0036a41106a2205201e290300370300200041b0036a41086a22082026290300370300200020002903b0053703b0030240202d202e470d00202e41016a2204202e490d0e202e410174220d2004200d20044b1b2204ad422c7e2206422088a70d0e2006a7220d4100480d0e02400240202e0d00200d1021212c0c010b202c202e412c6c200d1025212c0b202c450d04202e212d2004212e0b202c202d412c6c6a220420002903b003370200200829030021062005290300210e200329030021112004200a3602282004201336022420042014360220200441186a2011370200200441106a200e370200200441086a2006370200202d41016a212d0c050b2013450d04201410230c040b200441041030000b41ece2c0002003200a102d000b200d41041030000b41ece2c0002003200a102d000b202041e0006a22202025470d000b0b0240201d450d00201210230b02402024450d00202441e0006c2103201c41306a210403400240200441046a280200450d00200428020010230b200441e0006a2104200341a07f6a22030d000b0b02402022450d00201b10230b20002802f00420002802f40420002802f80410d0010240024020070d0041012114200041013a00b4032000410b3a00b003200041b0036a108e01200041b0056a210d0c010b42002115200041b0036a41186a22054200370300200041b0036a41106a2232420037030041082133200041b0036a41086a22034200370300200042003703b003200041a0046a41086a2204419da0c200ad4280808080800284220e1003220841086a290000370300200020082900003703a0042008102320032004290300370300200020002903a004220637038803200020063703b00320044183e0c400ad4280808080f000841003220841086a290000370300200020082900003703a00420081023203220002903a0042206370300200041b0056a41086a220d2003290300370300200041b0056a41106a22102006370300200041b0056a41186a220a20042903003703002000200637038803200020002903b0033703b005200041b0036a200041b0056a10c0024200213041082134024020002802b0032208450d00200041b0056aad4280808080800484100520002902b4032130200821340b200542003703002032420037030020034200370300200042003703b0032004200e1003220841086a290000370300200020082900003703a0042008102320032004290300370300200020002903a004220637038803200020063703b003200441eeacc200ad42808080809001841003220841086a290000370300200020082900003703a0042008102320004188036a41086a20042903002206370300200020002903a004220e370388032032200e370000203241086a2006370000200d200329030037030020102032290300370300200a2005290300370300200020002903b0033703b005200041b0036a200041b0056a10c002024020002802b0032204450d00200041b0056aad4280808080800484100520002902b4032115200421330b024002400240024002400240024002400240024002400240201641306c2203450d00200721040340200441286a2903002106200441206a290300210e200041d0046a41186a200441186a290200370300200041d0046a41106a200441106a290200370300200041d0046a41086a200441086a290200370300200020042902003703d004200e2006844200520d02200441306a2104200341506a22030d000b0b4101211a410021190240202f0d004100211e0c020b200710234100211e0c010b200041e0026a41086a2205200041d0046a41086a290300370300200041e0026a41106a2208200041d0046a41106a290300370300200041e0026a41186a220d200041d0046a41186a290300370300200020002903d004220637038005200020063703e00241201021221a450d07201a20002903e002370000201a41186a200d290300370000201a41106a2008290300370000201a41086a20052903003700000240024020034130470d00410121194101211e0c010b200441306a21052007201641306c6a220d41506a2110410121194101211e03402005210402400340200441286a2903002106200441206a290300210e200041d0046a41186a2203200441186a290200370300200041d0046a41106a2205200441106a290200370300200041d0046a41086a2208200441086a290200370300200020042902003703d004200e2006844200520d01200d200441306a2204470d000c030b0b200041b0056a41086a20082903002206370300200041b0056a41106a2005290300220e370300200041b0056a41186a20032903002211370300200020002903d00422013703b00520004180056a41186a2208201137030020004180056a41106a220a200e37030020004180056a41086a220f200637030020002001370380050240201e2019470d00201941016a22032019490d13201941017422052003200520034b1b221e41ffffff3f71201e470d13201e41057422034100480d130240024020190d0020031021211a0c010b201a201941057420031025211a0b201a450d040b200441306a2105201a20194105746a2203200029038005370000200341186a2008290300370000200341106a200a290300370000200341086a200f290300370000201941016a211920102004470d000b0b202f450d00200710230b200042003702e402200041d8a7c3003602e00202402019450d0020194105742103201a2104034020004188036a41186a200441186a29000037030020004188036a41106a200441106a29000037030020004188036a41086a200441086a2900003703002000200429000037038803200041b0036a41186a4200370300200041b0036a41106a4200370300200041b0036a41086a4200370300200042003703b003200041003602d803200042083703d003200041b0056a200041e0026a20004188036a200041b0036a10ce01024020002802d0052205450d0020002802d405450d00200510230b200441206a2104200341606a22030d000b0b0240202d412c6c2204450d00202c20046a211f200041d0046a41106a211441d5fbc400ad42808080808001842118202c211303400240201328022841246c2204450d002013280220221220046a21200340200041c0016a201310c202200041c0016a41086a290300210e20002903c0012111200041d0046a41186a2208420037030020144200370300200041d0046a41086a22034200370300200042003703d004200041a0046a41086a220420181003220541086a290000370300200020052900003703a0042005102320032004290300370300200020002903a0043703d004200441d6a0c200ad4280808080d001841003220541086a290000370300200020052900003703a00420051023200041a0056a41086a20042903002206370300200020002903a00422013703a00520142001370000201441086a2006370000200041b0056a41086a2003290300370300200041b0056a41106a2014290300370300200041b0056a41186a2008290300370300200020002903d0043703b005200041a8016a200041b0056a412010890220004198016a20002903b001200041a8016a41106a290300427f420010e20420004188016a2011200e200029039801420020002802a80122041b22064201200642015620004198016a41086a290300420020041b22064200522006501b22041b2006420020041b10e204200041f8006a2000290388012206428094ebdc0380220e42002012220d3502202211420010e104200041f8006a41086a2903002000290378220120112006200e4280ec94a37c7e7c7e22062006428094ebdc038022064280ec94a37c7e7c4280cab5ee01562006a76aad7c2206200154ad7c210e200d41246a2112200041e0026a210420002802e402210a0240024003402004280200221041086a210320102f0106220f4105742104410021050240024003402004450d01200d2003412010de042208450d02200441606a2104200541016a2105200341206a21032008417f4a0d000b2005417f6a210f0b200a450d02200a417f6a210a2010200f4102746a41f8066a21040c010b0b201041e8026a200541306c6a21040240200d2013460d00200d2013412010de04450d002004427f2004290310221120067c220120012011542203200441186a22052903002211200e7c2003ad7c220120115420012011511b22031b3703102005427f200120031b37030020004188036a41186a220d201341186a29000037030020004188036a41106a2210201341106a29000037030020004188036a41086a220a201341086a2900003703002000201329000037038803200441286a2105200441206a2108024020042802282203200441246a280200470d00200341016a22042003490d172003410174220f2004200f20044b1b220fad42307e2211422088a70d172011a722214100480d170240024020030d002021102121040c010b2008280200200341306c2021102521040b2004450d0320082004360200200841046a200f360200200528020021030b2008280200200341306c6a220420002903880337030020042006370320200441186a200d290300370300200441106a2010290300370300200441086a200a290300370300200441286a200e3703002005200528020041016a3602000c010b2004427f2004290300221120067c220120012011542203200441086a22052903002211200e7c2003ad7c220120115420012011511b22031b3703002005427f200120031b3703002004427f2004290310221120067c220620062011542203200441186a22052903002206200e7c2003ad7c220e200654200e2006511b22031b3703102005427f200e20031b3703000b20122020460d020c010b0b202141081030000b2013412c6a2213201f470d000b0b4108213520004180056a41086a200041e0026a41086a280200360200200020002903e0023703800502400240024020190d0041002136410021120c010b201941057422044105752236ad42307e2206422088a70d112006a722034100480d11200310212235450d01201a20046a2119200041d0046a41106a21144100211241d5fbc400ad4280808080800184211820352110201a210a0340200a41086a2900002106200a41106a290000210e200a2900002111200041b0036a41186a2220200a41186a290000370300200041b0036a41106a2221200e370300200041b0036a41086a221f2006370300200020113703b003200a41206a210a20004180056a2104200028028405210f024003402004280200220d41086a2103200d2f01062213410574210441002105024003402004450d01200041b0036a2003412010de042208450d03200441606a2104200541016a2105200341206a21032008417f4a0d000b2005417f6a21130b0240200f450d00200f417f6a210f200d20134102746a41f8066a21040c010b0b41c9a3c20041da00104a000b20004188036a41186a2208202029030037030020004188036a41106a220f202129030037030020004188036a41086a2213201f290300370300200020002903b00337038803200d200541306c6a22044180036a290300210e200441f8026a2903002111200041d0046a41186a220d420037030020144200370300200041d0046a41086a22034200370300200042003703d004200041a0046a41086a220420181003220541086a290000370300200020052900003703a0042005102320032004290300370300200020002903a0043703d004200441d6a0c200ad4280808080d001841003220541086a290000370300200020052900003703a00420051023200041a0056a41086a20042903002206370300200020002903a00422013703a00520142001370000201441086a2006370000200041b0056a41086a2003290300370300200041b0056a41106a2014290300370300200041b0056a41186a200d290300370300200020002903d0043703b005200041e0006a200041b0056a4120108902200041d0006a2000290368200041e0006a41106a290300427f420010e204200041c0006a20002903504200200028026022041b220642012006420156200041d0006a41086a290300420020041b22064200522006501b22041b2006420020041b2011200e10e104201041186a2008290300370300201041106a200f290300370300201041086a20132903003703002010200029038803370300201041286a200041c0006a41086a29030037030020102000290340370320201241016a2112201041306a2110200a2019470d000b0b0240201e450d00201a10230b41002137024002402012410d2012410d491b220d0d004108212141002138410021290c010b200d41306c220410212221450d070240200d41306c22080d00200d2138410021290c010b41002105410021290340203520056a22042903002106200441086a290300210e200441106a2903002111200441186a2903002101202120056a220341286a200441286a290300370300200341206a200441206a290300370300200341186a2001370300200341106a2011370300200341086a200e37030020032006370300202941016a21292008200541306a2205470d000b200d21380b202941306c220441306e21030240024020040d00410121390c010b200341057422054100480d11200510212239450d06200321370b024002402021202120046a223a470d004100211d0c010b202941306c21054100211d2039210420212103034020042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a290000370000201d41016a211d200441206a2104200341306a2103200541506a22050d000b0b024002402035201241306c6a2035200d41306c6a6b22040d004108213b4100213c0c010b200441306e213c20044100480d1120041021223b450d050b024002402012410d4b0d004101213d4100213e203b21224101213f0c010b200d41306c201241306c22046b2105200420356a41506a21044100213e203b21030340200441086a2903002106200441106a290300210e200441186a290300211120042903002101200341286a200441286a290300370300200341206a200441206a290300370300200341186a2011370300200341106a200e370300200341086a200637030020032001370300200341306a2103200441506a2104203e41016a213e200541306a22050d000b203e41ffffff3f71203e470d11203e41057422044100480d1120041021223f450d04203b203e41306c6a21224100213d0b02400240203b2022470d004100211b0c010b4100211b203f2104203b2103034020042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a290000370000201b41016a211b200441206a21042022200341306a2203470d000b0b20294115490d0820294101762240ad42307e2206422088a70d0b2006a72204417f4c0d0b0240024020040d004108211c4108210a0c010b20041021221c450d03201c210a0b202141506a2141202141406a2142200041b0036a41506a212a4104211f41002143410021164100211220292125034020252110410021254101210d02402010417f6a2204450d000240024002400240024002402021200441306c6a220420212010417e6a220341306c6a2205412010de042208450d0020084100480d010c020b200429032020052903205a200441286a2903002206200541286a290300220e5a2006200e511b0d010b4100210802402003450d002042201041306c6a21040340024002400240200441606a200441b07f6a412010de042205450d00200541004e0d010c020b2004290300200441506a220529030054200441086a2903002206200541086a290300220e542006200e511b0d010b200321080c020b200441506a21042003417f6a22030d000b0b024020102008490d00201020294b0d03201020086b220d4101762205450d022041201041306c6a21042021200841306c6a21030340200041b0036a41286a220f200341286a2213290300370300200041b0036a41206a2214200341206a2220290300370300200041b0036a41186a2219200341186a221a290300370300200041b0036a41106a221e200341106a2226290300370300200041b0036a41086a2225200341086a2227290300370300200020032903003703b003200441086a22242903002106200441106a2217290300210e200441186a22282903002111200441206a222b2903002101200441286a22232903002118200320042903003703002013201837030020202001370300201a20113703002026200e370300202720063703002023200f290300370300202b2014290300370300202820192903003703002017201e29030037030020242025290300370300200420002903b003370300200441506a2104200341306a21032005417f6a22050d000c030b0b20082010103e000b024020030d004102210d410021250c040b2042201041306c6a21044102210d0240034002400240200441606a200441b07f6a412010de042203450d00200341004e0d010c030b2004290300200441506a220329030054200441086a2903002206200341086a290300220e542006200e511b0d020b200441506a21042010200d41016a220d470d000b410021252010210d0c040b2010200d6b21080b024020080d00200821250c030b0240200d41094d0d00200821250c030b0240201020294b0d00201020086b21052021200841306c6a2113034020102008417f6a2225490d030240201020256b220d4102490d00024002402021200841306c6a22042021202541306c6a220f412010de042203450d0020034100480d010c020b2004290320200f2903205a200441286a2903002206200f41286a290300220e5a2006200e511b0d010b200041b0036a41286a2214200f41286a2203290300370300200041b0036a41206a2220200f41206a2208290300370300200041b0036a41186a2219200f41186a221a290300370300200041b0036a41106a221e200f41106a2226290300370300200041b0036a41086a2227200f41086a22242903003703002000200f2903003703b003200f20042903003703002024200441086a2903003703002026200441106a290300370300201a200441186a2903003703002008200441206a2903003703002003200441286a290300370300410121030240200d4103490d004101210320132104034002400240202a2004460d00200441306a200041b0036a412010de042208450d0020084100480d010c030b200441d0006a29030020002903d0035a200441d8006a29030022062014290300220e5a2006200e511b0d020b200441286a200441d8006a290300370300200441206a200441d0006a290300370300200441186a200441c8006a290300370300200441106a200441c0006a290300370300200441086a200441386a2903003703002004200441306a2208290300370300200821042005200341016a2203470d000b0b200f200341306c6a220420002903b003370300200441286a2014290300370300200441206a2020290300370300200441186a2019290300370300200441106a201e290300370300200441086a20272903003703000b2025450d04200541016a2105201341506a211320252108200d410a4f0d040c000b0b20102008417f6a2225490d010b201020291036000b20252010103e000b02400240024020122043470d00204341016a22042043490d14204341017422032004200320044b1b220441ffffffff01712004470d14200441037422034100480d140240024020430d0020031021211f0c010b201f204341037420031025211f0b201f450d0120042143201621120b201f20124103746a2204200d36020420042025360200201641016a2212211620124102490d01024003400240024002400240201f2012417f6a22164103746a2204280200450d002012410374201f6a220841746a2802002205200428020422034d0d000240201241024b0d0020122116410221120c080b201f2012417d6a22194103746a2802042204200320056a4d0d010240201241034b0d0020122116410321120c080b200841646a280200200420056a4d0d01201221160c070b20124103490d0120042802042103201f2012417d6a22194103746a28020421040b20042003490d010b2012417e6a21190b0240024002400240024002402012201941016a22274b2224450d00201220194b2217450d01201f20194103746a221a2802042228201a2802006a2204201f20274103746a221e2802002226490d02200420294b0d032021202641306c6a220f201e280204222041306c22036a2105200441306c2108200420266b221020206b220420204f0d04201c2005200441306c220310dc041a200a20036a210d0240024020204101480d00200441014e0d010b20052104200a21080c060b204120086a21030340200541506a2104200d41506a2110024002400240200d2005460d0020102004412010de042213450d0020042108201341004e0d010c020b20042108200d41706a2213290300200541706a221429030054201341086a2903002206201441086a290300220e542006200e511b0d010b200521042010210d201021080b20032008290300370300200341286a200841286a290300370300200341206a200841206a290300370300200341186a200841186a290300370300200341106a200841106a290300370300200341086a200841086a2903003703000240200f2004490d00200a21080c070b200341506a210320042105200a2108200a200d490d000c060b0b4198bfc10020272012102d000b4198bfc10020192012102d000b20262004103e000b200420291036000b201c200f200310dc041a200a20036a210d0240024020204101480d00201020204a0d010b200f2104200a21080c010b202120086a2113200a2103200a2108200f21040340024002400240024020052003460d0020052003412010de042210450d00201041004e0d010c020b2005290320200329032054200541286a2903002206200341286a290300220e542006200e511b0d010b200341306a2108200521100c010b200541306a2110200521030b20042003290300370300200441286a200341286a290300370300200441206a200341206a290300370300200441186a200341186a290300370300200441106a200341106a290300370300200441086a200341086a290300370300200441306a2104201020134f0d012008210320102105200d20084b0d000b0b20042008200d20086b220320034130706b10dc041a02402017450d00201a2026360200201a41046a202820206a3602002024450d02201e201e41086a20122027417f736a41037410dd041a20162112201641014d0d040c010b0b41a8bfc10020192012102d000b41b8bbc000102b000b200341041030000b20250d000b02402043450d00201f10230b2040450d09201c10230c090b200341081030000b200341011030000b200441081030000b200441011030000b200441081030000b200541011030000b200441081030000b412041011030000b20294102490d002029417f6a21052021202941306c6a210a4100210d03400240024002400240202920052204417f6a2205490d00202920056b22034102490d03024002402021200441306c6a22042021200541306c6a2210412010de042208450d0020084100480d010c050b200429032020102903205a200441286a2903002206201041286a290300220e5a2006200e511b0d040b200041b0036a41286a220f201041286a2208290300370300200041b0036a41206a2213201041206a2214290300370300200041b0036a41186a2212201041186a2220290300370300200041b0036a41106a221f201041106a2219290300370300200041b0036a41086a221a201041086a221e290300370300200020102903003703b00320102004290300370300201e200441086a2903003703002019200441106a2903003703002020200441186a2903003703002014200441206a2903003703002008200441286a2903003703004101210420034103490d0241002108200a2104034002400240200041b0036a2004460d002004200041b0036a412010de042203450d0020034100480d010c040b200441206a29030020002903d0035a200441286a2903002206200f290300220e5a2006200e511b0d030b200441506a22032004290300370300200341286a200441286a290300370300200341206a200441206a290300370300200341186a200441186a290300370300200341106a200441106a290300370300200341086a200441086a290300370300200441306a2104200d200841016a2208470d000c020b0b20052029103e000b200841016a21040b2010200441306c6a220420002903b003370300200441286a200f290300370300200441206a2013290300370300200441186a2012290300370300200441106a201f290300370300200441086a201a2903003703000b200d41016a210d200a41506a210a20050d000b0b2030422088a7220441306c220341306d2110410021050240024002400240024002400240024020030d004101210a410021100c010b201041ffffff3f712010470d0d201041057422034100480d0d20031021220a450d010b2030a7210d02402004450d00200441306c210841002105200a2104203421030340200341086a2900002106200341106a290000210e20032900002111200441186a200341186a290000370000200441106a200e370000200441086a200637000020042011370000200541016a2105200441206a2104200341306a2103200841506a22080d000b0b0240200d450d00203410230b200041b0036a2039201d200a200510c602200041c4036a280200210d200041c0036a280200211920002802bc03211f20002802b403211a20002802b003212602402010450d00200a10230b200d41ffffff3f71200d470d07200d4105742210417f4c0d070240024020100d004101210a0c010b20101021220a450d020b4100211341002114410021120240200d450d00200d4105742105200a2104201f2103034020042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a290000370000200441206a2104200341206a2103200541606a22050d000b200d41057441606a41057641016a2112200d21140b200041b0036a41186a22084200370300200041b0036a41106a220f4200370300200041b0036a41086a22034200370300200042003703b003200041a0046a41086a2204419da0c200ad42808080808002841003220541086a290000370300200020052900003703a0042005102320032004290300370300200020002903a0043703b00320044183e0c400ad4280808080f000841003220541086a290000370300200020052900003703a0042005102320004188036a41086a20042903002206370300200020002903a004220e370388032002200e370000200241086a2006370000200041b0056a41086a2003290300370300200041b0056a41106a200f290300370300200041b0056a41186a2008290300370300200020002903b0033703b005200041b0036a200041b0056a10c00220002902b403420020002802b00322031b2206422088a7220541306c220841306d21040240024020080d004101210f0c010b200441ffffff3f712004470d0d200441057422084100480d0d20081021220f450d03200421130b2006a7211e2003410820031b21200240024020050d00410021050c010b200541306c210841002105200f2104202021030340200341086a2900002106200341106a290000210e20032900002111200441186a200341186a290000370000200441106a200e370000200441086a200637000020042011370000200541016a2105200441206a2104200341306a2103200841506a22080d000b0b0240201e450d00202010230b200a2012200f200510c70202402013450d00200f10230b02402014450d00200a10230b0240024020100d00410121140c010b201010212214450d040b4100210f4100210a410021100240200d450d00200d410574210520142104201f2103034020042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a290000370000200441206a2104200341206a2103200541606a22050d000b200d41057441606a41057641016a2110200d210a0b2015422088a7220341306c220541306d21040240024020050d004101210d0c010b200441ffffff3f712004470d0d200441057422054100480d0d20051021220d450d052004210f0b2015a721130240024020030d00410021050c010b200341306c210841002105200d2104203321030340200341086a2900002106200341106a290000210e20032900002111200441186a200341186a290000370000200441106a200e370000200441086a200637000020042011370000200541016a2105200441206a2104200341306a2103200841506a22080d000b0b02402013450d00203310230b200041b0036a203f201b200d200510c602200041c4036a2802002103200041c0036a280200210520002802bc032104024020002802b403450d0020002802b00310230b0240200f450d00200d10230b0240200a20106b200341057422034105752208490d00201020086a2112200a21200c060b201020086a22122010490d0c200a41017422082012200820124b1b222041ffffff3f712020470d0c202041057422084100480d0c02400240200a0d002008102121140c010b2014200a4105742008102521140b20140d05200841011030000b200341011030000b201041011030000b200841011030000b201041011030000b200541011030000b201420104105746a2004200310dc041a02402005450d00200410230b0240200c450d002009200c4105746a210a024020290d00201b410574210d200921080340200841086a2900002106200841106a290000210e20082900002111200041b0056a41186a200841186a290000370300200041b0056a41106a200e370300200041b0056a41086a2006370300200020113703b005200841206a2108200d2103203f21040240024003402003450d01200041b0056a2004460d02200341606a21032004200041b0056a412010de042105200441206a210420050d000c020b0b200041206a200041b0056a4280a094a58d1d420010c8022000290320200041206a41086a29030010c9020b2008200a470d000c020b0b201b410574210f20294101462113200921100340201041086a2900002106201041106a290000210e20102900002111200041b0056a41186a201041186a290000370300200041b0056a41106a200e370300200041b0056a41086a2006370300200020113703b00541002103024020130d0041002103202921050340200041b0036a41186a20212005410176220820036a220d41306c6a220441186a290000370300200041b0036a41106a200441106a290000370300200041b0036a41086a200441086a290000370300200020042900003703b003200d2003200041b0036a200041b0056a412010de044101481b2103200520086b220541014b0d000b0b201041206a2110200041b0036a41186a2021200341306c6a220441186a290000370300200041b0036a41106a200441106a290000370300200041b0036a41086a200441086a290000370300200020042900003703b003200f2103203f21040240200041b0036a200041b0056a412010de04450d00024003402003450d01200041b0056a2004460d02200341606a21032004200041b0056a412010de042105200441206a210420050d000c020b0b200041306a200041b0056a4280a094a58d1d420010c8022000290330200041306a41086a29030010c9020b2010200a470d000b0b0240200b450d00200910230b02402012450d0020124105742103201421040340200441086a2900002106200441106a290000210e20042900002111200041b0036a41186a200441186a290000370300200041b0036a41106a200e370300200041b0036a41086a2006370300200020113703b003200041106a200041b0036a4280a094a58d1d420010c8022000290310200041106a41086a29030010c902200441206a2104200341606a22030d000b0b02402020450d00201410230b200041b0036a41186a22084200370300200041b0036a41106a220d4200370300200041b0036a41086a22034200370300200042003703b003200041a0046a41086a2204419da0c200ad42808080808002841003220541086a290000370300200020052900003703a0042005102320032004290300370300200020002903a004220637038803200020063703b00320044183e0c400ad4280808080f000841003220541086a290000370300200020052900003703a0042005102320004188036a41086a20042903002206370300200020002903a004220e370388032032200e370000203241086a2006370000200041b0056a41086a2003290300370300200041b0056a41106a200d290300370300200041b0056a41186a2008290300370300200020002903b0033703b005200041003602b803200042013703b0032029200041b0036a105c0240024002402029450d002021210403402004200041b0036a1071200441286a2903002106200441206a290300210e0240024020002802b403220820002802b80322036b4110490d0020002802b00321050c010b200341106a22052003490d0b200841017422032005200320054b1b220d4100480d0b0240024020080d00200d102121050c010b20002802b0032008200d102521050b2005450d032000200d3602b403200020053602b00320002802b8032103200d21080b200520036a220d2006370008200d200e3700002000200341106a22033602b803203a200441306a2204470d000c030b0b20002802b803210320002802b403210820002802b00321050c010b200d41011030000b200041b0056aad428080808080048422112003ad4220862005ad84100202402008450d00200510230b200041b0036a41186a22084200370300200041b0036a41106a220d4200370300200041b0036a41086a22034200370300200042003703b003200041a0046a41086a2204419da0c200ad42808080808002841003220541086a290000370300200020052900003703a0042005102320032004290300370300200020002903a004220637038803200020063703b003200441eeacc200ad42808080809001841003220541086a290000370300200020052900003703a0042005102320004188036a41086a20042903002206370300200020002903a004220e370388032032200e370000203241086a2006370000200041b0056a41086a2003290300370300200041b0056a41106a200d290300370300200041b0056a41186a2008290300370300200020002903b0033703b005200041003602b803200042013703b003203e200041b0036a105c02400240203d450d0020002802b803210320002802b403210820002802b00321050c010b203b210403402004200041b0036a1071200441286a2903002106200441206a290300210e0240024020002802b403220820002802b80322036b4110490d0020002802b00321050c010b200341106a22052003490d09200841017422032005200320054b1b220d4100480d090240024020080d00200d102121050c010b20002802b0032008200d102521050b2005450d052000200d3602b403200020053602b00320002802b8032103200d21080b200520036a220d2006370008200d200e3700002000200341106a22033602b8032022200441306a2204470d000b0b20112003ad4220862005ad84100202402008450d00200510230b2029ad42307e2206422088a70d012006a72204417f4c0d010240024020040d00410821100c010b200410212210450d040b02400240203a2021470d00410021050c010b202941306c21084100210520102104202121030340200341086a2903002106200341106a290300210e200341186a290300211120032903002101200441286a200341286a290300370300200441206a200341206a290300370300200441186a2011370300200441106a200e370300200441086a200637030020042001370300200441306a2104200541016a2105200341306a2103200841506a22080d000b0b2005ad42307e2206422088a70d012006a72204417f4c0d010240024020040d004108210a0c010b20041021220a450d050b410021080240200541306c220d450d0041002108200a2104201021030340200341086a2903002106200341106a290300210e200341186a290300211120032903002101200441286a200341286a290300370300200441206a200341206a290300370300200441186a2011370300200441106a200e370300200441086a200637030020042001370300200441306a2104200841016a2108200341306a2103200d41506a220d0d000b0b200041c0036a2008360200200041bc036a2005360200200041b8036a200a360200200041003a00b4032000410b3a00b003200020002f00b0053b00b5032000200041b2056a2d00003a00b703200041b0036a108e0102402029450d00201010230b02402019450d00201f10230b0240201a450d00202610230b0240203e450d00203f10230b0240203c450d00203b10230b02402037450d00203910230b02402038450d00202110230b02402036450d00203510230b200028028805210d20002802800521040240024020002802840522050d00200421030c010b2005210820042103034020032802f80621032008417f6a22080d000b0340200420042f01064102746a41f8066a28020021042005417f6a22050d000b0b200041cc036a20042f010636020041002114200041c8036a4100360200200041c4036a20043602002000200d3602d003200041003602c003200042003703b803200020033602b403200041003602b003200041b0036a10d4010240202d450d00202d412c6c2103202c41206a210403400240200441046a280200450d00200428020010230b2004412c6a2104200341546a22030d000b0b200041b0056a210d202e450d00202c10230b200041b0036a41186a22054200370300200041b0036a41106a22084200370300200041b0036a41086a22034200370300200042003703b003200041a0046a41086a2204419da0c200ad428080808080028422061003221041086a290000370300200020102900003703a0042010102320032004290300370300200020002903a004220e370388032000200e3703b003200441e4acc200ad4280808080a001841003221041086a290000370300200020102900003703a00420101023200820002903a004220e370300200041b0056a41086a22102003290300370300200041b0056a41106a220a200e370300200041b0056a41186a220f20042903003703002000200e37038803200020002903b0033703b005200dad4280808080800484220e1005200542003703002008420037030020034200370300200042003703b003200420061003221341086a290000370300200020132900003703a0042013102320032004290300370300200020002903a004221137038803200020113703b0032004418c92c300ad4280808080e0018422111003221341086a290000370300200020132900003703a0042013102320052004290300220137030020102003290300370300200a20002903a0042218370300200f20013703002000201837038803200020002903b0033703b005200041086a200d4120108f012000280208210d200028020c2113200542003703002008420037030020034200370300200042003703b003200420061003220841086a290000370300200020082900003703a0042008102320032004290300370300200020002903a004220637038803200020063703b003200420111003220841086a290000370300200020082900003703a0042008102320052004290300220637030020102003290300370300200a20002903a0042211370300200f20063703002000201137038803200020002903b0033703b0052000201341016a4101200d1b3602b003200e200041b0036aad4280808080c0008410020240024020070d00200b450d062014410173450d010c060b2014450d050240202f450d00200710230b0240202d450d00202d412c6c2103202c41206a210403400240200441046a280200450d00200428020010230b2004412c6a2104200341546a22030d000b0b0240202e450d00202c10230b200b450d050b200910230c040b102f000b200d41011030000b200441081030000b200441081030000b200041e0056a24000f0b102a000bbd0201027f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100410900102400240200228021022010d00200041003602000c010b200228021421032002200241106a41086a28020036022420022001360220200241c8006a200241206a108401024002402002280248450d0020002002290348370200200041086a200241c8006a41086a2802003602000c010b20024100360230200242013703282002410c36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c20024198c2c3003602482002200241386a360258200241c4006a41b8a3c500200241c8006a102e1a2002350230422086200235022884100820004100360200200228022c450d00200228022810230b2003450d00200110230b200241e0006a24000bc60303047f017e017f230041d0006b22012400200141c0006a41086a2202419da0c200ad42808080808002841003220341086a2900003703002001200329000037034020031023200141206a41086a220420022903003703002001200129034037032020024190a0c200ad4280808080d001841003220341086a2900003703002001200329000037034020031023200141306a41086a20022903002205370300200141086a2004290300370300200141186a20053703002001200129034022053703302001200129032037030020012005370310024002404101450d004120210302400240024002404120450d004120102122020d01412041011030000b411021030240411010212202450d00200141106a210420022001290300370000200241086a200141086a2903003700000c020b411041011030000b20022001290300370000200241086a200141086a290300370000200141106a210441204110470d010b20022003200341017422064120200641204b1b220610252202450d02200621030b20022004290000370010200241186a200441086a290000370000200041203602082000200336020420002002360200200141d0006a24000f0b102f000b200641011030000bff0202057f027e230041e0006b22022400200241c0006a41086a2203419da0c200ad42808080808002841003220441086a2900003703002002200429000037034020041023200241206a41086a2205200329030037030020022002290340370320200341a3a4c200ad4280808080f000841003220441086a2900003703002002200429000037034020041023200241306a41086a2206200329030037030020022002290340370330200241c0006a200110ac01024041c000102122040d0041c00041011030000b200420022903203700002004200229033037001020042002290040370020200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241c0006a41106a290000370000200441386a200241c0006a41186a290000370000200241086a200441c000108902200241086a41106a290300210720022903102108200228020821032004102320002007420020031b37030820002008420020031b370300200241e0006a24000bac2e07017f017e017f027e017f027e187f23004180036b2207240002400240024002402001200284500d002003200484500d004201210820074198016a200320012003200156200420025620042002511b22091b220a2004200220091b220b20054201200542015620064200522006501b220c1b220520064200200c1b220610e20420074188016a200729039801220d20074198016a41086a290300220e2005200610e1042002200420091b21022001200320091b2104200a20072903880185200b20074188016a41086a290300858450450d01200d210a200e210b420021060c020b20004100360200200041106a4200370300200041086a42003703000c020b200741f8006a200420022005200610e204200741e8006a20072903782201200741f8006a41086a29030022032005200610e1044200200620042007290368852002200741e8006a41086a29030085845022091b21064201200520091b21082003200220091b21022001200420091b21040b200741386a200b42002004420010e104200741c8006a20024200200a420010e104200741d8006a200a42002004420010e104024002400240024002400240024002400240024002400240024002400240024002400240024002400240200b420052200242005271200729034042005272200729035042005272200741d8006a41086a2903002201200729033820072903487c7c2203200154724101470d00411010212209450d032009200a3e020c2009200a4220883e02082009200b3e02042009200b4220883e020020074284808080c00037029c02200720093602980220074198026a10d004200741a8016a41086a20072802a00236020020072007290398023703a801411010212209450d02200920043e020c200920044220883e0208200920023e0204200920024220883e020020074284808080c00037029c02200720093602980220074198026a10d004200741b8016a41086a20072802a00236020020072007290398023703b801411010212209450d0120092008a7220f36020c200920084220883e0208200920063e0204200920064220883e020020074284808080c00037029c02200720093602980220074198026a10d00420072802a0022110200728029c0221112007280298022112200741f0026a41086a200741b8016a41086a280200360200200720072903b8013703f00220074198026a41086a200741a8016a41086a280200360200200720072903a80137039802200741c8016a20074198026a200741f0026a10d204024020072802f402450d0020072802f00210230b200741c8016a10d00420104101460d0420072802cc01211320072802c80121142010450d0e2012280200450d0e024020072802d0012215450d002014280200450d0f201520104d0d0f200720103602d401201520106b221641016a22174101201741014b1b221841ffffffff03712018470d0620184102742209417f4c0d0602400240024020090d00410421190c010b200910272219450d010b201041ffffffff03712010470d072010410274221a417f4c0d07024002400240201a0d004104211b0c010b201a1027221b450d010b410221094101210f2012280200220c67221c211d0240200c41ffffffff034b0d0041022109201c210c4101210f034020094101200c4101711b200f6c210f200c41034b211e200920096c2109200c410176221d210c201e0d000b0b200720153602f802200720133602f402200720143602f002024041041021220c450d00200c20094101201d4101461b200f6c220f360200200742818080801037029c022007200c36029802200741d8016a200741f0026a20074198026a10d204200c1023024002400240201a0d00410421090c010b201a10212209450d010b20092012201041027410dc042109200720103602f802200720103602f402200720093602f0020240410410212209450d002009200f360200200742818080801037029c022007200936029802200741e8016a200741f0026a20074198026a10d20420091023024002400240024020072802d40120176a220920072802e001220c4d0d00024002402009200c6b22090d004104210f410021090c010b200941ffffffff03712009470d032009410274221e4100480d03201e1021220f450d02200f4100200941027410db041a0b20072802d801211d2009211e0240200c450d002009200c6a221e2009490d0320094101742214201e2014201e4b1b221e41ffffffff0371201e470d03201e41027422144100480d030240024020090d0020141021210f0c010b200f200941027420141025210f0b200f450d040b200f20094102746a201d200c41027410dc041a2009200c6a2109024020072802dc01450d00201d10230b200720093602e0012007201e3602dc012007200f3602d8010b200741e8016a10d00402400240024002400240024002400240024002400240034020072016221f3602f401024020072802e001220920072802d401220c201f6a220f417f736a221e2009490d0041d4b2c600201e2009102d000b0240024002400240024002400240024002400240024002400240024002400240024020092009200f6b220f4d0d0020072802f00122092009200c6b220c4d0d0120072802e801200c4102746a35020022024200510d02201f201f4100476b211620072802d8012209201e4102746a35020021012009200f4102746a3502002104200741003602f80120072004200142208684200280220137038002200741003602880220072004200120027e7d42ffffffff0f83370390022007200741f4016a3602ac022007200741d8016a3602a8022007200741d4016a3602a4022007200741e8016a3602a002200720074188026a36029c022007200741f8016a3602980220074198026a10d3041a034020072802880241016a41004c0d04024020072903900242ffffffff0f560d0020074198026a10d3040d010b0b2007290380022102200720072802d40120072802f40122096a3602f402200720093602f0022007200741d8016a3602fc02200741023a00f802200741b0026a200741f0026a10d60420072802f001220941ffffffff03712009470d2b2009410274220c417f4c0d2b20072802e801210f02400240200c0d004104211e0c010b200c1021221e450d050b201e200f200c10dc04210c200720093602e802200720093602e4022007200c3602e002410810212209450d0520092002a72220360204200920024220883e020020074282808080203702f402200720093602f002200741c0026a200741e0026a200741f0026a10d2042009102320072802b802222120072802c8022222202120224b1b22144101201441014b1b220c41ffffffff0371200c470d2b200c410274220f417f4c0d2b20072802b402212320072802b002212402400240200f0d00410421250c010b200f10272225450d070b2014450d092022417f6a221720224b211520072802c00221262021417f6a221a20214b0d07200c417f6a21092025200f6a417c6a211d4100210f4200210203404100211e02402021201a200f6b22134d0d004100211e2013201a4b0d00202420134102746a280200211e0b201ead21044100211e024020150d0020222017200f6b22134d0d00201320174b0d00202620134102746a280200211e0b024002402004201ead22037d22012004560d00200120027d220a2001560d00200a42ffffffff0f832104420021020c010b20044280808080108420027d20037d2104420121020b200c20094d0d0c201d20043e0200201d417c6a211d2009417f6a2109200f41016a220f2014490d000c090b0b41d4b2c600200f2009102d000b41d4b2c600200c2009102d000b41c8b3c600102b000b4187b5c6004118200741f0026a41a0b5c6001031000b200c41041030000b410841041030000b200f41041030000b200c417f6a21092025200f6a417c6a211e4100211d4200210203404100210f024020150d004100210f20222017201d6b22134d0d004100210f201320174b0d00202620134102746a280200210f0b024002404200200fad22017d22044200520d00200420027d22032004560d00200342ffffffff0f832104420021020c010b428080808010200220017c7d2104420121020b200c20094d0d04201e20043e0200201e417c6a211e2009417f6a2109201d41016a221d2014490d000b0b41012113200250450d010b410021130b02402023450d00202410230b20072802d401221e20072802f401220f6a2215201e490d05200f20154f0d01200f417f7321090340200c200c200f6a20096a221d4d0d03200920072802e00122146a220f20094f0d0420072802d801200f4102746a2025201d4102746a2802003602002009417f6a210920072802f401210f201e417f6a221e0d000c050b0b41b8b3c6002009200c102d000b201e450d020c030b41d4b2c60020222021202220214b1b22074101200741014b1b200f6a20096a200c102d000b41b8b3c600200f2014102d000b200c200c2015417f7322096a200f6a220f4d0d0220072802e001220c20096a2209200c4f0d0320072802d80120094102746a2025200f4102746a28020036020020072802f401210f0b2018200f417f736a220920184f0d03201920094102746a202036020002402013450d00201820072802f401417f736a220920184f0d05201920094102746a22092009280200417f6a36020020072802f401210920072802d401210c200741023a00f8022007200c20096a3602f402200720093602f0022007200741d8016a3602fc02200741d0026a200741f0026a10d60420072802f001220941ffffffff03712009470d1b2009410274220c417f4c0d1b20072802e801210f02400240200c0d004104211e0c010b200c1021221e450d070b201e200f200c10dc04210c200720093602f802200720093602f4022007200c3602f002200741e0026a200741f0026a200741d0026a10d104024020072802d401220920072802f40122146a220c2009490d00024002402014200c4f0d00200c417f73210920072802e002211320072802e802210f2014211e0340200f200f201e6a20096a221e4d0d0b200920072802e00122156a221d20094f0d0c20072802d801201d4102746a2013201e4102746a280200360200200941016a210920072802f401211e2014200c417f6a220c490d000c020b0b20090d0120072802e802210f2014211e0b201e2014417f7322096a220c200f6a221e200c4f0d0a20072802e001220c20096a2209200c4f0d0b20072802d80120094102746a20072802e002201e4102746a2802003602000b024020072802e402450d0020072802e00210230b20072802d402450d0020072802d00210230b20251023024020072802c402450d0020072802c00210230b201f0d000b0240201c450d004101210920072802d401220c4101460d1f4100200c6b2114201c411f7121134100201c6b411f7121152010410274201b6a417c6a210c417f210903400240200920072802e001221e6a220f2009490d0041d4b2c600200f201e102d000b201e200f417f6a221d4d0d0b201020096a221e20104f0d0c200c20072802d801221e201d4102746a280200201574201e200f4102746a28020020137672360200200c417c6a210c20142009417f6a2209460d1f0c000b0b20072802e001211020072802dc01210f20072802d801211e201b1023410021090c1f0b41d4b2c600200f200c102d000b41b8b3c6002009200c102d000b41b8b3c60020092018102d000b41d4b2c60020092018102d000b200c41041030000b41d4b2c600201e200f102d000b41b8b3c600201d2015102d000b41d4b2c600201e200f102d000b41b8b3c6002009200c102d000b41d4b2c600200f417f6a201e102d000b41b8b3c600201e2010102d000b201e41041030000b102a000b201441041030000b410441041030000b201a41041030000b410441041030000b201a41041030000b200941041030000b41d4b2c60041004100102d000b200741286a200729035820032008200610e20420004100360200200041106a200741286a41086a290300370300200041086a20072903283703000c140b411041041030000b411041041030000b411041041030000b20074198026a41086a200741c8016a41086a280200221d360200200720072903c80137039802201d4101201d41014b1b221e41ffffffff0371201e470d00201e4102742209417f4c0d000240024020090d004104211a0c010b20091027221a450d020b201d450d03201d417f6a2114201a201e201d6b22134102746a210c200f4101200f41014b1bad21024200210441002109200728029802210f0340201e201320096a22154d0d03200c2004422086200f35020084220420028022013e020020142009460d04200c41046a210c200f41046a210f2004200120027e7d2104201d200941016a22094b0d000b41d4b2c6002009201d102d000b102f000b200941041030000b41b8b3c6002015201e102d000b2007201e3602f8022007201e3602f4022007201a3602f002200728029c02450d0720072802980210230c070b20072802d40121090b20072802e001220c200c20096b220f4d0d012010201020096b22094d0d02201b20094102746a20072802d801200f4102746a280200201c411f7176360200410121092010210f201b211e0b024020072802ec01450d0020072802e80110230b2009450d0320072802dc01450d0320072802d80110230c030b41d4b2c600200f200c102d000b41b8b3c60020092010102d000b4100211902402013450d00201410230b0b410410212209450d012009410036020041041021220c450d02200c41003602004101211d0240024020190d002009211941012118200c211e4101210f410121100c010b20091023200c10230b2007201836028002200720183602fc01200720193602f801200720103602a0022007200f36029c022007201e3602980220074198026a10d004420021020240024020072802a00222094105744180014d0d00421d21040c010b4100211d024020090d00420021040c010b200728029802220c200941027422096a417c6a220f280200211e0240200c200f470d00201ead21040c010b200c41786a210f201ead2104200741206a211e4120210c420021020340200741186a200f20096a3502004200200c41e0007110df04201e29030020027c2007290318220220047c2204200254ad7c2102200c41206a210c2009417c6a22094104470d000b0b0240200728029c02450d0020072802980210230b201d0d030240200420084201882006423f8684562002200642018822045620022004511b450d0020074188026a41086a200741f8016a41086a280200360200200720072903f80137038802411010212209450d0520094280808080103702082009420037020020074284808080c00037029c02200720093602980220074198026a10d004200741f0026a41086a20072802a00236020020072007290398023703f002200741f8016a20074188026a200741f0026a10d10420072802f402450d0020072802f00210230b200741f0026a41086a200741f8016a41086a280200360200200720072903f8013703f0020b200741f0026a10d00420074198026a41086a2209200741f0026a41086a280200360200200720072903f0023703980220074198026a10d0044200210202400240200928020022094105744180014d0d00421d21044101211d0c010b4100211d024020090d00420021040c010b200728029802220c200941027422096a417c6a220f280200211e0240200c200f470d00201ead21040c010b200c41786a210f201ead2104200741106a211e4120210c420021020340200741086a200f20096a3502004200200c41e0007110df04201e29030020027c2007290308220220047c2204200254ad7c2102200c41206a210c2009417c6a22094104470d000b0b0240200728029c02450d0020072802980210230b02400240201d0d00200041106a2002370300200041086a2004370300410021090c010b20004190b6c600360204200041086a4119360200410121090b200020093602002011450d04201210230c040b410441041030000b410441041030000b200720043e029c02200741eab4c6003602980241d0b5c600412f20074198026a4180b6c6001031000b411041041030000b20074180036a24000bd30201037f230041d0006b220824000240024002402002200685200320078584500d00200220038450450d01410121090c020b417f20002004852001200585844200522000200454200120055420012005511b1b21090c010b0240200620078450450d0041ff0121090c010b200841206a2000200110d704200841306a2006200710d704200841c0006a41086a2209200841206a41086a220a280200360200200820082903203703402008200841c0006a200841306a10d20402402008280234450d00200828023010230b200841206a2004200510d704200841306a2002200310d7042009200a28020036020020082008290320370340200841106a200841c0006a200841306a10d20402402008280234450d00200828023010230b2008200841106a10d404210902402008280214450d00200828021010230b2008280204450d00200828020010230b200841d0006a240020090beb0203017f047e017f230041d0006b2202240002400240200029031022032001290310220485200041186a2903002205200141186a29030022068584500d00200241206a2000290300200041086a29030010d704200241306a2004200610d704200241c0006a41086a2200200241206a41086a2207280200360200200220022903203703402002200241c0006a200241306a10d20402402002280234450d00200228023010230b200241206a2001290300200141086a29030010d704200241306a2003200510d7042000200728020036020020022002290320370340200241106a200241c0006a200241306a10d20402402002280234450d00200228023010230b2002200241106a10d404210002402002280214450d00200228021010230b200041ff0171210002402002280204450d00200228020010230b20004521000c010b2000290300200129030085200041086a290300200141086a29030085845021000b200241d0006a240020000bc40901157f230041206b220524002003410020041b21062001410020021b2107200341206a200320041b2108200141206a200120021b2109200120024105746a210a200320044105746a210b4100210c4100210d4101210e4100210f410021104101211102400340200c4101742112200c410574211302400240024002400340024020060d0020082114200e2115200d2116200c21020c040b2006210120082103200e2115200d2116200c2102201321042012211702400340024002402007450d0020012007460d0620012007412010de042214450d062014417f4c0d01200321082015210e2016210d2002210c200121060c080b200541186a2203200641186a290000370300200541106a2202200641106a290000370300200541086a2207200641086a290000370300200520062900003703000240200c200d470d00200c41016a2201200c490d0a200c41017422042001200420014b1b220d41ffffff3f71200d470d0a200d41057422014100480d0a02400240200c0d0020011021210e0c010b200e200c41057420011025210e0b200e450d030b200e200c4105746a22012005290300370000200141186a2003290300370000200141106a2002290300370000200141086a200729030037000041002107410020082008200b4622011b2106201241026a2112201341206a2113200c41016a210c2008200841206a20011b21080c030b200541186a2214200141186a290000370300200541106a2218200141106a290000370300200541086a2219200141086a29000037030020052001290000370300024020022016470d00200241016a22012002490d0920172001201720014b1b221641ffffff3f712016470d09201641057422014100480d090240024020020d002001102121150c010b201520042001102521150b2015450d040b201520046a22012005290300370000200141186a2014290300370000200141106a2018290300370000200141086a2019290300370000410020032003200b4622141b2101201741026a2117200441206a2104200241016a21022003200341206a20141b221421032001450d050c000b0b0b200141011030000b200141011030000b2015210e2016210d2002210c2003200341206a2003200b4622011b2108410020092009200a4622021b21074100200320011b21062009200941206a20021b21090c020b41002106024020070d002000201536020c2000200f3602082000201036020420002011360200200041146a2002360200200041106a2016360200200541206a24000f0b201421082015210e2016210d2002210c0b200541186a2203200741186a290000370300200541106a2202200741106a290000370300200541086a2204200741086a2900003703002005200729000037030002400240200f2010470d00200f41016a2201200f490d03200f41017422072001200720014b1b221041ffffff3f712010470d03201041057422014100480d0302400240200f0d002001102121110c010b2011200f4105742001102521110b2011450d010b2011200f4105746a22012005290300370000200141186a2003290300370000200141106a2002290300370000200141086a2004290300370000410020092009200a4622011b2107200f41016a210f2009200941206a20011b21090c010b0b200141011030000b102a000b9e1008087f027e047f017e057f027e017f057e230022042105200441a0016b416071220424000240024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610212207450d020b410021084100210602402001450d002001410574210820072106034020062000290000370000200641186a200041186a290000370000200641106a200041106a290000370000200641086a200041086a290000370000200641206a2106200041206a2100200841606a22080d000b200141057441606a41057641016a2106200121080b200420063602102004200836020c2004200736020820072006410041202006676b109303200441e0006a41186a22094200370300200441e0006a41106a220a4200370300200441e0006a41086a220b420037030020044200370360200441286a41086a2208418881c400ad4280808080b00284220c1003220041086a2900003703002004200029000037032820001023200b200829030037030020042004290328370360200841f980c400ad42808080809001841003220041086a2900003703002004200029000037032820001023200a2004290328220d370300200441c0006a41086a220e200b290300370300200441c0006a41106a220f200d370300200441c0006a41186a221020082903003703002004200d3703900120042004290360370340200441e0006a200441c0006a412010bb0120042802602200410120001b21112004290264420020001b2212422088a72200450d0320004105742113200441e0006a4114722114200441e0006a4108722115200441c0006a410c722116200441e0006a410c6a2117201121060340200641086a290000210d200641106a2900002118200629000021192009200641186a290000370300200a2018370300200b200d370300200420193703602008200c1003220041086a2900003703002004200029000037032820001023200441186a41086a22012008290300370300200420042903283703182008418281c400ad4280808080e000841003220041086a290000370300200420002900003703282000102320044190016a41086a220720082903003703002004200429032837039001200441c0006a200441e0006a10ac0141c00010212200450d0320002004290318370000200020042903900137001020002004290040370020200041086a2001290300370000200041186a2007290300370000200041286a200e290000370000200041306a200f290000370000200041386a2010290000370000200441e0006a200041c00010a7032008201741086a290200370300200441286a41106a221a201741106a28020036020020042017290200370328024020042802682201450d002004290360210d20162004290328370200201641086a2008290300370200201641106a201a2802003602002004200d3703400b20042001360248200441003602682004290358211920042004290378221b3703582004290350211c20042004290370221d3703502004290340211e2004200429036022183703402004290348210d20042004290368221f370348201fa7210102400240200da7221a0d00201f210d201d211c201b21190c010b2004201e3703602004200d3703682004201c370370200420193703782004201a201ca74105746a3602342004201a3602302004200d422088a736022c2004201a3602282004200441086a36023820044190016a200441286a108601201541086a200728020036020020152004290390013702002004201c422088a7221a2019422088a74105746a3602342004201a36023020042019a736022c2004201a3602282004200441086a36023820044190016a200441286a108601201441086a200728020036020020142004290390013702002004290368210d20042903602118200429037821192004290370211c02402001450d00201ba721070240201f422088a7450d00200110230b2007450d00201d422088a710230b200420183703402004200d3703482004201c37035020042019370358200da721010b200420183703602004200d3703682004201c370370200da72107200420193703780240024020010d002000ad428080808080088410050c010b200441c00036022c20042000360228200441e0006a200441286a10ce030b02402007450d002019a721010240200d422088a7450d00200710230b2001450d00201c422088a710230b200641206a210620001023201341606a22130d000c040b0b102f000b200641011030000b41c00041011030000b02402012a7450d00201110230b200441c0006a41186a4200370300200441c0006a41106a22014200370300200441c0006a41086a2206420037030020044200370340200441286a41086a2200418881c400ad4280808080b002841003220841086a29000037030020042008290000370328200810232006200029030037030020042004290328220d3703182004200d37034020004183e0c400ad4280808080f000841003220841086a290000370300200420082900003703282008102320012004290328220d370300200441e0006a41086a2006290300370300200441e0006a41106a200d370300200441e0006a41186a20002903003703002004200d370390012004200429034037036020044100360248200442013703402003200441c0006a105c02402003450d002003410574210003402002200441c0006a1071200241206a2102200041606a22000d000b0b20042802442100200441e0006aad4280808080800484200435024842208620042802402206ad84100202402000450d00200610230b0240200428020c450d00200428020810230b200524000bb70302057f027e230041e0006b22042400200441c0006a41086a220541d5fbc400ad42808080808001841003220641086a2900003703002004200629000037034020061023200441206a41086a2207200529030037030020042004290340370320200541eea0c200ad4280808080f001841003220641086a2900003703002004200629000037034020061023200441306a41086a2208200529030037030020042004290340370330200441c0006a200110ac01024041c000102122060d0041c00041011030000b200620042903203700002006200429033037001020062004290040370020200641086a2007290300370000200641186a2008290300370000200641286a2005290000370000200641306a200441c0006a41106a290000370000200641386a200441c0006a41186a290000370000200441086a200641c000108902200441086a41106a29030021092004290310210a20042802082105200610232001200a420020051b220a2002200a200a2002562009420020051b220920035620092003511b22061b22027d20092003200920061b22037d200a200254ad7d10ca022000200337030820002002370300200441e0006a24000bf00508017f017e047f017e017f017e037f017e230041e0016b22022400200241186a20002001108703200241186a41106a2903002101200229032021000240024020022903182203a7450d00200241e0006a109302200241e0006a2000200110da02200241f8006a2001370300200241e0006a41106a2000370300200241e8006a41053a00002002410d3a0060200241e0006a108e010c010b2003500d00200241e0006a41186a22044200370300200241e0006a41106a22054200370300200241e0006a41086a2206420037030020024200370360200241d0016a41086a220741d5fbc400ad428080808080018422081003220941086a290000370300200220092900003703d0012009102320062007290300370300200220022903d001220337035020022003370360200741d6a0c200ad4280808080d00184220a1003220941086a290000370300200220092900003703d00120091023200520022903d0012203370300200241306a41086a220b2006290300370300200241306a41106a220c2003370300200241306a41186a220d200729030037030020022003370350200220022903603703302002200241306a4120108902200241106a29030021032002290308210e2002280200210920044200370300200542003703002006420037030020024200370360200720081003220541086a290000370300200220052900003703d0012005102320062007290300370300200220022903d0012208370350200220083703602007200a1003220541086a290000370300200220052900003703d00120051023200420072903002208370300200b2006290300370300200c20022903d001220a370300200d20083703002002200a37035020022002290360370330200242002003420020091b220320017d200e420020091b2201200054ad7d2208200120007d2200200156200820035620082003511b22071b37036820024200200020071b370360200241306aad4280808080800484200241e0006aad428080808080028410020b200241e0016a24000bbc0902057f017e230041c0016b22032400200341d0006a41086a220441d5fbc400ad42808080808001841003220541086a2900003703002003200529000037035020051023200341306a41086a2206200429030037030020032003290350370330200441eea0c200ad4280808080f001841003220541086a2900003703002003200529000037035020051023200341c0006a41086a2207200429030037030020032003290350370340200341d0006a200010ac0102400240024041c00010212205450d00200520032903303700002005200329034037001020052003290050370020200541086a2006290300370000200541186a2007290300370000200541286a2004290000370000200541306a200341e0006a290000370000200541386a200341d0006a41186a29000037000020032001370350200320023703582005ad4280808080800884200341d0006aad42808080808002841002200510230240200142ffc7afa0255620024200522002501b0d00200341d0006a41086a220441d5fbc400ad42808080808001841003220541086a2900003703002003200529000037035020051023200341306a41086a2206200429030037030020032003290350370330200441eea0c200ad4280808080f001841003220541086a2900003703002003200529000037035020051023200341c0006a41086a2207200429030037030020032003290350370340200341d0006a200010ac0141c00010212205450d02200520032903303700002005200329034037001020052003290050370020200541086a2006290300370000200541186a2007290300370000200541286a2004290000370000200541306a200341d0006a41106a290000370000200541386a200341d0006a41186a290000370000200341186a200541c000108902200341186a41106a2903002102200329032021010240200329031822084201520d002005ad428080808080088410050b2005102302402001200284500d002008a7450d002001200210cb020b200341d0006a41086a220441d5fbc400ad42808080808001841003220541086a2900003703002003200529000037035020051023200341306a41086a2206200429030037030020032003290350370330200441e3a0c200ad4280808080b001841003220541086a2900003703002003200529000037035020051023200341c0006a41086a2207200429030037030020032003290350370340200341d0006a200010ac0141c00010212205450d03200520032903303700002005200329034037001020052003290050370020200541086a2006290300370000200541186a2007290300370000200541286a2004290000370000200541306a200341d0006a41106a290000370000200541386a200341d0006a41186a2900003700002003200541c000108902200341106a290300210220032802002104200329030821012005102302402001200284500d0020040d010b200010ab01200341d0006a41086a41013a0000200341d9006a2000290000370000200341e1006a200041086a290000370000200341e9006a200041106a290000370000200341f1006a200041186a290000370000200341023a0050200341d0006a108e010b200341c0016a24000f0b41c00041011030000b41c00041011030000b41c00041011030000b890a08017f017e047f017e017f017e037f017e230041b0016b22022400200241386a20002001108703200241386a41106a29030021012002290340210002400240024020022903382203a7450d00200241f0006a41186a22044200370300200241f0006a41106a22054200370300200241f0006a41086a2206420037030020024200370370200241a0016a41086a220741d5fbc400ad428080808080018422081003220941086a290000370300200220092900003703a0012009102320062007290300370300200220022903a00122033703900120022003370370200741d6a0c200ad4280808080d00184220a1003220941086a290000370300200220092900003703a00120091023200520022903a0012203370300200241d0006a41086a220b2006290300370300200241d0006a41106a220c2003370300200241d0006a41186a220d2007290300370300200220033703900120022002290370370350200241206a200241d0006a4120108902200241206a41106a29030021032002290328210e2002280220210920044200370300200542003703002006420037030020024200370370200720081003220541086a290000370300200220052900003703a0012005102320062007290300370300200220022903a001220837039001200220083703702007200a1003220541086a290000370300200220052900003703a00120051023200420072903002208370300200b2006290300370300200c20022903a001220a370300200d20083703002002200a3703900120022002290370370350200242002003420020091b220320017d200e420020091b2201200054ad7d2208200120007d2200200156200820035620082003511b22071b37037820024200200020071b370370200241f0006a2107200241d0006a21060c010b2003500d01200241f0006a41186a22044200370300200241f0006a41106a22054200370300200241f0006a41086a2206420037030020024200370370200241a0016a41086a220741d5fbc400ad428080808080018422081003220941086a290000370300200220092900003703a0012009102320062007290300370300200220022903a00122033703900120022003370370200741d6a0c200ad4280808080d00184220a1003220941086a290000370300200220092900003703a00120091023200520022903a0012203370300200241d0006a41086a220b2006290300370300200241d0006a41106a220c2003370300200241d0006a41186a220d2007290300370300200220033703900120022002290370370350200241086a200241d0006a4120108902200241086a41106a29030021032002290310210e2002280208210920044200370300200542003703002006420037030020024200370370200720081003220541086a290000370300200220052900003703a0012005102320062007290300370300200220022903a001220837039001200220083703702007200a1003220541086a290000370300200220052900003703a00120051023200420072903002208370300200b2006290300370300200c20022903a001220a370300200d20083703002002200a3703900120022002290370370350200242002003420020091b220320017d200e420020091b2201200054ad7d2208200120007d2200200156200820035620082003511b22071b37037820024200200020071b370370200241f0006a2107200241d0006a21060b2006ad42808080808004842007ad428080808080028410020b200241b0016a24000bd08c010c057f017e017f017e047f027e0a7f017e077f017e057f017e230041b0086b2201240010cd020240024020004101460d00200141d0056a41186a22024200370300200141d0056a41106a22034200370300200141d0056a41086a22044200370300200142003703d00520014180016a41086a220541cafbc400ad4280808080c0008422061003220741086a29000037030020012007290000370380012007102320042005290300370300200120012903800122083703a001200120083703d005200541d4d0c300ad4280808080b001841003220741086a29000037030020012007290000370380012007102320032001290380012208370300200141b0046a41086a22072004290300370300200141b0046a41106a22092008370300200141b0046a41186a220a2005290300370300200120083703b001200120012903d0053703b004200141f0006a200141b0046a109c02200129037821082001280270210b200242003703002003420037030020044200370300200142003703d005200520061003220c41086a2900003703002001200c29000037038001200c1023200420052903003703002001200129038001220d3703a0012001200d3703d005200541e4cfc300ad4280808080a001841003220c41086a2900003703002001200c29000037038001200c102320022005290300220d370300200720042903003703002009200129038001220e370300200a200d3703002001200e3703b001200120012903d0053703b004200141e0006a200141b0046a109c022001280260210c2001290368210d200242003703002003420037030020044200370300200142003703d005200520061003220341086a29000037030020012003290000370380012003102320042005290300370300200120012903800122063703a001200120063703d005200541b8d0c300ad4280808080b001841003220341086a290000370300200120032900003703800120031023200220052903002206370300200720042903003703002009200129038001220e370300200a20063703002001200e3703b001200120012903d0053703b004200141d0006a200141b0046a109c02420020084200200b1b22062001290358420020012802501b200d42d8047e4200200c1b7c7d220820082006561b42d804540d00200141f0066a41186a22024200370300200141f0066a41106a220f4200370300200141f0066a41086a22044200370300200142003703f006200541f7fbc400ad4280808080f0008422061003220341086a29000037030020012003290000370380012003102320042005290300370300200120012903800122083703c801200120083703f00620054194b7c200ad4280808080c001841003220341086a290000370300200120032900003703800120031023200f20012903800122083703002007200429030037030020092008370300200a2005290300370300200120083703c801200120012903f0063703b004200141c8006a200141b0046a4120108f01200128024c210b2001280248211020024200370300200f420037030020044200370300200142003703f006200520061003220341086a29000037030020012003290000370380012003102320042005290300370300200120012903800122083703c801200120083703f006200541a8b7c200ad4280808080d001841003220341086a290000370300200120032900003703800120031023200220052903002208370300200720042903003703002009200129038001220d370300200a20083703002001200d3703c801200120012903f0063703b004200141b0046a109b02210310bd0120024200370300200f420037030020044200370300200142003703f006200520061003220c41086a2900003703002001200c29000037038001200c102320042005290300370300200120012903800122063703c801200120063703f006200541f7acc200ad4280808080a001841003220c41086a2900003703002001200c29000037038001200c10232002200529030022063703002007200429030037030020092001290380012208370300200a2006370300200120083703c801200120012903f0063703b004200141203602c4012001200141b0046a3602c001200141b0016a200141b0046aad428080808080048422061004109001410021110240024002400240024002400240024002400240024002400240024020012802b00122090d00410021070c010b20012802b401210a2001200141b8016a2802003602a401200120093602a001200141c0006a200141a0016a106e02400240024020012802400d0020012802a401220241c0016e221241c0016c2205417f4c0d04200128024421130240024020050d00410121070c010b200510212207450d0d0b02402013450d00200141f0066a41206a211420014188036a41017221154100210c0340200141003a00a803200c41016a21164100210502400240024002400340200141003a00af0420022005460d0120014188036a20056a20012802a00122042d00003a00002001200441016a3602a0012001200541016a22043a00a8032004210520044120470d000b200141d0056a41086a220520014188036a41086a290300370300200141d0056a41106a221720014188036a41106a290300370300200141d0056a41186a221820014188036a41186a29030037030020012001290388033703d0052001200220046b3602a40120014188036a200141a0016a10ce0220012d0088034101460d01200141f0066a41186a2018290300370300200141f0066a41106a2017290300370300200141f0066a41086a2005290300370300200120012903d0053703f0062014201541a00110dc041a200141c8016a200141f0066a41c00110dc041a2012200c470d03200c41017422052016200520164b1b2212ad42c0017e2208422088a70d172008a7220541004e0d020c170b200141003602a401200541ff0171450d00200141003a00a8030b20014100360280012012450d05200710230c050b02400240200c0d002005102121070c010b2007200c41c0016c2005102521070b2007450d0c0b2007200c41c0016c6a200141c8016a41c00110dc041a20162013460d0120012802a40121022016210c0c000b0b20014188016a2013360200200120123602840120012007360280012007450d0120012902840121080c020b20014100360280010b41002107200141003602d001200142013703c8012001410c36028c032001200141c0016a360288032001200141c8016a3602d00520014184076a4101360200200142013702f40620014198c2c3003602f006200120014188036a36028007200141d0056a41b8a3c500200141f0066a102e1a20013502d00142208620013502c801841008024020012802cc01450d0020012802c80110230b0b200a450d00200910230b2008420020071b2219422088a7221841c0016c220941c0016e21054101211a02402009450d00200541057422041021221a450d08200521110b200341ff0171210a2007410120071b21164100210202402018450d00201841c0016c210741002102201a210520162104034020052004290000370000200541186a200441186a290000370000200541106a200441106a290000370000200541086a200441086a290000370000200241016a2102200541206a2105200441c0016a2104200741c07e6a22070d000b0b200a410247210a200141f0066a41186a220c4200370300200141f0066a41106a22134200370300200141f0066a41086a22044200370300200142003703f00620014180016a41086a220541f7fbc400ad4280808080f000841003220741086a29000037030020012007290000370380012007102320042005290300370300200120012903800122083703c801200120083703f006200541e7acc500ad4280808080a001841003220741086a290000370300200120072900003703800120071023200141c8016a41086a200529030022083703002001200129038001220d3703c801200f200d370000200f41086a2008370000200141b0046a41086a2004290300370300200141b0046a41106a2013290300370300200141b0046a41186a200c290300370300200120012903f0063703b004200141003602f806200142013703f0062002200141f0066a105c02402002450d0020024105742104201a210503402005200141f0066a1071200541206a2105200441606a22040d000b0b2003200a71211720012802f4062105200620013502f80642208620012802f0062204ad84100202402005450d00200410230b02402017450d00200141f0066a41186a22074200370300200141f0066a41106a220a4200370300200141f0066a41086a22044200370300200142003703f00620014180016a41086a220541f7fbc400ad4280808080f000841003220241086a29000037030020012002290000370380012002102320042005290300370300200120012903800122083703c801200120083703f00620054198b8c200ad4280808080a002841003220241086a290000370300200120022900003703800120021023200141c8016a41086a200529030022083703002001200129038001220d3703c801200f200d370000200f41086a2008370000200141b0046a41086a2004290300370300200141b0046a41106a200a290300370300200141b0046a41186a2007290300370300200120012903f0063703b004200141f0066a200141b0046a10950220012802f0062205450d002006100520012802f406450d00200510230b201620096a21154101211b200141f0066a200b41016a410120101b221c10cf020240024020012802f006221d0d00200141f0066a41186a4200370300200141f0066a41106a22074200370300200141f0066a41086a22044200370300200142003703f00620014180016a41086a220541f7fbc400ad4280808080f000841003220241086a2900003703002001200229000037038001200210232004200529030037030020012001290380013703f006200541e7acc500ad4280808080a001841003220241086a29000037030020012002290000370380012002102320072001290380012208370300200141c8016a41086a2004290300370300200141c8016a41106a2008370300200141c8016a41186a20052903003703002001200837038803200120012903f0063703c801200141f0066a200141c8016a412010bb0120012902f406420020012802f00622051b21082005410120051b211e4100211d4100211f0c010b200141f8066a350200210820014180076a2802002107200141fc066a280200210220012802f4062120024020014184076a2802002205450d00200541d0006c2104200241c0006a210503400240200541046a280200450d00200528020010230b200541d0006a2105200441b07f6a22040d000b0b02402007450d00200210230b20084220862020ad8421084101211f4100211b201d211e0b200141f0066a41186a22074200370300200141f0066a41106a22094200370300200141f0066a41086a22044200370300200142003703f00620014180016a41086a220541f7fbc400ad4280808080f000841003220241086a290000370300200120022900003703800120021023200420052903003703002001200129038001220d3703c8012001200d3703f00620054194b7c200ad4280808080c001841003220241086a290000370300200120022900003703800120021023200141c8016a41086a2005290300220d3703002001200129038001220e3703c801200f200e370000200f41086a200d370000200141b0046a41086a2004290300370300200141b0046a41106a2009290300370300200141b0046a41186a2007290300370300200120012903f0063703b0042001201c3602f0062006200141f0066aad22214280808080c0008410022001201f3a00af04200120153602c401200120163602c0012001200141c0016a3602a4012001200141af046a3602a00141002112024002402008422088a7220541057422040d0041012114410021220c010b20044105752222ad42c0017e220d422088a70d0e200da722044100480d0e200410212214450d070b2008a7212302402005450d002005410574220441606a4105762124200141f0066a41206a210b200141b0046a4180016a2125200141b0046a41e0006a2126200141b0046a41c0006a2112200141b0046a41206a2113200141c8016a410172211020142102201e2105034020014180016a41186a2207200541186a29000037030020014180016a41106a2209200541106a29000037030020014180016a41086a220a200541086a2900003703002001200529000037038001200141b0016a20014180016a10d002200141c8016a20012802b001220c20012802b80110d10220012d00c801210320014188036a201041a00110dc041a0240024020034101470d00200141d0056a20014188036a41a00110dc041a024020012802b401450d00200c10230b200141b0046a200141d0056a41a00110dc041a0c010b024020012802b401450d00200c10230b200141b0046a410041a00110db041a0b024020012802a0012d00000d0020012802a401220c2802002203200c280204460d00200c200341c0016a36020002400240200141b0046a200341206a220c460d00200c200141b0046a412010de040d010b02402013200341c0006a220c460d00200c2013412010de040d010b02402012200341e0006a220c460d00200c2012412010de040d010b0240202620034180016a220c460d00200c2026412010de040d010b2025200341a0016a2203460d0120032025412010de04450d010b20012802a00141013a00000b200541206a2105200141f0066a41186a2007290300370300200141f0066a41106a2009290300370300200141f0066a41086a200a29030037030020012001290380013703f006200b200141b0046a41a00110dc041a2002200141f0066a41c00110dc0441c0016a2102200441606a22040d000b202441016a21120b02402023450d00201e10230b2012ad42c0017e2208422088a70d002008a72205417f4c0d0020012d00af0421130240024020050d00410121100c010b200510212210450d020b4100210302402012450d002014201241c0016c6a210b200141f0066a41a0016a2104200141f0066a4180016a2102200141f0066a41e0006a2107200141f0066a41c0006a2109200141f0066a41206a210a410021032010210c201421050340200141f0066a41186a200541186a290000370300200141f0066a41106a200541106a290000370300200141f0066a41086a200541086a290000370300200120052900003703f006200a41186a200541386a290000370000200a41106a200541306a290000370000200a41086a200541286a290000370000200a200541206a2900003700002009200541c0006a290000370000200941086a200541c8006a290000370000200941106a200541d0006a290000370000200941186a200541d8006a2900003700002007200541e0006a290000370000200741086a200541e8006a290000370000200741106a200541f0006a290000370000200741186a200541f8006a290000370000200220054180016a290000370000200241086a20054188016a290000370000200241106a20054190016a290000370000200241186a20054198016a2900003700002004200541a0016a290000370000200441086a200541a8016a290000370000200441186a200541b8016a290000370000200441106a200541b0016a290000370000200341016a2103200c200141f0066a41c00110dc0441c0016a210c200541c0016a2205200b470d000b0b200141f0066a41186a22074200370300200141f0066a41106a22094200370300200141f0066a41086a22044200370300200142003703f00620014180016a41086a220541f7fbc400ad4280808080f000841003220241086a29000037030020012002290000370380012002102320042005290300370300200120012903800122083703c801200120083703f006200541f7acc200ad4280808080a001841003220241086a290000370300200120022900003703800120021023200141c8016a41086a200529030022083703002001200129038001220d3703c801200f200d370000200f41086a2008370000200141b0046a41086a2004290300370300200141b0046a41106a2009290300370300200141b0046a41186a2007290300370300200120012903f0063703b004200141003602f806200142013703f0062003200141f0066a105c02402003450d002010200341c0016c6a21042010210503402005200141f0066a1071200541206a200141f0066a1071200541c0006a200141f0066a1071200541e0006a200141f0066a107120054180016a200141f0066a1071200541a0016a200141f0066a1071200541c0016a22052004470d000b0b20012802f4062105200620013502f80642208620012802f0062204ad84100202402005450d00200410230b02402012450d00201010230b200141f0066a41186a22074200370300200141f0066a41106a22094200370300200141f0066a41086a22044200370300200142003703f00620014180016a41086a220541f7fbc400ad4280808080f000841003220241086a29000037030020012002290000370380012002102320042005290300370300200120012903800122083703c801200120083703f006200541a8b7c200ad4280808080d001841003220241086a290000370300200120022900003703800120021023200141c8016a41086a200529030022083703002001200129038001220d3703c801200f200d370000200f41086a2008370000200141b0046a41086a2004290300370300200141b0046a41106a2009290300370300200141b0046a41186a2007290300370300200120012903f0063703b004200120133a00f006200620214280808080108410022001201c3602f406200141053a00f006200141f0066a108e01410810212202450d022002201536020420022016360200024020170d00200141f0066a41186a220a4200370300200141f0066a41106a22074200370300200141f0066a41086a22044200370300200142003703f006200141d0056a41086a22054188e0c100ad4280808080f001841003220941086a290000370300200120092900003703d0052009102320042005290300370300200120012903d005220637038803200120063703f006200541f4f0c100ad4280808080c001841003220941086a290000370300200120092900003703d00520091023200720012903d0052206370300200141c8016a41086a22032004290300370300200141c8016a41106a220c2006370300200141c8016a41186a220b20052903003703002001200637038803200120012903f0063703c801200141306a200141c8016a109c022001290338210820012802302110200a42003703002007420037030020044200370300200142003703f006200541f7fbc400ad4280808080f000841003220941086a290000370300200120092900003703d0052009102320042005290300370300200120012903d0053703f00620054194b7c200ad4280808080c001841003220941086a290000370300200120092900003703d00520091023200720012903d005220637030020032004290300370300200c2006370300200b20052903003703002001200637038803200120012903f0063703c801200141286a200141c8016a4120108f012008420020101b200128022c410020012802281b10ab02200210230c0c0b024002402018450d002002201641c0016a2207360200200141003a009007201641206a2104410021050340200141003a00af04200141f0066a20056a200420056a2d00003a00002001200541016a22053a00900720054120470d000b200141c8016a41086a2205200141f0066a41086a290300370300200141c8016a41106a2204200141f0066a41106a290300370300200141c8016a41186a2209200141f0066a41186a290300370300200120012903f0063703c80120160d010b200210234108210c41002107410021050c0b0b200141d0056a41186a2009290300370300200141d0056a41106a2004290300370300200141d0056a41086a2005290300370300200120012903c8013703d005201520076b41c0016e41016a220541286c2204417f4c0d0020041021220c450d03200c20012903d005370300200c4201370320200c41186a200141d0056a41186a290300370300200c41106a200141d0056a41106a290300370300200c41086a200141d0056a41086a2903003703000240200228020022042002280204470d00410121070c0a0b2002200441c0016a360200200141003a009007200441206a2107410021040340200141003a00af04200141f0066a20046a200720046a2d00003a00002001200441016a22043a00900720044120470d000b20014188036a41186a2218200141f0066a41186a22092903002206370300200141c8016a41086a220b200141f0066a41086a220a290300370300200141c8016a41106a2210200141f0066a41106a2203290300370300200141c8016a41186a220f2006370300200120012903f0063703c801410121070340200141d0056a41186a200f2903002206370300200141d0056a41106a20102903002208370300200141d0056a41086a200b290300220d370300200120012903c801220e3703d0052009200637030020032008370300200a200d3703002001200e3703f0060240024020052007460d00200521130c010b200228020420022802006b41c0016e20056a41016a22042005490d0f200541017422132004201320044b1b2213ad42287e2206422088a70d0f2006a722044100480d0f0240024020050d0020041021210c0c010b200c200541286c20041025210c0b200c450d060b200c200741286c6a220520012903f006370300200a2903002106200329030021082009290300210d20054201370320200541186a200d370300200541106a2008370300200541086a2006370300200741016a21070240200228020022042002280204470d00201321050c0b0b2002200441c0016a36020041002105200141003a009007200441206a21040340200141003a00af04200141f0066a20056a200420056a2d00003a00002001200541016a22053a00900720054120470d000b201820092903002206370300200b200a29030037030020102003290300370300200f2006370300200120012903f0063703c801201321050c000b0b102f000b200541011030000b410841041030000b200441081030000b200441081030000b200541011030000b200441011030000b200441011030000b200541011030000b200210230b200141f0066a41186a4200370300200141f0066a41106a22094200370300200141f0066a41086a22024200370300200142003703f006200141d0056a41086a22044188e0c100ad4280808080f001841003220a41086a2900003703002001200a2900003703d005200a102320022004290300370300200120012903d005220637038803200120063703f006200441b4f0c100ad4280808080f000841003220a41086a2900003703002001200a2900003703d005200a1023200920012903d0052206370300200141c8016a41086a2002290300370300200141c8016a41106a2006370300200141c8016a41186a20042903003703002001200637038803200120012903f0063703c801200141f0066a200141c8016a41201086020240024020012802f0064101460d00200120073602f806200120053602f4062001200c3602f006200141f0066a41004100200110ac02200141c8016aad428080808080048421060c010b200141c8016aad42808080808004842206100520012902f4062108200120073602f806200120053602f4062001200c3602f006200141f0066a2008a741012008422088a710ac020b200141f0066a41186a22074200370300200141f0066a41106a22024200370300200141f0066a41086a22044200370300200142003703f006200141d0056a41086a22054188e0c100ad4280808080f0018422081003220a41086a2900003703002001200a2900003703d005200a102320042005290300370300200120012903d005220d370388032001200d3703f006200541f4f0c100ad4280808080c00184220d1003220a41086a2900003703002001200a2900003703d005200a102320014188036a41086a22102005290300220e370300200120012903d00522273703880320092027370000200941086a220f200e370000200141c8016a41086a220a2004290300370300200141c8016a41106a22032002290300370300200141c8016a41186a220c2007290300370300200120012903f0063703c801200141186a200141c8016a109c02200128021821132001290320210e200742003703002002420037030020044200370300200142003703f006200520081003220b41086a2900003703002001200b2900003703d005200b102320042005290300370300200120012903d005220837038803200120083703f0062005200d1003220b41086a2900003703002001200b2900003703d005200b1023201020052903002208370300200120012903d005220d370388032009200d370000200f2008370000200a200429030037030020032002290300370300200c2007290300370300200120012903f0063703c8012001200e42017c420120131b22083703f0062006202142808080808001841002200742003703002002420037030020044200370300200142003703f006200541f7fbc400ad4280808080f000841003220741086a290000370300200120072900003703d0052007102320042005290300370300200120012903d0053703f00620054194b7c200ad4280808080c001841003220741086a290000370300200120072900003703d00520071023200220012903d0052206370300200a200429030037030020032006370300200c20052903003703002001200637038803200120012903f0063703c801200141106a200141c8016a4120108f0120082001280214410020012802101b10ab020b024002400240410810212205450d0020052015360204200520163602000240410810212204450d0020042014201241c0016c6a221c360204200420143602002005200410d2020240410810212202450d0020022015360204200220163602000240410810212226450d002026201c36020420262014360200200141f0066a41186a220a4200370300200141f0066a41106a22184200370300200141f0066a41086a22044200370300200142003703f006200141d0056a41086a220541c4fbc400ad4280808080e000841003220741086a290000370300200120072900003703d0052007102320042005290300370300200120012903d0053703f006200541f9bcc000ad4280808080e000841003220741086a290000370300200120072900003703d00520071023201820012903d0052206370300200141c8016a41086a2004290300370300200141c8016a41106a2006370300200141c8016a41186a20052903003703002001200637038001200120012903f0063703c801200141086a200141c8016a4120108f0120012802082103200128020c210c20014188036a41186a420037030020014188036a41106a221e420037030020014188036a41086a22074200370300200142003703880320054194fcc400ad42808080808001841003220941086a290000370300200120092900003703d0052009102320072005290300370300200120012903d00522063703a001200120063703880320054195dfc000ad42808080808001841003220941086a290000370300200120092900003703d00520091023201e20012903d00522063703002004200729030037030020182006370300200a2005290300370300200120063703b00120012001290388033703f0062001200c41ac026a41ac0220031b3602c801202142808080808004842221200141c8016aad22274280808080c00084100202402002280200220520022802042209460d002002200541c0016a220a360200200141003a009007200541e0006a2104410021050340200141003a00af04200141f0066a20056a200420056a2d00003a00002001200541016a22053a00900720054120470d000b200141b0046a41086a2205200141f0066a41086a290300370300200141b0046a41106a2203200141f0066a41106a290300370300200141b0046a41186a220c200141f0066a41186a290300370300200120012903f00622063703c801200120063703b0044101210702402009200a6b41c0016e41016a220441057422091021220b450d00200b20012903b004370000200b41186a200c290300370000200b41106a2003290300370000200b41086a2005290300370000200228020022052002280204460d062002200541c0016a360200200141003a009007200541e0006a2107410021050340200141003a00af04200141f0066a20056a200720056a2d00003a00002001200541016a22053a00900720054120470d000b20014188036a41186a2212200141f0066a41186a22092903002206370300200141c8016a41086a2210200141f0066a41086a220a290300370300200141c8016a41106a220f200141f0066a41106a2203290300370300200141c8016a41186a22132006370300200120012903f0063703c801410121070340200141d0056a41186a20132903002206370300200141d0056a41106a200f2903002208370300200141d0056a41086a2010290300220d370300200120012903c801220e3703d0052009200637030020032008370300200a200d3703002001200e3703f0060240024020042007460d002004210c0c010b200228020420022802006b41c0016e20046a41016a22052004490d0b2004410174220c2005200c20054b1b220c41ffffff3f71200c470d0b200c41057422054100480d0b0240024020040d0020051021210b0c010b200b200441057420051025210b0b200b0d00200541011030000b200b20074105746a220520012903f006370000200541186a2009290300370000200541106a2003290300370000200541086a200a290300370000200741016a21070240200228020022042002280204470d00200c21040c080b2002200441c0016a36020041002105200141003a009007200441e0006a21040340200141003a00af04200141f0066a20056a200420056a2d00003a00002001200541016a22053a00900720054120470d000b2012200929030022063703002010200a290300370300200f200329030037030020132006370300200120012903f0063703c801200c21040c000b0b200941011030000b200210234101210b41002107410021040c050b410841041030000b410841041030000b410841041030000b410841041030000b200210230b20014188036a41186a220a420037030020014188036a41106a2203420037030020014188036a41086a220242003703002001420037038803200141d0056a41086a22054194fcc400ad42808080808001841003220941086a290000370300200120092900003703d0052009102320022005290300370300200120012903d00522063703a00120012006370388032005419ddfc000ad4280808080c000841003220941086a290000370300200120092900003703d00520091023200141b0016a41086a20052903002206370300200120012903d00522083703b001201e2008370000201e41086a2006370000200141f0066a41086a2002290300370300200141f0066a41106a2003290300370300200141f0066a41186a200a29030037030020012001290388033703f006200141003602d001200142013703c8012007200141c8016a105c02402007450d0020074105742102200b210503402005200141c8016a1071200541206a2105200241606a22020d000b0b20012802cc012105202120013502d00142208620012802c8012202ad84100202402005450d00200210230b02402004450d00200b10230b2026102302400240024002400240410810212202450d0020022015360204200220163602000240410810212226450d002026201c360204202620143602002017450d0202402002280200220520022802042209460d002002200541c0016a220a360200200141003a00900720054180016a2104410021050340200141003a00af04200141f0066a20056a200420056a2d00003a00002001200541016a22053a00900720054120470d000b200141b0046a41086a2205200141f0066a41086a290300370300200141b0046a41106a2203200141f0066a41106a290300370300200141b0046a41186a220c200141f0066a41186a290300370300200120012903f00622063703c801200120063703b0044101210702402009200a6b41c0016e41016a220441057422091021220b450d00200b20012903b004370000200b41186a200c290300370000200b41106a2003290300370000200b41086a2005290300370000200228020022052002280204460d052002200541c0016a360200200141003a00900720054180016a2107410021050340200141003a00af04200141f0066a20056a200720056a2d00003a00002001200541016a22053a00900720054120470d000b20014188036a41186a2212200141f0066a41186a22092903002206370300200141c8016a41086a2210200141f0066a41086a220a290300370300200141c8016a41106a220f200141f0066a41106a2203290300370300200141c8016a41186a22132006370300200120012903f0063703c801410121070340200141d0056a41186a20132903002206370300200141d0056a41106a200f2903002208370300200141d0056a41086a2010290300220d370300200120012903c801220e3703d0052009200637030020032008370300200a200d3703002001200e3703f0060240024020042007460d002004210c0c010b200228020420022802006b41c0016e20046a41016a22052004490d0b2004410174220c2005200c20054b1b220c41ffffff3f71200c470d0b200c41057422054100480d0b0240024020040d0020051021210b0c010b200b200441057420051025210b0b200b0d00200541011030000b200b20074105746a220520012903f006370000200541186a2009290300370000200541106a2003290300370000200541086a200a290300370000200741016a21070240200228020022042002280204470d00200c21040c070b2002200441c0016a36020041002105200141003a00900720044180016a21040340200141003a00af04200141f0066a20056a200420056a2d00003a00002001200541016a22053a00900720054120470d000b2012200929030022063703002010200a290300370300200f200329030037030020132006370300200120012903f0063703c801200c21040c000b0b200941011030000b20021023410021044101210b410021070c040b410841041030000b410841041030000b20261023200210230c020b200210230b200141f0066a41186a220a4200370300200141f0066a41106a22034200370300200141f0066a41086a22024200370300200142003703f006200141d0056a41086a22054182fdc400ad4280808080a001841003220941086a290000370300200120092900003703d0052009102320022005290300370300200120012903d0053703f006200541fccfc300ad4280808080b001841003220941086a290000370300200120092900003703d0052009102320014180016a41086a20052903002206370300200120012903d00522083703800120182008370000201841086a2006370000200141c8016a41086a2002290300370300200141c8016a41106a2003290300370300200141c8016a41186a200a290300370300200120012903f0063703c801200141003602f806200142013703f0062007200141f0066a105c02402007450d0020074105742102200b210503402005200141f0066a1071200541206a2105200241606a22020d000b0b20012802f40621052027428080808080048420013502f80642208620012802f0062202ad84100202402005450d00200210230b02402004450d00200b10230b202610230b02400240024002400240410810212202450d0020022015360204200220163602000240410810212215450d002015201c360204201520143602002017450d0202402002280200220520022802042209460d002002200541c0016a220a360200200141003a009007200541a0016a2104410021050340200141003a00af04200141f0066a20056a200420056a2d00003a00002001200541016a22053a00900720054120470d000b200141b0046a41086a2205200141f0066a41086a290300370300200141b0046a41106a2203200141f0066a41106a290300370300200141b0046a41186a220c200141f0066a41186a290300370300200120012903f00622063703c801200120063703b0044101210702402009200a6b41c0016e41016a220441057422091021220b450d00200b20012903b004370000200b41186a200c290300370000200b41106a2003290300370000200b41086a2005290300370000200228020022052002280204460d052002200541c0016a360200200141003a009007200541a0016a2107410021050340200141003a00af04200141f0066a20056a200720056a2d00003a00002001200541016a22053a00900720054120470d000b20014188036a41186a2212200141f0066a41186a22092903002206370300200141c8016a41086a2210200141f0066a41086a220a290300370300200141c8016a41106a220f200141f0066a41106a2203290300370300200141c8016a41186a22132006370300200120012903f0063703c801410121070340200141d0056a41186a20132903002206370300200141d0056a41106a200f2903002208370300200141d0056a41086a2010290300220d370300200120012903c801220e3703d0052009200637030020032008370300200a200d3703002001200e3703f0060240024020042007460d002004210c0c010b200228020420022802006b41c0016e20046a41016a22052004490d0b2004410174220c2005200c20054b1b220c41ffffff3f71200c470d0b200c41057422054100480d0b0240024020040d0020051021210b0c010b200b200441057420051025210b0b200b0d00200541011030000b200b20074105746a220520012903f006370000200541186a2009290300370000200541106a2003290300370000200541086a200a290300370000200741016a21070240200228020022042002280204470d00200c21040c070b2002200441c0016a36020041002105200141003a009007200441a0016a21040340200141003a00af04200141f0066a20056a200420056a2d00003a00002001200541016a22053a00900720054120470d000b2012200929030022063703002010200a290300370300200f200329030037030020132006370300200120012903f0063703c801200c21040c000b0b200941011030000b20021023410021044101210b410021070c040b410841041030000b410841041030000b20151023200210230c020b200210230b200141f0066a41186a220a4200370300200141f0066a41106a22034200370300200141f0066a41086a22024200370300200142003703f006200141d0056a41086a2205419cfcc400ad4280808080a002841003220941086a290000370300200120092900003703d0052009102320022005290300370300200120012903d0053703f0062005419ddfc000ad4280808080c000841003220941086a290000370300200120092900003703d0052009102320014180016a41086a20052903002206370300200120012903d00522083703800120182008370000201841086a2006370000200141c8016a41086a2002290300370300200141c8016a41106a2003290300370300200141c8016a41186a200a290300370300200120012903f0063703c801200141003602f806200142013703f0062007200141f0066a105c02402007450d0020074105742102200b210503402005200141f0066a1071200541206a2105200241606a22020d000b0b20012802f40621052027428080808080048420013502f80642208620012802f0062202ad84100202402005450d00200210230b02402004450d00200b10230b201510230b02402022450d00201410230b02402020450d00201b201f720d00201d10230b02402011450d00201a10230b2019a7450d00201610230b20014188036a41186a420037030020014188036a41106a2207420037030020014188036a41086a220442003703002001420037038803200141a0016a41086a220541a6a3c500ad4280808080a001841003220241086a290000370300200120022900003703a0012002102320042005290300370300200120012903a00137038803200541fca4c500ad4280808080e000841003220241086a290000370300200120022900003703a00120021023200720012903a0012206370300200141f0066a41086a2004290300370300200141f0066a41106a2006370300200141f0066a41186a2005290300370300200120063703d00520012001290388033703f006200141c8016a200141f0066a10d30220012802c8012205410420051b210902400240024002400240024020012902cc01420020051b2206422088a7220a41c4006c22050d00410021040c010b200920056a2102410021042009210502400340024020052d00004101460d00200541046a28020020004f0d020b200441016a21042002200541c4006a2205470d000b0b2004200a4b0d010b200642ffffffff0f8321060240200a20046b2205450d0002402004450d0020092009200441c4006c6a200541c4006c10dd041a0b2005ad42208620068421060b20014188036a41186a220a420037030020014188036a41106a2203420037030020014188036a41086a220442003703002001420037038803200141a0016a41086a220541a6a3c500ad4280808080a001841003220241086a290000370300200120022900003703a0012002102320042005290300370300200120012903a00137038803200541fca4c500ad4280808080e000841003220241086a290000370300200120022900003703a00120021023200141d0056a41086a20052903002208370300200120012903a001220d3703d0052007200d370000200741086a2008370000200141f0066a41086a2004290300370300200141f0066a41106a2003290300370300200141f0066a41186a200a29030037030020012001290388033703f006200141c8016a20092006422088a710d402200141f0066aad4280808080800484220820013502d00142208620012802c8012204ad8410022006a72105024020012802cc01450d00200410230b02402005450d00200910230b20014188036a41186a2203420037030020014188036a41106a220a420037030020014188036a41086a220442003703002001420037038803200141a0016a41086a220541a6a3c500ad4280808080a001841003220241086a290000370300200120022900003703a0012002102320042005290300370300200120012903a0013703880320054184a9c500ad4280808080c001841003220241086a290000370300200120022900003703a00120021023200141d0056a41086a220220052903002206370300200120012903a001220d3703d0052007200d370000200741086a2006370000200141f0066a41086a22072004290300370300200141f0066a41106a2209200a290300370300200141f0066a41186a220a200329030037030020012001290388033703f006200141003a00af042008200141af046aad428080808010841002200141c8016a10d502200a200141c8016a41186a22032903003703002009200141c8016a41106a220c2903003703002007200141c8016a41086a220b290300370300200120012903c8013703f006412410212204450d01200420012903f00637000020044114360220200441186a200a290300370000200441106a2009290300370000200441086a2007290300370000200142818080801037028c03200120043602880320014188036a10d602200a20032903003703002009200c2903003703002007200b290300370300200120012903c8013703f006200141f0066a10c80110cd02200141d0056a41186a22094200370300200141d0056a41106a2204420037030020024200370300200142003703d005200541c4fbc400ad4280808080e000841003220741086a290000370300200120072900003703a0012007102320022005290300370300200120012903a0013703d005200541ffbcc000ad4280808080a001841003220741086a290000370300200120072900003703a00120071023200420012903a0012206370300200141b0046a41086a2002290300370300200141b0046a41106a2006370300200141b0046a41186a20052903003703002001200637038001200120012903d0053703b004200141f0066a200141b0046a4120108a0120012d00f0062105200920014189076a290000370300200420014181076a2900003703002002200141f9066a290000370300200120012900f1063703d0050240024020054101460d00200141a0036a420037030020014198036a420037030020014190036a420037030020014200370388030c010b20014188036a41186a200141d0056a41186a29030037030020014188036a41106a200141d0056a41106a29030037030020014188036a41086a200141d0056a41086a290300370300200120012903d005370388030b200141d0056a41186a22094200370300200141d0056a41106a220a4200370300200141d0056a41086a22024200370300200142003703d005200141a0016a41086a220541d899c600ad42808080808003841003220741086a290000370300200120072900003703a0012007102320022005290300370300200120012903a0013703d005200541f099c600ad4280808080e001841003220741086a290000370300200120072900003703a0012007102320014180016a41086a20052903002206370300200120012903a00122083703800120042008370000200441086a2006370000200141b0046a41086a2002290300370300200141b0046a41106a200a290300370300200141b0046a41186a2009290300370300200120012903d0053703b004200141f0066a200141b0046a412010bb01024002400240024020012802f00622020d00200141c8016a41186a20014188036a41186a290300370300200141c8016a41106a20014188036a41106a290300370300200141c8016a41086a20014188036a41086a29030037030020012001290388033703c8014101210241002107200141c8016a2105410021090c010b20012902f4062206a7210a02402006422088a7220441d100490d00200141f0066a41186a220720014188036a41186a290300370300200141f0066a41106a220920014188036a41106a290300370300200141f0066a41086a220320014188036a41086a29030037030020012001290388033703f0062000417f6a41d10070220520044f0d06200220054105746a220520012903f006370000200541186a2007290300370000200541106a2009290300370000200541086a2003290300370000200a21070c030b200141f0066a41086a280200210920012802f4062107200141c8016a41186a20014188036a41186a290300370300200141c8016a41106a20014188036a41106a290300370300200141c8016a41086a20014188036a41086a29030037030020012001290388033703c80102402004200a460d00200141c8016a2105200a2107200421090c020b200141c8016a210520072004470d010b200741016a22042007490d062007410174220a2004200a20044b1b220441ffffff3f712004470d062004410574220a4100480d060240024020070d00200a102121020c010b20022007410574200a102521020b2002450d05200421070b200220094105746a22042005290000370000200441186a200541186a290000370000200441106a200541106a290000370000200441086a200541086a290000370000200941016a21040b200141f0066a41186a4200370300200141f0066a41106a22034200370300200141f0066a41086a22094200370300200142003703f006200141a0016a41086a220541d899c600ad42808080808003841003220a41086a2900003703002001200a2900003703a001200a102320092005290300370300200120012903a0013703f006200541f099c600ad4280808080e001841003220a41086a2900003703002001200a2900003703a001200a1023200320012903a0012206370300200141c8016a41086a2009290300370300200141c8016a41106a2006370300200141c8016a41186a2005290300370300200120063703b001200120012903f0063703c8010240024020020d00200141c8016aad428080808080048410050c010b200141003602f806200142013703f0062004200141f0066a105c02402004450d00200441057421042002210503402001200141f0066a3602d0052005200141d0056a106b200541206a2105200441606a22040d000b0b20012802f4062105200141c8016aad428080808080048420013502f80642208620012802f0062204ad84100202402005450d00200410230b2007450d00200210230b200141b0086a24000f0b41ccbac000102b000b412441041030000b41c4acc60020052004102d000b200a41011030000b102a000b8b1b09017f017e047f017e027f017e017f017e057f23004190046b2200240042002101200041c0036a41186a4200370300200041c0036a41106a22024200370300200041c0036a41086a22034200370300200042003703c003200041a0036a41086a220441cafbc400ad4280808080c000841003220541086a290000370300200020052900003703a0032005102320032004290300370300200020002903a00322063703d801200020063703c00320044188d3c300ad4280808080b001841003220541086a290000370300200020052900003703a00320051023200220002903a0032206370300200041f0036a41086a2003290300370300200041f0036a41106a2006370300200041f0036a41186a2004290300370300200020063703d801200020002903c0033703f003200041e8016a200041f0036a109d020240024020002d00e8014102470d00200041e8016a41186a4200370300200041e8016a41106a22074200370300200041e8016a41086a22034200370300200042003703e801200441c4fbc400ad4280808080e000841003220541086a290000370300200020052900003703a0032005102320032004290300370300200020002903a0033703e80120044197bdc000ad4280808080e000841003220541086a290000370300200020052900003703a00320051023200720002903a0032206370300200041f8006a41086a2003290300370300200041f8006a41106a2006370300200041f8006a41186a200429030037030020002006370310200020002903e801370378200041e8016a200041f8006a108c010240024020002802e80122080d0041042108410021040c010b20002902ec012201422088a721040b02400240200441246c2203450d002008210402400340024020042d00004101470d00200441016a2800002105200441086a28020021072000200441106a28020036027c20002007360278200541c28289aa04470d00200041e8016a200041f8006a109b0320002d00e80122074102470d020b200441246a21042003415c6a2203450d020c000b0b200020002800ec0136006b200020002800e901360268200041f0016a2903002106200041106a200041f8016a41d80010dc041a200041d0026a29030021090c010b410221070b02402001422088a72204450d00200441246c21032008210403400240024020042d0000220541034b0d0002400240024020050e0404000102040b2004410c6a280200450d03200441086a28020010230c030b2004410c6a280200450d02200441086a28020010230c020b2004410c6a280200450d01200441086a28020010230c010b200441086a280200450d00200441046a28020010230b200441246a21042003415c6a22030d000b0b02402001a7450d00200810230b200020002802683602d0012000200028006b3600d301200041f8006a200041106a41d80010dc041a0240024020074102470d0041002103200041f0036a21080c010b200020002802d0013602e802200020002800d3013600eb02200020063703e002200041e8016a200041f8006a41d80010dc041a200020093703d802200041c0036a41186a22054200370300200041c0036a41106a22084200370300200041c0036a41086a22034200370300200042003703c003200041a0036a41086a220441cafbc400ad4280808080c0008422061003220a41086a2900003703002000200a2900003703a003200a102320032004290300370300200020002903a00322013703d801200020013703c003200441b8d0c300ad4280808080b00184220b1003220a41086a2900003703002000200a2900003703a003200a1023200041d8016a41086a220c20042903002201370300200020002903a00322093703d80120022009370000200241086a220d2001370000200041f0036a41086a220a2003290300370300200041f0036a41106a220e2008290300370300200041f0036a41186a220f2005290300370300200020002903c0033703f0032000200041f0036a109c02024002402000280200450d002000290308500d00200041f0036aad42808080808004842101200041f0036a21080c010b200041e0026a200041d8026a20074101461b2903002101200542003703002008420037030020034200370300200042003703c003200420061003221041086a290000370300200020102900003703a0032010102320032004290300370300200020002903a00322093703d801200020093703c0032004200b1003221041086a290000370300200020102900003703a00320101023200c20042903002209370300200020002903a003220b3703d8012002200b370000200d2009370000200a2003290300370300200e2008290300370300200f2005290300370300200020002903c0033703f003200020013703c003200041f0036aad42808080808004842201200041c0036aad42808080808001841002200041f0026a109c03200542003703002008420037030020034200370300200042003703c003200420061003221041086a290000370300200020102900003703a0032010102320032004290300370300200020002903a00322063703d801200020063703c003200441f8d0c300ad4280808080a001841003221041086a290000370300200020102900003703a00320101023200c20042903002206370300200020002903a00322093703d80120022009370000200d2006370000200a2003290300370300200e2008290300370300200f2005290300370300200020002903c0033703f003200041c0036a200041f0036a109d0320002d00c0032104200f200041d9036a290000370300200e200041d1036a290000370300200a200041c9036a290000370300200020002900c1033703f0030240024020044101460d00200041b8036a4200370300200041b0036a4200370300200041a8036a4200370300200042003703a0030c010b200041a0036a41186a200041f0036a41186a290300370300200041a0036a41106a200041f0036a41106a290300370300200041a0036a41086a200041f0036a41086a290300370300200020002903f0033703a0030b200041f0026a41246a200041a0036a41186a290300370200200041f0026a411c6a200041a0036a41106a290300370200200041f0026a41146a200041a0036a41086a290300370200200020002903a0033702fc02200041ec036a20004198036a280200360200200041c0036a41246a20004190036a290300370200200041c0036a411c6a200041f0026a41186a290300370200200041c0036a41146a200041f0026a41106a290300370200200041cc036a200041f0026a41086a290300370200200020002903f0023702c403200041003602c003200041c0036a10ea02200041f0036a21080b41012103200041e0026a200041d8026a20074101461b2903002106200041c0036a41186a220e4200370300200041c0036a41106a220f4200370300200041c0036a41086a22054200370300200042003703c003200041a0036a41086a220441cafbc400ad4280808080c000841003220a41086a2900003703002000200a2900003703a003200a102320052004290300370300200020002903a00322093703d801200020093703c003200441d4d0c300ad4280808080b001841003220a41086a2900003703002000200a2900003703a003200a1023200041d8016a41086a20042903002209370300200020002903a003220b3703d8012002200b370000200241086a2009370000200041f0036a41086a2005290300370300200041f0036a41106a200f290300370300200041f0036a41186a200e290300370300200020002903c0033703f003200020063703c0032001200041c0036aad4280808080800184100202402007450d00410021030c010b200041f0026a41086a200041e8016a41086a290300370300200041f0026a41106a200041e8016a41106a2d00003a0000200020002800eb02360073200020002802e802360270200020002903e8013703f00220002903e00221060b200041e8016a41086a2006370300200041e8016a41106a20002903f002370300200041e8016a41186a200041f0026a41086a29030037030020004188026a200041f0026a41106a2d00003a0000200020033a00e801200020002802703600e901200020002800733600ec01200041c0036a41186a220a4200370300200041c0036a41106a220e4200370300200041c0036a41086a22054200370300200042003703c003200041a0036a41086a220441cafbc400ad4280808080c000841003220741086a290000370300200020072900003703a0032007102320052004290300370300200020002903a00322063703d801200020063703c00320044188d3c300ad4280808080b001841003220741086a290000370300200020072900003703a00320071023200041d8016a41086a20042903002206370300200020002903a00322013703d80120022001370000200241086a2006370000200041f0036a41086a2005290300370300200041f0036a41106a200e290300370300200041f0036a41186a200a290300370300200020002903c0033703f003410110212204450d012000420137027c200020043602780240024020030d002000410136028001200441003a00000c010b2000410136028001200441013a0000200041e8016a410172200041f8006a109e030b200028027c21042008ad428080808080048420003502800142208620002802782203ad8410022004450d00200310230b20004190046a24000f0b410141011030000bc30b01087f23004190036b2202240041002103200241003a002820012802042204417f6a2105417f210602400240034020042003460d01200241086a20036a200128020022072d00003a00002001200420066a3602042001200741016a22083602002002200341016a22093a00282005417f6a21052006417f6a21062009210320094120470d000b200241a8016a41086a200241086a41086a290300370300200241a8016a41106a200241086a41106a290300370300200241a8016a41186a200241086a41186a290300370300200220022903083703a80141002106200241003a0028200420096b21030340024020030d000240200641ff0171450d00200241003a00280b200041013a00000c030b200241086a20066a20082d00003a000020012003417f6a22033602042001200841016a22083602002002200641016a22093a00282009210620094120470d000b200241c8016a41086a200241086a41086a290300370300200241c8016a41106a200241086a41106a290300370300200241c8016a41186a200241086a41186a290300370300200220022903083703c80141002106200241003a0028200520096b2103200720096a2105034002402003417f470d000240200641ff0171450d00200241003a00280b200041013a00000c030b200241086a20066a200820066a2d00003a0000200120033602042001200520066a41026a3602002002200641016a22093a00282003417f6a21032009210620094120470d000b200241e8016a41086a200241086a41086a290300370300200241e8016a41106a200241086a41106a290300370300200241e8016a41186a200241086a41186a290300370300200220022903083703e80141002104200241003a0028200820096a2106200520096a2108034002402003417f470d000240200441ff0171450d00200241003a00280b200041013a00000c030b200241086a20046a20062d00003a0000200120033602042001200820046a41026a3602002002200441016a22093a00282003417f6a2103200641016a21062009210420094120470d000b20024188026a41086a200241086a41086a29030037030020024188026a41106a200241086a41106a29030037030020024188026a41186a200241086a41186a290300370300200220022903083703880241002109200241003a008803034002402003417f470d000240200941ff0171450d00200241003a0088030b200041013a00000c030b200241e8026a20096a20062d00003a0000200120033602042001200641016a22063602002002200941016a22083a0088032003417f6a21032008210920084120470d000b200241a8026a41086a2201200241e8026a41086a290300370300200241a8026a41106a2203200241e8026a41106a290300370300200241a8026a41186a2206200241e8026a41186a290300370300200241086a41086a200241a8016a41086a290300370300200241086a41106a200241a8016a41106a290300370300200241086a41186a200241a8016a41186a290300370300200220022903e8023703a802200220022903a801370308200241c0006a200241c8016a41186a290300370300200241386a200241c8016a41106a290300370300200241306a200241c8016a41086a290300370300200220022903c801370328200241e0006a200241e8016a41186a290300370300200241d8006a200241e8016a41106a290300370300200241d0006a200241e8016a41086a290300370300200220022903e80137034820024180016a20024188026a41186a290300370300200241f8006a20024188026a41106a290300370300200241f0006a20024188026a41086a2903003703002002200229038802370368200241a0016a200629030037030020024198016a200329030037030020024190016a2001290300370300200220022903a80237038801200041016a200241086a41a00110dc041a200041003a00000c010b0240200341ff0171450d00200241003a00280b200041013a00000b20024190036a24000bd89c020f057f017e017f017e097f017e037f017e017f027e017f037e017f157e1a7f230041a00f6b22022400200241e00e6a41186a22034200370300200241e00e6a41106a22044200370300200241e00e6a41086a22054200370300200242003703e00e200241980d6a41086a220641c6acc500ad4280808080f0008422071003220841086a290000370300200220082900003703980d2008102320052006290300370300200220022903980d22093703f80d200220093703e00e200641e8fac500ad4280808080b003841003220841086a290000370300200220082900003703980d20081023200420022903980d2209370300200241c80b6a41086a220a2005290300370300200241c80b6a41106a220b2009370300200241c80b6a41186a220c2006290300370300200220093703980e200220022903e00e3703c80b200241880b6a200241c80b6a4120108f01200228028c0b210d20022802880b210e200342003703002004420037030020054200370300200242003703e00e200620071003220841086a290000370300200220082900003703980d2008102320052006290300370300200220022903980d22093703f80d200220093703e00e200641e8fbc500ad42808080808001841003220841086a290000370300200220082900003703980d20081023200320062903002209370300200a2005290300370300200b20022903980d2207370300200c2009370300200220073703980e200220022903e00e3703c80b02400240024002404100200241c80b6a10a9032206200641ff01714104461b41ff0171220641034b0d00024020060e0400020103000b2001200d4100200e1b6b220620014b0d00200641064f0d020b200041003602000c020b200241e00e6a41186a22084200370300200241e00e6a41106a220a4200370300200241e00e6a41086a22054200370300200242003703e00e200241980d6a41086a220641c6acc500ad4280808080f000841003220341086a290000370300200220032900003703980d2003102320052006290300370300200220022903980d22093703f80d200220093703e00e200641e8fbc500ad42808080808001841003220341086a290000370300200220032900003703980d20031023200241980e6a41086a20062903002209370300200220022903980d22073703980e20042007370000200441086a2009370000200241c80b6a41086a2005290300370300200241c80b6a41106a200a290300370300200241c80b6a41186a2008290300370300200220022903e00e3703c80b200241c80b6aad428080808080048410050b200241a80c6a41186a4200370300200241a80c6a41106a220f420037030041082110200241a80c6a41086a22054200370300200242003703a80c200241980d6a41086a220641f7fbc400ad4280808080f000841003220441086a290000370300200220042900003703980d2004102320052006290300370300200220022903980d3703a80c200641e7acc500ad4280808080a001841003220441086a290000370300200220042900003703980d20041023200f20022903980d2209370300200241c80b6a41086a2005290300370300200241c80b6a41106a2009370300200241c80b6a41186a2006290300370300200220093703980e200220022903a80c3703c80b200241a80c6a200241c80b6a412010bb014100211141002112024002400240024002400240024002400240024020022902ac0c420020022802a80c22061b2209422088a722054105742204450d0020044105752212ad42d0007e2207422088a70d092007a722044100480d09200410212210450d010b2009a7210d2006410120061b210c02402005450d002005410574220441606a210e200241a80c6a41206a210620102103200c21050340200541086a2900002109200541106a290000210720052900002113200241c80b6a41186a2208200541186a290000370300200241c80b6a41106a220a2007370300200241c80b6a41086a220b2009370300200220133703c80b200241f00b6a200241c80b6a10be01200241a80c6a41186a2008290300370300200241a80c6a41106a200a290300370300200241a80c6a41086a200b290300370300200620022903f00b370300200641086a200241f00b6a41086a290300370300200641106a200241f00b6a41106a290300370300200641186a200241f00b6a41186a290300370300200641206a200241f00b6a41206a290300370300200641286a200241f00b6a41286a290300370300200220022903c80b3703a80c2003200241a80c6a41d00010dc0441d0006a2103200541206a2105200441606a22040d000b200e41057641016a21110b0240200d450d00200c10230b200241c80b6a41186a22044200370300200241c80b6a41106a22144200370300200241c80b6a41086a22054200370300200242003703c80b200241980d6a41086a220641c6acc500ad4280808080f0008422091003220341086a290000370300200220032900003703980d2003102320052006290300370300200220022903980d22073703f80d200220073703c80b2006418cfbc500ad4280808080e002841003220341086a290000370300200220032900003703980d20031023201420022903980d2207370300200241a80c6a41086a22032005290300370300200241a80c6a41106a22082007370300200241a80c6a41186a220a2006290300370300200220073703980e200220022903c80b3703a80c200241f00b6a200241a80c6a10ae03410021150240024020022802f40b22160d004104211642002117410021180c010b200241a80c6aad4280808080800484100520022802f00b211820022903f80b21170b200a42003703002008420037030020034200370300200242003703a80c200641be99c600ad42808080809001841003220b41086a2900003703002002200b2900003703980d200b102320032006290300370300200220022903980d3703a80c200641f0cec400ad428080808030841003220b41086a2900003703002002200b2900003703980d200b1023200241980e6a41086a220b20062903002207370300200220022903980d22133703980e200f2013370000200f41086a200737000020052003290300370300201420082903003703002004200a290300370300200220022903a80c3703c80b200241f80a6a200241c80b6a109c0220022903800b210720022802f80a210d200442003703002014420037030020054200370300200242003703c80b200620091003220c41086a2900003703002002200c2900003703980d200c102320052006290300370300200220022903980d22133703f80d200220133703c80b20064184adc500ad4280808080f0018422131003220c41086a2900003703002002200c2900003703980d200c1023200b20062903002219370300200220022903980d221a3703980e2014201a370000201441086a220e20193700002003200529030037030020082014290300370300200a2004290300370300200220022903c80b3703a80c200241e80a6a200241a80c6a109c0220022903f00a211920022802e80a211b200442003703002014420037030020054200370300200242003703c80b200620091003220c41086a2900003703002002200c2900003703980d200c102320052006290300370300200220022903980d22093703f80d200220093703c80b200620131003220c41086a2900003703002002200c2900003703980d200c1023200b20062903002209370300200220022903980d22133703980e20142013370000200e20093700002003200529030037030020082014290300370300200a2004290300370300200220022903c80b3703a80c200220074200200d1b22093703f00b200241a80c6aad221c4280808080800484221d200241f00b6aad221e42808080808001841002200920194200201b1b7d2213500d07200241a80c6a41186a22044200370300200241a80c6a41106a22034200370300200241a80c6a41086a22054200370300200242003703a80c200241980d6a41086a220641c6acc500ad4280808080f0008422091003220841086a290000370300200220082900003703980d2008102320052006290300370300200220022903980d3703a80c20064185b2c500ad4280808080e001841003220841086a290000370300200220082900003703980d20081023200241980e6a41086a220d20062903002207370300200220022903980d22193703980e200f2019370000200f41086a221f2007370000200241c80b6a41086a22082005290300370300200241c80b6a41106a220a2003290300370300200241c80b6a41186a220b2004290300370300200220022903a80c3703c80b200241a80c6a200241c80b6a412010bb0120022802a80c210c20022902ac0c2119200b4200370300200a420037030020084200370300200242003703c80b200620091003220e41086a2900003703002002200e2900003703980d200e102320082006290300370300200220022903980d22093703f80d200220093703c80b20064193b2c500ad42808080809001841003220e41086a2900003703002002200e2900003703980d200e1023200d20062903002209370300200220022903980d22073703980e20142007370000201441086a2009370000200520082903003703002003200a2903003703002004200b290300370300200220022903c80b3703a80c200241d00a6a200241a80c6a4120108902200241d00a6a41106a290300211a20022903d80a212020022802d00a210e200442003703002003420037030020054200370300200242003703a80c200641d5fbc400ad42808080808001841003221b41086a2900003703002002201b2900003703980d201b102320052006290300370300200220022903980d3703a80c200641d6a0c200ad4280808080d001841003221b41086a2900003703002002201b2900003703980d201b1023200d20062903002209370300200220022903980d22073703980e200f2007370000201f200937000020082005290300370300200a2003290300370300200b2004290300370300200220022903a80c3703c80b200241b80a6a200241c80b6a4120108902200241a80a6a20022903c00a420020022802b80a22061b2207200241b80a6a41106a290300420020061b2209428094ebdc03420010e204200241880a6a20204200200e1b201a4200200e1b20194200200c1b22214220882222420010e104200241980a6a20022903a80a221a200241a80a6a41086a29030022204280ec94a37c427f10e1042009200241880a6a41086a290300221920022903880a2223200756201920095620192009511b22061b21092007202320061b212320022903980a20077c21192022a721032013428086ebc7f5002013428086ebc7f500541b421f8042ffffffff0f83428094ebdc037e429880b5e50380212241012105200c4101200c1b211f41d87d21060240024003402006450d01200241f8096a201a2020200641b0d3c4006a3502002207420010e1042005417f6a2105200641086a2106202320022903f8092213200720197e22072007428094ebdc038022074280ec94a37c7e7c4280cab5ee01562007a76aad7c2207542009200241f8096a41086a2903002007201354ad7c22075420092007511b2204450d000b0240200441016a41017120056b2206417f6a220520064d0d00200241f8086a201a202042c0f0f50b420010e10420024180096a29030020022903f8082207201942c0f0f50b7e201942288022094280ec94a37c7e7c4280cab5ee01562009a76aad7c2209200754ad7c21130c020b0240200541244b0d00200241e8096a201a2020200541037422044188d1c4006a2802002208ad2207420010e104200241c8096a202320022903e8092213200720197e22072007428094ebdc038022074280ec94a37c7e7c4280cab5ee01562007a76aad7c220720232007562009200241e8096a41086a2903002007201354ad7c22135620092013511b22051b22242007202320051b22077d22232009201320051b2013200920051b7d2024200754ad7d41002006410374220a4188d1c4006a280200220620086b2208200820064b1b22064101200641014b1bad2209420010e204200241b8096a20022903c8092207200241c8096a41086a29030022242009420010e104200241d8096a201a20202004418cd1c4006a2802002206ad2225420010e10420024188096a20244200200a418cd1c4006a28020022042006200420064b22081b2006200420081b6bad2213420010e104200241a8096a200742002013420010e10420024198096a420042002007420010e104427f427f200241a8096a41086a29030022072002290388092002290398097c7c222420022903900920022903a0098442005220242007547222081b2224427f20022903a80920081b2207202320022903b8097d20137e2009807c22092007542208ad7c221320082013202454200920075a1b22081b2123427f200920081b2113200241d8096a41086a29030020022903d8092209202520197e22072007428094ebdc038022074280ec94a37c7e7c4280cab5ee01562007a76aad7c2207200954ad7c210902402005200420064d730d004200200920237d2007201354ad7d2223200720137d2224200756202320095620232009511b22061b21134200202420061b21090c030b427f200920237c200720137c22232007542206ad7c22072006200720095420072009511b22061b2113427f202320061b21090c020b4198e8c10020054125102d000b200241e8086a201a202042e8aafa0b420010e104200241f0086a29030020022903e8082207201942e8aafa0b7e22092009428094ebdc038022094280ec94a37c7e7c4280cab5ee01562009a76aad7c2209200754ad7c21130b42002126200241a8086a201a20204280c2d72f420010e10420024198086a20022903a808221a20194280c2d72f7e2019420a8022074280ec94a37c7e7c4280cab5ee01562007a76aad7c2207200241a8086a41086a2903002007201a54ad7c428094ebdc03420010e204200241d8086a20092013428094ebdc03420010e20420024188086a200229039808221320024198086a41086a29030022194280ec94a37c427f10e104200241f8076a201320192022420010e104200241c8086a20022903d8082213200241d8086a41086a29030022194280ec94a37c427f10e104200241b8086a201320192022420010e104202220072002290388087c7e2227428094ebdc0380212820022903f8072129200241f8076a41086a290300212a2022200920022903c8087c7e2207428094ebdc03802109024020030d004200212b0c070b201f20034105746a210e20162017422088a74102746a210d200241e8076a20022903b8082213200720094280ec94a37c7e7c4280cab5ee01562009a76aad7c2209200241b8086a41086a2903002009201354ad7c428094ebdc03420010e204200241d8076a20022903e807222c200241e8076a41086a290300222d4280ec94a37c427f10e10420184101201841014b1b220a418094ebdc036e22064101200641014b1b210b200920022903d8077c212e200241c80b6a41106a2118420021264200212b20162103201f2108024003402003200d460d080240024020032802002206450d00200241c8076a202c202d200a2006200a2006491b200b6ead428094ebdc037e200a200b6ead8042ffffffff0f832209420010e104200241980d6a41086a220641c6acc500ad4280808080f000841003220541086a290000370300200220052900003703980d20051023200241f80d6a41086a22042006290300370300200220022903980d3703f80d200641e7acc500ad4280808080a001841003220541086a290000370300200220052900003703980d20051023200241980e6a41086a22052006290300370300200220022903980d3703980e200241c80b6a200810ac012009202e7e2213428094ebdc0380210920022903c8072107200241c8076a41086a290300211941c00010212206450d0520192007201320094280ec94a37c7e7c4280cab5ee01562009a76aad7c2209200754ad7c2107200620022903f80d370000200641086a2004290300370000200620022903980e370010200641186a2005290300370000200620022903c80b370020200641286a200241c80b6a41086a290300370000200641306a2018290300370000200641386a200241c80b6a41186a290300370000200241c0003602840f200220063602800f200241c80b6a2006ad428080808080088410041090010240024020022802c80b22050d00410021040c010b20022802cc0b211b200220022802d00b3602a40b200220053602a00b200241c0076a200241a00b6a106e0240024020022802c0070d0020022802c407210c410121040c010b200241003602f80b200242013703f00b2002410c3602bc0e2002200241800f6a3602b80e2002200241f00b6a3602e00e200241013602bc0c200242013702ac0c20024198c2c3003602a80c2002200241b80e6a3602b80c200241e00e6a41b8a3c500200241a80c6a102e1a20023502f80b42208620023502f00b841008024020022802f40b450d0020022802f00b10230b410021040b201b450d00200510230b42002113200241b0076a20092007428094ebdc03420010e204200241a0076a20022903b0072219200241b0076a41086a290300221a4280ec94a37c427f10e10420024190076a2019201a200c410020041bad2220420010e10420061023200242003703f80b200242003703f00b024002404200200920022903900722192020200920022903a0077c7e221a201a428094ebdc0380221a4280ec94a37c7e7c4280cab5ee0156201aa76aad7c222f7d221a201a200956200720024190076a41086a290300202f201954ad7c22307d2009202f54ad7d220920075620092007511b22061b22314200200920061b22328450450d00420021090c010b200241a80c6a200810be0120024180076a20022903a80c220942012009420156200241a80c6a41086a29030022094200522009501b22061b22132009420020061b2209428094ebdc03420010e20420022802c80c210c20024180076a41086a29030021332002290380072134024020022802d00c2206450d00200241f0066a2013200920344201203442015620334200522033501b22051b221a2033420020051b222010e204200241d0066a20312032428094ebdc03420010e204200241e0066a20312032428094ebdc03420010e30420022903f006220742ffffffff0f56200241f0066a41086a29030022194200522019501b0d032007a7450d05200c200641306c6a2104200742ffffffff0f832123200241d0066a41086a290300212220022903d006212420022903e0062125200c21060340200241c0066a20132006290300220720132007542009200641086a29030022075420092007511b22051b2009200720051b201a202010e20420022903c0062207428080808010544100200241c0066a41086a290300501b450d0c20024198066a20242022200742ffffffff0f83428094ebdc037e20238042ffffffff0f832207420010e104200241a8066a200641106a2002290398062219200720257e22072007428094ebdc038022074280ec94a37c7e7c4280cab5ee01562007a76aad7c220720024198066a41086a2903002007201954ad7c10b504200241f00b6a20022903a80620022903b006200241a8066a41106a29030010a503200641306a22062004470d000b0b200241f8056a2013200920344201203442015620334200522033501b22061b221a2033420020061b222010e20420022903f8052207428080808010544100200241f8056a41086a290300501b450d07200241e8056a201320022903b80c221920132019542009200241a80c6a41186a29030022195420092019511b22061b2009201920061b201a202010e20420022903e8052209428080808010544100200241e8056a41086a290300501b450d082007a7450d09200241d8056a20312032428094ebdc03420010e204200241c8056a20022903d8052213200241d8056a41086a29030022194280ec94a37c427f10e104200241b8056a20132019200942ffffffff0f83428094ebdc037e200742ffffffff0f838042ffffffff0f832209420010e10420022903b80522072009203120022903c8057c7e22092009428094ebdc038022094280ec94a37c7e7c4280cab5ee01562009a76aad7c2213200754ad2109200241b8056a41086a2903002107024020022802cc0c450d00200c10230b200720097c21090b200241a0056a20082013202f7c2207200920307c2007201354ad7c10b504200241f00b6a20022903a00520022903a805200241a0056a41106a29030010a503427f202b200241f00b6a41086a2903007c202620022903f00b7c22072026542206ad7c220920062009202b542009202b511b22061b212b427f200720061b21260b200341046a2103200841206a2208200e470d010c090b0b200241113602cc0b200241ad99c6003602c80b419b97c60041e000200241c80b6a41ec9bc6001031000b20024188066a2013200c290300220720132007542009200c41086a29030022075420092007511b22061b2009200720061b201a202010e20420022903880642808080801054410020024188066a41086a290300501b450d0541fc97c600102b000b200441081030000b41c00041011030000b200241113602cc0b200241ad99c6003602c80b419b97c60041e000200241c80b6a41ec9bc6001031000b200241113602cc0b200241ad99c6003602c80b419b97c60041e000200241c80b6a41ec9bc6001031000b41fc97c600102b000b200241113602cc0b200241ad99c6003602c80b419b97c60041e000200241c80b6a41ec9bc6001031000b202a2029202720284280ec94a37c7e7c4280cab5ee01562028a76aad7c2209202954ad7c210702402017a7450d00201610230b200241a80c6a41186a202b370300200241a80c6a41106a2026370300200241a80c6a41086a41003a0000200241d00c6a42002007202b7d2009202654ad7d2213200920267d2219200956201320075620132007511b22061b2207370300200241a80c6a41206a4200201920061b2213370300200241033a00a80c200241a80c6a108e0120024188056a2026202b10870320024188056a41106a2903002119200229039005211a0240024002402002290388052209a7450d00200241c80d6a41186a22044200370300200241c80d6a41106a22034200370300200241c80d6a41086a22054200370300200242003703c80d200241980d6a41086a220641d5fbc400ad428080808080018422201003220841086a290000370300200220082900003703980d2008102320052006290300370300200220022903980d22093703a00b200220093703c80d200641d6a0c200ad4280808080d0018422231003220841086a290000370300200220082900003703980d20081023200320022903980d2209370300200241a80d6a41086a220a2005290300370300200241a80d6a41106a220b2009370300200241a80d6a41186a220c2006290300370300200220093703e80d200220022903c80d3703a80d200241f0046a200241a80d6a4120108902200241f0046a41106a290300210920022903f804212220022802f0042108200442003703002003420037030020054200370300200242003703c80d200620201003220341086a290000370300200220032900003703980d2003102320052006290300370300200220022903980d22203703a00b200220203703c80d200620231003220341086a290000370300200220032900003703980d20031023200420062903002220370300200a2005290300370300200b20022903980d2223370300200c2020370300200220233703e80d200220022903c80d3703a80d2002427f2009420020081b220920197c2022420020081b2219201a7c221a2019542206ad7c22192006201920095420192009511b22061b3703b00c2002427f201a20061b3703a80c200241a80c6a2106200241a80d6a21050c010b2009500d01200241c80d6a41186a22044200370300200241c80d6a41106a22034200370300200241c80d6a41086a22054200370300200242003703c80d200241980d6a41086a220641d5fbc400ad428080808080018422201003220841086a290000370300200220082900003703980d2008102320052006290300370300200220022903980d22093703a00b200220093703c80d200641d6a0c200ad4280808080d0018422231003220841086a290000370300200220082900003703980d20081023200320022903980d2209370300200241a80d6a41086a220a2005290300370300200241a80d6a41106a220b2009370300200241a80d6a41186a220c2006290300370300200220093703e80d200220022903c80d3703a80d200241d8046a200241a80d6a4120108902200241d8046a41106a290300210920022903e004212220022802d8042108200442003703002003420037030020054200370300200242003703c80d200620201003220341086a290000370300200220032900003703980d2003102320052006290300370300200220022903980d22203703a00b200220203703c80d200620231003220341086a290000370300200220032900003703980d20031023200420062903002220370300200a2005290300370300200b20022903980d2223370300200c2020370300200220233703e80d200220022903c80d3703a80d2002427f2009420020081b220920197c2022420020081b2219201a7c221a2019542206ad7c22192006201920095420192009511b22061b3703b00c2002427f201a20061b3703a80c200241a80c6a2106200241a80d6a21050b2005ad42808080808004842006ad428080808080028410020b200241a80c6a41186a22044200370300200241a80c6a41106a22034200370300200241a80c6a41086a22064200370300200242003703a80c200241980d6a41086a220541d5fbc400ad428080808080018422201003220841086a290000370300200220082900003703980d2008102320062005290300370300200220022903980d22093703f00b200220093703a80c200541d6a0c200ad4280808080d0018422231003220841086a290000370300200220082900003703980d20081023200241980e6a41086a220b20052903002209370300200220022903980d22193703980e200f2019370000200f41086a220c2009370000200241c80b6a41086a220d2006290300370300200241c80b6a41106a220e2003290300370300200241c80b6a41186a221b2004290300370300200220022903a80c3703c80b200241c0046a200241c80b6a4120108902200241c0046a41106a290300210920022903c804211920022802c0042108200442003703002003420037030020064200370300200242003703a80c200520201003220a41086a2900003703002002200a2900003703980d200a102320062005290300370300200220022903980d221a3703f00b2002201a3703a80c200520231003220a41086a2900003703002002200a2900003703980d200a1023200b2005290300221a370300200220022903980d22223703980e200f2022370000200c201a370000200d2006290300370300200e2003290300370300201b2004290300370300200220022903a80c3703c80b2002427f2009420020081b220920077c2019420020081b221920137c22222019542208ad7c221a2008201a200954201a2009511b22081b3703b00c2002427f202220081b3703a80c200241c80b6aad4280808080800484201c4280808080800284221a1002024002402019427f85201320081b22132009427f85200720081b2209844200520d00200241c80d6a41186a22034200370300200241c80d6a41106a22084200370300200241c80d6a41086a22044200370300200242003703c80d200520201003220a41086a2900003703002002200a2900003703980d200a102320042005290300370300200220022903980d22093703a00b200220093703c80d200620231003220541086a290000370300200220052900003703a80c20051023200820022903a80c2209370300200241a80d6a41086a220a2004290300370300200241a80d6a41106a220b2009370300200241a80d6a41186a220c2006290300370300200220093703e80d200220022903c80d3703a80d200241a8046a200241a80d6a4120108902200241a8046a41106a290300210920022903b004210720022802a8042105200342003703002008420037030020044200370300200242003703c80d200620201003220841086a290000370300200220082900003703a80c2008102320042006290300370300200220022903a80c22133703a00b200220133703c80d200620231003220841086a290000370300200220082900003703a80c20081023200320062903002213370300200a2004290300370300200b20022903a80c2219370300200c2013370300200220193703e80d200220022903c80d3703a80d20022009420020051b3703b00c20022007420020051b3703a80c200241a80d6aad4280808080800484201a10020c010b200241a80c6a109302200241a80c6a2013200910da022004200937030020032013370300200641053a00002002410d3a00a80c200241a80c6a108e010b410121152021a7450d00201f10230b200241c80b6a41186a22044200370300200241c80b6a41106a22034200370300200241c80b6a41086a22054200370300200242003703c80b200241980d6a41086a220641c6acc500ad4280808080f0008422091003220841086a290000370300200220082900003703980d2008102320052006290300370300200220022903980d22073703f80d200220073703c80b200641b0fac500ad4280808080a0018422071003220841086a290000370300200220082900003703980d20081023200241980e6a41086a220820062903002213370300200220022903980d22193703980e20142019370000201441086a220a2013370000200241a80c6a41086a220b2005290300370300200241a80c6a41106a220c2003290300370300200241a80c6a41186a220d2004290300370300200220022903c80b3703a80c200241a0046a200241a80c6a4120108f0120022802a004211b20022802a4042118200442003703002003420037030020054200370300200242003703c80b200620091003220e41086a2900003703002002200e2900003703980d200e102320052006290300370300200220022903980d22133703f80d200220133703c80b200620071003220e41086a2900003703002002200e2900003703980d200e1023200820062903002207370300200220022903980d22133703980e20142013370000200a2007370000200b2005290300370300200c2003290300370300200d2004290300370300200220022903c80b3703a80c2002201841016a4101201b1b22353602f00b201d201e4280808080c0008422071002200442003703002003420037030020054200370300200242003703c80b200620091003220e41086a2900003703002002200e2900003703980d200e102320052006290300370300200220022903980d22133703f80d200220133703c80b200641e8fac500ad4280808080b0038422131003220e41086a2900003703002002200e2900003703980d200e1023200820062903002219370300200220022903980d221a3703980e2014201a370000200a2019370000200b2005290300370300200c2003290300370300200d2004290300370300200220022903c80b3703a80c20024198046a200241a80c6a4120108f01200442003703002003420037030020054200370300200242003703c80b200620091003220e41086a2900003703002002200e2900003703980d200e102320052006290300370300200220022903980d22193703f80d200220193703c80b200620131003220e41086a2900003703002002200e2900003703980d200e1023200820062903002213370300200220022903980d22193703980e20142019370000200a2013370000200b2005290300370300200c2003290300370300200d2004290300370300200220022903c80b3703a80c200220013602f00b201d20071002200442003703002003420037030020054200370300200242003703c80b200620091003220e41086a2900003703002002200e2900003703980d200e102320052006290300370300200220022903980d22093703f80d200220093703c80b200641d0fdc500ad4280808080a001841003220e41086a2900003703002002200e2900003703980d200e1023200820062903002209370300200220022903980d22073703980e20142007370000200a2009370000200b2005290300370300200c2003290300370300200d2004290300370300200220022903c80b3703a80c200241f00b6a200241a80c6a10af0320022802f00b2206410420061b2136024002400240024002400240024002400240024002400240024002400240024002400240024020022902f40b420020061b22094220882207a722062009a7470d00200641016a22052006490d132007a722034101742204200520052004491b220541ffffffff01712005470d13200541037422044100480d130240024020060d002004102121360c010b203620034103742004102521360b2036450d012009422088a721062005ad21090b203620064103746a2205200136020420052035360200200942ffffffff0f832113200641016a2137024020350d0020132037ad4220868421130c060b2037450d05200641037441086a21054100211f2036210602400340200628020020354f0d01200641086a2106201f41016a211f200541786a22050d000b0b2037201f490d010240201f0d00410021060c050b201f4103742118201c4280808080c0008421092036211b0340201b2802002101200241980d6a41086a220541c6acc500ad4280808080f0008422071003220641086a290000370300200220062900003703980d20061023200241a00b6a41086a22042005290300370300200220022903980d3703a00b20054193adc500ad4280808080b002841003220641086a290000370300200220062900003703980d20061023200241e80d6a41086a22032005290300370300200220022903980d3703e80d200220013602a80c200241c80d6a41186a220820091001220641186a290000370300200241c80d6a41106a220a200641106a290000370300200241c80d6a41086a220b200641086a290000370300200220062900003703c80d20061023200241a80d6a41186a220c2008290300370300200241a80d6a41106a220d200a290300370300200241a80d6a41086a220e200b290300370300200220022903c80d3703a80d41c00010212206450d03200620022903a00b370000200641086a2004290300370000200620022903e80d370010200641186a2003290300370000200620022903a80d370020200641286a200e290300370000200641306a200d290300370000200641386a200c2903003700002006ad4280808080800884100a20061023200520071003220641086a290000370300200220062900003703980d2006102320042005290300370300200220022903980d3703a00b200541a6adc500ad4280808080b002841003220641086a290000370300200220062900003703980d2006102320032005290300370300200220022903980d3703e80d200220013602a80c200820091001220641186a290000370300200a200641106a290000370300200b200641086a290000370300200220062900003703c80d20061023200c2008290300370300200d200a290300370300200e200b290300370300200220022903c80d3703a80d41c00010212206450d04201b41086a211b200620022903a00b370000200641086a2004290300370000200620022903e80d370010200641186a2003290300370000200620022903a80d370020200641286a200e290300370000200641306a200d290300370000200641386a200c2903003700002006ad4280808080800884100a20061023201841786a22180d000b201f21060c040b200441041030000b41ccbac000102b000b41c00041011030000b41c00041011030000b2037201f6b221b450d0002402006450d002036203620064103746a201b41037410dd041a0b20362802042101200241a80d6a41186a4200370300200241a80d6a41106a220e4200370300200241a80d6a41086a22054200370300200242003703a80d200241980d6a41086a220641f7fbc400ad4280808080f000841003220441086a290000370300200220042900003703980d2004102320052006290300370300200220022903980d22093703a00b200220093703a80d200641f3b8c000ad4280808080b001841003220441086a290000370300200220042900003703980d20041023200e20022903980d2209370300200241f80d6a41086a2005290300370300200241f80d6a41106a2009370300200241f80d6a41186a2006290300370300200220093703e80d200220022903a80d3703f80d200241a80c6a200241f80d6a41201086024101210620022902ac0c21190240024020022802a80c22054101460d00200541014621060c010b2019422088a722182001200120184b1b220d2019a72205490d000240200d20054d0d00201c4280808080c00084210941f7fbc400ad4280808080f0008421070340200241980d6a41086a220620071003220441086a290000370300200220042900003703980d20041023200241a00b6a41086a22032006290300370300200220022903980d3703a00b200641f2a9c300ad4280808080a002841003220441086a290000370300200220042900003703980d20041023200241e80d6a41086a22042006290300370300200220022903980d3703e80d200220053602a80c200241c80d6a41186a220820091001220641186a290000370300200241c80d6a41106a220a200641106a290000370300200241c80d6a41086a220b200641086a290000370300200220062900003703c80d20061023200241a80d6a41186a220c2008290300370300200241a80d6a41106a2208200a290300370300200241a80d6a41086a220a200b290300370300200220022903c80d3703a80d41c00010212206450d04200620022903a00b370000200641086a2003290300370000200620022903e80d370010200641186a2004290300370000200620022903a80d370020200641286a200a290300370000200641306a2008290300370000200641386a200c2903003700002006ad4280808080800884100520061023200d200541016a2205470d000b0b20012018492106201942808080807083200dad8421190b201bad4220862109200220193702ac0c200220063602a80c0240024020060d00200241a80d6a41186a22034200370300200241a80d6a41106a22084200370300200241a80d6a41086a22054200370300200242003703a80d200241980d6a41086a220641f7fbc400ad4280808080f000841003220441086a290000370300200220042900003703980d2004102320052006290300370300200220022903980d22073703a00b200220073703a80d200641f3b8c000ad4280808080b001841003220441086a290000370300200220042900003703980d20041023200241e80d6a41086a20062903002207370300200220022903980d22193703e80d200e2019370000200e41086a2007370000200241f80d6a41086a2005290300370300200241f80d6a41106a2008290300370300200241f80d6a41186a2003290300370300200220022903a80d3703f80d200241f80d6aad428080808080048410050c010b200241a80d6a41186a22034200370300200241a80d6a41106a22084200370300200241a80d6a41086a22054200370300200242003703a80d200241980d6a41086a220641f7fbc400ad4280808080f000841003220441086a290000370300200220042900003703980d2004102320052006290300370300200220022903980d22073703a00b200220073703a80d200641f3b8c000ad4280808080b001841003220441086a290000370300200220042900003703980d20041023200241e80d6a41086a20062903002207370300200220022903980d22193703e80d200e2019370000200e41086a2007370000200241f80d6a41086a2005290300370300200241f80d6a41106a2008290300370300200241f80d6a41186a2003290300370300200220022903a80d3703f80d200241f80d6a4120200241a80c6a410472108c020b201320098421130b200241c80b6a41186a22034200370300200241c80b6a41106a22084200370300200241c80b6a41086a22054200370300200242003703c80b200241980d6a41086a220641c6acc500ad4280808080f000841003220441086a290000370300200220042900003703980d2004102320052006290300370300200220022903980d22093703f80d200220093703c80b200641d0fdc500ad4280808080a001841003220441086a290000370300200220042900003703980d20041023200241980e6a41086a20062903002209370300200220022903980d22073703980e20142007370000201441086a2009370000200241a80c6a41086a2005290300370300200241a80c6a41106a2008290300370300200241a80c6a41186a2003290300370300200220022903c80b3703a80c024002400240024020360d00201d10050c010b200241003602f80b200242013703f00b2013422088a72206200241f00b6a105c0240024020060d0020022802f80b210320022802f40b210420022802f00b21050c010b203620064103746a210c20022802f40b210420022802f80b21032036210803402008280200210b02400240200420036b4104490d00200341046a210620022802f00b21050c010b200341046a22062003490d12200441017422052006200520064b1b220a4100480d120240024020040d00200a102121050c010b20022802f00b2004200a102521050b2005450d052002200a3602f40b200220053602f00b200a21040b200220063602f80b200520036a200b360000200841046a280200210a0240200420066b41034b0d00200641046a22032006490d122004410174220b2003200b20034b1b22034100480d120240024020040d002003102121050c010b200520042003102521050b2005450d04200220033602f40b200220053602f00b200321040b2002200641046a22033602f80b200520066a200a360000200841086a2208200c470d000b0b2013a72106201d2003ad4220862005ad84100202402004450d00200510230b2006450d00203610230b200241003602980b200242043703900b200241a80c6a10ad04200241a00b6a20022802a80c220620022802b00c108a01024020022802ac0c450d00200610230b200241c80b6a410c6a200241a00b6a41086a290300370200200241c80b6a41146a200241a00b6a41106a290300370200200241c80b6a411c6a200241a00b6a41186a290300370200200241c80b6a41246a200241a00b6a41206a2d00003a0000200220022903a00b3702cc0b2002200241900b6a3602c80b200241a80c6a200241c80b6a41047210a301410121180240024002400240024002400240024020022802a80c4101460d004100210e4100211f0c010b200241f00b6a41206a200241a80c6a41246a280200360200200241f00b6a41186a200241a80c6a411c6a22062902002209370300200241f00b6a41106a200241a80c6a41146a22052902002207370300200241f00b6a41086a200241a80c6a410c6a22042902002213370300200220022902ac0c22193703f00b200241e00e6a41186a2009370300200241e00e6a41106a2007370300200241e00e6a41086a2013370300200220193703e00e200241a80d6a41186a2006290200370300200241a80d6a41106a2005290200370300200241a80d6a41086a2004290200370300200220022902ac0c3703a80d412010212205450d06200520022903e00e370000200541186a200241e00e6a41186a2203290300370000200541106a200241e00e6a41106a2208290300370000200541086a200241e00e6a41086a220a290300370000200241f80d6a41086a200241a80d6a41086a2903002209370300200241f80d6a41106a200241a80d6a41106a2903002207370300200241f80d6a41186a200241a80d6a41186a2903002213370300200220022903a80d22193703f80d20022802c80b2106200241c80d6a41186a220b2013370300200241c80d6a41106a220c2007370300200241c80d6a41086a220d2009370300200220193703c80d024020062802082204200641046a280200470d00200441016a220e2004490d162004410174221b200e201b200e4b1b220ead422c7e2209422088a70d162009a7221b4100480d160240024020040d00201b102121040c010b20062802002004412c6c201b102521040b2004450d0620062004360200200641046a200e360200200628020821040b200d2903002109200c2903002107200b290300211320022903c80d211920062802002004412c6c6a22044281808080103702242004200536022020042019370200200441186a2013370200200441106a2007370200200441086a20093702004101210e2006200628020841016a360208200241800f6a41086a200a290300370300200241800f6a41106a2008290300370300200241800f6a41186a2003290300370300200220022903e00e3703800f412010212218450d04201820022903800f370000201841186a200241800f6a41186a221b290300370000201841106a200241800f6a41106a2201290300370000201841086a200241800f6a41086a2236290300370000200241f00b6a41206a200241c80b6a41206a290300370300200241f00b6a41186a200241c80b6a41186a290300370300200241f00b6a41106a200241c80b6a41106a290300370300200241f00b6a41086a200241c80b6a41086a290300370300200220022903c80b3703f00b200241a80c6a200241f00b6a410472223810a301024020022802a80c4101460d004101211f0c010b200241a80c6a41047221054102210a412021084101210e4101211f0340200241b80e6a41206a200541206a280200360200200241b80e6a41186a200541186a22062902002209370300200241b80e6a41106a200541106a22042902002207370300200241b80e6a41086a200541086a220329020022133703002002200529020022193703b80e200241e00e6a41186a220b2009370300200241e00e6a41106a220c2007370300200241e00e6a41086a220d2013370300200220193703e00e200241a80d6a41186a22372006290000370300200241a80d6a41106a22062004290000370300200241a80d6a41086a22392003290000370300200220052900003703a80d412010212204450d04200420022903e00e370000200441186a200b290300370000200441106a200c290300370000200441086a200d290300370000200241f80d6a41086a20392903002209370300200241f80d6a41106a20062903002207370300200241f80d6a41186a20372903002213370300200220022903a80d22193703f80d20022802f00b2106200241c80d6a41186a22372013370300200241c80d6a41106a22392007370300200241c80d6a41086a223a2009370300200220193703c80d024020062802082203200641046a223b280200470d00200341016a223c2003490d172003410174223d203c203d203c4b1b223cad422c7e2209422088a70d172009a7223d4100480d170240024020030d00203d102121030c010b20062802002003412c6c203d102521030b2003450d0420062003360200203b203c360200200628020821030b203a2903002109203929030021072037290300211320022903c80d211920062802002003412c6c6a22034281808080103702242003200436022020032019370200200341186a2013370200200341106a2007370200200341086a20093702002006200628020841016a360208200241980e6a41086a2206200d290300370300200241980e6a41106a2204200c290300370300200241980e6a41186a2203200b290300370300200220022903e00e3703980e201b20032903003703002001200429030037030020362006290300370300200220022903980e3703800f0240200e201f470d00200e41016a2206200e490d17200a2006200a20064b1b221f41ffffff3f71201f470d17201f41057422064100480d1702400240200e0d002006102121180c010b201820082006102521180b2018450d030b201820086a220620022903800f370000200641186a201b290300370000200641106a2001290300370000200641086a2036290300370000200241a80c6a203810a301200a41026a210a200841206a2108200e41016a210e20022802a80c4101460d000b0b200241f00b6a10af04200241a80c6a20022802f00b220620022802f80b108a01024020022802f40b450d00200610230b200241b80e6a41086a200241a80c6a41086a22372903002209370300200241b80e6a41106a200241a80c6a41106a22392903002207370300200241b80e6a41186a200241a80c6a41186a223a2903002213370300200241b80e6a41206a200241a80c6a41206a220d2d000022063a0000200220022903a80c22193703b80e200241c80b6a41206a20063a0000200241c80b6a41186a2013370300200241c80b6a41106a2007370300200241c80b6a41086a2009370300200220193703c80b200241a80c6a200241c80b6a10a60102400240024002400240024002400240024020022d00d80c4102460d000340200241f00b6a41286a200241a80c6a41286a280200360200200241f00b6a41206a200d290300370300200241f00b6a41186a221b203a290300370300200241f00b6a41106a22012039290300370300200241f00b6a41086a22362037290300370300200220022903a80c3703f00b200d28020021084100210a024020022902cc0c2209422088a72203450d0020022802d40c210c4100210a41002106024003402006210502400240200a0d000340024020062003490d00200621050c240b2002200820064105746a3602980e200241e00e6a200241980e6a10b1040240024020022802e80e2205450d0020022802e40e2104024020022802ec0e450d00200510230b200641016a21062004200c4d0d010c040b200641016a21060b20062003490d000b4100210a0c040b0340200520034f0d222002200820054105746a22043602980e200241e00e6a200241980e6a10b1040240024020022802e80e22060d00200541016a21060c010b20022802e40e210b024020022802ec0e450d00200610230b200541016a2106200b200c4b0d020b02402005200a6b220520034f0d00200820054105746a22052004290000370000200541186a200441186a290000370000200541106a200441106a290000370000200541086a200441086a29000037000020062105200620034f0d040c010b0b41c4bcc00020052003102d000b200a41016a210a20062003490d000b0b200a450d00200620034f0d00200820064105746a2205200a4105746b2005200320066b41057410dd041a0b200241800f6a41186a2206201b290300370300200241800f6a41106a22052001290300370300200241800f6a41086a22042036290300370300200220022903f00b3703800f2008450d01200241c80d6a41186a220b2006290300370300200241c80d6a41106a220c2005290300370300200241c80d6a41086a221b2004290300370300200220022903800f3703c80d0240024020022802980b220520022802940b460d0020022802900b21060c010b200541016a22062005490d1f200541017422042006200420064b1b2204ad422c7e2207422088a70d1f2007a722014100480d1f0240024020050d002001102121060c010b20022802900b2005412c6c2001102521060b2006450d03200220043602940b200220063602900b0b201b2903002107200c2903002113200b290300211920022903c80d211a20062005412c6c6a2206200942ffffffff0f832003200a6bad42208684370224200620083602202006201a370200200641186a2019370200200641106a2013370200200641086a20073702002002200541016a3602980b200241a80c6a200241c80b6a10a60120022d00d80c4102470d000b0b200241c80b6a41186a22044200370300200241c80b6a41106a22034200370300200241c80b6a41086a22054200370300200242003703c80b200241980d6a41086a220641c6acc500ad4280808080f0008422091003220841086a290000370300200220082900003703980d2008102320052006290300370300200220022903980d22073703f80d200220073703c80b20064198f7c500ad4280808080e001841003220841086a290000370300200220082900003703980d20081023200241980e6a41086a220a20062903002207370300200220022903980d22133703980e20142013370000201441086a220b2007370000200241a80c6a41086a220c2005290300370300200241a80c6a41106a220d2003290300370300200241a80c6a41186a221b2004290300370300200220022903c80b3703a80c20024190046a200241a80c6a4120108f01200228029404213e200228029004213f200442003703002003420037030020054200370300200242003703c80b200620091003220841086a290000370300200220082900003703980d2008102320052006290300370300200220022903980d22093703f80d200220093703c80b200641b4f7c500ad4280808080d002841003220841086a290000370300200220082900003703980d20081023200a20062903002209370300200220022903980d22073703980e20142007370000200b2009370000200c2005290300370300200d2003290300370300201b2004290300370300200220022903c80b3703a80c20024188046a200241a80c6a4120108f01200228028c042106200228028804210520022802900b214020022802940b214120022802980b2137200242003702cc0b200241d8a7c3003602c80b2037200e6a223aad42e0007e2209422088a70d132009a72239417f4c0d134108211b0240024020390d0041082142410821430c010b203910212242450d02204221430b4100210d410021440240200e4105742203450d0020034105752244ad42d8007e2209422088a70d1d2009a722044100480d1d20041021221b450d030b2006410420051b223b41014b213c0240200e450d00200341606a2138200241d80c6a2105200241d00c6a2136201b210841002104201821060340200241800f6a41186a220a200641186a220b290000370300200241800f6a41106a220c200641106a220d290000370300200241800f6a41086a220e200641086a2201290000370300200220062900003703800f200241f00b6a41186a200b290000370300200241f00b6a41106a200d290000370300200241f00b6a41086a2001290000370300200220062900003703f00b200241c80b6a200241f00b6a200410cf01200241a80c6a41086a4200370300200241a80c6a41106a4200370300200241a80c6a41186a4200370300200241a80c6a41206a420037030020364200370300200541186a200a290300370000200541106a200c290300370000200541086a200e290300370000200520022903800f370000200242003703a80c2008200241a80c6a41d00010dc04220841d0006a41003a0000200841d8006a2108200641206a2106200441016a2104200341606a22030d000b203841057641016a210d0b203b4101203c1b21060240201f450d00201810230b0240200d2006490d0002400240203a2037412c6c2206412c6d2205490d00203a21450c010b203a41017422042005200420054b1b2245ad42e0007e2209422088a70d1e2009a722054100480d1e02400240203a0d002005102121420c010b204220392005102521420b2042450d05204221430b204020066a2146024020370d004100213d2040213c0c130b200241c80d6a41106a2101204021062042213b4100213d0340200241800f6a41186a2205200641186a290200370300200241800f6a41106a2204200641106a290200370300200241800f6a41086a2203200641086a290200370300200220062902003703800f2006412c6a213c20062802202238450d13200641286a280200210e200641246a2802002147200241f00b6a41186a22482005290300370300200241f00b6a41106a22492004290300370300200241f00b6a41086a224a2003290300370300200220022903800f3703f00b200241f8036a200241f00b6a10b604200ead42c8007e2209422088a70d152009a72206417f4c0d15200241f8036a41086a290300211a20022903f80321200240024020060d004108211f0c010b20061021221f450d070b02400240200e0d004100210e410021180c010b2038200e4105746a213a410021182038210a0340200a41086a2900002109200a41106a2900002107200a2900002113200241a80c6a41186a2236200a41186a290000370300200241a80c6a41106a22372007370300200241a80c6a41086a22392009370300200220133703a80c200a41206a210a200241c80b6a210620022802cc0b210b024003402006280200220841086a210520082f0106220c4105742106410021040240024003402006450d01200241a80c6a2005412010de042203450d02200641606a2106200441016a2104200541206a21052003417f4a0d000b2004417f6a210c0b200b450d02200b417f6a210b2008200c4102746a4194036a21060c010b0b200d200820044102746a41e8026a220528020022064d0d0a201b200641d8006c6a22062903202109200641286a2903002107200241c80d6a41186a2208420037030020014200370300200241c80d6a41086a22044200370300200242003703c80d200241980d6a41086a220641d5fbc400ad42808080808001841003220341086a290000370300200220032900003703980d2003102320042006290300370300200220022903980d3703c80d200641d6a0c200ad4280808080d001841003220341086a290000370300200220032900003703980d20031023200241e80d6a41086a20062903002213370300200220022903980d22193703e80d20012019370000200141086a2013370000200241a80d6a41086a2004290300370300200241a80d6a41106a2001290300370300200241a80d6a41186a2008290300370300200220022903c80d3703a80d200241e0036a200241a80d6a4120108902200241d0036a20022903e803200241e0036a41106a290300427f420010e204200d200528020022064d0d0b200241c0036a2020201a20022903d003420020022802e00322041b221342012013420156200241d0036a41086a290300420020041b22134200522013501b22041b2013420020041b10e204201b200641d8006c6a220641286a427f2007200920022903c0037c22132009542204ad7c221920042019200754201320095a1b22041b3703002006427f201320041b370320200241f80d6a41186a22042036290300370300200241f80d6a41106a22032037290300370300200241f80d6a41086a22082039290300370300200220022903a80c3703f80d20052802002105024002402018200e460d00201821060c010b200e41016a2206200e490d22200e410174220b2006200b20064b1b220bad42c8007e2209422088a70d222009a722064100480d2202400240200e0d0020061021211f0c010b201f200e41c8006c20061025211f0b201f450d0d200e2106200b210e0b201f200641c8006c6a2206420037030020062005360220200641186a4200370300200641106a4200370300200641086a4200370300200620022903f80d3702242006412c6a2008290300370200200641346a20032903003702002006413c6a2004290300370200201841016a21180b200a203a470d000b0b02402047450d00203810230b200241e00e6a41186a22032048290300370300200241e00e6a41106a22082049290300370300200241e00e6a41086a220a204a290300370300200220022903f00b3703e00e200241c80d6a41186a220b420037030020014200370300200241c80d6a41086a22054200370300200242003703c80d200241980d6a41086a220641d5fbc400ad42808080808001841003220441086a290000370300200220042900003703980d2004102320052006290300370300200220022903980d3703c80d200641d6a0c200ad4280808080d001841003220441086a290000370300200220042900003703980d20041023200241e80d6a41086a20062903002209370300200220022903980d22073703e80d20012007370000200141086a2009370000200241a80d6a41086a2005290300370300200241a80d6a41106a2001290300370300200241a80d6a41186a200b290300370300200220022903c80d3703a80d200241a8036a200241a80d6a412010890220024198036a20022903b003200241a8036a41106a290300427f420010e20420024188036a2020201a200229039803420020022802a80322061b22094201200942015620024198036a41086a290300420020061b22094200522009501b22061b2009420020061b10e204203b4200370308203b200229038803370300203b4200370310203b41186a4200370300203b41286a4200370300203b4201370320203b2018360238203b200e360234203b201f360230203b20022903e00e37023c203b41c4006a200a290300370200203b41cc006a2008290300370200203b41d4006a2003290300370200203d41016a213d203b41e0006a213b203c2106203c2046470d000c140b0b02402044450d00201b10230b0240203a450d00204210230b20022802c80b20022802cc0b20022802d00b10d00102402037450d002037412c6c2105204041206a210603400240200641046a280200450d00200628020010230b2006412c6a2106200541546a22050d000b0b2041450d19204010230c190b200141041030000b203941081030000b200441081030000b200541081030000b200641081030000b41a0abc2002006200d102d000b41c8a1c3002006200d102d000b200641081030000b200641011030000b203d41041030000b412041011030000b412041011030000b201b41041030000b412041011030000b200341011030000b200a41011030000b41c00041011030000b203c2046460d000340203c41206a2802002205450d01203c412c6a21060240203c41246a280200450d00200510230b2006213c20462006470d000b0b203e4100203f1b213b02402041450d00204010230b203bad42307e2209422088a70d002009a72206417f4c0d00024002400240024020060d00410821360c010b200610212236450d010b203b412c6c2206417f4c0d0202400240024020060d00410421460c010b200610212246450d010b4100213c0240200d203b200d203b491b223e0d00203b2140410021480c030b201b41a87f6a2147200d41d8006c21382043203d41e0006c6a211f200241800f6a41186a2149200241800f6a41106a214a200241800f6a41086a2141203b2139410021484100213a03400240200d450d0020382105201b210603400240200641d0006a2d00000d0002400240200641206a2903002207200641286a29030022138450450d0042002109427f2107427f21130c010b427f2109200241f8026a427f427f2007201310e204200241f8026a41086a290300211320022903f80221070b2006200737030020062013370308200641106a2009370300200641186a20093703000b200641d8006a2106200541a87f6a22050d000b0b204321030240203d450d0002400340024020032802382206450d00200641c8006c2104200328023041206a21060340200d200628020022054d0d030240201b200541d8006c6a22052d00500d0020052903202209200541286a290300220784500d00200241a80c6a2003290310200341186a2903002003290300200341086a2903002009200710c302200520052903002209427f2009427f20022903b00c20022802a80c41014622081b22137c22072007200954220a200541086a220b2903002209427f200241a80c6a41106a29030020081b22197c200aad7c220720095420072009511b22081b201320198450220a1b370300200b2009427f200720081b200a1b3703000b200641c8006a2106200441b87f6a22040d000b0b200341e0006a2203201f460d020c000b0b41e4ecc0002005200d102d000b203a41016a213a20382106204721040340024020060d00203921400c050b200641a87f6a2106200441a8016a2103200441d8006a2205210420032d00000d000b02402006450d00200541d8006a2104200541086a2903002109200541186a2903002107200541106a2903002113200529030021194100210303400240200441d0006a2d00000d00200441086a290300221a2009201920092013200720042903002220201a200441106a2903002223200441186a290300222210c40241ff017141014622081b21092020201920081b21192022200720081b21072023201320081b21132004200520081b21050b200441d8006a21042006200341d8006a2203470d000b20050d00203921400c040b200541013a00500240203d450d002005410c6a2101200541306a2118204321040340200441e0006a2137024020042802382203450d0020042802302106200341c8006c210303400240024020012006460d00200641246a2018412010de040d010b200441186a22082903002119200541086a220a290300210920042903102113200529030021072005290310211a200641186a200541186a220b290300370300200641106a201a370300200620094200200920197d2007201354ad7d221a200720137d2220200756201a200956201a2009511b220c1b201320198450220e1b3703082006200742002020200c1b200e1b370300200a2903002109200b29030021072005290300211320042005290310370320200441286a200737030020042013370310200820093703000b200641c8006a2106200341b87f6a22030d000b0b203721042037201f470d000b0b2049200541c8006a290000370300204a200541c0006a2900003703002041200541386a290000370300200220052900303703800f200541286a29030021092005290320210702400240024020482039460d00203921400c010b203941016a22062039490d0f203941017422052006200520064b1b2240ad42307e2213422088a70d0f2013a722064100480d0f0240024020390d002006102121360c010b2036203941306c2006102521360b2036450d0120392148204021390b20412903002113204a29030021192049290300211a20022903800f21202036204841306c6a2206200737032020062020370300200641286a2009370300200641186a201a370300200641106a2019370300200641086a2013370300204841016a2148203a203e4f0d040c010b0b200641081030000b200641041030000b200641081030000b0240203d450d002043203d41e0006c6a2147204841306c2137200241f00b6a41186a2139200241f00b6a41106a213a200241f00b6a41086a21384100213c2043210103402039200141d4006a290000370300203a200141cc006a2900003703002038200141c4006a2900003703002002200129003c3703f00b024020012802382206450d002001280230220c200641c8006c6a2118200141106a211f4100210d4104210e4100210b02400240024002400340200c220a41246a2104200a41c8006a210c410021032037210520362106024003402005450d01024020042006460d0020062004412010de042108200341016a2103200541506a2105200641306a210620080d010b0b418094ebdc0321060240201f200a10c5020d00410021050240200a290310200129032085200a41186a290300200141286a29030085844200520d00200241a80c6a428094ebdc034200200a290300200a41086a290300201f290300201f41086a29030010c30220022802a80c4101460d0120022903b00c220742ff93ebdc0356200241a80c6a41106a29030022094200522009501b0d012007a721050b200521060b200220063602a80c2002418094ebdc033602ac0c200241a80c6a2006418094ebdc034b4102746a2802002105200241980e6a41186a2204200a413c6a290000370300200241980e6a41106a2203200a41346a290000370300200241980e6a41086a2208200a412c6a2900003703002002200a2900243703980e02400240200b200d460d00200b21060c010b200d41016a2206200d490d13200d410174220a2006200a20064b1b220aad42247e2209422088a70d132009a722064100480d1302400240200d0d0020061021210e0c010b200e200d41246c20061025210e0b200e450d03200d2106200a210d0b200e200641246c6a220620022903980e37020020082903002109200329030021072004290300211320062005360220200641186a2013370200200641106a2007370200200641086a2009370200200b41016a210b0b200c2018470d000b0240200b450d0002400240200b41246c22040d00410021050c010b200e41206a2106410021050340200628020020056a2105200641246a21062004415c6a22040d000b0b02404100418094ebdc0320056b22062006418094ebdc034b1b220a200b6e2206418094ebdc032006418094ebdc03491b2208450d00200e41206a2106410021050340200b2005460d042002417f2006280200220420086a220320032004491b22043602a80c2002418094ebdc033602ac0c2006200241a80c6a2004418094ebdc034b4102746a280200360200200641246a2106200b200541016a2205470d000b0b0240200a2008200b6c6b2208450d00410021060340200b2006200b7022054d0d062002417f200e200541246c6a2205280220220441016a220320032004491b22043602a80c2002418094ebdc033602ac0c2005200241a80c6a2004418094ebdc034b4102746a280200360220200641016a22062008490d000b0b200241a80c6a41186a22052039290300370300200241a80c6a41106a2204203a290300370300200241a80c6a41086a22032038290300370300200220022903f00b3703a80c0240203c203b470d00203b41016a2206203b490d12203b41017422082006200820064b1b2206ad422c7e2209422088a70d122009a722084100480d1202400240203b0d002008102121460c010b2046203b412c6c2008102521460b2046450d04203b213c2006213b0b2046203c412c6c6a220620022903a80c3702002003290300210920042903002107200529030021132006200b3602282006200d3602242006200e360220200641186a2013370200200641106a2007370200200641086a2009370200203c41016a213c0c050b200d450d04200e10230c040b200641041030000b41ece2c0002005200b102d000b200841041030000b41ece2c0002005200b102d000b200141e0006a22012047470d000b0b02402044450d00201b10230b0240203d450d00203d41e0006c2105204341306a210603400240200641046a280200450d00200628020010230b200641e0006a2106200541a07f6a22050d000b0b02402045450d00204210230b20022802c80b20022802cc0b20022802d00b10d0012036450d06204841306c220641306e21050240024020060d00420021264101213e0c010b200541057422044100480d0a20041021223e450d052005ad21260b024002402036203620066a470d00410021490c010b204841306c210441002149203e210620362105034020062005290000370000200641186a200541186a290000370000200641106a200541106a290000370000200641086a200541086a290000370000204941016a2149200641206a2106200541306a2105200441506a22040d000b0b200242003702840f200241d8a7c3003602800f02402049450d0020494105742105203e21060340200241c80b6a41186a200641186a290000370300200241c80b6a41106a200641106a290000370300200241c80b6a41086a200641086a290000370300200220062900003703c80b200241a80c6a41186a4200370300200241a80c6a41106a4200370300200241a80c6a41086a4200370300200242003703a80c200241003602d00c200242083703c80c200241f00b6a200241800f6a200241c80b6a200241a80c6a10ce01024020022802900c2204450d0020022802940c450d00200410230b200641206a2106200541606a22050d000b0b0240203c412c6c2206450d00204620066a211f200241c80d6a41106a210e41d5fbc400ad4280808080800184211a2046210d03400240200d28022841246c2206450d00200d280220221b20066a21010340200241e8026a200d10b604200241e8026a41086a290300210720022903e8022113200241c80d6a41186a22034200370300200e4200370300200241c80d6a41086a22054200370300200242003703c80d200241980d6a41086a2206201a1003220441086a290000370300200220042900003703980d2004102320052006290300370300200220022903980d3703c80d200641d6a0c200ad4280808080d001841003220441086a290000370300200220042900003703980d20041023200241e80d6a41086a20062903002209370300200220022903980d22193703e80d200e2019370000200e41086a2009370000200241a80d6a41086a2005290300370300200241a80d6a41106a200e290300370300200241a80d6a41186a2003290300370300200220022903c80d3703a80d200241d0026a200241a80d6a4120108902200241c0026a20022903d802200241d0026a41106a290300427f420010e204200241b0026a2013200720022903c002420020022802d00222061b220942012009420156200241c0026a41086a290300420020061b22094200522009501b22061b2009420020061b10e204200241a0026a20022903b0022209428094ebdc038022074200201b22083502202213420010e104200241a0026a41086a29030020022903a00222192013200920074280ec94a37c7e7c7e22092009428094ebdc038022094280ec94a37c7e7c4280cab5ee01562009a76aad7c2209201954ad7c2107200841246a211b200241800f6a210620022802840f210b0240024003402006280200220a41086a2105200a2f0106220c4105742106410021040240024003402006450d0120082005412010de042203450d02200641606a2106200441016a2104200541206a21052003417f4a0d000b2004417f6a210c0b200b450d02200b417f6a210b200a200c4102746a41f8066a21060c010b0b200a41e8026a200441306c6a210602402008200d460d002008200d412010de04450d002006427f2006290310221320097c221920192013542205200641186a2204290300221320077c2005ad7c221920135420192013511b22051b3703102004427f201920051b370300200241f80d6a41186a2208200d41186a290000370300200241f80d6a41106a220a200d41106a290000370300200241f80d6a41086a220b200d41086a2900003703002002200d2900003703f80d200641286a2104200641206a2103024020062802282205200641246a280200470d00200541016a22062005490d112005410174220c2006200c20064b1b220cad42307e2213422088a70d112013a722184100480d110240024020050d002018102121060c010b2003280200200541306c2018102521060b2006450d0320032006360200200341046a200c360200200428020021050b200b2903002113200a29030021192008290300212020022903f80d21232003280200200541306c6a2206200937032020062023370300200641286a2007370300200641186a2020370300200641106a2019370300200641086a20133703002004200428020041016a3602000c010b2006427f2006290300221320097c221920192013542205200641086a2204290300221320077c2005ad7c221920135420192013511b22051b3703002004427f201920051b3703002006427f2006290310221320097c220920092013542205200641186a2204290300220920077c2005ad7c220720095420072009511b22051b3703102004427f200720051b3703000b201b2001460d020c010b0b201841081030000b200d412c6a220d201f470d000b0b20022802880f210e20022802840f210820022802800f2105200241a80c6a41186a220a4200370300200241a80c6a41106a220b4200370300200241a80c6a41086a22044200370300200242003703a80c200241980d6a41086a220641c6acc500ad4280808080f000841003220341086a290000370300200220032900003703980d2003102320042006290300370300200220022903980d3703a80c20064185b2c500ad4280808080e001841003220341086a290000370300200220032900003703980d20031023200241980e6a41086a20062903002209370300200220022903980d22073703980e200f2007370000200f41086a2009370000200241c80b6a41086a2004290300370300200241c80b6a41106a200b290300370300200241c80b6a41186a200a290300370300200220022903a80c3703c80b200241a80c6a200241c80b6a412010bb0120022902ac0c420020022802a80c22061b210702402006410120061b220d450d002007422088a72206450d002006410574210a41c6acc500ad4280808080f000842109200241d80b6a210c200d21040340200241980d6a41086a220620091003220341086a290000370300200220032900003703980d20031023200241f80d6a41086a220b2006290300370300200220022903980d3703f80d200641fdacc500ad4280808080f000841003220341086a290000370300200220032900003703980d20031023200241980e6a41086a22032006290300370300200220022903980d3703980e200241c80b6a200410ac0141c00010212206450d03200441206a2104200620022903f80d370000200641086a200b290300370000200620022903980e370010200641186a2003290300370000200620022903c80b370020200641286a200241c80b6a41086a290300370000200641306a200c290300370000200641386a200241c80b6a41186a2903003700002006ad4280808080800884100520061023200a41606a220a0d000b0b02402007a7450d00200d10230b0240024020080d00200521060c010b2008210420052106034020062802f80621062004417f6a22040d000b0340200520052f01064102746a41f8066a28020021052008417f6a22080d000b0b2002418c0c6a20052f0106360200200241f00b6a41186a4100360200200241840c6a20053602002002200e3602900c200241003602800c200242003703f80b200220063602f40b200241003602f00b200241a80c6a200241f00b6a10b6010240200241a80c6a41c0006a28020022370d00427f2125427f21220c060b200241c80d6a41106a2103200241a80c6a41106a2118200241a80c6a41386a2142200241a80c6a41286a2143427f2125427f21220340200241e00e6a41086a200241a80c6a41086a22062903002209370300200241e00e6a41106a20182903002207370300200241e00e6a41186a200241a80c6a41186a221f2903002213370300200220022903a80c22193703e00e204229030021232043290300212420022802ec0c214a20022802f00c210a20022903d80c212b20022903c80c212f200241800f6a41186a2013370300200241800f6a41106a2007370300200241800f6a41086a2009370300200220193703800f201f42003703002018420037030020064200370300200242003703a80c200241980d6a41086a220441d5fbc400ad4280808080800184221a1003220541086a290000370300200220052900003703980d2005102320062004290300370300200220022903980d3703a80c200441d6a0c200ad4280808080d0018422201003220541086a290000370300200220052900003703980d20051023200241980e6a41086a223a20042903002209370300200220022903980d22073703980e200f2007370000200f41086a220b2009370000200241c80b6a41086a22382006290300370300200241c80b6a41106a223d2018290300370300200241c80b6a41186a2247201f290300370300200220022903a80c3703c80b20024188026a200241c80b6a4120108902200241e0016a20022903900220024188026a41106a290300427f420010e2042002280288022105201f42003703002018420037030020064200370300200242003703a80c2004201a1003220841086a290000370300200220082900003703980d2008102320062004290300370300200220022903980d3703a80c200420201003220841086a290000370300200220082900003703980d20081023203a20042903002209370300200220022903980d22073703980e200f2007370000200b200937000020382006290300370300203d20182903003703002047201f290300370300200220022903a80c3703c80b200241f0016a200241c80b6a4120108902200241d0016a20022903f801200241f0016a41106a290300427f420010e204200241b0016a20022903e001420020051b220942012009420156200241e0016a41086a290300420020051b22094200522009501b22061b2009420020061b202f202410e104200241c0016a20022903d001420020022802f00122061b220942012009420156200241d0016a41086a290300420020061b22094200522009501b22061b2009420020061b202b202310e104200a41306c220c41306d2106200241b0016a41086a290300212b200241c0016a41086a29030021234100210b20022903b001212f20022903c001212441002148410821390240200c450d002006ad42307e2209422088a70d0b2009a722054100480d0b200510212239450d04200621480b02402037200c6a2037460d004100210b20392106203721050340200541286a2903002107200541206a2903002113200241f80d6a41186a220d200541186a290300370300200241f80d6a41106a220e200541106a290300370300200241f80d6a41086a221b200541086a290300370300200220052903003703f80d200241c80d6a41186a2201420037030020034200370300200241c80d6a41086a22084200370300200242003703c80d2004201a1003220a41086a2900003703002002200a2900003703980d200a102320082004290300370300200220022903980d3703c80d200420201003220a41086a2900003703002002200a2900003703980d200a1023200241e80d6a41086a20042903002209370300200220022903980d22193703e80d20032019370000200341086a2009370000200241a80d6a41086a2008290300370300200241a80d6a41106a2003290300370300200241a80d6a41186a2001290300370300200220022903c80d3703a80d20024198016a200241a80d6a412010890220024188016a20022903a00120024198016a41106a290300427f420010e204200241f8006a200229038801420020022802980122081b22094201200942015620024188016a41086a290300420020081b22094200522009501b22081b2009420020081b2013200710e1042006200241f8006a41086a29030037030820062002290378370300200641106a20022903f80d370300200641186a201b290300370300200641206a200e290300370300200641286a200d290300370300200641306a2106200b41016a210b200541306a2105200c41506a220c0d000b0b0240204a450d00203710230b200bad42307e2209422088a70d012009a72206417f4c0d010240024020060d004108210c0c010b20061021220c450d050b02400240200b0d00410021080c010b2039200b41306c6a210a41002108200c2106203921050340200620052903003703002006200541086a290300370308200641106a200541106a290300370300200641186a200541186a290300370300200641206a200541206a290300370300200641286a200541286a290300370300200641306a2106200841016a2108200541306a2205200a470d000b0b201f202b3703002002202f3703b80c200220243703a80c200220083602d00c2002200b3602cc0c2002200c3602c80c200220233703b00c200441c6acc500ad4280808080f000841003220641086a290000370300200220062900003703980d20061023200241f80d6a41086a22052004290300370300200220022903980d3703f80d200441fdacc500ad4280808080f000841003220641086a290000370300200220062900003703980d20061023203a2004290300370300200220022903980d3703980e200241c80b6a200241800f6a10ac01024041c00010212204450d00200420022903f80d370000200441086a2005290300370000200420022903980e370010200441186a203a290300370000200420022903c80b370020200441286a2038290300370000200441306a203d290300370000200441386a2047290300370000200241003602d00b200242013703c80b2002200241a80c6a3602980e200241980e6a200241c80b6a10c301200220183602980e200241980e6a200241c80b6a10c30120022802c80c210620022802d00c2205200241c80b6a105c02402005450d00200541306c21050340200641106a200241c80b6a1071200220063602980e200641306a2106200241980e6a200241c80b6a10c301200541506a22050d000b0b20022802cc0b21062004ad428080808080088420023502d00b42208620022802c80b2205ad84100202402006450d00200510230b20242025542106202320225121052023202254210820041023024020022802cc0c450d0020022802c80c10230b2006200820051b210602402048450d00203910230b2023202220061b21222024202520061b2125200241a80c6a200241f00b6a10b60120022802e80c2237450d070c010b0b41c00041011030000b102f000b41c00041011030000b200541081030000b200641081030000b200441011030000b200241f00b6a10d401200241c80b6a41186a22044200370300200241c80b6a41106a22034200370300200241c80b6a41086a22054200370300200242003703c80b200241980d6a41086a220641c6acc500ad4280808080f0008422091003220841086a290000370300200220082900003703980d2008102320052006290300370300200220022903980d22073703f80d200220073703c80b20064193b2c500ad42808080809001841003220841086a290000370300200220082900003703980d20081023200241980e6a41086a220a20062903002207370300200220022903980d22133703980e20142013370000201441086a220b2007370000200241a80c6a41086a220c2005290300370300200241a80c6a41106a220d2003290300370300200241a80c6a41186a220e2004290300370300200220022903c80b3703a80c200220223703f80b200220253703f00b201d201e42808080808002841002200442003703002003420037030020054200370300200242003703c80b200620091003220841086a290000370300200220082900003703980d2008102320052006290300370300200220022903980d22093703f80d200220093703c80b20064185b2c500ad4280808080e001841003220841086a290000370300200220082900003703980d20081023200a20062903002209370300200220022903980d22073703980e20142007370000200b2009370000200c2005290300370300200d2003290300370300200e2004290300370300200220022903c80b3703a80c200241003602f80b200242013703f00b2049200241f00b6a105c02402049450d0020494105742105203e210603402006200241f00b6a1071200641206a2106200541606a22050d000b0b20022802f40b2106201d20023502f80b42208620022802f00b2205ad84100202402006450d00200510230b2049ad21090240203c450d00203c412c6c2105204641206a210603400240200641046a280200450d00200628020010230b2006412c6a2106200541546a22050d000b0b200942208621090240203b450d00204610230b202620098421292040450d01203610230c010b200241c80b6a41186a22034200370300200241c80b6a41106a22084200370300200241c80b6a41086a22054200370300200242003703c80b200241980d6a41086a220641c6acc500ad4280808080f000841003220441086a290000370300200220042900003703980d2004102320052006290300370300200220022903980d22093703f80d200220093703c80b20064193b2c500ad42808080809001841003220441086a290000370300200220042900003703980d20041023200241980e6a41086a20062903002209370300200220022903980d22073703980e20142007370000201441086a2009370000200241a80c6a41086a2005290300370300200241a80c6a41106a2008290300370300200241a80c6a41186a2003290300370300200220022903c80b3703a80c200241e0006a200241a80c6a41201089024100213e0b200241c80b6a41186a22404200370300200241c80b6a41106a22444200370300200241c80b6a41086a22434200370300200242003703c80b200241980d6a41086a224241c6acc500ad4280808080f00084222e1003220641086a290000370300200220062900003703980d2006102320432042290300370300200220022903980d22093703f80d200220093703c80b204241f8ffc500ad4280808080e0028422281003220641086a290000370300200220062900003703980d20061023200241980e6a41086a223f20422903002209370300200220022903980d22073703980e20142007370000201441086a22452009370000200241a80c6a41086a224b2043290300370300200241a80c6a41106a224c2044290300370300200241a80c6a41186a224d2040290300370300200220022903c80b3703a80c200241d8006a200241a80c6a4120108f01200228025c214102402002280258224e4101470d00024020414100203541796a2206200620354b1b22464f0d00200241a00b6aad4280808080800284212b200241a80d6aad4280808080800484212f201c4280808080c00084212d200241c80d6a41106a2106200241c80b6a41086a211b200241a80c6a41386a2149200241a80c6a41246a213a2041214a0340200241980d6a41086a220141c6acc500ad4280808080f000841003220541086a290000370300200220052900003703980d20051023200241f80d6a41086a22082001290300370300200220022903980d3703f80d2001419cb2c500ad42808080808002841003220541086a290000370300200220052900003703980d20051023200241980e6a41086a22482001290300370300200220022903980d3703980e2002204a3602a80c200241c80d6a41186a2203202d1001220541186a2900003703002006200541106a290000370300200241c80d6a41086a2204200541086a290000370300200220052900003703c80d20051023200241c80b6a41186a223b2003290300370300200241c80b6a41106a220a2006290300370300201b2004290300370300200220022903c80d3703c80b0240024041c00010212205450d00200520022903f80d370000200541086a2008290300370000200520022903980e370010200541186a2048290300370000200520022903c80b370020200541286a201b290300370000200541306a200a290300370000200541386a203b290300370000200241a80c6a200541c00010a8030240024020022802a80c2235450d002005ad4280808080800884100520022902ac0c212c0c010b4200212c410821350b200510232035202c422088a7220541d8006c6a213c2035210e2005450d010340203b200e41186a290300370300200a200e41106a290300370300201b200e41086a290300370300200e280220210c200e2903002109200241a80c6a41206a220d200e41c4006a290200370300200241a80c6a41286a2218200e41cc006a290200370300200241a80c6a41306a221f200e41d4006a280200360200200241a80c6a41086a2205200e412c6a290200370300200241a80c6a41106a2208200e41346a290200370300200241a80c6a41186a220b200e413c6a290200370300200220093703c80b2002200e41246a2902003703a80c200e41d8006a210e200c450d02200241b80e6a41186a2236203b290300370300200241b80e6a41106a2237200a290300370300200241b80e6a41086a2239201b290300370300200241f00b6a41086a220f2005290300370300200241f00b6a41106a22382008290300370300200241f00b6a41186a223d200b290300370300200241f00b6a41206a2247200d290300370300200241f00b6a41286a220d2018290300370300200241f00b6a41306a2218201f280200360200200220022903c80b3703b80e200220022903a80c3703f00b200b20362903003703002008203729030037030020052039290300370300203a20022903f00b370200203a41086a200f290300370200203a41106a2038290300370200203a41186a203d290300370200203a41206a2047290300370200203a41286a200d290300370200203a41306a2018280200360200200220022903b80e3703a80c2002200c3602c80c200242003703a00e200242003703980e2002200b2903003703e80e200220082903003703e00e204920022903a80c2005290300200241e00e6a200241980e6a10b704024020022802d00c2208450d0020022802c80c2105200841306c210803402005200541206a290300200541286a290300200241e00e6a200241980e6a10b704200541306a2105200841506a22080d000b0b2048290300213120022903980e21340240024020022903e00e2207200241e00e6a41086a290300220984500d0020022802dc0c2205450d0020022802d40c2108200241c8006a203420072034200754203120095420312009511b220b1b223220312009200b1b22302005ad420010e2042005410574210b200241c8006a41086a290300212320022903482122203221192030211a0340200241386a2008202220192019202256201a202356201a2023511b22051b22092023201a20051b2207109702200a2007200241386a41086a29030022207d20092002290338221354ad7d202020077d2013200954ad7d20132009582020200758202020075122051b220c1b3703002002200920137d201320097d200c1b3703d00b20022013200956202020075620051b2205ad3703c80b201a20077d21072019200954ad21130240024020050d002002201b3602f80d200342003703002006420037030020044200370300200242003703c80d200241a00b6a41086a220541d5fbc400ad428080808080018422201003220c41086a2900003703002002200c2900003703a00b200c102320042005290300370300200220022903a00b221a3703800f2002201a3703c80d200541d6a0c200ad4280808080d0018422241003220c41086a2900003703002002200c2900003703a00b200c1023200241800f6a41086a220d2005290300221a370300200220022903a00b22253703800f20062025370000200641086a2218201a370000200241a80d6a41086a221f2004290300370300200241a80d6a41106a22362006290300370300200241a80d6a41186a22372003290300370300200220022903c80d3703a80d200241086a200241a80d6a4120108902200241086a41106a29030021252002290310212620022802082105200a290300213320022903d00b211a200342003703002006420037030020044200370300200242003703c80d200241e80d6a41086a223920201003220c41086a2900003703002002200c2900003703e80d200c102320042039290300370300200220022903e80d22203703800f200220203703c80d200120241003220c41086a2900003703002002200c2900003703980d200c1023200d20012903002220370300200220022903980d22243703800f2006202437000020182020370000201f20042903003703002036200629030037030020372003290300370300200220022903c80d3703a80d200242002025420020051b222020337d2026420020051b2224201a54ad7d22252024201a7d221a202456202520205620252020511b22051b3703a80b20024200201a20051b3703a00b0c010b2002201b3602f80d200342003703002006420037030020044200370300200242003703c80d200241a00b6a41086a220541d5fbc400ad4280808080800184221a1003220c41086a2900003703002002200c2900003703a00b200c102320042005290300370300200220022903a00b22203703800f200220203703c80d200541d6a0c200ad4280808080d0018422201003220c41086a2900003703002002200c2900003703a00b200c1023200241800f6a41086a221820052903002224370300200220022903a00b22253703800f20062025370000200641086a221f2024370000200241a80d6a41086a22362004290300370300200241a80d6a41106a22372006290300370300200241a80d6a41186a22392003290300370300200220022903c80d3703a80d200241206a200241a80d6a4120108902200241206a41106a2903002124200229032821252002280220210c200a290300212620022903d00b2133200342003703002006420037030020044200370300200242003703c80d2005201a1003220d41086a2900003703002002200d2900003703a00b200d102320042005290300370300200220022903a00b221a3703800f2002201a3703c80d200520201003220d41086a2900003703002002200d2900003703a00b200d102320182005290300221a370300200220022903a00b22203703800f20062020370000201f201a370000203620042903003703002037200629030037030020392003290300370300200220022903c80d3703a80d2002427f202620244200200c1b221a7c203320254200200c1b22207c22242020542205ad7c222020052020201a542020201a511b22051b3703a80b2002427f202420051b3703a00b0b202f202b1002200720137d211a201920097d2119200841206a2108200b41606a220b0d000b427f203420327d220920197c220720072009542205203120307d2034203254ad7d2209201a7c2005ad7c220720095420072009511b22051b427f200720051b10c9020c010b2034203110c9020b024020022802cc0c450d0020022802c80c10230b024020022802d80c450d0020022802d40c10230b200e203c470d000b203c210e0c010b41c00041011030000b202ca721080240200e203c460d000340200e41206a2802002204450d01200e41306a2802002105200e412c6a28020021030240200e41246a280200450d00200410230b200e41d8006a210e02402005450d00200310230b203c200e470d000b0b204a41016a214a02402008450d00203510230b204a2046470d000b0b20412046204120464b1b21410b204042003703002044420037030020434200370300200242003703c80b2042202e1003220641086a290000370300200220062900003703980d2006102320432042290300370300200220022903980d22093703f80d200220093703c80b204220281003220641086a290000370300200220062900003703980d20061023203f20422903002209370300200220022903980d22073703980e2014200737000020452009370000204b2043290300370300204c2044290300370300204d2040290300370300200220022903c80b3703a80c02400240204e0d00201d10050c010b200220413602f00b201d201e4280808080c0008410020b024020152017a745720d00201610230b0240203e0d002000410036020002402011450d00201141d0006c2105201041c0006a210603400240200641046a280200450d00200628020010230b200641d0006a2106200541b07f6a22050d000b0b2012450d03201010230c030b200020293702042000203e360200200041146a2011360200200041106a20123602002000410c6a20103602000c020b41f0bbc00020052003102d000b102a000b200241a00f6a24000bd50501087f230041c0006b22022400200241086a220341f7fbc400ad4280808080f000841003220441086a2900003703002002200429000037030020041023200241206a41086a2003290300370300200220022903003703202003418eadc200ad42808080808001841003220441086a2900003703002002200429000037030020041023200241306a41086a20032903003703002002200229030037033020024181adc200410d10d7020240024002400240024002400240024002402002280208220541206a2206417f4c0d0020022802002107024002402006450d00200610212203450d032006410f4d0d01200621040c060b200641017422034110200341104b1b2204102121030c040b200641017422044110200441104b1b220441004e0d020c050b102f000b200641011030000b200320062004102521030b20030d00200441011030000b20032002290320370000200341086a200241206a41086a290300370000024020044170714110470d00200441017422084120200841204b1b22084100480d0120032004200810252203450d02200821040b20032002290330370010200341186a200241306a41086a2903003700000240200441606a20054f0d00200541206a22082005490d01200441017422092008200920084b1b22084100480d0120032004200810252203450d03200821040b200341206a2007200510dc041a02402002280204450d00200710230b2002200110ac010240200420066b411f4b0d00200641206a22072006490d01200441017422012007200120074b1b22074100480d0120032004200710252203450d04200721040b200320066a22062002290000370000200641186a200241186a290000370000200641106a200241106a290000370000200641086a200241086a2900003700002000200541c0006a3602082000200436020420002003360200200241c0006a24000f0b102a000b200841011030000b200841011030000b200741011030000bd60201027f23004180036b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022010d00200041003a00000c010b200328021421042003200341186a2802003602ec02200320013602e802200341c0016a200341e8026a10ce02410121020240024020032d00c0014101460d00200341206a200341c0016a41017241a00110dc041a200041016a200341206a41a00110dc041a0c010b4100210220034100360228200342013703202003410c3602f4022003200341086a3602f0022003200341206a3602fc02200341d4016a4101360200200342013702c40120034198c2c3003602c0012003200341f0026a3602d001200341fc026a41b8a3c500200341c0016a102e1a200335022842208620033502208410082003280224450d00200328022010230b200020023a00002004450d00200110230b20034180036a24000be62f0b067f017e017f027e027f017e037f017e207f027e1a7f230041e0016b22022400200241206a200041f4f5c100108501200241306a20014180f8c100108501200228022821032002280224210420022802202105200241c0006a41086a200241306a41086a28020036020020022002290330370340200241d0006a41186a22064200370300200241d0006a41106a22074200370300200241d0006a41086a2200420037030020024200370350200241d0016a41086a220141cafbc400ad4280808080c0008422081003220941086a290000370300200220092900003703d0012009102320002001290300370300200220022903d001220a3703a0012002200a370350200141e4cfc300ad4280808080a00184220b1003220941086a290000370300200220092900003703d00120091023200720022903d001220a37030020024180016a41086a2209200029030037030020024180016a41106a220c200a37030020024180016a41186a220d20012903003703002002200a3703a0012002200229035037038001200241106a20024180016a109c0202400240024002400240024002400240024002400240024002400240024002400240024002402002290318420020022802101b220e42017c220a200e540d0020064200370300200742003703002000420037030020024200370350200120081003220f41086a2900003703002002200f2900003703d001200f102320002001290300370300200220022903d001220e3703a0012002200e3703502001200b1003220f41086a2900003703002002200f2900003703d001200f1023200241a0016a41086a22102001290300220b370300200220022903d001220e3703a0012007200e370000200741086a2211200b37000020092000290300370300200c2007290300370300200d200629030037030020022002290350370380012002200a37035020024180016aad4280808080800484220e200241d0006aad220b4280808080800184100220064200370300200742003703002000420037030020024200370350200120081003220f41086a2900003703002002200f2900003703d001200f102320002001290300370300200220022903d00122083703a00120022008370350200141fccfc300ad4280808080b001841003220f41086a2900003703002002200f2900003703d001200f1023201020012903002208370300200220022903d00122123703a001200720123700002011200837000020092000290300370300200c2007290300370300200d2006290300370300200220022903503703800120024100360258200242013703502003200241d0006a105c02402003450d002005200341286c6a21092005210003402000200241d0006a1071200041206a29030021080240024020022802542206200228025822016b4108490d00200228025021060c010b200141086a22032001490d15200641017422012003200120034b1b22014100480d150240024020060d002001102121060c010b200228025020062001102521060b2006450d042002200136025420022006360250200228025821010b2002200141086a360258200620016a20083700002009200041286a2200470d000b0b20022802542101200e200235025842208620022802502200ad84100202402001450d00200010230b02402004450d00200510230b200a42017c2212200a540d0220024180016a41186a2206420037030020024180016a41106a2211420037030020024180016a41086a220042003703002002420037038001200241d0016a41086a220141cafbc400ad4280808080c0008422081003220341086a290000370300200220032900003703d0012003102320002001290300370300200220022903d001220a3703a0012002200a37038001200141dcd1c300ad4280808080e001841003220341086a290000370300200220032900003703d00120031023201120022903d001220a370300200241b0016a41086a22032000290300370300200241b0016a41106a2209200a370300200241b0016a41186a220c20012903003703002002200a3703a00120022002290380013703b001200241d0006a200241b0016a109d03410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f410021204100212141002122410021234100212441002125410021264100212741002128410021294100212a4100212b4100212c4100212d4100212e4100212f410021304100213141002132024020022d00504101470d00200241d0006a41086a2d0000211a200241d9006a2d0000211b200241da006a2d0000211c200241db006a2d0000211d200241dc006a2d0000211e200241dd006a2d0000211f200241de006a2d00002120200241df006a2d00002121200241d0006a41106a2d00002122200241e1006a2d00002123200241e2006a2d00002124200241e3006a2d00002125200241e4006a2d00002126200241e5006a2d00002127200241e6006a2d00002128200241e7006a2d00002129200241d0006a41186a2d0000212a200241e9006a2d0000212b200241ea006a2d0000212c200241eb006a2d0000212d200241ec006a2d0000212e200241ed006a2d0000212f200241ee006a2d00002130200241ef006a2d00002131200241f0006a2d0000213220022d0051211320022d0052211420022d0053211520022d0054211620022d0055211720022d0056211820022d005721190b2006420037030020114200370300200042003703002002420037038001200120081003220d41086a2900003703002002200d2900003703d001200d102320002001290300370300200220022903d001220a3703a0012002200a3703800120014184d2c300ad4280808080c00184220a1003220d41086a2900003703002002200d2900003703d001200d1023200241a0016a41086a220f20012903002233370300200220022903d00122343703a00120112034370000201141086a220520333700002003200029030037030020092011290300370300200c200629030037030020022002290380013703b001200241086a200241b0016a4120108f01200228020c2104200228020821102006420037030020114200370300200042003703002002420037038001200120081003220d41086a2900003703002002200d2900003703d001200d102320002001290300370300200220022903d00122083703a00120022008370380012001200a1003220d41086a2900003703002002200d2900003703d001200d1023200f20012903002208370300200220022903d001220a3703a0012011200a370000200520083700002003200029030037030020092011290300370300200c200629030037030020022002290380013703b00120024100360250200241b0016aad42808080808004842233200b4280808080c000841002417f2004410020101b220541016a220120012005491b410d744128722235417f4c0d03203510212203450d0420032012370020200320323a001f200320313a001e200320303a001d2003202f3a001c2003202e3a001b2003202d3a001a2003202c3a00192003202b3a00182003202a3a0017200320293a0016200320283a0015200320273a0014200320263a0013200320253a0012200320243a0011200320233a0010200320223a000f200320213a000e200320203a000d2003201f3a000c2003201e3a000b2003201d3a000a2003201c3a00092003201b3a00082003201a3a0007200320193a0006200320183a0005200320173a0004200320163a0003200320153a0002200320143a0001200320133a00004128211041002100410021044100210f410021010340024002400240024002402001450d0020362006470d010b03402001210c200020054f0d02200241d0016a2000109e0220024180016a20022802d001220920022802d8012201109f0202402002280280012206450d002001ad4220862009ad8410050b20022902840121082006410120061b2101024020022802d401450d00200910230b2001450d022008420020061b2208422088a721060240200c450d00200d450d00200f10230b200041016a21002008a7210d2001210f200121042006450d000b200120064105746a2136200121042001210f200121060b200241b0016a41186a200641186a2209290000370300200241b0016a41106a200641106a220c290000370300200241b0016a41086a200641086a2237290000370300200220062900003703b00120372900002108200c290000210a2006290000210b200241d0006a41186a220c2009290000370300200241d0006a41106a2209200a370300200241d0006a41086a223720083703002002200b37035020024180016a41186a2238200c29030037030020024180016a41106a220c200929030037030020024180016a41086a223920372903003703002002200229035037038001203520106b411f4b0d02201041206a22092010490d16203541017422372009203720094b1b220941004e0d010c160b0240200c450d00200d450d00200410230b2010ad4220862003ad84100122012d001f210920012d001e210c20012d001d210d20012d001c210f20012d001b210520012d001a210420012d0019211020012d0018213720012d0017213820012d0016213920012d0015213620012d0014213a20012d0013213b20012d0012213c20012d0011213d20012d0010213e20012d000f213f20012d000e214020012d000d214120012d000c214220012d000b214320012d000a214420012d0009214520012d0008214620012d0007214720012d0006214820012d0005214920012d0004214a20012d0003214b20012d0002214c20012d0001214d20012d0000214e2001102302402035450d00200310230b20024180016a41186a2203420037030020024180016a41106a2235420037030020024180016a41086a220042003703002002420037038001200241d0016a41086a220141cafbc400ad4280808080c000841003220641086a290000370300200220062900003703d0012006102320002001290300370300200220022903d00122083703a0012002200837038001200141dcd1c300ad4280808080e001841003220641086a290000370300200220062900003703d00120061023200241a0016a41086a20012903002208370300200220022903d001220a3703a0012011200a370000201141086a2008370000200241b0016a41086a2000290300370300200241b0016a41106a2035290300370300200241b0016a41186a200329030037030020022002290380013703b001410110212201450d092001204e3a000020014101410210252201450d0a2001204d3a000120014102410410252201450d0b2001204b3a00032001204c3a000220014104410810252201450d0c200120473a0007200120483a0006200120493a00052001204a3a000420014108411010252201450d0d2001203f3a000f200120403a000e200120413a000d200120423a000c200120433a000b200120443a000a200120453a0009200120463a000820014110412010252201450d0e200120093a001f2001200c3a001e2001200d3a001d2001200f3a001c200120053a001b200120043a001a200120103a0019200120373a0018200120383a0017200120393a0016200120363a00152001203a3a00142001203b3a00132001203c3a00122001203d3a00112001203e3a001020332001ad4280808080800484100220011023200241d0006a41186a22034200370300200241d0006a41106a22094200370300200241d0006a41086a2200420037030020024200370350200241d0016a41086a220141cafbc400ad4280808080c000841003220641086a290000370300200220062900003703d0012006102320002001290300370300200220022903d00122083703a00120022008370350200141f8d0c300ad4280808080a001841003220641086a290000370300200220062900003703d00120061023200241a0016a41086a20012903002208370300200220022903d001220a3703a0012007200a370000200741086a200837000020024180016a41086a200029030037030020024180016a41106a200929030037030020024180016a41186a20032903003703002002200229035037038001410110212201450d0f200120133a000020014101410210252201450d10200120143a000120014102410410252201450d11200120163a0003200120153a000220014104410810252201450d122001201a3a0007200120193a0006200120183a0005200120173a000420014108411010252201450d13200120223a000f200120213a000e200120203a000d2001201f3a000c2001201e3a000b2001201d3a000a2001201c3a00092001201b3a000820014110412010252201450d14200120323a001f200120313a001e200120303a001d2001202f3a001c2001202e3a001b2001202d3a001a2001202c3a00192001202b3a00182001202a3a0017200120293a0016200120283a0015200120273a0014200120263a0013200120253a0012200120243a0011200120233a0010200e2001ad4280808080800484100220011023200241d0006a41186a22004200370300200241d0006a41106a22064200370300200241d0006a41086a2203420037030020024200370350200241d0016a41086a220141cafbc400ad4280808080c000841003220941086a290000370300200220092900003703d0012009102320032001290300370300200220022903d00122083703a00120022008370350200141dcd1c300ad4280808080e001841003220941086a290000370300200220092900003703d00120091023200241a0016a41086a20012903002208370300200220022903d001220a3703a0012007200a370000200741086a200837000020024180016a41086a200329030037030020024180016a41106a200629030037030020024180016a41186a20002903003703002002200229035037038001200241d0006a20024180016a109d0341002101410021094100210c4100210d4100210f41002105410021044100210741002110410021114100213541002137410021384100213941002136410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f41002120410021214100212241002123024020022d00504101470d0020032d0000211c200241d9006a2d0000211b200241da006a2d0000211a200241db006a2d00002119200241dc006a2d00002118200241dd006a2d00002117200241de006a2d00002116200241df006a2d0000211520062d00002114200241e1006a2d00002113200241e2006a2d00002136200241e3006a2d00002139200241e4006a2d00002138200241e5006a2d00002137200241e6006a2d00002135200241e7006a2d0000211120002d00002110200241e9006a2d00002107200241ea006a2d00002104200241eb006a2d00002105200241ec006a2d0000210f200241ed006a2d0000210d200241ee006a2d0000210c200241ef006a2d00002109200241f0006a2d0000210120022d0051212320022d0052212220022d0053212120022d0054212020022d0055211f20022d0056211e20022d0057211d0b200241fc006a200d3a0000200241f8006a20073a0000200241f4006a20373a0000200241f0006a20133a0000200241ec006a20173a00002000201b3a0000200241e4006a201f3a0000200620233a0000200241dc006a200241c0006a41086a28020036020020022002290340370254200220013a007f200220093a007e2002200c3a007d2002200f3a007b200220053a007a200220043a0079200220103a0077200220113a0076200220353a0075200220383a0073200220393a0072200220363a0071200220143a006f200220153a006e200220163a006d200220183a006b200220193a006a2002201a3a00692002201c3a00672002201d3a00662002201e3a0065200220203a0063200220213a0062200220223a006120024100360250200241d0006a10ea02200241e0016a24000f0b0240024020350d002009102121030c010b200320352009102521030b2003450d07200921350b200641206a2106200320106a2209200229038001370000200941186a2038290300370000200941106a200c290300370000200941086a2039290300370000201041206a21100c000b0b41dce1c30041c900104a000b200141011030000b41dce1c30041c900104a000b102f000b203541011030000b200941011030000b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000b102a000be51302157f037e230041f0026b220224002002412036021420022001360210200241186a2001ad4280808080800484100410900102400240200228021822030d00200041003602000c010b200228021c21042002200241206a28020036023c20022003360238200241086a200241386a106e024002400240024002400240024020022802080d00200228023c220541c4006e220641c4006c2201417f4c0d02200228020c21070240024020010d00410421080c010b200110212208450d020b2007450d03200241c8026a41077221094100210a024003400240024002400240024002402005450d0020022005417f6a220b36023c20022002280238220c41016a360238200c2d0000220141014b0d000240024020010e020001000b200b41034d0d0120024184026a41026a20024188026a41026a2d00003a0000200241e8016a41086a200241a8026a41086a290200370300200241e8016a41106a200241a8026a41106a290200370300200241e8016a41186a200241a8026a41186a2d00003a0000200241c8016a41086a200241c8026a41086a290100370300200241c8016a41106a200241c8026a41106a290100370300200241c8016a41186a200241c8026a41186a290100370300200220022f0088023b018402200220022902a8023703e801200220022901c8023703c80120022005417b6a220d36023c2002200c41056a360238200c280001210e200220022f01a4023b01c6014100210f0c030b4100210f200241003a00e8022005417e6a211003400240200b200f2201470d000240200141ff0171450d00200241003a00e8020b4100210d4102210f0c040b200241c8026a20016a200c20016a220f41016a2d00003a00002002200f41026a3602382002200141016a220f3a00e8022002201036023c2010417f6a2110200f4120470d000b200241a4026a41026a221120022d00ca023a000020024188026a41086a2212200941086a29000037030020024188026a41106a2213200941106a29000037030020024188026a41186a2214200941186a2d00003a0000200220022f01c8023b01a40220022009290000370388024100210d200b200f460d0120022800cb0221152002201036023c2002200c200f6a220b41026a3602380240200b41016a2d0000220f41014d0d002010210d4102210f0c030b024002400240200f0e020100010b4100210f200241003a00e802200520016b417c6a2101034002402010200f470d000240200f41ff0171450d00200241003a00e8020b4100210d0c050b200241c8026a200f6a200b200f6a220c41026a2d00003a00002002200c41036a3602382002200f41016a220c3a00e8022002200136023c2001417f6a2101200c210f200c4120470d000b200241a8026a41186a200241c8026a41186a290300370300200241a8026a41106a200241c8026a41106a290300370300200241a8026a41086a200241c8026a41086a290300370300200220022903c8023703a8022010200c6b210d410121160c010b410021162010210d0b200241c8016a41186a200241a8026a41186a290300370300200241c8016a41106a200241a8026a41106a290300370300200241c8016a41086a200241a8026a41086a29030037030020024184026a41026a20112d00003a0000200241e8016a41086a2012290300370300200241e8016a41106a2013290300370300200241e8016a41186a20142d00003a0000200220022903a8023703c801200220022f01a4023b01840220022002290388023703e8014101210f2015210e0c020b200241c2016a41026a20024184026a41026a2d00003a0000200241a8016a41086a200241e8016a41086a290300370300200241a8016a41106a200241e8016a41106a290300370300200241a8016a41186a200241e8016a41186a2d00003a000020024188016a41086a200241c8016a41086a29030037030020024188016a41106a200241c8016a41106a29030037030020024188016a41186a200241c8016a41186a290300370300200220022f0184023b01c201200220022903e8013703a801200220022903c80137038801200220022f01c6013b0186010c020b4102210f0b200241c2016a41026a220120024184026a41026a2d00003a0000200241a8016a41086a220c200241e8016a41086a290300370300200241a8016a41106a220b200241e8016a41106a290300370300200241a8016a41186a2205200241e8016a41186a2d00003a000020024188016a41086a2211200241c8016a41086a29030037030020024188016a41106a2212200241c8016a41106a29030037030020024188016a41186a2213200241c8016a41186a290300370300200220022f0184023b01c201200220022903e8013703a801200220022903c80137038801200220022f01c6013b018601200f4102460d00200a41016a211020024182016a41026a221420012d00003a0000200241e8006a41086a2215200c290300370300200241e8006a41106a220c200b290300370300200241e8006a41186a220b20052d00003a0000200241c8006a41086a22052011290300370300200241c8006a41106a22112012290300370300200241c8006a41186a22122013290300370300200220022f01c2013b018201200220022903a8013703682002200229038801370348200220022f0186013b01462006200a470d020240200a41017422012010200120104b1b2206ad42c4007e2217422088a70d002017a7220141004e0d020b102a000b200241003602282006450d08200810230c080b02400240200a0d002001102121080c010b2008200a41c4006c2001102521080b2008450d020b2008200a41c4006c6a2201200f3a00002001200e360004200141036a20142d00003a0000200120022f0182013b0001200b2d0000210f200c29030021172015290300211820022903682119200120163a002120012019370008200141106a2018370000200141186a2017370000200141206a200f3a00002001413a6a2012290300370000200141326a20112903003700002001412a6a200529030037000020012002290348370022200120022f01463b0042200d21052010210a20102007470d000b200241306a20073602002002200636022c200220083602280c060b200141041030000b200241003602280c030b200141041030000b102f000b200241306a20073602002002200636022c2002200836022820080d010b200241003602b002200242013703a8022002410c3602cc012002200241106a3602c8012002200241a8026a36028801200241dc026a4101360200200242013702cc0220024198c2c3003602c8022002200241c8016a3602d80220024188016a41b8a3c500200241c8026a102e1a20023502b00242208620023502a8028410082000410036020020022802ac02450d0120022802a80210230c010b20002002290328370200200041086a200241286a41086a2802003602000b2004450d00200310230b200241f0026a24000bb00701057f230041106b22032400200341003602082003420137030020022003105c02400240024002400240024002402002450d00200241c4006c210403400240024020012d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a200241017422062005200620054b1b22064100480d0a0240024020020d002006102121050c010b200328020020022006102521050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a0000200141046a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d0a200541017422022007200220074b1b22024100480d0a0240024020050d002002102121050c010b200328020020052002102521050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d09200241017422062005200620054b1b22064100480d090240024020020d002006102121050c010b200328020020022006102521050b2005450d062003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a00002003200336020c200141016a2003410c6a106b0240200141216a2d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a200241017422062005200620054b1b22064100480d0a0240024020020d002006102121050c010b200328020020022006102521050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d09200241017422062005200620054b1b22064100480d090240024020020d002006102121050c010b200328020020022006102521050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a0000200141226a200310710b200141c4006a2101200441bc7f6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b200641011030000b200241011030000b200641011030000b200641011030000b200641011030000b102a000b900f06017f017e057f017e057f017e230041f0016b2201240042002102200141e0006a41186a22034200370300200141e0006a41106a22044200370300200141e0006a41086a2205420037030020014200370360200141d0006a41086a220641a6a3c500ad4280808080a001841003220741086a29000037030020012007290000370350200710232005200629030037030020012001290350370360200641b0a3c500ad4280808080e000841003220741086a2900003703002001200729000037035020071023200420012903502208370300200141206a41086a2005290300370300200141206a41106a2008370300200141206a41186a2006290300370300200120083703402001200129036037032020014180016a200141206a4120108a0120012d0080012107200320014199016a290000370300200420014191016a290000370300200520014189016a29000037030020012001290081013703600240024020074101470d0020002001290360370000200041186a2003290300370000200041106a2004290300370000200041086a20052903003700000c010b20014180016a41186a420037030020014180016a41106a2209420037030020014180016a41086a220742003703002001420037038001200641c4fbc400ad4280808080e000841003220a41086a2900003703002001200a290000370350200a102320072006290300370300200120012903503703800120064197bdc000ad4280808080e000841003220a41086a2900003703002001200a290000370350200a102320092001290350220837030020052007290300370300200420083703002003200629030037030020012008370320200120012903800137036020014180016a200141e0006a108c0102400240200128028001220a0d004104210a410021060c010b2001290284012202422088a721060b02400240200641246c2206450d002006415c6a2105200a210603400240024020062d00004101460d002005450d030c010b200641016a2800002103200641086a28020021072001200641106a280200360264200120073602600240200341c28289aa04460d0020050d010c030b20014180016a200141e0006a109b0320012d00800122054102460d02200141e4016a2802002109200128028401210b20014180016a41186a420037030020014180016a41106a220c420037030020014180016a41086a220342003703002001420037038001200141d0006a41086a220641f7fbc400ad4280808080f000841003220741086a2900003703002001200729000037035020071023200320062903003703002001200129035037038001200641e7acc500ad4280808080a001841003220741086a2900003703002001200729000037035020071023200c20012903502208370300200141e0006a41086a2003290300370300200141e0006a41106a2008370300200141e0006a41186a200629030037030020012008370320200120012903800137036020014180016a200141e0006a412010bb012001280280012206410120061b2107410021030240200b200920054101711b2205200129028401420020061b2208422088a74f0d00200720054105746a2206450d00200141186a200641186a290000370300200141106a200641106a290000370300200141086a200641086a29000037030020012006290000370300410121030b02402008a7450d00200710230b2003450d0220014180016a41186a2207200141186a29030037030020014180016a41106a2209200141106a29030037030020014180016a41086a220b200141086a2903003703002001200129030037038001200141e0006a41186a220c4200370300200141e0006a41106a220d4200370300200141e0006a41086a2205420037030020014200370360200141d0006a41086a220641a6a3c500ad4280808080a001841003220341086a29000037030020012003290000370350200310232005200629030037030020012001290350370360200641b0a3c500ad4280808080e000841003220341086a2900003703002001200329000037035020031023200141c0006a41086a2006290300220837030020012001290350220e3703402004200e370000200441086a2008370000200141206a41086a2005290300370300200141206a41106a200d290300370300200141206a41186a200c29030037030020012001290360370320200141203602642001200141206a36026020014180016a200141e0006a10f501200041186a2007290300370000200041106a2009290300370000200041086a200b29030037000020002001290380013700000c030b200641246a21062005415c6a21050c000b0b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000b02402002422088a72206450d00200641246c2105200a210603400240024020062d0000220341034b0d0002400240024020030e0404000102040b2006410c6a280200450d03200641086a28020010230c030b2006410c6a280200450d02200641086a28020010230c020b2006410c6a280200450d01200641086a28020010230c010b200641086a280200450d00200641046a28020010230b200641246a21062005415c6a22050d000b0b2002a7450d00200a10230b200141f0016a24000b980e09057f017e017f017e037f017e027f027e087f230041f0006b22012400200141306a41186a22024200370300200141306a41106a22034200370300200141306a41086a2204420037030020014200370330200141e0006a41086a220541c6acc500ad4280808080f0008422061003220741086a290000370300200120072900003703602007102320042005290300370300200120012903602208370350200120083703302005418cfbc500ad4280808080e002841003220741086a2900003703002001200729000037036020071023200320012903602208370300200141106a41086a22092004290300370300200141106a41106a220a2008370300200141106a41186a220b20052903003703002001200837035020012001290330370310200141306a200141106a10ae032001290338210c200128023421072001280230210d20024200370300200342003703002004420037030020014200370330200520061003220e41086a2900003703002001200e290000370360200e1023200420052903003703002001200129036037033020054185b2c500ad4280808080e001841003220e41086a2900003703002001200e290000370360200e102320032001290360220837030020092004290300370300200a2008370300200b20052903003703002001200837035020012001290330370310200141306a200141106a412010bb01200d410020071b210b200c420020071b210f20012902344200200128023022051b21102007410420071b21112005410120051b210d2000280200211220002802042113024002400240024020002802082205450d002012200541246c6a21142010422088a741057421152012210903402009280220210a200941086a2900002108200941106a29000021062009290000210c2002200941186a29000037030020032006370300200420083703002001200c370330200941246a21094100210020152107200d21050240024003402007450d02200141306a2005460d01200041016a2100200741606a21072005200141306a412010de04210e200541206a2105200e0d000b200e4541016a41017120006a417f6a21000b200b200a6a2207200b490d000240200041016a220e200f422088a722054d0d000240200fa7220b20056b200e2005200e20054b1b221620056b220e4f0d002005200e6a22172005490d06200b41017422182017201820174b1b221741ffffffff03712017470d06201741027422184100480d0602400240200b0d002018102121110c010b2011200b4102742018102521110b2011450d052017ad210f0b201120054102746a210b02400240200e4102490d00200b410020162005417f736a220e41027410db041a2011200520166a20056b4102746a417c6a210b200e20056a21050c010b200e450d010b200b4100360200200541016a21050b200520004d0d05201120004102746a22002000280200200a6a360200200f42ffffffff0f832005ad42208684210f2007210b0b20092014470d000b0b02402013450d00201210230b02402010a7450d00200d10230b200120113602042001200b3602002001200f3703080240024020110d00200141306a41186a220e4200370300200141306a41106a22094200370300200141306a41086a2207420037030020014200370330200141e0006a41086a220541c6acc500ad4280808080f000841003220041086a290000370300200120002900003703602000102320072005290300370300200120012903602208370350200120083703302005418cfbc500ad4280808080e002841003220041086a2900003703002001200029000037036020001023200141d0006a41086a2005290300220837030020012001290360220637035020032006370000200341086a2008370000200141106a41086a2007290300370300200141106a41106a2009290300370300200141106a41186a200e29030037030020012001290330370310200141106aad428080808080048410050c010b200141306a41186a220e4200370300200141306a41106a22094200370300200141306a41086a2207420037030020014200370330200141e0006a41086a220541c6acc500ad4280808080f000841003220041086a290000370300200120002900003703602000102320072005290300370300200120012903602208370350200120083703302005418cfbc500ad4280808080e002841003220041086a2900003703002001200029000037036020001023200141d0006a41086a2005290300220837030020012001290360220637035020032006370000200341086a2008370000200141106a41086a2007290300370300200141106a41106a2009290300370300200141106a41186a200e29030037030020012001290330370310200141203602342001200141106a3602302001200141306a10a9042011450d00200fa7450d00201110230b200141f0006a24000f0b201841041030000b102a000b4180b9c00020002005102d000bcb0603067f017e077f230041106b2203240002400240024002400240200241046a2204417f4c0d0002400240024020040d00410121050c010b200410212205450d010b20034100360208200320043602042003200536020020022003105c02400240024020032802042206200328020822046b2002490d00200328020021070c010b200420026a22052004490d07200641017422082005200820054b1b22054100480d070240024020060d002005102121070c010b200328020020062005102521070b2007450d012003200536020420032007360200200521060b200720046a2001200210dc041a200420026a2201ad4220862007ad84100c220229000021092002102320032009370300200720016a210a200141086a220b20014f0d03200341086a210c20032108410021024100210b410121042007210d41002105034020024101742101200c200841016a220e6b210f034020082d0000210802400240024002402002200b470d00200f210b024002400240200541ff01710e03010200010b200a200d6b210b0c010b417f200f200a200d6b6a220b200b200f491b210b0b2002417f200b41016a22102010200b491b6a220b2002490d0c2001200b2001200b4b1b220b4100480d0c0240024020020d00200b102121040c010b20042002200b102521040b2004450d010b200420026a20083a00000240024002400240200541ff01710e03010300010b200a200d460d010c050b0240200e200c460d00410021050c040b200a200d470d040b200241016a21020c0a0b41012105200e200c470d01200241016a21020c090b200b41011030000b200241016a2102200e21080c020b200241016a210241022105200141026a2101200d220841016a210d0c000b0b0b200541011030000b200441011030000b102f000b410121040240200b450d00200b4100480d03200b10212204450d020b410021020340200420026a200320026a2d00003a0000200241016a22024108470d000b024020010d00410821020c010b200420026a2105410021020340200520026a200720026a2d00003a00002001200241016a2202470d000b200a20076b41086a21020b200020023602082000200b3602042000200436020002402006450d00200710230b200341106a24000f0b200b41011030000b102a000bf40601067f230041f0006b21020240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a2206360204410121072001200441016a360200200541f001490d0a200541847e6a220541034b0d0420050e0401020803010b200041023a00000f0b20064102490d0320042f0001210520012003417d6a3602042001200441036a360200200541ef014b0d04200041023a00000f0b20064104490d042004280001210520012003417b6a3602042001200441056a36020041012107200541ffff034b0d07200041023a00000f0b41002105200241003a00682003417f6a21062003417e6a210302400340024020062005470d000240200541ff0171450d00200241003a00680b410121010c020b200241c8006a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00682003417f6a21032007210520074120470d000b200241c6006a20022d004a3a0000200241306a200241d7006a290000370300200241386a200241df006a290000370300200241c0006a200241e7006a2d00003a0000200220022f01483b01442002200229004f370328200228004b2105410021010b200241246a41026a2203200241c4006a41026a2d00003a0000200241086a41086a2207200241286a41086a290300370300200241086a41106a2204200241286a41106a290300370300200241086a41186a2206200241286a41186a2d00003a0000200220022f01443b0124200220022903283703082001450d05200041023a00000f0b200041023a00000f0b200041023a00000f0b410121070c030b200041023a00000f0b0240200641044f0d00200041023a00000f0b200041023a000020012003417b6a3602042001200441056a3602000f0b200241286a41026a20032d00003a0000200241c8006a41086a2007290300370300200241c8006a41106a2004290300370300200241c8006a41186a20062d00003a0000200220022f01243b012820022002290308370348410021070b200020073a0000200020022f01283b0001200041046a2005360200200041086a2002290348370200200041036a2002412a6a2d00003a0000200041106a200241c8006a41086a290300370200200041186a200241c8006a41106a290300370200200041206a200241c8006a41186a2802003602000bb20801037f0240024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d08200241017422042003200420034b1b22044100480d080240024020020d002004102121030c010b200128020020022004102521030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41ff013a0000200041016a200110710f0b0240024002400240200041046a280200220241ffff034b0d00200241ef014b0d03200141046a280200200141086a2802002200460d01200128020021030c020b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0a200041017422042003200420034b1b22044100480d0a0240024020000d002004102121030c010b200128020020002004102521030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fd013a000002400240200141046a2802002203200428020022006b4104490d00200128020021030c010b200041046a22042000490d0a200341017422002004200020044b1b22004100480d0a0240024020030d002000102121030c010b200128020020032000102521030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20023600000f0b200041016a22032000490d08200041017422042003200420034b1b22044100480d080240024020000d002004102121030c010b200128020020002004102521030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20023a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d07200041017422042003200420034b1b22044100480d070240024020000d002004102121030c010b200128020020002004102521030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fc013a000002400240200141046a2802002203200428020022006b4102490d00200128020021030c010b200041026a22042000490d07200341017422002004200020044b1b22004100480d070240024020030d002000102121030c010b200128020020032000102521030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20023b00000f0b200441011030000b200441011030000b200041011030000b200441011030000b200441011030000b200041011030000b102a000b9a0808017f027e037f017e017f027e047f037e23004190016b22032400200341206a200020012002109702200341206a41086a290300210420032903202105200341d0006a41186a22064200370300200341d0006a41106a22074200370300200341d0006a41086a220842003703002003420037035020034180016a41086a220041d5fbc400ad428080808080018422091003220a41086a2900003703002003200a29000037038001200a1023200820002903003703002003200329038001220b3703702003200b370350200041d6a0c200ad4280808080d00184220c1003220a41086a2900003703002003200a29000037038001200a10232007200329038001220b370300200341306a41086a220a2008290300370300200341306a41106a220d200b370300200341306a41186a220e20002903003703002003200b37037020032003290350370330200341086a200341306a4120108902200120057d200520017d200520015820042002582004200251220f1b22101b2111200220047d2001200554ad7d200420027d2005200154ad7d20101b2112200341086a41106a2903004200200328020822101b210b2003290310420020101b21130240024020052001562004200256200f1b0d0020064200370300200742003703002008420037030020034200370350200020091003220f41086a2900003703002003200f29000037038001200f10232008200029030037030020032003290380012201370370200320013703502000200c1003220f41086a2900003703002003200f29000037038001200f1023200341f0006a41086a200029030022013703002003200329038001220237037020072002370000200741086a2001370000200a2008290300370300200d2007290300370300200e20062903003703002003200329035037033020034200200b20127d2013201154ad7d2201201320117d22022013562001200b562001200b511b22001b37035820034200200220001b370350200341d0006a21000c010b20064200370300200742003703002008420037030020034200370350200020091003220f41086a2900003703002003200f29000037038001200f10232008200029030037030020032003290380012201370370200320013703502000200c1003220f41086a2900003703002003200f29000037038001200f1023200341f0006a41086a200029030022013703002003200329038001220237037020072002370000200741086a2001370000200a2008290300370300200d2007290300370300200e2006290300370300200320032903503703302003427f200b20127c201320117c22022013542200ad7c220120002001200b542001200b511b22001b3703582003427f200220001b370350200341d0006a21000b200341306aad42808080808004842000ad4280808080800284100220034190016a24000bf70e05057f017e027f027e037f230041e0016b22012400200141e0006a41186a4200370300200141e0006a41106a22024200370300200141e0006a41086a2203420037030020014200370360200141d0016a41086a220441cefbc400ad4280808080f000841003220541086a290000370300200120052900003703d0012005102320032004290300370300200120012903d001220637035020012006370360200441aae1c300ad4280808080b001841003220541086a290000370300200120052900003703d00120051023200220012903d0012206370300200141306a41086a2003290300370300200141306a41106a2006370300200141306a41186a20042903003703002001200637035020012001290360370330200141186a200141306a4120108f0120012802182107200128021c210820002d00002103024002400240024002400240024002400240410110212204450d00200420033a000020002d0001210320044101410210252204450d01200420033a000120002d0002210320044102410410252204450d02200420033a0002200420002d00033a000320002d0004210320044104410810252204450d03200420033a0004200420002d00053a0005200420002d00063a0006200420002d00073a000720002d0008210320044108411010252204450d04200420033a0008200420002d00093a0009200420002d000a3a000a200420002d000b3a000b200420002d000c3a000c200420002d000d3a000d200420002d000e3a000e200420002d000f3a000f20002d0010210320044110412010252204450d05200420033a0010200420002d00113a0011200420002d00123a0012200420002d00133a0013200420002d00143a0014200420002d00153a0015200420002d00163a0016200420002d00173a0017200420002d00183a0018200420002d00193a0019200420002d001a3a001a200420002d001b3a001b200420002d001c3a001c200420002d001d3a001d200420002d001e3a001e200420002d001f3a001f20042d0000210320042d0001210520041023200141306a2003200541087472410676220510bc0202402003413f71220420012802384f0d00200141086a200128023020044105746a220410e3012001290308200141086a41086a290300844200520d00200041086a2900002106200041106a2900002109200041186a290000210a20042000290000370000200441186a200a370000200441106a2009370000200441086a2006370000200141e0006a41086a200141306a41086a280200360200200120012903303703602005200141e0006a10a4030c090b2008410020071b210402402001280234450d00200128023010230b200141e0006a200410bc020240200128026841c000490d000340200441016a210402402001280264450d00200128026010230b200141e0006a200410bc022001280268413f4b0d000b0b200141206a41086a200141e0006a41086a2207280200220336020020012001290360370320200141e0006a41186a2208200041186a290000370300200141e0006a41106a220b200041106a2900003703002007200041086a29000037030020012000290000370360024020032001280224470d00200341016a22052003490d082003410174220c2005200c20054b1b220541ffffff3f712005470d082005410574220d4100480d080240024020030d00200d1021210c0c010b20012802202003410574200d1025210c0b200c450d07200120053602242001200c3602200b200320044106746a210c200128022020034105746a22052001290360370000200541086a2007290300370000200541106a200b290300370000200541186a20082903003700002001200341016a22033602280240200341c000470d00200141e0006a41186a22084200370300200141e0006a41106a220b4200370300200141e0006a41086a2205420037030020014200370360200141d0016a41086a220341cefbc400ad4280808080f000841003220741086a290000370300200120072900003703d0012007102320052003290300370300200120012903d001220637035020012006370360200341aae1c300ad4280808080b001841003220741086a290000370300200120072900003703d00120071023200141d0006a41086a20032903002206370300200120012903d001220937035020022009370000200241086a2006370000200141306a41086a2005290300370300200141306a41106a200b290300370300200141306a41186a2008290300370300200120012903603703302001200441016a360260200141306aad4280808080800484200141e0006aad4280808080c0008410020b200141e0006a41086a2203200141206a41086a280200360200200120012903203703602004200141e0006a10a40320032000290000370300200141e0006a41106a200041086a290000370300200141e0006a41186a200041106a29000037030020014180016a200041186a2900003703002001200c360264200141013a0060200141e0006a108e010c080b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000b200d41011030000b102a000b200141e0016a24000bf40b02057f017e230041c0016b22032400200341d0006a41086a220441d5fbc400ad42808080808001841003220541086a2900003703002003200529000037035020051023200341306a41086a2206200429030037030020032003290350370330200441e3a0c200ad4280808080b001841003220541086a2900003703002003200529000037035020051023200341c0006a41086a2207200429030037030020032003290350370340200341d0006a200010ac01024002400240024041c00010212205450d00200520032903303700002005200329034037001020052003290050370020200541086a2006290300370000200541186a2007290300370000200541286a2004290000370000200541306a200341e0006a290000370000200541386a200341d0006a41186a29000037000020032001370350200320023703582005ad4280808080800884200341d0006aad42808080808002841002200510230240200142ffc7afa0255620024200522002501b0d00200341d0006a41086a220441d5fbc400ad42808080808001841003220541086a2900003703002003200529000037035020051023200341306a41086a2206200429030037030020032003290350370330200441e3a0c200ad4280808080b001841003220541086a2900003703002003200529000037035020051023200341c0006a41086a2207200429030037030020032003290350370340200341d0006a200010ac0141c00010212205450d02200520032903303700002005200329034037001020052003290050370020200541086a2006290300370000200541186a2007290300370000200541286a2004290000370000200541306a200341d0006a41106a290000370000200541386a200341d0006a41186a290000370000200341186a200541c000108902200341186a41106a2903002102200329032021010240200329031822084201520d002005ad428080808080088410050b20051023200341d0006a41086a220441d5fbc400ad42808080808001841003220541086a2900003703002003200529000037035020051023200341306a41086a2206200429030037030020032003290350370330200441fda0c200ad4280808080d000841003220541086a2900003703002003200529000037035020051023200341c0006a41086a2207200429030037030020032003290350370340200341d0006a200010ac0141c00010212205450d03200520032903303700002005200329034037001020052003290050370020200541086a2006290300370000200541186a2007290300370000200541286a2004290000370000200541306a200341e0006a290000370000200541386a200341d0006a41186a2900003700002005ad428080808080088410052005102302402001200284500d002008a7450d002001200210cb020b200010dd02200341d0006a41086a220441d5fbc400ad42808080808001841003220541086a2900003703002003200529000037035020051023200341306a41086a2206200429030037030020032003290350370330200441eea0c200ad4280808080f001841003220541086a2900003703002003200529000037035020051023200341c0006a41086a2207200429030037030020032003290350370340200341d0006a200010ac0141c00010212205450d04200520032903303700002005200329034037001020052003290050370020200541086a2006290300370000200541186a2007290300370000200541286a2004290000370000200541306a200341d0006a41106a290000370000200541386a200341d0006a41186a2900003700002003200541c000108902200341106a290300210220032802002104200329030821012005102302402001200284500d0020040d010b200010ab01200341d0006a41086a41013a0000200341d9006a2000290000370000200341e1006a200041086a290000370000200341e9006a200041106a290000370000200341f1006a200041186a290000370000200341023a0050200341d0006a108e010b200341c0016a24000f0b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000b9b0e03057f017e077f23004190016b22012400200141e8006a41086a220241c6acc500ad4280808080f000841003220341086a2900003703002001200329000037036820031023200141c8006a41086a2204200229030037030020012001290368370348200241f1acc500ad4280808080e000841003220341086a2900003703002001200329000037036820031023200141d8006a41086a2205200229030037030020012001290368370358200141e8006a200010ac0102400240024002400240024002400240024041c00010212203450d00200320012903483700002003200129035837001020032001290068370020200341086a2004290300370000200341186a2005290300370000200341286a2002290000370000200341306a200141e8006a41106a290000370000200341386a200141e8006a41186a290000370000200141e8006a200341c000108a010240024020012d00684101470d002003ad42808080808008841005200141086a41186a220220014181016a290000370300200141086a41106a2204200141f9006a290000370300200141086a41086a2205200141f1006a2900003703002001200129006937030820031023200141286a41186a2002290300370300200141286a41106a2004290300370300200141286a41086a200529030037030020012001290308370328200141e8006a41086a220241c6acc500ad4280808080f000841003220341086a2900003703002001200329000037036820031023200141c8006a41086a2204200229030037030020012001290368370348200241f7acc500ad4280808080e000841003220341086a2900003703002001200329000037036820031023200141d8006a41086a2205200229030037030020012001290368370358200141e8006a200141286a10ac0141c00010212203450d03200320012903483700002003200129035837001020032001290068370020200341086a2004290300370000200341186a2005290300370000200341286a2002290000370000200341306a200141f8006a290000370000200341386a200141e8006a41186a2900003700002003ad42808080808008841005200310230c010b200310230b200141e8006a41086a220241c6acc500ad4280808080f0008422061003220341086a2900003703002001200329000037036820031023200141c8006a41086a2204200229030037030020012001290368370348200241acb2c500ad4280808080d000841003220341086a2900003703002001200329000037036820031023200141d8006a41086a2205200229030037030020012001290368370358200141e8006a200010ac0141c00010212203450d02200320012903483700002003200129035837001020032001290068370020200341086a2004290300370000200341186a2005290300370000200341286a2002290000370000200341306a200141f8006a2204290000370000200341386a200141e8006a41186a22052900003700002003ad4280808080800884100520031023200010ac04200010ae04200220061003220341086a2900003703002001200329000037036820031023200141086a41086a200229030037030020012001290368370308200241b9adc500ad4280808080d001841003220341086a2900003703002001200329000037036820031023200141286a41086a200229030037030020012001290368370328200141e8006a200010ac0141c00010212203450d03200320012903083700002003200129032837001020032001290068370020200341086a200141086a41086a290300370000200341186a200141286a41086a290300370000200341286a200141e8006a41086a2207290000370000200341306a2004290000370000200341386a2005290000370000200141e8006a200341c00010ab030240200128027022080d00200310230c090b2003ad4280808080800884100520012802682109200129027421062003102320082006422088a74102746a210a2006a7210b2009210c2008210441002105410041ff01710e03040506040b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000b410121030c020b410221030c010b410021030b0340024002400240024002400240024020030e03000102020b2004200a460d03200441046a210441022103200c417f6a2202210c0c020b41002103024020054102460d0041022105200921020c020b2004200a460d02200441046a210441022105200c417f6a2202210c410221030c010b2005410247210d410121034102210520092102200d450d010b200141e8006a41186a200041186a290000370300200141e8006a41106a200041106a2900003703002007200041086a290000370300200120023602880120012000290000370368200141e8006a10b4040240200341ff01710e03000203000b410121030c030b200b450d03200810230c030b410221030c010b410021030c000b0b20014190016a24000be40f08047f017e017f047e037f027e017f017e230041d0016b220524000240024002400240024002402002410671450d00200541b8016a41086a220641d5fbc400ad42808080808001841003220741086a290000370300200520072900003703b80120071023200541a8016a41086a22082006290300370300200520052903b8013703a801200641cdadc200ad4280808080f000841003220741086a290000370300200520072900003703b80120071023200541e8006a41086a22072006290300370300200520052903b80137036820054188016a200110ac0141c00010212206450d01200620052903a801370000200620052903683700102006200529008801370020200641086a2008290300370000200641186a2007290300370000200641286a20054188016a41086a290000370000200641306a20054188016a41106a290000370000200641386a20054188016a41186a290000370000200541c00036025c20052006360258200541b8016a2006ad428080808080088410041090010240024020052802b80122070d00420021090c010b20052802bc01210802400240200541b8016a41086a280200220a4110490d00200a4170714110460d00200a417c714120460d00200741086a290000210b2007290000210c200741186a290000210d2007290010210e2007280020210a420121090c010b20054100360270200542013703682005410c3602ac012005200541d8006a3602a8012005200541e8006a3602cc012005419c016a41013602002005420137028c0120054198c2c300360288012005200541a8016a36029801200541cc016a41b8a3c50020054188016a102e1a200535027042208620053502688410080240200528026c450d00200528026810230b420021090b2008450d00200710230b200610232009500d00200541b8016a41086a220741d5fbc400ad42808080808001841003220641086a290000370300200520062900003703b80120061023200541a8016a41086a22082007290300370300200520052903b8013703a801200741e3a0c200ad4280808080b001841003220641086a290000370300200520062900003703b80120061023200541e8006a41086a220f2007290300370300200520052903b80137036820054188016a200110ac0141c00010212206450d02200620052903a801370000200620052903683700102006200529008801370020200641086a2008290300370000200641186a200f290300370000200641286a20054188016a41086a2208290000370000200641306a20054188016a41106a2210290000370000200641386a20054188016a41186a2211290000370000200541c0006a200641c000108902200541c0006a41106a2903002112200529034821132005280240211420061023420021152011420037030020104200370300200842003703002005420037038801200741c4fbc400ad4280808080e000841003220641086a290000370300200520062900003703b8012006102320082007290300370300200520052903b80137038801200741f9bcc000ad4280808080e000841003220641086a290000370300200520062900003703b80120061023201020052903b8012209370300200f2008290300370300200541e8006a41106a2009370300200541e8006a41186a2007290300370300200520093703a8012005200529038801370368200541386a200541e8006a4120108f01200541186a200d42004100200528023c410020052802381b2206200a6b2207200720064b1bad2209420010e104200541286a20094200200e420010e104200541086a42004200200e420010e1042012420020141b210e2013420020141b210d4200210902402005290310200529032084420052200541286a41086a2903002213200529030820052903187c7c2212201354720d00200b2012200c2005290328221556200b201256200b2012511b22061b20127d200c201520061b220b201554ad7d2109200b20157d21150b2015200d200d201556200e200956200e2009511b22061b2003562009200e20061b220920045620092004511b450d004185aec2002106412621010c050b200541d8006a200110df02200528026022080d0241002106200528025c450d03200528025810230c030b41c00041011030000b41c00041011030000b20054188016a41186a420037030020054188016a41106a220a420037030020054188016a41086a220142003703002005420037038801200541b8016a41086a220641c4fbc400ad4280808080e000841003220741086a290000370300200520072900003703b8012007102320012006290300370300200520052903b80137038801200641f9bcc000ad4280808080e000841003220741086a290000370300200520072900003703b80120071023200a20052903b8012209370300200541e8006a41086a2001290300370300200541e8006a41106a2009370300200541e8006a41186a2006290300370300200520093703a80120052005290388013703682005200541e8006a4120108f012005280204410020052802001b210720084105742101200528025c21082005280258220a21060240034002402007200641106a2802004f0d002006290300200358200641086a290300220920045820092004511b0d002006411c6a2d000020027141ff01710d020b200641206a2106200141606a22010d000b410021062008450d01200a10230c010b41d4adc20021062008450d00200a10230b413121010b2000200136020420002006360200200541d0016a24000bc509030c7f037e037f230041f0006b22022400200241286a41086a220341d5fbc400ad42808080808001841003220441086a2900003703002002200429000037032820041023200241086a41086a2205200329030037030020022002290328370308200341fda0c200ad4280808080d000841003220441086a2900003703002002200429000037032820041023200241186a41086a2206200329030037030020022002290328370318200241286a200110ac010240024002400240024041c00010212204450d00200420022903083700002004200229031837001020042002290028370020200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241386a290000370000200441386a200241286a41186a290000370000200241c00036024c20022004360248200241086a2004ad428080808080088410041090010240024020022802082207450d00200228020c21082002200241106a280200360254200220073602502002200241d0006a106e02400240024020022802000d00200228025422034160712205417f4c0d0620022802042109024002402003410576220a0d00410821010c010b200510212201450d080b02402009450d00411d210b4100210c4100210d0340200241186a200241d0006a10be020240024020022d00184101460d00200228025422054110490d002002290019210e20022002280250220341106a3602502002200541706a220636025420064104490d00200341086a290000210f2003290000211020022005416c6a22063602542002200341146a36025020060d010b20024100360228200a450d04200110230c040b200d41016a210620032800102111200241ec006a41026a200241d8006a41026a2d000022123a0000200241e8006a41026a221320123a000020022005416b6a3602542002200341156a360250200220022f005822053b016c200220053b016820032d001421050240200d200a470d00200c2006200c20064b1b220a41ffffff3f71200a470d0c200a41057422034100480d0c02400240200d0d002003102121010c010b2001200b41636a2003102521010b2001450d0b0b2001200b6a2203417f6a20053a0000200341636a2205200f37030820052010370300200341776a200e370200200341736a2011360200200320022f01683b0000200341026a20132d00003a0000200c41026a210c200b41206a210b2006210d20092006470d000b200241306a20093602002002200a36022c20022001360228200229022c210e0c030b200241306a20093602002002200a36022c200220013602282001450d01200229022c210e0c020b200241003602280b4100210120024100360220200242013703182002410c36025c2002200241c8006a3602582002200241186a3602642002413c6a41013602002002420137022c20024198c2c3003602282002200241d8006a360238200241e4006a41b8a3c500200241286a102e1a200235022042208620023502188410080240200228021c450d00200228021810230b0b02402008450d00200710230b2001450d002000200e370204200020013602000c010b20004100360208200042083702000b20041023200241f0006a24000f0b41c00041011030000b102f000b200541081030000b200341081030000b102a000bf61003097f027e037f230041c0006b22022400200241206a41086a220341d5fbc400ad42808080808001841003220441086a2900003703002002200429000037032020041023200241086a2205200329030037030020022002290320370300200341fda0c200ad4280808080d000841003220441086a2900003703002002200429000037032020041023200241106a41086a2204200329030037030020022002290320370310200241206a200010ac01024002400240024002400240024002400240024002400240024041c00010212206450d00200620022903003700002006200229031037001020062002290020370020200641086a2005290300370000200641186a2004290300370000200641286a2003290000370000200641306a200241206a41106a290000370000200641386a200241206a41186a290000370000200128020021072001280208210320024100360228200242013703202003200241206a105c02402003450d0020034105742108410021090340200720096a220341146a2d0000210502400240200228022420022802282204460d00200228022021000c010b200441016a22002004490d0f2004410174220a2000200a20004b1b220a4100480d0f0240024020040d00200a102121000c010b20022802202004200a102521000b2000450d042002200a360224200220003602200b2002200441016a360228200020046a20053a0000200341156a2d0000210502400240200228022420022802282204460d00200228022021000c010b200441016a22002004490d0f2004410174220a2000200a20004b1b220a4100480d0f0240024020040d00200a102121000c010b20022802202004200a102521000b2000450d052002200a360224200220003602200b2002200441016a360228200020046a20053a0000200341166a2d0000210502400240200228022420022802282204460d00200228022021000c010b200441016a22002004490d0f2004410174220a2000200a20004b1b220a4100480d0f0240024020040d00200a102121000c010b20022802202004200a102521000b2000450d062002200a360224200220003602200b2002200441016a360228200020046a20053a0000200341176a2d0000210502400240200228022420022802282204460d00200228022021000c010b200441016a22002004490d0f2004410174220a2000200a20004b1b220a4100480d0f0240024020040d00200a102121000c010b20022802202004200a102521000b2000450d072002200a360224200220003602200b2002200441016a360228200020046a20053a0000200341186a2d0000210502400240200228022420022802282204460d00200228022021000c010b200441016a22002004490d0f2004410174220a2000200a20004b1b220a4100480d0f0240024020040d00200a102121000c010b20022802202004200a102521000b2000450d082002200a360224200220003602200b2002200441016a360228200020046a20053a0000200341196a2d0000210502400240200228022420022802282204460d00200228022021000c010b200441016a22002004490d0f2004410174220a2000200a20004b1b220a4100480d0f0240024020040d00200a102121000c010b20022802202004200a102521000b2000450d092002200a360224200220003602200b2002200441016a360228200020046a20053a00002003411a6a2d0000210502400240200228022420022802282204460d00200228022021000c010b200441016a22002004490d0f2004410174220a2000200a20004b1b220a4100480d0f0240024020040d00200a102121000c010b20022802202004200a102521000b2000450d0a2002200a360224200220003602200b2002200441016a360228200020046a20053a00002003411b6a2d0000210502400240200228022420022802282204460d00200228022021000c010b200441016a22002004490d0f2004410174220a2000200a20004b1b220a4100480d0f0240024020040d00200a102121000c010b20022802202004200a102521000b2000450d0b2002200a360224200220003602200b2002200441016a360228200020046a20053a0000200341086a290300210b2003290300210c0240024020022802242200200228022822056b4110490d00200228022021040c010b200541106a22042005490d0f2000410174220a2004200a20044b1b220a4100480d0f0240024020000d00200a102121040c010b20022802202000200a102521040b2004450d0c2002200a36022420022004360220200a21000b200420056a220a200b370008200a200c3700002002200541106a220a360228200341106a280200210d02402000200a6b41034b0d00200a41046a220e200a490d0f2000410174220f200e200f200e4b1b220e4100480d0f0240024020000d00200e102121040c010b20042000200e102521040b2004450d0d2002200e360224200220043602200b2002200541146a3602282004200a6a200d3600002003411c6a2d0000210002400240200228022420022802282203460d00200228022021040c010b200341016a22042003490d0f200341017422052004200520044b1b22054100480d0f0240024020030d002005102121040c010b200228022020032005102521040b2004450d0e20022005360224200220043602200b2002200341016a360228200420036a20003a00002008200941206a2209470d000b0b200228022421032006ad4280808080800884200235022842208620022802202204ad84100202402003450d00200410230b200610230240200141046a280200450d00200710230b200241c0006a24000f0b41c00041011030000b200a41011030000b200a41011030000b200a41011030000b200a41011030000b200a41011030000b200a41011030000b200a41011030000b200a41011030000b200a41011030000b200e41011030000b200541011030000b102a000bec05030c7f017e017f23004180066b22022400200241b8036a20011088010240024020022802bc0322030d00200041003602040c010b200241c4036a280200210420022802c003210520022802b8032106200241106a200241c8036a41e00010dc041a200241086a2001106e024020022802080d000240024002400240200128020441c8026e220741c8026c2208417f4c0d00200228020c21090240024020080d004108210a0c010b20081021220a450d020b024002402009450d004100210b410021084100210c0340200241b8036a200110e20220022903a0044203510d02200c41016a210d200241f0006a200241b8036a41c80210dc041a0240200c2007470d00200b200d200b200d4b1b2207ad42c8027e220e422088a70d07200ea7220f4100480d0702400240200c0d00200f1021210a0c010b200a2008200f1025210a0b200a450d060b200a20086a200241f0006a41c80210dc041a200b41026a210b200841c8026a2108200d210c2009200d470d000b0b200a450d05200241b8036a200241106a41e00010dc041a2000410c6a2004360200200020053602082000200336020420002006360200200041106a200241b8036a41e00010dc041a200041f8006a2009360200200041f4006a2007360200200041f0006a200a3602000c060b0240200c450d00200a4198016a210d0340200d10db01200d41c8026a210d200841b87d6a22080d000b0b2007450d04200a10230c040b102f000b200841081030000b200f41081030000b102a000b2000410036020402402004450d00200441246c210d2003210803400240024020082d0000220c41034b0d00024002400240200c0e0404000102040b2008410c6a280200450d03200841086a28020010230c030b2008410c6a280200450d02200841086a28020010230c020b2008410c6a280200450d01200841086a28020010230c010b200841086a280200450d00200841046a28020010230b200841246a2108200d415c6a220d0d000b0b2005450d00200310230b20024180066a24000be31104047f017e037f047e230041d0056b22022400200241206a2001106e02400240024002400240024020022802200d00024020022802242203450d0003402003417f6a22030d000b0b20012802042203450d01200128020022042d0000210520012003417f6a3602042001200441016a36020002400240200541ff00714104470d0020054118744118754100480d01420221060c060b200042033703680c060b200241e0036a200110d80220022d00e0034102460d02200241b8036a41206a200241e0036a41206a280200360200200241b8036a41186a200241e0036a41186a290300370300200241b8036a41106a200241e0036a41106a290300370300200241b8036a41086a200241e0036a41086a290300370300200220022903e0033703b80320012802042205450d02200128020022042d0000210320012005417f6a3602042001200441016a360200200341024b0d02024002400240024020030e03000102000b41002103200241003a00c0022005417f6a2107417e21080340024020072003470d00200341ff0171450d07200241003a00c0020c070b20024180026a20036a200420036a220941016a2d00003a00002001200520086a3602042001200941026a3602002002200341016a22093a00c0022008417f6a210820092103200941c000470d000b20024190056a41386a20024180026a41386a290300220637030020024190056a41306a20024180026a41306a290300220a37030020024190056a41286a20024180026a41286a290300220b37030020024190056a41206a20024180026a41206a290300220c37030020024190056a41186a20024180026a41186a290300220d370300200241c8046a41086a20024180026a41086a290300370300200241c8046a41106a20024180026a41106a290300370300200241c8046a41186a200d370300200241c8046a41206a200c370300200241c8046a41286a200b370300200241c8046a41306a200a370300200241c8046a41386a200637030020022002290380023703c8042009417f7320056a2105200420096a41016a2104410021030c020b41002103200241003a00c0022005417f6a2107417e21080340024020072003470d00200341ff0171450d06200241003a00c002420221060c070b20024180026a20036a200420036a220941016a2d00003a00002001200520086a3602042001200941026a3602002002200341016a22093a00c0022008417f6a210820092103200941c000470d000b20024190056a41386a20024180026a41386a290300220637030020024190056a41306a20024180026a41306a290300220a37030020024190056a41286a20024180026a41286a290300220b37030020024190056a41206a20024180026a41206a290300220c37030020024190056a41186a20024180026a41186a290300220d370300200241c8046a41086a20024180026a41086a290300370300200241c8046a41106a20024180026a41106a290300370300200241c8046a41186a200d370300200241c8046a41206a200c370300200241c8046a41286a200b370300200241c8046a41306a200a370300200241c8046a41386a200637030020022002290380023703c8042009417f7320056a210541012103200420096a41016a21040c010b41002103200241003a00c1022005417f6a2107417e21080340024020072003470d00200341ff0171450d05200241003a00c102420221060c060b20024180026a20036a200420036a220941016a2d00003a00002001200520086a3602042001200941026a3602002002200341016a22093a00c1022008417f6a210820092103200941c100470d000b200241c8046a20024180026a41c10010dc041a2009417f7320056a2105200420096a41016a2104410221030b20024187046a200241c8046a41c10010dc041a2005450d022004310000210b20012005417f6a22083602042001200441016a36020002400240200b50450d00420021060c010b2008450d032004310001210c20012005417e6a3602042001200441026a3602004202200b420f8386220a4204540d0342012106200c420886200b84420488200a420c88220b4201200b4201561b7e220b200a5a0d030b200241186a2001106e20022802180d02200228021c21052002200110eb022002290300a70d02200241106a290300210d2002290308210c20024190056a41206a200241b8036a41206a28020036020020024190056a41186a200241b8036a41186a29030037030020024190056a41106a200241b8036a41106a29030037030020024190056a41086a200241b8036a41086a290300370300200220022903b8033703900520024180026a20024187046a41c10010dc041a200220022f01b6033b01fe010c030b200042033703680c040b200042033703680c030b420221060b200241d8016a41086a220420024190056a41086a290300370300200241d8016a41106a220820024190056a41106a290300370300200241d8016a41186a220920024190056a41186a290300370300200241d8016a41206a220720024190056a41206a28020036020020022002290390053703d80120024197016a20024180026a41c10010dc041a200220022f01fe013b019401024020064202520d00200042033703680c020b200241f0006a41206a2007280200360200200241f0006a41186a2009290300370300200241f0006a41106a2008290300370300200241f0006a41086a2004290300370300200220022903d8013703702002412f6a20024197016a41c10010dc041a200220022f0194013b012c0b20024180026a200110d9010240200228028002411a460d0020002002290370370300200020033a0024200041206a200241f0006a41206a280200360200200041186a200241f0006a41186a290300370300200041106a200241f0006a41106a290300370300200041086a200241f0006a41086a290300370300200041256a2002412f6a41c10010dc041a200020022f012c3b016620004188016a200d37030020004180016a200c37030020004190016a2005360200200041f8006a200b3703002000200a3703702000200637036820004198016a20024180026a41b00110dc041a0c010b200042033703680b200241d0056a24000bfb0302037f037e230041f0006b22042400200441206a200110e3010240024002402004290320200441206a41086a29030084500d00200441d0006a41086a220541d5fbc400ad42808080808001841003220641086a2900003703002004200629000037035020061023200441306a41086a200529030037030020042004290350370330200541e3a0c200ad4280808080b001841003220641086a2900003703002004200629000037035020061023200441c0006a41086a200529030037030020042004290350370340200441d0006a200110ac0141c00010212205450d02200520042903303700002005200429034037001020052004290050370020200541086a200441306a41086a290300370000200541186a200441c0006a41086a290300370000200541286a200441d0006a41086a290000370000200541306a200441d0006a41106a290000370000200541386a200441d0006a41186a290000370000200441086a200541c000108902200441086a41106a290300210720042903102108200428020821062005102320012008420020061b220820027c22092007420020061b20037c2009200854ad7c10dc02200041106a2003370300200041086a2002370300410021050c010b200041b4a0c200360204200041086a4122360200410121050b20002005360200200441f0006a24000f0b41c00041011030000b130020004101360204200041acaec2003602000b3400200041f7fbc40036020420004100360200200041146a4107360200200041106a4190b2c200360200200041086a42073702000b3001017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200241003600000b13002000410136020420004188bfc2003602000b880201057f230041106b22022400024002400240411110212203450d002002421137020420022003360200410d2002105c0240024020022802042204200228020822036b410d490d002003410d6a2105200228020021040c010b2003410d6a22052003490d03200441017422062005200620054b1b22064100480d030240024020040d002006102121040c010b200228020020042006102521040b2004450d0220022006360204200220043602000b20022005360208200420036a22034100290081ad42370000200341056a4100290086ad4237000020002002290300370200200041086a2002280208360200200241106a24000f0b411141011030000b200641011030000b102a000b891206057f027e047f017e047f027e23004180016b22012400200141d0006a41186a4200370300200141d0006a41106a22024200370300200141d0006a41086a2203420037030020014200370350200141c0006a41086a220441f7fbc400ad4280808080f000841003220541086a29000037030020012005290000370340200510232003200429030037030020012001290340370350200441e7acc500ad4280808080a001841003220541086a2900003703002001200529000037034020051023200220012903402206370300200141106a41086a2003290300370300200141106a41106a2006370300200141106a41186a20042903003703002001200637033020012001290350370310200141d0006a200141106a412010bb0120012902544200200128025022041b2207422088a74105742103410021052004410120041b220821040240024002400240024002400340024020030d00410221090c030b20002004460d0120042000412010de042102200541016a2105200341606a2103200441206a210420020d000b20024541016a41017120056a417f6a21050b200141d0006a41186a4200370300200141d0006a41106a220a4200370300200141d0006a41086a2203420037030020014200370350200141c0006a41086a220441f7fbc400ad4280808080f000841003220041086a2900003703002001200029000037034020001023200320042903003703002001200129034022063703302001200637035020044198b8c200ad4280808080a002841003220041086a2900003703002001200029000037034020001023200a20012903402206370300200141106a41086a2003290300370300200141106a41106a2006370300200141106a41186a20042903003703002001200637033020012001290350370310200141d0006a200141106a10950220012802502203410420031b210b4100210402400240024002402001290254420020031b2206422088220ca7220d41014b0d00200d0e020201020b200d2103034020042003410176220020046a22022005200b20024102746a280200491b2104200320006b220341014b0d000b0b4100210902402005200b20044102746a2802002203470d004100210e0c020b2004200520034b6a21040b200141d0006a41186a220f4200370300200141d0006a41106a22104200370300200141d0006a41086a2200420037030020014200370350200141c0006a41086a220341f7fbc400ad4280808080f000841003220241086a29000037030020012002290000370340200210232000200329030037030020012001290340220c3703302001200c370350200341e7acc500ad4280808080a001841003220241086a2900003703002001200229000037034020021023200141306a41086a2003290300220c370300200120012903402211370330200a2011370000200a41086a200c370000200141106a41086a2000290300370300200141106a41106a2010290300370300200141106a41186a200f29030037030020012001290350370310200141d0006a200141106aad4280808080800484100410900102400240200128025022020d00410021030c010b2001280254210f2001200028020036024420012002360240200141086a200141c0006a106e0240024020012802080d00200128020c21030c010b410021030b200f450d00200210230b20032003418094ebdc036e22004180ec94a37c6c6aad4280fd87d1007e2212428094ebdc038021112004200d4b0d020240200d2006a7470d00200d41016a2203200d490d06200d4101742202200320032002491b220341ffffffff03712003470d06200341027422024100480d0602400240200d0d0020021021210b0c010b200b200d41027420021025210b0b200b450d042003ad21060b200b20044102746a220341046a2003200d20046b41027410dd041a200320053602004101210e200642ffffffff0f83200d41016a2204ad220c422086842106200420004180fd87d1006c2011a76a201220114280ec94a37c7e7c4280cab5ee01566a4b21090b200141d0006a41186a22024200370300200141d0006a41106a220d4200370300200141d0006a41086a2203420037030020014200370350200141c0006a41086a220441f7fbc400ad4280808080f000841003220041086a2900003703002001200029000037034020001023200320042903003703002001200129034022113703302001201137035020044198b8c200ad4280808080a002841003220041086a2900003703002001200029000037034020001023200141306a41086a20042903002211370300200120012903402212370330200a2012370000200a41086a2011370000200141106a41086a2003290300370300200141106a41106a200d290300370300200141106a41186a20022903003703002001200129035037031002400240200b0d00200141106aad428080808080048410050c010b2001410036025820014201370350200ca72203200141d0006a105c0240024020030d002001280258210a2001280254210d200128025021030c010b4100200128025822046b2100200b20034102746a21102001280254210d200b210203402002280200210f02400240200d20006a4104490d00200128025021030c010b200441046a22032004490d08200d410174220a2003200a20034b1b220a4100480d0802400240200d0d00200a102121030c010b2001280250200d200a102521030b2003450d072001200a36025420012003360250200a210d0b2001200441046a220a360258200320046a200f3600002000417c6a2100200a21042010200241046a2202470d000b0b2006a72104200141106aad4280808080800484200aad4220862003ad8410020240200d450d00200310230b2004450d00200b10230b200e450d00200141106a41086a2005ad37030020014102360210200141d0006a200141106a109902200141cb006a200141d0006a41086a28020036000020012001290350370043200141dc006a200141c7006a290000370000200141c6a4b9da04360051200141023a005020012001290040370055200141d0006a108b012001410136025020012005360254200141d0006a10ea020b02402007a7450d00200810230b20014180016a240020090f0b4180bbc000102b000b200241041030000b200a41011030000b102a000bbc0503047f017e027f230041e0006b22012400200141003602402001420137033820002802002102410110212103024002400240024002400240024020024101460d002003450d02200142818080801037023c20012003360238200341013a0000200028020421022000410c6a2802002203200141386a105c02402003450d002002200341286c6a210403402002200141386a1071200241206a290300210502400240200128023c2206200128024022036b4108490d00200128023821060c010b200341086a22072003490d09200641017422032007200320074b1b22034100480d090240024020060d002003102121060c010b200128023820062003102521060b2006450d062001200336023c20012006360238200128024021030b2001200341086a360240200620036a20053700002004200241286a2202470d000b0b200041106a200141386a109e030c010b2003450d03200142818080801037023c20012003360238200341023a00002000280204210602400240200128023c2202200128024022036b4104490d00200128023821020c010b200341046a22072003490d06200241017422042007200420074b1b22074100480d060240024020020d002007102121020c010b200128023820022007102521020b2002450d052001200736023c200120023602380b2001200341046a360240200220036a20063600000b200141246a200141386a41086a2802003600002001200129033837001c200141c4006a200141206a290000370000200141cc006a2001290208370200200141d4006a200141086a41086a290200370200200141c28289aa04360039200141023a00382001200129001937003d200141386a108b01024020002802000d00200041086a280200450d00200028020410230b200141e0006a24000f0b410141011030000b200341011030000b410141011030000b200741011030000b102a000bde0506067f017e017f017e017f017e230041206b220224000240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200024002400240200541037122074103460d0002400240024020070e03000102000b2005410276ad21080c040b410121072006450d0220042d0001210620012003417e6a3602042001200441026a3602002006410874200572220141ffff0371418002490d02200141fcff0371410276ad21080c030b4101210720064103490d01200441036a2d0000210620042f0001210920012003417c6a3602042001200441046a3602002009200641107472410874200572220141808004490d012001410276ad21080c020b024020054102762209410c4b0d0002400240024020090e0d00030303010303030303030302000b20064104490d052004350001210820012003417b6a3602042001200441056a36020020084280808080045421074200210a0c060b20064108490d04200429000121082001200341776a3602042001200441096a3602002008428080808080808080015421074200210a0c050b20064110490d03200441096a290000210a2004290001210820012003416f6a3602042001200441116a360200200a428080808080808080015421070c040b200941046a220641104b0d022003417e6a2103200441026a21044100210541012107200241186a210b420021084200210a03402003417f460d01200241106a2004417f6a3100004200200541037441f8007110df0420012003360204200120043602002003417f6a2103200441016a2104200b290300200a84210a20022903102008842108200541016a220541ff01712006490d000b2002427f427f41e80020094103746b41f8007110e0042008200229030058200a200241086a290300220c58200a200c511b21070c030b0c020b4200210a410021070c010b410121070b20002008370308200041106a200a37030020002007ad370300200241206a24000b130020004104360204200041ecc0c2003602000b3400200041d5fbc40036020420004100360200200041146a4105360200200041106a41d8d5c200360200200041086a42083702000b130020004103360204200041ace6c2003602000b3a01017f02404110102122020d00411041011030000b2002420037000820024280c2d72f370000200042908080808002370204200020023602000b3400200041effbc40036020420004100360200200041146a4103360200200041106a41bce9c200360200200041086a42083702000b5101027f230041106b2202240002404104102122030d00410441011030000b200242043702042002200336020041002002105c200041086a200228020836020020002002290300370200200241106a24000bd72305017f037e087f017e037f230041900d6b220224004202210302400240024002400240024002400240024002400240200129036822044202520d00200241106a20014198016a41b00110dc041a0c010b2002418e026a200141246a41c20010dc041a200241d0026a41086a20014188016a290300370300200241d0026a41106a20014190016a290300370300200220014180016a2903003703d002200141f8006a2903002103200129037021052001280204210620012d00002107200241f00c6a41026a2208200141036a2d00003a000020024188036a41086a2209200141106a29020037030020024188036a41106a220a200141186a29020037030020024188036a41186a220b200141206a280200360200200220012f00013b01f00c200220012902083703880302400240024020074101460d00200241a00c6a41026a20082d00003a0000200241c0076a41086a2009290300370300200241c0076a41106a200a290300370300200241c0076a41186a200b2d00003a0000200220022f01f00c3b01a00c20022002290388033703c0070c010b200241f8086a200641067610bc0220022802f8082107024002402002280280092006413f7122064b0d00410021080c010b200241a00c6a41026a200720064105746a220641026a2d00003a0000200241c8076a2006410f6a290000370300200241d0076a200641176a290000370300200241d8076a2006411f6a2d00003a0000200220062f00003b01a00c200220062900073703c00720062800032106410121080b024020022802fc08450d00200710230b20080d00410121070c010b200241f8086a41026a200241a00c6a41026a2d00003a000020024188036a41086a200241c0076a41086a29030037030020024188036a41106a200241c0076a41106a29030037030020024188036a41186a200241c0076a41186a2d00003a0000200220022f01a00c3b01f808200220022903c00737038803410021070b200241800c6a41026a2208200241f8086a41026a2d00003a000020024188066a41086a220920024188036a41086a29030037030020024188066a41106a220a20024188036a41106a29030037030020024188066a41186a220b20024188036a41186a2d00003a0000200220022f01f8083b01800c20022002290388033703880602402007450d00200041013b0001200041013a0000200041036a41003a000020014198016a10db010c0a0b200241f7026a2009290300370000200241ff026a200a29030037000020024187036a200b2d00003a0000200220022f01800c3b01e802200220063600eb0220022002290388063700ef02200220082d00003a00ea02200241f8086a20014198016a41b00110dc041a200241a80a6a41106a200241d0026a41106a290300370300200241a80a6a41086a200241d0026a41086a290300370300200220022903d0023703a80a41002106200241f00c6a4100108901200241c00b6a41086a200241fb0c6a290000370300200241c00b6a41106a200241830d6a290000370300200241d50b6a200241f00c6a41186a2209290000370000200220022900f30c3703c00b20022f01f00c210c20022d00f20c210d200241a00c6a41186a4200370300200241a00c6a41106a220a4200370300200241a00c6a41086a22074200370300200242003703a00c200241e00c6a41086a220141c4fbc400ad4280808080e000841003220841086a290000370300200220082900003703e00c2008102320072001290300370300200220022903e00c220e3703c00c2002200e3703a00c200141f9bcc000ad4280808080e000841003220841086a290000370300200220082900003703e00c20081023200a20022903e00c220e370300200241f00c6a41086a2007290300370300200241f00c6a41106a200e370300200920012903003703002002200e3703d00c200220022903a00c3703f00c200241086a200241f00c6a4120108f01024020044201520d0020054200510d02200228020c410020022802081b2101417f21062001ad220e20032003200e541b220e200e20037d2005827d220e42ffffffff0f560d00200ea721060b200241e00c6a41086a220141c4fbc400ad4280808080e000841003220741086a290000370300200220072900003703e00c20071023200241c00c6a41086a22082001290300370300200220022903e00c3703c00c200141f0bcc000ad42808080809001841003220741086a290000370300200220072900003703e00c20071023200241d00c6a41086a22072001290300370300200220022903e00c3703d00c200220063602e00c200241f00c6a41186a2209200241e00c6aad4280808080c000841001220141186a290000370300200241f00c6a41106a220a200141106a290000370300200241f00c6a41086a220b200141086a290000370300200220012900003703f00c20011023200241a00c6a41186a220f2009290300370300200241a00c6a41106a2209200a290300370300200241a00c6a41086a220a200b290300370300200220022903f00c3703a00c41c00010212201450d02200120022903c00c370000200141086a2008290300370000200120022903d00c370010200141186a2007290300370000200120022903a00c370020200141286a200a290300370000200141306a2009290300370000200141386a200f2903003700002002200141c00041014100410010b8012002280200210720011023024020074101460d00200241e00b6a41156a200241800c6a41156a290000370000200241e00a6a41086a200241a00b6a41086a290000370300200241e00a6a41106a200241a00b6a41106a290000370300200241e00a6a41156a200241a00b6a41156a290000370000200241c00a6a41156a200241800b6a41156a290000370000200220022900a00b3703e00a200241f8086a10db01200041036a41003a0000200041800a3b0001200041013a00000c0a0b200241f00c6a2006108901200241800c6a41156a2201200241880d6a290000370000200241800c6a41106a2206200241830d6a290000370300200241e00b6a41086a2207200241fb0c6a290000370300200241e00b6a41106a22082006290300370300200241e00b6a41156a22062001290000370000200220022900f30c3703e00b20022f01f00c210120022d00f20c2109200241a00b6a41156a220a200241c00b6a41156a290000370000200241a00b6a41106a220b200241c00b6a41106a290300370300200241a00b6a41086a220f200241c00b6a41086a290300370300200220022903c00b3703a00b200241800b6a41156a22102006290000370000200241800b6a41106a22062008290300370300200241800b6a41086a22082007290300370300200220022903e00b3703800b200241e00a6a41156a2207200a290000370000200241e00a6a41106a220a200b290300370300200241e00a6a41086a220b200f290300370300200220022903a00b3703e00a200241c00a6a41156a220f2010290000370000200241c00a6a41106a22102006290300370300200241c00a6a41086a22062008290300370300200220022903800b3703c00a200241d0056a41156a22082007290000370000200241d0056a41106a2207200a290300370300200241d0056a41086a220a200b290300370300200220022903e00a3703d005200241b0056a41156a220b200f290000370000200241b0056a41106a220f2010290300370300200241b0056a41086a22102006290300370300200220022903c00a3703b005200241f0056a41106a2206200241a80a6a41106a290300370300200241f0056a41086a2211200241a80a6a41086a290300370300200220022903a80a3703f005200241c0076a41046a200241f8086a41b00110dc041a20024188066a200241c0076a41b40110dc041a20024188036a20024188066a41046a41b00110dc041a200241ee046a200c200d41107472220c4110763a0000200241ec046a220d200c3b0100200241c8046a2003370300200241c0046a2005370300200241d0046a220c20022903f005370300200241d8046a2011290300370300200241e0046a22112006290300370300200241ef046a20022903d005370000200241f7046a200a290300370000200241ff046a200729030037000020024184056a2008290000370000200220043703b804200241fc073602e8042002418e056a20093a00002002418c056a220720013b01002002418f056a20022903b00537000020024197056a20102903003700002002419f056a200f290300370000200241a4056a200b290000370000410410212201450d03200242043702c407200220013602c00720024188036a200241c0076a10cb010240024020022903b8044201510d000240024020022802c40720022802c8072201460d0020022802c00721060c010b200141016a22062001490d0a200141017422082006200820064b1b22084100480d0a0240024020010d002008102121060c010b20022802c00720012008102521060b2006450d07200220083602c407200220063602c00720022802c80721010b2002200141016a3602c807200620016a41003a00000c010b20022903c80420022903c0042203420c882204420120044201561b8021040240024020022802c407220620022802c80722016b4102490d0020022802c00721060c010b200141026a22082001490d09200641017422012008200120084b1b22014100480d090240024020060d002001102121060c010b20022802c00720062001102521060b2006450d07200220013602c407200220063602c00720022802c80721010b2002200141026a3602c807200620016a2004a741047420037aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b2011200241c0076a10af012002200c3602880620024188066a200241c0076a10c30120022802e80421080240024020022802c407220620022802c80722016b4104490d0020022802c00721060c010b200141046a22092001490d08200641017422012009200120094b1b22014100480d080240024020060d002001102121060c010b20022802c00720062001102521060b2006450d07200220013602c407200220063602c00720022802c80721010b2002200141046a3602c807200620016a20083600002002200241c0076a36028806200d20024188066a106b2002200241c0076a36028806200720024188066a106b20022802c007210120022802c40721070240024020022802c80722064180024b0d002002418e026a20012006200241e8026a10f30221060c010b200241f00c6a41186a22082006ad4220862001ad841001220641186a290000370300200241f00c6a41106a2209200641106a290000370300200241f00c6a41086a220a200641086a290000370300200220062900003703f00c20061023200241a00c6a41186a2008290300370300200241a00c6a41106a2009290300370300200241a00c6a41086a200a290300370300200220022903f00c3703a00c2002418e026a200241a00c6a4120200241e8026a10f30221060b02402007450d00200110230b2006450d08200241e8016a41086a200241e8026a41086a290300370300200241e8016a41106a200241e8026a41106a290300370300200241e8016a41186a200241e8026a41186a290300370300200241c0016a41086a200241c8046a290300370300200241c0016a41106a200241d0046a290300370300200241c0016a41186a200241d8046a290300370300200241e0016a200241e0046a290300370300200220022903e8023703e8012002200241c0046a2903003703c00120022903b8042103200241106a20024188036a41b00110dc041a0b200041086a20022903e801370300200041286a2003370300200041306a20022903c001370300200041206a200241e8016a41186a290300370300200041186a200241e8016a41106a290300370300200041106a200241e8016a41086a290300370300200041386a200241c0016a41086a290300370300200041c0006a200241c0016a41106a290300370300200041c8006a200241c0016a41186a290300370300200041d0006a200241c0016a41206a290300370300200041d8006a200241106a41b00110dc041a200041003a0000200241900d6a24000f0b41e8b8c600102b000b41c00041011030000b410441011030000b200841011030000b200141011030000b200141011030000b102a000b20004180083b0001200041013a0000200041036a41003a000020024188036a10db010b200241900d6a24000b9e0501037f230041b0016b22042400024002400240024020002d00000e03000102000b200441206a41186a200341186a290000370300200441206a41106a200341106a290000370300200441206a41086a200341086a29000037030020042003290000370320200041016a2002ad4220862001ad84200441206a100d41014621000c020b200441206a41186a200341186a290000370300200441206a41106a200341106a290000370300200441206a41086a200341086a29000037030020042003290000370320200041016a2002ad4220862001ad84200441206a100941014621000c010b20044190016a41186a22052002ad4220862001ad841001220141186a29000037030020044190016a41106a2202200141106a29000037030020044190016a41086a2206200141086a290000370300200420012900003703900120011023200441186a2005290300370300200441106a2002290300370300200441086a2006290300370300200420042903900137030041012101200441206a200041016a200410bd034100210020042d00200d00200441c8006a41206a200441c1006a2d00003a0000200441c8006a41186a200441396a290000370300200441c8006a41106a200441316a290000370300200441c8006a41086a200441296a290000370300200420042900213703482005200441c8006aad42808080809004841001220041186a2900003703002002200041106a2900003703002006200041086a290000370300200420002900003703900120001023200441f0006a41186a2005290300370300200441f0006a41106a2002290300370300200441f0006a41086a200629030037030020042004290390013703700240200441f0006a2003460d00200441f0006a2003412010de044521010b200121000b200441b0016a240020000b13002000410636020420004198f4c2003602000b34002000419da0c20036020420004100360200200041146a4106360200200041106a41c88dc300360200200041086a42103702000b130020004105360204200041c496c3003602000b3101017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200241b0093600000b3001017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200241073600000b3001017f02404104102122020d00410441011030000b20004284808080c000370204200020023602002002410d3600000b3c01017f02404110102122020d00411041011030000b2002420037000820024280e8eda1ba01370000200042908080808002370204200020023602000bb90202027f017e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120042001103921000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d02200141a085c0004102200220006a4180016a410020006b103c21000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d02200141a085c0004102200220006a4180016a410020006b103c21000b20024180016a240020000f0b2003418001103e000b2003418001103e000bfb0505027f027e017f027e027f230041a0016b220224002000280200210002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0220054290ce005441002004501b450d012005a72103412721000c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d02200141a085c0004102200241206a20006a41800120006b103c21000c060b41272100200241186a21060340200241106a200520044290ce00420010e2042002200229031022072006290300220842f0b17f427f10e104200241206a20006a2203417c6a200520022903007ca7220941ffff037141e4006e220a41017441ca82c0006a2f00003b00002003417e6a200a419c7f6c20096a41ffff037141017441ca82c0006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000c040b0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d01200141a085c0004102200241206a20006a41800120006b103c21000c040b2000418001103e000b2000418001103e000b2007a721030b02400240200341e3004a0d00200321090c010b200241206a2000417e6a22006a2003200341ffff037141e4006e2209419c7f6c6a41ffff037141017441ca82c0006a2f00003b00000b024002402009410a480d00200241206a2000417e6a22006a200941017441ca82c0006a2f00003b00000c010b200241206a2000417f6a22006a200941306a3a00000b200141c4b8c6004100200241206a20006a412720006b103c21000b200241a0016a240020000bba0201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff01832001103921000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d02200141a085c0004102200220006a4180016a410020006b103c21000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d02200141a085c0004102200220006a4180016a410020006b103c21000b20024180016a240020000f0b2004418001103e000b2004418001103e000b940705017f047e087f057e017f23004180026b22022400200241c0006a200110eb02024002402002290340a7450d00200041003602200c010b200241c0006a41106a290300210320022903482104200241286a200110eb0202402002290328a7450d00200041003602200c010b200241286a41106a290300210520022903302106200241206a2001106e0240024002400240024020022802200d00200128020441306e220741306c2208417f4c0d02200228022421090240024020080d004108210a0c010b20081021220a450d040b02402009450d004100210b0340200241003a00f801200b220c41016a210b2001280204417f6a21084100210d024002400240024003402008417f460d01200241d8016a200d6a2001280200220e2d00003a0000200120083602042001200e41016a3602002002200d41016a220e3a00f8012008417f6a2108200e210d200e4120470d000b200241b8016a41186a2208200241d8016a41186a290300370300200241b8016a41106a220d200241d8016a41106a290300370300200241b8016a41086a220e200241d8016a41086a290300370300200220022903d8013703b801200241086a200110eb022002290308a70d01200241086a41106a290300210f20022903102110200241f8006a41086a200e2903002211370300200241f8006a41106a200d2903002212370300200241f8006a41186a20082903002213370300200241d8006a41086a220d2011370300200241d8006a41106a220e2012370300200241d8006a41186a22142013370300200220022903b8012211370378200220113703582007200c470d030240200c4101742208200b2008200b4b1b2207ad42307e2211422088a70d002011a7220841004e0d030b102a000b200d41ff0171450d00200241003a00f8010b200241f8006a41086a20024198016a41086a2903003703002007450d04200a10230c040b02400240200c0d0020081021210a0c010b200a200c41306c20081025210a0b200a450d070b200a200c41306c6a2208200f3703082008201037030020082002290358370310200841186a200d290300370300200841206a200e290300370300200841286a2014290300370300200b2009470d000b0b200a0d010b200041003602200c040b20002004370300200020073602242000200a3602202000200637031020002003370308200041286a2009360200200041186a20053703000c030b102f000b200841081030000b200841081030000b20024180026a24000ba90c010d7f230041d0006b22022400200241306a41086a220341f7fbc400ad4280808080f000841003220441086a2900003703002002200429000037033020041023200241206a41086a20032903003703002002200229033037032020034184b9c200ad42808080808001841003220441086a2900003703002002200429000037033020041023200241086a200329030037030020022002290330370300200241306a4181adc200410d10d702024002400240024002400240024002402002280238220541206a2206417f4c0d00200228023021040240024002400240024002402006450d00200610212203450d022006410f4d0d01200621070c050b200641017422034110200341104b1b2207102121030c030b200641017422074110200741104b1b220741004e0d010c0b0b200641011030000b200320062007102521030b20030d00200741011030000b20032002290320370000200341086a200241206a41086a2903003700000240024002400240024020074170714110470d00200741017422084120200841204b1b22084100480d0c20032007200810252203450d01200821070b20032002290300370010200341186a200241086a2903003700000240200741606a20054f0d00200541206a22082005490d0c200741017422092008200920084b1b22084100480d0c20032007200810252203450d02200821070b200341206a2004200510dc041a02402002280234450d00200410230b200141086a280200220a41046a2208417f4c0d0420080d02410121040c030b200841011030000b200841011030000b200810212204450d020b20024100360238200220083602342002200436023020012d00002109024020080d00410110212204450d0320024101360234200220043602300b20024101360238200420093a000020012d0001210b02402002280234220920022802382208470d00200841016a22092008490d082008410174220c2009200c20094b1b22094100480d080240024020080d002009102121040c010b200420082009102521040b2004450d0420022009360234200220043602300b2002200841016a220c360238200420086a200b3a000020012d0002210d024002402009200c460d002009210b0c010b200941016a220b2009490d082009410174220e200b200e200b4b1b220b4100480d080240024020090d00200b102121040c010b20042009200b102521040b2004450d052002200b360234200220043602300b2002200841026a22093602382004200c6a200d3a000020012d0003210c0240200b2009470d00200b41016a220d200b490d08200b410174220e200d200e200d4b1b220d4100480d0802400240200b0d00200d102121040c010b2004200b200d102521040b2004450d062002200d360234200220043602300b2002200841036a360238200420096a200c3a000020012802042109200a200241306a105c0240024020022802342201200228023822046b200a490d00200228023021080c010b2004200a6a22082004490d082001410174220b2008200b20084b1b220b4100480d080240024020010d00200b102121080c010b20022802302001200b102521080b2008450d072002200b36023420022008360230200b21010b200820046a2009200a10dc041a200241306a41186a22092004200a6aad4220862008ad841001220441186a290000370300200241306a41106a220a200441106a290000370300200241306a41086a220b200441086a2900003703002002200429000037033020041023200241186a2009290300370300200241106a200a290300370300200241086a200b2903003703002002200229033037030002402001450d00200810230b02400240200720066b411f4b0d00200641206a22042006490d09200741017422082004200820044b1b22044100480d0920032007200410252203450d01200421070b200320066a22042002290300370000200441186a200241186a290300370000200441106a200241106a290300370000200441086a200241086a2903003700002000200541c0006a3602082000200736020420002003360200200241d0006a24000f0b200441011030000b102f000b200841011030000b410141011030000b200941011030000b200b41011030000b200d41011030000b200b41011030000b102a000b4d01017f230041206b22002400200041146a410136020020004201370204200041d09dc6003602002000410436021c200041849ec6003602182000200041186a360210200041f8abc2001038000bc20d08027f017e027f017e047f027e017f037e230041d0016b22062400200641e0006a41086a220741d5fbc400ad428080808080018422081003220941086a2900003703002006200929000037036020091023200641c0006a41086a220a200729030037030020062006290360370340200741e3a0c200ad4280808080b00184220b1003220941086a2900003703002006200929000037036020091023200641d0006a41086a220c200729030037030020062006290360370350200641e0006a200110ac01024002400240024041c00010212209450d00200920062903403700002009200629035037001020092006290060370020200941086a200a290300370000200941186a200c2903003700004128210d200941286a2007290000370000200941306a200641e0006a41106a220e290000370000200941386a200641e0006a41186a220f290000370000200641286a200941c000108902200641286a41106a2903002110200629033021112006280228211220091023200720081003220941086a2900003703002006200929000037036020091023200a2007290300370300200620062903603703402007200b1003220941086a2900003703002006200929000037036020091023200c200729030037030020062006290360370350200641e0006a200210ac0141c00010212209450d01200920062903403700002009200629035037001020092006290060370020200941086a200641c0006a41086a290300370000200941186a200641d0006a41086a290300370000200941286a200641e0006a41086a290000370000200941306a200e290000370000200941386a200f290000370000200641106a200941c000108902200641106a41106a2903002113200629031821142006280210210a2009102341c49ac300210920034280c2d72f7c2208200354220720042007ad7c220b200454200820035a1b0d0302402011420020121b221120087d22152011562010420020121b2210200b7d2011200854ad7d220820105620082010511b4101470d0041ec9ac3002109411d210d0c040b20134200200a1b210b20144200200a1b21100240200342ffc7afa0255620044200522004501b0d002010200b8450450d0041b69bc3002109411f210d0c040b200641086a200141022015200810de02024020062802082209450d00200628020c210d0c040b0240201020037c22112010542209200b20047c2009ad7c2210200b542010200b511b450d0041899bc3002109412d210d0c040b41002109024020012002470d000c040b024020012002412010de040d000c040b0240201542ffc7afa0255620084200522008501b0d0020050d0041d59bc3002109411b210d0c040b20012015200810dc02200641e0006a41086a220941d5fbc400ad42808080808001841003220741086a2900003703002006200729000037036020071023200641c0006a41086a220a200929030037030020062006290360370340200941e3a0c200ad4280808080b001841003220741086a2900003703002006200729000037036020071023200641d0006a41086a220c200929030037030020062006290360370350200641e0006a200210ac0141c00010212207450d02200720062903403700002007200629035037001020072006290060370020200741086a200a290300370000200741186a200c290300370000200741286a2009290000370000200741306a200641e0006a41106a290000370000200741386a200641e0006a41186a290000370000410021092006200741c00041014100410010b8012006280200210a200710230240200a4101460d00200210db02200641e0006a41386a2010370300200641e0006a41306a2011370300200641e0006a41086a41003a0000200641e9006a2002290000370000200641f1006a200241086a290000370000200641f9006a200241106a29000037000020064181016a200241186a290000370000200641023a0060200641e0006a108e010b20022011201010dc024280c2d72f420010cb02200641c8016a4200370300200641c0016a4280c2d72f370300200641b8016a2004370300200641b0016a2003370300200641e0006a41086a41023a0000200641e9006a2001290000370000200641f1006a200141086a290000370000200641f9006a200141106a29000037000020064181016a200141186a29000037000020064189016a200229000037000020064191016a200241086a29000037000020064199016a200241106a290000370000200641a1016a200241186a290000370000200641023a0060200641e0006a108e010c030b41c00041011030000b41c00041011030000b41c00041011030000b2000200d36020420002009360200200641d0016a24000b997908017f027e037f017e117f027e0f7f017e230041f0046b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e070001020304050a000b200341d4026a4101360200200342013702c402200341d09dc6003602c002200341043602e401200341849ec6003602e0012003200341e0016a3602d002200341c0026a41cc9cc3001038000b200141186a2903002104200141106a29030021052001410c6a2802002106200141086a2802002107200128020421082002411a6a2901002109200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241046a2d0000211741022101200241026a2f010021180240024020022d00000d0020022d00014101470d00200241056a2d00002101200241066a2f01002119200241086a2d000021024100211a0c010b4101211a41002102410021190b201941ffff0371410874200241187472200141ff01717221010240201a450d00410f211941aab0c0002102024002400240024020010e050001020321000b20154108742016722014411874722102201241087420137220114118747221190c200b410e211941aabac60021020c1f0b411321194197b0c00021020c1e0b411121194186b0c00021020c1d0b200320093703b0012003200a3a00af012003200b3a00ae012003200c3b01ac012003200d3a00ab012003200e3a00aa012003200f3b01a801200320103a00a701200320113a00a601200320123b01a401200320133a00a301200320143a00a201200320153b01a001200320163a009f012003200136009b01200320173a009a01200320183b019801200341c0026a41186a4200370300200341c0026a41106a22024200370300200341c0026a41086a22194200370300200342003703c002200341c0016a41086a2201419da0c200ad4280808080800284221b1003221a41086a2900003703002003201a2900003703c001201a102320192001290300370300200320032903c00122093703b002200320093703c002200141e4acc200ad4280808080a001841003221a41086a2900003703002003201a2900003703c001201a1023200220032903c0012209370300200341e0036a41086a2019290300370300200341e0036a41106a22132009370300200341e0036a41186a2001290300370300200320093703e001200320032903c0023703e003200341c0026a200341e0036aad4280808080800484220910041090014100211141002112024020032802c0022201450d0020032802c40221192003200341c8026a2802003602e401200320013602e001200341286a200341e0016a106e0240024020032802280d00200328022c21120c010b410021120b2019450d00200110230b200341c0026a41186a2214420037030020024200370300200341c0026a41086a22194200370300200342003703c002200341c0016a41086a2201201b1003221a41086a2900003703002003201a2900003703c001201a102320192001290300370300200320032903c001221b3703b0022003201b3703c00220014183e0c400ad4280808080f000841003221a41086a2900003703002003201a2900003703c001201a1023200341e0016a41086a2001290300221b370300200320032903c001221c3703e0012002201c370000200241086a201b370000200341e0036a41086a201929030037030020132002290300370300200341e0036a41186a2014290300370300200320032903c0023703e003200341c0026a20091004109001024020032802c0022202450d0020032802c4022101200320192802003602e401200320023602e001200341206a200341e0016a106e0240024020032802200d00200328022421110c010b410021110b2001450d00200210230b0240201120126a22020d0041dc9cc3002102412f21190c1d0b0240200620024d0d00418b9dc3002102412021190c1d0b41ab9dc300210241252119200641104b0d1c024020060d0041d09dc30021020c1d0b024020054281c8afa0255441002004501b450d0041f59dc3002102413021190c1d0b024020034198016a1083030d00200341186a20034198016a4280e8eda1ba01420010f1012003280218450d0041a59ec3002102411d21190c1d0b200341086a20034198016a10e301200342f0d0c9abc6add9b1f4003703b801200341b8016a20034198016a2003290308220920052009200554200341086a41086a290300220920045420092004511b22021b22052009200420021b2209417f411e10f701200341c0016a41086a2201419da0c200ad428080808080028422041003220241086a290000370300200320022900003703c00120021023200341b0026a41086a22192001290300370300200320032903c0013703b002200141a3a4c200ad4280808080f000841003220241086a290000370300200320022900003703c00120021023200341e0016a41086a221a2001290300370300200320032903c0013703e001200341c0026a20034198016a10ac0141c00010212202450d0a200220032903b002370000200241086a2019290300370000200220032903e001370010200241186a201a290300370000200220032903c002370020200241286a200341c0026a41086a290300370000200241306a200341d0026a2211290300370000200241386a200341c0026a41186a2212290300370000200320093703c802200320053703c0022002ad4280808080800884200341c0026aad4280808080800284100220021023200120041003220241086a290000370300200320022900003703c0012002102320192001290300370300200320032903c0013703b002200141ada0c200ad4280808080f000841003220241086a290000370300200320022900003703c00120021023201a2001290300370300200320032903c0013703e001200341c0026a20034198016a10ac0141c00010212201450d0b200120032903b002370000200141086a200341b0026a41086a290300370000200120032903e001370010200141186a200341e0016a41086a290300370000200120032903c002370020200141286a200341c0026a41086a290300370000200141306a2011290300370000200141386a2012290300370000200341e0016a200141c00010a2010240024020032d00ec0122024102460d0020034190046a41086a200341f5016a29000037030020034190046a41106a200341fd016a29000037030020034190046a41186a20034185026a290000370300200341c0016a41086a20034196026a290100370300200341c0016a41106a2003419e026a290100370300200341c0016a41186a200341a6026a2901003703002003200341ed016a2900003703900420032003418e026a2901003703c0012003418d026a2d0000211920032802e401450d0120032802e00110230c010b200320034198016a3602b403200341c0026a10c102200341b8036a20032802c002220220032802c802108a01024020032802c402450d00200210230b0240024020032d00b8030d00200341c0026a10c10220032802c0022102200320032802c80236029404200320023602900420034198016a20034190046a10f501024020032802c402450d00200210230b410021190c010b200341f8036a200341d1036a290000370300200341e0036a41106a200341c9036a290000370300200341e0036a41086a200341c1036a290000370300200320032900b9033703e00320034180046a200341e0036a10a101200341c0026a200328028004221a200328028804221110a201024020032d00cc024102470d00200341003602b802200342013703b002200341c0016a41146a410f360200200341c0016a410c6a410c360200200341103602dc042003419da0c2003602d8042003410c3602c401200341073602e404200341ada0c2003602e004200320034180046a3602d0012003200341e0046a3602c8012003200341d8046a3602c0012003200341b0026a3602ec0420034190046a41146a41033602002003420337029404200341e4ddc000360290042003200341c0016a3602a004200341ec046a41b8a3c50020034190046a102e1a20033502b80242208620033502b00284100820032802b403211920034190046a10c102200328029004210220032003280298043602c401200320023602c0012019200341c0016a10f5010240200328029404450d00200210230b024020032802b402450d0020032802b00210230b0240200328028404450d0020032802800410230b410021190c010b20034190046a200341c0026a410c6a41c20010dc041a20032d00b1042119200341c0016a41086a200341c0026a41086a2802002202360200200341c0016a41106a200341b2046a410020194101461b360200200320032903c00222093703c0012003200341b4036a3602cc01200341003602b802200342013703b0022002200341b0026a105c200341c0016a410c6a21132009a7211202402002450d00200241057421192012210203402002200341b0026a1071200241206a2102201941606a22190d000b0b2013200341b0026a10aa0120032802b40221022011ad422086201aad8420033502b80242208620032802b0022219ad84100202402002450d00201910230b024020032802c401450d00201210230b0240200328028404450d0020032802800410230b20032802b4032119200341c0026a10c10220032802c0022102200320032802c802360294042003200236029004201920034190046a10f501024020032802c402450d00200210230b200341c0016a41086a200341e0036a41086a290300370300200341c0016a41106a200341e0036a41106a290300370300200341c0016a41186a200341e0036a41186a290300370300200320032903e0033703c001410121190b410021020b200341cd026a200329039004370000200341ed026a20193a0000200341ee026a20032903c001370100200341d5026a20034190046a41086a290300370000200341dd026a20034190046a41106a290300370000200341e5026a20034190046a41186a290300370000200341f6026a200341c0016a41086a290300370100200341fe026a200341c0016a41106a29030037010020034186036a200341c0016a41186a290300370100200320023a00cc02200320063602c802200320073602c402200320083602c002200341003602e801200342013703e0012006200341e0016a105c20064105742102200341cc026a211903402008200341e0016a1071200841206a2108200241606a22020d000b2019200341e0016a10a90120032802e40121022001ad428080808080088420033502e80142208620032802e0012208ad84100202402002450d00200810230b20011023024020032802c402450d0020032802c00210230b410021020c1d0b2002411a6a2901002109200241196a2d00002119200241186a2d00002107200241166a2f0100211a200241156a2d00002111200241146a2d00002112200241126a2f01002113200241116a2d00002114200241106a2d000021152002410e6a2f010021162002410d6a2d000021062002410c6a2d0000210a2002410a6a2f0100210b200241096a2d0000210c200241046a2d0000210d41022108200241026a2f0100210e0240024020022d00000d0020022d00014101470d00200241056a2d00002108200241066a2f0100210f200241086a2d00002102410021100c010b41012110410021024100210f0b200320093703f803200320193a00f703200320073a00f6032003201a3b01f403200320113a00f303200320123a00f203200320133b01f003200320143a00ef03200320153a00ee03200320163b01ec03200320063a00eb032003200a3a00ea032003200b3b01e8032003200c3a00e7032003200d3a00e2032003200e3b01e0032003200f41ffff0371410874200241187472200841ff01717222083600e30302402010450d00410f211941aab0c0002102024020080e05000506071c000b20032800e703210220032800eb0321190c1b0b200341c0026a41186a200341e0036a41186a290300370300200341c0026a41106a200341e0036a41106a290300370300200341c0026a41086a200341e0036a41086a290300370300200320032903e0033703c002200341c0026a108303450d08200341c0026a4101108403410021020c1a0b2001411d6a29000021092001411c6a2d00002111200141196a2f00002112200141186a2d00002113200141156a2f00002114200141146a2d00002115200141116a2f00002116200141106a2d000021062001410d6a2f0000210a2001410c6a2d0000210b200141086a280200211920012d001b210c20012d0017210d20012d0013210e20012d000f210f20012d0007211020012f0005211720012d0004211d2002411a6a2901002104200241196a2d0000211e200241186a2d0000211f200241166a2f01002120200241156a2d00002121200241146a2d00002122200241126a2f01002123200241116a2d00002124200241106a2d000021182002410e6a2f010021252002410d6a2d000021262002410c6a2d000021272002410a6a2f01002128200241096a2d00002129200241046a2d0000212a41022108200241026a2f0100212b0240024020022d00000d0020022d00014101470d00200241056a2d00002108200241066a2f01002107200241086a2d000021024100211a0c010b4101211a41002102410021070b200741ffff0371410874200241187472200841ff01717221080240201a450d00410f211941aab0c0002102024020080e05000405061b000b20284108742029722027411874722102202541087420267220184118747221190c1a0b200320043703d0032003201e3a00cf032003201f3a00ce03200320203b01cc03200320213a00cb03200320223a00ca03200320233b01c803200320243a00c703200320183a00c603200320253b01c403200320263a00c303200320273a00c203200320283b01c003200320293a00bf03200320083600bb032003202a3a00ba032003202b3b01b8030240201d41ff01714101470d00200341c0026a201941067610bc0220032802c00221080240024020032802c8022019413f7122024b0d00410021020c010b200820024105746a2202290018210920022d0017211120022d0016210c20022f0014211220022d0013211320022d0012210d20022f0010211420022d000f211520022d000e210e20022f000c211620022d000b210620022d000a210f20022f0008210a20022d0007210b2002280003211920022d0002211020022f00002117410121020b024020032802c402450d00200810230b2002450d190b200320093703a804200320113a00a7042003200c3a00a604200320123b01a404200320133a00a3042003200d3a00a204200320143b01a004200320153a009f042003200e3a009e04200320163b019c04200320063a009b042003200f3a009a042003200a3b0198042003200b3a0097042003201936009304200320103a009204200320173b0190040240200341b8036a20034190046a412010de040d0041c29ec3002102411221190c1a0b0240200341b8036a1083030d0041d49ec3002102411821190c1a0b02400240024020034190046a108303450d00200341c0016a41086a2212419da0c200ad4280808080800284221b1003220241086a290000370300200320022900003703c00120021023200341b0026a41086a22082012290300370300200320032903c0013703b002201241ada0c200ad4280808080f000841003220241086a290000370300200320022900003703c00120021023200341e0016a41086a220a2012290300370300200320032903c0013703e001200341e0036a20034190046a10ac0141c00010212202450d0d200220032903b002370000200241086a2008290300370000200220032903e001370010200241186a200a290300370000200220032903e003370020200241286a200341e0036a41086a220b290300370000200241306a200341e0036a41106a290300370000200241386a200341e0036a41186a290300370000200341c0026a200241c00010bb012002102320032802c0022202410120021b221720032902c402420020021b221c422088a74105746a2110200341c0026a41106a21132017211a0340201a2010460d02200341c0026a41186a2215420037030020134200370300200341c0026a41086a22144200370300200342003703c0022012201b1003220241086a290000370300200320022900003703c0012002102320142012290300370300200320032903c0013703c00220124183e0c400ad4280808080f000841003220241086a290000370300200320022900003703c00120021023200b20122903002209370300200320032903c00122043703e00320132004370000201341086a220d2009370000200a2014290300370300200341e0016a41106a220e2013290300370300200341e0016a41186a220f2015290300370300200320032903c0023703e001200341c0026a200341e0016a10c002410021190240024020032902c402420020032802c00222021b2209422088a7220841306c22070d0041012111410021160c010b200741306d221641ffffff3f712016470d1c201641057422064100480d1c200610212211450d100b2009a7210c2002410820021b210602402008450d004100211920112102200621080340200841086a2900002109200841106a290000210420082900002105200241186a200841186a290000370000200241106a2004370000200241086a200937000020022005370000201941016a2119200241206a2102200841306a2108200741506a22070d000b0b0240200c450d00200610230b4101210841002102024002400240201941014b0d0020190e020201020b03402019410176220820026a22072002201120074105746a201a412010de044101481b2102201920086b221941014b0d000b0b201120024105746a201a412010de0441004721080b02402016450d00201110230b02402008450d00201542003703002013420037030020144200370300200342003703c0022012201b1003220241086a290000370300200320022900003703c0012002102320142012290300370300200320032903c0013703c002201241e4acc200ad4280808080a001841003220241086a290000370300200320022900003703c00120021023200b20122903002209370300200320032903c00122043703e00320132004370000200d2009370000200a2014290300370300200e2013290300370300200f2015290300370300200320032903c0023703e001200341c0026a200341e0016a412010bb0120032802c0022208410120081b21114100210202400240024020032902c402420020081b2209422088a7220841014b0d0020080e020201020b03402008410176221920026a22072002201120074105746a201a412010de044101481b2102200820196b220841014b0d000b0b201120024105746a201a412010de044521020b02402009a7450d00201110230b201a41206a211a2002450d010b0b201ca7450d00201710230b200341f0006a200341b8036a4280e8eda1ba01420010c8022003290370200341f8006a29030010c90241002108200341b8036a21190c010b0240201ca7450d00201710230b200341e0006a200341b8036a10e30102402003290360200341e0006a41086a2903008450450d0041b4a0c2002102412221190c1b0b200341c0016a41086a220241d5fbc400ad428080808080018422091003220841086a290000370300200320082900003703c00120081023200341e0036a41086a2002290300370300200320032903c0013703e003200241eea0c200ad4280808080f001841003220841086a290000370300200320082900003703c00120081023200341e0016a41086a2002290300370300200320032903c0013703e001200341c0026a20034190046a10ac0141c00010212202450d0d200220032903e003370000200241086a200341e0036a41086a221a290300370000200220032903e001370010200241186a200341e0016a41086a2208290300370000200220032903c002370020200241286a200341c0026a41086a290300370000200241306a200341c0026a41106a290300370000200241386a200341c0026a41186a290300370000200341c8006a200241c000108902200341c8006a41106a2903002104200329035021052003280248211920021023200341c0016a41086a220220091003220741086a290000370300200320072900003703c00120071023200341b0026a41086a22112002290300370300200320032903c0013703b002200241e3a0c200ad4280808080b001841003220741086a290000370300200320072900003703c0012007102320082002290300370300200320032903c0013703e001200341e0036a200341b8036a10ac0141c00010212202450d0e200220032903b002370000200241086a2011290300370000200220032903e001370010200241186a2008290300370000200220032903e003370020200241286a201a290300370000200241306a200341e0036a41106a290300370000200241386a200341e0036a41186a290300370000200341306a200241c000108902200341306a41106a290300211b200329033821092003280230210820021023200341b8036a2009420020081b221c2005420020191b22094280e8eda1ba0120094280e8eda1ba015441002004420020191b2204501b22021b22057c222c201b420020081b2004420020021b221b7c202c201c54ad7c10dc0220034190046a200920057d2004201b7d2009200554ad7d10ca024101210820034190046a21190b4100210220194100108403200341cd026a20034190046a41086a290300370000200341d5026a20034190046a41106a290300370000200341dd026a20034190046a41186a290300370000200341e5026a20032903b803370000200341ed026a200341b8036a41086a290300370000200341f5026a200341b8036a41106a290300370000200341fd026a200341b8036a41186a29030037000020034185036a20083a0000200341043a00c4022003410b3a00c00220032003290390043700c502200341c0026a108e010c190b2002411a6a2901002109200241196a2d00002116200241186a2d00002106200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000211a2002410e6a2f010021112002410d6a2d000021122002410c6a2d000021132002410a6a2f01002114200241096a2d00002115200241046a2d0000210f41022108200241026a2f010021100240024020022d00000d0020022d00014101470d00200241056a2d00002108200241066a2f01002119200241086a2d00002102410021070c010b4101210741002119410021020b201941ffff0371410874200841ff017172200241187472210802402007450d00410f211941aab0c0002102024020080e05000304051a000b201441087420157220134118747221022011410874201272201a4118747221190c190b200320093703a804200320163a00a704200320063a00a6042003200a3b01a4042003200b3a00a3042003200c3a00a2042003200d3b01a0042003200e3a009f042003201a3a009e04200320113b019c04200320123a009b04200320133a009a04200320143b019804200320153a00970420032008360093042003200f3a009204200320103b019004200341c0026a41186a4200370300200341c0026a41106a22114200370300200341c0026a41086a22084200370300200342003703c002200341c0016a41086a2202419da0c200ad42808080808002841003221941086a290000370300200320192900003703c0012019102320082002290300370300200320032903c0013703c002200241e4acc200ad4280808080a001841003221941086a290000370300200320192900003703c00120191023201120032903c0012209370300200341e0016a41086a2008290300370300200341e0016a41106a2009370300200341e0016a41186a2002290300370300200320093703e003200320032903c0023703e001200341c0026a200341e0016a412010bb0120032802c0022208410120081b211a4100211241002102024020032902c402420020081b2209422088a7220841014b0d004100211320080e021615160b03402008410176221920026a22072002201a20074105746a20034190046a412010de044101481b2102200820196b220841014b0d000c150b0b2002411a6a2901002109200241196a2d00002116200241186a2d00002106200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000211a2002410e6a2f010021112002410d6a2d000021122002410c6a2d000021132002410a6a2f01002114200241096a2d00002115200241046a2d0000210f41022108200241026a2f010021100240024020022d00000d0020022d00014101470d00200241056a2d00002108200241066a2f01002119200241086a2d00002102410021070c010b4101210741002119410021020b201941ffff0371410874200841ff01717220024118747221082007450d03410f211941aab0c0002102024020080e050001020318000b201441087420157220134118747221022011410874201272201a4118747221190c170b410e211941aabac60021020c160b411321194197b0c00021020c150b411121194186b0c00021020c140b200320093703a804200320163a00a704200320063a00a6042003200a3b01a4042003200b3a00a3042003200c3a00a2042003200d3b01a0042003200e3a009f042003201a3a009e04200320113b019c04200320123a009b04200320133a009a04200320143b019804200320153a00970420032008360093042003200f3a009204200320103b019004200341e0016a20034190046a108503024002400240024002400240024020032d00e001450d00200341c0026a41186a4200370300200341c0026a41106a22114200370300200341c0026a41086a22084200370300200342003703c002200341c0016a41086a2202419da0c200ad42808080808002841003221941086a290000370300200320192900003703c0012019102320082002290300370300200320032903c0013703c002200241eeacc200ad42808080809001841003221941086a290000370300200320192900003703c00120191023201120032903c0012209370300200341e0016a41086a2008290300370300200341e0016a41106a2009370300200341e0016a41186a2002290300370300200320093703e003200320032903c0023703e001200341c0026a200341e0016a10c00220032802c0022208410820081b211a4100210202400240024020032902c402420020081b2205422088a7221241014b0d0020120e020201020b2012210803402008410176221920026a22072002201a200741306c6a20034190046a412010de044101481b2102200820196b220841014b0d000b0b201a200241306c6a20034190046a412010de04450d050b200341c0026a41186a22074200370300200341c0026a41106a22124200370300200341c0026a41086a22084200370300200342003703c002200341c0016a41086a2202419da0c200ad42808080808002841003221941086a290000370300200320192900003703c0012019102320082002290300370300200320032903c0013703c002200241e4acc200ad4280808080a001841003221941086a290000370300200320192900003703c00120191023200341e0036a41086a20022903002209370300200320032903c00122043703e00320112004370000201141086a2009370000200341e0016a41086a2008290300370300200341e0016a41106a2012290300370300200341e0016a41186a2007290300370300200320032903c0023703e001200341c0026a200341e0016a412010bb0120032802c0022202410120021b211120032902c402420020021b2209422088a7221241014b0d014100210220120e020302030b20034190046a4280a094a58d1d420010de01200341cd026a20034198046a290300370000200341d5026a200341a0046a290300370000200341dd026a200341a8046a290300370000200341033a00c4022003410b3a00c00220032003290390043700c502200341c0026a108e01410021020c140b410021022012210803402008410176221920026a22072002201120074105746a20034190046a412010de044101481b2102200820196b220841014b0d000b0b201120024105746a20034190046a412010de04450d030b41f09fc30021022009a70d010c100b200220124f0d0a201a200241306c6a2208200841306a2002417f7320126a41306c10dd041a20034190046a4280a094a58d1d420010de01200341e0036a41186a4200370300200341e0036a41106a22074200370300200341e0036a41086a22084200370300200342003703e003200341c0016a41086a2202419da0c200ad42808080808002841003221941086a290000370300200320192900003703c0012019102320082002290300370300200320032903c00122093703b002200320093703e003200241eeacc200ad42808080809001841003221941086a290000370300200320192900003703c00120191023200720032903c0012209370300200341c0026a41086a2008290300370300200341c0026a41106a2009370300200341c0026a41186a2002290300370300200320093703e001200320032903e0033703c002200341003602e801200342013703e0012012417f6a2202200341e0016a105c0240024020020d0020032802e801210820032802e401210720032802e00121190c010b201a200241306c6a2112201a210203402002200341e0016a1071200241286a2903002109200241206a29030021040240024020032802e401220720032802e80122086b4110490d0020032802e00121190c010b200841106a22192008490d16200741017422082019200820194b1b22114100480d160240024020070d002011102121190c010b20032802e00120072011102521190b2019450d0e200320113602e401200320193602e00120032802e8012108201121070b201920086a22112009370008201120043700002003200841106a22083602e8012012200241306a2202470d000b0b200341c0026aad42808080808004842008ad4220862019ad84100202402007450d00201910230b410021022005a7450d10201a1023412e21190c150b201110230c0e0b200220124f0d0a201120024105746a2208200841206a2002417f7320126a41057410dd041a20034190046a4280a094a58d1d420010de01200341e0036a41186a4200370300200341e0036a41106a22074200370300200341e0036a41086a22084200370300200342003703e003200341c0016a41086a2202419da0c200ad42808080808002841003221941086a290000370300200320192900003703c0012019102320082002290300370300200320032903c00122043703b002200320043703e003200241e4acc200ad4280808080a001841003221941086a290000370300200320192900003703c00120191023200720032903c0012204370300200341c0026a41086a2008290300370300200341c0026a41106a2004370300200341c0026a41186a2002290300370300200320043703e001200320032903e0033703c002200341003602e801200342013703e0012012417f6a2202200341e0016a105c02402002450d00201241057441606a21082011210203402002200341e0016a1071200241206a2102200841606a22080d000b0b20032802e4012102200341c0026aad428080808080048420033502e80142208620032802e0012208ad84100202402002450d00200810230b410021022009a7450d0d201110230c0d0b024020022d000120022d000072450d004186b0c0002102411121190c130b200141086a2802002108024020012d00044101460d00200141106a2d00002119200141146a2d00002107200141186a2d0000211a2001411c6a2d0000211120012f0005210220012d0007211220012d000c211320012f000d211420012d000f211520012f0011211620012d0013210620012f0015210a20012d0017210b20012f0019210c20012d001b210d200129001d21090c0b0b200341c0026a200841067610bc0220032802c002210e0240024020032802c8022008413f7122024b0d004100210f0c010b200e20024105746a2202290018210920022d0017211120022d0016210d20022f0014210c20022d0013211a20022d0012210b20022f0010210a20022d000f210720022d000e210620022f000c211620022d000b211920022d000a211520022f0008211420022d000721132002280003210820022d0002211220022f000021024101210f0b024020032802c402450d00200e10230b200f0d0a4101210e0c0b0b419ea0c3002102410f21190c110b41c00041011030000b41c00041011030000b41c00041011030000b200641011030000b41c00041011030000b41c00041011030000b41b8bbc000102b000b201141011030000b41b8bbc000102b000b4100210e0b200320093701f803200320113a00f7032003200d3a00f6032003200c3b01f4032003201a3a00f3032003200b3a00f2032003200a3b01f003200320073a00ef03200320063a00ee03200320163b01ec03200320193a00eb03200320153a00ea03200320143b01e803200320133a00e703200320083600e303200320123a00e203200320023b01e003200e0d05200341e0016a41186a2202200341e0036a41186a290100370300200341e0016a41106a2208200341e0036a41106a290100370300200341e0016a41086a2219200341e0036a41086a290100370300200320032901e0033703e00120034190046a200341e0016a108503024020032d0090044101460d0020032d009104210720034188016a200341e0016a4280a094a58d1d420010c80220032903880120034188016a41086a29030010c902200341cd026a2019290300370000200341d5026a2008290300370000200341dd026a2002290300370000200341023a00c4022003410b3a00c002200320032903e0013700c502200341c0026a108e014100210202402007450d000c080b10bf020c070b20034190046a41086a280200211920032802940421020c060b2005a7450d00201a1023412e21190c050b412e21190c040b0240201a20024105746a20034190046a412010de0422080d0041012112200221130c010b2008411f7620026a21130b02402009a7450d00201a10230b02402012450d0041ec9ec3002102411e21190c030b200341c0026a41186a22074200370300200341c0026a41106a221a4200370300200341c0026a41086a22084200370300200342003703c002200341c0016a41086a2202419da0c200ad42808080808002841003221941086a290000370300200320192900003703c0012019102320082002290300370300200320032903c0013703c00220024183e0c400ad4280808080f000841003221941086a290000370300200320192900003703c00120191023200341e0036a41086a20022903002209370300200320032903c00122043703e00320112004370000201141086a2009370000200341e0016a41086a2008290300370300200341e0016a41106a201a290300370300200341e0016a41186a2007290300370300200320032903c0023703e001200341c0026a200341e0016a10c00220032902c402420020032802c00222021b2209422088a7220841306c220741306d21124100211902400240024002400240024020070d004101211a410021120c010b201241ffffff3f712012470d05201241057422074100480d0520071021221a450d010b2009a721152002410820021b211402402008450d00200841306c210741002119201a2102201421080340200841086a2900002109200841106a290000210420082900002105200241186a200841186a290000370000200241106a2004370000200241086a200937000020022005370000201941016a2119200241206a2102200841306a2108200741506a22070d000b0b02402015450d00201410230b4101210841002102024002400240201941014b0d0020190e020201020b03402019410176220820026a22072002201a20074105746a20034190046a412010de044101481b2102201920086b221941014b0d000b0b201a20024105746a20034190046a412010de0441004721080b02402012450d00201a10230b418a9fc3002102412121192008450d06200341c0026a41186a221a4200370300200341c0026a41106a22124200370300200341c0026a41086a22084200370300200342003703c002200341c0016a41086a2202419da0c200ad42808080808002841003220741086a290000370300200320072900003703c0012007102320082002290300370300200320032903c0013703c002200241eeacc200ad42808080809001841003220741086a290000370300200320072900003703c00120071023200341e0036a41086a20022903002209370300200320032903c00122043703e00320112004370000201141086a2009370000200341e0016a41086a2008290300370300200341e0016a41106a2012290300370300200341e0016a41186a201a290300370300200320032903c0023703e001200341c0026a200341e0016a10c00220032902c402420020032802c00222021b2209422088a7220841306c221a41306d21144100210702400240201a0d0041012112410021140c010b201441ffffff3f712014470d052014410574221a4100480d05201a10212212450d020b2009a721162002410820021b211502402008450d00200841306c211a4100210720122102201521080340200841086a2900002109200841106a290000210420082900002105200241186a200841186a290000370000200241106a2004370000200241086a200937000020022005370000200741016a2107200241206a2102200841306a2108201a41506a221a0d000b0b02402016450d00201510230b4101210841002102024002400240200741014b0d0020070e020201020b03402007410176220820026a221a20022012201a4105746a20034190046a412010de044101481b2102200720086b220741014b0d000b0b201220024105746a20034190046a412010de0441004721080b02402014450d00201210230b41ab9fc30021022008450d064200210920034180016a20034190046a4280a094a58d1d420010f1010240200328028001450d0041cc9fc3002102412421190c070b20032903a804210420032d00a704210720032d00a604211a20032f01a404211220032d00a304211420032d00a204211520032f01a004211620032d009f04210620032d009e04210a20032f019c04210b20032d009b04210c20032d009a04210d20032f019804210e20032d009704210f200328009304211020032d009204211720032f0190042118200341c0026a41186a22254200370300200341c0026a41106a22264200370300200341c0026a41086a22084200370300200342003703c002200341c0016a41086a2202419da0c200ad42808080808002841003221941086a290000370300200320192900003703c0012019102320082002290300370300200320032903c0013703c002200241e4acc200ad4280808080a001841003221941086a290000370300200320192900003703c00120191023200341e0036a41086a20022903002205370300200320032903c001221b3703e0032011201b370000201141086a2005370000200341e0016a41086a2008290300370300200341e0016a41106a2026290300370300200341e0016a41186a2025290300370300200320032903c0023703e001200341c0026a200341e0016a412010bb010240024020032802c00222190d004100210241012119410021080c010b20032902c4022209422088a721082009a721020b20082013490d02024020082002470d0020022009a7470d00200241016a22112002490d05200241017422252011202520114b1b221141ffffff3f712011470d05201141057422254100480d050240024020020d002025102121190c010b201920024105742025102521190b2019450d042011ad21090b201920134105746a220241206a2002200820136b41057410dd041a20022004370018200220073a00172002201a3a0016200220123b0014200220143a0013200220153a0012200220163b0010200220063a000f2002200a3a000e2002200b3b000c2002200c3a000b2002200d3a000a2002200e3b00082002200f3a000720022010360003200220173a0002200220183b0000200341e0036a41186a4200370300200341e0036a41106a22114200370300200341e0036a41086a22074200370300200342003703e003200341c0016a41086a2202419da0c200ad42808080808002841003221a41086a2900003703002003201a2900003703c001201a102320072002290300370300200320032903c00122043703b002200320043703e003200241e4acc200ad4280808080a001841003221a41086a2900003703002003201a2900003703c001201a1023201120032903c0012204370300200341c0026a41086a2007290300370300200341c0026a41106a2004370300200341c0026a41186a2002290300370300200320043703e001200320032903e0033703c002024020190d00200341c0026aad42808080808004841005410021020c070b200341003602e801200342013703e001200841016a2202200341e0016a105c02402002450d00201920024105746a21082019210203402002200341e0016a10712008200241206a2202470d000b0b2009a7210220032802e4012108200341c0026aad428080808080048420033502e80142208620032802e0012207ad84100202402008450d00200710230b02402002450d00201910230b410021020c060b200741011030000b201a41011030000b4180bbc000102b000b202541011030000b102a000b41aabac6002102410e21190b20012802004101470d01200141086a280200450d01200128020410230c010b2007450d00200810230b2000201936020420002002360200200341f0046a24000bd60201057f230041d0006b22012400200141306a41086a2202419da0c200ad42808080808002841003220341086a2900003703002001200329000037033020031023200141106a41086a2204200229030037030020012001290330370310200241a3a4c200ad4280808080f000841003220341086a2900003703002001200329000037033020031023200141206a41086a2205200229030037030020012001290330370320200141306a200010ac01024041c000102122030d0041c00041011030000b200320012903103700002003200129032037001020032001290030370020200341086a2004290300370000200341186a2005290300370000200341286a2002290000370000200341306a200141c0006a290000370000200341386a200141306a41186a290000370000200141086a200341c00041014100410010b8012001280208210220031023200141d0006a240020024101460bea1505047f017e027f017e047f23004180046b22022400200241e0006a41086a2203419da0c200ad42808080808002841003220441086a2900003703002002200429000037036020041023200241186a41086a2205200329030037030020022002290360370318200341ada0c200ad4280808080f000841003220441086a2900003703002002200429000037036020041023200241a0026a41086a22042003290300370300200220022903603703a002200241f0026a200010ac010240024002400240024041c00010212203450d0020032002290318370000200320022903a002370010200320022900f002370020200341086a2005290300370000200341186a2004290300370000200341286a200241f0026a41086a290000370000200341306a20024180036a290000370000200341386a200241f0026a41186a290000370000200241f0026a200341c00010a201024020022d00fc0222044102460d002003ad428080808080088410050b20022902f402210620022802f0022107200241186a200241fd026a41c30010dc041a200241e0006a200241186a41c30010dc041a024020044102470d00200310230c050b200220043a00a801200241a8016a410172200241e0006a41c10010dc042108200241ca016a21050240024020022d00c9014101460d00200241003602f0010c010b200241f0016a200510a10120022d00a80121040b024002400240200441ff01714101460d0020024100360280020c010b20024180026a200810a1012002280280020d010b024020022d00c9014101460d00200241f0026a10c10220023502f80242208620022802f0022204ad84100520022802f402450d04200410230c040b200241f0026a10c10220022802f0022104200220022802f8023602a402200220043602a0022005200241a0026a10f50120022802f402450d03200410230c030b20024190026a41086a20024180026a41086a28020022083602002002200229038002220937039002200241a0026a2009a7220a200810a201024020022d00ac024102470d00200241003602c803200242013703c003200241d0036a41146a410f360200200241dc036a410c360200200241103602ec032002419da0c2003602e8032002410c3602d403200241073602f403200241ada0c2003602f003200220024190026a3602e0032002200241f0036a3602d8032002200241e8036a3602d0032002200241c0036a3602fc03200241f0026a41146a4103360200200242033702f402200241a8ddc0003602f0022002200241d0036a36028003200241fc036a41b8a3c500200241f0026a102e1a20023502c80342208620023502c00384100820022802c403450d0220022802c00310230c020b200241f0026a200241a0026a41d00010dc041a200241bd036a200241c9016a220441206a2d00003a0000200241b5036a200441186a290000370000200241ad036a200441106a290000370000200241a5036a200441086a2900003700002002419d036a2004290000370000200241003602d803200242013703d00320022802f002210420022802f8022205200241d0036a105c200241fc026a210b02402005450d002005410574210503402004200241d0036a1071200441206a2104200541606a22050d000b0b200b200241d0036a10a90120022802d40321042008ad422086200aad8420023502d80342208620022802d0032205ad84100202402004450d00200510230b20022802f402450d0120022802f00210230c010b41c00041011030000b0240200228029402450d0020022802900210230b4101210a0c010b4100210a0b0240024020022802f00122080d00410021040c010b20024190026a41086a200241f0016a41086a280200220b360200200220022903f001220937039002200241a0026a2009a7220c200b10a2010240024020022d00ac024102470d00200241003602c803200242013703c003200241d0036a41146a410f360200200241dc036a410c360200200241103602ec032002419da0c2003602e8032002410c3602d403200241073602f403200241ada0c2003602f003200220024190026a3602e0032002200241f0036a3602d8032002200241e8036a3602d0032002200241c0036a3602fc03200241f0026a41146a4103360200200242033702f402200241ccdcc0003602f0022002200241d0036a36028003200241fc036a41b8a3c500200241f0026a102e1a20023502c80342208620023502c00384100820022802c403450d0120022802c00310230c010b200241f0026a200241a0026a41d00010dc041a2002419c036a200241a8016a41206a2d00003a000020024194036a200241c0016a2903003702002002418c036a200241b8016a29030037020020024184036a200241a8016a41086a290300370200200220022903a8013702fc02200241003602d803200242013703d00320022802f002210420022802f8022205200241d0036a105c200241fc026a210d02402005450d002005410574210503402004200241d0036a1071200441206a2104200541606a22050d000b0b200d200241d0036a10a90120022802d4032104200bad422086200cad8420023502d80342208620022802d0032205ad84100202402004450d00200510230b20022802f402450d0020022802f00210230b0240200228029402450d0020022802900210230b410121040b0240200a200228028002220545720d00200228028402450d00200510230b02402004200845720d0020022802f401450d00200810230b200310232007450d002006a7450d002007410120071b10230b200241e0006a41086a2204419da0c200ad42808080808002841003220341086a2900003703002002200329000037036020031023200241186a41086a2205200429030037030020022002290360370318200441a3a4c200ad4280808080f000841003220341086a2900003703002002200329000037036020031023200241a0026a41086a22072004290300370300200220022903603703a002200241f0026a200010ac01024041c00010212203450d0020032002290318370000200320022903a002370010200320022900f002370020200341086a2005290300370000200341186a2007290300370000200341286a200241f0026a41086a2205290000370000200341306a200241f0026a41106a2208290000370000200341386a200241f0026a41186a220a2900003700002003ad4280808080800884100520031023200242f0d0c9abc6add9b1f400370310200a42003703002008420037030020054200370300200242003703f002200441c4fbc400ad4280808080e000841003220341086a290000370300200220032900003703602003102320052004290300370300200220022903603703f002200441f9bcc000ad4280808080e000841003220341086a290000370300200220032900003703602003102320082002290360220637030020072005290300370300200241a0026a41106a2006370300200241a0026a41186a200429030037030020022006370318200220022903f0023703a002200241086a200241a0026a4120108f012002200228020c410020022802081b360260200241f0026a200010df0220022802f402210420022802f002210320022802f802210820024184036a200241106a3602002002200320084105746a3602fc02200220033602f802200220043602f402200220033602f0022002200241e0006a36028003200241a0026a200241f0026a10870120052007280200360200200220022903a0023703f0022000200241f0026a10e00202402001450d0020004280e8eda1ba01420010de010b20024180046a24000f0b41c00041011030000bb9200b057f017e027f017e037f017e017f017e037f047e017f23004190016b22022400200241e0006a41186a4200370300200241e0006a41106a22034200370300200241e0006a41086a220442003703002002420037036020024180016a41086a2205419da0c200ad42808080808002841003220641086a29000037030020022006290000370380012006102320042005290300370300200220022903800137036020054183e0c400ad4280808080f000841003220641086a29000037030020022006290000370380012006102320032002290380012207370300200241c0006a41086a2004290300370300200241c0006a41106a2007370300200241c0006a41186a20052903003703002002200737031020022002290360370340200241306a200241c0006a10c0020240024002400240024002400240024002400240200228023022080d0041002109410821080c010b2002290234220aa721094100210502400240200a422088a7220b41014b0d00200b0e020201020b200b210403402004410176220620056a220c20052008200c41306c6a2001412010de044101481b2105200420066b220441014b0d000b0b2008200541306c6a2001412010de04450d010b200041013a0000200041086a410c360200200041046a419ae0c4003602002009450d01200810230c010b024002400240024002402005200b4f0d002008200541306c6a2204200441306a200b2005417f736a41306c10dd041a200241e0006a41186a220d4200370300200241e0006a41106a220c4200370300200241e0006a41086a220442003703002002420037036020024180016a41086a2205419da0c200ad4280808080800284220e1003220641086a290000370300200220062900003703800120061023200420052903003703002002200229038001370360200541eeacc200ad42808080809001841003220641086a290000370300200220062900003703800120061023200241106a41086a220f200529030022073703002002200229038001221037031020032010370000200341086a2007370000200241c0006a41086a22112004290300370300200241c0006a41106a2212200c290300370300200241c0006a41186a2213200d29030037030020022002290360370340200241e0006a200241c0006a10c002200b417f6a210320022802602206410820061b210902402002290264420020061b221442208822074200520d00200d4200370300200c420037030020044200370300200242003703602005200e1003220641086a29000037030020022006290000370380012006102320042005290300370300200220022903800122073703302002200737036020054183e0c400ad4280808080f000841003220641086a290000370300200220062900003703800120061023200c2002290380012207370300201120042903003703002012200737030020132005290300370300200220073703302002200229036037034020024100360268200242013703602003200241e0006a105c0240024020030d00200228026821042002280264210c200228026021060c010b2008200341306c6a21032008210503402005200241e0006a1071200541286a2903002107200541206a2903002110024002402002280264220c200228026822046b4110490d00200228026021060c010b200441106a22062004490d0f200c41017422042006200420064b1b22014100480d0f02400240200c0d002001102121060c010b2002280260200c2001102521060b2006450d052002200136026420022006360260200228026821042001210c0b200620046a22012007370008200120103700002002200441106a22043602682003200541306a2205470d000b0b200aa72105200241c0006aad42808080808004842004ad4220862006ad8410020240200c450d00200610230b02402005450d00200810230b200041003b01002014a7450d06200910230c060b200a42ffffffff0f83210e20092007a7417f6a220d41306c6a22052903202115200541286a290300211620052900002107200541086a2900002110200541106a2900002117200241106a41186a200541186a290000370300200241106a41106a2017370300200f201037030020022007370310410021050240200b417f6a220441014b0d00024020040e020004000b200241e0006a41186a200241106a41186a290300370300200241e0006a41106a200241106a41106a290300370300200241e0006a41086a200241106a41086a2903003703002002200229031037036041002106200241e0006a21040c040b2003210403402004410176220620056a220c20052008200c41306c6a200241106a412010de044101481b2105200420066b220441014b0d000c030b0b41b8bbc000102b000b200141011030000b02402008200541306c6a200241106a412010de0422060d00200241c0006a210f0c020b200241e0006a41186a200241106a41186a290300370300200241e0006a41106a200241106a41106a290300370300200241e0006a41086a200241106a41086a29030037030020022002290310370360200241e0006a210420032006411f7620056a2206490d030b02402003200aa7470d00200341016a22052003490d082003410174220c2005200c20054b1bad220e42307e2207422088a70d082007a722054100480d080240024020030d002005102121080c010b2008200341306c2005102521080b2008450d040b2008200641306c6a220541306a2005200320066b41306c10dd041a200541286a201637030020052015370320200541186a200441186a290300370300200541106a200441106a290300370300200541086a200441086a29030037030020052004290300370300200241e0006a41186a22064200370300200241e0006a41106a220c4200370300200241e0006a41086a220442003703002002420037036020024180016a41086a2205419da0c200ad428080808080028422101003220341086a2900003703002002200329000037038001200310232004200529030037030020022002290380012207370330200220073703602005418c92c300ad4280808080e0018422171003220341086a290000370300200220032900003703800120031023200c2002290380012207370300200241c0006a41086a220f2004290300370300200241c0006a41106a22112007370300200241c0006a41186a221220052903003703002002200737033020022002290360370340200241086a200241c0006a4120108f0120022802082113200228020c211820064200370300200c42003703002004420037030020024200370360200520101003220341086a290000370300200220032900003703800120031023200420052903003703002002200229038001220737033020022007370360200520171003220341086a290000370300200220032900003703800120031023200620052903002207370300200f2004290300370300201120022903800122103703002012200737030020022010370330200220022903603703404101210f2002201841016a410120131b360260200241c0006aad4280808080800484200241e0006aad4280808080c0008410022006200141186a290000370300200c200141106a2900003703002004200141086a2900003703002002200129000037036002400240200a422088a722030d00410021010c010b200341ffffff3f712003470d08200341057422054100480d0820051021220f450d05200321010b0240024020082008200341306c6a470d00410021060c010b200b41306c210c41002106200f210520082104034020052004290000370000200541186a200441186a290000370000200541106a200441106a290000370000200541086a200441086a290000370000200641016a2106200541206a2105200441306a2104200c41506a220c0d000b0b200241e0006a4101200f200610c70202402001450d00200f10230b200241c0006a210f0b200241e0006a41186a4200370300200241e0006a41106a220b4200370300200241e0006a41086a220442003703002002420037036020024180016a41086a2205419da0c200ad42808080808002841003220641086a29000037030020022006290000370380012006102320042005290300370300200220022903800122073703302002200737036020054183e0c400ad4280808080f000841003220641086a290000370300200220062900003703800120061023200b2002290380012207370300200241c0006a41086a2004290300370300200241c0006a41106a2007370300200241c0006a41186a2005290300370300200220073703302002200229036037034020024100360268200242013703602003200241e0006a105c0240024020030d00200228026821042002280264210c200228026021060c010b2008200341306c6a21032008210503402005200241e0006a1071200541286a2903002107200541206a2903002110024002402002280264220c200228026822046b4110490d00200228026021060c010b200441106a22062004490d09200c41017422042006200420064b1b22014100480d0902400240200c0d002001102121060c010b2002280260200c2001102521060b2006450d072002200136026420022006360260200228026821042001210c0b200620046a22012007370008200120103700002002200441106a22043602682003200541306a2205470d000b0b200fad4280808080800484220a2004ad4220862006ad8410020240200c450d00200610230b0240200e500d00200810230b200241e0006a41186a220c4200370300200241e0006a41106a22084200370300200241e0006a41086a220442003703002002420037036020024180016a41086a2205419da0c200ad42808080808002841003220641086a290000370300200220062900003703800120061023200420052903003703002002200229038001220737033020022007370360200541eeacc200ad42808080809001841003220641086a290000370300200220062900003703800120061023200241306a41086a2005290300220737030020022002290380012210370330200b2010370000200b41086a2007370000200241c0006a41086a2004290300370300200241c0006a41106a2008290300370300200241c0006a41186a200c290300370300200220022903603703402002410036026820024201370360200d200241e0006a105c02400240200d0d00200228026821042002280264210c200228026021060c010b2009200d41306c6a21012009210503402005200241e0006a1071200541286a2903002107200541206a2903002110024002402002280264220c200228026822046b4110490d00200228026021060c010b200441106a22062004490d09200c41017422042006200420064b1b22084100480d0902400240200c0d002008102121060c010b2002280260200c2008102521060b2006450d082002200836026420022006360260200228026821042008210c0b200620046a22082007370008200820103700002002200441106a22043602682001200541306a2205470d000b0b200a2004ad4220862006ad8410020240200c450d00200610230b02402014a7450d00200910230b20004180023b01000b20024190016a24000f0b4180bbc000102b000b200541081030000b200541011030000b200141011030000b200841011030000b102a000bb40602027f067e230041b0016b220624000240200341ff0171450d00200641306a2001ad420042c0843d420010e104200641206a2002418094ebdc032002418094ebdc03491bad420042e807420010e104200641f0006a41186a4200370300200641f0006a41106a22074200370300200641f0006a41086a2203420037030020064200370370200641a0016a41086a220241d5fbc400ad42808080808001841003220141086a290000370300200620012900003703a0012001102320032002290300370300200620062903a001370370200241e8bbc300ad42808080809002841003220141086a290000370300200620012900003703a00120011023200720062903a0012208370300200641d0006a41086a2003290300370300200641d0006a41106a2008370300200641d0006a41186a2002290300370300200620083703900120062006290370370350200641306a41086a290300200641206a41086a2903007c2006290330220820062903207c2209200854ad7c20094280c2d72f7c2208200954ad7c2109200641c0006a200641d0006a109c020240024020062802400d00410021024200210a0c010b2006290348220b200b423f87220a7c200a85210a200b42005521020b200641106a20082009200a428094ebdc0380220b420010e1042006200a200b4280ec94a37c7e7ca722033602702006418094ebdc0336027420062008428094ebdc03804200200641f0006a2003418094ebdc034b4102746a350200220a420010e104427f427f2009200641106a41086a290300200641086a2903007c2006290310220c20062903007c220b200c54ad7c200b200a2008428094ebdc03827e220a200a428094ebdc0380220a4280ec94a37c7e7c4280cab5ee0156200aa76aad7c220a200b54ad7c220c7c2008200a7c220d2008542203ad7c220b2003200b200954200b2009511b22031b42002009200c7d2008200a54ad7d220b2008200a7d220a200856200b200956200b2009511b22011b20021b220820057c427f200d20031b4200200a20011b20021b220920047c22042009542202ad7c22092002200920085420092008511b22021b2105427f200420021b21040b2000200437030020002005370308200641b0016a24000be90408027f017e037f017e017f027e037f017e23004180016b2203240020012002844200522204ad2105024020040d00200341c0006a41186a22064200370300200341c0006a41106a22074200370300200341c0006a41086a2208420037030020034200370340200341f0006a41086a220441d5fbc400ad428080808080018422091003220a41086a2900003703002003200a290000370370200a10232008200429030037030020032003290370220b3703602003200b370340200441d6a0c200ad4280808080d00184220c1003220a41086a2900003703002003200a290000370370200a102320072003290370220b370300200341206a41086a220d2008290300370300200341206a41106a220e200b370300200341206a41186a220f20042903003703002003200b37036020032003290340370320200341086a200341206a4120108902200341086a41106a290300210b200329031021102003280208210a20064200370300200742003703002008420037030020034200370340200420091003220741086a290000370300200320072900003703702007102320082004290300370300200320032903702209370360200320093703402004200c1003220741086a2900003703002003200729000037037020071023200620042903002209370300200d2008290300370300200e2003290370220c370300200f20093703002003200c370360200320032903403703202003200b4200200a1b370348200320104200200a1b370340200341206aad4280808080800484200341c0006aad428080808080028410020b2000200137030820002005370300200041106a200237030020034180016a24000b13002000410336020420004184aac3003602000b3400200041f4fcc40036020420004100360200200041146a4103360200200041106a41a4b1c300360200200041086a42083702000b130020004104360204200041bcb5c3003602000b0b0020004190ce00108c030b3001017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200220013600000b3201017f02404104102122020d00410441011030000b20004284808080c0003702042000200236020020024180a3053600000b0b00200041d08603108c030be90804067f027e077f027e230041e0016b220324002003200236020420032001360200200341086a2002ad4220862001ad84100410900102400240200328020822040d00200042003703000c010b200341106a2802002105200328020c210641002101200341003a00d801200541706a2107024002400340024020052001470d00200141ff0171450d02200341003a00d8010c020b200341b8016a20016a200420016a2d00003a00002003200141016a22023a00d8012007417f6a21072002210120024120470d000b200341d8006a41086a200341b8016a41086a290300370300200341d8006a41106a200341b8016a41106a290300370300200341d8006a41186a200341b8016a41186a290300370300200320032903b801370358200520026b22084110490d00200420026a22052900002109200541086a290000210a41002101200341003a00d801200841706a21080340024020082001470d00200141ff0171450d02200341003a00d8010c020b200341b8016a20016a200520016a41106a2d00003a00002003200141016a22023a00d8012002210120024120470d000b200341f8006a41086a220b200341b8016a41086a2201290300370300200341f8006a41106a220c200341b8016a41106a2208290300370300200341f8006a41186a220d200341b8016a41186a220e290300370300200320032903b801370378200720026b410f4d0d00200341386a41086a2207200341d8006a41086a290300370300200341386a41106a220f200341d8006a41106a290300370300200341386a41186a2210200341d8006a41186a290300370300200341186a41086a2211200b290300370300200341186a41106a220b200c290300370300200341186a41186a220c200d2903003703002003200329035837033820032003290378370318200520026a220241106a2900002112200241186a2900002113200120072903003703002008200f290300370300200e201029030037030020034198016a41086a2202201129030037030020034198016a41106a2207200b29030037030020034198016a41186a2205200c290300370300200320032903383703b8012003200329031837039801200041206a2013370300200041186a2012370300200041106a200a37030020002009370308200041286a20032903b801370300200041306a2001290300370300200041386a2008290300370300200041c0006a200e290300370300200041c8006a200329039801370300200041d0006a2002290300370300200041d8006a2007290300370300200041e0006a2005290300370300420121090c010b200341003602a00120034201370398012003410c36027c20032003360278200320034198016a360258200341cc016a4101360200200342013702bc0120034198c2c3003602b8012003200341f8006a3602c801200341d8006a41b8a3c500200341b8016a102e1a20033502a0014220862003350298018410080240200328029c01450d0020032802980110230b420021090b200020093703002006450d00200410230b200341e0016a24000b3400200041d5fbc40036020420004100360200200041146a4101360200200041106a4190bbc300360200200041086a42083702000b13002000410236020420004194bcc3003602000b3901017f02404110102122020d00411041011030000b20024200370008200242c0843d370000200042908080808002370204200020023602000bde2003167f037e067f230041c0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d00200020011094032003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200a200a417f6a220d2000200a4105746a2000200d4105746a412010de04220e410048220f1b2210200a41016a2211200d200a200f1b220a200020114105746a2000200a4105746a412010de0441004822111b220a2000200a4105746a200020104105746a412010de0422104100481b210a200c200c417f6a220d2000200c4105746a2000200d4105746a412010de04221241004822131b2214200c4101722215200d200c20131b220c200020154105746a2000200c4105746a412010de0422134100481b220c2000200c4105746a200020144105746a412010de0422144100481b210c200b200b417f6a220d2000200b4105746a2000200d4105746a412010de04221541004822161b2217200b41016a2218200d200b20161b220b200020184105746a2000200b4105746a412010de04220d4100481b220b2000200b4105746a200020174105746a412010de0422164100481b210b41024101200f1b200e411f7620111b2010411f766a2012411f766a2013411f766a2014411f766a2015411f766a200d411f766a2016411f766a210d0b2000200c4105746a2000200a4105746a412010de04220f411f76200d6a2000200b4105746a2000200a200c200f410048220f1b220e4105746a412010de042210411f766a210d2000200b200e20104100481b220b4105746a2000200c200a200f1b22194105746a412010de04417f4c0d01200b21190c020b200020011095030c0f0b200d41016a220d410c490d0002402001410176220b450d00200020014105746a41606a210a2000210c0340200441206a41186a220d200c41186a220f290000370300200441206a41106a220e200c41106a2210290000370300200441206a41086a2211200c41086a22122900003703002004200c290000370320200a41086a2213290000211a200a41106a2214290000211b200a41186a2215290000211c200c200a290000370000200f201c3700002010201b3700002012201a3700002015200d2903003700002014200e29030037000020132011290300370000200a2004290320370000200a41606a210a200c41206a210c200b417f6a220b0d000b0b20012019417f736a21194101210a0c010b200d45210a0b0240200a452009724101710d00200020011096030d0d0b2002450d02201920014f0d0102402002200020194105746a220a412010de0441004e0d0020002108200121070c040b200441206a41186a2212200041186a220e290000370300200441206a41106a2213200041106a2210290000370300200441206a41086a2214200041086a221129000037030020042000290000370320200a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2000200a290000370000200e201c3700002010201b3700002011201a370000200d2012290300370000200b2013290300370000200c2014290300370000200a2004290320370000200441c0016a41186a2217200e290000370300200441c0016a41106a22182010290000370300200441c0016a41086a22192011290000370300200420002900003703c001200041606a2115200041206a21164100210c2001210b03400240200c200b417f6a220d4f0d002016200c4105746a210a0340200441c0016a200a412010de04417f4c0d01200a41206a210a200d200c41016a220c470d000b200d210c0b2015200b4105746a210a02400340200c200b417f6a220b4f0d01200441c0016a200a412010de04210d200a41606a220f210a200d4100480d000b20122016200c4105746a220a41186a220d2900003703002013200a41106a221d2900003703002014200a41086a22062900003703002004200a290000370320200f41286a221e290000211a200f41306a221f290000211b200f41386a2220290000211c200a200f41206a220f290000370000200d201c370000201d201b3700002006201a37000020202012290300370000201f2013290300370000201e2014290300370000200f2004290320370000200c41016a210c0c010b0b200020042903c001370000200e2017290300370000201020182903003700002011201929030037000002402001200c41016a220a490d002000200a4105746a21002001200a6b220141154f0d010c0c0b0b200a2001103e000b4190bfc30020192001102d000b2007450d010b201920074f0d01200441206a41186a2216200841186a221e290000370300200441206a41106a2217200841106a221f290000370300200441206a41086a2218200841086a222029000037030020042008290000370320200820194105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200441186a2205201e290000370300200441106a2209201f290000370300200441086a2221202029000037030020042008290000370300200841206a21014100211d2007417f6a220d450d022001210a0340200a2004412010de0441004e0d03200a41206a210a200d201d41016a221d470d000b200d211d0c020b41d8bec30041004100102d000b41e8bec30020192007102d000b200820074105746a210c200d210b02400340200c2100200b220a201d4d22060d01200a417f6a210b200041606a220c2004412010de04417f4a0d000b0b0240200a201d490d00200d200a490d0241800121144100210f410021124100210d4100211141800121152001201d4105746a2222210103400240200020016b220a419fc0004b22190d00200a410576220a41807f6a200a2012200f492011200d49220c72220b1b210a0240200b450d002015200a200c1b2115200a2014200c1b21140c010b200a200a41017622156b21140b02402011200d470d00024020150d00200441c0006a220d21110c010b4100210a200441c0006a2211210d2001210c0340200d200a3a0000200d200c2004412010de04417f73411f766a210d200c41206a210c2015200a41016a220a470d000b0b02402012200f470d00024020140d00200441c0016a220f21120c010b200041606a210a4100210c200441c0016a2212210f0340200f200c3a0000200f200a2004412010de04411f766a210f200a41606a210a2014200c41016a220c470d000b0b0240200f20126b220a200d20116b220c200c200a4b1b2213450d002016200120112d00004105746a220a41186a2900003703002017200a41106a2900003703002018200a41086a2900003703002004200a290000370320200120112d00004105746a220a200020122d0000417f734105746a220c290000370000200a41186a200c41186a290000370000200a41106a200c41106a290000370000200a41086a200c41086a290000370000024020134101460d004100210a034020002012200a6a220e2d0000417f734105746a220c20012011200a6a41016a22102d00004105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200120102d00004105746a220c2000200e41016a2d0000417f734105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200a41026a210c200a41016a220b210a200c2013490d000b2012200b6a21122011200b6a21110b200020122d0000417f734105746a220a2004290320370000200a41186a2016290300370000200a41106a2017290300370000200a41086a2018290300370000201241016a2112201141016a21110b200020144105746b20002012200f461b2100200120154105746a20012011200d461b210120190d000b024002402011200d4f0d002000210a034020162001200d417f6a220d2d00004105746a220c41186a220b2900003703002017200c41106a220f2900003703002018200c41086a22002900003703002004200c290000370320200a41606a220a41086a220e290000211a200a41106a2210290000211b200a41186a2212290000211c200c200a290000370000200b201c370000200f201b3700002000201a3700002012201629030037000020102017290300370000200e2018290300370000200a20042903203700002011200d490d000c020b0b2001210a2012200f4f0d000340200f417f6a220f2d0000210c2016200a41186a220b2900003703002017200a41106a220d2900003703002018200a41086a22012900003703002004200a2900003703202000200c417f734105746a220c41086a220e290000211a200c41106a2210290000211b200c41186a2211290000211c200a200c290000370000200b201c370000200d201b3700002001201a3700002011201629030037000020102017290300370000200e2018290300370000200c2004290320370000200a41206a210a2012200f490d000b0b20082004290300370000201e2005290300370000201f2009290300370000202020212903003700002007200a20226b410576201d6a22014d0d032016201e2900003703002017201f2900003703002018202029000037030020042008290000370320200820014105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41206a2100024002402001200c417f6a220c490d002000200c200a2003109303200821000c010b2008200120022003109303200a2102200c21010b200b200d4f2105200141154f0d010c050b0b201d200a103e000b200a200d1036000b41e8bec30020012007102d000b41f8bec300102b000b20014102490d00200041606a210f4101210b0340200b410574210a200b417f6a210c200b41016a210b02402000200a6a220a2000200c4105746a220d412010de04417f4a0d00200441c0016a41186a220e200a41186a2210290000370300200441c0016a41106a2211200a41106a2212290000370300200441c0016a41086a2213200a41086a22142900003703002004200a2900003703c001200a200d2900003700002014200d41086a2900003700002012200d41106a2900003700002010200d41186a2900003700004100210d0240200c450d00200f210a03400240200441c0016a200a412010de044100480d00200c210d0c020b200a41206a200a290000370000200a41386a200a41186a290000370000200a41306a200a41106a290000370000200a41286a200a41086a290000370000200a41606a210a200c417f6a220c0d000b0b2000200d4105746a220a20042903c001370000200a41186a200e290300370000200a41106a2011290300370000200a41086a20132903003700000b200f41206a210f200b2001470d000b0b200441c0026a24000beb050a067f017e017f017e017f017e017f017e017f017e230041206b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200020044105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c37000020052008370000024020032001490d00200321040c030b2006410d7420067322054111762005732205410574200573220620077122054100200120052001491b6b220520014f0d01200020034105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c370000200520083700002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200020044105746a22012900002108200020054105746a220041086a2205290000210a200041106a2204290000210c200041186a2203290000210e20012000290000370000200141186a220629000021102006200e370000200141106a2206290000210e2006200c370000200141086a2201290000210c2001200a370000200320103700002004200e3700002005200c370000200020083700000b200241206a24000f0b41e8bec30020052001102d000b41d8bec30020042001102d000be90609067f017e017f017e017f027e017f017e027f230041206b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d0220052006200020064105746a200020054105746a412010de044100481b21060b200620014f0d03200420014f0d02200020044105746a2204200020064105746a2205412010de0441004e0d03200541086a22072900002108200541106a2209290000210a200541186a220b290000210c2004290000210d20042005290000370000200441186a220e290000210f200e200c370000200441106a220e290000210c200e200a370000200441086a2204290000210a20042008370000200b200f3700002009200c3700002007200a3700002005200d370000200621040c000b0b41d8c0c30020062001102d000b41e8c0c30020042001102d000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241186a2209200041186a2204290000370300200241106a220b200041106a2205290000370300200241086a220e200041086a2203290000370300200020074105746a220641086a2900002108200641106a290000210a200641186a290000210c2000290000210d200020062900003700002004200c3700002005200a370000200320083700002002200d37030041002105024002400240034020062002290300370000200641186a2009290300370000200641106a200b290300370000200641086a200e2903003700002005410174220641017221040240200641026a220620074f0d00200420074f0d0220062004200020044105746a200020064105746a412010de044100481b21040b200420074f0d03200520074f0d02200020054105746a2205200020044105746a2206412010de0441004e0d032009200541186a2203290000370300200b200541106a2210290000370300200e200541086a2211290000370300200641086a2900002108200641106a290000210a200641186a290000210c2005290000210d200520062900003700002003200c3700002010200a370000201120083700002002200d370300200421050c000b0b41d8c0c30020042007102d000b41e8c0c30020052007102d000b200741014b0d000b0b200241206a24000f0b41e8bec30020072001102d000bdb08030a7f017e0a7f230041c0006b22022400200041a07f6a21032001417f6a2104200141324921054101210641002107024003400240024020062001490d00410021080c010b41012108200020064105746a2209200941606a412010de044100480d0003404101210a20042006460d03200641016a2106200941206a220a2009412010de042108200a21092008417f4a0d000b200620014921080b2006200146210a20050d0120062001460d0102400240024002402006417f6a220920014f0d002008450d0120002006410574220b6a220a290000210c200a200020094105746a22092900003700002009200c370000200a41086a220d290000210c200d200941086a220e290000370000200e200c370000200a41106a220f290000210c200f200941106a22102900003700002010200c370000200a41186a2211290000210c2011200941186a22122900003700002012200c37000020064102490d03200920002006417e6a22084105746a2213412010de04417f4a0d032009290000210c20092013290000370000200241206a41186a22142012290000370300200241206a41106a22152010290000370300200241206a41086a2216200e290000370300200e201341086a2900003700002010201341106a2900003700002012201341186a2900003700002002200c3703204100210e2008450d022003200b6a210903400240200241206a2009412010de044100480d002008210e0c040b200941206a2009290000370000200941386a200941186a290000370000200941306a200941106a290000370000200941286a200941086a290000370000200941606a21092008417f6a22080d000c030b0b41d8bec30020092001102d000b41e8bec30020062001102d000b2000200e4105746a22092002290320370000200941186a2014290300370000200941106a2015290300370000200941086a20162903003700000b200741016a21070240200120066b22104102490d00200a41206a2209200a412010de04417f4a0d00200a290000210c200a2009290000370000200241206a41186a22122011290000370300200241206a41106a2213200f290000370300200241206a41086a220b200d290000370300200d200941086a290000370000200f200941106a2900003700002011200941186a2900003700002002200c3703204101210d024020104103490d00200a41c0006a200241206a412010de04417f4a0d00410321084102210e0340200a200e4105746a220941606a220d2009290000370000200d41186a200941186a290000370000200d41106a200941106a290000370000200d41086a200941086a290000370000024020082010490d00200e210d0c020b20084105742109200e210d2008210e200841016a2108200a20096a200241206a412010de044100480d000b0b200a200d4105746a22092002290320370000200941186a2012290300370000200941106a2013290300370000200941086a200b2903003700000b20074105470d000b4100210a0b200241c0006a2400200a0bbb1301147f23004180026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d00200020011098032003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200b200b417f6a220e2000200b4102746a280200220f2000200e4102746a280200221049220d1b2211200b41016a2212200e200b200d1b200020124102746a280200220b2010200f200d1b220e4922101b200b200e20101b200020114102746a2802004922131b210b200c200c417f6a220e2000200c4102746a28020022112000200e4102746a280200221249220f1b2214200c4101722215200e200c200f1b200020154102746a280200220c20122011200f1b220e4922111b200c200e20111b200020144102746a2802004922141b210c200a200a417f6a22122000200a4102746a2802002215200020124102746a280200220649220e1b2216200a41016a22172012200a200e1b200020174102746a280200220a20062015200e1b22154922121b200a201520121b200020164102746a2802004922151b210a41024101200e1b200e20121b20156a200f6a20116a20146a200d6a20106a20136a210d0b200d2000200c4102746a280200220f2000200a4102746a280200221049220e6a2000200b4102746a280200220d2010200f200e1b22114922106a210f200d201120101b2000200c200a200e1b220d4102746a280200490d01200b200a200c200e1b20101b210d0c020b200020011099030c0f0b200f41016a220f410c490d0002402001410176220b450d00200020014102746a417c6a210a2000210c0340200c280200210e200c200a280200360200200a200e360200200c41046a210c200a417c6a210a200b417f6a220b0d000b0b2001200d417f736a210d4101210a0c010b200f45210a0b0240200a452009724101710d0020002001109a030d0d0b2002450d02200d20014f0d01024020022802002000200d4102746a220a280200220c4f0d0020002108200121070c040b2000280200210b2000200c360200200a200b3602002000417c6a2110200041046a21112000280200210d4100210c2001210b03400240200c200b417f6a220e4f0d002011200c4102746a210a0340200d200a280200490d01200a41046a210a200e200c41016a220c470d000b200e210c0b2010200b4102746a210a02400340200c200b417f6a220b4f0d01200a280200210e200a417c6a220f210a200d200e490d000b2011200c4102746a220a2802002112200a200e360200200f41046a2012360200200c41016a210c0c010b0b2000200d36020002402001200c41016a220a490d002000200a4102746a21002001200a6b220141154f0d010c0c0b0b200a2001103e000b4190bfc300200d2001102d000b2007450d010b200d20074f0d012008280200210a20082008200d4102746a220c280200360200200c200a360200200841046a210f20082802002111410021142007417f6a220d450d02200f210a0340200a28020020114f0d03200a41046a210a200d201441016a2214470d000b200d21140c020b41d8bec30041004100102d000b41e8bec300200d2007102d000b200820074102746a210c200d210b02400340200c210e200b220a20144d22060d01200a417f6a210b200e417c6a220c28020020114f0d000b0b0240200a2014490d00200d200a490d0241800121054100210b410021014100210c410021104180012109200f20144102746a2216210d03400240200e200d6b220a4183084b22130d00200a410276220a41807f6a200a2001200b492010200c49220f7222001b210a02402000450d002009200a200f1b2109200a2005200f1b21050c010b200a200a41017622096b21050b02402010200c470d00024020090d002004220c21100c010b4100210a20042210210c200d210f0340200c200a3a0000200c200f28020020114f6a210c200f41046a210f2009200a41016a220a470d000b0b02402001200b470d00024020050d0020044180016a220b21010c010b200e417c6a210a4100210f20044180016a2201210b0340200b200f3a0000200b200a2802002011496a210b200a417c6a210a2005200f41016a220f470d000b0b0240200b20016b220a200c20106b220f200f200a4b1b2212450d00200d20102d00004102746a220a2802002115200a200e20012d0000417f734102746a280200360200024020124101460d004100210a0340200e2001200a6a220f2d0000417f734102746a200d2010200a6a41016a22002d00004102746a280200360200200d20002d00004102746a200e200f41016a2d0000417f734102746a280200360200200a41026a210f200a41016a2200210a200f2012490d000b200120006a2101201020006a21100b200e20012d0000417f734102746a2015360200200141016a2101201041016a21100b200e20054102746b200e2001200b461b210e200d20094102746a200d2010200c461b210d20130d000b024002402010200c4f0d00200e210a0340200d200c417f6a220c2d00004102746a220b280200210e200b200a417c6a220a280200360200200a200e3602002010200c490d000c020b0b200d210a2001200b4f0d000340200a280200210c200a200e200b417f6a220b2d0000417f734102746a220d280200360200200d200c360200200a41046a210a2001200b490d000b0b200820113602002007200a20166b41027620146a22014d0d032008200820014102746a220a280200360200200a2011360200200720016b220c450d04200c20012001200c4b1b210b2007410376210e200a41046a2100024002402001200c417f6a220c490d002000200c200a2003109703200821000c010b2008200120022003109703200a2102200c21010b200b200e4f2105200141154f0d010c050b0b2014200a103e000b200a200d1036000b41e8bec30020012007102d000b41f8bec300102b000b20014102490d00200041746a210e4102210d4101210a0340200a41016a210c02402000200a4102746a2210280200220b2000200a417f6a22114102746a220f28020022124f0d002010201236020002402011450d00200b2000200a417e6a22104102746a221128020022124f0d00200f2012360200024020100d002011210f0c010b0240200b2000200a417d6a220a4102746a220f2802002210490d002011210f0c010b20112010360200200a450d00200d210f200e210a02400340200b200a28020022104f0d01200a41046a2010360200200a417c6a210a200f41016a2210200f4921112010210f2011450d000b0b200a41046a210f0b200f200b3602000b200d417f6a210d200e41046a210e200c210a200c2001470d000b0b20044180026a24000bf30201067f02400240024020014108490d00200141017641feffffff07712202417f6a220320014f0d022001410d74200173220441117620047322044105742004732205417f2001417f6a677622067122044100200120042001491b6b220420014f0d01200020034102746a220328020021072003200020044102746a220428020036020020042007360200024020022001490d00200221030c030b2005410d7420057322044111762004732204410574200473220520067122044100200120042001491b6b220420014f0d01200020024102746a220328020021072003200020044102746a2204280200360200200420073602002002410172220320014f0d022005410d742005732204411176200473220441057420047320067122044100200120042001491b6b220420014f0d01200020034102746a220128020021022001200020044102746a2200280200360200200020023602000b0f0b41e8bec30020042001102d000b41d8bec30020032001102d000bc70301067f024020014101762202450d0003402002417f6a2202210302400240024003402003410174220441017221050240200441026a220420014f0d00200520014f0d0220042005200020054102746a280200200020044102746a280200491b21050b200520014f0d03200320014f0d02200020034102746a22032802002204200020054102746a220628020022074f0d032003200736020020062004360200200521030c000b0b41d8c0c30020052001102d000b41e8c0c30020032001102d000b20020d000b0b0240024020014102490d002001210403402004417f6a220420014f0d02200028020021052000200020044102746a2203280200360200200320053602004100210302400240024003402003410174220641017221050240200641026a220620044f0d00200520044f0d0220062005200020054102746a280200200020064102746a280200491b21050b200520044f0d03200320044f0d02200020034102746a22032802002206200020054102746a220728020022024f0d032003200236020020072006360200200521030c000b0b41d8c0c30020052004102d000b41e8c0c30020032004102d000b200441014b0d000b0b0f0b41e8bec30020042001102d000b8a05010f7f2001417d6a2102200041086a21032000416c6a21042001417f6a2105200041046a2106410021072001413249210841012109024003400240024020092001490d004100210a0c010b4101210a20002009410274220b6a220c280200220d200c417c6a280200490d002006200b6a210a03404101210c20052009460d03200941016a2109200a280200220c200d4f210b200a41046a210a200c210d200b0d000b2009200149210a0b2009200146210c20080d0120092001460d0102400240024002402009417f6a220d20014f0d00200a450d012000200d4102746a220c280200210b200c20002009410274220e6a220a280200220d360200200a200b360200024020094102490d00200d20002009417e6a220b4102746a220f28020022104f0d00200c201036020002400240200b0d00200f210c0c010b0240200d20002009417d6a220b4102746a220c2802002210490d00200f210c0c010b200f2010360200200b450d00200d200a41706a280200220f4f0d002004200e6a2110024003402010220c41086a200f360200200b417f6a220b450d01200c417c6a2110200d200c280200220f490d000b0b200c41046a210c0b200c200d3602000b200741016a2107200120096b220b4102490d03200a280204220f200a280200220c4f0d03200a41046a210d200a200f360200200b4103490d02200a280208220f200c4f0d02200d200f3602000240200b41044f0d00200a41086a210d0c030b200220096b210a2003200e6a210d0340200d41046a220b280200220e200c4f0d03200d200e360200200b210d200a417f6a220a0d000b200b210d0c020b41d8bec300200d2001102d000b41e8bec30020092001102d000b200d200c3602000b20074105470d000b4100210c0b200c0bd20903067f017e057f230041f0016b22022400024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002005417f6a220541014b0d0520050e020102010b200041023a00000c050b20064104490d012004280001210720012003417b6a22053602042001200441056a36020020054108490d02200429000521082001200341736a36020420012004410d6a36020041002105200241003a00b001410d20036b2109200341726a210603400240200920056a0d000240200541ff0171450d00200241003a00b0010b200041023a00000c060b20024190016a20056a200420056a220a410d6a2d00003a0000200120063602042001200a410e6a3602002002200541016a220a3a00b0012006417f6a2106200a2105200a4120470d000b200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a290300370300200220022903900137037041002105200241003a00d0012004200a6a2109200a20036b410d6a210a03400240200a20056a0d000240200541ff0171450d00200241003a00d0010b200041023a00000c060b20024190016a20056a200920056a2204410d6a2d00003a00002001200636020420012004410e6a3602002002200541016a22043a00d0012006417f6a210620042105200441c000470d000b200241106a41386a220120024190016a41386a290300370300200241106a41306a220520024190016a41306a290300370300200241106a41286a220620024190016a41286a290300370300200241106a41206a220420024190016a41206a290300370300200241106a41186a220a20024190016a41186a290300370300200241106a41106a220320024190016a41106a290300370300200241106a41086a220920024190016a41086a290300370300200241d0006a41086a220b200241f0006a41086a290300370300200241d0006a41106a220c200241f0006a41106a290300370300200241d0006a41186a220d200241f0006a41186a290300370300200220022903900137031020022002290370370350200041003a000020002002290350370001200041096a200b290300370000200041116a200c290300370000200041196a200d290300370000200041216a2002290310370000200041296a2009290300370000200041316a2003290300370000200041396a200a290300370000200041c1006a2004290300370000200041c9006a2006290300370000200041d1006a2005290300370000200041d9006a2001290300370000200041e3006a2002410f6a2d00003a0000200041e1006a20022f000d3b0000200041e8006a2008370300200041e4006a20073602000c040b0240024020064104490d002004280001210620012003417b6a22053602042001200441056a360200200541084f0d010b200041023a00000c040b200041013a0000200020022f00103b0001200429000521082001200341736a36020420012004410d6a360200200041086a2008370300200041046a2006360200200041036a200241126a2d00003a0000200041106a20024190016a41e00010dc041a0c030b200041023a00000c020b200041023a00000c010b200041023a00000b200241f0016a24000beb0904057f017e0a7f037e230041c0016b2201240020014198016a41186a420037030020014198016a41106a2202420037030020014198016a41086a220342003703002001420037039801200141f8006a41086a220441cafbc400ad4280808080c000841003220541086a2900003703002001200529000037037820051023200320042903003703002001200129037837039801200441fccfc300ad4280808080b001841003220541086a2900003703002001200529000037037820051023200220012903782206370300200141086a41086a2003290300370300200141086a41106a2006370300200141086a41186a20042903003703002001200637035820012001290398013703082001412036022c2001200141086a360228200141306a200141086aad4280808080800484100410900102400240024002400240200128023022070d00410021080c010b200128023421092001200141306a41086a280200360254200120073602502001200141d0006a106e02400240024020012802000d002001280254220241286e220a41286c2204417f4c0d042001280204210b0240024020040d00410821080c010b200410212208450d060b0240200b450d004100210c0340200141003a00b801200c220d41016a210c410021040240024002400240034020022004460d0120014198016a20046a200128025022052d00003a00002001200541016a3602502001200441016a22033a00b8012003210420034120470d000b200141f8006a41086a220e20014198016a41086a290300370300200141f8006a41106a220f20014198016a41106a290300370300200141f8006a41186a221020014198016a41186a29030037030020012001290398013703782001200220036b220436025420044108490d01200141d8006a41086a2203200e290300370300200141d8006a41106a220e200f290300370300200141d8006a41186a220f2010290300370300200120012903783703582001200541096a3602502001200441786a220236025420052900012106200a200d470d030240200d4101742204200c2004200c4b1b220aad42287e2211422088a70d002011a7220441004e0d030b102a000b20014100360254200441ff0171450d00200141003a00b8010b4100210420014100360240200a450d05200810230c050b02400240200d0d002004102121080c010b2008200d41286c2004102521080b2008450d090b2008200d41286c6a2204200129035837030020032903002111200e2903002112200f290300211320042006370320200441186a2013370300200441106a2012370300200441086a2011370300200c200b470d000b0b200141c8006a200b3602002001200a36024420012008360240024020080d00200821040c020b200129024421060c020b41002104200141003602400b2001410036028001200142013703782001410c36025c2001200141286a3602582001200141f8006a360240200141ac016a41013602002001420137029c0120014198c2c300360298012001200141d8006a3602a801200141c0006a41b8a3c50020014198016a102e1a20013502800142208620013502788410080240200128027c450d00200128027810230b200421080b2009450d00200710230b024002402008450d0020002006370204200020083602000c010b20004100360208200042083702000b200141c0016a24000f0b102f000b200441081030000b200441081030000bd60302057f047e230041f0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100410900102400240200228021022030d00200041003a00000c010b200241186a28020021042002280214210541002101200241003a006802400340024020042001470d000240200141ff0171450d00200241003a00680b4100210120024100360228200242013703202002410c3602442002200241086a3602402002200241206a36026c200241dc006a41013602002002420137024c20024198c2c3003602482002200241c0006a360258200241ec006a41b8a3c500200241c8006a102e1a200235022842208620023502208410082002280224450d02200228022010230c020b200241c8006a20016a200320016a2d00003a00002002200141016a22063a00682006210120064120470d000b200241206a41186a200241c8006a41186a2903002207370300200241206a41106a200241c8006a41106a2903002208370300200241206a41086a200241c8006a41086a290300220937030020022002290348220a370320200041196a2007370000200041116a2008370000200041096a20093700002000200a370001410121010b200020013a00002005450d00200310230b200241f0006a24000b952901067f20002d0000210202400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2203280200200141086a22042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0120012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0001210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0220012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0002210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0320012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0003210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0420012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0004210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0520012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0005210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0620012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0006210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0720012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0007210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0820012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0008210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0920012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0009210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0a20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000a210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0b20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000b210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0c20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000c210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0d20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000d210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0e20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000e210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d0f20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d000f210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1020012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0010210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1120012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0011210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1220012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0012210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1320012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0013210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1420012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0014210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1520012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0015210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1620012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0016210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1720012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0017210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1820012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0018210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1920012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d0019210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1a20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001a210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1b20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001b210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1c20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001c210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1d20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001d210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1e20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001e210202400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d21200541017422072006200720064b1b22074100480d210240024020050d002007102121060c010b200128020020052007102521060b2006450d1f20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20023a000020002d001f210502400240200328020020042802002200460d00200128020021030c010b200041016a22032000490d21200041017422062003200620034b1b22064100480d210240024020000d002006102121030c010b200128020020002006102521030b2003450d2020012003360200200141046a2006360200200141086a28020021000b2004200041016a360200200320006a20053a00000f0b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200641011030000b102a000b3400200041cafbc40036020420004100360200200041146a4109360200200041106a41ccc9c300360200200041086a42043702000bcf0101017f024002400240024002400240410110212202450d00200241003a000020024101410210252202450d01200241003a000120024102410410252202450d02200241003b000220024104410810252202450d032002410036000420024108411010252202450d042002420037000820024110412010252202450d052002420037001820024200370010200042a08080808004370204200020023602000f0b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000b1300200041023602042000418cdcc3003602000b3101017f02404108102122020d00410841011030000b20004288808080800137020420002002360200200242f02e3700000b3101017f02404108102122020d00410841011030000b20004288808080800137020420002002360200200242d8043700000bde0401077f230041f0006b22022400200241d0006a41086a220341cefbc400ad4280808080f000841003220441086a2900003703002002200429000037035020041023200241086a41086a2205200329030037030020022002290350370308200341b5e1c300ad4280808080f000841003220441086a2900003703002002200429000037035020041023200241186a41086a22062003290300370300200220022903503703182002200036024c200241d0006a41186a2200200241cc006aad4280808080c000841001220441186a290000370300200241d0006a41106a2207200441106a2900003703002003200441086a2900003703002002200429000037035020041023200241286a41186a22042000290300370300200241286a41106a22082007290300370300200241286a41086a2207200329030037030020022002290350370328024041c00010212200450d00200020022903083700002000200229031837001020002002290328370020200041086a2005290300370000200041186a2006290300370000200041286a2007290300370000200041306a2008290300370000200041386a2004290300370000200128020021052001280208210320024100360258200242013703502003200241d0006a105c02402003450d00200341057421042005210303402003200241d0006a1071200341206a2103200441606a22040d000b0b200228025421032000ad4280808080800884200235025842208620022802502204ad84100202402003450d00200410230b200010230240200141046a280200450d00200510230b200241f0006a24000f0b41c00041011030000bae0a04037f027e057f017e23004190016b220424004101210502402001a722064101470d002000427f2000290300220720027c220820082007542205200041086a2209290300220720037c2005ad7c220820075420082007511b22051b3703002009427f200820051b370300410021050b0240024020014201560d00024020060e020200020b2005450d01200441d0006a41186a22064200370300200441d0006a41106a22094200370300200441d0006a41086a220542003703002004420037035020044180016a41086a220041d5fbc400ad428080808080018422071003220a41086a2900003703002004200a29000037038001200a1023200520002903003703002004200429038001220137037020042001370350200041d6a0c200ad4280808080d0018422081003220a41086a2900003703002004200a29000037038001200a102320092004290380012201370300200441306a41086a220b2005290300370300200441306a41106a220c2001370300200441306a41186a220d20002903003703002004200137037020042004290350370330200441186a200441306a4120108902200441186a41106a29030021012004290320210e2004280218210a20064200370300200942003703002005420037030020044200370350200020071003220941086a290000370300200420092900003703800120091023200520002903003703002004200429038001220737037020042007370350200020081003220941086a290000370300200420092900003703800120091023200620002903002207370300200b2005290300370300200c2004290380012208370300200d200737030020042008370370200420042903503703302004427f20014200200a1b220120037c200e4200200a1b220320027c22072003542200ad7c22022000200220015420022001511b22001b3703582004427f200720001b370350200441306aad4280808080800484200441d0006aad428080808080028410020c010b200441d0006a41186a22064200370300200441d0006a41106a22094200370300200441d0006a41086a220542003703002004420037035020044180016a41086a220041d5fbc400ad428080808080018422071003220a41086a2900003703002004200a29000037038001200a1023200520002903003703002004200429038001220137037020042001370350200041d6a0c200ad4280808080d0018422081003220a41086a2900003703002004200a29000037038001200a102320092004290380012201370300200441306a41086a220b2005290300370300200441306a41106a220c2001370300200441306a41186a220d200029030037030020042001370370200420042903503703302004200441306a4120108902200441106a29030021012004290308210e2004280200210a20064200370300200942003703002005420037030020044200370350200020071003220941086a290000370300200420092900003703800120091023200520002903003703002004200429038001220737037020042007370350200020081003220941086a290000370300200420092900003703800120091023200620002903002207370300200b2005290300370300200c2004290380012208370300200d200737030020042008370370200420042903503703302004427f20014200200a1b220120037c200e4200200a1b220320027c22072003542200ad7c22022000200220015420022001511b22001b3703582004427f200720001b370350200441306aad4280808080800484200441d0006aad428080808080028410020b20044190016a24000bdb0c040a7f027e017f017e230041900f6b220324002003200236020420032001360200200341086a2002ad4220862001ad84100410900102400240200328020822040d00200041033602000c010b200341086a41086a2802002105200328020c2106200341003a00f8082004210241002107024002400240024003400240024002402005450d0020022d0000220141014b0d002005417f6a2108200241016a21090240024002400240024020010e020100010b2008450d01200241026a21092005417e6a210120022d0001220a41014b0d02024002400240200a0e020001000b41002101200341003a00e0092005417e6a210a03400240200a2001470d00200220016a41026a2109200141ff0171450d05200341003a00e0090c050b200341c0096a20016a200220016a41026a2d00003a00002003200141016a22093a00e0092009210120094120470d000b200341f00e6a41186a220a200341c0096a41186a290300370300200341f00e6a41106a220b200341c0096a41106a290300370300200341f00e6a41086a220c200341c0096a41086a290300370300200320032903c0093703f00e200220096a21020240200520096b2209417e6a220141034b0d00200241026a21094102210a0c060b200241026a2800002108200341d00e6a41186a200a290300370300200341d00e6a41106a200b290300370300200341d00e6a41086a200c290300370300200320032903f00e3703d00e2009417a6a2101200241066a21094100210a0c010b200141034d0d0320022800022108200341d00e6a41186a200341c0096a41186a290200370300200341d00e6a41106a200341c0096a41106a290200370300200341d00e6a41086a200341c0096a41086a290200370300200320032902c0093703d00e2005417a6a2101200241066a21094101210a0b200341b00e6a41086a2202200341d00e6a41086a290300370300200341b00e6a41106a2205200341d00e6a41106a290300370300200341b00e6a41186a220b200341d00e6a41186a290300370300200320032903d00e3703b00e20014110490d02200941086a290000210d2009290000210e200341c0096a41186a200b290300370300200341c0096a41106a2005290300370300200341c0096a41086a2002290300370300200320032903b00e3703c009200941106a2109200141706a21012008210f0c030b20034180096a41186a200341a0096a41186a29030037030020034180096a41106a200341a0096a41106a29030037030020034180096a41086a200341a0096a41086a290300370300200320032903a009370380094102210a200821050c050b410021010b4102210a0b200341f00d6a41086a2202200341c0096a41086a290300370300200341f00d6a41106a2205200341c0096a41106a290300370300200341f00d6a41186a2208200341c0096a41186a290300370300200320032903c0093703f00d200a4102470d010b20034180096a41186a200341a0096a41186a290300370300200741ff0171450d03200341003a00f8080c030b200341a0096a41186a2008290300221037030020034180096a41086a200229030037030020034180096a41106a200529030037030020034180096a41186a2010370300200320032903f00d37038009200121050b20092102200341c8046a200741386c6a2201200a360200200141086a200329038009370200200141106a20034180096a41086a290300370200200141186a20034180096a41106a290300370200200141206a20034180096a41186a290300370200200141306a200d370200200141286a200e3702002001200f3602042003200741016a22013a00f808200121072001410a470d000b20032802c8042102200341c0096a200341c8046a41047241ac0410dc041a200141ff017141094b0d010b410321020c010b200341186a200341c0096a41ac0410dc041a20024103460d00200341c8046a200341186a41ac0410dc041a200041046a200341c8046a41ac0410dc041a0c010b200341003602c809200342013703c0092003410c36021c200320033602182003200341c0096a3602f00e200341dc046a4101360200200342013702cc0420034198c2c3003602c8042003200341186a3602d804200341f00e6a41b8a3c500200341c8046a102e1a20033502c80942208620033502c00984100820032802c409450d0020032802c00910230b200020023602002006450d00200410230b200341900f6a24000bfa0302077f017e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022010d00200041003602080c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d002003200141046a36022020032002417c6a220536022420054104490d00200128000021052003200241786a3602242003200141086a36022020012800042106200341c8006a200341206a107e20032802482202450d00200341c8006a41086a2802002107200328024c2108200341c8006a200341206a107e20032802480d012008450d00200210230b20034100360230200342013703282003410c36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034198c2c3003602482003200341386a360258200341c4006a41b8a3c500200341c8006a102e1a2003350230422086200335022884100820004100360208200328022c450d01200328022810230c010b200341286a41086a200341c8006a41086a280200220936020020032003290348220a370328200041106a20073602002000200836020c200020023602082000200636020420002005360200200041146a200a3702002000411c6a20093602000b2004450d00200110230b200341e0006a24000b8e0b040e7f027e037f037e230041c0016b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022040d00200041003602000c010b200328021421052003200341186a280200360234200320043602302003200341306a106e024002400240024002400240024002400240024002400240024020032802000d002003280234220641d8006e220741d8006c2201417f4c0d02200328020421080240024020010d00410821090c010b200110212209450d040b2008450d014100210a4100210b0340200341003a00b801200b41016a210c4100210102400240034020062001460d0120034198016a20016a2003280230220d2d00003a00002003200d41016a3602302003200141016a22023a00b8012002210120024120470d000b200341f8006a41086a220e20034198016a41086a290300370300200341f8006a41106a220f20034198016a41106a290300370300200341f8006a41186a221020034198016a41186a29030037030020032003290398013703782003200620026b2201360234200141104f0d010c0d0b20034100360234200141ff0171450d0c200341003a00b8010c0c0b2003200d41116a3602302003200141706a360234200d41096a2900002111200d290001211220034198016a200341306a1084012003280298012202450d0b20032802a0012113200328029c01210d20034198016a200341306a107e2003280298012206450d0a200328029c012114024020032802342201410f4b0d0020140d090c0a0b20032802a0012115200341d8006a41086a200e2903002216370300200341d8006a41106a200f2903002217370300200341d8006a41186a20102903002218370300200341386a41086a220e2016370300200341386a41106a220f2017370300200341386a41186a221020183703002003200329037822163703582003200141706a36023420032003280230220141106a36023020032016370338200141086a29000021162001290000211702402007200b470d00200b4101742201200c2001200c4b1b2207ad42d8007e2218422088a70d072018a722014100480d0702400240200b0d002001102121090c010b2009200b41d8006c2001102521090b2009450d060b2009200b41d8006c6a2201201737031020012011370308200120123703002001200636022c20012002360220200141186a2016370300200141346a2015360200200141306a2014360200200141286a2013360200200141246a200d36020020012003290338370338200141c0006a200e290300370300200141c8006a200f290300370300200141d0006a20102903003703000240200c2008470d00200341286a200836020020032007360224200320093602200c080b200a41d8006a210a20032802342106200c210b0c000b0b200341003602200c0a0b200341286a2008360200200320073602242003200936022020090d040c090b102f000b200141081030000b200141081030000b102a000b20002003290320370200200041086a200341206a41086a2802003602000c050b200610230b200d450d01200210230c010b200d450d00200210230b200341003602200240200b450d00200941306a210103400240200141746a280200450d00200141706a28020010230b02402001280200450d002001417c6a28020010230b200141d8006a2101200a41a87f6a220a0d000b0b2007450d00200910230b2003410036028001200342013703782003410c36025c2003200341086a3602582003200341f8006a360238200341ac016a41013602002003420137029c0120034198c2c300360298012003200341d8006a3602a801200341386a41b8a3c50020034198016a102e1a200335028001422086200335027884100820004100360200200328027c450d00200328027810230b2005450d00200410230b200341c0016a24000b810201037f230041d0006b220124002001412036020420012000360200200141086a2000ad4280808080800484100410900102400240200128020822020d00410421000c010b200128020c210302400240200141106a280200450d0020022d000022004104490d010b20014100360220200142013703182001410c36022c200120013602282001200141186a360234200141cc006a41013602002001420137023c20014198c2c3003602382001200141286a360248200141346a41b8a3c500200141386a102e1a200135022042208620013502188410080240200128021c450d00200128021810230b410421000b2003450d00200210230b200141d0006a240020000be10c05077f017e037f037e017f23004190016b220324002003200236022420032001360220200341286a2002ad4220862001ad84100410900102400240200328022822010d00200041033a00040c010b200328022c21042003200341306a280200220536023c200320013602380240024020054104490d002001280000210620032005417c6a220236023c2003200141046a3602382002450d0020012d0004210220032005417b6a36023c2003200141056a360238200241024b0d000240024002400240024002400240024020020e03000102000b41002102200341003a0088012005417b6a2107417a21080340024020072002470d00200241ff0171450d09200341003a0088010c090b200341e8006a20026a200120026a220941056a2d00003a00002003200520086a36023c2003200941066a3602382003200241016a22093a0088012008417f6a21082009210220094120470d000b200341c8006a41086a20034183016a2d00003a00002003200329006f37005f200320032903683703582003200329007b220a370348200520096b2202417b6a41034d0d07200341e6006a2d0000210b20032f0164210c200328028401210d20032800772108200328026021072003290358210e2003290049210f200341c4006a41026a200341c0006a41026a2d00003a0000200320032f00403b0144200120096a220941056a28000021052003200241776a36023c2003200941096a3602382008411874200c200b4110747241ffffff077172210b200aa741ff01714118742008410876722109410021020c020b41002102200341003a0088012005417b6a21092005417a6a21050340024020092002470d00200241ff0171450d08200341003a0088010c080b200341e8006a20026a200120026a220841056a2d00003a00002003200841066a3602382003200241016a22083a0088012003200536023c2005417f6a21052008210220084120470d000b200341d0006a220220034183016a2d00003a000020032003290368220e370358200341c2006a20032d005a3a00002003200329006f37005f2003200329007b220a3703482003200e3d0140200335028401210f2003280077210720023100002110200329005f210e200328005b2105200328024c2109200341086a200341386a106e20032802080d06200328023c2202200328020c2208490d062008417f4c0d0202400240024020080d004101210d4101450d090c010b20081027220d450d01200d2003280238220b200810dc04210c2003200220086b36023c2003200b20086a360238200c450d080b200aa7210b200341c4006a41026a200341c0006a41026a2d00003a0000200320032f01403b0144200f420886201084210f410121020c020b200841011030000b200341186a200341386a106e20032802180d05200328023c2208200328021c2202490d052002417f4c0d010240024020020d00410121050c010b200210272205450d03200520032802382209200210dc041a2003200820026b36023c2003200920026a3602380b2005450d052002ad220e422086200e84210e200341106a200341386a106e20032802100d04200328023c22022003280214220b490d04200b417f4c0d0102400240200b0d00410121070c010b200b10272207450d04200720032802382208200b10dc041a20032002200b6b36023c20032008200b6a3602380b2007450d0441022102200341c4006a41026a200341e8006a41026a2d00003a0000200320032f00683b0144200b21090b200341e8006a41026a200341c4006a41026a2d0000220c3a0000200320032f014422113b016820002006360200200020113b0005200041076a200c3a0000200041306a20083600002000412c6a2008360000200041286a200d360000200041206a200f3700002000411c6a2009360000200041186a200b360000200041146a20073600002000410c6a200e370000200041086a20053600000c050b102f000b200241011030000b200b41011030000b200ea7450d00200510230b20034100360260200342013703582003410c36024c2003200341206a3602482003200341d8006a360240200341fc006a41013602002003420137026c20034198c2c3003602682003200341c8006a360278200341c0006a41b8a3c500200341e8006a102e1a200335026042208620033502588410080240200328025c450d00200328025810230b410321020b200020023a00042004450d00200110230b20034190016a24000b830301047f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022010d00200041003602080c010b200328021421042003200341186a2802002202360224200320013602200240024020024104490d002003200141046a36022020032002417c6a220536022420054104490d00200128000021052003200241786a3602242003200141086a36022020012800042102200341c8006a200341206a107b20032802482206450d002000200329024c37020c2000200636020820002002360204200020053602000c010b20034100360230200342013703282003410c36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034198c2c3003602482003200341386a360258200341c4006a41b8a3c500200341c8006a102e1a2003350230422086200335022884100820004100360208200328022c450d00200328022810230b2004450d00200110230b200341e0006a24000be40301057f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad8410041090010240024002400240200328021022010d00200041003602000c010b200328021421022003200341186a280200360224200320013602202003200341206a106e0240024020032802000d002003280224220420032802042205490d002005417f4c0d030240024020050d0041012106200328022421040c010b200510272206450d05200620032802202207200510dc041a2003200420056b22043602242003200720056a3602200b024020044110490d002000200536020420002006360200200041106a20032802202206290000370300200041086a2005360200200041186a200641086a2900003703002003200441706a3602242003200641106a3602200c020b2005450d00200610230b20034100360230200342013703282003410c36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034198c2c3003602482003200341386a360258200341c4006a41b8a3c500200341c8006a102e1a2003350230422086200335022884100820004100360200200328022c450d00200328022810230b2002450d00200110230b200341e0006a24000f0b102f000b200541011030000beb0808047f047e057f027e017f017e017f017e230041f0016b220324002003200236026420032001360260200341e8006a2002ad4220862001ad84100410900102400240200328026822040d00200041003602200c010b200328026c21052003200341f0006a280200220636029c01200320043602980141002101200341003a00e801024002400340024020062001470d002003410036029c01200141ff0171450d02200341003a00e8010c020b200341c8016a20016a200420016a22022d00003a00002003200241016a360298012003200141016a22023a00e8012002210120024120470d000b200341a8016a41086a200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200341a8016a41186a200341c8016a41186a290300370300200320032903c8013703a8012003200620026b36029c01200341c8006a20034198016a10eb022003290348a70d00200341c8006a41106a290300210720032903502108200341306a20034198016a10eb022003290330a70d00200341306a41106a29030021092003290338210a200341286a20034198016a106e20032802280d000240024002400240200328029c0141186e220b41186c2201417f4c0d00200328022c210c0240024020010d004108210d0c010b20011021220d450d020b0240200c450d00200341106a41106a210e4100210f41002106410021020340200341106a20034198016a10eb02024002402003290310a70d00200e290300211020032903182111200341086a20034198016a106e2003280208450d010b200b450d07200d10230c070b200241016a2101200328020c211202402002200b470d00200f2001200f20014b1b220bad42187e2213422088a70d062013a722144100480d060240024020020d0020141021210d0c010b200d200620141025210d0b200d450d050b200d20066a2202201037030820022011370300200241106a2012360200200f41026a210f200641186a210620012102200c2001470d000b0b200d450d04200341f8006a41186a200341a8016a41186a2903002210370300200341f8006a41106a200341a8016a41106a2903002211370300200341f8006a41086a200341a8016a41086a2903002213370300200320032903a8012215370378200041186a20093703002000200a37031020002007370308200020083703002000200cad422086200bad843702242000200d3602202000412c6a2015370200200041346a20133702002000413c6a2011370200200041c4006a20103702000c050b102f000b200141081030000b201441081030000b102a000b200341003602b001200342013703a8012003410c36027c2003200341e0006a3602782003200341a8016a3602a401200341dc016a4101360200200342013702cc0120034198c2c3003602c8012003200341f8006a3602d801200341a4016a41b8a3c500200341c8016a102e1a20033502b00142208620033502a8018410082000410036022020032802ac01450d0020032802a80110230b2005450d00200410230b200341f0016a24000bd90201047f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100410900102400240200228021022010d00200041003602040c010b200228021421032002200241186a2802002204360224200220013602200240024020044104490d0020022004417c6a3602242002200141046a36022020012800002104200241c8006a200241206a107b20022802482205450d002000200229024c37020820002005360204200020043602000c010b20024100360230200242013703282002410c36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c20024198c2c3003602482002200241386a360258200241c4006a41b8a3c500200241c8006a102e1a2002350230422086200235022884100820004100360204200228022c450d00200228022810230b2003450d00200110230b200241e0006a24000be005010d7f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100410900102400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a106e024002400240024020022802000d00024002400240200228022422054178712201417f4c0d002002280204210602400240200541037622070d00410421080c010b200110212208450d020b02402006450d00410021094100210a4100210b03402002410036022802400240024020054104490d0020022005417c6a220536022420022002280220220141046a3602202001280000210c2002410036022820054104490d00200b41016a210d20022005417c6a22053602242002200141086a36022020012800042101200b2007470d0202402009200d2009200d4b1b220741ffffffff01712007470d002007410374220e41004e0d020b102a000b200241003602482007450d08200810230c080b02400240200b0d00200e102121080c010b2008200a200e102521080b2008450d050b2008200a6a220b200c360200200b41046a2001360200200941026a2109200a41086a210a200d210b2006200d470d000b200241d0006a20063602002002200736024c200220083602480c060b200241d0006a20063602002002200736024c2002200836024820080d050c040b102f000b200141041030000b200e41041030000b200241003602480b20024100360230200242013703282002410c36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c20024198c2c3003602482002200241386a360258200241c4006a41b8a3c500200241c8006a102e1a2002350230422086200235022884100820004100360200200228022c450d01200228022810230c010b20002002290348370200200041086a200241c8006a41086a2802003602000b2004450d00200310230b200241e0006a24000bbf05020a7f027e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100410900102400240200328021022040d00200041003602000c010b200328021421052003200341186a280200360224200320043602202003200341206a106e024002400240024020032802000d00024002400240200328022422064170712201417f4c0d002003280204210702400240200641047622080d00410821090c010b200110212209450d020b02402007450d004100210a410021024100210b034002400240024020064110490d00200b41016a210120032003280220220c41106a360220200c41086a290000210d200c290000210e200b2008470d020240200a2001200a20014b1b220841ffffffff00712008470d002008410474220b41004e0d020b102a000b20034100360248200320063602242008450d08200910230c080b0240024020020d00200b102121090c010b20092002200b102521090b2009450d050b200641706a2106200920026a220b200d370308200b200e370300200a41026a210a200241106a21022001210b20072001470d000b200341d0006a20073602002003200836024c20032009360248200320063602240c060b200341d0006a20073602002003200836024c2003200936024820090d050c040b102f000b200141081030000b200b41081030000b200341003602480b20034100360230200342013703282003410c36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034198c2c3003602482003200341386a360258200341c4006a41b8a3c500200341c8006a102e1a2003350230422086200335022884100820004100360200200328022c450d01200328022810230c010b20002003290348370200200041086a200341c8006a41086a2802003602000b2005450d00200410230b200341e0006a24000bf90301027f20002d00002102024002400240024002400240410110212203450d00200320023a000020002d0001210220034101410210252203450d01200320023a000120002d0002210220034102410410252203450d02200320023a0002200320002d00033a000320002d0004210220034104410810252203450d03200320023a0004200320002d00053a0005200320002d00063a0006200320002d00073a000720002d0008210220034108411010252203450d04200320023a0008200320002d00093a0009200320002d000a3a000a200320002d000b3a000b200320002d000c3a000c200320002d000d3a000d200320002d000e3a000e200320002d000f3a000f20002d0010210220034110412010252203450d05200320023a0010200320002d00113a0011200320002d00123a0012200320002d00133a0013200320002d00143a0014200320002d00153a0015200320002d00163a0016200320002d00173a0017200320002d00183a0018200320002d00193a0019200320002d001a3a001a200320002d001b3a001b200320002d001c3a001c200320002d001d3a001d200320002d001e3a001e200320002d001f3a001f20012902002003ad42808080808004841002200310230f0b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000be70203017f017e017f23004190036b22032400200320023602b401200320013602b001200341b8016a2002ad4220862001ad84220410041090010240024020032802b80122010d00411a21010c010b20032802bc0121052003200341c0016a2802003602fc02200320013602f802200341c8016a200341f8026a10d9010240024020032802c8012202411a460d002003200341c8016a41047241ac0110dc041a0c010b20034100360208200342013703002003410c360284032003200341b0016a360280032003200336028c03200341dc016a4101360200200342013702cc0120034198c2c3003602c801200320034180036a3602d8012003418c036a41b8a3c500200341c8016a102e1a200335020842208620033502008410082003280204450d00200328020010230b02402005450d00200110230b411a21012002411a460d0020041005200221010b20002001360200200041046a200341ac0110dc041a20034190036a24000b881f03037f017e197f23004190016b220224000240024020012d00004101460d00200041003b0001200041013a0000200041036a41003a00000c010b200241106a200141016a10b403200241206a200141216a20022802102203200228021810b5030240024020022d00200d00200041800e3b0001200041013a0000200041036a41003a00000c010b200241386a41106a200241316a280000360200200241386a41086a200241296a29000037030020022002290021370338200241f0006a41086a220441fcfcc400ad4280808080e0008422051003220141086a2900003703002002200129000037037020011023200241d0006a41086a2206200429030037030020022002290370370350200420051003220141086a2900003703002002200129000037037020011023200241e0006a41086a2207200429030037030020022002290370370360200241f0006a200241386a10b603024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024041c00010212201450d00200120022903503700002001200229036037001020012002290070370020200141086a2006290300370000200141186a2007290300370000200141286a2004290000370000200141306a200241f0006a41106a290000370000200141386a200241f0006a41186a290000370000200241086a200141c00041014100410010b8012002280208210420011023024020044101470d00410c10212207450d0220022d0038210820022d0039210920022d003a210a20022d003b210b20022d003c210c20022d003d210d20022d003e210e20022d003f210f20022d0040211020022d0041211120022d0042211220022d0043211320022d0044211420022d0045211520022d0046211620022d0047211720022d0048211820022d0049211920022d004a211a20022d004b211b410a10212201450d032002420a370274200220013602704106200241f0006a105c0240024020022802742201200228027822066b4106490d00200228027021040c010b200641066a22042006490d1a2001410174221c2004201c20044b1b221c4100480d1a0240024020010d00201c102121040c010b20022802702001201c102521040b2004450d052002201c36027420022004360270201c21010b2002200641066a221c360278200420066a221d41046a41002f00c0e1433b0000201d41002800bce14336000002402001201c470d00200141016a221d2001490d1a2001410174221e201d201e201d4b1b221d4100480d1a0240024020010d00201d102121040c010b20042001201d102521040b2004450d062002201d360274200220043602700b2002200641076a3602782004201c6a20083a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d0720022006360274200220043602700b2002200141016a360278200420016a20093a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d0820022006360274200220043602700b2002200141016a360278200420016a200a3a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d0920022006360274200220043602700b2002200141016a360278200420016a200b3a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d0a20022006360274200220043602700b2002200141016a360278200420016a200c3a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d0b20022006360274200220043602700b2002200141016a360278200420016a200d3a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d0c20022006360274200220043602700b2002200141016a360278200420016a200e3a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d0d20022006360274200220043602700b2002200141016a360278200420016a200f3a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d0e20022006360274200220043602700b2002200141016a360278200420016a20103a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d0f20022006360274200220043602700b2002200141016a360278200420016a20113a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d1020022006360274200220043602700b2002200141016a360278200420016a20123a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d1120022006360274200220043602700b2002200141016a360278200420016a20133a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d1220022006360274200220043602700b2002200141016a360278200420016a20143a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d1320022006360274200220043602700b2002200141016a360278200420016a20153a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d1420022006360274200220043602700b2002200141016a360278200420016a20163a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d1520022006360274200220043602700b2002200141016a360278200420016a20173a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d1620022006360274200220043602700b2002200141016a360278200420016a20183a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d1720022006360274200220043602700b2002200141016a360278200420016a20193a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d1820022006360274200220043602700b2002200141016a360278200420016a201a3a000002400240200228027420022802782201460d00200228027021040c010b200141016a22042001490d1a200141017422062004200620044b1b22064100480d1a0240024020010d002006102121040c010b200228027020012006102521040b2004450d1920022006360274200220043602700b2002200141016a360278200420016a201b3a0000200241e0006a41086a20022802782201360200200220022903702205370360200741086a200136020020072005370200200041306a41013a0000200041286a428180808010370200200041246a2007360200200041206a4100360200200041186a4204370300200041106a427f370300200041086a42e400370300200041316a2002280070360000200041346a200241f3006a280000360000200041003a00002002280214450d1b200310230c1b0b200041800e3b0001200041013a0000200041036a41013a00000c190b41c00041011030000b410c41041030000b410a41011030000b201c41011030000b201d41011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b200641011030000b102a000b2002280214450d00200310230b20024190016a24000bbe0601077f20012d000021020240410110212203450d00200320023a000020012d00012102024020034101410210252203450d00200320023a000120012d00022102024020034102410410252203450d00200320023a0002200320012d00033a000320012d00042102024020034104410810252203450d00200320023a0004200320012d00053a0005200320012d00063a0006200320012d00073a000720012d00082102024020034108411010252203450d00200320023a0008200320012d00093a0009200320012d000a3a000a200320012d000b3a000b200320012d000c3a000c200320012d000d3a000d200320012d000e3a000e200320012d000f3a000f20012d00102102024020034110412010252204450d00200420023a0010200420012d00113a0011200420012d00123a0012200420012d00133a0013200420012d00143a0014200420012d00153a0015200420012d00163a0016200420012d00173a0017200420012d00183a0018200420012d00193a0019200420012d001a3a001a200420012d001b3a001b200420012d001c3a001c200420012d001d3a001d200420012d001e3a001e200420012d001f3a001f024041c00010212205450d00200421064100210241c0002103034020062d00002107024002400240024020022003460d00200321010c010b200341016a22012003490d01200341017422082001200820014b1b22014100480d010240024020030d002001102121050c010b200520032001102521050b20050d00200141011030000b200520026a413041d700200741a001491b20074104766a3a00000240200241016a22082001460d00200121030c020b200141016a22032001490d00200141017422082003200820034b1b22034100480d000240024020010d002003102121050c010b200520012003102521050b02402005450d00200121080c020b200341011030000b102a000b200520086a413041d7002007410f712201410a491b20016a3a0000200641016a2106200241026a220241c000470d000b200020023602082000200336020420002005360200200410230f0b41c00041011030000b412041011030000b411041011030000b410841011030000b410441011030000b410241011030000b410141011030000be50c02097f027e230041a0026b22042400024002400240024002400240024002400240024002402003411f6a22050d004101210641002107410021080c010b41002107410021084101210603402005410a6e2109024020072008470d00200841016a220a2008490d032008410174220b200a200b200a4b1b220a4100480d030240024020080d00200a102121060c010b20062008200a102521060b2006450d07200a21080b200620076a2005200941766c6a4130723a0000200741016a2107200541094b210a20092105200a0d000b0b411a210b411a1021220a450d05200a41186a41002f00dae1433b0000200a41106a41002900d2e143370000200a41086a41002900cae143370000200a41002900c2e1433700000240024020070d00411a21070c010b2007411a6a22052007490d0120054134200541344b1b220b4100480d01200a411a200b1025220a450d07200620076a210c2006417f6a2109200a411a6a210503402005200920076a2d00003a0000200541016a21052007417f6a22070d000b200c20066b411a6a21070b02402008450d00200610230b0240200b20076b411e4b0d002007411f6a22052007490d01200b41017422082005200820054b1b22054100480d01200a200b20051025220a450d022005210b0b200a20076a220541002900b0d344370000200541176a41002900c7d344370000200541106a41002900c0d344370000200541086a41002900b8d344370000200b2007411f6a22076b20034f0d03200720036a22052007490d00200b41017422082005200820054b1b220541004e0d020b102a000b200541011030000b02400240200b0d0020051021210a0c010b200a200b20051025210a0b200a450d042005210b0b200a20076a2002200310dc041a200441d8016a41186a2205200720036aad422086200aad84100b220741186a290000370300200441d8016a41106a2208200741106a290000370300200441d8016a41086a2209200741086a290000370300200420072900003703d80120071023200441186a2005290300370300200441106a2008290300370300200441086a2009290300370300200420042903d8013703000240200b450d00200a10230b41002107200441206a41106a4100360200200441206a41086a420037030020044200370320200441d8016a2001200410b703024020042d00d8014101460d00200441d0016a20044191026a290000370300200441c8016a20044189026a290000370300200441c0016a20044181026a290000370300200441b8016a200441f9016a290000370300200441b0016a200441f1016a29000037030020044198016a41106a200441e9016a29000037030020044198016a41086a200441e1016a290000370300200420042900d90137039801410121070b200441d8016a41386a220820044198016a41386a290300370300200441d8016a41306a220920044198016a41306a290300370300200441d8016a41286a220620044198016a41286a290300370300200441d8016a41206a220a20044198016a41206a290300370300200441d8016a41186a220520044198016a41186a290300370300200441d8016a41106a20044198016a41106a290300370300200441d8016a41086a20044198016a41086a29030037030020042004290398013703d801024020070d00410021070c050b200441d8006a41386a2008290300370300200441d8006a41306a2009290300370300200441d8006a41286a2006290300370300200441d8006a41206a200a290300370300200441d8006a41186a2005290300370300200441d8006a41106a200441d8016a41106a2208290300370300200441d8006a41086a200441d8016a41086a2209290300370300200420042903d8013703582005200441d8006aad4280808080800884100b220741186a2900003703002008200741106a2900003703002009200741086a290000370300200420072900003703d80120071023200441386a41186a2005290300370300200441386a41106a2008290300370300200441386a41086a2009290300370300200441206a41106a200441d4006a2802002207360200200441206a41086a200441cc006a290200220d370300200420042903d80137033820042004290244220e370320200041116a2007360000200041096a200d3700002000200e370001410121070c040b200a41011030000b411a41011030000b200b41011030000b200541011030000b200020073a0000200441a0026a24000bc50301057f230041206b2202240020012d00002103024002400240024002400240410110212204450d00200420033a000020012d0001210320044101410210252204450d01200420033a000120012d0002210320044102410410252204450d02200420033a0002200420012d00033a000320012d0004210320044104410810252204450d03200420033a0004200420012d00053a0005200420012f00063b000620012d0008210320044108411010252204450d04200420033a0008200420012d00093a0009200420012f000a3b000a2004200128000c36000c20012d0010210320044110412010252204450d05200420033a0010200420012d00113a0011200420012f00123b0012200241186a22032004ad4280808080c002841001220141186a290000370300200241106a2205200141106a290000370300200241086a2206200141086a2900003703002002200129000037030020011023200041186a2003290300370000200041106a2005290300370000200041086a20062903003700002000200229030037000020041023200241206a24000f0b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000ba30503017f017e027f23004190016b22032400024020012002101e2204422088a72201450d002004a722022d0000220541014b0d002001417f6a210602400240024020050e020001000b41002101200341003a008801200241016a21050340024020062001470d00200141ff0171450d04200341003a0088010c040b200341c8006a20016a200520016a2d00003a00002003200141016a22023a00880120022101200241c000470d000b200341106a200341d1006a290000370300200341186a200341d9006a290000370300200341206a200341e1006a290000370300200341286a200341e9006a290000370300200341306a200341f1006a290000370300200341386a200341f9006a2900003703002003413f6a20034180016a2900003700002003200329004937030820032d00482101410021020c010b2006450d0120022d0001220141034f0d01200341086a41376a200341c8006a41376a290000370000200341086a41306a200341c8006a41306a290000370300200341086a41286a200341c8006a41286a290000370300200341086a41206a200341c8006a41206a290000370300200341086a41186a200341c8006a41186a290000370300200341086a41106a200341c8006a41106a290000370300200341086a41086a200341c8006a41086a29000037030020032003290048370308410121020b200020013a0001200020023a0000200041026a20032903083700002000410a6a200341106a290300370000200041126a200341186a2903003700002000411a6a200341206a290300370000200041226a200341286a2903003700002000412a6a200341306a290300370000200041326a200341386a290300370000200041396a2003413f6a29000037000020034190016a24000f0b41f4b7c600412e200341c8006a41a4b8c6001031000b831703077f027e057f230041206b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024041ca0210212203450d00200241ca0236020420022003360200200341003b00002002410236020802400240200128020022042903684202520d00024020022802044102470d0020022802004102410410252203450d0420024104360204200220033602000b200228020041043a00022002200228020841016a3602080c010b024020022802044102470d0020022802004102410410252203450d0420024104360204200220033602000b20022802004184013a00022002200228020841016a3602082004200210d902024020042d0024220341024b0d0002400240024020030e03000102000b02400240200228020420022802082203460d00200228020021010c010b200341016a22012003490d19200341017422052001200520014b1b22054100480d190240024020030d002005102121010c010b200228020020032005102521010b2001450d082002200536020420022001360200200228020821030b2002200341016a360208200120036a41003a0000200441256a2106410021010340200620016a2d0000210702400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d1a200341017422082005200820054b1b22084100480d1a0240024020030d002008102121050c010b200228020020032008102521050b2005450d0a2002200836020420022005360200200228020821030b2002200341016a360208200520036a20073a0000200141016a220141c000470d000c030b0b02400240200228020420022802082203460d00200228020021010c010b200341016a22012003490d18200341017422052001200520014b1b22054100480d180240024020030d002005102121010c010b200228020020032005102521010b2001450d092002200536020420022001360200200228020821030b2002200341016a360208200120036a41013a0000200441256a2106410021010340200620016a2d0000210702400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d19200341017422082005200820054b1b22084100480d190240024020030d002008102121050c010b200228020020032008102521050b2005450d0b2002200836020420022005360200200228020821030b2002200341016a360208200520036a20073a0000200141016a220141c000470d000c020b0b02400240200228020420022802082203460d00200228020021010c010b200341016a22012003490d17200341017422052001200520014b1b22054100480d170240024020030d002005102121010c010b200228020020032005102521010b2001450d0a2002200536020420022001360200200228020821030b2002200341016a360208200120036a41023a0000412521010340200420016a2d0000210702400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d18200341017422082005200820054b1b22084100480d180240024020030d002008102121050c010b200228020020032008102521050b2005450d0c2002200836020420022005360200200228020821030b2002200341016a360208200520036a20073a0000200141016a220141e600470d000b0b0240024020042903684201510d0002400240200228020420022802082203460d00200228020021010c010b200341016a22012003490d18200341017422052001200520014b1b22054100480d180240024020030d002005102121010c010b200228020020032005102521010b2001450d0d2002200536020420022001360200200228020821030b2002200341016a360208200120036a41003a00000c010b200441f8006a29030020042903702209420c88220a4201200a4201561b80210a0240024020022802042201200228020822036b4102490d00200228020021010c010b200341026a22052003490d17200141017422032005200320054b1b22034100480d170240024020010d002003102121010c010b200228020020012003102521010b2001450d0d2002200336020420022001360200200228020821030b2002200341026a360208200120036a200aa741047420097aa7417f6a22034101200341014b1b2203410f2003410f491b723b00000b20044190016a200210af01200220044180016a360210200241106a200210c3010b20044198016a200210cb012002280208210320024100360218200242013703102003417e6a200241106a105c2002280208220141014d0d0b200228021821042002280214210b200228021021072002410036020820022802002103024002402001417e6a2208450d00410221062004450d13200320072d00003a00004101210c2002200228020841016a36020820044101460d13200720046a210d200320072d00013a00012002200228020841016a36020841022106200741026a21052004417e6a220e0d014100210e0c110b0240024002402002280204220120044f0d00200141017422052004200520044b1b22054100480d180240024020010d002005102121030c010b200320012005102521030b2003450d102002200536020420022003360200200228020821060c010b410021062004450d010b200320066a220120072d00003a0000024020044101470d00200641016a21060c010b2004417f6a2105200741016a2103200141016a21010340200120032d00003a0000200141016a2101200341016a21032005417f6a22050d000b200620046a21060b20022006360208410221060c110b024002402002280204220320016b200e490d00200228020021030c010b2001200e6a22062001490d15200341017422012006200120064b1b22014100480d150240024020030d002001102121030c010b200228020020032001102521030b2003450d0e20022001360204200220033602000b200320046a200341026a200810dd041a0240200420022802082203460d00200420036b21062004417e6a2101200228020020036a210c410021030340024020012003470d00200421060c130b200c20036a20052d00003a00002002200228020841016a360208200541016a21052006200341016a2203470d000b200d20056b220e0d004100210e4101210c0c0f0b200e4100480d14200e1021220c0d0e200e41011030000b41ca0241011030000b410441011030000b410441011030000b200541011030000b200841011030000b200541011030000b200841011030000b200541011030000b200841011030000b200541011030000b200341011030000b41ccbac000102b000b200541011030000b200141011030000b200421060b0240200d2005460d00200c20052d00003a00004101210f02400240200541016a2203200d470d00200c41016a21040c010b200c41016a21012007200420056b6a21050340200120032d00003a0000200141016a2101200d200341016a2203470d000b2005450d01200c20056a21042005210f0b0240024020022802042203200820066a22016b200f490d00200228020021030c010b2001200f6a22052001490d06200341017422012005200120054b1b22014100480d060240024020030d002001102121030c010b200228020020032001102521030b2003450d0520022001360204200220033602000b20032006200f6a220d6a200320066a200810dd041a0240200d20022802082203460d00200228020020036a21012006200f6a20036b2105200c2103034020042003460d01200120032d00003a00002002200228020841016a360208200341016a2103200141016a21012005417f6a22050d000b0b200d21060b200e450d00200c10230b2008450d010b0240200620022802082203460d002002280200220120036a200120066a200810dd041a0b2002200820036a3602080b0240200b450d00200710230b20002002290300370200200041086a200241086a280200360200200241206a24000f0b200141011030000b102a000b3400200041cefbc40036020420004100360200200041146a4102360200200041106a41a8e2c300360200200041086a42073702000bfb0101077f230041106b220124002001410036020820014201370300200110ba0320012802042102200128020021030240024002400240200041046a2802002204200041086a28020022056b20012802082206490d00200028020021040c010b200520066a22072005490d02200441017422052007200520074b1b22054100480d020240024020040d002005102121040c010b200028020020042005102521040b2004450d0120002004360200200041046a2005360200200041086a28020021050b200041086a200520066a360200200420056a2003200610dc041a02402002450d00200310230b200141106a24000f0b200541011030000b102a000bd90401037f20012d000021020240024002400240024002400240410110212203450d00200320023a000020012d0001210220034101410210252203450d01200320023a000120012d0002210220034102410410252203450d02200320023a0002200320012d00033a000320012d0004210220034104410810252203450d03200320023a0004200320012d00053a0005200320012d00063a0006200320012d00073a000720012d0008210220034108411010252203450d04200320023a0008200320012d00093a0009200320012d000a3a000a200320012d000b3a000b200320012d000c3a000c200320012d000d3a000d200320012d000e3a000e200320012d000f3a000f20012d0010210220034110412010252203450d05200320023a0010200320012d00113a0011200320012d00123a0012200320012d00133a0013200320012d00143a0014200320012d00153a0015200320012d00163a0016200320012d00173a0017200320012d00183a0018200320012d00193a0019200320012d001a3a001a200320012d001b3a001b200320012d001c3a001c200320012d001d3a001d200320012d001e3a001e200320012d001f3a001f0240200341cde4c300460d00200328000041f0c2c98b06470d070b200328000421044108210102400240034020014120460d01200320016a2102200141016a210120022d0000450d000b410021010c010b20002004360204410121010b20002001360200200310230f0b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000b20004100360200200310230bbb0401037f230041106b2202240020012d00002103024002400240024002400240410110212204450d00200420033a000020012d0001210320044101410210252204450d01200420033a000120012d0002210320044102410410252204450d02200420033a0002200420012d00033a000320012d0004210320044104410810252204450d03200420033a0004200420012d00053a0005200420012d00063a0006200420012d00073a000720012d0008210320044108411010252204450d04200420033a0008200420012d00093a0009200420012d000a3a000a200420012d000b3a000b200420012d000c3a000c200420012d000d3a000d200420012d000e3a000e200420012d000f3a000f20012d0010210320044110412010252204450d05200420033a0010200420012d00113a0011200420012d00123a0012200420012d00133a0013200420012d00143a0014200420012d00153a0015200420012d00163a0016200420012d00173a0017200420012d00183a0018200420012d00193a0019200420012d001a3a001a200420012d001b3a001b200420012d001c3a001c200420012d001d3a001d200420012d001e3a001e200420012d001f3a001f200241086a22032004ad42808080808004841003220141086a2900003703002002200129000037030020011023200041086a20032903003700002000200229030037000020041023200241106a24000f0b410141011030000b410241011030000b410441011030000b410841011030000b411041011030000b412041011030000bb80303017f017e027f230041d0006b22032400024020012002101f2204422088a72201450d002004a722022d0000220541014b0d002001417f6a210602400240024020050e020001000b41002101200341003a0049200241016a21050340024020062001470d00200141ff0171450d04200341003a00490c040b200341286a20016a200520016a2d00003a00002003200141016a22023a00492002210120024121470d000b200341106a200341316a290000370300200341186a200341396a290000370300200341206a200341c1006a2900003703002003200329002937030820032d00282101410021020c010b2006450d0120022d0001220141034f0d01200341086a41186a200341286a41186a290000370300200341086a41106a200341286a41106a290000370300200341086a41086a200341286a41086a29000037030020032003290028370308410121020b200020013a0001200020023a0000200041026a20032903083700002000410a6a200341106a290300370000200041126a200341186a2903003700002000411a6a200341206a290300370000200341d0006a24000f0b41f4b7c600412e200341286a41a4b8c6001031000b4d01017f230041206b22002400200041146a410136020020004201370204200041d09dc6003602002000410436021c200041849ec6003602182000200041186a360210200041b8c5c3001038000b4d01017f230041206b22002400200041146a410136020020004201370204200041d09dc6003602002000410436021c200041849ec6003602182000200041186a360210200041d4c6c3001038000bfc1a01047f20002d0000210202400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0001210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0002210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0003210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0004210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0005210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0006210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0007210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0008210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0009210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000a210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000b210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000c210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000d210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000e210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d0f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d000f210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d1020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0010210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d1120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0011210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d1220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0012210202400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d15200341017422052004200520044b1b22054100480d150240024020030d002005102121040c010b200128020020032005102521040b2004450d1320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20023a000020002d0013210402400240200141046a28020020052802002200460d00200128020021030c010b200041016a22032000490d15200041017422022003200220034b1b22024100480d150240024020000d002002102121030c010b200128020020002002102521030b2003450d1420012003360200200141046a2002360200200141086a28020021000b200141086a200041016a360200200320006a20043a00000f0b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200241011030000b102a000b3400200041fcfcc40036020420004100360200200041146a4102360200200041106a41d4e4c300360200200041086a42063702000b3701017f02404110102122020d00411041011030000b2002420037000820024200370000200042908080808002370204200020023602000b130020004102360204200041fce7c3003602000b130020004101360204200041a8eac3003602000ba60201057f230041106b22022400024002400240412310212203450d002002422337020420022003360200411f2002105c0240024020022802042204200228020822036b411f490d002003411f6a2105200228020021040c010b2003411f6a22052003490d03200441017422062005200620054b1b22064100480d030240024020040d002006102121040c010b200228020020042006102521040b2004450d0220022006360204200220043602000b20022005360208200420036a220341002900b0d344370000200341106a41002900c0d344370000200341176a41002900c7d344370000200341086a41002900b8d34437000020002002290300370200200041086a2002280208360200200241106a24000f0b412341011030000b200641011030000b102a000b89d5010c067f017e067f027e097f067e0d7f017e057f047e097f067e230022012102200141c01a6b41607122012400200141a80d6a41186a4200370300200141a80d6a41106a22034200370300200141a80d6a41086a22044200370300200142003703a80d200141f0166a41086a2205418cfdc400ad4280808080d000841003220641086a290000370300200120062900003703f0162006102320042005290300370300200120012903f01622073703f808200120073703a80d200541d8fdc300ad4280808080b001841003220641086a290000370300200120062900003703f01620061023200320012903f0162207370300200141c80d6a41086a2004290300370300200141c80d6a41106a2007370300200141c80d6a41186a2005290300370300200120073703f811200120012903a80d3703c80d200141c8046a200141c80d6a4120108602200041a08d066e210802400240024002400240024020012802c8044101470d0020012902cc042207422088a741e8076a2000470d00200141c80d6a4101410010ff0120012802c80d2106200141f0166a41086a2205418cfdc400ad4280808080d000841003220441086a290000370300200120042900003703f01620041023200141a8166a41086a22092005290300370300200120012903f0163703a816200541e3fdc300ad4280808080f000841003220441086a290000370300200120042900003703f01620041023200141b8166a41086a22042005290300370300200120012903f0163703b8162001200641e807703602f81120014180176a41186a2206200141f8116aad4280808080c000841001220541186a29000037030020014180176a41106a220a200541106a29000037030020014180176a41086a220b200541086a290000370300200120052900003703801720051023200141f8086a41186a220c2006290300370300200141f8086a41106a2206200a290300370300200141f8086a41086a220a200b29030037030020012001290380173703f8080240024041c00010212205450d00200520012903a816370000200541086a2009290300370000200520012903b816370010200541186a2004290300370000200520012903f808370020200541286a200a290300370000200541306a2006290300370000200541386a200c290300370000200141c80d6a200541c00010a60320012802c80d2104200141f8116a200141c80d6a41047241ac0410dc041a0240024020044103460d00200141f8086a200141f8116a41ac0410dc041a20051023200120043602c804200141c8046a410472200141f8086a41ac0410dc041a0c010b20051023200141023602c0082001410236028808200141023602d0072001410236029807200141023602e006200141023602a806200141023602f005200141023602b8052001410236028005200141023602c8040b2007a7210d200141c80d6aad220e4280808080c00084210741002104418cfdc400ad4280808080d00084210f02400340200141f0166a41086a2205200f1003220641086a290000370300200120062900003703f01620061023200141f8086a41086a22092005290300370300200120012903f0163703f808200541e3fdc300ad4280808080f000841003220641086a290000370300200120062900003703f01620061023200141f8116a41086a22062005290300370300200120012903f0163703f811200120043602c80d20014180176a41186a220a20071001220541186a29000037030020014180176a41106a220b200541106a29000037030020014180176a41086a220c200541086a290000370300200120052900003703801720051023200141a80d6a41186a2210200a290300370300200141a80d6a41106a220a200b290300370300200141a80d6a41086a220b200c29030037030020012001290380173703a80d41c00010212205450d01200520012903f808370000200520012903f811370010200520012903a80d370020200541086a2009290300370000200541186a2006290300370000200541286a200b290300370000200541306a200a290300370000200541386a20102903003700002005ad4280808080800884100520051023200441016a220441e807470d000b200141a80d6a41186a22094200370300200141a80d6a41106a220a4200370300200141a80d6a41086a22044200370300200142003703a80d200141f0166a41086a2205418cfdc400ad4280808080d000841003220641086a290000370300200120062900003703f0162006102320042005290300370300200120012903f01622073703f808200120073703a80d200541d8fdc300ad4280808080b001841003220641086a290000370300200120062900003703f01620061023200141f8116a41086a20052903002207370300200120012903f016220f3703f8112003200f370000200341086a2007370000200141c80d6a41086a2004290300370300200141c80d6a41106a200a290300370300200141c80d6a41186a2009290300370300200120012903a80d3703c80d200e4280808080800484100520012802c8042105200141f8116a200141c8046a41047241ac0410dc041a20054103460d03200120053602c80d200141c80d6a410472200141f8116a41ac0410dc041a200141f8116a2109200141c80d6a2105200141b0046a41106a210a0240024002400240024002400240034002400240024020092005460d0020052802002104200541386a2206210520044102460d03200141c8046a200641486a220b10c703200141b0046a20012802c804220520012802d0042204108902200a290300210f20012903b804210e024020012903b00422074201520d002004ad4220862005ad8410050b2007a72104024020012802cc04450d00200510230b2006210520044101470d03200b2802004101460d01200141c8046a41186a200641506a220541186a290000370300200141c8046a41106a200541106a290000370300200141c8046a41086a200541086a290000370300200120052900003703c8040c020b200141c8046a200141c80d6a41b00410dc041a200141f0096a4200370300200141e8096a4200370300200141d0096a4200370300200141c8096a4200370300200141f8086a41386a4200370300200141f8086a41306a4200370300200141f8086a41186a4200370300200141e0096a4100360200200141c0096a4100360200200141f8086a41286a41003602002001420037038809200142013703d809200142013703b80920014201370398092001410036028009200142013703f8084100210403400240200141c8046a200441386c6a22052802004102460d00200541306a290300210f200541286a290300210e42012107024002400240024020044103710e0403000102030b420221070c020b420321070c010b420421070b200141a0046a20074200200e200f10e104410110212206450d0b200141a0046a41086a290300210720012903a004210f200620043a0000200141f8086a20044105746a2205410472210902402005280204450d00200528020010230b20094101360200200520063602002005200f37031020054101360208200541186a20073703000b02402004450d00200141f8086a20044105746a221141086a21122011410472210c201141106a210941002106200141f8086a21050340024020042006220a41016a22066b220b20044d0d00411b210541ddc7c30021040c160b0240200a41024d0d0041152105418ec8c30021040c160b024002400240024002400240200a0e03000102000b200b4103490d030c190b200b41014b0d184107210a200b0e020301030b4109210a200b0d170c020b4108210a0c010b200b41046a210a0b02400240200141c8046a200a41ff017141386c6a220b2802004102460d00200b41306a290300210f200b41286a290300210e4201210702400240024002400240200a410f710e0a04030001040302040304040b420321070c030b420421070c020b420321070c010b420221070b20014190046a20074200200e200f10e104200541106a290300220f2001290390047c2207200929030058200541186a29030020014190046a41086a2903007c2007200f54ad7c220f200941086a290300220e58200f200e511b0d01200541086a280200220b417f4c0d132005280200211002400240200b0d00410121130c010b200b10212213450d0e0b20132010200b10dc042114200b41016a2210200b490d15200b41017422132010201320104b1b22154100480d1502400240200b0d002015102121130c010b2014200b2015102521130b2013450d0a2013200b6a200a3a00000240200c280200450d00201128020010230b20092007370300200c201536020020112013360200201220103602002009200f3703080c010b200541106a220b290300200929030058200541186a22102903002207200941086a290300220f582007200f511b0d00200541086a280200220a417f4c0d122005280200211302400240200a0d0041012115410021140c010b200a2114200a10212215450d0c0b20152013200a10dc04211320102903002107200b290300210f0240200c280200450d00201128020010230b2009200f370300200c2014360200201120133602002012200a360200200920073703080b200541206a210520042006470d000b0b200441016a22044104470d000b20012802e009211620012802dc09211720012802d8092112024020012802fc08450d0020012802f80810230b0240200128029c09450d0020012802980910230b024020012802bc09450d0020012802b80910230b0240024020160d004100211641082118410021060c010b201641ffffff1f712016470d11201641067422054100480d11200510212218450d0520014180176aad4280808080c000842119200141f8086aad4280808080800484211a20014180176a41106a210b200141e0186a410872210941002106201821050340201220066a2d0000220a410a460d01200142013703e018200141c8046a200a41386c6a2204280200220c4102460d0841002004200c4102461b2204290310210f200420012903f0183703102004290308210e200420012903e81837030820042903002107200420012903e0183703002004290328211b20044200370328200441186a220c290300211c200c20012903f818370300200441306a220c290300211d200c42003703002001200f3703f0182001200e3703e818200120073703e0182001201c3703f8182004290320210f200141a0176a41106a2211200941106a290200370300200141a0176a41086a2215200941086a290200370300200120092902003703a017410021042007422088a72210210c02402007a70d0020014180176a41186a22134200370300200b420037030020014180176a41086a220c42003703002001420037038017200141f0166a41086a22044191fdc400ad428080808090018422071003221441086a290000370300200120142900003703f01620141023200c2004290300370300200120012903f016220e3703c8162001200e370380172004418addc100ad4280808080a00184220e1003221441086a290000370300200120142900003703f01620141023200141c8166a41086a22142004290300221c370300200120012903f016221e3703c816200b201e370000200b41086a221f201c370000200141f8086a41086a2220200c290300370300200141f8086a41106a2221200b290300370300200141f8086a41186a2222201329030037030020012001290380173703f80820014188046a200141f8086a4120108f01200128028c042123200128028804212420134200370300200b4200370300200c42003703002001420037038017200420071003222541086a290000370300200120252900003703f01620251023200c2004290300370300200120012903f01622073703c81620012007370380172004200e1003222541086a290000370300200120252900003703f01620251023201420042903002207370300200120012903f016220e3703c816200b200e370000201f20073700002020200c2903003703002021200b2903003703002022201329030037030020012001290380173703f808410121042001202341e80720241b220c41016a36028017201a2019100220142015290300370300200141c8166a41106a2011290300370300200120012903a0173703c8160b2005201d3703082005201b370300200541146a2010360200200541106a2004360200200141c8166a41106a2903002107200141c8166a41086a290300210e20012903c816211b2005413c6a200a3a0000200541186a201b370300200541206a200e370300200541286a2007370300200541386a200c360200200541306a200f3703002005413d6a20012f00f8083b00002005413f6a200141f8086a41026a2d00003a0000200541c0006a21052016200641016a2206470d000b0b02402017450d00201210230b200141a80d6a41186a22214200370300200141a80d6a41106a22224200370300200141a80d6a41086a221f4200370300200142003703a80d200141f0166a41086a2210418cfdc400ad4280808080d00084221e1003220541086a290000370300200120052900003703f01620051023201f2010290300370300200120012903f01622073703a816200120073703a80d2010419efec300ad4280808080e001841003220541086a290000370300200120052900003703f01620051023200141b8166a41086a222620102903002207370300200120012903f016220f3703b8162003200f370000200341086a22272007370000200141f8086a41086a2228201f290300370300200141f8086a41106a22292022290300370300200141f8086a41186a222a2021290300370300200120012903a80d3703f80820014180046a200141f8086a4120108f01200141d4046a20012802840441002001280280041b360200200141c8046a41086a221241023a00002001410f3a00c804201820064106746a212b200141c8046a108e0120060d03201821130c0c0b200141c8046a2006414c6a1087020b200141c8046a200e200f10de01200621050c000b0b200141c8046aad22074280808080c00084211920074280808080800284212c200141f8086aad4280808080800484211a200d20086b222d200d4b212e200141c8046a41106a2115200141e0186a4104722123200141c8046a410572212f200141c8046a41036a2130200141c8046a41186a2125200141c8046a41206a2117200141c8046a41286a21312018211303402013220541086a29030021072005290300210e200528021021042015200541246a29020037030020252005412c6a2902003703002017200541346a28020036020020122005411c6a2902003703002001200541146a2902003703c804200541c0006a211320044102460d09200141c8166a41086a2012290300220f370300200141c8166a41106a2015290300221b370300200141c8166a41186a2025290300221c370300200141c8166a41206a20172802002209360200200120012903c804221d3703c81620052d003c212420052802382106200141a0176a41206a22052009360200200141a0176a41186a2209201c370300200141a0176a41106a220a201b370300200141a0176a41086a220b200f3703002001201d3703a017200120063602bc1a0240024002400240024002400240024002400240024020040d00200141d8036a200610c8034200211b4200211c0240200e20012903d803220f7d221d200e562007200141d8036a41086a2903007d200e200f54ad7d220f200756200f2007511b0d00200141e0186a200141bc1a6a10870220014180176a200141e0186a201d200f41084101108802024020012802801722050d00202542003703002015420037030020124200370300200142003703c804201041d5fbc400ad4280808080800184221c1003220441086a290000370300200120042900003703f0162004102320122010290300370300200120012903f016221b3703a80d2001201b3703c804201041d6a0c200ad4280808080d0018422321003220441086a290000370300200120042900003703f01620041023201f2010290300221b370300200120012903f01622333703a80d20152033370000201541086a220a201b3700002028201229030037030020292015290300370300202a2025290300370300200120012903c8043703f808200141c0036a200141f8086a4120108902200141c0036a41106a290300213320012903c803213420012802c003210420014180176a41106a2903002135200129038817211b202542003703002015420037030020124200370300200142003703c8042010201c1003220941086a290000370300200120092900003703f0162009102320122010290300370300200120012903f016221c3703a80d2001201c3703c804201020321003220941086a290000370300200120092900003703f01620091023201f2010290300221c370300200120012903f01622323703a80d20152032370000200a201c3700002028201229030037030020292015290300370300202a2025290300370300200120012903c8043703f808200142002033420020041b221c20357d2034420020041b2232201b54ad7d22332032201b7d221b2032562033201c562033201c511b22041b3703d00420014200201b20041b3703c804201a202c10020b201d211b200f211c20054101460d0b0b203120073703002025201c3703002001200e3703e8042001201b3703d804200120063602d404200120243a00d104200141043a00d0042001410f3a00c804200141c8046a108e010c010b200141e0186a41206a22362005280200360200200141e0186a41186a22372009290300370300200141e0186a41106a2238200a290300370300200141e0186a41086a2239200b290300370300200120012903a0173703e01820014180176a2023200e200741084101108802024020012802801722050d00202542003703002015420037030020124200370300200142003703c804201041d5fbc400ad4280808080800184221b1003220441086a290000370300200120042900003703f0162004102320122010290300370300200120012903f016220f3703a80d2001200f3703c804201041d6a0c200ad4280808080d00184221c1003220441086a290000370300200120042900003703f01620041023201f2010290300220f370300200120012903f016221d3703a80d2015201d370000201541086a220a200f3700002028201229030037030020292015290300370300202a2025290300370300200120012903c8043703f808200141e8036a200141f8086a4120108902200141e8036a41106a290300211d20012903f003213220012802e803210420014180176a41106a2903002133200129038817210f202542003703002015420037030020124200370300200142003703c8042010201b1003220941086a290000370300200120092900003703f0162009102320122010290300370300200120012903f016221b3703a80d2001201b3703c8042010201c1003220941086a290000370300200120092900003703f01620091023201f2010290300221b370300200120012903f016221c3703a80d2015201c370000200a201b3700002028201229030037030020292015290300370300202a2025290300370300200120012903c8043703f80820014200201d420020041b221b20337d2032420020041b221c200f54ad7d221d201c200f7d220f201c56201d201b56201d201b511b22041b3703d00420014200200f20041b3703c804201a202c10020b20054101460d09202542003703002015420037030020124200370300200142003703c8042010201e1003220541086a290000370300200120052900003703f0162005102320122010290300370300200120012903f0163703c804201041acfec300ad4280808080a00184221b1003220541086a290000370300200120052900003703f01620051023201f2010290300220f370300200120012903f016221c3703a80d2015201c370000201541086a223a200f3700002028201229030037030020292015290300370300202a2025290300370300200120012903c8043703f80820014180176a200141f8086a4120108b0202400240024002400240024020012802801722140d004200210f4104211441002104410021050c010b200129028417220fa7212041002105024002400240200f422088a7220b41014b0d0041002104200b0e020201020b200b2104034020052004410176220920056a220a20062014200a4102746a280200491b2105200420096b220441014b0d000b0b2006201420054102746a2802002204460d052005200620044b6a2104200b21052004200b4b0d020b20052020470d030b2005200fa7470d02200541016a22092005490d1b2005410174220a2009200a20094b1b220941ffffffff03712009470d1b2009410274220a41004e0d010c1b0b4180bbc000102b000b0240024020050d00200a102121140c010b20142005410274200a102521140b2014450d082009ad210f0b201420044102746a220941046a2009200520046b41027410dd041a20092006360200200541016a210b200fa721200b2021420037030020224200370300201f4200370300200142003703a80d2010201e1003220541086a290000370300200120052900003703f01620051023201f2010290300370300200120012903f016220f3703a8162001200f3703a80d2010201b1003220541086a290000370300200120052900003703f0162005102320262010290300220f370300200120012903f016221b3703b8162003201b3700002027200f3700002028201f29030037030020292022290300370300202a2021290300370300200120012903a80d3703f8080240024020140d00201a10050c010b200141003602d004200142013703c804200b200141c8046a105c02400240200b0d0020012802d004210b20012802cc04210a20012802c80421040c010b200b410274210c410020012802d00422056b210620012802cc04210a2014210903402009280200211102400240200a20066a4104490d0020012802c80421040c010b200541046a22042005490d1b200a410174220b2004200b20044b1b220b4100480d1b02400240200a0d00200b102121040c010b20012802c804200a200b102521040b2004450d092001200b3602cc04200120043602c804200b210a0b200941046a21092001200541046a220b3602d004200420056a20113600002006417c6a2106200b2105200c417c6a220c0d000b0b201a200bad4220862004ad8410020240200a450d00200410230b2020450d00201410230b20012802bc1a210420012802e0182105200141c8046a41c0006a200737030020152023290000370000203a202341086a290000370000201541106a202341106a290000370000201541186a202341186a2900003700002001200e37038005200120053602d404200141033a00d004200120043602f8042001410f3a00c804200120243a00d104200141c8046a108e012010201e1003220541086a290000370300200120052900003703f01620051023200141a8166a41086a223a2010290300370300200120012903f0163703a816201041f8fec300ad4280808080c001841003220541086a290000370300200120052900003703f0162005102320262010290300370300200120012903f0163703b81620012024410873410f7141027441b8fec3006a280200200d6a223b3602c80420014180176a41186a223c20191001220541186a29000037030020014180176a41106a223d200541106a29000037030020014180176a41086a223e200541086a2900003703002001200529000037038017200510232021203c2903003703002022203d290300370300201f203e29030037030020012001290380173703a80d41c00010212214450d04201420012903a816370000201420012903b816370010201420012903a80d370020201441086a203a290300370000201441186a2026290300370000201441286a201f290300370000201441306a2022290300370000201441386a2021290300370000200141c8046a201441c000108b0202400240024020012802c80422200d0041002105410421204200210f0c010b20012902cc04220f422088a72205200fa7470d010b02402005200fa7470d00200541016a22062005490d19200541017422092006200920064b1b220641ffffffff03712006470d19200641027422094100480d190240024020050d002009102121200c010b202020054102742009102521200b2020450d05200f428080808070832006ad84210f0b200f422088a721050b2020200541027422096a20043602000240024020200d002014ad428080808080088410050c010b200141003602d004200142013703c804200541016a2205200141c8046a105c0240024020050d0020012802d004210b20012802cc04210a20012802c80421040c010b410020012802d00422056b2106202020096a41046a211120012802cc04210a2020210903402009280200210c02400240200a20066a4104490d0020012802c80421040c010b200541046a22042005490d1b200a410174220b2004200b20044b1b220b4100480d1b02400240200a0d00200b102121040c010b20012802c804200a200b102521040b2004450d062001200b3602cc04200120043602c804200b210a0b2001200541046a220b3602d004200420056a200c3600002006417c6a2106200b21052011200941046a2209470d000b0b200fa721052014ad4280808080800884200bad4220862004ad8410020240200a450d00200410230b2005450d00202010230b201410232010201e1003220541086a290000370300200120052900003703f01620051023203a2010290300370300200120012903f0163703a81620104184ffc300ad4280808080b001841003220541086a290000370300200120052900003703f0162005102320262010290300370300200120012903f0163703b816200120012802bc1a22063602c804203c20191001220541186a290000370300203d200541106a290000370300203e200541086a2900003703002001200529000037038017200510232021203c2903003703002022203d290300370300201f203e29030037030020012001290380173703a80d41c00010212205450d01200520012903a816370000200520012903b816370010200520012903a80d370020200541086a203a290300370000200541186a2026290300370000200541286a201f290300370000200541306a2022290300370000200541386a2021290300370000200141c0003602cc04200120053602c8042023200141c8046a10f50120051023203041206a2036280200360000203041186a2037290300370000203041106a2038290300370000203041086a2039290300370000203020012903e0183700002028201229000037030020292015290000370300202a2025290000370300200141f8086a411f6a2205200141c8046a411f6a290000370000200120012900c8043703f808200141003a00cc042001203b3602c804202f20012903f808370000202f41086a2028290300370000202f41106a2029290300370000202f41186a202a290300370000202f411f6a20052900003700002006200141c8046a10c9030b202e0d082010201e1003220541086a290000370300200120052900003703f01620051023200141a8166a41086a2010290300370300200120012903f0163703a816201041d0ffc300ad42808080808001841003220541086a290000370300200120052900003703f0162005102320262010290300370300200120012903f0163703b816200120063602c80420014180176a41186a220420191001220541186a29000037030020014180176a41106a2206200541106a29000037030020014180176a41086a2209200541086a2900003703002001200529000037038017200510232021200429030037030020222006290300370300201f200929030037030020012001290380173703a80d024041c00010212220450d002024410873410f71410274220941b8fec3006a2802002211202d6a2104202020012903a816370000202020012903b816370010202020012903a80d3700204108210c202041086a200141a8166a41086a290300370000202041186a200141b8166a41086a290300370000202041286a200141a80d6a41086a290300370000202041306a2022290300370000202041386a2021290300370000200141c8046a202041c00010b0030240024020012802c80422050d00410021064200210f0c010b20012902cc04220f422088a721062005210c0b024002400240200420064b0d00200621050c010b0240200fa7220520066b200420066b220b4f0d002006200b6a220a2006490d1a20054101742214200a2014200a4b1b220a41ffffffff0071200a470d1a200a41047422144100480d1a0240024020050d0020141021210c0c010b200c200541047420141025210c0b200c450d02200f42808080807083200aad84210f0b200c200f422088a722054104746a210a024002400240200b4102490d00200a410020042006417f736a220b41047410db041a200c2011200d6a20056a200820066a6b4104746a41706a210a200b20056a21050c010b200b450d010b200a4200370308200a4200370300200541016a21050b200f42ffffffff0f832005ad42208684210f0b200420094190ffc3006a280200202d6a220a4b0d082004410474210603400240024002400240200520044b0d0020042005470d0102402005200fa7470d00200541016a22092005490d1e2005410174220b2009200b20094b1b220941ffffffff00712009470d1e2009410474220b4100480d1e0240024020050d00200b1021210c0c010b200c2005410474200b1025210c0b200c450d03200f422088a721052009ad210f0b200c20054104746a220920073703082009200e370300200f42ffffffff0f83200541016a2205ad42208684210f0c030b200c20066a22092009290300221b200e201b200e56200941086a2209290300221b200756201b2007511b220b1b3703002009201b2007200b1b3703000c020b200141dc046a4101360200200142013702cc04200141d09dc6003602c804200141043602fc08200141d8ffc3003602f8082001200141f8086a3602d804200141c8046a41e0ffc3001038000b200b41081030000b200641106a21062004200a492109200441016a210420090d000c0a0b0b201441081030000b41c00041011030000b41c00041011030000b200b41011030000b200941041030000b41c00041011030000b200b41011030000b200a41041030000b200c0d002020ad42808080808008841005202010230c010b200141003602d004200142013703c8042005200141c8046a105c024002400240200541047422040d0020012802d004210520012802cc04210920012802c804210a0c010b410020012802d00422056b2106200c20046a211120012802c804210a20012802cc042109200c21040340200441086a29030021072004290300210e0240200920066a410f4b0d00200541106a220b2005490d1220094101742214200b2014200b4b1b220b4100480d120240024020090d00200b1021210a0c010b200a2009200b1025210a0b200a450d03200b21090b200a20056a220b2007370008200b200e370000200641706a2106200541106a21052011200441106a2204470d000b200120093602cc04200120053602d0042001200a3602c8040b200fa721042020ad42808080808008842005ad422086200aad84100202402009450d00200a10230b02402004450d00200c10230b202010230c010b200b41011030000b2013202b470d000b202b21130c080b200541081030000b201541011030000b4193a1c3004133104a000b200a41011030000b200b41011030000b410141011030000b41c00041011030000b41c00041011030000b202b20136b2105024003402005450d01200541406a210520132802102104201341c0006a211320044102470d000b0b2016450d00201810230b410021040240024002400240024002400240200841e0f2796c410020006b460d00200141f8086a2109200141c8046a21040c010b200141d40d6a2008360200200141c80d6a41086a41003a00002001410f3a00c80d200141c80d6a108e014200210f200141c8046a41186a4200370300200141c8046a41106a220a4200370300200141c8046a41086a22064200370300200142003703c804200141f0166a41086a2205418cfdc400ad4280808080d000841003220941086a290000370300200120092900003703f0162009102320062005290300370300200120012903f0163703c804200541acfec300ad4280808080a001841003220941086a290000370300200120092900003703f01620091023200a20012903f0162207370300200141f8086a41086a2006290300370300200141f8086a41106a2007370300200141f8086a41186a2005290300370300200120073703a80d200120012903c8043703f808200141c80d6a200141f8086a4120108b020240024020012802c80d220a0d004104210a410421050c010b20012902cc0d220f422088a72104200a21050b2005200441027422046a210602400340024020040d004104211341002109410021110c020b2001200528020022093602c80d2004417c6a2104200541046a2105200141c80d6a10ca03450d000b02400240410410212213450d00201320093602004101210941012111034020062005460d032001200528020022043602c80d200541046a2105200141c80d6a10ca03450d00024020112009470d00200941016a220b2009490d0d2009410174220c200b200c200b4b1b221141ffffffff03712011470d0d2011410274220b4100480d0d0240024020090d00200b102121130c010b20132009410274200b102521130b2013450d030b201320094102746a2004360200200941016a21090c000b0b410441041030000b200b41041030000b0240200fa7450d00200a10230b200141a80d6a41186a220a4200370300200141a80d6a41106a220b4200370300200141a80d6a41086a22044200370300200142003703a80d200141f0166a41086a2205418cfdc400ad4280808080d000841003220641086a290000370300200120062900003703f0162006102320042005290300370300200120012903f01622073703f808200120073703a80d200541acfec300ad4280808080a001841003220641086a290000370300200120062900003703f01620061023200141f8116a41086a20052903002207370300200120012903f016220f3703f8112003200f370000200341086a2007370000200141c80d6a41086a2004290300370300200141c80d6a41106a200b290300370300200141c80d6a41186a200a290300370300200120012903a80d3703c80d0240024020130d00200141c80d6aad428080808080048410050c010b200141003602d004200142013703c8042009200141c8046a105c0240024020090d0020012802d004210b20012802cc04210a20012802c80421040c010b410020012802d00422056b2106201320094102746a211020012802cc04210a2013210903402009280200210c02400240200a20066a4104490d0020012802c80421040c010b200541046a22042005490d0c200a410174220b2004200b20044b1b220b4100480d0c02400240200a0d00200b102121040c010b20012802c804200a200b102521040b2004450d062001200b3602cc04200120043602c804200b210a0b2001200541046a220b3602d004200420056a200c3600002006417c6a2106200b21052010200941046a2209470d000b0b200141c80d6aad4280808080800484200bad4220862004ad8410020240200a450d00200410230b2011450d00201310230b200141f0166a41086a2205418cfdc400ad4280808080d000841003220441086a290000370300200120042900003703f01620041023200141f8086a41086a22062005290300370300200120012903f0163703f808200541f8fec300ad4280808080c001841003220441086a290000370300200120042900003703f01620041023200141f8116a41086a22042005290300370300200120012903f0163703f811200120083602c80d20014180176a41186a2209200141c80d6aad22074280808080c000841001220541186a29000037030020014180176a41106a220a200541106a29000037030020014180176a41086a220b200541086a290000370300200120052900003703801720051023200141a80d6a41186a220c2009290300370300200141a80d6a41106a2209200a290300370300200141a80d6a41086a220a200b29030037030020012001290380173703a80d41c00010212205450d01200520012903f808370000200520012903f811370010200520012903a80d370020200541086a2006290300370000200541186a2004290300370000200541286a200a290300370000200541306a2009290300370000200541386a200c290300370000200141c80d6a200541c000108b020240024020012802c80d2224450d002005ad4280808080800884100520012902cc0d211b0c010b4200211b410421240b200510230240201b422088a72205450d002005410274211120074280808080c0008421072024210903402009280200210a200141f0166a41086a2204418cfdc400ad4280808080d00084220f1003220541086a290000370300200120052900003703f01620051023200141a8166a41086a22062004290300370300200120012903f0163703a816200441c7f3c300ad4280808080a00184220e1003220541086a290000370300200120052900003703f01620051023200141b8166a41086a22152004290300370300200120012903f0163703b8162001200a3602c80d20014180176a41186a220b20071001220541186a29000037030020014180176a41106a220c200541106a29000037030020014180176a41086a2210200541086a290000370300200120052900003703801720051023200141f8086a41186a2212200b290300370300200141f8086a41106a2214200c290300370300200141f8086a41086a2213201029030037030020012001290380173703f808024002400240024041c00010212205450d00200520012903a816370000200541086a2006290300370000200520012903b816370010200541186a2015290300370000200520012903f808370020200541286a2013290300370000200541306a2014290300370000200541386a2012290300370000200141c80d6a200541c00010aa03024020012d00cc0d220641034622150d0020012802f00d212320012802f40d210820012802d00d212020012802d40d212520012802d80d212220012802dc0d210320012802e00d211f20012802e40d21210b20051023410121122006410371417e6a220541014b0d020240024020050e020100010b20150d040240200641014b0d00024020060e020600060b2008450d05202310230c050b02402025450d00202010230b201f450d04200310230c040b200120223602d004200120253602cc04200120203602c804200120213602d00d2001201f3602cc0d200120033602c80d200a4100200141c8046a200141c80d6a10b2021a2004200f1003220541086a290000370300200120052900003703f0162005102320132004290300370300200120012903f0163703f8082004200e1003220541086a290000370300200120052900003703f01620051023200141f8116a41086a22122004290300370300200120012903f0163703f8112001200a3602c80d200b20071001220541186a290000370300200c200541106a2900003703002010200541086a290000370300200120052900003703801720051023200141a80d6a41186a2204200b290300370300200141a80d6a41106a220a200c290300370300200141a80d6a41086a220b201029030037030020012001290380173703a80d41c00010212205450d01200520012903f808370000200520012903f811370010200520012903a80d370020200541086a2013290300370000200541186a2012290300370000200541286a200b290300370000200541306a200a290300370000200541386a20042903003700002005ad4280808080800884100520051023410021122015450d020c030b41c00041011030000b41c00041011030000b0240200641024b0d000240024020060e03030100030b2012450d0202402025450d00202010230b201f450d02200310230c020b2008450d01202310230c010b02402025450d00202010230b201f450d00200310230b200941046a21092011417c6a22110d000b0b200141c8046a2104200141f8086a2109201ba7450d00202410230b200141c8046a41186a4200370300200141c8046a41106a220a4200370300200141c8046a41086a220b4200370300200142003703c804200141f0166a41086a22054182fdc400ad4280808080a001841003220641086a290000370300200120062900003703f01620061023200441086a2005290300370000200420012903f016370000200541b39fc600ad42808080809001841003220441086a290000370300200120042900003703f01620041023200a20012903f0162207370300200141f8086a41086a200b290300370300200141f8086a41106a2007370300200141f8086a41186a2005290300370300200120073703a80d200120012903c8043703f8082009ad428080808080048410050240200041b009700d0010bf020b02400240200041c0930670450d00200141f8116a2109200141e0186a2117200141a0176a2126200141f8086a21240c010b200141f8086a41186a4200370300200141f8086a41106a22094200370300200141f8086a41086a22044200370300200142003703f808200141f0166a41086a220541aefcc400ad42808080809001841003220641086a290000370300200120062900003703f0162006102320042005290300370300200120012903f01622073703a017200120073703f808200541e8a1c100ad4280808080d002841003220641086a290000370300200120062900003703f01620061023200920012903f0162207370300200141f8116a41086a2004290300370300200141f8116a41106a2007370300200141f8116a41186a2005290300370300200120073703e018200120012903f8083703f81102400240200141f8116a109b02220541ff01714102460d00200141f8116aad4280808080800484100520054101710d010b200141f8086a2124200141a0176a2126200141e0186a2117200141f8116a2109200010d501450d01200010d8011a0c010b200141f8086a2124200141a0176a2126200141e0186a2117200141f8116a2109200010d801450d00200010d5011a0b200141f8086a41186a22064200370300200141f8086a41106a222a4200370300200141f8086a41086a22044200370300200142003703f808200141f0166a41086a220541aefcc400ad428080808090018422071003220a41086a2900003703002001200a2900003703f016200a1023200141a0176a41086a220b2005290300370300200120012903f0163703a017202441086a220c202641086a221029000037000020242026290000370000200541849fc100ad42808080809001841003220a41086a2900003703002001200a2900003703f016200a1023200141e0186a41086a22132005290300370300200120012903f0163703e018202a2017290000220f370300200141f8116a41086a22112004290300370300200141f8116a41106a2215200f370300200141f8116a41186a2212201741086a2214290000370300200120012903f8083703f811200141b8036a20094120108f0120012802bc03212520012802b803211f20064200370300202a420037030020044200370300200142003703f808200520071003220a41086a2900003703002001200a2900003703f016200a1023200b2005290300370300200120012903f0163703a017200c201029000037000020242026290000370000200541ec9ec100ad4280808080f001841003220a41086a2900003703002001200a2900003703f016200a102320132005290300370300200120012903f0163703e018200620142900002207370300201120042903003703002015201729000037030020122007370300200120012903f8083703f811200141b0036a20094120108f010240024020254100201f1b220520012802b403410020012802b0031b22044f0d0002400340200141c8046a200510e50120012802c8042206411a470d012004200541016a2205470d000c020b0b200141f8116a200141c8046a41047241bc0110dc041a200141f8086a200141f8116a41bc0110dc041a200141e0186a200141f8086a41bc0110dc041a200120063602d00d20012005ad22073703c80d200141d40d6a200141e0186a41bc0110dc04210a200141800f6a2802002000460d01200141d00d6a10db010b4100213c4108213a410021050c050b200141a0176a200a41bc0110dc041a200141c80d6a200141a0176a41bc0110dc041a024041c8011021223a450d00203a2006360208203a2007370300203a410c6a200141c80d6a41bc0110dc041a02400240200541016a220620044f0d000340200141c8046a200610e50120012802c804220a411a470d022004200641016a2206470d000b0b410121054101213c0c060b200141f8116a200141c8046a410472221341bc0110dc041a200141f8086a200141f8116a41bc0110dc041a200141e0186a200141f8086a41bc0110dc041a2001200a3602d00d20012006ad22073703c80d200141c80d6a410c6a200141e0186a41bc0110dc04210c41012105200141d00d6a2110200141800f6a2802002000470d04200641016a2106200141a0176a200c41bc0110dc041a410121054101213c0340200141c80d6a200141a0176a41bc0110dc041a0240203c2005470d00200541016a220b2005490d0a20054101742211200b2011200b4b1b223cad42c8017e220f422088a70d0a200fa7220b4100480d0a024002402005450d00203a200541c8016c200b1025213a0c010b200b1021213a0b203a450d050b203a200541c8016c6a220b200a360208200b2007370300200b410c6a200141c80d6a41bc0110dc041a200541016a2105200620044f0d0602400340200141c8046a200610e501024020012802c804220a411a460d00200141f8116a201341bc0110dc041a200141f8086a200141f8116a41bc0110dc041a200141e0186a200141f8086a41bc0110dc041a2001200a3602d00d20012006ad22073703c80d200c200141e0186a41bc0110dc04210b20012802800f2000470d02200641016a2106200141a0176a200b41bc0110dc041a0c030b2004200641016a2206470d000c080b0b0b201010db010c050b41c80141081030000b41c00041011030000b200b41011030000b200b41081030000b201010db014101213c0b203a200541c8016c6a212f024020050d00203a21030c020b200141f8116a4104722105200141f8086aad4280808080c00084213f200141c8166aad4280808080c0008421402009ad42808080808004842141200141e0186a41106a2123200141c80d6a4104722116203a210303402003280200210920032802082104200141c80d6a2003410c6a41bc0110dc041a200341c8016a21032004411a460d02200141c8046a200141c80d6a41bc0110dc041a200120043602c80d2016200141c8046a41bc0110dc041a200141f8086a200910df0120012802f808210c0240024020012802800922040d0042002132420021334200212c420021344200211c420021190c010b2004410574210a4200211c200c2104420021194200212c4200213442002132420021330340200141a0036a200410e301200141a0036a41086a290300210f20012903a003210720052004290000370000200541086a200441086a290000370000200541106a200441106a290000370000200541186a200441186a290000370000200120093602f81120014198036a200141f8116a10e00120012d00980341017121060240024020012d009903220b0d00200141d8026a2007200f420a420010e20420012903d802220e2107200141d8026a41086a290300221b210f0c010b200141f8026a200f4200200bad220e420010e10420014188036a20074200200e420010e104200141e8026a420042002007420010e104427f20014188036a41086a290300220e20012903f80220012903e8027c7c221b20012903800320012903f00284420052201b200e5472220b1b211b427f200129038803200b1b210e0b200441206a21044200201b20061b20347c4200200e20061b221d202c7c222c201d54ad7c2134201b420020061b20337c200e420020061b220e20327c2232200e54ad7c2133200f20197c2007201c7c221c200754ad7c2119200a41606a220a0d000b0b024020012802fc08450d00200c10230b200141f8086a200910df0120012802f80821110240024020012802800922040d004200211d420021354200211e420021424200211b4200211a0c010b2004410574210a4200211b201121044200211a4200211e420021424200211d42002135034020052004290000370000200541086a200441086a2206290000370000200541106a200441106a220b290000370000200541186a200441186a220c290000370000200120093602f811200141d0026a200141f8116a10e00120012d00d002211020012d00d1022113200141f8116a41186a200c290000370300200141f8116a41106a200b290000370300200141f8116a41086a2006290000370300200120042900003703f811200141b0026a2009200141f8116a2013411010e101200141b0026a41186a290300201a7c20012903c0022207201b7c221b200754ad7c211a4200200141b0026a41086a2903002207201041017122061b20427c420020012903b002220f20061b220e201e7c221e200e54ad7c21422007420020061b20357c200f420020061b2207201d7c221d200754ad7c2135200441206a2104200a41606a220a0d000b0b024020012802fc08450d00201110230b200141e0186a41186a2206420037030020234200370300200141e0186a41086a22084200370300200142003703e018200141f0166a41086a222241d5fbc400ad42808080808001841003220441086a290000370300200120042900003703f0162004102320082022290300370300200120012903f0163703e018202241d6a0c200ad4280808080d001841003220441086a290000370300200120042900003703f01620041023200141f8116a41086a222920222903002207370300200120012903f016220f3703f8112023200f370000202341086a2007370000200141a0176a41086a22102008290300370300200141a0176a41106a22132023290300370300200141a0176a41186a22112006290300370300200120012903e0183703a01720014198026a200141a0176a412010890220014198026a41106a290300420020012802980222041b210720012903a002420020041b210f02400240201b201c7c220e420288201a20197c200e201b54ad7c221b423e8684221c201b420288221984500d00201c200e852019201b8584500d00410021040240034020014188026a200e201b200441046a41fe007110e004200441026a2104200129038802221c20014188026a41086a290300221984500d01201c200e852019201b858450450d000b0b200141f8016a200e201b200441fe007110e00420012903f801200141f8016a41086a29030084211c42002119024020040d00201c420052ad211c0c020b201c420052ad211c0340200141d8016a200e201b41002004417e6a2206200620044b1b220441ff007110e004200141e8016a201c4201862243420184221a2019420186201c423f88842219201a201910e1042043201a20012903e80120012903d80156200141e8016a41086a290300221c200141d8016a41086a290300224456201c2044511b1b211c20040d000c020b0b42002119200e201b84420052ad211c0b02400240200f4202882007423e8684220e2007420288221b84500d00200e200f85201b20078584500d004100210402400340200141c8016a200f2007200441046a41fe007110e004200441026a210420012903c801220e200141c8016a41086a290300221b84500d01200e200f85201b2007858450450d000b0b200141b8016a200f2007200441fe007110e00420012903b801200141b8016a41086a29030084210e4200211b024020040d00200e420052ad210e0c020b200e420052ad210e034020014198016a200f200741002004417e6a2206200620044b1b220441ff007110e004200141a8016a200e4201862243420184221a201b420186200e423f8884221b201a201b10e1042043201a20012903a80120012903980156200141a8016a41086a290300220e20014198016a41086a290300224456200e2044511b1b210e20040d000c020b0b4200211b200f200784420052ad210e0b02400240024002400240201c20198450450d004100210c0c010b204220347c201e202c7c220f201e54ad7c211e203520337c201d20327c2207201d54ad7c211d02400240024020012d00800f0e03010200010b2007200f56201d201e56201d201e511b210c0c020b0340200141c8006a200f201e201c201910e204200e2232201b2233844200510d04200141c8006a41086a290300210e2001290348211b200141386a2007201d2032203310e2044101210c201b2001290338222c54200e200141386a41086a290300221a54200e201a5122041b0d020240202c201b54201a200e5420041b450d004100210c0c030b200141286a201b200e201c201910e104200141186a202c201a2032203310e104024020072001290318220e7d221b201d200141186a41086a2903007d2007200e54ad7d221a84500d00201e200141286a41086a2903007d212c200f20012903282207542104200f20077d210e201c21072019211d201b211c201a21192032210f2033211e200e202c2004ad7d221b84500d030c010b0b4100210c0c010b03402019211a201c2132200e201b844200510d02200141f8006a2007201d2032201a10e20420014188016a200f201e200e201b10e2044101210c20012903880122332001290378222c5420014188016a41086a290300221c200141f8006a41086a290300221954201c20195122041b0d010240202c2033542019201c5420041b450d004100210c0c020b200141e8006a2033201c200e201b10e104200141d8006a202c20192032201a10e104024020072001290358221c7d2219201d200141d8006a41086a2903007d2007201c54ad7d22338450450d004100210c0c020b201e200141e8006a41086a2903007d212c200f20012903682207542104200f20077d211c200e2107201b211d2019210e2033211b2032210f201a211e201c202c2004ad7d2219844200520d000b0b200141f8116a200910df0120012802f811212820012802fc1121302001280280122204450d022028200441057422256a21212028210402400340200141f8086a41186a2206200441186a2215290000370300200141f8086a41106a220a200441106a2212290000370300200141f8086a41086a220b200441086a2214290000370300200120042900003703f80820042900002107200541186a221f201529000037000020052007370000200541086a22152014290000370000200541106a22142012290000370000200120093602f811200141106a200141f8116a10e0012010200b2903003703002013200a29030037030020112006290300370300200120012903f8083703a0170240200c20012d001041017145734101470d0020012d00112112200441206a21040c020b200441206a2104202541606a22250d000c040b0b0340200141c8166a41186a20112903002207370300200141c8166a41106a2013290300220f370300200141c8166a41086a2010290300220e370300200120012903a017221b3703c816200141f8116a41186a2007370300200141f8116a41106a200f3703002029200e370300200142e4cab5fbb6ccdcb0e3003703b8162001201b3703f811200141b8166a200141f8116a201241187441187541027441c0b1c0006a280200418084076c20006a10f80120042021460d03024003402006200441186a2212290000370300200a200441106a2225290000370300200b200441086a2220290000370300200120042900003703f808200120093602f811202029000021072025290000210f2004290000210e201f20122900003700002014200f370000201520073700002005200e370000200141086a200141f8116a10e0012010200b2903003703002013200a29030037030020112006290300370300200120012903f8083703a017200c20012d000841017145730d012021200441206a2204470d000c050b0b20012d00092112200441206a21040c000b0b41b0c4c300102b000b41b0c4c300102b000b02402030450d00202810230b200910e40102400240200c0d00200141053a0080122001200936028412200141083a00f811200141f8116a108e01200141f8086a41186a22064200370300200141f8086a41106a220a4200370300200141f8086a41086a220b4200370300200142003703f808202241aefcc400ad42808080809001841003220441086a290000370300200120042900003703f0162004102320102022290300370300200120012903f0163703a017202441086a202641086a29000037000020242026290000370000202241849fc100ad42808080809001841003220441086a290000370300200120042900003703f0162004102320082022290300370300200120012903f0163703e018202a2017290000370000202a41086a201741086a2900003700002029200b290300370300200141f8116a41106a200a290300370300200141f8116a41186a2006290300370300200120012903f8083703f8112001200941016a3602f8082041203f1002200141c80d6a10db010c010b2001200936028412200141043a008012200141083a00f811200141f8116a108e010240024020012802fc0e2206450d00200141f8116a200141c80d6a41b00110dc041a200120093602a813202241aefcc400ad428080808090018422071003220441086a290000370300200120042900003703f0162004102320102022290300370300200120012903f0163703a017202241aff3c000ad4280808080d00184220f1003220441086a290000370300200120042900003703f0162004102320082022290300370300200120012903f0163703e0182001200620006a221f3602c81620014180176a41186a221320401001220441186a29000037030020014180176a41106a2211200441106a29000037030020014180176a41086a2206200441086a290000370300200120042900003703801720041023200141f8086a41186a220a2013290300370300200141f8086a41106a220b2011290300370300200141f8086a41086a220c200629030037030020012001290380173703f8080240024002400240024002400240024002400240024002400240024002400240024002400240024041c00010212204450d00200420262900003700002004201729000037001020042024290000370020200441086a202641086a2212290000370000200441186a201741086a2214290000370000200441286a202441086a2225290000370000200441306a202441106a2220290000370000200441386a202441186a2221290000370000200141e0186a2004ad4280808080800884220e10041090010240024020012802e0180d002001410036028009200142013703f8084100200141f8086a105c200141a80d6a41086a200128028009360200200120012903f8083703a80d0c010b200141a80d6a41086a2008280200360200200120012903e0183703a80d0b2006200141a80d6a41086a2802002215360200200120012903a80d37038017024002400240024002402015450d00200141f8086a20012802801720154101106920012802f8084101460d0420012802fc08213d20012802840922152001280280092228460d03200128028817201520286b6a223041046a223e417f4c0d1d203e0d014101212b0c020b410120014180176a105c20012802841721282001280288172115024020012802f811411a470d000240024020282015460d0020012802801721280c010b201541016a22282015490d20201541017422302028203020284b1b22304100480d200240024020150d002030102121280c010b20012802801720152030102521280b2028450d072001203036028417200120283602801720012802881721150b2001201541016a36028817202820156a41003a00000c140b0240024020282015460d0020012802801721280c010b201541016a22282015490d1f201541017422302028203020284b1b22304100480d1f0240024020150d002030102121280c010b20012802801720152030102521280b2028450d072001203036028417200120283602801720012802881721150b2001201541016a36028817202820156a41013a0000200141f8116a20014180176a10cb01200141f8116a41b0016a280200213002400240200128028417222820012802881722156b4104490d0020012802801721280c010b201541046a223d2015490d1f20284101742215203d2015203d4b1b22154100480d1f0240024020280d002015102121280c010b20012802801720282015102521280b2028450d082001201536028417200120283602801720012802881721150b2001201541046a36028817202820156a20303600000c130b203e1021222b450d070b2001203e3602cc162001202b3602c816200120303602d0162001200141c8166a3602f808203d200141f8086a201510920120302015490d0720012802d016223d2030490d08200128028817223d2028490d0920012802c816213e200128028017212b2001203020156b22303602b81a2001203d20286b223d3602bc1a2030203d470d0a203e20156a202b20286a203010dc041a20012802cc16212820012802d01621150240024020012802f811411a470d000240024020282015460d0020012802c81621280c010b201541016a22282015490d1f201541017422302028203020284b1b22304100480d1f0240024020150d002030102121280c010b20012802c81620152030102521280b2028450d0e200120303602cc16200120283602c81620012802d01621150b2001201541016a3602d016202820156a41003a00000c010b0240024020282015460d0020012802c81621280c010b201541016a22282015490d1e201541017422302028203020284b1b22304100480d1e0240024020150d002030102121280c010b20012802c81620152030102521280b2028450d0e200120303602cc16200120283602c81620012802d01621150b2001201541016a3602d016202820156a41013a0000200141f8116a200141c8166a10cb01200141f8116a41b0016a28020021300240024020012802cc16222820012802d01622156b4104490d0020012802c81621280c010b201541046a223d2015490d1e20284101742215203d2015203d4b1b22154100480d1e0240024020280d002015102121280c010b20012802c81620282015102521280b2028450d0f200120153602cc16200120283602c81620012802d01621150b2001201541046a3602d016202820156a20303600000b20012802d016212820012802cc16213020012802c8162115200128028417450d1220012802801710230c120b200120014180176a3602f808203d200141f8086a202810920120012802841721282001280288172115024020012802f811411a470d000240024020282015460d0020012802801721280c010b201541016a22282015490d1d201541017422302028203020284b1b22304100480d1d0240024020150d002030102121280c010b20012802801720152030102521280b2028450d0f2001203036028417200120283602801720012802881721150b2001201541016a36028817202820156a41003a00000c110b0240024020282015460d0020012802801721280c010b201541016a22282015490d1c201541017422302028203020284b1b22304100480d1c0240024020150d002030102121280c010b20012802801720152030102521280b2028450d0f2001203036028417200120283602801720012802881721150b2001201541016a36028817202820156a41013a0000200141f8116a20014180176a10cb01200141f8116a41b0016a280200213002400240200128028417222820012802881722156b4104490d0020012802801721280c010b201541046a223d2015490d1c20284101742215203d2015203d4b1b22154100480d1c0240024020280d002015102121280c010b20012802801720282015102521280b2028450d102001201536028417200120283602801720012802881721150b2001201541046a36028817202820156a20303600000c100b200128028417450d1120012802801710230c110b41c00041011030000b203041011030000b203041011030000b201541011030000b203e41011030000b20152030103e000b2030203d1036000b2028203d103e000b200141e0186a41146a410d360200200141ec186a410e360200200141a0176a41146a4103360200200142033702a417200141acb6c6003602a0172001410e3602e4182001200141b81a6a3602a8162001200141bc1a6a3602f0162001420437038809200142013702fc0820014180b7c6003602f8082001200141e0186a3602b0172001200141f8086a3602f0182001200141f0166a3602e8182001200141a8166a3602e018200141a0176a41bcb7c6001038000b203041011030000b203041011030000b201541011030000b203041011030000b203041011030000b201541011030000b2001280288172128200128028417213020012802801721150b2015450d00200e2028ad4220862015ad84100202402030450d00201510230b200410230c010b20041023202220071003220441086a290000370300200120042900003703f0162004102320102022290300370300200120012903f0163703a0172022200f1003220441086a290000370300200120042900003703f0162004102320082022290300370300200120012903f0163703e0182001201f3602c816201320401001220441186a2900003703002011200441106a2900003703002006200441086a290000370300200120042900003703801720041023200a2013290300370300200b2011290300370300200c200629030037030020012001290380173703f80841c00010212204450d01200420262900003700002004201729000037001020042024290000370020200441086a2012290000370000200441186a2014290000370000200441286a2025290000370000200441306a2020290000370000200441386a2021290000370000200141f8086a200141f8116a410110ca012004ad428080808080088420013502800942208620012802f8082206ad841002024020012802fc08450d00200610230b200410230b024020012802f811411a460d00200141f8116a10db010b200a4200370300200b4200370300200c4200370300200142003703f808202220071003220441086a290000370300200120042900003703f0162004102320102022290300370300200120012903f0163703a0172025201229000037000020242026290000370000202241849fc100ad42808080809001841003220441086a290000370300200120042900003703f0162004102320082022290300370300200120012903f0163703e018202a2017290000370000202a41086a20142900003700002029200c290300370300200141f8116a41106a200b290300370300200141f8116a41186a200a290300370300200120012903f8083703f8112001200941016a3602f8080c020b41c00041011030000b200141f8116a200141c80d6a41b00110dc041a200141003b01f808200141e0186a200141f8116a200141f8086a108d02200120012d00e8184102463a008112200141073a0080122001200936028412200141083a00f811200141f8116a108e01200141f8086a41186a22064200370300200141f8086a41106a220a4200370300200141f8086a41086a220b4200370300200142003703f808202241aefcc400ad42808080809001841003220441086a290000370300200120042900003703f0162004102320102022290300370300200120012903f0163703a017202441086a202641086a29000037000020242026290000370000202241849fc100ad42808080809001841003220441086a290000370300200120042900003703f0162004102320082022290300370300200120012903f0163703e018202a2017290000370000202a41086a201741086a2900003700002029200b290300370300200141f8116a41106a200a290300370300200141f8116a41186a2006290300370300200120012903f8083703f8112001200941016a3602f8080b2041203f10020b2003202f470d000b202f21030c010b102f000b02402003202f460d00200141c80d6a41086a2104200141c80d6a410c6a21060340200341086a280200210520032903002107200141c80d6a2003410c6a41bc0110dc041a2005411a460d01200141c8046a200141c80d6a41bc0110dc041a200120053602d00d200120073703c80d2006200141c8046a41bc0110dc041a200410db01200341c8016a2203202f470d000b0b0240203c450d00203a10230b200141f0166a41086a220541aefcc400ad42808080809001841003220441086a290000370300200120042900003703f01620041023200141a0176a41086a2005290300370300200120012903f0163703a017200541aff3c000ad4280808080d001841003220441086a290000370300200120042900003703f01620041023200141e0186a41086a2005290300370300200120012903f0163703e018200120003602c80d20014180176a41186a2204200141c80d6aad4280808080c000841001220541186a29000037030020014180176a41106a2206200541106a29000037030020014180176a41086a2209200541086a290000370300200120052900003703801720051023200141f8086a41186a2004290300370300200141f8086a41106a2006290300370300200141f8086a41086a200929030037030020012001290380173703f8080240024041c00010212205450d00200520262900003700002005201729000037001020052024290000370020200541086a202641086a290000370000200541186a201741086a290000370000200541286a202441086a290000370000200541306a202441106a290000370000200541386a202441186a290000370000200141c80d6a200541c00010f4010240024020012802c80d220c450d002005ad4280808080800884100520012902cc0d21070c010b420021074108210c0b20051023200c2007422088a7220441b8016c22066a2109200c210502402004450d00200641c87e6a2106200141c80d6a410472210b200c21050240034020052802002104200141c8046a200541046a41ac0110dc041a2004411b460d01200141c80d6a200141c8046a41ac0110dc041a0240024002402004411a470d0020060d01200921050c050b200541b0016a280200210a200141f8116a200141c80d6a41ac0110dc041a200120043602c80d200b200141f8116a41ac0110dc041a200141003b01c804200141f8086a200141c80d6a200141c8046a108d0220012d00800921042001200a3602d40d200120044102463a00d10d200141073a00d00d200141083a00c80d200141c80d6a108e012006450d010b200541b8016a2105200641c87e6a21060c010b0b200921050c010b200541b8016a21050b2007a7210a20052009460d01200141c80d6a4104722106034020052802002104200141c80d6a200541046a41b40110dc041a2004411b460d02200141c8046a200141c80d6a41b40110dc041a200120043602c80d2006200141c8046a41b40110dc041a02402004411a460d00200141c80d6a10db010b200541b8016a22052009470d000c020b0b41c00041011030000b0240200a450d00200c10230b20014180176a41186a220a420037030020014180176a41106a2206420037030020014180176a41086a220442003703002001420037038017200141f0166a41086a22054188e0c100ad4280808080f00184220f1003220941086a290000370300200120092900003703f0162009102320042005290300370300200120012903f01622073703c8162001200737038017200541fccfc300ad4280808080b00184220e1003220941086a290000370300200120092900003703f01620091023200620012903f0162207370300200141f8086a41086a22092004290300370300200141f8086a41106a220b2007370300200141f8086a41186a220c2005290300370300200120073703c81620012001290380173703f8082001200141f8086a412041014100410010b801024020012802004101470d00200a4200370300200642003703002004420037030020014200370380172005200f1003221041086a290000370300200120102900003703f0162010102320042005290300370300200120012903f01622073703c81620012007370380172005200e1003221041086a290000370300200120102900003703f01620101023200141c8166a41086a20052903002207370300200120012903f016220f3703c8162006200f370000200641086a200737000020092004290300370300200b2006290300370300200c200a29030037030020012001290380173703f808200141203602cc162001200141f8086a3602c816200141f8116a200141f8086aad4280808080800484220710041090010240024020012802f8112205450d0020012802fc112106200120014180126a2802003602a417200120053602a017200141c80d6a200141a0176a106d0240024020012802c80d2204450d0020012902cc0d210f0c010b41002104200141003602d004200142013703c8042001410c3602e4182001200141c8166a3602e0182001200141c8046a36028017200141dc0d6a4101360200200142013702cc0d20014198c2c3003602c80d2001200141e0186a3602d80d20014180176a41b8a3c500200141c80d6a102e1a20013502d00442208620013502c804841008024020012802cc04450d0020012802c80410230b0b02402006450d00200510230b2004450d00200710052001200f3702cc0d200120043602c80d0c010b200141003602d00d200142083703c80d0b200141143602fc112001418adcc1003602f811200141013a00c8042001200141c80d6a3602cc04200141c8046a200141f8116a107020012802cc0d450d0020012802c80d10230b200010cc02200224000f0b102a000b4113210541a3c8c30021040b200120053602e418200120043602e01841fcfdc3004122200141e0186a41ecfdc3001031000bcc0601067f230041e0006b22022400200241c0006a41086a2203418cfdc400ad4280808080d000841003220441086a2900003703002002200429000037034020041023200241086a200329030037030020022002290340370300200341d780c400ad4280808080f001841003220441086a2900003703002002200429000037034020041023200241106a41086a200329030037030020022002290340370310200241003602482002420137034020012802002104410110212103024002400240024002400240024020044101460d002003450d02200242818080801037024420022003360240200341003a0000200141086a200241c0006a1071200220012802042204360220200241206a21050c010b2003450d02200242818080801037024420022003360240200341013a0000200220012802042204360220200241206a21050b0240024020022802442201200228024822036b4104490d00200228024021010c010b200341046a22042003490d04200141017422032004200320044b1b22034100480d040240024020010d002003102121010c010b200228024020012003102521010b2001450d03200220033602442002200136024020052802002104200228024821030b2002200341046a360248200120036a200436000020022802442101200241c0006a41186a2204200235024842208620022802402206ad841001220341186a290000370300200241c0006a41106a2205200341106a290000370300200241c0006a41086a2207200341086a2900003703002002200329000037034020031023200241206a41186a2004290300370300200241206a41106a2005290300370300200241206a41086a20072903003703002002200229034037032002402001450d00200610230b41c00010212203450d04200320022903003700002003200229031037001020032002290320370020200042c0808080800837020420002003360200200341086a200241086a290300370000200341186a200241106a41086a290300370000200341286a200241206a41086a290300370000200341306a200241306a290300370000200341386a200241206a41186a290300370000200241e0006a24000f0b410141011030000b410141011030000b200341011030000b102a000b41c00041011030000bac0502067f047e230041f0006b22022400200241d0006a41086a2203418cfdc400ad4280808080d000841003220441086a2900003703002002200429000037035020041023200241086a41086a2205200329030037030020022002290350370308200341d0ffc300ad42808080808001841003220441086a2900003703002002200429000037035020041023200241186a41086a22062003290300370300200220022903503703182002200136024c200241d0006a41186a2201200241cc006aad4280808080c000841001220441186a290000370300200241d0006a41106a2207200441106a2900003703002003200441086a2900003703002002200429000037035020041023200241286a41186a22042001290300370300200241286a41106a22012007290300370300200241286a41086a2207200329030037030020022002290350370328024041c00010212203450d00200320022903083700002003200229031837001020032002290328370020200341086a2005290300370000200341186a2006290300370000200341286a2007290300370000200341306a2001290300370000200341386a2004290300370000200241d0006a200341c00010b003200229025421082002280250210420031023420021092008420020041b2208a721062004410820041b2105024002402008422088a722040d00024020060d00420021080c020b2005102342002109420021080c010b200541086a290300210820052903002109024020044101460d00200541106a2103200441047441706a210403402008200341086a290300220a20092003290300220b562008200a562008200a511b22011b21082009200b20011b2109200341106a2103200441706a22040d000b0b2006450d00200510230b2000200937030020002008370308200241f0006a24000f0b41c00041011030000b820501067f230041f0006b22022400200241d0006a41086a2203418cfdc400ad4280808080d000841003220441086a2900003703002002200429000037035020041023200241086a41086a2205200329030037030020022002290350370308200341c7f3c300ad4280808080a001841003220441086a2900003703002002200429000037035020041023200241186a41086a22062003290300370300200220022903503703182002200036024c200241d0006a41186a2200200241cc006aad4280808080c000841001220441186a290000370300200241d0006a41106a2207200441106a2900003703002003200441086a2900003703002002200429000037035020041023200241286a41186a22042000290300370300200241286a41106a22002007290300370300200241286a41086a22072003290300370300200220022903503703280240024041c00010212203450d00200320022903083700002003200229031837001020032002290328370020200341086a2005290300370000200341186a2006290300370000200341286a2007290300370000200341306a2000290300370000200341386a2004290300370000410410212204450d0120024204370254200220043602502001200241d0006a10cb03200228025421042003ad4280808080800884200235025842208620022802502200ad84100202402004450d00200010230b200310230240024020012d0004220341014b0d00024020030e020200020b2001412c6a280200450d01200141286a28020010230c010b02402001410c6a280200450d00200141086a28020010230b200141186a280200450d00200141146a28020010230b200241f0006a24000f0b41c00041011030000b410441011030000bc42508067f017e037f027e017f027e047f037e23004190026b2201240020014180026a41086a2202418cfdc400ad4280808080d000841003220341086a290000370300200120032900003703800220031023200141d8006a41086a220420022903003703002001200129038002370358200241d0ffc300ad42808080808001841003220341086a290000370300200120032900003703800220031023200141f8006a41086a22032002290300370300200120012903800237037820012000280200220536028002200141c8016a41186a220620014180026aad22074280808080c000841001220241186a290000370300200141c8016a41106a2208200241106a290000370300200141c8016a41086a2209200241086a290000370300200120022900003703c8012002102320014198016a41186a220a200629030037030020014198016a41106a2206200829030037030020014198016a41086a22082009290300370300200120012903c801370398010240024002400240024041c00010212202450d0020022001290358370000200220012903783700102002200129039801370020200241086a2004290300370000200241186a2003290300370000200241286a2008290300370000200241306a2006290300370000200241386a200a290300370000200141c8016a200241c00010b00320012902cc01210b20012802c8012103200210232003410820031b21060240024002400240200b420020031b220c422088a7220d41014b0d00200d0e020201020b200641086a290300210e2006290300210f2006200641106a2204200d41047441706a10dd04211020014180026a41086a2202418cfdc400ad4280808080d000841003220341086a290000370300200120032900003703800220031023200141d8006a41086a220620022903003703002001200129038002370358200241d0ffc300ad42808080808001841003220341086a29000037030020012003290000370380022003102320014198016a41086a220320022903003703002001200129038002370398012001200028020036028002200141c8016a41186a220820074280808080c000841001220241186a290000370300200141c8016a41106a2209200241106a290000370300200141c8016a41086a220a200241086a290000370300200120022900003703c80120021023200141f8006a41186a22022008290300370300200141f8006a41106a22082009290300370300200141f8006a41086a2209200a290300370300200120012903c80137037841c00010212211450d0420112001290358370000201120012903980137001020112001290378370020201141086a2006290300370000201141186a2003290300370000201141286a2009290300370000201141306a2008290300370000201141386a2002290300370000200141003602d001200142013703c801200d417f6a2212200141c8016a105c0240024002400240201241047422020d0020012802d001210220012802cc01210820012802c80121090c010b201020026a2105410020012802d00122026b210620012802c801210920012802cc012108201021030340200341086a29030021072003290300210b0240200820066a410f4b0d00200241106a220a2002490d0420084101742213200a2013200a4b1b220a4100480d040240024020080d00200a102121090c010b20092008200a102521090b2009450d03200a21080b200920026a220a2007370008200a200b370000200641706a2106200241106a21022005200341106a2203470d000b200120083602cc01200120023602d001200120093602c8010b2011ad42808080808008842002ad4220862009ad84100202402008450d00200910230b20111023201041086a2903002107200ca721062010290300210b024020124101460d00200d41047441606a210203402007200441086a290300220c200b20042903002214562007200c562007200c511b22031b2107200b201420031b210b200441106a2104200241706a22020d000b0b02402006450d00201010230b41012102200f200b7d220c200f56200e20077d200f200b54ad7d2207200e562007200e511b0d04200141f8006a2000108702200141206a200141f8006a200c2007109702200141206a41086a290300210b2001290320210c200141c8016a41186a22064200370300200141c8016a41106a22084200370300200141c8016a41086a22044200370300200142003703c80120014180026a41086a220341d5fbc400ad428080808080018422141003220941086a29000037030020012009290000370380022009102320042003290300370300200120012903800222073703b801200120073703c801200341d6a0c200ad4280808080d00184220e1003220941086a2900003703002001200929000037038002200910232008200129038002220737030020014198016a41086a220a200429030037030020014198016a41106a2205200737030020014198016a41186a22132003290300370300200120073703b801200120012903c80137039801200141086a20014198016a4120108902200141086a41106a29030021072001290310210f20012802082109200642003703002008420037030020044200370300200142003703c801200320141003220841086a29000037030020012008290000370380022008102320042003290300370300200120012903800222143703b801200120143703c8012003200e1003220841086a290000370300200120082900003703800220081023200620032903002214370300200a20042903003703002005200129038002220e370300201320143703002001200e3703b801200120012903c801370398012001427f200b2007420020091b22077c200c200f420020091b220b7c220c200b542203ad7c220b2003200b200754200b2007511b22031b3703d0012001427f200c20031b3703c80120014198016aad4280808080800484200141c8016aad428080808080028410020c040b200a41011030000b102a000b20014180026a41086a2202418cfdc400ad4280808080d000841003220341086a290000370300200120032900003703800220031023200141d8006a41086a220420022903003703002001200129038002370358200241c7f3c300ad4280808080a001841003220341086a29000037030020012003290000370380022003102320014198016a41086a220320022903003703002001200129038002370398012001200536028002200141c8016a41186a220820074280808080c000841001220241186a290000370300200141c8016a41106a2209200241106a290000370300200141c8016a41086a220a200241086a290000370300200120022900003703c80120021023200141f8006a41186a22132008290300370300200141f8006a41106a22082009290300370300200141f8006a41086a2209200a290300370300200120012903c80137037841c00010212202450d0420022001290358370000200220012903980137001020022001290378370020200241086a2004290300370000200241186a2003290300370000200241286a2009290300370000200241306a2008290300370000200241386a2013290300370000200141c8016a200241c00010aa03024020012d00cc0122034103460d002002ad428080808080088410050b200141f4016a2802002104200141c8016a41286a280200210a200141e0016a2802002108200141dc016a2802002113200141d4016a2802002109200141d0016a28020021112002102302400240200341034b0d00024020030e0402000102020b2004450d01200a10230c010b02402009450d00201110230b2008450d00201310230b024020034103470d00200510b3021a0b20014180026a41086a2202418cfdc400ad4280808080d000841003220341086a290000370300200120032900003703800220031023200141d8006a41086a22042002290300370300200120012903800237035820024184ffc300ad4280808080b001841003220341086a29000037030020012003290000370380022003102320014198016a41086a220320022903003703002001200129038002370398012001200536028002200141c8016a41186a220820074280808080c000841001220241186a290000370300200141c8016a41106a2209200241106a290000370300200141c8016a41086a220a200241086a290000370300200120022900003703c80120021023200141f8006a41186a22052008290300370300200141f8006a41106a22082009290300370300200141f8006a41086a2209200a290300370300200120012903c80137037841c00010212202450d0520022001290358370000200220012903980137001020022001290378370020200241086a2004290300370000200241186a2003290300370000200241286a2009290300370000200241306a2008290300370000200241386a2005290300370000200141c8016a200241c000108a010240024020012d00c8014101470d002002ad4280808080800884100520014198016a41186a200141e1016a290000220b37030020014198016a41106a200141d9016a290000221437030020014198016a41086a200141d1016a290000220e370300200141d8006a41186a200b370300200141d8006a41106a2014370300200141d8006a41086a200e370300200120012900c901220f37039801200141f8006a41186a200b370300200141f8006a41106a2014370300200141f8006a41086a200e3703002001200f3703582001200f3703780c010b20014198016a41186a200141e1016a290000220b37030020014198016a41106a200141d9016a290000221437030020014198016a41086a200141d1016a290000220e370300200141d8006a41186a4200370300200141d8006a41106a4200370300200141d8006a41086a4200370300200120012900c901220f37039801200141f8006a41186a200b370300200141f8006a41106a2014370300200141f8006a41086a200e370300200142003703582001200f3703780b20021023200141c8006a200141d8006a2006290300200641086a290300109702200141c8006a41086a29030021142001290348210e200141c8016a41186a22044200370300200141c8016a41106a22084200370300200141c8016a41086a22034200370300200142003703c80120014180026a41086a220241d5fbc400ad4280808080800184220f1003220941086a290000370300200120092900003703800220091023200320022903003703002001200129038002220b3703b8012001200b3703c801200241d6a0c200ad4280808080d0018422151003220941086a2900003703002001200929000037038002200910232008200129038002220b37030020014198016a41086a2209200329030037030020014198016a41106a2213200b37030020014198016a41186a221120022903003703002001200b3703b801200120012903c80137039801200141306a20014198016a4120108902200141306a41106a290300210b200129033821162001280230210a200442003703002008420037030020034200370300200142003703c8012002200f1003220541086a290000370300200120052900003703800220051023200320022903003703002001200129038002220f3703b8012001200f3703c801200220151003220541086a29000037030020012005290000370380022005102320042002290300220f37030020092003290300370300201320012903800222153703002011200f370300200120153703b801200120012903c801370398012001427f2014200b4200200a1b220b7c200e20164200200a1b22147c220e201454220aad7c2214200a2014200b542014200b511b220a1b3703d0012001427f200e200a1b3703c80120014198016aad4280808080800484200141c8016aad428080808080028410022002418cfdc400ad4280808080d000841003220a41086a2900003703002001200a29000037038002200a1023200141d8006a41086a220520022903003703002001200129038002370358200241d0ffc300ad42808080808001841003220a41086a2900003703002001200a29000037038002200a1023200920022903003703002001200129038002370398012001200028020036028002200420074280808080c000841001220241186a2900003703002008200241106a2900003703002003200241086a290000370300200120022900003703c80120021023200141f8006a41186a220a2004290300370300200141f8006a41106a22042008290300370300200141f8006a41086a22082003290300370300200120012903c80137037841c00010212202450d0620022001290358370000200220012903980137001020022001290378370020200241086a2005290300370000200241186a2009290300370000200241286a2008290300370000200241306a2004290300370000200241386a200a2903003700002002ad42808080808008841005200210230b41002102200ca7450d00200610230b20014190026a240020020f0b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000b41c00041011030000bf60b01067f230041106b220224002000280200210302400240024002400240024002400240024002400240200141046a2802002204200141086a28020022056b4104490d00200128020021040c010b200541046a22062005490d09200441017422052006200520064b1b22054100480d090240024020040d002005102121040c010b200128020020042005102521040b2004450d0120012004360200200141046a2005360200200141086a28020021050b200141086a200541046a360200200420056a2003360000024020002d0004220541024b0d0002400240024020050e03000102000b02400240200141046a280200200141086a2802002205460d00200128020021040c010b200541016a22042005490d0c200541017422032004200320044b1b22034100480d0c0240024020050d002003102121040c010b200128020020052003102521040b2004450d0520012004360200200141046a2003360200200141086a28020021050b200141086a2203200541016a360200200420056a41003a00002000410c6a200110712000280208210402400240200141046a2802002205200328020022006b4104490d00200128020021050c010b200041046a22032000490d0c200541017422002003200020034b1b22004100480d0c0240024020050d002000102121050c010b200128020020052000102521050b2005450d0620012005360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200520006a20043600000c020b02400240200141046a280200200141086a2802002205460d00200128020021040c010b200541016a22042005490d0b200541017422032004200320044b1b22034100480d0b0240024020050d002003102121040c010b200128020020052003102521040b2004450d0620012004360200200141046a2003360200200141086a28020021050b200141086a2203200541016a360200200420056a41013a00002002200136020c200041056a2002410c6a106b20002802282106200041306a28020022002001105c02400240200141046a2802002204200328020022056b2000490d00200128020021040c010b200520006a22032005490d0b200441017422052003200520034b1b22054100480d0b0240024020040d002005102121040c010b200128020020042005102521040b2004450d0720012004360200200141046a2005360200200141086a28020021050b200141086a200520006a360200200420056a2006200010dc041a0c010b02400240200141046a280200200141086a2802002205460d00200128020021040c010b200541016a22042005490d0a200541017422032004200320044b1b22034100480d0a0240024020050d002003102121040c010b200128020020052003102521040b2004450d0720012004360200200141046a2003360200200141086a28020021050b200141086a2206200541016a360200200420056a41023a000020002802082107200041106a28020022052001105c02400240200141046a2802002203200628020022046b2005490d00200128020021030c010b200420056a22062004490d0a200341017422042006200420064b1b22044100480d0a0240024020030d002004102121030c010b200128020020032004102521030b2003450d0820012003360200200141046a2004360200200141086a28020021040b200141086a2206200420056a360200200320046a2007200510dc041a200028021421032000411c6a28020022002001105c02400240200141046a2802002204200628020022056b2000490d00200128020021040c010b200520006a22062005490d0a200441017422052006200520064b1b22054100480d0a0240024020040d002005102121040c010b200128020020042005102521040b2004450d0920012004360200200141046a2005360200200141086a28020021050b200141086a200520006a360200200420056a2003200010dc041a0b200241106a24000f0b200541011030000b200341011030000b200041011030000b200341011030000b200541011030000b200341011030000b200441011030000b200541011030000b102a000bb80901177f230041206b220424002002410020031b21052000410020011b2106200241206a200220031b2107200041206a200020011b2108200020014105746a2109200220034105746a210a4100210b4100210c4101210d4100210e4100210f41012110024002400340200b4101742111200b4105742112024002400240024002400340024020050d0020072113200d2114200c2115200b21160c040b2005210220072103200d2114200c2115200b2116201221172011211802400340024002402006450d0020022006460d0620022006412010de042213450d062013417f4c0d01200321072014210d2015210c2016210b200221050c080b200441186a2203200541186a290000370300200441106a2216200541106a290000370300200441086a2206200541086a290000370300200420052900003703000240200b200c470d00200b41016a2202200b490d0c200b41017422172002201720024b1b220c41ffffff3f71200c470d0c200c41057422024100480d0c02400240200b0d0020021021210d0c010b200d200b41057420021025210d0b200d450d030b200d200b4105746a22022004290300370000200241186a2003290300370000200241106a2016290300370000200241086a200629030037000041002106410020072007200a4622021b2105201141026a2111201241206a2112200b41016a210b2007200741206a20021b21070c030b200441186a2213200241186a290000370300200441106a2219200241106a290000370300200441086a221a200241086a29000037030020042002290000370300024020162015470d00201641016a22022016490d0b20182002201820024b1b221541ffffff3f712015470d0b201541057422024100480d0b0240024020160d002002102121140c010b201420172002102521140b2014450d040b201420176a22022004290300370000200241186a2013290300370000200241106a2019290300370000200241086a201a290300370000410020032003200a4622131b2102201841026a2118201741206a2117201641016a21162003200341206a20131b221321032002450d050c000b0b0b200241011030000b200241011030000b2014210d2015210c2016210b2003200341206a2003200a4622021b210741002008200820094622161b21064100200320021b21052008200841206a20161b21080c030b410021052006450d01201321072014210d2015210c2016210b0b200441186a2203200641186a290000370300200441106a2216200641106a290000370300200441086a2217200641086a290000370300200420062900003703000240200e200f470d00200e41016a2202200e490d04200e41017422062002200620024b1b220f41ffffff3f71200f470d04200f41057422024100480d0402400240200e0d002002102121100c010b2010200e4105742002102521100b2010450d030b2010200e4105746a22022004290300370000200241186a2003290300370000200241106a2016290300370000200241086a201729030037000041002008200820094622021b2106200e41016a210e2008200841206a20021b21080c010b0b201420162000200110cd0302402015450d00201410230b0240200f450d00201010230b200441206a24000f0b200241011030000b102a000b9e1008087f027e047f017e057f027e017f057e230022042105200441a0016b416071220424000240024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610212207450d020b410021084100210602402001450d002001410574210820072106034020062000290000370000200641186a200041186a290000370000200641106a200041106a290000370000200641086a200041086a290000370000200641206a2106200041206a2100200841606a22080d000b200141057441606a41057641016a2106200121080b200420063602102004200836020c2004200736020820072006410041202006676b109303200441e0006a41186a22094200370300200441e0006a41106a220a4200370300200441e0006a41086a220b420037030020044200370360200441286a41086a220841e680c400ad4280808080b00284220c1003220041086a2900003703002004200029000037032820001023200b200829030037030020042004290328370360200841f980c400ad42808080809001841003220041086a2900003703002004200029000037032820001023200a2004290328220d370300200441c0006a41086a220e200b290300370300200441c0006a41106a220f200d370300200441c0006a41186a221020082903003703002004200d3703900120042004290360370340200441e0006a200441c0006a412010bb0120042802602200410120001b21112004290264420020001b2212422088a72200450d0320004105742113200441e0006a4114722114200441e0006a4108722115200441c0006a410c722116200441e0006a410c6a2117201121060340200641086a290000210d200641106a2900002118200629000021192009200641186a290000370300200a2018370300200b200d370300200420193703602008200c1003220041086a2900003703002004200029000037032820001023200441186a41086a22012008290300370300200420042903283703182008418281c400ad4280808080e000841003220041086a290000370300200420002900003703282000102320044190016a41086a220720082903003703002004200429032837039001200441c0006a200441e0006a10ac0141c00010212200450d0320002004290318370000200020042903900137001020002004290040370020200041086a2001290300370000200041186a2007290300370000200041286a200e290000370000200041306a200f290000370000200041386a2010290000370000200441e0006a200041c00010a7032008201741086a290200370300200441286a41106a221a201741106a28020036020020042017290200370328024020042802682201450d002004290360210d20162004290328370200201641086a2008290300370200201641106a201a2802003602002004200d3703400b20042001360248200441003602682004290358211920042004290378221b3703582004290350211c20042004290370221d3703502004290340211e2004200429036022183703402004290348210d20042004290368221f370348201fa7210102400240200da7221a0d00201f210d201d211c201b21190c010b2004201e3703602004200d3703682004201c370370200420193703782004201a201ca74105746a3602342004201a3602302004200d422088a736022c2004201a3602282004200441086a36023820044190016a200441286a108601201541086a200728020036020020152004290390013702002004201c422088a7221a2019422088a74105746a3602342004201a36023020042019a736022c2004201a3602282004200441086a36023820044190016a200441286a108601201441086a200728020036020020142004290390013702002004290368210d20042903602118200429037821192004290370211c02402001450d00201ba721070240201f422088a7450d00200110230b2007450d00201d422088a710230b200420183703402004200d3703482004201c37035020042019370358200da721010b200420183703602004200d3703682004201c370370200da72107200420193703780240024020010d002000ad428080808080088410050c010b200441c00036022c20042000360228200441e0006a200441286a10ce030b02402007450d002019a721010240200d422088a7450d00200710230b2001450d00201c422088a710230b200641206a210620001023201341606a22130d000c040b0b102f000b200641011030000b41c00041011030000b02402012a7450d00201110230b200441c0006a41186a4200370300200441c0006a41106a22014200370300200441c0006a41086a2206420037030020044200370340200441286a41086a220041e680c400ad4280808080b002841003220841086a29000037030020042008290000370328200810232006200029030037030020042004290328220d3703182004200d37034020004183e0c400ad4280808080f000841003220841086a290000370300200420082900003703282008102320012004290328220d370300200441e0006a41086a2006290300370300200441e0006a41106a200d370300200441e0006a41186a20002903003703002004200d370390012004200429034037036020044100360248200442013703402003200441c0006a105c02402003450d002003410574210003402002200441c0006a1071200241206a2102200041606a22000d000b0b20042802442100200441e0006aad4280808080800484200435024842208620042802402206ad84100202402000450d00200610230b0240200428020c450d00200428020810230b200524000ba20301067f230041106b22022400200241003602082002420137030020002802002103024002400240410410212204450d0020024284808080c0003702042002200436020020042003360000200028020421050240024020022802042206200228020822046b4104490d00200441046a2103200228020021060c010b200441046a22032004490d03200641017422072003200720034b1b22074100480d030240024020060d002007102121060c010b200228020020062007102521060b2006450d0220022007360204200220063602000b20022003360208200620046a200536000020002802082104200041106a28020022032002105c02402003450d00200341057421030340200420021071200441206a2104200341606a22030d000b0b200028021421042000411c6a28020022032002105c02402003450d00200341057421030340200420021071200441206a2104200341606a22030d000b0b200228020421042001290200200235020842208620022802002203ad84100202402004450d00200310230b200241106a24000f0b410441011030000b200741011030000b102a000b1300200041043602042000419c81c4003602000b3400200041e680c40036020420004100360200200041146a4105360200200041106a418c8cc400360200200041086a42133702000b34002000418881c40036020420004100360200200041146a4105360200200041106a418c8cc400360200200041086a42133702000b950902067f047e230041a0036b220224000240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541034b0d0620050e0401020304010b200041053a00000c090b200241206a2001107e20022802200d03200041053a00000c080b200241c0006a200110d901024002402002280240411a460d00200241f0016a200241c0006a41b00110dc041a41b001102122050d0141b00141081030000b200041053a00000c080b2005200241f0016a41b00110dc042105200041023a0000200020022f00103b0001200041036a200241106a41026a2d00003a0000200041046a2005360200200041086a2002290220370200200041106a200241206a41086a290200370200200041186a200241206a41106a290200370200200041206a200241206a41186a2902003702000c070b20022001106e20022802000d0520022802042105200241c0006a200110d9012002280240411a460d05200241f0016a200241c0006a41b00110dc041a41b00110212201450d032001200241f0016a41b00110dc042101200041033a0000200020022f00103b0001200041036a200241126a2d00003a0000200041086a2001360200200041046a20053602002000410c6a2002290220370200200041146a200241206a41086a2902003702002000411c6a200241306a290200370200200041246a200241386a2802003602000c060b41002105200241003a0090022003417f6a21062003417e6a21030340024020062005470d00200541ff0171450d05200241003a0090020c050b200241f0016a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a0090022003417f6a21032007210520074120470d000b200241c0006a41186a200241f0016a41186a290300370300200241c0006a41106a200241f0016a41106a290300370300200241c0006a41086a200241f0016a41086a290300370300200220022903f001370340200241086a2001106e20022802080d0320012802042203450d03200228020c2104200128020022072d0000210520012003417f6a3602042001200741016a360200200541014b0d03410021010240024020050e020100010b410121010b200241206a41186a200241c0006a41186a2903002208370300200241206a41106a200241c0006a41106a2903002209370300200241206a41086a200241c0006a41086a290300220a37030020022002290340220b370320200041043a00002000200b370001200041096a200a370000200041116a2009370000200041196a2008370000200041246a2004360200200041216a20013a00000c050b200241cb006a200241206a41086a28020036000020022002290320370043200041013a000020002002290040370001200041086a200241c7006a290000370000200041106a20022902f001370200200041186a200241f0016a41086a290200370200200041206a200241f0016a41106a2902003702000c040b200041053a00000c030b41b00141081030000b200041053a00000c010b200041053a00000b200241a0036a24000b810801047f230041106b22022400024002400240024002400240024020002d0000417f6a220341034b0d00024002400240024020030e0400010203000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0a200341017422052004200520044b1b22054100480d0a0240024020030d002005102121040c010b200128020020032005102521040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200028020421032000410c6a28020022002001105c2000450d03200041057421000340200320011071200341206a2103200041606a22000d000c040b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d09200341017422052004200520044b1b22054100480d090240024020030d002005102121040c010b200128020020032005102521040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000280204200110cb010c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d08200341017422052004200520044b1b22054100480d080240024020030d002005102121040c010b200128020020032005102521040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041046a200110af012000280208200110cb010c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d07200341017422052004200520044b1b22054100480d070240024020030d002005102121040c010b200128020020032005102521040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a00002002200136020c200041016a2002410c6a106b200041246a200110af0120002d0021210402400240200141046a28020020052802002203460d00200128020021000c010b200341016a22002003490d07200341017422052000200520004b1b22054100480d070240024020030d002005102121000c010b200128020020032005102521000b2000450d0620012000360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200020036a20043a00000b200241106a24000f0b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b102a000b811301057f230041106b2202240002400240024002400240024002400240024002400240024002400240024020002d0000220341054b0d0002400240024002400240024020030e06000102030405000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d14200341017422052004200520044b1b22054100480d140240024020030d002005102121040c010b200128020020032005102521040b2004450d0720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041016a200110712000280244210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d14200441017422032005200320054b1b22034100480d140240024020040d002003102121040c010b200128020020042003102521040b2004450d0820012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a20063600002002200136020c200041216a2002410c6a106b2000280248210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d14200341017422002005200020054b1b22004100480d140240024020030d002000102121030c010b200128020020032000102521030b2003450d0920012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d13200341017422052004200520044b1b22054100480d130240024020030d002005102121040c010b200128020020032005102521040b2004450d0920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041016a200110712002200136020c200041216a2002410c6a106b20002d0041210602400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d13200341017422052004200520044b1b22054100480d130240024020030d002005102121040c010b200128020020032005102521040b2004450d0a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20063a00002000280244210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d13200441017422032005200320054b1b22034100480d130240024020040d002003102121040c010b200128020020042003102521040b2004450d0b20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a20063600002000280248210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d13200341017422002005200020054b1b22004100480d130240024020030d002000102121030c010b200128020020032000102521030b2003450d0c20012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d12200341017422052004200520044b1b22054100480d120240024020030d002005102121040c010b200128020020032005102521040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200136020c200041016a2002410c6a106b0c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102121040c010b200128020020032005102521040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002002200136020c200041016a2002410c6a106b0c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d10200341017422052004200520044b1b22054100480d100240024020030d002005102121040c010b200128020020032005102521040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a00002002200136020c200041016a2002410c6a106b20002d0021210402400240200141046a28020020052802002200460d00200128020021030c010b200041016a22032000490d10200041017422052003200520034b1b22054100480d100240024020000d002005102121030c010b200128020020002005102521030b2003450d0d20012003360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200320006a20043a00000c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0f200341017422052004200520044b1b22054100480d0f0240024020030d002005102121040c010b200128020020032005102521040b2004450d0d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a00002002200136020c200041016a2002410c6a106b20002d0021210402400240200141046a28020020052802002200460d00200128020021030c010b200041016a22032000490d0f200041017422052003200520034b1b22054100480d0f0240024020000d002005102121030c010b200128020020002005102521030b2003450d0e20012003360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200320006a20043a00000b200241106a24000f0b200541011030000b200341011030000b200041011030000b200541011030000b200541011030000b200341011030000b200041011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b102a000b966807067f017e017f027e0f7f027e097f230041c0056b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d000022040e050001020304000b200341e4026a4101360200200342013702d402200341d09dc6003602d0022003410436028404200341849ec60036028004200320034180046a3602e002200341d0026a41d48fc4001038000b200141086a2802002104200141046a2802002105024020022d000120022d000072450d00411121024186b0c00021062004450d19200510230c190b20052001410c6a280200220210fa01200341d0026a41186a22074200370300200341d0026a41106a22014200370300200341d0026a41086a22084200370300200342003703d002200341b0056a41086a220641e680c400ad4280808080b0028422091003220a41086a2900003703002003200a2900003703b005200a102320082006290300370300200320032903b0053703d00220064183e0c400ad4280808080f00084220b1003220a41086a2900003703002003200a2900003703b005200a1023200120032903b005220c37030020034180046a41086a200829030037030020034180046a41106a200c37030020034180046a41186a20062903003703002003200c370340200320032903d00237038004200341d0026a20034180046a412010bb012005200220032802d0022206410120061b220820032902d402420020061b220c422088a710cc030240200ca7450d00200810230b2007420037030020014200370300200341d0026a41086a22084200370300200342003703d002200341b0056a41086a220620091003220a41086a2900003703002003200a2900003703b005200a102320082006290300370300200320032903b005220c3703602003200c3703d0022006200b1003220a41086a2900003703002003200a2900003703b005200a1023200120032903b005220c370300200341c0006a41086a2008290300370300200341c0006a41106a200c370300200341c0006a41186a20062903003703002003200c370370200320032903d002370340200341003602d802200342013703d0022002200341d0026a105c02402002450d00200241057421012005210203402002200341d0026a1071200241206a2102200141606a22010d000b0b20032802d4022102200341c0006aad428080808080048420033502d80242208620032802d0022201ad84100202402002450d00200110230b4100210602402004450d00200510230b0c180b200141046a28020021072002411a6a290100210c200241196a2d00002105200241186a2d00002108200241166a2f0100210a200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241046a2d0000211741022106200241026a2f010021180240024020022d00000d0020022d00014101470d00200241056a2d00002106200241066a2f01002119200241086a2d000021024100211a0c010b4101211a41002102410021190b2003200c3703e802200320053a00e702200320083a00e6022003200a3b01e4022003200d3a00e3022003200e3a00e2022003200f3b01e002200320103a00df02200320113a00de02200320123b01dc02200320133a00db02200320143a00da02200320153b01d802200320163a00d702200320173a00d202200320183b01d0022003201941ffff0371410874200241187472200641ff01717222053600d3020240201a450d00410f210241aab0c0002106024002400240024020050e05000102031a000b20032800d702210620032800db0221020c190b410e210241aabac60021060c180b411321024197b0c00021060c170b411121024186b0c00021060c160b20034180016a41186a200341d0026a41186a220629030037030020034180016a41106a200341d0026a41106a220529030037030020034180016a41086a200341d0026a41086a2202290300370300200320032903d00237038001200642003703002005420037030020024200370300200342003703d002200341b0056a41086a220641e680c400ad4280808080b002841003220841086a290000370300200320082900003703b0052008102320022006290300370300200320032903b0053703d00220064183e0c400ad4280808080f000841003220841086a290000370300200320082900003703b00520081023200520032903b005220c37030020034180046a41086a200229030037030020034180046a41106a200c37030020034180046a41186a20062903003703002003200c370340200320032903d00237038004200341d0026a20034180046a412010bb0120032902d402420020032802d00222021b220c422088a741057421062002410120021b220a210202400340024020060d00410021080c020b4101210820034180016a2002460d01200641606a2106200220034180016a412010de042105200241206a210220050d000b0b0240200ca7450d00200a10230b024020080d0041e48fc4002106411521020c160b4100210a200341003602d802200342013703d0022007200341d0026a10cb0120032802d4022106200341d0026a41186a220520033502d80242208620032802d002220fad841001220241186a290000370300200341d0026a41106a2208200241106a290000370300200341d0026a41086a220d200241086a290000370300200320022900003703d00220021023200341a0016a41186a22022005290300370300200341a0016a41106a22052008290300370300200341a0016a41086a220e200d290300370300200320032903d0023703a00102402006450d00200f10230b200341d0026a200741b00110dc041a20034180046a410d6a20034180016a41086a29030037000020034180046a41156a20034180016a41106a29030037000020034180046a411d6a20034180016a41186a29030037000041012108200341013a008404200320032903800137008504200341023a008004200341c0006a200341d0026a20034180046a108d0220032d00482106200341d0026a410d6a200e290300370000200341d0026a41156a2005290300370000200341d0026a411d6a2002290300370000200341f5026a20064102463a0000200341053a00d4022003410a3a00d002200320032903a0013700d502200341d0026a108e0120071023410021060c160b200141086a280200210a200141046a280200211b2002411a6a290100210c200241196a2d00002112200241186a2d00002113200241166a2f01002114200241156a2d00002115200241146a2d00002116200241126a2f01002117200241116a2d00002118200241106a2d000021072002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241046a2d0000211941022106200241026a2f0100211a0240024020022d00000d0020022d00014101470d00200241056a2d00002106200241066a2f01002105200241086a2d00002102410021080c010b4101210841002105410021020b200541ffff0371410874200641ff017172200241187472210502402008450d00410f210241aab0c0002106024002400240024020050e050001020318000b2010410874201172200f411874722106200d410874200e7220074118747221020c170b410e210241aabac60021060c160b411321024197b0c00021060c150b411121024186b0c00021060c140b2003200c37039801200320123a009701200320133a009601200320143b019401200320153a009301200320163a009201200320173b019001200320183a008f01200320073a008e012003200d3b018c012003200e3a008b012003200f3a008a01200320103b018801200320113a0087012003200536008301200320193a0082012003201a3b018001200341d0026a41186a4200370300200341d0026a41106a22074200370300200341d0026a41086a22064200370300200342003703d002200341b0056a41086a220241e680c400ad4280808080b002841003220541086a290000370300200320052900003703b0052005102320062002290300370300200320032903b0053703d00220024183e0c400ad4280808080f000841003220541086a290000370300200320052900003703b00520051023200720032903b005220c37030020034180046a41086a200629030037030020034180046a41106a200c37030020034180046a41186a20022903003703002003200c370340200320032903d00237038004200341d0026a20034180046a412010bb0120032902d402420020032802d00222021b220c422088a741057421062002410120021b220d210202400340024020060d00410021080c020b4101210820034180016a2002460d01200641606a2106200220034180016a412010de042105200241206a210220050d000b0b0240200ca7450d00200d10230b024020080d0041e48fc4002106411521020c140b200341003602d802200342013703d002200a200341d0026a10cb0120032802d402210d200341d0026a41186a220620033502d80242208620032802d0022210ad841001220241186a290000370300200341d0026a41106a2205200241106a290000370300200341d0026a41086a2208200241086a290000370300200320022900003703d00220021023200341a0016a41186a22022006290300370300200341a0016a41106a220e2005290300370300200341a0016a41086a220f2008290300370300200320032903d0023703a0010240200d450d00201010230b200620022903003703002005200e2903003703002008200f290300370300200320032903a0013703d002200341b0056a41086a220241e680c400ad4280808080b002841003220641086a290000370300200320062900003703b00520061023200341e0006a41086a2002290300370300200320032903b005370360200241c089c400ad4280808080a001841003220641086a290000370300200320062900003703b00520061023200341f0006a41086a2002290300370300200320032903b005370370200341c0006a200341d0026a10ac0141c00010212202450d0220022003290360370000200241086a200341e0006a41086a29030037000020022003290370370010200241186a200341f0006a41086a29030037000020022003290340370020200241286a200341c0006a41086a290300370000200241306a200341d0006a290300370000200241386a200341c0006a41186a290300370000200341186a200241c00041014100410010b801200328021821062002102320064101460d0302400240201b4102490d0042002109200341c0006a41186a220e4200370300200341c0006a41106a220f4200370300200341c0006a41086a2206420037030020034200370340200341b0056a41086a220241e680c400ad4280808080b00284220c1003220541086a290000370300200320052900003703b0052005102320062002290300370300200320032903b005220b3703602003200b370340200241888ac400ad4280808080d00184220b1003220541086a290000370300200320052900003703b00520051023200f20032903b005221c370300200341d0026a41086a22052006290300370300200341d0026a41106a2208201c370300200341d0026a41186a220d20022903003703002003201c370370200320032903403703d002200341106a200341d0026a4120108f012003280214211120032802102112200e4200370300200f420037030020064200370300200342003703402002200c1003221041086a290000370300200320102900003703b0052010102320062002290300370300200320032903b005221c3703602003201c3703402002200b1003221041086a290000370300200320102900003703b00520101023200e2002290300221c37030020052006290300370300200820032903b005221d370300200d201c3703002003201d370370200320032903403703d002200341086a200341d0026a4120108f0120032802082110200328020c2113200e4200370300200f420037030020064200370300200342003703402002200c1003220f41086a2900003703002003200f2900003703b005200f102320062002290300370300200320032903b005221c3703602003201c3703402002200b1003220f41086a2900003703002003200f2900003703b005200f1023200e2002290300220b37030020052006290300370300200820032903b005221c370300200d200b3703002003201c370370200320032903403703d0024101210e2003201341016a410120101b36028004200341d0026aad428080808080048420034180046aad4280808080c000841002200d42003703002008420037030020054200370300200342003703d0022002200c1003220f41086a2900003703002003200f2900003703b005200f102320052002290300370300200320032903b0053703d002200241f980c400ad42808080809001841003220f41086a2900003703002003200f2900003703b005200f102320062002290300220c370300200320032903b005220b3703402007200b370000200741086a200c37000020034180046a41086a200529030037030020034180046a41106a200829030037030020034180046a41186a200d290300370300200320032903d00237038004200341d0026a20034180046a412010bb010240024020032802d00222070d0041002106410021020c010b20032902d4022209422088a721022009a721062007210e0b200d200341a0016a41186a2903003703002008200341a0016a41106a2903003703002005200341a0016a41086a290300370300200320032903a0013703d0020240024020022006460d002006210d0c010b024020062009a7220d470d00200641016a22022006490d05200641017422052002200520024b1b220d41ffffff3f71200d470d05200d41057422024100480d050240024020060d0020021021210e0c010b200e200641057420021025210e0b200e450d0820094280808080708321090b2009422088a721020b200e20024105746a220620032903d002370000200641186a200341d0026a41186a2205290300370000200641106a200341d0026a41106a2208290300370000200641086a200341d0026a41086a2206290300370000200542003703002008420037030020064200370300200342003703d002200341b0056a41086a220541e680c400ad4280808080b002841003220741086a290000370300200320072900003703b0052007102320062005290300370300200320032903b005220c3703602003200c3703d002200541f980c400ad42808080809001841003220741086a290000370300200320072900003703b00520071023200820032903b005220c370300200341c0006a41086a2006290300370300200341c0006a41106a200c370300200341c0006a41186a20052903003703002003200c370370200320032903d00237034002400240200e0d00200341c0006aad428080808080048410050c010b200341003602d802200342013703d002200241016a2206200341d0026a105c02402006450d00200241057441206a2106200e210203402003200341d0026a36028004200220034180046a106b200241206a2102200641606a22060d000b0b20032802d4022102200341c0006aad428080808080048420033502d80242208620032802d0022206ad84100202402002450d00200610230b200d450d00200e10230b200341d0026a200a41b00110dc041a20034180046a41186a200341a0016a41186a29030037030020034180046a41106a200341a0016a41106a29030037030020034180046a41086a200341a0016a41086a290300370300200320032903a00137038004200341b0056a41086a220241e680c400ad4280808080b002841003220641086a290000370300200320062900003703b00520061023200341e0006a41086a22052002290300370300200320032903b005370360200241c089c400ad4280808080a001841003220641086a290000370300200320062900003703b00520061023200341f0006a41086a22062002290300370300200320032903b005370370200341c0006a20034180046a10ac0141c00010212202450d0720022003290360370000200241086a200529030037000020022003290370370010200241186a200629030037000020022003290340370020200241286a200341c0006a41086a290300370000200241306a200341c0006a41106a290300370000200241386a200341c0006a41186a29030037000020034100360288042003420137038004200341d0026a20034180046a10cb0120032802840421062002ad42808080808008842003350288044220862003280280042205ad84100202402006450d00200510230b20021023200341d0026a10db01412010212206450d082006200329038001370000200641186a20034180016a41186a2208290300370000200641106a20034180016a41106a2207290300370000200641086a20034180016a41086a220d2903003700002003419c046a41003602002003418c046a428180808010370200200342013702940420032006360288042003201b3602840420032011410020121b220e36028004200341d0026a41186a200341a0016a41186a220f290300370300200341d0026a41106a200341a0016a41106a2210290300370300200341d0026a41086a200341a0016a41086a2211290300370300200320032903a0013703d002200341b0056a41086a220241e680c400ad4280808080b002841003220541086a290000370300200320052900003703b00520051023200341e0006a41086a22122002290300370300200320032903b0053703602002418281c400ad4280808080e000841003220541086a290000370300200320052900003703b00520051023200341f0006a41086a22052002290300370300200320032903b005370370200341c0006a200341d0026a10ac0141c00010212202450d0920022003290360370000200241086a201229030037000020022003290370370010200241186a200529030037000020022003290340370020200241286a200341c0006a41086a290300370000200241306a200341c0006a41106a290300370000200241386a200341c0006a41186a290300370000200341c0003602d402200320023602d00220034180046a200341d0026a10ce032002102320061023200341dd026a200d290300370000200341e5026a2007290300370000200341ed026a2008290300370000200341f5026a20032903a001370000200341fd026a201129030037000020034185036a20102903003700002003418d036a200f2903003700002003419c036a201b36020020034198036a200e360200200341003a00d4022003410a3a00d00220032003290380013700d502200341d0026a21020c010b200341d0026a41186a22084200370300200341d0026a41106a220d4200370300200341d0026a41086a22064200370300200342003703d002200341b0056a41086a220241e680c400ad4280808080b002841003220541086a290000370300200320052900003703b0052005102320062002290300370300200320032903b0053703d00220024183e0c400ad4280808080f000841003220541086a290000370300200320052900003703b00520051023200341c0006a41086a2002290300220c370300200320032903b005220937034020072009370000200741086a200c37000020034180046a41086a200629030037030020034180046a41106a200d29030037030020034180046a41186a2008290300370300200320032903d00237038004200341206a20034180046a412010bb0102400240200328022022060d00410021020c010b2003290224220c422088a72102200ca7450d00200610230b200341d0026a200a41b00110dc041a2003418c046a200236020020034180046a41086a4101360200200341003a008404200341023a008004200341c0006a200341d0026a20034180046a108d0220032d00482102200341dd026a200341a0016a41086a290300370000200341e5026a200341b0016a290300370000200341ed026a200341b8016a290300370000200341f5026a20024102463a0000200341043a00d4022003410a3a00d002200320032903a0013700d502200341d0026a21020b2002108e01200a1023410021084101210a410021060c150b200141216a2d0000211b200141246a280200211a200341206a41186a200141196a290000370300200341206a41106a200141116a290000370300200341206a41086a200141096a290000370300200320012900013703202002411a6a290100210c200241196a2d00002111200241186a2d00002112200241166a2f01002113200241156a2d00002114200241146a2d00002115200241126a2f01002116200241116a2d00002117200241106a2d0000210a2002410e6a2f010021072002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241046a2d0000211841022106200241026a2f010021190240024020022d00000d0020022d00014101470d00200241056a2d00002106200241066a2f01002105200241086a2d00002102410021080c010b4101210841002105410021020b200541ffff0371410874200641ff017172200241187472210502402008450d00410f210241aab0c0002106024002400240024020050e050001020316000b200f410874201072200e4118747221062007410874200d72200a4118747221020c150b410e210241aabac60021060c140b411321024197b0c00021060c130b411121024186b0c00021060c120b2003200c37039801200320113a009701200320123a009601200320133b019401200320143a009301200320153a009201200320163b019001200320173a008f012003200a3a008e01200320073b018c012003200d3a008b012003200e3a008a012003200f3b018801200320103a0087012003200536008301200320183a008201200320193b018001200341d0026a41186a4200370300200341d0026a41106a22074200370300200341d0026a41086a22064200370300200342003703d002200341b0056a41086a220241e680c400ad4280808080b002841003220541086a290000370300200320052900003703b0052005102320062002290300370300200320032903b0053703d00220024183e0c400ad4280808080f000841003220541086a290000370300200320052900003703b00520051023200720032903b005220c37030020034180046a41086a200629030037030020034180046a41106a200c37030020034180046a41186a20022903003703002003200c370340200320032903d00237038004200341d0026a20034180046a412010bb0120032902d402420020032802d00222021b220c422088a741057421062002410120021b220a210202400340024020060d00410021080c020b4101210820034180016a2002460d01200641606a2106200220034180016a412010de042105200241206a210220050d000b0b0240200ca7450d00200a10230b024020080d0041e490c4002106411221020c120b200341b0056a41086a220241e680c400ad4280808080b002841003220641086a290000370300200320062900003703b00520061023200341e0006a41086a22052002290300370300200320032903b0053703602002418281c400ad4280808080e000841003220641086a290000370300200320062900003703b00520061023200341f0006a41086a22082002290300370300200320032903b005370370200341c0006a200341206a10ac0141c00010212206450d0720062003290360370000200641086a200529030037000020062003290370370010200641186a200829030037000020062003290040370020200641286a200341c0006a41086a29000037000041102102200641306a200341c0006a41106a290000370000200641386a200341c0006a41186a290000370000200341d0026a200641c00010a703200341ec026a2802002113200341d0026a41186a2802002111200341e4026a280200210a200341d0026a41106a280200211020032802dc02211220032802d802210f20032802d402211420032802d0022105200610230240200f0d00419890c4002106411321020c120b41ab90c40021062005201a470d10201041057421064100211541002105200f21020240024003402006450d0220034180016a2002460d01200541016a2105200641606a2106200220034180016a412010de042108200241206a210220080d000b20084541016a41017120056a417f6a21050b410121150b2013410574210d20034180016a200a6b210e410021164100210641002102024002400340200d2002460d02200e2002460d01200641016a2106200a20026a2108200241206a2102200820034180016a412010de0422080d000b20084541016a41017120066a417f6a21060b410121160b02400240201b41ff01710d002016450d010c110b20150d10200341d0026a41186a220820034180016a41186a290300370300200341d0026a41106a220d20034180016a41106a290300370300200341d0026a41086a220e20034180016a41086a29030037030020032003290380013703d002024020102012460d0020122105201021120c0b0b201241016a22022012490d01201241017422052002200520024b1b220541ffffff3f712005470d01200541057422024100480d010240024020120d0020021021210f0c010b200f201241057420021025210f0b200f0d0a200241011030000b200329039801210c20032d009701210820032d009601210d20032f019401210e20032d009301211620032d009201211720032f019001211820032d008f01211920032d008e01211e20032f018c01211f20032d008b01212020032d008a01212120032f018801212220032d0087012123200328008301212420032d008201212520032f0180012126024020132011460d0020112106201321110c090b201141016a22022011490d00201141017422062002200620024b1b220641ffffff3f712006470d00200641057422024100480d000240024020110d0020021021210a0c010b200a201141057420021025210a0b200a0d08200241011030000b102a000b41c00041011030000b41f98fc4002106411f21020c0f0b200241011030000b41c00041011030000b412041011030000b41c00041011030000b41c00041011030000b200a20114105746a2202200c370018200220083a00172002200d3a00162002200e3b0014200220163a0013200220173a0012200220183b0010200220193a000f2002201e3a000e2002201f3b000c200220203a000b200220213a000a200220223b0008200220233a000720022024360003200220253a0002200220263b0000201341016a2113024002402015450d00201020054d0d01200f2010417f6a22104105746a2202290000210c200229000821092002290010210b200f20054105746a220541186a200241186a2900003700002005200b370010200520093700082005200c3700000b20062111201221050c020b41d490c40020052010102d000b200f20124105746a220220032903d002370000200241186a2008290300370000200241106a200d290300370000200241086a200e290300370000201041016a21102016450d00201320064d0d01200a2013417f6a22134105746a2202290000210c200229000821092002290010210b200a20064105746a220641186a200241186a2900003700002006200b370010200620093700082006200c3700000b200341f5026a2003290320370000200341dd026a20034180016a41086a290300370000200341e5026a20034180016a41106a290300370000200341ed026a20034180016a41186a290300370000200341fd026a200341206a41086a29030037000020034185036a200341206a41106a2903003700002003418d036a200341206a41186a290300370000200341013a00d4022003410a3a00d00220032003290380013700d5022003419c036a201336020020034198036a201036020020034195036a201b3a0000200341d0026a108e01200341d0026a41186a220d4200370300200341d0026a41106a220e4200370300200341d0026a41086a22064200370300200342003703d002200341b0056a41086a220241e680c400ad4280808080b002841003220841086a290000370300200320082900003703b0052008102320062002290300370300200320032903b0053703d00220024183e0c400ad4280808080f000841003220841086a290000370300200320082900003703b00520081023200341c0006a41086a2002290300220c370300200320032903b005220937034020072009370000200741086a200c37000020034180046a41086a200629030037030020034180046a41106a200e29030037030020034180046a41186a200d290300370300200320032903d00237038004200341a0016a20034180046a412010bb010240024020032802a00122020d00410021060c010b20032902a401220c422088a72106200ca7450d00200210230b02400240201020144f22020d004100200620136b2208200820064b1b2014490d00200341ec026a2013360200200341d0026a41186a2011360200200341d0026a41106a2010360200200341dc026a20053602002003200a3602e4022003200f3602d802200320143602d4022003201a3602d002200341b0056a41086a220241e680c400ad4280808080b002841003220641086a290000370300200320062900003703b00520061023200341e0006a41086a22082002290300370300200320032903b0053703602002418281c400ad4280808080e000841003220641086a290000370300200320062900003703b00520061023200341f0006a41086a22062002290300370300200320032903b005370370200341c0006a200341206a10ac0141c00010212202450d0320022003290360370000200241086a200829030037000020022003290370370010200241186a200629030037000020022003290040370020200241286a200341c0006a41086a290000370000200241306a200341c0006a41106a290000370000200241386a200341c0006a41186a290000370000200341c000360284042003200236028004200341d0026a20034180046a10ce032002102302402005450d00200f10230b02402011450d00200a10230b410021060c010b0240024020020d00200341dd026a200341286a290300370000200341e5026a200341306a290300370000200341ed026a200341386a290300370000200341033a00d4022003410a3a00d002200320032903203700d502200341d0026a108e010c010b200341dd026a200341206a41086a290300370000200341e5026a200341206a41106a290300370000200341ed026a200341206a41186a290300370000200341023a00d4022003410a3a00d002200320032903203700d502200341d0026a108e01200341b0056a41086a220241e680c400ad4280808080b002841003220841086a290000370300200320082900003703b00520081023200341e0006a41086a220d2002290300370300200320032903b005370360200241c089c400ad4280808080a001841003220841086a290000370300200320082900003703b00520081023200341f0006a41086a22082002290300370300200320032903b005370370200341c0006a200341206a10ac0141c00010212202450d0420022003290360370000200241086a200d29030037000020022003290370370010200241186a200829030037000020022003290040370020200241286a200341c0006a41086a290000370000200241306a200341c0006a41106a290000370000200241386a200341c0006a41186a290000370000200341d0026a200241c00010b20320032802d002210820034180046a200341d0026a410472220d41ac0110dc041a02402008411a470d00200210230c010b200341a0016a20034180046a41ac0110dc041a20021023200320083602d002200d200341a0016a41ac0110dc041a2003418c046a200636020020034180046a41086a2014360200200341003a008404200341023a008004200341c0006a200341d0026a20034180046a108d0220032d00482102200341dd026a200341206a41086a290300370000200341e5026a200341306a290300370000200341ed026a200341386a290300370000200341f5026a20024102463a0000200341043a00d4022003410a3a00d002200320032903203700d502200341d0026a108e010b200341b0056a41086a220641e680c400ad4280808080b00284220c1003220241086a290000370300200320022900003703b00520021023200341e0006a41086a22082006290300370300200320032903b0053703602006418281c400ad4280808080e000841003220241086a290000370300200320022900003703b00520021023200341f0006a41086a220d2006290300370300200320032903b005370370200341c0006a200341206a10ac0141c00010212202450d0420022003290360370000200241086a200829030037000020022003290370370010200241186a200d29030037000020022003290040370020200241286a200341c0006a41086a220d290000370000200241306a200341c0006a41106a290000370000200241386a200341c0006a41186a2900003700002002ad4280808080800884100520021023200341d0026a41186a220e4200370300200341d0026a41106a22104200370300200341d0026a41086a22024200370300200342003703d0022006200c1003220841086a290000370300200320082900003703b0052008102320022006290300370300200320032903b0053703d002200641f980c400ad42808080809001841003220841086a290000370300200320082900003703b00520081023200d2006290300220c370300200320032903b005220937034020072009370000200741086a200c37000020034180046a41086a200229030037030020034180046a41106a201029030037030020034180046a41186a200e290300370300200320032903d00237038004200341d0026a20034180046a412010bb010240024020032802d0022202450d00200320032902d4023702a401200320023602a0010c010b200341003602a801200342013703a0010b200341a0016a200341206a107620032802a801210d20032802a401211020032802a0012107200341c0006a41186a4200370300200341c0006a41106a220e4200370300200341c0006a41086a2206420037030020034200370340200341b0056a41086a220241e680c400ad4280808080b002841003220841086a290000370300200320082900003703b0052008102320062002290300370300200320032903b005220c3703602003200c370340200241f980c400ad42808080809001841003220841086a290000370300200320082900003703b00520081023200e20032903b005220c370300200341d0026a41086a2006290300370300200341d0026a41106a200c370300200341d0026a41186a20022903003703002003200c370370200320032903403703d0020240024020070d00200341d0026aad428080808080048410050c010b20034100360288042003420137038004200d20034180046a105c0240200d450d00200d4105742106200721020340200320034180046a3602402002200341c0006a106b200241206a2102200641606a22060d000b0b2003280284042102200341d0026aad42808080808004842003350288044220862003280280042206ad84100202402002450d00200610230b2010450d00200710230b02402005450d00200f10230b410021062011450d00200a10230b0c060b41d490c40020062013102d000b41c00041011030000b41c00041011030000b41c00041011030000b41bb90c4002106411621020b02402012450d00200f10230b2011450d00200a10230b4101210a410121080c020b200a10db01200a1023410021084101210a0c010b200710db0120071023410121084100210a0b2004417f6a220541024b0d0002400240024020050e03000102000b200141086a280200450d02200141046a28020010230c020b200a450d01200141046a280200220110db01200110230c010b2008450d00200141086a280200220110db01200110230b2000200236020420002006360200200341c0056a24000b816905067f017e107f047e097f230041c0056b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d000022040e050001020304000b200341e4026a4101360200200342013702d402200341d09dc6003602d0022003410436028404200341849ec60036028004200320034180046a3602e002200341d0026a41d48fc4001038000b200141086a2802002104200141046a2802002105024020022d000120022d000072450d00411121024186b0c00021062004450d19200510230c190b20052001410c6a280200220210fa01200341d0026a41186a4200370300200341d0026a41106a22064200370300200341d0026a41086a22074200370300200342003703d002200341b0056a41086a2201418881c400ad4280808080b002841003220841086a290000370300200320082900003703b0052008102320072001290300370300200320032903b0053703d00220014183e0c400ad4280808080f000841003220841086a290000370300200320082900003703b00520081023200620032903b005220937030020034180046a41086a200729030037030020034180046a41106a200937030020034180046a41186a200129030037030020032009370340200320032903d00237038004200341d0026a20034180046a412010bb01200341d0026a2005200220032802d0022201410120011b220720032902d402420020011b2209422088a710c6022006280200210120032802d402210620032802d002210820032802dc02220a200341e4026a2802002005200210c70202402001450d00200a10230b02402006450d00200810230b02402009a7450d00200710230b200341d0026a41186a4200370300200341d0026a41106a22084200370300200341d0026a41086a22064200370300200342003703d002200341b0056a41086a2201418881c400ad4280808080b002841003220741086a290000370300200320072900003703b0052007102320062001290300370300200320032903b0052209370360200320093703d00220014183e0c400ad4280808080f000841003220741086a290000370300200320072900003703b00520071023200820032903b0052209370300200341c0006a41086a2006290300370300200341c0006a41106a2009370300200341c0006a41186a200129030037030020032009370370200320032903d002370340200341003602d802200342013703d0022002200341d0026a105c02402002450d00200241057421012005210203402002200341d0026a1071200241206a2102200141606a22010d000b0b20032802d4022102200341c0006aad428080808080048420033502d80242208620032802d0022201ad84100202402002450d00200110230b4100210602402004450d00200510230b0c180b200141046a280200210a2002411a6a2901002109200241196a2d00002105200241186a2d00002107200241166a2f01002108200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241046a2d0000211541022106200241026a2f010021160240024020022d00000d0020022d00014101470d00200241056a2d00002106200241066a2f01002117200241086a2d00002102410021180c010b4101211841002102410021170b200320093703e802200320053a00e702200320073a00e602200320083b01e4022003200b3a00e3022003200c3a00e2022003200d3b01e0022003200e3a00df022003200f3a00de02200320103b01dc02200320113a00db02200320123a00da02200320133b01d802200320143a00d702200320153a00d202200320163b01d0022003201741ffff0371410874200241187472200641ff01717222053600d30202402018450d00410f210241aab0c0002106024002400240024020050e05000102031a000b20032800d702210620032800db0221020c190b410e210241aabac60021060c180b411321024197b0c00021060c170b411121024186b0c00021060c160b20034180016a41186a200341d0026a41186a220629030037030020034180016a41106a200341d0026a41106a220529030037030020034180016a41086a200341d0026a41086a2202290300370300200320032903d00237038001200642003703002005420037030020024200370300200342003703d002200341b0056a41086a2206418881c400ad4280808080b002841003220741086a290000370300200320072900003703b0052007102320022006290300370300200320032903b0053703d00220064183e0c400ad4280808080f000841003220741086a290000370300200320072900003703b00520071023200520032903b005220937030020034180046a41086a200229030037030020034180046a41106a200937030020034180046a41186a200629030037030020032009370340200320032903d00237038004200341d0026a20034180046a412010bb0120032902d402420020032802d00222021b2209422088a741057421062002410120021b2208210202400340024020060d00410021070c020b4101210720034180016a2002460d01200641606a2106200220034180016a412010de042105200241206a210220050d000b0b02402009a7450d00200810230b024020070d0041e48fc4002106411521020c160b41002108200341003602d802200342013703d002200a200341d0026a10cb0120032802d4022106200341d0026a41186a220520033502d80242208620032802d002220dad841001220241186a290000370300200341d0026a41106a2207200241106a290000370300200341d0026a41086a220b200241086a290000370300200320022900003703d00220021023200341a0016a41186a22022005290300370300200341a0016a41106a22052007290300370300200341a0016a41086a220c200b290300370300200320032903d0023703a00102402006450d00200d10230b200341d0026a200a41b00110dc041a20034180046a410d6a20034180016a41086a29030037000020034180046a41156a20034180016a41106a29030037000020034180046a411d6a20034180016a41186a29030037000041012107200341013a008404200320032903800137008504200341013a008004200341c0006a200341d0026a20034180046a108d0220032d00482106200341d0026a410d6a200c290300370000200341d0026a41156a2005290300370000200341d0026a411d6a2002290300370000200341f5026a20064102463a0000200341053a00d402200341093a00d002200320032903a0013700d502200341d0026a108e01200a1023410021060c160b200141086a2802002108200141046a28020021192002411a6a2901002109200241196a2d00002110200241186a2d00002111200241166a2f01002112200241156a2d00002113200241146a2d00002114200241126a2f01002115200241116a2d00002116200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241046a2d0000211741022106200241026a2f010021180240024020022d00000d0020022d00014101470d00200241056a2d00002106200241066a2f01002105200241086a2d00002102410021070c010b4101210741002105410021020b200541ffff0371410874200641ff017172200241187472210502402007450d00410f210241aab0c0002106024002400240024020050e050001020318000b200e410874200f72200d411874722106200b410874200c72200a4118747221020c170b410e210241aabac60021060c160b411321024197b0c00021060c150b411121024186b0c00021060c140b2003200937039801200320103a009701200320113a009601200320123b019401200320133a009301200320143a009201200320153b019001200320163a008f012003200a3a008e012003200b3b018c012003200c3a008b012003200d3a008a012003200e3b0188012003200f3a0087012003200536008301200320173a008201200320183b018001200341d0026a41186a4200370300200341d0026a41106a220a4200370300200341d0026a41086a22064200370300200342003703d002200341b0056a41086a2202418881c400ad4280808080b002841003220541086a290000370300200320052900003703b0052005102320062002290300370300200320032903b0053703d00220024183e0c400ad4280808080f000841003220541086a290000370300200320052900003703b00520051023200a20032903b005220937030020034180046a41086a200629030037030020034180046a41106a200937030020034180046a41186a200229030037030020032009370340200320032903d00237038004200341d0026a20034180046a412010bb0120032902d402420020032802d00222021b2209422088a741057421062002410120021b220b210202400340024020060d00410021070c020b4101210720034180016a2002460d01200641606a2106200220034180016a412010de042105200241206a210220050d000b0b02402009a7450d00200b10230b024020070d0041e48fc4002106411521020c140b200341003602d802200342013703d0022008200341d0026a10cb0120032802d402210b200341d0026a41186a220620033502d80242208620032802d002220ead841001220241186a290000370300200341d0026a41106a2205200241106a290000370300200341d0026a41086a2207200241086a290000370300200320022900003703d00220021023200341a0016a41186a22022006290300370300200341a0016a41106a220c2005290300370300200341a0016a41086a220d2007290300370300200320032903d0023703a0010240200b450d00200e10230b200620022903003703002005200c2903003703002007200d290300370300200320032903a0013703d002200341b0056a41086a2202418881c400ad4280808080b002841003220641086a290000370300200320062900003703b00520061023200341e0006a41086a2002290300370300200320032903b005370360200241c089c400ad4280808080a001841003220641086a290000370300200320062900003703b00520061023200341f0006a41086a2002290300370300200320032903b005370370200341c0006a200341d0026a10ac0141c00010212202450d0220022003290360370000200241086a200341e0006a41086a29030037000020022003290370370010200241186a200341f0006a41086a29030037000020022003290340370020200241286a200341c0006a41086a290300370000200241306a200341d0006a290300370000200241386a200341c0006a41186a290300370000200341186a200241c00041014100410010b801200328021821062002102320064101460d030240024020194102490d004200211a200341c0006a41186a220c4200370300200341c0006a41106a220d4200370300200341c0006a41086a2206420037030020034200370340200341b0056a41086a2202418881c400ad4280808080b0028422091003220541086a290000370300200320052900003703b0052005102320062002290300370300200320032903b005221b3703602003201b370340200241888ac400ad4280808080d00184221b1003220541086a290000370300200320052900003703b00520051023200d20032903b005221c370300200341d0026a41086a22052006290300370300200341d0026a41106a2207201c370300200341d0026a41186a220b20022903003703002003201c370370200320032903403703d002200341106a200341d0026a4120108f012003280214210f20032802102110200c4200370300200d42003703002006420037030020034200370340200220091003220e41086a2900003703002003200e2900003703b005200e102320062002290300370300200320032903b005221c3703602003201c3703402002201b1003220e41086a2900003703002003200e2900003703b005200e1023200c2002290300221c37030020052006290300370300200720032903b005221d370300200b201c3703002003201d370370200320032903403703d002200341086a200341d0026a4120108f012003280208210e200328020c2111200c4200370300200d42003703002006420037030020034200370340200220091003220d41086a2900003703002003200d2900003703b005200d102320062002290300370300200320032903b005221c3703602003201c3703402002201b1003220d41086a2900003703002003200d2900003703b005200d1023200c2002290300221b37030020052006290300370300200720032903b005221c370300200b201b3703002003201c370370200320032903403703d0024101210c2003201141016a4101200e1b36028004200341d0026aad428080808080048420034180046aad4280808080c000841002200b42003703002007420037030020054200370300200342003703d002200220091003220d41086a2900003703002003200d2900003703b005200d102320052002290300370300200320032903b0053703d002200241f980c400ad42808080809001841003220d41086a2900003703002003200d2900003703b005200d1023200620022903002209370300200320032903b005221b370340200a201b370000200a41086a200937000020034180046a41086a200529030037030020034180046a41106a200729030037030020034180046a41186a200b290300370300200320032903d00237038004200341d0026a20034180046a412010bb010240024020032802d002220a0d0041002106410021020c010b20032902d402221a422088a72102201aa72106200a210c0b200b200341a0016a41186a2903003703002007200341a0016a41106a2903003703002005200341a0016a41086a290300370300200320032903a0013703d0020240024020022006460d002006210b0c010b02402006201aa7220b470d00200641016a22022006490d05200641017422052002200520024b1b220b41ffffff3f71200b470d05200b41057422024100480d050240024020060d0020021021210c0c010b200c200641057420021025210c0b200c450d08201a42808080807083211a0b201a422088a721020b200c20024105746a220620032903d002370000200641186a200341d0026a41186a2205290300370000200641106a200341d0026a41106a2207290300370000200641086a200341d0026a41086a2206290300370000200542003703002007420037030020064200370300200342003703d002200341b0056a41086a2205418881c400ad4280808080b002841003220a41086a2900003703002003200a2900003703b005200a102320062005290300370300200320032903b0052209370360200320093703d002200541f980c400ad42808080809001841003220a41086a2900003703002003200a2900003703b005200a1023200720032903b0052209370300200341c0006a41086a2006290300370300200341c0006a41106a2009370300200341c0006a41186a200529030037030020032009370370200320032903d00237034002400240200c0d00200341c0006aad428080808080048410050c010b200341003602d802200342013703d002200241016a2206200341d0026a105c02402006450d00200241057441206a2106200c210203402003200341d0026a36028004200220034180046a106b200241206a2102200641606a22060d000b0b20032802d4022102200341c0006aad428080808080048420033502d80242208620032802d0022206ad84100202402002450d00200610230b200b450d00200c10230b200341d0026a200841b00110dc041a20034180046a41186a200341a0016a41186a29030037030020034180046a41106a200341a0016a41106a29030037030020034180046a41086a200341a0016a41086a290300370300200320032903a00137038004200341b0056a41086a2202418881c400ad4280808080b002841003220641086a290000370300200320062900003703b00520061023200341e0006a41086a22052002290300370300200320032903b005370360200241c089c400ad4280808080a001841003220641086a290000370300200320062900003703b00520061023200341f0006a41086a22062002290300370300200320032903b005370370200341c0006a20034180046a10ac0141c00010212202450d0720022003290360370000200241086a200529030037000020022003290370370010200241186a200629030037000020022003290340370020200241286a200341c0006a41086a290300370000200241306a200341c0006a41106a290300370000200241386a200341c0006a41186a29030037000020034100360288042003420137038004200341d0026a20034180046a10cb0120032802840421062002ad42808080808008842003350288044220862003280280042205ad84100202402006450d00200510230b20021023200341d0026a10db01412010212206450d082006200329038001370000200641186a20034180016a41186a2207290300370000200641106a20034180016a41106a220a290300370000200641086a20034180016a41086a220b2903003700002003419c046a41003602002003418c046a4281808080103702002003420137029404200320063602880420032019360284042003200f410020101b220c36028004200341d0026a41186a200341a0016a41186a220d290300370300200341d0026a41106a200341a0016a41106a220e290300370300200341d0026a41086a200341a0016a41086a220f290300370300200320032903a0013703d002200341b0056a41086a2202418881c400ad4280808080b002841003220541086a290000370300200320052900003703b00520051023200341e0006a41086a22102002290300370300200320032903b0053703602002418281c400ad4280808080e000841003220541086a290000370300200320052900003703b00520051023200341f0006a41086a22052002290300370300200320032903b005370370200341c0006a200341d0026a10ac0141c00010212202450d0920022003290360370000200241086a201029030037000020022003290370370010200241186a200529030037000020022003290340370020200241286a200341c0006a41086a290300370000200241306a200341c0006a41106a290300370000200241386a200341c0006a41186a290300370000200341c0003602d402200320023602d00220034180046a200341d0026a10ce032002102320061023200341dd026a200b290300370000200341e5026a200a290300370000200341ed026a2007290300370000200341f5026a20032903a001370000200341fd026a200f29030037000020034185036a200e2903003700002003418d036a200d2903003700002003419c036a201936020020034198036a200c360200200341003a00d402200341093a00d00220032003290380013700d502200341d0026a21020c010b200341d0026a41186a22074200370300200341d0026a41106a220b4200370300200341d0026a41086a22064200370300200342003703d002200341b0056a41086a2202418881c400ad4280808080b002841003220541086a290000370300200320052900003703b0052005102320062002290300370300200320032903b0053703d00220024183e0c400ad4280808080f000841003220541086a290000370300200320052900003703b00520051023200341c0006a41086a20022903002209370300200320032903b005221a370340200a201a370000200a41086a200937000020034180046a41086a200629030037030020034180046a41106a200b29030037030020034180046a41186a2007290300370300200320032903d00237038004200341206a20034180046a412010bb0102400240200328022022060d00410021020c010b20032902242209422088a721022009a7450d00200610230b200341d0026a200841b00110dc041a2003418c046a200236020020034180046a41086a4101360200200341003a008404200341013a008004200341c0006a200341d0026a20034180046a108d0220032d00482102200341dd026a200341a0016a41086a290300370000200341e5026a200341b0016a290300370000200341ed026a200341b8016a290300370000200341f5026a20024102463a0000200341043a00d402200341093a00d002200320032903a0013700d502200341d0026a21020b2002108e01200810234100210741012108410021060c150b200141216a2d00002119200141246a2802002118200341206a41186a200141196a290000370300200341206a41106a200141116a290000370300200341206a41086a200141096a290000370300200320012900013703202002411a6a2901002109200241196a2d0000210f200241186a2d00002110200241166a2f01002111200241156a2d00002112200241146a2d00002113200241126a2f01002114200241116a2d00002115200241106a2d000021082002410e6a2f0100210a2002410d6a2d0000210b2002410c6a2d0000210c2002410a6a2f0100210d200241096a2d0000210e200241046a2d0000211641022106200241026a2f010021170240024020022d00000d0020022d00014101470d00200241056a2d00002106200241066a2f01002105200241086a2d00002102410021070c010b4101210741002105410021020b200541ffff0371410874200641ff017172200241187472210502402007450d00410f210241aab0c0002106024002400240024020050e050001020316000b200d410874200e72200c411874722106200a410874200b7220084118747221020c150b410e210241aabac60021060c140b411321024197b0c00021060c130b411121024186b0c00021060c120b20032009370398012003200f3a009701200320103a009601200320113b019401200320123a009301200320133a009201200320143b019001200320153a008f01200320083a008e012003200a3b018c012003200b3a008b012003200c3a008a012003200d3b0188012003200e3a0087012003200536008301200320163a008201200320173b018001200341d0026a41186a4200370300200341d0026a41106a220a4200370300200341d0026a41086a22064200370300200342003703d002200341b0056a41086a2202418881c400ad4280808080b002841003220541086a290000370300200320052900003703b0052005102320062002290300370300200320032903b0053703d00220024183e0c400ad4280808080f000841003220541086a290000370300200320052900003703b00520051023200a20032903b005220937030020034180046a41086a200629030037030020034180046a41106a200937030020034180046a41186a200229030037030020032009370340200320032903d00237038004200341d0026a20034180046a412010bb0120032902d402420020032802d00222021b2209422088a741057421062002410120021b2208210202400340024020060d00410021070c020b4101210720034180016a2002460d01200641606a2106200220034180016a412010de042105200241206a210220050d000b0b02402009a7450d00200810230b024020070d0041e490c4002106411221020c120b200341b0056a41086a2202418881c400ad4280808080b002841003220641086a290000370300200320062900003703b00520061023200341e0006a41086a22052002290300370300200320032903b0053703602002418281c400ad4280808080e000841003220641086a290000370300200320062900003703b00520061023200341f0006a41086a22072002290300370300200320032903b005370370200341c0006a200341206a10ac0141c00010212206450d0720062003290360370000200641086a200529030037000020062003290370370010200641186a200729030037000020062003290040370020200641286a200341c0006a41086a29000037000041102102200641306a200341c0006a41106a290000370000200641386a200341c0006a41186a290000370000200341d0026a200641c00010a703200341ec026a2802002111200341d0026a41186a280200210f200341e4026a2802002108200341d0026a41106a280200210e20032802dc02211020032802d802210d20032802d402211220032802d0022105200610230240200d0d00419890c4002106411321020c120b41ab90c400210620052018470d10200e41057421064100211341002105200d21020240024003402006450d0220034180016a2002460d01200541016a2105200641606a2106200220034180016a412010de042107200241206a210220070d000b20074541016a41017120056a417f6a21050b410121130b2011410574210b20034180016a20086b210c410021144100210641002102024002400340200b2002460d02200c2002460d01200641016a2106200820026a2107200241206a2102200720034180016a412010de0422070d000b20074541016a41017120066a417f6a21060b410121140b02400240201941ff01710d002014450d010c110b20130d10200341d0026a41186a220720034180016a41186a290300370300200341d0026a41106a220b20034180016a41106a290300370300200341d0026a41086a220c20034180016a41086a29030037030020032003290380013703d0020240200e2010460d0020102105200e21100c0b0b201041016a22022010490d01201041017422052002200520024b1b220541ffffff3f712005470d01200541057422024100480d010240024020100d0020021021210d0c010b200d201041057420021025210d0b200d0d0a200241011030000b200329039801210920032d009701210720032d009601210b20032f019401210c20032d009301211420032d009201211520032f019001211620032d008f01211720032d008e01211e20032f018c01211f20032d008b01212020032d008a01212120032f018801212220032d0087012123200328008301212420032d008201212520032f018001212602402011200f460d00200f21062011210f0c090b200f41016a2202200f490d00200f41017422062002200620024b1b220641ffffff3f712006470d00200641057422024100480d0002400240200f0d002002102121080c010b2008200f4105742002102521080b20080d08200241011030000b102a000b41c00041011030000b41f98fc4002106411f21020c0f0b200241011030000b41c00041011030000b412041011030000b41c00041011030000b41c00041011030000b2008200f4105746a22022009370018200220073a00172002200b3a00162002200c3b0014200220143a0013200220153a0012200220163b0010200220173a000f2002201e3a000e2002201f3b000c200220203a000b200220213a000a200220223b0008200220233a000720022024360003200220253a0002200220263b0000201141016a2111024002402013450d00200e20054d0d01200d200e417f6a220e4105746a220229000021092002290008211a2002290010211b200d20054105746a220541186a200241186a2900003700002005201b3700102005201a370008200520093700000b2006210f201021050c020b41d490c4002005200e102d000b200d20104105746a220220032903d002370000200241186a2007290300370000200241106a200b290300370000200241086a200c290300370000200e41016a210e2014450d00201120064d0d0120082011417f6a22114105746a220229000021092002290008211a2002290010211b200820064105746a220641186a200241186a2900003700002006201b3700102006201a370008200620093700000b200341f5026a2003290320370000200341dd026a20034180016a41086a290300370000200341e5026a20034180016a41106a290300370000200341ed026a20034180016a41186a290300370000200341fd026a200341206a41086a29030037000020034185036a200341206a41106a2903003700002003418d036a200341206a41186a290300370000200341013a00d402200341093a00d00220032003290380013700d5022003419c036a201136020020034198036a200e36020020034195036a20193a0000200341d0026a108e01200341d0026a41186a220b4200370300200341d0026a41106a220c4200370300200341d0026a41086a22064200370300200342003703d002200341b0056a41086a2202418881c400ad4280808080b002841003220741086a290000370300200320072900003703b0052007102320062002290300370300200320032903b0053703d00220024183e0c400ad4280808080f000841003220741086a290000370300200320072900003703b00520071023200341c0006a41086a20022903002209370300200320032903b005221a370340200a201a370000200a41086a200937000020034180046a41086a200629030037030020034180046a41106a200c29030037030020034180046a41186a200b290300370300200320032903d00237038004200341a0016a20034180046a412010bb010240024020032802a00122020d00410021060c010b20032902a4012209422088a721062009a7450d00200210230b02400240200e20124f22020d004100200620116b2207200720064b1b2012490d00200341ec026a2011360200200341d0026a41186a200f360200200341d0026a41106a200e360200200341dc026a2005360200200320083602e4022003200d3602d802200320123602d402200320183602d002200341b0056a41086a2202418881c400ad4280808080b002841003220641086a290000370300200320062900003703b00520061023200341e0006a41086a22072002290300370300200320032903b0053703602002418281c400ad4280808080e000841003220641086a290000370300200320062900003703b00520061023200341f0006a41086a22062002290300370300200320032903b005370370200341c0006a200341206a10ac0141c00010212202450d0320022003290360370000200241086a200729030037000020022003290370370010200241186a200629030037000020022003290040370020200241286a200341c0006a41086a290000370000200241306a200341c0006a41106a290000370000200241386a200341c0006a41186a290000370000200341c000360284042003200236028004200341d0026a20034180046a10ce032002102302402005450d00200d10230b0240200f450d00200810230b410021060c010b0240024020020d00200341dd026a200341286a290300370000200341e5026a200341306a290300370000200341ed026a200341386a290300370000200341033a00d402200341093a00d002200320032903203700d502200341d0026a108e010c010b200341dd026a200341206a41086a290300370000200341e5026a200341206a41106a290300370000200341ed026a200341206a41186a290300370000200341023a00d402200341093a00d002200320032903203700d502200341d0026a108e01200341b0056a41086a2202418881c400ad4280808080b002841003220741086a290000370300200320072900003703b00520071023200341e0006a41086a220b2002290300370300200320032903b005370360200241c089c400ad4280808080a001841003220741086a290000370300200320072900003703b00520071023200341f0006a41086a22072002290300370300200320032903b005370370200341c0006a200341206a10ac0141c00010212202450d0420022003290360370000200241086a200b29030037000020022003290370370010200241186a200729030037000020022003290040370020200241286a200341c0006a41086a290000370000200241306a200341c0006a41106a290000370000200241386a200341c0006a41186a290000370000200341d0026a200241c00010b20320032802d002210720034180046a200341d0026a410472220b41ac0110dc041a02402007411a470d00200210230c010b200341a0016a20034180046a41ac0110dc041a20021023200320073602d002200b200341a0016a41ac0110dc041a2003418c046a200636020020034180046a41086a2012360200200341003a008404200341013a008004200341c0006a200341d0026a20034180046a108d0220032d00482102200341dd026a200341206a41086a290300370000200341e5026a200341306a290300370000200341ed026a200341386a290300370000200341f5026a20024102463a0000200341043a00d402200341093a00d002200320032903203700d502200341d0026a108e010b200341b0056a41086a2206418881c400ad4280808080b0028422091003220241086a290000370300200320022900003703b00520021023200341e0006a41086a22072006290300370300200320032903b0053703602006418281c400ad4280808080e000841003220241086a290000370300200320022900003703b00520021023200341f0006a41086a220b2006290300370300200320032903b005370370200341c0006a200341206a10ac0141c00010212202450d0420022003290360370000200241086a200729030037000020022003290370370010200241186a200b29030037000020022003290040370020200241286a200341c0006a41086a220b290000370000200241306a200341c0006a41106a290000370000200241386a200341c0006a41186a2900003700002002ad4280808080800884100520021023200341d0026a41186a220c4200370300200341d0026a41106a220e4200370300200341d0026a41086a22024200370300200342003703d002200620091003220741086a290000370300200320072900003703b0052007102320022006290300370300200320032903b0053703d002200641f980c400ad42808080809001841003220741086a290000370300200320072900003703b00520071023200b20062903002209370300200320032903b005221a370340200a201a370000200a41086a200937000020034180046a41086a200229030037030020034180046a41106a200e29030037030020034180046a41186a200c290300370300200320032903d00237038004200341d0026a20034180046a412010bb010240024020032802d0022202450d00200320032902d4023702a401200320023602a0010c010b200341003602a801200342013703a0010b200341a0016a200341206a107620032802a801210b20032802a401210e20032802a001210a200341c0006a41186a4200370300200341c0006a41106a220c4200370300200341c0006a41086a2206420037030020034200370340200341b0056a41086a2202418881c400ad4280808080b002841003220741086a290000370300200320072900003703b0052007102320062002290300370300200320032903b005220937036020032009370340200241f980c400ad42808080809001841003220741086a290000370300200320072900003703b00520071023200c20032903b0052209370300200341d0026a41086a2006290300370300200341d0026a41106a2009370300200341d0026a41186a200229030037030020032009370370200320032903403703d00202400240200a0d00200341d0026aad428080808080048410050c010b20034100360288042003420137038004200b20034180046a105c0240200b450d00200b4105742106200a21020340200320034180046a3602402002200341c0006a106b200241206a2102200641606a22060d000b0b2003280284042102200341d0026aad42808080808004842003350288044220862003280280042206ad84100202402002450d00200610230b200e450d00200a10230b02402005450d00200d10230b41002106200f450d00200810230b0c060b41d490c40020062011102d000b41c00041011030000b41c00041011030000b41c00041011030000b41bb90c4002106411621020b02402010450d00200d10230b200f450d00200810230b41012108410121070c020b200810db012008102341002107410121080c010b200a10db01200a102341012107410021080b2004417f6a220541024b0d0002400240024020050e03000102000b200141086a280200450d02200141046a28020010230c020b2008450d01200141046a280200220110db01200110230c010b2007450d00200141086a280200220110db01200110230b2000200236020420002006360200200341c0056a24000b34002000418cfdc40036020420004100360200200041146a4109360200200041106a41a892c400360200200041086a42053702000bb70101027f230041d0006b22022400200241033a000c0240410110212203450d00200341003a0000200041086a41013602002002410136024420022003360240200020022903403702000240024041000d00024020022d000c0e0402000102020b200241346a280200450d01200241306a28020010230c010b0240200241146a280200450d00200241106a28020010230b200241206a280200450d002002411c6a28020010230b200241d0006a24000f0b410141011030000b2401017f230041b0046b22022400200241033602002000200210cd01200241b0046a24000b2201017f230041106b22022400200241003602002000200210cc01200241106a24000be52f06057f017e017f017e077f047e230041e0126b22072400200741b8096a41186a22084200370300200741b8096a41106a22094200370300200741b8096a41086a220a4200370300200742003703b809200741e80d6a41086a220b418cfdc400ad4280808080d00084220c1003220d41086a2900003703002007200d2900003703e80d200d1023200a200b290300370300200720072903e80d220e3703b8122007200e3703b809200b419efec300ad4280808080e001841003220d41086a2900003703002007200d2900003703e80d200d1023200920072903e80d220e370300200741d8006a41086a220d200a290300370300200741d8006a41106a220f200e370300200741d8006a41186a2210200b2903003703002007200e37038805200720072903b809370358200741d0006a200741d8006a4120108f010240024002402007280254410020072802501b2002460d0041e7afc400210b0c010b2008420037030020094200370300200a4200370300200742003703b809200b200c1003220241086a290000370300200720022900003703e80d20021023200a200b290300370300200720072903e80d220e3703b8122007200e3703b809200b41d8fdc300ad4280808080b001841003220241086a290000370300200720022900003703e80d2002102320074188056a41086a200b290300220e370300200720072903e80d220c370388052009200c370000200941086a200e370000200d200a290300370300200f200929030037030020102008290300370300200720072903b809370358200741a8126a200741d8006a4120108602024020072802a8124101470d0041bfc7c300210b411e210a200320044b0d0220072802ac12220920034b0d02200941036a2004490d020240200420036b220b20044d0d0041ddc7c300210b411b210a0c030b0240200320096b220a20034d0d0041f8c7c300210b4116210a0c030b0240200a41034d0d00418ec8c300210b4115210a0c030b02400240024002400240024002400240200a0e0400010203000b200b4104490d040c060b200b41034f0d05200b41046a210f0c040b200b41014b0d044107210f200b0e020301030b200b0d034109210f0c020b4108210f0c010b200b210f0b200741b8096a41186a22024200370300200741b8096a41106a22094200370300200741b8096a41086a220a4200370300200742003703b809200741e80d6a41086a220b41c4fbc400ad4280808080e000841003220d41086a2900003703002007200d2900003703e80d200d1023200a200b290300370300200720072903e80d3703b809200b41f9bcc000ad4280808080e000841003220d41086a2900003703002007200d2900003703e80d200d1023200920072903e80d220e370300200741d8006a41086a2208200a290300370300200741d8006a41106a2203200e370300200741d8006a41186a2210200b2903003703002007200e37038805200720072903b809370358200741c8006a200741d8006a4120108f01200728024c2104200728024821112002420037030020094200370300200a4200370300200742003703b809200b418cfdc400ad4280808080d000841003220d41086a2900003703002007200d2900003703e80d200d1023200a200b290300370300200720072903e80d3703b809200b41d8fdc300ad4280808080b001841003220d41086a2900003703002007200d2900003703e80d200d1023200920072903e80d220e3703002008200a2903003703002003200e3703002010200b2903003703002007200e37038805200720072903b809370358200741b8126a200741d8006a41201086020240024020072802b8124101460d00410021120c010b410021122004410020111b220b200741b8126a41086a2802006b220a200b4b0d00200a4100200a41e807491b21120b200741e80d6a41086a220b418cfdc400ad4280808080d000841003220a41086a2900003703002007200a2900003703e80d200a102320074198126a41086a2209200b290300370300200720072903e80d37039812200b41e3fdc300ad4280808080f000841003220a41086a2900003703002007200a2900003703e80d200a1023200741a8126a41086a220d200b290300370300200720072903e80d3703a812200720123602dc12200741e80d6a41186a2202200741dc126aad4280808080c000841001220a41186a290000370300200741e80d6a41106a2208200a41106a290000370300200b200a41086a2900003703002007200a2900003703e80d200a1023200741b8126a41186a220a2002290300370300200741b8126a41106a22022008290300370300200741b8126a41086a2208200b290300370300200720072903e80d3703b81202400240024041c0001021220b450d00200b200729039812370000200b20072903a812370010200b20072903b812370020200b41086a2009290300370000200b41186a200d290300370000200b41286a2008290300370000200b41306a2002290300370000200b41386a200a290300370000200741b8096a200b41c00010a60320072802b809210a200741e80d6a200741b8096a410472220941ac0410dc041a0240200a4103460d0020074188056a200741e80d6a41ac0410dc041a200b10232007200a3602b809200920074188056a41ac0410dc041a0c020b200b1023200741b8096a2012417f6a220b20124d200b10920220072802b8094103470d01200741023602d0042007410236029804200741023602e003200741023602a803200741023602f002200741023602b8022007410236028002200741023602c8012007410236029001200741023602580c020b41c00041011030000b200741d8006a200741b8096a41b00410dc041a0b024002400240200741d8006a200f41ff0171221341386c6a22082802004102460d00200841286a29030020055a200841306a290300220e20065a200e2006511b0d010b200141086a211120012802042103200128020021020240024002400240200f410f71220b450d00200b417f6a2114410021094100210d03400240200741d8006a20096a220b280200410246220a0d004100200b200a1b220b2802002002470d000240024020024101460d000240200b41086a220a2011460d00200a2011412010de040d030b200b2802042003470d020c010b200b2802042003470d010b41032115410321044103210f024002400240024002400240024002400240024020140e09000102030405060709000b4100210f410121040c080b4100210f410221040c070b4100210f0c050b410121044101210f0c050b4101210f410221040c040b4101210f0c020b410221044102210f0c020b4102210f0b410321040b410321100240024002400240024002400240024002400240200d410f710e0a00010203040506070809000b41002115410021100c080b41002110410121150c070b41002110410221150c060b410021100c050b41012115410121100c040b41012110410221150c030b410121100c020b410221150b410221100b41faafc400210b4125210a200f20154b0d0b201020044b0d0b0b200d41016a210d200941386a220941b004470d000c020b0b0240024020072802b802410246220b0d004100200741b8026a200b1b220b2802002002470d00024020024101460d000240200b41086a220a2011460d00200a2011412010de040d020b200b2802042003470d010c020b200b2802042003460d010b024020072802f002410246220b0d004100200741f0026a200b1b220b2802002002470d00024020024101460d000240200b41086a220a2011460d00200a2011412010de040d020b200b2802042003460d020c010b200b2802042003460d010b024020072802a803410246220b0d004100200741a8036a200b1b220b2802002002470d00024020024101460d000240200b41086a220a2011460d00200a2011412010de040d020b200b2802042003460d020c010b200b2802042003460d010b024020072802e003410246220b0d004100200741e0036a200b1b220b2802002002470d00024020024101460d000240200b41086a220a2011460d00200a2011412010de040d020b200b2802042003460d020c010b200b2802042003460d010b0240200728029804410246220b0d00410020074198046a200b1b220b2802002002470d00024020024101460d000240200b41086a220a2011460d00200a2011412010de040d020b200b2802042003460d020c010b200b2802042003460d010b20072802d004410246220b0d014100200741d0046a200b1b220b2802002002470d01024020024101460d000240200b41086a220a2011460d004200210e4200210c200a2011412010de040d050b4200210e4200210c200b2802042003470d040c010b200b2802042003470d020b41faafc400210b4125210a0c080b4200210e4200210c20024101470d010b200741386a200310c803200741c0006a290300210c2007290338210e0b200741b8096a200110c703200741206a20072802b809220a20072802c009108902200741306a2903002116200729032821172007280220210b024020072802bc09450d00200a10230b0240200520174200200b1b2217200e7c220e7d2218200556200620164200200b1b200c7c200e201754ad7c7d2005200e54ad7d220e200656200e2006511b0d000240024020012802004101460d00200741b8096a41186a200141206a290000370300200741b8096a41106a200141186a290000370300200741b8096a41086a200141106a2900003703002007200141086a2900003703b8090c010b200741b8096a200141046a1087020b200741186a200741b8096a2018200e10f10102402007280218220b450d00200728021c210a0c070b200741e80d6a200110c70320072802e80d210b20073502f00d210c200720063703c009200720053703b809200c422086200bad84200741b8096aad42808080808002841002024020072802ec0d450d00200b10230b0240024020012802004101460d00200741b8096a41186a200141206a290000370300200741b8096a41106a200141186a290000370300200741b8096a41086a200141106a2900003703002007200141086a2900003703b8090c010b200741b8096a200141046a1087020b200741e80d6a41186a200741b8096a41186a290300220c370300200741e80d6a41106a200741b8096a41106a2903002216370300200741e80d6a41086a200741b8096a41086a220b2903002217370300200720072903b80922193703e80d200741800a6a2006370300200741f8096a2005370300200741f0096a200e370300200741e8096a2018370300200b41053a0000200741c1096a2019370000200741c9096a2017370000200741d1096a2016370000200741d9096a200c370000200741e1096a200728008805360000200741e4096a2007418b056a2800003600002007410f3a00b809200741b8096a108e010b2008290310210c2008200129021037031020082903082116200820012902083703082008290300210e20082001290200370300200841186a220b2903002117200b200141186a290200370300200741d8006a201341386c6a220b41306a2006370200200b41286a2005370200200b41206a220b2902002106200b200141206a2902003702000240200ea7220b4102460d00200e422088a7210a200741e80d6a41206a2006370300200741e80d6a41186a20173703002007200e3703e80d200720163703f00d2007200c3703f80d200741f00d6a210902402007280258220d4102460d00200d200b470d000240200b4101460d00200741e0006a2009412010de040d01200728025c200a460d020c010b200728025c200a460d010b0240200728029001220d4102460d00200d200b470d000240200b4101460d0020074198016a2009412010de040d0120074194016a280200200a460d020c010b20074194016a280200200a460d010b024020072802c801220d4102460d00200d200b470d000240200b4101460d00200741d0016a2009412010de040d01200741cc016a280200200a460d020c010b200741cc016a280200200a460d010b0240200728028002220d4102460d00200d200b470d000240200b4101460d0020074188026a2009412010de040d0120074184026a280200200a460d020c010b20074184026a280200200a460d010b024020072802b802220d4102460d00200d200b470d000240200b4101460d00200741c0026a2009412010de040d01200741bc026a280200200a460d020c010b200741bc026a280200200a460d010b024020072802f002220d4102460d00200d200b470d000240200b4101460d00200741f8026a2009412010de040d01200741f4026a280200200a460d020c010b200741f4026a280200200a460d010b024020072802a803220d4102460d00200d200b470d000240200b4101460d00200741b0036a2009412010de040d01200741ac036a280200200a460d020c010b200741ac036a280200200a460d010b024020072802e003220d4102460d00200d200b470d000240200b4101460d00200741e8036a2009412010de040d01200741e4036a280200200a460d020c010b200741e4036a280200200a460d010b0240200728029804220d4102460d00200d200b470d000240200b4101460d00200741a0046a2009412010de040d012007419c046a280200200a460d020c010b2007419c046a280200200a460d010b024020072802d004220d4102460d00200d200b470d000240200b4101460d00200741d8046a2009412010de040d01200741d4046a280200200a460d020c010b200741d4046a280200200a460d010b200741b8096a200741e80d6a10c703200720072802b809220b20072802c009220a108902200741106a29030021062007290308210c02402007290300220e4201520d00200aad422086200bad8410050b200ea7210a024020072802bc09450d00200b10230b200a4101470d000240024020072802e80d4101460d00200741b8096a41186a200741880e6a290300370300200741b8096a41106a200741e80d6a41186a290300370300200741b8096a41086a200741e80d6a41106a2903003703002007200741e80d6a41086a2903003703b8090c010b200741b8096a200741e80d6a4104721087020b200741b8096a200c200610de010240024020072802e80d4101460d00200741b8096a41186a200741880e6a290300370300200741b8096a41106a200741e80d6a41186a290300370300200741b8096a41086a200741e80d6a41106a2903003703002007200741e80d6a41086a2903003703b8090c010b200741b8096a200741e80d6a4104721087020b20074188056a41186a200741b8096a41186a290300220e37030020074188056a41106a200741b8096a41106a290300220537030020074188056a41086a200741b8096a41086a220b2903002216370300200720072903b809221737038805200741f0096a2006370300200741e8096a200c370300200b41063a0000200741c1096a2017370000200741c9096a2016370000200741d1096a2005370000200741d9096a200e370000200741e1096a20072800a812360000200741e4096a200741ab126a2800003600002007410f3a00b809200741f8096a20072903b812370300200741800a6a200741b8126a41086a290300370300200741b8096a108e010b200741e80d6a41086a220b418cfdc400ad4280808080d000841003220a41086a2900003703002007200a2900003703e80d200a1023200741b8126a41086a2209200b290300370300200720072903e80d3703b812200b41e3fdc300ad4280808080f000841003220a41086a2900003703002007200a2900003703e80d200a102320074188056a41086a220d200b290300370300200720072903e80d37038805200720123602a812200741e80d6a41186a2202200741a8126aad4280808080c000841001220a41186a290000370300200741e80d6a41106a2208200a41106a290000370300200b200a41086a2900003703002007200a2900003703e80d200a1023200741b8096a41186a2002290300370300200741b8096a41106a220a2008290300370300200741b8096a41086a2202200b290300370300200720072903e80d3703b80941c0001021220b450d01200b20072903b812370000200b200729038805370010200b20072903b809370020200b41086a2009290300370000200b41186a200d290300370000200b41286a2002290300370000200b41306a200a290300370000200b41386a200741b8096a41186a290300370000200741c0003602bc092007200b3602b809200741d8006a200741b8096a10d101200b10230b4100210b0c040b41c00041011030000b41a3c8c300210b0c010b41d9afc400210b410e210a0c010b4113210a0b2000200a3602042000200b360200200741e0126a24000b130020004106360204200041a4b0c4003602000bb20201027f024002402000280200220141064b0d00024002400240024020010e0705050005010203050b200041086a280200450d04200028020410230f0b200041086a280200450d03200028020410230f0b02402000410c6a2802002202450d0020002802042101200241186c210203400240200141046a280200450d00200128020010230b0240200141106a280200450d002001410c6a28020010230b200141186a2101200241686a22020d000b0b200041086a280200450d02200028020410230f0b02402000410c6a2802002202450d00200028020421012002410c6c210203400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b200041086a280200450d01200028020410230c010b200041086a280200450d00200028020410230f0b0b130020004105360204200041a8dac4003602000b130020004105360204200041c0d6c4003602000b130020004102360204200041a0aec0003602000b130020004101360204200041bcc2c3003602000b13002000410336020420004184a1c2003602000b130020004103360204200041d0adc5003602000b130020004101360204200041bcb5c0003602000b130020004101360204200041b4b7c0003602000b130020004103360204200041dcb1c0003602000b130020004103360204200041a4dfc0003602000b13002000410b360204200041c4edc0003602000b130020004106360204200041ccebc3003602000b130020004105360204200041aca4c2003602000b130020004106360204200041bca2c3003602000b130020004101360204200041b8c8c3003602000b130020004107360204200041d4f3c3003602000b13002000410236020420004194ddc1003602000b130020004103360204200041fcd9c1003602000b900e01037f0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1a000102030405060708090a0b0c0d0e0f10111213141516171819000b417f2102024002400240200141086a280200417f6a220341064b0d0041012101024020030e0703010200020202030b41c09a0c21020c020b410021010b4190ce0021020b200041013a0005200020013a0004200020023602000f0b20004180023b010420004190ce003602000f0b20004181023b010420004190ce003602000f0b20004180023b010420004190ce003602000f0b4100210202400240200141086a280200417f6a220341034b0d0041c0843d2101024020030e0402000202020b4101210241d0860321010c010b4190ce0021010b200041013a0005200020023a0004200020013602000f0b20004181023b010420004190ce003602000f0b410121024100210302400240200141086a2d0000417f6a2204410f4b0d0041a0c21e210102400240024020040e1004040000010104040102020202020202040b4180b51821010c030b41b0e32d21010c020b4100210141012103410021020c010b4190ce0021010b200020023a0005200020033a0004200020013602000f0b20004180023b010420004190ce003602000f0b20004180023b0104200041f093093602000f0b20004180023b010420004190ce003602000f0b20004180023b010420004190ce003602000f0b20004180023b010420004190ce003602000f0b20004180023b010420004190ce003602000f0b4100210202400240200141086a2d0000417f6a220341104b0d0041c096b102210102400240024002400240024020030e110707000001070707020205050303030404070b41c09a0c21010c060b4101210241a0c21e21010c050b41c09a0c21010c040b41a08d0621010c030b41a0c21e21010c020b410121020b4190ce0021010b200041013a0005200020023a0004200020013602000f0b0240024020012d0004417f6a220341034b0d004101210241a08d0621010240024020030e0403030001030b41c096b10221010c020b41c09a0c21010c010b410021024190ce0021010b200041013a0005200020023a0004200020013602000f0b0240024020012d0004417f6a220341034b0d004101210241a08d0621010240024020030e0403030001030b41c096b10221010c020b41c09a0c21010c010b410021024190ce0021010b200041013a0005200020023a0004200020013602000f0b4100210202400240200141086a280200417f6a220341054b0d0041a08d06210102400240024020030e06040300010202040b41c0843d21010c030b41a0c21e21010c020b41012102418089fa0021010c010b4190ce0021010b200041013a0005200020023a0004200020013602000f0b024020012d0004417f6a220141034b0d00024002400240024020010e0400010203000b20004180023b0104200041d086033602000f0b20004180023b0104200041d086033602000f0b20004180023b0104200041d086033602000f0b20004180023b0104200041d086033602000f0b20004180023b010420004190ce003602000f0b4100210202400240200141086a280200417f6a220341024b0d0041a0c21e2101024020030e03020000020b4101210241a08d0621010c010b4190ce0021010b200041013a0005200020023a0004200020013602000f0b410121024100210302400240200141086a2d0000417f6a220441014b0d0041c0843d2101024020040e020200020b4100210141012103410021020c010b4190ce0021010b200020023a0005200020033a0004200020013602000f0b20004180023b0104200041c0843d3602000f0b20004180023b010420004190ce003602000f0b02400240200141086a2d0000417f6a220341054b0d004101210141a08d06210202400240024020030e06040101000102040b4100210141c0843d21020c030b4100210141a0c21e21020c020b4100210141c096b10221020c010b410021014190ce0021020b200041013a0005200020013a0004200020023602000f0b02400240024020012d0004417f6a220341064b0d004101210241c096b102210120030e0702010000000000020b410021020b4190ce0021010b200041013a0005200020023a0004200020013602000f0b024002402001280204417f6a220441024b0d00410021014101210241002103024020040e03020100020b4101210241002101410121030c010b41012103410021024190ce0021010b200020033a0005200020023a0004200020013602000f0b02402001280204417f6a220141034b0d00024002400240024020010e0400010203000b20004180023b0104200041d086033602000f0b20004180023b010420004190ce003602000f0b200041013b0104200041003602000f0b200041013b0104200041003602000f0b20004180023b010420004190ce003602000b9ac20106017f037e127f017e127f057e23004190056b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e110001020304050607080b0f101112131415000b200341ec036a4101360200200342013702dc03200341d09dc6003602d803200341043602c401200341849ec6003602c0012003200341c0016a3602e803200341d8036a41c494c6001038000b200141306a2903002104200141286a29030021052001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410f6a2d000021112001410d6a2f000021122001410c6a2d00002113200141086a2802002114200141076a2d00002115200141056a2f00002116200141046a2d0000211720012d000121182002411a6a2901002119200241196a2d0000211a200241186a2d0000211b200241166a2f0100211c200241156a2d0000211d200241146a2d0000211e200241126a2f0100211f200241116a2d00002120200241106a2d000021212002410e6a2f010021222002410d6a2d000021232002410c6a2d000021242002410a6a2f01002125200241096a2d00002126200241046a2d0000212741022128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002128200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472202841ff01717221020240202b450d00410f212841aab0c000212a024020020e05000c0d4243000b2025410874202672202441187472212a202241087420237220214118747221284101212141012123410121220c430b20032019370388012003201a3a0087012003201b3a0086012003201c3b0184012003201d3a0083012003201e3a0082012003201f3b018001200320203a007f200320213a007e200320223b017c200320233a007b200320243a007a200320253b0178200320263a007720032002360073200320273a0072200320293b0170200341f8026a41086a220241c6acc500ad4280808080f000841003222841086a290000370300200320282900003703f8022028102320034190036a41086a2002290300370300200320032903f80237039003200241f1acc500ad4280808080e000841003222841086a290000370300200320282900003703f80220281023200341c0016a41086a2002290300370300200320032903f8023703c001200341b0046a200341f0006a10ac0141c00010212202450d142002200329039003370000200241086a20034190036a41086a290300370000200220032903c001370010200241186a200341c0016a41086a290300370000200220032903b004370020200241286a200341b0046a41086a290300370000200241306a200341c0046a290300370000200241386a200341b0046a41186a29030037000041012121200341186a200241c00041014100410010b8012003280218212820021023024020284101470d00419e95c600212a4114212841012123410121220c430b0240201741ff01714101460d0020164180fe037141087621280c3d0b200341d8036a201441067610bc0220032802d803212a0240024020032802e0032014413f7122024b0d00410021020c010b202a20024105746a22022f0000221641087621282002290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b211020022d000a211120022f0008211220022d000721132002280003211420022d00022115410121020b024020032802dc03450d00202a10230b20020d3c41aabac600212a410e212841012123410121220c420b200141106a2903002106200141086a29030021042002411a6a2901002119200241196a2d0000212a200241186a2d0000212b200241166a2f01002121200241156a2d00002122200241146a2d00002123200241126a2f01002124200241116a2d00002125200241106a2d000021262002410e6a2f010021142002410d6a2d0000211a2002410c6a2d0000211b2002410a6a2f0100211c200241096a2d0000211d200241046a2d0000211e41022128200241026a2f0100211f0240024020022d00000d0020022d00014101470d00200241056a2d00002128200241066a2f01002120200241086a2d00002102410021270c010b4101212741002102410021200b200320193703f0032003202a3a00ef032003202b3a00ee03200320213b01ec03200320223a00eb03200320233a00ea03200320243b01e803200320253a00e703200320263a00e603200320143b01e4032003201a3a00e3032003201b3a00e2032003201c3b01e0032003201d3a00df032003201e3a00da032003201f3b01d8032003202041ffff0371410874200241187472202841ff01717222023600db0302402027450d00410f212841aab0c000212a20020e05070a0b4041070b200341b0046a41186a200341d8036a41186a290300370300200341b0046a41106a200341d8036a41106a290300370300200341b0046a41086a200341d8036a41086a290300370300200320032903d8033703b004200341d8036a200341b0046a10b804410121020240024020032d00d8034101460d00410b212841b295c600212a0c010b200341ba036a20032d00db033a0000200341c0016a41086a200341ec036a290200370300200341cd016a200341f1036a290000370000200320032f00d9033b01b8032003200341e4036a2902003703c001200341d8036a41086a28020021284100210220032802dc03212a0b200341d8026a41026a222b200341b8036a41026a2d00003a000020034190036a41086a2221200341c0016a41086a29030037030020034190036a41106a200341c0016a41106a290300370300200320032f01b8033b01d802200320032903c0013703900320020d4020034183016a2021290300370000200341f0006a41186a2003419d036a290000370000200320032f01d8023b0170200320283600772003202a360073200320032903900337007b2003202b2d00003a0072200341d8036a200341f0006a10f20320032802f8032202450d3a200341ee016a20032d0086043a0000200341f3016a20032d008b043a0000200341e4016a20032902fc03370200200341c0016a410c6a200341d8036a410c6a3502003e0200200341c0016a41186a200341d8036a41186a290300222c370300200341c0016a412f6a200341d8036a412f6a280000360000200341c0016a41c4006a200341d8036a41c4006a290200370200200341c0016a41346a200341d8036a41346a290200370200200341c0016a413c6a200341d8036a413c6a290200370200200320032902dc033702c401200320032903e803222d3703d001200320032802d8033602c001200320023602e001200320034184046a2f01003b01ec012003200341a4046a28020036028c02200341206a200341b0046a10940202402003290320221920032903c001222e7d222f201956200341206a41086a2903002205200341c0016a41086a29030022307d2019202e54ad7d221920055620192005511b0d0020032004202f202f200456201920065620192006511b22021b2204202d7c22053703d001200341d8016a2006201920021b2219202c7c2005200454ad7c37030020032004202e7c22063703c0012003201920307c2006200454ad7c3703c801200341f0006a200341c0016a10b9040b20032802e401450d3920032802e00110230c390b200141106a2903002106200141086a29030021042002411a6a2901002119200241196a2d00002114200241186a2d0000211a200241166a2f0100211b200241156a2d0000211c200241146a2d0000211d200241126a2f0100211e200241116a2d0000211f200241106a2d000021212002410e6a2f010021222002410d6a2d000021232002410c6a2d000021242002410a6a2f01002125200241096a2d00002126200241046a2d0000212041022128200241026a2f010021270240024020022d00000d0020022d00014101470d00200241056a2d00002128200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472202841ff01717221020240202b450d00410f212841aab0c000212a024020020e05000a0b4041000b2025410874202672202441187472212a202241087420237220214118747221284101212141012123410121220c410b2003201937038801200320143a0087012003201a3a0086012003201b3b0184012003201c3a0083012003201d3a0082012003201e3b0180012003201f3a007f200320213a007e200320223b017c200320233a007b200320243a007a200320253b0178200320263a007720032002360073200320203a0072200320273b0170200341d8036a200341f0006a10f20320032802f8032202450d39200341e4016a20032802fc03222b360200200341ee016a20032d0086043a0000200341f3016a20032d008b043a0000200341c0016a410c6a200341d8036a410c6a3502003e0200200341c0016a41186a200341d8036a41186a2903002219370300200341c0016a41286a200341d8036a41286a2802002228360200200341c0016a412f6a200341d8036a412f6a280000360000200341c0016a41c4006a200341d8036a41c4006a290200370200200341c0016a41346a200341d8036a41346a290200370200200341c0016a413c6a200341d8036a413c6a290200370200200320032902dc033702c401200320032903e80322053703d001200320032802d8033602c001200320023602e001200320034184046a2f01003b01ec012003200341a4046a28020036028c0202402028411f4d0d0041cd95c600212a41232128202b450d40200210234101212141012123410121220c410b200520042005200454201920065420192006511b22021b22042019200620021b220684500d36200341c0016a41186a4200201920067d2005200454ad7d222e200520047d222f4280c8afa025544100202e501b22281b37030020034200202f20281b3703d001200341d8036a41186a4200370300200341d8036a41106a22214200370300200341d8036a41086a222a4200370300200342003703d803200341f8026a41086a220241c6acc500ad4280808080f000841003222b41086a2900003703002003202b2900003703f802202b1023202a2002290300370300200320032903f802222e3703602003202e3703d803200241b0fac500ad4280808080a001841003222b41086a2900003703002003202b2900003703f802202b1023202120032903f802222e370300200341b0046a41086a202a290300370300200341b0046a41106a202e370300200341b0046a41186a20022903003703002003202e3703b803200320032903d8033703b004200341306a200341b0046a4120108f012003280230212a2003280234212b20032802e801220220032802e401470d35200241016a22212002490d33200241017422222021202220214b1b2221ad42187e222e422088a70d33202ea7222241004e0d340c330b2002411a6a2901002119200241196a2d00002114200241186a2d0000211a200241166a2f0100211b200241156a2d0000211c200241146a2d0000211d200241126a2f0100211e200241116a2d0000211f200241106a2d000021212002410e6a2f010021222002410d6a2d000021232002410c6a2d000021242002410a6a2f01002125200241096a2d00002126200241046a2d0000212041022128200241026a2f010021270240024020022d00000d0020022d00014101470d00200241056a2d00002128200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472202841ff01717221020240202b450d00410f212841aab0c000212a024020020e0500090a3f40000b2025410874202672202441187472212a202241087420237220214118747221284101212141012123410121220c400b200320193703a803200320143a00a7032003201a3a00a6032003201b3b01a4032003201c3a00a3032003201d3a00a2032003201e3b01a0032003201f3a009f03200320213a009e03200320223b019c03200320233a009b03200320243a009a03200320253b019803200320263a0097032003200236009303200320203a009203200320273b019003200341d8036a20034190036a10f20320032802f8032224450d38200341d8036a41186a2202290300212e2003419c046a290200212c20034198046a2f0100212620034194046a2f0100211420034190046a2f0100211a2003418c046a2f0100211b20034187046a280000211c20034184046a2f0100211d20034180046a2802002125200341e4036a350200210420032903e803212f20032d009b04211e20032d009a04211f20032d009704212020032d009604212720032d009304212920032d009204211620032d008f04210720032d008e04210820032d008b04210920032d008604210a20032802fc03210b20033502d803210520032902dc03210620024200370300200341d8036a41106a222b420037030041082123200341d8036a41086a22284200370300200342003703d803200341f8026a41086a220241c6acc500ad4280808080f000841003222a41086a2900003703002003202a2900003703f802202a102320282002290300370300200320032903f8022219370360200320193703d803200241b0fac500ad4280808080a001841003222a41086a2900003703002003202a2900003703f802202a1023202b20032903f8022219370300200341b0046a41086a2028290300370300200341b0046a41106a2019370300200341b0046a41186a2002290300370300200320193703b803200320032903d8033703b004200341c0006a200341b0046a4120108f01410021222004422086200642208884211920052006422086842106024002400240202541186c2202450d002003280244410020032802401b212b202420026a2121200241686a2128202421020340200241086a290300210520022903002104202b200241106a280200222a490d024200201920057d2006200454ad7d2205200620047d2204200656200520195620052019511b222a1b211942002004202a1b2106202841686a2128200241186a22022021470d000b0b0240200b0d004100212a0c020b202410234100212a0c010b411810212223450d13202320043703002023202a360210202320053703080240024020280d00410121224101212a0c010b200241186a210c202541186c20246a41686a210d410121224101212a0340200c210202400340200241086a290300210520022903002104202b200241106a2802002228490d014200201920057d2006200454ad7d2205200620047d2204200656200520195620052019511b22281b21194200200420281b2106200241186a22022021470d000c030b0b0240202a2022470d00202241016a222a2022490d3620224101742225202a2025202a4b1b222aad42187e222d422088a70d36202da722254100480d360240024020220d002025102121230c010b2023202241186c2025102521230b2023450d170b200241186a210c2023202241186c6a222520053703082025200437030020252028360210202241016a2122200d2002470d000b0b200b450d00202410230b2003419c046a202c3702002003419b046a201e3a00002003419a046a201f3a000020034198046a20263b010020034197046a20203a000020034196046a20273a000020034194046a20143b010020034193046a20293a000020034192046a20163a000020034190046a201a3b01002003418f046a20073a00002003418e046a20083a00002003418c046a201b3b01002003418b046a20093a000020034187046a201c36000020034186046a200a3a000020034180046a2022360200200341fc036a202a3602002003202f3703e803200341f0036a202e370300200320063703d8032003201d3b018404200320233602f803200320193703e0030240202f202e844200520d002022450d1a0b20034190036a200341d8036a10b9040c310b200141046a28020021292002411a6a2901002119200241196a2d0000212a200241186a2d0000212b200241166a2f01002121200241156a2d00002122200241146a2d00002123200241126a2f01002124200241116a2d00002125200241106a2d000021262002410e6a2f010021142002410d6a2d0000211a2002410c6a2d0000211b2002410a6a2f0100211c200241096a2d0000211d200241046a2d0000211e41022128200241026a2f0100211f0240024020022d00000d0020022d00014101470d00200241056a2d00002128200241066a2f01002120200241086a2d00002102410021270c010b4101212741002120410021020b200320193703c8042003202a3a00c7042003202b3a00c604200320213b01c404200320223a00c304200320233a00c204200320243b01c004200320253a00bf04200320263a00be04200320143b01bc042003201a3a00bb042003201b3a00ba042003201c3b01b8042003201d3a00b7042003201e3a00b2042003201f3b01b0042003202041ffff0371410874202841ff01717220024118747222023600b30402402027450d00410f212841aab0c000212a024020020e050008093e3f000b20032800b704212a20032800bb0421284101212141012123410121220c3f0b200341b8026a41186a200341b0046a41186a29030037030041102128200341b8026a41106a200341b0046a41106a290300370300200341b8026a41086a200341b0046a41086a290300370300200320032903b0043703b802200341d8036a200341b8026a10f20320032802f8032202450d2f200341ee016a20032d0086043a0000200341f3016a20032d008b043a0000200341e4016a20032902fc03370200200341c0016a410c6a200341d8036a410c6a3502003e0200200341c0016a41186a200341d8036a41186a222b290300370300200341c0016a412f6a200341d8036a412f6a280000360000200341c0016a41c4006a200341d8036a41c4006a290200370200200341c0016a41346a200341d8036a41346a290200370200200341c0016a413c6a200341d8036a413c6a290200370200200320032902dc033702c401200320032903e8033703d001200320032802d8033602c001200320023602e0012003200341d8036a412c6a2f01003b01ec012003200341a4046a28020036028c02200341c0016a412c6a222a10ae04200341f8026a41086a220241c6acc500ad4280808080f000841003222841086a290000370300200320282900003703f80220281023200341e0006a41086a22212002290300370300200320032903f802370360200241e7acc500ad4280808080a001841003222841086a290000370300200320282900003703f80220281023200341b8036a41086a22282002290300370300200320032903f8023703b803200341d8036a202a10ac0141c00010212202450d1320022003290360370000200241086a2021290300370000200220032903b803370010200241186a2028290300370000200220032903d803370020200241286a200341d8036a41086a290300370000200241306a200341d8036a41106a290300370000200241386a202b290300370000200341f0006a200241c00010a501024020032d007422284102470d002003202a36028c05200341d8036a10ad0420034190036a20032802d803222820032802e003108a01024020032802dc03450d00202810230b024020032d0090030d00200341d8036a10ad0420032802d8032128200320032802e0033602b404200320283602b004202a200341b0046a10f50120032802dc03450d2f202810230c2f0b200341d0036a200341a9036a290000370300200341c8036a200341a1036a290000370300200341b8036a41086a20034199036a29000037030020032003290091033703b803200341f8026a200341b8036a10a401200341d8036a20032802f8022228200328028003222a10a501024020032d00dc034102470d00200341003602a0022003420137039802200341d8026a41146a410f360200200341e4026a410c3602002003410736028405200341c6acc500360280052003410c3602dc022003410a360264200341e7acc5003602602003200341f8026a3602e8022003200341e0006a3602e002200320034180056a3602d802200320034198026a3602f804200341b0046a41146a4103360200200342033702b404200341e4ddc0003602b0042003200341d8026a3602c004200341f8046a41b8a3c500200341b0046a102e1a20033502a002422086200335029802841008200328028c05212a200341b0046a10ad0420032802b0042128200320032802b8043602dc02200320283602d802202a200341d8026a10f501024020032802b404450d00202810230b0240200328029c02450d0020032802980210230b20032802fc02450d2f20032802f80210230c2f0b20032802d803212b200341b0046a200341d8036a41047241c20010dc041a20034198026a41086a200341d2046a410020032d00d1044101461b3602002003202b3602980220032003418c056a36029c02200341003602e002200342013703d80220034198026a200341d8026a10af0120034198026a410472200341d8026a10aa0120032802dc02212b202aad4220862028ad8420033502e00242208620032802d8022228ad8410020240202b450d00202810230b024020032802fc02450d0020032802f80210230b200328028c05212a200341d8036a10ad0420032802d8032128200320032802e0033602b404200320283602b004202a200341b0046a10f501024020032802dc03450d00202810230b200341d8026a41086a200341b8036a41086a290300370300200341d8026a41106a200341b8036a41106a290300370300200341d8026a41186a200341b8036a41186a290300370300200320032903b8033703d8024101212a410021280c2f0b200341b0046a41186a2003418d016a290000370300200341b0046a41106a20034185016a290000370300200341b0046a41086a200341fd006a290000370300200341d8026a41086a2003419e016a290100370300200341d8026a41106a200341a6016a290100370300200341d8026a41186a200341ae016a290100370300200320032900753703b004200320034196016a2901003703d80220034195016a2d0000212a0c2e0b2001410c6a280200211b200141086a280200211a200141046a28020021142002411a6a2901002119200241196a2d0000211c200241186a2d0000211d200241166a2f0100211e200241156a2d0000211f200241146a2d00002120200241126a2f01002127200241116a2d00002129200241106a2d000021212002410e6a2f010021222002410d6a2d000021232002410c6a2d000021242002410a6a2f01002125200241096a2d00002126200241046a2d0000211641022128200241026a2f010021070240024020022d00000d0020022d00014101470d00200241056a2d00002128200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b4100212a410021020b202a41ffff0371410874202841ff01717220024118747221020240202b450d00410f212841aab0c000212a024002400240024020020e05000102032f000b2025410874202672202441187472212a202241087420237220214118747221280c2e0b410e212841aabac600212a0c2d0b411321284197b0c000212a0c2c0b411121284186b0c000212a0c2b0b200320193703d0022003201c3a00cf022003201d3a00ce022003201e3b01cc022003201f3a00cb02200320203a00ca02200320273b01c802200320293a00c702200320213a00c602200320223b01c402200320233a00c302200320243a00c202200320253b01c002200320263a00bf02200320023600bb02200320163a00ba02200320073b01b802200341d8036a200341b8026a10f203024020032802f80322020d004110212841bd95c600212a0c2b0b200341f0006a41246a20032802fc03222b3602002003419e016a20032d0086043a0000200341a3016a20032d008b043a0000200341f0006a410c6a200341d8036a410c6a3502003e0200200341f0006a41186a200341d8036a41186a290300370300200341f0006a41286a200341d8036a41286a280200360200200341f0006a412f6a200341d8036a412f6a280000360000200341f0006a41c4006a200341d8036a41c4006a290200370200200341f0006a41346a200341d8036a41346a290200370200200341f0006a413c6a200341d8036a413c6a290200370200200320032902dc03370274200320032903e80337038001200320032802d80336027020032002360290012003200341d8036a412c6a2f01003b019c012003200341a4046a2802003602bc01201b0d1e41f095c600212a41172128410121020c290b2002411a6a2901002119200241196a2d0000212a200241186a2d0000212b200241166a2f01002121200241156a2d00002122200241146a2d00002123200241126a2f01002124200241116a2d00002125200241106a2d000021262002410e6a2f010021142002410d6a2d0000211a2002410c6a2d0000211b2002410a6a2f0100211c200241096a2d0000211d200241046a2d0000211e41022128200241026a2f0100211f0240024020022d00000d0020022d00014101470d00200241056a2d00002128200241066a2f01002120200241086a2d00002102410021270c010b4101212741002120410021020b200320193703f0032003202a3a00ef032003202b3a00ee03200320213b01ec03200320223a00eb03200320233a00ea03200320243b01e803200320253a00e703200320263a00e603200320143b01e4032003201a3a00e3032003201b3a00e2032003201c3b01e0032003201d3a00df032003201e3a00da032003201f3b01d8032003202041ffff0371410874202841ff01717220024118747222023600db0302402027450d00410f212841aab0c000212a20020e050205063b3c020b200341f0006a41186a200341d8036a41186a29030037030041102128200341f0006a41106a200341d8036a41106a290300370300200341f0006a41086a200341d8036a41086a290300370300200320032903d803370370200341d8036a200341f0006a10f20320032802f8032202450d2d200341ee016a20032d0086043a0000200341f3016a20032d008b043a0000200341e4016a222820032902fc03370200200341c0016a410c6a200341d8036a410c6a3502003e0200200341c0016a41186a200341d8036a41186a290300370300200341c0016a412f6a200341d8036a412f6a280000360000200341c0016a41c4006a200341d8036a41c4006a290200370200200341c0016a41346a200341d8036a41346a290200370200200341c0016a413c6a200341d8036a413c6a290200370200200320032902dc033702c401200320032903e8033703d001200320032802d8033602c001200320023602e0012003200341d8036a412c6a2f01003b01ec012003200341a4046a28020036028c02200341c0016a412c6a220210ac04200210ae042028280200450d3420032802e00110234100212a0c370b20012d000121292002411a6a2901002119200241196a2d0000212a200241186a2d0000212b200241166a2f01002121200241156a2d00002122200241146a2d00002123200241126a2f01002124200241116a2d00002125200241106a2d000021262002410e6a2f010021142002410d6a2d0000211a2002410c6a2d0000211b2002410a6a2f0100211c200241096a2d0000211d200241046a2d0000211e41022128200241026a2f0100211f0240024020022d00000d0020022d00014101470d00200241056a2d00002128200241066a2f01002120200241086a2d00002102410021270c010b4101212741002120410021020b200320193703f0032003202a3a00ef032003202b3a00ee03200320213b01ec03200320223a00eb03200320233a00ea03200320243b01e803200320253a00e703200320263a00e603200320143b01e4032003201a3a00e3032003201b3a00e2032003201c3b01e0032003201d3a00df032003201e3a00da032003201f3b01d8032003202041ffff0371410874202841ff01717220024118747222023600db032027450d01410f212841aab0c000212a20020e05000304393a000b20032800df03212a20032800e30321284101212141012123410121220c3a0b200341f0006a41186a200341d8036a41186a29030037030041102128200341f0006a41106a200341d8036a41106a290300370300200341f0006a41086a200341d8036a41086a290300370300200320032903d803370370200341d8036a200341f0006a10f20320032802f8032202450d2a200341ee016a20032d0086043a0000200341f3016a20032d008b043a0000200341e4016a222820032902fc03370200200341c0016a410c6a200341d8036a410c6a3502003e0200200341c0016a41186a200341d8036a41186a290300370300200341c0016a412f6a200341d8036a412f6a280000360000200341c0016a41c4006a200341d8036a41c4006a290200370200200341c0016a41346a200341d8036a41346a290200370200200341c0016a413c6a200341d8036a413c6a290200370200200320032902dc033702c401200320032903e8033703d001200320032802d8033602c001200320023602e0012003200341d8036a412c6a2f01003b01ec012003200341a4046a28020036028c02200341c0016a412c6a202910c8042028280200450d3120032802e00110234100212a0c340b2001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410f6a2d000021112001410d6a2f000021122001410c6a2d00002113200141086a2802002114200141076a2d00002115200141056a2f00002116200141046a2d000021172002411a6a2901002119200241196a2d0000211a200241186a2d0000211b200241166a2f0100211c200241156a2d0000211d200241146a2d0000211e200241126a2f0100211f200241116a2d00002120200241106a2d000021212002410e6a2f010021222002410d6a2d000021232002410c6a2d000021242002410a6a2f01002125200241096a2d00002126200241046a2d0000212741022128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002128200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b4100212a410021020b202a41ffff0371410874202841ff0171722002411874722102202b450d02410f212841aab0c000212a024020020e050001023738000b2025410874202672202441187472212a202241087420237220214118747221284101212141012123410121220c380b410e212841aabac600212a4101212141012123410121220c370b411321284197b0c000212a4101212141012123410121220c360b200320193703b0022003201a3a00af022003201b3a00ae022003201c3b01ac022003201d3a00ab022003201e3a00aa022003201f3b01a802200320203a00a702200320213a00a602200320223b01a402200320233a00a302200320243a00a202200320253b01a002200320263a009f022003200236009b02200320273a009a02200320293b019802200341d8036a20034198026a10b804410121020240024020032d00d8034101460d00410b212841b295c600212a0c010b200341ba036a20032d00db033a0000200341c0016a41086a200341ec036a290200370300200341cd016a200341f1036a290000370000200320032f00d9033b01b8032003200341e4036a2902003703c001200341d8036a41086a28020021284100210220032802dc03212a0b200341d8026a41026a222b200341b8036a41026a2d00003a000020034190036a41086a2221200341c0016a41086a29030037030020034190036a41106a200341c0016a41106a290300370300200320032f01b8033b01d802200320032903c0013703900320020d34200341cb026a2021290300370000200341d0026a2003419d036a290000370000200320032f01d8023b01b802200320283600bf022003202a3600bb0220032003290390033700c3022003202b2d00003a00ba020240201741ff01714101460d0020164180fe037141087621280c160b200341d8036a201441067610bc0220032802d803212a0240024020032802e0032014413f7122024b0d00410021020c010b202a20024105746a22022f0000221641087621282002290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b211020022d000a211120022f0008211220022d000721132002280003211420022d00022115410121020b024020032802dc03450d00202a10230b20020d1541aabac600212a410e21284101212141012123410121220c350b41012121024020022d000120022d000072450d004186b0c000212a4111212841012123410121220c350b200141046a280200212b200341d8036a41186a4200370300200341d8036a41106a22224200370300200341d8036a41086a22284200370300200342003703d803200341f8026a41086a220241c6acc500ad4280808080f000841003222a41086a2900003703002003202a2900003703f802202a102320282002290300370300200320032903f8022219370360200320193703d80320024198f7c500ad4280808080e001841003222a41086a2900003703002003202a2900003703f802202a1023202220032903f8022219370300200341b0046a41086a2028290300370300200341b0046a41106a2019370300200341b0046a41186a2002290300370300200320193703b803200320032903d8033703b0042003202b3602d803200341b0046aad4280808080800484200341d8036aad4280808080c0008410024100212a0c300b20022d000120022d0000720d12200341d8036a41186a4200370300200341d8036a41106a222b4200370300200341d8036a41086a22284200370300200342003703d803200341f8026a41086a220241c6acc500ad4280808080f000841003222a41086a2900003703002003202a2900003703f802202a102320282002290300370300200320032903f8022219370360200320193703d803200241e8fbc500ad42808080808001841003222a41086a2900003703002003202a2900003703f802202a1023202b20032903f8022219370300200341b0046a41086a2028290300370300200341b0046a41106a2019370300200341b0046a41186a2002290300370300200320193703b803200320032903d8033703b00441012121410110212202450d09200241023a0000200341b0046aad42808080808004842002ad428080808010841002200210234100212a0c2f0b20022d000120022d0000720d11200341d8036a41186a4200370300200341d8036a41106a222b4200370300200341d8036a41086a22284200370300200342003703d803200341f8026a41086a220241c6acc500ad4280808080f000841003222a41086a2900003703002003202a2900003703f802202a102320282002290300370300200320032903f8022219370360200320193703d803200241e8fbc500ad42808080808001841003222a41086a2900003703002003202a2900003703f802202a1023202b20032903f8022219370300200341b0046a41086a2028290300370300200341b0046a41106a2019370300200341b0046a41186a2002290300370300200320193703b803200320032903d8033703b00441012121410110212202450d09200241013a0000200341b0046aad42808080808004842002ad428080808010841002200210234100212a0c2e0b200141086a280200212b200141046a2802002122024020022d000120022d000072450d004186b0c000212a411121284100212341012121202b450d2020221023410121220c320b2001410c6a2802002128200341d8036a41186a4200370300200341d8036a41106a22234200370300200341d8036a41086a222a4200370300200342003703d803200341f8026a41086a220241c6acc500ad4280808080f000841003222141086a290000370300200320212900003703f80220211023202a2002290300370300200320032903f8022219370360200320193703d803200241e4f7c500ad4280808080d001841003222141086a290000370300200320212900003703f80220211023202320032903f8022219370300200341b0046a41086a202a290300370300200341b0046a41106a2019370300200341b0046a41186a2002290300370300200320193703b803200320032903d8033703b004200341003602e003200342013703d8032028200341d8036a105c02402028450d00202841057421282022210203402002200341d8036a1071200241206a2102202841606a22280d000b0b20032802dc032102200341b0046aad428080808080048420033502e00342208620032802d8032228ad84100202402002450d00202810230b41012121202b450d0f202210230c0f0b200341d8036a41186a200141196a29000037030041112128200341d8036a41106a200141116a290000370300200341d8036a41086a200141096a290000370300200320012900013703d8034186b0c000212a20022d000120022d0000720d2f200342f3e885db96cddbb3203703b004200341c0016a41186a4200370300200341c0016a41106a22214200370300200341c0016a41086a22024200370300200342003703c001200341f8026a41086a222a41c4fbc400ad4280808080e000841003222b41086a2900003703002003202b2900003703f802202b10232002202a290300370300200320032903f8023703c001202a41f9bcc000ad4280808080e000841003222b41086a2900003703002003202b2900003703f802202b1023202120032903f8022219370300200341f0006a41086a22212002290300370300200341f0006a41106a2019370300200341f0006a41186a202a290300370300200320193703b803200320032903c001370370200341d8006a200341f0006a4120108f014100212a2003200328025c410020032802581b36029003200341c0016a200341d8036a10df0220032802c401212220032802c001212b20032802c8012123200341d4016a200341b0046a3602002003202b20234105746a3602cc012003202b3602c801200320223602c4012003202b3602c001200320034190036a3602d001200341f0006a200341c0016a10870120022021280200360200200320032903703703c001200341d8036a200341c0016a10e002200341d8036a10dd024101212141012123410121220c300b20022d000120022d0000720d0e200341d8036a41186a4200370300200341d8036a41106a222b4200370300200341d8036a41086a22284200370300200342003703d803200341f8026a41086a220241c6acc500ad4280808080f000841003222a41086a2900003703002003202a2900003703f802202a102320282002290300370300200320032903f8022219370360200320193703d803200241e8fbc500ad42808080808001841003222a41086a2900003703002003202a2900003703f802202a1023202b20032903f8022219370300200341b0046a41086a2028290300370300200341b0046a41106a2019370300200341b0046a41186a2002290300370300200320193703b803200320032903d8033703b00441012121410110212202450d07200241033a0000200341b0046aad42808080808004842002ad428080808010841002200210234100212a0c2b0b200141106a28020021282001410c6a280200211d200141086a280200211a200141046a280200211e02400240024020022d0000222a4101470d00200241046a2d00004101460d02200241096a21020c010b200241016a21020b202a4104460d00202a20022d00007241ff0171450d0041b696c600212a410a21284100212241012121201d450d0c201a10230c0c0b201a2028410041202028676b109703200341f8026a41086a220241c6acc500ad4280808080f000841003222a41086a2900003703002003202a2900003703f802202a1023200341e0006a41086a222b2002290300370300200320032903f8023703602002419cb2c500ad42808080808002841003222a41086a2900003703002003202a2900003703f802202a1023200341b8036a41086a222a2002290300370300200320032903f8023703b8032003201e360270200341c0016a41186a2221200341f0006aad22064280808080c000841001220241186a290000370300200341c0016a41106a2222200241106a290000370300200341c0016a41086a2223200241086a290000370300200320022900003703c00120021023200341d8036a41186a22242021290300370300200341d8036a41106a22212022290300370300200341d8036a41086a22222023290300370300200320032903c0013703d80341c00010212202450d0720022003290360370000200241086a202b290300370000200220032903b803370010200241186a202a290300370000200220032903d803370020200241286a2022290300370000200241306a2021290300370000200241386a2024290300370000200341d8036a200241c00010a80320032902dc03211920032802d803212a2002102320194200202a1b2119202a4108202a1b211b2028410274221c450d0941002128417f21224100212b4100212a03400240201a20286a2802002221202a4f0d00418796c600212a410f21280c0c0b0240202b20216a22022019422088a72223490d00419696c600212a412021280c0c0b201b200241d8006c6a220228022c212620022802202114200241306a2802002124200241246a28020021252002200241d8006a202220236a20216b41d8006c10dd041a02402025450d00201410230b02402024450d00202610230b202a41016a212a20194280808080707c2119202241016a2122202b417f6a212b201c202841046a2228470d000c0a0b0b41c00041011030000b411841081030000b202541081030000b41c00041011030000b410141011030000b410141011030000b410141011030000b41c00041011030000b200341b0046a41186a2003419c046a290200370300200341b0046a41106a20034194046a290200370300200341b0046a41086a2003418c046a29020037030020032003290284043703b004200342f3e885db96cddbb3203703d802200341c0016a41186a4200370300200341c0016a41106a222b4200370300200341c0016a41086a22024200370300200342003703c001200341f8026a41086a222841c4fbc400ad4280808080e000841003222a41086a2900003703002003202a2900003703f802202a102320022028290300370300200320032903f8023703c001202841f9bcc000ad4280808080e000841003222a41086a2900003703002003202a2900003703f802202a1023202b20032903f8022219370300200341f0006a41086a222a2002290300370300200341f0006a41106a2019370300200341f0006a41186a2028290300370300200320193703b803200320032903c001370370200341386a200341f0006a4120108f012003200328023c410020032802381b3602b803200341c0016a200341b0046a10df0220032802c401212b20032802c001212820032802c8012121200341d4016a200341d8026a3602002003202820214105746a3602cc01200320283602c8012003202b3602c401200320283602c0012003200341b8036a3602d001200341f0006a200341c0016a1087012002202a280200360200200320032903703703c001200341b0046a200341c0016a10e002200341b0046a10dd020c170b0240201d450d00201a10230b200341f8026a41086a220241c6acc500ad4280808080f000841003222841086a290000370300200320282900003703f80220281023200341e0006a41086a222a2002290300370300200320032903f8023703602002419cb2c500ad42808080808002841003222841086a290000370300200320282900003703f80220281023200341b8036a41086a22282002290300370300200320032903f8023703b8032003201e360270200341c0016a41186a222b20064280808080c000841001220241186a290000370300200341c0016a41106a2221200241106a290000370300200341c0016a41086a2222200241086a290000370300200320022900003703c00120021023200341d8036a41186a2223202b290300370300200341d8036a41106a222b2021290300370300200341d8036a41086a22212022290300370300200320032903c0013703d8030240024041c00010212202450d0020022003290360370000200241086a202a290300370000200220032903b803370010200241186a2028290300370000200220032903d803370020200241286a2021290300370000200241306a202b290300370000200241386a2023290300370000200341d8036a201b2019422088a7222810be042002ad428080808080088420033502e00342208620032802d803222aad841002024020032802dc03450d00202a10230b2002102302402028450d00202841d8006c2128201b41306a210203400240200241746a280200450d00200241706a28020010230b02402002280200450d002002417c6a28020010230b200241d8006a2102202841a87f6a22280d000b0b410121212019a7450d01201b10230c010b41c00041011030000b41002122410121230c070b0240201d450d00201a10230b02402019422088a7222b450d00201b41306a2102202b41d8006c212b03400240200241746a280200450d00200241706a28020010230b02402002280200450d002002417c6a28020010230b200241d8006a2102202b41a87f6a222b0d000b0b41002122410121212019a7450d00201b1023410121230c230b410121230c220b410021230c030b4186b0c000212a411121284101212141012123410121220c200b200320063703f002200320073a00ef02200320083a00ee02200320093b01ec022003200a3a00eb022003200b3a00ea022003200c3b01e8022003200d3a00e7022003200e3a00e6022003200f3b01e402200320103a00e302200320113a00e202200320123b01e002200320133a00df02200320143600db02200320153a00da0220032028410874201641ff0171723b01d802200341f8026a41086a220241c6acc500ad4280808080f000841003222841086a290000370300200320282900003703f80220281023200341e0006a41086a222a2002290300370300200320032903f802370360200241f7acc500ad4280808080e000841003222841086a290000370300200320282900003703f80220281023200341b8036a41086a22282002290300370300200320032903f8023703b803200341d8036a200341d8026a10ac0102400240024041c00010212202450d0020022003290360370000200241086a202a290300370000200220032903b803370010200241186a2028290300370000200220032903d803370020200241286a200341d8036a41086a290300370000200241306a200341e8036a290300370000200241386a200341d8036a41186a290300370000200341d0006a200241c00041014100410010b8012003280250212820021023024020284101470d0041d494c600212a411921284101212141012123410121220c230b200341d8026a200341b8026a412010de04450d1a20034198026a200341d8026a10c904200341f8026a41086a220241c6acc500ad4280808080f000841003222841086a290000370300200320282900003703f8022028102320034190036a41086a222a2002290300370300200320032903f80237039003200241f7acc500ad4280808080e000841003222841086a290000370300200320282900003703f80220281023200341c0016a41086a22282002290300370300200320032903f8023703c001200341b0046a200341b8026a10ac0141c00010212202450d012002200329039003370000200241086a202a290300370000200220032903c001370010200241186a2028290300370000200220032903b004370020200241286a200341b0046a41086a290300370000200241306a200341b0046a41106a2222290300370000200241386a200341b0046a41186a2223290300370000200341d8036a200241c00010ad03024020032802f803222a450d002002ad428080808080088410050b20034190036a41186a2224200341d8036a41186a222529030037030020034190036a41106a2226200341d8036a41106a221429030037030020034190036a41086a222b200341d8036a41086a2228290300370300200341c0016a41086a222120034184046a221e290200370300200341c0016a41106a221a2003418c046a221f290200370300200341c0016a41186a221b20034194046a2220290200370300200341c0016a41206a221c2003419c046a2227290200370300200341c0016a41286a221d200341a4046a2229280200360200200320032903d80337039003200320032902fc033703c001200341b0046a41086a2216202b2903003703002022202629030037030020232024290300370300202820212903003703002014201a2903003703002025201b290300370300200341d8036a41206a2223201c290300370300200341d8036a41286a201d28020036020020032003290390033703b004200320032903c0013703d8030240202a450d00200341b8036a41186a2224200341b0046a41186a2225290300370300200341b8036a41106a2226200341b0046a41106a2214290300370300200341b8036a41086a221a2016290300370300200341f0006a41086a221b2028290300370300200341f0006a41106a221c200341d8036a41106a2222290300370300200341f0006a41186a221d200341d8036a41186a2216290300370300200341f0006a41206a22072023290300370300200341f0006a41286a2223200341d8036a41286a2208280200360200200320032903b0043703b803200320032903d8033703702002102320162024290300370300202220262903003703002028201a290300370300200341fc036a2003290370370200201e201b290300370200201f201c2903003702002020201d2903003702002027200729030037020020292023280200360200200320032903b8033703d8032003202a3602f803200341f8026a41086a220241c6acc500ad4280808080f000841003222841086a290000370300200320282900003703f80220281023202b2002290300370300200320032903f80237039003200241f7acc500ad4280808080e000841003222841086a290000370300200320282900003703f8022028102320212002290300370300200320032903f8023703c001200341b0046a200341d8026a10ac0141c0001021222a450d03202a200329039003370000202a41086a20034190036a41086a290300370000202a20032903c001370010202a41186a200341c0016a41086a290300370000202a20032903b004370020202a41286a200341b0046a41086a290300370000202a41306a2014290300370000202a41386a2025290300370000200341003602c801200342013703c00120034184046a200341c0016a10712003200341d8036a3602b004200341b0046a200341c0016a10c301200320223602b004200341b0046a200341c0016a10c30120032802f803210220082802002228200341c0016a105c02402028450d002002202841186c6a21280340200320023602b004200341b0046a200341c0016a10c301200241106a200341c0016a10af012028200241186a2202470d000b0b20032802c4012102202aad428080808080088420033502c80142208620032802c0012228ad84100202402002450d00202810230b202a102320032802fc03450d1b20032802f80310234100212a0c1e0b200210234100212a0c1d0b41c00041011030000b41c00041011030000b41c00041011030000b200341003a00b803200341103602a00320032014201b41246c6a36029c0320032014360298032003201a3602940320032014360290032003200341b8036a3602a403200341d8036a20034190036a10bb020240024020032d00d8034101460d00200328029c03212a2003280298032102024003400240202a2002470d002002212b0c020b20022d00002128200241246a222b210220284102470d000b0b2003202b36029803410021234101212202402003280294030d00410021020c020b2003280290031023410021020c010b412010212222450d03202220032900d903370000202241186a200341f1036a290000370000202241106a200341e9036a290000370000202241086a200341e1036a290000370000200341b0046a41106a20034190036a41106a290300370300200341b0046a41086a20034190036a41086a29030037030020032003290390033703b004200341d8036a200341b0046a10bb020240024020032d00d8030d0041012102410121230c010b200341d8036a4101722128410221214120212b41012102410121230340200341c0016a41186a2224202841186a290000370300200341c0016a41106a2225202841106a290000370300200341c0016a41086a2226202841086a290000370300200320282900003703c001024020022023470d00200241016a222a2002490d152021202a2021202a4b1b222341ffffff3f712023470d152023410574222a4100480d150240024020020d00202a102121220c010b2022202b202a102521220b2022450d0c0b2022202b6a222a20032903c001370000202a41186a2024290300370000202a41106a2025290300370000202a41086a2026290300370000202141026a2121202b41206a212b200241016a2102200341d8036a200341b0046a10bb0220032d00d8030d000b0b20032802bc04212b20032802b8042128024003400240202b2028470d00202b21210c020b20282d0000212a202841246a22212128202a4102470d000b0b200320213602b80420032802b404450d0020032802b00410230b024020032d00b803450d002023450d0a202210230c0a0b2022450d09200341d8036a41186a22244200370300200341d8036a41106a22214200370300200341d8036a41086a222b4200370300200342003703d803200341f8026a41086a222841c6acc500ad4280808080f0008422061003222a41086a2900003703002003202a2900003703f802202a1023202b2028290300370300200320032903f8022219370360200320193703d803202841b0fac500ad4280808080a001841003222a41086a2900003703002003202a2900003703f802202a1023202120032903f8022219370300200341b0046a41086a202b290300370300200341b0046a41106a2019370300200341b0046a41186a2028290300370300200320193703b803200320032903d8033703b004200341c8006a200341b0046a4120108f01200320023602a0022003202336029c022003202236029802200341003a00a8022003200328024c410020032802481b3602a402200341f0006a412c6a222210ac04202820061003220241086a290000370300200320022900003703f80220021023200341e0006a41086a22232028290300370300200320032903f802370360202841cdacc500ad4280808080a001841003220241086a290000370300200320022900003703f80220021023200341b8036a41086a22022028290300370300200320032903f8023703b803200341d8036a202210ac0141c0001021222a450d03202a2003290360370000202a41086a2023290300370000202a20032903b803370010202a41186a2002290300370000202a20032903d803370020202a41286a202b290300370000202a41306a2021290300370000202a41386a2024290300370000200341c0016a202a41c00010a8010240024020032d00d0014102460d00200341b0046a41086a200341dd016a290000370300200341b0046a41106a200341e5016a290000370300200341b0046a41186a200341ed016a290000370300200341d8026a41086a200341fe016a290100370300200341d8026a41106a20034186026a290100370300200341d8026a41186a2003418e026a2901003703002003200341d5016a2900003703b0042003200341f6016a2901003703d802200341f5016a2d0000210220032d00d401212820032802c401450d0120032802c00110230c010b2003202236028c03200341d8036a10af0420034190036a20032802d803220220032802e003108a01024020032802dc03450d00200210230b0240024020032d0090030d00200341d8036a10af0420032802d8032102200320032802e0033602b404200320023602b0042022200341b0046a10f501024020032802dc03450d00200210230b410021020c010b200341b8036a41186a200341a9036a290000370300200341b8036a41106a200341a1036a290000370300200341b8036a41086a20034199036a29000037030020032003290091033703b803200341e0006a200341b8036a10a701200341d8036a2003280260222b2003280268222110a801024020032d00e8034102470d002003410036028003200342013703f802200341d8026a41146a410f360200200341e4026a410c360200200341073602fc04200341c6acc5003602f8042003410c3602dc022003410a36028405200341cdacc500360280052003200341e0006a3602e802200320034180056a3602e0022003200341f8046a3602d8022003200341f8026a36028c05200341b0046a41146a4103360200200342033702b404200341e4ddc0003602b0042003200341d8026a3602c0042003418c056a41b8a3c500200341b0046a102e1a20033502800342208620033502f802841008200328028c032128200341b0046a10af0420032802b0042102200320032802b8043602dc02200320023602d8022028200341d8026a10f501024020032802b404450d00200210230b024020032802fc02450d0020032802f80210230b02402003280264450d00200328026010230b410021020c010b200341b0046a200341d8036a41146a41c20010dc041a20032d00d1042102200341d8026a41106a200341d8036a41106a280200360200200341d8026a41086a200341d8036a41086a2903002219370300200341d8026a41186a200341d2046a410020024101461b360200200320032903d80322063703d80220032003418c036a3602ec022003410036028003200342013703f8022019a72202200341f8026a105c2006a7212202402002450d00200241057421282022210203402002200341f8026a1071200241206a2102202841606a22280d000b0b20032802e40221230240024020032802fc02222820032802800322026b4104490d0020032802f80221280c010b200241046a22242002490d14202841017422022024200220244b1b22024100480d140240024020280d002002102121280c010b20032802f80220282002102521280b2028450d07200320023602fc02200320283602f80220032802800321020b2003200241046a36028003202820026a202336000020032d00e80221230240024020032802fc022003280280032202460d0020032802f80221280c010b200241016a22282002490d14200241017422242028202420284b1b22244100480d140240024020020d002024102121280c010b20032802f80220022024102521280b2028450d08200320243602fc02200320283602f80220032802800321020b2003200241016a36028003202820026a20233a0000200341d8026a41146a200341f8026a10aa0120032802fc0221022021ad422086202bad8420033502800342208620032802f8022228ad84100202402002450d00202810230b024020032802dc02450d00202210230b02402003280264450d00200328026010230b200328028c032128200341d8036a10af0420032802d8032102200320032802e0033602b404200320023602b0042028200341b0046a10f501024020032802dc03450d00200210230b200341d8026a41086a200341b8036a41086a290300370300200341d8026a41106a200341b8036a41106a290300370300200341d8026a41186a200341b8036a41186a290300370300200320032903b8033703d802410121020b410021280b200341fd036a20023a0000200341fe036a20032903d802370100200341e5036a200341b0046a41086a290300370000200341ed036a200341b0046a41106a290300370000200341f5036a200341b0046a41186a29030037000020034186046a200341d8026a41086a2903003701002003418e046a200341d8026a41106a29030037010020034196046a200341d8026a41186a290300370100200320283a00dc03200320032903b0043700dd03200320034198026a3602d803200341003602c801200342013703c001200328029802210220032802a0022228200341c0016a105c02402028450d002028410574212803402002200341c0016a1071200241206a2102202841606a22280d000b0b20032802a402212b0240024020032802c401222820032802c80122026b4104490d0020032802c00121280c010b200241046a22212002490d12202841017422022021200220214b1b22024100480d120240024020280d002002102121280c010b20032802c00120282002102521280b2028450d07200320023602c401200320283602c00120032802c80121020b2003200241046a3602c801202820026a202b36000020032d00a802212b0240024020032802c40120032802c8012202460d0020032802c00121280c010b200241016a22282002490d12200241017422212028202120284b1b22214100480d120240024020020d002021102121280c010b20032802c00120022021102521280b2028450d08200320213602c401200320283602c00120032802c80121020b2003200241016a3602c801202820026a202b3a0000200341d8036a410472200341c0016a10a90120032802c4012102202aad428080808080088420033502c80142208620032802c0012228ad84100202402002450d00202810230b202a10230240200328029c02450d0020032802980210230b0240200328029401450d0020032802900110230b41002121410121230b410121220b4100212a0c1c0b412041011030000b41c00041011030000b200241011030000b202441011030000b200241011030000b202141011030000b202a41011030000b41aabac600212a410e212841002102200328029401212b0b0240202b450d0020032802900110230b20020d004101212341002121410121220c130b4101212341002121201a450d00201410230b410121220c110b4100212a410021280b200341fd036a202a3a0000200341fe036a20032903d802370100200341e5036a200341b0046a41086a290300370000200341ed036a200341b0046a41106a290300370000200341f5036a200341b0046a41186a29030037000020034186046a200341d8026a41086a2903003701002003418e046a200341d8026a41106a29030037010020034196046a200341d8026a41186a290300370100200320283a00dc03200320293602d803200320032903b0043700dd032003410036027820034201370370200341d8036a200341f0006a10af01200341d8036a410472200341f0006a10a901200328027421282002ad428080808080088420033502784220862003280270222aad84100202402028450d00202a10230b2002102320032802e401450d0720032802e00110234100212a0c0a0b41bd95c600212a4101212141012123410121220c0e0b20032802fc03450d0520032802f80310234100212a0c080b102a000b0240024020020d002022102121020c010b20032802e001200241186c2022102521020b2002450d02200320213602e401200320023602e00120032802e80121020b20032802e001200241186c6a22022019200620281b37030820022005200420281b3703002002202b4100202a1b360210200320032802e80141016a3602e801200341f0006a200341c0016a10b90420032802e401212b0b202b450d0120032802e00110234100212a0c040b202241081030000b4100212a0c020b41bd95c600212a411021284101212141012123410121220c060b200320063703d801200320073a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320133a00c701200320143600c301200320153a00c20120032028410874201641ff0171723b01c001200341f8026a41086a220241c6acc500ad4280808080f000841003222841086a290000370300200320282900003703f80220281023200341e0006a41086a222a2002290300370300200320032903f802370360200241f7acc500ad4280808080e000841003222841086a290000370300200320282900003703f80220281023200341b8036a41086a22282002290300370300200320032903f8023703b803200341d8036a200341c0016a10ac0141c00010212202450d0220022003290360370000200241086a202a290300370000200220032903b803370010200241186a2028290300370000200220032903d803370020200241286a200341d8036a41086a290300370000200241306a200341e8036a290300370000200241386a200341d8036a41186a290300370000200341106a200241c00041014100410010b8012003280210212820021023024020284101470d0041d494c600212a4119212841012123410121220c060b024020054280c8afa0255441002004501b450d0041ed94c600212a4131212841012123410121220c060b200341f0006a200341c0016a10c904200341f0006a201810c8042003200341f0006a109402200341086a2903002119200329030021064100212a20034180046a410036020020034186046a20032d00723a000020034187046a20032800733600002003418b046a20032d00773a00002003419c046a2003290388013702002003418c046a200329037837020020034194046a200329038001370200200341f0036a201920042006200554201920045420192004511b22021b2219370300200320032f01703b018404200342083703f803200320193703e00320032006200520021b22193703d803200320193703e803200341c0016a200341d8036a10b904200341fc036a280200450d0020032802f80310230b410121210b41012123410121220c030b41c00041011030000b411121284186b0c000212a0b4101212141012123410121220b0240024020012d0000222b417f6a2202410f4b0d0002400240024020020e1004030303040003030403030301040302040b2021450d03200141086a280200450d03200141046a28020010230c030b2023450d02200141086a280200450d02200141046a28020010230c020b2022450d012001410c6a280200450d01200141086a28020010230c010b0240202b410f4b0d004101202b7441bebf03710d010240202b4106460d00202b410d470d01200141086a280200450d02200141046a28020010230c020b200141086a280200450d01200141046a28020010230c010b2001410c6a280200450d00200141086a28020010230b200020283602042000202a36020020034190056a24000b8b0501087f230041a0016b22022400200241086a220341c6acc500ad4280808080f000841003220441086a290000370300200220042900003703002004102320024180016a41086a220520032903003703002002200229030037038001200341f7acc500ad4280808080e000841003220441086a2900003703002002200429000037030020041023200241d0006a41086a22062003290300370300200220022903003703502002200110ac01024041c00010212204450d0020042002290380013700002004200229035037001020042002290000370020200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241106a2201290000370000200441386a200241186a22072900003700002002200441c00010ad032005200329030037030020024180016a41106a2205200129030037030020024180016a41186a2201200729030037030020062002412c6a290200370300200241d0006a41106a2206200241346a290200370300200241d0006a41186a22072002413c6a290200370300200241f0006a2208200241c4006a290200370300200241d0006a41286a2209200241cc006a280200360200200220022903003703800120022002290224370350024020022802202203450d00200020022903800137030020002002290350370224200041186a2001290300370300200041106a2005290300370300200041086a20024180016a41086a2903003703002000412c6a200241d0006a41086a290300370200200041346a20062903003702002000413c6a2007290300370200200041c4006a2008290300370200200041cc006a20092802003602000b2000200336022020041023200241a0016a24000f0b41c00041011030000b4d01017f230041206b22002400200041146a410136020020004201370204200041d09dc6003602002000410436021c200041849ec6003602182000200041186a360210200041b09ec6001038000b3400200041be99c60036020420004100360200200041146a4102360200200041106a41bc9dc500360200200041086a42093702000b130020004101360204200041dc99c5003602000b130020004101360204200041b096c5003602000b3400200041f0dfc40036020420004100360200200041146a4101360200200041106a418c95c500360200200041086a42133702000b130020004104360204200041a88ec5003602000b3400200041e3e0c40036020420004100360200200041146a4101360200200041106a41848dc500360200200041086a42043702000b1300200041043602042000419080c5003602000b130020004103360204200041a0fdc4003602000b3001017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200241103600000b3001017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200241033600000b3b01017f02404110102122020d00411041011030000b2002420037000820024280c8afa025370000200042908080808002370204200020023602000b4f01027f230041106b2202240002404101102122030d00410141011030000b200341003a0000200041086a4101360200200241013602042002200336020020002002290300370200200241106a24000b3101017f02404108102122020d00410841011030000b20004288808080800137020420002002360200200242b8173700000bea1102077f027e230041106b22022400200241003602082002420137030041062002105c0240024002400240024002400240024002400240024002400240024002400240024020022802042203200228020822046b4106490d00200441066a2105200228020021030c010b200441066a22052004490d0f200341017422062005200620054b1b22064100480d0f0240024020030d002006102121030c010b200228020020032006102521030b2003450d0120022006360204200220033602000b20022005360208200320046a220441002800d1cf44360000200441046a41002f00d5cf443b0000410d2002105c0240024020022802042203200228020822066b410d490d002006410d6a2104200228020021050c010b2006410d6a22042006490d0f200341017422052004200520044b1b22074100480d0f0240024020030d002007102121050c010b200228020020032007102521050b2005450d022002200736020420022005360200200721030b20022004360208200520066a220641002900d7cf44370000200641056a41002900dccf4437000002400240200320046b4104490d00200441046a21060c010b200441046a22062004490d0f200341017422072006200720064b1b22074100480d0f0240024020030d002007102121050c010b200520032007102521050b2005450d0320022007360204200220053602000b20022006360208200520046a41023600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f200541017422062003200620034b1b22034100480d0f0240024020050d002003102121050c010b200228020020052003102521050b2005450d0420022003360204200220053602000b2002200441046a360208200520046a41fc073600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f200541017422062003200620034b1b22034100480d0f0240024020050d002003102121050c010b200228020020052003102521050b2005450d0520022003360204200220053602000b2002200441046a360208200520046a4100360000410c2002105c41e4cfc4002104034020042d0000210602400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422072003200720034b1b22074100480d100240024020050d002007102121030c010b200228020020052007102521030b2003450d0720022007360204200220033602000b2002200541016a360208200320056a20063a0000200441016a2d0000210602400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422072003200720034b1b22074100480d100240024020050d002007102121030c010b200228020020052007102521030b2003450d0820022007360204200220033602000b2002200541016a360208200320056a20063a0000200441026a2d0000210602400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422072003200720034b1b22074100480d100240024020050d002007102121030c010b200228020020052007102521030b2003450d0920022007360204200220033602000b2002200541016a360208200320056a20063a0000200441036a2d0000210602400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422072003200720034b1b22074100480d100240024020050d002007102121030c010b200228020020052007102521030b2003450d0a20022007360204200220033602000b2002200541016a360208200320056a20063a0000200441046a2d0000210602400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422072003200720034b1b22074100480d100240024020050d002007102121030c010b200228020020052007102521030b2003450d0b20022007360204200220033602000b2002200541016a360208200320056a20063a0000200441056a2d0000210602400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422072003200720034b1b22074100480d100240024020050d002007102121030c010b200228020020052007102521030b2003450d0c20022007360204200220033602000b2002200541016a360208200320056a20063a0000200441066a2d0000210602400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422072003200720034b1b22074100480d100240024020050d002007102121030c010b200228020020052007102521030b2003450d0d20022007360204200220033602000b2002200541016a360208200320056a20063a0000200441076a2d0000210602400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422072003200720034b1b22074100480d100240024020050d002007102121030c010b200228020020052007102521030b2003450d0e20022007360204200220033602000b2002200541016a360208200320056a20063a0000200441086a28020021060240024020022802042203200228020822056b4104490d00200228020021030c010b200541046a22072005490d10200341017422082007200820074b1b22074100480d100240024020030d002007102121030c010b200228020020032007102521030b2003450d0f20022007360204200220033602000b2002200541046a360208200320056a20063600002004410c6a220441f4d0c400470d000b200235020821092002350200210a200241106a2400200a2009422086840f0b200641011030000b200741011030000b200741011030000b200341011030000b200341011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b200741011030000b102a000bd31a05037f017e047f037e017f230041800b6b22022400024002402001450d00200220003602100c010b200241013602100b20022001360214200241b8086a200241106a10e1020240024020022802bc08450d00200241186a200241b8086a41fc0010dc041a20024198016a200241186a41fc0010dc041a20024198016a10830402402002280298012201450d00200241b8086a2001417f6a108901200241b8086a200241a8016a412010de040d000240024020024190026a28020022030d004100210341042104410021010c010b024002402003ad420c7e2205422088a70d002005a722014100480d0020022802880221002001102122040d01200141041030000b102a000b200341c8026c210620034103742107200421010340200220003602e004200241b8086a200241e0046a10b803200141086a200241b8086a41086a280200360200200120022903b8083702002001410c6a2101200041c8026a2100200641b87d6a22060d000b200741786a41037641016a21010b200220013602e804200220033602e404200220043602e004200241b8086a200241e0046a1084040240200241e8016a2201200241b8086a412010de04450d00418ebac600ad4280808080e0018410082001ad4280808080800484100f200241b8086aad4280808080800484100f0b02402001200241b8086a412010de040d002002418c026a28020021082002280288022107200228029002210620024198026a20024198016a41f00010dc041a2007200641c8026c6a2100200228029802210920072101024002402006450d00200241e0046a41f0006a210441b8bac600ad4280808080d00184210a2007210102400340200241d0076a200141e80010dc041a200141e8006a290300210520024188036a200141f0006a41d80110dc041a20054203510d01200241e0046a200241d0076a41e80010dc041a200220053703c805200420024188036a41d80110dc041a2002200241e0046a3602a807200241b8086a200241a8076a10b80320022802c0082106024020022802bc08450d0020022802b80810230b200241b8086a200241e0046a41c80210dc041a200241003602b807200241a8076a200241b8086a2006200241b8076a10850420022d00a8074101460d03024020022d00b40722064102460d0020023100b607210520023100b507210b20023502b007210c20022802ac072103200a100802402006450d00200b100e0b2005100e2003450d00200c4220862003ad8410080b200141c8026a22012000470d000b200021010c010b200141c8026a21010b20012000460d04200241d0096a2106200241b8086a41f0006a2103034020024188036a200141e80010dc041a200141e8006a2903002105200241b8086a200141f0006a41d80110dc041a20054203510d05200241d0076a20024188036a41e80010dc041a200241e0046a200241b8086a41d80110dc041a200241b8086a200241d0076a41e80010dc041a200220053703a0092003200241e0046a41d80110dc041a200610db01200141c8026a22012000470d000c050b0b200241086a20022f00a90720022d00ab074110747210860420022903082105200241c4086a42dd808080f01e370200200241323602cc08200241cca2c6003602c008200220053703b808200241b8086a102b000b41b4a2c600102b000b419ca2c600102b000b20024194036a4104360200200241f4046a4102360200200242023702e404200241f89fc5003602e0042002410436028c03200241f09fc500360288032002410036029c01200241c4b8c60036029801200220024188036a3602f004200220024198016a36029003200241e0046a4188a0c5001038000b02402008450d00200710230b200241d4bcc0004110108f01200228020421030240200228020022044101470d0041d4bcc000ad428080808080028410050b200241b8086a41186a4200370300200241b8086a41106a22074200370300200241b8086a41086a22014200370300200242003703b808200241e0046a41086a220041c4fbc400ad4280808080e000841003220641086a290000370300200220062900003703e0042006102320012000290300370300200220022903e0043703b80820024188036a41086a22084188cec000ad4280808080e001841003220641086a2900003703002002200629000037038803200610232007200229038803220537030020002001290300370300200241e0046a41106a2005370300200241e0046a41186a2008290300370300200220053703d007200220022903b8083703e00420022003410020041b3602b808200241e0046aad4280808080800484200241b8086aad4280808080c0008410022009109002200241b8086a109b01200220024198026a410c6a28020022073602c807200228029c0221032002200241b8086a410c6a28020022013602cc07024020072001470d0002402007450d0020022802bc0821044100210641b6c9c300ad4280808080c0028421050340024002400240024002400240024002400240200320066a22012d00002208200420066a22002d0000470d000240024002400240024020080e050001020304000b20032004460d0c200141016a200041016a412010de040d040c070b024020032004460d00200141016a280000200041016a280000470d040b200141106a2802002208200041106a280200470d03200141086a2802002209200041086a280200220d460d092009200d200810de040d030c090b024020032004460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a2802002209200041086a280200220d460d072009200d200810de040d020c070b024020032004460d00200141016a280000200041016a280000470d020b200141106a2802002208200041106a280200470d01200141086a2802002209200041086a280200220d460d052009200d200810de040d010c050b2001410c6a28020022082000410c6a280200470d00200141046a2802002209200041046a280200220d460d012009200d200810de04450d010b20051008200241e0046a200110b00120023502e80442208620022802e0042208ad84100f024020022802e404450d00200810230b200241e0046a200010b00120023502e80442208620022802e0042208ad84100f024020022802e404450d00200810230b20012d000020002d00002208470d0620080e050105040300010b2001410c6a28020022082000410c6a280200470d05200141046a2802002201200041046a2802002200460d0620012000200810de04450d060c050b20032004460d050b200141016a200041016a412010de040d030c040b024020032004460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a2802002201200041086a2802002200460d0320012000200810de040d020c030b024020032004460d00200141016a280000200041016a280000470d020b200141106a2802002208200041106a280200470d01200141086a2802002201200041086a2802002200460d0220012000200810de040d010c020b024020032004460d00200141016a280000200041016a280000470d010b200141106a2802002208200041106a280200470d00200141086a2802002201200041086a2802002200460d0120012000200810de04450d010b41c4a3c600102b000b200641246a21062007417f6a22070d000b0b024020024198026a41306a2201200241b8086a41306a2200412010de04450d00418ebac600ad4280808080e0018410082001ad4280808080800484100f2000ad4280808080800484100f0b024020012000412010de04450d0041dca3c600102b000b024020022802c4082200450d0020022802bc082101200041246c210003400240024020012d0000220641034b0d0002400240024020060e0404000102040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b0240200241c0086a280200450d0020022802bc0810230b024020022802a4022200450d00200228029c022101200041246c210003400240024020012d0000220641034b0d0002400240024020060e0404000102040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b0240200241a0026a280200450d00200228029c0210230b200241800b6a240042010f0b20024188036a41146a410d36020020024188036a410c6a410e360200200241d0076a41146a4103360200200242033702d407200241acb6c6003602d0072002410e36028c032002200241c8076a3602b8072002200241cc076a3602a807200242043703f004200242013702e404200241aca3c6003602e004200220024188036a3602e0072002200241e0046a360298032002200241a8076a360290032002200241b8076a36028803200241d0076a41b4a3c6001038000bdc5a090e7f047e017f027e067f017e057f057e0e7f230022012102200141e0016b4160712203240002400240024002400240024002400240024002400240024002400240024002402000410c6a28020041246c22040d004104210541002106410021070c010b200028020421014104210541002106410021070340024020012d00004101470d00200141106a2802002208417f4c0d0d200141086a2802002109200141016a280000210a0240024020080d004101210b0c010b20081021220b450d040b200b2009200810dc04210b200341086a41026a220c200341c8006a41026a2d00003a0000200341a0016a41086a220d20034180016a41086a290200370300200320032f00483b010820032003290280013703a001024020062007470d00200641016a22092006490d112006410174220e2009200e20094b1b2207ad42247e220f422088a70d11200fa722094100480d110240024020060d002009102121050c010b2005200641246c2009102521050b2005450d050b2005200641246c6a220941013a00002009200a360001200920083600102009200836000c2009200b360008200920032f01083b0005200941076a200c2d00003a0000200920032903a0013702142009411c6a200d290300370200200641016a21060b200141246a21012004415c6a22040d000b0b200341003602a00141d4bcc000ad4280808080800284200341a0016aad22104280808080c000842211100220034180016a41186a2204420037030020034180016a41106a2208420037030020034180016a41086a220942003703002003420037038001200341386a41086a220141c4fbc400ad4280808080e00084220f1003220a41086a2900003703002003200a290000370338200a1023200920012903003703002003200329033822123703282003201237038001200141f9bcc000ad4280808080e000841003220a41086a2900003703002003200a290000370338200a1023200820032903382212370300200341086a41086a220b2009290300370300200341086a41106a220c2012370300200341086a41186a220d20012903003703002003201237036020032003290380013703082003200028020022133602a001200341086aad2214428080808080048422122011100220044200370300200842003703002009420037030020034200370380012001200f1003220a41086a2900003703002003200a290000370338200a102320092001290300370300200320032903382211370328200320113703800120014197bdc000ad4280808080e000841003220a41086a2900003703002003200a290000370338200a1023200420012903002211370300200b2009290300370300200c20032903382215370300200d2011370300200320153703602003200329038001370308200341203602a4012003200341086a3602a00120052006200341a0016a108d0120044200370300200842003703002009420037030020034200370380012001200f1003220a41086a2900003703002003200a290000370338200a1023200920012903003703002003200329033822113703282003201137038001200141ffbcc000ad4280808080a001841003220a41086a2900003703002003200a290000370338200a1023200420012903002211370300200b2009290300370300200c20032903382215370300200d2011370300200320153703602003200329038001370308200341203602a4012003200341086a3602a001200041106a2216200341a0016a10b1032001200f1003220a41086a2900003703002003200a290000370338200a1023200341286a41086a2217200129030037030020032003290338370328200141f0bcc000ad42808080809001841003220a41086a2900003703002003200a290000370338200a1023200341e0006a41086a220e20012903003703002003200329033837036020032013417f6a360208200341a0016a41186a221320144280808080c000841001220a41186a290000370300200341a0016a41106a2218200a41106a290000370300200341a0016a41086a2219200a41086a2900003703002003200a2900003703a001200a1023200420132903003703002008201829030037030020092019290300370300200320032903a0013703800141c0001021220a450d02200a2003290328370000200a41086a2017290300370000200a2003290360370010200a41186a200e290300370000200a200329038001370020200a41286a2009290300370000200a41306a2008290300370000200a41386a20042903003700002003200a3602a001200341c0003602a4012016200341a0016a10b103200a102320044200370300200842003703002009420037030020034200370380012001200f1003220a41086a2900003703002003200a290000370338200a102320092001290300370300200320032903382211370328200320113703800120014189bdc000ad4280808080e001841003220a41086a2900003703002003200a290000370338200a1023200e2001290300221137030020032003290338221437036020082014370000200841086a220a2011370000200b2009290300370300200c2008290300370300200d20042903003703002003200329038001370308200341203602a4012003200341086a3602a001200041d0006a200341a0016a10b10320044200370300200842003703002009420037030020034200370380012001200f1003221641086a2900003703002003201629000037033820161023200920012903003703002003200329033822113703282003201137038001200141c0bdc000ad4280808080e000841003221641086a2900003703002003201629000037033820161023200e2001290300221137030020032003290338221437036020082014370000200a2011370000200b2009290300370300200c2008290300370300200d200429030037030020032003290380013703082012100520044200370300200842003703002009420037030020034200370380012001200f1003221641086a2900003703002003201629000037033820161023200920012903003703002003200329033822113703282003201137038001200141a4d0c000ad4280808080a001841003221641086a2900003703002003201629000037033820161023200e2001290300221137030020032003290338221437036020082014370000200a2011370000200b2009290300370300200c2008290300370300200d20042903003703002003200329038001370308201210052001200f1003220a41086a2900003703002003200a290000370338200a10232017200129030037030020032003290338370328200141c6bdc000ad4280808080b001841003220a41086a2900003703002003200a290000370338200a1023200e200129030037030020032003290338370360201342011001220141186a2900003703002018200141106a2900003703002019200141086a290000370300200320012900003703a00120011023200420132903003703002008201829030037030020092019290300370300200320032903a0013703800141c00010212201450d0320012003290328370000200141086a200341286a41086a29030037000020012003290360370010200141186a200341e0006a41086a2903003700002001200329038001370020200141286a20034180016a41086a2204290300370000200141306a20034180016a41106a220a290300370000200141386a20034180016a41186a220b2903003700002001ad4280808080800884100a200110232000280200211a200341a0016a41186a4200370300200341a0016a41106a220c4200370300200341a0016a41086a22094200370300200342003703a001200341386a41086a22014191fdc400ad42808080809001841003220841086a290000370300200320082900003703382008102320092001290300370300200320032903383703a001200141a9e0c100ad4280808080f001841003220841086a2900003703002003200829000037033820081023200c2003290338220f37030020042009290300370300200a200f370300200b20012903003703002003200f370360200320032903a00137038001200341086a20034180016a109102024002400240200328020822040d00410421044100210141002109410021084100210e4100211b410421160c010b200328020c21010240200341086a41086a280200220941024f0d00410421164100210e200921084100211b0c010b2004280208210e2004280204211b2004280200211620042004410c6a2009417f6a2209410c6c10dd041a41012108200941014b0d010b0340024020082001470d00200141016a22082001490d102001410174220a2008200a20084b1b2208ad420c7e220f422088a70d10200fa7220a4100480d100240024020010d00200a102121040c010b20042001410c6c200a102521040b2004450d0720082101200921080b20042008410c6c6a2208410036020820084204370200200941016a2209210820094102490d000b0b20034180016a41086a2009360200200320013602840120032004360280010240024020040d00200341086a41186a4200370300200341086a41106a22044200370300200341086a41086a2209420037030020034200370308200341386a41086a22014191fdc400ad42808080809001841003220841086a29000037030020032008290000370338200810232009200129030037030020032003290338220f3703602003200f370308200141a9e0c100ad4280808080f001841003220841086a290000370300200320082900003703382008102320042003290338220f370300200341a0016a41086a2009290300370300200341a0016a41106a200f370300200341a0016a41186a20012903003703002003200f370328200320032903083703a0012010428080808080048410050c010b200341086a41186a4200370300200341086a41106a220d4200370300200341086a41086a220a420037030020034200370308200341386a41086a22084191fdc400ad42808080809001841003220b41086a2900003703002003200b290000370338200b1023200a200829030037030020032003290338220f3703602003200f370308200841a9e0c100ad4280808080f001841003220b41086a2900003703002003200b290000370338200b1023200d2003290338220f370300200341a0016a41086a200a290300370300200341a0016a41106a200f370300200341a0016a41186a20082903003703002003200f370328200320032903083703a0012003412036020c2009410c6c21082003200341a0016a36020820034180016a200341086a10732004210903400240200941046a280200450d00200928020010230b2009410c6a2109200841746a22080d000b2001450d00200410230b200341a0016a41186a22044200370300200341a0016a41106a220a4200370300200341a0016a41086a22094200370300200342003703a001200341386a41086a22014191fdc400ad42808080809001841003220841086a290000370300200320082900003703382008102320092001290300370300200320032903383703a0012001419adfc100ad4280808080a001841003220841086a2900003703002003200829000037033820081023200341e0006a41086a2001290300220f370300200320032903382212370360200c2012370000200c41086a200f37000020034180016a41086a200929030037030020034180016a41106a200a29030037030020034180016a41186a2004290300370300200320032903a00137038001200341a0016a20034180016a10910220032902a401420020032802a00122091b220f422088a72200410c6c21012009410420091b220d41746a2109410121080240034020082113024020010d00410021080c020b200141746a2101201341016a2108200941146a21042009410c6a220a210920042802002204450d000b20034180016a41086a200a2802002201410c6a29020037030020034190016a200141146a29020037030020032001290204370380012001411c6a290200211c2001280200210b2001200141246a2004417f6a220941246c10dd041a200a41086a2009360200410121080b2003200d3602702003200f37027402400240200d0d00200341086a41186a4200370300200341086a41106a220a4200370300200341086a41086a2209420037030020034200370308200341386a41086a22014191fdc400ad42808080809001841003220441086a29000037030020032004290000370338200410232009200129030037030020032003290338220f3703602003200f3703082001419adfc100ad4280808080a001841003220441086a2900003703002003200429000037033820041023200a2003290338220f370300200341a0016a41086a2009290300370300200341a0016a41106a200f370300200341a0016a41186a20012903003703002003200f370328200320032903083703a0012010428080808080048410050c010b200fa7210a200341086a41186a4200370300200341086a41106a22184200370300200341086a41086a2209420037030020034200370308200341386a41086a22014191fdc400ad42808080809001841003220441086a29000037030020032004290000370338200410232009200129030037030020032003290338220f3703602003200f3703082001419adfc100ad4280808080a001841003220441086a290000370300200320042900003703382004102320182003290338220f370300200341a0016a41086a2009290300370300200341a0016a41106a200f370300200341a0016a41186a20012903003703002003200f370328200320032903083703a0012003412036020c2003200341a0016a360208200341f0006a200341086a107302402000450d002000410c6c2109200d210103400240200141046a280200450d00200128020010230b2001410c6a2101200941746a22090d000b0b200a450d00200d10230b200341c8006a41086a20034180016a41086a290300370300200341c8006a41106a20034180016a41106a2903003703002003200329038001370348024002402008450d00200e41246c2101201621090340024020010d00410121180c030b2001415c6a210120092802002108200941246a21092008200b470d000b0b410021180b200341a0016a41186a22044200370300200341a0016a41106a220a4200370300200341a0016a41086a22094200370300200342003703a001200341386a41086a22014191fdc400ad42808080809001841003220841086a290000370300200320082900003703382008102320092001290300370300200320032903383703a00120014182fdc400ad4280808080a001841003220841086a2900003703002003200829000037033820081023200341e0006a41086a2001290300220f370300200320032903382212370360200c2012370000200c41086a200f37000020034180016a41086a200929030037030020034180016a41106a200a29030037030020034180016a41186a2004290300370300200320032903a00137038001200341a0016a20034180016a4120108b0220032802a001210120032902a401210f200341086a41106a2208200341c8006a41106a290300370300200341086a41086a2204200341c8006a41086a290300370300200320032903483703082001410420011b211d200f420020011b220fa7211e02400240200f422088a7220c410274220a41027522012016200e41246c6a221920166b41246d6a22092001490d00200920186a221f20094f0d010b201d200a6a21172003200b360284012003201836028001200320032903083703880120032004290300370290012003200829030037039801412821094100211f41042120410021214100210e2016210a201d21000240410041ff01710e03080900080b410021010c090b4100212102400240201f0d00410421204100211f410421010c010b201fad422c7e220f422088a70d0e200fa722014100480d0e200110212220450d06202021010b2003200b36028401200320183602800120032003290308370388012003200341106a290300370290012003200341186a290300370398010240200c450d00200c4102742208417c6a410276210a20202101201d2109034020092802002104200141246a4102360200200120043602002001412c6a2101200941046a21092008417c6a22080d000b200a41016a21210b0240201e450d00201d10230b024020192016460d00200341b8016a2108200341b0016a2104200341a8016a210a2016210903402009280200210b20082009411c6a2902003703002004200941146a290200370300200a2009410c6a2902003703002003200941046a2902003703a0012001200b360200200141046a20032903a0013702002001410c6a200a290300370200200141146a20042903003702002001411c6a2008290300370200200141246a42013702002001412c6a2101202141016a2121200941246a22092019470d000b0b0240201b450d00201610230b200329038801211220032903900121112003290398012114200329038001210f200341003602a001200fa74101470d09200f422088a7210920032903b801211520032903b001212220032903a801212320032903a001210f034020152124202221252023212620012009360200200141046a2012370200200141286a2013360200200141246a41013602002001411c6a201c3702002001410c6a2011370200200141146a2014370200200341003602a0012001412c6a2101202141016a2121200fa72108200f422088a7210920032903b801211520032903b001212220032903a801212320032903a001210f20262112202521112024211420084101460d000c0a0b0b200841011030000b200941041030000b41c00041011030000b41c00041011030000b200a41041030000b200141041030000b410121010c010b410221010b034002400240024002400240024002400240024020010e03000104040b200341003602a0012003290398012111200320032903b801370398012003290390012112200320032903b00137039001200329038801210f200320032903a801370388012003290380012114200320032903a0012215370380012014a74101470d042014422088a7210b2015a721180c010b0240024002400240200e41ff01710e03010200010b2019200a470d044102210e0c020b024020172000470d0002402019200a470d004102210e0c030b200a41146a2902002111200a410c6a2902002112200a411c6a2902002122200a290204210f4101210c4102210e200a2101200a41246a210a0c080b4102210c4100210e20002101200041046a21000c070b20172000470d054101210e0b200341003602a0012003290398012111200320032903b801370398012003290390012112200320032903b00137039001200329038801210f200320032903a801370388012003290380012114200320032903a0012215370380012014a74101470d032014422088a7210b2015a721180b4101210c41022104201c21142013210d0c050b200a41146a2902002111200a410c6a2902002112200a411c6a2902002122200a290204210f4101210c4102210e200a2101200a41246a210a0c030b024002400240200e41ff01710e03010200010b2019200a460d02200a41146a2902002111200a410c6a2902002112200a411c6a2902002114200a290204210f200a280200210b4100210d410121044102210e200a41246a210a4101210c0c050b024020172000470d002019200a460d02200a41146a2902002111200a410c6a2902002112200a411c6a2902002114200a290204210f200a280200210b4100210d410121044102210e200a41246a210a4101210c0c050b2000280200210b4102210c410121044100210e200041046a21000c040b20172000460d002000280200210b4102210c4101210e200041046a2100410121040c030b0240201e450d00201d10230b201b450d04201610230c040b4102210c4101210e200021012023210f2024211220252111200041046a21000b2001280200210b41002104200f21232012212420112125202221144100210d0b024002400240024002402021201f470d00024002400240024020040e03010200010b201841014621010c020b0240024002400240200e41ff01710e03010200010b2019200a6b41246d21010c020b417f201720006b41027522012019200a6b41246d6a220820082001491b21010c010b201720006b41027521010b417f200120184101466a220820082001491b21010c010b024002400240200e41ff01710e03010200010b2019200a6b41246d21010c020b417f201720006b41027522012019200a6b41246d6a220820082001491b21010c010b201720006b41027521010b201f417f200141016a220820082001491b6a2201201f490d0a201f41017422082001200820014b1b2201ad422c7e2215422088a70d0a2015a722084100480d0a02400240201f0d002008102121200c010b2020201f412c6c2008102521200b2020450d012001211f0b202020096a2201200d3602002001415c6a220820123702082008200f3702002001417c6a200c360200200141746a2014370200200141586a200b360200200841106a20113702002009412c6a2109202141016a2121200441ff01710e03010203010b200841041030000b410121010c020b410221010c010b410021010c000b0b20214115490d0120214101762227ad422c7e220f422088a70d00200fa72201417f4c0d0002400240024020010d00410421284104210d0c010b200110212228450d012028210d0b202041546a21292020412c6a212a202041fc7e6a212b410421184100212c4100211e410021002021211b0340201b210b4100211b4101210a0240200b417f6a2208450d0002400240024002400240024020202008412c6c6a280200200b412c6c220e20206a41a87f6a2802002201490d00200b417e6a210c202b200e6a21084100211b4100210903400240200c2009470d00200b210a0c080b200941016a21092001200828020022044f210a200841546a210820042101200a0d000b200941016a210a2009417f73200b6a21080c010b202b200e6a210902400340024020084101470d00410021080c020b2008417f6a210820012009280200220449210a200941546a210920042101200a0d000b0b200b2008490d01200b20214b0d03200b20086b220a4101762204450d0020202008412c6c6a21012029200e6a21090340200341a0016a41286a220c200141286a220e280200360200200341a0016a41206a2213200141206a2219290200370300200341a0016a41186a2217200141186a2216290200370300200341a0016a41106a221d200141106a221b290200370300200341a0016a41086a222d200141086a222e290200370300200320012902003703a001200941086a222f290200210f200941106a22302902002112200941186a22312902002111200941206a22322902002114200941286a2233280200213420012009290200370200200e20343602002019201437020020162011370200201b2012370200202e200f3702002033200c28020036020020322013290300370200203120172903003702002030201d290300370200202f202d290300370200200920032903a0013702002001412c6a2101200941546a21092004417f6a22040d000b0b024020080d002008211b0c050b0240200a41094d0d002008211b0c050b200b20214b0d01200b20086b2104202a2008412c6c6a210c0340200b2008417f6a221b490d040240200b201b6b220a4102490d0020202008412c6c6a22012802002020201b412c6c6a220828020022194f0d00200341a0016a41206a2217200841246a290200370300200341a0016a41186a22162008411c6a290200370300200341a0016a41106a221d200841146a290200370300200341a0016a41086a222d2008410c6a2902003703002008290204210f200841286a200141286a2802003602002003200f3703a001200841206a200141206a290200370200200841186a200141186a290200370200200841106a200141106a290200370200200841086a200141086a29020037020020082001290200370200410121090240200a4103490d00200828025820194f0d004102210e200c211303402013220141546a22092001290200370200200941286a200141286a280200360200200941206a200141206a290200370200200941186a200141186a290200370200200941106a200141106a290200370200200941086a200141086a2902003702002004200e2209460d01200941016a210e2001412c6a22132802002019490d000b0b2001201936020020082009412c6c6a220120032903a001370204200141246a20172903003702002001411c6a2016290300370200200141146a201d2903003702002001410c6a202d2903003702000b201b450d05200c41546a210c200441016a2104201b2108200a410a4f0d050c000b0b2008200b103e000b200b2008417f6a221b490d010b200b20211036000b201b200b103e000b0240024002402000202c470d00202c41016a2201202c490d08202c41017422092001200920014b1b220141ffffffff01712001470d08200141037422094100480d0802400240202c0d002009102121180c010b2018202c4103742009102521180b2018450d012001212c201e21000b201820004103746a2201200a3602042001201b360200201e41016a2200211e20004102490d0102400340024002400240024020182000417f6a221e4103746a2201280200450d00200041037420186a220441746a2802002208200128020422094d0d000240200041024b0d002000211e410221000c080b20182000417d6a22194103746a2802042201200920086a4d0d010240200041034b0d002000211e410321000c080b200441646a280200200120086a4d0d012000211e0c070b20004103490d012001280204210920182000417d6a22194103746a28020421010b20012009490d010b2000417e6a21190b0240024002400240024002402000201941016a222d4b222e450d00200020194b222f450d01201820194103746a2217280204223020172802006a22012018202d4103746a2216280200221d490d02200120214b0d032020201d412c6c6a220e20162802042213412c6c22096a21042001412c6c21082001201d6b220b20136b220120134f0d04202820042001412c6c220910dc041a200d20096a210a0240024020134101480d00200141014e0d010b20042101200d21080c060b202920086a21092004210103402009200141546a2204200a41546a220b200b280200200428020049220c1b2208290200370200200941286a200841286a280200360200200941206a200841206a290200370200200941186a200841186a290200370200200941106a200841106a290200370200200941086a200841086a290200370200200a200b200c1b210a0240200e20042001200c1b2201490d00200d21080c070b200941546a2109200d2108200d200a490d000c060b0b4198bfc100202d2000102d000b4198bfc10020192000102d000b201d2001103e000b200120211036000b2028200e200910dc041a200d20096a210a0240024020134101480d00200b20134a0d010b200e2101200d21080c010b202020086a210c200d2108200e210103402001200420082004280200200828020049220b1b2209290200370200200141286a200941286a280200360200200141206a200941206a290200370200200141186a200941186a290200370200200141106a200941106a290200370200200141086a200941086a29020037020020082008412c6a200b1b21082001412c6a21012004412c6a2004200b1b2204200c4f0d01200a20084b0d000b0b20012008200a20086b22092009412c706b10dc041a0240202f450d002017201d360200201741046a203020136a360200202e450d022016201641086a2000202d417f736a41037410dd041a201e2100201e41014d0d040c010b0b41a8bfc10020192000102d000b41b8bbc000102b000b200941041030000b201b0d000b0240202c450d00201810230b2027450d03202810230c030b200141041030000b102f000b20214102490d002021417f6a210820202021412c6c6a210b4101210a03400240024002400240202120082201417f6a2208490d00202120086b22094102490d0320202001412c6c6a220128020020202008412c6c6a2204280200220e4f0d03200341a0016a41206a2200200441246a290200370300200341a0016a41186a22132004411c6a290200370300200341a0016a41106a2218200441146a290200370300200341a0016a41086a22192004410c6a2902003703002004290204210f200441286a200141286a2802003602002003200f3703a001200441206a200141206a290200370200200441186a200141186a290200370200200441106a200141106a290200370200200441086a200141086a290200370200200420012902003702004101210c20094103490d022004280258200e4f0d024100210c200b210903402009220141546a22092001290200370200200941286a200141286a280200360200200941206a200141206a290200370200200941186a200141186a290200370200200941106a200141106a290200370200200941086a200141086a290200370200200a200c220d460d02200d417f6a210c2001412c6a2209280200200e4f0d020c000b0b20082021103e000b4102200d6b210c0b2001200e3602002004200c412c6c6a220120032903a001370204200141246a20002903003702002001411c6a2013290300370200200141146a20182903003702002001410c6a20192903003702000b200b41546a210b200a417f6a210a20080d000b0b200341086a41186a4200370300200341086a41106a22044200370300200341086a41086a2209420037030020034200370308200341386a41086a22014191fdc400ad42808080809001841003220841086a29000037030020032008290000370338200810232009200129030037030020032003290338220f3703602003200f37030820014184ddc100ad4280808080e000841003220841086a290000370300200320082900003703382008102320042003290338220f370300200341a0016a41086a2009290300370300200341a0016a41106a200f370300200341a0016a41186a20012903003703002003200f370328200320032903083703a00120034100360288012003420137038001202120034180016a105c024002402021450d0020202021412c6c6a210b2020210903402009280200210402400240200328028401220820032802880122016b4104490d0020032802800121080c010b200141046a220a2001490d0420084101742201200a2001200a4b1b22014100480d040240024020080d002001102121080c010b20032802800120082001102521080b2008450d032003200136028401200320083602800120032802880121010b2003200141046a36028801200820016a2004360000200941046a20034180016a10d3012009412c6a2209200b470d000b0b2003280284012101201042808080808004842003350288014220862003280280012209ad84100202402001450d00200910230b0240201f450d00202010230b201a10c603109a01109a0102402006450d00200641246c21092005210103400240024020012d0000220841034b0d0002400240024020080e0404000102040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012009415c6a22090d000b0b02402007450d00200510230b200224000f0b200141011030000b102a000b8804010b7f230041206b220224002001280200210320012802082104200241003602082002420137030020042002105c024002400240024020040d002002280208210520022802042106200228020021070c010b20032004410c6c6a21082003210903402009280200210a200941086a280200220b2002105c02400240200228020422062002280208220c6b200b490d00200228020021070c010b200c200b6a2207200c490d04200641017422052007200520074b1b22054100480d040240024020060d002005102121070c010b200228020020062005102521070b2007450d032002200536020420022007360200200521060b2002200c200b6a22053602082007200c6a200a200b10dc041a2009410c6a22092008470d000b0b200241186a22092005ad4220862007ad841016220b41186a290000370300200241106a220c200b41106a290000370300200241086a220a200b41086a2900003703002002200b290000370300200b1023200041186a2009290300370000200041106a200c290300370000200041086a200a2903003700002000200229030037000002402006450d00200710230b02402004450d002004410c6c21092003210b03400240200b41046a280200450d00200b28020010230b200b410c6a210b200941746a22090d000b0b0240200141046a280200450d00200310230b200241206a24000f0b200541011030000b102a000bac2705097f077e027f017e027f230041e0086b22042400200441c8046a200141c80210dc041a200441c0026a200441c8046a10f2024101210502400240024020042d00c0024101470d00200020042f00c1023b0001200041013a0000200041036a20042d00c3023a000020032802002106410021000c010b200441c0006a200441c0026a41086a220741800210dc041a02400240024002400240024002400240024002400240024020032802002206450d00200341086a280200210820032802042109200441386a41d4bcc0004110108f01200428023c210a2004280238210b200441b8076a41086a220141c4fbc400ad4280808080e000841003220541086a290000370300200420052900003703b8072005102320044198076a41086a2001290300370300200420042903b80737039807200141f4cec000ad4280808080d001841003220541086a290000370300200420052900003703b80720051023200441a8076a41086a2001290300370300200420042903b8073703a807410021052004200a4100200b1b3602c804200441c0026a41186a220a200441c8046aad4280808080c000841001220141186a290000370300200441c0026a41106a220b200141106a2900003703002007200141086a290000370300200420012900003703c00220011023200441d8076a41186a220c200a290300370300200441d8076a41106a220a200b290300370300200441d8076a41086a2007290300370300200420042903c0023703d80741c00010212201450d012001200429039807370000200141086a20044198076a41086a290300370000200120042903a807370010200141186a200441a8076a41086a290300370000200120042903d807370020200141286a200441d8076a41086a290300370000200141306a200a290300370000200141386a200c290300370000200441c0003602cc04200420013602c80420062008200441c8046a10c501200110232009450d00200610230b20044190076a200441c0006a41d0006a10f003200441c8046a200441c0006a41800210dc041a200429039007210d02400240024020042903e804220e4202520d00024010ad01220141ff01714102460d0020014180feff077141087621070c0d0b024010ad01220141ff01714102460d0020014180feff077141087621070c0d0b024010ad01220141ff01714102460d0020014180feff077141087621070c0d0b10ad011a024010ad01220141ff01714102460d0020014180feff077141087621070c0d0b4100210920042802980541756a220141084b0d0b20010e09010b0b0b0b0b0b0b02010b200441a0086a41186a200441c8046a41186a290300370300200441a0086a41106a200441c8046a41106a290300370300200441a0086a41086a200441c8046a41086a290300370300200420042903c8043703a00820044188056a290300210f20044180056a290300211020044190056a280200210720042903f00421110240200428029805220141174b0d004101200174419080800671450d004100210141870421070c090b10ad011a024010ad01220141ff01714102460d0020014180feff077141087621070c090b200441c0026a41186a4200370300200441c0026a41106a22084200370300200441c0026a41086a22094200370300200442003703c002200441d0086a41086a220141c4fbc400ad4280808080e0008422121003220a41086a2900003703002004200a2900003703d008200a102320092001290300370300200420042903d0083703c002200141f9bcc000ad4280808080e000841003220a41086a2900003703002004200a2900003703d008200a1023200820042903d0082213370300200441d8076a41086a2009290300370300200441d8076a41106a2013370300200441d8076a41186a2001290300370300200420133703c008200420042903c0023703d807200441306a200441d8076a4120108f010240200e4201520d0020114200510d040b200120121003220941086a290000370300200420092900003703d00820091023200441a8076a41086a2001290300370300200420042903d0083703a807200141e4bcc000ad4280808080c001841003220941086a290000370300200420092900003703d00820091023200441c0086a41086a2001290300370300200420042903d0083703c008200441c0026a200441a0086a10ac0141c00010212201450d04200120042903a807370000200120042903c008370010200120042903c002370020200141086a200441a8076a41086a290300370000200141186a200441c0086a41086a290300370000200141286a200441c0026a41086a290300370000200141306a200441d0026a290300370000200141386a200441c0026a41186a290300370000200441286a200141c000108f01200428022c21092004280228210a200110234100210120094100200a1b22092007470d06200441d0086a41086a220141c4fbc400ad4280808080e00084220e1003220941086a290000370300200420092900003703d00820091023200441b8076a41086a2001290300370300200420042903d0083703b807200141e4bcc000ad4280808080c001841003220941086a290000370300200420092900003703d0082009102320044198076a41086a2001290300370300200420042903d00837039807200441d8076a200441a0086a10ac0141c00010212201450d05200120042903b807370000200141086a200441b8076a41086a2903003700002001200429039807370010200141186a20044198076a41086a290300370000200120042903d807370020200141286a200441d8076a41086a220c290300370000200141306a200441d8076a41106a2214290300370000200141386a200441d8076a41186a22152903003700002004200741016a3602c0022001ad4280808080800884200441c0026aad22164280808080c000842213100220011023200441c0026a41186a22174200370300200441c0026a41106a220b4200370300200441c0026a41086a22094200370300200442003703c002200441c0086a41086a220a200e1003220141086a290000370300200420012900003703c008200110232009200a290300370300200420042903c0083703c002200441d0086a41086a220741c4cec000ad428080808080028422121003220141086a290000370300200420012900003703d00820011023200441a8076a41086a2007290300220e370300200420042903d00822113703a80720082011370000200841086a200e370000200c20092903003703002014200b29030037030020152017290300370300200420042903c0023703d807200441206a200441d8076a4120108f014100210141062107417f2004280224410020042802201b220820026a221820182008491b220842808080c0f588fe064280808080f28ba809200d4280808080f01f835022181b220e200e428094ebdc0380220e4280ec94a37c7e7c4280cab5ee0156200ea76a4b0d0820174200370300200b420037030020094200370300200442003703c002200a41c4fbc400ad4280808080e0008422111003220141086a290000370300200420012900003703c008200110232009200a290300370300200420042903c008220e3703b8072004200e3703c002200a20121003220141086a290000370300200420012900003703c00820011023200b20042903c008220e370300200c20092903003703002014200e3703002015200a2903003703002004200e3703b807200420042903c0023703d807200420083602c002200441d8076aad428080808080048422122013100220174200370300200b420037030020094200370300200442003703c002200a20111003220141086a290000370300200420012900003703c008200110232009200a290300370300200420042903c0083703c002200a41a0cec000ad4280808080b0028422131003220141086a290000370300200420012900003703c00820011023200b20042903c008220e370300200c20092903003703002014200e3703002015200a2903003703002004200e37039807200420042903c0023703d807200441186a200441d8076a4120108f0141002101417f200428021c410020042802181b220a4180afd0e502418094ebdc0320181b2208200da7220920082009491b6a220c200c200a491b220a20084b0d08200441c0026a41186a22144200370300200441c0026a41106a220c4200370300200441c0026a41086a22074200370300200442003703c002200441c0086a41086a220120111003220841086a290000370300200420082900003703c0082008102320072001290300370300200420042903c008220e3703b8072004200e3703c002200120131003220841086a290000370300200420082900003703c00820081023200441b8076a41086a2001290300220e370300200420042903c00822113703b807200b2011370000200b41086a200e370000200441d8076a41086a2007290300370300200441d8076a41106a200c290300370300200441d8076a41186a2014290300370300200420042903c0023703d8072004200a3602c002201220164280808080c000841002200441086a20022009200d422888a72010200f1086034101210741002101200441c0026a200441a0086a2004290308200441086a41086a290300410141112010200f84501b410010880220042802c0024101460d0820042903c802200c290300109104200441c0026a200441c8046a41d0006a10a502024020042d00c0024101460d00200441ec026a2802002102200441e8026a280200210a200441e4026a2802002108200441dc026a280200210b200441d8026a28020021090240200441e0026a2802002201450d002001410c6c21072009210103400240200141046a280200450d00200128020010230b2001410c6a2101200741746a22070d000b0b0240200b450d00200910230b02402002450d002002410c6c21072008210103400240200141046a280200450d00200128020010230b2001410c6a2101200741746a22070d000b0b200a450d0a200810230c0a0b20042d00c10222014102460d0920042f01c20221070c080b200441c0026a2004419c056a10ba01024020042d00c0024101460d00200441ec026a2802002102200441e8026a280200210b200441e4026a2802002108200441dc026a280200210c200441d8026a280200210a0240200441e0026a2802002201450d002001410c6c2107200a210103400240200141046a280200450d00200128020010230b2001410c6a2101200741746a22070d000b0b0240200c450d00200a10230b02402002450d002002410c6c21072008210103400240200141046a280200450d00200128020010230b2001410c6a2101200741746a22070d000b0b200b450d0a200810230c0a0b20042d00c10222014102460d090c060b200441c0026a200441a0056a10b303024020042d00c0024101460d00200441ec026a2802002102200441e8026a280200210b200441e4026a2802002108200441dc026a280200210c200441d8026a280200210a0240200441e0026a2802002201450d002001410c6c2107200a210103400240200141046a280200450d00200128020010230b2001410c6a2101200741746a22070d000b0b0240200c450d00200a10230b02402002450d002002410c6c21072008210103400240200141046a280200450d00200128020010230b2001410c6a2101200741746a22070d000b0b200b450d09200810230c090b20042d00c10222014102460d080c050b41c00041011030000b41e8b8c600102b000b41c00041011030000b41c00041011030000b41034102200920074b1b21070c010b20042f01c20241087420017221010c040b2007410874200141ff01717221010c030b20044180086a41186a200441a0086a41186a29030037030020044180086a41106a200441a0086a41106a29030037030020044180086a41086a200441a0086a41086a290300370300200420042903a00837038008410121090b200441b8076a41186a220820044180086a41186a2201290300370300200441b8076a41106a220a20044180086a41106a2207290300370300200441b8076a41086a220b20044180086a41086a220229030037030020042004290380083703b807200441c0026a20044198056a41b00110dc041a200441a0086a41186a220c2008290300370300200441a0086a41106a2214200a290300370300200441a0086a41086a220a200b290300370300200420042903b8073703a0084102210802402009450d002001200c290300370300200720142903003703002002200a290300370300200420042903a00837038008410121080b200441e2076a2002290300370100200441ea076a2007290300370100200441f2076a2001290300370100200420083a00d90720042004290380083701da07200441003a00d807200441a0086a200441c0026a200441d8076a108d02200441ab086a2d0000210720042903a008210e20042d00a808210120042f00a9082102200441dc046a200d370200200441c8046a41106a20012002200741107472410874722207360200200441c8046a41086a200d200e20014102461b370300200420014102473602cc04200441003a00c804200441c8046a108e01200441d4bcc0004110108f012004200428020441016a410120042802001b3602c80441d4bcc000ad4280808080800284200441c8046aad4280808080c0008410022000410c6a2007360200200041046a200e370200200041003a00002006450d032005450d03200341046a280200450d03200610230c030b2007410874200141ff01717221010b20044198056a10db01200041036a20014110763a0000200020013b0001200041013a000020054521000b20000d002006450d00200341046a280200450d00200610230b200441e0086a24000beb0101027f20014180feff077141087621020240024020014101710d00411f210341ccbcc60021010240024002400240024002400240200241ff01710e080006010203040508000b4120210341acbcc60021010c070b4127210341ccbbc60021010c060b4117210341b5bbc60021010c050b4196bbc60021010c040b4126210341f0bac60021010c030b412b210341c5bac60021010c020b4139210341f3bbc60021010c010b411f210341edbdc600210102400240200241ff01710e03000102000b41c100210341acbdc60021010c010b41c100210341ebbcc60021010b20002003360204200020013602000ba20301027f23004180026b22022400024002402001450d00200220003602000c010b200241013602000b20022001360204200241f8006a20021088010240200228027c450d00200241086a200241f8006a41f00010dc041a200241086a1083040240200241086a410c6a2802002200450d00200228020c2101200041246c210003400240024020012d0000220341034b0d0002400240024020030e0404000102040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b0240200241106a280200450d00200228020c10230b20024180026a240042010f0b200241f4016a41043602002002411c6a41023602002002420237020c200241f89fc500360208200241043602ec01200241fca0c5003602e801200241003602fc01200241c4b8c6003602f8012002200241e8016a3602182002200241f8016a3602f001200241086a4188a0c5001038000bbf2e020b7f017e230041d0006b22022400200241003602282002420137032002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410410212203450d0020024284808080c00037022420022003360220200341edcad18b0636000002400240200228022420022802282203460d00200228022021040c010b200341016a22042003490d26200341017422052004200520044b1b22054100480d260240024020030d002005102121040c010b200228022020032005102521040b2004450d0220022005360224200220043602200b2002200341016a360228200420036a41093a0000411c200241206a105c41f4e3c400210603402006280204210720062802082203200241206a105c0240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d27200541017422042008200420084b1b22044100480d270240024020050d002004102121050c010b200228022020052004102521050b2005450d042002200436022420022005360220200228022821040b2002200420036a360228200520046a2007200310dc041a200228022421042002280228210302400240200628020c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d29200341017422052004200520044b1b22054100480d290240024020030d002005102121040c010b200228022020032005102521040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d28200341017422052004200520044b1b22054100480d280240024020030d002005102121040c010b200228022020032005102521040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628020c4101460d00200241306a20062802101103002002280234210720022802382203200241206a105c0240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d29200541017422042008200420084b1b22044100480d290240024020050d002004102121050c010b200228022020052004102521050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a2007200310dc041a200228024021050240200228023c4101460d0020052002280244200241206a105d0c020b200520022802482203200241206a105d02402003450d00200341d8006c21074100210403400240200520046a220341346a280200450d002003413c6a280200450d00200341386a28020010230b0240200341c4006a280200450d00200341cc006a280200450d00200341c8006a28020010230b2007200441d8006a2204470d000b0b2002280244450d01200510230c010b2006280214210720062802182203200241206a105c0240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d28200541017422042008200420084b1b22044100480d280240024020050d002004102121050c010b200228022020052004102521050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a2007200310dc041a200628022021030240200628021c4101460d002003200641246a280200200241206a105d0c010b20032006280228200241206a105d0b200228022421042002280228210302400240200628022c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d29200341017422052004200520044b1b22054100480d290240024020030d002005102121040c010b200228022020032005102521040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d28200341017422052004200520044b1b22054100480d280240024020030d002005102121040c010b200228022020032005102521040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628022c4101460d00200241186a200628023011030020022802182104200228021c2203200241206a105c2003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a105c0240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d2a20074101742205200a2005200a4b1b22054100480d2a0240024020070d002005102121070c010b200228022020072005102521070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410dc041a200341706a200241206a105e2003200241206a105b2003412c6a2103200841546a22080d000c020b0b2006280230210420062802382203200241206a105c2003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a105c0240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d2920074101742205200a2005200a4b1b22054100480d290240024020070d002005102121070c010b200228022020072005102521070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410dc041a200341706a200241206a105e2003200241206a105b2003412c6a2103200841546a22080d000b0b200228022421042002280228210302400240200628023c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d29200341017422052004200520044b1b22054100480d290240024020030d002005102121040c010b200228022020032005102521040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d28200341017422052004200520044b1b22054100480d280240024020030d002005102121040c010b200228022020032005102521040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628023c4101460d00200241106a20062802401103002002280210210420022802142203200241206a105c2003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a105c0240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d2a20074101742205200a2005200a4b1b22054100480d2a0240024020070d002005102121070c010b200228022020072005102521070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410dc041a200341706a200241206a105b2003200241206a105b2003412c6a2103200841546a22080d000c020b0b2006280240210420062802482203200241206a105c2003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a105c0240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d2920074101742205200a2005200a4b1b22054100480d290240024020070d002005102121070c010b200228022020072005102521070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410dc041a200341706a200241206a105b2003200241206a105b2003412c6a2103200841546a22080d000b0b02400240200628024c4101460d00200241086a20062802501103002002280208210b200228020c2203200241206a105c2003450d01200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a105c0240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2a20084101742205200a2005200a4b1b22054100480d2a0240024020080d002005102121080c010b200228022020082005102521080b2008450d142002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410dc041a200341106a2802002109200341146a2802002204200241206a105c0240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2a20084101742205200a2005200a4b1b22054100480d2a0240024020080d002005102121080c010b200228022020082005102521080b2008450d152002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410dc041a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1102002002280230210920022802382204200241206a105c0240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2c20084101742205200a2005200a4b1b22054100480d2c0240024020080d002005102121080c010b200228022020082005102521080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410dc041a2002280234450d01200910230c010b2003411c6a2802002109200341246a2802002204200241206a105c0240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2b20084101742205200a2005200a4b1b22054100480d2b0240024020080d002005102121080c010b200228022020082005102521080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410dc041a0b200341286a200241206a105b200c200741386a2207470d000c020b0b2006280250210b20062802582203200241206a105c2003450d00200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a105c0240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2920084101742205200a2005200a4b1b22054100480d290240024020080d002005102121080c010b200228022020082005102521080b2008450d172002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410dc041a200341106a2802002109200341146a2802002204200241206a105c0240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2920084101742205200a2005200a4b1b22054100480d290240024020080d002005102121080c010b200228022020082005102521080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410dc041a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1102002002280230210920022802382204200241206a105c0240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2b20084101742205200a2005200a4b1b22054100480d2b0240024020080d002005102121080c010b200228022020082005102521080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410dc041a2002280234450d01200910230c010b2003411c6a2802002109200341246a2802002204200241206a105c0240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2a20084101742205200a2005200a4b1b22054100480d2a0240024020080d002005102121080c010b200228022020082005102521080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410dc041a0b200341286a200241206a105b200c200741386a2207470d000b0b02400240200628025c4101460d00200220062802601103002002280200210420022802042203200241206a105c2003450d012003411c6c21082004410c6a21030340200341786a28020021092003417c6a2802002204200241206a105c0240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d2a20074101742205200a2005200a4b1b22054100480d2a0240024020070d002005102121070c010b200228022020072005102521070b2007450d1c2002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410dc041a2003200241206a105b2003411c6a2103200841646a22080d000c020b0b2006280260210420062802682203200241206a105c2003450d002003411c6c21082004410c6a21030340200341786a28020021092003417c6a2802002204200241206a105c0240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d2920074101742205200a2005200a4b1b22054100480d290240024020070d002005102121070c010b200228022020072005102521070b2007450d1c2002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410dc041a2003200241206a105b2003411c6a2103200841646a22080d000b0b200641ec006a220641c4fbc400470d000b2002280228220341046a2204417f4c0d192002280224210920022802202108024002402004450d00200410212205450d1c2003413f4b0d01200520034102743a0000410121070c240b41012104410110212205450d1c200541033a0000410521070c1e0b200341808001490d212003418080808004490d200c1c0b410441011030000b200541011030000b200441011030000b200541011030000b200541011030000b200441011030000b200441011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b200541011030000b102f000b200441011030000b410141011030000b200541033a00002004417f6a41044f0d01200441017422074105200741054b1b22074100480d080b20052004200710252205450d01200721040b20052003360001410521070c030b200741011030000b02400240200441034b0d00200441017422074104200741044b1b22074100480d0620052004200710252205450d01200721040b20052003410274410272360000410421070c020b200741011030000b0240200441014b0d0020052004200441017422074102200741024b1b220710252205450d02200721040b41022107200520034102744101723b00000b0240200420076b20034f0d00200720036a22062007490d032004410174220a2006200a20064b1b22064100480d0320052004200610252205450d020b200520076a2008200310dc041a200720036aad4220862005ad84210d02402009450d00200810230b200241d0006a2400200d0f0b200741011030000b200641011030000b102a000bca0601047f23004190086b22022400024002402001450d00200220003602000c010b200241013602000b20022001360204200241b8056a200210e20202400240024002400240024020022903a0064203510d00200241186a200241b8056a41c80210dc041a200241e0026a200241186a41c80210dc041a2002200241e0026a3602b805200241a8056a200241b8056a10b80320022802b0052101200241b8056a200241e0026a41c80210dc041a20024188086a20022802b005360200200220022903a80537038008200241086a200241b8056a200120024180086a1085044101410220022d000841014622031b220010212201450d01200241003602c005200220003602bc05200220013602b8050240024020030d00200141003a000041022103200241023602c0050240200241146a2d000022044102470d00200141003a00010c020b200141013a00010240024020044101470d0020014102410410252201450d06200141013a000220024284808080303702bc05200220013602b8054103210320022d001521040c010b410221034100210420004102470d0041000d0820004101742204200041016a2205200420054b1b22044100480d0820012000200410252201450d06200220043602bc05200220013602b805410021040b200120036a20043a00002002200341016a22003602c005200241166a2d00002104024020022802bc052000470d0041000d0820004101742203200041016a2205200320054b1b22034100480d080240024020000d002003102121010c010b200120002003102521010b2001450d07200220033602bc05200220013602b8050b2002200041016a22033602c005200120006a20043a00000c010b200141013a0000200241013602c005200241086a410172200241b8056a108a0420022802c005210320022802b80521010b20024190086a24002003ad4220862001ad840f0b200241246a4104360200200241f4026a4102360200200242023702e402200241f89fc5003602e0022002410436021c20024194a1c5003602182002410036020c200241c4b8c6003602082002200241186a3602f0022002200241086a360220200241e0026a4188a0c5001038000b200041011030000b410441011030000b200441011030000b200341011030000b102a000bea0b01057f230041106b22022400200141046a2802002103200141086a28020021040240024002400240024002400240024002400240024020002d00004101460d000240024020032004460d00200128020021050c010b200441016a22032004490d0b200441017422052003200520034b1b22034100480d0b0240024020040d002003102121050c010b200128020020042003102521050b2005450d0320012005360200200141046a2003360200200141086a28020021040b200141086a2206200441016a36020041002103200520046a41003a000002400240024002400240024002400240024020002d00010e080700010203040506070b200241013a000f410121030c070b410221030c050b410321030c040b410421030c030b410521030c020b410621030c010b200241073a000f02400240200141046a28020020062802002204460d00200128020021030c010b200441016a22032004490d0d200441017422052003200520034b1b22054100480d0d0240024020040d002005102121030c010b200128020020042005102521030b2003450d0620012003360200200141046a2005360200200141086a28020021040b200141086a200441016a360200200320046a41073a000020002d000221030b200220033a000f0b02400240200141046a280200200141086a2802002204460d00200128020021000c010b200441016a22002004490d0b200441017422052000200520004b1b22054100480d0b0240024020040d002005102121000c010b200128020020042005102521000b2000450d0520012000360200200141046a2005360200200141086a28020021040b200141086a200441016a360200200020046a20033a00000c010b0240024020032004460d00200128020021030c010b200441016a22032004490d0a200441017422052003200520034b1b22054100480d0a0240024020040d002005102121030c010b200128020020042005102521030b2003450d0520012003360200200141046a2005360200200141086a28020021040b200141086a200441016a360200200320046a41013a000020002d0001220441024b0d0002400240024020040e03000102000b02400240200141046a280200200141086a2802002204460d00200128020021000c010b200441016a22002004490d0c200441017422032000200320004b1b22034100480d0c0240024020040d002003102121000c010b200128020020042003102521000b2000450d0820012000360200200141046a2003360200200141086a28020021040b200141086a200441016a360200200020046a41003a00000c020b02400240200141046a280200200141086a2802002204460d00200128020021000c010b200441016a22002004490d0b200441017422032000200320004b1b22034100480d0b0240024020040d002003102121000c010b200128020020042003102521000b2000450d0820012000360200200141046a2003360200200141086a28020021040b200141086a200441016a360200200020046a41013a00000c010b02400240200141046a280200200141086a2802002204460d00200128020021030c010b200441016a22032004490d0a200441017422052003200520034b1b22054100480d0a0240024020040d002005102121030c010b200128020020042005102521030b2003450d0820012003360200200141046a2005360200200141086a28020021040b200141086a2205200441016a360200200320046a41023a000020002d0002210302400240200141046a28020020052802002204460d00200128020021000c010b200441016a22002004490d0a200441017422052000200520004b1b22054100480d0a0240024020040d002005102121000c010b200128020020042005102521000b2000450d0920012000360200200141046a2005360200200141086a28020021040b200141086a200441016a360200200020046a20033a00000b200241106a24000f0b200341011030000b200541011030000b200541011030000b200541011030000b200341011030000b200341011030000b200541011030000b200541011030000b102a000b901307077f017e017f027e067f017e067f23004190026b22022400200241186a41d4bcc0004110108f01200228021c21030240200228021822044101470d0041d4bcc000ad428080808080028410050b200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a2207420037030020024200370320200241b0016a41086a220841c4fbc400ad4280808080e0008422091003220a41086a2900003703002002200a2900003703b001200a102320072008290300370300200220022903b00137032020084188cec000ad4280808080e00184220b1003220a41086a2900003703002002200a2900003703b001200a1023200620022903b001220c370300200241d0016a41086a220d2007290300370300200241d0016a41106a220a200c370300200241d0016a41186a220e20082903003703002002200c37039001200220022903203703d00120022003410020041b360220200241d0016aad4280808080800484200241206aad4280808080c0008410022005420037030020064200370300200742003703002002420037032020024190016a41086a220f20091003220341086a2900003703002002200329000037039001200310232007200f2903003703002002200229039001370320200f41f9bcc000ad4280808080e000841003220341086a2900003703002002200329000037039001200310232006200229039001220c370300200d2007290300370300200a200c370300200e200f2903003703002002200c3703b001200220022903203703d001200241106a200241d0016a4120108f012002280214410020022802101b1090022005420037030020064200370300200742003703002002420037032020024180026a41086a221020091003220341086a290000370300200220032900003703800220031023200720102903003703002002200229038002220c3703f0012002200c3703202010200b1003220341086a2900003703002002200329000037038002200310232006200229038002220c370300200d2007290300370300200a200c370300200e20102903003703002002200c3703f001200220022903203703d001200241086a200241d0016a4120108f01024002400240024002400240200228020c410020022802081b22110d0041042112410021110c010b2011ad420c7e220c422088a70d03200ca7220a4100480d03200a10212212450d0420024180026aad4280808080c00084210b4100210341c4fbc400ad4280808080e00084211320122104034020024180026a41086a220a20131003221441086a290000370300200220142900003703800220141023200241b0016a41086a2215200a29030037030020022002290380023703b001200a41f4cec000ad4280808080d001841003221441086a29000037030020022014290000370380022014102320024190016a41086a2214200a2903003703002002200229038002370390012002200336028002200241206a41186a2216200b1001220a41186a290000370300200241206a41106a2217200a41106a290000370300200241206a41086a2218200a41086a2900003703002002200a290000370320200a1023200241d0016a41186a22192016290300370300200241d0016a41106a22162017290300370300200241d0016a41086a22172018290300370300200220022903203703d00141c0001021220a450d02200341016a2103200a20022903b001370000200a41086a2015290300370000200a200229039001370010200a41186a2014290300370000200a20022903d001370020200a41286a2017290300370000200a41306a2016290300370000200a41386a2019290300370000200241206a200a41c00010c001024020022802202214450d00200aad428080808080088410050b2002290224210c200a1023200441046a200c420020141b37020020042014410120141b3602002004410c6a210420112003470d000b0b20022011360228200220113602242002201236022020024190016a200241206a108404200241b0016a41186a20024190016a41186a290300370300200241b0016a41106a20024190016a41106a2903003703002008200f29030037030020022002290390013703b00120054200370300200241206a41106a220a42003703002007420037030020024200370320201020091003220341086a290000370300200220032900003703800220031023200720102903003703002002200229038002220c3703f0012002200c37032020104189bdc000ad4280808080e001841003220341086a290000370300200220032900003703800220031023200241f0016a41086a2010290300220c3703002002200229038002220b3703f0012006200b370000200641086a200c370000200d2007290300370300200241d0016a41106a200a290300370300200e2005290300370300200220022903203703d001200241203602242002200241d0016a360220200241b0016a200241206a10b103200241206a109b01200241003602b801200242013703b0012002200241b0016a3602d001200a200241d0016a106b200241206a200241b0016a10af012002200241b0016a3602d001200241d0006a200241d0016a106b2002200241b0016a3602d001200241f0006a200241d0016a106b200228022421042002412c6a280200220a200241b0016a105c0240200a450d00200a41246c21160340200241d0016a200410b00120022802d00121150240024020022802b401221420022802b801220a6b20022802d8012203490d0020022802b00121140c010b200a20036a2217200a490d052014410174220a2017200a20174b1b220a4100480d050240024020140d00200a102121140c010b20022802b0012014200a102521140b2014450d042002200a3602b401200220143602b00120022802b801210a0b2002200a20036a3602b8012014200a6a2015200310dc041a024020022802d401450d00201510230b200441246a21042016415c6a22160d000b0b20023502b801422086210c20023502b001210b0240200228022c2203450d002002280224210a200341246c2103034002400240200a2d0000220441034b0d0002400240024020040e0404000102040b200a410c6a280200450d03200a41086a28020010230c030b200a410c6a280200450d02200a41086a28020010230c020b200a410c6a280200450d01200a41086a28020010230c010b200a41086a280200450d00200a41046a28020010230b200a41246a210a2003415c6a22030d000b0b200c200b84210c0240200241286a280200450d00200228022410230b20024190026a2400200c0f0b41c00041011030000b200a41011030000b102a000b200a41041030000ba41305017f017e027f017e077f230041f0026b22022400024002402001450d00200220003602180c010b200241013602180b2002200136021c200241106a200241186a106e024020022802100d00200228021421012002200241186a3602d001200241003a00e002200242003702fc01200241d8a7c3003602f80120022001360234200241003602302002200241e0026a36023c2002200241d0016a360238200241306a200241f8016a10bd0220022802f801210120022902fc012103024020022d00e002450d0020012003a72003422088a710b4010c010b2001450d002002200337022420022001360220200241306a200241206a1068024002400240024002400240024020022802304101460d00200241306a41086a22002903002103200241306a41186a4200370300200241306a41106a220442003703002000420037030020024200370330200241d0016a41086a220141be99c600ad42808080809001841003220541086a290000370300200220052900003703d0012005102320002001290300370300200220022903d001370330200141f0cec400ad428080808030841003220541086a290000370300200220052900003703d00120051023200420022903d0012206370300200241f8016a41086a2000290300370300200241f8016a41106a2006370300200241f8016a41186a2001290300370300200220063703e002200220022903303703f8012002200241f8016a109c02200229030821062002280200210041c80210212207450d012007200241f8016a41e80010dc04220842023703682008410236029801200820022903d001370370200841f8006a200129030037030020084180016a200241d0016a41106a29030037030020084188016a200241d0016a41186a29030037030020084190016a200241f0016a29030037030020082003200642b8177c42b81720001b220620032006561b3703a001200841a8016a200241306a41a00110dc041a200241206a210120022802242109024003402001280200220a41086a2100200a2f0106220b4103742101410021050240024003402001450d01419ea3c5002000410810de04220c450d02200141786a2101200541016a2105200041086a2100200c417f4a0d000b2005417f6a210b0b024020090d004101210d0c030b2009417f6a2109200a200b4102746a41e4016a21010c010b0b4101210d200a41e0006a2005410c6c6a22012802084104490d0020012802002800002109200241306a41186a220c4200370300200241306a41106a220a4200370300200241306a41086a2200420037030020024200370330200241d0016a41086a220141be99c600ad42808080809001841003220541086a290000370300200220052900003703d0012005102320002001290300370300200220022903d001370330200141cd99c600ad4280808080b001841003220541086a290000370300200220052900003703d00120051023200241e0026a41086a20012903002203370300200220022903d00122063703e00220042006370000200441086a2003370000200241f8016a41086a2000290300370300200241f8016a41106a200a290300370300200241f8016a41186a200c290300370300200220022903303703f801200241306a200241f8016a10950220022802302201410420011b21054100210002402002290234420020011b2203422088a72201417f6a220c20014b0d00200c20014f0d002005200c4102746a2201450d00200128020020094721000b02402003a7450d00200510230b2000450d00200841c80241900510252207450d03200741c8026a200241f8016a41e80010dc041a200742023703b003200720093602e403200741093602e003200720022903d0013703b803200741c0036a200241d8016a290300370300200741c8036a200241e0016a290300370300200741d0036a200241e8016a290300370300200741d8036a200241f0016a290300370300200741f0036a200241306a41a00110dc041a4102210d0b200241206a21012002280224210a024003402001280200220841086a210020082f01062209410374210141002105024003402001450d0141e4bcc1002000410810de04220c450d03200141786a2101200541016a2105200041086a2100200c417f4a0d000b2005417f6a21090b0240200a450d00200a417f6a210a200820094102746a41e4016a21010c010b0b4191bdc100412a104a000b200220082005410c6c6a220141e8006a2802003602fc012002200141e0006a2802003602f801200241306a200241f8016a107f2002280230220c450d03200229023421032007200d41c8026c2200200d4101742201200d41016a2205200120054b1b41c8026c220110252204450d04200420006a200241f8016a41e80010dc0422014202370368200120022903d001370370200141f8006a200241d8016a29030037030020014180016a200241e0016a29030037030020014188016a200241e8016a29030037030020014190016a200241f0016a290300370300200141a0016a20033703002001419c016a200c3602002001411436029801200141a8016a200241306a41a00110dc041a20022802202002280224200228022810b4012002410036028002200242013703f8012005200241f8016a105c200041c8026a210720022802fc01210a2002280280022101200421050340200220053602d001200241306a200241d0016a10b8032002280230210902400240200a20016b20022802382208490d00200120086a210020022802f801210c0c010b200120086a22002001490d08200a410174220c2000200c20004b1b220b4100480d0802400240200a0d00200b1021210c0c010b20022802f801200a200b1025210c0b200c450d072002200b3602fc012002200c3602f801200b210a0b2002200036028002200c20016a2009200810dc041a02402002280234450d00200910230b200541c8026a210520002101200741b87d6a22070d000b20044198016a2101200d41c8026c41c8026a21052000ad422086200cad8421030340200110db01200141c8026a2101200541b87d6a22050d000b20041023200241f0026a240020030f0b200220022902343703f80141a9cfc4004128200241f8016a41f4cec4001031000b41c80241081030000b41900541081030000b2002412936023420024194bec60036023041ecbcc1004125200241306a41d4bcc1001031000b200141081030000b200b41011030000b102a000b20024184026a4104360200200241c4006a410236020020024202370234200241f89fc500360230200241043602fc01200241aca1c5003602f801200241003602d401200241c4b8c6003602d0012002200241f8016a3602402002200241d0016a36028002200241306a4188a0c5001038000be82c06077f017e0b7f027e017f037e230041c0026b22022400024002402001450d00200220003602200c010b200241013602200b20022001360224200241d8006a200241206a10e1020240024002400240200228025c2203450d00200241d0016a2802002104200241cc016a2802002105200241c8016a2802002106200241d8006a410c6a280200210720022802602108200241186a200241206a106e20022802180d02200228021c21012002200241206a360248200241003a0038200242003702e401200241d8a7c3003602e0012002200136025c200241003602582002200241386a3602642002200241c8006a360260200241d8006a200241e0016a10bd0220022802e001210120022902e401210920022d0038450d0120012009a72009422088a710b4010c020b200241d4006a4104360200200241f4016a4102360200200242023702e401200241f89fc5003602e0012002410436024c200241c8a1c5003602482002410036023c200241c4b8c6003602382002200241c8006a3602f0012002200241386a360250200241e0016a4188a0c5001038000b20010d010b200241e0016a410c6a4104360200200241ec006a41023602002002420237025c200241f89fc500360258200241043602e401200241c8a1c5003602e0012002410036024c200241c4b8c6003602482002200241e0016a3602682002200241c8006a3602e801200241d8006a4188a0c5001038000b2002200937022c20022001360228200241013b01442002420037023c200241d8a7c300360238200241386a41086a210a024002400240024002402004450d002006200441c8026c6a210b200241e0016a410272210c200241d8006a41106a210d2006210e024002400240024002400240024002400340200e41e8006a2903004202520d0902400240200e28029801410247220f0d00200e2903a0012109200241286a2101200228022c2110024002400240024002400240024002400240024002400240024002400240024003402001280200221141086a210020112f010622124103742101410021130240024003402001450d01418cbec6002000410810de042214450d02200141786a2101201341016a2113200041086a21002014417f4a0d000b2013417f6a21120b2010450d022010417f6a2110201120124102746a41e4016a21010c010b0b201141e0006a2013410c6c6a220128020841074b0d014194bec6002112201542808080807083422984a721100c020b41bdbec6002112201542808080807083421c84a721100c010b200942f02e8020012802002900002215510d0141a0c6c3002112413121100b0240024020022d0045450d00413121014185acc50021000c010b2002280238200228023c200228024010b4012002420037023c200241d8a7c300360238200242e2c289abb68edbb7f40037034841002101200241e0016a410272410041da0010db041a200241d8006a410041840110db041a41e40110212214450d0220144100360200201441046a200241e0016a41dc0010dc041a201441e0006a200241d8006a41840110dc041a2002410036023c2002201436023820142f0106220e4103742111417f2100024002400340024020112001470d00200e21000c020b200241c8006a201420016a41086a410810de042213450d02200141086a2101200041016a21002013417f4a0d000b0b200242e2c289abb68edbb7f40037026c2002200a360268200220003602642002201436025c200241003602582002200241386a360260201041046a2200417f4c0d04024002402000450d00200010212201450d07200241003602bc02200220013602e0012010413f4b0d01200120104102743a0000410121130c190b200241003602bc0241012100200241013602e001410110212201450d07200141033a0000200241013602bc02200220013602e001410521130c130b201041808001490d162010418080808004490d150c100b412d210141d8abc50021000b2002200136025c2002200036025841a5abc5004122200241d8006a41c8abc5001031000b200f0d0c200e2903a0012116200241d8006a200241286a10680240024020022802584101470d0020023502602109200228025c21174101210f0c010b20022903602109200241d8006a41186a22144200370300200d4200370300200241d8006a41086a2200420037030020024200370358200241e0016a41086a220141be99c600ad42808080809001841003221341086a290000370300200220132900003703e0012013102320002001290300370300200220022903e001370358200141f0cec400ad428080808030841003221341086a290000370300200220132900003703e00120131023200241c8006a41086a20012903002218370300200220022903e0012219370348200d2019370000200d41086a201837000020012000290300370300200241e0016a41106a200d290300370300200241e0016a41186a2014290300370300200220022903583703e001200241086a200241e0016a109c0202402016200942b0ea017c560d004100210f2016200229031042b8177c42b81720022802081b2209540d010c0e0b201a4280808080708342258421094101210f4184cfc40021170b024020022d0045450d00413121014185acc50021000c070b0240200f450d002002280238200228023c200228024010b4012002420037023c200241d8a7c300360238200242f4d2b59bc7ae98b8303703480c050b20022802382111200242f4d2b59bc7ae98b830370348201141d8a7c300460d04200228023c21100c050b41e40141041030000b102f000b200041011030000b410141011030000b200c410041da0010db041a200241d8006a410041840110db041a41e40110212211450d024100211020114100360200201141046a200241e0016a41dc0010dc041a201141e0006a200241d8006a41840110dc041a2002410036023c200220113602380b02400340201141086a210020112f01062212410374210141002113024003402001450d01200241c8006a2000410810de042214450d03200141786a2101201341016a2113200041086a21002014417f4a0d000b2013417f6a21120b02402010450d002010417f6a2110201120124102746a41e4016a28020021110c010b0b200242f4d2b59bc7ae98b83037026c2002200a360268200220123602642002201136025c200241003602582002200241386a360260200241003602e801200242013703e00141011021210102400240200f0d002001450d05200141003a000020024281808080103702e401200220013602e00120014101410910252201450d06200120093700012002428980808090013702e401200220013602e0010c010b2001450d06200141013a000020024281808080103702e401200220013602e0012009a72201200241e0016a105c0240024020022802e401221320022802e80122006b2001490d0020022802e00121130c010b200020016a22142000490d16201341017422112014201120144b1b22144100480d160240024020130d002014102121130c010b20022802e00120132014102521130b2013450d08200220143602e401200220133602e0010b2002200020016a3602e801201320006a2017200110dc041a0b200241c8006a41086a200241e0016a41086a280200360200200220022903e001370348200241d8006a200241c8006a10d2012002200f3a0045200241003a00442009211a200f450d07200241e0016a41086a200241386a41086a290300370300200220022903383703e0010c130b412d210141d8abc50021000b200220003602582002200136025c41a5abc5004122200241d8006a41c8abc5001031000b41e40141041030000b410141011030000b410941011030000b410141011030000b201441011030000b200e41c8026a220e200b470d010c0a0b0b200141033a0000200241013602bc022000417f6a41034b0d01200041017422134105201341054b1b22134100480d0a0b20012000201310252201450d01200220013602e001201321000b20012010360001410521130c030b201341011030000b02400240200041034b0d00200041017422134104201341044b1b22134100480d0820012000201310252201450d01200220013602e001201321000b20012010410274410272360000410421130c020b201341011030000b0240200041014b0d0020012000200041017422134102201341024b1b221310252201450d02200220013602e001201321000b41022113200120104102744101723b00000b200220133602bc0202400240200020136b2010490d00200021140c010b201320106a22142013490d05200041017422112014201120144b1b22144100480d0520012000201410252201450d02200220013602e0010b2002201320106a3602bc02200120136a2012201010dc041a2002201436024c200220022802e001360248200220022802bc02360250200241d8006a200241c8006a10d20120024180023b0144200241e0016a41086a200241386a41086a290300370300200220022903383703e0010c030b201341011030000b201441011030000b200241e0016a41086a200a290300370300200220022903383703e0010b2002280228200228022c200228023010b40102402007450d00200741246c21002003210103400240024020012d0000221341034b0d0002400240024020130e0404000102040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b02402008450d00200310230b02402004450d00200441c8026c210020064198016a21010340200110db01200141c8026a2101200041b87d6a22000d000b0b02402005450d00200610230b200241003602602002420137035820022d00ec012100410110212201450d022002410136025c20022002280260221341016a36026020022001360258200120136a20003a000020022d00ed01211302400240200228025c20022802602201460d00200228025821000c010b200141016a22002001490d01200141017422142000201420004b1b22144100480d010240024020010d002014102121000c010b200228025820012014102521000b2000450d022002201436025c20022000360258200228026021010b2002200141016a360260200020016a20133a000020022802e801200241d8006a105c20022802e00122132100024020022802e4012214450d002014210120132100034020002802e40121002001417f6a22010d000b0b0240024002400240024002400240024002400240024020022802e80122120d00410021010c010b200241e0016a210b41002114034002400240201420002f01064f0d0020002014410c6c6a41e0006a2111200020144103746a41086a2101201441016a21140c010b02400240200028020022010d00201642808080807083200bad84211641002113410021010c010b2000330104422086200bad842116410121130b201621152016210902402016422088a7220020012f0106490d0003402009221542ffffffff0f832109201341016a211320012f01042200200128020022012f01064f0d000b0b20012000410c6c6a2114200120004103746a2110200041027420016a41e8016a28020021002015a7210b02402013417f6a2201450d00034020002802e40121002001417f6a22010d000b0b201441e0006a2111201041086a2101410021140b20012d0000210e02400240200228025c20022802602213460d00200228025821100c010b201341016a22102013490d0c2013410174220f2010200f20104b1b220f4100480d0c0240024020130d00200f102121100c010b20022802582013200f102521100b2010450d032002200f36025c20022010360258200228026021130b2002201341016a360260201020136a200e3a000020012d0001210e02400240200228025c20022802602213460d00200228025821100c010b201341016a22102013490d0c2013410174220f2010200f20104b1b220f4100480d0c0240024020130d00200f102121100c010b20022802582013200f102521100b2010450d042002200f36025c20022010360258200228026021130b2002201341016a360260201020136a200e3a000020012d0002210e02400240200228025c20022802602213460d00200228025821100c010b201341016a22102013490d0c2013410174220f2010200f20104b1b220f4100480d0c0240024020130d00200f102121100c010b20022802582013200f102521100b2010450d052002200f36025c20022010360258200228026021130b2002201341016a360260201020136a200e3a000020012d0003210e02400240200228025c20022802602213460d00200228025821100c010b201341016a22102013490d0c2013410174220f2010200f20104b1b220f4100480d0c0240024020130d00200f102121100c010b20022802582013200f102521100b2010450d062002200f36025c20022010360258200228026021130b2002201341016a360260201020136a200e3a000020012d0004210e02400240200228025c20022802602213460d00200228025821100c010b201341016a22102013490d0c2013410174220f2010200f20104b1b220f4100480d0c0240024020130d00200f102121100c010b20022802582013200f102521100b2010450d072002200f36025c20022010360258200228026021130b2002201341016a360260201020136a200e3a000020012d0005210e02400240200228025c20022802602213460d00200228025821100c010b201341016a22102013490d0c2013410174220f2010200f20104b1b220f4100480d0c0240024020130d00200f102121100c010b20022802582013200f102521100b2010450d082002200f36025c20022010360258200228026021130b2002201341016a360260201020136a200e3a000020012d0006210e02400240200228025c20022802602213460d00200228025821100c010b201341016a22102013490d0c2013410174220f2010200f20104b1b220f4100480d0c0240024020130d00200f102121100c010b20022802582013200f102521100b2010450d092002200f36025c20022010360258200228026021130b2002201341016a360260201020136a200e3a000020012d0007211002400240200228025c20022802602201460d00200228025821130c010b200141016a22132001490d0c2001410174220e2013200e20134b1b220e4100480d0c0240024020010d00200e102121130c010b20022802582001200e102521130b2013450d0a2002200e36025c20022013360258200228026021010b2002200141016a360260201320016a20103a00002011280200211020112802082201200241d8006a105c02400240200228025c2211200228026022136b2001490d00200228025821110c010b201320016a220e2013490d0c20114101742213200e2013200e4b1b22134100480d0c0240024020110d002013102121110c010b200228025820112013102521110b2011450d0b2002201336025c20022011360258200228026021130b2002201320016a360260201120136a2010200110dc041a2012417f6a22120d000b20022802e801210120022802e401211420022802e00121130b200235025821092002350260211520132014200110b401200241c0026a240020092015422086840f0b200f41011030000b200f41011030000b200f41011030000b200f41011030000b200f41011030000b200f41011030000b200f41011030000b200e41011030000b201341011030000b102a000b201441011030000b410141011030000b5602017f027e230041306b2202240020024101410010ff0120024100360228200242013703202002200241206a36022c20022002412c6a106b2002350228210320023502202104200241306a240020042003422086840bfc4505077f027e027f047e067f230041d00e6b22022400024002402001450d00200220003602300c010b200241013602300b2002200136023420024188086a200241306a10e202024002400240024002400240024002400240024002400240024020022903f0084203510d00200241f0006a20024188086a41c80210dc041a200241b8036a200241f0006a41c80210dc041a2002200241b8036a3602800620024188086a20024180066a10b80320022802900821010240200228028c08450d0020022802880810230b20024188086a200241b8036a41c80210dc041a20024180066a20024188086a10f20241012100024020022d0080064101470d00200220022d0083063a003b200220022f0081063b0039200241013a00380c0c0b20024188086a20024180066a41086a41800210dc041a200241d00a6a200241d8086a220310f0030240024002400240024020022903a8084202520d00200241386a41206a22014200370300200241386a41186a22004280808080c000370300200241013a0060200242043703482002427f3703402002420037033820024180066a41206a2204420037030020024180066a41186a22054280808080c000370300200241013a00a80620024204370390062002427f370388062002420037038006200241b80b6a200241386a20024180066a109004200241386a41286a2206200241b80b6a41286a2903003703002001200241b80b6a41206a2903003703002000200241b80b6a41186a290300370300200241386a41106a2207200241b80b6a41106a290300370300200241386a41086a2208200241b80b6a41086a290300370300200220022903b80b3703382004420037030020054280808080c000370300200241013a00a80620024204370390062002427f370388062002420037038006200241e80b6a200241386a20024180066a1090042006200241e80b6a41286a2903003703002001200241e80b6a41206a2903003703002000200241e80b6a41186a2903003703002007200241e80b6a41106a2903003703002008200241e80b6a41086a290300370300200220022903e80b3703382004420037030020054280808080c000370300200241013a00a80620024204370390062002427f370388062002420037038006200241980c6a200241386a20024180066a1090042006200241980c6a41286a2903003703002001200241980c6a41206a2903003703002000200241980c6a41186a2903003703002007200241980c6a41106a2903003703002008200241980c6a41086a290300370300200220022903980c3703382004420037030020054280808080c000370300200241013a00a80620024204370390062002427f370388062002420037038006200241c80c6a200241386a20024180066a1090042006200241c80c6a41286a2903003703002001200241c80c6a41206a2903003703002000200241c80c6a41186a2903003703002007200241c80c6a41106a2903003703002008200241c80c6a41086a290300370300200220022903c80c3703382004420037030020054280808080c000370300200241013a00a80620024204370390062002427f370388062002420037038006200241800d6a200241386a20024180066a1090042006200241800d6a41286a2903003703002001200241800d6a41206a2903003703002000200241800d6a41186a2903003703002007200241800d6a41106a2903003703002008200241800d6a41086a290300370300200220022903800d3703382004420037030020054280808080c000370300200241013a00a80620024204370390062002427f370388062002420037038006200241b00d6a200241386a20024180066a1090042006200241b00d6a41286a2903003703002001200241b00d6a41206a2903003703002000200241b00d6a41186a2903003703002007200241b00d6a41106a2903003703002008200241b00d6a41086a290300370300200220022903b00d3703382004420037030020054280808080c000370300200241013a00a80620024204370390062002427f370388062002420037038006200241e00d6a200241386a20024180066a1090042006200241e00d6a41286a2903003703002001200241e00d6a41206a2903003703002000200241e00d6a41186a2903003703002007200241e00d6a41106a2903003703002008200241e00d6a41086a290300370300200220022903e00d3703382004420037030020054280808080c000370300200241013a00a80620024204370390062002427f370388062002420037038006200241900e6a200241386a20024180066a109004200241940b6a2200200241900e6a41086a290300370200200220022903900e37028c0b200241a40e6a2802002107200241900e6a41186a2802002101200241900e6a41206a2802002108200241b40e6a280200210420022802a00e210520022802ac0e210620022903b80e2109200241d80a6a41086a20002902003703002002200229028c0b3703d80a20022802d80841756a220041084b0d0120000e09020101010101010103020b20022903d00a210a200241900e6a41206a4200370300200241900e6a41186a22044280808080c000370300200241013a00b80e200242043703a00e427f21092002427f3703980e200242003703900e024020022802d808220041174b0d004101200074419080800671450d00200241023a003b200241800e3b0039200241013a00380c0f0b20024180066a41206a2205420037030020024180066a41186a22004280808080c000370300200220022800e00d3602b00d2002200241e30d6a2800003600b30d200241ac066a20022800b30d360000200241013a00a80620024204370390062002427f370388062002420037038006200220022802b00d3600a906200241d80a6a200241900e6a20024180066a109004200241386a41286a2206200241d80a6a41286a290300370300200241386a41206a2207200241d80a6a41206a290300370300200241386a41186a2208200241d80a6a41186a290300370300200241386a41106a220b200241d80a6a41106a290300370300200241386a41086a220c200241d80a6a41086a290300370300200220022903d80a3703382005420037030020004280808080c000370300200241013a00a80620024204370390062002427f370388062002420037038006200241880b6a200241386a20024180066a1090042006200241880b6a41286a2903003703002007200241880b6a41206a2903003703002008200241880b6a41186a290300370300200b200241880b6a41106a290300370300200c200241880b6a41086a290300370300200220022903880b3703382005420037030020004280808080c000370300200241013a00a80620024204370390062002427f370388062002420037038006200241b80b6a200241386a20024180066a1090042006200241b80b6a41286a2903003703002007200241b80b6a41206a2903003703002008200241b80b6a41186a290300370300200b200241b80b6a41106a290300370300200c200241b80b6a41086a290300370300200220022903b80b3703382000420037030020024180066a41106a2207420037030020024180066a41086a220542003703002002420037038006200241c00e6a41086a220041c4fbc400ad4280808080e00084220d1003220641086a290000370300200220062900003703c00e2006102320052000290300370300200220022903c00e37038006200041f9bcc000ad4280808080e000841003220641086a290000370300200220062900003703c00e20061023200720022903c00e220e370300200241900e6a41086a22062005290300370300200241900e6a41106a2205200e370300200420002903003703002002200e3703e00d20022002290380063703900e200241286a200241900e6a4120108f01200228022c410020022802281bad210e024020022903a8084201520d0020022903b00822094200510d06200e200241b8086a290300220f200f200e541b221020097c2010200f7d2009827d21090b20024180066a41206a420037030020024180066a41186a4280808080c000370300200241013a00a80620024204370390062002420037038006200242002009200e7d220e200e2009561b37038806200241e80b6a200241386a20024180066a109004200241900e6a41286a200241e80b6a41286a290300370300200241900e6a41206a200241e80b6a41206a290300370300200241900e6a41186a200241e80b6a41186a2903003703002005200241e80b6a41106a2903003703002006200241e80b6a41086a290300370300200220022903e80b3703900e2000200d1003220441086a290000370300200220042900003703c00e20041023200241b00d6a41086a2000290300370300200220022903c00e3703b00d200041e4bcc000ad4280808080c001841003220441086a290000370300200220042900003703c00e20041023200241800d6a41086a2000290300370300200220022903c00e3703800d200241e00d6a20024188086a10ac0141c00010212200450d06200020022903b00d370000200020022903800d370010200020022900e00d370020200041086a200241b00d6a41086a290300370000200041186a200241800d6a41086a290300370000200041286a200241e00d6a41086a290000370000200041306a200241f00d6a290000370000200041386a200241e00d6a41186a290000370000200241206a200041c000108f012002280224210420022802202105200010230240024020022802d00822002004410020051b2208490d00410c10212205450d09410410212204450d0a2002420437023c2002200436023820024188086a200241386a107102400240200228023c2206200228024022046b4104490d00200228023821070c010b200441046a22072004490d13200641017422042007200420074b1b22044100480d130240024020060d002004102121070c010b200228023820062004102521070b2007450d0c2002200436023c20022007360238200228024021040b410421062002200441046a360240200720046a2000360000200241e00d6a41086a2204200228024022073602002002200229033822093703e00d200541086a200736020020052009370200410021070240200820004f0d00410c10212206450d0d410410212207450d0e2002420437023c2002200736023820024188086a200241386a107102400240200228023c2208200228024022076b4104490d00200228023821080c010b200741046a220b2007490d1420084101742207200b2007200b4b1b22074100480d140240024020080d002007102121080c010b200228023820082007102521080b2008450d102002200736023c20022008360238200228024021070b2002200741046a360240200820076a2000417f6a360000200241e00d6a41086a200228024022003602002002200229033822093703e00d200641086a200036020020062009370200410121070b20024180066a41206a42818080801037030020024180066a41186a200736020020024194066a2007360200200241ac066a200241cb0c6a280000360000200241013a00a8062002200536029c0620022006360290062002427f37038806200220022800c80c3600a9062002200a42ffffffff0f8337038006200241980c6a200241900e6a20024180066a109004200241900e6a41286a200241980c6a41286a290300370300200241900e6a41206a200241980c6a41206a290300370300200241900e6a41186a2207200241980c6a41186a290300370300200241900e6a41106a200241980c6a41106a290300370300200241900e6a41086a200241980c6a41086a290300370300200220022903980c3703900e200241e00d6a41186a22084200370300200241e00d6a41106a2205420037030020044200370300200242003703e00d200241800d6a41086a220641c4fbc400ad4280808080e00084220e1003220041086a290000370300200220002900003703800d2000102320042006290300370300200220022903800d3703e00d200241c00e6a41086a220641c4cec000ad42808080808002841003220041086a290000370300200220002900003703c00e20001023200520022903c00e2209370300200241386a41086a2004290300370300200241386a41106a22002009370300200241386a41186a220b2006290300370300200220093703b00d200220022903e00d370338200241186a200241386a4120108f010240417f200228021c410020022802181b220420016a220620062004491b4280808080f28ba80942808080c0f588fe06200a422088a7221141ff017122061b22092009428094ebdc038022094280ec94a37c7e7c4280cab5ee01562009a76a4b0d00200b420037030020004200370300200241386a41086a220b420037030020024200370338200241800d6a41086a2204200e1003220c41086a2900003703002002200c2900003703800d200c1023200b2004290300370300200220022903800d370338200441a0cec000ad4280808080b002841003220c41086a2900003703002002200c2900003703800d200c1023200020022903800d2209370300200241e00d6a41086a200b2903003703002005200937030020082004290300370300200220093703b00d200220022903383703e00d200241106a200241e00d6a4120108f01417f2002280214410020022802101b2205418094ebdc034180afd0e50220061b2200200aa7220420002004491b6a220620062005491b20004d0d020b200241003a003b200241800c3b0039200241013a003820022802a00e2104024020072802002201450d002001410c6c21002004210103400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b0240200241a40e6a280200450d00200410230b20022802ac0e21040240200241b40e6a2802002201450d002001410c6c21002004210103400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b200241b00e6a280200450d10200410230c100b200241003a003b20024180063b0039200241013a003820022802a00e21040240200241a80e6a2802002201450d002001410c6c21002004210103400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b0240200241a40e6a280200450d00200410230b20022802ac0e21040240200241b40e6a2802002201450d002001410c6c21002004210103400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b200241b00e6a280200450d0f200410230c0f0b20024180066a41206a2200420037030020024180066a41186a22054280808080c000370300200241ac066a2206200241f90c6a41036a2800003600002002420437039006200220022800f90c3600a906200241013a00a8062002427f370388062002427f200a42ffffffff0f83201141ff01714101461b37038006200241c80c6a200241900e6a20024180066a109004200241900e6a41286a200241c80c6a41286a290300370300200241900e6a41206a200241c80c6a41206a290300370300200241900e6a41186a2207200241c80c6a41186a290300370300200241900e6a41106a200241c80c6a41106a290300370300200241900e6a41086a200241c80c6a41086a290300370300200220022903c80c3703900e200220012004200a422888a720022903c0082209200241c8086a290300220a108603200241e00d6a20024188086a2002290300220e200241086a290300220d410141112009200a84501b4100108802024020022802e00d4101470d00200241003a003b20024180023b0039200241013a003820022802a00e2104024020072802002201450d002001410c6c21002004210103400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b0240200241a40e6a280200450d00200410230b20022802ac0e21040240200241b40e6a2802002201450d002001410c6c21002004210103400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b200241b00e6a280200450d0f200410230c0f0b20022903e80d200241e00d6a41106a22012903001091042000420037030020054280808080c0003703002006200241b00d6a41036a2800003600002002420437039006200220022800b00d3600a9062002427f370388062002200e427f200d501b37038006200241013a00a806200241800d6a200241900e6a20024180066a109004200241e00d6a41286a200241800d6a41286a290300370300200241e00d6a41206a200241800d6a41206a290300370300200241e00d6a41186a200241800d6a41186a2903003703002001200241800d6a41106a290300370300200241e00d6a41086a200241800d6a41086a290300370300200220022903800d3703e00d20024180066a200310a502024020022d0080064101470d00200220022d0083063a003b200220022f0081063b0039200241013a003820022802f00d21040240200241f80d6a2802002201450d002001410c6c21002004210103400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b0240200241f40d6a280200450d00200410230b20022802fc0d21040240200241840e6a2802002201450d002001410c6c21002004210103400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b200241800e6a280200450d0f200410230c0f0b200241900e6a41286a20024180066a41306a290300370300200241900e6a41206a20024180066a41286a290300370300200241900e6a41186a20024180066a41206a290300370300200241900e6a41106a20024180066a41186a290300370300200241900e6a41086a20024180066a41106a29030037030020022002290388063703900e200241b00d6a200241e00d6a200241900e6a109004200241386a41086a20022903b00d370300200241386a41106a200241b00d6a41086a290300370300200241386a41186a200241b00d6a41106a290300370300200241386a41206a200241b00d6a41186a290300370300200241386a41286a200241b00d6a41206a290300370300200241386a41306a200241b00d6a41286a290300370300200241003a00380c0e0b200241003a008306418102210020024181023b008106200241013a0080060c0c0b20024180066a200241dc086a10ba010c010b20024180066a200241e0086a10b3030b024020022d0080064101470d0020022f00810620022d0083064110747221000c0a0b200241b00d6a41286a220020024180066a41306a290300370300200241b00d6a41206a220b20024180066a41286a220c290300370300200241b00d6a41186a221120024180066a41206a2212290300370300200241b00d6a41106a221320024180066a41186a2214290300370300200241b00d6a41086a221520024180066a41106a221629030037030020022002290388063703b00d200241900e6a41086a200241d80a6a41086a290300370300200241b40e6a2004360200200241900e6a41206a2008360200200241900e6a41186a2001360200200241a40e6a2007360200200220022903d80a3703900e200220093703b80e200220063602ac0e200220053602a00e200c20002903003703002012200b290300370300201420112903003703002016201329030037030020024180066a41086a2015290300370300200220022903b00d37038006200241e00d6a200241900e6a20024180066a109004200241386a41086a20022903e00d370300200241386a41106a200241e00d6a41086a290300370300200241386a41186a200241e00d6a41106a290300370300200241386a41206a200241e00d6a41186a290300370300200241386a41286a200241e00d6a41206a290300370300200241386a41306a200241e00d6a41286a290300370300200241003a00380c0a0b200241fc006a4104360200200241cc036a4102360200200242023702bc03200241f89fc5003602b80320024104360274200241e0a1c5003602702002410036028406200241c4b8c600360280062002200241f0006a3602c803200220024180066a360278200241b8036a4188a0c5001038000b41e8b8c600102b000b41c00041011030000b410c41041030000b410441011030000b200441011030000b410c41041030000b410441011030000b200741011030000b200241013a0038200220003b0039200220004110763a003b02402001450d002001410c6c21002005210103400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b02402007450d00200510230b02402004450d002004410c6c21002006210103400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b2008450d00200610230b200310db0120022d003821000b024002400240024002400240410110212201450d002002420137028c08200220013602880802400240200041ff01714101460d002002410136029008200141003a0000200241c0006a29030021090240200228028c082200417f6a41074b0d00200041017422044109200441094b1b22044100480d0920012000200410252201450d042002200436028c0820022001360288080b200241093602900820012009370001200241d0006a2802002100200241d8006a280200220120024188086a105c02402001450d0020002001410c6c6a2108034020002802002106200041086a280200220120024188086a105c02400240200228028c08220520022802900822046b2001490d0020022802880821050c010b200420016a22072004490d0b200541017422032007200320074b1b22074100480d0b0240024020050d002007102121050c010b20022802880820052007102521050b2005450d072002200736028c0820022005360288080b2002200420016a36029008200520046a2006200110dc041a2000410c6a22002008470d000b0b200241dc006a2802002100200241e4006a280200220120024188086a105c0240024020010d00200228028c08210620022802900821080c010b20002001410c6c6a2103034020002802002107200041086a280200220120024188086a105c02400240200228028c08220620022802900822046b2001490d0020022802880821050c010b200420016a22052004490d0b200641017422082005200820054b1b22084100480d0b0240024020060d002008102121050c010b20022802880820062008102521050b2005450d082002200836028c082002200536028808200821060b2002200420016a220836029008200520046a2007200110dc041a2000410c6a22002003470d000b0b200241c8006a290300210902400240200620086b4108490d0020022802880821010c010b200841086a22012008490d09200641017422002001200020014b1b22004100480d090240024020060d002000102121010c010b20022802880820062000102521010b2001450d072002200036028c0820022001360288080b2002200841086a36029008200120086a2009370000200241e8006a2d000021050240200228028c082002280290082200470d00200041016a22042000490d09200041017422062004200620044b1b22044100480d090240024020000d002004102121010c010b200120002004102521010b2001450d082002200436028c0820022001360288080b2002200041016a220436029008200120006a20053a00000c010b2002410136029008200141013a0000200241386a41017220024188086a108a04200228029008210420022802880821010b2004ad4220862001ad842109024020022d00380d000240200241d8006a2802002200450d00200241d0006a28020021012000410c6c210003400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b0240200241d4006a280200450d00200228025010230b0240200241e4006a2802002200450d00200241dc006a28020021012000410c6c210003400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b200241e0006a280200450d00200228025c10230b200241d00e6a240020090f0b410141011030000b200441011030000b200741011030000b200841011030000b200041011030000b200441011030000b102a000bd40505017f027e077f017e017f230041206b220324002002290300210420012903002105200141106a2106200228021021070240024002400240024002400240200141146a2802002208200141186a28020022096b200241186a280200220a490d00200628020021080c010b2009200a6a220b2009490d032008410174220c200b200c200b4b1b220bad420c7e220d422088a70d03200da7220c4100480d030240024020080d00200c102121080c010b20062802002008410c6c200c102521080b2008450d0120012008360210200141146a200b3602000b20082009410c6c6a2007200a410c6c10dc041a200141186a2009200a6a36020020024100360218200341086a200641086a280200360200200320062902003703002001411c6a2106200228021c210b02400240200141206a2802002208200141246a28020022096b200241246a280200220a490d00200628020021080c010b2009200a6a220c2009490d032008410174220e200c200e200c4b1b220cad420c7e220d422088a70d03200da7220e4100480d030240024020080d00200e102121080c010b20062802002008410c6c200e102521080b2008450d022001200836021c200141206a200c3602000b427f200520047c220420042005541b210520082009410c6c6a200b200a410c6c10dc041a200141246a2009200a6a36020020024100360224200341106a41086a200641086a28020036020020032006290200370310200229030822042001290308220d200d2004561b210420012d0028450d034101210120022d0028450d030c040b200c41041030000b200e41041030000b102a000b410021010b20002005370300200020032903003702102000200329031037021c200020013a002820002004370308200041186a200341086a280200360200200041246a200341106a41086a2802003602000240200241146a280200450d00200710230b0240200241206a280200450d00200b10230b200341206a24000bb30c06017f027e057f017e037f017e230041f0016b22022400200241f8006a20002001108703200241f8006a41106a290300210020022903800121010240024020022903782203a7450d00200241c0006a200142004204420010e104200241306a420042002001420010e104200241d0006a2002290340200241c0006a41086a2903002203200042028620022903307c7c22044205420010e20442b3e6cc99b3e6cc99332002290350200042ffffffffffffffff3f8320005220022903384200527220042003547222051b220320012001200356200042b3e6cc99b3e6cc9933200241d0006a41086a29030020051b22035620002003511b22051b22042003200020051b220310c902200241e0006a200120047d200020037d2001200454ad7d108703200241e0006a41106a290300210120022903682100024020022903602203a7450d00200241b0016a10d502200241b0016a2000200110da020c020b2003500d01200241b0016a41186a22064200370300200241b0016a41106a22074200370300200241b0016a41086a22084200370300200242003703b001200241e0016a41086a220541d5fbc400ad428080808080018422041003220941086a290000370300200220092900003703e0012009102320082005290300370300200220022903e00122033703d001200220033703b001200541d6a0c200ad4280808080d00184220a1003220941086a290000370300200220092900003703e00120091023200720022903e001220337030020024190016a41086a220b200829030037030020024190016a41106a220c200337030020024190016a41186a220d2005290300370300200220033703d001200220022903b00137039001200241186a20024190016a4120108902200241186a41106a29030021032002290320210e20022802182109200642003703002007420037030020084200370300200242003703b001200520041003220741086a290000370300200220072900003703e0012007102320082005290300370300200220022903e00122043703d001200220043703b0012005200a1003220741086a290000370300200220072900003703e00120071023200620052903002204370300200b2008290300370300200c20022903e001220a370300200d20043703002002200a3703d001200220022903b00137039001200242002003420020091b220320017d200e420020091b2201200054ad7d2204200120007d2200200156200420035620042003511b22051b3703b80120024200200020051b3703b00120024190016aad4280808080800484200241b0016aad428080808080028410020c010b2003500d00200241b0016a41186a22064200370300200241b0016a41106a22074200370300200241b0016a41086a22084200370300200242003703b001200241e0016a41086a220541d5fbc400ad428080808080018422041003220941086a290000370300200220092900003703e0012009102320082005290300370300200220022903e00122033703d001200220033703b001200541d6a0c200ad4280808080d00184220a1003220941086a290000370300200220092900003703e00120091023200720022903e001220337030020024190016a41086a220b200829030037030020024190016a41106a220c200337030020024190016a41186a220d2005290300370300200220033703d001200220022903b00137039001200220024190016a4120108902200241106a29030021032002290308210e20022802002109200642003703002007420037030020084200370300200242003703b001200520041003220741086a290000370300200220072900003703e0012007102320082005290300370300200220022903e00122043703d001200220043703b0012005200a1003220741086a290000370300200220072900003703e00120071023200620052903002204370300200b2008290300370300200c20022903e001220a370300200d20043703002002200a3703d001200220022903b00137039001200242002003420020091b220320007d200e420020091b2200200154ad7d2204200020017d2201200056200420035620042003511b22051b3703b80120024200200120051b3703b00120024190016aad4280808080800484200241b0016aad428080808080028410020b200241f0016a24000bb53c07047f017e047f017e037f027e1a7f23004180046b2202240002400240024002400240024002400240024020014104490d0020002800002103410041002802ecbe462200410120001b3602ecbe460240200041014b0d000240024020000e020001000b410041f0adc0003602f4be46410041c4b8c6003602f0be46410041023602ecbe460c010b034041002802ecbe464101460d000b0b10104101470d05200241b0016a41186a4200370300200241b0016a41106a22044200370300200241b0016a41086a22014200370300200242003703b001200241206a41086a22004194fcc400ad42808080808001841003220541086a290000370300200220052900003703202005102320012000290300370300200220022903203703b00120004195dfc000ad42808080808001841003220541086a2900003703002002200529000037032020051023200420022903202206370300200241e0006a41086a2001290300370300200241e0006a41106a2006370300200241e0006a41186a2000290300370300200220063703a001200220022903b001370360200241106a200241e0006a4120108f01200228021421002002280210210141002105200241b0016a410041cce2c000ad4280808080e0038410111090012000410020011b21010240024020022802b00122000d00410121040c010b20022902b4012206422088a72205450d0320002d0000220441014b0d032005417f6a2105410021070240024020040e020100010b410121070b20054104490d032000280001210502400240024020070d0020052003460d0141002104200520034f0d02410121040c020b4101210420052001490d010b410021040b200021050b200120034f0d012004450d010240410110212200450d00200041003a0000024020004101410510252200450d00200020033600012002200536026020022006370264200241b0016a200241e0006a10840220022802b4012101410041cce2c000ad4280808080e0038420023502b80142208620022802b0012207ad842000ad4280808080d000841012210402402001450d00200710230b02402005450d002006a7450d00200510230b200010234101210820044101470d0720022003360218200241b0016a41186a4200370300200241b0016a41106a22094200370300200241b0016a41086a22014200370300200242003703b001200241206a41086a22004194fcc400ad42808080808001841003220541086a290000370300200220052900003703202005102320012000290300370300200220022903203703b0012000419ddfc000ad4280808080c000841003220541086a2900003703002002200529000037032020051023200920022903202206370300200241e0006a41086a2001290300370300200241e0006a41106a2006370300200241e0006a41186a2000290300370300200220063703a001200220022903b001370360200241b0016a200241e0006a10bc0120022802b001210a20022902b401210b200241b0016a41e9dabdf30610930420022802b001210320022802b40121070240024002400240024020022802b80122010d004100210c4100210d0c010b20014105742200410575220c41ffffff3f71200c470d0e20004100480d0e200010212208450d01200320006a210e20014105742104410021000340200320006a22012900002106200141086a290000210f200141106a2900002110200820006a220541186a200141186a290000370000200541106a2010370000200541086a200f370000200520063700002004200041206a2200470d000b200e20036b41606a41057641016a210d0b02402007450d00200310230b200d4115490d084101450d02200d41017622114105742200417f4c0d02200010212212450d01200841606a2113200841a07f6a211441042115410021164100211741002118200d2119034020192107410021194101210402402007417f6a2205450d00024002400240024002400240200820054105746a2007410574220e20086a41406a412010de044100480d002007417e6a21032014200e6a210041002119410021010340024020032001470d00200721040c080b200141016a2101200041206a2000412010de042105200041606a21002005417f4a0d000b200141016a21042001417f7320076a21050c010b2014200e6a210002400340024020054101470d00410021050c020b2005417f6a2105200041206a2000412010de042101200041606a210020014100480d000b0b20072005490d012007200d4b0d03200720056b22044101762203450d002013200e6a2100200820054105746a21010340200241b0016a41186a220e200141186a221a290000370300200241b0016a41106a221b200141106a221c290000370300200241b0016a41086a221d200141086a221e290000370300200220012900003703b001200041086a221f2900002106200041106a2220290000210f200041186a2219290000211020012000290000370000201a2010370000201c200f370000201e20063700002019200e2903003700002020201b290300370000201f201d290300370000200020022903b001370000200041606a2100200141206a21012003417f6a22030d000b0b024020050d00200521190c050b0240200441094d0d00200521190c050b2007200d4b0d01200720056b2103200820054105746a210e034020072005417f6a2219490d040240200720196b22044102490d00200820054105746a2200200820194105746a2205412010de04417f4a0d00200241b0016a41186a221d200541186a2201290000370300200241b0016a41106a221e200541106a221a290000370300200241b0016a41086a221f200541086a221b290000370300200220052900003703b00120052000290000370000201b200041086a290000370000201a200041106a2900003700002001200041186a2900003700004101211c024020044103490d00200541c0006a200241b0016a412010de04417f4a0d0041022101200e210002400340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a221a29000037000020032001460d01200041c0006a211b2001211c201a2100200141016a2101201b200241b0016a412010de04417f4a0d020c000b0b2001211c0b2005201c4105746a220020022903b001370000200041186a201d290300370000200041106a201e290300370000200041086a201f2903003700000b2019450d05200e41606a210e200341016a2103201921052004410a4f0d050c000b0b20052007103e000b20072005417f6a2219490d010b2007200d1036000b20192007103e000b02400240024020182016470d00201641016a22002016490d11201641017422012000200120004b1b220041ffffffff01712000470d11200041037422014100480d110240024020160d002001102121150c010b201520164103742001102521150b2015450d0120002116201721180b201520184103746a2200200436020420002019360200201741016a2218211720184102490d0102400340024002400240024020152018417f6a22174103746a2200280200450d00201841037420156a220341746a2802002205200028020422014d0d000240201841024b0d0020182117410221180c080b20152018417d6a221d4103746a2802042200200120056a4d0d010240201841034b0d0020182117410321180c080b200341646a280200200020056a4d0d01201821170c070b20184103490d012000280204210120152018417d6a221d4103746a28020421000b20002001490d010b2018417e6a211d0b0240024002400240024002402018201d41016a22214b2222450d002018201d4b2223450d012015201d4103746a221e2802042224201e2802006a2200201520214103746a221f2802002220490d022000200d4b0d03200820204105746a221b201f280204221c41057422016a210320004105742105200020206b2207201c6b2200201c4f0d04201220032000410574220110dc04221a20016a210402400240201c4101480d00200041014e0d010b20032100201a21010c060b201320056a21052003210003402005200041606a2203200441606a220720072003412010de04410048220e1b2201290000370000200541186a200141186a290000370000200541106a200141106a290000370000200541086a200141086a29000037000020042007200e1b21040240201b20032000200e1b2200490d00201a21010c070b200541606a2105201a2101201a2004490d000c060b0b4198bfc10020212018102d000b4198bfc100201d2018102d000b20202000103e000b2000200d1036000b2012201b200110dc04221a20016a210402400240201c4101480d002007201c4a0d010b201b2100201a21010c010b200820056a210e201a2101201b2100034020002003200120032001412010de0441004822071b2205290000370000200041186a200541186a290000370000200041106a200541106a290000370000200041086a200541086a2900003700002001200141206a20071b2101200041206a2100200341206a200320071b2203200e4f0d01200420014b0d000b0b20002001200420016b41607110dc041a02402023450d00201e2020360200201e41046a2024201c6a3602002022450d02201f201f41086a20182021417f736a41037410dd041a20172118201741014d0d040c010b0b41a8bfc100201d2018102d000b41b8bbc000102b000b200141041030000b20190d000b02402016450d00201510230b2011450d09201210230c090b200041011030000b200041011030000b102f000b410541011030000b410141011030000b200241ec006a4104360200200241c4016a4102360200200242023702b401200241f89fc5003602b00120024104360264200241fca1c50036026020024100360224200241c4b8c6003602202002200241e0006a3602c0012002200241206a360268200241b0016a4188a0c5001038000b2000450d032006a7450d03200510230c030b02402006a7450d00200010230b41e0b4c000ad4280808080d0058410080c020b200d4102490d002008200d417f6a22014105746a21044101210503400240024002400240200d20012200417f6a2201490d00200d20016b22074102490d03200820004105746a2200200820014105746a2203412010de04417f4a0d03200241b0016a41186a2218200341186a220e290000370300200241b0016a41106a221c200341106a221a290000370300200241b0016a41086a2215200341086a221b290000370300200220032900003703b00120032000290000370000201b200041086a290000370000201a200041106a290000370000200e200041186a2900003700004101210020074103490d02200341c0006a200241b0016a412010de04417f4a0d0241002107200421000340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a221a29000037000020052007220e460d02200e417f6a2107200041c0006a211b201a2100201b200241b0016a412010de04417f4a0d020c000b0b2001200d103e000b4102200e6b21000b200320004105746a220020022903b001370000200041186a2018290300370000200041106a201c290300370000200041086a20152903003700000b200441606a21042005417f6a210520010d000b0b41012100200a4101200a1b2119200b4200200a1b2206a721230240024002402006422088a722010d0041002101410021030c010b201920014105746a211b200241c8026a2125200241f1026a211f200241b0016a41027221204100211e410021214101211741002107201921040240024003400240024002400240200d41014b0d004100210141002103410121000240200d0e020800080b0340200241b0016a41186a200441186a290000370300200241b0016a41106a200441106a290000370300200241b0016a41086a200441086a290000370300200220042900003703b0012008200241b0016a412010de04450d03200741016a2107201b200441206a2204470d000c020b0b0340200241b0016a41186a200441186a290000370300200241b0016a41106a200441106a290000370300200241b0016a41086a200441086a290000370300200220042900003703b001200441206a21040240200d450d0041002100200d210103402001410176220520006a22032000200820034105746a200241b0016a412010de044101481b2100200120056b220141014b0d000b200820004105746a200241b0016a412010de04450d040b200741016a21072004201b470d000b0b201e210120212103201721000c050b200441206a2104410021000b0240200d20004b0d0041ece2c0002000200d102d000b2002200736021c200241b0016a41186a22054200370300200241b0016a41106a22034200370300200241b0016a41086a22014200370300200242003703b001200241206a41086a221d41f7fbc400ad4280808080f0008422101003220e41086a2900003703002002200e290000370320200e10232001201d290300370300200220022903203703b001201d41e7acc500ad4280808080a001841003220e41086a2900003703002002200e290000370320200e1023200241a0016a41086a2218201d290300220637030020022002290320220f3703a0012009200f370000200941086a221c2006370000200241e0006a41086a22122001290300370300200241e0006a41106a22162003290300370300200241e0006a41186a22132005290300370300200220022903b001370360200241b0016a200241e0006a412010bb0120022802b001220e4101200e1b211a0240024002400240200720022902b4014200200e1b2206422088a7490d002006a7450d01201a10230c010b2007201a20074105746a10b701210e02402006a7450d00201a10230b200e0d010b200241b0016a1094040240024002400240024002400240024020022802b001220a450d0020022802c401212420022802c001212620022802bc01211420022802b801212220022802b401212720022802182111200542003703002003420037030020014200370300200242003703b001201d20101003220e41086a2900003703002002200e290000370320200e10232001201d290300370300200220022903203703b001201d4194b7c200ad4280808080c001841003220e41086a2900003703002002200e290000370320200e10232018201d290300220637030020022002290320220f3703a0012009200f370000201c2006370000201220012903003703002016200329030037030020132005290300370300200220022903b001370360200241086a200241e0006a4120108f01200228020c212820022802082129200228021c212a200242013703b001200241003602b801410410212201450d0120024284808080c0003702b401200220013602b001200120113600002022200241b0016a105c0240024020022802b401220520022802b80122016b2022490d0020022802b00121050c010b200120226a22032001490d132005410174220e2003200e20034b1b22034100480d130240024020050d002003102121050c010b20022802b00120052003102521050b2005450d03200220033602b401200220053602b0010b2002200120226a3602b801200520016a200a202210dc041a2024200241b0016a105c2024450d0320142024410c6c6a211520142105034020052802002118200541086a2802002201200241b0016a105c0240024020022802b401220e20022802b80122036b2001490d0020022802b001211a0c010b200320016a221a2003490d14200e410174221c201a201c201a4b1b221c4100480d1402400240200e0d00201c1021211a0c010b20022802b001200e201c1025211a0b201a450d062002201c3602b4012002201a3602b001201c210e0b2002200320016a221c3602b801201a20036a2018200110dc041a2005410c6a22052015470d000c060b0b410221050c050b410441011030000b200341011030000b20022802b401210e20022802b801211c0c010b201c41011030000b02400240200e201c6b4104490d0020022802b00121010c010b201c41046a2201201c490d0d200e41017422052001200520014b1b22054100480d0d02400240200e0d002005102121010c010b20022802b001200e2005102521010b2001450d04200220053602b401200220013602b0012005210e0b2002201c41046a22053602b8012001201c6a2028410020291b221a36000002400240200e20056b41034d0d00200e21030c010b200541046a22032005490d0d200e41017422182003201820034b1b22034100480d0d02400240200e0d002003102121010c010b2001200e2003102521010b2001450d06200220033602b401200220013602b0010b200120056a202a360000200241b0016a41e9dabdf306200820004105746a2001201c41086a10950420022d00b0014101460d0102402003450d00200110230b02402027450d00200a10230b02402024450d002024410c6c21012014210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b410121052026450d00201410230b4100210102402023450d00201910230b20212103201721000c070b201d202041086a290000370300200241206a41106a2200202041106a290000370300200241206a41186a2205202041186a290000370300200241206a41206a220e202041206a290000370300200241206a41286a2218202041286a290000370300200241206a41306a221c202041306a290000370300200241206a41376a2215202041376a2900003700002002202029000037032020022d00b101212802402003450d00200110230b200241e0006a41376a22012015290000370000200241e0006a41306a2203201c290300370300200241e0006a41286a221c2018290300370300200241e0006a41206a2218200e29030037030020132005290300370300201620002903003703002012201d29030037030020022002290320370360024041002802e8be464103490d00200241123602ac01200241123602a4012002200241186a3602a80120022002411c6a3602a00141002802f4be46210041002802f0be46210541002802ecbe46210e200241a7033602f001200242dd808080103703e801200241a4e3c0003602e401200242103702dc0120024194e3c0003602d801200242023703d001200242023703c001200241fce2c0003602bc01200241083602b8012002418ce3c0003602b401200241033602b001200041a8b1c000200e410246220e1b28021021002002200241a0016a3602cc01200541c0b1c000200e1b200241b0016a20001102000b201f2002290360370000201f41086a2012290300370000201f41106a2016290300370000201f41186a2013290300370000201f41206a2018290300370000201f41286a201c290300370000201f41306a2003290300370000201f41376a2001290000370000200220283a00f0022002202a3602ec022002201a3602e802200220243602e402200220263602e002200220143602dc02200220223602d802200220273602d4022002200a3602d002200220113602cc022002410b3602c80220024202370398022002200241b0016a3602fc03200241a0016a200241fc036a10b80320022802a00120022802a40120022802a8011096042100202510db010240201e2021470d00201e41016a2201201e490d0b201e41017422052001200520014b1b22214100480d0b02400240201e0d002021102121170c010b2017201e2021102521170b2017450d050b2017201e6a4103410420001b3a0000201e41016a211e0b200741016a2107201e210120212103201721002004201b460d040c010b0b200541011030000b200341011030000b202141011030000b02402023450d00201910230b4104210502400240024002402001450d00024020002d00002207417c6a220441014b0d0020040e020201020b200721050b20030d010c020b0240024020014101470d00410421050c010b20002d00012205417c6a220441014b0d0041042105024020040e020001000b4102210403402004450d08024020012004470d00410421050c020b200020046a2107200441016a21044104210520072d000022074104460d000b20074105460d00200721050b2003450d010b200010230b4101210120054104470d0020022802182101410110212200450d02200041013a000020004101410510252200450d0320002001360001410041cce2c000ad4280808080e003842000ad4280808080d00084101320001023200c450d01200810230c010b0240200c450d00200810230b02402001200345720d00200010230b412e2103418db5c0002100200241a0016a2101024002400240024020050e0400010203000b412d210341e0b4c0002100200241206a21010c020b411f210341c1b4c0002100200241e0006a21010c010b4193b4c0002100200241b0016a21010b20012003360204200120003602002003ad4220862000ad8410080b20024180046a240042010f0b410141011030000b410541011030000b102a000b8b0503017f017e0a7f230041e0006b220224002002200136020c20022002410c6a101c22034220883e0214200220033e02102002200241106a106e024020022802000d00024002400240200228021422044160712205417f4c0d002002280204210602400240200441057622010d00410121070c010b200510212207450d020b2001ad2103024002402006450d0041002108034020042109200241003a0058200841016a210841002101024002400240034020092001460d01200241386a20016a200228021022052d00003a00002002200541016a3602102002200141016a22053a00582005210120054120470d000b200241186a41186a220a200241386a41186a290300370300200241186a41106a220b200241386a41106a290300370300200241186a41086a220c200241386a41086a290300370300200220022903383703182003a72003422088a72201470d020240200141016a22042001490d002001410174220d20042004200d491b220441ffffff3f712004470d002004410574220d41004e0d020b102a000b200241003602140240200141ff0171450d00200241003a00580b2003a7450d08200710230c080b0240024020010d00200d102121070c010b20072001410574200d102521070b2007450d062003428080808070832004ad8421030b200920056b2104200720014105746a22012002290318370000200141186a200a290300370000200141106a200b290300370000200141086a200c29030037000020034280808080107c210320082006470d000b2002200920056b3602140c010b2007450d040b2000200337020420002007360200200241e0006a24000f0b102f000b200541011030000b200d41011030000b41f4b7c600412e200241386a41e4b7c6001031000b890603017f017e0c7f230041306b22012400200110192202a7220336022020012002422088a7220436022402402004450d0020032d0000210520012004417f6a3602242001200341016a360220200541014b0d00024002400240024002400240024002400240024020050e020001000b200141186a200141206a106e20012802180d0920012802242203200128021c2206490d092006417f4c0d020240024020060d004101210741010d010c0b0b200610272207450d08200720012802202204200610dc0421052001200320066b3602242001200420066a3602202005450d0a0b200141106a200141206a106e20012802100d082001280224410c6e2208410c6c2203417f4c0d02200128021421090240024020030d004104210a0c010b20031021220a450d040b024002402009450d004100210b410021044100210c0340200141086a200141206a106e20012802080d0220012802242205200128020c2203490d022003417f4c0d050240024020030d004101210d0c010b20031027220d450d08200d2001280220220e200310dc041a2001200520036b3602242001200e20036a3602200b200c41016a21050240200c2008470d00200b2005200b20054b1b2208ad420c7e2202422088a70d0a2002a7220e4100480d0a02400240200c0d00200e1021210a0c010b200a2004200e1025210a0b200a450d090b200a20046a220c200d360200200c41046a2003ad2202422086200284370200200b41026a210b2004410c6a21042005210c20092005470d000b0b200a450d0920070d020c0a0b0240200c450d00200a210303400240200341046a280200450d00200328020010230b2003410c6a2103200441746a22040d000b0b2008450d08200a10230c080b410021070b2000200636020420002007360200200041146a2009360200200041106a20083602002000410c6a200a360200200041086a2006360200200141306a24000f0b102f000b200341041030000b200341011030000b200e41041030000b102a000b200641011030000b2006450d00200710230b41f4b7c600412e200141286a41a4b8c6001031000b8e0402017f017e23004190016b22052400200520013602040240200541046a20022004ad4220862003ad84101d2206422088a72201450d002006a722042d0000220341014b0d00410021020240024020030e020100010b41002102200541003a008801200441016a21042001417f6a21010340024020012002470d00200241ff0171450d03200541003a0088010c030b200541c8006a20026a200420026a2d00003a00002005200241016a22033a00880120032102200341c000470d000b200541086a41386a200541c8006a41386a290300370300200541086a41306a200541c8006a41306a290300370300200541086a41286a200541c8006a41286a290300370300200541086a41206a200541c8006a41206a290300370300200541086a41186a200541c8006a41186a290300370300200541086a41106a200541c8006a41106a290300370300200541086a41086a200541c8006a41086a29030037030020052005290348370308410121020b200020023a000020002005290308370001200041096a200541106a290300370000200041116a200541186a290300370000200041196a200541206a290300370000200041216a200541286a290300370000200041296a200541306a290300370000200041316a200541386a290300370000200041396a200541c0006a29030037000020054190016a24000f0b41f4b7c600412e200541c8006a41a4b8c6001031000b7603017f017e017f230041106b220324000240024002402002ad4220862000ad8410182204428080808010540d00410121022004a72d0000220541014b0d0020050e020102010b41f4b7c600412e200341086a41a4b8c6001031000b410021020b02402001450d00200010230b200341106a240020020b910302057f027e230041e0006b22022400200241206a41186a4200370300200241206a41106a22034200370300200241206a41086a2204420037030020024200370320200241d0006a41086a22054182fdc400ad4280808080a001841003220641086a29000037030020022006290000370350200610232004200529030037030020022002290350370320200541fccfc300ad4280808080b001841003220641086a2900003703002002200629000037035020061023200320022903502207370300200241086a2004290300370300200241106a2007370300200241186a20052903003703002002200737034020022002290320370300200241206a200210bc01200228022021052002290224210720024100360228200242013703202007420020051b2207422088a72204200241206a105c2005410120051b210602402004450d00200441057421042006210503402005200241206a1071200541206a2105200441606a22040d000b0b2002350228422086200235022084210802402007a7450d00200610230b200241e0006a240020080be604020b7f017e230041306b22022400200210fd01200228020421032002280200210420022802082105200241003602082002420137030020052002105c0240024002400240024002402005450d00200541037421062004210703400240024020072802004101460d0002400240200228020420022802082208460d00200228020021050c010b200841016a22052008490d08200841017422092005200920054b1b22094100480d080240024020080d002009102121050c010b200228020020082009102521050b2005450d0520022009360204200220053602000b2002200841016a220a360208200520086a41003a00000c010b024002402002280204220920022802082208460d00200228020021050c010b200841016a22052008490d07200841017422092005200920054b1b22094100480d070240024020080d002009102121050c010b200228020020082009102521050b2005450d0520022009360204200220053602000b2002200841016a220b360208200520086a41013a0000200741046a280200210c024002402009200b6b4104490d00200841056a210a0c010b200b41046a220a200b490d0720094101742208200a2008200a4b1b22084100480d070240024020090d002008102121050c010b200520092008102521050b2005450d0620022008360204200220053602000b2002200a3602082005200b6a200c3600000b200741086a2107200641786a22060d000c060b0b2002280208210a200228020021050c040b200941011030000b200941011030000b200841011030000b102a000b200aad4220862005ad84210d02402003450d00200410230b200241306a2400200d0bc20404057f017e037f017e230041e0006b22022400200241206a41186a4200370300200241206a41106a22034200370300200241206a41086a2204420037030020024200370320200241d0006a41086a22054191fdc400ad42808080809001841003220641086a2900003703002002200629000037035020061023200420052903003703002002200229035037032020054184ddc100ad4280808080e000841003220641086a2900003703002002200629000037035020061023200320022903502207370300200241086a2004290300370300200241106a2007370300200241186a20052903003703002002200737034020022002290320370300200241206a200210fe01200228022021052002290224210720024100360228200242013703202007420020051b2207422088a72204200241206a105c2005410420051b21080240024002402004450d0020082004412c6c6a2109200821040340200428020021030240024020022802242206200228022822056b4104490d00200228022021060c010b200541046a220a2005490d0420064101742205200a2005200a4b1b22054100480d040240024020060d002005102121060c010b200228022020062005102521060b2006450d032002200536022420022006360220200228022821050b2002200541046a360228200620056a2003360000200441046a200241206a10d3012004412c6a22042009470d000b0b2002350228422086200235022084210b02402007a7450d00200810230b200241e0006a2400200b0f0b200541011030000b102a000bb90703017f027e067f230041d0006b22022400024002400240024002400240024020014104490d00200220002800002200360218200241306a200241186a108702200241086a200241306a109402200241086a41086a290300210320022903082104200241306a2000108002200241306a41086a28020021012002280234210520022802302106410110212200450d012002428180808010370234200220003602300240024020060d0041002101200041003a000042808080801021030c010b200041013a00002001200241306a105c0240024020022802342200200228023822076b2001490d00200228023021000c010b200720016a22082007490d08200041017422092008200920084b1b22084100480d080240024020000d002008102121000c010b200228023020002008102521000b2000450d0420022008360234200220003602300b2002200720016a360238200020076a2006200110dc041a0240024020022802342207200228023822086b4110490d00200841106a21010c010b200841106a22012008490d08200741017422092001200920014b1b22094100480d080240024020070d002009102121000c010b200020072009102521000b2000450d052002200936023420022000360230200921070b200020086a22082003370008200820043700002002200136023802400240200720016b410f4d0d00200721080c010b200141106a22082001490d08200741017422092008200920084b1b22084100480d080240024020070d002008102121000c010b200020072008102521000b2000450d0620022008360234200220003602300b200020016a22074200370008200742003700002002200141106a22073602380240200820076b410f4b0d00200741106a22092007490d082008410174220a2009200a20094b1b22094100480d080240024020080d002009102121000c010b200020082009102521000b2000450d0720022009360234200220003602300b200020076a22074200370008200742003700002002200141206a22013602382001ad4220862103200621010b20032000ad84210302402006450d002005450d00200110230b200241d0006a240020030f0b200241246a4104360200200241c4006a410236020020024202370234200241f89fc5003602302002410436021c20024194a2c5003602182002410036022c200241c4b8c6003602282002200241186a3602402002200241286a360220200241306a4188a0c5001038000b410141011030000b200841011030000b200941011030000b200841011030000b200941011030000b102a000bb80502057f017e230041f0006b220224000240024020014104490d0020002800002103200241d0006a41086a22004182fdc400ad4280808080a001841003220141086a2900003703002002200129000037035020011023200241086a41086a2204200029030037030020022002290350370308200041e8bdc100ad4280808080c000841003220141086a2900003703002002200129000037035020011023200241186a41086a22052000290300370300200220022903503703182002200336024c200241d0006a41186a2203200241cc006aad4280808080c000841001220141186a290000370300200241d0006a41106a2206200141106a2900003703002000200141086a2900003703002002200129000037035020011023200241286a41186a22012003290300370300200241286a41106a22032006290300370300200241286a41086a220620002903003703002002200229035037032841c00010212200450d01200020022903083700002000200229031837001020002002290328370020200041086a2004290300370000200041186a2005290300370000200041286a2006290300370000200041306a2003290300370000200041386a2001290300370000200241d0006a200041c00010c00102400240200228025022010d0041002101200241003602280c010b20022002290254220737022c200220013602282007a74521030b20001023200241d0006a200241286a1084022002350258422086200235025084210702402001450d0020034101710d00200110230b200241f0006a240020070f0b200241346a4104360200200241e4006a410236020020024202370254200241f89fc5003602502002410436022c200241aca2c5003602282002410036021c200241c4b8c6003602182002200241286a3602602002200241186a360230200241d0006a4188a0c5001038000b41c00041011030000bd91003097f017e017f23004180016b220224000240024002400240024002400240024020014104490d00024020014104460d002000410120011b22032d0004220441014b0d0020032800002100410021050240024020040e020100010b2001417b6a4104490d0120032800052106410121050b200241d0006a41086a22014182fdc400ad4280808080a001841003220341086a2900003703002002200329000037035020031023200241106a41086a2204200129030037030020022002290350370310200141f1bdc100ad4280808080a001841003220341086a2900003703002002200329000037035020031023200241c0006a41086a220320012903003703002002200229035037034020022000360250200241e0006a41186a2207200241d0006aad4280808080c000841001220141186a290000370300200241e0006a41106a2208200141106a290000370300200241e0006a41086a2209200141086a2900003703002002200129000037036020011023200241206a41186a220a2007290300370300200241206a41106a22072008290300370300200241206a41086a220820092903003703002002200229036037032041c00010212201450d02200120022903103700002001200229034037001020012002290320370020200141086a2004290300370000200141186a2003290300370000200141286a2008290300370000200141306a2007290300370000200141386a200a290300370000200241086a200141c000108f01200228020c210320022802082104200110230240024020040d004100210a0c010b200241e0006a41186a4200370300200241e0006a41106a22084200370300200241e0006a41086a2204420037030020024200370360200241d0006a41086a220141c4fbc400ad4280808080e000841003220741086a29000037030020022007290000370350200710232004200129030037030020022002290350370360200141f9bcc000ad4280808080e000841003220741086a290000370300200220072900003703502007102320082002290350220b370300200241206a41086a2004290300370300200241206a41106a200b370300200241206a41186a20012903003703002002200b370340200220022903603703202002200241206a4120108f01410021094104210a02402006410020051b2201417f200341016a220520052003491b2203200120034b1b22012002280204410020022802001b2203490d004100210c0c010b200241e0006a2000200110f901200141016a21010240200228026422050d000340024020012003490d004100210c0c030b200241e0006a2000200110f901200141016a210120022802642205450d000b0b2002290368210b2002280260210641101021220a450d04200a200b370208200a2005360204200a2006360200024020012003490d00410121094101210c0c010b410121094101210c0340200241e0006a2000200110f90102400340200141016a2101200228026422050d01200120034f0d03200241e0006a2000200110f9010c000b0b2002290368210b200228026021040240200c2009470d00200941016a22062009490d0b200941017422072006200720064b1b220c41ffffffff0071200c470d0b200c41047422064100480d0b0240024020090d0020061021210a0c010b200a200941047420061025210a0b200a450d070b200a20094104746a2206200536020420062004360200200641086a200b370200200941016a210920012003490d000b0b410110212201450d0520024281808080103702642002200136026002400240200a0d00200141003a00000c010b200141013a00002009200241e0006a105c2009450d00200a20094104746a2108200a21070340200728020021030240024020022802642200200228026822016b4104490d00200228026021000c010b200141046a22052001490d0b200041017422012005200120054b1b22014100480d0b0240024020000d002001102121000c010b200228026020002001102521000b2000450d092002200136026420022000360260200228026821010b2002200141046a360268200020016a200336000020072802042100200728020c2201200241e0006a105c02402001450d002000200141246c6a21040340200028020021050240024020022802642203200228026822016b4104490d00200228026021030c010b200141046a22062001490d0d200341017422012006200120064b1b22014100480d0d0240024020030d002001102121030c010b200228026020032001102521030b2003450d0c2002200136026420022003360260200228026821010b2002200141046a360268200320016a20053600002002200241e0006a360220200041046a200241206a106b200041246a22002004470d000b0b200741106a22072008470d000b0b2002350268422086200235026084210b0240200a450d0002402009450d0020094104742100200a41046a210103400240200141046a280200450d00200128020010230b200141106a2101200041706a22000d000b0b200c450d00200a10230b20024180016a2400200b0f0b2002412c6a4104360200200241f4006a410236020020024202370264200241f89fc50036026020024104360224200241c4a2c50036022020024100360254200241c4b8c6003602502002200241206a3602702002200241d0006a360228200241e0006a4188a0c5001038000b2002412c6a4104360200200241f4006a410236020020024202370264200241f89fc50036026020024104360224200241c4a2c50036022020024100360254200241c4b8c6003602502002200241206a3602702002200241d0006a360228200241e0006a4188a0c5001038000b41c00041011030000b411041041030000b200641041030000b410141011030000b200141011030000b200141011030000b102a000ba20703067f067e017f230041e0006b220224002002411436020c2002418adcc100360208200241106a418adcc100ad4280808080c0028410041090010240024020022802102203450d00200228021421042002200241186a2802002205360224200220033602200240024002402005450d0020022005417f6a3602242002200341016a36022020032d00002105200241c8006a200241206a106d20022802482206450d00200228024c2107200541ff01714101460d012007450d00200610230b20024100360230200242013703282002410c36023c2002200241086a3602382002200241286a36024441012105200241dc006a41013602002002420137024c20024198c2c3003602482002200241386a360258200241c4006a41b8a3c500200241c8006a102e1a200235023042208620023502288410080240200228022c450d00200228022810230b410221070c010b200241d0006a3502004220862007ad84210841012107410021050b02402004450d00200310230b20050d0020074101460d010240024020062802082205ad220942287e220a422088a70d00200aa72204417f4c0d00200628020021030240024020040d00410821060c010b200410212206450d020b0240024020050d004200210a0c010b200541286c21044200210a200621050340200341086a2903002108200341106a290300210b200341186a290300210c2003290300210d200541206a200341206a290300370300200541186a200c370300200541106a200b370300200541086a20083703002005200d370300200541286a2105200a4280808080107c210a200341286a2103200441586a22040d000b0b200a20098421080c030b102f000b200441081030000b42002108410821060b20024100360250200242013703482008422088a72203200241c8006a105c0240024002402003450d002006200341286c6a210e2006210503402005200241c8006a1071200541206a290300210a02400240200228024c2204200228025022036b4108490d00200228024821040c010b200341086a22072003490d04200441017422032007200320074b1b22034100480d040240024020040d002003102121040c010b200228024820042003102521040b2004450d032002200336024c20022004360248200228025021030b2002200341086a360250200420036a200a370000200e200541286a2205470d000b0b2002350250422086200235024884210a02402008a7450d00200610230b200241e0006a2400200a0f0b200341011030000b102a000ba20d03057f017e017f230041d0016b22022400200241d8006a109c03200241086a41186a4200370300200241086a41106a22034200370300200241086a41086a220442003703002002420037030820024188016a41086a220541cafbc400ad4280808080c000841003220641086a290000370300200220062900003703880120061023200420052903003703002002200229038801370308200541f8d0c300ad4280808080a001841003220641086a29000037030020022006290000370388012006102320032002290388012207370300200241b0016a41086a22062004290300370300200241b0016a41106a22042007370300200241b0016a41186a2203200529030037030020022007370368200220022903083703b00120024188016a200241b0016a109d0320022d00880121052003200241a1016a290000370300200420024199016a290000370300200620024191016a29000037030020022002290089013703b0010240024020054101460d00200241e8006a41186a4200370300200241e8006a41106a4200370300200241e8006a41086a4200370300200242003703680c010b200241e8006a41186a2003290300370300200241e8006a41106a2004290300370300200241e8006a41086a2006290300370300200220022903b0013703680b200241086a41186a4204370300200241306a200241d8006a41086a2802003602002002413c6a200241e8006a41086a290300370200200241c4006a200241f8006a290300370200200241cc006a200241e8006a41186a29030037020020024201370318200242d804370310200242f02e3703082002200229035837032820022002290368370234200241013a0054200241003602900120024201370388010240024002400240024002400240410810212205450d002002410836028c012002200228029001220441086a360290012002200536028801200520046a42f02e3700002002290310210702400240200228028c01220420022802900122056b4108490d0020022802880121040c010b200541086a22062005490d07200441017422052006200520064b1b22054100480d070240024020040d002005102121040c010b20022802880120042005102521040b2004450d022002200536028c01200220043602880120022802900121050b2002200541086a36029001200420056a20073700002002290318210702400240200228028c01220420022802900122056b4108490d0020022802880121040c010b200541086a22062005490d07200441017422052006200520064b1b22054100480d070240024020040d002005102121040c010b20022802880120042005102521040b2004450d032002200536028c01200220043602880120022802900121050b2002200541086a36029001200420056a20073700002002290320210702400240200228028c01220420022802900122056b4108490d0020022802880121040c010b200541086a22062005490d07200441017422052006200520064b1b22054100480d070240024020040d002005102121040c010b20022802880120042005102521040b2004450d042002200536028c01200220043602880120022802900121050b2002200541086a36029001200420056a200737000020022802282104200241086a41286a280200220520024188016a105c02402005450d002004200541286c6a21080340200420024188016a1071200441206a290300210702400240200228028c01220620022802900122056b4108490d0020022802880121060c010b200541086a22032005490d09200641017422052003200520034b1b22054100480d090240024020060d002005102121060c010b20022802880120062005102521060b2006450d072002200536028c01200220063602880120022802900121050b2002200541086a36029001200620056a20073700002008200441286a2204470d000b0b200241346a20024188016a109e0320022d0054210602400240200228028c012002280290012205460d0020022802880121040c010b200541016a22042005490d07200541017422032004200320044b1b22034100480d070240024020050d002003102121040c010b20022802880120052003102521040b2004450d062002200336028c01200220043602880120022802900121050b2002200541016a36029001200420056a20063a000020023502900142208620023502880184210702402002412c6a280200450d00200228022810230b200241d0016a240020070f0b410841011030000b200541011030000b200541011030000b200541011030000b200541011030000b200341011030000b102a000be60904057f017e097f017e230041b0016b2202240020024188016a41186a420037030020024188016a41106a2203420037030020024188016a41086a220442003703002002420037038801200241e8006a41086a2205419cfcc400ad4280808080a002841003220641086a29000037030020022006290000370368200610232004200529030037030020022002290368370388012005419ddfc000ad4280808080c000841003220641086a2900003703002002200629000037036820061023200320022903682207370300200241106a41086a2004290300370300200241106a41106a2007370300200241106a41186a2005290300370300200220073703302002200229038801370310200241203602442002200241106a360240200241c8006a200241106aad4280808080800484100410900102400240024002400240200228024822080d00410021030c010b200228024c21092002200241c8006a41086a28020036025c20022008360258200241086a200241d8006a106e02400240024020022802080d00200228025c22054160712204417f4c0d04200228020c210a024002402005410576220b0d00410121030c010b200410212203450d060b0240200a450d004100210c034020052106200241003a00a801200c220d41016a210c41002105024002400240034020062005460d0120024188016a20056a200228025822042d00003a00002002200441016a3602582002200541016a22043a00a8012004210520044120470d000b200241e8006a41186a220e20024188016a41186a290300370300200241e8006a41106a220f20024188016a41106a290300370300200241e8006a41086a221020024188016a41086a2903003703002002200229038801370368200b200d470d020240200d4101742205200c2005200c4b1b220b41ffffff3f71200b470d00200b410574220541004e0d020b102a000b2002410036025c0240200541ff0171450d00200241003a00a8010b20024100360230200b450d05200310230c050b02400240200d0d002005102121030c010b2003200d4105742005102521030b2003450d090b200620046b21052003200d4105746a220d2002290368370000200d41186a200e290300370000200d41106a200f290300370000200d41086a2010290300370000200c200a470d000b200241386a200a3602002002200b360234200220033602302002200620046b36025c200229023421070c030b200241386a200a3602002002200b360234200220033602302003450d01200229023421070c020b200241003602300b4100210320024100360270200242013703682002410c3602342002200241c0006a3602302002200241e8006a3602642002419c016a41013602002002420137028c0120024198c2c300360288012002200241306a36029801200241e4006a41b8a3c50020024188016a102e1a200235027042208620023502688410080240200228026c450d00200228026810230b0b2009450d00200810230b200241003602900120024201370388012007420020031b2207422088a7220520024188016a105c2003410120031b210602402005450d0020054105742104200621050340200520024188016a1071200541206a2105200441606a22040d000b0b20023502900142208620023502880184211102402007a7450d00200610230b200241b0016a240020110f0b102f000b200441011030000b200541011030000b900f03037f027e047f230041e0026b220224000240024020010d002002200136020c200241013602080c010b20022001417f6a36020c2002200041016a36020820002d0000220141014b0d004100210002400240024002400240024002400240024002400240024020010e020100010b2002200241086a106e20022802000d0b200228020c220320022802042201490d0b2001417f4c0d010240024020010d00410121000c010b200110272200450d03200020022802082204200110dc041a2002200320016b36020c2002200420016a3602080b2000450d0b2001ad220542208620058421050b0240024020000d00410021030c010b20054220882206a72201417f4c0d010240024020010d00410121030c010b200110212203450d040b20032000200110dc041a20062005428080808070838421060b200220033602b002200220063702b402200241e7e485f30636029002200241106a200241b0026a10840220022802142104200241106a41186a220720024190026a200235021842208620022802102208ad841014220141186a290000370300200241106a41106a2209200141106a290000370300200241106a41086a220a200141086a2900003703002002200129000037031020011023200241b0016a41186a2007290300370300200241b0016a41106a2009290300370300200241b0016a41086a200a290300370300200220022903103703b00102402004450d00200810230b02402003450d002006a7450d00200310230b410021010240024020000d00410021030c010b20054220882206a72204417f4c0d010240024020040d00410121030c010b200410212203450d050b20032000200410dc041a20062005428080808070838421060b2002200637021420022003360210200241d0016a41e2c289ab06200241106a10a1040240024020000d000c010b20054220882206a72203417f4c0d010240024020030d00410121010c010b200310212201450d060b20012000200310dc041a20062005428080808070838421060b2002200637021420022001360210200241f0016a41e9dabdf306200241106a10a104410021010240024020000d00410021030c010b20054220882206a72204417f4c0d010240024020040d00410121030c010b200410212203450d070b20032000200410dc041a20062005428080808070838421060b200220063702142002200336021020024190026a41f0c2c98b06200241106a10a1040240024020000d000c010b20054220882206a72203417f4c0d010240024020030d00410121010c010b200310212201450d080b20012000200310dc041a20062005428080808070838421060b200220063702d402200220013602d002200241b0026a41e1ea91cb06200241d0026a10a104200241106a41086a200241b0016a41086a290300370300200241106a41106a200241b0016a41106a290300370300200241106a41186a200241b0016a41186a290300370300200241386a200241d0016a41086a290300370300200241c0006a200241d0016a41106a290300370300200241c8006a200241d0016a41186a290300370300200241d8006a200241f0016a41086a290300370300200241e0006a200241f0016a41106a290300370300200241e8006a200241f0016a41186a290300370300200220022903b001370310200220022903d001370330200220022903f00137035020024188016a20024190026a41186a29030037030020024180016a20024190026a41106a290300370300200241f8006a20024190026a41086a29030037030020024198016a200241b0026a41086a290300370300200241a0016a200241b0026a41106a290300370300200241a8016a200241b0026a41186a2903003703002002200229039002370370200220022903b00237039001200241003602b802200242013703b002200241106a200241b0026a1071200241306a200241b0026a1071200241d0006a200241b0026a1071200241f0006a200241b0026a107120024190016a200241b0026a107120022802b802210120022802b402210720022802b002210402402000450d002005a7450d00200010230b200141046a2200417f4c0d000240024020000d00410121030c010b200010212203450d080b2002410036021820022000360214200220033602102001200241106a105c0240024020022802142203200228021822006b2001490d00200228021021030c010b200020016a22092000490d0a2003410174220a2009200a20094b1b22094100480d0a0240024020030d002009102121030c010b200228021020032009102521030b2003450d0920022009360214200220033602100b200320006a2004200110dc041a200020016aad4220862003ad84210502402007450d00200410230b200241e0026a240020050f0b102f000b200141011030000b200141011030000b200441011030000b200341011030000b200441011030000b200341011030000b200041011030000b200941011030000b102a000b200241bc026a4104360200200241246a410236020020024202370214200241f89fc500360210200241043602b402200241d4a2c5003602b0022002410036029402200241c4b8c600360290022002200241b0026a360220200220024190026a3602b802200241106a4188a0c5001038000b810201057f230041306b22032400200341086a200241086a280200360200200320022902003703002003200136020c200341106a200310840220032802142101200341106a41186a22042003410c6a200335021842208620032802102205ad841020220241186a290000370300200341106a41106a2206200241106a290000370300200341106a41086a2207200241086a2900003703002003200229000037031020021023200041186a2004290300370000200041106a2006290300370000200041086a20072903003700002000200329031037000002402001450d00200510230b024020032802002200450d002003280204450d00200010230b200341306a24000bc80503037f047e027f23004190016b2202240041002103200241003a00482000410120011b2104024002400240034020012003460d01200241286a20036a200420036a2d00003a00002002200341016a22003a00482000210320004120470d000b200241086a41186a200241286a41186a22012903002205370300200241086a41106a200241286a41106a22042903002206370300200241086a41086a200241286a41086a22002903002207370300200220022903282208370308200241d0006a41186a2005370300200241d0006a41106a2006370300200241d0006a41086a200737030020022008370350200041c4fbc400ad4280808080e000841003220341086a2900003703002002200329000037032820031023200241f0006a41086a2209200029030037030020022002290328370370200041e4bcc000ad4280808080c001841003220341086a290000370300200220032900003703282003102320024180016a41086a220a20002903003703002002200229032837038001200241286a200241d0006a10ac0141c00010212203450d0120032002290370370000200320022903800137001020032002290028370020200341086a2009290300370000200341186a200a290300370000200341286a2000290000370000200341306a2004290000370000200341386a20012900003700002002200341c000108f01200228020421002002280200210120031023410410212203450d0220032000410020011b36000020024190016a24002003ad4280808080c000840f0b0240200341ff0171450d00200241003a00480b2002413c6a4102360200200241dc006a41043602002002420237022c200241f89fc50036022820024104360254200241f4a2c5003602502002410036020c200241c4b8c6003602082002200241d0006a3602382002200241086a360258200241286a4188a0c5001038000b41c00041011030000b410441011030000bc50402027f027e230041c0056b22022400024002402001450d00200220003602100c010b200241013602100b20022001360214200241f8026a200241106a10e202024002400240024020022903e0034203510d00200241186a200241f8026a41c80210dc041a0240200228021422014104490d0020022802102200280000210320022001417c6a3602142002200041046a360210200241f8026a200241186a41c80210dc041a200241e0026a20024190046a220110f0032002200320022903e0022204a722002004422888a742004200108603200241086a29030021042002290300210520022d00e4022103200110db01410410212201450d022001200036000020014104410810252201450d03200120033a000420014108411510252201450d04200120053700052001410d6a2004370000200241c0056a24002001ad4280808080d002840f0b200241ec026a41043602002002418c036a4102360200200242023702fc02200241f89fc5003602f802200241043602e4022002418ca3c5003602e002200241003602f402200241c4b8c6003602f0022002200241e0026a360288032002200241f0026a3602e802200241f8026a4188a0c5001038000b200241ec026a41043602002002412c6a41023602002002420237021c200241f89fc500360218200241043602e4022002418ca3c5003602e002200241003602f402200241c4b8c6003602f0022002200241e0026a3602282002200241f0026a3602e802200241186a4188a0c5001038000b410441011030000b410841011030000b411541011030000bc00101037f02400240024002402000280200220041046a2802002203200041086a28020022046b2002490d00200028020021030c010b200420026a22052004490d02200341017422042005200420054b1b22044100480d020240024020030d002004102121030c010b200028020020032004102521030b2003450d0120002003360200200041046a2004360200200041086a28020021040b200041086a200420026a360200200320046a2001200210dc041a41000f0b200441011030000b102a000bab0301047f230041106b22022400200028020021002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b0240024002400240200041046a2802002203200041086a28020022046b2001490d00200028020021030c010b200420016a22052004490d02200341017422042005200420054b1b22044100480d020240024020030d002004102121030c010b200028020020032004102521030b2003450d0120002003360200200041046a2004360200200041086a28020021040b200041086a200420016a360200200320046a2002410c6a200110dc041a200241106a240041000f0b200441011030000b102a000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41b8a3c500200241086a102e2101200241206a240020010b13002000410136020420004184a5c5003602000b3400200041a6a3c50036020420004100360200200041146a4103360200200041106a4190a6c500360200200041086a420a3702000bf60201087f230041106b22022400200241003602082002420137030020002802002103024002400240410410212204450d002004200336000020024284808080c00037020420022004360200200028020421052000410c6a28020022002002105c0240024020000d002002280208210420022802042106200228020021030c010b20004102742107200228020421062002280208210003402005280200210802400240200620006b4104490d00200041046a2104200228020021030c010b200041046a22042000490d05200641017422032004200320044b1b22094100480d050240024020060d002009102121030c010b200228020020062009102521030b2003450d042002200936020420022003360200200921060b200541046a210520022004360208200320006a2008360000200421002007417c6a22070d000b0b20012902002004ad4220862003ad84100202402006450d00200310230b200241106a24000f0b410441011030000b200941011030000b102a000b950401067f230041f0006b22032400200341d0006a41086a220441c6acc500ad4280808080f000841003220541086a2900003703002003200529000037035020051023200341086a41086a220620042903003703002003200329035037030820044193adc500ad4280808080b002841003220541086a2900003703002003200529000037035020051023200341186a41086a22072004290300370300200320032903503703182003200136024c200341d0006a41186a2201200341cc006aad4280808080c000841001220541186a290000370300200341d0006a41106a2208200541106a2900003703002004200541086a2900003703002003200529000037035020051023200341286a41186a22052001290300370300200341286a41106a22012008290300370300200341286a41086a22082004290300370300200320032903503703280240024041c00010212204450d00200420032903083700002004200329031837001020042003290328370020200441086a2006290300370000200441186a2007290300370000200441286a2008290300370000200441306a2001290300370000200441386a2005290300370000200341d0006a200210bc03200441c00041800110252204450d0120042003290050370040200441c8006a200341d8006a29000037000020004280818080800a37020420002004360200200341f0006a24000f0b41c00041011030000b41800141011030000b950401067f230041f0006b22032400200341d0006a41086a220441c6acc500ad4280808080f000841003220541086a2900003703002003200529000037035020051023200341086a41086a2206200429030037030020032003290350370308200441a6adc500ad4280808080b002841003220541086a2900003703002003200529000037035020051023200341186a41086a22072004290300370300200320032903503703182003200136024c200341d0006a41186a2201200341cc006aad4280808080c000841001220541186a290000370300200341d0006a41106a2208200541106a2900003703002004200541086a2900003703002003200529000037035020051023200341286a41186a22052001290300370300200341286a41106a22012008290300370300200341286a41086a22082004290300370300200320032903503703280240024041c00010212204450d00200420032903083700002004200329031837001020042003290328370020200441086a2006290300370000200441186a2007290300370000200441286a2008290300370000200441306a2001290300370000200441386a2005290300370000200341d0006a200210bc03200441c00041800110252204450d0120042003290050370040200441c8006a200341d8006a29000037000020004280818080800a37020420002004360200200341f0006a24000f0b41c00041011030000b41800141011030000bad0e03057f017e017f230041e0036b22012400200141d8026a41086a220241c6acc500ad4280808080f000841003220341086a290000370300200120032900003703d80220031023200141d0006a41086a22042002290300370300200120012903d802370350200241e7acc500ad4280808080a001841003220341086a290000370300200120032900003703d8022003102320014190026a41086a22052002290300370300200120012903d80237039002200141d8026a200010ac010240024002400240024041c00010212203450d00200320012903503700002003200129039002370010200320012900d802370020200341086a2004290300370000200341186a2005290300370000200341286a2002290000370000200341306a200141e8026a290000370000200341386a200141d8026a41186a290000370000200141d8026a200341c00010a501024020012d00dc02220241024622000d002003ad428080808080088410050b2001410d6a200141d8026a41057241c30010dc041a200141d0006a2001410d6a41c30010dc041a20000d04200120023a00980120014198016a410172200141d0006a41c10010dc042104200141ba016a21000240024020012d00b9014101460d00200141003602e0010c010b200141e0016a200010a40120012d00980121020b024002400240200241ff01714101460d00200141003602f0010c010b200141f0016a200410a40120012802f0010d010b024020012d00b9014101460d00200141d8026a10ad0420013502e00242208620012802d8022202ad84100520012802dc02450d04200210230c040b200141d8026a10ad0420012802d8022102200120012802e002360294022001200236029002200020014190026a10f50120012802dc02450d03200210230c030b20014180026a41086a200141f0016a41086a2802002202360200200120012903f00122063703800220014190026a2006a72204200210a501024020012d0094024102470d00200141003602a803200142013703a003200141b0036a41146a410f360200200141bc036a410c360200200141073602cc03200141c6acc5003602c8032001410c3602b4032001410a3602d403200141e7acc5003602d003200120014180026a3602c0032001200141d0036a3602b8032001200141c8036a3602b0032001200141a0036a3602dc03200141d8026a41146a4103360200200142033702dc02200141a8ddc0003602d8022001200141b0036a3602e802200141dc036a41b8a3c500200141d8026a102e1a20013502a80342208620013502a00384100820012802a403450d0220012802a00310230c020b200141d8026a20014190026a41c80010dc041a2001419d036a200141b9016a220041206a2d00003a000020014195036a200041186a2900003700002001418d036a200041106a29000037000020014185036a200041086a290000370000200141fd026a2000290000370000200141003602b803200142013703b003200141d8026a200141b0036a10af01200141d8026a410472200141b0036a10a90120012802b40321002002ad4220862004ad8420013502b80342208620012802b0032202ad8410022000450d01200210230c010b41c00041011030000b0240200128028402450d0020012802800210230b410121000c010b410021000b0240024020012802e00122020d00410021040c010b20014180026a41086a200141e0016a41086a2802002204360200200120012903e00122063703800220014190026a2006a72205200410a5010240024020012d0094024102470d00200141003602a803200142013703a003200141b0036a41146a410f360200200141bc036a410c360200200141073602cc03200141c6acc5003602c8032001410c3602b4032001410a3602d403200141e7acc5003602d003200120014180026a3602c0032001200141d0036a3602b8032001200141c8036a3602b0032001200141a0036a3602dc03200141d8026a41146a4103360200200142033702dc02200141ccdcc0003602d8022001200141b0036a3602e802200141dc036a41b8a3c500200141d8026a102e1a20013502a80342208620013502a00384100820012802a403450d0120012802a00310230c010b200141d8026a20014190026a41c80010dc041a200141fc026a200141b8016a2d00003a0000200141f4026a200141b0016a290300370200200141ec026a200141a8016a290300370200200141e4026a20014198016a41086a29030037020020012001290398013702dc02200141003602b803200142013703b003200141d8026a200141b0036a10af01200141d8026a410472200141b0036a10a90120012802b40321072004ad4220862005ad8420013502b80342208620012802b0032204ad8410022007450d00200410230b0240200128028402450d0020012802800210230b410121040b0240200020012802f001220545720d0020012802f401450d00200510230b2004200245720d0020012802e401450d00200210230b20031023200141e0036a24000bc60303047f017e017f230041d0006b22012400200141c0006a41086a220241c6acc500ad4280808080f000841003220341086a2900003703002001200329000037034020031023200141206a41086a2204200229030037030020012001290340370320200241d7acc500ad42808080808002841003220341086a2900003703002001200329000037034020031023200141306a41086a20022903002205370300200141086a2004290300370300200141186a20053703002001200129034022053703302001200129032037030020012005370310024002404101450d004120210302400240024002404120450d004120102122020d01412041011030000b411021030240411010212202450d00200141106a210420022001290300370000200241086a200141086a2903003700000c020b411041011030000b20022001290300370000200241086a200141086a290300370000200141106a210441204110470d010b20022003200341017422064120200641204b1b220610252202450d02200621030b20022004290000370010200241186a200441086a290000370000200041203602082000200336020420002002360200200141d0006a24000f0b102f000b200641011030000b8b0d05027f017e027f017e047f230041f0036b2201240041c6acc500ad4280808080f0008410032202290008210320022800042104200228000021052002102341cdacc500ad4280808080a00184100322022900082106200228000421072002280000210820021023200141d8026a200010ac010240024002400240024041c00010212202450d00200220063700182002200736001420022008360010200220033700082002200436000420022005360000200220012900d802370020200241286a200141e0026a290000370000200241306a200141e8026a290000370000200241386a200141f0026a290000370000200141d8026a200241c00010a801024020012d00e802220041024622040d002002ad428080808080088410050b20012802dc02210520012802d80221072001200141ec026a41c40010dc04220141c4006a200141c40010dc041a20040d0420014188016a200141c4006a41c20010dc041a200141aa016a21040240024020012d00a9014101460d00200141003602d0010c010b200141d0016a200410a7010b02400240024020012d0088014101460d00200141003602e0010c010b200141e0016a20014188016a41017210a70120012802e0010d010b024020012d00a9014101460d00200141d8026a10af0420013502e00242208620012802d8022204ad84100520012802dc02450d04200410230c040b200141d8026a10af0420012802d8022108200120012802e002360284022001200836028002200420014180026a10f50120012802dc02450d03200810230c030b200141f0016a41086a200141e0016a41086a2802002204360200200120012903e00122033703f00120014180026a2003a72209200410a801024020012d0090024102470d00200141003602b803200142013703b003200141c0036a41146a410f360200200141cc036a410c360200200141073602dc03200141c6acc5003602d8032001410c3602c4032001410a3602e403200141cdacc5003602e0032001200141f0016a3602d0032001200141e0036a3602c8032001200141d8036a3602c0032001200141b0036a3602ec03200141d8026a41146a4103360200200142033702dc02200141a8ddc0003602d8022001200141c0036a3602e802200141ec036a41b8a3c500200141d8026a102e1a20013502b80342208620013502b00384100820012802b403450d0220012802b00310230c020b200141d8026a20014180026a41d80010dc041a200141ad036a200141a9016a220841206a2d00003a0000200141a5036a200841186a2900003700002001419d036a200841106a29000037000020014195036a200841086a2900003700002001418d036a2008290000370000200120043602c403200120093602c003200141d8026a200141c0036a10b00420012802dc02450d0120012802d80210230c010b41c00041011030000b024020012802f401450d0020012802f00110230b410121080c010b410021080b0240024020012802d00122040d00410021090c010b200141f0016a41086a200141d0016a41086a2802002209360200200120012903d00122033703f00120014180026a2003a7220a200910a8010240024020012d0090024102470d00200141003602b803200142013703b003200141c0036a41146a410f360200200141cc036a410c360200200141073602dc03200141c6acc5003602d8032001410c3602c4032001410a3602e403200141cdacc5003602e0032001200141f0016a3602d0032001200141e0036a3602c8032001200141d8036a3602c0032001200141b0036a3602ec03200141d8026a41146a4103360200200142033702dc02200141ccdcc0003602d8022001200141c0036a3602e802200141ec036a41b8a3c500200141d8026a102e1a20013502b80342208620013502b00384100820012802b403450d0120012802b00310230c010b200141d8026a20014180026a41d80010dc041a2001418c036a200141a8016a2d00003a000020014184036a200141a0016a290300370200200141fc026a20014198016a290300370200200141f4026a20014188016a41086a29030037020020012001290388013702ec02200120093602c4032001200a3602c003200141d8026a200141c0036a10b00420012802dc02450d0020012802d80210230b024020012802f401450d0020012802f00110230b410121090b0240200820012802e001220a45720d0020012802e401450d00200a10230b2009200445720d0020012802d401450d00200410230b20021023024020004102460d002005450d00200710230b200141f0036a24000bc60303047f017e017f230041d0006b22012400200141c0006a41086a220241c6acc500ad4280808080f000841003220341086a2900003703002001200329000037034020031023200141206a41086a2204200229030037030020012001290340370320200241b6acc500ad42808080808002841003220341086a2900003703002001200329000037034020031023200141306a41086a20022903002205370300200141086a2004290300370300200141186a20053703002001200129034022053703302001200129032037030020012005370310024002404101450d004120210302400240024002404120450d004120102122020d01412041011030000b411021030240411010212202450d00200141106a210420022001290300370000200241086a200141086a2903003700000c020b411041011030000b20022001290300370000200241086a200141086a290300370000200141106a210441204110470d010b20022003200341017422064120200641204b1b220610252202450d02200621030b20022004290000370010200241186a200441086a290000370000200041203602082000200336020420002002360200200141d0006a24000f0b102f000b200641011030000bd90301057f230041106b22022400200241003602082002420137030020002802002103200028020822042002105c02402004450d00200441057421040340200320021071200341206a2103200441606a22040d000b0b200028020c21050240024002400240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22062003490d03200441017422032006200320064b1b22034100480d030240024020040d002003102121040c010b200228020020042003102521040b2004450d012002200336020420022004360200200228020821030b2002200341046a360208200420036a200536000020002d0010210502400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d03200341017422062004200620044b1b22064100480d030240024020030d002006102121040c010b200228020020032006102521040b2004450d022002200636020420022004360200200228020821030b2002200341016a360208200420036a20053a0000200041146a200210a901200228020421032001290200200235020842208620022802002204ad84100202402003450d00200410230b200241106a24000f0b200341011030000b200641011030000b102a000bed0201057f230041c0006b22022400200241206a41086a220341c6acc500ad4280808080f000841003220441086a2900003703002002200429000037032020041023200241086a2205200329030037030020022002290320370300200341b9adc500ad4280808080d001841003220441086a2900003703002002200429000037032020041023200241106a41086a2206200329030037030020022002290320370310200241206a200128020010ac01024041c00010212204450d00200420022903003700002004200229031037001020042002290020370020200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241306a290000370000200441386a200241206a41186a290000370000200241206a200441c00010ab03024020022802282203450d002000200229022c37020c200020022903203702000b2000200336020820041023200241c0006a24000f0b41c00041011030000bea0201057f230041c0006b22022400200241206a41086a220341c6acc500ad4280808080f000841003220441086a2900003703002002200429000037032020041023200241086a2205200329030037030020022002290320370300200341b9adc500ad4280808080d001841003220441086a2900003703002002200429000037032020041023200241106a41086a2206200329030037030020022002290320370310200241206a200110ac01024041c00010212204450d00200420022903003700002004200229031037001020042002290020370020200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241306a290000370000200441386a200241206a41186a290000370000200241206a200441c00010ab03024020022802282203450d002000200229022c37020c200020022903203702000b2000200336020820041023200241c0006a24000f0b41c00041011030000be10501087f230041c0006b22022400200241206a41086a220341c6acc500ad4280808080f000841003220441086a2900003703002002200429000037032020041023200241086a2205200329030037030020022002290320370300200341b9adc500ad4280808080d001841003220441086a2900003703002002200429000037032020041023200241106a41086a2204200329030037030020022002290320370310200241206a200010ac010240024002400240024041c00010212206450d00200620022903003700002006200229031037001020062002290020370020200641086a2005290300370000200641186a2004290300370000200641286a2003290000370000200641306a200241306a290000370000200641386a200241206a41186a290000370000200241003602282002420137032020012802002104410410212203450d0120024284808080c00037022420022003360220200320043600002001280204210420034104410810252203450d02200242888080808001370224200320043600042002200336022020012802082104200141106a2802002201200241206a105c0240024020010d002002280228210720022802242105200228022021030c010b200141027421084100200228022822016b21002002280224210503402004280200210902400240200520006a4104490d00200228022021030c010b200141046a22032001490d07200541017422072003200720034b1b22074100480d070240024020050d002007102121030c010b200228022020052007102521030b2003450d062002200736022420022003360220200721050b200441046a21042002200141046a2207360228200320016a20093600002000417c6a2100200721012008417c6a22080d000b0b2006ad42808080808008842007ad4220862003ad84100202402005450d00200310230b20061023200241c0006a24000f0b41c00041011030000b410441011030000b410841011030000b200741011030000b102a000bc80501067f230041e0006b22012400200141c0006a41086a220241c6acc500ad4280808080f000841003220341086a2900003703002001200329000037034020031023200141086a200229030037030020012001290340370300200241c6adc500ad42808080809001841003220341086a2900003703002001200329000037034020031023200141106a41086a2002290300370300200120012903403703100240024002400240410410212202450d0020014204370244200120023602402000200141c0006a1071200028022021030240024020012802442200200128024822026b4104490d00200128024021000c010b200241046a22042002490d03200041017422022004200220044b1b22024100480d030240024020000d002002102121000c010b200128024020002002102521000b2000450d022001200236024420012000360240200128024821020b2001200241046a360248200020026a200336000020012802442100200141c0006a41186a2203200135024842208620012802402205ad841001220241186a290000370300200141c0006a41106a2204200241106a290000370300200141c0006a41086a2206200241086a2900003703002001200229000037034020021023200141206a41186a2003290300370300200141206a41106a2004290300370300200141206a41086a20062903003703002001200129034037032002402000450d00200510230b41c00010212202450d03200220012903003700002002200129031037001020022001290320370020200241086a200141086a290300370000200241186a200141106a41086a290300370000200241286a200141206a41086a290300370000200241306a200141306a290300370000200241386a200141206a41186a2903003700002002ad4280808080800884100520021023200141e0006a24000f0b410441011030000b200241011030000b102a000b41c00041011030000bf60e04057f017e197f027e230041f0026b22042400200441a0026a41086a220541c6acc500ad4280808080f000841003220641086a290000370300200420062900003703a00220061023200441386a41086a22072005290300370300200420042903a002370338200541acb2c500ad4280808080d000841003220641086a290000370300200420062900003703a00220061023200441e0016a41086a22062005290300370300200420042903a0023703e001200441a0016a200110ac010240024002400240024041c00010212205450d0020052004290338370000200520042903e001370010200520042900a001370020200541086a2007290300370000200541186a2006290300370000200541286a200441a0016a41086a290000370000200541306a200441b0016a290000370000200541386a200441a0016a41186a290000370000200441c00036027c20042005360278200441386a2005ad42808080808008841004109001024020042802382206450d00200428023c210802400240200441c0006a280200450d0020062d000022074103490d010b200441003602e801200442013703e0012004410c36020c2004200441f8006a3602082004200441e0016a3602c001200441b4026a4101360200200442013702a40220044198c2c3003602a0022004200441086a3602b002200441c0016a41b8a3c500200441a0026a102e1a20043502e80142208620043502e001841008024020042802e401450d0020042802e00110230b410321070b02402008450d00200610230b20074103470d020b200510230c020b41c00041011030000b200510230240024020070e03020001020b200441a0026a20012002200310e30220043502a0024201852102200441b0026a2903002109200441a8026a29030021030c030b200441a0026a200110b80420042d00a0024101470d01200441f8016a200441b9026a290000370300200441e0016a41106a200441b1026a290000370300200441e0016a41086a200441a9026a290000370300200420042900a1023703e001200441386a200441e0016a2002200310e30220043502384201852102200441386a41106a2903002109200441386a41086a29030021030c020b200441f8006a200110b80420042d00784101470d00200441c0016a41186a220720044191016a290000370300200441c0016a41106a220520044189016a290000370300200441c0016a41086a220620044181016a290000370300200420042900793703c001200441a0026a200441c0016a10f203200441a0016a41186a22082007290300370300200441a0016a41106a22072005290300370300200441a0016a41086a220a2006290300370300200420042903c0013703a00120042802c002220b450d00200441e0016a41186a220c2008290300370300200441e0016a41106a220d2007290300370300200441e0016a41086a220e200a290300370300200441e0016a41286a2207200441a0026a41086a2208290300370300200441e0016a41306a220a200441a0026a41106a220f290300370300200441e0016a41386a2210200441a0026a41186a2211290300370300200441086a41286a2212200441ec026a2213280200360200200441086a41206a2214200441e4026a2215290200370300200441086a41186a2216200441dc026a2217290200370300200441086a41106a2218200441d4026a2219290200370300200441086a41086a221a200441cc026a221b290200370300200420042903a0013703e001200420042903a00237038002200420042902c402370308200441386a41386a221c2010290300370300200441386a41306a221d200a290300370300200441386a41286a221e2007290300370300200441386a41206a221f200429038002370300200441386a41186a2220200c290300370300200441386a41106a2221200d290300370300200441386a41086a2222200e290300370300200420042903e0013703382010201c290300370300200a201d2903003703002007201e290300370300200441e0016a41206a221c201f290300370300200c2020290300370300200d2021290300370300200e2022290300370300200420042903383703e001200441f8006a41186a2020290300370300200441f8006a41106a2021290300370300200441f8006a41086a20222903003703002004200429033837037820112010290300370300200f200a290300370300200820072903003703002004200b3602c0022004201c2903003703a002200441c4026a22072004290308370200201b201a2903003702002019201829030037020020172016290300370200201520142903003702002013201228020036020020112903002109200f200f290300222320027c22243703002011200920037c2024202354ad7c37030020082903002109200420042903a002222320027c22243703a0022008200920037c2024202354ad7c370300200441c0016a20012002200310e30220043502c00121022005290300210920062903002103200441f8006a200441a0026a10b90402402007280200450d0020042802c00210230b200242018521020c010b420021020b2000200337030820002002370300200041106a2009370300200441f0026a24000bf80302047f027e230041c0016b22022400200241086a200110b8040240024020022d00084101470d0020024180016a41186a200241216a29000037030020024180016a41106a200241196a29000037030020024180016a41086a200241116a2900003703002002200229000937038001200241306a41086a220341c6acc500ad4280808080f000841003220141086a2900003703002002200129000037033020011023200241a0016a41086a22042003290300370300200220022903303703a001200341f7acc500ad4280808080e000841003220141086a2900003703002002200129000037033020011023200241b0016a41086a22052003290300370300200220022903303703b001200241306a20024180016a10ac01024041c00010212201450d00200120022903a001370000200120022903b00137001020012002290030370020200141086a2004290300370000200141186a2005290300370000200141286a2003290000370000200141306a200241306a41106a290000370000200141386a200241306a41186a2203290000370000200241306a200141c00010ad0320032903002106200229034021072002280254210420022802502103200110232003450d012004450d02200310230c020b41c00041011030000b42002107420021060b2000200737030020002006370308200241c0016a24000bb71105017f047e017f057e047f230041b0026b22052400200541a0016a200010b80402400240024020052d00a0014101470d00200541306a41186a200541b9016a290000370300200541c0006a200541b1016a290000370300200541306a41086a200541a9016a290000370300200520052900a101370330200541a0016a200541306a10f20320052802c001450d00200541d0006a200541a0016a41d00010dc041a200541d0006a41086a290300210620052903502107024002402005290360220820012008200154200541d0006a41186a290300220920025420092002511b220a1b220b20092002200a1b220c8450450d002007210d2006210e0c010b200541e8006a220a2009200c7d2008200b54ad7d220d37030020052008200b7d220f37036002400240200f4280c8afa02556200d420052200d501b450d00200b2108200c21090c010b200a420037030020054200370360200d20027c200f20017c2201200f54ad7c21020b20054200200620097d2007200854ad7d220b200720087d220d200756200b200656200b2006511b220a1b220e37035820054200200d200a1b220d370350200220097d2001200854ad7d2102200120087d21010b02400240024002400240200541f8006a28020022100d004100210a410021100c010b2005280270210a201041186c21114100211003400240200a2903002208200120012008562002200a41086a221229030022095620022009511b22131b220b2009200220131b220c84500d00200a2008200b7d220f370300200a2009200c7d2008200b54ad7d220d37030802400240200f4280c8afa02556200d420052200d501b450d00200b2108200c21090c010b200a4200370308200a4200370300200d20027c200f20017c2201200f54ad7c21020b200541d0006a41086a221342002013290300220b20097d2005290350220d200854ad7d220c200d20087d220f200d56200c200b56200c200b511b22131b220e37030020054200200f20131b220d370350200220097d2001200854ad7d2102200120087d210120122903002109200a29030021080b024020082009844200520d00200a41186a210a201041016a2110201141686a22110d010b0b2005280278220a2010490d010b200541003602780240200a20106b220a450d0002402010450d00200528027022132013201041186c6a200a41186c10dd041a200541d8006a290300210e2005290350210d0b2005200a3602780b42002007200d7d220820082007562006200e7d2007200d54ad7d220920065620092006511b220a1b220842002009200a1b22098450450d010c020b41ccbac000102b000b200541a0016a41086a221041d5fbc400ad42808080808001841003220a41086a2900003703002005200a2900003703a001200a102320054190026a41086a22132010290300370300200520052903a00137039002201041e3a0c200ad4280808080b001841003220a41086a2900003703002005200a2900003703a001200a1023200541a0026a41086a22112010290300370300200520052903a0013703a002200541a0016a200010ac0141c0001021220a450d02200a200529039002370000200a20052903a002370010200a20052900a001370020200a41086a2013290300370000200a41186a2011290300370000200a41286a2010290000370000200a41306a200541a0016a41106a290000370000200a41386a200541a0016a41186a290000370000200541186a200a41c000108902200541186a41106a29030021022005290320210120052802182110200a102320002001420020101b22012008200120012008562002420020101b220b200956200b2009511b220a1b22027d200b2009200b200a1b220c7d2001200254ad7d10dc0202400240200820027d220b2009200c7d2008200254ad7d220d844200520d002004427f2004290300220220087c22012001200254220a200441086a2210290300220220097c200aad7c220120025420012002511b220a1b3703002010427f2001200a1b3703000c010b200541a0016a41086a221041d5fbc400ad42808080808001841003220a41086a2900003703002005200a2900003703a001200a102320054190026a41086a22132010290300370300200520052903a00137039002201041eea0c200ad4280808080f001841003220a41086a2900003703002005200a2900003703a001200a1023200541a0026a41086a22112010290300370300200520052903a0013703a002200541a0016a200010ac0141c0001021220a450d04200a200529039002370000200a20052903a002370010200a20052900a001370020200a41086a2013290300370000200a41186a2011290300370000200a41286a2010290000370000200a41306a200541a0016a41106a290000370000200a41386a200541a0016a41186a2900003700002005200a41c000108902200541106a29030021012005290308210f20052802002110200a10232000200f420020101b220f200b200f200f200b562001420020101b220e200d56200e200d511b220a1b22017d200e200d200e200a1b22067d200f200154ad7d10ca022004427f2004290300220f200120027c220e7c22022002200f54220a200441086a221029030022022006200c7c200e200154ad7c7c200aad7c220c200254200c2002511b220a1b3703002010427f200c200a1b370300200b20017d2202200d20067d200b200154ad7d220d84500d00200342002003290300220120027d220b200b200156200341086a220a290300220b200d7d2001200254ad7d2202200b562002200b511b22101b370300200a4200200220101b3703000b200541306a200541d0006a10b904200541d8016a2009370300200541d0016a2008370300200541a0016a41086a41013a0000200541a9016a2000290000370000200541b1016a200041086a290000370000200541b9016a200041106a290000370000200541c1016a200041186a290000370000200541033a00a001200541a0016a108e010b200541f4006a280200450d00200528027010230b200541b0026a24000f0b41c00041011030000b41c00041011030000be50301047f230041f0006b22022400200241086a41086a220341c6acc500ad4280808080f000841003220441086a2900003703002002200429000037030820041023200241306a41086a2205200329030037030020022002290308370330200341f1acc500ad4280808080e000841003220441086a2900003703002002200429000037030820041023200241c0006a41086a2204200329030037030020022002290308370340200241d0006a200110ac01024041c00010212203450d00200320022903303700002003200229034037001020032002290350370020200341086a2005290300370000200341186a2004290300370000200341286a200241d0006a41086a2205290300370000200341306a200241e0006a2204290300370000200341386a200241d0006a41186a2201290300370000200241086a200341c000108a012005200241086a41096a2900003703002004200241086a41116a2900003703002001200241086a41196a290000370300200220022900093703500240024020022d00084101460d00200041003a00000c010b200041013a000020002002290350370001200041096a200241d8006a290300370000200041116a2004290300370000200041196a20012903003700000b20031023200241f0006a24000f0b41c00041011030000bb70401067f230041d0006b22022400200242f3e885db96cddbb320370308200241086a2001412c6a22032001290300200141086a290300417f411f10f701200241306a41086a220441c6acc500ad4280808080f000841003220541086a2900003703002002200529000037033020051023200241106a41086a2206200429030037030020022002290330370310200441f7acc500ad4280808080e000841003220541086a2900003703002002200529000037033020051023200241206a41086a2207200429030037030020022002290330370320200241306a200010ac01024041c00010212205450d00200520022903103700002005200229032037001020052002290030370020200541086a2006290300370000200541186a2007290300370000200541286a2004290000370000200541306a200241306a41106a290000370000200541386a200241306a41186a29000037000020024100360238200242013703302003200241306a107120022001360220200241206a200241306a10c3012002200141106a360220200241206a200241306a10c30120012802202104200141286a2802002201200241306a105c02402001450d002004200141186c6a2101034020022004360220200241206a200241306a10c301200441106a200241306a10af012001200441186a2204470d000b0b200228023421042005ad4280808080800884200235023842208620022802302201ad84100202402004450d00200110230b20051023200241d0006a24000f0b41c00041011030000b130020004110360204200041b4b2c5003602000bcd0405057f017e017f027e037f230041e0006b22002400200041206a41186a22014200370300200041206a41106a22024200370300200041206a41086a2203420037030020004200370320200041d0006a41086a220441c6acc500ad4280808080f0008422051003220641086a29000037030020002006290000370350200610232003200429030037030020002000290350220737034020002007370320200441e8fbc500ad428080808080018422081003220641086a2900003703002000200629000037035020061023200220002903502207370300200041086a22092003290300370300200041106a220a2007370300200041186a220b200429030037030020002007370340200020002903203703000240024002404100200010a9032206200641ff01714104461b41ff0171417f6a220641024b0d0020060e03010001010b20014200370300200242003703002003420037030020004200370320200420051003220641086a29000037030020002006290000370350200610232003200429030037030020002000290350220737034020002007370320200420081003220641086a2900003703002000200629000037035020061023200041c0006a41086a2004290300220737030020002000290350220537034020022005370000200241086a200737000020092003290300370300200a2002290300370300200b200129030037030020002000290320370300410110212204450d01200441013a00002000ad42808080808004842004ad428080808010841002200410230b200041e0006a24000f0b410141011030000b3400200041c6acc50036020420004100360200200041146a411a360200200041106a41a8e5c500360200200041086a42073702000b6101017f02400240411010212202450d00200242003700082002420037000020024110412010252202450d0120024200370010200042a0808080800437020420002002360200200241186a42003700000f0b411041011030000b412041011030000b940603027f027e047f230041106b22032400200341003602082003420137030020022003105c024002400240024002402002450d002001200241d8006c6a21040340200141386a20031071200141086a2903002105200129030021060240024020032802042207200328020822026b4110490d00200328020021070c010b200241106a22082002490d06200741017422022008200220084b1b22024100480d060240024020070d002002102121070c010b200328020020072002102521070b2007450d032003200236020420032007360200200328020821020b200720026a22072005370008200720063700002003200241106a36020820012802202102200128022822072003105c02402007450d002002200741306c6a21090340200220031071200241286a2903002105200241206a29030021060240024020032802042208200328020822076b4110490d00200328020021080c010b200741106a220a2007490d0820084101742207200a2007200a4b1b22074100480d080240024020080d002007102121080c010b200328020020082007102521080b2008450d062003200736020420032008360200200328020821070b200820076a22082005370008200820063700002003200741106a3602082009200241306a2202470d000b0b200128022c2102200141346a28020022072003105c02402007450d00200741057421070340200220031071200241206a2102200741606a22070d000b0b200141186a2903002105200129031021060240024020032802042207200328020822026b4110490d00200328020021070c010b200241106a22082002490d06200741017422022008200220084b1b22024100480d060240024020070d002002102121070c010b200328020020072002102521070b2007450d052003200236020420032007360200200328020821020b200720026a22072005370008200720063700002003200241106a360208200141d8006a22012004470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b200241011030000b200741011030000b200241011030000b102a000b090020004100108c030b6b01027f230041106b22022400200241003602082002420137030002404104102122030d00410441011030000b2003410036000020024284808080c0003702042002200336020041002002105c200041086a200228020836020020002002290300370200200241106a24000b8c0201037f230041c0006b22022400200241186a4200370300200241106a22034200370300200241086a4200370300200241286a22044100360200200242003703002002420837032020024100360238200242013703302002200236023c2002413c6a200241306a10c3012002200336023c2002413c6a200241306a10c3012002280220210320042802002204200241306a105c02402004450d00200441306c21040340200341106a200241306a10712002200336023c200341306a21032002413c6a200241306a10c301200441506a22040d000b0b20002002290330370200200041086a200241306a41086a28020036020002402002280224450d00200228022010230b200241c0006a24000b890201047f230041106b220224002002410036020c024002400240024002400240410110212203450d000240200228020c2204413f4b0d00200320044102743a0000410121050c050b200441808001490d032004418080808004490d020c010b410141011030000b200341033a0000200228020c210441052105024020034101410510252203450d00200320043600010c030b410541011030000b41042105024020034101410410252203450d00200320044102744102723600000c020b410441011030000b4102210520034101410210252203450d01200320044102744101723b00000b200020053602082000200536020420002003360200200241106a24000f0b410241011030000b3001017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200241043600000b130020004102360204200041ac92c6003602000b3001017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200241063600000bbd0101057f2001280208210302402001410c6a280200220420024d0d0002400240200141186a2802002205450d00200141106a2802002101200541027421062003417f6a2103034002402004200128020022076b220520024b0d00200420024b0d030b200141046a21012003417f6a2103200521042006417c6a22060d000b0b200041023602080f0b2000200736020c2000410136020820002005ad4220862003ad843702000f0b2000410036020820002004ad4220862003ad843702000b931704027f037e057f047e230041e0026b22052400200541c8016a2001200210c6040240024020052802d0014102470d00410021020c010b20052802c80121062001280204220241086a2900002107200241106a290000210820022900002109200541c8016a41186a200241186a290000370300200541c8016a41106a2008370300200541c8016a41086a2007370300200520093703c801200520063602e801200541b0026a41086a220241c6acc500ad4280808080f000841003220a41086a2900003703002005200a2900003703b002200a1023200541f0016a41086a2002290300370300200520052903b0023703f001200241c6adc500ad42808080809001841003220a41086a2900003703002005200a2900003703b002200a102320054180026a41086a2002290300370300200520052903b00237038002024002400240024002400240024002400240024002400240410410212202450d00200542043702b402200520023602b002200541c8016a200541b0026a107120052802e801210b0240024020052802b402220a20052802b80222026b4104490d0020052802b002210a0c010b200241046a220c2002490d09200a4101742202200c2002200c4b1b22024100480d0902400240200a0d0020021021210a0c010b20052802b002200a20021025210a0b200a450d02200520023602b4022005200a3602b00220052802b80221020b2005200241046a3602b802200a20026a200b36000020052802b402210a200541b0026a41186a220b20053502b80242208620052802b002220dad841001220241186a290000370300200541b0026a41106a220c200241106a290000370300200541b0026a41086a220e200241086a290000370300200520022900003703b0022002102320054190026a41186a200b29030037030020054190026a41106a200c29030037030020054190026a41086a200e290300370300200520052903b002370390020240200a450d00200d10230b41c00010212202450d02200220052903f00137000020022005290380023700102002200529039002370020200241086a200541f0016a41086a290300370000200241186a20054180026a41086a220b290300370000200241286a20054190026a41086a290300370000200241306a20054190026a41106a290300370000200241386a20054190026a41186a290300370000200541c0003602d402200520023602d00220054180026a2002ad4280808080800884100410900102400240200528028002220a0d004200210f0c010b200528028402210c02400240200b280200220b4110490d00200b4170714110460d00200a41186a2900002108200a41086a2900002110200a2900102107200a29000021094201210f0c010b200541003602980220054201370390022005410c3602f4012005200541d0026a3602f001200520054190026a3602dc02200541c4026a4101360200200542013702b40220054198c2c3003602b0022005200541f0016a3602c002200541dc026a41b8a3c500200541b0026a102e1a2005350298024220862005350290028410080240200528029402450d0020052802900210230b4200210f0b200c450d00200a10230b2002102320084200200f42005222021b21082007420020021b21072009420020021b220f2003542010420020021b220920045420092004511b0d03200f20038520092004858450450d05200541b8016a20032004428094ebdc03420010e204200541a8016a20052903b8012209200541b8016a41086a290300220f4280ec94a37c427f10e10420054198016a2009200f20013502242210420010e10420054188016a4200200529039801220f201020052903a80120037c7e22092009428094ebdc038022094280ec94a37c7e7c4280cab5ee01562009a76aad7c220920077d2210201020095620054198016a41086a2903002009200f54ad7c220f20087d2009200754ad7d2209200f562009200f511b22021b220f4200200920021b428094ebdc03420010e204200541f8006a200529038801220920054188016a41086a29030022104280ec94a37c427f10e104200541e8006a200920104280cab5ee01420010e104200541e8006a41086a29030020052903682210200f20052903787c22094280cab5ee017e428094ebdc03824280cab5ee01562009420188a76aad7c2209201054ad7c210f410021020c040b410441011030000b200241011030000b41c00041011030000b200541c8006a20032004428094ebdc03420010e204200541d8006a20032004428094ebdc03420010e304200541386a2005290348200541c8006a41086a29030020013502242210420010e104200541286a420020052903382211201020052903587e22102010428094ebdc038022104280ec94a37c7e7c4280cab5ee01562010a76aad7c221020077d22122012201056200541386a41086a2903002010201154ad7c221120087d2010200754ad7d221020115620102011511b22021b22114200201020021b428094ebdc03420010e204200541186a20052903282210200541286a41086a29030022124280ec94a37c427f10e104200541086a201020124280cab5ee01420010e104200141206a28020022022003200f7d221020022903007c2212370300200241086a2202200420097d2003200f54ad7d20022903007c2012201054ad7c370300200541086a41086a2903002005290308220f201120052903187c22094280cab5ee017e428094ebdc03824280cab5ee01562009420188a76aad7c2209200f54ad7c210f410121020b024002402009200f84500d00200128021c22022002290300221020097c2211370300200241086a22022002290300200f7c2011201054ad7c3703002008200f7c200720097c2209200754ad7c2108200921070c010b2002450d010b200141013a0028200541b0026a41086a220241c6acc500ad4280808080f000841003220141086a290000370300200520012900003703b00220011023200541f0016a41086a2002290300370300200520052903b0023703f001200241c6adc500ad42808080809001841003220141086a290000370300200520012900003703b0022001102320054180026a41086a2002290300370300200520052903b00237038002410410212202450d01200542043702b402200520023602b002200541c8016a200541b0026a107120052802e801210a0240024020052802b402220120052802b80222026b4104490d0020052802b00221010c010b200241046a220b2002490d0420014101742202200b2002200b4b1b22024100480d040240024020010d002002102121010c010b20052802b00220012002102521010b2001450d03200520023602b402200520013602b00220052802b80221020b2005200241046a3602b802200120026a200a36000020052802b4022101200541b0026a41186a220a20053502b80242208620052802b002220ead841001220241186a290000370300200541b0026a41106a220b200241106a290000370300200541b0026a41086a220c200241086a290000370300200520022900003703b0022002102320054190026a41186a200a29030037030020054190026a41106a200b29030037030020054190026a41086a200c290300370300200520052903b0023703900202402001450d00200e10230b41c00010212202450d04200220052903f00137000020022005290380023700102002200529039002370020200241086a200541f0016a41086a290300370000200241186a20054180026a41086a290300370000200241286a20054190026a41086a290300370000200241306a20054190026a41106a290300370000200241386a20054190026a41186a290300370000411010212201450d05200120033700002001200437000820014110412010252201450d0620012007370010200141186a20083700002002ad42808080808008842001ad4280808080800484100220011023200210230b410121020c060b410441011030000b200241011030000b102a000b41c00041011030000b411041011030000b412041011030000b2000200636020420002002360200200541e0026a24000bc70302057f017e230041c0006b22022400200241206a41086a220341c6acc500ad4280808080f000841003220441086a2900003703002002200429000037032020041023200241086a2205200329030037030020022002290320370300200341acb2c500ad4280808080d000841003220441086a2900003703002002200429000037032020041023200241106a41086a2206200329030037030020022002290320370310200241206a200010ac010240024041c00010212204450d00200420022903003700002004200229031037001020042002290020370020200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241306a290000370000200441386a200241206a41186a29000037000002400240200141ff0171220341024d0d004101210342002107410121010c010b024002400240024020030e03000102000b410021010c020b410121010c010b410221010b200220013a0020410110212203450d02200320013a00004100210142808080801021070b2004ad428080808080088420072003ad841002024020010d00200310230b20041023200241c0006a24000f0b41c00041011030000b410141011030000bcc0201057f230041c0006b22022400200241206a41086a220341c6acc500ad4280808080f000841003220441086a2900003703002002200429000037032020041023200241086a2205200329030037030020022002290320370300200341f1acc500ad4280808080e000841003220441086a2900003703002002200429000037032020041023200241106a41086a2206200329030037030020022002290320370310200241206a200010ac01024041c000102122040d0041c00041011030000b200420022903003700002004200229031037001020042002290020370020200441086a2005290300370000200441186a2006290300370000200441286a2003290000370000200441306a200241306a290000370000200441386a200241206a41186a290000370000200241c000360224200220043602202001200241206a10f50120041023200241c0006a24000b130020004101360204200041b8a5c6003602000b1300200041023602042000418ca7c6003602000b3101017f02404104102122020d00410441011030000b20004284808080c00037020420002002360200200241e5003600000b3400200041d899c60036020420004100360200200041146a4101360200200041106a41e4a9c600360200200041086a42183702000b3400200041a79fc60036020420004100360200200041146a4103360200200041106a41fcacc600360200200041086a420c3702000b13002000410136020420004198b1c6003602000ba70201077f0240024002400240200041086a2802002201450d00410020014102746b2102417f210320002802002204210503402002450d01200341016a2103200241046a210220052802002106200541046a21052006450d000b4100200641004741016a41017122056b2003460d002001200520036a2207490d012001200641004741016a4101716b20036b220541ffffffff03712005470d0220054102742203417f4c0d020240024020030d00410421010c010b200310212201450d040b2001200420074102746a4104200641004741016a41017141027420026a6b10dc0421020240200041046a280200450d00200028020010230b20002002360200200041086a2005360200200041046a20053602000b0f0b20072001103e000b102f000b200341041030000bbf0403067f017e097f02400240024002400240200141086a2802002203200241086a2802002204200320044b1b220541016a22064101200641014b1b220741ffffffff03712007470d0020074102742206417f4c0d000240024020060d00410421080c010b200610272208450d020b024020050d00420021090c040b2004417f6a220a20044b210b2002280200210c2003417f6a220d20034b0d022001280200210e20082007417f6a22024102746a210f410021064200210903404100211002402003200d20066b22114d0d00410021102011200d4b0d00200e20114102746a28020021100b410021110240200b0d002004200a20066b22124d0d002012200a4b0d00200c20124102746a28020021110b200720024d0d05200f20092010ad7c2011ad7c22093e0200200f417c6a210f2002417f6a210220094220882109200641016a22062005490d000c040b0b102f000b200641041030000b20082007417f6a22024102746a21104100210f420021090340410021060240200b0d00410021062004200a200f6b22114d0d00410021062011200a4b0d00200c20114102746a28020021060b200720024d0d02201020092006ad7c22093e02002010417c6a21102002417f6a210220094220882109200f41016a220f2005490d000b0b024020072005417f736a220220074f0d00200020073602082000200736020420002008360200200820024102746a20093e02000240200141046a280200450d00200128020010230b0f0b41b8b3c60020022007102d000b41b8b3c60020022007102d000bbf04030d7f017e017f02400240200241086a2802002203200141086a28020022046a22054101200541014b1b220641ffffffff03712006470d0020064102742205417f4c0d0002400240024020050d00410421070c010b200510272207450d010b2004450d022001280200210802400240024020030d0020082004417f6a22054102746a210320072006417f6a22024102746a21090340200420054d0d0302402003280200450d00200620024d0d03200941003602000b2003417c6a21032009417c6a21092002417f6a21022005417f6a2205417f470d000c060b0b200641027420076a417c6a210a200341027420022802006a417c6a210b4100210c2006210d03402004200c417f736a220520044f0d020240200820054102746a220e280200220f450d0042002110417f2105200a2102200b2109024003402006200d20056a22114d0d0120022009350200200fad7e20107c20023502007c22103e0200201042208821100240200320056a0d002006200c20036a417f736a220220064f0d05200720024102746a20103e02000c030b2002417c6a21022009417c6a2109200e280200210f20032005417f6a22056a22112003490d000b41d4b2c60020112003102d000b41d4b2c60020112006102d000b200a417c6a210a200d417f6a210d200c41016a220c2004460d050c000b0b41b8b3c60020022006102d000b41d4b2c60020052004102d000b200541041030000b102f000b2000200636020820002006360204200020073602000240200141046a280200450d00200128020010230b0bb60302097f017e230041106b2201240002400240024002400240024002402000280200220228020041016a41004c0d002000280204220328020041016a41004c0d012000280208220441086a28020022054101200028020c22062802006b22076a220820054f0d02200720002802142802006b22052000280210220741086a28020022006a220920054f0d03024002402002290308220a42ffffffff0f560d0041002100200a200428020020084102746a3502007e2003290308422086200728020020094102746a35020084580d010b20022802000d052002410036020020022002290308427f7c370308200441086a2802002200200020062802006b22024d0d0620032802000d07200428020020024102746a350200210a200341003602002003200a20032903087c370308410121000b200141106a240020000f0b4187b5c6004118200141086a41a0b5c6001031000b4187b5c6004118200141086a41a0b5c6001031000b41d4b2c60020082005102d000b41d4b2c60020092000102d000b41b0b5c6004110200141086a41c0b5c6001031000b41d4b2c60020022000102d000b41b0b5c6004110200141086a41c0b5c6001031000b9e0301087f200028020822024102742103410021042000280200220521000240024003402003450d012004417f6a21042003417c6a210320002802002106200041046a21002006450d000b410121072004417f73200641004741016a4101716a21080c010b41002107410020046b21080b200128020822094102742103410021042001280200220121000240024003402003450d012004417f6a21042003417c6a210320002802002106200041046a21002006450d000b410021032004417f73200641004741016a4101716a21000c010b410020046b2100410121030b024020070d00410020034101736b0f0b4101210402400240024020030d0020022008490d0120092000490d02417f200220086b2203200920006b22064720032006491b22040d0020062003200320064b1b2107200120004102746a2103200520084102746a2100417f210103400240200141016a22012007490d0041000f0b2003280200210420002802002106200341046a2103200041046a2100417f200620044720062004491b2204450d000b0b20040f0b20082002103e000b20002009103e000b100020002802002000280204200110580b8906010d7f200128000c21022001280204210320012802002104024002400240024002400240024020012d000822054102470d00200320044f0d010c020b20054101710d010b41002106024002400240024002404100200320046b2201200120034b1b220741016a220120074f0d000240200420034b200520054102461b22014102460d002001410171450d004104210841002101410021060c080b2003417f732109200241086a210a41002107200321054104210841002106410021010340200920016a220b200a280200220c6a220d200b4f0d022004200549210b2002280200200d4102746a280200210d024020012006470d002006417f417f41002005200b6b220c20046b220e200e200c4b1b220c41016a220e200e200c491b4100200b1b220c41016a220e200e200c491b6a220c2006490d062006410174220e200c200e200c4b1b220c41ffffffff0371200c470d06200c410274220e4100480d060240024020060d00200e102121080c010b20082006410274200e102521080b2008450d04200c21060b200820076a200d360200200741046a21072005417f6a2105200141016a2101200b0d000c080b0b024020010d00410421080c060b200141ffffffff03712001470d03200141027422064100480d03200610212208450d02200121060c050b41d4b2c600200120036b200c6a417f6a200c102d000b200e41041030000b200641041030000b102a000b41042108410021060b410021012003200449200520054102461b4101710d0002400240200320044d0d002003417f732101200241086a210d200821052003210703402001200d280200220c6a220b20014f0d0420052002280200200b4102746a280200360200200141016a2101200541046a210520042007417f6a2207490d000b200320046b41016a21010c010b20032004470d0141012101200821050b200241086a28020022072004417f736a220420074f0d022005200228020020044102746a2802003602000b2000200136020820002006360204200020083602000f0b41d4b2c600200b200c102d000b41d4b2c60020042007102d000b7701027f230041106b2203240002404110102122040d00411041041030000b200420013e020c200420014220883e0208200420023e0204200420024220883e020020034284808080c00037020420032004360200200310d004200041086a200328020836020020002003290300370200200341106a24000bac0301047f230041c0006b2202240020002802002100410121030240200128021841c1acc000410c2001411c6a28020028020c1100000d0002400240200028020822030d0020002802002203200028020428020c11040042e4aec285979ba58811520d012002200336020c2002411336021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241d0acc0003602282002200241106a36023820042005200241286a102e0d020c010b2002200336020c2002410836021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241d0acc0003602282002200241106a36023820042005200241286a102e0d010b200241106a41146a4101360200200241106a410c6a4101360200200241043602142002200041186a3602202002200041146a36021820022000410c6a36021020012802182100200128021c2101200241286a41146a41033602002002420337022c200241e0acc0003602282002200241106a36023820002001200241286a102e21030b200241c0006a240020030b21002000417f6a41ff01712002ad4220862001ad842004ad4220862003ad8410000b1c00200128021841d9bec600410f2001411c6a28020028020c1100000b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f0240024020012000490d002002450d01200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000c020b0b2002450d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200141016a2101200041016a21002002417f6a2202450d020c000b0b200420056b21030b20030b5701017e02400240200341c000710d002003450d012001410020036b413f71ad8820022003413f71ad220486842102200120048621010c010b20012003413f71ad862102420021010b20002001370300200020023703080b5701017e02400240200341c000710d002003450d0120012003413f71ad2204882002410020036b413f71ad86842101200220048821020c010b20022003413f71ad882101420021020b20002001370300200020023703080b7501027e200020034220882205200142208822067e200320027e7c200420017e7c200342ffffffff0f832203200142ffffffff0f8322017e2204422088200320067e7c22034220887c200342ffffffff0f83200520017e7c22034220887c37030820002003422086200442ffffffff0f83843703000b3e01017f230041106b2205240020052001200220032004410010e404200529030021012000200541086a29030037030820002001370300200541106a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a10e404200529031021012000200529031837030820002001370300200541206a24000be20502037f067e230041306b2206240002400240024002400240024002400240024002402002500d002003500d012004500d02200479a7200279a76b2207413f4b0d0341ff0020076b2108200741016a21070c080b02402004500d0020050d040c060b024002402005450d0020034200510d0620054200370308200520012003823703000c010b20034200510d050b200120038021010c060b2004500d030240024002402001500d0020047b4201510d01200479a7200279a76b2207413e4b0d0241ff0020076b2108200741016a21070c090b02402005450d0020054200370300200520022004823703080b200220048021010c070b02402005450d002005200137030020052004427f7c2002833703080b200220047a423f838821010c060b2005450d040c020b024020037b4201510d0041bf7f200379a7200279a76b22076b2108200741c1006a21070c060b02402005450d002005420037030820052003427f7c2001833703000b20034201510d06200641206a2001200220037aa710e004200641286a2903002102200629032021010c060b2005450d020b2005200137030020052002370308420021010c020b00000b420021010b420021020c010b200620012002200841ff007110df04200641106a20012002200741ff007110e004200641086a2903002102200641106a41086a2903002109200629030021012006290310210a0240024020070d004200210b4200210c0c010b4200210c4200210d03402009420186200a423f8884220b200b427f8520047c200a4201862002423f8884220a427f85220b20037c200b54ad7c423f87220b2004837d200a200b200383220e54ad7d2109200a200e7d210a420020024201862001423f8884842102200d2001420186842101200b420183220b210d2007417f6a22070d000b0b02402005450d002005200a370300200520093703080b200c20024201862001423f8884842102200b20014201868421010b2000200137030020002002370308200641306a24000b0b93bf060300418080c0000be8be061800100011000000290010001700000009030000050000006361706163697479206f766572666c6f777372632f6c6962616c6c6f632f7261775f7665632e7273b00010004600000063010000130000001400000004000000040000001500000016000000170000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f720018000000000000000100000019000000000000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f666d742f6d6f642e72730000180110002000000038011000120000001800000000000000010000001a000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e646578206973203030303130323033303430353036303730383039313031313132313331343135313631373138313932303231323232333234323532363237323832393330333133323333333433353336333733383339343034313432343334343435343634373438343935303531353235333534353535363537353835393630363136323633363436353636363736383639373037313732373337343735373637373738373938303831383238333834383538363837383838393930393139323933393439353936393739383939000034021000060000003a02100022000000cc9b110018000000180a000005000000696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e677468207c02100016000000920210000d000000cc9b1100180000001e0a000005000000736c69636520696e64657820737461727473206174202062757420656e6473206174206030785b2e2e2e5d00660310000b00000012161000160000009f0210000100000050031000160000000308000009000000f01510000e000000fe1510000400000002161000100000009f0210000100000050031000160000000708000005000000b01510002b000000db151000150000007a01000015000000660310000b000000710310002600000097031000080000009f031000060000009f02100001000000500310001600000014080000050000007372632f6c6962636f72652f7374722f6d6f642e72736279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f662060000000e603100002000000d0031000160000006004000011000000d00310001600000054040000280000007372632f6c6962636f72652f666d742f6d6f642e72732e2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000f8030000000000000000000000000000000000000000000000000000000000000000feffffffffbfb6000000000000000000ff070000000000f8ffff0000010000000000000000000000c09f9f3d0000000002000000ffffff0700000000000000000000c0ff01000000000000f80f20900f10004a000000e011100000020000e01310003a00000000010203040506070809080a0b0c0d0e0f10111213140215161718191a1b1c1d1e1f2002020202020202020202210202020202020202020202020202222324252602270228020202292a2b022c2d2e2f300202310202023202020202020202023302023402020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023502360237020202020202020238023902020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023a3b3c020202023d02023e3f4041424344454602020247020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202024802020202020202020202024902020202023b020001020202020302020202040205060202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020207020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200010305050606030706080809110a1c0b190c140d120e0d0f0410031212130916011705180219031a071c021d011f1620032b042c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f0040d1145496465808184b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f747596972f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab351e1580e003190801042f043404070301070607110a500f1207550802041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a061f414c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b030740c80d61a0c0580ff0580b605240c9bc60ad23010848d033709815c1480b80880c73035040a06380846080c06740b1e035a0459098083181c0a16094808808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b02100111041205131114021502170219041c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f906fa020c273b3e4e4f8f9e9e9f060709363d3e56f3d0d104141836375657bd35cecfe01287898e9e040d0e11122931343a4546494a4e4f64655a5cb6b71b1ca8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d00c72a3a4cbcc6e6f5e227b0503042d036504012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a81261f808128082a808617094e041e0f430e19070a0647092709750b3f412a063b050a0651060105100305808b602048080a80a65e22450b0a060d1339070a362c041080c03c64530c0180a0451b4808531d398107460a1d03474937030e080a0639070a81361980c7320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140041c97f80882f3a50d811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a0d035d033d391d0d2c040907020e06809a83d60a0d030b05740c59070c140c0438080a0628081e527703310380a60c14040305030d06856a000000700f1000200000002700000019000000700f1000200000002800000020000000700f1000200000002a00000019000000700f1000200000002b00000018000000700f1000200000002c0000002000000000000000000000007372632f6c6962636f72652f756e69636f64652f626f6f6c5f747269652e72730000c0fbef3e00000000000e0000000000000000000000000000f8fffbffffff0700000000000014fe21fe000c00000002000000000000501e2080000c00004006000000000000108639020000002300be2100000c0000fc02000000000000d01e20c0000c0000000400000000000040012080000000000011000000000000c0c13d60000c0000000200000000000090443060000c00000003000000000000581e2080000c00000000845c8000000000000000000000f207807f000000000000000000000000f21f003f000000000000000000030000a002000000000000fe7fdfe0fffeffffff1f40000000000000000000000000e0fd66000000c301001e006420002000000000000000e00000000000001c0000001c0000000c0000000c00000000000000b03f40fe0f200000000000380000000000006000000000020000000000008701040e00008009000000000000407fe51ff89f000000000000ff7f0f0000000000f0170400000000f80f00030000003c3b00000000000040a303000000000000f0cf000000f7fffd211003fffffffffffffffb00100000000000000000ffffffff01000000000000800300000000000000008000000000ffffffff0000000000fc00000000000600000000000000000080f73f000000c0000000000000000000000300440800006000000030000000ffff038000000000c03f000080ff030000000000070000000000c833000000002000000000000000007e660008100000000000100000000000009dc1020000000030400000000000202100000000004000000000ffff0000ffff00000000000000000001000000020003000000000000000000000000000000000000000000000000000004000005000000000000000006000000000000000007000008090a000b0c0d0e0f000010111200001314151600001718191a1b001c0000001d0000000000001e1f202100000000002200230024252600000000270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002829000000000000000000000000000000002a2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000002d2e00002f0000000000000000000000000000000000000000000000000000000000003031320000000000000000000000000000000000000000003300000029000000000000340000000000000000000000000000000000000000000000350036000000000000000000000000000000000000000000000000000037380000383838390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000001000000000000000000c0076ef0000000000087000000006000000000000000f0000000c0ff01000000000002000000000000ff7f0000000000008003000000000078060700000080ef1f000000000000000800030000000000c07f001e000000000000000000000080d34000000080f8070000030000000000005801008000c01f1f0000000000000000ff5c00004000000000000000000000f9a50d000000000000000000000000803cb00100003000000000000000000000f8a70100000000000000000000000028bf00000000e0bc0f0000000000000080ff060000f00c01000000fe0700000000f87980007e0e0000000000fc7f03000000000000000000007fbf0000fcfffffc6d000000000000007eb4bf000000000000000000a3000000000000000000000018000000000000001f000000000000007f0000800000000000000080070000000000000000600000000000000000a0c307f8e70f0000003c00001c00000000000000ffffffffffff7ff8ffffffffff1f2000100000f8feff00007ffffff9db0700000000000000f0000000007f0000000000f00700000000000000000000ffffffffffffffffffffffffffffffffffff000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75657372632f6c6962636f72652f6f7074696f6e2e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f662060426f72726f774572726f72426f72726f774d75744572726f7270616e69636b65642061742000000079161000010000007a16100003000000449c110000000000781610000100000078161000010000003a27272c20000000db15100015000000a204000005000000a0161000150000008d040000050000007372632f6c6962636f72652f726573756c742e72735b5d0a1b0000000c000000040000001c0000001d0000001e0000002c0a2c201400000004000000040000001f000000200000002100000020202020180000000000000001000000220000002300000024000000140000000400000004000000250000002600000027000000000000007817100010000000000000008817100001000000000000000000000090171000010000000000000000000000981710000f00000000000000a8171000020000000000000000000000b8171000010000000000000045787472696e73696353756363657373d51710000c000000e11710002500000045787472696e7369634661696c656400389d11000d000000d51710000c000000c01710001500000020416e2065787472696e736963206661696c65642e4469737061746368496e666f20416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e52657175697265526f6f744f726967696e526571756972655369676e65644f726967696e526571756972654e6f4f726967696e00000000000000171810001300000000000000449c1100000000000000000000000000061810001100000000000000449c11000000000000000000000000002a1810000f00000000000000449c110000000000000000001800000000000000010000002800000029000000240000001800000000000000010000002800000029000000240000000000000001000000020000000400000008000000100000002000000000000000601910000e000000000000007019100001000000000000000000000078191000010000000000000000000000801910000600000000000000449c110000000000000000000000000088191000010000000000000000000000901910000700000000000000449c11000000000000000000000000009819100001000000000000004e6577417574686f7269746965730000907710000d000000ef191000240000005061757365640000c819100027000000526573756d656400a0191000280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e4f6666636861696e206572726f723a206665746368696e67206e6574776f726b207374617465206661696c6564214f6666636861696e206572726f723a207369676e696e67206661696c6564214f6666636861696e206572726f723a206465636f64696e6720576f726b6572537461747573206661696c6564214f6666636861696e206572726f723a207375626d697474696e67207472616e73616374696f6e206661696c6564210000000000e81a10000700000000000000f01a1000020000000000000000000000001b100002000000000000004f6666656e63650036b61000040000003ab610000e000000101b100055000000651b10004e00000020546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e6420286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e0000000000e01b10000a00000000000000b8571100010000000000000000000000ec1b100002000000000000004e657753657373696f6e0000fc1b100055000000511c100022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e53746f72656452616e67650000901c100048000000a20a00000e0000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f6d6f642e727374696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672e4572726f727372632f6c6962616c6c6f632f7665632e7273000000641d10001c000000361d100013000000c904000009000000617373657274696f6e206661696c65643a20656e64203c3d206c656e981d10001e000000361d100013000000b603000009000000617373657274696f6e206661696c65643a20696e646578203c3d206c656e0000d01d10001d000000361d100013000000de03000009000000617373657274696f6e206661696c65643a20696e646578203c206c656e000000001e1000430000000a0b0000300000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962616c6c6f632f7665632e727300001e100043000000160b00002c0000003a65787472696e7369635f696e6465784163636f756e744e6f6e6365426c6f636b486173684e756d626572506172656e744861736845787472696e73696373526f6f744469676573740000001400000004000000040000002a000000180000000000000001000000190000004576656e74734576656e74546f7069637300000000000000082010000a00000000000000449c1100000000000000000000000000142010000100000000000000000000001c2010000600000000000000242010000100000000000000000000003c201000010000000000000000000000442010000e00000000000000542010000100000000000000000000006c2010000100000000000000000000007420100008000000000000007c201000010000000000000000000000942010000100000000000000000000009c2010000b00000000000000a8201000010000000000000000000000c0201000010000000000000000000000c82010000c00000000000000d4201000010000000000000000000000ec201000010000000000000000000000f42010000b000000000000000021100001000000000000000000000018211000010000000000000066696c6c5f626c6f636b0000362210004800000072656d61726b0000000000002f2210000700000000000000dc43110007000000142210001b0000007365745f686561705f70616765730000000000000f2210000500000000000000eee7100003000000d02110003f0000007365745f636f646500000000986511000300000000000000dc43110007000000be211000120000007365745f73746f726167650000000000ac2110000500000000000000b12110000d000000912110001b0000006b696c6c5f73746f7261676500000000ff981000040000000000000089211000080000006b2110001e0000006b696c6c5f7072656669780000000000652110000600000000000000e8731000030000002021100045000000204b696c6c20616c6c2073746f72616765206974656d7320776974682061206b657920746861742073746172747320776974682074686520676976656e207072656669782e707265666978204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e5665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e6974656d735665633c4b657956616c75653e2053657420746865206e657720636f64652e2053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e7061676573204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b20412062696720646973706174636820746861742077696c6c20646973616c6c6f7720616e79206f74686572207472616e73616374696f6e20746f20626520696e636c756465642e000000000000641e10000c0000000101000000000000676411000c00000000000000f82610000800000000000000000000000000000000000000449c11003828100000000000000000000027100001000000000000000100000000000000082710000e0000000000000000000000a67b11000300000000000000000000000000000000000000000000000000000000000000449c1100542710000000000000000000182710000100000000000000000000000000000020271000130000000000000000000000332710000600000000000000000000000000000000000000000000000000000000000000449c11005427100000000000000000003c2710000100000000000000000000000000000044271000100000000000000000000000a67b11000300000000000000000000000000000000000000000000000000000000000000449c11005427100000000000000000006427100001000000000000000000000000000000701e1000090000000101000000000000069411000e000000000000000c0311000700000000000000000000000000000000000000449c1100ac27100000000000000000006c27100001000000000000000100000000000000742710000d0000000101000000000000a67b11000300000000000000dc4311000700000000000000000000000000000000000000449c11008427100000000000000000009427100001000000000000000100000000000000791e1000060000000000000000000000069411000e00000000000000000000000000000000000000000000000000000000000000449c11003828100000000000000000009c271000010000000000000001000000000000007f1e10000a00000000000000000000000c0311000700000000000000000000000000000000000000000000000000000000000000449c1100ac2710000000000000000000a427100001000000000000000100000000000000891e10000e00000000000000000000000c0311000700000000000000000000000000000000000000000000000000000000000000449c1100ac2710000000000000000000bc27100001000000000000000100000000000000971e1000060000000000000000000000c42710000b00000000000000000000000000000000000000000000000000000000000000449c1100d02710000000000000000000e027100001000000000000000100000000000000c01e1000060000000000000000000000e82710002300000000000000000000000000000000000000000000000000000000000000449c11000c28100000000000000000001c28100001000000000000000100000000000000242810000a00000000000000000000002e2810000a00000000000000000000000000000000000000000000000000000000000000449c11003828100000000000000000004828100001000000000000000100000000000000c61e10000b00000002010100000000001f18110002000000000000000c0311000700000000000000502810002100000000000000449c1100742810000000000000000000842810000d0000000000000001000000543a3a496e646578002e10001f00000045787472696e736963436f756e740000d22d10002e000000416c6c45787472696e736963735765696768745765696768740000008d2d100045000000416c6c45787472696e736963734c656e1800000000000000010000002b0000003d2d100050000000172d10002600000045787472696e736963446174610000001800000000000000010000002c000000c82c10004f000000862c1000420000006a2c10001c0000001800000000000000010000002d000000252c1000450000004469676573744f663c543e001800000000000000010000002e000000e92b10003c0000005665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e001800000000000000010000002f000000c12b1000280000004576656e74436f756e744576656e74496e64657818000000000000000100000030000000932b10002e0000005665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e0000001800000000000000010000002e000000ec281000490000003529100025000000449c1100000000005a2910004b000000a52910002a000000449c110000000000cf29100054000000232a100051000000742a100039000000449c110000000000ad2a100053000000002b100053000000532b100040000000204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20546865206669727374206b657920736572766573206e6f20707572706f73652e2054686973206669656c64206973206465636c6172656420617320646f75626c655f6d6170206a75737420666f7220636f6e76656e69656e6365206f66207573696e67206072656d6f76655f707265666978602e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2045787472696e7369637320726f6f74206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2077656967687420666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e2045787472696e73696373206e6f6e636520666f72206163636f756e74732e4e6f646520697320636f6e6669677572656420746f20757365207468652073616d6520686173683b2071656400642e100023000000449c110000000000872e10001e0000004552524f523a20436f727275707465642073746174653a206c696e6b6564206d6170203a206e6578742076616c756520646f65736e277420657869737420617420000000642e100023000000449c110000000000c02e1000220000003a2070726576696f75732076616c756520646f65736e2774206578697374206174200000642e100023000000449c110000000000fc2e10001e0000003a20686561642076616c756520646f65736e27742065786973742061742000003b2f10005a000000e6000000010000003a6865617070616765733a636f64652f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f73797374656d2f7372632f6c69622e7273476f7373697041744b657973000000000000002830100011000000000000003c301000010000000000000000000000443010000100000000000000000000004c3010000700000000000000449c1100000000000000000000000000543010000100000000000000000000005c3010000b00000000000000683010000100000000000000000000007030100001000000000000004865617274626561745265636569766564000000413110000b0000001131100030000000416c6c476f6f6400dc30100035000000536f6d654f66666c696e6500c430100018000000783010004c0000002041742074686520656e64206f66207468652073657373696f6e2c206174206c65617374206f6e63652076616c696461746f722077617320666f756e6420746f206265206f66666c696e652e5665633c4964656e74696669636174696f6e5475706c653e2041742074686520656e64206f66207468652073657373696f6e2c206e6f206f6666656e63652077617320636f6d6d69747465642e2041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f72697479496460417574686f7269747949647061726974792f696d2d6f6e6c696e652d776f726b65722d737461747573000040321000480000009c0a00000a00000001321000080000000932100020000000696d6f6e6c696e6570616c6c65745f696d5f6f6e6c696e652f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f696d2d6f6e6c696e652f7372632f6c69622e72735b696e6465783a205d205265706f7274696e6720696d2d6f6e6c696e6520617420626c6f636b3a20417574686f726564426c6f636b730000000000000000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000b43210000900000000000000c0321000020000000000000000000000449c1100000000000000000068656172746265617400000000000000b43210000900000000000000f03210001900000000000000093310000a00000000000000133310002f0000004865617274626561743c543a3a426c6f636b4e756d6265723e5f7369676e61747572653c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e6174757265000000000000952f1000080000000000000000000000069411000e00000000000000000000000000000000000000000000000000000000000000449c1100143510000000000000000000a4341000010000000000000001000000000000009d2f1000040000000000000000000000ac3410001300000000000000000000000000000000000000000000000000000000000000449c1100c03410000000000000000000d034100001000000000000000100000000000000d8341000120000000201010000000000295811000c00000000000000ea3410000900000000000000dc4311000700000000000000449c1100f434100000000000000000000435100002000000000000000000000000000000293210000e0000000201010000000000295811000c00000000000000449c10000e00000000000000a67b11000300000000000000449c1100143510000000000000000000243510000200000000000000010000003b361000280000005665633c543a3a417574686f7269747949643e001800000000000000010000002e000000073610003400000052656365697665644865617274626561747341757468496e646578001800000000000000010000002b000000ab35100039000000e435100023000000180000000000000001000000300000003435100045000000793510003200000020466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f662060543a3a56616c696461746f7249646020746f20746865206e756d626572206f6620626c6f636b7320617574686f7265642062792074686520676976656e20617574686f726974792e20466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206041757468496e6465786020746f20606f6666636861696e3a3a4f70617175654e6574776f726b5374617465602e205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e2054686520626c6f636b206e756d626572207768656e2077652073686f756c6420676f737369702e004032100048000000a20a00000e0000004475706c696361746564206865617274626561742e4e6f6e206578697374656e74207075626c6963206b65792e486561644f6644656c65676174696f6e7344656c65676174696f6e73566f74654f660000000000d4f610000800000000000000a8381000020000000000000000000000449c1100000000000000000000000000b83810000600000000000000c0381000030000000000000000000000449c1100000000000000000000000000d83810000e00000000000000449c1100000000000000000000000000449c1100000000000000000000000000e63810000700000000000000f0381000020000000000000000000000449c110000000000000000000000000000391000060000000000000008391000010000000000000000000000449c110000000000000000000000000010391000090000000000000008391000010000000000000000000000449c110000000000000000000000000019391000090000000000000008391000010000000000000000000000449c110000000000000000000000000078f71000080000000000000024391000020000000000000000000000449c110000000000000000000000000034391000090000000000000040391000020000000000000000000000449c1100000000000000000000000000503910000b00000000000000242c1100010000000000000000000000449c11000000000000000000000000005b391000060000000000000064391000030000000000000000000000449c11000000000000000000983910000900000087581100070000005461626c6564000098391000090000008758110007000000a13910000e00000045787465726e616c5461626c6564537461727465640000007c3910000f0000008b3910000d00000050617373656400007c3910000f0000004e6f7450617373656443616e63656c6c656400007c3910000f000000e89711000400000044656c6567617465640000007e581100090000007e58110009000000556e64656c6567617465645665746f65640000007e58110009000000b897110004000000acfe10000b0000005265666572656e64756d496e646578566f74655468726573686f6c6450726f70496e6465785665633c4163636f756e7449643e446973706174636851756575655265666572656e64756d496e666f4f66566f74657273466f725075626c696350726f7073603a100048000000a20a00000e0000004465706f7369744f664e6f207075626c69632070726f706f73616c732077616974696e6743616e6e6f7420696e6a6563742061207265666572656e64756d207468617420656e6473206561726c696572207468616e2070726563656564696e67207265666572656e64756d00000000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f6d6f642e72734e65787445787465726e616c4e6f2065787465726e616c2070726f706f73616c2077616974696e6700000000c80111000700000000000000bc3d1000020000000000000000000000ec3d10000600000000000000000000001c3e10000600000000000000243e10000100000000000000000000003c3e10000600000000000000000000002002110004000000000000006c3e10000200000000000000000000009c3e1000070000000000000000000000d43e10000a000000000000006c3e1000020000000000000000000000e03e1000070000000000000000000000183f10001000000000000000283f1000010000000000000000000000403f1000020000000000000000000000503f10001000000000000000c0701000010000000000000000000000603f1000020000000000000000000000703f10001900000000000000c07010000100000000000000000000008c3f1000050000000000000000000000b43f10001800000000000000c0701000010000000000000000000000cc3f1000050000000000000000000000f43f10000a000000000000000040100003000000000000000000000048401000090000000000000000000000904010000d00000000000000a0401000010000000000000000000000b8401000010000000000000000000000c04010001100000000000000d4401000010000000000000000000000ec401000010000000000000000000000f44010000d00000000000000044110000300000000000000000000004c4110000100000000000000000000005441100009000000000000006041100001000000000000000000000078411000050000000000000000000000a04110000c00000000000000449c1100000000000000000000000000ac411000050000000000000000000000d44110000c0000000000000060411000010000000000000000000000e04110000500000000000000000000000842100008000000000000001042100002000000000000000000000040421000050000000000000000000000684210000a00000000000000449c110000000000000000000000000074421000050000000000000000000000040311000800000000000000d272100010000000000000004d6f11000500000000000000526f1100150000006249100028000000449c1100000000007e6311000b0000008d701100080000009c491000200000009e6311000c0000007365636f6e640000000000000403110008000000000000008a491000120000006249100028000000449c1100000000007e6311000b0000008d70110008000000336f1100100000009e6311000c00000000000000ab43100009000000000000007e43100018000000000000002002110004000000000000005e49100004000000e24810004d0000002f4910002f000000449c1100000000007e6311000b0000008d70110008000000c34810001f0000009e6311000c00000070726f78795f766f746500003148100054000000854810003e000000449c1100000000007e6311000b0000008d70110008000000c34810001f0000009e6311000c000000656d657267656e63795f63616e63656c00000000ab43100009000000000000007c3910000f000000dd47100054000000d14710000c00000065787465726e616c5f70726f706f7365854710004c000000d14710000c00000065787465726e616c5f70726f706f73655f6d616a6f7269747900000017471000560000006d47100018000000449c1100000000009d46100053000000f04610002700000065787465726e616c5f70726f706f73655f64656661756c742a461000520000007c46100021000000449c1100000000009d46100053000000f046100027000000666173745f747261636b000000000000e34310000d000000000000000c0311000700000000000000184610000d00000000000000069411000e00000000000000254610000500000000000000069411000e000000f04310005400000044441000590000009d4410003b000000449c110000000000d84410003e00000016451000580000006e451000260000009445100055000000e94510002f0000007665746f5f65787465726e616c00000000000000e34310000d000000000000000c03110007000000b44310002f00000063616e63656c5f7265666572656e64756d00000000000000ab43100009000000000000007e43100018000000964310001500000063616e63656c5f717565756564000000000000007143100004000000000000007493110017000000000000007543100005000000000000009b6511000c000000000000007a43100004000000000000007e4310001800000049431000280000007365745f70726f787900000000000000444310000500000000000000676411000c0000001e43100026000000449c1100000000007e6311000b000000e9981000160000009e6311000c00000072657369676e5f70726f7879f842100026000000449c1100000000007e6311000b000000abd71000100000009e6311000c00000072656d6f76655f70726f7879d242100026000000449c1100000000007e6311000b000000abd71000100000009e6311000c00000064656c656761746500000000bc4210000200000000000000676411000c00000000000000be4210000a00000000000000c84210000a000000ad4210000f000000449c1100000000007e6311000b000000e9981000160000009e6311000c000000756e64656c656761746500009c42100011000000449c1100000000007e6311000b0000008d701100080000009e6311000c00000020556e64656c656761746520766f74652e2044656c656761746520766f74652e746f636f6e76696374696f6e436f6e76696374696f6e20436c656172207468652070726f78792e2043616c6c6564206279207468652073746173682e20436c656172207468652070726f78792e2043616c6c6564206279207468652070726f78792e205370656369667920612070726f78792e2043616c6c6564206279207468652073746173682e70726f78792043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e7768656e776869636877686174436f6d706163743c5265666572656e64756d496e6465783e2052656d6f76652061207265666572656e64756d2e7265665f696e646578205665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e70726f706f73616c5f68617368205363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c656420696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e6520627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e202d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e20496e6372656173656420746f20202060456d657267656e6379566f74696e67506572696f646020696620746f6f206c6f772e202d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265202020656e61637465642e205468697320646f65736e277420686176652061206d696e696d756d20616d6f756e742e766f74696e675f706572696f6464656c6179205363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061207072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e205363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e205363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e205363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d6520566f746520696e2061207265666572656e64756d206f6e20626568616c66206f6620612073746173682e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b20206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d204f6e65204442206368616e67652c206f6e6520444220656e7472792e20566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e566f74652050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e436f6d706163743c50726f70496e6465783e202d2054776f204442206368616e6765732c206f6e6520444220656e7472792e00000000e44e10000f0000000000000000000000983910000900000000000000000000000000000000000000000000000000000000000000449c1100904f10000000000000000000f44e100001000000000000000100000000000000d53910000b0000000000000000000000fc4e10002b00000000000000000000000000000000000000000000000000000000000000449c1100245010000000000000000000284f100001000000000000000100000000000000f0391000090000000101000000000000983910000900000000000000304f10002100000000000000000000000000000000000000449c1100544f10000000000000000000644f1000010000000000000000000000000000006c4f10000f00000000000000000000007c3910000f00000000000000000000000000000000000000000000000000000000000000449c1100904f100000000000000000007c4f100001000000000000000100000000000000844f10000900000000000000000000007c3910000f00000000000000000000000000000000000000000000000000000000000000449c1100904f10000000000000000000a04f100001000000000000000100000000000000bc3910001000000001010000000000007c3910000f00000000000000a84f10002d00000000000000000000000000000000000000449c1100945010000000000000000000d84f100001000000000000000000000000000000af3910000d0000000101000000000000069411000e00000000000000e04f10002b00000000000000000000000000000000000000449c11000c50100000000000000000001c50100001000000000000000100000000000000cc3910000900000001010000000000007c3910000f00000000000000b06411001100000000000000000000000000000000000000449c11002450100000000000000000003450100001000000000000000100000000000000bd3610000600000001010000000000003c5010001f000000000000005e4910000400000000000000000000000000000000000000449c11005c50100000000000000000006c501000040000000000000001000000000000008c501000050000000101000000000000676411000c00000000000000676411000c00000000000000000000000000000000000000449c1100945010000000000000000000a450100002000000000000000000000000000000b23610000b0000000101010000000000676411000c00000000000000b45010001a00000000000000000000000000000000000000449c1100d05010000000000000000000e050100001000000000000000100000000000000e8501000150000000000000000000000e89711000400000000000000000000000000000000000000000000000000000000000000449c1100b851100000000000000000000051100002000000000000000100000000000000a83a10000c0000000000000000000000105110001c00000000000000000000000000000000000000000000000000000000000000449c11002c51100000000000000000003c511000040000000000000000000000000000005c5110000900000001010000000000000c0311000700000000000000655110002300000000000000000000000000000000000000449c11008851100000000000000000009851100002000000000000000000000000000000a85110000d00000001010000000000000c0311000700000000000000e89711000400000000000000000000000000000000000000449c1100b85110000000000000000000c85110000100000000000000010000005075626c696350726f70436f756e7400385710003d0000005665633c2850726f70496e6465782c20543a3a50726f706f73616c2c20543a3a4163636f756e744964293e0018571000200000002842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e2900000018000000000000000100000031000000f7561000210000005265666572656e64756d436f756e7400ab5610004c0000004e65787454616c6c79000000180000000000000001000000300000007956100032000000285265666572656e64756d496e666f3c543a3a426c6f636b4e756d6265722c20543a3a50726f706f73616c3e290000004c5610002d0000005665633c4f7074696f6e3c28543a3a50726f706f73616c2c205265666572656e64756d496e646578293e3e001800000000000000010000002e0000001c561000300000001800000000000000010000002e000000f355100029000000285265666572656e64756d496e6465782c20543a3a4163636f756e74496429001800000000000000010000002b000000b4541000580000000c551000530000005f55100057000000b65510003d00000050726f78790000001800000000000000010000002b000000465410004c000000925410002200000028543a3a4163636f756e7449642c20436f6e76696374696f6e29000018000000000000000100000032000000f6531000500000004c6173745461626c656457617345787465726e616c0000009653100056000000ec5310000a00000028543a3a50726f706f73616c2c20566f74655468726573686f6c642918000000000000000100000033000000a852100056000000fe5210005500000053531000290000007c5310001a000000426c61636b6c69737428543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e29180000000000000001000000310000001a521000540000006e5210003a00000043616e63656c6c6174696f6e730000001800000000000000010000002b000000d05110004a000000205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e2041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d6265722028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e20546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e20546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743a202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f72202d20605075626c696350726f70736020697320656d7074792e205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c69632070726f706f73616c2e2047657420746865206163636f756e742028616e64206c6f636b20706572696f64732920746f20776869636820616e6f74686572206163636f756e742069732064656c65676174696e6720766f74652e2057686f2069732061626c6520746f20766f746520666f722077686f6d2e2056616c7565206973207468652066756e642d686f6c64696e67206163636f756e742c206b65792069732074686520766f74652d7472616e73616374696f6e2d73656e64696e67206163636f756e742e204765742074686520766f746520696e206120676976656e207265666572656e64756d206f66206120706172746963756c617220766f7465722e2054686520726573756c74206973206d65616e696e6766756c206f6e6c792069662060766f746572735f666f726020696e636c756465732074686520766f746572207768656e2063616c6c6564207769746820746865207265666572656e64756d2028796f75276c6c20676574207468652064656661756c742060566f7465602076616c7565206f7468657277697365292e20496620796f7520646f6e27742077616e7420746f20636865636b2060766f746572735f666f72602c207468656e20796f752063616e20616c736f20636865636b20666f722073696d706c65206578697374656e636520776974682060566f74654f663a3a657869737473602066697273742e204765742074686520766f7465727320666f72207468652063757272656e742070726f706f73616c2e205175657565206f66207375636365737366756c207265666572656e646120746f20626520646973706174636865642e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e20546865206e657874207265666572656e64756d20696e64657820746861742073686f756c642062652074616c6c6965642e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e00000000000000c85810000f00000000000000069411000e00000000000000449c1100d85810000000000000000000e8581000050000000000000000000000105910000c00000000000000069411000e00000000000000449c1100a059100000000000000000001c591000010000000000000000000000245910000c00000000000000069411000e00000000000000449c1100a0591000000000000000000030591000010000000000000000000000385910000e00000000000000c47d11000c00000000000000449c110048591000000000000000000058591000010000000000000000000000605910001500000000000000069411000e00000000000000449c110078591000000000000000000088591000010000000000000000000000905910000d00000000000000069411000e00000000000000449c1100a05910000000000000000000b05910000100000000000000456e6163746d656e74506572696f640018000000000000000100000034000000ff5a10005c000000449c1100000000005b5b10004c000000a75b10005a000000015c1000270000004c61756e6368506572696f64c65a100039000000566f74696e67506572696f64985a10002e0000004d696e696d756d4465706f7369740000180000000000000001000000350000004b5a10004d000000456d657267656e6379566f74696e67506572696f6400000018000000000000000100000036000000105a10003b000000436f6f6c6f6666506572696f6400000018000000000000000100000037000000b85910005800000020506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f7220616e20656d657267656e6379207265666572656e64756d2e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e20546865206d696e696d756d20706572696f64206f66206c6f636b696e6720616e642074686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e2049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e73757265207468617420766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652ef45d10005d0000004d0100000100000076616c756520746f6f206c6f7770726f706f73657227732062616c616e636520746f6f206c6f7763616e206f6e6c79207365636f6e6420616e206578697374696e672070726f706f73616c7365636f6e64657227732062616c616e636520746f6f206c6f776e6f7420612070726f787970726f706f73616c207374696c6c20626c61636b6c697374656470726f706f73616c20616c7265616479206d616465696e76616c696420686173686e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974796e6f2070726f706f73616c206d616465756e6b6e6f776e2070726f706f73616c6e6f2065787465726e616c2070726f706f73616c6964656e74697479206d6179206e6f74207665746f20612070726f706f73616c207477696365616c726561647920612070726f787977726f6e672070726f78796e6f742064656c656761746564756e6b6e6f776e20696e64657863616e6e6f742063616e63656c207468652073616d652070726f706f73616c20747769636570726f706f73616c206e6f7420666f756e64766f746520676976656e20666f7220696e76616c6964207265666572656e64756d2e2f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f64656d6f63726163792f7372632f6c69622e7273000000380000000800000004000000390000006e6577686561647350617261636861696e20686561647320636f756c64206e6f74206265206465636f6465642e4e6f2070617261636861696e20686561647320666f756e6420696e20696e686572656e7420646174612e626164206f726967696e3a20657870656374656420746f20626520612070617261636861696e206f726967696e436f6465486561647357617465726d61726b73556e726f75746564496e67726573730000245f100031000000555f100043000000120100000400000050617261636861696e206865616473206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b2f686f6d652f766f6c742f776f726b7370616365732f706172697479746563682f706f6c6b61646f742f72756e74696d652f7372632f70617261636861696e732e7273c05f1000480000009c0a00000a000000c05f100048000000a20a00000e00000000000000000000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f6d6f642e727376616c696461746f725f726f6c655f7061697273c05f100048000000b201000023000000c05f100048000000b3010000230000005060100043000000b402000014000000000000002f686f6d652f766f6c742f776f726b7370616365732f706172697479746563682f706f6c6b61646f742f72756e74696d652f7372632f70617261636861696e732e72730000000000fce710000b0000000000000000000000ac6310001000000000000000000000000000000000000000000000000000000000000000449c1100046510000000000000000000bc63100001000000000000000100000000000000e85e100004000000010100000000000055fd10000600000000000000dc4311000700000000000000000000000000000000000000449c1100cc6310000000000000000000c463100001000000000000000000000000000000ec5e100005000000010100000000000055fd10000600000000000000dc4311000700000000000000000000000000000000000000449c1100cc6310000000000000000000dc63100001000000000000000000000000000000f15e10000a000000010100000000000055fd10000600000000000000069411000e00000000000000000000000000000000000000449c1100e46310000000000000000000f463100003000000000000000000000000000000fb5e10000f00000001010000000000000c6410001800000000000000246410001300000000000000000000000000000000000000449c110038641000000000000000000048641000040000000000000000000000000000006864100012000000010100000000000055fd100006000000000000007a6410001200000000000000000000000000000000000000449c11008c64100000000000000000009c64100002000000000000000100000000000000ac64100016000000010100000000000055fd10000600000000000000c26410000a00000000000000000000000000000000000000449c1100cc6410000000000000000000dc64100003000000000000000100000000000000f46410000d0000000000000000000000580c11000b00000000000000000000000000000000000000000000000000000000000000449c11000465100000000000000000001465100001000000000000000100000000000000b38f1100090000000000000000000000580c11000b00000000000000000000000000000000000000000000000000000000000000449c11001c65100000000000000000002c6510000400000000000000000000005665633c56616c696461746f7249643eb66910002500000090691000260000001800000000000000010000003a0000005d691000330000001800000000000000010000002b000000776810003f000000b668100050000000066910005700000028543a3a426c6f636b4e756d6265722c20506172614964295665633c285061726149642c2048617368293e001800000000000000010000002b000000ae67100055000000449c1100000000000368100053000000566810002100000052656c6179446973706174636851756575655665633c5570776172644d6573736167653e1800000000000000010000002e00000035671000470000007c6710003200000052656c61794469737061746368517565756553697a65287533322c20753332291800000000000000010000003b0000004f66100051000000a066100056000000f66610003f0000004e6565647344697370617463680000001800000000000000010000002e0000000b661000440000001800000000000000010000002b0000004c65100059000000a56510004d000000449c110000000000f26510001900000020536f6d65206966207468652070617261636861696e20686561647320676574207570646174656420696e207468697320626c6f636b2c20616c6f6e672077697468207468652070617261636861696e20494473207468617420646964207570646174652e204f72646572656420696e207468652073616d652077617920617320607265676973747261723a3a416374697665602028692e652e20627920506172614964292e204e6f6e65206966206e6f742079657420757064617465642e20546865206f726465726564206c697374206f662050617261496473207468617420686176652061206052656c6179446973706174636851756575656020656e7472792e2053697a65206f6620746865206469737061746368207175657565732e205365706172617465642066726f6d2061637475616c206461746120696e206f7264657220746f2061766f696420636f73746c79206465636f64696e67207768656e20636865636b696e6720726563656970742076616c69646974792e204669727374206974656d20696e207475706c652069732074686520636f756e74206f66206d65737361676573097365636f6e642069662074686520746f74616c206c656e6774682028696e20627974657329206f6620746865206d657373616765207061796c6f6164732e204d6573736167657320726561647920746f2062652064697370617463686564206f6e746f207468652072656c617920636861696e2e204974206973207375626a65637420746f20604d41585f4d4553534147455f434f554e546020616e64206057415445524d41524b5f4d4553534147455f53495a45602e20556e726f7574656420696e67726573732e204d6170732028426c6f636b4e756d6265722c20746f5f636861696e2920706169727320746f205b2866726f6d5f636861696e2c206567726573735f726f6f74295d2e205468657265206d617920626520616e20656e74727920756e6465722028692c20702920696e2074686973206d617020666f722065766572792069206265747765656e207468652070617261636861696e27732077617465726d61726b20616e64207468652063757272656e7420626c6f636b2e205468652077617465726d61726b2068656967687473206f66207468652070617261636861696e7320726567697374657265642061742070726573656e742e20466f722065766572792070617261636861696e2c20746869732069732074686520626c6f636b206865696768742066726f6d20776869636820616c6c206d6573736167657320746172676574696e6720746861742070617261636861696e2068617665206265656e2070726f6365737365642e2043616e20626520604e6f6e6560206f6e6c79206966207468652070617261636861696e20646f65736e27742065786973742e20546865206865616473206f66207468652070617261636861696e7320726567697374657265642061742070726573656e742e205468652070617261636861696e7320726567697374657265642061742070726573656e742e20416c6c20617574686f72697469657327206b65797320617420746865206d6f6d656e742e50617261636861696e206865616473206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b546f6f206d616e792070617261636861696e2063616e646964617465736e6f2076616c696461746f722067726f757020666f722070617261636861696e4e6f7420656e6f7567682076616c6964697479206174746573746174696f6e73546865206e756d626572206f66206174746573746174696f6e73206578636565647320746865206e756d626572206f6620617574686f726974696573417474657374696e672076616c696461746f72206e6f74206f6e207468697320636861696e27732076616c69646174696f6e20647574792e4e6f7420656e6f7567682076616c696469747920766f74657343616e6469646174652076616c6964697479206174746573746174696f6e207369676e6174757265206973206261642e457874726120756e7461676765642076616c696469747920766f74657320616c6f6e6720776974682063616e64696461746563616e64696461746520666f7220756e726567697374657265642070617261636861696e207b7d696e76616c696420636f6c6c61746f7263616e646964617465206f7574206f66206f72646572626164206d657373616765206f726967696e4d65737361676573206164646564207768656e2071756575652066756c6c03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314456d707479207472696520726f6f7420696e636c75646564526f7574696e6720746f206e6f6e2d6578697374656e742070617261636861696e50617261636861696e20726f7574696e6720746f2073656c6645677265737320726f75746573206f7574206f66206f726465722062792049446f7264657265645f6e656564735f646973706174636820636f6e7461696e732069643f2100000000bc6c10000900000000000000c86c1000010000000000000000000000f098110001000000000000007365745f686561647300000000000000e06c10000500000000000000e56c10001600000068656164735665633c417474657374656443616e6469646174653e0000000000806d10000500000000000000886d1000010000000000000000000000906d1000010000000000000000000000986d10000a00000000000000242c1100010000000000000000000000a46d1000010000000000000000000000ac6d10000a00000000000000886d1000010000000000000000000000906d100001000000000000005375646964000000e897110004000000f26d1000180000004b65794368616e6765640000b66d10003c0000005375646f4173446f6e6520546865207375646f6572206a757374207377697463686564206964656e746974793b20746865206f6c64206b657920697320737570706c6965642e2041207375646f206a75737420746f6f6b20706c6163652e3a6772616e6470615f617574686f7269746965730000306e100042000000d30000001e0000002f686f6d652f766f6c742f776f726b7370616365732f706172697479746563682f706f6c6b61646f742f72756e74696d652f7372632f7265676973747261722e72730000306e100042000000d20000001c0000004163746976654e65787446726565496400000000ec6e10001400000000000000006f1000010000000000000000000000086f1000010000000000000000000000106f10001600000000000000006f1000010000000000000000000000286f10000100000000000000506172617468726561645265676973746572656455fd100006000000656f100035000000506172617468726561644465726567697374657265640000306f100035000000205468652070617261746872656164206f662074686520737570706c696564204944207761732064652d726567697374657265642e204120706172617468726561642077617320726567697374657265643b20697473206e657720494420697320737570706c6965642e52657472795175657565c06f100048000000a20a00000e0000000000000000000000000000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f6d6f642e72734772616e64706146696e616c69747950656e64696e674368616e6765537461746553656c65637465645468726561647300000000bc7010000400000000000000c0701000010000000000000000000000d87010000a0000000000000000000000287110000700000000000000307110000100000000000000000000004871100009000000000000000000000090711000070000000000000098711000020000000000000000000000c87110000b000000000000007375646f00000000040311000800000000000000d2721000100000003f7310004e000000449c1100000000000c45110034000000449c1100000000007e6311000b0000008d7011000800000042d710001900000085721000180000009d721000350000009e6311000c0000007365745f6b65790000000000986511000300000000000000f366110023000000e27210005d000000449c1100000000000c45110034000000449c1100000000007e6311000b0000008d7011000800000042d71000190000005bd71000110000009e6311000c0000007375646f5f61730000000000864a11000300000000000000f36611002300000000000000040311000800000000000000d27210001000000020721000540000007472100011000000449c1100000000000c45110034000000449c1100000000007e6311000b0000008d7011000800000042d710001900000085721000180000009d721000350000009e6311000c0000002041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c207769746820605369676e656460206f726967696e2066726f6d206120676976656e206163636f756e742e202d204f6e6520444220777269746520286576656e74292e202d20556e6b6e6f776e20776569676874206f662064657269766174697665206070726f706f73616c6020657865637574696f6e2e426f783c543a3a50726f706f73616c3e2041757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f206b65792e2041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e00000000000000e8731000030000000000000000000000676411000c00000000000000000000000000000000000000000000000000000000000000449c1100308210000000000000000000ec7310000100000000000000010000004b657900f4731000210000002054686520604163636f756e74496460206f6620746865207375646f206b65792e0000003074100068000000330000000600000000000000000000002f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f7072696d6974697665732f73722d7072696d6974697665732f7372632f63757276652e72735061726173546872656164436f756e7400000000d47410001200000000000000e87410000100000000000000000000000075100001000000000000007265706f72745f6d69736265686176696f72000000000000217510000700000000000000dc431100070000000875100019000000205265706f727420736f6d65206d69736265686176696f722e5f7265706f727400000000fce710000b0000000000000000000000907710000d00000000000000000000000000000000000000000000000000000000000000449c1100108210000000000000000000a07710000400000000000000010000000000000024701000050000000000000000000000c07710001b00000000000000000000000000000000000000000000000000000000000000449c1100dc7710000000000000000000ec77100001000000000000000100000000000000177010000d0000000000000000000000f47710002300000000000000000000000000000000000000000000000000000000000000449c1100d881100000000000000000001878100001000000000000000000000000000000207810000a0000000000000000000000069411000e00000000000000000000000000000000000000000000000000000000000000449c1100b478100000000000000000002c78100001000000000000000000000000000000347810000700000000000000000000003b7810002000000000000000000000000000000000000000000000000000000000000000449c11005c78100000000000000000006c78100001000000000000000000000000000000747810000c0000000000000000000000807810000500000000000000000000000000000000000000000000000000000000000000449c11008878100000000000000000009878100002000000000000000100000000000000a87810000c0000000101000000000000807810000500000000000000295811000c00000000000000000000000000000000000000449c1100b47810000000000000000000c4781000010000000000000000000000417574686f726974794c6973740000006c7a10000b000000449c110000000000777a100058000000cf7a10002500000053746f72656453746174653c543a3a426c6f636b4e756d6265723e001800000000000000010000003c000000487a10002400000053746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723e00177a1000310000004e657874466f726365640000e87910002f0000005374616c6c656428543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d62657229001800000000000000010000003d000000c47910002400000043757272656e74536574496453657449640000001800000000000000010000003e0000003c791000570000009379100031000000536574496453657373696f6e1800000000000000010000002b000000cc781000700000002041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f7220776869636820697473206d656d62657273207765726520726573706f6e7369626c652e20546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c69746965732920696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e20607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e20444550524543415445442054686973207573656420746f2073746f7265207468652063757272656e7420617574686f72697479207365742c20776869636820686173206265656e206d6967726174656420746f207468652077656c6c2d6b6e6f776e204752414e4450415f415554484f52495445535f4b455920756e686173686564206b65792e3800000008000000040000003f0000004000000000000000000000004100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003800000008000000040000003f0000004000000000000000000000004100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f7d1000580000006b000000010000006f6e6c79207468652063757272656e74207375646f206b65792063616e207375646f6f6e6c79207468652063757272656e74207375646f206b65792063616e206368616e676520746865207375646f206b65792f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f7375646f2f7372632f6c69622e727350617261636861696e20616c726561647920657869737473496e76616c696420696400000000000000823e11000a0000000000000000000000580c11000b00000000000000000000000000000000000000000000000000000000000000449c1100108210000000000000000000449c1100000000000000000001000000000000009d7410000b0000000000000000000000a67b11000300000000000000000000000000000000000000000000000000000000000000449c11000481100000000000000000001481100001000000000000000100000000000000297010000f00000000000000000000001c8110001e00000000000000000000000000000000000000000000000000000000000000449c11001082100000000000000000003c81100002000000000000000100000000000000846e10000600000000000000000000004c8110002e00000000000000000000000000000000000000000000000000000000000000449c11001082100000000000000000007c811000060000000000000001000000000000008a6e10000a000000000000000000000055fd10000600000000000000000000000000000000000000000000000000000000000000449c1100ac8110000000000000000000bc81100002000000000000000100000000000000cc8110000b000000010100000000000055fd1000060000000000000055fd10000600000000000000000000000000000000000000449c1100d88110000000000000000000e8811000010000000000000000000000000000009874100005000000010100000000000055fd10000600000000000000f08110000800000000000000000000000000000000000000449c1100f8811000000000000000000008821000010000000000000000000000000000009a6f10000a00000000000000000000001c8110001e00000000000000000000000000000000000000000000000000000000000000449c110010821000000000000000000020821000010000000000000001000000000000002882100007000000010100000000000055fd10000600000000000000676411000c00000000000000000000000000000000000000449c11003082100000000000000000004082100001000000000000000100000018000000000000000100000030000000408510002d0000005665633c5665633c285061726149642c20436f6c6c61746f724964293e3e0000a084100054000000f48410004c0000005665633c285061726149642c204f7074696f6e3c28436f6c6c61746f7249642c20526574726961626c65293e293e00005483100057000000ab8310005800000003841000560000005984100034000000449c1100000000008d8410001300000018000000000000000100000042000000f08210004f0000003f8310001500000050656e64696e6753776170001800000000000000010000002b000000d78210001900000050617261496e666f1800000000000000010000002b000000ad8210002a0000001800000000000000010000002e000000738210003a000000446562746f72730018000000000000000100000043000000488210002b0000002055736572732077686f20686176652070616964206120706172617468726561642773206465706f736974205468652063757272656e7420717565756520666f7220706172617468726561647320746861742073686f756c6420626520726574726965642e204d6170206f6620616c6c20726567697374657265642070617261746872656164732f636861696e732e2050656e64696e672073776170206f7065726174696f6e732e20546865206e65787420756e75736564205061726149642076616c75652e2053746172742074686973206869676820696e206f7264657220746f206b656570206c6f77206e756d6265727320666f722073797374656d2d6c6576656c20636861696e732e2050617261746872656164732f636861696e73207363686564756c656420666f7220657865637574696f6e207468697320626c6f636b2e2049662074686520636f6c6c61746f72204944206973207365742c207468656e206120706172746963756c617220636f6c6c61746f722068617320616c7265616479206265656e2063686f73656e20666f7220746865206e65787420626c6f636b2c20616e64206e6f206f7468657220636f6c6c61746f72206d61792070726f766964652074686520626c6f636b2e20496e2074686973206361736520776520616c6c6f772074686520706f73736962696c697479206f662074686520636f6d62696e6174696f6e206265696e67207265747269656420696e2061206c6174657220626c6f636b2c206578707265737365642062792060526574726961626c65602e204f726465726564206279205061726149642e20416e206172726179206f6620746865207175657565206f6620736574206f662074687265616473207363686564756c656420666f722074686520636f6d696e6720626c6f636b733b206f72646572656420627920617363656e64696e6720706172612049442e2054686572652063616e206265206e6f206475706c696361746573206f66207061726120494420696e2065616368206c697374206974656d2e20546865206e756d626572206f66207468726561647320746f207363686564756c652070657220626c6f636b2e0000009f85100042000000d900000001000000696e76616c6964206964696e76616c696420706172617468726561642069642f686f6d652f766f6c742f776f726b7370616365732f706172697479746563682f706f6c6b61646f742f72756e74696d652f7372632f7265676973747261722e727300000000000000188710000d000000000000002887100004000000000000000000000088871000020000000000000000000000988710000f00000000000000a8871000010000000000000000000000c0871000010000000000000000000000c88710001000000000000000d8871000010000000000000000000000f08710000500000000000000000000001888100013000000000000002c8810000200000000000000000000005c8810000400000000000000000000007c881000110000000000000090881000030000000000000000000000d8881000050000000000000000000000008910001500000000000000449c110000000000000000000000000018891000070000000000000000000000508910000400000000000000548910000100000000000000000000006c891000080000000000000072656769737465725f7061726100000000000000c18f10000200000000000000591f11000f000000000000000c9010000400000000000000f08110000800000000000000681f11000400000000000000dc4311000700000000000000f22011001100000000000000dc43110007000000c38f100026000000e98f100023000000646572656769737465725f706172610000000000c18f10000200000000000000591f11000f0000009c8f1000250000007365745f7468726561645f636f756e7400000000978f10000500000000000000a67b110003000000008f100050000000449c110000000000508f100026000000449c110000000000768f10002100000072656769737465725f706172617468726561640000000000681f11000400000000000000dc4311000700000000000000f22011001100000000000000dc43110007000000368e100029000000449c1100000000005f8e100053000000b28e10004e00000073656c6563745f7061726174687265616400000000000000168e10000300000000000000591f11000f00000000000000198e10000900000000000000228e10000a000000000000002c8e10000a000000000000000c03110007000000198d100041000000449c1100000000005a8d100050000000aa8d100057000000018e100015000000646572656769737465725f70617261746872656164000000de8b100032000000449c110000000000108c100048000000449c110000000000588c100056000000ae8c100051000000ff8c10001a0000007377617000000000d98b10000500000000000000591f11000f000000ac89100059000000058a1000590000005e8a100057000000449c110000000000b58a1000580000000d8b1000500000005d8b100056000000b38b100026000000205377617020612070617261636861696e207769746820616e6f746865722070617261636861696e206f7220706172617468726561642e20546865206f726967696e206d7573742062652061206050617261636861696e602e2054686520737761702077696c6c2068617070656e206f6e6c7920696620746865726520697320616c726561647920616e206f70706f7369746520737761702070656e64696e672e204966207468657265206973206e6f742c2074686520737761702077696c6c2062652073746f72656420696e207468652070656e64696e67207377617073206d61702c20726561647920666f722061206c6174657220636f6e6669726d61746f727920737761702e20546865206050617261496460732072656d61696e206d617070656420746f207468652073616d652068656164206461746120616e6420636f646520736f2065787465726e616c20636f64652063616e2072656c79206f6e20605061726149646020746f2062652061206c6f6e672d7465726d206964656e746966696572206f662061206e6f74696f6e616c202270617261636861696e222e20486f77657665722c207468656972207363686564756c696e6720696e666f2028692e652e2077686574686572207468657927726520612070617261746872656164206f722070617261636861696e292c2061756374696f6e20696e666f726d6174696f6e20616e64207468652061756374696f6e206465706f736974206172652073776974636865642e6f7468657220446572656769737465722061207061726174687265616420616e6420726574726965766520746865206465706f7369742e204d7573742062652073656e742066726f6d2061206050617261636861696e60206f726967696e2077686963682069732063757272656e746c79206120706172617468726561642e20456e737572652074686174206265666f72652063616c6c696e672074686973207468617420616e792066756e647320796f752077616e7420656d70746965642066726f6d2074686520706172617468726561642773206163636f756e74206973206d6f766564206f75743b20616674657220746869732069742077696c6c20626520696d706f737369626c6520746f207265747269657665207468656d2028776974686f757420676f7665726e616e636520696e74657276656e74696f6e292e20506c61636520612062696420666f722061207061726174687265616420746f2062652070726f6772657373656420696e20746865206e65787420626c6f636b2e20546869732069732061206b696e64206f66207370656369616c207472616e73616374696f6e20746861742073686f756c642062792068656176696c79207072696f726974697a656420696e20746865207472616e73616374696f6e20706f6f6c206163636f7264696e6720746f20746865206076616c7565603b206f6e6c792060546872656164436f756e7460206f66207468656d206d61792062652070726573656e74656420696e20616e792073696e676c6520626c6f636b2e5f69645f636f6c6c61746f72436f6c6c61746f7249645f686561645f686173682052656769737465722061207061726174687265616420666f7220696d6d656469617465207573652e204d7573742062652073656e742066726f6d2061205369676e6564206f726967696e20746861742069732061626c6520746f206861766520506172617468726561644465706f7369742072657365727665642e2060636f64656020616e642060696e697469616c5f686561645f646174616020617265207573656420746f20696e697469616c697a6520746865207061726174687265616427732073746174652e20526573657420746865206e756d626572206f6620706172617468726561647320746861742063616e2070617920746f206265207363686564756c656420696e20612073696e676c6520626c6f636b2e202d2060636f756e74603a20546865206e756d626572206f662070617261746872656164732e204d7573742062652063616c6c65642066726f6d20526f6f74206f726967696e2e636f756e74204465726567697374657220612070617261636861696e207769746820676976656e206964696420526567697374657220612070617261636861696e207769746820676976656e20636f64652e204661696c7320696620676976656e20494420697320616c726561647920757365642e696e666f486561644f66566f7465734f6650687261676d656e456c656374696f6e566f7465734f6662656e6566696369617279206163636f756e74206d757374207072652d6578697374546f74616c49737375616e63654672656542616c616e6365526573657276656442616c616e63654c6f636b73000000000000089110000a0000000000000084571100020000000000000000000000149110000100000000000000000000001c9110000d00000000000000242c11000100000000000000000000002c9110000100000000000000000000003491100008000000000000003c9110000400000000000000000000005c91100001000000000000004e65774163636f756e740000a79110001b0000005265617065644163636f756e7400000090911000170000005472616e736665727e581100090000007e5811000900000087581100070000008758110007000000649110002c000000205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c75652c2066656573292e20416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e5265706f727473656e74697265206e65775f7365742077617320676976656e20746f206275696c645f737570706f72745f6d61703b20656e20656e747279206d757374206265206372656174656420666f722065616368206974656d3b207165645374616b654f660000000000000893100007000000000000001093100001000000000000000000000018931000020000000000000000000000289310000900000000000000449c1100000000000000000000000000349310000100000000000000000000003c9310000c00000000000000242c110001000000000000000000000048931000020000000000000000000000589310000f00000000000000242c110001000000000000000000000068931000010000000000000000000000709310000d00000000000000809310000300000000000000000000009893100002000000000000004e65775465726d008595100019000000df941000550000003495100051000000456d7074795465726d000000a9941000360000004d656d6265724b69636b65644b941000510000009c9410000d0000004d656d62657252656e6f756e636564002394100028000000566f7465725265706f727465640000007e581100090000007e58110009000000e897110004000000a8931000580000000094100023000000204120766f7465722028666972737420656c656d656e742920776173207265706f72746564202862797420746865207365636f6e6420656c656d656e742920776974682074686520746865207265706f7274206265696e67207375636365737366756c206f72206e6f742028746869726420656c656d656e74292e2041206d656d626572206861732072656e6f756e6365642074686569722063616e6469646163792e2041206d656d62657220686173206265656e2072656d6f7665642e20546869732073686f756c6420616c7761797320626520666f6c6c6f7765642062792065697468657220604e65775465726d60206f742060456d7074795465726d602e204e6f20286f72206e6f7420656e6f756768292063616e64696461746573206578697374656420666f72207468697320726f756e642e2041206e6577207465726d2077697468206e6577206d656d626572732e205468697320696e64696361746573207468617420656e6f7567682063616e6469646174657320657869737465642c206e6f74207468617420656e6f756768206861766520686173206265656e20656c65637465642e2054686520696e6e65722076616c7565206d757374206265206578616d696e656420666f72207468697320707572706f73652e5665633c284163636f756e7449642c2042616c616e6365293e0000b0951000480000009c0a00000a0000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f6d6f642e7273089610005c0000004f000000010000002f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f6f6666656e6365732f7372632f6c69622e727343616e6469646174657352756e6e65727355705175657565644b6579733a73657373696f6e3a6b6579734e6578744b657973746f6f2066657720667265652066756e647320696e206163636f756e747061796d656e7420776f756c64206b696c6c206163636f756e7456657374696e676163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c76657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c7565000000000058971000080000000000000060971000020000000000000000000000909710000a000000000000007365745f6b65797300000000ff98100004000000000000000399100007000000000000000a9910000500000000000000dc43110007000000e09710003900000019981000480000006198100031000000449c1100000000009298100035000000449c1100000000007e6311000b000000c798100022000000e9981000160000009e6311000c0000002053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b6579602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d204f286c6f67206e2920696e206e756d626572206f66206163636f756e74732e202d204f6e6520657874726120444220656e7472792e6b657973543a3a4b65797370726f6f660000000000675611000a0000000000000000000000789b10001300000000000000000000000000000000000000000000000000000000000000449c110054c9100000000000000000008c9b100001000000000000000100000000000000949b10000c0000000000000000000000295811000c00000000000000000000000000000000000000000000000000000000000000449c11001cc910000000000000000000a09b100001000000000000000100000000000000a89b10000d0000000000000000000000e89711000400000000000000000000000000000000000000000000000000000000000000449c1100b89b10000000000000000000c89b100002000000000000000100000000000000779610000a0000000000000000000000d89b10001e00000000000000000000000000000000000000000000000000000000000000449c1100f89b10000000000000000000089c100002000000000000000100000000000000189c1000120000000000000000000000c26311000800000000000000000000000000000000000000000000000000000000000000449c110054c9100000000000000000002c9c1000030000000000000001000000000000008e961000080000000204010000000000dc4311000700000000000000449c10000e00000000000000039910000700000000000000449c1100549c10000000000000000000649c100004000000000000000000000000000000849c1000080000000204010000000000dc43110007000000000000008c9c10001400000000000000449c10000e00000000000000449c110008b610000000000000000000a09c10000400000000000000000000005665633c543a3a56616c696461746f7249643e00679f10001f00000043757272656e74496e646578499f10001e0000005175657565644368616e6765640000001800000000000000010000002b000000d29e10004e000000209f1000290000005665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e00001800000000000000010000002e0000004b9e10004f0000009a9e10003800000044697361626c656456616c696461746f72730000de9d100020000000449c110000000000fe9d10004d000000543a3a56616c696461746f72496400001800000000000000010000002b000000b79d100027000000449c110000000000099d1000560000005f9d1000580000004b65794f776e6572284b65795479706549642c205665633c75383e29c09c100049000000449c110000000000099d1000560000005f9d10005800000020546865206f776e6572206f662061206b65792e20546865207365636f6e64206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206669727374206b657920697320616c77617973206044454455505f4b45595f5052454649586020746f206861766520616c6c20746865206461746120696e207468652073616d65206272616e6368206f662074686520747269652e20486176696e6720616c6c206461746120696e207468652073616d65206272616e63682073686f756c642070726576656e7420736c6f77696e6720646f776e206f7468657220717565726965732e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e20496e6469636573206f662064697361626c65642076616c696461746f72732e205468652073657420697320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e732061206e657720736574206f66206964656e7469746965732e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f727320686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e000000000000c09f1000100000000000000066f510000500000000000000449c1100d09f10000000000000000000e09f1000020000000000000044454455505f4b45595f50524546495818000000000000000100000044000000f09f10005900000049a010000d0000002055736564206173206669727374206b657920666f7220604e6578744b6579736020616e6420604b65794f776e65726020746f2070757420616c6c20746865206461746120696e746f207468652073616d65206272616e6368206f662074686520747269652e6e6f7420656e6f75676820667265652066756e647300000000001ca11000080000000000000024a1100002000000000000000000000054a110001900000000000000000000001ca210000b0000000000000028a2100003000000000000000000000070a210000d0000000000000000000000d8a210000e00000000000000e8a2100003000000000000000000000030a3100002000000000000000000000040a31000130000000000000024a1100002000000000000000000000054a3100006000000000000007472616e7366657200000000a72111000400000000000000f366110023000000000000004d6f11000500000000000000ada410001300000081a6100036000000449c110000000000b7a6100042000000f9a610004800000041a710004500000086a710002d000000449c110000000000b3a7100046000000449c1100000000007e6311000b000000f9a710004c00000045a810003300000078a810005a000000449c110000000000d2a8100013000000449c110000000000e5a810005400000039a910004b00000084a9100035000000b9a9100037000000f0a910005600000046aa10005200000098aa10003e000000449c1100000000009e6311000c0000007365745f62616c616e63650000000000864a11000300000000000000f366110023000000000000006da610000800000000000000ada41000130000000000000075a610000c00000000000000ada4100013000000c0a4100025000000449c110000000000e5a41000480000002da51000420000006fa5100046000000b5a510003a000000449c110000000000efa510002d000000449c1100000000007e6311000b0000001ca61000200000003ca61000310000009e6311000c000000666f7263655f7472616e73666572000000000000a7a410000600000000000000f36611002300000000000000a72111000400000000000000f366110023000000000000004d6f11000500000000000000ada410001300000048a41000540000009ca410000b0000007472616e736665725f6b6565705f616c6976650084a3100054000000d8a3100010000000449c110000000000e8a310002f000000449c11000000000017a41000310000002053616d6520617320746865205b607472616e73666572605d2063616c6c2c206275742077697468206120636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e20393925206f66207468652074696d6520796f752077616e74205b607472616e73666572605d20696e73746561642e205b607472616e73666572605d3a207374727563742e4d6f64756c652e68746d6c236d6574686f642e7472616e736665722045786163746c7920617320607472616e73666572602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74206d6179206265207370656369666965642e736f75726365436f6d706163743c543a3a42616c616e63653e20536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e636520286073797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e6e65775f667265656e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c2074726967676572202020202060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e6365646020616e642060543a3a4f6e4672656542616c616e63655a65726f3a3a6f6e5f667265655f62616c616e63655f7a65726f602e2020202d20607472616e736665725f6b6565705f616c6976656020776f726b73207468652073616d652077617920617320607472616e73666572602c206275742068617320616e206164646974696f6e616c2020202020636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e000000000000569010000d000000000000000000000090ac10000a00000000000000000000000000000000000000000000000000000000000000449c11003cc9100000000000000000009cac100001000000000000000100000000000000cd961000070000000101000000000000676411000c00000000000000a4ac10002b00000000000000000000000000000000000000449c1100d0ac10000000000000000000e0ac100001000000000000000000000000000000639010000b0000000101000000000000676411000c0000000000000090ac10000a00000000000000000000000000000000000000449c11003cc910000000000000000000e8ac10000b0000000000000001000000000000006e9010000f0000000101000000000000676411000c0000000000000090ac10000a00000000000000000000000000000000000000449c11003cc91000000000000000000040ad10000b0000000000000001000000000000007d901000050000000101000000000000676411000c0000000000000098ad10002c00000000000000000000000000000000000000449c1100c4ad10000000000000000000d4ad1000010000000000000001000000543a3a42616c616e6365000005b310002600000056657374696e675363686564756c653c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e001800000000000000010000002b000000cfb210003600000055b0100027000000449c1100000000007cb0100050000000ccb010005d00000029b11000550000007eb110004f000000cdb11000510000001eb2100015000000449c11000000000033b21000570000008ab21000450000000aae10005d00000067ae100027000000449c1100000000008eae10005b000000e9ae100049000000449c11000000000032af10005d0000008faf10002d000000449c110000000000bcaf1000530000000fb01000460000005665633c42616c616e63654c6f636b3c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e3e1800000000000000010000002e000000dcad10002e00000020416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e2054686520616d6f756e74206f66207468652062616c616e6365206f66206120676976656e206163636f756e7420746861742069732065787465726e616c6c792072657365727665643b20746869732063616e207374696c6c2067657420736c61736865642c20627574206765747320736c6173686564206c617374206f6620616c6c2e20546869732062616c616e63652069732061202772657365727665272062616c616e63652074686174206f746865722073756273797374656d732075736520696e206f7264657220746f2073657420617369646520746f6b656e73207468617420617265207374696c6c20276f776e65642720627920746865206163636f756e7420686f6c6465722c20627574207768696368206172652073757370656e6461626c652e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e2074686973202772657365727665206163636f756e74272069732064656c657465643a207370656369666963616c6c792c2060526573657276656442616c616e6365602e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c6574656420696620604672656542616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e2920546865202766726565272062616c616e6365206f66206120676976656e206163636f756e742e205468697320697320746865206f6e6c792062616c616e63652074686174206d61747465727320696e207465726d73206f66206d6f7374206f7065726174696f6e73206f6e20746f6b656e732e20497420616c6f6e65206973207573656420746f2064657465726d696e65207468652062616c616e6365207768656e20696e2074686520636f6e747261637420657865637574696f6e20656e7669726f6e6d656e742e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e20746865202763757272656e74206163636f756e74272069732064656c657465643a207370656369666963616c6c7920604672656542616c616e6365602e20467572746865722c2074686520604f6e4672656542616c616e63655a65726f602063616c6c6261636b20697320696e766f6b65642c20676976696e672061206368616e636520746f2065787465726e616c206d6f64756c657320746f20636c65616e2075702064617461206173736f6369617465642077697468207468652064656c65746564206163636f756e742e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c657465642069662060526573657276656442616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e20496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e0000000000d4b31000120000000000000090ac10000a00000000000000449c1100e8b310000000000000000000f8b3100001000000000000000000000000b410000b0000000000000090ac10000a00000000000000449c110020b4100000000000000000000cb4100001000000000000000000000014b410000b0000000000000090ac10000a00000000000000449c110020b41000000000000000000030b4100001000000000000004578697374656e7469616c4465706f73697400001800000000000000010000004500000084b41000350000005472616e73666572466565005fb41000250000004372656174696f6e466565001800000000000000010000004600000038b4100027000000205468652066656520726571756972656420746f2063726561746520616e206163636f756e742e205468652066656520726571756972656420746f206d616b652061207472616e736665722e20546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e00000000000000c2911000070000000101000000000000c4b510000d00000000000000d1b510003400000000000000000000000000000000000000449c110008b61000000000000000000018b610000100000000000000000000000000000020b6100016000000020101000000000036b6100004000000000000003ab610000e0000000000000048b610001200000000000000449c110054c9100000000000000000005cb610000100000000000000010000000000000064b6100012000000010100000000000036b610000400000000000000dc4311000700000000000000000000000000000000000000449c110078b61000000000000000000088b610000600000000000000010000005265706f727449644f663c543e4f6666656e636544657461696c733c543a3a4163636f756e7449642c20543a3a4964656e74696669636174696f6e5475706c653e0000001800000000000000010000002b00000021b8100052000000436f6e63757272656e745265706f727473496e6465784b696e644f706171756554696d65536c6f745665633c5265706f727449644f663c543e3e0000d7b710004a0000005265706f72747342794b696e64496e64657800001800000000000000010000002c000000b8b6100044000000449c110000000000fcb610002f000000449c1100000000002bb71000520000007db710005a00000020456e756d65726174657320616c6c207265706f727473206f662061206b696e6420616c6f6e672077697468207468652074696d6520746865792068617070656e65642e20416c6c207265706f7274732061726520736f72746564206279207468652074696d65206f66206f6666656e63652e204e6f74652074686174207468652061637475616c2074797065206f662074686973206d617070696e6720697320605665633c75383e602c207468697320697320626563617573652076616c756573206f6620646966666572656e7420747970657320617265206e6f7420737570706f7274656420617420746865206d6f6d656e7420736f2077652061726520646f696e6720746865206d616e75616c2073657269616c697a6174696f6e2e204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e20546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e566563746f72206361706163697479206f766572666c6f7700bfb9100013000000edb910001a0000006cb91000530000005703000003000000bfb9100013000000d2b910001b0000006cb91000530000005d03000003000000e4b81000260000000ab91000620000004400000004000000617373657274696f6e206661696c65643a2062697473203c3d20726573756c742e6c656e28292f686f6d652f766f6c742f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e312e302f7372632f6269745f7665632e72732f686f6d652f766f6c742f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6269747665632d302e31352e322f7372632f7665632e72734361706163697479206f766572666c6f773a20206f766572666c6f777320616c6c6f636174696f6e2073697a6520206f766572666c6f7773206d6178696d756d206c656e67746820696d2d6f6e6c696e653a6f66666c696e000000000020021100040000000000000020bb100002000000000000000000000050bb10000f0000000000000000000000c8bb10000c00000000000000449c1100000000000000000000000000d4bb10000700000000000000000000000cbc10001400000000000000c841110001000000000000000000000020bc10000d000000000000000000000088bc10001000000000000000449c110000000000000000000000000098bc10000d000000000000000000000000bd10001200000000000000449c110000000000000000000000000014bd1000090000000000000000000000144811000d000000000000005cbd100001000000000000000000000074bd10000d0000000000000000000000c2c610000500000000000000b064110011000000000000004d6f11000500000000000000526f11001500000028c5100041000000449c11000000000069c51000140000007dc51000120000008fc510002b000000449c110000000000bac510005700000011c610005700000068c6100028000000449c1100000000007e6311000b00000037bf10000b0000001cc510000c00000090c61000320000009e6311000c00000072656d6f76655f766f746572d4c4100048000000449c1100000000007e6311000b00000037bf10000b0000001cc510000c0000001bc310000d0000009e6311000c0000007265706f72745f646566756e63745f766f74657228c31000570000007fc3100057000000d6c3100017000000449c110000000000edc31000220000000fc410005300000062c410002d000000449c1100000000007e6311000b00000037bf10000b0000008fc41000450000001bc310000d0000009e6311000c0000007375626d69745f63616e646964616379d9c110001e000000449c110000000000f7c110001900000010c210003b0000004bc210004b00000096c2100055000000ebc210000d000000449c1100000000007e6311000b00000037bf10000b000000f8c21000230000001bc310000d0000009e6311000c00000072656e6f756e63655f63616e64696461637900006fbf100054000000c3bf100010000000d3bf10005000000023c010003d00000060c0100056000000b6c0100021000000d7c01000530000002ac110005600000080c110005900000000000000864a11000300000000000000f366110023000000dcbd10005700000033be100020000000449c11000000000053be100056000000a9be10003d000000449c110000000000e6be100051000000449c1100000000007e6311000b00000037bf10000b00000042bf10001600000058bf1000170000009e6311000c0000002052656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c7920616e642074686520626f6e64206f6620746865206f7574676f696e67206d656d62657220697320736c61736865642e20496620612072756e6e65722d757020697320617661696c61626c652c207468656e2074686520626573742072756e6e65722d75702077696c6c2062652072656d6f76656420616e64207265706c6163657320746865206f7574676f696e67206d656d6265722e204f74686572776973652c2061206e65772070687261676d656e20726f756e6420697320737461727465642e204e6f74652074686174207468697320646f6573206e6f7420616666656374207468652064657369676e6174656420626c6f636b206e756d626572206f6620746865206e65787420656c656374696f6e2e20232323232053746174652052656164733a204f28646f5f70687261676d656e29205772697465733a204f28646f5f70687261676d656e292052656e6f756e6365206f6e65277320696e74656e74696f6e20746f20626520612063616e64696461746520666f7220746865206e65787420656c656374696f6e20726f756e642e203320706f74656e7469616c206f7574636f6d65732065786973743a202d20606f726967696e6020697320612063616e64696461746520616e64206e6f7420656c656374656420696e20616e79207365742e20496e207468697320636173652c2074686520626f6e64206973202020756e72657365727665642c2072657475726e656420616e64206f726967696e2069732072656d6f76656420617320612063616e6469646174652e202d20606f726967696e6020697320612063757272656e742072756e6e65722075702e20496e207468697320636173652c2074686520626f6e6420697320756e72657365727665642c2072657475726e656420616e642020206f726967696e2069732072656d6f76656420617320612072756e6e65722e202d20606f726967696e6020697320612063757272656e74206d656d6265722e20496e207468697320636173652c2074686520626f6e6420697320756e726573657276656420616e64206f726967696e20697320202072656d6f7665642061732061206d656d6265722c20636f6e73657175656e746c79206e6f74206265696e6720612063616e64696461746520666f7220746865206e65787420726f756e6420616e796d6f72652e20202053696d696c617220746f205b6072656d6f76655f766f746572605d2c206966207265706c6163656d656e742072756e6e657273206578697374732c20746865792061726520696d6d6564696174656c7920757365642e205375626d6974206f6e6573656c6620666f722063616e6469646163792e20412063616e6469646174652077696c6c206569746865723a2020202d204c6f73652061742074686520656e64206f6620746865207465726d20616e6420666f7266656974207468656972206465706f7369742e2020202d2057696e20616e64206265636f6d652061206d656d6265722e204d656d626572732077696c6c206576656e7475616c6c7920676574207468656972207374617368206261636b2e2020202d204265636f6d6520612072756e6e65722d75702e2052756e6e6572732d75707320617265207265736572766564206d656d6265727320696e2063617365206f6e65206765747320666f72636566756c6c79202020202072656d6f7665642e2052656164733a204f284c6f674e2920476976656e204e2063616e646964617465732e205772697465733a204f283129205265706f727420607461726765746020666f72206265696e6720616e20646566756e637420766f7465722e20496e2063617365206f6620612076616c6964207265706f72742c20746865207265706f727465722069732072657761726465642062792074686520626f6e6420616d6f756e74206f662060746172676574602e204f74686572776973652c20746865207265706f7274657220697473656c662069732072656d6f76656420616e6420746865697220626f6e6420697320736c61736865642e204120646566756e637420766f74657220697320646566696e656420746f2062653a2020202d206120766f7465722077686f73652063757272656e74207375626d697474656420766f7465732061726520616c6c20696e76616c69642e20692e652e20616c6c206f66207468656d20617265206e6f20202020206c6f6e67657220612063616e646964617465206e6f7220616e20616374697665206d656d6265722e2052656164733a204f284e4c6f674d2920676976656e204d2063757272656e742063616e6469646174657320616e64204e20766f74657320666f722060746172676574602e2052656d6f766520606f726967696e60206173206120766f7465722e20546869732072656d6f76657320746865206c6f636b20616e642072657475726e732074686520626f6e642e2052656164733a204f28312920566f746520666f72206120736574206f662063616e6469646174657320666f7220746865207570636f6d696e6720726f756e64206f6620656c656374696f6e2e205468652060766f746573602073686f756c643a2020202d206e6f7420626520656d7074792e2020202d206265206c657373207468616e20746865206e756d626572206f662063616e646964617465732e2055706f6e20766f74696e672c206076616c75656020756e697473206f66206077686f6027732062616c616e6365206973206c6f636b656420616e64206120626f6e6420616d6f756e742069732072657365727665642e2049742069732074686520726573706f6e736962696c697479206f66207468652063616c6c657220746f206e6f7420706c61636520616c6c206f662074686569722062616c616e636520696e746f20746865206c6f636b20616e64206b65657020736f6d6520666f722066757274686572207472616e73616374696f6e732e205772697465733a204f28562920676976656e2060566020766f7465732e205620697320626f756e6465642062792031362e766f746573000000000003301100070000000000000000000000d8c810002100000000000000000000000000000000000000000000000000000000000000449c110054c910000000000000000000fcc81000010000000000000001000000000000006e961000090000000000000000000000d8c810002100000000000000000000000000000000000000000000000000000000000000449c110054c91000000000000000000004c91000010000000000000001000000000000000cc910000e0000000000000000000000a67b11000300000000000000000000000000000000000000000000000000000000000000449c11001cc9100000000000000000002cc91000010000000000000001000000000000002d901000070000000101010000000000676411000c00000000000000b06411001100000000000000000000000000000000000000449c110054c91000000000000000000034c910000100000000000000010000000000000023921000070000000101000000000000676411000c00000000000000c47d11000c00000000000000000000000000000000000000449c11003cc9100000000000000000004cc9100001000000000000000100000000000000649610000a0000000000000000000000b06411001100000000000000000000000000000000000000000000000000000000000000449c110054c91000000000000000000064c910000200000000000000010000005665633c28543a3a4163636f756e7449642c2042616c616e63654f663c543e293e00000008cb10003c000000b6ca100052000000456c656374696f6e526f756e647300001800000000000000010000003000000066ca10005000000026ca100040000000180000000000000001000000470000000dca1000190000001800000000000000010000002e00000074c9100059000000cdc9100040000000205468652070726573656e742063616e646964617465206c6973742e20536f72746564206261736564206f6e206163636f756e742069642e20412063757272656e74206d656d6265722063616e206e6576657220656e746572207468697320766563746f7220616e6420697320616c7761797320696d706c696369746c7920617373756d656420746f20626520612063616e6469646174652e204c6f636b6564207374616b65206f66206120766f7465722e20566f746573206f66206120706172746963756c617220766f7465722c20776974682074686520726f756e6420696e646578206f662074686520766f7465732e2054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e65642c206578636c7564696e6720746865207570636f6d696e67206f6e652e205468652063757272656e742072756e6e6572735f75702e20536f72746564206261736564206f6e206c6f7720746f2068696768206d657269742028776f72736520746f20626573742072756e6e6572292e205468652063757272656e7420656c6563746564206d656d626572736869702e20536f72746564206261736564206f6e206163636f756e742069642e000000005ccc10000d00000000000000c47d11000c00000000000000449c11006ccc10000000000000000000449c11000000000000000000000000007ccc10000a00000000000000c47d11000c00000000000000449c110088cc10000000000000000000449c110000000000000000000000000098cc10000e00000000000000a67b11000300000000000000449c1100a8cc10000000000000000000449c1100000000000000000000000000b8cc10001000000000000000a67b11000300000000000000449c1100c8cc10000000000000000000449c1100000000000000000000000000d8cc10000c00000000000000069411000e00000000000000449c1100e4cc10000000000000000000449c1100000000000000000043616e646964616379426f6e6400000018000000000000000100000035000000566f74696e67426f6e64000018000000000000000100000048000000446573697265644d656d626572730000180000000000000001000000490000004465736972656452756e6e65727355701800000000000000010000004a0000005465726d4475726174696f6e1800000000000000010000004b0000006e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e72656769737465726564206475706c6963617465206b657900f0cd10005c0000008401000001000000676f74206f766572666c6f7720616674657220616464696e6720612066656520746f2076616c756562616c616e636520746f6f206c6f7720746f2073656e642076616c756564657374696e6174696f6e2062616c616e636520746f6f206869676820746f20726563656976652076616c756576616c756520746f6f206c6f7720746f20637265617465206163636f756e747472616e7366657220776f756c64206b696c6c206163636f756e742f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f62616c616e6365732f7372632f6c69622e72732dd0100066000000ab0000000100000063616e6e6f7420766f7465207768656e206e6f2063616e64696461746573206f72206d656d6265727320657869737463616e6e6f7420766f7465206d6f7265207468616e2063616e6469646174657363616e6e6f7420766f7465206d6f7265207468616e206d6178696d756d20616c6c6f7765646d75737420766f746520666f72206174206c65617374206f6e652063616e6469646174652e63616e6e6f7420766f74652077697468207374616b65206c657373207468616e206d696e696d756d2062616c616e6365766f7465722063616e206e6f742070617920766f74696e6720626f6e6463616e6e6f74207265706f72742073656c667265706f72746572206d757374206265206120766f7465726475706c69636174652063616e646964617465207375626d697373696f6e6d656d6265722063616e6e6f742072652d7375626d69742063616e64696461637972756e6e65722063616e6e6f742072652d7375626d69742063616e64696461637963616e64696461746520646f6573206e6f74206861766520656e6f7567682066756e64736f726967696e206973206e6f7420612063616e6469646174652c206d656d626572206f7220612072756e6e65722e6d757374206265206120766f7465722f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f656c656374696f6e732d70687261676d656e2f7372632f6c69622e72736e6f6e652076616c756573206172652066696c7465726564206f757420696e2070726576696f7573206c6f6769633b207165640000b095100048000000a20a00000e0000002f686f6d652f766f6c742f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e312e302f7372632f636f6d706163742e7273000000000000d4f61000080000000000000044d210000100000000000000000000004cd2100001000000000000000000000054d2100008000000000000005cd2100001000000000000000000000064d210000100000000000000000000006cd21000070000000000000074d210000300000000000000000000008cd2100001000000000000000000000094d2100005000000000000005cd210000100000000000000000000009cd21000010000000000000000000000a4d2100008000000000000005cd21000010000000000000000000000acd21000010000000000000000000000b4d2100007000000000000005cd21000010000000000000000000000bcd21000010000000000000098f910000d000000add310000e0000005370656e64696e67875811000700000073d310003a000000417761726465640098f910000d00000087581100070000007e5811000900000053d31000200000004275726e7400000030d3100023000000526f6c6c6f766572e4d210004c0000004465706f73697400c4d210002000000020536f6d652066756e64732068617665206265656e206465706f73697465642e205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e204e65772070726f706f73616c2e0035d4100036000000d8d01000620000005f01000005000000000000000000000000000000f8d310003d000000d8d01000620000006601000005000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b2071656450726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b207165640035d4100036000000d8d01000620000008b010000050000000000000000000000000000000000000000000000d8d01000620000009201000005000000496e636f6e73697374656e74207374617465202d20636f756c646e277420736574746c6520696d62616c616e636520666f722066756e6473207370656e74206279207472656173757279486973746f726963616c53657373696f6e730000000088d510000d0000000000000098d51000020000000000000000000000c8d5100009000000000000000000000010d610000f0000000000000020d6100001000000000000000000000038d6100007000000000000000000000070d61000100000000000000020d6100001000000000000000000000080d61000080000000000000070726f706f73655f7370656e64000000000000004d6f11000500000000000000526f1100150000000000000098d810000b00000000000000f366110023000000c6d710004b00000011d810004d0000005ed8100015000000449c1100000000007e6311000b0000008d7011000800000042d710001900000073d81000250000009e6311000c00000072656a6563745f70726f706f73616c0000000000bbd710000b0000000000000018031100160000006cd710003f000000449c1100000000007e6311000b0000008d7011000800000042d7100019000000abd71000100000009e6311000c000000617070726f76655f70726f706f73616cc0d610005700000017d710002b000000449c1100000000007e6311000b0000008d7011000800000042d71000190000005bd71000110000009e6311000c00000020417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e202d204c696d697465642073746f726167652072656164732e202d204f6e65204442206368616e67652e2052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e202d204f6e6520444220636c6561722e70726f706f73616c5f69642050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e202d204f6e65204442206368616e67652c206f6e6520657874726120444220656e7472792e62656e65666963696172790000000000080511000d000000000000000000000098f910000d00000000000000000000000000000000000000000000000000000000000000449c1100acd910000000000000000000bcd91000010000000000000001000000000000007900110009000000010100000000000098f910000d00000000000000c4d910002400000000000000000000000000000000000000449c1100e8d910000000000000000000f8d910000100000000000000000000000000000000da100009000000000000000000000009da10001200000000000000000000000000000000000000000000000000000000000000449c11001cda100000000000000000002cda10000100000000000000010000001800000000000000010000003000000091da10002900000050726f706f73616c3c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e1800000000000000010000002b00000072da10001f000000417070726f76616c735665633c50726f706f73616c496e6465783e001800000000000000010000002e00000034da10003e0000002050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e0000000000009cdb10000c00000000000000a8db10000700000000000000449c1100b0db10000000000000000000c0db1000020000000000000000000000d0db10001300000000000000c47d11000c00000000000000449c1100e4db10000000000000000000f4db1000010000000000000000000000fcdb10000b00000000000000069411000e00000000000000449c110008dc1000000000000000000018dc100001000000000000000000000020dc10000400000000000000a8db10000700000000000000449c110024dc1000000000000000000034dc1000010000000000000050726f706f73616c426f6e645065726d696c6c001800000000000000010000004c000000f4dc10005500000049dd10004400000050726f706f73616c426f6e644d696e696d756d0018000000000000000100000035000000a2dc1000520000005370656e64506572696f64001800000000000000010000004d00000080dc1000220000004275726e1800000000000000010000004e0000003cdc1000440000002050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e204672616374696f6e206f6620612070726f706f73616c27732076616c756520746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c616365207468652070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f6573206e6f742e00000000000000e8dd1000110000000000000000000000f9dd10000a00000000000000000000000000000000000000000000000000000000000000449c110004de10000000000000000000449c11000000000000000000010000004e6578744665654d756c7469706c6965724d756c7469706c696572001800000000000000010000003e0000000000000084de10001200000000000000c47d11000c00000000000000449c110098de10000000000000000000a8de1000010000000000000000000000b0de10001200000000000000c47d11000c00000000000000449c1100c4de10000000000000000000d4de100001000000000000005472616e73616374696f6e426173654665650000180000000000000001000000460000001fdf1000370000005472616e73616374696f6e4279746546656500001800000000000000010000004f000000dcde100043000000205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b2074686520626173652e000010e0100048000000b20100002300000010e0100048000000b301000023000000e9df10001c000000cc9b110018000000e60300000d000000a0df100049000000870200001d0000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f736f72742e7273617373657274696f6e206661696c65643a206d6964203c3d206c656e00000000000000000000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f6d6f642e7273a0df1000490000009d0000003a000000a0df100049000000a400000030000000bbe010005c000000720000000100000050726f706f73657227732062616c616e636520746f6f206c6f774e6f2070726f706f73616c206174207468617420696e6465782f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f74726561737572792f7372632f6c69622e72730020e110001a0000004552524f523a20436f727275707465642073746174652061742000000000000068e110000f0000000000000078e1100002000000000000000000000088e1100004000000000000004e65774163636f756e74496e646578007e5811000900000023e210000c000000a8e1100022000000449c110000000000cae11000410000000be21000180000002041206e6577206163636f756e7420696e646578207761732061737369676e65642e2054686973206576656e74206973206e6f7420747269676765726564207768656e20616e206578697374696e6720696e64657820697320726561737369676e656420746f20616e6f7468657220604163636f756e744964602e4163636f756e74496e6465780050e210001900000070e2100048000000bb0100002d0000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f6f70732f61726974682e7273c8e2100058000000a1000000010000002f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f626162652f7372632f6c69622e727374696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c00000064e310005b0000004a000000010000002f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f696e64696365732f7372632f6c69622e7273496e76616c69642072616e676520666f7220746869732061756374696f6e72616e676520656e6473206265666f726520697420626567696e7372616e676520626567696e7320746f6f206561726c7972616e676520626567696e7320746f6f206c61746572616e676520656e647320746f6f206c61746500000000000064e4100007000000000000006ce4100003000000000000000000000084e410000100000000000000436c61696d6564007e58110009000000a7e410000f00000087581100070000008ce410001b00000020536f6d656f6e6520636c61696d656420736f6d6520444f54732e457468657265756d416464726573734469676573744974656d206e6f7420657175616c000000000000e4e710000a0000000000000000000000eee710000300000000000000000000000000000000000000000000000000000000000000449c110060e810000000000000000000f4e7100001000000000000000100000000000000fce710000b000000000000000000000007e810002700000000000000000000000000000000000000000000000000000000000000449c110000f21000000000000000000030e810000100000000000000010000000000000038e810000b0000000000000000000000eee710000300000000000000000000000000000000000000000000000000000000000000449c110060e81000000000000000000044e810000200000000000000010000000000000054e810000b0000000000000000000000eee710000300000000000000000000000000000000000000000000000000000000000000449c110060e81000000000000000000070e810000100000000000000010000000000000078e810000a000000000000000000000082e810000800000000000000000000000000000000000000000000000000000000000000449c1100ece8100000000000000000008ce810000a000000000000000100000000000000dce810000e000000000000000000000082e810000800000000000000000000000000000000000000000000000000000000000000449c1100ece810000000000000000000fce810000100000000000000010000000000000004e910000c0000000000000000000000a67b11000300000000000000000000000000000000000000000000000000000000000000449c1100e8f11000000000000000000010e910000900000000000000010000000000000058e91000110000000101000000000000a67b1100030000000000000069e910000d00000000000000000000000000000000000000449c110078e910000000000000000000449c11000000000000000000010000000000000088e910000b000000000000000000000093e910000800000000000000000000000000000000000000000000000000000000000000449c11009ce910000000000000000000ace9100002000000000000000000000045706f6368496e646578753634000000f7ed100015000000417574686f7269746965735665633c28417574686f7269747949642c2042616265417574686f72697479576569676874293e0000dced10001b00000047656e65736973536c6f74007aed10003e000000b8ed10002400000043757272656e74536c6f74001800000000000000010000003e00000065ed10001500000052616e646f6d6e6573735b75383b2033325d00009feb10002e000000449c110000000000cdeb10000b000000449c110000000000d8eb10004100000019ec10003e00000057ec1000450000009cec100045000000e1ec10004100000022ed1000430000004e65787452616e646f6d6e65737300001800000000000000010000005000000088eb1000170000005365676d656e74496e64657843ea10001f000000449c11000000000062ea10003d0000009fea100040000000dfea100025000000449c11000000000004eb10003b0000003feb10004200000081eb100007000000556e646572436f6e737472756374696f6e5665633c5b75383b2033325d3e00001800000000000000010000002e000000496e697469616c697a65644d61796265567266001800000000000000010000002b000000bce9100040000000fce91000470000002054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d6560206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e205765206d616b6520612074726164656f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e2057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f2060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e20576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572792065706f63682e204e6578742065706f63682072616e646f6d6e6573732e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2043757272656e7420736c6f74206e756d6265722e2054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e2054686973206973203020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e000000007cee10000d00000000000000eee710000300000000000000449c11008cee100000000000000000009cee1000020000000000000000000000acee10001100000000000000754b11000900000000000000449c1100c0ee10000000000000000000d0ee1000050000000000000045706f63684475726174696f6e0000001800000000000000010000005100000028f01000430000006bf010003f0000004578706563746564426c6f636b54696d6500000018000000000000000100000052000000f8ee10004100000039ef1000440000007def100041000000beef10004200000000f010002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e20546865206e756d626572206f66202a2a736c6f74732a2a207468617420616e2065706f63682074616b65732e20576520636f75706c652073657373696f6e7320746f2065706f6368732c20692e652e2077652073746172742061206e65772073657373696f6e206f6e636520746865206e65772065706f636820626567696e732e4e657874456e756d536574456e756d536574636c61696d7319457468657265756d205369676e6564204d6573736167653a0a65706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b2071656400000000000000aaf010000b0000000000000000000000d8f110000f00000000000000000000000000000000000000000000000000000000000000449c1100e8f110000000000000000000f8f1100001000000000000000100000000000000b5f01000070000000101000000000000d8f110000f00000000000000b06411001100000000000000000000000000000000000000449c110000f21000000000000000000010f21000010000000000000001000000543a3a4163636f756e74496e64657800180000000000000001000000300000002ef210001f0000001800000000000000010000002e00000018f21000160000002054686520656e756d65726174696f6e20736574732e20546865206e657874206672656520656e756d65726174696f6e207365742e70617261000000000000007c3e1100060000000101000000000000a7e410000f00000000000000c47d11000c00000000000000000000000000000000000000449c110004f310000000000000000000449c11000000000000000000000000000000000014f31000050000000000000000000000c47d11000c00000000000000000000000000000000000000000000000000000000000000449c11001cf310000000000000000000449c11000000000000000000010000001800000000000000010000002b000000546f74616c00000018000000000000000100000047000000bbf310003f0000007900000001000000496e76616c696420457468657265756d207369676e6174757265457468657265756d206164647265737320686173206e6f20636c61696d008cf310002f000000bbf310003f0000008e000000050000004c6f676963206572726f723a20506f74206c657373207468616e2074686520746f74616c206f6620636c61696d73212f686f6d652f766f6c742f776f726b7370616365732f706172697479746563682f706f6c6b61646f742f72756e74696d652f7372632f636c61696d732e727300000000000054f4100005000000000000005cf410000200000000000000000000008cf4100001000000000000000000000094f410000a00000000000000a0f41000020000000000000000000000d0f410000100000000000000636c61696d00000000000000a72111000400000000000000676411000c0000000000000008f5100012000000000000001af510000e000000faf410000e0000006d696e745f636c61696d000000000000864a11000300000000000000a7e410000f000000000000004d6f11000500000000000000c47d11000c000000d8f4100022000000204164642061206e657720636c61696d2c20696620796f752061726520726f6f742e204d616b65206120636c61696d2e657468657265756d5f7369676e617475726545636473615369676e61747572650000000060f51000060000000000000066f510000500000000000000449c11006cf5100000000000000000007cf510000100000000000000507265666978265b75385d001800000000000000010000005300000084f510004500000020546865205072656669782074686174206973207573656420696e207369676e656420457468657265756d206d6573736167657320666f722074686973206e6574776f726b00000000000000d4f610000800000000000000dcf61000040000000000000000000000fcf610000200000000000000000000000cf71000050000000000000014f710000500000000000000000000003cf710000200000000000000000000004cf71000080000000000000054f710000100000000000000000000005cf7100001000000000000000000000064f710000b0000000000000054f7100001000000000000000000000070f7100001000000000000000000000078f71000080000000000000080f7100002000000000000000000000090f7100001000000000000000000000098f710000e0000000000000080f71000020000000000000000000000a8f71000010000000000000050726f706f7365647e5811000900000098f910000d000000b8971100040000002af910000b00000035f910005300000088f9100010000000566f7465640000007e58110009000000b897110004000000e8971100040000002af910000b0000002af910000b000000a2f8100042000000e4f8100046000000417070726f766564b89711000400000071f8100031000000446973617070726f766564003cf81000350000004578656375746564b897110004000000e897110004000000fbf71000410000004d656d62657245786563757465640000b0f710004b00000020412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e4d656d626572436f756e742041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20604d656d626572436f756e7460292e50726f706f73616c496e64657863616e2774207377617020616e20756e6465706c6f7965642070617261636861696e4f6e626f617264696e670000000000000008fb10000e0000000000000018fb100001000000000000000000000020fb100001000000000000000000000028fb10000e0000000000000038fb100003000000000000000000000050fb100002000000000000000000000060fb10000d0000000000000070fb100001000000000000000000000078fb100001000000000000000000000080fb100009000000000000008cfb1000040000000000000000000000acfb1000010000000000000000000000b4fb10000a00000000000000c0fb1000040000000000000000000000e0fb1000020000000000000000000000f0fb10000800000000000000f8fb100003000000000000000000000010fc100002000000000000000000000020fc10000a00000000000000845711000200000000000000000000002cfc100001000000000000004e65774c65617365506572696f640000a1fe10000b000000b7fe10002100000041756374696f6e537461727465640000fcfd10000c000000a1fe10000b000000acfe10000b00000008fe1000530000005bfe10004600000041756374696f6e436c6f736564000000fcfd10000c000000cdfd10002f000000576f6e4465706c6f79000000b9fd1000140000005bfd10000900000055fd100006000000875811000700000064fd100055000000576f6e52656e6577616c000055fd1000060000005bfd10000900000087581100070000008758110007000000d4fc10003100000005fd10005000000052657365727665647e58110009000000875811000700000087581100070000006cfc100053000000bffc100015000000556e7265736572766564000034fc1000380000002046756e6473207765726520756e72657365727665642073696e636520626964646572206973206e6f206c6f6e676572206163746976652e2046756e6473207765726520726573657276656420666f7220612077696e6e696e67206269642e2046697273742062616c616e63652069732074686520657874726120616d6f756e742072657365727665642e205365636f6e642069732074686520746f74616c2e20416e206578697374696e672070617261636861696e20776f6e2074686520726967687420746f20636f6e74696e75652e2046697273742062616c616e63652069732074686520657874726120616d6f756e7420726573657665642e205365636f6e642069732074686520746f74616c20616d6f756e742072657365727665642e506172614964536c6f7452616e676520536f6d656f6e6520776f6e2074686520726967687420746f206465706c6f7920612070617261636861696e2e2042616c616e636520616d6f756e7420697320646564756374656420666f72206465706f7369742e4e65774269646465723c4163636f756e7449643e20416e2061756374696f6e20656e6465642e20416c6c2066756e6473206265636f6d6520756e72657365727665642e41756374696f6e496e64657820416e2061756374696f6e20737461727465642e2050726f76696465732069747320696e64657820616e642074686520626c6f636b206e756d6265722077686572652069742077696c6c20626567696e20746f20636c6f736520616e6420746865206669727374206c6561736520706572696f64206f662074686520717561647275706c657420746861742069732061756374696f6e65642e4c65617365506572696f64426c6f636b4e756d6265722041206e6577206c6561736520706572696f6420697320626567696e6e696e672e41756374696f6e496e666f57696e6e696e670000380000000800000004000000540000006069203c2034603b20606a203c2069603b20606a202b2031203c2034603b2071656441756374696f6e436f756e7465724d616e616765644964730000020000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000001000000020000004f6e626f61726451756575654f6666626f617264696e6700030000000300000000000000000000000000000000000000000000000000000000000000010000000200000003000000010000000200000003000000020000004465706f736974732e00110029000000f0ff10003e0000004e020000080000002f686f6d652f766f6c742f776f726b7370616365732f706172697479746563682f706f6c6b61646f742f72756e74696d652f7372632f736c6f74732e72736561726c69657220726573697a65206d65616e73206974206d757374206265203e3d20693b207165645265736572766564416d6f756e7473496e7374616e636532436f6c6c65637469766550726f706f73616c73566f74696e67496e7374616e636531436f6c6c65637469766500000000004c0111000b00000000000000580111000100000000000000000000007001110004000000000000000000000090011100070000000000000098011100010000000000000000000000b0011100030000000000000000000000c80111000700000000000000d001110002000000000000000000000000021100040000000000000000000000200211000400000000000000240211000300000000000000000000006c02110004000000000000007365745f6d656d626572730000000000ab0411000b00000000000000b0641100110000002a041100540000007e04110017000000449c1100000000009504110016000000657865637574650000000000040311000800000000000000a40311001e000000c20311003d000000449c110000000000ff0311002b00000070726f706f73650000000000870311000900000000000000900311001400000000000000040311000800000000000000a40311001e0000007e6311000b0000003503110024000000590311002e0000009e6311000c000000766f7465000000000403110008000000000000000c03110007000000000000001303110005000000000000001803110016000000000000002e0311000700000000000000e8971100040000007e6311000b0000008c02110023000000af021100550000009e6311000c000000202d20426f756e6465642073746f72616765207265616420616e64207772697465732e202d2057696c6c20626520736c696768746c792068656176696572206966207468652070726f706f73616c20697320617070726f766564202f20646973617070726f7665642061667465722074686520766f74652e70726f706f73616c543a3a48617368696e646578436f6d706163743c50726f706f73616c496e6465783e617070726f7665202d20426f756e6465642073746f7261676520726561647320616e64207772697465732e202d20417267756d656e7420607468726573686f6c6460206861732062656172696e67206f6e207765696768742e7468726573686f6c64436f6d706163743c4d656d626572436f756e743e426f783c3c542061732054726169743c493e3e3a3a50726f706f73616c3e20446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e204f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e205365742074686520636f6c6c6563746976652773206d656d62657273686970206d616e75616c6c7920746f20606e65775f6d656d62657273602e204265206e69636520746f2074686520636861696e20616e642070726f76696465206974207072652d736f727465642e20526571756972657320726f6f74206f726967696e2e6e65775f6d656d626572730000e80511002400000050726f706f73616c4f663c542061732054726169743c493e3e3a3a50726f706f73616c00b505110033000000566f7465733c543a3a4163636f756e7449643e00880511002d00000050726f706f73616c436f756e740000007605110012000000280511004e000000205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e2050726f706f73616c7320736f206661722e20566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e2054686520686173686573206f6620746865206163746976652070726f706f73616c732e00000000790011000900000000000000000000003c9511000c00000000000000000000000000000000000000000000000000000000000000449c1100c80d11000000000000000000b804110001000000000000000100000000000000c00411000a00000001010000000000000c0311000700000000000000ca0411001900000000000000000000000000000000000000449c1100c40711000000000000000000e404110001000000000000000000000000000000820011000600000001010000000000000c0311000700000000000000ec0411001300000000000000000000000000000000000000449c1100c407110000000000000000000005110001000000000000000000000000000000080511000d0000000000000000000000a67b11000300000000000000000000000000000000000000000000000000000000000000449c1100400c11000000000000000000180511000100000000000000010000000000000003301100070000000000000000000000b06411001100000000000000000000000000000000000000000000000000000000000000449c1100c80d11000000000000000000200511000100000000000000010000001800000000000000010000002b000000c80811005e000000820000000100000070726f706f736572206e6f742061206d656d6265726475706c69636174652070726f706f73616c73206e6f7420616c6c6f77656470726f706f73616c206d7573742065786973746d69736d61746368656420696e6465786475706c696361746520766f74652069676e6f7265640000008008110048000000a20a00000e000000766f746572206e6f742061206d656d626572000000000000000000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f6d6f642e72732f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f636f6c6c6563746976652f7372632f6c69622e72730000000000001eff10000e0000000000000000000000fcfd10000c00000000000000000000000000000000000000000000000000000000000000449c1100400c11000000000000000000500c1100010000000000000001000000000000002cff10000a0000000000000000000000580c11000b00000000000000000000000000000000000000000000000000000000000000449c1100c80d11000000000000000000640c110002000000000000000100000000000000d0ff100008000000010100000000000055fd10000600000000000000740c11001100000000000000000000000000000000000000449c1100c80d11000000000000000000880c11000d000000000000000100000000000000d8fe10000b0000000000000000000000f00c11002200000000000000000000000000000000000000000000000000000000000000449c1100140d11000000000000000000240d110005000000000000000000000000000000e3fe1000070000000101000000000000069411000e000000000000004c0d11000e00000000000000000000000000000000000000449c11005c0d110000000000000000006c0d110003000000000000000000000000000000570011000f0000000101000000000000840d11001400000000000000c47d11000c00000000000000000000000000000000000000449c1100980d11000000000000000000a80d11000200000000000000000000000000000078ff10000c0000000101000000000000b80d11001000000000000000580c11000b00000000000000000000000000000000000000449c1100c80d11000000000000000000d80d110002000000000000000100000000000000c7f910000a000000010100000000000055fd10000600000000000000e80d11003c00000000000000000000000000000000000000449c1100240e11000000000000000000340e11000400000000000000000000000000000084ff10000b000000010100000000000055fd10000600000000000000676411000c00000000000000000000000000000000000000449c1100540e11000000000000000000640e110002000000000000000100000018000000000000000100000030000000ab161100310000005665633c5061726149643e000e16110053000000611611004a0000005665633c42616c616e63654f663c543e3e00000043131100570000009a13110014000000449c110000000000ae1311005900000007141100540000005b1411002c000000449c1100000000008714110058000000df1411002d000000449c1100000000000c151100540000006015110057000000b715110057000000284c65617365506572696f644f663c543e2c20543a3a426c6f636b4e756d6265722900001800000000000000010000003d000000091211003e000000449c11000000000047121100510000009812110054000000ec1211005700000057696e6e696e67446174613c543e00001800000000000000010000005500000017111100570000006e11110054000000c2111100470000004269646465723c543a3a4163636f756e7449643e1800000000000000010000002b000000bd1011004c000000091111000e0000004c65617365506572696f644f663c543e1800000000000000010000002e0000002810110059000000811011003c000000284c65617365506572696f644f663c543e2c20496e636f6d696e6750617261636861696e3c543a3a4163636f756e7449642c20543a3a486173683e29180000000000000001000000560000001b0f1100530000006e0f110049000000b70f1100560000000d1011001b00000018000000000000000100000043000000740e110059000000cd0e11004e000000204f66662d626f617264696e67206163636f756e743b2063757272656e63792068656c64206f6e206465706f73697420666f72207468652070617261636861696e206765747320706c616365642068657265206966207468652070617261636861696e2067657473206f66662d626f61726465643b20692e652e20697473206c6561736520706572696f6420697320757020616e642069742069736e27742072656e657765642e205468652061637475616c206f6e2d626f617264696e6720696e666f726d6174696f6e2e204f6e6c7920657869737473207768656e206f6e65206f662074686520666f6c6c6f77696e6720697320747275653a202d204974206973206265666f726520746865206c6561736520706572696f642074686174207468652070617261636861696e2073686f756c64206265206f6e2d626f61726465642e202d205468652066756c6c206f6e2d626f617264696e6720696e666f726d6174696f6e20686173206e6f7420796574206265656e2070726f766964656420616e64207468652070617261636861696e206973206e6f74207965742064756520746f206265206f66662d626f61726465642e2054686520736574206f662050617261204944732074686174206861766520776f6e20616e64206e65656420746f206265206f6e2d626f617264656420617420616e207570636f6d696e67206c656173652d706572696f642e205468697320697320636c6561726564206f7574206f6e2074686520666972737420626c6f636b206f6620746865206c6561736520706572696f642e20416d6f756e74732063757272656e746c7920726573657276656420696e20746865206163636f756e7473206f662074686520626964646572732063757272656e746c792077696e6e696e6720287375622d2972616e6765732e205468652077696e6e696e67206269647320666f722065616368206f66207468652031302072616e676573206174206561636820626c6f636b20696e207468652066696e616c20456e64696e6720506572696f64206f66207468652063757272656e742061756374696f6e2e20546865206d61702773206b65792069732074686520302d626173656420696e64657820696e746f2074686520456e64696e6720506572696f642e2054686520666972737420626c6f636b206f662074686520656e64696e6720706572696f6420697320303b20746865206c6173742069732060456e64696e67506572696f64202d2031602e20496e666f726d6174696f6e2072656c6174696e6720746f207468652063757272656e742061756374696f6e2c206966207468657265206973206f6e652e20546865206669727374206974656d20696e20746865207475706c6520697320746865206c6561736520706572696f6420696e646578207468617420746865206669727374206f662074686520666f757220636f6e746967756f7573206c6561736520706572696f6473206f6e2061756374696f6e20697320666f722e20546865207365636f6e642069732074686520626c6f636b206e756d626572207768656e207468652061756374696f6e2077696c6c2022626567696e20746f20656e64222c20692e652e2074686520666972737420626c6f636b206f662074686520456e64696e6720506572696f64206f66207468652061756374696f6e2e20566172696f757320616d6f756e7473206f6e206465706f73697420666f7220656163682070617261636861696e2e20416e20656e74727920696e20604d616e616765644964736020696d706c6965732061206e6f6e2d2064656661756c7420656e74727920686572652e205468652061637475616c20616d6f756e74206c6f636b6564206f6e2069747320626568616c6620617420616e792074696d6520697320746865206d6178696d756d206974656d20696e2074686973206c6973742e20546865206669727374206974656d20696e20746865206c6973742069732074686520616d6f756e74206c6f636b656420666f72207468652063757272656e74204c6561736520506572696f642e20466f6c6c6f77696e67206974656d732061726520666f72207468652073756273657175656e74206c6561736520706572696f64732e205468652064656661756c742076616c75652028616e20656d707479206c6973742920696d706c6965732074686174207468652070617261636861696e206e6f206c6f6e6765722065786973747320286f72206e65766572206578697374656429206173206661722061732074686973206d6f64756c6520697320636f6e6365726e65642e20496620612070617261636861696e20646f65736e2774206578697374202a7965742a20627574206973207363686564756c656420746f20657869737420696e20746865206675747572652c207468656e2069742077696c6c206265206c6566742d7061646465642077697468206f6e65206f72206d6f7265207a65726f657320746f2064656e6f74652074686520666163742074686174206e6f7468696e672069732068656c64206f6e206465706f73697420666f7220746865206e6f6e2d6578697374656e7420636861696e2063757272656e746c792c206275742069732068656c6420617420736f6d6520706f696e7420696e20746865206675747572652e204f726465726564206c697374206f6620616c6c2060506172614964602076616c756573207468617420617265206d616e616765642062792074686973206d6f64756c652e205468697320696e636c7564657320636861696e73207468617420617265206e6f7420796574206465706c6f7965642028627574206861766520776f6e20616e2061756374696f6e20696e2074686520667574757265292e20546865206e756d626572206f662061756374696f6e732074686174206265656e207374617274656420736f206661722ef0ff10003e000000e3000000010000006163636f756e74206973206e6f7420612070617261636861696e6e6f7420612070617261636861696e206f726967696e70617261636861696e206964206e6f7420696e206f6e626f617264696e67616c7265616479207265676973746572656470617261636861696e206e6f742072656769737465726564206279206f726967696e6465706c6f792064617461206e6f7420796574206669786564636f6465206e6f7420646f65736e277420636f72726573706f6e6420746f206861736861756374696f6e20616c726561647920696e2070726f67726573736c6561736520706572696f6420696e20706173746e6f7420616e2061756374696f6e6e6f742063757272656e742061756374696f6e6269646465722077696e6e696e67206e6f6e2d696e74657273656374696e672072616e67652829000000000000002c1911000b000000000000003819110002000000000000000000000068191100050000000000000000000000901911000300000000000000941911000500000000000000000000000c1a11001000000000000000000000008c1a11000900000000000000981a1100040000000000000000000000f81a11000f0000000000000000000000701b11000f00000000000000801b1100010000000000000000000000981b1100050000000000000000000000c01b11000f00000000000000d01b1100040000000000000000000000301c1100070000000000000000000000681c11001500000000000000801c1100020000000000000000000000b01c11000c000000000000006e65775f61756374696f6e0000000000b32611000800000000000000749311001700000000000000bb2611001200000000000000ae24110019000000a725110016000000449c110000000000bd25110055000000122611004a0000005c261100570000006269640000000000d82011000300000000000000db2011000e00000000000000822411000d000000000000008f2411001500000000000000a42411000a00000000000000ae2411001900000000000000c72411000900000000000000ae2411001900000000000000d02411000600000000000000526f110015000000d624110053000000292511000b000000449c110000000000ff211100570000005622110050000000449c11000000000034251100560000008a2511001d000000a622110054000000fa2211001b00000015231100530000006823110043000000ab231100510000006823110043000000fc231100530000004f241100330000006269645f72656e657700000000000000822411000d000000000000008f2411001500000000000000a42411000a00000000000000ae2411001900000000000000c72411000900000000000000ae2411001900000000000000d02411000600000000000000526f110015000000ab21110054000000449c110000000000352111002a000000449c110000000000ff211100570000005622110050000000449c110000000000a622110054000000fa2211001b00000015231100530000006823110043000000ab231100510000006823110043000000fc231100530000004f241100330000007365745f6f6666626f617264696e670000000000a72111000400000000000000f3661100230000000321110032000000449c110000000000352111002a000000449c1100000000005f211100480000006669785f6465706c6f795f646174610000000000d82011000300000000000000db2011000e00000000000000521f11000700000000000000591f11000f00000000000000e920110009000000000000000c0311000700000000000000f22011001100000000000000dc431100070000006c1f11004b000000449c110000000000b71f110032000000e91f11002c000000152011004000000055201100470000009c2011003c000000656c61626f726174655f6465706c6f795f6461746100000000000000521f11000700000000000000591f11000f00000000000000681f11000400000000000000dc43110007000000101d11001d000000449c1100000000002d1d110053000000801d110031000000449c110000000000b11d110058000000091e1100510000005a1e110059000000449c110000000000b31e11001b000000ce1e11003f0000000d1f110045000000204e6f74652061206e65772070617261636861696e277320636f64652e2054686973206d7573742062652063616c6c656420616674657220606669785f6465706c6f795f646174616020616e642060636f646560206d7573742062652074686520707265696d616765206f66207468652060636f64655f68617368602070617373656420746865726520666f72207468652073616d652060706172615f6964602e2054686973206d61792062652063616c6c6564206265666f7265206f722061667465722074686520626567696e6e696e67206f66207468652070617261636861696e2773206669727374206c6561736520706572696f642e2049662063616c6c6564206265666f7265207468656e207468652070617261636861696e2077696c6c206265636f6d65206163746976652061742074686520666972737420626c6f636b206f6620697473207374617274696e67206c6561736520706572696f642e2049662061667465722c207468656e2069742077696c6c206265636f6d652061637469766520696d6d6564696174656c7920616674657220746869732063616c6c2e202d20605f6f726967696e6020697320697272656c6576616e742e202d2060706172615f696460206973207468652070617261636861696e2049442077686f736520636f64652077696c6c20626520656c61626f72617465642e202d2060636f6465602069732074686520707265696d616765206f662074686520726567697374657265642060636f64655f6861736860206f662060706172615f6964602e706172615f6964436f6d706163743c5061726149643e636f64652053657420746865206465706c6f7920696e666f726d6174696f6e20666f722061207375636365737366756c2062696420746f206465706c6f792061206e65772070617261636861696e2e202d20606f726967696e60206d75737420626520746865207375636365737366756c20626964646572206163636f756e742e202d20607375626020697320746865207375622d626964646572204944206f6620746865206269646465722e202d2060706172615f696460206973207468652070617261636861696e20494420616c6c6f7474656420746f207468652077696e6e696e67206269646465722e202d2060636f64655f6861736860206973207468652068617368206f66207468652070617261636861696e2773205761736d2076616c69646174696f6e2066756e6374696f6e2e202d2060696e697469616c5f686561645f6461746160206973207468652070617261636861696e277320696e697469616c206865616420646174612e737562436f6d706163743c53756249643e636f64655f68617368696e697469616c5f686561645f646174612053657420746865206f66662d626f617264696e6720696e666f726d6174696f6e20666f7220612070617261636861696e2e20546865206f726967696e202a6d7573742a20626520612070617261636861696e206163636f756e742e202d20606465737460206973207468652064657374696e6174696f6e206163636f756e7420746f2072656365697665207468652070617261636861696e2773206465706f7369742e64657374204d616b652061206e6577206269642066726f6d20612070617261636861696e206163636f756e7420666f722072656e6577696e67207468617420287072652d6578697374696e67292070617261636861696e2e204d756c7469706c652073696d756c74616e656f757320626964732066726f6d207468652073616d65206269646465722061726520616c6c6f776564206f6e6c79206173206c6f6e6720617320616c6c206163746976652062696473206f7665726c61702065616368206f746865722028692e652e20617265206d757475616c6c79206578636c7573697665292e20426964732063616e6e6f742062652072656461637465642e202d206061756374696f6e5f696e646578602069732074686520696e646578206f66207468652061756374696f6e20746f20626964206f6e2e2053686f756c64206a757374206265207468652070726573656e742076616c7565206f66206041756374696f6e436f756e746572602e202d206066697273745f736c6f746020697320746865206669727374206c6561736520706572696f6420696e646578206f66207468652072616e676520746f20626964206f6e2e205468697320697320746865206162736f6c757465206c6561736520706572696f6420696e6465782076616c75652c206e6f7420616e2061756374696f6e2d7370656369666963206f66667365742e202d20606c6173745f736c6f746020697320746865206c617374206c6561736520706572696f6420696e646578206f66207468652072616e676520746f20626964206f6e2e205468697320697320746865202d2060616d6f756e74602069732074686520616d6f756e7420746f2062696420746f2062652068656c64206173206465706f73697420666f72207468652070617261636861696e2073686f756c6420746865206269642077696e2e205468697320616d6f756e742069732068656c64207468726f7567686f7574207468652072616e67652e61756374696f6e5f696e646578436f6d706163743c41756374696f6e496e6465783e66697273745f736c6f74436f6d706163743c4c65617365506572696f644f663c543e3e6c6173745f736c6f74616d6f756e74204d616b652061206e6577206269642066726f6d20616e206163636f756e742028696e636c7564696e6720612070617261636861696e206163636f756e742920666f72206465706c6f79696e672061206e65772070617261636861696e2e202d20607375626020697320746865207375622d6269646465722049442c20616c6c6f77696e6720666f72206d756c7469706c6520636f6d706574696e67206269647320746f206265206d6164652062792028616e642066756e64656420627929207468652073616d65206163636f756e742e204372656174652061206e65772061756374696f6e2e20546869732063616e206f6e6c792068617070656e207768656e2074686572652069736e277420616c726561647920616e2061756374696f6e20696e2070726f677265737320616e64206d6179206f6e6c792062652063616c6c65642062792074686520726f6f74206f726967696e2e20416363657074732074686520606475726174696f6e60206f6620746869732061756374696f6e20616e642074686520606c656173655f706572696f645f696e64657860206f662074686520696e697469616c206c6561736520706572696f64206f662074686520666f757220746861742061726520746f2062652061756374696f6e65642e6475726174696f6e6c656173655f706572696f645f696e646578000000e82611002b000000132711005d0000009e0000000400000054696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b2f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f74696d657374616d702f7372632f6c69622e72734e6f77003800000008000000040000005400000054696d657374616d7020746f6f2066617220696e2066757475726520746f206163636570744765747320616e64206465636f6465732074696d657374616d7020696e686572656e7420646174616b7573616d617061726974792d6b7573616d61df6acb689907609b0200000037e397fc7c91f5e40100000040fe3ad401f8959a04000000d2bc9897eed08f1501000000f78b278be53f454c01000000af2c0297a23e6d3d01000000ed99c5acb25eedf502000000cbca25e39f14238701000000687ad44ad37f03c201000000ab3c0572291feb8b01000000bc9d89904f5b923f0100000037c8bb1350a9a2a8010000006772616e62616265696d6f6e70617261617564690000000040787d010065cd1d00e1f505d85aae1ec0542205b0508f1f38e4750488467020d853e903603c5121d0bf760338323222a8591903402013236039cd02480ef423a82a8f0268f8d42470955c02b8dab525c05a3302d8c4962648bd1102e0b27727a855f601e8a05828e8fedf0180773929c0cacd01586d1a2af8f1be019053fb2a50d8b201d00edc2be0fca80138edbc2c48f2a001e06d9d2d80669a01c80d7e2e500f9501c0575e2f08b6900140323f30e0278d0148202031b0418a0108a3ff3120e8870120bedf32f0fb85013856c03398698401f0fda03478218301b8d87f35d8178201d8c26036183d8101b8223e37508d800188d21c38c8fc7f0168b5f93898877f01a829d139d8297f0120d6ab3ab8db7e0168ae803b389d7e0100ca9a3b68957e01506179204b534d7320746f20746865204b7573616d61206163636f756e743a00ffffff1f122b110016000000282b110016000000882a110057000000a701000003000000df2a11002d0000000c2b1100030000000f2b110003000000010000000000000020000000000000000300000000000000030000000000000003000000010000000100000020000000080000000300000000000000000000000200000003000000010000000200000020000000000000000300000000000000030000000000000003000000882a110057000000b7010000030000002f686f6d652f766f6c742f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6269747665632d302e31352e322f7372632f706f696e7465722e727342697450747220726567696f6e2063616e6e6f7420777261702074686520616464726573732073706163653a20202b20203d204269745074722063616e6e6f7420616464726573732020626974733b20746865206d6178696d756d206973200000000000001c2c11000700000000000000242c11000100000000000000000000002c2c1100010000000000000000000000342c11000a00000000000000242c1100010000000000000000000000402c1100010000000000000000000000482c11000b00000000000000242c1100010000000000000000000000542c11000100000000000000000000005c2c11000b0000000000000084571100020000000000000000000000682c1100010000000000000000000000702c11000a00000000000000845711000200000000000000000000007c2c110001000000000000004e616d65536574007e58110009000000172d1100100000004e616d65466f726365640000fe2c1100190000004e616d654368616e67656400ea2c1100140000004e616d65436c656172656400b62c1100340000004e616d654b696c6c65640000842c1100320000002041206e616d65207761732072656d6f76656420616e642074686520676976656e2062616c616e636520736c61736865642e2041206e616d652077617320636c65617265642c20616e642074686520676976656e2062616c616e63652072657475726e65642e2041206e616d6520776173206368616e6765642e2041206e616d652077617320666f726369626c79207365742e2041206e616d6520776173207365742e0000000000042e11000b00000000000000449c1100000000000000000000000000102e1100010000000000000000000000182e11000d00000000000000449c1100000000000000000000000000282e1100010000000000000000000000302e11000e00000000000000449c1100000000000000000000000000402e1100010000000000000000000000482e11000c00000000000000449c1100000000000000000000000000542e11000100000000000000000000005c2e11000500000000000000642e11000100000000000000000000006c2e110001000000000000004d656d626572416464656400752f1100390000004d656d62657252656d6f7665640000003a2f11003b0000004d656d62657273537761707065640000032f1100370000004d656d626572735265736574bd2e11004600000044756d6d79000000902e11002d000000742e11001c000000205068616e746f6d206d656d6265722c206e6576657220757365642e727374643a3a6d61726b65723a3a5068616e746f6d446174613c284163636f756e7449642c204576656e74293e20546865206d656d62657273686970207761732072657365743b2073656520746865207472616e73616374696f6e20666f722077686f20746865206e6577207365742069732e2054776f206d656d62657273207765726520737761707065643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732072656d6f7665643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732061646465643b2073656520746865207472616e73616374696f6e20666f722077686f2e0000c431110030000000132711005d0000009200000004000000763111004e000000132711005d0000009300000004000000183111005e0000005e00000001000000496e7374616e6365314d656d626572736869704d656d62657273616c72656164792061206d656d6265726e6f742061206d656d6265720000d030110048000000a20a00000e000000763011005900000064000000010000004e616d6520746f6f2073686f72744e616d6520746f6f206c6f6e675375646f4e616d654f664e6f74206e616d65642f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f6e69636b732f7372632f6c69622e7273002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f6d6f642e72732f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f6d656d626572736869702f7372632f6c69622e727354696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b7354696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b00000000c43d11000600000000000000570000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000590000000000000000000000000000005a0000000000000000000000000000005b000000000000000000000000000000d88c110018000000000000005c0000000000000000000000000000000000000000000000000000000200000000000000000000000000000002000000000000000000000000000000000000005a0000000000000000000000000000005a000000000000000000000000000000ca3d110004000000000000005d000000000000000000000000000000000000000000000000000000000000005a000000000000000000000002000000000000000000000000000000000000005e0000000000000000000000000000005a000000000000000000000000000000be8c110009000000000000005f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000200000000000000000000000000000000000000610000000000000000000000000000005a000000000000000000000000000000ce3d1100070000000000000062000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000630000000000000000000000000000005a0000000000000000000000000000005a000000000000000000000000000000d53d1100080000000000000064000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000066000000000000000000000000000000670000000000000000000000000000005a000000000000000000000000000000dd3d1100120000000000000068000000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000000000000000000000000000000690000000000000000000000000000005a000000000000000000000000000000a65111000a000000000000006a000000000000000000000000000000000000000000000000000000000000006b000000000000000000000002000000000000000000000000000000000000005a0000000000000000000000000000005a0000000000000000000000000000004656110007000000000000006c000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000006e0000000000000000000000000000006f0000000000000000000000000000005a000000000000000000000000000000ef3d1100080000000000000070000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000710000000000000000000000000000005a0000000000000000000000000000005a000000000000000000000000000000f73d1100070000000000000072000000000000000000000000000000000000000000000000000000000000007300000000000000000000000000000074000000000000000000000000000000750000000000000000000000000000005a000000000000000000000000000000fe3d11000f0000000200000000000000000000000000000000000000000000000000000000000000000000007600000000000000000000000200000000000000000000000000000000000000770000000000000000000000000000005a0000000000000000000000000000000d3e110007000000000000007800000000000000000000000000000000000000000000000000000000000000790000000000000000000000000000007a0000000000000000000000000000005a0000000000000000000000000000005a000000000000000000000000000000143e110008000000000000007b000000000000000000000000000000000000000000000000000000000000007c0000000000000000000000000000007d0000000000000000000000000000005a0000000000000000000000000000005a0000000000000000000000000000001c3e1100120000000200000000000000000000000000000000000000000000000000000000000000000000005a000000000000000000000002000000000000000000000000000000000000005a0000000000000000000000000000005a0000000000000000000000000000002e3e110009000000000000007e000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000080000000000000000000000000000000810000000000000000000000000000005a000000000000000000000000000000373e11000700000000000000820000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000840000000000000000000000000000005a0000000000000000000000000000005a0000000000000000000000000000003e3e11001200000000000000850000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000840000000000000000000000000000005a0000000000000000000000000000005a000000000000000000000000000000503e1100110000000000000086000000000000000000000000000000000000000000000000000000000000008700000000000000000000000000000088000000000000000000000000000000890000000000000000000000000000005a000000000000000000000000000000613e110013000000000000008a000000000000000000000000000000000000000000000000000000000000008b0000000000000000000000000000008c0000000000000000000000000000005a0000000000000000000000000000005a000000000000000000000000000000743e110008000000000000008d000000000000000000000000000000000000000000000000000000000000008e0000000000000000000000000000008f000000000000000000000000000000900000000000000000000000000000005a0000000000000000000000000000007c3e1100060000000000000091000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000093000000000000000000000000000000940000000000000000000000000000005a000000000000000000000000000000823e11000a00000000000000950000000000000000000000000000000000000000000000000000000000000096000000000000000000000002000000000000000000000000000000000000005a0000000000000000000000000000005a000000000000000000000000000000a78f11000c00000000000000970000000000000000000000000000000000000000000000000000000000000098000000000000000000000002000000000000000000000000000000000000005a0000000000000000000000000000005a0000000000000000000000000000008c3e1100050000000000000099000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000009b0000000000000000000000000000005a0000000000000000000000000000005a000000000000000000000000000000913e110009000000000000009c000000000000000000000000000000000000000000000000000000000000009d0000000000000000000000000000009e0000000000000000000000000000005a0000000000000000000000000000005a0000000000000000000000000000006330110004000000000000009f00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000a10000000000000000000000000000005a0000000000000000000000000000005a0000000000000000000000000000009a3e11000500000000000000a200000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000a4000000000000000000000000000000a50000000000000000000000000000005a000000000000000000000053797374656d42616265496e646963657342616c616e6365735472616e73616374696f6e5061796d656e744f6666656e63657353657373696f6e46696e616c697479547261636b65724772616e647061496d4f6e6c696e65417574686f72697479446973636f7665727944656d6f6372616379436f756e63696c546563686e6963616c436f6d6d6974746565456c656374696f6e7350687261676d656e546563686e6963616c4d656d626572736869705472656173757279436c61696d7350617261636861696e73536c6f74735265676973747261724e69636b730000000000483f11000e00000000000000c47d11000c00000000000000449c1100583f11000000000000000000683f1100010000000000000000000000703f11000900000000000000a67b11000300000000000000449c11007c3f110000000000000000008c3f1100010000000000000000000000943f11000900000000000000a67b11000300000000000000449c1100a03f11000000000000000000b03f110001000000000000005265736572766174696f6e466565000018000000000000000100000045000000fc3f1100110000004d696e4c656e677468000000180000000000000001000000a6000000da3f1100220000004d61784c656e677468000000180000000000000001000000a7000000b83f11002200000020546865206d6178696d756d206c656e6774682061206e616d65206d61792062652e20546865206d696e696d756d206c656e6774682061206e616d65206d61792062652e205265736572766174696f6e206665652e00000000000000c04011000800000000000000c8401100010000000000000000000000e0401100100000000000000000000000604111000a00000000000000449c11000000000000000000000000006c4111000a0000000000000000000000bc4111000900000000000000c8411100010000000000000000000000e04111000d0000000000000000000000484211000a0000000000000054421100020000000000000000000000844211000c000000000000007365745f6e616d6500000000d84311000400000000000000dc431100070000005945110057000000b045110013000000449c110000000000c345110058000000449c1100000000001b461100570000007246110010000000449c1100000000000c45110034000000449c1100000000007e6311000b0000008d701100080000008a43110021000000ab4311001a000000c54311000d0000009e6311000c000000636c6561725f6e616d650000b844110054000000449c1100000000000c45110034000000449c1100000000007e6311000b0000008d701100080000004045110019000000ab4311001a000000c54311000d0000009e6311000c0000006b696c6c5f6e616d6500000000000000d24311000600000000000000f366110023000000e343110039000000449c1100000000001c441100520000006e44110013000000449c1100000000003e4311004c000000449c1100000000007e6311000b0000008d701100080000008144110037000000ab4311001a000000c54311000d0000009e6311000c000000666f7263655f6e616d65000000000000d24311000600000000000000f36611002300000000000000d84311000400000000000000dc43110007000000e442110032000000449c1100000000001643110028000000449c1100000000003e4311004c000000449c1100000000007e6311000b0000008d701100080000008a43110021000000ab4311001a000000c54311000d0000009e6311000c0000002053657420612074686972642d7061727479206163636f756e742773206e616d652077697468206e6f206465706f7369742e204e6f206c656e67746820636865636b696e6720697320646f6e65206f6e20746865206e616d652e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f206f72206d617463682060543a3a466f7263654f726967696e602e202d204174206d6f7374206f6e652062616c616e6365206f7065726174696f6e2e202d204f6e652073746f7261676520726561642f77726974652e202d204f6e65206576656e742e7461726765746e616d655665633c75383e2052656d6f766520616e206163636f756e742773206e616d6520616e642074616b6520636861726765206f6620746865206465706f7369742e204661696c73206966206077686f6020686173206e6f74206265656e206e616d65642e20546865206465706f736974206973206465616c742077697468207468726f7567682060543a3a536c61736865646020696d62616c616e63652068616e646c65722e202d204f6e6520756e62616c616e6365642068616e646c6572202870726f6261626c7920612062616c616e6365207472616e736665722920436c65617220616e206163636f756e742773206e616d6520616e642072657475726e20746865206465706f7369742e204661696c7320696620746865206163636f756e7420776173206e6f74206e616d65642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e202d204f6e652062616c616e6365206f7065726174696f6e2e2053657420616e206163636f756e742773206e616d652e20546865206e616d652073686f756c642062652061205554462d382d656e636f64656420737472696e6720627920636f6e76656e74696f6e2c2074686f75676820776520646f6e277420636865636b2069742e20546865206e616d65206d6179206e6f74206265206d6f7265207468616e2060543a3a4d61784c656e677468602062797465732c206e6f72206c657373207468616e2060543a3a4d696e4c656e677468602062797465732e20496620746865206163636f756e7420646f65736e277420616c726561647920686176652061206e616d652c207468656e206120666565206f6620605265736572766174696f6e4665656020697320726573657276656420696e20746865206163636f756e742e00000000000067301100060000000101000000000000676411000c00000000000000dc4611001700000000000000000000000000000000000000449c1100f4461100000000000000000004471100010000000000000000000000285665633c75383e2c2042616c616e63654f663c543e2900180000000000000001000000310000000c4711001c00000020546865206c6f6f6b7570207461626c6520666f72206e616d65732e00000000d84711000a00000000000000e4471100010000000000000000000000fc471100030000000000000000000000144811000d00000000000000e4471100010000000000000000000000244811000300000000000000000000003c4811000b000000000000004848110002000000000000000000000078481100030000000000000000000000904811000d00000000000000a0481100010000000000000000000000b848110004000000000000006164645f6d656d626572000000000000864a11000300000000000000676411000c0000003a4a11001f000000449c110000000000594a11002d00000072656d6f76655f6d656d626572000000e649110024000000449c1100000000000a4a110030000000737761705f6d656d6265720000000000dd4911000600000000000000676411000c00000000000000e34911000300000000000000676411000c0000007f49110030000000449c110000000000af4911002e00000072657365745f6d656d6265727300000000000000784911000700000000000000b064110011000000d8481100560000002e4911001b000000449c110000000000494911002f000000204368616e676520746865206d656d6265727368697020746f2061206e6577207365742c20646973726567617264696e6720746865206578697374696e67206d656d626572736869702e204265206e69636520616e64207061737320606d656d6265727360207072652d736f727465642e204d6179206f6e6c792062652063616c6c65642066726f6d206052657365744f726967696e60206f7220726f6f742e6d656d626572732053776170206f7574206f6e65206d656d626572206072656d6f76656020666f7220616e6f746865722060616464602e204d6179206f6e6c792062652063616c6c65642066726f6d2060537761704f726967696e60206f7220726f6f742e72656d6f76656164642052656d6f76652061206d656d626572206077686f602066726f6d20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d206052656d6f76654f726967696e60206f7220726f6f742e204164642061206d656d626572206077686f6020746f20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d20604164644f726967696e60206f7220726f6f742e77686f0000000000000003301100070000000000000000000000b06411001100000000000000000000000000000000000000000000000000000000000000449c1100e44a11000000000000000000f44a11000100000000000000010000001800000000000000010000002e000000fc4a110032000000205468652063757272656e74206d656d626572736869702c2073746f72656420617320616e206f726465726564205665632e000000000000684b11000d00000000000000754b11000900000000000000449c1100804b11000000000000000000904b110004000000000000004d696e696d756d506572696f64543a3a4d6f6d656e740000180000000000000001000000a8000000b04b11005a0000000a4c11005a000000644c110059000000bd4c11001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e00000000000000084d110003000000000000000c4d1100010000000000000000000000244d110009000000000000007365740000000000a64e11000300000000000000a94e1100120000006c4d110016000000449c110000000000824d110056000000d84d110036000000449c1100000000000e4e1100510000005f4e110011000000449c110000000000704e11003600000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e6e6f77436f6d706163743c543a3a4d6f6d656e743e000000000070271100030000000000000000000000754b11000900000000000000000000000000000000000000000000000000000000000000449c11006c4f110000000000000000007c4f110001000000000000000100000000000000b38f1100090000000000000000000000e89711000400000000000000000000000000000000000000000000000000000000000000449c1100844f11000000000000000000944f11000100000000000000010000001800000000000000010000003e000000c94f1100240000001800000000000000010000002b0000009c4f11002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e0000006f5011000d000000545011001b0000000855110002000000185011003c00000080020000010000002f686f6d652f766f6c742f776f726b7370616365732f706172697479746563682f706f6c6b61646f742f72756e74696d652f7372632f6c69622e727342616420696e70757420646174612070726f766964656420746f20657865637574655f626c6f636b8450110010000000696e697469616c697a655f626c6f636b9c5011000f0000006170706c795f65787472696e73696300b450110013000000696e686572656e745f65787472696e7369637300d05011000f000000636865636b5f696e686572656e747300e85011001400000076616c69646174655f7472616e73616374696f6e045111000f0000006f6666636861696e5f776f726b6572001c5111001000000070617261636861696e5f737461747573345111000e00000070617261636861696e5f636f646500004c51110007000000696e6772657373005c5111001500000067656e65726174655f73657373696f6e5f6b6579730000007c5111000d0000006163636f756e745f6e6f6e6365000000945111000a00000071756572795f696e666f66696e616c6e756d417574686f7273686970417574686f720000140000000400000004000000a9000000aa000000ab000000496e646578200000e05111000200000075382f686f6d652f766f6c742f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6269747665632d302e31352e322f7372632f73746f72652e727300d0511100060000004852110022000000206973206e6f7420612076616c696420706f736974696f6e20666f722074797065200000e251110055000000a201000003000000556e636c6573000000000000b05211000a00000000000000bc521100010000000000000000000000d452110001000000000000007365745f756e636c6573000000000000f55211000a00000000000000ff5211000e000000dc521100190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e000000000000007c521100060000000000000000000000185411003a00000000000000000000000000000000000000000000000000000000000000449c11005454110000000000000000006454110001000000000000000100000000000000b0511100060000000000000000000000676411000c00000000000000000000000000000000000000000000000000000000000000449c11006c54110000000000000000007c54110001000000000000000000000000000000845411000c0000000000000000000000e89711000400000000000000000000000000000000000000000000000000000000000000449c1100905411000000000000000000a05411000100000000000000010000005665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e00001800000000000000010000002e000000f0541100070000001800000000000000010000002b000000d754110019000000446964536574556e636c65731800000000000000010000002b000000a85411002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c657300449c11000000000008551100020000003a20556e636c657320616c72656164792073657420696e20626c6f636b2e756e636c6520616c726561647920696e636c75646564756e636c652069732067656e65736973756e636c6520697320746f6f206869676820696e20636861696e756e636c6520706172656e74206e6f7420696e20636861696e756e636c65206e6f7420726563656e7420656e6f75676820746f20626520696e636c756465645468657265206973206f6e6c79206f6e6520666174616c206572726f723b207165640038000000080000000400000039000000496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473214e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f7221486561644f664e6f6d696e61746f72735374616b696e674e6f6d696e61746f7273486561644f6656616c696461746f727356616c696461746f7273426f6e6465644c65646765725374616b65727343757272656e74457261537461727456616c696461746f72536c617368496e4572614e6f6d696e61746f72536c617368496e457261536c617368696e675370616e735370616e536c61736800000000005457110006000000000000005c5711000200000000000000000000006c5711000200000000000000000000007c571100050000000000000084571100020000000000000000000000945711000100000000000000000000009c5711001a00000000000000b8571100010000000000000000000000c057110002000000000000005265776172640000875811000700000087581100070000008e58110054000000e258110023000000536c6173680000007e58110009000000875811000700000035581100490000004f6c64536c617368696e675265706f72744469736361726465640000295811000c000000d057110047000000175811001200000020416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64206e6f742062652070726f6365737365642e53657373696f6e496e646578204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e4163636f756e74496442616c616e636520416c6c2076616c696461746f72732068617665206265656e207265776172646564206279207468652066697273742062616c616e63653b20746865207365636f6e64206973207468652072656d61696e6465722066726f6d20746865206d6178696d756d20616d6f756e74206f66207265776172642e43757272656e74456c6563746564536c6f745374616b65556e6170706c696564536c6173686573506179656500000000000000f45b11000400000000000000f85b1100030000000000000000000000405c11000f0000000000000000000000b85c11000a00000000000000c45c1100010000000000000000000000dc5c11000e00000000000000000000004c5d11000600000000000000545d11000100000000000000000000006c5d1100170000000000000000000000245e11001100000000000000449c1100000000000000000000000000385e1100100000000000000000000000b85e11000800000000000000c05e1100010000000000000000000000d85e11000b0000000000000000000000305f11000800000000000000385f1100010000000000000000000000505f11000b0000000000000000000000a85f11000500000000000000449c1100000000000000000000000000b05f11000b0000000000000000000000086011000900000000000000146011000100000000000000000000002c6011000b0000000000000000000000846011000e0000000000000094601100010000000000000000000000ac6011000b00000000000000000000000461110013000000000000001861110001000000000000000000000030611100010000000000000000000000386111000d00000000000000449c110000000000000000000000000048611100050000000000000000000000706111000d00000000000000449c110000000000000000000000000080611100060000000000000000000000b06111001100000000000000c4611100010000000000000000000000dc611100010000000000000000000000e46111000d00000000000000f46111000100000000000000000000000c621100010000000000000000000000146211001400000000000000449c11000000000000000000000000002862110005000000000000000000000050621100150000000000000068621100020000000000000000000000986211000700000000000000626f6e6400000000e96611000a00000000000000f366110023000000000000004d6f11000500000000000000526f110015000000000000009967110005000000000000009e67110011000000a370110059000000fc70110021000000449c1100000000001d7111004c000000449c1100000000006971110049000000449c1100000000007e6311000b000000b2711100350000008d70110008000000e77111001a000000449c110000000000017211005b0000005c721100490000009e6311000c000000626f6e645f6578747261000000000000957011000e00000000000000526f110015000000676f110059000000c06f11000d000000449c110000000000cd6f11005400000021701100590000007a70110013000000449c1100000000000266110055000000449c1100000000007e6311000b000000576611003a0000008d70110008000000336f1100100000009e6311000c000000756e626f6e640000000000004d6f11000500000000000000526f110015000000626b110055000000b76b110040000000f76b110049000000449c110000000000406c110052000000926c110030000000449c110000000000c26c11004f000000116d11004f000000606d11003f000000449c1100000000004467110055000000449c1100000000009f6d110026000000449c1100000000007e6311000b000000c56d1100500000009166110026000000156e1100590000006e6e11005c000000ca6e110069000000336f110010000000436f11000a00000077697468647261775f756e626f6e6465640000005b6911004b000000449c110000000000a66911004d000000f369110013000000449c1100000000004467110055000000449c110000000000066a11001b000000449c1100000000007e6311000b000000216a110055000000766a110051000000c76a11003d000000046b11005e000000b7661100320000009e6311000c00000076616c6964617465000000004869110005000000000000004d6911000e0000000e6911003a000000449c110000000000cb65110037000000449c1100000000004467110055000000449c1100000000007e6311000b000000576611003a0000009166110026000000b7661100320000009e6311000c0000006e6f6d696e61746500000000df6811000700000000000000e668110028000000f667110044000000449c110000000000cb65110037000000449c1100000000004467110055000000449c1100000000007e6311000b0000003a681100490000008368110026000000a9681100360000009e6311000c0000006368696c6c000000af67110032000000449c110000000000cb65110037000000449c1100000000004467110055000000449c1100000000007e6311000b000000576611003a000000e167110015000000b7661100320000009e6311000c0000007365745f7061796565000000000000009967110005000000000000009e67110011000000166711002e000000449c110000000000cb65110037000000449c1100000000004467110055000000449c1100000000007e6311000b000000576611003a0000009166110026000000b7661100320000009e6311000c0000007365745f636f6e74726f6c6c6572000000000000e96611000a00000000000000f366110023000000a765110024000000449c110000000000cb65110037000000449c1100000000000266110055000000449c1100000000007e6311000b000000576611003a0000009166110026000000b7661100320000009e6311000c0000007365745f76616c696461746f725f636f756e7400000000009865110003000000000000009b6511000c0000007865110020000000666f7263655f6e6f5f657261730000004c6511002c000000449c1100000000007e6311000b0000003c651100100000009e6311000c000000666f7263655f6e65775f657261000000c1641100530000001465110028000000449c1100000000007e6311000b0000003c651100100000009e6311000c0000007365745f696e76756c6e657261626c657300000000000000a66411000a00000000000000b0641100110000007364110033000000666f7263655f756e7374616b6500000000000000626411000500000000000000676411000c0000001f64110043000000666f7263655f6e65775f6572615f616c77617973ca63110041000000449c1100000000007e6311000b0000000b641100140000009e6311000c00000063616e63656c5f64656665727265645f736c61736800000000000000aa6311000300000000000000ad6311000800000000000000b56311000d00000000000000c263110008000000d062110051000000216311001c0000003d63110041000000449c1100000000007e6311000b00000089631100150000009e6311000c0000002043616e63656c20656e6163746d656e74206f66206120646566657272656420736c6173682e2043616e2062652063616c6c6564206279206569746865722074686520726f6f74206f726967696e206f72207468652060543a3a536c61736843616e63656c4f726967696e602e2070617373696e67207468652065726120616e6420696e6469636573206f662074686520736c617368657320666f7220746861742065726120746f206b696c6c2e2023203c7765696768743e202d204f6e652073746f726167652077726974652e2023203c2f7765696768743e657261457261496e646578736c6173685f696e64696365735665633c7533323e20466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f662073657373696f6e7320696e646566696e6974656c792e202d204f6e652073746f7261676520777269746520466f72636520612063757272656e74207374616b657220746f206265636f6d6520636f6d706c6574656c7920756e7374616b65642c20696d6d6564696174656c792e7374617368543a3a4163636f756e74496420536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e76616c696461746f72735665633c543a3a4163636f756e7449643e20466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c20626520726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e202d204e6f20617267756d656e74732e20466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e2054686520696465616c206e756d626572206f662076616c696461746f72732e6e6577436f6d706163743c7533323e202852652d297365742074686520636f6e74726f6c6c6572206f6620612073746173682e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e636f6e74726f6c6c65723c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f75726365202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e706179656552657761726444657374696e6174696f6e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e202d20436f6e7461696e73206f6e6520726561642e204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f66206074617267657473602c2077686963682069732063617070656420617420604d41585f4e4f4d494e4154494f4e53602e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e746172676574735665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e707265667356616c696461746f7250726566732052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c656420766961206077697468647261775f756e626f6e646564602e202d204f6e6520444220656e7472792e203c2f7765696768743e76616c7565436f6d706163743c42616c616e63654f663c543e3e2041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e202d204f2831292e6d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e00000000000000987b11000e0000000000000000000000a67b11000300000000000000000000000000000000000000000000000000000000000000449c1100d48911000000000000000000ac7b110001000000000000000100000000000000b47b1100150000000000000000000000a67b11000300000000000000000000000000000000000000000000000000000000000000449c1100cc7b11000000000000000000dc7b110001000000000000000100000000000000e47b11000d0000000000000000000000b06411001100000000000000000000000000000000000000000000000000000000000000449c1100f87e11000000000000000000f47b11000300000000000000010000000000000071561100060000000101000000000000676411000c00000000000000676411000c00000000000000000000000000000000000000449c1100407c110000000000000000000c7c11000100000000000000000000000000000077561100060000000101000000000000676411000c00000000000000147c11002900000000000000000000000000000000000000449c1100407c11000000000000000000507c1100010000000000000000000000000000002c591100050000000101000000000000676411000c000000000000009e6711001100000000000000000000000000000000000000449c1100587c11000000000000000000687c110001000000000000000100000000000000675611000a0000000101010000000000676411000c000000000000004d6911000e00000000000000000000000000000000000000449c1100707c11000000000000000000807c1100010000000000000001000000000000004d5611000a0000000101010000000000676411000c00000000000000887c11001900000000000000000000000000000000000000449c1100a47c11000000000000000000b47c1100040000000000000000000000000000007d561100070000000101000000000000676411000c00000000000000d47c11002400000000000000000000000000000000000000449c1100f87c11000000000000000000087d110004000000000000000100000000000000055911000e0000000000000000000000b06411001100000000000000000000000000000000000000000000000000000000000000449c1100f87e11000000000000000000287d110001000000000000000100000000000000307d11000a0000000000000000000000ad6311000800000000000000000000000000000000000000000000000000000000000000449c1100d489110000000000000000003c7d110001000000000000000100000000000000845611000f0000000000000000000000447d11000b00000000000000000000000000000000000000000000000000000000000000449c1100507d11000000000000000000607d110001000000000000000100000000000000687d11001b0000000000000000000000295811000c00000000000000000000000000000000000000000000000000000000000000449c1100d48911000000000000000000847d1100010000000000000001000000000000008c7d1100160000000000000000000000a27d11000900000000000000000000000000000000000000000000000000000000000000449c1100ac7d11000000000000000000bc7d11000100000000000000010000000000000013591100090000000000000000000000c47d11000c00000000000000000000000000000000000000000000000000000000000000449c1100687e11000000000000000000d07d110003000000000000000100000000000000e87d1100080000000000000000000000f07d11000700000000000000000000000000000000000000000000000000000000000000449c1100f87d11000000000000000000087e110001000000000000000100000000000000107e1100130000000000000000000000237e11000700000000000000000000000000000000000000000000000000000000000000449c11002c7e110000000000000000003c7e110003000000000000000100000000000000547e1100130000000000000000000000c47d11000c00000000000000000000000000000000000000000000000000000000000000449c1100687e11000000000000000000787e1100020000000000000001000000000000001c591100100000000101000000000000ad6311000800000000000000887e11002f00000000000000000000000000000000000000449c1100b87e11000000000000000000c87e110001000000000000000100000000000000d07e11000a0000000000000000000000da7e11001d00000000000000000000000000000000000000000000000000000000000000449c1100f87e11000000000000000000087f11000100000000000000010000000000000093561100130000000201020000000000ad6311000800000000000000676411000c00000000000000107f11001700000000000000449c1100287f11000000000000000000387f110002000000000000000000000000000000a6561100130000000201020000000000ad6311000800000000000000676411000c00000000000000c47d11000c00000000000000449c1100487f11000000000000000000587f110001000000000000000000000000000000b95611000d0000000101000000000000676411000c00000000000000607f11001700000000000000000000000000000000000000449c1100787f11000000000000000000887f110001000000000000000000000000000000c6561100090000000101000000000000907f11002300000000000000b37f11002200000000000000000000000000000000000000449c1100d87f11000000000000000000e87f110002000000000000000100000000000000f87f1100160000000000000000000000ad6311000800000000000000000000000000000000000000000000000000000000000000449c11001080110000000000000000002080110001000000000000000000000000000000288011000e0000000000000000000000a67b11000300000000000000000000000000000000000000000000000000000000000000449c1100d489110000000000000000003880110001000000000000000100000056616c696461746f72436f756e74753332000000ff8811002a0000004d696e696d756d56616c696461746f72436f756e74000000180000000000000001000000ac000000af88110050000000496e76756c6e657261626c6573000000db871100560000003188110053000000848811002b0000009b871100400000005374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e0000001800000000000000010000002b0000004a871100510000001800000000000000010000002b0000001187110039000000180000000000000001000000ad000000c0861100510000004e6f6d696e6174696f6e733c543a3a4163636f756e7449643e0000001800000000000000010000002b000000e485110059000000449c1100000000003d8611004d0000008a861100360000004578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e180000000000000001000000ae00000027851100530000007a85110046000000449c110000000000c085110024000000e88411003f00000043757272656e744572610000d1841100170000004d6f6d656e744f663c543e001800000000000000010000003e000000b38411001e00000043757272656e74457261537461727453657373696f6e496e646578007f8411003400000043757272656e74457261506f696e74734561726e6564457261506f696e747300180000000000000001000000af0000003c8411004300000042616c616e63654f663c543ec08311004c000000449c1100000000000c84110030000000466f726365457261466f7263696e67001800000000000000010000002b0000007983110047000000536c6173685265776172644672616374696f6e50657262696c6c0000180000000000000001000000b0000000028311003e000000449c110000000000408311003900000043616e63656c6564536c6173685061796f757400180000000000000001000000470000008282110045000000c78211003b0000005665633c556e6170706c696564536c6173683c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3e001800000000000000010000002e0000005182110031000000426f6e646564457261735665633c28457261496e6465782c2053657373696f6e496e646578293e001800000000000000010000002e00000008821100490000002850657262696c6c2c2042616c616e63654f663c543e29001800000000000000010000002b0000009b81110051000000ec8111001c0000001800000000000000010000002b0000004381110058000000736c617368696e673a3a536c617368696e675370616e73001800000000000000010000002b000000208111002300000028543a3a4163636f756e7449642c20736c617368696e673a3a5370616e496e64657829736c617368696e673a3a5370616e5265636f72643c42616c616e63654f663c543e3e000000180000000000000001000000b1000000a38011004f000000f28011002e0000004561726c69657374556e6170706c696564536c61736800001800000000000000010000002b000000648011003f00000053746f7261676556657273696f6e00004080110024000000205468652076657273696f6e206f662073746f7261676520666f7220757067726164652e20546865206561726c696573742065726120666f72207768696368207765206861766520612070656e64696e672c20756e6170706c69656420736c6173682e205265636f72647320696e666f726d6174696f6e2061626f757420746865206d6178696d756d20736c617368206f6620612073746173682077697468696e206120736c617368696e67207370616e2c2061732077656c6c20617320686f77206d7563682072657761726420686173206265656e2070616964206f75742e20536c617368696e67207370616e7320666f72207374617368206163636f756e74732e20416c6c20736c617368696e67206576656e7473206f6e206e6f6d696e61746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682076616c7565206f6620746865206572612e20416c6c20736c617368696e67206576656e7473206f6e2076616c696461746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682070726f706f7274696f6e20616e6420736c6173682076616c7565206f6620746865206572612e2041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e20416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e2054686520616d6f756e74206f662063757272656e637920676976656e20746f207265706f7274657273206f66206120736c617368206576656e74207768696368207761732063616e63656c65642062792065787472616f7264696e6172792063697263756d7374616e6365732028652e672e20676f7665726e616e6365292e205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e205472756520696620746865206e6578742073657373696f6e206368616e67652077696c6c2062652061206e657720657261207265676172646c657373206f6620696e6465782e2054686520616d6f756e74206f662062616c616e6365206163746976656c79206174207374616b6520666f7220656163682076616c696461746f7220736c6f742c2063757272656e746c792e2054686973206973207573656420746f20646572697665207265776172647320616e642070756e6973686d656e74732e205265776172647320666f72207468652063757272656e74206572612e205573696e6720696e6469636573206f662063757272656e7420656c6563746564207365742e205468652073657373696f6e20696e646578206174207768696368207468652063757272656e742065726120737461727465642e20546865207374617274206f66207468652063757272656e74206572612e205468652063757272656e742065726120696e6465782e205468652063757272656e746c7920656c65637465642076616c696461746f7220736574206b65796564206279207374617368206163636f756e742049442e204e6f6d696e61746f727320666f72206120706172746963756c6172206163636f756e74207468617420697320696e20616374696f6e207269676874206e6f772e20596f752063616e27742069746572617465207468726f7567682076616c696461746f727320686572652c2062757420796f752063616e2066696e64207468656d20696e207468652053657373696f6e206d6f64756c652e2054686973206973206b6579656420627920746865207374617368206163636f756e742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e204e4f54453a206973207072697661746520736f20746861742077652063616e20656e73757265207570677261646564206265666f726520616c6c207479706963616c2061636365737365732e204469726563742073746f7261676520415049732063616e207374696c6c2062797061737320746869732070726f74656374696f6e2e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e000000000000009c8911000e00000000000000295811000c00000000000000449c1100ac8911000000000000000000bc891100010000000000000000000000c48911000f00000000000000ad6311000800000000000000449c1100d48911000000000000000000e4891100010000000000000053657373696f6e735065724572610000180000000000000001000000b2000000258a11001c000000426f6e64696e674475726174696f6e0018000000000000000100000030000000ec89110039000000204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e000000408b11005b0000001203000001000000636f6e74726f6c6c657220616c72656164792070616972656463616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e6365737461736820616c726561647920626f6e6465646e6f7420612073746173686e6f74206120636f6e74726f6c6c657263616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b73746172676574732063616e6e6f7420626520656d7074796475706c696361746520696e646578736c617368207265636f726420696e646578206f7574206f6620626f756e6473626164206f726967696e2f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f7374616b696e672f7372632f6c69622e727371202f2028712f246d617829203c202832202a20246d6178292e204d6163726f2070726576656e747320616e792074797065206265696e672063726561746564207468617420646f6573206e6f74207361746973667920746869733b2071656400208c110019000000408c11006d0000006f00000012000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f7072696d6974697665732f73722d61726974686d657469632f7372632f7065725f7468696e67732e72734661696c656420746f20636f6e7665727454696d657374616d70557064617465526563656e7448696e747352616e646f6d6e657373436f6c6c656374697665466c697052616e646f6d4d6174657269616c0000188d110031000000498d110064000000470000000400000046696e616c2068696e74206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b2f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f66696e616c6974792d747261636b65722f7372632f6c69622e7273000000c88d110023000000498d110064000000480000000400000046696e616c697a6564206865696768742061626f766520626c6f636b206e756d62657200380000000800000004000000540000000c8e110018000000248e110009000000426974536c6963652063616e6e6f7420616464726573732020656c656d656e7473000000408e11005500000029010000030000002f686f6d652f766f6c742f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6269747665632d302e31352e322f7372632f736c6963652e7273000000a88e110014000000bc8e110004000000496e646578206f7574206f662072616e67653a20203e3d20408e110055000000bc02000003000000d88e11002a000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a2000000c8f1100230000005f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e00408f1100670000002b000000010000002f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f617574686f726974792d646973636f766572792f7372632f6c69622e72734174746573746174696f6e734469645570646174654d6f7265206174746573746174696f6e732063616e206265206164646564206f6e6c79206f6e636520696e206120626c6f636b2e4f72646572656448696e74734d656469616e616c77617973206174206c65617374206f6e6520726563656e742073616d706c653b20716564726563656e7420616e64206f72646572656420636f6e7461696e207468652073616d65206974656d733b20716564000014000000040000000400000012000000d890110043000000498d110064000000800000000400000090901100480000009c0a00000a0000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f6d6f642e72737072756e696e672064696374617465642062792077696e646f775f73697a6520776869636820697320616c776179732073617475726174656420617420313b2071656400999211001c0000004c9111005d000000b70000000300000075921100240000004c9111005d000000c0000000030000002f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f6672616d652f6578656375746976652f7372632f6c69622e727300000043921100320000004c9111005d0000001b010000030000001c921100270000004c9111005d0000002301000004000000f4911100280000004c9111005d000000290100000300000053746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e5472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642e506172656e7420686173682073686f756c642062652076616c69642e00000000000000e49211000a00000000000000f092110001000000000000000000000008931100020000000000000066696e616c5f68696e740000000000007093110004000000000000007493110017000000189311003d000000559311001b0000002048696e7420746861742074686520617574686f72206f66207468697320626c6f636b207468696e6b732074686520626573742066696e616c697a656420626c6f636b2069732074686520676976656e206e756d6265722e68696e74436f6d706163743c543a3a426c6f636b4e756d6265723e0000000000fc9311000a00000000000000069411000e00000000000000449c1100149411000000000000000000249411000100000000000000000000002c9411000d00000000000000069411000e00000000000000449c11003c94110000000000000000004c941100010000000000000057696e646f7753697a65543a3a426c6f636b4e756d626572180000000000000001000000b30000009b941100460000005265706f72744c6174656e6379000000180000000000000001000000420000005494110047000000205468652064656c617920616674657220776869636820706f696e74207468696e6773206265636f6d6520737573706963696f75732e2044656661756c7420697320313030302e20546865206e756d626572206f6620726563656e742073616d706c657320746f206b6565702066726f6d207468697320636861696e2e2044656661756c74206973203130312e00000000000000f08c11000e00000000000000000000003c9511000c00000000000000000000000000000000000000000000000000000000000000449c1100489511000000000000000000589511000300000000000000010000005665633c543a3a486173683e1800000000000000010000002e0000007095110058000000c895110058000000209611001100000020536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e672062756666657220776974682060626c6f636b5f6e756d626572202520383160206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e000000408e110055000000de0b0000030000009090110048000000a20a00000e000000526563656e7450617261426c6f636b7350617261426c6f636b4174746573746174696f6e730000000000000054961100100000000101000000000000069411000e00000000000000849711001100000000000000000000000000000000000000449c1100989711000000000000000000a89711000200000000000000000000000000000064961100150000000201000000000000069411000e00000000000000b89711000400000000000000bc9711001400000000000000449c1100d09711000000000000000000e097110001000000000000000000000000000000b38f1100090000000000000000000000e89711000400000000000000000000000000000000000000000000000000000000000000449c1100ec9711000000000000000000449c1100000000000000000001000000496e636c75646564426c6f636b733c543e0000001800000000000000010000002b000000269811003c000000629811003300000048617368426c6f636b4174746573746174696f6e733c543e1800000000000000010000002b000000fc9711002a000000626f6f6c1800000000000000010000002b000000204174746573746174696f6e73206f6e206120726563656e742070617261636861696e20626c6f636b2e2041206d617070696e672066726f6d206d6f64756c617220626c6f636b206e756d62657220286e2025204174746573746174696f6e506572696f642920746f2073657373696f6e20696e64657820616e6420746865206c697374206f662063616e646964617465206861736865732e00000000000000c49811001100000000000000d8981100010000000000000000000000f098110001000000000000006d6f72655f6174746573746174696f6e73000000000000003d99110005000000000000004299110010000000f8981100450000002050726f766964652063616e64696461746520726563656970747320666f722070617261636861696e732c20696e20617363656e64696e67206f726465722062792069642e5f6d6f72654d6f72654174746573746174696f6e73000070991100480000009c0a00000a0000000000000000000000000000002f72757374632f313732316339363835623165653639663165313762336138623039313435623130666466626534612f7372632f6c6962636f72652f736c6963652f6d6f642e72737099110048000000a20a00000e000000e099110019000000009a11006a000000440000000a000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f7072696d6974697665732f73722d61726974686d657469632f7372632f62696775696e742e727363616e6e6f74206669742061206e756d62657220696e746f2075313238616c7265616479206d757461626c7920626f72726f77656400180000000000000001000000b4000000616c726561647920626f72726f776564180000000000000001000000b500000072656d696e646572206f6620646976206279206320697320616c77617973206c657373207468616e20633b207165640038000000080000000400000054000000726573756c742063616e6e6f742066697420696e2075313238000000449b11002d000000719b11000c0000007d9b110003000000617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a20889b11003400000064657374696e6174696f6e20616e6420736f7572636520736c69636573206861766520646966666572656e74206c656e67746873cc9b11001800000059080000090000007372632f6c6962636f72652f736c6963652f6d6f642e727318000000000000000100000019000000486f737420746f207761736d2076616c7565732061726520656e636f64656420636f72726563746c793b20716564000018000000000000000100000019000000449c11000000000072756e74696d650052756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e670000809c110019000000a09c11006e0000005800000022000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f766f6c742f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f643966636137652f7072696d6974697665732f73722d7072696d6974697665732f7372632f67656e657269632f6572612e727348617368206e6f7420657175616c496e76616c6964206f726967696e43616e206e6f74206c6f6f6b757044697370617463684572726f725472616e73616374696f6e20776f756c642065786861757374732074686520626c6f636b206c696d6974735472616e73616374696f6e2068617320616e20616e6369656e7420626972746820626c6f636b5472616e73616374696f6e20686173206120626164207369676e61747572655472616e73616374696f6e206973206f757464617465645472616e73616374696f6e2077696c6c2062652076616c696420696e2074686520667574757265496e6162696c69747920746f2070617920736f6d6520666565732028652e672e206163636f756e742062616c616e636520746f6f206c6f77295472616e73616374696f6e2063616c6c206973206e6f74206578706563746564496e76616c69645472616e73616374696f6e20637573746f6d206572726f72436f756c64206e6f742066696e6420616e20756e7369676e65642076616c696461746f7220666f722074686520756e7369676e6564207472616e73616374696f6e436f756c64206e6f74206c6f6f6b757020696e666f726d6174696f6e20726571756972656420746f2076616c696461746520746865207472616e73616374696f6e556e6b6e6f776e5472616e73616374696f6e20637573746f6d206572726f7262616265736c6f74436f756c64206e6f74206465636f64652072657175657374656420696e686572656e742074797065214241424520696e686572656e742064617461206e6f7420666f756e643c7761736d3a73747269707065643e0041e8bec6000b0800000000000000000041f0bec6000b08709f110090181000008aff02046e616d650181ff02e50400196578745f6c6f6767696e675f6c6f675f76657273696f6e5f3101206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f3102196578745f73746f726167655f7365745f76657273696f6e5f31031e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f3104196578745f73746f726167655f6765745f76657273696f6e5f31051b6578745f73746f726167655f636c6561725f76657273696f6e5f31061a6578745f73746f726167655f726f6f745f76657273696f6e5f3107226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f31081d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f3109236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f310a226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f310b206578745f68617368696e675f6b656363616b5f3235365f76657273696f6e5f310c1d6578745f68617368696e675f74776f785f36345f76657273696f6e5f310d236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f310e1c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f310f1c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f3110236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f3111286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f3112346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f3113286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f3114256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f3115206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f31162a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f31171a6578745f73746f726167655f726561645f76657273696f6e5f3118296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f3119246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f311a1e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f311b1c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f311c286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f311d216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f311e2c6578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f76657273696f6e5f311f376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f3120256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f31210c5f5f727573745f616c6c6f63220a5f5f72675f616c6c6f63230e5f5f727573745f6465616c6c6f63240c5f5f72675f6465616c6c6f63250e5f5f727573745f7265616c6c6f63260c5f5f72675f7265616c6c6f6327135f5f727573745f616c6c6f635f7a65726f656428115f5f72675f616c6c6f635f7a65726f65642909686173685f746573742a34616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68356233306265363662343435353034382b29636f72653a3a70616e69636b696e673a3a70616e69633a3a68323063313464323066633562643735392c25616c6c6f633a3a666d743a3a666f726d61743a3a68323831393632633865383762323437642d36636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a68616235343331366165643263313732662e23636f72653a3a666d743a3a77726974653a3a68396230643164626332363937633836392f48616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303032626638303561376238393139373008727573745f6f6f6d312e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a68356434303837616430646137363763653230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6831356333303661383239333633316437333a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6830663064323735666631376134343330343b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6832613832613334626139363963333332353a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68326638353766623233303363633838313634636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a6863376135643936316432663964303734374e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a6863386666343861623735643264653361382d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a6864646265316133303038306530306238392f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a68626239333338383365613738393463623a11727573745f626567696e5f756e77696e643b313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a68383833323064313536313161356639623c35636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a68666161613666646133623938323461653d43636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a68306262373635663830326331656166633e36636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a68303462666530613564353537313264383f2c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a6837333936386132343239306363343736402e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a683561353061613735386539323134323641323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6830613866613161646266393336323933424a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683733656565373531373561303937306143323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838653032373461303430356432623664443d636f72653a3a756e69636f64653a3a626f6f6c5f747269653a3a426f6f6c547269653a3a6c6f6f6b75703a3a68343933346537373839666462616663394549636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a68313937306334616565326135393234344634636f72653a3a666d743a3a417267756d656e7456313a3a73686f775f7573697a653a3a683839303832356232353731376561333647453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686135383738383335396463393431333148483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686663393736636137363865373336653349323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68626236666532383064653133383030614a2e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a68306464366561376562346534636134314b303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68316439353632393731326265616561394c2e636f72653a3a736c6963653a3a6d656d6368723a3a6d656d6368723a3a68656166623931643661653061356431614d8001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a68303238663933386333626434366139304e4d636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f722075383e3a3a666d743a3a68666266386165356233313032636537664f30636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a683032633035656539393633393062666450533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6864393661323463646635666665646462512f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a6831663336303037613334396331653532522e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a6866653239613738646439376265386334533a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6863626538666233323531333634626365543b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6839306530656362623334303434643465553a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68653233326239353739646430313736325637636f72653a3a666d743a3a6275696c646572733a3a44656275675365743a3a656e7472793a3a683538346335386563663433353464313257443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683530623364376162653532633531383258313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834353039316439343663623062363337594a636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a557070657248657820666f72206933323e3a3a666d743a3a68326635306430643539646365373730395a3e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68393134323438356435303939613561645b693c6672616d655f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68623738336331663064393763333535665c6c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68313261663538306634353835373264385d483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68363431636664663232393863363936385e693c6672616d655f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68383161373938386163366633346363335f4d3c6672616d655f737570706f72743a3a64656275673a3a52756e74696d654c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a683632616539366461336438663630326560493c6672616d655f737570706f72743a3a64656275673a3a52756e74696d654c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a683761346666626135316439353365396261323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6830643964396466316365613861363937623a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6863666361373562303439613238356130633b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6831383865313638636166383862646137643a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a686434386536363733393539386139666265383c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a686138383639323036626636366439616366343c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a683162643862633638613731393763303967363c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a666c7573683a3a6866656365656266343364313635626161683a70616c6c65745f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a683535356131396632626264323066376369497061726974795f7363616c655f636f6465633a3a656e636f64655f617070656e643a3a657874726163745f6c656e6774685f646174613a3a68316465313665636364323536336461376a49706f6c6b61646f745f7072696d6974697665733a3a70617261636861696e3a3a43616e646964617465526563656970743a3a686173683a3a68386262353262653939663139366233366b437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68353735646661343130366365313633326c30636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68386639636236313234373134613964356d543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68633864643835323366336661613731646e6b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68613535393365393532376234376130666f7d7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c205230293e3a3a6465636f64653a3a686434653136336139363736313338666270437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a686238323633373630386435353034343771463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6864323266356338616131656232346563724a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6832393738666530636364386362373338734a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6836616236623433346437313262613435742d616c6c6f633a3a7665633a3a5665633c543e3a3a72657461696e3a3a6830633630396366653965656265396162752d616c6c6f633a3a7665633a3a5665633c543e3a3a72657461696e3a3a6831623565306664333631393764656338762d616c6c6f633a3a7665633a3a5665633c543e3a3a72657461696e3a3a686138643137646139383061323865373177403c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683137363661353762666132313764656378443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683534366333383061333664626666653379443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68363530646432306438643731613666647a463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68656535356135333065386630326365387b543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68323234613834363834396136326631347c543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68323966636330643836613939303336627d543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68356130363337303062613038336535357e543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68386533326239353931373032656365387f543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68616530326537353564343564653833348001543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686534373936363137633633656439373981015d3c6269747665633a3a736c6963653a3a497465723c432c543e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68643338376262373565643135343363388201383c2a636f6e7374205420617320636f72653a3a666d743a3a506f696e7465723e3a3a666d743a3a68316363336237626530383139623430638301356269747665633a3a7665633a3a4269745665633c432c543e3a3a63617061636974793a3a68663738623033666438376664333866618401543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68626637663133613837356237323839628501513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68316263303232303837373562363463658601513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68343634623565306434316230343335338701513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68393439303336343565333134363562638801753c73725f7072696d6974697665733a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68323262643535643532343231333339308901366672616d655f73797374656d3a3a4d6f64756c653c543e3a3a626c6f636b5f686173683a3a68613934316666333732623265616331658a01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68333462663538386331633061363831668b01376672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a68666635653932363739346338613465628c01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68333534613961363265323539656165328d01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68393466353934656363346530656333668e01416672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6576656e745f696e64657865643a3a68633333323564363337653866333237378f01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683162663265616537613834303336396590018a013c7375627374726174655f72756e74696d655f696e746572666163653a3a706173735f62793a3a436f6465633c543e206173207375627374726174655f72756e74696d655f696e746572666163653a3a706173735f62793a3a506173734279496d706c3c543e3e3a3a66726f6d5f6666695f76616c75653a3a68303231356265633133313737353061379101463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68663031303038666133353934633665629201703c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6833346332646533613437663836646139930130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68333166613133333531656234343461659401303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683636333537653336383335646239313195013a6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a686434306163376139386563386166616496013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68636338306631366539613962363264629701683c6672616d655f73797374656d3a3a5f5f476574427974655374727563744576656e74733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68353036653539396634666139366266629801703c6672616d655f73797374656d3a3a5f5f4765744279746553747275637445787472696e73696373526f6f743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68363135346562643734373034613936399901703c6672616d655f73797374656d3a3a5f5f4765744279746553747275637445787472696e736963436f756e743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68316164313563373132343037306435339a014b6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a72656769737465725f65787472615f7765696768745f756e636865636b65643a3a68306235656130333231396231656632349b01346672616d655f73797374656d3a3a4d6f64756c653c543e3a3a66696e616c697a653a3a68346330383737323262343465356366379c0185013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a456e756d657261746f723c4b2c562c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68333431303163663439323534636438359d01696672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4b6579466f726d61743a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f6b65793a3a68333461663135346131306633626638649e01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68396631303565353830656665336333619f01303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838646365646131343438323233333538a00185013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a456e756d657261746f723c4b2c562c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833383561326232626366316461623762a101696672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4b6579466f726d61743a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f6b65793a3a6834353036393632306535383638396333a201386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865313839623063343263323137393666a30185013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a456e756d657261746f723c4b2c562c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6862306635373765396365633633303039a401696672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4b6579466f726d61743a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f6b65793a3a6833326663653563336465313663616539a501386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837313233303363613330363832626337a60185013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a456e756d657261746f723c4b2c562c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6863613563373839643232323464363038a701696672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4b6579466f726d61743a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f6b65793a3a6838366135616437356539656333326638a801386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865383233636634373763333336343337a901b8016672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4c696e6b6167653c4b65793e3e3a3a656e636f64655f746f3a3a6861613135613765343230316261363833aa01cc016672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a456e636f64654c696b654c696e6b6167653c504b65792c4e4b65792c4b65793e3e3a3a656e636f64655f746f3a3a6835396231323061666435663464623564ab01776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6837633134663363313262633564386134ac01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6832363734646632356635623665316632ad014773725f7072696d6974697665733a3a7472616974733a3a5369676e6564457874656e73696f6e3a3a7072655f64697370617463683a3a6830313832373661623965393531643030ae01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6832643635386663303736303232663430af016f3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6837313436623762373930393038343666b001723c73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6838316238363763316530626639333634b1019e01706f6c6b61646f745f7072696d6974697665733a3a70617261636861696e3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f7072696d6974697665733a3a70617261636861696e3a3a43616e646964617465526563656970743e3a3a656e636f64655f746f3a3a6839653465353938623961376664336139b20177706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f72756e74696d653a3a4576656e743e3a3a656e636f64655f746f3a3a6862383438376135393635623236653532b3015d3c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6861306331356365323063646263643162b401613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6834326331323333663035616465363238b501723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6836373031383039363364356531633437b601723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6865306362383739383739613439636666b7013d70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a69735f6f6e6c696e655f6175783a3a6861643961656537616531623031663762b8014373725f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a726561643a3a6838356639353632393363333532623631b90147636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207533323e3a3a666d743a3a6838393861383166336230616565633136ba016e3c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a56616c6964617465556e7369676e65643e3a3a76616c69646174655f756e7369676e65643a3a6838326164303030303536313830666637bb01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837343132626131646533666436343536bc01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837636665663966313564336561393766bd0196013c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e2061732070616c6c65745f73657373696f6e3a3a4f6e6553657373696f6e48616e646c65723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f6265666f72655f73657373696f6e5f656e64696e673a3a6832306639393261346465306630613934be013570616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a7374616b6572733a3a6862653338663830653035323362643165bf014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6866396531313337333064333436613465c001386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831613061353364646437396565663566c101706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6830366264333931626265346530666139c2014b3c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6861613436353065353631383339613261c301723c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6866633065616261356335346365363130c40168636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6861363536653831336664373738356235c501437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6832363335636433636136646466383936c601ff013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e2061732073725f7374616b696e675f7072696d6974697665733a3a6f6666656e63653a3a4f6e4f6666656e636548616e646c65723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c283c542061732070616c6c65745f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249642c203c542061732070616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a54726169743e3a3a46756c6c4964656e74696669636174696f6e293e3e3a3a6f6e5f6f6666656e63653a3a6865383362383663633635643936663361c7013e70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863303932613839336366313861626234c8013f70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a6e6f74655f617574686f72736869703a3a6839383536663630623538613433663337c9014070616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865356536623736336532383463323731ca013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6861383636353561666666613632323262cb0176706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a6865343336373637656334356261623635cc013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6832353237636464373564363162306337cd013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6837313266666665613837393535663833ce0148616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6838616239396162313931393632356164cf0148616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6832653639303139636564396334616435d00130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6864396134393833376463303936393536d1014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6831316165333839326361646530666434d2014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6863333031623936653036343964323933d3015c3c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6838316264353335653565623331323965d401613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6865643365393131396164303936653830d5013f70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f65787465726e616c3a3a6831393062386137383132343538373230d601386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862613432343561373534613262313832d7014170616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a696e6a6563745f7265666572656e64756d3a3a6864363530643337623362653430666437d8013d70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f7075626c69633a3a6837353933303839306638653765626633d90173706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f7220706f6c6b61646f745f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a6833656335353862633636626262303137da0130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6861333832623266326564343162366335db0134636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68613338326232663265643431623663352e383635dc013a70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6465706f7369745f6f663a3a6862353864303033633266333938306366dd01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862336461396364303565626263333935de0190013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a756e726573657276653a3a6834396331393237383461323734313037df013a70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a766f746572735f666f723a3a6836396338653537383563326537383562e0013770616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a766f74655f6f663a3a6836666564316130643963643836363662e1013f70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a64656c6567617465645f766f7465733a3a6864646131333861396564383433343231e2016e6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4b6579466f726d61743a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f686561645f6b65793a3a6866333361316437643062363261326663e3018a013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a746f74616c5f62616c616e63653a3a6832633866653562306435663266643932e4014070616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a636c6561725f7265666572656e64756d3a3a6832646563303865326163373732353035e5013f70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7265666572656e64756d5f696e666f3a3a6839383030306532663330306161366331e6013e70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863323138646464343831336135343433e7014070616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6831316632363735626534663339663662e801723c70616c6c65745f64656d6f63726163793a3a5f5f476574427974655374727563744e65787445787465726e616c3c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862656332333135373163663030666331e901713c70616c6c65745f64656d6f63726163793a3a5f5f4765744279746553747275637444656c65676174696f6e733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830613735663635666432363030396239ea01713c70616c6c65745f64656d6f63726163793a3a5f5f476574427974655374727563745075626c696350726f70733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863396634313065333464643333326236eb014970616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6833636139636230366238643431653561ec019a013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4c61756e6368506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861303434353763616636613030633336ed01a3013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456d657267656e6379566f74696e67506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830616365373234393631336436383037ee019c013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d4465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833383636636565633630626530303436ef019d013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456e6163746d656e74506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833376261313436356634323964303239f0015f3c70616c6c65745f64656d6f63726163793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6832376166396436623063346535366163f1018e013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a726573657276653a3a6836626432666332393931643066653938f2013770616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a646f5f766f74653a3a6864323934316138366665663837343363f301386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834353130306164373862323661643966f401386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838343666396133643162653531386634f5014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6830303738363961346637666438313336f601776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6833393531383365383966346338626539f7018d013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f6c6f636b3a3a6837353333623262306334616135613335f80190013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a657874656e645f6c6f636b3a3a6861386362633833623838323364303332f90168636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6862333866616238313137343266623065fa012b616c6c6f633a3a736c6963653a3a6d657267655f736f72743a3a6838333837343434383534393465616532fb0142706f6c6b61646f745f72756e74696d653a3a70617261636861696e733a3a6c6f63616c697a65645f7061796c6f61643a3a6835656663356266316335306435356564fc01776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6832336361396335313065343061366339fd0151706f6c6b61646f745f72756e74696d653a3a70617261636861696e733a3a4d6f64756c653c543e3a3a63616c63756c6174655f647574795f726f737465723a3a6866323033373061643435393266356536fe01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834663232323231343364323135333264ff0190013c70616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a52616e646f6d6e6573733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a486173683e3e3a3a72616e646f6d3a3a683533616639303539393039316264343180024a706f6c6b61646f745f72756e74696d653a3a70617261636861696e733a3a4d6f64756c653c543e3a3a70617261636861696e5f686561643a3a683365653561316131323233616137346181024c706f6c6b61646f745f72756e74696d653a3a70617261636861696e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866313636333231326563306630313339820288013c706f6c6b61646f745f72756e74696d653a3a70617261636861696e733a3a5f5f4765744279746553747275637452656c61794469737061746368517565756553697a653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68396163303664656364376365386637628302763c706f6c6b61646f745f72756e74696d653a3a70617261636861696e733a3a5f5f47657442797465537472756374436f64653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683931336330633637656264376263343784023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6834343263613864356230323031313937850245706f6c6b61646f745f72756e74696d653a3a70617261636861696e733a3a4d6f64756c653c543e3a3a7365745f68656164733a3a68373866653334633162646430633561648602386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a686530613938663634636432396432383487024b73725f7072696d6974697665733a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a6838643032653336393838663230326436880285013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a77697468647261773a3a68356132616238656661653863616435338902386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68376131306538393334366565356532618a024b706f6c6b61646f745f72756e74696d653a3a6174746573746174696f6e733a3a4d6f64756c653c543e3a3a6e6f74655f696e636c756465643a3a68383230396330333835353738653939388b02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68313432633464623838616636373736338c02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a68313233306136373035323634666631378d025c3c706f6c6b61646f745f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68313330623338613565356237396465638e024a706f6c6b61646f745f72756e74696d653a3a70617261636861696e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68366537356561343461323233623933338f0230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68303261306438316533363762323331359002723c285475706c65456c656d656e74302c205475706c65456c656d656e7431292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e46696e616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a68346232373936613034363162373466369102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834623562613035373762333538323938920234636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e3a3a616e645f7468656e3a3a683536666636613230313866623364636293024b73725f7072696d6974697665733a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a6862346562383831323936396539633336940289013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a667265655f62616c616e63653a3a68666439393364316630326534656562319502386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683762623336323737306161663166323996023870616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a70726f706f73616c733a3a683461303830393064386362653538633597028d013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f6372656174696e673a3a68323432303336666261323836393431649802723c285475706c65456c656d656e74302c205475706c65456c656d656e7431292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e46696e616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a683465653230376638346662653932363299023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68636239636663616139643335323766329a023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68316332303762333164646566326236629b02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68346237393439396231323763633461649c02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68396533383638383766316561363066669d02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68306132653738333830303862353863379e025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68623033343336373765376133336166309f02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837663932366434643231303066643231a0023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6835386635643265303333643935316431a1023970616c6c65745f7375646f3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835306461653162343632613831366164a2023b70616c6c65745f7375646f3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835353637653934393537323163336266a302783c706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a5f5f47657442797465537472756374446562746f72733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864653131623834366535383931313666a40292017375627374726174655f7072696d6974697665733a3a63727970746f3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a63727970746f3a3a4163636f756e74496433323e3a3a656e636f64653a3a6836383861383133323362316231303336a5027f3c706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a4c696d697450617261746872656164436f6d6d6974733c543e2061732073725f7072696d6974697665733a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a6833313138646364636533376539383233a602386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839623865313363366562346563643030a7023c70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835343231323139653938646265366231a8023e70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6837356165333838326663373736306265a902703c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637443757272656e7453657449643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831313230653565303337613233623033aa02693c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837613534333431666261363664343966ab02776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6863393434346562333461646133343834ac023d70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a7363686564756c655f6368616e67653a3a6864393734373734326439636130326361ad0230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830643762346131323662383133373864ae02683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a6834623836303634636232383230383763af02633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6838363030383839393538386666643635b0023e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6830396166316261313562633038666236b10230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6861333832623266326564343162366335b2029b013c706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a4d6f64756c653c543e20617320706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a5265676973747261723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a72656769737465725f706172613a3a6834633639363762326134396434333139b3029d013c706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a4d6f64756c653c543e20617320706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a5265676973747261723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a646572656769737465725f706172613a3a6839316338356166336236623166626564b40246706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a737761705f6f7264657265645f6578697374656e63653a3a6838373832653766616435616463633531b5024b706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6861633237663963333461303038316131b6027b3c706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a5f5f476574427974655374727563744e6578744672656549643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836663837333230326431373561303664b7026a3c706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6862626337623035336361373762383530b802776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6578697374733a3a6831316133613339306536373337636231b9026c3c706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6830316363626630386537633838393232ba0249706f6c6b61646f745f72756e74696d653a3a7265676973747261723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830643866653531313134313235663362bb026b3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6836333563653066306539386664303132bc023670616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a656e756d5f7365743a3a6837333431366434623236666263653239bd026f3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a6837316331383932343230626331303564be02483c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6839346630323431346332383465313633bf024470616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a646f5f70687261676d656e3a3a6839353963393832353263336436316332c002386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861336632613964656435666132376139c1026e6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4b6579466f726d61743a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f686561645f6b65793a3a6866656364663961333736626430343233c2024870616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6c6f636b65645f7374616b655f6f663a3a6837363562643263623837353632323834c3024673725f61726974686d657469633a3a68656c706572735f3132386269743a3a6d756c7469706c795f62795f726174696f6e616c3a3a6865386435633263323766333462376566c402533c73725f61726974686d657469633a3a726174696f6e616c3132383a3a526174696f6e616c31323820617320636f72653a3a636d703a3a4f72643e3a3a636d703a3a6836616633383563613266356162636235c502583c73725f61726974686d657469633a3a726174696f6e616c3132383a3a526174696f6e616c31323820617320636f72653a3a636d703a3a5061727469616c45713e3a3a65713a3a6835636362326465633666623437346539c6024d6672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a636f6d707574655f6d656d626572735f646966663a3a6837656534643864383762656437616338c70299013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6839313034633061666431303638353534c80295013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736c6173685f72657365727665643a3a6865333263323136346533376561343038c902456672616d655f737570706f72743a3a7472616974733a3a4f6e556e62616c616e6365643a3a6f6e5f756e62616c616e6365643a3a6830666436653964646439356566326461ca024570616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f72657365727665645f62616c616e63653a3a6835663334303235636538336461396335cb02456672616d655f737570706f72743a3a7472616974733a3a4f6e556e62616c616e6365643a3a6f6e5f756e62616c616e6365643a3a6865613362313632363835303431313236cc02763c285475706c65456c656d656e74302c205475706c65456c656d656e7431292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6863656361626565363535303963343031cd023870616c6c65745f626162653a3a4d6f64756c653c543e3a3a646f5f696e697469616c697a653a3a6835313564336632356335303634323162ce027a706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f7220706f6c6b61646f745f72756e74696d653a3a53657373696f6e4b6579733e3a3a6465636f64653a3a6837383532373233386335353163623237cf023970616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6e65775f73657373696f6e3a3a6836363830326337396263663566356537d002706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6836353436363562613535666563346266d102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832623437323463303665393137353435d20287013c70616c6c65745f626162653a3a4d6f64756c653c543e2061732070616c6c65745f73657373696f6e3a3a4f6e6553657373696f6e48616e646c65723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f6e65775f73657373696f6e3a3a6833363963653265656637663030653461d302386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838613331613035313165346462613537d4023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6839333765623564623535623536316236d5023770616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a6839313839326231373932623433666262d6023b70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a7265776172645f62795f6964733a3a6836393430363732383338393033346238d7024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6830633531626665343634633365326233d8027a3c70616c6c65745f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6838383239336536366263663063656532d9027d3c70616c6c65745f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6831313864636462356635366235306532da02446672616d655f737570706f72743a3a7472616974733a3a43757272656e63793a3a7265736f6c76655f6372656174696e673a3a6838346463303563376230306338636663db0283013c70616c6c65745f696e64696365733a3a4d6f64756c653c543e206173206672616d655f73797374656d3a3a4f6e4e65774163636f756e743c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f6e65775f6163636f756e743a3a6866316164336437326331666335653363dc024170616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f667265655f62616c616e63653a3a6835633661633030666562633362373935dd023870616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a6830633764643730643561633765656234de0290013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a656e737572655f63616e5f77697468647261773a3a6836633732653265383962373537306265df023670616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6c6f636b733a3a6836353833666239383033303762333734e002776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6830323165663030383161326637306431e102a00173725f7072696d6974697665733a3a67656e657269633a3a626c6f636b3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073725f7072696d6974697665733a3a67656e657269633a3a626c6f636b3a3a426c6f636b3c4865616465722c45787472696e7369633e3e3a3a6465636f64653a3a6861393030386330383265643534313638e2029f013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6863343037303664373365373665633632e30292013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f696e746f5f6578697374696e673a3a6830656137666532323235346436363334e4023c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6833386133366534326161373761373864e5023e70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6839653561383531656236363332323331e602703c70616c6c65745f73657373696f6e3a3a5f5f4765744279746553747275637443757272656e74496e6465783c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833343033353037306338306637653537e7024770616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6835313966346130633132333238636463e8029c013c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a44454455505f4b45595f50524546495844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866333639376262313764326666663432e9023570616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a64697361626c653a3a6864306566313534303337316265633262ea023c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6465706f7369745f636f6e73656e7375733a3a6862303330316235653165373838376437eb026c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6864306361633939366162326234636435ec023f70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6838356536323365393562646338643434ed024170616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6837343232303766356661373838323434ee024a70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6866343231383936616133333439306132ef029c013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4372656174696f6e46656544656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863386462663164313339346339383666f0023f70616c6c65745f6f6666656e6365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6837626634323930326533356563353634f102773c70616c6c65745f6f6666656e6365733a3a5f5f476574427974655374727563745265706f72747342794b696e64496e6465783c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839306433306461666163643764643763f202a5013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073725f7072696d6974697665733a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a6835656333383864613036623436663438f3025b3c73725f7072696d6974697665733a3a4d756c74695369676e61747572652061732073725f7072696d6974697665733a3a7472616974733a3a5665726966793e3a3a7665726966793a3a6862343164333031613232636236343261f4024770616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864626634666530386534393538656339f5024970616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6864303432633337666562626335363134f6025270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6863613533383361663434376235626639f702a3013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5465726d4475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861326538353731643235623566383863f802a7013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4465736972656452756e6e657273557044656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834353264393965386536323165323939f902a5013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a446573697265644d656d6265727344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861646161623033343334343836343536fa02a1013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67426f6e6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865363065363861323036393531396531fb02303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834613335383638383730363335376634fc02303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838306132386662623738396334626365fd02303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862346164353366363037623835653233fe02860170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7374616b696e673a3a4578706f737572653c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a6838396537613966306338333563636665ff02706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a683062663430376633346566336337653180035e3c70616c6c65745f6f6666656e6365733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6839323534346466363265373233323131810385013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7472616e736665723a3a68396238373961636165626636316561348203683c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683339323564636266653335306666343683034170616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a69735f766f7465723a3a683436663166626365336236646637636184034870616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a646f5f72656d6f76655f766f7465723a3a686434353766313762646332346261626685035270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a72656d6f76655f616e645f7265706c6163655f6d656d6265723a3a686636306566333436326130626233623486035770616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4368617267655472616e73616374696f6e5061796d656e743c543e3a3a636f6d707574655f6665653a3a68613630663534633331363733373763388703743c70616c6c65745f62616c616e6365733a3a696d62616c616e6365733a3a4e65676174697665496d62616c616e63653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a54727944726f703e3a3a7472795f64726f703a3a686365373632653961333161343166313488033d70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683233366134666530323262653531633589033f70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68373131393233643937353839383365348a034870616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68653135313837386539356337323030308b0391013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4275726e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68376164636239346330343162363133348c03880173725f61726974686d657469633a3a7065725f7468696e67733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073725f61726974686d657469633a3a7065725f7468696e67733a3a50657262696c6c3e3a3a656e636f64653a3a68373265336135643030373833646665628d0398013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5370656e64506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68663739303262323434633265633038358e0399013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f706f73616c426f6e6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68643937623262623439373636393566668f03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683131336239636134376230643235613590034a70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a683330336365326132336562303732306191035370616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68333364333066396165653038663532649203aa013c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686130653838303839633932323031306193032d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6833316237386536666135393663633966940334636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a686232343737386433333737313165643795032e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a686639393031663136393238623533663796033c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a686264373336356236666365356566343897032d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6866376435636530626533616338396432980334636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a683163316562383165313462373438346199032e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a68303563356337336435666138323534619a033c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a68313966376234363330323964313864389b03b5017375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a526177426162655072654469676573743e3a3a6465636f64653a3a68666635633361396436363937366337359c033670616c6c65745f626162653a3a4d6f64756c653c543e3a3a617574686f7269746965733a3a68353962323934626133346265343031319d03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68653166653835386665646631383738349e034b3c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68396363316266623438373363393537619f033b70616c6c65745f626162653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6839656463613961333936366537313435a0036b3c70616c6c65745f626162653a3a5f5f4765744279746553747275637452616e646f6d6e6573733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830613036616132373333613433396332a1034470616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6866626231363337306239343364656337a2039a013c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837633133386363646165313663393732a30396013c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863626532623665343961663834656638a403776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6834366530613532393863656334306439a503426672616d655f737570706f72743a3a7472616974733a3a496d62616c616e63653a3a6d617962655f73756273756d653a3a6830633934326266343562623834663263a603386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830313965623739363035653233313735a703386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830316162613161663761666437643333a803386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830623064626634643163663239306561a903386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831653363306332356266363963346665aa03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834343566343339366539666230333931ab03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834353532343830646131353237303836ac03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837353530363033633833313461373766ad03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839653937633935336265363732386263ae03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861386638303565353931313565393134af03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862396539633666356535663831323033b003386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864303131336134303961333439393865b103437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830303765356134666232653338393263b203396672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6865383432653861613836663738313334b303763c706f6c6b61646f745f72756e74696d653a3a636c61696d733a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a56616c6964617465556e7369676e65643e3a3a76616c69646174655f756e7369676e65643a3a6832333931386334666432313264363161b4034a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6836373965356262666262363733663532b50343706f6c6b61646f745f72756e74696d653a3a636c61696d733a3a4d6f64756c653c543e3a3a6574685f7265636f7665723a3a6834363231326261626638346239343837b6039501706f6c6b61646f745f72756e74696d653a3a636c61696d733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f72756e74696d653a3a636c61696d733a3a457468657265756d416464726573733e3a3a7573696e675f656e636f6465643a3a6838613665396631396634613730363639b7035573725f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a736563703235366b315f65636473615f7265636f7665723a3a6866356663306261396539363432353562b8034173725f7072696d6974697665733a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6833626261633531323935343463343132b9033e70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6833316635323065653666663535623836ba033f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6834366537393962613161346163373739bb034a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6831636261376139633239623630353163bc034a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6865346430613366343738313537633862bd036073725f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a736563703235366b315f65636473615f7265636f7665725f636f6d707265737365643a3a6833323339376331383139353333363133be035a3c70616c6c65745f626162653a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6834343362613063323231313634663536bf035d3c70616c6c65745f696e64696365733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6865616339316664653034643962303232c0039101706f6c6b61646f745f72756e74696d653a3a636c61696d733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f72756e74696d653a3a636c61696d733a3a457468657265756d416464726573733e3a3a656e636f64655f746f3a3a6832613965643565363365653866376630c10348706f6c6b61646f745f72756e74696d653a3a636c61696d733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6864323366633166313838333463323036c203733c706f6c6b61646f745f72756e74696d653a3a636c61696d733a3a5f5f47657442797465537472756374546f74616c3c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834613465353838343965346238663631c30346706f6c6b61646f745f72756e74696d653a3a636c61696d733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6839386563373762396631646332653564c40351706f6c6b61646f745f72756e74696d653a3a636c61696d733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6833656161623364376232653136313835c5039c013c706f6c6b61646f745f72756e74696d653a3a636c61696d733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726566697844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830616333393831326236393263626566c603763c285475706c65456c656d656e74302c205475706c65456c656d656e7431292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6834343532633562333330613664653962c7035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865643033636332616666363164323834c80343706f6c6b61646f745f72756e74696d653a3a736c6f74733a3a4d6f64756c653c543e3a3a6465706f7369745f68656c643a3a6831663766316566633766636339656539c903776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6861613631653036626161343739666536ca0368636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6830303831333266643465633063393335cb0380017061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202851302c205230293e3a3a656e636f64655f746f3a3a6830626534613633393632363763613236cc034b6672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a7365745f6d656d626572735f736f727465643a3a6831343664336537306536313334313363cd0399013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6837363331316132346532323164306637ce034a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6861343665336635343361653939313931cf034170616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6832396535323565623362663539356637d0034370616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6833376438613837653238373930383731d1034370616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6839363333646338663734613563376563d2037a70616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a6832313236313663363164336535613130d3037d70616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a656e636f64655f746f3a3a6835353230333864623863316137343536d4038e0170616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6c6c6563746976653a3a5261774576656e743c486173682c4163636f756e7449642c493e3e3a3a656e636f64655f746f3a3a6839653237623133653737646462313938d503623c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6833386165303336356361633964383834d603623c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6839396139333663636135343630393632d70347706f6c6b61646f745f72756e74696d653a3a736c6f74733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863353337303030323963323531656366d803773c706f6c6b61646f745f72756e74696d653a3a736c6f74733a3a5f5f476574427974655374727563744f6e626f617264696e673c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866373431373464383830356263323338d903743c706f6c6b61646f745f72756e74696d653a3a736c6f74733a3a5f5f4765744279746553747275637457696e6e696e673c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865643534373330316432613763393865da03783c706f6c6b61646f745f72756e74696d653a3a736c6f74733a3a5f5f4765744279746553747275637441756374696f6e496e666f3c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862356663643066333162663266616436db0341706f6c6b61646f745f72756e74696d653a3a736c6f74733a3a4d6f64756c653c543e3a3a68616e646c655f6269643a3a6830366663323439386634643664623261dc0345706f6c6b61646f745f72756e74696d653a3a736c6f74733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6837393136623439626164633435616235dd0330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6861393134313132323634623061323762de0352706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6d656d626572736869705f496e7374616e6365313a3a6834656231306362316464346338636663df0343706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6e69636b733a3a6835616232653136326462306136376363e00344706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73797374656d3a3a6839633639663130326532633561343838e10345706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696e64696365733a3a6861323733636433343037333139363135e20346706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f62616c616e6365733a3a6837353034316665383765653839656132e30345706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7374616b696e673a3a6838633864616630613765653436656365e40346706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6f6666656e6365733a3a6835363962663633666530396231626661e50345706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73657373696f6e3a3a6865613037613565366662363064336634e60345706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6772616e6470613a3a6864393335616563316433323164633031e70347706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696d5f6f6e6c696e653a3a6864613937346163383162653839393361e80347706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f64656d6f63726163793a3a6866626539376232333863663037386463e90352706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6c6c6563746976655f496e7374616e6365313a3a6837336439303731353665373632333862ea0350706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f656c656374696f6e735f70687261676d656e3a3a6862336362303238346166616633343630eb0346706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f74726561737572793a3a6831303431306230346431623632346666ec0344706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636c61696d733a3a6866303335663761333963656534366336ed0343706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f736c6f74733a3a6839386332353637353165386661616335ee0347706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7265676973747261723a3a6861346362353931656234333364643164ef0342706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7375646f3a3a6830326164306232663035346438656230f003693c706f6c6b61646f745f72756e74696d653a3a43616c6c206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6837633335663831303230363436313338f1035d3c70616c6c65745f7374616b696e673a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6861633664663964616437653130386636f2033470616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6c65646765723a3a6835383261663266366436336465626430f303693c70616c6c65745f617574686f726974795f646973636f766572793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6832366664386531646635303139353139f4034070616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6837383738326230393839393764316662f5033e70616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835353236656430313534383862343731f6034970616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6863386535616366646134323562633131f7034370616c6c65745f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6864343633616330363438643766343333f8034170616c6c65745f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6837613135363233356137316534363634f9033c70616c6c65745f6e69636b733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863373132393538353937613236383561fa033a70616c6c65745f6e69636b733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862323562373639616133346533393063fb034570616c6c65745f6e69636b733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6838343432643265313365316533663964fc0393013c70616c6c65745f6e69636b733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d61784c656e67746844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839326131613835353039336261313330fd0393013c70616c6c65745f6e69636b733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e4c656e67746844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862363937326331653862353534653536fe0398013c70616c6c65745f6e69636b733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5265736572766174696f6e46656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833653632656264666666666331323837ff03683c70616c6c65745f6e69636b733a3a5f5f476574427974655374727563744e616d654f663c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686139333534666161643461373665333080049b013c70616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686137363432393064396136623136623581040c436f72655f76657273696f6e820412436f72655f657865637574655f626c6f636b8304726672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a696e697469616c697a655f626c6f636b3a3a683962613735373265326364643261356684045373725f696f3a3a747269653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a626c616b65325f3235365f6f7264657265645f726f6f743a3a686164313731353032336439333666306285047a6672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a6170706c795f65787472696e7369635f776974685f6c656e3a3a68383639393339643136633461626563358604363c5420617320636f72653a3a636f6e766572743a3a496e746f3c553e3e3a3a696e746f3a3a6839353537363661393439366436336438870415436f72655f696e697469616c697a655f626c6f636b8804114d657461646174615f6d6574616461746189041c426c6f636b4275696c6465725f6170706c795f65787472696e7369638a04b00173725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a5472616e73616374696f6e56616c69646974794572726f723e3a3a656e636f64655f746f3a3a68353531616138343165643663366562358b041b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b8c0420426c6f636b4275696c6465725f696e686572656e745f65787472696e736963738d041c426c6f636b4275696c6465725f636865636b5f696e686572656e74738e0418426c6f636b4275696c6465725f72616e646f6d5f736565648f042b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e90045673725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a68353336626465663630313337303534369104456672616d655f737570706f72743a3a7472616974733a3a4f6e556e62616c616e6365643a3a6f6e5f756e62616c616e6365643a3a68373033383966303763366430626166359204214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b657293045173725f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7075626c69635f6b6579733a3a686439386664653566623035363930613294044d73725f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6e6574776f726b5f73746174653a3a683462393032646635623163396431613795044a73725f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7369676e3a3a683236306436636139343439323133623996045273725f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a7375626d69745f7472616e73616374696f6e3a3a686338653736346462653637623465353197041850617261636861696e486f73745f76616c696461746f727398041950617261636861696e486f73745f647574795f726f7374657299041f50617261636861696e486f73745f6163746976655f70617261636861696e739a041e50617261636861696e486f73745f70617261636861696e5f7374617475739b041c50617261636861696e486f73745f70617261636861696e5f636f64659c041550617261636861696e486f73745f696e67726573739d041e4772616e6470614170695f6772616e6470615f617574686f7269746965739e0415426162654170695f636f6e66696775726174696f6e9f0421417574686f72697479446973636f766572794170695f617574686f726974696573a0042153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b657973a104ad017375627374726174655f6170706c69636174696f6e5f63727970746f3a3a737232353531393a3a3c696d706c207375627374726174655f6170706c69636174696f6e5f63727970746f3a3a7472616974733a3a52756e74696d655075626c696320666f72207375627374726174655f7072696d6974697665733a3a737232353531393a3a5075626c69633e3a3a67656e65726174655f706169723a3a6836306331616663353539316639366464a2041d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e6365a304205472616e73616374696f6e5061796d656e744170695f71756572795f696e666fa4043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6832306334303238323930633538326332a5043b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6836363335643463663633633863643538a6043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6836373435393036666439333866663164a7043f70616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862386333663635336265626134643734a8044170616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6837313130303134643936663161386164a9044a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6861653430663538643662633834653236aa04706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6838626531633339316164626565376235ab04706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6838663664633136316465646566356263ac0484016672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654c696e6b65644d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6836316132656336386166646333393264ad046e6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4b6579466f726d61743a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f686561645f6b65793a3a6861636365623438386631373237393561ae0484016672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654c696e6b65644d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6866333266343634376565343936356564af046e6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4b6579466f726d61743a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f686561645f6b65793a3a6831373863376134633732623930663632b004437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830613161633334353833346165633735b104746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6864663338363036393231306362626635b204746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6866393636396130663933623330393736b304776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6837383732333166646234663336663437b404776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6863396566306435396666633638346331b5043970616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a6865613364306161656134646366616131b6044270616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a736c61736861626c655f62616c616e63655f6f663a3a6830643630663932386661663834366366b7043570616c6c65745f7374616b696e673a3a736c617368696e673a3a646f5f736c6173683a3a6831336630666431633538623264316361b8043470616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a626f6e6465643a3a6834303937643962306335306566303063b9043b70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a7570646174655f6c65646765723a3a6835643738616633633035663339633938ba043c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6866303034616361383766303032386137bb043c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a656e737572655f6e65775f6572613a3a6832393564353235633637383261383331bc043e70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835663335333161373865613536346261bd046d3c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563745370616e536c6173683c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861316166333363656639336435316133be043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6837336162353263353139343831636666bf04773c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374536c6173685265776172644672616374696f6e3c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834383063633736356264663564633238c0047a3c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637443757272656e74457261506f696e74734561726e65643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837363066663632363032653962333932c1046b3c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563745374616b6572733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863653537313264663539623766393461c2046e3c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637456616c696461746f72733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862633365663339366662623537333739c304793c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563744d696e696d756d56616c696461746f72436f756e743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862326661626365333964636332323663c4044770616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6839326564356438616136383362663062c5049a013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53657373696f6e7350657245726144656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865313333393137303433363635326637c6044970616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a6572615f7370616e3a3a6832393764353332646462313961626639c7045e70616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a636f6d706172655f616e645f7570646174655f7370616e5f736c6173683a3a6861656462356665333166366139313232c804776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6863393538373963393535643533373364c904776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6831643437613363613464313239656435ca044570616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6833323762633966353735663538633938cb045070616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6839613334303039336335656264323039cc049f013c70616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a57696e646f7753697a6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862366662393166393066316634313362cd045170616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866313963626535343464616533343038ce044e706f6c6b61646f745f72756e74696d653a3a6174746573746174696f6e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862366463663936373732616231353132cf044c706f6c6b61646f745f72756e74696d653a3a6174746573746174696f6e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864623532633830396639653339643332d0043a73725f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6c73747269703a3a6838623365363838333737356439653138d1043773725f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6164643a3a6834313932363039613363303231636461d2043773725f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6d756c3a3a6835366332626634383063346566383931d3044473725f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6469763a3a7b7b636c6f737572657d7d3a3a6865656538633661386366333439313565d4044b3c73725f61726974686d657469633a3a62696775696e743a3a42696755696e7420617320636f72653a3a636d703a3a4f72643e3a3a636d703a3a6836366238623565363864346262303437d504303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6864336166303632633739626565376539d604513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6838613131363331663363643635633964d7043d73725f61726974686d657469633a3a68656c706572735f3132386269743a3a746f5f6269675f75696e743a3a6865323965356566323962613136653836d804323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6830373461333161653064336137356539d9044273725f696f3a3a6c6f6767696e673a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6c6f673a3a6866353239376165613937386438666162da04483c7375627374726174655f696e686572656e74733a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835303330313663633833613537343038db04066d656d736574dc04066d656d637079dd04076d656d6d6f7665de04066d656d636d70df04095f5f6173686c746933e004095f5f6c736872746933e104085f5f6d756c746933e204095f5f75646976746933e304095f5f756d6f64746933e4040c5f5f756469766d6f6474693400550970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105727573746325312e34302e302d6e696768746c79202831373231633936383520323031392d31302d313229", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b482d7d0ed7ce9120a7c1e2759f64e8d5bba9a0ecc5393ed70518ece8ade7c4b9b": "0x0000d098d4af71000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977671636ac6d1ebdd54d2c3096e71130c79a630182052427e3b8175336634f663": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9ac41ccca21a3f2433027c0dfba8c98d0e897f6d3885a1574b9ca27dfb5fe7d": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339761667e34990459e5ae02af8b6b7e4773e478fa4bda0dd10d7b055cc66a82d7e7": "0x00aa8e680e0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1c99876c5e2c0846232fe3e31bf253ee30d545ec15911273ca9eed2ec696601": "0x00aae20ead3e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a52b8a0f88596b502b2af434bd8285cbd292415e50c37aa450da04bc447a5eb": "0x0040f09bbce108000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d5244f1d0c1d4efad45b9b07ae00c5c357815a7a4b1d54472b0fc88379bc95d": "0x00da3a60ac3800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c3055d92396a518ebfe69aaa049df702b160ced2edba85b1dc5ccf64ae4255bf": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d32c9c02fdbd6482236b8854f76b6d0e489b072047353054206f9fea4e896a46": "0x0046240a010300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975fd57afbe7003217f29f9a10c6d83cbd10e55c6f1926c3938864e40d5c65eb50": "0x00582f6605815e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339719a7e9de70786714521ca45ade3d746814a657a163956abe950a594bf2d6bab9": "0x004e1d826b2608000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b30565240cddb1d2ff58c014ea1cc6e0859c68625d994d9f84b6b2859550a4b": "0x006ee0d6c48800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea5b96e54f7577158753eb6572e43091b4abd60f2bd09b0f0fa0ce8b1371d891": "0x00c0fd58439600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397115ade7dc1611efbe66dbdc07c8763f1afb33ed720db2053e1b18b27ff90b214": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a93eeddddfbbf2b276cea0b161216cd5e74a7732e11dabc41189b0091a1f73b": "0x00e0c03b49b506000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e300e48673d6b13073527a20f3e0af735bf7739a7e954e5d7a4163ad4b0be696": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973d650f0807f3988aca0e45a42ee6d286f717f94604144da5ca584e78060ae34e": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d92601d917512822c6f525c805fa1f3df6faf0144d1a41ed579ba69160f4b487": "0x00f031b1450f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243f38e6f7e119f073e779d0332617609da1e6280bc277cc857bf53341c7e2930d1": "0x00b4606a31e0a50000000000000000002189e04906000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a3d227ce75bafe6872e2d7c30b7e2a1021e6c56a6059fd49534328e09ad26cf": "0x006e6c5ebe4d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974681115db6540f1f04fe30ea7b7f98d6d90575071becb20e80bd48671f6c570a": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c39e7044b28695d555cc7fd08899aebb2e4f930605e751613518a5e18b0a5d2e": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744fd32aa3556d2a6b52d2e3905e88a5b508ef007f5813039c3ba740f155c867d": "0x002a378ad65b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d3033ac8d4b43439e640b3b3d48426eac4f1a3e479b8c5548665e9611bfdb03a": "0x006e35f8103500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df55cbd1c8513f158816f85118124483c789e8afc4645b244c5c5c906db7b1c7": "0x0054a6b6228506000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b49dc520da360c6cfae88229e6f44d792083e74d431accdb3d77edefb3695a8bb2": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764a17f236d6e2bfda920eceb61f97b53f24efc7e598f093f1df1753f8d85963a": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975458a965c90791988da9998b48a292dfa6be5ee5cfb5d20f2414b8d9b519d83a": "0x0018a2191e1300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b47e04b920e66f97ee56f3aef9106f0f0a6135c2bb6e89b4cc6a63ec8b95917f91": "0x0040b10baf682c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b39f9650c20719cce03a313fdd6a2e3adae3c18001253b8578027ef9d2c7fa4": "0x00ba51b4360400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973b31429aa13fa8400b666f6d25bb3ee1ead8aeb180ac5587753b74262d44c7e6": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339726e649d85e4a4035a743002eff9740606f1ecded199dd21dce2ce42f1ed533c6": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397734a17043b5ea921b582763d16428df9fa107605825da125b5689b426a224384": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e8b4bb344efdd8b68d3f4c7f4ac406c65d8c5e550851169b3677d29d34e60c9": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e86f242de9fd642a65e41c69c09543aa60841a060d90601bac4e859c94f356c": "0x001a4b6b869603000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972dce15ca943b4c535d2755ae9c0740dcbce7fdfa69af298fb5a5f4eef7960a89": "0x007e313b741900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b3598947e6ed965466685f68a77c28385a58b0c499abab6f99cc8a92662af9e": "0x000822b9df0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ca5038abdf0997d2d336ec7a491e615f4d660d11bd6b6cb5c2e1ed8745032bdb": "0x00ae0053919e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977da6d4b371ba81b11922456bfab9f01b6710498e122acc5b3a062775e1f21afc": "0x005a3db8ca1c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d872824382d7d0ed7ce9120a7c1e2759f64e8d5bba9a0ecc5393ed70518ece8ade7c4b9b": "0x005014176ae14c0000000000000000004d6726ea02000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798033b53969364066b87822d813bebd30728b79d25017214d3c3d61bd7d60845": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339789b89d036f2f5a168b129c14319cfdba35c12b4de079b48a77874ec95b00fbe6": "0x00425a2f59a800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705bf4dba2fc0d3a46e9feb0a93128e69d1343f01f6f76adda58d2df619aafae5": "0x001ebc12440b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700777593d608cf1fb365f5121412687ff7509219848aa969da17b2bdb2500b66": "0x00ca91bb010500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd766a279e77d75a40555fd1a595a8d0eebf45dcda1d37d3bff7c542bebd9ae0": "0x003036d4980900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e7512f4aac2fbe33f03554bfeb559ea2690ed8521caa4be961e61c91ac9a1530dce7a": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533245a6b368f1f5b619d140c038534c88f2e466dac9efea3c175ed8002af0255627888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331de428baf9121ddc82d74517532355588094093681ce61ac3324be5a6f8451e0de88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455331088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553308daf7daff12d20c135d30d95040044a41b3839530c00b0f8ae606b9a34f7f8a2588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533066a52a40a6017ab19ed03e55e380890dc56ab547556311c6523d42a703cdf2f5588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455330088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ff88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532fe88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532fd68e5ac45776105b2219a062b8501857f2a82708c9a59c24691de932362a6f02b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532fb88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532fa88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532f988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532f8aa339be97e8b33e2eaa4bd2ae50e48d238882841f2a1caf34da47b021880443488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532f688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532f588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532f49e1f33cc9f2d6793adb7b951d8a0f9cb3df1431174403a1f49428e876c995a6a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532f288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532f11e521cb4a4d0e788b8f9ccc773070719f576facaa1c5e73281eb9c0835d9de6388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ef88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ee88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ed88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ec", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff1f6b696f5e733257c2e8e74bffaa58cee1458b781265ae80e4fce51b41e80b": "0x00f8a4ceeddb3d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ac3e37a121c22d1a11a3ce928c8cbd6a9c871dc42ec4df6f70d0f199379a3e7": "0x00e8578c8f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339779537b557100c9a92bea9603f575bd6c06806cf0acd0587d4fe07da4f9709cf1": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979148dce83378ee8df7ee746cd9fd3cef880599f0d3f738743026ffb3313fd176": "0x00827e537c0200000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973cf4669cdd41d904f4145be4a6ddc881619a5602776b5b7a57b1e655425e34310": "0x2280483e7614020101d7e03e0019d5d0c082ba9e23fc43a2a36b261bcfa5cc3b", + "0x5f3e4907f716ac89b6347d15ececedca5579297f4dfb9609e7e4c2ebab9ce40a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f95a4fc93d2953fddd1d2908d57d0b1b31057b93a4cf38d0b0c45844b63d1665": "0x00fe0f93981100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ff94cd3043734d2b438d3a2a7ae110c9062a6bb98b906b806a171748980b27f": "0x002af235ca8602000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c01ff34785ebfa8b74f56ae1462583a37b9775b60486f65e00a631261e1909b": "0x0076cf5ffa7b0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e2be65b515f0b5cacfec3c552d121cd28e452d2b580fa72771c3f590edf453fa": "0x003e8bb26e5b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b89905c704657034fa62deb0d953353f50a4ddd2a7435b530297e0f1adcd73a": "0x00ccf483926900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970eb819ecd23c7864a7aee3288ff28984c84a3989e3468cc8739f8b4c934df72e": "0x0098983cd6fa02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733e49b51a89a4f03b57208c49010ef4fb78083f09dc8e454535ed7e86b52a1a9": "0x0078b90cce0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705c4d889f8a3042e36670d6460412701d39cb2c13733068432bb6cb2e5ab442d": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339758c5ff3621a50d12ebf945ca428496b3cbbc2eac6dd91660d587aad378db1c08": "0x00203d88792d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746c4f1fbf545af69694a4b91d91ffdbb3c0aa59313885f645166835e703ff160": "0x007c90bd712c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397854beabb850b1980d90394ad5e5b2b7e959a95328f883fc05c20933f7f7abee4": "0x00e8912de00e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea02e7cdb65e977fae1bd15e5d98abe96bdcb1042e1dd2a1c8e016ae376a021f": "0x00d422207f0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d487d1cfd300010bc4616f567abc94b791283cb37c84523f16294552fc189b04": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ce72b1965381ccf616fe86316f86e0c8c1f2cbffa7f273c4ada35d0651ee52c": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c1c5750ad558a38cd1fe783a745bf80ec9353d401a96de613767d28cc4fb2f80": "0x003036d4980900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4de552eee2fc27186e728f2250b6bd071098c9ed7ea329b0e81e6f967e0110201": "0x00580efad5aa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339766957f862724ef07bb9db884c37cb744d23ae299bbea696e1bb682d078114f56": "0x000e103af39f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac8f469c598adf0217fa9b610052de1e0c9e16e71aaf0d4f6f1e8c498081743f": "0x002a07e4311300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b49b2c66f6502344f8139a17f69c5ecc66b526c3806effd20058b03c5ef0faa3b4": "0x000082dfe40d47000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397598cd42a4149614d2b0a4ec474779568c753279f62ec072620f3842672da0bd3": "0x005857a4df5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4f65aaec46f126247a387f4f79c9289611e167f1f298a597eb4aa2f6f9c4897": "0x00e0b69c4f2f2a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339797447b036c4e5775116ad453ccfabdd725d4cc49fc7172ec0765d9cdfcda69ca": "0x008aff50bf1a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b91db8dc654e32665b5bc687b074d1828d6839f76ab78562b0a9e38beaab601d": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397896d0eabfcae6f909d783568dbed1cefcb7c83a9b1c38c653606ae731fb0a856": "0x008072f2681600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1d08fbad58c10631bf00b995e37d0a6639d2d09478222e8877e401c6229b12a": "0x008267fa158c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702ac7bf8afbc820f2dfae2821f34387ebfa43419fbd0bdde5a423b5aaea3c052": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9b6e93f06f81ccb0eefc6aaddf4bd4c006887806f50a83230fdb7a3f7c5fc4c": "0x00646ce1a00200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397197564d03acdf71f90b949d3ca001b0cf8c78477d0a4483acb57e436c99549f7": "0x00eceb5f0dfc3b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976907a693f9deff845a634856a2234588bf407fc4b12a3c58c3b80100990423cb": "0x00f6428f3a2a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dae0d5cbeb2729f77ee085890cd7b20b4f30d049a061ca2e2ec984db94edefa0": "0x009e5cf258aa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e8bdf4066ac3511663eb54705d815f4df636136279b7db0310b7d1a0d9f24e2e": "0x000c439bb19703000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b8e7fc3befcad11eb780e8d8048fed1e16bb6f01b3d9dea3ae343f907a1a5af": "0x0040b10baf682c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973d99f87a0f1830352377f4612d0738d1fb1c76fbb925cbd869fcee61b50ab7fd": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d34d5e6f629a188fcb1560e2fb78297cd8119d33b5498f0ec17eb7d7c2fa9e5": "0x0066497f817f07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f32ed3921eaf3bac22b8b7351ffdbf28c72d056c501d76a9fd64013abab05f65": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e9538cddbc4f7ac2c6e861737eb4117a233c7027707ec04d38a9cc8f7821fbb": "0x00901f44ae003f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f78c7bc16bc5bdf1fdc4c80e99d94fbc5f9f290c8364daa57ec95fb0965ccc02": "0x004e1d826b2608000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767bfa5a0fab48893f3f570a5f909e238c984587f9916dc2ce388187bdedf52e7": "0x00c453c2e12000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339752a26ae49c8bcc421f389fffda53f29a646081f5d34512863ee3f9adc33b99c7": "0x005880abe94f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3921d5ac95af7bcbfdbf8401693caab25b4ed34791bd61c1a41316ba1fecf3f": "0x000c58bce01700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b9b9f7d58696585f1ceacfc6963892898a3b7072990bdfd7af767e1af1a25c27": "0x0042224efe1700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b47103941c7d93ac9cee1efd10f90f56b81f2083ea8e8b75c92914343c257e67b4": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339772ff2eef28878bab3656ede7298b91c7116faf4c780eaa76d57a1ed6d0fda7f0": "0x00f6fb67c47c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43620f81fe27dfa6ba47ad798b27edc1c659a13408a0f6bf2391bd7429020608b": "0x00003426f56b1c000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43ecd5b1ea87f1ca04360c76ef565df360eaedbb19dc38032889683032ab30bea": "0x00946f32c2d301000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46ed432ef91ac052f33dd1204fd1a3231ef3b7f9b56aafef555a9b7475b8c39fd": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fde7f62d60690156ec9068aefb7288d4d476ec6ca02fe13c939f35e65ebc9763": "0x0026f61e763a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397840ae2eefc05ae337de2452acdfdb4a1412a0963649ceb59d235c30d67bda606": "0x008ace1a761902000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c0f21c8a78b138a93128ee8b946198226a703dc2c64862f27b31b2cbecafaba": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977a4f6eda0796c016cca5c4744c16eb11953922bd7c2d0e81dd2017434b2c74b5": "0x00e070e8b01000000000000000000000", + "0x492a52699edf49c972c21db794cfcf57ba7fb8745735dc3be2a2c61a72c39e78": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705af4ca7ab5b5bb4508b74b5ef125e3294f1757baf04825920eef2f2330e2f97": "0x00465d66090b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978861917955e1cacc13716d0a9c84e506c9998f9308ebaabef17c63b9156d7da8": "0x007ab0403b2c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7668e31deafe93ee7f0f2c5d69cf3ece8bce98b3a884c27b103aeb218f50b9b": "0x009273630f2300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ecf398321f1ea9a65d32afdb32307fb3e7c4d83c106b125acc2da1e5c8a90ac9": "0x001cd8b7510200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769ff0cc44aca8c694d1e1b8dd5d3cc82f7c614f8d8bc322ba35a603e1a148ad1": "0x00947b88965300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339749cfd559ddf277df81cf714f6a29b71d8b76919923e8d4668237a6ab31905a36": "0x0094e7521f5300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43800c31b3b5adc4fa9318517ca5ac2cd4e4a2e7bd5467ac709dd55e29e294ffd": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b3918837379b55dcfac6b4455aece06e403880a2fee590edfe3376aa36ba41f6": "0x009a32d2642900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975113c147150323541ef6be7620e10f5d85bc4177f715c1c3ca5f78da56777640": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c51f2f6c3defd2513db6fe017b23f8f6b4dd6da69e57cda76a7937c6266333c9": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976866fd74f02b4862081e1d5026d57a2c5fc6783a3db2eb317a18e7d8da104323": "0x0052dba5770a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397298f6a2c18135b157a9666f5af3395db967135bb2d41ffbcc81e1589da973a30": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f10adc8239ec7c9c75993fb411f915446dd72078cf8fafd7e8b006cb9f88aeb": "0x000e064d410300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f784321a4cd932a42901f29665d2218a8417e8b1df6af53e4838311cb79318ee": "0x000e0675acf100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8eff0c4508c1d32bfac46d2b6f32e894f63561ea579d7ad947247f72e6ca995": "0x002604194c3900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b45e216d3f400db7137984cc7a81d4553c7de1868e8ef21a66fbd34b8b836b78f7": "0x0080e03779c311000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397893c89d9e0fe9630f52c912e7905e5583483df10430d11723eff5bf3794a6923": "0x0062ebffa05700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2a7ffe640ce81a1c4d6ee4b8961e47556d0ddbd6c683e11780217db248d4679": "0x00a47a85db1001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781c07e03471906bdf2f1c5f0ab02a7aaa22beb31a00bf5cb51a94c352780152e": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979da9216982fa7476d4e5e1571e672d050c8c2e9e45c1780b787c1e903ca689b0": "0x00465a9730f100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397362f19f530f0206de88037f559072f1027a9d722c45ad756d80e625b0eef1267": "0x00e849c81e1900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792aad0d540ec94c5c4e722b3523ab900001354f06a241c9e0d5158ec5916076c": "0x00ccd58f146b2f010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974012f98fa3b2ba561fee4465ed85bee0c25381aa172584c56bee0d121a8e4c8a": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397999110adb233d8c399b930e93494714f93bd4951df407a6002d95f4ccb178891": "0x006cfad2dc649c010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bddae69348a3ac647f704fa679a0f4c887cf57c4353a87cfd50ad810cfa90e90": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397acc54154646d6088b18dfd77a1014e2fa158cccc8c46512a312ca1feb5d67882": "0x0082357a0a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700777ef98abbbd245b7f226f44f05fb6772d2d72f8313872e6a0adcafe358342": "0x009e4397200200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798f44c7267076dee66820b501a927e99f52678576ec2856dd5f726ce1238392f": "0x008cde7f2d6906000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979fdbb237ec67e2ae5c6f724adeeb7828afedc40d84f7eba7de7fe08b8856e275": "0x0084449cfc2f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b455440c8358681d0d42eabc8e59bd9a32e023cbaee84912960bd56af501c24e36": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b0dd1291928a18ab72909da7f4ee01effe2991637397a9ccc330e2689701a548": "0x00263025941300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a998199d10df5046f7db080d882f39a8aee6f3c80e6195b21bf73dd9dc96c7d": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9e840bf2aa607e057368e0d81807961f417fd1de5252647f8c0d22d0fcbc590": "0x00c0e1d0612100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40c4a4d22bcae4a833da8312076262f69476480b27467d4aa3c11cefd4084f0c6": "0x0056103f218725000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f313a55adef03ca6e6b0b6915a1dddb1b7e76d2ddc86d9ec8e7bafe65562f29": "0x00f424648f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339759b07b7a13cb3a327e6541a27712a4addbef6c8ac382332a6b40600d7a000be3": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339709d198430cc32b7f27e35c99d3ccbdaf242d787ff78e9387d6e17d0734e3f943": "0x00181b6acc0400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b443a876172f28175b3f1cf704f9e51aab77d3add14cb240c1b3e30fc1449ffe89": "0x00805cec442900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a96200988b43c0803e46e478bdc937db993d9d90c41507d7e71af9b240d31051": "0x00de0f257d5781000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f927e749b712a31c0fa5841429733b79d7b8e8bf7a4c55af786bbfd49c387d2": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a5d87064488aa324f302b226b7002e1c5312cd977a223238611ae2f8068f68c": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774d5306a4cdd52e1307bd5bd4cb864494c10b0cb84f410d9f8deeb32994df18d": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b25266585abf7a1e223c109fac5f86a63f4c8d0ee2e09b22ad19a311f46fc33": "0x002e79c7b73c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa9a9bcb8a7423fd058b1cfb5fbf9465d73e42a0188d8e501acce64eaf4ad59c": "0x00c0a31bf09801000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da45a82ef60da55c1ec3d157a7cd3ff4c8a752f02c77b747e95addac9e589561": "0x003219bbda0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef9e40bedebe8947251fb0105ea1e37bb6be81dfe4489aa5dc31f034ac724934": "0x00c27e3a434100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb27abe92fd322f823be770b1925f9d631914e656743e898467b4224dd094a85": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d23396cddb8eb4e67cdacc09377f135b025099feed98f4d14668a13345b9a729": "0x007829c1894d02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1f1d36196595d0a3dce2d5bc087355e1aa4e298d20bfc7e714d6386e0091111": "0x006c564955cd08000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397503da82fc2af5453e97490bac96d885b7ce0ecde3b8010a96272df3fd0c1bd94": "0x008c0d35660200000000000000000000", + "0x3a6772616e6470615f617574686f726974696573": "0x0118316ecc2b9b780084ed10ba7b401696afd2106561b8192c3d821811eddc85be120100000000000000411fc1a5c88ab2bb7f63b23b15c39983cf38f3ac2dfd9c5168d5d7ebbad835440100000000000000d548c490ff6e728ed093a7406711d76b2c7d04c77277fb88b1c3c789fa6417370100000000000000b98c930b9b4a782ca392580d02ed1185fa3214be9e7669ff7dc096d17d286bd201000000000000005ce30d8c007d0a438c92c37a660b7709fd1ff3bba79c6c4832ea4107d266e0010100000000000000f45475c15d447317b7de38972656d207e362f7fa4429d665ce10a9da2ace254c0100000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397445f13a50ab1768f206f5b81d086d3c4e641dc31ea94e46aaee30554832d5a20": "0x00e00d9e260c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979758e656183ba79264d951d69d29a311f1b62f030c5c73e0cd51cb2c6a556262": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397869fe0ffa94376a9bafaa7e46a314b5ff0aeb1e485bbdfcc82ce3db094ac37fa": "0x0022afc58d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339715d2669cc661cecdee75537ce806cc75e268b9a7d84ff3daa02f6dc00e3ea089": "0x00ba0f07985a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339776a90a4d70fbe0c5a0fd199b1364531be573a3cae3e6b6589b37332d9925bc1f": "0x0010a7bc491a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c5e5db52c2f9abc54143d14fa7b63cfbac0815195860858f99e903e7455646e": "0x00befbbc765800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d60684b60090b1bb22baea329c5403c93d6f50a22ef0236957d9272147b003bb": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e28e339db3226e9c610158377032d299e4c221fd5b39697626db8994153a2a9c": "0x009294f9fd1201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b948a0e2060aee325e33e20b02890ff6d1f917fa9228a2b3323da451b63cc8b": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733a07938bbdc73efdf476da8bf8d60af72f28ff19729ee57d57ecbe3eb709e6b": "0x00927581d50000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b422d74fed4421b5426c84e3aec1143a83a845931509bfb17c266bb4932934d25e": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fab33c6ae0efd7f2c424924c73ee053e698f39902a8a951504c29876376ed55a": "0x00e47f23dc8200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978b4e7b1ce77602a1c473b343427e7ede04769f763473d8f86e53d6898a3c611c": "0x001e2ac52d2400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44624d5cce1d75d31071c7003edcad1ef6dc9027af9ab7f885bccd7545733300b": "0x00a4289f320700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397306e86da3b6a5c65d443b23a6649c910ddccc36f94d6b356f584dde4f82e1e59": "0x00148b66da2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a422dce0a81e403db6850f3bc3b6c310782995dd683a2f55ece7b1b9bfb60bff": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f5ea1558f10716a5401d5f9c791a3a7123fc16e4d3e8b676259e434c091274f": "0x00f424648f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b95e55eaeaa99686c477648ce51728e3af183eb3636606c1d66209fc89c7875": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339703aa3baef1451c43582ee036693e1e1d851d6af7e50c9530e681bc17cd0536f7": "0x009cc589734803000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397398c57f32e9f6783d906f0e5692edb82fbc8a3ee2813bedb5e6c44065949c0a4": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771c411b8443e023c9d9b54750e40e19f40c9d9c79e6956dcb86b2ed718de1e56": "0x007a2120ce1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5caabcf774d24a5e4f8e3ff6b9671055cb94df3051ee174b1ab702d831c89b8": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769dbeff8f860954c118681b73c0b6f2fae29bd828d9835de9a2022cc27a58d88": "0x00a2ed9f605600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748f888815aefd10d9c17d36c85c0177f1018828644c24802c58cb8610a3a6d07": "0x00204a736c3d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397751ba57af7f80305a44c441d6c536169b9d214b891663400df601f6cb7dfd38e": "0x00564aa0b30100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397405607a92137bb895b8763a79dd425d6269606363aace7da137b4845d5077ae0": "0x00da5001030800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977bfa69ed72b8e2aa38dc4070351a42ff3e32f2ec41cfbcf173218b51a33255ae": "0x00dc597e469902000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1513c640e2bd98200f8474bd498ea5dba83e1bf10ad31d0babf511c62fb42fe": "0x001442866bbc00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ac6be94a01493d2005236a9ff343815717e1d8d35a24556004e704769845bb0": "0x00fe2d45b7a603000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976dde58c5574e157ff0158d0bee26c1d758e274922bfc8b10f774c4cadda32761": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac0da986fcc45b839829efc91930b132eb80c7c9f643771f850b63fbd538cee0": "0x00ecdbb3710d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397beebcd787fe172c7778ceaa9675fc9d2a460a9735109e5615c33334721082d7b": "0x00942d64b5a600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ccd07aa13473783cc5f1708a0e7d5e2e231d7da7ec5c7e16c06315ac18a7803e": "0x00c0b6403b6f0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d9c4b5502024aefc02b3ad1541a51178bcf55c7fa419e3755f48d271653c8e1": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a6b83b32af8ea92743df1fe346ab8b8b512e653bac49c8f1ba79edf7fe15b77": "0x0062844325d300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b145d3d06afedf6d3297055c7fdda2ea44e33e0d6d573b94b1386edd1684058": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f67001d5e20b77479af66d015adf408ef9f382573ea95d7f63ae83ddb8517e6f": "0x0056b961800900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397805b7b1b819049494a689624e0000de44965d360d5de71f296882695d9c66046": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975afb598b91feb1ed9d63d6f78d66b03f9d18f1e002dc0b5f58c3a1c69d340836": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397302c53c50b6a38acb8b344c56e5f872a52394ca2402733d8c72deb0bf954f271": "0x00920d70945f06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751827e01e708a0a9b81387229c9e388ffd457584a493a92fba733c493a8d135e": "0x0086319f582201000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4137548c71edcca875d889aa0b278b4961caaa01bb40cbff030dcf208d8086b58": "0x006cde705d0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c9d5e42bb7e99ae5924e3bbf3233223a9408a0447c9aec995829bb0ad4d616a9": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c4f9db385f894a5158a21ed3d94247dbbc5859c45ef2b7e1f3a364f22491c2f": "0x001cd6fe584200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971b6fe686d3b6660d949641f415c551ba6f019cc3723294eb198fbc13f78a66e9": "0x008e55b3603a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397488d554f733101cf9326fe71875dec746230abdc591a9d448cbe03ac8bb4edcd": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea83de81d97a98402635f3eb765fde5e1fd05431a04c4df0beba0485c8363b4f": "0x00dca897991c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c3a15f0ab0b851c9b612cedcaefe672acf182cc83e575aae72e62533d694db58": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339735f7538488a779df3195981fe05dc0765a41e554bfed5c5625fe1260dcc692a0": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a9c8301d4cfeefd77da70b8fd4ad62448bf8f3243fe07bb546e2c788a0d7ee57": "0x0030345aead918000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ae9ab57551a139c6d414a53664eae54dffed79b3c3dcf8854429367aed279c2": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f11af1a73d1428938849ba8db42af3817b29c50c57eefbfca8985103d63f3f7": "0x006c9bea403b00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b432ee3634136384775c0e9028b914ad184b8f81bba53084072fe7e6f9b3406ef9": "0x006a0b9bba8400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f5c1714a4ed058c970fdd6e9e3696c8edc4849e185e25a5f43dd8694e5ec3ab": "0x0084449cfc2f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d0afad14c97667e9075e2def3c51bb050276a3f3147b8ff2c985d5e02ee6c3e9": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eadf023c0bf67fb69c6b6b2e0eeda5ed7d171b26189e5ad3f7a29a546f2f58d7": "0x00d8dfea53d67d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397797561f723f5f5a823b1c6e9564912e2eb744d076a6ce934966dbf382d3330e8": "0x00427f58a79b02000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b45529f46eb156dd9f4522ba93e47c1788c281e4fe0047799f35d52cdd3912e522": "0x00e4b0a9fb6000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c0e2132638067565cb814f7e38fa60a769197c2811c597389139edd53e67dfc6": "0x001a5524560200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec88647256ec1b7ccf461a2c8608b47f02fa7e55e65a5ee444c71e6908725ac3": "0x00f43e5be3af01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971dd7051caef8ba0c977bfac03d8d42174881e96a15a8c392ef6b2868df640d1c": "0x00daf69b441c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ca7495d2cb1bebc0a3da05ff93ba982d22008b16947a0f50c50d881136a64a8d": "0x00ae670f0d2300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781af1d01483df2ca27b83022ece1e295b383d29d25cd9ad3d422463d2808001c": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972aea24c663637655acfbe5844ba7b946887de7299183b562b32ecb39d0dfda9a": "0x00806aacaf3c09000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b47a1a7315341d9721845e161556656fa49e30fbd0d2116287f4396cd69758f236": "0x009e65b9ad8307000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb39fe6329cc0b39e09343a73657373696f6e3a6b6579736b898a265f07867010402a3e0cc63cd48957e62d5e565df9d7c0360730857c5d": "0x316ecc2b9b780084ed10ba7b401696afd2106561b8192c3d821811eddc85be12ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc1677ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc1677ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc1677ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc1677", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0fc23e46a55a3c49ae6ace509d1709adabf081a125c31b54f00ff7fc8ebee34": "0x00904accfec908000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339704a0e8ab3c0815670df25efc9ba7a363a3a88da911f491362d3135fd7f05daf7": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc98858f8897216aa66f628d5e20806f9f8f9c190eec2aa8084aa2ca0b95c712": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a99dba37bc5b00f09133360896b206c2234d44ac24cb5f3b678108feea6ae383": "0x005e737e69fa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b470ffc2ca0928a7f05e0a579ea5edfb7113a3c9bb7f392204a9f6e6c25d2ae3": "0x00aa7f5f551c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979d520c4950096510e347b29c703f08258c4f34253dfbd517a9319d3dc8cd8fda": "0x002e6ed21f1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c3a8edcb45c45c0326aba09d730ba7f2d842ceb98ca3e9aaa2139e9a8b48f4a": "0x002e01f9b32d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974fd33d957e2d31ffbe84d6e12bc69895a50883a4b1fc4d8e29f9a74f175f4f2f": "0x0026da6a887d25000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d15fc0b3d2ef2d27e5376b9df8591a37310f6cc3a2a00be3ffdffe4ceb600ac0": "0x0092ba17bedc00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec436c051732cbcfee1a6ccb1ed412c06b27d30998ee51afec1dec2b444f4a38": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397606febf5974bd3e3c960d4b148827e7c9a8ff40e271a46ad1f061dee36f376cf": "0x0080292c6bc102000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fe60ebc97711032e5330887a2480efd46737a1ff256fa85c5fc8ec6c1d6dfcb": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c62c5eba29d405ef742e1e87d4b57812bc43c42d72b1a0a8309848d7148d3d9": "0x002e8b3a7c2600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978b90fb4e7e2c90e17e8709022a1d8135d8877665cd2af1ecfa82c22735b98564": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339739861ebca070883b80417a4d3d7e062e2f6ba11ff63643ee49b5b152696366ed": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972be872213348f1d71f238eeb6086c7ba63bb2481d54db0b2a03ca4a3add825d6": "0x004a61a31c5e04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975beb7fe937f3260ed00d05bc6b8014746853869caf0b5f8597304e4fbc3594a3": "0x0092cec9b62701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792819d383f4d8ef876f873382f52952741fe5d8c93cc49d7d36b1b6d58a6943d": "0x00d8adf2724902000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4937ff12d7dcc1f94d73ac61d6ca51165ef6bfbac182f91c60f588dd1c7fe9500": "0x005a3e8aa72920050000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b430b0df6ea16e3f4dcc4c17a39a9a7aa7dee0324a3cd377bc4f1d83889c9b8b1c": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e09b19ea8cfaca1845a1ab4ea080303b56e3dbda273bdca8dcf17207cec22ca": "0x0058823c772100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b5bb1d010739d204203c5c5964887e5c5822b017253b99fd7607ab5184c639a6": "0x0084449cfc2f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46df572d5ef320c819d2f43859745ad9cb2bce64e6e57c92654b9e297e45a3443": "0x0094bcba878500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef413de1da8e5783cdd6a53a3363ff48acc6e2c6f364452c876075affa1bb6e5": "0x00703874580800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4aedf69b783ea7deadb7a21601e808da5aa4ac1a15702692a84dfd1fed5af85d9": "0x001a3995772200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e584291ffdfbf1c32ae5901fd9ddb93ace3da44fd0e53bac8c4cdc7e3d123496": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c5c95a72c9fbdaf3ba8e4e53438c6c4b336e009014c5e5704a45bf5e2e37ec6": "0x00c0a31bf09801000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e65c3691498f1547f274d50dc82155e9d7e84d99a0383e83f273ffe7b7acb17": "0x00ee853eab0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b93f401c18aa67c2b410a827d50d372ba4332b20befbf6a6329559d8b9b22d2": "0x00c88263aa1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea4a03aba3cdb250170744f979c2226bcfe6bb2a9d9eb5454aa42be5071e4071": "0x0022bdbf630700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339714f615ad01c6fd01da1cf0a7d5bb5fc003d3bf4c0b4a20ce5231204e6a907b12": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972386d822849c2e916b8f9e47866371387a8c016b5fd26b7bf73c206ea7814411": "0x00963016623e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a0f6eccb34f6f35bd15f49eafea82914e6c35f5040645ddccfd17580f568c3b1": "0x00f27812638201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6a721f560fe78106aa4b9786de77f50277d052544cb0a24b2072c841ebc1a76": "0x00444b753ec100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6bd74c3fce84356218175172bdb6f80828c739d4ad4898e04ed6f99cb32324c": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c41a223f614c97ce66a7b642f0cc368cdf5de348327d49fa262f4fe4356b26a3": "0x00a452f2812100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e612a15bb049d65705df5885b0e73c41ec9046cc6cd87f74028167d5b2c301a3": "0x002082eff9af00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707926c0fc752812d874e93b2b9c97a0c2905eb3d4a942af8252cb87e48da2884": "0x00ba4f31a30800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b435808ddac12abb15ee984f98ed63a5121ff68f78e98bff6c4fa1815b33cf6f4f": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778e270c088eb556a24e6a514f0d73b266c71ba2ae74b4061da3a968e40995510": "0x00e6add2ed0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339735976d944c977fb4be81ffef1b43868b6c19083cce3e7efdd12ec0be9ec66162": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6b585744d014855922f92ecd193441f3fadb1bf68b7154b134e417e6dfde46e": "0x00c41afa0e9000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397462f05eba61a3a04f5c57272ba7e15bf7224f8bfba9d0458b80ddba42800499b": "0x000484564a1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a3ab87f7865a20c0d2e56b715f9a2af8cdcb0e543400fd511727a3dfbaa8c58": "0x00ec045dab5600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767f97a171460cb74e6c2f7217291b19dbcda15cdc06cb96c72a518945974fa0c": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978bf931b0ea9274239dc3d21134c5bfc8bf2a8866f0ee4683b060dbed00857ab9": "0x00488c227be903000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971438c48e73d30b8e94915468d139c4b5b26814b18761ef26d7a41f047654c68f": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009d979fd811f5800c676031135433ac4708907c0dbc51eae8a7647d5d93341c": "0x00ea56e6bb8302000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339763b9e3c56d2d9cecf7be8b8405dd5e1e41293afefbd6a71b3e06db82fac4088a": "0x00bcc1fbefef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6ac1d22aa2ce27ea4989f917eecd3697e0dcd0831f077aba5f85f06f1edbf94": "0x0090abfcc81700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792352d605942a5f11ba508c3b2d69bb3e6eb64e9fd4b1e9e6688f5eefe65ccd3": "0x0020034cf68f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4bae97af614e917d9642f013e93292079ed35b0419e0bee3cd63888b22249fe3b": "0x0088110e954c03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977054aacdb4b13c6a43d118d7f9c1cad8bd88d542f0e1bbce4a612f03e14ed476": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397563ae8daa4a852be1ff31d52697bc28d293136b9b831d1cc33667ff632d93972": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977022988dac7483ad221c225931890d54f5ed44191f9beac9caee1a4bdea1fdfe": "0x00a4823fc99198000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a6e1177b6b513f9eac8962806c14bf75fff9dceda50cca675ee0658b03d88a1": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a901b01f88208e9a58ae4ef4f650b43012e70da09f155f560a6d37350a3ef91a": "0x003c7ab90c2c07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339784badc906832425894fc981dd0df619d46040e6b95313045eee5c4e5ec60deaa": "0x00e09b147e5500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971449a37be4780294648da07a852d4188cc1a08403941358897f5044c5823811e": "0x00f4fb4e8b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c74f51b8df313289809bbaffe2dfa5f0cdbf627e7b4fa3c032faa45ffb224e4": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40df628aff3a76a499b37a11dc6a7b83c74e29a84e75a6cb8a4f79848bc166b67": "0x0040db35ba1601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397de624c8e2e81331887918b3dadc74b63329920c9ea1de1562c24b1e063c72052": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970690115da28753b6521cc31164e272cb0674a7c9a02200be99cea44d972b63ea": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768daca4e2508d55a02d60ee13f181884888607c5b44b40f773302b2de627590d": "0x00703874580800000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca9cbd2f0b29a008a36009ac44cca0c969": "0x00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744b2aadcb24e100bf23e7f24e278fdc4786122e1abb8c011bb6432c0b568e34b": "0x0034bf3fed0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bfd307cdf2e0cac8cfdff49cac81daf1aff76b8f7c7e8692c2f7fe9f87b45c44": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aeec2684cf98d8561dc00b33590a18bd39a61b9c74531ec8415b77be3a0bc84b": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f194f9d03ae634f4fc6b396ec77f5e7ded61c2de34b3b074dd2192749c6dfc6b": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b63de8048a8ba8500de75e66fd8fa73f9145ad83308cb9ab0be1311b72b40bb2": "0x00c41afa0e9000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738b9b0115fa58a8d30be0cb52066faac4dedc35795e188f735db8854c5be3969": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397637f77d119f7d3c7b9ee1fc91b4f309eb4c5d535b82892684942587a42f17099": "0x008a5f28be2406000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339739e75f41063ea4ee3a3e92882e27f9a64ba31a736f6b32e81671f7b4af75cf00": "0x000e259dfe2600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973daa530f5a0c6357cc274ffbe64ddc6dd48894a256af6fda4c019340802b14d8": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bf06ceca5faaa2d73758b478023dea97bdd98ef8bed91bd2f19dce87ce45d28": "0x00d6b1f4573f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d929b329a8d9651c1821da74687dfff7085d5ddc8976b8f41fc20c045b697311": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718b923ff2921c85bd0e8fe5eff9fd21d71d5850ed1ab8dc0e11c03dcf0768424": "0x001428b7820700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785067909f7a3d6312cb985f1288f1b43eabe278d380f60bc10f6ad8ea2b57a8e": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339715579ccea2ad656af34856b5679859be424b9cceb6ebb534e8c90a84e4572d47": "0x00881b5b9a2f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282437103941c7d93ac9cee1efd10f90f56b81f2083ea8e8b75c92914343c257e67b4": "0x00bc15368e363d00000000000000000020bd175202000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ecf4a69957902652982210bea651425cb8c0dff2e33f17624d8b18a16fdcfc2": "0x007ceafac42900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e1896f54e8368286b5b5709dc5b76d24bbe3f687e7e977790eb28a6e3853267": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d93c4c6e0b5550e12026e35a0581b1e132c4f861fa44c2b4bd45d8225d8b765": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f37803431e008ccef2526af4d0c41172ea262f967308bc4caab74aa16b24b07": "0x0072d1c9185b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972e8372cecfd7ed1dbf3cf84708f6240656684de5dbd558921b3c739107f2a59c": "0x000a5aba704800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41acbc08df9659ed58911fdde3cc56c176373a0e1a6686bbbb437bc4b25da1c81": "0x0078818246ba00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcd342d8b90b9753f218b598b5ab7e2e29521e1b21a84e1fec98afe0c61280f3": "0x00f43bde630600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aed99f75b4259baa98249ed5ede86399b0e21a4c61027822e5f8e5584cd847d7": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2595cb78d2cbc57f249efeb19576e04517b42c7a4c6a7a3f274f0cdb6e436b4": "0x002691e58db100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722183db25c201fdd0d2bf07bb10f61c61955c3a317c6852982b9ee3b5670d7d8": "0x0098caaee7b005000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397943b0c82013475cff759e037d9ef4d6ab1b9ff86f5a044068df2237d527cdec5": "0x00728e40997870000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751a83c28100d253aeb2b58a4e1aec4514e516706b00c70f9d9ca97653be6cff9": "0x0076e6a2f50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397763fae548b084dd248eaec9c64daa5bdac0fe0b9e81714c40c3f7a89b844c6df": "0x0080c6a47e8d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6e0fd3d4d512cc0e49b639ae93d66e069741fe09d5aa0ce52f3809361cd0687": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977fc85d7ff32ce65b580c4055e40fb503d2dd1910bfd9fda07ffad6cced33b15d": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397270f7c4130c2c958c65b2389b3bc5ba99c6e597bbddd5a33a11b13109390a3a9": "0x00d22374f95f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4056ba8af483f8732a35c46e861d839c8acee98d14d6a2578708ea8271c8e2477": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397098b448fc2c2ec9f519634579c5efc3632ecaca3e9df6035f107c86cb47f049d": "0x00f022a88c2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b77c2c3fd6e34e76c0ab67fb6a83170f371a5e80f269eeb2a63467f611c3fda5": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c143c370138b08ad1df8cf84c2afe88f8ec8a3d2cb06cc983f0e49527c2e8eb": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c59de23b2322ec9f9116b29878a212c39677bcf98aee2b84db77c8dd70fd0336": "0x00924866aa3700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b435c102d635357a134359ba658fe5a183a74b050d95e19e9ae61fccec7a4b1b71": "0x00e4dbdcc51000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339791894e427f8a7d54a04efafe4298b3ed58255cf49c61f61aaa486b73f3c2be65": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e814caa722c07384eee3d0f308bc250898f968f406855de2c478fba12cbf2716": "0x0080ea33341900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8c77076ebdeabb6bfe1f7b030a3ed2b1aaa2e40a4dc70d2c48e0f48fd713d4b": "0x00ceaa99f6be0f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d0cf0ed909bf09d7560f0ef35d9d8cf06cbf004b72d2baf1fd25969d645cf15d": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c3047377e2403c45f0e5ade4e7ba7e3ec88f274249c4cae6cf3e7924c267f0b": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773eae323d27dcff658d01283e1648cb11b09a935da5910f155f7aa82e3260d61": "0x003036d4980900000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b65797390df2fbb9e5803a1bfbb80016c5fbbda6a6adec011e684820eb8326ed6f47b83": "0x2280483e7614020101d7e03e0019d5d0c082ba9e23fc43a2a36b261bcfa5cc3b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6bf6a5cb066373827239ebc9181216aaa2650bbcf8d474b9e735bccebf479e3": "0x00a65f83e67f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397575269321554ea44fb3f18a44ded7b902797f5c2f34b13793592a06271425311": "0x007870ddfc680b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f7348b74a1fd586aaa153d128ff63a96f70f1971dddd3219f8bf560a24e608b2": "0x002ccfe5aa0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d9b636bceefe8030141fb86c207996d0a50518ff1ff10998aea41f9cd7d8e2d": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c596eaaf328b622bf9b075379e7cbd3368c5f5bfa5344eadc0c3fc19eca7120": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c3d971aa8ce27924f14168b86a10618f84690e19b415ebb13ee60ec36785821": "0x00568005780100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792bfda510e2e3b64aa96a227d16668cec1698c898781f2f6a1a25851b7060ebc": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799ca0d955625d6b6a7e038ab401b977fc1495f304d48abeb0c77665ee0503241": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6a54d3466705b92ec92171961bc45b9ff4f6132077a6688999b10b2a26b1fa6": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339776ac0ecf142fb7c670db687e9640f7ac10520defafebbf75952a93264c9690d1": "0x0094bcba878500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339711e4bcabeaec31774bc1fe34ff6ed9a2dc72d4d9c95df23874d4ed9c3e08cc82": "0x00a854ae840c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41932680cd17166acd08c9559cca5c7233262b7a44b830868cbbc90e9050425ab": "0x0082377cd53497000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397157fd8eb8549ba225351c0a488606f67e798fefb99f0aed5a82f6a6374e24633": "0x00005fcd95f209000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1fb416256883c3b831a9595b144f54067b4b917d79b5c1a13cf4d750677e1cc": "0x0014a9784c0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339789157d4de1941b7574666d8752d24a8755c775e1b3e567aa47e39a7a83dcf5bb": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b438aec4b8524165a41bea452628f9389ab7a9bdddeb1b62f9ff4c69035e99af5d": "0x001c44aa45f000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397081ab7907be9204bead6842ffd54cd83be368107369086505577097297ab07ac": "0x00fc8d0e800000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397240d16d5d1c2f7fd517246e8516efae541b56a7d94541a992699af17f96b27c1": "0x00f456eebdaf62000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba1da6723c144dbab4126523069bf7fd186d031c1bcf611cb5f0c7dd7ed36d8f": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794643194f29fa159600d522012dda5592c2968c30cc4c872a6b792a4d3193ad9": "0x00284c32795300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b444b9a6c6c7e4ca1081995a55f75ebffedbc8bc9a2869e15ad7ef313de13b89ea": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be580a586fda73b919e6882786aba825641b41c184afd344261887010ad7aebb": "0x00aa8e680e0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ed0e37a9eb3da5e7031190af90482495056dbc24c289bc7fc6a0fe49781a084": "0x00b0a6277a7802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339729ffa19b01edb26c7f1fd68fb0e26812b793714f968703d8f528df67c4fcd838": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972123e6eef568309cb196f41e7842dc180c60684ea4f3bf9a222464facb8b8ea1": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397425dd320dc63e91f687f66fd80386667b743b578143453cf1d90c3a6213de201": "0x00e66123a67e01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f2ec3ac826572b72f924adba308be75c142ad98b5391abddadc56be0b07cc04": "0x00888bf5e46100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972517ad3e93721594a89704d17d273eb40029889a8b00a2b51bc706f8a72052f6": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9bea4e4f24db23ea554a3a28aaa25b28873ccf4c7744539058760e78dfc98ab": "0x00fee1cd577700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ddb2bf270287fab863f486e98e7cacfc141d0603264f33cebaa340f79bfa0a19": "0x0026dfe67d4703000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339758fb1bd6714fcd5b897a5af8b6b056d114109c2df0719487173f8bad13ba492c": "0x0032d33d7a2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6ce636fc7a501ac18da4ade87d47165864b1f985ab7abbabb6d8555f39e835c": "0x00ecf4b0d90200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f5a12ef40ebcddaa71ecc91d2e71e7a1c12e4021e79c5070cdbe81a67f331956": "0x007629af4d7601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec759e7422cf7928c1abd3bbd5837d4623c69d58ab6954e02c564f227e7a8fa9": "0x001cd75d120e02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bbe23aa4d55cfff026536fd4322d77e653b3854012d45e2ba1454620ecd8010b": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c61cbeb83abfd34ba0b4538d941faa5f08380da394e748a33d998fab7579d43b": "0x00142a8aecdf01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979aec2bc0dcf3561ed862c1dd89bf7f539e9de80ba8cd90b95edb927d0ac3bac5": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339782791c76e28672a1bf19458a94f6e1ecdbcdcf568fb891a10bb5905ad55978fc": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f3980260aa572aad6b6eedc5fe3929809afb961f91c19d96973adb1d3402c01": "0x009c4d06cc3e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970054c4ddd8464beb867c4edb8fd1a2cd2f6dab6ad8f83d16877fac9d5d5ca65b": "0x006c2932302b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af769e1c58509e0de78c247003a7a95960c324259b0cac5b35a8ad8390a8f00c": "0x008e713b42af00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736583bf0f5606cda3fec61ea5b63d1d12e6a340d22e6ef2a34a60635bb061288": "0x00d6087cfef24e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c3189ff7ddc5c10fa16335c0d753250027c4efa187ae4c4f2a915b91bfe773a7": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b46b452ee13e9d747fa0394be282451a8d397744da9e64437a8bf63420f9cd7e": "0x00a21abb8b1f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d462fc04b8f8d9acdfd7a7d3f7fc7ec60041d15afd7b444f18c97cb0e93febfb": "0x002a96626fe000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e799c586a3f41e71d9326288d2f7643ca97a72bf4a1117bf5ace92b266cb73d9": "0x00dc0b7d560300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f22ab503d7e4cc0583634058641016bc8f8891a76aa09004675da9bf377d4538": "0x00ae8f7afb2300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ebc150773969a17faf8a247a59302cf421774c432b38a7c8767790c0a8cd6d4": "0x00dc6ca21dbf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c82bbf2ad08a864dbb1540d8d92032c5248476dcd6e19b71a3a953d05d3943c": "0x00ccf483926900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9053fd5ceab233f4624ac83df47f11e552d0c68102bd9f3141ae92eb391f735": "0x00461784db1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd5d2778d9ca15138833551c7a70db3824a26bd533cbacc2a8e9513d6066e683": "0x00703874580800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46f6f43824e0fdfcdd9cadcd9c4fc550563dd9528f397c44d7be339ba9dcca231": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ccfc7684727b484e2653e10e2bf5ef3cd67fc4f8c50f2e44b9377e1dbe896d6e": "0x002c490fd71c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397687cac370280ae914f53a65e26ebca34f592ddb9645f34126aa09a6268b6794f": "0x000c7a9e142600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397011945c9a166a3e3a591eedc896a6e813fdfacf2412ddea0ed982bad1f4af712": "0x0080c6a47e8d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b08eef7a2cab7c03bbe6bf5ebf50fee7da76f1e5c56747d9bf67a69071f779e2": "0x003cf35d972100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339788d5c6c66cef535c7fc4c1339911283d6d0623199a9e298e50ad56730fd512d0": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397116aa5566225ac36172e736dfd3b43db4666d8a478238969107738a5005e5943": "0x002484462f7d00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b447f3223051d5a5bfe1db28244b0729449d58f72600e41121e7abbefa884ee417": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b07ba2ef04e1d54ee13bd69766b9fe7d9b30db13a1be1ca728a330b0ae68a019": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bf224392199648bce8bf66416c0d64f4d72539d46b1cc3e8a8fae323fd14e02": "0x00a031a95fe300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974baf300fc541b692ee61b4bbfa9cf2354a802ae7d95207f91966c2c38fb3d19d": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb067fb5318a62c247dfe66b337564198a0cfac71352b7db98a52f5af7d42544": "0x008aa98c5a0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339753d88d7cdd039ce24a745031a73f83890e4c2e23b3fe61d2473a3409238ef098": "0x00ec8a7c58ac02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977e81c3af44ad348575661f08d9f2e24c90e7d2eb02e84e99e1ba47bc1b516381": "0x002c79ae7efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b5ed326b66f41f12c82f13103e92e62da388426443c382e939176ff9f3f1f14": "0x00440062123503000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1": "0x32000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977533c07fc7e2b574aeab7470871dcc1a2662902cd028ab86ace16d53ddfd3455": "0x00e801c82a4100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ca74c6b85347f130a2fee1829a6c3d09bb4f6d0946e3efd897e90fa837f2739d": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa5cca309371fb46dfe0ab4ddbda95fb2c0d6364013561faa2d17a08b713a623": "0x00e2ab7bb83800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a3d7a07174e4d4bb57cda6399dd754cce91881948aa40a0a6ab153a5e17393d": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976076841f612727b0670023f6424b2948280c64cf3d87552494d2345890899739": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339790fa0f70c430e5a40a45155509a578b5c195acb96af8a01e6f7b4a23036d4d0e": "0x00702964a2af00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794bdd08c266902071d4ae39be80edb6c96935c1b7c16ac7dd681ecd6f7498215": "0x000a78cce22300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718d6240cad1eef110b239f2b570a748796e4814752b813f2c3ee2ab8840757d1": "0x009c778883b200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f3aaf90ef248c4f9f0e62bb9d2ef7eb0202b41d6e3079bef714737b5c47784c": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339753f794c858e4e43a687a4011eedd33be735c283554eec87589529bc94a557f2c": "0x009a3f588a1b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c7cabb51075dd95e42915aacdf8caee49d70280b8fa14328aa2223c3260c3f2f": "0x008e46e00c1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f034a4482dd09b018a4be8a71455c429bfa0e4cb41520f93b11676a781f5e378": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb59d99c1e6f7c025a1b1995c1135ccb7c2dc7730f6c0abb50bba37b3dcd2bcb": "0x005ac97c261100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bbfbd713f0657e4e6657ea71df11d1311cb3a86f9feaa56b4e0ad0fffa7dd3c7": "0x00f660a1ac0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773ddfe8195e849ae1845532daf419b805752230587a121fde0c36f508c363a02": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b48fce62c8e5cf3d38204b70e588e4d8ede1025f98593616e45843c7ad1d58deae": "0x00e01fd2053304000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9896222fac623a45d8bf0006292f6b16cf0d7986cc1d5784628876b8d33e86d": "0x004e3715665c16000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d1fd9884a8fd6882c9f6950afb582b55e68208c793ad64cab01eb70e56efd70": "0x008c4400e13801000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976521ab804b19a952c0bd05b5626bedb58fb4d7cadaee0c9ac779603c87b0a471": "0x002e03c87cac28000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa43264259775ecf6783ac2dee1c4d8c2d82208f7b9557170884b8ac9268bae8": "0x00bac1e9b31800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397189b4308bf1339ba1df91b5c6261a2fa6a42b387a46ef24091e6477365f3e27b": "0x00be5290be5900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339787e4a0f4e442e57af9bb1df1693fe1772be0e1c9b5af9e103b3c9a4e61892001": "0x00782fcb050a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8be95b7fb56fc12c0663a77186aa41d8cc3f854325eef84d3ec47afde2d5206": "0x004067d2aa1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c9f0bf6c8c3598ac8d210709e2b32cb81cf8777765c7b6556495fcade38de83": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773f02028678bbf8c381b7ca1fed3c0c8d87daa83194033f85ce84c0033e268d7": "0x00f6e55aa32401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e8af8c0184aa4ff4849a42a2a70abfe730b8f2bdd1409452af7f99705947125a": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973fa35f4313040e8d1a25cf8cd42eef869a7770e9351569f8593c1229b81a6315": "0x00ceb632b62800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c210689a2cc48cca7b1579a30528f7b7b4e10f9be7b7f55bd7f4dd6d2f096c7": "0x0008bdebc10a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397759c95000cce052d53bbb433da2ff9887e2406a0fba7aaed430a2e80a79297fb": "0x002a799c422300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e7512e12c22d4f162d9a012c9319233da5d3e923cc5e1029b8f90e47249c9ab256b35": "0x010124a8e101a08e84136b0b33477867523ba2591ededc6c1247a0f77ab2b3ff746a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455346a6cd54809a1cb5e1ca4ec9f583c00c98aec6ce768d9f10370b32add71bfade74a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455346888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345534676444817329f55798fc369637f87586f4c897ab648b802d5424b66c5c99f0026488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455346588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553464acae4ebc67baab582b04298a37175961c531a1e8efeb94f03723b09678b91a7f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455346288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455346188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455346088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455345f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455345e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455345d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455345c8a0f349c56207e869186a5a29e0f848fed08ab1617a4115f6a628531b54d2e7a9613f7a9e8e8b5c80805e4ab9474a540ac23d5b4c08ed3dbc23ed3bb00fd650858c6d7a3ca28af1cfd0d8c1cb69619e85a82404cdc655522756f1a498ff231be08c71e9b40bc639ac1b3e109b15f4a9f701529eb6941b0fbb51ca6856dea4c0820952856965f0099f1183f81f16cce52efe3ed2fd543c63c2692db598ddf97ae88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455345688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455345588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455345488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455345388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455345288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455345188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455345088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344c86a8c83bf323e6e4d715c2d24c71ada7edd456323c1eb66490752ee950b60c5788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344a1c41a9336d45cf1ee3e4e655c07f49af5e8313bf72298a06397d870bf2a05a3cc08d5de7a5d97bea2c7ddf516d0635bddc43f326ae2f80e2595b49d4a08c461988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344476d7aefcafa78ff735b07e082de3e15edc535b2a927a3922242fbab69af8a30d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455344088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455343f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455343e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455343d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455343c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455343b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455343a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455343988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553438a6ff2197e260745daf5ae4c9f73ec52ddb19dd9d9f4a31786ec16ecc54430a5f8ba481dddf61ceb606c28ba81e59bb525e81c9a0d78942bde63af3bac13b41eb88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455343588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455343488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455343388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553432fefc84ec1b276e0664192695311c40885769b9a75954e49fe12c6aad6c85312888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553430a493de655d6a57c136e22828f46b8532e2d31cc6f2e7a5c7ba2a20e689f7540c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339726f2cb4f443feeb4301ec5eeaa8da9be47c3a4f4764ffa3cb3add11f4902c11c": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a53c54b8ae518596eda89f856b3daf1fc645cb57044ec1dc38a105d9c3369f8": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977fbdd8a1d211270d864cad77b9cd4ae786f972edf7d52e025c25bcd534b87825": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bfef98f9b38129bfee60c37f6cac951d4d0e57bce8dcee22d411869be409c50e": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339777c3aed1b00522e49cd38c3cc93b4c9853cc328ab12c0704a88a5cb79555bf9c": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397708363b987e1d681773e9744d378a75ddb48d41d498531c78e8bcf79129d50c4": "0x004c98974d4000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397090d8c6ab2a11fca5118cc839d4f55797c6725b538ea3c882af967a2bf75c8b3": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339713ab80500c57e35644dd21d1ead928ed78039eed03891cdc4e6e2c4b1a8ce875": "0x00e0d10d78cc00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b431c523b86787810de50cb0882e93245d510c1a2cdb18a5aa97a6450855c7a904": "0x009657704f8a22000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970db1f747dbd00e3bf7c3d5b9c126befd95fc99263219440b73148dc5006264a6": "0x002046fdcb6951010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339758065be8ea1c52d16814aa0e584cef0f95f90c03754bdb026b214de57b8334a4": "0x00ba6a3f4bb60d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978708a463d0c3a6cf3a55841ab4547c5363be5bf3300999f7a9d97999827e7c22": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397513638aa3ffcb89c023d6388bf942600ee03a54b251fa8c5b1d8bba74a7af52f": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da46e347c9815125352029863165b9f7764be16d0e49b03d94f0cb4aa55627ab": "0x0050a95c091900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b47f21d7797148b01787a6a834bfd29b515f39e3806f45c1689550b6065389d9cc": "0x00e8addc7b5fc5000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd4a955a878c10d266f680daa5003880a0cefc9dd82e244e24df869817dd6f9a": "0x008435f8106000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975cf0de3e39b41586882cdc341a8b22f43b0b659358b686871af71176e3ff5ebf": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42bb0f1aaf77cb1892017d606f0207cbbcc9b3121c3fbdee7510c43277ce18786": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a96895559051fe5416f83d6edfb03ffac1bb534e272d2a83280d33f31a3aafd": "0x002468be4d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339797b77d838b7a8cae4ff39140f61d6152ae857649c104d12f2b601ad91905f4b8": "0x0012a3c85efa00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4665cc45b15775fc7e47880ded45cee9b13304ac3608e635117247b84824ee4ff": "0x0074d5f6726a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736eb099b871dcb77a8dc2fbacc7e30e4ce78fd2aacdae7a38a3553469c6d9dff": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af1b018f3f16063bc6e50403b5dcfb9cf4e0898ed2ad8d4132f38410b6b560bc": "0x000258fb633200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397adad3ed12941ae256ff82dbe5b0f4f09ad8cb0f5f2d2d44659196bbe4fe8ee7a": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339779ce1845ff8cccdee165539136460d9f5f13b12a5d7143e8c2ba7a366666c320": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be43a023b1d031497efb54a0c42ac9b6774e57470cf8cb6701cdbff56888d54f": "0x00744903af1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973fd8e006cbbfa649802122aae8a784f4ea766c78b6e25c824943021e8d749549": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e25ddd6cb49034d1ad1c3e9c4ab2acc28061cd69dc2e95ab023b59832cd6ba5d": "0x008ecd52fcef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ace88aec11b8637788709b5f2274124d4950835f2a0fe7638e3c232380fb7cdd": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397afe3a11bbfe3dccd8f3b8a7daf329e35e3f2412675ebb3da56bdf101e0b707ae": "0x0060b7986c8800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bddd7335e6a99d2e0fefd9ff5eee2a3a24efa0005bca0142c7607d7adb8dd565": "0x008644b5357200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46b951a8db9a908cd6f551a914d342ec0430111272509f8f2113bef298c9aab2e": "0x0014752a517800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765e0e36830e78b34cd29e1b0c7b6d9a8a78e921bcb7eda2098b50c645bc17129": "0x00987756112e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977477a534b83427e5628d292d5038b9a14716806b1011115eadc99541da36c8d9": "0x009ecc2ed32900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d4f1985a57bb95a814eb33a263b8137c4a79cf229456eda93602751cf0f99d3": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c78513abc7a05ad2995acd5b8bd9990245fc23d732046347a098ac4f8ed8940e": "0x00a0724e180900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41fab46e6c30411c4f3c1bcf39a0af80276f6ab1d4128bba449f536c8a2e336e9": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e8bfffd6bf276b2419f40be97f06f921b4d852d0a1fc696a0995eadccb9bca89": "0x00ba080a2d5b00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42a28eb16d16d51fd14274f75797968fa9a9b87aa0903119f048fa6eea8ad31cf": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970de04c75de5f9155046eb98e0a3f9e1be30313ad55d0f9c33e9735dad29cf8bb": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979916a8fbd0b4dc9dfe02706b55196675a69df32ed08f04b8c55d3e7d7a835fad": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339760a64f2d3923932a08d5cdea19e6364430c7dda9027c50b2adda68e04436677e": "0x0088d21c5b0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769693fa72206fdfd5660e9de0f37abc2acf0cc8448e3f05f609a4a595c6499c8": "0x00d0841bbabb00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4880186e45243126507b4a93305852d861645a12af9bebad33d383230de6fbd3b": "0x00f2b4d8768600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722b62a603f76fcb19f959aa9d4b779d9be8b0f055af308f5b5c67c73a441a480": "0x0084449cfc2f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42ffb9d21fde4391995c63b6a40b00c886a7f770037e28572ac3bcdaa6e946f2f": "0x00fa444440aa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a071dd1abe97111b852bf222f7431f59a5ab8d1868a12796254de06284f0c5e9": "0x004ce66c318e28000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ecfb49208f40f242724191878cfcf0b499f0b16298a469538f6eb8ed9e8aa0a": "0x00d26818dc1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6c2934814625e032a48cfb623b5254a37dd5254c874f3f86eb34214b369e2b9": "0x00ae658c792700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973dfe6717dd725eb7ebdd64e918b5a3d132606cf08b420ea6f26a7cb67afa6572": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea18561133afdb84564b80389c6c67ad9655f2842ae0b4d33a502ba1fd535839": "0x0038e5be87aa00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e4ee14073b491d25c23a2cb3d885a46ee9b2e3d0030a0a8cc57bbc74d84b563e": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397266ec3908702055d1a4bc9bcd532a23848df581733639416350d5bd86442b7ed": "0x0040ac6893f800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765d50d88acdd38bbf2cfabe6830ea768763214eb3d2cca4ebaa4ec423fbe7154": "0x00beeb09a89900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397326c51e1f18e150e7929b3d54a162dbed72bf65078f9cfb318d5c69b1bb9a210": "0x001230d9ff0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bb0eeb50f76a24637fed16f095ba55abb8a0cee3d5f3304fc5c1b1f9d96b254": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973b9f1ee7e6b79937a8793537e34ba415b21957035ea751e73792ca0718144957": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f36b431133d814aab7f79af935d1babaf0ac54c4d75e103648a7867c7723dea8": "0x00dcbe9dbd0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a216e6784ec474a38033cbc71ec4b483ec4e78cc68ec04429ddefd19d7537cbe": "0x002acfc5745300000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac": "0x01000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973bf5fdb0b6f3d2239ea709f67f721f6fd9c19fbc0ed7e319c7d66d2228a950fd": "0x00fad415c00000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a69488c456535b88afd15188fcca72c63980ed408ddfb5f7fc860484565069b1": "0x0072ef4755bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d7ca5cef727fa9e2e10e10a6f2aa2002b179da0c03f4dbe3761d12ac682aae3": "0x00f0f70ff55300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b47e5da1f8d06bd05a22c85eb463bafad09fe2f84bb246f05c6c5d73b1c6406591": "0x00d01ea1f47316000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397acc690dbd75f00629b3cffd916f17f3f7c9a0e937748fa00e969156145f81fce": "0x00d634d4e71a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397afe065dc8ef7d45213dff1484d102f72fc078fb1e7b28a4879f40534cc79e7e3": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974801c7d8c8ab2ed5c8f04b3f96f4bda4b5f4f94587bcb75030a7a574fdc46491": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976440b2f0f371b962449cf9b850e8945dc2b09e5285723a64b7dd142acbb57213": "0x0032efcc580900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b463bc24437250a45806aa82b26d358e531e866bd18f1064f5d32386d5d5adcd32": "0x0054e32fcc5800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970419a684c4ba8eea24a105b9e2efa7ba702e285ced1e4356eccd330d74ba3207": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973d1aa2342296c48dd7afceb02304c99148d2621d0dc5b82273c5a89209bfdf22": "0x0072e669861100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a9145bd8ddbe0f263f5dcb897cb524ea564c344eaa6a051401c66ceeeb50dabf": "0x0066497f817f07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e6f21e4e05240a412acdc70569b25d743a0046ffd076af2bded5a8119ac0c864": "0x007eed5f265e7d000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ab48b6454cdfd67ff61a56b11a3b06d55fbc4444422cdc60dbd32d85fab30aff": "0x00026c488f5f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397818a564f05545812b1445a26e80822a983dabd311e132373129e621e5264b16c": "0x00868bdcab1f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b0455066a48da7b03beef39611674d8afa31dea711e575000b6545bd6b596e47": "0x002c0980fe5000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee8e13fbe6b18d535fc68677cf2f20babf80376bf345733c668d7ec1f698e5cd": "0x00e61c8dbda200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978527358cb6e201b3cc13e36c05dc0db718925ca5a8b82d0c75b9afb6c95c2e62": "0x00c68d5f688f13000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8ea06e4a46f0f3fc88ba8710519ca8e1c66d30f3b231f4b1d7b9e82c9ab21eb": "0x00962d3a03ff0e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339759dac3301efe0a650f9054825b9fa16a46ef8966215ecdd6a457fd147330bbf3": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c83ce1c9d7f0e69716d96af4f91399d96329b8e1ce8bdfd74858447aea208523": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701e59759b4aeac8c1269efa9e2089131444fdc74d579eb94333d7f68d4c05295": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339757f5f56f400da6a6359245483d277c5b3b6de46195126ecec78925a919c1b7ce": "0x008ae174b20300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974187114502206b363a742a7795537b4f0eeb69decfcf0cbecd936d9b2ffd5c49": "0x0020f84dde7004000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8efa60ce5fd9ebb42efb621ac7d7e832a19bda30f855845df437b8add25f269": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a80d33cf6c1f7b78d58fc1a0309406ad5157662d78c81840d01eaa19ad1365c5": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f751e373bb924e0480c128cc94653415e410305894df8410f4fb55df93b3c40": "0x0078e6bb2e4300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f1b1d07a2a9080fa1c149cd3d95985513f53f6cad7dd8206ba3f2bc8fe7560c3": "0x00bc04ffc76607000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e7512d86b397901605eef0229e0598759a8984f13c8d62b040e194fc5da975fd7d26e": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531eb88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ea88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531e988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531e868c56f1614b37b1505038f7115043fb06eb21bbaf39eca61ff34230a82fb931f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531e688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531e588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531e488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531e388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531e288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531e188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531e088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531df88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531de88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531dd88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531dc88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531db88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531da88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531d988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531d888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531d7cc6a9d8c19b76a55b97079fee87bb615ef9bee42c269088ca4304b4245dbdf1a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531d588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531d488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531d388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531d288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531d188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531d088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531cf88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ce88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531cd88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ccc4dab03cda4e9bc7e0e896342a87e55c15779683b42c81a2ac3a20494fd80b3488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ca88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531c988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531c804c6871f21173e22bbcc9902a1ba41a513cc5fff797c948a36927cef70148c3088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531c688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531c588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531c488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531c388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531c288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531c188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531c088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531bf88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531be88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531bd88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531bc88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531bb88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ba88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531b988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531b888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531b788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531b688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531b588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531b4220567dfab9710deb501d5c1a3438e8146fa690ebf29968e6931cd8661bb5e3c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531b288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531b188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531b088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531af88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ae88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ad88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531ac", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d4f84015fff76695fcd49182be3cce2f00c991f0bad709c23e6a33f23dc0bb53": "0x00c6c5932b7300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c230c8505215b01d0b772638bfd4888773d0dd93e346ea6592df12c0de57c46": "0x0004b30e7af001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397465c15fa37a0ae0a71f412100a95f7a18ad9f0e2c5deb930c550057a5cd757ec": "0x00020edda97c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b7d7d7fb5ac1e17c013d66148ff4997a24f496de08de85e88f2f0f104fb52a8": "0x00dc2582a47c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c40f62b3e06894e1685b69b0626fc64b09c860db70a4cedfa01537ee09d9d462": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc6f0f65f80079c46f4b66a9495904f45b58b9c9e51a1ba6a94e9c121f98db57": "0x001e10b9e23f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41e700beba5dedb470bb3659d047cebc928d4b768d765395eaa0e71df122dff6f": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975bb4424405846a424244f4ee870cfb85c4bd98ba4c7080fe7730b9e0676c9a58": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c3b34fb913f2aaf3f36bef02c20fdeea4ee0541b93337730f7374bcf4e29e26c": "0x0072f3efab0300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b471789cf60430f48687793ff23a84066777552e5e14a7aaba2e12b75c1d9936de": "0x00409263457f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ca80d98f55c02a2e8d108088b781ce0b4ca8303cc6006e72b3bd3fab7d99f48d": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976bad2f30876f406e954ca7f61e82532138dad18cda549bfd31bf45f83037f56b": "0x009e7961b21f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705285d2b67627342d20eda26ac41637cd32c0677da6251a4460abecbfb84c892": "0x00f67d9d3e8700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e3421ca364d240b9ad4bca9012fadc70e2f7c734895e3d93bda9989af7ecf92f": "0x001880cb1f7c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738c530150967a170af780787289ee0b33e2f655979f9a042f9baba621eea34ae": "0x00d03bdd7a9b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f8dad9ee41aa6542824534dafad0e5f72425a250416c8c3f31fa49f0d9fd91b": "0x004292e8484a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5e2c35fedd19964adeb0c0514aa6fa3d0657f5e808572cd96972275e51dbbc5": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e28adeb36591190f2996bd9dd5b1dbe0506dd7ce8787b4d547da82e6e446898f": "0x00406241594406000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a3ae29e2b3278aca8bf07cbf45d09e6a9f732c352c1c033cf8a0d6b39aea9032": "0x0080afe64af904000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44d8c5ecb1b94009145963370ed59151ba68e111f3512c73863fa05fab41a8c29": "0x00ac55c0712600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d45333762a76f91e4cf6b4c186f4f06242daf8919c8893f440665a567b7ebcfb": "0x002e275035cd25000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a23bf9ee36f21aadd1e85a20b40fb8460d6dd1388c12a0648805157a9c75c68e": "0x00526255c91800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f9fbca6b5a880670494489b24cbb4ad9e42c08315caeb26995a5464884b079a": "0x003e3ea46d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4af75499c006821c1b1abc17cc7a8010a4d0c8bc03b7740cdb377bde30b64b0": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397042d3eca29bc94870a0c276f2d285c03bcef02af8d935a5a8743dc0eebaad361": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ed39c089c89f829a21881984fdfe23486452349b2f6697bd0c15a1ee0c560cc": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4ad84c1e345ad4f9c06f4c41e0a37573cce74377cb58b0202990f38fefe3ca6": "0x005ce2476b4302000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972359ca6d2c2111c19f2bb5d67e07f46f0a9e4a1425cef937f78b4e2732a41eca": "0x0086ef35191300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972e7d5bed556cc624b1b25d7bc4611e3d454aa70f0f149f9df165d5545db0e3c4": "0x008015c5ce7b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff78e91a1caceb500c719b70e9880f207431789e4764c6b0eae04d625264a1f1": "0x009e1b25359600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793392572264c56b9c190f370a2e2275dfbed5cc537ae334a42f5515d661f354f": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397184864eda38675200112934c75eb8852d4def5a1dd155b9ebaece76b167acc19": "0x00ccf483926900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b98edc72bd8f849b47fc2f8ec07fd59a17af429ee9c7feb306e5b2209126a7f8": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397de8efe8ae4e905552287512100480858736bb689b0f34230cc16db4177359992": "0x00021044ae9920000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ff14fae086b15b5a9ff4fb34d8bbe0cfc81fdd1ea4ce544716f91cb6685005b": "0x00fa901bf31f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b45c027f07edff51fa31270ba23681ee8c3534218fd05d966f86fbc10830035600": "0x00a29f816d3111000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339761090e94773e281e074d40e3a6f9f6249cf0024f4de77782df53ae99d55e4b78": "0x001e076f490900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1b1912f549ce8fae24a22d542f22e90dc760ea6fca4fbae993fa6641090d1db": "0x00b2db83201e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8ba8c86dd8caa4b6ad2c93c6509256b4c757edd9b148a105dfeb8fc93778915": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d1d0cedf839e0f1243c580b58880b1b73e02d3c39671fb5562cd7a2b655e589": "0x00684cead73800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973708472cbe8043ccd43d5d2c359488eac57ea09af693a202841a7f2a733c9619": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339743542f767665cb165df64d006e570cc2eb383cc0b889758f048d96686017b308": "0x0090f5e41d0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397534fddbac734dc4a94910bc37f69fbbd82e0d1bacb46fa60e1c64d41b59955a8": "0x00188d22dd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ff777f387387aa7de603f3c8884dcb8ff896ef923ce556135035a28f7ed491a": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781758e7c38eb588a9b5381da9f591a2c2783b1f505c2f641ab1e75dcd4a40664": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bdc9a373c328c1928872e9cb060bd53a2804c5cd3b0f70054fc7509d54919a87": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f281dc549bbf774533e68c94fc96d10d97c7077f3323ac18f47eb45f7ed4f7c": "0x00624c25681301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b154d257a5aabe2444cc5dbdb77099b97299a02b1d04f55511c02c7c7f90fc0": "0x00f00f84b5fb01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a77674411a00565f8d02f40c78dfc647c8130d67f0d19e51c8afaf0f3ce157f": "0x00ca8f386e0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a86bcf75dd3b4b1998dba49f61dd7c4eeaefa5d98cc946fef360d2e816680c51": "0x003a3ce86a1d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e3167acf2a51dd05680ee8b308e8752b90e0c55a8fadc62f849241ed400585a": "0x00c48801495d06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972952cce68054b323aca010dc8704015596ed279866052c8fbd89ab1fbab724de": "0x0040222ec86a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976cffce8287f34891ff8e79b2749b43fc74b06072d012d187cbc0c49320ae443e": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976fd76f801ee73afbcecf26a573635f920525a65d2f658bafe33600f883475748": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f1f2572a684763c9f08b3d945f213d143755deabd93fc951c445841208ddcc4f": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397439746352d3919cba06acbb2aa769eecac816c3437f2f435507eb9db17477de5": "0x003ece57dbec23000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978340f58159a4f79e23193e97a1595ed6a586cfb6d38a4c07a0b261ae76deb67f": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771ae34877526fc1b2b5dfdd3c054b3867aae2e29ecc66962e2eefbc018217df1": "0x003036d4980900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4cbb88d4229fc8fd49f408dd102e9e33777e4a7f9b18623c2bab9534cb3981f0d": "0x0042b0c4556100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b49669a64740cf745804b66c8f917bc4ab2735089c66d40d8c95477f81ac769621": "0x00540ec8632600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4dea3ffc2e7aa5c5b6d6831d2cad7782d8da64a543ce26678c125c61022369a13": "0x0000434fd7946a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975107f5ff91483abb7e91f04060939b4a9fbe3fee0373a328b5973f93902309ff": "0x00cc087b5eff0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6798ee8b157d4b0d03a822bb85c440e82f0064d30a4a5e4951ad9972644fd6e": "0x0006b016fe1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a60b508eae97fc8ce6b4313ddc7ccdff6da7018a92b98c4b52071ad05a237f3f": "0x006af59b273877000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727205b9f209cc20090e4fa72acf677181650c2ffeeb0510eb59629031bbd6b71": "0x00aef96617b907000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397adb51575bca3934ceb1ce3b042e63071d90a2f258b037200f1d9c8ff70e359e3": "0x0066a69b2a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975cebbfcc0f5d8d6841ba8086f4e33b5e527e8ab58224fd4052e6b2b9019ef7d2": "0x00881529b38401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793880cc3a43c056cda36aaabeaf82b9214c36b9d57b17c45097ac58617ef2cda": "0x00421e33e0df01000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4842a67a9ee94a69fe0f8d499b6a218a07554ebad3475a3859251a32763478663": "0x00c2c5c6860c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b09c4fa81a4673cc9914f9f156e0694539e6dab93035f067075e6de4728c695": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6e2292b7f5ce1edbb03f88d8f8abeb805f36fd74fab5675cb344b1e2b5f98f0": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973465fe2e54c4e0acc0a8f3d23f2f0bdcb1b80ad7f9515e62ebcde655594a9985": "0x005264d85c1400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b49fc1915721843e8350824cca390d9868f7f8fb1adc37552284516a1f3a28cdf7": "0x00244691bdf401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eed0e260027d592543e765c3720dbfa9a8a9d3152ec12319aa499cc517909bdd": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720b82a85965b7152107002c25b91824488dab8c4fa5f1f24cf22f12bed83bb7f": "0x00c0fd2831272f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e2484836d16a13490887f7e144fc5430782ef89564d05c479fe41cb45aa5cb7b": "0x002afac2d93e00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b49d21668a1a3ef94a64a5af64a329c7541ecbf7ace2afb902ae2947399b4d8e9d": "0x002a07e4311300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243ccb3f8c195a88489438996f9eb16bc71088f68cbdd83ea35a2c87d5c99fa3340": "0x00d45be1e85b7700000000000000000020d96a8604000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397997d045efa097a494bf05f32b11f51c491b8e3f485e3514838beda7d6672da42": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ebb32ba26339347b4e83009e168888796123b73873e85d81cf21ef38e64d5c3": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773eea15a2bb63bbcc454f5cc88944a8cfe7641368d35273572386f077ad81441": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397734cc17b952f893758f51acdb5770fc3990d598f51303dc1e7d81bf4d155fb61": "0x0066fa41c93400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce4e344662c9851aefc3e333be7167b2108107db989fb1155d63d0a07e6ba61b": "0x008cc15e273d0d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fba2c3aeb42690b1137ee801e4a431fd8950969d74ee38a10893ea292927f186": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972301cfd620add909dd375ff8b46ab5b02ba64098904f83cc027b02afab8035dd": "0x00cc1013714900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397940c1621093d2f5b26dd8515adde6aa1347acc4194dcdb6b3e9745e4bec153de": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c91aa6647bd073b3e0cd3a8bae5ce9a431c051a039b7a99f948bcad5a37a397": "0x00deb7eff01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732953f7ac4adc5f8b13135e71eaca64667837c6fff2b62e901dd16d388f8d1c2": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970fa9ecb0d45413971f025b8addfacdd82580036e37decb9eb59d626cca9b239a": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e057a2b8323c917576c205e8383101b1628953d0189f5db1482fd1132bf959e": "0x00ec226f1d3200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa362ef1857d2b9654410fe133444f9b8c91ab84c9d62bb78ab801c6864d53b4": "0x0094bcba878500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973406e62e38f445c7e64356b963c67be9a495e719424a7fcc26eef5f7925fbec5": "0x005ea223252a00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4eacfe7ef826eb7e7b04170ec5386e0c353a21008b43741476ec6d0723527e527": "0x000c5849192401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb2c8bddb9207aa9d5a5821285404bbe4c240b585302d04c0acb90dfdeb764df": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397877e57ed2c807e969da6930161e158b4de21cc6b04495df3ce59812df24e274b": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970e1897c799a7ef1bb6ff5ca48afc20da5cb3687e2947de19c5dc92889e51b9dd": "0x00fa5354f60200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b45553dc2db9eab35ed889b303566d9a54eb347cfc381abba34b088ba46e176868": "0x00a85d62653804000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb39fe6329cc0b39e09343a73657373696f6e3a6b657973185991e3eaddf311ebc1f06314a73571ffe74f4fb643117931b32a25b432401f": "0x411fc1a5c88ab2bb7f63b23b15c39983cf38f3ac2dfd9c5168d5d7ebbad83544b46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723fb46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723fb46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723fb46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723f", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d5344081f29ed47469574d50f99be66de01a498b94b76d09a34c934d1b5977b2": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e692e01188e905148759fd115a6e47bc3b0a41b959cd847ce5b20688d1c301ec": "0x006c054ca75702000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339791435485fbf38b699f830800c553fdd8f6ba45e891cc296b19c0abd8a628b299": "0x00244691bdf401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e95d0b36a010ace2cabf2475b712633b7a35417640840abf82fc2f6bddab7b9b": "0x00581193490000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b41afacad27ecb70559cabb6caf6a625bd3769816b930596902dca35a7dcf64": "0x003cf35d972100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44f44dc8b1864565e9ad190a802b1f277b6993122c64acec1261edfabc62c52ff": "0x0000869eae29d5000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702859465ba9ad496d82c52ca148ed4440e4121a40462b45c4dbe28d2fd892144": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b77d4fb1e8c781c179e3de6a8ace53c3201575c2c7100391c94fb80414bc466a": "0x006a097df4a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d2eac8363ee4b62eef4be1b5cfa7e5abcedad718206eb03716e3b30f80f9cfd": "0x00f2ce1a272f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7217121028a9b57870e244b10b1db93ba7b21b918d7050ff04e028104082e73": "0x002c419ebb1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707da2503f758d9e9c3c2dd7532beefe72fb583e5f5fe5067567d16157b88463f": "0x00ea26c1d80400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d122a79f7029d17ea90536eaeef3aa3991845d43ae6f2c75ec3b8b410641e6c": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f99c2e5f6061f3a446ffba00f687ba759d6399782ef69398d7c431640688f0a1": "0x00fe42f31e3301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974037e7890d14d1777ca4db487bdfebbc392547b16926d466deff6d052460d8fb": "0x00d6dc8cef0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc6c2f88fcd2189445e112681f2c97f74a3d5b9c42c60f6b51830c3a1fb03946": "0x001ec02c1dfb4a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397885a74e0f27b36ddbf09a916512fb676790647149905c8037efe52fa80c23cf8": "0x00b65f759d1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397afe5802ce9fc5b2ac73379d354243d3e83d11b7814812dfa18e801cb5d5483d6": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce3c6a597c4684b875ef7396fc42bf42f6c1fe36b504a7b96474b50704957ba0": "0x00427f58a79b02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dca2f42dadb7b7e1662195ced1344d2e3b397949a45dbedbba48accbc2538c2b": "0x00c6c5932b7300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397726d96e5a59965b101b8e580ed098c91116828ff45fd4c9bf25b1775dd3644d5": "0x005e9fc7130400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d80a0d6b9917fbcb085ce60b340847de485d271f0c17278b3c475589e965b561": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976763305d8bf82f5d77efd2f1155f48541d113df08f5411367f06b7bd051dffa9": "0x00ee5692f26601000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b4928f23bb8bbfa6f2bade1035d417de218bc40a4d3f1d9270e4b550e9c6218d": "0x0050a95c091900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b459fd48f3366f87d047ba3711dfbb3e05e8f3f6791406bb87c5ea0468d094f1e4": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c5e0fdac13cf08a4889b2c26a1d326fd5f11bc51aeadcd0a28b4073db63d17c": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978c2dcbab41ec1c04fea89109c20494f7378de2159116c1e14f23d71987cf62d1": "0x00703874580800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40e9d219852639b17bc0fef83fee476a9269c0eb4a537ee46ec0acef003dc2580": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ab62243ce81805faca0e50650a216f2fe54667f06626c6ebcdfd51f3fe298ab": "0x00301a45ba2900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c32f12e2de4654204accbe490b9d6198a2c8357ddd050836259a84f764ba8bc1": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339716f34d37413c95b23a8ec18a9f2f6482c444b375eb867c7967246a027cd6556c": "0x0050a95c091900000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973889419c2db3e786bbc9e836cc9c315952c2a79e475f5670c5588a1733f577e23": "0x5e3ed914a3f9da416f69613d98c0848a6435ca4bda8d00af53a8a5bf5898b904", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339784d1f6123736f0ecda66cbf97024496e477abbd149acdca2a0b97dfbf4305701": "0x006cfecffd2100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4bf82afc94e60e8e44984107a15de7c79c5cd46212e124f819988005ea70d0171": "0x0024d4d8ace401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a04cd86b7efbeb8680a13bce1a93b2e19f16402332459e8c80402dea2095b927": "0x005a9010a19f05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c368a0b8bd718c10f9512b51e6f8d85e85e689dac41ce3f8a489a0845134c91": "0x0080cbc1f98e0f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6c795fecdddf2c3f90c2b3555ab3527aaa65334d23ae0471aef7c1abb867dad": "0x00e00d68c14700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339714f15168900c74f6fdaa26e7fb86f24d47389c405a35ef21cd1cb67beb14538f": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c4131889ecaf3f77e968d226c24fc7e3b5a9af8a3db585ff02098e4c184262f": "0x000aa1d3ec1f01000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46bd8ac4fd8983e3027b68b394e75c33c2cc34c1f696a48b622fa31515c084580": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ac227f883fe9cd6bca1d0b960897bc194fabfcb0f1f5e31501b8585beccdf9b": "0x00d25b92b61f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c01b4737f44e1181162c5dee8ab85ad54a2d4b14c4c8e4e5d7850d318864dc99": "0x00a07bce160400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b425d96534c5cd2686ba5ee1d4dba5ddff937a69a0509cc493188171f74728db8a": "0x0000b605da7963000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c0e0b36fe998cfe2b2d3e35d4e59a5ca28cb814247226530df4666ff535f9d94": "0x00d4cb74a2ed00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733a0c15def809bbb275381d81721cac8302ff8596c1e477a5a99050e36ce3beb": "0x00021044ae9920000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751582819925aa3767b50eae9d54e5c2ecb7767be53844a258c0f4ba0c764b164": "0x0008711b0c0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9fef3b71eb30622fd74306027c4acd769b38c693054cf50f82a3c47223682bd": "0x00f8199a6c0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ce77f3920e5d25e9de252e8215a08edfb4a44a4103acd6e687af18bc22e9b4f": "0x009693c5b96000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e442ce51af228e7fd3018ace5bb7df8276bd0f5f44b781159696de41c33df43": "0x00261a1f702600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975eb7a1d98c91cb43411c000234441fee0e15ac6c042f014f5aeaea948435ead0": "0x00f6d259bd1500000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b412e382b06c7aea3ab24617e0e49ad0f61c3be8c6454ce7244387c4fe514dc2ac": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397840afee2a276b201dd3ae19e5be94a7249bc5703b921d3acb1fab785742a0552": "0x00703af7eb0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e303a11455fa9730d42ebca802b41d61822f094d37558160feadade576c45722": "0x00bae4d8dbb77b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397456605a8db0d399f42aad60cf7cc4f62a09bc6f0dad991cfb1e4c5e7bac9f980": "0x00d42517c30800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708ec9c8cee8c49ae1f48d4726386ccea5528ef4083d08d055497a3feeb238b63": "0x00805ce547be00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979dee234be5196c23fcc660253e7cbb4a8fc11558781cafe37f52e4b73b62c316": "0x003278ff3d1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397617134293d892cd046e9897e2b2d5363ba6be061df232b35a1800f4ada770688": "0x007ae857fb8000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1254621a41b048186879661e6913fa463a8829960aaed78d273a4195a915f60": "0x0024858b773000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1dd0c43a0ee986683fde2c9b8d5bbdc2c87834577f917ef64d821e818802fef": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972794662887f78dc7bf10783a9c60091886495cbf652eb84a67d5abbd616875b0": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f845619090323913773eab17f7a202431c1ae18b33703428dc8347a31f35f3a": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707c4c5f55f17bf4ef73b2eecaea71eff731ed67e5688d2900dc93e7309239de8": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397838fbbb44e349682762c61b66df98f8d9476c2821d6f65e3c24b1fc728cdecbf": "0x0012fad10bc000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397494e067a028bc3a8e47d084948ec9df5765e7457051829cd8cabae0eec98aca4": "0x00523940c54600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee5def829790da3fe137b6fa22e21659a2403c17e6160f355fefc6dd4c28471d": "0x000472e3852901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397219f2a72e3088141e9dec06d557dba6fe23c6536aef89e2d72d46f795f3aed82": "0x00e04fa9956800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973afd5c59626469b8cfb8ebe9c47b298431e993f13c173b8fb966e2355b00fd30": "0x00b44bcbd90901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977834726ee292184aea17e359bf9ba2d017bbf04f9296813afc3e10519185c890": "0x0066497f817f07000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b485e466c0bd956930824487e2b329d1b833fb8dd50faded32d2e3d97b0f5b6991": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b59724f99572f6d006788cecc69e2c75d389e7a2b87c2a4e107f0f8976dabcb6": "0x000a357c2b1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339731468145599563fc7c20939d44054f9dcccde2af2852f44fda25e21f07c8e618": "0x00b2f58f6b0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f7a7a51b59231fdf58397d7bc8ef6d86619d726d3387384204fd520f1d95967": "0x008c0d35660200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970e44e9d7193a80054b84d8ea91773255bcd1bd60697c69c5e3fc3b7fcf2c5682": "0x00ca73a98f2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e7010f1fefc453f313f79fec58e1e58bc8d3f57cfd1d265988e84624b162b90e": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c99b90a765dca9a7c511c137da7fbaefd2da371db78ffa2b448da0f214b615cd": "0x0044135e7e6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9c40705ed03023fbc4a9ee0b27bb42d19968ffc36a7c469f271345958282659": "0x00fc5e9c971e16000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397631e8cb77937226d5d564d41afe26f70cbaf5602eb53df84c63c18d9d3548122": "0x002e808ebd7701000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d872824324b1cffe3c67b4fa4fac0de9c461c26445222ccee3bd2f9026cc44e907699495": "0x00e0fe36966e94000000000000000000216794a005000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397db91780bf30890a909a85d6a5da4cc0eb7fb90e1e9b91c0e992c56a808a3a6ca": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6f06fbe7af213f9b5642cdc32b90b1b9d41267f1a1f8760e5f0397efe248648": "0x00d6cf06ca1a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979475d97d3b6ef68496025b690fd5272eb941af4f2206c19b46938372f186d888": "0x0036270f8e7701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970cdee41febc10da3b4cca5d65fe2f4a4bd224236e788819f0c9b2d423b975d02": "0x0088c596351d00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b496f85828d8121a93de16b74433c25880f151c4174a07c8c7303f7041b557af32": "0x00825826b37f12000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ae9b17db7cc854aa34f008299f73a1d2c75df7d3b800f954f0037d22a6909ddd": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bcf53ea60f2f640e33f7365213b5f206041921286b5e959534d2d970573af95": "0x0074aa57de3101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978239f70820c30ad94a520bc62ec9b3283165e93aab94e858b6de630a7ead2b23": "0x0026da6a887d25000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e762920380084e64ca750c8d8403a0a5480eef29d2303a76fca9ee5270abe02e": "0x00d22374f95f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243916c8a2802d08646f0782eed3a2fbe48dbdcaa5034109b4508cd0aa3dd0be3bd": "0x00d45be1e85b7700000000000000000020d96a8604000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764d2ce7d5323ca206f861f436f58a7c4d89df57ed5e6d01db6f660f47defaf4a": "0x00901f44ae003f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c783f9dd5d06ba309c7fdbbe9910caf92b5e665400305d0870a68da045091b1": "0x00ec226f1d3200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339714a4b8ed05d5e419065d4403c40dcdf2c674e1b470bcc0bb8eb200fece975256": "0x00b8ee71e14001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977eae2d7b986f6f0f00a0d7a9b1080a0b5cf1699bc1c569dd37fb3f48544645a6": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c1dace57a4226763052ffc92b8ed478bee699b2bc37f248ca16d80d7f309978": "0x00205917580d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3a9efec00d2a7f5a39d5f507e9b4c50686101c56dfd8fe9c54c3f6b1808aa1d": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978548554a9ab820870f106bcd74980dc046336a4330311799af6029e4c2f5505f": "0x000c5849192401000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42f9b131df6072a83ff8561a3454c091de778151d8da299bc6a35c6e0deb7326f": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750adf0ed850ca74398086cc5cd762423fb466257daf32b200c6a9807bfd4913b": "0x0030b795620700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970772bd24748c2d2b129168d0b23f6bd99501bfa237ec122b8b40decbb4279de8": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397731c214051abf5a2802015d2c71bcb92b267c502c120248e1c372993efcd686a": "0x00542cdad50100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718c10d31a81fbd1c8b017cb0ad339e536f675ad25a03d480551794c4a195755d": "0x00ee853eab0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970eed3827be8f759462f0ae66778195e788ccc72760e4b68310aab2406e4f20f6": "0x004cb4d510fb4a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7c08bba3a4378c7a78a42d97449130b9a8e9fefabb32c36dfc64c7fa1e156ca": "0x00684cead73800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740bcde914591be0ea55c5479b52782e7dd56529025833a7d6a5369f038ee50de": "0x0082663a29ff6d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5fc87bdb9d348ec4734060b29eaa3103bcbd13dd50920ef1e46546f77222535": "0x00142a8aecdf01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397128f837cb10eeb57c4f8cc42cdaabdc935830b39ff751a80da7ce49d78d7c9b3": "0x00ee853eab0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ebee9931da17ee80f25b1eb9e6ccf7dea2ef0ac49d696b5e0e26af071b2745e3": "0x00bc7c65071400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4513e1afd2ea2cc1b71e86f80ee1b4311c900689a1064c8008520db41317851e1": "0x00e42b2c22294b000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a0c9c6efe8ca0cc3abc38a67b8514ce3f0b61fdc4ab6f4346af42d4e038d671c": "0x000467eeed0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d50ac3f8e592913630d151a4474dab38801026db1e9622c08b3ce20a98208cb0": "0x00ba7a93d51100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783295360e02b5b2a382c977297d8d2ed47b1b048b5dfb270a101e18d2da0d781": "0x000449dc7b2d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977a396cb25d2bac9942b5fc1eb7cda5874a1b126bb91d263ea7cdf500a5632dc8": "0x00f41015e14b04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397184f068dbb18ca09fe72241fc47e863c3c00bc215eb91a7b6c1ef5ca20f54980": "0x00f85e3055e100000000000000000000", + "0x2099d7f109d6e535fb000bba623fd4409f99a2ce711f3a31b2fc05604c93f179": "0x18ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc1677b46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723fd684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e17968195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e9411a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad820018168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da58009", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c088c440ddd847a1c92fe44c77cd4dca56c62bfd313ce677cb46137f3a6db2c9": "0x0060f86c8d0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be0255e51897933ec18f6cf9c44cacadc5e701a91f7d73bb5fc5574c6734e326": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b789ad9da19ac5b75e329ce138ddbecc6de7813f975439e86b6e9f2e48960e2": "0x00823eec0e2501000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339726bcdbdc088131dc85cf2674c308c94785aa41889b0ea0ea85c9fbcfa888146f": "0x0042224efe1700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42ad8c1e97d2c8faa7d56892254f9dee146f73fa3ba3cd965a31c8d630bdb194c": "0x0000434fd7946a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339754113a167e5bc4ed3ed42f51c3d43f706b8fc845740cde3d25d84f7ace34e11b": "0x00da07bcc67c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d797007499b97b31a755ff665935c0b995c857d826ead3a59a3a799539a2213b": "0x0054daaab8531a000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a77acc3967bc83dfb00d72711a6f2aa77984b5c99143281b5430c58e5fbb4ee3": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f33a63ba672eff6bc2f676da96d15cfac312080df076d147b7c20e054b2d9868": "0x0088fe199a3012000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b3fdfd0d1a7bb99dc2cabb394af9239eb2ca696d2c753aa6108eacad1571ab3d": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746acb5b327ea208f0f577f5d6681d3240ed352d22221fe0ea2a331386132cbfa": "0x00624c25681301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f24ef5227adf7dddd6d555b0963d84428bba066774f916847e44d8823b9855a5": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970add826e870bfea68577d447926caa3ae6e7b4c997f07cdc870f3d3360472602": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738bfe96aae343d135c2273308dfd12f5dbd02f1289cb885b35258d1f9a0258cb": "0x00a87036668100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b37f60fb942eaf61c64ba1780e41c0219842762d37c0c30338cdbff69fca9789": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d20b09743bed65f6da3b10858bc91c2fc590aff93267f22250b60be49bf8eafa": "0x004c343ee04c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339706a3ec78e99bffa75e187aef2a1361c6e0d4c4a48be04fd6ce98f2737c3e5394": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b17271aa28133c9a5469f43d3626a0276105eac4414efa545016c66ba103df99": "0x008a74cb221f0d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b038c38e469bff6842d33970f0f7f4e98bcedfd82246473837f8132a0138db9": "0x00985db8783319000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397999cfebbced3c77cf6262ba4dda9b1761cccade66bf9c191e7121ee93e115cc8": "0x00089d43ad531b000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b48f15b4cbe531bc6b239eff53a34081915e2594df62cea3599787edbfe2066d64": "0x00d6cf06ca1a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972048884f4cf97c937234e1bec98630bf96bb9f9ba790dd0af3b791a638b01ea6": "0x0062ad4a2fcf01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972abccb6a55a5da8b67bc3e90ec438cd5f38052be4db36ee9447072f1f9e569d6": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973cbe15f62ac4e29402e2b414ca66e19dc1c8bc15d86390029dfe4f7c15ccf4ff": "0x000cb2866c2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786c14477c78bf8091e15de92fa49120e55b0229278173c89c4e1e7047724f5dc": "0x0066172ede4c06000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b480b9435e656c8d37c51fc69e93feec2d159aab6cf5e888267a7108bb9b2ee15f": "0x0074e3f0486900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339710297237efab673fab1df3db8426a623ad70abbb61f4cd59123de10baf0ed57f": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979afb5373093529c16a5a4a1eae86b2dfd5f94eb7d1d74b71a36bd3c98db638aa": "0x0094e7521f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397396320d55eb1ca81dbab001c5b4df2fd4173b74d8b53797c1c0d000e468afbb2": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339742af40afa40e1b53e54063f83b5559c04c71197269feb0bd7a887bc34bb38e09": "0x00da79080d0401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e32f7a4cd6beb57cfba78775ecbaced4f048ef2be371e2599492a40ecf45e06": "0x00663dbd474427000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c63d41b77fcb6b03bbd9330f1a31d359262f165e52cbe8557ece5df5517a61d": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339741b6152d7b3742371dfe34422edb833dd2b3f08bb1658116613f877016dc008e": "0x00b688ef6e0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9bf771203a3c05267f629e48df33bfeabbacf6e60e5eb08c791f4178ceecd95": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a69346652406feea422447a14e9d4b69a5c1ab51af78d3c234563097b7fc712": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e66c3ba225cbb941b76e2289300e859610bc70d59440da0d65dd3d5f54bf1ab": "0x0040f09bbce108000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973bd4e1c68a9abe2ccc5b98c3f828201107fead78df6cd2425ff95e7c7bf972fe": "0x00f826855f1500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973493a6769216fc5e98a60b6eb723c64d2a2a4f72e72a9bb66ec7baa04bf445fc": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339747b4583d50fc1f64cd31dc8510df2aa452ef0b142f1c9feedc5f01adda95c1be": "0x00406352bfc601000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41ae071bcad08c3a2435a5fdc7ac2f912bf726716cc494430f9aedca5299f82cd": "0x00b638bc35ff0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978fdb892e0dac5cf839f29ba8dd52fb48a8153594103d94f893518cc9dc0b548c": "0x00e070e8b01000000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb39fe6329cc0b39e09343a73657373696f6e3a6b657973cad9c169c1c62126d0894e86e9f134182b99435fd1e9757d021c29832b076646": "0xf45475c15d447317b7de38972656d207e362f7fa4429d665ce10a9da2ace254c18168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da5800918168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da5800918168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da5800918168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da58009", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978db75a9da798262251e0a1662530510b292711075e9af9fc3de5569fc94fd5fe": "0x00301a45ba2900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f50fcb27915225d87c756576219368c84cfaf086c745e40bebb3ec1bed4362ee": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b5be522954f06d16baf26abb6010765f60235174d123dd1080390012d93a0574": "0x0098d65615a101000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b45a9f66919e6f04d8dbcb0b1956c1b9eb750a6dbc08ebbfcca0f27f0bd0a290b4": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bca9a030ee36cd32fa6751d629d533bcf5f6ef13c3e9680b64f2426a9142cce6": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339737f40ab390a33b551ff8ff69340dd07cf76ea36a23808a89baa49f0b300624f8": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fdd8b6058eff8e0f3d273ba92a773c648aee59715121b0fddd51d2e91a4e937d": "0x004043148d3703000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9c9d550da30deff45c4b419cec63b7ebd63860c67544e8a2bca12b8c228e49a": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397140ff3e78e5a87925b4ce44c2b91bd65c00e46d5ebe4cfd064965f5413505788": "0x001e5c373fda02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c8cfaed86d6d385d7b20c7ec94e9b3bbe0cded2eeeb591b59e42e715c3296c2": "0x0002d580a17400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282438fce62c8e5cf3d38204b70e588e4d8ede1025f98593616e45843c7ad1d58deae": "0x0080c6a47e8d03000000000000000000a6ef7a2200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a3c5d810f32d22896fe8bb63cd77f9c3c075965e4502b4e30bddd91e6bddb64": "0x00769f7b7f5300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d67d83577a984ffeb93e107b8c74ef7f5a3dce23ec4502b958bbab972fa4f30a": "0x00d2a4642bb700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971dbefda38295f7ebdde819a153e8b578cca7fdd1e95943ce7ac504c5f041ebfb": "0x0070720eac5800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a2934c430ed73e6d6c4ab189b5507587c09df5344104bab1e4a96e9ccb81ca0": "0x000ec2dc1ab816000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4761f965d08861a460d72abfd2cda95138ba058d1d6e5d4cecef637d4b614e8": "0x00421e33e0df01000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243a3a59829e59a4cfc32f5ce21b45d1c06c2e0fa883df5e8f261c0add2ca8fc792": "0x000c2a4df8178a0000000000000000006d243e3c05000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0cf4cbfd2bd015bfa98ec98dbe6971d64bb1ee2300612a2c5a8845682e1f6e9": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff1238be060a274c5a2917e043f38ad7a1d533713d0c376927838569ebbcb46b": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a13b3f73f65055111a283c3762f103a56e8b315b809073f5522996a221ccc92": "0x005892837b5700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b445b0fb57d713680efbaf7f194df25df17e793b1829fc2880646f6347a375c701": "0x007202ee615f09000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e44101503fa6c5f36602b0f54c98bb1208b7f52f3663e8a23b00d38a446bf9b": "0x00188d22dd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339706df00ede31f4c5716ee85e2cfbe38dcb9d8e00444c91c94af8c864e01b3fea9": "0x00226399efab18000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e35c7c080e52584dd84b45ad962c805d53b9887869ec1c34772e2d87cee858e8": "0x008025114d8904000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a0457a07d19fc10928d10961aef8996e871dc7fef5a78998a07e81ff1a3895b": "0x00703874580800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4099811b0d2cdde53295bd7a5ac1f4b30749317c0cd854d18c500a4f607e87332": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977fdea030349a680b7f024ae199fc624aed66a9b1afcfd7bcb8f1e9a5e0ce1dcd": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976138a4461802573af5b4569712452ebf1f4ebd176fa861b6c0f2ba960d094ed2": "0x00dee251231a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cca8ef3794c838c9ad2e1b6a7ac01ff2dd52ddf7046e08e534d09134b16307cb": "0x00dcea73a01f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bc6f4c280bc1d89aa90d2f3e4452c55401d6699a5b2d2b692b0e36c08e314b0": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768e74604bddc185f37e0cd7da36497bfcd6c365d89901dbac0f5c9868c36151a": "0x009c3a04d74c10000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b446d9a002e238ab1f2cf3dbbda3c3ade40e1711bcb55ba13183b3a07b17744154": "0x00989568830900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d872824308e0a2f0e999ae82dcb4bdc8bdf0dbfdc18baf86cd78e39ca7ca41c7c8dbfc61": "0x009c1abfd6ba6b000000000000000000206d8d1504000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6cd7f632afe15a36b13eac494a9c4a3bba3b6929895cf975e3236071497b938": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6ff6e14c28c9c3087687524f27442aae588c2572d9b1dcea5024673385ccef8": "0x00488c227be903000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a1fa38b818648d04a34913261df63c14da6e70262e94766d6ef6c906396302a": "0x00fcc4c468c320000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da38ae92e6932dec243e7bb4ab9bbefe65accc09bb40b151bf88103413c82c47": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765922a92ae4df7ce35deefad339b8d1fb911b79d3517cf3b66a6eea579bd9d3d": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a1ac0f66f869270cb1b5b6a2a46d8299d1d2366507777e07a5b776dbf01872b": "0x00a031a95fe300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f894958709711e36eb4bf19d767cd697df4fa72953e454418a7ca7601943d76c": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970427ea5d7ef99c821faa6b9086bc40857a78b075687eae16a9a1a515f5f67833": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bebd5e78466ab2c98b3cd8b217bd0b4e6e7ac401b62e36a66e0e0cd5cd20a47e": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0953adfa9cdf494f868c12dc6989ae03c05c1828b9a57cea41e1a42aa3ee916": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab094d75d93e6683344f4dc710e41852292b6f9f39e66e0305610361bed2efda": "0x00b4d919c66400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786f9db90362072607b0f46d3753ffc34466c291dd2cf6bbb00bd6200f3f88a4c": "0x00eca039a32700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46803c06cb50575a857d616b7a56a8318824c5eb070d4549cfe7f32060b0a4542": "0x00321a5ef36b00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b291b35b5a09b938edfd10fcbacc615abb0c": "0x12000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973838dfa3265031479d77aec89ab08d6ee049eb33c42e1e5c8a4c3a865e4f8f52": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339728857bc5d0be0ed73d3421ef5e50552c504b2aee52a2bfda041a3afbce46063a": "0x004e3ef96e2603000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e75126c189a0c52c0032063c36617e81362ecfd24e7a5c7d9c3e259b6360e0f12310f": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455310b88d78754004a285b5e8dcabacee518301ccf46c48d8de53da4821053ce798065b914ce57e256c7af66b34f7b442a23814cc1584bccd64550c8c7e0b265e73b7fd6c0f0b3e8b292aefe2d57f56eda3931aa84bdbc2afd2ad9b8aea91aab8ab74f749ddc93a65dfec3af27cc7478212cb7d4b0c0357fef35a0163966ab5333b757666c474e2f859bb39716a333ad449122df3605cf2d272ab876171d0a61cbdd07383f6c8cee12a4e767fc9012639af86a5cb0e6079a47bd0e4a66df193171010f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455310a44806b5a6313e34e1c81efa55cdb8490770456364b07c1e56479ea940fd2ad5f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455310988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553108be4d59e1111ee942e04ee5449f4ed59493a65f9dd86edf0d28ad011d84d58001143c86ebc123cf0428b8d194ca19f43cf153792330ec1dd9c15325ab8f8cde6f9cf6346455aff64b7ca24e354ec2efd2aca023eafc4a5d9338d220ebe58245f17667171c3b0dd4476bb14003492aca83308a4d03df5e1c212605c841807a6e4ec2930567b62a6e88ddd91d65eb31331882234863fb0a8a6f46098aa45b9c5a0e1e1031c99a84bbdbca5c5238696791640981daf65140360dab49a457619b1717c5032a7bb8c6d069abb4f8969999472d20efb052cbac29c09bab99b6bc9b3d56deaa788e2b9ff2b707cb496b9eea85f891c723b489e78a9e2275444af678d304ac4c9729f118f6fdfcddd3eb272bee0228787f701757311a6e9f8983ba52b530ae277e9fae175d69912d4eaea13e25fa1df68883d7cfad302dabf37d5de6245484583d9d96ad734c94c2a8e35e9545434a0aaf87ef3b14a3aafeeb6f863ccbd4c283e873fb6464bdddf90e0b5a0f486535171834ed2c5f3fc9c01eaeadf05b7676729e17ad31469debcb60f3ce3622f79143e442e77b58d6e2195d9ea998680db8ca7586deadfd2c84ce9d5e964965b38e7c20d0d5609ce163c5047195f774618af72e08affdef4b7da68950bc485e933929281781fc12d524e98c8c1e90a41dccc83eab7836cb5f5d65190635c496470b3ce4eb9b505a711501fc3795e68f3659bf5059081b5ba8729c7944309194d9cf47dfc0dd9255166373fca9c1ccf93daad717d8a78b953151aa2ccfb93b48e3aadb7e84fc995491b810f206215414e73695abd0e874dd639c8d66c7b9e2af758b5b36de36bb01f0e95048cfb5e00f68ca228690381b9fafd16218c87bb0bab8ebb6db4fd3fd4994873c9b88cf3cad7ba0ea063ae5ef147ed12d8d69625d1e97fc5d527cd6c7d1140b5a94dbd4141f44f8fe5254bfe0680181070979efe72c5eb099043b30074f30dd0c15a84abc445c8a55ed29d113e0d64aad31f6877f7f724e8b3e2c384ae1c00f31da3720d47994cac28b50ec77e1f824e485d02fea983bb84a15959ed55a855e7f1ac4b1491643c4e3afd1ce0b8bf479541e3c7b1329897f65ad808d9dd7264b5909a4bfb7d63a1ed81036900b804ca0797c809eafcdf72d44f25d465898c9c004d302f469356c58ecfd5a68fd8ca1da05e049c26ff34b9ab4d6245a3e7f8e11ee5b24d9ee930e1c7e5c34d912a5c52443f04e01f962bd8454395c0ee1b8120ae84fae4079c13510afe343fd4a4a5c21f15cb0902fad69e18053c9918e48f3bf2e6a8d6f27f9d75a727272c1143df1c5f17343f9b1e84785fa861bccfc82c0284fbdb9ad59a7a5e80da4c39364068f1623952a196e57fb177c64e4d9e22324b80e7682fa97f34016886826bc110b26967c042dec94fb4a9b0bfed13b5f8b4dc00eec7b3419ec165cd992745ac97a51f7535709b288163895baa3b70f2620c3141f9a16b8ec8714365572e4f9d2762cc1c4312399485b3b3bbfe113fe2b5a12a73f9ffb5b9e694b98b834750c1ce700978b737dcece0acb33c01cbb2cfda7d07c5610bcd95c9f1070eda832cd7a8bdb1e2f8d8482a7d9448011029bb098ddf82a98f43cd12994130e4104be878e56062763ccdacf8fe28456f23d5d897404d32408cdf87b1a095788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553107b8b42f8f879fba9a112d9ca04605f67400a687ddbaabb883f9f81a7f4300f10b0ec611076c371039aabd585ff81f6cea47e94f526ac4d374b52bbd234fe02b2f0f930f177891d22296f55fd8d9b521d24fcd482e5931c168a4584c79f7e934199a7792b00a63329a247f5a75f7c87f28a3802c566044335df8320cb9ad78665a78e5a10b37e92b89b2a1e6d67b562da75eb5fcd9d75001c61ee625a688b63d1180caa53a3404ff9fb0ae79eaa486f7afa9e1531b97bc81caea35985b9f7c3c32c66b23b00fef56bb26c023059b77bb70cc9b41b7ee3251f7eafd1fb5c34c5f671e0a6917ff1ed3d4f87949fb4fbeb3d175b3065e1a68ce2ea09020b01479162a9e8183157aa5a4a2aaef7d51d91fce7ef7ce3c2208112a8f2abe66092df1b96856208625541b6ecf1bcc521bffdf173a21433afacfae5fccb3bbed79840f8905accf410e1f04248a1ce9b70693cfb6c0cc7647f11ee112806a354fbb02ccba0a2a0d6a5f9c64ade09131d059bdd96caa28198319f67fbabff92d5375a0ae02389a4534c80784a52f3cda33d89658bb22fd0267c637769d4e41da86dd65b949bed8db10fc7f845a393f39ca5611818f89daee51ad7273bd7f4a56b956f95a64145c8fb42e80bd47cf56e5f6255c175819a349ea6b93ef127d763984b3fd714f31", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46e9a5da7dde01fa79265c0039ec2aff96ae63d59b060aaf37faf579e5a6239b4": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778fbbd522a82beef632d26afdbf75583c140078904f33974bca69b6d576536b2": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397abd29bee4c14a11f0aa43143a0993b9bdf19e65168e30d19bcfda29702312a62": "0x00749ddfb21500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971d1986ed767cb4636ca6b125c8c9ac32114697c04ae936be6d789edbeb353b09": "0x001e1d3f083200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c71fcaae5a65bf0255ce6deacf3e688ddbafb3439911fbd3bf9f1983fa10b2ed": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d78d0f66f39f3ce821a919ae830cee7b860e1f9ea944f6236a557b1430f29ba8": "0x0080c6a47e8d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bdc1e6732e6c17002d3b8eb8a6a911193bd2696768c323a48509f1c5520d121f": "0x00769f7b7f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ea67b3e5bb9d17358af6f0536f6e3eef0af2e813d9edcc3d46b0142076d64ae": "0x007ebb5c423f0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d367ee3dee78bb26ecdb3f1aa9e45294dc83f01829148ab473804e6b39868b3": "0x0040ee7affbf00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41b2027bce60d117bd23db234e4f17003f55d2c1e71c563d7189977ebae960ba3": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be70ab4f36364d4d08f7c4e219e91e4d84f459363414f43a4979f1ae9ec5cde7": "0x004010ff621b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fbf71142f172fe154b2f6983b7e9be5a779b2efe041f90a4142201779a7381b1": "0x00b4a102061000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977fb96e19a97a9abbb65e7e27611c201b41d1c3937a4a348a88aa8802e7ded7b3": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397641957b230bcafd4e9d85fec2269a91b9cb576d357cef0a1ad201daffa3fe3eb": "0x003036d4980900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4fcc4f44287d2b7cf00d9a0bd70d0305f6e50e1839699422614521a2d988254a4": "0x0000ef73b31600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397687d40f133b6d35cb65e6d3e156a9df59e0864e76b1b9960d2cb524b61a006fb": "0x0008711b0c0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c1890b4244c1ad184f2d1acc0a8113e323ca99904f84708f241a10098e0079f9": "0x00d27175e9f502000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783e41ab69fcc6360e3faf5f571683d49988d678bc3b9eecd62f4bd8e3172438a": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397198ad24ea7abd142f6538840f879ee0acbfcc87a0e9c6ecadfec2b95ad9ca5b4": "0x005880abe94f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973bf0178260f084881a56133e1e9a480c4547066ddd56150dc7ea65db4c5f90d7": "0x00ac81fb215a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f2c25372b894cea82c59fe6058793af0f0fb88238370cdd1df0546ccc026566": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397676d70165cf4daff1fc792f7fe92396d87ddd02a1cc0814818fbc92d8c13bd83": "0x00b875ca5f0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d83465cbca77fe97b60bd273a0fe1feb51b7b75976ae96ff514d375244f0cfca": "0x00b02d87f5a900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979d8d5edbdca700c77ecfaf64a715106023e687eaa39c1883de9fb1d3ed986d75": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339735052fbf04d43dc62fec473a04a62d95a142af0e6424ab668dfb1c2337018546": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397951e5e604f0b4ac50af235475be167f8c5bd01d32a55e621bd972aca9751ca94": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339795a658df039d15b0fbfc3eb8605b3c1b3755a8d1887e9a3aee13dd3c251b454f": "0x002a3246641c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339737749eef475d9b6c42b78db934f2407dfa9910ae15e4ca5a75a6e4144ed75ffd": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f5ee55ed6cf4a86743411af8dd6002bf7936c5ebd2d8406ba48815dfa5b94a3": "0x0068367fe62d00000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579738fff7cc92faf04763097eabf4923b8e53152b8cf4570d76dc5cef74607f232e1": "0x7ce21330f614e9f11065cf3e7e96207fec4086b7cb83584daccf6bac6d35d16c", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282437e04b920e66f97ee56f3aef9106f0f0a6135c2bb6e89b4cc6a63ec8b95917f91": "0x00b072e0e023200000000000000000001f2fee3701000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978aebeb192944d94e757f0165feda76794f628c9c69704b6dd510bde683fe0b56": "0x0010b4426f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d45a5bed19fd6dfdc7c56a9063ef487e032b6f6b7fab3f9d4fdf6a7d52170c45": "0x00f45c7452f600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e637df8d67b685b610f109fde312d604c8a9f3e046810ab3b7c5344d947cacee": "0x006aedf4123200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ab3926aa424570cc17bd96e2f315d159cc2b6298ea5abd09f51d6439eeed2006": "0x002acfc5745300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4178dbe11e427d1edee939cfac2b88892d15eac14b9f323a8a648efdd7875bf9a": "0x006859ef3b6102000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4bea566e10311e2a2c11e747610b3bdf0fd9cc949a676131c2414c516b808525f": "0x00d22374f95f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4455b315c37e2c7266fd31b68b850cdc3a62cc793acb049bd41025463a6d06654": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397689f3fb366c82e7c85717703bc7c8b1af26d100b1e9601d6685e64be021b6664": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f712571a476b511525ee202cf6dbc60eb6682f00a5f35e60c920c8ab0c840d9": "0x00fa7c33951000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca308ce9615de0775a82f8a94dc3d285a1": "0x01000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a7f900780d0cd10b96fb7ab0d779830a88f81d5e90602165cc364cdf9d2b233a": "0x0024a8be34cf3e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732adf0a8caa14c2b9aad34484c60225e17088d9986bcb405a308bf4d61243a6f": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970257899c73a3575b8e830a99d13f5ca2d0d34b8fa2a41eb1c7eabfa305f7ce5f": "0x002ecc1f8ebf06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978cbbfeb43a25f4c787c7f4c99325a38e2d2494f1c3cbdcc75975c02ae2e58c5f": "0x0080f420e6b500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339725510d736793b76b0fb84381f356b002cac2fbd3351d6f8da6999cc8472ad515": "0x0074f9f66c5600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40a41b262709e64dc9956e5e93db4a7e217db6ccff10125e3fe2e561a910e0195": "0x00d4d44477c502000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ca7e1d45833f60f60b0daabad1ec96e00d35d053a089c82392e3c9a6b993dabb": "0x00563d1a8e0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0df6465b4a29356069006b6068c9464f97cedf3c5af4aac37e0459510308a14": "0x00fafc0f343c38000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783fea13414bf90ff3514c2661be75d5a90cfd392522c19e160d0afe3786f93d9": "0x008c0d35660200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d562df676bd2c52b4a2f05c3088cfdbf7f4eab2d134c1f4e51a65c77a72424c": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd3dcac29fe6cd540604eb17684e772d7c2befe4d5244c6f08bd9a863ea01859": "0x008c2a02902a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d93fcde6e1a188877216133ee4025ae2d75b679b513a825c16ecaf24206d2077": "0x0080c6a47e8d03000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b45c03fcffb1a72f0f8a4ac38bae172f6e7ad04e4f1002408284edd7e34f91fdf5": "0x0028f637af7c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e56427d4f2895718f985423534cf20984429a108c348178f0027d1a201e28301": "0x00c0ddf9a28300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6ea6ef5e123dbea0e004e5349da00a746fa1b02d24def5b46fa00bdf4bdd9fc": "0x00e081d2cdac00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f8e25036108a3737cdb400351b5821f25ac461d277636a2038598d32ae636ac": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a34be1ff96a02c4660f24398fbed24d9d3342c4bb89ed0240da9bd9b646ee6b": "0x0010fb62e84e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d4f970d8a1a28279d491c098ba977d212429c93dbd054a0e44a6d758ee971e8": "0x0038e451d40800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e25c629f28ddde70c6aeb1d55964fc96b174320c9917cbc7c37fdcabf00b49f": "0x009cc874400e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e058165e7b87daba18f3ee9b0ba59a1a6c2eb1b5e04be736a65e5d330d8c1660": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971b3833ad709024c7eeb1aa35f51cf06a0dab1026494e91c773b29620dafbd22a": "0x004a61a31c5e04000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4274f4f56888cfffcfa71b364015dd34f8aae3f0923122fbd78639f299936160b": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732cd7de73177849f23e359b0e4e1a431ec8adf11824823380a6b2f973fea2ae5": "0x00943d4de92900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746cae6626514282b1478a6c1b90385ed4a4af3c93e3cabbcc1501e5036a354cb": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a4f1593a4af4d545aa176623d49226c2913a29a0e874008cd3d43bc0f562ee8": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f65ba9ff10798d73a65538a500dac5cd11494bfef111f88d516aeab00aaabf6": "0x00581c527c5c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da7462891e1f5029c465abc3db3d8859c5cdf57999eeefc8559bb8bee6061674": "0x002cb5d95f1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b31ae8779f7037be320b905b79f04ee79aa0f25cbda8c56024049bdcccdec6ab": "0x00c43733034100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397113b6b6421084df50c05c691a569ccb22f27dc28c72ff024efe87378c5ae94e6": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977dc9dc6f9ffd18895bc89fbd4e6eeaae4d55580581628d83da97f2e45352da22": "0x004e67f401e000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4aa5cd4b3ced035011fec1d41b3e4ef15eeb7445794e20feb20f017e6f15347e3": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977eaad0b3c5910fc7edc8bc9d554f241193d6786bcf3b7a9e784e06501da7da8d": "0x006677ef716501000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f56daf5420eed45bb1a0da2455d0e798c7589172a1ea32d18549022f94fe460a": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fad1b8633c6a9fcdc646714045a037cf5cac26b0536c6eef1c2824bab9f6c613": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339741581e7e97084ae0e3df8639275c7ee3cc95b45d3407b55b4d6a3eb6bbb93591": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775c32e20ef17142347dbb3e6b9c07a018d361cd8eafb3239288444733767dc30": "0x00f0f1bc9f2500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a00625427025598cdac59fbc9c4fdee032c643e9395401b667a13877435a474c": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794f0460250ebc530349be56c86ebb55206906115bbbedcdba400716993b37765": "0x0020c9e7070400000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973f2f1ad465be4ffac30dd8bc6c522f448a2cb87524bbde8ca93c81b7aeb0e3df1": "0x7a977e950acc55770b4452fc418bd59fc4ccdc25ce3c2d4cce58dd0d6f9a2d15", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c21e46a4f95cf6be57022f95b71a21babe2bb5e047fabbe9fa76163596557f68": "0x00f41140b8e601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a464ad173716f23cd4d29b712191fddca8ed03702f5728aa8190e309bd37a6bf": "0x00463efd4e7f0a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397350ce34419f92ac5e4aadce1ad6bfe5a2171c1ec48595dd0d8e580c74ccc4c6a": "0x00c6c5932b7300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dacb479b4507d9c7e1c21f35ab7a703a7511d7bf98f3b115ef29c82153dd1062": "0x00f889cfe91900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f8aeefc6f35613a5e8f7abddc5967428852b1b3431397e2b6cb2f9904dedd60c": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397309eb3856325e0cbba9a4622f164d2aade71c9dd494cc38bce0beca078a52374": "0x00da5001030800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397208857b2443cb23269809fc6be935970b76185bd18d1934161b684ca1f4a5fb8": "0x0058823c772100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971dc94182f190bbd123677024348620bcea71e2347a668f3cbcd483c6aeba725a": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b43eb98c54660a94919cf760008436c8ea54b3719dd102a8b9d64613fc59afd": "0x00ec226f1d3200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bfb80b1473204da6b416add4deb918834f23be1e39a8a3974c5a7cb4f3caf91b": "0x0066a69b2a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc3e81cba512445b01bd37bc8a5d6df3fe1369fa93a983bec0ffca32fb330dd5": "0x009e05e9abe400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e4b19ce4928ef434b3fbf8c3f0975f87031f15147828e45f65a8d7f4569a888a": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397599a0618518f265f9a41e572bc7c18b3e56a1547431cd9965bd74c3ffd4cfab4": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339762caf70d70dff4ee00845e0e2432ccd220e4f89063e06fc77bef04a039032984": "0x00b44bd2d67400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3c4303637923bc42c30b2eb3474f889fa0bc4d8f02500c91a98fb05c948966a": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c7afd3d6d7727f426c8e78dc55156379ecee88660a457494d4d5995d52e83647": "0x0084df6214a700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971113faa19e595512fca8633bdad681b25a04157a77b07771eaed3bf57827f7c5": "0x0000b9d8895200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243bef865eb9f98fe4d6ddcdad70a4387f9052bfd76c68f0468de54f9c5ebbb9a05": "0x00bc15368e363d00000000000000000020bd175202000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f37ac791ea0ec11f2e0b230943db05c000787f261fd949b80217d4c0b12ea52e": "0x00801a0941bb00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977303c831db36d6f7c57c5154db6549f630bd6ecd4c5b5d598855080a3975a89d": "0x00805c14b01701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a562f7f057219037f1cde02f406566539ec238231e51dda180f8c864569f3718": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793bd2e508d7c6e555aedfce64188302dc08bda8c3d29eed9c3c2d17a13a9d410": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b926c0fa693a009462416eb269d3c237ad152c1d811021a1c180f7ffcb0f513": "0x00b02bfd644301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979dde172dcbb58af329c408e3dfd97e89b9ef799ad5e6290045f992ffadbb12fb": "0x006e525970d400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b48c627bedf5b665a011533431f7908df477a02bffd42665f9e0fa78dd470b59": "0x001a8f7a4ab801000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974afa4f29ea8a3645510f108b51d797af283bcf34550b95d8f4cc0995db9c17fb": "0x00f660a1ac0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976fc59c3f9b2baa6fdf8d6ae2968023af80598e7e9b354041e7d429749fb54ef8": "0x000a8552081600000000000000000000", + "0xf2794c22e353e9a839f12faab03a911ba8d640d9c77979401862d05552af4802": "0x00000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974094c90b2b2d4cc3d73f94454b13c4ed7cc05dedce8e3c3957fe8006b174403e": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971cce9fc8c7efc5f1897e845bc85843f50b8ab905dcfdbca3b0e41e171e3450ff": "0x00c0ee56871300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c13d97ab9b388dcd9c2011ae287f67ec2a734e8f11fcfa5c43c30c3f300a56c7": "0x00ee5c29a72f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339713313b92cbbd38d105776580b4a37993d42f5f340319e89bac2e64402e8aa4c8": "0x009259f2f62000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b0b7f60e35a3f769bdcc1a23a0d239f963154909bae9acd6cd3a126f87c1ab1c": "0x000c5849192401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339704c247facc695598315cf680fd4f0275fcb309fd63927f1973d78396f03b2429": "0x00a4d3b34b1f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972e9d34254b1dac0f346afd36e9b5795f91b67ccf43cbc831e2aec4ed2eded7b3": "0x002888565d0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ceb6411a20d14e2f8ce54bbc3bbe15382fb90f5519aa16b20a8a36f774ae3734": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775d38f78534e607fc04f2f1d4987bdc75985c135908aa63364ce5b760c8d266e": "0x000af7ebba6e06010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707293d1037f775269c9a939dcd23e601f1621b32ba4f54693feb422a8541f08f": "0x00421fbc872d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774706ec327722e38362eb548156ba934d13f115a84678958d6f7ae99cebde835": "0x00dc5f23f53700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43ec7149041154e4e466c226b348f31d0cfd0a04d9c49c0793267214cce5ebbfd": "0x008eb9a57d7c04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971711d7718bc90de4e24ce3a6a5918771cac684d98473b2f080cd1335fca597f8": "0x001ab8ccb0b900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397443ec9b89ec4fb0b9cb8dd2fe957f79a20ec649df0ca567644ce897128e7fdb8": "0x002a0967c50e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7ccb50052161bf3745a1a8f808abca871e6b49c5284b504ea3217b6d67d7cae": "0x00807c4be53b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b70d73f11cc47e242ac92b6479929c10f516465c854201eb4d4beaef9f354bd5": "0x00da602c785f20000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b5d94e43148b70d5cea547c1e96aae36782c1428ae40b2d22b4653ca79180fb6": "0x00bcdd8acecf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f1fade96f8397fe0c93ca056301d96a4ab9a332769a80b527036957cd96b70a": "0x002828fa960f05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d01b7216e2e771dd2a34d05c52a39fa21ec828b99fe5a16dd3fc3c2c7658a9a6": "0x00aa0f2ad80700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979114e70e0c527d92676f3f1336eeebada2033ffd9b44aba8338baf9ac6d63b0c": "0x00b888d2428100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ae821a2492fe78b656aaa949610798897855b11debbcf84dc98ff1535d2c403": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec410c2a8b2283351b80650eed4cbba1488c85e6562fae7cdc10e3191aca5c88": "0x0086e2798e5c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cce430926378f7e79c1912bfa62465f7402dcd3bbc33b9e0f5f2edc95a416169": "0x0094e5cf8b5700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397254da64a76c363f498f548955ed29390d64baac62cf17eb82c5ef2c2755c8d4c": "0x009e00db9e6900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397572991957ff07ae0004c64faaa63615e9f32499e27b93a46235fd224831184d0": "0x00cac9c7bec709000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c55798df116b1ccf0baa04e1efb8f46085f22999029fda28bea6b50f5946391": "0x005037a4f80800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e5b2484937e8b6efd90830b8f4a3d034a5d97b0ccb721540ff14481eb92faff": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f542ab5670084d1b434a6273be6d345f61131ba637fff00a253833f6b13a9812": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744855cf58fe81d1192e997c6bedfe9f6f773512868292b4071fb510482dac1ad": "0x00ec670c037900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ca4d1e5ae50488084913e7ee67ad6dcce0def56068b3cfc09e0680df69d3b608": "0x00903973206100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339749b6f96e1e913088a5b6d8920ab2474104f38920f299a4570e79016c6ae538e3": "0x00aa26be1d1a02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733afb1400e7f03b47392288717ec4ab02d3f09c2749158c94d75a481b5f2a3f1": "0x000e31dedb6500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af98cfdf2893a8c2ae10bdbee53afe12766b209330e7af29082ff1dd64b65f4b": "0x001e39c7e9a600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4aaf0ef180e58af6c3ade791837cab8f59cb2e7ca35e27b031567b1786e2c682b": "0x00bacad1767508000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b909b6d66e3b4e6aa93d526fa3e2a50ab74e7f4ddda98ce8f5b66cc363ddfec": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c7a0eb14740d9505f75c8150497aa30288140f77db18383fccf94c7c75a73e16": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd7f9f8be1a06705b993882e10f2c265ab2efe01bea026ed8a291a9bf4efa5f8": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b459626058c0b37d2e3ed4dcccc5a455d890335ca05a7c23928f541398a76f44dc": "0x007acc2a584816000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397241a987b1a0cd489ba7116e7ef09244d9be97aa771971cd33c087ba1954836cf": "0x00e6d7efd75b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a655a7eddd163df9a2d117800ab73b4d2a5a58d35867329c1cbde0c788ea2fcb": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e657140d1a920f23cb1eca7eb9f038dafcae16396a3291878f06e7eea1bc3ffb": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c9c85a0df7196c2728bfdfc2e953008be2e32f2cdaaba0632eb36e06c586e849": "0x00ce84d3182000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac98857ae1c2be58afb211e29382a9fdb39d9cb43223afabd384458ea00b9e89": "0x00daf6518b2f68000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43fe45af9325987842111cf3c73082d12ac85d5b9046ae82af38d467286506020": "0x0018b092324802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397097dec1909901391d3e485c8cabe1c9073278c7d5ed4c5e127fe84243f730e54": "0x0018b092324802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c347818b19959a3040a44d5c8d95950c3d6d26d24b63c206774cdd6375ccb8b": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e17ae3992c3ba8158ff787b2720f8c03c3330496670a8ad2f57b916935b68eb": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6f2435429ad7d62468466adf835f9669aebac74655367a710ce6761ca6d6787": "0x002e3f6ac61b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973bb532612d6b6ff897f66d6da00a1ec45e8d5f45fb3735eca3bae639dc165b8d": "0x0032cf29595c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f31159bac69af385b7fb821ecf833c6564288b81206df77a2c8c635e3802c164": "0x008aa477502200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a424394373c6c3fb1897fb45a9e1745856142f1f269c2ee758ad9b1e5216496": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774243b854b5de27233d88f981193f66bc5ce0a784f8f13bb61fbdb54c7c246d1": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a78e85e139cbfaf36ec6fb459f0c774a75dc65acd802335421ba3b1528f7fa41": "0x00a4d3b34b1f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c365d8602e9017ec0eced75ff43f01e71b1c86db6d578896f315d56438eda1c": "0x00a0724e180900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282431a7b36634518c4bd258451d3afca781ef41c43e2cc13767ade6d58216bb4b54e": "0x00d45be1e85b7700000000000000000020d96a8604000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397944e83d0cbe1e54530543a1f443a8900f3d928afb6f932f733ca9392add701ec": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af8eeec065a60f9ff21e7a24aa5f32c93f433d34b7eeefb88069058c40ce8588": "0x007ef91cb75900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339725b1864dafe40e48303286cc37fe44a386e2bd0a75fb99fb5572d75db488a726": "0x005acbffb90c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc8fbc8f36d7c033ba24ea5eb8cba0af738246c30e09583e6eefc273c6e60b17": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec2bfcf13209f2a799a982f16350ee072b71922208d5b9caa24e8ee0c675999c": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978eab154ccc600d578d30dcb99987c7d66506951ef94141496ebfecfb73767fd2": "0x00703874580800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b414729ad00c64650f9752e4beae474199b2e656b1fdc07cbd428d6268a8a870e6": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975eeab8fbadee245fbcf39cf0fbf793b03d0a83008f34b22595b6f204f2f779a2": "0x0070644a3b1e00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4395065dd404b0e20080049009aba7f480e3afe7fc6b841d1f3ed80d6c6b248cc": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0f1b00de53ad151794f529285ff718aa45585276522efbd169f27347df385a5": "0x00927581d50000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d5468ebeeda63faa15d4ef1f56cf6d9b82d7abf1b2ee479076f611239c803ec1": "0x00e022299d8100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f669a0345ef1fe9b6613370ce6cc3e369f4f3aa1fc015a6f2c0e93a08313639f": "0x00a277755ec600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339777e83d4fa9d010909c6f053f6261bd46934558d64169d393aff0ecce3238e92e": "0x00a60beb412100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397486e7d5c396f6b16a570337a1c45384f724104e19cef44a82bffd78bd66029a1": "0x00f8199a6c0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738e359405ecda5406958218b29d94793d3105cd21bc44fe3a208d7b23f152991": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339725738f9ee464c222dcc0315e4e29680ffc7a0b9b3d3f7ad395edac98625e79db": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339777c3c21554adcbad3bd994b3ddab7b23a30a0746d730e9b657bf4885867ef9ac": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea7a74b16ff06d4bca35bea0eb3af9adb7fc16e9fef18f97fcded490a6ceff87": "0x002026ca459901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397247e60aba93bb4e95a1ed1001efe52cf0d2824057c24e1ffd17bd6068c590598": "0x0074ace86b0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975fec0b94ca8178c968b9b97f9646e455327a190ee40666da3ca1fdc23ee51891": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf02d0f399bb9410b2fbb5ea3cd9633870e4df2ad05983c6dacb974fa011e4fe": "0x00a209940c5400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339762a0130eddc82e1cc85eecdf5d1aad6dfb05c88b0a041460a01023801da24b03": "0x0072e25c62af00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397950b62c8c2fcd768e9e1e27632a49c25fdca4cc93bf0262a145684760055ecf0": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d79760396dd611727f7815b8bf416f532f3f071f5bce70f7abecdd7912851627": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f3ca00d17f4cf1a35877afa6b679c1ca4504cc530e80b3e0bb59ca0eed18606": "0x00a673ea82c503000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397418101d136f0183e0482dd85fc44dd66f3e72029af30d2cfccce7578ee8189d2": "0x0068f8c974a501000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf9dc3ebcda3ec43aaf5e8e9167c11485a3a06fca9b6877adb08f8b09409cace": "0x0040b10baf682c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ba55bc9fba2f65fdced50f0c76d52c6f3d5127ee1849c0a0d0f45923ee03f2a": "0x000870a05e8800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7ac865a345aa6cf53aade6558be29fd5d8b123cae2182351309f57cabdfd639": "0x009ea4c3e42800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707ed39eb3f9eadaa394eaff421a8ea0dec64daec1f3bbd3f6e98586adb597a2f": "0x008a28cb900a00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b469f6a8b0eb22a3208efc7fa44a73247282b107ae335c695597fd1f8b0b2ee970": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397264c6d39e36e2ec355afed53260c0c9f04a1a5894bee33b5a59e75f4dfb7b5fa": "0x004e914751fa00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e41a5976acaf8d99505dd5e9cc86a00c260dd483ffe7d14fa9a0e03945b22287": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d2a57f0e793d52d31bb64e1734e02a2a7de69ed835cff14b64f976affaed6789": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339703b4c62e6ae85d5f04cfe9a8aa4cc2b02e72e476c63cfd7932d85cc7c7fb4ea4": "0x001013e5a2cc00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ead1ff86cd47046a9275486c1d10d8a8b919d0f5a5315756e5e147d591a99a28": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2fb9377e9aa0383d7892dcb6e46244a8544274506836220fa54777c320f12d7": "0x006ee223f3bf00000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579739412d46a6e26424f7d213c86bb856e50ef41be31798b3b9eb38f0c4eaa9a4137": "0x7a977e950acc55770b4452fc418bd59fc4ccdc25ce3c2d4cce58dd0d6f9a2d15", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab1d39a194ee869201ec3b10c9558c9bdccdd395795762425b6f6ab6143d1731": "0x0068520ec50d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d19a3fbf6ee3717a5f4e4bc2e2b2dce2f4467983acf5018f4c397d463ba6a9": "0x00e077afb64b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975cc9945283f8e3ef68f54dafba8ee02db2492d5d03c75ea0514c68d3131fa02a": "0x00e0609aaf6f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6bd71bf14ad09c77fa88ec5c147d9a67e970fdbc5a24040afde32592268f95b": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7f2f1c5d9f2d8d34c72c613eab7d500f323c4fedbce26f158f783ef60d269d1": "0x002a886f964c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f253c62b080f056ce32ea35b896093ea79f56952a7e1bcc72f4cfaa72f197b87": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e99d3a180e4a1ac3b38a592d5c399e849706e5c2f5c05afe5e779a3965dd26e3": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c59f68c284f61c93ba8a755bd3446d9a8d9ed56f7161b254cbd8c5b9b7f8801": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732db85578e133937f0f0208567403996a1c7a16c4b3a41469998b801a6cc748d": "0x0010ea0504bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397156f66301bd5477c8b1aa080eb065eecb2978c10b53313a054996ad71ec8e312": "0x003c7ab90c2c07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781c663e621993a7614c46ebe2bb8fd9c940b621a31ff3c6cb90172e90d9cd162": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eda36daf5716638e2ebde28c55d6f8922b56982e7e3cc7141ccfb0a546764bc4": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c7a6507d87d179cb6dd8a6408440dbea4590b54aebadec6dbd1cdc81b6ba1deb": "0x006296e5511600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b993fe69e716e1e587b8593e3cd68517840a77f8a1c14f220076264cb9dd416": "0x00e8d992a10400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977545f08bb7d65a16434c5a814b183f22668fd0aa80daa21ac76e523faee4b291": "0x00a61c778e0a00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4dd7a99947262f2084dbecb67fa16b1e71712de7108dbc4c2d30956f3fb16840c": "0x00385308034c27000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e244c1cbe2d65a7655a96f0f8c33de639928895b26504f56c0608533e7e7251f": "0x00809403057e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee28e8bbfcfdcaeea827979324c534898cdf81cba0208bade1ee6873fda93332": "0x005eb12cde1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1a68ccfc3ca3db31a3f7026b3c1c4840b1d0239570776eb12adc780988a460a": "0x00e24758b00900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d72f6ef9e8abfef85979d67b0cd9eba341dc2adf558caf470c7ad8f59a2cacee": "0x007e4df9ba5200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba95154c28512cc1f9dda97f2de93abbe9b2496cd263b5b8f7903b80212414fd": "0x007e222bbec000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b38c3145df44247d33becb305b1ded0c77a6aaeef4797bd69f45ac857086c2e4": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee337d8bfdfa65fc04a1c45b590f576e6ec3dc4ed9bda162e745d93f06e48f88": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e686c48b040296b06a91725afbea8167e85166738a7a7d6e81f3c67b9162cb9d": "0x00941032be6000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c705864a9eaca8b5ab0f1bdd3e731fe2c0d2edcf9840dccd8f1e1c26a4f81a8": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e240f38dc56f5efe1705af285b4df30a0872c5c857b9e570defb2c8cfdbdd9d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da768cf39883d590a95680d30d4cbcf1ba1b561a22d91729810374df88f5e8af": "0x00de83d2453e1a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b52ebb26ab3ff7278cf818d74e195ba894b0c8d2c9d8e89ae021802d8949dc5": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d37a223d5f348ccad327e314cda5f8110ff00ac6d914c066eccb4935d2072d7c": "0x00a452f2812100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d4891c7a8b12e2969a1efa9b9df870a014e03909d840f1311a5200ef1402ec9": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705d16ecd4103cf73e7f0ddd189583edc83f800aae108695c3dfb79f7a31e2542": "0x00b2e809461000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722f0f47a726151a340b8bba485a646fd17010aea5df9095bcedcee5678029d66": "0x00328a93708000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e813cd0251a32b89556d2b5c7310c58ef06ee3b3813bc3c7906664491de2a250": "0x00221e875a1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6ffdf368d50b6cae19a1f6ea8d955eaf5727b6cfcfe7a46c222c156c1a8e3fd": "0x000892b8f75a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339742c5a2f58ae523569577dc592b07b53a7df0e57dd0754eea77768a4c4a4bd161": "0x00a6ffa0e4e304000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff80209f783aa7d38931d92308b7f7efe8e7939ee1907206cf4861d56e87796f": "0x005a3db8ca1c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243e49e9344ad7601a3591e06a19ac8b9c420f38d78afc7aada469d0d714aa54797": "0x00406352bfc601000000000000000000d3773d1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd2d091670cbe8742470be07d52affb6b78f415174cacc9062c9f4535da7e836": "0x00f8d272f65700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b4674f460f7b34f738dcdf0add24cae660769792afe6d911b20a0aa0582f4854": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736c1beaf90e604e0f01b57c0ac8253a8b43ddc55d38a8d737ff2a3c40210d8c9": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339706cf46b7c899a94641bf32d08a43faacccfc7b78a254841685cf0060d500ee30": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f8dd2d6a58c524edddb4f2aa92f657546b7b857353038864f34c4103aed0f730": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b5d9c959441d9b447df05fd87f37d96ab470f72cb45aa6a0c6ef8ac5abf316b6": "0x00c01cbc746703000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b51cbf678e47ff7e6cf78d497711d422508bd4e2ce62db7333851a4647073102": "0x006ee223f3bf00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41db3b3ebb8b6ce760c92dbc20cdb0ccc8f0fdd04fcc08c52fdbdabc31f91c290": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e761d62201ba910868a004f80251e3ad3f716636708c387386275af3afe4dff": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dac29e0680477be9923dd27793e4f2f31f959bf0f4ecfcbc2f514876bb720633": "0x00145319b51000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f265d301ba00e1b51f5ed8ac011c2f59e02fcf806c1db9da034e35dd1a5e14cb": "0x00f2b28b484f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c47cf22bfe24debc85580d1f7c1590823db81785865e47fefc4a7ebb63507fc9": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c43fedbd9927be2397a0fd962e74ceb51a65b8e5d5f1195254f4294bc12847e8": "0x006ee223f3bf00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d485f36bbf2cf79c89a72fbf8a151c33189e8866d749738aa416ba3b6365fbe9": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4f1c9015ba39e0866be17d362fa23c08e0d67f34ad44fdb8aad9fb6d98176b7": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c9b252d0c8edddd6c3244639e56050b53e8d9129aa09721d341e164a8d66485f": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971766ed4f76b734a2c1698c5f71b7efdfac7c193f7f5bed22e0cf3f643fa248ef": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd053fa7e107f1c0085c942848ffd2e32e789b5f6f960df491f967a719fcc2bf": "0x007403bcb30400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d046705c0e73224788f7c8596fbd6340f1a57168a510a60e774145760a4c04e2": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed03f9fe374a5fcfdee9a90b6fc5f62891866d0ccbc961d67086c02d03cd44e5": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786aa0c8a5e08c80f1e2dae097d3ce785b9981ad917c87610b67b22e3e1cd6385": "0x0074f6c33acf0d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a0c5f8fc4ccf949eae90b76f99913a5e34fb34ef8c406a69594509aababc5436": "0x00d4c710ab4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397394ac4a24c2edac23d081d43d15d584086e8d76b7dfcfd00f9cdf97d2057696c": "0x0068367fe62d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f21476e6b819c94192148710bc00fed733a2750229b60cf41541a74c7a0b007": "0x00a0a4c029bf02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d16e733e71e80b67a3df597da7e7e22a79b51b582eee506a6bce7c9b24f5285e": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970e367ea0514323cc24f1ad97cdf1b7129de3c21a44e64b56e28fc29afb9676b2": "0x002e7164960600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40d94c0a4170857b4f1c810d5080a216b36211806b5c979f68746edeb95abc9b0": "0x0076aec8f5abb1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339745e97712643393ea51bd32f8ab67bff2ba4ce722275125742eb8b467211553a8": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc27747d9b01f6ccce6248bb60443560266587411371cc252d5358a9c40cb661": "0x00b808f1f31800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ae1e278fec0eb51839b4e47203ef9fe238435bb43a302d23d8a3e4bb04a412a5": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751865a8f0b8afacd9748b22b907d7d30e2913762743706e255b5a6ea0d39d24f": "0x00d0e98a070900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397937bb780ff2a3bdc3c8e45aa570890f12f6c0041e8fd44848415f1c41166119f": "0x00442e98972f06000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243e7fdd89a295dc1c99b9b12fbef35a876c135bacad08c10694369108a0f23c588": "0x00989999d6cd44000000000000000000f3eac39b02000000000000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b485a5163d2fc99df3cf7a165aa11ed82b7d949d3fa493a0a502c21fe1381947f7": "0x0076cf5ffa7b0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9f34ecc172a1be1b15543cb010874184a71712c51d96cf6fd90625a135539df": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe6bdda1196e178f89fa0f4ce45804174b19ed5f5e23a7aee52615ce7359d23a": "0x0020750b040b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c85eb7f9b344e618e359c74857c27b2db8bd06b25f901aa48005959f819052ae": "0x00da99da740a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339788da04c516bbe3241e8e4c686ca7ba807b2cb6e84b82531e598e8cca5e023a9f": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d5151651a109168f98e2a6aaa9d92cf888e14869c4a27d12d0dae683d9f6f2c": "0x0058823c772100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339791505e815ee86e260ae4bd65942a433db1acf6d5a8cc5c7d024a62f6c20348fe": "0x001cf28d372200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c34dae89d53d357089aa36916d35f35b7b5c4143d5898aec4cb4b2c8fe622802": "0x0042b095ed0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397adfef38bb5ef59f31c94e3742b0a0be5148dc975336e6d5144cbe6ab0bbdeca0": "0x00c4c3f061ca00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f77082f9e3cdd8a409347b7a0f0418becd4b8aea2dcc713f9c0f8213bd0b1519": "0x00264979cf5001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970bfdd342898cab5c5d6a63703b837940b64c25b029acca77f257b81d2099f3c2": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727403f7a5e1a15a3b65a67cdd80177782cc2fb88e2b220494ea8771e360d2a33": "0x006897abaa5400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397caf2a4ea0124d9bfef7513f368e8d24f487f2f00f9880bece2f88ede2d03f4d6": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339788bc601dbeafbaf726f41866fbde22f3e1fa92c90091cd5fe732952aa1a475da": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397566f7b49435058cde0d5402ea6f96b7e84c1f81e63c5c64fdf04eca9db31942d": "0x00348d451d1800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1df42c2368b351b759096bd75062fcc5b2d552816d6b903eb4054ccdf49a7f7": "0x00b267417fa700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978bea3b674d7b1a39b32b41ad2bf4bdec9fa2399305a767aed102551598cd4119": "0x00483fcba02401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339741302bba9d7bfe4c4c7ba793490a066485beaf70764a46d8f9a8ad5cd769f046": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339760b1bcd5e22bf543459bc0f52e11d6e9c3abf46aa753f44c356a60f1bf6f5763": "0x00a83f001d8002000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ee85a16d68e16c807ebe7578b256c0b8697fcc5dabeeca4c27f826e0fbee44d": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b154cdb472df5cddc74ff8a5f2d3f38e39661bf661a29fc230cdeff422452afe": "0x00461784db1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976da80cfafba089407e68aafd023b54c13cb3e6cb25201d08e9aad1f1e94dbf56": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b698da80c9dda47b701561ec023839fdb70392496f460011e023bba01cd7c0b0": "0x00aa03ee74a003000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f994858ce07080c01469119df43d75b97cbf89d40f06256f6093d1cbb995bc32": "0x00d487ed9c0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785dae95854a080406380c47af1114e910d7623b214f587e22e4c534dce08b6ca": "0x00381c3a2c0400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41d4a42e23c1bfcaced1acefb3ffda01a2d9217d9e5cd2f18b27e4acbcdeeca34": "0x0022f2d1e57d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b5809cae82f537e0d48af3b64b4c47ecf9e25936c01dea087e3703993363cc4": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792096f06493948512ad3af708a3c666a205c2df4c489bade2fdc05b5c7cb6a6a": "0x00ba12184d7b02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d5d16db77dc11fd8c7c3548111420d036e699068cea6552bf2b2a8a9bd5e869": "0x000467eeed0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974dc2a7559fcf21d1b2ede405ed7f3f4a73a58793b9af871ee93b084b5d6fbfef": "0x00bcc1fbefef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d10af48733a9ebe40a704aae0d735d34178aa56ad3eb3a2199c20d3ded81eedf": "0x000673b4ce1200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a30b412ee9fafb4f7daa8730ff846b7c39b53b97f997c5e7c0f693e3b3e05e36": "0x0000d28398d702000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e7eed31ffcd91f1c03060ff4fb69b23e67b66fdadd53b3ab20432600ea849b8d": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339757c7aade2e9d97bbbee153a1aa3b7f560bccc754cdd3889569a2b4cb4fe412d9": "0x0018ee47a4d000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282432ad8c1e97d2c8faa7d56892254f9dee146f73fa3ba3cd965a31c8d630bdb194c": "0x00f45658a0d7480000000000000000002029f5c202000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba91928aee0a5159cf240472dc4c706dd91c54f0a7b13515296ecf34b73f9d84": "0x0046e6548f7a01000000000000000000", + "0x2371e21684d2fae99bcb4d579242f74a8a2d09463effcc78a22d75b9cb87dffc": "0x0000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b021cb75ddef6ae4200cc572254f41260aa063cd24b72b7ee3b2c4d08194488e": "0x0066497f817f07000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d64e04c31a1edad60ff60250a633b76600217b7c955af0d283f2892b70fca982": "0x0068d9d7873402000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c2b2424e2527c03b6888f5d9427f230a0c1698ebd3673a3016455e99230e3b5": "0x003a46774c0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d4da215ea234cb18abdbe3c98510b549b78d76c7b15ab8ad9f326c6bf906d82": "0x0020aeccd93000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0252a5c375d5f62912b63635d8200ea060ba5bfe4d91b3a64c4c0914144a740": "0x003cf35d972100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4e834a195636964ce6a22292f737af625669d46d8eb93fe75066ca842965e25": "0x0020f6cccd0800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4dafaf1257f056555f656fd352b8c2faa0647adb17d5fee73143d09ca6f9dcafb": "0x007a55aa1ceb0f000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243a868058bdf02b477f9ea4b522bf0af37b81192211dfe597c84b4ea83b1ef8db9": "0x0040f09bbce1080000000000000000001f57335600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b754f1c93c7537dc5dbe41a9e9204c510e7fa49ff520a2fcec76b0c4a8854d62": "0x003c34d961c502000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb39fe6329cc0b39e09343a73657373696f6e3a6b6579730f1bab80e805877f676cab54e02bb7f2a9484e7e280fe592f6d4cdd424aaedc6": "0x5ce30d8c007d0a438c92c37a660b7709fd1ff3bba79c6c4832ea4107d266e0011a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad82001a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad82001a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad82001a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad8200", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339729023693c108d204dbd2fdd38166975f43685c92ac0967ee1d95df3ecb05365e": "0x00545a7c258502000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e1526ece5025e3f79e30a30f3aa0c1a91d2859326bed81243a76efd0ee73e31": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397255cf0548fe8c7ec5004fdd911aea73b0986d1984d05e54870eac2aeb805f7ef": "0x00a0724e180900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b496ee88669be2277948736ed0660ccd2dcb99fb593c5bba6545ed67d0496d0056": "0x0000c16ff28623000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d4b93efedd7ccefd692d68487a3f2594004e3f1f0a28eff2697afcefd95ebf7": "0x002a07e4311300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44905f3de32049494ebca6cc26063eb29c899f8c0f64271bbdf2306e09648a579": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339725f3e012b06c14d2535255568c6439bbed207770862d59a0d3b3b15d4af74909": "0x009c7912141900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3574065c59f306ce90173fb8afb9f25c1dc38a5e8f5dd67369861fd46d5ab8f": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339749005344d26261af83386a28d0481e7a49a1fc77ef7e6476b6ca736cd2d92aca": "0x000892b8f75a00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44755bf64e1c024db208f3f22f77f1251cd56542a7e86216bea8abc4e7cb839ff": "0x0070b9648a5f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e03aee2637e250a68730a19c3d2aa32ea5eca5308e001ba1933052ee764ba083": "0x0068367fe62d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8e4a2b960ce19a612ec799d97c8932109c6cf5090f077395d70520f87a55a35": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783726ef784a62502f80d868f6bf3f8f855d612decd71567f0c48161285d080d6": "0x0048a2f99b4a21000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774d174fbb74b8cf399fcbdd887b28fa8405b052dd49dcdca8384a61f379dee4e": "0x00a06e48f11100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fd57478a371109c76d766e8701dae7d3a37f723d6daaaf24dc56dacb1852d65e": "0x0064eb1fd70400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397982d3b2ba19ab22b066122019c56e78f87eef4815ae4013ab11c4c3ffd4dd6f8": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a248bed519bdbb8411f05be7e10224a253a09c5dc0aa131a538a78dbb20aab8f": "0x00a234c7d60300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701a5746f2bf1f502927d1841714e2e78af0eadae74b3a7b3c11e01a4f37e3ea8": "0x0032d33d7a2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971190d99b4a99e01d3109b27b4f5bbda8ed442c7d50b5dabf50ed0199336c03c3": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab3041149c4f7e9aa0a25dd2a48378f2c8a824448684c05aaf19d24751bcd980": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6e84f914d4ce27d0ed58e69a5b96bd2a0747529a52db948afe38d5102a65021": "0x0000c8e1424000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397028beaaa72eb0285cfae6671fb9d9a4e53f0c0281c9172e0a197b30ea43c211e": "0x00f05585cee507000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8ec80cebf997a1a30cbfd2fbf16cee87c6880eaee10994cf23d05de31a4e615": "0x00d639e9f10000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c57cbc5283fcc7d20ccb0aa10b001d59366e6c307a39eb261ccf9dfe4aa50ac": "0x00301a45ba2900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b45ef64d0573364983dfa298afbe09486f27718e4b79b34f2f8d75a9f46a3d590c": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970265d2c27dd5bf7e0902a6771fe739fb639aa50c8f33b961c7543899ed7b62cb": "0x00e0d10d78cc00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4cac5f85b919511504e631b10c0f0f49c6c82501e5a6e19bd0cd7e078f8d7f456": "0x000ca376b6c800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b48f4d52cf0e5baa6019bc9aeb9668f782555b8fb46b582143a246114a0a30fa3d": "0x00543b1e6e8b03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e64ac94a423f38fbaf0806ac448724baacdb60dcf3fa0b28b1b62962f08f869b": "0x00bc082a630800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4114ea1bbc64ff8ae705f2e48730c3bb46824e1fdbe51e40738ee2c7b725b87f8": "0x00cc3bab081700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d9f6b3ec784a191faabc1fb4ad11216128013cceced07f372209863f8bd495d": "0x0010a3fee5b4a8000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973c6c90a3ba38fe11c932aab13fe8ce43cc23de985f861b688b38026630e4eb819": "0x3a2b5aa8ffd4e3c5ccb11d342867d964414dd36e138de466f5fa6d865f19d665", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339717ad7486ea4e7ba0c56584993a3ffb8433d5b36907980e58ffb190c4a56301f3": "0x006044e269a307000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785673f28544e7a1371b66b2da1fa4f3492aee51e69d9ac134b7468eeddfe4884": "0x007c068aa30900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b2bdaf1755900c6246a3f6541efc83bfbb1d0fb8d3301491d9daf5652a9bace1": "0x0090e5961c6800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42ef6d4ca0f83d3f66be9313c6fcbcc1490dff9d041c416ccb84a6e04d6dfa466": "0x0070bad83a6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8beffcf9a3f10e888776738881a80460d5844cf6c09cbd398dd8f79f59be6eb": "0x0026da6a887d25000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f6a3b982a158f205fb30470a7b2dc1d97d087c7a656e3279571c78d1b7f83894": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397adaa6748d3ced35bc548ca12b1febe4a5e5c8120308e868f726641a335b1e7b9": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac35a73e4eef0b2a9432c9f042e2c7db5308027430afdb50272a6d0a49cf4ebd": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973d7fa509df074efd0141e3b97599a13c815e3999e0c07d03c54b387d6036e9b6": "0x00d09172775400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b431b7722076e5a347070c05d6842117a06eea4c013ed03ad774d1e0e140357beb": "0x00b2cc7a673000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9f2411372716f459507d21d552740581165e79b69c04da4df0675aa30a5940c": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc12f081d7abe1de939e5bdbb67e6f10ba3ac3286f937be52e7ef897cfaa7e4a": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe6c13e66b05e2f4cece5857ef52536ba84c107e031cda6e79966245869b61bc": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397287e65aac01b7c949ec3ce08ba76b5b4ebf96e3cf55fe9dcbf53693ed1a54a44": "0x00d64e45001d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972375feb524cbc6ea00b3fb04ccf00f9e243bd571dcd03494a5491de7a05c5d53": "0x007ebb5c423f0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f2e3d5770b0dc1f7e644a4d9c0daacd129cd072609bc31379facbe21885c65b9": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972aff94bbb0616aa5847232e425f5fc000d50cb070d2888c4aa88b84f2b320f45": "0x0086ef35191300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339772f86816371f3cf3234453065a80b7c3db275398f765898d77f71ffad6b4d98f": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f843e82583cc74e8cae7eae1c5f1a30baeeab6b79341a8484c567a3cd2e209e8": "0x009a3f588a1b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a4b808149d750966a59d63095c944f5e6d266b6f9a7668d60e4a568820c7fe7": "0x00e4c3b8db4500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ace1df625cb71a696f30548615fb7bd170dde5504653456c6ed2e9f7f2dc89d0": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974de8a7dc65573272a9cb9e93cd346361a27097f2ce913ca40f8216b99e2faff7": "0x00ae9ee8812f00000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579735eea5fd9e6126eaa68a9bdd165641c070cc3e2ccfc49fb0b7827e4437bfb54ce": "0x5e3ed914a3f9da416f69613d98c0848a6435ca4bda8d00af53a8a5bf5898b904", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978461eb448400a344cb0617ebbb2f8a71f8b3269863c5103241effa2020940da2": "0x0016c10c435a01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339790cdab3e609d8845fdd9713984e94d839db2cf0f416531ca9774a1970e2d6842": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e20bd93804e1c49b667011e24340ee9ddf16cb91c2d9e2a6f3e45109312dcd1b": "0x00542e2007ce00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397228d6759232a475cd1c448e7a90708e7cc329da1acee733cbd5b202e55b86660": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ea747cff17180db4c1c79abeef6de72f2ee273831b7fb559ea53414fa51aeb8": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971b6fc1a30dbd33604c0c75b4c64364de2897de5e912eb1b7fa32dc882bc4a959": "0x00ca8f386e0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df7c83a5fe3985a4860ad5f6fbacdc0ff84ebf33f21120219ac12bc5c960c960": "0x00b2c931cab702000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397efd36ab1b4e45c4394f040ec458b1664bf67b34eb8526efe23825878ab2d8c3d": "0x0098407d9c2100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c8f48ae4a42c972086f8a86102dbe3402370687eb58cebfedbe72ae1452d09a3": "0x008a5433260405000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b305488542ed9e83488c7c260a6fe123b4f92d6bbb7e8421379d1d51ba48bc5": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cdd1185bed7b2110b0c3c97ea86170eff785cfc3aaf61d260bacf8dc12666ed6": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a78939fd69c354d6be5ef6da739aab58f71d20ab82107522de06782d815a9f39": "0x00341c01bd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397210bc59c967e59dc492e6e8426ec11bb9df5506725826ce1f618145e61b33bb3": "0x00ccf483926900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2e8e3dde96da3475c621c545cf15952d47c2fce5cda5376f0d6348972ff3b23": "0x008c2a02902a00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b485242d9831df008c158d9227b654ed49229ff4c6fb757b46962007df45a3507f": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fddc833a02d42951f63594d2041cc131ec8e5c2c70e4e9fae649895ab8f9a553": "0x00c8bab0cf2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977214b31910b07279bb52c72fcd286e8915a14fc78a92d743835cc8892098e8d2": "0x0042b095ed0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397adfa5f8bda8f9cc71a0ceb4a3b054822c27cd4605826305af35fc4b679f94d53": "0x00fc8d0e800000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b89c1ee9307e44c5f3d73a029ff66d5aacc4594fda2f25fdf5c171dc1a7f88c": "0x00901ec4bc1600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f58ad50d487ba1609645a6d02a5db0b462fbb208bc35bcba1a673d5c780262b": "0x007623119c4203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977adcef9544a83dbeee911c7d9880e720c2b3bc9c1cdb4db2675c0ed661efc8c6": "0x000a56a64f7b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f088738d2b396c35b68fbfaffe4c0cd0831387d44a604185e40c990ac6b91281": "0x00828a13987702000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a4f91fcb64332806d8807b4df54b5839ca7f4b676814145d28a91e2a825e525": "0x004ed2873c0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339766880de76c39c4b25cdbb36304006989d6db2e45071b6e3f41cb4591859e246d": "0x00a2c3388eab0e000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973aee0fbd3e9007d21de253ca310762178e14b1bb9c11cde81c16d62b61d85cf51": "0xfcdeb580add093f3b5f06603032c2fe89d329ba372147c100aa0391a44a51601", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c1e185ead17919d3fcee877343a127b2972bebcfc18f16f2681a688d330d803": "0x004c44f1ae0b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750ed976a5820820c21e1233c4ef2492470b9bbf679bbc0c3555983583c185f43": "0x00e86151d60100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b31b749029c02d6d9007613e8902e8bc0e362585c8c5873392859c80243cd46": "0x001c6ed5291c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397534f0bbbbf340acec9086589761a73f9e517fe0ee462cc2db2d01ed4e01660f3": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4e4e78ae4dc49ba352374a601eddcdea13c4b58f4924784c166a4663cffa81d": "0x00c6ac59614e01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a9a38bb0dc11b37441e961bb3053e3f4679a8a3a1a9cef8f6b4b041fd024aa65": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f99e8a4cf8fdb4937b57414de38fde110691159d60d9b55476e9d3fcc099b23": "0x00e4f2bb672800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397baec31b91f974ae1f5b617d61f7a66ddc3dce5d8208f134aeca2114c1865e8bc": "0x0098857b495f09000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d07420212911fdf76235c5f61b6900a098383a776d5a3f07d85ee74938bb9fe9": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971d6e3ccff7f65603fe336a624138f82b05f9cf4fc8832022b5bc85aa56d79f26": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ced7d9cf225a1baa35c78417551bfd4de382f8cf0f5ee8f7c049eb22f6ced439": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397defddf7e4d536aa8fc7b983cd69598285d29016eff4c91bf7c07e68d2bf896de": "0x00b4d919c66400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339712a889e910303ad84ff685c95ec931e74edb25e209994a00eb590e7cc704d22b": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b25e6591b35337273c4e5da5a9944289afde945fc0cb6c485913efc048c4d4e3": "0x00c462cb9a0e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a5dbd18addc00350952d8b9fa234b032cf2a5da43e674b7888774527a533b68f": "0x0000c16ff28623000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c5c0bac3f4ea355acf2e8fa2cce37ed01ddf54989c60f89c493b5a19452577d3": "0x0008385ea1ce14000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ce256ccf8e2bacaee33ad3eb81e58ced0c572ecca34ce1a96f9c9180ea5911c": "0x001ad45b8f9900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974134ab11c99f27e5c63a6fcf185f5156a519f8350bd9a260f54df75f4a6c74b9": "0x003497c6042c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339710a515398090baaeeb23dec29f83c928ff80ef911847f93bfcd15525f4c6b21d": "0x00be174c553800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c67692bb06872b328904022c285952488bff6004a7e10194e44bd219bfe953f9": "0x0060a0b2cd0501000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5d0f136261c43e2a5fab136c1374bdf9b2f5f828b300e05ae9bd55bda462d51": "0x001e20d17e1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397722be272c48a137139809b3450133aef35df9d45361700adda22bfb734c80c7d": "0x00ec2501941c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf0d7960b329c26ea0435adf5dda1e432b416104942d43aa4d38bb1042edb4a7": "0x00fa46ced01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b15805f1fc79439b05ca996d80f76cdcec9e9c64cddb9f875b9af893c9b3cdbc": "0x000e6e45853c04000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e7fdd89a295dc1c99b9b12fbef35a876c135bacad08c10694369108a0f23c588": "0x0000b605da7963000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339779f3f6ec834cdf5fed55c15dbab533e2c05fdfe59dfc8c355c94b713f94119f2": "0x00704ccdfa7703000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac0287e363931edd22b7c88c12275169f8fc0af76b9988011743c93f4405a39e": "0x001e39c7e9a600000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b65797344af557eb96e19e7d7d3593049767a261dde1196135e0ba6803b8cb287f4c6ec": "0x7ce21330f614e9f11065cf3e7e96207fec4086b7cb83584daccf6bac6d35d16c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979582ae130ddd5ab814cce3449ec4171d19627046bbfdcb58c3a30cfe334c340e": "0x00448fb25b5910000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786a48a94f7ad5f5425631b19df9fe043ac56b8f58a0ffd88c1f39d03839a53bf": "0x00de52b6088800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b49199fc3778e84a44e88dfde4341db059f8a755e3caade4a97591878a75feeb60": "0x00761509960840000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c57348b07a00d27ab02e1686122e26d737c96cbfc8b2a6ba1350d35d6f775869": "0x005ca0805b8100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e72fc2442e17296bdd135b7906d2553674b6c8b850983e7163e6e07d55501674": "0x001aa84f47bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979946b34099750742bf4c0efb32cc68034ba4c70a49a521896641c365be7f8336": "0x00feb8bf501000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976dafda8f2c905900238cd9456ee69472591d5bb121963915d09a7c9e2644f509": "0x007a6af93f1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b139545a06b47789bcafa4af28ded62af7600621f21fe3f8afaf23174bb60a6": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750543a87238aa5fbc162c418f9946f8cff1e3594671f31bd725a88c2ce1041f3": "0x002a0967c50e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339719230004512aa36170e94c7954acb1699882456a61ce5b1c7104ac86cefb7de4": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9cba11b8e4145a7249c17a903fbcfaf3ebc95d4401b29b300e0d39c40b9eb9d": "0x00dee86e138400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e3d9c1855bcdbe7a8a66c3353a980d054f1f7be07e550bc79bc4a7002020670": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1e37d1e9c4a10029a75454efdf29cc78ce3ac37f67b58ecd62ab9cd13bf85b3": "0x00ae839eeb0200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ed693bf8a6bfdd89021b00561e1e6442d501a00d2486676a98f5a841b70ec03a": "0x00d0f74e784300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43dd52beb9b7c03e80a2109b1ee1846cb734f35fa6d0eaf28455213407e64fff2": "0x00b22a00be2b02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc9866f95925b4e09be15a0b9eed5ce133134cd9d4b2f3fca1105a5c989d1bd0": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397738ec5f118dfee5369e57df68b1278cdf1aeb953c38de28d8d6c232b6887731e": "0x00008d49fd1a07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ebf95a8ff79550993df5b47749610d976c543cf6a5fa1dfca196612dab7abff2": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a5fd87d8833f490920addade0da27348d7a3f303c4e8a034ab87158cac194a56": "0x00f6d4ce563b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397355d078a5123302e1d01dd1e7c99eb7c8f86172d62bc216f04a85bb5dd065162": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765f2d2721f22f9098076585b7eecdec26c992e3eb6c4a437091b90cb7e9b6724": "0x007863f906c40a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b2dfc67da004bc4b30a3abf1b69c4277d4fa7206651e3deb4ef85309a2deebb5": "0x00a234c7d60300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976cc5416765cbc408b0be98d7691b05650cb5172b42527f49e7c1e3cb708851f8": "0x001ed109850900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339719e2721f720779a5f15a274a8ce54c0ca15aafa6ac23aff37bcf07231f0b641d": "0x0050a95c091900000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b65797379811c3f4788591e4c2618ef513a9169b12f56d0a8bffffaf39083cfe94d42d3": "0x3a2b5aa8ffd4e3c5ccb11d342867d964414dd36e138de466f5fa6d865f19d665", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974095099846775ba00766b04359feb6575c15ad0920132d643b7e38f31afe9a33": "0x001a5524560200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c5ba9d3aea5fc51cca420c0839761cb967cf7f3bfafc194d18468c9e21014e81": "0x0050248021e301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339762e3dbd00351fadf8472daedc607ffbc40ea6a3041dd93603ca096c580bb145f": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397100f07cac971c6d5187afbb8585ec780c7ca890e4dda3c203d2c5a22ba325e2d": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397919ada1cf521c7542529cd4564dc43375d97a9b2fa1950fa8fcaf7cbd181270c": "0x0088ee10070d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef6cb490bc3aee2a892ede57b5c8f2fdbdc2aa908439d50b8d71ae0ec0652b3f": "0x0062c655919a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b77ad0c3a73c1a5dea31cd98fdf26aeee7f032dc4f6f8eb49b5c61e6ae2aafe5": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978673324141a3ce8a3d9cf2224603a477c162eb5082677f072a9f90661b0ffd95": "0x004069553e1800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43603027109282c647909f66a7f592b25c157f0bb0fda0b83310a40f34945980d": "0x008c53a2497505000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4027688a9cd8a80de20a46a52a6ca40be11af63cc642598d8fd53d979abc4eebe": "0x00eaca971ec709000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f15d7748fb464fab25f1b8ee53c8208f16c06bea700e2c38b3b97e3d73f2da24": "0x007623119c4203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b69892d350dde0ca3e281e9b514632a3798b648e615d4eb8baf2b5e03d8f5fae": "0x00126d3b2f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397010dacd7f29f94bf5fa40b740d218a4d4ed3beac85bc696c3f23d0ad81745085": "0x00406352bfc601000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e751211da6d1f761ddf9bdb4c9d6e5303ebd41f61858d0a5647a1a7bfe089bf921be9": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345534abfae7334fe623a3a77843be58bba94be80a89546f81fb67ff3507775201af526288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345534a9aa16ea96e59d8fc82b496362eb68947ccace82da2f1f3357142c072725de6a45f0f52623a816f811e5027d598195baad272d16a1e7864015b5fb75d2711c131888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345534a688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345534a588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345534a4da46b0a90dae1c606c5ada0716b6eee1b8e325c34b12d747c1a1663cbdf1085958de2f4d49bcf1f53950de13d6e2afdda6a0ba2ca944fd791c5beb6ee49765654adf51a47b72795366d52285e329229c836ea7bbfe139dbe8fa0700c4f86fc569ed2733809fff8fc440d3fb8c4365ac7a6a520c46ba4a2bdf94f107bcc5cea0b6ed4e490d482667ac41cfce61cb6595a36e7b70cc16316f305fe5c590c89275688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455349eeaeecc69264af49b96ee5fd971b691db67b72e2b377914ffd770771a81c0dc6088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455349c586edf69a4ddfc5eb0984e194a549997f01e021ab413ccf08cf48e6f30cb2456beae5bcad1a8c156291b7ddf46b38b0c61a6aaacebd57b21c75627bfe7f9ab7188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455349952ffd72c532815b3ec9d13291ad1989418129c3e89499a918e884d5bf3fbb03588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345534971423335909d97596059c527ce5fff56ee5cae4e98dd5e80ccd72c974e223a31988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455349588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455349488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455349388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455349288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455349188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553490b8c725ae2dfca19e469628eea1e2523ac75b4b829bb40a27d0dc5c72eaa9f2251a7435849cb3175839693f7e078d1fabf90ef3fd38df8c50dde7fb5c8826086288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455348d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455348c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455348b243411786f2b168b5024685ea3474897ef2e77b7599275431ba5229bf657890b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455348988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455348888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455348788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455348688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345534851c2a5f648afea2a94286c17f6c60d16c9ef8511fa4ae88a54ce2748b6c8fa90f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455348388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455348248454b0387f763dcf46291236ddfe846ef6466aba368f75aec3bb84b65b39f6688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455348088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347e7edcebca836ca101bc903f9433bc515526eefab65779fb6abbe9a55f5898373588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345534730a55a4cbc52cec34989fa806a54937f6f67aa21641e90844560beee78246855a22d269578c78297105adc92592eca029dc325412e24786db30efe1219a3bcc7e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455347088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455346f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455346e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455346d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455346c", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b48a0b97a488e99302222e811a82f1d945777ad9db1a458a015c10456f65fdf501": "0x000a1e02571a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736cb09a8cb840ab800a59b0b4d6a88d148380ca213a36f30cefb8b0d072e2033": "0x00b44bd2d67400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971065d5bb33ef00ebdffa67296456a150ba43b9784f3d52d584c39661b80d7860": "0x00188d22dd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e08ada799dc28e5da40c3b4728c8c71a04479cb8fe7abd93621ddfcc04cc296": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397806ee69e2c38dbe547cddb7e76328f7f03439ba472f90247e451d86e99c4f775": "0x007899ef09f702000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339779f9e3e38d2005aa00a9444f67000a7a67dc0543196a11aedddb6c52e090c12f": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707bda05ce25bfef118b75968fd7f8242bfba43418dbbdf66d1306054858e48ab": "0x00a6367cdc8300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970711169f9fc1798767d359219442bb6efd1285b4c20555b8ffe99b1c58bc7e6d": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722274410da7060d722bf2a9294d7794fb122f19a1177c49c1f8c442da95e1319": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339758feda065d1f099ef4622e60e2bfda740a16167c110d8a6e94efd0ab844c4172": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba571db7c9a4af0a74d99336a07dbf9bf8e1907a315415877a08b97ae374201a": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f424ddd545cf786456e11ee6b229a062be539d939b6723e260fa6a0602ab39e4": "0x00bc110f2f2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339714d2af39211b20495c698ae85ced7c449fb7db468ae066e09c7d0dff378fa0c4": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794589687b9f6534fbb63243e7f551ca952fc9f626b1144e0de148db4f2ce6e0b": "0x005650f3083000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d206c221c1980b4dd36bf1cf41c0b668803ad26ece3bc982c9050b48c3212f6a": "0x00ba28a926e107000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972fba3228b768ff604ce093644b454b545a7d6dc9b4e129f9c2c2ec63ea0e22c2": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979945b6118dadbc0b30eed957cca73cdfa1fbd6831e3e723d907dc36532fae44f": "0x00c68d756eb300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a14415d1275b4c5ddb2138cc89fc94715cf7964220b66556cd4cecd6078dc38e": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f784479d293439f5736be35087c12ac2b55286838bf6d3587c380accdea24bd2": "0x00b05a73b81900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b49f8917257f6ad909e749272e83142826203f91b30436bd6a58bb36ae1143e2fa": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd5e1fee43747c760a0745ba7ae0eec0aaa6e97d159dcc6133284b8810d786c6": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397988a7b0f1a52db630da97c025a335ba15d363df9f0db9797dd84ed5ff5541436": "0x00cc3d2e9c1200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339788ccf9fd41ef2e9fa2eeacd83bd057f3f1a5b3597a20ff61172bad7fdd4acb22": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339713911ea87468a8e966b375e2ea067dd684bb64aeeeeb25372d5e7f47c8a3728e": "0x0052f76b2f5f0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765849946110dfc1a91d16b9e9fcbdb11465b3b7440835aec6997aacf3ad38e8b": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732f677be5f59da8fcc8e3c168d6a7b9ec2702a2f99fa4b72e69dadd51f37a192": "0x00e0758af30201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f88597979e8f2cc839f4a19294e3e0f888fc4f4b47f07197a568a362b079e51": "0x00ae6ec28fcd0e000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e7512d730b9b18f000e2d67b09eac611eda5bbdef729872387b80d989a4f10f833c56": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553163889f76e505c0a2ae452838076682e8b6be03e48edc6298f3e38c76e5dcc1611088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315d7006773c9a1bcdcbb702883eaaa9e1ea01c701123e6c14bc6c78f117a6b66e7188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455315088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455314088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313da8f2cab37bfdea437ef24b2751e4ea9e6cb872ae36c559f06e706de4a1ece44088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455313088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7ebf6734438c033a1607bab28e988adcfe1929600fe9bb9bfab07f566bfc47c": "0x0020e4319e3000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2a704e4ed93ef279712b3c1f85630374e60170db386a2a6cb1f661300e9216c": "0x008ace1a761902000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab9c08abe0b768bcb696bcd1e776387980ca3e670945f092dd643dd4c90c9a1c": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a06b77803ba878049f03aaa4d4cd16ed8c43a4f5d8b3e5d771e8749db4d364d": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979db10638271b3750fc1a7562de362f1f1ada24901bf6f5d566c1be0fcf5854f4": "0x002a07e4311300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b47a681239ade33a8d8a92d9a45a8a3b79cb85fa8e845c01ef7e1f8f027ac4aa4f": "0x0080afe64af904000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6773803f29a9e23d5d378a09e8bad470e97ed3a2e5a76b7213eda427e78e02e": "0x0020f84dde7004000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f14a5927e351492e9e2138f5571a821d014610fc693693cb48eb22d501d50128": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397519954033e4722c3b35ac22aba65e8cedd41392202c15b1de93a0bc6b775f248": "0x0082357a0a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b9bb3f292266ddbf075e05e464dd42f5ea315db76d1872aead526e9024ee7e5b": "0x00c0e1d0612100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b51ebc6f99b2085b3d13e40c70fe5bd8f7af76651fe33c941632d4dcd91980dc": "0x00e4d5530b1e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d87592b80b22d8752ead3fc6a6d5436eceb8110f23563535a06ecb7369fa753": "0x00080442a01100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc4ce0f8ce188ed9340355a76cb1e73f0e4c68b2776d9248c38ab5d7ced4b84b": "0x005c05ba430a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397342d0cc3b0c187846a67b3168805e9f29b6f8634dca76a8daf32ced8581ebc48": "0x00ec226f1d3200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975560896b56acb8dddd785eb5dbd7c8a3d327d93051e36b2f8ff20c4b33b2d449": "0x0032cffaf00201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ebe551f965a4be5d25a05648ba42a7d773867c79db114562c578dc88089e949": "0x007eddf9a20200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ec5df53165aaa4a90b4c67ccc8d881741a1d6f324fe319177f16b444b4480e7": "0x00ca91bb010500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b58c8f41dbc79600acd79c9d770c17f4d92aec24708c29cf144b286ee30928c": "0x00d6dc8cef0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5ac2b7e18da0bab0eaecaa0a7ed48621cf729f4524f3aaf0d401e44474908aa": "0x00fc6893d89c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5f6967ac265a67bd351352e0a6752cae7af911dd876f165f867f67603a1838a": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397271b3a42d8ba7378364767b90caba56d5930e39c62678f0fb2e58319e22980d4": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8a763021baea9650c8ddcd4d9e7d25955e8a754104493a0d54767dbaa7f2dab": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339797a2b015fbabec608bec296644c8e2296f1ed2f9e1bdb92278806c3477894712": "0x00f6781c6a1801000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e365ac90dc49af193172959918e3d551a177012d77202aadfce3aab6b7ad1663": "0x00728e40997870000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c1a72b0b3bdb2b706d9e1ebab28208f70edea911e9738ed767bb552f6ccc71e": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7cd521d0c1663ccadcebde90d12deec64149f3de3b9498f4615e6a408155d02": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973913d7f33d1b119aa5d231e02942adbd83abe77c0482750e70ede850be367125": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397599866374b26c8e46d013048539a065d7ac2947b91526fee9d4a969ef86fb8a7": "0x00eef3db9dd901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4594b62f5a858d3694981901bc4d168437a28b59c4de49ccf14eaa8d881893a": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c3226107acb1a71564f3d815c1d896e681bba8657c2e31f9db908e53096a45d": "0x00a61c778e0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e7e551597a0bc6d9d2764afb8d4b91491fd58792e1d3e29454e08be51cea8cab": "0x00ba38eea7830c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fdfab9115877848448b55e506ea757830546821464cbacd117ffbb3ef623cf7": "0x00e0ef26e71200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f201c82640c496a0e71cb97d1dc36fe38129e67b05e6d3aba5da2bc6b04c9d2": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d03fded9c4b4d8cfbe3c25ebd092720afc0242749936d836cb216ba062a954c7": "0x0032f4233ff602000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974973747631dbdae12019fc4924269a698b4deea6e11b1a8b3dd2fd81ca5df846": "0x0088c596351d00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4468eeff5816e1b2068c15b330df2300490e351449d0a499911c77d9ba5b29254": "0x001e22598cef03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f10fb7560e65cb4fe77f0ae77590997c9ae6595df97b80a3d39201e159b4b067": "0x00eccc45eb0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5d840019a8209daa279e1e67b965fe3891bd5ee98f8005ebce65d99b129f844": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794ec684507ab4ce33b0ab74f18699e0c6a5f32baf60ce88b547376e9d85546fd": "0x00e099efba0c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339739c97778b8fa00cc4a0fa041afd1626199f3161fd239c79a2a973f75a81f1254": "0x006859e438cf0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397960df3fafab6a2570f8551c269c84d5e5f8549daa31e54a44d216ca4bd466c38": "0x009457819ffc00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f6d2411c216dab922cfb08905eaadf95a1cc1c9a0f516ef71c7c2eab0fe5df1": "0x00eccc45eb0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b505cba07c56490c91377df24ce2c13c25586ea3bd8946fceabca5ad88b69c2": "0x001242a3973e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4046c729810b97b864496fcae944e82845beb2a46cf858e68ded78e9cecf707": "0x00cab51931711e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978319211e52e1372c41ee8ba15a275210b2e4ecf1c165ee2543d02ecf3466b0f4": "0x005650f3083000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b4197e8a6122d9265f8e9b7cdc9511b6543d823b5c5c84ba6d9eee181adb12f7": "0x001e39c7e9a600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d6c268ab1510b38e1cb8c1c4641bd19c147379dbdf11fdb1e0dac64a6259c44b": "0x006c95538c7201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b24cda42b1b75da906739c875c9fb85b9bf3c5627ae04a14caddcd8af35badd": "0x007ef911b4c709000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397adf4b2192ec41c56e33acf2d2c8743849eb7e2179317de444342238e716d4d8d": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bdd34b18e301664cb3ee61ab27680af3fcd3cb77db2e453eeaf325832a243670": "0x00da72776c8d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976762b5fc6e2a93176f798ac32e88db1c2a39ddf3465a2c26fa762d0ebf5a2ed3": "0x00341a7e291900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b62534399647f86ce4c0ec6940d3c561ba707ebe2a324ac2941cf8404c67bdb3": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d40cf544a4653193176de2261c2e126fe609cfe25a0873911ce16fb53758c493": "0x00a854ae840c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f24396cf480380c0ccd36f802680f16acad9e4d4fe5dffbb747f0430db9cdcbd": "0x0000434fd7946a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a097e55925733286ec26e4fd1c0bcbfab0ce95e04c032b8c237c586e272a75fc": "0x006240eb873f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b970d1e1439361fb0e49c2723c45e7f4d884312e5770882bec7aace1edbfbc51": "0x00be6bbc8ea800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fb450e0feb74f0d0d654c357b0a36fd591c4e1485203272ea7b8175405380936": "0x00ee1fce3e363b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397add5de3caf4eb830736c0f5b20a1f7159eda97316462341169e663b56f194af1": "0x00647b482aa300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a368752115fa493079eb0f2782b0841d189cf87bab9007a076aba7088344894": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e38a4b30e5090a78555b57fd3271476df93416bacf1adf8d693af2ab43ddd227": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d7eac1d91e12eaba3b7999df716b99061a707ddbb6d4b352d7f1e469cf24e7e": "0x00746ba880fb00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397db23670993ac309071413694c93063aea9d4528133af399c265f2e62490e8b8e": "0x0022217e9e1800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397db48b59df27b28b3cc6dfa9e5752804fd1a8ce66de2b1b6757d602c5c3b08853": "0x0056b961800900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b57e268c1961393017964637f50e4ab271a06fe41e3715a66dba0331b259a38": "0x00cee28ed4df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773d332f6d1feb456746e595bde08a652669fb7190e78ed77c75992277453b169": "0x00244691bdf401000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43ecee039eccea006f786a6dd921254e9005c290ff525a280b70d088939de2954": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb22b6ae54aa19696b02c1ffe66f774a64f6def53b167062c06036ccc22b417d": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f77ef895a8a171fb06ea11aac0967968ee81949df6dfe1019486e14f08dd4612": "0x00b4217f875a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977874eef15e9fda194b375b79586381603f0c3cb248bb1e466825aa009a1726b6": "0x0026a278d70500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783d1f1675503fcfb6b5da7279ac08bf350e317f4095f0faa7f7abe6a1decc307": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397223540756ff071302b885ff032a815f992bc6ad46dbf9ecfc4537158ce9a177b": "0x0088d21c5b0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764c1bd35768e2ef41d30eaccaf4adf9a7cc01d766c051bfd25568f48c50846b9": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ffa203e39c90597535f5f252ada945518b5fb3023fff79cee661832080638340": "0x00b83cd3241d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976996b5a96f2afa2c86a829aa099270e24df064919c7c7c6f31b2a8e6637f2659": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977399681b4a91c1e982f4b6dc241be301e7f897c932c30b2abaf01f9b9124a814": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397214afbd4f4479299436aa7ed5e4f47fcb632934d7697875ca9303d8c62de0122": "0x009a073acd5b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974393bec7048100a5baaec6770b1a3330ffef025a40caa0c66d60ddd130cf13ab": "0x009c7912141900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a5832c97cfbc608b594cf3103152317fa7e4a73a8472fdb1f38cd03329e1fc1c": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4fd869008041b67f65a0dd852b820d7f0905b74d3aada47d2af44e6554ca17d": "0x00745a2fa8bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b1e380e355b71d9a125f6f4b798600923307ad2a2a91c53922dd05588f0754d9": "0x00f0bf279d5800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768944dc9f71e662b470f63a381b0f2dd1ca1b8248968564d23d5894584a50484": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397503c6cb0ff2b5993c712d9b2c14af21bad86ca6b0819747a20b64d4c275191c8": "0x00624f8f730f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722f32b9d6679700e2650b4c3af63d83ea10647213b285d859371adbac323fc41": "0x00c684979f0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a15d02b00072706f076f1c4e5085cf8262a140f3496148378217b6f856db5df8": "0x0030dc8f48a101000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4439ca4cce6eefa4689638418cc00be4221500527362b0618621295334863b687": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339758652a319b0fb0e3d97c69027c912c91dad10716bd9208af83fe0d484ee1cf0f": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f52e662adc56ccced9582b3d722ae81c2d5439927bbca38acaf9b8df72f0eb7": "0x00645dd8e71400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973078b6e8a2818a3d2ea62e98018ed7197e1066e0086f3f33cc8fbdf98831ddbe": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f437cd1e46ef974bfb66b634ce1603edcf2a27b6dcecccf5461a6da991bc8a72": "0x00aa63c979d100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c27c7a07c5720b3bce026193fffaf11d370a947dfd6094a87f8c006bb99501a": "0x003ab9a30d2400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a9291c5547f4e209c7a020d87356891a5955b947f0487bb9469d07e8c044969c": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740847c4ded044d6841cf2ecf0328b1fd85962517b1614185b79836866e1a7f08": "0x006aa028eee502000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738f0cfbf7c2dcd039486641e9d4fff22afc8488b670e8a9efdf43b29a8dc5882": "0x00dc99bd488800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b9d516528c0de12f32770726e4b3768b8c86708555d277be7e2715937662309a": "0x0040763a6b0bde000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da49217f502be783f4122ccc6a4cef33fe91781c025fc6709ded3489a0b011ff": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d63d8e85e01fb802737e786a5747968abbe6402c2ab2710dcbe3271e80a24602": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c03a86ba91779c2a307f34dbd5759d8108d2d5628924f3b5e6e31c3052b82cae": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a2ca667627c02cc4ee4f191c4f6cb769ad09eb36ca0a9ec290c595266fbba765": "0x0080d1a30a5d0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397986d05260287f5210eae9aabd27ef4d67c0f6f91198c04ad3ebf63819e082b8c": "0x00d8b10d918100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d6dbbfb8a8c9d6d85fc956d1e824162b2377c93af9ae701f17d72013c589d43": "0x003e7409320800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6868cf2e32af1fb63b629a66df797e189095e9bf2178cec66faf09914899bf7": "0x00b67872050900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa364d8185ccc63c1f3a8d8039aa4233dc226a2c02498bb015a45bb46c6c8e8b": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e553d9c3312034e307f378d799a4b0856f5ece73e6d37b8063cd5a4a9402a49": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee15c1cb30bab59d35eeaca4a9e4fcc9f7a7c14bc88f560f462fed10d4d22413": "0x00f2d5e5975e15000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f8ce1436fd62c35907a41fc2204201c16b905792bf5719632d2ab5fc839df39": "0x0060a48df79715000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6515d59883cfa46b2671824f95f71af9b39bbca0c790f21a4540584fc688ea6": "0x00c65a1111d361000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f8cfdec2c5342a436c79df726a4a6e1183501711895d58db96985f0c9a1900d": "0x007a4b0e500e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397466199aae0792a1cfa099badc08151c33587608165d9ff6ad36454b2c82dc674": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718551c18c479727c5fe81dcda62b4faf39f0228cf0d6aec90aa19d3b3cca8ef0": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a1ee420c626ceb95955418b2b0b1790af670443bb83a568607d8773587b4a3f": "0x00f031b1450f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c5bd9592a3f356df6be95819697e838dbc100f8f8d5d2da70612f80d505f7b30": "0x000a78cce22300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5d6405a38a857442a712df0c92d896fdab8af98e8071345d1850faae99b9831": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a580ce0b00f55c64c930ae581d23cfa884a6914fd523a4d855268e5eafaba19": "0x0076e6a2f50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dffa505d9ecd10a0231e511ca220294a7a20a6f329bb0880636fd3f0ca200981": "0x002acfc5745300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4fe8ec31f36f7c3c4a4372f738bb7809d3aa5f533f46b3637458a630746b304a8": "0x0080ce9d58ce00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973622741129cc4c83dede878e59e3d4972808a9e917900b3a0c1ac699b5d0e52a": "0x00203f885c017e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ee21173aa9a179a8d458e55f2a84a39281cecb767f015138280644205f77d43": "0x00e80abae14c10000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2b8e4658b45d714e282c4ea4c51f093aa2c8bf8b977da4c9ad26d6c3bd8ce9a": "0x0018809cb72200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397209ea62d6fba011dd63453fb4f4e6a7e5bbb42a982243d67798cc4f1e393b192": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8b32173dcdf87fd92b22afd4bc6ddd861e2d8a24e6ba82889916490eae6c732": "0x001a3581565501000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b93a68b62c56e791d11092a044040ae0b07eb8aab3df83573b4091057edf9335": "0x002c419ebb1000000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0e0cdd062e6eaf24295ad4ccfc41d4609": "0x185e3ed914a3f9da416f69613d98c0848a6435ca4bda8d00af53a8a5bf5898b904316ecc2b9b780084ed10ba7b401696afd2106561b8192c3d821811eddc85be12ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc1677ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc1677ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc1677ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc16772280483e7614020101d7e03e0019d5d0c082ba9e23fc43a2a36b261bcfa5cc3b411fc1a5c88ab2bb7f63b23b15c39983cf38f3ac2dfd9c5168d5d7ebbad83544b46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723fb46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723fb46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723fb46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723f3a2b5aa8ffd4e3c5ccb11d342867d964414dd36e138de466f5fa6d865f19d665d548c490ff6e728ed093a7406711d76b2c7d04c77277fb88b1c3c789fa641737d684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e179d684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e179d684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e179d684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e1797a977e950acc55770b4452fc418bd59fc4ccdc25ce3c2d4cce58dd0d6f9a2d15b98c930b9b4a782ca392580d02ed1185fa3214be9e7669ff7dc096d17d286bd268195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e94168195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e94168195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e94168195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e941fcdeb580add093f3b5f06603032c2fe89d329ba372147c100aa0391a44a516015ce30d8c007d0a438c92c37a660b7709fd1ff3bba79c6c4832ea4107d266e0011a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad82001a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad82001a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad82001a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad82007ce21330f614e9f11065cf3e7e96207fec4086b7cb83584daccf6bac6d35d16cf45475c15d447317b7de38972656d207e362f7fa4429d665ce10a9da2ace254c18168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da5800918168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da5800918168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da5800918168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da58009", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397db4aee364416249336af93ef33595bedadaeeffb9d8e22dbe518bc733725bddb": "0x00909e76a32500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8f18d2e6b1bb7fb4c5964d95d3ba5f486ce8ce4d6064a10eb99778ec9e691e1": "0x004c44f1ae0b00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b481c75a3724cb98d8c614ef1821e1b6721f9fc3bfffe3a324c69bebe07103e44c": "0x00684252765005000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bbb9fb06f1bac334d3d64e294a6b6208cbbb556ab53a0725c4d4b1b8a0478282": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720679813b8468530b4709cba5bc108699f8b733e6e82986b84cfcb3637381971": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339706a62619b7d44f124056c2a55198052889303b39785c217cae0b677ddfb91e85": "0x00c4c38b94ac00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243a57e4c95a199a3c5e2184cf286fc177c97f9c7177b7c6446df6d41a1f4c3eddc": "0x001452cf57531a0000000000000000001f797fff00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b9ddab96a41e46d3d9cf0532cc4778c6612b9db8e1ae12d8e33acab218181f3f": "0x007ceafac42900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ddbd37e25fc34b016df42173321aed158b1e392658b9484ea9d173084e35fc5b": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea185ec285b7999af96888f0898c1544925244446c306da3094e2e73271e090d": "0x0034fc4eb4ae13000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a787a005c84ed93e8716b6cd7518c3d65f7f5302ded3b2152be1e2efb1a96985": "0x0040aef2235f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783fd231791900c77d5abe29d01b1304ca9cc39939d6177a0ab0a1ecda2236d1f": "0x00903d79475800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971541891b08fcc323620fe9bcde98778c1e913b55850b2590df82113cf39f3fd6": "0x00accaa52b0300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41f68c2a85de64409a9eb78fb348dc35a0887079c0be1ab8486cd81e4e6b1b0f0": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5431ab697cc29d6fd8a9b7352f870dac9d4553f0f92f499af3e21f8a0e67eb1": "0x007ece841f8c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7232f1574bebf04d7b5f9ca09525dedd46d7e195637db21698eeca8c9f31f22": "0x00bc8b6ec00100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b480f61f9e642dc02cb69bb7083cc19444a13df167c9cf9a0818c58c389e3b277a": "0x0034179fd39506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ec9f39c51a5cc286445631bbdc59298c8e706579d4ecd949f81d00259c9086e": "0x009ac9845bd301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339776a6f4e35aacc375b4a64b03edfa76ff8d0f4a029df260d3da12f6bdd61378af": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f29732a0415e1f72dfab97570d2bf0ec3f517fa8a8d5a23899aba689a2155806": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a937e4c36d15070dddea0d07842683bab2b8cdf9d4aaac09dc8d366c737a2d19": "0x007ef911b4c709000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b434e9202f203e3369959ae4b3df60f5b7280990775cfd2faafe2d8c6971a69ebd": "0x0018b092324802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d2104006dcb8432ed45cb99c198e2b0f515bb7e8a16acf9567b6936f43fdd495": "0x00f424648f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397774c79c5655c4f62c210728d5af86fff7264813c15269663e25763ab0386795e": "0x000e64d297fe01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b399a58ec33464fb3f5e2567b01fa8facb65aa6ecb8595fc37788aa8b808138": "0x00667bcd2d6e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397825a6b1cbb12ab146466a6ac260e80632b7f85fcc3f516a2a5a32e685c1ca4e1": "0x0012a3c85efa00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f91f92a628d45365aed0a521c01a064d546ddfbbfbaa44b41051c223118b7717": "0x00204a736c3d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac2a392779a03b3c3811cc39692b19ea349494eac2bf64adbec1e2bd0e096f7a": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977879a7aa62a2671d53a7747a20da3552d559398e3cc4637703a4acef81a767ec": "0x00e4d5530b1e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976799bc3fe41c608cd2d5d3503f4ff6b73fa8c086b89e6e340d575aa864b685a3": "0x00e8d992a10400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397edec17321ba9001cb7f5746068a679a078b595a4fcd01d28f3ad27abe5a6a70a": "0x00f0d7b0544100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a61a8455b1364d1b70b40db024079f3db7ba203db86a5c33a88421e29ae434ee": "0x00245b38281600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769a497e2f9613f871399f13585288153ba40c63fa32522212fb1b5e915463477": "0x0014a56b28a300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778612e594574b11816c4979aade5079c4c69b9963501047fc8a1a883f3aa5bb2": "0x0074b138558503000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740fdceb2eb4bc3293dd185456e10e2754f728e0737eb703e84efe9935e78b941": "0x00e849c81e1900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c244004a73d95259c9f813f57402b0633c7bf9f81e5e10631da8c33ab7343ec6": "0x0000c16ff28623000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970fe1e94ecb1e0371caa071e0a0492b353b5019d8b7af846b8e3f762b4c0bf8d4": "0x00dedce2d93f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e2faa3a519fc5c6fc903fafcba73ba3ce8fd8253fa3b17f6f4566c66ecfdea2c": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f1f15b43b3d3825368a65ced1bc97c65913fb0a6b5b51aae2396660047515e13": "0x002acfc5745300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4be9d57852ff862585b0124ccd6b3b9fd6ed59e282895a6acd7d6dcb43f0d5633": "0x00a007c2da5100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be0f84d3c2d7d1d16343cff649935a845a8c9a78476788f32b66641ca851bcf9": "0x002cb5d95f1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a27afeb062799da5261ee5f911254980e7d9edec5f1e0f1612c58f0198426e19": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9211d789c35464f1938730b3592fd485bd3b04a8d2cce3b1721172a0fca6031": "0x00901f44ae003f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb8f01448b216b55afebc6154d634581858fa28361e9870d2ec6b9cb4e0c11c1": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339776e24eb0abd0b34e6a263b994c0f38eb3613c80960eaea907f2bf72cedffd466": "0x00842449d35f03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5b1a7daae99a092fc2c2630cb284a6406cc3c82c9f94088b114402569d3ec2a": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339726c4d1650a42c89163d0a33cbfb73685ec8b5b5dd53b3ea2404fc93dfb134f6b": "0x0082b4b8400200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971020c4345af3c6c5844d3a8f3dc036dbfb6b5a2ac49041b9f4595e654338ada4": "0x003cb11cc30000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397624d9a77d5fa68ad0969871bfaf1b44ef56f7da689e7b9df0ae976488caa0650": "0x00c803ef0e4a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974dd82b58852aa874f89a152bffd3917f33dac43cbb725dd605fe795ff6eb757d": "0x009614e5531101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a5096bf72ecd7a04f7c51aa01d7b3d84e1b0f77a70409784387144c61b978306": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979186ffd40a99e24d2211ec68be0e6a01f3ba84710624f746b8ec1acf28ee32ac": "0x002a952b210300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cdfff9f4dbf4ff0cff6db71fc507be8425ed680b7414e6d8213648bad74ff20a": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f59db5299e178d67af17ddfdc76776867ea6adf5512b89d76aadab5410a64257": "0x00c4c57af23000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339796283e824133f3a49a92cd19d868f368992e89c8e505abe255bac90ba0f7c701": "0x0054a6b6228506000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcac29a0310e1bb45d20cace77ccb62c97d": "0x00e1f505", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c29dc09c6507bcf6f99c4efd88317a5d115afdda6495d1a59f58432f1d9305e": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7e01c73075fcc3df52d982f4d16089c778d629cd6a3ad7965360c37f812245f": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ab073252ff6e9221b245bc4fe7e7727ec66e018c7c87150a1cac06a8f35ad21": "0x008674a4b32c03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a2e90f0c5bae55c08a13c272d899d3331dc5034f782ed83b628379e75eec856": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744d8dc7417facf30385e62c9de8a946122ef006bb4f9e01a01cc8ff535573699": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397363454ccbde9823b6dfa5c9e59f1c1f6c5a46391bbef7a54303efdabb07c55d6": "0x00b0ad01f46005000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339712b8eb850d12cc90dceb0847cf3698d0532cd7da9c86ce69cbe80228cff1f8f2": "0x0056d410e45300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972138b26ebf7fbabd355b932ae8658a6e2065f739b6acf97c47b479d2ad02bfa3": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1d7749642d9a6bf31cb457fe1899063639ae67cca726d18c9a4663c64a3b127": "0x00b420a6093000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972faf2e679e117d8cdb5ee945ea1e4affe9ba3a8e92bc0b20d55fd2b19789c8af": "0x00e23c551e1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767c62d20a60d7f8b0bf6b5527f203dbadb74d3193a4539e1468ba8cec1c7f35f": "0x00ce2f83641a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397982c19b01299adcd7e9fad4b14cf63ed61f75e76cfabae59014624f26a1a905c": "0x0090ba05820500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397048af2b5e01c09f37ed77556e87dc676760e88964f07af0128747236c9ed5562": "0x00fe73aa8ecb1a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a30b1ddb14afe398abeeec993fce182ee0b802423c83714c3e8f86284241029": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397340da2fe1456f27e868319f0392aef2980869c22c9cad18c4f38ae96a26f2f73": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397748b68c8f7382c967884a783e1fad50406dcaa6bd6cb961cda46c89eea6e05ee": "0x00e6236e34f602000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb3631ff8fc9929db27b86a3edec0390f0c7c62e4552ec8970bb3d5f19ba1a2d": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979109720769831089b3bc1e87305b120e1a6180e70c11d91a3783e22e95f99d85": "0x00f066368f7900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab2daaf7a0af0637da67b0bcfd31e24037bb006551dad55616bc37140abf07ed": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ae98e5cbc72b6439c619d793c15ac9ab118f861699cbdf4f64689ba82d8710cf": "0x007e33be071500000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b464d5d9ff57e3cf3895f2c86b9fc9d8e8f32fa41b3c7a35d4bc988bcc172925be": "0x00be5449b71900000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b65797384f7bce41f3655eb13864a315d6cab21556b38b5a51a410a18cb840c891841b1": "0x3a2b5aa8ffd4e3c5ccb11d342867d964414dd36e138de466f5fa6d865f19d665", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733a889c73e7a1ae26a1ee7f1c85d2dc406b851440e373ed7f53eb06141a079c9": "0x0024e56bf63801000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4029806cde27f7ed49aa001497f9aa1f495971781cab4994ecc0fc71e7680fda4": "0x006ee223f3bf00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f15b80878c905960bf01faf020642acb02e0056a5874465e455fdcfcd9fe7882": "0x0084df6214a700000000000000000000", + "0xf2794c22e353e9a839f12faab03a911b7f17cdfbfa73331856cca0acddd7842e": "0x00000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9d4c89cf1736723879bdde27610075836e6e491662f2dd14921b932f491e926": "0x00bc41b5d36900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46ea236460509148b477c0db0f3dc291848f30528296c4cbb9e34fa1944a8852f": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973bc6e04d2782a1abbc5b79b8bc50ac5f1b99e2f3f3b979f927ec623f60650bcc": "0x0078ca2c506300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793aa09de1ab126f87a21ce23a257bfdb8858e2b0c6683064cbcb9dfe5c88cf01": "0x00f28802947000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971d5e38002acf492c947534d6db7e46409900dbed309cf63474c9a21926fee2a6": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975db8b6d9987874ebe8e923e83f9b1c6a2b2e455b0260f98af06be4652f994025": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b31210bda0a7303d2f34011d7ab9d7249575d72d6413c1ba2a68fc0bc47a4c0": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd09407e2b21561ddb0869a33dfa1d701c33bebe279202e2a9e8fce77b3c53a0": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2fc59f3309f34e36d63661d3ca620791854d8286bea13cab217912bc2de520b": "0x0080afe64af904000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d522ededf818203f83f662f7789e20c43708ce98d5f55be80610ae71a2f0d7cf": "0x0040f09bbce108000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740e2d7f61f1bbb309d464046cad5b8392b6e77f35745b03d63ebd3dd78986f91": "0x006cb365fe4d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971856f7cdc86352b326db61aebc613eaef6d6e110849fdd6c3799e6f305199cfa": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397618e60f764c4dd302706f52d6b0df067c26a47308e1a2e435090bb863cef5fec": "0x00fe39811a0e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cdd9a6577b85dc0eaa11c1bdfa48226cf55ac2059fdc3ecb3a7f1b3c41b7f022": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba77b0b352d7c368ef042b3fcf1c74f066bf689b3ac80a47bfc7632e9cf81b35": "0x00d6de0f830800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d0b4cb090ff8a3a38f4fb1d11c86afa04fa4ccd49b7652f1d2692af3720333a7": "0x0068068c624c06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e5aee84eecdc400867864aa46905aa0c5830bd95051b283dcab7615001172ca": "0x0026a278d70500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a044fa85e5756916302aa9946ef5164495b7d919d75e393dbf1e12a121c6bf6": "0x0044cec0982500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ad3b3b9b22aea083ed75e1506738c8976073a8350ce914e1afca8130db5024cf": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f4bd770cf9d0f0f14e6afc7df01400ec610f1afd65340aa95f529fea6e71240": "0x005094aea18c02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a8b46e7f0cadec7a80bd9a6b257303c7131a46a43455930d4af96d65b02e3b0": "0x0036effeca8d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397608130e75afef93c748d584fbc11544ff558cce74df76fc0fcf79ca4a52231df": "0x00c0e1d0612100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f426e2a998d899c30c1b6c74cd4b7ce63034d1858ca858b6eb1875d3b9542620": "0x006a71b29a0f04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397baefaebbdd47b6d1a14ed7884f4513bd329136c1a4c70661cf1dee98911bcc81": "0x00c0e1d0612100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4641de20f8d6deff5ed7de6ad677c3443959c724f6761d85523a5a5ddcf7d7ce1": "0x00341735f16d20000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a42ba8fda4302a8703f934a58f72b267b08ccf330eede446457a43ec0737f795": "0x0018b092324802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c93c782ec19b6f7a140e17d3aee1e76aa7a552ce8351ca4b9ad0ad196e56ae0": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b861f1e5d2dbfdf1dde91388fec85fd4d4d68f9fb8c4c0c2685212da8401200c": "0x00c4463cbc2e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b221f2a75bf4c42960e77cc4dc4793addc5c893b804ecf24a76d918abaec41b": "0x004efde96e0b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397349190cc0ef7c7f808787005d23263ce96443925c4e79b0598325c9a67c9d08a": "0x00be4216aa73bb000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c846ad4fff07c8302a3b0725c0957e36ca092770a3cc8963971f7c497a16bd17": "0x001242a3973e00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b49376af8ec85b9d8597fd32d2bc85859d29cf9b901c1203ad8fa20edfb0074c15": "0x00e40b54020000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e75127b0aa1735e5ba58d3236316c671fe4f00ed366ee72417c9ed02a53a8019e85b8": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455342388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345534220e2be37dbdb56afdd62d81c6ed49cc8eb5acc0739aa3c0ea6de2e83cd66c86241e3f14dca035256d45ba9501c64d1e635badd0961a0e5c0faa94930d28f4975088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341e7c134872c9fc375ef3fc3d54deb576f32738b26595476d21e5c7892f9e611e3e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553414023f1505e3e54e2925d67915d720d12db1a32bcc04218ad713d75f5b543cbc5288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455341088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455340088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533ff88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533fe88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533fd88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533fc88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533fb80899484d584894ce49d4192c2e5a8ed9167e2c5da50a3534d022777640aed7c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533f90e0a207225e52c21bfbf08c5022e9a6fb26daf70c6cee1ee92a6a5c02085cf2488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533f788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533f63ec3099325a5663af5fe203517a09f655f823b941d71b79364637ccd7b1f937788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533f488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533f388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533f288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533f126e93371e3e2b7c38be52ac91e8ea621a5ad7518d5580fa7b36d250b9ed3571a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533ef88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533ee88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533ed88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533ec", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397074bbf3e2941c6ec69c11c07b95ec94978a7f803b98547e0065d28d8d14ca781": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397299865985150a0cd2405ba2fa98e3840752e11dd8b36bc4bbeb58d41afd68ce7": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397397d9339cd90de5d97ca8001535c05aa96c7c7f7c90345f6b3423b13b7aeaa55": "0x0080c6a47e8d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397241207cd82f0b1f9c6ce09463158efc650b173760e5f050543aa28d482425867": "0x00f4fb4e8b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708589b39426bd955f399bb7fdfdeba99d3bfb0da4df921db64c425168b2ef2c6": "0x00fa3db39f3300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6ed3c15f7080cb64ad72f39af7e4413f8be6d4173be693a20758fda0def0736": "0x0020c9e7070400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397427e00df8e783018c51c3cf6a83840e2ae3fb942cd6c8c8eea3bfe4339610cfe": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e168b0ce4f7bd2bad4edaf81f9cc7d5c180484f10f7166a30b42a326274ea3a": "0x00120a85da7e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397476ba1dfc8be18636b055b32452a64050b426c3f810d161ea73447f7e20db421": "0x00d098d4af7100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970abf60c9d659d29b34929a4c503effd38c3213dbf41198917e1f10ab960ad691": "0x005c3f8afc1e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ecbe24cdfc7d4197d7afc2226791fa2ecdba67e2543aded8fb7521cf8a7c1d5": "0x004efde96e0b00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4342447024b1f1a9f090e3763e34529ed206953e1c8b8bb4f50ce043b526e6c18": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397404cdb81dfd36e5018f52434e447131060ead8fb16d54ece89bdad1c0797de9d": "0x0002651cbc0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785881748c6adeb75d12128bef39f815c9c2284a7458293e958687851d6579cdf": "0x0048a8b159c903000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339723076e74a4b56505a6f03f6e884748c9e12ceddb65fb81064cce3c4ebf98d21d": "0x008a0e5a780800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751998f81c1321ba1f536814da2b1ba042e86e46863bef693367dafc10c3d9b93": "0x00aa5106df0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c3fbcd6f3511800613c24d063b40168fc6a78842190b08c003a542746dc58c2": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397585b7f227af4aa9e7a728811555023a05b0b0ee356eb862e55c8314229bb96bf": "0x00fa4c6f798806000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579731a1ada8f6156bd850b5f01db88a074a4aa38e6d087ba7477aadfba84f3cbf899": "0x7a977e950acc55770b4452fc418bd59fc4ccdc25ce3c2d4cce58dd0d6f9a2d15", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d872824313e365c07f536bd495699d5fa01b88a87abcd9c14858ac0505b6fbfbbb014ad4": "0x00d45be1e85b7700000000000000000020d96a8604000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971dcd53c415a20adb1628e54d12330bd4dc26a3de1eb4ddbafdeb540fd4a45715": "0x00301a45ba2900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c44263e162cff7923af91fb6ef68a5dc120e3bc9fd9d6a83b1dd54ea0ce2ff2b": "0x00acc822980700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397615ee2196e0ae215ee218b43d40d4b20ef1ce91967ac868b851ae7dbd60a7246": "0x00f6ad147b7600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397159eb804709578c96f8d7e5e6a84b08508efa11128e7351e9548d117ce67b840": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397db815626b21a15d01d49af3ebf1e0bbccfec8418eab820c7f523ca60108f816b": "0x005880abe94f01000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e0a9021692c2bfb9b13f7069c71f0dc32e2b72d7c78643275b3e33b185148280": "0x00fa16e50a7949000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397281ef1c256c95083f243b70df516a24e6eb8293a01a9d99dd80234fb3bf0958a": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb8a7ae889283039a7c499b92d8eb9052511332c47311b0770b78f3f881def36": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c68d5b53dfbeeee4e6c8829f6041a88d980a0f6d448c0b26dff5f6c7d6629e32": "0x0008e8e1298b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397584d3bd2671dbfe605b94b2fb52b3545888de13476df89b7e3a27d03e44cbc52": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397386485de8a0eb1e77ffbb1643ee053bc1af52eec103292332a1edc0e07323558": "0x005c3dd1035f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973540bdf0df2592e9f974052ef58e05cb36821603affc1de3b0afc5a4ce13490f": "0x0080c045b21c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dcfdf1f4c05a893178592eb2972d3bd208a2c85f2250c0a9f0db27f637e737ef": "0x00461784db1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fef0734c1e1746c5228f4e344990bd3d189eea158b9d334e5d79d99fc4f9f744": "0x0046fc085af703000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700586efa0ca946862b9af6b7e98cfb2150effe104dffb0e5e382fba161aa7229": "0x006e1f92990104000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d46628fbd89119d1469a7a583b7f342360f3dacac689c09b2fc3dea43677f9b": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973d31eeb29629b2701c46aa785d354360d2768a908e10b16f51e798915e565d46": "0x00fc717fa12000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ac1114ebbd8ebd44ecae115097e982ef4a74751acf43b677669a9e33995424e": "0x00962d3a03ff0e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d25c581322c811968a27c16b192a662d3fe5dd76821675861d3eff8a3c8af879": "0x00d42517c30800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4e4f759421349a7a1c19d52e2fa7c0989a2d7aab6a74cb78c1e4595e6427d15": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e196e011c38fbf0cc1f6c59bea94c61c8e3e8a8262b687d492248b76dc8b2ed6": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b2a6596da7de449bc2e27cb3a025495c4ba3a4ac8e85b7def1ef7165d29cca92": "0x00ae5806543500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397acad2ad1b1c4fc875aa093eacb4f50c33b9a2ff63688a034ba3fdca32fb0b4e5": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c4a855d36af69e1155f751db9e92bc74e63e662eb53e35eb0b798db27ecdbb2": "0x0080c6a47e8d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973318c715aa0ea4a648882a97033d2d82d2576269fb5397a087be59c01ace2914": "0x00a60beb412100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e24bb765faceb8eed15fd38fca44028711269b82c1087b8ef0454c9bb3fc3b3": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d4d57709517b213f0db14705badef2660d2e0e17b6c1e2b656cfef265d25e6cb": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f96fc9d87b0d987a77895ee437deb413f1249f6c6816d0fc7585ce2ff0074c6d": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c3287dea9c4a41a960ec62a368cef7b838d0e0ed2b191c1463a4be3ce5f1b228": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fd834098d536dcbce83c2a1af610f1e238b62c77c6cbd9ecd3d6bf81fb3243cc": "0x005c88c2daeffb000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781bc44b66654bd13df3f8f1d7b7ea4e38dcdcf8047cbb6ee9d97922c272d52d3": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ab0ea9ad6468c22e101415cd3ae5a00857063bc5d4ecbfedd3cb1b09c47fa47": "0x0052c7a69f2606000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f844841cd9e6a884d2a66df0121abe009a559da6a964d1cbb1c5ddbcf4f0dbb": "0x00942e7a950000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775ee6d21c5413e84019cdb81416d401a1667141c5d236355dfa67afc18fe7d1c": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3eed2a4d979938979e031cec723704a97dfb5ab3f9348188572a2bf0980f651": "0x00aac729e42f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa910ba96482b7b0b73e3f17d214d51bd49f5f2718f800ef88449c9a89be66a1": "0x00d22374f95f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e779b75f30c4fb837099f6f6afb91e91a5d42bb6f2a47f79b5e7e137a9f4f425": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975afbaafaf4894d155d216918dbfd35225c7f1ddf9f76b0e7d0e635249dba537b": "0x0056b961800900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a189cbb95f80a66564dbfb4b1501cd57073e1a45ee61c5963233e91fdb36f820": "0x0088e11e179200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba1189331c08766d3292bfaa36b0c82b621e95278cdb23865e44b1b01e9a62de": "0x001efb11781e02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744061268e708cdd23f318750de9fcbc0f8073b9c9b3f0349a251361c48e61e63": "0x00be4467800100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d01b32aa4109dafdcb4c1c89dd47d1fcf5e4997e60fc538c77a059a76fd37ced": "0x00ae3aede4ee00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972183e51de03c411e4a73b186d132f4770340784461442f9e81635f63e2fcf04f": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f445d09e06e99af9e14b5bbbd33f73b2f7b87c5a5d40a1f680830fcb9f68c4c8": "0x009cdcc16b3b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ed11b7f2992696466a3cc73a347f918d4feef1b7cd39b76d3cfa6904c51c1d3": "0x00549b94a59e00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a20efa8365b2d90e72062803cdf863028775fb49bd5fd32662df8b8589dd597f": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397798b158ace5a01ab332404b3756369ec8e50f56ab8d6b66c58bee95b315c7e17": "0x004203eec38a05000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3": "0x02", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c077afa6cd946b3d26c003242765fd60990da7ae5a7d9b0236628cb908ac858c": "0x00645dd8e71400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ca0f9280886668c15286f6ac59eacb3c9788b7e15c94824e1cc3627a350273f": "0x00da25696b3a00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40e8c264d4b66aedf67f5672d6745dee4e8e6c6f0d0afc7a8757b165322aa16d7": "0x00347818775500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339753d7a03970b1fbe498cd0ec087f2c6170f1ecf6ac3457f82c0789a3a3bae5c18": "0x00dc023837a403000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4dec0edef2447e5773acb08bb5b3ecf5dc6325e343e3c39c1472eb27004a4bca7": "0x0080e03779c311000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c711c270cda75182be5f29714d74462369ce982584ef5134dcb41fae3a734907": "0x0002d40cf16700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c869c569f80eb7aa54afc99f515a21926a8355c44b63249bd910b60a5fb7019": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397444fa899db46ee8d3d096737bf51e7b0d658e3435750e702b4600eb37209d602": "0x00b2f5886e9700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339716fed2c1f991e0dfd326b0cf4c17001d99b29ca780050a32a88b6af12a4f437b": "0x0070ca7d0f5501000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339753485ed9ca92484d0cd971e8625a1356b49c7cb76ba97cd9ff1c2014549b7375": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397491e171a6ca341dbdeb57d5cb11df96f0b1cb3c8b6ff5637620c2eff9897a100": "0x0024858b773000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bf0fbe3cfe3724c48a5193995bb6902f2fcf3d49d966f813464d21d0619ecb0": "0x0088d21c5b0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397954b5f47b04e6ad10cbd3c8383c8bc2e94d8d16ee6f31b9387da1b84067dd686": "0x0098c5448d1600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e7c79324d355237126a9a56fa9f21c17e9de9c2868e4fedc3a19e834b494a983": "0x009cb26e1c2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2e44216d4e171b0108317e2e7809e17f7f06cadf9d009c45fd57217ca47da89": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f1cf33b770b57f2662dbf176ab803348e831b5aaa9b0dc89b7fa24c2d9258af": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397882f2a33bb3f548a6541cba7e350e756a15d968f6e3af4e9065488f682c1495b": "0x0032efcc580900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978b3e7b1194804fc30f433d8f7e56f61fa39204d71824fa59cdcfcbea03ef4fd3": "0x00b27571ba6a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b13e5cd0fb5c449129a55f38c2ff7955e4bb2caf4b00e6c448d27005c0154d87": "0x00b218f2c65f03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c476c4c7c5c89a391a14fe3ac524e4101d1980ce4083aca43732853307e4312": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972de384695741f03e5f1bd61a9c729f955fb1a7953798359cf9e8e125f6c7a09f": "0x009e359d4a0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973020c3e14dca96abda8fb78a2dc1ff932343374e17669b0eda12da6d86c101f4": "0x00a0724e180900000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973bc0e4d31d3d1e21ac6c1cacb0f05457af3e4ce73344c7318a49298adf99351d4": "0x7ce21330f614e9f11065cf3e7e96207fec4086b7cb83584daccf6bac6d35d16c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a6a90ebb8cd93840d5e30510bd9836312d223c41d7081126b83be8d7179c06f": "0x00d26a9b6f0d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c77d8bdb7f794aff84770c7c85d9d9e198ef0a90961a9bbc3bb28ad4b7317710": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397321ae9b7132719a50aec1babcb8903e781ad06ad7432b03717df59be33e91e3d": "0x004834a0a33f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b90774fe7a4adce204af2016b8f4adea0fa79ae52c93ed8d7c11ad958e5b216": "0x00c8a697cf0676020000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dc7d4c89b67313bc3fd9283f3cdd51c4898669b90ed66f01294596c6ef878b5e": "0x008c5b88af0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b2c0a074959c39a5a3fdd734866fa67607b539269527d8c4d25e18118ab85dc6": "0x00f077ddc02b0f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397951606ef876a14dd53547e00a0cffce5797f0f9bab38996c36b96c5ca2c6f5cb": "0x00fa194ed82900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339728d87fb520deddad7742e492634eee16427c9a62f32477cfc8290ad9c6326f77": "0x006cfe5380ca41000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973fcde6609f96a72323069020ca7f3bd6f83ba546f033fedfa16f8b68f71d5567": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b97c44b64e288b3542540f07dda2d9d1f9414a50f98799c0104459bf1b2fe868": "0x00ea32381b0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339780868b51512d1ce5d4214997d8d1b13bcc336f56b7e3367ce88028084e68900a": "0x00249ddec95400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f81e3c6b60ef4693959790d52cad7ffe652f6beff24bc2bf438861763d4f42b": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339712863afe866baa5fbe26dd93ced6bf498dbcca16ef26f6a793ad91eea2140c58": "0x007ab0403b2c00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e7512b54e7369fd1e5b9a7f0814e32046aded3caa4ec45a62a4e98a99160b91b34b51": "0x0101faecfd2322e369e0f4d1fc9677c6bad5b8f84b69f4a39881745e8325d64e2d0ec1a82204f76e2f3b4fcb5ec75a9c4bce9801ebe7affc1b9867cbccb75f47db0126bbbc05dc79375d55c293e921864d2a532856fa5b65afb218709599b710177088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553106fc0297afe08648c61f32cd3e302f71bf05c56f39d86e3dcb9728037c2397423f16000fafb501c8e9db5a99693441cade6cc91682da9b06c7045027f24b547ed4f28fd34f402602d61b40d3166e8786d5696f2c656bb1a8f33704dc00b00e6c6c38553e116232fc90a5c38e0e55e42e61c3dbcc43c5b240ea7c3e32b37d67c951f07d91bbde80ffdb4c50b3bd6faeea64ab44df1a2f1d6cd45d479d3c07bb5ec6726aa3997c0b3a9b23dbd0f5577be9740eda4ebb9ee558d33c9d0b41f17d9347abac510a7e28d5f65242fdfd329a707528f5a2865ded8e342968b01b014fee54a31e65d592563b7f89b578b5a31daaf6519d490f8cf20b452e4eebf823e6aabdc02e7288eea025b732f0344d8414737f0e838b36d2a85deabf429b2dec6c390f4e0309e0dba9a3bbace6ed2b196b59a7283b680b20a32248e8179d59187362760a8c0c31c6014b9ffdf60eaa5c6b569b16fa1cc7932dba4ed15e733049f6d613f60a68aa2edb8e091c3bf6f6cfbcebe67961561df2af74835a23f584e043ed189e60796c6a12cdacf70d75060b72d0b25fd53e51cfb217d298cb2b8d91e93a6db0eb10f2db6e2380b10c2e80205d839e03b596e228fd8df2bc75bfc596aeab246a1a5d08cfc927f31eb6dd85f3d6d05ea325b982a5589c4f418e178f4fefd93101861165f38113498b4e5fb2f0cc12c0a36f1d9ffe1a1e270d2345a937518fc2d6d0151583b65a5a289e03c622f404c95732953aa0099703e693268fb1b3c1b5985c7eab8fc2dc180181d30f297491cce3e74e081ac2376380cc24eaae219c0140f9719739d71de2f79afb5653be5ddf31e4ddaff6af9b52625516b4a8f5c52b705c51fe40b32185b55049705c63c8df0fd1be9f576fa8aab2ef3a5350c12f4bbc1deacfc7e5c6e5f0373560c14fbce156ff2a0ed7e208d049ccd985dec85545e42d9017ca3c0f68f4b4639b26273b2397727cfa8e7276c93760ea877d2cb0622c709012f807af8fc3f0d2abb0c51ca9a88d4ef24d1a092bf89dacf5ce63ea1d804a96590d940c4bec0560a3e6228ae4e4c6cbcafd7deddc1a7142c8440ee71072c6f6fafac6c8ca374f56096b561772e05537f112a0d9e8346d1cfc6401de2428490ea37531c4654fac2b99ccee3da19a5727aac118ec8aa635b80d0fb376f3aef0ea6117a8f8cabd6b4970221a9f5718b3dc5f9d212529bbe64638bc945f5bcc8cf7933962cb2d0c468473bdcb8bf2b705294c6ecbe54e0d6eabbbead7286c789743345abc4d0010997f5af311e7138aca868cee71c85da5ebb78fd9e780447c5ebd9f74280353f1ab2ab4d91d811ef9cc766666cd5509d582965dc2b41b3f7e095d9e2ce6bd88d8b2e0a91cd0cc584adc7bd4e27b48624a4f8a81b71e683c6c8e053bc6d1d234bd0f57b2db8bd022594456c683009d52548dcd1bfa09db457ce12bf707fba68bfcbe27e679ad81457e213c62432b705cf4d8cda243d75e7288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553105b8ec94a46bfa2a5ca9bd55355d5fd5381f4fa603bea39822e28fe6f4ec4061475c3d26776ca5b7b1b296a196eea3cb5437e7cfadb599c5ceb4b8fe9f02880a389e0b94ea09f2eb6edaf6d94752f6eb1f78b641f62472e46fc0e611238e525943445437376b7a357641514a427a4d59337238745356456552787741394a6776477a0e47bfe7c962bfa0fd68712d2f0f48a5860e1d26553201c7b69cecf081403ac0ccbdc8e0b2a70168cbaa5181e39e1e00f846f84c8d6ddf0a7d4f67058c9b646cb98ee23392da461bb3bdca3222b23bd0bb5af030f3052c02ce125c6665ab08d484e10ce08164ab7d798909082866bb1cfbcbf65d76faa1d6fd57826d36c76c8ccb42774258b3b60b97907e01f2e404399cb36be9fe50ea55dfca6026d7e1392e460f299b2e0e4491e0eb192dcce836e6ac976a22f1efc229c036587b1efa0a12c68264b410597f3a3319ebf7ac86d2abeed5e5cad4efe190c744f0ebb9ad264cee71de18291ff4c68ac6d091d6e1c36d125c5bbca201c6a9d5dea7752140173dcb0110d60de968a850623cee3158f646c49e1d5badb6a279c068974d6a6513211bacc8a1f61a214963a29cd53db26607db086c8e066f521e9a073c9a4fa585238b05978c0d74d441bc740a41fb4295180f87169e223650910c6848e901997f4fbd89ed5213da63a46da6ff5dacea62d24fb9009f1758abb0a57ef258824fb68cf75f737ea0b0461e39b7a75641dd34d1ac49313922d3d5c4e429b683d6f82232aebdc78278b61b794ac4d636b3bdf15b01e8c3eb0b76476a7315356b5cad0d283bf53bce9e545cdf2440cf6b678af58c51e1051f98abbf03a62b210ff2ea207876d325b7e951db1aed53c42e3b44ed588918d9489e2cae2ecf611a8768c640dd24c212f887efc72fc27674e93551da7b81b66c9a2f53926b7bab15c51acac4a2611b65c473a6861e0dedd38e6b148a574da50a854db53c69f1ea4941f0d628b252ae3c5da5027182c53e3e4e31d56729e046cce68dcc1e64a3fd88f27c6d3308fdccfa7883de5a4b8bf5b3b48194dbcbf83ed2e0c77dc517d44c5c5882015e60026548dc63ab854c688f0f6555421f4a59be10ae391eb74e030b9f08152b4d00d37030de1b80b7e6be7f7ac09075d4c614f67a928f379c207f187ac8c1f727", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f2cca7cd2d3af065629b0b9ef76b7a9c33acde83f7ab995099a4418cec416e8": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c625f4a9d97de218d11a9cfb8d6496d3aeb21e1e1fca052c02d19ce45cb7ec31": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397990c89fc15b1423ebf2cb3a3294717697e96a76459a8906fa3cd02e41c4da41a": "0x002484462f7d00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b45d11d7336e0e1f4f8bff6401869741bb705e20b6220fb9c704cddb681d33231a": "0x00a843143e4d01000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282433620f81fe27dfa6ba47ad798b27edc1c659a13408a0f6bf2391bd7429020608b": "0x0014c5855a3813000000000000000000d39989ba00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339709d3b8b58eec1bf7c6e0ab4d870ea1be06214b85a76b78554aea15063d0444ec": "0x009cc0f3713341000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744367b4c30ed18f8be0e2046d541d7c56e633293caca79cdf71f2b4e3c68d2c8": "0x00366603bff80c000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4381b5bd9b04a62616c14b718a534b6cbdc303df70f4a1ffe5c65cee67f955361": "0x008027461a740a010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397523f65b1cbee606055898388021d35846816e080da587c5fd235879a0f71d9cf": "0x00f031b1450f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1a7c4808b2133b099e281904575a38dd9441ddc1eed494305b9dc7307f1c719": "0x00c07c9e760300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397812864c448ba1731d8e7e460aa8c6270dacc50a362beace2d038cda02d5d7d54": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397643112b139d3d39cb262af7ed83ef6b8223cb26893082eb387e1d7e85409e9a4": "0x0052941237d400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339761bbc20bb8177f6f1a76d39e51baa114a3f66108e1fe3f3a58110e5bffd1be36": "0x00ee4eb50cd201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e6b308b3ba0bdd2856d82ec29437c8565ccee01af5978aff17b1321d9db31232": "0x009ab138061a01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397de84be9421d3d1abcaee6649dd4ab8a9bb12fe3a9f0a4501b92687bc1a1db142": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975dfdcf0f48570327d8ccd9b14d47947973b5ca33ef5e628423a7f52ba4b4580d": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d44d9ca94c41f14bb31f623adf59c4863595a7474be1cd9b63005b7891e37e7": "0x00e67db2845e01000000000000000000", + "0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e78c385c862a9b20750ddfdb94d8785a0eede75d76941f3eff345a0fd9bc588": "0x00dec475160300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d0b53aeaa486a7cbd238a29c7aec6a8d6eae52b936e7190aa94c53e7a36d2c85": "0x00ccf483926900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978cbbb35d810a3aa5a34a67b33fcc0a2b4293895aa322846ba98bf6b9a7759282": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397885548a7515cc0274ec1cfcee30f9ed01a195bc8a86c2e494db14eafa8763df0": "0x0068367fe62d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397806946a24a68482338553324ecb4641fd9e63512cbff8938ea302909d8ec70b5": "0x00da5284960300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397292ecde05fbeb8cb89bdd145878db1772383b72c29a46c29aabf0e66632b3eb1": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970dbaafcdae90ac709ee5edbdc38c656b68a0d715c340f48dd294b7fca51dbb4a": "0x00bc04ffc76607000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397111ebc8f0c5f311bd1aaf939c8403a462f81200a7673baf45b978cfa7e9e0669": "0x000c254e602000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d13bc1a88544e5637a929c7640add1d9dd81da5f9927a7750cafb22f72a1658": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970491dcdf10a82d46ba7ae25e109f506da678defe667fec22f6475bb6f7b619e3": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f1b83931f524fb4729bf07ff4bb5fb1d4ef0462ee3edf17b916a7be1a5f34f65": "0x00a27b4c1d6400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974dab5b70cf0989e928c84208145f7feddad94dd38bcd83ab5a65912dfbc444a2": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d40d1e7113f70f25f97dc0a9e98b61453296c7bd167c05b54e8f02dcaf252bec": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bf2d73785be95ce9dc573a165fd8f045ca5e15c949a8860b1f6c7dfb4553257": "0x00165b74a10500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b10be3022696f26dab4140c1259a43c2ad9a0073de7ce630bc0c6a47c2ef7b64": "0x007aa137823e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a153629bfa1e4fb751187de2d037fabecc987dd5b9bfd03bac8e70e8382df39": "0x004c44f1ae0b00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e7512c7856cb5ae12a2894083db901119ee630c3cd37725716a98a446a3f2476ecd73": "0x0101b2dc42595cd47cf78bd4fa4f99b99cd4f20ec4ea682b0715d906b5694e4dc345da9c6a6ad458f966eb78979e4c7bf8557a89f71c221927e0efd1f5c8614e815488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531a988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531a888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531a788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531a688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531a588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531a488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531a388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531a288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531a188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531a088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455319088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531870628dae391a37ccb6ccae7e6b6495c2622d69cda00000000000000000000000088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455318088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455317188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531700016292937846b8e0f933c667229d8b6765917b86dd19e0f6c32bdb4ab1a2e3488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455316c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa7e5ff42bde28e881edd85005eeed16e54e53b3257ba5c0bd1ecf809d741779": "0x00ca752c232500000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b410a5562e0be040e127774c5d7737161a4af53b6da1184f0dd5281598c443a96c": "0x00ae256710bcf2000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7e8ea38e268f7a4e61f37ea79050bb711711a4681748ac09744abdd7666c0a3": "0x00d26a9b6f0d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971bb01790f21e53cf7ca423a0ef2a8dc08fbd3d21684105c250b521f74105b796": "0x00d89163946902000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41c912a261be47255137fc3c4a199f82958a8a47c5ac1403f13969d48017f7d03": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6daacdb378eba7a05fbd24700bc64c7a78bf4ca27d2577af42a8250993f81e2": "0x004e1d826b2608000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e6f918d5a17137b3946015bbc733e29b574563a3f1a5d0024781cd819d7a0f18": "0x00c69e08b80700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f7df2080ba4ba7ded52b4f3bcee531938270ce8354f8b92442f6322c32c5f661": "0x000290e3bb2d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397799aa1af68e2f81d98712486a535c41e4d1c3dda148cdb934a7fb0bcfc044b6d": "0x0048efb761f301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ecdc7f253ef7e9149f4bbdb93c26a83e5246b6320e409dedad7c3055e63cd11": "0x005a2febd9e304000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397699c8ac6b2350ce2122f6d43a5926e44c112fde83f2e74f240ebb4bc34f45670": "0x00206885de1800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f35cbeeac8c2d96e26915d2f411208e17b4c2d4f6c5a1c01a195a7cdb5bc0afe": "0x00e0ec47918f06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af18244c0bae41ec2d19b781ffee661ae4218998b678095f6cfc7f33bc3edd8e": "0x00ae9f17c4be12000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701860111a28e23c596cdbeb04f7c0fb8d9b0ccc9f881afcc2205912cc60916a5": "0x00864900a51c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5252704a73d4b87f3a244219ed761c728faa8f1f1bec3aff601280f32fd1040": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727a440ddd5288b175522bafb1d50509cc63257b28a583f4b44c75d330d58784d": "0x006e7f7b980800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799718678903aed056b39863ab400c0e79f2f1ddc2adb07d02a173067a6d9a14d": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e7ddf1b23ee9626d29c64806c458b411f2c92c824c9de19818f18350cfbb08e6": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339734c8cac6e4fa312fc576c247b8af08345bd44043dcdff0c06a8b2a5a59d4cfe6": "0x00306025659004000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3d3350b6daa0f6ce60fb8519333a1f28fa880bc568c61d177602b7b80265ee0": "0x00a0d6432c8f0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c0a17af675c043e1aed36282b949fef14f935a5a0a5f36b5c7551bd659b5e990": "0x0098224f9b6720000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974622dacf701ec5844237c113bf4f32be34fc3081d6ae71515c45f8d17382a20d": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d4e95fbaf162620c3e5d553775fe7a269bafb2bada3e36626a46ca68cdcfefcf": "0x003aec118e1b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f7e0cdf733a50a49208617331bcbd6145da0a09ae0e66b3b521fe30dc1acad5": "0x005880abe94f01000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b48c3aaca32d45ffc91e8e0f86029393631b1de797e0f8a8d84fe32491b3603a04": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b54a850559d7f951fe8ecb767229d4e4e59da057973bbfdfeacca8ae64468af": "0x00805cec442900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1d8c9358166e926c5b29f5aa7262bb8d13dce556cda3bd6d98261cef14857d7": "0x0010b8a666b600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef80ab6ded3bcdc4a2da9910cb1eae8e3f5583613aa94e5ca3de07181e0053f6": "0x00f2dbcfb47a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975be88dfe2bd4801524b55ee8f8c19036e7dcbd2134378b0a5a2d5bc0715459bf": "0x00b438b5fcb901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ef354e6e5f0365b4ab060a2f77b0bfea013193bdfbe3e989d9917d3f6c89598": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c0dd0eac2c0d94f28b556a029c485e928d09e85e6034b4f7f466047eb351c253": "0x0002d703357000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970145db2891424ae429263d8c6a3962cd7fdaecbbbdd1635457602920ed7200f5": "0x00900126fb4700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d65768e349bc9b5fda8a7ed164ce063da7bce35164f12a791eca9b415329cdc5": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720f49bdf3ffc9a868ccb19a4d810fcd5ef5b42d06bd0f03f8a8edd7bf6152066": "0x0030dc8f48a101000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43e4bb9d7ed405c9da5a1b121d882aec9ad1b8e132921b96222f937afdf1301b5": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb3b89b2bf479bd9f1b5a90f2eb5b8920e54c68dde7894266674422b876221c7": "0x00600d64ce0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397657ec14fd8a614d4dc8d902409dffca4d19680aa6633024c6c956191aae43e1c": "0x007ef91cb75900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d49b59397cc3376e8939577df499ebcd9302ae19190e79ef9c97bd2366dab7bf": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f68859838c6dbdfd7295d683e5168b3184583e80119902d42bbf13d4aa7def68": "0x00849704501c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b3cd350ec15fec050564d443e2256490fb2300fbdc8a347bda1cfeb10a1410f0": "0x00ba9d84ec0e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978db577eedef94e4f2cefa05037686997b14b36b6755d8aa3e107d9e9796d19c4": "0x0082313f7f2d19010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975e7c000378704b086ad09f1244ededf381e51326657c39b6be4ce7ef54f613bb": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3fbf2f108e817e150add4357b1489098e4337c0fc43be71240fea480f408628": "0x00806231a08101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798adfdb69aeb60a08cf50536b164e33d6ebd3230715c4aad752873ebc0426550": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799490f31f3ae6bdd8bbe42dba00739ce2f235710c8038cdcc8183c2777811619": "0x00924351a05100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397717afb4cf0ecca434bfcca278da5f87551279c65aedee91204f52a0b8ed90f6e": "0x00501213dfb68a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397227a6b116464a185c498499029f8d851499d3b883be8d403d9399ea7b17c374d": "0x009c7912141900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4cddc10595a991198075fde4703d2dc7becf3950ab6d2b0f5a3dab54f239d9442": "0x0016354fe4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979d1c1a61a2408fe24fae05fdb25c00e7ae53e442bec7c96ed693f9e9534cc340": "0x00ea941a6c4203000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42aa97e54a14a7b6a84c55e47e8f4970b5c76169bf04beac8fc818ae7419b6ba0": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339776f40a6b3f4538851c78651b93c8a96b3c242ca78051192c5636a6feb807469c": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978562e0da858978ac6d49943e27f21ae6866bf3f5f6fc488106db56dbdf4bbf35": "0x002c419ebb1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f245671593038f17ef021fc0e8909496b16ffbe361a0af2aac2453b103d0f97": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733c4797d24b7ecf0b8f12f319de1839573cff3b63a8130a010e4ba006449bf04": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397426b30e0f76372a8cdd1ad6ac2409486d7845aac0d9dffeda2afca9dbf91810d": "0x00fc245ca98c01000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b448894d6372a562662f579e748137ada53cf9af152cf096f75a7bd11c66d39edf": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c3060476a9b2111747e61bed686527b0b49daf4ffdeb7cc3b26f2154f555886": "0x00f2b28b484f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397639ed7f0db118d3ac9c486c696f930f3e7b86c799f18856ce177865673ae73fd": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f4c5b0efb5814b6a4c5bde8f55d02d346b06fc9303b92237ef9eedaa1675999": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397febfdf5cf67c0ed4f842d52c6126b709759b94938b795f60a78ef72ac06a2571": "0x00d4f831fd0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5386010d56c10c800f1ecd7e9e6a7102ca29a7781fa48d57b283423faeec0cf": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e9197cc5385d2a7d208f6f072d331694bf71695f25c8c51957f5fe8ed10aaa1": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f1e128e20293d5be87a997590722d05e36c973d0f3d42d5b381a49c12e771b9": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339712c938b560bcbcabe986dbc62dd9427d0ab68f02bb8405693a440d8e2627071a": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b45b33b87577e59a8af9bc1874c186c434c198c99eb9b1c7825c60c03dbce44d03": "0x0052007fef2000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397866eb329c7ad9b82e32ae194f189b3f4f57150c92450b1b29cb115a351c03ff4": "0x005857a4df5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783b7e2f438a07521e4c5f2000d280826dcc28298fb7c94d7c701f92c4751a17b": "0x00aecaf4c90900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b413e365c07f536bd495699d5fa01b88a87abcd9c14858ac0505b6fbfbbb014ad4": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397108b37e4384cd14cd968ee5cd93c086a6a00fc7f357e08b449cfb2d9115e6ea5": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971176da955cb06b865595188edcf6193af40e94cb71c513941fd402e2ad72e929": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f764703dfb50926940cace2a03e83337dbb20e995e6fbed50e46f95070000206": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979648f1821d2fd979f89b593a79484800ad94123a615fff3f4bfb8ed70452745f": "0x0018ee47a4d000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4772fa0067fd20a4d50ecdbe5cc044b29cb7c4b3e2d11f164dc35004745065a2d": "0x008c49524d4e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972235911f45798580a59cba9c03e164f901aa5c378ca1a0c8b037a0362374a27c": "0x00b2a1b3670900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397421d38d5284384d89d3a99c8a4461f1126bf1ce732f66aada7f1b0b63105b807": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397500538083cb37be8862a75ed26766d4af25afc2ca787030913cf2d3d3d20a53e": "0x001428b7820700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44da07fc8dc296160ffa40d3f242f07ba2276c5bdad5e32bb53eea5331f6da71d": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397db46df6dd2b1624b1ff679f7775b39359e29576237ca68619b2f6c97423e53a3": "0x0082db3cb70201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a96cd9bfae53f87d72d7b557f6e6680e8cc832e567e76c65e0514e04984ae4ab": "0x006e1a13482600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d899901267f714a73583f0c25a330d9c29f39fc52dcdf1a0fd3b99b2f551df0f": "0x003036d4980900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b47f3125d79a9d786a74b6127e78cb7acb4a0fd66b852f8529effa9292702b5a44": "0x00d83b74c6278e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339795c15216e17b73ed35c2c33e84f27ac4213dc8ec85f6883d1362f260a1e6228a": "0x00bcb9c7361300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339711d912f1762fdd2d46128163719ad496bfa87b710ee665047512afa398095ed3": "0x0000851ec43c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cba3da1ff5d810d7a4542971b718250075c9d80a0c99da521f67a9be8ba569b7": "0x0042c4f58ce202000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8c3969a697a0c6e9c5d53f929b0f8bf7f13a3b1bd1c6cf64e6c57e57b48e587": "0x00feb8bf501000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b408e0a2f0e999ae82dcb4bdc8bdf0dbfdc18baf86cd78e39ca7ca41c7c8dbfc61": "0x0080e4f642df9f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ddb3c5d359ebcf1515596d11301b799bb0fbd392ef979ab7073a15d83a540490": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970daabd8e7c312eb2cf69a03e369eb420d7cdd0b18818c01fc86179dd9860d8c4": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d9e619998b7ec591d0761ad5061a5a1d4986e9f056a06ba178b93c49fb5f2f6": "0x0020034cf68f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ea51d7e051c8e1287462a7a7d55d4448a91f1177883a9000c1522d539f8a04df": "0x00a498397d3900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b45d95ae0f820b84bf2b6c4ac95685f78393d707ef54cf3fc4e3585775c0b34f12": "0x00aabbe1098600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975afd16603ad97043b66e6033920eaf4b880e726e39da35c1744f9cf7be31afef": "0x00ba51b4360400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397434a2992a0d92f68bedd7a5142667143e340639f4f690f5b670df91373a9e129": "0x00c8d6688da80d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f103888af604cfafcea9a17af4d9df64dfdf1f0a9f2f20a8139ac29af6576838": "0x0082357a0a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dc30cba8b295536c2554544f29312d5b858c35ec18f970487d9d258264f1b9e2": "0x004ce4f43b5701000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a19d0092c90362f0a4f62720881075eee1e81a6f761d4be0ab29a033eced628b": "0x00624c25681301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f07666c81682825accb067387566e724e9fe975bb28ded8a9137f2bd413b9f7c": "0x00821289f30200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a683ab999fec58267f7bf49f12794ea3c742abd10e57f7e0ad256f644c1f162e": "0x002e50c0ad4000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c1f22ba011263fda839413156b1e680c2556eb6605ea1849500902ae99a8df8": "0x00f6a94eadf207000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339745e0424cdd78296f3ef48797649c48198490a488c32d27ea44099de7a07da22f": "0x00cccfe07f1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339725ce4a928fc966013f7699d025b79b833633b85855ca42cc1e8e3ef52624ddcd": "0x00c4c57af23000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975fa2309ced309b3af16d0246e7c5de58c5174043a260921fccbbb6c24b805ed6": "0x0044698ead0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c13d5c898acb588e078e2c1c80dba9296d3d96a327202eca92d848db1fd8d9c0": "0x00202e585d3783000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722d6a74ef49f4b4711eabefb1115e7fb951e144a359d25bd79f5f64c8e905742": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972590289eeb3c88cf1dfc8cb8a9dcfd385da536c6db392600ca8fba91f570d497": "0x0064c20ad33200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b49fad2b236555bee4ec3762607ad35cdb9c76c716f1676ecf2e6b6a94dec43fc5": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b427fa9f6801533bdb37786269822a30f2f6742d63ae8608bc88c36b544f240f": "0x007e2232bb2b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979dbcd39162909d444c28848f1a5e802b980145f337a6aefd324370cdd72d34b0": "0x008c0e73b14a00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43a0e8e3225158ce414cc323b4eaa3d2dde89570604099616ecd689fb6d57823b": "0x007435ce717406000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b564d4b927402864fab5315fc8ef61ea956483324d243c5680e00d3751fbabf0": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6298163e66282d0611dd6d9e48572197dfc1457c22241694bd7382adf5b86e9": "0x008a8883a42400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397508d1effcd45a0f8e62a535994c67ac943aead88e29d8215497524d0fbc5c45e": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339703ebfcf3c31440d6e99ef997a77c74d15eed5b952412e7d1662a7fcb09665ef4": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bebf967bc0449865d5cc79138df958269117ae73711fcf4b82a3fb617d7504f5": "0x0082db3cb70201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d56382789ff9ce1a16b02c86a6372376c8624dc7330da9421971fa13cec20180": "0x00a652dc520a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d83afcc9dc879bf0f150ac668b109156410ca5247021d79d52d2ef41bf406676": "0x00027454dd4d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397897599f055eebbd5737fd02546d72462e33dc80246e33896773b08b251ecedc2": "0x00b0b673f88506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fd8fe58bf01f2104925904d0b436653db9397e554cd7e8fc2aabb82bdf457c26": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b9f0b9e55ea0a33cad4782f2626c49083a975ccb70f8d5b8be7fec6c39ce8af2": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c19ba4e2bc2d5297e6ee46ba07e7a58c153f3a1a8575c608ebfba85383ab64b8": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771e313362196326d1f5334260181711be30fec01cf0aa3d774726385fafa6adb": "0x00381c3a2c0400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b455e2558fd31719c32d9b7e47433d3c082cac7d95655c9cd09867ea761b364318": "0x0066c2f4a31b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a59fbb53612de1e425524421347c598d18b99cd59721e05a98f272eebf110c5": "0x004686d9dd8f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c16a7d825aa576dfc91e29f17e52d3feeea0a4f68d8ef0336862519e9ca98a5": "0x005806d2931003000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339762c5e9f2d9b4d757118c53d16b8f07712f990a142be067421a2c3a3a7a9bccb4": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339719b938720a076abd5cc42e52c2422a5cedc2e46265a66b5e795bdf13b7a7ea9f": "0x002087c009c91f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971917e483033d42614e9988031bcf828b70d55c322f4a0df4dfeeff297a918977": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a6d88b78d20bc1a1e9d230f504a562d78f3be5662bc2d775966f4c5e0a37169": "0x0014ee15324c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d583514a0a450024ba0a733b20d10c8c32ce873e1711035a9855531c5bda60f": "0x00cc2ca24f2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771c0e2245195863c1d6f865040f10c009d4830143d8ded5a77e5ffa6cc90b00b": "0x0066506bfb6400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397961561f098d3969baf0b6222a460427d7d8c619591bd013f52c4538d7ef15583": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397872d277064d4f7062c2681f252dedbdf12af71ce460d065afb202bab5a31cda4": "0x00983e953b0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751d16b8a40d502f540b4f02308ec7f9257fbf84a1bed217f36c5e2cf834d8c27": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970de1057c6493ae6db942b46e73749ad90ea0b570a541ace3502cf66969a33e34": "0x008642033a1d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975e08257fa3107900ffebed384a96fe974474950b5333af48c82918c01c380b40": "0x004c2862d02b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4a0bee3f5ade097026e9e4b06764308a11f1dced413a52ea89c0a23ae837db0": "0x00d68c1be02800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976fd854c03d2996bc858662c545040bb1ba8630ae17af4adc8d5cce0666035c72": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977cdfb7880488182ad2e37aff1b4767b4a6f1109f7dd17dca2b37c624b64eb886": "0x00021044ae9920000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b65797335118964bc0b74ff811f3c9b8f003b2ab9e551723f2c6931cbd6f693936af536": "0xfcdeb580add093f3b5f06603032c2fe89d329ba372147c100aa0391a44a51601", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a33b746521869fa2c643ae9b5f73cc1b131fcf48b807434e4717be91ec883df": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e0c358174661342532fe36d1085c818b1475f2038de0defbfeb332b3802705a": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397299fb5825beb3e6de0ec4c57b098a75e06fff854e6af8b652f38eb28b4c40423": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bcb2eae4736b364661bf5bbddc6147c6d95925da32f20a0f293fb9e4525ae05d": "0x00be80bacc1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d4aa6be12e462777b2f571f0e80856c8c5df0c5262d65f7b7bb2e6d9619b3b23": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339742e2f5fb65eef4f6b8ea91379266a743cfb5429eab3871b081a002a233d2e77e": "0x00e69d55840b00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46f915bdae6812f5bc2f014b440927744eb5db391eaff16ab3f7d3967f0a6f84c": "0x00b4d0d53e1bd8090000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397724b4775cb0f8ca4e89c46d1c966ad25e187b58f567831757c91334e3bbb0e25": "0x0002aef52d0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397200d299014751cc5a0e7b5e35a60aa14ad69558ce12f1ef9759be2e9f862d2ca": "0x000620e7ad0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff05ab3378684482db7025a7bc9b1f4545404c2be51333a98026a5145526f621": "0x008290b149ab00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339706405f7852d979a3e3ecea4dcaa0725aa30cf838a7f6121b16edd45149985a22": "0x008a53f75d4f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d20c54416ced819488a1208e0c78ec28084e2643819d135b7c793e9fc915816": "0x00aa3d8fc55b03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ecb888886708f641c8d7fd7cf92764490417e1b2b7046d22a7934de4b41364f": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b29fbc1b44d38ab089a62692ea1bd24c347be4e60a043df8adc6f99abb2f069": "0x00963016623e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a42b452f211bdabbb7db7f86c7cea207a20d5fc516177aadbd05b5da141ae951": "0x00a2092f3f3600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcdd4f7ae648d633afcc28efe00b7898f3bda3e5579cdb80b44b0b54e6cabb5d": "0x009e0aa0e51700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339757e3fe3c6a1d62569addd3cfc5463b7041cddb43b3653823ac16946edf058a61": "0x005c63e2a2d02b000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ffdc0d411b62aed4d7c4bfbcb8df724711de6549a4b5fa16676ab7ff04ef8dd0": "0x00a678b08f4c2c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c245b66d703f2b1225e44fbfc618baa480d8a43eaa08023564dad0a96cf1e93": "0x00cc6bc2f1bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971d0c761fbbf3c7dcda2eecb5d342c45f2b729cac82d26127116d9f3c55c2a631": "0x00d87b79642800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c770e86703a885beeb557841b02659f06eb83f1ad5655c5f69e1839e624fa01": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a012bfc2a1f7bcde36a77d1dbb42fdfef2b53665b757fb53213825a3d3d20c0": "0x008826bcfcd800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b4088e3e0ff06fee410b63e0497dc2dc9b2c10202b61778b2160668f654e0255": "0x0028dc32610300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a6c32e455b47ab55ad658c6755c9a66cd5c330592f3baaf99b1cf52494dd19a": "0x004eb3011a1a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978c1a663b1d9d30a7dba134dbf929b3293367528f9d731270e5bd8e24d850ddf2": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6ae3b4084b6e1a7c097b3ae0afda8bd96d8b4b1109fa370803e73c5bc51a46a": "0x0026da6a887d25000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339795d8d18d4ebb5acb5af32a125bc0c626c8ff0e70bd4380d5a25464fd0a380a07": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339780aae7cbb783e2950f843c7ebb23c01ed1d434c54a3b5999336097df4e137ace": "0x00f64ec09aff05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3df99e4d729ed410d5ca144e11797f6cc36085b150a0098475bf4d28c72bd50": "0x005a9010a19f05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775602a52292cd4a88cabf22fd2ebc60a13aa82b92525058bdfe4bd57b4e3d4c1": "0x0010a539b61e00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40def09fdffb7bd58bb75d518d2249595980d1cc1bf2dc93d937c237869a8f1f0": "0x0040b10baf682c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d99a5e08c57b25fa89cddae38bf2dad37a4c9baf300efc33188358fe867ecb0": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397834c2b2ec3b9f76fb03505be6a21e1193c22b66d6371594db758a02d7b8b1847": "0x0062b3e8e00200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af9466fbca6083d24d2ddca158e6431f98712684fe1eea149e7b478785c51241": "0x006e003d620600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d3f0efb9526693fca1aa158206283aa23cd5e3a9a5a9137684ae2ca3eab2f469": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339735fe1f52cada1327b5977d79129c41fafc67c0b4f03128516a94bbf7c0934bfc": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974eb0ad2510fda4d5acf95107c044a1512b3500d62f8639af7263fca42ae72343": "0x00fcc39bafee00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397422157e06516af436d924df4335804ec1d27f2a4be1351cf0f283ed1d28382b2": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f56c072b9601f6474376bb2fa7d069a73839eff2b828d6ed2738019420f1f1fa": "0x00e268b13cca01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ce1e3bba4208d14b99cab63e2fb59b975ea7471bea1947379c0814cc4901edb": "0x00d8c00f4d0401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339717ede621b954cd363b6efc566f39c72b92de304ca91727ddfe119c34066a6798": "0x0056b961800900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc9b98baa192c06a1d3bfd5b0c79235d4fafa1d7eef4716a6744edcf627fc143": "0x009c09dd960400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a09451604ea12cd471a39f60257573f5f4ffa6f273021a7097951afe2140c93c": "0x00488c227be903000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c8ea524772655e74bffc6d96e5cdeeb08294a54d7b72b3076ae021fc3c0b211": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708c4042efa14e97432ae022e1e2a62e53051c6440343fa09951fc203ccaffd9d": "0x00546f2390a600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282431c79538fb87a09de261557bc1de0720c0fe3295b4dcaa78611f93b02c14188c5": "0x00d8444f0a5c0f0000000000000000006eb4119500000000000000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b406ba815c9300a73243387d1b3fe34a06ce69f40eb9895cc9d84550d5231cc2f0": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397755df9876ceae619116dee0295a591b24b35afa9c32e96e24503cbe6423d8de3": "0x001869bd150b00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b484bd7850ea1697b3e6b23313ecd627d2c118ae27b2f097c5fc0aa0c89b959b99": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c3e8f05766bd3534c5eb9ffe2f58814b4d8ce934a47fb43f004a4dd5da56ca95": "0x007a4984bfa700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4916c8a2802d08646f0782eed3a2fbe48dbdcaa5034109b4508cd0aa3dd0be3bd": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f340ead02afaab48ece41b346dcef4839ee6dd93a928c9ff38d8ce25ac85d5a5": "0x0002422ba50900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e89095fe09e827b36fc5c42aabceaabbe811b82c42d4d6761a3e47e37e7e392": "0x0072a9f3d3810e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764b7d6b62be8a8e3918239da252e65bb7e58e1821493ad76edc75c974a88c00e": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a78e663b9eb01f617ede8259abeda27bb1b6fea46f7057c923c86a889dc31c6a": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5961c640f107432bf844d41d01122f0c656c961f7a3c97cd46e49c61fc6dbce": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb6dbf4ff0c1c9ac0d54dfc12ea08a968c57a6c7cf1270157b42d35083abe29f": "0x005ca0805b8100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397880117e5b3144c9c12de44772bb31b4141c8f6b9098e29b366e74e73fb5c3900": "0x00de8ad4c54700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a28c82312f6d4264f8985f53f1ce7b7d3c45ba4f89aa1f518e9e6472365478e7": "0x008281e2607615000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d779907a943bebd5a9e08b9272dc087e4f0afe8ab7f1fc0ae47c24901aec97e8": "0x008057d73a4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f05569786e5fb3dc0a1e0acfe131189d62b8d5fb13d8751e2602bc93bc886ef": "0x009cebca242900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f3e532bae77899f4e63611fe4450f6023b14b58f5515689c3990a2fea36b020": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978fe5993302c982a4881a7ce36a46fcabc65a9a7f010ef739ba0eae3856f95acd": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973fb631762c11a5aa79351d2f68407729dcf0edd19e25b0eb7dff0d501f4ac8ba": "0x00589ab7343401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397503b5bbbb7af869a375e0d8caadb874175500ab416e75022a2e2c1aadb82161d": "0x0016e332d60200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c63fea294c43a7464d7783e054abd2ec95d2b07f88add03b8f28d11e655583a": "0x00e0fe28a39500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed8a84e0dae2cf5cf65b76ee318156a0163215e104bf70cca256e3b8232329a8": "0x002c07fd6a5500000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46da6b80be6d834dc68a6f6e602a4f0cc138d02e204be5c63324c682830aefdc7": "0x00ca0a717d1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339726486acb7cec03f2fd1363046431e0ee5e67321e59c70b1da442a1c798ecb640": "0x0056cfcc711400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397183617620a8a81a3f067b3e0b40286f6b1469cb0624b5bb40cf55a91ecda5ecc": "0x009a2bd5f92900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ca384f50830d599ee1d8f4a89563efb0c6e4241c15fc0e18e3a7cef18ded22f": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746eaa5c38d861c3595630cb4d2f2112be1d47a6ead85f243042bafc1601eb2f3": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976cf451347b31cf8917bdc4b1bd2907e70b7832191bcdf59945519f4262171dcb": "0x00f80bcffe5f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397907eacfe7873180cdf6a592d30f060e84f4203ce1dd5bbff6d5267019df1ee1b": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ebba47714ef93b237f40cd412f7fb36d159385aa90500a1e226be4326d4d953e": "0x00989568830900000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579732ba78e376c1e9456b7043e088a67d3d41feb1f41d62efb7da2cdb033fdee1273": "0x7a977e950acc55770b4452fc418bd59fc4ccdc25ce3c2d4cce58dd0d6f9a2d15", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c7f40a01667845ef5505de076e96717c4991e04ec46deebea4a47ab6dbf06068": "0x00ac9de8d0ec00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a9348c60233a7389863decb1317fde3c46b7e5591ac10955619937f2f2045b4": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a2b5ff1813b997349643239ba091f0df38004b5fc04f7f197c55cb57634aaa40": "0x00561064306400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397179620c8869a47e32766b21802adfd4c41f2eee6d515ad4228f317513c26ba7a": "0x004035d6579e04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339703872bf78d4b2bc03bbd20636b0d8314371b1e7f51f6de2d3358cda087ef5543": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c1ecf814d7ed85132287696190409b56d3be1b63d68fc4385bb02d60f9ae898": "0x00f2eaa9050f00000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973183906509419142d8592867b72c5ab8f7312f8c4c1ae70bcb63f65c66d229067": "0x5e3ed914a3f9da416f69613d98c0848a6435ca4bda8d00af53a8a5bf5898b904", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c60bba29338895d317737d41acaa2f8dbc417d3a7736947c3c7c4ec654704371": "0x007ebb5c423f0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732393de39df24ea7a451804b2873218d094d1ef5f85b9f218e0edca81caacfa0": "0x003278ff3d1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6378df905190e9f0a2fc3ee36d533ef977b47f9fffc16de4f613bb2ca994bd5": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397523827c4fa654843bd041ffff2a7a7fda9883b80ce7a9791c95044bb807f8ca6": "0x004294060f2800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a22965efee839778562380130b6b085b9988ca8213d79b9640409b6c9406ac76": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397641407de13cf4a4cb83e2164277ad1c51fcb6568a4d06b62eade8b142725dc09": "0x00d26a9b6f0d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b7de906218a695ee0bc383d1a6bc2838645c8fa81b16b880973edb777d5b480": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974299565ded82c007ea54f76a9a3221d29c64cb2abae8ab06404a1bd2e5cabb31": "0x00a6c8b2dd6324000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702391e7ec5197da0499c1933d9fbb9bcc7127f511ae147e471f230fce9cb47c3": "0x00825973078100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a85f09b6c234545b83364f3d6b620edbb437f8e5f1b6791fd5880a999fa2283": "0x00c42f04c43b03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971518fad4c96c3b46faabae6e3a2a2ea63bf7b679251ff6d132a826af0e66e1e5": "0x0042b095ed0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397207be858bdb6d309112f6e91fe519fd156b7870dfdc6be9f7bd7789892d7dded": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd8ff63a38c383b3bde3fde04c38cfbee26e9bb15ba273f53b3faa4bdfe46491": "0x00301a45ba2900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40f26918b0854f04dabe7c1bae603239428271c27522d4e55e2aba82599d1d087": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971bc024f46cbfbe2fc45e21d4daedd5837fdbd4b3545e8103c02b7356fc4e3165": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732f435da0b19b53f92fd06990f205931ee08b15eca6594bb0c13ee45bde9ac35": "0x0082db3cb70201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8def41eb803a5a44e83edbb7d6661ab823c303cd010969e6efee90c2256365a": "0x0074d126b13700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976455a0a6cbb75398b15c8e3a0685d0077d244f6adb18aaa4f5f894b5ee5a240a": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979aeb338b33ca6a954e6b434bf434d18edc46fc663c121211adc448e398260b25": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339739008ebc3063ec10762cddd4aa8144ac2fdcb66da78f2d9a6ba4c29a4c92da08": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f24119ef82706287d0001a2b51706c1fa79629559c1d10dc72b9e3eaa0f562f": "0x00a2c66bc03201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c22f35cc35918359e423a1935a7206e9ab048bac95cd17c2431a7f1fc0fcf012": "0x006c2932302b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397194fa58714627bfd202ebce582a72da0efed92aa30312c786b824309b82ad1b2": "0x008c61cb87cd05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976604107400ab041ecc2ec9710a2f04df50a2930934c40ce0d01815d74cf39124": "0x00fa5354f60200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a5c93417bc165c2b1748cde6fcf24180f9c9d18a8e350848926972d363bb36b2": "0x0004f52ee08d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700543bf7ad0424db185c2389ead1b6f3e2e7cc842d712c81db865e1a581cf49e": "0x0098550f100200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977de43ea037928d0cee57886251d4931d265048cc75a892f82134a00541ac1149": "0x008a74cb221f0d000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4936e4507f99679591ec362ca897451ddbee048e9dae9a1ab2c8fb5fcc6285cdd": "0x0082377cd53497000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979cf2eb6693ccaf037f9d9c85133a4021e15467c986184166df99cb73827f2a92": "0x00781154c61000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718845487bca8615945d6c3ff8600aaa51a4a7f254cabfe85ee80633408bff809": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fec2e1988911026db9b4bff937ac3ab147ec2252cf075ddd3d401839dc78b6b6": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb3ddb59d94ea25227c10471d5c8ebb9a11de052ca406c2aa2ce2bf4abb5c813": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397853489fcbcb241615aa39334144911000c5507c882dc85e33bc9248795783d7e": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978452efc07ba666f734c5c0fd6d0f2caa1564802ebd596a3a63f2f701d8f7743e": "0x00769f7b7f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397020f078e6ae44c9d48e84e3a0fe962aabd2a3780c1b19315c26b8d4f4bb4d804": "0x00f8fd0a8e2500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d522c38a597c39d106152477ea1ee1d6f61e49b26f6b5ac776473035b5c699b": "0x00f4989f331800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977bbc88dad42dc48da43182dde48c754f28f3d43ffb28230fc5b32b5f33431624": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977e99b6b2cfe7b45559d7a356b6de637a79c7ae689d1f676c20d8c9e4bf191720": "0x002c419ebb1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3315caecbffd8825d5ca43cca46cd5a823b6cfef8849d3490003eeb6935e3c8": "0x001ab867e39b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be22bcbd70e515fb8d71608f41680b267555cc0ac48cb2973429e558d9fd60e8": "0x007a29e1bffa01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397238162387e9491275d053c6e43c7b4fd416c087bd0ba8563c90081fd6f5b1a30": "0x002291b31b2d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978088a1f656514debbdcbcc860e3db1d1ff1b3029433bcad792a23d6a5e53cb51": "0x00922e5a5f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f4cff9b551942bdf9ffc891e9e978c86f859419c60a248a1b8e164dabb575ba": "0x00c0433b719000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bbcdc0369cd3ed007fb2f2a543cdb7a60635a6ec6c9082f9b5d4965a96670069": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397050954c1d6fd46df31dc32f13aae0d8e32d2d6dc640325f4b5dede931c7ae6dc": "0x003e35893c2b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ce9986457f116bd675695a320d2c697991427b1fe6a8975b2d470bd11678cee": "0x006ce3e337a800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783834b50534ea5fcccd6a4d07ce83631f3ce342761ca5a2a5910bb3a977f8189": "0x004ec3481e5000000000000000000000", + "0x0b76934f4cc08dee01012d059e1b83ee5e0621c4869aa60c02be9adcc98a0d1d": "0x18ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc1677b46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723fd684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e17968195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e9411a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad820018168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da58009", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c087648deab60ca80650e1fcb01f84dfe803b60e86c2083e80bffb21f53e838a": "0x0040ee7affbf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6f2895b7f25df1559d6268c1bcac8368214ecb637ed1621c09bd5cd52d57581": "0x0094f4d8444500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f465a8fe3d06b4379a240b0dba2d39c2fa5c8745775fdfccb82b830369bfe9cb": "0x00c26f318a5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a825f0ba604c216f510fe4763a31f2b324e05a49b5e2c96f9761a165879fe254": "0x00dcefed772300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397306dc6345b8d278e22890cea0dee12f771bc75667d7dd9c34a86f56c78e802d2": "0x001afff3266700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976462e952e2d143574e5f1295e579029015532d2da97ccf2b756b37cd81573280": "0x005a3db8ca1c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b442aa0c4b6f204962b1a2de4c816d3a674b7d2204c0e642445200c4bc8adf1c21": "0x00fad415c00000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973d36bd7792fac4d7d3557538ef0b8d7db0156e45ebfdc08d9e11caea11b11eef": "0x008ee409331900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e80a5123480226790991d2902a2b533b19b27a3900adaab2668536dd99ef8e1d": "0x00acd53cf37000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b2162a42ad4c45ce6ef7981dc2dfa42fd0471bfe6a632f079fb5f2e56adf536": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b66fd6bea730162f0a2207c0815596233a25f320dec3b73fe50e287e884236cc": "0x00caf46a592700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282434f44dc8b1864565e9ad190a802b1f277b6993122c64acec1261edfabc62c52ff": "0x0044de250d9e8e00000000000000000021b1256805000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397030e6ece42707f476c14c58db85198d607f6796690bd375c5e7f0d2b8e32a5e9": "0x00ee4d20ee4100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971db77c51cb622144dc09cfec8ef44b85aa76d0de9ed6c5e2e36e379012c3535c": "0x00188d22dd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722950ec982428fcc3679ff788d3c5b80c11c73e6a6b74019230d6c3f5ab5c317": "0x00741c17ecac00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da902f5c830919f8a01c6273af301e28b7f901bcf0b5961711b8dad47cfc1c04": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab4bbd20fa180a536bd5a7a67b6db9d8854cc2a7cc5b9eadcd2285d6c9038b21": "0x0044135e7e6c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b45404ad9ddc3750950a52cdf070b7267133c63d61bdcd1b961376dfe6edcd9261": "0x00c012390ac006000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a868058bdf02b477f9ea4b522bf0af37b81192211dfe597c84b4ea83b1ef8db9": "0x0040f09bbce108000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ea273a228b6632ce20e15109dbe441d6c6683684f49908ca3131ed9e44a5c53": "0x009868ab21f695000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c3274b1ccf41f4ec3624cffa3ea982040eee1d92da8a340924ee24e4bc61b28c": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8ae463789a5a2fb47507650fec113650d61d16aa8ed5364437cc169f0ccc131": "0x0074bccaa21b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4a27b267b4d6ad387c5e68d2724c75f30291e5ef041faa78c9b0b08fa287fd1": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339784128dd15e08106dd2eadfa148d25ed3be073348c93f2dd8ccdf2b3118032a8d": "0x00accd72818903000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397edc14f2f8272e8d61c7516e26dcc7b728a47a013b9bdcdbb79b20d7eb79d4a6b": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397424266ff6b9ae0792521383dee453d6babaed959fe2d611c97f9801a5b4029ab": "0x00882070a41500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6dd2f98a94a2fad0b5c775e08872578182b834896fa294c11fcf6aa6ec99714": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976321b76477cad18e7207280a406b4b2f50ebd401a603a025e6378708ec423b0c": "0x0032b7ae9b4900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775ada81be6104985afccaf6c02fb8b541dab0066c5ada670689af351c94e80f7": "0x007e58bfea1901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c918f001c509f275fc20f06f992d93e14731e88512bd4151721725db7228293": "0x0094487fe37900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768f42e6ae54d00204cb5060847f005094069fe74be9e244189a5bedbe7a9c0fc": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f8caf86aea4d423284fe83db587e3685bfa905bcd3f9f28694ffc07d1cc4eb5": "0x00e6a893f59d03000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b404dbe1bffd8027f5a610d588fb690bba39908b44ee46a442c327ef31f564ffd5": "0x001ab8ccb0b900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397adae7a36653a5c87cf76066d97f8e865690756d3494a804adaad0d01c506ebef": "0x00742daa350100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339797089b1c5287f7eea7c44382f7fc99da2fc327d6bf633806da3c65d442dd343e": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f763f6d0a3438661e691088370b128800f1552f359920861204d6a86b4c7b8e8": "0x0084449cfc2f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d61b3433df816e1cecfe5daf8de881cbdcddf1237abcbb8969cd80876dfa7b32": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339763d2c2c95dd5b492bd07940539453ee4a3e3bd822aec5a64c9ef061c2f534268": "0x005880abe94f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705dd4f34750067d249b93466e286182b6b366e560e6a7c8f5c865e0045d8d978": "0x006897a4ade900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40f3680842fb9c71c70445d3feefe83aeb1a4afbeb306b044c567f3530d675696": "0x00567189f71f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339789b48deea271d529de53bf46dea8bc837450f5632d67dd39bba8d50afdd74ce5": "0x00222837aa7d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775700dd48659b98fdd589977f8d9acc50799f04ffed9113736456f20139037f3": "0x0060a23c5e6c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4761b1664223fd9279f8e80e68d7145f61f8a9c122e8d9e94938d5d8a2a5e779f": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da6324513d4e3e6e59163e667d296259e38e9d27044ff98804827acb58072cbd": "0x00bc7a47413600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339716516f1030a95f0867576a566de5217ff20ba068127d60f1b641b3933ff53409": "0x001e10ef470400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcbe565165b1d67d3270b0bf7765fbc774c81017a68a8a1a2e18dc760a0c921f": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973531b1c7cefea791cbfb79e7fc4b763e5fdee9bf173bf395bc4cf92956d419f7": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973d5f1dd88d38b3361a16e406f6ed53c27c59389b02b7e53884e6a6a8338a2b92": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd256be2c93c38d729316d969e7dc57b7c900d2e53deb8382ca4a4631652d7ab": "0x00e681c6a52b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974bd19497b354d5f9dae50977a5a6550c4e3d84e7cfe62c16b2d2a66302c3adad": "0x00dedce2d93f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397272603ea7c7363ded58ffac06729dc831275b48bfb8fbbf74da6cb54e92de15d": "0x0050ecc22b1a0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397424ddb4862ed9b83f503921962cbbba7a0799b97a463327aaf7d5bd35a71f737": "0x0060b7986c8800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397793b551c18be49a121097647d5fc45fd7f8418c1d276ec2e48ba2ed9b4b6b6e6": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c8b814605210501b949f726001d5dde1cc6265d3a683bda265f88bbd139e65a": "0x005cbc0f3a6100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b462d09e2075f7b6a537241d823c07167506f092644d9c024de1827924a071737a": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b1105a281e4ceb5fd3e95da93a1047afaf2e0d5658f59e7b5be6e9c80e6cebd1": "0x00f077f8402700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a293379316d6213f5618787a77078510e4d520937f492b4995895934d27ea081": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397222cd0cd6c19c586541d9943f147dbb0e831bdb59682890667cd40abc634cbba": "0x00ceaeb81a1e05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397130ff39f4077954896b4fe7fd5141b0c3c3a0d9778d3d88dfa70a317c655e5fb": "0x0058909b1a3e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738708bbbb09a60647db7902cdac994ed953e6e7f3a28776ed4634f97ec403013": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f9c6b579a8e7a00b115cd28c040f89047a527163bc79d2122b1336d99d6c6f0": "0x0032468a9ae612000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339729f728e846a0def519b51b82354f559246eadb8a932c308b88b3348b0f674f79": "0x0082357a0a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f987623db85c4adf7fe5314db1258e6040270fbb69fe234b9d636312c3b941fa": "0x0040b10baf682c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720f77a0c108d502bad945f180e997f8b04ed46e38edf12aaadfb3ddff5ca8405": "0x00c07ed6adf901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d957bb94e51666fbf9f3f6c1240ceafd4e914b68660818afef6d57507af80ebf": "0x006aedf4123200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d5d472fbb9f5e37f1479727ed7691992ba96e9a0b78d73a97872232e092b203d": "0x00b218f2c65f03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e879e48aa44c2450501a5c6f1a541b05d1424fbc68c67cb928d9bf4767cd244d": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973aa5ac1800e48f7996aff4f226ad6d36c9042947d4b7f336cfadb6056b9b14be": "0x0048513e650e00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4979c33208a02b086e463ef599fc696f1886a9ff283d5f0926dc2a49010125958": "0x00d266874e4001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3459aca41c27baa72e6f4fca0a9152240a0435b51482c24836357abf72a7932": "0x00be5b46221900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4470a7b7187188c331da21004a160921a2593f98478f4b34fb47940b2d478dde0": "0x00ae518f24d701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397177e8565eda5dfe7dca69128e120aa3125e7c97424f78b3bfd301d13f6531c72": "0x001ad45b8f9900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e39a8d9c7f2bd8c63866f621773a475cadf3d1975619f60570482e1a5589cc15": "0x00e6e02b77bc01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9d9f3bb08c927fc1f054ce859808237e9eae9807eb964f2d7e84b642a7643bb": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397274759a016bc590028d816ad6eb8cd73d888ec25b7513216d8e08e8a84db0059": "0x008c2a02902a00000000000000000000", + "0x1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d": "0x18ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc16770100000000000000b46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723f0100000000000000d684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e179010000000000000068195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e94101000000000000001a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad8200010000000000000018168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da580090100000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972bc90c4181962b9899e66aea90dd4af4126803d7431c1929b47b6bdabf49cf3b": "0x003899e7d43401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978642b1a8e1a11ec5747638fc17e1c8b2522e6b05625de840ce4b9a6dbe36408f": "0x0004f52ee08d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339759c75899426e8a334e7ee59029f42e9ec14468208f8b3ffe8fa5ee6df47b43ca": "0x0066fa41c93400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748646d93f9367d96dbe5d389f48ebd635198762b2e4992976632999aab950012": "0x001cd6fe584200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f23fb260ab0c44cd98b98d2feb52ada9ebe6b842284df32957a1c443633c6dbb": "0x000ece41f8f002000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d75b16a890b50cc7e5d23e7b53b49684a99464dc85fb4ee851920f479cb3e2c2": "0x007c9718adde01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf0a94e0b5e0d6e404956fa4c1e4aa44cd6b508e4d42fd98579d6ad2b45bf99d": "0x004e246ee50b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ba38266cb9fbdb057fd063ba149d9ab8782bf61bfc4e8c583dbab628fb5ca78": "0x002cbcbad66f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a65f866af4b3dc68e1caf63d06672751ef4a9b1d10e684e1c7e09c40e51fb882": "0x00c0fd5f400100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d47eb02de7c9fa86d77dda417e4e34bdd123d50204af41cead50446a7c806e4": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e75122f016b7a5db930dabdea03aa68d2734d2fa47a0557e20d130cc1e044f8dc5796": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325a98791e0671f15c5ba005bff6c74d43e098ddf3b3833e3f7a84ae65f4e506b62d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455325088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324774a93bb520ede4583d8644a52f95a6ba72334bf12ee6efcbfa7e124cec184c1088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455324088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455323088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455322c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d98c7d7d9154bc0968d0e126589f90045bb7603264edeb8f7b619834e35669": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f7c26298fab2ecae47f88d6a0b27747a3cd0b3f1e616be552b77bb5e422f7974": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798283ad8ae55733346b1e3071ebf3efa8205ea3f9d720bfddb698f312d25a971": "0x002a9799bdbd01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f34970041ccea330f4f970218d59782a51916e43e13c4bf184985cc852f8da5": "0x00a4289f320700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339763d03b61a16e37aacbbc2a3f5fd9d736b33866b9e31e96276ed3f8decf42965c": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339770c6a5d83f7dbfc7128ad6d702b942c2bfb270ada0aafd35d81664cb3f473945": "0x00c0fd5f400100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397674102c6b57c5ccaa07fc87a0a5b7694c48c026c14bceb1471e04c111a782983": "0x00a6ffa0e4e304000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970dde7e16f305e914fe96bb793ac35ee3c59112757ea85bf2974961bc30427429": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5062884328f6fd8ef076ac53195db573fc643eb9af737fe34fe346a1942c6bd": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb0ae5f876298c6738a6f56a94e5af1a15186a56d03d2f3a97ac0cc38065a561": "0x00bab4638e2600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4079d0714c2f684a7840438773346ba658b81b123ac84ac71a31a8d1cae36dfd9": "0x005a4a3ef00e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9e85d006d43afb35adc52d3ce8e1f00d4131ab6dbfb93f54a565e7c12c2312c": "0x0014c1cb9e2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ac905a07f9f5dfcbe8e9976cf945837f5e4e0492e8926b73a3fedd35ac7a39a": "0x00060f4d674901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce47fffd13e737a75abc1e9e95546a23d0e8e378273b299225f093132f4ee820": "0x00263134770200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef80dfd45b17d275e85f8f9cdb39bf5efdc79efd0e26dcaad7bab1590842dc81": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971adcbe8bcfc151ac541e8e237ae64648cd8ccc9e6918c87814999d37fef5b2c8": "0x00e849c81e1900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44884f49cd86ab21cf91b76963c7ddc7fd6235eff0f18b1dfa73fea15e0d8b0a1": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c3d2aa1a555570080f7af0a2a319fb7ed4846e660a680a4d1d27408a55222f8": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773c821539e94383be780cbf3dbe7ae23e87911ee105469b3d02a92cb371e55c5": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973faa3b34758e4a863464a0bfe8fb35faedb5192e5691ef6736cd6f8d5d63d9eb": "0x00c8bab0cf2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f81e3802ce8f30af05071a3b7ea06d9608a66cfe5b94139a12de15e9d30daa3f": "0x0062ebffa05700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b0e678279dfaccb1bc44994a1e1a32fd065270f3b4d94b36c7eecc7fd44854c6": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ffbb1981c310825bc2daab524d54d7b45786dfd31b623548cef66d2a8a84eae": "0x007e58b8edae01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b38123220a96960ad44210b5c66df4aeb8ec917f3243a72672dd69b36b6541f3": "0x00ba96511c4b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c11bc60b3b0ff13f3a2e5e436fa27aefdaff03cef466f07440c440c754e60c35": "0x0084365685e34e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397898e1d0117a9af0b84c7732e6931a9b2c488c0afe1e84dbb4008cf9bde9f92c8": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978cf0c39463fe37f7de485d4a18e4a167a4187ef58173b05ef51f090cf6e64891": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed1b3c0b0f973b1c77434cc947272be5d932965007690b205c93f826cdec3f0a": "0x005c57d4f6aff3000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e43535e0de5aea3055fa93c81cefa7e5196031f5d0132bd4bf2e6661169a44b4": "0x00e45615d51b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c79eaaacf0483bad48cca0994af6d45f942ac6dfc7e02228d88db0f7d5a10bb": "0x0030ba393ebc13000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dfe57d263c5a897f2f145de77ced556587e39cf8e8c89d9fe8d8d11e53e4be87": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bbb919aa5ce5341293d001300337675c424423cdf34beb9ffa6e3a1ef05e44ac": "0x0080e702852509000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c5e4ac9c671fc6120dcc1712dfcd02e9624613b822a3d230c00c77742870457": "0x00e61c8dbda200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774a5adda14446f53f4725690a75339c475694b4f0db927a6b852a3858394c3ba": "0x0080fbbf800200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b430567146acc0d02b2edc61b2d9675df42c036bfcd4f19f37b8574fac38cb8613": "0x003c560def4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397418f8937c5e4b8c5a1041ec93d66a2d19f600a457c93d6b23406ecf5f7075bdb": "0x00f8b460847c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c5d05e0b245f1a74945a11c15f23730451bd4e2e94311dfae6af95c37c4d501b": "0x0082377cd53497000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973e57671f96561c20bed728a12ca7983054af7d67af145c3a3eef20696cba19873": "0x2280483e7614020101d7e03e0019d5d0c082ba9e23fc43a2a36b261bcfa5cc3b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef35f3996d4146a416a53107c6a7b895a29f3738362b1fd9840a36f515cb0efb": "0x000cf037d88207000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b97012e17b68bdfa5b4be393d0a06961012c7eb037832d2fa2ffe0e7d760b1d8": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c1c21ada81acb03fdefc85643f8d52d98c99cecef5957e729a478d9b5474969": "0x00406cde340405000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0013536ac1a6d304c749f9e08cec9e7035b9dd7d8393e69d182ff5d6939d534": "0x00a2ed9f605600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd264d278acf51adee8b20f0042b80ceb50e82bbbbababe403053eaf2e55573e": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a655be16fed87b606a5a814334acb070480a22d5430de98c31e0f09d7b4d972": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b05aff73d29021779c431b4597d9374bd45037432a560e2aefe15a37dde784bc": "0x00e898be808500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a0c02b506efc363a9bbf865b96fb063bc41082d5487d7eaa6a722ef437bbab6d": "0x0096af54984000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af6ff73cd7ed24f783df04b5933b08e230f8d5fef6d3f28df85f928c7c209d1a": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339735619ca4c15e0755eb7614f9eef5db573188b89633d59b2d42ab47634dc21400": "0x007804cea01e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d8b05286b98be9f1617ad3833c662c44141fb7805a466e517a125315b12e213": "0x007a0bb5dc0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f1c3e5c70f4c63ff793f72e929fc65ac72b5f72137843ceaf55e3f05e3b59a97": "0x00a234c7d60300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397040e335b566475573cd4e214c0130fadfdbb4c094299ada11467ee0009059ea8": "0x0096e772550000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40b945802f68263ab63b0fb6ff25406242fd4a55a43034a3e1e52128e5a4aaad7": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c41807be13e98af7c7864de498804c90761bbced99e7d7d2e8aa3d21c8b09d69": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397acfa13785c80ca097ef8231b66197db78014a5c66dd83bda0557dc173af96b51": "0x00667b03933200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b8563c4a9bd69a30a05fea770f36403ab7f8fbb1ba25be3949a6d48ee85a0ad": "0x00d098d4af7100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339715f55c1d1c905d044774f48c84250b6baef9494b64a61026dd546247053e0208": "0x00e229e1701000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778be5cf6e3b6f7b8b6c3c6c48303f014e0b2b5ef69cc26f9c98c0d6db2581ab4": "0x00a25665ab7701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978fa7814cbb4f9085a0e10e64f25c6bdf3da124526fd5fc2141740491c4b29d99": "0x003ac8acc61100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768560d67bcfb7195f2191908c588fcb83cc5efb6bfe2aeb4856a966cc5ce9407": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970df5b74ee94f0c77a5cb4a94fbde0a062ea0551f19e26488dbc61be11bf7a8fe": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f8d8e7afbac8178668193dfc2d66828ab65c7d230a8c2737b4cee38fcdf43fc": "0x00bcc1fbefef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e6281caea0e6354fc8b07db2664305fc6ac91673861f3aeaac870cdb7d10b28": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a16268719097d1fd6560a9fe5048a2442fd4b9019471bac2f637fcabc7e84bc1": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979fe4abccc722d42e89300d0cab428bcaad44b57821329e6798f1b8f6d3fca098": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970fb3fe32a414cbd055ea6305c1e0f0718a77ed9da1fd71913680d0428ac3721c": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339734cf23e98b9416f82261556b691c288aa237ed2b0cd0551ffc17e38dd42ae1e0": "0x0016ba87ad5b7b000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579734d84520c5f6e462647f3d5388a102b1de3f941fca61293e4cd003600d28cbce1": "0x5e3ed914a3f9da416f69613d98c0848a6435ca4bda8d00af53a8a5bf5898b904", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397de1b7af6fe7a96de4a9a6b0865221b512b7552674e5107809199f1aeb7f7248f": "0x0092013f348a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973b2b07830c108fb2b3e454309303fdc8ef29b38c7e68b648bdf74e7752a4be5e": "0x007ceafac42900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339753dbddd605d462c0717b81de57bf3fdce72f1111a2c5c432b3e933ad23c27a9b": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aed587de83312aa79cce387fddd99614491591ce9dd4a787a8272587ff9c30e8": "0x006ee223f3bf00000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397652ec0b736aafe307517e82799c99b2186c161b58fc20c4b7dcef58823dd9e89": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f5b58cd7fe936ed45964fe80cd9c08e15b8780f8b03fe94fb321b7ae7f4f0fed": "0x005a9010a19f05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397349c08d4c7fadfe6048844db576fe249bc018221dff26e01c4e225f0a45c2d53": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977808a738252c05729dafbeceebfaf2dae83b59c39d97f64a34d94b7c820a6137": "0x005c01a6223d01000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b47851e0af960f4ebfbaf56fb9610ddfbebd4a7ab8f17849cb14eb9c1bfd9e1c99": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a5174bd5e2b080ed43ddd953ef3e3bca1426a4ae21ce446af6fe51b2ce64ddf": "0x00b808f1f31800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397453d5ddc0e5dcd4b327c5cceefa4ada1c63ec7f1ac3261605dfde2d07d10269d": "0x008a39bcaa1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea9811684484f47266741cf2790ff7c6ea8c13ce652d01933d406e583411d52b": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a17149903eda930c9da714562735f4a4db52698d3b7481bf6ecab06e3183a56b": "0x007cac4553a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f001673538fd05d912880cdd45375e68462944cdaae863b48ad6a3ba491e45bd": "0x0030dc8f48a101000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46fe7d4bd079b8d02640b8c1b8342f336fa2ab2c5c0f2cf422538a36e54539b79": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976977435bbf2fc45cf545382a7a57275da74eff4289110d856f4664f29ed72d83": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740a6e4aa183d2e1d8bd8fa217a224def3f0c768fab5e4c945e0d73290a3eef7e": "0x0058823c772100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f15f46c1dfbeeb8af5ec6cb975d4dab6a5115a1d88f323c11766a7d3c50ce90": "0x00bc082a630800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b8d8aac0e9e29bd665123c20d8534806e8fee0dcbc3605a2759bed79a7671ced": "0x00a225b720ab00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e329cdb64032cb6dc2ab70b90983faf6b97e92081ed355aab47556af46bfb83b": "0x00b0f6194b2600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b81a0ca87fb2bb1f64c5e731ec6b9b60f6694a0c343c9e5551fce399f3302dd2": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397175ca22cc5da19cd4215bad6f6db3e0ddf586b7624cac2d6d0eaa91854cc9467": "0x00868bdcab1f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339719b0a0eac2dce2c4a7a3912dd5896c575fa3ef9b3a048237fb024ffb0ac2747a": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978991a0c896ecdceb517ebe69c883a427e1a5c888a27ca8bb0fbb40d932e3daf2": "0x00e08b22cad305000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397819b66781296d974f2dcc0c9933cf7cec1e37fd909d2e882d9183b8f2b672991": "0x0066497f817f07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb83c2bd7b294c3edefb2279eb9851106450613a57398a3078decb8150ef4822": "0x0036270f8e7701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ef31ee8597f399d5a36ecb4b574cb6073a58866367caaeec7d3ba1883068680": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5af82d89e99368f42af2be2556d6be9770398fa6071a9dc3bbec4946fbdd43d": "0x0066497f817f07000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b436e16459dd6eedce16ace5639e4ab6c4d950258e15da15abc7c502327a6df140": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397050e88676062a80ad5b4c942fee2b574cdb8bba9592dc8bb95a674dd62f51a41": "0x0006ae27a08d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8bf689b609bfad48c8f209c2b1f63e0e58401be01a23ac1077f123f9481c8b4": "0x0066f52cbf4e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e984abe0c4e739ea2a0874cf1c2bb901125c7e52074f04d9fe99b35a2e672d81": "0x00f0ab75a40d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcf41024de3e725e9d161c26ab3e76e066180d19bd005533ad2b2cbe66b5a856": "0x00b2f58f6b0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b586e2ae814bc567c7319d7978b848c1f86a57d3ed9757fc45ce08e1f446965": "0x0022afc58d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4be358cae5ba6ae477079c3bc56fc328444ec11b40c6ba8dcbdf1da830647ac": "0x00cc3bab081700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ecfb69f2716116ffde0e65df373b4b09b9523f70d32c5a687a2ac82f3be99165": "0x0028c0a3822300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ae0c02c5b43fd3abdce03101c17d0f8ee8ada6c267932bb707c4c8806e584a6": "0x00feb8bf501000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339739667819c1e07be2b943d4099c979d6fc4fa03e4afa2e731bb750d537f21b182": "0x0014e8e34aa101000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44a4e9939a0e0bc87130bf4b9359152ef2ca87f124c9d55d14557b82c7d174ad8": "0x00e4b0a9fb6000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339724c1aa5e7f15e86bf805298d7d72a2a3259d48f4c5a88a61faf9a7082a918853": "0x00d098d4af7100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975bfdb86218d23d688058aad9b949c2a6e5a4a19202c34375b1ce300ffebd91fc": "0x00487ddee25f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708788bb94ab56198ccc705fdbb0919ced65f60ce39be72e56bad07b7a4065a6d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b89b100cd020b0223397b50b763ab55e0b034b0d2bfa1690b8a8ea4b7fdba454": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ffe70841acc191a543beab570c9535a256c41fb8ac02ebdb8eece36fa976df6a": "0x0066172ede4c06000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f25c55d03fad7d5d2daa2bfc7079089cb6587d8edcd1b6d8679919e9d8e67ef5": "0x0076022bd77500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f70be6113be881cd1139c47bbb3e408d78e197350666884853f2d36b6997f7a9": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397017aeb0e9f9bf86230e0e6884f3ccf3b61ec947229ea0c7d4dcba8c09be783db": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d94e253bc788d6645ce218bb3d79145351104af600958a2e485b84d76bf53e63": "0x00ec759f88c604000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579734a4663ff9c8628e451d504f5b57149cae11d0d022c15a156067b42c34c3f31ac": "0x3a2b5aa8ffd4e3c5ccb11d342867d964414dd36e138de466f5fa6d865f19d665", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b32e8170aed1a558ee0c1d65acc2a9dfab677a2c54ab9f353be892e5798f0d05": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a968c70c6ae0548c4ceb6ec7e8e99c5faab3058034d84ef219dc8bc78b8a61a5": "0x0076585b061100000000000000000000", + "0xf2794c22e353e9a839f12faab03a911bbdcb0c5143a8617ed38ae3810dd45bc6": "0x00000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c0d016c2747a279dc4d62913f84f0dc045d9d5d7740029cfe44117e7e1584ae0": "0x00760a48167e07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c5c6102674305ba4954a214540b10245b686eca7d7d2c9748beb692bf5cd212": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d18afebdba073d8ca5e9dc0f58028a8ccd4e7b17bbaf2ee1e6b7bbfc2b23ae49": "0x005a9010a19f05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fd865faae90a888380d8baea440af24f73ce301aa7c0438f91569bbf2a9900a6": "0x00185504205500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976fd7c1706b7f3616a6ef5eaac7f50f53497cf57c0648abae9a57419223edba41": "0x002c467663c700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40bf67bd259d9d6ae1681b1effc23a4dde4edf79f64a19bc56afe84e8dde40e42": "0x007ebb5c423f0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397565b2879c09fa6ad5726d8ba5eb5a15b5850ec9948491932b109829c790ba367": "0x00c029f73d5405000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b452dc5c6a1c0c06702535234b91fe56c604a9d79e45024d43d36dbb113ae8a3": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c7a223743998937cc44ac49f01d78539cdb21a1de42eb9d814437366551c2250": "0x00901f44ae003f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1a89ce7ed4881b368478a7f676b26f7c6920098dbbcfa0cc9286eb80ec53ae0": "0x0040f09bbce108000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282431037d2efe6f18fd28c1070b8e65b2b7b5487a505662e5406964dfaee106d186e": "0x00d45be1e85b7700000000000000000020d96a8604000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e041aea19972a6d0ce2c4882f3ec628fe3a40e9b42e49b88f20f5b137f4f162e": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c1860d0e9033411dc776dc82aec9d55ca6f3f4a804104fc0d9e5743c6a5eb9f": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f426f6dc2d695663688bee04c774de3f5592966cbd771d4c9c741928a73fb1d": "0x00c296aafdc10a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e15b9e9488bc7a11510fd2f90ebda64ae0a072d0404f7f1c77ee3172f5fc33e6": "0x00cccb758b0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798d70864d2acb67ad8be3096cf4ce1e1232e1043c98e5d573e277d70f4381d53": "0x000458e5341b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd53b251800a17766ad88bc81eb32734ac36437441aedb67147fa1e799b3c112": "0x0084449cfc2f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4eacd000ec4b740ed72a8c36547d1aa85d00a924eda02a003b990d2734937cdf0": "0x00f8bf551c9d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974defe5a19687116652f6e81b16bdc16af64e1e980639f27344e3b7ebb5820125": "0x0012a3c85efa00000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579730c86e1f2912ebd6264f8b0d320bab1db66968cfcf9b007a65ead378cfbf40de6": "0x3a2b5aa8ffd4e3c5ccb11d342867d964414dd36e138de466f5fa6d865f19d665", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44e1e87ad0c92c0f66ba05485324e75c02023df995ae49d21d823675667cb803f": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1f4a90b4b6698a3cb1ca3ff2577355162cc3daeed96b143df3927dcf1e32057": "0x009a685f941701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970970059d13d7aac9ea9522dfa0ccaef33309021ba3c0319cc059cc5ed27c5d01": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa0e30b1c7f9651e78c1375ce458a85197dfa3ad7140760f8486e3f5b1ea3946": "0x00446b11410300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c0af787b6cdcad53aa6edf7a34986597fa5976cc42141b40109ead1ac4d6559": "0x0012a7a61a0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab8d209283fdde9d4b354ce1aec79943ed03c52d2d63abcb63aa9e530e4260a0": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972e94c0aab910577d40bc987d2700a27aa05c7e3cbe925a00b71e044d62bde6bf": "0x006c9bea403b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397428baf33028ed463182d79ec75809c9bee2fb08bba4e6018457db9d4590ac72b": "0x00a44ae6333300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed4c8b7a815d71734d4b134158154e5a5d571c1997ebabeb32888f579044a3e5": "0x00341a7e291900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769ee391c13a7ef3980997b054264c3a8f63d8bf14f6de780a7233c7e0ef5c21c": "0x00b4d919c66400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8b4fe68ee27d76d751231e36f790ceb3de4774cee5bd53f32c58a127841a945": "0x005a64433e8800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b420abab7d268eac2f6c8bb2b87beca65e44bb35ee6bb8c50f61d9292b141d5546": "0x00301a45ba2900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x00b0800e91aca32f0000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d3c064aa3d5e9c107f1d5f05fee025e47c210267baf2ac43bd59724532117c03": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976dd6e00e6cc1d7295aaca9e9f61c515a407354d641da310ed19813cff51b5480": "0x00ca73a98f2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f83918e6874812aca58371f2acd34f4161e09da85d075ccfa3d0b164206d54e5": "0x002a0967c50e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fb2ed43b9feea240109e5ffe1e6e0e803b408fca5c07f9f42eeabb4a4405dc36": "0x000cbd89fe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b699c2af68f827524ce304c475b5def26b8e4d07b514fab864d5eab1e4bf4fbd": "0x00b2f58f6b0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339795cea311b9197a24251629484b0712b2fd31a9d7f5984a619c77f48fd3f5059f": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe792f6002060d6c984c8cbdd8d5cb1f3c22a59f5f116a543d29f8bec0808bca": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df28017d607812f50872ed7bb7476eb63d7deab5574c51557674223cc3811924": "0x00c408874aa601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ad8bf9ff085dda3086aa83094630afec5f03bb501325b0e994ea4fc5a74bf93": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e2eaf6617e46b0bb0c44a3172f58d9a4c734ecf20e651caf122e3a6078d77e6c": "0x00482276b8c703000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b440425f615c631595a4016547e6a17da6c85dcc934220ada56789a6015546d2c5": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975fba653a44d566862ed933b58347b5b678647fe23fbc63f53f7b82c77c83ae9f": "0x0020bc2b7d4d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b74c81f7ecc836e4b7f3b91300d53982a6b0b7ce21e3c7068e152d1f1c747c62": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339776d4d694f4d5b6e1db9acfb2dcbb6e38114c1910976d1bc29b6dc1c82234d4e9": "0x002c419ebb1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf65dcf4adc0b56eb1b025c57cc5f7c9217570f21f956a4034b156e42a78214c": "0x007a116602e800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a1b2554103ee01631213d81776bbbbede650480aa71441cfe35ca36625531a9": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c0d6d53346f5296e6d23e4e29e200ebd3ad677453cefd56bdf6ebf26acc7278": "0x002656d56b8e22000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b0f8fccffceb5423c5a15f69f08280124097b6548931a0541494b3d8a0b219cd": "0x001ea1cd27b603000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977acb02cdbd4d622c9421d4d58ebaf801ec9f69204a18e8f4bc5c86bb068dc2d6": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d04cf2b539c1400c75bd382d1832af5f7664147f8381eeaefa5743e40665bf8f": "0x00540ec8632600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b413003cbdcdd82cee7fbafb34d5361b8ed123ecc649c80967baf9aa4bb77ab0b7": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397135e0a4baeb85feb2ec1a7ad4c0d146e18e5d7dc680c061d2f8079e890a6fe4d": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008676c38dc8071a8e13fc50b1bc3c74c9414f39d8d164b6e8eba0ff1f5a96b7": "0x007ebb5c423f0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ac11ffd7bec30cf57ab5a97e742d036bc8f33cc2c9a6cd7b799f541a6d7b8ce": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397079796f256ede4531dc4146bcfc9dbc544f707b4f4c17b137e608760fc3241a2": "0x00223675df1600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282431259f61aaeee32ae5dd4ccce582589d6ab6004108ec8922e0519a389fda4ada4": "0x00bc15368e363d00000000000000000020bd175202000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339797af1879293bb9441e89bc5e31fed7ac3e1b1c14920a0ee768b1ebc4311f29e2": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c204a2d6c981fb3b28d10945bbe059a9f3181c474268e3a264682c1948653d9": "0x0084fde0500b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb71b8372dc7b730a90dd0e69222ab083001a6d2bee229e9835afb82e0f4c343": "0x00c48d2dcd1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a37c2141b6d26d6234a7a82679fc6957e9f976b168d75607b3a73c485298831c": "0x00985db8783319000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397898d79cc1e5584f2ccb1b9b3d4dde806d221d90a18872a6077ce64ea11f24d99": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397955fb58122fdb1793572853e7cd48bedb1d80209c15deae1de9a364e4c1e608d": "0x00d4238d32a200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974191fccd7bee918390449e59419ac02d4596a9f73bbc36493523552820a98290": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0488e01f1f2ed73eef89bc1f5b3ff762f4ef9e37f30b832fc82565f0d14bc86": "0x003ab9a30d2400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793939493f6471628d8583972f3b801a1bc01230a528cb43dc681a78a89dd2542": "0x00ca3777b19c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339703cc4f59641d782eaa2335f428382c4a2cfb37daa228a1fc6509761523775fdb": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d4efe19beb29c17a940087605a7a33efb867595a08c422cf9b7cfba0b2388842": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0260a282518d553819f0e8b1d6323b2f35d609c5bcf4141d459accdb8d0e6b7": "0x00920d70945f06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b14529fa5115ecdef33d7f36db66935c9346218e6eb0553e7c5b5b758a36749": "0x006e358c46ac00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b441779d26f06cbdad4a031cb42fd4d649f41d38499c134aa0655e3adcf0eb7332": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5c04e1a137d21d66d537c0e62b3ac344057099ae647d185f9bdad42f9ff75fb": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d3563285d40af04d6e52dc6a955a06fa01548078245acfab102d7b5c41d45eab": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a544afb1cb2aad25fb9bd6ea3ddd35e2fcfd655ee8e357ac58415f701c8dd3c": "0x00769f7b7f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fafafc5db4913f5d12c8e2a78c6662422e58b725ee9f251d5b0e8d5a3e6a2b60": "0x00aa8e680e0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397805960fa078e64906bb8caf21b21fed39b78870f1ddff65800560963df7cb657": "0x00dce0e4be3500000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41da906a21baef219d4eb7f8a144cdf15a088da1c1ecfb0c39fed8818f59e42f9": "0x00da868e32f600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ae4a6d8543b0ac036f100f06f89dfa4d49c5fa4543aa9cb2883c26fe34b9ec3": "0x00ae41ce5b4203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b4c2a5f0f6956ad7374b404754f929868e70341ea83e5ace378186d9a02c5d92": "0x002291b31b2d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339789e36feecb230ae60b21d827935ceb9b6d425cd2c01260d9ac63943286de5834": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397992861bcabdf0bcf2d0c86184711c83d1a2c5ad69eb191da68c41e816b9757fc": "0x00b4766a6e4200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397589611640c8331b9c28d902ae1b3f7814fb1e895b24b03e2c3e0ab6e1bc6d096": "0x00822671511200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b3a6c376a040bbdf1cdbf26e7d08918e59706a24cbdffb08c8472aba27a9dea0": "0x007ebb5c423f0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf4941f7a322ec9514ad9322a1d4fd8eb8e70503b9ddf68bc8ba688f4cdd6fa0": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975acb5868500bf781f374c0f7890357fa8f06c1f1b9702ff6c5832cc75c4a9ea4": "0x00b0631b220301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd770655207a9ec146d492c5b39ffc5c1cc89328d692a0f896fd4e080af2fb8d": "0x00a8c4dc04b600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ae243bc0db34bb6ebd415ecc5b5a94c71c10e4259d72ca112c9f487517094ae": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bffdbfeaa84467968d30fc9d7f02569efba5ea3c046fe79ccd28f5fcdf5f6083": "0x007ceafac42900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e454d8d7c4fbec13962bbb68825f4a76b538a9f1d24d0df9e0c44d695d4b562f": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702545431a898150c42e5e2515228217ab00487597e8a8c6078678bbc7460a736": "0x000420885c3341000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579732aca8b91876d3671ab52d6778988c8a1d4bedb0425edfd52b59bed23956a81a4": "0xfcdeb580add093f3b5f06603032c2fe89d329ba372147c100aa0391a44a51601", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ddebac5d269e7669562c791ae646ce0e9071a31e7dc8480f6afe64ae9fb1b739": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6d45d20813ada0e5858b4e51f6501be70038f76b119921795ce9fd3b98ec3b0": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978dc13b43a3b7c0be5e84ef46f8ff7f4507246d91b3e13cf6e41203e7d36c5fbb": "0x006a5d2393db00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8f9883c3e1172329c5fdff42bbadfc843ef3b9126bb5b422d168b15c8fe137c": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a483a9a3034ea15f940a10d12f3c14baa4a357b09d7aaf67f4617754fb4e77a": "0x0062231e5e1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c28bf6aed7a023dc5968166e233130990e5bc010da5eaee1c4ba19ed6b513229": "0x00124ccdab0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397126115d674cad7bed8b46554a31f483d08368b4cc00bbb6fb261d8b1018e6435": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339782779080567f3cd33406770cd132a2ae7c670f8a06517f37011ccc552f29ab6b": "0x005cdd841f9b1d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bfdb739b628cfc335e92453ec540a394467dfe498bf1f4b41b73f01b68f4522e": "0x0022b2219f2e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339759e997c9e8c10f792b37e53b5d39ae89e5eb93715fef1f2af9d773ee739db1e3": "0x0040e022590e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339753e92a4cddec1437e712dec5056ddbe110ce0076af90de29a391b5a52dfff96d": "0x00c4de2a7b8d06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3899112540e154068163fc0278e50f224166f0705454f4505f49d36b3921ecd": "0x0048b4edbc3000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339717466275c3924112f2efbd27e6ae2a1d8a44b0183adef58e10187cf5e6038e0c": "0x00a42fcb056000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397059b0d30e340868696488935de7ff4e9041dea0f0f42a422a9fd45fa6cb7da35": "0x008a8b0e1ea400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397060fc955e3e2467a2927b86c89114c7c1ce65317a74328446be76e9d3987310a": "0x001cc7f59f5400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a12d38db0be74e67dfa22e3610f895bfa4497237de8a91a970ddf37695047f52": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c5825db6a3813a2b6aedf272daed10e1b86c8a41da155185df067e8c32c8cfe": "0x0068eda86b6f08000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397029c9baaad74b6e97741da5111124436c1a026125b54c1303d7dd713ab8fb3ed": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750090b716ef32085a72de1b22516806a4ccbea61514bf1bd0e23ea7a8f4acd5c": "0x005251bb825901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397695e44915dac2578d3a18d0fa5a046bbd8f311c75319181b75037357c4224542": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733fefcb48a6f4e25e71ca58443a37529601ff2154c1ff1ab4e5e576d8858f55d": "0x0042b38c311000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b4345f90a1b867258c06939e4c9ee0504690e057c0a892d303a2f1f4a565e17": "0x0010a125955101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f97e4d101b62a5441e554eb46a29878d28900d9c44da067a986fbc833d2dbccc": "0x008415f7400001000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243931bda21d0851a0545b159f336cd393b51e455830af4b3d6c4b764263eb5ea9d": "0x00d45be1e85b7700000000000000000020d96a8604000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dabfe3fda5913af784c957cbebc43a93d4bb6f1e66f0134b14358f9f24acd3fd": "0x00ea85053c1200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a125543db336ee1226f7e8533dea80a01b73ed25e10f60f1034eed5cedb3dce1": "0x00ac0b28f31102000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b664d0163575919ec4c6a2b837471e934d44bec7846b87af98f2375a5acf357": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e055600892532c46051878e21c8f9c5100b2de9728868e168e449a90e3b0456f": "0x000af98dac2100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4931bda21d0851a0545b159f336cd393b51e455830af4b3d6c4b764263eb5ea9d": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397acff0f13a3db70e9cce7a500d34e64df508c91b40aec75ecf8be17ffdc3e4383": "0x0060970a641c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0230991f841b5914dc842f826f202125423605f1f0b20a61ab503347a2391cc": "0x009ea646782400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4cf0b3296a7c2f8377c7b912339e1060e8f41434a08c794bf2850c77f57e05917": "0x00005fcd95f209000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718322578b492744bf3801935a3c994d634c4ae5ff4a36d42ec8f0988b85f7ed3": "0x00a667d3930800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b47060560136cfa8d67aae1d4d7230d5556528d5dbb6ad74c5afa4157a8f9867cd": "0x00bc15a98b8f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339784fbaafc76e6ee803463a40f610870c0c759301d86b7ec3661753b19c0dc31b7": "0x00e8868f1b3600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397316947786b07a694a39efb74c165a41a6a6cb274ee68e16c67e4a0bef0f54752": "0x002a07e4311300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b495fdbe7044c414c5da4e01138ff2c4b2e69bb603745b73676d7888108ea85112": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b868e265492331c94ea218ab0892aef4a4a650a334070a02e83c46ded9377ee7": "0x000033381b3300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397249cbeccbfd663d78f4ea97a16951610a925634cf7c69ffee9a86955106c18ec": "0x00b039c67ebd5e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397031dbd6ebdbc746dbe31ae67b032fe5a4c4318f0806ec59247c85964fbc2b304": "0x00963016623e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397add9c33825e5821f37ef38d3fd8c6494c94ca2f08cba100748a937fa6970aced": "0x008ee3351d2bd4270000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c08e83090bf1e4f526b59c3b7e079f7cf5e9a39192d01eb23b17ab94ddbd9952": "0x00c8f4b6ed0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b3574e8341e8af764ffb71cd8aef18a94df2494396963ec3ae691929bf689cd": "0x0080c6a47e8d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972844ec16e4932a4ffd399eb9ebd0f05d16bcbffc5465919f496d852e8bfc37fb": "0x00022d34640b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397281f7764bf03e364f9439543f1ae952f3f4e916ff6ef4cb892bf04c6040cd397": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb23e63c4db87396ee2db9d04c0974c469a203d93df6c869327f71f2ba86ea2e": "0x005634ac23476d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397edbdb1b69558595108da17ab4ee34f3dd009cb627548427fbb82528e80628913": "0x00123ce8e27b15000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397461412a9517b615e6a1a24e5c6467517ba6cb1ade51cca1addbf93f21f138fc5": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397876ef24d01d907199b7191ebabd9fbaa04c5fe361edf7dbbb3bbe96869a678de": "0x00a6e190f59b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4a8161d5820d3cce96d810eb9417290fd93de15317526b5935fa8ae4c0c7ce9": "0x007c6a12795600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f35b5c18a45577daaf2b7bfb720fc83f5f52e769b1cfaa63880f7e1d2fa6903": "0x006a097df4a600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e9b0174f8556fadb636c6ddc0ed4e56ccf833944475c3a5eabb10e824ed4445b": "0x00ec851e755400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397daf8f700e5fa98bcc1ba9df448e3b4356edbcc2cbfd245189e6a5073fe6f7da3": "0x000cf723526800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722929a78cd0e39555709cedadad85360170729e9bbd1964fae2024871398fab8": "0x000a945bc10300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972e16c522c1e5c531e29db2c977414ff4d27c44af7e2a123adc35ab0d1296f8b8": "0x00c2511f187800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978dec9d43b4d58561e70c838faf4736775b642fbd4aab24bf517184aefa59750b": "0x005880abe94f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738f36880d7fd172caabdb2b27a8d2ebe43d976144214dab403fbbc5537685069": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b87a3f8dde24ddd26dfc612fa65e456e37465fd53e120f50ebd74efa218d91d9": "0x001a1d06994200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c96f69650289fa3e737ecb2f659dc1cf462b59cb6188b483b6d4884d9968c99a": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec1fd62a8e82f9b4b6f37ad42299279a162d029a40a9a02e69478d9dbc31f502": "0x0056550116ab00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab2791070508ab95ca32da475994760f8750ab09e90f2508d60a6d67d1458a91": "0x00c0042bb13015000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978838b6184388464b04c03b5c52e0266ca9872bc8929a623178e40b027a3705d7": "0x00d22374f95f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f5b2937d6e608aeb6614af48fb91063e51fe613bbd59bb412e876f8fbaebd1c1": "0x00bcc1fbefef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5984cabc5fd69b6eeb9273fc95183d64ea41f1ad5fe8f1077536b7b75a1c686": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970362ff7eda73208542c42bb914ff74f0756b094f58bc006b830c42741472ecf0": "0x00e4d5530b1e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979947ba5c22d3850c382ce917a61143223d42dff7eba1c1e085791ab2bdcd15f1": "0x00d42517c30800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d3e97355b6e29f4b6386c92729977c6df3c85839d852a0bc129177895edb515": "0x00f85e3055e100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397051af92bbb199b1ef0c4931a0b35cf4886a5ccc5a7606efefa6eb0c879dfa37e": "0x00923d997d0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7b0461a71aa227c9273b4f80d8baaa225c01f9d81d72bf7c72ced1e7e3e367a": "0x0056b961800900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cdd1e867c9734ab6643b325393f747de775a74ac32d8c50f1cd1cf4413390e7e": "0x0004b90afcd600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397344f3fb940ee124ccfd0bbe0d3656412cdc569a37dbb9e686f185433763769be": "0x00bac1e9b31800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43b8838062cce51020c9cfb335a55c68aed60c70786a6f70882a229de391fd4dc": "0x00b869b1edb600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44bd2bb3775d2e5ecb40ff4a8f12c0efe8bb40a06930e8294bd371baa2879b0f3": "0x00ca26e4674802000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42e40d43d28190616ac8926324b0bb99a4c52bd70ad9f7b10f6bb82765c2e1f70": "0x00c26f318a5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b5c1a91100d3a2a46046841a6cb57406cebf13890c1ce09ee4de45f5273435c": "0x00a02b27a25b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd0b8198676c0740dfc8997b751ac4fe071d24ab75a3c1e16328e9c31a795ccb": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339709f25f3c04afd368eab6b4d0f969ce3f9854ff5787286aa82ad4eefcf1375bde": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb85cb4e5294cdffdf86783862742eb97a89ea8a45d520fd42eca7efbbe543fc": "0x0066c90483c802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339755878d6d1daca93e421b89b3fa0af899af4d0f3759c182e52d970da19cd4b113": "0x0020f84dde7004000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f7b3209d5965cb89b9116b0ea9c125487eea9af3e3bbb5138d0b8bd523567d74": "0x001cd01a8f7b43000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397082da023e83ab3c5c31a9e4089d9ed1e902845a83d2be4fb1d3d6b284f3afda9": "0x00ce429ebb4103000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d60cb34d738ec904d68c9d331ed1774ee45f300c6c7c4c54a916ece207774814": "0x00ecc28c1b9603000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b444cee1a21bb64deeac54fca37209db71de482be103cdf6d13aac76576c314efc": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b49a8cda72a4c56000c7d31955f48652a06731952bf4b47d336cb59ed3c456a": "0x0096e772550000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a2a5b3903a2186e3fb6be99d1f795c8950574193074479c117083f0a8e2b1e28": "0x004af6b3941c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bde7760427b8236b5681704df9f616349f801752a955ee2024ba6da0d68fc03": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9623768468d2a71ddf93c44364790c269801fa64438c13dc20ecf40b3eb103d": "0x003036d4980900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b404e96df460ff8eea2db9fbca87620880bd9cdb6e2b2ed4b421bdfc53d26a04a3": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ce65e8230b040846fe102352a565d8d882d4312ad050789a912ede9ac992a0b": "0x00f43e5be3af01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775c76a987f6694dae116ca8ea619221f1faf1c5958f838656018f0354b155b95": "0x00f65e1e190a00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a3b946cb497f690511d1e866566486634ecce782196e17bf8e803dd1b6ba437a": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9f6894291989d70a8916eb373708afa86f2ba0ae45734d6e76d84827d1e11ff": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a10a4abbe9f611d190a442fad27d038877fb3aa97e6703645d8e96c465bf06ec": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d92398dce0cae27fb448b25aee5c557b070a12588539259e1cb49a8205e699ca": "0x008eb862b85c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339712c63144a40ead8b11efe7df93fc3034913274bf5b4ea224bf58bc56f0e0bda1": "0x00ca752c232500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ad8f58bc5d22839368e6356263c88516c83e183ebf8db75b2366cf5e526e32aa": "0x00eeb51b29bf0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785f9892944ef88b2cd55b0c74405af94b2973228ef5c4f7f6ce6bca662891e7f": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef2b5acdd31c69f4c4cbe54ecb608c334af91b16c9ef457574973aeea137dd01": "0x00f6e4be872900000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcab49a2738eeb30896aacb8b3fb46471bd": "0x04000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397584a7f657e99708240b43aa06c4b4fa1a23914c5059398d23294ff3cf56212cf": "0x00c6c5932b7300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f74d9fe9eaee4051f874c98881a54c1cfc6f4f847e461637f13547ce3991fc3": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5541c57a8dc15b0c1a347841abb579b7b5c73155ba1c300c4853885fabfe876": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397649cae02d7a466aa620512c5fd6b05cbff27242eb8b4503a2b5ad7fa380de643": "0x007e58b8edae01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dfdf864346e8ed0d7e3ae67c3b3803e5021a43e8c68aa9c2ffcd208ff923e85f": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c532a414bc0c6818940ea915cd88dee97b9c03b1f04125eb784622ccffff741a": "0x00b634136b0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e6e468387739726966a50db481c5c318eb2494d98d6a7a60065dfb61d53d5d52": "0x0050a95c091900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4860ab491b2325b4a593447f0661edb8d3314d26c8908318006df7e88dcccacb1": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397726960cd382acc57b5e91483c1213f8e63a032c98ae52098d86b61c13adb9f6a": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa2ef455ac0427e01fb957df607f6f5e9bc5c48414ff1b4dbf9129203776ce4e": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785992469fdad981c8f69a54269113faef9c36f9bbbe7841e5d6e4818c90a3262": "0x000481ec3e1701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e435bf6dd94a1c5f178be542346a1a2956882dff12a5ffc5671178e2815b6fb": "0x0084602bdb0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397267fc127a9e7fc19850420df5455d14e05448ba01461202ca5a9228d46509932": "0x00769f7b7f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f15acbea317cc4c1d4416107857b11880e6f52390dae96512d711419c6a737c9": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b9a8cbce3a3931974dfe18d3f377624ca440a1ae781e508987c0562f5e49fa8": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f3b34e7d55d3eab370fbbd03f0832e357b6fb59c3853189ab31cf5b535aacd6": "0x005a4602645300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339795982064ea5325fe950a52328bfebbaf6ff3efd6524ccac3073af6ad258ad267": "0x00c2d8ce698600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dc789724d3a839d5424ef74e95c373cbedf77dcfe28000f7ef33743d9609f9df": "0x005ebeb2030a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aeeb5f745954939416fb52f14227ea00fdd1d144a4bda42341f0421f39666327": "0x00583b15017400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974eb49cb41dbdee5d7880f9c762b84d849b58fd138ea4218e5d08c767b482b950": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6e51ef87bc1765887ddb70ab205769424b77b0d07ef16de17ddf58907406578": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b45d46e99a9022402854eaedb3aa9abfc0b8d5fd2009961fe82098e992579ba": "0x00181b6acc0400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4975ca7de6a5d9883d0b512f78069ef22978b7a8b00485da487700674547b9223": "0x005aab55bdf401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5c5c4685488eb95d7178a6f19d043a37dca2e8847d9b9de4618e362df27e257": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b23e999d120fae0870b8dce80a0afbf7474bf0d3662e11a4e96e04ac53ad005b": "0x0078cdf9a5e903000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ebb1aefab2d3b12c156dabdcffa36a90eeb41eb9795e42c188db3c116567140": "0x0048513e650e00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243439ca4cce6eefa4689638418cc00be4221500527362b0618621295334863b687": "0x00d45be1e85b7700000000000000000020d96a8604000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7f6862e74ff8acc3b183bfc11b80179ecaada61e7b031cc5574619e6b6a5b6a": "0x0064eda26a0000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b47a9f67d3ec44e939b2bc22650f338877469c35ab827dab132724c6be10f4c23b": "0x00d0d6a3921201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397effe740d8eebb04018e4f5f3d0b466484879d8d8807874956ccd59afd457d585": "0x0030494149a100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339735cdf4e261989ebba654a9a70709deac93384cc996a4aff890345226a145e4d6": "0x004cb4d510fb4a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339784da736705970f7d8f591731d4d8d6004682afa16624266f3f5d8d69e50a9b52": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b807cc184d815bdd19dc71a1924d584bb8cba4594de5c2ad6d725a245dfe462a": "0x001428b7820700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970aa6104bc1605aaf8c3f2f6cf2949c0267c3dd70db274df714a1ce7056869c7a": "0x00605b1ce52900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700737814f5f3785419e2ccb01c9af9778f52918e9e33c8de70e55789c3809282": "0x00962d3a03ff0e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d77a8edeb69b4a48560419df1017576e2c7f26d5be79db62f64660645506320c": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b59499c8e72a3cf9994590d644fe8309c7329647bc70e51696246d3575f3e66": "0x00a8b75ddc2e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5332b3b543a14c956cf2198b8e491a2daf5beb7b4e64f0c3d3b72bd42431ca3": "0x00fc717fa12000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6e325564fd7cc613874f7cebb52f20abef5578f2dfc88408549e39d2b872409": "0x00b03c97ab0200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f74f0e5470050752369ab25b7ecfe9f21be37ea49e3ff8ec3387fdd6d790f367": "0x00406352bfc601000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40a14813831b26c08f93ce7ea95418cfc15e2e77e8815fba868afeaf7fb424446": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f8aeb183f1047117a8e038cf86098487517460dd216a931f0560bbf300a1a3ad": "0x00ee69afcc2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f92e2b7881b502edd50fce767e74bddb0682009bba9998995c6c55fc0bf3de5": "0x008ac580060600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42af699357c8556830b312cb42271bb0eaa3ed4c0e38f189171a4723913ffe015": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c36bb05faf0fd4fb351f93dcaeda323e7c1e0bfd5881263f112c2f16f91ef0a1": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f2975395c4c18ed35a374a3badf87cf88adf79eee3be0be9ebc9c777f83fe23f": "0x00621698382500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397992de3750df7da5b3914b63a42625850128b2039f3b901f402fed766728229a9": "0x00241c35eedb06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af563e2fc2d392c1a3066aac0c8c3e4d46c7c98a20fc071a9547e2bc53ebc36e": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397922022499335814e61c422c996deeae8176cb4c1bb57b743ed26bbf4388166ed": "0x0072dd4e553400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397baa1c38978b24eabafd2daff5b7ae15546b74d3bb1910a0d095dd75e518f6612": "0x0068eb4646f709000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c4778106d6b796e0f2caf74bfb9c07f9ad69cf91507377e1cb1af5297d767aa": "0x00087e93371c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e94b5816ec168cc909fee02166c60e77b31fba09acd80d08b35a49a8cb791b62": "0x002039f3969603000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b3d78e8157bd145397112e350cd17126b20b3d6970b447b31ce995f6221ca75b": "0x0008db62010400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f8b4662fd481a54a41d3ce7e6e6eaa30e5bd200408643fbfd1b5131319c62e7": "0x00461501481500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e615b1a49b2de0f716a9b717d9dfbeb153f1cec2d4978abc637ba1a4ed1ca886": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339716e1d85a970485963b5151b65810fd858adf587f04f1779aeb8763abc01fda26": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe929879363c108994831280f4659b43bb171e2d8f41b22c2dc55ce55e114b0a": "0x00500a82d0d400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786a817d2a2548c7e7597b107461f9f1b9f24bf09c6a276355c879d7fc5e906af": "0x002a5a3c089605000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d2dd181d01de6bcc83b2d43041b72153c35ab7536c9b964f4b5063585e03c7be": "0x001854c6d40c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dbdc10df537f786b394035a331196a6c0f7a12a860bb4d2e9f89a70bd18ce429": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e7512e368a18dde7eb682dafa880806aba8df888a8653fa0b0bf4f0f90cb69f49f1d9": "0x01012020b1b5f8296308a15f3c0c42c22f1ad155017194bb736c40eb02c305110d1288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553126046e280a9e3325432d777b63e1f8e30528de666497a098b816cef014019fe47888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455312188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553120f0b9195878c2c04b5ad253034bf43c6ef5490add07cd17baab96833a2fda847288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455311088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455310feaa73a033b31c0b3cdeba1f9c7f113c54e13e57161dd957367167cf8eae30a2f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455310e005fae564f08de5bb5908dfff6bff0f9507b744b21d7017d478aa7ef5c87f97c005a433c8e151c81ae948544f4cb07622b18a8430480de6fc6e1a38bc46f9c27b032b7dd32aac17c528ea660d9c9215ee2526c7f37f7e18e9339efbe4d4a89028857b3cbb79f75ee7762d8a4318439927fd2b516439c597134c3d09fe0e3f10332355be1fcb11e84737c1056ae1fcf33172bc652b4103b00dd091f6c7c84cd0426e5514c23d43fe8fec280e4529ce535f1b5b56da5423c17cd384a4d89c9dc73868cd54faea1a0e45836635b2bf658733436ec69c5567d651be592392cbb69dc200e05c7f86ade5a5d7d1a26ed2abe5be72e8c591a65c4938698e4f20994ee2b34ea169f0bbf6ab861377b3e9cc34e52ffa3f1674f887b71b14b32404221b13588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455310df6049154d238bb85d976c29ddc372b58e4fedf057e41687d0cfa39f14771ab530ea2376acee36454341f0a626cde932000a591da9b5cb385b5fdafaf077b2425cb7cc7b2f624c92c6fad8ee77458a35c7acaade2b03e5f0634509cef1db7ce09e4a6bc20742c72fafd45ff5ef53f7073d174aa51bc63126183ba20fedc25186788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455310c3543797963596a3431767a387269796e723258546f6171484d694634767073436467fd4e7038b925c2422357380d8cc0c5f17d272f639af8fcfd1f1156de70405ae4225f8b80de2406a965fe7c262d2ad77dd793af8a4cdc82f194f0bfb25a3576fda1c6f0ce06ef296b697bb217f98e4592f25f1471e46192947337923093ad084e478080bfc1bc7af2492ac94e6983006dace0e9660a4135f84f85023da732475541636b6177614a4e505671477a684d36486d37795a4d45586977687a6b69b2830101a23e2c9082b3b149c1a73aae2e1e9482416486cbe0e9a370c183195d3054b90a068592010f1a2e3e4525df3a5bd8f1c71b44a4ec5ced1bbfea225b4f1ea03129bac8665e20576fe238d270cab2441d839818d533d5ea903f8960725e3c9e7bbc52a16127598682b3f1f67e7601b6d372592029beb00f6e09f2132847c22b622f0adfbf8793c38faa55abd487d782bc484a4e900b20523b54ca5e243580e30c47a3fc276c022612170e25be798153bdc6fbfc229c398f580646242978b41259da19620b59b86d5e3b761f0d047df29575a38d1175334b1be1dd1f713aa6ff5707dde3642c6f95ecb24f9bc9f285bb91d34e08ff9a3296783120e0440056fdb6ef85bb41e02e3c0586c0a3ffaeed1dfc7b7fddc7d31c1bb79fec14f327ac8e020e9583a6ddadf3894afcdc880c4bacfd70804b56036a5c785463050241888d8a52c49e7e6827147d1f92d35749b0c64cae053cddf54522f11a7f6be8025845206d529e2e58da0e486ac94f6887555d8d70d2fd312e7da2c9a280932925", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976040a6b164902432f868056b7d7d24b3f8366d226b7f849d232f1dca4ebf57af": "0x00a2a8027b0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b8381e1d66453dccb25a6dcc16e715d6d6f94b3bdc32440625edd0a898841db": "0x007c177bbd1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8fc6c3bfda9f5a95ef50e98b0d89644ba96e915977baad8ffa1b13569f78a8c": "0x008826bcfcd800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ebac054d9fd5bfc623e6c7e7be0bd6c38a0f10a36ff9519283754da36c44a5cb": "0x002acfc5745300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b442415a6c1aa5925dde42f8d8728733da42462e04d7350f3320f86220fa7af4d9": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e2243baf2157b36575025e0c5f49fb207c5b417e1d12b185f9a8dc00c30185b5": "0x000290e3bb2d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792e6d4205367f7c529ae01b2cef8353f7be505181a6e55a128afe22d6b4a19df": "0x00542cdad50100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339731fc545b515db5f0a96f2d92302b4da1b018b94c35c88b48780002d5b721593a": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339779a5513efe556a399f80dd11a2ed31e29a8950161115163e037d8d4571a3f0a2": "0x002ca8141f0241000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e7d00572b6d0401e5ed3b33560ac3429918a4cc6d6af9ea64e6902d47a043c11": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f7e2ffabb33460646d09e2b6e0533517cf60885acdc71c87d21e54d99d477ed": "0x005afceaa60800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972fa30e1cbc3e2055db03c1a89b9378b9e83e442dbbfa3abecb785203b365af07": "0x00a0724e180900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a8c79b2b50e29324db627823c928bdceb5d77e2870c596d1346a0cdda14d4dea": "0x00be4216aa73bb000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb929bd849ba06ada31fad8ee2f4331f98befdfe35b0b2f8fba903cd4bb56c24": "0x000467eeed0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339788c56a0e6912942063b3315c4392ce9a007f05af04b6590d180b845069c66e57": "0x00e005f7a53b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339752a22cd3b3742fc77e4b9ffa2a44152552c1ac694975d20d3ac7ff384ff99698": "0x006e38ef543d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b321bda1b7034484acda0e4180901da82d315ba0deee6e8c5f198a960c41fc57": "0x00a4b18db87601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a547e6151b37078425dbd21b8bd216922b94f19abfe4d167dec04fdd6ddaf2be": "0x003cf35d972100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e75128c039ff7caa17ccebfcadc44bd9fce6a4b6699c4d03de2e3349aa1dc11193cd7": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533eb88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533eab06e66dff95cbb0f8ed61ff4a4e400fff92c8a7a3c5b971e017592393e364b173ce72b62d59cbad8484e9d9cb06edab1f465e7f30f3eab441ae94df1c701336388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533e788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533e688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533e588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533e488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533e3e49bcf3e8d759623e150e8952e645a358872a84dc95f8dc27bf766be8d66052688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533e188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533e0da61c824abfb1e5df1140697374346be4443e41fd1e6ec99c22f2cf3381eb82e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533de88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533dd88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533dc88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533db88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533da88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533d98687495febea21de449ff27381f9308da6f15ce5d9d3146261275dec18cd566f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533d788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533d68bdf3fad45fb5b0faccd6bc9dd9418a503db87e8955edd58fc0479e8b407b41088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533d488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533d388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533d2f4b90c9beba179a66ce2a4111436cfb7e21f93939a02c34554e86d085404f53988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533d088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533cf88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533ce88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533cd88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533cc88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533cb88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533cae8f3490064b9164ab0f2abfb065588ad0d3f1484d67796854ab262c02d241e59ca5bc1915da74aba3aadd7ce7b809045d5eb5b73559259755fdcd85a40a5dc6e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533c788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533c688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533c588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533c4187b2d05705cb7237ad816758ccf686425bf998ccfa327ae4c2004f2d79fd302b221f3d33adbabe1695b6def8f9fb3b30a33c9eee2e7b024341152d5fdbbe23388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533c188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533c0faf41a99388f45bc9d18e3b93383221b6f815298acf8b3debf235aa33509de3b342ab9d4bfb3f7bd553caa97e31b9706b1ae24ad7ca17189921f2da8d0c62c4688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533bdaed7efec80092410d5bbf134d29e673e1592e2b95bb7fc24f84d5121344c2c2988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533bb88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533ba88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533b988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533b888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533b76a02a48539983fb04d39d15b8683e55f0c8be25ae66bbcd8019c6a0bf4fa041888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533b588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533b488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533b388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533b288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533b188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533b088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533af88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533aeaa861aaeda4c2db6361e9f8cc5682aaa4952b6af4d6533c1d7dfce4674f89df088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533ac", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6c98728705e3aeac725bfb06b23caa3bf3d3a835338163337b76fbf366a7c1c": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971d8f467e3a352964e0eb60ff3981d19fd592fc8c015effba1bbb4367c36acad4": "0x00268dca6f7902000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b64ea43395c03d859c5939621fab9919ebf7f2d7a6f5b27f72083aae635b3ba2": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3b311c849366a2f3a8900eac4781ab8a00271e02aca2c5154f46952cf5de259": "0x000cf723526800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397747ffbfcefa9bf3797a590419054de86b53d20f35db4502ce5a4a69c33cae4a9": "0x0090bc88150100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397517c5e62791c5a55208ca5efc82625bd38f9240c30186500f43b65660d78fa30": "0x007ceafac42900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf8b5ebf7ac3551372f03fcf936efb1194033eeaefebb7d8ae57a287b3aecb76": "0x00be18543bbc00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d627bd79c4b17cc88816e7ffdc6d350d9d2ee96e975e28aae23ecc1df1d58173": "0x00d0c4165d1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c9583dbd8499c1085aed97f2d3dff37622d50db530985edf36a042f60009c471": "0x008c8b2757e600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339797614edb259b933ed28652a94810e58387be390d59bf91f7485a7302a4a67118": "0x0016ccb8010900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008f8a1f0c263c90d49e846a3a7b5b255972c71e58cc5992e932fe6b6f32ea5f": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb31b79d3b8d0b5f073ba6fe81e075baa52d6214ebaad638fe4ad08e40e6ee15": "0x00b65c7e590b00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243dec0edef2447e5773acb08bb5b3ecf5dc6325e343e3c39c1472eb27004a4bca7": "0x00dc10ad45b20e0000000000000000001f0da28e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0c4e36273f0ec93ada8175ffd94b547753584943bf6f46fc9f39a89b6d2b8a5": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975beb6a2db82ecb639c530ec548cd66e7699dce2fcc56c94ec7e1ede98ff7be50": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ab1e1d96e4af44dab6e4df25973b9adfee5e9db432a971353b018090756baa5": "0x00188d22dd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c07c62507b795e2591230f39a491fba0278764ee10330a3c217135d8435c349": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397025ba096dae863af320f1a88a61617a803bdd908d874528f38f6054990443a30": "0x004ef86f970700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792edbc30618b42ccc923018e7c26e35c8ff3767020448ab59dc9dc3e32ff3849": "0x00188d22dd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e846aff8fa91b739fc7a1e83e31a4a8788d546f3a6344712f5648a81fe9e1461": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec8ea660f0131eab8949bc74cf4467d9b226a4a3bd39e2e119cf4ef0d8f65b8b": "0x00f213b10f0b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd4e4acbdd0c86838b25ccca2ddfa6ffe1a98428175cff93a17bc058e957a722": "0x00e80f27ce5d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792f95336f706cb5e81351229549200c275dee3c377c670690822152780939077": "0x0000bbf64f3000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe36f9cefab92c51422b62c6a6d6ed42ba4c7f75b1f092cf8c601300938e2b18": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973853c34aed9ca17a241cff9c63288942675ac09079895edd08298ef2a81bc538": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c48d2f1c475e9a2eb1902d38e613b7f80bf0792dc7a46f8df9cf216626de6369": "0x001267b2741900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978514c8115011bac6a5115ad06c2fb65528caabe39e780f58d18746efe328ddfc": "0x00eccc45eb0100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4153b719054e1e6897a808fa04d3da23ad213807764d613e4de20fb9410e30678": "0x000cef52127e5d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740a3296530e6e1b3474bd451260625a4d3d81136aeefb937d30d4fd8030ef994": "0x001242a3973e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da138c7a8c8385453921a52b755293cc8207506fc57d04ed65fadf49f64218a0": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974bdbb6353b97cfa9ecf1b182a7da398f7cfc950a535d1ee18de604052487de59": "0x0034fc4eb4ae13000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b48da1407145d4a5c21f8148c5dd2babaa65056ddf4f4134647c1dfd39a99a3071": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bacdd249b0caa3e526a7956ae3b3f45725b14d064438e1bfaf17fd2f8bc48bfd": "0x00d22374f95f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ba0e8cdb2b7e882ee0b5904c8d8df9b36315186a5c2bfc253f68d85c183db579": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705e3c0c24c7cf83c79322e57a336577cf2dbe0a507b97ccbbfa4393e08c64c8c": "0x0018ecb616ff01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f9efb81d16bdf993ef94ae853a8fe78f0b7c7a71aeef1bef69441511459e8e1": "0x000620e7ad0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979662945e332d42a77001c70d757f6202453daebb027bac45eb0b761970635217": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339766933ae2c5730f9c0547313b96758a6785ab140d707c96c70148a3f8570d8933": "0x0080c6a47e8d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339721647a7b6951e035fc4e5e017253bbaa3a59ace314d261165880cdd9f39d59aa": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397524891f29420874d202572af24d34d7b634fbfdd52fa358d0da161669e84a728": "0x00a8c65f98b100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397416a22250ff1d767292d1f99c5f62eba25f3d114f7b00dd646525d51624814c7": "0x00d22374f95f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b907c0350206b560c50d8b6eb7e2ef53031763421177ab40c475f58acd5bc2e6": "0x000628f9e97e10000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ca2315da0b3a825313e638b61774917ce137a57abe8e00b32a52c4f253bce6e": "0x001c44e7a71f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a2b4bb3f2097a299cc6dc829fb57f3963f90a7143bd8134ff47254f649883fd1": "0x004e6d18efb400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0c24db25f99c1bacdf37b84cca839dece5db1c9c121561dcab626f2b733f925": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970daec67e6a8ba64c55a539a8e14bd50a93f5188777f0d34bc7c69f77504ad823": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f436b222c7c1c8c5d474202601059240597155b8c7c89b4a2eed346d4854ac3b": "0x00ba1ae7383a03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974077ba8dfd7e56cee811f63dbc0f73794431d3160298f6a348fbaffa129a5b5d": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397907eaa81f70cfb2f53240d5f889ee7f1a9023987583d58835947fc2cf60dda73": "0x00ba96511c4b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397664540f814fa8a1495a58d1f2e87cdf24acfc3bf5133942f1928156284e5d0dd": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c832452e825c87cb426b62f40e4a8db6163d3e5b8941a382de5be741dd5d2bde": "0x00eccc45eb0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978581d9ad54003da068dfd09e964fa804e25b44c7cb151c467add3746a3fcc4a3": "0x007c16070d0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d276d2523d17ec5d341153c489d36c321d1cc3496e159bd328587df5dad6f5d6": "0x00bcc1fbefef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971aca4b81408b03f26b02d34eae9567f222f3b51af67eaae4b990d495bbf6faaa": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397048a8cd42bd5fda1f54fd37c594d35c02cf7373d08fdf6b0e0dbed373f9c7877": "0x00c87a6ad0cf02000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282434520e3e74c0b8ee4bebb68dcdd5682bbb448f5f23eca33e44d815c7184fd0a5c": "0x00d45be1e85b7700000000000000000020d96a8604000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4b2fb3a7b1e8716f04b08657fb29425ecdaa2ad4486abf7f335033d02751a6b": "0x0062b3e8e00200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971bdc750fa896049ed2df4fdcf56401aca06195a5b0948f54df7d98039db0d01f": "0x007ea3f3842900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d354e7168bcf0c4894c0041730396431e36ade0237f06f5a561765762a48374b": "0x00fcd42ef94200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe5e345f6f414768e8a12041f482a2d53ad7b73f5c36ae13b102b879fa9630fb": "0x003e3ea46d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339796b8426e66c4e0c290f28f54f63bbbf52342b0ec8e7a4efb97608534f2ff0c6f": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976108e2921a19df85dfa2a43080ee93b3d8f7d13f72527ed36b7cbfaa38ad40ff": "0x00fe189e4c8505000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4004def926cde2699f236c59fa11909a2aee554f0fe56fb88b9a9604669a200a9": "0x00d4e9d4ccdf24000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397759a0903bf45eed110e0ff7930257ebcadd822c932d08db4175295be240f0677": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973367ec217f15d0f6e934d0a3de0e0e266093e995d205bb9657bab3ec3048f699": "0x00126d3b2f0c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ed1587bfba57ad746c9890285de308f631d8c070e70c3a41fd31b51a9b53dd31": "0x0080c792f3f801000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d775a86c5f972cd650a296713e28cbc5d79488320a235f7644e343a5cd4e7a66": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3b3b026aad553a142a02cf3ee9b29e707b8fa2b81051318c6199e870458ee3a": "0x00c0e1d0612100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e75129dff876a4b942d0a9711d18221898f11ca39751589ebf4d49d749f6b3e493292": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ab88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532aa88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532a988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532a888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532a788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532a688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532a588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532a488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532a388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532a288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532a188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532a088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455329088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455328088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327fa202c0ee08d7900739bb4cc645a29750489c32af0f87fe329069caafee6dc4c388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455327088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455326c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397406bd698679f5a312f914d1a14b9a5d56fc5d163c29f2433799e2a515eac1d83": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe52478176cc4349a7078fe906c756affc966222109ccc7576dd0f968deec05b": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397430a5614cd27981334a2a72f76440b9c989fb011555671054959db6a09b30160": "0x009e4397200200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764fe232bc393b854446d7c204297296bec625add6386786ac72a322e0b46fe32": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786245845c5b3762661c25f78bda822ef78d2296e13526c149a5bdccf46a80616": "0x0024113bdce301000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e7512ed71dccd7b507f90bd44e9e1e96d39481278657ba4011aca903f883e6242b0c5": "0xe8780c9d8ff3121bf764b263a23d7913b4822df102bff190f70ea63effb2672d70354543556a39684d61626f434556715461544569576f4a325868633838646944b2056476c0f47cc879c39651c67c196762d3f46070497602d558260610740d5c386846e8d19cb468fa25093247fc9a0cabdfbebdb53e20e9ac7aa757a2cd4d5cda750c658d067a0c39319246d5705acd32034d8f331fc9059967f0e52572f27a346a8fbe1f38539a525040113a71c771278a4038a1536bc3994ffa7423e6f0295ed63adb9a29910d6d4477fe9c759d15bbdea9ff976c7fe98e34fbf11a54fd8c22fff76bb4a0a5d66cff0392dbc083abbac3b3046f6fcc328abf0ddd16ca083718206093fc9956e58ffcaa9c5f6f7f98924e9d0649686e14190999b8eb2ad0783ce4862fed138c9dc8bf746d9939a0533d663ebddfc6c80ccf9778d27646c232aabaa6f058f51bfa31f31a65ec3cd01db33ad68ff3de1b6593d805682d34414cfe034493ea206c79c1182e385a177e2164e3bd932d6ad9a3d19c400f1341a97fe84a7a3920a6e66fa467eaa4f4586a36f994a48e8c374bc0404125d3912b07103a10e0d35ea09f9c79ab828802f8d18d30361fc1674942929b70c53cc7b1cb66da464a490dd62b4378f123bbb3c778f624f84182467f526f5bf10b9c44cbf429aa2ddafafa932de268656a0ff43654062cf28241bcbebb67ec74499e066049483e65e73bb4a7e6d8938785ced52b26560b30d8369e945d423cae0bb03dc6a545b03a6d05c231601dda6cd76ad44944d2ed8ea11650d76f2f3d6d43f72792017fe6b11c10b6756891e84f7ea004a60c1c8906189197e8eb8b44371df6580aeb61bebf2dfb5f7916304859c6628beabef149d9646f7874aab9413604f220eef973fecbcb02adfe9704150ef03ebb30192d148a7607a5d60f3373efeed43c1a447134072ec68a47e221e734a1b505745e803b6e658f4f1747c79cf62e179e94f67cde0d50daf96d49ba29b4df5319c6e3d6457322cacbbfecc09bbc6a0d066bc75f0439f99ba631ae0288bcaf5411b22d18be33b8ab507f11c10ab7399e76ed664e5036705f0580617ed42d5a59fec71e373a243eddae36f10a2d336c3ec6eef628e233d8c9ddac1bb7105ca9c7b8f56c3954e78bb214478095ee1ccde3c340966998f389a1b8b75a3b3cce888eed57a178d738097ce06ffe7d2862e763a5b0ab63ccb08ffe7b9f5038f912499d40a5dcde603fbcac1ad410c24dfd1403303cab0ac61e6c58b2a786d8d26c66b5c52e2c744caa4da0410d8a34436469db510c246eccfad7ea2406bcbf7b44f9a744c474b6c56252aa8eee245583037817a1305713de88495b943241da1411b314560edcb51bc99062dbdc4dcf906bac0c4852f434ee0874d09c3b5d554cc991a98bb9e1f7287671660fd542d7796ace33dc7c7502a417cc0112bac87e60e00ee2fec744cc81614d6c4fac07b454d8719b5994dc1abcb50da086e4cf6e64b62dcd473409cf5f69c8d35eccbc31cc981aa96ed4221bfe7fce341ff73e1db537daa4cc8c539997a8b0654b06cb81c47e4f067f55a65a3ad5ee721eeaa1a3b7f1904df7b1a6a035995911973abafab3ec2d67b592b239306e9a8365b56e5017a5e9222511558c093ecf62fc283e5ea980792f3f3e8e02daf465f50f90970cf16497c9dc072a42febe1b73845720dac11e9ff7eee0ff3558117c3145fa744ef5f82d8db853e5b48916c47cb777b3955f9d33ff279eb947acea2c774c89b88b538b617639a4d25499b4eff9fc54835e763a3b98acefa535da8564ba0f7e717dd8d61025823ef756b474d6a3f3e8099da01ce16b53d85154962168ae9e867c25c4d9557b4dd65a3a335e42fb173cae9129a8aa4f1a40bb3400bc86e1f6ac9f20d17b7eba14b98cf0dd9094e4c99cb63f4ef335efb4cbf0053645d33b8d6eaa28f463c02714cfb4cbc3b275fb55962ce0653539ff6931902b7036fc2cc5a44e28d92392be9d9ef3420fe2755cd50ee4f6d6cfc2eaa5888e408e342ffa941377ebe35df81da70ea4c7f433c8ea75d1fe05c3887062f7c38625ca18620ccd876c76da8eafcae4bbe7d7d17d263ca07fdaa829c5b32c7ba5f134f82cfc999ddae0daeba4919afcd498f96397696ba434dbf92169b2994472455f483f908fb4a2ca9089c019be542f289c0cf8313aa43660754b6530f44042e51f1cb6177d778b641db89d6a3ca4783c67fc5e901eaae5ef8b448d08bd76ac08304ed69bf7876e274ad82412bc7504c44aa5009057a878f3d8ae1dd2e4bf7b5c74de081827ebbe24725b95eceee637451809230fe8b7b04315a0486ab800a9b9c9454a6b6e6348646d76565a616b4e4d6e6962475947705143434157703879566588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345530ff88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345530fe88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345530fdfc10d1556a65f36e2a97bd7d34f06d8b34040d2afbecf9ff379f043aeefe79508a1b703bc8ab1ca1b84cf1328cf9ecc1486eb88e52d316b005217f1d7a292e06", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778c07f14740a4310b0a8908075ce144ab9e3aac3ea221742de2f84df0018ad35": "0x00525742bab805000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976dc693708f3359e154d11c6bce79e0ab18ea15ea2fc21bd24e51b73248f3a713": "0x00a0205a752900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b403683b3dbf85c7747341db3c1ec7e44a29cefdb893a7d3ce4e6cbfcaffd4d995": "0x0026b84199c300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972116ee7a3416d8c2fccee935f038e751482691c2ae8c945c093c9dda5a34ac94": "0x009ac019541900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979455bbb05c65b9190fba78ff250d5eb9891f153e8775d48a2696f2f75ee2ad5e": "0x00bcc1fbefef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e659b7f7f345ddcaa5409664775a4a468b034284a5887b917912129c25890bc5": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c85b9f1ab205a15aca2715d96b02d7a73d209132c070c69cfd520bf78cd53c50": "0x00c024e4b60101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972766c97b1351d499b8a075b02e207cec32b8f1b3ae948ec06c2ad406d5d4b6f2": "0x00d22374f95f00000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973651a29855029b51c9e65625930efb14a85295198900fa6b491187545ab2eb80f": "0x2280483e7614020101d7e03e0019d5d0c082ba9e23fc43a2a36b261bcfa5cc3b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397373f4622642eca620e9f018ee2b021c5ec06aef0d990461e358054308a1708ed": "0x0010b6c8f94b08000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397907a9407dfeec937b96854faca7cd893a209020841e86831221b877d1a27984b": "0x00c61bc45a0e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339795c07596d5022239a60e5a9379d1514021676ff6d268000afe63a4fdb241bd0c": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf6411c04ae97dd11100c003a24ca950b88c8b70d5e180cc068dabaac50812da": "0x0076eb7a9db700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a894f96f07fc032c8ec58c9fdc5137de7990db38faa5119802b8ef2d58ea25f5": "0x006859ef3b6102000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977fa223fbdf85099a2f5481390c5af289ae0f42daa551d12b15a6112c92386ea5": "0x003036d4980900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e118ac7996c4fe3f5df9d8eccebc43da0096b42fb946d3e7f9e82bb7edd18f37": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746fed281b0e60c97f8352898d695d29dac4c74e6deba4aa3bc482246722d95da": "0x00cc8e03df9905000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d2b47d7ca26aca8e52e069c5ed807cb95716819b26b6997c332149a0a02af5b": "0x00d6fa032f0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972780d72940d762f9f891b176b200ead3a3be9a3c5fc678138477506240b118df": "0x0072e669861100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978281e9fc03f8ab0459aeeeeca601867805b9e14bddffe4aaf32f659f147cf200": "0x001a5524560200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a67a352c89a46a6bdbaf702eeddc4754805e8943eaa6d53a49cd90fdec9e01f5": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339704b74a8845c733760075600099f12b48b415973f94fc42d5100a89c5e32498de": "0x00aea986460800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd5baf15894c9981073992a0a92a06956036e15dda3cd44c3e6e94dab331743a": "0x0052e1f8cc3800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c546a2c310f026f075b74f203288cf1af0e4903d980a3f60b8d519febf1110fe": "0x002a6809f9ce00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f05ba683de51950423f2316d5b48866c397b895d2cda0bc893205e7a8db147d": "0x005cd94131a700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397407c6c5bf0987974cfce765f8fbd2fffb2db41c4417c4efe30ee6066f33c7eab": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f697baff0e7d250ff05e64dcffae912a5cb9143b6d1e1a27f638035c319e5bed": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397107226de239a42feba3c2c60842e4db27f20a866d89fb0caa810e6e709daecb8": "0x00446b11410300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8361651aa2d8d51e690500377c4a8c37492a9e9e4d15191bfcc284add1fbe08": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975e73dc9eb43ebb94b9a750e139775330c6680ed417c1e193363adad9a25b1208": "0x0004e8afb70600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bc20c7ec6a5c75d5fa56bec16d7b1e17fd1e023326a2c9e909164f07e970125": "0x0044135e7e6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e9fa407bf499377d7228c02e6a0f680b17d9e68fa0e0a9a75b5f1097ffbf4c7": "0x004465738fcf01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e75128c35d22f459d77ca4c0b0b5035869766d60d182b9716ab3e8879e066478899a8": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455336b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455336a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455336988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533687c31384c062b7d0e7769b816bb95317e69b29b8bb8fe5e8e05113430b86f194788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455336688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455336588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455336488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553363ba9789e37ed91b3bea19b0aadb6dd966ecc12d337794f23dee8694b82bf6163a68d958e8c1f36ccb18e17e1151bbfa4319cb4fb578b14f0b74b8b28cb2d5f01f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455336088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335bf2e0312fee897977ebbeee65d654913d4b0faa1a16d235cd3eee31888aa5e45b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455335088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334e30599dba50b5f3ba0b36f856a761eb3c0aee61e830d4beb448ef94b6ad92be3988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455334088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553337f6463e4720c2d3108ec180d18df7c6f5ff2cd54ee4c906adb5b2d78ec054d04688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455333088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455332c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5fcc02be22b413442f1dd9118d85f10be80555c815e8372d2c0d63c3196871b": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799b010e47909783f78781b3a087690e5032a1b7352414ddd6d671848010dae92": "0x001428b7820700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d39daf4c38b465893f17d4aedfed9b3b5a73b1ee2dd53d8d03623e274254331e": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e6d4205898bc0226c3c4380d2a0f04a0fe54cceae2136695e8546b5fa9f60a55": "0x003ab9a30d2400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4599fec310528573a6765733e04faebc80e994713605c9ec819b64216c51b01f9": "0x005827a658e00f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769c4fc80ed1b3a1727a544ddfef5625048a3a21b799bdcecc650bd36c0de9f3a": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977e926895f3e0d77bd2d53fa29e7da9d7d22969e12689065b3632c680c7322716": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397acb6c146ac3fde79dca9f73cff1e0f7a024c14f978a0d98a262196d0523285d3": "0x00e6ea478ab597000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3c73969237805b18227552d6f761e1a4da00a82179242cdd19a4a1889b7ec74": "0x00d46ab4a84f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a3fd563a7e63411fe82df18d21b17c2c9675ed882e0e328d80224b4744460a0": "0x0096f674118300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397339d8acee851037b5f56524ac3b2efb4c29538685e5504a79d84c0a9ac3db0a4": "0x006e0dbc8a8d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c2c4318b82d5e172af42b14c1de07fde3b2d9eb1e85c66634fb86f6729c7728": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a4460ad0480a1a8fb463a897a36feadc830c8ca7f64b05b92f6b139e09bdbb7": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c03860cf3819711525144f78abde244460d917c72446e5781e69690060f09dd": "0x00786de3c11c03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397162ed5f13577445b6d58c11adced2b808e8baa89c463df4f90c2d100ef899c7e": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339784a81175216e36dc5a4afb2729055c4d563bf969573e9a9768e29fe02102594d": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e41e09e5944d19c80afd6f942fa571a3f9082e79d829e72b44abe16e8651001": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fec4cdda15b154c26aeb180b44e20bd712754dc35f37b9693b810c1739320f79": "0x0038b8458c2e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975fc43e4760c81c9c6c69bd1cfe246bb8a01da4ecdef746f9c8b9f6e93e700d28": "0x0044db3fc1ac00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b6bdce03c496cacb46f8be262e94c3d27882831c8121ae7c00adfebabcdb4ce": "0x00ce0530150000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd549442b7f0d2ffe3120a6f43666af8fa1f11382cc07921d7280353900bcd27": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702d771037f9579489c1337fef5789d5f1ae42c92dedbf53cdc9e887f2628af62": "0x0018b092324802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397edb5d8be7043b7cc67fc911e90946c6c0108a0e713dfbd7f646bf5d808653afb": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5b90ac68dc8932c63b473c8e931d72ac1d39a2dfd0ac186d1884a6ee3db841e": "0x004c2df6184802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397707dab37d36a86b3cbc675dd1723df8ee73871b8c1996e8517cdd4e55247e53e": "0x00d098d4af7100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397acec7a3ff8937f39169d47cff080d2068ed8d3979a3b84a226ba731070b9c5aa": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ae01eb5b17e8485443766e24f4f5b02e564ea0c796e3face30e227403717718": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df090c093eda1aba9cee2eeb6a26d5726313f0899e350541a7d51dc780255fe1": "0x0072e669861100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397192de8c8560588592baf7190077a3fea956fbc53ce54ec5c34c145f8552b818b": "0x00f0ac68935002000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f7e93c107c2c8c0d7e35a9f1c5396f7f46d195222e610e7b2347346098ca023": "0x000620e7ad0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0e4d7e06ff81bdc8d83e76df093a5d0197789dffbde9344d8428e039a93727b": "0x00e00ad64a5d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f027498f71aa382d2d982ece1318c455f2d80905eba6a282650228641df0e88f": "0x00f80a5b4e5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ba685476f5fae9faff2d3ca796ed2c0197d708e7575d1cf2c76d3c158b5ba74": "0x002acfc5745300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4127e01ec910952ceaf880274f705acfb9c8637c6f021de84a0769da6f9c51f2e": "0x009cb679bdef03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339721fa8dcfd60bbf559841df39f2c444d4171cb14aa3db8912fd7cf93230f34e4f": "0x00f8fb80fdbe00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a22895ce1636570d3fab9d2d87f7a2a1ffc2cac5b45850f33a6b1f5312f2c28a": "0x00725cb5f62401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397063fc894d8b03d48a236dd2a3641ab0595b29e41b4eb0e013028ad82363f5d6f": "0x0044135e7e6c00000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903": "0x185e3ed914a3f9da416f69613d98c0848a6435ca4bda8d00af53a8a5bf5898b9042280483e7614020101d7e03e0019d5d0c082ba9e23fc43a2a36b261bcfa5cc3b3a2b5aa8ffd4e3c5ccb11d342867d964414dd36e138de466f5fa6d865f19d6657a977e950acc55770b4452fc418bd59fc4ccdc25ce3c2d4cce58dd0d6f9a2d15fcdeb580add093f3b5f06603032c2fe89d329ba372147c100aa0391a44a516017ce21330f614e9f11065cf3e7e96207fec4086b7cb83584daccf6bac6d35d16c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975fe23a1a1a3ebab58a836aff7b805f830db0e2f85d846927f82b7e4f781e06b8": "0x00703874580800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243ba1ba137f951df73983d306bb783236caeb9420de73544761d9cc5908df98dec": "0x00d45be1e85b7700000000000000000020d96a8604000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339763d88be2e393b3b1d48b9f04e60e71f5accacd36e471953073961da1837fbadb": "0x007a55aa1ceb0f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794e6e54f8f884d0b7135259aecab5ab9c3aef520a400fb5dd21b7abdf3e0ea53": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397149d6ef9c197e6cf9511716aaed77c5be028a30873f94a0cff7594d800407d33": "0x00d27183e3cb01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339711333f85628915dc70bb49a027fae512a93ef22887d6d725f8da6287e4eb9f21": "0x007465c1f55500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339789704764f58c6d623f0c3fb51903a4e846728c9d054d33a3fcd8dc12eacdf5ff": "0x00bace6fd90a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705cf70bac7fa781f71a033e94d1636122049f98825481d22340a32ef640af116": "0x008e713b42af00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a173a3f8ec0d34834f2d4578cbd65ca3aa7161932c62ba4c3ab5fad841ac638": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979391fa49fb5b47dcff88b624e59aba57ce6c2f389bc4d88c82eed0740927f042": "0x002c490fd71c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c60a8584236620b3fd4919e33f3712127ffe563f726cb90eab23938ba9be709": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ed1055939b52506e3ff757ff4f119c4dd7beac26c5f46073e881ef1b2d9a45b": "0x008c114007d103000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c3e67fc5fddc0e08757713ab0f9516b25778bd2f1307b2a5c5a5aa454e792554": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f5d075a496ee9b3d45f0ab7693dd7efee37835e227563fbdd9fce6b076dc6ea3": "0x00fc31262e1900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa0163acb28e9d09950aabf844f4c701f5bfadc0f1e393c7b449890aacca50b5": "0x00301a45ba2900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f877ee273c23c46dc9857296921668b3d3419c8c5e8a8cce7cb389e6dc1e0544": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7c6b5c9a7001bae120ad5f0408e37ce51fc05f5a88c1a30c5db7c8263ed9bd9": "0x00ae9f92970000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d400ee29fb1a4b4e3a9175026814457ed3a8cbddc0c710396ed4463ec3749d9e": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f28d4cd781977ef7c7fc7e1bac68c42e00d7e1a4e89929f182c61523e75b637c": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb6e6681f202fdb456ed1a21f828f869426f59e1a91a2e4a53f2bdf00cf96730": "0x00ea9551ba1f04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa0a89ccf5811ee759da4236214826a1acb15c5713a8597a33f09845c4a4849f": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397730cfca6e2ea772ba25e2d0ac6705c9cba8fbba5f3c574d89e751dde96ca2615": "0x00a8b5d34bc800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c3ef24c93c48ad51c8416c0b531c28e9e007c86323841514ad38e0075a46ea5": "0x00ca91bb010500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979703bd44e8195606e27c561615499ef3813ed6073c571d0dc639d9a9c5f18666": "0x00b2e809461000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397caa85ca18fa889bcbb3e996e6d33f7cead22557b6cf97bdff4d29748c879285f": "0x0060a90a611200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970790fdad1c905ca73a0a04e9cc99a41ea3c03a061036cecb1d5c9cf312f54d76": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972dd7ad71737b58891dc39da1a0b2bc35f7de4f2cdcba7d5026aebc03e0d38bfa": "0x00b2e809461000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b19b7f77634d1d15f737ef4be8ac1664b976cb0123944f539b6f828897f1543": "0x0010b4426f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773574e373d7597939e85461816911019bc640d5757bd13eae06c30441359d8a5": "0x00dedce2d93f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740d5e6689926da69fa835ef4d4dfdf3feecd70e7b00aac20b300f8464db4cb76": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a70d1577e80c112e1793b63d80ecee7d1be2d0b113dcc1cba7faf64e0c2b492": "0x00008a2cd1b701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339762e827a0b82c6f9b6a5defae4591f214cffdbc6b2459a421b2e22e8e1a8cdfa6": "0x005ac97c261100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243f24396cf480380c0ccd36f802680f16acad9e4d4fe5dffbb747f0430db9cdcbd": "0x00f45658a0d7480000000000000000002029f5c202000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cafb1ed23733e64148bfc7f3acbcbe368b65718b4ff1bb6bfbe04c66e818c0af": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702471d3a560d1fc3a87e1802f15fb8331d2bb69f0d7a732a168b7da4ed4db22c": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fb0b9926e06c293cb28096a173622a81831ac84478b7630a2242564d59bf16a5": "0x00d8a5ccb34200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4829a684286d7ecd53a281e19808cdd2c2a88bf7095f527b018b65f1a9b3521f8": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba28ab8ec49f11c360eaf95d35c2dab5eee64e3b56ae3524b85131d5abd08b15": "0x00b28ec5f5a701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fffdf161103f30920d31d06d427df6db048e1f85c3afe47c6274fc25605f8594": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971eb8cd24f2600599a9fac974bac5a8a12f90f9377cf51d00fc906651f18c271f": "0x0066497f817f07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397379cc7259683096f65d64e4bd18366d4d492871033a72ffc738baeec3b6efdce": "0x00b602b4cd0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1f9ac2b540830b7ee31a8863fa4f01a2f993b02785dd799776d6c05cb3891a0": "0x0048513e650e00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b48db008436ea7561a88e53edd54721bcfb499207ae37f901d78e410bbd07dbe77": "0x00a81c90c74c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4adeff2f6f22d23f6d20ca5276c0a9d68fcdb548ac7185a2294c70aa7c8d936e7": "0x00ec5e19a2571f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339752b92ae6cfaeb270de7ee09e65ad409f8c9514ab773e3217f3d59c4f4aab2e24": "0x00a816e30c6014000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b439570972e646c4c3ab1c6a209c7dea9a527f385fd420a2be54b03e39de869129": "0x00d44d82b10900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c9dfebc7822a831ce0ad7634862afceec173c807d93388a0a79a8ea2274bdfdf": "0x009e3f8afc9f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4408ff7da2184c403f9592d8935e97abef2e008e4c0581ddef8de5c8b610a364b": "0x00c6a6060c2001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b7723ee03b9d4e2cc661ad8bb7769a645cee222f8059c847123f4bcf36b76d8": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aab39ae4bb7d5b590149d078b0ee5ad7c7240cc9353fd41bbfd75921334b6efe": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a990a8f02334cc6e7a9ccd9da7507f34b392389e5dfd697b3890b4e4b6760b14": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed18f72bb0581569d91b07e7cac127f869246bc466d0da4d96a11a7de89b1625": "0x002c419ebb1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea4aaa3b978063c89bda6d91f69a8552f1243ced5c31a6af22a24ca6b19484f2": "0x006cc682d80800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005723600c71a4102badc748960f23cd577548b57c4124542921988cc02530b2": "0x0008db62010400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f98f1110d7f9e1e5ed12e373be37dd603de7fbc697a76a7a105ea4d94e7d70e5": "0x00c48d929a3500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b74958d099d6862194dd20f0ed771dd57b77a6ff72c59308fda3af383a484311": "0x00d422a5abbe12000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ccd5f671f0a9e97e43d8eae5a5d9ab954984604dd90c56d68ee2366ae67e7546": "0x00dacf383c9f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4410b9d33a74f4434b0758cd00cf6324ee3ad96b4160f93aad4401395be66c078": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977bceb93c115fa6596397e8371c3e8c40c5dfdd6d828c8cd140471bb4a3b37fb2": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746445b9f2c1bfcbacc5f4e03c2a9dec0491c2029cde7a53077c333093dc48152": "0x00fad0089c9e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d150c66ebbe320efac2127711e293ebfbfc336211f576aecdb63e6532790a4fc": "0x00e09358064402000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397823c4f4f17f78af27d2457969272afacba49b701840511a4c38795461d272e77": "0x0018ee47a4d000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282435e216d3f400db7137984cc7a81d4553c7de1868e8ef21a66fbd34b8b836b78f7": "0x00dc10ad45b20e0000000000000000001f0da28e00000000000000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42282f35e2b9e7d998af4e3e89c62d6d8492824bb417f5bb4a724b86cdb217227": "0x0060aea3230606000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978da9596af672e37845015abdff7bed2f28bf2a9f636aa8440fa5f77344e0017d": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dff67d663b33dce669b4241919b344bd05a954957727673129e68d74a87800a7": "0x00e070e8b01000000000000000000000", + "0x2b06af9719ac64d755623cda8ddd9b949f99a2ce711f3a31b2fc05604c93f179": "0x18ca239392960473fe1bc65f94ee27d890a49c1b200c006ff5dcc525330ecc1677b46f01874ce7abbb5220e8fd89bede0adad14c73039d91e28e881823433e723fd684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e17968195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e9411a0575ef4ae24bdfd31f4cb5bd61239ae67c12d4e64ae51ac756044aa6ad820018168f2aad0081a25728961ee00627cfe35e39833c805016632bf7c14da58009", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ec03ff4cc48a427553b392d43eb3ca552ab2ab233c8d85f061d17919a9a833b5": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397639b149cbc9e9a7f15ab18e8b0bd0d805711d8758e86ca3112bb14d0c998dd33": "0x006426b3d1ba4e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978509a4ef91065a3ffc11bfcbc82f5b9d5c8f4be1a06c4339f2e754da8cc677f4": "0x00e49d354e5e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a533768d069abdcdbea679b895ca603836298201324b3d2c2c0b13d37fab6735": "0x0060800fce5802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976294761214c1838f367b5fd9d3cd26ac05a720a83ac638e36f50e33ff8e9e92c": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339719ba9c2a5b2e8232e3134d796a61c792fbb0162a46dd70a6487a881507fa8133": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b367bb6b46e5469271c2be524f8e228f3bd0a378470dabcd8f8f4e4e8b8a273": "0x00e0fa29790900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dc133059c076530f80eec8cb304f1b887060af1080e6ce20c1c9685f5ac26da0": "0x00fc6276e83200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a5f14faa087cf4b7214600cc4422ca96233174d5699c23b9065d8af687185df8": "0x0044135e7e6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d03a1e3cd9102aaf335774b02759da1cd19fb0403242fa1d0c68a0be6f95808": "0x00b4a3ea662900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8d43ab62778c2fb2e8fc605750435be7cc1687a9dffdf7df11bd24450169dda": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe7d09121406ec3c5862e94d570bf7ee5c21a91455d2148864e42628c86b3c8e": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e51e3047f2b1e8e8901960f37afeefb64d3f2ff6ecd9e9c004945ac732c7ac6c": "0x00ae9f17c4be12000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e15139dad170e12179a1bf9dbd2494722f7ee4d0005a31224e701a033628827a": "0x00ea2314e21e0f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab70c9e4c9ba4b23180ceb4bd9209c45b760961879d9d1c4627c429689db2143": "0x0056c78abe6100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40602191be8ff628474bd399d9b1e0a01848b5f93c50b4ee99b812d190cd8f71e": "0x0078e6bb2e4300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4baf8021ce9973e4b759348823608d188da29b10989abd4bcc402a60b42e69d30": "0x00008d49fd1a07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f7623b6c38b24df739810d19271abdeae427273cd3fe7870cc5fb21c23788dfc": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785d223265c8cf486c429ab02da08cc5602f3e61e67c4eac877ec8cd4f7302586": "0x00f85e3055e100000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b405d7fbb287d2ba8218397b7f742afefa9903fb99d44315e610dc6c9a7de121c8": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971db67dc4dbe993e3fd0b951760d3278a178c4e67e12153e50a30e4cf311bc6c2": "0x00baad66232700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977813bd920b81c89381e187c4b5fd0822d1806250e90157facc7cf7e4b31ecb8d": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793b25be909ab94807896723e29025e5295c8808e935be384c4f015a3443414ec": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa4c27d8600189b293b464044e5583af003c0840aba0aa719434a0901b1821e7": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f1a838aa360cc94e6cab9f2367e420bbc9470d04f96a2156669b53026b9d10f": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b02f97adaabb2a9c234f1380dfdd3a9dd98d85c831274e84137c0e552a584032": "0x00bea716d82300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ec9b089f0eea22927d8c60e07ced495a9781978308fd304b1568a35c1c7f5a6": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d2f7d54c84b12ed968ecbc23847224e5f2200896a36990b0faebf79dfb2fa64": "0x00fa999bf11a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d87e708b8a7c8ab3be6b074891546a0e5030c6b3a893bd3e3ffad7b89e594485": "0x001a489e301000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b5cd562c2f8851d60bd15acdd00841bc26a18e42571f043562f177bf874f3de9": "0x0082357a0a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d14cbf1dd448bc3344d49e7bcaf81745001d767050e3e4e5bed5daec593950c5": "0x0006bb3ece4d34000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971935ac71ecf35044b9d1dc780aa7d6388c363a4f0393e97a3bf910f708f1870d": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339734b6af34d230164c9b7d515ef1f933d42475fc0021e03c433d0c1a22601150cd": "0x00380fb4061200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979524e8202f1606ea65aed333cc5b32c78f78ebd7d6e82f1e66e3b59cf8b3fdeb": "0x006297f4340500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973628ece1e5fad966ba7826ead21066f5a6d6416cb4bb7761035ca933d39a7735": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4809e434a88f4a74b9ce918615646d07c3df4203dddd60ed66f0321a30730b0": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339711dee95e030e5afd538ae15af086e7035af5faf94b97e8c5765ffbe2f1f423bc": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397830f34f5c7fb7c45773c4fc345495ebd435e9db68d82a8418f2fcc63f704e7d0": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339741aa105012aa6c67f3bd2f1666a21f179ee71adf575343531707ce4dbe2e1ac6": "0x0094bcba878500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f2860d0c4713681548644720dcc090847062e1dd69e19885984f6e4b93cb0392": "0x009e095b9d6400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f36e37dd4fd19278dd288815bac80f5ffe9333860d4f14565d8510ba08084083": "0x0026028fbbd200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975bebd85269693880cb0a937f9496d8eca273edb62f800cd73e27d501e82e66b5": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970bb6f304fda497f81c52d9abf69db966c8bafd0dc9ec79103692911676f55882": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d597748564650dcc76bbf5c526a1bbb8af07f8e4eedd39c5fc8015949d3a643e": "0x0098ba69660e01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aef25ffe188b099d5d1bf6244fbfe4ca362649870489570c4bc430379c290918": "0x0020034cf68f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43498070a82874264c14dc1d723bd7e89926a1abe299fcd56b37e8a7c26d71689": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733f298a5b8ea82b1c5bb83470def78391b7b212ccb0d477f0781a4018c897d86": "0x005cd89e184100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397844150df076993c12d1cedfbb4c89dcd28453246c405d051723b4613c7286345": "0x00d479824c3c38000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1adfdbce4c5db862533bca407eb514f38e075e68270b66cd09d28691eb5c302": "0x0022914e4e0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b2a16e9780f553bd47ea38f73c72cba92ea4b4ee35a9913952d419ed00fc0060": "0x00883676c80200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41259f61aaeee32ae5dd4ccce582589d6ab6004108ec8922e0519a389fda4ada4": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c6e261fe0884afb7ca9c13d2b107999a4d8a376ae0d2fe4eb93ba8da4f5d976": "0x00ba4f31a30800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4bb394cc489dcb06059cf11db48e710d9b3023fac0f118eb979ac44713220b097": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978c9d46c22f8e1c3d7f46f719aab6ac5955610750f1c8a25067ddead329ea5d6f": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971dced4b184beea89cdd546586e818e38e404dadc76b5c72a7dc751fc5ebdc36f": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974410608324086d5d6476ab0b310d3df05a7fced0244bc9fadad2f0651f45ae6a": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339758fbdef219638f9f693fd641bcba4a3a58c689ad26b20cc40f4f2c033f23daec": "0x00a031a95fe300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b49f8069a46abc41ecf5e3b0e40bb551bbd0d79ddd7658d19228f44f86582156f0": "0x00d6ddca3a5500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af5904dcd95ab46d3428c148fbd795a1aa193132b50ad44b0dca82129b222490": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727051b881edcc13f77007f6342470ec5e0716fd94f4bf596743baf7614b5c643": "0x00f0cc775d8600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6421ec42520a5f53f0ceb5c03d562d4dca5a1d57f3db76722c61c916dcf237b": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976237291019746ab5300a69009846dd67c427df51275736641a54e33574dc9a9d": "0x000a31a56c7600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a366ee70b3e11f8e046d04b33155132c002b0f5db9d000d861a0cc17c565a0af": "0x00d815f9b05805000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397498d0f6cdd0013756e9f6dab29eda820eb7eb21c8d1d8b7dc38926c7aed09399": "0x0078ae926ef109000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c824b1fd9c7fa47926d8615230a2952622732f79b2c4062f3cc2ad70167895cb": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736344dc8bf108240f35eaa9bff7d7ac66ea83d46eb13e695ae119e6cbb49561c": "0x006e7072df1a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3582149b0f510fd087607e1087394e91831c24a899f322cd4629513c603b386": "0x00e83abf652b00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d2634022e475e676e77b8733e5a8cccbb874c9b7db0712e5eeb6be2365abbc0c": "0x00321bb20e7329000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb76fb5f19bca17dd83c5d43c12b0be4bd35d85d18d21e67299ae32ad0b08d18": "0x00148b66da2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef4db7edb956b052546169036d75ca63d9c4dc45818fefb2eb11f2217828cd86": "0x0022afc58d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a71f1b2311ae8a086ab3e4c910d3d13cb960afecce074e8863db2c5789ae26c": "0x00087387252706000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397163df7203b6cb1b6a87fe579f8a0e3f34672576fe9240e5fff0d52ce55ca83e5": "0x0042b095ed0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970999fd1b975746c5fc9fec6e700a0dd80e5a6a82e6ec5bd0ef08e21a1a5dae12": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb9ffa3ba293a8f5cf1ac0d5c72023633a88c052e2776daefab128fd98b37950": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397361bf1273b50f25ba514dc2e28c71acef700f2e1520787e6c00f5a17bd0598fc": "0x002eb47ee85100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397753a0fc3d4337ee84d8b363dd6fd01de563d9fd85999a8e34d0760d566ad4bec": "0x00b4697f7b3200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972e84e687832e1b6b37b128156d3f725716c9c070744886d6d36c7e3eabc9fb93": "0x00865401b47f04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970dac6c54c1404d38dc5ff021d5b50e71f5832ac53998e31fc989364d67d0dea2": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e27576a474c823dcdb1abc02d118018e1b520ee2bd7ecbc1b28eb60f5bf90812": "0x009e4e93b58d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339710b650f637884f31e2e0245566f18db3af1b9fc3e1b2e3856efb4d35051e46c9": "0x00742024100f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b1f1f7fe850b36f72845a6a757dd51de74b904023b47bc1d18a8bef2b050b507": "0x00eceba11f6803000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dcd83959e0cb6731bb29b14619f03da39e1e8d0dcef0068d0e3d3f4afe517e49": "0x0024d4d8ace401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768f7261a19a7942170e7a0a0107a2b48133422736eec083d690849c1647a176e": "0x0080dc9e2b3800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339760956a76de7bdffdb6d35afe3d4dc8b97771edda830f511a48d524fe15b3f759": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f4ba6526817b6d0a5a0c0182ed76eca0fa489fa4e5dbe830da76cc360c5dc3e": "0x00749f62461100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771139284b40c73a146bffa75aba340644e80ba2f39013efa79870196fe8803fb": "0x002695f2b11300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9da0820d34dcca764eaf033b588a81985cf8b9e8cea8a147fa1fc71697ccb7c": "0x0060f86c8d0700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d4c251397eb79fb614bdc01c1cabffabb11a43b11c71e43e22227b112f9cff46": "0x0040900e0bfa11000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979fa3fb44c8c9246dcab8f3f21077df10080d7188a45051514dd8438e446bbafd": "0x007c97c8d60100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973b18d7b5724ad95d5d3b20959bda8b31c3f9b6891fea48f01ac305073f3de66b": "0x008aa5136c1d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f547c5b56e1b83ed49b511b7643942b86785092693da543788f499bc51ef738": "0x000c6098159ac3000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736dac60aabdd58cab5400cb79ec1bde9b58fd141537f6f7fa79f65b5cab815cb": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397621b569d0d60b988a51d9e9048ba67b95ec6373cb04574fa4641d08221a59645": "0x00aecaf4c90900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b49530d3026aead41bcbd7a210f4774ca8ae9c9eb0b32e961dc0ed35a5d0969d1b": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f44f3875bc7e885cd983373c33f8e7517633e3d0aa2d9a31db362c1f0c740c2": "0x00eccc45eb0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff826bdba22a56f109b19112937b0b21da5892b463c0db1a18cac4267f07d2b0": "0x00fa7c62fd6900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397219572a66339a14ba9cd1618a2e86931fa368bc6d4f963f862cc043b41e8af16": "0x005a1220334f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975774340f172694dad5e61349fea2460d032edba181a931b8c561281d254d3d4c": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339721a62207ec1cde8bbd35db05424dda6164568f7f7bc01bf81609473a6bbd4f0f": "0x00ec4622388506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783258ca32bb04f476298158d13ce38913515b80903a399c89b97152cf2644f96": "0x00500a82d0d400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397de002d583dece901bf213ea94822270646222498bed02f4a81e4523a901eabd6": "0x00e23c551e1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f907659c187e5e1bfe10102d26161f0e794632da72eddd96b3a8407b36b3ca1a": "0x00ba589caac201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ae495d501f955ee9c608627ad28a8f96377419f11380460b8baef83e5b3c0757": "0x00282e48726601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e4d35ca9c91e104c71c304e239b7ef5d74c1f46cdeefc13d76ff33f642ca061": "0x0004f52ee08d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397676566f43e1788c2aff54361510ae726c5f51d82f39b02350a748144cf764fdc": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397807dc8f5efc77d453cf6a43440f72401225eea5a26c879b531b873bddb84fa91": "0x0050bd21761103000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4833639d883659b173ef4a85be5457ebc3a1311bcee6ffe5601173156fccb20": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee46bc6fdd5c7bf3df032bcd6820581c63e00baaba4e6abe0787be0aade84374": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b47454b5c51f9bab7cdc0c0276c5cef873810556f299b3efd37399a4b8c1a3770a": "0x006e36bb883b13000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b6b3ee90df3b0d13ee3226b27aab53a83fe327663110958e4f70ca46bf25ac25": "0x003e7d663fec02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972cba2d2645924c4a33f8ed2d64f998612a7420cb271dacda0dac5493e9ef8517": "0x00a05a8c338051000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730f3c09df99bd678931847dafdc94062bb7b934ccb7763ef2815ac1af52f589c": "0x0010d733860900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4677da0cd006d1f41898d8564573deac8b952e15f8134457f9cb7b0bc945f8ec3": "0x00bc915c481200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4e3e9028d03e6acdad7fd80db3ec391b991bc4bf031eecc7c9f01a1faf42757": "0x000ea4d437be00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397081331bead78c35b3c317514e2c4f1990a1a7d729f904ca2edf0709bcd782253": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397785bc43999ca51a18353109d8402449a83dd89f2bd1b60f47370bf2f847d786f": "0x00fed5f1475600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40ce7aef4ab9db244456aad87ca1cfbc8daec198b1346177822af60dd13a175a7": "0x00f4a811ff4d27000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f624471835b0453961e6906a80afe0b1eb2e1f90b84a9aeb8632bed50ee8f33": "0x00460467015601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774ffbacb37577f595a4547b6c97e281a65f3e1093f62684c38f7b31898bcdc21": "0x00f87ce4f60900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972feaac7cfd80b406d7a9e47e0ec204a6f8ce3359222dda7e7d19dd190d10a2f1": "0x00520c259a7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ada48c95bb2ac5db3a9e3e3604fac06f55380c476bddd1dccd7a6b408dca1cda": "0x00c4463cbc2e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f003d48501b251518c2cceb35104d8d8b7c5211917af44410259fb46f8fef363": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd75efa2c0bcf5fad279a5a603f5a7ee02bf39f0483d7d572ae1dc5ab9e5f77e": "0x00da6352bff302000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b979305a9fa67cf368d271e3caca9bcbf855000cfaa23e4a787172b6fb20c4e7": "0x000cc18f250f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701a1926aa4c3d61a127c727f24c2fbfe765d8e3cf747273253337a9f6a2b09cc": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339759ff8071472702b5ad55aaf82a61a94dc1c15c7d54cba2c123f04bd8deae529d": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9e7c9488a5606622d83a12f4a11a8b6132fe47d66504b25828d3f94068bc6dd": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c387b03a097de9cb4d8c81450478cc9fdba0966156451f0e841d0f8e77e70d0d": "0x0026da6a887d25000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339714a3a33ca3547a9bbb03cc71897f9031c3be7e81a6bf010dcc47870711acfde8": "0x0092e5b6521500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd66a6e33f989ec822808ce98446a081ea4180498625ef501b0b7a7b172faf06": "0x0062844325d300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a9dcfa727706f710ac69bcf9ceb5486de66b28587ae56843f38de2b475adf1b": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e6b95ebccb3dfd5d59a53ecb15da6adc5f39d0e56b84f92f83d4fd125f82828d": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec042500f780740e4730e2d04b9acf7e187143de6a9364fab4a0be626ab857dd": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339713f2c4463411468ed024534a97e8a34fab4e677c70870448b0931a9f20403eb8": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339776af85bc5777465f28d9a8fb2daed5d0bbb678f3c68942acef1e3c994e46c520": "0x003a970f2d5f06000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41c79538fb87a09de261557bc1de0720c0fe3295b4dcaa78611f93b02c14188c5": "0x0020e464717e15000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975e053cfaf45fb940c904731172d674f119383f84b45d44c76f53f386680f4b8a": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d918c1641aa49afd519182e7f7155bd29662d41060bbb03cf36c659d857113a0": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397270752166b2caa3ebb3c8f1e897a7ed217786e54fbaf9d6c692b77257ccc2e5d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978aad5dd4961f735a346e678f9643b9dfa69e5422298d6d4bdd4b81835faf0b4f": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970e05928c130c84373d1ef77e84f484fc17d16f4d6468180d4c919cf71988a760": "0x0016365ec7bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975350322a31225612183f5c45776bbce3a8fd7b5a7c2aaba2f96521307e03bf21": "0x00289650330900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c1d78306f04f9aecf0b5adfcb94ba183eddc3701c3752e42e4e57d7ff2bd818c": "0x00261a1f702600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6a3fa4196d38c83f3380f91d32172eb444ea365886d2e045245de7f0d864e84": "0x00e0abb9523e01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b218ba9bc1cb48a6fbbf4b994dbad3f67ea61bf5323289ea90ebbada959bb024": "0x00a65f83e67f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397798b87a2c7417c2a5f602c3d8df0cd0d95678a486c34e1309839cc8802bfef46": "0x004cc1a554a700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339796ca715ca45867f5489275b2b72ae222e6d0f7a01dd38bca00162b48d676cd94": "0x00b61557e35d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2578a0cd5a1e0d92dabfbb01b4534d0f2a9c09fef68f40071d751934ac83e0e": "0x0094f9a9ef9001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746f530f59b9075feec4e1f5345584f12cf262759d79e9bd087949e42dbc71a76": "0x00e070e8b01000000000000000000000", + "0x8985776095addd4789fccbce8ca77b23ba7fb8745735dc3be2a2c61a72c39e78": "0x0c8478f51feef5a376deda20303e61c855e0b96451f692ead53d838130bce9cd086c98dfc795cd34290966dfa3a4f690a2c703dfaa31792854885295a61cfdd6708a0e42d190d3ecaebf11d3834f4b992e0fab469e6bf17056d402cb172b827a22", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46d5fbf6eff824b075795c381ad7b5c1b8cec6a59ef046ec7bcf8418d9c87fcb8": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc6f979e36d2f845dd0edb8d356d4d9fe73036d6a41fbaf16dcb49160e9d8e25": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6bb8ebf257f800c1ba6919fc9b0affda34473bb16f07cded64d7350e5b29dfd": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ae472ef56c1f2a980a334a6f20716cc8ad8253ed872fab37b3a6bea077429379": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b1e782b9429d2aaa39b60135755af6d02e0c00ac6a98e79f09402b1d60a5b500": "0x00d4dae9256400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a2bca2bd3e9975a2c338bd68ec164dc0de8d63700e4796d1731ab2d7e74dffc7": "0x0042e07d6e5703000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778c3feb21ede74d8c7e50607a2de9c0b6626be768568c280370655e9419dc008": "0x00fe42f31e3301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971886119eea70552a4fb887bad9a56740efdfd05638c9b96fa99ff08a6ece7bc3": "0x00309112d51f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f601fad2ec0d84b3435f8e99b88b609175e136d5fdc91b76cfa73c4299adbe3": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e751226a08e4d0c5190f01871e0569b6290b86760085d99f17eb4e7e6b58feb8d6249": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533ab4c8a71bb3ebc2c052fc592f1ed816a76a38c3fac9bec6e78a20859b84e39c55b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533a988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533a888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533a788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533a688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533a5f52c03336ce008911b7a7ee42d09226495b6615a0669c638598d7a60981e745488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533a388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533a288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533a188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533a088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339c02572939d97f5b7b7e9131fc6471e52e7167a4fa60f603b05d7191b2f4aaab4488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455339088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338a88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455338378afea5d2708b19a7b52836a12a9be3b29d333f76a22405952c22d1c6913f72b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533810c4c8ab4da7d824e44992488316b5e19086758cf0d11778eb46947037de4444c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455337f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455337e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455337d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455337c88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455337b3e171f99509173fdcf801b04b99c5f9b7223972c97acfb610a599af2353eef6a2ce76811e623e00a9a924b1c97e5e914d920f63a02078aacac0914f5353e460088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455337888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455337788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533763224fc332242a93d466150af8460afd740f79e14150640fb2a216ca1844d0d5486c0d8e2d856eaa6efed981f15d07f89d1598e870b62cc7c61fb464f943b961a4d58a9fc7c2894b0f065cc6403246fb7970c2448ecd0e385e0e172c6f3d3eb4488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345533721aaad9133956b5100150de82a91d8a576dcfb63fc7dd0d533608398395c6d05388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455337088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455336f88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455336e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455336d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455336c", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243aa5cd4b3ced035011fec1d41b3e4ef15eeb7445794e20feb20f017e6f15347e3": "0x00bc15368e363d00000000000000000020bd175202000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da2426805be69e09fd800a81efda6d3730438ec2620f658220f2eb3037eb23ab": "0x009ea646782400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e720bb6ac505c8b8d4edebb9e518b9bd6fa6a09483c1f3e287710c94e80278b2": "0x00b44bd2d67400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd68e50eea0bf231276a5b52df8490f79b9a1116a5355a5a1b813680769aa725": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d78deec53c1720d9bb326543d2b639212bfd3d2f7e182179edc81ce55212de95": "0x0074efedc60d02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ad053fbf26b10d7c06fbac2c2006fb90170f40afbea356cdb93c50372357275": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339795f35e5c641f844d17f559c9c01414fafb32da0f02518ec4ac17bd61c26a4aec": "0x009a3f588a1b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975476fd95b5cf876f18951bef1267cca68c8778f1f99cb34826bf628f86367b47": "0x009c1a62e68200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339710e4b7e7092de9077afc9a9292021fed8aa18a3556e1327bf7aec7479e979357": "0x0006e8c8f04800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e1eca5294c3fbd3295f4cd5d45c0e29b41ca929bb4105e2061dd639ee398c04": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4e21a2e49eceafba47f6f8cf2cfcb6f6c723b102377ad3ba1079d858bbe655b": "0x000c5849192401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ecac0c22fbc522be84fc7319d64cb747ccd02cdcb61714d0378b1471bbd4a87e": "0x007cfd09a50e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea0e33fd75d64ccccd1e4f527f0ba63639b04e76147b8dd9b6e031702f34267d": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397464cb60f9442263bfa06c723f06ac45cf0c74ab417f6631cdd8bd3be36809016": "0x00f4e9112c1501000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397efdc5371750682c75e0e3dea9dac40e4996418e5104f434a7da9a3fda7ad1965": "0x00dedce2d93f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397584b4030ec470fae470e152dd3d0218437102b5602e6cca6db5b5f82ddb65ed7": "0x002a80fe7a4000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1794bbd290bae43f89507d831f33ee70aa5b68dac2d3c28463743d4bf651ea5": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f5c90460885316f7929ed14e47c2b75753c15d6aa38ae6a2f657145eee2aa1b8": "0x00301a45ba2900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40a9fb27b563d9c4f2b354a487237dd99fd89ffeeda6a74a0fa307f5d33b040ba": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722ac00a7ea1f3fc4bc6c3da93b2969508888c3da7c97de4e78f67d67537b808e": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b5aa43abe176fee551d7c9479c681fe776d870f1274c663690c667d2d5825737": "0x00da88e95a0300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c878385dcc29699e1a40d96c79573c7959d2275b1230141ed7401d15ea944753": "0x004ad900dc0c02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc57389fd633240ace8b75f242e977c49aa0f6b1c3423b9a86dcf16a11d8fc68": "0x00a4289f320700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339714cd367044990b5375955ef1080739a8c7bc28dd00dc62b2e0b23cf2570be4ec": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397976b67ff8cfa373caa75b75a296aab7b32a6d4e2573f185af993a253145c0b23": "0x00a6e052aa5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974703f3c335b2c2e08eab521bd40f6d975fa5e0d7c871797bc8e8a03d41432bf2": "0x00566411cc0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786d77f3d89980d1c765aca9c86fb8a81c97c019bcedf0ba52acb52c8cafba78f": "0x0044698ead0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c065ecf440749bfe59c8681cdb8b9a3e2da8dc493f0043bdfe6eb52ba166312e": "0x00449673730c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397766b80f068405ed28118c4e9dee490825b8178d6f39b9077a9b5298a8781733f": "0x0044de13149e03000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41037d2efe6f18fd28c1070b8e65b2b7b5487a505662e5406964dfaee106d186e": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac94aaea1efa51372c8ccfd3912422ef45ccfb48dbeee017fe67d832f42f85ef": "0x00042c3eba5e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc725755363870af28d97ff8bd6399b22c9ee4e93b6fb912b62331c4f2601c37": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972096a89785062d2ec8c3b4f1e965a2eb52305b0ddc5cec89cee3f8f67cb22967": "0x00d6e5f7f6c601000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ab129cbc6b6d789b3150f5baa31706806ff89c0a4ca8d416d88f491eb1989615": "0x00da49aa61b26d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d07cc0b4bf83e9454c737da06c1f827b8e1e7051466fee363e50c783875050e7": "0x00d8d7433fd006000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43fda6b10ddd6be1decb4461c1eac82a19b3d7375fc020f02a0f21d9f69226804": "0x00d6d9e581e101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339780154059751738c853acb8fda64d5c72409e5c8654c338120c3de715cebaec9c": "0x00feb8bf501000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771a103789fd66f124f76989d69f5a40bef0aedf2b3a93a1f331cc33c39668e5d": "0x00f0cc775d8600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1b9c3852bd8300f3d408a97cfe37b90e7a60ae97a7b3294af7d2961da8c554b": "0x0084e236679803000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40c07a452863140d440fbefe7743193d869dbba52c25ba41681b7a72d2d9f6ac9": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e10df2cf79a503029fd20b19e5f1364b7bce571277ccfbf353f90e173e420068": "0x00dcd1db054800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b661cf96535c01832be62b34414c83a9c6972839d25a9803ef8ec1813b404190": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397459663470ed5fb78a0f9dcfd07b2bd9e9d34a32568b508e51db24a95db69e237": "0x00a26a5406f200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a544b8c367dab7a2fa10092b1903eaa7f55ab881fce1b9f820bbb75d616d255": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978747917e671e787e4231e5151860d0ec2c38b8f1ae808bb75b18d918b267e247": "0x00203f885c017e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397db931e6785815436c350c8b7391b693b2edc788fcbaa6e1d659402823fe4b229": "0x00e03b8bd29400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397473a6cc04b8672a0000a9b9b7ccbfa2b102bcae7ec4a5611b85d11fa54375f01": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339721a3a7263410e5607ac06f920bda32e5c40b9b358c11af751c320a438b04457d": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978b9e73e91f841e6329f85d2cded1d3936efe923d15a010a3099a03132ef53cd3": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e17cd1635c9a8578179a3ca619750564e9cb2588c2ed25ff01f3621c2641dd03": "0x00fcec52e30d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397732b6b9d7248f13a054a6cf6f1c2d0a850f690fed62abc72ffd69a201495084f": "0x00d8b10d918100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d65e66af0220f2944656fe7d8ba2f069d7f9dc58f424db0a675d1c77af69b54": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339721480fcc1252110c2a9e5617a298d7127e9b9bf0182103ef62557bcd7f062c96": "0x00ec4622388506000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e75125b8f29db76cf4e676e4fc9b17040312debedafcd5637fb3c7badd2cddce6a445": "0x010188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ebd05764432a4ebcbe97e8b434b0e2a25c53aaf9ce32b1218b9d472ecdcd0d534388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532e988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532e888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532e788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532e688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532e588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532e488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532e388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532e288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532e188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532e088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532df88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532de88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532dd88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532dc88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532db88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532da88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532d988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532d888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532d788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532d688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532d588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532d488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532d388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532d288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532d188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532d088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532cf88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ce88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532cd88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532cc88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532cb88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ca88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532c988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532c888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532c788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532c688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532c588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532c488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532c388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532c288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532c188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532c088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532bf88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532beb2c8872393487fb35de85c2d12fff24c4aa0068fa4cf3da82e9bf9b34a85e56288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532bc88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532bb88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ba88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532b988c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532b888c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532b788c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532b688c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532b588c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532b488c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532b388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532b288c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532b188c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532b088c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532af88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ae88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ad88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345532ac", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397058cf2fdea803157331a2be94c9995b4c9367164fb1a0cda9fd8f03142c2be6a": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc7418e0bc214673483d076bb8500d6caea527fefa0f8439d41544bd7037dfc3": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a912777b30ac3e9e7b3d6ef2b687df472e0d7b21c350d5893bc30d4c50194c8f": "0x0064b3011a4500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397767ba719b97ee6a516bd7fd6a1f2fa9255b5e750bb33731acbf2a47c27f550a5": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397418ad7d848ff916b35d107014959e2686ca080fd1241f14e6f99296bc83c5c83": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339784000a4276a7223914cefc955b5be770d893d8e56d54ce03895fa65ee389d714": "0x00d403f12f6001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971932b7b9fa3b144c0d5a2e6a1da193b9ede053490c7a7856332c17600aab9ec0": "0x004e6904cee701000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb39fe6329cc0b39e09343a73657373696f6e3a6b6579733bf5ad9c63be8730ee493d32b1df909e52cf64db4118b568a638f06bbc14cb45": "0xd548c490ff6e728ed093a7406711d76b2c7d04c77277fb88b1c3c789fa641737d684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e179d684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e179d684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e179d684d9176d6eb69887540c9a89fa6097adea82fc4b0ff26d1062b488f352e179", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f2eecd8123ad533b0bf63af08562fb254ae9440300a9c31c607c0cf7ab52cef6": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d8b9a9c99bd2f7b0cc10b5bdcdbb62c64cbb51a87b69e8e47e8f7381cf87fc0": "0x00665faa191700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970646ca3f158db4fe362dfa76b2ca08cfae463d0d9a4031d981151d81e39fc402": "0x0050a95c091900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4780aca6dd97a6b1b048b59d313e18e253cf4b5e10ab09c70e0df715b349be18f": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733c26f0977b13d080265dcf7b158c46bcf20dfb644782869b72ffe550311d158": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ff057d683efadf2819b3b25df63f28434912233fd2f59bcd0d56c995fcc9726": "0x0096837eb52a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce0d73b8e6f72ed8a0b16505ce75bea4479c76a1aa1bc0ce55bfc4e32ab4baee": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397badef469685e5fbde2ca11abe686386c4a90780fe0590589d87894ee51d3a4d7": "0x005c0337b00e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b681f961f459042004e89c6cf00e16dc4497ea95076973df19ef1a9166cd91ee": "0x00ca91bb010500000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4371dbbb3cd6d6bf7e46f49d612173a6d3bbb27c1a9c3c6f49eac5bfbdee06d95": "0x007270a4519f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c38b11121434e404bc6ed42f345e5b214f7f54e0229f16a38f1f9c55c7ea8a96": "0x00ced1754fea00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf9334b579b4ce69e9b0b5909669a553233cca1c8af691005c223cdd9d4ccb72": "0x0026a278d70500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339743c9bc7c3edc22e95908830afa887ee54c9e27d31d911b010aaf827851a28894": "0x00d89708430800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a7148deb95f6f96007f44b4bbd2e107fea58c45d74077dd9da52724520a4c4e": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339728e79e20b0c027eb21b0fc43fcecaad4ac30cf778e8f6b93ef4e57b5189da08b": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc2701bf6ec8b7a25697e3fbdcc2f7d2c494f7c5364b04015fef6ef7f377f66f": "0x002ac6cbb1f901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aedc6048d352c7f20dccbfea887d0a0fc419f6569d4f0d40081f7eb7e68d2295": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a5e8a2f01ea09f27fb96bcd15576878af34993f1af9777b99b2dcebebbb8ad98": "0x00a65c64378900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d4ca7a0b4449faf00d2947e88b55ce5c6d085ad8dacf5c881e695f5ce49d4680": "0x0042c538520207000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720f57b44de1cfbd045ee96ffc295ffa995ef566a1fcfb9b2f1dac2ff6cd51215": "0x005ebeb2030a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972fa4cd54b91837d4fb20b2084888e46f7ec5a77071c3a8f5b54fd4a9b4e96ac9": "0x00a69227cc3b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397666679fbe8a3137dc6c62d50f1b9aca1926f5bf6a9e79e22425855819222c085": "0x00bc7c65071400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aed95955872288d41735cfe1f017910bbab6949a08be8442a0afa33e8be3eaf8": "0x006005ecb58e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972fb0d7c4ef31a3413041d1190fd0a2577c40e975c9ec26c35cf69f348d3cae17": "0x007649524d2300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c6734e2bd9c8345421f28d138b42d3a08b99d804b9663227dfc61bfec22e0fb": "0x0018f5b0d95800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c7b78c8c5368539d57aa462217586a5f248159f6e711dc61e2ee50e30d5c9fbe": "0x009c3f425b0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb0f9eb339698c36a46878437415e2448fb985783012aa5b760cbb7ba430bf35": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef2f95823ef6ff15b905fa2ae2b782404e125c01602f60b6fc697a9f5287bd3d": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa435b0256bc9a9c2be374a7ca92d3a90e6e906b6fdfc8e0ab274d33566e7fa2": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e403f02a349210bffbd8187fc59e660105330c766267b864ea15099e2b51912f": "0x000aa1d3ec1f01000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b439a49f8392c2a40af93e6f74ae8e79bef6a0861bec9ac66a25fe22a95ef2c5b1": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397168268478d3ccc5890b37e576008a32bcb06657aa5f9adde78db2e034f7bd43e": "0x009859449f5200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d53443240e4f19c00ab053356daffc9d1d7f4d0ca6329c431783990cdaa97f8c": "0x001428b7820700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972507e9f948754376908946994aef4ffcb732bca50740b171d0b62f6a2844cf53": "0x001662710c0500000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4cce213e374a6936506375ccdb9831ff12392265e1a8208dae4b9690ffe5f9747": "0x00f43e5be3af01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b58750111e2bc9bf5b2c53af90d38a278ffe43fbd0fc660e24a191117044ea79": "0x00aede25018b02000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4f38e6f7e119f073e779d0332617609da1e6280bc277cc857bf53341c7e2930d1": "0x0000470ea1b0f8000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ccb3f8c195a88489438996f9eb16bc71088f68cbdd83ea35a2c87d5c99fa3340": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339754d3845849d913f698a2615879b2f8c220c41d47177ef0ef44cef3110c5811e7": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979cc47230b5746f631343ba8713f164a22c9ce09ff7d954381447efa6ee3705a2": "0x000edd373d3100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5ec2075c80a2c0c8ee131c0008851532e63bbd99acfadc5083728f2126c02b3": "0x00d22374f95f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e7ee6514501c96e61d1d0dbad930262e333e9048bbc235127ca80fbb79cda255": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf1687fafe70a719e3375c7d28f4a0a1d5e01705f0bb8a32146ff50f91453386": "0x00ce0530150000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc68649f550e9ed5827812e963c3f30712bb5f512e0bcb41a4c8a21a286b4cb0": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339756ef297a4c2b0bd9e8eff22f1cf885f29002bcc801a3283010f861756db95c48": "0x00f0cc775d8600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ebe29b48a301e5b5828b539de78d61990f8f1fd77e57a39d4a8b3ede63650075": "0x00eca5b6716f08000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c42fa95448d90825affbc1bbfeab5b59eecfb188c502ff72d3b13e4709924ab4": "0x004203eec38a05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339753727b871e4e34ce90fe7b5f58c1e3ae77221e43ed97614aa423b0d9ef24a98e": "0x00da5001030800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397558576e91f7665a5a53b73f1822ef20e9e002cb6c8c054e344cbc2fa48ac08d7": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397291bddde18b94c2db8b3e32d7d925dfb1801020a46faeb8c053858a54592617a": "0x00189c2b960200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397573625c9c21a028d6545523c943344ae943ede76514a9d2db351eaf04177e5c8": "0x008c8b2757e600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764dfea868f40dd8a0e52956fa8749882b7f91d7c3cf2f4f0baa405e72925b4d7": "0x00142ea50a1800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a6ed74137f578ea6a851531dd3928b3cbe5cdf417c00759b7315d5492953d73": "0x00b4ddf0840200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a27e948a088b8947d60f03748ccc6739e9aad20cc08e331326120fbb0b1c8037": "0x00eef3db9dd901000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b43b75fd183768ca115ff086c8a2159eca66511a669504387f4a025b49a95bb6ba": "0x0040ee7affbf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9cb2b659c80b6a377f3316a54d1712c58b3129e76af29bd4b3728296f44c9f2": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977be71a8d49fdeffcdf038016e50e30c99139d77154bb307365ec29a324ef2a58": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf83801498e32f215e19c83acd33496091a56753c372b8e5f2b576fc26b2f698": "0x0080525d633f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975991da5a2a22ef3bdeaa241b375f167f6f1053a7f0199374f2d6a19cdb6c4b14": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ab65fa26538d85e030d04dceb5740ed5133b649e2932c9dde58b477a5bb6bf3": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f4b05b91c0eb420e4118657dd7a9fc68fc3018b1ccf24ef528d3296ba49d0d7": "0x00343cfb8f0900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4378b771691eba4a8e5f3cb63507985375c1c6d9073a43da5afb09837b6d88ab8": "0x00c462cb9a0e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397027c6cf021ce7a87189b36fd48e64b050a1dc89dde676ca374257a1be0d8a5d5": "0x0098e2471c0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974325316bad2d1823d806401cdc6a494b685ae87f26143d89dccbeb6c0579539c": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976658e72be9cddc69c4b5e040c9ff538706b442ab351052e82d5a74381dc9626d": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd52740727336dae111ddcaeb071012253f7c460024f42053d9b21ec52ece64e": "0x00b808f1f31800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f61e8c6bcd71e6eac84eebc4ab6f8755846a7c63821eef73dcd2d6db525d592d": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c6f8f4968743b24a9aafd5825e0207f92e94b35b6e50f10c626ec8fdb8fff97": "0x0094bcba878500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a8d72823d2f9f78490c3e123582bb0d0a0b5e68faec256c10611450ba8cdb67": "0x006c6c3e88a001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339704a95143a5bfa8999a390788efde9bf4b08eac4dbe94234b1aaa35c5f061c8f5": "0x00a031a95fe300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed9b35f1bb26d05ee6b064120a8f9d3690df8a0d508802803623c25f10dec394": "0x00b27651350000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975e86afb879efbf9be8b35046b7495871751a7f79b96eaf3db84e8bd7fe7d6356": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf6cf9d66d142dfeec15468379ad7f9efe715c25af1287e4b117dd204dfedb09": "0x00cc1d9299d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d39cb8f41ada0ed9ff41230f20c68e4e7378c4a02f9c29b755acfcd740aa32d0": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397746d7e9d29780c59fb0d3049a58b3cc8d602079be899afa1435cf0489c2cc43a": "0x004eff6c020700000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b44587d96ad84ceba8c27ce2d5b14f169166f3ae07ff7ba01069e2eb33ed290c6f": "0x006e82e59c0794000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730806de91059fcf10337452a6a8bb14aa384f1d987646fc9603715e167130b29": "0x003461d4072000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397366ebea28766e9c7feeab4b45d4a9ae50f54fb8ed4137ff8313e8be5639216ff": "0x002841654c2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975bfdeb94a5021b0ed217c7dba71c7bf77fa17cd09e1cd01147df3fff7ef75b34": "0x00fafe32aa5600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4fae76e79d18f4cc6b0ab9ebde23e8eccb10ab75656dc28dca9d20e27595504e0": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397637970cbec446f9dcfb5737107dd372e711e899757f39341e2ea6422a2a1336b": "0x0044941f486a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973b19830590f2d2eaeacf198f8f26ac36f7b3a3716bf84a94d6b1b6cbae934eb5": "0x00f259fa575138000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b8b225e6e1f2c77c6eb2adac94b407f295ce6fccf674f5bde7d2c712e791f0ab": "0x0008997865f81e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978737924b2f4c6d32ee0d6c01fa8797b26016839aa87161e1944909987aa3157a": "0x00da2e68a86b02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c981e73b9f170fe75c5dc068b22c555f4d043a82d45e54555b42c8b56b51a982": "0x00823c627ebe01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b830af024bed067aea950068d1ce541a7a7e6752a1cfd6f302db9256f9bfa47": "0x00c26f318a5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0f280a073235b9f6de2436ff60a26c2a26a0edb3556c8a632c9c0dcab0def00": "0x0088c596351d00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d872824325d96534c5cd2686ba5ee1d4dba5ddff937a69a0509cc493188171f74728db8a": "0x00989999d6cd44000000000000000000f3eac39b02000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e75570027967edfaca204a7c9b98e75c35a56deff507052a306a6a24ce66fb61": "0x002acfc5745300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b426be58719c0d4a4c5e0de508b1ec0c5455d2bc448ccf92949a7a794d8a004c23": "0x0030d15643ec2b010000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a7a98b80c5023e699b0226c950ad4657819bea2848dadb3afb23df4a5bd530d3": "0x0044db3fc1ac00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f0fb940b9c7f3593120574d6e7ec381fad053244fa7d516af8806d758da256f": "0x004c2ee675141a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a504314eba2643872d5154879865e9c745a04e9789f4c96f416eec610f807061": "0x00805cec442900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ccc42c4d8c7b505739630d3e8146b135cfc0be4f0a6f492280382ca7bdf51c7c": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8810b43a6f4eb3f45831f33fe348de5aa59ebb78b485f08a5239114b4ed12af": "0x00900126fb4700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973523c3b8522004b4e1871ddf6823cc412cef845c5a5dc0fc32695f56db04616d": "0x002a535b914203000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2917ac6a308d645671864cda07d358e751225078660c533195e7da18235df53a19f3451bd2fdc9e4504ea2a067d6e06de38": "0x010135455a5737346d69753261754d555669724e594c6e41503950704a487a396361fe0fa06dcc3d959687440e296a620f940245ded4a1a543a469a282b1ed65666a641c42015cbac274c6494f87d9ef1d6241b5d65fd1e1ab9cff55d3c5a675a11448657333507a48436d4b655537767956574c667255325a594d37647051417964ec63a3b6985e7a08351357f83f1893543accc9c4ef8817811e788674f6fb2a40e011c283ab85512cc6daab814652bb4a3721e87fb0355a7ac5e8d814c173900716b565071a49756783626110028c390a6128c035fc026f826a5ef3c6202b6e369ce2cb313ff5112712a060b5310892db55483c4e3f2cebc577dd390992743b7f3441da0f4c003eb0d38d8c3e56fc3decfdf7a9555325ef18b88c4dc001052139e43aa2946b5c5f23ad3deb028e8cc0aa3a97b3711ae8afe66fd8bb8df32d822358ea15c54d6d4115808fefdc36a34690e5ce5012843f8ef44c857423257f174458606c950e0962b1d0005618123e174265e57d8b7b89ed77d93a7e1e3fe26c07326ff2db8d266fa682b3f271228c59e568fe51fccbd6656f99ae5b36e4b5cc4d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553104b07896e2555b95f29a2f533b3b7ccb7d1708daf144fd2b1ce5c6d2f6dc59bc62662b79268689d3cbd52ae1b98afae110510a8ca6a4a3fbc3891246222f7be567aeeaf77b9d9f7a8735062666983a9ae06d505235f72f4fc184d61c68f3748e3014e55debcb1a970db1b51f535601080d128df5dff2593fee1e3369139d51c072aaf3b830a58e11226dc40a722e80d1885ce70b03f3283d6fa33b78161500035966652bb5004351a31c7d4528d0cb506339fe6153ab65cce1c87fc0c70946bd30da6df04cf8afac153b0360129b862216663d7f2537d157cbec2dc860b340583506d533d37959ef8856c817b76cc9d77097d5b8b169ff910b484724e68ed46e415ea23ce8d6d91d2db94005efc7cc641480ebae3d76eb2f27da042aae370a8f6e783eb106ba819ff2125db858ac9bc9a5f0cc3f825f6a8050d586db169555ee16420a5bb3e842f45eeb373912201ee8d458c63758f98f94933f42fbc64d13bd1dfa7eec1636ca9441be76a23ce833204a0b13dc51f0627d7a8bb1187704a61c149efbf480d958cdfcb501e7c573026da710fbc824f4fa05501fa36cfad8dfcd5092fab26f40b895a4f244105543872f16558ee0c2f572a5db308338e6f1cd7623f6b21d624832094b03aa672e016462a020e217cc67b1434785b99114a2b4fa5a759f81b50a391fd885c5e3cfd86a31f212467d65582c95010a48bb30d27ed1e73217c16cee41c3175cb82558cc2370e308dffc62bc79b2b782a6cd16ab79286840ae1bc79ffc30a6b7859da8c2159a4dab813072fa29bc05cbe2324d00cdd577d6ac28ef62f212e4a5888fa5e72b1515a32233dfb118a9ea5de97558b1a53d6512d86b9c435aa889f34178daeda9b781f36cd3b6789e4b51e90d64f043475551688c0fd813982bc4316c5855d5c7dbffda5fdbce46667ca8a72d7ca224a25a1d845e84bac2e12154ebcdb473953fbb50f37277cca16ad7047f6e12c425814657784abf3cdc5417f9db86fb77b89d0677cfb0523742ea616bdaad590386bde64e9ad164134516e276a943254016fdca1d481bf92e493b60a3a2e436dd2a1a672e7437fd3f9f8f6f8a18f6fd20c644d02d36aa27ea3e780cf1e9f452576479f95314955b6306f92c4bb143c1f0bc28d6b1c04bf5fb9c7a38969d279b9fe78cf53a7028170b7d09cf7687f409c4999e6ff129e5aa4deca5a1b5044138babcdb790c082cb53d6299dc033e467de007bfd5c4c0d24135aa85d2f1d983008ff78fbb66f628bc11ec994800136a6fb4567f4fafa26362416a5d42dcf23eb2b4dfc06510d810694ada5bfa1dcb55d4ed2ad1c19d37275ee93148bcf0c7e51cca78d64b4f327497753b33243d0ce0f0e0d4a4c6e102b628d0ca2f49d606cff851203ee36a34f01d81d6b5c405e5aca44c4a729d7b106f15b7ed051af372e9824adc471474c42345fe470e86e5e21151a10f2b204b2709ba40e9feef168384151d895aa827b6bf9d0bd6e71ade796bc515b5632c47bb9d8f9ae5515f342d371786ff6e5a1e8c6de2daa327135f09c25b914b37e5f116fb7cc3af3892e6b1b1617a9bb1b02d88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d3455310388c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553102e6bf945e20e8a12944e5d8044c77bb0f2b5d9205d03c7942888d1cd02c32ce5b88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d345531013e63ecfa7794545a774b45b8ed7ab977e59f6b9d1f6be0e2533db2476cd3331e7ec294a2ad5329e92488dc1de82e4da5d0ef70ce85242c0f5d16aedb2460007d6cf513881f519aa8ffa7b6631e934e954afba13b14629e9683c20d697fbf5d5a486f2737d933bc6db4fecba55377d789dec3f48a963b70114655c790e256e06e88c47944e4aaf9d53a9627400f9a948bb5f355bda38702dbdeda0c5d34553100767b6804d3a3d7a6d67af7e6f2155cb739c2c22dcfe2fad2efdb2f8bb6c96b0332aaecb8959f89c7f2254a456e4dca1ed4c4e578af78a8163d553decac06702a58cbc031d94e3c4ac28a8da357e62e0408db5c8150e44188de92cb29e92bec160ca7999ecee02ff74b24312522ad6531c2cc81ebad5219b52439f791a6402d603808c1fa577b76321cb0efe7a16eae5864c0e120fa1ab45baa0bee49c69a0f378c43e6504928c56f0151eac7575949a8951c4deb28c9cd1acb26743de41df80d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397309884f24092bb9d4d35743b83bbf223154f853b5087a917136619feee2e1ae6": "0x0028cd22abaa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc442c99d8e1f4da6a9802f6720c9c97b92d7b37971b529b6b90f6292effcefd": "0x00f89a5b360300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d299dd1ed7e1690dfddd108ffa34aa22a1f1f333171e31c97a2050b0708a51d": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774664245e38d6433ac195fb1dcedca090623a95d70ad1092777283076cd8c5f5": "0x00e67bd81d1b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a384a4efe221424a9c624a556e25ba7b3b5d4bffc28c3687bbf513b16b03a11": "0x005c92571d2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a73a3b5fe10710ccf3c56cbbbb3cdf05673fa67a1c57926906bca74936e88ce6": "0x00ea7479ef2800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc24557c647ec7ed669fb437d284b3738f26e3b92ed20b7fe55f38c5fe4e6afc": "0x005a3db8ca1c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4660985483d2fab5b4fe64150df0d18910fb97ca780ee44afa0ffd3da834888fe": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970397424423c07459b5954e3bc2e9b15e0a80aab4dd3b254ff881b2219b164883": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a888deb47624f3d872a186c854c63479c397e55ec000df50e23c4c8577c2366": "0x009c3a04d74c10000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec52420946f566dfa1d6673066b81fc83b8fae18e22235abbbd54757e8f86692": "0x0010fc266f3802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977dd434cedc05fc08b9d091f9899861c9f9da8a9c4e478d6ae483b609ac7d90ae": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a86e2bad2cdc462c83314486e05b421e6748163f2b26edfe3a8d9508024cb997": "0x005a2eaf112f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b8caa28c86d611643d6362541a7924aca8a8c20bd517177edaa6ae4ac4778e4": "0x00a0724e180900000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca28dccb559b95c40168a1b2696581b5a7": "0x00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979cb83e02649b343e92b5ce040d699a7449d997010feddb4b773eef9541115e0c": "0x00a86126b02801000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c29eea0a546ad5fedc48e2af65f0ac9c530cabd7d1202ad881f4a5d4b484d607": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c5e10fdd568c6b2c26cb4a2becea665a7e3cf4598289acfe5d6aba2b2bec4f8a": "0x0074791a98c503000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397681498467bf3455ea6e2752e553b58cc99de729530f61e1f9dad1ca4161f419e": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a3aaa9a493d8b2ce6068cc5a180b60dca6bcc7b7e89992e0b79807e03f09fbf": "0x0090c5a0b46715000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8f2af9ad9eb5739ec9e57b82c05ef2786b2cb83c974ba5a4f15922748a18c3f": "0x00c8c736f51b00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4823d2b6a8a69e73a659f8f4560f2ed1d10685286d050fe9af27b3af6f8146a76": "0x00a854ae840c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b432fa5461a25a8c94187dd2126f012fa136eada44b0a7cf85c722b688395226d6": "0x003e4d65c1340a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb3c2a9e816717bf87bb9202680cb66380d8b51d99d0b924ba85c10567162713": "0x00aec6b140e300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d87282433ecee039eccea006f786a6dd921254e9005c290ff525a280b70d088939de2954": "0x00dc8363489707000000000000000000d32dac4900000000000000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e3d694842ca3b3b1c9ca722f726948d7f262e8f42f7c8bfa832595719aaf7244": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2b8a9e5b6f01be1333bd7b2be366065273471d2d2b69926a404455d2f3dd668": "0x0056e5d2950100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397272ccbd17b14ecca50aa31de34973cf69a2ce1744a0115f1247a3b0051247226": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397443c25a9e76d1ff33eb1251dd7d665e04f99c78bbf9c55ed865374e24a1bff54": "0x0094ba30f71e01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f40ed50c3a2a8938ba9c95ecc37e5313114a1b8a5c05e82637f43fb9a9b52b1": "0x00eca5b6716f08000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb39fe6329cc0b39e09343a73657373696f6e3a6b65797333d741b7d98ef2b37fecb9daf1bb48a3081c14eb42e78513f57b41f3e293687b": "0xb98c930b9b4a782ca392580d02ed1185fa3214be9e7669ff7dc096d17d286bd268195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e94168195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e94168195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e94168195a71bdde49117a616424bdc60a1733e96acb1da5aeab5d268cf2a572e941", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979571cd1bca182e89edf81cf02e2a6b602bd0201d7d44f946ea593fa95963f5fa": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397702ba4f6278778fd8088f49d721bbb451ade888018ae1b9ecb768af29d08c482": "0x00c014c51dba01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975be88fb21ec95b6b94b6316d826e68db8506b330be34aeacd7a574944a880294": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744b7901008fef7342ccc61e22aa5d6148635696251868f35732d721904aa3f2c": "0x000ed4b73e3600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a2893ad601fe443433b61e9a7437a8544b86c9e4a4720bc37f15b2b360bd676": "0x00c2b658000100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397032c38e2c9a6ac85d7fc8105b4ca349689f15e0487aa4fedc0fd8d36ab3416ee": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da46e352fcb76db7f93b8350544b2913ec60e6e95ecf197490516369924f4b36": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9e116bba52d768bc9638337f79eaaaaa4904afd60c8bea9a4fd4eec8d36f209": "0x005eafa94a1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c702dd842991a6be75eb0c7631e176a333371d59d8cc630dac20869c3774721c": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d777d6e0617487fe93b9af58863605aecb14dcf076a1d31fa9781f7bb29ee5f": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977e3f53e0e8f1e3a7475c1a2c6d5527540f5cd8b63f83cb9ae673a203d8198b86": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e46dd1e48d68d3c7ff81076c4a87113b66ee57d3ea38aa3f5c15f5feb51b32a3": "0x0086df824a5400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973368643ab8575421212615e7f42ab7b16f66f2a6beedca7f2dc7418571d9c0e0": "0x00d27175e9f502000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d4d83373a52744818eba340eb3523a1e56a94e7c54c033d89d6ab466578cd18": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397de306a7514cc9b8c42874c9eb38670c53e65ec378d90c9ff3ae89c515c02717b": "0x00f20ea3029000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b5e6f5e7ab6a49ea85952a5b8cc0da3003a1e84fd929abb385ccb82335a8950": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d629b68ee442ae4794f935a8f4ddbd118ae2e3252d6cc9ccfaf47c179faf97b": "0x0080e9b886a100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970929f1fd8ffc5c2fd009b7e0fcafdb1d87675e7638c22d1fd2dae7348ad30282": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793e73f161413e969209719cfd780a66726228cd58e5b79eee11b3c30b4a5954f": "0x00a0d885573416000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df8b4ffa7d0021e581709a8b3591fd224b97db1e4a730fc791aaaeb23162e877": "0x000e688dc7bd21000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977993f7716cbdc2e62778fbb00c4000e7c43a3ff01fca99ad7da47c5a024b6dd3": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c0f0c0edfc53bd76f7c9271d50d0321c3c8e2d075370048ffefefb0d0127acd9": "0x001c1f0e300900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ed292e651221e69c8a9227e1c6b6f1a377df7e8a7719d54160c8af1199d5539c": "0x00947d79410637000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a1174423961cfd112ad94a1ec2aa96a9008cf0ffa566a34971da6cc3a450373": "0x0068b3338cc900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a9e05aac03e1cca7124587b2e62ab39fdbff088eec3c890c8dc4f7d3d0a6e792": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a2da1ea36658f01c686927febecaeac21c33b3d89465e9241b5d68f5c27cc191": "0x00dcfef6301100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a79ee2d745c7a89be55d4742ebc9165ad9f4a0ee2446c4036d3abc71518ec0d": "0x00ba42ab7d1600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397430da8f4e2218f8dff7f8276998cd1231db37fd853f1e3a87f6b06b70f5000d6": "0x00c66729ba400d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736488da248932273d6364b5ecd8bd7038cf2aa994df6d7ebc7ede8ee0dfa2776": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979602a99e5c039cd5f0129c880c36fa916e7d843376689a258a4db7464a3f85d7": "0x008e0d1eb5401d010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765594abd63a8dbfbbd8eeabf0eedafca6b0d02ab5a7f117e1b86a8088ba8b461": "0x002efc190f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974af7809d4bf47e10488e837a01b431d9e8783a2b398983ab3f4048667b0bec37": "0x00e094fb1eaa02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720340ba2445c5cc2526246413ae001e137b6ea70651fb3f606d6bfe4d8b76a44": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397606ff5fd69007403405f2e47f269fbe3c861d0d98fa4e6243d4a0f33b04316d5": "0x002e33bd1e5400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f658fe3468fd36d127a379ed0ce716b88c5ce6a3b214c19192b6e2c58946b6d": "0x00381c3a2c0400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b419d43658c2993ea4efb54e3620dd963a88b60ff9bfe53edf03dc42d3b82e2134": "0x0080e03779c311000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4f7ede018ac9ddce0f7fa13892d0fcaad1a9a8f9b526a9438d216031d01fc96": "0x0034795dbf0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd7cd718bbb56b25f3b14e2ce2c082146b0e3ef7698aba374736272ec857807c": "0x006e89135fbe18000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b1621fb16e9ed302f6ef2bb16d65bfd22d954911d3c7495f015b40490bb126c5": "0x00daf338368b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397145b44defb39898ebbd421326cca067c3fa2f8cb188db1f5f4054f23b164a003": "0x00de0629a33410000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f3f1efe9270922fe55fad4c8e2eebb47944d9a12b93af0fb5763f35d5e54d3a": "0x00f0cc775d8600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f9a2a1501dbb897cdb75388ef854a7ff926a9cecb9044935a5743d7b949d03c": "0x0044db3fc1ac00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c42abf7fafece6dc85f78f4c77d8037c07da3248deb1801a80b09f5ba04dd5f": "0x00c662e4d35000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3a751b1233a870b55bebb478176c934e76a66f53c7998f4cff938012629eb4d": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774036fa05818b4f92f377a052195056d4fff2cfdc37893dfc91daf8acc47cd4a": "0x00baff5ac60600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764b4a7870edc43d506e64eb4052ee115ea3bae4c041b9d6d06c96d3490d539f2": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c64120b8e47f35d673f41b075372c40f3a1f0b8708a7df222aef0ec4d1b4096": "0x00de0f257d5781000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974426aed04348309cda0f4d88dd6f1c20fad3cc64b22d5b5d4a58b3841cefcc85": "0x00b218f2c65f03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cbd48f3ee7bd811a97e7ee93c31a8b1fc4f7cd24131624b5bcb520077c5cd30d": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397778dbfcb48d73aab381684b5d425dc450993f72132a4d83cd7746fa2698664ba": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397495b18e900f2f80e7a63345ec0541f662abf766230ea41e7775876c545017715": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a1b2a23597b69113694dce394a23d509483370234f75bb3b83b3b086eb53531": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b40098201e377b938cb64ac1e466610a10b45df25af37888060633951c0a6b6e1f": "0x003c541e91bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a30660485d5e9d108a8b0e014e14d492b90d673f2bccb4749ea766f361cf317e": "0x005a915366bf09000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732b90c022814e9a8693d40027e8bb39a91a081281f9dbc6630688044ad8daf17": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973942486075cacff26c2571f8658931eaf4dac6cb8c34928ea5f87bd606d8bc3c": "0x00d22374f95f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ce6ab5fbaece3f9ac2fbf2b7d007e9665b039dbdd240fb5d8bb53f8d94ce3790": "0x00e074b175d800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ee85761c4413e6461e9486936ff8dfa4ba670db51ebfdabb91b2d4dab03699ec": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f636c2837aea9f626f0e65987268c638af92cb20c296b88b12cd5e873d0bde6": "0x008ac4fe5b2301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974149145c6b4507bd6f4ffe9eed44109c55d985e1987616b374f6974eee372ff0": "0x0084449cfc2f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b482d215941cd58d22f742b5e6bb573f9cbf59590265cfe90bdfee424bf7c4ecc2": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba4faa80ed46dc7dbe3037e8d36088a09c0c1fa7df0c7d9766a1769f845e9867": "0x007e15ac953900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4bca57bbf5e735f508054cdd81c1bd1d93482446911cbc9e027311944736cade4": "0x00a07115479803000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f9f92d8e963e71f1b0feaf0e6113abad353a1fee68262ddd45ba9bbe41ab074": "0x00e6562e0e5e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e945ea72ee1497ee7c0a6d1b46e26f62b1bb5cb67ac621b0315ae3e0c90f30a": "0x002e50c0ad4000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ba0b2d426918ec26f64b00e5e74ccb92f574e6db4f170471ecf1b5f537651fe": "0x00cec8c6e89500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974fed7f0638d7c2ee871016eedcc74830d02c62995565a5fc2ad93009aa3640c7": "0x00c68d756eb300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ad16f18ae44149bd5aad66fe6ca7f07641224dc9bb0b9b230f8381fed2608cb": "0x00fcfa64a79106000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794281d96887f90b369d16406f9d2fce13359abba0b766a46e3c6008959a7d051": "0x00c601b80f2a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977897adbef3c118c51e20bc055a5924ed16400d1bb7519159a34ee6b51c393f38": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339742befb51b5fb59db64bc604e201cf97450da7a6d279995390dc7c628e00cf7fc": "0x007c9f9ebf2b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9ad84881565cecab143da7c298980660e4f924195940e6ef9ea739f43f168c2": "0x0040ff72163200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397672f2f95f8dce48918590d2031ff8266e23a98cb9ffd767b94da11da65d35f91": "0x0002aef52d0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979fd7fd551fcedb57d4ae40ff3872fd58347d5bc3adab0cca0721066c51024a52": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339710e31af6f36a087f3576b741335058487a3c9f6ddca183cb8176b4d43e9c8f4e": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397392dea221cd2683cb1ebd4b1081c38cb5883b66b95850ab9737e0e0e4f5736e4": "0x00ee69afcc2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f296c9a2be581a579919c5468ba2feff385d405922d756197e8982a3d29c822a": "0x0080fbbf800200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4239692ff87564a11984df789a9835523fd2976dc10a0c441084f41f9523d5aed": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d2e19ae38d3de83dda1348f7b6ad29eedb0063511a5ff18a0b8dfe376d2024b0": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c754ab6f373daaa829c7ebf079cc67b064a5ca67adcdd6ae5c3864396a07c54d": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb3f7ddb5fa927971efedf5deab939d09bdd45115ef85c7703ddb43f8a991d3b": "0x00b4d5fea72c02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974dd6377f20158cb9fed9bbd5f6bd0f83c02a06f476a7273eef753c6d8cf0017d": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec245aed3a47b71731dd15ef18fb5c777892a97bf87d958f83770a7a9a862579": "0x0036fe07847b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ca9e6d67de59357683d1c9419c7e308b352f6b72171dc8476c6cbcc5a13c368e": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ecab62971caf49e74c0787af6f65bab108a72b76ffecbabb84451fcead08cf1c": "0x0080c045b21c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778d6796e083246a0493eb66ba197f04b16b7f31e5c485f13f2db31e43142fa43": "0x006c1a29773d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ea3934386acfa687b2ce534d07e3179e836a7705a8e91632236ee2a9e4ed5ff": "0x00a26a5406f200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ef8db642ce529ca3ebca144a157c9d2ed498579050d5b5bbc94dffe5ef7a680": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977373ac82c55af7de4de86d9a5fc2995208ad2f53012101400a4b6bbb002d2728": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f2487de7005a74344f8f5a1b460a5414a4342121bfc06ad774f89a810d9c3a77": "0x00ecae33792600000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579731640e7e1c82f7a9051b8646145ef79f464b3ea9ac5236e0795e417eac2143028": "0x5e3ed914a3f9da416f69613d98c0848a6435ca4bda8d00af53a8a5bf5898b904", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746541fd2b7cb8b936ef0989f9cd3a6ffde0f0934cc15fd9ca2ede441d5e3c8b7": "0x003aac1de83100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979cd5f60a5e66edfea61ea400dd589229614d455937a2f99edd4daa2eb8694273": "0x00e070e8b01000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ac675a9615c6a628e31c22d88ff29b19fb2f5f1883a94ef67e2251d25545b96b": "0x007ece841f8c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973979ded76f28f98c8bcce5400aaae3665323e7669b03e889e0e8834a02bec20b": "0x00b65c7e590b00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b487676635fded02c8ffce341aebc7bc9413db2757450711a2d45e3f24b0b1247d": "0x008062175ed158000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b48ebe608b0279a5ced1c839113039d4c5b3d483acc44a91c4bfce12ef091a4ee5": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa68d7220e0b8190d96c0873068a330db4b73ed4ea935a0107d5268c1f2f00cd": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a0eb59ebba8f1310f03e98ec68a0c566c501943c9d4051476a3b1e0f439d8dbb": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971b8b286c860d61710d56c0680d86fd20d4a1b106822ccffef418f77506c01225": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773832f07e7f2017b3e73d06ab0a2a9f01ffe27d0536b887b7bf4ac19e28ae839": "0x00dedce2d93f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339729119cad31c0934b7d671605dbc016e837c675604b9fc4ce822c7f5aaff992e6": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0a5dd6da9fad71f314a7b412aeeb0c3dd274902e3cd66c320dad2eec822681e": "0x00645dd8e71400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8f9e8ffa85ba6d594c10b02307d3bd61732b83a1496fce8e7a385da90280117": "0x00d64e0f9b5800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971263a3084cc7e541aeac53e0317bb7168c5733113f95b1ce92d8428aa1cd0768": "0x009a3f588a1b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f2f73f3e0f7afd40750205e493f176c2e9dd280e2a8e726b46d074f22bcd6f1": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397170800c41ce2067607906958abc962d22e1766349daebabf6e35ceae1ae395bd": "0x0012a552ef6000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b7ec9d78daa9154ea54eecb5dec81640d59e4478365d8d910e874170b6ae0d0": "0x00beedf8051e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977524a89d1060401a6f5960f6d5e41499ec6f812f39af3178022f10bcf8818f88": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397821667f39e371e6335320bdf0a2d7e9de2fc2d752245b0eeddbc53e0c6bbece2": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736a6a715c289dd524ff47eb44726a513cba3a090a191e0af6cecb0c631c4e1f2": "0x00feb635c0a900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e842fdfd9b4c80f09bce42dae79f9cf7affe15a75f55d8c659ce6c010fffb1bf": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397626d623e17a88edfc52da4a3cdfa628dcfc761f04345d5ae11e7da0ae5c5407e": "0x00e61c8dbda200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733031e857620a971978cf27c9da6958571bc3625043d0d9d6c17e2874c3070ba": "0x00bec3a5b60300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4d8ea2cea6cc00e38755a669de0bf9cf3080d1abf35d4d5967b56233d043dd678": "0x00eca1ad533400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa64ca256ead063ee4d5070c2c0351ea862341e53c3aaf7e991573611d4e28de": "0x006a097df4a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339795ed790eda05ce73635c028e68cd089369e6f196ecb9193b8ebb36ad7448c799": "0x008ad235945100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c30d3ced7e845a5f2644ed3ae586e113ff51f318c90d2f6403786eab042844ee": "0x00868bdcab1f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397811b67df8251ee237ef39add9a2615f1991c71c6720aff45928b2c705e4a8c0e": "0x0066a69b2a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767f63b33adda16318b7b89247f443fe8b0199b98eaa60f879fc63f0743f883fd": "0x00a65f83e67f01000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b6579734c089da3a86c4b3aac53d628b2ae52d1a47f2c612ff3f08ce84508f44597f1b4": "0xfcdeb580add093f3b5f06603032c2fe89d329ba372147c100aa0391a44a51601", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979767ff8f70ce3310f7fd6f8b3118853eaa2ac4471588d8459bf43805af99c9a4": "0x00ba96511c4b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4061799e80600fca63dd351a846f2e884441a75f6dbae29dc3418377930d7ca": "0x00a0ed86271400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339759a5344483abbafed218687e61a4c04a727072f5efd08d5aa010b679ffe9a101": "0x0016a70ef24b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b1b0eb06cb75b2ff008f82788a9e64c29ed7f96ea62f28cb4e70ff183d1c44e": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be07a94c8351c98805b315cb9b129cd07cb020b0577f1363d1f10b34323a16af": "0x004ed7a1c0bf03000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509fe6329cc0b39e09343a73657373696f6e3a6b657973aa7b5b59916d801fc25f69c7ace024b061a4a9a0fb1848097a2dda4817a63c00": "0x7a977e950acc55770b4452fc418bd59fc4ccdc25ce3c2d4cce58dd0d6f9a2d15", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771502d4a683bb5028cb62f4fdf449a2b6be63c4da66c2d55d80f7a6883a03fb4": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397313bc4d46160e67f9ace8dc53576800c2e9238f23698e14d68c9d97975781a41": "0x004ed7a1c0bf03000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a409a76fc42140b21b188cab86b6a693f7b97f95ac72e94cae053ce62a393fd0": "0x00c88f18385c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3fe8f3ecea4f4fd7bf2c798cca1b1cff6d5863d8cabb03ee44193aa7a3829ad": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b64d31a8720add0621cd3ed96e7b553cba8bbbeb6a8b77fb9e83b93bd8fd476": "0x007a2bf7de5731000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ff34904bc62615e0518a279e43b763c72792223f75d14204243c2b1858678d7": "0x0076e6a2f50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d33f36b49c2b1f0080713af5dbe78024e89faa6229c56dcab495e910514002a6": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ed09656c6b5619d93b77e173c53bffe1097c40e336b16e984e7143842bf2398": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d4726a58ca7df85c1a38096e8fca201a200488f4dbbcd7afd69690827d2b6b9": "0x00ea352f5f1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970cf13e7d433f9299aa57c71fee4ec03bd6be4bad6374609ba45b915fbbb8ff59": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339796ac9e7ae5d22f47b86a3fbc4bc83f01097ba9298175dc4d086de43a79e22c21": "0x009ea4c3e42800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b80c3c547e1f93155c10ac58d1d971b89190db0002b708d0070d1c69b5640a9f": "0x00bcd2c49e0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ea2f546efd6807ee8d8087dc93a72670156b51508f9a1221744feae42b3c286": "0x00ba96511c4b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ea88bb0458b8e7f83d132e504e8df12a39428619fc73771e100e0e2fb4f326e": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974eabc84cba425d28e9e80b53b4738eef5541db50508828c133f35697d66c1cef": "0x008c23ea09fd2c000000000000000000", + "0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b": "0x022a075d439622b2f100ac4174bd1af71e64e0913c7a7230924ae4f71b2c2a42", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd2d41ade956c3828b69616ecd92fe040f7ff161d4ef3f95d57ee3baa43c6804": "0x007e22cded0d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc0eb877e5367f45b7a6c9e61b49dc014410d60fbf32adf108a1322127f7285f": "0x00646a57109c00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4bef865eb9f98fe4d6ddcdad70a4387f9052bfd76c68f0468de54f9c5ebbb9a05": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799d39309804207f2ebef47c30b4f48244cdfc4ff202283a8b79b50f192ce8a24": "0x0066fa41c93400000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a54926db7eb987dbe006c44e8b4a179fd24ef9acab9b64334037ad3542280b81": "0x00d22374f95f00000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243e4b19ce4928ef434b3fbf8c3f0975f87031f15147828e45f65a8d7f4569a888a": "0x00d45be1e85b7700000000000000000020d96a8604000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a0551b1368fa5523275f8dd01c220c8e9969a4e7215ebccc0499c8a587e6d90": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978815b5f2e8183aa3b709dcd0bc43a6139c46df08804d8d75a199f2c59a67bb6e": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397f43d6436dec51f09c3b71287a8fc9d48": "0x000a373683bc335b0000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397268ef3780ca81bd62a2e5e4a2dcea56a3e96ef7e5906daebb919ca17d9d45af1": "0x00d86d7f8e2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977a4af07f4c9070ce390080105e592372cedabad743c802408a7382ca07a97ffa": "0x00ca3777b19c01000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e6c61097245ce835a28fb2f8661c11c27b917f04489d505760ffbeb5456eb12f": "0x00dae7b3f9b101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970cd4677b78b7d82ce58a28da625e5d654ce2436bc6428f323d3c69800384d439": "0x003e06689ed624000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f41349718d44d787d9cfecb5d5489d6abceb4365139e0da04e0c1a1308e26d3f": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b092bfe8ddbf5bf034ad0b225cd802c94ceb1036e72d939d0826840dc9f29904": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f5bd0c4dbf6e08b15c36d9cdc1be23fa23261ee5964e9a238f51a1a2ce59bad4": "0x00f03fab1b0e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ab899c39c441a3683fe20dcf157558dd7c79e37a7780660ce75f14bccabf5cc": "0x00b8dd585c4b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397254d4c35ac4c66141b00d09b758feda72704a9512977b5ae33796201209c5a27": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397374a1a00351f10254402e5f819c79a3d160803dbc0a2c7828c9488a45ed6b678": "0x00242316652f09000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768c1fe59858081dd3cd88daf0b32b7ebe63c846a82e6c205da554a0baa129c5b": "0x002a911003cb01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976df25d78adcc3ce8ca79cd41d2e65dca1e7f17bf2adabc0b03dc0acccbbc8fa9": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c9fd23ba8d60b340ecccea828632a24f9495a3cf5da225566ab547a66ea49e6d": "0x00f898d8a20700000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca0b6a45321efae92aea15e0740ec7afe7": "0x00000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b65c4252beb95cdb5aa15ae1330bf1718b8f9e1407cb50988d97a072c72cd735": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f91538e4acaf048917baf43866b3af4f4fe325d9678e5a69b3b8e3050a30efd8": "0x00a61c778e0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792db1c01a90f21eaf421f3576fac329061f6f980c13746aa79b2697526854488": "0x00fac8d95c9903000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6e8ace431309a7931c690cbd5d4274df52125653c112967d0d788caf122ef94": "0x007472471b4800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a9655f4b17043fe4aa2db0949957c18b8ff04cbca18f60e28af1e32ee8c8634d": "0x0040f79c2d0800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b430dcadbc8aa51e8c14a7dad9e68100b720b825069ab63874b39f5f7bfdbb8924": "0x00b2f58f6b0200000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c91859b6e201eb6cbd9377f40f9d3d9d454da1e03018d3c7090dc0a29480c944": "0x00cc2e5cbc990c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c00a1d449d3ea16ab226f62fcf6671c60f373915b8200e42d0fd61c3ac1b867": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781e8a138885cef3159df2fbd07894a29d682591d91c51a690ff7dec80e731359": "0x003eac4f5ab600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e579e593fa31ad474220ecc4283355f56db677ffc67ac05c6716460f7b65165": "0x00c611f5847e16000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4c11eefe96cc67f58360742e8a1c7a9553e8e5c7937b965513a7ea3be316bbee0": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f40e2e3222b534cc4f1c6fc6d6f28354a0ee1cb6b50ff0a6faabdc53fa13499": "0x00ccbae241ae00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339710c956b489e5bfd83650a6fbd668ff13ea9097e064ef4d8fbb1df35479d93ece": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765a229441c201aec56db46dd67f932d5cc712d9310b985b48712e79661a94c29": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9ecdffe2759904e8d7c9c30484831ed31c30f3d76a75c3498bfd2168997a873": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ca8e2543fba60ae84639b52c3916a5867914c45bcee136494c9a5f6f8a965d7": "0x00dc704a740300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243baf8021ce9973e4b759348823608d188da29b10989abd4bcc402a60b42e69d30": "0x00008d49fd1a070000000000000000004cdff54400000000000000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4ddedba74c3683cc578b23678e5e713e4e1fca1a058dce5504cbcf7aa4542352b": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fb2218936157983a83cb22ed4050c4718048b96f8436bb6ed03ca08c1d9fa735": "0x002a07e4311300000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b448689c0701bae61450f0f617e7dd46949fd3f0d3eb2686231ed0b16f3bfef775": "0x00fcc39bafee00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976efbaa57d5bfea4244d0ef8ba42f997ce307d8d63809e39cff51b41d5942d2b3": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9afba4f36a455c6736adadc443fdbc3898f6f9748b8ba320f213618a2cff0b0": "0x0086ef35191300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339711b5e1d2a5e2e8205107b38e973f14feb62afee91b0473773695a1e2ba48ca47": "0x0002aef52d0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ab4ff6f3547c1130bcabf90f5df14e9bb10834759e7ec7083b427c189cc63dd": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c553ff348f59de543f69247ca767d0fe9a9d1d19cb42e60f027e51c039d2931a": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea8a08a4a1694448caf124733edd497c1638066d14b280301be4cedd4c6e2162": "0x00202e585d3783000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d872824370490cb6ec60dc6b19173b661b8cd3092307f849ae2648554c2874b55ad11374": "0x00c06e31d91001000000000000000000b114580a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f5b3d80dc71b786ce4c40c06e4870adc3e149cc86ab6fcaa6df5d11d17b74f0": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339772011652b06df87ff345ea26eecde2f440933eaafea167a2d460d77a13aef2b0": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c5da28c999767600d2fe868e6dc020010df627cbee00dee469c5e867ac6525a": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977bd9ca73bb5aa8135cf43b4a4eeb9249a276cf0a52b5d6230dd03d15ba522d52": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e4ec5901f7c0a57fe6bb079ee176007f3ee8e0c7c43b0aa1f1483c1423cb832": "0x009c7912141900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5f391cf308a53e9d74c2059ef8c4d4b014b5ff5a7166d404edc60aab7fe59d3": "0x0056b961800900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4a57e4c95a199a3c5e2184cf286fc177c97f9c7177b7c6446df6d41a1f4c3eddc": "0x0000c16ff28623000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f67e7d734b2897d18134c4ec00be2d60ecb57af9cdb2103bd50c31b235d2e92": "0x0088d21c5b0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b43145ec1b84bc01ac440b2f5a1a1394fb16b6f36365a44a59957128ded5ddb6": "0x00da332b59e104000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f2aaeec5b7a4d35daf770e97702705deb7bffb5cadbabf0021ddc3ca7f40e374": "0x0014ee4b971000000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b420dac970eb3948295b5873362b7fd3d9c41fe5d56536bdff875488a2f35850cb": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397641da552515a05d37cbb6602563f6a689c91252162749bb8e2af84365e0d4a72": "0x006aef77a62d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0b72fa51671297c01b37308555d530a79e0cfae883b1066fb9d9cdbe6916eec": "0x007ada938a4600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c294e5f14ae81750c7b76c7411bb14f908be0e9e2c4ba7de9ed537513553bf2c": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973b13e44df4fa62d7125ab2172fab67aa5f95d3b2fcee247006b2e324259b9f38": "0x0040f79c2d0800000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b5337ab70ef136f087f254b0bd523d4491993b2ce620d06be2b3d8ddd7a0ff41": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769c0157c8f3d2900da34ab1e9805b54cc97d31aea3734246ef14d5409ab248bf": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397743de50838191438dbf5db02abfcbcd606816954de07e2cf62e5059ea257c622": "0x00b0631b220301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a951aded8235570276f5736f2f8c894e5cff029d457d5b844e64068f13cbe170": "0x009a073acd5b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3a749e89a37889bf403224fce1d8eabcb16f011ff99d5e2fec6491a939ec09c": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a18cd96b09d10afd8c6fb67103cae0175fa9f3fd760959987c674d0da766f52": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978dbe34bd1950189ad587d2f7f07c22958ec884d0a23b77cd5e9b1b9396be2014": "0x000e1c29776e03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a2ec757e1d2ee47c8fed38ca5430f57f077df7d4dd47e224d9ea1beab48c322": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a525e5cc1bac8cb3eda1935adea48272da1a0f8c936e90693ad69147abee6128": "0x001e39c7e9a600000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b6092915677c2a2896def22d7c21611708bc2ff3efadcf152697a5bff2316983": "0x0090f5e41d0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f04e6d9a73ce68b78e53c9fc11412db4121e5325c80e09685fa8a3ce841c515": "0x00ca09fdcc0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a95fc10899f9939fe9f376f90b678d436e6cbd6cfbad752e1d16e1bd207970fd": "0x00aa8af681571e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be0013089e49d5187af79a902767da35cf39652bf8ee558f7780d185a484dd3c": "0x007202ee615f09000000000000000000" + }, + {} + ] + } +} diff --git a/polkadot/node/service/chain-specs/polkadot.json b/polkadot/node/service/chain-specs/polkadot.json new file mode 100644 index 0000000000000000000000000000000000000000..c648b425a4729e8f3de317fce4b514fe9253ce38 --- /dev/null +++ b/polkadot/node/service/chain-specs/polkadot.json @@ -0,0 +1,11717 @@ +{ + "name": "Polkadot", + "id": "polkadot", + "chainType": "Live", + "bootNodes": [ + "/dns/polkadot-connect-0.parity.io/tcp/443/wss/p2p/12D3KooWEPmjoRpDSUuiTjvyNDd8fejZ9eNWH5bE965nyBMDrB4o", + "/dns/polkadot-connect-1.parity.io/tcp/443/wss/p2p/12D3KooWLvcA24g6sT9YTaQyinwowMbLF5z7iMLoxZpEiV9pSmNf", + "/dns/polkadot-connect-2.parity.io/tcp/443/wss/p2p/12D3KooWDhp18HYzJuVX2jLhtjQgAhT1XWGqah42StoUJpkLvh2o", + "/dns/polkadot-connect-3.parity.io/tcp/443/wss/p2p/12D3KooWEsPEadSjLAPyxckqVJkp54aVdPuX3DD6a1FTL2y5cB9x", + "/dns/polkadot-connect-4.parity.io/tcp/443/wss/p2p/12D3KooWFfG1SQvcPoUK2N41cx7r52KYXKpRtZxfLZk8xtVzpp4d", + "/dns/polkadot-connect-5.parity.io/tcp/443/wss/p2p/12D3KooWDmQPkBvQGg9wjBdFThtWj3QCDVQyHJ1apfWrHvjwbYS8", + "/dns/polkadot-connect-6.parity.io/tcp/443/wss/p2p/12D3KooWBKtPpCnVTTzD7fPpCdFsrsYZ5K8fwmsLabb1JBuCycYs", + "/dns/polkadot-connect-7.parity.io/tcp/443/wss/p2p/12D3KooWP3BsFY6UaiLjEJ3YbDp6q6SMQgAHB15qKj41DUZQLMqD", + "/dns/p2p.0.polkadot.network/tcp/30333/p2p/12D3KooWHsvEicXjWWraktbZ4MQBizuyADQtuEGr3NbDvtm5rFA5", + "/dns/p2p.1.polkadot.network/tcp/30333/p2p/12D3KooWQz2q2UWVCiy9cFX1hHYEmhSKQB2hjEZCccScHLGUPjcc", + "/dns/p2p.2.polkadot.network/tcp/30333/p2p/12D3KooWNHxjYbDLLbDNZ2tq1kXgif5MSiLTUWJKcDdedKu4KaG8", + "/dns/p2p.3.polkadot.network/tcp/30333/p2p/12D3KooWGJQysxrQcSvUWWNw88RkqYvJhH3ZcDpWJ8zrXKhLP5Vr", + "/dns/p2p.4.polkadot.network/tcp/30333/p2p/12D3KooWKer8bYqpYjwurVABu13mkELpX2X7mSpEicpjShLeg7D6", + "/dns/p2p.5.polkadot.network/tcp/30333/p2p/12D3KooWSRjL9LcEQd5u2fQTbyLxTEHq1tUFgQ6amXSp8Eu7TfKP", + "/dns/cc1-0.parity.tech/tcp/30333/p2p/12D3KooWSz8r2WyCdsfWHgPyvD8GKQdJ1UAiRmrcrs8sQB3fe2KU", + "/dns/cc1-1.parity.tech/tcp/30333/p2p/12D3KooWFN2mhgpkJsDBuNuE5427AcDrsib8EoqGMZmkxWwx3Md4", + "/dns/polkadot-boot.dwellir.com/tcp/30334/ws/p2p/12D3KooWKvdDyRKqUfSAaUCbYiLwKY8uK3wDWpCuy2FiDLbkPTDJ", + "/dns/polkadot-boot.dwellir.com/tcp/443/wss/p2p/12D3KooWKvdDyRKqUfSAaUCbYiLwKY8uK3wDWpCuy2FiDLbkPTDJ", + "/dns/boot.stake.plus/tcp/30333/p2p/12D3KooWKT4ZHNxXH4icMjdrv7EwWBkfbz5duxE5sdJKKeWFYi5n", + "/dns/boot.stake.plus/tcp/30334/wss/p2p/12D3KooWKT4ZHNxXH4icMjdrv7EwWBkfbz5duxE5sdJKKeWFYi5n", + "/dns/boot-node.helikon.io/tcp/7070/p2p/12D3KooWS9ZcvRxyzrSf6p63QfTCWs12nLoNKhGux865crgxVA4H", + "/dns/boot-node.helikon.io/tcp/7072/wss/p2p/12D3KooWS9ZcvRxyzrSf6p63QfTCWs12nLoNKhGux865crgxVA4H", + "/dns/polkadot.bootnode.amforc.com/tcp/30333/p2p/12D3KooWAsuCEVCzUVUrtib8W82Yne3jgVGhQZN3hizko5FTnDg3", + "/dns/polkadot.bootnode.amforc.com/tcp/30334/wss/p2p/12D3KooWAsuCEVCzUVUrtib8W82Yne3jgVGhQZN3hizko5FTnDg3", + "/dns/polkadot-bootnode.polkadotters.com/tcp/30333/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3", + "/dns/polkadot-bootnode.polkadotters.com/tcp/30334/wss/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3", + "/dns/boot-cr.gatotech.network/tcp/33100/p2p/12D3KooWK4E16jKk9nRhvC4RfrDVgcZzExg8Q3Q2G7ABUUitks1w", + "/dns/boot-cr.gatotech.network/tcp/35100/wss/p2p/12D3KooWK4E16jKk9nRhvC4RfrDVgcZzExg8Q3Q2G7ABUUitks1w", + "/dns/boot-polkadot.metaspan.io/tcp/13012/p2p/12D3KooWRjHFApinuqSBjoaDjQHvxwubQSpEVy5hrgC9Smvh92WF", + "/dns/boot-polkadot.metaspan.io/tcp/13015/ws/p2p/12D3KooWRjHFApinuqSBjoaDjQHvxwubQSpEVy5hrgC9Smvh92WF", + "/dns/boot-polkadot.metaspan.io/tcp/13016/wss/p2p/12D3KooWRjHFApinuqSBjoaDjQHvxwubQSpEVy5hrgC9Smvh92WF", + "/dns/polkadot-bootnode.turboflakes.io/tcp/30300/p2p/12D3KooWHJBMZgt7ymAdTRtadPcGXpJw79vBGe8z53r9JMkZW7Ha", + "/dns/polkadot-bootnode.turboflakes.io/tcp/30400/wss/p2p/12D3KooWHJBMZgt7ymAdTRtadPcGXpJw79vBGe8z53r9JMkZW7Ha", + "/dns/polkadot-boot-ng.dwellir.com/tcp/443/wss/p2p/12D3KooWFFqjBKoSdQniRpw1Y8W6kkV7takWv1DU2ZMkaA81PYVq", + "/dns/polkadot-boot-ng.dwellir.com/tcp/30336/p2p/12D3KooWFFqjBKoSdQniRpw1Y8W6kkV7takWv1DU2ZMkaA81PYVq", + "/dns/polkadot-bootnode.radiumblock.com/tcp/30335/wss/p2p/12D3KooWNwWNRrPrTk4qMah1YszudMjxNw2qag7Kunhw3Ghs9ea5", + "/dns/polkadot-bootnode.radiumblock.com/tcp/30333/p2p/12D3KooWNwWNRrPrTk4qMah1YszudMjxNw2qag7Kunhw3Ghs9ea5", + "/dns/dot-bootnode.stakeworld.io/tcp/30310/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg", + "/dns/dot-bootnode.stakeworld.io/tcp/30311/ws/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg", + "/dns/dot-bootnode.stakeworld.io/tcp/30312/wss/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg" + ], + "telemetryEndpoints": [ + [ + "wss://telemetry.polkadot.io/submit/", + 0 + ] + ], + "protocolId": "dot", + "properties": { + "ss58Format": 0, + "tokenDecimals": 10, + "tokenSymbol": "DOT" + }, + "forkBlocks": null, + "badBlocks": null, + "consensusEngine": null, + "genesis": { + "raw": { + "top": { + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928905217a5ea7391027b88f54b550bca825d6108af7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289204ebe348564569032991905d5d1d4ccd35df422": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7081542596adb05d6140c170ac479edf7cfd5aa35357590acfe5d11a804d944e": "0x0d1456fdda7b8ec7f9e5c794cd83194f0593e4ea", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892a04068a84913bf3db84f450a82588801197e028": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977a2dce72ec5f24ed58baf131ea24762f3947ac46": "0x00b869b1edb600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e3bcb85f93385dd35ea005d6cb8ee5e093657f39": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ebb3b5365f80f437d4be00fffaedec844b24ce14": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890087e6f26b4df85ddd9b9b60910c593fe401025e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003bb46bab150b189a72adf721963e275453ddcc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f8a55193512202fe419de12ff41207968ffdce": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928916af41d7d554e5814b2a906b2ac27bac06c9a61a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899bbd5f8d33f607a03690fa73f177f5a30c864542": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979955dc870b36c6ff8c41567f6937f8277b00769c": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b4624dca7c8be0b12e1f883cd5a64da42ee200e7": "0x000010a5d4e800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f5d7b6314cafa1938306aa393f09f6012ab7288f": "0x004c98974d4000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51371bf1d2d980d73aaeaee5f7505502c8ad010000": "0x8431d50beb39f9d5af9a9047edd2ab987d35877815de7cd2ebc271db1dd9005c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51194c65d3e5558c3a49c5f803c862a76536050000": "0xc0c0f3b4bddf5f9fd3faf21c65b3cb1d917863107dc954c7f6ec55ae9a31867400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5154c5948820c02c2dded0a22b49fadae80f080000": "0x0e5da0878b3aa76231dcc38ba1c8ef7308df8bf3d50496e5d52e8ee76b9b965500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971b919a32ea4ba16c20e24ee83cbdf98b89c94a31": "0x00269b554e4636000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c6b8bda3f7adaf20a55a970706d195a3ef9a1cc": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513805cceffce797ecb69a49be25b83459ea040000": "0xaa92a247b4699210595e1cbcfab051163e245ac8747e9bdf9e48c73532e6dd0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ec12141e117791b66693d6ab5ca3e270f531f76c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891749564105214d51d63a7a2c1178203a4c0c4671": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ad03ba0db46620f77489393a7e62e598cd7ea988": "0x00f6781c6a1801000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ac8a6d59db3938ddbee19f4ec3ea8a0a771bf6e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d723190b070d3f73eda09fc58829629109630936fa4f60203034e17957ef64360": "0xfd164dfeaeafabe0d241e2313b57ea7fd97747d9", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003b872492daab5764157df79e40d853ebbac4cd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cb139d5b7f41d8b74b5a5027ca35e9ac8a7cda": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519350ee000e2003dda1ca40379edc6612e3000000": "0xda3e9e776eb3b7e775e51e6e91ce0bbc70c15bb47a87c639a3a37b64db46a04600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c16ee72ac33a6a9e5e887792c26526f9cc080000": "0x664dbd21a50bec286ed2ae25da8f41634778154b3ae6dbd93290bcae58f1dd6000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d861e5108e876877f742bdeb0d90022549b70ecd31dec379b90d0489b33fb584e": "0x005e14b50c77daf1b3fc6f12f3b4cf820a313adc", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970099fedd81ce071a859bc98a84b7bfdfc52f4242": "0x0020aeccd93000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970035fc5208ef989c28d47e552e92b0c507d2b318": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928936569c3f76b66f8d3acaa386be180b76c39a2f19": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517c86ed18de22932de93cf92512202d3ca2000000": "0xf032c776601ba298d9b688400db9bcd08ccd6a42cbea068369de450076cdbd5600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2ab493bfe56173fd911c6f476d0490cc85c83db9e07f087f0e08ed259664dd0f": "0x2e05cd4a04815510ab2d10464db9c1356cec8bd1", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfaf41a99388f45bc9d18e3b93383221b6f815298acf8b3debf235aa33509de3b": "0xdd41dde058e870f4274deb8cb2417eef04940f61", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c7314260d5f3567f89e0425b6de0189c3f040000": "0x0c53bca5a649c275c951cd479dfbe21e6c4bb9fb9c94dc3fcb6a71410825f63200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1e2b0e0122e7c8598b5e600b94d16d88da6f9b90a520ad2fa21bd3004bf2901a": "0x009d470cc85e114eb2b35c64b39f8a0e3dfd6759", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928905b30ed53364a95a0ac56b214077a85bd5992772": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928944696286e8ba88c8c0f782b33fa7527cf3a66e39": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d264a106d7206b10c8a97168cd25b2e0b7fdae7d827b50299366bf9ffb5939d79": "0xa4e325e0ff51a61d129d2848b0e6a5324bb42471", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890001e57b2199d16ae1aa1e5f4d24a83349ff6939": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3a15620906193ee1e02c754d33d5a2f78aa9568bd87e7c241dd73a6329758f53": "0x00185a694e3eb29e58f03442d75a8f59479ac8c4", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0830fe5930e891dd5912ead314dab09f8c47b462b478ba5f09f363ac626a3f48": "0x151310c5ed21bc68b85c5c754cfcc5a7b1869cac", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b065022613dc0585e7b5536173fbe028eb6c00": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e293a1ded3dc1b5f86121f41d9043cbd18914a2f": "0x00cccb758b0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4c3412318ed1dabfcdb03d1e7776a9888e9482e7c7154edd44603c439b65fd3d": "0x22128818393800d4123cbb9b81740db04f380977", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5113b862ce0e10adfa857eaca42c57d035f6080000": "0x467023bb6cdf712422c34498a5143b0c7f9d3e92e336d5e8c7bfd1da7f11947300000000000000000000000000000000", + "0x2b06af9719ac64d755623cda8ddd9b949f99a2ce711f3a31b2fc05604c93f179": "0x186a103df5c5131813fa77ba4f8be88b2d2b4a47323d2011c9d987615f067e9e783ccde029459535c8bda2aa6fc2d97af3880409010bbc05a15f8d42bce8f0176d5e5ab03e0bc62a8fd3fded0b09ac04c6192796873b38abceffdbd1548f35f61a6c694dbad86b8de9c1c9947e536b3391b77caaca86a23195a2b111b24b0d51643cfc25dae5d649a0d4f2775656419f2c9a4318584694bb60c66e8d0c8b96f502b09bbdce34c5bff2f9f212118c05296db12854ecd09ed0eb0dc7714c9337ce29", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339787b1cfa38fc11bc6ba0794e44b8fd5cdf98c7640": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b7482d5d6204ac5d40c673125ff1fd07d183183": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339780fd49b3453f8df565032a0aee096834600235a0": "0x002afac2d93e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d40bbe499b94672c1618d355759184eece4fddb4a142d3ee0b79d4de66b92e321": "0x7eb9c6574928e51488595ce200904de622a212ec", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890026ec71cb407474b48df42a58a80618c4e44e99": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c5d33619ffdf46315cd16bd053a03d2873bc37": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890b7866698f9b8920bef90aa5e16a0bbb238343d0": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dde7fc29e54e79d51f4a8c5d54f67523265c2a538a79edd0a601ee16cdc1bea3a": "0xc9f6de8445d99ef74450c9ea88efbece5f5e4d06", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008f6eb1f8852e3ec09a2a33ff19e4c7369ea37b": "0x0034fc4eb4ae13000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289449b5b91b10523f024b6d9101afad2f3cfe7c8ea": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928949e961c06237fdc4bb51c48813a8480e75701478": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a930215be931d1729ed9b5b3919097182b6923ff": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c4a991fd5f82d736df9ceee054511249b89f9a4d": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb382ca4823aec6bef2e240d12c7ad07bb0e7785ee6837095ddeebb7aef84d6ed7ea87da197805b343a": "0x8e59368700ea89e2bf8922cc9e4b86d6651d1c689a0d57813f9768dbaadecf716c52d02d95c30aa567fda284acf25025ca7470f0b0c516ddf94475a1807c4d25b09bbdce34c5bff2f9f212118c05296db12854ecd09ed0eb0dc7714c9337ce29cec7e2d5e28925ae9f906e5ebf1c81adcc7e524751273a73a278f472d863f5324c0831fc73ca4ae4d46cf82e74ad01549973d132795c579d40eed490cbb01524", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5ea8720587253f86842774d431c1f5bdfc3a044fcd46e435888ba44486c1fa0d": "0xa2096e3dc4c8173bb1064f33b005844a22513d03", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d38e956e11e3185142e2b50fcf2f02afe9e12ba": "0x00264979cf5001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6a2b356718faf8cce70e78f06712f1ce5917d04": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ba22a63969aa637e9a0d4ae31beeefe97ed270b2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51527fba669a83f267a3317183587940047e060000": "0x06a27940e88886fb198b8d92bd517084e259c3811495ceabdfc4ac5dc99c955b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ccda9de9a7a369174a04ebfc2d18faec1120225a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397549afb2f9cdb90fdef7861b65c2bcf80aabbf765": "0x0030345aead918000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ad5f21adf36e7fb8eb51391c3a68cf44de0ba3": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d504bca16b59dfc6f9dce786197e6fcbb082a8cbb8b9c7fa9b541720ccf6adc0b": "0x2a89681d73055acfac5c4ce4ed108c3ea7a84a59", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d78dec21cc26ca8e9a6c12f5f11b0a59f21829e0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700961f206d72118bcbb9685c1f642682c11902bd": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001895edb9215904d416dc35822c8576444e674a": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890013e7914c4e0368bb75176c58d7b85064ba76af": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5112ce71f16b9248870b96651f7f6efcc536080000": "0x99e562b4b9c2a56791089d0b56824b913c9e4509d15da48126e586395b976da400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900998aaa8fe8444322729f9dc9f32b41cd006bbb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897b0e85ebdb55e25262849ba46b0a3e31c928944d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928905fc2dc53c14f07faa71da549035569e14c7c793": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928959674388ca17d95cf03ca527665f789ac10bf4f1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975af08f5a0e43a3587ce7c8bfa21e77082e559f37": "0x007e4df9ba5200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa4be1af84fe8101f91891adc2d52a37b93dfd11": "0x00123ce8e27b15000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d36d886739e9ae36cd8642c33d2d991f613b3036c95950421f8e7e2b5ddb5cb32": "0xb4fcdf9e6c5fc7ab486cb70177e3676f1df239f4", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db60bf1d765ac0c534a544084850f794258e4c9f4e55965abfe9fecf52ea0c245": "0xce76a4eb328d7c14d3a425ac145f887d7277e6ff", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ebd92abd194f0cd6ffd845b0f7c81bc9b11ab1d": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d00e2711e44108938250ef0890c80128c0aac93fe6e146ca54e6905a1895ff061": "0xcaff66193c177e60ef230f8c45a5867ca46f578d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e64078aaf2bb01b7dca49d0257a43652f03813f7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e955f59b4abc283f9d5813aed5666666f7476f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289af44c1183aea35445f24b3b82073cc0afd007cf6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899346f8545c9f873b09d9265c2ba196b21fe3f838": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971206272257240aa1336db145d922a5509ef79e2d": "0x0040f09bbce108000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df6bf5945bd3abe20c1cded2b4250a87c47a13726ea2dee57f8a56920ef53d613": "0x00718f7d6f56e3aef4ae4d4dca50bedaa4bc4f3a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397741db5b3024790ff32fea3591714c38987948dd8": "0x0042b095ed0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f2a9c275221468f59ac010f639c06615bcdc8076": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5184742ad30e76e2320820ea709bd78b76c0040000": "0xda91670ea8e3b7b52e7b221279ce9dfe7f97d1c836ba42202f59d245d1589c2d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243731396ed98bbc215c9078bbc583034ac85a4995d": "0x00a007c2da51000000000000000000006c74840000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f19ab8f5c20d77119dba61bc195214fdc045e680": "0x00a014e3322600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ab9b7cd7311c80902b85d9536531efacf92085": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243449b5b91b10523f024b6d9101afad2f3cfe7c8ea": "0x00901ec4bc160000000000000000000001cb240000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d0c352dbc3f03762421093ac7225224cca2f54f9": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289238593df591076886834b28306cbbf83b333d924": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970032b7a3470928f2e782c4e4c636bb007631234b": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928998725bea9caf118e3e31a0fe480b887f81f45bd7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aa0fd755c0d0528c9b7633462a4570b75bcabdb9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397668dbd6154064e193ab693a4f79bbbd06e107741": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d5c914d49eef7110f4b178ade972bafcdf83f994": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8ac080a57b99bdc0f1a66d24064113b8bc5f728": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f21a0e51dbf4a93d9ff5bdd23d6c01775f1d708c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce856779cf6c02521d578ea679e1f013b277dc334498cd252aa76f9b6bb59649": "0x4a5b1ecb17b9ced712df12474c5588c8433ccb44", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e419f33cb1673690d0ba113af46c36e2392198e9df48ac1210e36258943c71e": "0x51aa47c803a20a6334e4589ca76642a68d3cfb32", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007c0b89085282ce1cdba3bbf12e1228547275d4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970087814a753208557c3fad394d80348307326fac": "0x009c7912141900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e585af0cb7cfcfe9314679e120318a5daa8644": "0x004069553e1800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512c02ecd74ed0b9ecbd5c2504af596a292c040000": "0xd69e158003222f6d68e25d9f39e881c74c2a833a6f048b854f79a03eec996e4000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289219a0751553ba999f730fc1af78bb5a3f255670b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa44cf61123c6bf9110c8cc4454cc241f0dbfa92af8719ae1c33334f90dc2970": "0x00aa83bc9abf0e8c4937a8ebde74a7961f050747", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289656dc09b4dc821695c9de996b762b3362e00a205": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3e5dc9bba6c0396f878c3258d641a53c41b0d9274a55eb4dcf59107924e38300": "0x6a6a46f3bceaa2b9799712e1d4413ce08cb8a801", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513697b525213c80b5bed52221897c735aac000000": "0x94134606e7f52b31b53c7b6c131e500b392182c05d76a729ae70c333052edf5400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2477936b39af9f05f27a86561c99f1bcba421ccb39a08cb1f58402796ef8235e": "0x00f30aa1a2b965b6273414c69bcdbbcea76a52ff", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700036d90bb4e462221fbe06403a023192c0e6c4f": "0x00a47a85db1001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007b2f1e74f2d7a146dc352b987b44bb49d0d6ab": "0x0034179fd39506000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900613989b259f1d4c333ae80a3e78e67446646b1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af1ad6a98e5f53c3bb27509177ac3564b55703ff": "0x007472471b4800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397edbf4187931cb3d852b762e5ff28fd6af6b761c4": "0x00c68d756eb300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b01dc922ee206c3906accf74e175a5fd38ef5c": "0x001ea1cd27b603000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289beb910ae193dc54411747ac236e67d221ff3f1d7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51df0373ca28b4732c0955e5a21fe88ec6d1050000": "0xa03f5afd74de173c5d2033951f8225e29d58d813bb078d82569a07eb7cf6062900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da203f552cab792a1e664d742c53e060f014328d8d2fa8eefe5edca90c3fa8a41": "0xd5cceedf3c21bb629353405e2e438cfab7c94c56", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51483fca30f93f5c61c502e482eb7d09f802050000": "0x4a2a23436d36970bec3b5da3286eba930a3bcd38197cd3b791397cd53cd4dd6000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2a21638d6758619800f032eb67fd7943490c20b5ab1f8453d11382769447d34d": "0xa59c51409b63f4900cc5c90374036d3a98f7673b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c6f3bf84417dd2c0b9c2d148b3cd0639c5b9387": "0x00b0692089b518000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397538d278e05a35c96bcdca1039e92c65b994256a0": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cbe4cd526f64beb3f283fe5afdce5192cdc261db": "0x003036d4980900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b5ad7945e0a91088537dc2f950f87883b0050000": "0x8c43e6504928c56f0151eac7575949a8951c4deb28c9cd1acb26743de41df80d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005807b3364cb222841a96051227671f15d1f502": "0x008e55b3603a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c2e1891250427bebe1e66c1d86d1ef010e4396": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d52c5195ab72c06d0793bc325a879ed2e1b3f06ba330ded7bda82855336bcf46c": "0x2ee824bf2fad9d0e360bdccd74c2b5d3f634b9c2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339709ee4979e687c267db3ea238a9ec64fb74140438": "0x001e0f9c057b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c12f8fec9a75f790a19e955ff87908b0a89ddc8": "0x0010a5d4e80000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5125374402a1bf77fba351444469d8a248d0050000": "0x00b9d35957bc6db556c4d0cb694c9b728b67b9694153087c7b67095bca47021a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339737213da6063363ebdae7ba5a3b0dee7e139483f1": "0x00ec226f1d3200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004b592365dccc0bcdc29fb82223f2774b93bfea": "0x0046240a010300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b72829217952e8237e00c5a1019521f30b070000": "0xee540d3a73580cf5e0ae2d80ac9d98dc27847f5518d62b652a6561d46c16b55300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928929c0e5b31ccbcc929e001a4828a62e09bd307688": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289205ef96ca87f9546f2d241ce8dc949c49765e4df": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7067ad6ed9252ea6d37ab1b78a62132bfc6340f": "0x0062231e5e1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928941f2f7387969ac7c06fa49a29fc479c22a9ec8e6": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b7ce6873ee9cd4a462a3e13fc8dd93d9a40ae5ba": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289db3a83ce2d027400f34819317f357e9e967007c4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397592f17165cfaa5397984f7306155d330fcbad444": "0x0066a69b2a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397460cad37045859b3f67579bb363d3e8f48c4df50": "0x007899ef09f702000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ea81627c72919ac393603aa79d4c7e00cd9438": "0x004c44f1ae0b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e163cf2b25ebddf54bc1ffa47a56b96e820871c": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51eaea4efc5962bb7a0597bd7e442749a665040000": "0xbe84f63b9e30f438711f49b4a2f3e251c541f9a6e43b0e9df4f64e8394ba517e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daaaf1b0d98b3fe0673c0cfca35d10d99e198d97e8e757b3bfcbb6b7d0fc0b676": "0x00aec6e482d2ec9cedf8f03072ff8bd27850e95c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c6b8bda3f7adaf20a55a970706d195a3ef9a1cc": "0x00203d88792d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001dfd1c89c8c18aacdfde2e1e30b11ec2d2dffe": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a728387999628bc1f493e98cf1beb9c604315e27": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514b780244285408d14414cef6644d005b2d090000": "0x4263bb05caff304086fb08790ff345aac33cbef0eeb795be86fe796e9e5dd91700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a44f67e79908d52a5d81bf30cd063a481eb528f": "0x00060f4d674901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ba9171e89937ac44dfe9a19a1307e54814ce78": "0x00b2e809461000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ef732c7ba71e0ac5b110cd10879df9089c20bd": "0x0094ba30f71e01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d5d68cc4abd796fad100f3bf0402eebe9f050000": "0x9289bcdc9cae01e2d396a8b70b27bfe77caf341e969c1175cf908a7ea1906e3a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cc3a572c4d49eeabd53154a59779f7eb6da912a9": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514c51446001c4e7c7ae292fded4d0912204040000": "0x723190b070d3f73eda09fc58829629109630936fa4f60203034e17957ef6436000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977bc8bc547457f1a52e7547baeecfde77966657c0": "0x00f8fd0a8e2500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775203bc03125befff8aed3b9fd687d8818a8b2e1": "0x0068367fe62d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d34285c047d5d8757551baa45e471e62e72f468": "0x00bacad1767508000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d54ff47b0c118a4a37b57849e03c7a1b1e223991e427789b7d0b1a6c152c41d21": "0x532276374258365ec2058848caa8975da2e9dba8", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db84eb79af3f341a2e12f5e215104df773cf4f7746226afbf0f955dfecdbb9d4b": "0x1749564105214d51d63a7a2c1178203a4c0c4671", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700908f63171b29bd00a69a2c0864318843bf169d": "0x00a86126b02801000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cc1162ef65ff4c434e986880d325a2705cc64b37": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397034e104e2767228cc99fb3aa5af22db30c428b12": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d42cb52bfcf607025393c55d84cf361775c5a3914b69d6f78c93972b8eff56507": "0x6812d2dbd83e65750a7db91ab8806972ce170be9", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895ad04210ddb16c4b66644eda430918fd5826ca17": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005e5c04f113b7ca7c62a331be999bff4f0ec44d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef30979a1e72cc99c93805d076c1c44eb90ed895": "0x00483fcba02401000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515354818e4346284db7df94b81af803f3fd030000": "0x622140277a3ac51d0b235438d6c40c282038db51285130194d9f61bc3894e67c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d1b96a31ea448d0213a11aa8c2cda340d1335280": "0x008062175ed15800000000000000000098fdb88f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510a92f8fa62d4bd17278e0dfe0e834e7734000000": "0xbccb08c3fa76ca4db33b9a8b1e52b40e8b3d9b1ec93e47c774f631019907951100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eef2e4a5f6a01d5fb89f38211fb4e6a8702d33b6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfc504c4be97bb6552ef8e0dd3646ae7273605c8282ec2ff1f086e4d7af536c23": "0xaa70dbd775c74c3182ccf34636c63637b49a8f56", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d565dc10edbba93e52936f84801076ff37f32f90b28491a8dff3204ec08486c0d": "0xb8369231f4ee7d48791e4b23b789a6de4ac1beb6", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51689ced527103cc7f2463a48e5651d1e265070000": "0xc2736969960ab728695cfd8b866b2d1d1219ae9799fafbf20c2901779ca1c27500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720766f01d859f1ee11e14428d9fb96bb1ebad946": "0x00900260406909000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e92133cf03d81c3a6dbc919f19ddc3c3ae95f354": "0x0082377cd53497000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890002f625594208e49a2a858a109794d50276bf82": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a3182c6b3fabe222b3bc13c912232d037bd765d0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700843587f711b5b15b4b234450e0a3ac1750e4b3": "0x00b0a6277a7802000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928926496ea4743de7d6927f107151fc67616fc0a4a2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0e9511e878e0deed76cb465595c6f558d9cf512f8632e43feca07a26d0602152": "0x1206272257240aa1336db145d922a5509ef79e2d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e09656727d41176c0b8987f684450af02eda1466": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51970331d6a2da0031310f1ce2ddc8b4bb77060000": "0x20e5782fa85cb47b81c3eeb5186e5d5a8288c92e1cc9001c16bdc6a2c194cd4c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397196fd44f1f3f36458e9c36324640a8e7ff5fabfe": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8c2a3dd76bbaff6c13be1d583b3c95aef9e773d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2c01c997b6df6a1ae8a1475e6cbcd1f1c8d9b60d2b4aad28868de3e61d837a68": "0x3fb4981d33258835ed1de86668344ee3f08c626d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f65fe2f2d8215e4dfdaf150b031259ece9998f8a": "0x00188d22dd1400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512ae6e3ef5f2137b77cc7b528d687771d93050000": "0xe828c1a8caca7d6b13de01babf4dcff99beb7f0b6dc743a355e77cc24614855d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d522ed1a44f5b6302feb8ae1d71e42c6727e88c94f896f68d5aa214a52ec89e34": "0xa728387999628bc1f493e98cf1beb9c604315e27", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397805d90d33dcedad0f8efc6510dbb067fe4b36674": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a74d379117fae37e0f17f3ad6634baa201af20ee": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc0944541a69214a840390dc794232b9baed56f93fd4acf46cabdeef8e5fa8962": "0x9d6b708f01044bc2d23ac51ed5dbc7563c46a6fd", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d48231493044b6f421fc9e9ca2d9f1f0fc18ebeea1d51035a5843b82a70c88101": "0x862453aa222291ad19396dc22a94d2688ffc08a3", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b4f9c11f2a5c9f6e2b41275cdd915da7a8070000": "0x1ed7e0cc71b2e17e00fccbb69c8fa70a32da1a96a83e2ee44e30f05678b1da0600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003116c624463619d017b4919effc6deabaaf09a": "0x005ca0805b8100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705a5830f9d6fc22700b9439ba20d15531be0c789": "0x00385308034c27000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781d94d58834fdbb584d72b40429d43cf42f70aef": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397edc6c4c1ae525da2942fcf03c7b98c12391edaed": "0x00e40b54020000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51162ce5aa9730b05c13aa40e1abab7a2ac4030000": "0x80fa64d542fe68bc290ee68b8b71c568b1338488430d5fcc67a4b5bae97b370e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900973738d8b9ff38e9af49f5c7b511f41199c106": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891e825b93af6a21bc084f8f21d59398daeaf2ecd1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893518a8c749b8c46685b5bfbb5ac32932edafc9f9": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51eac5175e1ac76bd5b048ab363707a326a4060000": "0x4e2629f039089150d0cdc2988f05232b306534567f3c2a2bf93075a82a0fa11300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002da979ad2e50484456020e661e39a076c2dd33": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba10276d69a11c6ca944dcfecd669325b67614eb": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890072ffb8069bdd4f791fbf9352a7226c7f46ecd9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7a9b1c894620751312656b66c7dc2e333cfe677": "0x009457819ffc00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009151601c379b0c211e12bb1342e183857126af": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289442bb3cc2095dfa3447c774c3ecaa91805c4a94f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a7917ca8ca77855eb657fb414a3736204e4e3cca": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c155940fe345651798e48f29c54a2cd860304734": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d14a05377eae1b20f0895fd7b7eb55ff1d89bb396c311850605cde11befa7f923": "0x02fa77f03cddf7f1ab675723e15e88505da9a025", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970047b7702418e3f3ac962feee269d4057214997a": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f511e2cef19f48355bf52d70dc291f2e9ad16e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339756f780c276f972ecf6363412132bd9801204949e": "0x0068367fe62d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d221cfba0cf7d028ceea3c4e5f8cfbc76f2a46d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397586e945c70b8411172261d48c2d549e52aacf643": "0x00249ddec95400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc01b6709d6c07ce5a82ce7b917ef8b19fc65646709877afd79ee810c24a08d0e": "0x006cb4d719cad2ba7ac9cae5520378b76fcbaf1a", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510c71f795849e77ea70d6cb27e1b72f5483040000": "0xdc0293434648638559e1a4cf30e829f17d2695980d5a3374af8d663bd521490500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f50d1357a060256a94e9633fed0398f047050000": "0x5ea8720587253f86842774d431c1f5bdfc3a044fcd46e435888ba44486c1fa0d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c65722a0772976ce0ecc020f2eaf0c4468b919a": "0x0024858b773000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979da50c01643c31e889bb2ff6c0ed168c8c22f98a": "0x0020034cf68f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ffeb0f01d4f388904688a9b4d21c3c9331080000": "0x20b9c82a5cc380317eca92f17436eecbc8fe948913a035db183c30dff468798d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bd9d6e7489a7b450937fa7ecbabd71be819bee3d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c771ceb58b220cb663c2a77b37558cde21c471ee": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f6be6461b1a0badb3d4458da2f77da2268b83a9": "0x00a673ea82c503000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d20d2e91f70891ab5b5ca943b300d5b056c47a2bcc5b13efc7c907bd73c384c50": "0x126e1dd8189d7a9d7d1b3e927339fc58526dae45", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cbbedda51e4c9cfe80f429f6436a53c9738b59db": "0x0042c538520207000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243f963fef4235744c3cd26d5a3b155534f72ec6d23": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979019ec6a366f30602f324bf32d91fdc926ee23e2": "0x0090abfcc81700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000ee102d3ca744851a94c25c3eea1cfea5bc5a8": "0x005094aea18c02000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d981ad92f7900ec801b1935618f031c7d69f089dc84e2fd2b4c09045c8b7bd658": "0x177a47426d4c1a6a65276505167c36b663db2575", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397de4d5886da98c3a1140260aaf536a2f1262e2948": "0x00a07115479803000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d17ab53317cb7505b62c9306fb5a569889070000": "0x80e30c47a3fc276c022612170e25be798153bdc6fbfc229c398f58064624297800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbec6a380acb8489f21891545cfb9b4964bf0f3170c5deddea166cd8f87bf2078": "0x2a6625ad8643ea9c894da55c4a5393bbcb59446f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928935d4fbfef171c1f89be9fa8b14a6b4bcf8ff89df": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900171d810de904efc8b649c8224652ef9b75e53c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893cefad973ebe1f54b6e790c823f90f81e95f4aa8": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfa2db1b22b343a78c282caf8cf333bafc9e08446a7f1b4c78b36dc36522fdd09": "0x28020c484d59bc36b2741d5aa1e1d48e6e3ab0e8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f09af5717a441341ce58f1b2bc5d9df7c1ad4fe": "0x000822b9df0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d040fddcb4b5b6707697e2431f7330ee99372e2a55b955bf7b93f8a853d07f10f": "0xcecd25a7e218c0cdc8fd36c50d1369a691f56d90", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d90c86ffd4c51b7cb742cc247b992c880bd23d00972912da343d1dee59f118e27": "0xe3bcb85f93385dd35ea005d6cb8ee5e093657f39", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c4ba011e13f2f735dee87c7801001ef5e7348d0": "0x008c5b88af0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a305168cbb7ce64213517ce4b9fc6c2d8dd8913": "0x0008bdebc10a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893955e672f3306fd39545edb3d7040cf8de2f9180": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894514bcb1596297d8a9110c03306b47429203aaaa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928951e9ebaa1d6b6029c88a42bdffe81ab4956cc062": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51207837764dee8239af5f22fcb387433b33090000": "0xd2610d42a7cc342bdfac6abb2efc488ca51c5685a3cef97ffbf3614a98ecd03b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51976eebe6cad96dab1d369010f7eca8f9b1070000": "0x3640b7b7fbbecf967f99ec9516a74f9e255efa5c8529751a383afccfe936175e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289782dd81060bc85bddb0ce7b2a53eaddd9f1f6aa0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f00a83c85b0a5fd088b7ef7cd5b4910ade729d03": "0x0080ca39612400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d68410aa34e30d94c8f4b266e5d9db3d14f44242327d9266877454ec70ae0cc47": "0xc383c50f156431e8f7187e0c04f14b85ad4aff27", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ec6ff8b811135779cab408d1449e9ee75703e8c7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd43d053efbce28083bf144fd919b8b5338e67f71b349ab9a4dbaa71845a9ca42": "0x4765d5715c351557d5242e3e6af8e1365ed5d08d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900597dbb469f69d8ec4de77af1da483c6775a794": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5025d1377cbba45a79dc41256dcb4e5dfa71c53ee3ae46352f2a20ac0f542327": "0xebe4fd701cce5d001c481f5662d1e941371c49f2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ada9f2058fada409eab656d7d017f54086499bba": "0x00ae670f0d2300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900388e518f2aac5b12485f3e2dafa9aa8262945e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339742d0a88bd5baa87a3cf4b6e32c7b6cb3850a3aac": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5140904aed64ad8e41cde44da1521b74e8fc030000": "0x605fd1308af1ce85bab5ba3fb19b330ab7dac29e01ad501420560f44df7e0e1c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006d966f0ad73ec431cc6816f7436b8486f1b25a": "0x00444b753ec100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fe4c20335a78abf60128c5f0a375a09d5b64e7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518becf6d107eebae775b19f003f0649f2d4080000": "0xc0103c4b56ce752d05b16a88260e3a9e2c44306602a74c5edd1cd4ff56356f7c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df449728349d850e44f8043b65efd6be7d8db8f4360fad672bfeb2ff6a304877c": "0x0183f3866e19384aa414dadfdb3f18395b36f631", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970328d281d559d1e3aad4059a8d5a137e4dbc663b": "0x004292e8484a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289839c073864b9958f0aa84446302d41712b1993f8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d3e9d9cc92f6c3802baa4c0e2f3bde6c3c37c75": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a09c71abc6ddcfeb38b68eef7d236d0f4b94c11d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9103bb6b67a55a7fece2d1af62d457c2178946d": "0x00d8b10d918100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1af976180cd02a36b76a442a92af3bf89a15500a334d64271369d1b41639b476": "0x50d07d27600d0c2d74c22befa45e749c3d3f090d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b2cd0402bc1c5e2d064c78538df5837b93d7cc99": "0x007c177bbd1000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51aa27c4831d4777f0b723b98f133ac6d504050000": "0xd68a0b50d9c1fa1644238aed53f0bf7b0926a143e1568fb13f1d9142f6c84d7600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e070de69e6cce7c2347b1b8e8bae4b68b04a8c6": "0x0096af54984000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009b72735e42cb02b19f88204e08931c633be665": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b505830ffd0059f9a3d98c1eebade1b8279a40e3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971206a4d89194c3fa52d2e48bddfd64f38cfa7a53": "0x00cac9c7bec709000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51565ac881d80625f6ef0bbc5aebadc96d1f030000": "0x0c560bdbdad78ed9733cf5906595432fabb4766695333562c45a512de84f805100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddc233e94075cb10f5f5e60e39cf7379b2fc23ee8c1b64ac7918dbd3660a1f64e": "0x726a0e3227f10b8967864ea8f7fba8b5637c192f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975529ba8a2dd48942abc90f9d08667b4e0e7be69d": "0x0070ca7d0f5501000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da4d723984b6656d3c74af107267ef2f8177a8621516544ea3025f52a3feab619": "0x00e2d9f005a1d631591c5ba047232a6516890a9d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b104f528a2f421d2ec9be3364b7f266fa628e2": "0x006240eb873f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5160bb8baf60db71baf71775ed56c92f83cb070000": "0x5591b55d2c256e25c03af5647edc09041fffe640cfc9be2889c1236e740ec00900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1ddb8c1e2204a92febaa4dc7242590cb74359f1": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001bfdf3604e075218ba10e202d13bcde0382ead": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b72e3cb05569922440ec3a39875f98af237e42": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289549afb2f9cdb90fdef7861b65c2bcf80aabbf765": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974659d80655ac837fc7f48b96aea70518da7a9082": "0x0040900e0bfa11000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513647a3325a1400967d53603ae7615b4524040000": "0xbe921850b08e283ad8e9fa23d55b6b9a50223d4bbde1f86884783c861944524400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893eef4ebb6697b4b0408d4394a37794b484f3f9fb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4a51e088519499f09d4efa334b901675050a1d5ab6fc66a25eab4dc38a9b097e": "0xb32816c1386cf0f7d5df26b4ca5921730c6f0ece", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976189e56073fb6102fd6c0fd5f0d1547c4f3fe350": "0x0056d410e45300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517739b8a3761d573c1985df6c46854b01a1080000": "0x449bc4f0c813a72037bb8747e3c2277c8e2136052071a3dda29af93ca1d66b2e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b4fcdf9e6c5fc7ab486cb70177e3676f1df239f4": "0x004cb4d510fb4a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397deb44b42a9d5c331e0e03d3fbe9c7a9496872d05": "0x00a452f2812100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890047b1aae6b63c54033f652a84fc05eb863ab1bf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f9c86dd81e7c9af956327767f5e9c5da7a3bdf21": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc8e921a1e3b5b4045d4bc9ac039e586c127deee3762ad2082060993467309268": "0x0003664d63acee3b899631c4ac4615f402430330", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397daefe0f07df89bd8236d1007e80f1914e2b85853": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928912980b8c3399747ec2dea6d7586d30c43b9326f7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971098afe502a221d6d6687077daee2b5692faa9e5": "0x00461501481500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001597df1153c433614b9dcb4ef8f11b640e19b7": "0x00ae9f92970000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8b29dd8d38485d5f9324eac3ba03c31a71b47e2": "0x0080e4f642df9f000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c0bb615eda6512f1a95869a638ef9d21e63469d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289584455c19de7416a22e6832be0c35516948fae82": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975124f80db491ec897cc316a5e11bc0dac771128c": "0x0056103f218725000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3803ceb541a628b43ee926b45440e6be38d618b955444001639cb18b1b685001": "0x001c0a1988b92b2538bb264e649e285bd78beb07", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705b9879bc7d504d8c242283745eb9ab59fd0763e": "0x00805c14b01701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ffb99b6c2fcbeaada365a38b333eaefef3ad99eb": "0x004a5eddc34200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51667a518b5cf12af147313fa410aea87ce1050000": "0x58b05775f004e33d9212457b1f0e246dd665f76142bdf5115f561180acf0bb3200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006d966f0ad73ec431cc6816f7436b8486f1b25a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d0c8f50cc79c2db25a9287e689081fe466060000": "0xfe020b75ee933b460f88ad71502469ba44fa6ee9590f9c14321b97484f8a8e3600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d21d90b501c8f1a883642c9158b61c987753650d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b0fe4c9158992bf5af9256b0b4793dd6ef42711": "0x00b634136b0a00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e1810ab918751329f6115907200a2e604a040000": "0x22bc7c1d9f897c874dbee193dbef08a2796a31dc46ac7223db1b1bd61d47db2800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de043d8f7872cd895f8957c9179c4264816be3e649713cb3bdc523f752602cc3a": "0x99faf90716291c57b7958f26bc0268b837ef2418", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbaa38e2043aa15f54d2febc1f3218827d08767a15cb325d19fde69f7ce62af3f": "0x9c0c36cb561beb841efcfc7212710d0c7b1bb187", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b7cca43d3978afdba4ce49a5ef38c28516050000": "0x3032a878f698e0ce7cc3706da046062a0c10a30713345cfdba86ceb38d560e0d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004935e21786073fabd32f21b6492ad354ad871e": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d0d4cfa04b458077b80a2b625bca31d710cb0e9": "0x00301a45ba2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516314dc334d7d6eee60e1fa0b9156726a6e050000": "0xcc934099b134c32666f4cd05609766f1def7e5bbefde6edf66c9aec477e65e1f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b21e0c1e2cb89951d7ca49778dd0f1b747040000": "0x189fb4ccfd8af44b0027a7461e069906aa1fec05da7ac552b54d651fd14b881f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cef45cadd1e590c243490ad0c0fb9bd0a47d07c3": "0x0004e7dbb3b303000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817decde39c637280f59fd38dfb06099f3d6bb049e91b2ca221ea93dd7461a420a52": "0xf1b8ecd32d89c484ec8ad5e216e573c03de39b0c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008550c3b4af1fa7a4503bc9e55a8622f213138b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896d482c372545dcc163359bb181126befde763314": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a33674bcbdcbdf860db590db177e3ca258795121": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243b26577622b961191d9760e43cfe25ce444b02807": "0x0060725ed1cb040000000000000000004dd2c20700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dca74fb0ebfeab701b8bd771fa5e240265832961": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928927fad8fa4f7ab0d981f0a5635cce2895f786e59a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5150d2f946b6c14fe037faf9dc1ba6d295bd050000": "0x80f9384b92e09042571a9e5cd43d9656d62acfeb0324ff44698bb2cfe422b36b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f3b383d191e038b067079e267bfdf3c70b422a18": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ef30979a1e72cc99c93805d076c1c44eb90ed895": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898c6778f77b22cead996a7bd73de2283e38d5aa4a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289530d949961092c5fbbd9a27e48902155e3208a64": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897a2dce72ec5f24ed58baf131ea24762f3947ac46": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5108684ad5dc077ecceccdeda475bb7a8c86010000": "0x0c08fd32ace7cf4d4689ca90420a0fdae83e637bd6166611a6c1ff2c3f17d51a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a597705df555e27d97c07b97e277d1169eba89e": "0x0026028fbbd200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ec89b84200b69fa6bc48793405af37706e7cb3": "0x00b0f6194b2600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cf14cb2a1582112f352b2853400b532891e6eb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2871403d3277ed54a2745378fc937e98bee1f7a7447331e9e05eb559671d9645": "0x006bc93719aef20a0258f9371a725b576c046148", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b51113c775e15754b42a7ffcef1bc3281adfc01": "0x00089d43ad531b000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e4fc54ad6d9b96543f33797cc384ed2ee33902dd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fef3b3dead1a6926d49aa32b12c22af54d9ff985": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928920af7b38515f4fcb71c988625bc3c35d510ba7b3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9eb97d7b1c97639a6914e0cb56dd8e584910646": "0x00c4fc1d027900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289290da05daec7be770a7c20be2881abc1ae2a4e8c": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282439fd1eba5f41419b2887a1e36e4dc22598254864e": "0x00b0a2f9e79201000000000000000000c7f88b0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896b0c4f552eee0531a134802d847c8f2fa0ca4e79": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d5e9ea82cabbb9fc6b0485d31b5fd5bf97431d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339739b51396ef3c70571ce86532feab5598a766e8be": "0x0060e17ff11901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282435cd12fb4761f91f6a2bd4240c73e7d8fc8a3f638": "0x00406352bfc6010000000000000000001ddcdf0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cb70a267c49250f5c85f0c4008046cde3df51ec6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397db3a83ce2d027400f34819317f357e9e967007c4": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b690005f19d3b95eaeb7a0a8ae76e49962030000": "0xde566e4f0d29c4bfeeb3d23a0a9f923fe62d7fc5bdf8c9afd75506bc8fe69a0e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fa6dda94cd91f2160d9d7d091ef0c7230520810d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007afbd65d5b7651dc8540420ba3ef42ebf62c5d": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824386821570ee3ec4bfaa2e2ffbbf16ee4f61336dc7": "0x00f07a75c0d001000000000000000000790cf00200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5183c2b22810498782b3ea859b6cb1376bc2000000": "0xb06e66dff95cbb0f8ed61ff4a4e400fff92c8a7a3c5b971e017592393e364b1700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8040433695ee5bcae5ecd8b9a2f329c8d625f74146ad3060104914f1cdc72414": "0x76436bdf4f3b3b9abfa08f825d2db471a4e33507", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ae6869a774b00ba29794c8d4611295bb0d9c2bf2": "0x0042e07d6e5703000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b4e04b8555340c888b1201d2cb15b976ff060000": "0x46ef2823db8925dfc223d2be94661efd2e77286cc9ed573d94c0391d0622262d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7cd6988ebf11799cd1e193aef0c87b6475656d42572eda38d962e05c76260f58": "0x69a80ca39168c9bc6761b9a326c6f15735139e0b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6052a08ffad405ce2bffd714c580447afe20c80": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008b789d4787d4b2688f82f0cdf9f95ac4865d0c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5143e8dc2ffb0aef04881515722db8ac47dc070000": "0xdc9fa5280bf7a60580e96e1617d22c1bc83f6358777c9b3d8b1d73548fc9152800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e37562bb4844e827a9b9fc94ab966edb11000000": "0xbeae5bcad1a8c156291b7ddf46b38b0c61a6aaacebd57b21c75627bfe7f9ab7100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720965e529c2a05a2630d84b9809be93b76720096": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339703b98c95a07743243350cc5eee4ee030e8e09d06": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397453d0ee5abb40b1c632506cd5ac93ea8933cf33e": "0x001854c6d40c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897cee83aedd18502b30da96e6c96f6a1be237f949": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fbdb3a61bcd4cbc31b50cf8c86487a3ca2040000": "0x2e6ebc8ca688165b98479e557e0f1722d08cc23a910b99d73152f8777f6a3c1600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289188d44d65f4198e7f2714df73b099330a4bebd49": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700241515212d8321ca983eff69a2bf11b58ea42f": "0x0002651cbc0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891e7aaa4af7293898e3d1d70fe20cbd525c495818": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979157a5fbc82a5eca9ebc3a225de072b4ebe7cc30": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928943140ac2d3c02cba8e461602cc15c3889dd9fa3d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd439e90cb7b87858601acec7aaf207b47e406c9779b3cf0d4dc03466870d7c08": "0x00bca0e2071d5f0e59803828bc7e0d3dd67e4215", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b58305431aee894728e5faca9e6cb28c28ac7a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5184b95a564a725826645fbf403cbdc3b088060000": "0x44450201e6957b7ffdcc7f63d42477e336461ed6d74410c812d79c3081ad8f6b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df89537d3a6e3eea634392a7db7096c70319cf6c7a8806d6312ec58179e53c606": "0xf3b4bfb9fa5372a43bab26800f6cb125c922c452", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928975f095e103de3ac2cd8410ed059fdd5bd050d21d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5163105188b1414e75750fe5faff6db93c3c090000": "0x84c74f819ebdfa0b67b0807eedbd49cc649a38b769d42632458c6a13ea6c541600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928998b6371f584b45a302d9f09e8741c4f0e4526bfa": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d30e781c192463969c3ce7dc64ae7db4427334cf542998ee6e8bc8fdb83168f5e": "0x097b2eece415aa2a4a7b1e0c310c81ea3ee1e292", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5139dcdff5249bce60ed5bdc84c0c674d161070000": "0x523eb91d3fc1ccd920cc991e39c6fcd03d3ea55a6dfda2eb971ab595987ca37900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f4bb083f86ee54172695e239f5aaaf0211050000": "0x8e8b7a80b5e743654945bd74ad666fbb76f5bd7e468643470bf889ee9de3a32600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51aa2c228caacddc4d207b320eea1b45ef23070000": "0x30cfdb48ff7f33b08499dfc618a8ef9699b8345fa65f0b1339eb8eec3c0e455500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd6e1166e5621c7bb14591fd4530a0424c3089260083b087b9d77e2cec1bc31de": "0xebedde101b40b694e2e90043403c1aeaf6e7140e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740d0a40a05c43ce715932731f2ae3f6b0fbcfbab": "0x00ba4f31a30800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928911feb627f21cb0d2e4daeb7f8aeee1fad6574704": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897574855f00481cddf4c103ae36ddf6e042e5d367": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008ab9fdfe08b2cc37703e4fd5f1312f885cabb4": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce877e2264669fecf930d064b268d29020a96f910282d642f96e2052a5daac76": "0x2a04068a84913bf3db84f450a82588801197e028", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700afdf133993cc0d4101f56f4b12a0504024bfd6": "0x007202ee615f09000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890077d40b5898cf2fead807b1589e90142b99a3a4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928977dd7978b817865a780464f0d3628e800a47fe9a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970093422567550d4787d6a5e41b20844d6e0cea87": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007e917588d7a1392c3604501e00a73565d06845": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289213de3994517a65ef92c7ad4ec9b824dcccc67f5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518c67da06f0fa83826e45059abedbc70476080000": "0xf2ea1da319a6f1135144b3daa5bc1c34a92dfbcfac7f3a77233ac12009ab3f9000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cfb01de1720803645bf4e9fbb470da73ab000000": "0xb096a731f7b2b62dda5658f829976c2226df044ca3820f3fb5f805f9651f801c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f651fd29c612a4b39a1a19cc749fa099f82ec9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799ce75400cd94e1277047d0913ba8e6921aa1637": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928904867292a47c5837759dfe13bc70bd30aa01050d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928907bec2143e7052bc6608c012ea585984f8f9b27f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289538d278e05a35c96bcdca1039e92c65b994256a0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e1f4258fad2126cdaab3266e9caa82bd51692980": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339713983684c4cddfc884ad85d31f5e46f078f13095": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890092aa89dc07f1080415ce14e85cb02d97937255": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c0dc84869b0efae772635a889ba9986b28c0fb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892ee824bf2fad9d0e360bdccd74c2b5d3f634b9c2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc02535f37b33f8787bde96761f4643f2229a0d0553c81883939d31215b4cc308": "0xf3e809c51300ca5731ae485be9885098ea8139d0", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928930da5c03ce04c15dfea28b7466b5598e0f48c1e0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971cc55a8304d1fab6dcc1003d16783eb213620293": "0x0000e38080f44d010000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a1c45f47adf9afd4df16500a4c213cf52af55f88": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339743a6edd95e865b50426330da71638b56f2a75c21": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d4f741b495b845b4e4ec9bb7851f71c854d4a9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892cb9aa7eb7da683a1feb615e780bfd52306aabe5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740692724326503b8fdc8472df7ee658f4bdbfc89": "0x002af235ca8602000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282433cefad973ebe1f54b6e790c823f90f81e95f4aa8": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5167b6aabb7b8b226788bf58f622f48df5cc040000": "0x40145d31d0a4233efc8d72f2917e57d3af5631e01550629ea87570561fbcb95200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970001376e9c388b5995e3a115f7d2813dacd35078": "0x004a5eddc34200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510a77fdac21983fb7c42253ee46c780ee2a030000": "0x42b941936ef857f9d5b97908ca6a7f2c0fec05c6dcb763f9e8d7780699a8b23e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1a6d83de58105258076725b05d526d8af18d027c86f0b702ec1143946f4fa23a": "0xa79d6c7ad0312485e375127d0844a4658b220fb3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c84df4cf2dc2f818925a0cc7a14b1a19edd5e2b6": "0x00a816e30c6014000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701ba3841bbe358c1b3a9310d84ba98bfac5fb318": "0x000ec2dc1ab816000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e448f88bdd86658308994de3c90a473f04abb4d4": "0x00b65c7e590b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891b282f5fe4bd0bfda21a07f7184bfd720bcb0886": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890dd9b78c6d063cfed41ee21c7fab626f86b64de5": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd4d775911ffa93f25ad53bc9243483e0ca632eb22ea96ede54c71b9a75060b31": "0xdf423fe29ac1331bfcdc8e01f2934a971e4dfb72", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dbddc3563c920884f1efd111c93ff30d3d8465": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d709326ed34f4e04f9cc1808d1bf6f368c24448f9327c1926ec673fd5093e2c70": "0xd67346067f88f10855b3580e8230dac8650116e4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc03c8f4f7484323459b2b4910f2f67e59c8d0dd": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824331369166ee8d31fce7b69d3231e42245b117c9bd": "0x00404c948b3203000000000000000000348c2c0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974877170e1a23388f4121c72d6b8cee7696ab92d4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928923a7e13e72a9844787fab89ca269940f80ae76f1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5112baaeb2febadd7369b029884c005aacc7040000": "0x3af8b075de8a04f234f06c62ab44ef258be19bce462385f9d03c1244dab2734e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da0dbf685db6681f3d704f4a2c6890f965d5cf1f2d7fa169a6fb5c25f8a4265bf": "0xcc1162ef65ff4c434e986880d325a2705cc64b37", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfad04e90c4a85afd98a0577632b4e720045ea8b9888661b735d929cedede390d": "0x48c13b7bc700451b3d801023cfd6b0d1433b301a", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c61cc0c61926bf3783c7915045c1b41f01060000": "0x98e54d3a278c69a0a65b7bdc5a82294ae9c59fa7ef908a41a3f479ae08742b2300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d68b96498d1be734042e4cb74d95fed63cd8c08ebc7dafde5564107e1c1a24d55": "0x00dcb926da7ff3bdd92ea659beea369ef286464e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf2c5698312de5417c17d2f7a0e7d8404a1ba62b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c8e20df2aed2601379f90cca198dba99cbd8ef": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51abade770045fd2cf341a9c0d4594a2052e090000": "0x72d8647fca16d78cae19f6186371a4aa9091dce52f566f05834afa9ab177dd2800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9e743c08f7db2511b7d73fbf70d949c62944ab8fe18ec19690f2ced2c0fc3514": "0x006a8106e821a1b44cb0626f7fea5a951b11a282", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517dc9d04b35621534da9cde5c72aad9208a060000": "0x285f6f5fc6353dcab3853dae25cc92bb18a849fe7493b654338a3527d9d9da6800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c003133c97db8ed8cb2d008f29b97414fbf48f62": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bc17ff2de0b6577aae386e5bfe8ab7695282a52f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397987901179f790fd04e956173d45fcac9aa74b66c": "0x0074b138558503000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ceb2c93a77979ae759ed4d670e15b5674cee870b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893a9b0cdab618a437cfbb3aff8fc8b22ea5188d70": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d16e27023c7dd6bd17320aa50c58b1a07410011070add2d5636d012a5e942d40c": "0x00ca6719bc9fd490cea2f94f000a3a47a4a5a498", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbe2b56289bd3fc54e462418ab4b49789b94f7aec6869f1c09af669e4a55b6956": "0x4fbf276d6fa1f36b0f0b12fe8182e4bd108ec9bb", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928969c575e3d825fed93c07195a802b6f77de4f5226": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970042f115150fc2eb576fc9a626075ce1c785adaa": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b11453d090fc10f3645d14a2e2b1af79030b948": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928926a21090f6187a35c5d0578c68e22c78e569b18f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928969ff7706b367405d95890cba4d905a9f040cd467": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897c4401ae98f12ef6de39ae24cf9fc51f80eba16b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d99b6e4871d4235bc2dbcf58c6c1cca46ea8ad1f": "0x00d27183e3cb01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e92133cf03d81c3a6dbc919f19ddc3c3ae95f354": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51106646a3e2444392f27f02ba35fb5c125f030000": "0x0484129cd5f6ade38d42fd0bb7ee99e1b77a287f1dcb20131319fffa6fec3b4800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8a8d6adb510e76876d66dd0ce3abae5e37781ae": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b3393e6991ccf120bf7d83e6e53aa6ac8ac5c551": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974bcdf08359aeae40aafdd2cc282e7c1fbb2d310a": "0x00ae0053919e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e5027fdd10e5041c66a7e580c605258bd92b84de": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007523b9bfcc0c822d57cfd89edbe777e6994c76": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8cea24ecc961f20fd7ea6332915c9ae85521f1b": "0x00f03fab1b0e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894b8b042fbc1bee7f5b9bde50c0706ddf3422c890": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516720a9476f1f348b5dfcfa1b032a68d355060000": "0x4c50edaf90e2ffff9be31f8cee70ba060b7471eaa81c3cfa1e7c090fb32c7a6800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973d8f5b9f1936995c3db39bc0da5c858015595328": "0x00261a1f702600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748e8806eba183d1364c2acfca72280c95bb41ec3": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f11a5b9d492c53674ebf1694954f19bab83a7c8": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c49b7d15f4b1fc5beded08a2d77d7d57373f3d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee8ad6769fe89ecb8fee0d981ad709e08e6d1c06": "0x00b039c67ebd5e000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ffcc480bf0e6acdbfdf71c7b8ae796647378c155": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976245b5b0af5cb4eb4742f118eb76312b17acb807": "0x00380fb4061200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512ae2ac19dabd46fdf49cac132662ef6af9040000": "0xf80400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b21315771454ef8c680dddd7b9bd5405a273262d": "0x00d098d4af7100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8b8e5173aa4696b5ffb4fb411811d3198ce837b": "0x008072f2681600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfe5711e8434fec36172075fa74d8168a95de0baf14c3d12430ccd97ac8b5d258": "0x390bd123181387d8427df74476627411146a0862", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700624c215baee850f4182d0602cb938bba095066": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515f18f908401d100052bef0d6dbe4c7ad38040000": "0xfad04e90c4a85afd98a0577632b4e720045ea8b9888661b735d929cedede390d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c7de1dc8dd9d66a96356bb58351d674469040000": "0xfc6abe24151bd4bd9a8a3c8e578e649d96f27467749cd5198bda48388de2a42e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898dd535c62fe25e520fb4becc53d19d39f5d798c4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d665bdca7d60b85bf96de183ff4175d4278494dbd68b9e72f21b142a2ea5a7e3b": "0x0b7482d5d6204ac5d40c673125ff1fd07d183183", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397257634912236e07f8bec7c6c015c88667d04b272": "0x003036d4980900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c10256aef4b3d145e26db1f762553783a7060000": "0xfef5cbbfba6e78c7d2c31bcdd9fb77355456a420bc43defe448758bd13a3da7900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df45007634380d0945f4056026a04e2f546df29985da61753b225409fb8f42628": "0x00957438646d37820df1a7d2434f4955f4c930ec", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970087fd9f134dbd9d68a2a869f14d88c812a14051": "0x00da5001030800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511b94dfb76acc5e90d75a30b890081db78a050000": "0x9ad7b209525ea818e43395b6e67de351731a7fc781eecd5c94cbda642e07f42700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894709a3a7b4a0e646e9953459c66913322b8f4195": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8ea9b58a1411d609b8768bb31439964f8493cee32508c9a4b07088dadc43b322": "0x6904b80d7b5967daf9a55a469e18c55ea75964e8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970cb193903063145dc5ec3acf56bbd5a784fe25d2": "0x00c0433b719000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518d26652a427bfe9e643ecad796904bb485060000": "0x38080b924384b2923f18fbbf77bada41b87d9852c8703aecd85796c228edc00d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970424193a415ebc86ff650e3bda37c521c5f6d45a": "0x00f0cc775d8600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ac878698356f130ce0ea0fec56bb0cded29f4fad": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1c55d0e6a0f11181546f76dab623b362ead1b0e116aded1d03cbea230e25a246": "0x611ef0a18a260834d1a063bd279c8f4dfe6f37c0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001a3dfb43b4686238359abf20ffe8b890cc65ed": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d60335162d0bc32398956a135d92d88892dfb89e37155721c982965e0ad9e9650": "0x5432d9368e60cf5c7b3b166a2b2354864d3d12cf", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5112a479c83f81fef65df3facf89eceeb686040000": "0xba8cbd759ac337120fdce334348ec173f6e2ce90fe573292119f6b33bb805c6e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339752ce0fbe0808b1602284b9cbe22d0cb06203fb4e": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928984f135b9ea6cd15016bc1790909a0710ef2fe918": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0237d930cc0e0748cd9f00e95d88d25de6165b2": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b6f20d6fa4c28a6ae5a4372d4798f2f759c25ba7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d78431453addcdf3e1ae922819e854136abd32cf2937ae9c84329f1eb92a15b71": "0x95e1a959df4af4ac693c2de538b4b0de14592423", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977e3c5b62a7faf6f5c4fe49eed72acca25edcf2e4": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b409f5afa0274854823681114344484d69fc0f": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f7d61f6573db5f748e402dee14b0aa70a1a12288": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fdf903708e2b7eec59ea3f985d7b748248020000": "0xe2a3a940afc8f2dda379e32bb95a977514d9bb7fdb4aa27eea3c9a7ee8e8802d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d761a4086e686fb60b17943b03eca939e82fa2d1e4f9d6a9cbad22578d12be274": "0xf67649a3f084eeccf566b5193cb6faa830cb10bb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339709960be416c44f27b6eab88cfa5bca92634935d5": "0x00fe42f31e3301000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51aefd7c25cfad82558d4323d453a64125ed030000": "0x364c29bfbc9f06a42b5cf37ffd831e91c843cc25d8b90071546810ecf279e45800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970017dd07201d4f2f7cf7b46d5b54f710ab579f4c": "0x0050a795168301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e570c0980bce80fe9be2a231dade76b1276301e4": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009c889dd86e5465eba2a0bd3481d2e89d4ac209": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f0047ad5e5ba9963f9430b2306b6856aa5b9b15": "0x0010b4426f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767af2e44d9eb9eccddfc05163361f6eb5fd89629": "0x001a8f7a4ab801000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51881418f0d0d0fc38ef3b89c82c543b014d080000": "0xaaabded5fabc47d6ed0818f8d44cff1c5a9b97d0d863dfe92fb616cbd2e119c100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895bf688eeb7857748cdd99d269dfa08b3f56f900b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d56715f37cc9f7b4cf7c97ae4a0f8f4f10d8a22f6a45f0b08a6281bfb175f7f1f": "0x005cb064be2ae806ff8a6eeba102978d6b32d625", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928975d27075d8d9aa87e54f05a07a52c5a117436cc7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c99a3b6afc1215dc0b1196ebd9edbf8b045b76": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d769597b907a9fc660d40ceb46cdbc04e015f971727f2f530b6376e96e601ba1e": "0x22a0105994c3f4ad8c3e78144e47a6eff9976377", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890097843adb6489371e27819e20fece2d58cdda3d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c6b58e5a157b1d1aee043e50be138b60bb41c478": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d50ec868243f5ec5af29a7c679163a34978815b6f1d6e2b871f1f361cb7a1f905": "0xbfd720d4cc1aeaca059c466b41ae0a55c652b8a1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc1d8a37770d2a67c13255e89b3a235a57a3d1aa": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897adc26b95c3e4625e1ac01f4eba38273e6c1ce48": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ecda139d1a13ac2f0ea53cd2be13188e54a1c4b3": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daec79507bbfc51d7bfa389f36bbbd7aa71bcec11e7d8f4415384854d74bfce4a": "0x009655d2ce1236c20262b402d2fc89892962d45b", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a149253145935c55070d204fce94c5797d070000": "0x2477936b39af9f05f27a86561c99f1bcba421ccb39a08cb1f58402796ef8235e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794192ed10285470edf1488bee3cfce683bce1877": "0x007c90bd712c01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518ef4c8d399a841bb49a6f2cd674ea74106080000": "0x2c4e4dece27c83d62cf01816cffd256d3871b309e43e65f9e2ac33e670b5db3100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339743eb43b52539b354b30f15b96367a733b109432b": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4aba3bac858eb8a53f6a3e3dfbd0a73a699d225": "0x00f80a5b4e5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cdbe5c54d75ea03526b2241a1d79329805ac23bf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d1b96a31ea448d0213a11aa8c2cda340d1335280": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d6fbc613b4bedf87e57a6134fb72508099bc089": "0x00c4c57af23000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979cb6247bf9e22da514b1b32acae28c560c73d848": "0x000620e7ad0800000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950e98059c0563d1d356772616e80680d278213f908658a49a1025a7f466c197e8fb6fabb5e62220a7bd75f860cab": "0x82104c22c383925323bf209d771dec6e1388285abe22c22d50de968467e0bb6c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a6497fc08fc439fd02e6cba9782717b3b1d123bd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289199a8bdf216604b7b05272240b71fab7597749f6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d68f6553582e121f75aeef7e61d4c694cb787ebc016d8a53ca89dee0c3704f45c": "0xeb21364d4087af9e9ce7dce7ee20233012c9d80c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c9520bc4a39e7ba4108d2794b5ef7727c78d34e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3f59ebc3bf8fa664ce12e2f841fe6556289f053": "0x0052c7a69f2606000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df02cb843f10eb104a933a57252ae8bc1a76c6681eddf513205a8404a68d4b92c": "0x9fc6a2b131fb10fd547d90100629791d67619156", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289184da5b2c2b2fa406f1ccd4d33ea8430cb0c54f7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5151eca2ed337651b94f17a6ea0a464ba45d060000": "0x40e09074de729692e44ec9b276557f6486183d7195d87ebcf77eec6bbe92173000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8f75b9f984e23dfacdb81f0bcfc56370a0933a026545a0eb04df04ec3630f747": "0x1c2020bae730eb78cbc511018cdfbd369e6957c7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700590fc72b10e46e5a5eb6adeeb2966b37b61b4c": "0x00ae3d71610302000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339761f4f7d2a593d1040406d2df519699b96f455a50": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d966ee7c8c9dd52e4650c99b77e62531cfec2f7611aa8b5d77ce28206faa3267e": "0x07b63625869391c66528acf9610ab2c19d935d9d", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51745a5ebf850dc2af44c0adff853d4e358b070000": "0x8af72e08affdef4b7da68950bc485e933929281781fc12d524e98c8c1e90a41d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003d69a4460b62a962d7dc8f5cf77db217998d25": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51519f1ce915c96c23c73b56da1dbab82bfb040000": "0x163fba2398eddb0b956aea50e711358a3a0406fd1401fae031331eb1dbad491d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da24dbcca5040cd15564dc59a2768d42eb475ba636fdc072c1671ff9030d6292c": "0x4504eb623e2c8ae4e61ad147b13cf978aef376ee", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b53d311cf309403b9f3538ffe66927c3702ea8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900eeb83600ff5dfb5936a0b8e7dfa7806da471d9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899479eb3392e8a2b6ca2e649536b55c8a2b932f1b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e1cab702cdcb0a445bc6b19ced6efe6d911adfac": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5176003e0e7f7dfe3f57705278973549c159080000": "0x92c003ff0cbe260dac5a3f86d9cbff3caec28bdce628adf125a40e72b26a971200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339745008c79499a54004ebf93a3b1a902f009a6f41f": "0x005251bb825901000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f55dbf691b3e67bf10853c67310a10c60a5834e8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51171c3f24ea29853fedd02bcd4d012f8972050000": "0xb08a593d2617176b23f2c2d1e32f7d9bab61aa012c1a5ba68104bfda6504322e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a39f0f9664328bc6dd494d323810c93a19f20a": "0x00", + "0xf2794c22e353e9a839f12faab03a911b7f17cdfbfa73331856cca0acddd7842e": "0x00000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9e110ce4f1c6c10618f508aff37aaa6989afbe8deb5ccbc4c13ced92dacbaf6b": "0xef3190039aefa5914791dab9d5b4d019b0441e14", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972489c8d02c79287a37e21809eb3f5eb4cd25d347": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004aa70bdd021cf9aaae7e33feb7efb057255266": "0x00dcbe9dbd0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d86f03e5ee97b91ba5253acf5d142ed086ab37cfb331de077e37c2c905fd9fb6c": "0x00f36a2d00e9312041d71615ac5260dac69b2c44", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339766f1c634f11355c3dee9015852dff6e65dbbf49c": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002dbe8e8627105c4255ccf96f8e81ed4915f277": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ae5328446d335ff5aefe66bbc5be2d827915a3": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397db64136231a5004bf3fa556667b26e4eccc15bc5": "0x00f0d7b0544100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899e643779779aec00285eac62b88c8f926c6bb1c7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a5734f7df95b6d0cba283ea001ad7678dc040000": "0x72a974c2a30d8f9cd9e000b31d94bf7bd39d93252c8b862a3894c191554a284f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397484ac7901a2de5f9923afe4ff67546525e07ce8e": "0x00c0042bb13015000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5e15888c2f897ddc27dcd87dd9f32a04a695feb": "0x00dca897991c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db87e61450d3bf5521e5c3f466faeca51b8242ceb29296dffeb4cb9a923127178": "0xb340bb2b047e45d6653aef7a5e94aaf40b7baa1e", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517e19bf46066d74446ee15c8c2715f7030d000000": "0xc0134e2e55a47b5c53427f613dceba99c7d519c6d412e64e596807a65c69b32600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b8b042fbc1bee7f5b9bde50c0706ddf3422c890": "0x00e8868f1b3600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d64ae31d2250bcfed87214097d5e793c9426c03c193d3c47533506281f5b34461": "0x6aa251b33219bd6095ffcb9db692ce2abb203e43", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900864b879b69a70b8798a0f61de21ee5b5bab3f4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890093422567550d4787d6a5e41b20844d6e0cea87": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d67346067f88f10855b3580e8230dac8650116e4": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ea43ab661f2d2583d0f3234f74dfb7770d51e00": "0x002a0967c50e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004d8fc7cad40c95a1d1cd38cbaf4a6c2a119722": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975acaf60782e62269ec264824dbbb13f9e85d71cb": "0x0080ca39612400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891f8a9aa97618c77fad4be22fba26d4ea0507119c": "0x01", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5e50ae079503cb865c2f6933205ce0132c3e7cf2562c5b95d91eed99f3e5d979": "0xaca3500b68da8eb37f45381fa3a0c7f815e8f5a7", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbe43cf13f10c57748e61120df82c8bace4563984fb09e8823b24f7c6106da61f": "0x2553a9aa6cdb203895a904e98f6d2437be0805ce", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978bf3edf0ef51f211bc580ad6068b21f83d163ab1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976adab48e2bc7819044ed2a9e4041f918db545aea": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d388610ae23e60ed846aaed8241eff3c792915b98bed9c1eea8f0a8defd2b976d": "0x8c94b11f460481f86363563e7eeb447225fdb61e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979604602d57c5ad85c36b8bc59394086b5f18e7b4": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f63722233f5e19010e5daf208472a8f27d304b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f361416db134b72a3e84dece57cbe6179e40f283": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289436b98f3a614079ad005b7c62743020ad3dd672a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2c4bba68b6aacea483b743d0431b1ff5c33cd7522e2c4e3b53c0928211e25b59": "0x0023d77a0316ae6c765a6e1c6616be7030f462dd", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa339c0fd9d6df6927cbffbbb4a0256caf8ae245bdcaf8882c2163b36877390d": "0x43eb43b52539b354b30f15b96367a733b109432b", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512198bb28dcdfc6553383e41a6db608cf6c080000": "0x3c51c73ed08d30afc617d04819231224ee4904e048ab132be6823cf419b6e00300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c69c3cfceace9836d63b90c6bcd9ed4e479dc871": "0x00cc3d2e9c1200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890089d8cdbb9494f662738349c4d940cce6d95ff9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892d05ccdd7d7481f71eef6aeb4e0527ad47753272": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976314bea21ac7c7c29127ac20b508ff8d430bdfbc": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c2020bae730eb78cbc511018cdfbd369e6957c7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d22f738ac3bf4393d7968dfee80d6fac4d0457c0e80b56e4d599b40d7b4a3e347": "0x55755dcb998f1218761831ffd74747cdeb54e1ba", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ca69ee86a4131262ccb5c56af72f42d597c5a2d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f71ffc433df3a137c9c0a5cf08fcc3e4316e4e8e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e6ec101524276a692f4a4fd0a2f811060cd3d434": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1a7435849cb3175839693f7e078d1fabf90ef3fd38df8c50dde7fb5c88260862": "0x9a27e4a44e3633f546f8af7fc0acefc55e58af5a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da2bf8e3c90f7250c9db68d9566f40350380149f": "0x00f4fb4e8b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890c25af253615dd16c0cc521514164ff2b390b5cf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6f9eff7c30c41ddfc4cd9f78a5757cf3679ce7b": "0x007804cea01e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928986e3d8f8c1252600304047adec71785c41671bc2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514ad9acca1ad5e1cd4cad8adffd2dc5766e040000": "0xb86e3fde6516ff1915abd6839a50460ad9e44ef24942d7cc88688de5bbb5ae2a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519b041b88e58334380acdc13d4c4bebd96c020000": "0x4ae00a86d40e8e73dc86d13f85c1f4a8c89bed88b44bb614c7c33290e139b37400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339755c6c9d943a08b9e39e0ea27c50f0f6b16898f92": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f2c671d4cbb4fc23efccecf72c6b995a67fac341": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976285a2a0892b479e0324f4e51b2f1052712a1e73": "0x00c601b80f2a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d90015ffd36994c8dbf954609926bbf6fa9833924e190acd6a4b248e5aed1cd46": "0xec9465777aa326e36b60abfb4a01298a7f51845d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f4b56df57e5dc51587163525b2d82d6a461e35": "0x00ca3777b19c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e7bd3dc5a41971455a7e5af99c3ab77766b964e": "0x00181b6acc0400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51294cdb6880895dc52bc8499a2ab80711b6060000": "0x3e2a1374cfa7647e2031be60fcafec5add32295e3f65c887654f80a215ff771100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5187aec6c4274a801805d6cfd8c4455e3435050000": "0xcaa27102248bc174654009763f4b911b9d2420e7b06c432b0f2434a742a7c06700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970046a7c2d9d55fbfbd3bb829995aa25d4bf6e401": "0x0066497f817f07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b55a1713236871fff3c17bb02fe5f3eb6a7d25e3": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970312116a083d27cfbaf9441b576f3ea63d968967": "0x00f898d8a20700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5133acc3cc4029ad1589c2b8ab51c426ab10000000": "0x98a1d22e4fb59772d3e41ca11f72f00f4fd330c2d9c6c37c05e8404fe10cf72500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897967c0ec1b8b1bb821c84551ca7c9fd49c720a9d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289445fca1e2473f0c47938979ee2cb469aca9d36b6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289554c9622a293ea2f075f259f06d9f19b9154c253": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005734cba73fa9aa8aae2e4a11c1ddd631f3d064": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dffb703dc6c44e62c195bbbcd9c7fdbf45f5a133": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e277e496431750ba944779d1dfc2b2487d6926f1": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893680537578bd5308cf4c5d98d235c7882800142b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928984256d81c1a191e6952c781f6a204626c6912b83": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5149768329c6823e969f4489e233e9b4e22a080000": "0x487097aba3397325d639a01695be93718b161dca43704d6efeac308bfe7af56e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9a50a0e597419f53c4faa1f9bbba58733ea731bb0a3fbda8c12466892683375a": "0xafe949978ae2f7098f9b5c2338ed5de20ffdfff9", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da2a2536e669216a495a670f031cc0499cc4e5d20f1c4d7db8d7d7597e227215e": "0x5ea3c5be41a73bd49b97f4cdd3eb55335baf03b3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978212ec9b5cde7fd6a19690f889fc34d45d1db06d": "0x0032efcc580900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f9998f8570b0afdf090d930b702e430edf66f8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289162ea064ea50973af277b0c8b32e9f900e2fc635": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928954f37dc277ea0ae185cc45886365f99889a9168d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890059d48fa65e3440a352527e5c11627927751023": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe740f05146eac00d2b48f2527eef1deac1e1c50": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895e4d95432c7d44feb173a155f31a7c65a1f13668": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7623c898ff1dc910b8ac22ced18595072bec72a22f5ac79f132b29b4cf03330b": "0x7a2dce72ec5f24ed58baf131ea24762f3947ac46", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289301ddc73314300e25229803eb78e02ada22c9059": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bf4a1f0e0e564aedf0b1d5e826b97454cc050000": "0x44ba33d654fef43a6736352ccf94a226569f10be0fa323d34c09f13419dec25a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5190b0ef1da227e250a1cd83225f8409f89d070000": "0x60270251b87e5fb87da897643ce4f706689d027a033582cb731bfa7f2e50730200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5173f4434cd046e308cbee36879b81209e2a090000": "0x96488ffc974e750f6dafae05a28f29dbafc2ffc1265661aed70937aba06d102d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cc3fd9c77dfe29e8d63f42432d05e26cecd97d": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c003133c97db8ed8cb2d008f29b97414fbf48f62": "0x00f8a4ceeddb3d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d4b3731451de43ad92166a9866cb90795b6c85be": "0x004067d2aa1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc29a37e321f816145f9645967ab5e2a87d8b0ff": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004db71babc8ba9aef9c02bc96ae2c4daa74db15": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c5e4db864861d9b6203bd86af0c0b5ffcd6115d": "0x00d22374f95f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5185ecc7c3a1c2e4816f9824bfbca5173ca7020000": "0xd401f460e0251ed41d7fb32ca463b5233b620cb9569eef5327def27fbd7c7b5700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397879b86a32a6d56f04db27fca343ea8844c98fb27": "0x0040f09bbce108000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517f0cafcbfec728ea4f52ceaa6c1919a314020000": "0x68b849aada5aea5d27bb322b8dff4b540cdd4e52d9c32aae3db8a6a9afb43d5200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51979203928cc14f6d9684773d53f1fc491f050000": "0x22ed1a4911800562bedf94162f45f4b3ed383ff35defc9586c6861105e50194500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a8043a578111b05d48162eab62fcdd9adce5185": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c235870df0ab4d032329925e9f4024a6e753e7a7": "0x000290e3bb2d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891d2fc4af6283590eee0d236dee41b1c0b257472e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928969b293a17ac91de3552bd7381f8753f385f1cfda": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f72a6e8a84e112b9fd925ad040b81bec8b17a6bb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eb21364d4087af9e9ce7dce7ee20233012c9d80c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890035b3ad14d644a13c32441d55dd13f846aa76c3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b9ee82eb0c10e873760fc39cbae615d05dea7a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928942520065f9da805ed7d122f009976a4dc769c040": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700998aaa8fe8444322729f9dc9f32b41cd006bbb": "0x005a4602645300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5198fc3e5889f54a9b459ad92e00c8a9633a090000": "0x5ea3d15ed87ff434997bbea75c8be3e78650699bacd6bc7759045e22d90ad47700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339723fc17c723c870ec4bf48e71135a4446986b5d0d": "0x00fa999bf11a00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ded238e5b72118e077c81e3e06c151d5f5040000": "0xae43c3cd9c3e320d03f5cf5ccc4eed0383c6b879bca35e8ccc7174f2147a2a1700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748f5ae497b444b6acc53150116526f0b239d1170": "0x00242316652f09000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc04e3158efca9c78e6610d1277c9bbef0ef1ad80896d4d8a4240c3eb5a2e1706": "0x9944d6a90b6e313fa8dcd0281d7760ffe4ee0530", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824341a7300cfe3e58c2a2c248b3f55228122961b132": "0x00407a10f35a00000000000000000000062c930000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004840267ca0976045bee42e0b7dd7dfd3b827ce": "0x00b67872050900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dde462529cab3f839cf03bf49a7e850013794fee8b7667bd8c3c15469b802d029": "0x50ed8729f9b9cf868b12785094dcd61b4e37fcd9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d3077ba23533692a3434fa28f7cd678fc3f2783a": "0x00e801c82a4100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701b54f22deff4e08365c731d923a31379aef62ff": "0x005c88c2daeffb000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b8d82c1ee5bdc3505523ca8d1e0e8e7df6b10b": "0x0064c20ad33200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513d64143d2d385ea133c98aafc021f8f649090000": "0x8c7856350e309384b519c873fb20d4393fe42085ef1a2f2c260a14eac804597300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcebcc2ead5f62db0af2c326d9125d36c69ea03b3bdf88d5ecf79d53d82626566": "0x0628dae391a37ccb6ccae7e6b6495c2622d69cda", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c335498511b633e6c7c582d837735dc1ed628f8": "0x006e38ef543d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e596919783fa9da0f9a813b029fb5f3473440b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008235374c2b0a0fadd61c6bbdde2b9983af91f4": "0x00126d3b2f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a8ac74f5da1ae7e61f7c7c511e2b888589b801c2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512f2c372a0af668699c1284baba94322563000000": "0xc08d5de7a5d97bea2c7ddf516d0635bddc43f326ae2f80e2595b49d4a08c461900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781d6578eaae7398c11d6b3ae4842411ede0d8c14": "0x00421e33e0df01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5137ffe8421a77040ea09e6463243297c22d080000": "0x707c94e3ad62ed919cf1eebeffe3381161c4daef849a306d698539931a08ce1400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5108ae15fc8ebeec34fb26a23ba2031c593f070000": "0xe8edf00ce75a71ce5cf3a1aebd19a0ea171c5524bbfb858eda9fd5ee6be3487900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700671fa9ddc406391fd5d60aa885f6d10d9f0c9a": "0x000481ec3e1701000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1cecfe91a79314b3139d7dcd65db4f5b12cc2a47fcb912dcf8d69903d879da52": "0x0098a926dfd4c742a18bb91e0dd1196cab95f4b6", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515a96c66f1e50d131e284fafdcb86e60f23080000": "0xb84eb79af3f341a2e12f5e215104df773cf4f7746226afbf0f955dfecdbb9d4b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970387fcdba9b695926f21ae1b0701fadc85b28744": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977cef137621ee58bd6c3a7036924dbc0288f81dc4": "0x00dc99bd488800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec27421edc22ae46c23ad1e8b34f8651b3d1d350": "0x0054e32fcc5800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700010b75619f666c3f172f0d1c7fa86d02adcf9c": "0x0060f86c8d0700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511b13e8a276a8f525f7536cef9e381b089d030000": "0xe82b4045016786e298d7f72e2ae948a7d9981df0fe2d3180648fbb4a52b8584900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008c2651bfc939ffc086fd5b5e598cdc1d662c97": "0x00769f7b7f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774f484196d48d68936c07bcc9509d3894fcf7eba": "0x0010a539b61e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890b546f4ee227999882be22ac4425227c4a80c550": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df8f5d1e351b28ed8669a4b295907d12566df2267d0d244b21a0974a0830e4b14": "0x22a71133e0a9514145b5ea4ce0b874a9afd596fb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339704d83431115cc45d7e1fb79b4d64b5669238b687": "0x008aa98c5a0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dac58e10e4125165d840d53169e111a4e76487f930d7bda577583f6bbf6db513b": "0x44401fb5cedde57d33b2898ee66cc263029b6508", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c908d506ddb0c9a41766b3f54f2ef592c50fbb5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000160df2f8fffb230d8cb9f67cea2461d38ebc6": "0x007ef911b4c709000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5103e5ac455f0efe0d5437cd4ff1e9669f11030000": "0x2c0864711e2aea8b1327f958e73d8c4de709a31b05a72defd997e5538c54565100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c5229fd8a631cf877622f2e37af6eabf15cd99": "0x0080e9b886a100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890088db9e97689c85a29e67d08f1f0e43bc40ae4d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d827acec5295bdb2d134df3a5dd2e8ff5db1d3eb75c5620b3ec687b24c5be571f": "0x01e19120eaaaf5cd7514f028d5ee7993be7fbe6d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928941a7300cfe3e58c2a2c248b3f55228122961b132": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928948135590503369f344c719db70e50aac005cfc24": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6eb0649daef06ef9c43deaa38b2e6d867ab9e44480d4a30f1f3d364e7aff9329": "0x40f0e17c0e8d725e985840198edda545fc3a7162", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895c94565b1d83230d62649ffe8fef08c755251853": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700abcc8bd0d281984f9234065c889396c7e3244e": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b0f6f73022881bbf0516b30d182761a001b7244": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900812ef6564c068b4612e2c1f289358a115b2ddc": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8aa7eef9275f5b5230173bf9392682ebaede3cebca4f7acad4e383b8f172723f": "0xf5c78d56cecddfa5e7151650201b5144bdb25fb1", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ee009a16375c624ebf875040a1c0c724667ee60e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f46a575607dc5b276eb6f5bb2c7abb8ec75fb648": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a6badf4b7cb3eab8cdb6216d1a334a48be8c5db": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc6947bd508359f995d40def74ae4e73d64375cbecae152ad22b39275eda21201": "0x5ae39db49af9e2dec759ad1647fdadefb7184399", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900538ad6845f3526e08a2d1bdda4ce56a6191ecf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890087814a753208557c3fad394d80348307326fac": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d5c3f6832e88fd28cf40a1f25684b7ff99a66a5": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b6694b3bedd5ba593526ce5e1d6f5ce899ce70b5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972165753514a94b7777f495bf2634a0baba07534f": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928924094ad3da60814fa50da15508539effa329a1b8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898e17fbc2389061940e39af6db317b48ab56d2a33": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243ee41bd5428594191446fef91d5b0de95706ad49b": "0x00202346c98400000000000000000000feded60000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d2a75f1ebb6ed6919277401a2e3fd6e3d828e086": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d60c05022f8868ca43dfac61219a3e3e51bd234b2e76a4e3f2c21793402447e50": "0x00692c9b1e40a8eb213880ac4908eb8cfaf1f598", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f6013d2fd484b19077df506f97da590ee9ab6c3": "0x00dcea73a01f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892d3949b803273f985e9a167bc42c0ef376b70d8b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fcfe4380a6592abb74ab7a3d270f87acaafe118d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d4eeec5a0501388bb3cb6806fc62d9edb7010000": "0x908a2a6b07c69278da04e238eb396d240e9818b9e3ad11545bac463a4cb3be1a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd6c29a7c39cee45b0e045a94081bc188ef73be2be086d66aefd850fc7eeacc45": "0x8961f4e5650444509af31c4a7cf2a0924f224b04", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f36700ff798394c4a58fe861a4661f5489d90735": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b795fa77b056e488eb37a624a0f6a6db1e1401a8": "0x00543b1e6e8b03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895f9a76fbba12dc70d5c4b71c9638f1c1f0b4c280": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006a2ebbbfbbd4c4d0537c033b1e1ff34202bc61": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975eeb604e66c8afebce169152326276d345bc320e": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824336921aa381ba281dcb6fb6489461c2cabb8c23db": "0x00b051af5a84010000000000000000009e6c740200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895a01e248364beedae2dc37ddce5f45dc5b7011c6": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824331b68bed40ea6d8608779acf8c61a453e264e253": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d90b3bb381576bb2acd03c2e06930913a373b1c3d2ef68b9275d86940812be312": "0xd6d9fcefe1a8f0fdc1c52c8f7a33d299be4b4e67", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4841dd23a0c6e2069f543be8dd5db5442f62cff": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5115df9ea7063c012d39af5b8b2c44a24fe9030000": "0x9008091e2d1fb20e6d6a46c0d66591c9b00b73ea42386c0897dfdd5327c1553100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007843ded6c179363a1dead9c1fa8acada60528e": "0x009e86e7d71100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008a15ba6eb9104f34001a142a0b57e0008d8e07": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df8b2ec818f2b911044bc04e2a921a95d81a5d1672ae68b6c65cdd10987c23126": "0x9c8f8f563c3e6a9fbb039fc3e20b53591796d745", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c1aef275a28f2ee7241ac81ba4f25bcf09bccde": "0x005c92571d2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a209cb38555635734249fe6868ad40b4af6ec88": "0x008a74cb221f0d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd03d9b87fc7a4669076fb8675021f04e4e8f9da": "0x00009573c24800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfe020b75ee933b460f88ad71502469ba44fa6ee9590f9c14321b97484f8a8e36": "0x7daee2fdc5f2aed7ccd792223a8945707469d1d4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fba6cb41b57abe94c1d80b7d738e9946d867f8fd": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d967f0b9f6a4866cab8637e73ea56412b45b99ce1e8d5be2bece2ca3aab67aa46": "0x1a490262c85d993e3318fd0bdf26bf6ff5c470bf", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dec09c2e24ae25500ab5e3ca7fc1961b76feaaf7c24a70847e8742bd74ca90312": "0xcb33463e1812ee584c557a160780b0331a50b3dc", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008e158b389d89e9f98ab781725f34f5d06e7ed0": "0x00e61c8dbda200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fafeac92a9fa31c91d99cc699cff09a91b060000": "0x1a4c0dbeb509712262d38d375d758f5709932676b5eacee8a63df2f47bd2f42a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfef5cbbfba6e78c7d2c31bcdd9fb77355456a420bc43defe448758bd13a3da79": "0x7b365d77a01b72223a89517b981d0b97e5e41646", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397530d949961092c5fbbd9a27e48902155e3208a64": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900671fa9ddc406391fd5d60aa885f6d10d9f0c9a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928917161323d264e413ae0984c6ec4825cb4082cf9f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928950b7f7661c2057fd75c097eec2d06b21d586661a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ba14c03407af028976f69c7876671d7dc3000000": "0x3ce72b62d59cbad8484e9d9cb06edab1f465e7f30f3eab441ae94df1c701336300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794cbc73d485035a0ab712484144dde3352d6cf60": "0x007c9718adde01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900642284ddd6a101231e93d0a8469b39d85ec85c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5194314e068c9046f3b977ab344ee5d190b0aed": "0x00a6e190f59b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3826a238beb074eae1d6c2a42cd3c63e2fc9147": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a319d0e87221ca1ee751c1529f201522c0070000": "0xacf1956d8f6e2af1d9d1c895a4388a2985a10d99a573be37abf16c86fe5da36000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a62bc08e021695b3cfada083d0481452bf5c0fd4": "0x008290b149ab00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ec705b0199b23563c3a3a9b5599aa1747af42eee": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700345e8d6c2fbe70fe65954937ef335cfc092cb1": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001c35a3ca5e21f8398bddcce36aceb288d11f5e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002c2d84a889df4bdab0175a1c4487f67adacff9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001a3929769b8f2f809aad807767b5e2c0a9e27e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cecd25a7e218c0cdc8fd36c50d1369a691f56d90": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc2511b9ebf609e66a3ead4d7eb980e9f0a6ecdfea9846726d14e45d295792071": "0x173ba35fbb37fd281880645a2e7f8e18ba38de0c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289919633258963e54df2e985f3f42b3cbfe43f24ff": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300c509424fd0794e367683b213a91f3cd83d1180": "0x009432196c4604000000000000000000e1f6ea0600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894fe56ab3bae1b0a44433458333c4b05a248f8241": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a369d5026865d345184ff86caed29c118a1566a4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6e7bb138941680a1cfbe21e2cd8452babb9cb2648b3593379afeca1a87858924": "0x05217a5ea7391027b88f54b550bca825d6108af7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001bdd794e80b596665dfed06d2876eedfe4f1ec": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894e163cf2b25ebddf54bc1ffa47a56b96e820871c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702308e5635b9df891a27b2f837d88b8dbaf01042": "0x000c5849192401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397afd6e8fdc9e0f3579e0b51f4af2587141b34ae18": "0x006a0b9bba8400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b5d5685dedfd298695086da41f3f0699ae9d82c": "0x0068068c624c06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975448b9defbabba9c0d81faeac87be5b4f01d4fb8": "0x00e87648170000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d605a10f7a8372c3ab9d2b945827cbd548781d9c3a054697de99f995aa096ce52": "0x9c3668049cc8c0e75c32ec8bad06421c3bd26281", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289050e3aa7f5b52e7f547821ffd5abd8ffe6062a86": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51161fac40e4caf6464df36b9349499648f8000000": "0xcce77d786693195b956708015ff218d87a546e5b2c4a2696dc7cdd82b98c9b4400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a44e6d1cca8226e718ee0b4f4edfa68bd3773705": "0x00b420a6093000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dced8b2fdf65900940781d3c01ddc03e4adbb8ef6941df7b6e4bf370b10f60944": "0x7d2305280d7e05b1c3c5213fe4f626c9b5557af2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971b778a8d83c0fac09f992fb701d1c085cc9c76d9": "0x002604194c3900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3ac8adb41dbcf04f2d67294fa621940d040400987e05cff6326b1318939db159": "0xe0298def89745f03113783ad625933dd7732fd69", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da4f294e483405fcde773f272c296fd45088a1f7f105d750a8c57eabec9737523": "0x00846460e32cf55cb7917297457d5f7ef697caf3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722e90752520af777fbd85cfbdf28b94748e7b871": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d760f4fea13251aa55dcf9d3baf44aa467128767f29789fcc3fc1edf69949c779": "0x00b91355280b218cadf3772a949f0478880594d0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339796f568fd6311f0fcf6c8fb0d017f4b7a85f5dd38": "0x0094adb1ce9700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ff6a2fe83421f7c8634dcdb876c6ee43b23804": "0x007e222bbec000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dac1cb3bb7dbca1415903b9e193880f791cfedd7cba5a2318ea00e2ce946c605f": "0xb06d958cce8ced5b26ea37e63d26a3a3a0d3ab34", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750b7f7661c2057fd75c097eec2d06b21d586661a": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824397062eb6c3d95d33c040c98a54187b5a66541b6d": "0x00706f96a686020000000000000000008564160400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e91362a99a6e8e6e0577feb433b3ac7841b5892": "0x0080e702852509000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0e741e91998cee7bdfd13bb0c48ec23fb8c1f60": "0x0080a1a76b4a35000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890038954411d31a29442c8978cd56cb764982fb65": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700da54bae3fa6d6612987a7f29a32ef9999af062": "0x00962d3a03ff0e000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518b66f37cb770b69a40a72709e7036368dd010000": "0xbc1d8ebf568492bdb5735740168af7187006eed87bed5d2082b32b0b3fa9d95300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928948c13b7bc700451b3d801023cfd6b0d1433b301a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a6159a97922ef4ff521d112496fe98d868050000": "0x2e7449accdeebc3e4a01c18196406b518503b44397d3a30347d43b5b6dfe857e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892186264cf67b36c8e63ca37098645e77c331d769": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339714edaa223bfef22b1af6f5500fe1766b15cca12c": "0x000e259dfe2600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289678498badbe31d20f718a303e51324a6d039e7af": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397731396ed98bbc215c9078bbc583034ac85a4995d": "0x00a007c2da5100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891213c5f7d2cfc86eb87f0bc54e0418009ac46f99": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c2b301e2d9d3c0ab57cac6982917d92673040000": "0x3cb41637bcd76f2609d767597d6863ccb3cd965d896637769a43039c6347a47c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51df262b29f22ced2a4084d2e58b11b52e37000000": "0xb6583b354dfc9f39075200ac364392bed6c5d409ef63f8b8698e7aa14b9b146900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8cdefebaa227c1477106c9276b992ada6bdad3ed9164d548dc8abaf899e2ae39": "0x2f81a1831e1bb3b21b063f40b5fd29969d9cb2ee", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5133429622f42421b4f0099655fa4a8488de070000": "0xbe672adea7c17054748cf224dbd6bf1c769e99f301921ccc034b14b0234e726700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d08c71e9b40bc639ac1b3e109b15f4a9f701529eb6941b0fbb51ca6856dea4c08": "0xb94299c95f6f3fb6b0e35433232e4e4468d1b760", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8a0d544a89df376af974b0fb1a1bc47b43d9668d910504573466f70b5d391507": "0xd9bd91673fffca8936f266f14ebbcf940f684658", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700597dbb469f69d8ec4de77af1da483c6775a794": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700760e131413c57cf00d098dc27ee53f0fc3a7ff": "0x00b44bd2d67400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972fbd318ce7d1b4399d68fdd3561921b1b6fb1d80": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fc0e5caf1f5e1f3a37cfbfcf9dfebb9323060000": "0xf66c98834c19d0aff9f578921681f766f530af84e8b53a5632a364f1a796a43200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730f0056172b5a1432a49c44b0c5bdff96a7fb54a": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ed69230ff6fdc2362113979ad08500065c83f31": "0x00d6cf06ca1a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339711e328bd7023e933426940ad12d6e1b5bbd55f1e": "0x00e0d21c5bbb00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339756fe408b24e6ebcf0d0230c8f4b7ba25f2c2197b": "0x0098ba69660e01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397656e42bef0b20a74de23d365958a4461f595b755": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977098da7dde0b85baa6517d732d16fb06d8bbe022": "0x000e1c29776e03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ebea2c1deba5a629af27b0c8383113008c8ef43": "0x008053ee7ba80a000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51808b4a80582c3a58e4adef492444d52a8c080000": "0x2e3d07942314ac67dafd42efa35e4663b35aff06b05eac14f8da0805970080f800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f26a98109d0e971370b72be7857f44a822a4651": "0x009cb26e1c2100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513e430555274870a524d566c373ce3c9bfe070000": "0x967f0b9f6a4866cab8637e73ea56412b45b99ce1e8d5be2bece2ca3aab67aa4600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c25f885b631247a34d1429b3f43d7bb2639a7e3b": "0x004294060f2800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510a82a45be62423438dfcce26916ddc62fe000000": "0xcc38d3766d286b1a624f7031882479cd84feccf7076a2a44f8b9936cbe26877e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e09f6bbacf54dcddfc5277a0355f2dcfe657c2d0": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003040fdf21fcd3084fd4076962bc4c7e66395d9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a82c7fd9dc03658b255b5d68e6251146748953": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289053e71a33ab7f5250fd4cefe232b2fd6ec92b0a4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977daee2fdc5f2aed7ccd792223a8945707469d1d4": "0x003e4d65c1340a000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004c129a0b05b5bda2b7ce56313ffd840c3b47d5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d06dd653d12418aca05e155c451e4c4f628ae986": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e260e35f88bb3d71ff842178649c2817dbf50c04": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9c14dbe4982ae73a084bafe1f7eea2d51f3819088f08a10eb2fd7a1343c5140b": "0x4ae4f357871171a3c3e10586ff545acd8e165618", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b94299c95f6f3fb6b0e35433232e4e4468d1b760": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510ad833ce33ae2c4b47792c316325b01cae080000": "0x6c28acd0770917ad6b838e8b3dca4cfeba208839b5459d90b7b375193da1674b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a935ab0c20e6349bc6eb43ae9f30ac2f42080000": "0x7b8441d5110c178c29be709793a41d73ae8b3119a971b18fbd20945ea5d622f000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d52b419784a06ff99509b1b18b627672506fe92c6843bc19643a1cace1f4cba54": "0x7ecb2df664796fad819f35cdfa6870975e26bc0c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970092aa89dc07f1080415ce14e85cb02d97937255": "0x0026da6a887d25000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978c4a8da8157683e753d28767849df4e6d216c079": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397596c4221758f875f51403416940e0ea1bc1755c8": "0x0042b0c4556100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900020887bd8bfafa35f1d5de3c18c6f81b0f8f29": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928927ff5ebc0d4ad36f0190d6fbf8d774ca7d4acc34": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e899a68189ac4b743750da4bd8445f7f148932e3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d8e2e6b9118484134a1925813e545b37cb89102": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b300a2c7b89455cd5f3b4d3a998afd356165607": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e326e81577ca673de641881b5d997528ee246f20": "0x008aff50bf1a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928935895e864b6a7b88db055924e01de9e030c42020": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f18fa0631873e56df496a05d96116fc39da12b0a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009276734775cde94eba0c4fdb98078db07d5fef": "0x00bec3a5b60300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd9c3c2f403af26731d5349f2e8824f85cba0086": "0x00b808f1f31800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894a3f746d8fdb67aa729cd740d720c4a64ffaad89": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824306d6ee9ea1c648071973cde4669d95955d496422": "0x0080e03779c3110000000000000000001e99be1c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001ed2471e25c381b3c24895fceb399dbb4f319d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773a4bf5507f57385118846444b38bc10eedb7fa7": "0x0062b3e8e00200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ea9d00813f1ba972a361ff2d3761d2a396fb2c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700541ab0a813fda7012babe7b3378441432f48e1": "0x0078cdf9a5e903000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6694b3bedd5ba593526ce5e1d6f5ce899ce70b5": "0x003e7d663fec02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1677d96bb82668bb188ec71498db5c0c0c4830e": "0x008ad235945100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0298def89745f03113783ad625933dd7732fd69": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddcf77dc7b6033d7330a9d9c3bf666cdfb86362038400f4776da8dfdb03ad8c49": "0x008af2eb1b57b4a591e08cd0dcb93b0b0978053f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001c23d4e5d6b3b797fe085fb0a3bafb7f758da9": "0x00f6ad147b7600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009957a264dfab5c3c7c572c1a4ceb8d1e1ad779": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b1655ab727bc613b0cfbbfd2a8222a17955ed0cb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cfe809074cb2f767285e8f0bc8e2604116c7bdc9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bd125f7c40e252a090871b865aca471f5cb8ee01": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9c59488b8c7a70a2d91b288b43f0799a001b1d26bad39fb4e7ec5eb73fa0482f": "0xc885efcdc3b5c736b0407b0e402b5b842c81367f", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51305acd413305de3e529a2174cb68ec1cb5060000": "0xdee9d01ef9ae9a28b5d1ad92908701b2eef4b6ab8dd733a2bc50fd3f73fb4b6300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8af72e08affdef4b7da68950bc485e933929281781fc12d524e98c8c1e90a41d": "0xf61e40add6b7b887ffe8792aadcb6433d5209a4e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397032f6b944721fd338858bcc0e323d9afe77e0a40": "0x00cc2e5cbc990c000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928908c58b2dcf43c4505526af8e5e067bc08d3d0175": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928954f5873787daa1ddc97272e9f7fce534015f4d19": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928973213bdb86a2636440bba625ce5b570461ea79b2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513953f8ab8a916a327cc230d831fa516235020000": "0x2c1679ed3eb12e0f00ff6e9e42f893aa377539640a1519abe3cd2e02023c125c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e7eaacd78e6ed0bad7e6cbb80b10d34b4a070000": "0x2ee50c5aaf279bbec8871d5468131c9463d590e48a5a5e12a6ebdec60cf41c2000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cd0cbe2eefa616252e493b03b5c2dbb9060784ff": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0ba2bcb31e7789cf711bdb657cc69526bb9a2f7": "0x00a85d62653804000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9a8ead39ce1b44f37d16e98496441be79018e910d5f58c0fa1518d8fd7749550": "0x0092dd784a50e356b9e1705dc780fcdcd55d78e7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000df35b3d62b94414a010b9f2fe6a1489b32944": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec705b0199b23563c3a3a9b5599aa1747af42eee": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900290671c99ac34bc7c8254033de25a938d4fafb": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a88f54595f9543cedbfe0697532882ae3d70ea50": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895ae7dfb217953af11182fb68fc210c9ad11adb39": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970096746df961fdae3247ffa893802d1cdbe60e86": "0x00aa03ee74a003000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c673e696e12296fd3f52e0f6e354039467b518": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897b5d5685dedfd298695086da41f3f0699ae9d82c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ecb2df664796fad819f35cdfa6870975e26bc0c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289edbf4187931cb3d852b762e5ff28fd6af6b761c4": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243c5d3a4a84a2d404dc9828428180fd927dcdbc896": "0x00003426f56b1c000000000000000000cac1fd2d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970097788b27b144f03715621ac2de4aab5b94c158": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bf19d44b1f516ef06f569b5d775ff8ee57080000": "0xce78603c8966932919873970f15729482bf020697acc7b2fafc031cfc9d9fc1c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895af08f5a0e43a3587ce7c8bfa21e77082e559f37": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896a8d70c0692ce44b04c5ce0a7e77bcc6a0490766": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512972e327a2b9e8db1255cc4c47aa90591e070000": "0xae0ba2b9eb48ed60ce02ebd80d1632e1efee027c15b0823e4133d32173d4e11100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d48af0a9782bce4b43ce6864a1c9e32e5f47c6c": "0x0090e5961c6800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339749e961c06237fdc4bb51c48813a8480e75701478": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289143365830ba0c2a2aeb0549cce5107d484143877": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ab94b48bb0eb0f1f9d4f3a66302af5c1406c195d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa42d5acb3d55990ce403d714e77cc15320796c9": "0x002082eff9af00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289029e46d21436a8e435cec948d8a0a5bca6f19b7e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d0eb611e8056e7061e0acdbc497eca0db4292af": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975dab307d07dba5375eb40ac1f1b285c2d8307b03": "0x007ab0403b2c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f7d61f6573db5f748e402dee14b0aa70a1a12288": "0x008ace1a761902000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282436314bea21ac7c7c29127ac20b508ff8d430bdfbc": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976115c56329f345ba42307b2769817361a92029a2": "0x00343cfb8f0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893dbbbce710fc71eab5fd35c40743851ac5f08407": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289afefeb0eb9875074ca2a2d508eab621fdec459e2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d646982089831a323228bf105965a23817d28308": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977e1a9cacf28b0e0fd619a5037c231047c3e5aedf": "0x00ace901606903000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397635954403448b9f55655fd5dbcc9675e8a4b8109": "0x0000851ec43c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7ef6733ceb972d95d74368fe24b511512ae857f": "0x009a3f588a1b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890023772fedf1a43256e6ae4c227b6dc05989f814": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002475878828a236151128f5af451fc3c1ad194c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900da52ce7a1d54e078399894b20f3b4c6c99ebfe": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289286409bf413131c1bdb5c2ff95c5f8d7379c5162": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004272a32a2ca68c679f25fcd14ef02cd7933a5a": "0x0040f09bbce108000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928970a5643374c28a958b5dcfbb68a36d3fc31e2fb6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975daf6d0f17ad397b6a50308bab72dba0a7a74249": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007ca5c1afdce9618c0bb7d86c2e1699fe935581": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de26f1171b9708d791cfb6f144d994a52d30fa3ffeccda0dedebe6b17b054c071": "0x6d4b9143dddb89e914b180b3cd9e55bcd74f7c9a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727d8519774c77bab85031463f236c702c7ee8bd7": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700228be11366ac5fe81770d49480c2a190a9da08": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979028b660bd9fb93c44efafa5472407f82108e5bd": "0x00743ba40b0000000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950b734daf7517c7a876261626580ccb6bef60defc30724545d57440394ed1c71ea7ee6d880ed0e79871a05b5e406": "0x5809fd84af6483070acbb92378e3498dbc02fb47f8e97f006bb83f60d7b2b15d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799ddd5e2568b6f88f4ebc3d8025ba4538c8cc8ac": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ef59d6d8b11b8b7c23f9d6ab5043237a9ee8f3f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a4932280b37de5fcec32232fb378cbb24275e8f8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339752a7310eb44ee058ca1a430356defa045e4153b5": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009e02b21abefc7ecc1f2b11700b49106d7d552b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700eacd0f6481a7df06b3af2c13b2a185316803eb": "0x00725cb5f62401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ceb2c93a77979ae759ed4d670e15b5674cee870b": "0x004e4748e70125000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897735e8af95538d6b436e3f63db0233b46f23aa08": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5ebf156bbed4f20662ecd3634c447e7f44873c8f660622490b044f93af2e544b": "0x3078f22015436d621062f7cc8334774eb5685e97", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890086eb4edda94678c1d7894533072af28e6b0faa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f721bc7693c0742843d9d5180715178b81f90f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b9f92d067202d78d58b86cdd2ff7efcddc4a4839": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f40c3463efb7815a2369d56492cd4a8202033720": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bfd720d4cc1aeaca059c466b41ae0a55c652b8a1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de805f9ae6f23f4e1bd98a26b1c055d0729755e1fe4c913a713c7094ebb1e362b": "0xe89e08763debfe1abb6bae24d4bc21c91150dc79", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824323803954be1a85583e00ed01ffc8d232edc87e1c": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900543f7424da419242560b6036cd8a21dfa01c52": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f6f372dfaecc1431186598c304e91b79ce115766": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51935b2e4ba800da23c655c66f212c9f5a2b000000": "0x1a8ff393032bfe3802d48f5ae53e9cad36830d2257e79b9acbefaf8f188e665a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970569baf12b57be4808c0539b9eb6b34b0fca7466": "0x00728e40997870000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3182c6b3fabe222b3bc13c912232d037bd765d0": "0x00e057eb481b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d60dab79d7d7d4e55174c0e747736025fb57423e997131daffb65509d9814ef11": "0xef30979a1e72cc99c93805d076c1c44eb90ed895", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cbbf87e662f48e24c47db88fbe9af500e10d05": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928915010e04d91ca1a9374a0cda2902039d362fbedd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f1d5ca8c8cf354b8d5ee91f6ed61f20059ba4beb": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d56216e1ef2e122893b8f8057ba5af16febc4e7f977ae6d7148bebb5de8eb3168": "0x4cb26d4abc32e99e107f1cfed2b07bbadd425b79", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339710fa75506994a9d1a03fb01abb31135d662a7086": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0571e067930c59f974d3394987bf4392513748e": "0x00e4f2bb672800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5193cedfa7e13a8c977a9e790f5f36629d62070000": "0x744bc15cd7e338227277c4d4c382389582cbc495365bb80398f94558b84f3a7000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339763118c5e7a405fbc2fabd7d2b03588488fa2c602": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a3d8392d560d174203e7c080f13421c5aacf1314": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517dbe52649ee31c1e12283e9b7a0f35df1c060000": "0x84a8b7fd4d56a3a955e9b72ae0b793335b479fa4e77a9f95c87d51f789de5f7f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d089c56451184d40b7911f91ab7f12d07ef6e2b1b4dc50a050adbfa4f8b58cb55": "0x64465f1b98dbd0158f23e0dc0b1aeb967e1565a5", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514e4f8a045839d496197d319f5f58f1eff9070000": "0xb0d20e5bdab9012279de331fd4061f6920e24d5c768754518be3b26b193d496e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51315a39711fedd259cdbbc7a6f172371b37060000": "0xeee9d5d071a418b51c02b456d5f5cefd6231041ad59b0e8379c59c11ba4a243900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004bc0521cf3e6289217adc9ab50722a3d2f6849": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ad80a2b3a1b573b0a7a15668e37f08c848000000": "0x1eacff2415e856692ddc43aa3dc4e8f965353af039e2efe4a70d6accb6e7662500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899a94771e7e73f9d8d6e880cfb12cab4e9573c45e": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282438ebea2c1deba5a629af27b0c8383113008c8ef43": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978961f4e5650444509af31c4a7cf2a0924f224b04": "0x00e415ad7e2500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf66f78612884363c0f231c11a33ebbd6d26ef82": "0x0080f420e6b500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890033f21fa9aaff0f79eaf1759611f0d8c60f7b03": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928904e38005b0c3a9e183c22ddaac3e074c689757de": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007523b9bfcc0c822d57cfd89edbe777e6994c76": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da255df385c871dae02401415b3a097695741863d9f4fa6c086889b9d14a3ee69": "0x00998aaa8fe8444322729f9dc9f32b41cd006bbb", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890055ddcd8b7423b0acec3d0de6c0666b06c14e7c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890d228ef1e58117a07783f0c17ba1faa7aca9516f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928912f9122d6ca5294f6817ae79a9c4634a07931a85": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897a47861cd4c65225b1e00284090503ce41023acf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970093897717316daa87a594feb918503d7adb5fb1": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974bcc2b45c57fa511a18cf50b5d54cbba9aa6cfa9": "0x00827e537c0200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d8bfb1af1cd3b81cfe14c9fe2bf6a51a55070000": "0x3c7927e2b4364f8ea6745336ee77f9a77bda0e4dbe2354d3c4b9328817505a7a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd82afa0d1687d166c1c47e1cf8768ce194d452a636bffbb2545d06e5c2c51143": "0x0054a7cf7c027ea72ac2b1994d1f6221539593a5", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c0f428bff6a974aefaafb3d14930fe63699a4bb0": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891e5faccf1d24fc1db3347fe4315bb7d00bbc45b7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d844d7741df7f47531af93e28a1bd1912a471977cc3cf5666030936380715054c": "0xf4487a0a91f3c75bb9631fe6160690d9149ed853", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897b1ec653cb5acf9b5e95dc259928fc766d0ac22e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d957478b19d8fffb6c622003e411a99f96c42301": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243b60facbf94a85c68b5455253564a2e60954f70c8": "0x00901ec4bc160000000000000000000001cb240000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fcdd5112170e4d994c41b72915dc50f9e4000000": "0xb221f3d33adbabe1695b6def8f9fb3b30a33c9eee2e7b024341152d5fdbbe23300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243175a83f4a1abbb88f6facc969d669cae9f48d7c1": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928977c2a982679c5d64e845eeb58f59af38459578b6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4a2a23436d36970bec3b5da3286eba930a3bcd38197cd3b791397cd53cd4dd60": "0xb6052a08ffad405ce2bffd714c580447afe20c80", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51847db6cf04045e4ed33970148934be49c5070000": "0xb023d129d9a0cb9490d097dbd3ca947d4830d3a6d7e0fa9975ff2789d9d9735200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896adaf97e46d6d7aaaee6698cd764ed2b960ad5fb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e04a97005acf858ce1f991e18fd742c98422d5b1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d0e8e4ab292f43b95ab94c1014d22abc9adffd": "0x0042b095ed0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c65b45c6c2b417a7bfe7a1f164ef12b53749fb5b": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51aa6eba795fe093d0bf965c9115187ca96d080000": "0x74958c765a261f7746221a02d4616939d27a21837dbf876c79446f13711e7b0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5fd1573c5cc41093c6d0944a40325e971771b9132ef47655b4c23bcf988cce00": "0x4a6a90222087648297e923b01d86cd754a7e7f7f", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d22012413e01a5b1cf021dd3a5b14aaf65ff97116880363686fa7493efbe9f938": "0x00c5229fd8a631cf877622f2e37af6eabf15cd99", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001264aae739aad7299ae9e4154d598c0419f226": "0x00962d3a03ff0e000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a608801bed3a876995532ad14fed513fe1040000": "0x98e9fcc2871bfd309e2b7804dd699f1a9ec889d70b71788d6f19407df9dffd0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d60afeb2a1bd8750a849bc9a851a3bac0d708a882bd4f2c5916ae0b714b4b5f00": "0x7f59fbfe6c2cba95173d69b4b0b00e09c76501fc", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289116812f3295d2754012b63805ca7f89226115950": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dda6898e71868f7f38396c71107b01396ad4c36a": "0x00703af7eb0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970005ffdac0973574e3fe91ff31b254fe2fd08acb": "0x0026dfe67d4703000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771a3d6c54338788dc4da94e34cd9ad2f1d89d7e0": "0x000458e5341b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928956feea6b7563f20c2d2dbba65afe424fa39e68b5": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d14bb873b383aa7bfc47eca28391ee5482af6bacc5be7ef49f6edfcd7b8be727f": "0x00c6ea84064e0db68bf36b61506bcd3f4a48de7b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289594a1a912ebf1023bf9bf1b0e77d6d40b8232323": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895ae16f3f5c84047aa300e066774a1c3001b50c35": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8af773cc899e6beafdf0f125cda8cc0b24b253fb2d856db1297c8bd01d762112": "0xb9b7ef4b7a727dae1735e3ce35827316135f3210", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004e69986ee1df06458380aeb694d42e5d4b4098": "0x000467eeed0800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fcfae0c7c49301fdbd9e1f31a5e09c9b80080000": "0x5a9ae1e0730536617c67ca727de00d4d197eb6afa03ac0b4ecaa097eb87813d600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d063ae62f76c019f22db0492b9e2ece04dc8a6c37532cee44cf1e8a43da760530": "0x002cbd649b7c80d1c0b018deeb64f6836e8552ac", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c65ef40b6a9a126951a17eb84fef0ff99d54de2": "0x00d26a9b6f0d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee41bd5428594191446fef91d5b0de95706ad49b": "0x00202346c98400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a951a1bcbbd1bee2cc35cfd96dcf9d101e630c40": "0x0080c6a47e8d0300000000000000000039b8bf0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786821570ee3ec4bfaa2e2ffbbf16ee4f61336dc7": "0x00f07a75c0d001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738f438c88c8c43562c4ceb3c0d7b24e11c03b708": "0x00aa8e680e0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895b3513da99c0572a510334c4256b99ac3a8eb72e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732f8dd495c7da7c59780a4fc381e45b90a2f891a": "0x004ac18c1b6500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243cef45cadd1e590c243490ad0c0fb9bd0a47d07c3": "0x0020db87b1b3030000000000000000002788fd0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c0a78ca841d922a4254e8957d62198a4425ef314": "0x00ea941a6c4203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243e3bcb85f93385dd35ea005d6cb8ee5e093657f39": "0x0050990588790500000000000000000081ebdb0800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51946e2fcc9aa3167a3e545f4862e4762d28080000": "0xa65b765fa2b4a31d06732e463b6c0ddcbfc615ec83d94ec4570512254b6d0b4300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e2b429c8428f37654b553ea0aaad267f8c67cf82": "0x00f6d259bd1500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d38e00c10beaa10ed77f6e574adcdc31f1647e56": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db0c02861db2e67ac0e487fc765d3ef8d30e65824f780d8406b00300c078d9f6f": "0x559bd4befa5d868ca380a9928ca2228e3ed26ff1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5a48a8500f9b4e22f0eb16c6f4649687674267d": "0x003cf35d972100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f1b8ecd32d89c484ec8ad5e216e573c03de39b0c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289465fcb930bde0872602382aef73fc393a31d8122": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970020540fa863f29743c6ec48150a3bce97706f18": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970014f112fdf769779b38ead59b66f955dad1b147": "0x00c01cbc746703000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddce9c106990ee809fbfa94214d6a5824b2a4c9a8eccde773c7de16dacc66d021": "0x9a2d3f2f6d4a3fc6b4e5be57fa3d896b3d7e04cd", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007af51d441a632cbf0b4ec175e61332f28583eb": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b54344f31910051ac875f62234bb7acece040000": "0xde462529cab3f839cf03bf49a7e850013794fee8b7667bd8c3c15469b802d02900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51287595e668d85daeaa1fddd3a6a331c904060000": "0xfa9066b188cbf62e3b2a063e5ffe4b4f92f8e287b7bf5368fdff1a992bd5285700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514113434c70ef8ec2ba9fae8e43328d81bd080000": "0xda25ab05eac156cf1a05e04c4e6474da8d31e104f00b2e006dc482e622165f5300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d24652a0007675be75ca678be9843f30a5080000": "0x06350b5634bf72fbb66298b193fce9a5acbfb564712cc3594a39dc051a03985000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890088f742d8a320915da103114ff128fe472c7cff": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516d90cc6b617586ac08515c07e6297fa4a2010000": "0x3e5ae76a3a9b417bf426cc6197998bc4bda848e6f01bef81749a51af89cf403100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339731d04a32f22022ec66afe6c2351db768ed32b873": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891de627e3faf8e64287bd2152ca027e4eff582790": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893e0c4d785244c2df4fb88b81b2ca0aa7411a6ec2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928949818d5fe1387b70b4b7bf57a64f7c86bbd15ae2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d163fba2398eddb0b956aea50e711358a3a0406fd1401fae031331eb1dbad491d": "0xba747ec663ca7239cfefc4be89639c3cff6da31d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c9f6de8445d99ef74450c9ea88efbece5f5e4d06": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897009eb50d01c3aa66f09ed1b9d675c6edbe392b8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890082edd0064f00c679183e5c014d3b4a77a4cc67": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289487bfea2ffcde43dc7cb20b5cf1f84c7c836e917": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cf7c0865a0dcaaf8bf3c5641e82eb37c690d5024": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db6750cc4f1e3b72f3b7495883daba0c156f9f5abc93650f2153f2b99ede82f08": "0xc8f490959275fc91f0bace6fb722639c4924317e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f61b2a45875ef1019da9bd2353572f00935d163b": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243e4b5aefb88bd749426b9a4bbcc09a3e9760493c6": "0x00000e8308e4090000000000000000007744011000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e643779779aec00285eac62b88c8f926c6bb1c7": "0x00706f96a68602000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8f490959275fc91f0bace6fb722639c4924317e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928937356375fca1781c398d3a68924bc6e95bf30ee0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a0bf75b9ffc770e921521c963d369ac457000000": "0xa814b8d83478b845fb4997be044588f4970be5507f41cdfd2c57328cbb83224b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd315db0cbeace9fdfa9b1fca41d0c0918f4827b": "0x00fc717fa12000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1c778ab3f6068c5583ee0df394fc7251cb00fe3": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928901772953ed3b69349088ae7824c649d6dcd0cb1e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897f352be93aa9f68a7c666a3bb280ab2e6a69c5d4": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243f00a83c85b0a5fd088b7ef7cd5b4910ade729d03": "0x0080ca3961240000000000000000000069de3a0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a07166eb5793a0f9d60a9adf056b7e4fdd2eda73": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b14c0abd57488f6c66fa299c0b26cddc60da9367": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970092faf23a9a9c66a7d8ffd3163d81d9f2bdfe56": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894dce6b147ce7c96b3722bcf6ea4f86c98f0c3419": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282433fd29fbaf2b2245931f154595c2b909bea226418": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243839c073864b9958f0aa84446302d41712b1993f8": "0x0000c52ebca2b100000000000000000030fb711f01000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700353dc8b8425298b8b6bdf587c4f5631601715c": "0x009cb26e1c2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397247927ac71bdd4d795b6478286a7800064dae9d5": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970089e3121271cf650d27633bd9693190bd2f69f0": "0x004072e62d2d07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a172d2ca38c6011f6a48bc781b2196b294e3f2aa": "0x00303fb7e18e04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397949b82dfc04558bc4d3ca033a1b194915a3a3bee": "0x0076022bd77500000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fdc926b0c8bd82c78aa1ce6624e6a3e55c000000": "0xcee069cef47b4e49b0d253fc46ac96f191cba7ca32e138122d6771e986c5ae1e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746a1ee4cb00bd3f064e1a02fd5c187e34bf4c97c": "0x00c4de2a7b8d06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397801aa940bf8ac12429d35c2cbf0a13b61758bd4e": "0x00549b94a59e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d4920fa9841558c97da4dbad60bfea2664f6cb9": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970549c3f578615e95f58e521a726269b6c1985dd5": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c9f6de8445d99ef74450c9ea88efbece5f5e4d06": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5ca2f86b5a4cc1d1f4c1c043cebda2d4ecb3f3d9057d9948cf2509dc67663159": "0x5f8edb714fbe38dad3e6a03dc61fb36fc4c37114", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928966d3157036246be0bdb9bb8427313949b21a70c6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d5b0da867de47e3400367d80d606d08f064e5e8": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397035e77f52292994008eeac5689f59457998f4f05": "0x00546f2390a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcae048bf18031f7f4781b51b36bdbdf12b0259c07316c67ca4e0859d4ecec353": "0x00f4b56df57e5dc51587163525b2d82d6a461e35", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928971fd1c6b80977e2763c24ce6b4dc6b863b2a5c97": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700aa961aeab33a6e82ee5a8f3a0c42c4f87f7068": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890efabe80d1646ec4d11f46d8fed63b070c11d5f3": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daeaea210589babb9eb1cb9a7787994ee4b65e98906cc9d9288386fa39184a750": "0x9e643779779aec00285eac62b88c8f926c6bb1c7", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243df524873fc92acd043016194ea11dfa3276f7e70": "0x0000c52ebca2b100000000000000000030fb711f01000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b69412672ab0f9a1e43b9d57f996f7231320e2cb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4c50edaf90e2ffff9be31f8cee70ba060b7471eaa81c3cfa1e7c090fb32c7a68": "0x00a53e3fea0109124613c5ba34c1bb2a9dbec3d7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c9e65f133b90e4fcf565abb95408708f9845b90c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970019bd61d8a9591e1922a11b46063a887cdd935c": "0x0098caaee7b005000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970098491a72d51c3e29f41eae6ef5042b4cbc6c9f": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d96488ffc974e750f6dafae05a28f29dbafc2ffc1265661aed70937aba06d102d": "0xb60facbf94a85c68b5455253564a2e60954f70c8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d5d65287605d949dfc3ce2691b6774766a0d3c0": "0x00da6352bff302000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9ffec62661647c99718d1e2783261291a545747": "0x00baff5ac60600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d7b88b6d9199cb9cfd50020218517f1b6cd0ec50": "0x0000a40731af050000000000000000005cc0320900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d605fd1308af1ce85bab5ba3fb19b330ab7dac29e01ad501420560f44df7e0e1c": "0xbf2c5698312de5417c17d2f7a0e7d8404a1ba62b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700383b93d6bb219fde72527528fad143dbaa7a48": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977732eeae979408d24c88500bb4e9166aa1616aff": "0x00d44d82b10900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702783580dc6b94e83db00d2ed655a809966d66cb": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928909790fda0cc6a748b715bb2ecd8fcc012d38811a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5161ffb64a13fa69211688bcbd16b3d73d37080000": "0xc5778652ed1b557c3e495d505b76ba1c87934d040a014005468f199c28bfccc900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891eb3162901545cb116b780f3456186b5d1396142": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799cf1375f2c178bfc895cd207ebb142621e8b8ef": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ae6916a981c3df939efe41a37045ba2c0b1daafa": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ef5b46a23ae74f4c079306fb11198d526b28b3": "0x0082db3cb70201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009f33693d1d3fc5b3eedc3d9d457f77059a498a": "0x00021044ae9920000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ee21068ba0c94e7833940cc4c8058e2dd41096e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890055823c75b1ea66d16f08559adbc70e19227322": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289231e4177e2d79bcffb4dd1d0e9b6cfa31f1acd98": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518085031f4a34f1dfcf29ca256dffc67aa0050000": "0x52c5195ab72c06d0793bc325a879ed2e1b3f06ba330ded7bda82855336bcf46c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e367a73ab3fb5ecfbcb4b118bf57538d1d4a77": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb21364d4087af9e9ce7dce7ee20233012c9d80c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339755e9a88d4c79252e7340f1e7816098b755c942d0": "0x00e08a5e43ea03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001bfdf3604e075218ba10e202d13bcde0382ead": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895f8edb714fbe38dad3e6a03dc61fb36fc4c37114": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397537b2feb029a7073da038c2b9bd34c1c6109a0a0": "0x00c03c208f5107000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b37489e03c48cf54cff37898b07f64402edaf101": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c71916faeb4697a163328b984e41cc4035440ee0": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b365d77a01b72223a89517b981d0b97e5e41646": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e0efc13ef5ef79db8c5973c8d1956a63e3310b43014dc64187bd50693c97631": "0x226c85b4f7e53cee040b6d2f45f4fddef5d97bee", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397225f3e472c48e708915cb4b24a3091f22fda52eb": "0x006e89135fbe18000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339754036dcfa7deae92f0d948088690cfdfea648143": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d38e00c10beaa10ed77f6e574adcdc31f1647e56": "0x00009573c24800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900410f38e2ab3f96a8303558ec4b470ad81dd10f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ac370278e27bd62fc22ca4b0a1f850fbd7b20e6fe5f4c55bccb72fffec80566": "0xc330c1abd1fa488ffce0ddc6527afc4106f122bf", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895b0fe4c9158992bf5af9256b0b4793dd6ef42711": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfa04b68da0a4e5933340abda5c7d7007c51bbb2bc48067e8dec0ffaacdb11820": "0x9b53723ef104396f1f44a378a84a15067e11e166", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008d4360424c57ea4e11f07b95ee83d591570557": "0x00fe73aa8ecb1a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f40139d03ee67228f37fba06e187cb0944fc9e": "0x009e4397200200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397884748c1ba66a37845abd3cc3bee1621cff23241": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bea41f180d6d5a48ebfb12f9c497ed3ffe1453": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fe222cd463ad1e79b057bfaf53d7865205050000": "0xcc95af78380ab7e33bb69e1239247559677f86f74418b395d790a236c751ec4600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db20bd9a3646907b754afe17589e1d08ba7604099110ec787dad89638e3436e19": "0x48e8806eba183d1364c2acfca72280c95bb41ec3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009c889dd86e5465eba2a0bd3481d2e89d4ac209": "0x000620e7ad0800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ac3ac23542f9c6f42194b7e485335dc5f7040000": "0x3ce2e3348670207db72f1be4076a5725bf3f59c41fb13c5f6e585ebe4ce6497f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8ea678d1d866f5ebe84e3830ddaa3df3c1dd58e11be510aba931d36ce40f8b71": "0xfc29a37e321f816145f9645967ab5e2a87d8b0ff", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a261c62ed56b0176947b6e54f7017e2843090000": "0x9232d67619fc452fad6b32e2bf06d6e1265a28c09cb6e10bc48b971092ec733c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1e05e059f95a160e511a4a2c00c70031f65a84dcda52ed3532f4e8d6959d395d": "0xd7438a2461c64335a5c736b31be6a2506be76d10", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab255abe36663fccdba892c4ca3bd160bf845f35": "0x007ceafac42900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970006c9e7bec9d239b8b08a48c3c4a0ac7dfca848": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4ea4230999370bef2b2f92144bc03c9511338a7": "0x0060a0b2cd0501000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289746aa9ec270bba58b97a30b5b402efeaab86bd28": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a56a6f0449004c2e91b73b9e3c11db59df060000": "0xa4910e5bf0a07ad0b3dd37d04aec0eafdbcc5ce4c96e7bbfb4c332a3d135db7900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243bebb6f638336fe10517a0b38bd73105f2086690f": "0x007045af21f501000000000000000000e2ea2a0300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5175370025a291caba8301ae2b92e4319b16010000": "0x0a6d7337f0454acdaf58ff349faf36febd6f9dadddbebd1198919523b91f6b1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b2ad5daf9b7852104cadd134f786faa798f0387f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397027ed05be029f65a37ae646f349adafcc9758755": "0x00a031a95fe300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339712ecdad9268108d4cdb6c21da81e447ab12ad84d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d1ae1c475ef49e628bfa5e4e09e52fae00d6b66b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5106b29252d7251aaef654b255941bee5d3b070000": "0x5e4e1bb00487836ed9891e040019c477ec5fd483ac46cda73b62e151f31f610300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c02897a2a0d8caf336a1a5997db294e39df614": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289df586c86efdcf8add8219c7c987a16d25e39b6ec": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f65aba8ace3c2b4a36c14de6c24a05f664274791": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894e86113466d232dd99103281ee6da6888245253e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ee153ce83372a6a2624bddc0f6f9b6235e85f576219380cd0d2a03eac704d53": "0x008d4e47715eb112c1ffba14275bfad41150a735", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5104cc4092dc50590cf5a303ef948cead3a0020000": "0xd249dac11030f2f8f76370724c3362701b312f643c313ac3badbce5d5634b61b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f67b3776ac1df6d0562b404d4ec62deb0cbe930c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003116c624463619d017b4919effc6deabaaf09a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397129631915a3ca10b9a159a7dc95bde0ba71682d3": "0x00488c227be903000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513436db8bf2d563cb5d2999a82809eded0b000000": "0x9ed2733809fff8fc440d3fb8c4365ac7a6a520c46ba4a2bdf94f107bcc5cea0b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517f2072543d39c452e533542863875651ea030000": "0x000dbbcd4f4f6dbf3f62581d050c4b9e0f23ab599a59502df2e0cd0c8367774600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcc95af78380ab7e33bb69e1239247559677f86f74418b395d790a236c751ec46": "0x00116621921d8a7b01706539d19d65ec48dc7dcf", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003e3ea8f5c20dfa974948da91960c0812c09ab9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b3b6d0e8643d53b6b22807385fa63146058f56": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928948d28e8123451e65d0b54aaccbf5f13fe4d3a162": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d4c974f7fbeb3bd79a34b7e8bc789af96b8daf86": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513aeabdfcd033cbeafbe009f13b672fa0de040000": "0x47e503b630c37057023c04ea57149dc70ae19f186db24f59881c55cb61da522f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974bff2ceb822e1217ac9e0b02e78e31a7a8924f5b": "0x003a22a6ba7400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282435d8e2e6b9118484134a1925813e545b37cb89102": "0x00a0724e1809000000000000000000009ab70e0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890041910d9e4c61fdd7759a2d317ab892cfd80ec4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972fa4c6f0e3652cf77c03002677a72a46205e8f07": "0x00eccc45eb0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781ed4c64b1809a7e859cc746ba10f8e777358941": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004272a32a2ca68c679f25fcd14ef02cd7933a5a": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824344401fb5cedde57d33b2898ee66cc263029b6508": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289029ecc9d77295d1126c333cb1e1bdf3ceea8d515": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928938b89b94dc5dec100a23fae5b5140ffcf81c8b24": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897e5684f9a6f43932992d720d52b378fadb376732": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cd7c282b347e54ed214e842158c7c36c99cac70e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ecb3d65993040d26944b347119eefa31f7bf3b4": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004deef731d0998523980400c6be915b827d4a17": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751aa47c803a20a6334e4589ca76642a68d3cfb32": "0x0074e3f0486900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f4400714bf70c32740d1b103553e4147c0ae254": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f42003e7c19b429ca0f6b9f0f75ae6c08cec5463": "0x0072dd4e553400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8c80d2977137d56f3a0ab93f78e5c7966bc2a94fed331d9457d8cc4b96a43a2a": "0xeed251dbde2ca8d330a978ccbfe4758294a096c7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004d8fc7cad40c95a1d1cd38cbaf4a6c2a119722": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977db1094c1006eb7c057cde290791334ee99e4754": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f1f605aa47e882d4c33a928fb1620881682ebd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003d1907558997ed87601acc550e672ac01fd7aa": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d24462de23cf247bc7779c3ad0d1aa31f3e45d434f5fd362e3a1485c533748205": "0xfcf3808986a5bdfbf72211debc42cdd72af74aa1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397151310c5ed21bc68b85c5c754cfcc5a7b1869cac": "0x00045a68c81600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7f164ab2ee6bc8581a0d06bfae3fb98e258b265": "0x00203d88792d00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5192e04f4896568ee3610e6086de6532cb50050000": "0x08246355efbe8d86aae3451c75562cf542ea7ad6069576181ec97acfaf7a144500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003278cdde8afa055f7a54a0e928965df0d681a2": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970035d19bc0178da96f2ad24504182733d90a0ed5": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ac9bc183534b782d3f6042cc77b81cb4656bcf8": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c20dd03a784a16714c24794834e04903f9395a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773344288a3782ca4badf486ce54de2f6398d1271": "0x00f6a94eadf207000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b689184990829b35eabcf62d5dda2f2c5c050000": "0xa4a61e58337c41c96a70b2c906fd4ad346f180800caf880af2662e658fc6144100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002696d567f76c4b7a60cb00b1d95b0993fdcf95": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397123843545fb525c8e134c9a5f15ada6865cc3848": "0x00e0c03b49b506000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d14a53177750a94e9bc22574f2f971d71b8be81b55d607c45eeb52d7a4ce9b859": "0x15b8f1a95061a20392e601bb5bb008415ba20ca6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970072726b3815bdcdd6c5fe51f96bee5bfd7ca289": "0x003e35893c2b00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51252dbbe52aac4459ff0aa177f218894863070000": "0xfcbce9929e3c47198198c5f16c5786fdcd613bb1d973ab16eea54bc850f0aa4400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dd4dfe0df462b5c44aa84b1edd24dfb1d0070000": "0x46b90d1f06bebf05dd594186ed002b546f85a4e612d060ce43fd0581197fa14300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5193e6efe3b7697aacb37b3274065d7317fd080000": "0x42cb52bfcf607025393c55d84cf361775c5a3914b69d6f78c93972b8eff5650700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc23e44c4eae7d243cd5795c4e25170a40cd82a5ce426bd807014d7c0e4793872": "0xd67c0d69691f9d012cf1fd44c5ac23c79cd441fc", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f1de81781e8bf83b57548a1ad3bad66a16c4e01": "0x00e45615d51b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892ab7d6f01cebfd4f9fa58e85fca6ba6a50e4a2a6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a9807e6a10518c24038521c00541af1e0e32a052": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289173ba35fbb37fd281880645a2e7f8e18ba38de0c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893fa2c79b96c7e30d5fa1f24a81a84e10aa336ae0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e9f9b1decdbf877d13094d5b1944f5a982040000": "0x528797c0df02524a8804adb5101bd30ca763253ad70423368b4cac159975766c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b0d433e9da913b17b4d0dcb6050b1f24f0050000": "0x16e7952efb44b46257327d0d81cf6298ef98eb5caaacc783c082a3cd47d0d22d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b60facbf94a85c68b5455253564a2e60954f70c8": "0x00901ec4bc1600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518f85778883f087ec5224e53df0599d03ec080000": "0x0ca516bb62f4ab81eb6d854c7f11abc68f0a0dae8719a1dec67ab3648c8a170a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5070438c5a597c4f1f46a4fdb4a1b5a88f46b37f1985b15d8a6daee52670fc36": "0xce8a0915d27d4d3295e8b67c593d3423f371ce7d", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5175afdccac4036b107412a3a48c318d5f64070000": "0xdaa6241ff8215d829ca2e362f944ec72067791d57746cac1baeeb1ef499c690100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d08246355efbe8d86aae3451c75562cf542ea7ad6069576181ec97acfaf7a1445": "0xed089a796d2a81919e46643e7c2351aead6f1437", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef3190039aefa5914791dab9d5b4d019b0441e14": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a670d24c5fe23dc467cd47ff9b8b5fb07369dd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928943c8ec1ace6c4b36e88ea5b6388c20ff3f13b19c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3edd53fe4fbdb56bb537f274e8c902fc65832f4e053d0920659caa7459f9b95c": "0x00063eccd46e37c80e52b55e9ff2912afd8d99bb", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df05f3ef3586fa4012fc8249571cf84792d3dd1adedfa603f719edba2a142170e": "0x00b1a22d149fbe630c3f18a01bd593618e1e2fdd", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a22fbd442e50f1cd5ce576ca9a6d917e1481c7": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824320766f01d859f1ee11e14428d9fb96bb1ebad946": "0x00900260406909000000000000000000d5953a0f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928950d30f8fc7564e1fd231e160169f19e864c3a641": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008550c3b4af1fa7a4503bc9e55a8622f213138b": "0x00ca73a98f2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ee795dfb870d57cf366f358e3eb41c40544313": "0x002e33bd1e5400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978b655867ee164b797df4a199f98f745757630bb0": "0x000a31a56c7600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a56f814d9f170a1c285817223b072626b517d099": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ac9e50fa5a78b072c26e33e6ac2c8e00fb2a22": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928908afb83c6ec32222be7277238e78b8b768f47ad7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51220cee30d447cadc277f082608b896ec71070000": "0x48c36a6ca9bc4cee5de809eb648c06c25900abb5bf37fa09b1e24435d4b9602900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896115c56329f345ba42307b2769817361a92029a2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de6890223c279fe3fc640de86171ae7e6f9edb04203d5a8670168bb725576af62": "0xc094df9784e3a409a27f39875a85d47fb9d6d520", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970025c20580d7ce0b8996c9bc91f5935dc031f3ad": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898b655867ee164b797df4a199f98f745757630bb0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d6d9fcefe1a8f0fdc1c52c8f7a33d299be4b4e67": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890e696320539189bf06f28dc0c7b7ece1880e14e4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51502a23c90e630d225a635766c2cbfa96bb070000": "0xc2d785f6ae83eba091d04a43b9dbb91ecd9862ac20b70c46ebed79f7068e6e6200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c72c867cc89ccb922cda5821ffe7f060d8603d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397810cff23a588aadac06cd93b443a12fa3a78affc": "0x00008d49fd1a07000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae1595f870cc27a34374a6b819a554e242997efeb760433c6fdb4372c2f28204": "0x3bace2a685d8d73c3e60b84bbc34ab782f54100c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928942b1d63ebbc6ca0cc4a679fb341c78d1089702ea": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518f157199ac37e16ec1ddc5abacdf03e91d000000": "0x1a7435849cb3175839693f7e078d1fabf90ef3fd38df8c50dde7fb5c8826086200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d29fb1d3724764405fdea290aaba4637eb2a6d72": "0x003cf35d972100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c6f2351c0d351af08be5f54ca624f1a12417531": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a496c36bc39f1dc6d989db28d51c55c102555007": "0x0080dd4bf4ed6d010000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514fab27570bdaac17568825d7ce6f106977000000": "0x6cabd36a1a0833f843b41221a584ee3396ac4df33712dd8b96f6a5f0babe415800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517d64c08958d03208cd2682ca0b47d45777070000": "0x0ac370278e27bd62fc22ca4b0a1f850fbd7b20e6fe5f4c55bccb72fffec8056600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339756fa0858580a1f355ef357c2b909915f72c4b626": "0x00188d22dd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c7f440d4c45c1ce7a295c788d9cbea9ff627cf8a": "0x0024a0d50d5d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900684acee25e34f5ea3b944a58c5e23f922c14b0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978dd535c62fe25e520fb4becc53d19d39f5d798c4": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900185a694e3eb29e58f03442d75a8f59479ac8c4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891394c491173702c7bf42b7320853fe4ba3630d9b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c96ff8e5bccba1f29e17561d2aaf59cb6e38a9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1a952f5ea1b437ae5ea5b6b877340e776124812cf6c399d2fa07ed893fddf84f": "0x57981d9691cc20a7ce7c628f6d7b1ab82fac8607", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda54c31637509fec9b39b34a070c98437c8e78beedd7eacdb46aa99f41ecdb00": "0x7db1094c1006eb7c057cde290791334ee99e4754", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51451b5d84a143e596c60184b13b45e5362f070000": "0x0a1f26b375e08d87252b12ede342a0f5062802fb2f5aa45f1fd87e50ce68645500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890bae10406f82399bab8c8713aa8f5e0c05c98d84": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5153818d1ccbc0ed4c506a2875694a4a508b040000": "0xa082ef6765a3eef5cce291b2507c5ac3d6ffe5e10ecec2525d1554b8d2db144000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c527becdb446083e54bfcea69cddf296fe030000": "0x665bdca7d60b85bf96de183ff4175d4278494dbd68b9e72f21b142a2ea5a7e3b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979311235dbedff7b53b7ab20dc27a76aa9708bb0f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928981a1929517b52ccb71a63d31774bef3efa6d080e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002bbfd34859c09b36b907c0bf0f3bd0046709c1": "0x00a25665ab7701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970062340e032f69aa1370bbe8901d6f4e40f66b60": "0x004a5eddc34200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e840d7b43436037967390c763c9b440c88020000": "0xd86a0dc8d062ca62c6df695d1a7afa138453cbccbe7eb0a05eafd587cb68905e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ffa848fac4488e115b3c44b86a0309a386030000": "0xb2098bb66a2346135b378a64c3de1d2bde6c4199cb7d805a970b4f6fe9deb37500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de828c1a8caca7d6b13de01babf4dcff99beb7f0b6dc743a355e77cc24614855d": "0x52e0f7339c1bed710dbd4d84e78f791ebe2df6b9", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f38865dac042397b42a80a2cdd54eaf32d439754": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970052ff8b09907fd5cbd63791a01672362a6cb075": "0x00f41140b8e601000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fc976b60a67ac88d018a0e5dc940548364060000": "0x3878ca973b0f31e3c7a63bcb0bf7229452ff5850e734d3fcf3aa59ef2a6f556700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbee56ca36a0a5393bf9bfbe5d2079e31d4359d35388df257e23793c7b195b855": "0x54f37dc277ea0ae185cc45886365f99889a9168d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970011f97b8a9f4902288c235478d2a5f3aa060073": "0x000c6098159ac3000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d40e09074de729692e44ec9b276557f6486183d7195d87ebcf77eec6bbe921730": "0x7c89a2437b7cc02b0bdac206ac317a8a1e7826db", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51afa3e2b56ef09ea815536fc1f119ec1d18010000": "0xc63b6d81d7d307b9f4464304330a840f5159c78a804dd344c5fcbfb3da9aad1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006e1c09312f5397c46089a6f95fd0424523eab7": "0x0084449cfc2f00000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca28dccb559b95c40168a1b2696581b5a7": "0x00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddaa6241ff8215d829ca2e362f944ec72067791d57746cac1baeeb1ef499c6901": "0x2ae125582205e28cc4786f5e729d9a09608d7b27", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974dff7bffb7fc240abf06141976d2fe0bf610edee": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975fd474f8abdb347ec54b15cbca40b56dd2f2aefc": "0x00e4b0a9fb6000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976503fe6dc225865a54dccca75e9410f53a35b137": "0x00fcd42ef94200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1d09b38beaef617e933f8c735fee190db1d0263": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf1e7d7b8b56e594e0294c5aef7a81b957350e34": "0x00d266874e4001000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bca0e2071d5f0e59803828bc7e0d3dd67e4215": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289110b0b10908876406b974a5ee670dfb9d86ca0f7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289719819815ba8d64ed7712c3005c8df49b2085368": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700729f3355fdf72962e9734ffa26ccff9e64c0ac": "0x007eed5f265e7d000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f97abe3fe52ecda47e997fb559216fd85e000000": "0x10b5f5141a6e5bb941902a1c358472374c98b36fe1352c5cdcc0083acacbef0700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b4de57c216b2bb92151828a9335856f54bab03f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c44438ca119cb3f91dee8f514f435f2d88c338f": "0x001cc7f59f5400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785bad1dedbccdfafd231fe1c96b3a9bdd4e2e083": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b0b0d02d246dadb22f40133c2fb0fcf738b3337c": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e7573ef29328441aba06fcbecae95383cc85a5db": "0x0076e6a2f50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7ccfc66f0b7e76f786bdcaadccc5171ec82d013ab65e33440fc6c1d92c07d521": "0x4c638efea44e5b7898f33a7ac1773f4b7deb3631", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ad03ba0db46620f77489393a7e62e598cd7ea988": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6816dca78be4303480a42b848fef6ffc01e4189a5ec4aee433543b0381c3a51e": "0xff3592363b611cd701ccfa565dff6d1de23dfb2e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970049a562169b9aa96c9327681444d541c8382cd4": "0x00dc5f23f53700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970010aacbcfaa53a4b19bd7bad12ea033d1377220": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700613989b259f1d4c333ae80a3e78e67446646b1": "0x005857a4df5300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513695b9fdeefbd4d264da562493b640fba3050000": "0xfe5711e8434fec36172075fa74d8168a95de0baf14c3d12430ccd97ac8b5d25800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a172d2ca38c6011f6a48bc781b2196b294e3f2aa": "0x00303fb7e18e040000000000000000005e37600700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de695de55d5fb0be7525b45245933bef3b57b71fc7eb68c38d0611015c3c6f22e": "0x09d7bc4d2ce5b5369c16b76f6c6297b1c711b832", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e565ecb628a3fe2b055f178840bdd340ba5d7e3": "0x00d6cf06ca1a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282437da1f36b13c74e5f988f806da14650b790a54b4c": "0x00208dc1a0b9040000000000000000001963a50700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2cc16da9d1f7271475075aa8eb5c6667714426b8c41dbecf92bdedfa462b7163": "0x009e51b0d7a06b3a8a22ddc326e1981d417a8b4a", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd07fcba81f01c46a75c6f430ee4938322ddd3340a460aec133b410962daa3045": "0x1dc13ea429ed10d2ad98c5eb66d528e4875bf2c1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf7c0865a0dcaaf8bf3c5641e82eb37c690d5024": "0x0080ca39612400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895acaf60782e62269ec264824dbbb13f9e85d71cb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898c0a288a91525460275a7b8762d2138207210ee9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d74cbd10ee9e9e9f772b6c60db076022f568dd36388147e08a99ee3b5f3472749": "0x00e594def1a782c9f0bd4f6e5ad16cee01e380f3", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900de86782f19fa9e5881223077680101b2b99019": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397818c69a3f3bd436087ec101f0ff8aa2d3cd35e62": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928969b8875ca9c33f7293ad4aec9a36577c257041bb": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5125386ffede0dea6b09c2452277d3a86613050000": "0x9841d92c40dfe289a0ad0ba13bc970838226f9d9baf089655588eac023e3b17900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd245df4fa44f453b3aa554bfebae8f4310fbf8c4a5abf9da6c1e40c1f05a1b7b": "0xcb70a267c49250f5c85f0c4008046cde3df51ec6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a482566e63d032af218a8d65caeeda5dec73e4b4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7e9182dc2b0264895724fdc38238d5a20a2904885d35ee292e2b810fa5313a18": "0x895607ffa297db864ec7da7351353618ddaebdef", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397190e7c0403a5dd4bd21d426d88b76b1d513d39b1": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ddef1f2b6433c7dd4d7012090f5049bbe4c0dc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893ea7272f84cfca9811d2103170ffe0dc551ed3ea": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002cdf90e124b3a929d16682b6683f198d65d9b4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4c28c57507b59cf24b2649003b9f8b9e7980ae5": "0x00667bcd2d6e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890054fb3c10d0b0228569744734c66321e14c01a1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513d510768dc24e1383a0541343bcd6842f8070000": "0x522ed1a44f5b6302feb8ae1d71e42c6727e88c94f896f68d5aa214a52ec89e3400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397436b98f3a614079ad005b7c62743020ad3dd672a": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e899a68189ac4b743750da4bd8445f7f148932e3": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d7b42e27e2382e2d28e06bde9d82413906c6c03": "0x0024113bdce301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a42264114e13a067ac2baca439e9ec5df20c8819": "0x00c029f73d5405000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3b8cbbeeaf1eacd6fac6d3bc0450b3736482f14": "0x007ceafac42900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8ada3c6fa6d06703711d5ecd225ce1839bc44ae0e6b9c3ef1ea241db8f668170": "0x5937c41f80fc6111e6703873f89270c60fe559a0", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517e257044599566a53268cf75a6c20a1a2e050000": "0xfe1d28518ed43e08ee85b800b936b9111893813279dc718f4ed8c09bc407a80b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d261f0bbb3c232961255def15a8939e3e0a5f6ec619496d704519ba3e111a6012": "0x07bf572c47678e5141ace6b29c38e0a9995d7134", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001ca8b01a535b2f6d01d9f361f86dc495bdb21d": "0x00c0a31bf09801000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397782dd81060bc85bddb0ce7b2a53eaddd9f1f6aa0": "0x004c343ee04c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8fabd8cd6b1a1eb325d682e8532fa3c55ee40d8": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dac7def1123c306bd08a5dc4651f054c92854a6f6181a7e5cef8a1cf45790b42a": "0x0042fc4e1015fd757f149ca0ad34f44c33b51893", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d0ee80934b74c7f0f25c7a137a8a16e58e713283": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f619e5784802a7c966c46b12cbd2510ceb084de": "0x00e2ab7bb83800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515341a6446944f17638dcda441dc5c67dfa010000": "0xfab2071283358794145d6ded609332c49c186df882ee3033ff446d462ae9cd1700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289822fd50f043f331fe44df12af8559527b4be8006": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d6c4d3830cec539bb01d5209b79ae4fcc5053bc2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d9eb97d7b1c97639a6914e0cb56dd8e584910646": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4690257c528a11bd5b91364eb0ded445aebbc97ff9f994167142a74d486ba054": "0x203d2e2bf08a58c132f650f44e6db94b78097032", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c9b6f1962d279e00a886247793a794d16a060000": "0x92e5e6c84e9781e37eb1afb166eefd22687054c8bbed4426282077b19aa0e70800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511cb4d7c73fdd4375f75ed0e8df32337c89040000": "0x76a6b80847d39f2242188ab8488af63177db6cc02d15808fddf18668e2d6bc2500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397328752def488a9c3aa9e89edfb56cd7b4b56f7c0": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002b44b7211507e761721b71b7d9dd77b29c67f1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ce1296828e55f7bdd965edeb7ebf72bcc3050000": "0x622470e00c50400929243e6e9ed4c62edc88c1a4f7f70e62bca37c277ef3ae7400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5176ee277fab778cbcad297988f333339fdb060000": "0x7aaf0d5e96dbe960bf0a63df1183a14398d655a1bdbeda95758696f73fe5773800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e4d4b606ea5d17de20136f8e12d3521ffd48fe8acaf5325c7961f002b582d0b": "0x2f4400714bf70c32740d1b103553e4147c0ae254", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890c78bf3b5da90e93c22b8b41666f8b30472358c1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289968bbcc804a1003e95b3150c50fcc25873e0d8ba": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511387b9468d38a338a532c826eb6d4925ce080000": "0xba274ee6e60ffddeb999cfb69b277133b404a7a81e7f2b2482cb6e390dc2f13c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896052ed2407cd5e04f17216d9687c289e325e14bb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a2fb944dd8930532d3fb08109bd7a46cf07a75d0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977758d89177a41267dd2390262707faa602f4f2d9": "0x0066c90483c802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824354970d8d6d8f8dbe9c87ab9cab9057fa5039e4ab": "0x0040cedefc7d010000000000000000004b1f6a0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339754368965237a390978643cced184c6ec51d0ffed": "0x004efde96e0b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891bc24e64bd4446b8873a956a4fc1d1af2b798a2d": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d64d09556b4e737f932b39dbbe48fa4f67d862b": "0x00d07afd1c3204000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cb2f6197ace28dcb66d7c726caecb534a79925": "0x00da88e95a0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddeeb4b4fbcbc7e7e1dd19a2371c71951f820801be5e87e8e18e2e2291e4b132d": "0x008f6eb1f8852e3ec09a2a33ff19e4c7369ea37b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397671dd13509d95926af853a161e78b4ed5c8a37a6": "0x008c114007d103000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51198a56a86e1ad99e38491c17d47b54f8a2060000": "0xe03136d76b36804ad53f74d2bc7a0f9f50ebd9619a5746c20da5780fb739c33c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e173806d025484091145ca79d5d830f3d38b4f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892a7cb534202768d7daa624051d64ed942ed546bf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899a1329847393a87ad4c25bb21ff093e1d4d050b3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a899ca042ea5de91cd2174dfe9e13233e9deafd6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514367d9f6b31e21e7d4f9e0191a1e790a21040000": "0xbe2b56289bd3fc54e462418ab4b49789b94f7aec6869f1c09af669e4a55b695600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005e14b50c77daf1b3fc6f12f3b4cf820a313adc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cee564d87985e3ef80e8d0cea1d8f49278fee135": "0x00e8addc7b5fc5000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899cac5a27e397ca42444c2d39af23bff9eb681125": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b2f4451bf599ec52cece0a8cf96d61f350d4ab20": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ddcb32a75577e9a33c2af218bb8209e96f92627f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ed4629967a1994b2f28b66ca0ad7d5f7bb583ee4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518a394355761ed0713ab00891fe8e85df8a080000": "0xe9c6d2f52e842646238aa9a4b144820f450c5c55b0503cdc92dcd302cde08e9c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d785378390bb8bcde9f1b6a663a8cc3258a92ed222602e3be7ed626051d6a8c5f": "0xd7200c399634a9dbbf59db9f48685ec22ea4acb7", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d5ce5a6db3349b614aaa7f3b793bd57e8f050000": "0x40602cf99698212b9115e545fdb1d449d37ed001a3b8c4cc9fb6b890ba92c45b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d01d14e379d23d6a9b47e8886761d8e9d7e56f": "0x00ce84d3182000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397805cbf1fae3e810ed0cece7016848a677cce945b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fbf27816ed8612ba4477bed6e0a554a1a35fb015": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc6b49f7539a0bdb98f78b3089baeb861b9e71c1": "0x00feb8bf501000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974dde991987acdfc23c0e4e72c70d715794a052c4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900320c624958997f6d8ec1d130a436e87a1f0b0e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339739634580a5670327b6f4f925dd85f2bcc2c44c6d": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f18ccca441625179b40e774436ba038505fcef83": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e3a98d5a1091e1c5589741feb3799e8a57050000": "0x3e5dc9bba6c0396f878c3258d641a53c41b0d9274a55eb4dcf59107924e3830000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397414f19cf5dbf026f6e069532c8c220b82239c652": "0x002a80fe7a4000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b0afe917e54529d9151a5ec682107da993d89065": "0x00947b88965300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7c9e58caac08b868c221d0347c32a43e1ca416ee023125bd2f43b590f2c58e39": "0x000e8ad6492f516c942bef6561251b531fd7b10c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890b792f95c5d535942270423c12a735beace8e36f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928914f7f1344ee6dfe20dd9d292c543e9e443babbec": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ecad80fa0ba008c28f47b446a99f7c401a24df80": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff4030b388b3dc8280c53544646159759e3032dd": "0x0086e2798e5c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f00098c1c1c81604a82b903cc34f91436e6a72ff": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e35152239ee9fe923f20df2f38280b32bc98d22": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890db44731b34934498c4853216a0e08c8d05fcb3e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289198a1bad80c2eac0fb986553955cfb5e30f464c7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce22e1a0a40b684163a37c72112c304dd51bee92": "0x0004f52ee08d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b27b940bf01de20eca4abfd7c9bdb2304142ad5c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e087bc674e53b1b48ca0d8bd6691eaaea2ff78dc": "0x00a630de2a5002000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339721fa2fd0d1126a88a7fcfae18f8fe849999a17ed": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a32c58cec6a3db131c52c9dd88d7e006bd18bb5": "0x003036d4980900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51245c3c4360c9bf6c7fdd94c0a99f161e71060000": "0x929257d29d18a4c4a2ee7f6b395d0c1eb9cb7685ceac9624437674db49404f0d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928908ec4aa26d04dba7ecbbf121d50373ba1037e763": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895b650393b228dfb785b07f149fb213d691e49b33": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006dd904124038280e01c52b465f2d802b3c1783": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928978ab8402b3e615c292fe9a69a9b4ac17983bc875": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eb514a98e40a66e5d4f634b9afae1ec41d58c659": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339716c09044a80d3a419403362413241ea81d5fa78b": "0x003c541e91bf00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515dd8be1410d389d3f699d403819b0fe1f1040000": "0x4cd38181e02e880a53114ccaf987a6f51a10bc1d172d509bab6f7e9d6eb2e00b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e3a573adcce5735ff7dda7eba84b27809c040000": "0x26b5fe12119935324adf8e3434cfd8c42cc9ea717fde9262fdf37717b40f6a3400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900385543ba35bb319a9067f9c03b1a8cf917a6dd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893dd62544630d94aed21653ed9ec15810cc759a55": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339749aa20d0109520abd79ca28bdb453ba1ba348b3b": "0x0082357a0a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397790a8706d0ae9782042de2a022125b746511047d": "0x00ba51b4360400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977967c0ec1b8b1bb821c84551ca7c9fd49c720a9d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db841bffab3688ea94e37983ff28b3288746249b87d1114828dc7b030c669a1cf": "0x668dbd6154064e193ab693a4f79bbbd06e107741", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970014c1efea175cd39fb686024383fc07374d6db8": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900939f839c289a1512d9859cfa8fb0ca0485a8ac": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daecf138ea1b459133e80dc71b736b388df75561d405dd1af13c872433b346856": "0x4185524e7b4ec8f909a435f4ac705f9348105b32", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339724dc293f38625991044c976a3c99c358563f82d1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a96e78d4900cb5f8c412c1437b15aaf81f6733": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d88fa1f44c372d28f74829f4304bfbd868e94069ee27bf338f6d6567ccf2e645f": "0x009b32198b47c8b8006c0c3483ba90a7fa18f8f2", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928972af8296d1272deffe909926d1db18ee418542a8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a807188cf956530898c1cb2b0017428f95a3560": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbac8d55b78ea5cf2f5a7e57a51eee3f0074cb71c80bc23dcd2d0bd16620a6f05": "0x143365830ba0c2a2aeb0549cce5107d484143877", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e204f47c00bf581d3673b194ac2b1d29950d6ad3": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700710a76cb9637a974616f5f9295470eb4abcce9": "0x00461784db1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e3aeda1fec9c6242efa7ffc383b897f0e06d85": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700385543ba35bb319a9067f9c03b1a8cf917a6dd": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890129b205bd7da590c22b986f2fcfcb3079ee3d69": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928925dc5d102c1d282b89ee19709bab596db52e3d57": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a56106482594175c13790cc8fd6d99575fbe5154": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5165f2a832ee83c01c54f0fa8c767bd01db8060000": "0xc6a52590a53bad9273441f2e6a594885b7c567b8dbbdcebe3b40cf561eb1671400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e22bdca82b186c02ba11cccaeb2515d10b0a81": "0x00381c3a2c0400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515ff0e99a0c2cd2ddb21680cf13ba822774080000": "0x0c5aad719ec7f446020947e59a75f4ebcdeada5f14a43fd3e4e2cc7ae7ba005300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002cbd649b7c80d1c0b018deeb64f6836e8552ac": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289484ac7901a2de5f9923afe4ff67546525e07ce8e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895ff44d535cee05fc476c35232eeecbdd5d5ec9b9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d4b6a8249f1ae3f967892d0187e7d783a49d926": "0x0082357a0a0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510ac0f59c2846ff34619a9d0392efebc4ab030000": "0x7017fbaea2e43910a041dd8513d200c3cba7b6dda9f84f565e7800fad57ae55d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890047b7702418e3f3ac962feee269d4057214997a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d7541983658ca17367c10e4ad6553103b3a719": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ecacc2f1bf37e9b8278709b785922e52abd83b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5121dbda6c124645fa1d5e092c16553d99e3080000": "0x2a21638d6758619800f032eb67fd7943490c20b5ab1f8453d11382769447d34d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339756be9656add1b07ddf587a25ca2ee79b5dded4e2": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b71d05cf5cdf7a9b15b20b9aab5e91332c271c96": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d502937e1a131cb6646bcb72d521c894d4d3fb35f1da1c44058b7658d8d299d36": "0x0549c3f578615e95f58e521a726269b6c1985dd5", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5162232d4cb336d5f629559f759e2002ac1a010000": "0x028942b7e78c61e78086e9076430bd3c69cf08736f3e463d0419f0f12751f63500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732b2c49c595f816c6ff3852f983d77249dc9463d": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900da3fb304e2f3598a15b96abce88a619669935b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928960f2a161f72ca11980c5b6ebb86a537e63fc2de8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fa4c4ea0ceeb34bf67c13be01e477cf0bc8db84": "0x007e15ac953900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f71f22775221b1945fe6cfa3c6550c7c09000000": "0x5c5062779d44ea2ab0469e155b8cf3e004fce71b3b3d38263cd9fa9478f12f2800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4a80a6b62d1147e7520adfcb464d6006483c2506e258d1bb4e8bcb057e637b3b": "0x4659d80655ac837fc7f48b96aea70518da7a9082", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd84d3591efaa337adb83215be213e18204dd71fe9cf356f72281a687c825356a": "0xfef3b3dead1a6926d49aa32b12c22af54d9ff985", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339737977eaf6917d93704a3283bfe16d87aa5eb0717": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2ace8953c1bd780e51bca97a0d5946b613d918571490c7a11e0181907e21a60a": "0x77c56ecfc21bf4bc66adae4898224b07a81b4efa", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df1e9b2eae31aafa11fcc281d6d0efb49c7e12b2": "0x00da332b59e104000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289be638e483b91290575009bb63815c3ffe36de43d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002deff295e375a68734582a3ed0f7786b7e92af": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894877170e1a23388f4121c72d6b8cee7696ab92d4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519d06cd94550a4be6a4bf1506c2247760b0040000": "0x4690257c528a11bd5b91364eb0ded445aebbc97ff9f994167142a74d486ba05400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f65a7c12c29867648798aa6a777b44cc3a9ebc72": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a5c6dbf8963947d36e94126df831a50df8eb6e": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f7932b29b98c93c7844cc0833deff8b0109f958": "0x0062ad4a2fcf01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971cd62e399651ed8835de4be49eef4b5a3b190489": "0x00842449d35f03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c95f72c8e52f3df1ebfe156e7ce75c2121c8d1": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5160150cab18958a39702a59e6e0608759ff070000": "0xee9be31704415170409d65ccee6fdc7149ce835a99396e1e471db458d249d47200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890424193a415ebc86ff650e3bda37c521c5f6d45a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c3078593afdb525caed7ec794de3cd88b917b0": "0x00446b11410300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f4b56df57e5dc51587163525b2d82d6a461e35": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ee1301ee318ac92f4ae4254263da4325640a97a2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289652346bcbe5e8683ade954a0b4491a58809fb539": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e5664b93ad268393d1f695c4180993e60c59fc3e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ec3c0312d2a35ed0677a7f8eb29116ecc4ebb6d4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002802750d12a39450f2f4a0e19375b8de24074d": "0x00d403f12f6001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339782d313f325b3c9b63502bffe9c01361037086e99": "0x003036d4980900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516a0b5134ba0afe57242f27ce42e90bc7cc070000": "0xe25e8c141e674ba58ca7fd0043366f6903488f3c585ff1180c9993eb896a337300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4a39b2e373446d6df599953c0b0601c66d266732324077924b8aa89e0e543710": "0x0db44731b34934498c4853216a0e08c8d05fcb3e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d54e69813db314fb5f49b1532d7944d4195c5415402551ba3c16d1183cd89d127": "0x8bf1c1e68d1bee9a5d188c2b49939acfd804fc4d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970047753c8946ba8f3ba101ba2afa2832c4a5b6fd": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ba8649eceb83037c22cf1727ff5d47b9f666a5b": "0x00126d3b2f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db0d20e5bdab9012279de331fd4061f6920e24d5c768754518be3b26b193d496e": "0xe659b900949f70623fda99c695dbd27e9cd9e7fb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c1be5037ac4806f3087c19c2ea3375700b9682f": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397919633258963e54df2e985f3f42b3cbfe43f24ff": "0x0074f6c33acf0d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339725b28e2fbab8ce0b5d54ac6968369d6a9f1e2197": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243fba281c66fe1034a2f1cfcde7fc6f6d939df9cd6": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c5142225c7e26732a7ea83d3b25c826d8637556": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d769cd0854afec0c1a6d6c71d68417a13e653809dc8ef73842b0fe19f90b1b24d": "0x1c4ba011e13f2f735dee87c7801001ef5e7348d0", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5105669d7290d420bb80c44e0d153ca1e81f040000": "0xb60bf1d765ac0c534a544084850f794258e4c9f4e55965abfe9fecf52ea0c24500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5115dcfc01de543f9c61f863f49f22a8e060020000": "0x00933f6ead73f4396ac3ea16dd9988dd6b9b8b9309e2c8ffad113ee7f6b9f42100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c495e48cc5612e90dbfff05b12532a69303bf72": "0x00000e8308e409000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890063d8aa6c33d88963ee4176bdcbd65ece06cc13": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890d567082d66dc9c1cd236a3044a92c5b595fbeb6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890f6550e2abcd33b14be0768e4fa62c66fcbf665f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a6bddeffe26cd501deca6569ef33870f15aeb637": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b92a8aa0fc53b924467aceda1ac915abbd537be3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d0e6d8a610c30652d3ac9c2db8df936c62040000": "0xf0de782e8bad3c663be60812f0a2ac63464f5da3ec448c73334c07d71ef27f2c00000000000000000000000000000000", + "0xf2794c22e353e9a839f12faab03a911bbdcb0c5143a8617ed38ae3810dd45bc6": "0x00000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ee03095cfa46cab6e89cdf19dc2cdc64fc76d2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ef0d89b032790648bdccbd29b8fbe87868070000": "0x6699d3b4f697ad91f6e279bb380d8487560793f0f247ca0634c3d9242476577e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc0134e2e55a47b5c53427f613dceba99c7d519c6d412e64e596807a65c69b326": "0x3bcae7a7bee3a07c59a217cddc891d947965ec00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289461df0f49a1b5b38318c1cd425840986e15176f2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890011f97b8a9f4902288c235478d2a5f3aa060073": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282435acaf60782e62269ec264824dbbb13f9e85d71cb": "0x0080ca3961240000000000000000000069de3a0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289012d78b8ae3effb27d1a177cb14b2776562aa192": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c6ea84064e0db68bf36b61506bcd3f4a48de7b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339752e0f7339c1bed710dbd4d84e78f791ebe2df6b9": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f6bee6899ccd70cf776107ca787cd88dcca0b37": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0c0235079df3f9a6b9a431e0c3bf0e20d673ccb362376937b9e5e423a307fa79": "0xd1200ce6d0ba222db35d6135e051267d901f44b1", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900adedcb13c0420643327f35b6ad5da4a0d8c259": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289be581d9e93e611f86b7fd67cc33ea7125187ea07": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824356666fc53f50972d6fe7d75d1149ca3ecfef486e": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed089a796d2a81919e46643e7c2351aead6f1437": "0x00825826b37f12000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51952b2227cd4a00a7d3bd5e3a0810dfb209090000": "0x422f2aadd599b4974e4cb9a5410f03159e5459fa81e8348f8746a8ad845b830600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bafa18521bc5dfc93e4d298749f666dce7070000": "0x34bc6fb5ba6e2150087c96fd4852ec188aba74a5a383a22ef66b12c588cea00d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009d470cc85e114eb2b35c64b39f8a0e3dfd6759": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f67649a3f084eeccf566b5193cb6faa830cb10bb": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ce8a5f25554d7c733169f3b682eb3458b67472f": "0x00a6ffa0e4e304000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b6052a08ffad405ce2bffd714c580447afe20c80": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700936a6c0bd3a0110725442f1e0887d5ad459160": "0x001cd6fe584200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c9094f605ab3790ed1bcae8111c987c786dd294a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cee564d87985e3ef80e8d0cea1d8f49278fee135": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c061223361f4e8b4a71fb7837fd8eac1bcab9c": "0x002e7164960600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928965d6275a941e393d588ed1b1d0adc94285e00757": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289560cd6b5772c69efe8c36ec3e1f8af3b95c66b44": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896e3c0a9a3d9bf8854865b75f6d4b01935b4eba1e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289756034a116ad26a3a26d264e1cf490a12231b1f0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289344640acab3fe1ec3b3f7af2e9b7ea4296aa7085": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcc3a8b98f63e0c86737c439a3fb82a5769fc333b42e8abb683f7bc52dc313742": "0xd3b33791c1ea8922dba88bd800b509e884c33bab", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d315959e879d36d314c19ccf6654dce6b7255fb4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ee32592386daab2d2ac0ca657e8e165e0889f8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5191fb799863e9805cda4875fc529daf1201090000": "0x5abed40690213905ecddaf187a5a16cba5705720196bd942354f1debb47c447000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df66ad061b8b6ff29e2cf485f542b90e733f2164dd9567d2713eaa54362c4d521": "0x9704593a5983b6b3e498b644802337974a2d0c3c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d3949b803273f985e9a167bc42c0ef376b70d8b": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c376d7a071d508102173761ddf2b8c27f3cda11": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009978d735f1a23bb6922b620c490ac4aba66cfd": "0x00be4216aa73bb000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c316f08646011244eb99228d384661e77ca480": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928915955df69f2c7dfb120839d6b4c78230b664a362": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d78957d2a1ba4d3d9890e2ef1bb3562eb0774075455b7be56d0ba88eb3bd40943": "0xc43ec0fb4c71b599ab3b5e9e6fbd89553eb615d2", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c82c18505a345f5208a1724f6d2334dcb3000000": "0x0e0a207225e52c21bfbf08c5022e9a6fb26daf70c6cee1ee92a6a5c02085cf2400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d26b5fe12119935324adf8e3434cfd8c42cc9ea717fde9262fdf37717b40f6a34": "0x09a89f6468aecaffae52142487eac08e126bc071", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b248acf3f128a50f811761121ec10fc60c5bac44": "0x008015c5ce7b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893078f22015436d621062f7cc8334774eb5685e97": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5154972270baee765cd03ca32bf832dd8fa3060000": "0x2ca94b3c294fed7e144817ec4682fd72039057462bb94de1076d6990039c862700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890ace3d849dcc2c1b7758b05cea344a7a108fce03": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd6b9c9d40ae9d4db6dcefa18167658c8c5afa1b": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cb86edbc8bbb1f9131022be649565ebdb09e32a1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397997dfab7fe0925ba6e6c1c9abcd20a840540095d": "0x002ca8141f0241000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928978fa87ec68adec6d13477e797f062562cbcdfb4b": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431b282f5fe4bd0bfda21a07f7184bfd720bcb0886": "0x0040f09bbce1080000000000000000008f4c5f0e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d00b9d35957bc6db556c4d0cb694c9b728b67b9694153087c7b67095bca47021a": "0x4a7a5c1f34c57b9d1e0993e83060b6736f6a42bd", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fcaf0a13a98b04a3080d7e246ffa7d072777e7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aea57f34d0f7c04bf6f29e4b91baf66955901035": "0x000c5849192401000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900746df19d71232f9e5acc79bffda2745b69b97c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700361b7e4eb1e3af12bd13b2403fdad70b822268": "0x0094e7521f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896c068858140829f7fddd7907bca518e6b97c7274": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5103d55b133773dbe948d6e3f71365f9bd5b020000": "0x4cfea3e89b8563274d1cdb191bd0d5de97de790821a6d41990f7671db2ae910800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9088903c35f715b176cc6dc581484cc306a7d643b0220f1386a31ca925c9a60d": "0x0ace3d849dcc2c1b7758b05cea344a7a108fce03", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a53e3fea0109124613c5ba34c1bb2a9dbec3d7": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f72a6e8a84e112b9fd925ad040b81bec8b17a6bb": "0x006ee223f3bf00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514323a3c01c36d94d37e6ca002f7d1ab1f8040000": "0xa03927f2c5ec70e2a6c64be18c91cc75a7a41e176579bc7d632d78e488265b0800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cb139d5b7f41d8b74b5a5027ca35e9ac8a7cda": "0x00b218f2c65f03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c5464af38cf465bee0a30d7ddccd900cc20ab9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1abaeefafe1ae6d3eb202f130440b7b2d3365279ce56def44f2610e56986ca0b": "0xf19ab8f5c20d77119dba61bc195214fdc045e680", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7addfa612b215eb31656bda9898be79259e308ab918ec8d61364fc1e872b47af": "0xfe265551142de05f83c1ae9bc54ee9bd1248f80b", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516adeb3a1d9a6caf3c272e13546c5c74638070000": "0x26171b3ad75723bf624a27485e51e4c2fe38f4b2d24ee52b86a979fb772c513b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf382c70d3bfe51f50fbb462568ed1ceafe02999": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ecb3531beae3a8d1c0827a8ce461025835feb8fb": "0x008a53f75d4f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a75898108ab84228adde0a8ede1434a593040000": "0xe043d8f7872cd895f8957c9179c4264816be3e649713cb3bdc523f752602cc3a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f265277da5c970ee569bbe6a2fb378ff40000000": "0x58049496de2baead8a7fef06cfcff07764d07d7d466c9d64a4982cb3ca32b85c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785591bfabb18be044fa98d72f7093469c588483c": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a1cac24ee6eb326f1640c5c97b8a2e260b4452aa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f28a4aeefb6f2d8b39298422ffd4a329fac161": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f409aba35fd318d2f06b820f80cdda3819f7a545": "0x002291b31b2d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d90a6b364317b9f367adeccb9432c3e8f8e1badf60cab29b241da813d1e64f413": "0x00ad5f21adf36e7fb8eb51391c3a68cf44de0ba3", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891b919a32ea4ba16c20e24ee83cbdf98b89c94a31": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d44681d99e5d8c26050428ee732f3e8c01ca7251be24c12ae7b99aa44126bb606": "0x27c6574264011276bb58654e48973380d5c20717", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339760f7905da2eef27ee2992082769b0c1c236c7395": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ffe3083861f58aa0101453a61fd3a1b747d2b75": "0x002e3f6ac61b00000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19507270f0d884b506b5617564698074b919094e1fca66ed767766aa0a91025b6a8b955bb970912900ad4e413ea936": "0x88ee494d719d68a18aade04903839ea37b6be99552ceceb530674b237afa9166", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d565518b05d731fc47de585ee3b3270c188bec481385e8abde5384c0d12dac97a": "0x00ddaad281bd203effd53340aab51fbcef400e9c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339743eca45f63a712ae079385f35e1d0622a2c4132f": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d59dac3bcb670d0ed0c737ab8f2560ce0e564e": "0x00f031b1450f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974185524e7b4ec8f909a435f4ac705f9348105b32": "0x0052f76b2f5f0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a1e09cd44050639a816fb6374da3baa1228ea4d": "0x00924866aa3700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c0c36cb561beb841efcfc7212710d0c7b1bb187": "0x00009573c24800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289190e7c0403a5dd4bd21d426d88b76b1d513d39b1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289726a0e3227f10b8967864ea8f7fba8b5637c192f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6a2e7a2d10fb2093f63f2f7923622b3f357f8a1": "0x00e0ec5e0b6400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f2293358c8721bb10cf8fef9fc9704189581ccb": "0x00c296aafdc10a000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b1c20535f3fc208f2b320157b65ea09e960496": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cecd25a7e218c0cdc8fd36c50d1369a691f56d90": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d603cbc4d841ffa9811ca096535fb43ec8e240f6c058fc98f2619c72a9fa9e31b": "0xb7ef6733ceb972d95d74368fe24b511512ae857f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b3d18c655353ca14fb9d4ba8d047d08d1140974": "0x0032468a9ae612000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5bd0f12144dde4c70b3a80bd8b0817cc1ae6593": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928905df79a1f08a459cd77ebbf6b3333da75dcb6141": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289589c431cb0e9255b1fe912079034ca6711c76eec": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5efad5aef39eadd6d70721079c222dcfd7a12faddd95169f5df916c45b4e7b3b": "0x46db544038c59b826dda8d3cc8b72de90c86e683", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5186a7064a1f4245274d2ae8b256160c22cf070000": "0x3e35d39ed1562e36efd2facd3fc6312c25241e8c665fbe0fef836b92224bb72e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339787e9e73dd37a9e2163a893462c2664121c9c5e31": "0x00dedce2d93f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890352804a070c4d94d441ceb8490ec619899f9e4d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce5b1c0387a6aee95bc73e296421663cebd676af55c12566479cc81dc83a5309": "0x00472a26baddb79f1149a9589a132e5e0f762253", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c616dcddb10148ef5351b5b0c272486d15b3f629": "0x00d0cfdc8cd700000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d520bb8772cb80655102c3c0395b92b8bbe820dcb8d8ef656bdc2f15cf2701c49": "0x00ece6fd032e4d674561246baffa8f92728955b6", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282434b58917b2b71399c841b985727a3ff7fb59547f1": "0x00605f3580ce0200000000000000000094a88a0400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db67d17f0067c5650930c4d4259ef7b5f7ee951af57f06cf6360b75b7a56e824e": "0xed825d6533c5220639bea97f98aeba7e02b0845f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa6dda94cd91f2160d9d7d091ef0c7230520810d": "0x00a42fcb056000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514472409cd7ef153b993db5226b2be2e33d060000": "0x14287358494932512dc188bb7700c1ae44f9b31e251d918a4f9301a11eb6d62f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5197a4f0d08d230dd6c944d8591bbbbf88d1060000": "0x7ab28f300e32aa503233448cb8b7ae963933abae546105ea1925172f28efab0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9ccea8905de715b2b260070927dfff763ee6d0ffbeb7afda26ddfb2f614fd200": "0x86716e7f1b8a4ab2d72262ec5e034ff995b684bc", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970088f742d8a320915da103114ff128fe472c7cff": "0x001c6ed5291c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974bd74d345c128f0a80bc711740d16cf3cce70de1": "0x008281e2607615000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dccbfb039ee654031cc916533ef1ce64e6b1422f": "0x00b05a73b81900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f7a28702a142caee8178da955f3bf87fdf449bf2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d74d422ddfaf5c928d04f719fe7f218e9de21d83f5fd0e7cf66fa20a3c2a72d2b": "0x09fbc09d7da0c050d4fd80db0649b30378cc4839", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282433a7dd8fc58ff94de5cede695988e78e5f3fb3df2": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d48c36a6ca9bc4cee5de809eb648c06c25900abb5bf37fa09b1e24435d4b96029": "0x94c90e0a573db26467e0e812090a9220c20edcd3", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d860ed6468ffbb2ccc21b5fabba90031f5f828c1fb44ec5d167f183a1afdd2f4c": "0xfe2d3714dc0abc2fed9f148be5ed1f224793f01d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978efb665b2cfd82983e06562b355878da59878368": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d559c543464fdea0ec1795669c96182180b559": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd0a28cd71e1b713dafa7168963102e068ee03c9921cc6ecaa91a6f3cfa5b0770": "0xfcfe4380a6592abb74ab7a3d270f87acaafe118d", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d92d2877d5408cb4596cbaaac36d35efd65a619b99487ba980f158f83904f0001": "0x00e955f59b4abc283f9d5813aed5666666f7476f", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243173ba35fbb37fd281880645a2e7f8e18ba38de0c": "0x0060b7986c880000000000000000000009c2dc0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b9ee82eb0c10e873760fc39cbae615d05dea7a": "0x00221e875a1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890d2b35b43c6ecd57e7f154ef5d5dffd0c73f8d4c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c53e4175affb6add29bedc688783c6dd9afc452": "0x00d422207f0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001c75e0c290be78b48b440123a7b9c9950cb4dc": "0x00449673730c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928931c1fdc59cea10ca6dec6975e83f3c2f5bc629cc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b4513bc7f383d9f27e8c9d2b16216328927f1669": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339713d62d5a1963046a3caccc3097a4576d1f9b42e1": "0x0074bccaa21b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b4294fc374566d487008f154cfb6701ae636196": "0x00ae3aede4ee00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005a2a05c903bb1491b9988dbcc67cd15c7f491d": "0x000c254e602000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748640126abdef6682ad0637024f814e3e40196b1": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8f150feb4983f36ab7bf83f0829c94a00471c1e": "0x0010a3fee5b4a8000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d63e4031c07cf74da563595cf55df4b52063a7ac": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751e9ebaa1d6b6029c88a42bdffe81ab4956cc062": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893bace2a685d8d73c3e60b84bbc34ab782f54100c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512ba96865eb101d5e044f7f86d61b2defdd070000": "0xc05210b4c8af29367ca9ecbde4992250204318d053a6cee2a99850ca05cfdb5e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891f928e604b981ca97463d9bbd06d84ebb5c87ef4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928904d83431115cc45d7e1fb79b4d64b5669238b687": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339742b1d63ebbc6ca0cc4a679fb341c78d1089702ea": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928930caa2e774035687e738e60ed754c1787b206a81": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979dd8ff7445db83b54311b53593c8cf23dae7ee9f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899887c59b42a14ad759d1abfdeb258dfd505a01db": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000abf987d6d132cd1477b2c9f1fca2ffc0a4375": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d76dec076c9a31c9b8493516198ad24f0e8f47969953cee5821e30c340f276519": "0x7a1e82a8554ccc29275f5cd010de3668578bbc9f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890084000ca2cf4517f4af097574805a518efcdbd0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928918ec44fb47a4014261d7617347773bf27b8e2e8d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d67c0d69691f9d012cf1fd44c5ac23c79cd441fc": "0x009868ab21f695000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000fb1553ecce5ad47b7a31dacde54f02d10896a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515299f9fabdbf760aa03c72ac7f505fe5f0060000": "0x804886d79ea6b1e21493730ae735f66b0789c48a6cbf3d0c3a6aa5eb7f47fc0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da0226b58094e54045005fe23c8a403e110a4eacfc8ccdcf6cb009c81c4f94447": "0x00cf14cb2a1582112f352b2853400b532891e6eb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339749818d5fe1387b70b4b7bf57a64f7c86bbd15ae2": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339777c6f7a1f67e4810c454d57f5972da4761f8079f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6475d23c468c6da8d92298d6edc33b5cbd3feadc6d637d207ff6ba64acd4b317": "0xd34e9fe863c26cfcecf82bf4cc18701b3ad4767f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397042a8622ec46cf242361e045250ba7687278f929": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7ed2d43538974c607917ddb8454f00f3cfe250b": "0x004e6d18efb400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d50ef6fb05f46fc0e58cca849698d21a330418e612d0e206ab19c6899245b8e6f": "0x1a0094af5e7a2d052f67814b9bbc799ad6ece294", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e8c721f9eea540a54837dcfd3fc7289307060000": "0x5025d1377cbba45a79dc41256dcb4e5dfa71c53ee3ae46352f2a20ac0f54232700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2c75b578ae2bfc003b5fca59f1e26630652005a07144bba9a75ed44a00fed751": "0xc77c440c06384717ad302a6c5290c9e8716f67c1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397392e05b27079b3502ef2937e0af15aac14e8d8e6": "0x00c43733034100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd86986ba67b4a1a8e7be4833dde2c09243333d7": "0x00eccc45eb0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339739274cc91485b4501445ba4c1a67b16e6a5fd78b": "0x001e39c7e9a600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a670e45ff53ae0febb60638c16459dbf87060000": "0x74f57b8c30f491524688bda45df9f49aeaf6b96b4c1a4aed06d777aaee60533800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a249e3666698c434db898a9ae29b64875638019": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928935edf1cce3d9c1775ff5e214dbfee26abec3fb3b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de6ba7360b9e07983d3503bd24e0ebd36b6bdf50a613785f994cb4964708c791e": "0xa0cf34d8a3dd4d379800bb440c1a3523cad4d9ea", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ea9d00813f1ba972a361ff2d3761d2a396fb2c": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51aceda49b20dbd77197925490fd185c1660030000": "0xbe43cf13f10c57748e61120df82c8bace4563984fb09e8823b24f7c6106da61f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d1f0e0febf66f337e5033bc9a8988c605b070000": "0x542ac2735e893007bb75a64c95a1658025f9d3c2f58c5af1c1060d87a43aaa5b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ee8ad6769fe89ecb8fee0d981ad709e08e6d1c06": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970003664d63acee3b899631c4ac4615f402430330": "0x00de0af1581922000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ad5f21adf36e7fb8eb51391c3a68cf44de0ba3": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899c8050f5ff8d448a5f3ac9e092f45f5ebb9df9de": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c6ae8a52978150c27cad4136308d4acf3bdee0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928948299f5998fbdc5898ac71e8221014a7124e0788": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bffcff3d2093925b8a99458b5d9e81dc8c0034": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891f8978b550c0291627d5604a84e76fc044c23fb5": "0x01", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824350d919314f2981bda224370b7165fde7bd733040": "0x0060b7986c880000000000000000000009c2dc0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708c58b2dcf43c4505526af8e5e067bc08d3d0175": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974999ba3e07e8446389fc80467cf6cba34ab2363b": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a07166eb5793a0f9d60a9adf056b7e4fdd2eda73": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb4576a033caf3ea0eb8a9545b26fef07ee78115": "0x003cb11cc30000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dfe4c9aa892384176066b2776c0507c17cbf5099": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289216ad8bd24f5f277b78774e605910e04016b6e78": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f01fb7123fd21b1428098e7684093babeb59b764": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928988b5c0f4c52ac62c66c1c4d009e6ae0f72f4d042": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896bfa1d111e63e47a3ee2daf430ff319aa7079fa5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890be9a01de08f7c18e973f073844aed6d8414a5e6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51adbbb9398ce25370fb0eb5af3db1b09c53080000": "0xa2f43a8179d71374a49f4151bae8d01dd1ca9cc85eaf135a23e8134ae32d4fe700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f18036a91dcfc6f8b39de68f170a683efbe0527": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aba13ff6c070ac900ca4e3861ef66045be42b37b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898da0a15786008f543a760701e2021f992e1c1cc5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e5db04802c56a6de7532a9aac9cf39c7a3bc7b71": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ab416fe30d58afe5d9454c7fce7f830bcc750356": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db0a08e27f26e1d8b3f3c61643df806c8b631a1fc8b34cbfeccd406a29e423c54": "0x027ed05be029f65a37ae646f349adafcc9758755", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397035c88dccea98eb443d506347b9f96044da9bcfc": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb431327705a1ee54417f8cf3146669ea52f3e41": "0x0068f8c974a501000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a9409db5aafca9b68f43dcf38bf46d460079cc3e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab3237736c07beddde7dfdc0f9357e00a9727646": "0x00dedce2d93f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b98bc9f8919ee39e563d1ce3c1aea8ff31ab0585": "0x0080a925ff8151010000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ac139d4ae0e405462f35f4a5f9238f39844cb982": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b41ad734f67cad3c933793be448dfad709060000": "0x1ea949d53645e094cc44db822ad4c0d779f9c9a3252c5bb85816696b75e04c0700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005325ce1235df371bf5e8671ba58f7bc2d549c1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397610449b5f52ba2fd6a5cba5c29d650d12248017b": "0x00542e2007ce00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a1f84545ff677fdb54d955f707055dc70f05452": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f91769506a288aa7edf21f0100444eec2c6f1033": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b98df46a871a544265c71648cb708525fd913ed8": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518f32bbee91fa86b4a3c11aa7774b86b4d8060000": "0xda04a11b64e7fc03f1d79937689c4d5cb4be50e9e459edd9217adcab52c3533200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000fb7f3c777a047c7730c8a4d5055d62355ebba": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397953bbf3ce4f4e15d76793c6d672f227993c4f3ec": "0x00d6fa032f0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009e98ad910f26769d6a0e2037aa4285820fc9b8": "0x007e22cded0d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a56106482594175c13790cc8fd6d99575fbe5154": "0x00924351a05100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fe740f05146eac00d2b48f2527eef1deac1e1c50": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a7a5c1f34c57b9d1e0993e83060b6736f6a42bd": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a0cf34d8a3dd4d379800bb440c1a3523cad4d9ea": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc0103c4b56ce752d05b16a88260e3a9e2c44306602a74c5edd1cd4ff56356f7c": "0xf6a2e7a2d10fb2093f63f2f7923622b3f357f8a1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b92a8aa0fc53b924467aceda1ac915abbd537be3": "0x0020c9e7070400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000fb1553ecce5ad47b7a31dacde54f02d10896a": "0x004e1d826b2608000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5da2d78dbc9d7a047ac8700a09f4fb50a23d8c3": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aeb41235f3375e4a0c3006882b6ae446a4818753": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973dbbbce710fc71eab5fd35c40743851ac5f08407": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d96fa67ee8a1c434d8efd13671fbb12ae29421c4c0e350e2fe93744caea8ad20b": "0xc46fbc59c8742b17c3f67fb39338046c1b3be969", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339791f2376856197b8bb33ee86f56d4a17da7298859": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd2d4d9f76f3919510de38109dd63172b05e86a6": "0x00cec8c6e89500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289df4dff459b93832e9bd6e0c32e5866126ecc434a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ac64a0c791cd0b6edb560c121fabfe6a23be2c43": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d067ad823d661ceda5e04f4f814589bc39a90bfb09660677296cdbff49049e83a": "0x003edcc4d34cd4a22b85b496aa33defee0ae5717", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896a0638fc950ad83956179d5584f8115b9f9e0cb4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e26ce35987459077ef8ab733663a231bc5040000": "0xd8bd9c7e5df52ce11d6370096388ebc0ce1d165fb610382be7f322f78eaef40100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004f42b803fbc2580a9cd18fc130caebea8651ee": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720af7b38515f4fcb71c988625bc3c35d510ba7b3": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289998c1f93bcdb6ff23c10d0dc924728b73be2ff9f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891d78010ae098d2ddfc01c7306f16776d1409a576": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8a8c0cdeb30b068e0e3aafe157189e0a93caaf6ff05961dd98d58db11e1e2731": "0xfa5b8e7942818890da1ab0b8ea9f79c6e912a758", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da082ef6765a3eef5cce291b2507c5ac3d6ffe5e10ecec2525d1554b8d2db1440": "0xcdffcefb552c1638915cefa56d551c4221e5d6d0", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895e0e7a5ca7fd2b638cb8e544d9188dfc38385db3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fe383db1da47144fb59082c47d97ffb1848d13": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51029389976abe4c8cc9e2ba88bb7a3b6398050000": "0xdecf71909282816105360e12c52694c8e39f30f82532be18b3e32e3e435dbf0800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d847ca879aa4ee4e774297222315e844f84e6b15f035b54a658be03a7166e9802": "0x38f438c88c8c43562c4ceb3c0d7b24e11c03b708", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890054ee21332017c772a9dcb68cc6e120b305c9ea": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a5b68dd85f2aff5bc60ece004f36879399c242": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d569ed842ea4694ae65819ed0ec5ccdc9ffc46e8e1986e8f41489926196a5c15b": "0x2fcef6913ba9d9ce25e509979180d5fd0e047b07", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970060ed7298f6492489442f555e38acd8c672edfd": "0x002ccfe5aa0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c330c1abd1fa488ffce0ddc6527afc4106f122bf": "0x007e15ac953900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514da93edcaf84b14ce2eb804174a3a71ce5040000": "0xf4164fa5fd5aa70d2d524d72d9e17d16a56946c3b9fa97d03d2aa2a05e25cf4e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971add1af6a3949b9613922f9dd9cc3c98d003d5fa": "0x004834a0a33f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339706eb856aeb8687f1803c095615b3e7143bf130c5": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df04861121b61c5f1251e345b3bdd173cd18a89e4641984c7f051d796e295e01d": "0x487bfea2ffcde43dc7cb20b5cf1f84c7c836e917", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971b22a64ea64c2f4cf1d6ae25c855db5fe1ca0e20": "0x001e5c373fda02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970012f59b4690aaaac5d4631d56f30e00383eb29c": "0x00fafc0f343c38000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f170d28a026ca70f9c4a011409cff2d195d0359b": "0x00202e585d3783000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51218d19ff794c68b9ffc65f2a631525f415000000": "0x20c9f5448d22044f25fdb213b6a5fa752b29b2cfb57380deede293c7dc3f326900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a50382a9b22b0720698d39131fcbe289841a54bd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397075c5fec47d39bd6482df2cfe32a6d1f83b722b8": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e2f7d96ae83b7967015b3c483a070239f74baa6b": "0x009a2bd5f92900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928973344288a3782ca4badf486ce54de2f6398d1271": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c8d6ee56d63c0ccc987b1bbce567834e4e3f312": "0x00901ec4bc1600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de02202417084cd61934725dceeeb213f4a3317e0380658dcd137cb3dcb4d972d": "0x87b1cfa38fc11bc6ba0794e44b8fd5cdf98c7640", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289749ba28f1a561b462e7617728bf8f62ce0afbbbc": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243e6c6c739e406cf3ccb1c666d24cfd200585faafe": "0x00a031a95fe3000000000000000000000eee6f0100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5164d8e242e4fdf69f1127693d8d3433991a040000": "0xac9699995e6091a616897cc7344af69d9ee2ab61aa33ffcd2d11cdb895a6f94400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a2f8347074e14f1e2eb5737f8b71dd2628060000": "0xc8fcab73fd1b77bf96980783858afad61a357214ab29114ced424a9a2d24834c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511738b9a4c28998ec6eab75ae354c079f08070000": "0xa87141729cc078f61473a1ad23b5b625b23d88c4329a1d4a7b4e9d22b0e2bb4000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df49313e8188843be3e2b454b00064aff16256196b535d4d511ab57207812714f": "0x4f1de81781e8bf83b57548a1ad3bad66a16c4e01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006b0c951ffdbd1e139bb4734001e5bb38590533": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764cea862ccb0395f7b0f2ad5bc63b0f299a56637": "0x00341a7e291900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f0650200d57ff9098164898d2231b2de220c99": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898b1f512edfd229d910efed5af91445aaebc8c7a1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289968ced1eadf5bbe3ec2f6c6e1911b8f4e43452a7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f19ab8f5c20d77119dba61bc195214fdc045e680": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ce2dcc3b6911ac513d32f326bb72bc44c1ca1b84": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5105cdf75484c2aa1eebce8744866c087913090000": "0xa2961c9a8ef0879e6f08c41d9a1957b7e5d7be02d2462557b1490609fdb5d02a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900328824a4fc0484c8ff3353c8d2f65ba9e05638": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511d9ab946129490be72947c90e4f9551d4f050000": "0xeaa58dc24089f8bf9d09ce5be1ae57d6f47213a94475761fd34f73e92a3db15a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d57d447ac2a9cde3401bba7abb6f888eb63ed7": "0x00a209940c5400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c9f778ebffa282838000bdab016dfa08f75dd445": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a2e5004a31e7b931bef05499dc4f3dca1b616b": "0x0048b4edbc3000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b986ff7069c7e6c8a4bb67419d839a8cd9d07d": "0x006e1f92990104000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db2098bb66a2346135b378a64c3de1d2bde6c4199cb7d805a970b4f6fe9deb375": "0x6a37135f77421be9d9e5c15284188e9658207dba", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971eb3162901545cb116b780f3456186b5d1396142": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a21429126894675cf6e76bdee44a18c6122c0ca": "0x00261a1f702600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b0d0571d39cf62dabc905c3892c32fa578defc2": "0x00d6b1f4573f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004935e21786073fabd32f21b6492ad354ad871e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fcf8700996507fefbcbe7258ff7f5af0abd5821d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d44a1336854e44cdbfa929ad12e913e4a1870c590a6dc5e3983a6fd416b927f53": "0x8e6fa447855eb59c62f23e3df8a556b07a0ee4d9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c0bb615eda6512f1a95869a638ef9d21e63469d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fb5b702b7d3c5efb00630e8014e79bfbbf5ef81": "0x0090f5e41d0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004a9d5ffc97eb0a4f20df642bedc5f7a848e2be": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a70be61eaf9073505bae64126b3048b3046edabc": "0x003e3ea46d0800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51198441c55321af69c172ea861733b5c674070000": "0x068f8efb41894171c5344bc16f74eb1dd05fad93647955140e0f7d7711d1d82c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ccf27ab564b31e8835ea23f48894d22b986382bae5889720c66225960dbd80a": "0x032f6b944721fd338858bcc0e323d9afe77e0a40", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971b1bd494502e19e60d13e635c6931fce893f7824": "0x007623119c4203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c7975fa3b0e1ecc47baad4596626aa2c1089524": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a045d6728561c3b5f1978c235e83331e4f9d54": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775f095e103de3ac2cd8410ed059fdd5bd050d21d": "0x00621698382500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005ba629a682cfc064d0f7e35710819889fa357b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007a74c0c90eb301c7355654b4c91fbcf267a1c6": "0x00c024e4b60101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b054ab94e535ea6808941b416fdc14255dec9d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b3e7a175f6183e2c8a32e94881d9cc24b96f4a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003f12ba2e37d864732ce8b000270b05fdb2a893": "0x0094f4d8444500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fbf27816ed8612ba4477bed6e0a554a1a35fb015": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5107d6ed276f6ca99d688cfffad58322e9a4000000": "0x163826c8ce7c0ae26db248337eab2cc31d575dd344859e51d13e8703666a124600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974fbf276d6fa1f36b0f0b12fe8182e4bd108ec9bb": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6eb77631f65ea04b3ef1407b04dd59a50ef6af249eba5d82cd61604076ab067a": "0xd7d53f3b0307de42d7dc018f672f7e6af34a8194", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a224725ea45e342d5f769ad16c4f7f19df7b1c39": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000e1841bd5780f77ebee2dd24a19cc47e1e47b2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895daf6d0f17ad397b6a50308bab72dba0a7a74249": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892969dcc4bbf824145328bca8860135f4cd9ce9a9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289805d90d33dcedad0f8efc6510dbb067fe4b36674": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51df54a4ca9017b31244856bb7e2307055b0060000": "0xd22abcdf4219140319a7f2155c838897e8df31bdcf7a5f59567ca06093e7825200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397532276374258365ec2058848caa8975da2e9dba8": "0x00540ec8632600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5176a23fe68fe8a3ffb03f1cf79dc1542ab8070000": "0xea93f58088e27ecf986ed4d70c4f4d40d726b390bcb87f448fcc35fc917e0d3200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f7269f2171f05759a8946831c2300720391320c": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890044603a9c1b3e99918dc373a07dcdfedf38bdca": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d2b403199705e292860c2978457aec9075b897": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e6ec101524276a692f4a4fd0a2f811060cd3d434": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890009e426649bbf47ae1816b30bce4d4bb3977259": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b409f5afa0274854823681114344484d69fc0f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c4d09effbea40dcbc56bbced8bd75c4bca2dc6": "0x001e39c7e9a600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517e0af9d7eb14d3efb109b8e53df1cc9719060000": "0xece2eb75309f0b344a924dd7a35febfe235f71bbb3ec4cf986a440342256ce4f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397652346bcbe5e8683ade954a0b4491a58809fb539": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ea0f4b12d694e26a89872bcb86213a8f6ae25c5": "0x003278ff3d1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895a64f00b89146c02ee1c879b22dcc661609a6fe3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397459e0021404e96b2cccf7ad0611c5ae87449704c": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339721b967d11709c5f62eccd737625effc14de873ea": "0x0020750b040b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bf2209a10d9ffda04bf453bcb3e367f3eb6756": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765e7c827ef5af55a5080f2589dbbd334e06dae9a": "0x001428b7820700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b1655ab727bc613b0cfbbfd2a8222a17955ed0cb": "0x0086319f582201000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d94134606e7f52b31b53c7b6c131e500b392182c05d76a729ae70c333052edf54": "0x0094e5350b60f62464c4006345eb31c2e731f6c9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5db04802c56a6de7532a9aac9cf39c7a3bc7b71": "0x00bcc1fbefef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d04b32df44ba1c02abfda2d4d9dd55b3fc4f0bee5b136b7eee836787771e02119": "0x001e0d294383d5b4136476648acc8d04a6461ae3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d409b74db75be650cc36e53192fdf7aaec35002": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000b79d6fea0f31e919301506d8c62c645949af0": "0x00", + "0x3a65787472696e7369635f696e646578": "0x00000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af302aa751058797c6ab5249cb83547a6357763a": "0x0040ee7affbf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890092dd784a50e356b9e1705dc780fcdcd55d78e7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397759e87db3f90e6dadd412213aa32140a8cf26ba1": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e238e274e49faaa50d80cefc0bd04d793f190d119a4ca4d05d6e5a9f951207a": "0x12f9122d6ca5294f6817ae79a9c4634a07931a85", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbe2daf84705de34c1930370f53566524b08145b4d192d6cdd5a35cc71930e240": "0x5b11453d090fc10f3645d14a2e2b1af79030b948", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970089d8cdbb9494f662738349c4d940cce6d95ff9": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778f5234552ba1bac0a945d5e5bdfb56d84d4931a": "0x0020e464717e15000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890084125bebeaa11df85ac05d8da15c2ad150e814": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894ae4f357871171a3c3e10586ff545acd8e165618": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397afe949978ae2f7098f9b5c2338ed5de20ffdfff9": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928968a85a879380543b48c40d0620e0681300a88553": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dccdab8025bb63660540679cce9993fbbfa4a0d0c7ad4704d7d0a04e4be9c6b26": "0xdd9c6de73ea0b65c5aba8bbd3a3a9a212be3b93c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928970f055cd7b671c7d5f167c93b506f30ee46c9938": "0x01", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8c17e962f910139d0710b3037a7fd7929e6da7912de43fcf8c5dde90c94bbf6c": "0xb3868d1aeb675f1fe97eae0da557f9fceff37afa", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b8cc90051abd0b9b33bd17121b899bb7a9d796e": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289765fdcbaa945c2f73dae083770dd0aedfa386d5a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bc12728eae828a7eb29d712c04ae95e3dfeaf32e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891dc59612f191c66e69dc23f3ab00b945593836e9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002bd178dc5ec5ae344d367d4a97281f63736d7b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e6c6c739e406cf3ccb1c666d24cfd200585faafe": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950186cf6cff105370f696d6f6e806c694dbad86b8de9c1c9947e536b3391b77caaca86a23195a2b111b24b0d5164": "0x88ee494d719d68a18aade04903839ea37b6be99552ceceb530674b237afa9166", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978c01e3c81c99db5918e079c5198282c29b773020": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896ddce5e113d3d358257a4130d8f2eef6008dceec": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970067be6b1747f53e8c03246205773f4622b858db": "0x0044135e7e6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e9b7c3ff2bcf46973579131465d2bb4dc46871": "0x0086df824a5400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f7e7b1b52725e1f32729d3a2c521a5f76c98df": "0x00600d64ce0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd9ebcb7c6bcf472a69a1c7a84735942859d3ace": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397febbc884e93912a472969e7da085eba33f526ffe": "0x00881b5b9a2f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51469895bc1302c720fb0bd6cca953955d60000000": "0xe49eb00a5f8632db3e45b24a7824605c7c7cdf4abcd9b17fe39ab29da4b7733900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a02c4b206630fe17cf7657ea80f1b6fab809da": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aba3761ab14f87094b3ec4bec2b49477e65f9bc0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5185aa0247372be67beef006c1f89f76a80f010000": "0x16293cb2df2f2416193f757871510572f7afddc8d958832689ef456c1096b12f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eb4a41fcb2d83f3cef61737e96467e5045729670": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928914ba180622dcd7ff90ca091fae20ffc0dc847100": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c70d550d680ec50b87d53cd1b0ed8e71d9040000": "0x5057dbc6c810eddf1e13d94305854ab72621bbe9566b117f69e705bdbaa9143d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d74d34e1eaa0a764af6084ef3728d63362298575d5efa077a8586333452960222": "0x003febedc03910f869564187f04c2ef1ab840fa6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a59c51409b63f4900cc5c90374036d3a98f7673b": "0x00d0c2bb340301000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893ab2aaa53121d617f02e48c6e8ac908c4467a5dd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000fa4aa94334c36300b16254889a721a01d6cbb": "0x00a234c7d60300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b28bdfb808ed2c7df779664ebbf541b0abde08": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3c51c73ed08d30afc617d04819231224ee4904e048ab132be6823cf419b6e003": "0x9a1329847393a87ad4c25bb21ff093e1d4d050b3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767c5eb8059d9dbb1319f71dbe45952871e59d845": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289453d0ee5abb40b1c632506cd5ac93ea8933cf33e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ac4ded60d7ec4175bcc13f8290f946c612090000": "0x62ba968eea9ac1fb02e752328be8c273e0374396051cd47dc602a6ff0145304b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ae34487911e04d149472ff9819d3c0fcf84249": "0x0094bcba878500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397839c073864b9958f0aa84446302d41712b1993f8": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a09493ecfecb6c710157bba28443bf28bed792af": "0x005ac97c261100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcd8d9d843b3a5558a914eb74b0ee05e7da49f59": "0x0058823c772100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700004c5c68de80a76948dfcf7a77045af476d346": "0x00d479824c3c38000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890016cd03db08cffafe5afd43d9cc903856a042f3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890072d5c92b77a0ca227964a4dfb304acadc78a05": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518c35ec3cfd9571b28ab2f416df6193dd23040000": "0xbe6c22b41a47d782268a2d1eecf5e623ae6b984591db92f77de07a27a447f87c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fe2716ed876e1a4243333758d547131a98490a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d67346067f88f10855b3580e8230dac8650116e4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003813a962efb1a03191600aa682d38b08d953cf": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978036c27fab2691804b28b9f47239e64c15e249bf": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928909a89f6468aecaffae52142487eac08e126bc071": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2a85f847dd5d86132513b8e5db91d5a05d15d615c121ebcda24f09e496a73901": "0x008211ed672526f479a537039766a8d8daf809f7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004aa70bdd021cf9aaae7e33feb7efb057255266": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781a1929517b52ccb71a63d31774bef3efa6d080e": "0x00f2ce1a272f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c45559a7a79bd667e9dcbd6dfdbf09ae8ba497f": "0x00e0ef26e71200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d109a7113c1d9b145d8af5be42af278d4eb46caaed127c698070b1302fcc4c80c": "0x1ad661fe9878af3b77754710f50981c82549bda8", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516701f038295e7c6414ec2f343ea330a3b6000000": "0x78fd3865bb8c8a833369aea5b5014df0d9e860a390391250f367fbe5771a2b4900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972576f5ef8309dbb23c39be29d62273b4c917d783": "0x0088110e954c03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289173216d1fd08e76fd4f25710d2849091ce2fb026": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c8e15c38714d27525ea5dcc9bb1e622f04fd04": "0x00589ab7343401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397feeb1670e956f2d17025c2e80ba377eac074625f": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d66d0e8a978133b248e0d8f228c1040af8f7152f366a2b6543349b2555f21141f": "0xe35219d98bf6f9c693bf04197070d79d9ba73bfc", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289196fd44f1f3f36458e9c36324640a8e7ff5fabfe": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5146b9e0027f6fee3677e154a454060dfb68010000": "0x4a009890abc59e1a2fe19b17d72028fc7049052704ad807f463ad1a7a95cba0b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51314c8210c5da410ec73c5d4a07e06fcae9050000": "0x8e2899d61a0734001d791a641f8965228ab1e60b4021750beeeca6194d10c36d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa41228830918cc1cf16e50df86ba154a483d77ebe3182bacfb876af4fe9ff6b": "0x542055cba6dc03f704e613894cc1d5bfdd74dbe0", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893b7a90105bf9acbcdc3b5219c1b55bc38397cec5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab94b48bb0eb0f1f9d4f3a66302af5c1406c195d": "0x000038e5be87aa000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976813622de314f3d0f3fa46717374e12a7bf6ffac": "0x00d0841bbabb00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d98a8cd51a12a19dd5440fde5e43cb50f9d48d95ea5c5ee3618eb0b2945f02f21": "0x9e538fc87abe6b95622e5af0d60906350fbe2280", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005d79be124e0852482eea03f11c3ce1eab68805": "0x00f0caaee75c06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ab6a08ca44645fca5b8a50ddfb04a8f9477923": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970540049071c933a260a422784626b2b894823952": "0x00e4d5530b1e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cdffcefb552c1638915cefa56d551c4221e5d6d0": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5170a3b8cf88cd085e117fbdd78220e23d49050000": "0x12e4fa92d67dc73b2ae4a7eab1451467be74b56b03d7892cd31f10ba3991474a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000fa4aa94334c36300b16254889a721a01d6cbb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e367a73ab3fb5ecfbcb4b118bf57538d1d4a77": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928927c6574264011276bb58654e48973380d5c20717": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b7e97b5534c07fe5d20ae838dfa7a830d5080000": "0x56216e1ef2e122893b8f8057ba5af16febc4e7f977ae6d7148bebb5de8eb316800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928927f3ee1c40ec45fda74a1f7c1bf36a66864a2376": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ca3e84bdb1a6d3e68fd572699737d203ffc66ea": "0x00d0d6a3921201000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1a8ff8f05a8d95a40db07204752c60359d031ad01e2618e2a5a33b63823d2b1f": "0x9e420616cf7f23f48fd442e11cbb1f36e37546f1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339777c56ecfc21bf4bc66adae4898224b07a81b4efa": "0x00909e76a32500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896fbb52a0c06818f7022fcabb7b815f86cfc1eeda": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339731b68bed40ea6d8608779acf8c61a453e264e253": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d122783b8ec70bada6ca07f33b05109f4d70c1310ec34d168ae5a93c76fa81d2d": "0x219a0751553ba999f730fc1af78bb5a3f255670b", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518b85718a9326ea3664423d84fba5e501f1080000": "0x94b6b94508e6afc5a85d01a5cf4a5bc7db6953981d36ca03d82c851d7964837200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b1c20535f3fc208f2b320157b65ea09e960496": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971739e6e25e3da9107b7f60145dd2c8cbb76fc139": "0x00341a7e291900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb4a41fcb2d83f3cef61737e96467e5045729670": "0x003ab9a30d2400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890076df9bcdb37939908f00f66c2d3d83b98345a0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff3592363b611cd701ccfa565dff6d1de23dfb2e": "0x00a031a95fe300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750d919314f2981bda224370b7165fde7bd733040": "0x0060b7986c8800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243354b2ae0cce6f0ed8f332f123d4367bb800ac687": "0x00c0afd69136000000000000000000009d4d580000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d107210db50634b820ed2323b16a861a2980dc828cd432458a37efcf0efc33904": "0x62431669ffdeeafb1d3b071ceebe443011b8d6ab", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d34285c047d5d8757551baa45e471e62e72f468": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282432a61258bf9cb93b77da65701e212c4f1653abf9c": "0x0020400cf641010000000000000000001ffd080200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282433ba7149b3bc64c6f805d02017a0d71e89362de64": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009957a264dfab5c3c7c572c1a4ceb8d1e1ad779": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339745271d8057632813229ef2eeb585a3024d6ce876": "0x00c82b5afd4a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339754f37dc277ea0ae185cc45886365f99889a9168d": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f9b5d3eb2fc3b978cb71beb0fc309bf7f5070000": "0xd65ce74d64b974f226eb2437a7ef2d13b5c240d1de9d3432186358f4f6f8216300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cbbedda51e4c9cfe80f429f6436a53c9738b59db": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51917de97e51f2c37f26736325a5b7185984070000": "0x8eddba03a0f2ddba21aab778f772c14bc6f1999fc1f5e25fcb2a7ea0da24055d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895d8e2e6b9118484134a1925813e545b37cb89102": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d88b4bf092b2dcc6e904f78261e8e40a9bd99f108b4b607ae2b9940cb6bef2e0e": "0x75485be7dc5d7e1218052accd222e75d4484df1c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004e3b44cad5fb1b7f0e23aecb9564e183a51fc0": "0x00624c25681301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5d005e57310e4c5f148be7ba4dd666db6884c36": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f09452094039cebf83165008759d201e7176d2d3": "0x0012fd6a7f1500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824343a125a9461625e72cf17558f1c8b3b653347686": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2ca94b3c294fed7e144817ec4682fd72039057462bb94de1076d6990039c8627": "0x7009eb50d01c3aa66f09ed1b9d675c6edbe392b8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700600ea2eca09b387d5be17a4a7df47d956e1ec4": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d3e9d9cc92f6c3802baa4c0e2f3bde6c3c37c75": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892dbdb05d09c9e0f10446881b9be2e107f91f7e41": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7cc77c4360b1e179bcea17c296e799401504ff28dc6db9840adcafa1b0cb0a4b": "0x7f2981e8a482c36f074440101c3a1007de7048cc", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289861bdc02d79dd2598d829fcba91e11f1d26b0aa0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51752ee5209532e0aa6b5f137472e0d6d7b7050000": "0xce46eb5500a059797f47cf38f119ecb0eeb360b856f67fcb7a74e98f52b8415700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971732d95532f10ae18b2317ee75d4ab0981369f37": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ed8bda7a810d594f145079dfb46849d8ae35c716": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ebd8cdafc1e22b03b2b6975ae4c4b5c174000000": "0xd650c3670b5cd26153d23688b773c926ac3188fde5961ee0a6b3d4ebc7cd900f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5177bc9cbaca6083a380cd81fb7971c80f96080000": "0x860ed6468ffbb2ccc21b5fabba90031f5f828c1fb44ec5d167f183a1afdd2f4c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518cf252f9f343d0a2482eb5e18e19e4d09d050000": "0x4c5ba8bcd28ecb0062f3c8ccfc909982c23ac3d0233756fcc5ba5e88e752aa4a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aa884c81b7b5f4b675e2e041826394e8f0b16bbe": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ad5c6ec30473c916e39a4098f252d8f2561eb975": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971394c491173702c7bf42b7320853fe4ba3630d9b": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a930215be931d1729ed9b5b3919097182b6923ff": "0x00ca91bb010500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c0b6a53433a49d2d9aa4817570b9ccfef4764cec": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5197ec3677d90a77d8db76e117602844568c060000": "0x9e03aeab23bd20a06fab8fc6b81589d02a4086b57262233b345b61859909167c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5199fd11234e74fb8de5fa27845c1b180844060000": "0x7cb80242c9f91aa58a2a5b8565bd270aca1fe2d83339e83f90b5de02cc2c8b1600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db62858778eee786f221c566984853d9ecd56c03238b3618aa982546de7abda2e": "0x00bbdb18494bba1635fc00d53735c06eeb171908", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e955f59b4abc283f9d5813aed5666666f7476f": "0x00d26a9b6f0d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a490262c85d993e3318fd0bdf26bf6ff5c470bf": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397729184154b516f6caafdc8ef2826809669a6e082": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a79d6c7ad0312485e375127d0844a4658b220fb3": "0x00f40062128d04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c43b0c4013131b17eccdcef96e6c873a21c3d087": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900692c9b1e40a8eb213880ac4908eb8cfaf1f598": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928955b3230118d3952b35b7965b09752dd299a95706": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f94a56eb52dc8ed546f5e737db99958f35090000": "0x0453de8b68a795494ce1ce969819ede9bf795d7e1b389de4f5b01b6fe111840400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243824432f160f254ca59fafad843a74ecb32d3a4fd": "0x0080c6a47e8d0300000000000000000039b8bf0500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51438e83a610a73fa9a7f3794357cf3cbea9050000": "0xb036f284468b4fb6b3d48f86280cb806fc36713edd255d195504d1f32607af2600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f91769506a288aa7edf21f0100444eec2c6f1033": "0x00f28802947000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5130d106f1fbacdd3cb14a7b0fd682e79eef050000": "0x04901365ee56151d864164012b6e08c412f3bff9ba22fcef3dada1e49efc2a0c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b4b2611b6a9433aa098aa0a026a1d99037710f66": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e666339d61a192d437f96ad1e40f197d547187c8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f6a3ad2ff813cdb72fbf4a76d6a9a7bd276f732e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339758445ba5cb35d9d4513df77f8ef3ccc8d608045d": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003d4fcad4255d3f37dd02df6b961b352298a023": "0x00301a45ba2900000000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bbb49b1ffed08d3f79a352f1a0f149d88722fd2": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da2062f4049a118f70b5f523c45f2d637d73a43f73a80949c0c35fc9856043932": "0x4d9354ef22423d1d544a01a2fd8b2ac03af0aa0e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928960256530d074465406df460b6f38424ab5df6bed": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892d7b42e27e2382e2d28e06bde9d82413906c6c03": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007b2f1e74f2d7a146dc352b987b44bb49d0d6ab": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970021381df55f5e10059831b97653c52d42a1e137": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397341ad4e79cb95c9c556e0bf96863d78a182d08f1": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ced37101dd628249ce535dbb34c9958fc0080000": "0x5e21f84db1d346670f5ae35b49fb1ed8ce2d6019ec1591f1a0a593c7e1e42f0300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511b99dbc819bfe468a0418320f3f57eac4d050000": "0xa621946a1439a0a376cca02fe2883fad7aee68a4b93938ba4089a75bb9d60e5b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339756feea6b7563f20c2d2dbba65afe424fa39e68b5": "0x00f65e1e190a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a65b40f6e9bd80597482769f6bf1e09d49a5634": "0x009e65b9ad8307000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517b53d01891a919f8cecc8bcbcdfa92c1e5050000": "0xd46f947c425657f5c458d5718cf796b1b6b5c4606da1eab11a2e3b14a50baf2a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51acddaa9e78f4aeeca811f6eb309765c086050000": "0x94c9b57fce4ae83da1b01355bba84a76f5cd8bb7b79cb177085798ea538cd91a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cfcfb4fa0e64528b2c5c8c42e7d46118ae142d92": "0x003c728ed34d01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5109abfdc40187ad848f25a8ba60ab89da36060000": "0xa2341ada39b90cbfffeabc35096269f14b5de2e50446e16ac26d8b02a026394900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf79ded61f78515c23a76e625039bedd77c50aaa": "0x00aac947aa0d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890225bf3928801e04bffc49fa57329c999a3bbc41": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928950723761bed6eebd4ad8cd418b0b262a66fc0b97": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a71f095a32e886f926f17c350b1dba021d00d50b": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195034dd778889665a6562616265806c52d02d95c30aa567fda284acf25025ca7470f0b0c516ddf94475a1807c4d25": "0xe240d12c7ad07bb0e7785ee6837095ddeebb7aef84d6ed7ea87da197805b343a", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282436a8d70c0692ce44b04c5ce0a7e77bcc6a0490766": "0x00a031a95fe3000000000000000000000eee6f0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001bdd794e80b596665dfed06d2876eedfe4f1ec": "0x006cfad2dc649c010000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896245b5b0af5cb4eb4742f118eb76312b17acb807": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b69412672ab0f9a1e43b9d57f996f7231320e2cb": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928955c6c9d943a08b9e39e0ea27c50f0f6b16898f92": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891b1bd494502e19e60d13e635c6931fce893f7824": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c301610a4ec130d407fdf49bc4cc94f89b316d17": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5104b536ae130ba7a050ae5a4c6c5f7cb059040000": "0xcb97a0426ba454b11a314f7c9d9479cb519eb93f8c79032abbede30932d67da500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970078c6117d6a926565915465f81e685c29e31f5f": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c00e0743d704094b1d198076a33a33487e2d38c": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d3aa3b4ebd357d5ebde65ce8ac9b4d99ac2b125": "0x001442866bbc00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897ba739859643cd795fdf204bdcc4236fa6ce04ee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b3868d1aeb675f1fe97eae0da557f9fceff37afa": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51de1f3d7406b40b58c679920c66e79a6eae050000": "0x9a7d372d156a9cf5315d828bdb0ee0b983253242f676e5760b1eb32b6fbc567c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928922a5afcec732df9e65eb56c0ca7fab1c3c26e7d3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009d14e5ef0bdaae60db17775e772dcd9e6130c6": "0x00f031b1450f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970067fe87b5fbabca1cbf1971d25f26162cb2d060": "0x002cb5d95f1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b8577dadcf48e02e17c649edf5185844dd2df05c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f4ecba233c28d3b5334c7c1c1d1d0e2b1ffc71": "0x00646ce1a00200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce28f4350076be8555df352a48c0e9451f6cde0d": "0x00ea2314e21e0f000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289deda0b6b9c98ac5ea010fe9f2086e93bc1514ec7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e594def1a782c9f0bd4f6e5ad16cee01e380f3": "0x0010b4426f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c17b6f24cf566e25bb33302da671b658577c1373": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d04f8e9018e5d7471067ed148c3c91f980b6f713f6d921104bd17b33917a63366": "0xf4f8d0377b14301ea3778fc39552b421b586f7e4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e6f13f5f9c2a098a1b0e02774f73b16f93ed892f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bffcff3d2093925b8a99458b5d9e81dc8c0034": "0x0014e8e34aa101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d4b9143dddb89e914b180b3cd9e55bcd74f7c9a": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282432ed99752dabb3138a911c2b71c9a80c7fc917614": "0x00a02488070f010000000000000000008c92b60100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970003ec6a173a7f45631ca5d96bb5b0a3ecccb5da": "0x008234c2fa5801000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970041910d9e4c61fdd7759a2d317ab892cfd80ec4": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c016f534d20ebfbe4acdec6977762f79317e137e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891d65fe9687372da1184e62ab01638d3949124565": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b13a2ca9b77ef417c02164de32e7a1b34e523d5a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ea6ff3e232c357928eebb2a6548c2efcdb4c6e14d3bff63f4641ff5d874764a": "0x8134fae7112d109c4dd3a1f09aac75f2372cdf0b", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5e160a7580ca586ea01814a9fcb95f99470a814bee39a7adb651cccfef60b423": "0x5a41d48673da40f5343bc1e871eb360ad8b9bdff", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970074bac45b84b3067a8a8d7044396275532d72a5": "0x00f213b10f0b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005056c4cc0929d2eafdfa995455e68427137dec": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ba325bdfa51320407c91f0323c303ac8a01cd7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ce28f4350076be8555df352a48c0e9451f6cde0d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289042a8622ec46cf242361e045250ba7687278f929": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970044208bb3e0d5b0dd69cff4eb36acdeb986c189": "0x0024858b773000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898ce53c77f34472605558eff3805538aa77b08f10": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b67a2bfea6579b273cfa427637adf9fab925f68a": "0x0010dcdcc56600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700120c2c12a1b40077200b7122aac76068b49490": "0x00ae41ce5b4203000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddec5caa60a55f5abd1f1aca49f2670591b5709d2d9e94fcebc1e5aaad92a405f": "0xa99e74d6616ae317cbeef70401baef1383d287a3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339715b8f1a95061a20392e601bb5bb008415ba20ca6": "0x00ced1754fea00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970069b8480fc4275a0bc10a317a8687deb83ba972": "0x0078ca2c506300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000d31e57b61e464c0241eeb74d9e6ef8f9ebe09": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d62b0506e832a39e504dd59605b37bc2aa7c243fd8f4e15687c85ca5b5737fb6b": "0xf786d0aca37d4965c2929cacee16ad42d7cf9bab", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d908f80aba091f8eb3135e7876d51b5b1a7bb188": "0x002691e58db100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511936b87ea893d4e38cfd6c4d9bec038780050000": "0x0c0235079df3f9a6b9a431e0c3bf0e20d673ccb362376937b9e5e423a307fa7900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f54663c66d90010e39c7c5f3124b2965e5f0d069": "0x006ee223f3bf00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51940964f22ff1e3b72438f62acf874e4c3d080000": "0x18bf39c2dac34143e07106240352c660e6cf571c4629a77a7751cdc20371e16100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ffd011cc6737e113dc8ba4b2cc294e656e9d8f00": "0x00aa63d0763c00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5164d2a59074309cb96661d6ef4762abbf7c060000": "0xa232ea049b0cffb350f95dfb094959d721a7c331f0fc8c976539fe521fc8044000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517c2cfd55456e03138079a1e3c9d10d8e12070000": "0x80bab9bae5457b9bd180ac52e9d067e4c3a365d114948187d991825c6914c30700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007924aa5e2abb7a230caa625cc0f073f0ca61f4": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ddef1f2b6433c7dd4d7012090f5049bbe4c0dc": "0x00ba9d84ec0e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5fa99dbaae82b30e809eeccbfe8bcbe0e83f241": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dfe344098825e1ac854d356926e44f303b7d08f2": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289afd6e8fdc9e0f3579e0b51f4af2587141b34ae18": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f170d28a026ca70f9c4a011409cff2d195d0359b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397121231fa85c0453947732b1e902dfafa04c71563": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d60b99a3e1fee8d744f08290a2ade61b26e044862efb7ca60dc0c944ef9d9aa7a": "0x810cff23a588aadac06cd93b443a12fa3a78affc", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970387d965a607009b865652830e675a2ad5c734a5": "0x0080c6a47e8d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d70001bb5611ed06bc17a2d36520bc84621baca6e76448ef632aec450edb0c971": "0xc923b032f3c9641cfcbc6a909fb66b29faa5449e", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243f01fb7123fd21b1428098e7684093babeb59b764": "0x0080c6a47e8d0300000000000000000039b8bf0500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ad5c481bec025207fa766ae91c8c80dbc2040000": "0x7cf315eb88caf2dcbfdd1161ce790d7293fae62990145fce1213fa4555f4bb5500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895641519cc28def80d631baa28b949f17a6a22ad1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e552266e3743f056350f50ea341a60ecc8080000": "0xc8855e85e66cf69a1652147e4f0f29ff9c32eb0bb2bf5ca462f4f7d022938c6900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824318ad26cf42a6d886352e9337ba7d2e1fa7302c8f": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a5e5e5f1350b92dd9bedcb9b840032fc728dac": "0x005cd94131a700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702d0f868a0467b7eedf6b252c6a7e53ea90b13b6": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fc4bf2d98b12ab9b121713eafd468e3d1dd1338d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928944e45fb5b5bd8e1bf9d1310b761571e73fb02924": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928940f0e17c0e8d725e985840198edda545fc3a7162": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282436dcbf212a83175dff095fea2d226aca22a93d643": "0x00407a10f35a00000000000000000000062c930000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dacf1956d8f6e2af1d9d1c895a4388a2985a10d99a573be37abf16c86fe5da360": "0xa6497fc08fc439fd02e6cba9782717b3b1d123bd", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db86e3fde6516ff1915abd6839a50460ad9e44ef24942d7cc88688de5bbb5ae2a": "0x8e10e1d033589ab6ff05a410ec742434858d3f4e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7e6b597b7c166901e03ec2d436ab4de5185b7ad1a59795b90cc403612e17b273": "0x001ed2471e25c381b3c24895fceb399dbb4f319d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928919200c712302c7c8421ca893d95bd985c8586007": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002408a2f9bbf1fee7a53eb361f8eb2ce47aa6af": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976174a3a6ae9bafb6aea1b87fcdaba0bcbeda4ecf": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d06fbacf43d7ff4e047983220c1b73b914ad77f93a4d73789c73930b2ba6de643": "0xcfd2bd2a86152bf48b1cb9ab2e52c19d5717fa86", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001adb13591f0a8ac80d152b8902b0a9e66aa599": "0x00448fb25b5910000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7073fdfd03fb9aa8f6153812c21f0a9eb2a14862c76bc8f17fe026c64e3f7369": "0x719819815ba8d64ed7712c3005c8df49b2085368", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d42a0955465512b8f6e3afa33bad2036803c4786825097a6a7b81f289bd1c5201": "0xb03d651170ceee35729aff792d522fd952cf94c0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004af69a0c1ef595d06cdd6fa458165efeb0fa8c": "0x00acc822980700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004c19d0274828f463ee886328a9c797ea9185da": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003087fb385b37b81d76ace33b535fbe1568d19a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dac2f0e3d8c2bec6c5f11f6f5e99adb3e9f3b6ae": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978049419a99016123ed264ca39436a91c35c7fe2a": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c05dec4d0797b45e7f6e036155261cb1cbb5cb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928971375e5bf468a9461b1b49e25dfc97440b0f277e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ce7ed9f16f6ae3a25599f03d4f65f8d3bd7664ba": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fea35be9327aca7beffc93d2b0cfea5d291f7d13": "0x00f00f84b5fb01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397803abe2c97e98816ef63a7b039bb59aa8a380909": "0x00c4c57af23000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928950ef20ae1ec6ca0229f4a3195401f1256985bfea": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a3cfef97dad26bf0e3f7152edb74b84a278c123b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928941df190f54ac5d369149a92583cfc240154fa8f6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511724f8608fbac57d80eba25efa7287e5f9030000": "0x5cc332716801e8f3a44b124dafbea4f22f4d3b9316d81e16815bf60c1fad095a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5132bf5188ca660aa47a1f9e87c25062b22d040000": "0xda1032f908449065d9512274e07fa2bc8311658a89e10ebb2b93d4d442c3ce2900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f8d8980d3863730a67fd6d320a5f131fff040000": "0x067ad823d661ceda5e04f4f814589bc39a90bfb09660677296cdbff49049e83a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f6b2de83758ce1339fff86482f305172d2020000": "0xf67048f1edb9b4c247c24e8b69219024581aa0d3aa509fbf8567199e2acf247a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515233b5763e4195a8c9de72dbb40dee5523010000": "0xd639c3f23f8d6d929550409f25e95d7b02e50a236ddb0e2c61c0022c04cd2c2500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d822fcb603c9ef8a930dc0cfceb1247f746637c9429bf78c5d97af940c580b42c": "0x008e158b389d89e9f98ab781725f34f5d06e7ed0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a55e8d42c5212d555acc4c1756744ab91530dbad": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d80fa64d542fe68bc290ee68b8b71c568b1338488430d5fcc67a4b5bae97b370e": "0xa95e38a8dc50337aed200378a46bfd23d33232f5", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfa74a5a45fd63ee5693a96ac0e371fe7559fd8e9895321bc7761e1cbcd73a322": "0x7ad41e9d6e1fa47f1f6bcc63bd0327009590a47b", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512e1ff1bb6ac6300c5d2503ca02c1837fa3080000": "0xb48db47e2db5323dbfc4ad1fd358f731424b27a1d3a323eeb57702bf51589c1e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700472a26baddb79f1149a9589a132e5e0f762253": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a99757c8c2bdacdb8c1470ed761d375f962184bf": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6c0c85366f11498dd656da6e5b05bb8eabf1c82": "0x006c95538c7201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d31748110020cb554ef2d73be9dd33892ce435": "0x0004f52ee08d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008ad6dca0f98838668c5a336ebc4f72e2872e30": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003e922b9535ab92618c64fcb7e08320a8e5c3f0": "0x0028bb1bb14901000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d26171b3ad75723bf624a27485e51e4c2fe38f4b2d24ee52b86a979fb772c513b": "0x0044208bb3e0d5b0dd69cff4eb36acdeb986c189", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f2fdfdb7945f770436d1f41c01b47fb76313a39": "0x004ec3481e5000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900da40c72ba0f9b64145964396c15ccc71cf7766": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ec9465777aa326e36b60abfb4a01298a7f51845d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c98707ab918996655722ae43be493b42b1060000": "0x1489a65848401b2fca29f84ca8041af9ec1e8bc08d79469d95554d9c59cbc65900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c5a77d735f01aab53e4ff89ccc60d503db7c3b": "0x00e80f27ce5d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f29c684feb0dd39f45960bbc4becc9f776be4ef2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbadd8927d3b3276bf4691aaea34e7b5cc8c1afea864578263fd57abc6ded4d45": "0xe3110f4e11c5b4efd2ea579663b23907c98e13f9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750ef20ae1ec6ca0229f4a3195401f1256985bfea": "0x00009573c24800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fa93a39e60a804ed41e1bdfd38badd4197e6a977": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928971b183dc5834b02237e996efed6933c104bc9292": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de04ccd02a8675ac3bd0af1ed88f893c33cdd541cf71562b00a8bec1db6d17d44": "0x669b996dfbf62da2ddf0c9ceeac503b920671639", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f77fd2297cb28b7a104f3f4d47b19a50a1ddd451": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcee069cef47b4e49b0d253fc46ac96f191cba7ca32e138122d6771e986c5ae1e": "0x173216d1fd08e76fd4f25710d2849091ce2fb026", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003febedc03910f869564187f04c2ef1ab840fa6": "0x009cc0f3713341000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f15c8b4ab29548dc9c1461c6b88a4d4cc9040000": "0x1894d7a0d8c769f8ce8973709a4215e91f895430fa64a5bbd42c73eb429f3f1d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d05ccdd7d7481f71eef6aeb4e0527ad47753272": "0x00e229e1701000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b68bbc3e20ee753a024a480dea125bb69262abb4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971213c5f7d2cfc86eb87f0bc54e0418009ac46f99": "0x006aedf4123200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518d87952c78388aa1a73610cb0cc3b694dd040000": "0x1baa453966c043ca367ccfa19f450244447b9d32f4b7af2d9749e55a57ac09cc00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339766e369a3a9c3678e3e4d05ef6a9886181c9a2c5b": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cbbf87e662f48e24c47db88fbe9af500e10d05": "0x00aef96617b907000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8a7cd13c25d7237e4e957074e70bc3985920f21": "0x003036d4980900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511fda9d19459a4aae336c650befd78ccf46050000": "0xfa6bec1c59118bb967eacc2d3f52b46779d20a6301fbed69d536e505caf7591900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e659b900949f70623fda99c695dbd27e9cd9e7fb": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900004c5c68de80a76948dfcf7a77045af476d346": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cc3d336002054a3215fd3cd1f00f08bcc494fbcb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700928ab46f9251610992b3f5fd257cc031f354ba": "0x00427f58a79b02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f57e50a2ea8f652c4166eff8ce217baa204e7f17": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002bb2aee0241ac3b7a6fb01a6fdb8c5c7cd61c8": "0x000af98dac2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890035fc5208ef989c28d47e552e92b0c507d2b318": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ffb2420d9a86a67109af4888e729180f69050000": "0x3050a297efff865cd424b60c6b56e4eadd261280c2e156f2b04fc6f1f9e2327900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fa4be1af84fe8101f91891adc2d52a37b93dfd11": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1894d7a0d8c769f8ce8973709a4215e91f895430fa64a5bbd42c73eb429f3f1d": "0x9dd8ff7445db83b54311b53593c8cf23dae7ee9f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397442bb3cc2095dfa3447c774c3ecaa91805c4a94f": "0x0048efb761f301000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006d9acfd7f6917019a8e1f1f25cb8f48faf17f8": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243c5180bb2f2975ce4750af769d7a32dcbd69d39ea": "0x0030f20137170100000000000000000064d1c30100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d94c9b57fce4ae83da1b01355bba84a76f5cd8bb7b79cb177085798ea538cd91a": "0xf09452094039cebf83165008759d201e7176d2d3", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892215457b391a2660337b75568ec05adaec457502": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ea72ad53b162c6759b80a0b33e523f391a9c41a1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d3fdace77e1ceca5128ff2f9269bb27afe9dbe": "0x006ee223f3bf00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513cfac1c10336ba96994c8abd6c5ef4490f070000": "0xbc0d52af72f95b948522eee7d3b09b8d77dd465baebc301f332aa52b1a93b24000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c861c2296e9911ce4a1cd4bbd197a360f8cfdfb": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282434c490375c379dbf184757b100561207f8ab1938e": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786ec1830e985a7f8b3c7cebfa6c86774f9b347b9": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900042b93368df4bd63e3764f6508992829dfaf97": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243005b8da2c805e382fdce0dcdb2bfed16611861b9": "0x008062175ed15800000000000000000098fdb88f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282432fc342c182bd05c93bc824952d36fb4316392684": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519f11b80c9e67dad7ec1a78347f009d5c49040000": "0x22a371deb8c40c0e598bcf145b98cf2603707a87415f0afcda8d4fb8b19f575700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894999ba3e07e8446389fc80467cf6cba34ab2363b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d78e6c1972ad777f576760bf364b908b07556bc0db927413c1aa6ceebb79fe562": "0x8963d38fea40b7cb37c9bb2c4d3252415f0b6d65", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824339634580a5670327b6f4f925dd85f2bcc2c44c6d": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339743e0c52f9a3920e2f8c01479fdba32a8115ad332": "0x0040ff72163200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dd76301e7c4b342f1d805b7205db98f6c1611ad7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df264f0bf05eb6609b213f83c4546f0f196f62e0917699e517903e6ae7be5735e": "0xf947f05d2b295c924a3e6058771180cbb75cd60a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700042b93368df4bd63e3764f6508992829dfaf97": "0x001c1f0e300900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9e03aeab23bd20a06fab8fc6b81589d02a4086b57262233b345b61859909167c": "0x00385543ba35bb319a9067f9c03b1a8cf917a6dd", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbe29d91eef0aac3d083dce8b7033d16b98fe94fc303d21e6e268ad311313844a": "0xadffeef501353d90db6612ed584b1438daf02c4d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974051efad9288cc12636868e4302397a4ba38478d": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6ecc3d4267ee15a905e60b267efe7058a8033d41840b86a90afd6fd2544c4242": "0x4b51113c775e15754b42a7ffcef1bc3281adfc01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977363ce9c3118275a73211c2746432167ea95ebb4": "0x0072e669861100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928903fee733b242749112fee4ff2bbf7f612dd607ed": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b3bc9934e8b33722ca127accd270cced149b5f": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c9e65f133b90e4fcf565abb95408708f9845b90c": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928909f8eb817bed2df18ed680c9c310b9ea75c2a488": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895dfa9a92eb14a3455b46eed5f6e17253f304abce": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339717161323d264e413ae0984c6ec4825cb4082cf9f": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bbb1ea6d7b0b887163d6e32cbdf53e87187cb3": "0x00301a45ba2900000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x0020706f6c6b61646f74", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd65612e123691bec4f749b69367b6c04653ba5ba43e83e7d2d9237cd4fb2a20c": "0x81a1929517b52ccb71a63d31774bef3efa6d080e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700de86782f19fa9e5881223077680101b2b99019": "0x0000434fd7946a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339709a89f6468aecaffae52142487eac08e126bc071": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971bd8808429c6f5c520232fafa9dfe1ea760c5bf8": "0x00927581d50000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514ad951d71a7b963fe36672537e16406fd4050000": "0x2ace8953c1bd780e51bca97a0d5946b613d918571490c7a11e0181907e21a60a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891cd65f74d01ecbe6a63f131c3bb140a0e0a90955": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d565169aafd38d441981d7560cd298045d69aa86113a0ef023ca4de562441827d": "0x0099fedd81ce071a859bc98a84b7bfdfc52f4242", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f129becea934154fdb5a9a95d1e3825a33070000": "0x9c59488b8c7a70a2d91b288b43f0799a001b1d26bad39fb4e7ec5eb73fa0482f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397200b6591326cca7daf74d4b6a5789824040d5660": "0x00fc5e9c971e16000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce629fe0c1c653419be992df3bfa1c6405a65ab8df60bcdeff1ef5341546fb42": "0x000ce94f81d1f81401712a57f615bfd9b139a657", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c11894e867b2706791252e9f7bb14cff19040000": "0xa8e87388e083b3f1a9dfeef27977d883cf10e7c94acdf0c60f57f0a9621d453900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243ec3c0312d2a35ed0677a7f8eb29116ecc4ebb6d4": "0x0040b10baf682c000000000000000000cc7edc4700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1cf5cc62622f472e9e347070cc4cfbe265f0e1bfe56e07462cfe8a7b628e3f55": "0x000bc706ebecb19e4c334a8e8e9becef6e58a2f0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c31fd4e2f78849537318712136cbf7317f21828": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5168344daaa8ed71fe4822c715c5b7c13b6c040000": "0xf6f1e50e3c4b01acaa9db382c361d878f07d6e100cff337017a88102ac7cfe6800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5c5062779d44ea2ab0469e155b8cf3e004fce71b3b3d38263cd9fa9478f12f28": "0xd957478b19d8fffb6c622003e411a99f96c42301", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc8fcab73fd1b77bf96980783858afad61a357214ab29114ced424a9a2d24834c": "0x99c72a739535fef15968b080611b4752a564a3f8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975feac080c5d43df16479488252694eff5bcf7a2c": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d264319ed6a0895c04112917fc9bdc0771f4a4773aae014a99d25bbe06fa1057a": "0x00091bfd5d263eaf2c04134a4ddd0eea8c70468a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff7f274399c5040331a59e941b4971f31e15e47d": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009525c96a2340c3cd1e0d4d11199f781fee5e10": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a69c42be4828dcffcba1bc8dd9bd10f5c3caf3": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243393774d01e81a2fa93affad6e3f75a86a569f11e": "0x0080c6a47e8d0300000000000000000039b8bf0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397824432f160f254ca59fafad843a74ecb32d3a4fd": "0x0080c6a47e8d03000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5153bd7e1ecb6aaa9fd0f88f3586c50f6e4f040000": "0xc20a5c102573d715a962f123d0991e9c5bf60ca03aea31a1305c72d9d510167100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002c8f6cf6fffece4a83cc3d75760f268bb0c90b": "0x0050be534a1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea72ad53b162c6759b80a0b33e523f391a9c41a1": "0x00de0f257d5781000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289946ef62e1a97865e99dd8366a87506858d83f279": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3cba3cb96173c2dfff3f2bb0cf5e3c70784cffadbf02b1b2be4fcdd1f78e4374": "0x9c6f2351c0d351af08be5f54ca624f1a12417531", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d47559701f69ecb16d40d5fdbdb5f604fdbb9d1c": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243e5af6b59d2da9b4dbe2ce617dcae625a004b0607": "0x00c06e31d910010000000000000000001184b90100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397188d44d65f4198e7f2714df73b099330a4bebd49": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b28bdfb808ed2c7df779664ebbf541b0abde08": "0x00ce2f83641a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d16e7952efb44b46257327d0d81cf6298ef98eb5caaacc783c082a3cd47d0d22d": "0x6407c0c25a5ac315d64b8eea2f315983f4096f7b", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d24fe4c500ca6a4eb82c597d12ea9e5925549433fde896d7aa5d7f929cf87e17c": "0xb67a2bfea6579b273cfa427637adf9fab925f68a", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da814b8d83478b845fb4997be044588f4970be5507f41cdfd2c57328cbb83224b": "0x46ac13adfb85fb7261d69153e73b006e585509e3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397088cca87b0d829b35efeb6934ff807cd3befc48b": "0x00823c627ebe01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975fa8bf3d389f425cd6bdca59d08b92645e236b2f": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008ab9fdfe08b2cc37703e4fd5f1312f885cabb4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928965ad859676e14ccafd371f0e5b5841d1ed014cf5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b26577622b961191d9760e43cfe25ce444b02807": "0x0060725ed1cb04000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514c98e04b0c8a8ec399f1efab973b6cd6e6050000": "0xe406ff2bb0c4bddb3b8fa92cba3c11042f2f83580a9ebfc2e5fe0e4102cfd70b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397261c307a058f4a6970c2fd1c3d696fdb968b83a2": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900eee540f78117a6ee55e4dfbf89ed4d1153e644": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893fd29fbaf2b2245931f154595c2b909bea226418": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890045ebe3bc90887088d9c91446a2973e79b0f78c": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903": "0x183887050ecff59f58658b3df63a16d03a00f92890f1517f48c2f6ccd215e5450edc9974cdb3cebfac4d31333c30865ff66c35c1bf898df5c5dd2924d3280e72015809fd84af6483070acbb92378e3498dbc02fb47f8e97f006bb83f60d7b2b15d88ee494d719d68a18aade04903839ea37b6be99552ceceb530674b237afa916682104c22c383925323bf209d771dec6e1388285abe22c22d50de968467e0bb6ce240d12c7ad07bb0e7785ee6837095ddeebb7aef84d6ed7ea87da197805b343a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892e40fb968520f859414e62bdb05e5b1f2f6201fb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700567685d0b24e7a550e84ec66adc6fa91c35208": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970de05b51aac16e7df22a871673adc10eb572fe93": "0x0018a2191e1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973716046b0394219102f5c2cdfd234312c0cb59a2": "0x0048a8b159c903000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dbf54f643d3827ab6cd931a05d4643c524060000": "0x845731661473decb5f5f8a168516450f53efb325ce899c6d356aa13b7135666200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397527a1247054d4dee8fe4720990dd8b9154225487": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d247bf0e53c7df2d529571a0f30b45813cd97fcd008f8d20fb42b44a0cd5f1c77": "0x4678b10000b032197ae5a403058cd72096198650", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b33841ab8e4fc931a294256066286270a77632cb": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736569c3f76b66f8d3acaa386be180b76c39a2f19": "0x00646a57109c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339742eeeee8340f7018c662faf487351acdf434f301": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005032c359b798eb433f50af95dcd79ab333dc2a": "0x007274b1750100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976bd98f74f818c4fbfb760afc077c3c8059b11276": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000e0eff1c1ea2d6c76862b36009e1e1017acb88": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243e63bdf498cc6781799cc23953e32dce295a95a0f": "0x00600eebf2bf020000000000000000006a1c730400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc8ca8ddd21b83ee3a70faadf02745a57659bd0063b8844312300127a8988c103": "0x1ac7a5d501554f521168dca348bce0e034a3f9a2", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5133fd3d50298fc87901c2f33ab4c38bcaab070000": "0xb6750cc4f1e3b72f3b7495883daba0c156f9f5abc93650f2153f2b99ede82f0800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d41ec9ddc83bdbead278781f9b8c57fd2028dbf": "0x00b02d87f5a900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893310cb1ad03f5b8a93d5c673e11782f159a017ad": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c5a48a8500f9b4e22f0eb16c6f4649687674267d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895124f80db491ec897cc316a5e11bc0dac771128c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895937c41f80fc6111e6703873f89270c60fe559a0": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950a028bba113c792317061726180a25cc78808d9ffb966aaa53c3c399cff7ea0b409dc8b42908b9f2da6d34c3525": "0x5809fd84af6483070acbb92378e3498dbc02fb47f8e97f006bb83f60d7b2b15d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c70ad716691ecf66e0665397fa4a7ed8f5979b77": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700eeb83600ff5dfb5936a0b8e7dfa7806da471d9": "0x0018809cb72200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975976fd31391dd442d59af9ed43d37a5394379956": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005dd929c6d703a12daee88fc368b849b0505c27": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004f42b803fbc2580a9cd18fc130caebea8651ee": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51635d382a6d09f3b1e1f7f78a6075bdb791060000": "0xa24280ca3cec95cfa124e17a8f01f1dd287bf14df1937d9ed97c91e39ed5a25200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc639594cd4090c83e3bee137a917bbd0a5f3c9bab4f974ba8203f7fd08d1ef37": "0xd95df826fc3ea014f404a1368a254e23d29d99c8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a926f76a86362c456e877e0b3f00c1a43b05c4ce": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817deac2b6fb8a0391cdc0b02ebf3cb87a81e4bea950d63b3ccc5b13cbbbac392261": "0x3c15412599907bcda854ca9f243f32baaf3844a2", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890087fd9f134dbd9d68a2a869f14d88c812a14051": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289772ea6e9bb2ecfb884c881cd186dede1ae2b63ca": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5141cc37f90fb192d585cda93dd5defb616d070000": "0x4ec0fb95dfc28a7d6a15d3b0307a004048b0acce0b23b340d8c8e646290e803c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9c396028b751adc267744c732e5838ef86a0e83bbc957103d31206df3e24f131": "0x746aa9ec270bba58b97a30b5b402efeaab86bd28", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dcb926da7ff3bdd92ea659beea369ef286464e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c7b56263af73e000370631e069866b8256040000": "0x205c26c75bc97c8a32afd10e3a4b7b1af83739b7be3dab18ec7a435cc9b4ff2f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d103092c0a2aa3bbbbd71945f255bd5cfb7a97acd4a7f08efdf2ff5cd9c6cc348": "0x004e0fc93058997aaba684c4b3e9b5549a736fcb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ba5e63b8242e3720ce62015edbbc4037bc44c60": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e10e1d033589ab6ff05a410ec742434858d3f4e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900353dc8b8425298b8b6bdf587c4f5631601715c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004840267ca0976045bee42e0b7dd7dfd3b827ce": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008792aa9191cb0bf670babdaab314c232435152": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890d5f69c67dae06ce606246a8bd88b552d1dde140": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a77e549ab954b951a118c7106bb46e606e9c445": "0x0080f420e6b500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282439ca696ecc735a7a734fbce108cea75f8e982cfa2": "0x00508df5952701000000000000000000134fde0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765ad859676e14ccafd371f0e5b5841d1ed014cf5": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892165753514a94b7777f495bf2634a0baba07534f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ed2d6c16707836c6609b53b802692fe176db28": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893fb4981d33258835ed1de86668344ee3f08c626d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd836ff75f3d718375497728671cb90ab593372cb4a29f953604a77444818e71c": "0x790a8706d0ae9782042de2a022125b746511047d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289460cad37045859b3f67579bb363d3e8f48c4df50": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b78c8f3b56f2e4264792922e064afb51b37c4e58": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e1677d96bb82668bb188ec71498db5c0c0c4830e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517fe5709e54e656ab48c8374433dc766292060000": "0x74e4867b46b4d8ca428315963427c002b2e78d0faf10f6f7ce28a3d963cbc65d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1245821dcf1ae288a0dcda3b81a608893cca26a21cc01affb83e9dc64a2a5f4d": "0xb4e721d3968b0c88be2dca14041f75701064b3b6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001b93e99a0ea0e8b12f3df09af6564b460aa7e6": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d087e2eabc4ccaf442c1cb9fcccc3e09560cc0be2fa17f26b3d5a08b658f7db02": "0x8e17fbc2389061940e39af6db317b48ab56d2a33", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f8e35697891efb39506e932c9084a855ee53ef7": "0x00a29f816d3111000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397517d18c6a1f053420d79772cd05b676d3468d21e": "0x0040ee7affbf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e4cc4afb6dc15d5be10f9ff1cdb373e6cf1ee3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f53159c395cb16ef27a758ff164280ca28090000": "0xae77fe3329cb18cbb61840793fa16d02319cca0da4ffc3fec7f1a50fbfc1e91f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1e578c7d15ce8a11f4e713e63f5465ff324a3a856f7ca64574dbd704597e72d9": "0x1d2fc4af6283590eee0d236dee41b1c0b257472e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d68ccb9cfb2b212cb33a483824baaa23e4a088ce87b23d790e3eaf77290eec925": "0x2cf6d5701b164808a3f3886ee6258bf3208c3743", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895db9fef353f8a6c00294a980d2897083499ec00f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891fc2d658b3346975cc5bd586efd5e7c26db8c98d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892da0721ba1e1f36de7c61bbf20ed24cb66ce9c1b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5189bf24440ca72c436687043fede30be535060000": "0x2ab6a0d5885b1debcb5f089ce73d3abe16792cd01d63d788609f8d859fc1fe0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c71916faeb4697a163328b984e41cc4035440ee0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aba74c2bbedd2cc9fbf53faea49cf1080aeca487": "0x008a5f28be2406000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339723a7e13e72a9844787fab89ca269940f80ae76f1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e5cdd4b7b3a78a4277749957553371cb6b2310": "0x00d01ea1f47316000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d6ddc7a1b324b86019d2a4cc333ddf36a70b0f6c": "0x00c03618962805000000000000000000d8ef580800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008af2eb1b57b4a591e08cd0dcb93b0b0978053f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a2096e3dc4c8173bb1064f33b005844a22513d03": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700951b683e7eedce3efc6199759ea1ab521fa5b3": "0x00f0bf279d5800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bd408cbacbae6abf32dbca24ba4400709bcca948": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979405ffe8c225312b403cb49a313e7a0da78c1387": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e94ec60bb2c3c196338c7512dd5dc87839aa2d18": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51484d257daa10da0e6fd9b5529818625c06000000": "0x0061d29cf9d6d397701166c8c1e07d742e1852fd8ece9731f8d1fb9243bf131d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5193b1135eb7bad1b83a36265ecad11170d1040000": "0x08a42f9d42527558253666ca03c7ba05ed79b0ee71469cdeb27d99482da0932000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df0de782e8bad3c663be60812f0a2ac63464f5da3ec448c73334c07d71ef27f2c": "0x00ee03095cfa46cab6e89cdf19dc2cdc64fc76d2", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd6077b2cf2af58f058dce80e52283bb700ac5d2cf8a979fb6b8e6f4f90a04544": "0x000e229e2cccd3c40cc7d3182ac72fde71122213", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928945008c79499a54004ebf93a3b1a902f009a6f41f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f19d683242168f46e014eb8db43d21b7e8040000": "0x040fddcb4b5b6707697e2431f7330ee99372e2a55b955bf7b93f8a853d07f10f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f527277ddc787974e57fc195a0ed5c86cf5ddeec": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928939274cc91485b4501445ba4c1a67b16e6a5fd78b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbe8b6c175c9b2c8e856d8d8f48b48b2e6ff221dad80764466c4f4ff46132b427": "0x0ae46dc2234842d01e72c6d688bc2e1c4b18a004", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397542055cba6dc03f704e613894cc1d5bfdd74dbe0": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718e653d8262814fb82b703cf058c97e7b2020c38": "0x002a9799bdbd01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928908c204dc28bcd0c991b903bfed4eb5309d1053ee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890074bac45b84b3067a8a8d7044396275532d72a5": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d22cf9dc37215691aeb166d34895f9651b6b9f0eac9e67795b1d48e8eea19a371": "0x98c97b38d63ba67d0770cdcf8115a5c8a470e937", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e3597e85a29412f80e5597cacb09fc7aa4ea9d3a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f6be6461b1a0badb3d4458da2f77da2268b83a9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b58917b2b71399c841b985727a3ff7fb59547f1": "0x00605f3580ce02000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfab20f6aac6679222f627da75051b3866b8a547686f676a73a906ef985c48c38": "0xf9c86dd81e7c9af956327767f5e9c5da7a3bdf21", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897daee2fdc5f2aed7ccd792223a8945707469d1d4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928913983684c4cddfc884ad85d31f5e46f078f13095": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744401fb5cedde57d33b2898ee66cc263029b6508": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cbe4cd526f64beb3f283fe5afdce5192cdc261db": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ef788a96d4857ba2e5a46a461985577fde080000": "0x9aad9414088708b92ec181c612190b68da9d63cdc7a62f1d0c6ed9f56847122400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397657944ab5a639ec79ba234dabfd0eb792ee9412a": "0x00a0205a752900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517e6fa0b582cd2af8429ce2629445a21097020000": "0x4ac3e0cbc1bf2889a7d39e3a2d4f3f1a2ea203367207c98c62a0d7fddaa2251000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339711efc885eda7ddde9c1c77f2946737796ef06e3f": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289620348621ce092ee666b698246491e95c8e61499": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ec4e012df5a2a6ad90def9941c754c27d7eb0d": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de6d97bf878b1012927ae6afb7e092c541a5abc3904656981beaefb9ebb781d1c": "0xeb2ef83188323b61e2cad0ad628bfa33e45cd0c8", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5857a2b92920aeb74ab5f9ee71485235eb11e81979f0efcd45c4e6099f4e8212": "0x5f0549f359ac15f6afa11cf6b0d78c22242802a2", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512d06c5e1794ad888faa7628ccf02e5d191050000": "0x761a334025503fc32b8d7029bd4f1f90fa08b78f6144e0680b430931c36de76a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfa5640a653470ee0da616be3b471374a4af3bf29545d540b5fa7c63b59c9d060": "0xc326c5ab988880f8fe6c1e17b97cfbea724a39cc", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d84769386be549c14827cecb1b29051855410397dc53ac9a6c38917878db70577": "0xe0ba2bcb31e7789cf711bdb657cc69526bb9a2f7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bf51d287fc91f694da8c8ed0005b1251397eba": "0x00746ba880fb00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397554c9622a293ea2f075f259f06d9f19b9154c253": "0x004ad900dc0c02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bdacb2381dea4e23621e4e3f5c8f0ae020cfc688": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e18eb8520947679c4780bae0abb06e6a219b8df7": "0x002a535b914203000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51508f79d042ff0b1efd0be28dfdd48ecf25090000": "0x8a05b03e8c6bb87fac85e9d3a627f076be05c5e38fbb911f88510ee1e274b70000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d06ab119355c4230391d5a2983adcf81d91fa5c160c77993512437b35bfa67d41": "0x41f2f7387969ac7c06fa49a29fc479c22a9ec8e6", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5135cc8473ab8efb62994f898e34bd1d33e3040000": "0x86bacff9e50488125f449229ffa6767a36ab06a48b04e41c70cc7e6d82359d7d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9c2a6baa6ddb14dca58593ca97531705f61781e9e6d7eb181bf8d0bc5ccc162e": "0xdbda5deda828ffa3c15dc99cad296c5671181fd3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798e43e922b829f33f3a8c9a81943df15706e7441": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928934cc2861eeb213da8bf366becdfb319f16aff12c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b00ae1e677b27eee9955d632ff07a8590210b366": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe265551142de05f83c1ae9bc54ee9bd1248f80b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004c8ab207f6e5e33d260559aff9cff4d803f4da": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df93b554f8a7c976f8fdb35afe4880a13b463dda": "0x004810e3f90a10000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7017fbaea2e43910a041dd8513d200c3cba7b6dda9f84f565e7800fad57ae55d": "0x3fe5d6a2d1caba760006007687adca8661a252f4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899157a5fbc82a5eca9ebc3a225de072b4ebe7cc30": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b614ba568f71a18428d29dc741ef829140b46e5": "0x0010a5d4e80000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5172523eb9e57bba09fb1c7651f641cb74ae040000": "0xde55dc13c5df43146dd3a4e8b44da6a27d052dd19443121adc90bbd690b4c33400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51102aa58f350146961bca1b6ec7bb933b9b030000": "0xd44028df7e4094fe55acc1d3decd7b43349c968bece089408f40391002d6680700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2cd0447bbdce4d89867458397fe69cc242c9e1cfda74ce65eef5fd6af8858d1a": "0xecdfb30ff7141766182ca031e20777c0bca09306", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3223bf5cc2f5be39a507a92ace7e924cc07bfb43bcb61aeb55e09fb63affd53f": "0x08548af3414d04416f96f60cb1c39dc8ea927b4c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008b0c207b6efeccb38af8b6849ffa6b9be0eb61": "0x00e45615d51b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fe8f3d02414c57745f1e87be25ee3496a1a573ff": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b0ed4774f5cb36752a3661f8248958418d4bd1": "0x00bcc1fbefef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbe3f8396e3f7de378fe665cd2cd3521af932a8a376d8d81dda40bb4e4438504f": "0x14ba180622dcd7ff90ca091fae20ffc0dc847100", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa7f691c51ed0ef0f26c8f780911c95d5ed62ad8": "0x00ec226f1d3200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de4e822f53c6197f69e968d91b2e0d7ef65d1c4a870cecad43f82195e7841e51a": "0x51a5356d5546a139adadf0a7752c4ba266dae69a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700411a29c7d830c7e7461e7ef541b1a7a00453ff": "0x00eccc45eb0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824335edf1cce3d9c1775ff5e214dbfee26abec3fb3b": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d56137106658725f976ea2409e4a015d980c2cfafec7b57d1e4b7fe268cc35b2f": "0xbd546ebfde341c6b20726d206d084de51c316358", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900036d90bb4e462221fbe06403a023192c0e6c4f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5141e9f73f8f95e65a2f769eb843d5f04054000000": "0x64ae31d2250bcfed87214097d5e793c9426c03c193d3c47533506281f5b3446100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e0956573baada8dd69fae1cff092d73739050000": "0x447942da8bdc750d846b7ba4f88b0d8b3ee8f00f83949e07339656a5b5c04a7700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928965dd37ee6e2df4710af8229d4aa913ea6264ddb7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8094382e17e1d0c9393bf84d2fa671d57a71a05": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b0efda181dd90a361cc220d5b9a6a12b38a551": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5185eac9818c58dfeee4f5bde4ba8c2e9f34090000": "0xe01265d6a89565dde0b89e1b68e74b661d389dcb7619efb71e5c9d8ba46ec72200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cb41214ae65c8ea58500c913d29305ac2092f0d0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515bb0ad1d2ccafb0c76bd51186991e886ab040000": "0x4a39b2e373446d6df599953c0b0601c66d266732324077924b8aa89e0e54371000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516f81d200bf815640442722e6fdf3ca7919080000": "0xe804b725c80575d237aff27c784f805903dc0a98a108c46f70486c9b49a34e2800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824301beef9b0f0a48597e1454d75eb062d70775b13a": "0x00a031a95fe3000000000000000000000eee6f0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d20dbb8000a9a464d581d28cfa5fc2f4d49e4a1159e9cdf039111559fdd2c6502": "0xb26577622b961191d9760e43cfe25ce444b02807", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979944d6a90b6e313fa8dcd0281d7760ffe4ee0530": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b129e8f6a6e723e77313bf99718cdd640721d5": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bebb6f638336fe10517a0b38bd73105f2086690f": "0x007045af21f501000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c989efe9779ddef5ba408bc1d3bdfbbe3c070000": "0x00c68940bd54119e1b84fbf90e9dd10034a2b937f2c2016a155100a598db892b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339760540e1682be7484af2d79b6cfda708ee285dc8e": "0x007aa137823e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bfe953b6bb77bf8c7851141ca684c5dcfd6cb925": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5109dc7278361f28885afe053ebff3ab23e3050000": "0x4a7b08615c6206550ca43f314f3814deb5842b7dee2ad0af0d292847cedc661d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed8f71ffd7c2e8d8b37564a4e3b5d6fefa7f66c1": "0x00c6a6060c2001000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8820d7c939883f302beb71f2d459632bb46ce2ed64456f90e6b31a6980704a23": "0x00554019bc1d942aef1cbf7ee6becdab99ca91d7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890e8e3a75280f066163eddafe3c5fa91ea6196047": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b53d311cf309403b9f3538ffe66927c3702ea8": "0x00145319b51000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289151712ac05d7df898940e3be3ccabf6d77cd4150": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ff9783bc7ee8de42612f752d6145fa729402a59": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928943eb43b52539b354b30f15b96367a733b109432b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894daae42c5e89d09da39cb90f81bcb2acbfddf67c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894dff7bffb7fc240abf06141976d2fe0bf610edee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892d849681da9673b51535230397b2aad3e68f7d49": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900577ac183e66678ad5f27a8e5cde19eda76cf6d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8e2899d61a0734001d791a641f8965228ab1e60b4021750beeeca6194d10c36d": "0x005dd1c702c3fcbca5f63b3ab931b15e03b3c9ed", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519daaceaae8c28139c4732f43e449c51af5050000": "0xa6ff9f3390c3e28e47d5eb35081d2bff9ed3a3db244c46b29ed0bd09adc32f2b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c2fdc1f6d5ade6a3d39ab48d545a6a59d971265": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8c6480536395191bbc760632ae89722cba67f49042cd1a5a5e729c3186a41767": "0xa6c0c85366f11498dd656da6e5b05bb8eabf1c82", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397097b2eece415aa2a4a7b1e0c310c81ea3ee1e292": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d963cce358c1b7f7a0dad86343e1ef27995a3559168a1f5d8f3b33c24a023b754": "0x72381e109c9f9f9318307e249fdbd0304cc6559e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970054cf3827073c8663e5211e7af6c63ed4b0ceac": "0x00ea56e6bb8302000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895246fd9b509ae75c0f4b2c176c3ee71de674f292": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895ca260bfbe4c116f9f13d007d83c27f8e7bbc675": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896a8d40e52242e2bcb59b5163e4f7aa05ec1c7474": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898622cef8a526857f4a3223af10b302fc29f79226": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f00098c1c1c81604a82b903cc34f91436e6a72ff": "0x00c0e1d0612100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51eb010991bbcdec44b94ba7814cffe2540e080000": "0xdc3ebef58d5bbd698bd02d914225a4736cf023bc21ebce7cd1a41c03a432457500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c2e1891250427bebe1e66c1d86d1ef010e4396": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e82b6cab96e3a03c7f974089a585b10893a5a9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a50382a9b22b0720698d39131fcbe289841a54bd": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339714f7f1344ee6dfe20dd9d292c543e9e443babbec": "0x008c0d35660200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ec77c48e880d46812d3e9c6fc5e4f8858f51d94c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bea41f180d6d5a48ebfb12f9c497ed3ffe1453": "0x00ceb632b62800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f043f875302e01d60d90831ca17593557969b10": "0x0080cbc1f98e0f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397319112568bec6af88d43c258f36d94319bf1ac23": "0x00c61bc45a0e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d2989b71404e366138b454d9e27295671f96ebd3": "0x00be5b46221900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778a451390d870ab409d22dd5afabbbb623166e3f": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516d09c9097d59b173ed38c0bc7b709f432b080000": "0xace38628d126313f685422e818d27331e9afae30fec205b60f5741faeb831c3100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b86a8cbd383f9a45c70ed742eb6edfa2e1aa8e9c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b8ba75ea553f7049eb54e20e3ef220054bbbe583": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778ab8402b3e615c292fe9a69a9b4ac17983bc875": "0x00caf46a592700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890089698ab4f16050d36225631917d4db489dc251": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289df5aa870ca48f1dd80eeb75b80b7d2d797d74ca8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289642a4f994bcbf6fea70c54ec416ed9de02f8e00c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928977c6f7a1f67e4810c454d57f5972da4761f8079f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ff7f274399c5040331a59e941b4971f31e15e47d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d80f9384b92e09042571a9e5cd43d9656d62acfeb0324ff44698bb2cfe422b36b": "0xe4b424e1ccc6f08768c921455f83181bacbfe3f0", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51950f765ed1dd62bf1261877a398b1b9a64050000": "0xae7976297df7e47f83d7166c1dc7c5170c45574aa384519a0bbd549479bb913900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976064d1a20e529ea15b06551e1690c8f50342edf2": "0x00dc6ca21dbf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976abe176c495486e953392e1203c4f675aa7bcce0": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778d4635ec2588de43585ca514e0ea0201c52f689": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e4c6d9d21ed31544cc123f5153d39fe65e9a9e1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970017a7dbf1051e0ea2a57513ff9423919bc8a5e3": "0x001a489e301000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e0834be7dd8eb02ee1ae17ba5af36b576df80a3b9be07f8837c3739ea698662": "0x6a4bab3ab426b32a90c353ae450a1d9712d67d64", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e6a8d75bc5e3c79b23e45d6ff505015db1b0b753": "0x00ca73a98f2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ef47d6455ac924fd91990a3c5aa921f15e9ffd88df32cf6d59adee70108ce26": "0x009978d735f1a23bb6922b620c490ac4aba66cfd", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b01d06372d7bfdf7ddacb9b11037e024377810": "0x005a2febd9e304000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397209e077793d4f2390c410705351407ddd7a31d99": "0x00dcd1db054800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ddaad281bd203effd53340aab51fbcef400e9c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df6f1e50e3c4b01acaa9db382c361d878f07d6e100cff337017a88102ac7cfe68": "0xa83f2bcefba0bc8bc10f88eebabb7806bce2f156", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fcbce22223d8e6051bd25cd6026ba660f81b04": "0x0000434fd7946a000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512b3c75d714728e67c417cfabafeec8e21b050000": "0xd4d775911ffa93f25ad53bc9243483e0ca632eb22ea96ede54c71b9a75060b3100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a70464ab2804d852f76709174e8f4c30b46e7c58dd5ad8d189865185873521a": "0x3842775e7e6cba076c5f3d44f0fc444b93a1502b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890088f9993ebf41b1009dc7b17a4a01ae47bbfbc5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ac15089b8aec4ee664da691ca3e7e29bbdf1b7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d18f26f499a9c3e89abe57a17973da7fac070000": "0x78e6c1972ad777f576760bf364b908b07556bc0db927413c1aa6ceebb79fe56200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890c12f8fec9a75f790a19e955ff87908b0a89ddc8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764be1c1a0198370f53b2081e15478be3135d6bef": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de25e8c141e674ba58ca7fd0043366f6903488f3c585ff1180c9993eb896a3373": "0x482b1c8fcbb12b90573071652cc5d46fc24fa426", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513178133b82824ff0c8ee279bfde224ea7c070000": "0x96c27443a5b800cd9324210798250c05f931bee9db9d99c0e1968b820da5b56700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f8978b550c0291627d5604a84e76fc044c23fb5": "0x00b4d0d53e1bd8090000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d098fec4ecf9ac948b17a179c638f1dbbcef72d": "0x00805cec442900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282437886c5f36d2d74ddae70a9125b9f375fbf614cd7": "0x0000869eae29d50000000000000000006d2def5801000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397970a3182ec4dbe8115a001c5abf6f5383cfd6c6c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4f934bf2530bc28447f594ff4f05818afec1e8d": "0x00e6a893f59d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289291cb06901bae540721973fb6a98a2f6170b21a0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519d604dede2a84bceee5bc19236b33555e1010000": "0x0a2eab03e8d24c980a0b7a03c30f0c5537caf9c27907477fe481898217d25c7000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928955755dcb998f1218761831ffd74747cdeb54e1ba": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d0d4cfa04b458077b80a2b625bca31d710cb0e9": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243b7f164ab2ee6bc8581a0d06bfae3fb98e258b265": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736518f6425b4e3d1045cac34d91cacdb49bbb9ad": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ec3af4ace34c5c019a1bc08de4dd22df31f0895f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5172fa18d14b7be8c1c85c7603400dd37a35030000": "0x9efbf480d958cdfcb501e7c573026da710fbc824f4fa05501fa36cfad8dfcd5000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d76b3fa5836fb5eb23288d20ac261989160ce1c76eded0e23e6e25ab982341529": "0xdfad4e398bcfee3910f788ba02ac6de09156ff44", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9bc7845bcdf580a95687ae90c37e0b7f995135f": "0x000ed4b73e3600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db32770b6f97f03b60991eb4d710ad6d28a09ff4671e8b50c6f6347edcf059d3d": "0x7c33a725229490756ac021941021ea509853ff7d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005e14b50c77daf1b3fc6f12f3b4cf820a313adc": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900365211e85575a3a4ade9c33c7207fcfe886bb7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897c838d644d5b60a023afed7497c311fa78175a6d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518e7900765e74c99e96bb05cc73cc41c69f040000": "0xaa6130c09a0f5db6245a628b67546a22b2a9c691b076073711a0fe0a9803a14b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dcf5ac110bfb16933b6f50b5e5f8e38c98d39481": "0x00347818775500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928972d6b2f916ffed3858da78c4b91c40954bea13fc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a4e325e0ff51a61d129d2848b0e6a5324bb42471": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a89681d73055acfac5c4ce4ed108c3ea7a84a59": "0x00a0e05ed2d400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d6f5646d9e7fbee7cc907eb8e12dafa5378431e6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ecb3531beae3a8d1c0827a8ce461025835feb8fb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890887159799951fa038ecd71dd8335d2c19d14d29": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722a35cbb6356055d8216a36af746c58bcfb99566": "0x006426b3d1ba4e000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897e3c5b62a7faf6f5c4fe49eed72acca25edcf2e4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cbbc5d06be48b9b1d90a8e787b4d42bc4a3b74a8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009b6f347d957e1374610319d75d49348c54251c": "0x00c0fd58439600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397928318b2e90c8b1a5255d03ee5eb3a1533e3dbea": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900406bb075308305d80cfa3e5121ba4354d200f6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289279e235500d1b882c58d2b679ed5253b6e3df0d3": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a50ee9a3d2480093dd4d94442dd6e9ef2044ed39": "0x0000b605da79630000000000000000004426f8a000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bc894689f9202d7e7b18734c97453335548694": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cb499f916df9a47952ca10324161b4ff89000000": "0x1e05e059f95a160e511a4a2c00c70031f65a84dcda52ed3532f4e8d6959d395d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928969f32538b86469d94666f6d7f570185dda0a6781": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d42059f4bba9e1ec1aff76fc2c0afffbb0abe68c": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ea81d109d526eebecfc18c680281235a4bf23fade14e838d120a2943a48efab": "0x0c12f8fec9a75f790a19e955ff87908b0a89ddc8", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d34d46a7b5d29b3012f3d797ddbdf0e2a5a211d5a2f071a48828897a2f35ca30e": "0x00c39eb735f8dbdf396c2749f298cba2bfd74cde", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9a976f1fe1d9b93e4931a5fc14d9312f64677e32033366f01d9f855edc92ed12": "0x006307f7e5034af0a325f5eb706ec2a8dda67c09", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282432658a833b04556526cbd6b2caab0a9fada7d8977": "0x0070c7f9924000000000000000000000fa7d680000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970041a3cf4d4230d2ac84ad786f5675c9c06779a6": "0x001a5524560200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c3e4e713e333bbc44b36f89912b5d8dfecb725f": "0x00fa194ed82900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d04c895bdb4bde0c4f6d3cdd1d2d6483e5a8a946": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975432d9368e60cf5c7b3b166a2b2354864d3d12cf": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002128dc2b569d5765ff40f2656d6d7b91422c58": "0x0022afc58d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970098a926dfd4c742a18bb91e0dd1196cab95f4b6": "0x00f6e55aa32401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f581c3646c7eba0b95e6ad486ee48c2be833b660": "0x00465a9730f100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431c495e48cc5612e90dbfff05b12532a69303bf72": "0x00000e8308e4090000000000000000007744011000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aea57f34d0f7c04bf6f29e4b91baf66955901035": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ec27421edc22ae46c23ad1e8b34f8651b3d1d350": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738103bda64188813b4d890ecd742d389589525bf": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970033f21fa9aaff0f79eaf1759611f0d8c60f7b03": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005789f1339729bd51c51cc221efaaeb571b6dfb": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700185a694e3eb29e58f03442d75a8f59479ac8c4": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339735edf1cce3d9c1775ff5e214dbfee26abec3fb3b": "0x008053ee7ba80a000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b89265b5f43d642a6bbbea3d06be0f781d090000": "0xca56407a6476d9375e9dd68a55e38feeb2cff715286f9c8597e2272453e8af6000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928914ff1233fa526a1c2a67640f637ffb1bce5df502": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c5a77d735f01aab53e4ff89ccc60d503db7c3b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894051efad9288cc12636868e4302397a4ba38478d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b22aa7e75b82d9ac77525ec0d7648872d8050000": "0x2ea620515ca448e7d546849540f0ffe2bc8dc3b665b7b1350f21f70a35fac05500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517e039e727602a1124e3a879731e5f68ecd040000": "0x00fedab32153c74b69435ee6c8df8c097d47a12e6e513a05079f7cee24c3511300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1650c532ed1a8641e8922aa24ade0ff411d03edd9ed1c6b7fe42f1a801cee37c": "0x44e5715f7db1a59de2af178cdad023b16e39da31", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700512a3d8d53dcea7e5eb52946e0d41988b6ca55": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971d65fe9687372da1184e62ab01638d3949124565": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0298def89745f03113783ad625933dd7732fd69": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764606650c04bde33fab32ad33833dde37b47360b": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51399b84b7524151ab86bf4415ccf69f1830060000": "0xac7def1123c306bd08a5dc4651f054c92854a6f6181a7e5cef8a1cf45790b42a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431c6b8bda3f7adaf20a55a970706d195a3ef9a1cc": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890074b0b90a98675309b9db4c27badd1b8ea42b0b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c03372f10f16d819de4d9b22f59caa35b91c0d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aa3b62303f219bd6622c9039ce7df26e89cbe72b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928966b9dfaea3ddef53b98da82a224f70842c817703": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51323946c2ba683a95c7db955bad38a928c2070000": "0xcee1aac0dd848c7cdd6be9ade44d705c02f821cdd2bb857a3add5388b324003600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890004ed6ee7f9141133026274973ed0ee4ce84f65": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6ddc7a1b324b86019d2a4cc333ddf36a70b0f6c": "0x00c03618962805000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002a7fd49620dac7ed03ba8cdd224ec2ddd16a1c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f2c73d48441ebbd6f8b6c7307732c77ca5060000": "0x04bbc70b5c1467975bc6ab17d413ed85adc3ad473e3ea52b0f87abc2eab0557100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d608143776c6a638a7732e342ded84da6ed30c006087c12f022df56b74571e456": "0xd5162bef9ca95cab0b5469e0399878923131d36c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb8192767e4a432cf722450cdd0985d904e6b748": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890048e604f2473ee6eca508c80397d2d8cee49bae": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339731a7a3da4c0952b89144a7f47e04c47dabe9d914": "0x00a6add62f8601000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515cb3ba30ccd2c8e8ee4232bd7e7859e8d3060000": "0x18857b6eb8e9baf2c7b1914ffb45ae7c73d017d0d0bfd0ed7155a7c8f6c0511b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001ac6d62145c0db63bac474a8bf1ac31ade59b9": "0x00d87b79642800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d44e78b7a854326aa0e22da37b9041acfbdfd06eb176a44e76c105928938d3d6b": "0x005d79be124e0852482eea03f11c3ce1eab68805", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895ae39db49af9e2dec759ad1647fdadefb7184399": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ca509880fffc0b2dd5c6a4ffff2074483f0e982": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928952a7310eb44ee058ca1a430356defa045e4153b5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d8f13d654e51f66ed93335d573ab2da1cdaf832d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771375e5bf468a9461b1b49e25dfc97440b0f277e": "0x0044db3fc1ac00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de071f2e75eedf15710e782320a18a5f76510b8d991c9f5f6054b99bf2610e73c": "0x00fff7e689a4ed9668c9207f55c8d68bab1cb507", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896abcac223e44ced17304fe30be5d35661ed1d142": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f2986549e4a6d8486b64bee434a3978c3e5a1bc": "0x00e0ec47918f06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a20f355ae68be4805fab64fe798f19e6db744a": "0x004e1d826b2608000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976236f26b6bf5e69bae11e794e9ef25d3895b3b1d": "0x00465d66090b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769ff7706b367405d95890cba4d905a9f040cd467": "0x00408ab5c74301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971221d505ceba3ea8f70b3324e11ee7eae3740b93": "0x00885fd4d4ae5b000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d72117b487f33e88cbfb017e9925874f664a0d0cabebafecf2a2677eff0cb847a": "0x97d9c5ee5dd7eeb360eaa1cf37252154ca145e2b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e5faccf1d24fc1db3347fe4315bb7d00bbc45b7": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397301ddc73314300e25229803eb78e02ada22c9059": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289206dcd656eb235659735538e8c7e708ba0c3779d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a6badf4b7cb3eab8cdb6216d1a334a48be8c5db": "0x0084df6214a700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5114cc1e3fec7fa8d8d75cd2668442929015020000": "0x70fb86ded71ec9629d9edd8f664d277ca1695b56c069cc710c823f6eb7ce091700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700406bb075308305d80cfa3e5121ba4354d200f6": "0x002a3246641c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008e7bdaa3171666718763a8b46b28415c256a8d": "0x00284c32795300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928952ce0fbe0808b1602284b9cbe22d0cb06203fb4e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51caac2474c0b5c1b163b8ae01dc00964f83050000": "0x8e5df47c25340b48d443389c64abf88909ded6b6dd62c01548840970cc4f14a500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c15031d35a947d4f64c09b7153cf9a0b2b18a431": "0x00667b03933200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1cc0cacf39176b5947925ed5084e7badd44b625": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003278cdde8afa055f7a54a0e928965df0d681a2": "0x00", + "0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b": "0x0e6de68b13b82479fbe988ab9ecb16bad446b67b993cdd9198cd41c7c6259c49", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893e527eaf454a93e9aaf096b404c8450e66cbb9ed": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51be1f3931028cc05c2e18a319e8f64f9e08000000": "0x3c82ab06b794c99f14a161973be7aa6012568b1c491d45ec969ed7420bcfaa5900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df524873fc92acd043016194ea11dfa3276f7e70": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d663525fbf0252118f120be94f11c5d24beb308b9414cb670ac1bcb05edd9de43": "0xd396f87af37acca0980aeb814375eb46880d37bc", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b41a84ae7ae518633f1eea1d4f4d13c4cf8dd6a7": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899dd8ff7445db83b54311b53593c8cf23dae7ee9f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b5a5a1382d1d88caaec3262a614216da798e5f": "0x0044c061f50800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397462891ac9ea16c799f864e308c7e73829faafc02": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ad5c6ec30473c916e39a4098f252d8f2561eb975": "0x00ae9ee8812f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397343f61f6d7393b93a6693b0114b8be1fec7fe9b5": "0x00d6de0f830800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339716af41d7d554e5814b2a906b2ac27bac06c9a61a": "0x003ec7d7905d48000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6fbb8b9ba0bb75bd0f6109df41a2d22a6f48566": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890040c3cb223f156e97861b8afb63fc8f62e577b2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890150dea99371e59d756012651a55cfe5e7a1299e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000b07ee73f21b4946786178085fcf66f760b69c": "0x009e4397200200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c2acbebe3deafc493391631727c11da323aaa8e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894f9623e0605ed7294195c72779b378b442834633": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895ae20bb9616cc25af5dfe06997d4e5b8437a7421": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51faac345842aa79367bfd9ff8853732cb4c010000": "0xd8c7102e0d36e57f8df5a97e7ddf1d194903a45378036d95d25e7dfe9259847a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d000dbbcd4f4f6dbf3f62581d050c4b9e0f23ab599a59502df2e0cd0c83677746": "0xc8f5bda31f9c72d742e8763200717a78b8081be8", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7c911f087ecbd131871ac6262c81521e5f32f5e626d30ffb35456a42c0d95c35": "0x00406bb075308305d80cfa3e5121ba4354d200f6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a974c739d6a0f8bbf598f8da986f6667b347eb78": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004f7dda0a8e0054890ca92e930239cdb6a6f74f": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971749564105214d51d63a7a2c1178203a4c0c4671": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513471c945df32d458153154909e5aa95313070000": "0xee94ebffc484d8d283783d8eaf3080c5af24811ad9c23a9cc52d8ec7f928fc2e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d9bd91673fffca8936f266f14ebbcf940f684658": "0x0030c374696c080000000000000000007e72a10d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ab980e9f3b036a21ad11568aa020f6ffb407067": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970062633756e91d8fca9dde56511e65f7a1d73298": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517edda4d9ca05bb3d38fbcd4f065bb525ff050000": "0xba61cf8a989911a9a3f51ddeffdfb15e959fdf99b1dc76a3ad576243dc2f4d7e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51085330ee641d8c10839bf3f58469705a72070000": "0xc0b8e03e1b852120a5cba39dffcfd8dafd1a882472200210c3a8e6a51bb1c02000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511c2611385af81e1c51937a544823048ddb070000": "0x22fff76bb4a0a5d66cff0392dbc083abbac3b3046f6fcc328abf0ddd16ca083700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510a3100e4191acfb6632e8219c803535687080000": "0x8f75b9f984e23dfacdb81f0bcfc56370a0933a026545a0eb04df04ec3630f74700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1cab702cdcb0a445bc6b19ced6efe6d911adfac": "0x003e3ea46d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928923c93d5b4d09093d82ec6b4e62505071c3ef00f9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c3281efb7dcaa9970370a2a5d842c3616f815ca": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895dedb58e1daed431391fe2f71a4296ab37e01462": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51302048fee6c45a3394d281a0b1fb09e7ae070000": "0xb87e61450d3bf5521e5c3f466faeca51b8242ceb29296dffeb4cb9a92312717800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243eeba76f589cb390ceaee0f15302f5cd567a05b44": "0x00e8212ac29708000000000000000000e296e70d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003e07c10cd803f10f33b0a1c470a8e3f7e326f4": "0x00dedce2d93f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b22169c960de13bcee687ffc210c714aa77235": "0x0076e6a2f50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971de627e3faf8e64287bd2152ca027e4eff582790": "0x004e6904cee701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b78bdc1a48d2186c3a5c3c8c0892ef47155f85d": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928903b98c95a07743243350cc5eee4ee030e8e09d06": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d24e1cd7f14516acf2a8ddeedac439da4b58536cf7ff061690f7bc921e1741a1d": "0xa3182c6b3fabe222b3bc13c912232d037bd765d0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef039c706c593b89dc9a9113f96430cdb47a592d": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397678498badbe31d20f718a303e51324a6d039e7af": "0x00fee1cd577700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928907b8ae7d128d58f51815d99b751c0dd9b6cf2d44": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d12810d0b133504b5b0f6174b2ef048eb0cfe1b5e45fc7b4e422eed4b2bc18463": "0x97883f6fb7483a6cb748a647f23b601fcd69b393", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004d1fe43ac70412e62d8186e8e0cb261d6c602b": "0x00d6de0f830800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ee41bd5428594191446fef91d5b0de95706ad49b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a8b4d130af9ac6de034f80f4899960283b090000": "0x60b99a3e1fee8d744f08290a2ade61b26e044862efb7ca60dc0c944ef9d9aa7a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899af1322b1526ea42be721916e6ba232b4f001fd6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778524544864e0a83425ad4c8408f81dd55bf7ed5": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898300b3ecdbea1e3dd2d028f566ecd7d04627a3ee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898803cd717982cbf4036d0ecd1925f13c09a11a51": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c43b0c4013131b17eccdcef96e6c873a21c3d087": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a42264114e13a067ac2baca439e9ec5df20c8819": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289818c69a3f3bd436087ec101f0ff8aa2d3cd35e62": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bc1da291d36c0e06b01a1e60fb623af909070000": "0xf05f3ef3586fa4012fc8249571cf84792d3dd1adedfa603f719edba2a142170e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516d4d72f93e42b6c1df699a0249e217bd83060000": "0x3a1c2b4df870c87d3f205b720185a9e54176207b9c52a6803c82de6b34332e0e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d385721fc43fb4262c56a1d6a6e8c07c64c7d7fee8b27c023b24470902bcf462f": "0x9c5faed48240954efe9b5f666d1b6df1de3fa2ae", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ae16f3f5c84047aa300e066774a1c3001b50c35": "0x005a3db8ca1c00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510d999ddb2a0ee361400233eb513e9a0f9f060000": "0x7e2928aa326bc909add3e91fc8389d76e6c5fa1d9605edb04d657aab22e5a25800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e4465431b88b42ed2cda2b4d4c50b38ca1ac8f83": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890028dbe0396e7c888373dc2bf00ec85c292afd84": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d523eb91d3fc1ccd920cc991e39c6fcd03d3ea55a6dfda2eb971ab595987ca379": "0x004e1ef7504fcd7d982885efd88d190d3179fcc3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f882d59de84b2bbe5a37dea30d6156abc2624301": "0x0058823c772100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519b35a064c057e6048948a8b01ff822274f090000": "0x84882d133a24d5f846dbb25597744a99f71327ecc0dd6a9e6ed54fdfd3fd173e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397250498d076866e2178a28cf09444f2ab34d57aea": "0x002888565d0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d24d8e5836c187481f76ab9c0a7ab01a912c31": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928909bb2615c8f45144a7d4bc6d06c1ea346b8d3063": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928906d2ab1ed0c25b0629d277afd6fd928d232d41b2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da0048e4648a919387cd0843a35a68bd6ea9a1418927eac08a6f7bc11e3f38a46": "0xf0b7319293c3508cb16215561b7f2ff539bdebd3", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cdffcefb552c1638915cefa56d551c4221e5d6d0": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd249dac11030f2f8f76370724c3362701b312f643c313ac3badbce5d5634b61b": "0x4051efad9288cc12636868e4302397a4ba38478d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cb55ab5cdb7797b8a44a76c4d923701985df4d": "0x00f80bcffe5f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e59ec81fbd604f8de6eefc90cd6c155e0cc50e93": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243050e3aa7f5b52e7f547821ffd5abd8ffe6062a86": "0x0080e03779c3110000000000000000001e99be1c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771fe8590d29d971bbbbb17342ea62a3c52c6ed0b": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d60710d0e326430a244694534e75250dff666d2a8643daa19aefddc39aa5ade05": "0x00600ea2eca09b387d5be17a4a7df47d956e1ec4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979fbaf540fab13261780b0eac3e1beafb4a923bd5": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007843ded6c179363a1dead9c1fa8acada60528e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896d508a1452fc1ae7b10b6e858d75e669536fea16": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b06d958cce8ced5b26ea37e63d26a3a3a0d3ab34": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515cb117dd9aef8d203bd41de446a01d7831030000": "0x28206efde24bcb2b8e30e1f36b1fa31bbe821bd61f5bfab0b8c8e7c2a0df735600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892f45d57c49adf2be37f4cda720141fc9cb6236bd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928994c70b28e483cbfe9d7554e211f5f38ef9435bb9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970068c220ede25b44a185ba20fa5f540928adf5e4": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a48d6223b001e03cce2b775a968e5199a626434": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7687b89809c7a3c7450a60f94b3f5e23b2e989312f14c3e521506479e4883c1d": "0x081c8e52338007010ab569afb8f1e098e645d3ec", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397142f4db6d6e603f4c5990723c9376300edc964a5": "0x000070ca7d0f55010000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513c29d375bbafa9e6a3ad4cc709b72207b4050000": "0x74cbd10ee9e9e9f772b6c60db076022f568dd36388147e08a99ee3b5f347274900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1600e09e1d8a1324934f83d55d5f6f503e2d91bf4270eeaefd462f24e4487e29": "0x4c2d79f8483b8fa0b0026d39db21dd51d90021d9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8c167731c26d3dabde6783daee8735ba0408190": "0x0092013f348a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5664b93ad268393d1f695c4180993e60c59fc3e": "0x00d0c4165d1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970092dd784a50e356b9e1705dc780fcdcd55d78e7": "0x00bcb9c7361300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289741db5b3024790ff32fea3591714c38987948dd8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008fd24707883affbd4c830eee85a8a4149306ce": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e5bd25b8ca7659835bc91ed7562812eff9352dcc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac4d821503dff89c3cee4e7797926ae8b7db2554": "0x00868bdcab1f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008d3af90dba667b290dc64a97f2711ed3a7039f": "0x00ca91bb010500000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de2dcfc052f7656cb9e107a9c2d0adc19d2c206bc51e3225ffffca10b83b8c216": "0x298679f84e404ac8a9c73158ee6fa4973eca9abd", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397377e7e59dc2f5c9e08d0292ece47611b515dfac9": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb86edbc8bbb1f9131022be649565ebdb09e32a1": "0x00b22a00be2b02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003cefd9d6241b8d10bd2e4d9047f6174a4ddca6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e1738f0a09511622e06dfede9ec64201bd394e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517844551f1b04b8de61f668dd3be7f1fca9080000": "0xa653655826c606e95ea798282f0e700f22d9669ed58fe5279acc79f03f2fb34100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ed4ef795465ef79cd0fcba0f6ca3f35a1ac1816": "0x003aac1de83100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3b383d191e038b067079e267bfdf3c70b422a18": "0x00c2511f187800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f55dbf691b3e67bf10853c67310a10c60a5834e8": "0x00b2cc7a673000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cc404b72cf3db9dc45c5abe72c585bce0f060000": "0x36a5433f5116598c58ce3400f6a2a23f6104fc92b5c30e4610d86110a1ded03900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289553581f31faeec2ffb2119e7ae41a257f5ae0c44": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bea1d038be0b029dffb599a396eabbff2584b2a8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979833f0f9247ee62faea47d6fcc838e262742b95f": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894ccf6ed5fb4b037e92aa2b61cb1239fc6572d0c6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289705fb243cd2cdda5ffd62c702fbe2d48353e3bdf": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510a7d0a8702dc71aceb8b8ae21924f37c43050000": "0x608143776c6a638a7732e342ded84da6ed30c006087c12f022df56b74571e45600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fd164dfeaeafabe0d241e2313b57ea7fd97747d9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d38080b924384b2923f18fbbf77bada41b87d9852c8703aecd85796c228edc00d": "0x2b3d18c655353ca14fb9d4ba8d047d08d1140974", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dbe2e4f5b4322a6cf5cdca229febf825a21462ca": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516e5504e4a14344a1ed47b04fa0dab65e71050000": "0x624f523610e459d18d7dca623df5000f61e7ff083aabf4358595230f89c5e33200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243572613e81421b11b7cf99fb41c3bdcb915a50d31": "0x0000c52ebca2b100000000000000000030fb711f01000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518d23f57165f60c0d8d4baacb420426ed4f060000": "0x1f206f7c890fea0cec8c819d1a9e302849fdc7b1d54e8385895155e1aa4490ea00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c6413b27ddb2809bdd86034bbff83b1e0c070000": "0xd2cd0bac7ae51daeb1c11493b6dc337fa471e9a1656f8e86b066c6fb22af282200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d308ffc25bb1c9025b53d9ac651ce189b9f4588a1981eabf55f0949231740044e": "0xb422b17a216192f8a25ee6d08342dfeb3e05e6dc", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5e21f84db1d346670f5ae35b49fb1ed8ce2d6019ec1591f1a0a593c7e1e42f03": "0x2fc342c182bd05c93bc824952d36fb4316392684", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f9eb393cdc15571b243d3e211d986db3c0050000": "0x88fc08d7997cf899274ea31d6e9f6c883483b95ed1d489575fb1523d4291251700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c490c98679eb8687f2b3528d9c35a67e99080000": "0xe8b4be3ef901eccef4c3abe01bf1af20d6685d42d644d1c0a6f739207dd9c06800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339756666fc53f50972d6fe7d75d1149ca3ecfef486e": "0x00009573c24800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5119ef188735232ba892b9d69c9f259a20dd050000": "0x1c7a132e41c02fa4c8dcb647700633c59d6fc8235b867d9422d1fccf24f77b4500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519210ef6aec6a31a339c091910c3dd97ad3070000": "0xccca577630b892c34f36d9681dde7ba25bed23356d467e1415913b7e2515755d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ed9633f73160a3c6b6162c5c91ed95aefc29525": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928951aa47c803a20a6334e4589ca76642a68d3cfb32": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700acc0bd13770679812fae76ceaada758781a5ee": "0x0006bb3ece4d34000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d033fef6d4c75ce2f4878314057c2f959fab4679": "0x003e3ea46d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975223d8d88e106df03f953b6ea1fbc11db396f2f7": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511711f4961200de487c44eb8d835d2121db010000": "0x14d13395a032cb5e4aba7116449d03472be74a0a8ba9a6a97723ea6bede6727b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c35a8e70b0530d2bff51daedbcf752d8dafde91b": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001c57173ef5705bfed109af15e677a8d8f5e520": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d5d7db3ddf7db52ed81bdeb09e2517f710040000": "0x9032a7c54bbe6a7c1c9ab89364242a3d39a725aa880a38110fd92bfceac13b0900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928956666fc53f50972d6fe7d75d1149ca3ecfef486e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289354b2ae0cce6f0ed8f332f123d4367bb800ac687": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bdc058e69ad60873787e67fe22ef40e6a82032e6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aac3bccfaddf32b9066fed9a76f0694a471e8b71": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbed497470a04ca4c13caccd69c7827e3ddc64473fd2d7c5d496c71061f452b05": "0x441dae5199e8c642556707176913c2942b455251", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bfe488a26ec2e61bfd6a2f59e445980752d634": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cce96dfe085a2673456d6bfb80406b8b2a0483": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339772bd01b74ab575b2bea1ac2f8112a0a15cf09deb": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289895607ffa297db864ec7da7351353618ddaebdef": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897dbb16b85b247430888763302413d6d2abc1ff8c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928985bad1dedbccdfafd231fe1c96b3a9bdd4e2e083": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f670ee7d6bd866b161756469808acc4f2aa64faa0c97ea1f8702fbdf1843694734eee4d7c65c5605c2f8127148": "0xdc9974cdb3cebfac4d31333c30865ff66c35c1bf898df5c5dd2924d3280e7201", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ae6916a981c3df939efe41a37045ba2c0b1daafa": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ae2a64d4c258fb4278cef0dbe4fd9e6d1e639d1": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339795e1a959df4af4ac693c2de538b4b0de14592423": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1b96a31ea448d0213a11aa8c2cda340d1335280": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ea81627c72919ac393603aa79d4c7e00cd9438": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282437d64d09556b4e737f932b39dbbe48fa4f67d862b": "0x00d07afd1c3204000000000000000000d319ca0600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd0435f6d91a7c7316277378edb9cf826f46af1caa25b187ff9e16386640c600e": "0x1fa6cdbeec8b0ae15c81a65c5da6d152a0a6c25e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894209c9ea64fb4fa437eb950b3839a43c99d96c06": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cf6aef56499745cfc8abee1fec089e86dc2e0b33": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900aa83bc9abf0e8c4937a8ebde74a7961f050747": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c5e4db864861d9b6203bd86af0c0b5ffcd6115d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397164d92a6126ebf0f354fa098e173f1a50277fdd2": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c6f3bf84417dd2c0b9c2d148b3cd0639c5b9387": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282432a89681d73055acfac5c4ce4ed108c3ea7a84a59": "0x00a0e05ed2d400000000000000000000e461580100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e8b688cb562a028e5d9cb55ac1ee43c22c96995": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928908047a8561852b8d75e9ce66751a9e0ef4eb2ad3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894b58917b2b71399c841b985727a3ff7fb59547f1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515ff8de633dfda576bf4023c34c5e459821000000": "0x243411786f2b168b5024685ea3474897ef2e77b7599275431ba5229bf657890b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976db74596a7f6ca2798670cc82ac150a41610fdc7": "0x008e713b42af00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da494377af81b9e491c444929c24ae96e88099a23c0e207aa130d2d1ae5897650": "0x9bf140794f7009345dc3de37523f63ecca1b155f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f80791d5ce62ea36ded1fba5e1bf53c15938c9f2": "0x0086ef35191300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de67bd0c0f260a6fb9b90870109b8a97cf0f1442b4694d7c17a6f0ba103db850d": "0xc5180bb2f2975ce4750af769d7a32dcbd69d39ea", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705e248f31370ff8f16c3bb5db186ff80eefafe62": "0x000ca376b6c800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5cec348d901c9a9d931610a858474d3c5092d1297df3fa7dc986faed11c4d05b": "0xcd2d4d9f76f3919510de38109dd63172b05e86a6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397546d80fbdadde160e5d4a3482bbdbf310163192c": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708d2502ef55264180f07970bd2fe83bc206f0715": "0x00341a7e291900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006c0cc442ab4dc5ed006af112fd7e064511eca8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007ceccc832e7d85b6e02859a60ef100bfb4a2b0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b06eb11eaa3455375b66c1c72c109a134580f7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339761aa4b596264f9e1eabf688567e8e80080732169": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289470f765ac9ca7fd2d19b7b68b39f3a3da9f648c6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d17756d5e1ec2bf3d045828d7dfe00edb4c24acd899a5f1e251a86d39c156a204": "0xa38edc99fbc7935f47a5047a757bd870a7f02640", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894e96f9207310a9dcbfb0f8acf5e44573b56eadf7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bcee6270883c347592db909aabcdfd5670050000": "0x9e6083c954f38683706efe10783ddf7522c2d817adb5495c7ec73614c1c8387300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d885e9172fadfb8cbdb532c65d07078a2c9c150bc3ded165da437268b1cf3afe1": "0xdeda0b6b9c98ac5ea010fe9f2086e93bc1514ec7", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824304c6f1d15b8b0d5058db45fc13d6193fa78848be": "0x00706f96a686020000000000000000008564160400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895feea0d35bc1d74650856fdba465a9fd7582b08f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a184d0a2f7d54d4552bbdcfc10d287a4c5bea5aa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b187f9d6ce0329e2e8d12c6ddfe989023abf839d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c4bcf84bbba74f7ed07abf9e39df86bca995fca9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928989af1ab14542363a2c631dac9d2eaafd0bfaf008": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972658a833b04556526cbd6b2caab0a9fada7d8977": "0x0070c7f9924000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51754faa9acf0378f8c3543d9f132d85bc02000000": "0x264a106d7206b10c8a97168cd25b2e0b7fdae7d827b50299366bf9ffb5939d7900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976bd681cda54942050d622af1e35e6e3054eca95e": "0x0094a032a61000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895cb05a5971756ce32ceab168695de963f70b051b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896ee315451190394da7fcdceb57d157d6a3453201": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dde91f855c77aeb4b742c66cbf0f4f852809d98804518f4b3e00ed60437f0f618": "0x9da6c5ebb2a225a395ee772d77ec5178fd5a6307", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b16547a72b4d9f37fe34fd67259d07f65953d141": "0x00cab51931711e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e908988fa7712617b50643886e51ed6ff5333d6a": "0x00124ccdab0a00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51903cba3be22fc94f5c99d88766869eec48050000": "0x90637eb688d85ae50e97ed270439a093f7e3e56a42af1693ea1921a6589a770100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d177586539eb325c70e15b369e1f8510bbd3cf44": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289679ca8cd4ae11f7813074b9337395cafc78ad4a4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cf4ab05bd4e774afe13334b2bd7ef803a2080000": "0x62e11b08e75dca26b32d2cddbbb7c9acccd504aa7dd2ecb41a7e30ff08baca0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007afbd65d5b7651dc8540420ba3ef42ebf62c5d": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a3f59ebc3bf8fa664ce12e2f841fe6556289f053": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397772ea6e9bb2ecfb884c881cd186dede1ae2b63ca": "0x00647b482aa300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dec7861534b86faa8f8ae36a561fae5277da4709": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df68f12537fd063f3949875a1efc2ced4485685e4899a8674c64ac042dbb67d43": "0x318aa87413115388a04d0083e792849e09fe496e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890023d77a0316ae6c765a6e1c6616be7030f462dd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972e40fb968520f859414e62bdb05e5b1f2f6201fb": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bf5ae4b593a56432357a7ff8d8098b9c10469c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df8999d6c00d5014ef989664191dd131f18fee4d5b3341637baae3a9925a3ce25": "0x00dbddada20c7b2b653812577388aea9ac896ac9", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b0cbf6c353bf88fae5f78bdb61d9c7f5be080000": "0x8a8c0cdeb30b068e0e3aafe157189e0a93caaf6ff05961dd98d58db11e1e273100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f85c6f6c7e5d78513fd9317d90409f71a58099": "0x0054a6b6228506000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fc7e4a74ee62977ee61f7f301176c539dc060000": "0xbc1deacfc7e5c6e5f0373560c14fbce156ff2a0ed7e208d049ccd985dec8554500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a1b46319be9163b8ae30dbe506235608a563dc": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5181d8b8684bd24113d792d4dc3d9c2a7d4d060000": "0x7ccfc66f0b7e76f786bdcaadccc5171ec82d013ab65e33440fc6c1d92c07d52100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d00933f6ead73f4396ac3ea16dd9988dd6b9b8b9309e2c8ffad113ee7f6b9f421": "0x460cad37045859b3f67579bb363d3e8f48c4df50", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9c65cc13119222af7653d69ca15a6def918788550819c98d5232841f7ba2db6a": "0xf55dbf691b3e67bf10853c67310a10c60a5834e8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890c50ea337609096cd614dc0752ed130e0de08757": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af7c56140a7017ea7fa9fccae6341dcf50ba0556": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970052b34370f45aa1a3d93b5837975bd9e088d6c6": "0x00e47f23dc8200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397caff66193c177e60ef230f8c45a5867ca46f578d": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785f0c61774dc981a07fd9fd76f45c336fc87b44a": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898e7bd3dc5a41971455a7e5af99c3ab77766b964e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972fce155ddf214a56eb2e88939f2a48afb4b751c6": "0x00f0f70ff55300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b999004b49c6b907d4278067da5c85195dcd7fc7": "0x0060aea3230606000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397589c431cb0e9255b1fe912079034ca6711c76eec": "0x006c9bea403b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ad5077d22fd0309130fc1a1ce0e655ce4de9513a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005b2da8bb885172492b3f57a510e3a90526c637": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d232ce096d839fc8519890b596ef9e99e9040000": "0x28996c52694155d7ec9082650fbf108f69da60c44a4b2565fce4e03f9bbb017800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d84e6b806bcba1f9f0255ec9eacff9f4322805b842b6e02e00f469cd5494eca5f": "0x00928ab46f9251610992b3f5fd257cc031f354ba", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890028b16bf35427a11760cc5f4db866dd8127be14": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dfba60f29b3caff9e6942494862994c277f05d": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b3513da99c0572a510334c4256b99ac3a8eb72e": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700eb8e47a06707a3dfb17728f8961009adb88eb8": "0x00ca09fdcc0700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ebbdf1db3c35a492db9c7d6e9c644d4a8d070000": "0xa6331c5c97cbbd671ee9023d3a163d81e965dad7d509f28b970dc86c6f3e985500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900aa7d705eaf0a79ef8f0eb9b8c4b80b885205ea": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a6d4b980ebb41243978f92316777792ec14fff50": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974118b3011a348538694a2655100db72e5010a0c4": "0x0010a5d4e80000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518d0279071dfd8cf4d5b40c71fd0aaf8c87030000": "0x82aef72a8fb431d49db51e0a208fcd679ab78a8b8c88dfca61b28e67a8f56a7500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5113517fe5c7f842f1b673db986921ab2a25060000": "0x2a6821bd42b8a9447c08b522c8b303f1c208dbd014484d3ff30fe3ababe7f73200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890e5b7813fe019f6aaf820546035fcbb40b58125f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339706d6ee9ea1c648071973cde4669d95955d496422": "0x0090add11a511b000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517fe61a749ecb0ca5b2226fce9130638681040000": "0x6eb77631f65ea04b3ef1407b04dd59a50ef6af249eba5d82cd61604076ab067a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511e5197734c803bf26eb05eab6c0620fc9b070000": "0x484cdc76e0b6b2cb4e30850327cf37e717d91e343a62bbfaded38aa8133cfe3400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006a1212d2d3e63753368cbb4116ed4bf3719e64": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5173a87ec39149f52cfb4a42511fb5461343080000": "0xe61956f7fe271404c5b0cd4b155ed105f9364f4ea7608cb6a9c127794b8e3a6a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d34f4f4236b04e3bf83610b55d3527b50da22aac3ca85ea0d520196835964b67a": "0x0087c431927e0a49ac8908026cfb13d3cf96b950", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b0efda181dd90a361cc220d5b9a6a12b38a551": "0x00b875ca5f0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289482b1c8fcbb12b90573071652cc5d46fc24fa426": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fe585adf04d3b20b6fa246c2183a20fa20070000": "0x6e747c701718b04a86a4f693a987662fff73f1cfba6fd907d86662725c82470700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db6a52f2a63faa6a7f88f1f77631e712948d098d67087168955bc4d2c4adcb01e": "0xb27b940bf01de20eca4abfd7c9bdb2304142ad5c", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51000772c5f44ff1ae5233c073e4b0b85d7f070000": "0x66b1ebbaeb6b2beee0ef60ab899c6a6ccfc7e3cbf820e5be26f561b44a56832f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e2f7d96ae83b7967015b3c483a070239f74baa6b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009f33693d1d3fc5b3eedc3d9d457f77059a498a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b059b066f976d528172c8d6cc5257a4787266012": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef9d64a965dbebd8671375325a0aad9358218934": "0x003c560def4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891cc55a8304d1fab6dcc1003d16783eb213620293": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517a7077e127e555a197899b3226a2f5d361040000": "0x8284b7cc1e21c463fbe2e309c8cda79827620863b9a26a7445c9daceae91a77800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928944e5715f7db1a59de2af178cdad023b16e39da31": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eb0d43ba23028b7db38d8d6e2e2fdb56db9c0302": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d981e0c8001f0d80ef450c0c0561f9e4b22337af479023b9d79851381ffbe0348": "0x54970d8d6d8f8dbe9c87ab9cab9057fa5039e4ab", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900afdf133993cc0d4101f56f4b12a0504024bfd6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d42b941936ef857f9d5b97908ca6a7f2c0fec05c6dcb763f9e8d7780699a8b23e": "0xa50382a9b22b0720698d39131fcbe289841a54bd", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515ee1816cd74736cb5de980afa2c2245516030000": "0x126647690e4dc7b7b7a0705802d62342f6f759578ffd888ff6a60cd1708b3a4a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51408329977613d6e5213ff39c064b948afe040000": "0xda1858f63aeaf2dc56970d9071cec207978ece8813a381174c0e36dcdf0eb06300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289efabdb22a54dbdc370b31156a16b7a362199affb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d581b789243689bc3367ae7d487ef44b695892c6693e3c9ef8c4ff95fff99df17": "0xf2f3d21866a3167be7b0af44dacb2e496c5b827e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000b6274e5e9464df801fcfd8a9fed607086fbb8": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcb97a0426ba454b11a314f7c9d9479cb519eb93f8c79032abbede30932d67da5": "0xc0b6a53433a49d2d9aa4817570b9ccfef4764cec", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac139d4ae0e405462f35f4a5f9238f39844cb982": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d3fdace77e1ceca5128ff2f9269bb27afe9dbe": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900eaa3371c03ec84b98706abf06bfca8b85956bd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c094df9784e3a409a27f39875a85d47fb9d6d520": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928921fa2fd0d1126a88a7fcfae18f8fe849999a17ed": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515138b420434e5e73b61d3fb55e1ead102e060000": "0x48231493044b6f421fc9e9ca2d9f1f0fc18ebeea1d51035a5843b82a70c8810100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514943cb510c09eca48fa3c9692fb19fb0fd050000": "0x5828b1463a98785b431f8bfc4806215f1d062aa098eeb76b09a80fd9e63c9d0a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d62894f873f68ec0788abb573bf388efcc5267b7164b770abad90cd17b65f161e": "0xd89384c4107f7d0feadb833e769e7e1396eaa5e4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700edd7f8f834eee9eff0a602e6cd8c11ab501e4d": "0x00f424648f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003d4fcad4255d3f37dd02df6b961b352298a023": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009cbd06cd1a0812b83234ff4b16d4561901dadf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970082edd0064f00c679183e5c014d3b4a77a4cc67": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bfe488a26ec2e61bfd6a2f59e445980752d634": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d260f09bf8836b84b88d389cf793389a6387090d930c1dc555789d94b304d0934": "0x4f65d1913b854830681e7d0ee71c9756e0fe9f32", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517ca7f7515e8f8ac92acf8a63e99aafac75070000": "0xd0b18c9b2c9b480b43aa8f03d542c1ee68692cd42aaef3c46b57ea19cc9e6c6a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1f4258fad2126cdaab3266e9caa82bd51692980": "0x00fcc39bafee00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928952e0bb68c4b18ad158ac8e9489378e5e855224f8": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d423185717826a19d375e259a844fad640a1bda720f14e0fa7c74bf936a42007f": "0x1fb5b702b7d3c5efb00630e8014e79bfbbf5ef81", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974765d5715c351557d5242e3e6af8e1365ed5d08d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d7b4f68efe1aee99bc58f9a511f43738fe5b0d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5184184784b77281c6119fc4c7509a5d2d48090000": "0x9097fb3f7e7de0007abed486c2b5860e7de0ccf395acd0b1a0cccc124b2b710b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a8c2c0007f4f50045241bf96aa1934b0dda2528d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3bbc9586ef4c2baa9cc995fc50dfa7118d35dad": "0x003a3ce86a1d00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f7a288ca1191026f22718d61b6acc3922a070000": "0x3c803d0e3f20e39f3060761bcffc56363024d98234dc248583149be800647c7e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b187f9d6ce0329e2e8d12c6ddfe989023abf839d": "0x004043148d3703000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289af7c56140a7017ea7fa9fccae6341dcf50ba0556": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c74a66dbe1c89a65c6f6bd4fe20d0f989e080000": "0x62168680c9ed6e456fa59bd01525a53dd6fa991757e920482016e7db6caebd4500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970008cd3b0bffddf4b7f4528c58db5416eb998ac0": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928914edaa223bfef22b1af6f5500fe1766b15cca12c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970065939d87e6f958a20873ba9ebe06bf120a2d33": "0x00ba96511c4b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928903fcec3a20f276aac1f7967a461301d75180371a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d79cf77ed776c7b4520fc4f95a21cdd75a7b9b07": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512ebe852bb554f4b834dd8c6fafea4e3a43060000": "0x5e17c90f875b62d277af6d0fd9ed6e2258c8627ac561c55ba7e193e6fc18d83f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900294eb6c545e738597385f7cc36298ba90db70b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005c3e8ef86d7ec80976e586dc76f8267fc8368b": "0x00245b38281600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ca696ecc735a7a734fbce108cea75f8e982cfa2": "0x00349949982701000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b0a37554976f25303adf7a715fb050f7d1d73d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0450c35fb5d3306a120893b253cfcc588bd9f5d0a30e1250b2e15a39a4610a0e": "0x2ac9bc183534b782d3f6042cc77b81cb4656bcf8", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da2341ada39b90cbfffeabc35096269f14b5de2e50446e16ac26d8b02a0263949": "0x57ba0396c511c6dde22e4c524c07b85411d6d05d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397edf039c36c3fc977c8830d68d75d989d42ed1827": "0x001ed109850900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513e97e7be528dec396a0fb0ab5ac4b3eb46080000": "0xb32770b6f97f03b60991eb4d710ad6d28a09ff4671e8b50c6f6347edcf059d3d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ba325bdfa51320407c91f0323c303ac8a01cd7": "0x0084e236679803000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5189d6ee3f9fe80885b62b09dfdb913bbf1f080000": "0xb6a52f2a63faa6a7f88f1f77631e712948d098d67087168955bc4d2c4adcb01e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f369bc4c5edeb597431e050a728e981dea050000": "0x3890fe49cc68cb8567fd01fcea08055b25b3cb1d8fd1c37f2896d3819ebffa1b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b91355280b218cadf3772a949f0478880594d0": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738b89b94dc5dec100a23fae5b5140ffcf81c8b24": "0x0080a1a76b4a35000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b877e76f8fc58370a3a94259c232ade145070000": "0xd02c1edcd16c17e8e1a9b6d3bf8c20df4c1427225868599d0e11da1442eb297b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f81756700dca9b2fe8d4269a761206ff26ca95": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2434fb99a4b3f7768f861ffef0a7dbed086174caa733acd2cdec25bbbcdfcc5e": "0x50e36dd2f9f0b112a8eedf160bdd4aeee06dbed3", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a140372769316543c7a6bb5bd4d980ea00050000": "0x1ee80fb1539fcc03433b535fe90ca636d1c77de813a6858edbf802da6bb1920600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db0eea2a1f67da637fd1fa8c1895d15ec763c789567cb02463c6edb494d3af07b": "0x0d567082d66dc9c1cd236a3044a92c5b595fbeb6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750b2c3a213d353c66a2138e3f21a1f909b0a87b8": "0x00321bb20e7329000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514671f3b0f75141e3511b3597f3223e920e000000": "0x543d64b162e96ac48944161ce5c2abe57553d0720979cd90030ffcdd97ddb25b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397594a1a912ebf1023bf9bf1b0e77d6d40b8232323": "0x00cc3bab081700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5124948c0be687f0cdb4a252c20fff128cf4080000": "0xa47e84d64df494ecf1a2cd5c1b2170c23dd39d9b7c416a34f74ee809e929660d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975fe82ccf847c7f2a0281fac8fd9bcfc7ef245f9a": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a48bda48cdcbdd257fa55b7b7985a1ba61d9e1f3": "0x008a39bcaa1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005cb064be2ae806ff8a6eeba102978d6b32d625": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890078c6117d6a926565915465f81e685c29e31f5f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900908f63171b29bd00a69a2c0864318843bf169d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891e768862e1b8abaf3c1c776b032036c7b774de85": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928951a1bac19e5fde2dcacf1024a16aa62f8302617f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e96f9207310a9dcbfb0f8acf5e44573b56eadf7": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928967303886cd4d268eaa3a6cd8de51413da1a72dcf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928970c853a88dcfdf9996e60d3d33f3002ceddf46ca": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ffb27ede09161a4c13d4176afffc9bcb13c97d0": "0x00005fcd95f209000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891206a4d89194c3fa52d2e48bddfd64f38cfa7a53": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519211dd747b759929404027144b4f609024090000": "0xa0c2802ba380d41dcc343cbf730e65bb198929288d6577799e9056014079bc7100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a6629c7691f18cc987a61b0774a524287b5d0c": "0x0004f52ee08d00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517ac0ad9efc83bedda21868ca5c18af5fe4040000": "0x8889bb12ffc22c93e6190aeac259184d7181bed3f0cc9938d27315f8e61c8c4a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974709a3a7b4a0e646e9953459c66913322b8f4195": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890d5a35d09bd00dd0d73928aa1d67c266bfd6273a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e2021221b0bb5e2d1ceda9f024ed9804b055708": "0x00ccf483926900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe7c8c647c3574eb9931d1d3f36019b6a6d06e2f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002d43afbc32a0d67168a2de3833ec368ffe8983": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894b78bdc1a48d2186c3a5c3c8c0892ef47155f85d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ce971552082e64ecea872da2bb4ecf8549d2760947c952722e8d8684dcd605e": "0x4e9763a3ac1928e281c7776b41aaa83b558204e0", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896cc5d8a4f16d0dd7122bc1d2759703ee9013c237": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289987901179f790fd04e956173d45fcac9aa74b66c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976afe9576ad00a571d9c04402006414ae45a8a490": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899c00bb75cbd8e55346d2fe041c632d5b6cb6f6c4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5105c6059e87d5a826532adec50ef822253c050000": "0x86f68361d0a346a62be267558e72dfb9e3b5a04adcc2c9e46fb7b9482f7c876f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893fce4a3b54b4ae9acae0c1b7911d4511e01090b6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d1200ce6d0ba222db35d6135e051267d901f44b1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6b58e5a157b1d1aee043e50be138b60bb41c478": "0x00fc8d0e800000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ac2a0ac293d17fc58e2ddbb25e08b94313080000": "0x827acec5295bdb2d134df3a5dd2e8ff5db1d3eb75c5620b3ec687b24c5be571f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339745602bfba960277bf917c1b2007d1f03d7bd29e4": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6aaac987bd9fce6505fb58c50175ec3577e4b1cfe4b8632ff68ff66000a75847": "0x0efabe80d1646ec4d11f46d8fed63b070c11d5f3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977894774b62144bf5cbbee837c96e833e16e3edce": "0x000cf037d88207000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c52fc440544c4bc65fbeb7233bcf6874d2040000": "0x7a848efd719f7a216be0e7ab86944c5c23bd0bcc66216ae6a0aaffcb2bbf3b7a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f527277ddc787974e57fc195a0ed5c86cf5ddeec": "0x00f85e3055e100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289afab97a2147313fa873dbcfaf175aa1f24c8cbbb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b1b561896f65cd50341459052a69cefb25673451": "0x01", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcefdc27aacad24de17bc8753a3c743debf7925f382a6d1c08601395aa679995e": "0x319112568bec6af88d43c258f36d94319bf1ac23", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928907ff3463620606e7483f074c44fc25c32383bc79": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f3181f5237629b697ee63a8a25636281c84e0a9b": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950ba9dc4b69ca46fa26772616e8048b623941c2a4d41cf25ef495408690fc853f777192498c0922eab1e9df4f061": "0xdc9974cdb3cebfac4d31333c30865ff66c35c1bf898df5c5dd2924d3280e7201", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007ce39c82c2cf3d1d4e5890abdd3bb51567e469": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397687f956a18fd757f21ff2c1f0334c589a6bd4d1b": "0x00cc1013714900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d106711bd6fe7f02667ea334ff74f06788939959": "0x006ee0d6c48800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900642d51e2ef92650e2c7308b4078864ab0d8603": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de9c6d2f52e842646238aa9a4b144820f450c5c55b0503cdc92dcd302cde08e9c": "0x081dadcdd7cc5d6f406061007a6b4af00444e75e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397679ca8cd4ae11f7813074b9337395cafc78ad4a4": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d7d53f3b0307de42d7dc018f672f7e6af34a8194": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339715010e04d91ca1a9374a0cda2902039d362fbedd": "0x00b4d5fea72c02000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1a4b46decc58f38eddd3fd8f8b7a0a92b18ad34305d8d6f85efcae77dafb255d": "0xa640c639421c815ad2e40be3ed98ff0eb0e446b4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339734e8812c8f789cb9dbd6993cecb92155a6af62ab": "0x002291b31b2d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970087c431927e0a49ac8908026cfb13d3cf96b950": "0x001869bd150b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339760984850ffe55a4c330723b7b439f70e6184bcc3": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1baa453966c043ca367ccfa19f450244447b9d32f4b7af2d9749e55a57ac09cc": "0xcd1cf598b1a50d24d53c7241fedf2de60f489597", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001ad8e92592570e989ca076e2d5e4c1638cd3c5": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510cfdcedd520e320205f5e1acdf6ca3552e070000": "0xe4cf3489002e8064b9ec479414290e3bc4a87095b4b1a65cdc3ef1e06593d25600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ae7dfb217953af11182fb68fc210c9ad11adb39": "0x0068b3338cc900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896deb669e7db5d02735d5a4f14d622a09f6d27682": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972da865b913ce50451351a315d8b37cb87a4f4109": "0x0000ef73b31600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518f7539e4e2d9a2274863eaa78b0a3ee574060000": "0x2a4252f6d64dad6c3c4b8154a21c2103f6271822a5120cfa4725fbb7f7372c7000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900eb4363d35b0824c7ac8b54c2d05c6bf54b9946": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894a6a90222087648297e923b01d86cd754a7e7f7f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5170c73a4dc65174edfa79804f522c362f9e060000": "0x2c01c997b6df6a1ae8a1475e6cbcd1f1c8d9b60d2b4aad28868de3e61d837a6800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d788bee7fa9fd8731e80ceec5614e5568781b75f54b34d72fd1b07f0e185cb728": "0x001720fe2bf6df9dab32f313343766cd4a0ac2e6", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0061d29cf9d6d397701166c8c1e07d742e1852fd8ece9731f8d1fb9243bf131d": "0x520ad81a6359835797a4a7b0b0cfd0406a18f64c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c5de4fee9a3aa7722f7d285c6cffcabbc760ea": "0x0020bc2b7d4d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894f8e35697891efb39506e932c9084a855ee53ef7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e4d4993cf7be0b894bb458dff9c2653434d407fe": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ec48f00c3ee6fcdf2ccb4344de1769843e040000": "0x087e2eabc4ccaf442c1cb9fcccc3e09560cc0be2fa17f26b3d5a08b658f7db0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975dedb58e1daed431391fe2f71a4296ab37e01462": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba90e5b6d3376d792ca3927524c27a185fbfb159": "0x006aef77a62d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f65fe2f2d8215e4dfdaf150b031259ece9998f8a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928945271d8057632813229ef2eeb585a3024d6ce876": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900624c215baee850f4182d0602cb938bba095066": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009b72735e42cb02b19f88204e08931c633be665": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eb2ef83188323b61e2cad0ad628bfa33e45cd0c8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928916c09044a80d3a419403362413241ea81d5fa78b": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5167469bcbd2d9fe430c985c02435c612f91040000": "0xdce017740d3a4d978b15057144384c96e46691410218ac91cec8be4f7d67977a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516c70a7e8301b6362a779301debeef49740040000": "0x0e25c438529a9db85e8d1d45020e02862ad22f1bee84a0713895f20ac765624b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008dc499df64ff95fd5b048b15d430ca0baabbe1": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928968476977382d9cb85d11775b79252ee7d2859738": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f09452094039cebf83165008759d201e7176d2d3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289516ca63270b7d253cd9af64cb9d92d62de81656c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892a9184c124058289cde2f114180733a9e5b29724": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c4cfb90d630bdaab104b05386b6f7aa3574263": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d168878d025e08bf4d1d68a950034db16057191cff93cc2aef5603816dc524640": "0x49a1c510c50555b7be6e68e064067038e5499748", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d72a974c2a30d8f9cd9e000b31d94bf7bd39d93252c8b862a3894c191554a284f": "0x1c20dbe4d8839b6953c7528824e42dd91ff1c564", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e45ee0163ddfc1fe2780064ffbb0d0dc2999f873": "0x00fc31262e1900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4e325e0ff51a61d129d2848b0e6a5324bb42471": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970098cda511c8a1a04705b0e22e81ffb60008a21d": "0x00a652dc520a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008240239c06fca835d97696c23a9cb68ff4d5e1": "0x00923d997d0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890037af14a08100231979898635d6fe870b1c846f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a7dd8fc58ff94de5cede695988e78e5f3fb3df2": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daeb543882dc06d0cde4ef60f889fec6349ac00299bfcc2b2e843aea1c7811a38": "0x00b3b6d0e8643d53b6b22807385fa63146058f56", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900116621921d8a7b01706539d19d65ec48dc7dcf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005b6d541644ffd62b7c61884bf8651b1e10e146": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892c400a9c0e85fec5dc0607362a1783e0ec224ef7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899f043f875302e01d60d90831ca17593557969b10": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700556f5ccd2cd28ee1f82cb391636d9961cfb1bf": "0x00fcfa64a79106000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bc7d1910bc4424aed7eddf5e5a008931625c28": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de84e22cbed34955f4428ec758aeeecd33185648ab8c187f579cdccb935cacf44": "0x00477bcf4c48a8c4814ace55160c0ab89ddc9795", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc5666fb8f709373953716884e8e3e46537957d9": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f8536ca7a25cbf70df754fa310079ada4c6114c2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928943a125a9461625e72cf17558f1c8b3b653347686": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928945602bfba960277bf917c1b2007d1f03d7bd29e4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d95d6253809ef7c7649c839667cc1996e24d8f36": "0x0034795dbf0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397100dbb75eab5d98ad65ef16483aaa68e68aafbc5": "0x005a2eaf112f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519643018f0c21be678ba7ec1529eb155fb2000000": "0xb6ecb6d155ca342849b05dd7b4f289ca0499cced8dc84cd812b9d9aa4332630500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e613d5ff2f7ed0d7ff4c00155b749984ec0ab732": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51551997315f94f6ae899ebcc459eb117dbc060000": "0x4ef47d6455ac924fd91990a3c5aa921f15e9ffd88df32cf6d59adee70108ce2600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3235f7d984058bb410c163fc1d7a90e5475c0917aad77deb241093a50b4f683f": "0x6df205592f28ab7e1db1ff8e24d66c53e5f22c3f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397354b2ae0cce6f0ed8f332f123d4367bb800ac687": "0x00c0afd6913600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890c3281efb7dcaa9970370a2a5d842c3616f815ca": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397286409bf413131c1bdb5c2ff95c5f8d7379c5162": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928964be1c1a0198370f53b2081e15478be3135d6bef": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c14b2331974ac8706ad674e22f707f34a17ebf": "0x0096e772550000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977956952b9ea6540641fd0dfe110f071d45c835d0": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891d55410119f0d9f4d3eda0a346a43ff04e15b36f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701a7d9fa7d0eb1185c67e54da83c2e75db69e39f": "0x00728e40997870000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289df81dc558baecf13373d4324fa3a8050cb7b63e7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900228be11366ac5fe81770d49480c2a190a9da08": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979cac5a27e397ca42444c2d39af23bff9eb681125": "0x00befbbc765800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d14287358494932512dc188bb7700c1ae44f9b31e251d918a4f9301a11eb6d62f": "0x65e01fd6abad727e8726046f5b55b25ff6bddf92", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928961aa4b596264f9e1eabf688567e8e80080732169": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339788884e35d7006ae84efef09ee6bc6a43dd8e2bb8": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be2fde5ea1a064e4b3708f35c269ac5e06c3eb7b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d99e562b4b9c2a56791089d0b56824b913c9e4509d15da48126e586395b976da4": "0xc70ad716691ecf66e0665397fa4a7ed8f5979b77", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289029cd6683f849069fd70d6e9e7ac4b3a71cfe9a9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928922a35cbb6356055d8216a36af746c58bcfb99566": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898ae1a0bd06aa351227ec269277a43831f0d34da5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517db553039e15ef1f5a08b4555b97145c4d070000": "0x2ac3cd2c26629ff98575e00f181f83a9fe5e801988868fc22ab8d911c7a56d5600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cda6357a43a63683e5387f4a91fc959339090000": "0xb6e326b0768501c103f52fa0e2011501053da8b7a8ed204abfab34383bdae84c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c90efde43639f566ed43d95d9f909697245acaa": "0x006c1a29773d00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5104965c98a35dee1b2e99e32873955006d0060000": "0xce371857e768db4c8e5e3cb7c5b1aefaea189aa3e9f0e708577666535113517c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970000a940f973ccf435ae9c040c253e1c043c5fb2": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397828912ebbc7be3ceb23de58fcf221f171b31c88d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794ce92ac9c9839221b976caabc83820dc33a337e": "0x00b2e809461000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339726496ea4743de7d6927f107151fc67616fc0a4a2": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970dc056cd15bc9857757eabee309f0412cc9c79e5": "0x0094e5cf8b5700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ee315451190394da7fcdceb57d157d6a3453201": "0x0060a90a611200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea53530092af66d4706fb53e7891d2b1ef730b31": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d62544cac590661359cfd64c73c4f33f806d24": "0x00cc2ca24f2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397745e0ddf824ef48ae3506f915facde8382d4501d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339780dc500e1464a32ab0faec15feaec216a734162b": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d68489fc73900b3e283faa5b0c7b7fe49815a54499653ed3ffead8d683f52002c": "0xf61b2a45875ef1019da9bd2353572f00935d163b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890a9c3868f96e8a3e5386470d78f78046e09cf77a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5126706cc6825d2101fd524bcf022b6034f4070000": "0x08d3cd80270b7fcb3d94ca800834890bd03f39d867a9fae9b7335de90e9a576a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002309df96687e44280bb72c3818358faeeb699c": "0x0008385ea1ce14000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e3d5720a6ff59071c395d3205ff5796c7c040000": "0x2e79aa58c609548a02ddfe3e79ee12a11da33e242ecbd879e1dbe389f6ee5a7500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243ec9465777aa326e36b60abfb4a01298a7f51845d": "0x00f0ab75a40d000000000000000000006713160000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744696286e8ba88c8c0f782b33fa7527cf3a66e39": "0x007ada938a4600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d30cfdb48ff7f33b08499dfc618a8ef9699b8345fa65f0b1339eb8eec3c0e4555": "0x00c6c0f1c8825c7ea730b6fc23bceee8ee5a8389", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900718f7d6f56e3aef4ae4d4dca50bedaa4bc4f3a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928921ef1af339cb2c91e55acbb82863552803e1fc55": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f6d321376850f36041db18c5189104c6c97bcae": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000ce94f81d1f81401712a57f615bfd9b139a657": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970069bf728cdbeb783ee8adb4801db3721f94f1ca": "0x005ecf6db84c00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5188b5cb4ce332207efd29ebe94a91e9a95e070000": "0x02a4706d7ba244bdf80f9d5b2a9615802aeb33d71235a2be2798e6a48d76354100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e72549c3b5e6abc7e856db369535795fc4040000": "0x382e8702ca97efbe99754ae545488c526e3f56d6e1f6643a6b2981407aff264c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b10d4d83491e7be1f9451065c9dc5909b717a28c": "0x00bea716d82300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890010cb37589862d13ee82641c31b3d3efe93e06e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e73ecfd355db154dd6f0f9a26a610d791d95ed": "0x00fc6893d89c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008ddde69a07c04100b334040505dc6b4125bdfc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928978a451390d870ab409d22dd5afabbbb623166e3f": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282437ff48b76335074baa82f4236dc673b6c56a8a703": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5164ab18ef7ce917d30b6789bc3644de2f2f080000": "0x9fa413d7d329f4217ff3b4713843b6ef8f64c2ad1d769db015187dda34a7ca0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea0f7286121217c6369ad3c99f1ba910f5137aa283da71cce47111244fe2cb40": "0xc2e763a5924cb23fc77515a19ec3cc7e7a122250", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009dd16c2560bd2907136d9569c32920e5f0ae05": "0x0032d33d7a2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748135590503369f344c719db70e50aac005cfc24": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d24392caae002c7705b8a8ae61f55a5bae270ddf4b2a61147e43596f62e6dc15c": "0xaf770e8cbcce62a1a458739a4ae0811c72d33f55", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767494fb2a324220f917b9f9d6f6cfe72093d4cae": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397750383c5e0fcaab8fa81b168ebb0da0f280ff80e": "0x00328a93708000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894b51113c775e15754b42a7ffcef1bc3281adfc01": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a19ba54235400e8ac4e77957eded1345dbb54277": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700813451b4ee8df7c523fb49b9f817963d0c355b": "0x00c88263aa1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c81f502e87e7a0236ca1616016d216b81b91fc61": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9792a2ef4c3e368f3e570caa0f090fe31d6a3cd2f9d0b2ec270067e123db105e": "0x391a6bb5f2fca9a19d16f09aa298e9e23288a5f8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ac42f377da5d9a624f94d0e9904e76c144736d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009181f75cd5f86b015f28e0b1919f5fbb3a3eb6": "0x00b4d5fea72c02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339755ed1eae79078844675b794dee5902ab7304db79": "0x000edd373d3100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928905e248f31370ff8f16c3bb5db186ff80eefafe62": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5108ae7b03ca7d2360d493c324566449d1c8000000": "0xaec79507bbfc51d7bfa389f36bbbd7aa71bcec11e7d8f4415384854d74bfce4a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d808776b923a9800a6a340da7dadecba63033a28c5f30879db9b6f8975caa9a28": "0xea9d6a9ff692b9616f90f983f2e2aae2ca3c9186", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fb2d2432975267c79d283a617c62324a5b0897": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289012b4170e46b07ad9cc49d4ae4f7b406467cbacb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d5194314e068c9046f3b977ab344ee5d190b0aed": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d04f884dfd110962de6f4cd9068ef5bccd48a62ea21506d69aacf8e97ff644a5c": "0x00467243b6d8312a68f35ca037c0428d52ed8aaf", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970088db9e97689c85a29e67d08f1f0e43bc40ae4d": "0x0000c16ff28623000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f30aa1a2b965b6273414c69bcdbbcea76a52ff": "0x006897a4ade900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d5a9b2328bfce7b23d8ecd6dc396125418dc03a4": "0x00d098d4af710000000000000000000007f7b70000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da047e6133dc6937a00131b4c460161d9a7a54ae0bc93c61fb95b057828dd715d": "0x0087fd9f134dbd9d68a2a869f14d88c812a14051", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b243dee66433ea21911a964a9fa3bc04e63f4a": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da47e84d64df494ecf1a2cd5c1b2170c23dd39d9b7c416a34f74ee809e929660d": "0xb3aeabe65664ab160d8ddef2d0a74f24faf321c7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977038e2b36b1117c7c9ac36c511c1965bc14b2062": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339754970d8d6d8f8dbe9c87ab9cab9057fa5039e4ab": "0x0040cedefc7d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b44c291ee2df2fe32fe4cdca5937e9c8cb4d5f3d": "0x0088e11e179200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900512a3d8d53dcea7e5eb52946e0d41988b6ca55": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da7b00af38ee8a3de3bf7ddb6c08cb924ba97d72": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893b271c43635a5ff2be9b8ce704bdc3ec1cd199a1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dbefd695363d03dfec48e770ad6859dfb30cac4a": "0x0064befdaed000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898f60895fbebbb5017fcbff3cdda397292bf25ba6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517bb8b281d4989439519aaeade7b739f8bc050000": "0x28ca3d92a66a8c35c479af3375d6181a95ae794d798e02e6997b73c3d930754300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d747f1a48023fec5d71e82ddc8daa3c0b1d1f4e6f7e1e753323eafd83c3b6865b": "0xdaec98c63f553f059c024da69f7becc810f8ca0c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dfad4e398bcfee3910f788ba02ac6de09156ff44": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751a5356d5546a139adadf0a7752c4ba266dae69a": "0x00a61c778e0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fdbdeaede3cef361db915f912bcb676475074f21": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289efaa2f28aed1cf6923c64137ddcedc4a94181fa5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a228f05157969366882c78be7c434dc3d66b5b19": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e9a22abbd383ef785c21809548b56a3abc020000": "0x90a6b364317b9f367adeccb9432c3e8f8e1badf60cab29b241da813d1e64f41300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978c6778f77b22cead996a7bd73de2283e38d5aa4a": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d36bc6b7da07101e5302f94d5e39f1eca8aef0dd": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970016930644a71069819f2642d0ad4a07a5add934": "0x0098857b495f09000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000160df2f8fffb230d8cb9f67cea2461d38ebc6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928907b10fb900a97ec4a265c6ef64d47db52b9702d0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891206272257240aa1336db145d922a5509ef79e2d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970044b3d793d4cbf50f0973e2c8d62ca3bdcbb38d": "0x0072d1c9185b01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51660394a5d29a74a8e6dfa9f6055008f03e090000": "0xf2457c0d57b6b806170c32383b6dfafa843768f7b96d34bffe9ac42bc23c747000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519c1c28c10259eaa642881cd98ec899933b010000": "0x5a7aab883d2cb1309e3c942074c7a2fc1455152d9adcc2d590b5457eea146e5f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ee32592386daab2d2ac0ca657e8e165e0889f8": "0x00009791882600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b9d69f27ca990815a5d6479b824c3f2fa7070000": "0x265013803cbe5f9f3ef7b38ad278b6d097d3be3ed79248030f460ba93d164a6000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928901401ede19c4beeb2ea70043493695646023d0dc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894f1de81781e8bf83b57548a1ad3bad66a16c4e01": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397750410db2d74027243fa5b6abcab763635fa7fa9": "0x00421fbc872d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397255de88ca59b050e361ac05df197578bd70a732b": "0x00b218f2c65f03000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516f5e34a84d46474a4fe30177d15d9a98da050000": "0xd82afa0d1687d166c1c47e1cf8768ce194d452a636bffbb2545d06e5c2c5114300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f1f605aa47e882d4c33a928fb1620881682ebd": "0x00962d3a03ff0e000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ccca334581577efc4bb151df227389f879050000": "0x00d79a5a68a82dfaf55ec01108f9850e47ca61887ff2f7272f5dd9216cf4643200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890008cd3b0bffddf4b7f4528c58db5416eb998ac0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51978ad0d4182728dbc76b6ddf8d070c35f6070000": "0xa221d23c94dcb9839d8211590e39f17c2b62f2eec91a66b3102c409856c8456b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289283adfa795ede051c814731721c14b6c1dc3e2cf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289141de041d47905ce043140c61970a5a28ca39879": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824398194b95e37bd6de019d5ac8fc416daed2091408": "0x008027461a740a010000000000000000c8f82aaf01000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d38258ff5251b93f46034c7e4ad5eccef902a733ac24cd1db66549041273ec238": "0x5ca69ee86a4131262ccb5c56af72f42d597c5a2d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003b382fd41c33964be3e159799e8539c0b78159": "0x003c7ab90c2c07000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a79d6c7ad0312485e375127d0844a4658b220fb3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970084000ca2cf4517f4af097574805a518efcdbd0": "0x005264d85c1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c963b8f2ca98eab214ba907e8b1fefc8f291fb09": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5119b0d6e25ace1feaae175bc6fc467b681d040000": "0xb0c02861db2e67ac0e487fc765d3ef8d30e65824f780d8406b00300c078d9f6f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970063dc69f9baacd4f90f8e385a2b93e8233dd8a5": "0x009ecc2ed32900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397144da3f7abbb9a22238f2258d13d238a9149dbb4": "0x001e076f490900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b6616a37a8564b972baafeda7489ef8b78050000": "0xb0455a49cd7799893e8a3e3928baa35c2a921c63352b4126ecb7942d7122861b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ab234c65bd20f8ecd6ad7aeb23e025b168b7a91847fa048927e2434e3cfa25c": "0x38db95df5bffa0bd5e39c27866f7d53e04c2f87c", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51216eb0d9253928f51de54502e31e7e1bf6030000": "0x52b419784a06ff99509b1b18b627672506fe92c6843bc19643a1cace1f4cba5400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397320a67f5d718c4b541a5ef8194ad4f4638162f6c": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c44151439965c709f7d79ceebaeda5bc5fba9ca": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d4340fef5d32f2754a67bf42a44f4cec14540606": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f3654937b2fb15344117b9b16fe5065d8f0d386": "0x00ca8f386e0900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51864b574748b22ea4b5a67048f45239cc39060000": "0x385721fc43fb4262c56a1d6a6e8c07c64c7d7fee8b27c023b24470902bcf462f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397904a974b3f43903b63d2b6c7fd379550baf4742c": "0x007ebb5c423f0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e28c5e4c6891afb0df739910c733766305cde69a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397206dcd656eb235659735538e8c7e708ba0c3779d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007598555819639ca06fb8b20e3ecffe1159cb99": "0x004e3715665c16000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397709e8bdba7a7ca0bf99a138cb2a1d3e84b91c753": "0x00b61557e35d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb5634d0c12b29996b2086639b804b441878b167": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dacf2842c60fe2d7ddac8ef14f56bbf25fb2994330da54be6432568717945f330": "0x00bc7d1910bc4424aed7eddf5e5a008931625c28", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289239133b0a6973e8b1c2b7657dfe9abf78501a894": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a5fe200655224ca4109e8bc0b29ccbbc1e1269b0": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd25b2aa840158dd94bb9a19e85a798324e2a0e4748eac08ded47a5fe2814ba28": "0xa1924e3e6693420a5461039f1225c5cc765de4f0", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d382e8702ca97efbe99754ae545488c526e3f56d6e1f6643a6b2981407aff264c": "0x66d3157036246be0bdb9bb8427313949b21a70c6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339755755dcb998f1218761831ffd74747cdeb54e1ba": "0x006a71b29a0f04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970194b15e139b48efe1c11fd9143f24be3597d162": "0x0014a56b28a300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006e7f956676282819af849760db488febfcf3c2": "0x0090abc6635300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a50ee9a3d2480093dd4d94442dd6e9ef2044ed39": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001971fb3e5be59084ff323d05976eadde3a8852": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972fcef6913ba9d9ce25e509979180d5fd0e047b07": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397359043a2edeac162a5bcb5594a24724176dd68bf": "0x0060800fce5802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979479eb3392e8a2b6ca2e649536b55c8a2b932f1b": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006d3a544384b63158fe841d6c84b27d998ee27a": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977eba0c6ce3bc5bba68807e2f390ed997a5f78763": "0x007ece841f8c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973b7a90105bf9acbcdc3b5219c1b55bc38397cec5": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c186dbc2c878448f2fb2969967abcd307d98c247": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890194b15e139b48efe1c11fd9143f24be3597d162": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e2955db86f098d3e695d30944a61ef610d060000": "0x82f33de37b35de7cc4f5ad4b4af122aeb25e084bd1e87a6bc28b60ad35d2861500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d24cb880e0d4f3181a2f4faf3df0dae7e138c3f2ef4a4d2c65e5030b41410733c": "0xd3b766e58e0d0aecf1375297e84c798b15936d1b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397136cda791826a28b55f4af98698a51f3c5ce4e9b": "0x00805002f7d266010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d4e4a2ac2754434e6b32d114c03b18f3c30c0f": "0x00f2b28b484f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004af69a0c1ef595d06cdd6fa458165efeb0fa8c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979d979604f1633bd31944245b5f6d183adebcf10a": "0x00404c948b3203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bf1c98cd754206368af6e2c36e0661454adb11": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928997062eb6c3d95d33c040c98a54187b5a66541b6d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970038dbd81462e435a757f14dafacc119b98bc2cf": "0x00d4f831fd0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df2457c0d57b6b806170c32383b6dfafa843768f7b96d34bffe9ac42bc23c7470": "0x9d979604f1633bd31944245b5f6d183adebcf10a", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5154a17df9ed51a26d82d68a71edd0716f02040000": "0x6e30851f4b86598f344b29224ebc8a52503adf8cdc32af154ab6ed837fa9091d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ac38d6c7d86e398726a7817ded1002f5da000000": "0xc4f955aa807f2c144801b3ff189da53ae841c7f5d6bd15cb3fd3b5001e94f85500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289798036906b3adc3d933e8cf1a88bf25955b2ee06": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b2bedc981445a47fd58cb9814b8c11699093df": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fa7f691c51ed0ef0f26c8f780911c95d5ed62ad8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f0f3afd02178ae1d3e34a7f787b9b8a07b937295": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6afef10e3de1ac622a67217de17ac4ee000d179fd54edba27e77470d961e8d45": "0x35edf1cce3d9c1775ff5e214dbfee26abec3fb3b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002cbd649b7c80d1c0b018deeb64f6836e8552ac": "0x003a46774c0700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f57eb791dc9ee61bb41f077d2819ef125e050000": "0x6475d23c468c6da8d92298d6edc33b5cbd3feadc6d637d207ff6ba64acd4b31700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970010e77665415c63e47bbe3dac8a0859f10cb525": "0x00901f44ae003f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700033b2323f771073dc59b1b9a869d1b6a945330": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289209e077793d4f2390c410705351407ddd7a31d99": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b8369231f4ee7d48791e4b23b789a6de4ac1beb6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900092cb42b631dfbdf26f405f931c409fe5a3913": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc4852d47110a2efd4d38499db303859f407dc430027b7b7c582adc7d5b187547": "0xe4465431b88b42ed2cda2b4d4c50b38ca1ac8f83", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51160b9764756b300c1fa4a9f8b30edd7c66040000": "0xb8ec978a98432565745c836f384440f84ddddd40922aac33d98a1e46f896901b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d228ef1e58117a07783f0c17ba1faa7aca9516f": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397184da5b2c2b2fa406f1ccd4d33ea8430cb0c54f7": "0x0040b10baf682c000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a528e61d81a47cc9ab160555143da7220f9471d2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e277e496431750ba944779d1dfc2b2487d6926f1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970091e7dfb2cfa0adac37bb5cab874838973c7f0e": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243004cf480789b4cbad22bdfe4c1ae7ccf4a4675c7": "0x00008d49fd1a0700000000000000000073707f0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e7321d013167e5d2a3b591bac90baf4c75839e5": "0x00409263457f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51575a2106b1dcd7b033057eab09adabff5b080000": "0xce7afec36eceb2f4f7ce11d6165425203098d1b0d935e9dbe7b7ce8ee8faf74e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d17b7295b2d66adadef5746c793b746bd2443e1da913636625ba95c7ff853bf22": "0x456209ca9fcf4dc8d276a659f6c37003555fd0ac", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b3c251acc2a56b1a49d7629aa2787a17fd070000": "0x7a73cf30748f8e2654e678381901e539062e86ed9c56cd51a057e27dec03532900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d82aef72a8fb431d49db51e0a208fcd679ab78a8b8c88dfca61b28e67a8f56a75": "0xd9103bb6b67a55a7fece2d1af62d457c2178946d", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ca516bb62f4ab81eb6d854c7f11abc68f0a0dae8719a1dec67ab3648c8a170a": "0xeb514a98e40a66e5d4f634b9afae1ec41d58c659", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2ab6a0d5885b1debcb5f089ce73d3abe16792cd01d63d788609f8d859fc1fe01": "0x00e18a7c74b913a4f28da74fe2c194ed4655d63e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892085aa6de1e83261fa966ed09b518c3eb3ec30bc": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfec441cf991e77767c7acf554e9d61efb63454b4d57153c4ebe95e15d7c3a329": "0x1b919a32ea4ba16c20e24ee83cbdf98b89c94a31", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e293a1ded3dc1b5f86121f41d9043cbd18914a2f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f4a877389deac7c25ef61210125c528c81050000": "0x34f4f4236b04e3bf83610b55d3527b50da22aac3ca85ea0d520196835964b67a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893cc9063e7ac5fa8345e1f59bc32a470ccd30ca6d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b21315771454ef8c680dddd7b9bd5405a273262d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397974f15f02a0b9715495ef4b620abe5f8debbf0c9": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977cee83aedd18502b30da96e6c96f6a1be237f949": "0x00001e52c4519c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339725dc5d102c1d282b89ee19709bab596db52e3d57": "0x00b44bcbd90901000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900860b441b1ae0c0641409e5863e1a5f3a28a651": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397298679f84e404ac8a9c73158ee6fa4973eca9abd": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893637f645f8bdb74e1cd1b28b5afc64c4a29c1f1b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897804275d8e53aed92f09f99f55e135c75bf297d7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928905a5830f9d6fc22700b9439ba20d15531be0c789": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890b7482d5d6204ac5d40c673125ff1fd07d183183": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5157e6dfd9e074f967a74b9f06ffa0923847080000": "0x9ba5e7fef2305ec746210a83430a31cabd44cb964ae70bf16ea9bde11ca2509b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009276734775cde94eba0c4fdb98078db07d5fef": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51548f0c21bc627571bcd2669407a85bd7a9070000": "0x9446b359ee88fd32037b052b4d815ca777566ecb8cd6860db053a7d4454eb14f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339755479b40703db085c9abeee0d45fef0c61b0098d": "0x0080dd62b22102000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e60cd5cfd2a79cb84942b411750fae1f800b5dde": "0x01", + "0x8985776095addd4789fccbce8ca77b23ba7fb8745735dc3be2a2c61a72c39e78": "0x0ce0855069a59fa0ddf72205213ba6d7bc3bcfc44316af9684bb215f815fc0113fdc559c88e35aa258566bd616d0e31fac0efda3d881b52055a31b35892086bb1c908626870725d87736e1476482cc7df7bf32f03f83ed8cb6db40a830067d973d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700939f839c289a1512d9859cfa8fb0ca0485a8ac": "0x000033381b3300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431e7aaa4af7293898e3d1d70fe20cbd525c495818": "0x0040b10baf682c000000000000000000cc7edc4700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae6e1f76f1a161f6a6e884753f86ba364bd84c59d7ee14a32554bd1710be622e": "0x13d45bada78daa5cd52162254d158a217dd1faa4", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d662d6d64e01bcc5f3a54341ef0bb1cbc022105de37a80558723f50a59ff68952": "0x008dd1b21dad14a42715a406f36abc940ebf0287", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000d6dbcc9191c9bdaf3904cbc0bd1135f5ccfcb": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a3db207ac468ff88714a85028b6fd96cc90363": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d50684b3f7255302490563ba108a92765a0c4f0ede17c923bb105ace91b75f30c": "0x89af1ab14542363a2c631dac9d2eaafd0bfaf008", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397559bd4befa5d868ca380a9928ca2228e3ed26ff1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d5bd2aba04a07bfa0cc976c73ed45b23cc6d6a2": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3181f5237629b697ee63a8a25636281c84e0a9b": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51df009857059a88625167a5663db8a08417060000": "0xd8e8d4bc65f8628e10a4f90c10798486663d608d1500fd99c38e026414d35b6f00000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcaad811cd65a470ddc5f1d628ff0550982b4def25cfda6ef3a00000000": "0x00000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ad41e9d6e1fa47f1f6bcc63bd0327009590a47b": "0x008c61cb87cd05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f431cd35684e41f2f37677f28b4a760d8fb364b9": "0x003899e7d43401000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289144aaca2fc5b80cf9407d115281ec805e620c211": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000f7e4679bd941ca16000210130b66329e28845": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891fa4c4ea0ceeb34bf67c13be01e477cf0bc8db84": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dcf5ac110bfb16933b6f50b5e5f8e38c98d39481": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397516760a6e0a4f8e3683260c1b5275ac0b28992f4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928956fa0858580a1f355ef357c2b909915f72c4b626": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda91fe41a638929d565d92843dee98c6fc02f8bb7227939aab4accca69aa7b08": "0x92ee94af3a409600eefbcd59bb63623a6280a13b", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51039b4d658d5baf71687cee969af7bc895f060000": "0x96eae07e988c50ffc04e445a287e64b4c0ecd35859d8255ac438438f7af6802100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002b8afafdbf14bd18a1ee36bfd45a35adc783d7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbc0d52af72f95b948522eee7d3b09b8d77dd465baebc301f332aa52b1a93b240": "0x0013aa2fb5ec916660b38f1d53d4fc9bf8ef8a84", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890628dae391a37ccb6ccae7e6b6495c2622d69cda": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bebd4c731ec56e072e94cb0617bb47783ef3741d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e4f4e78097c5d1eee4c95718d8d3931226080000": "0xea53c14c3481ba7416851fddf1c192362ac5b8123e4866ff2ead77cd6c2d772a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5119b39ec1939d7be0d03a787c306ed82907040000": "0x7c2241b8ad2176aa340dea400bd84fc389091a7511086bbc78fa98a7356e630a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397106d77aa34d1fedbcdf0cfc17d140745aa5c2626": "0x0082db3cb70201000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9097fb3f7e7de0007abed486c2b5860e7de0ccf395acd0b1a0cccc124b2b710b": "0xcb4e4ab1d79759d29b58116ef6c0158298a0d12d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac64a0c791cd0b6edb560c121fabfe6a23be2c43": "0x00f456eebdaf62000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8369231f4ee7d48791e4b23b789a6de4ac1beb6": "0x0000c8e1424000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005423adf241a0a11478d32b7d49930fa4267709": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aa71944087a4242e157bb28a8a1b110274228ea5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928958445ba5cb35d9d4513df77f8ef3ccc8d608045d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397775d8bb769448c20a545c582088db5bff3751e84": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b054ab94e535ea6808941b416fdc14255dec9d": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243ee1301ee318ac92f4ae4254263da4325640a97a2": "0x00901ec4bc160000000000000000000001cb240000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e69c4321926a7604508fcf837e03ea65d941ef8b": "0x002a0967c50e00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51854dd729024f01fe506ec629d68450236c050000": "0x646dbbbc90e5dd14a432f77bfabcb173d4d9d9918473847fa8e63ceba441cf3300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893024413123731ac0ce07c13e9511c0bb76a228d9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900eefc4631700701e9d546fb7451705dc83b0731": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928936518f6425b4e3d1045cac34d91cacdb49bbb9ad": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289853fa0c1b613b0756d7798756eb87de67a6787a8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a640c639421c815ad2e40be3ed98ff0eb0e446b4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dacc0fd259ce0de2829b38a0765970e7ab65346c": "0x004c808dd48d02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289226c85b4f7e53cee040b6d2f45f4fddef5d97bee": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518bda250ca9d0e594d7d2bb2aa2a5d5c715060000": "0x2e419f33cb1673690d0ba113af46c36e2392198e9df48ac1210e36258943c71e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da05acd278b0b5c1c6ee96916b67d5e4468799fd875829dc626140f5aab5d300d": "0x006c0cc442ab4dc5ed006af112fd7e064511eca8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b94ac84a9f1d304a6aa6ee6dbcbfdb3ac81f82": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007eb3537067c48639bce08b04e4fb52caf64e9c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928972705657a219aaa87e5b7223cc79cd15e33e18af": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f3b8cbbeeaf1eacd6fac6d3bc0450b3736482f14": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970059314f3708129bba2e5370209f0e54da9bd354": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cd5df6d891ec36ac93b730a2919c56d3e211a5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973b8f1babf9c1a911eefd093089acb1a47b7c4fb2": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ac7a5d501554f521168dca348bce0e034a3f9a2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddaf5e24f1300e8f83b716baf3b1fedd62eab829ecba9592d373871dc1e9b8f6a": "0xaa5eb42c2fa202b4df66a36994d41e04bb3af2b5", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973799d6c8dfad3c6cac7d4ea9430458503bd9d4e9": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dbe2e4f5b4322a6cf5cdca229febf825a21462ca": "0x00ae5806543500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1b28877a75798bed7c923d042a8bee3753aa796": "0x00d26a9b6f0d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d60270251b87e5fb87da897643ce4f706689d027a033582cb731bfa7f2e507302": "0x8d221cfba0cf7d028ceea3c4e5f8cfbc76f2a46d", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1ea9fa1c4639443f9cbf06f83e53f11d817b751cc333915cd9d15eb6dd917b11": "0xa224725ea45e342d5f769ad16c4f7f19df7b1c39", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900936a6c0bd3a0110725442f1e0887d5ad459160": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f21808c5f1198f548a6be2410fb55fc0c4ac15f3": "0x0026da6a887d25000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f5358b6c215df659c467e36c26a4dfccad070000": "0xb20bd9a3646907b754afe17589e1d08ba7604099110ec787dad89638e3436e1900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6de115e43fc234b448bab78e647bf65c608d4e5": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b37489e03c48cf54cff37898b07f64402edaf101": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cad1acfa9151d7eae13f06ea4d90a0024cf37301": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515b0902f22984ef946ed343b34f916417e6000000": "0xbe8b6c175c9b2c8e856d8d8f48b48b2e6ff221dad80764466c4f4ff46132b42700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f40c3463efb7815a2369d56492cd4a8202033720": "0x00d0f74e784300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7bfb979281653e88fb409461d39f319ae988197": "0x00d22374f95f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511b74ffd31e827212ab3fea8322769fa581070000": "0xf6cee83fe99a1a53a1296c5a478df2a8e62a00db5f412735d925c080dc58851500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004e35c529b6d6f7768f868036f065138fe68b57": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ff551a18250d3764de26d99e1ff0e854771056a3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f7661408c9dab98f34022b610f386cbb65080000": "0x6a9dd1d60d062e40c25417c5aae94b0efaa1d3096a35e9640215a3a0d6e9977600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339763c62d874ed1c6fb31ecf56529892875ac6b467b": "0x00985db8783319000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dca74fb0ebfeab701b8bd771fa5e240265832961": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009e7f3b1be6c5e05c4b3c39804293b582ca64b7": "0x00904accfec908000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1200ce6d0ba222db35d6135e051267d901f44b1": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d4a8282ffebc08c9decb113a822135434f9b4a2": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ebd4b8ed2ce27e41820169a6f89111436e1507": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890069c7b8173234a0b275d948db0a415a7b48091c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5170530cc3752b4214305a46ca32da19c679070000": "0xd6f274e764d8329ffc4d8c1178cb04f473819ce3c0e420e03aa77d679a43d03c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc44cba2747fcc1dfdc75f1ad38fbb13fc2ea072cc3855f7db2a52f9e5dd5080e": "0x0056962a7b6b0ec4c917488d06892ce34075218e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ee9f9804eff1886d23e8a04e5bd9ae506b64740": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9653bcf18e30531092fdc1c52afe06cf61f56fb1fa5d719078cd6914d395ed0f": "0x415ad707749eec89443896f6e55843a208e671e9", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d205c26c75bc97c8a32afd10e3a4b7b1af83739b7be3dab18ec7a435cc9b4ff2f": "0x5ca260bfbe4c116f9f13d007d83c27f8e7bbc675", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824339b51396ef3c70571ce86532feab5598a766e8be": "0x0060e17ff11901000000000000000000ab3bc80100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890011e93c401330194e47c9ba85368c0205eee60c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928949739691fb5f3992b3f2536f309d955558e75933": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f786d0aca37d4965c2929cacee16ad42d7cf9bab": "0x00263025941300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5120dcaa75f719b651fc723862651bf0144b070000": "0x14a53177750a94e9bc22574f2f971d71b8be81b55d607c45eeb52d7a4ce9b85900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5a0d7d8d403f371985fcb5c4dd9527bf82ee4ab": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eaab1f865f5fef8b614c6b2468333205122cd5f7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da03f5afd74de173c5d2033951f8225e29d58d813bb078d82569a07eb7cf60629": "0x0088db9e97689c85a29e67d08f1f0e43bc40ae4d", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b646f262e971cbbcd4bd0d591d1fb7378e030000": "0xd2cf95a89356bb2253306df3fa6b44e3281c4bab6c06fb3bf7a8268a311c455700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da83b893579065ff9265b9cc79966041e55cf8f06d1d45fbd9e957daee08bc260": "0xda7b00af38ee8a3de3bf7ddb6c08cb924ba97d72", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ca6719bc9fd490cea2f94f000a3a47a4a5a498": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7a39d58de9e6f425d04d99b7693ee5f37658db558114b7aec1501018158d257b": "0x00c72c867cc89ccb922cda5821ffe7f060d8603d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a1924e3e6693420a5461039f1225c5cc765de4f0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b98bc9f8919ee39e563d1ce3c1aea8ff31ab0585": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894523dbf40b244fec4c04fb37682ba584aba0711f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c7e8ac122deb2f7dac7456f73cb4aadd9d479862": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732fc9e119218462c2171fa5bbd554979fb7a3e74": "0x000cef52127e5d000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3445faa3597b667b65809fd84af6483070acbb92378e3498dbc02fb47f8e97f006bb83f60d7b2b15d": "0xf72daf2e560e4f0f22fb5cbb04ad1d7fee850aab238fd014c178769e7e3a9b84ccb6bef60defc30724545d57440394ed1c71ea7ee6d880ed0e79871a05b5e4065e5ab03e0bc62a8fd3fded0b09ac04c6192796873b38abceffdbd1548f35f61aa25cc78808d9ffb966aaa53c3c399cff7ea0b409dc8b42908b9f2da6d34c352514f13a09505d4014b468c1d3e394002832d9edc35dbbae1a7a6dc96025d47d5b", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b9852b8e54eb76495b55ac3056bfeef457070000": "0xe0d92174136d7990f5ddc8577ff5ff898c9da30350cb244548c21f2b377ad41200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d1b7bff428ae90b82147cfe52e2e251b1fcafd": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ed2d6c16707836c6609b53b802692fe176db28": "0x0098983cd6fa02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bff9908ed6553a0c3b071b1232bb6b544abdbf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893686e9daaed20aca53640fc3c51059f6c5afb54d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c490375c379dbf184757b100561207f8ab1938e": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce34da5a6b581256cfda4af16a50bdcc4264dfcd315dbe8b609fe83f408c2568": "0x3fd29fbaf2b2245931f154595c2b909bea226418", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcd52c547ebcb0b817752c5b62d132b96b797250": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51311439b80608d78c1cd9e33d735df1b2a8000000": "0x16fcf8dd3680ec588538e1b3f27a827da4f3b725ba71e74ef68a636b6f5cc37200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397198054b85123c69a58423e20437a9190b56ae823": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002deff295e375a68734582a3ed0f7786b7e92af": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975bf688eeb7857748cdd99d269dfa08b3f56f900b": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890062340e032f69aa1370bbe8901d6f4e40f66b60": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1ea03129bac8665e20576fe238d270cab2441d839818d533d5ea903f8960725e": "0xd9459cc85e78e0336adb349eabf257dbaf9d5a2b", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c564910f11a0b70616a373d3b183e1c9e6040000": "0xb4f3b0258a6c76ddaf414bedb1cbfa64eaad958a0cff4f3c57085c5df38c630400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f721bc7693c0742843d9d5180715178b81f90f": "0x00fe39811a0e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397110b0b10908876406b974a5ee670dfb9d86ca0f7": "0x00f05585cee507000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b2f2bb8265e997bac1df35b75ad84fba30010000": "0x88fa1f44c372d28f74829f4304bfbd868e94069ee27bf338f6d6567ccf2e645f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f7a28702a142caee8178da955f3bf87fdf449bf2": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890005ed1b33b541a3029004ccbba7cef3748ae1c7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d1cc0cacf39176b5947925ed5084e7badd44b625": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5114b138498abe173338169138ec10e62a88040000": "0x5e888a7a333cfc1433a594a9b198b64bb2493f574e57cbf3f4cb195a79fe4a4000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700864b879b69a70b8798a0f61de21ee5b5bab3f4": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001895edb9215904d416dc35822c8576444e674a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005848ab7e3f13a54848c46469327bf62fe0e5a3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bb178156445326540aff00dc2b5d1290f2050000": "0xaa339c0fd9d6df6927cbffbbb4a0256caf8ae245bdcaf8882c2163b36877390d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5125b2602561f053d40962b47f222d3aa40e060000": "0x8c71c824b4bf5d9111f4513c46ef76f4b003631e3e5fed3f644c2737fc56265600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339704e38005b0c3a9e183c22ddaac3e074c689757de": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3ce72b62d59cbad8484e9d9cb06edab1f465e7f30f3eab441ae94df1c7013363": "0x530d949961092c5fbbd9a27e48902155e3208a64", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972107691d8a935f6f5ff47171ed954e332c4248aa": "0x00e8912de00e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d1906f171b3ae82d0c500555143c28d239ca74": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f3cfe478ac06d285b4d02c57b47e06874a060000": "0x127a30e486492921e58f2564b36ab1ca21ff630672f0e76920edd601f8f2b89a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896dcbf212a83175dff095fea2d226aca22a93d643": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897e22e58855cad471e60b297f1a48c34f44091132": "0x00", + "0xf2794c22e353e9a839f12faab03a911be2f6cb0456905c189bcb0458f9440f13": "0x00000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004b8716a1f5c2f8a423a5f170dd5fbe4f436171": "0x0088d21c5b0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744eb5b6c2d5cbe2d38f9fc21e5166f5964bc47a7": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e22bdca82b186c02ba11cccaeb2515d10b0a81": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750dbae8912187371548f53f74fbd269f86fa44ec": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895b11453d090fc10f3645d14a2e2b1af79030b948": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d3388e1ed707443442afa9bb133d9dffacd9b467": "0x002087c009c91f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c83c9437f59ab9d5c0f5e16a12bdb905158912": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2a6821bd42b8a9447c08b522c8b303f1c208dbd014484d3ff30fe3ababe7f732": "0x003c0f01ebe0f29488c629e253dcd4cb9f1cc586", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c078e415b18fe4d186735580c1cc894800060000": "0xd4c1562a1e4d60a14486fa3b12d843501862d77075d222ea7ae7e61ac8cf6a1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896c9f5c47814f33659ef2d1996a0961e80b8597bf": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51884b50ecba0e12c819209a9bfcba43336b060000": "0x5a4407a49eb2bc29d1d9f1583a0037b94bfaa348b76a0589147a7cc3d35a800c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d724e0032275bac5598878e5dee08149d11c44700c9c4626d1f339ff1be715f30": "0x5daf6d0f17ad397b6a50308bab72dba0a7a74249", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900845040dab8b551a3b246664a6f9d2c2431c0f2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898ab7edcd19d92170528cd5d8a7d25dc6ffb75c39": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dba8cbd759ac337120fdce334348ec173f6e2ce90fe573292119f6b33bb805c6e": "0xb5eba1c7420ab3513ca76e1358b1a7c9038d1fe1", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519eb5dacb71a17558383a71ba174d53c73e050000": "0x3e08fe860b1689624b46560ca277927a7f18006f176db498b3f7af236748755700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db096a731f7b2b62dda5658f829976c2226df044ca3820f3fb5f805f9651f801c": "0x000077e89a2702e5438d2be4f7e8744a5ee2b60a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002a9013053f71ba888e54a8f4896a5cea18f904": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900368ab2cb58eba931c52dfed54379ef3b56f79c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928938c1a42ec8564eb3a62966a831a5fa45e42b5455": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ccd8ff59612d4108d9bbe5f16add545efc6fdbe": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516eade0c5e7146b3507f5faa97ef036a5ed040000": "0xc4e4ff6adcb360ec9eb50d5e04ad47aec66a30055222dc13c6215b5f2db5976700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dd9c6de73ea0b65c5aba8bbd3a3a9a212be3b93c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d560363fbc8b0990637a3014805fade6ead14f20c453cb780eb32e9ebb5839d44": "0x254c62b0e0862a383dbba455dcf692e71fadcebf", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890005ffdac0973574e3fe91ff31b254fe2fd08acb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002bd178dc5ec5ae344d367d4a97281f63736d7b": "0x00d6e5f7f6c601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748e17a5cea6d3fb095b75fd94f36f6a902dd6702": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f21a0e51dbf4a93d9ff5bdd23d6c01775f1d708c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d58049496de2baead8a7fef06cfcff07764d07d7d466c9d64a4982cb3ca32b85c": "0x0014c1efea175cd39fb686024383fc07374d6db8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cfd2bd2a86152bf48b1cb9ab2e52c19d5717fa86": "0x003c728ed34d01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510d40821bd2486ba9e15b3f8dc6ce1bf67e050000": "0x54a341917b5bc8c35dc4182e611a4b4d7550e1847669fd6203c3c2fcc9ebe46500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900de002b79aade8d38abb85617f6dff10f60917b": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300b0fb7ee5554869bfb57d69836b005e00a942d7": "0x008062175ed15800000000000000000098fdb88f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339725d56aca979398aca283611258eaf84de39c0d9d": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243184da5b2c2b2fa406f1ccd4d33ea8430cb0c54f7": "0x0040b10baf682c000000000000000000cc7edc4700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431a0433933f6ea1084a7bf83ccb474b4cd263e7d8": "0x00502269587001000000000000000000e40b540200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ac7a5d501554f521168dca348bce0e034a3f9a2": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b9c635d29a8bd145547759a0e823aa306c607a4e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a83f2bcefba0bc8bc10f88eebabb7806bce2f156": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fb2815ace3d144b7381e2364e799abed8c0d6ec1": "0x00f066368f7900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977a419133257993a9af281933febc870657c764d3": "0x0000b605da7963000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f220d58015031403687716a43c54f64dc99713b6": "0x00645dd8e71400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d02a4706d7ba244bdf80f9d5b2a9615802aeb33d71235a2be2798e6a48d763541": "0x48135590503369f344c719db70e50aac005cfc24", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928918be7c263f1de5d3c4e78105638ccc5cef8e7c9d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890051ef63e8b9714d239156854c615606cd9effdd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289656e42bef0b20a74de23d365958a4461f595b755": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ba10276d69a11c6ca944dcfecd669325b67614eb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c26f719cdfe1303d3ef566ca2ada12cc56407c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339760aebc1d9f35ac28f40444bbc318abd850c9376c": "0x00eeb51b29bf0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824399dfbf9a028384c05ea011e6279a4c1d18c782be": "0x00a031a95fe3000000000000000000000eee6f0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895baef8c667a773f2fce5568f70ea4b8cf94dde65": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f82fb4366eb81322a5e8ba8b6281d04c32b3d631": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f09f297c045899f5cc00131329ee10e522de08": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897d098fec4ecf9ac948b17a179c638f1dbbcef72d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cfcf3ff87b3c34cfe4285a85f2115f96cf0fe5c1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ee2f123f672d5bce14e7f9dbad8cfc34146319bc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900729f3355fdf72962e9734ffa26ccff9e64c0ac": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a5489a5578fa895e4d39b3f3adca0ee1bf080000": "0xce34da5a6b581256cfda4af16a50bdcc4264dfcd315dbe8b609fe83f408c256800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397831cead0805ac7cf4a744e9e8d088317eab8d0c0": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289035c88dccea98eb443d506347b9f96044da9bcfc": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3640b7b7fbbecf967f99ec9516a74f9e255efa5c8529751a383afccfe936175e": "0x5a752166d908f57d724163a24c4ca1fa4ad17d7e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb2e14a1805cee42c55d5ffe6bb07a2a8d09ea19": "0x00d26818dc1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd04defd841f7efce21f5c63f123baacc61b796c": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b3bc9934e8b33722ca127accd270cced149b5f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c1c6383e5fdee5909518f8fb94e23d9757334e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513afb6537a80eeb60212b36c6ffbf627635070000": "0x9a58c667ab381990c1070fae2940bff21a5af23ebf4313e745aec8217277331500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928960540e1682be7484af2d79b6cfda708ee285dc8e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c69fa1a7e9572b1d8e1abf43739fee285e3b018e": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3afa3ce88a657a1c8bfb69da7910fbf48b36af6246ab91c868d410338b998a36": "0xb2e52e1a42c3ab5305f1b071ce7d197565e9bbb7", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511ce8498608e9ba50120ce172f85ec87666030000": "0xd43d6feb9c8b0455a11950079b65ad498771bd454e01b56907a2ac6362d7274b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a05f5603a17f60c7c651710b3c5b3ee254040000": "0x72ac4cde67de555c2f0b1ebf55bc45f0b61458d134719bf9f56d28867cdef85800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd8e8d4bc65f8628e10a4f90c10798486663d608d1500fd99c38e026414d35b6f": "0x2b4d63aa980b39130ed7e3ae50ec40c4d8b33935", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce1cb60d9a8ca55e467f0cd5ac465505d39b1f58": "0x00accaa52b0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769f32538b86469d94666f6d7f570185dda0a6781": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289462891ac9ea16c799f864e308c7e73829faafc02": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289db5d3aa321ed9182afd69a3e1ac855073fd914e4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a6629c7691f18cc987a61b0774a524287b5d0c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5197067eaa87b5054252fe7efe5b60299f6c060000": "0xa2658d4ade7565e18570e0289c8c4ecf3b923b424ea7699232cc678241d1e84700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51090f86beefef0152549b2f69c700c21322070000": "0x20d2e91f70891ab5b5ca943b300d5b056c47a2bcc5b13efc7c907bd73c384c5000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c83f97b509306d26b9a7dc44993e2d82f73a049c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817deaeac37aa13c38ed2518b7b4be3e4e7899c5b971091d93a4d33ae18231b1fc1e": "0xdc26b2ce9c7de60d60c165f8c70ba7f8b08286aa", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511fe1b20d1fcdcc86a42e19f9a4d4e14eeb070000": "0x003ba0c4031ffae41ee2dd2d8505f8e9f6792fbe955b675072c42d302dad7c6400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff110236b3b40155057b45ae77b99d1b38851b15": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928985e2f2767bcc9cb4814bd555413e2e17e1cf8459": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397749ba28f1a561b462e7617728bf8f62ce0afbbbc": "0x004072e62d2d07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397946ef62e1a97865e99dd8366a87506858d83f279": "0x002e808ebd7701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fae6fdcff481d6966bb864e8ba258c43df1d2da": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289268b05ee0e0e033bf074554452e701a250ed3375": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e538fc87abe6b95622e5af0d60906350fbe2280": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970096b6577d9a53f506476c8cc6212f947562ca4a": "0x00244691bdf401000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900383b93d6bb219fde72527528fad143dbaa7a48": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289542055cba6dc03f704e613894cc1d5bfdd74dbe0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928962431669ffdeeafb1d3b071ceebe443011b8d6ab": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514fbb32b4154a776dd72db7550312a0796b040000": "0x4a46f196fd6ae9d508b04218c4210a55b6ddce13348b82a5c5f2e8960601aa7400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707b63625869391c66528acf9610ab2c19d935d9d": "0x003036d4980900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512fa990badb5e345358cc30df9e1ed0ea0d090000": "0xe695de55d5fb0be7525b45245933bef3b57b71fc7eb68c38d0611015c3c6f22e00000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1": "0x32000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e73ecfd355db154dd6f0f9a26a610d791d95ed": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e4add2e79c9cb1b479a22a663f7f25e53f63ee7d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a926f76a86362c456e877e0b3f00c1a43b05c4ce": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c923b032f3c9641cfcbc6a909fb66b29faa5449e": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e8628d1190bcede69725c4e920d9ce42c23ee29e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5148c3c883d518a90c169a1ba1b8a145ba17080000": "0x88f66ef5a1b50f36b1ebc997c91cb47affe0d1de4d5d9be9bfe009c0783e912d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f947f05d2b295c924a3e6058771180cbb75cd60a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0c0f7fd4a8a750920dc953229b45f708754a2a0": "0x0064eda26a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f00a83c85b0a5fd088b7ef7cd5b4910ade729d03": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ac7850fba178228acbd4c8b601bda2342392e21": "0x0088d21c5b0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970532ce0c1d948b2e8317af8279e07561ee3a3979": "0x000ece41f8f002000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d48a9fe7dddf4711de4871c4a9f5c52135b49bdb7fe99d393b60868428e063703": "0xee13480f5e260b749022ff1e533a22e14e48c083", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339703377073f2421fc3d9eafe9e235a820c4038ec8b": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008389dd2775442702e13781f464c01558823b23": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd2cf95a89356bb2253306df3fa6b44e3281c4bab6c06fb3bf7a8268a311c4557": "0x009276734775cde94eba0c4fdb98078db07d5fef", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5133123b7e8fd7a60b67272b515fca10bd9b060000": "0x9e110ce4f1c6c10618f508aff37aaa6989afbe8deb5ccbc4c13ced92dacbaf6b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730caa2e774035687e738e60ed754c1787b206a81": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4bcf84bbba74f7ed07abf9e39df86bca995fca9": "0x0072e669861100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899b8a4884a5afc6cbf0dacd720fd6468b41b6d437": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928942eeeee8340f7018c662faf487351acdf434f301": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519467f371592a7ff9c8e6c6b0c3b202db59050000": "0x54ff47b0c118a4a37b57849e03c7a1b1e223991e427789b7d0b1a6c152c41d2100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890054d65ed11bf1e5ca7f22799d64d88e7e5c38ee": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513b5d4260af31ac1c134bb8a740da2b016d000000": "0xe67bd0c0f260a6fb9b90870109b8a97cf0f1442b4694d7c17a6f0ba103db850d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519bb518594fa705bca1166a663aa755a4b5040000": "0x74e407185cbb9a15657307dd6f0f589b1a275cbdc4f31578ce7abae1c8470e3700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c6c2b5e7393405e85ce36af97abf70fb59060000": "0x6ae9bce20ec8b89105efadbd7bc50d34843e9a12dba7eb10694105c61731015500000000000000000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950c46c18ba2bc2ccab6772616e80f72daf2e560e4f0f22fb5cbb04ad1d7fee850aab238fd014c178769e7e3a9b84": "0x5809fd84af6483070acbb92378e3498dbc02fb47f8e97f006bb83f60d7b2b15d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dbefd695363d03dfec48e770ad6859dfb30cac4a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfe1d28518ed43e08ee85b800b936b9111893813279dc718f4ed8c09bc407a80b": "0x66b9dfaea3ddef53b98da82a224f70842c817703", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007e98442eba3fff13fdb90fefc77b2afb347e5e": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b4f896bf50e0e40f03240f07c80a3be82e1fae": "0x00f67d9d3e8700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ecbd51638c57c1bc38e405ed703d82a977bb76": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e7e3f4863f3f5ac3d8f05e35979b020c62000000": "0x603153efe4c60f146d61b66d5c9f4a9b469291aa260899bd99083d755a28923d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c062628943a930b805849b494719c7d23c77bd5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b27b940bf01de20eca4abfd7c9bdb2304142ad5c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928938103bda64188813b4d890ecd742d389589525bf": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c963e429b2d92133d801e9cfbede0efe65050000": "0xcc0b999bcedaeacee67b1e36d207f68bd55f1e128cdc90b1a970b1656efc653100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ffda559dc06f88b229af02fdc41a5a6a48127aa1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f96700e4dcf528139667aca495b572f7e8070000": "0x6ed6a67496a5bd0146cf3595ad50be243ef788d6ef3bde1d66e9783499f8052400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2806d2821e7ee92952bd25fde83ed76930fd5d1c7139fb9f3742991ea3c3e352": "0xeaab1f865f5fef8b614c6b2468333205122cd5f7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786a62b26065489467abafd4e02c86fa4ba37e8fd": "0x002c419ebb1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300fcaf0a13a98b04a3080d7e246ffa7d072777e7": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895529ba8a2dd48942abc90f9d08667b4e0e7be69d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cb2bef1fbc9cc3220680981588cc4e27f4040000": "0xfe5b9cf85b687c9f15be1e46995655e81764937973191978549c4362eed9722700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006a8106e821a1b44cb0626f7fea5a951b11a282": "0x00f43bde630600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5111d2df4e979aa105cf552e9544ebd2b500000000": "0xf1fe9f7ba0feab9e47684d4006ed25ad6c441a1553cef62748545ea575392af500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339749739691fb5f3992b3f2536f309d955558e75933": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397572613e81421b11b7cf99fb41c3bdcb915a50d31": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e63bdf498cc6781799cc23953e32dce295a95a0f": "0x00600eebf2bf02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893f2986549e4a6d8486b64bee434a3978c3e5a1bc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f18ccca441625179b40e774436ba038505fcef83": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824312f9122d6ca5294f6817ae79a9c4634a07931a85": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f24d94bbc5db0a1b2e34b4569abd5f5ea8050000": "0xaa86d43d6d5265003d203cf22d753c9b3a4fb8f651c6424d68768a86c12d384700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c885efcdc3b5c736b0407b0e402b5b842c81367f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890273a1c21222e27a3d41dfb835e07af4b4494c08": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900165863e6f9608161d8533e213c009390fec3e7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c4a157e6363fb44cf9a3edaabeec6657914f8a1": "0x0012a7a61a0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973274e22d86cc21778df15836833e147b1894d3e4": "0x00c07ed6adf901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba22a63969aa637e9a0d4ae31beeefe97ed270b2": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cd28ff9bf4f1a4a1715dd4c364254b7b74050000": "0xea0f7286121217c6369ad3c99f1ba910f5137aa283da71cce47111244fe2cb4000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001c693771e3caa38974d719d5ba8b65654e916c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928943eca45f63a712ae079385f35e1d0622a2c4132f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899b67da45314e56d9603cba1d09804e710759b57c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004e1ef7504fcd7d982885efd88d190d3179fcc3": "0x001c44e7a71f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289be0c68748745eafc6cb8e7ffc3666f68115954dd": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6e747c701718b04a86a4f693a987662fff73f1cfba6fd907d86662725c824707": "0x009bd3c56ae851e91ac23e8a736a7698de525f1d", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243cc3a572c4d49eeabd53154a59779f7eb6da912a9": "0x00508df5952701000000000000000000134fde0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dda6898e71868f7f38396c71107b01396ad4c36a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970038954411d31a29442c8978cd56cb764982fb65": "0x00fcc39bafee00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b07cf336066916f70b0b5c90468feb73790e1e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f6292826b8af10c8b70a178fce20411da8b37b4": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f613cbfe3c3552aa32bd23cc820b811b666007e3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ab255abe36663fccdba892c4ca3bd160bf845f35": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a82c7fd9dc03658b255b5d68e6251146748953": "0x00fc245ca98c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289136cda791826a28b55f4af98698a51f3c5ce4e9b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512f1f8c68df1c887eac95349aec6d3b407e000000": "0x462b54f04a4e212e9f2f1735957fb753295b120e212052c7386b6f674dc5af4d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d92e5e6c84e9781e37eb1afb166eefd22687054c8bbed4426282077b19aa0e708": "0x00d01d14e379d23d6a9b47e8886761d8e9d7e56f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890026db7abf8a3fe7b3543a035d11e22b90615ee5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a20f355ae68be4805fab64fe798f19e6db744a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289438ccbd79f20c1e68b828211ec2ba30c0ec9c05a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c0c5b7692501593568f6ffec95a25de72b090000": "0xf68f12537fd063f3949875a1efc2ced4485685e4899a8674c64ac042dbb67d4300000000000000000000000000000000", + "0x0b76934f4cc08dee01012d059e1b83ee5e0621c4869aa60c02be9adcc98a0d1d": "0x1856f0bb1f6307e043be568014eb4062a9bca4a255f39ed0be9205ee97c93b4b6e3c7d33a7ca6e152bcceb20a75bf67dca553cfe1fa0546decfdab25177765ae07a25cc78808d9ffb966aaa53c3c399cff7ea0b409dc8b42908b9f2da6d34c352550e91d8b60377c58f1e8dfb6236dece92917f1b4ee67d2787ab090c5f8d2200f9ab54fd64223ac5dd0c547efbf0015944d1bcf8f4ca721716d8922fc940c9a61cec7e2d5e28925ae9f906e5ebf1c81adcc7e524751273a73a278f472d863f532", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282433e784d624d4e60da998bdd79169edb8beff89d27": "0x00406352bfc6010000000000000000001ddcdf0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dace38628d126313f685422e818d27331e9afae30fec205b60f5741faeb831c31": "0x5bb506f259835349974c5fbf0bfd5cbd37157dfb", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc2d785f6ae83eba091d04a43b9dbb91ecd9862ac20b70c46ebed79f7068e6e62": "0x2dbdb05d09c9e0f10446881b9be2e107f91f7e41", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cfcf3ff87b3c34cfe4285a85f2115f96cf0fe5c1": "0x005a3db8ca1c00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e5513acdf30de3194ccc93acbba065113e070000": "0xc02535f37b33f8787bde96761f4643f2229a0d0553c81883939d31215b4cc30800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ffcc480bf0e6acdbfdf71c7b8ae796647378c155": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c116f3128654372fa53ea006f91d4a6cc8ab13b": "0x00c8bab0cf2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972406879e1a8d273aeb64b000677b597ae8db8517": "0x0000a4f0727b71010000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890c90de3a4c3005a259e20cb50402d7c41948c657": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289577acb95cb312b867f08b214f421a52497597688": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971476d4c5204269665dac82770a8cfa80cb4ee953": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817decbcba92701cdf5ef12ba295931dcc4867f816621fe32a9871ec2a72247e3569": "0x3e527eaf454a93e9aaf096b404c8450e66cbb9ed", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a172d2ca38c6011f6a48bc781b2196b294e3f2aa": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d54a341917b5bc8c35dc4182e611a4b4d7550e1847669fd6203c3c2fcc9ebe465": "0x40692724326503b8fdc8472df7ee658f4bdbfc89", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fe265551142de05f83c1ae9bc54ee9bd1248f80b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d84f70fa89ae1707982e11b6ea49d1ea0f4242f82b963281c7292683d780ad50d": "0x3310cb1ad03f5b8a93d5c673e11782f159a017ad", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a0c59e84c73e9f41ac8dbc44eada4bd908a07f05": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7051b75d2765d40638e37a5d0dba578dc82bd9b6ad5a29c03cf7200402125618": "0x2392f61669f6e3b81a46d30210761c77b0ed35cd", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512e48556ce783f4218616effb3da5069e8f070000": "0x5e58b984496c06c4668dc371110f5c0052d826627fea35dbf7dd9254d719665b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339716eb8921f75fd6761fe5cc90674bd9c69d05d1ea": "0x009c7912141900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d82fda6e5d6dedf42042f3ddfa2b78b152b6402": "0x00427f58a79b02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890091e7dfb2cfa0adac37bb5cab874838973c7f0e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928975485be7dc5d7e1218052accd222e75d4484df1c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794c70b28e483cbfe9d7554e211f5f38ef9435bb9": "0x0000d098d4af71000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899782b9c2c85c2e9db211cb6200065e312853e68c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d34e9fe863c26cfcecf82bf4cc18701b3ad4767f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928954036dcfa7deae92f0d948088690cfdfea648143": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891933a3602d1ad20840dc198946803e0ab2b49d06": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dba439a857d9063fe02433e129da8ed247e75351f480b1b2fc023fa1023795625": "0x38c1a42ec8564eb3a62966a831a5fa45e42b5455", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d8bd56a9cb0b6a854305830f3f8269a9e5e705": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515de7deeb2639f871ebc4a32e27ad189bab080000": "0x460711f6cd4dc36bb338b1548884b1ce28f5d919f9ce479116294dd34784524e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a42e82c8cb31068b240772ec69685ffc59b7fd11": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5e500d5c726fe768ca583c996e244d0d809a1c9": "0x00e0e6a5d93411000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7c75519e31519e8ab8a48f5ed081d4de06770298fa42f2a469619448f4896804": "0x0054e99a8a384386279936d42dcbabb4a710ee74", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5cc332716801e8f3a44b124dafbea4f22f4d3b9316d81e16815bf60c1fad095a": "0x50dbae8912187371548f53f74fbd269f86fa44ec", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bc94540e69a5c2d5a2e8432e99d9a99d66265343": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c9f5c47814f33659ef2d1996a0961e80b8597bf": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004cf480789b4cbad22bdfe4c1ae7ccf4a4675c7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008d4e47715eb112c1ffba14275bfad41150a735": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d74e4867b46b4d8ca428315963427c002b2e78d0faf10f6f7ce28a3d963cbc65d": "0x574f85614c44755bfd42ee17a3bdebbd67a531bf", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744e5715f7db1a59de2af178cdad023b16e39da31": "0x00fa3a40d55343050000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928901e086773e4f00f25c04e6f0b8607274ba27bd94": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f7a2d983c0ae1613f4b3c50dd85965a81fa43a49": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289422af240dff9d253cd31c30d5af9647fc60bdc64": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928974d452179482b55e13d4382a7cb9fc74392b5e4b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890751f20e8b8b2686d8844d5c452ec8ecff3fc36a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928986821570ee3ec4bfaa2e2ffbbf16ee4f61336dc7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cd03d9b87fc7a4669076fb8675021f04e4e8f9da": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e283542b59d9573051c34e6b319b3c7169060000": "0x34ec6782d6aa76c498734281a7118615544a986f39bcdb18fd3542fe567d044d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289800819914cb399e8eba6cc9f026066fae96e4ff1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891daedf70a4ec0745ec4968d3e29ccbb4d6001109": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f39b53937f425d7e764d6b1902bd775ba3d514e1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890010e77665415c63e47bbe3dac8a0859f10cb525": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b9f9d6b531546e4c80058bee5749d72ffc76b54f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51734d819cda9ff0c746f74526af697af732070000": "0x937ef7f30b8533c60dddd948dfca54140055f7c001bc8b7b7f4e3cc483609b4700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700eb4363d35b0824c7ac8b54c2d05c6bf54b9946": "0x000258fb633200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c24318e1ea1b011a6a84d2f83436c77bd753e840": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd0cbe2eefa616252e493b03b5c2dbb9060784ff": "0x00de83d2453e1a000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b8d82c1ee5bdc3505523ca8d1e0e8e7df6b10b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513f26ee7b9a0580e24fb699329f34fb62f6020000": "0x28e3d3c413860766007043602a6d6921c324a873c736d96691a40c9d8ceb8d4700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ac8eecbef704590852f8e75d87ae2da59bc5fc61": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d22ace5447bc2071e2b0712f2a8dd927634840fff178eec30ef93bf15055a462c": "0x8ab7edcd19d92170528cd5d8a7d25dc6ffb75c39", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002176cb83b3b5670fd6231bd92169346fd49227": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006e724fce558be730b5ebf7f1d4da69b8d72daf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890014c1efea175cd39fb686024383fc07374d6db8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e146bab9d18b787b7b863353ed89536b3b060000": "0x8cefa6b7f204e06e8fda587af0917d02df5a35ceb8bed4583c3a5e91352f834c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970074a0ca635c314c5cd73ef58b1b8d64c5d7d20b": "0x008e713b42af00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b0b1000a023e99555058d8dbce1debbd149a6f6": "0x0062ebffa05700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511ef757a1cf6564b9a6c8199d5d0f738a60050000": "0xa69c4536ec42bf8f3b60198d7b78be15ad9a147ed73f25164474fc61af261a5300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727efade55131916b2f0a34e313d858bd6a30cf4b": "0x00dae7b3f9b101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289414c8f14496260104e238a324b6b02a7e8d2f4ef": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5127379300762fd73ce284b5725ddca35628050000": "0x5cba75ed8675adb79470d814cf37fa72d13b8df12ea9651a7e65f6bd526bfd4800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d5ce12a848bb0d982d8a07ae5c462f5e9a7199": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fc7d085592f433e4523a2bc030842427b63ce31c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9ee708bbdb68556d834835ba8214cdb27197d54f6d0fb26107006cd5754b4951": "0x8a34b5de30bbf7a351c897e26b088397487bad42", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da46b7c2ff66b1247e437df5b9eee7da98a4df42092e82dd14f74b8ddf00cae1d": "0x4341633902051568199e6436ef96483c49e72dd7", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da6331c5c97cbbd671ee9023d3a163d81e965dad7d509f28b970dc86c6f3e9855": "0x0030122b94e0e0c56a5b04feb3ec224244a5b18c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcf8700996507fefbcbe7258ff7f5af0abd5821d": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b67b5d99f7bd244fae58ebf86d35e38f72cc7d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e1c778ab3f6068c5583ee0df394fc7251cb00fe3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a88f54595f9543cedbfe0697532882ae3d70ea50": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793c419191cbbef6717b1992a1f854ab2d90aa7ba": "0x00fcc4c468c320000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ae41481227f53a5b760aaf3fc5f0039ed8010000": "0xe40ce409805d07fb7286ab3c59923f87776aa2f51d1d1b517ec07bea804a871a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001b2ca922cd635a78fc6e87d33b8e8726e057d8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5135f1709e2cabd26728fe6f96889bd4cc88080000": "0xedf6aa7debec01f84d3d24b349540814e033ff7cdd6f0c4200657758f1d39e6500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c5c5385fb7bebfc1fbe02db4b9c4df76e39941e": "0x00a44ae6333300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891f77687df949341a0fd8f69a3b557a26e13efc8f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5121f6f22acffda5f4dc09e3a938e6007b0a050000": "0xac33d356f459227a73109e31a9745e0a5b7d366ab0d489fc0b2bdd520c4cd92f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ae00a86d40e8e73dc86d13f85c1f4a8c89bed88b44bb614c7c33290e139b374": "0x0001343f03e9ad77fa47f674c4ff59d5fa11fcb3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005b8da2c805e382fdce0dcdb2bfed16611861b9": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ab3237736c07beddde7dfdc0f9357e00a9727646": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e53166f4d724236b4235a9bacef0e425d9f13956": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ea6d745b4dad0ef65899ca31e2989b3dc49124f": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003d69a4460b62a962d7dc8f5cf77db217998d25": "0x0014805c4bc800000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19505f8a461f1ef963666175646980e0a3e2de329a70e2763438a1a757bf6dab945dcaededc7455a7fcfae83def07b": "0x3887050ecff59f58658b3df63a16d03a00f92890f1517f48c2f6ccd215e5450e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3bcb85f93385dd35ea005d6cb8ee5e093657f39": "0x00509905887905000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eb9458f5c5facbba1a3d21099f8bbec44d7e3d00": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b86ef72b38f189bbf18a94bc46c044b73ea807a": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289391a6bb5f2fca9a19d16f09aa298e9e23288a5f8": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea67cbf97f4e26cbd9406118041b54ad460248c3dae2f3d12c2ec84588697803": "0x599ad3f92f76e859f7b7a87dbe3aacb81e54c6e6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928901c0a58e08274297cf31f4660c89723f655de3c4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aa5eb42c2fa202b4df66a36994d41e04bb3af2b5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e4df8be3f7e423f508badb894620fb54e0080000": "0x22f00f2ef7569b9f5e8fed76777eaae266c7c355b03000329d1e6856791ff22900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a34b5de30bbf7a351c897e26b088397487bad42": "0x005cbc0f3a6100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894aa9324f187b1005e43892e3fe65bc9c78bb8d8a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fa022c7a8d5712e902569e7dbefc471919a1ad": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e577a9eeb79d887f0d6bf7f504c5f273f533c04": "0x008c0d35660200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d8a185b4c3f9684a0c7db5a9f49a54d9227ebe5e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289175a83f4a1abbb88f6facc969d669cae9f48d7c1": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da25fceeab53dd6644261c4723907ee3bf1b8229": "0x00f45c7452f600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bf2209a10d9ffda04bf453bcb3e367f3eb6756": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895a6e3ec695183eb5c9808f550fff6a29d2f40de6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d189fb4ccfd8af44b0027a7461e069906aa1fec05da7ac552b54d651fd14b881f": "0x3dbc5ff979d0f30d65c33f684eb4b32cb4cfd3cb", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928990947676a04a00d14056a9d1d428e24999f60f2c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d265508bb6b8c2e04c18c3c0d7491fc36935f55adb4ee5ad20d5d13b90e1c4978": "0x537b2feb029a7073da038c2b9bd34c1c6109a0a0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c29f18ff6f0c0ba071e0c6435efc1cad05c25a9c": "0x0068eda86b6f08000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ac8a6d59db3938ddbee19f4ec3ea8a0a771bf6e": "0x0080ce9d58ce00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897c019777dfda36dd460e7322fe6e1f5c94972517": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005b2192a3fc9f380351b5931adffd50a3614731": "0x00a4d3b34b1f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b7b17b9d5739e3612f390e12023966ebe8020000": "0xf4e69b23f84fdc3e0482543eea31a871c709f845d9a5575ee148679266db787300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397abd9a0c14b25a69a5bd2f2c67e7192d88e64d152": "0x0046fc085af703000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824338b89b94dc5dec100a23fae5b5140ffcf81c8b24": "0x0080a1a76b4a350000000000000000005bcb3b5600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008ad80219aac538f2374ae749d1ac797da21bf7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928903377073f2421fc3d9eafe9e235a820c4038ec8b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289230647d9f4ec617a62a6685058aff69d729a5dcf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a0d73de5df565717a3994af5cb75455d8674b46c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d761c14101d6d4d268b7d8fe9df7b1411fff2e3c1248cf72b1fae155214b8d35d": "0x9bb987d0bfab369b9eca904b842723670584a5fe", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2021456d5c848daa658b302a50a0a682e78f24599a6fc4b224621cfb9f00a953": "0x00e3ea41cc49b5791b4410ecc3d2dc4a303e09f4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891f0047ad5e5ba9963f9430b2306b6856aa5b9b15": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928901beef9b0f0a48597e1454d75eb062d70775b13a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928957981d9691cc20a7ce7c628f6d7b1ab82fac8607": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9a99db07618548fa203c1816e4fc95741d00d8d0ce0f38eec8633f0ea5a6c519": "0x383f42b5de515c564641f65f5da3bd8b4a35b4b4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008350bdba3dcc3c01474bde4a9a6bfc4144baa4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f18055387961a61eeff5a3fcf9d510b56a94c6da": "0x00f0f1bc9f2500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a6bddeffe26cd501deca6569ef33870f15aeb637": "0x00408ab5c74301000000000000000000a4ee0b0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700116621921d8a7b01706539d19d65ec48dc7dcf": "0x0066fa41c93400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd69dde7cc6a614142150f8edc4c87b2f48a13f3a250b2a9698e7c7e473ec2615": "0xbb9f0597834168a78ec443f09f75e3d62ee98dd4", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2861549f4eded2d6aa490a7a313e0108aeac7c17bb63ad2b99f815d725311e33": "0x20ac64b955ebc54f7287fe3ce29671086722b60b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732878ea4b480bcc29e7404128a116c75278b80c8": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e78da27c3d7a1ae6ef59a79946d8c77a708319": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d604ed1079ac6edec50ff937aed6ede2929c20d1d8b15854af06cfc7a5adea822": "0x07bec2143e7052bc6608c012ea585984f8f9b27f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f156f0e79a516f69163743f87e592677fe3e74f7": "0x009ac9845bd301000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289531aa49f00416d099c75ab4ffad972cc61f83de1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f9ca97f3aa305699b44f0d8cb0cb72e7d2060000": "0x8820d7c939883f302beb71f2d459632bb46ce2ed64456f90e6b31a6980704a2300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976cb08b8792e23b72a3af06933a30997d51ad1565": "0x00743ba40b0000000000000000000000", + "0x2371e21684d2fae99bcb4d579242f74ad47cb8f5328af743ddfb361e7180e7fcbb1bdbcacd6ac9340000000000000000": "0x00000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970e5b7813fe019f6aaf820546035fcbb40b58125f": "0x00823eec0e2501000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d5bd8a5efaa38c2c9f3ffcc73006b8ff19192e3": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d06a27940e88886fb198b8d92bd517084e259c3811495ceabdfc4ac5dc99c955b": "0x34cc2861eeb213da8bf366becdfb319f16aff12c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339733f00d8b2e67b6239aaf2e152efc9d85ef113583": "0x0044de13149e03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897525af9498280da3fc2f5498c495e89561b8ee79": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b60facbf94a85c68b5455253564a2e60954f70c8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397081754b0a1468f7ee643f1ff9896174ddc6fb4b1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339766d3157036246be0bdb9bb8427313949b21a70c6": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510b31b43f36acb6f7029f2637c054fab97c080000": "0xcc5d8f3af2e32f1c627f09e1c1d2769249d00c17c12da2fa06ed040beb38b1bd00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397862453aa222291ad19396dc22a94d2688ffc08a3": "0x00f43e5be3af01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8f9101b21f47ceaf22f52b0f4373a0d95ae7af9": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0fb96e2ba70b2c330c297339cb535629f887bf0": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928938f438c88c8c43562c4ceb3c0d7b24e11c03b708": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c35a8e70b0530d2bff51daedbcf752d8dafde91b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51df886d671ef48d3ea7427ac5a9a9a3210b090000": "0x2e0b481719c0a64b20d1e541cb40c80c2384fa61c77e56bf4787ab94447cf54b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51228c67364b323839d09a5aea89866e1bba060000": "0xb4f1d6715086ecf1c0f4f46320455faec20ca76cd7dac4151427b212c502196400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900878eea2b606244d21b41565ebdc18bc324d38e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970607df4570ebc920deb346220ffb52a0bf1fdcde": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928918e653d8262814fb82b703cf058c97e7b2020c38": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fcec00a57e3900cd43cc6f187ad3deaaa27ff56": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289035e77f52292994008eeac5689f59457998f4f05": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289da0e34cfc36d47a3e0c08d8fdb0ede1408c7aa3d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700360b1b494ea0f8e156f9f003732727e94e6986": "0x00a83f001d8002000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5101b0c2bf5b42b400be5bab5e1544ed2f20080000": "0xc4b2c91d9d4fc939948ca13e03fc91b01b6c9c286ebdeb4c6f9843156166aa1900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513a233dd5caa7af24cb99415b9fd8ebb920040000": "0xb64c29324eb942fab6b41cc041f0e099f35d5c7fec824bae17717c5fa68cb83e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778fa87ec68adec6d13477e797f062562cbcdfb4b": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51862984261aecabc9ca4e1b3b3f94afe62e010000": "0x767c06d934298a9bf8f317aeaf2fd3a6481fb052acad0b9ca6d8dd5dcc103d0700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000ea5d2483ef8ee35807c829bdb6addc0f8b76c": "0x00bc8b6ec00100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2c0864711e2aea8b1327f958e73d8c4de709a31b05a72defd997e5538c545651": "0x2f41a6aa9773d67c3d31aab2ce54b27f6945b049", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a63a3a0fa11052369722629a9ac94a23a8960d": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3041ce2ef4e9ddad0ee763522a641b03863d5a5": "0x0080f420e6b500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767303886cd4d268eaa3a6cd8de51413da1a72dcf": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289511912af85b5b6fa435339879dd81d5140e516c9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b61959b37aadff714af150580559858483459b8e": "0x00a031a95fe300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d729324ff6798093939a73546e0f3d53a9cd7d4e938d238145c9422ce9f0beb07": "0x861bdc02d79dd2598d829fcba91e11f1d26b0aa0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397853fa0c1b613b0756d7798756eb87de67a6787a8": "0x00fc6276e83200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e18a7c74b913a4f28da74fe2c194ed4655d63e": "0x0084365685e34e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f1e189ada672a8b8ddf69ce356e287ca318f99": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002954009901528acdcd08e4bc173f271ae4c291": "0x00b638bc35ff0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900db158028c2d7db707c525956aa3fde0409eca0": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289210f50483da86a563e049ccc0e261835a63b98ee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928955a3df57b7aaec16a162fd5316f35bec082821cf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b752d54f3436601d8ccb4fa02bf2289192e4ab59": "0x0006dbddfd3800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750723761bed6eebd4ad8cd418b0b262a66fc0b97": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730b943dd80ec2729942b65aed370835bff04bfec": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5185238813c76906ee6d25ac80d69a22dd94060000": "0x141d0c26801c2dd28a7024e5def054866acaa52b6f3ae9a75bc97cb94635875600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928962a98395a16d0050d55a4c575daf1048bc9cb023": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dfe4c9aa892384176066b2776c0507c17cbf5099": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e302eb54d1c41647ee0eecea4d5b7dd90dac8ddd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eef5a1f6ced7e72d0c52f342fa1cb6e8cc5fd9a9": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511453df8160276d2b9f81ec3ccd4d5352d2050000": "0xe2e6771397bb71c2008483d31e053f551649d98fd835a540afdf9edf781a322e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515e5f4934fbba1161c414c9e69b62d3dd81020000": "0x9867e6bf67fecdb4e31c565bfd7854ac3604f1718e52cdbc8464a112681ad76500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db8a3477a6ca9f9545ded0272a812d70c23b1267c8a7d0a077aef540b1d06087a": "0x128b1dec802ddf81681e3d6f113bd83dd852311e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895623284ba17d06a852e3c74b6b3ef1509a13b65d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dca9a6590fa55d82d686597287bef830a7f0e7eae2650c54f94f2d24995253308": "0x52a7310eb44ee058ca1a430356defa045e4153b5", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de021bf4bd6fd2aef6f2ad1e01e89cbd1e86ae489393d90528d634c06a2b4e209": "0xcd9b1a9d7e2c239ccd8fd3f739bf2d3bdb3d6a1d", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4c5ba8bcd28ecb0062f3c8ccfc909982c23ac3d0233756fcc5ba5e88e752aa4a": "0x28cd36b7b86b3d6a8d53f0332fc3563489aee858", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517c4d701c1bf50a4629243e55b5bfe7d668080000": "0x80d8a3f4317249a895e4b49badcfa7293cfbd215d6e552d1c07024d36acfbd5d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d63e4031c07cf74da563595cf55df4b52063a7ac": "0x0000c52ebca2b100000000000000000030fb711f01000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95ad57628c1ba701bd2cb2d792b0ceefd88ee494d719d68a18aade04903839ea37b6be99552ceceb530674b237afa9166": "0x000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e3bbc9586ef4c2baa9cc995fc50dfa7118d35dad": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ff110236b3b40155057b45ae77b99d1b38851b15": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000bee5537a6910f6dcee78c1ea1b7967d4efc2e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d22bc7c1d9f897c874dbee193dbef08a2796a31dc46ac7223db1b1bd61d47db28": "0x83d8e1a3d7f05fdc4f4a1a99d5a89bcc62324a04", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d76817c2ac6b91279539b83574f5d22009a2bb2f37fad4f0ffc8355e69bc59a6c": "0x3f2986549e4a6d8486b64bee434a3978c3e5a1bc", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890024f96565d874463a46684d2f276318793049e5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c589611f018087385cbd3d91b8fedc67f2c9c795": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bfb8779a31e7ad4c1e4f852383bb1c6ad7dcd0": "0x00a29994f40300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005a2a05c903bb1491b9988dbcc67cd15c7f491d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ce1cb60d9a8ca55e467f0cd5ac465505d39b1f58": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243151310c5ed21bc68b85c5c754cfcc5a7b1869cac": "0x00901ec4bc160000000000000000000001cb240000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515fd0e7751e8a7bdd90dd19a1eb7a47c961080000": "0xd573535a40bb01903e616a383deed22b5e3ff30e552017d2395e3e75a8e7861300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fa8bf8c0bb1b6a89bb9f45a5228aea9d296653": "0x00e0609aaf6f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fd164dfeaeafabe0d241e2313b57ea7fd97747d9": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514cbf26731c23d9508699dc374ac4ecac97060000": "0x8621027cf6c97d46500c2978193be29b4fdc1838cf768057440793a5910dbe2000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1b609382d115d355e65a0ea206290fbd6ccde06": "0x0050248021e301000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2436d28eba2d9eb5a342e5fc9a2de9b2070f4a20ecca3dfdcbc83fdb0d199236": "0x00964d7fd8a498f37164ba1c1b5dbb99a3c90125", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006e514cf3312db766b10f6ddc624518b8e02618": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d28dd13379371ab7ddb0b1efae7ffab1bcaef3b3cce2ad502992952c1b70b9a18": "0x8ba5e63b8242e3720ce62015edbbc4037bc44c60", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ea1f1e791d12fb79e53eddfb13fd9df66627c49d8fdd6773d19ff40ea360f37": "0x9505ea825ca9bc29d21446a6584c6771b21f193c", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da87141729cc078f61473a1ad23b5b625b23d88c4329a1d4a7b4e9d22b0e2bb40": "0xb3393e6991ccf120bf7d83e6e53aa6ac8ac5c551", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6bfc7493f9fea17283d9060a6316b02c3e92bc1": "0x00bcc1fbefef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8a300b59d4f4b3bc88e66d4ddc8edb8f0703edf": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d97436259f34e11ee1a0be1e59a98a6c4ccdbc": "0x001242a3973e00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c344e1c2841eec8b00e18d6d777a01aac0060000": "0xe65a278c02c568b67d0bac04b701deeca427066d27f8ac2237972bb86dfc484000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894fa4a8ce59764fbc5166bfe260c1aa4eaee8023a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c610dd72844e40880581a02fa3d3d881744c37f1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978b584cf38bfe7d50809bbc2a622c7bd118a82577": "0x00d634d4e71a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339724586e1a8a6fbb94ca745b6ceeb98017fc8de873": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515e9f5fedb96c990343988c64134d5ff818060000": "0x4c3412318ed1dabfcdb03d1e7776a9888e9482e7c7154edd44603c439b65fd3d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfa407293a2fdaf63407100b29d4c02196810ac847cfbf3d9b472e29abff58728": "0x43140ac2d3c02cba8e461602cc15c3889dd9fa3d", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431df8d1ba25da8a9d6804aed11a7650f89fe91996": "0x00007eb58eb401000000000000000000e86cc20200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c522a2fe6dd800459133be7817b955fae0beb57": "0x00a61c778e0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289596c4221758f875f51403416940e0ea1bc1755c8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001d4db20608af2ddf38dae3c22255f5a6509cd9": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e06881f37343120d9e61be3ec5772250d7060000": "0xae43aa58d1bea3f6cfe4741001f77174a074659668bd6a8ad6fffb9c34915a1400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8a05b03e8c6bb87fac85e9d3a627f076be05c5e38fbb911f88510ee1e274b700": "0xbebb6f638336fe10517a0b38bd73105f2086690f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009bd3c56ae851e91ac23e8a736a7698de525f1d": "0x00fa901bf31f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972cf6d5701b164808a3f3886ee6258bf3208c3743": "0x0010df60427b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003febedc03910f869564187f04c2ef1ab840fa6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289320a67f5d718c4b541a5ef8194ad4f4638162f6c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a490262c85d993e3318fd0bdf26bf6ff5c470bf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890037b4f93292da122cee7227bbe94ebd9f2fe930": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975140e3aa403d274eaa6f6b4af30e2c050c1ec8d4": "0x006ee223f3bf00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518a7719c533e62badeafd17f70115487d25050000": "0x5069765b772020113456bb1fb00f7b2f262b30fb5ac03ba3a803f2250f09725100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c62ad9fe1773e8163ddb765169ac188aea5b8403": "0x00366603bff80c000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a3db207ac468ff88714a85028b6fd96cc90363": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c62019e4aab737f1f9cdcdc73c3c55b2a303d5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c83c9437f59ab9d5c0f5e16a12bdb905158912": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c495e48cc5612e90dbfff05b12532a69303bf72": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ef039c706c593b89dc9a9113f96430cdb47a592d": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3da1d74e69289876782104c22c383925323bf209d771dec6e1388285abe22c22d50de968467e0bb6c": "0x680d278213f908658a49a1025a7f466c197e8fb6fabb5e62220a7bd75f860cab6236877b05370265640c133fec07e64d7ca823db1dc56f2d3584b3d7c0f161583cfc25dae5d649a0d4f2775656419f2c9a4318584694bb60c66e8d0c8b96f5029ab54fd64223ac5dd0c547efbf0015944d1bcf8f4ca721716d8922fc940c9a610a7d2ed5da6a62c32ef4477bef2a1ba05c5feea57ebd44516a8257dcf9a3b67b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dc120c0536de04a202721962e9be40432ba642": "0x0094e7521f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282438f656b95dd71863355bd5aefb313a06590eb921a": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d068f8efb41894171c5344bc16f74eb1dd05fad93647955140e0f7d7711d1d82c": "0xbb5d0f2f6b345f9c6afc5bcb3dab5ac11385e512", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a728387999628bc1f493e98cf1beb9c604315e27": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004e1ce5cbd307c6242a9d224693a4dde031d519": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51acb0af5ad710382febb3fff232e2b2bb72020000": "0xb6caa98b3af02040bc59ac2086370f722bb98f22031f65f56fa9a5d2fbf8d84900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397699fcd9fc201726b30d6f6dd8b3307334f1b89be": "0x00a0d6432c8f0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d97e73afd7e39b59832ce426537ce534bb5a34a9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339753359144f93b2a061fce84895acefab5b537a055": "0x008642033a1d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da69382e0d2fc2b3044c30b46be39ce071c773b9333d56631783a535be929494d": "0x100dbb75eab5d98ad65ef16483aaa68e68aafbc5", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195095e8fff66ed5030b696d6f6e806a103df5c5131813fa77ba4f8be88b2d2b4a47323d2011c9d987615f067e9e78": "0x3887050ecff59f58658b3df63a16d03a00f92890f1517f48c2f6ccd215e5450e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3aa9d6f420f82d9f11560aae9fd19c539b967c35179f40613786f1046228d968": "0xe59d5f000bd5e17b3d5f9a87bcf85d1940f2aa8e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001c693771e3caa38974d719d5ba8b65654e916c": "0x004cc1a554a700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007b6e06cb7b7a104d3ea36f466bc14ed99eb513": "0x00645dd8e71400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51308b666c4f525d7724bb508d74c3ef854f080000": "0x9792a2ef4c3e368f3e570caa0f090fe31d6a3cd2f9d0b2ec270067e123db105e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900eb3893593421571007c99eecf18314b37d2319": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8e5df47c25340b48d443389c64abf88909ded6b6dd62c01548840970cc4f14a5": "0xfcae7970392f510a985a7eaccd3820b7759d65d9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700aa4c31db8fcf894fcc3499b2ebcf3e4eeb8842": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397177a47426d4c1a6a65276505167c36b663db2575": "0x009a3f588a1b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751e6d5501ea26f012b2d37fbc4933bcebcc28244": "0x00e681c6a52b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6aea039650e63303c3c78f7b1bdd0be8cc2ac20511c074822ff5dc02bedbc02e": "0x7a47861cd4c65225b1e00284090503ce41023acf", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d324ec702cbef49677b575d5f1d84768fa445f2e273530172952030521917985f": "0xf21a0e51dbf4a93d9ff5bdd23d6c01775f1d708c", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de8edf00ce75a71ce5cf3a1aebd19a0ea171c5524bbfb858eda9fd5ee6be34879": "0x0090087b636ef3f95b14a4dd93d28fb2b1747fea", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b5f703d39c4328cb7e87a6d73818c9dc2e4dc6f": "0x00c014c51dba01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d8f150feb4983f36ab7bf83f0829c94a00471c1e": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d2305280d7e05b1c3c5213fe4f626c9b5557af2": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898e6365a5dad54ec79a5411b6a8100d6b25f155b8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51842dff5eebb05d057ab147d3c4b2045268060000": "0xca00f0f34006135ea399fd9f872a904fa4d1f2d76c9c4b681337fc5e2fc1ce2a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928981ed4c64b1809a7e859cc746ba10f8e777358941": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289123685f3b3c7550254f187ca3746db61e6a248fd": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893d5b125732ab8687d607772cae3a63dc5784ce87": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896abe176c495486e953392e1203c4f675aa7bcce0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f48b621ec245ae6a2f1743302e9a0d2a5b3e1228": "0x00ec226f1d3200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ae0942112b3e1d36089fc756b8a71cd765ed18eb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da686df428ce6fef4c9888ec3b9934c66ab1a0c1b475c22d5ef0fda78a1f9cd4c": "0x3637f645f8bdb74e1cd1b28b5afc64c4a29c1f1b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d470122b2f8c87b9303d36a4d1a0c089234fa31": "0x0032efcc580900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300b07cf336066916f70b0b5c90468feb73790e1e": "0x0000c52ebca2b100000000000000000030fb711f01000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c70ad716691ecf66e0665397fa4a7ed8f5979b77": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970062b58537fc07796be0571257f39a591efe3cb1": "0x00d89163946902000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d14d13395a032cb5e4aba7116449d03472be74a0a8ba9a6a97723ea6bede6727b": "0x007af51d441a632cbf0b4ec175e61332f28583eb", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5a9ae1e0730536617c67ca727de00d4d197eb6afa03ac0b4ecaa097eb87813d6": "0xc4895ea497de505d9c6e2adcc2e036d1d567d088", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e570c0980bce80fe9be2a231dade76b1276301e4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513549c882de0e23715cbf7b0793715ca2fc040000": "0x04f884dfd110962de6f4cd9068ef5bccd48a62ea21506d69aacf8e97ff644a5c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975998492a4881a733e4beefb71b2022b3eab9bb6e": "0x00301a45ba2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5155adb5c621a2e867a0a62eef3b32f3d027090000": "0xec082e185832750e0fd4ed4c5011b37db13eafbae70ce18f0bb093efe8ca712500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcc934099b134c32666f4cd05609766f1def7e5bbefde6edf66c9aec477e65e1f": "0xe1cab702cdcb0a445bc6b19ced6efe6d911adfac", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700000a9c44f24e314127af63ae55b864a28d7aee": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9051936ee4376c9062485bf5d47e3755d24f3baf00d120b4162abe72296f584a": "0x1c6f3bf84417dd2c0b9c2d148b3cd0639c5b9387", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d52edbffac1aea8f0bdcd78ca849abfc51a03d28": "0x006c6c3e88a001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f61b2a45875ef1019da9bd2353572f00935d163b": "0x00e6ea478ab597000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c5d33619ffdf46315cd16bd053a03d2873bc37": "0x00bc7c65071400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dbc95b59e3e29bb391db5de0b7de37a31a080000": "0x6c6cae8ad5e77ec2b3c9df3df6c139a3e824193b1c9f0ba69cc6e4c01e867a6100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c5463e2740bf82a52ebc0b310c575854d592940c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890065939d87e6f958a20873ba9ebe06bf120a2d33": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d982aa00fdf3835f109ab98a569a0476af2e87c92bbf3cb6c399254fd9b31c900": "0x6f11a5b9d492c53674ebf1694954f19bab83a7c8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895d4502a61e5f5e02b811cae81ba9768c136fa101": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895a752166d908f57d724163a24c4ca1fa4ad17d7e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890041a3cf4d4230d2ac84ad786f5675c9c06779a6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b5eba1c7420ab3513ca76e1358b1a7c9038d1fe1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771fd1c6b80977e2763c24ce6b4dc6b863b2a5c97": "0x00008d49fd1a07000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928988884e35d7006ae84efef09ee6bc6a43dd8e2bb8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dc86f44b16c4ecce7679486cf4006ae586bca879": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898c94b11f460481f86363563e7eeb447225fdb61e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d6ca1b1688484531b74a6b61ed3f1c7b57060000": "0x1a8ff8f05a8d95a40db07204752c60359d031ad01e2618e2a5a33b63823d2b1f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515fa337157cc1302d53ba2b5cfe1ed41d79060000": "0xac1cb3bb7dbca1415903b9e193880f791cfedd7cba5a2318ea00e2ce946c605f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e7b9a7b203678bd95a2c7c44630e7d56efa2d4": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928973648bc5effaacbb36d73486e7a3cf424fe0d928": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975e0e7a5ca7fd2b638cb8e544d9188dfc38385db3": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fc9f2eeac9e40c581c898481ba696b0e6300bd": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d36a5433f5116598c58ce3400f6a2a23f6104fc92b5c30e4610d86110a1ded039": "0x3a9b0cdab618a437cfbb3aff8fc8b22ea5188d70", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897ec93f2b709623605acf6120849e088dbe0fc37a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ae070273b639a73c42e1878849ed52f6d9e0cc6d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd657f17319e754644e239fae0cdf743468637219cfd0e3847bb0ab9679805234": "0x43bf5419c4eb65b6f8cd55489338ded388c71b62", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cd52a72f9655ced5ed66134b11deefa841a28d": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397017a5d5fcc1bf0ff50080df6b62f484e96c5831d": "0x00540ec8632600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d89f1ee9d2235ca7a55e837d340d083ee2020000": "0x22ace5447bc2071e2b0712f2a8dd927634840fff178eec30ef93bf15055a462c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51553e73323f6d3baf32973ed04017931c08060000": "0x8ea9b58a1411d609b8768bb31439964f8493cee32508c9a4b07088dadc43b32200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700368e2ec353e7dc90153075954cd3dca551f35f": "0x009c7912141900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c61840fbe306c4e984a41128a5a5a492f5491ddc": "0x00cee28ed4df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c963b8f2ca98eab214ba907e8b1fefc8f291fb09": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e787eb81b0267dafdb6083fc33f318ad0bc945a4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bec2507ef7762118315313ca50bc41b3ef070000": "0x5efbdf49bf5a39cd986dc91cc98bf5639e55c2031c9e00229d366e5b7efadd0600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f52eea67eac5e43ae5562e4daaedc440d51378": "0x001428b7820700000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d04901365ee56151d864164012b6e08c412f3bff9ba22fcef3dada1e49efc2a0c": "0xa145addb0a24f0c4697189a02eadb006be244d49", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51edac9a28c16dbd052b4bd8e241171eabe2080000": "0x90015ffd36994c8dbf954609926bbf6fa9833924e190acd6a4b248e5aed1cd4600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f1a0adc19a2cb4f04bef8a27e35039d0d90746": "0x00c040b571e803000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ca260bfbe4c116f9f13d007d83c27f8e7bbc675": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005dd929c6d703a12daee88fc368b849b0505c27": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900edf9881b2295cd5f87e43d57ac2707bef7f2c0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f569ab0d06bd42de35282c5cbd70552bdd080000": "0x7073fdfd03fb9aa8f6153812c21f0a9eb2a14862c76bc8f17fe026c64e3f736900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005ea4d2572a2015e589d4412f4894da6fb4bea3": "0x00769f7b7f5300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ceecb4499df8705ddda042379018d63e70060000": "0xd6c29a7c39cee45b0e045a94081bc188ef73be2be086d66aefd850fc7eeacc4500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243058457cb480231445486c786db63ead914b9e1d3": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970087e6f26b4df85ddd9b9b60910c593fe401025e": "0x00ca80c3ea9200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5129401d703252a0ce211448cc7a391f51fe080000": "0x7e88787d9eb21f9643369b4357b4a5e61865cc7caa976ae37b2192fc6721863400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cd67b58f233cbc39fbb07ba036e219512c070000": "0x46a4232f9aa69c5313bb2909632365ffef0d59eaa0031dbeb68f903b164b071400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002475878828a236151128f5af451fc3c1ad194c": "0x00aa5106df0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a91beae0866ae95a1e006e7d6d2366a0a839f4": "0x008ae174b20300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dea07a98574e30bd9c10dcef40d228a0526d6e": "0x0098e2471c0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773213bdb86a2636440bba625ce5b570461ea79b2": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243fa5b8e7942818890da1ab0b8ea9f79c6e912a758": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977abd31d835a1a6ae9d8912936e8b68f7fc89ee0a": "0x00e415ad7e2500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c301610a4ec130d407fdf49bc4cc94f89b316d17": "0x00a0a4c029bf02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900600ea2eca09b387d5be17a4a7df47d956e1ec4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003087fb385b37b81d76ace33b535fbe1568d19a": "0x00ccf483926900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a7eac235c1800f3301e452f50a8df7a6f82f6192": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700606ba24a1649ee35a5c37671941444ab6d2b8a": "0x006cfecffd2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f4639a86127f62435576d4ea0665cc07584551dc": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fdab58a430124be19791e0daa62257ae33060000": "0xdc233e94075cb10f5f5e60e39cf7379b2fc23ee8c1b64ac7918dbd3660a1f64e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f20bd8e796b2f22770413390eb1a845ccd060000": "0xba1fc21a2eeccf7b3437dcb9d4333c6da2283d46d5d76766e1b232a77023056600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003e07c10cd803f10f33b0a1c470a8e3f7e326f4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2459105748cd16d4f93c3166c7e4118d762ebccd0cb41c924236a94a3bfbf042": "0x0138bd5b9fe5ee16cc0e0b0d63adc94a6ad7b21a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e04a97005acf858ce1f991e18fd742c98422d5b1": "0x00a2ed9f605600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928950633256a5f5a0a59ebb7c37a29efb44f0c21e8c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f0549f359ac15f6afa11cf6b0d78c22242802a2": "0x00f022a88c2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e59d5f000bd5e17b3d5f9a87bcf85d1940f2aa8e": "0x0050bd21761103000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ec4678578f549f7cd3091645877cce5f52070000": "0xea4ca720a5284bec0611c7d63e78cf1d5fa8a64d0c3bfa17354fb2a4cfe4514400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979505ea825ca9bc29d21446a6584c6771b21f193c": "0x00b0631b220301000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e34157f21cad220e1816172cae97c65b9c060000": "0xe467841a086f53e1b6dd67a93cc116d062ba000f884f2e49546a7e8f5552412e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003040fdf21fcd3084fd4076962bc4c7e66395d9": "0x005c3f8afc1e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dc9de83f11941407e4c81debc7a2023a27e118bc": "0x00223675df1600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d041fc41dbb6b131df000bac16c94ee5601d9620957db7c59068dba04e3ac0625": "0xa9807e6a10518c24038521c00541af1e0e32a052", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d69358163f5146f04918a092ec4f527cf6f252": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dfe344098825e1ac854d356926e44f303b7d08f2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d4b3731451de43ad92166a9866cb90795b6c85be": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007b6e06cb7b7a104d3ea36f466bc14ed99eb513": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd9c6de73ea0b65c5aba8bbd3a3a9a212be3b93c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289456ec4d3265a0e2c8566728f819737a8c4a9872e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339729bff29d8193e551e089b3aad1e3937882fd9d3d": "0x00ea352f5f1000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fb5fc1c7b6b158856f174b40cbeb2d7844080000": "0x17756d5e1ec2bf3d045828d7dfe00edb4c24acd899a5f1e251a86d39c156a20400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928928020c484d59bc36b2741d5aa1e1d48e6e3ab0e8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b11f86a69ed65e8e2266d936c55dc66f43da055": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000fa37652ab02d5da570506aa4f0625102f91e8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d29fb1d3724764405fdea290aaba4637eb2a6d72": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eeba76f589cb390ceaee0f15302f5cd567a05b44": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7a56dc6e96af40fefe5799aed949f2c53c7fe497f8d830320656dd6709fbde5b": "0x39634580a5670327b6f4f925dd85f2bcc2c44c6d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c08a9da0ab9bb63faca19694e66c95fce5dfcabc": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac3947b090a8daa38eec83cd7bbc5dd49c0e5071": "0x002e01f9b32d00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ae87a7e9532cc4d0a680c86a5fe43fd815040000": "0x9c14dbe4982ae73a084bafe1f7eea2d51f3819088f08a10eb2fd7a1343c5140b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51281ace2045d9969075a57078fd8a72f55d080000": "0xe8af9d2a328449e3a5ca67a98189d488ad8311b2bbd0fc2b9d02d2ca9dbffd4100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007e1b953932516a6560c9161409b4fa15595bd3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397855f896fe935353955324fb1609165ec9372d473": "0x009e095b9d6400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9ee9f66b501f25d1a28c7de9aa2e2717dfdddd281cb0971f5e42a8657c05aa53": "0x94b05d7a1cfc33b148caedb2b979d603a6532bcd", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b9d07a44db8209b9a6988a41ef4b352d5f010000": "0x0c5ca519856ed9f4245a8613db481fab23c68914960802465e2f2c6f67f40f7900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b65e84c0f199c20f12318567a72d255148080000": "0xbac8d55b78ea5cf2f5a7e57a51eee3f0074cb71c80bc23dcd2d0bd16620a6f0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e7551eed3542006fb6ce1487e3330f44f6db0f": "0x0002aef52d0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d09cdcfe42bb7443b5f0d32c6e770f32b18b7ff9838f7015eb6083b5fdeb5cfdb": "0xdaefe0f07df89bd8236d1007e80f1914e2b85853", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707b10fb900a97ec4a265c6ef64d47db52b9702d0": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d80d8a3f4317249a895e4b49badcfa7293cfbd215d6e552d1c07024d36acfbd5d": "0x6f5133638ea25da451abbc648fb87b28d0318aef", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928913d8779df2c88e622175dc24f8bd2b53c562e631": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928960984850ffe55a4c330723b7b439f70e6184bcc3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f4cb2595186d9876177cfd60bfddb0dbf4dc11bd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973bcae7a7bee3a07c59a217cddc891d947965ec00": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4a46f196fd6ae9d508b04218c4210a55b6ddce13348b82a5c5f2e8960601aa74": "0xe7848bedb58a722316a55a845fea16b34cea5e5b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339712d86da4cf1d9846b7118006e6948b51c75c6cb3": "0x0090c5a0b46715000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c68bb853570f4d75a02e7f7c1a7bc179e62e830d": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d957478b19d8fffb6c622003e411a99f96c42301": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511b5f9fcb87be67582f5f7a24b96b74a411080000": "0xae3fa55a10ce27c1f669636f4c9c9a6e3e665806743ae2ea04129f24e6f7a85000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516640badb32e582b2257ef8a033974065e0010000": "0x46ae3dd83d4737906858d8cdaebea882b9bc8581f6716140e1e9cc1516ea016100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d20b9c82a5cc380317eca92f17436eecbc8fe948913a035db183c30dff468798d": "0x40f8fc59e380b53808df1bd1c4e0e2674186dfab", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d46b90d1f06bebf05dd594186ed002b546f85a4e612d060ce43fd0581197fa143": "0x8bf3edf0ef51f211bc580ad6068b21f83d163ab1", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4e8b242422577c9f7a6ed78ebb9408e38e03d7c9096a338ef4081241c29d8907": "0xc301610a4ec130d407fdf49bc4cc94f89b316d17", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339784256d81c1a191e6952c781f6a204626c6912b83": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007050147f1b0875723fcb4ffce39451ed3fbb4d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928931b68bed40ea6d8608779acf8c61a453e264e253": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289693e1450bee60182d0f34256ac03c94de1cf781b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397390bd123181387d8427df74476627411146a0862": "0x00b28ec5f5a701000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515df0e9ef7242e4a438571887649293eeb2050000": "0x90bb7e90c2ad7c2a11f03c5237c6bdc77720cd5ebc3257f138e94b004fcd1d4700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751a8e0efe83ffa0ecb7f175fc41e38563886939e": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006e724fce558be730b5ebf7f1d4da69b8d72daf": "0x0002aef52d0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a2096e3dc4c8173bb1064f33b005844a22513d03": "0x009cdcc16b3b00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5103fd91a59acd909636547dabc976284136090000": "0xd68b9347a3c6c5a16919f86d7d7e822f0b7d797361fcfc03338f5c18b6c7cf2300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51776a46c6dee791b1bc9f7539733ff667b3010000": "0xd8ee28573fc3a94c320b07a44cb8360d2f3497a82df0904fbe8209abe49a780900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a4390841918eb8b1ca88e377ada4da46f8f83e8": "0x000014bbf08ac6020000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243b3aeabe65664ab160d8ddef2d0a74f24faf321c7": "0x0080dd62b221020000000000000000002208730300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972969dcc4bbf824145328bca8860135f4cd9ce9a9": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7687a5a3e7b49522705833bf7d5baf18aabdd2d": "0x00b05b4c364400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c7e8ac122deb2f7dac7456f73cb4aadd9d479862": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d48d307a492109a221d7237b1b3ab2026ab23810b16f8cab2c750aa9181984a78": "0x731396ed98bbc215c9078bbc583034ac85a4995d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d067ee646a21d8904fe24a5d1047cce91b34bdc9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890065ecf82bd0cf4b0645fbdd271c790298a364ee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bd5f99e04c74736c9af2996d0b15c3f8165207": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799dfbf9a028384c05ea011e6279a4c1d18c782be": "0x00a031a95fe300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd47637eb6578f4f2017e7dafba599a2829b73980e13e3e5f17b3a2081b9abf07": "0x35c9070e864636da7462d5a6a59f81f7645e72e2", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5195ed745dbbf834d4f5a74930d543dcefb7080000": "0x84f70fa89ae1707982e11b6ea49d1ea0f4242f82b963281c7292683d780ad50d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fecd5df71e03db79046adc4e474d3d0e4871e2f3": "0x0072e25c62af00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a32ad2c6d4d5ce0b978e4e0e955e02abbb70ca": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fc1d8a37770d2a67c13255e89b3a235a57a3d1aa": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002dbe8e8627105c4255ccf96f8e81ed4915f277": "0x00c684979f0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008481aa634a6d406c0ab9ba67ab019f68ec7d45": "0x0010ea0504bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896e565ecb628a3fe2b055f178840bdd340ba5d7e3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee213d531429838906fcd09e48b7a488bcc501f4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928990a990f3e8856f6264326b2053a0ecadbfa34720": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c69f44ccd469078bb71e7a704c162029e45c0c9d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f2675d66af40e1475921afe999fbfd0dbe000000": "0xd439e90cb7b87858601acec7aaf207b47e406c9779b3cf0d4dc03466870d7c0800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1a4c0dbeb509712262d38d375d758f5709932676b5eacee8a63df2f47bd2f42a": "0xdcf5ac110bfb16933b6f50b5e5f8e38c98d39481", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008dd1b21dad14a42715a406f36abc940ebf0287": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900850453ab4667fbce4688912e43f1ded185f847": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51071cfb79ca83b8b4a07d2ead3ba71079be050000": "0xe04ccd02a8675ac3bd0af1ed88f893c33cdd541cf71562b00a8bec1db6d17d4400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720a77f06ce8ad15268b50577aec5dd0af28c5c84": "0x007649524d2300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d98a1d22e4fb59772d3e41ca11f72f00f4fd330c2d9c6c37c05e8404fe10cf725": "0x2a61258bf9cb93b77da65701e212c4f1653abf9c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890052a07979799d203c54b44b3544a2e1bd30cc9a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51689e5bf77dbf3598eced4d4e33f3e8dc40080000": "0x5fd1573c5cc41093c6d0944a40325e971771b9132ef47655b4c23bcf988cce0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d18bf39c2dac34143e07106240352c660e6cf571c4629a77a7751cdc20371e161": "0xc65b45c6c2b417a7bfe7a1f164ef12b53749fb5b", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4a009890abc59e1a2fe19b17d72028fc7049052704ad807f463ad1a7a95cba0b": "0xb6f20d6fa4c28a6ae5a4372d4798f2f759c25ba7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899edc6ba142d75e9662cdbdd2224773be20db4260": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972cb9aa7eb7da683a1feb615e780bfd52306aabe5": "0x00e87648170000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d52559f2c7324385aade778eca4d7837c7492d92ee79b66d6b416373066869d2e": "0x0077f609a73630a90fdd05e6edb7ab0c99bf71f8", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d96eae07e988c50ffc04e445a287e64b4c0ecd35859d8255ac438438f7af68021": "0x819669704eab9a1a1086840eab684846647b969b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f4f934bf2530bc28447f594ff4f05818afec1e8d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f64f98b115b42ccd8f6dcbace3c5d6bcf8030000": "0x566e7d7d28c4566bf9c64bfc61e0bd122dcea4315c30a4db862e96634092446d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979fc6a2b131fb10fd547d90100629791d67619156": "0x0080c6a47e8d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ab791e5fc047dbb25dac95d3a01f162738ffdd2": "0x00a61c778e0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1803002442406c0d57f20520b633b631ad3193b654564ef92577569747f9f109": "0xd98fa099942b9179688793b146505935d64def65", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005032c359b798eb433f50af95dcd79ab333dc2a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289824432f160f254ca59fafad843a74ecb32d3a4fd": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d823ab8fb16d1f8dee7f90459777ec16efa1a35a6626e965a80f4135c4a6ef335": "0x442bb3cc2095dfa3447c774c3ecaa91805c4a94f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746e4cf75e7a515935482c3f1b557efe92893d483": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972702f707de88382ba6cf64a6341d089514341a5b": "0x00b65f759d1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a752faa9889de57975049d585fa87377c7bf0894": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a440bdbe81c1cb6e7ee0432788c3bbd5a769542": "0x00e099efba0c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002611243b23dc29e9ed64f28df2c344055cf3dd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339729feaa65869e737ad53bfc2325bd8ffed8d27a07": "0x005a9010a19f05000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289701ce59b203d5368c7ac68f6f57a5f23552d6458": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b943e534ccb68a976bfa9007ad6705c76da81ec6": "0x002acfc5745300000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da97220630bb99fbae69a2ff81890fe2b4382104c22c383925323bf209d771dec6e1388285abe22c22d50de968467e0bb6c": "0x000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339784668bac6daf894a1e4203bd93863a7c7dbf87e0": "0x00f2dbcfb47a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de073fab94e8c03caeb0da108520998cfe419f269d4b7ae006faf2a55991dd818": "0x00ab6a08ca44645fca5b8a50ddfb04a8f9477923", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ea153d7dcbb78aa15a80f015aa4b433228836d77": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893fe5d6a2d1caba760006007687adca8661a252f4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d04bbc70b5c1467975bc6ab17d413ed85adc3ad473e3ea52b0f87abc2eab05571": "0x007fd348bf472eaaf68e58f652c082b86813bdca", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d2c6e327a6f3088c31e64ee915f6821f7d080000": "0xa0dbf685db6681f3d704f4a2c6890f965d5cf1f2d7fa169a6fb5c25f8a4265bf00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a34456aec68d1fc7036ef0616ffcd7514d63cd1d9433c0f55b372dd469c8811": "0x70c853a88dcfdf9996e60d3d33f3002ceddf46ca", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001971fb3e5be59084ff323d05976eadde3a8852": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a4c2cb3ef01a02eeb516c1adb1325e3bfde619": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d52b0605b1fe9bf82a21c3231b611f23945734683851d49e29cbb51f4acdf041e": "0x009181f75cd5f86b015f28e0b1919f5fbb3a3eb6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339780a8bca8a6bfe60479f523c10c459ff6384760c2": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978610e7e131ecc29b1edc1eef2f7fd6df2b6400f9": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b61eb7bad145d2c220180375b327c7cbe0ae9a21": "0x007cfd09a50e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976bd16c10081589deaeb5cdce5963fabbbd350616": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289341e46b97431121edb45c7397534704946e1090f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397465fcb930bde0872602382aef73fc393a31d8122": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720a372f22493279f89526a1f5d525d6c6b4abeea": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894a08ec412ead6bbc45a465aff936e772ad133569": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8405d696b6b0800c3732f87b3e817969896dcaeaeb0af813c27dc797501c245a": "0x8ee43bc46973fb91459bbeea3c7f637c6efef128", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f2c671d4cbb4fc23efccecf72c6b995a67fac341": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fb5f94631aa89da40556a8d8d7308c7a74030000": "0x24b52b51914d952bf86bdfa37e11c66a382cf39cd0380901deb6b445b957cd7d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003813a962efb1a03191600aa682d38b08d953cf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970011e93c401330194e47c9ba85368c0205eee60c": "0x00da25696b3a00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514dac39a2ccc1be3055071718779819d48c040000": "0xb2751ab0acae482c9785925ea091b999ecb9cf62c8cd2b1a8ad582a90a52b31700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513f99801215cd0fefec3a861574c8a8f3b1080000": "0x48610dd34137fc88e4826aa1a964b4a8f532453005ecfd4ec2fe9fa14e88211700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5174977e570b357efab244d89e62bcf63906040000": "0x7a4cd6e585400fb82dcf09388a3b6eeb62d4803f027e7fff775038ec0898795300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0605f038b446e037786a3bbbbb0e1c78c2472c4910ae6f97902985f3b72e114f": "0x8e6d7485cbe990acc1ad0ee9e8ccf39c0c93440e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900541ab0a813fda7012babe7b3378441432f48e1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900638fb5bd1fa89cd2c29c98e6196620d749810c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890ae46dc2234842d01e72c6d688bc2e1c4b18a004": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892489c8d02c79287a37e21809eb3f5eb4cd25d347": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928949a1c510c50555b7be6e68e064067038e5499748": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899edf2a093bd2c6d0a7d44368480ce8fc34bcdd80": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c019777dfda36dd460e7322fe6e1f5c94972517": "0x00e69d55840b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824348e17a5cea6d3fb095b75fd94f36f6a902dd6702": "0x00406352bfc6010000000000000000001ddcdf0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d24b52b51914d952bf86bdfa37e11c66a382cf39cd0380901deb6b445b957cd7d": "0x00a4c2cb3ef01a02eeb516c1adb1325e3bfde619", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5e007cb54f4faae216bee9bbe78fc93ebc83017932c2fbfa14e73de785d9ae7e": "0x2ecb3d65993040d26944b347119eefa31f7bf3b4", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ec88e08447dcecc239ceda23bd35e22f6b070000": "0x941030b8cae55fe5459f75470417cce9030d285e1683f98324a7dd81ae1b6c0700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ac15089b8aec4ee664da691ca3e7e29bbdf1b7": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ba2b48d35573cd15a89057fc6aa79f58945c36": "0x00b428577eaf07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976556deebc10e49b32cad8ed7f3604827f9672e0d": "0x00e4d5530b1e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c4468c8fd916e17f85b6e76e320e631712eb8312": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970019eb2b083a143b40e6bcd7a0d4508467100f22": "0x00786de3c11c03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b999004b49c6b907d4278067da5c85195dcd7fc7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e064b904dfb30bdd37886efb20bb328a6b5b4a6c": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773361bd483cc76d6d0681065e6ddb25e84ca96df": "0x009017ab5d6b02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eec5230343cb5336cd6e3a8cb29e5e267d6d5b21": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae449c74fbd4b173c01dcf0de0add765a844dc463ae5f0d2b03b2762a3ed2165": "0x945df54583eb102061f57d3b4f3e499d7acc49b7", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d28996c52694155d7ec9082650fbf108f69da60c44a4b2565fce4e03f9bbb0178": "0xfcd52c547ebcb0b817752c5b62d132b96b797250", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c4bf46544793204b9ab9b0d276c7416b86378115": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b0e85ebdb55e25262849ba46b0a3e31c928944d": "0x00dee251231a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fa6ab66fa1e479c1873ce0c8ea5c1261d778e6": "0x00", + "0x3fba98689ebed1138735e0e7a5a790ab0b76934f4cc08dee01012d059e1b83ee": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc73c898b502cfba8144fd3a1a33757ab84440ac": "0x00742024100f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008d4e47715eb112c1ffba14275bfad41150a735": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f149bc61ff4343e1c1c87f8d4d00b46725080000": "0x041fc41dbb6b131df000bac16c94ee5601d9620957db7c59068dba04e3ac062500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a9f94b0f5bed56d03c2a3741eef545edb7c27ddc": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893ce8a5f25554d7c733169f3b682eb3458b67472f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8e8b7a80b5e743654945bd74ad666fbb76f5bd7e468643470bf889ee9de3a326": "0xf8f3088978f60f5a6c1992b1b3ada0f228cf47ac", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895ffcf1f0f84cfc6fd881348ac8e74ec5856beefe": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397efddc6a78911e0d1964ed041a8d81de69cdc8ca4": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dca51a1ec0e15c10c0bf0e44a957964485d66ddb7009419186136d1cdd60f9a33": "0x0569baf12b57be4808c0539b9eb6b34b0fca7466", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fbcd1a1318617d6df1d267e92dc329c6dda05d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b4c4dc1fb222bae0e04fd8cd23f78b37bb39c17d": "0x00008d49fd1a07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a9924ef83a357ec4c978a66ddddfe9cd325b0bd": "0x005880abe94f01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514f6e25f08171ae8269a0e4f1e46c767950040000": "0x76729e17ad31469debcb60f3ce3622f79143e442e77b58d6e2195d9ea998680d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009dbf13548b5351c0646b52b1f81d913d0fd4ae": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a53e3fea0109124613c5ba34c1bb2a9dbec3d7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c794e65e0fc0135082244e2105900e3177cfc5": "0x00fa5354f60200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d48454b0387f763dcf46291236ddfe846ef6466aba368f75aec3bb84b65b39f66": "0xb8630c7dbf3b9ec8021876f9f1fab265df12368e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397415ad707749eec89443896f6e55843a208e671e9": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978963d38fea40b7cb37c9bb2c4d3252415f0b6d65": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289557e9b0f30b4e4d1738c4288d7a69ed8e79a7036": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899bbb49b1ffed08d3f79a352f1a0f149d88722fd2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd26931ae163fd44192217c67bbf944eccf68df012a0e6b24b042d9604c70956c": "0x6fbb52a0c06818f7022fcabb7b815f86cfc1eeda", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700735384d4b8bc62916ff05a16679d41c9850fb1": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b2c52e1aeb3340a166c483297a70f1ec3d0cd160": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e95141639b4ac81e74704c7fb969ed396d50f67d": "0x00900126fb4700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516ce22064540cd8398db142e2e734880707080000": "0xb854d52707f6ed71c182597e415b55532a3a49bc0a20075f1a8f693b25e6976100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928950dbae8912187371548f53f74fbd269f86fa44ec": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700171d810de904efc8b649c8224652ef9b75e53c": "0x008e46e00c1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e187973a417e345f5c4f5dfb690b3d01001e43": "0x0078ca2c506300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289abf9eedde255d9fb1047d2f63970faf7637ce68d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b41a84ae7ae518633f1eea1d4f4d13c4cf8dd6a7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d908f80aba091f8eb3135e7876d51b5b1a7bb188": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e902b00370977bf81f4f2eef795133a1711ce38c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b74cdac11f1d6845bf60e28d787eb4413f804f31": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cfe809074cb2f767285e8f0bc8e2604116c7bdc9": "0x000c439bb19703000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928989379ecb3d84d69e1b18075d89e864bea36c9b10": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516ba58d3c6a91fd481b9416ee20f46e44f0070000": "0xde91f855c77aeb4b742c66cbf0f4f852809d98804518f4b3e00ed60437f0f61800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d396f87af37acca0980aeb814375eb46880d37bc": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51866c528ba8d7392188fe37866e3b24bba8080000": "0x4479a684448e202bae5f8fcc4f2a898757ab8ea3b891baa6132b37ca3cfee13900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339758245d4b05fab653dbe189c35a98c9e4d84d67b1": "0x009e0aa0e51700000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d480e00bf0602f92b26802a794b8d837677d77a4abcfeacd6d5b9f97c4f26df5e": "0x006704be2884970368def1738cc901f92025c04a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dfcf0b6ccf1cfb1e77c2b259c08b1510dd978fea": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5180f379430e270e60f4842296bf5d78343a080000": "0x24cb880e0d4f3181a2f4faf3df0dae7e138c3f2ef4a4d2c65e5030b41410733c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979661231272cfd204a6bc7aca349e597d0c034701": "0x00e849c81e1900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ecdfb30ff7141766182ca031e20777c0bca09306": "0x005847f80d0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0dc528b979898218393f18a4568c69476640918": "0x00da79080d0401000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890096746df961fdae3247ffa893802d1cdbe60e86": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898961f4e5650444509af31c4a7cf2a0924f224b04": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a951a1bcbbd1bee2cc35cfd96dcf9d101e630c40": "0x00cc7a7a8f884e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824393011e03417d775496e3e81c5ba87cd973538dab": "0x00901ec4bc160000000000000000000001cb240000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339758ccfa1c26b8a49b83ffc4bd2804fdc5191bc28a": "0x009859449f5200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc674a3c614e1c49a0389b3797ca27f30a5dc78d": "0x004ef86f970700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d4f741b495b845b4e4ec9bb7851f71c854d4a9": "0x00461784db1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928924dc293f38625991044c976a3c99c358563f82d1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899028b660bd9fb93c44efafa5472407f82108e5bd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bccda47579963d17ba3becdad1512e02aa9fb80d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970063a1ad9b3ad315d4a0bb590435d34d4593845e": "0x009294f9fd1201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708c204dc28bcd0c991b903bfed4eb5309d1053ee": "0x00205a4ea6ea00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243537b2feb029a7073da038c2b9bd34c1c6109a0a0": "0x00c03c208f510700000000000000000010bed70b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d028942b7e78c61e78086e9076430bd3c69cf08736f3e463d0419f0f12751f635": "0xfea35be9327aca7beffc93d2b0cfea5d291f7d13", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ac8938e1faed5af69a6516f48b450c82dafa61": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894c638efea44e5b7898f33a7ac1773f4b7deb3631": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898a8043a578111b05d48162eab62fcdd9adce5185": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c89b9819ae522824ade6efe464d30f8e431cf904": "0x0080e03779c311000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6a36947e2a739ac119a83602d101a0ea24df365aacfd1a91c166d8734f96491e": "0x9b8a4884a5afc6cbf0dacd720fd6468b41b6d437", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970028a86e047f2fe0834d472d87728dfb50774251": "0x005880abe94f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339731b81404b826658f107997f2a9cf96e6fae6915d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a6f5ad410b4659a89bb23a5bdc841fc55f56567": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5bd25b8ca7659835bc91ed7562812eff9352dcc": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfe9618d4aa657facfcb1c1cc989bd42afb1b4cee7733e308bfb340b78cb1c144": "0x00b67b5d99f7bd244fae58ebf86d35e38f72cc7d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007edbaf17817a91eb48f6166a592d16cc47846e": "0x0044135e7e6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970054fb3c10d0b0228569744734c66321e14c01a1": "0x00301a45ba2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d6f4309ebadb22fa01cb9d47614d74d100040000": "0x6aaac987bd9fce6505fb58c50175ec3577e4b1cfe4b8632ff68ff66000a7584700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8ff6762eda9af66117a353dbce0cf9098d8c1d9": "0x000484564a1300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5144c050502cf882bd3216d7cc640d543c20050000": "0xd8ba33ba9e1d1c1250cea9a8aa6aeb93df2df2bab98d7c330a2834cbf707ac7e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512599d11a48e716f0c7be33b69a4423d663020000": "0xf4e80b965077bdd3110511713a4d625df31159877337d894999d66713cd5535500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d38f3bcebf40af031ddc003ef309221ec57a19da01d1c3a2771478af5a2607960": "0x009789e46d6734cab174c01e5811d744f664504f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c5d2111b3445cbf18bfa5709ddca8d4757c8155": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928951e6d5501ea26f012b2d37fbc4933bcebcc28244": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397126e1dd8189d7a9d7d1b3e927339fc58526dae45": "0x008c8b2757e600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea35e7ea94ba3312211f2313f6ae0f7120ff84e77a7595b49f5243a921bfdc32": "0x19d1e23c329025f05bc9249d021fc59abb483254", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6258a2d221b191f83061b09c4f6f778d9097362192cd35231c149e46ad369835": "0x5dfa9a92eb14a3455b46eed5f6e17253f304abce", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897a377641a0f741ba35458b3fb478f0a6d013dbea": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339790a990f3e8856f6264326b2053a0ecadbfa34720": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ba4795e1db269aa9156234e30888d75ff3aaddfd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd41dde058e870f4274deb8cb2417eef04940f61": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289048109448c4730ac047abe0097034754cc9f0dc8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890d2eb8b578ae98447fcb32a4f6b68c45058635ab": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339789af1ab14542363a2c631dac9d2eaafd0bfaf008": "0x0052e1f8cc3800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397114ee4ee7e6c4bf88c112a1cd1590c82e71ab298": "0x00226399efab18000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cc8681b437b11ec69945cb7b60c4ba242e040000": "0xded7e8da518feec2fcfa346bc021ea2d31a042cbb4e69838cd6edd865108325200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002d27082129124544148246a221366cd71844f2": "0x0026da6a887d25000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700eb0d1842deec54de9fee30c06369c21e33b99a": "0x00fed5f1475600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928942d0a88bd5baa87a3cf4b6e32c7b6cb3850a3aac": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df02898c0c4db9a86d5b6c4192c26147cc0d4845d3c93f723a4082701a68c116b": "0xd6c4d3830cec539bb01d5209b79ae4fcc5053bc2", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51862210bc2e1035c82fcb1a1e5de668fb1a070000": "0xa05acd278b0b5c1c6ee96916b67d5e4468799fd875829dc626140f5aab5d300d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970065ecf82bd0cf4b0645fbdd271c790298a364ee": "0x00f8199a6c0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928926c96b604abf5871c32e63ae7be295008967a47f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289390bd123181387d8427df74476627411146a0862": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d0ee80934b74c7f0f25c7a137a8a16e58e713283": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b0966d51374a7fea1bed099f4d92c3fbf0192321": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900508808bce4e1d3d170cc4cedf616e759522144": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928990a66cd2def2d13f4c8d09222a11cc2bd508153e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c47108828a0c47dabe79cb9fc8f87fa9b4dd3447": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc49098d1f282e8d10fc8ec1f27e119fa45f8498": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397efcaae9ff64d2cd95b5249dcffe7faa0a0c0e44d": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009d470cc85e114eb2b35c64b39f8a0e3dfd6759": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f67b3776ac1df6d0562b404d4ec62deb0cbe930c": "0x00ca91bb010500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890037428972d6c3f5f40200902235c03843a3ed94": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe2ebe8b791bff2fe45927e9fcde8a5f9760e249": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894118b3011a348538694a2655100db72e5010a0c4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ca1cee8b12e77cf34758c36773e9f1fcc3070000": "0xc8229bde539592a0e953424f61f362d2e275eec51c6f88facd1b8cbc925f045a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c154d6a5f53e66085ce1d7c26f23aeb6d6b18ac": "0x006c564955cd08000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900360b1b494ea0f8e156f9f003732727e94e6986": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289600011fee56096e5858518ba9d12c43474866e37": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005a9309489cc3231adee672e986e79d7dd1acd9": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e51a3b279fd48464ef2b37e25fe2ef7dff030000": "0x68f6553582e121f75aeef7e61d4c694cb787ebc016d8a53ca89dee0c3704f45c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bb2e14a1805cee42c55d5ffe6bb07a2a8d09ea19": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339777dd7978b817865a780464f0d3628e800a47fe9a": "0x00941032be6000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008a15ba6eb9104f34001a142a0b57e0008d8e07": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a4bab3ab426b32a90c353ae450a1d9712d67d64": "0x004e246ee50b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d5ce50ecdb86b2e04589daed8e6cfcfc238d3d7": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289202a7913fc42692223e0f04d3be7a8c11c76dc5c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b2ad5daf9b7852104cadd134f786faa798f0387f": "0x0042224efe1700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51459b5997b354318e3894297cc13f6b85f7050000": "0xfe9618d4aa657facfcb1c1cc989bd42afb1b4cee7733e308bfb340b78cb1c14400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ea53530092af66d4706fb53e7891d2b1ef730b31": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa16ea96e59d8fc82b496362eb68947ccace82da2f1f3357142c072725de6a45": "0xf548b1c7499a85e9574fa5845d0308efc39d19bd", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289abd9a0c14b25a69a5bd2f2c67e7192d88e64d152": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a6c0c85366f11498dd656da6e5b05bb8eabf1c82": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f385662f28eb02ccd3da6d3a370777cf73e68306": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c6ea84064e0db68bf36b61506bcd3f4a48de7b": "0x00c0e1d0612100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bef0fd94c275016b202a44338b91cf9d07090000": "0x14468f3eec001c098b4584022004007011be560c11664b6025cb7c4aa39e640a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970083c66b575c021b8ab547e522a4354b78032602": "0x000620e7ad0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009655d2ce1236c20262b402d2fc89892962d45b": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928931d6b3576ab86a04f10bf8e000161a3defb38ab8": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ed47a3c5d9fc5612ae7b8f02585298aef42161140370c1c6169061963792f0c": "0x31a7a3da4c0952b89144a7f47e04c47dabe9d914", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511498c11588d5418e02a4a54c5441d3ab8b060000": "0x3edd53fe4fbdb56bb537f274e8c902fc65832f4e053d0920659caa7459f9b95c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f225892b73821e043e121121f994e274ad040000": "0xd0edd5db182fdc10042073db3a03c757819bcfaf39613e34bcec04b971e9140800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928993677d3d013f091f772e54e6e50f26204de7db79": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397143365830ba0c2a2aeb0549cce5107d484143877": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b7687a5a3e7b49522705833bf7d5baf18aabdd2d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928968307d03aad558716061762b9b62f0f5d17c5c4a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519b76b44494802f7c1f94e6df6e3b001b24050000": "0x68db02183e85ea761242a57f6d610fe20c59ea47e97794dcfdc7dea470670a5500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243bf66f78612884363c0f231c11a33ebbd6d26ef82": "0x0080f420e6b5000000000000000000000b58260100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890036725f3317d37d0b948a2593892bd5c186b98e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005848ab7e3f13a54848c46469327bf62fe0e5a3": "0x006a097df4a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6699d3b4f697ad91f6e279bb380d8487560793f0f247ca0634c3d9242476577e": "0x60aebc1d9f35ac28f40444bbc318abd850c9376c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d136726fcaf415dc235995fafe215258aed5c421": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5116260af363e44a8cb904fcaa73511cb29e010000": "0xd0fb8a9ff2c401782c57be9d81d51d4083fb4d77deca12888b29dc737274e83200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890c22a65da50ff23a3b8e236d586fe7e3e01ddba5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514218987fcf5deb81f0f5f58910fcd2a9ee070000": "0xb428e7a5a1127119f7af84d611066db63cc1c4d1e4baf1ed201247629cbd2d7d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519e4637f480e16968ce751eb9b4b85ab4f2030000": "0x48b2cc621a25ed86391676c3686bc2cf76f06edc66a4c3c21e2452618ee1bf4e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971d78010ae098d2ddfc01c7306f16776d1409a576": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977025fe5275828b45b97d3b950d65666dcdb9fc95": "0x004ed2873c0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898ddac589d703e854e22f71b8f2fb6efce134e5c0": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243b043ebcca29d4a6c8ba1dfdb75fedad3dac2a5f6": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d88d74924b788c1f7ec64a54c63eccaddca748f588f67c26e5595870acecd9259": "0x0e8e3a75280f066163eddafe3c5fa91ea6196047", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e7449accdeebc3e4a01c18196406b518503b44397d3a30347d43b5b6dfe857e": "0x81594a7163a447cb1ac16ddb7f831dc1c43f9307", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd9364642d32a48eb2cb1b0b65d18656f4a66180": "0x0008997865f81e000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dc86f44b16c4ecce7679486cf4006ae586bca879": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d9c68f89ba7aa4546ae88f1c90ce2fb2a1070000": "0x1e1fa2e8cd46e066c37ba6ab79822b0217bc35122349367473f7fd0851d3b22400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928931369166ee8d31fce7b69d3231e42245b117c9bd": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519f030b77f9340e522b9c9b63be743bf693080000": "0x245558c69f4ef719bafc87b4f554cb0b73499b32582f54846a05f7effda32c2b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6b2fc358a77318dacd1eabcc8a5b27b7ec14861": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896a305168cbb7ce64213517ce4b9fc6c2d8dd8913": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3476a6305429ae9215028af5afdfa49abd1104cadf55e65e20af5173acb2de60": "0xae070273b639a73c42e1878849ed52f6d9e0cc6d", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512442c57f887927ac1c4912630c3a5bf8d1080000": "0xee00d15dad4842dd984531c1375fe57ccd9e5bc47c10fd505885e1fbe107aa5600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a1d09b38beaef617e933f8c735fee190db1d0263": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000a8a991cb59ddd83b76f334288e57997d25853": "0x005eafa94a1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970082f93778fdd8d0264b2718574c75566651201e": "0x0022217e9e1800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000fb7f3c777a047c7730c8a4d5055d62355ebba": "0x009c3a04d74c10000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976deb669e7db5d02735d5a4f14d622a09f6d27682": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397932b0f9fcf70fbf60f6ac1b4db3f74593d1969be": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928999ddd5e2568b6f88f4ebc3d8025ba4538c8cc8ac": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004f8b0da646a07903c9d2fdbd90579b142fe435": "0x00e0d10d78cc00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ada5f104845314b5a01b3836b9e26daf62050000": "0x560363fbc8b0990637a3014805fade6ead14f20c453cb780eb32e9ebb5839d4400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ba835a2252a188d72be311ab7dcea6a29eba4ad": "0x007270a4519f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970073e43211dcde9c888a7f57d65e3dc23e967896": "0x00be80bacc1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799faf90716291c57b7958f26bc0268b837ef2418": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5105326b69a3fafe5df7d15adfae79e95b5b060000": "0x908aab5055588f2742840a5c03d5df671c1a20427efa284748daa3990e21ab0f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a4146e5d4eb7d13aa83c9a86ddb78f4b68b6a4f4c4410fbbfae65c2ae7f8f76": "0x00ecbd51638c57c1bc38e405ed703d82a977bb76", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8431d50beb39f9d5af9a9047edd2ab987d35877815de7cd2ebc271db1dd9005c": "0x0019eb2b083a143b40e6bcd7a0d4508467100f22", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894bff2ceb822e1217ac9e0b02e78e31a7a8924f5b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51748bc9ed38566e9b2b60940952f52eff04070000": "0xc06510f1df698ee3779298c8999a544fef1c15b5a805068e0ebc056d2496520100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243ee13480f5e260b749022ff1e533a22e14e48c083": "0x004c4cc09aca000000000000000000005ed9470100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518ad9c901ce8b8576ad5060465f7e2a7e7a060000": "0xce629fe0c1c653419be992df3bfa1c6405a65ab8df60bcdeff1ef5341546fb4200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51aae16afa3ad6efa92bf4b20caa745b4f00030000": "0xb2dc42595cd47cf78bd4fa4f99b99cd4f20ec4ea682b0715d906b5694e4dc34500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289269f2df75c2f22db96592cad6ad5ce58bb85472b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b96841cabbc7dbd69ef0cf8f81dff3c8a5e21570": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ef2e01a9f54a4567f054356635348f69bb29e7e70592436f60b3dd4a3bd0b1a": "0xbd9ebcb7c6bcf472a69a1c7a84735942859d3ace", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282430549c3f578615e95f58e521a726269b6c1985dd5": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897d38e956e11e3185142e2b50fcf2f02afe9e12ba": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975dd5aa7a9b90b8ca0e608cfa2022281854490dcb": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bdb3924fc91e02130cde47545865b618eeb5e1d4": "0x0044941f486a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ce53c77f34472605558eff3805538aa77b08f10": "0x00d03bdd7a9b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fd5d715b04e11ef04b8a406c4faefff7eba3fe7f": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339777fa549b3eaa7e18718235b376be4eb130fa54ec": "0x00244691bdf401000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b66e4cd327c761fcbcac782909bde1518bcf55cd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c316f08646011244eb99228d384661e77ca480": "0x00f6e4be872900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3e5f290acd69dfe4ef0ed31024db52c380ea2b18be398c37cd53d1ffe807d777": "0x3ba7149b3bc64c6f805d02017a0d71e89362de64", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bdc59bc934360468b13b8a94bad99871df53ae": "0x00b888d2428100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890062b58537fc07796be0571257f39a591efe3cb1": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243003e922b9535ab92618c64fcb7e08320a8e5c3f0": "0x0028bb1bb14901000000000000000000957f150200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d66ea46144093bd290acc67ed188e375cb13daf3f329ec5898cd6bf22922a3635": "0x81d94d58834fdbb584d72b40429d43cf42f70aef", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5100e8eb3b791df6f84435ab593c4dbe7e49060000": "0x5097017378c065cfad77e7360fba48624873f44c16669a73913e735237a82a2900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b2deac69d3ec9489812479a2994bc068d133706a": "0x0040f09bbce108000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51501292c3eb7ee57add413aebda547b45df040000": "0x09cdd094e9a51d26bbc6cbb71d3f7c5b8edde629402e3e5370e7f6904512fc4a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519f138dce5a45b867d19580d9e807fbd730020000": "0x9c65cc13119222af7653d69ca15a6def918788550819c98d5232841f7ba2db6a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ece6fd032e4d674561246baffa8f92728955b6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289151310c5ed21bc68b85c5c754cfcc5a7b1869cac": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d1456fdda7b8ec7f9e5c794cd83194f0593e4ea": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896174a3a6ae9bafb6aea1b87fcdaba0bcbeda4ecf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977eced1aea8a70ed73f12f0550ff58671ec34953a": "0x00809828176506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300f1a0adc19a2cb4f04bef8a27e35039d0d90746": "0x00c040b571e8030000000000000000003fe4520600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890099d229b3b989f3d7ad9778549a540058160fec": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ea982050e0777f55c745aecaa048b8874ca2a81b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397f43d6436dec51f09c3b71287a8fc9d48": "0x0000e8890423c78a0000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19504bc6fe3aa98fb3e0706172618056f0bb1f6307e043be568014eb4062a9bca4a255f39ed0be9205ee97c93b4b6e": "0x3887050ecff59f58658b3df63a16d03a00f92890f1517f48c2f6ccd215e5450e", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51794e0984810f5885f81d58e5af9b56635e060000": "0x847ccc12910274a556bd06371c25a54bb922c447c8dae6c8818d86579e494a7100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d18403959947079acc738119e8cff8a944ac6e3a4956a1a378f1a268b01baf476": "0x0011e93c401330194e47c9ba85368c0205eee60c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900964d7fd8a498f37164ba1c1b5dbb99a3c90125": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d79cf77ed776c7b4520fc4f95a21cdd75a7b9b07": "0x0066fa41c93400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518ed4f76a3278f04b0dec15d6f088bb774b020000": "0x1e7981c2d131ff111fe1449faef19ae71ab9bffefc3c43f1a1938b287f47b06000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bcef9a935704dabff1755b7673ac29924b050000": "0xba58db6c7bfc75aa2b8ec1c9b2624172c81f6d2391180047091dcd0cea5ec45c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ed99752dabb3138a911c2b71c9a80c7fc917614": "0x00a02488070f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8441ea3b1d64620b1b83a902a7b711c2066447c": "0x00684252765005000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928980fd49b3453f8df565032a0aee096834600235a0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5130cb27c3446d11e330560e8fb48bc2ceaa040000": "0x7c76e3fdfc70d2082cd519b4ce83fe49e545561a5d108d7420af8b15eb118a7d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cf7076697e8531b8140da00df1446677c8070000": "0xea2d46da940941153d236e8693624e1f4c75111f1d0dadf824786425c53cc04500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9c0acef99357fd179a671b7724ce635b53b25611ad3742af3878ccc6a0f0046e": "0x002611243b23dc29e9ed64f28df2c344055cf3dd", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e87f59ab519b9ba01190ef68bd814728ef58fd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976adaf97e46d6d7aaaee6698cd764ed2b960ad5fb": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ec89b84200b69fa6bc48793405af37706e7cb3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727a56b2c1723942b8722a456af024ebdca0580b5": "0x004035d6579e04000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3a2ff980384cc7996c6ae89384ed5f47531ba3ac7f9b2a3f89863a99266a3b10": "0x2fbd318ce7d1b4399d68fdd3561921b1b6fb1d80", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978134fae7112d109c4dd3a1f09aac75f2372cdf0b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970045ebe3bc90887088d9c91446a2973e79b0f78c": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dc7778c338e869497f09f0894618334afc21d266": "0x00f85e3055e100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d97d053f7c5743eb80c78ae4111ea464ba30a2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928906eb856aeb8687f1803c095615b3e7143bf130c5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a97ce748186008e51831f6753e40e6ee9e34acf7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b9c635d29a8bd145547759a0e823aa306c607a4e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700778318977af805d19aecd1aec84802cc0672b2": "0x0008db62010400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b9f5c58ff70657d2c607eda6c44c1b70e69665": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289255de88ca59b050e361ac05df197578bd70a732b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51aa296ff9b6aa0de261e2392c0270a41c60040000": "0xbed497470a04ca4c13caccd69c7827e3ddc64473fd2d7c5d496c71061f452b0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a9b5d50da09d57e940215c15f075139f7788cd38": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51af2ae4227df2d4216647986b9c99530d5f050000": "0xaa72f6b0d74e9843b68cbba5e8d622d055f7a4e6dd196b421a67f23baf05a84100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006e514cf3312db766b10f6ddc624518b8e02618": "0x007870ddfc680b000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfa68c92bfdbd08a08d4cf5995379e28d3ac042b814a7bb2a1e2095d5e27cec7b": "0x5b0f6f73022881bbf0516b30d182761a001b7244", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1ee80fb1539fcc03433b535fe90ca636d1c77de813a6858edbf802da6bb19206": "0x5852b57c0d039fda16a6c948d2689b402526497d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970098ffc92b4fbe3870fe9e8c688c988d380af738": "0x00a8c4dc04b600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c99d84dfd0058e1407c5142d1a798c295b050000": "0x5640a67cb9a12ac09b8a79ce6c9bb3d8fdcde7d4ffb20797b27341fd6690806e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971933a3602d1ad20840dc198946803e0ab2b49d06": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b8630c7dbf3b9ec8021876f9f1fab265df12368e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b8194e6e38c7d425dd2e4227995ee947d9050000": "0x225fabcc55fae4c1afebe501a378409a53191f0ae212b917cc3581c9adcd102d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db80268054c501c008024aee44a8d5462f59464ade23dde004291254683496a66": "0x557e9b0f30b4e4d1738c4288d7a69ed8e79a7036", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397410a7076af80d5c66f3eb350f4d455c959e99968": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002da979ad2e50484456020e661e39a076c2dd33": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890011dadd05ec7515e18f0bb50ad1918198ea2b5b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003e922b9535ab92618c64fcb7e08320a8e5c3f0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890183f3866e19384aa414dadfdb3f18395b36f631": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005c87548ba2fa697f7d3ee6d63722cb4f25c7c6": "0x002c419ebb1000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ef0ed5eea27e5b9f3014876805800300e9070000": "0x60335162d0bc32398956a135d92d88892dfb89e37155721c982965e0ad9e965000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824363c4681b602b2f61bbb65ddfdb7a3a339e527109": "0x004072e62d2d07000000000000000000a7df9c0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928911bc2c7ea454e083cea1186239abc83733200e78": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289884748c1ba66a37845abd3cc3bee1621cff23241": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5142f095ea0acb0f9b3da20ff9cd46526cdc080000": "0x4cf1511151f1ff35e0241aa5ffbf2bb4f13f57e68a2e9ced4274ec08b6af410a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ccabcd8ff377bae0838b7bd827a83676bce01aec": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006d9c60615239ae70c618e265f3fc12f7a3b12a": "0x00769f7b7f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d2137339627c6cb8de09eeceea4b8160c116a30f": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3110f4e11c5b4efd2ea579663b23907c98e13f9": "0x00c012390ac006000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dd3bd59974417b224b5951648e5209ddadc42381": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897f6013d2fd484b19077df506f97da590ee9ab6c3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a59f85d8badb315d33d47327f37f632d0c060000": "0x7ed18ee2a4570d6d5da249195b8169757c0104f9398db1be982e656844dbe33d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892b3d18c655353ca14fb9d4ba8d047d08d1140974": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a7986da7d631e90cc61bd9b5272b6524a03702": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004c19d0274828f463ee886328a9c797ea9185da": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397648764f0789afe09b446db06388edb09d9588cb0": "0x00188d22dd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970054a7cf7c027ea72ac2b1994d1f6221539593a5": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b4f630ce350efe5e1171e7310bfb519b33cbdb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ae0942112b3e1d36089fc756b8a71cd765ed18eb": "0x00c48801495d06000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517f2d612f969a30082cabc94e031ec106ea060000": "0xc6419b1a4cfb8b590a3eb48bcd5bdc8cdfd8f595ac6e1bac1899e82a1c54820000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898b0885a1a520a11daab59febcba271e67ceda6bd": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5158492c5a4f473d515a0fa401e6d0cf3023000000": "0xeae7f0525b059f6a986863ce528fff8a3eac44e5a9a213475f3fc7886628a26100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517f29392e76070b3ce988de2e4c0b8360a4080000": "0x5e6bfb60d6b71fe80ee70912e01de904de80da6da39d1128f210e53db3c7185300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d08aaa9d9c3977f4d0e15e7164d1c04c9f020000": "0x82dd64c4a66dbd2dc7ba864df36c11af0d44120713270c85ef0b5dd38f5b9b2100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339797883f6fb7483a6cb748a647f23b601fcd69b393": "0x007ae6d4678500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896314bea21ac7c7c29127ac20b508ff8d430bdfbc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976cf10be9868455941c4cc1f1d29b741ae0629cae": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dbddada20c7b2b653812577388aea9ac896ac9": "0x00542cdad50100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979782b9c2c85c2e9db211cb6200065e312853e68c": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8e5c313c4964fbbf1876c174b86f7d030ae001f67249ef7122bafc679cd07e1c": "0x1e35152239ee9fe923f20df2f38280b32bc98d22", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7eb937e55cb2550e258629834c5bc2449e30083b2c8e67d82a62eb4f3b6f2e0a": "0x004ad027efd31c17dc857f5e3bcddc672da6bd7c", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d90ebf0971459d3c56b434d4a20257625893fd27ad1bd423739d918976adaf866": "0x05a5830f9d6fc22700b9439ba20d15531be0c789", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243ff7f274399c5040331a59e941b4971f31e15e47d": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dfcf0b6ccf1cfb1e77c2b259c08b1510dd978fea": "0x00406241594406000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dfe138e5ef68eaffac3ed112fdac6c1f614f59f6": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008bd7c09ec961aac1fffb733e6f7615ba6990b7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513e5dd524dbb83e3c22ee2ddad30e1bd7f7060000": "0x44e78b7a854326aa0e22da37b9041acfbdfd06eb176a44e76c105928938d3d6b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da46bfe557b5ccc967536df92b1f24bc6031bbfe646f2658f5b3ebac73cbd036f": "0x14edaa223bfef22b1af6f5500fe1766b15cca12c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971df8d1ba25da8a9d6804aed11a7650f89fe91996": "0x00007eb58eb401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397199a8bdf216604b7b05272240b71fab7597749f6": "0x008eb9a57d7c04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f897a81a6ab5aa5cc24e18c9976b3882cd0f4ccf": "0x00d4d44477c502000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928901e19120eaaaf5cd7514f028d5ee7993be7fbe6d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b9f92d067202d78d58b86cdd2ff7efcddc4a4839": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928913d62d5a1963046a3caccc3097a4576d1f9b42e1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b248acf3f128a50f811761121ec10fc60c5bac44": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c77c440c06384717ad302a6c5290c9e8716f67c1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516d3a712492fe925ef435ff891817a58a94080000": "0xe244a01a44bff3d79ed4d3d94bad2b172099b654cd11350563eaea8aa827256c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000c6e132057a388a9ef1bf73a0e6b686dad276a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e47494379c1d48ee73454c251a6395fdd4f9eb43": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ed801c678ebc0e0c2c688aad5bd4c11d32060000": "0x0a963493ad9461db8813dc1a72f886a7c84bba8f5aa6480dce7cf77c1849765e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004a9d5ffc97eb0a4f20df642bedc5f7a848e2be": "0x00eca5b6716f08000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896c11fa9f82689aa0d4d41f2ed3e3a80932707b46": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c84bb367c7efdfa0490412a91a1e4ac7a613510d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa6130c09a0f5db6245a628b67546a22b2a9c691b076073711a0fe0a9803a14b": "0xba22a63969aa637e9a0d4ae31beeefe97ed270b2", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5100eba617f988d89b30cae1905f1d85bc46070000": "0x963cce358c1b7f7a0dad86343e1ef27995a3559168a1f5d8f3b33c24a023b75400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928902fa77f03cddf7f1ab675723e15e88505da9a025": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748973b94b0273ce3d54774144b4941996bc62556": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d487097aba3397325d639a01695be93718b161dca43704d6efeac308bfe7af56e": "0x1c2fdc1f6d5ade6a3d39ab48d545a6a59d971265", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c9234f3b6117260ff6de428e15b943b387a6d4a7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f6de115e43fc234b448bab78e647bf65c608d4e5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f1982dd848a72657e026e5f9df604017b2060000": "0xf25e936da97c044ba8806998462c4e7a67ef74d34cc9c7913c1110712915791c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890087e1ad6809711d463c993d6d4396ef57423883": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5d925ba5a234ee898fb4ec7e86b1427eca421788dc9caad1e7293611cdea300c": "0x144aaca2fc5b80cf9407d115281ec805e620c211", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51090138a1f816acba67633390889140cf37040000": "0xf8b2ec818f2b911044bc04e2a921a95d81a5d1672ae68b6c65cdd10987c2312600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899e0ee8a2c14d8c467a9b31129caeae40b021659f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898067113652df86032aa683acd46c0b2abd8c4a36": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339728c42de479e57cc0c90b8a3eceb406dc173ad7cc": "0x00f2bf116e4100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d421f3f945c49886c4993af976b9d06e97b4a59f99b151c9af27fd612446bcd6d": "0x3716046b0394219102f5c2cdfd234312c0cb59a2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005ecb236707b6e0e75bbe9fb034528668ad21a3": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ff6a2fe83421f7c8634dcdb876c6ee43b23804": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892f41a6aa9773d67c3d31aab2ce54b27f6945b049": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009bae8840cb3906de25e5f8b9e89ee6cf7eaa43": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971b282f5fe4bd0bfda21a07f7184bfd720bcb0886": "0x0040f09bbce108000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a1a27dc484f0411fa9787e137d350b249a0cd8c6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708c6c136fb974c8ffec3b38e8d053791a048a0b9": "0x002a799c422300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397de5eea1691af15296ab6474d161ea8a4ab5f86f6": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8e2c77ae05286333b7a6f8a71f41b83e8a9d4e956639f22095f9e61d6bf76441": "0xec50c43867523234d23f0238a29f3e0df59e7b4f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700470a170ba243e44eda167e15063b4a96f25aaf": "0x007ef911b4c709000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339770c853a88dcfdf9996e60d3d33f3002ceddf46ca": "0x00eceba11f6803000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df2f675d0370f2f3fa3e011cd0c381e2c12d17fe56a01ca3045ee38357e158020": "0xe899a68189ac4b743750da4bd8445f7f148932e3", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282439a2d3f2f6d4a3fc6b4e5be57fa3d896b3d7e04cd": "0x0080f420e6b5000000000000000000000b58260100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702351fba2d7d4e88f690bad6feb6f93d0dff6906": "0x00e005f7a53b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b74a9972cc5dbed5eb8714672680d8a1bdecbc3d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cef11607ebc0a7535f23e0b7bc4eba5dd65a75b2": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510960e66f01b4f7dfdeb64da0a638a9b21b080000": "0x40a053bc7cc36ada17db15a16100e48122fe97f3993e9bda1e7b351167ebe31400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928920ac64b955ebc54f7287fe3ce29671086722b60b": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282432cf6d5701b164808a3f3886ee6258bf3208c3743": "0x0010df60427b0100000000000000000003b5650200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5a9b2328bfce7b23d8ecd6dc396125418dc03a4": "0x00d098d4af7100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928983730c5d67dc5740a2ced307a2612e4a337dc46e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c3f7af57008a7cd9b19ceec9c196178c7a080000": "0x48ff48391b63229dc9407669fb7973389cf9a9b6fb3afc5d3b39e3ac8da7f9e900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51117128150bf4d4b6950fcbb631221ab6bb000000": "0x2cd0447bbdce4d89867458397fe69cc242c9e1cfda74ce65eef5fd6af8858d1a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d36c27983d26ff572358bdfd21942a2b4cbb3391": "0x00bc41b5d36900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e78da27c3d7a1ae6ef59a79946d8c77a708319": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397968bbcc804a1003e95b3150c50fcc25873e0d8ba": "0x006001ca9aeb02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b577fc5fdc344b41df64449866e73d33848ea51d": "0x00f031b1450f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51840ccee27ac68f78561495dda30ccf9e46040000": "0x169679c4a927396e65263ed42c5bcf3a824cf1dfd03ef3dca2bdc0f3538e487b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0c08fd32ace7cf4d4689ca90420a0fdae83e637bd6166611a6c1ff2c3f17d51a": "0xed8bda7a810d594f145079dfb46849d8ae35c716", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970085a7ee9578243c26fa140b97bf771178297a3b": "0x00f826855f1500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397024afac105064abd224256087859ce5fe0dd2f89": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bd4e8aafa7d3e1d9fc46c5ca788d6dcd1ba873": "0x00a60beb412100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a37135f77421be9d9e5c15284188e9658207dba": "0x00541ff2d93508000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4b424e1ccc6f08768c921455f83181bacbfe3f0": "0x00c0b6403b6f0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900120c2c12a1b40077200b7122aac76068b49490": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894bd74d345c128f0a80bc711740d16cf3cce70de1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a08ec412ead6bbc45a465aff936e772ad133569": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce21f3256f9b285def6328b996d6ba21ee6cf192cf6b10364e6540ac9245bb6b": "0xbb2be121b15ca94f6156f20b8b45410676546ee9", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51911fc710a062b787fa4ac23e141a0e5112040000": "0x982a7fc06922cb361516d5fd621f1801e31943c3e1d957ed63e925dbd5672a3500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892b4d63aa980b39130ed7e3ae50ec40c4d8b33935": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cd5df6d891ec36ac93b730a2919c56d3e211a5": "0x0028dc32610300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e204f47c00bf581d3673b194ac2b1d29950d6ad3": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243b32816c1386cf0f7d5df26b4ca5921730c6f0ece": "0x00c0206bc81602000000000000000000035f610300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db4f3b0258a6c76ddaf414bedb1cbfa64eaad958a0cff4f3c57085c5df38c6304": "0x3ab2aaa53121d617f02e48c6e8ac908c4467a5dd", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700336f4647818e2acaf710ad55c714dfffaf1ecb": "0x00ec759f88c604000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700edf9881b2295cd5f87e43d57ac2707bef7f2c0": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397210f50483da86a563e049ccc0e261835a63b98ee": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cd24a754c817f83acfd14e75dc751f3fa9babf35": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397387902d21b6f76d28cac09065719c4f48f4cacdf": "0x00d42517c30800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6e1586b3fb4ce04143f3b84729234ab9c1e28eb": "0x0082db3cb70201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978036d0aa7ffdc5c19ffa7d73a50265849b7a54e1": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e45e521d5179090a446dd312330530177f585091": "0x0012fad10bc000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899fc6a2b131fb10fd547d90100629791d67619156": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900063eccd46e37c80e52b55e9ff2912afd8d99bb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765d6275a941e393d588ed1b1d0adc94285e00757": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397522325d3c47c84ff0a86fae37bd4f62a703d5b42": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d95df826fc3ea014f404a1368a254e23d29d99c8": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397279e235500d1b882c58d2b679ed5253b6e3df0d3": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ca509880fffc0b2dd5c6a4ffff2074483f0e982": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cfd2bd2a86152bf48b1cb9ab2e52c19d5717fa86": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f51382de43471e6056864cb39123ac877c1902b": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005ea02626ac9c77dad4f5b7601d99c54e112157": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5148b35d8cd90dbf19e60e3d64f22824955c010000": "0xea3243ff8c88cc961edec6c1cb24ff779dab9e1159a83d6a42ea07e125262a4b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c063dddb0309717f742363085e29ca9b097db6": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a752166d908f57d724163a24c4ca1fa4ad17d7e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928961436deba951a9f929c5d7f5d9488204c2037aa2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928978524544864e0a83425ad4c8408f81dd55bf7ed5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517f1bd3c825c1e3ff102a43397b877102ab060000": "0xb40b9e0fbd4e819b9a56f1e7e7768e7d68f35220f086a80165e38037f391894d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282433a6d927022815090c856377c74b4128f1fb114cb": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea153d7dcbb78aa15a80f015aa4b433228836d77": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ecda139d1a13ac2f0ea53cd2be13188e54a1c4b3": "0x0080dc9e2b3800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289266215c7cafe4d42985587d614ecc2a94075cce5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971af41a96bbaf348c3ca582b65193ab4d9108a22b": "0x00ec5e19a2571f000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928994ce92ac9c9839221b976caabc83820dc33a337e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289351a7dffbe4b4eba06a0b583c970c4f83e89835c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c68b2706d13f729df4eb2ab8edf4f2d59e037803": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928940692724326503b8fdc8472df7ee658f4bdbfc89": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894a7a5c1f34c57b9d1e0993e83060b6736f6a42bd": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d80f8873883fb8b60de13d8fb78416c118c1b7baca67a058896cd976073e37721": "0x3bca1e6cc37f9b72191cd98b6fbdce4e092f0d3d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977a377641a0f741ba35458b3fb478f0a6d013dbea": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928956b8729ffcc28c4bb5718c94261543477a4eb4e5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928922e90752520af777fbd85cfbdf28b94748e7b871": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bf8ef866b3d8139c982961f6850fadc17f1d48": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d16735bbcfb152276f7322d3360d6f4a6ff55b364a953484161e0de19f5599b13": "0x6f4920d9045a58646dada2c7a8b48f513387c86c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339719200c712302c7c8421ca893d95bd985c8586007": "0x0084449cfc2f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51eb22a433b90920be16b2aac81fc61b0a90070000": "0x769597b907a9fc660d40ceb46cdbc04e015f971727f2f530b6376e96e601ba1e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c34cd6c012ec6faa1cb8f6659a4e07b7f0834f87": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b340bb2b047e45d6653aef7a5e94aaf40b7baa1e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f2f3d21866a3167be7b0af44dacb2e496c5b827e": "0x009a073acd5b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282434cb26d4abc32e99e107f1cfed2b07bbadd425b79": "0x00d0ef2636a90200000000000000000068514e0400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893e7321d013167e5d2a3b591bac90baf4c75839e5": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc4727db059e79445c819878fb43324451122df130dbc91b177e62df8ddb8017b": "0x2b4294fc374566d487008f154cfb6701ae636196", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978afe5cd482d702980f9b141ab34150996db32341": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928970d394f0974b088f02599badc4b1df6e7fe52d09": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e1b609382d115d355e65a0ea206290fbd6ccde06": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f21808c5f1198f548a6be2410fb55fc0c4ac15f3": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19505a97a23b762327d26772616e80dea6f4a727d3b2399275d6ee8817881f10597471dc1d27f144295ad6fb933c7a": "0x3887050ecff59f58658b3df63a16d03a00f92890f1517f48c2f6ccd215e5450e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700410f38e2ab3f96a8303558ec4b470ad81dd10f": "0x00021044ae9920000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519e24c44fe5f18c4ca168e6211f87133c92010000": "0xbefddfbfcbd24527d9318e17879559ff9ccfd74181722e017ff693ec92aa104200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9abddb3e03b3abda683c57883445f02d6f6902efd36bae7007e1a71f37368f0d": "0x00d9f222b9f83e22e15702b798ff9b4d9d30b117", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a7986da7d631e90cc61bd9b5272b6524a03702": "0x00ce0530150000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978b2e32fc97a28e0ebc5482e328a8f8de993650a6": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001802a47a849fb5d290323e4255e690fba12898": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b752d54f3436601d8ccb4fa02bf2289192e4ab59": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513992c2fd10595cddb629fe30bc84aead0b060000": "0x4653f0d351f8bca69b7be83c41b90fcee17c7ac2b285bb01a95b3755a6101a3c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817decb5f00888229dd98de2aae6a2bfb8f31b52104987f4b52df713b32e4a48df8f": "0x4dde991987acdfc23c0e4e72c70d715794a052c4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976dcbf212a83175dff095fea2d226aca22a93d643": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289328752def488a9c3aa9e89edfb56cd7b4b56f7c0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899a2d3f2f6d4a3fc6b4e5be57fa3d896b3d7e04cd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d1ba30cfd46c08cf699b00c705de01764689c272": "0x01", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d38e9e71e1ed6e521e2fc802a333996a60fa2581b1496e9eee3665ce0994a8213": "0xd7ff0231086abe3e95ce3773d60a39bf27321ee2", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f454f6cd7fdc154be5bdc8ae57c9ef6d83c71b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5182527102535b40f63760edd3379c4bc929040000": "0xd006d0f2c483b3ad7df4a76432af79ff2d6d2adb608c1066c7aa1758cc6b0c0800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519c1c52c6761b493557c8745c88811fa499020000": "0x08ca477537ecd3556ea4e694f0d3c9959afdef57149bd303bb85c84a3124a30200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bc894689f9202d7e7b18734c97453335548694": "0x00747465e12500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a1504b9d2fa2a344ae27cf32d1ddef24ef6d46": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974daae42c5e89d09da39cb90f81bcb2acbfddf67c": "0x00341735f16d20000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f548b1c7499a85e9574fa5845d0308efc39d19bd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928905c312d2134e5c632296c124a975e7cb9f79f519": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ef12fe1136a22b1ba0906561ed22a934e44e244": "0x001e39c7e9a600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514502ed4ab93771bdb7e0923a6eeff6020f050000": "0xae86355012408b1130842a93db57f27d3edab57e7187589b16d4186dc8eb5d2f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8c71c824b4bf5d9111f4513c46ef76f4b003631e3e5fed3f644c2737fc562656": "0x002475878828a236151128f5af451fc3c1ad194c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720135f71a2c2d92ad87aab4431862fd7c38c79c4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767936306c1490db7c491b0fe56bcf067ede1fd28": "0x00aa8af681571e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ca1c423a0a9af92343998ac10b6668ecff9e09b6": "0x0082357a0a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890038dbd81462e435a757f14dafacc119b98bc2cf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700aba4b515e5c9b0e4dcdd8fdd9c870a3761d943": "0x00dedce2d93f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006061c454fdec0a781c00ca44508a04361ccd93": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de88a80739ece6a8dfbc8a37158c0c1bc0dd0368c672a4ecf3516f0cbd6cf4350": "0xba90e5b6d3376d792ca3927524c27a185fbfb159", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bd9ebcb7c6bcf472a69a1c7a84735942859d3ace": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f2478f49dc3dc086605e6b5a8dc1d8a8d415c876": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ce59a64a8f8d700c31ec0879dd62602fa6070000": "0x137e2c529088676c797702ce425fa0e4ca92a4e27dac6a2e6351bd151cf9441700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1acb59938083cf7d003b8cdb348e28855feadca45ed08b49256bf8e13471d461": "0xe688284626ca2d00b578865c0e7d189c6ca978b0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397960cbcac0d20353c14c5a4392af3b80b3f962eef": "0x001e1d3f083200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007abc56f6083d36db03065f7afd36c55bad6afb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004ad027efd31c17dc857f5e3bcddc672da6bd7c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397139369f83fcbb405f405796c3f2589bf9a9a882d": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d396f87af37acca0980aeb814375eb46880d37bc": "0x00009573c24800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f1b0cf40e48bf2dd646e0fe719476ebc06010000": "0x74d34e1eaa0a764af6084ef3728d63362298575d5efa077a858633345296022200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a39f0f9664328bc6dd494d323810c93a19f20a": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cd0699b4667af672f71ea4e589d9d2c29ca992": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339787ccdf773a25a7036e7b95de5ec8fe74bf7121f6": "0x00301a45ba2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b7b4350283ad1256f14ecf068f941dbd21050000": "0xaecf138ea1b459133e80dc71b736b388df75561d405dd1af13c872433b34685600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970075cfddebf8f19740296cad7870516db11db25a": "0x00942d64b5a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928950b2c3a213d353c66a2138e3f21a1f909b0a87b8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001ead7676d5a7c09c64ebc80de0099cae972e45": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c5d005e57310e4c5f148be7ba4dd666db6884c36": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282439d979604f1633bd31944245b5f6d183adebcf10a": "0x00404c948b3203000000000000000000348c2c0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0f3ca995aadd1438b56bd795335a723114ae98e": "0x007863f906c40a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970adf0238f7edcb1733269f852ff86bd4a9f37b99": "0x00901f44ae003f000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002d43afbc32a0d67168a2de3833ec368ffe8983": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d2f58c155d8bdfb4cca005e775f4fc53d6080000": "0x6a51e7f4c64e59e468d49709561ab3d04062aebd5c0f297a491a8002f2a7225000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b0c38ee5e16a61029d6cea44a11f26ca39070000": "0xe2782c6448329ca3bfa30c87ff5ee66a059329a9a27ccf8e33806f0698c38a1700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cabc87c953dad294fc0ed22c563bac10fa8e3ab5": "0x00c4afe38f1008000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006e6907ba032a02644f7289d5a2e5b6f3e41a49": "0x000c5849192401000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a3041ce2ef4e9ddad0ee763522a641b03863d5a5": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289582dc3c082204020f1639c2079fcbf2d197eebf4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c80ef41c175b8728d6e337e89a8a6f4a1d010000": "0x9a50a0e597419f53c4faa1f9bbba58733ea731bb0a3fbda8c12466892683375a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b691159dd19b5793991002db8bcd61fe3b080000": "0x3a426ce80e46773962e068093597661b7733494a3dc2ecd9873ccb7958a7a15300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005ff1551da72279435c79cb877af44a76a7d552": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba747ec663ca7239cfefc4be89639c3cff6da31d": "0x00e268b13cca01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511736660595ec1d2a12acaad646a5ba0ded080000": "0x82e4431bca23b39a02f6131a04c65d0aac0ff3ed9e7d1ca880cee1d65ab8296200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b8a300b59d4f4b3bc88e66d4ddc8edb8f0703edf": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de4cf3489002e8064b9ec479414290e3bc4a87095b4b1a65cdc3ef1e06593d256": "0x31369166ee8d31fce7b69d3231e42245b117c9bd", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898a654566edd646283c920e3225873fca5370f489": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282439fc6a2b131fb10fd547d90100629791d67619156": "0x0080c6a47e8d0300000000000000000039b8bf0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973078f22015436d621062f7cc8334774eb5685e97": "0x00ee1fce3e363b000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aa0346f3edefd952f673a0e24ae4658c22a64743": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897928c0238f5850957d9826f712b688d00041cdcb": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51078842af4496dd697c1627a4ecf780288f080000": "0xaa84e0c7acc3e5566e5b833d2f8619b98abd0d2a2c159398fbe616c3f16f8bd000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d47559701f69ecb16d40d5fdbdb5f604fdbb9d1c": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f2f1db23b31f2a3dbbf9aadb4fdc790a13040000": "0x982aa00fdf3835f109ab98a569a0476af2e87c92bbf3cb6c399254fd9b31c90000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970051ef63e8b9714d239156854c615606cd9effdd": "0x00542cdad50100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d31748110020cb554ef2d73be9dd33892ce435": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397914c952f5746b19f007124c995ee5b08061139dd": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a9409db5aafca9b68f43dcf38bf46d460079cc3e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f3841e5e0672e7bcd9a2a3a25e24ea7eb0d6c74": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b7680dba45cb6fd6ae148cc8b30963667d386d": "0x0084fde0500b00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51014939148f5420828f88b76dfc41f913a0060000": "0xb62858778eee786f221c566984853d9ecd56c03238b3618aa982546de7abda2e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895ca69ee86a4131262ccb5c56af72f42d597c5a2d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f489b21d5a4c8283a1bd0d39e47b654ba2f65a62": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ffb3bd8b5365758350008118961254c5ecd1f80a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bbd5f8d33f607a03690fa73f177f5a30c864542": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c8f8f563c3e6a9fbb039fc3e20b53591796d745": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289141af52b68e8e1cfe3318d7b91c698b6c0e2d9f5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf6aef56499745cfc8abee1fec089e86dc2e0b33": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339772ff95ddf81bfd2db7a088aaafe39e7f3ad3682d": "0x00a0724e180900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510b60a48f2075a52ee5e796dc164ccfdc73050000": "0x6a276c8c59606dbc8515f3bbde2bbf30956ae793689cf5c003d7e595d1ecee6400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700248d1380769d8ad43a4663da2712bd1186dc76": "0x00cccfe07f1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900648e430be595e8293d447699e00f383da18abe": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890089e3121271cf650d27633bd9693190bd2f69f0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700da52ce7a1d54e078399894b20f3b4c6c99ebfe": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5162f1503ebb79b1c53d356b4bb663781ef4060000": "0xcec75028adfd5db7751930c7d9c79a0e660fa55a9cfe45030c0fbb8339021d1c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd65ce74d64b974f226eb2437a7ef2d13b5c240d1de9d3432186358f4f6f82163": "0x3bbfb20c83b79f8cfe3c3f7296f0390900760745", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c1be5037ac4806f3087c19c2ea3375700b9682f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514ebc4682968784cccdcd5f8f2d359ed303030000": "0x46975f837e5abf94b061174335507d461e5b4774944e42bb1f41003eb590cf5a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1a27dc484f0411fa9787e137d350b249a0cd8c6": "0x008062175ed158000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cba036df49f3553123e3a1096df8167a04090000": "0x6a8ab02983c79bae0385d2650e022adc6d121bef8827d81ef82104e43b21ee4400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397458e55f31a66a01be0801221777d1127de93f6d4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928911e328bd7023e933426940ad12d6e1b5bbd55f1e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514974e6f244d55c25352b9537942fd40703060000": "0xbcbad26ad9af28cfd50dd70c8fa6c7dd3964941a4e124f19851c003ee8be013700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708ec4aa26d04dba7ecbbf121d50373ba1037e763": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e86113466d232dd99103281ee6da6888245253e": "0x00822671511200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970e8e3a75280f066163eddafe3c5fa91ea6196047": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd4d2cbec06234804a90868dfa7f89619dcc178d8d361aa9e9eb082309ad6c920": "0xae6869a774b00ba29794c8d4611295bb0d9c2bf2", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890035d19bc0178da96f2ad24504182733d90a0ed5": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d58783e1e9b02c77a63dbb17861f1fc21cca35045ff11132bcee7afe4ed5db238": "0x37c5bf8acb3140f17819ecb4dccbf2e66dff9ec6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e1a6e1d0d940de7accfddc03ae542af6d690c64": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d97436259f34e11ee1a0be1e59a98a6c4ccdbc": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df4ae0f55fc7387bbf3ae242e71c5146254575a1a14d98bae30ffe28acf508c0e": "0xaddb5210dce9127918db041caee93be7b50ce633", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d9354ef22423d1d544a01a2fd8b2ac03af0aa0e": "0x000a5aba704800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fc43f8e2e61130eeee24b8f1d5fa9e80dcdd4f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896064d1a20e529ea15b06551e1690c8f50342edf2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514b5023c9b8e367fc4f684bae788c0d09aa050000": "0x8cb954a659869c053877b65d7ebc7c30e97a7ba696432a649f5f02965187295b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5138722c30e3526046d4f0d63b1747615b51090000": "0x48e781045357bb7da0d214452aa40813fbbba5a960196c5104617760e517307c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519368ef96f1c00a00a83af1f1803543cd31040000": "0xec09c2e24ae25500ab5e3ca7fc1961b76feaaf7c24a70847e8742bd74ca9031200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891dac430b96f24ff9f0e1cbdb725407372e09f09c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289671dd13509d95926af853a161e78b4ed5c8a37a6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b7bfb979281653e88fb409461d39f319ae988197": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d7438a2461c64335a5c736b31be6a2506be76d10": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289032f6b944721fd338858bcc0e323d9afe77e0a40": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970fdf6c80ed447a4b0692af53a1acbb7df7bf983d": "0x00f43e5be3af01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000177e159f6b155a0e81f6859e9ca4c6610156d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971399824aa53d03fba9d3d13585341c819882184b": "0x00b2c931cab702000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900feb32379a84bc54fafefc9e3faa03e626892f8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b372cf3e7c70309bd436314663ebd45f3ca4b15c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708548af3414d04416f96f60cb1c39dc8ea927b4c": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d182bfd28e1df3520bbae3602ca44f076a7b928b": "0x00cc087b5eff0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894bf278ff22a98e2ec520472ee271da5586d4ac12": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a8fabd8cd6b1a1eb325d682e8532fa3c55ee40d8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c235870df0ab4d032329925e9f4024a6e753e7a7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0c04181f1437010d0db38d7623be82af40ecd6e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928963c4681b602b2f61bbb65ddfdb7a3a339e527109": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700638fb5bd1fa89cd2c29c98e6196620d749810c": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dc9c428b9828211415ee1e79fc3aabadc9db23": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f67649a3f084eeccf566b5193cb6faa830cb10bb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d36bc6b7da07101e5302f94d5e39f1eca8aef0dd": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d72ac4cde67de555c2f0b1ebf55bc45f0b61458d134719bf9f56d28867cdef858": "0x30b943dd80ec2729942b65aed370835bff04bfec", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a1347203b8093b7ad0f21f821e7d53f841b25892": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895f7269f2171f05759a8946831c2300720391320c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397599ad3f92f76e859f7b7a87dbe3aacb81e54c6e6": "0x002a535b914203000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5103a0e638cfbcea4020df32100ba5657a2c080000": "0x70fc94e4372b91e68eae0dbbff7d37a76308ad2c1260b27ca02a1dd4a17f704200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aba13ff6c070ac900ca4e3861ef66045be42b37b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a4c2cb3ef01a02eeb516c1adb1325e3bfde619": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289968e43f6be8d8ec1e8ef7c8d5c60f34eed8af3fa": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979fd1eba5f41419b2887a1e36e4dc22598254864e": "0x00b0a2f9e79201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f61e40add6b7b887ffe8792aadcb6433d5209a4e": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51133f6a6876eeffd5a8efd6360cf88f1e1c070000": "0x90a14c0e9d0fc3ae3a3398cd3a5735deb453da1b09c3c651c7dafd2a624f1a1d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b243dee66433ea21911a964a9fa3bc04e63f4a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8c23324b0cb29e4fd1a68cb08febe58b50e39d8afdb5f752d6c26c8ba52fc002": "0xc231dc7e55ec4b6e33ea3ea6d77d88917d879781", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970022d7796a2d5977267948e5ffba8b9fe04c3da5": "0x0066a39de98c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d5f062ae922c42aba01b342b17fee7c9ff2d071": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea982050e0777f55c745aecaa048b8874ca2a81b": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c391666d5b864610559e59c046357585192a25": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892d4a8282ffebc08c9decb113a822135434f9b4a2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001dfd1c89c8c18aacdfde2e1e30b11ec2d2dffe": "0x00ee853eab0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d3396c5b7ada618bb851ef905bddd1bbbf4379": "0x0016365ec7bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890062633756e91d8fca9dde56511e65f7a1d73298": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d82c12285b5d4551f88e8f6e7eb52b8101000000": "0x984e16482c99cfad1436111e321a86d87d0fac203bf64538f888e45d793b541300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339791e943fd3640f82f0b3577e796a9cb31724b7bc0": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897df289cbd544ba6bd153b783ee9024e46a1a7527": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d3b766e58e0d0aecf1375297e84c798b15936d1b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f88370269b6718332b8005b44de1c1abb1c194b5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512a7b0d5f65f1c471620492ede3de62da09080000": "0x80ea70620d770611eaa9f1a784b08d3be34f0c48166c640fd478059b954ff43200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243320a67f5d718c4b541a5ef8194ad4f4638162f6c": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970037af14a08100231979898635d6fe870b1c846f": "0x006e36bb883b13000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769a80ca39168c9bc6761b9a326c6f15735139e0b": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c417ec8432a7cc95fff6a7efee0d97555b07caab": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b7067ad6ed9252ea6d37ab1b78a62132bfc6340f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289afe949978ae2f7098f9b5c2338ed5de20ffdfff9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d802bf4620f7a14c125343ee7bb185208670bae709c63228c12acf6ac4d023f22": "0xa172d2ca38c6011f6a48bc781b2196b294e3f2aa", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970055ddcd8b7423b0acec3d0de6c0666b06c14e7c": "0x008c23ea09fd2c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006ff6c79e263c3d58e9718ca0f08540d46d0db2": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289026581d80b9cf65c119f32a750947c45cdbb0847": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899661231272cfd204a6bc7aca349e597d0c034701": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928998f94748373c637c8599aec7c09e7d40ede3b78e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895168b667344102495f2d51ac4e8de93e537403e1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899ca696ecc735a7a734fbce108cea75f8e982cfa2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ea63a7e85bbf2cb582c90d97d8f78170ba7743a5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b46c2526e227482e2ebb8f4c69e4674d262e75": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3050a297efff865cd424b60c6b56e4eadd261280c2e156f2b04fc6f1f9e23279": "0xf72a6e8a84e112b9fd925ad040b81bec8b17a6bb", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd0c1c48b97e9bf16e10f7449a111e40dda58ede742fbe3aa9a6dd5662a6bce34": "0x164d92a6126ebf0f354fa098e173f1a50277fdd2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b7866698f9b8920bef90aa5e16a0bbb238343d0": "0x0040b10baf682c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976846d14e5177c97220466fa343cb3ef0d1e29f07": "0x0024e56bf63801000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928907dc1a136ca9cfa640962ec0a9a8332f99b0bbff": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972bca1236e83b1189db3941cf479b7c7cb1112720": "0x000aa1d3ec1f01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d3c1c718031e8255bc5f2064d8eb34534a050000": "0x3aa9d6f420f82d9f11560aae9fd19c539b967c35179f40613786f1046228d96800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977804275d8e53aed92f09f99f55e135c75bf297d7": "0x00e4c619674304000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397422af240dff9d253cd31c30d5af9647fc60bdc64": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006e7f956676282819af849760db488febfcf3c2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fcaf0a13a98b04a3080d7e246ffa7d072777e7": "0x0008661df4e003000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892a6f5ad410b4659a89bb23a5bdc841fc55f56567": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895ca455068327d42db7e66c6c80532452f39ad256": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8a03b55a75d4baae8acab8224a1ed1bd6636b477234b3c540fb3282f17ab7716": "0x4036ce05f4b3f7254541e9f50f56247cccafc14e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339745ddca7c0426fb78561229a9958873ae9cae4e79": "0x007ebb5c423f0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339713d8779df2c88e622175dc24f8bd2b53c562e631": "0x00f2b28b484f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897894774b62144bf5cbbee837c96e833e16e3edce": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e13540ecee11b212e8b775dc8e71f374aae9b3f8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928986716e7f1b8a4ab2d72262ec5e034ff995b684bc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e87f59ab519b9ba01190ef68bd814728ef58fd": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e173806d025484091145ca79d5d830f3d38b4f": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f9aa698b3781ea29878036773a0df87f5325d98": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700799a6372295097cd51c0769caa6c8866bcf7bf": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890062e7f8465aaec10bc526bf5bf01443b0e450e7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893257722a739a71c5bd42d8818a17faa4179385e5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898036d0aa7ffdc5c19ffa7d73a50265849b7a54e1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928999bc4449c9a1e3435912f2c19e75afb1defcbd94": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339713d5d590be45f86e1c1297073951ad7abfb746e4": "0x000449dc7b2d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fba281c66fe1034a2f1cfcde7fc6f6d939df9cd6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700feecad71fbf3f5acb1569b036cf1bd14056316": "0x004203eec38a05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b059b066f976d528172c8d6cc5257a4787266012": "0x006e7072df1a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928912d86da4cf1d9846b7118006e6948b51c75c6cb3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977a1e82a8554ccc29275f5cd010de3668578bbc9f": "0x00e6add2ed0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282439c0c36cb561beb841efcfc7212710d0c7b1bb187": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517605566fce1354201c477a305526a8f118050000": "0x603cbc4d841ffa9811ca096535fb43ec8e240f6c058fc98f2619c72a9fa9e31b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c326c5ab988880f8fe6c1e17b97cfbea724a39cc": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51301b0066d52e9ee37ab667a6b44c882e08080000": "0x747f1a48023fec5d71e82ddc8daa3c0b1d1f4e6f7e1e753323eafd83c3b6865b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977dbb16b85b247430888763302413d6d2abc1ff8c": "0x00e849c81e1900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f40139d03ee67228f37fba06e187cb0944fc9e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513bc9d65d31aab11613d936afd952710bd3040000": "0xca9a6590fa55d82d686597287bef830a7f0e7eae2650c54f94f2d2499525330800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d265013803cbe5f9f3ef7b38ad278b6d097d3be3ed79248030f460ba93d164a60": "0xa3b20eee7cd3801a6408ff4c6f73a75556da2a1d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977cb45acd0b8a871f396b319e5549bcd36a047533": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e17abe40cddfc8a2d2ed13eea958eb0030c0db": "0x0056e5d2950100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d54ba59a8d253a79ff9481e5f86153c55e5b01f20eea7a2fb32f1a4f38d6b7532": "0x00c391666d5b864610559e59c046357585192a25", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51986c4eb31b62281df5c166a050eab611a0040000": "0x0450c35fb5d3306a120893b253cfcc588bd9f5d0a30e1250b2e15a39a4610a0e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d559c543464fdea0ec1795669c96182180b559": "0x005c05ba430a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824343a6edd95e865b50426330da71638b56f2a75c21": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928920a372f22493279f89526a1f5d525d6c6b4abeea": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e409357222d95275da1b5bedabf0c27f95080000": "0x14a05377eae1b20f0895fd7b7eb55ff1d89bb396c311850605cde11befa7f92300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515ac2ecae4a6885effbeffadf04a151e66a070000": "0x5070438c5a597c4f1f46a4fdb4a1b5a88f46b37f1985b15d8a6daee52670fc3600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516d427c59fff4938a7299e8ce877b2be10f040000": "0x8e2c77ae05286333b7a6f8a71f41b83e8a9d4e956639f22095f9e61d6bf7644100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289febbc884e93912a472969e7da085eba33f526ffe": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f55e8a9bc462bbb788e83ec8d022f1deebb3e4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972085aa6de1e83261fa966ed09b518c3eb3ec30bc": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d90bb7e90c2ad7c2a11f03c5237c6bdc77720cd5ebc3257f138e94b004fcd1d47": "0x924c251902924c7dbd4cbf166d42757fb2d146cb", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893799d6c8dfad3c6cac7d4ea9430458503bd9d4e9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928961f4f7d2a593d1040406d2df519699b96f455a50": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b48eaf22121c5090df38caa3150be0872b9de6ce": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928954368965237a390978643cced184c6ec51d0ffed": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289517d18c6a1f053420d79772cd05b676d3468d21e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d9797fa252d49e91e3d3c6be5e698ac9ba040000": "0xae50b8775cc2cdddd86bc443fe42bfea4e801a316ee579264cc7b4d54bad330700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a528e61d81a47cc9ab160555143da7220f9471d2": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d666d51a8d222c2065f611e6aa7d4c8ff4a4bbd": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510edaa8f8c2f52fbc5c1942f87feb68f16c070000": "0x0605f038b446e037786a3bbbbb0e1c78c2472c4910ae6f97902985f3b72e114f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397422d9bba52a289ca568b6be38a5bda2ed79fb328": "0x0032d33d7a2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751a1bac19e5fde2dcacf1024a16aa62f8302617f": "0x000892b8f75a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928901b54f22deff4e08365c731d923a31379aef62ff": "0x01", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243802b450c936ab1849243267995dc9aa45f234a48": "0x00e094fb1eaa020000000000000000002bca4f0400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4aadcb14243c81ea0785494a25185106c5dc1ee5a56078ae95603f2f2aaaa153": "0x39b51396ef3c70571ce86532feab5598a766e8be", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289819669704eab9a1a1086840eab684846647b969b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b75e5a1bd0b8ee7ae4bbcf5551eec80ae52a4bd7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009f9a431fe97b71e157c50043f770cd5db2558f": "0x002ac6cbb1f901000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7628a5be63c4d3c8dbb96c2904b1a9682e02831a1af836c7efc808020b92fa63": "0x11efc885eda7ddde9c1c77f2946737796ef06e3f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700368ab2cb58eba931c52dfed54379ef3b56f79c": "0x008a5433260405000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824337356375fca1781c398d3a68924bc6e95bf30ee0": "0x0000470ea1b0f8000000000000000000aa5f6c9201000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339761fe11633c0fd8d3c9392b777c0996254e5368cd": "0x0056b961800900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee1fae10668204a6a11d73f1dfba264e212d3286": "0x007465c1f55500000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5147f0b2271b7f2e7126cb8e761239abbe41070000": "0x788bee7fa9fd8731e80ceec5614e5568781b75f54b34d72fd1b07f0e185cb72800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f18036a91dcfc6f8b39de68f170a683efbe0527": "0x00ecae33792600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339731d6b3576ab86a04f10bf8e000161a3defb38ab8": "0x000a357c2b1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000c10b4afef8d4c640ae287e75dd71c427cb0e0": "0x004e914751fa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b422b17a216192f8a25ee6d08342dfeb3e05e6dc": "0x005c344a08f900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e3d07942314ac67dafd42efa35e4663b35aff06b05eac14f8da0805970080f8": "0x8d5bd8a5efaa38c2c9f3ffcc73006b8ff19192e3", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f4ecba233c28d3b5334c7c1c1d1d0e2b1ffc71": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c22a65da50ff23a3b8e236d586fe7e3e01ddba5": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892406879e1a8d273aeb64b000677b597ae8db8517": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289422d9bba52a289ca568b6be38a5bda2ed79fb328": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000d31e57b61e464c0241eeb74d9e6ef8f9ebe09": "0x004efde96e0b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005dcc47544933b9b69fd851d150394c011baa6d": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0fa0937a830c3b80de826638649742fcc0f747c": "0x0010d454955324000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515431f26eb168d8c1d3d3d6f73b1a8885e5070000": "0xba19adf8ab8528c9f53058b494b6154dde0fadfe2bdeb3a9b9c87761cdcbb44100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b3aeabe65664ab160d8ddef2d0a74f24faf321c7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d44450201e6957b7ffdcc7f63d42477e336461ed6d74410c812d79c3081ad8f6b": "0xcee564d87985e3ef80e8d0cea1d8f49278fee135", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004d1fe43ac70412e62d8186e8e0cb261d6c602b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be7f0d32ca1cfa5d95b4c10c960a088f2080a508": "0x00dacf383c9f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9133e7d31845d5f2b66a2618792e869311acf66": "0x006cfe5380ca41000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700edd6cbe72d13a402da3478c6fbc8a0eb461fb8": "0x00301a45ba2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51675453c711cf782be41abffd34f965a92b060000": "0x06fbacf43d7ff4e047983220c1b73b914ad77f93a4d73789c73930b2ba6de64300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700598748134c87ab7e0e4de09dcb4c060fd73591": "0x005ac97c261100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890052b34370f45aa1a3d93b5837975bd9e088d6c6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ecddc1c11402f03446a1bd87ca5232df46bd5db7f9a80537464b299d1bd8a0f": "0x516ca63270b7d253cd9af64cb9d92d62de81656c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928932c6220c6116e3666c220ffbcddd2e7ae8d78c2d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cee1f42da366ae653c516cd4897792785a070000": "0x46847f68e28bd9107279ca1a70ef05f942036e3216d4a47a88361e563b2a592000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970013aa2fb5ec916660b38f1d53d4fc9bf8ef8a84": "0x002c467663c700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970048de500664dd14290254bc70fa818079308610": "0x002c419ebb1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c2ba9a003f6616bbb133e3dbbe827e5f5c45371": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c8b461ad395fe2411869281301c2ee7b5fbe5d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f993f7ba557bde7f6f8c49c7d53d2b0d6dc87361": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d06ba2bdf21a8e40bc4f333eea2868aba048a42f00bee1ea5c1cd8913eeb32a56": "0x0012f59b4690aaaac5d4631d56f30e00383eb29c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928956fe408b24e6ebcf0d0230c8f4b7ba25f2c2197b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512c26abf3b390e47e4ce118221f72ecc565000000": "0x5647a240f4d349175675f16c74a964e387b5d8af5053d29a9c4b20cbc457086d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893eea99becd232fdc16b87fd8ee370a4d0ff68165": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d509603fcf64e4c4e9332d7732430ca2dc400a758418bcc1ed6b68829b34a017d": "0x00f1a0adc19a2cb4f04bef8a27e35039d0d90746", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddac5dd2abf4db76ff860108062bb8bfe188f80d69546d19c1993f23926ae3638": "0x00c26f719cdfe1303d3ef566ca2ada12cc56407c", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d204afa2bbb11abce235187463313f068329f58a7a8fe132cf04400fb3cdc092b": "0x1c861c2296e9911ce4a1cd4bbd197a360f8cfdfb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008389dd2775442702e13781f464c01558823b23": "0x0074e2759bf100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397144aaca2fc5b80cf9407d115281ec805e620c211": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c4d09effbea40dcbc56bbced8bd75c4bca2dc6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928926dc3a2b04c409af7f03783b000b2cc05020ed7c": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431feed555363e3ec72086c6f347b1b8f67d869333": "0x00e4c88703fe05000000000000000000a94cb20900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dee94ebffc484d8d283783d8eaf3080c5af24811ad9c23a9cc52d8ec7f928fc2e": "0x00ac42f377da5d9a624f94d0e9904e76c144736d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fd5d715b04e11ef04b8a406c4faefff7eba3fe7f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e228a4c62c1abced2b55ca9af8b08b1cf0ae4988": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339789c37fb9e6396ed6ef843c62fb32c43250e2f451": "0x009e1b25359600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b0fb7ee5554869bfb57d69836b005e00a942d7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003edcc4d34cd4a22b85b496aa33defee0ae5717": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765dd37ee6e2df4710af8229d4aa913ea6264ddb7": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b94299c95f6f3fb6b0e35433232e4e4468d1b760": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893f9265fd0b4f92eee642703e72d749c077cffbbb": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511c9441926f98de666c6b79647da7947ce2060000": "0xbccd3abe59dc17a36fae237852338d0fcc0f616a257aa8ee05a964b8b521ea7400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5113eab907ed8797e02d09c89c16c2cd1e06090000": "0x68ccb9cfb2b212cb33a483824baaa23e4a088ce87b23d790e3eaf77290eec92500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c2746e9042bc252215d3153d0592bc44f28b2f0": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892bca1236e83b1189db3941cf479b7c7cb1112720": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d84a8b7fd4d56a3a955e9b72ae0b793335b479fa4e77a9f95c87d51f789de5f7f": "0x00d24d8e5836c187481f76ab9c0a7ab01a912c31", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51039b863a309ff53a282b747533be17af37090000": "0xc81a4baa6265095f1081b86633e628677325b8f7ce821d1a44492e05b017577f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970db4dc6e5a9039b2b8fca026963655b04596e903": "0x007e313b741900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51618063be048166b5f21fc0da45ea548767040000": "0xda775cb27a9b7eca3f00c453b23e18c69fd9e4920363f31c201e7d1fddfaa04000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d937ef7f30b8533c60dddd948dfca54140055f7c001bc8b7b7f4e3cc483609b47": "0x1f8978b550c0291627d5604a84e76fc044c23fb5", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff45a27708c55e909009e59f1d53aad9b940e273": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ad1bdd11ebe8658f0084ba66824e9fe616000000": "0xdec5caa60a55f5abd1f1aca49f2670591b5709d2d9e94fcebc1e5aaad92a405f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d2b403199705e292860c2978457aec9075b897": "0x00b2f58f6b0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339795009f768050dfb14ef9ada842323c6349386972": "0x00488c227be903000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900443dd96337e1a0de0d5b909ca680f00af85f45": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de61956f7fe271404c5b0cd4b155ed105f9364f4ea7608cb6a9c127794b8e3a6a": "0x2a6f5ad410b4659a89bb23a5bdc841fc55f56567", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004e8ca36ea8d56e723c642cafab49c34f261abd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895414dda50fb2b732ce8ef2f3f796fdf342daa5fc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d69358163f5146f04918a092ec4f527cf6f252": "0x00ba42ab7d1600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001597df1153c433614b9dcb4ef8f11b640e19b7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894ef12fe1136a22b1ba0906561ed22a934e44e244": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899a2da86405f0032f5ae8337cfdf47f067fcafc67": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9004d2df7c89ba8d7d65f01056ce579d41a7216db3c8e6c28826aec6d6c21b26": "0x9cb6247bf9e22da514b1b32acae28c560c73d848", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009e98ad910f26769d6a0e2037aa4285820fc9b8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb5d0f2f6b345f9c6afc5bcb3dab5ac11385e512": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004217146a0642a86afb5e6293021dd02d1f4729": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f05bdfd076980a8884e37d1cf90bda6801cba37": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397654ae9a08e15cea8d7d8bbce09f06ccc1cd8024a": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c6b2e23616f4c246e2e0dfaa0485ac98be69725d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928984b3ea9389fd14b2d023a0650890e7ae7c2fbfcb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d6d291937e1e0158624cc3644af95a6140f2c11": "0x0074d126b13700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516d6da545fedfb3bd3fe0ec7f30a10f1c87050000": "0x769cd0854afec0c1a6d6c71d68417a13e653809dc8ef73842b0fe19f90b1b24d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de2e6771397bb71c2008483d31e053f551649d98fd835a540afdf9edf781a322e": "0x00a32ad2c6d4d5ce0b978e4e0e955e02abbb70ca", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a63a3a0fa11052369722629a9ac94a23a8960d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce855e2b5a5260a655291157b6517146f10888ca83cb17609b906a401681a145": "0x190e7c0403a5dd4bd21d426d88b76b1d513d39b1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b593edd7cba746ca27bca29de492b3cdaae2b3fa": "0x0000c52ebca2b1000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519e56b3781e29da7a9b90a43c240ed08e3e060000": "0x54dc905cdef051a3b6bbce57b6e6c5edda54bcde2f34d763dad9e179ce042a3200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975414dda50fb2b732ce8ef2f3f796fdf342daa5fc": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae723b4cb2d54c6806751d253f1e457daeac267c88eae738864e5c8f1ab30801": "0x05df79a1f08a459cd77ebbf6b3333da75dcb6141", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b67da45314e56d9603cba1d09804e710759b57c": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd546ebfde341c6b20726d206d084de51c316358": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d524106d11c5b394e41ca464f7bbeccb2c44e1c9d69ee5c74b87074fcd9a4984a": "0xcf0489ae7bbf3b7321841f3ce9db682a6b0cf612", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a35905c72be4e346fbac94bf343665b680060000": "0x28b60a62d04c7d92c4fcba02072a384e2f60ecffd56264aaff66325509ee227700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f67383180d9cb41b115c017a3e1e9134a6571e7": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e737ea62ef4a2b771e3e82be3b8e0898181a8b62": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001f7eef6a5b727738156deae8f0604d92df119c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976cfc099da855617d28bf1513d6af852bbe836da2": "0x00e87648170000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a7c2054d39cb60856cf2180be68ce2265eaffe7": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894ff86d93a528d81402eb6b76cd270be3ec36c25a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fad872c4ab30f08252d2981056c5c5b2ed060000": "0x1efb42259f19cb4fd06aa4ceada857028a371af88868bd3bd88808ffc5a0747c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979303b03dc3aa29a78c0495513920fa310f9e561d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd46f947c425657f5c458d5718cf796b1b6b5c4606da1eab11a2e3b14a50baf2a": "0x00d97436259f34e11ee1a0be1e59a98a6c4ccdbc", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac878698356f130ce0ea0fec56bb0cded29f4fad": "0x00f0ac68935002000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7e9f6f76760ac65628e32e5a1db5d030f0623ab5108cf68ac23fa6732b47b032": "0xeaeccfcf272dee48fa3e4e783c6dea0fa1fc38cf", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928916621a778e3533c0219fa9db54f2d65c1ffd978f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd573535a40bb01903e616a383deed22b5e3ff30e552017d2395e3e75a8e78613": "0xc589611f018087385cbd3d91b8fedc67f2c9c795", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6ee274ce5c8a1dca1db4d84ac8e9d7164148b088247f6647596573a526843958": "0x967e82bac222eb299da4d0b3c47a4d2c69602fab", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a75b7cd418b3b3ee94b151aeab4947e7fc890fc5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e4c28c57507b59cf24b2649003b9f8b9e7980ae5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e73a25b58bf440d8ad53eb773f412a4e89e22719": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975e9ceb0d90f70a8911ee0c3b11f80a500767f21e": "0x00a452f2812100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a4aba3bac858eb8a53f6a3e3dfbd0a73a699d225": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1a8ff393032bfe3802d48f5ae53e9cad36830d2257e79b9acbefaf8f188e665a": "0x8b2e32fc97a28e0ebc5482e328a8f8de993650a6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f9e910a0736b49e13dc9c5d575af7dc0943c0e2": "0x004cb4d510fb4a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973257722a739a71c5bd42d8818a17faa4179385e5": "0x00d89708430800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c3a5ab4587b414dc754ec4c26105385a8cbff43": "0x0080c6a47e8d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894504eb623e2c8ae4e61ad147b13cf978aef376ee": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7c8c3a92d8feb9d27f32f3ec67bcc6792f8496f7ed86d1b249c54205a39ee30c": "0x41df190f54ac5d369149a92583cfc240154fa8f6", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516a0e16540cb923b4f189c46fef445c5710070000": "0xd0f33dbea6c78781e080606ecbee91c08daf0c684a8a11496d364f369e511b0f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8f13d654e51f66ed93335d573ab2da1cdaf832d": "0x001ab8ccb0b900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c0ab889aa9583f67dd90116710079d7d2d94f3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c62ad9fe1773e8163ddb765169ac188aea5b8403": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900361b7e4eb1e3af12bd13b2403fdad70b822268": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d4c5ecefdd2a070bd0caffceda6b50ca10d7fd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dcb926da7ff3bdd92ea659beea369ef286464e": "0x00741c17ecac00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519a55139d7061135a07579f2ef45a1a6500070000": "0xd662430013e36f7be38e1e1b58fa50bcd5b2ff6985db177978e2089d694fe11800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f963fef4235744c3cd26d5a3b155534f72ec6d23": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e56fb2b9754f5fc2e781634def3b45d8e0030000": "0xc01b6709d6c07ce5a82ce7b917ef8b19fc65646709877afd79ee810c24a08d0e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928999947c78186a7ebe1e620924ef0bc50721da4e28": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a92d58547d1c7a1f0f340e540267f278011ce0f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d68db02183e85ea761242a57f6d610fe20c59ea47e97794dcfdc7dea470670a55": "0xff45a27708c55e909009e59f1d53aad9b940e273", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289790a8706d0ae9782042de2a022125b746511047d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5124abbc0f6af3c645afa1a3f92e6969ee80010000": "0x169fef7931a98fdb221a745be8614283794ebf9123d4486a59e7673b86423f5b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339735c9070e864636da7462d5a6a59f81f7645e72e2": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928955ed1eae79078844675b794dee5902ab7304db79": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397669b996dfbf62da2ddf0c9ceeac503b920671639": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af5b50ce2aa522d8d9d6f06247ec7d877d0ea3aa": "0x00ba28a926e107000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d22e6e4560ba8144ea5c993aeabb32d8c9b69cbf13c26ad41e450d8d1a6426632": "0x4f7765e7ebfafb17ebd8da8a9422d5d1a9a4760f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774b9ee01ea740c5d61e3868dbfd5abe504269ae6": "0x00805ce547be00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515f2c1a093b75363938402045ebd1dfc007050000": "0xda91fe41a638929d565d92843dee98c6fc02f8bb7227939aab4accca69aa7b0800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289128bef3c7b002090dd018677f551a865595a19d1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899da50c01643c31e889bb2ff6c0ed168c8c22f98a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ac3947b090a8daa38eec83cd7bbc5dd49c0e5071": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928966e369a3a9c3678e3e4d05ef6a9886181c9a2c5b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970098b67b82c0be8d4cbdcaf68c96a1bce7bf61fa": "0x00b8ee71e14001000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289daefe0f07df89bd8236d1007e80f1914e2b85853": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289415ad707749eec89443896f6e55843a208e671e9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4397c030e61ce77f663d79186e3e1c86eaae6616e1695e0ee2ca87ef7e18d19a": "0xead61e3f92e933b8ce06bc76061f92455029fb34", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51545ffbd2434e362e8362f036ae5958c41a090000": "0x504bca16b59dfc6f9dce786197e6fcbb082a8cbb8b9c7fa9b541720ccf6adc0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928992ee94af3a409600eefbcd59bb63623a6280a13b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c17d9bb1ec5b9baa20b7d0b4d90aa5643ca1175c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7cf0679071a357a43da60fe7685f9d0314b704a6465af69c4ec86a310d2cad49": "0x6e4b9fc84af5b73f2d99d036273766f211d9d6b6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890532ce0c1d948b2e8317af8279e07561ee3a3979": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da2961c9a8ef0879e6f08c41d9a1957b7e5d7be02d2462557b1490609fdb5d02a": "0x2ed99752dabb3138a911c2b71c9a80c7fc917614", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5af6b59d2da9b4dbe2ce617dcae625a004b0607": "0x00c06e31d91001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f7f7e96799de9750a394f3d6310eedd09c31fb": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d1ba30cfd46c08cf699b00c705de01764689c272": "0x00d098d4af710000000000000000000007f7b70000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f360b24a530d29c96a26c2e34c0dabcab12639f4": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c03372f10f16d819de4d9b22f59caa35b91c0d": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893842775e7e6cba076c5f3d44f0fc444b93a1502b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892a57844f09543679d27a8f5ce1b6bf81bc14f021": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ebd4b8ed2ce27e41820169a6f89111436e1507": "0x0096e772550000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516c0a13ce72fc4a2b98d5618babc7d74948040000": "0x1ed877f9fb8eed0ada11b8f3562e73b807cf65754a073388fd7bae9104b59d0c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8a2086278ce66471ae2b31bccc818095eda142f95bb13339ce5e8fe7c4599618": "0x9193eaa11ee8101beb2f7c3c88a5df61a5114f98", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5175bb26335c9f83fbf1c45a84d16b869eb6040000": "0xc04e3158efca9c78e6610d1277c9bbef0ef1ad80896d4d8a4240c3eb5a2e170600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515591084a62d696fb628ec4aa3ec728d9b3020000": "0x0e60dc2e716e841366dd85abf1464d4d8a7e27a1a1bd4b7719f5c26877c52e3900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f92ba9453db2397461fd37fd06209e6d8f030000": "0xae3df6f5826c3b9d92ea03524f83fb4c7db52708b6c23e61843433506ce08e2300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899588686984edb566be1e1b5c367aabd49aaa5522": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928983d8e1a3d7f05fdc4f4a1a99d5a89bcc62324a04": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a2342e466f377fdf800a11c7affefc3e1b6e575": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005a1f98863767d7a9cb58dd848119874ebf099f": "0x009ea4c3e42800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fb82d696619496ad28d708285770225159e2236f": "0x001a5524560200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5168eaa000434ff0fd7c473c1dcb50c3d358070000": "0x5857a2b92920aeb74ab5f9ee71485235eb11e81979f0efcd45c4e6099f4e821200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890069b8480fc4275a0bc10a317a8687deb83ba972": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd8c7102e0d36e57f8df5a97e7ddf1d194903a45378036d95d25e7dfe9259847a": "0xe260e35f88bb3d71ff842178649c2817dbf50c04", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890006c9e7bec9d239b8b08a48c3c4a0ac7dfca848": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e4c51165f7f13ce32256492d88388901cf7e615f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975168b667344102495f2d51ac4e8de93e537403e1": "0x001ec02c1dfb4a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed2d649d7c8a8c8c62368e42c5717df2af5e1a33": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e69c4321926a7604508fcf837e03ea65d941ef8b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db6e1b1e9deea63d87810cc9d86bb759d26666a54086a9b650d91d95c59e3a8de": "0x6052ed2407cd5e04f17216d9687c289e325e14bb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f00eb46d1af27a6022117722fb36628a4fd16cc": "0x00561064306400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fba61ddba9f9e0b2a3e4d5b0f402284c00090000": "0x989af479f0457113b84f73d9c0bf4abcb2f273b8fcb944ae64141328db140e6800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513f05f9a27002a01c8b005dca6531a4845c070000": "0x2a38cf1b92fd5b83c387d7d0f6a05ea2fe915cf9f0e2557b3c7fbcad6cdcb83e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd44028df7e4094fe55acc1d3decd7b43349c968bece089408f40391002d66807": "0xe56be81797e2616b7d4c57c892dbecda35045fa1", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890032b7a3470928f2e782c4e4c636bb007631234b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897d2305280d7e05b1c3c5213fe4f626c9b5557af2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898212ec9b5cde7fd6a19690f889fc34d45d1db06d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f229ac4cc64385aa20b2cf7f75a9eba129b6711": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6cf513881f519aa8ffa7b6631e934e954afba13b14629e9683c20d697fbf5d5a": "0x9a597705df555e27d97c07b97e277d1169eba89e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfc5d04e7ff3965c8285a2c23aa573117deeed886bbe5e3be0974f1cf0a2ff216": "0x7abd31d835a1a6ae9d8912936e8b68f7fc89ee0a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890f7f54dc0421d8b06c07e3d872730fa111e1aa67": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a901cba20c6616581ae8df057838198b5b41f3": "0x00ceaeb81a1e05000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510627ec2ae9dedc86627a0f87fce5d9fc7a070000": "0x5ebf156bbed4f20662ecd3634c447e7f44873c8f660622490b044f93af2e544b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f735d737ce77eb036d353ef6dbd3a37fde010000": "0xc4852d47110a2efd4d38499db303859f407dc430027b7b7c582adc7d5b18754700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897e103f3df1e411be2cb88bd11e9c2e15c4e69394": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890017dd07201d4f2f7cf7b46d5b54f710ab579f4c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e3fa6cb97ab683b535d7937264e633b093000000": "0x4e58becd5f1b09ee3876eb448f6a9b7fd75740b0b1498a73d53ddcc094b6bd7900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514cb6904c53261f2264ed1b057a7d1fbc6c010000": "0x565518b05d731fc47de585ee3b3270c188bec481385e8abde5384c0d12dac97a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e925445ec68d6a9ce15567e1f769fd481ce9bae1": "0x002a07e4311300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ab1c9cc91d08f652158e554de079b1162f050000": "0x861e5108e876877f742bdeb0d90022549b70ecd31dec379b90d0489b33fb584e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892ac9bc183534b782d3f6042cc77b81cb4656bcf8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ff3bf82aaa27d245946571141b113cc4e6080000": "0x5cfa14f1be34d343b9e57e73ed8f76e09cda02868bb39e6f62f4eea00c031f4500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de648126c1f38e729968541f3a55390e13ebf3b076c8ea1509e378eec2594286d": "0x00fe4c20335a78abf60128c5f0a375a09d5b64e7", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e8a222bba2d0b96de1cc1ab1fb282c55bf060000": "0xe8a3132b1815c4668f541f5fc8271ffb50d0ddadb2ecd1f3e7a34d7ca37a3f7e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339743140ac2d3c02cba8e461602cc15c3889dd9fa3d": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002f331dd9949283c6f9f9b1833dfcdcba874740": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894bcc2b45c57fa511a18cf50b5d54cbba9aa6cfa9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006bc93719aef20a0258f9371a725b576c046148": "0x00da07bcc67c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977cca361415fbf12722397c47e063a4952ad65bc0": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519089ae5fd9369f62d984fe4a1afe545fe1060000": "0x16f74c762a21dcc935462cb83092a8dca9762672aa22dd479db60408d747142000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289828912ebbc7be3ceb23de58fcf221f171b31c88d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a5b47f605e7f1a0cfa91371ea887111a13a90bef3ed321c1c821661ebd82679": "0x1fd593bd99ed831bb189c73ad7290501597199ac", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b4b2611b6a9433aa098aa0a026a1d99037710f66": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515cdfc00db1defef16f916a20fb87716c99040000": "0xf27ed3676d7baa6d7504e8e5714bc39eca954e71b466e5715e034f9152f5967100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517eaa62d434a114b6fbfc4e34d74a3da9e7050000": "0x1a952f5ea1b437ae5ea5b6b877340e776124812cf6c399d2fa07ed893fddf84f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b9b7ef4b7a727dae1735e3ce35827316135f3210": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510e708be37da36b128810e7357eec6a6e3f080000": "0x5d925ba5a234ee898fb4ec7e86b1427eca421788dc9caad1e7293611cdea300c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899704593a5983b6b3e498b644802337974a2d0c3c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c2c2c26961e5560081003bb157549916b21744db": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dde566e4f0d29c4bfeeb3d23a0a9f923fe62d7fc5bdf8c9afd75506bc8fe69a0e": "0x004f8b0da646a07903c9d2fdbd90579b142fe435", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c687a26242033da5caffa1ef62a293c930a3dc": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b59ac37bc3e2ae0f9d32b6751e516eccb38732": "0x0080ea33341900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dec082e185832750e0fd4ed4c5011b37db13eafbae70ce18f0bb093efe8ca7125": "0x663e2ead665b23089266bed606d492ddfafa5ff7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928920766f01d859f1ee11e14428d9fb96bb1ebad946": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e3aeda1fec9c6242efa7ffc383b897f0e06d85": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c69c3cfceace9836d63b90c6bcd9ed4e479dc871": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d5fa99dbaae82b30e809eeccbfe8bcbe0e83f241": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002afcb6eb1d06a5f5f26360f72d777b2942c4f2": "0x009a073acd5b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289deee4f9f7c3af2f271f030229d3af254f2bdb0c9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa339be97e8b33e2eaa4bd2ae50e48d238882841f2a1caf34da47b0218804434": "0x60984850ffe55a4c330723b7b439f70e6184bcc3", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51540e64603f8048bdb50c600925ce27abb9040000": "0x6eb0649daef06ef9c43deaa38b2e6d867ab9e44480d4a30f1f3d364e7aff932900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895448b9defbabba9c0d81faeac87be5b4f01d4fb8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005ea02626ac9c77dad4f5b7601d99c54e112157": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f68ff9a1cb4aeb9018a8671087fcc6155bef517b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f67932ecb94e1429c330d71258165fc877080000": "0x98b995d8a902881fcb8891ebe35d50318453a0fd745232ff11e8cbcd5b11b70000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5177d39841e41d2895c7f8d8efaa77761610090000": "0x149528821a9e955805a4e10b49ef3ab68b0adcf7388bd60202f441b121d92b3600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700de5d8e1837eca3e4241011b7e6ae4c090d9f9e": "0x00b2e809461000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a55e8d42c5212d555acc4c1756744ab91530dbad": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928999faf90716291c57b7958f26bc0268b837ef2418": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a029dda3fe3b92411f2665465af3a3f302060000": "0x30e781c192463969c3ce7dc64ae7db4427334cf542998ee6e8bc8fdb83168f5e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c29914ed1b4ae2981825eeb257a58d4937030000": "0x6a605250d5a59894de282fde4fe4c46312b9ad3962438017b6d896a3e93e0d7200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5103d13f82e9e7269c776186a1585a381a6e060000": "0xa4d723984b6656d3c74af107267ef2f8177a8621516544ea3025f52a3feab61900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5647a240f4d349175675f16c74a964e387b5d8af5053d29a9c4b20cbc457086d": "0xfb2815ace3d144b7381e2364e799abed8c0d6ec1", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cce4010299a3f49e6530c55e063174aa2a060000": "0x4ce971552082e64ecea872da2bb4ecf8549d2760947c952722e8d8684dcd605e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9212c23e56838d5813efaec0b256040ba31348213b5d9001c95643164f02486f": "0x32878ea4b480bcc29e7404128a116c75278b80c8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003c6df13f3c95f12e0f3e2c82e3980d9732558b": "0x00b02bfd644301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722128818393800d4123cbb9b81740db04f380977": "0x00d46ab4a84f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5199d087f66997044ce1100e3466769f66eb040000": "0x0ca0db0283dbf8d123602a2ec334ab5c3fd9e2540577e0955eaec679cefa4f0a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282430b7866698f9b8920bef90aa5e16a0bbb238343d0": "0x0040b10baf682c000000000000000000cc7edc4700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d38e7887c528f5b54f12d9c9ebf7731d89c84622e02a8139059f3af6e4ba64521": "0xc83f97b509306d26b9a7dc44993e2d82f73a049c", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d462b54f04a4e212e9f2f1735957fb753295b120e212052c7386b6f674dc5af4d": "0xb55cb6edcc8c9cca3b659007d1abec171bf75ea4", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51329d9c9dc16c10d0faafb34ca1122f465a060000": "0x928b092428cad53613dd8b953f1b3c942c38637c01a34f6481717b2d1b2c174c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c94565b1d83230d62649ffe8fef08c755251853": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b74cdac11f1d6845bf60e28d787eb4413f804f31": "0x00005278b9bdb8000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891bbd9ddc49fd2d67462d0b1919151ec9aa45fc4b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f57c911367700dc2b5d847ffb0849293ba5af025": "0x00e8d992a10400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898761e0dd63d14cf566acf4b730f3540f164b6b56": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee58852b55610f513c694362070de7122a144b87": "0x00241c35eedb06000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898f7c2327fbd51bb8040c53fc64e3aa6df197c9c0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890019bd61d8a9591e1922a11b46063a887cdd935c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289610449b5f52ba2fd6a5cba5c29d650d12248017b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f760704253f15e9798783e695e6011893b38b549": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3032a878f698e0ce7cc3706da046062a0c10a30713345cfdba86ceb38d560e0d": "0x2576f5ef8309dbb23c39be29d62273b4c917d783", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979edf2a093bd2c6d0a7d44368480ce8fc34bcdd80": "0x005c0337b00e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d82dd64c4a66dbd2dc7ba864df36c11af0d44120713270c85ef0b5dd38f5b9b21": "0xf9c1f8b4234b1d9b714c018fe96afaa186d841a7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6bddeffe26cd501deca6569ef33870f15aeb637": "0x00408ab5c74301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339715245f6c73bdddef958c94650431c4c2330d4faa": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c19f28184295a37171703d21b242216a1b10ba3c": "0x0018f5b0d95800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928925b584e9363f10433b2b033e3a9f0d207235c89c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970710c910d3d8061019f91bb90ccdf607898e135e": "0x001ab8ccb0b900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890967e2492eb0f8a7bec3979df99088fad360d62f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004c8ab207f6e5e33d260559aff9cff4d803f4da": "0x007ef911b4c709000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928983b16a18f7fd937545ce0a72341bcc700bc72c69": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b53723ef104396f1f44a378a84a15067e11e166": "0x009a3f588a1b00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c5f64f4b694d7725a40979c22105c20532050000": "0xe071f2e75eedf15710e782320a18a5f76510b8d991c9f5f6054b99bf2610e73c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fba1a1a641591737a3ba3e7eb236d2cfafdeb69": "0x00aa3d8fc55b03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974af79369d49d03b92400c3b67a65b694044ead5a": "0x00203d88792d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c834fd44543334caa34c024436112b2f2d6721": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e18a7c74b913a4f28da74fe2c194ed4655d63e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b129e8f6a6e723e77313bf99718cdd640721d5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928948e8806eba183d1364c2acfca72280c95bb41ec3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5118d17b8de7d83791730190dc10f91fbe0a010000": "0x94a5e3cb03e089fd5d39f713036cdea09665ccac86ae2271fe1b18cb40a04f3600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519c0984338edddb16ee57c6a3c44bdec753060000": "0xd4b51c3fe940b0fd7dbeb9f6ab13292166e1deeeae43b8d5a632c6c331e3da6c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339757ba0396c511c6dde22e4c524c07b85411d6d05d": "0x00accd72818903000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dbda5deda828ffa3c15dc99cad296c5671181fd3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890027be158b9f1dc432577577d225f0520c309696": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397625181f151d0300b8a8ed7a5bf2779f939ecad4d": "0x00027454dd4d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009dd16c2560bd2907136d9569c32920e5f0ae05": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de0ac044eaf1755905c1b70d749a8412385612930a28d50f97ccdf2e5489b8e28": "0x05b30ed53364a95a0ac56b214077a85bd5992772", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899da6c5ebb2a225a395ee772d77ec5178fd5a6307": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517a815f1967a4e10d65046f23b643d6437d040000": "0xfc504c4be97bb6552ef8e0dd3646ae7273605c8282ec2ff1f086e4d7af536c2300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289862772a77f471da418313e3fb7680d570908b206": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d7b4f68efe1aee99bc58f9a511f43738fe5b0d": "0x0040f79c2d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928948e17a5cea6d3fb095b75fd94f36f6a902dd6702": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289888a870b0e77521b1121874499e934714af32f8b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f7f7e96799de9750a394f3d6310eedd09c31fb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d420c638c444c31f43e678d1f1565f1c40c3d2319de8096fd24ecde1be227ff24": "0xb78c8f3b56f2e4264792922e064afb51b37c4e58", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5148daaa7a229e9885636f16d4f6aef8db7e080000": "0x81d2a92dd5f2b6ffe5fec1e40595cfa0dd456ea74935fffab3e5dbcb2b14135200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970001e57b2199d16ae1aa1e5f4d24a83349ff6939": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700367f2a3dc2af6089b3d5c929f997655d7a9151": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c4363a5d67bed3671cecdb593609745882e913": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397461df0f49a1b5b38318c1cd425840986e15176f2": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900539df92b2c2e52a873c02479906672608fe563": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5117cfd54f660b517cc98cd3adb98d0176a5040000": "0x501bb225e3c5794bc5c96942847648613c63625ff3593b3901e903ba83c7d95700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee009a16375c624ebf875040a1c0c724667ee60e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005703ac09115ef8422705c86a94025182b20fb1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339782e2b7d189a81a251eaa51ac31871f8c4b91dff4": "0x00a2c66bc03201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397185d5cd827f66703890387d348a796cc8538d08e": "0x0040c1bda4a901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7ce447361509f0575a6a206888ea2afd88557e8": "0x008cc15e273d0d000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890012f59b4690aaaac5d4631d56f30e00383eb29c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890001376e9c388b5995e3a115f7d2813dacd35078": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c794e65e0fc0135082244e2105900e3177cfc5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518de6e8e8f3aea4024df0d297fe95eb32cd050000": "0x88bc66a4d38128c8dd29d60a4d333824baa33209272321aa212489ea2d19105a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b67a2bfea6579b273cfa427637adf9fab925f68a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000e8ad6492f516c942bef6561251b531fd7b10c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289960cbcac0d20353c14c5a4392af3b80b3f962eef": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897cb45acd0b8a871f396b319e5549bcd36a047533": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c8f9a7246af6650f96401dbbee0c30e5f913cf54": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339752e0bb68c4b18ad158ac8e9489378e5e855224f8": "0x00e24758b00900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f72fce633c6ff04e9d82d01a79cf7c4e3a54eecb": "0x00e09358064402000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fcdb795c73962290ed72e9e9e250f39f331fa6e0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a5e5e5f1350b92dd9bedcb9b840032fc728dac": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fbce25b75b05e04b9f22e60721aaea19e87e92": "0x003c34d961c502000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289540f856a7ebd537891067c98e61d70d235257e5d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ce8a0915d27d4d3295e8b67c593d3423f371ce7d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970062e7f8465aaec10bc526bf5bf01443b0e450e7": "0x00b267417fa700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900556f5ccd2cd28ee1f82cb391636d9961cfb1bf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978300b3ecdbea1e3dd2d028f566ecd7d04627a3ee": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890312116a083d27cfbaf9441b576f3ea63d968967": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db640c8c456f0757ff52f051ffb503c6611e8d7c24c520d9be406c9a735878945": "0x37977eaf6917d93704a3283bfe16d87aa5eb0717", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514baf2ed54403920027e405200f591e2494050000": "0x84769386be549c14827cecb1b29051855410397dc53ac9a6c38917878db7057700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514717206d3c225ec0b0e41d3f769bd7c283080000": "0x0ad57cf7ec770f7d356b96e7b5abed7e10fed2c60c21cd43a558ccd33ceed9cd00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aeb41235f3375e4a0c3006882b6ae446a4818753": "0x007a2bf7de5731000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001ff7e32cfd40f06e0d9f60f60eac6bef113f41": "0x00a843143e4d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d56d15a35cf075ed48f31269e6431d2891da8c1305cb520bfbfb60493e9ef026e": "0x005e42814cdf3db319923b257a0e0a48e3ee5350", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f1d5ca8c8cf354b8d5ee91f6ed61f20059ba4beb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d18857b6eb8e9baf2c7b1914ffb45ae7c73d017d0d0bfd0ed7155a7c8f6c0511b": "0x762a1795292a3d9355aeea85e4b174e9bd8cc3cd", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001ed2471e25c381b3c24895fceb399dbb4f319d": "0x00ca752c232500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aca3500b68da8eb37f45381fa3a0c7f815e8f5a7": "0x00f4989f331800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d083cc8444e66f2751a2d725275690c48a2ecef4f5bc519738cec602aa5dfe451": "0x27fad8fa4f7ab0d981f0a5635cce2895f786e59a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd22ff2d97e949911807c2f142d609ae40522cea": "0x000a78cce22300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c885efcdc3b5c736b0407b0e402b5b842c81367f": "0x00828a13987702000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899505ea825ca9bc29d21446a6584c6771b21f193c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513feb73161582f3bf7a52fbe4c71aa0a1de050000": "0x3223bf5cc2f5be39a507a92ace7e924cc07bfb43bcb61aeb55e09fb63affd53f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282430088f9993ebf41b1009dc7b17a4a01ae47bbfbc5": "0x0000c52ebca2b100000000000000000030fb711f01000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002e2b254a4e3877c6ffc42106cb4f519e6ac27a": "0x00aa8e680e0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898f656b95dd71863355bd5aefb313a06590eb921a": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009bdf8ded35fd7e2b8f649a808323978569e05a": "0x0068520ec50d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd6c0fcf38a991d9c95d2e379f4f234807bcbeba": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7c14ce5e6afa3158feb921d32d89d236e26b9485bcb995402108495a7574f547": "0xbeb910ae193dc54411747ac236e67d221ff3f1d7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928931d04a32f22022ec66afe6c2351db768ed32b873": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d2c56fc0046932d4aa37cfecef3a47d143722518": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000bc706ebecb19e4c334a8e8e9becef6e58a2f0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928939db9ac590a3fc2ef947f0deb09b400f891769c3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b26c71b5246b3d118411f74cfdaaefcfc07645f1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514eaafeffe022fac614c984da7c4a4dd931070000": "0xf1c7807add4fbf549db8d37e8279efac27bd1478a333e4c9bc10c80cdafc9e9000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df6cee83fe99a1a53a1296c5a478df2a8e62a00db5f412735d925c080dc588515": "0xcc674a3c614e1c49a0389b3797ca27f30a5dc78d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ec50c43867523234d23f0238a29f3e0df59e7b4f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bd8c7d349edac2387a40066aa52cffbf41090000": "0x5a0669f20ddc7e3feea1e2df54372a8776fc42e4b1997f3f95fac2a962f3367b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c43bb13f32b49aa921797bd8a391866cfd3ac6d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d245558c69f4ef719bafc87b4f554cb0b73499b32582f54846a05f7effda32c2b": "0xea53530092af66d4706fb53e7891d2b1ef730b31", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d06350b5634bf72fbb66298b193fce9a5acbfb564712cc3594a39dc051a039850": "0x8f656b95dd71863355bd5aefb313a06590eb921a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928998d13c1d3fb4621065d79a06a17a0621daa314ee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898a21429126894675cf6e76bdee44a18c6122c0ca": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dbb8868fa368ec46f1961ddb5ad9f01cb770424b": "0x000aa1d3ec1f01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d0a1bc938a1fb74eec812b7d0c4d3e6328010000": "0xe827d83f5b7fa514c856ca4157b894148a5a2d7e05265b449422f88213d9ea4f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700af0c8544bbbe405642a32b0aa5758fe489e37b": "0x0056b961800900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ebb3b5365f80f437d4be00fffaedec844b24ce14": "0x0066c2f4a31b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896a8666af2e42ebaae251383d5d96bfe80e41b4e2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c1c3992737f0ed1cb650835f6ae4d44763cccd0": "0x0010f5d92d5c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895d5c3f6832e88fd28cf40a1f25684b7ff99a66a5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0e0b97949687e5cdc9ca843c0428bd0437e176d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289546d80fbdadde160e5d4a3482bbdbf310163192c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d68b849aada5aea5d27bb322b8dff4b540cdd4e52d9c32aae3db8a6a9afb43d52": "0x93c419191cbbef6717b1992a1f854ab2d90aa7ba", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975937c41f80fc6111e6703873f89270c60fe559a0": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928967e3653e795000b68a3b2f763f628483e21c96bd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e3110f4e11c5b4efd2ea579663b23907c98e13f9": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bb74b61eb261cd52af172df59ef39a45fe060000": "0x2cc16da9d1f7271475075aa8eb5c6667714426b8c41dbecf92bdedfa462b716300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890081ba2106e5e4a6ca54e9dab7ce93d6f95c095b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890059314f3708129bba2e5370209f0e54da9bd354": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289932b0f9fcf70fbf60f6ac1b4db3f74593d1969be": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b01461ad0d7176bfc2f367039bacee6a31050000": "0x58cbb85bc4457b36fe8a2b28cfa63f0dd44bb00745db796b84e2699c4a9a007100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c5d2111b3445cbf18bfa5709ddca8d4757c8155": "0x0092e5b6521500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928928ddb52172f1e4b268415b84edc45316bea434d5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ac0f75d0d139301dd8d666526b02234220b14a": "0x002484462f7d00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510c5645e0f29a4278d896359c0979629fa9040000": "0x20e0a7b8b478d267fed40ccc4a53315eb9dda9e258c6cd12befa4ce2039b707f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ae92580ffe442350bfefc4c9e4fd5b137a0fc9": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e499dde041fdfd3cf0251a08b7ba8582088870": "0x007e33be071500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ff82054932bb21f78c58582390d34e16a479294": "0x003084f17c4b00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ea54d42ec8594576300d7c3feb8534448a040000": "0x8e5c313c4964fbbf1876c174b86f7d030ae001f67249ef7122bafc679cd07e1c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dc26b2ce9c7de60d60c165f8c70ba7f8b08286aa": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970887159799951fa038ecd71dd8335d2c19d14d29": "0x003a970f2d5f06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397deee4f9f7c3af2f271f030229d3af254f2bdb0c9": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289328e1f8f95476bc8e2df5911cdb36d311c57aa06": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928930d6d9ce640c97def75838cde7f753bf7f161403": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e596919783fa9da0f9a813b029fb5f3473440b": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d12d777258efa6c17819186568ee99a5bafd6d2ab4f707ebe15d843756ef4c077": "0xb7687a5a3e7b49522705833bf7d5baf18aabdd2d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289275b51c1557dec3d252df5984bd2ce9e1f7429ad": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc12728eae828a7eb29d712c04ae95e3dfeaf32e": "0x001230d9ff0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd6f274e764d8329ffc4d8c1178cb04f473819ce3c0e420e03aa77d679a43d03c": "0x8588ebee2efaafca8642783fe8bede2d9857fd68", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894c490375c379dbf184757b100561207f8ab1938e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894fe992e566f8a28248acc4cb401b7ffd7df959b0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970db44731b34934498c4853216a0e08c8d05fcb3e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d102ecd1c98119bb49b5fdcdde4160e597892cb30aa1aa3a40dafe3717e59a74a": "0xee1301ee318ac92f4ae4254263da4325640a97a2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ebedde101b40b694e2e90043403c1aeaf6e7140e": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511e3ea618901e9f415c64d2128fb5a4defc060000": "0x0673ad71d66accc24a6f3635b26852ea24bbe2762d966f4335aafb505920d75e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f8d9661e088fb7fd2de78aec0393b660b7040000": "0xfa68c92bfdbd08a08d4cf5995379e28d3ac042b814a7bb2a1e2095d5e27cec7b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5185b948501521d150005d4a66568283b695050000": "0x7a4f4bd2ebfde2b52565fcf21498d1fed82347dbe23c16cc499fa3e19401655800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a44cea029eaca82db52bbafc8ad32db502080000": "0x204afa2bbb11abce235187463313f068329f58a7a8fe132cf04400fb3cdc092b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b043ebcca29d4a6c8ba1dfdb75fedad3dac2a5f6": "0x00203d88792d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ebe4fd701cce5d001c481f5662d1e941371c49f2": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006860119dc98195115d8bfd4011eea31214f028": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516a3c58d1016ae874d5dc50d8a008be2a77040000": "0x3a152213a76fcf28db0993669126eb2a16f9ce070778de9d5f3784ac2cac341200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289139369f83fcbb405f405796c3f2589bf9a9a882d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289121231fa85c0453947732b1e902dfafa04c71563": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775f555adde5385aa0b852e0c551f3aa47715f593": "0x003ab9a30d2400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009840b0386d229b17d0c230dc03fe8a77a99b2e": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289144da3f7abbb9a22238f2258d13d238a9149dbb4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d102007852fb6304637ad44457b9bf42be382b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df27ed3676d7baa6d7504e8e5714bc39eca954e71b466e5715e034f9152f59671": "0x1ab980e9f3b036a21ad11568aa020f6ffb407067", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243eec5230343cb5336cd6e3a8cb29e5e267d6d5b21": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c50ea337609096cd614dc0752ed130e0de08757": "0x0030b795620700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005b2192a3fc9f380351b5931adffd50a3614731": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928902351fba2d7d4e88f690bad6feb6f93d0dff6906": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894cb26d4abc32e99e107f1cfed2b07bbadd425b79": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895e9ceb0d90f70a8911ee0c3b11f80a500767f21e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895eeaeef816f1015b042f74c42d8d3ee153c2cfde": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fe383db1da47144fb59082c47d97ffb1848d13": "0x00883676c80200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513c8914b059f9bf86506c5aa98938e0c448010000": "0xf264f0bf05eb6609b213f83c4546f0f196f62e0917699e517903e6ae7be5735e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339741f2f7387969ac7c06fa49a29fc479c22a9ec8e6": "0x004e23271ac505000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f73226e1933cfd506c16b06b172e564bece222d7": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f619a00f641e82037048c9d0cd20f9b64c664fc0": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddecf71909282816105360e12c52694c8e39f30f82532be18b3e32e3e435dbf08": "0x03fcec3a20f276aac1f7967a461301d75180371a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928977603bf4ae686fae678f2b2591a3487dc68599b5": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbefddfbfcbd24527d9318e17879559ff9ccfd74181722e017ff693ec92aa1042": "0x27d8519774c77bab85031463f236c702c7ee8bd7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339763c4681b602b2f61bbb65ddfdb7a3a339e527109": "0x004072e62d2d07000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928947e90830e0665a6935ef79a72a27db6c23e00228": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513d457f87092a1efeda070d2e2daabfe4c2050000": "0x729fab2b0a01ff5d67532d4632d22c6e4889a076f88a57dea33a675381cf7b3800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339717d6baf59972f76f96eded80604af2a5820fcbc9": "0x000cf723526800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b20a9355f834dc352aad5ab9bb4edef1d45a37ed": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c834fd44543334caa34c024436112b2f2d6721": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7438a2461c64335a5c736b31be6a2506be76d10": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d59dac3bcb670d0ed0c737ab8f2560ce0e564e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ce6c2909b2bbe2f6a5bb8df2f37568668d22663": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009580bb9bb318dac9a5b0b3607491c858c45aed": "0x006e358c46ac00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d04f320fad7173da9ae78391b0d5322fef4fea16922a97a699fdcd83dc5ad9c49": "0x21ef1af339cb2c91e55acbb82863552803e1fc55", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514086dbe3c2a278309a4f5cef671519d7b8040000": "0xdad463ee00bc9a0e288a87bf7f80ba96ae2bd082d49beeb7467c40eaf153f00d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000989f1b22b2b2ce40d680a388f9033bc8fa704": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b5d47ed8c07fe4d9a143fddf967ca8d66562beb3": "0x00e67bd81d1b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6a2484979a9f60423218a17095a44c4db2f17f2db386017faa64bd92724a1e7d": "0xaf7c56140a7017ea7fa9fccae6341dcf50ba0556", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d74e407185cbb9a15657307dd6f0f589b1a275cbdc4f31578ce7abae1c8470e37": "0x49818d5fe1387b70b4b7bf57a64f7c86bbd15ae2", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a3437295823c66aa4e245297ed78ef52fa6c71": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339719527a176a9634ef8b83e25bc0fdd90533e0a966": "0x00c8bab0cf2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5131eb0541f34fc4e805e66da5f7e77c5616070000": "0x6e7bb138941680a1cfbe21e2cd8452babb9cb2648b3593379afeca1a8785892400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973955e672f3306fd39545edb3d7040cf8de2f9180": "0x00deb7eff01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b0198e1f457b40b590e532237ed88e5ee52dc8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705b30ed53364a95a0ac56b214077a85bd5992772": "0x00001c0611c813000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282437b9be8a12f0bb04e290a6727e57dd34757b776d6": "0x00a0d885573416000000000000000000663fee2300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970035b3ad14d644a13c32441d55dd13f846aa76c3": "0x005c3dd1035f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3b20eee7cd3801a6408ff4c6f73a75556da2a1d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4468c8fd916e17f85b6e76e320e631712eb8312": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282432b98fadb1f1143a50c58954b92c83800d2f23c1d": "0x0060adfb90c801000000000000000000a2cde20200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dc0fbb0d3eb93773ccc744fe13c0beb2820a9e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289caff66193c177e60ef230f8c45a5867ca46f578d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ab9b7cd7311c80902b85d9536531efacf92085": "0x00c48d929a3500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243328752def488a9c3aa9e89edfb56cd7b4b56f7c0": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899b300a2c7b89455cd5f3b4d3a998afd356165607": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfe7f59743f2e3b19178dd8d7eebdd926f541752e408ea28d769f5897239b255b": "0x7967c0ec1b8b1bb821c84551ca7c9fd49c720a9d", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824355479b40703db085c9abeee0d45fef0c61b0098d": "0x0080dd62b221020000000000000000002208730300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e0252904378f658092e394f8e8a066e29a060000": "0xe679bd5e3d1d3bf6e8a515cca2afc8e5bf5d25aeeda6851134357d1c69070b2b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee0a93db77fb6741be11c337e2edfe00233b0c19": "0x0084449cfc2f00000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d3dcce592e72f9de4f14f72c699145950c7f2889": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c25f885b631247a34d1429b3f43d7bb2639a7e3b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513f3375b56279046eeac29f9f625ac11cb3080000": "0x109a7113c1d9b145d8af5be42af278d4eb46caaed127c698070b1302fcc4c80c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e33c5c1f3a42e74eb61862584b27454a9a44a06": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a75b7cd418b3b3ee94b151aeab4947e7fc890fc5": "0x00e077afb64b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b48eaf22121c5090df38caa3150be0872b9de6ce": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890067fe87b5fbabca1cbf1971d25f26162cb2d060": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892c335498511b633e6c7c582d837735dc1ed628f8": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6adaad6649b233917f6b7c5f5ab20c229b2b2520fd85ea21cbc2510eb5c40a52": "0x2b98fadb1f1143a50c58954b92c83800d2f23c1d", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824308c204dc28bcd0c991b903bfed4eb5309d1053ee": "0x00205a4ea6ea0000000000000000000023b47b0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898919f90098e7976078c2ca828b6af4fdc3ab9052": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006cb4d719cad2ba7ac9cae5520378b76fcbaf1a": "0x005037a4f80800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5131ce5ae5cb00c612c1df1a2313c6edb01d080000": "0xc692c0ca48ca508dfe638774741a1f049f03f7799fffcf84c804d7f2a264510800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3fe95f3b54dcb987f29f3de7c979a88e9a8ab6a45c47f0c32f2cf14fc1d273f0": "0xa7917ca8ca77855eb657fb414a3736204e4e3cca", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5179a4338e696809f2798d4bca0c16280455040000": "0xeac2b6fb8a0391cdc0b02ebf3cb87a81e4bea950d63b3ccc5b13cbbbac39226100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51df6f1571bb90aee106760aa25c81121afa040000": "0xb6ce2b0af9df0b5485dac8eacce7f147efd70bb39f181a67e5f049f8ae6f4f2700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289164d92a6126ebf0f354fa098e173f1a50277fdd2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009840b0386d229b17d0c230dc03fe8a77a99b2e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891eb95275df958625d6ee8a7da99eea9fff12127f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a1f26b375e08d87252b12ede342a0f5062802fb2f5aa45f1fd87e50ce686455": "0x0002ec0da4bfd7e9b5cfdcef93f8a02d4b271aba", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2c59026a5b96292f0ef483d5604bf90dd067ab2e442adc25767091806dde5775": "0x0085a7ee9578243c26fa140b97bf771178297a3b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dec7861534b86faa8f8ae36a561fae5277da4709": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289206c99512d5e7bbfb0d430813e23b7b9dc1b41be": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a7d341dec7a554c2f7117527a1514f34ead904b6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7ae802beabf67df0788ff71dbe81741b307e187423abc0a709d73f2997a85226": "0x10fa75506994a9d1a03fb01abb31135d662a7086", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a1a27dc484f0411fa9787e137d350b249a0cd8c6": "0x008062175ed15800000000000000000098fdb88f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51239f525c108b56a9e2baf098dc7fd74915070000": "0x60dab79d7d7d4e55174c0e747736025fb57423e997131daffb65509d9814ef1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970002ec0da4bfd7e9b5cfdcef93f8a02d4b271aba": "0x002e79c7b73c01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513e6aea807d63a67fb0f6c7d0b65ce496c6070000": "0xcc09076d5cbf29fd82ed31be066e2909af4f7af62d3b34007383e60211d4c10000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c186dbc2c878448f2fb2969967abcd307d98c247": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f619a00f641e82037048c9d0cd20f9b64c664fc0": "0x0090dd1e04f100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c6f2faaa16c7641c1adff6944452976ca1504976": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700290671c99ac34bc7c8254033de25a938d4fafb": "0x00e23c551e1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d0380d16422278eaf980fcb91502a4cfd23d46": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928942d75f75d1aaf59304642bd7530e5de5a42d8fba": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928973a4bf5507f57385118846444b38bc10eedb7fa7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2ac3cd2c26629ff98575e00f181f83a9fe5e801988868fc22ab8d911c7a56d56": "0xa22438f8c8ba4f08a9a3c857b2687cc1a890ee30", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890fdf6c80ed447a4b0692af53a1acbb7df7bf983d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928968f67e0a9c4a93ea99f820c1b4fb86dad5a27883": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397523a99d1767f000e1e77ee5a4fe0bc6cf264a1b1": "0x00b0631b220301000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928978cc3793d423ccb41bf53b2659d49a6c42ca3fdf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c638efea44e5b7898f33a7ac1773f4b7deb3631": "0x00c0e6de6e9c00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51406ea1eecd2aaf189c28a4f5e66619288e040000": "0xd834724ac202075b2125e21c88829469c79745d3615dad5ecfbc96c2b651ad1700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928920275e007f9678e47a9f3c52ea85d68c24217a65": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897851079f455f5dae12a4f668b983908dbf98e56e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002fa17657a9c0e03b1b0c3d833b200a013dff47": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900adae7292b68d8d92ded17f5c4f606bb90f6f5c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c673e696e12296fd3f52e0f6e354039467b518": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d8bd56a9cb0b6a854305830f3f8269a9e5e705": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b4c4dc1fb222bae0e04fd8cd23f78b37bb39c17d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007fd348bf472eaaf68e58f652c082b86813bdca": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397116812f3295d2754012b63805ca7f89226115950": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3297a3b21fe2d3c8a89bfaabaa0f2e059a3d94577a04d961a557c2d25a3e5736": "0x005b75905e8b686acbe0365d46ba0ac2a70b3160", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f813b5cf2750a59a45f3c5e50397d6ac02b64f9": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b20a9355f834dc352aad5ab9bb4edef1d45a37ed": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda3e9e776eb3b7e775e51e6e91ce0bbc70c15bb47a87c639a3a37b64db46a046": "0xa7455f18d8399830baad97632cda0a9cc2008f66", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700878eea2b606244d21b41565ebdc18bc324d38e": "0x0090f5e41d0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f6550e2abcd33b14be0768e4fa62c66fcbf665f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282433e386f707569dfdea7210b53bf3e03f6d24ee073": "0x00407a10f35a00000000000000000000062c930000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971dc59612f191c66e69dc23f3ab00b945593836e9": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339728ddb52172f1e4b268415b84edc45316bea434d5": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898c4a8da8157683e753d28767849df4e6d216c079": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a42264114e13a067ac2baca439e9ec5df20c8819": "0x00c029f73d540500000000000000000056949f0800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511897839ee353b541f7442b09cbcabac458060000": "0xe218d439c40293656ad41f042840106973655483a4e3481535b798cebfc46d5200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d46847f68e28bd9107279ca1a70ef05f942036e3216d4a47a88361e563b2a5920": "0x007ed64ac2fe49e1bcb932151e72de0ca813ecf8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ee3a5ae8aa8909d1759cd909d15a646ba94a025": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b4bfe7e67030cd1da33c01c06256038d4713a5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750633256a5f5a0a59ebb7c37a29efb44f0c21e8c": "0x0086ef35191300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008792aa9191cb0bf670babdaab314c232435152": "0x00ee853eab0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001e0d294383d5b4136476648acc8d04a6461ae3": "0x00a4d3b34b1f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397283adfa795ede051c814731721c14b6c1dc3e2cf": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcc614406d9612fa12c9384213e4e4203287d777a602a84c931240fd8c2aa3753": "0xe6c6c739e406cf3ccb1c666d24cfd200585faafe", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8e11401fdf86813483585117c55a6a912ab954917e64d3e70efeb25e18901c5e": "0xc68b2706d13f729df4eb2ab8edf4f2d59e037803", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007ad88b72dc1cf54adf012caf81e3db579bf04e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512a9061438c6db60e4ae98c538e3c01fe0a080000": "0x5ca2f86b5a4cc1d1f4c1c043cebda2d4ecb3f3d9057d9948cf2509dc6766315900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705c94ef9192ca1b80c427a749771cde2e0f7dc53": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339715510ab37ed950371ec9ddd5635fb5d1419ba3f9": "0x00fc7e05c71200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c84bb367c7efdfa0490412a91a1e4ac7a613510d": "0x006aedf4123200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51009404c9922aa254ae3e28cda4d8d01efb050000": "0x7c3c0e9543220809e9207ece95c504006574f50c42361068e846dc51f7e44c7100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b4f630ce350efe5e1171e7310bfb519b33cbdb": "0x00d815f9b05805000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e51231daa306acf16eac34a864564ca36b262a1f": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890c45559a7a79bd667e9dcbd6dfdbf09ae8ba497f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c330c1abd1fa488ffce0ddc6527afc4106f122bf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748d28e8123451e65d0b54aaccbf5f13fe4d3a162": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d315959e879d36d314c19ccf6654dce6b7255fb4": "0x00987756112e00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511c10b0785fa4cdcde17109e5c60fea4945090000": "0xee0874d09c3b5d554cc991a98bb9e1f7287671660fd542d7796ace33dc7c750200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d94d6b2fffc1abde3f0d4b8098ffcf92d71ef84f2439990b8eb9486c2a0077552": "0x70d394f0974b088f02599badc4b1df6e7fe52d09", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890045fa890802d3a2b2a1c7fb78859017786a9fad": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e1ddb8c1e2204a92febaa4dc7242590cb74359f1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928963c62d874ed1c6fb31ecf56529892875ac6b467b": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a61258bf9cb93b77da65701e212c4f1653abf9c": "0x00044c60f84101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1347203b8093b7ad0f21f821e7d53f841b25892": "0x004a61a31c5e04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005cb064be2ae806ff8a6eeba102978d6b32d625": "0x00204a736c3d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e8ff247832dc7f7d5163f2623869d3dd3c36b56b": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d7ff0231086abe3e95ce3773d60a39bf27321ee2": "0x0040c7c59dd20300000000000000000000922f0600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707dc1a136ca9cfa640962ec0a9a8332f99b0bbff": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339741a7300cfe3e58c2a2c248b3f55228122961b132": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fc27d391ed66cd60f72ce19ccc99abb67a57ee": "0x00189c2b960200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f7a3bb54858fdc941a3be7418e1026dcfdf65d": "0x000a56a64f7b01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510ae272e5e8a78fbc45f5971bbea7442bbd060000": "0x7225bf2a5f6b10dea716b22a85f6f1fe23fb44d555f435e7e8e31d13f825c53600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de204497afb88b9af744c7d7b0cb10516cf0750aba8ef1989cdd0c511b9c15c6e": "0x5cd12fb4761f91f6a2bd4240c73e7d8fc8a3f638", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970036725f3317d37d0b948a2593892bd5c186b98e": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397271b8269e278d8a2ab0113de746c1b1136b320cc": "0x00ea9551ba1f04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ad04210ddb16c4b66644eda430918fd5826ca17": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778402f084d2219d4844e5446ce4e67fba23b9d1e": "0x00e6e02b77bc01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002bbfd34859c09b36b907c0bf0f3bd0046709c1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972317fedd4b4af7c3b6fd14cd044a2acc92ff15a0": "0x00b4d919c66400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd62f37fe5de823d66a120bd90a86e7be43c372a5eb9b487d702a8459203bec10": "0xb7f164ab2ee6bc8581a0d06bfae3fb98e258b265", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4ba1c4ac566a049429432cc11f4724a4e394538": "0x0080525d633f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df032c776601ba298d9b688400db9bcd08ccd6a42cbea068369de450076cdbd56": "0x27efade55131916b2f0a34e313d858bd6a30cf4b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928958ccfa1c26b8a49b83ffc4bd2804fdc5191bc28a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893716046b0394219102f5c2cdfd234312c0cb59a2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6cecea2c48271687c926a72814cfccede993dad2b803ec0d546d2bafa586c11d": "0xbc493b051f40fb47625edb508d1a43509ef0e3a6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397185a7fc4ace368d233e620b2a45935661292bdf2": "0x008cde7f2d6906000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977eb9c6574928e51488595ce200904de622a212ec": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900002f21194993a750972574e2d82ce8c95078a6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e79aa58c609548a02ddfe3e79ee12a11da33e242ecbd879e1dbe389f6ee5a75": "0xfe7c8c647c3574eb9931d1d3f36019b6a6d06e2f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004db71babc8ba9aef9c02bc96ae2c4daa74db15": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289805cbf1fae3e810ed0cece7016848a677cce945b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339762a98395a16d0050d55a4c575daf1048bc9cb023": "0x0052007fef2000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928915510ab37ed950371ec9ddd5635fb5d1419ba3f9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900abcc8bd0d281984f9234065c889396c7e3244e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289643ee88f0cc3872eb8d2092d43c3220e35427653": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896ea0f4b12d694e26a89872bcb86213a8f6ae25c5": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dee540d3a73580cf5e0ae2d80ac9d98dc27847f5518d62b652a6561d46c16b553": "0x4f9623e0605ed7294195c72779b378b442834633", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928967af2e44d9eb9eccddfc05163361f6eb5fd89629": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cd2d4d9f76f3919510de38109dd63172b05e86a6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f2d2b848ede60d9480631fe6a365cbc8e304c14": "0x00ec4622388506000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bda832c615d83444efecd879827c588b9b000000": "0x9ee708bbdb68556d834835ba8214cdb27197d54f6d0fb26107006cd5754b495100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f548b1c7499a85e9574fa5845d0308efc39d19bd": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e47494379c1d48ee73454c251a6395fdd4f9eb43": "0x0074efedc60d02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f9d17d432948ac1a523ae7d1a16e18903705f0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897eced1aea8a70ed73f12f0550ff58671ec34953a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738db95df5bffa0bd5e39c27866f7d53e04c2f87c": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740f264c803b913ce7769ab4319b371b95a072103": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c5137df3f8f85e7b8d1f5059045ed0639db413": "0x00d4e9d4ccdf24000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516dbef88b3fc63341b8a50cb1da35e8fc15080000": "0xa8b44f24437db42008b305e9047895ece47eb7cce3cdeb97bdd2ddf0b4943d5b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51071f29df455dafe18b110682fec311a8a3040000": "0xd43d053efbce28083bf144fd919b8b5338e67f71b349ab9a4dbaa71845a9ca4200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3e514819b14bd168c797646db45a4c143390eac318c97c11839ccf819ce24b7f": "0x00d1906f171b3ae82d0c500555143c28d239ca74", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda04a11b64e7fc03f1d79937689c4d5cb4be50e9e459edd9217adcab52c35332": "0x22e90752520af777fbd85cfbdf28b94748e7b871", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002a66b507752653dd0468eac677ce6063b58701": "0x00120a85da7e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979887c59b42a14ad759d1abfdeb258dfd505a01db": "0x00bcc1fbefef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ab35e5fe5354151bccc15e6d219dcd23c2e868": "0x00985db8783319000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7c2241b8ad2176aa340dea400bd84fc389091a7511086bbc78fa98a7356e630a": "0x029e46d21436a8e435cec948d8a0a5bca6f19b7e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de07628deaa9c6fbbf2288f879396ff3566871c0dbce85c9e23764d15b810657f": "0x7956952b9ea6540641fd0dfe110f071d45c835d0", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d8b29dd8d38485d5f9324eac3ba03c31a71b47e2": "0x0080e4f642df9f0000000000000000001262b30201000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339709fbc09d7da0c050d4fd80db0649b30378cc4839": "0x008053ee7ba80a000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513aa40e79fcaa275be98cc69519d63d7051040000": "0x4ab530a569015d1cb75ec21da05e00b943b903b22232d8e2d2c24245b5e3777d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a670d24c5fe23dc467cd47ff9b8b5fb07369dd": "0x00ecdbb3710d00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5154015586a35d3ddf5f75de868f0d0cf1d3000000": "0x60afeb2a1bd8750a849bc9a851a3bac0d708a882bd4f2c5916ae0b714b4b5f0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e2d8cd482efb93b788cff519bcbf5e25dca333be": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b3393e6991ccf120bf7d83e6e53aa6ac8ac5c551": "0x008a8883a42400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890037a6b811ffeb6e072da21179d11b1406371c63": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5177cecca906873a1e2deb65a6d2ac17257f040000": "0xce21f3256f9b285def6328b996d6ba21ee6cf192cf6b10364e6540ac9245bb6b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ca15a530dca1d29ca3557b90d80e3a05638fdbc": "0x0082377cd53497000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005dcc47544933b9b69fd851d150394c011baa6d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900844b1cb340393be1e3cf1c0a9157c57dfeeb2e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794b05d7a1cfc33b148caedb2b979d603a6532bcd": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf0489ae7bbf3b7321841f3ce9db682a6b0cf612": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa5eb42c2fa202b4df66a36994d41e04bb3af2b5": "0x00825973078100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d026b8bffe70f2a6f11535177e90412025040000": "0xbec6a380acb8489f21891545cfb9b4964bf0f3170c5deddea166cd8f87bf207800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ecacc2f1bf37e9b8278709b785922e52abd83b": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d767c06d934298a9bf8f317aeaf2fd3a6481fb052acad0b9ca6d8dd5dcc103d07": "0x029c5bc3bb8be76487f9b75b5065a6f57ade84a8", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51344f9986e219ea58828e023e0824e23d26010000": "0xe879d14e74c8c5de8dbb00e01fa32b495c0f1fbc66b6b93bc31006f04429395500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b87487eca8ec9080b3c2650e1d3a83bbc07077ae": "0x002caf1a406500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e531bbb0dc3abe3d335edbcf5f479b84c2839c8a": "0x009ea4c3e42800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431bbd9ddc49fd2d67462d0b1919151ec9aa45fc4b": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890019eb2b083a143b40e6bcd7a0d4508467100f22": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899fd1eba5f41419b2887a1e36e4dc22598254864e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004e35c529b6d6f7768f868036f065138fe68b57": "0x0092cec9b62701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700106ef113a8cb3c3a233553c4ce69ea14d88524": "0x00244691bdf401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970086163e3bd61e85334868c8b1a2d65d3f244f6f": "0x009c09dd960400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d543d64b162e96ac48944161ce5c2abe57553d0720979cd90030ffcdd97ddb25b": "0xfe740f05146eac00d2b48f2527eef1deac1e1c50", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928913d5d590be45f86e1c1297073951ad7abfb746e4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9852f33e7b714fdcb0cc70fd2338923c5ee9c45": "0x0030d15643ec2b010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005703ac09115ef8422705c86a94025182b20fb1": "0x000c7a9e142600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978b0885a1a520a11daab59febcba271e67ceda6bd": "0x00a06e48f11100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ac0f75d0d139301dd8d666526b02234220b14a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928985f0c61774dc981a07fd9fd76f45c336fc87b44a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971b289087ee4dd222cb003d5cf9d14e376502c7c7": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707bec2143e7052bc6608c012ea585984f8f9b27f": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972deb3f6d44a5bb8154181f32f79988bfee948d49": "0x007e58b8edae01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a64f00b89146c02ee1c879b22dcc661609a6fe3": "0x00c41afa0e9000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900acc0bd13770679812fae76ceaada758781a5ee": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511d6e10236d8e521e043df8f92f743f27f8080000": "0xa29b24398799903fe36cfe2b193e8d0a90643a3abc81105a5356afe30c7e837700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c155940fe345651798e48f29c54a2cd860304734": "0x00ba96511c4b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f11a5b9d492c53674ebf1694954f19bab83a7c8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51585977bf17aab4537be8d49578c6a9b421070000": "0x50684b3f7255302490563ba108a92765a0c4f0ede17c923bb105ace91b75f30c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d929257d29d18a4c4a2ee7f6b395d0c1eb9cb7685ceac9624437674db49404f0d": "0x55a3df57b7aaec16a162fd5316f35bec082821cf", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc17ff2de0b6577aae386e5bfe8ab7695282a52f": "0x00ba6a3f4bb60d000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bf79ded61f78515c23a76e625039bedd77c50aaa": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002fa17657a9c0e03b1b0c3d833b200a013dff47": "0x001ad45b8f9900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dece71fba2046bf700da154b046b97359c83d0e14f81b53e33161e30593571a7a": "0x006e6907ba032a02644f7289d5a2e5b6f3e41a49", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d023f1505e3e54e2925d67915d720d12db1a32bcc04218ad713d75f5b543cbc52": "0x67c5eb8059d9dbb1319f71dbe45952871e59d845", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce7afec36eceb2f4f7ce11d6165425203098d1b0d935e9dbe7b7ce8ee8faf74e": "0x6b80b7d073b3ed63690c0962d061dbd88cef4f64", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0673ad71d66accc24a6f3635b26852ea24bbe2762d966f4335aafb505920d75e": "0xb8577dadcf48e02e17c649edf5185844dd2df05c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397497acc237dab7e7f944a8b1acdf9f56288bddf13": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289034e104e2767228cc99fb3aa5af22db30c428b12": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928994cbc73d485035a0ab712484144dde3352d6cf60": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928902308e5635b9df891a27b2f837d88b8dbaf01042": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514bd3bb142bea719a94ed9ce35f626a4bb5050000": "0x247bf0e53c7df2d529571a0f30b45813cd97fcd008f8d20fb42b44a0cd5f1c7700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bc20d69d0a7b480858550141e5789a5e4d090000": "0x761c14101d6d4d268b7d8fe9df7b1411fff2e3c1248cf72b1fae155214b8d35d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfdb612d1816c094e2d7bd3d957b76444c172c761fdf19df2f31d63917926e34e": "0x577acb95cb312b867f08b214f421a52497597688", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700099a01d4d41e7df0f2f08687d2edbf7884d99c": "0x0018b092324802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970aa431c58dac3b6f8cc07877c817165572ac383c": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896b5f703d39c4328cb7e87a6d73818c9dc2e4dc6f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8f8068f55fb15342508809c3b2f6606aca7a650": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6a605250d5a59894de282fde4fe4c46312b9ad3962438017b6d896a3e93e0d72": "0xcad1acfa9151d7eae13f06ea4d90a0024cf37301", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db3e6c17ba16170624265646fe4aa82d140d20783c65972a712de76e07a595529": "0x54f5873787daa1ddc97272e9f7fce534015f4d19", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397940650c5f5f78618c938c182d89b0687579a99c9": "0x00e0d10d78cc00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001e14757da7169f07fe225c2afad22e69eb93cb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001d4db20608af2ddf38dae3c22255f5a6509cd9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701e19120eaaaf5cd7514f028d5ee7993be7fbe6d": "0x00743ba40b0000000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195028e95e42348384df6772616e808e59368700ea89e2bf8922cc9e4b86d6651d1c689a0d57813f9768dbaadecf71": "0xe240d12c7ad07bb0e7785ee6837095ddeebb7aef84d6ed7ea87da197805b343a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928967c5eb8059d9dbb1319f71dbe45952871e59d845": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970024d44f11a321a70888283808c81c454b156546": "0x00c0a31bf09801000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db023d129d9a0cb9490d097dbd3ca947d4830d3a6d7e0fa9975ff2789d9d97352": "0x5ad04210ddb16c4b66644eda430918fd5826ca17", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5110b98e3b8e802f67687ef6a6462443e744050000": "0xf65227f172a1e2e0ccf5238ba986c3ebe035b77f062ef04b43d88614cbc0750200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007ed64ac2fe49e1bcb932151e72de0ca813ecf8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289392e05b27079b3502ef2937e0af15aac14e8d8e6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000c6e132057a388a9ef1bf73a0e6b686dad276a": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339779af82bbb0552f8ad0192f4a7638dfbe8be00908": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d9f222b9f83e22e15702b798ff9b4d9d30b117": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5130fe3a48485a1c74dc51b2567c0a56592a040000": "0xd25b2aa840158dd94bb9a19e85a798324e2a0e4748eac08ded47a5fe2814ba2800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519af718dc448e52bfcbb2e8d8eb7b8de9db040000": "0xecbcba92701cdf5ef12ba295931dcc4867f816621fe32a9871ec2a72247e356900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282436851cab6bfadfa47246dd71528c4d519aeb85fd4": "0x00008d49fd1a0700000000000000000073707f0b00000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca0b6a45321efae92aea15e0740ec7afe7": "0x00000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de467841a086f53e1b6dd67a93cc116d062ba000f884f2e49546a7e8f5552412e": "0x00bfe8f085ce6b73c1e59c3eae993e73125180ae", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003be22889aedf2d4ddab4756263f82d6aa52ed2": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973fb4981d33258835ed1de86668344ee3f08c626d": "0x00da49aa61b26d000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cf211b9f0fb04dfa9f7717ac2d614226bd1873": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db854d52707f6ed71c182597e415b55532a3a49bc0a20075f1a8f693b25e69761": "0xbe2fde5ea1a064e4b3708f35c269ac5e06c3eb7b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928953359144f93b2a061fce84895acefab5b537a055": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0c0d87bad01936885224edbb57160500b135fa1aa87aaf55de4334b3e10e5336": "0x1c5d2111b3445cbf18bfa5709ddca8d4757c8155", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970091da397a6675117a811b82cab27508d75d078b": "0x00a234c7d60300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5128210239547ef1b1a87a0b1c87bd80bc1e000000": "0x669dd77d915c5c24e5dc787de28d5f0016e3af9013ce52be7ded1bd0a4d3845d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895c1c3992737f0ed1cb650835f6ae4d44763cccd0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900adefc329ef84f5ab49315271912a1ca57cc18c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928927a56b2c1723942b8722a456af024ebdca0580b5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897886c5f36d2d74ddae70a9125b9f375fbf614cd7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897b40d5c17aab371a6ed5ac622ea232b590f2a31b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d74958c765a261f7746221a02d4616939d27a21837dbf876c79446f13711e7b05": "0xa003fc1e731965c0e08ccc93868cddae6895d8e0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc0a73abf38de6f332b9dca8778add43e53bf4ad": "0x005acbffb90c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928993c419191cbbef6717b1992a1f854ab2d90aa7ba": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c4895ea497de505d9c6e2adcc2e036d1d567d088": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de4a865acc76e7c89557365725832e3ba3ccaabadafdd5f1a668ff74243823c78": "0x970a3182ec4dbe8115a001c5abf6f5383cfd6c6c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890f9e910a0736b49e13dc9c5d575af7dc0943c0e2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e89e08763debfe1abb6bae24d4bc21c91150dc79": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cf13b4933a43a2484b5ac0594ffa5942bb030000": "0xfe578ba506f1c6f5d82d2cc86cef3e6b7447b24c2b9e82891f7f454a55dcc21600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517580b0f9c5222074d91fd90d066ddb1214070000": "0xe84e22cbed34955f4428ec758aeeecd33185648ab8c187f579cdccb935cacf4400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b71d05cf5cdf7a9b15b20b9aab5e91332c271c96": "0x007ae857fb8000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5104de76198905f1249d6f26c7922df7793a040000": "0x06301860f2816ef4da65a86597de885e9071806a79d273815b4ceacb98247c4300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339797d9c5ee5dd7eeb360eaa1cf37252154ca145e2b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000ce94f81d1f81401712a57f615bfd9b139a657": "0x007ebb5c423f0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fc03c8f4f7484323459b2b4910f2f67e59c8d0dd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397905aa2247bfd6b8c4850d59b83cb6a43007b2ad8": "0x002c79ae7efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ad5077d22fd0309130fc1a1ce0e655ce4de9513a": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f4487a0a91f3c75bb9631fe6160690d9149ed853": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de8eacc9d19f41e050e02e99f34a704b7afcd65c7886bcd79d6c888440e5ba71b": "0xb71d05cf5cdf7a9b15b20b9aab5e91332c271c96", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea989e5de8381aadf03a456ee925107e6145ff1f649ae0576eb763f339314007": "0x6b84b4c46babd3748c1c73bc408f6999238d00a1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397449b5b91b10523f024b6d9101afad2f3cfe7c8ea": "0x00901ec4bc1600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb70a267c49250f5c85f0c4008046cde3df51ec6": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfa6bec1c59118bb967eacc2d3f52b46779d20a6301fbed69d536e505caf75919": "0xb3c2a4ce7ce57a74371b7e3dae8f3393229c2aac", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339766b9dfaea3ddef53b98da82a224f70842c817703": "0x00a4289f320700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dd2fd84c6a67d15d0eac21e08e00c3d47c010000": "0xf4015230238cad5d18740a481674824e976409255571cdd91c0ba9a439b7544a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397557e9b0f30b4e4d1738c4288d7a69ed8e79a7036": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5144760584f68b3fea3098bcd3327c669c10060000": "0x2abe942feac803c6d77291161d840e67db6fb19fcbd45364446358d25c3fd11500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f46a575607dc5b276eb6f5bb2c7abb8ec75fb648": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006c1983fccaf096caaee155ce27a6bcafe640bf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890077f609a73630a90fdd05e6edb7ab0c99bf71f8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289129bce7b810124fa5745667a17b69a5c3eb5ac4d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928975f555adde5385aa0b852e0c551f3aa47715f593": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899c8f8f563c3e6a9fbb039fc3e20b53591796d745": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ccb2545aaf81d791232b9e111f4acf0a182547f3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c662747812327628780f26e0aa80149f4bf26ea3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289da384f18b8a6e83d45afa4731424f1bd08317d10": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896d4b9143dddb89e914b180b3cd9e55bcd74f7c9a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339717ce04ca9524aad7df1a14d591576f0a7cfb8565": "0x00c4c38b94ac00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896189e56073fb6102fd6c0fd5f0d1547c4f3fe350": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008d3af90dba667b290dc64a97f2711ed3a7039f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000f7b173834095ef9a8050828649ac394046818": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517260f8d75cf2e3d34a68a64f397322ed3a060000": "0x0ea61ed6dafeca43601645e1cc6842daa7ec0c54795269e30df0c03f819ee26500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db8cb6953945a47bf445e342ff346b73496519646383bafdf669462c5ed30f500": "0x3024413123731ac0ce07c13e9511c0bb76a228d9", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890031aa2156f558895016433e6299dec2a4505d5b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0042d0cde6e173a7beb9c72315b9efb8ace76c323ce8644fceaa8c2d7a18dd3a": "0x67303886cd4d268eaa3a6cd8de51413da1a72dcf", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897a78aa44b5660cc42e0941782a278c510f17cfe7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891114c8fc7287c7b9eaca65be89d82d85288a891a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51daa15a76d84d95cb61adfc8bf8b8ffb80c000000": "0x6ed4e490d482667ac41cfce61cb6595a36e7b70cc16316f305fe5c590c89275600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009151601c379b0c211e12bb1342e183857126af": "0x00aea986460800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896cf10be9868455941c4cc1f1d29b741ae0629cae": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003ec3f13edfbe650fc1a703298e66caeba93476": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970087066f0dbebe06b184ad03aaac64f28b6299cc": "0x007c16070d0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6110e8081a10caefd8ed1b95db4621085b55807": "0x009e00db9e6900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f6157016fcc42a5c2219fd80b69679bc92050000": "0x0a34456aec68d1fc7036ef0616ffcd7514d63cd1d9433c0f55b372dd469c881100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289adffeef501353d90db6612ed584b1438daf02c4d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339752d508678aa5eec68ec5faf8f17abdabf9ded9e1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289592f17165cfaa5397984f7306155d330fcbad444": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c89b9819ae522824ade6efe464d30f8e431cf904": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d804886d79ea6b1e21493730ae735f66b0789c48a6cbf3d0c3a6aa5eb7f47fc0b": "0xaf50942a6552333a69f736a00aaf7d5f57e764e1", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51adbab0becbc805c94fd7dec982887d97fb060000": "0xea67cbf97f4e26cbd9406118041b54ad460248c3dae2f3d12c2ec8458869780300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971dac430b96f24ff9f0e1cbdb725407372e09f09c": "0x00d42517c30800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799947c78186a7ebe1e620924ef0bc50721da4e28": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c14f09369aa8e6a7490ce9c54be313e5daafc0c7": "0x000e64d297fe01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893e784d624d4e60da998bdd79169edb8beff89d27": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008240239c06fca835d97696c23a9cb68ff4d5e1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4639a86127f62435576d4ea0665cc07584551dc": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003e042a1c0d20f39cbb5664edb923aaf00b8e30": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfa32ba6d93b464f5c8b53ef103ea2d296ba373ab17b21dc04f2ee78c7389d23a": "0x00cbbf87e662f48e24c47db88fbe9af500e10d05", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c094df9784e3a409a27f39875a85d47fb9d6d520": "0x00ccd58f146b2f010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f7b34d58d8a6134c268fb8f0174e94ce07874e0": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978da0a15786008f543a760701e2021f992e1c1cc5": "0x00f64ec09aff05000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a70be61eaf9073505bae64126b3048b3046edabc": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b8c2af3baa7b5b43ee4e082be3fdfa8096020000": "0x6a82d00e3a0a34d054f2f20a66371ea821cea6f3491a3b9ffcda6e151fc37e6800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dde8f4427e9db9a35e0c832a3622287db2dcbb58b2190e6a9a697e867f8d53818": "0x00e4992bb3d86f6734af7fd1528a658f8484936b", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243e666339d61a192d437f96ad1e40f197d547187c8": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da4a61e58337c41c96a70b2c906fd4ad346f180800caf880af2662e658fc61441": "0xad4551742f5718e0af5d88119974c86efc8b83bb", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dedf6aa7debec01f84d3d24b349540814e033ff7cdd6f0c4200657758f1d39e65": "0x1c6e3ee84e63c897962f1f40975bf14f5b10c2af", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4bf46544793204b9ab9b0d276c7416b86378115": "0x002484462f7d00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513ecebf473ba03055df0798ebe840ead1b5070000": "0x2ab493bfe56173fd911c6f476d0490cc85c83db9e07f087f0e08ed259664dd0f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510b9f9dd488ffb5be830daaa665fe4772ec000000": "0xfaf41a99388f45bc9d18e3b93383221b6f815298acf8b3debf235aa33509de3b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900eb8e5c2880dab44f41e7ebd008ba6031789932": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890c11fa6623df9ce654d9b7e75841cf9156ba99cc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891cd62e399651ed8835de4be49eef4b5a3b190489": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899944d6a90b6e313fa8dcd0281d7760ffe4ee0530": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894b11f86a69ed65e8e2266d936c55dc66f43da055": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e11df746c5ae8018c863f98ba5e0970529780eda": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d1329c5042de8e73a19012577ff26372d003d1": "0x00b602b4cd0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b2921eadb2ce19c3aa97d1563333060bfc472a": "0x002a952b210300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a8bcdee6b78af63f0ce1c8b97bb7199b8172a10b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511428d0852614f3412cb298f46ddf8e7c83070000": "0xaeb543882dc06d0cde4ef60f889fec6349ac00299bfcc2b2e843aea1c7811a3800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d95e4b573c9825824a9274497e5777bc500b68": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898f4d910b1ba48ef5349f3cbfb01908c1f42ed63a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899e8b9dc427650bb1136f50ab903b00fdee88e946": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d58e8986a603cab040fb5e976c61b23021a5f5e7a0206da27c08fbaec24fba755": "0x0076df9bcdb37939908f00f66c2d3d83b98345a0", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a4ceceef89a949afa2ce10c73ed5f0d79dfb3c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d3b33791c1ea8922dba88bd800b509e884c33bab": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514ca8cfa3edc3ad4bc4b95a958ecddf7a47060000": "0x5ae32d080487ab45708d505c20edf8ff9f49213a0849b378f2e229bf603e760800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289762a1795292a3d9355aeea85e4b174e9bd8cc3cd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ecfb901249099cf545de2da3c3ff6e320fc11765": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de8a3132b1815c4668f541f5fc8271ffb50d0ddadb2ecd1f3e7a34d7ca37a3f7e": "0x99d1efb41a2c5ce8d000599595f598e6ae9a8356", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daee72821ca00e62304e4f0d858122a65b87c8df4f0eae224ae064b951d39f610": "0xfbf27816ed8612ba4477bed6e0a554a1a35fb015", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005dd1c702c3fcbca5f63b3ab931b15e03b3c9ed": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511284ae9bb711606c924b85ac95a6ce5d3a010000": "0x3a15620906193ee1e02c754d33d5a2f78aa9568bd87e7c241dd73a6329758f5300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddc0293434648638559e1a4cf30e829f17d2695980d5a3374af8d663bd5214905": "0xfe7c59f5c785ddb869662aecdccf932b29e10771", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da232ea049b0cffb350f95dfb094959d721a7c331f0fc8c976539fe521fc80440": "0x002fa17657a9c0e03b1b0c3d833b200a013dff47", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895a403e651ec2cd3b6b385dc639f1a90ea01017f7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5144d2d6a6a256b7fab2898477ec5111d8a6060000": "0x4a0ec663291c413542dd5919d73f95057ea06907f2937d711fd9f17591c0d25f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339704c6f1d15b8b0d5058db45fc13d6193fa78848be": "0x00706f96a68602000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008d4360424c57ea4e11f07b95ee83d591570557": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892c2c1ce72623e05242ce3932ded73bdc36898f66": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ea1a59c6785f5c391efee3656f5c7e84dd20e07b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397584455c19de7416a22e6832be0c35516948fae82": "0x00dc704a740300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff0447aac61f107abc8872248ceb6a04522f54a3": "0x0078b90cce0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009f7cd88fcaefeb56fc2c00be4f50ca8fd6d0da": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5101963aeae48e97dd3d2c613fb0e3d2bce3010000": "0x822fcb603c9ef8a930dc0cfceb1247f746637c9429bf78c5d97af940c580b42c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783b16a18f7fd937545ce0a72341bcc700bc72c69": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dca00f0f34006135ea399fd9f872a904fa4d1f2d76c9c4b681337fc5e2fc1ce2a": "0x07ef90799d9df56a442e958d6bcbb274f2f9bd55", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d57d447ac2a9cde3401bba7abb6f888eb63ed7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970062dd565ced1168f0e8f55ccbd353d41a19e144": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d16f74c762a21dcc935462cb83092a8dca9762672aa22dd479db60408d7471420": "0x006d3a544384b63158fe841d6c84b27d998ee27a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006307f7e5034af0a325f5eb706ec2a8dda67c09": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004996dcf23cdf72b62191ac358142615192c7c2": "0x00b0b673f88506000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928946a1ee4cb00bd3f064e1a02fd5c187e34bf4c97c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289da7b00af38ee8a3de3bf7ddb6c08cb924ba97d72": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c16e288726a587ef85a23c884cdb4232637ddf5e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc67f0f6ffaffdbc60d7994ab226f632dee4a8249c363b33359daff64200fec22": "0x355d599405c853d1be6f1ff027967879d69acafb", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f409aba35fd318d2f06b820f80cdda3819f7a545": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720ac64b955ebc54f7287fe3ce29671086722b60b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397129bce7b810124fa5745667a17b69a5c3eb5ac4d": "0x00bab4638e2600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397230647d9f4ec617a62a6685058aff69d729a5dcf": "0x00c0fd5f400100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9ad7b209525ea818e43395b6e67de351731a7fc781eecd5c94cbda642e07f427": "0xd1cc0cacf39176b5947925ed5084e7badd44b625", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc08d5de7a5d97bea2c7ddf516d0635bddc43f326ae2f80e2595b49d4a08c4619": "0x7804275d8e53aed92f09f99f55e135c75bf297d7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d35ee346bf2df7627509006d92316ed8d0713d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397123685f3b3c7550254f187ca3746db61e6a248fd": "0x00e6236e34f602000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900de0911e577096ba2d8e3f2d5ec0458b1d24830": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea93f58088e27ecf986ed4d70c4f4d40d726b390bcb87f448fcc35fc917e0d32": "0x20135f71a2c2d92ad87aab4431862fd7c38c79c4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ecbd51638c57c1bc38e405ed703d82a977bb76": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891808a1c1c2d6fbc1752b8a3bfcae4b1ccc033202": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928955e9a88d4c79252e7340f1e7816098b755c942d0": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df2287de36aac9be3d8253ca258bbd653f66e65df2ef87d41272ad8ce0cb6c658": "0x000abf987d6d132cd1477b2c9f1fca2ffc0a4375", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928905b9879bc7d504d8c242283745eb9ab59fd0763e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a1184c3202e060ccc335e1268a1b379141080000": "0xe02202417084cd61934725dceeeb213f4a3317e0380658dcd137cb3dcb4d972d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0e0a207225e52c21bfbf08c5022e9a6fb26daf70c6cee1ee92a6a5c02085cf24": "0x1ff27838e63649d23e22c115e15e5a22ceb7a680", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896ae921692a206089246a967450b1b88783ce8fda": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51de7eada19b914f232ce540abfe9c3a0b55080000": "0xab68f3f5cbd61feb43e4204d1376d42b3c154478e1d1931ce9cd9bd98de8d7cd00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da843370edee7d8a3fd7e09330ef328b00788b7484afaba29241cb36247e4540d": "0xdf2bf630289bf17443c0eb89d5fdca0868eafa0a", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5155bdee8f3d95491fa96c812852b55fa0bc040000": "0xd245df4fa44f453b3aa554bfebae8f4310fbf8c4a5abf9da6c1e40c1f05a1b7b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d688ad06202344d47304eb9eb4392842fcbcc8e06977d6cd55f02c2c9af602b04": "0x163e5addf68d6e21695adfe1f8fbb33c78d9cd4a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008ddde69a07c04100b334040505dc6b4125bdfc": "0x00989568830900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d567fd94f85be51453babbffb0162adbdf06d3887b0ca3aa44e5bf57587190f7b": "0xd4c974f7fbeb3bd79a34b7e8bc789af96b8daf86", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d71c24d7117a6fa9b1802a366e51568a79080000": "0xa95cca149f246208e7bcefeed44145b6ca332fb9b797084eccedfc9b746d1daf00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d664dbd21a50bec286ed2ae25da8f41634778154b3ae6dbd93290bcae58f1dd60": "0xc61840fbe306c4e984a41128a5a5a492f5491ddc", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817deae7f0525b059f6a986863ce528fff8a3eac44e5a9a213475f3fc7886628a261": "0x70a5643374c28a958b5dcfbb68a36d3fc31e2fb6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890091da397a6675117a811b82cab27508d75d078b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ba747ec663ca7239cfefc4be89639c3cff6da31d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891b22a64ea64c2f4cf1d6ae25c855db5fe1ca0e20": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d38e00c10beaa10ed77f6e574adcdc31f1647e56": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514a3f4abc7ef1f9092a0cdc9f3d60822d04080000": "0x7ae802beabf67df0788ff71dbe81741b307e187423abc0a709d73f2997a8522600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339728e66a9abb74aa9fbc4dddb71775f0cdbb7ae031": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d95df826fc3ea014f404a1368a254e23d29d99c8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fd4e15b4dd20136a9621576743893a17d4dfff2d": "0x008025114d8904000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5113305efc31075fd0b5957254fb3aa19774020000": "0x229822081bb748111238c67574884b63ca85638c9b139102fb97796dfc2d660e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973cd0266a7d638588e79fa9b471fb4c2d6072e4d9": "0x00b4217f875a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df370202f48a6858de8eab90afaa3ebe1c6bc63b": "0x0080366ffc9c58010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397050e3aa7f5b52e7f547821ffd5abd8ffe6062a86": "0x0080e03779c311000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a78dd3ac7f1f8e53a445d54e8927b7a063040000": "0x98106d7b4993f855c6b5f7b9a62102a587a3da69a9616d0d110b5250a65fca6b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5175eb6a4abdcea48a2bc1afa216f99fbbf1050000": "0x0ea2376acee36454341f0a626cde932000a591da9b5cb385b5fdafaf077b242500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b41b39479a525ab69e38c701a713d98e3074252c": "0x00e87648170000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006d9c60615239ae70c618e265f3fc12f7a3b12a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289803abe2c97e98816ef63a7b039bb59aa8a380909": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b41b39479a525ab69e38c701a713d98e3074252c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f993f7ba557bde7f6f8c49c7d53d2b0d6dc87361": "0x0080c6a47e8d03000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516f167645f69ea7fa45a97a1ec5da4b36b6050000": "0x0c0d87bad01936885224edbb57160500b135fa1aa87aaf55de4334b3e10e533600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b1a23f44831545ced859b3e80e580b2aeb050000": "0x604ed1079ac6edec50ff937aed6ede2929c20d1d8b15854af06cfc7a5adea82200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890e4aa4412dc3eed8c5c6a39288866940730dd257": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea9c4b014031963e4e1961db0b632181056d80692b9f9f8302b0916394e14027": "0x85f0c61774dc981a07fd9fd76f45c336fc87b44a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970013742c72bc005ef342eb367374d089ac6dd481": "0x0076cf5ffa7b0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002aa61c8653d63ed86aa91053285c5db6be2ef1": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892a8dc8b6ce13666fe5c2c56d23f9831a7b61a13a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a857b41cc4c4638381003add9e721affe1080000": "0xf02cb843f10eb104a933a57252ae8bc1a76c6681eddf513205a8404a68d4b92c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a10042730f48659fb0c3fd7f3cdeeaae03317f18": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3e08fe860b1689624b46560ca277927a7f18006f176db498b3f7af2367487557": "0x6e8b688cb562a028e5d9cb55ac1ee43c22c96995", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282432aabaf50bdb0b288e642f0753758ec38ee556567": "0x008062175ed15800000000000000000098fdb88f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007edbaf17817a91eb48f6166a592d16cc47846e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cbd1b6c83908c27f324e5cfbb6f62d27ef9e27c4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dac33d356f459227a73109e31a9745e0a5b7d366ab0d489fc0b2bdd520c4cd92f": "0x72705657a219aaa87e5b7223cc79cd15e33e18af", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707b8ae7d128d58f51815d99b751c0dd9b6cf2d44": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928952d508678aa5eec68ec5faf8f17abdabf9ded9e1": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d507b544916be600bd033d37e659e090467d1cdd29bf9dcfab11e1a8eb7b4c67b": "0x13376a50540351f4d0242e20256e857a80bc86b0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397350b85f8b7d4924c88b90cdac534ff4931512ab3": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001720fe2bf6df9dab32f313343766cd4a0ac2e6": "0x00e00ad64a5d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b0807cf08105020d06cbdec06fb549adcccf14e0": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4a7aba74ee1dedb88846e9b9fb572b8be27d19be26bb49c3d0c431bb648c2d17": "0x0024d44f11a321a70888283808c81c454b156546", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e1738f0a09511622e06dfede9ec64201bd394e": "0x0036270f8e7701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fba281c66fe1034a2f1cfcde7fc6f6d939df9cd6": "0x00009573c24800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d5f0ae658e4d4d48cce0355ab6c1eb155b7a82": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009789e46d6734cab174c01e5811d744f664504f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890098491a72d51c3e29f41eae6ef5042b4cbc6c9f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c063dddb0309717f742363085e29ca9b097db6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51562294a9f228eb65b7a116fe6e143a96f3040000": "0x509603fcf64e4c4e9332d7732430ca2dc400a758418bcc1ed6b68829b34a017d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339724941335e79baae9751f508e7e95c1dd475b4e31": "0x0042b095ed0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243dacc0fd259ce0de2829b38a0765970e7ab65346c": "0x00e0a11c777e02000000000000000000ad25090400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397746aa9ec270bba58b97a30b5b402efeaab86bd28": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897098da7dde0b85baa6517d732d16fb06d8bbe022": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bb2da6e051604740d95273c51180219056d3e70c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d7ed2d43538974c607917ddb8454f00f3cfe250b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e45ee0163ddfc1fe2780064ffbb0d0dc2999f873": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e9133e7d31845d5f2b66a2618792e869311acf66": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e3bf929b3f1c271e62cc6d1f2882eda0e741f8": "0x002468be4d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d8094382e17e1d0c9393bf84d2fa671d57a71a05": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890098ffc92b4fbe3870fe9e8c688c988d380af738": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890046a7c2d9d55fbfbd3bb829995aa25d4bf6e401": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289524db42cfa6386c5bd43229805ba087cc5d25438": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51791a6ba4cba65a9f08118ff328fbf5d6b2010000": "0x7e9f6f76760ac65628e32e5a1db5d030f0623ab5108cf68ac23fa6732b47b03200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f4b3e6adabbbd946c2c4859607a134e4c609f53": "0x00ee5692f26601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b02427864d348004ecb1044d508c68c79d955d": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d52eeb0775a35b135b1cc12b0c4234db95f5a684bc6553bd94ce177914830941e": "0x003c6df13f3c95f12e0f3e2c82e3980d9732558b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ae921692a206089246a967450b1b88783ce8fda": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5170d86badf5a96d4bc18d39750242530b8c070000": "0x80f8873883fb8b60de13d8fb78416c118c1b7baca67a058896cd976073e3772100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1ba30cfd46c08cf699b00c705de01764689c272": "0x00d098d4af7100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397219a0751553ba999f730fc1af78bb5a3f255670b": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ded0fefac80ac08719087232565beddf95620d75": "0x00c26f318a5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971749ad951fb612b42dc105944da86c362a783487": "0x00741a684c6926000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928949aa20d0109520abd79ca28bdb453ba1ba348b3b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289925cc6e8424900f85c93957095893f806afab0a8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397020e6a798d9f7d8eef4696d0f9c555359900ea19": "0x00f27812638201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ff86d93a528d81402eb6b76cd270be3ec36c25a": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339742d75f75d1aaf59304642bd7530e5de5a42d8fba": "0x0006b016fe1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890607df4570ebc920deb346220ffb52a0bf1fdcde": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df2febc980f27d3470e1ccad9a8106c009c08b08cbd1cdebb70786669f76c8340": "0xefcaae9ff64d2cd95b5249dcffe7faa0a0c0e44d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d2a75f1ebb6ed6919277401a2e3fd6e3d828e086": "0x00f6428f3a2a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c90de3a4c3005a259e20cb50402d7c41948c657": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cc674a3c614e1c49a0389b3797ca27f30a5dc78d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397053e71a33ab7f5250fd4cefe232b2fd6ec92b0a4": "0x00e00d68c14700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397847c5586665b81798aec196a3065cdc577a013dd": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007fe28a2303b0943a759b036d56a73b48bd3164": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db6113f1e61796e5bc0493f464c9de6000dd35b498a40225f97a5f1bf2491d262": "0x6d82fda6e5d6dedf42042f3ddfa2b78b152b6402", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ccfe74df2e586d29d3fef37a234148f3a1b99262": "0x0036fe07847b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ae92580ffe442350bfefc4c9e4fd5b137a0fc9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5438aa39d5800ee70449975bb26d31c60792dc9": "0x00c48d2dcd1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890adf0238f7edcb1733269f852ff86bd4a9f37b99": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b5a89555aceb6e7cd871907a573e3fa207323c61": "0x0080fbbf800200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5198aacf368e86cdc068c2d91c64faf33b72040000": "0xb63b6311906644f4385479c41b9c08d1392886c83104810043145f480b78f23200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397deda0b6b9c98ac5ea010fe9f2086e93bc1514ec7": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c636b16cee0a7cb4e5dc4662b7d321b772a8c1ec": "0x009e5cf258aa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddc9fa5280bf7a60580e96e1617d22c1bc83f6358777c9b3d8b1d73548fc91528": "0x1ca509880fffc0b2dd5c6a4ffff2074483f0e982", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008fd24707883affbd4c830eee85a8a4149306ce": "0x0014a9784c0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e594def1a782c9f0bd4f6e5ad16cee01e380f3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928981d94d58834fdbb584d72b40429d43cf42f70aef": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002c8f6cf6fffece4a83cc3d75760f268bb0c90b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d7ff0231086abe3e95ce3773d60a39bf27321ee2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519f564f606584bc7f06fe77b4f094161532080000": "0x09e3d208f737d92bd55e3cc348094b24e60d223f7bbe266a49d7f87e727118dc00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d182bfd28e1df3520bbae3602ca44f076a7b928b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e902b00370977bf81f4f2eef795133a1711ce38c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec92519007b823765664beac13efaf630c263316": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b5a89555aceb6e7cd871907a573e3fa207323c61": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f3ca35e377d360676537c40eb6d60f5b5b2de856": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e5cdd4b7b3a78a4277749957553371cb6b2310": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397608cb60905efc0b59ebad8a9c650a410fead95a0": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890063dc69f9baacd4f90f8e385a2b93e8233dd8a5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dd9364642d32a48eb2cb1b0b65d18656f4a66180": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339735f7b776fee00f961f7cd1168d48e9be61cc17ca": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736a2688e8e60c13b4a124766e598b6169b0e9642": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a6d927022815090c856377c74b4128f1fb114cb": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a0d73de5df565717a3994af5cb75455d8674b46c": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973686e9daaed20aca53640fc3c51059f6c5afb54d": "0x0070bad83a6c00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5130ba39a552492b1d9fdf07b6f705bf1d6b050000": "0xc0944541a69214a840390dc794232b9baed56f93fd4acf46cabdeef8e5fa896200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ebb73c3f457b46f0e1b2c20406d790bebbc0a6b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975db9fef353f8a6c00294a980d2897083499ec00f": "0x00beeb09a89900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a974c739d6a0f8bbf598f8da986f6667b347eb78": "0x0070eab4447900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928935c9070e864636da7462d5a6a59f81f7645e72e2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899019ec6a366f30602f324bf32d91fdc926ee23e2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e35219d98bf6f9c693bf04197070d79d9ba73bfc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970063d8aa6c33d88963ee4176bdcbd65ece06cc13": "0x0000c16ff28623000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d4c974f7fbeb3bd79a34b7e8bc789af96b8daf86": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51986310f86335c12aaa56e7d9051947590b080000": "0x581e058f65025437bf5ab67e0df34ad454e077f5470d947969713eb76a036d3300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973b6fb28ce75cfe369247c591afa0f21f30fe3ede": "0x00e87648170000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289862453aa222291ad19396dc22a94d2688ffc08a3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e17de34ca530df364f3b818e29a8ec82a3da8e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e4c826e8a26d72cd784052b0a45f93a451a5e2": "0x0022afc58d0800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5152a5034022958664b5ce512f94c422dcac010000": "0x86f03e5ee97b91ba5253acf5d142ed086ab37cfb331de077e37c2c905fd9fb6c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fa6cdbeec8b0ae15c81a65c5da6d152a0a6c25e": "0x00a65f83e67f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db8e06dc2e6bb6bd269319ace4cf8f663338f8f285a0564d6a139063c985d2310": "0xd9eb97d7b1c97639a6914e0cb56dd8e584910646", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517be7dffc0a6b1d38e04d3bdf249d2fb087070000": "0xd00f2a04707472db297d54c9ac7ceaa6c6bdd05d1c12876d7ab3464ebaa2055800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006061c454fdec0a781c00ca44508a04361ccd93": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcc38d3766d286b1a624f7031882479cd84feccf7076a2a44f8b9936cbe26877e": "0xfa4be1af84fe8101f91891adc2d52a37b93dfd11", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eed251dbde2ca8d330a978ccbfe4758294a096c7": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ef5b46a23ae74f4c079306fb11198d526b28b3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005ff1551da72279435c79cb877af44a76a7d552": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2abe942feac803c6d77291161d840e67db6fb19fcbd45364446358d25c3fd115": "0x00f91786aecd3995bf5fd3a6183973193b51d6b5", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de8d0e24aa19d8b502a4b778f6172d6ecdc11bd3b9d320c70cec262e291d4a540": "0x1c495e48cc5612e90dbfff05b12532a69303bf72", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700360778f53e71ee3aa3ba78e9b6728ca5917b3b": "0x00c2d8ce698600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b53aba6899696c8f9638267c5c32fe003b86c871": "0x008644b5357200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef710bfee1c6e6ded8ecbbfb8449e782a809376b": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899a597705df555e27d97c07b97e277d1169eba89e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397414c8f14496260104e238a324b6b02a7e8d2f4ef": "0x009ea646782400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c0798c0df1e87069417e76b8ca4fa089d051f1": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cfc49da98153ce90639fa4e327f1516f98cc6e": "0x00aec6b140e300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973de899827e1b9413d6889727a4662074ffab3a73": "0x00567189f71f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972fc342c182bd05c93bc824952d36fb4316392684": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2aafd93579d64984844551475573904219cfdc9bd7a7ccbb732c0d7184bdce5c": "0x3c44438ca119cb3f91dee8f514f435f2d88c338f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928932f8dd495c7da7c59780a4fc381e45b90a2f891a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397903e339fcd2bff1d25c91e1bc0d2b46fe71dc1d2": "0x008267fa158c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900aba4b515e5c9b0e4dcdd8fdd9c870a3761d943": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c2020bae730eb78cbc511018cdfbd369e6957c7": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339784b3ea9389fd14b2d023a0650890e7ae7c2fbfcb": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397792b11a085ce9034cf2f6f7e31c53d85e4da2240": "0x003033a7ef3c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db6e0bb21fa812549e3f75b92d433225455e299a0d106a5d0a1a5867ef5d3a37b": "0xd136726fcaf415dc235995fafe215258aed5c421", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be0c68748745eafc6cb8e7ffc3666f68115954dd": "0x004010ff621b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900de5d8e1837eca3e4241011b7e6ae4c090d9f9e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9ba5e7fef2305ec746210a83430a31cabd44cb964ae70bf16ea9bde11ca2509b": "0xe613d5ff2f7ed0d7ff4c00155b749984ec0ab732", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397524db42cfa6386c5bd43229805ba087cc5d25438": "0x00c8f4b6ed0200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5194fbf39019b729dd28efde6eb59dc643c3010000": "0x86b8c669e6eb75936e2bdeeaec46be25388fe9104540395aecd2d03a4335e95900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890049a562169b9aa96c9327681444d541c8382cd4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893b6fb28ce75cfe369247c591afa0f21f30fe3ede": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397290da05daec7be770a7c20be2881abc1ae2a4e8c": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a7033fe4bf19e90a0ea35e264bf7d2b28f040000": "0x089c56451184d40b7911f91ab7f12d07ef6e2b1b4dc50a050adbfa4f8b58cb5500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b943e534ccb68a976bfa9007ad6705c76da81ec6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bef780ac34cf7b53b5624b863d1a84918e6defbc": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5194ff66da795be4922d578003224d8516d1070000": "0x0a7f29211d50461588ec3c6857c9ca25474c650c7d2048ef2283a2245ceaa83100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51809792f4b850a4efa7d248d510f525df63050000": "0x122783b8ec70bada6ca07f33b05109f4d70c1310ec34d168ae5a93c76fa81d2d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f2981e8a482c36f074440101c3a1007de7048cc": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339756d8d3046128996b3356e248e2448c7de420d98b": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c5de4fee9a3aa7722f7d285c6cffcabbc760ea": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0c560bdbdad78ed9733cf5906595432fabb4766695333562c45a512de84f8051": "0x00606ba24a1649ee35a5c37671941444ab6d2b8a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895f0549f359ac15f6afa11cf6b0d78c22242802a2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000b79d6fea0f31e919301506d8c62c645949af0": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002c33c9811e4b478b1d4a2e4c6f60250e792919": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bca0e2071d5f0e59803828bc7e0d3dd67e4215": "0x005ca0805b8100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cdd4f0d8d858b122c56d54a8a719d7c76e4db0": "0x0088ee10070d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b78c8f3b56f2e4264792922e064afb51b37c4e58": "0x00809403057e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da6ff9f3390c3e28e47d5eb35081d2bff9ed3a3db244c46b29ed0bd09adc32f2b": "0x5c1c3992737f0ed1cb650835f6ae4d44763cccd0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339725e710cb23477bcc48cb54d6a329d35cb6a79d67": "0x009ea4c3e42800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005ea4d2572a2015e589d4412f4894da6fb4bea3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895852b57c0d039fda16a6c948d2689b402526497d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511bc1edd2a136522a0cccf62068956f7c21060000": "0x22012413e01a5b1cf021dd3a5b14aaf65ff97116880363686fa7493efbe9f93800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de0d92174136d7990f5ddc8577ff5ff898c9da30350cb244548c21f2b377ad412": "0xbe581d9e93e611f86b7fd67cc33ea7125187ea07", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970047b1aae6b63c54033f652a84fc05eb863ab1bf": "0x00fa46ced01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700684c55baee983062a207cca3d8581c7a2c32ef": "0x00b27571ba6a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b104f528a2f421d2ec9be3364b7f266fa628e2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3ca35e377d360676537c40eb6d60f5b5b2de856": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928931a7a3da4c0952b89144a7f47e04c47dabe9d914": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730aeeadd2dad9c66d74ca5c6b52d9d8d3d1b8ed3": "0x000cf723526800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928994192ed10285470edf1488bee3cfce683bce1877": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006d9acfd7f6917019a8e1f1f25cb8f48faf17f8": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899936b02740624946720db39a34ab4f5ce0c11ab9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718b453f5fa588d41497ecf34e19fd30ed008e34e": "0x007465c1f55500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893274e22d86cc21778df15836833e147b1894d3e4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d96469fe84419254dd3e2e10075b0c69a11bd362768481b7c527279043b7d041a": "0xf760704253f15e9798783e695e6011893b38b549", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974755d3d389180081398ce855382d5f03e6547acc": "0x0018b092324802000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c7f440d4c45c1ce7a295c788d9cbea9ff627cf8a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f60895fbebbb5017fcbff3cdda397292bf25ba6": "0x00da2e68a86b02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928944eb5b6c2d5cbe2d38f9fc21e5166f5964bc47a7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397185476974fb1f9346c90d0831778f958456bcd53": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898506d946cc63d1f1f3a303d68b0da64597cd64f3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a97ce748186008e51831f6753e40e6ee9e34acf7": "0x002a5a3c089605000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ada9f2058fada409eab656d7d017f54086499bba": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243075c5fec47d39bd6482df2cfe32a6d1f83b722b8": "0x00407a10f35a00000000000000000000062c930000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513a7dae00bbe4c9875ca2ffdd04ffbd984c040000": "0x2852dd1c93302c44657e8bab87b8c86a550e18c4a0dead775708bd6ff909b91500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a5b1ecb17b9ced712df12474c5588c8433ccb44": "0x00c0fd2831272f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975450bf5155e553cc022385842799d6a464a835b1": "0x00b832ae8a2804000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e8b9dc427650bb1136f50ab903b00fdee88e946": "0x0016354fe4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b75e5a1bd0b8ee7ae4bbcf5551eec80ae52a4bd7": "0x003aac1de83100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892a61258bf9cb93b77da65701e212c4f1653abf9c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928951a5356d5546a139adadf0a7752c4ba266dae69a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898f2d2b848ede60d9480631fe6a365cbc8e304c14": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515605b774d9865fe7955ef635a73469fa84080000": "0x8a76c7a194f0828ddfd4fe8f20120af0c7740b94f010f84df375eda189db399c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765e9bd9c64b29a79b286f4b2f8a3cb449c13a91d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897956952b9ea6540641fd0dfe110f071d45c835d0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bf1a4bb27ae3ced0991a0c60d49adffaa014779d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f1b8ecd32d89c484ec8ad5e216e573c03de39b0c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ff3592363b611cd701ccfa565dff6d1de23dfb2e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339770f055cd7b671c7d5f167c93b506f30ee46c9938": "0x0030494149a100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db0082cb409439012ffaed48a46ea0b190fb972f35c32263763558c2c4e94226d": "0xa4932280b37de5fcec32232fb378cbb24275e8f8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000e1841bd5780f77ebee2dd24a19cc47e1e47b2": "0x00bc110f2f2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fe4c20335a78abf60128c5f0a375a09d5b64e7": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928946db544038c59b826dda8d3cc8b72de90c86e683": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a8d40e52242e2bcb59b5163e4f7aa05ec1c7474": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c11fa9f82689aa0d4d41f2ed3e3a80932707b46": "0x00be5449b71900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51af35371c6b18cd0931a9cbd3f731bd1556000000": "0x3803ceb541a628b43ee926b45440e6be38d618b955444001639cb18b1b68500100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243719819815ba8d64ed7712c3005c8df49b2085368": "0x00d0bba2d557030000000000000000005fe3680500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51866a8e782d17d1c257ae1a499503206a79040000": "0xfa2db1b22b343a78c282caf8cf333bafc9e08446a7f1b4c78b36dc36522fdd0900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700da3fb304e2f3598a15b96abce88a619669935b": "0x00460467015601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f65a7c12c29867648798aa6a777b44cc3a9ebc72": "0x009c1a62e68200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b87487eca8ec9080b3c2650e1d3a83bbc07077ae": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006bcfd60159e0019278ce871a0a34bf54d9c585": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ba3b6302e0fd7fe3d21fe1d2ec3ccec915b505f": "0x005cdd841f9b1d000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895d5d65287605d949dfc3ce2691b6774766a0d3c0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890569baf12b57be4808c0539b9eb6b34b0fca7466": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51097c9830b9dd5bae5f687c94273fa724fa030000": "0x5e348817abb98cb962fc0780a47ebd471d9c318395fa80b4529a64cfabb2e32c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896db74596a7f6ca2798670cc82ac150a41610fdc7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f1ad9cf75089d42b8b56407fa8cd4914cf1453": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243c616dcddb10148ef5351b5b0c272486d15b3f629": "0x00d0cfdc8cd7000000000000000000002ccc5c0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007cceedecc880f30ab9f9b968e0d6860d51c6d0": "0x00fad0089c9e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339737356375fca1781c398d3a68924bc6e95bf30ee0": "0x0000470ea1b0f8000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282433310cb1ad03f5b8a93d5c673e11782f159a017ad": "0x00a0724e1809000000000000000000009ab70e0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f67a905cd6e24183abe1bd4718aaba22c520d02": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f26719804c82085d861d13a0338d07967af11cfd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e4cc4afb6dc15d5be10f9ff1cdb373e6cf1ee3": "0x00e23c551e1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339703fee733b242749112fee4ff2bbf7f612dd607ed": "0x00901ec4bc1600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d71200fbf01872b2e196ab9bece2a78ed0080000": "0x163b6b73f9e9a77c336cb7ac90510eca3bb7a3bb567fc62415b52ce3282b9c2300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d6110e8081a10caefd8ed1b95db4621085b55807": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ef59d6d8b11b8b7c23f9d6ab5043237a9ee8f3f": "0x0046e6548f7a01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cf5802c077d573e5b61be1380678ac83ec030000": "0x2eef2aee654d4975535f2701af86ba6d169c2c9a1599b16635a2a5e4640db94d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001835bf16df6bece037ee219ddc4870adbbc528": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009f7cd88fcaefeb56fc2c00be4f50ca8fd6d0da": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897ff48b76335074baa82f4236dc673b6c56a8a703": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514a0e86d5ab8776588af8c399d1c11176f5030000": "0x520aefaa9aa8f2c237f96957bc1858cce594c62126484c3cef56600e11580a7700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973518a8c749b8c46685b5bfbb5ac32932edafc9f9": "0x002e03c87cac28000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397756034a116ad26a3a26d264e1cf490a12231b1f0": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894341633902051568199e6436ef96483c49e72dd7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928946ac13adfb85fb7261d69153e73b006e585509e3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976052ed2407cd5e04f17216d9687c289e325e14bb": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a33674bcbdcbdf860db590db177e3ca258795121": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6497fc08fc439fd02e6cba9782717b3b1d123bd": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d590735c51726c9e24a446143734dd5ed632031": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5116c21a18e226b1381b232975434593f22b040000": "0xd682e2bffca19e9276a79ab0bf0d76fbb5ac62cc7938b4c3ec7463543539c87000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511bcdc19a60021a88d377b56075f86a0f4a080000": "0xb3e6c17ba16170624265646fe4aa82d140d20783c65972a712de76e07a59552900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b6f10a1b8aeb82bf4d1a220805387ac11a060000": "0xc23e44c4eae7d243cd5795c4e25170a40cd82a5ce426bd807014d7c0e479387200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5121204028707cbfd73241eb45044f3e17a1060000": "0x0ee153ce83372a6a2624bddc0f6f9b6235e85f576219380cd0d2a03eac704d5300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd0edd5db182fdc10042073db3a03c757819bcfaf39613e34bcec04b971e91408": "0xee009a16375c624ebf875040a1c0c724667ee60e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339755c1214cb709381cc47eb4edbd28d19c67939a7a": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba3fb82687f28ce414dcb4803d05eacacb697db4": "0x00882070a41500000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd0f33dbea6c78781e080606ecbee91c08daf0c684a8a11496d364f369e511b0f": "0x00ed2d6c16707836c6609b53b802692fe176db28", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5efbdf49bf5a39cd986dc91cc98bf5639e55c2031c9e00229d366e5b7efadd06": "0x24586e1a8a6fbb94ca745b6ceeb98017fc8de873", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac8eecbef704590852f8e75d87ae2da59bc5fc61": "0x00f20ea3029000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c60d96a54d67eabb888e162ded238773b44ca3b1": "0x008415f7400001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c2c1ce72623e05242ce3932ded73bdc36898f66": "0x00dee86e138400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005ff4500730a6a2a32b6add8c27abf2803b3bf0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928902e3d57578cc2ee4dcd3bfc43bbf0d550accf6dd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897d2136d6cc5cae6b60520050f1cc902abb8460ed": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa92a247b4699210595e1cbcfab051163e245ac8747e9bdf9e48c73532e6dd02": "0xf73226e1933cfd506c16b06b172e564bece222d7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397db5d3aa321ed9182afd69a3e1ac855073fd914e4": "0x003c7ab90c2c07000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8a76c7a194f0828ddfd4fe8f20120af0c7740b94f010f84df375eda189db399c": "0xc520b8c3e99de440a600168725914ebacc16b548", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d5f69c67dae06ce606246a8bd88b552d1dde140": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cf211b9f0fb04dfa9f7717ac2d614226bd1873": "0x0002d703357000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e087bc674e53b1b48ca0d8bd6691eaaea2ff78dc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900aec6e482d2ec9cedf8f03072ff8bd27850e95c": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824354036dcfa7deae92f0d948088690cfdfea648143": "0x008062175ed15800000000000000000098fdb88f00000000000000000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19507203aff0c53f3646696d6f6e803cfc25dae5d649a0d4f2775656419f2c9a4318584694bb60c66e8d0c8b96f502": "0x82104c22c383925323bf209d771dec6e1388285abe22c22d50de968467e0bb6c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dd083f4f90637b34f98f77c9c6027a0c78c6f2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bb0366a7cfbd3445a70db7fe5ae34885754fd468": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfc96e66c4ab58a38b86c7013ed317c808c0e8684a8e921db83280190aabff655": "0x00368ab2cb58eba931c52dfed54379ef3b56f79c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892c65722a0772976ce0ecc020f2eaf0c4468b919a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b55a1713236871fff3c17bb02fe5f3eb6a7d25e3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ee213d531429838906fcd09e48b7a488bcc501f4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b4ca18fcfe2bb2da18efed209373f50ad5060000": "0x88b4bf092b2dcc6e904f78261e8e40a9bd99f108b4b607ae2b9940cb6bef2e0e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008dc499df64ff95fd5b048b15d430ca0baabbe1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eaa40f6b29ce35d8f53f6bf9b2a7397e3d8475af": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7ee68da95f66a1211c7b843f161409ea7a8f9107fd8b8e29e1d8d6f2afdd9507": "0x5d8e2e6b9118484134a1925813e545b37cb89102", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972de237a350c65bf399bf853a3cc6bffd23b21917": "0x00a225b720ab00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700599a3e41a80ed4b6dc948a52fb52bba05ef887": "0x00922e5a5f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928975203bc03125befff8aed3b9fd687d8818a8b2e1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002ac73d3488df5bad2e9e70dc37db667371df44": "0x000a945bc10300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f454f6cd7fdc154be5bdc8ae57c9ef6d83c71b": "0x0004e8afb70600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a7a2179c90de5faaa539ef2f2d8a1d0f2ea547db": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973d022562f644e3f88a3ce6bfce0afc0539d421e5": "0x0020ff663d1c02000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2c4fa0b90e34cd788d2be0354965cfb4bc5207dca0e825b468e7c73a2c223c30": "0xcef11607ebc0a7535f23e0b7bc4eba5dd65a75b2", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5125fb6078eaa05729b355a8e40b77040ec1070000": "0xd460ce63649068b38c00c88f2b5b451e105f6e217cbe19c6a274819887379e6300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ad2ddf4425a05406b95be23d2d66c1b11844c28": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d930f5838e8f0a2e2db62535d767bdbb5da7ce4": "0x007a0bb5dc0600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5100b87f257781891244b39010790ace2432090000": "0x7a56dc6e96af40fefe5799aed949f2c53c7fe497f8d830320656dd6709fbde5b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b9282e60b61060488019bb1b41cd76859c070000": "0x8a64dca67c64d9361901a1415bfb3469b000d0bf7f1d439824cec71f8702215900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b43d777a3640c4b0d674668f57ed75b7fc84ea82": "0x0080c045b21c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896b3900179e0d9e20712ed41f8bb9ff8cb1e3fc88": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513d24318c6ec74d150e49a792eb796be147090000": "0xd0435f6d91a7c7316277378edb9cf826f46af1caa25b187ff9e16386640c600e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c65b45c6c2b417a7bfe7a1f164ef12b53749fb5b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f129a8a4ef740ad545508a30068725c058375c4a": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0e0cdd062e6eaf24295ad4ccfc41d4609": "0x183887050ecff59f58658b3df63a16d03a00f92890f1517f48c2f6ccd215e5450edea6f4a727d3b2399275d6ee8817881f10597471dc1d27f144295ad6fb933c7afa3437b10f6e7af8f31362df3a179b991a8c56313d1bcd6307a4d0c734c1ae316a103df5c5131813fa77ba4f8be88b2d2b4a47323d2011c9d987615f067e9e7856f0bb1f6307e043be568014eb4062a9bca4a255f39ed0be9205ee97c93b4b6ee0a3e2de329a70e2763438a1a757bf6dab945dcaededc7455a7fcfae83def07bdc9974cdb3cebfac4d31333c30865ff66c35c1bf898df5c5dd2924d3280e720148b623941c2a4d41cf25ef495408690fc853f777192498c0922eab1e9df4f061d2419bc8835493ac89eb09d5985281f5dff4bc6c7a7ea988fd23af05f301580a3ccde029459535c8bda2aa6fc2d97af3880409010bbc05a15f8d42bce8f0176d3c7d33a7ca6e152bcceb20a75bf67dca553cfe1fa0546decfdab25177765ae078acc4f2aa64faa0c97ea1f8702fbdf1843694734eee4d7c65c5605c2f81271485809fd84af6483070acbb92378e3498dbc02fb47f8e97f006bb83f60d7b2b15df72daf2e560e4f0f22fb5cbb04ad1d7fee850aab238fd014c178769e7e3a9b84ccb6bef60defc30724545d57440394ed1c71ea7ee6d880ed0e79871a05b5e4065e5ab03e0bc62a8fd3fded0b09ac04c6192796873b38abceffdbd1548f35f61aa25cc78808d9ffb966aaa53c3c399cff7ea0b409dc8b42908b9f2da6d34c352514f13a09505d4014b468c1d3e394002832d9edc35dbbae1a7a6dc96025d47d5b88ee494d719d68a18aade04903839ea37b6be99552ceceb530674b237afa91661c151c11cb72334d26d70769e3af7bbff3801a4e2dca2b09b7cce0af8dd813075e67b64cf07d4d258a47df63835121423551712844f5b67de68e36bb9a21e1276c694dbad86b8de9c1c9947e536b3391b77caaca86a23195a2b111b24b0d516450e91d8b60377c58f1e8dfb6236dece92917f1b4ee67d2787ab090c5f8d2200f74b919094e1fca66ed767766aa0a91025b6a8b955bb970912900ad4e413ea93682104c22c383925323bf209d771dec6e1388285abe22c22d50de968467e0bb6c680d278213f908658a49a1025a7f466c197e8fb6fabb5e62220a7bd75f860cab6236877b05370265640c133fec07e64d7ca823db1dc56f2d3584b3d7c0f161583cfc25dae5d649a0d4f2775656419f2c9a4318584694bb60c66e8d0c8b96f5029ab54fd64223ac5dd0c547efbf0015944d1bcf8f4ca721716d8922fc940c9a610a7d2ed5da6a62c32ef4477bef2a1ba05c5feea57ebd44516a8257dcf9a3b67be240d12c7ad07bb0e7785ee6837095ddeebb7aef84d6ed7ea87da197805b343a8e59368700ea89e2bf8922cc9e4b86d6651d1c689a0d57813f9768dbaadecf716c52d02d95c30aa567fda284acf25025ca7470f0b0c516ddf94475a1807c4d25b09bbdce34c5bff2f9f212118c05296db12854ecd09ed0eb0dc7714c9337ce29cec7e2d5e28925ae9f906e5ebf1c81adcc7e524751273a73a278f472d863f5324c0831fc73ca4ae4d46cf82e74ad01549973d132795c579d40eed490cbb01524", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51358b305399f3902077de1fd8c2d204ea6a050000": "0x5e160a7580ca586ea01814a9fcb95f99470a814bee39a7adb651cccfef60b42300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c60cdf39e74013724f9cb7893a61e45897080000": "0xbad47546eeef76ee44b91a0084628b6b841692ef6b087c62d043991c019e631000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970007186e9b4a6d02ba04e7b7504173a64814387d": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5151c0c31650d67b9f659ad02c1f6ea4423b040000": "0x06e11fd0d4df6c4765eb346aac47682cb7871da9ecfd235255f6eadb8392b20d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de804b725c80575d237aff27c784f805903dc0a98a108c46f70486c9b49a34e28": "0x07dc1a136ca9cfa640962ec0a9a8332f99b0bbff", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928939634580a5670327b6f4f925dd85f2bcc2c44c6d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbc309fd2bdd98d456fabda1bf024664ad14d59f052dcee610e47d8db622bf701": "0x00a3b9f63335f09ab460319dc5b38b9f7029803b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767db7a2aa35266295c4e478f2f6f1a1f6663e0c0": "0x00bc915c481200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de8b4be3ef901eccef4c3abe01bf1af20d6685d42d644d1c0a6f739207dd9c068": "0x7162bf64f3d1e899cdea224458af61a33511ff42", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0b7319293c3508cb16215561b7f2ff539bdebd3": "0x00a0724e180900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c114eb5f530b857ba46defa23cd1afc669080000": "0x24e1cd7f14516acf2a8ddeedac439da4b58536cf7ff061690f7bc921e1741a1d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c43bb13f32b49aa921797bd8a391866cfd3ac6d": "0x005a9010a19f05000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7a73cf30748f8e2654e678381901e539062e86ed9c56cd51a057e27dec035329": "0xa0c59e84c73e9f41ac8dbc44eada4bd908a07f05", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339749fa2629dd5ba6ece667bf6eadf174d2c8195cf4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc8e26d12f564d9430977d9d4528b6d81a7e965354fcdee3dbedbdb3366c65046": "0x2f45d57c49adf2be37f4cda720141fc9cb6236bd", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339761436deba951a9f929c5d7f5d9488204c2037aa2": "0x0084602bdb0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890003664d63acee3b899631c4ac4615f402430330": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a8b5bb41b4a1a97ce7cab8ce22183024c57125fe": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f9d17d432948ac1a523ae7d1a16e18903705f0": "0x00f424648f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004d9f28eab5867df8ce500efa3bb8a2354b46b0": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824373361bd483cc76d6d0681065e6ddb25e84ca96df": "0x009017ab5d6b02000000000000000000b63dea0300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da621946a1439a0a376cca02fe2883fad7aee68a4b93938ba4089a75bb9d60e5b": "0xd6110e8081a10caefd8ed1b95db4621085b55807", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ff27838e63649d23e22c115e15e5a22ceb7a680": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e4b424e1ccc6f08768c921455f83181bacbfe3f0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970048d77cd53479c2e9594d55f058a224041c11ce": "0x00ae6ec28fcd0e000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519f5b17a59e074a0d3a699b9530170e7b19090000": "0x6adaad6649b233917f6b7c5f5ab20c229b2b2520fd85ea21cbc2510eb5c40a5200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513f1b93bc223f3052b57da913e6cbcd9e9b050000": "0x3c0189ef9aacac36959a78f72da2d5a49535d5b9a31845b820c0da2ff4e2660200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002844ae6b76746980ce8bc65f409abe021582a9": "0x004080ba809e1f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243cabc87c953dad294fc0ed22c563bac10fa8e3ab5": "0x00e0a38f8d1008000000000000000000b5cd0c0d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bbdb18494bba1635fc00d53735c06eeb171908": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a45d72e4ba11ccc796d37b6b1d9518183fa451e": "0x0032cffaf00201000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514468a4676c45bb3171f4245812be4b0e16060000": "0x78957d2a1ba4d3d9890e2ef1bb3562eb0774075455b7be56d0ba88eb3bd4094300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d647a9b6cc579aafd3b0b1a04ae88f2dc5724b89a8fc45042679e87665e177200": "0x00eb3893593421571007c99eecf18314b37d2319", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddcd52d8332620b371c24b68a5f8f303792981975e817ac1e0e0d5a1034e1ae1f": "0x36921aa381ba281dcb6fb6489461c2cabb8c23db", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510d4a3cd00563cea748bf39ad093ecc73ad080000": "0x1acb59938083cf7d003b8cdb348e28855feadca45ed08b49256bf8e13471d46100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978bf1c1e68d1bee9a5d188c2b49939acfd804fc4d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000b6274e5e9464df801fcfd8a9fed607086fbb8": "0x005a915366bf09000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004337ca7ef0391b38f913689626697307aece2b": "0x0018ecb616ff01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eddd2fca63445c9c60a720cb40ea47d0218b828a": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971daedf70a4ec0745ec4968d3e29ccbb4d6001109": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d40c1e3c54b1a2443b533b14505b267c1329a25d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b4624dca7c8be0b12e1f883cd5a64da42ee200e7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928963a673778cb652db8fe7b320da78842e364c40eb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928969a80ca39168c9bc6761b9a326c6f15735139e0b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d12c5c9b9dfc7ddbc627c60771de9a84b552bf1bd48e9332ff8abcb7cce87bb16": "0x279e235500d1b882c58d2b679ed5253b6e3df0d3", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db6e326b0768501c103f52fa0e2011501053da8b7a8ed204abfab34383bdae84c": "0x55479b40703db085c9abeee0d45fef0c61b0098d", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5828b1463a98785b431f8bfc4806215f1d062aa098eeb76b09a80fd9e63c9d0a": "0xb43d777a3640c4b0d674668f57ed75b7fc84ea82", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c49b7d15f4b1fc5beded08a2d77d7d57373f3d": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eef5a1f6ced7e72d0c52f342fa1cb6e8cc5fd9a9": "0x009657704f8a22000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f7a2d983c0ae1613f4b3c50dd85965a81fa43a49": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339713376a50540351f4d0242e20256e857a80bc86b0": "0x00be45120a830c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282435529ba8a2dd48942abc90f9d08667b4e0e7be69d": "0x0070ca7d0f550100000000000000000015e5270200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898a7c2054d39cb60856cf2180be68ce2265eaffe7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc4826569e68b7eee1b5b93406e4951fcd7ab6b40be519a7db5c6732f66da1149": "0x83b16a18f7fd937545ce0a72341bcc700bc72c69", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740095bd940a96c8b42abc9602a265071d0ef82c6": "0x00bace6fd90a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e5e500d5c726fe768ca583c996e244d0d809a1c9": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513064ac819e95dee52e4303882721922dc1050000": "0x4639d2b10d88d41a4fdf2ce50a922e9a99477aa5500316347f2036dda7cc805b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512f1001e89a406a29206d368a0e7176e14d040000": "0x28dd13379371ab7ddb0b1efae7ffab1bcaef3b3cce2ad502992952c1b70b9a1800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d13fc3ce8ea30f518e4ff96b5a74318d31d7239": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006d21a300eeab8a54eb2ef797195f60b2517e0c": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002a6b8504b4aa93bf79f1c8bff1fed68c591380": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300cc7693fe047247443cb52fda4173543adb8843": "0x0000c52ebca2b100000000000000000030fb711f01000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000b07ee73f21b4946786178085fcf66f760b69c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cb055d7ecdfdd1a7ea22db2b5c64c5dc9c080000": "0xd485ebc07a3913f5734c389f7b74a7d81f62ada7262e22d485b1ac2c640ca64600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774d452179482b55e13d4382a7cb9fc74392b5e4b": "0x003aec118e1b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c061223361f4e8b4a71fb7837fd8eac1bcab9c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928952e0f7339c1bed710dbd4d84e78f791ebe2df6b9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900edf872c332daee73e6d6885fed66b03f1885de": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f37eefbd5d24af0a94d743f3395e74612f060000": "0x04b32df44ba1c02abfda2d4d9dd55b3fc4f0bee5b136b7eee836787771e0211900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824343bf5419c4eb65b6f8cd55489338ded388c71b62": "0x00006c34d0f4030000000000000000002fe8660600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006a1212d2d3e63753368cbb4116ed4bf3719e64": "0x0002d40cf16700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ca6719bc9fd490cea2f94f000a3a47a4a5a498": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6c28acd0770917ad6b838e8b3dca4cfeba208839b5459d90b7b375193da1674b": "0xa3cfef97dad26bf0e3f7152edb74b84a278c123b", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e516cebd7b5014f69a56b310c480ce103887050ecff59f58658b3df63a16d03a00f92890f1517f48c2f6ccd215e5450e": "0x000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397205ef96ca87f9546f2d241ce8dc949c49765e4df": "0x00c462cb9a0e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339757f0c073f9954b81dd7de5d4b33cbcea46500d8d": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dba1fc21a2eeccf7b3437dcb9d4333c6da2283d46d5d76766e1b232a770230566": "0x00d5ce12a848bb0d982d8a07ae5c462f5e9a7199", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900928c48cd1e36087af5c06ed90b4a6cc161abde": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b59ac37bc3e2ae0f9d32b6751e516eccb38732": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c861c2296e9911ce4a1cd4bbd197a360f8cfdfb": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a2061e6b87d97d99221be7f5b47ad6c465020000": "0xe073fab94e8c03caeb0da108520998cfe419f269d4b7ae006faf2a55991dd81800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009bb861090ee8778e674f54857d9fa5e2f32358": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895f7932b29b98c93c7844cc0833deff8b0109f958": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b2921eadb2ce19c3aa97d1563333060bfc472a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d590735c51726c9e24a446143734dd5ed632031": "0x00c06e31d91001000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890001343f03e9ad77fa47f674c4ff59d5fa11fcb3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890047522120faa210d0e6722c57a5b1d83c417950": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e629f5ed94561a2e8a2572b46eef3bfb4419162a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5144ee40197f5db720025dfc8039294a9a9a040000": "0xb8e2b3878594576b6226e0050abcfbd96ec61db33f60b5541e3adddb3eff284c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243226c85b4f7e53cee040b6d2f45f4fddef5d97bee": "0x00d0cfdc8cd7000000000000000000002ccc5c0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5813a73dadc69a6b1bf781c33e3a7c814a4454981710271f167757f60c9f3567": "0xcc85b0daca47936a407193940ba2ab7414970818", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3c82ab06b794c99f14a161973be7aa6012568b1c491d45ec969ed7420bcfaa59": "0xe6ec101524276a692f4a4fd0a2f811060cd3d434", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700de78cd0ddc98246466f7fffd6cd96ececf7430": "0x00ecf4b0d90200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977da1f36b13c74e5f988f806da14650b790a54b4c": "0x00208dc1a0b904000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890038aa4c51581fb226d7a515c038de9796f41fff": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fc8f49ee403b661f718e8b561813d055e7d8b76": "0x00ba080a2d5b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900470a170ba243e44eda167e15063b4a96f25aaf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897f2981e8a482c36f074440101c3a1007de7048cc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cc3fd9c77dfe29e8d63f42432d05e26cecd97d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928987b1cfa38fc11bc6ba0794e44b8fd5cdf98c7640": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b650393b228dfb785b07f149fb213d691e49b33": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897a419133257993a9af281933febc870657c764d3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894e9763a3ac1928e281c7776b41aaa83b558204e0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339747b340a7cd29bfa96a17c1685f61a67f0c7de422": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b01dc922ee206c3906accf74e175a5fd38ef5c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928949a4754c8d01ba67609c0ebd6569e18679d43abc": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc06510f1df698ee3779298c8999a544fef1c15b5a805068e0ebc056d24965201": "0x00f0f772504eca495a1e9bc3b8a1cec2b639c9df", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896d6fd4653efa8efde0a7bd582adb2d0c8101c930": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc5778652ed1b557c3e495d505b76ba1c87934d040a014005468f199c28bfccc9": "0x1c1b9adf120f8247211132d86a8b3c9d04dbec26", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718ec44fb47a4014261d7617347773bf27b8e2e8d": "0x004a61a31c5e04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793011e03417d775496e3e81c5ba87cd973538dab": "0x00901ec4bc1600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8b3219495b480547011e7eb4c773b6b1778077195169a4e5fb16ce6b553b9b0c": "0xdf5aa870ca48f1dd80eeb75b80b7d2d797d74ca8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d517ccc6eaa9380931987daf0ea1c53ce4ac4ca8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514df20c2ea6de2e21af1c291af85e3833b0070000": "0xd2f0789cefd1e9c0432e8bfd47c4f1ef06b0a50e1e1884ccd7e1bf263c53af3300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289287bb445456ee7a2ea62c0a8c0de60d6eb41bf3a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890003ec6a173a7f45631ca5d96bb5b0a3ecccb5da": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243ffda559dc06f88b229af02fdc41a5a6a48127aa1": "0x00c0a539b6760100000000000000000036595e0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700484a2fe88db28bad5aeacf9aad06c476542d92": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928948640126abdef6682ad0637024f814e3e40196b1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009715b79dcb53d3fff43ed82c11b2cef7088730": "0x00c2c5c6860c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397151712ac05d7df898940e3be3ccabf6d77cd4150": "0x00de0629a33410000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cbb01e33cb0ee6a000f9f334858d8acb54030000": "0x3413070fd675fa96164a98442f0cdaf50d6e70c25de43a5268f987f7cbf6742600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eddd2fca63445c9c60a720cb40ea47d0218b828a": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824378f5234552ba1bac0a945d5e5bdfb56d84d4931a": "0x0020e464717e150000000000000000005be7c72200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928927786aebb2cd05b2fecede13382aabc3a838c69d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397238593df591076886834b28306cbbf83b333d924": "0x007403bcb30400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895b0f6f73022881bbf0516b30d182761a001b7244": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339747e90830e0665a6935ef79a72a27db6c23e00228": "0x00be4467800100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd682e2bffca19e9276a79ab0bf0d76fbb5ac62cc7938b4c3ec7463543539c870": "0xa4841dd23a0c6e2069f543be8dd5db5442f62cff", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397462cc75caee4d0be283eeddbc2cd5698b9880b91": "0x00301a45ba2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ef8921f885101db8aacb6111e65545e244090000": "0xdc06551a8b6f10345ba4675109499b12443eeeeb47e0f8ebba2772815ebfd80f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ccdecb6fb16e73a9311e57c75beef3487b3a0b08": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fc6e2bd34595f49ccd77ef257810d6aa9c4941f4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a3b9f63335f09ab460319dc5b38b9f7029803b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a8c37be0bf0e98ef58010178b70edffa1b070000": "0x0a5b47f605e7f1a0cfa91371ea887111a13a90bef3ed321c1c821661ebd8267900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddc06551a8b6f10345ba4675109499b12443eeeeb47e0f8ebba2772815ebfd80f": "0x847c5586665b81798aec196a3065cdc577a013dd", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a0d9967935116cdbc4ca46dc114bd175c7eaefb8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c520b8c3e99de440a600168725914ebacc16b548": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d229edddcf6d16c5d5438aa50b68c67ce9a422dfcbfe5500650d897c1bd50e042": "0xcb431327705a1ee54417f8cf3146669ea52f3e41", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd408cbacbae6abf32dbca24ba4400709bcca948": "0x005ce2476b4302000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282437162bf64f3d1e899cdea224458af61a33511ff42": "0x00c029f73d540500000000000000000056949f0800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc2b8dfe759e221edee35ecb51b15ec454425d1e772d224e2efcecda23f7a3c5e": "0x70bc832c319132b534d1e32eb24a5a58a29f2624", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004c7f45a2cee4336a07480fc8fa78c101c10409": "0x00306025659004000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700692c9b1e40a8eb213880ac4908eb8cfaf1f598": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e73a25b58bf440d8ad53eb773f412a4e89e22719": "0x00881529b38401000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000d9e4a0c84a34414c20b308ade8f9c048218ce": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900732c6677028393e3bd88433aa4c221e1d4bda2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6a3ad2ff813cdb72fbf4a76d6a9a7bd276f732e": "0x00ae839eeb0200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51266d6efcdfd5c4b8e277c4ac5a0a868300080000": "0x7e9182dc2b0264895724fdc38238d5a20a2904885d35ee292e2b810fa5313a1800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894a3585a53e68650e03cebff3c42ced82c21ba6b6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5131c7375a0cc0700b904d9ef2908d318deb000000": "0xec0f3c02a519e687645f6d29219695eb2461e01ad6813ab7a9144aa85e4ddb5600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c84616c13fc8266181a4589ca35f2f2463b0e4b3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5163f1697207865578f05e0c894514a30de4070000": "0xaa41228830918cc1cf16e50df86ba154a483d77ebe3182bacfb876af4fe9ff6b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971bbd9ddc49fd2d67462d0b1919151ec9aa45fc4b": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a016496ded64b9724a571f0703892fcd5a0ad47": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2c2c26961e5560081003bb157549916b21744db": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b03d651170ceee35729aff792d522fd952cf94c0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289be7d69b9aec64673f2ccdb97c24bdacafeaaf2a7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c20dd03a784a16714c24794834e04903f9395a": "0x00026c488f5f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970052a07979799d203c54b44b3544a2e1bd30cc9a": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799d1efb41a2c5ce8d000599595f598e6ae9a8356": "0x00e08b22cad305000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900240495286c0f4420b6cf3b7d98f50682f82544": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928999ce75400cd94e1277047d0913ba8e6921aa1637": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cc85b0daca47936a407193940ba2ab7414970818": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa98586310c2340a471a30255b03bb4736205056373576e53c5062c1a80f6426": "0xe0dc528b979898218393f18a4568c69476640918", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512fe32d480dce124d59c57ad5b36663b699050000": "0x7c14ce5e6afa3158feb921d32d89d236e26b9485bcb995402108495a7574f54700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c90480cd768c13eb1be84bbc0414883bcbac27": "0x00b4ddf0840200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f0be27337ccc1182df91cd4075af2f6dc7a67c5e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f54663c66d90010e39c7c5f3124b2965e5f0d069": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4adf51a47b72795366d52285e329229c836ea7bbfe139dbe8fa0700c4f86fc56": "0xe7321957993cae05c6d5e4282e83d1b09b57caa9", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df058d4c46a6efa9894fa49e07fa14d756b3934a65ce6592cf3ff441dd527db2e": "0x081754b0a1468f7ee643f1ff9896174ddc6fb4b1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006307f7e5034af0a325f5eb706ec2a8dda67c09": "0x0018b092324802000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928923803954be1a85583e00ed01ffc8d232edc87e1c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ed825d6533c5220639bea97f98aeba7e02b0845f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892fc342c182bd05c93bc824952d36fb4316392684": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519daf9dd0973aed61edbb294b0afc7cdbe0060000": "0xdce9c106990ee809fbfa94214d6a5824b2a4c9a8eccde773c7de16dacc66d02100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d58cbb85bc4457b36fe8a2b28cfa63f0dd44bb00745db796b84e2699c4a9a0071": "0x0052b34370f45aa1a3d93b5837975bd9e088d6c6", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513c8fb2780a43d1076cf7a9a90872a81c84040000": "0x24f8b3dbcb13ea214b670cb611fe7939e20a23db19647485e01206502e64ef7b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dded7e8da518feec2fcfa346bc021ea2d31a042cbb4e69838cd6edd8651083252": "0xad5077d22fd0309130fc1a1ce0e655ce4de9513a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899fcf5f950cd5ff61ca37042f293113dcfec1ea5f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750d30f8fc7564e1fd231e160169f19e864c3a641": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dd82457a6fb1ea688d0fa4a2a2151368619403": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e8628d1190bcede69725c4e920d9ce42c23ee29e": "0x00c4463cbc2e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f963fef4235744c3cd26d5a3b155534f72ec6d23": "0x0040e59c301200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b19175a4b74f9227ff9f1f0ae60e4a2cc7060000": "0x04f320fad7173da9ae78391b0d5322fef4fea16922a97a699fdcd83dc5ad9c4900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5139c2830342e60b62b4d9b48f9f1a4e8f95040000": "0x4ea6ff3e232c357928eebb2a6548c2efcdb4c6e14d3bff63f4641ff5d874764a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397012d78b8ae3effb27d1a177cb14b2776562aa192": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce7ed9f16f6ae3a25599f03d4f65f8d3bd7664ba": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289651547546b24fa036b9c1b1c2dc8b2ae9c07aed9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fe2ebe8b791bff2fe45927e9fcde8a5f9760e249": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d80bab9bae5457b9bd180ac52e9d067e4c3a365d114948187d991825c6914c307": "0xe04fba4d693e414f7252ff3381616d711e13b992", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c61ed74017d66eceb5eee1f20a012e4774cd79f0": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbe6c22b41a47d782268a2d1eecf5e623ae6b984591db92f77de07a27a447f87c": "0x0c31fd4e2f78849537318712136cbf7317f21828", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcfe4380a6592abb74ab7a3d270f87acaafe118d": "0x00020edda97c00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518441af73a144f72032efe025fb3c9ec9de030000": "0x2aafd93579d64984844551475573904219cfdc9bd7a7ccbb732c0d7184bdce5c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e908988fa7712617b50643886e51ed6ff5333d6a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897d5b0da867de47e3400367d80d606d08f064e5e8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dacc0fd259ce0de2829b38a0765970e7ab65346c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510cd2568286005ae16fda31c2742063c3f1030000": "0x4877511245f8954e48858da743b9eb3544681c27ffd8802c8ea1669e961a2b6100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5177caaac9e8db15f78c132fabf1ffee33c8060000": "0x9c2a6baa6ddb14dca58593ca97531705f61781e9e6d7eb181bf8d0bc5ccc162e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f514161e2daa4571c9933c440fb3af6d08020000": "0xcebcc2ead5f62db0af2c326d9125d36c69ea03b3bdf88d5ecf79d53d8262656600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928922a0105994c3f4ad8c3e78144e47a6eff9976377": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928963118c5e7a405fbc2fabd7d2b03588488fa2c602": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c016f534d20ebfbe4acdec6977762f79317e137e": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339731c1fdc59cea10ca6dec6975e83f3c2f5bc629cc": "0x005a4a3ef00e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289088e9ad1f2411247868395d0b0a6279d92bf12f3": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d581e058f65025437bf5ab67e0df34ad454e077f5470d947969713eb76a036d33": "0x3c0bb615eda6512f1a95869a638ef9d21e63469d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d30ef809e87bb997989679572d1416d0d311276": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0484129cd5f6ade38d42fd0bb7ee99e1b77a287f1dcb20131319fffa6fec3b48": "0x1739e6e25e3da9107b7f60145dd2c8cbb76fc139", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d268eda4ec34cc03c815a14dd8465c0e2b7a404f56b6ed9399c363ac244fd6122": "0x0710c910d3d8061019f91bb90ccdf607898e135e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339755b3230118d3952b35b7965b09752dd299a95706": "0x005c57d4f6aff3000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289deb44b42a9d5c331e0e03d3fbe9c7a9496872d05": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893e1404e9af1c94c9eaf8fa92e2c2e1a936ed8701": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003d1907558997ed87601acc550e672ac01fd7aa": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e19cd2053003ffead8c5b88c77062a6f7b080000": "0x2945102218ec28141fd0be4fa57b11ffbb0bf25a6732f2aa68fb70653321b66b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51da31629b2f67c63e23078928578d264ea5070000": "0x3fe95f3b54dcb987f29f3de7c979a88e9a8ab6a45c47f0c32f2cf14fc1d273f000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700882015100d9a8165e33467f695de68d115a172": "0x0084df6214a700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f36700ff798394c4a58fe861a4661f5489d90735": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289654ae9a08e15cea8d7d8bbce09f06ccc1cd8024a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fb2815ace3d144b7381e2364e799abed8c0d6ec1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fb2d2432975267c79d283a617c62324a5b0897": "0x00daf6518b2f68000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de626934768e68509f3b657372165e6f98fdefe615cc8e669d5bbe033a6478556": "0x9ca696ecc735a7a734fbce108cea75f8e982cfa2", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51891fc62100b73f034f04d597209789f2ca040000": "0xde7fc29e54e79d51f4a8c5d54f67523265c2a538a79edd0a601ee16cdc1bea3a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970081ba2106e5e4a6ca54e9dab7ce93d6f95c095b": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970029dc8d8ef8c287ad395732dbe5d5bf951da820": "0x004686d9dd8f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e94ec60bb2c3c196338c7512dd5dc87839aa2d18": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898285a8f9373803328ce82b909ed406e7b88e8206": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fc9f2eeac9e40c581c898481ba696b0e6300bd": "0x00d22374f95f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b6251493a6a0a97029c8bc5ca39ae29778040000": "0x8ea678d1d866f5ebe84e3830ddaa3df3c1dd58e11be510aba931d36ce40f8b7100000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcab49a2738eeb30896aacb8b3fb46471bd": "0x04000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c2e763a5924cb23fc77515a19ec3cc7e7a122250": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d86fda27b3c3ff7a15263d00c70005336bd9c68bed4de5c3a0a3aa647e837ff48": "0x801aa940bf8ac12429d35c2cbf0a13b61758bd4e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fff7e689a4ed9668c9207f55c8d68bab1cb507": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ee13480f5e260b749022ff1e533a22e14e48c083": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339703197abad8079143a69da8d037b6d69bca469bcb": "0x003036d4980900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51db22ab22b9c2c668f1502fbd016965ead3050000": "0x524106d11c5b394e41ca464f7bbeccb2c44e1c9d69ee5c74b87074fcd9a4984a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d3bff828bb4c616bf9d526a3551987b8f7000000": "0xe4cd169b3bf263d47e5604fde85081d4eea4fb30ffbca3d34d45160cfa9f7e6c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339721ef1af339cb2c91e55acbb82863552803e1fc55": "0x005880abe94f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928996cced3c89d0565c7075aad1b2b19c49f449af1c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c5b5f898ef9dfd2971c5fc2f145a4c05d762f2": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339732c6220c6116e3666c220ffbcddd2e7ae8d78c2d": "0x003219bbda0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a01b1820b48fa4f1866f485e6351659beed55d2a": "0x00beedf8051e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397029cd6683f849069fd70d6e9e7ac4b3a71cfe9a9": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339714ff1233fa526a1c2a67640f637ffb1bce5df502": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000f6cdbe9dfc875008e23822266cef6ff78124d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008d723ecd3298ecf004ea846fc880002822cf59": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339784f135b9ea6cd15016bc1790909a0710ef2fe918": "0x009ab138061a01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397173216d1fd08e76fd4f25710d2849091ce2fb026": "0x0004f52ee08d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896e33fe6344ffd1fb1aa35d7823021a99e10aa1fb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e2ccc768dbf601ace5bfb82591e59297993dc9ef": "0x00a4289f320700000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7a4cd6e585400fb82dcf09388a3b6eeb62d4803f027e7fff775038ec08987953": "0x03224123bd06444350b7d75e2b080ba68598ddc9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f18fa0631873e56df496a05d96116fc39da12b0a": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700adefc329ef84f5ab49315271912a1ca57cc18c": "0x00de8ad4c54700000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd0b18c9b2c9b480b43aa8f03d542c1ee68692cd42aaef3c46b57ea19cc9e6c6a": "0x3be58c29b09669c1b1edd3153b0872e3cbcd8492", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900de397b4f819087f0d36a12f89b4c0eebad2dbe": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51da23d1c6d9fe22131eb5e905f240e077a7040000": "0xa46b7c2ff66b1247e437df5b9eee7da98a4df42092e82dd14f74b8ddf00cae1d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339734cc2861eeb213da8bf366becdfb319f16aff12c": "0x001ad45b8f9900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890007265d4ce76f580ccf575ef78d9f63181eaec4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397029c5bc3bb8be76487f9b75b5065a6f57ade84a8": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397344640acab3fe1ec3b3f7af2e9b7ea4296aa7085": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b72b4ef3d1bc5158136b21f91e44bafdcb8faa60": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971cd65f74d01ecbe6a63f131c3bb140a0e0a90955": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be1c575e4d30176199bad4b2fcf7217a6df20f16": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928982e2b7d189a81a251eaa51ac31871f8c4b91dff4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7a9749cfb7256e7e48edca7a6911018861ec6e26d9eb2c81bbf037628fefcf04": "0x6cc5d8a4f16d0dd7122bc1d2759703ee9013c237", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002537ce06f4d8d67fa5c81c75dda886efb646b2": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001f7eef6a5b727738156deae8f0604d92df119c": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a2da86405f0032f5ae8337cfdf47f067fcafc67": "0x009259f2f62000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d44dc7e01917e80374fd8bab942b77bbb6dc857b578b681ce199cc524fd8caf19": "0x9588686984edb566be1e1b5c367aabd49aaa5522", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5189c7ba2998d0e7af5d5a234ffedd5465ca070000": "0x1e578c7d15ce8a11f4e713e63f5465ff324a3a856f7ca64574dbd704597e72d900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6ed6a67496a5bd0146cf3595ad50be243ef788d6ef3bde1d66e9783499f80524": "0xae6916a981c3df939efe41a37045ba2c0b1daafa", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970037a6b811ffeb6e072da21179d11b1406371c63": "0x00581193490000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b792f95c5d535942270423c12a735beace8e36f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896b12c9b8714c27aad069301ad0bc4c0cc416f1e7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d36e5192ceacb95e0919a64940e90ca47852b8aa1271e2d4c69383411e72b2702": "0xa2fb944dd8930532d3fb08109bd7a46cf07a75d0", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2252a1d50d94240bd4e5b32ef5c118d59e864a8add6e2d30fcff53b939f08a10": "0x040e5e95969b231eb8dbccf2bbe7b339588fde54", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005b75905e8b686acbe0365d46ba0ac2a70b3160": "0x0066497f817f07000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895223d8d88e106df03f953b6ea1fbc11db396f2f7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896bd681cda54942050d622af1e35e6e3054eca95e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891fd593bd99ed831bb189c73ad7290501597199ac": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5115c3d9f49d05aca1b29d09c04bf4a88ffc050000": "0x5cbf38076b2d9b9faef9f96907d266d5effda6e8458ca6f4287615089f05502a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289edc6c4c1ae525da2942fcf03c7b98c12391edaed": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec3af4ace34c5c019a1bc08de4dd22df31f0895f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970076df9bcdb37939908f00f66c2d3d83b98345a0": "0x0076eb7a9db700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be581d9e93e611f86b7fd67cc33ea7125187ea07": "0x0072ef4755bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df3a6a9b086181a0005de487ea5fd72fe7066d056d7c7b9d6572e0f609925f3dd": "0x48973b94b0273ce3d54774144b4941996bc62556", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51edeee793d8164da822d6e40d569c2bc8ea070000": "0x567fd94f85be51453babbffb0162adbdf06d3887b0ca3aa44e5bf57587190f7b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890011aba70dc64ecc7f869f9c415c3dd23642eb2e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896e8b688cb562a028e5d9cb55ac1ee43c22c96995": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898e6fa447855eb59c62f23e3df8a556b07a0ee4d9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de406ff2bb0c4bddb3b8fa92cba3c11042f2f83580a9ebfc2e5fe0e4102cfd70b": "0x00bdc59bc934360468b13b8a94bad99871df53ae", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d90a14c0e9d0fc3ae3a3398cd3a5735deb453da1b09c3c651c7dafd2a624f1a1d": "0x001a3929769b8f2f809aad807767b5e2c0a9e27e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d52b2685e43a4ff9ae6ff3476f2bdb84356ff427ab671bbcca1de6e486881e154": "0xa184d0a2f7d54d4552bbdcfc10d287a4c5bea5aa", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5161f76ec2710f6f2b43ffdb795a2bd2956f030000": "0xc4727db059e79445c819878fb43324451122df130dbc91b177e62df8ddb8017b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512c1d264fb654bd7d676047dbd0fc92a21e050000": "0x16e27023c7dd6bd17320aa50c58b1a07410011070add2d5636d012a5e942d40c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339724a7eaad0d7f13d1999206d8c22f926980a12ca6": "0x00f0cc775d8600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004e1ce5cbd307c6242a9d224693a4dde031d519": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002e2b254a4e3877c6ffc42106cb4f519e6ac27a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aba3761ab14f87094b3ec4bec2b49477e65f9bc0": "0x00564aa0b30100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b1190e1c02cc7db63072609b9da9dae5557f478a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744f4c9eb38dbc24b17fadecb8033c24c70e7d836": "0x005a9010a19f05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785e96a824790b12fe512397506d97038500b861d": "0x004ce66c318e28000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978889ff5b6323e71c28c26d2c34b8bb52654f00a6": "0x008e0d1eb5401d010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c81f502e87e7a0236ca1616016d216b81b91fc61": "0x00c4463cbc2e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac47d44618795ab6924305321ad07000cf52b350": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8cb954a659869c053877b65d7ebc7c30e97a7ba696432a649f5f02965187295b": "0xe5664b93ad268393d1f695c4180993e60c59fc3e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890067be6b1747f53e8c03246205773f4622b858db": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289198054b85123c69a58423e20437a9190b56ae823": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898533a89796fe8070604197679c3e250ea2a88a4a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e6ddfa467463a61a727a6f163f470ed467080000": "0xf04861121b61c5f1251e345b3bdd173cd18a89e4641984c7f051d796e295e01d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ca2f2067fa1c81a353a98e49b7085292f3526969d67362080bece38eba9c93d": "0x00368e2ec353e7dc90153075954cd3dca551f35f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006e97e28caa58d3357d070c9535d6cd06bd875e": "0x0080afe64af904000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b2272bea66948af04edeecbeb0171521cfb24f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c60d96a54d67eabb888e162ded238773b44ca3b1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ad4551742f5718e0af5d88119974c86efc8b83bb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d4e4a2ac2754434e6b32d114c03b18f3c30c0f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004b8716a1f5c2f8a423a5f170dd5fbe4f436171": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f4bbd56287c3b642dde6ed8f03d2f85ab803c0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b42b3d9cbbc9daac90d469cb60ab5bf116bd9adc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006ef813cd8eab68641cd6fb8d5f3b8126abb5ba": "0x002a535b914203000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517f419efe3106cd177605843315645cbf4a090000": "0xea62962b601de31248d06aa13a52bfbdcb1ad4e534ef4f271bd5b39fe075963700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890540049071c933a260a422784626b2b894823952": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5175300f82161f4d33bea459719b458be498070000": "0xba439a857d9063fe02433e129da8ed247e75351f480b1b2fc023fa102379562500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8b5bb41b4a1a97ce7cab8ce22183024c57125fe": "0x00e4b0a9fb6000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd4ad39c91010433747d3e6817e73678e317969eb4c33786cdf091affcebe4505": "0x31c1fdc59cea10ca6dec6975e83f3c2f5bc629cc", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51066df031a7bca6942fdf201169ef08d73d090000": "0x168878d025e08bf4d1d68a950034db16057191cff93cc2aef5603816dc52464000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928933f00d8b2e67b6239aaf2e152efc9d85ef113583": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896641a9a247811657a0c435567260eea47c3fc81a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51843e6a606c97d2b71b0924b3fbf75d12f8050000": "0x229edddcf6d16c5d5438aa50b68c67ce9a422dfcbfe5500650d897c1bd50e04200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824399fb6c13d95f1b74e77778fc86b98ffb30cfb929": "0x0060b7986c880000000000000000000009c2dc0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1ebd2c29909eb603331b960308a070b839ee78e80fe12ef05e4639a176ab743e": "0xbd6e08fb25db746221175b2d50e9fdf7b227643a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736921aa381ba281dcb6fb6489461c2cabb8c23db": "0x00b051af5a8401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a369d5026865d345184ff86caed29c118a1566a4": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db0479284ed416d070f4f6867eeef4c2413ecd4d57db3c9fabb82feeba8326e2e": "0xcc3d336002054a3215fd3cd1f00f08bcc494fbcb", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895a41d48673da40f5343bc1e871eb360ad8b9bdff": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289638a66644872aef9572ad260b0b353d4a860b45d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f84b835800125e729921cb11f3e4becd258d7741": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c8b8633670b06b418295c37ad8e9390c6f6ad72": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339743bf5419c4eb65b6f8cd55489338ded388c71b62": "0x00006c34d0f403000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e4e3d34f7a72015774f9e614b0d20fe48d050000": "0x2894a4e556566eaf46b3e383c7d1b63b16d0bf1400bb2c763dbce51947b14f5e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e4b5aefb88bd749426b9a4bbcc09a3e9760493c6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289029c5bc3bb8be76487f9b75b5065a6f57ade84a8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768a85a879380543b48c40d0620e0681300a88553": "0x008053ee7ba80a000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514b48fc9d64cab5a9ffea245e1eb20ec016020000": "0x2871403d3277ed54a2745378fc937e98bee1f7a7447331e9e05eb559671d964500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d863ef80ba5eaa59e9daf2528dfeb5e78e8f83b": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b06d958cce8ced5b26ea37e63d26a3a3a0d3ab34": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d22f00f2ef7569b9f5e8fed76777eaae266c7c355b03000329d1e6856791ff229": "0x8ebea2c1deba5a629af27b0c8383113008c8ef43", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dc3020ef4790527aeb51d62567bb48642acac8": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339744e45fb5b5bd8e1bf9d1310b761571e73fb02924": "0x0048513e650e00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ea82af5d798473d0632d903e65c3360f56080000": "0x4397c030e61ce77f663d79186e3e1c86eaae6616e1695e0ee2ca87ef7e18d19a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8829babf92550447e53be69e21369ef808fcb572a5629ce18dce2af6194e951a": "0x4af79369d49d03b92400c3b67a65b694044ead5a", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfcc3adcc46a1d2dde1ccb5a05db9534b7c7fc30404ffc7a5c2e3de947909e94f": "0x0069bf728cdbeb783ee8adb4801db3721f94f1ca", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ead61e3f92e933b8ce06bc76061f92455029fb34": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ef3190039aefa5914791dab9d5b4d019b0441e14": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b7097260be77cd8ca74c7069087c05a601030000": "0xda9c6a6ad458f966eb78979e4c7bf8557a89f71c221927e0efd1f5c8614e815400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700844b1cb340393be1e3cf1c0a9157c57dfeeb2e": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339742520065f9da805ed7d122f009976a4dc769c040": "0x0026a278d70500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289511e81b9d6c360fb6ecbd923f66aad7c34cdffb9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890083c66b575c021b8ab547e522a4354b78032602": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397082d3e0f04664b65127876e9a05e2183451c792a": "0x00963016623e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a774182aaae3cb75b28f24b4b77f7c96b2b820b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002ac73d3488df5bad2e9e70dc37db667371df44": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282439e643779779aec00285eac62b88c8f926c6bb1c7": "0x00706f96a686020000000000000000008564160400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd63e66ba8c5af8b64993b764f71aa50a4b0f112d87f49015031b8378f8ce2d6a": "0xb4c4dc1fb222bae0e04fd8cd23f78b37bb39c17d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e82b6cab96e3a03c7f974089a585b10893a5a9": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890092faf23a9a9c66a7d8ffd3163d81d9f2bdfe56": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008ce1ef049738e34a1f1e03764ec209b329a558": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2c1679ed3eb12e0f00ff6e9e42f893aa377539640a1519abe3cd2e02023c125c": "0x00d1b7bff428ae90b82147cfe52e2e251b1fcafd", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d9f222b9f83e22e15702b798ff9b4d9d30b117": "0x0066497f817f07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970098029c2d615fe6f6cd9a6b6d35618878dc4cdc": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000df35b3d62b94414a010b9f2fe6a1489b32944": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289024afac105064abd224256087859ce5fe0dd2f89": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895fa8bf3d389f425cd6bdca59d08b92645e236b2f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d580251e8a4e82ce48d1b4f09b836170753650f7095235ce0d0ad4249cacd1a7e": "0x805cbf1fae3e810ed0cece7016848a677cce945b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6f372dfaecc1431186598c304e91b79ce115766": "0x0010d733860900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4cbd028b49652bb2a34aca9063cf88a06495ef9d5d33392598e0e57de5046811": "0x00e173806d025484091145ca79d5d830f3d38b4f", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d96c27443a5b800cd9324210798250c05f931bee9db9d99c0e1968b820da5b567": "0xac64a0c791cd0b6edb560c121fabfe6a23be2c43", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890052ff8b09907fd5cbd63791a01672362a6cb075": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b3b1314062c51b5df40b45278143d24558080000": "0xb2d89b7dbf920e6cd64997f1b3ee49c4de09327342dbbba971a362062817a24e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928954970d8d6d8f8dbe9c87ab9cab9057fa5039e4ab": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970089698ab4f16050d36225631917d4db489dc251": "0x0026da6a887d25000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd0aed46706bbb3fd28d13bc698b81ef6aaa0cf78942879954835e3f8475f4044": "0x6deb669e7db5d02735d5a4f14d622a09f6d27682", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397819669704eab9a1a1086840eab684846647b969b": "0x001880cb1f7c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f39b53937f425d7e764d6b1902bd775ba3d514e1": "0x0024d4d8ace401000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f48b621ec245ae6a2f1743302e9a0d2a5b3e1228": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890060ed7298f6492489442f555e38acd8c672edfd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a22fbd442e50f1cd5ce576ca9a6d917e1481c7": "0x0032b7ae9b4900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b546f4ee227999882be22ac4425227c4a80c550": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928903197abad8079143a69da8d037b6d69bca469bcb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976be555d4469720a6a980245a1a2139a5e678e415": "0x00a678b08f4c2c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970efabe80d1646ec4d11f46d8fed63b070c11d5f3": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5145111ecb0584e6ffa836220c43885e399e070000": "0x9e6e426ce0daef13a18330489126c709e3c54dd535be6e3840513ee1441ddb6300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f6d321376850f36041db18c5189104c6c97bcae": "0x00005fcd95f209000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d622140277a3ac51d0b235438d6c40c282038db51285130194d9f61bc3894e67c": "0xdd766dc1c0441f9b06691d3b19ff1d150b839e7d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eaa40f6b29ce35d8f53f6bf9b2a7397e3d8475af": "0x0076e6a2f50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ae070273b639a73c42e1878849ed52f6d9e0cc6d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928902d0f868a0467b7eedf6b252c6a7e53ea90b13b6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc2736969960ab728695cfd8b866b2d1d1219ae9799fafbf20c2901779ca1c275": "0x00a22fbd442e50f1cd5ce576ca9a6d917e1481c7", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b44d2cd7ed00d8bea6151d614bb0d058af060000": "0x0c0abd27328b055be235a79d6b8a9ec1ab7d38d4c6f2b6ff20d9637f9aee4e7800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da0396c581d426dd0c333d8991c1e979e02f3223": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d941030b8cae55fe5459f75470417cce9030d285e1683f98324a7dd81ae1b6c07": "0x0041910d9e4c61fdd7759a2d317ab892cfd80ec4", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243006261f93219f1cf1b3468d807503dce5a5b11f5": "0x00008d49fd1a0700000000000000000073707f0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970e4aa4412dc3eed8c5c6a39288866940730dd257": "0x0094bcba878500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b1a22d149fbe630c3f18a01bd593618e1e2fdd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ac0ef3f6d0ad997a16438cf7cc685c2aaf032f": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892d409b74db75be650cc36e53192fdf7aaec35002": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289343f61f6d7393b93a6693b0114b8be1fec7fe9b5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289355d599405c853d1be6f1ff027967879d69acafb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d6fd4653efa8efde0a7bd582adb2d0c8101c930": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c116f3128654372fa53ea006f91d4a6cc8ab13b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928985f8d96b05b4b33b934f358bcffc916ea60ca1e7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289849c50c6f7bbd0663381241fe5a7c65b3d74227b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a99e74d6616ae317cbeef70401baef1383d287a3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518ee27c4a756dea20d48104529055cdb539080000": "0xa83b893579065ff9265b9cc79966041e55cf8f06d1d45fbd9e957daee08bc26000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51835c7bfe9cb1c66001424ac36319745eb2030000": "0x5e007cb54f4faae216bee9bbe78fc93ebc83017932c2fbfa14e73de785d9ae7e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ae2770b60928d239ac9f3f2cdf1f1532df020000": "0xdc73a045120bad713a3c84fb3ea30d2b28b680eae6737465ab10706b088b011000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900272a64bc6afa24c034902ae6d9253314a0f655": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289af9e08f3020e624c945cc446e8759602049cb176": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51555748e65f4978304e4e4feb42f05d8709040000": "0x7cc77c4360b1e179bcea17c296e799401504ff28dc6db9840adcafa1b0cb0a4b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339754f5873787daa1ddc97272e9f7fce534015f4d19": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d404e40fa7bc7015956de0fc04bc542baad0442e04440387a464f85f77d25a25a": "0x000e5a0a7326596d024936e96ec7b662e5de59e7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897194210fbd35b97b861afb593c7832c201e1d149": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e0ed608adb4488caaa5b7ae3e39f3d7ff7487b": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c08a9da0ab9bb63faca19694e66c95fce5dfcabc": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d243411786f2b168b5024685ea3474897ef2e77b7599275431ba5229bf657890b": "0xf38865dac042397b42a80a2cdd54eaf32d439754", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890f465f7ce5a1e26c402177194653c12e7222f127": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8c43e6504928c56f0151eac7575949a8951c4deb28c9cd1acb26743de41df80d": "0x16af41d7d554e5814b2a906b2ac27bac06c9a61a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b31458838ae39fb3d4e961d063fe89ff6f8d9f37": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e95a0b7851db5423d0aadc91bf963eab02c6d440": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894d6352629387b12b8c5a32871336775d10b105b3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ff4030b388b3dc8280c53544646159759e3032dd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004e69986ee1df06458380aeb694d42e5d4b4098": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0e0b97949687e5cdc9ca843c0428bd0437e176d": "0x0010df60427b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397287bb445456ee7a2ea62c0a8c0de60d6eb41bf3a": "0x00348d451d1800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898a91987a0fcba374782d45d0a7237be1627836b8": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282430ae2f976301c5afec7ec28494b91471c1c2f1093": "0x00c05773a57c020000000000000000002834060400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db0455a49cd7799893e8a3e3928baa35c2a921c63352b4126ecb7942d7122861b": "0x28046b3cdb72ce8eac1e8953d17727f87dd6ff2f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970046cadc70ad1cdac10862e9ca7ddf6f5d1dd47f": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824347a22454aab7e24467ac9fd5453db69b3dfe8cdd": "0x004072e62d2d07000000000000000000a7df9c0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977dfc554e9b71dc76d1836307af3f81c15eb9d0bf": "0x00e849c81e1900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928945bca14081244a055409294312fb1731ab3750ac": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6ae9bce20ec8b89105efadbd7bc50d34843e9a12dba7eb10694105c617310155": "0x0024f96565d874463a46684d2f276318793049e5", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5177f5bdd537a4aceeaec8f5cf802a30242b050000": "0x6c29577335bfd3cbe0df3daf35919a30761a13580aa72d1d3fe8003e2fc1a44300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e30bd1dd4977a85589a8000480e8356630050000": "0x308ffc25bb1c9025b53d9ac651ce189b9f4588a1981eabf55f0949231740044e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008c2651bfc939ffc086fd5b5e598cdc1d662c97": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7cb80242c9f91aa58a2a5b8565bd270aca1fe2d83339e83f90b5de02cc2c8b16": "0x02d0f868a0467b7eedf6b252c6a7e53ea90b13b6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ec92519007b823765664beac13efaf630c263316": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798725bea9caf118e3e31a0fe480b887f81f45bd7": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700328824a4fc0484c8ff3353c8d2f65ba9e05638": "0x00c803ef0e4a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799fb6c13d95f1b74e77778fc86b98ffb30cfb929": "0x0060b7986c8800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd22abcdf4219140319a7f2155c838897e8df31bdcf7a5f59567ca06093e78252": "0x0045ebe3bc90887088d9c91446a2973e79b0f78c", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3878ca973b0f31e3c7a63bcb0bf7229452ff5850e734d3fcf3aa59ef2a6f5567": "0xb33841ab8e4fc931a294256066286270a77632cb", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891615d921575a6948c48758e6ab9c560f1e862328": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a553b4aa347a13d5957b84d6f54aaa2e08040000": "0x7c8c3a92d8feb9d27f32f3ec67bcc6792f8496f7ed86d1b249c54205a39ee30c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289203d2e2bf08a58c132f650f44e6db94b78097032": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda8564ba0f7e717dd8d61025823ef756b474d6a3f3e8099da01ce16b53d85154": "0x8e7bd3dc5a41971455a7e5af99c3ab77766b964e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895d67096571f54542c5950d22122a030c308e7ecb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897f4b3e6adabbbd946c2c4859607a134e4c609f53": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c4d620dd343cd3fe7c350707ad56680b4baae9a3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b3e7a175f6183e2c8a32e94881d9cc24b96f4a": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893ae2a64d4c258fb4278cef0dbe4fd9e6d1e639d1": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddc313b667a08d4a8293ed90733697961647be1182449338e3ba7215cb786311d": "0x4a3585a53e68650e03cebff3c42ced82c21ba6b6", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d22a371deb8c40c0e598bcf145b98cf2603707a87415f0afcda8d4fb8b19f5757": "0x9311235dbedff7b53b7ab20dc27a76aa9708bb0f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f72fce633c6ff04e9d82d01a79cf7c4e3a54eecb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ff34674c9401c39cf82d06d04f2037411d835db8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51de18007c0afadc771c45bf719bc7fe5103000000": "0xaa16ea96e59d8fc82b496362eb68947ccace82da2f1f3357142c072725de6a4500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d5bd2aba04a07bfa0cc976c73ed45b23cc6d6a2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda25ab05eac156cf1a05e04c4e6474da8d31e104f00b2e006dc482e622165f53": "0x058457cb480231445486c786db63ead914b9e1d3", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894c3f69ca5a5806321b36b68e6a25aaee0b58b259": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978c723d6c9f5710dd0cc7219a4658f09c3f5d9928": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb41214ae65c8ea58500c913d29305ac2092f0d0": "0x008053ee7ba80a000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bda644140f26702df53ea796f34c6c48a7080000": "0xbaa38e2043aa15f54d2febc1f3218827d08767a15cb325d19fde69f7ce62af3f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e5af6b59d2da9b4dbe2ce617dcae625a004b0607": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700705b1272d1301af42e4a730161bcc1da26b534": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda1858f63aeaf2dc56970d9071cec207978ece8813a381174c0e36dcdf0eb063": "0x0035fc5208ef989c28d47e552e92b0c507d2b318", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d7fa21691eba7c0030910989903f677705060000": "0x1afd8047b4dd08d1d8bc15ffe901a00390a71d7dc601650097828c3fbc6a220200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dee9be31704415170409d65ccee6fdc7149ce835a99396e1e471db458d249d472": "0x78cc3793d423ccb41bf53b2659d49a6c42ca3fdf", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007486e5e3a85ada7f1ce1fa177e02da6321ab3a": "0x00742daa350100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4fc54ad6d9b96543f33797cc384ed2ee33902dd": "0x0034fc4eb4ae13000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519fbc06809f8798db97f6cf453571a59a82000000": "0x581b789243689bc3367ae7d487ef44b695892c6693e3c9ef8c4ff95fff99df1700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8a64dca67c64d9361901a1415bfb3469b000d0bf7f1d439824cec71f87022159": "0x07b10fb900a97ec4a265c6ef64d47db52b9702d0", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d229822081bb748111238c67574884b63ca85638c9b139102fb97796dfc2d660e": "0xe1ddb8c1e2204a92febaa4dc7242590cb74359f1", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b14e2f2c808cfcbed4b27fc8f692c928589ded14": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890044b3d793d4cbf50f0973e2c8d62ca3bdcbb38d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006d3a544384b63158fe841d6c84b27d998ee27a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ead8db7ec6c9dc388f70011caa225f016e070000": "0x36d886739e9ae36cd8642c33d2d991f613b3036c95950421f8e7e2b5ddb5cb3200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970040c3cb223f156e97861b8afb63fc8f62e577b2": "0x0014c1cb9e2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a7eac235c1800f3301e452f50a8df7a6f82f6192": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900994d4bbb81f3d3cf352edc8af739c878b78768": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d88ec6a8cc750ec1221580f795c40b2e270a9724dead719ed76076760851f5878": "0x00b8d82c1ee5bdc3505523ca8d1e0e8e7df6b10b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c8b8633670b06b418295c37ad8e9390c6f6ad72": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbaedf2e50d3732045c8b24d42ad3167b994e318707f4ae4cabb7ef212f5e3860": "0x1732d95532f10ae18b2317ee75d4ab0981369f37", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51040bb853cd2e1e5ea274bcfdb6aa218734060000": "0x92d2877d5408cb4596cbaaac36d35efd65a619b99487ba980f158f83904f000100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516e3f368a59aab0ee2f18e822eb48ea1853050000": "0xb8cb6953945a47bf445e342ff346b73496519646383bafdf669462c5ed30f50000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c9094f605ab3790ed1bcae8111c987c786dd294a": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896eeef85c9161e7486156e8fa517ab0964fc1b969": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397726a0e3227f10b8967864ea8f7fba8b5637c192f": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002cbe540f860818a183be6052ffbb1de22dfbec": "0x00ec045dab5600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899f10fbb6634415227e89d542844618591a7a8ddf": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517c70168f36a1c2fb21fc8610f326db568a070000": "0x5e4dd79678be50fbf6aebb41dd0a4b6eb2412d28c481d09c0fd2dbb14beed61900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798f94748373c637c8599aec7c09e7d40ede3b78e": "0x008aa5136c1d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007abc56f6083d36db03065f7afd36c55bad6afb": "0x0000434fd7946a000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cb635cf62e87d26bb5fbbdcc5f2cc16bfb030000": "0x5eb1ff55a31e109bf2246f0c8a430037b4ee4b676d4d8a5ef02ecf3d4e292e6500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978919f90098e7976078c2ca828b6af4fdc3ab9052": "0x0070f7e810fb02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e005e96b230631a08c53a58cbde5e1e13943647": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516c319e148aca75808a0ae5b613c33a7b8f060000": "0xe00c839391d9bd0ebb8f571176bd305e67677d96a44ee1a73962deb31a34162a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ed65f1402181b155f890aa7715576d32eb020000": "0x480e00bf0602f92b26802a794b8d837677d77a4abcfeacd6d5b9f97c4f26df5e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002176cb83b3b5670fd6231bd92169346fd49227": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928967a01ab58cc873bfbd93c89f2b0897e85007b772": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e688284626ca2d00b578865c0e7d189c6ca978b0": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289afd4d2d92a53cd312df6856ea9faf6b8d9f8c3c5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f81a1831e1bb3b21b063f40b5fd29969d9cb2ee": "0x00769ce20bfe00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928960aebc1d9f35ac28f40444bbc318abd850c9376c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397582dc3c082204020f1639c2079fcbf2d197eebf4": "0x00d6087cfef24e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e79ea613690def3083ecc0d55b223e7711369c72": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51510253c3b4839c9187eadb4111b301f905080000": "0x0042d0cde6e173a7beb9c72315b9efb8ace76c323ce8644fceaa8c2d7a18dd3a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a0433933f6ea1084a7bf83ccb474b4cd263e7d8": "0x00502269587001000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aef69db824a8cec8208fb4264ba6831ef717ae8f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51111fb9077a9e8b21222433ed4ddc1a83a5030000": "0x52559f2c7324385aade778eca4d7837c7492d92ee79b66d6b416373066869d2e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de2d126c3dffe301385f3d6da21756147d8f58040a9021e4196a89fffa2800a48": "0x56666fc53f50972d6fe7d75d1149ca3ecfef486e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003b382fd41c33964be3e159799e8539c0b78159": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6a9dd1d60d062e40c25417c5aae94b0efaa1d3096a35e9640215a3a0d6e99776": "0xc4468c8fd916e17f85b6e76e320e631712eb8312", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928908d2502ef55264180f07970bd2fe83bc206f0715": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c76c643a4c56e4d7f45d3e8a9166340c5e787d3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bd33bc721e6470c15d18489c3d56a0253b030000": "0xa44cef17a2676c816212c314fd6b6c46fc1c3d88c888188a0bcd272e25059d3d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700092cb42b631dfbdf26f405f931c409fe5a3913": "0x00c0ddf9a28300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895a6ed25e84058c2810261558ebc593216aa8d1bd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c95d852b78d3be6f3df2c1448f023ff3ee4f51": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e11df746c5ae8018c863f98ba5e0970529780eda": "0x0010b4426f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e787eb81b0267dafdb6083fc33f318ad0bc945a4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700020887bd8bfafa35f1d5de3c18c6f81b0f8f29": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d647cdeac80acda72c27a54c2aaf6e125cba3eee": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928947a22454aab7e24467ac9fd5453db69b3dfe8cdd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d5a9b2328bfce7b23d8ecd6dc396125418dc03a4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dd083f4f90637b34f98f77c9c6027a0c78c6f2": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4e2629f039089150d0cdc2988f05232b306534567f3c2a2bf93075a82a0fa113": "0xdbb8868fa368ec46f1961ddb5ad9f01cb770424b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978622cef8a526857f4a3223af10b302fc29f79226": "0x002c0980fe5000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d68d958e8c1f36ccb18e17e1151bbfa4319cb4fb578b14f0b74b8b28cb2d5f01f": "0x5d045e79ff7d87b7fc35c70bec29501fbbc28203", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dfa25c63cf36b2049181a0038762839ba364a8": "0x0040aef2235f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d484cdc76e0b6b2cb4e30850327cf37e717d91e343a62bbfaded38aa8133cfe34": "0x537902c724861132c14848de8f504f196eef562c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007af51d441a632cbf0b4ec175e61332f28583eb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d80e30c47a3fc276c022612170e25be798153bdc6fbfc229c398f580646242978": "0xef9d64a965dbebd8671375325a0aad9358218934", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f41b89ea9a14abeb84183d25896b79071a81f5a9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891fba1a1a641591737a3ba3e7eb236d2cfafdeb69": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d78ac7bd0fd72ba1836610283e8035a8f5f62e4305c890358a7e182dc1686b734": "0xeec5230343cb5336cd6e3a8cb29e5e267d6d5b21", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d97d053f7c5743eb80c78ae4111ea464ba30a2": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4a7b08615c6206550ca43f314f3814deb5842b7dee2ad0af0d292847cedc661d": "0x0aa3a0ddc82af4c06c0bc4c8acc6a9a9a6280672", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397341e46b97431121edb45c7397534704946e1090f": "0x00ac81fb215a00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51247099be3e71ac2d5e4f8aacf0aa5e8631090000": "0xee5101da99530e61539f3ffdad3185b717c3177095b2007af99b7dd05823a94300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d225fabcc55fae4c1afebe501a378409a53191f0ae212b917cc3581c9adcd102d": "0xe4ba1c4ac566a049429432cc11f4724a4e394538", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d01fe71aa1b2188725a4a1d197f8032c27f75f": "0x00ccf483926900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fb7bfae13cf461dfbdd9ca3820b42ca2ce060000": "0xd0947083ab9417ea4c8a5e1cf759f3619622753fb60579c45dc65c6cdda10c5600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002d27082129124544148246a221366cd71844f2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df4e69b23f84fdc3e0482543eea31a871c709f845d9a5575ee148679266db7873": "0x0083c66b575c021b8ab547e522a4354b78032602", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d1b7bff428ae90b82147cfe52e2e251b1fcafd": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddefd71969bd8c3999920e2e07a671cf76f502b08341a0bef1a4669d3affe205a": "0x392e05b27079b3502ef2937e0af15aac14e8d8e6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3b4bfb9fa5372a43bab26800f6cb125c922c452": "0x00e04d4e6d5b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7c76e3fdfc70d2082cd519b4ce83fe49e545561a5d108d7420af8b15eb118a7d": "0x50d30f8fc7564e1fd231e160169f19e864c3a641", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df4e80b965077bdd3110511713a4d625df31159877337d894999d66713cd55355": "0xd7ed2d43538974c607917ddb8454f00f3cfe250b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b67b5d99f7bd244fae58ebf86d35e38f72cc7d": "0x005a1220334f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894e577a9eeb79d887f0d6bf7f504c5f273f533c04": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971808a1c1c2d6fbc1752b8a3bfcae4b1ccc033202": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd125f7c40e252a090871b865aca471f5cb8ee01": "0x002c490fd71c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890046cadc70ad1cdac10862e9ca7ddf6f5d1dd47f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900518bc639b1ace490d22790ae1ac8dc933160fb": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3dd0f2a2fbb75a38488ee494d719d68a18aade04903839ea37b6be99552ceceb530674b237afa9166": "0x1c151c11cb72334d26d70769e3af7bbff3801a4e2dca2b09b7cce0af8dd813075e67b64cf07d4d258a47df63835121423551712844f5b67de68e36bb9a21e1276c694dbad86b8de9c1c9947e536b3391b77caaca86a23195a2b111b24b0d516450e91d8b60377c58f1e8dfb6236dece92917f1b4ee67d2787ab090c5f8d2200f74b919094e1fca66ed767766aa0a91025b6a8b955bb970912900ad4e413ea936", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898ee43bc46973fb91459bbeea3c7f637c6efef128": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730d381605485745197162f89fd80937d890b5358": "0x009a685f941701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c840d94dcf091b87fd63db7eb0885d9ca4b5f79": "0x00bae4d8dbb77b000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c29f18ff6f0c0ba071e0c6435efc1cad05c25a9c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928918b453f5fa588d41497ecf34e19fd30ed008e34e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d163826c8ce7c0ae26db248337eab2cc31d575dd344859e51d13e8703666a1246": "0x00b4f630ce350efe5e1171e7310bfb519b33cbdb", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e7551eed3542006fb6ce1487e3330f44f6db0f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977851079f455f5dae12a4f668b983908dbf98e56e": "0x0056b961800900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289250498d076866e2178a28cf09444f2ab34d57aea": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5112d8f4c24cc861ca7cdcd2ce96c8226c4f030000": "0xd69dde7cc6a614142150f8edc4c87b2f48a13f3a250b2a9698e7c7e473ec261500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fae39043b8698caa4f1417659b00737fa19b8ecc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dd86986ba67b4a1a8e7be4833dde2c09243333d7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397562cf2b3763971e591c547a116f0d08035dc6155": "0x00087387252706000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6a82d00e3a0a34d054f2f20a66371ea821cea6f3491a3b9ffcda6e151fc37e68": "0x0074b0b90a98675309b9db4c27badd1b8ea42b0b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899193eaa11ee8101beb2f7c3c88a5df61a5114f98": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e8d6becb121ced21059c3a7e05f80af633050000": "0x103978c14955ceaae31e258d640048cba43ea36a3636d4f6884b7ddf5e30d11300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6a8ab02983c79bae0385d2650e022adc6d121bef8827d81ef82104e43b21ee44": "0x73361bd483cc76d6d0681065e6ddb25e84ca96df", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db63b6311906644f4385479c41b9c08d1392886c83104810043145f480b78f232": "0x9b300a2c7b89455cd5f3b4d3a998afd356165607", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e1a73e362728d8de8f7e7961a7a92486d9897c1c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004f8b0da646a07903c9d2fdbd90579b142fe435": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcc5d8f3af2e32f1c627f09e1c1d2769249d00c17c12da2fa06ed040beb38b1bd": "0xc69fa1a7e9572b1d8e1abf43739fee285e3b018e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f511e2cef19f48355bf52d70dc291f2e9ad16e": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518aebdb5a385cec744f6f8ce06a152c6c8b020000": "0xea9138be7bd2bf49ac9e7eb09cc9e7727ae44b1b66deb95562f353c71b2ce16800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ea9d6a9ff692b9616f90f983f2e2aae2ca3c9186": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893e386f707569dfdea7210b53bf3e03f6d24ee073": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db06e66dff95cbb0f8ed61ff4a4e400fff92c8a7a3c5b971e017592393e364b17": "0x24a9f3b7757a2f30e5171009f067bb906f9a8e67", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d06dd653d12418aca05e155c451e4c4f628ae986": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a963493ad9461db8813dc1a72f886a7c84bba8f5aa6480dce7cf77c1849765e": "0x73213bdb86a2636440bba625ce5b570461ea79b2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4cb2595186d9876177cfd60bfddb0dbf4dc11bd": "0x000620e7ad0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900130a5ac1ae656f19e54e2c28c7d9b4e96462c1": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae3df6f5826c3b9d92ea03524f83fb4c7db52708b6c23e61843433506ce08e23": "0xcfcfb4fa0e64528b2c5c8c42e7d46118ae142d92", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397254c62b0e0862a383dbba455dcf692e71fadcebf": "0x00aecaf4c90900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b42b3d9cbbc9daac90d469cb60ab5bf116bd9adc": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397328e1f8f95476bc8e2df5911cdb36d311c57aa06": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de00c839391d9bd0ebb8f571176bd305e67677d96a44ee1a73962deb31a34162a": "0x2d409b74db75be650cc36e53192fdf7aaec35002", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b004efb56cdd4fb9bc79132f2fd60902c28142": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4653f0d351f8bca69b7be83c41b90fcee17c7ac2b285bb01a95b3755a6101a3c": "0x42d0a88bd5baa87a3cf4b6e32c7b6cb3850a3aac", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970054ee21332017c772a9dcb68cc6e120b305c9ea": "0x007623119c4203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b9c31d32260bde35e51bff1fcf2237219d99ef91": "0x00bac1e9b31800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bee33ac5520a2245cbf8288e768a5cc26927cddf": "0x008ace1a761902000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892f67383180d9cb41b115c017a3e1e9134a6571e7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51680e8f01be116107068ba8b0c1920406fc080000": "0x885a263f335b180210364cc9de22b23cfcd1c90792971a82fca0980952a8721900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51de50cb5ea3d16534aae8b2cacfc7582a5f020000": "0xfa04b68da0a4e5933340abda5c7d7007c51bbb2bc48067e8dec0ffaacdb1182000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289da0396c581d426dd0c333d8991c1e979e02f3223": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890087066f0dbebe06b184ad03aaac64f28b6299cc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339743dc2d9be62bee47b83825a901aebe29a1277454": "0x00b44bd2d67400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d847c474dfcb41662f246b6e223fab3c9d17832da63304dcce5202f7aa686574d": "0x422af240dff9d253cd31c30d5af9647fc60bdc64", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daec55c9f5ae328c609a1fb6a914ea6079f25f33d5ea261fe272460b0f0973d7a": "0x005e5c04f113b7ca7c62a331be999bff4f0ec44d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748c13b7bc700451b3d801023cfd6b0d1433b301a": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fd663b3697e5e2251919cfa274345afc70040000": "0x2888de98d79687ad6a7f8c38c9408829b86680eab8e30d62ec36b989f8088c7e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339764465f1b98dbd0158f23e0dc0b1aeb967e1565a5": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006704be2884970368def1738cc901f92025c04a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970aa3a0ddc82af4c06c0bc4c8acc6a9a9a6280672": "0x006e003d620600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928917d6baf59972f76f96eded80604af2a5820fcbc9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bf8ef866b3d8139c982961f6850fadc17f1d48": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289657944ab5a639ec79ba234dabfd0eb792ee9412a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897e1a9cacf28b0e0fd619a5037c231047c3e5aedf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e531bbb0dc3abe3d335edbcf5f479b84c2839c8a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974dda8293a5da4a6021f6b228845713ab246a8607": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e77bca46a70638e60c9f81bc09d2daad7ebfb379": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900928ab46f9251610992b3f5fd257cc031f354ba": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890ee3a5ae8aa8909d1759cd909d15a646ba94a025": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d84583d9d96ad734c94c2a8e35e9545434a0aaf87ef3b14a3aafeeb6f863ccbd4": "0x7e22e58855cad471e60b297f1a48c34f44091132", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d80ea70620d770611eaa9f1a784b08d3be34f0c48166c640fd478059b954ff432": "0x26dc3a2b04c409af7f03783b000b2cc05020ed7c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339739db9ac590a3fc2ef947f0deb09b400f891769c3": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973cefad973ebe1f54b6e790c823f90f81e95f4aa8": "0x00009573c24800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002afcb6eb1d06a5f5f26360f72d777b2942c4f2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51870204cd13f30721c29a31401fe406dd7c000000": "0xbaedf2e50d3732045c8b24d42ad3167b994e318707f4ae4cabb7ef212f5e386000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895b279c406a13a1772c7c382d1096b04a7e65e753": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8eddba03a0f2ddba21aab778f772c14bc6f1999fc1f5e25fcb2a7ea0da24055d": "0x003040fdf21fcd3084fd4076962bc4c7e66395d9", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5147e7c8dbaa1cd4740245506168fdf3980c050000": "0x76dec076c9a31c9b8493516198ad24f0e8f47969953cee5821e30c340f27651900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700169f2979d901be42b7ae68ee6f25bb38ad1d10": "0x009a3f588a1b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740f8fc59e380b53808df1bd1c4e0e2674186dfab": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793d79977ef117007a0028218d99dd2caebd70b55": "0x00148b66da2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890087df4a94ed0637178dff912b20e01ace2dc9d3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897bc8bc547457f1a52e7547baeecfde77966657c0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cd9b1a9d7e2c239ccd8fd3f739bf2d3bdb3d6a1d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f78e47fb57e98c185185608bec057d495f2abffa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c00e0743d704094b1d198076a33a33487e2d38c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c23af0d609849eecfc412d90ac2da7acfa050000": "0x783eb106ba819ff2125db858ac9bc9a5f0cc3f825f6a8050d586db169555ee1600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5167b497952718b90a35b48f164db8c11247070000": "0x0e9511e878e0deed76cb465595c6f558d9cf512f8632e43feca07a26d060215200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9462cdda81c70aa96a411b2b570e53e581fb7f7c49bc26dd5c1dd1e304e1a46a": "0x4c9520bc4a39e7ba4108d2794b5ef7727c78d34e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a10042730f48659fb0c3fd7f3cdeeaae03317f18": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d920bbd35a0a98f20c6eac5857ffd316b80963": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892bba2ac16832d15f8f415f1cb351fe20977ca399": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d60145312077b3fbd05398e5fd1f349e29b41e6e38029fbc9bae2f1f8a9ae8a2d": "0x765fdcbaa945c2f73dae083770dd0aedfa386d5a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e87a44ddfc5762e9cf415c9c00fcab24f3ada6d3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289af770e8cbcce62a1a458739a4ae0811c72d33f55": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511a5a3e05772e49a78847210ae01d942757040000": "0xae6e1f76f1a161f6a6e884753f86ba364bd84c59d7ee14a32554bd1710be622e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cd17aab6f8299d35bc11428093bf1c4ae3b981f3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899ad897f48e2166a71b83e541cdeab9c36232d905": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971cda53cdae34c5c3b2c62e35bdd1db577e56d3a5": "0x006cc682d80800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c5f66fc6dd672a91114e67edcde69ac17b2ebc8": "0x00ccf483926900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ad1ad5f214271d037176bec3f90fb4448ee56399": "0x00e0fe28a39500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7ee8a9df96c3eb8146b2532d3b25421a451a770": "0x0080a5663566c3000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928995009f768050dfb14ef9ada842323c6349386972": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daaabded5fabc47d6ed0818f8d44cff1c5a9b97d0d863dfe92fb616cbd2e119c1": "0x6ae921692a206089246a967450b1b88783ce8fda", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b55cb6edcc8c9cca3b659007d1abec171bf75ea4": "0x00cc6fa527a006000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d2c56fc0046932d4aa37cfecef3a47d143722518": "0x007e58b8edae01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890055a15e869bb215e605335181284aee8be30a50": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973eef4ebb6697b4b0408d4394a37794b484f3f9fb": "0x000620e7ad0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978beb69c07a54a0feff772c42eed03d8036bcd446": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979588686984edb566be1e1b5c367aabd49aaa5522": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a27e4a44e3633f546f8af7fc0acefc55e58af5a": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c43afbf4fae6c9545c16a6de3c8abedc2c589271": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db65d26557de4647d0b74c1c74f33ee210cb1bab3d38754bb09a664f6d1db760a": "0x03fee733b242749112fee4ff2bbf7f612dd607ed", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891476d4c5204269665dac82770a8cfa80cb4ee953": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397895607ffa297db864ec7da7351353618ddaebdef": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b2898e4595621bda49420c368efe9a2b10050000": "0x500774a5e6eb480dcabecc949e4c2508d7329ea62a1e68aebf76b819da6b864e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cc0a73abf38de6f332b9dca8778add43e53bf4ad": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fcf3808986a5bdfbf72211debc42cdd72af74aa1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972186264cf67b36c8e63ca37098645e77c331d769": "0x00301a45ba2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512373859cee064c4848ff2807e3a472647d050000": "0xd65612e123691bec4f749b69367b6c04653ba5ba43e83e7d2d9237cd4fb2a20c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289945df54583eb102061f57d3b4f3e499d7acc49b7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b26c71b5246b3d118411f74cfdaaefcfc07645f1": "0x0080c3b8f9b75f010000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928901ba3841bbe358c1b3a9310d84ba98bfac5fb318": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003850a6770db5d0bde4dcf7985838a12a1f4045": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5199d341468e6a933c152b170acac5262b56060000": "0xb0082cb409439012ffaed48a46ea0b190fb972f35c32263763558c2c4e94226d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e84c6f6811e60fe8d08e6bb2dcc81d4b16080000": "0x9e3a57ce212b3db9c683245532d085de60e18bf3d249275c9e7a827939568d1d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f4920d9045a58646dada2c7a8b48f513387c86c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700240495286c0f4420b6cf3b7d98f50682f82544": "0x003e7409320800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fba6cb41b57abe94c1d80b7d738e9946d867f8fd": "0x0056b961800900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512e56477ba6fe39168a8e5d6c5afbde72f2080000": "0x6afef10e3de1ac622a67217de17ac4ee000d179fd54edba27e77470d961e8d4500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d22fff76bb4a0a5d66cff0392dbc083abbac3b3046f6fcc328abf0ddd16ca0837": "0x141af52b68e8e1cfe3318d7b91c698b6c0e2d9f5", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397781088752c0d882ad057dcb31dd0d023efb8d872": "0x00c66729ba400d000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51375e2162dc0dfe5cf0247a0d6e91053c5f040000": "0x38e7887c528f5b54f12d9c9ebf7731d89c84622e02a8139059f3af6e4ba6452100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb9520248a32078fca7bcdc6459dda51afa86fe3": "0x006e1a13482600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e09656727d41176c0b8987f684450af02eda1466": "0x002cbcbad66f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e3ea41cc49b5791b4410ecc3d2dc4a303e09f4": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289781088752c0d882ad057dcb31dd0d023efb8d872": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289efe2bad68fa91496e13adadf87568b1fc3b454a4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928993f4c3085d088c79aa83a9e60ebaa245e8c3425b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5110f86a524410fb3a434444ef52d786cef3070000": "0xa800e44b2b342ef986a4e96fa2f2b49f57ba47851db3a54e915295d148c8180b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890023d732d511a5d2cb335d824655f29daa85be26": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894d863ef80ba5eaa59e9daf2528dfeb5e78e8f83b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892f7b34d58d8a6134c268fb8f0174e94ce07874e0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397600011fee56096e5858518ba9d12c43474866e37": "0x002ecc1f8ebf06000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d33aae1defd629dba3d3d9c225b1274788127318": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975246fd9b509ae75c0f4b2c176c3ee71de674f292": "0x00de9804010b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b0a37554976f25303adf7a715fb050f7d1d73d": "0x003cf35d972100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289081c8e52338007010ab569afb8f1e098e645d3ec": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891020df9da65f804831fa334e16befbac20599a33": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4cd38181e02e880a53114ccaf987a6f51a10bc1d172d509bab6f7e9d6eb2e00b": "0x4dff7bffb7fc240abf06141976d2fe0bf610edee", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890002945f1fc37863f255e0803b75ff1f5276e23a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896813622de314f3d0f3fa46717374e12a7bf6ffac": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977735e8af95538d6b436e3f63db0233b46f23aa08": "0x0000b0d140d30f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978588ebee2efaafca8642783fe8bede2d9857fd68": "0x0000c16ff28623000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f76516ce11965b9970b53f7cbcf53cd4d984ebd3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975baef8c667a773f2fce5568f70ea4b8cf94dde65": "0x00c27e3a434100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ff0447aac61f107abc8872248ceb6a04522f54a3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928913376a50540351f4d0242e20256e857a80bc86b0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d6a54b8c2aa14f2a9ab5c4d99c10f8bde48de08e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5127c20e30caeb2934b6fef459e226a3fa72060000": "0x3297a3b21fe2d3c8a89bfaabaa0f2e059a3d94577a04d961a557c2d25a3e573600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001802a47a849fb5d290323e4255e690fba12898": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ee051c50b5c51b147d939e25ce61aa7e05af10ced2ed62ce7051509009ddf54": "0x8370da48be315b1f73fdbf206a9a8678234a16a4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dc7dcc21d1c488fcf7775d7b081a882502ef47": "0x0094f9a9ef9001000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f307788d880e273d474fd37b4260469291070000": "0xe6890223c279fe3fc640de86171ae7e6f9edb04203d5a8670168bb725576af6200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979346f8545c9f873b09d9265c2ba196b21fe3f838": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea3243ff8c88cc961edec6c1cb24ff779dab9e1159a83d6a42ea07e125262a4b": "0x008ddde69a07c04100b334040505dc6b4125bdfc", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768307d03aad558716061762b9b62f0f5d17c5c4a": "0x0028dda6111000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bc41f12063661d86d9df79c28c9a360782b478": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eeba76f589cb390ceaee0f15302f5cd567a05b44": "0x00e8212ac29708000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289523a99d1767f000e1e77ee5a4fe0bc6cf264a1b1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bc13a9ed082cc1556a92d05a143fcd2346ebe62c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c20dbe4d8839b6953c7528824e42dd91ff1c564": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009cbd06cd1a0812b83234ff4b16d4561901dadf": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a6bfc7493f9fea17283d9060a6316b02c3e92bc1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510db92076d98f4f58593ac283d5cc09656e080000": "0xc07f51d638daea7871de9c9b3685c306b70e1144e2c4886c808ad3a40f0c5a5f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928982d31226f14b0b79aaa950cfdd01ad248765ad20": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976df24f6685a62f791ba337bf3ff67e91f3d4bc3a": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397762a1795292a3d9355aeea85e4b174e9bd8cc3cd": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ec0fb95dfc28a7d6a15d3b0307a004048b0acce0b23b340d8c8e646290e803c": "0x9f043f875302e01d60d90831ca17593557969b10", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289898f81f8f9e937dc0629c0b6915921de04d13b6f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928931b81404b826658f107997f2a9cf96e6fae6915d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892deb3f6d44a5bb8154181f32f79988bfee948d49": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bfe8f085ce6b73c1e59c3eae993e73125180ae": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c69fa1a7e9572b1d8e1abf43739fee285e3b018e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bfbe75d8f450aa54d8291b0a03b83f063a070000": "0xb0479284ed416d070f4f6867eeef4c2413ecd4d57db3c9fabb82feeba8326e2e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513f1f57a1b4a81a5dc119f226fee4ebfad4060000": "0x1cf5cc62622f472e9e347070cc4cfbe265f0e1bfe56e07462cfe8a7b628e3f5500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a3041ce2ef4e9ddad0ee763522a641b03863d5a5": "0x0080f420e6b5000000000000000000000b58260100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d7541983658ca17367c10e4ad6553103b3a719": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890026c2822209f9a0f8427fcf5d8f75dc0e471058": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eaeccfcf272dee48fa3e4e783c6dea0fa1fc38cf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289df93b554f8a7c976f8fdb35afe4880a13b463dda": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c2a09108fc4add5e5259f8858d684162641430": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db8bf671a6d683d47aadddebc4586550750407f68178f77a6aedda63fd0cec131": "0xdc86f44b16c4ecce7679486cf4006ae586bca879", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928982d313f325b3c9b63502bffe9c01361037086e99": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750ed8729f9b9cf868b12785094dcd61b4e37fcd9": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bb2be121b15ca94f6156f20b8b45410676546ee9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e95141639b4ac81e74704c7fb969ed396d50f67d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c1c9d83d1736537a50ca150879f2af7329080000": "0x0830fe5930e891dd5912ead314dab09f8c47b462b478ba5f09f363ac626a3f4800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5172fcd951206a2acec9bb0530ddc987d3dc030000": "0x44681d99e5d8c26050428ee732f3e8c01ca7251be24c12ae7b99aa44126bb60600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b2272bea66948af04edeecbeb0171521cfb24f": "0x0040763a6b0bde000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c2a09108fc4add5e5259f8858d684162641430": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c8b461ad395fe2411869281301c2ee7b5fbe5d": "0x0026a278d70500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397222954391116326ccc7e022861d3d3f22116ffce": "0x00d4dae9256400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518eeed960ed82a024bc79003b3140e02a96060000": "0x1803002442406c0d57f20520b633b631ad3193b654564ef92577569747f9f10900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975705d16cc35d891bf6951c24c374afec5f7e38dc": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e25fbe47354d8ed5377773251b41e1caa13f1363": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51effed96a97099720940328980fe1f610d5050000": "0xea989e5de8381aadf03a456ee925107e6145ff1f649ae0576eb763f33931400700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de642efdde17e295727ee9ee006201c9a06da916a936452babfaf190da3ed1f58": "0x04c6f1d15b8b0d5058db45fc13d6193fa78848be", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5198add5f7b76230ebf9eb0849dbbefba374040000": "0xf6be65cc16c65708bb6a0e4b9958ffe23d1c56ee5683670a69dbbbb70c10d50700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701e086773e4f00f25c04e6f0b8607274ba27bd94": "0x00caadafad0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397765fdcbaa945c2f73dae083770dd0aedfa386d5a": "0x00520122088700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785e2f2767bcc9cb4814bd555413e2e17e1cf8459": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289100dbb75eab5d98ad65ef16483aaa68e68aafbc5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f63722233f5e19010e5daf208472a8f27d304b": "0x007ceafac42900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289996709841049286c8d63df10988e70a790a68daf": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d00d79a5a68a82dfaf55ec01108f9850e47ca61887ff2f7272f5dd9216cf46432": "0xd315959e879d36d314c19ccf6654dce6b7255fb4", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51016f9a6dcc7601d0a632fd00375289ce29070000": "0x08e7cdbe4ea147b107456a5a1c4885f3306890522fd89b7394a1ce9ebda1357f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928969294b14b71f036b1f394e45b46a370bfa860300": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c383c50f156431e8f7187e0c04f14b85ad4aff27": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a43d494953912c2d75d8148f3e773100cf050000": "0x60bd4d5a4a4b80c613ec911ea4b1a3066f040369ac2655c3dc63e6f9ea97822c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000e8ad6492f516c942bef6561251b531fd7b10c": "0x000290e3bb2d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895998492a4881a733e4beefb71b2022b3eab9bb6e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c6a209a8a9a17b3acac1b3316de1522c90050000": "0x167d9286a956bc717c29ebd938fc46bc05eeda8f507575a77d01985e35211e2000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890098cda511c8a1a04705b0e22e81ffb60008a21d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fa8bf8c0bb1b6a89bb9f45a5228aea9d296653": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a34ef7ba5b23bf5f55f3e4fc094486d4e9000000": "0xca5bc1915da74aba3aadd7ce7b809045d5eb5b73559259755fdcd85a40a5dc6e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718ad26cf42a6d886352e9337ba7d2e1fa7302c8f": "0x00203d88792d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bdac7423ca974deb9f4d5db731cbc3f5c64e3f4b": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928998194b95e37bd6de019d5ac8fc416daed2091408": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397984af7d5fc49ec8bfe113d542f3eb2f8e2551dfb": "0x005073b3e57e01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de8382680e672b8403c57f2bd1073c34219fbd40160e8907ff4cbc548976d263f": "0x8d3e9d9cc92f6c3802baa4c0e2f3bde6c3c37c75", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ac8938e1faed5af69a6516f48b450c82dafa61": "0x0066f52cbf4e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d163b6b73f9e9a77c336cb7ac90510eca3bb7a3bb567fc62415b52ce3282b9c23": "0xc616dcddb10148ef5351b5b0c272486d15b3f629", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ef710bfee1c6e6ded8ecbbfb8449e782a809376b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da26d7f204384eec001d21fec7638b13c5fedaabf38d64fb8cb70fd9bc4146e46": "0x44eb5b6c2d5cbe2d38f9fc21e5166f5964bc47a7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f29c684feb0dd39f45960bbc4becc9f776be4ef2": "0x00c6c5932b7300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339796f0aa4251eb879290d36ae975c57a59f2a5472f": "0x00a4823fc99198000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824367cdd37fa7b4c8dec31e218467ff93f2d1d44efe": "0x008062175ed15800000000000000000098fdb88f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339725b584e9363f10433b2b033e3a9f0d207235c89c": "0x00ca8f386e0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893b8f1babf9c1a911eefd093089acb1a47b7c4fb2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928934e8812c8f789cb9dbd6993cecb92155a6af62ab": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bb645bb339add4632150de669a3973657a040000": "0xbe3f8396e3f7de378fe665cd2cd3521af932a8a376d8d81dda40bb4e4438504f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005417c5ae560be9c83ad34e3f1cfbfde481ba61": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b02427864d348004ecb1044d508c68c79d955d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339728a6ba2203b78b7e0de3dfcaf687c400bdf1548d": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900241515212d8321ca983eff69a2bf11b58ea42f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fa0496aac933cc02710bb23a815445cdcc060000": "0x8a03b55a75d4baae8acab8224a1ed1bd6636b477234b3c540fb3282f17ab771600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f52eea67eac5e43ae5562e4daaedc440d51378": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c636b16cee0a7cb4e5dc4662b7d321b772a8c1ec": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dd6c0fcf38a991d9c95d2e379f4f234807bcbeba": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f3b4bfb9fa5372a43bab26800f6cb125c922c452": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ade17a1a405f0cc75fc17e49b2e018b1e4080000": "0x688ad06202344d47304eb9eb4392842fcbcc8e06977d6cd55f02c2c9af602b0400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd24a754c817f83acfd14e75dc751f3fa9babf35": "0x000e103af39f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397577acb95cb312b867f08b214f421a52497597688": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d82f33de37b35de7cc4f5ad4b4af122aeb25e084bd1e87a6bc28b60ad35d28615": "0x0019012e00e460970f1d39925494ec20a2dbd50b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c610dd72844e40880581a02fa3d3d881744c37f1": "0x0038e451d40800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009181f75cd5f86b015f28e0b1919f5fbb3a3eb6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001a3dfb43b4686238359abf20ffe8b890cc65ed": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5192c838ca1c5c908c1a1ac6b7099d91969a000000": "0xc6947bd508359f995d40def74ae4e73d64375cbecae152ad22b39275eda2120100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bf2d514689fad1121753850b85496743cb6ba7df": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397373ddacb2c816717998cf44bf784e75471d2545c": "0x00b218f2c65f03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894e3d9fe074569618c2b58486d13f2af969516dc0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928907b63625869391c66528acf9610ab2c19d935d9d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5180bb2f2975ce4750af769d7a32dcbd69d39ea": "0x0014fe55391701000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dbddada20c7b2b653812577388aea9ac896ac9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928955479b40703db085c9abeee0d45fef0c61b0098d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289648764f0789afe09b446db06388edb09d9588cb0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e89e08763debfe1abb6bae24d4bc21c91150dc79": "0x0016ba87ad5b7b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ffda559dc06f88b229af02fdc41a5a6a48127aa1": "0x00c0a539b67601000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899d6b708f01044bc2d23ac51ed5dbc7563c46a6fd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0237d930cc0e0748cd9f00e95d88d25de6165b2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af1063dc4a5261ecda991dc24ee256e4700be7bb": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890054cf3827073c8663e5211e7af6c63ed4b0ceac": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700518bc639b1ace490d22790ae1ac8dc933160fb": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976904b80d7b5967daf9a55a469e18c55ea75964e8": "0x0040e022590e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006cb4d719cad2ba7ac9cae5520378b76fcbaf1a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774f63340b5ca9fca58b50dcbf6cedd1c97972200": "0x000cc18f250f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928907940d682e51fe3f01b2236d18aae7fae021a7e1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289532276374258365ec2058848caa8975da2e9dba8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289af1063dc4a5261ecda991dc24ee256e4700be7bb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d12b1988e003ba72cf070e76e70db32569a8a90e4676deb1013b4f5872dbaa239": "0x8afe5cd482d702980f9b141ab34150996db32341", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b1b561896f65cd50341459052a69cefb25673451": "0x00008d49fd1a07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975dfa9a92eb14a3455b46eed5f6e17253f304abce": "0x00868bdcab1f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893ff9783bc7ee8de42612f752d6145fa729402a59": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfaedd625e171137c08fa81173e73ed48f4835e396a9b8d0581170de58cecf639": "0xa34c6bcae6f46ac6470443ccea67d937f6060c7e", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51de36f998e9945b2df9ebcfe94ff64513f5060000": "0xce877e2264669fecf930d064b268d29020a96f910282d642f96e2052a5daac7600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dec18887a19369a1c99fafec6d8e52b3f6d0a1af6abdab0d0ca49daa56bfdbb26": "0x42a49b7c7a88907053060c8011f11c5d26f2db8f", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c31bb5d37dfad0b2e0f0aa896d95360152060000": "0x8040433695ee5bcae5ecd8b9a2f329c8d625f74146ad3060104914f1cdc7241400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e6224fd18cbbc2e20a5cbd2103d6e8cea741f8": "0x005880abe94f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339709bb2615c8f45144a7d4bc6d06c1ea346b8d3063": "0x00181b6acc0400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b6780e13fc68b9e998c2dd70c0ccfe1e9b020000": "0x10ded14d9cffc8776745dbc613da8aa7ab6a22fa02b9d1e929ddb169e8a5445b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae0ba2b9eb48ed60ce02ebd80d1632e1efee027c15b0823e4133d32173d4e111": "0x3686e9daaed20aca53640fc3c51059f6c5afb54d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c4401ae98f12ef6de39ae24cf9fc51f80eba16b": "0x006a097df4a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5eb1ff55a31e109bf2246f0c8a430037b4ee4b676d4d8a5ef02ecf3d4e292e65": "0x26496ea4743de7d6927f107151fc67616fc0a4a2", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d542ac2735e893007bb75a64c95a1658025f9d3c2f58c5af1c1060d87a43aaa5b": "0x4bd120e887cc82285aff8408dc208ed32b132bb3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001835bf16df6bece037ee219ddc4870adbbc528": "0x0098407d9c2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9f169d904363571adbf247965ae962e69cadc7e": "0x00a667d3930800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006d2623e4d647b291d41850c287d0f45ab856cc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289831cead0805ac7cf4a744e9e8d088317eab8d0c0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e04fba4d693e414f7252ff3381616d711e13b992": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ec51c4a049e6621ca891bc03533a9572b93165aeb4b9f00ee1625cc4ad7472a": "0xe2d8cd482efb93b788cff519bcbf5e25dca333be", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700642284ddd6a101231e93d0a8469b39d85ec85c": "0x0078ae926ef109000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892d6d291937e1e0158624cc3644af95a6140f2c11": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282437eced1aea8a70ed73f12f0550ff58671ec34953a": "0x008098281765060000000000000000006718590a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289940650c5f5f78618c938c182d89b0687579a99c9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977574855f00481cddf4c103ae36ddf6e042e5d367": "0x0024a8be34cf3e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4c17652254bc6e13310168a21c5749982cb6d64": "0x0020f6cccd0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899b0d0571d39cf62dabc905c3892c32fa578defc2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c61ed74017d66eceb5eee1f20a012e4774cd79f0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fe7c59f5c785ddb869662aecdccf932b29e10771": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899c5faed48240954efe9b5f666d1b6df1de3fa2ae": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df66c98834c19d0aff9f578921681f766f530af84e8b53a5632a364f1a796a432": "0x52c7f3fb2a8bdc8f2d9cdc9404b5779108d4ea0c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890cb193903063145dc5ec3acf56bbd5a784fe25d2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfc99f7d3bcc5a32a627866ab9762e1993b1bc0623cdeeaf16f48d38cfa9e1e28": "0xdca74fb0ebfeab701b8bd771fa5e240265832961", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c77c440c06384717ad302a6c5290c9e8716f67c1": "0x00009573c24800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d92c003ff0cbe260dac5a3f86d9cbff3caec28bdce628adf125a40e72b26a9712": "0x0b86ef72b38f189bbf18a94bc46c044b73ea807a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765076dd6f1438dea38b5901315208ee437482051": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fd4fac2aa9f0e0d34751d2d1d6fd792fb6080000": "0x7ee68da95f66a1211c7b843f161409ea7a8f9107fd8b8e29e1d8d6f2afdd950700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5136a9e62f14037083b4cdc841a0bdb5bfb4040000": "0x8c80d2977137d56f3a0ab93f78e5c7966bc2a94fed331d9457d8cc4b96a43a2a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c5d3a4a84a2d404dc9828428180fd927dcdbc896": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d5cceedf3c21bb629353405e2e438cfab7c94c56": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dd9c3c2f403af26731d5349f2e8824f85cba0086": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5141130e47fcf21dc5f82d2b0274caf7ec41040000": "0x1245821dcf1ae288a0dcda3b81a608893cca26a21cc01affb83e9dc64a2a5f4d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd24f805ca7bafb11cfdb0ace585a9d0e6edf83878dc7b42946c33c2378211464": "0x9157a5fbc82a5eca9ebc3a225de072b4ebe7cc30", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397223124942a06b92fd5267174d18dee47bebd942d": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e3d9fe074569618c2b58486d13f2af969516dc0": "0x00ec4622388506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d3b33791c1ea8922dba88bd800b509e884c33bab": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dfc044a6c92db8aa2a0507a157039970a86c582a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f18055387961a61eeff5a3fcf9d510b56a94c6da": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899e91362a99a6e8e6e0577feb433b3ac7841b5892": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824394c70b28e483cbfe9d7554e211f5f38ef9435bb9": "0x0000d098d4af710000000000000000002907f7b700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd06d0c9aac9a1db183583979bd2eb6633fa7af90c276f41a2d5a5297695c752f": "0x18e653d8262814fb82b703cf058c97e7b2020c38", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397719e57b6d5969fdbc9b35bf76153dee9d09e2536": "0x00eaca971ec709000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970048e604f2473ee6eca508c80397d2d8cee49bae": "0x00963016623e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4877511245f8954e48858da743b9eb3544681c27ffd8802c8ea1669e961a2b61": "0x6256921fd93382ce2d468570f6bfb385e5bccf0f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339780c503db92ae417099a025c49103b80e370ddae1": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900590fc72b10e46e5a5eb6adeeb2966b37b61b4c": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282430035d19bc0178da96f2ad24504182733d90a0ed5": "0x0000c52ebca2b100000000000000000030fb711f01000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890045e6f8ae50c7b511c257acc200e3fbbf947d44": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da03927f2c5ec70e2a6c64be18c91cc75a7a41e176579bc7d632d78e488265b08": "0x004840267ca0976045bee42e0b7dd7dfd3b827ce", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5116a16be6261a35c574c7ab4f4600ec7bac050000": "0xb24b419150b1a22c259fd8321a3058ea83a8118d29eb0bc46e0056e6f988942700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dde880ff77037dce39d035916f70a67006ee696b9cf9b4de4c613601943630378": "0x128bef3c7b002090dd018677f551a865595a19d1", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004d70b92f0b70b284fc33d396e293ab6d72c04b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df69a73bcfc9996e432faaeca61f336deaab5ce773dc236161ce08bc852df7e0c": "0xc771ceb58b220cb663c2a77b37558cde21c471ee", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898a77e549ab954b951a118c7106bb46e606e9c445": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510e99e5e903d2a37920fea64fb1eab9c2f4030000": "0x50ef6fb05f46fc0e58cca849698d21a330418e612d0e206ab19c6899245b8e6f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0e25c438529a9db85e8d1d45020e02862ad22f1bee84a0713895f20ac765624b": "0x4e96f9207310a9dcbfb0f8acf5e44573b56eadf7", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519472ad231556f1aa034391d360a1ffc154080000": "0xecb5f00888229dd98de2aae6a2bfb8f31b52104987f4b52df713b32e4a48df8f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5e888a7a333cfc1433a594a9b198b64bb2493f574e57cbf3f4cb195a79fe4a40": "0x04f0594c389d0071131f288014a05e91449146bd", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976fbb52a0c06818f7022fcabb7b815f86cfc1eeda": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e723454d7ca777999065bd370faaf671b469149e": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701beef9b0f0a48597e1454d75eb062d70775b13a": "0x00a031a95fe300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890016930644a71069819f2642d0ad4a07a5add934": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dc9de83f11941407e4c81debc7a2023a27e118bc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d7ce447361509f0575a6a206888ea2afd88557e8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890094e5350b60f62464c4006345eb31c2e731f6c9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890d1456fdda7b8ec7f9e5c794cd83194f0593e4ea": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d531b67faf691723fda5e741359efa9bdb52bde5": "0x0036270f8e7701000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928965b761631b6f2fcc2c085a544b6602d1317dd94c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bfe953b6bb77bf8c7851141ca684c5dcfd6cb925": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d58771ce0f83cf6651fba0037541ec21a0afab196938a7ef3722769f24a38de59": "0x04d83431115cc45d7e1fb79b4d64b5669238b687", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd2595b4dd370884f00e06b9b1e6f8e26e80797cec0660c246a616649f09a490a": "0x3ffe3083861f58aa0101453a61fd3a1b747d2b75", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d62ba968eea9ac1fb02e752328be8c273e0374396051cd47dc602a6ff0145304b": "0x55e9a88d4c79252e7340f1e7816098b755c942d0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971615d921575a6948c48758e6ab9c560f1e862328": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512b23240a15acf4e8b341265833fe501699030000": "0xa4f294e483405fcde773f272c296fd45088a1f7f105d750a8c57eabec973752300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977886c5f36d2d74ddae70a9125b9f375fbf614cd7": "0x0000869eae29d5000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c6ae8a52978150c27cad4136308d4acf3bdee0": "0x00ec8a7c58ac02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba4795e1db269aa9156234e30888d75ff3aaddfd": "0x00d6ddca3a5500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001c35a3ca5e21f8398bddcce36aceb288d11f5e": "0x002c419ebb1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e08fc7cb11366c6e0091fb0fd64e0e5f8190bca": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397693e1450bee60182d0f34256ac03c94de1cf781b": "0x0000f954b10ece000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b0c94ae3d19f2c585b920842211d2d8430da691f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c1efc49285eb5deda2ac887d613242475ed15048": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243c5d005e57310e4c5f148be7ba4dd666db6884c36": "0x00406352bfc6010000000000000000001ddcdf0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c3078593afdb525caed7ec794de3cd88b917b0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e5e15888c2f897ddc27dcd87dd9f32a04a695feb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289185a7fc4ace368d233e620b2a45935661292bdf2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51364fea1ed5a9a5eccc6d508ead9849b556070000": "0xf0dace05e939a7d03eb7edb13409ea19b7cb1f0d20469267322acc92c9cdc62b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008ad6dca0f98838668c5a336ebc4f72e2872e30": "0x00a6e052aa5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722e00a49eb33d077e389a17928e7f7bbed4fb938": "0x009e05e9abe400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891ad661fe9878af3b77754710f50981c82549bda8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896bf95319e992a3ea48071692bb0553b173fd7d34": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289081dadcdd7cc5d6f406061007a6b4af00444e75e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c8f490959275fc91f0bace6fb722639c4924317e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e6fa447855eb59c62f23e3df8a556b07a0ee4d9": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513e38f7c68614edf74ed1585bc9dc64331b090000": "0x380ffa0d99a6519e0ab4d8a08c2d60ff5a8c7762c79e148ae6ee89917001004400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397280b9eb4839eb05e05e48973e1c969226fcc4392": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c583fd0876ecf8c8497bbcb3f8e888f2ee1c214": "0x005c01a6223d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da221d23c94dcb9839d8211590e39f17c2b62f2eec91a66b3102c409856c8456b": "0xdf4dff459b93832e9bd6e0c32e5866126ecc434a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b13a2ca9b77ef417c02164de32e7a1b34e523d5a": "0x00b4d919c66400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be638e483b91290575009bb63815c3ffe36de43d": "0x0056b961800900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928971fe8590d29d971bbbbb17342ea62a3c52c6ed0b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e3f51f35abe48323c6734d1f83342c684225ae": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b795fa77b056e488eb37a624a0f6a6db1e1401a8": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cd6b9c9d40ae9d4db6dcefa18167658c8c5afa1b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a7ffad9c186a581b06ffae5f5c1fbfbf190c794": "0x004cc5b2780900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5136cd423d881871f84a41c448ecd49905f0030000": "0x44a1336854e44cdbfa929ad12e913e4a1870c590a6dc5e3983a6fd416b927f5300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d928b092428cad53613dd8b953f1b3c942c38637c01a34f6481717b2d1b2c174c": "0x82e2b7d189a81a251eaa51ac31871f8c4b91dff4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f454fa5c8c9dc56209f6f5d4c7df32c735c4946": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979da6c5ebb2a225a395ee772d77ec5178fd5a6307": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890cade02299ddef16f672b3525001d473485289db": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975eeaeef816f1015b042f74c42d8d3ee153c2cfde": "0x00aac729e42f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c78724c7d87165b1e7ddece03dcc717b9557c1ff": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006f3b97c4f8cb8ddf2838d296108a63425e63ec": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce76a4eb328d7c14d3a425ac145f887d7277e6ff": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dab68f3f5cbd61feb43e4204d1376d42b3c154478e1d1931ce9cd9bd98de8d7cd": "0x63a673778cb652db8fe7b320da78842e364c40eb", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897732eeae979408d24c88500bb4e9166aa1616aff": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5123cee1a41eac7051c179e56ac23862149f070000": "0x8485fea2004315662000d9fbbb7d5c9e79ac617c40cd6a2046ce079d67195c5c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d4ff781e1de100c601a55c007e2cd85581841dca": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928989c37fb9e6396ed6ef843c62fb32c43250e2f451": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ddf2bd305b334ee4aa8e27481db525338c87da5f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c8bb43bfcda8845d576effa7ee5c555e126b0e": "0x00b03c97ab0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd2837598797295d619785777a5b9771ba532dbe841b224caad6ab58110d67a61": "0x1df8d1ba25da8a9d6804aed11a7650f89fe91996", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a3907773de2b12033f7196b9517045a63315b4cd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa884c81b7b5f4b675e2e041826394e8f0b16bbe": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928984668bac6daf894a1e4203bd93863a7c7dbf87e0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515fa01b4a8f2aaacc0ec9447f1c859a5229050000": "0xf49313e8188843be3e2b454b00064aff16256196b535d4d511ab57207812714f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9ed2733809fff8fc440d3fb8c4365ac7a6a520c46ba4a2bdf94f107bcc5cea0b": "0x50723761bed6eebd4ad8cd418b0b262a66fc0b97", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722f6a08b13d46bfac92f45a624dafd3ab4ca5761": "0x007ceafac42900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748299f5998fbdc5898ac71e8221014a7124e0788": "0x003cf35d972100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928976436bdf4f3b3b9abfa08f825d2db471a4e33507": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511f19f91c022f2741c5cadb34b5ef30c38b030000": "0xa255df385c871dae02401415b3a097695741863d9f4fa6c086889b9d14a3ee6900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f9c1f8b4234b1d9b714c018fe96afaa186d841a7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d9a5fcc7c0b2b6415b5ec65f196724dd6f070000": "0x7eb937e55cb2550e258629834c5bc2449e30083b2c8e67d82a62eb4f3b6f2e0a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928918ad26cf42a6d886352e9337ba7d2e1fa7302c8f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d9af4d724f3a570367973d1f167b9026ac060000": "0x268eda4ec34cc03c815a14dd8465c0e2b7a404f56b6ed9399c363ac244fd612200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aef69db824a8cec8208fb4264ba6831ef717ae8f": "0x00749f62461100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2c4e4dece27c83d62cf01816cffd256d3871b309e43e65f9e2ac33e670b5db31": "0xa56f814d9f170a1c285817223b072626b517d099", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007e1b953932516a6560c9161409b4fa15595bd3": "0x004eb3011a1a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c84df4cf2dc2f818925a0cc7a14b1a19edd5e2b6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a6625ad8643ea9c894da55c4a5393bbcb59446f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ab6a08ca44645fca5b8a50ddfb04a8f9477923": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b32816c1386cf0f7d5df26b4ca5921730c6f0ece": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db6ce2b0af9df0b5485dac8eacce7f147efd70bb39f181a67e5f049f8ae6f4f27": "0x7a377641a0f741ba35458b3fb478f0a6d013dbea", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b46c2526e227482e2ebb8f4c69e4674d262e75": "0x00baa2b4bbc33b0b0000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a6a2b356718faf8cce70e78f06712f1ce5917d04": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d34bc6fb5ba6e2150087c96fd4852ec188aba74a5a383a22ef66b12c588cea00d": "0xbdacb2381dea4e23621e4e3f5c8f0ae020cfc688", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977928c0238f5850957d9826f712b688d00041cdcb": "0x00feb8bf501000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d48b2cc621a25ed86391676c3686bc2cf76f06edc66a4c3c21e2452618ee1bf4e": "0x4a08ec412ead6bbc45a465aff936e772ad133569", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c163730557af3cc84dffd66affb23d2347154257": "0x0066172ede4c06000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d784419cb586fb38c30625aa6783d4000bd4c39337d510826414d825689324e75": "0xe25fbe47354d8ed5377773251b41e1caa13f1363", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f55e8a9bc462bbb788e83ec8d022f1deebb3e4": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895432d9368e60cf5c7b3b166a2b2354864d3d12cf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dfc044a6c92db8aa2a0507a157039970a86c582a": "0x007e15ac953900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5134345e770c0a24d56505c2fc09d4370b0e040000": "0x8ce7ed6c49e1abc8477271f684f669c2ce87f48f94f847c1a9a7193ec8ed7f7900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d106711bd6fe7f02667ea334ff74f06788939959": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900367f2a3dc2af6089b3d5c929f997655d7a9151": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5146ff8b95a2e967e35ec0fd9e0260b0155d000000": "0x2a8c3c2f2e55ac470078c1021e3f8b77d106f62f7282799e765f75f1723f810b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bdf51e4fd4d1101b1ac20e916a6f7cb2f0040000": "0x784419cb586fb38c30625aa6783d4000bd4c39337d510826414d825689324e7500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd8ee28573fc3a94c320b07a44cb8360d2f3497a82df0904fbe8209abe49a7809": "0x60c5157e1255dae7acf046b38fece4a69ad6289e", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824309d7bc4d2ce5b5369c16b76f6c6297b1c711b832": "0x0000204aa9d1010000000000000000003c85f10200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970016625480945278b5ff3606667b0571f183efb7": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d88bc66a4d38128c8dd29d60a4d333824baa33209272321aa212489ea2d19105a": "0x9782b9c2c85c2e9db211cb6200065e312853e68c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a249e3666698c434db898a9ae29b64875638019": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006704be2884970368def1738cc901f92025c04a": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397898f81f8f9e937dc0629c0b6915921de04d13b6f": "0x005ebeb2030a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d70d68c29241a3ef5841c11afdbb956a75e971fef57ce8b82248f027644bf2966": "0xc43afbf4fae6c9545c16a6de3c8abedc2c589271", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282430387d965a607009b865652830e675a2ad5c734a5": "0x0080c6a47e8d0300000000000000000039b8bf0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970094e5350b60f62464c4006345eb31c2e731f6c9": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cdc5f944f190ab822712994782a65d7723582eff": "0x005c63e2a2d02b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7b88b6d9199cb9cfd50020218517f1b6cd0ec50": "0x0000a40731af05000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0023f35fad621e22d2da59dad0233f8d93e302cb55acbea4b2467e6a59ec5b3e": "0xfe8f3d02414c57745f1e87be25ee3496a1a573ff", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da8e87388e083b3f1a9dfeef27977d883cf10e7c94acdf0c60f57f0a9621d4539": "0xb98df46a871a544265c71648cb708525fd913ed8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d0036b211691a8f28a2f159a8db9d84fd3eee0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890ffb27ede09161a4c13d4176afffc9bcb13c97d0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289222954391116326ccc7e022861d3d3f22116ffce": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b3a82b6e21abf58b057077ff00130f292973a041": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de25518f95848feb16fd5dabaadafb39cbd03c0d440b47eee1042a5ab37301d4e": "0x00d0036b211691a8f28a2f159a8db9d84fd3eee0", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b9882362f41860e1dbc58a143942f5681e040000": "0xb0ff4787cad35fd28bc266d4e799e2395e31a9e4b5c1970b8acfcdcfa0d8560700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ffb3bd8b5365758350008118961254c5ecd1f80a": "0x00d22374f95f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5151af18accb1d8a91917ec084a455e0d97b040000": "0xbc913f31cbfd866b69c0b295577462dae9dc4532defcb67d2ddf6f0b09ee447b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928917ce04ca9524aad7df1a14d591576f0a7cfb8565": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b340bb2b047e45d6653aef7a5e94aaf40b7baa1e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a99dc7c944cb8c2cf094502e581afd9a15b0867783234427828e7e557903e49": "0xfa93a39e60a804ed41e1bdfd38badd4197e6a977", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894af9fe0d55c749c5fa4eac73c660afe9614c926f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001c0a1988b92b2538bb264e649e285bd78beb07": "0x002efc190f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001c57173ef5705bfed109af15e677a8d8f5e520": "0x00282e48726601000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ec07e54b38187e0a140bc2f987a1fee0fa080000": "0xe642efdde17e295727ee9ee006201c9a06da916a936452babfaf190da3ed1f5800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f45d57c49adf2be37f4cda720141fc9cb6236bd": "0x00e8578c8f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a3585a53e68650e03cebff3c42ced82c21ba6b6": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5115f16375741147b2312eee8a82f9ba9251080000": "0x53ff1caf92232a43e8935260dd13dcf03bb4e6473df67213af77085e2948c08a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c662747812327628780f26e0aa80149f4bf26ea3": "0x00903973206100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970016cd03db08cffafe5afd43d9cc903856a042f3": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977d2136d6cc5cae6b60520050f1cc902abb8460ed": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928945ddca7c0426fb78561229a9958873ae9cae4e79": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5129a2cb1eeb3321b045d6e5e2841eced3aa080000": "0xb09131af9d0a9204475313dc71104ba4ab278d9101977e1e9f523a8220e0074f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300de86782f19fa9e5881223077680101b2b99019": "0x0000434fd7946a000000000000000000b79677ac00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5196a64e4143c948edcbbcf68c979f13e3b0020000": "0xee095ff182d11b07804c7ae6184e03ea05cdb5e35c0a7d2cbed0e6fdd5ac050a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289377e7e59dc2f5c9e08d0292ece47611b515dfac9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dba274ee6e60ffddeb999cfb69b277133b404a7a81e7f2b2482cb6e390dc2f13c": "0xd0d62f0e012fd9cde4c2b255305228fd4a3160de", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001c79f24805bab6c77ae73d7e484769a7034875": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700edf872c332daee73e6d6885fed66b03f1885de": "0x0056c78abe6100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727c6574264011276bb58654e48973380d5c20717": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c78b72770635153e1562b11b3042355d8d040000": "0x7051b75d2765d40638e37a5d0dba578dc82bd9b6ad5a29c03cf720040212561800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700994d4bbb81f3d3cf352edc8af739c878b78768": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a6a90222087648297e923b01d86cd754a7e7f7f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896df205592f28ab7e1db1ff8e24d66c53e5f22c3f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ca1c423a0a9af92343998ac10b6668ecff9e09b6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700daeed67ad54dab091b23a46ee6cc9f7e27d510": "0x0056550116ab00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7c63cf2a62f9fec0367c3f77d665e2406ca7940cdce57f736cc6ae356b71b612": "0xaf302aa751058797c6ab5249cb83547a6357763a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339728046b3cdb72ce8eac1e8953d17727f87dd6ff2f": "0x0012a3c85efa00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fea42bdbd815aa1b370fd953d033c80262080000": "0xc601b3e5d664c8cfd77f6713be93b8b4364e6a1e93217d04888b3c7cc21ee23500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de4cd169b3bf263d47e5604fde85081d4eea4fb30ffbca3d34d45160cfa9f7e6c": "0x01c0a58e08274297cf31f4660c89723f655de3c4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979d0d5ff120f3d5a0daec7ea328dbe9e682d0efd3": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ce22e1a0a40b684163a37c72112c304dd51bee92": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d06301860f2816ef4da65a86597de885e9071806a79d273815b4ceacb98247c43": "0xefaa2f28aed1cf6923c64137ddcedc4a94181fa5", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bdc058e69ad60873787e67fe22ef40e6a82032e6": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b31458838ae39fb3d4e961d063fe89ff6f8d9f37": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6f5646d9e7fbee7cc907eb8e12dafa5378431e6": "0x00f8199a6c0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243663e2ead665b23089266bed606d492ddfafa5ff7": "0x00c07ed6adf901000000000000000000af46320300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339745d094b1790602ec766d3a81701f02ad99f3e954": "0x0088d21c5b0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009e2144ec83c3caf492d6ad92cf33cb2cf3aa7c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7cf315eb88caf2dcbfdd1161ce790d7293fae62990145fce1213fa4555f4bb55": "0x9028b660bd9fb93c44efafa5472407f82108e5bd", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da2658d4ade7565e18570e0289c8c4ecf3b923b424ea7699232cc678241d1e847": "0x000f6cdbe9dfc875008e23822266cef6ff78124d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895feac080c5d43df16479488252694eff5bcf7a2c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d447942da8bdc750d846b7ba4f88b0d8b3ee8f00f83949e07339656a5b5c04a77": "0xf3826a238beb074eae1d6c2a42cd3c63e2fc9147", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dba35225c3fc78975a20ea5119f4b9e9e458e44c981e67e38f2082b144faecd59": "0x006f3b97c4f8cb8ddf2838d296108a63425e63ec", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f78e47fb57e98c185185608bec057d495f2abffa": "0x0060f86c8d0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd4b51c3fe940b0fd7dbeb9f6ab13292166e1deeeae43b8d5a632c6c331e3da6c": "0x05e248f31370ff8f16c3bb5db186ff80eefafe62", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894c376d7a071d508102173761ddf2b8c27f3cda11": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928986a62b26065489467abafd4e02c86fa4ba37e8fd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dd82457a6fb1ea688d0fa4a2a2151368619403": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339773648bc5effaacbb36d73486e7a3cf424fe0d928": "0x002828fa960f05000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cb2f6197ace28dcb66d7c726caecb534a79925": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928913597c1e37b3dbfb347255a2939b6d58f557e1ca": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fa204a1b8d4d8da5577c1eacac9b7e5f3e896c70": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d6fbb8b9ba0bb75bd0f6109df41a2d22a6f48566": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fcbe7c027c8cc33f9ff58358629a833279c814": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b53d322d505c0b8f76e745023c7d69845d663b4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db0ff4787cad35fd28bc266d4e799e2395e31a9e4b5c1970b8acfcdcfa0d85607": "0xe787eb81b0267dafdb6083fc33f318ad0bc945a4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cf14cb2a1582112f352b2853400b532891e6eb": "0x00cc1d9299d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f5133638ea25da451abbc648fb87b28d0318aef": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970009e426649bbf47ae1816b30bce4d4bb3977259": "0x0072f3efab0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c766b7772d2ed956c850107bf56ca79299ce6d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a80374ebca14d88815007753844b2785bb010000": "0x0ac2094b05a915b14b9b27ba6a7d92da35d0000279947e64b42e9da82752f97e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970084e0ea2823277102b3701b0b29d974c29e5e3f": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d13fc3ce8ea30f518e4ff96b5a74318d31d7239": "0x0080bff92f9cd1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb9458f5c5facbba1a3d21099f8bbec44d7e3d00": "0x006cb365fe4d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d86bacff9e50488125f449229ffa6767a36ab06a48b04e41c70cc7e6d82359d7d": "0xf57e50a2ea8f652c4166eff8ce217baa204e7f17", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a83f2bcefba0bc8bc10f88eebabb7806bce2f156": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a91987a0fcba374782d45d0a7237be1627836b8": "0x00849704501c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c62019e4aab737f1f9cdcdc73c3c55b2a303d5": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a9807e6a10518c24038521c00541af1e0e32a052": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa93a39e60a804ed41e1bdfd38badd4197e6a977": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f843d23f9c75d5e2602c6de0574ad94e57e8132": "0x0066497f817f07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c509424fd0794e367683b213a91f3cd83d1180": "0x009432196c4604000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db6ecb6d155ca342849b05dd7b4f289ca0499cced8dc84cd812b9d9aa43326305": "0x88b5c0f4c52ac62c66c1c4d009e6ae0f72f4d042", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dec908d5b90a9d0a6e7255ac455cfd353abea89d31ecd28166efd9c033e6b6f14": "0xc9094f605ab3790ed1bcae8111c987c786dd294a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c14b2331974ac8706ad674e22f707f34a17ebf": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3c5efe835b5f538e43d755f3b1847af1a33ecb796c24445fec6abad99fb2d04c": "0x05c94ef9192ca1b80c427a749771cde2e0f7dc53", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5106f2f424100ea2a1c562409386044652e8050000": "0x6258a2d221b191f83061b09c4f6f778d9097362192cd35231c149e46ad36983500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7657cea869409d039e938e7e3c418ee4a0377eed697591775c3210e2f7186253": "0x742aa56043ed0dcf2673279f39b7dfe2abaf3610", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9e6083c954f38683706efe10783ddf7522c2d817adb5495c7ec73614c1c83873": "0xbd125f7c40e252a090871b865aca471f5cb8ee01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003c0f01ebe0f29488c629e253dcd4cb9f1cc586": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339797062eb6c3d95d33c040c98a54187b5a66541b6d": "0x00706f96a68602000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897ecb2df664796fad819f35cdfa6870975e26bc0c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511ce409a778c3505f7768acbf972e74fd10080000": "0x8c2100c8a8ae062f38b1eaed5b6e754179080d9e37d53b11f4ae7bf94102f45100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b577fc5fdc344b41df64449866e73d33848ea51d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b8f9101b21f47ceaf22f52b0f4373a0d95ae7af9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d26f7f8e2427eed26b1844a1a5fe5cfcd9a9fd7038a0e9049552c71f2a244b22c": "0xb6694b3bedd5ba593526ce5e1d6f5ce899ce70b5", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700802eaceef7911f5ef5884174357a13de4b63ac": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891fae6fdcff481d6966bb864e8ba258c43df1d2da": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51097b855b965e4d06c719367f78f7fda1df050000": "0x7a72895374cf1814aa3d5e82a21dcf181782df422e033027fa4ad6562938587200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002cc28b6e9a1c0757029c8e42378e7ce97021e8": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897bd77a44bafa948bc94d8fb6dc2d0b9e9583f215": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970945c91d5ddc3cdfdf7fdd45ded0746d0f31296e": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b7a48187bc1b9f6d29f075dbbb53e4a0e8060000": "0x1cecfe91a79314b3139d7dcd65db4f5b12cc2a47fcb912dcf8d69903d879da5200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b4f896bf50e0e40f03240f07c80a3be82e1fae": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc0c0f3b4bddf5f9fd3faf21c65b3cb1d917863107dc954c7f6ec55ae9a318674": "0x946ef62e1a97865e99dd8366a87506858d83f279", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792ee94af3a409600eefbcd59bb63623a6280a13b": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898610e7e131ecc29b1edc1eef2f7fd6df2b6400f9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339741df190f54ac5d369149a92583cfc240154fa8f6": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec9465777aa326e36b60abfb4a01298a7f51845d": "0x00f0ab75a40d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002e54f5a746d8af042121ad2129c4240bf460a2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ccacd4afcf104e4ad26bf9f8878f09ff96050a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928902783580dc6b94e83db00d2ed655a809966d66cb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970022bcca7fea62918f9412994bde69b9a396e446": "0x00540ec8632600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511c8a02f456942930c9730654ca687a3a04000000": "0xb01694db6ea17d4ecf62bf8919c2ed7bf166b237b9dce969168be4c6c600047d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d744bc15cd7e338227277c4d4c382389582cbc495365bb80398f94558b84f3a70": "0x00dc120c0536de04a202721962e9be40432ba642", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5195e63aa748b7e59e83867e9fe309acd437010000": "0x6040e208bf4e558f83104424ed4f442e822cd3a867aeee45ac09d05e295f916600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d48e781045357bb7da0d214452aa40813fbbba5a960196c5104617760e517307c": "0xe4b5aefb88bd749426b9a4bbcc09a3e9760493c6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898ba5e63b8242e3720ce62015edbbc4037bc44c60": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dc25b44e836f8c898328d42e96e0b7b99e050000": "0xc639594cd4090c83e3bee137a917bbd0a5f3c9bab4f974ba8203f7fd08d1ef3700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dfa25c63cf36b2049181a0038762839ba364a8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970751f20e8b8b2686d8844d5c452ec8ecff3fc36a": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5075a1c853e34a1d380591c710d35608dead70ea561e4d6a8bb35639514bc305": "0x31b68bed40ea6d8608779acf8c61a453e264e253", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973fce4a3b54b4ae9acae0c1b7911d4511e01090b6": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbccb08c3fa76ca4db33b9a8b1e52b40e8b3d9b1ec93e47c774f6310199079511": "0xc43b0c4013131b17eccdcef96e6c873a21c3d087", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701401ede19c4beeb2ea70043493695646023d0dc": "0x006aedf4123200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5126f8af16743dade2732eaad0009386e219010000": "0x6ecc3d4267ee15a905e60b267efe7058a8033d41840b86a90afd6fd2544c424200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397900a94e7b5ef122f71d1cede47deb4cf429cd10a": "0x00f8d272f65700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890072726b3815bdcdd6c5fe51f96bee5bfd7ca289": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ac20c60ff77408b1fdf3ac6e2739a14742a2779a": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c0b6a53433a49d2d9aa4817570b9ccfef4764cec": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b12c9b8714c27aad069301ad0bc4c0cc416f1e7": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b44c291ee2df2fe32fe4cdca5937e9c8cb4d5f3d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d6ddc7a1b324b86019d2a4cc333ddf36a70b0f6c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d3a005968eaf0f9a32e2f1b1077dcc2843030000": "0x8e8e3ab65dbcb1a1835299935bad1d984a80fd4d1e3f10f7402dab53aa44b12800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d18d97c8a8030d9450e706a8affb50f35b961b348606433e47c35173f4691d144": "0x0087e6f26b4df85ddd9b9b60910c593fe401025e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de4af1cfecc881925c64cbb34a528ee9b77805b0b357c8301996bb5d3b21da57e": "0x0b4de57c216b2bb92151828a9335856f54bab03f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895bb96900d055aa4b3de73bd195c49400237fe7f2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc07f51d638daea7871de9c9b3685c306b70e1144e2c4886c808ad3a40f0c5a5f": "0x792b11a085ce9034cf2f6f7e31c53d85e4da2240", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701c0a58e08274297cf31f4660c89723f655de3c4": "0x00ba589caac201000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970011aba70dc64ecc7f869f9c415c3dd23642eb2e": "0x00ba51b4360400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fcfee4691f55d3ee2276a75fa57b784d98ffd1": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006e97e28caa58d3357d070c9535d6cd06bd875e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ae126ea28199ca921aff97c3deb18f0d8e050000": "0xd06d0c9aac9a1db183583979bd2eb6633fa7af90c276f41a2d5a5297695c752f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dbb8868fa368ec46f1961ddb5ad9f01cb770424b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ed2c3880ccde98d3366d536feb1d71b7f04b74": "0x006aedf4123200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51914902fac4051bd12544804fa2cf5abb03070000": "0x10d1cfebf94c6eedbf01ab8895c59f50e660d46717bb226b23ea14124f2edb5600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891399824aa53d03fba9d3d13585341c819882184b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5109418e489a3298ad5889a1a3094db6d8d6040000": "0xd26931ae163fd44192217c67bbf944eccf68df012a0e6b24b042d9604c70956c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fa42d5acb3d55990ce403d714e77cc15320796c9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f431cd35684e41f2f37677f28b4a760d8fb364b9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397752975f5990c33da38c4cd50f0a41b70b3a6796c": "0x00d8dfea53d67d000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738422523da6181fbda6662269bd301a95686a001": "0x002eb47ee85100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c02897a2a0d8caf336a1a5997db294e39df614": "0x002c419ebb1000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517aea0e9d909b15bdb801879e996179ba17040000": "0xa06c4e59af8d86d8b552887762255c830d79b847a6648210ca6b24d0dbba0e2d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289150afa640c00b0f2b7add198bb670ddeacd2ba1f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009b6f347d957e1374610319d75d49348c54251c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895d045e79ff7d87b7fc35c70bec29501fbbc28203": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de40ce409805d07fb7286ab3c59923f87776aa2f51d1d1b517ec07bea804a871a": "0x00e82fe500c39f4644d479f85e4b3e407a9d6a1e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e9b7c3ff2bcf46973579131465d2bb4dc46871": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e5027fdd10e5041c66a7e580c605258bd92b84de": "0x009693c5b96000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6eb49bf513747f0547e07635cfb06fcde75dd66f96ccde6fa072b9fc12603c3c": "0xd6ddc7a1b324b86019d2a4cc333ddf36a70b0f6c", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5591b55d2c256e25c03af5647edc09041fffe640cfc9be2889c1236e740ec009": "0x4d5f062ae922c42aba01b342b17fee7c9ff2d071", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ed6f2cb4f74ed164582fef026304ef2b1d1b637": "0x002841654c2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006d2623e4d647b291d41850c287d0f45ab856cc": "0x0088fe199a3012000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bbfb61f18a0949a5ba261b5a7054c53d5b3c93": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c6e3ee84e63c897962f1f40975bf14f5b10c2af": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51befcfdf540c366bb80abc7b3e605b40e03050000": "0x1ea03129bac8665e20576fe238d270cab2441d839818d533d5ea903f8960725e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514e9fda3c338973d3ac3dfb7284d0558838090000": "0x78ac7bd0fd72ba1836610283e8035a8f5f62e4305c890358a7e182dc1686b73400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7200c399634a9dbbf59db9f48685ec22ea4acb7": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a5d4145d389cca2ae8740dc2af3a06acf135e3": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa86d43d6d5265003d203cf22d753c9b3a4fb8f651c6424d68768a86c12d3847": "0xdd3bd59974417b224b5951648e5209ddadc42381", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bf5ae4b593a56432357a7ff8d8098b9c10469c": "0x0094bcba878500000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fe2413cc3a97ecc16300bf11a1f31a4462010000": "0xd836ff75f3d718375497728671cb90ab593372cb4a29f953604a77444818e71c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970098e8aaf2dc065865e68baad8c60fb2d9787179": "0x002c419ebb1000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f17cb2d4f469ad4776a976ef606c4a871c0677de": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727786aebb2cd05b2fecede13382aabc3a838c69d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8ce7ed6c49e1abc8477271f684f669c2ce87f48f94f847c1a9a7193ec8ed7f79": "0xc9234f3b6117260ff6de428e15b943b387a6d4a7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bebb6f638336fe10517a0b38bd73105f2086690f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515f8354f99ccf159bdb134f103e3b3ca240060000": "0x3a24d20be9357d2ea5d385ae82bb06015260533d800c23145dbac4b1cfee7f7700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8485fea2004315662000d9fbbb7d5c9e79ac617c40cd6a2046ce079d67195c5c": "0x65076dd6f1438dea38b5901315208ee437482051", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928977fa549b3eaa7e18718235b376be4eb130fa54ec": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289126e1dd8189d7a9d7d1b3e927339fc58526dae45": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aa5fbfcddc1a8cc93b95498880951526ee7314a5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928927efade55131916b2f0a34e313d858bd6a30cf4b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a31b46b526485e4699b91b3ce13d42037c050000": "0xb6113f1e61796e5bc0493f464c9de6000dd35b498a40225f97a5f1bf2491d26200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1251da9bb3f5185428cdc2eb2178278babcc3ffa9bc8bc4b19209d60f5832c69": "0x042a8622ec46cf242361e045250ba7687278f929", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ee9bf7584ef015af3a9eeded671e1e424f0e62": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700eee540f78117a6ee55e4dfbf89ed4d1153e644": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289925807e0ad65347794cffac5a8622d573c3cd80a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d067ee646a21d8904fe24a5d1047cce91b34bdc9": "0x00ba0f07985a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928966c6c69ee2c1b963f63710a599e7fb3508aa3e61": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f7cece00401dc5c5a713aed4f7b8c6b953090000": "0xe8d0e24aa19d8b502a4b778f6172d6ecdc11bd3b9d320c70cec262e291d4a54000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900aa569e5eeb25e923ea96578d77a73a53bd643e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397607f233defb94a83543cd250f2113eb5b5d68f7e": "0x00942e7a950000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d43d052fcc727cb262971ea068d3f94f774935": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ee795dfb870d57cf366f358e3eb41c40544313": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794ec83fc57394504eb57001350f2b5d4e6f7c5b6": "0x0002d580a17400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51715f691265d78ec53eef789cc81ca5259c050000": "0x682736f965078d3b99638dcdaa574b2f9cdbd60f5a0e0a4c6082496687260d5000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970003903739a38fdc8226d75fe036caa51f37ba9f": "0x004c2df6184802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339760256530d074465406df460b6f38424ab5df6bed": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eec5230343cb5336cd6e3a8cb29e5e267d6d5b21": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005b8da2c805e382fdce0dcdb2bfed16611861b9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbad47546eeef76ee44b91a0084628b6b841692ef6b087c62d043991c019e6310": "0x11feb627f21cb0d2e4daeb7f8aeee1fad6574704", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900edd7f8f834eee9eff0a602e6cd8c11ab501e4d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972586319850defd14dbfa93fe588780fdea0d4336": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928987e9e73dd37a9e2163a893462c2664121c9c5e31": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516ac5249778024279bec8f0d0c3fbdfaf8e080000": "0x65d5df37328bd4ee8ac0c5e487b0f3675e8ae8272c82d3cbcd699af3d68f61c800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f41a6aa9773d67c3d31aab2ce54b27f6945b049": "0x0014752a517800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e1d483bb4ab67995d0689ddb9104df604cc04178": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928995fb1fbd1f13ca58ef95a91fc8171d6f0c53439e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892d3aa3b4ebd357d5ebde65ce8ac9b4d99ac2b125": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d003ba0c4031ffae41ee2dd2d8505f8e9f6792fbe955b675072c42d302dad7c64": "0xe902b00370977bf81f4f2eef795133a1711ce38c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900735384d4b8bc62916ff05a16679d41c9850fb1": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1492d85a4c248f9eb0c1d5786ba25459f136216d637cf45f69e7ac035a94873c": "0x15955df69f2c7dfb120839d6b4c78230b664a362", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5188e1b20bc05513b73fa4c2214d898baed0040000": "0x569ed842ea4694ae65819ed0ec5ccdc9ffc46e8e1986e8f41489926196a5c15b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890085ebc8d2dda15b907c3b43e5f6cdb17849b98b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896a4bab3ab426b32a90c353ae450a1d9712d67d64": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d67c0d69691f9d012cf1fd44c5ac23c79cd441fc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009bb861090ee8778e674f54857d9fa5e2f32358": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fac201d9eb3ac69d0f333067bb0df400ebcbea7c": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c16e288726a587ef85a23c884cdb4232637ddf5e": "0x00feb635c0a900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975bb96900d055aa4b3de73bd195c49400237fe7f2": "0x00ae256710bcf2000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f6cd77548b31a8d04ce8d3faa358b76861e4a3f": "0x00bc4a066a0b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d445a834ed21583bcae5888eb433323c745fa4a472dd8ef0af700df918158d201": "0xbe1c575e4d30176199bad4b2fcf7217a6df20f16", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722a5afcec732df9e65eb56c0ca7fab1c3c26e7d3": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900250aa807dbedae13eff449a8303ac62fa0dee6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002dc409f3938a24541ad2dbff32b8635f5af5e9": "0x00165b74a10500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fa9ed378e8bc649df332605415e5a9f3cea779": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002848284eb655a5a99250ffbb09605b8e624261": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c44151439965c709f7d79ceebaeda5bc5fba9ca": "0x009273630f2300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005c3e8ef86d7ec80976e586dc76f8267fc8368b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892fbd318ce7d1b4399d68fdd3561921b1b6fb1d80": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282437804275d8e53aed92f09f99f55e135c75bf297d7": "0x0000bbc56443040000000000000000004510e60600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5192d70b647ba4be7e4b39f1dfe3bfafe151070000": "0x7c75519e31519e8ab8a48f5ed081d4de06770298fa42f2a469619448f489680400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397029e46d21436a8e435cec948d8a0a5bca6f19b7e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ebedde101b40b694e2e90043403c1aeaf6e7140e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e050d97bd5830b7df04e2693074424f7d7070000": "0x54e69813db314fb5f49b1532d7944d4195c5415402551ba3c16d1183cd89d12700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb4e4ab1d79759d29b58116ef6c0158298a0d12d": "0x0026a278d70500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f41b89ea9a14abeb84183d25896b79071a81f5a9": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c9fff9f2fd3bf895fdedae1c18c3951fa135331": "0x003461d4072000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890387d965a607009b865652830e675a2ad5c734a5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51af09a327f7392c00368b5a4b285acfbc55050000": "0x4a7aba74ee1dedb88846e9b9fb572b8be27d19be26bb49c3d0c431bb648c2d1700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ad682addf837939690da95071b9492b064797b9": "0x0094bcba878500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895a79e6221d11f5f98254fb956a38a55076f83d0e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bc2c9667bbaa1b51c94f8a6d157a099abbddda": "0x00ccbae241ae00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a7cb534202768d7daa624051d64ed942ed546bf": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891f6cd77548b31a8d04ce8d3faa358b76861e4a3f": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824371fd1c6b80977e2763c24ce6b4dc6b863b2a5c97": "0x00008d49fd1a0700000000000000000073707f0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973be58c29b09669c1b1edd3153b0872e3cbcd8492": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b6a48781fe2ed596deaff18ff09363ad627245": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ed2c3880ccde98d3366d536feb1d71b7f04b74": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289040e5e95969b231eb8dbccf2bbe7b339588fde54": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928934672e7c7d9d2df99683cb8162b1190aea453239": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51758c524de4497bc170946fe74c3f5a3ecd080000": "0x2c2b9441c516f28c9aa9cbc04f5aa257a18b77083c8ef8092b7e6332eb5ccd5100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dca09f130c47fda19a2512d38b5e7ba1b84e849eca85a93677122fbae4ceb4f1b": "0xc61ed74017d66eceb5eee1f20a012e4774cd79f0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339734672e7c7d9d2df99683cb8162b1190aea453239": "0x006e0dbc8a8d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd018840d66c4f9365a2da31759f36a354306e12944d9c207a3668207dfb7e165": "0x005789f1339729bd51c51cc221efaaeb571b6dfb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397992094bb15f3c52186de0e92dc4912318446be04": "0x0042b38c311000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cfe2d550e5f331a0626b08e9dea48b37c7d33231": "0x00188d22dd1400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514dcf28a0db1114c96fc8bae88f11c95b83020000": "0x9c159c7347f55c54a3e600e3e9781b9982f05ca871bdeace6b6775dca9eebd1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976bfa1d111e63e47a3ee2daf430ff319aa7079fa5": "0x0020e4319e3000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900169f2979d901be42b7ae68ee6f25bb38ad1d10": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f57f2f7af6b196ff8cda28f9ea27010464d009": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006f3b97c4f8cb8ddf2838d296108a63425e63ec": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928932878ea4b480bcc29e7404128a116c75278b80c8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000d9e4a0c84a34414c20b308ade8f9c048218ce": "0x00c69e08b80700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928944401fb5cedde57d33b2898ee66cc263029b6508": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5174ba310d93c322e3039e014730e148bdeb010000": "0x22e6e4560ba8144ea5c993aeabb32d8c9b69cbf13c26ad41e450d8d1a642663200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519bad06a7711daf95c833e9d677d5a244ef060000": "0x62b0506e832a39e504dd59605b37bc2aa7c243fd8f4e15687c85ca5b5737fb6b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0c04181f1437010d0db38d7623be82af40ecd6e": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289562cf2b3763971e591c547a116f0d08035dc6155": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e2d9f005a1d631591c5ba047232a6516890a9d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aeb9aaee118a585de364026e8b449f37ff9ffe54": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ae34487911e04d149472ff9819d3c0fcf84249": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e3c0a9a3d9bf8854865b75f6d4b01935b4eba1e": "0x008a0e5a780800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000a0f7d5a3ba578fd3438cbccae3d3c722702c9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c05dec4d0797b45e7f6e036155261cb1cbb5cb": "0x00f660a1ac0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b7f164ab2ee6bc8581a0d06bfae3fb98e258b265": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289af804c858e8bca9e04340cc5c9984f5f2acfb409": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b948cf71421adabaefa250d9a812c6a982060000": "0xfaedd625e171137c08fa81173e73ed48f4835e396a9b8d0581170de58cecf63900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f9acba5ae9041d0a2d78df1bb105632ad8070000": "0x94d6b2fffc1abde3f0d4b8098ffcf92d71ef84f2439990b8eb9486c2a007755200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3a152213a76fcf28db0993669126eb2a16f9ce070778de9d5f3784ac2cac3412": "0x52d508678aa5eec68ec5faf8f17abdabf9ded9e1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339758a0056880f6490bf35430b081f49d2edf2b1915": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c8958274e69c4799e16269b962753af4c9070000": "0x5ae1ab6d1fffe69e07bae35aa873beb9f1a4352134629535ddcb0a9bc531397400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ded0fefac80ac08719087232565beddf95620d75": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dd766dc1c0441f9b06691d3b19ff1d150b839e7d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bbdb18494bba1635fc00d53735c06eeb171908": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397963260139fd90579c3a8a16292433d4170fc23ca": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970273a1c21222e27a3d41dfb835e07af4b4494c08": "0x00d422a5abbe12000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970037b4f93292da122cee7227bbe94ebd9f2fe930": "0x00ba7a93d51100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900813451b4ee8df7c523fb49b9f817963d0c355b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f8fce84ceddb0e33e9b310adcc5625d8f7b8b77d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51356e3245b2a1af1ba91da9bd6cee82ab18040000": "0xa2a2536e669216a495a670f031cc0499cc4e5d20f1c4d7db8d7d7597e227215e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a6d7337f0454acdaf58ff349faf36febd6f9dadddbebd1198919523b91f6b11": "0x0091da397a6675117a811b82cab27508d75d078b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005ce603c14ee8349fadd8888ff87d53d93fd43c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511a452ec1a37ded42cc595b394b6e85b9ab050000": "0xe4a6bc20742c72fafd45ff5ef53f7073d174aa51bc63126183ba20fedc25186700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890062dd565ced1168f0e8f55ccbd353d41a19e144": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339709d7bc4d2ce5b5369c16b76f6c6297b1c711b832": "0x0000204aa9d101000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5069765b772020113456bb1fb00f7b2f262b30fb5ac03ba3a803f2250f097251": "0x5f9a76fbba12dc70d5c4b71c9638f1c1f0b4c280", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892063700c6e019a814d24f514ec6512711c399826": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928998c97b38d63ba67d0770cdcf8115a5c8a470e937": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700577ac183e66678ad5f27a8e5cde19eda76cf6d": "0x00263134770200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5110fce6fae703c71d69a570d347e2650985010000": "0x54ba59a8d253a79ff9481e5f86153c55e5b01f20eea7a2fb32f1a4f38d6b753200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d86f68361d0a346a62be267558e72dfb9e3b5a04adcc2c9e46fb7b9482f7c876f": "0x599266e9b5c0983b9f68f13f1834fdac9c2f0ff6", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5a4407a49eb2bc29d1d9f1583a0037b94bfaa348b76a0589147a7cc3d35a800c": "0x7d098fec4ecf9ac948b17a179c638f1dbbcef72d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002c5f1d2459a12bd296be7ebc652e9c7d1bf2c0": "0x004ed7a1c0bf03000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fae84a97831f764e66c588636acd728a28070000": "0x7c80d34e75a864a4b6cf0278fe6fc102e87857659ac76af39864360eeba96a2900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339729955c36088322a44d55f597eb63a7f60af639d3": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289211f8d4e57db34f5a7476771ab52ef4e407666e7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895d5ce50ecdb86b2e04589daed8e6cfcfc238d3d7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928936a2688e8e60c13b4a124766e598b6169b0e9642": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896ebd92abd194f0cd6ffd845b0f7c81bc9b11ab1d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896cfc099da855617d28bf1513d6af852bbe836da2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977162bf64f3d1e899cdea224458af61a33511ff42": "0x00c029f73d5405000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51365d4504b9044f57de30f207a684358e05070000": "0xf73baa66d4746e8447877fe051d6dffa85811dcd14c6dceeb29e011b1514f23e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5118177950db2387b53f8eb7150c30776eec070000": "0xf46963643d40844f90c6d1b927d82f67955371cfb3523ab6c272e22a66a9233400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6040e208bf4e558f83104424ed4f442e822cd3a867aeee45ac09d05e295f9166": "0xedf039c36c3fc977c8830d68d75d989d42ed1827", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd662430013e36f7be38e1e1b58fa50bcd5b2ff6985db177978e2089d694fe118": "0x50b2c3a213d353c66a2138e3f21a1f909b0a87b8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890022d7796a2d5977267948e5ffba8b9fe04c3da5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fcbce22223d8e6051bd25cd6026ba660f81b04": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae0686ea4fda9aeff2ed8ae87b70eab0453af7bd4f938128ae447cfb54f61555": "0x4bcdf08359aeae40aafdd2cc282e7c1fbb2d310a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339757d6f80480c6c1c0c7269c7b5ff282d0e37154b2": "0x00301a45ba2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516526bf6d54e7048f2f97f3e1f06e968ad8040000": "0xa4cd4dd151f0106d8157bdf02bfac75f9abe8e635ecc6498b8a8f6acc1f5e67400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e982f5dea466c5f328cbaa9aa1a4e743d4040000": "0xfc99f7d3bcc5a32a627866ab9762e1993b1bc0623cdeeaf16f48d38cfa9e1e2800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700463c8b0c4f1596ada872e327fa84481fed673d": "0x00b4a102061000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b06eb11eaa3455375b66c1c72c109a134580f7": "0x008a8b0e1ea400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397511e81b9d6c360fb6ecbd923f66aad7c34cdffb9": "0x00f4fb4e8b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397996709841049286c8d63df10988e70a790a68daf": "0x001cd6fe584200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8f5bda31f9c72d742e8763200717a78b8081be8": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc04cd98da89a9172372aef4b62bedecd01a7f5a": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a3f746d8fdb67aa729cd740d720c4a64ffaad89": "0x00760a48167e07000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004c7f45a2cee4336a07480fc8fa78c101c10409": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b22169c960de13bcee687ffc210c714aa77235": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5138b54aceddbcd24ff52fdf22db7c0f4560070000": "0x6ec145d10ce8dd253112cf021c3e9b217a791a422a8ccf1312d463b52f749d0400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289668ba98f1cf879d29ff9767dd89dd06c188bdcca": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b4e721d3968b0c88be2dca14041f75701064b3b6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d647cdeac80acda72c27a54c2aaf6e125cba3eee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f0b7319293c3508cb16215561b7f2ff539bdebd3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ef6623036edb96606b9dff2b5b26e697fbbb9e": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891fc8f49ee403b661f718e8b561813d055e7d8b76": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004d9f28eab5867df8ce500efa3bb8a2354b46b0": "0x00b2f58f6b0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890042fc4e1015fd757f149ca0ad34f44c33b51893": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f0fa0937a830c3b80de826638649742fcc0f747c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da422bb294c984d6edf3736feb318ff9e316d1a8488e2bde3c9cfdc50a802ee2b": "0x009580bb9bb318dac9a5b0b3607491c858c45aed", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda6b7380d10c98da303b571403864215b403dcb77b1d9183649278f9c02c761f": "0xd04c895bdb4bde0c4f6d3cdd1d2d6483e5a8a946", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dc4c9ca153c261742b5d71d8dbb799d4af040000": "0x580251e8a4e82ce48d1b4f09b836170753650f7095235ce0d0ad4249cacd1a7e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c2acbebe3deafc493391631727c11da323aaa8e": "0x0084449cfc2f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517e85ba93ec73ad26d5dd8336468fcff301080000": "0x7469d0b58b2bbc82cab494984169f7f189108866270e92a449a07aa3ca96747600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397620348621ce092ee666b698246491e95c8e61499": "0x001c44aa45f000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513f768edc5f35937e181d6e27626004ffdd060000": "0x0ea1f1e791d12fb79e53eddfb13fd9df66627c49d8fdd6773d19ff40ea360f3700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970007265d4ce76f580ccf575ef78d9f63181eaec4": "0x00801a0941bb00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da459850c4accf690b03ee38b0d0b4e312ec1005f58f2f761b01d77c00514ec00": "0xefe2bad68fa91496e13adadf87568b1fc3b454a4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979f10fbb6634415227e89d542844618591a7a8ddf": "0x0080ca6348a991000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d06489613133c162307321143c102143da96dd6309bcc1ba2ff7f1b53f4298433": "0x22f6a08b13d46bfac92f45a624dafd3ab4ca5761", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289974f15f02a0b9715495ef4b620abe5f8debbf0c9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894659d80655ac837fc7f48b96aea70518da7a9082": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bd6e08fb25db746221175b2d50e9fdf7b227643a": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300fcbce22223d8e6051bd25cd6026ba660f81b04": "0x0000434fd7946a000000000000000000b79677ac00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339778cc3793d423ccb41bf53b2659d49a6c42ca3fdf": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900033b2323f771073dc59b1b9a869d1b6a945330": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895e5766ead1ece2e47e415f74fcd2d2aebf46e87a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510446fbf71013b0b1f9e6984fc8132f4095030000": "0xa047e6133dc6937a00131b4c460161d9a7a54ae0bc93c61fb95b057828dd715d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339716621a778e3533c0219fa9db54f2d65c1ffd978f": "0x0074aa57de3101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c8ff6762eda9af66117a353dbce0cf9098d8c1d9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702e3d57578cc2ee4dcd3bfc43bbf0d550accf6dd": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d00fc3e7faefe136c6dc0e7bcd5f13c2cd070000": "0x9462cdda81c70aa96a411b2b570e53e581fb7f7c49bc26dd5c1dd1e304e1a46a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972e3fcfa6ce2e239eb735071d9f86e38dd5f8d8f0": "0x00de0f257d5781000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d5a35d09bd00dd0d73928aa1d67c266bfd6273a": "0x006aedf4123200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511d46047850b56835bf692ee7f42bc30dbf050000": "0xf4ae0f55fc7387bbf3ae242e71c5146254575a1a14d98bae30ffe28acf508c0e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970088f9993ebf41b1009dc7b17a4a01ae47bbfbc5": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cd1cf598b1a50d24d53c7241fedf2de60f489597": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51681f327e254184ec0aa0f48c6081f1e764080000": "0x5813a73dadc69a6b1bf781c33e3a7c814a4454981710271f167757f60c9f356700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d90637eb688d85ae50e97ed270439a093f7e3e56a42af1693ea1921a6589a7701": "0x9e8b9dc427650bb1136f50ab903b00fdee88e946", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c6e3ee84e63c897962f1f40975bf14f5b10c2af": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979324439bdee04087564a0c4d01fd94fc5240f88f": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006dcb8ce8e81b15ea955599cbd14b0532da2d0f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b2deac69d3ec9489812479a2994bc068d133706a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397822b1f91970e2a6a2b4a72b75c3aa890d9b1fad8": "0x00eef3db9dd901000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289feeb1670e956f2d17025c2e80ba377eac074625f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511e5eb8c26c053755ac27078f69b74bc986080000": "0xb841bffab3688ea94e37983ff28b3288746249b87d1114828dc7b030c669a1cf00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a49b7c571e40e73be0122d9256016ebc704a38c4": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896b80b7d073b3ed63690c0962d061dbd88cef4f64": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b84b4c46babd3748c1c73bc408f6999238d00a1": "0x0044698ead0700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51acd502c7828b8ad9e553759d1185bfdf89030000": "0x108a708f579783ecb399a6e3f7a67b997440e4925737e9bcecbc49558d505d5b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890090087b636ef3f95b14a4dd93d28fb2b1747fea": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e4ba1c4ac566a049429432cc11f4724a4e394538": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928928bf51f47e903925c00a03264c7e7a0576785600": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ea43f91226ba2c18b9d8f754c642549ae5060000": "0x56d15a35cf075ed48f31269e6431d2891da8c1305cb520bfbfb60493e9ef026e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892a6625ad8643ea9c894da55c4a5393bbcb59446f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c83f97b509306d26b9a7dc44993e2d82f73a049c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339723803954be1a85583e00ed01ffc8d232edc87e1c": "0x00203d88792d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1c19bf607d2d9ed9f309ab155d73a215e2e8501a6dfaf0ff34a8baa944c68d0b": "0xb13a2ca9b77ef417c02164de32e7a1b34e523d5a", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518db880a8691833061fcababb4206713cd6070000": "0x5688ea1a52557de119e6cfc97be9ed2bf1882fea1c7c2c3c28b32f19ca81f60e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b55be9f54c6606717a0ae67942f3fb297df4e396": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898bf3edf0ef51f211bc580ad6068b21f83d163ab1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5103b234595e835b2615c159a9f04dac87af000000": "0xe626934768e68509f3b657372165e6f98fdefe615cc8e669d5bbe033a647855600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51403f4b7cf3e3bcfe4b9e074a870fa331ca080000": "0x28f1facbab196ec6986b7b5160b9345188d2ac9ba60a5375415a7c80be2b8d1200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b256843e306a3a7d9262a6ca7903f93c37020000": "0xd4b82f0101e2c306b1cf78e966da56058ad177d1c649111f3dd2ebe90afe3c7500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8a14f3b22fd8bb376d4639aaa8011bd8aa0bc34a5fa83d91e11a07bf83a1613e": "0x00c49b7d15f4b1fc5beded08a2d77d7d57373f3d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007d79331ea38e90d35ce0540f37067f2662585c": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fc43f8e2e61130eeee24b8f1d5fa9e80dcdd4f": "0x007a29e1bffa01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976ddce5e113d3d358257a4130d8f2eef6008dceec": "0x00563d1a8e0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397998c1f93bcdb6ff23c10d0dc924728b73be2ff9f": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f7765e7ebfafb17ebd8da8a9422d5d1a9a4760f": "0x00e0b69c4f2f2a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a88f54595f9543cedbfe0697532882ae3d70ea50": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900169602c4e4f14ba7adabe3c3829b6115e244e4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fb1c60db3703abaf29a2d3a01f46c109275e0d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbc913f31cbfd866b69c0b295577462dae9dc4532defcb67d2ddf6f0b09ee447b": "0xdfe138e5ef68eaffac3ed112fdac6c1f614f59f6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d43d052fcc727cb262971ea068d3f94f774935": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243b1b561896f65cd50341459052a69cefb25673451": "0x00008d49fd1a0700000000000000000073707f0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d72c725acce32a689fa5eb670601a139a3dae75fa9e0e77224428896082c5642d": "0xeaa40f6b29ce35d8f53f6bf9b2a7397e3d8475af", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2a7942832aefac80ff43a6842bedcb6f194094474d663ed88c14a940dffc426c": "0xcb41214ae65c8ea58500c913d29305ac2092f0d0", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001ca8b01a535b2f6d01d9f361f86dc495bdb21d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511523c4974e05c5b917b6037dec663b5d0a000000": "0x4adf51a47b72795366d52285e329229c836ea7bbfe139dbe8fa0700c4f86fc5600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c15412599907bcda854ca9f243f32baaf3844a2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928942a49b7c7a88907053060c8011f11c5d26f2db8f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894dfdcd7e1ac714e61cffb899d09235f4b548f960": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51821df780609bc44763c6d3cd576e7c934c090000": "0xe0ac044eaf1755905c1b70d749a8412385612930a28d50f97ccdf2e5489b8e2800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895450bf5155e553cc022385842799d6a464a835b1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f6a2e7a2d10fb2093f63f2f7923622b3f357f8a1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897025fe5275828b45b97d3b950d65666dcdb9fc95": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f9f169d904363571adbf247965ae962e69cadc7e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890087043671cef82fae55c6e6648e0d763e65e2fa": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700349f41813fd23d0e1c6fe6160d5d44f9931624": "0x0098d65615a101000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19503ba8d4e31714fcf961756469800a7d2ed5da6a62c32ef4477bef2a1ba05c5feea57ebd44516a8257dcf9a3b67b": "0x82104c22c383925323bf209d771dec6e1388285abe22c22d50de968467e0bb6c", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824349a1c510c50555b7be6e68e064067038e5499748": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a2e5004a31e7b931bef05499dc4f3dca1b616b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289742aa56043ed0dcf2673279f39b7dfe2abaf3610": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5205f3382194a16e9f1e95e9dada0ca5b5f44e5f35cb257c054a5b072ab25151": "0x1933a3602d1ad20840dc198946803e0ab2b49d06", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f73226e1933cfd506c16b06b172e564bece222d7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894ed4ef795465ef79cd0fcba0f6ca3f35a1ac1816": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f1e189ada672a8b8ddf69ce356e287ca318f99": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19503cd8a23e268464b062616265805e67b64cf07d4d258a47df63835121423551712844f5b67de68e36bb9a21e127": "0x88ee494d719d68a18aade04903839ea37b6be99552ceceb530674b237afa9166", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d26a9d684d5dcf7d34c82d0e88b811cf5f9faa13c95ee1eef1aabaa1f2f3b956c": "0xf54663c66d90010e39c7c5f3124b2965e5f0d069", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894f813b5cf2750a59a45f3c5e50397d6ac02b64f9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928992fb25e8d9fa70512c5709c401274d1e6a441f6d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e4b9fc84af5b73f2d99d036273766f211d9d6b6": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898a807188cf956530898c1cb2b0017428f95a3560": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899bf140794f7009345dc3de37523f63ecca1b155f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5ea3d15ed87ff434997bbea75c8be3e78650699bacd6bc7759045e22d90ad477": "0x50d919314f2981bda224370b7165fde7bd733040", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928939dc8b68208f3cf7de41f8129623dea433dade6d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e2d9f005a1d631591c5ba047232a6516890a9d": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ed9633f73160a3c6b6162c5c91ed95aefc29525": "0x0022bdbf630700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51332be08ceaf32dd002f4c8356033c0c976050000": "0xea35e7ea94ba3312211f2313f6ae0f7120ff84e77a7595b49f5243a921bfdc3200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397386c6c6a0df3ebf66b64cb34c6f8834b9711a2e1": "0x0066497f817f07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb2ef83188323b61e2cad0ad628bfa33e45cd0c8": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51254f2bd413726f0294d3373c2373ca582f090000": "0x20dbb8000a9a464d581d28cfa5fc2f4d49e4a1159e9cdf039111559fdd2c650200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d904187b85d65703dbba21e51c74e2d89b492c9b0d44f3ec3b1974824d3eec95c": "0x1b289087ee4dd222cb003d5cf9d14e376502c7c7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397318aa87413115388a04d0083e792849e09fe496e": "0x0030bd6c704306000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b925e4006856dc4ecbcf9144c3e93d9d5c060000": "0xacf2842c60fe2d7ddac8ef14f56bbf25fb2994330da54be6432568717945f33000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d80c506c8a97b330e37357f791c6d498369d086fbbe9e78d67d7e07720d51ea6f": "0x2085aa6de1e83261fa966ed09b518c3eb3ec30bc", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce46eb5500a059797f47cf38f119ecb0eeb360b856f67fcb7a74e98f52b84157": "0x386c6c6a0df3ebf66b64cb34c6f8834b9711a2e1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b50e79852b9973d30f5b775509cd3d8dd8bd78ba": "0x00e42b2c22294b000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928972381e109c9f9f9318307e249fdbd0304cc6559e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928915b8f1a95061a20392e601bb5bb008415ba20ca6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339772381e109c9f9f9318307e249fdbd0304cc6559e": "0x0058692a7db81f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b0198e1f457b40b590e532237ed88e5ee52dc8": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746ac13adfb85fb7261d69153e73b006e585509e3": "0x002421e0b0cc02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a79d6c7ad0312485e375127d0844a4658b220fb3": "0x0010f50d108d04000000000000000000d9455d0700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddcf71d4ff2e0e30717fbc3f2b8cb0074d7e950971e9b77ede358e6006a6cbc42": "0x4ff82054932bb21f78c58582390d34e16a479294", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c6c0f1c8825c7ea730b6fc23bceee8ee5a8389": "0x00920d70945f06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a2fb944dd8930532d3fb08109bd7a46cf07a75d0": "0x008eb862b85c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397335c0552eb130f3dfbe6efcb4d2895aed1e9938b": "0x00fe42f31e3301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009789e46d6734cab174c01e5811d744f664504f": "0x00d68c1be02800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a3c5437ebea4546ac6e6cfc1d8a76f30a6539f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510f860a14ed025f1699ac5f9aa2bf6ff87f050000": "0x8cdefebaa227c1477106c9276b992ada6bdad3ed9164d548dc8abaf899e2ae3900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ddac589d703e854e22f71b8f2fb6efce134e5c0": "0x005892837b5700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ae7f5cba238e1116167e0efa51b76d22d9060000": "0x58342df06e837a7ff38096d1169b1f87938fd88bd84c81edcf5900fc525e791b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894214a1879b2678aa9ca0abcdc8effd02e40f4419": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ff44d535cee05fc476c35232eeecbdd5d5ec9b9": "0x00be6bbc8ea800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f38ec7db08dbc9613964110529710ed1bd070000": "0xe07628deaa9c6fbbf2288f879396ff3566871c0dbce85c9e23764d15b810657f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d46a1fee5a1810662ef7c82a2e91a37a39ab9611105b3a45717ec131bdc4cfe40": "0x93011e03417d775496e3e81c5ba87cd973538dab", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727ff5ebc0d4ad36f0190d6fbf8d774ca7d4acc34": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc6a52590a53bad9273441f2e6a594885b7c567b8dbbdcebe3b40cf561eb16714": "0x00c03372f10f16d819de4d9b22f59caa35b91c0d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397268b05ee0e0e033bf074554452e701a250ed3375": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890b3967aac9abb324d90ba784b0a4ed41d2a7c257": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce2dcc3b6911ac513d32f326bb72bc44c1ca1b84": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b74a9972cc5dbed5eb8714672680d8a1bdecbc3d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fba333b57f360e4aacb9d0809928fe8077d19a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51094dfefd310bf7fbd323569c1cc890fb06060000": "0x265508bb6b8c2e04c18c3c0d7491fc36935f55adb4ee5ad20d5d13b90e1c497800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51526f1a827f52287b95f461f312b4a97975050000": "0x96b238d8b52668f90c36ad34ec02572133c9f234ca8983e33fbacab88345243c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d108a708f579783ecb399a6e3f7a67b997440e4925737e9bcecbc49558d505d5b": "0x96cced3c89d0565c7075aad1b2b19c49f449af1c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d4340fef5d32f2754a67bf42a44f4cec14540606": "0x0052dba5770a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003df8ef68083daaaae470187267dd53bcdb133a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896236f26b6bf5e69bae11e794e9ef25d3895b3b1d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001720fe2bf6df9dab32f313343766cd4a0ac2e6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972bba2ac16832d15f8f415f1cb351fe20977ca399": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928943dc2d9be62bee47b83825a901aebe29a1277454": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289befc4249d323465b36830ee666c6df935904da3d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900368e2ec353e7dc90153075954cd3dca551f35f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970087e1ad6809711d463c993d6d4396ef57423883": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898a45d72e4ba11ccc796d37b6b1d9518183fa451e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899311235dbedff7b53b7ab20dc27a76aa9708bb0f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dc26b2ce9c7de60d60c165f8c70ba7f8b08286aa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890db4dc6e5a9039b2b8fca026963655b04596e903": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ea9568c9876a62f3951a61b1acd1dcbf7a050000": "0x7e1e7b99b256c9faf8acc6fa17a1ad3e6e30cb99ca64df0daaef71735f21b07e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512734545045b25902f691486208e04428f7030000": "0x54730499c6c53dd16d1e3f8007b64be019cc9229db22d36a12e44eff1670cf5f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518859a58b8cd305d900ca2ba96ed262b429010000": "0x6aea039650e63303c3c78f7b1bdd0be8cc2ac20511c074822ff5dc02bedbc02e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de01265d6a89565dde0b89e1b68e74b661d389dcb7619efb71e5c9d8ba46ec722": "0x3e0c4d785244c2df4fb88b81b2ca0aa7411a6ec2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bfe8f085ce6b73c1e59c3eae993e73125180ae": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec3c0312d2a35ed0677a7f8eb29116ecc4ebb6d4": "0x0040b10baf682c000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894287603500f11aa83802c4c02e2b5a9130ebe23a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289622f1c8146096564ed842e48b498c08fb298b4b8": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de2782c6448329ca3bfa30c87ff5ee66a059329a9a27ccf8e33806f0698c38a17": "0x6e33fe6344ffd1fb1aa35d7823021a99e10aa1fb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ec079be8fccf89a39f8a2ffe35bc08f3047876d": "0x009e359d4a0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ce6e5f32bd27b3f64a693b593378b389c5103a83": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f6cffc26fb979a2a3d44cb74b6295d31974e4ede": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ea7272f84cfca9811d2103170ffe0dc551ed3ea": "0x009c778883b200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f8536ca7a25cbf70df754fa310079ada4c6114c2": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f4c327d9fb68a5b249d96d7680c8203ef4fe56c": "0x00e66123a67e01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890085a7ee9578243c26fa140b97bf771178297a3b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700adedcb13c0420643327f35b6ad5da4a0d8c259": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769b293a17ac91de3552bd7381f8753f385f1cfda": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfe5b9cf85b687c9f15be1e46995655e81764937973191978549c4362eed97227": "0xf897a81a6ab5aa5cc24e18c9976b3882cd0f4ccf", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8ba75ea553f7049eb54e20e3ef220054bbbe583": "0x006c9bea403b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701c08575d845acf2bdd1df6b449afebe9e8910cf": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972967ed7db96f71cfff4626dafc29258e337a26f3": "0x0080afe64af904000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769b8875ca9c33f7293ad4aec9a36577c257041bb": "0x00500a82d0d400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c20dbe4d8839b6953c7528824e42dd91ff1c564": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898b584cf38bfe7d50809bbc2a622c7bd118a82577": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750e36dd2f9f0b112a8eedf160bdd4aeee06dbed3": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9867e6bf67fecdb4e31c565bfd7854ac3604f1718e52cdbc8464a112681ad765": "0x1de627e3faf8e64287bd2152ca027e4eff582790", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972e05cd4a04815510ab2d10464db9c1356cec8bd1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3aef55642426e0153ede83ed786d7d8bc66ced9f461bf5a77348032dddcd8533": "0x0005ffdac0973574e3fe91ff31b254fe2fd08acb", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbc1deacfc7e5c6e5f0373560c14fbce156ff2a0ed7e208d049ccd985dec85545": "0x6c11fa9f82689aa0d4d41f2ed3e3a80932707b46", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d729fab2b0a01ff5d67532d4632d22c6e4889a076f88a57dea33a675381cf7b38": "0x009dcd9ee2679e1a794297acdcdb9b325ed9f2d5", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ee9bf7584ef015af3a9eeded671e1e424f0e62": "0x007ea3f3842900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b7b02c9a7f9b6444ef6e54384a5b5feb6b36be5": "0x008c2a02902a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e3597e85a29412f80e5597cacb09fc7aa4ea9d3a": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f76516ce11965b9970b53f7cbcf53cd4d984ebd3": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3004ccce7f54f6043f13a030b1f07231d81826e99ffd3508fddfdbd0e5a95854": "0x0be9a01de08f7c18e973f073844aed6d8414a5e6", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51abf62515c4338d19703781899f01c26df6060000": "0x9a5fa029a852ac699897b9bac268e3baaa9c920fc37fae630f62a726b1f2584000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f0ac4a702918dab29f9c5c317d250141b0afd8f3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b986ff7069c7e6c8a4bb67419d839a8cd9d07d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c87fba5f5fb3d590b8552d06d1b700acf5000000": "0x62894f873f68ec0788abb573bf388efcc5267b7164b770abad90cd17b65f161e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a6ed25e84058c2810261558ebc593216aa8d1bd": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d70a7e3caa9a1670cb78998b9a9e3a81b834c24d5cd86efedccfd854b45ac7d67": "0xcd24a754c817f83acfd14e75dc751f3fa9babf35", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894678b10000b032197ae5a403058cd72096198650": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974fa4a8ce59764fbc5166bfe260c1aa4eaee8023a": "0x0074ace86b0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890044f4a7d8f9da9528d852b1d02ed6e867d32215": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890d9905f0c546708f12b180ed038e87fa702e0cad": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ac0d35c69dc7dd99f83eda4764a231c497040000": "0xe8382680e672b8403c57f2bd1073c34219fbd40160e8907ff4cbc548976d263f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970082f8170db9a32e8cfed10aaaca5cba2c20eee2": "0x00a60beb412100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d680f6ff2de0a6401afa65d55ba9bf6f2cb6043914916950ad51e3eade0f0d677": "0x61aa4b596264f9e1eabf688567e8e80080732169", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf2e734042a355d05ffb2e3915b16811f45a695e": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ac00bcb875fae707ed8d800e17985d174ad3027": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892ecb3d65993040d26944b347119eefa31f7bf3b4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928956f780c276f972ecf6363412132bd9801204949e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc0e4f5e8f715c5e6acbb2f15742f021693ecd39501613dfdc93a85c1cd77582e": "0x00eb8e47a06707a3dfb17728f8961009adb88eb8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897d64d09556b4e737f932b39dbbe48fa4f67d862b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c34cd6c012ec6faa1cb8f6659a4e07b7f0834f87": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0be27337ccc1182df91cd4075af2f6dc7a67c5e": "0x000e31dedb6500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900957438646d37820df1a7d2434f4955f4c930ec": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894fbf276d6fa1f36b0f0b12fe8182e4bd108ec9bb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970138bd5b9fe5ee16cc0e0b0d63adc94a6ad7b21a": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900411a29c7d830c7e7461e7ef541b1a7a00453ff": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ed089a796d2a81919e46643e7c2351aead6f1437": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c14584ac76ee1a0c3d35d336f2448c65f1dbad7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512c399c11d782416ac5a2034d728fe62826000000": "0x404e40fa7bc7015956de0fc04bc542baad0442e04440387a464f85f77d25a25a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001ead7676d5a7c09c64ebc80de0099cae972e45": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513829c2935561828b0a5d36ba382ba9bcf3030000": "0x50ec868243f5ec5af29a7c679163a34978815b6f1d6e2b871f1f361cb7a1f90500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896c3a5ab4587b414dc754ec4c26105385a8cbff43": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3af8b075de8a04f234f06c62ab44ef258be19bce462385f9d03c1244dab2734e": "0xc186dbc2c878448f2fb2969967abcd307d98c247", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289387902d21b6f76d28cac09065719c4f48f4cacdf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000fa37652ab02d5da570506aa4f0625102f91e8": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397862772a77f471da418313e3fb7680d570908b206": "0x0080292c6bc102000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df4164fa5fd5aa70d2d524d72d9e17d16a56946c3b9fa97d03d2aa2a05e25cf4e": "0x9405ffe8c225312b403cb49a313e7a0da78c1387", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c39eb735f8dbdf396c2749f298cba2bfd74cde": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397968e43f6be8d8ec1e8ef7c8d5c60f34eed8af3fa": "0x008c4400e13801000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243bc09b4284743f45d2c07926caaeaffa1bb4b6d46": "0x0000c52ebca2b100000000000000000030fb711f01000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bffbc05987709ade08d71b36d7e36fcb7a613b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518f7e72a6bbb90f036bf5f585a47f16b896050000": "0x52528ac5266c38e3558705368e9627a53290f0620a464fd74378bf6fce3f4c5a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bb357cc6b9eb80d1a3f0d06435f22fab24080000": "0xe021bf4bd6fd2aef6f2ad1e01e89cbd1e86ae489393d90528d634c06a2b4e20900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ead61e3f92e933b8ce06bc76061f92455029fb34": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700165863e6f9608161d8533e213c009390fec3e7": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890037b4388420542e29d72d06ccbe5cc751e17867": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009e7f3b1be6c5e05c4b3c39804293b582ca64b7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd639c3f23f8d6d929550409f25e95d7b02e50a236ddb0e2c61c0022c04cd2c25": "0x0096746df961fdae3247ffa893802d1cdbe60e86", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289441dae5199e8c642556707176913c2942b455251": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289574f85614c44755bfd42ee17a3bdebbd67a531bf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928958245d4b05fab653dbe189c35a98c9e4d84d67b1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a3f80af332d2b92874c1e0f76af6f23586847357": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bc09b4284743f45d2c07926caaeaffa1bb4b6d46": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824350ef20ae1ec6ca0229f4a3195401f1256985bfea": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339772d6b2f916ffed3858da78c4b91c40954bea13fc": "0x0000b9d8895200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004f7dda0a8e0054890ca92e930239cdb6a6f74f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bf382c70d3bfe51f50fbb462568ed1ceafe02999": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d20c9f5448d22044f25fdb213b6a5fa752b29b2cfb57380deede293c7dc3f3269": "0xa3f59ebc3bf8fa664ce12e2f841fe6556289f053", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513f74fbbc6e81855b30b336ac2507235142000000": "0x3e78c61b1083bde0307908fcb6231736fc9d51e930469146b4ebb45c68167f4b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c8f5bda31f9c72d742e8763200717a78b8081be8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289963260139fd90579c3a8a16292433d4170fc23ca": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900feecad71fbf3f5acb1569b036cf1bd14056316": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893bbfb20c83b79f8cfe3c3f7296f0390900760745": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978a654566edd646283c920e3225873fca5370f489": "0x0014ee15324c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775d27075d8d9aa87e54f05a07a52c5a117436cc7": "0x00fa557518f225000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891b778a8d83c0fac09f992fb701d1c085cc9c76d9": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c3a73dea8ac2768c308aee8af41a7c5c11090000": "0x368d7df47ff9f015a247ddea7b37abb1d56387b632adf8393bb73f606540fd1f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4465431b88b42ed2cda2b4d4c50b38ca1ac8f83": "0x007435ce717406000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928909fbc09d7da0c050d4fd80db0649b30378cc4839": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339790a66cd2def2d13f4c8d09222a11cc2bd508153e": "0x0034bf3fed0200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5112f53254a863ff9d51cc7efb1866459ddb050000": "0x4ca2f2067fa1c81a353a98e49b7085292f3526969d67362080bece38eba9c93d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5141dddfb722d3ff71c60ae7f5e314d25189050000": "0x7c0e9733213d62d53db42c6ab23ba4f20748c41c83f28f7f2ed935a43a32292c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000077e89a2702e5438d2be4f7e8744a5ee2b60a": "0x00c26f318a5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5688ea1a52557de119e6cfc97be9ed2bf1882fea1c7c2c3c28b32f19ca81f60e": "0x344640acab3fe1ec3b3f7af2e9b7ea4296aa7085", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007486e5e3a85ada7f1ce1fa177e02da6321ab3a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928957ba0396c511c6dde22e4c524c07b85411d6d05d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289af5b50ce2aa522d8d9d6f06247ec7d877d0ea3aa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d8b29dd8d38485d5f9324eac3ba03c31a71b47e2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e6d069b07b1212c829691f3b421b1b44ef080000": "0x5075a1c853e34a1d380591c710d35608dead70ea561e4d6a8bb35639514bc30500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700aa569e5eeb25e923ea96578d77a73a53bd643e": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7ff0231086abe3e95ce3773d60a39bf27321ee2": "0x0040c7c59dd203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea3b864640285099bf8b3535affd24c83050b306": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896be555d4469720a6a980245a1a2139a5e678e415": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0867efd74f0e185120843b417f4b62e3a937df54007f8b68eef468bf97e2e342": "0x5223d8d88e106df03f953b6ea1fbc11db396f2f7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a59c51409b63f4900cc5c90374036d3a98f7673b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c09c648b43dacc11c63f053c95beed79c3e7fb31": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2ee50c5aaf279bbec8871d5468131c9463d590e48a5a5e12a6ebdec60cf41c20": "0x0001376e9c388b5995e3a115f7d2813dacd35078", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d2989b71404e366138b454d9e27295671f96ebd3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dfe138e5ef68eaffac3ed112fdac6c1f614f59f6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339753972a2e0db345848a8fa288b902d1be01393ecb": "0x00f6d4ce563b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b0c6e7d0d2756e3c703cb749a78699880892744c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ef732c7ba71e0ac5b110cd10879df9089c20bd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c15031d35a947d4f64c09b7153cf9a0b2b18a431": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893ea43ab661f2d2583d0f3234f74dfb7770d51e00": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5133874cb2f7d95da28414231134b739b740090000": "0x2e238e274e49faaa50d80cefc0bd04d793f190d119a4ca4d05d6e5a9f951207a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519935a7c1ec3cf65a725c4bdad7cc7ceac6040000": "0xe63503ec5788a8aa4911a43ee47190ae94f2ab44ad62096bffc56a422b38b26e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e0b481719c0a64b20d1e541cb40c80c2384fa61c77e56bf4787ab94447cf54b": "0x7eced1aea8a70ed73f12f0550ff58671ec34953a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722b2d90d35c20a47c6f579fb6603778e7010940b": "0x0074d5f6726a00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515d65607379c3136ff7f977ae0c8b3edb9b040000": "0x0023f35fad621e22d2da59dad0233f8d93e302cb55acbea4b2467e6a59ec5b3e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339794c90e0a573db26467e0e812090a9220c20edcd3": "0x00624c25681301000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b3a82b6e21abf58b057077ff00130f292973a041": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894d35300fe32b48fc3eb97d1033cbefe8aac2d2d9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a9c3868f96e8a3e5386470d78f78046e09cf77a": "0x00c68d5f688f13000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765b761631b6f2fcc2c085a544b6602d1317dd94c": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d888f666828e8328a33647a47bc97574a6a5671819270cc01e66c7139a1a6911a": "0x42b1d63ebbc6ca0cc4a679fb341c78d1089702ea", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db067a8a7015b58d16ccdd5dd7ee3e2d6e07f725bec022f6b6604adcb058ec70e": "0xab416fe30d58afe5d9454c7fce7f830bcc750356", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006261f93219f1cf1b3468d807503dce5a5b11f5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289599ad3f92f76e859f7b7a87dbe3aacb81e54c6e6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d721f7b0f0217f3fe8b192b5a2a7feb22b296e": "0x0022914e4e0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb9f0597834168a78ec443f09f75e3d62ee98dd4": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a2342e466f377fdf800a11c7affefc3e1b6e575": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a7f5082cece0be9b14e8be6c1747d0fca39ec8d7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fb82d696619496ad28d708285770225159e2236f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397697eeab43d4558bd0d82e805d319d59578fd12ef": "0x003e3ea46d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896cb08b8792e23b72a3af06933a30997d51ad1565": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de8c7ad65c15fa3ba64424a61b177382a0c5468135aecca9ca454f5e7ce4d305b": "0xde4d5886da98c3a1140260aaf536a2f1262e2948", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397048109448c4730ac047abe0097034754cc9f0dc8": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970023d77a0316ae6c765a6e1c6616be7030f462dd": "0x001e2ac52d2400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a5c6dbf8963947d36e94126df831a50df8eb6e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b33841ab8e4fc931a294256066286270a77632cb": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514b73b7b8217bc22c2b83aebeacdd2473ad060000": "0x981ad92f7900ec801b1935618f031c7d69f089dc84e2fd2b4c09045c8b7bd65800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cce96dfe085a2673456d6bfb80406b8b2a0483": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928976211ee383d28be255a7a44de4a5e641a7d88e93": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516cfd39a414aa59c64aed47a6ce0ba6b60b050000": "0xae449c74fbd4b173c01dcf0de0add765a844dc463ae5f0d2b03b2762a3ed216500000000000000000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195018456cbd802f9216696d6f6e80b09bbdce34c5bff2f9f212118c05296db12854ecd09ed0eb0dc7714c9337ce29": "0xe240d12c7ad07bb0e7785ee6837095ddeebb7aef84d6ed7ea87da197805b343a", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824376211ee383d28be255a7a44de4a5e641a7d88e93": "0x00e094fb1eaa020000000000000000002bca4f0400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9ed22cfc6877c1961ac2cdbe5536684b0761074b8ea475d0c2f173f5989be904": "0x3ff9783bc7ee8de42612f752d6145fa729402a59", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975b279c406a13a1772c7c382d1096b04a7e65e753": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d62168680c9ed6e456fa59bd01525a53dd6fa991757e920482016e7db6caebd45": "0xec3c0312d2a35ed0677a7f8eb29116ecc4ebb6d4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928956da5ac544ffd544d8c78afba72665b79dd1b87b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892b0b1000a023e99555058d8dbce1debbd149a6f6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512c852cc3889541878bb0980da71548fef1060000": "0xc8e921a1e3b5b4045d4bc9ac039e586c127deee3762ad208206099346730926800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b82ec69d0521ebd32f7d445188e5b6593ee49046": "0x0062844325d300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5153a5605ca5bf08ee5105ffd1cb49f87611070000": "0x8ae2ec50efc3eab6dac128888c6171c2c1a01a03fd01109ec467daa2c3af3b7500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970036c76ec47dfc17a96b1a68893bf269e1c2875b": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d84372f8b7fefa198c90e3ec77d5b062e0467b32": "0x00e83abf652b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d489ce3deac0c0573439241af1f5b6aefaa31bf07c4cc1fe3191f6de83b44952f": "0x004d9f28eab5867df8ce500efa3bb8a2354b46b0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c11fa6623df9ce654d9b7e75841cf9156ba99cc": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890620a4b3b1a36178015ae2c7204498ffb160853b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea1b65102cd4e98ef88d31c7d627ab4d4f26a92d4c68bc516ab7ee84cf326e6c": "0xa1cac24ee6eb326f1640c5c97b8a2e260b4452aa", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892fcef6913ba9d9ce25e509979180d5fd0e047b07": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893d8f5b9f1936995c3db39bc0da5c858015595328": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289459e0021404e96b2cccf7ad0611c5ae87449704c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339772705657a219aaa87e5b7223cc79cd15e33e18af": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f85c6f6c7e5d78513fd9317d90409f71a58099": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ea3b864640285099bf8b3535affd24c83050b306": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f961ef1f20028e8340d5618d3bcb077718e58825": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970dd9b78c6d063cfed41ee21c7fab626f86b64de5": "0x00ea7479ef2800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289997dfab7fe0925ba6e6c1c9abcd20a840540095d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dbe27dcd12d17d906c2bc1cf9bbb5b61fb070000": "0x96469fe84419254dd3e2e10075b0c69a11bd362768481b7c527279043b7d041a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510d8132ca9938d9fb4a3d18e1418621ac18070000": "0xf2287de36aac9be3d8253ca258bbd653f66e65df2ef87d41272ad8ce0cb6c65800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51392ca2e3cb9a01a874a0234126fed20bb5080000": "0x663525fbf0252118f120be94f11c5d24beb308b9414cb670ac1bcb05edd9de4300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1a80b1f8a44594e343b3d36806898616c3c123a": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c0798c0df1e87069417e76b8ca4fa089d051f1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a6e3ec695183eb5c9808f550fff6a29d2f40de6": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51abf05b912549956fe941f87105ca64ab75060000": "0x38f3bcebf40af031ddc003ef309221ec57a19da01d1c3a2771478af5a260796000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e6224fd18cbbc2e20a5cbd2103d6e8cea741f8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894d41ec9ddc83bdbead278781f9b8c57fd2028dbf": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51557ffc62f29c0e4bf80df9c03a128c3123050000": "0x88ec6a8cc750ec1221580f795c40b2e270a9724dead719ed76076760851f587800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5159ec21b559e34ef529013c057dfb1e3527080000": "0xd01fdc12481b7c5de7004e8dd54ff70d4bc561d3ee07de32dbee35b7348b813e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700964d7fd8a498f37164ba1c1b5dbb99a3c90125": "0x0036270f8e7701000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289de4d5886da98c3a1140260aaf536a2f1262e2948": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8630c7dbf3b9ec8021876f9f1fab265df12368e": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d989af479f0457113b84f73d9c0bf4abcb2f273b8fcb944ae64141328db140e68": "0x20766f01d859f1ee11e14428d9fb96bb1ebad946", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5100c8ba1afc1f02850984abfd05e26ed334050000": "0x527ed0e44c244b57e8c2013fe51f2a692650ad1eb58340921ad245bb3299351600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0c0f7fd4a8a750920dc953229b45f708754a2a0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b79356aad9bf2116efe1a66ed55bf1a0d124393b": "0x004e3ef96e2603000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976aa251b33219bd6095ffcb9db692ce2abb203e43": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005906f955d7a8c58b036a9c36c96398cc40e32d": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fecd5df71e03db79046adc4e474d3d0e4871e2f3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c26f719cdfe1303d3ef566ca2ada12cc56407c": "0x003ac8acc61100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890de05b51aac16e7df22a871673adc10eb572fe93": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397175a83f4a1abbb88f6facc969d669cae9f48d7c1": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e20357f4f128753e6fc6de0e6ac51e897d2ba9": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300c5137df3f8f85e7b8d1f5059045ed0639db413": "0x00d4e9d4ccdf24000000000000000000693aab3b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dee00d15dad4842dd984531c1375fe57ccd9e5bc47c10fd505885e1fbe107aa56": "0xee41bd5428594191446fef91d5b0de95706ad49b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928929feaa65869e737ad53bfc2325bd8ffed8d27a07": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978234c57f49a272ab89ed69f445cf9ce68406a1e1": "0x008ecd52fcef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824351afd27a799424910c5bfbe69646a6f87cc8b73d": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928930d381605485745197162f89fd80937d890b5358": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928972d8a23c70ec138734d5cde0fd9e3edad5102320": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700130a5ac1ae656f19e54e2c28c7d9b4e96462c1": "0x00943d4de92900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513fe60cff75b04f82f57edf148c92a5715d070000": "0xa69382e0d2fc2b3044c30b46be39ce071c773b9333d56631783a535be929494d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007ceccc832e7d85b6e02859a60ef100bfb4a2b0": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f374deac1b5daf9d8f703189f1eec12bd80295a0": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243f6a2e7a2d10fb2093f63f2f7923622b3f357f8a1": "0x00e0ec5e0b6400000000000000000000a0e3a10000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b0966d51374a7fea1bed099f4d92c3fbf0192321": "0x00a0325a721f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008211ed672526f479a537039766a8d8daf809f7": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d609aed1ba0cddb3e20270d959f1bea0923325b221f31d85579f61823beb16a35": "0x3e1404e9af1c94c9eaf8fa92e2c2e1a936ed8701", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243007abc56f6083d36db03065f7afd36c55bad6afb": "0x0000434fd7946a000000000000000000b79677ac00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db221f3d33adbabe1695b6def8f9fb3b30a33c9eee2e7b024341152d5fdbbe233": "0x9e8014d80afe8da0e24e90539b864794c6981a0a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003bb46bab150b189a72adf721963e275453ddcc": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd827433e2e48f71fb28bdfdfeeb6ebef2cc8f1bfcd4062487372fa4a0064ee6e": "0x004337ca7ef0391b38f913689626697307aece2b", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d901873793cdc00c038c78a1144c8c548482bb2daef46d5cc56e76ba142ecf632": "0x23f9313f69cc340859fdd8afd5d69f9298fd295d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000e229e2cccd3c40cc7d3182ac72fde71122213": "0x0012a3c85efa00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518e6517259d9415c471f32484b8d1099d34080000": "0x9641374a4f6f48768d9a6bd815c31807e4765251a974ce0b0c75f2382086fd3500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008bd6775fb6055f78ac30fc24f3e55669499f5e": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397163e5addf68d6e21695adfe1f8fbb33c78d9cd4a": "0x00203d88792d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfce03157d8e323968680f92bb8e16e468e35613b5e9645d56b736c1fcbcad72d": "0x968bbcc804a1003e95b3150c50fcc25873e0d8ba", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397351a7dffbe4b4eba06a0b583c970c4f83e89835c": "0x000a78cce22300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d3b766e58e0d0aecf1375297e84c798b15936d1b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e53166f4d724236b4235a9bacef0e425d9f13956": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890030122b94e0e0c56a5b04feb3ec224244a5b18c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007cceedecc880f30ab9f9b968e0d6860d51c6d0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289879b86a32a6d56f04db27fca343ea8844c98fb27": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a738917e17968c22c3ae246a69df2f64fea012ac": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a802d746c8079759da87cd76c3cf7d0145080000": "0x8ed1e4ffbfc0f87a0ca99d9058e2900c23959e1f410fe31f2648ec3af27006c200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddc940c013d2869a42dfbdef9882e33b67ae45dd42494db04d49feef8dc2a6804": "0x6a8147b63c67b2d13f3d19f6607ae3086f088490", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ba3fb82687f28ce414dcb4803d05eacacb697db4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c43ec0fb4c71b599ab3b5e9e6fbd89553eb615d2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892ef38ee9ba641cba4c3b92a1c594dd6e6708cd3e": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824344e5715f7db1a59de2af178cdad023b16e39da31": "0x00a0fcb52d2a23000000000000000000b214e73800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c88fa499e7561e464292a8a3c76f4f0351101bea": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c1b9adf120f8247211132d86a8b3c9d04dbec26": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006c0cc442ab4dc5ed006af112fd7e064511eca8": "0x00be5290be5900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971b1a105919ffc05d685f342385d5aa4ff4260383": "0x007c6a12795600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767cdd37fa7b4c8dec31e218467ff93f2d1d44efe": "0x008062175ed158000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5104a6f42c7570266e3c52bf00f08540fc69070000": "0x1c19bf607d2d9ed9f309ab155d73a215e2e8501a6dfaf0ff34a8baa944c68d0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d169fef7931a98fdb221a745be8614283794ebf9123d4486a59e7673b86423f5b": "0x00d4f741b495b845b4e4ec9bb7851f71c854d4a9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006dbb368da30eeda3c789408a6162512e75a788": "0x00e0758af30201000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b69e155d8752222d3efe8543b27ed9e6a4070000": "0xa843370edee7d8a3fd7e09330ef328b00788b7484afaba29241cb36247e4540d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51acde9147d1535292a684ac831c939aabd8080000": "0x24fe4c500ca6a4eb82c597d12ea9e5925549433fde896d7aa5d7f929cf87e17c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d4502a61e5f5e02b811cae81ba9768c136fa101": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786e3d8f8c1252600304047adec71785c41671bc2": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcee1aac0dd848c7cdd6be9ade44d705c02f821cdd2bb857a3add5388b3240036": "0x4e163cf2b25ebddf54bc1ffa47a56b96e820871c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970037b4388420542e29d72d06ccbe5cc751e17867": "0x002e50c0ad4000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb0366a7cfbd3445a70db7fe5ae34885754fd468": "0x00eceb5f0dfc3b000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d98b995d8a902881fcb8891ebe35d50318453a0fd745232ff11e8cbcd5b11b700": "0x1d55410119f0d9f4d3eda0a346a43ff04e15b36f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fbce25b75b05e04b9f22e60721aaea19e87e92": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512f16527cebc6e365a934250f691dcff373080000": "0xb0a08e27f26e1d8b3f3c61643df806c8b631a1fc8b34cbfeccd406a29e423c5400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0c0abd27328b055be235a79d6b8a9ec1ab7d38d4c6f2b6ff20d9637f9aee4e78": "0x211f8d4e57db34f5a7476771ab52ef4e407666e7", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dae64afb310a3426ad84f0739fde5cef61000000": "0x9e771b378ddd0f68c41961af73e4e93c78dfed5778d5377673ba9ee8573e3d0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a774182aaae3cb75b28f24b4b77f7c96b2b820b": "0x0076cf5ffa7b0c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ee9f9804eff1886d23e8a04e5bd9ae506b64740": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa5fbfcddc1a8cc93b95498880951526ee7314a5": "0x0010a7bc491a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001c79f24805bab6c77ae73d7e484769a7034875": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8f9a7246af6650f96401dbbee0c30e5f913cf54": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcaa27102248bc174654009763f4b911b9d2420e7b06c432b0f2434a742a7c067": "0x350b85f8b7d4924c88b90cdac534ff4931512ab3", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ef3444aa6d3090efb1d8970ab8be5dc6bc070000": "0x8405d696b6b0800c3732f87b3e817969896dcaeaeb0af813c27dc797501c245a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a91beae0866ae95a1e006e7d6d2366a0a839f4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517f4f4deef01b26bc699d6a7a9d66b3a4f2010000": "0xc67f0f6ffaffdbc60d7994ab226f632dee4a8249c363b33359daff64200fec2200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700892b067f072e1f337b367c9a8d9ea968d4419d": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ecfb901249099cf545de2da3c3ff6e320fc11765": "0x0044135e7e6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1a286c553f1c240de8df6b45d223c3eaa7bba7c29379cc6c634975a48c17503c": "0x00ae92580ffe442350bfefc4c9e4fd5b137a0fc9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397822fd50f043f331fe44df12af8559527b4be8006": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ed8f71ffd7c2e8d8b37564a4e3b5d6fefa7f66c1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5112a2cf84d3a4eecdaa065acc236bb2f0bf040000": "0xdc313b667a08d4a8293ed90733697961647be1182449338e3ba7215cb786311d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a8147b63c67b2d13f3d19f6607ae3086f088490": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7c80d34e75a864a4b6cf0278fe6fc102e87857659ac76af39864360eeba96a29": "0x7da1f36b13c74e5f988f806da14650b790a54b4c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c231dc7e55ec4b6e33ea3ea6d77d88917d879781": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dee5101da99530e61539f3ffdad3185b717c3177095b2007af99b7dd05823a943": "0x97062eb6c3d95d33c040c98a54187b5a66541b6d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ccacd4afcf104e4ad26bf9f8878f09ff96050a": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895a65b40f6e9bd80597482769f6bf1e09d49a5634": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d527ed0e44c244b57e8c2013fe51f2a692650ad1eb58340921ad245bb32993516": "0xe1b609382d115d355e65a0ea206290fbd6ccde06", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a56f814d9f170a1c285817223b072626b517d099": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e4d35cb41da50f320fb28123684440d99e450d24": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d8a80008fdcb5757be67395cca67178d60080000": "0x824a7af00f98513fc725908955b32f8c745bde6131ee4b71fdae8ea15310121800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de4abcfe30c4b4f7ac36c37366241c6091d766a03d28f070deb646707bbbd0562": "0xa44e6d1cca8226e718ee0b4f4edfa68bd3773705", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890ca15a530dca1d29ca3557b90d80e3a05638fdbc": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51eecc42c84d948535d8fb64070044147509050000": "0x1650c532ed1a8641e8922aa24ade0ff411d03edd9ed1c6b7fe42f1a801cee37c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243b67a2bfea6579b273cfa427637adf9fab925f68a": "0x0010dcdcc56600000000000000000000e84da60000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da5131ad6c8ee8e53a73081a3a56a7706274b851700c5caf5b8202c9d2bdcbf56": "0x25b28e2fbab8ce0b5d54ac6968369d6a9f1e2197", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e386f707569dfdea7210b53bf3e03f6d24ee073": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f09af5717a441341ce58f1b2bc5d9df7c1ad4fe": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928980dc500e1464a32ab0faec15feaec216a734162b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970054e99a8a384386279936d42dcbabb4a710ee74": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397331ca0d8ac0d809e8e6031769d5318589a469e0d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289373ddacb2c816717998cf44bf784e75471d2545c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890f2dbb3e34ed1d44c56caa450a65199ce15165e3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928968616b50e3e0eaed3c1b12fc53162e335e0853c1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb514a98e40a66e5d4f634b9afae1ec41d58c659": "0x0000dc20749701000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514a70278b6f7049e315ae5cc3e8bb464e32040000": "0xec0b26473a8566bcb2220ef71791a54381860591c9293f4d51d49f4015025c5800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ae83c799eeb9d91044cbb2ffd28e79e577e1a9": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705c312d2134e5c632296c124a975e7cb9f79f519": "0x00f022a88c2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a228f05157969366882c78be7c434dc3d66b5b19": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d30599dba50b5f3ba0b36f856a761eb3c0aee61e830d4beb448ef94b6ad92be39": "0xa6d4b980ebb41243978f92316777792ec14fff50", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7a848efd719f7a216be0e7ab86944c5c23bd0bcc66216ae6a0aaffcb2bbf3b7a": "0x90a990f3e8856f6264326b2053a0ecadbfa34720", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ac47d44618795ab6924305321ad07000cf52b350": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d622470e00c50400929243e6e9ed4c62edc88c1a4f7f70e62bca37c277ef3ae74": "0x8d590735c51726c9e24a446143734dd5ed632031", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970044f4a7d8f9da9528d852b1d02ed6e867d32215": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a02c4b206630fe17cf7657ea80f1b6fab809da": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397352fc97f4dfc29a453be0898d59984431a6e0714": "0x0070644a3b1e00000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca308ce9615de0775a82f8a94dc3d285a1": "0x02", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928909ee4979e687c267db3ea238a9ec64fb74140438": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897f88b00db27a500fbfa7ebc9c3caa2dea6f59d5b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513c21f407a369d5ec74c9891620a3a1fb50070000": "0x0ed47a3c5d9fc5612ae7b8f02585298aef42161140370c1c6169061963792f0c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda775cb27a9b7eca3f00c453b23e18c69fd9e4920363f31c201e7d1fddfaa040": "0x78fa87ec68adec6d13477e797f062562cbcdfb4b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af9e08f3020e624c945cc446e8759602049cb176": "0x00d64e0f9b5800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec12141e117791b66693d6ab5ca3e270f531f76c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900daeed67ad54dab091b23a46ee6cc9f7e27d510": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f229ac4cc64385aa20b2cf7f75a9eba129b6711": "0x00903d79475800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9c1f8b4234b1d9b714c018fe96afaa186d841a7": "0x001e39c7e9a600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511ea9f6348baf80f9b278a786db5275feba050000": "0xa24dbcca5040cd15564dc59a2768d42eb475ba636fdc072c1671ff9030d6292c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397531aa49f00416d099c75ab4ffad972cc61f83de1": "0x000ea4d437be00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f9a76fbba12dc70d5c4b71c9638f1c1f0b4c280": "0x00605b1ce52900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890054a7cf7c027ea72ac2b1994d1f6221539593a5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928919527a176a9634ef8b83e25bc0fdd90533e0a966": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928946e4cf75e7a515935482c3f1b557efe92893d483": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c84616c13fc8266181a4589ca35f2f2463b0e4b3": "0x0004b90afcd600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e56be81797e2616b7d4c57c892dbecda35045fa1": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fcd52c547ebcb0b817752c5b62d132b96b797250": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d669dd77d915c5c24e5dc787de28d5f0016e3af9013ce52be7ded1bd0a4d3845d": "0x2da865b913ce50451351a315d8b37cb87a4f4109", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a49c0914f127ebf3bf1364ab5a351479d32700fd8b73bc2d6a94cc38176b539": "0x01e086773e4f00f25c04e6f0b8607274ba27bd94", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d68659f683ec88be378fb7729f1e6ab48731265b4c1f915a17cf25624c1109a29": "0xf76516ce11965b9970b53f7cbcf53cd4d984ebd3", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d460711f6cd4dc36bb338b1548884b1ce28f5d919f9ce479116294dd34784524e": "0xe666339d61a192d437f96ad1e40f197d547187c8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972d849681da9673b51535230397b2aad3e68f7d49": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5140a31c6ea26bd87acb236fcf30e2158e4e060000": "0x7623c898ff1dc910b8ac22ced18595072bec72a22f5ac79f132b29b4cf03330b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b72e3cb05569922440ec3a39875f98af237e42": "0x0090ba05820500000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a538f4357c760881d250e0a1bbd9e35999060000": "0x6ed0606d9db7d50d37072ffc93b580a94c9e11424c96fbd7d9c06dd8f331493800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700aa83bc9abf0e8c4937a8ebde74a7961f050747": "0x007ceafac42900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514e8cb2868d61177ec837649e170e52cb7e070000": "0x7a39d58de9e6f425d04d99b7693ee5f37658db558114b7aec1501018158d257b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b58305431aee894728e5faca9e6cb28c28ac7a": "0x001ab867e39b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894f7765e7ebfafb17ebd8da8a9422d5d1a9a4760f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c78bf3b5da90e93c22b8b41666f8b30472358c1": "0x002e8b3a7c2600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e16ac66b63f96b1d8e9e3b203c613f9f246385e3571bd7730f793f01c668153": "0x4af9fe0d55c749c5fa4eac73c660afe9614c926f", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c7ab705f87c13869b0a150742aeb36f34a010000": "0x68d958e8c1f36ccb18e17e1151bbfa4319cb4fb578b14f0b74b8b28cb2d5f01f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ae83c799eeb9d91044cbb2ffd28e79e577e1a9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8ef70a1d0d8e97d88585fce557a65af431dbf158d2682b5088134e1cbb089b78": "0x6dcbf212a83175dff095fea2d226aca22a93d643", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2251fc8e7977546c82b7bd4bfc3383601436d5ef3cf7a3060859bebc05a9a046": "0x00e28833ecc493aa66477f04c932a4d689598910", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511962edc5cba9d487cbd05e9d8476f561cb010000": "0x565dc10edbba93e52936f84801076ff37f32f90b28491a8dff3204ec08486c0d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007c2833e9857bdcfd571270b500c0c397f0ea80": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007e98442eba3fff13fdb90fefc77b2afb347e5e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d60babb8bab89537c2b2c8d0dfce9ecf940e40": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4b5aefb88bd749426b9a4bbcc09a3e9760493c6": "0x00000e8308e409000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b7d3dfb87fc35055dcb7d292d3bdc430496380": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a440bdbe81c1cb6e7ee0432788c3bbd5a769542": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894a522a059291f53b8ffee8b90b72a1223b6dac46": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cc7693fe047247443cb52fda4173543adb8843": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928986bc373e025f772a169e0c3a1f973f8725979169": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928950e36dd2f9f0b112a8eedf160bdd4aeee06dbed3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928981d6578eaae7398c11d6b3ae4842411ede0d8c14": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d646dbbbc90e5dd14a432f77bfabcb173d4d9d9918473847fa8e63ceba441cf33": "0x009b6f347d957e1374610319d75d49348c54251c", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817deee9d5d071a418b51c02b456d5f5cefd6231041ad59b0e8379c59c11ba4a2439": "0x007598555819639ca06fb8b20e3ecffe1159cb99", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fc6b49f7539a0bdb98f78b3089baeb861b9e71c1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bfb8779a31e7ad4c1e4f852383bb1c6ad7dcd0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a04a8b46187fc60ec1754b78c6489f8918941321": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890096b6577d9a53f506476c8cc6212f947562ca4a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009dcd9ee2679e1a794297acdcdb9b325ed9f2d5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5146733e3e0f5a76228547fb9ac54c780078010000": "0x5247024eb375e8741cd51473702b6f574bf45b8585fce64768177d2659da5f3b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928978d4635ec2588de43585ca514e0ea0201c52f689": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d95d6253809ef7c7649c839667cc1996e24d8f36": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5e17c90f875b62d277af6d0fd9ed6e2258c8627ac561c55ba7e193e6fc18d83f": "0x0d9905f0c546708f12b180ed038e87fa702e0cad", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003ef653b996a653d41d4ed315b3209f44bcce9d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397836856d5d672d99ad3b450542cdacb91c394605d": "0x00583b15017400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b98fadb1f1143a50c58954b92c83800d2f23c1d": "0x0060adfb90c801000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6208d7c4e716bc9605f4eeeb26a73f884f9cc17f2bbfec39364ac917c716f149": "0x8a8043a578111b05d48162eab62fcdd9adce5185", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dfde2d5b4ecbe01f64d4441f0e996171bf070000": "0xc4826569e68b7eee1b5b93406e4951fcd7ab6b40be519a7db5c6732f66da114900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b9f9d6b531546e4c80058bee5749d72ffc76b54f": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2894a4e556566eaf46b3e383c7d1b63b16d0bf1400bb2c763dbce51947b14f5e": "0x00497c0ea743f6a572459c14dff09468021c84de", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a951a1bcbbd1bee2cc35cfd96dcf9d101e630c40": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900df109c62f7e61eb2531f8751a9202beb4f5436": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009907458a775081e900351ba720465e4f64f812": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d0e96f05d6d91d1b10ada40e532f72ecaa060000": "0xaa65fa461471c7ad4b09bc9b74844df0faf71d0198782b0f26f704b185ac363400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ef398a72ca7e9c352d14aa297c5c59f604c43bdc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900799a6372295097cd51c0769caa6c8866bcf7bf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928994b05d7a1cfc33b148caedb2b979d603a6532bcd": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2eef2aee654d4975535f2701af86ba6d169c2c9a1599b16635a2a5e4640db94d": "0x9bbb49b1ffed08d3f79a352f1a0f149d88722fd2", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da91ab2f4124a8fd2c5a3af5d64fd1120ebe240d12c7ad07bb0e7785ee6837095ddeebb7aef84d6ed7ea87da197805b343a": "0x000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781df87a117417b554a2ade4f7a425fcc4b2d919a": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6cffc26fb979a2a3d44cb74b6295d31974e4ede": "0x00d4cb74a2ed00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515c17327d78928d9d302a6614be5b5aa236040000": "0xf8750a008794352b2a7533510bfd2fdc2f2ebb55e343d2dfc4c1bebdd0b8987800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d35300fe32b48fc3eb97d1033cbefe8aac2d2d9": "0x0020f84dde7004000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894ff636bfe534a97fa8adc9366aee821059b032d2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ccfe74df2e586d29d3fef37a234148f3a1b99262": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51965ddca4df450ce493b696822aa710d6aa070000": "0x12b1988e003ba72cf070e76e70db32569a8a90e4676deb1013b4f5872dbaa23900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b8a4884a5afc6cbf0dacd720fd6468b41b6d437": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de03136d76b36804ad53f74d2bc7a0f9f50ebd9619a5746c20da5780fb739c33c": "0x4b8b042fbc1bee7f5b9bde50c0706ddf3422c890", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f786d0aca37d4965c2929cacee16ad42d7cf9bab": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518de8bd83a7ce80bb5ac408edd85d2f96e4050000": "0x4a80a6b62d1147e7520adfcb464d6006483c2506e258d1bb4e8bcb057e637b3b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339735d4fbfef171c1f89be9fa8b14a6b4bcf8ff89df": "0x008c49524d4e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397656dc09b4dc821695c9de996b762b3362e00a205": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513ab56ba0302e15df90677d55d3a832b0c1060000": "0xce5b1c0387a6aee95bc73e296421663cebd676af55c12566479cc81dc83a530900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df81dc558baecf13373d4324fa3a8050cb7b63e7": "0x007ebb5c423f0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcdb795c73962290ed72e9e9e250f39f331fa6e0": "0x00440062123503000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001ac6d62145c0db63bac474a8bf1ac31ade59b9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009525c96a2340c3cd1e0d4d11199f781fee5e10": "0x00b83cd3241d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cc7693fe047247443cb52fda4173543adb8843": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d137e2c529088676c797702ce425fa0e4ca92a4e27dac6a2e6351bd151cf94417": "0x6cb08b8792e23b72a3af06933a30997d51ad1565", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b9b7ef4b7a727dae1735e3ce35827316135f3210": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19501c78c2a8f3328fc86261626580d2419bc8835493ac89eb09d5985281f5dff4bc6c7a7ea988fd23af05f301580a": "0xdc9974cdb3cebfac4d31333c30865ff66c35c1bf898df5c5dd2924d3280e7201", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289731396ed98bbc215c9078bbc583034ac85a4995d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b91d0e4a1e311d6f95820a1d7c237f0648060000": "0xcae048bf18031f7f4781b51b36bdbdf12b0259c07316c67ca4e0859d4ecec35300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd9b1a9d7e2c239ccd8fd3f739bf2d3bdb3d6a1d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892b91c155fd65aa757542460218f00df1e9a1d822": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a99757c8c2bdacdb8c1470ed761d375f962184bf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289257634912236e07f8bec7c6c015c88667d04b272": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da4cd4dd151f0106d8157bdf02bfac75f9abe8e635ecc6498b8a8f6acc1f5e674": "0x08ec4aa26d04dba7ecbbf121d50373ba1037e763", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397540f856a7ebd537891067c98e61d70d235257e5d": "0x00963016623e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e35219d98bf6f9c693bf04197070d79d9ba73bfc": "0x006859e438cf0b000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897038e2b36b1117c7c9ac36c511c1965bc14b2062": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900887eb8f21035046af3c7f298fce3bf38785d7e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700efcd61a32da40d230aac22bc0ebd026d8a9fcd": "0x0074f9f66c5600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a145addb0a24f0c4697189a02eadb006be244d49": "0x001242a3973e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c5229fd8a631cf877622f2e37af6eabf15cd99": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bb5d0f2f6b345f9c6afc5bcb3dab5ac11385e512": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f09f297c045899f5cc00131329ee10e522de08": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900958aa22920b759f069b570b275e2f9034ad0b9": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516fa11d0011a329b296349a5fe0f1b35636020000": "0x24bdf1036d7330a4523dd74314816746d3969569fa9604a4d3f8a3de9ce24f2800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970023d732d511a5d2cb335d824655f29daa85be26": "0x006a5d2393db00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e1404e9af1c94c9eaf8fa92e2c2e1a936ed8701": "0x001a3995772200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892107691d8a935f6f5ff47171ed954e332c4248aa": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dba61cf8a989911a9a3f51ddeffdfb15e959fdf99b1dc76a3ad576243dc2f4d7e": "0x008b0c207b6efeccb38af8b6849ffa6b9be0eb61", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51666cdb2320d200e9324ad39c268245363e080000": "0xa5131ad6c8ee8e53a73081a3a56a7706274b851700c5caf5b8202c9d2bdcbf5600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d01d14e379d23d6a9b47e8886761d8e9d7e56f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d845731661473decb5f5f8a168516450f53efb325ce899c6d356aa13b71356662": "0x00afdf133993cc0d4101f56f4b12a0504024bfd6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a74d379117fae37e0f17f3ad6634baa201af20ee": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289799217756e33b324e3af7439e0645c0d65b614a5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ad1626660dc56812b6798a4960b02662e2e7b70b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f352be93aa9f68a7c666a3bb280ab2e6a69c5d4": "0x00009108c73695000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973eea99becd232fdc16b87fd8ee370a4d0ff68165": "0x0022b2219f2e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9a7d372d156a9cf5315d828bdb0ee0b983253242f676e5760b1eb32b6fbc567c": "0x1af41a96bbaf348c3ca582b65193ab4d9108a22b", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daced6ba10b1cdbb0cb10cf662c37e312414c26f632fb5e89e1ac410238a44068": "0x268b05ee0e0e033bf074554452e701a250ed3375", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890dc2547858e1caf83aaf4d61db51d3696b2a593a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a38edc99fbc7935f47a5047a757bd870a7f02640": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928904c6f1d15b8b0d5058db45fc13d6193fa78848be": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894a5b1ecb17b9ced712df12474c5588c8433ccb44": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008b789d4787d4b2688f82f0cdf9f95ac4865d0c": "0x006859ef3b6102000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516f13b88ee31ab680cf81eff28518f9c61f060000": "0xfec441cf991e77767c7acf554e9d61efb63454b4d57153c4ebe95e15d7c3a32900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d46975f837e5abf94b061174335507d461e5b4774944e42bb1f41003eb590cf5a": "0x002cbe540f860818a183be6052ffbb1de22dfbec", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f4bbd56287c3b642dde6ed8f03d2f85ab803c0": "0x00da868e32f600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d528797c0df02524a8804adb5101bd30ca763253ad70423368b4cac159975766c": "0xffcc480bf0e6acdbfdf71c7b8ae796647378c155", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8a1ec46479fec3c43eea382d637de8f295ccb2c0b6f6fdd4c5d34a687737a601": "0xe77bca46a70638e60c9f81bc09d2daad7ebfb379", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6d9fcefe1a8f0fdc1c52c8f7a33d299be4b4e67": "0x00203d88792d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000ea5d2483ef8ee35807c829bdb6addc0f8b76c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900606ba24a1649ee35a5c37671941444ab6d2b8a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51898b161dd038cbb146f4aa1cfa97dab35f070000": "0xc07a393135ceff70346ef1d14953f5f348acbacfaee49076c903c17883f75d7e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d6d9fcefe1a8f0fdc1c52c8f7a33d299be4b4e67": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243b4c4dc1fb222bae0e04fd8cd23f78b37bb39c17d": "0x00008d49fd1a0700000000000000000073707f0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928915245f6c73bdddef958c94650431c4c2330d4faa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890d4b6a8249f1ae3f967892d0187e7d783a49d926": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ec93f2b709623605acf6120849e088dbe0fc37a": "0x007eddf9a20200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892b98fadb1f1143a50c58954b92c83800d2f23c1d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928987b72db3c9257c0647034b53686116d2ffa0f384": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c49830add09b7b13758537fa4e8db73fa5fd4bb4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519781ddb16f6436b80dd5e509b4ae8da5a8060000": "0xae0686ea4fda9aeff2ed8ae87b70eab0453af7bd4f938128ae447cfb54f6155500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aca3500b68da8eb37f45381fa3a0c7f815e8f5a7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d42059f4bba9e1ec1aff76fc2c0afffbb0abe68c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a1329847393a87ad4c25bb21ff093e1d4d050b3": "0x00d098d4af7100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928951a8e0efe83ffa0ecb7f175fc41e38563886939e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512f288a5688016f2b198cb8b105ddbe6e17070000": "0xe25518f95848feb16fd5dabaadafb39cbd03c0d440b47eee1042a5ab37301d4e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d525c90c5a8fac52e9992258bc4bf9b8de7f812b172afef45147ddc56ef23731f": "0x828912ebbc7be3ceb23de58fcf221f171b31c88d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d30ef809e87bb997989679572d1416d0d311276": "0x00206885de1800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289addb5210dce9127918db041caee93be7b50ce633": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e4599a9f87ed76820e4a662b0208d137af070000": "0x9653bcf18e30531092fdc1c52afe06cf61f56fb1fa5d719078cd6914d395ed0f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fc5ab3cd8bb41cd6c4b6319d75c8b84d40050000": "0x68489fc73900b3e283faa5b0c7b7fe49815a54499653ed3ffead8d683f52002c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ecc05d761209a12fbab5791b193ef3855ac7abd0": "0x00e09b147e5500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928935f7b776fee00f961f7cd1168d48e9be61cc17ca": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d10d1cfebf94c6eedbf01ab8895c59f50e660d46717bb226b23ea14124f2edb56": "0xab255abe36663fccdba892c4ca3bd160bf845f35", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a901cba20c6616581ae8df057838198b5b41f3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339714ba180622dcd7ff90ca091fae20ffc0dc847100": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824317e7adf544b8c6ab81cfd449f4154d14a61b2b29": "0x00706f96a686020000000000000000008564160400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243163e5addf68d6e21695adfe1f8fbb33c78d9cd4a": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db428e7a5a1127119f7af84d611066db63cc1c4d1e4baf1ed201247629cbd2d7d": "0x974f15f02a0b9715495ef4b620abe5f8debbf0c9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008350bdba3dcc3c01474bde4a9a6bfc4144baa4": "0x00e4c3b8db4500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928928a6ba2203b78b7e0de3dfcaf687c400bdf1548d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898bf1c1e68d1bee9a5d188c2b49939acfd804fc4d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ffb99b6c2fcbeaada365a38b333eaefef3ad99eb": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513432f87443e661a6e7fd4950184b9f6a91080000": "0x785378390bb8bcde9f1b6a663a8cc3258a92ed222602e3be7ed626051d6a8c5f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928909960be416c44f27b6eab88cfa5bca92634935d5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009907458a775081e900351ba720465e4f64f812": "0x008c2a02902a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970036ec309c318597ab5e273d535c6cf2b4ecb98e": "0x00f077f8402700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002c39a54adc4033eb6cd69c7f67459c0bf90ad9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928978f5234552ba1bac0a945d5e5bdfb56d84d4931a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d54730499c6c53dd16d1e3f8007b64be019cc9229db22d36a12e44eff1670cf5f": "0x7d5b0da867de47e3400367d80d606d08f064e5e8", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d14468f3eec001c098b4584022004007011be560c11664b6025cb7c4aa39e640a": "0x18ad26cf42a6d886352e9337ba7d2e1fa7302c8f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009e2144ec83c3caf492d6ad92cf33cb2cf3aa7c": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ad661fe9878af3b77754710f50981c82549bda8": "0x00009573c24800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976abcac223e44ced17304fe30be5d35661ed1d142": "0x0096f674118300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e0ee8a2c14d8c467a9b31129caeae40b021659f": "0x006c2932302b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890006bdc62b8bc4ffb50a0e99803b147843117239": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512ba8de048096f281123e14069af9ee6c29020000": "0x064beb03134e27c7ea7635c6dbaa993b3b54819217b3b50838fd21cecfedf72500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928907ef90799d9df56a442e958d6bcbb274f2f9bd55": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898ec079be8fccf89a39f8a2ffe35bc08f3047876d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c4ea7d30d01e1d8438dbbea89d44d235a46aca": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397081dadcdd7cc5d6f406061007a6b4af00444e75e": "0x0010a5d4e80000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fd6e3905128b79f64f6bd3cb727134c81f070000": "0x52bab50114e81b832ea60de94e7bfb05dc831a309ddb04cbb1be5eaed217151a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d0d62f0e012fd9cde4c2b255305228fd4a3160de": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f4c17652254bc6e13310168a21c5749982cb6d64": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d208bf08c0dfef7a942588f65ce004eba9932fae7c25fb33720debf8d1e273502": "0x0d666d51a8d222c2065f611e6aa7d4c8ff4a4bbd", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891df8d1ba25da8a9d6804aed11a7650f89fe91996": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511b0b889e2c356ae90da4692519b9d6e1f4020000": "0x3ac0cc6ebb5ab258f626ddd6ad1c1833140996e9703c6c4a5688f45b421ad71000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a0957c6c74540218f392c01174ac3e6c911b57": "0x00a277755ec600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd62a2b80ebcda1b2f14d2a903088759ce56482401fb4130cde32775d6d210a6a": "0x11e328bd7023e933426940ad12d6e1b5bbd55f1e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f9d96b3520fc91f21d75d65ed8531cfda0628a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51386a2a88bfa6cd974a663307c1044aad39040000": "0xfe7f59743f2e3b19178dd8d7eebdd926f541752e408ea28d769f5897239b255b00000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcaac0a2cbf8e355f5ea6cb2de8727bfb0c": "0x54000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928922b2d90d35c20a47c6f579fb6603778e7010940b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928925e710cb23477bcc48cb54d6a329d35cb6a79d67": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d34e9fe863c26cfcecf82bf4cc18701b3ad4767f": "0x0008e8e1298b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003be22889aedf2d4ddab4756263f82d6aa52ed2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896ea6d745b4dad0ef65899ca31e2989b3dc49124f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e79ea613690def3083ecc0d55b223e7711369c72": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d3077ba23533692a3434fa28f7cd678fc3f2783a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a8853db1bf892ef57532516bf9d3b2b422060000": "0x9ccea8905de715b2b260070927dfff763ee6d0ffbeb7afda26ddfb2f614fd20000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004e1d33f9cddab664a732b7eebe2a80d04ae413": "0x00f43e5be3af01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ae5328446d335ff5aefe66bbc5be2d827915a3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c268681587b32ae57f9d9d774853d02c43070000": "0xfa32ba6d93b464f5c8b53ef103ea2d296ba373ab17b21dc04f2ee78c7389d23a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fe7c8c647c3574eb9931d1d3f36019b6a6d06e2f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f94e18a08e26f52c30f0bbabe599c449ae060000": "0xea1b65102cd4e98ef88d31c7d627ab4d4f26a92d4c68bc516ab7ee84cf326e6c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51946722619b0d780ebe8a673deb82a76127050000": "0xec908d5b90a9d0a6e7255ac455cfd353abea89d31ecd28166efd9c033e6b6f1400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a81108e5483a351280f7ff2d3fa429adee050000": "0x8c17e962f910139d0710b3037a7fd7929e6da7912de43fcf8c5dde90c94bbf6c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008ad80219aac538f2374ae749d1ac797da21bf7": "0x008826bcfcd800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783d8e1a3d7f05fdc4f4a1a99d5a89bcc62324a04": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000bc706ebecb19e4c334a8e8e9becef6e58a2f0": "0x002a0967c50e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ad1d079078b3775e1779bf8bdf34a72d89455cd0cfc224a73c7844ad80e190c": "0x8067113652df86032aa683acd46c0b2abd8c4a36", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f9623e0605ed7294195c72779b378b442834633": "0x00a0724e180900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c8871bfc5d87a0cc0ecdeac961efbce730090000": "0xd62a2b80ebcda1b2f14d2a903088759ce56482401fb4130cde32775d6d210a6a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970045fa890802d3a2b2a1c7fb78859017786a9fad": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dec0f3c02a519e687645f6d29219695eb2461e01ad6813ab7a9144aa85e4ddb56": "0x3955e672f3306fd39545edb3d7040cf8de2f9180", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d63e4031c07cf74da563595cf55df4b52063a7ac": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974dce6b147ce7c96b3722bcf6ea4f86c98f0c3419": "0x00ae658c792700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890068c220ede25b44a185ba20fa5f540928adf5e4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890082f93778fdd8d0264b2718574c75566651201e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fe149294b9421c2b54501d84b1cbd4c2a1050000": "0x9ee9f66b501f25d1a28c7de9aa2e2717dfdddd281cb0971f5e42a8657c05aa5300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ea61ed6dafeca43601645e1cc6842daa7ec0c54795269e30df0c03f819ee265": "0x6c9f5c47814f33659ef2d1996a0961e80b8597bf", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d28f1facbab196ec6986b7b5160b9345188d2ac9ba60a5375415a7c80be2b8d12": "0xcf7c0865a0dcaaf8bf3c5641e82eb37c690d5024", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004d70b92f0b70b284fc33d396e293ab6d72c04b": "0x0016ccb8010900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700887eb8f21035046af3c7f298fce3bf38785d7e": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ab7d6f01cebfd4f9fa58e85fca6ba6a50e4a2a6": "0x001afff3266700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa3b62303f219bd6622c9039ce7df26e89cbe72b": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890020540fa863f29743c6ec48150a3bce97706f18": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928910fa75506994a9d1a03fb01abb31135d662a7086": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970025641d2b744f643432cfef4c08b76430fda5e0": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ddf8f475ee3b847117ed3df673e85c8b4593bbf3": "0x00a65f83e67f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9459cc85e78e0336adb349eabf257dbaf9d5a2b": "0x000467eeed0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397228679ce88ce13bb8483bbefc4d107a1aed02d2b": "0x00dedce2d93f02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a378bab57ff303be5842361b3c0b5ff44e222a76": "0x00dc0b7d560300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892c1aef275a28f2ee7241ac81ba4f25bcf09bccde": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243f3b4bfb9fa5372a43bab26800f6cb125c922c452": "0x00e04d4e6d5b010000000000000000006832320200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243e688284626ca2d00b578865c0e7d189c6ca978b0": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a36821b843a170995a145f3503400866bd69fe4": "0x00001c0611c813000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243f385662f28eb02ccd3da6d3a370777cf73e68306": "0x00008d49fd1a0700000000000000000073707f0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397888a870b0e77521b1121874499e934714af32f8b": "0x00a0ed86271400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397adffeef501353d90db6612ed584b1438daf02c4d": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289522aef9c286463840def1e9d7b43f15de76b1b4b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897c89a2437b7cc02b0bdac206ac317a8a1e7826db": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4263bb05caff304086fb08790ff345aac33cbef0eeb795be86fe796e9e5dd917": "0x1c6b8bda3f7adaf20a55a970706d195a3ef9a1cc", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928980a8bca8a6bfe60479f523c10c459ff6384760c2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f220d58015031403687716a43c54f64dc99713b6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d149528821a9e955805a4e10b49ef3ab68b0adcf7388bd60202f441b121d92b36": "0x9fd1eba5f41419b2887a1e36e4dc22598254864e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d94a5e3cb03e089fd5d39f713036cdea09665ccac86ae2271fe1b18cb40a04f36": "0xf4c17652254bc6e13310168a21c5749982cb6d64", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f360b24a530d29c96a26c2e34c0dabcab12639f4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f361416db134b72a3e84dece57cbe6179e40f283": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890063a5947b2cb42b51fe5e6fa0b75e6105b3a0f2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900aa0554b5802d43ab255cd089a6a7fee211a41a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d12c60124aaaccb363fa69e6cc5cbc5a14a023292bda1b4bd5627ecd63a571601": "0xb9c635d29a8bd145547759a0e823aa306c607a4e", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5139bdaa25c2f88d09205eb4d0daaa910725010000": "0x24462de23cf247bc7779c3ad0d1aa31f3e45d434f5fd362e3a1485c53374820500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1afc89af3de835961ef0c698e6dfb77ab5de39e040d90944febdc47941600f48": "0x2de237a350c65bf399bf853a3cc6bffd23b21917", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512e99e08f6e5fb9d43e5fa9fd8c9d38680d080000": "0x1050436acc3c741a67ef38f329a01baaf317c24ef837ab6245e3c1531719692f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c64f09d3a447e74cd8e8e769983c25c95d697714": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de49eb00a5f8632db3e45b24a7824605c7c7cdf4abcd9b17fe39ab29da4b77339": "0xbdb3924fc91e02130cde47545865b618eeb5e1d4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000e5a0a7326596d024936e96ec7b662e5de59e7": "0x00f4e9112c1501000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b9be8a12f0bb04e290a6727e57dd34757b776d6": "0x00a0d885573416000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893be088b61fe7972ccefd39298656ef9b147e06b9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970001343f03e9ad77fa47f674c4ff59d5fa11fcb3": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006dd904124038280e01c52b465f2d802b3c1783": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972684445d42e93876de6d41ed685081b9ae9bdd31": "0x000e0675acf100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397162ea064ea50973af277b0c8b32e9f900e2fc635": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dcca132d5786a46bd92175cfb22cfaf39e020000": "0x2259051e6c53d3a07e28073904ccbebb981a4afa2df4ecc48f2b2a6a8965077800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702fa77f03cddf7f1ab675723e15e88505da9a025": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007589e0ef0ead23d975d47e48eda004c90b14a6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895976fd31391dd442d59af9ed43d37a5394379956": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d531b67faf691723fda5e741359efa9bdb52bde5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289df423fe29ac1331bfcdc8e01f2934a971e4dfb72": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51af0e96fa5aa6c46d035a4b2e3bbc036027010000": "0xf4f3e8a5bf3a21759f79fdf15f03b1bb099b3ea8284a845d5eac8b476e61880400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1e713a22e920a812dc7179926fd698289ad66bbba84c982851ddcaaeb26e0758": "0x0003ec6a173a7f45631ca5d96bb5b0a3ecccb5da", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f2f1561451395ed8091ac2e016f0953087040000": "0x3004ccce7f54f6043f13a030b1f07231d81826e99ffd3508fddfdbd0e5a9585400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dc0fbb0d3eb93773ccc744fe13c0beb2820a9e": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339749a1c510c50555b7be6e68e064067038e5499748": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af804c858e8bca9e04340cc5c9984f5f2acfb409": "0x00645dd8e71400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51faa2e76d984fad5ad56eb78def8615bb0d070000": "0x981e0c8001f0d80ef450c0c0561f9e4b22337af479023b9d79851381ffbe034800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cb2b6f2f316f419c8bbaf441ea94e47a2193f7e2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c3f69ca5a5806321b36b68e6a25aaee0b58b259": "0x0040f79c2d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975e5766ead1ece2e47e415f74fcd2d2aebf46e87a": "0x0094487fe37900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339704867292a47c5837759dfe13bc70bd30aa01050d": "0x003036d4980900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5153708fb45e4217f45616285f424cc2b10a070000": "0x264319ed6a0895c04112917fc9bdc0771f4a4773aae014a99d25bbe06fa1057a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb2be121b15ca94f6156f20b8b45410676546ee9": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0bf059f5658c248e0ac04ee4f1dc07bfd739ef0": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900349f41813fd23d0e1c6fe6160d5d44f9931624": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928943a6edd95e865b50426330da71638b56f2a75c21": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51509574d1f64b78922db4f776b391fc15b1050000": "0x3a32583d65fb0c890d13834bd3f1477b91ad86446828a80c3ba30f6241725a1000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c870ce8eef81fe072556ca579fbf77b06f060000": "0x3882ccb174b01d544a410c104c75d018db85d9a749e9cc59249cfcf3d4f4d53000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519a05ff2cd8358b7f546aec3be1a0952dc1020000": "0xdac5dd2abf4db76ff860108062bb8bfe188f80d69546d19c1993f23926ae363800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397198a1bad80c2eac0fb986553955cfb5e30f464c7": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928960f7905da2eef27ee2992082769b0c1c236c7395": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397239133b0a6973e8b1c2b7657dfe9abf78501a894": "0x00b2f5886e9700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899e070de69e6cce7c2347b1b8e8bae4b68b04a8c6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fffa82724ad200edcdc04731ad4320549b080000": "0x48a9fe7dddf4711de4871c4a9f5c52135b49bdb7fe99d393b60868428e06370300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005056c4cc0929d2eafdfa995455e68427137dec": "0x00da5001030800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898588ebee2efaafca8642783fe8bede2d9857fd68": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a2a6f1eaaeced797b514b9da30309ccdf857d70": "0x0062c655919a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7d53f3b0307de42d7dc018f672f7e6af34a8194": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dd04defd841f7efce21f5c63f123baacc61b796c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df586c86efdcf8add8219c7c987a16d25e39b6ec": "0x00ca91bb010500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004e8ca36ea8d56e723c642cafab49c34f261abd": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339706118f0b0b10db4ea349c972900c67fc44d54516": "0x006e6c5ebe4d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d88f66ef5a1b50f36b1ebc997c91cb47affe0d1de4d5d9be9bfe009c0783e912d": "0xbcf0c42b60a210ce7d16928b5cfc4421d23ada25", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004ad027efd31c17dc857f5e3bcddc672da6bd7c": "0x00c453c2e12000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397553581f31faeec2ffb2119e7ae41a257f5ae0c44": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899dedc7bf7fbcfc0d48964cd9977337b944e177e1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f04a8b3701556ebe9ff89b64058f0875ba4366e3": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dece2eb75309f0b344a924dd7a35febfe235f71bbb3ec4cf986a440342256ce4f": "0x77fa549b3eaa7e18718235b376be4eb130fa54ec", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b9a26d09671340f879132d0db15c3be7da030000": "0x847ca879aa4ee4e774297222315e844f84e6b15f035b54a658be03a7166e980200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cd9efe87867960ad16f32ed71491d76efa060000": "0xcc3a8b98f63e0c86737c439a3fb82a5769fc333b42e8abb683f7bc52dc31374200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a003fc1e731965c0e08ccc93868cddae6895d8e0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cb2404dfb98a34ba65def56b35315fe65a050000": "0x60710d0e326430a244694534e75250dff666d2a8643daa19aefddc39aa5ade0500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d48610dd34137fc88e4826aa1a964b4a8f532453005ecfd4ec2fe9fa14e882117": "0x1c5142225c7e26732a7ea83d3b25c826d8637556", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009655d2ce1236c20262b402d2fc89892962d45b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e8014d80afe8da0e24e90539b864794c6981a0a": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d508a1452fc1ae7b10b6e858d75e669536fea16": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6e30851f4b86598f344b29224ebc8a52503adf8cdc32af154ab6ed837fa9091d": "0x076f1329e5a326f9b1a7a83b99281e1fa0895585", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc13a9ed082cc1556a92d05a143fcd2346ebe62c": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0016292937846b8e0f933c667229d8b6765917b86dd19e0f6c32bdb4ab1a2e34": "0xe737ea62ef4a2b771e3e82be3b8e0898181a8b62", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4932280b37de5fcec32232fb378cbb24275e8f8": "0x003036d4980900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51406336dd7e68e1d0b1bdd15c1fea9b67f1000000": "0xc8e26d12f564d9430977d9d4528b6d81a7e965354fcdee3dbedbdb3366c6504600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8a185b4c3f9684a0c7db5a9f49a54d9227ebe5e": "0x005afceaa60800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6a51e7f4c64e59e468d49709561ab3d04062aebd5c0f297a491a8002f2a72250": "0xb043ebcca29d4a6c8ba1dfdb75fedad3dac2a5f6", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db227d24a97cba787bde41e45897f6cf34822e210d475862df1a62710a661e13e": "0x269f2df75c2f22db96592cad6ad5ce58bb85472b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed4629967a1994b2f28b66ca0ad7d5f7bb583ee4": "0x0032cf29595c01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510d126eb6590ffee5e04197ebf508cfb295060000": "0x5820b363e423d6569657bec1820a35823af2aa019c17507f2204ed9f5c10714700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b10714a62fa5f24666e50af93d70ffd033040000": "0xecde39c637280f59fd38dfb06099f3d6bb049e91b2ca221ea93dd7461a420a5200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900710a76cb9637a974616f5f9295470eb4abcce9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289051ae28151a68cceea5e234694b82c913a802fb9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928939b51396ef3c70571ce86532feab5598a766e8be": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e95a0b7851db5423d0aadc91bf963eab02c6d440": "0x0092ba17bedc00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b16547a72b4d9f37fe34fd67259d07f65953d141": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e7aaa4af7293898e3d1d70fe20cbd525c495818": "0x0040b10baf682c000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289414f19cf5dbf026f6e069532c8c220b82239c652": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b3c2a4ce7ce57a74371b7e3dae8f3393229c2aac": "0x000e688dc7bd21000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bf140794f7009345dc3de37523f63ecca1b155f": "0x00feb8bf501000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282430129b205bd7da590c22b986f2fcfcb3079ee3d69": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b065022613dc0585e7b5536173fbe028eb6c00": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cbd1b6c83908c27f324e5cfbb6f62d27ef9e27c4": "0x00e081d2cdac00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824339dc8b68208f3cf7de41f8129623dea433dade6d": "0x00001a93fa350e000000000000000000e5e0fe1600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289de5eea1691af15296ab6474d161ea8a4ab5f86f6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bce70d037bdb23d24b729510a4d9afa46d060000": "0xa46bfe557b5ccc967536df92b1f24bc6031bbfe646f2658f5b3ebac73cbd036f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d221cfba0cf7d028ceea3c4e5f8cfbc76f2a46d": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513956c52153dd4012be7607ab20634b52a0080000": "0xec3b9a4f7823e1300b670dc007d3408763760cb7c320453d33619773b01c412a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d126647690e4dc7b7b7a0705802d62342f6f759578ffd888ff6a60cd1708b3a4a": "0x007edbaf17817a91eb48f6166a592d16cc47846e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2a38cf1b92fd5b83c387d7d0f6a05ea2fe915cf9f0e2557b3c7fbcad6cdcb83e": "0x461df0f49a1b5b38318c1cd425840986e15176f2", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d908aab5055588f2742840a5c03d5df671c1a20427efa284748daa3990e21ab0f": "0x3c3e4e713e333bbc44b36f89912b5d8dfecb725f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4895ea497de505d9c6e2adcc2e036d1d567d088": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e9faddbdf9c03466a607fc06415ac3f129aa2dc4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d368d7df47ff9f015a247ddea7b37abb1d56387b632adf8393bb73f606540fd1f": "0xf619a00f641e82037048c9d0cd20f9b64c664fc0", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f61b041f3e62a7770f67009cd5b7af4676040000": "0x9c396028b751adc267744c732e5838ef86a0e83bbc957103d31206df3e24f13100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700294eb6c545e738597385f7cc36298ba90db70b": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f897a81a6ab5aa5cc24e18c9976b3882cd0f4ccf": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d783eb106ba819ff2125db858ac9bc9a5f0cc3f825f6a8050d586db169555ee16": "0x003d69a4460b62a962d7dc8f5cf77db217998d25", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bb9520248a32078fca7bcdc6459dda51afa86fe3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa5b8e7942818890da1ab0b8ea9f79c6e912a758": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d98106d7b4993f855c6b5f7b9a62102a587a3da69a9616d0d110b5250a65fca6b": "0x23c93d5b4d09093d82ec6b4e62505071c3ef00f9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d95e4b573c9825824a9274497e5777bc500b68": "0x00a498397d3900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fdab49634888d5432dd9f4718887fdc69d27f39a": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900aa961aeab33a6e82ee5a8f3a0c42c4f87f7068": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397391a6bb5f2fca9a19d16f09aa298e9e23288a5f8": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397849c50c6f7bbd0663381241fe5a7c65b3d74227b": "0x003278ff3d1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892586319850defd14dbfa93fe588780fdea0d4336": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a0cc283d935edb5c0df5e29b111534c101fa0280": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51147ff462cb2c243e40baea79116a06dc28040000": "0xced8b2fdf65900940781d3c01ddc03e4adbb8ef6941df7b6e4bf370b10f6094400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e48fa43331d29570366a4244398aeb56756467cb": "0x007a6af93f1400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51404ccfb641e5b17f9598d4801019c6c4cb050000": "0x70a7e3caa9a1670cb78998b9a9e3a81b834c24d5cd86efedccfd854b45ac7d6700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6ed0606d9db7d50d37072ffc93b580a94c9e11424c96fbd7d9c06dd8f3314938": "0x1a1f84545ff677fdb54d955f707055dc70f05452", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c4cfb90d630bdaab104b05386b6f7aa3574263": "0x00b2a1b3670900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e7321957993cae05c6d5e4282e83d1b09b57caa9": "0x00e40b54020000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5139edabef548fc1fcdd5761fffe4573ee06070000": "0xae723b4cb2d54c6806751d253f1e457daeac267c88eae738864e5c8f1ab3080100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd8ba33ba9e1d1c1250cea9a8aa6aeb93df2df2bab98d7c330a2834cbf707ac7e": "0x9af1322b1526ea42be721916e6ba232b4f001fd6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900049f62287af249ec7e0afef09cd6d6d708bf6f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7e96c1b891441afa759d3b9f5576f58ddff074f49f65059f410a4b4b9bad8837": "0x00c99a3b6afc1215dc0b1196ebd9edbf8b045b76", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720c1bf2cb99a7026fea57c28dcc9e85c4ac89c94": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1a2f001ed283dc87324378e0fb2c820997b8ad16632be93cc19869440f5f5d47": "0x00864b879b69a70b8798a0f61de21ee5b5bab3f4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894cf7037aeb2962a18b2e08aa140f07cb53e1a957": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289992094bb15f3c52186de0e92dc4912318446be04": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b494019d773226920acbb62e0d9a1dee4b080000": "0xa033ebb41c70f7fe3525f62f6678ea6b8b986e2808c4e221b51c3cf42beb3df800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ec4e012df5a2a6ad90def9941c754c27d7eb0d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289599266e9b5c0983b9f68f13f1834fdac9c2f0ff6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970dc2547858e1caf83aaf4d61db51d3696b2a593a": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aeb9aaee118a585de364026e8b449f37ff9ffe54": "0x00900126fb4700000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7aaf0d5e96dbe960bf0a63df1183a14398d655a1bdbeda95758696f73fe57738": "0x00b7d3dfb87fc35055dcb7d292d3bdc430496380", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003ec3f13edfbe650fc1a703298e66caeba93476": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4e2c830f308677db112a4a79bc17a39c91352b6d3ea0e476ed59dff980a01677": "0x08c204dc28bcd0c991b903bfed4eb5309d1053ee", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898f00eb46d1af27a6022117722fb36628a4fd16cc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b07cf336066916f70b0b5c90468feb73790e1e": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f06b9faa0d5b71935682f53b6ec711158a8e9b": "0x00042c3eba5e00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517df2d61306f1c493f624b44b2367244c4f070000": "0xf2febc980f27d3470e1ccad9a8106c009c08b08cbd1cdebb70786669f76c834000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b5a5a1382d1d88caaec3262a614216da798e5f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ac2094b05a915b14b9b27ba6a7d92da35d0000279947e64b42e9da82752f97e": "0x001ff7e32cfd40f06e0d9f60f60eac6bef113f41", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc63b6d81d7d307b9f4464304330a840f5159c78a804dd344c5fcbfb3da9aad11": "0x008ce1ef049738e34a1f1e03764ec209b329a558", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc686d330dff564af88ccd1d23e92b22b69e3b8ca825fd429bc3b8ce96758394c": "0xb4b2611b6a9433aa098aa0a026a1d99037710f66", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7469d0b58b2bbc82cab494984169f7f189108866270e92a449a07aa3ca967476": "0x4b58917b2b71399c841b985727a3ff7fb59547f1", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51867507d529d48d32f894c43c59f3ae7bbe060000": "0x72322cff7ccfe90301cecc6957a68c3024c93c6b498f2b3cafa29cb75b85d00c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000d21538f4fbbe5aee7b158591e7cfc2456b0c2": "0x00080442a01100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e06a8d603b1151b6e88a82a4ce53e6e8b985b5": "0x009ac019541900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765e01fd6abad727e8726046f5b55b25ff6bddf92": "0x00c0f2ee60ee04000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bf51d287fc91f694da8c8ed0005b1251397eba": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892c431b755d5b1ccd238d5b8470b35afa2591474e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a8b8e5173aa4696b5ffb4fb411811d3198ce837b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339712980b8c3399747ec2dea6d7586d30c43b9326f7": "0x0024d4d8ace401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973680537578bd5308cf4c5d98d235c7882800142b": "0x00e6d7efd75b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eef2e4a5f6a01d5fb89f38211fb4e6a8702d33b6": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfcbce9929e3c47198198c5f16c5786fdcd613bb1d973ab16eea54bc850f0aa44": "0x0087066f0dbebe06b184ad03aaac64f28b6299cc", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243b21315771454ef8c680dddd7b9bd5405a273262d": "0x00d098d4af710000000000000000000007f7b70000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ac4d821503dff89c3cee4e7797926ae8b7db2554": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f65aba8ace3c2b4a36c14de6c24a05f664274791": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d40c1e3c54b1a2443b533b14505b267c1329a25d": "0x006a097df4a600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51eef33d80b1de326c70cfe70ce0ba3c983c060000": "0xaa79627160ce8dad4d4619e0c5dc2890254d56b03dd41adbe171d38094b3345e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5199a457a2cf6fb2aa5e1a505165289de559070000": "0x5e50ae079503cb865c2f6933205ce0132c3e7cf2562c5b95d91eed99f3e5d97900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f28a4aeefb6f2d8b39298422ffd4a329fac161": "0x00ee69afcc2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d16293cb2df2f2416193f757871510572f7afddc8d958832689ef456c1096b12f": "0x000177e159f6b155a0e81f6859e9ca4c6610156d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978c94b11f460481f86363563e7eeb447225fdb61e": "0x00c6c5932b7300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d517ccc6eaa9380931987daf0ea1c53ce4ac4ca8": "0x00b808f1f31800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892fa4c6f0e3652cf77c03002677a72a46205e8f07": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928930f92bacb185193876bf6f37a6bb10f01aaeb36e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972271afc06ff1ccad666da20d7e4c5817ce1af599": "0x00a8c65f98b100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b79356aad9bf2116efe1a66ed55bf1a0d124393b": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51013f52bd9c2f46055087bf84aa58e77ba5050000": "0xe81caeb02e5b76e68d008ebbf4e3b036b570f2d4c44064daa5d1b5efa0e5e05200000000000000000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19502d9681c2705eea4a62616265806236877b05370265640c133fec07e64d7ca823db1dc56f2d3584b3d7c0f16158": "0x82104c22c383925323bf209d771dec6e1388285abe22c22d50de968467e0bb6c", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514a8d43b27fb31e087ea37e8b143955fb30040000": "0xe6d97bf878b1012927ae6afb7e092c541a5abc3904656981beaefb9ebb781d1c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002611243b23dc29e9ed64f28df2c344055cf3dd": "0x00580efad5aa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ae2f976301c5afec7ec28494b91471c1c2f1093": "0x00c05773a57c02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f489b21d5a4c8283a1bd0d39e47b654ba2f65a62": "0x0042224efe1700000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195035227179e48c40b8617564698014f13a09505d4014b468c1d3e394002832d9edc35dbbae1a7a6dc96025d47d5b": "0x5809fd84af6483070acbb92378e3498dbc02fb47f8e97f006bb83f60d7b2b15d", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d40a053bc7cc36ada17db15a16100e48122fe97f3993e9bda1e7b351167ebe314": "0xf95ca3e58c701eff23bcacbfc3c889ec6dc4a8ed", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243749ba28f1a561b462e7617728bf8f62ce0afbbbc": "0x004072e62d2d07000000000000000000a7df9c0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df49b492b314717533bade41861cb8699c765a0bab8ad7b83635662705c0a11d5": "0x516760a6e0a4f8e3683260c1b5275ac0b28992f4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009dbf13548b5351c0646b52b1f81d913d0fd4ae": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd86a0dc8d062ca62c6df695d1a7afa138453cbccbe7eb0a05eafd587cb68905e": "0x00fbcd1a1318617d6df1d267e92dc329c6dda05d", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b3fc16a327712c1b1cfe4ea6c22a21d136000000": "0x609aed1ba0cddb3e20270d959f1bea0923325b221f31d85579f61823beb16a3500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514ce6e23988ed01097fe19e29010cd76b72080000": "0xdcf71d4ff2e0e30717fbc3f2b8cb0074d7e950971e9b77ede358e6006a6cbc4200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890000a940f973ccf435ae9c040c253e1c043c5fb2": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243c69f44ccd469078bb71e7a704c162029e45c0c9d": "0x008032b03281ca000000000000000000c104b04701000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3222d82d891be17090c06fa35c1409148eb2f4240aec973b8b06e3320256e03c": "0xb8a300b59d4f4b3bc88e66d4ddc8edb8f0703edf", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cad1acfa9151d7eae13f06ea4d90a0024cf37301": "0x008eb095483490000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de8af9d2a328449e3a5ca67a98189d488ad8311b2bbd0fc2b9d02d2ca9dbffd41": "0x9bbd5f8d33f607a03690fa73f177f5a30c864542", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f1a0adc19a2cb4f04bef8a27e35039d0d90746": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970093073268cc5bbc3c4a616d9fa90cb49a34d339": "0x00d26a9b6f0d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfab2071283358794145d6ded609332c49c186df882ee3033ff446d462ae9cd17": "0x00d5f0ae658e4d4d48cce0355ab6c1eb155b7a82", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975bec595767bf447fb61edddc723765f241de1dc4": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d98e9fcc2871bfd309e2b7804dd699f1a9ec889d70b71788d6f19407df9dffd00": "0xd177586539eb325c70e15b369e1f8510bbd3cf44", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0ac4a702918dab29f9c5c317d250141b0afd8f3": "0x0044135e7e6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289836856d5d672d99ad3b450542cdacb91c394605d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767a01ab58cc873bfbd93c89f2b0897e85007b772": "0x004c2ee675141a000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b0afe917e54529d9151a5ec682107da993d89065": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898a209cb38555635734249fe6868ad40b4af6ec88": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397051ae28151a68cceea5e234694b82c913a802fb9": "0x00ea26c1d80400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6ec145d10ce8dd253112cf021c3e9b217a791a422a8ccf1312d463b52f749d04": "0x1bc24e64bd4446b8873a956a4fc1d1af2b798a2d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ffcf1f0f84cfc6fd881348ac8e74ec5856beefe": "0x004c9749858e05000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700de397b4f819087f0d36a12f89b4c0eebad2dbe": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51393d0670ebd6e639c31a5d82e77ab67ac8040000": "0xc686d330dff564af88ccd1d23e92b22b69e3b8ca825fd429bc3b8ce96758394c00000000000000000000000000000000", + "0x492a52699edf49c972c21db794cfcf57ba7fb8745735dc3be2a2c61a72c39e78": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006bcfd60159e0019278ce871a0a34bf54d9c585": "0x00a26a5406f200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243006a2ebbbfbbd4c4d0537c033b1e1ff34202bc61": "0x0000c52ebca2b100000000000000000030fb711f01000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970b3967aac9abb324d90ba784b0a4ed41d2a7c257": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775993bdf8a6c4c657f007fe09ec4fb4fcdeb3ba7": "0x00b4d919c66400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e59ec81fbd604f8de6eefc90cd6c155e0cc50e93": "0x0070b9648a5f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339720275e007f9678e47a9f3c52ea85d68c24217a65": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c33a725229490756ac021941021ea509853ff7d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008bd6775fb6055f78ac30fc24f3e55669499f5e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000a8a991cb59ddd83b76f334288e57997d25853": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c020f030a93bf6e1836931274ecaa1cc958683": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dc9c428b9828211415ee1e79fc3aabadc9db23": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009e51b0d7a06b3a8a22ddc326e1981d417a8b4a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dea07a98574e30bd9c10dcef40d228a0526d6e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289750383c5e0fcaab8fa81b168ebb0da0f280ff80e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890074a0ca635c314c5cd73ef58b1b8d64c5d7d20b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a8beea0a04b6f97bb39cff19803de453ef4cc02": "0x000e6e45853c04000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928985e96a824790b12fe512397506d97038500b861d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510ec7d96cdc380efe7b62a3af1e0dd8c575080000": "0x4ad1d079078b3775e1779bf8bdf34a72d89455cd0cfc224a73c7844ad80e190c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972da0721ba1e1f36de7c61bbf20ed24cb66ce9c1b": "0x005857a4df5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0fb96e2ba70b2c330c297339cb535629f887bf0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d59a70f01833d99da1ccf34de5792b10a3070000": "0x888f666828e8328a33647a47bc97574a6a5671819270cc01e66c7139a1a6911a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51200bc3e1973e504b2ced57eb4ada39e443040000": "0x12c60124aaaccb363fa69e6cc5cbc5a14a023292bda1b4bd5627ecd63a57160100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970087043671cef82fae55c6e6648e0d763e65e2fa": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977194210fbd35b97b861afb593c7832c201e1d149": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ac445b201cf29935e8ba9b60a2b6d5e7da040000": "0x3222d82d891be17090c06fa35c1409148eb2f4240aec973b8b06e3320256e03c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a44db7ef03c1c87530fe2aaba58a0b6b01d3c3e1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b4d63aa980b39130ed7e3ae50ec40c4d8b33935": "0x006e82e59c0794000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e28833ecc493aa66477f04c932a4d689598910": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ac20c60ff77408b1fdf3ac6e2739a14742a2779a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e925445ec68d6a9ce15567e1f769fd481ce9bae1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c05217770e1cae59d85c04f333cabfde7c7dbefb": "0x0044db3fc1ac00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51501fede49378d628c14dd0af5734f80575030000": "0xcefdc27aacad24de17bc8753a3c743debf7925f382a6d1c08601395aa679995e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da0dd8643134d45dc348125039356a3d2f9d785235a057a20476de704a088396b": "0x30caa2e774035687e738e60ed754c1787b206a81", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fba333b57f360e4aacb9d0809928fe8077d19a": "0x005cd89e184100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970033d8e0c69970ce4aa5402658135a4977e0948e": "0x0000bbf64f3000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c25af253615dd16c0cc521514164ff2b390b5cf": "0x00566411cc0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d141d0c26801c2dd28a7024e5def054866acaa52b6f3ae9a75bc97cb946358756": "0x1ccd8ff59612d4108d9bbe5f16add545efc6fdbe", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397516ca63270b7d253cd9af64cb9d92d62de81656c": "0x00f85e3055e100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339755a3df57b7aaec16a162fd5316f35bec082821cf": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fb5dfca2e526f23b90d21488082228750c17a3": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df25e936da97c044ba8806998462c4e7a67ef74d34cc9c7913c1110712915791c": "0x3e7321d013167e5d2a3b591bac90baf4c75839e5", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007a74c0c90eb301c7355654b4c91fbcf267a1c6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b14e2f2c808cfcbed4b27fc8f692c928589ded14": "0x00806a95f10875010000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c80503caa4caae2640f0bf835bd5e3418d4ee1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890c31fd4e2f78849537318712136cbf7317f21828": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892cf6d5701b164808a3f3886ee6258bf3208c3743": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ebb73c3f457b46f0e1b2c20406d790bebbc0a6b": "0x0016a70ef24b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898a34b5de30bbf7a351c897e26b088397487bad42": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5144210727819e664cf937354b3bd693d976070000": "0x86fda27b3c3ff7a15263d00c70005336bd9c68bed4de5c3a0a3aa647e837ff4800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5cfa14f1be34d343b9e57e73ed8f76e09cda02868bb39e6f62f4eea00c031f45": "0x17e7adf544b8c6ab81cfd449f4154d14a61b2b29", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928967db7a2aa35266295c4e478f2f6f1a1f6663e0c0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f3bbb30d00284df9abc29e5601e34965df641199": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b5f693f7f2c0816e8fd985ff70cbefec71040000": "0xd24f805ca7bafb11cfdb0ace585a9d0e6edf83878dc7b42946c33c237821146400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5101b9073aad15c4f4b97d04017a373a417b070000": "0x1a4b46decc58f38eddd3fd8f8b7a0a92b18ad34305d8d6f85efcae77dafb255d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51721245d3c35c025faab60ebf14cb9192f2070000": "0x1c55d0e6a0f11181546f76dab623b362ead1b0e116aded1d03cbea230e25a24600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de244a01a44bff3d79ed4d3d94bad2b172099b654cd11350563eaea8aa827256c": "0x8e4c6d9d21ed31544cc123f5153d39fe65e9a9e1", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001b93e99a0ea0e8b12f3df09af6564b460aa7e6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890050e26f4860d18a81ec8685bee8e73b18f2614a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b03d651170ceee35729aff792d522fd952cf94c0": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282437c89a2437b7cc02b0bdac206ac317a8a1e7826db": "0x00602225aa3f000000000000000000003705670000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df2ea1da319a6f1135144b3daa5bc1c34a92dfbcfac7f3a77233ac12009ab3f90": "0x50b7f7661c2057fd75c097eec2d06b21d586661a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397798036906b3adc3d933e8cf1a88bf25955b2ee06": "0x00dcefed772300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c589611f018087385cbd3d91b8fedc67f2c9c795": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e88b871f4d3c16b385ddff8370f6730b9b74c38b": "0x0028c0a3822300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7afff4a998fecc10c07df0f46ace2a365517324289dd106c75005d1c5cccfd21": "0xfc03c8f4f7484323459b2b4910f2f67e59c8d0dd", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cabc87c953dad294fc0ed22c563bac10fa8e3ab5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973842775e7e6cba076c5f3d44f0fc444b93a1502b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b50e79852b9973d30f5b775509cd3d8dd8bd78ba": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2eba9a39dbfdd5f3cba964355d45e27319f0271023c0353d97dc6df2401b0e3d": "0xedc6c4c1ae525da2942fcf03c7b98c12391edaed", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397202a7913fc42692223e0f04d3be7a8c11c76dc5c": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d6352629387b12b8c5a32871336775d10b105b3": "0x002a378ad65b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928948973b94b0273ce3d54774144b4941996bc62556": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891af41a96bbaf348c3ca582b65193ab4d9108a22b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5ce26469794d196f16f4b83422bdae40f610dd8": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b98df46a871a544265c71648cb708525fd913ed8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890036c76ec47dfc17a96b1a68893bf269e1c2875b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891330b7402f677e3adc774d13164ebbd9066ce181": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6ed4e490d482667ac41cfce61cb6595a36e7b70cc16316f305fe5c590c892756": "0x527a1247054d4dee8fe4720990dd8b9154225487", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f656b95dd71863355bd5aefb313a06590eb921a": "0x00009573c24800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5178e2e5a74d8645914d05428266134dd453070000": "0x565169aafd38d441981d7560cd298045d69aa86113a0ef023ca4de562441827d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928928e66a9abb74aa9fbc4dddb71775f0cdbb7ae031": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898efb665b2cfd82983e06562b355878da59878368": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928974f63340b5ca9fca58b50dcbf6cedd1c97972200": "0x00", + "0x3a636f6465": "0x0061736d0100000001fe023560037f7f7f017f60027f7f017f60027f7f0060017f0060047f7f7f7f0060057f7f7f7f7f0060037f7f7f0060017f017e60037f7e7e0060017e017f60027e7e0060017e0060017e017e6000017f60000060027f7e017e60047f7e7e7e017f60037f7e7f017f6000017e60027f7e017f60027f7f017e60037f7f7e017e60037e7e7f017e60017f017f60027e7f017f60057f7f7f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60047f7f7f7e0060067f7f7f7f7f7f0060057f7e7e7f7f0060027f7e0060057f7f7f7e7e0060057f7f7e7e7f0060047e7e7e7e017f60047f7f7e7e0060087f7f7f7f7f7f7f7f0060067f7f7e7f7f7f0060037e7f7f017f60067f7f7e7f7e7e0060077f7e7e7e7e7e7e0060087e7e7e7e7e7e7e7e017f60067f7f7f7e7e7f0060077f7f7e7e7e7e7f0060077f7f7f7f7f7e7e0060057f7f7f7f7f017e60067f7f7f7f7e7e0060057f7e7e7e7e017f60047f7e7f7f0060057f7e7e7e7e0060027e7e017e60067f7e7e7e7e7f0060047f7e7e7f0002cf0c2803656e76066d656d6f727902001403656e76196578745f6c6f6767696e675f6c6f675f76657273696f6e5f31000803656e761e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f31000903656e761d6578745f68617368696e675f74776f785f36345f76657273696f6e5f31000903656e76196578745f73746f726167655f7365745f76657273696f6e5f31000a03656e761b6578745f73746f726167655f636c6561725f76657273696f6e5f31000b03656e76206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f31000903656e76226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f31000b03656e76196578745f73746f726167655f6765745f76657273696f6e5f31000c03656e761d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f31000b03656e76226578745f6f6666636861696e5f72616e646f6d5f736565645f76657273696f6e5f31000d03656e761c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f31000b03656e76276578745f63727970746f5f73746172745f62617463685f7665726966795f76657273696f6e5f31000e03656e76286578745f63727970746f5f66696e6973685f62617463685f7665726966795f76657273696f6e5f31000d03656e76236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f31000d03656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f31000f03656e76346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f31001003656e76206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f31000903656e76206578745f68617368696e675f6b656363616b5f3235365f76657273696f6e5f31000903656e76236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f31001103656e76226578745f6d6973635f72756e74696d655f76657273696f6e5f76657273696f6e5f31000c03656e761c6578745f73746f726167655f617070656e645f76657273696f6e5f31000a03656e761e6578745f73746f726167655f6e6578745f6b65795f76657273696f6e5f31000c03656e761c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f31000b03656e76236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f32001103656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f31000803656e761a6578745f73746f726167655f726f6f745f76657273696f6e5f31001203656e76226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f31000c03656e762a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f31000903656e76256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f31001303656e762c6578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f76657273696f6e5f31001403656e76376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f31001403656e76256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f31001303656e76286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f31000703656e76216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f31001503656e76246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f31001203656e76296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f31000c03656e761a6578745f73746f726167655f726561645f76657273696f6e5f31001603656e761e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f31001703656e761c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f31000303c707c5071717030300001717140e0e0e06060206000e0e050001010201020202020201180307191a06060005010101171b0101010601010100040101000101000001000301010102060617020202020602060200010106010203010203060601051c050301010206030606060606060606060606060606060606060606060206060206060606060606060606020702171712020202010602060303030e020603020206021d02060203030606060206010203060606020202020202020206070606020202030e030202020602020202020203020203020602020602061e080802020202020304021d1f01020206172002020203020205020502040606060206060202060203020621060201022223240304060401060203010302020202020206250d0226270602020206020203030228030a020d0602290105032200030202060202020202020206061902020206020202021402140202030202040e030302011414031402021402061402030202140214061402060601011402050202020114140314020614140614021402140214021402020206010114020106140202141414060614020214021402020202030204030302030202010202030104022a03030202230606062a040303020306060601020e0206020202020202020202020202020202020602060602060606031d1a04020303061d02020106020602020206060606020303030202020206022b06020206030206021f02020706020d020602020202020617060502020602020202060e0202170206020606022402020703030203030202020206032c010303030303030202020102060005020201041d0203030303030303030303030303030303030303030303030302020202020202020202020402060206040202020202060202060202020602060606020402020202061c2d060403060402020602020606020402060206020202062e020606020206042f02030202020202020e020202020202020202020201060206060b020203020202010106060302020206060206020103000103050101030303030303030203030202020202030201031d1d05041d0605050402040d060203030001010303020505060303020303060303030203030303020203061a06033006020202040303030206020505050202060303020204020303030303020204040600030202040002021c2d020602030302020603020206020303020303030202020202020203030201020206170203020303020303030202020203020202020202030302030202020203020303060617010102010105010206023131310e0c323232323232083131333100000000343434340407017001fc01fc010619037f01418080c0000b7f0041e0a7cc000b7f0041e0a7cc000b07800821195f5f696e6469726563745f66756e6374696f6e5f7461626c65010009686173685f74657374002f0c436f72655f76657273696f6e00f50212436f72655f657865637574655f626c6f636b00f70215436f72655f696e697469616c697a655f626c6f636b008303114d657461646174615f6d657461646174610084031c426c6f636b4275696c6465725f6170706c795f65787472696e7369630086031b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b00890320426c6f636b4275696c6465725f696e686572656e745f65787472696e73696373008c031c426c6f636b4275696c6465725f636865636b5f696e686572656e747300910318426c6f636b4275696c6465725f72616e646f6d5f736565640093032b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e009503214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b6572009b031850617261636861696e486f73745f76616c696461746f727300a2031950617261636861696e486f73745f647574795f726f7374657200a3031f50617261636861696e486f73745f6163746976655f70617261636861696e7300a5032850617261636861696e486f73745f676c6f62616c5f76616c69646174696f6e5f7363686564756c6500a8032350617261636861696e486f73745f6c6f63616c5f76616c69646174696f6e5f6461746100a9031c50617261636861696e486f73745f70617261636861696e5f636f646500ab031750617261636861696e486f73745f6765745f686561647300ad031d50617261636861696e486f73745f7369676e696e675f636f6e7465787400af031e4772616e6470614170695f6772616e6470615f617574686f72697469657300b1032f4772616e6470614170695f7375626d69745f7265706f72745f65717569766f636174696f6e5f65787472696e73696300b303274772616e6470614170695f67656e65726174655f6b65795f6f776e6572736869705f70726f6f6600ba0315426162654170695f636f6e66696775726174696f6e00be031b426162654170695f63757272656e745f65706f63685f737461727400c10321417574686f72697479446973636f766572794170695f617574686f72697469657300c2032153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b65797300c3031f53657373696f6e4b6579735f6465636f64655f73657373696f6e5f6b65797300c6031d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e636500c903205472616e73616374696f6e5061796d656e744170695f71756572795f696e666f00cb030a5f5f646174615f656e6403010b5f5f686561705f62617365030209dd03010041010bfb013f45584fce0750515964820167b8018c0283068701b602ba028203f7056899039a03a1039606b803b903a207840697065a87063b3c3d69485b5d5e5f60617677787a7b7f7d7ef3019407f201a205eb01b007f101f001ef01ee01ec01ea01f601f501cd07ed06d503d803d70355ed039907a904cb07e704e604e504f606ec04ed04d007f304af07ae078105b407c307d406be06c806c7068205d403d603f104f004f204ef04ee048305ec03eb038405ee039404d006d106e104e004ea04e901e7018505f401bb02df028605930792078705aa07cb06ca06cc06d806ec06eb068805fc069e069d068905ba068a058b058c058d058e05f206f1068f058807f306bc07bb079005be07c507a0079f0791059607950792059707ab07a106a0069106cf06ce06bf06e404e3049305b404f506f4069405df06a704a6049505a80495049b069a0696059c06b906e203e10397058f04990698069805aa069f059e059d059c059b059a059905a00556f2039f06a406a306a206bb06bc06bd06c406ff068007f806fb06c106f906fa06fd06fe06cd06f706d306d206e906e806ea06ee068d078e078f07900789078a078b078c079e079d079c079b079a079807b307b207b107ba07b907b807b707b607b507bd07c207c107c007bf070aa5945fc5070600200010280b0600200010250b06002000102a0b0600200010260b0a00200020012002102c0b2801017f0240200210252203450d002003200020022001200120024b1b10e4071a200010260b20030b06002000102e0b1c01017f0240200010252201450d0020014100200010e6071a0b20010bff0202017f037e230041206b220224002001ad42adfed5e4d485fda8d8007e42b9e0007c210302400240024002400240200141084b0d00200141014b0d0120010d02420021040c030b0240200141104b0d00200241106a2000290000200385420042adfed5e4d485fda8d800420010d507200241186a29030020022903107c200120006a41786a2900008521040c040b200120006a41786a2900002105200321040340200029000020048542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e2003852103200041086a2100200442cf829ebbefefde82147c2104200141786a220141084b0d000b200320058521040c030b0240200141034b0d00200120006a417e6a33000042108620003300008420038521040c030b200120006a417c6a35000042208620003500008420038521040c020b200031000021040b200420038521040b20022004420042adfed5e4d485fda8d800420010d507200241086a290300210420022903002103200241206a2400200420037c42c300850b05001031000b2400410041b093cc00ad4280808080f0008441b793cc00ad4280808080a00484100000000b110041a4a1cc004111419080c0001033000b4701017f230041206b22032400200341146a410036020020034180a6cc00360210200342013702042003200136021c200320003602182003200341186a360200200320021040000bdd0101047f0240024002400240200041046a2802002203200041086a28020022046b200220016b2202490d00200028020021050c010b200420026a22052004490d01200341017422062005200620054b1b22064100480d010240024002402003450d00200028020022050d010b024020060d00410121050c020b2006102722050d010c040b024020032006460d00200520032006102b21050b2005450d03200041086a28020021040b20002005360200200041046a20063602000b200520046a2001200210e4071a200041086a200420026a3602000f0b1032000b1030000b8b0301067f230041306b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240024002400240200141146a2802000d00200621070c010b024020040d004100410041b880c0001036000b024002402006410f4b0d00200341046a280200450d010b200620066a220720064f0d010b4100210741012105200241086a21060c010b2007417f4c0d01200241086a2106024020070d0041002107410121050c010b200710272205450d020b20024100360210200220053602082002200736020c2002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241146a41c880c000200241186a10370d0220002006290200370200200041086a200641086a280200360200200241306a24000f0b1038000b1039000b41e080c0004133200241186a419481c00041a481c000103a000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341a885c000360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a20021040000bba06010a7f230041306b22032400200341246a2001360200200341033a002820034280808080800437030820032000360220410021042003410036021820034100360210024002400240024020022802082205450d0020022802002106200228020422072002410c6a2802002208200820074b1b2209450d01200241146a280200210a2002280210210b41012108200020062802002006280204200128020c1100000d03200541106a2102200641086a2100410121040240024003402003200241746a28020036020c20032002410c6a2d00003a00282003200241786a280200360208200241086a28020021084100210541002101024002400240200241046a2802000e03010002010b2008200a4f0d032008410374210c41002101200b200c6a220c2802044102470d01200c28020028020021080b410121010b2003200836021420032001360210200228020021080240024002402002417c6a2802000e03010002010b2008200a4f0d0420084103742101200b20016a22012802044102470d01200128020028020021080b410121050b2003200836021c200320053602180240200241706a2802002208200a4f0d00200b20084103746a2208280200200341086a20082802041101000d06200420094f0d05200041046a210120002802002105200241206a2102200041086a210041012108200441016a2104200328022020052001280200200328022428020c110000450d010c070b0b2008200a41808ac0001036000b2008200a41f089c0001036000b2008200a41f089c0001036000b2002280200210620022802042207200241146a2802002208200820074b1b220a450d002002280210210241012108200020062802002006280204200128020c1100000d02200641086a21004101210403402002280200200341086a200241046a2802001101000d022004200a4f0d01200041046a210120002802002105200241086a2102200041086a210041012108200441016a2104200328022020052001280200200328022428020c110000450d000c030b0b0240200720044d0d00410121082003280220200620044103746a22022802002002280204200328022428020c1100000d020b410021080c010b410121080b200341306a240020080b05001032000b05001030000b7e01017f230041c0006b220524002005200136020c2005200036020820052003360214200520023602102005412c6a41023602002005413c6a41033602002005420237021c20054194f2c400360218200541043602342005200541306a3602282005200541106a3602382005200541086a360230200541186a20041040000b120020002802002001200120026a103441000bc30301047f230041106b22022400200028020021000240024002400240024002402001418001490d002002410036020c2001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c050b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c040b0240024020002802082203200041046a280200460d00200028020021040c010b200341016a22042003490d02200341017422052004200520044b1b22054100480d020240024002402003450d00200028020022040d010b024020050d00410121040c020b2005102722040d010c050b024020032005460d00200420032005102b21040b2004450d04200028020821030b20002004360200200041046a20053602000b200420036a20013a00002000200028020841016a3602080c040b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c020b1032000b1030000b20002002410c6a2002410c6a20016a10340b200241106a240041000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41c880c000200241086a10372101200241206a240020010b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c2002419082c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41a882c0001040000b0b002000350200200110460b3401017f230041106b220224002002200136020c20022000360208200241b885c00036020420024180a6cc0036020020021047000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241f882c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a419083c0001040000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241cc83c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41e483c0001040000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c2002418884c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41a084c0001040000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241ec84c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a418485c0001040000b0d0020002802001a037f0c000b0bd20203027f017e037f230041306b22022400412721030240024020004290ce005a0d00200021040c010b412721030340200241096a20036a2205417c6a200020004290ce0080220442f0b17f7e7ca7220641ffff037141e4006e220741017441fa85c0006a2f00003b00002005417e6a2007419c7f6c20066a41ffff037141017441fa85c0006a2f00003b00002003417c6a2103200042ffc1d72f5621052004210020050d000b0b02402004a7220541e3004c0d00200241096a2003417e6a22036a2004a7220641ffff037141e4006e2205419c7f6c20066a41ffff037141017441fa85c0006a2f00003b00000b024002402005410a480d00200241096a2003417e6a22036a200541017441fa85c0006a2f00003b00000c010b200241096a2003417f6a22036a200541306a3a00000b20014180a6cc004100200241096a20036a412720036b10492103200241306a240020030b6f01017f230041c0006b220124002001200036020c200141346a410136020020014201370224200141a893cc003602202001410536023c2001200141386a36023020012001410c6a360238200141106a200141206a1035410141b093cc0041072001280210200128021810cf0700000b0d0042a98089cda5ebd0e9ae7f0be80501067f20002802002205410171220620046a21070240024020054104710d00410021010c010b4100210802402002450d00200221092001210a03402008200a2d000041c00171418001466a2108200a41016a210a2009417f6a22090d000b0b200720026a20086b21070b412b418080c40020061b21080240024020002802084101460d004101210a2000200820012002104a0d012000280218200320042000411c6a28020028020c110000210a0c010b02402000410c6a280200220920074b0d004101210a2000200820012002104a0d012000280218200320042000411c6a28020028020c1100000f0b0240024020054108710d004100210a200920076b22092105024002400240410120002d0020220720074103461b0e0402010001020b2009410176210a200941016a41017621050c010b410021052009210a0b200a41016a210a0340200a417f6a220a450d0220002802182000280204200028021c280210110100450d000b41010f0b200028020421052000413036020420002d002021064101210a200041013a00202000200820012002104a0d014100210a200920076b22092102024002400240410120002d0020220820084103461b0e0402010001020b2009410176210a200941016a41017621020c010b410021022009210a0b200a41016a210a02400340200a417f6a220a450d0120002802182000280204200028021c280210110100450d000b41010f0b200028020421094101210a200028021820032004200028021c28020c1100000d01200241016a2108200028021c210220002802182101024003402008417f6a2208450d014101210a2001200920022802101101000d030c000b0b200020063a00202000200536020441000f0b200028020421094101210a2000200820012002104a0d00200028021820032004200028021c28020c1100000d00200541016a2108200028021c210220002802182100034002402008417f6a22080d0041000f0b4101210a200020092002280210110100450d000b0b200a0b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101101000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11000021040b20040b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341c487c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a20021040000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341fc87c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a20021040000b9307010c7f200041106a28020021030240024002400240200041086a28020022044101460d0020034101460d012000280218200120022000411c6a28020028020c11000021030c030b20034101470d010b0240024020020d00410021020c010b200120026a2105200041146a28020041016a21064100210720012103200121080340200341016a210902400240024020032c0000220a417f4a0d000240024020092005470d004100210b200521030c010b20032d0001413f71210b200341026a220921030b200a411f71210c0240200a41ff0171220a41df014b0d00200b200c41067472210a0c020b0240024020032005470d004100210d2005210e0c010b20032d0000413f71210d200341016a2209210e0b200d200b41067472210b0240200a41f0014f0d00200b200c410c7472210a0c020b02400240200e2005470d004100210a200921030c010b200e41016a2103200e2d0000413f71210a0b200b410674200c411274418080f0007172200a72220a418080c400470d020c040b200a41ff0171210a0b200921030b02402006417f6a2206450d00200720086b20036a21072003210820052003470d010c020b0b200a418080c400460d00024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20044101460d002000280218200120022000411c6a28020028020c1100000f0b4100210902402002450d002002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b0240200220096b200028020c2206490d002000280218200120022000411c6a28020028020c1100000f0b410021074100210902402002450d00410021092002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b200920026b20066a2209210a024002400240410020002d0020220320034103461b0e0402010001020b20094101762107200941016a410176210a0c010b4100210a200921070b200741016a2103024003402003417f6a2203450d0120002802182000280204200028021c280210110100450d000b41010f0b2000280204210941012103200028021820012002200028021c28020c1100000d00200a41016a2103200028021c210a20002802182100034002402003417f6a22030d0041000f0b20002009200a280210110100450d000b41010f0b20030bc80801067f230041f0006b220524002005200336020c20052002360208410121062001210702402001418102490d00410020016b2108418002210903400240200920014f0d00200020096a2c000041bf7f4c0d0041002106200921070c020b2009417f6a21074100210620094101460d01200820096a210a20072109200a4101470d000b0b200520073602142005200036021020054100410520061b36021c20054180a6cc0041c088c00020061b3602180240024002400240200220014b22090d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200520023602202002450d0220022001460d02200141016a210a03400240200220014f0d00200020026a2c000041404e0d040b2002417f6a210920024101460d04200a2002462107200921022007450d000c040b0b20052002200320091b360228200541306a41146a4103360200200541c8006a41146a4104360200200541d4006a410436020020054203370234200541c888c0003602302005410136024c2005200541c8006a3602402005200541186a3602582005200541106a3602502005200541286a360248200541306a20041040000b200541e4006a4104360200200541c8006a41146a4104360200200541d4006a4101360200200541306a41146a410436020020054204370234200541e088c0003602302005410136024c2005200541c8006a3602402005200541186a3602602005200541106a36025820052005410c6a3602502005200541086a360248200541306a20041040000b200221090b024020092001460d00410121070240024002400240200020096a220a2c00002202417f4a0d0041002106200020016a220721010240200a41016a2007460d00200a41026a2101200a2d0001413f7121060b2002411f71210a200241ff017141df014b0d012006200a4106747221010c020b2005200241ff0171360224200541286a21020c020b4100210020072108024020012007460d00200141016a210820012d0000413f7121000b200020064106747221010240200241ff017141f0014f0d002001200a410c747221010c010b41002102024020082007460d0020082d0000413f7121020b2001410674200a411274418080f00071722002722201418080c400460d020b2005200136022441012107200541286a21022001418001490d00410221072001418010490d0041034104200141808004491b21070b200520093602282005200720096a36022c200541306a41146a4105360200200541ec006a4104360200200541e4006a4104360200200541c8006a41146a4106360200200541d4006a4107360200200542053702342005418089c000360230200520023602582005410136024c2005200541c8006a3602402005200541186a3602682005200541106a3602602005200541246a3602502005200541206a360248200541306a20041040000b41a79dc800412b20041033000b1000200120002802002000280204104d0b800101037f230041206b22022400024002402000280200200110540d002001411c6a2802002103200128021821042002411c6a410036020020024180a6cc003602182002420137020c200241e889c00036020820042003200241086a1037450d010b200241206a240041010f0b2000280204200110542101200241206a240020010bdd0502047f017e410121020240200128021841272001411c6a2802002802101101000d0041022103024002400240024002402000280200220041776a2204411e4d0d00200041dc00470d010c020b41f40021050240024020040e1f05010202000202020202020202020202020202020202020202030202020203050b41f20021050c040b41ee0021050c030b024002400240200010520d00024002400240200041808004490d00200041808008490d0120004190fc476a4190fc0b490d02200041b5d9736a41b5db2b490d02200041e28b746a41e20b490d022000419fa8746a419f18490d02200041dee2746a410e490d02200041feffff0071419ef00a460d02200041a2b2756a4122490d02200041cb91756a410a4b0d050c020b200041d08ac000412941a28bc00041a20241c48dc00041b5021053450d010c040b200041f98fc000412641c590c00041af0141f491c00041a30310530d030b200041017267410276410773ad4280808080d0008421060c010b200041017267410276410773ad4280808080d0008421060b410321030c020b410121030c010b0b200021050b03402003210441dc002100410121024101210302400240024002400240024020040e0402010500020b02400240024002402006422088a741ff01710e06050302010006050b200642ffffffff8f608342808080803084210641f50021000c060b200642ffffffff8f608342808080802084210641fb0021000c050b20052006a72204410274411c7176410f712203413072200341d7006a2003410a491b210002402004450d002006427f7c42ffffffff0f832006428080808070838421060c050b200642ffffffff8f60834280808080108421060c040b200642ffffffff8f6083210641fd0021000c030b41002103200521000c030b20012802184127200128021c2802101101000f0b200642ffffffff8f60834280808080c0008421060b410321030b20012802182000200128021c280210110100450d000b0b20020b9d0301057f0240024002404100410f200041a49a04491b2201200141086a2201200141027441d895c0006a280200410b742000410b7422014b1b2202200241046a2202200241027441d895c0006a280200410b7420014b1b2202200241026a2202200241027441d895c0006a280200410b7420014b1b2202200241016a2202200241027441d895c0006a280200410b7420014b1b220241027441d895c0006a280200410b74220320014620032001496a20026a2201411e4b0d002001410274210241b105210302402001411e460d00200241dc95c0006a2204450d00200428020041157621030b4100210402402001417f6a220520014b0d002005411f4f0d03200541027441d895c0006a28020041ffffff007121040b02402003200241d895c0006a280200411576220141016a460d00200020046b21022003417f6a2103410021000340200141b0054b0d032000200141e496c0006a2d00006a220020024b0d012003200141016a2201470d000b0b20014101710f0b2001411f41989cc0001036000b200141b10541a89cc0001036000b2005411f41d496c0001036000bea0201067f200120024101746a210720004180fe0371410876210841002109200041ff0171210a0240024002400340200141026a210b200920012d000122026a210c024020012d000022012008460d00200120084b0d03200c2109200b2101200b2007470d010c030b0240200c2009490d00200c20044b0d02200320096a2101024003402002450d012002417f6a210220012d00002109200141016a21012009200a470d000b410021020c050b200c2109200b2101200b2007470d010c030b0b2009200c419895c000104c000b200c2004419895c000104b000b200041ffff03712109200520066a210c4101210202400340200541016a210a0240024020052d00002201411874411875220b4100480d00200a21050c010b200a200c460d02200b41ff007141087420052d0001722101200541026a21050b200920016b22094100480d02200241017321022005200c470d000c020b0b41a79dc800412b41a895c0001033000b20024101710ba50201037f23004180016b2202240002400240024002400240200128020022034110710d0020034120710d012000ad2001104621000c020b410021030340200220036a41ff006a2000410f712204413072200441d7006a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d02200141b88ac0004102200220036a4180016a410020036b104921000c010b410021030340200220036a41ff006a2000410f712204413072200441376a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d02200141b88ac0004102200220036a4180016a410020036b104921000b20024180016a240020000f0b200041800141a88ac000104c000b200041800141a88ac000104c000b1c00200128021841a99dc000410b2001411c6a28020028020c1100000b1c00200128021841b49dc000410e2001411c6a28020028020c1100000b5b01017f230041306b220324002003200136020c20032000360208200341246a410136020020034201370214200341a893cc003602102003410436022c2003200341286a3602202003200341086a360228200341106a20021040000b140020002802002001200028020428020c1101000b6901037f230041206b220224002001411c6a280200210320012802182104200241086a41106a2000280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a10372101200241206a240020010b15002001200028020022002802002000280204104d0bb10401077f230041306b220324000240024020020d00410021040c010b200341286a210502400240024002400340024020002802082d0000450d00200028020041fd9dc0004104200028020428020c1100000d050b2003410a3602282003428a808080103703202003200236021c200341003602182003200236021420032001360210200341086a410a20012002105c024002400240024020032802084101470d00200328020c210403402003200420032802186a41016a2204360218024002402004200328022422064f0d00200328021421070c010b200328021422072004490d00200641054f0d072003280210200420066b22086a22092005460d0420092005200610e707450d040b200328021c22092004490d0220072009490d0220032006200341106a6a41176a2d0000200328021020046a200920046b105c2003280204210420032802004101460d000b0b2003200328021c3602180b200028020841003a0000200221040c010b200028020841013a0000200841016a21040b2000280204210920002802002106024020044520022004467222070d00200220044d0d03200120046a2c000041bf7f4c0d030b200620012004200928020c1100000d04024020070d00200220044d0d04200120046a2c000041bf7f4c0d040b200120046a2101200220046b22020d000b410021040c040b2006410441849ec000104b000b200120024100200441949ec000104e000b200120022004200241b088c000104e000b410121040b200341306a240020040bf80201067f410021040240024020024103712205450d00410420056b2205450d0020032005200520034b1b210441002105200141ff01712106034020042005460d01200220056a2107200541016a210520072d000022072006470d000b410121032007200141ff01714641016a41017120056a417f6a21050c010b200141ff017121060240024020034108490d002004200341786a22084b0d00200641818284086c210502400340200220046a220741046a2802002005732209417f73200941fffdfb776a7120072802002005732207417f73200741fffdfb776a7172418081828478710d01200441086a220420084d0d000b0b200420034b0d010b200220046a2109200320046b210241002103410021050240034020022005460d01200920056a2107200541016a210520072d000022072006470d000b410121032007200141ff01714641016a41017120056a417f6a21050b200520046a21050c010b2004200341c09ec000104c000b20002005360204200020033602000b8b0201027f230041106b220224002002410036020c02400240024002402001418001490d002001418010490d012002410c6a21032001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c2002410c6a2103410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c2002410c6a2103410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b200020032001105b2101200241106a240020010b6001017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a418c9fc000200241086a10372101200241206a240020010b0d00200028020020012002105b0b0b0020002802002001105d0b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a418c9fc000200241086a10372101200241206a240020010bd30202047f027e230041c0006b2203240041012104024020002d00080d00200028020421050240200028020022062d00004104710d0041012104200628021841eb9ec00041a49fc00020051b4102410120051b2006411c6a28020028020c1100000d0120012000280200200228020c11010021040c010b024020050d0041012104200628021841a59fc00041022006411c6a28020028020c1100000d01200028020021060b41012104200341013a0017200341346a41f09ec000360200200320062902183703082003200341176a3602102006290208210720062902102108200320062d00203a00382003200837032820032007370320200320062902003703182003200341086a3602302001200341186a200228020c1101000d00200328023041889fc0004102200328023428020c11000021040b200020043a00082000200028020441016a360204200341c0006a240020000bd40202037f027e230041c0006b2203240041012104024020002d00040d0020002d000521040240200028020022052d00004104710d000240200441ff0171450d0041012104200528021841eb9ec00041022005411c6a28020028020c1100000d02200028020021050b20012005200228020c11010021040c010b0240200441ff01710d0041012104200528021841a89fc00041012005411c6a28020028020c1100000d01200028020021050b41012104200341013a0017200341346a41f09ec000360200200320052902183703082003200341176a3602102005290208210620052902102107200320052d00203a00382003200737032820032006370320200320052902003703182003200341086a3602302001200341186a200228020c1101000d00200328023041889fc0004102200328023428020c11000021040b200041013a0005200020043a0004200341c0006a240020000b6401027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a10372100200241206a240020000bd70a020c7f017e230041206b220324004101210402400240200228021841222002411c6a2802002802101101000d000240024020010d00410021050c010b200020016a21064100210520002107410021080240034020072109200741016a210a02400240024020072c0000220b417f4a0d0002400240200a2006470d004100210c200621070c010b20072d0001413f71210c200741026a220a21070b200b411f7121040240200b41ff0171220b41df014b0d00200c200441067472210c0c020b0240024020072006470d004100210d2006210e0c010b20072d0000413f71210d200741016a220a210e0b200d200c41067472210c0240200b41f0014f0d00200c2004410c7472210c0c020b02400240200e2006470d004100210b200a21070c010b200e41016a2107200e2d0000413f71210b0b200c4106742004411274418080f0007172200b72220c418080c400470d020c040b200b41ff0171210c0b200a21070b4102210a024002400240024002400240200c41776a220b411e4d0d00200c41dc00470d010c020b41f400210e02400240200b0e1f05010202000202020202020202020202020202020202020202030202020203050b41f200210e0c040b41ee00210e0c030b0240200c10520d0002400240200c41808004490d00200c41808008490d01200c4190fc476a4190fc0b490d02200c41b5d9736a41b5db2b490d02200c41e28b746a41e20b490d02200c419fa8746a419f18490d02200c41dee2746a410e490d02200c41feffff0071419ef00a460d02200c41a2b2756a4122490d02200c41cb91756a410a4d0d020c060b200c41d08ac000412941a28bc00041a20241c48dc00041b5021053450d010c050b200c41f98fc000412641c590c00041af0141f491c00041a30310530d040b200c41017267410276410773ad4280808080d00084210f4103210a0c010b0b200c210e0b2003200136020420032000360200200320053602082003200836020c0240024020082005490d0002402005450d0020052001460d00200520014f0d01200020056a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020056a200820056b200228021c28020c110000450d01410121040c060b20032003410c6a3602182003200341086a36021420032003360210200341106a1066000b0340200a210b4101210441dc0021054101210a024002400240024002400240200b0e0402010500020b0240024002400240200f422088a741ff01710e06050302010006050b200f42ffffffff8f608342808080803084210f4103210a41f50021050c070b200f42ffffffff8f608342808080802084210f4103210a41fb0021050c060b200e200fa7220b410274411c7176410f71220a413072200a41d7006a200a410a491b21050240200b450d00200f427f7c42ffffffff0f83200f4280808080708384210f0c050b200f42ffffffff8f608342808080801084210f0c040b200f42ffffffff8f6083210f4103210a41fd0021050c040b4100210a200e21050c030b4101210a0240200c418001490d004102210a200c418010490d0041034104200c41808004491b210a0b200a20086a21050c040b200f42ffffffff8f60834280808080c00084210f0b4103210a0b20022802182005200228021c280210110100450d000c050b0b200820096b20076a210820062007470d000b0b2005450d0020052001460d00200520014f0d02200020056a2c000041bf7f4c0d020b410121042002280218200020056a200120056b200228021c28020c1100000d0020022802184122200228021c28021011010021040b200341206a240020040f0b200020012005200141b088c000104e000b2b01017f2000280200220128020020012802042000280204280200200028020828020041ac9fc000104e000b870101027f23004180016b2202240020002d00002103410021000340200220006a41ff006a20034101714130723a00002000417f6a2100200341017641ff007122030d000b024020004180016a2203418101490d00200341800141a88ac000104c000b200141bc9fc0004102200220006a4180016a410020006b1049210020024180016a240020000b900101037f23004180016b2202240020002802002103410021000340200220006a41ff006a2003410f712204413072200441376a2004410a491b3a00002000417f6a2100200341047622030d000b024020004180016a2203418101490d00200341800141a88ac000104c000b200141b88ac0004102200220006a4180016a410020006b1049210020024180016a240020000b1c00200128021841bcb0c00041052001411c6a28020028020c1100000bc80401067e20002001290320220242338842137e2001290300220342ffffffffffffff03837c220442137c4233882001290308220542ffffffffffffff038320034233887c22037c4233882001290310220642ffffffffffffff038320054233887c22057c4233882001290318220742ffffffffffffff038320064233887c22067c423388200242ffffffffffffff038320074233887c22077c42338842137e20047c22023c0000200020024228883c0005200020024220883c0004200020024218883c0003200020024210883c0002200020024208883c00012000200242338820037c22044225883c000b20002004421d883c000a200020044215883c000920002004420d883c0008200020044205883c00072000200442338820057c2203422a883c0012200020034222883c001120002003421a883c0010200020034212883c000f20002003420a883c000e200020034202883c000d2000200442ffffffffffffff038322044203862002423088420783843c00062000200342338820067c22024227883c001820002002421f883c0017200020024217883c001620002002420f883c0015200020024207883c00142000200342ffffffffffffff038322054206862004422d88843c000c2000200242338820077c22034224883c001e20002003421c883c001d200020034214883c001c20002003420c883c001b200020034204883c001a2000200242ffffffffffffff038322024201862005423288843c00132000200342ffffffffffffff03832203422c883c001f200020034204862002422f88843c00190bd00702017f147e230041f0016b2203240020012903202104200129031821052001290310210620012903082107200129030021080340200341f0006a200842002007420010d507200341306a20064200200442137e2209420010d507200341e0016a200542137e220a42002005420010d507200341c0006a200a42002006420010d50720034180016a200742002009420010d507200341206a200842002006420010d507200341d0016a200a42002004420010d507200341106a200742002006420010d507200341a0016a200842002005420010d507200341c0016a200942002004420010d507200341d0006a200742002005420010d50720034190016a200842002004420010d507200341b0016a200842002008420010d507200341e0006a200742002007420010d5072003200642002006420010d507200329039001220b20032903507c2206420186220c20032903007c220720032903a001220d20032903107c2208420186220e20032903c0017c22042003290320220f20032903d0017c2205420186221020032903607c22092003290370221120032903307c220a420186221220032903e0017c2213200329038001221420032903407c2215420186221620032903b0017c221742338820034180016a41086a290300200341c0006a41086a2903007c2015201454ad7c4201862015423f8884200341b0016a41086a2903007c2017201654ad7c420d86847c2215423388200341f0006a41086a290300200341306a41086a2903007c200a201154ad7c420186200a423f8884200341e0016a41086a2903007c2013201254ad7c2015201354ad7c420d86847c220a423388200341206a41086a290300200341d0016a41086a2903007c2005200f54ad7c4201862005423f8884200341e0006a41086a2903007c2009201054ad7c200a200954ad7c420d86847c2205423388200341a0016a41086a290300200341106a41086a2903007c2008200d54ad7c4201862008423f8884200341c0016a41086a2903007c2004200e54ad7c2005200454ad7c420d86847c220442338820034190016a41086a290300200341d0006a41086a2903007c2006200b54ad7c4201862006423f8884200341086a2903007c2007200c54ad7c2004200754ad7c420d868442137e201742ffffffffffffff03837c220642ffffffffffffff038321082006423388201542ffffffffffffff03837c2107200442ffffffffffffff03832104200542ffffffffffffff03832105200a42ffffffffffffff038321062002417f6a22020d000b2000200437032020002005370318200020063703102000200737030820002008370300200341f0016a24000b85d20103017f2c7e037f230041d0c1006b22032400200341a8c1006a20024101106b200341b0386a20032903a8412204420020022903082205420010d507200341c0396a20032903c841220642002002290310220742137e2208420010d507200341803a6a20032903c041220942002002290318220a42137e220b420010d507200341c03a6a20032903b841220c42002002290320220d42137e220e420010d507200341f0386a20032903b041220f420020022903002210420010d507200341a0386a201042002004420010d507200341b0396a20064200200542137e2211420010d507200341f0396a200942002008420010d507200341b03a6a200c4200200b420010d507200341f03a6a200f4200200e420010d507200341c0386a200442002007420010d507200341d0396a20064200200b420010d507200341903a6a20094200200e420010d50720034180396a200c42002010420010d507200341803b6a200f42002005420010d507200341d0386a20044200200a420010d507200341e0396a20064200200e420010d50720034190396a200942002010420010d507200341d03a6a200c42002005420010d507200341903b6a200f42002007420010d507200341e0386a20044200200d420010d507200341a0396a200642002010420010d507200341a03a6a200942002005420010d507200341e03a6a200c42002007420010d507200341a03b6a200f4200200a420010d507200320032903d039221220032903c0387c220420032903903a7c22062003290380397c220920032903803b7c220c20032903c039221320032903b0387c220f20032903803a7c221420032903c03a7c221520032903f0387c221620032903b039221720032903a0387c221820032903f0397c221920032903b03a7c221a20032903f03a7c221b423388200341b0396a41086a290300200341a0386a41086a2903007c2018201754ad7c200341f0396a41086a2903007c2019201854ad7c200341b03a6a41086a2903007c201a201954ad7c200341f03a6a41086a2903007c201b201a54ad7c420d86847c2218423388200341c0396a41086a290300200341b0386a41086a2903007c200f201354ad7c200341803a6a41086a2903007c2014200f54ad7c200341c03a6a41086a2903007c2015201454ad7c200341f0386a41086a2903007c2016201554ad7c2018201654ad7c420d86847c220f42ffffffffffffff0383221c3703c03b200320032903e039221a20032903d0387c22142003290390397c221520032903d03a7c221620032903903b7c2219200f423388200341d0396a41086a290300200341c0386a41086a2903007c2004201254ad7c200341903a6a41086a2903007c2006200454ad7c20034180396a41086a2903007c2009200654ad7c200341803b6a41086a2903007c200c200954ad7c200f200c54ad7c420d86847c220442ffffffffffffff0383221d3703c83b200320032903a039221220032903e0387c220620032903a03a7c220920032903e03a7c220c20032903a03b7c220f2004423388200341e0396a41086a290300200341d0386a41086a2903007c2014201a54ad7c20034190396a41086a2903007c2015201454ad7c200341d03a6a41086a2903007c2016201554ad7c200341903b6a41086a2903007c2019201654ad7c2004201954ad7c420d86847c220442ffffffffffffff0383221e3703d03b20032004423388200341a0396a41086a290300200341e0386a41086a2903007c2006201254ad7c200341a03a6a41086a2903007c2009200654ad7c200341e03a6a41086a2903007c200c200954ad7c200341a03b6a41086a2903007c200f200c54ad7c2004200f54ad7c420d868442137e201b42ffffffffffffff03837c220442ffffffffffffff038322123703b03b20032004423388201842ffffffffffffff03837c22133703b83b200341a8c1006a200341b03b6a4101106b200341a0356a20032903a841220442002005420010d507200341f0356a20032903c841220642002008420010d507200341c0366a20032903c04122094200200b420010d50720034190376a20032903b841220c4200200e420010d507200341e0376a20032903b041220f42002010420010d50720034190356a200442002010420010d507200341e0356a200642002011420010d507200341b0366a200942002008420010d50720034180376a200c4200200b420010d507200341d0376a200f4200200e420010d507200341b0356a200442002007420010d50720034180366a20064200200b420010d507200341d0366a20094200200e420010d507200341a0376a200c42002010420010d507200341f0376a200f42002005420010d507200341c0356a20044200200a420010d50720034190366a20064200200e420010d507200341e0366a200942002010420010d507200341b0376a200c42002005420010d50720034180386a200f42002007420010d507200341d0356a20044200200d420010d507200341a0366a200642002010420010d507200341f0366a200942002005420010d507200341c0376a200c42002007420010d50720034190386a200f4200200a420010d507200341e0306a200329038036221a20032903b0357c220b20032903d0367c220420032903a0377c220620032903f0377c220920032903f035221920032903a0357c220e20032903c0367c220c2003290390377c220f20032903e0377c220820032903e035221b2003290390357c221420032903b0367c22152003290380377c221620032903d0377c2218423388200341e0356a41086a29030020034190356a41086a2903007c2014201b54ad7c200341b0366a41086a2903007c2015201454ad7c20034180376a41086a2903007c2016201554ad7c200341d0376a41086a2903007c2018201654ad7c420d86847c2215423388200341f0356a41086a290300200341a0356a41086a2903007c200e201954ad7c200341c0366a41086a2903007c200c200e54ad7c20034190376a41086a2903007c200f200c54ad7c200341e0376a41086a2903007c2008200f54ad7c2015200854ad7c420d86847c220c42ffffffffffffff0383220842137e221742002001290320220e420010d50720034190316a200329039036221f20032903c0357c220f20032903e0367c221420032903b0377c22162003290380387c2219200c42338820034180366a41086a290300200341b0356a41086a2903007c200b201a54ad7c200341d0366a41086a2903007c2004200b54ad7c200341a0376a41086a2903007c2006200454ad7c200341f0376a41086a2903007c2009200654ad7c200c200954ad7c420d86847c220442ffffffffffffff0383221a42137e221b42002001290318220b420010d507200341d0316a20032903a036222020032903d0357c220620032903f0367c220920032903c0377c220c2003290390387c2211200442338820034190366a41086a290300200341c0356a41086a2903007c200f201f54ad7c200341e0366a41086a2903007c2014200f54ad7c200341b0376a41086a2903007c2016201454ad7c20034180386a41086a2903007c2019201654ad7c2004201954ad7c420d86847c220f42ffffffffffffff0383221642137e2214420020012903102204420010d507200341f02f6a200f423388200341a0366a41086a290300200341d0356a41086a2903007c2006202054ad7c200341f0366a41086a2903007c2009200654ad7c200341c0376a41086a2903007c200c200954ad7c20034190386a41086a2903007c2011200c54ad7c200f201154ad7c420d868442137e201842ffffffffffffff03837c220942ffffffffffffff0383220c420020012903082206420010d507200341c0306a2009423388201542ffffffffffffff03837c220f420020012903002209420010d507200341f0306a20174200200b420010d507200341a0316a201b42002004420010d507200341e0316a201442002006420010d50720034180306a200c42002009420010d507200341d0306a200f42137e4200200e420010d507200341c0346a200842002009420010d50720034180316a201b4200200e420010d507200341c0316a20144200200b420010d507200341e02f6a200c42002004420010d507200341b0306a200f42002006420010d50720034180326a200842002006420010d507200341b0346a201a42002009420010d507200341b0316a20144200200e420010d507200341d02f6a200c4200200b420010d507200341a0306a200f42002004420010d507200341d0326a200842002004420010d507200341f0316a201a42002006420010d507200341a0346a201642002009420010d507200341c02f6a200c4200200e420010d50720034190306a200f4200200b420010d5072003200329038031221f20032903c0347c220f20032903c0317c220820032903e02f7c221420032903b0307c2215200329039031222020032903e0307c220c20032903d0317c221620032903f02f7c221820032903c0307c221920032903a031222120032903f0307c221a20032903e0317c221b2003290380307c221120032903d0307c2217423388200341a0316a41086a290300200341f0306a41086a2903007c201a202154ad7c200341e0316a41086a2903007c201b201a54ad7c20034180306a41086a2903007c2011201b54ad7c200341d0306a41086a2903007c2017201154ad7c420d86847c221a42338820034190316a41086a290300200341e0306a41086a2903007c200c202054ad7c200341d0316a41086a2903007c2016200c54ad7c200341f02f6a41086a2903007c2018201654ad7c200341c0306a41086a2903007c2019201854ad7c201a201954ad7c420d86847c221642ffffffffffffff0383220c3703e83b200320032903b03422202003290380327c221820032903b0317c221920032903d02f7c221b20032903a0307c2211201642338820034180316a41086a290300200341c0346a41086a2903007c200f201f54ad7c200341c0316a41086a2903007c2008200f54ad7c200341e02f6a41086a2903007c2014200854ad7c200341b0306a41086a2903007c2015201454ad7c2016201554ad7c420d86847c220842ffffffffffffff0383220f3703f03b200320032903f031222120032903d0327c221420032903a0347c221520032903c02f7c22162003290390307c221f2008423388200341b0346a41086a29030020034180326a41086a2903007c2018202054ad7c200341b0316a41086a2903007c2019201854ad7c200341d02f6a41086a2903007c201b201954ad7c200341a0306a41086a2903007c2011201b54ad7c2008201154ad7c420d86847c221842ffffffffffffff038322083703f83b20032018423388200341f0316a41086a290300200341d0326a41086a2903007c2014202154ad7c200341a0346a41086a2903007c2015201454ad7c200341c02f6a41086a2903007c2016201554ad7c20034190306a41086a2903007c201f201654ad7c2018201f54ad7c420d868442137e201742ffffffffffffff03837c221542ffffffffffffff038322143703d83b20032015423388201a42ffffffffffffff03837c22153703e03b200341803c6a200341d83b6a4101106b200341a8c1006a200341803c6a4101106b200341a83c6a200341a8c1006a4101106b200341f02c6a2014420020032903b03c2216420010d507200341802d6a2008420020032903b83c221942137e2217420010d507200341e02d6a200f420020032903c03c221b42137e2211420010d507200341c02e6a200c420020032903c83c221f42137e221a420010d507200341a02f6a2015420020032903a83c2218420010d507200341b02f6a201842002014420010d507200341b02c6a20084200201642137e420010d507200341902d6a200f42002017420010d507200341f02d6a200c42002011420010d507200341d02e6a20154200201a420010d507200341c02d6a201442002019420010d507200341d02d6a200842002011420010d507200341b02e6a200f4200201a420010d507200341902f6a200c42002018420010d507200341e02c6a201542002016420010d507200341902e6a20144200201b420010d507200341a02e6a20084200201a420010d507200341802f6a200f42002018420010d507200341d02c6a200c42002016420010d507200341b02d6a201542002019420010d507200341e02e6a20144200201f420010d507200341f02e6a200842002018420010d507200341c02c6a200f42002016420010d507200341a02d6a200c42002019420010d507200341802e6a20154200201b420010d507200341c02a6a20032903d02d222220032903c02d7c221620032903b02e7c221820032903902f7c221a20032903e02c7c221b20032903802d222320032903f02c7c221920032903e02d7c221120032903c02e7c221720032903a02f7c221f20032903b02c222420032903b02f7c222020032903902d7c222120032903f02d7c222520032903d02e7c2226423388200341b02c6a41086a290300200341b02f6a41086a2903007c2020202454ad7c200341902d6a41086a2903007c2021202054ad7c200341f02d6a41086a2903007c2025202154ad7c200341d02e6a41086a2903007c2026202554ad7c420d86847c2221423388200341802d6a41086a290300200341f02c6a41086a2903007c2019202354ad7c200341e02d6a41086a2903007c2011201954ad7c200341c02e6a41086a2903007c2017201154ad7c200341a02f6a41086a2903007c201f201754ad7c2021201f54ad7c420d86847c221742ffffffffffffff0383221942137e2227420020032903a03c2211420010d507200341f02a6a20032903a02e222820032903902e7c221f20032903802f7c222020032903d02c7c222520032903b02d7c22232017423388200341d02d6a41086a290300200341c02d6a41086a2903007c2016202254ad7c200341b02e6a41086a2903007c2018201654ad7c200341902f6a41086a2903007c201a201854ad7c200341e02c6a41086a2903007c201b201a54ad7c2017201b54ad7c420d86847c221642ffffffffffffff0383221a42137e2222420020032903983c2217420010d507200341b02b6a20032903f02e222920032903e02e7c221820032903c02c7c222420032903a02d7c222a20032903802e7c222b2016423388200341a02e6a41086a290300200341902e6a41086a2903007c201f202854ad7c200341802f6a41086a2903007c2020201f54ad7c200341d02c6a41086a2903007c2025202054ad7c200341b02d6a41086a2903007c2023202554ad7c2016202354ad7c420d86847c221642ffffffffffffff0383221b42137e2225420020032903903c221f420010d507200341d0296a2016423388200341f02e6a41086a290300200341e02e6a41086a2903007c2018202954ad7c200341c02c6a41086a2903007c2024201854ad7c200341a02d6a41086a2903007c202a202454ad7c200341802e6a41086a2903007c202b202a54ad7c2016202b54ad7c420d868442137e202642ffffffffffffff03837c221842ffffffffffffff03832216420020032903883c2220420010d507200341a02a6a2018423388202142ffffffffffffff03837c2218420020032903803c2221420010d507200341d02a6a202742002017420010d507200341802b6a20224200201f420010d507200341c02b6a202542002020420010d507200341e0296a201642002021420010d507200341b02a6a201842137e42002011420010d507200341d02b6a201942002021420010d507200341e02a6a202242002011420010d507200341a02b6a202542002017420010d507200341c0296a20164200201f420010d507200341902a6a201842002020420010d507200341e02b6a201942002020420010d507200341802c6a201a42002021420010d507200341902b6a202542002011420010d507200341b0296a201642002017420010d507200341802a6a20184200201f420010d507200341f02b6a20194200201f420010d507200341902c6a201a42002020420010d507200341a02c6a201b42002021420010d507200341a0296a201642002011420010d507200341f0296a201842002017420010d507200320032903e02a222720032903d02b7c221120032903a02b7c221720032903c0297c221f20032903902a7c222020032903f02a222820032903c02a7c222120032903b02b7c222520032903d0297c222620032903a02a7c222320032903802b222920032903d02a7c222220032903c02b7c222420032903e0297c222a20032903b02a7c222b423388200341802b6a41086a290300200341d02a6a41086a2903007c2022202954ad7c200341c02b6a41086a2903007c2024202254ad7c200341e0296a41086a2903007c202a202454ad7c200341b02a6a41086a2903007c202b202a54ad7c420d86847c2222423388200341f02a6a41086a290300200341c02a6a41086a2903007c2021202854ad7c200341b02b6a41086a2903007c2025202154ad7c200341d0296a41086a2903007c2026202554ad7c200341a02a6a41086a2903007c2023202654ad7c2022202354ad7c420d86847c222142ffffffffffffff03833703e03c200320032903802c222a20032903e02b7c222520032903902b7c222620032903b0297c222320032903802a7c22242021423388200341e02a6a41086a290300200341d02b6a41086a2903007c2011202754ad7c200341a02b6a41086a2903007c2017201154ad7c200341c0296a41086a2903007c201f201754ad7c200341902a6a41086a2903007c2020201f54ad7c2021202054ad7c420d86847c221142ffffffffffffff03833703e83c200320032903902c222720032903f02b7c221720032903a02c7c221f20032903a0297c222020032903f0297c22212011423388200341802c6a41086a290300200341e02b6a41086a2903007c2025202a54ad7c200341902b6a41086a2903007c2026202554ad7c200341b0296a41086a2903007c2023202654ad7c200341802a6a41086a2903007c2024202354ad7c2011202454ad7c420d86847c221142ffffffffffffff03833703f03c20032011423388200341902c6a41086a290300200341f02b6a41086a2903007c2017202754ad7c200341a02c6a41086a2903007c201f201754ad7c200341a0296a41086a2903007c2020201f54ad7c200341f0296a41086a2903007c2021202054ad7c2011202154ad7c420d868442137e202b42ffffffffffffff03837c221142ffffffffffffff03833703d03c20032011423388202242ffffffffffffff03837c3703d83c200341f83c6a200341d03c6a4101106b200341e0266a201b420020032903883d221f42137e2226420010d507200341c0276a20032903903d222142137e22254200201a420010d507200341a0286a20032903983d222342137e222042002019420010d507200341d0266a2016420020032903803d2211420010d50720034180296a2018420020032903f83c2217420010d50720034190266a201b4200201142137e420010d507200341f0266a20264200201a420010d507200341d0276a202542002019420010d50720034190296a201642002017420010d507200341b0286a201842002020420010d507200341b0276a20254200201b420010d50720034190286a20204200201a420010d507200341f0286a201742002019420010d507200341a0276a20164200201f420010d507200341c0266a201842002011420010d507200341b0266a201142002019420010d50720034180286a20204200201b420010d507200341e0286a20174200201a420010d507200341f0276a201642002021420010d50720034190276a20184200201f420010d507200341a0266a20114200201a420010d50720034180276a201f42002019420010d507200341d0286a20174200201b420010d507200341c0286a201642002023420010d507200341e0276a201842002021420010d5072003200329039028222220032903b0277c221620032903f0287c221820032903a0277c221a20032903c0267c221b20032903c027222320032903e0267c221920032903a0287c221120032903d0267c22172003290380297c221f20032903f02622242003290390267c222020032903d0277c22212003290390297c222520032903b0287c2226423388200341f0266a41086a29030020034190266a41086a2903007c2020202454ad7c200341d0276a41086a2903007c2021202054ad7c20034190296a41086a2903007c2025202154ad7c200341b0286a41086a2903007c2026202554ad7c420d86847c2221423388200341c0276a41086a290300200341e0266a41086a2903007c2019202354ad7c200341a0286a41086a2903007c2011201954ad7c200341d0266a41086a2903007c2017201154ad7c20034180296a41086a2903007c201f201754ad7c2021201f54ad7c420d86847c221142ffffffffffffff038322193703b03d2003200329038028222420032903b0267c221720032903e0287c221f20032903f0277c22252003290390277c2223201142338820034190286a41086a290300200341b0276a41086a2903007c2016202254ad7c200341f0286a41086a2903007c2018201654ad7c200341a0276a41086a2903007c201a201854ad7c200341c0266a41086a2903007c201b201a54ad7c2011201b54ad7c420d86847c221642ffffffffffffff038322203703b83d2003200329038027222220032903a0267c221820032903d0287c221a20032903c0287c221b20032903e0277c2211201642338820034180286a41086a290300200341b0266a41086a2903007c2017202454ad7c200341e0286a41086a2903007c201f201754ad7c200341f0276a41086a2903007c2025201f54ad7c20034190276a41086a2903007c2023202554ad7c2016202354ad7c420d86847c221642ffffffffffffff038322253703c03d2003201642338820034180276a41086a290300200341a0266a41086a2903007c2018202254ad7c200341d0286a41086a2903007c201a201854ad7c200341c0286a41086a2903007c201b201a54ad7c200341e0276a41086a2903007c2011201b54ad7c2016201154ad7c420d868442137e202642ffffffffffffff03837c221842ffffffffffffff038322163703a03d20032018423388202142ffffffffffffff03837c22183703a83d200341c83d6a200341a03d6a4105106b200341b0246a201942137e2223420020032903e83d221a420010d507200341f0246a202042137e2226420020032903e03d221b420010d507200341b0256a202542137e2221420020032903d83d2211420010d507200341b0236a2016420020032903d03d2217420010d50720034180246a2018420020032903c83d221f420010d50720034180256a20234200201b420010d507200341c0256a202642002011420010d50720034180266a202142002017420010d507200341c0236a20164200201f420010d507200341c0246a201842137e4200201a420010d507200341f0236a20194200201f420010d507200341a0246a20264200201a420010d507200341e0246a20214200201b420010d507200341a0236a201642002011420010d507200341f0256a201842002017420010d507200341e0256a201942002017420010d507200341e0236a20204200201f420010d50720034190246a20214200201a420010d50720034190236a20164200201b420010d507200341a0256a201842002011420010d50720034190256a201942002011420010d507200341d0256a202042002017420010d507200341d0236a20254200201f420010d50720034180236a20164200201a420010d507200341d0246a20184200201b420010d507200320032903a024222320032903f0237c221620032903e0247c221820032903a0237c221a20032903f0257c221b20032903f024222220032903b0247c221920032903b0257c221120032903b0237c22172003290380247c221f20032903c02522242003290380257c22202003290380267c222120032903c0237c222520032903c0247c2226423388200341c0256a41086a29030020034180256a41086a2903007c2020202454ad7c20034180266a41086a2903007c2021202054ad7c200341c0236a41086a2903007c2025202154ad7c200341c0246a41086a2903007c2026202554ad7c420d86847c2220423388200341f0246a41086a290300200341b0246a41086a2903007c2019202254ad7c200341b0256a41086a2903007c2011201954ad7c200341b0236a41086a2903007c2017201154ad7c20034180246a41086a2903007c201f201754ad7c2020201f54ad7c420d86847c221142ffffffffffffff038322193703803e200320032903e023222220032903e0257c22172003290390247c221f2003290390237c222120032903a0257c22252011423388200341a0246a41086a290300200341f0236a41086a2903007c2016202354ad7c200341e0246a41086a2903007c2018201654ad7c200341a0236a41086a2903007c201a201854ad7c200341f0256a41086a2903007c201b201a54ad7c2011201b54ad7c420d86847c221642ffffffffffffff0383221b3703883e200320032903d025222a2003290390257c221820032903d0237c221a2003290380237c221120032903d0247c22232016423388200341e0236a41086a290300200341e0256a41086a2903007c2017202254ad7c20034190246a41086a2903007c201f201754ad7c20034190236a41086a2903007c2021201f54ad7c200341a0256a41086a2903007c2025202154ad7c2016202554ad7c420d86847c221642ffffffffffffff038322243703903e20032016423388200341d0256a41086a29030020034190256a41086a2903007c2018202a54ad7c200341d0236a41086a2903007c201a201854ad7c20034180236a41086a2903007c2011201a54ad7c200341d0246a41086a2903007c2023201154ad7c2016202354ad7c420d868442137e202642ffffffffffffff03837c221842ffffffffffffff038322163703f03d20032018423388202042ffffffffffffff03837c22183703f83d200341983e6a200341f03d6a410a106b200341f0206a201942137e222a420020032903b83e2217420010d507200341c0216a201b42137e2211420020032903b03e221f420010d50720034190226a202442137e221a420020032903a83e2220420010d507200341e0226a2016420020032903a03e2221420010d507200341a0206a2018420020032903983e2225420010d507200341d0216a202a4200201f420010d507200341a0226a201142002020420010d507200341f0226a201a42002021420010d507200341b0206a201642002025420010d50720034180216a201842137e222c42002017420010d50720034190206a201942002025420010d507200341e0206a201142002017420010d507200341b0216a201a4200201f420010d50720034180226a201642002020420010d507200341d0226a201842002021420010d507200341c0226a201942002021420010d50720034180206a201b42002025420010d507200341d0206a201a42002017420010d507200341a0216a20164200201f420010d507200341f0216a201842002020420010d507200341e0216a201942002020420010d507200341b0226a201b42002021420010d507200341f01f6a202442002025420010d507200341c0206a201642002017420010d50720034190216a20184200201f420010d507200320032903e020222d2003290390207c221720032903b0217c221f2003290380227c222120032903d0227c222520032903c021222e20032903f0207c22202003290390227c222620032903e0227c222320032903a0207c222220032903a022222f20032903d0217c222b20032903f0227c222720032903b0207c22282003290380217c2229423388200341a0226a41086a290300200341d0216a41086a2903007c202b202f54ad7c200341f0226a41086a2903007c2027202b54ad7c200341b0206a41086a2903007c2028202754ad7c20034180216a41086a2903007c2029202854ad7c420d86847c2227423388200341c0216a41086a290300200341f0206a41086a2903007c2020202e54ad7c20034190226a41086a2903007c2026202054ad7c200341e0226a41086a2903007c2023202654ad7c200341a0206a41086a2903007c2022202354ad7c2027202254ad7c420d86847c222642ffffffffffffff038322203703d03e2003200329038020222f20032903c0227c222320032903d0207c222220032903a0217c222820032903f0217c222e2026423388200341e0206a41086a29030020034190206a41086a2903007c2017202d54ad7c200341b0216a41086a2903007c201f201754ad7c20034180226a41086a2903007c2021201f54ad7c200341d0226a41086a2903007c2025202154ad7c2026202554ad7c420d86847c221742ffffffffffffff0383222b3703d83e200320032903b022222d20032903e0217c221f20032903f01f7c222120032903c0207c22252003290390217c2226201742338820034180206a41086a290300200341c0226a41086a2903007c2023202f54ad7c200341d0206a41086a2903007c2022202354ad7c200341a0216a41086a2903007c2028202254ad7c200341f0216a41086a2903007c202e202854ad7c2017202e54ad7c420d86847c221742ffffffffffffff038322283703e03e20032017423388200341b0226a41086a290300200341e0216a41086a2903007c201f202d54ad7c200341f01f6a41086a2903007c2021201f54ad7c200341c0206a41086a2903007c2025202154ad7c20034190216a41086a2903007c2026202554ad7c2017202654ad7c420d868442137e202942ffffffffffffff03837c221f42ffffffffffffff038322173703c03e2003201f423388202742ffffffffffffff03837c221f3703c83e200341e83e6a200341c03e6a4114106b200341e01d6a202042137e222e420020032903883f2221420010d507200341b01e6a202b42137e2229420020032903803f2225420010d507200341801f6a202842137e2227420020032903f83e2226420010d507200341d01f6a2017420020032903f03e2223420010d507200341901d6a201f420020032903e83e2222420010d507200341c01e6a202e42002025420010d507200341901f6a202942002026420010d507200341e01f6a202742002023420010d507200341a01d6a201742002022420010d507200341f01d6a201f42137e42002021420010d507200341801d6a202042002022420010d507200341d01d6a202942002021420010d507200341a01e6a202742002025420010d507200341f01e6a201742002026420010d507200341c01f6a201f42002023420010d507200341b01f6a202042002023420010d507200341f01c6a202b42002022420010d507200341c01d6a202742002021420010d507200341901e6a201742002025420010d507200341e01e6a201f42002026420010d507200341d01e6a202042002026420010d507200341a01f6a202b42002023420010d507200341e01c6a202842002022420010d507200341b01d6a201742002021420010d507200341801e6a201f42002025420010d507200320032903d01d222e20032903801d7c221720032903a01e7c221f20032903f01e7c222020032903c01f7c222120032903b01e222d20032903e01d7c222520032903801f7c222620032903d01f7c222320032903901d7c222220032903901f222f20032903c01e7c222b20032903e01f7c222720032903a01d7c222820032903f01d7c2229423388200341901f6a41086a290300200341c01e6a41086a2903007c202b202f54ad7c200341e01f6a41086a2903007c2027202b54ad7c200341a01d6a41086a2903007c2028202754ad7c200341f01d6a41086a2903007c2029202854ad7c420d86847c222b423388200341b01e6a41086a290300200341e01d6a41086a2903007c2025202d54ad7c200341801f6a41086a2903007c2026202554ad7c200341d01f6a41086a2903007c2023202654ad7c200341901d6a41086a2903007c2022202354ad7c202b202254ad7c420d86847c222542ffffffffffffff03833703a03f200320032903f01c222820032903b01f7c222620032903c01d7c222320032903901e7c222220032903e01e7c22272025423388200341d01d6a41086a290300200341801d6a41086a2903007c2017202e54ad7c200341a01e6a41086a2903007c201f201754ad7c200341f01e6a41086a2903007c2020201f54ad7c200341c01f6a41086a2903007c2021202054ad7c2025202154ad7c420d86847c221742ffffffffffffff03833703a83f200320032903a01f222e20032903d01e7c221f20032903e01c7c222020032903b01d7c222120032903801e7c22252017423388200341f01c6a41086a290300200341b01f6a41086a2903007c2026202854ad7c200341c01d6a41086a2903007c2023202654ad7c200341901e6a41086a2903007c2022202354ad7c200341e01e6a41086a2903007c2027202254ad7c2017202754ad7c420d86847c221742ffffffffffffff03833703b03f20032017423388200341a01f6a41086a290300200341d01e6a41086a2903007c201f202e54ad7c200341e01c6a41086a2903007c2020201f54ad7c200341b01d6a41086a2903007c2021202054ad7c200341801e6a41086a2903007c2025202154ad7c2017202554ad7c420d868442137e202942ffffffffffffff03837c221742ffffffffffffff03833703903f20032017423388202b42ffffffffffffff03837c3703983f200341b83f6a200341903f6a410a106b200341801a6a20032903b83f221742002018420010d507200341d01a6a20032903d83f221f4200202a420010d507200341a01b6a20032903d03f222042002011420010d507200341f01b6a20032903c83f22214200201a420010d507200341c01c6a20032903c03f222542002016420010d507200341901a6a201742002016420010d507200341e01a6a201f4200202c420010d507200341b01b6a20204200202a420010d507200341801c6a202142002011420010d507200341d01c6a20254200201a420010d507200341f0196a201742002019420010d507200341c01a6a201f42002011420010d507200341901b6a20204200201a420010d507200341e01b6a202142002016420010d507200341b01c6a202542002018420010d507200341e0196a20174200201b420010d507200341b01a6a201f4200201a420010d507200341801b6a202042002016420010d507200341d01b6a202142002018420010d507200341a01c6a202542002019420010d507200341d0196a201742002024420010d507200341a01a6a201f42002016420010d507200341f01a6a202042002018420010d507200341c01b6a202142002019420010d507200341901c6a20254200201b420010d507200320032903c01a222320032903f0197c221620032903901b7c221820032903e01b7c221a20032903b01c7c221b20032903d01a222220032903801a7c221920032903a01b7c221120032903f01b7c221720032903c01c7c221f20032903e01a222420032903901a7c222020032903b01b7c222120032903801c7c222520032903d01c7c2226423388200341e01a6a41086a290300200341901a6a41086a2903007c2020202454ad7c200341b01b6a41086a2903007c2021202054ad7c200341801c6a41086a2903007c2025202154ad7c200341d01c6a41086a2903007c2026202554ad7c420d86847c2220423388200341d01a6a41086a290300200341801a6a41086a2903007c2019202254ad7c200341a01b6a41086a2903007c2011201954ad7c200341f01b6a41086a2903007c2017201154ad7c200341c01c6a41086a2903007c201f201754ad7c2020201f54ad7c420d86847c221142ffffffffffffff038322193703f03f200320032903b01a222220032903e0197c221720032903801b7c221f20032903d01b7c222120032903a01c7c22252011423388200341c01a6a41086a290300200341f0196a41086a2903007c2016202354ad7c200341901b6a41086a2903007c2018201654ad7c200341e01b6a41086a2903007c201a201854ad7c200341b01c6a41086a2903007c201b201a54ad7c2011201b54ad7c420d86847c221642ffffffffffffff0383221b3703f83f200320032903a01a222a20032903d0197c221820032903f01a7c221a20032903c01b7c221120032903901c7c22232016423388200341b01a6a41086a290300200341e0196a41086a2903007c2017202254ad7c200341801b6a41086a2903007c201f201754ad7c200341d01b6a41086a2903007c2021201f54ad7c200341a01c6a41086a2903007c2025202154ad7c2016202554ad7c420d86847c221642ffffffffffffff038322243703804020032016423388200341a01a6a41086a290300200341d0196a41086a2903007c2018202a54ad7c200341f01a6a41086a2903007c201a201854ad7c200341c01b6a41086a2903007c2011201a54ad7c200341901c6a41086a2903007c2023201154ad7c2016202354ad7c420d868442137e202642ffffffffffffff03837c221842ffffffffffffff038322163703e03f20032018423388202042ffffffffffffff03837c22183703e83f20034188c0006a200341e03f6a4132106b200341c0176a201942137e222a420020032903a8402217420010d50720034190186a201b42137e2211420020032903a040221f420010d507200341e0186a202442137e221a42002003290398402220420010d507200341b0196a201642002003290390402221420010d507200341f0166a201842002003290388402225420010d507200341a0186a202a4200201f420010d507200341f0186a201142002020420010d507200341c0196a201a42002021420010d50720034180176a201642002025420010d507200341d0176a201842137e222c42002017420010d507200341e0166a201942002025420010d507200341b0176a201142002017420010d50720034180186a201a4200201f420010d507200341d0186a201642002020420010d507200341a0196a201842002021420010d50720034190196a202142002019420010d507200341d0166a201b42002025420010d507200341a0176a201a42002017420010d507200341f0176a20164200201f420010d507200341c0186a201842002020420010d507200341b0186a201942002020420010d50720034180196a201b42002021420010d507200341c0166a202442002025420010d50720034190176a201642002017420010d507200341e0176a20184200201f420010d507200320032903b017222d20032903e0167c22172003290380187c221f20032903d0187c222120032903a0197c2225200329039018222e20032903c0177c222020032903e0187c222620032903b0197c222320032903f0167c222220032903f018222f20032903a0187c222b20032903c0197c22272003290380177c222820032903d0177c2229423388200341f0186a41086a290300200341a0186a41086a2903007c202b202f54ad7c200341c0196a41086a2903007c2027202b54ad7c20034180176a41086a2903007c2028202754ad7c200341d0176a41086a2903007c2029202854ad7c420d86847c222742338820034190186a41086a290300200341c0176a41086a2903007c2020202e54ad7c200341e0186a41086a2903007c2026202054ad7c200341b0196a41086a2903007c2023202654ad7c200341f0166a41086a2903007c2022202354ad7c2027202254ad7c420d86847c222642ffffffffffffff038322203703c040200320032903d016222f2003290390197c222320032903a0177c222220032903f0177c222820032903c0187c222e2026423388200341b0176a41086a290300200341e0166a41086a2903007c2017202d54ad7c20034180186a41086a2903007c201f201754ad7c200341d0186a41086a2903007c2021201f54ad7c200341a0196a41086a2903007c2025202154ad7c2026202554ad7c420d86847c221742ffffffffffffff0383222b3703c8402003200329038019222d20032903b0187c221f20032903c0167c22212003290390177c222520032903e0177c22262017423388200341d0166a41086a29030020034190196a41086a2903007c2023202f54ad7c200341a0176a41086a2903007c2022202354ad7c200341f0176a41086a2903007c2028202254ad7c200341c0186a41086a2903007c202e202854ad7c2017202e54ad7c420d86847c221742ffffffffffffff038322283703d0402003201742338820034180196a41086a290300200341b0186a41086a2903007c201f202d54ad7c200341c0166a41086a2903007c2021201f54ad7c20034190176a41086a2903007c2025202154ad7c200341e0176a41086a2903007c2026202554ad7c2017202654ad7c420d868442137e202942ffffffffffffff03837c221f42ffffffffffffff038322173703b0402003201f423388202742ffffffffffffff03837c221f3703b840200341d8c0006a200341b0c0006a41e400106b200341b0146a202042137e222e420020032903f8402221420010d50720034180156a202b42137e2229420020032903f0402225420010d507200341d0156a202842137e2227420020032903e8402226420010d507200341a0166a2017420020032903e0402223420010d507200341e0136a201f420020032903d8402222420010d50720034190156a202e42002025420010d507200341e0156a202942002026420010d507200341b0166a202742002023420010d507200341f0136a201742002022420010d507200341c0146a201f42137e42002021420010d507200341d0136a202042002022420010d507200341a0146a202942002021420010d507200341f0146a202742002025420010d507200341c0156a201742002026420010d50720034190166a201f42002023420010d50720034180166a202042002023420010d507200341c0136a202b42002022420010d50720034190146a202742002021420010d507200341e0146a201742002025420010d507200341b0156a201f42002026420010d507200341a0156a202042002026420010d507200341f0156a202b42002023420010d507200341b0136a202842002022420010d50720034180146a201742002021420010d507200341d0146a201f42002025420010d507200320032903a014222e20032903d0137c221720032903f0147c221f20032903c0157c22202003290390167c2221200329038015222d20032903b0147c222520032903d0157c222620032903a0167c222320032903e0137c222220032903e015222f2003290390157c222b20032903b0167c222720032903f0137c222820032903c0147c2229423388200341e0156a41086a29030020034190156a41086a2903007c202b202f54ad7c200341b0166a41086a2903007c2027202b54ad7c200341f0136a41086a2903007c2028202754ad7c200341c0146a41086a2903007c2029202854ad7c420d86847c222b42338820034180156a41086a290300200341b0146a41086a2903007c2025202d54ad7c200341d0156a41086a2903007c2026202554ad7c200341a0166a41086a2903007c2023202654ad7c200341e0136a41086a2903007c2022202354ad7c202b202254ad7c420d86847c222542ffffffffffffff038337039041200320032903c01322282003290380167c22262003290390147c222320032903e0147c222220032903b0157c22272025423388200341a0146a41086a290300200341d0136a41086a2903007c2017202e54ad7c200341f0146a41086a2903007c201f201754ad7c200341c0156a41086a2903007c2020201f54ad7c20034190166a41086a2903007c2021202054ad7c2025202154ad7c420d86847c221742ffffffffffffff038337039841200320032903f015222e20032903a0157c221f20032903b0137c22202003290380147c222120032903d0147c22252017423388200341c0136a41086a29030020034180166a41086a2903007c2026202854ad7c20034190146a41086a2903007c2023202654ad7c200341e0146a41086a2903007c2022202354ad7c200341b0156a41086a2903007c2027202254ad7c2017202754ad7c420d86847c221742ffffffffffffff03833703a04120032017423388200341f0156a41086a290300200341a0156a41086a2903007c201f202e54ad7c200341b0136a41086a2903007c2020201f54ad7c20034180146a41086a2903007c2021202054ad7c200341d0146a41086a2903007c2025202154ad7c2017202554ad7c420d868442137e202942ffffffffffffff03837c221742ffffffffffffff03833703804120032017423388202b42ffffffffffffff03837c37038841200341a8c1006a20034180c1006a4132106b200341b0106a20032903a841221742002018420010d50720034180116a20032903c841221f4200202a420010d507200341d0116a20032903c041222042002011420010d507200341a0126a20032903b84122214200201a420010d507200341f0126a20032903b041222542002016420010d507200341a0106a201742002016420010d507200341f0106a201f4200202c420010d507200341c0116a20204200202a420010d50720034190126a202142002011420010d507200341e0126a20254200201a420010d507200341c0106a201742002019420010d50720034190116a201f42002011420010d507200341e0116a20204200201a420010d507200341b0126a202142002016420010d50720034180136a202542002018420010d507200341d0106a20174200201b420010d507200341a0116a201f4200201a420010d507200341f0116a202042002016420010d507200341c0126a202142002018420010d50720034190136a202542002019420010d507200341e0106a201742002024420010d507200341b0116a201f42002016420010d50720034180126a202042002018420010d507200341d0126a202142002019420010d507200341a0136a20254200201b420010d50720034180346a200e4200201c42137e2219420010d507200341c0336a200b4200201d42137e2218420010d50720034180336a20044200201e42137e2216420010d507200341f00c6a200642002012420010d50720034180356a201342002009420010d507200341d0336a200b42002019420010d50720034190336a200442002018420010d507200341800d6a201242002009420010d507200341c0326a200642002016420010d50720034190346a201342137e4200200e420010d507200341f0346a20094200201c420010d507200341f0336a200e42002018420010d507200341b0336a200b42002016420010d507200341e00c6a201242002004420010d507200341b0326a201342002006420010d507200341e0346a20094200201d420010d507200341e0336a20164200200e420010d507200341800c6a20124200200b420010d507200341a0326a20064200201c420010d507200341f0326a201342002004420010d507200341d0346a201e42002009420010d507200341e0326a20044200201c420010d507200341a00b6a20124200200e420010d50720034190326a20064200201d420010d507200341a0336a20134200200b420010d5072003200329039011222120032903c0107c221620032903e0117c221820032903b0127c22192003290380137c221a200329038011222520032903b0107c221b20032903d0117c221220032903a0127c221320032903f0127c221120032903f010222620032903a0107c221720032903c0117c221f2003290390127c221c20032903e0127c2220423388200341f0106a41086a290300200341a0106a41086a2903007c2017202654ad7c200341c0116a41086a2903007c201f201754ad7c20034190126a41086a2903007c201c201f54ad7c200341e0126a41086a2903007c2020201c54ad7c420d86847c221742338820034180116a41086a290300200341b0106a41086a2903007c201b202554ad7c200341d0116a41086a2903007c2012201b54ad7c200341a0126a41086a2903007c2013201254ad7c200341f0126a41086a2903007c2011201354ad7c2017201154ad7c420d86847c221b42ffffffffffffff038337039041200320032903a011221c20032903d0107c221220032903f0117c221320032903c0127c22112003290390137c221f201b42338820034190116a41086a290300200341c0106a41086a2903007c2016202154ad7c200341e0116a41086a2903007c2018201654ad7c200341b0126a41086a2903007c2019201854ad7c20034180136a41086a2903007c201a201954ad7c201b201a54ad7c420d86847c221642ffffffffffffff038337039841200320032903b011222120032903e0107c22182003290380127c221920032903d0127c221a20032903a0137c221b2016423388200341a0116a41086a290300200341d0106a41086a2903007c2012201c54ad7c200341f0116a41086a2903007c2013201254ad7c200341c0126a41086a2903007c2011201354ad7c20034190136a41086a2903007c201f201154ad7c2016201f54ad7c420d86847c221642ffffffffffffff03833703a04120032016423388200341b0116a41086a290300200341e0106a41086a2903007c2018202154ad7c20034180126a41086a2903007c2019201854ad7c200341d0126a41086a2903007c201a201954ad7c200341a0136a41086a2903007c201b201a54ad7c2016201b54ad7c420d868442137e202042ffffffffffffff03837c221642ffffffffffffff03833703804120032016423388201742ffffffffffffff03837c37038841200341a8c1006a20034180c1006a4102106b200341900e6a200c420020032903c841221342137e2219420010d507200341e00e6a200f420020032903c041221b42137e2212420010d507200341b00f6a2008420020032903b841221a42137e2211420010d50720034180106a2014420020032903b0412216420010d507200341a00d6a2015420020032903a8412218420010d507200341f00e6a200c42002012420010d507200341c00f6a200f42002011420010d50720034190106a20084200201642137e420010d507200341900d6a201442002018420010d507200341a00e6a201542002019420010d507200341b00d6a200c42002018420010d507200341800e6a200f42002019420010d507200341d00e6a200842002012420010d507200341a00f6a20144200201a420010d507200341f00f6a201542002016420010d507200341e00f6a200c42002016420010d507200341c00d6a200f42002018420010d507200341f00d6a200842002019420010d507200341c00e6a20144200201b420010d507200341900f6a20154200201a420010d507200341800f6a200c4200201a420010d507200341d00f6a200f42002016420010d507200341d00d6a200842002018420010d507200341e00d6a201442002013420010d507200341b00e6a20154200201b420010d507200341800b6a20032903e032222a20032903d0347c221520032903a00b7c22162003290390327c221820032903a0337c221b20032903e033222320032903e0347c220c20032903800c7c220f20032903a0327c220820032903f0327c221420032903f033222220032903f0347c221920032903b0337c221a20032903e00c7c221220032903b0327c221320032903c033221d2003290380347c22112003290380337c221720032903f00c7c221f2003290380357c221c200329039033222420032903d0337c222020032903800d7c222120032903c0327c22252003290390347c222642338820034190336a41086a290300200341d0336a41086a2903007c2020202454ad7c200341800d6a41086a2903007c2021202054ad7c200341c0326a41086a2903007c2025202154ad7c20034190346a41086a2903007c2026202554ad7c420d86847c2220423388200341c0336a41086a29030020034180346a41086a2903007c2011201d54ad7c20034180336a41086a2903007c2017201154ad7c200341f00c6a41086a2903007c201f201754ad7c20034180356a41086a2903007c201c201f54ad7c2020201c54ad7c420d86847c2211423388200341f0336a41086a290300200341f0346a41086a2903007c2019202254ad7c200341b0336a41086a2903007c201a201954ad7c200341e00c6a41086a2903007c2012201a54ad7c200341b0326a41086a2903007c2013201254ad7c2011201354ad7c420d86847c221a423388200341e0336a41086a290300200341e0346a41086a2903007c200c202354ad7c200341800c6a41086a2903007c200f200c54ad7c200341a0326a41086a2903007c2008200f54ad7c200341f0326a41086a2903007c2014200854ad7c201a201454ad7c420d86847c221242ffffffffffffff0383220c420020032903800e221d20032903b00d7c220820032903d00e7c221420032903a00f7c221320032903f00f7c221720032903e00e222420032903900e7c220f20032903b00f7c22192003290380107c221f20032903a00d7c221c20032903c00f222b20032903f00e7c22212003290390107c222520032903900d7c222320032903a00e7c2222423388200341c00f6a41086a290300200341f00e6a41086a2903007c2021202b54ad7c20034190106a41086a2903007c2025202154ad7c200341900d6a41086a2903007c2023202554ad7c200341a00e6a41086a2903007c2022202354ad7c420d86847c2221423388200341e00e6a41086a290300200341900e6a41086a2903007c200f202454ad7c200341b00f6a41086a2903007c2019200f54ad7c20034180106a41086a2903007c201f201954ad7c200341a00d6a41086a2903007c201c201f54ad7c2021201c54ad7c420d86847c221f42ffffffffffffff0383221942137e222b420010d507200341e00b6a201a42ffffffffffffff0383220f420020032903c00d222720032903e00f7c221a20032903f00d7c221c20032903c00e7c222520032903900f7c2223201f423388200341800e6a41086a290300200341b00d6a41086a2903007c2008201d54ad7c200341d00e6a41086a2903007c2014200854ad7c200341a00f6a41086a2903007c2013201454ad7c200341f00f6a41086a2903007c2017201354ad7c201f201754ad7c420d86847c221442ffffffffffffff0383221342137e2217420010d507200341c00c6a201142ffffffffffffff03832208420020032903d00f221e20032903800f7c221120032903d00d7c221f20032903e00d7c221d20032903b00e7c22242014423388200341c00d6a41086a290300200341e00f6a41086a2903007c201a202754ad7c200341f00d6a41086a2903007c201c201a54ad7c200341c00e6a41086a2903007c2025201c54ad7c200341900f6a41086a2903007c2023202554ad7c2014202354ad7c420d86847c221442ffffffffffffff0383221c42137e221a420010d507200341b00a6a2014423388200341d00f6a41086a290300200341800f6a41086a2903007c2011201e54ad7c200341d00d6a41086a2903007c201f201154ad7c200341e00d6a41086a2903007c201d201f54ad7c200341b00e6a41086a2903007c2024201d54ad7c2014202454ad7c420d868442137e202242ffffffffffffff03837c221142ffffffffffffff0383221442002012423388200341e0326a41086a290300200341d0346a41086a2903007c2015202a54ad7c200341a00b6a41086a2903007c2016201554ad7c20034190326a41086a2903007c2018201654ad7c200341a0336a41086a2903007c201b201854ad7c2012201b54ad7c420d868442137e202642ffffffffffffff03837c2218423388202042ffffffffffffff03837c2215420010d507200341e0096a2011423388202142ffffffffffffff03837c22164200201842ffffffffffffff03832218420010d507200341f00b6a200f4200202b420010d507200341d00c6a200842002017420010d507200341c00a6a201a42002015420010d507200341f0096a201442002018420010d507200341900b6a200c4200201642137e420010d507200341d0096a201942002018420010d507200341f00a6a200c42002017420010d507200341d00b6a200f4200201a420010d507200341b00c6a200842002014420010d507200341a00a6a201642002015420010d507200341900a6a201942002015420010d507200341c0096a201342002018420010d507200341e00a6a200c4200201a420010d507200341c00b6a200f42002014420010d507200341a00c6a200842002016420010d507200341900c6a200842002019420010d507200341800a6a201342002015420010d507200341b0096a201c42002018420010d507200341d00a6a200c42002014420010d507200341b00b6a200f42002016420010d507200320032903f00a221120032903d0097c220c20032903d00b7c220f20032903b00c7c221420032903a00a7c221520032903e00b221720032903800b7c220820032903c00c7c221620032903b00a7c221820032903e0097c221920032903d00c221f20032903f00b7c221a20032903c00a7c221b20032903f0097c221220032903900b7c2213423388200341d00c6a41086a290300200341f00b6a41086a2903007c201a201f54ad7c200341c00a6a41086a2903007c201b201a54ad7c200341f0096a41086a2903007c2012201b54ad7c200341900b6a41086a2903007c2013201254ad7c420d86847c221a423388200341e00b6a41086a290300200341800b6a41086a2903007c2008201754ad7c200341c00c6a41086a2903007c2016200854ad7c200341b00a6a41086a2903007c2018201654ad7c200341e0096a41086a2903007c2019201854ad7c201a201954ad7c420d86847c221642ffffffffffffff038322083703e840200320032903c009221f20032903900a7c221820032903e00a7c221920032903c00b7c221b20032903a00c7c22122016423388200341f00a6a41086a290300200341d0096a41086a2903007c200c201154ad7c200341d00b6a41086a2903007c200f200c54ad7c200341b00c6a41086a2903007c2014200f54ad7c200341a00a6a41086a2903007c2015201454ad7c2016201554ad7c420d86847c220c42ffffffffffffff038322143703f040200320032903800a221c20032903900c7c220f20032903b0097c221620032903d00a7c221120032903b00b7c2217200c423388200341c0096a41086a290300200341900a6a41086a2903007c2018201f54ad7c200341e00a6a41086a2903007c2019201854ad7c200341c00b6a41086a2903007c201b201954ad7c200341a00c6a41086a2903007c2012201b54ad7c200c201254ad7c420d86847c220c42ffffffffffffff038322153703f8402003200c423388200341800a6a41086a290300200341900c6a41086a2903007c200f201c54ad7c200341b0096a41086a2903007c2016200f54ad7c200341d00a6a41086a2903007c2011201654ad7c200341b00b6a41086a2903007c2017201154ad7c200c201754ad7c420d868442137e201342ffffffffffffff03837c220f42ffffffffffffff0383220c3703d8402003200f423388201a42ffffffffffffff03837c220f3703e040200341a8c1006a200341d8c0006a4101106b20034190096a20032903b041221642002010420010d507200341c0086a20032903b841221942137e22134200200d420010d507200341f0076a20032903c041221b42137e22124200200a420010d507200341a0076a20032903c841221142137e221a42002007420010d507200341b0066a20032903a841221842002005420010d507200341a0096a201642137e4200200d420010d507200341d0086a20134200200a420010d50720034180086a201242002007420010d507200341a0066a201842002010420010d507200341b0076a201a42002005420010d50720034180096a201642002005420010d507200341b0086a201942002010420010d507200341e0076a20124200200d420010d50720034190076a201a4200200a420010d507200341c0066a201842002007420010d507200341f0086a201642002007420010d507200341a0086a201942002005420010d507200341d0076a201b42002010420010d50720034180076a201a4200200d420010d507200341d0066a20184200200a420010d507200341e0086a20164200200a420010d50720034190086a201942002007420010d507200341c0076a201b42002005420010d507200341f0066a201142002010420010d507200341e0066a20184200200d420010d507200320032903b00822112003290380097c221020032903e0077c22052003290390077c220720032903c0067c221620032903c00822172003290390097c220a20032903f0077c221820032903a0077c221920032903b0067c220d20032903d008221f20032903a0097c221a2003290380087c221b20032903a0067c221220032903b0077c2213423388200341d0086a41086a290300200341a0096a41086a2903007c201a201f54ad7c20034180086a41086a2903007c201b201a54ad7c200341a0066a41086a2903007c2012201b54ad7c200341b0076a41086a2903007c2013201254ad7c420d86847c221a423388200341c0086a41086a29030020034190096a41086a2903007c200a201754ad7c200341f0076a41086a2903007c2018200a54ad7c200341a0076a41086a2903007c2019201854ad7c200341b0066a41086a2903007c200d201954ad7c201a200d54ad7c420d86847c220a42ffffffffffffff038337039041200320032903a008221220032903f0087c221820032903d0077c22192003290380077c220d20032903d0067c221b200a423388200341b0086a41086a29030020034180096a41086a2903007c2010201154ad7c200341e0076a41086a2903007c2005201054ad7c20034190076a41086a2903007c2007200554ad7c200341c0066a41086a2903007c2016200754ad7c200a201654ad7c420d86847c221042ffffffffffffff0383370398412003200329039008221120032903e0087c220520032903c0077c220720032903f0067c221620032903e0067c220a2010423388200341a0086a41086a290300200341f0086a41086a2903007c2018201254ad7c200341d0076a41086a2903007c2019201854ad7c20034180076a41086a2903007c200d201954ad7c200341d0066a41086a2903007c201b200d54ad7c2010201b54ad7c420d86847c221042ffffffffffffff03833703a0412003201042338820034190086a41086a290300200341e0086a41086a2903007c2005201154ad7c200341c0076a41086a2903007c2007200554ad7c200341f0066a41086a2903007c2016200754ad7c200341e0066a41086a2903007c200a201654ad7c2010200a54ad7c420d868442137e201342ffffffffffffff03837c221042ffffffffffffff03833703804120032010423388201a42ffffffffffffff03837c37038841200341b0c0006a20034180c1006a106a20034188c0006a2001106a4100210141012102034020034188c0006a20016a2d0000200341b0c0006a20016a2d0000732230410020306b72417f7341800171410776106d2002712102200141016a22014120470d000b2002106d2131200342f0ffffffffffff3f200b7d220542338842f0ffffffffffff3f200e7d220b42ffffffffffffff03837c22103703c841200342f0ffffffffffff3f20047d2207423388200542ffffffffffffff03837c22053703c041200342f0ffffffffffff3f20067d220e423388200742ffffffffffffff03837c22073703b8412003200e42ffffffffffffff038342d0fdffffffffff3f20097d22044233887c220e3703b0412003200b42338842137e200442ffffffffffffff03837c220b3703a841200341b0c0006a20034180c1006a106a20034188c0006a200341a8c1006a106a4100210141012102034020034188c0006a20016a2d0000200341b0c0006a20016a2d0000732230410020306b72417f7341800171410776106d2002712102200141016a22014120470d000b200341b0056a2010420042a0d69f90da80b1cb00420010d50720034180066a200b4200429db1bce4dfb435420010d507200341e0046a2005420042badf96dcb5c3bac700420010d507200341c0036a200e420042b0c1bad0f4e48603420010d50720034190046a2007420042a7ecfac2b5f7ea19420010d507200341c0056a2010420042a7a7fbf49beaf607420010d50720034190066a200b420042b0c1bad0f4e48603420010d507200341f0046a2005420042a0d69f90da80b1cb00420010d507200341d0036a200e420042a7ecfac2b5f7ea19420010d507200341a0046a2007420042badf96dcb5c3bac700420010d507200341a0056a2010420042badf96dcb5c3bac700420010d507200341f0056a200b420042e098f4e5e9ebfb03420010d507200341d0046a2005420042a7ecfac2b5f7ea19420010d507200341b0036a200e4200429db1bce4dfb435420010d50720034180046a2007420042b0c1bad0f4e48603420010d50720034190056a2010420042a7ecfac2b5f7ea19420010d507200341e0056a200b4200429e9981b4dab2e103420010d507200341c0046a2005420042b0c1bad0f4e48603420010d507200341a0036a200e420042e098f4e5e9ebfb03420010d507200341f0036a20074200429db1bce4dfb435420010d50720034180056a2010420042b0c1bad0f4e48603420010d507200341d0056a200b4200429df893c0a486ae01420010d507200341b0046a20054200429db1bce4dfb435420010d50720034190036a200e4200429e9981b4dab2e103420010d507200341e0036a2007420042e098f4e5e9ebfb03420010d507200341b0056a41086a290300211220034180066a41086a290300211320032903b00521092003290380062110200341e0046a41086a290300211120032903e0042116200341c0036a41086a290300211720032903c003210a20034190046a41086a290300211f2003290390042118200341c0056a41086a290300211c20034190066a41086a290300212020032903c00521192003290390062105200341f0046a41086a290300212120032903f004210d200341d0036a41086a290300212520032903d003211a200341a0046a41086a290300212620032903a004211b20032903a005210e20032903f005210720032903d004210b20032903b003210420032903800421062002106d2132200320062004200b2007200e7c220e7c220b7c22047c22062018200a2016201020097c22097c22167c220a7c2218201b201a200d200520197c22197c220d7c221a7c221b4233882026202520212020201c7c2019200554ad7c7c200d201954ad7c7c201a200d54ad7c7c201b201a54ad7c420d86847c2205423388201f20172011201320127c2009201054ad7c7c2016200954ad7c7c200a201654ad7c7c2018200a54ad7c2005201854ad7c420d86847c221042ffffffffffffff03833703b841200320032903e00522192003290390057c220920032903c0047c221620032903a0037c220a20032903f0037c22182010423388200341f0056a41086a290300200341a0056a41086a2903007c200e200754ad7c200341d0046a41086a2903007c200b200e54ad7c200341b0036a41086a2903007c2004200b54ad7c20034180046a41086a2903007c2006200454ad7c2010200654ad7c420d86847c221042ffffffffffffff03833703c041200320032903d00522062003290380057c220720032903b0047c220e2003290390037c220b20032903e0037c22042010423388200341e0056a41086a29030020034190056a41086a2903007c2009201954ad7c200341c0046a41086a2903007c2016200954ad7c200341a0036a41086a2903007c200a201654ad7c200341f0036a41086a2903007c2018200a54ad7c2010201854ad7c420d86847c221042ffffffffffffff03833703c84120032010423388200341d0056a41086a29030020034180056a41086a2903007c2007200654ad7c200341b0046a41086a2903007c200e200754ad7c20034190036a41086a2903007c200b200e54ad7c200341e0036a41086a2903007c2004200b54ad7c2010200454ad7c420d868442137e201b42ffffffffffffff03837c221042ffffffffffffff03833703a84120032010423388200542ffffffffffffff03837c3703b041200341b0c0006a20034180c1006a106a20034188c0006a200341a8c1006a106a4100210141012102034020034188c0006a20016a2d0000200341b0c0006a20016a2d0000732230410020306b72417f7341800171410776106d2002712102200141016a22014120470d000b200341a0026a200842137e22074200429df893c0a486ae01420010d507200341d0016a201442137e22054200429e9981b4dab2e103420010d50720034180016a201542137e2210420042e098f4e5e9ebfb03420010d507200341306a200c4200429db1bce4dfb435420010d507200341f0026a200f420042b0c1bad0f4e48603420010d507200341b0026a20074200429e9981b4dab2e103420010d507200341e0016a2005420042e098f4e5e9ebfb03420010d50720034190016a20104200429db1bce4dfb435420010d507200341c0006a200c420042b0c1bad0f4e48603420010d50720034180036a200f42137e4200429df893c0a486ae01420010d50720034190026a2008420042b0c1bad0f4e48603420010d507200341c0016a20054200429df893c0a486ae01420010d507200341f0006a20104200429e9981b4dab2e103420010d507200341206a200c420042e098f4e5e9ebfb03420010d507200341e0026a200f4200429db1bce4dfb435420010d50720034180026a20084200429db1bce4dfb435420010d507200341b0016a2014420042b0c1bad0f4e48603420010d507200341e0006a20104200429df893c0a486ae01420010d507200341106a200c4200429e9981b4dab2e103420010d507200341d0026a200f420042e098f4e5e9ebfb03420010d507200341f0016a2008420042e098f4e5e9ebfb03420010d507200341a0016a20144200429db1bce4dfb435420010d507200341d0006a2015420042b0c1bad0f4e48603420010d5072003200c4200429df893c0a486ae01420010d507200341c0026a200f4200429e9981b4dab2e103420010d507200320032903a001221c20032903f0017c221020032903507c220520032903007c220720032903c0027c220e20032903b00122202003290380027c220b20032903607c220420032903107c220620032903d0027c220920032903c00122212003290390027c221620032903707c220a20032903207c221820032903e0027c221920032903d001222520032903a0027c220d2003290380017c221a20032903307c221b20032903f0027c221220032903e001222620032903b0027c22132003290390017c221120032903407c22172003290380037c221f423388200341e0016a41086a290300200341b0026a41086a2903007c2013202654ad7c20034190016a41086a2903007c2011201354ad7c200341c0006a41086a2903007c2017201154ad7c20034180036a41086a2903007c201f201754ad7c420d86847c2213423388200341d0016a41086a290300200341a0026a41086a2903007c200d202554ad7c20034180016a41086a2903007c201a200d54ad7c200341306a41086a2903007c201b201a54ad7c200341f0026a41086a2903007c2012201b54ad7c2013201254ad7c420d86847c220d423388200341c0016a41086a29030020034190026a41086a2903007c2016202154ad7c200341f0006a41086a2903007c200a201654ad7c200341206a41086a2903007c2018200a54ad7c200341e0026a41086a2903007c2019201854ad7c200d201954ad7c420d86847c2216423388200341b0016a41086a29030020034180026a41086a2903007c200b202054ad7c200341e0006a41086a2903007c2004200b54ad7c200341106a41086a2903007c2006200454ad7c200341d0026a41086a2903007c2009200654ad7c2016200954ad7c420d86847c220b423388200341a0016a41086a290300200341f0016a41086a2903007c2010201c54ad7c200341d0006a41086a2903007c2005201054ad7c200341086a2903007c2007200554ad7c200341c0026a41086a2903007c200e200754ad7c200b200e54ad7c420d868442137e201f42ffffffffffffff03837c220742ffffffffffffff0383200c8542002002106d203272106dad42ff01837d221083200c8522053703d84020032007423388201342ffffffffffffff03837c200f85201083200f8522073703e0402003200b42ffffffffffffff0383201585201083201585220e3703f8402003201642ffffffffffffff0383201485201083201485220b3703f0402003200d42ffffffffffffff038320088520108320088522043703e84020034188c0006a200341d8c0006a106a200342f0ffffffffffff3f200e7d220642ffffffffffffff038342f0ffffffffffff3f200b7d22094233887c200e85420020032d008840410171106dad42ff01837d221083200e853703f8402003200942ffffffffffffff038342f0ffffffffffff3f20047d220e4233887c200b85201083200b853703f0402003200e42ffffffffffffff038342f0ffffffffffff3f20077d220e4233887c2004852010832004853703e8402003200e42ffffffffffffff038342d0fdffffffffff3f20057d220e4233887c2007852010832007853703e0402003200642338842137e200e42ffffffffffffff03837c2005852010832005853703d84020002032203172106d3a0000200020032903d840370308200041106a20032903e040370300200041186a20032903e840370300200041206a20032903f040370300200041286a20032903f840370300200341d0c1006a24000b1501017f230041106b220120003a000f20012d000f0bdf960104017f227e057f057e230041a02a6b22022400200241c8296a20014101106b200241b0286a20022903d0292203420042b0c1bad0f4e48603420010d507200241e0276a20022903d829220442137e22054200429df893c0a486ae01420010d50720024190276a20022903e029220642137e22074200429e9981b4dab2e103420010d507200241c0266a20022903e829220842137e2209420042e098f4e5e9ebfb03420010d507200241d0256a20022903c829220a4200429db1bce4dfb435420010d507200241c0256a200a420042b0c1bad0f4e48603420010d507200241c0286a200342137e4200429df893c0a486ae01420010d507200241f0276a20054200429e9981b4dab2e103420010d507200241a0276a2007420042e098f4e5e9ebfb03420010d507200241d0266a20094200429db1bce4dfb435420010d507200241d0276a2004420042b0c1bad0f4e48603420010d50720024180276a20074200429df893c0a486ae01420010d507200241b0266a20094200429e9981b4dab2e103420010d507200241e0256a200a420042e098f4e5e9ebfb03420010d507200241a0286a20034200429db1bce4dfb435420010d507200241f0266a2006420042b0c1bad0f4e48603420010d507200241a0266a20094200429df893c0a486ae01420010d507200241f0256a200a4200429e9981b4dab2e103420010d50720024190286a2003420042e098f4e5e9ebfb03420010d507200241c0276a20044200429db1bce4dfb435420010d50720024190266a2008420042b0c1bad0f4e48603420010d50720024180266a200a4200429df893c0a486ae01420010d50720024180286a20034200429e9981b4dab2e103420010d507200241b0276a2004420042e098f4e5e9ebfb03420010d507200241e0266a20064200429db1bce4dfb435420010d507200241e0216a200229038027220b20022903d0277c220320022903b0267c220420022903e0257c220920022903a0287c220620022903e027220c20022903b0287c220a2002290390277c220720022903c0267c220520022903d0257c220820022903c028220d20022903c0257c220e20022903f0277c220f20022903a0277c221020022903d0267c2211423388200241c0286a41086a290300200241c0256a41086a2903007c200e200d54ad7c200241f0276a41086a2903007c200f200e54ad7c200241a0276a41086a2903007c2010200f54ad7c200241d0266a41086a2903007c2011201054ad7c420d86847c220e423388200241e0276a41086a290300200241b0286a41086a2903007c200a200c54ad7c20024190276a41086a2903007c2007200a54ad7c200241c0266a41086a2903007c2005200754ad7c200241d0256a41086a2903007c2008200554ad7c200e200854ad7c420d86847c220742ffffffffffffff0383220a42137e2208420042ffed8af7ec86c802420010d50720024180216a20022903802622122002290390267c22052002290380287c220f20022903b0277c221020022903e0267c220c20022903a026221320022903f0267c220d20022903f0257c22142002290390287c221520022903c0277c2216200742338820024180276a41086a290300200241d0276a41086a2903007c2003200b54ad7c200241b0266a41086a2903007c2004200354ad7c200241e0256a41086a2903007c2009200454ad7c200241a0286a41086a2903007c2006200954ad7c2007200654ad7c420d86847c2204423388200241a0266a41086a290300200241f0266a41086a2903007c200d201354ad7c200241f0256a41086a2903007c2014200d54ad7c20024190286a41086a2903007c2015201454ad7c200241c0276a41086a2903007c2016201554ad7c2004201654ad7c420d86847c220942338820024180266a41086a29030020024190266a41086a2903007c2005201254ad7c20024180286a41086a2903007c200f200554ad7c200241b0276a41086a2903007c2010200f54ad7c200241e0266a41086a2903007c200c201054ad7c2009200c54ad7c420d868442137e201142ffffffffffffff03837c2206423388200e42ffffffffffffff03837c2203420042a3f1e59aa1b9d301420010d50720024190226a200442ffffffffffffff0383220442137e220f420042bbf9809de6b8ce03420010d507200241d0226a200942ffffffffffffff0383220942137e2207420042a9808780a6f4f902420010d507200241d01f6a200642ffffffffffffff03832206420042bdddd5d88385ea00420010d507200241e01f6a2006420042a3f1e59aa1b9d301420010d507200241c0206a200342137e2217420042ffed8af7ec86c802420010d507200241f0216a2008420042bbf9809de6b8ce03420010d507200241a0226a200f420042a9808780a6f4f902420010d507200241e0226a2007420042bdddd5d88385ea00420010d507200241c0236a200a420042a3f1e59aa1b9d301420010d50720024180226a200f420042ffed8af7ec86c802420010d507200241c0226a2007420042bbf9809de6b8ce03420010d507200241c01f6a2006420042a9808780a6f4f902420010d507200241f0206a2003420042bdddd5d88385ea00420010d507200241c0246a2004420042a3f1e59aa1b9d301420010d507200241b0226a2007420042ffed8af7ec86c802420010d507200241b01f6a2006420042bbf9809de6b8ce03420010d507200241e0206a2003420042a9808780a6f4f902420010d507200241d0236a200a420042bdddd5d88385ea00420010d507200241b0256a2009420042a3f1e59aa1b9d301420010d507200241e01e6a2006420042ffed8af7ec86c802420010d507200241d0206a2003420042bbf9809de6b8ce03420010d507200241e0236a200a420042a9808780a6f4f902420010d507200241d0246a2004420042bdddd5d88385ea00420010d507200241f0246a2009420042ccf7d9e9fbcee010420010d507200241a0206a200642017c2205420042cff887b5bcb5c603420010d50720024180246a20044200428df582a3b0868004420010d50720024180236a200a4200429aebd0c282f1c201420010d507200241c0216a2003420042f682ffa299b88202420010d507200241e0246a2009420042ddf396f0fbf7b9c300420010d507200241b0206a2005420042f682ffa299b88202420010d507200241f0236a2004420042ccf7d9e9fbcee010420010d507200241f0226a200a4200428df582a3b0868004420010d507200241d0216a20034200429aebd0c282f1c201420010d50720024180256a20094200428df582a3b0868004420010d50720024190206a2005420042848dc885f9eff000420010d50720024190246a20044200429aebd0c282f1c201420010d50720024190236a200a420042f682ffa299b88202420010d507200241b0216a2003420042cff887b5bcb5c603420010d50720024190256a20094200429aebd0c282f1c201420010d50720024180206a2005420042dfddd7d2ccf91a420010d507200241a0246a2004420042f682ffa299b88202420010d507200241a0236a200a420042cff887b5bcb5c603420010d507200241a0216a2003420042848dc885f9eff000420010d507200241a0256a2009420042f682ffa299b88202420010d507200241f01f6a2005420042bed6acd4f2a00a420010d507200241b0246a2004420042cff887b5bcb5c603420010d507200241b0236a200a420042848dc885f9eff000420010d50720024190216a2003420042dfddd7d2ccf91a420010d507200241801d6a42efffffffffffffc30020022903e01e221820022903b0257c220e20022903d0207c221020022903e0237c221120022903d0247c220c20022903b022221920022903c0247c220520022903b01f7c220d20022903e0207c221420022903d0237c2215200229038022221a20022903c0237c221620022903c0227c220b20022903c01f7c221220022903f0207c221320022903e021221b2002290380217c221c2002290390227c221d20022903d0227c221e20022903d01f7c221f20022903c020222020022903e01f7c222120022903f0217c222220022903a0227c222320022903e0227c2224423388200241c0206a41086a290300200241e01f6a41086a2903007c2021202054ad7c200241f0216a41086a2903007c2022202154ad7c200241a0226a41086a2903007c2023202254ad7c200241e0226a41086a2903007c2024202354ad7c420d86847c2221423388200241e0216a41086a29030020024180216a41086a2903007c201c201b54ad7c20024190226a41086a2903007c201d201c54ad7c200241d0226a41086a2903007c201e201d54ad7c200241d01f6a41086a2903007c201f201e54ad7c2021201f54ad7c420d86847c221c42338820024180226a41086a290300200241c0236a41086a2903007c2016201a54ad7c200241c0226a41086a2903007c200b201654ad7c200241c01f6a41086a2903007c2012200b54ad7c200241f0206a41086a2903007c2013201254ad7c201c201354ad7c420d86847c2216423388200241b0226a41086a290300200241c0246a41086a2903007c2005201954ad7c200241b01f6a41086a2903007c200d200554ad7c200241e0206a41086a2903007c2014200d54ad7c200241d0236a41086a2903007c2015201454ad7c2016201554ad7c420d86847c220d42ffffffffffffff03837d221442ffffffffffffff038342efffffffffffffc300201642ffffffffffffff03837d22154233887c220542002008428b868581d2a18c387c2216420010d507200241d01d6a201442338842137e42bcfdffffffffffc300200d423388200241e01e6a41086a290300200241b0256a41086a2903007c200e201854ad7c200241d0206a41086a2903007c2010200e54ad7c200241e0236a41086a2903007c2011201054ad7c200241d0246a41086a2903007c200c201154ad7c200d200c54ad7c420d868442137e202442ffffffffffffff03837c221042ffffffffffffff03837d221442ffffffffffffff03837c22084200200342bdddd5d88385ea007c2211420010d507200241901f6a201542ffffffffffffff038342efffffffffffffc300201c42ffffffffffffff03837d220c4233887c220e4200200f42e18392a796b7d2c4007c220d420010d507200241c01e6a200c42ffffffffffffff038342efffffffffffffc3002010423388202142ffffffffffffff03837c7d22104233887c220f4200200742eda9ced69582d9307c220c420010d507200241c01c6a201042ffffffffffffff038320144233887c22074200200642a3f1e59aa1b9d3017c2210420010d507200241901d6a2005420020174287f0dc94c6dfde0f7c420010d507200241d01c6a201042002008420010d507200241a01f6a200e42002016420010d507200241d01e6a200f4200200d420010d507200241901e6a20074200200c420010d507200241f01c6a20054200200d420010d507200241c01d6a20084200200a42a9808780a6f4f9027c220d420010d507200241801f6a200e4200200c420010d507200241b01c6a200f42002010420010d507200241801e6a200742002011420010d507200241e01c6a20054200200c420010d507200241b01d6a20084200200442bbf9809de6b8ce037c220c420010d507200241a01c6a200e42002010420010d507200241b01e6a200f42002011420010d507200241f01d6a20074200200d420010d507200241901c6a200542002010420010d507200241a01d6a20084200200942ffed8af7ec86c8027c420010d507200241f01e6a200e42002011420010d507200241a01e6a200f4200200d420010d507200241e01d6a20074200200c420010d5072002200229038025220b2002290390207c22072002290390247c22052002290390237c220820022903b0217c220e20022903f024221220022903a0207c220f2002290380247c22102002290380237c221120022903c0217c220c20022903e024221320022903b0207c220d20022903f0237c221420022903f0227c221520022903d0217c2216423388200241e0246a41086a290300200241b0206a41086a2903007c200d201354ad7c200241f0236a41086a2903007c2014200d54ad7c200241f0226a41086a2903007c2015201454ad7c200241d0216a41086a2903007c2016201554ad7c420d86847c220d423388200241f0246a41086a290300200241a0206a41086a2903007c200f201254ad7c20024180246a41086a2903007c2010200f54ad7c20024180236a41086a2903007c2011201054ad7c200241c0216a41086a2903007c200c201154ad7c200d200c54ad7c420d86847c220f42ffffffffffffff03833703e028200220022903902522152002290380207c221020022903a0247c221120022903a0237c220c20022903a0217c2214200f42338820024180256a41086a29030020024190206a41086a2903007c2007200b54ad7c20024190246a41086a2903007c2005200754ad7c20024190236a41086a2903007c2008200554ad7c200241b0216a41086a2903007c200e200854ad7c200f200e54ad7c420d86847c220742ffffffffffffff03833703e828200220022903a025220b20022903f01f7c220520022903b0247c220820022903b0237c220e2002290390217c220f200742338820024190256a41086a29030020024180206a41086a2903007c2010201554ad7c200241a0246a41086a2903007c2011201054ad7c200241a0236a41086a2903007c200c201154ad7c200241a0216a41086a2903007c2014200c54ad7c2007201454ad7c420d86847c220742ffffffffffffff03833703f02820022007423388200241a0256a41086a290300200241f01f6a41086a2903007c2005200b54ad7c200241b0246a41086a2903007c2008200554ad7c200241b0236a41086a2903007c200e200854ad7c20024190216a41086a2903007c200f200e54ad7c2007200f54ad7c420d868442137e201642ffffffffffffff03837c220742ffffffffffffff03833703d02820022007423388200d42ffffffffffffff03837c3703d828200220022903f01c220b20022903c01d7c220720022903801f7c220520022903b01c7c220820022903801e7c220e20022903801d221220022903d01d7c220f20022903901f7c221020022903c01e7c221120022903c01c7c220c20022903901d221320022903d01c7c220d20022903a01f7c221420022903d01e7c221520022903901e7c2216423388200241901d6a41086a290300200241d01c6a41086a2903007c200d201354ad7c200241a01f6a41086a2903007c2014200d54ad7c200241d01e6a41086a2903007c2015201454ad7c200241901e6a41086a2903007c2016201554ad7c420d86847c220d423388200241801d6a41086a290300200241d01d6a41086a2903007c200f201254ad7c200241901f6a41086a2903007c2010200f54ad7c200241c01e6a41086a2903007c2011201054ad7c200241c01c6a41086a2903007c200c201154ad7c200d200c54ad7c420d86847c220f42ffffffffffffff038337038829200220022903e01c221520022903b01d7c221020022903a01c7c221120022903b01e7c220c20022903f01d7c2214200f423388200241f01c6a41086a290300200241c01d6a41086a2903007c2007200b54ad7c200241801f6a41086a2903007c2005200754ad7c200241b01c6a41086a2903007c2008200554ad7c200241801e6a41086a2903007c200e200854ad7c200f200e54ad7c420d86847c220742ffffffffffffff038337039029200220022903901c220b20022903a01d7c220520022903f01e7c220820022903a01e7c220e20022903e01d7c220f2007423388200241e01c6a41086a290300200241b01d6a41086a2903007c2010201554ad7c200241a01c6a41086a2903007c2011201054ad7c200241b01e6a41086a2903007c200c201154ad7c200241f01d6a41086a2903007c2014200c54ad7c2007201454ad7c420d86847c220742ffffffffffffff03833703982920022007423388200241901c6a41086a290300200241a01d6a41086a2903007c2005200b54ad7c200241f01e6a41086a2903007c2008200554ad7c200241a01e6a41086a2903007c200e200854ad7c200241e01d6a41086a2903007c200f200e54ad7c2007200f54ad7c420d868442137e201642ffffffffffffff03837c220742ffffffffffffff03833703f82820022007423388200d42ffffffffffffff03837c37038029200241c8296a200241d0286a200241f8286a106c20022d00c8292125200241a0296a41206a2226200241f0296a2903002207370300200241a0296a41186a2227200241c8296a41206a2903002205370300200241a0296a41106a2228200241c8296a41186a2903002208370300200241a0296a41086a2229200241c8296a41106a290300220e370300200220022903d029220f3703a029200241f01b6a200f420020012903082210420010d507200241a01b6a200742002001290310220c42137e2216420010d507200241d01a6a200542002001290318221442137e2215420010d507200241801a6a200842002001290320220b42137e220d420010d50720024190196a200e420020012903002211420010d50720024180196a20114200200f420010d507200241801c6a20074200201042137e420010d507200241b01b6a200542002016420010d507200241e01a6a200842002015420010d507200241901a6a200e4200200d420010d507200241901b6a200f4200200c420010d507200241c01a6a200742002015420010d507200241f0196a20054200200d420010d507200241a0196a200842002011420010d507200241e01b6a200e42002010420010d507200241b01a6a200f42002014420010d507200241e0196a20074200200d420010d507200241b0196a200542002011420010d507200241d01b6a200842002010420010d507200241801b6a200e4200200c420010d507200241d0196a200f4200200b420010d507200241c0196a200742002011420010d507200241c01b6a200542002010420010d507200241f01a6a20084200200c420010d507200241a01a6a200e42002014420010d507200220022903c019222220022903d0197c220720022903c01b7c220520022903f01a7c220820022903a01a7c220e20022903e019222320022903b01a7c220f20022903b0197c221020022903d01b7c221120022903801b7c220c20022903c01a222420022903901b7c220d20022903f0197c221420022903a0197c221520022903e01b7c221620022903a01b221720022903f01b7c220b20022903d01a7c221220022903801a7c22132002290390197c221c20022903801c22182002290380197c221d20022903b01b7c221e20022903e01a7c221f20022903901a7c2221423388200241801c6a41086a29030020024180196a41086a2903007c201d201854ad7c200241b01b6a41086a2903007c201e201d54ad7c200241e01a6a41086a2903007c201f201e54ad7c200241901a6a41086a2903007c2021201f54ad7c420d86847c221d423388200241a01b6a41086a290300200241f01b6a41086a2903007c200b201754ad7c200241d01a6a41086a2903007c2012200b54ad7c200241801a6a41086a2903007c2013201254ad7c20024190196a41086a2903007c201c201354ad7c201d201c54ad7c420d86847c220b423388200241c01a6a41086a290300200241901b6a41086a2903007c200d202454ad7c200241f0196a41086a2903007c2014200d54ad7c200241a0196a41086a2903007c2015201454ad7c200241e01b6a41086a2903007c2016201554ad7c200b201654ad7c420d86847c220d423388200241e0196a41086a290300200241b01a6a41086a2903007c200f202354ad7c200241b0196a41086a2903007c2010200f54ad7c200241d01b6a41086a2903007c2011201054ad7c200241801b6a41086a2903007c200c201154ad7c200d200c54ad7c420d86847c220f423388200241c0196a41086a290300200241d0196a41086a2903007c2007202254ad7c200241c01b6a41086a2903007c2005200754ad7c200241f01a6a41086a2903007c2008200554ad7c200241a01a6a41086a2903007c200e200854ad7c200f200e54ad7c420d868442137e202142ffffffffffffff03837c220742ffffffffffffff038322053703f8292002200f42ffffffffffffff038322083703982a20022007423388201d42ffffffffffffff03837c220e3703802a2002200d42ffffffffffffff0383220f3703902a2002200b42ffffffffffffff038322103703882a200241c8296a200241f8296a106a200242f0ffffffffffff3f20087d221142338842137e42d0fdffffffffff3f20057d220c42ffffffffffffff03837c200585420020022d00c829410171106d417f73410171106dad42ff01837d22078320058522053703f829200242f0ffffffffffff3f200e7d220d42ffffffffffffff0383200c4233887c200e85200783200e85220e3703802a2002201142ffffffffffffff038342f0ffffffffffff3f200f7d22114233887c20088520078320088522083703982a200242f0ffffffffffff3f20107d220c42ffffffffffffff0383200d4233887c20108520078320108522103703882a2002201142ffffffffffffff0383200c4233887c200f85200783200f85220f3703902a2025417f734101712201106d2125202920292903002211200e8542002025ad42ff01837d22078320118537030020282028290300220e201085200783200e8537030020272027290300220e200f85200783200e8537030020262026290300220e200885200783200e85370300200220022903a02922082005852007832008853703a029200241c00d6a200642ecffffffffffff038542002001106dad42ff01837d22078342ecffffffffffff038522054200200342f0ffffffffffff3f7c220e42ffffffffffffff0383200642cffdffffffffff3f7c220c4233887c2206420010d507200241b00e6a200942ffffffffffffff038520078342ffffffffffffff038522084200200a42f0ffffffffffff3f7c221042ffffffffffffff0383200e4233887c220f42137e220d420010d507200241d00e6a200442ffffffffffffff038520078342ffffffffffffff0385220e4200200442f0ffffffffffff3f7c220442ffffffffffffff038320104233887c221042137e2211420010d507200241800f6a200a42ffffffffffffff038520078342ffffffffffffff0385220a4200200942f0ffffffffffff3f7c221442ffffffffffffff038320044233887c221542137e2209420010d507200241f00c6a200342ffffffffffffff038520078342ffffffffffffff038522034200201442338842137e200c42ffffffffffffff03837c2204420010d507200241800d6a200442002005420010d507200241d00d6a20084200200642137e420010d507200241e00e6a200e4200200d420010d507200241900f6a200a42002011420010d507200241c00f6a200342002009420010d507200241800e6a20054200200f420010d507200241a00e6a200842002011420010d507200241c00e6a200e42002009420010d507200241e00c6a200a42002004420010d507200241b00d6a200342002006420010d507200241f00d6a200542002010420010d507200241900e6a200842002009420010d507200241800c6a200e42002004420010d507200241a00d6a200a42002006420010d507200241b00f6a20034200200f420010d507200241e00d6a200542002015420010d507200241a00b6a200842002004420010d507200241900d6a200e42002006420010d507200241f00e6a200a4200200f420010d507200241a00f6a200342002010420010d507200241800b6a20022903a00b221c20022903e00d7c220a20022903900d7c220420022903f00e7c220920022903a00f7c220620022903900e221d20022903f00d7c220320022903800c7c220720022903a00d7c220520022903b00f7c220820022903a00e221e20022903800e7c220e20022903c00e7c220f20022903e00c7c221020022903b00d7c221120022903b00e221f20022903c00d7c220c20022903d00e7c220d20022903800f7c221420022903f00c7c221520022903d00d222120022903800d7c221620022903e00e7c220b20022903900f7c221220022903c00f7c2213423388200241d00d6a41086a290300200241800d6a41086a2903007c2016202154ad7c200241e00e6a41086a2903007c200b201654ad7c200241900f6a41086a2903007c2012200b54ad7c200241c00f6a41086a2903007c2013201254ad7c420d86847c2216423388200241b00e6a41086a290300200241c00d6a41086a2903007c200c201f54ad7c200241d00e6a41086a2903007c200d200c54ad7c200241800f6a41086a2903007c2014200d54ad7c200241f00c6a41086a2903007c2015201454ad7c2016201554ad7c420d86847c220c423388200241a00e6a41086a290300200241800e6a41086a2903007c200e201e54ad7c200241c00e6a41086a2903007c200f200e54ad7c200241e00c6a41086a2903007c2010200f54ad7c200241b00d6a41086a2903007c2011201054ad7c200c201154ad7c420d86847c220e423388200241900e6a41086a290300200241f00d6a41086a2903007c2003201d54ad7c200241800c6a41086a2903007c2007200354ad7c200241a00d6a41086a2903007c2005200754ad7c200241b00f6a41086a2903007c2008200554ad7c200e200854ad7c420d86847c220742ffffffffffffff03832203420042f8fb9b94e0ed8617420010d507200241e0096a2007423388200241a00b6a41086a290300200241e00d6a41086a2903007c200a201c54ad7c200241900d6a41086a2903007c2004200a54ad7c200241f00e6a41086a2903007c2009200454ad7c200241a00f6a41086a2903007c2006200954ad7c2007200654ad7c420d868442137e201342ffffffffffffff03837c220642ffffffffffffff0383220a420042b5cccc99bcc0e502420010d507200241e00b6a200e42ffffffffffffff038322044200428b83d98ea38bdb0a420010d507200241c00c6a200c42ffffffffffffff03832209420042e6c09290d28a8b35420010d507200241b00a6a2006423388201642ffffffffffffff03837c2206420042a09ab5a7a4d5d602420010d507200241900b6a2003420042efabafe6f7c88835420010d507200241f0096a200a420042a09ab5a7a4d5d602420010d507200241f00b6a2004420042f8fb9b94e0ed8617420010d507200241d00c6a20094200428b83d98ea38bdb0a420010d507200241c00a6a2006420042e6c09290d28a8b35420010d507200241f00a6a20034200428b83d98ea38bdb0a420010d507200241d0096a200a420042a8f2a9fabaa79b01420010d507200241d00b6a2004420042e6c09290d28a8b35420010d507200241b00c6a2009420042a09ab5a7a4d5d602420010d507200241a00a6a2006420042b5cccc99bcc0e502420010d507200241e00a6a2003420042e6c09290d28a8b35420010d507200241c0096a200a420042a9afa6f3e694c800420010d507200241c00b6a2004420042a09ab5a7a4d5d602420010d507200241a00c6a2009420042b5cccc99bcc0e502420010d507200241900a6a2006420042a8f2a9fabaa79b01420010d507200241d00a6a2003420042a09ab5a7a4d5d602420010d507200241b0096a200a420042c2cdbdbdb3d1e502420010d507200241b00b6a2004420042b5cccc99bcc0e502420010d507200241900c6a2009420042a8f2a9fabaa79b01420010d507200241800a6a2006420042a9afa6f3e694c800420010d50720022903f8282103200229039829210f20022903902921092002290388292104200229038029210a200241c8296a200241a0296a4101106b200241e0186a20022903a02942018622064200200a420010d507200241e0166a202629030042018622074200200442137e220c420010d507200241a0176a202729030042018622054200200942137e2211420010d507200241a0166a202829030042018622084200200f42137e2210420010d507200241b0186a2029290300420186220e42002003420010d507200241f0186a200342002006420010d507200241f0166a20074200200a42137e420010d507200241b0176a20054200200c420010d507200241f0176a200842002011420010d507200241b0166a200e42002010420010d507200241d0186a200642002004420010d507200241d0166a200742002011420010d50720024190166a200542002010420010d507200241e0176a200842002003420010d507200241a0186a200e4200200a420010d507200241c0186a200642002009420010d507200241e0146a200742002010420010d50720024190176a200542002003420010d507200241d0176a20084200200a420010d50720024190186a200e42002004420010d507200241b0136a20064200200f420010d507200241c0166a200742002003420010d50720024180176a20054200200a420010d507200241c0176a200842002004420010d50720024180186a200e42002009420010d507200241a0076a20022903d00a222220022903b0097c220620022903b00b7c220720022903900c7c220520022903800a7c220820022903e00a222320022903c0097c220e20022903c00b7c221020022903a00c7c221120022903900a7c220c20022903f00a222420022903d0097c220d20022903d00b7c221420022903b00c7c221520022903a00a7c221620022903800b221720022903e0097c220b20022903e00b7c221220022903c00c7c221320022903b00a7c221c20022903900b221820022903f0097c221d20022903f00b7c221e20022903d00c7c221f20022903c00a7c2221423388200241900b6a41086a290300200241f0096a41086a2903007c201d201854ad7c200241f00b6a41086a2903007c201e201d54ad7c200241d00c6a41086a2903007c201f201e54ad7c200241c00a6a41086a2903007c2021201f54ad7c420d86847c221d423388200241800b6a41086a290300200241e0096a41086a2903007c200b201754ad7c200241e00b6a41086a2903007c2012200b54ad7c200241c00c6a41086a2903007c2013201254ad7c200241b00a6a41086a2903007c201c201354ad7c201d201c54ad7c420d86847c220b423388200241f00a6a41086a290300200241d0096a41086a2903007c200d202454ad7c200241d00b6a41086a2903007c2014200d54ad7c200241b00c6a41086a2903007c2015201454ad7c200241a00a6a41086a2903007c2016201554ad7c200b201654ad7c420d86847c220d423388200241e00a6a41086a290300200241c0096a41086a2903007c200e202354ad7c200241c00b6a41086a2903007c2010200e54ad7c200241a00c6a41086a2903007c2011201054ad7c200241900a6a41086a2903007c200c201154ad7c200d200c54ad7c420d86847c220e42ffffffffffffff0383200f7d42f0ffffffffffff3f7c220f42ffffffffffffff0383200d42ffffffffffffff038320097d42f0ffffffffffff3f7c22104233887c2209420042a88c8b81f5cabeca00420010d507200241d0066a200f42338842137e200e423388200241d00a6a41086a290300200241b0096a41086a2903007c2006202254ad7c200241b00b6a41086a2903007c2007200654ad7c200241900c6a41086a2903007c2005200754ad7c200241800a6a41086a2903007c2008200554ad7c200e200854ad7c420d868442137e202142ffffffffffffff03837c220642ffffffffffffff038320037d42d0fdffffffffff3f7c220742ffffffffffffff03837c2203420042d2dfded4f0ede000420010d50720024190096a201042ffffffffffffff0383200b42ffffffffffffff038320047d42f0ffffffffffff3f7c22054233887c2204420042c8ee859b8cd29829420010d507200241c0086a200542ffffffffffffff03832006423388201d42ffffffffffffff03837c200a7d42f0ffffffffffff3f7c22064233887c220a420042dcd78e98b19df320420010d507200241f0076a200642ffffffffffffff038320074233887c22064200429bdceccb84d4fd03420010d507200241b0076a2009420042969988cadca7b00e420010d507200241e0066a20034200429bdceccb84d4fd03420010d507200241a0096a2004420042a88c8b81f5cabeca00420010d507200241d0086a200a420042c8ee859b8cd29829420010d50720024180086a2006420042dcd78e98b19df320420010d50720024190076a2009420042c8ee859b8cd29829420010d507200241c0066a2003420042b8ecf9b5ffe8f503420010d50720024180096a2004420042dcd78e98b19df320420010d507200241b0086a200a4200429bdceccb84d4fd03420010d507200241e0076a2006420042d2dfded4f0ede000420010d50720024180076a2009420042dcd78e98b19df320420010d50720024190056a200342004298c9f9f3f9c09502420010d507200241f0086a20044200429bdceccb84d4fd03420010d507200241a0086a200a420042d2dfded4f0ede000420010d507200241d0076a2006420042b8ecf9b5ffe8f503420010d507200241f0066a20094200429bdceccb84d4fd03420010d507200241e0036a2003420042b4f0cadfb1d2dd01420010d507200241e0086a2004420042d2dfded4f0ede000420010d50720024190086a200a420042b8ecf9b5ffe8f503420010d507200241c0076a200642004298c9f9f3f9c09502420010d507200241c0126a20022903c016221c20022903b0137c22042002290380177c220920022903c0177c22062002290380187c220720022903e014221d20022903c0187c22032002290390177c220a20022903d0177c22052002290390187c220820022903d016221e20022903d0187c220e2002290390167c220f20022903e0177c221020022903a0187c221120022903e016221f20022903e0187c220c20022903a0177c220d20022903a0167c221420022903b0187c221520022903f016222120022903f0187c221620022903b0177c220b20022903f0177c221220022903b0167c2213423388200241f0166a41086a290300200241f0186a41086a2903007c2016202154ad7c200241b0176a41086a2903007c200b201654ad7c200241f0176a41086a2903007c2012200b54ad7c200241b0166a41086a2903007c2013201254ad7c420d86847c2212423388200241e0166a41086a290300200241e0186a41086a2903007c200c201f54ad7c200241a0176a41086a2903007c200d200c54ad7c200241a0166a41086a2903007c2014200d54ad7c200241b0186a41086a2903007c2015201454ad7c2012201554ad7c420d86847c220c423388200241d0166a41086a290300200241d0186a41086a2903007c200e201e54ad7c20024190166a41086a2903007c200f200e54ad7c200241e0176a41086a2903007c2010200f54ad7c200241a0186a41086a2903007c2011201054ad7c200c201154ad7c420d86847c220e423388200241e0146a41086a290300200241c0186a41086a2903007c2003201d54ad7c20024190176a41086a2903007c200a200354ad7c200241d0176a41086a2903007c2005200a54ad7c20024190186a41086a2903007c2008200554ad7c200e200854ad7c420d86847c220542ffffffffffffff03832203420042f0ffffffffffff3f20022903d82922107d220842ffffffffffffff038342f0ffffffffffff3f20022903d029220a7d22114233887c220f42137e2215420010d50720024180106a2005423388200241c0166a41086a290300200241b0136a41086a2903007c2004201c54ad7c20024180176a41086a2903007c2009200454ad7c200241c0176a41086a2903007c2006200954ad7c20024180186a41086a2903007c2007200654ad7c2005200754ad7c420d868442137e201342ffffffffffffff03837c220542ffffffffffffff038322044200201142ffffffffffffff038342d1fdffffffffff3f20022903c82922137d221c4233887c2209420010d507200241f0136a200e42ffffffffffffff03832206420042f0ffffffffffff3f20022903e02922147d220d42ffffffffffffff038320084233887c221142137e220e420010d507200241a0156a200c42ffffffffffffff03832207420042f0ffffffffffff3f20022903e82922167d220842ffffffffffffff0383200d4233887c220d42137e220b420010d507200241a0116a2005423388201242ffffffffffffff03837c22054200200842338842137e201c42ffffffffffffff03837c2208420010d507200241d0126a20034200200942137e420010d50720024190106a200842002004420010d50720024180146a200642002015420010d507200241b0156a20074200200e420010d507200241b0116a20054200200b420010d507200241b0126a20034200200e420010d507200241f00f6a20044200200f420010d507200241e0136a20064200200b420010d50720024190156a200742002008420010d50720024190116a200542002009420010d50720024190136a20034200201042137e2212420010d507200241d0106a20044200200a420010d507200241c0146a20064200201442137e2215420010d507200241f0156a20074200201642137e220c420010d507200241f0116a20054200201342017c220e420010d507200241a0136a20034200200a42137e2220420010d507200241e0106a200e42002004420010d507200241d0146a200642002012420010d50720024180166a200742002015420010d50720024180126a20054200200c420010d50720024180136a200342002015420010d507200241c0106a200442002010420010d507200241b0146a20064200200c420010d507200241e0156a20074200200e420010d507200241e0116a20054200200a420010d507200241a0126a20034200200b420010d507200241e00f6a200442002011420010d507200241d0136a200642002008420010d50720024180156a200742002009420010d50720024180116a20054200200f420010d507200241f0126a20034200200c420010d507200241b0106a200442002014420010d507200241a0146a20064200200e420010d507200241d0156a20074200200a420010d507200241d0116a200542002010420010d50720024190126a200342002008420010d507200241d00f6a20044200200d420010d507200241c0136a200642002009420010d507200241f0146a20074200200f420010d507200241f0106a200542002011420010d507200241e0126a20034200200e420010d507200241a0106a200442002016420010d50720024190146a20064200200a420010d507200241c0156a200742002010420010d507200241c0116a200542002014420010d507200241a0036a20022903f006222a20022903e0037c220320022903e0087c22042002290390087c220620022903c0077c2207200229038007222b2002290390057c220520022903f0087c220b20022903a0087c221320022903d0077c221c200229039007222c20022903c0067c221d2002290380097c221e20022903b0087c221f20022903e0077c222120022903a007222d20022903d0067c22222002290390097c222320022903c0087c222420022903f0077c221720022903b007222e20022903e0067c221820022903a0097c221920022903d0087c221a2002290380087c221b423388200241b0076a41086a290300200241e0066a41086a2903007c2018202e54ad7c200241a0096a41086a2903007c2019201854ad7c200241d0086a41086a2903007c201a201954ad7c20024180086a41086a2903007c201b201a54ad7c420d86847c2218423388200241a0076a41086a290300200241d0066a41086a2903007c2022202d54ad7c20024190096a41086a2903007c2023202254ad7c200241c0086a41086a2903007c2024202354ad7c200241f0076a41086a2903007c2017202454ad7c2018201754ad7c420d86847c222242338820024190076a41086a290300200241c0066a41086a2903007c201d202c54ad7c20024180096a41086a2903007c201e201d54ad7c200241b0086a41086a2903007c201f201e54ad7c200241e0076a41086a2903007c2021201f54ad7c2022202154ad7c420d86847c221d42338820024180076a41086a29030020024190056a41086a2903007c2005202b54ad7c200241f0086a41086a2903007c200b200554ad7c200241a0086a41086a2903007c2013200b54ad7c200241d0076a41086a2903007c201c201354ad7c201d201c54ad7c420d86847c220b42ffffffffffffff0383220542002012420010d507200241f0006a200b423388200241f0066a41086a290300200241e0036a41086a2903007c2003202a54ad7c200241e0086a41086a2903007c2004200354ad7c20024190086a41086a2903007c2006200454ad7c200241c0076a41086a2903007c2007200654ad7c200b200754ad7c420d868442137e201b42ffffffffffffff03837c220442ffffffffffffff038322034200200a420010d507200241d0046a201d42ffffffffffffff0383220742002015420010d50720024180066a202242ffffffffffffff038322064200200c420010d50720024190026a2004423388201842ffffffffffffff03837c22044200200e420010d50720024190036a200542002020420010d50720024180016a200e42002003420010d507200241c0046a200742002012420010d507200241f0056a200642002015420010d507200241a0026a20044200200c420010d507200241b0036a200542002015420010d507200241e0006a200342002010420010d507200241e0046a20074200200c420010d50720024190066a20064200200e420010d50720024180026a20044200200a420010d507200241a0056a200d4200200642137e2212420010d507200241e0026a200842002004420010d50720024180046a20114200200742137e220b420010d507200241206a200f4200200542137e2215420010d507200241c0016a200942002003420010d507200241d0016a200342002008420010d507200241f0026a200d4200200442137e420010d507200241b0056a201142002012420010d50720024190046a200f4200200b420010d507200241306a200942002015420010d507200241c0056a200842002006420010d507200241f0036a200d4200200b420010d507200241106a201142002015420010d507200241b0016a200f42002003420010d507200241d0026a200942002004420010d507200241c0036a20054200200c420010d507200241d0006a200342002014420010d507200241f0046a20074200200e420010d507200241a0066a20064200200a420010d507200241f0016a200442002010420010d507200241a0046a200842002007420010d5072002200d42002015420010d507200241a0016a201142002003420010d507200241c0026a200f42002004420010d507200241d0056a200942002006420010d507200241d0036a20054200200e420010d507200241c0006a200342002016420010d50720024180056a20074200200a420010d507200241b0066a200642002010420010d507200241e0016a200442002014420010d50720024180036a200842002005420010d50720024190016a200d42002003420010d507200241b0026a201142002004420010d507200241e0056a200f42002006420010d507200241b0046a200942002007420010d50720004188016a20022903b012221320022903f00f7c220320022903e0137c220a2002290390157c22042002290390117c220920022903c012220c2002290380107c220620022903f0137c220720022903a0157c220520022903a0117c220820022903d012220d2002290390107c220e2002290380147c220f20022903b0157c221020022903b0117c2211423388200241d0126a41086a29030020024190106a41086a2903007c200e200d54ad7c20024180146a41086a2903007c200f200e54ad7c200241b0156a41086a2903007c2010200f54ad7c200241b0116a41086a2903007c2011201054ad7c420d86847c220e423388200241c0126a41086a29030020024180106a41086a2903007c2006200c54ad7c200241f0136a41086a2903007c2007200654ad7c200241a0156a41086a2903007c2005200754ad7c200241a0116a41086a2903007c2008200554ad7c200e200854ad7c420d86847c220642ffffffffffffff03833703002000200229038013221c20022903c0107c220720022903b0147c220520022903e0157c220820022903e0117c220f200229039013221d20022903d0107c221020022903c0147c220c20022903f0157c220d20022903f0117c221420022903a013221e20022903e0107c221520022903d0147c22162002290380167c220b2002290380127c2212423388200241a0136a41086a290300200241e0106a41086a2903007c2015201e54ad7c200241d0146a41086a2903007c2016201554ad7c20024180166a41086a2903007c200b201654ad7c20024180126a41086a2903007c2012200b54ad7c420d86847c221542338820024190136a41086a290300200241d0106a41086a2903007c2010201d54ad7c200241c0146a41086a2903007c200c201054ad7c200241f0156a41086a2903007c200d200c54ad7c200241f0116a41086a2903007c2014200d54ad7c2015201454ad7c420d86847c221042ffffffffffffff038337031020004190016a20022903a012220b20022903e00f7c220c20022903d0137c220d2002290380157c22142002290380117c22162006423388200241b0126a41086a290300200241f00f6a41086a2903007c2003201354ad7c200241e0136a41086a2903007c200a200354ad7c20024190156a41086a2903007c2004200a54ad7c20024190116a41086a2903007c2009200454ad7c2006200954ad7c420d86847c220342ffffffffffffff0383370300200020022903f012221320022903b0107c220a20022903a0147c220420022903d0157c220920022903d0117c2206201042338820024180136a41086a290300200241c0106a41086a2903007c2007201c54ad7c200241b0146a41086a2903007c2005200754ad7c200241e0156a41086a2903007c2008200554ad7c200241e0116a41086a2903007c200f200854ad7c2010200f54ad7c420d86847c220742ffffffffffffff038337031820004198016a200229039012221c20022903d00f7c220520022903c0137c220820022903f0147c220f20022903f0107c22102003423388200241a0126a41086a290300200241e00f6a41086a2903007c200c200b54ad7c200241d0136a41086a2903007c200d200c54ad7c20024180156a41086a2903007c2014200d54ad7c20024180116a41086a2903007c2016201454ad7c2003201654ad7c420d86847c220342ffffffffffffff0383370300200020022903e012220b20022903a0107c220c2002290390147c220d20022903c0157c221420022903c0117c22162007423388200241f0126a41086a290300200241b0106a41086a2903007c200a201354ad7c200241a0146a41086a2903007c2004200a54ad7c200241d0156a41086a2903007c2009200454ad7c200241d0116a41086a2903007c2006200954ad7c2007200654ad7c420d86847c220a42ffffffffffffff03833703202000200342338820024190126a41086a290300200241d00f6a41086a2903007c2005201c54ad7c200241c0136a41086a2903007c2008200554ad7c200241f0146a41086a2903007c200f200854ad7c200241f0106a41086a2903007c2010200f54ad7c2003201054ad7c420d868442137e201142ffffffffffffff03837c220342ffffffffffffff03833703782000200a423388200241e0126a41086a290300200241a0106a41086a2903007c200c200b54ad7c20024190146a41086a2903007c200d200c54ad7c200241c0156a41086a2903007c2014200d54ad7c200241c0116a41086a2903007c2016201454ad7c200a201654ad7c420d868442137e201242ffffffffffffff03837c220a42ffffffffffffff038337030020004180016a2003423388200e42ffffffffffffff03837c3703002000200a423388201542ffffffffffffff03837c370308200041e0006a20022903b003221320022903607c220320022903e0047c220a2002290390067c22042002290380027c220920022903a003220c20022903707c220620022903d0047c22072002290380067c22052002290390027c2208200229039003220d2002290380017c220e20022903c0047c220f20022903f0057c221020022903a0027c221142338820024190036a41086a29030020024180016a41086a2903007c200e200d54ad7c200241c0046a41086a2903007c200f200e54ad7c200241f0056a41086a2903007c2010200f54ad7c200241a0026a41086a2903007c2011201054ad7c420d86847c220e423388200241a0036a41086a290300200241f0006a41086a2903007c2006200c54ad7c200241d0046a41086a2903007c2007200654ad7c20024180066a41086a2903007c2005200754ad7c20024190026a41086a2903007c2008200554ad7c200e200854ad7c420d86847c220642ffffffffffffff0383370300200041386a20022903f003221c20022903c0057c220720022903107c220520022903b0017c220820022903d0027c220f20022903a005221d20022903e0027c22102002290380047c220c20022903207c220d20022903c0017c221420022903f002221e20022903d0017c221520022903b0057c22162002290390047c220b20022903307c2212423388200241f0026a41086a290300200241d0016a41086a2903007c2015201e54ad7c200241b0056a41086a2903007c2016201554ad7c20024190046a41086a2903007c200b201654ad7c200241306a41086a2903007c2012200b54ad7c420d86847c2215423388200241a0056a41086a290300200241e0026a41086a2903007c2010201d54ad7c20024180046a41086a2903007c200c201054ad7c200241206a41086a2903007c200d200c54ad7c200241c0016a41086a2903007c2014200d54ad7c2015201454ad7c420d86847c221042ffffffffffffff0383370300200041e8006a20022903c003220b20022903507c220c20022903f0047c220d20022903a0067c221420022903f0017c22162006423388200241b0036a41086a290300200241e0006a41086a2903007c2003201354ad7c200241e0046a41086a2903007c200a200354ad7c20024190066a41086a2903007c2004200a54ad7c20024180026a41086a2903007c2009200454ad7c2006200954ad7c420d86847c220342ffffffffffffff0383370300200041c0006a2002290300221320022903a0047c220a20022903a0017c220420022903c0027c220920022903d0057c22062010423388200241f0036a41086a290300200241c0056a41086a2903007c2007201c54ad7c200241106a41086a2903007c2005200754ad7c200241b0016a41086a2903007c2008200554ad7c200241d0026a41086a2903007c200f200854ad7c2010200f54ad7c420d86847c220742ffffffffffffff0383370300200041f0006a20022903d003221c20022903407c22052002290380057c220820022903b0067c220f20022903e0017c22102003423388200241c0036a41086a290300200241d0006a41086a2903007c200c200b54ad7c200241f0046a41086a2903007c200d200c54ad7c200241a0066a41086a2903007c2014200d54ad7c200241f0016a41086a2903007c2016201454ad7c2003201654ad7c420d86847c220342ffffffffffffff0383370300200041c8006a200229039001220b2002290380037c220c20022903b0027c220d20022903e0057c221420022903b0047c22162007423388200241086a290300200241a0046a41086a2903007c200a201354ad7c200241a0016a41086a2903007c2004200a54ad7c200241c0026a41086a2903007c2009200454ad7c200241d0056a41086a2903007c2006200954ad7c2007200654ad7c420d86847c220a42ffffffffffffff038337030020002003423388200241d0036a41086a290300200241c0006a41086a2903007c2005201c54ad7c20024180056a41086a2903007c2008200554ad7c200241b0066a41086a2903007c200f200854ad7c200241e0016a41086a2903007c2010200f54ad7c2003201054ad7c420d868442137e201142ffffffffffffff03837c220342ffffffffffffff0383370350200041d8006a2003423388200e42ffffffffffffff03837c3703002000200a42338820024190016a41086a29030020024180036a41086a2903007c200c200b54ad7c200241b0026a41086a2903007c200d200c54ad7c200241e0056a41086a2903007c2014200d54ad7c200241b0046a41086a2903007c2016201454ad7c200a201654ad7c420d868442137e201242ffffffffffffff03837c220342ffffffffffffff0383370328200041306a2003423388201542ffffffffffffff03837c370300200241a02a6a24000b911d05027f137e017f0f7e017f230041c0056b2202240002400240024020012c001f22034100480d0020022001290000220437038005200241f0046a200231008605423086200231008505422886200231008405422086200231008305421886200231008205421086200231008105420886200442ff0183848484848484220542ffffffffffffff07832204420042edcd87b9d697d207420010d507200241e0046a20022903f0042206429bfcd192b1b4c7027e42ffffffffffffff07832207420042eda7d7e7a5e39801420010d507200241b0046a2004420042dac89fe3dad6ee01420010d50720024180056a41086a200141086a2900002208370300200241f0036a200231008c05422086200231008b05421886200231008a05421086200231008905420886200842ff0183848484842208420c864280e0ffffffffff0783200231008705423886200584423488842205420042edcd87b9d697d207420010d507200241d0046a200742004281cbb5cef7c5fa06420010d507200241e0036a20022903f003220920022903b0047c220a20022903d0047c220b200620022903e004220c7c2206423488200241e0046a41086a290300200241f0046a41086a2903007c2006200c54ad7c220d420c86847c220c429bfcd192b1b4c7027e42ffffffffffffff07832206420042eda7d7e7a5e39801420010d507200241a0046a20044200429bcad7d9feffff07420010d507200241b0036a2005420042dac89fe3dad6ee01420010d50720024180056a41106a200141106a290000220e370300200241f0026a200231009305421886200231009205421086200231009105420886200e42ff0183848484220f42188642808080f8ffffff0783200231008f05423886200231008e05423086200231008d054228862008848484422888842208420042edcd87b9d697d207420010d507200241c0046a2007420042f9bdd300420010d507200241d0036a200642004281cbb5cef7c5fa06420010d507200241e0026a20022903b003221020022903a0047c220e20022903f0027c221120022903c0047c221220022903d0037c221320022903e0032214200c7c2215423488200241e0036a41086a290300200241f0036a41086a290300200241b0046a41086a2903007c200a200954ad7c200241d0046a41086a2903007c200b200a54ad7c200d4234887c200c200b54ad7c7c2015201454ad7c2216420c86847c220c429bfcd192b1b4c7027e42ffffffffffffff0783220a420042eda7d7e7a5e39801420010d50720024190046a2004420042ffffffffffffff07420010d507200241a0036a20054200429bcad7d9feffff07420010d507200241b0026a2008420042dac89fe3dad6ee01420010d50720024180056a41176a2217200141176a290000370000200241f0016a2002310099054208862002310098058422184224862017310000423886200231009605423086200231009505422886200231009405422086200f84848484421c8884220b420042edcd87b9d697d207420010d507200241c0036a2006420042f9bdd300420010d507200241d0026a200a42004281cbb5cef7c5fa06420010d507200241e0016a20022903a00322192002290390047c220920022903b0027c220d20022903f0017c220f20022903c0037c221420022903d0027c221520022903e002221a200c7c221b423488200241e0026a41086a290300200241b0036a41086a290300200241a0046a41086a2903007c200e201054ad7c200241f0026a41086a2903007c2011200e54ad7c200241c0046a41086a2903007c2012201154ad7c200241d0036a41086a2903007c2013201254ad7c20164234887c200c201354ad7c7c201b201a54ad7c221b420c86847c220e429bfcd192b1b4c7027e42ffffffffffffff0783220c420042eda7d7e7a5e39801420010d50720024180046a2004420042ffffffffffff03420010d50720024190036a2005420042ffffffffffffff07420010d507200241a0026a20084200429bcad7d9feffff07420010d507200241b0016a200b420042dac89fe3dad6ee01420010d507200241f0006a2003ad42ff0083423886200231009e05423086200231009d05422886200231009c05422086200231009b05421886200231009a0542108620188484848484844210882204420042edcd87b9d697d207420010d507200241c0026a200a420042f9bdd300420010d507200241d0016a200c42004281cbb5cef7c5fa06420010d507200241e0006a200229039003221c2002290380047c221120022903a0027c221220022903b0017c221320022903707c22102007422c867c221620022903c0027c221820022903d0017c221a20022903e001221d200e7c221e423488200241e0016a41086a290300200241a0036a41086a29030020024190046a41086a2903007c2009201954ad7c200241b0026a41086a2903007c200d200954ad7c200241f0016a41086a2903007c200f200d54ad7c200241c0036a41086a2903007c2014200f54ad7c200241d0026a41086a2903007c2015201454ad7c201b4234887c200e201554ad7c7c201e201d54ad7c221f420c86847c2209429bfcd192b1b4c7027e42ffffffffffffff0783220e420042eda7d7e7a5e39801420010d50720024180036a2005420042ffffffffffff03420010d50720024190026a2008420042ffffffffffffff07420010d507200241a0016a200b4200429bcad7d9feffff07420010d507200241306a2004420042dac89fe3dad6ee01420010d507200241c0016a200c420042f9bdd300420010d507200241d0006a200e42004281cbb5cef7c5fa06420010d50720024180026a2008420042ffffffffffff03420010d50720024190016a200b420042ffffffffffffff07420010d507200241206a20044200429bcad7d9feffff07420010d507200241c0006a200e420042f9bdd300420010d507200241106a2004420042ffffffffffffff07420010d50720024180016a200b420042ffffffffffff03420010d50720022004420042ffffffffffff03420010d5072002200341ff00713a009f052002200e422c86222020022903007c2204200229031022212002290380017c2205200c422c867c220820022903900122222002290380027c220b20022903207c220d200a422c867c220f20022903407c221420022903900222232002290380037c221520022903a0017c221920022903307c221b2006422c867c221d20022903c0017c221e20022903507c22242002290360222520097c2226423488200241e0006a41086a29030020024190036a41086a29030020024180046a41086a2903007c2011201c54ad7c200241a0026a41086a2903007c2012201154ad7c200241b0016a41086a2903007c2013201254ad7c200241f0006a41086a2903007c2010201354ad7c20074214887c2016201054ad7c200241c0026a41086a2903007c2018201654ad7c200241d0016a41086a2903007c201a201854ad7c201f4234887c2009201a54ad7c7c2026202554ad7c2211420c86847c220742348820024190026a41086a29030020024180036a41086a2903007c2015202354ad7c200241a0016a41086a2903007c2019201554ad7c200241306a41086a2903007c201b201954ad7c20064214887c201d201b54ad7c200241c0016a41086a2903007c201e201d54ad7c200241d0006a41086a2903007c2024201e54ad7c20114234887c2007202454ad7c2211420c86847c220642348820024190016a41086a29030020024180026a41086a2903007c200b202254ad7c200241206a41086a2903007c200d200b54ad7c200a4214887c200f200d54ad7c200241c0006a41086a2903007c2014200f54ad7c20114234887c2006201454ad7c220b420c86847c220a423488200241106a41086a29030020024180016a41086a2903007c2005202154ad7c200c4214887c2008200554ad7c200b4234887c200a200854ad7c2208420c86847c2205423488200e421488200241086a2903007c2004202054ad7c20084234887c2005200454ad7c420c8684200542ffffffffffffff0783200a42ffffffffffffff0783200642ffffffffffffff0783200742ffffffffffffff07834293d8a898da9ce77e7c2204423f877c42ffb4cab188ba85797c2207423f877c4287c2ac7f7c2205423f877c2208423f877c428080808080807c7c220a423f87220642eda7d7e7a5e3980183200442ffffffffffffff07837c22043c00a005200220044228883c00a505200220044220883c00a405200220044218883c00a305200220044210883c00a205200220044208883c00a105200220064281cbb5cef7c5fa0683200742ffffffffffffff07837c20044234887c2207422c883c00ac05200220074224883c00ab0520022007421c883c00aa05200220074214883c00a90520022007420c883c00a805200220074204883c00a705200220074204862004423088420f83843c00a6052002200642f9bdd30083200542ffffffffffffff07837c20074234887c22073c00ad05200220074228883c00b205200220074220883c00b105200220074218883c00b005200220074210883c00af05200220074208883c00ae0520022007423488200842ffffffffffffff07837c2205422c883c00b905200220054224883c00b80520022005421c883c00b705200220054214883c00b60520022005420c883c00b505200220054204883c00b405200220054204862007423088420f83843c00b30520022006428080808080800483200a7c20054234887c22073c00ba05200220074228883c00bf05200220074220883c00be05200220074218883c00bd05200220074210883c00bc05200220074208883c00bb052004a72117200241a0056a410172212741002101410121030340201720024180056a20016a2d0000732217410020176b72417f7341800171410776106d20037121032001411f460d02202720016a2d00002117200141016a21010c000b0b200041003a00000c010b4100210102402003106d41ff01714101470d002000200229038005370001200041196a20024198056a290300370000200041116a20024190056a290300370000200041096a20024188056a290300370000410121010b200020013a00000b200241c0056a24000bff0101037f200028020421020240024020002802004101470d002000410c6a2802002200200110712000450d01200041186c2103200241146a21000340200041706a2802002102200041746a28020022042001107120012002200410722000417c6a280200210220002802002204200110712001200220041072200041186a2100200341686a22030d000c020b0b200041086a2802002200200110712000450d00200041186c2103200241146a21000340200041706a2802002102200041746a28020022042001107120012002200410722000417c6a280200210220002802002204200110712001200220041072200041186a2100200341686a22030d000b0b0bab0101017f230041106b220224000240024002400240200041c000490d00200041808001490d012000418080808004490d02200241033a00032001200241036a41011072200220003602042001200241046a410410720c030b200220004102743a00032001200241036a410110720c020b200220004102744101723b010a20012002410a6a410210720c010b2002200041027441027236020c20012002410c6a410410720b200241106a24000bcd0101047f0240024002400240200041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422062005200620054b1b22064100480d010240024020030d00024020060d00410121050c020b2006102722050d010c040b2000280200210520032006460d00200520032006102b2205450d03200041086a28020021040b20002005360200200041046a20063602000b200520046a2001200210e4071a200041086a200420026a3602000f0b1032000b1030000bb30101037f200028020421020240024020002802004101470d002000410c6a28020022002001107120004103742200450d01200220006a2103034020022802002100200241046a2802002204200110712001200020041072200241086a22022003470d000c020b0b200041086a28020022002001107120004103742200450d00200220006a2103034020022802002100200241046a2802002204200110712001200020041072200241086a22022003470d000b0b0ba90701057f230041206b2203240020012002107102402001450d00200141d8006c2104410021050340200020056a220141046a2802002106200141086a28020022072002107120022006200710722003200141d4006a2d00003a000d20022003410d6a4101107202402001410c6a2d0000220641024b0d0002400240024020060e03000102000b200341003a000e20022003410e6a41011072200141146a2802002106200141186a28020022072002107120022006200710720c020b200341013a000e20022003410e6a4101107202402001410d6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110720b200141146a2802002106200141186a2802002207200210712002200620071072200141206a2802002106200141246a280200220720021071200220062007107220032001410e6a2d00003a000e20022003410e6a410110720c010b200341023a000e20022003410e6a4101107202402001410d6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110720b200141146a2802002106200141186a2802002207200210712002200620071072200141206a2802002106200141246a28020022072002107120022006200710722001412c6a2802002106200141306a28020022072002107120022006200710722001410e6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110720b02400240200141346a2802004101470d00200141386a2802002106200141c0006a28020022072002107120022006200710720c010b200341106a200141386a2802002001413c6a28020028020c11020020032802102106200328021822072002107120022006200710722003280214450d00200610290b200141c4006a200210732004200541d8006a2205470d000b0b200341206a24000b8605010e7f2001410c6a2802002102200128020821032001280204210402400240024002400240024002400240200128020022050d0020030d010c060b200420056b2101024020030d00200121060c020b2001200220036b6a220620014f0d010240024020042005460d00200541016a21070c010b20022003460d064100210720032105200341016a21030b4100210841002106410121090340200420076b210a2008410174210b20022003220c6b210d410021010340200720016a210e20052d000021030240200820016a22052006470d002005417f417f2004200e6b2206200d6a220f200f2006491b200d200e1b220641016a220f200f2006491b6a22062005490d06200b2006200b20064b1b22064100480d06024020050d00024020060d00410121090c020b2006102722090d010c080b20052006460d00200920052006102b2209450d070b200920086a20016a20033a00000240200e450d00200a2001460d00200b41026a210b200141016a2101200e21050c010b0b200c2002460d03200541016a2108200c41016a210341002107200c21050c000b0b200220036b21060b0240024020060d00410121090c010b20064100480d02200610272209450d030b4100210b0240024020050d00200921010c010b024020042005470d00200921010c010b200921012005210e03402001200e2d00003a0000200141016a21012004200e41016a220e470d000b200420056b210b0b2003450d0420022003460d042003210e03402001200e2d00003a0000200141016a21012002200e41016a220e470d000b2002200b20036b6a210b0c040b200541016a210b0c030b1032000b1030000b410121094100210b410021060b2000200b36020820002006360204200020093602000bd40101037f02400240024002402000280200220041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004102722050d010c040b2000280200210520032004460d00200520032004102b2205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a2001200210e4071a200041086a200420026a36020041000f0b1032000b1030000bbf0301047f230041106b22022400200028020021002002410036020c02400240024002402001418001490d002001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b0240024002400240200041046a2802002203200041086a28020022046b2001490d00200028020021050c010b200420016a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004102722050d010c040b2000280200210520032004460d00200520032004102b2205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a2002410c6a200110e4071a200041086a200420016a360200200241106a240041000f0b1032000b1030000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41e0a0c000200241086a10372101200241206a240020010bcd0101037f0240024002400240200041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004102722050d010c040b2000280200210520032004460d00200520032004102b2205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a2001200210e4071a200041086a200420026a3602000f0b1032000b1030000b040041010bb60101017f230041c0006b2202240020024100360210200242013703082002410836021c20022001410c6a3602202002200241206a3602182002200241086a3602242002413c6a41013602002002420137022c200241a893cc003602282002200241186a360238200241246a41e0a0c000200241286a10371a20012d0000417f6a41ff0171200141046a290200200235021042208620023502088410000240200228020c450d00200228020810290b200241c0006a24000ba90803197e017f147e20002903c0012101200029039801210220002903702103200029034821042000290320210520002903b8012106200029039001210720002903682108200029034021092000290318210a20002903b001210b200029038801210c2000290360210d2000290338210e2000290310210f20002903a8012110200029038001211120002903582112200029033021132000290308211420002903a00121152000290378211620002903502117200029032821182000290300211941c07e211a0340200e200f85200d85200c85200b85221b4201892018201985201785201685201585221c85221d201385211e20012009200a85200885200785200685221f201c42018985221c85212020042005852003852002852001852221420189201b85221b2009854237892222201f4201892013201485201285201185201085220985221f200f85423e892223427f8583201d201085420289222485210120222021200942018985220f20168542298922212003201c854227892225427f8583852110201b2006854238892226201f200c85420f892227427f8583201d201285420a89222885210c2028200f2018854224892229427f8583201c200585421b89222a852116200f2015854212892215201f200e85420689222b201d201485420189222c427f85838521032002201c85420889222d201b200885421989222e427f8583202b8521122004201c85421489221c201b200a85421c89220a427f8583201f200b85423d89220e852104200a200e427f8583201d201185422d89221d852109200f2017854203892214200e201d427f858385210e201d2014427f8583201c852113200a2014201c427f8583852118201b200785421589221d200f201985221c2020420e89221b427f858385210a201b201d427f8583201f200d85422b89221f85210f201d201f427f8583201e422c89221d852114201a4180a4c0006a290300201c201f201d427f85838585211920262029202a427f858385221f2102201d201c427f8583201b85221d2105202120232024427f858385221c2106202a2026427f8583202785221b2107202c2015427f8583202d852226210820242021427f85832025852224210b202e2015202d427f8583852221210d202920272028427f8583852227211120252022427f858320238522222115202e202b427f8583202c8522232117201a41086a221a0d000b200020223703a00120002016370378200020233703502000201837032820002019370300200020103703a8012000202737038001200020123703582000201337033020002014370308200020243703b0012000200c37038801200020213703602000200e3703382000200f3703102000201c3703b8012000201b3703900120002026370368200020093703402000200a370318200020013703c0012000201f3703980120002003370370200020043703482000201d3703200b040041000b02000b02000bae1a01027f230041a0056b2203240020034198036a41126a410041b60110e6071a200341a6036a41002800bea440360100200341002f00b4a4403b019c03200341002800b0a44036029803200341002900b6a44037019e0320034198036a107c200341d0016a20034198036a41c80110e4071a20034198036a200341d0016a41c80110e4071a200341003a00e204200341003b01e00420034198036a41124100108101024020032d00e004220441c7014b0d0020034198036a20046a220420042d000041cd00733a0000200320032d00e00441016a22043a00e00402400240200441ff0171220441a601470d00200320032d00be0420032d00e104733a00be04200320032d00bf04418401733a00bf0420034198036a107c41002104200341003b01e0040c010b200441c8014f0d010b20034198036a20046a220420042d000041e500733a0000200320032d00e00441016a22043a00e00402400240200441ff0171220441a601470d00200320032d00be0420032d00e104733a00be04200320032d00bf04418401733a00bf0420034198036a107c41002104200341003b01e0040c010b200441c7014b0d010b20034198036a20046a220420042d000041f200733a0000200320032d00e00441016a22043a00e00402400240200441ff0171220441a601470d00200320032d00be0420032d00e104733a00be04200320032d00bf04418401733a00bf0420034198036a107c41002104200341003b01e0040c010b200441c7014b0d010b20034198036a20046a220420042d000041ec00733a0000200320032d00e00441016a22043a00e00402400240200441ff0171220441a601470d00200320032d00be0420032d00e104733a00be04200320032d00bf04418401733a00bf0420034198036a107c41002104200341003b01e0040c010b200441c7014b0d010b20034198036a20046a220420042d000041e900733a0000200320032d00e00441016a22043a00e00402400240200441ff0171220441a601470d00200320032d00be0420032d00e104733a00be04200320032d00bf04418401733a00bf0420034198036a107c41002104200341003b01e0040c010b200441c7014b0d010b20034198036a20046a220420042d000041ee00733a0000200320032d00e00441016a22043a00e00402400240200441ff0171220441a601470d00200320032d00be0420032d00e104733a00be04200320032d00bf04418401733a00bf0420034198036a107c41002104200341003b01e0040c010b200441c7014b0d010b20034198036a20046a220420042d00004120733a0000200320032d00e00441016a22043a00e00402400240200441ff0171220441a601470d00200320032d00be0420032d00e104733a00be04200320032d00bf04418401733a00bf0420034198036a107c41002104200341003b01e0040c010b200441c7014b0d010b20034198036a20046a220420042d000041f600733a0000200320032d00e00441016a22043a00e00402400240200441ff0171220441a601470d00200320032d00be0420032d00e104733a00be04200320032d00bf04418401733a00bf0420034198036a107c41002104200341003b01e0040c010b200441c7014b0d010b20034198036a20046a220420042d00004131733a0000200320032d00e00441016a22043a00e00402400240200441ff0171220441a601470d00200320032d00be0420032d00e104733a00be04200320032d00bf04418401733a00bf0420034198036a107c41002104200341003b01e0040c010b200441c7014b0d010b20034198036a20046a220420042d0000412e733a0000200320032d00e00441016a22043a00e00402400240200441ff0171220441a601470d00200320032d00be0420032d00e104733a00be04200320032d00bf04418401733a00bf0420034198036a107c41002104200341003b01e0040c010b200441c7014b0d010b20034198036a20046a220420042d00004130733a0000200320032d00e00441016a22043a00e0040240200441ff017141a601470d00200320032d00be0420032d00e104733a00be04200320032d00bf04418401733a00bf0420034198036a107c200341003b01e0040b200320034198036a41d00110e407220341124100108101024020032d00c801220441c8014f0d00200320046a220420042d000041e400733a0000200320032d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c41002104200341003b01c8010c010b200441c8014f0d010b200320046a220420042d000041ef00733a0000200320032d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c41002104200341003b01c8010c010b200441c7014b0d010b200320046a220420042d000041ed00733a0000200320032d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c41002104200341003b01c8010c010b200441c7014b0d010b200320046a220420042d0000412d733a0000200320032d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c41002104200341003b01c8010c010b200441c7014b0d010b200320046a220420042d000041f300733a0000200320032d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c41002104200341003b01c8010c010b200441c7014b0d010b200320046a220420042d000041e500733a0000200320032d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c41002104200341003b01c8010c010b200441c7014b0d010b200320046a220420042d000041f000733a0000200320032d00c80141016a22043a00c8010240200441ff017141a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c41002104200341003b01c8010b200341123a00ef0402400240024020032d00ca014112470d00200441ff0171220441c801490d010c020b200341d0016a41146a4109360200200341d0016a410c6a410a3602002003200341ca016a2204360288052003200341ef046a36028c0520034198036a41146a410236020020034198036a410c6a410236020020034190056a410c6a410b3602002003410a3602d401200341dca5c0003602a0032003410236029c03200341cca5c000360298032003410b360294052003200436029005200320034198036a3602e00120032003418c056a3602d801200320034188056a3602d001200320034190056a3602a8032003200341ef046a36029805200341f0046a41146a4103360200200342033702f404200341aca5cc003602f0042003200341d0016a36028005200341f0046a419ca6c0001040000b200320046a220420042d00002002733a0000200320032d00c80141016a22043a00c80102400240200441ff017141a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c41002104200341003b01c8010c010b200441ff0171220441c8014f0d010b200320046a220420042d00002002410876733a0000200320032d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c41002104200341003b01c8010c010b200441c7014b0d010b200320046a220420042d00002002411076733a0000200320032d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c41002104200341003b01c8010c010b200441c7014b0d010b200320046a220420042d00002002411876733a0000200320032d00c80141016a22043a00c8010240200441ff017141a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c200341003b01c8010b20034102410010810120032d00c801210402400340200441ff0171220441c7014b0d01200320046a220420042d000020012d0000733a0000200320032d00c80141016a22043a00c8010240200441ff017141a601470d00200320032d00a60120032d00c901733a00a601200320032d00a701418401733a00a7012003107c41002104200341003b01c8010b200141016a21012002417f6a22020d000b2000200341d00110e4071a200341a0056a24000f0b200441c80141c4a4c0001036000b200441c80141c4a4c0001036000b200441c80141c4a4c0001036000b200441c80141c4a4c0001036000b9a0701027f230041f0006b22032400200320013a000b024002400240024002400240024020020d002003200141087122023a000c20020d03200020013a00ca0120002d00c9012104200020002d00c801220241016a3a00c901200241c7014b0d02200020026a220220022d00002004733a0000200020002d00c80141016a22023a00c801200241ff0171220241a601470d01200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c41002102200041003b01c8010c050b20002d00ca01200141ff0171470d030c050b200241c801490d030b200241c80141c4a4c0001036000b200341386a41146a4109360200200341c4006a410a360200200341206a41146a410336020020032003410c6a360254200341b4e0c800360210200341d8006a41146a410036020020034203370224200341aca5cc003602202003410a36023c20034180a6cc003602682003420137025c200341aca6c0003602582003200341386a3602302003200341d8006a3602482003200341106a3602402003200341d4006a360238200341206a41b4a6c0001040000b200341386a41146a4109360200200341386a410c6a410a3602002003200041ca016a220036020c20032003410b6a360254200341d8006a41146a4102360200200341d8006a410c6a4102360200200341106a410c6a410b3602002003410a36023c200341dca5c0003602602003410236025c200341cca5c0003602582003410b360214200320003602102003200341d8006a3602482003200341d4006a36024020032003410c6a3602382003200341106a36026820032003410b6a360218200341206a41146a410336020020034203370224200341aca5cc003602202003200341386a360230200341206a419ca6c0001040000b200020026a220220022d00002001733a0000200020002d00c80141016a22023a00c8010240200241ff0171220441a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c200041003b01c8010c010b2004450d002001412471450d0002400240200241ff0171220141c7014b0d00200020016a220120012d000020002d00c901733a000020002d00c80141016a41ff0171220141c8014f0d01200020016a220120012d00004104733a0000200020002d00a701418001733a00a7012000107c200041003b01c8010c020b200141c80141c4a6c0001036000b200141c80141d4a6c0001036000b200341f0006a24000bc40201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff01832001104621000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d02200141b88ac0004102200220006a4180016a410020006b104921000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d02200141b88ac0004102200220006a4180016a410020006b104921000b20024180016a240020000f0b200441800141a88ac000104c000b200441800141a88ac000104c000bec0801027f230041f0006b22052400200041124100108101024002400240024002402002450d0020002d00c80121060340200641ff0171220641c7014b0d02200020066a220620062d000020012d0000733a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c41002106200041003b01c8010b200141016a21012002417f6a22020d000b0b200541123a000f20002d00ca014112470d0120002d00c801220641c7014b0d03200020066a220620062d00002004733a0000200020002d00c80141016a22063a00c8010240200641ff0171220641a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c41002106200041003b01c8010c030b200641c801490d020c030b200641c80141c4a4c0001036000b200541286a41146a4109360200200541286a410c6a410a3602002005200041ca016a220036024020052005410f6a360244200541c8006a41146a4102360200200541c8006a410c6a4102360200200541e0006a410c6a410b3602002005410a36022c200541dca5c0003602502005410236024c200541cca5c0003602482005410b360264200520003602602005200541c8006a3602382005200541c4006a3602302005200541c0006a3602282005200541e0006a36025820052005410f6a360268200541106a41146a410336020020054203370214200541aca5cc003602102005200541286a360220200541106a419ca6c0001040000b200020066a220620062d00002004410876733a0000200020002d00c80141016a22063a00c80102400240200641ff0171220641a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c41002106200041003b01c8010c010b200641c7014b0d010b200020066a220620062d00002004411076733a0000200020002d00c80141016a22063a00c80102400240200641ff0171220641a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c41002106200041003b01c8010c010b200641c7014b0d010b200020066a220620062d00002004411876733a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c200041003b01c8010b200041024100108101024002402004450d0020002d00c80121060340200641ff0171220641c7014b0d02200020066a220620062d000020032d0000733a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c41002106200041003b01c8010b200341016a21032004417f6a22040d000b0b200541f0006a24000f0b200641c80141c4a4c0001036000b200641c80141c4a4c0001036000be50e010a7f230041f0006b220424002000411241001081012003422888a721052003422088a721062003421888a721072003421088a721082003420888a721092003423888a7210a2003423088a7210b2003a7210c20002d00c801210d024002400240024002400340200d41ff0171220d41c7014b0d012000200d6a220d200d2d000020012d0000733a0000200020002d00c80141016a220d3a00c8010240200d41ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c4100210d200041003b01c8010b200141016a21012002417f6a22020d000b200441123a000f20002d00ca014112470d01200d41ff0171220141c7014b0d04200020016a220d200d2d00004108733a000041012101200020002d00c80141016a220d3a00c80102400240024002400240200d41ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c0c010b200d41ff0171220141c8014f0d082000200d41016a220d3a00c801200d41ff017141a601470d01200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c410021010b200020013b01c8012000200141016a220d3a00c8010c010b200d41ff0171220141c8014f0d062000200d41016a220d3a00c8010240200d41ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c200041013b01c8010c020b200d41ff0171220141c7014b0d060b2000200d41016a220d3a00c801200d41ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c200041003b01c8010b20004102410010810120002d00c801220d41c801490d020c030b200d41c80141c4a4c0001036000b200441286a41146a4109360200200441286a410c6a410a3602002004200041ca016a220036024020042004410f6a360244200441c8006a41146a4102360200200441c8006a410c6a4102360200200441e0006a410c6a410b3602002004410a36022c200441dca5c0003602502004410236024c200441cca5c0003602482004410b360264200420003602602004200441c8006a3602382004200441c4006a3602302004200441c0006a3602282004200441e0006a36025820042004410f6a360268200441106a41146a410336020020044203370214200441aca5cc003602102004200441286a360220200441106a419ca6c0001040000b2000200d6a220d200d2d0000200c733a0000200020002d00c80141016a220d3a00c80102400240200d41ff0171220d41a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c4100210d200041003b01c8010c010b200d41c8014f0d010b2000200d6a220d200d2d00002009733a0000200020002d00c80141016a220d3a00c80102400240200d41ff0171220d41a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c4100210d200041003b01c8010c010b200d41c7014b0d010b2000200d6a220d200d2d00002008733a0000200020002d00c80141016a220d3a00c80102400240200d41ff0171220d41a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c4100210d200041003b01c8010c010b200d41c7014b0d010b2000200d6a220d200d2d00002007733a0000200020002d00c80141016a220d3a00c80102400240200d41ff0171220d41a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c4100210d200041003b01c8010c010b200d41c7014b0d010b2000200d6a220d200d2d00002006733a0000200020002d00c80141016a220d3a00c80102400240200d41ff0171220d41a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c4100210d200041003b01c8010c010b200d41c7014b0d010b2000200d6a220d200d2d00002005733a0000200020002d00c80141016a220d3a00c80102400240200d41ff0171220d41a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c4100210d200041003b01c8010c010b200d41c7014b0d010b2000200d6a220d200d2d0000200b733a0000200020002d00c80141016a220d3a00c80102400240200d41ff0171220d41a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c4100210d200041003b01c8010c010b200d41c7014b0d010b2000200d6a220d200d2d0000200a733a0000200020002d00c80141016a220d3a00c8010240200d41ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c200041003b01c8010b200441f0006a24000f0b200d41c80141c4a4c0001036000b200141c80141c4a4c0001036000b8a0901027f230041f0006b2205240020004112410010810102400240024002402002450d0020002d00c80121060340200641ff0171220641c7014b0d02200020066a220620062d000020012d0000733a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c41002106200041003b01c8010b200141016a21012002417f6a22020d000b0b200541123a000f20002d00ca014112470d0120002d00c801220641c7014b0d02200020066a220620062d00002004733a0000200020002d00c80141016a22063a00c80102400240200641ff0171220641a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c41002106200041003b01c8010c010b200641c8014f0d030b200020066a220620062d00002004410876733a0000200020002d00c80141016a22063a00c80102400240200641ff0171220641a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c41002106200041003b01c8010c010b200641c7014b0d030b200020066a220620062d00002004411076733a0000200020002d00c80141016a22063a00c80102400240200641ff0171220641a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c41002106200041003b01c8010c010b200641c7014b0d030b200020066a220620062d00002004411876733a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c200041003b01c8010b2000410741001081010240024002402004450d0020002d00c80121060340200641ff0171220641c7014b0d022003200020066a2d00003a000020002d00c801220641c7014b0d03200020066a41003a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000107c41002106200041003b01c8010b200341016a21032004417f6a22040d000b0b200541f0006a24000f0b200641c80141aca5c0001036000b200641c80141bca5c0001036000b200641c80141c4a4c0001036000b200541286a41146a4109360200200541286a410c6a410a3602002005200041ca016a220036024020052005410f6a360244200541c8006a41146a4102360200200541c8006a410c6a4102360200200541e0006a410c6a410b3602002005410a36022c200541dca5c0003602502005410236024c200541cca5c0003602482005410b360264200520003602602005200541c8006a3602382005200541c4006a3602302005200541c0006a3602282005200541e0006a36025820052005410f6a360268200541106a41146a410336020020054203370214200541aca5cc003602102005200541286a360220200541106a419ca6c0001040000b200641c80141c4a4c0001036000bc20b00200041003a0000200041003a0001200041003a0002200041003a0003200041003a0004200041003a0005200041003a0006200041003a0007200041003a0008200041003a0009200041003a000a200041003a000b200041003a000c200041003a000d200041003a000e200041003a000f200041003a0010200041003a0011200041003a0012200041003a0013200041003a0014200041003a0015200041003a0016200041003a0017200041003a0018200041003a0019200041003a001a200041003a001b200041003a001c200041003a001d200041003a001e200041003a001f200041003a0020200041003a0021200041003a0022200041003a0023200041003a0024200041003a0025200041003a0026200041003a0027200041003a0028200041003a0029200041003a002a200041003a002b200041003a002c200041003a002d200041003a002e200041003a002f200041003a0030200041003a0031200041003a0032200041003a0033200041003a0034200041003a0035200041003a0036200041003a0037200041003a0038200041003a0039200041003a003a200041003a003b200041003a003c200041003a003d200041003a003e200041003a003f200041003a0040200041003a0041200041003a0042200041003a0043200041003a0044200041003a0045200041003a0046200041003a0047200041003a0048200041003a0049200041003a004a200041003a004b200041003a004c200041003a004d200041003a004e200041003a004f200041003a0050200041003a0051200041003a0052200041003a0053200041003a0054200041003a0055200041003a0056200041003a0057200041003a0058200041003a0059200041003a005a200041003a005b200041003a005c200041003a005d200041003a005e200041003a005f200041003a0060200041003a0061200041003a0062200041003a0063200041003a0064200041003a0065200041003a0066200041003a0067200041003a0068200041003a0069200041003a006a200041003a006b200041003a006c200041003a006d200041003a006e200041003a006f200041003a0070200041003a0071200041003a0072200041003a0073200041003a0074200041003a0075200041003a0076200041003a0077200041003a0078200041003a0079200041003a007a200041003a007b200041003a007c200041003a007d200041003a007e200041003a007f200041003a008001200041003a008101200041003a008201200041003a008301200041003a008401200041003a008501200041003a008601200041003a008701200041003a008801200041003a008901200041003a008a01200041003a008b01200041003a008c01200041003a008d01200041003a008e01200041003a008f01200041003a009001200041003a009101200041003a009201200041003a009301200041003a009401200041003a009501200041003a009601200041003a009701200041003a009801200041003a009901200041003a009a01200041003a009b01200041003a009c01200041003a009d01200041003a009e01200041003a009f01200041003a00a001200041003a00a101200041003a00a201200041003a00a301200041003a00a401200041003a00a501200041003a00a601200041003a00a701200041003a00a801200041003a00a901200041003a00aa01200041003a00ab01200041003a00ac01200041003a00ad01200041003a00ae01200041003a00af01200041003a00b001200041003a00b101200041003a00b201200041003a00b301200041003a00b401200041003a00b501200041003a00b601200041003a00b701200041003a00b801200041003a00b901200041003a00ba01200041003a00bb01200041003a00bc01200041003a00bd01200041003a00be01200041003a00bf01200041003a00c001200041003a00c101200041003a00c201200041003a00c301200041003a00c401200041003a00c501200041003a00c601200041003a00c7010b1c00200128021841b09bcc00410f2001411c6a28020028020c1100000ba00201067f410021020240200141016a2203200028020422044d0d000240200041146a22052802002201200041106a280200470d000240024002400240200141016a22022001490d00200141017422062002200620024b1b220241ffffffff03712002470d00200241027422024100480d00024020010d0020020d02410421060c040b200028020c2106200141027422072002460d03024020070d0020020d02410421060c040b200620072002102b2206450d020c030b1032000b2002102722060d010b1030000b2000200636020c200041106a20024102763602000b200028020c220241046a2002200141027410e5071a2002200320046b36020020002003360204410121022005200141016a3602002000200028020041016a3602000b20020b8c0201067f02400240024020012802002202450d00200128020421030340200241086a210420022f010622054103742101410021060240024003402001450d0141f3aec0002004410810e7072207450d02200141786a2101200641016a2106200441086a21042007417f4a0d000b2006417f6a21050b2003450d022003417f6a2103200220054102746a41e4016a28020021020c010b0b200241e0006a2006410c6c6a22012802084108490d01200041086a2001280200290000370300200041003602000f0b200041003602042000410c6a4128360200200041086a41fbaec0003602000c010b200041003602042000410c6a4129360200200041086a41a3afc0003602000b200041013602000bac0401057f024002400240200241046a2203417f4c0d0002400240024002400240024002400240024002402003450d00200310272204450d0b200241c000490d04200241808001490d052002418080808004490d0620030d010b41012103410110272204450d07200441033a0000410521050c010b200441033a000002402003417f6a41034d0d00200321050c020b200341017422064105200641054b1b22054100480d0720032005460d010b200420032005102b2204450d050b20042002360001410521060c030b024020030d0041012103410110272204450d040b200420024102743a000041012106200321050c020b02400240200341014d0d00200321050c010b200341017422064102200641024b1b2105024020030d002005102722040d010c040b20032005460d00200420032005102b2204450d030b41022106200420024102744101723b00000c010b02400240200341034d0d00200321050c010b200341017422064104200641044b1b22054100480d03024020030d002005102722040d010c030b20032005460d00200420032005102b2204450d020b20042002410274410272360000410421060b0240200520066b2002490d00200521030c050b200620026a22032006490d01200541017422072003200720034b1b22034100480d0120052003460d04200420052003102b22040d040b1030000b1032000b1038000b1039000b200420066a2001200210e4071a2000200620026a36020820002003360204200020043602000b890101037f0240024002400240200041046a2802002201450d000240200141037422024100480d0020002802002103200141027422012002460d04024020010d0020020d0341042103410021020c050b200320012002102b2203450d030c040b1032000b411021020b2002102722030d010b1030000b20002003360200200041046a20024102763602000bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d8007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d8006c22032001460d03024020030d0020010d02410821020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141d8006e3602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff01712001470d00200141037422014100480d00024020030d0020010d02410421020c040b20002802002102200341037422032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a20014103763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42c0017e2204422088a70d002004a722014100480d00024020030d0020010d02410121020c040b20002802002102200341c0016c22032001460d03024020030d0020010d02410121020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141c0016e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42187e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341186c22032001460d03024020030d0020010d02410821020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141186e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42307e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341306c22032001460d03024020030d0020010d02410821020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141306e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff1f712001470d00200141067422014100480d00024020030d0020010d02410421020c040b20002802002102200341067422032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a20014106763602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff00712001470d00200141047422014100480d00024020030d0020010d02410821020c040b20002802002102200341047422032001460d03024020030d0020010d02410821020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a20014104763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad422c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003412c6c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a2001412c6e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad421c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003411c6c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a2001411c6e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff3f712001470d00200141057422014100480d00024020030d0020010d02410421020c040b20002802002102200341057422032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a20014105763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42247e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341246c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141246e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42f0007e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341f0006c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141f0006e3602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff03712001470d00200141027422014100480d00024020030d0020010d02410421020c040b20002802002102200341027422032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a20014102763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42187e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341186c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141186e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42a8027e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341a8026c22032001460d03024020030d0020010d02410821020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141a8026e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad423c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003413c6c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a2001413c6e3602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff00712001470d00200141047422014100480d00024020030d0020010d02410421020c040b20002802002102200341047422032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a20014104763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad420c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003410c6c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a2001410c6e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff3f712001470d00200141057422014100480d00024020030d0020010d02410121020c040b20002802002102200341057422032001460d03024020030d0020010d02410121020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a20014105763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42c4007e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341c4006c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141c4006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42147e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341146c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141146e3602000b0bba0101027f0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1b220241ffffff3f712002470d00200241057422024100480d00024020010d0020020d02410821030c040b20002802002103200141057422012002460d03024020010d0020020d02410821030c040b200320012002102b2203450d020c030b1032000b2002102722030d010b1030000b20002003360200200041046a20024105763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42c1007e2204422088a70d002004a722014100480d00024020030d0020010d02410121020c040b20002802002102200341c1006c22032001460d03024020030d0020010d02410121020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141c1006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42287e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341286c22032001460d03024020030d0020010d02410821020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141286e3602000b0bbc0102027f017e0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1bad42c0037e2204422088a70d002004a722024100480d00024020010d0020020d02410821030c040b20002802002103200141c0036c22012002460d03024020010d0020020d02410821030c040b200320012002102b2203450d020c030b1032000b2002102722030d010b1030000b20002003360200200041046a200241c0036e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad4290027e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b2000280200210220034190026c22032001460d03024020030d0020010d02410821020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a20014190026e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42227e2204422088a70d002004a722014100480d00024020030d0020010d02410221020c040b20002802002102200341226c22032001460d03024020030d0020010d02410221020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141226e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42e0007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341e0006c22032001460d03024020030d0020010d02410821020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141e0006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42387e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341386c22032001460d03024020030d0020010d02410821020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141386e3602000b0bb40101027f0240200041046a280200220320016b20024f0d000240024002400240200120026a22042001490d00200341017422022004200220044b1b220420046a22012004490d0020014100480d00024020030d0020010d02410221030c040b2000280200210320022001460d03024020020d0020010d02410221030c040b200320022001102b2203450d020c030b1032000b2001102722030d010b1030000b20002003360200200041046a20014101763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42387e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341386c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141386e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42307e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341306c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141306e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d0007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d0006c22032001460d03024020030d0020010d02410821020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141d0006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42287e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341286c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141286e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42347e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341346c22032001460d03024020030d0020010d02410421020c040b200220032001102b2202450d020c030b1032000b2001102722020d010b1030000b20002002360200200041046a200141346e3602000b0bfc0403027f017e057f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941f7c4c000ad4280808080800284100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bc1760b047f017e017f017e087f017e027f017e077f027e027f230041801a6b22012400200120003602d805200141b0176a41186a22024200370300200141b0176a41106a22034200370300200141b0176a41086a22044200370300200142003703b01741eebec500ad4280808080f000842205100122062900002107200141e80f6a41086a2208200641086a290000370300200120073703e80f2006102920042008290300370300200120012903e80f3703b01741eab8c000ad4280808080900284100122092900002107200141b0126a41086a2206200941086a290000370300200120073703b01220091029200320012903b0122207370300200141386a41086a220a2004290300370300200141386a41106a220b2007370300200141386a41186a220c2006290300370300200120012903b017370338200141206a200141386a10b101420021070240024002400240024002402001280220417d710d0042002107200242003703002003420037030020044200370300200142003703b01720051001220929000021052008200941086a290000370300200120053703e80f2009102920042008290300370300200120012903e80f3703b01741b480c200ad4280808080d002841001220929000021052006200941086a290000370300200120053703b01220091029200320012903b012370000200341086a2006290300370000200a2004290300370300200b2003290300370300200c2002290300370300200120012903b01737033802400240200141386a10b201220941ff01714102460d0020094101710d010b200141b0176a41186a220d4200370300200141b0176a41106a220e4200370300200141b0176a41086a22094200370300200142003703b01741eebec500ad4280808080f00084100122082900002105200141e80f6a41086a220f200841086a290000370300200120053703e80f200810292009200f290300370300200120012903e80f3703b0174180fac100ad4280808080800184100122082900002105200141b0126a41086a220f200841086a290000370300200120053703b01220081029200320012903b012370000200341086a200f290300370000200141386a41086a2009290300370300200141386a41106a200e290300370300200141386a41186a200d290300370300200120012903b0173703384100200141386a10b3012209200941ff01714104461b41ff01710e0401000100010b20012802d805210d10b401210742002105200141b0126a41186a4200370300200141b0126a41106a220e4200370300200141b0126a41086a22094200370300200142003703b01241c8bec500ad4280808080c000841001220829000021102009200841086a290000370300200120103703b012200810294194f1c200ad4280808080b00184100122082900002110200141286a41086a220f200841086a2900003703002001201037032820081029200e20012903282210370300200141e80f6a41086a2009290300370300200141e80f6a41106a2010370300200141e80f6a41186a200f290300370300200120012903b0123703e80f200141106a200141e80f6a10b50102400240427f200742e0127c221020102007541b22072001290318420020012802101b7d22102007560d00417f200d2010a7417f2010428080808010541b6a22092009200d491b2209200d6b220820094b0d012008417f6a4195014b0d0141eebec500ad4280808080f00084100122092900002107200141e80f6a41086a2208200941086a290000370300200120073703e80f2009102941b8dcc900ad4280808080a00184100122092900002107200141b0126a41086a220d200941086a290000370300200120073703b01220091029412010272209450d03200920012903e80f370000200920012903b012370010200941086a2008290300370000200941186a220e200d290300370000412010272208450d0320082009290000370000200841186a200e290000370000200841106a200941106a290000370000200841086a200941086a290000370000200141a0086a41026a220d200141b0176a41026a2d00003a0000200120012f00b0173b01a008200141b00d6a41106a42a08080808004370300200141003a00c80d200120093602bc0d200142a080808080043702b40d200120083602b00d200141cb0d6a200d2d00003a0000200120012f01a0083b00c90d200141b0176a200141b00d6a10b6010240024020012802b0174101470d00200141b0126a41186a2209200141cc176a290200370300200141b0126a41106a200141c4176a290200370300200141b0126a41086a200141bc176a290200370300200120012902b4173703b01241201027220f450d05200f20012903b012370000200f41186a2009290300370000200f41106a200141b0126a41106a2211290300370000200f41086a200141b0126a41086a221229030037000020014281808080103702ec0a2001200f3602e80a200141386a41186a200141b00d6a41186a280200360200200141386a41106a200141b00d6a41106a290300370300200141386a41086a200141b00d6a41086a290300370300200120012903b00d370338200141b0176a200141386a10b6014101210d024020012802b0174101470d00200141b0176a41047221094102210d4120210e410121080340200141e80f6a41186a200941186a2902002207370300200141e80f6a41106a200941106a2902002205370300200141e80f6a41086a200941086a29020022103703002001200929020022133703e80f200141b0126a41186a221420073703002011200537030020122010370300200120133703b0120240200d417f6a2008470d00200141e80a6a20084101109e0120012802e80a210f0b200f200e6a220820012903b012370000200841186a2014290300370000200841106a2011290300370000200841086a20122903003700002001200d3602f00a200141b0176a200141386a10b60120012802b0174101470d01200e41206a210e200d41016a210d20012802ec0a21080c000b0b0240200128023c450d00200128023810290b0240200141c8006a280200450d00200128024410290b20012802ec0a21150c010b024020012802b40d450d0020012802b00d10290b4101210f4100210d024020012802c00d450d0020012802bc0d10290b410021150b41eebec500ad4280808080f00084100122092900002107200141e80f6a41086a2208200941086a290000370300200120073703e80f2009102941f5b7c000ad4280808080a00184100122092900002107200141b0126a41086a220e200941086a290000370300200120073703b01220091029412010272209450d03200920012903e80f370000200920012903b012370010200941086a2008290300370000200941186a2211200e290300370000412010272208450d0320082009290000370000200841186a2011290000370000200841106a200941106a290000370000200841086a200941086a290000370000200141f8146a41026a220e200141b0176a41026a2d00003a0000200120012f00b0173b01f814200141b00d6a41106a42a08080808004370300200141003a00c80d200120093602bc0d200142a080808080043702b40d200120083602b00d200141cb0d6a200e2d00003a0000200120012f01f8143b00c90d200141b0176a200141b00d6a10b7010240024020012d00e0174102460d00200141b0126a41186a200141b0176a41186a290300370300200141b0126a41106a200141b0176a41106a290300370300200141b0126a41086a200141b0176a41086a290300370300200120012903b0173703b012024020012802d41741ffffff3f71450d0020012802d01710290b412010272216450d05201620012903b012370000201641186a200141b0126a41186a2211290300370000201641106a200141b0126a41106a2212290300370000201641086a200141b0126a41086a221429030037000020014281808080103702ec0a200120163602e80a200141386a41186a200141b00d6a41186a280200360200200141386a41106a200141b00d6a41106a290300370300200141386a41086a200141b00d6a41086a290300370300200120012903b00d370338200141b0176a200141386a10b701024020012d00e0174102460d004120210e410121080340200141e80f6a41186a2209200141b0176a41186a290300370300200141e80f6a41106a2217200141b0176a41106a290300370300200141e80f6a41086a2218200141b0176a41086a290300370300200120012903b0173703e80f024020012802d41741ffffff3f71450d0020012802d01710290b201120092903003703002012201729030037030020142018290300370300200120012903e80f3703b0120240200820012802ec0a470d00200141e80a6a20084101109e0120012802e80a21160b2016200e6a220920012903b012370000200941186a2011290300370000200941106a2012290300370000200941086a20142903003700002001200841016a22083602f00a200e41206a210e200141b0176a200141386a10b70120012d00e0174102470d000b0b0240200128023c450d00200128023810290b0240200141c8006a280200450d00200128024410290b200141a0086a41086a200141e80a6a41086a2802002211360200200120012903e80a3703a0080c010b200141003602a808200142013703a008024020012802b40d450d0020012802b00d10290b4100211120012802c00d450d0020012802bc0d10290b2001200d3602e80a200120113602b00d2011200d6aad42c0f0f50b7e21050240200d41808004490d00024041002802d8a74c4102490d00200141386a411c6a4101360200200141cc006a4101360200200141c4006a41013602002001418cc5c00036025020014188c5c0003602402001410136023c2001200141b00d6a3602482001200141e80a6a36023841002802888040210941002802848040210841002802dca74c210d200141f0176a41c411360200200141e8176a42db80808010370300200141e4176a41eec5c000360200200141dc176a420e370200200141d8176a41e0c5c000360200200141d0176a4204370300200141c0176a4205370300200141b8176a4107360200200141b0176a411c6a200141386a36020020014190c5c0003602bc17200141bcc1c2003602b417200141023602b01720084180a4c000200d410246220d1b200141b0176a20094198a4c000200d1b2802101102000b024020012802a40841ffffff3f71450d0020012802a00810290b0240201541ffffff3f71450d00200f10290b41002802d8a74c4102490d022001410c36023c2001200141d8056a36023841002802888040210941002802848040210841002802dca74c210d200141f0176a419a0a360200200141e8176a42db80808010370300200141e4176a41eec5c000360200200141dc176a420e370200200141d8176a41e0c5c000360200200141d0176a4201370300200141c0176a4202370300200141b8176a4107360200200141cc176a200141386a360200200141c8c5c0003602bc17200141bcc1c2003602b417200141023602b01720084180a4c000200d410246220d1b200141b0176a20094198a4c000200d1b2802101102000c020b200d4105742209417f4c0d0402400240200d0d00200141003602b817200142013703b017200141b0176a41004100109e0120012802b817210920012802b01721120c010b200910272209450d04200141003602b8172001200d3602b417200120093602b017200141b0176a4100200d109e01200d410574210e20012802b017221220012802b81722144105746a2109200f2108034020092008290000370000200941186a200841186a290000370000200941106a200841106a290000370000200941086a200841086a290000370000200941206a2109200841206a2108200e41606a220e0d000b2001200d41057441606a41057620146a41016a22093602b8170b20012802b4172108200141a0086a201120094105742209410575220e109e0120012802a008221720012802a80822114105746a2012200910e4071a20012011200e6a22183602a8080240200841ffffff3f71450d00201210290b200141b0176a41186a22084200370300200141b0176a41106a220e4200370300200141b0176a41086a22094200370300200142003703b01741eebec500ad4280808080f000842207100122122900002110200141e80f6a41086a2211201241086a290000370300200120103703e80f2012102920092011290300370300200120012903e80f3703b01741c6b8c000ad4280808080a00284100122142900002110200141b0126a41086a2212201441086a290000370300200120103703b01220141029200320012903b012370000200341086a22142012290300370000200141386a41086a22162009290300370300200141386a41106a2219200e290300370300200141386a41186a221a2008290300370300200120012903b017370338200141203602b4172001200141386a3602b017200f200d200141b0176a10b9010240201541ffffff3f71450d00200f10290b20012802a408210f20084200370300200e420037030020094200370300200142003703b01720071001220d29000021072011200d41086a290000370300200120073703e80f200d102920092011290300370300200120012903e80f3703b01741d8b8c000ad4280808080a002841001220d29000021072012200d41086a290000370300200120073703b012200d1029200320012903b01237000020142012290300370000201620092903003703002019200e290300370300201a2008290300370300200120012903b017370338200141203602b4172001200141386a3602b01720172018200141b0176a10b9010240200f41ffffff3f71450d00201710290b20012802d805210d200141b0176a41186a220e4200370300200141b0176a41106a220f4200370300200141b0176a41086a22094200370300200142003703b01741eebec500ad4280808080f00084100122082900002107200141e80f6a41086a2211200841086a290000370300200120073703e80f2008102920092011290300370300200120012903e80f3703b01741eab8c000ad4280808080900284100122082900002107200141b0126a41086a2211200841086a290000370300200120073703b01220081029200320012903b012370000200341086a2011290300370000200141386a41086a2009290300370300200141386a41106a200f290300370300200141386a41186a200e290300370300200120012903b017370338410110272209450d07200941013a0000200941014105102b2209450d072009200d360001200141386aad42808080808004842009ad4280808080d0008410032009102920054280c6868f017c210541002802d8a74c4103490d012001410c36023c2001200141d8056a36023841002802888040210941002802848040210841002802dca74c210d200141f0176a41980a360200200141e8176a42db80808010370300200141e4176a41eec5c000360200200141dc176a420e370200200141d8176a41e0c5c000360200200141d0176a4201370300200141c0176a4202370300200141b8176a4107360200200141cc176a200141386a360200200141b8c5c0003602bc17200141bcc1c2003602b417200141033602b01720084180a4c000200d410246220d1b200141b0176a20094198a4c000200d1b2802101102000c010b41002802d8a74c4102490d0041002802888040210941002802848040210841002802dca74c210d200141f0176a419f0a360200200141e8176a42db80808010370300200141e4176a41eec5c000360200200141dc176a420e370200200141d8176a41e0c5c00036020042002105200141d0176a4200370300200141cc176a4180a6cc00360200200141c0176a4201370300200141b8176a4107360200200141d8c5c0003602bc17200141bcc1c2003602b417200141023602b01720084180a4c000200d410246220d1b200141b0176a20094198a4c000200d1b2802101102000b200542c0d1e1237c21070b200242003703002003420037030020044200370300200142003703b01741e4bec500ad4280808080a001841001220929000021052004200941086a290000370300200120053703b01720091029418cb2c400ad4280808080e000841001220929000021052006200941086a290000370300200120053703b01220091029200320012903b0122205370300200a2004290300370300200b2005370300200c2006290300370300200120012903b017370338200141b0176a200141386a10ba0120012802b0172204410420041b210a0240024002400240024002400240024020012902b417420020041b2205422088a7220641c4006c22040d00410021020c010b200a20046a210341002102200a210402400340024020042d00004101460d00200441046a28020020004f0d020b200241016a21022003200441c4006a2204470d000b0b200220064b0d010b20074280c2d72f7c211b200620026b210b200542ffffffff0f832107200a200241c4006c22036a2108200a210602400340024020030d00200821040c020b200341bc7f6a210320062d00002109200641c4006a2204210620094102470d000b0b0240034020082004460d0120042d00002103200441c4006a210420034102470d000b0b0240200b450d0002402002450d00200a200a200241c4006c6a200b41c4006c10e5071a0b200bad42208620078421070b200141b0176a41186a4200370300200141b0176a41106a22044200370300200141b0176a41086a22064200370300200142003703b01741e4bec500ad4280808080a00184100122092900002105200141b0126a41086a2203200941086a290000370300200120053703b0122009102920062003290300370300200120012903b0123703b017418cb2c400ad4280808080e000841001220929000021052003200941086a290000370300200120053703b01220091029200420012903b0122205370300200141386a41086a2006290300370300200141386a41106a2005370300200141386a41186a2003290300370300200120012903b017370338200141b0176a200a2007422088a710bb01200141386aad4280808080800484220520013502b81742208620012802b0172206ad8410032007a72103024020012802b417450d00200610290b02402003450d00200341c4006c450d00200a10290b200141b0176a41186a22064200370300200141b0176a41106a22094200370300200141b0176a41086a22034200370300200142003703b01741e4bec500ad4280808080a00184100122082900002107200141b0126a41086a2202200841086a290000370300200120073703b0122008102920032002290300370300200120012903b0123703b0174198b7c400ad4280808080c001841001220829000021072002200841086a290000370300200120073703b01220081029200420012903b012370000200441086a2002290300370000200141386a41086a22022003290300370300200141386a41106a22082009290300370300200141386a41186a220a2006290300370300200120012903b017370338200141003a00b0172005200141b0176aad221c428080808010841003200141386a10bc012006200a2903003703002009200829030037030020032002290300370300200120012903383703b017412410272204450d0a200420012903b01737000020044114360220200441186a2006290300370000200441106a2009290300370000200441086a200329030037000020014281808080103702b412200120043602b012200141b0126a10bd012006200a2903003703002009200829030037030020032002290300370300200120012903383703b017200141b0176a10be0110bf01200141386a200010c001200141b0176a200128023822042001280240220310c1010240024020012802b017220e0d004108210e420021070c010b2003ad4220862004ad84100420012902b41721070b0240200128023c450d00200410290b200e2007422088a7220341c8026c22096a21062007a72114200e21042003450d04200941b87d6a2108200141b0176a41046a210f200141386a41046a210b200141e80f6a41046a210c4100210920014180036a41086a2102200e21040240034020014190036a200441b40210e4071a200441b4026a28020021032002200441c0026a2903003703002001200441b8026a29030037038003024020034103470d00200441c8026a21040c070b200c20014190036a41b40210e407210d200141386a200141e80f6a41b80210e4071a200141f8146a200b41b40210e4071a200141e8146a41086a220a200229030037030020012001290380033703e8140240024020034102470d004101210a0c010b200f200141f8146a41b40210e4071a200141b00d6a200141b0176a41b80210e4071a200141a00d6a41086a200a290300370300200120012903e8143703a00d4100210a200921110b200141e80a6a200141b00d6a41b80210e4071a200141d80a6a41086a200141a00d6a41086a290300370300200120012903a00d3703d80a200a450d01200941016a2109200841b87d6a2108200441c8026a22042006470d000b200621040c050b200141d8056a200141e80a6a41b80210e4071a200141c8056a41086a2202200141d80a6a41086a290300370300200120012903d80a3703c805200141b0126a200141d8056a41b80210e4071a200141a0126a41086a220a2002290300370300200120012903c8053703a012200441c8026a210420034102460d04200141a0086a200141b0126a41b80210e4071a20014190086a41086a2202200a290300370300200120012903a01237039008200141b0176a200141a0086a41b80210e4071a200141386a41086a2002290300370300200120012903900837033841d00210272212450d0620122011360200201241046a200141b0176a41b80210e4071a201220033602bc02201220012903383703c002201241c8026a200141386a41086a290300370300200621032008450d02200941016a2102200141b0126a41046a210a200141a00d6a41086a210302400340200141d8056a200441b40210e4071a200441b4026a28020021092003200441c0026a2903003703002001200441b8026a2903003703a00d024020094103470d00200441c8026a21030c050b200a200141d8056a41b40210e4071a200141386a200141b0126a41b80210e4071a200141f8146a200b41b40210e4071a200141e8146a41086a22082003290300370300200120012903a00d3703e8140240024020094102470d00410121080c010b200f200141f8146a41b40210e4071a200141e80f6a200141b0176a41b80210e4071a20014190036a41086a2008290300370300200120012903e81437039003410021082002210c0b200141b00d6a200141e80f6a41b80210e4071a200141a0126a41086a20014190036a41086a29030037030020012001290390033703a0122008450d01200241016a2102200441c8026a22042006470d000b200621030c030b200141e80a6a200141b00d6a41b80210e4071a200141d80a6a41086a220a200141a0126a41086a2217290300370300200120012903a0123703d80a200441c8026a210341012119024020094102470d00410121160c040b200241016a2104200141a0086a200141e80a6a41b80210e4071a20014190086a41086a2218200a290300370300200120012903d80a3703900841012119410121160340200141b0176a200141a0086a41b80210e4071a200141386a41086a220820182903003703002001200129039008370338024020162019470d00201941016a22022019490d0a201941017422152002201520024b1bad42d0027e2207422088a70d0a2007a722024100480d0a02400240024020190d0020020d01410821120c020b201941d0026c22152002460d01024020150d0020020d01410821120c020b201220152002102b2212450d0e0c010b200210272212450d0d0b200241d0026e21190b2012201641d0026c6a2202200c360200200241046a200141b0176a41b80210e4071a200241bc026a2009360200200241c0026a2001290338370300200241c8026a2008290300370300201641016a2116024020032006470d00200621030c050b0240034020014190036a200341b40210e4071a200341b4026a280200210920014180036a41086a2202200341c0026a2903003703002001200341b8026a29030037038003024020094103470d00200341c8026a21030c070b200d20014190036a41b40210e4071a200141386a200141e80f6a41b80210e4071a200141f8146a200b41b40210e4071a200141e8146a41086a2208200229030037030020012001290380033703e8140240024020094102470d00410121020c010b200f200141f8146a41b40210e4071a200141b00d6a200141b0176a41b80210e4071a200141286a41086a20082903002207370300200141a00d6a41086a2007370300200120012903e8142207370328200120073703a00d41002102200421110b200141e80a6a200141b00d6a41b80210e4071a200a200141a00d6a41086a290300370300200120012903a00d3703d80a2002450d01200441016a2104200341c8026a22032006470d000b200621030c050b200141d8056a200141e80a6a41b80210e4071a200141c8056a41086a2202200a290300370300200120012903d80a3703c805200141b0126a200141d8056a41b80210e4071a20172002290300370300200120012903c8053703a01220094102460d02200341c8026a2103200441016a2104200141a0086a200141b0126a41b80210e4071a20182017290300370300200120012903a012370390082011210c0c000b0b200220061044000b200341c8026a21030c010b41012119410121160b024020062003460d000340200341c8026a21040240200341b4026a2802004102460d000240200341a8026a2802002209450d00200341ac026a280200450d00200910290b200310c2010b2004210320062004470d000b0b02402014450d00201441c8026c450d00200e10290b024020164115490d002016410176ad42d0027e2207422088a70d042007a7221d417f4c0d04201d10272215450d03410021042001410036024020014204370338201241b07d6a211a201241d87a6a211e410421034100210f2016211103402011210a41002111410121080240200a417f6a2214450d000240024002400240024002402012201441d0026c6a41c8026a2d0000200a41d0026c220c20126a41a87d6a2d00002209490d00200a417e6a210b201e200c6a2102410021114100210603400240200b2006470d00200a21080c080b200641016a2106200941ff0171210820022d00002109200241b07d6a2102200820094f0d000b200641016a21082006417f73200a6a21060c010b201e200c6a21022014210602400340024020064101470d00410021060c020b2006417f6a2106200941ff0171210820022d00002109200241b07d6a210220082009490d000b0b200a2006490d02200a20164b0d01200a20066b2208410176220b450d002012200641d0026c6a2109201a200c6a21020340200141b0176a200941d00210e4071a2009200241d00210e50741d0026a21092002200141b0176a41d00210e40741b07d6a2102200b417f6a220b0d000b0b024020060d00200621110c050b0240200841094d0d00200621110c050b200a20164b0d022012200641d0026c6a210c0340200a2006417f6a2211490d040240200a20116b22084102490d002012200641d0026c6a220241c8026a2d00002012201141d0026c6a220941c8026a2d0000220e4f0d00200141b0176a200941c80210e4071a2001200941cc026a2800003600b3122001200941c9026a2800003602b0122009200241d00210e407210d024020084103490d002014210b200c2109200d41e8076a2d0000200e4f0d0003402009200941d0026a220241d00210e407210d2006200b417f6a220b460d0120022109200d41e8076a2d0000200e490d000b0b2002200141b0176a41c80210e407220641c8026a200e3a0000200641c9026a20012802b012360000200641cc026a20012800b3123600000b2011450d05200c41b07d6a210c201121062008410a4f0d050c000b0b200a20164180cac700104b000b2006200a4180cac700104c000b200a2006417f6a2211490d00200a20164190cac700104b000b2011200a4190cac700104c000b0240200f200128023c470d00200141386a200f4101108d012001280238210320012802402204210f0b2003200f4103746a22062008360204200620113602002001200441016a22043602402004210f024020044102490d000240024003400240024002400240024020032004417f6a4103746a2206280200450d00200441037420036a220841746a2802002202200628020422094b0d010b20044103490d022006280204210920032004417d6a220d4103746a28020421060c010b4102210f200441024d0d0620032004417d6a220d4103746a2802042206200920026a4d0d004103210f200441034d0d06200841646a280200200620026a4b0d050b20062009490d010b2004417e6a210d0b02400240024002400240024002402004200d41016a220e4d0d002004200d4d0d012003200d41037422146a2204280204221720042802006a22042003200e41037422186a2203280200220f490d02200420164b0d032012200f41d0026c6a220b2003280204220c41d0026c22036a2109200441d0026c21082004200f6b2202200c6b2204200c4f0d0420152009200441d0026c220310e407220220036a2106200c4101480d0520044101480d05201a20086a21082009210303402008200341b07d6a2209200641b07d6a220a200641786a2d0000200341786a2d00004922041b41d00210e40721082006200a20041b21060240200b2009200320041b2203490d00200221040c080b200841b07d6a21082002210420022006490d000c070b0b200e200441a0cac7001036000b200d200441b0cac7001036000b200f200441c0cac700104c000b2004201641c0cac700104b000b2015200b200310e407220420036a21060240200c4101480d002002200c4c0d00201220086a210a20042104200b2103034020092004200941c8026a2d0000200441c8026a2d00004922021b21082004200441d0026a20021b21042003200841d00210e40741d0026a2103200941d0026a200920021b2209200a4f0d03200620044b0d000c030b0b200b2103200421040c010b20092103200221040b20032004200620046b2206200641d002706b10e4071a024020012802402204200d4d0d002001280238220320146a22062017200c6a3602042006200f3602002004200e4d0d02200320186a2206200641086a2004200e417f736a41037410e5071a20012004417f6a2204360240200441014b0d010c030b0b200d200441d0cac7001036000b200e20041042000b2004210f0b20110d000b0240200128023c41ffffffff0171450d00200310290b201d41d002702104201d41d002490d02201d2004460d02201510290c020b20164102490d012016417f6a21032012201641d0026c6a2109410021020340024002400240201620032204417f6a2203490d00201620036b22084102490d022012200441d0026c6a220441c8026a2d00002012200341d0026c6a220641c8026a2d0000220a4f0d02200141b0176a200641c80210e4071a2001200641cc026a2800003600b3122001200641c9026a2800003602b0122006200441d00210e407210b20084103490d012002210620092108200b41e8076a2d0000200a4f0d0103402008220441b07d6a200441d00210e4071a2006417f6a2206450d02200441d0026a210820044198056a2d0000200a4f0d020c000b0b2003201641f0c9c700104c000b2004200141b0176a41c80210e407220441c8026a200a3a0000200441c9026a20012802b012360000200441cc026a20012800b3123600000b200241016a2102200941b07d6a210920030d000c020b0b024020062004460d000340200441c8026a21030240200441b4026a2802004102460d000240200441a8026a2802002209450d00200441ac026a280200450d00200910290b200410c2010b2003210420062003470d000b0b410821124100211602402014450d00201441c8026c450d00200e1029410821120b410021190b2012201641d0026c6a210f02400240024020160d0042002113201221030c010b200141e0026a2115200141b0176a41b8026a2106200141386a41b8026a2108200041016a211a200141cd176a210e200141386a41046a211442c0a187f000210742002113200141d8056a41086a210a200141810b6a221741076a21184100210220122104024003402004280200210d200141b0126a200441046a41b80210e4071a200441bc026a2802002103200a200441c8026a2903003703002001200441c0026a2903003703d80520034102460d01200141386a200141b0126a41b80210e4071a200141b0176a201441b40210e4071a200620012903d805370300200641086a2209200a290300370300200120033602e419200141e80f6a200141b0176a10c30120012903e80f210520012802e419210320012802d819210b200141b00d6a200141b0176a41b40210e4071a200141a0086a41086a220c2009290300370300200120062903003703a008024020034102460d00427f427f427f200720057c220520052007541b220742c0b2cd3b7c220520052007541b427f200742c0f0f50b7c220520052007541b200b1b220742c0b2cd3b7c220520052007541b200720034101461b2107200141386a200141b00d6a41b40210e4071a200841086a220b200c290300370300200820012903a008370300200120033602ec0202400240024020012d00f80241c000490d002002450d0020074280c0a8ca9a3a560d010b200141b0176a200141386a10c40141002109200141003b01e80f200141e80a6a200141b0176a200141e80f6a10c501024020012802e0022211450d0020012802e8022203417f4c0d090240024020030d004100210b410121090c010b200310272209450d092003210b0b02400240200b2003490d00200b210c0c010b200b410174220c2003200c20034b1b220c4100480d0b0240200b0d00200c10272209450d0e0c010b200b200c460d002009200b200c102b2209450d0d0b20092011200310e4071a2003ad422086200cad8421100b0240024020012802ec024101460d004101210b20012802e002450d01200141b0176a201510c60120013502b81742208620012802b0172203ad84100420012802b417450d01200310290c010b20012802f00221030240024020012802f402220b41014b0d00200141003602ec020c010b200141013602ec022001200b417f6a3602f4020b200320006a2103024020012802e002450d00200141b0176a200310c00120012802b817211120012802b017210b4100210c200141f8146a41046a41003a0000200141003602f814200141086a200b2011200141f8146a4105410010c70102402001280208450d002001200128020c220c4105200c4105491b3602ec0f2001200141f8146a3602e80f2001200141e80f6a10c80120012802042111200128020045210c0b024020012802b417450d00200b10290b200141b0176a201510c60120012802b017210b200120012802b8173602ec0f2001200b3602e80f200320114100200c1b200141e80f6a10c90120012802b417450d00200b10290b200141b0176a200141386a41c80210e4071a2003200141b0176a10ca014100210b0b200120172900003703b017200120182800003600b7170240024020012903e80a4201510d00410421030c010b20012d00800b210c20012903f00a2105200120012800b7173600ef0f200120012903b0173703e80f4104210320054202510d00200120012800ef0f3600b717200120012903e80f3703b017200c21030b200120012903b0173703f814200120012800b7173600ff14200e20012903f814370000200e41076a20012800ff14360000200120033a00cc17200120103702c417200120093602c0172001200d3602bc17200120003602b817200141023602b417200141013a00b017200141b0176a10cb010240200b0d00200721130c020b024020012802e0022203450d0020012802e402450d00200310290b200141386a10cc01200721130c010b200141e80f6a200141386a41b40210e4071a200141e80a6a41086a220c200b290300370300200120082903003703e80a20034103460d00200141b0176a200141e80f6a41b40210e4071a200620012903e80a3703002009200c290300370300200120033602e419201a200141b0176a10ca010b2002417f6a2102200441d0026a2204200f470d010c040b0b200441d0026a21030c010b200441d0026a21030b200f2003460d002012201641d0026c6a210903402003220441d0026a21030240200441b0026a2802002206450d00200441b4026a280200450d00200610290b200441086a10c20120092003470d000b0b02402019450d00201941d0026c450d00201210290b200141b0126a41186a22094200370300200141b0126a41106a22044200370300200141b0126a41086a22034200370300200142003703b01241b3e6ca00ad4280808080e000841001220629000021072003200641086a290000370300200120073703b0122006102941cfe6ca00ad4280808080a00184100122062900002107200141b0176a41086a2202200641086a290000370300200120073703b01720061029200420012903b0172207370300200141e80f6a41086a2003290300370300200141e80f6a41106a2007370300200141e80f6a41186a2002290300370300200120012903b0123703e80f200141b0176a200141e80f6a412010cd0120012d00b01721062009200141c9176a2900003703002004200141c1176a2900003703002003200141b9176a290000370300200120012900b1173703b0120240024020064101460d00200141386a41186a4200370300200141386a41106a4200370300200141386a41086a4200370300200142003703380c010b200141386a41186a2009290300370300200141386a41106a2004290300370300200141386a41086a2003290300370300200120012903b0123703380b200141b0126a41186a22024200370300200141b0126a41106a22084200370300200141b0126a41086a22034200370300200142003703b0124188a2c800ad42808080808003841001220629000021072003200641086a290000370300200120073703b0122006102941a0a2c800ad4280808080e00184100122062900002107200141b0176a41086a2209200641086a290000370300200120073703b01720061029200420012903b017370000200441086a2009290300370000200141e80f6a41086a2003290300370300200141e80f6a41106a2008290300370300200141e80f6a41186a2002290300370300200120012903b0123703e80f200141b00d6a200141e80f6a412010ce01024002400240024020012802b00d22030d0041002104200141003602f00f200142013703e80f200141b0176a41186a200141386a41186a290300370300200141b0176a41106a200141386a41106a2903003703002009200141386a41086a290300370300200120012903383703b017200141b0176a21060c010b200120012902b40d22073702ec0f200120033602e80f2007a7210202402007422088a7220441d100490d00200141b0126a41186a2209200141386a41186a290300370300200141b0126a41106a2208200141386a41106a290300370300200141b0126a41086a220a200141386a41086a290300370300200120012903383703b0122000417f6a41d10070220620044f0d07200320064105746a220620012903b012370000200641186a2009290300370000200641106a2008290300370000200641086a200a2903003700000c030b200141b0176a41186a200141386a41186a290300370300200141b0176a41106a200141386a41106a290300370300200141b0176a41086a200141386a41086a290300370300200120012903383703b017200141b0176a210620042002470d010b200141e80f6a20044101109e0120012802ec0f210220012802e80f210320012802f00f21040b200320044105746a22092006290000370000200941186a200641186a290000370000200941106a200641106a290000370000200941086a200641086a2900003700002001200441016a22043602f00f0b200141b0126a41186a4200370300200141b0126a41106a22084200370300200141b0126a41086a22064200370300200142003703b0124188a2c800ad4280808080800384100122092900002107200141d8056a41086a220a200941086a290000370300200120073703d805200910292006200a290300370300200120012903d8053703b01241a0a2c800ad4280808080e00184100122092900002107200141a0086a41086a220a200941086a290000370300200120073703a00820091029200820012903a0082207370300200141b0176a41086a2006290300370300200141b0176a41106a2007370300200141b0176a41186a200a290300370300200120012903b0123703b0170240024020030d00201c428080808080048410040c010b200141203602b4122001200141b0176a3602b01220032004200141b0126a10cf01200241ffffff3f71450d00200310290b200141801a6a2400427f201b427f201342c096b1027c220720072013541b7c22072007201b541b0f0b1039000b1038000b1032000b2006200441d0a7c8001036000b1030000bb40201067f230041d0006b220224002002412036020420022001360200200241086a2001ad42808080808004841007108b0202400240200228020822030d00410221010c010b200228020c210402400240200241106a2802002205450d0020032d0000220641014b0d0041002101024020060e020200020b2005417f6a4104490d0020032800012107410121010c010b20024100360220200242013703182002410d36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241f4eaca003602382002200241286a360248200241346a41a8a3c800200241386a10371a200235022042208620023502188410080240200228021c450d00200228021810290b410221010b2004450d00200310290b2000200736020420002001360200200241d0006a24000b950201047f230041d0006b220124002001412036020420012000360200200141086a2000ad42808080808004841007108b0202400240200128020822020d00410221000c010b200128020c210302400240200141106a280200450d0020022d0000220441014b0d0041002100024020040e020200020b410121000c010b20014100360220200142013703182001410d36022c200120013602282001200141186a360234200141cc006a41013602002001420137023c200141f4eaca003602382001200141286a360248200141346a41a8a3c800200141386a10371a200135022042208620013502188410080240200128021c450d00200128021810290b410221000b2003450d00200210290b200141d0006a240020000b810201037f230041d0006b220124002001412036020420012000360200200141086a2000ad42808080808004841007108b0202400240200128020822020d00410421000c010b200128020c210302400240200141106a280200450d0020022d000022004104490d010b20014100360220200142013703182001410d36022c200120013602282001200141186a360234200141cc006a41013602002001420137023c200141f4eaca003602382001200141286a360248200141346a41a8a3c800200141386a10371a200135022042208620013502188410080240200128021c450d00200128021810290b410421000b2003450d00200210290b200141d0006a240020000b940405047f017e017f017e057f230041f0006b22002400200041c0006a41186a22014200370300200041c0006a41106a22024200370300200041c0006a41086a220342003703002000420037034041c8bec500ad4280808080c000842204100122052900002106200041e0006a41086a2207200541086a2900003703002000200637036020051029200320072903003703002000200029036037034041a4f0c200ad4280808080a001841001220529000021062007200541086a2900003703002000200637036020051029200220002903602206370300200041206a41086a22082003290300370300200041206a41106a22092006370300200041206a41186a220a200729030037030020002000290340370320200041106a200041206a10b5012000280210210b200029031821062001420037030020024200370300200342003703002000420037034020041001220529000021042007200541086a2900003703002000200437036020051029200320072903003703002000200029036037034041f8f0c200ad4280808080b001841001220529000021042007200541086a29000037030020002004370360200510292002200029036022043703002008200329030037030020092004370300200a2007290300370300200020002903403703202000200041206a10b5012000280200210720002903082104200041f0006a24002004420020071b200642e0127e4200200b1b7c0b990204017f017e017f017e230041d0006b220224002002412036020420022001360200200241086a2001ad42808080808004841007108b0202400240200228020822010d00420021030c010b200228020c210402400240200241086a41086a2802004108490d0020012900002105420121030c010b20024100360220200242013703182002410d36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241f4eaca003602382002200241286a360248200241346a41a8a3c800200241386a10371a200235022042208620023502188410080240200228021c450d00200228021810290b420021030b2004450d00200110290b2000200537030820002003370300200241d0006a24000b8a0604057f017e047f037e230041f0006b22022400200241286a200141146a350200422086200135020c841015108b020240024020022802282203450d00200141086a2104200141106a210503400240024020042802002206200229022c2207422088a722084b0d00200128020022092003460d0120092003200610e707450d010b2007a7450d02200310290c020b02402005280200450d00200128020c10290b2001200336020c20052007370200200220032008109e02024002402002280200450d002002280204210a024020012d0018450d002001350214422086200135020c8410040b2001280214220820042802002203490d0102400240200820036b22084108490d00200841786a2106200128020c20036a41086a21090c010b41002106024041002802d8a74c0d004180a6cc0021090c010b4100210641002802888040210341002802848040210841002802dca74c210b200241e600360268200242dc80808010370360200241db9fc00036025c20024213370254200241c89fc000360250200242003703484180a6cc00210920024180a6cc0036024420024201370338200241c09fc00036023420024113360230200241c89fc00036022c2002410136022820084180a4c000200b410246220b1b200241286a20034198a4c000200b1b2802101102000b41002103200241003a00480240034020062003460d01200241286a20036a200920036a2d00003a00002002200341016a22083a00482008210320084120470d000b200241086a41186a200241286a41186a2903002207370300200241086a41106a200241286a41106a290300220c370300200241086a41086a200241286a41086a290300220d37030020022002290328220e3703082000411c6a2007370000200041146a200c3700002000410c6a200d3700002000200e370004200041246a200a360200200041013602000c050b200341ff0171450d00200241003a00480b200241286a2001350214422086200135020c841015108b02200228022822030d010c020b0b2003200841bcf7c900104c000b200041003602000b200241f0006a24000ba90603067f017e047f230041f0006b22022400200241286a200141146a350200422086200135020c841015108b020240024020022802282203450d00200241086a2104200141106a2105034002400240200141086a22062802002207200229022c2208422088a722094b0d002001280200220a2003460d01200a2003200710e707450d010b2008a7450d02200310290c020b02402005280200450d00200128020c10290b2001200336020c2005200837020020022003200910b7020240024020022d00104102460d00200241186a41086a200441086a280200360200200220042902003703182002280204210b2002280200210c024020012d0018450d002001350214422086200135020c8410040b2001280214220920062802002203490d0102400240200920036b22094108490d00200941786a2107200128020c20036a41086a210a0c010b41002107024041002802d8a74c0d004180a6cc00210a0c010b4100210741002802888040210341002802848040210941002802dca74c2106200241e600360268200242dc80808010370360200241db9fc00036025c20024213370254200241c89fc000360250200242003703484180a6cc00210a20024180a6cc0036024420024201370338200241c09fc00036023420024113360230200241c89fc00036022c2002410136022820094180a4c000200641024622061b200241286a20034198a4c00020061b2802101102000b41002103200241003a00480240034020072003460d01200241286a20036a200a20036a2d00003a00002002200341016a22093a00482009210320094120470d000b20002002290328370000200041186a200241286a41186a290300370000200041106a200241286a41106a290300370000200041086a200241286a41086a2903003700002000200b3602242000200c36022020002002290318370228200041306a200241186a41086a2802003602000c050b0240200341ff0171450d00200241003a00480b200b41ffffff3f71450d00200c10290b200241286a2001350214422086200135020c841015108b02200228022822030d010c020b0b2003200941bcf7c900104c000b200041023a00300b200241f0006a24000bb30201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad2001104621000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141b88ac0004102200220006a4180016a410020006b104921000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141b88ac0004102200220006a4180016a410020006b104921000b20024180016a240020000f0b200441800141a88ac000104c000b200441800141a88ac000104c000ba30301067f230041106b22032400024020014105744104722204417f4c0d000240200410272205450d002003410036020820032004360204200320053602002001200310710240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020002101024002402006200522046b4120490d00200441206a21050c010b024002400240200441206a22052004490d00200641017422002005200020054b1b22004100480d000240024020060d00024020000d00410121070c020b2000102721070c040b20062000470d020b200021060c030b1032000b200720062000102b21070b2000210620070d001030000b200141206a2100200720046a22042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a290000370000200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100302402006450d00200710290b200341106a24000f0b1039000b1038000b901304057f017e107f027e230041e0026b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b020240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c8010240024020022802000d00200228020422052002280224220641c4006e2201200120054b1bad42c4007e2207422088a70d032007a72201417f4c0d030240024020010d00410421080c010b200110272208450d050b20024100360230200220083602282002200141c4006e36022c0240024002402005450d00200241b8026a41077221094100210a4100210b03402006450d0220022006417f6a220c36022420022002280220220d41016a360220200d2d0000220141014b0d0202400240024020010e020001000b200c4104490d04200241f4016a41026a200241f8016a41026a2d00003a0000200241d8016a41086a20024198026a41086a290200370300200241d8016a41106a20024198026a41106a290200370300200241d8016a41186a20024198026a41186a2d00003a0000200241b8016a41086a200241b8026a41086a290100370300200241b8016a41106a200241b8026a41106a290100370300200241b8016a41186a200241b8026a41186a290100370300200220022f00f8013b01f40120022002290298023703d801200220022901b8023703b80120022006417b6a220e3602242002200d41056a360220200d280001210f200220022f0194023b01b601410021100c010b41002111200241003a00d8022006417e6a2110024002400240024002400340200c20112201460d01200241b8026a20016a200d20016a221141016a2d00003a00002002201141026a3602202002200141016a22113a00d802200220103602242010417f6a211020114120470d000b20024194026a41026a221220022d00ba023a0000200241f8016a41086a2213200941086a290000370300200241f8016a41106a2214200941106a290000370300200241f8016a41186a2215200941186a2d00003a0000200220022f01b8023b019402200220092900003703f8014100210e200c2011460d0220022800bb022116200220103602242002200d20116a220c41026a360220200c41016a2d0000221141014d0d012010210e410221100c050b0240200141ff0171450d00200241003a00d8020b4100210e410221100c040b024020110e020200020b41002111200241003a00d802200620016b417c6a21010240034020102011460d01200241b8026a20116a200c20116a220d41026a2d00003a00002002200d41036a3602202002201141016a220d3a00d802200220013602242001417f6a2101200d2111200d4120470d000b20024198026a41186a200241b8026a41186a29030037030020024198026a41106a200241b8026a41106a29030037030020024198026a41086a200241b8026a41086a290300370300200220022903b802370398022010200d6b210e410121170c030b0240201141ff0171450d00200241003a00d8020b4100210e0b410221100c020b410021172010210e0b200241b8016a41186a20024198026a41186a290300370300200241b8016a41106a20024198026a41106a290300370300200241b8016a41086a20024198026a41086a290300370300200241f4016a41026a20122d00003a0000200241d8016a41086a2013290300370300200241d8016a41106a2014290300370300200241d8016a41186a20152d00003a000020022002290398023703b801200220022f0194023b01f401200220022903f8013703d801410121102016210f0b200241b2016a41026a2201200241f4016a41026a2d00003a000020024198016a41086a2211200241d8016a41086a29030037030020024198016a41106a220d200241d8016a41106a29030037030020024198016a41186a220c200241d8016a41186a2d00003a0000200241f8006a41086a2206200241b8016a41086a290300370300200241f8006a41106a2212200241b8016a41106a290300370300200241f8006a41186a2213200241b8016a41186a290300370300200220022f01f4013b01b201200220022903d80137039801200220022903b801370378200220022f01b6013b017620104102460d03200b41016a210b200241f2006a41026a221420012d00003a0000200241d8006a41086a22152011290300370300200241d8006a41106a2211200d290300370300200241d8006a41186a220d200c2d00003a0000200241386a41086a220c2006290300370300200241386a41106a22062012290300370300200241386a41186a22122013290300370300200220022f01b2013b0172200220022903980137035820022002290378370338200220022f01763b01360240200a200228022c470d00200241286a200a4101109f01200228022821082002280230210a0b2008200a41c4006c6a220120103a00002001200f360004200141036a20142d00003a0000200120022f01723b0001200d2d00002110201129030021072015290300211820022903582119200120173a002120012019370008200141106a2018370000200141186a2007370000200141206a20103a000020012002290338370022200c29030021072006290300211820122903002119200120022f01363b00422001413a6a2019370000200141326a20183700002001412a6a20073700002002200a41016a220a360230200e2106200b2005470d000b0b2008450d022000200229022c370204200020083602000c030b200241b2016a41026a200241f4016a41026a2d00003a000020024198016a41086a200241d8016a41086a29030037030020024198016a41106a200241d8016a41106a29030037030020024198016a41186a200241d8016a41186a2d00003a0000200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a200241b8016a41106a290300370300200241f8006a41186a200241b8016a41186a290300370300200220022f01f4013b01b201200220022903d80137039801200220022903b801370378200220022f01b6013b01760b200228022c2201450d00200141c4006c450d00200810290b200241003602a00220024201370398022002410d3602bc012002200241086a3602b801200220024198026a360278200241cc026a4101360200200242013702bc02200241f4eaca003602b8022002200241b8016a3602c802200241f8006a41a8a3c800200241b8026a10371a20023502a0024220862002350298028410080240200228029c02450d0020022802980210290b200041003602000b2004450d00200310290b200241e0026a24000f0b1038000b1039000bff0201037f230041206b2203240002400240200241c4006c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410272205450d020b20034100360208200320053602002003200436020420022003107102402002450d00200241c4006c210203400240024020012d00004101460d00200341003a00102003200341106a410110722003200141046a2802003602102003200341106a410410720c010b200341013a00102003200341106a41011072412010272204450d042003422037021420032004360210200341106a200141016a41201072200328021421042003200328021022052003280218107202402004450d00200510290b0240200141216a2d00004101460d00200341003a00102003200341106a410110720c010b200341013a00102003200341106a410110722003200141226a412010720b200141c4006a2101200241bc7f6a22020d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1038000b1039000b910f05017f017e047f017e067f230041f0016b2201240042002102200141d8006a41186a22034200370300200141d8006a41106a22044200370300200141d8006a41086a220542003703002001420037035841e4bec500ad4280808080a00184100122062900002107200141c8006a41086a2208200641086a29000037030020012007370348200610292005200829030037030020012001290348370358418e9fc400ad4280808080e000841001220629000021072008200641086a2900003703002001200737034820061029200420012903482207370300200141286a41086a22062005290300370300200141286a41106a2007370300200141286a41186a200829030037030020012001290358370328200141f8006a200141286a412010cd0120012d00782108200320014191016a290000370300200420014189016a290000370300200520014181016a290000370300200120012900793703580240024020084101470d0020002001290358370000200041186a2003290300370000200041106a2004290300370000200041086a20052903003700000c010b200141f8006a41186a4200370300200141f8006a41106a22094200370300200141f8006a41086a220842003703002001420037037841b3e6ca00ad4280808080e000841001220a29000021072008200a41086a29000037030020012007370378200a102941e7e6ca00ad4280808080e000841001220a29000021072006200a41086a29000037030020012007370328200a102920092001290328220737030020052008290300370300200420073703002003200629030037030020012001290378370358200141f8006a200141d8006a10cf03024002402001280278220a0d004104210a410021050c010b200129027c2202422088a721050b02400240200541246c2205450d002005415c6a2108200a210503400240024020052d00004101460d002008450d030c010b200541016a2800002103200541086a28020021062001200541106a28020036025c200120063602580240200341c28289aa04460d0020080d010c030b200141f8006a200141d8006a10e00220012903784203510d02200141f8006a41106a22052802002106200141f8006a41186a420037030020054200370300200141f8006a41086a220842003703002001420037037841b1dcc900ad4280808080f000841001220329000021072008200341086a290000370300200120073703782003102941b8dcc900ad4280808080a00184100122032900002107200141286a41086a2209200341086a2900003703002001200737032820031029200520012903282207370300200141d8006a41086a2008290300370300200141d8006a41106a2007370300200141d8006a41186a200929030037030020012001290378370358200141f8006a200141d8006a108d0220012802782205410120051b21034100210802402006200129027c420020051b2207422088a74f0d00200320064105746a2205450d00200141086a41186a200541186a290000370300200141086a41106a200541106a290000370300200141086a41086a200541086a29000037030020012005290000370308410121080b0240200742ffffff3f83500d00200310290b2008450d02200141f8006a41186a2208200141086a41186a290300370300200141f8006a41106a2203200141086a41106a290300370300200141f8006a41086a2206200141086a41086a29030037030020012001290308370378200141d8006a41186a220b4200370300200141d8006a41106a220c4200370300200141d8006a41086a220942003703002001420037035841e4bec500ad4280808080a001841001220d2900002107200141c8006a41086a2205200d41086a29000037030020012007370348200d10292009200529030037030020012001290348370358418e9fc400ad4280808080e000841001220d29000021072005200d41086a29000037030020012007370348200d102920042001290348370000200441086a2005290300370000200141286a41086a2009290300370300200141286a41106a200c290300370300200141286a41186a200b290300370300200120012903583703280240412010272205450d0020052001290378370000200541186a2008290300370000200541106a2003290300370000200541086a2006290300370000200141286aad42808080808004842005ad4280808080800484100320051029200041186a2008290300370000200041106a2003290300370000200041086a2006290300370000200020012903783700000c040b1039000b200541246a21052008415c6a21080c000b0b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000b02402002422088a72205450d00200541246c2108200a210503400240024020052d0000220341044b0d0002400240024020030e050400010204040b2005410c6a280200450d03200541086a28020010290c030b2005410c6a280200450d02200541086a28020010290c020b2005410c6a280200450d01200541086a28020010290c010b200541086a280200450d00200541046a28020010290b200541246a21052008415c6a22080d000b0b2002a72205450d00200541246c450d00200a10290b200141f0016a24000b800b04047f017e127f037e230041d0036b22012400200141f0006a41186a4200370300200141f0006a41106a22024200370300200141f0006a41086a220342003703002001420037037041eebec500ad4280808080f000841001220429000021052003200441086a290000370300200120053703702004102941f0f5c100ad4280808080900184100122042900002105200141206a41086a2206200441086a2900003703002001200537032020041029200220012903202205370300200141c0006a41086a22042003290300370300200141c0006a41106a2005370300200141c0006a41186a200629030037030020012001290370370340200141f0006a200141c0006a10d00102400240024020012903704202510d002000280208210320002802042107200028020021082001200228020010af01200141f0006a200128020022092001280208220a10d1012004200141f0006a410c6a290200370300200120012902743703400240024020012802704101460d00200141106a410c6a4100360200200142003703100c010b200141106a41086a200141c0006a41086a290300370300200120012903403703100b02402003450d002008200341246c6a210b20014184016a210c2001411c6a210d200141106a410472210e200141e8006a210f200141c0006a41206a211020082111034020112802202112200141206a41186a2213201141186a290000370300200141206a41106a2214201141106a290000370300200141206a41086a2215201141086a290000370300200120112900003703200240024020012802142206450d00200128021821160c010b200141f0006a410041e00210e6071a200f410036020020104200370300200141c0006a41186a22004200370300200141c0006a41106a22034200370300200141c0006a41086a220442003703002001420037034041940310272206450d0541002116200641003b010620064100360200200641086a200141f0006a41e00210e4071a20064190036a200f28020036020020064188036a201029030037020020064180036a2000290300370200200641f8026a2003290300370200200641f0026a2004290300370200200620012903403702e80220014100360218200120063602140b201141246a2111024002400340200641086a210320062f01062217410574210041002104024003402000450d01200141206a2003412010e7072202450d03200041606a2100200441016a2104200341206a21032002417f4a0d000b2004417f6a21170b02402016450d002016417f6a2116200620174102746a4194036a28020021060c010b0b200141c0006a41186a20132903002205370300200141c0006a41106a20142903002218370300200141c0006a41086a2015290300221937030020012001290320221a370340200c201a370200200c41086a2019370200200c41106a2018370200200c41186a20053702002001200d360280012001201736027c2001200e3602782001200636027420014100360270200141f0006a410010d20121000c010b200620044102746a41e8026a21000b2000200028020020126a3602002001200128021020126a3602102011200b470d000b0b02402007450d00200741246c450d00200810290b200141fc006a200141106a41086a290300370200200120012903102205370274200141013602702001410036024820014201370340410410272200450d0220002005a73600002001200036024020014284808080c000370244200141f0006a41086a2200200141c0006a10d30120012802442103200aad4220862009ad84200135024842208620012802402204ad84100302402003450d00200410290b200010d4012001280204450d01200910290c010b200041046a2802002203450d00200341246c450d00200028020010290b200141d0036a24000f0b1030000b850a03057f017e047f230041a0016b22012400200141e8006a41186a22024200370300200141e8006a41106a22034200370300200141e8006a41086a220442003703002001420037036841b1dcc900ad4280808080f000841001220529000021062004200541086a2900003703002001200637036820051029418886ca00ad4280808080c0018410012205290000210620014188016a41086a2207200541086a29000037030020012006370388012005102920032001290388012206370300200141c8006a41086a2004290300370300200141c8006a41106a2006370300200141c8006a41186a200729030037030020012001290368370348200141106a200141c8006a412010fc0120012802142105200128021021082002200041186a2900003703002003200041106a2900003703002004200041086a2900003703002001200029000037036841c6b7c700ad4280808080800184100122002900002106200141186a41086a200041086a290000370300200120063703182000102941e0c9c700ad4280808080e001841001220029000021062007200041086a29000037030020012006370388012000102920012005410020081b3602382001200141386aad4280808080c00084100222002900003703980120001029200141d4006a22052001413c6a360200200120014198016a41086a220736024c2001200141386a360250200120014198016a360248200141286a200141c8006a10750240024002400240412010272200450d0020002001290368370000200041186a2002290300370000200041106a2003290300370000200041086a200429030037000020012000ad42808080808004841002220429000037039801200410292005200041206a360200200120003602502001200736024c200120014198016a360248200141386a200141c8006a1075200010292001280230220741206a2202200128024022086a2204417f4c0d01200128023821092001280228210a0240024020040d0041002105410121000c010b200410272200450d01200421050b024002402005410f4d0d00200521030c010b200541017422034110200341104b1b22034100480d03024020050d002003102722000d010c050b20052003460d00200020052003102b2200450d040b20002001290318370000200041086a200141186a41086a2903003700000240024020034170714110460d00200321050c010b200341017422054120200541204b1b22054100480d0320032005460d00200020032005102b2200450d040b2000200129038801370010200041186a20014188016a41086a29030037000002400240200541606a2007490d00200521030c010b2007415f4b0d03200541017422032002200320024b1b22034100480d0320052003460d00200020052003102b2200450d040b200041206a200a200710e4071a02400240200320026b2008490d00200321050c010b20042002490d03200341017422052004200520044b1b22054100480d03024020030d00024020050d00410121000c020b200510272200450d050c010b20032005460d00200020032005102b2200450d040b200020026a2009200810e4071a0240200128023c450d00200910290b0240200128022c450d00200a10290b200141086a2000200410fc012001200128020c41016a410120012802081b3602682004ad4220862000ad84200141e8006aad4280808080c00084100302402005450d00200010290b200141a0016a24000f0b1039000b1038000b1032000b1030000be52907047f017e057f047e037f037e017f230041800f6b22002400200041a0026a41186a4200370300200041a0026a41106a22014200370300200041a0026a41086a22024200370300200042003703a00241c8bec500ad4280808080c00084100122032900002104200041c0026a41086a2205200341086a290000370300200020043703c0022003102920022005290300370300200020002903c0023703a00241a8c1c800ad4280808080b001841001220329000021042005200341086a290000370300200020043703c00220031029200120002903c002220437030020004180026a41086a200229030037030020004180026a41106a200437030020004180026a41186a2005290300370300200020002903a00237038002200041a80a6a20004180026a10ce030240024020002d00a80a4102470d00200041e8086a41186a4200370300200041e8086a41106a22034200370300200041e8086a41086a22054200370300200042003703e80841b3e6ca00ad4280808080e000841001220229000021042005200241086a290000370300200020043703e8082002102941e7e6ca00ad4280808080e00084100122022900002104200041a8046a41086a2206200241086a290000370300200020043703a80420021029200320002903a8042204370300200041a80a6a41086a2005290300370300200041a80a6a41106a2004370300200041a80a6a41186a2006290300370300200020002903e8083703a80a200041b00d6a200041a80a6a10cf030240024020002802b00d22070d0041002108200041003602b004200042043703a8044203210441042107200041a8046a21090c010b200020002902b40d22043702ac04200020073602a8042004a72108200041a8046a210902402004422088a72205450d00200541246c21022007210502400340024020052d00004101470d00200541016a2800002103200541086a28020021062000200541106a2802003602b40d200020063602b00d200341c28289aa04470d00200041a80a6a200041b00d6a10e00220002903a80a22044203520d020b200541246a21052002415c6a2202450d020c000b0b20002903b00a210a200041306a200041b80a6a41e80010e4071a0c010b420321040b200910d30202402008450d00200841246c450d00200710290b20004198016a200041306a41e80010e4071a41002106024020044203510d00200041d0026a20004198016a41e80010e4071a20004180026a41186a2206420037030020004180026a41106a2202420037030020004180026a41086a22034200370300200042003703800241c8bec500ad4280808080c00084220b10012207290000210c200041c0026a41086a2205200741086a2900003703002000200c3703c0022007102920032005290300370300200020002903c0023703800241f8f0c200ad4280808080b00184220d10012207290000210c2005200741086a2900003703002000200c3703c00220071029200220002903c002220c370300200041a8046a41086a22072003290300370300200041a8046a41106a2208200c370300200041a8046a41186a2209200529030037030020002000290380023703a804200041206a200041a8046a10b501024002402000280220450d002000290328500d00200041a8046aad4280808080800484210c0c010b2006420037030020024200370300200342003703002000420037038002200b1001220e290000210c2005200e41086a2900003703002000200c3703c002200e102920032005290300370300200020002903c00237038002200d1001220e290000210c2005200e41086a2900003703002000200c3703c002200e1029200220002903c002370000200241086a220f200529030037000020072003290300370300200820022903003703002009200629030037030020002000290380023703a8042000200a3703a80a200041a8046aad4280808080800484220c200041a80a6aad428080808080018410032006420037030020024200370300200342003703002000420037038002200b1001220e290000210d2005200e41086a2900003703002000200d3703c002200e102920032005290300370300200020002903c0023703800241d983cc00ad4280808080b001841001220e290000210d2005200e41086a2900003703002000200d3703c002200e1029200220002903c002370000200f200529030037000020072003290300370300200820022903003703002009200629030037030020002000290380023703a804200041a80a6a200041a8046a10bf0320002902ac0a210d20002802a80a210e2006420037030020024200370300200342003703002000420037038002200b10012210290000210b2005201041086a2900003703002000200b3703c0022010102920032005290300370300200020002903c0023703800241b8f1c200ad4280808080a0018410012210290000210b2005201041086a2900003703002000200b3703c00220101029200220002903c002370000200f200529030037000020072003290300370300200820022903003703002009200629030037030020002000290380023703a804200041a80a6a200041a8046a10c00320002d00a80a21052009200041c10a6a2900003703002008200041b90a6a2900003703002007200041b10a6a290000370300200020002900a90a3703a804200e4108200e1b21030240024020054101460d00200041c80d6a4200370300200041c00d6a4200370300200041b80d6a4200370300200042003703b00d0c010b200041b00d6a41186a200041a8046a41186a290300370300200041b00d6a41106a200041a8046a41106a290300370300200041b00d6a41086a200041a8046a41086a290300370300200020002903a8043703b00d0b200041e8086a41086a200041b00d6a41086a290300220b370300200041e8086a41106a200041b00d6a41106a2903002211370300200041e8086a41186a200041b00d6a41186a2903002212370300200020002903b00d22133703e808200041a80a6a41086a200d4200200e1b370300200041a80a6a41106a2013370300200041a80a6a41186a200b370300200041c80a6a2011370300200041d00a6a2012370300200020033602ac0a200041003602a80a200041a80a6a10d0030b20004180026a41186a2207420037030020004180026a41106a2208420037030020004180026a41086a22034200370300200042003703800241c8bec500ad4280808080c00084220b10012206290000210d200041c0026a41086a2205200641086a2900003703002000200d3703c0022006102920032005290300370300200020002903c002370380024194f1c200ad4280808080b00184220d1001220629000021112005200641086a290000370300200020113703c00220061029200220002903c002370000200241086a22092005290300370000200041a8046a41086a220e2003290300370300200041a8046a41106a220f2008290300370300200041a8046a41186a2210200729030037030020002000290380023703a804200041106a200041a8046a10b50120002802102114200029031821112007420037030020084200370300200342003703002000420037038002200b1001220629000021122005200641086a290000370300200020123703c0022006102920032005290300370300200020002903c0023703800241d1e8c200ad42808080808001841001220629000021122005200641086a290000370300200020123703c00220061029200220002903c00237000020092005290300370000200e2003290300370300200f20082903003703002010200729030037030020002000290380023703a80420004200200a201142017c420120141b7d22112011200a561b3e02a80a200c200041a80a6aad22114280808080c0008410032007420037030020084200370300200342003703002000420037038002200b1001220629000021122005200641086a290000370300200020123703c0022006102920032005290300370300200020002903c00237038002200d10012206290000210d2005200641086a2900003703002000200d3703c00220061029200220002903c00237000020092005290300370000200e2003290300370300200f20082903003703002010200729030037030020002000290380023703a8042000200a3703a80a200c2011428080808080018410034100210620044200520d002000200a3703b803200041b8036a41086a200041d0026a41e80010e4071a2007420037030020084200370300200342003703002000420037038002200b1001220629000021042005200641086a290000370300200020043703c0022006102920032005290300370300200020002903c0023703800241d983cc00ad4280808080b001841001220629000021042005200641086a290000370300200020043703c00220061029200220002903c00237000020092005290300370000200e2003290300370300200f20082903003703002010200729030037030020002000290380023703a804200041a80a6a200041a8046a10bf0320002802a80a2205410820051b21030240024020002802c003220620002902ac0a420020051b2204422088a74f0d002003200641286c6a2205290000210b200541086a290000210c200541106a290000210d200041e8086a41186a200541186a290000370300200041e8086a41106a200d370300200041e8086a41086a200c3703002000200b3703e808200041a80a6a200041e8086a10d10320002802a80a2105200041a8046a200041a80a6a41047241c40110e4071a20054101460d00200041a8076a200041b00d6a41046a200041a8046a41046a41c00110e40741c00110e4071a200041e8086a200041a8076a41c00110e4071a20004180026a41186a2208420037030020004180026a41106a2209420037030020004180026a41086a22064200370300200042003703800241c8bec500ad4280808080c0008410012207290000210b200041c0026a41086a2205200741086a2900003703002000200b3703c0022007102920062005290300370300200020002903c0023703800241b8f1c200ad4280808080a0018410012207290000210b2005200741086a2900003703002000200b3703c00220071029200220002903c002370000200241086a2005290300370000200041a8046a41086a22052006290300370300200041a8046a41106a22062009290300370300200041a8046a41186a2207200829030037030020002000290380023703a804200041a80a6a200041a8046a10c00320002d00a80a21082007200041c10a6a2900003703002006200041b90a6a2900003703002005200041b10a6a290000370300200020002900a90a3703a8040240024020084101460d00200041b8026a4200370300200041b0026a4200370300200041a8026a4200370300200042003703a0020c010b200041a0026a41186a200041a8046a41186a290300370300200041a0026a41106a200041a8046a41106a290300370300200041a0026a41086a200041a8046a41086a290300370300200020002903a8043703a0020b20004180026a41186a2207420037030020004180026a41106a2208420037030020004180026a41086a22054200370300200042003703800241c8bec500ad4280808080c0008410012209290000210b200041c0026a41086a2206200941086a2900003703002000200b3703c0022009102920052006290300370300200020002903c0023703800241a4f0c200ad4280808080a0018410012209290000210b2006200941086a2900003703002000200b3703c00220091029200220002903c002370000200241086a2006290300370000200041a8046a41086a2005290300370300200041a8046a41106a2008290300370300200041a8046a41186a200729030037030020002000290380023703a8042000200041a8046a10b5012000290308210b20002802002102200041a80a6a41af90cc004104108001200041a80a6a41b390cc00410b200a108401200041a80a6a41be90cc00410d200b420020021b108401200041a80a6a41cb90cc004110200041a0026a4120108301200041b00d6a200041a80a6a41d00110e4071a200041a8046a200041b00d6a41d00110e4071a200041a80a6a200041c4036a200041e8086a200041a8046a10d2034101210620002802a80a4101460d00200041a8046a200041a80a6a41086a41800310e4071a200041a80a6a200041a8046a41800310e4071a200041b00d6a41999fc8004109108001200041b00d6a4180a6cc004100419c90cc004113108301200041b00d6a41a29fc8004106200041c80b6a4120108301200041b00d6a41a89fc8004107200041880d6a4120108301200041e8086a41186a22024200370300200041e8086a41106a22094200370300200041e8086a41086a220e4200370300200042003703e808200041b00d6a4180a6cc004100200041e8086a412010850120072002290300370300200820092903003703002005200e290300370300200020002903e80837038002200041b00d6a108601200e2005290300370300200920082903003703002002200729030037030020002000290380023703e8080c010b410021060b2004a72205450d00200541286c450d00200310290b200041a80a6a41186a200041e8086a41186a290300370300200041a80a6a41106a200041e8086a41106a290300370300200041a80a6a41086a200041e8086a41086a290300370300200020002903e8083703a80a200041a0026a41186a22074200370300200041a0026a41106a22084200370300200041a0026a41086a22024200370300200042003703a00241c8bec500ad4280808080c00084100122032900002104200041c0026a41086a2205200341086a290000370300200020043703c0022003102920022005290300370300200020002903c0023703a00241a8c1c800ad4280808080b001841001220329000021042005200341086a290000370300200020043703c00220031029200120002903c002370000200141086a200529030037000020004180026a41086a200229030037030020004180026a41106a200829030037030020004180026a41186a2007290300370300200020002903a002370380024121410120061b10272205450d010240024020060d00200541003a000042808080801021040c010b200541013a0000200520002903a80a370001200541096a200041b00a6a290300370000200541116a200041b80a6a290300370000200541196a200041c00a6a2903003700004280808080900421040b20004180026aad428080808080048420042005ad841003200510290b200041800f6a24000f0b1039000bfc0403027f017e057f230041d0006b2202240041e0a7c800ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941efa7c800ad4280808080e00084100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bab0e05047f017e047f017e0f7f230041a00c6b220324002003200236021420032001360210200341186a2002ad4220862001ad841007108b020240024002400240200328021822040d00200041003602000c010b200328021c21052003200341206a28020036022c20032004360228200341086a200341286a10c80102400240024020032802080d00200328020c2202200328022c220141c8026e2206200620024b1bad42c8027e2207422088a70d052007a72206417f4c0d050240024020060d00410821080c010b200610272208450d050b200641c8026ead210702402002450d002002417f6a21060340024002402001450d00200328022822092d0000210a20032001417f6a220b36022c2003200941016a360228200a41014b0d00410221020240200a0e020200020b024002400240200b0d00410221020c010b20092d0001210a20032001417e6a220b36022c410221022003200941026a36022802400240200a41014b0d0041002101024002400240200a0e020100010b2003200341286a10c80120032802000d02200328022c2003280204220a490d02200a417f4c0d0f02400240200a0d0041002109410121010c010b200a102d2201450d0f200328022c200a490d0220012003280228200a10e4071a200328022c2209200a490d0420032009200a6b36022c20032003280228200a6a360228200a21090b2001450d02200aad4220862009ad84210c200328022c210b0b200ca7210a02400240024002400240200b450d002003280228220d2d000021092003200b417f6a36022c2003200d41016a360228200341f8096a200341286a10e40320032802f809411c460d03200341d0076a200341f8096a41a80210e4071a200328022c220b450d042003280228220e2d0000210d2003200b417f6a220f36022c2003200e41016a360228200d41014b0d0441002102200d0e020201020b2001450d07200a450d070c040b200f4104490d02200e280001210d2003200e41056a3602282003200b417b6a220236022c20024104490d02200e28000521102003200b41776a36022c2003200e41096a36022841012102200d21110b200c422088a72112200341f8096a200341d0076a41a80210e4071a200320032800c9073602c0072003200341c9076a41036a2800003600c3070c060b2001450d04200a450d040c010b200341d0076a10cc012001450d01200a450d010b200110290b201321092014210a20152101410221020c020b200a200941ccafc000104c000b201321092014210a201521010b20034198056a200341f8096a41a80210e4071a200320032800c30736009305200320032802c00736029005024020024102460d00200341f8096a20034198056a41a80210e4071a20032003280093053600d30720032003280290053602d00720012116200a211720122118200921192010211a2011211b20092113200a2114200121150c020b20092113200a2114200121150b410321020b200341e8026a200341f8096a41a80210e4071a200320032800d3073600e302200320032802d0073602e00202400240024020024103460d00200341386a200341e8026a41a80210e4071a200320032800e302360033200320032802e0023602302007422088220ca722012007a7470d02024002400240200141016a220a2001490d00200ca74101742209200a200a2009491bad42c8027e220c422088a70d00200ca7220a4100480d00024020010d00200a0d02410821080c050b200141c8026c2201200a460d04024020010d00200a0d02410821080c050b20082001200a102b2208450d020c040b1032000b200a102722080d020b1030000b02402007422088a72201450d00200141c8026c21022008210103400240200141b4026a2802004102460d000240200141a8026a2802002206450d00200141ac026a280200450d00200610290b200110c2010b200141c8026a2101200241b87d6a22020d000b0b2007a72201450d04200141c8026c450d04200810290c040b2007422088220ca72101200a41c8026ead21070b2008200141c8026c6a200341386a41a80210e407220141c0026a20193a0000200141bc026a201a3602002001201b3602b802200120023602b402200120183602b002200120173602ac02200120163602a802200141c1026a2003280230360000200141c4026a2003280033360000200c422086200742ffffffff0f83844280808080107c21072006450d012006417f6a2106200328022c21010c000b0b20080d010b200341003602d807200342013703d0072003410d36029c052003200341106a360298052003200341d0076a3602e8022003418c0a6a4101360200200342013702fc09200341f4eaca003602f809200320034198056a3602880a200341e8026a41a8a3c800200341f8096a10371a20033502d80742208620033502d007841008024020032802d407450d0020032802d00710290b200041003602000c010b20002007370204200020083602000b2005450d00200410290b200341a00c6a24000f0b1039000b1038000bea1501047f0240024020002802002201411a4b0d0002400240024002400240024002400240024002400240024002400240024002400240024020010e1b00011313131302031304130506130708090a0b0c0d130e0f101311000b200041086a280200417e6a220141074b0d1202400240024002400240024020010e080018010218030405000b200041106a280200450d172000410c6a28020010290f0b200041106a280200450d162000410c6a28020010290f0b200041106a280200450d152000410c6a28020010290f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141186a2101200241686a22020d000b0b200041106a2802002201450d14200141186c450d14200028020c10290f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d132001410c6c450d13200028020c10290f0b200041106a280200450d122000410c6a28020010290f0b024020002d0004220141034b0d000240024020010e0414001401140b200041186a220128020010c201200128020010290f0b02402000410c6a280200450d00200041086a28020010290b200041246a220128020010c201200128020010290f0b2000410c6a280200450d11200041086a28020010290f0b02402000410c6a2802002201450d00200141f0006c2102200028020441046a21010340200110d3020240200141046a2802002203450d00200341246c450d00200128020010290b200141f0006a2101200241907f6a22020d000b0b200041086a2802002201450d10200141f0006c450d10200028020410290f0b0240200041086a2d0000220141174b0d000240024002400240024020010e18151515151515001515151515150115150203151515151504150b200041106a28020041ffffff3f71450d142000410c6a28020010290f0b200041106a28020041ffffff3f71450d132000410c6a28020010290f0b200041146a28020041ffffffff0371450d12200041106a28020010290f0b200041146a2802002201450d11200141246c450d11200041106a28020010290f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010290b200041186a1087020f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010290b200041186a1087020f0b20002802042201450d0e200041086a280200450d0e200110290f0b024020004194026a2802002202450d002000418c026a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b20004190026a2802002201450d0d2001410c6c450d0d200028028c0210290f0b02402000410c6a280200450d00200041086a28020010290b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b200041186a2802002201450d0c2001410c6c450d0c200028021410290f0b200041086a2d0000416d6a220141034b0d0b024002400240024020010e0400010203000b200041106a280200450d0e2000410c6a28020010290f0b200041106a280200450d0d2000410c6a28020010290f0b200041106a280200450d0c2000410c6a28020010290f0b200041106a280200450d0b2000410c6a28020010290f0b200041086a2d0000417f6a220141024b0d0a02400240024020010e03000102000b200041306a28020041ffffff3f71450d0c2000412c6a28020010290f0b2000410c6a220128020010c201200128020010290f0b200041106a220128020010c201200128020010290f0b200041086a2d0000417f6a220141024b0d0902400240024020010e03000102000b200041306a28020041ffffff3f71450d0b2000412c6a28020010290f0b2000410c6a220128020010c201200128020010290f0b200041106a220128020010c201200128020010290f0b200041086a2d00004101470d08200041106a28020041ffffff3f71450d082000410c6a28020010290f0b20002d00044104470d072000410c6a28020041ffffff3f71450d07200041086a28020010290f0b200041086a2d0000417c6a220141024b0d060240024020010e03000801000b200041306a280200450d072000412c6a28020010290f0b200041306a280200450d062000412c6a28020010290f0b02402000280204220141014b0d00024020010e020700070b0240200041106a2802002201450d00200041086a280200220320014190026c6a210403400240200341d0006a280200450d00200328024c10290b0240200341186a2802002202450d00200328021021012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b0240200341146a28020041ffffffff0071450d00200328021010290b0240200328021c2201450d00200341206a280200450d00200110290b0240200341fc016a2802002201450d00200141c1006c450d0020032802f80110290b20034190026a210120034188026a41003602002003280284022102200341013602840202402003418c026a280200450d00200210290b2001210320012004470d000b0b2000410c6a2802002201450d0620014190026c450d06200028020810290f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d052001410c6c450d05200028020c10290f0b200041086a2d000022014105490d04024020014105470d002000413c6a280200450d05200041386a28020010290f0b200041146a280200450d04200041106a28020010290f0b20002d0004417f6a220141034b0d030240024020010e0400050501000b0240200041106a280200450d002000410c6a28020010290b2000411c6a280200450d04200041186a28020010290f0b02402000410c6a280200450d00200041086a28020010290b200041186a280200450d03200041146a28020010290f0b0240200041086a2d0000220141034b0d00024020010e0404040400040b200041f0006a280200450d03200041ec006a28020010290f0b200041106a280200450d022000410c6a28020010290f0b024020002d0004220141044b0d00024002400240024020010e050600010203060b0240200041106a2802002202450d00200041086a2802002101200241a8026c21020340200110c201200141a8026a2101200241d87d6a22020d000b0b2000410c6a2802002201450d05200141a8026c450d05200028020810290f0b200041086a220128020010c201200128020010290f0b02402000410c6a28020041ffffff3f71450d00200041086a28020010290b200041206a220128020010c201200128020010290f0b2000412c6a28020041ffffff3f71450d02200041286a28020010290c020b2000412c6a28020041ffffff3f71450d01200041286a28020010290f0b0240200041086a2d0000220141034b0d000240024020010e0403000103030b2000410c6a220128020010c201200128020010290f0b2000410c6a220128020010c201200128020010290f0b2000412c6a220128020010c201200128020010290f0b0b833206017f017e017f017e107f017e230041206b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c01020c03040506070c08090a0b0c0d0e0f1011121314151617181900010b4200210341002104024002400240024002400240200141086a2d00000e050001020503000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b200241086a2001410c6a280200220110c30120022903082103200241086a200110c30120034290ce007c2103200241086a21010c020b200141106a2903002103200241086a2001410c6a28020010c301200241086a21010c010b200241086a2001412c6a280200220110c30120022903082103200241086a200110c30120034290ce007c2103200241086a21010b20012d000821040b200041003a0009200020043a0008200020033703000c190b42e0dc2a2103410021040240024002400240024002400240024002400240200141086a2802000e0b0001090203030405060708000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b2001410c6a35020042d00f7e2103410121040c070b4101210442e088b33021030c060b410121044280c0a8ca9a3a21030c050b410121044280b191e40021030c040b200141146a35020042c091fc2f7e2103410121040c030b200141146a3502004280f7ef2f7e2103410121040c020b200141186a35020042d0b28b307e42d0b28b307c2103410121040c010b410121044280ade20421030b200041003a0009200020043a0008200020033703000c180b42c0b2cd3b210342c0f0f50b210502400240024002400240024020012d00040e050005010203000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b42c0f4a4eb0021030c020b4280e59af700210342c09dd81021050c020b4280e59af70021030b4280c2d72f21050b200041003b01082000200320057c3703000c170b200041023b010820004280c7abcb003703000c160b200041003b0108200042003703000c150b42c0b2cd3b21054280bbb021210302400240024002400240200141086a2d00000e050004010203000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b42c09dd81021030c020b4280e59af70021050c010b4280e1eb1721030b200041003b01082000200520037c3703000c140b200041023b0108200042003703000c130b4280cab5ee0121030240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141086a2d00000e19000102030405060708090a0a0a0b0c0d0e15150f1011121314000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b4280e8a49a0221030c130b42c0bda3a90121030c120b4280a7f2a60121030c110b2001410c6a3502002203428089fa007e20034280c2d72f7e7c42004280c2d72f2003501b7c428097e38b037c21030c100b42c0b1a8ff0021030c0f0b200141146a35020042c0fc157e42c0b8cf8d017c21030c0e0b4280adebfe0021030c0d0b4280e4ecc00021030c0c0b428088debe0121030c0b0b4280cbd13021030c0a0b200141146a35020042f02e7e4280cbd1307c21030c090b2001412c6a3502002203428089fa007e20034280c2d72f7e7c42004280c2d72f2003501b7c42c0fede96037c21030c080b4280cbd13021030c070b200141186a35020042c09dd8107e42c0e1d1aa167c21030c060b42c0cbb2f8f40021030c050b4280c7ca940121030c040b200141106a35020042c0b2cd3b7e4280a3c3c7007c21030c030b2001412c6a3502002203428089fa007e20034280c2d72f7e7c42004280c2d72f2003501b7c4280e6daa1037c21030c020b427f427f427f200141dc016a35020042c0fc157e200141e0016a33010042f0b9267e7c417f417f417f417f417f417f417f417f417f417f417f417f417f417f417f200141206a28020022042001412c6a28020022066a220720072004491b2207200141386a28020022086a220920092007491b2209200141c4006a28020022076a220a200a2009491b2209200141d0006a280200220a6a220b200b2009491b2209200141dc006a280200220b6a220c200c2009491b2209200141e8006a280200220c6a220d200d2009491b220d200141f4006a28020022096a220e200e200d491b220d20014180016a280200220e6a220f200f200d491b220d2001418c016a280200220f6a22102010200d491b220d20014198016a28020022106a22112011200d491b220d200141a4016a28020022116a22122012200d491b220d200141b0016a28020022126a22132013200d491b220d200141bc016a28020022136a22142014200d491b220d200141c8016a28020022146a22152015200d491b220d200141d4016a2802006a22152015200d491b220dad22034280b0e32d7e7c200141146a2802002201ad4280a4e8037e7c200342c0f0f50b7e7c428084afdf007c2203417f417f417f417f417f417f417f417f417f417f417f417f417f417f2004417f200620066a221520152006491b6a220620062004491b2204417f2008ad42037e2205a72005422088a71b6a220620062004491b2204417f2007410274200741ffffffff03712007471b6a220620062004491b2204417f200aad42057e2205a72005422088a71b6a220620062004491b2204417f200bad42067e2205a72005422088a71b6a220620062004491b2204417f200cad42077e2205a72005422088a71b6a220620062004491b2204417f2009410374200941ffffffff01712009471b6a220620062004491b2204417f200ead42097e2205a72005422088a71b6a220620062004491b2204417f200fad420a7e2205a72005422088a71b6a220620062004491b2204417f2010ad420b7e2205a72005422088a71b6a220620062004491b2204417f2011ad420c7e2205a72005422088a71b6a220620062004491b2204417f2012ad420d7e2205a72005422088a71b6a220620062004491b2204417f2013ad420e7e2205a72005422088a71b6a220620062004491b2204417f2014ad420f7e2205a72005422088a71b6a220620062004491bad42c0f0f50b7e7c220520052003541b2203200d20016aad4280e1eb177e7c220520052003541b220342c0f4a4eb007c220520052003541b21030c010b427f427f427f200141dc016a35020042c0fc157e200141e0016a33010042f0b9267e7c417f417f417f417f417f417f417f417f417f417f417f417f417f417f417f200141206a28020022042001412c6a28020022066a220720072004491b2207200141386a28020022086a220920092007491b2209200141c4006a28020022076a220a200a2009491b2209200141d0006a280200220a6a220b200b2009491b2209200141dc006a280200220b6a220c200c2009491b2209200141e8006a280200220c6a220d200d2009491b220d200141f4006a28020022096a220e200e200d491b220d20014180016a280200220e6a220f200f200d491b220d2001418c016a280200220f6a22102010200d491b220d20014198016a28020022106a22112011200d491b220d200141a4016a28020022116a22122012200d491b220d200141b0016a28020022126a22132013200d491b220d200141bc016a28020022136a22142014200d491b220d200141c8016a28020022146a22152015200d491b220d200141d4016a2802006a22152015200d491b220dad22034280b0e32d7e7c200141146a2802002201ad4280a4e8037e7c200342c0f0f50b7e7c428084afdf007c2203417f417f417f417f417f417f417f417f417f417f417f417f417f417f2004417f200620066a221520152006491b6a220620062004491b2204417f2008ad42037e2205a72005422088a71b6a220620062004491b2204417f2007410274200741ffffffff03712007471b6a220620062004491b2204417f200aad42057e2205a72005422088a71b6a220620062004491b2204417f200bad42067e2205a72005422088a71b6a220620062004491b2204417f200cad42077e2205a72005422088a71b6a220620062004491b2204417f2009410374200941ffffffff01712009471b6a220620062004491b2204417f200ead42097e2205a72005422088a71b6a220620062004491b2204417f200fad420a7e2205a72005422088a71b6a220620062004491b2204417f2010ad420b7e2205a72005422088a71b6a220620062004491b2204417f2011ad420c7e2205a72005422088a71b6a220620062004491b2204417f2012ad420d7e2205a72005422088a71b6a220620062004491b2204417f2013ad420e7e2205a72005422088a71b6a220620062004491b2204417f2014ad420f7e2205a72005422088a71b6a220620062004491bad42c0f0f50b7e7c220520052003541b2203200d20016aad4280e1eb177e7c220520052003541b220342c0f4a4eb007c220520052003541b21030b200041003b0108200020033703000c120b200041003b0108200042c0a3f5d00342808995ef0220012802041b3703000c110b200041023b0108200042003703000c100b200041003b0108200042003703000c0f0b200041003b01082000200141286a35020042b0e32d7e2001411c6a35020042809fc9007e7c4280f797f3017c3703000c0e0b10eb05000b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141086a2d00000e20000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b200041003b01082000428088debe013703000c2a0b200041003b01082000200141106a35020042f0840e7e42809ac9c6007c3703000c290b200041003b01082000428096acdb013703000c280b200041003b0108200042c08dc9f5013703000c270b200041013b0108200042c082f387013703000c260b200041003b01082000428098f6d3003703000c250b200041003b0108200042e0dc94313703000c240b200041003b0108200042e0dc94313703000c230b200041003b010820004280ae99b5013703000c220b200041003b010820004280bd8c8e013703000c210b200041013b010820004280a5963a3703000c200b200041013b01082000428097d197013703000c1f0b200041003b0108200042c0d6b53f3703000c1e0b200041003b0108200042c0fa9dc3003703000c1d0b200041003b0108200042c0d6b53f3703000c1c0b200041003b0108200042c0b7fe9c333703000c1b0b200041003b0108200042c0c3f0cc323703000c1a0b200041003b0108200042a08df0303703000c190b200041003b01082000200141146a35020042a01f7e42c0dddccd007c3703000c180b200041013b01082000200141146a35020042a01f7e42c0dddccd007c3703000c170b200041003b01082000200141146a35020042b8177e42c0b0fac8007c3703000c160b200041013b01082000200141146a35020042b8177e42c0b0fac8007c3703000c150b200041003b010820002001412c6a35020042b8177e4280e299ce007c3703000c140b200041003b0108200042c0ed86d7013703000c130b200041003b0108200042c0a8aefe003703000c120b200041003b0108200042c0e5b192013703000c110b200041003b010820004280e1f491013703000c100b200041003b010820004280bb96e1333703000c0f0b200041003b0108200042c0d391dc323703000c0e0b200041003b010820004280bebac4013703000c0d0b200041003b010820004280c0a8ca9a3a3703000c0c0b2000200141086a10ec050c0b0b2000200141086a10ec050c0a0b4280a7f2a60121030240024002400240024002400240200141086a2d00000e0700060102030405000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b428092fdfb0021030c040b2001410c6a35020042c0d587097e200141106a350200428089fa007e7c4280e9c9d6017c21030c030b2001410c6a35020042d8f1167e42c0a187f0007c21030c020b42c081c5d1002103024002402001410c6a2802000e03010300010b200141106a35020042f8ab0e7e42c08398c4007c21030c020b4280b4928d0121030c010b42c0b6fc9a014280c0a8ca9a3a20012d00291b21030b200041003b0108200020033703000c090b200041003b010820004280e1eb173703000c080b42c090c1a401210341002104024002400240024002400240024002400240200141086a2d00000e09000801020308040506000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b410121044280ae99b50121030c060b410121044280bcded70021030c050b200141346a35020042a01f7e42c0cbf1c5017c21030c030b200141346a35020042a01f7e4280c2d1ae017c21030c020b4280caacf40021030c010b42a0dcc4a20221030b410021040b200041003a0009200020043a0008200020033703000c070b02400240024020012802040e03000102000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b200041023b01082000428094ebdc033703000c070b200041003b0108200042003703000c060b200041023b0108200042003703000c050b410121044280c2d72f210302400240024002400240200141086a2d00000e0700040202010203000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b41002104428094ebdc0321030c020b410021044280cab5ee0121030c010b410021044280e497d01221030b200041003a0009200020043a0008200020033703000c040b410121044280e497d0122103024002400240024020012d00040e080003010202020202000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b4280ade20421030c010b41002104420021030b200041003a0009200020043a0008200020033703000c030b42c0f7c9fc042103410021040240024002400240200141086a2d00000e050003010302000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b42c0e3de9f0142c0a187f000200141306a2903004201511b42004280c2d72f20012d001d4102461b7c2103410021040c010b410121044280d6c28c0421030b200020043a0009200041003a0008200020033703000c020b4280e59af70021034280e1eb1721050240024002400240200141086a2d00000e0400030102000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b42c097e8b20121030c010b42c097e8b20121034280c2d72f21050b200041003b01082000200320057c3703000c010b0240024002400240024002400240024020012d00040e06000102030405000b2002411c6a41013602002002420137020c20024198e3ca0036020820024104360204200241cce3ca0036020020022002360218200241086a4180a6cc001040000b200141086a280200210442c0c3930721030240200141106a280200220741a8026c2206450d00200421010340200241086a200110c301427f427f200320022903087c220520052003541b220342c0843d7c220520052003541b2103200141a8026a2101200641d87d6a22060d000b0b200741a8026c21014101210603402001450d06200141d87d6a2101200241086a200410c301200441a8026a210420022d00104101460d000c050b0b200241086a200141086a280200220110c30120022903082103200241086a200110c301427f200342c08db7017c220520052003541b210320022d001021060c040b200141106a3502002105200241086a200141206a280200220110c30120022903082103200241086a200110c301427f427f427f200342c0caba157c221620162003541b220320054290a10f7e7c220520052003541b220342c0b2cd3b7c220520052003541b210320022d001021060c030b200141306a35020042c0a9077e4280fd87d1007c21030c010b200141306a35020042a08d067e42c0e6d6ce007c21030b410021060b200041003a0009200020063a0008200020033703000b200241206a24000b862703047f067e047f230041e0036b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c01020c03040506070c08090a0b0c0d0e0f1011121314151617181900010b200241b0016a200141086a10f8032000411b360200200041286a200241b0016a41206a290300370300200041206a200241b0016a41186a290300370300200041186a200241b0016a41106a290300370300200041106a200241b0016a41086a290300370300200041086a20022903b0013703000c190b200241b0016a200141086a10f90320004100360200200041186a200241b0016a41106a290300370300200041106a200241b0016a41086a290300370300200041086a20022903b0013703000c180b200241b0016a200141046a10fa0320004101360200200041246a200241d0016a2802003602002000411c6a200241c8016a290300370200200041146a200241c0016a2903003702002000410c6a200241b8016a290300370200200020022903b0013702040c170b20004103360200200041086a200141086a2903003703000c160b02400240024002400240024020012d0004417f6a220341034b0d00200141046a210420030e0401020304010b419cf7ca00412841b8a1cc001033000b200141086a2802002103410121050c030b41022105200241086a41026a200441036a2d00003a0000200241b0016a41086a200141146a290200370300200241c0016a2001411c6a290200370300200241c8016a200141246a2d00003a0000200220042f00013b010820022001410c6a2902003703b001200141086a2802002103200141286a28020021010c020b200141086a2802002103410321050c010b2002410a6a200441036a2d00003a0000200241b0016a41086a200141146a290200370300200241c0016a2001411c6a290200370300200241c8016a200141246a2d00003a0000200220042f00013b010820022001410c6a2902003703b001200141086a2802002103200141286a2802002101410421050b200020053a0004200020022f01083b000520004104360200200041086a20033602002000410c6a20022903b001370200200041286a2001360200200041076a2002410a6a2d00003a0000200041146a200241b0016a41086a2903003702002000411c6a200241c0016a290300370200200041246a200241c8016a2802003602000c150b02400240024002400240024002400240200141086a22032d0000417f6a220541034b0d0020050e0401020304010b419cf7ca00412841b8a1cc001033000b200241b8016a200341096a290000370300200241c0016a200341116a290000370300200241c8016a200341196a290000370300200220032900013703b001200141386a2903002106200141306a2903002107410121010c030b200241b8016a200341096a290000370300200241c0016a200341116a290000370300200241c8016a200341196a290000370300200220032900013703b001200141c8006a2903002108200141c0006a2903002109200141386a2903002106200141306a2903002107410221010c030b200241b8016a200341096a290000370300200241c0016a200341116a290000370300200241c8016a200341196a290000370300200220032900013703b0012002200341216a2800003602082002200341246a28000036000b200141c8006a3100002108200141c0006a2902002109200141386a2902002106200141306a2902002107200141d8006a290300210a200141d0006a290300210b410321010c030b200241b8016a200341096a290000370300200241c0016a200341116a290000370300200241c8016a200341196a290000370300200220032900013703b001200141386a2903002106200141306a2903002107410421010b0b0b200020022903b0013700092000200228020836002920004105360200200041d8006a200a370300200041d0006a200b370300200041c8006a2008370300200041c0006a2009370300200041386a2006370300200041306a2007370300200041086a20013a00002000412c6a200228000b360000200041116a200241b0016a41086a290300370000200041196a200241c0016a290300370000200041216a200241c8016a2903003700000c140b200241b0016a200141046a10fb03200041063602002000410c6a200241b8016a280200360200200020022903b0013702040c130b200241b0016a200141086a10a302200041086a200241b0016a41900210e4071a200041073602000c120b024002402001280204220c0d00410021030c010b200241b0016a41186a200141286a290000370300200241b0016a41106a200141206a290000370300200241b8016a200141186a290000370300200241b0016a41286a200141386a290000370300200241b0016a41306a200141c0006a290000370300200241b0016a41386a200141c8006a290000370300200241b0016a41c8006a200141d8006a290000370300200241b0016a41d0006a200141e0006a290000370300200241b0016a41d8006a200141e8006a2900003703002002200141106a2900003703b0012002200141306a2900003703d0012002200141d0006a2900003703f001200241b0016a41f8006a20014188016a290000370300200241b0016a41f0006a20014180016a290000370300200241b0016a41e8006a200141f8006a290000370300200241b0016a4198016a200141a8016a290000370300200241b0016a4190016a200141a0016a290000370300200241b0016a4188016a20014198016a2900003703002002200141f0006a29000037039002200220014190016a2900003703b0022001410c6a2802002201417f4c0d130240024020010d0041002105410121030c010b200110272203450d16200121050b0240024020052001490d00200521040c010b200541017422042001200420014b1b22044100480d15024020050d002004102722030d010c180b20052004460d00200320052004102b2203450d170b2003200c200110e4071a200241086a200241b0016a41a00110e4071a0b200020033602042000410c6a2001360200200041086a2004360200200041106a200241086a41a00110e4071a200041093602000c110b2000410a360200200020012802043602040c100b200241b0016a200141086a10fc03200041086a200241b0016a41980210e4071a2000410b3602000c0f0b200241b0016a200141046a10fd03200041046a200241b0016a41e80010e4071a2000410c3602000c0e0b10f403000b200241b0016a200141086a10fe032000410e360200200041386a200241b0016a41306a290300370300200041306a200241b0016a41286a290300370300200041286a200241b0016a41206a290300370300200041206a200241b0016a41186a290300370300200041186a200241b0016a41106a290300370300200041106a200241b0016a41086a290300370300200041086a20022903b0013703000c0c0b200241b0016a200141086a10ff032000410f360200200041386a200241b0016a41306a290300370300200041306a200241b0016a41286a290300370300200041286a200241b0016a41206a290300370300200041206a200241b0016a41186a290300370300200041186a200241b0016a41106a290300370300200041106a200241b0016a41086a290300370300200041086a20022903b0013703000c0b0b200241b0016a200141086a10ff0320004110360200200041386a200241b0016a41306a290300370300200041306a200241b0016a41286a290300370300200041286a200241b0016a41206a290300370300200041206a200241b0016a41186a290300370300200041186a200241b0016a41106a290300370300200041106a200241b0016a41086a290300370300200041086a20022903b0013703000c0a0b200241b0016a200141086a10800420004111360200200041306a200241b0016a41286a290300370300200041286a200241b0016a41206a290300370300200041206a200241b0016a41186a290300370300200041186a200241b0016a41106a290300370300200041106a200241b0016a41086a290300370300200041086a20022903b0013703000c090b0240024002400240024002400240024020012d0004417f6a220441064b0d00200141046a21034107210520040e0701020304050607010b419cf7ca00412841b8a1cc001033000b200241c8016a200341196a290000370300200241c0016a200341116a290000370300200241b8016a200341096a290000370300200220032900013703b001410121050c050b200241c8016a200341196a290000370300200241c0016a200341116a290000370300200241b8016a200341096a290000370300200220032900013703b001410221050c040b200241b0016a41186a200341196a290000370300200241b0016a41106a200341116a290000370300200241b0016a41086a200341096a290000370300200241086a41086a200341296a290000370300200241086a41106a200341316a290000370300200241086a41186a200341396a290000370300200220032900013703b0012002200341216a290000370308410321050c030b200141106a280200220d41ffffff3f71200d470d0c200d4105742203417f4c0d0c200141086a28020021040240024020030d00410121050c010b200310272205450d0f0b4100210120024100360210200220053602082002200341057636020c200241086a4100200d109e012002280210210e0240200d450d00200d410574210c2002280208200e4105746a210f0340200f20016a2203200420016a2205290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a290000370000200c200141206a2201470d000b200d41057441606a410576200e6a41016a210e0b200241bb016a200e360000200220022903083700b301410421050c020b200241c8016a200341196a290000370300200241c0016a200341116a290000370300200241b8016a200341096a290000370300200220032900013703b001410521050c010b200241c8016a200341196a290000370300200241c0016a200341116a290000370300200241b8016a200341096a290000370300200220032900013703b001410621050b200020053a0004200020022903b00137000520002002290308370025200020022f00ad013b00452000410d6a200241b0016a41086a290300370000200041156a200241b0016a41106a2903003700002000411d6a200241b0016a41186a2903003700002000412d6a200241086a41086a290300370000200041356a200241086a41106a2903003700002000413d6a200241086a41186a290300370000200041c7006a200241af016a2d00003a0000200041123602000c080b200241b0016a200141086a10820420004113360200200041c0006a200241b0016a41386a290300370300200041386a200241b0016a41306a290300370300200041306a200241b0016a41286a290300370300200041286a200241b0016a41206a290300370300200041206a200241b0016a41186a290300370300200041186a200241b0016a41106a290300370300200041106a200241b0016a41086a290300370300200041086a20022903b0013703000c070b200241b0016a200141046a108304200041046a200241b0016a41a00210e4071a200041143602000c060b200041153602000c050b200241b0016a200141086a10840420004116360200200041c0006a200241b0016a41386a290300370300200041386a200241b0016a41306a290300370300200041306a200241b0016a41286a290300370300200041286a200241b0016a41206a290300370300200041206a200241b0016a41186a290300370300200041186a200241b0016a41106a290300370300200041106a200241b0016a41086a290300370300200041086a20022903b0013703000c040b200241b0016a200141046a108504200041046a200241b0016a41c80010e4071a200041173602000c030b200241b0016a200141086a108604200041086a200241b0016a41f00010e4071a200041183602000c020b4102210c0240024002400240200141086a22032d0000417f6a220f41024b0d0041012105200f0e03030201030b419cf7ca00412841b8a1cc001033000b200141c8006a2903002107200141c0006a2903002106200141386a2903002109200141306a2903002108200141d0006a28020021044103210c0b200241c8016a200341196a290000370300200241c0016a200341116a290000370300200241b8016a200341096a290000370300200220032900013703b001200c21050b200020022903b0013700092000200228000836002920004119360200200041c8006a2007370300200041c0006a2006370300200041386a2009370300200041306a2008370300200041086a20053a0000200041d0006a2004360200200041116a200241b0016a41086a290300370000200041196a200241c0016a290300370000200041216a200241c8016a2903003700002000412c6a2002410b6a2800003600000c010b200241b0016a200141046a10f5032000411a3602002000413c6a200241e8016a280200360200200041346a200241e0016a2903003702002000412c6a200241d8016a290300370200200041246a200241d0016a2903003702002000411c6a200241c8016a290300370200200041146a200241c0016a2903003702002000410c6a200241b8016a290300370200200020022903b0013702040b200241e0036a24000f0b1038000b1032000b1039000b1030000beffa0409047f017e047f027e047f017e087f267e147f230022032104200341e0106b4160712203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c020301040506070801090a0b0c010d0e0f1011121314151617181900020b200341a00e6a41206a200141286a290300370300200341a00e6a41186a200141206a290300370300200341a00e6a41106a200141186a290300370300200341a00e6a41086a200141106a2903003703002003200141086a2903003703a00e200341c0036a41206a200241206a290200370300200341c0036a41186a200241186a290200370300200341c0036a41106a200241106a290200370300200341c0036a41086a200241086a290200370300200320022902003703c0032000200341a00e6a200341c0036a10af05200424000f0b000b410221052001410c6a2802002106200141106a2903002207a721082007422088a7210920022d0001210a20022d0000210b024002400240024002400240024002400240024002400240200141086a280200417f6a0e0a00010203040506070809000b4200210720004200370308200a200b41ff01714100477241ff0171450d0a200041186a410236020020004201370300200424000f0b0240200b41ff01710d00200a41ff01714101470d002008450d09200610290c090b02402008450d00200610290b20004200370308200041186a410236020020004201370300200424000f0b0240200a200b41ff01714100477241ff01710d00410810272203450d632003200737000041e8f2cb00ad4280808080a001842003ad42808080808001841003200310290c080b20004200370308200041186a410236020020004201370300200424000f0b0240200a200b41ff01714100477241ff0171450d000c83010b200341a00e6a2007428080808070832006ad220c841013108b0220032802a00e2202450d810120032802a40e21012003200341a80e6a2802003602dc0b200320023602d80b200341186a200341d80b6a10c80120032802180d800120032802dc0b2209200328021c220b490d8001200b417f4c0d6202400240200b0d00410021094101210a0c010b200b102d220a450d62200a20032802d80b2205200b10e4071a20032009200b6b3602dc0b20032005200b6a3602d80b200b21090b200a450d8001200341106a200341d80b6a10c801200bad4220862009ad84220da7210920032802100d7e20032802dc0b220b20032802142205490d7e2005417f4c0d620240024020050d00410021054101210e0c010b2005102d220e450d62200e20032802d80b220f200510e4071a2003200b20056b220b3602dc0b2003200f20056a3602d80b0b200e450d7e02400240024002400240200b4104490d00200320032802d80b220f41046a3602d80b2003200b417c6a22103602dc0b20104104490d012003200f41086a3602d80b200f28000421112003200b41786a22103602dc0b20104104490d032003200b41746a3602dc0b2003200f410c6a3602d80b200341086a200341d80b6a10c8012003280208450d020c82010b02402005450d00200e10290b20090d83010c84010b02402005450d00200e10290b20090d82010c83010b200328020c220f20032802dc0b410c6e220b200b200f4b1bad420c7e2212422088a70d642012a72210417f4c0d640240024020100d00410421130c010b201010272213450d640b4100210b200341003602c803200320133602c00320032010410c6e3602c40302400240200f450d000340200341b00a6a200341d80b6a10ab0420032d00b00a4101460d0220032802dc0b22104104490d0220032900b10a211220032802d80b2214280000211520032010417c6a3602dc0b2003201441046a3602d80b0240200b20032802c403470d00200341c0036a200b4101109d0120032802c003211320032802c803210b0b2013200b410c6c6a22102015360208201020123702002003200b41016a220b3602c803200f417f6a220f0d000b0b2013450d800120032902c403a7210f20032802dc0b41044f0d020240200f450d00200f410c6c450d00201310290b02402005450d00200e10290b2009450d83010c82010b20032802c4032203450d7f2003410c6c450d7f201310290c7f0b02402005450d00200e10290b20090d80010c81010b200d422088a7211002402001450d00200210290b410f21014197e5ca0021024100210b20104108470d7c0240200a41aca0c500460d00200a29000042f0deb1db968cd9b7f400520d7d0b024020110d00411a210141fde4ca0021024101210b0c7d0b02402009450d00200a10290b02402005450d00200e10290b0240200f450d00200f410c6c450d00201310290b41f2f2cb00ad4280808080d00084200742808080807083200c841003200341c8036a41023a0000200341003a00c003200341c0036a10cb012008450d06200610290c060b0240200a200b41ff01714100477241ff01710d0041f2f2cb00ad4280808080d000842007428080808070832006ad841003200341c8036a41023a0000200341003a00c003200341c0036a10cb012008450d06200610290c060b02402008450d00200610290b20004200370308200041186a410236020020004201370300200424000f0b200a200b41ff01714100477241ff01710d1d0240024020064101460d0041f7f2cb00ad4280808080d0018410040c010b410410272202450d6e20022008360000200241044108102b2202450d6e2002200936000441f7f2cb00ad4280808080d001842002ad42808080808001841003200210290b200341cc036a2009360200200341c8036a2008360200200320063602c403200341043a00c003200341c0036a10d3030c040b0240200a200b41ff01714100477241ff01710d000240200941186c2203450d00200620036a2102200621030340200341086a350200422086200335020084200341146a3502004220862003410c6a350200841003200341186a22032002470d000b0b02402009450d00200941186c21022006210303400240200341046a280200450d00200328020010290b0240200341106a280200450d002003410c6a28020010290b200341186a2103200241686a22020d000b0b2008450d04200841186c450d04200610290c040b02402009450d00200941186c21022006210303400240200341046a280200450d00200328020010290b0240200341106a280200450d002003410c6a28020010290b200341186a2103200241686a22020d000b0b02402008450d00200841186c450d00200610290b20004200370308200041186a410236020020004201370300200424000f0b0240200a200b41ff01714100477241ff01710d0002402009410c6c2203450d00200620036a2102200621030340200341086a35020042208620033502008410042003410c6a22032002470d000b0b02402009450d002009410c6c21022006210303400240200341046a280200450d00200328020010290b2003410c6a2103200241746a22020d000b0b2008450d032008410c6c450d03200610290c030b02402009450d002009410c6c21022006210303400240200341046a280200450d00200328020010290b2003410c6a2103200241746a22020d000b0b02402008450d002008410c6c450d00200610290b20004200370308200041186a410236020020004201370300200424000f0b0240200a200b41ff01714100477241ff01710d002007428080808070832006ad8410062008450d02200610290c020b02402008450d00200610290b20004200370308200041186a410236020020004201370300200424000f0b2002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f010021060240200b41ff0171450d00200320073702b403200320013a00b303200320083a00b203200320063b01b0030c750b200241156a2d0000210b200241146a2d00002109200241126a2f01002105200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021142002410c6a2d000021152002410a6a2f01002113200241096a2d00002111200241086a2d00002116200241066a2f01002117200241056a2d00002118200241046a2d00002119200241026a2f0100211a200320073703b00341012102200a41ff01714101470d74200320073703b80e200320013a00b70e200320083a00b60e200320063b01b40e2003200b3a00b30e200320093a00b20e200320053b01b00e2003200e3a00af0e2003200f3a00ae0e200320103b01ac0e200320143a00ab0e200320153a00aa0e200320133b01a80e200320113a00a70e200320163a00a60e200320173b01a40e200320183a00a30e200320193a00a20e2003201a3b01a00e200341b00a6a200341a00e6a10a802200341c0036a20032802b00a220120032802b80a10a902420021074200210c4200210d420021124200211b4200211c4200211d4200211e024020032903c0034201520d0020032d008c04452102200341d0036a290300211e200341e0036a290300210c200341d8036a2903002107200341f0036a2903002112200341e8036a290300210d20034180046a290300211c200341f8036a290300211b20032903c803211d0b024020032802b40a450d00200110290b024020020d00410f210b41bee4ca002101418080102103410321020c760b0240200d200784201b84201d842012200c84201c84201e8484500d004113210b41cde4ca0021014180800c2103410321020c760b200341c0036a41186a200341a00e6a41186a290300370300200341c0036a41106a200341a00e6a41106a290300370300200341c0036a41086a200341a00e6a41086a290300370300200320032903a00e3703c003200341b00a6a200341c0036a10ca0320033502b80a42208620032802b00a2202ad84100420032802b40a450d00200210290b42002107200042003703080b20002007370300200424000f0b200141186a2802002106200141146a280200210e200141106a28020021092001410c6a280200210a200141086a280200210820022d0001210b20022d0000210220012d000521050240024002400240024020012d00040e050001020304000b200341c0036a41146a4101360200200342013702c40320034198e3ca003602c003200341043602b40a200341cce3ca003602b00a2003200341b00a6a3602d003200341c0036a4180a6cc001040000b41002101200b200241ff01714100477241ff01710d1a200341a00e6a200641a80210e4071a0240200a4101470d002009410047200e41014b712101200e417f6a21020b200341c0036a200341a00e6a41a80210e4071a20034180066a20053a0000200341fc056a2002360200200320093602f805200320013602f40541002102200341003602e8052008200341c0036a10ca01200341c0036a200810c00120032802c803210b20032802c0032101200341dc0b6a41003a0000200341003602d80b200341286a2001200b200341d80b6a4105410010c7010240024020032802280d000c010b2003200328022c2202410520024105491b3602b40a2003200341d80b6a3602b00a200341206a200341b00a6a10c8012003280224417f6a210b20032802204521020b024020032802c403450d00200110290b200341c8036a2008360200200341003602c403200341cc036a200b410020021b360200200341013a00c003200341c0036a10cb0120061029420021070c730b418284042101200b200241ff01714100477241ff01710d1a200341b00a6a200810c001200341c0036a20032802b00a220920032802b80a220510c10120032802c0032202410820021b2106024002400240200a20032902c403420020021b221b422088a7220b4f0d002006200a41c8026c6a22010d010b200341023602b40e20032903b80e210d20032903a80e210c20032903a00e211220032903b00e21070c010b200341023602d403200141186a290300211f2006200a41c8026c6a22022903a002211220012903102120200129030821212001290300212220032903d803211c20032903c803210d20032903d003210c200220032903c0033703a002200241b0026a220129030021072001200c370300200241a8026a2201290300210c2001200d370300200241b8026a2201290300210d2001201c370300200320123703a00e2003200d3703b80e200320073703b00e2003200c3703a80e200229038002211d20022903e001212320022903c001212420022903a0012125200229038001212620022903602127200229034021282002290320212920024198026a290300212a20024190026a290300212b20024188026a290300211e200241f8016a290300212c200241f0016a290300212d200241e8016a290300212e200241d8016a290300212f200241d0016a2903002130200241c8016a2903002131200241b8016a2903002132200241b0016a2903002133200241a8016a290300213420024198016a290300213520024190016a290300213620024188016a2903002137200241f8006a2903002138200241f0006a2903002139200241e8006a290300213a200241d8006a290300213b200241d0006a290300213c200241c8006a290300213d200241386a290300213e200241306a290300213f200241286a2903002140200241c0026a290300211c0b0240024020060d002005ad4220862009ad8410040c010b200341c0036a2006200b10e2022005ad4220862009ad8420033502c80342208620032802c0032202ad841003024020032802c403450d00200210290b0240200b450d00200b41c8026c21012006210203400240200241b4026a2802004102460d000240200241a8026a280200220b450d00200241ac026a280200450d00200b10290b200210c2010b200241c8026a2102200141b87d6a22010d000b0b201ba72202450d00200241c8026c450d00200610290b024020032802b40a450d00200910290b4183840421012007422088a74102460d1a200341e8056a200c370300200341e0056a2012370300200341c8056a201e370300200341c0056a201d370300200341a8056a202e370300200341a0056a202337030020034188056a203137030020034180056a2024370300200341e8046a2034370300200341e0046a2025370300200341c8046a2037370300200341c0046a2026370300200341a8046a203a370300200341a0046a202737030020034188046a203d37030020034180046a2028370300200341e8036a2040370300200341e0036a2029370300200341f0056a22022007370300200341d0056a202b370300200341b0056a202d37030020034190056a2030370300200341f0046a2033370300200341d0046a2036370300200341b0046a203937030020034190046a203c370300200341f0036a203f370300200341f8056a200d370300200341d8056a202a370300200341b8056a202c37030020034198056a202f370300200341f8046a2032370300200341d8046a2035370300200341b8046a203837030020034198046a203b370300200341f8036a203e370300200341d8036a201f370300200320223703c0032003201c37038006200320213703c803200320203703d0030240200ca7450d00200341a80e6a2002280200360200200320032903e8053703a00e200341b00a6a200341a00e6a10b00520033502b80a42208620032802b00a2202ad84100420032802b40a450d00200210290b200341ac0e6a200a360200200341a80e6a2008360200200341013602a40e200341013a00a00e200341a00e6a10cb01200341c0036a10cc01420021070c720b200141246a280200210f41002110024002400240200b200241ff01714100477241ff01710d002001411c6a2902002107200320093602b80a2003200a3602b40a200320083602b00a200341c0036a200f41a80210e4071a200341a00e6a200341b00a6a200e20062007a72007422088a72005200341c0036a10dc0420032802a00e4101460d01200f1029420021070c740b200f10cc01200f1029410221030240200a0d000c020b200810290c010b200341a80e6a290300210c20032802a40e2103200f102942002107200341ff01714104460d72200341807e7121100b2000411c6a200c370200200041186a2010200341ff0171723602000c700b02400240200b200241ff01714100477241ff01710d00200320093602c8032003200a3602c403200320083602c003200341a00e6a200341c0036a10b1054200210720032d00a00e22024104460d7220032f00a10e20032d00a30e41107472210120032902a40e21070c010b410221020240200a450d00200810290b0b2000411c6a2007370200200041186a20014108742002723602000c6f0b0240024020022d00000d0020022d000141ff01714102470d00200141086a2903002107200341800e6a41186a220a4200370300200341800e6a41106a22024200370300200341800e6a41086a22014200370300200342003703800e41ccbec500ad4280808080900184220c1001220b290000210d200b2900082112200b1029200120123703002003200d3703800e41ac84cc00ad428080808090018410012208290000210d20034190066a41086a220b200841086a2900003703002003200d37039006200810292002200329039006220d370300200341b0066a41086a22062001290300370300200341b0066a41106a2209200d370300200341b0066a41186a2205200b290300370300200320032903800e3703b006200341c0006a200341b0066a41204180a6cc004100410010c70120032802404101460d1a200a42003703002002420037030020014200370300200342003703800e200c10012208290000210c2008290008210d200810292001200d3703002003200c3703800e41aafac400ad42808080803084220c10012208290000210d200b200841086a2900003703002003200d37039006200810292002200329039006370000200241086a200b29030037000020062001290300370300200920022903003703002005200a290300370300200320032903800e3703b006200341306a200341b0066a10b5012003290338220d42b8177c2007580d01200d500d012003280230450d0141cd9bc50041ce0041b8a1cc001033000b20004200370308200041186a410236020020004201370300200424000f0b200341800e6a41186a220b4200370300200341800e6a41106a220a4200370300200341800e6a41086a22014200370300200342003703800e41ccbec500ad4280808080900184220d1001220829000021122008290008211b200810292001201b370300200320123703800e200c10012206290000210c20034190066a41086a2208200641086a2900003703002003200c37039006200610292002200329039006370000200241086a22092008290300370000200341b0066a41086a22052001290300370300200341b0066a41106a220e200a290300370300200341b0066a41186a220f200b290300370300200320032903800e3703b006200320073703c003200341b0066aad42808080808004842207200341c0036aad42808080808001841003200b4200370300200a420037030020014200370300200342003703800e200d10012206290000210c2006290008210d200610292001200d3703002003200c3703800e41ac84cc00ad428080808090018410012206290000210c2008200641086a2900003703002003200c370390062006102920022003290390063700002009200829030037000020052001290300370300200e200a290300370300200f200b290300370300200320032903800e3703b006200341013a00b0032007200341b0036aad4280808080108410032000420037030820004200370300200424000f0b200141156a29000021072001410d6a290000210c2002411a6a290100211b200241196a2d00002108200241186a2d00002106200241166a2f01002109200241156a2d00002105200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021142002410e6a2f010021152002410d6a2d000021132002410c6a2d000021112002410a6a2f01002116200241096a2d00002117200241086a2d00002118200241066a2f01002119200241056a2d0000211a200241046a2d00002141200241026a2f01002142200141286a28020021432001411d6a290000210d200141056a2900002212421888a7210a20022d0001210b20022d000021020240024002400240024020012d00040e050001020304000b200341c0036a41146a4101360200200342013702c40320034198e3ca003602c003200341043602b40a200341cce3ca003602b00a2003200341b00a6a3602d003200341c0036a4180a6cc001040000b200241ff01710d1b200b41ff01714101470d1b2003201b3703f00b200320083a00ef0b200320063a00ee0b200320093b01ec0b200320053a00eb0b2003200e3a00ea0b2003200f3b01e80b200320103a00e70b200320143a00e60b200320153b01e40b200320133a00e30b200320113a00e20b200320163b01e00b200320173a00df0b200320183a00de0b200320193b01dc0b2003201a3a00db0b200320413a00da0b200320423b01d80b200341f0076a200a108005200341c0036a20032802f007220e20032802f807220f10b205200341a00e6a41086a2202200341c0036a41106a290300370300200341a00e6a41106a2201200341c0036a41186a290300370300200341a00e6a41186a220b200341e0036a290300370300200320032903c8033703a00e024020032903c0034201510d00200341b00a6a41086a200341d80b6a41086a290300370300200341b00a6a41106a200341d80b6a41106a290300370300200341b00a6a41186a200341d80b6a41186a290300370300200320032903d80b3703b00a200342003703980920034280d0dbc3f402370390092003200341d80b6a3602e8022003200341d80b6a3602d0062003200341d0066a3602c8032003200341e8026a3602c403200320034190096a3602c003200341a00e6a200341d80b6a200341c0036a108e04024020032802a00e4101470d00200341ac0e6a2802002101200341a80e6a280200210b20032d00a70e210820032d00a60e210620032d00a50e210920032d00a40e21100c6e0b410421100240200341a00e6a41086a2903004201510d000c6e0b200341a00e6a41106a290300210720032802d0062102200341f8036a200341a00e6a41186a290300370300200341f0036a2007370300200341c0036a41086a41003a0000200341c9036a2002290000370000200341d1036a200241086a290000370000200341d9036a200241106a290000370000200341e1036a200241186a290000370000200341033a00c003200341c0036a10cb010c6d0b200341b00a6a41186a200b290300370300200341b00a6a41106a2001290300370300200341b00a6a41086a2002290300370300200320032903a00e3703b00a4105210941fbf7c400210b410221064103210241002105410521010c6d0b200341b00a6a41106a2007370300200320123703b00a2003200d3703c80a2003200c3703b80a0240200241ff01710d00200b41ff01714101470d002003201b3703b80e200320083a00b70e200320063a00b60e200320093b01b40e200320053a00b30e2003200e3a00b20e2003200f3b01b00e200320103a00af0e200320143a00ae0e200320153b01ac0e200320133a00ab0e200320113a00aa0e200320163b01a80e200320173a00a70e200320183a00a60e200320193b01a40e2003201a3a00a30e200320413a00a20e200320423b01a00e0240200341a00e6a200341b00a6a412010e7070d0041002101410321024105210b410b210a41f0f7c4002108410321060c6c0b20034190096a2043108005200341c0036a2003280290092209200328029809220510b205410321024105210b41002101024020032903c0034201510d004188f8c4002108410b210a410021060c6b0b200341f0036a290300210c200341e8036a290300210d200341d0036a220a2903002112200341c0036a41206a290300210720032903c803211b200a200341d8036a290300370300200320073703d8032003201b3703c003200320123703c803200341c0036a200341a00e6a412010e7070d1c200341d80b6a200341a00e6a200341b00a6a200d200c410110e903200341d80b6a41086a29030021120240024020032802d80b4101460d004200200c200341d80b6a41106a2903007d200d201254ad7d2207200d20127d2212200d562007200c562007200c511b22021b210c4200201220021b210d200341b00a6a41106a290300211b20032903b80a211c20032903b00a211d20032903c80a2107420121124100210b41002106410021010c010b20032802dc0b22024118762101200241107621062002410876210b2012422088a7210a2012a72108200241ff01714104470d6b420021120b200341f0036a200c370300200341e8036a200d370300200341e0036a2007370300200320123703c003200341d8036a201b3703002003201d3703c8032003201c3703d0030240024020124201510d002005ad4220862009ad8410040c010b200320053602dc0b200320093602d80b200341c8036a200341d80b6a10b3050b410421020c6a0b4100210b4102210241002106410021010c6a0b0240200241ff01710d00200b41ff01714101470d002003201b3703f00b200320083a00ef0b200320063a00ee0b200320093b01ec0b200320053a00eb0b2003200e3a00ea0b2003200f3b01e80b200320103a00e70b200320143a00e60b200320153b01e40b200320133a00e30b200320113a00e20b200320163b01e00b200320173a00df0b200320183a00de0b200320193b01dc0b2003201a3a00db0b200320413a00da0b200320423b01d80b200341f0076a200a108005200341c0036a20032802f007220620032802f807220b10b2054103210241002101024020032903c0034201510d004188f8c400210b410b21080c680b200341f0036a2903002112200341e8036a290300211b200341c0036a41106a2903002107200341c0036a41206a290300210c20032903c803210d200341b00a6a41106a200341d8036a2903003703002003200c3703c80a2003200d3703b00a200320073703b80a200341b00a6a200341d80b6a412010e7070d1c2003201b3703900920032012370398090240201b201284500d002003200341d80b6a3602d006200341a00e6a200341d80b6a20034190096a200341d0066a10ea0320032903a00e4201520d0020032903a80e2107200341f8036a200341a00e6a41106a290300370300200341f0036a2007370300200341c0036a41086a41003a0000200341c9036a20032903d80b370000200341d1036a200341d80b6a41086a290300370000200341d9036a200341d80b6a41106a290300370000200341e1036a200341f00b6a290300370000200341033a00c003200341c0036a10cb010b200bad4220862006ad841004410421020c670b41002101410221020c670b200b200241ff01714100477241ff01710d1b20034190096a2043108005200341c0036a2003280290092202200328029809220610b205200341f0036a2101200341e8036a210b200341d8036a210a200341e0036a2108024020032903c0034201520d002001290300211b200b290300211c200341c0036a41106a290300211d2008290300211e20032903c803212b200341b00a6a41106a200a2903003703002003201e3703c80a2003202b3703b00a2003201d3703b80a2003201c3703d80b2003201b3703e00b201c201b84500d002003200341b00a6a3602f007200341a00e6a200341b00a6a200341d80b6a200341f0076a10ea0320032903a00e4201520d0020032903a80e211b200341f8036a200341a00e6a41106a290300370300200341f0036a201b370300200341c0036a41086a41003a0000200341c9036a20032903b00a370000200341d1036a200341b00a6a41086a290300370000200341d9036a200341b00a6a41106a290300370000200341e1036a200341c80a6a290300370000200341033a00c003200341c0036a10cb010b20014200370300200b42003703002008200d370300200a2007370300200320123703c803200342013703c0032003200c3703d003200320063602a40e200320023602a00e200341c8036a200341a00e6a10b3050240200328029409450d00200210290b200341cd036a200c370000200341e8036a2043360200200341dd036a200d370000200341d5036a2007370000200320123700c503200341003a00c403200341023a00c003200341c0036a10cb012000420037030820004200370300200424000f0b200141216a2900002107200141206a2d000021082001411d6a2f000021062001411c6a2d00002109200141196a2f00002105200141186a2d0000210e200141156a2f0000210f200141146a2d00002110200141116a2f00002114200141106a2d000021152001410d6a2f000021132001410c6a2d00002111200141096a2f00002116200141086a2d0000210b20012d001f211720012d001b211820012d0017211920012d0013211a20012d000f214120012d000b214220032001412c6a2800003600cb0d200320012800293602c80d200141c8006a290300211b200141c0006a2903002112200141386a290300210c200141306a290300210d2002411a6a290100211c200241196a2d00002143200241186a2d00002144200241166a2f01002145200241156a2d00002146200241146a2d00002147200241126a2f01002148200241116a2d00002149200241106a2d0000214a2002410e6a2f0100214b2002410d6a2d0000214c2002410c6a2d0000214d2002410a6a2f0100214e200241096a2d0000214f200241086a2d00002150200241066a2f01002151200241056a2d00002152200241046a2d00002153200241026a2f0100215420022d0001210a20022d0000210202400240024002400240200b0e050001020304000b200341c0036a41146a4101360200200342013702c40320034198e3ca003602c003200341043602b40a200341cce3ca003602b00a2003200341b00a6a3602d003200341c0036a4180a6cc001040000b200320073703a00d200320083a009f0d200320173a009e0d200320063b019c0d200320093a009b0d200320183a009a0d200320053b01980d2003200e3a00970d200320193a00960d2003200f3b01940d200320103a00930d2003201a3a00920d200320143b01900d200320153a008f0d200320413a008e0d200320133b018c0d200320113a008b0d200320423a008a0d200320163b01880d024002400240200241ff01710d00200a41ff01714101470d002003201c3703b80e200320433a00b70e200320443a00b60e200320453b01b40e200320463a00b30e200320473a00b20e200320483b01b00e200320493a00af0e2003204a3a00ae0e2003204b3b01ac0e2003204c3a00ab0e2003204d3a00aa0e2003204e3b01a80e2003204f3a00a70e200320503a00a60e200320513b01a40e200320523a00a30e200320533a00a20e200320543b01a00e200341c0036a41186a200341880d6a41186a290300370300200341c0036a41106a200341880d6a41106a290300370300200341c0036a41086a200341880d6a41086a290300370300200320032903880d3703c003200341b00a6a200341a00e6a200341c0036a200d200c410110e00320032d00b00a22024104460d0220032f00b10a20032d00b30a41107472210120032902b40a21070c010b410221020b200042003703082000411c6a2007370200200041186a200141087420027236020020004201370300200424000f0b2000420037030820004200370300200424000f0b200320073703f00d200320083a00ef0d200320173a00ee0d200320063b01ec0d200320093a00eb0d200320183a00ea0d200320053b01e80d2003200e3a00e70d200320193a00e60d2003200f3b01e40d200320103a00e30d2003201a3a00e20d200320143b01e00d200320153a00df0d200320413a00de0d200320133b01dc0d200320113a00db0d200320423a00da0d200320163b01d80d200a200241ff01714100477241ff01710d1e200341d0066a41186a200341d80d6a41186a290300370300200341d0066a41106a200341d80d6a41106a290300370300200341d0066a41086a200341d80d6a41086a290300370300200320032903d80d3703d0064200211d20034200201b2012200d7c22074280c8afa025544100201b200c7c2007201254ad7c501b22021b221b3703f00220034200201220021b22123703e8022003200341d0066a3602f80c200341880d6a200341d0066a10a802200341d80b6a20032802880d220b20032802900d220a10a90220032903d80b212b200342003703d80b4200200c20021b21074200200d20021b210c200341a00c6a280200210820032d00a40c210602400240202b4201510d00200341f0076a41306a4200370300200341f0076a41286a4200370300200341f0076a41206a4200370300200341f0076a41186a4200370300200341f0076a41106a4200370300200341f0076a41086a4200370300200342003703f0074200211e4200211c4200210d420021240c010b200341900c6a290300212a200341d80b6a41306a2903002123200341d80b6a41206a290300211e200341d80b6a41186a290300211d200341980c6a290300212420032903e80b210d20032903e00b211c200341f0076a41206a200341d80b6a41286a290300370300200341f0076a41286a2023370300200341f0076a41306a202a370300200341f0076a41106a201d3703002003201e370388082003201c3703f0072003200d3703f8070b200c201c562007200d562007200d5122021b0d1d200c201c542007200d5420021b450d64200341800e6a41186a220e4200370300200341800e6a41106a22014200370300200341800e6a41086a22024200370300200342003703800e41dcbec500ad4280808080800184221210012209290000211b2009290008212a200910292002202a3703002003201b3703800e419fe3c200ad4280808080d00184221b10012205290000212a20034190066a41086a2209200541086a2900003703002003202a37039006200510292001200329039006222a370300200341b0066a41086a220f2002290300370300200341b0066a41106a2210202a370300200341b0066a41186a22142009290300370300200320032903800e3703b00620034190016a200341b0066a412010e30120034190016a41106a290300212a20032903980121232003280290012105200e42003703002001420037030020024200370300200342003703800e20121001220e2900002112200e290008212e200e10292002202e370300200320123703800e201b1001220e29000021122009200e41086a2900003703002003201237039006200e102920012003290390062212370300200f20022903003703002010201237030020142009290300370300200320032903800e3703b00620034200202a420020051b2212201c200c54ad2007200d7d7c7c2023420020051b221b201c200c7d222354ad7d222a201b20237d2223201b56202a201256202a2012511b22021b3703c80320034200202320021b3703c003200341c0036a2102200341b0066a21010c630b200141d8006a290300211c200141d0006a290300211d200341af066a201b3c00002003419f066a200c370000200320123700a7062003200d37009706200320032800cb0d36009306200320032802c80d36029006024002400240200a200241ff01714100477241ff01710d00200320073703b80e200320083a00b70e200320173a00b60e200320063b01b40e200320093a00b30e200320183a00b20e200320053b01b00e2003200e3a00af0e200320193a00ae0e2003200f3b01ac0e200320103a00ab0e2003201a3a00aa0e200320143b01a80e200320153a00a70e200320413a00a60e200320133b01a40e200320113a00a30e200320423a00a20e200320163b01a00e200341c0036a41186a20034190066a41186a290300370300200341c0036a41106a20034190066a41106a290300370300200341c0036a41086a20034190066a41086a29030037030020032003290390063703c003200341b00a6a200341a00e6a200341c0036a201d201c410110e00320032d00b00a22024104460d0220032f00b10a20032d00b30a41107472210120032902b40a21070c010b410221020b200042003703082000411c6a2007370200200041186a200141087420027236020020004201370300200424000f0b2000420037030820004200370300200424000f0b200320073703c806200320083a00c706200320173a00c606200320063b01c406200320093a00c306200320183a00c206200320053b01c0062003200e3a00bf06200320193a00be062003200f3b01bc06200320103a00bb062003201a3a00ba06200320143b01b806200320153a00b706200320413a00b606200320133b01b406200320113a00b306200320423a00b206200320163b01b006024002400240200241ff01710d00200a41ff01714101470d002003201c3703b80e200320433a00b70e200320443a00b60e200320453b01b40e200320463a00b30e200320473a00b20e200320483b01b00e200320493a00af0e2003204a3a00ae0e2003204b3b01ac0e2003204c3a00ab0e2003204d3a00aa0e2003204e3b01a80e2003204f3a00a70e200320503a00a60e200320513b01a40e200320523a00a30e200320533a00a20e200320543b01a00e200341c0036a41186a200341b0066a41186a290300370300200341c0036a41106a200341b0066a41106a290300370300200341c0036a41086a200341b0066a41086a290300370300200320032903b0063703c003200341b00a6a200341a00e6a200341c0036a200d200c410010e00320032d00b00a22024104460d0220032f00b10a20032d00b30a41107472210120032902b40a21070c010b410221020b200042003703082000411c6a2007370200200041186a200141087420027236020020004201370300200424000f0b2000420037030820004200370300200424000f0b2001410c6a2802002106200141086a28020021052001280204210f4102210b02400240024020022d00000d0020022d000141ff01714102470d002006410a4b0d01200341b0066a41186a220a4200370300200341b0066a41106a22084200370300200341b0066a41086a22024200370300200342003703b00641e4bec500ad4280808080a00184220710012201290000210c2001290008210d200110292002200d3703002003200c3703b0064198b7c400ad4280808080c00184221210012201290008210c2001290000210d2001102920034190066a41106a220e200d37030020034190066a41186a2210200c37030020034190066a41086a22012002290300370300200320032903b0063703900620034190066a10b201220941ff01714102460d024103210b2009410171450d020b410121144110210e41d59fc40021152006450d5f0c5e0b410221144103210b410d210e41c89fc40021150c5d0b200a42003703002008420037030020024200370300200342003703b00620071001220b290000210c200b290008210d200b10292002200d3703002003200c3703b00620121001220b290008210c200b290000210d200b1029200e200d3703002010200c37030020012002290300370300200320032903b00637039006200341013a00b00320034190066aad4280808080800484221c200341b0036aad428080808010841003200341800e6a41186a220e4200370300200341800e6a41106a22184200370300200341800e6a41086a220b4200370300200342003703800e41b3e6ca00ad4280808080e0008410012209290000210c200b200941086a2900003703002003200c3703800e2009102941c9e6ca00ad4280808080e0008410012209290000210c2001200941086a2900003703002003200c37039006200910292018200329039006220c3703002002200b2903003703002008200c370300200a2001290300370300200320032903800e3703b006200341b0016a200341b0066a412010fc0120032802b401211020032802b0012114200e420037030020184200370300200b4200370300200342003703800e2007100122092900002107200b200941086a290000370300200320073703800e20091029418cb2c400ad4280808080e000841001220929000021072001200941086a290000370300200320073703900620091029201820032903900622073703002002200b29030037030020082007370300200a2001290300370300200320032903800e3703b006200341c0036a200341b0066a10ba010240024020032802c00322110d00200341003602980920034204370390094104211141002101410021020c010b200320032902c40322073702940920032011360290092007422088a721012007a721020b2010410020141b210b024020012002470d0020034190096a20014101109f01200328029009211120032802980921010b2011200141c4006c6a220241003a000020024101360230200241013602142002200b360204200220032f01d0063b0001200241036a200341d0066a41026a2d00003a00002003200141016a221336029809200f200641f0006c22026a2144024020060d00200f210a0c5b0b200f41f4006a2108200241907f6a2109200341c0036a41106a2146200341c0036a41086a214541b3e6ca00ad4280808080e00084211b200f210a0340200a2802042116200a280200210b200341c0036a200a41086a41e80010e4071a200a41f0006a210a2016450d5b200341a00e6a200341c0036a41e80010e4071a200320163602c4032003200b3602c0032045200341a00e6a41e80010e4071a200341800e6a41186a22194200370300200341800e6a41106a221a4200370300200341800e6a41086a22174200370300200342003703800e201b1001220229000021072017200241086a290000370300200320073703800e2002102941c9e6ca00ad4280808080e0008410012202290000210720034190066a41086a2201200241086a2900003703002003200737039006200210292018200329039006370000201841086a2001290300370000200341b0066a41086a22412017290300370300200341b0066a41106a2242201a290300370300200341b0066a41186a22432019290300370300200320032903800e3703b006200341a8016a200341b0066a412010fc0120032802a801210220032802ac012101200341d80b6a200341c0036a10e204410c210e0240200b0d0041bc9fc4002115410321140c5b0b0240200b2001410020021b22024d0d0041b09fc4002115410421140c5b0b200341b00a6a200b417f6a10b4050240200341b00a6a2046412010e707450d004112210e41e59fc4002115410021140c5b0b0240200b20024f0d004108210e41949fc4002115410621140c5b0b0240024020112011201341c4006c22016a460d00201141016a2102034002402002417f6a2d00004101470d0041012110200341d80b6a2002460d032002200341d80b6a412010e707450d030b200241c4006a2102200141bc7f6a22010d000b0b410021100b200341b00a6a200b10b405200341b00a6a200341d80b6a412010e70721024114210e419c9fc40021154105211420100d5a2002450d5a200341c80d6a41026a220120032d00d2063a0000200341f80c6a41026a220b20032d00f2073a0000200320032f01d0063b01c80d200320032f01f0073b01f80c200341d80b6a200341c0036a10e204200341880d6a41186a220e4200370300200341880d6a41106a22104200370300200341880d6a41086a22144200370300200342003703880d204342003703002042420037030020414200370300200342003703b00641c80010272202450d63200341800e6a10bc01200241186a2019290300370200200241106a201a290300370200200241086a2017290300370200200220032903800e3702002002410236022020024101360244200220032903b0063702242002412c6a2041290300370200200241346a20422903003702002002413c6a2043290300370200200320023602b00a20034282808080203702b40a200341b00a6a10bd01200341b00a6a41186a200e290300370300200341b00a6a41106a2010290300370300200341b00a6a41086a2014290300370300200320032903880d3703b00a200341b00a6a10be01200341d80d6a41086a220e200341d80b6a41086a290300370300200341d80d6a41106a2210200341d80b6a41106a290300370300200341d80d6a41186a2214200341d80b6a41186a290300370300200341b00a6a41026a221520012d00003a0000200341f0076a41026a2201200b2d00003a0000200320032903d80b3703d80d200320032f01c80d3b01b00a200320032f01f80c3b01f00702402013200328029409470d0020034190096a20134101109f0120032802980921130b2003280290092211201341c4006c6a220241013a0000201429030021072010290300210c200e290300210d20032903d80d2112200241003a0021200220032f01b00a3b0030200241326a20152d00003a0000200220032f01f0073b003f200241c1006a20012d00003a000020022012370001200241096a200d370000200241116a200c370000200241196a20073700002003201341016a221336029809024020032802cc032202450d00200241246c21012016210203400240024020022d0000220b41044b0d00024002400240200b0e050400010204040b2002410c6a280200450d03200241086a28020010290c030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b200241086a280200450d00200241046a28020010290b200241246a21022001415c6a22010d000b0b024020032802c8032202450d00200241246c450d00201610290b200941907f6a2109200841f0006a2108200a2044470d000c5c0b0b200341c0036a200141086a41900210e4071a200341a00e6a41206a200241206a290200370300200341a00e6a41186a200241186a290200370300200341a00e6a41106a200241106a290200370300200341a00e6a41086a200241086a290200370300200320022902003703a00e2000200341c0036a200341a00e6a10a502200424000f0b200141086a280200214720012802042146200341c0036a2001410c6a41a40110e4071a2002411a6a2901002107200241196a2d0000210b200241186a2d0000210a200241166a2f01002108200241156a2d00002106200241146a2d00002109200241126a2f01002105200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021142002410c6a2d000021152002410a6a2f01002113200241096a2d00002111200241086a2d00002116200241066a2f01002117200241056a2d00002118200241046a2d00002119200241026a2f0100211a20022d0001210120022d0000210202402046450d00200341d0066a200341c0036a41046a41a00110e4071a024002400240200241ff01710d00200141ff01714101460d010b02402047450d00204610290b41002103410221020c010b200320073703a00d2003200b3a009f0d2003200a3a009e0d200320083b019c0d200320063a009b0d200320093a009a0d200320053b01980d2003200e3a00970d2003200f3a00960d200320103b01940d200320143a00930d200320153a00920d200320133b01900d200320113a008f0d200320163a008e0d200320173b018c0d200320183a008b0d200320193a008a0d2003201a3b01880d200341f0076a200341d0066a41a00110e4071a200341b00a6a41186a20032903a00d370300200341c00a6a20032903980d370300200341b00a6a41086a20032903900d370300200320032903880d3703b00a200341a00e6a200341b00a6a1089020240024020032d00a00e4101470d00200341da0d6a20032d00a40e22023a0000200341d80b6a41086a200341b90e6a2900002207370300200320032f01a20e22013b01d80d2003200341b10e6a290000220c3703d80b200320032d00a10e3a00e802200320013b00e902200320023a00eb02200320032900a50e3702ec022003200341ad0e6a2800003602f402200341e8026a41186a20073703002003200c3703f80220034190096a200341f0076a41a00110e4071a200341d80d6a200341e8026a10b505200341a00e6a20032802d80d220120032802e00d10b60520032d00a00e2102200341d80b6a200341a00e6a41017241a00110e4071a0240024020024101460d00200341003a00b00a0c010b200341013a00b00a200341b00a6a410172200341d80b6a41a00110e4071a0b024020032802dc0d450d00200110290b20034190096a41206a2148200341d0096a2149200341f0096a214a200341900a6a214b200341d10a6a214c200341f10a6a214d200341910b6a214e200341b10b6a214f200341b00a6a4101722150416c210a0340410021014180a6cc00210b0240024002400240200a41e8a1c5006a280000220241e0ea91cb064a22090d00200241f0c2c98b06460d01200241e2c289ab06470d03412021012048210b0c030b200241e1ea91cb06460d010240200241e9dabdf306460d00200241e7e485f306470d034120210120034190096a210b0c030b412021012049210b0c020b41202101204a210b0c010b41202101204b210b0b200320013602a80e2003200b3602a40e200320023602a00e200341d80b6a200341a00e6a10b705200341a00e6a20032802d80b220620032802e00b10cd0120032802dc0b21080240024020032d00a00e4101470d0020032900b90e210720032d00b80e210520032d00b70e210e20032f00b50e210f20032d00b40e211020032d00b30e211420032f00b10e211520032d00b00e211320032d00af0e211120032f00ad0e211620032d00ac0e211720032d00ab0e211820032f00a90e211920032d00a80e211a20032d00a70e214120032f00a50e214220032d00a40e214320032d00a30e214420032f00a10e214502402008450d00200610290b200320073703b80e200320053a00b70e2003200e3a00b60e2003200f3b01b40e200320103a00b30e200320143a00b20e200320153b01b00e200320133a00af0e200320113a00ae0e200320163b01ac0e200320173a00ab0e200320183a00aa0e200320193b01a80e2003201a3a00a70e200320413a00a60e200320423b01a40e200320433a00a30e200320443a00a20e200320453b01a00e200341a00e6a200341e8026a412010e707450d0141808008210341efdbc9002101410d210b0c040b2008450d00200610290b0240024020032d00b00a4101470d00410021084180a6cc002106024002400240024020090d00200241f0c2c98b06460d01200241e2c289ab06470d0341202108204c21060c030b200241e1ea91cb06460d010240200241e9dabdf306460d00200241e7e485f306470d0341202108205021060c030b41202108204d21060c020b41202108204e21060c010b41202108204f21060b024020012008470d00200b2006460d02200b2006200110e707450d020b200320083602a80e200320063602a40e200320023602a00e200341d80b6a200341a00e6a10b70520033502e00b42208620032802d80b2208ad84100420032802dc0b450d00200810290b200320013602a80e2003200b3602a40e200320023602a00e200341d80b6a200341a00e6a10b70520032802d80b210120033502e00b2107412010272202450d58200220032903e802370000200241186a200341e8026a41186a290300370000200241106a200341e8026a41106a290300370000200241086a200341e8026a41086a29030037000020074220862001ad842002ad428080808080048410032002102920032802dc0b450d00200110290b200a41046a220a0d000b200341a00e6a200341e8026a10b50520033502a80e210720032802a00e2101412010272202450d642002200329039009370000200241186a20034190096a41186a290300370000200241106a20034190096a41106a290300370000200241086a20034190096a41086a2903003700002002412041c000102b2202450d64200220032903b009370020200241386a20034190096a41386a290300370000200241306a20034190096a41306a290300370000200241286a20034190096a41286a290300370000200241c000418001102b2202450d64200220032903d009370040200241d8006a20034190096a41d8006a290300370000200241d0006a20034190096a41d0006a290300370000200241c8006a20034190096a41c8006a290300370000200220032903f009370060200241e8006a20034190096a41e8006a290300370000200241f0006a20034190096a41f0006a290300370000200241f8006a20034190096a41f8006a2903003700002002418001418002102b2202450d64200220032903900a3700800120024198016a20034190096a4198016a29030037000020024190016a20034190096a4190016a29030037000020024188016a20034190096a4188016a29030037000020074220862001ad842002ad4280808080801484100320021029024020032802a40e450d00200110290b024020032d00b00a0d00200341880d6a10a7020b02402047450d00204610290b2000420037030820004200370300200424000f0b41808004210341fcdbc90021014117210b0b02402047450d00204610290b410321020b20004200370308200041206a200b3602002000411c6a2001360200200041186a20034180800c712002724180187236020020004201370300200424000f0b02400240200241ff01710d00200141ff01714101470d00200320113a00d706200320163a00d606200320173b01d406200320183a00d306200320193a00d2062003201a3b01d0062003200e3a00df062003200f3a00de06200320103b01dc06200320143a00db06200320153a00da06200320133b01d8062003200b3a00e7062003200a3a00e606200320083b01e406200320063a00e306200320093a00e206200320053b01e006200320073703e806200341b00a6a41186a2007370300200341c00a6a20032903e006370300200341b00a6a41086a20032903d806370300200320032903d0063703b00a200341a00e6a200341b00a6a108902024020032d00a00e4101470d00200341d80d6a41026a20032d00a40e22023a0000200341d80b6a41086a200341b90e6a2900002207370300200320032f01a20e22013b01d80d2003200341b10e6a290000220c3703d80b200320032d00a10e3a00f007200320013b00f107200320023a00f307200320032900a50e3702f4072003200341ad0e6a2800003602fc07200341f0076a41186a20073703002003200c37038008200341e8026a200341f0076a10b505200341a00e6a20032802e802220220032802f002220b10b605024020032d00a00e2201450d00200bad4220862002ad8410040b20032d00a10e210b200341d80b6a200341a00e6a410272419f0110e4071a200341a00e6a200341d80b6a419f0110e4071a024020014101470d0020034190096a200341a00e6a419f0110e4071a024020032802ec02450d00200210290b2003200b3a00b00a200341b00a6a41017220034190096a419f0110e4071a200341a80e6a4120360200200341e7e485f3063602a00e2003200341b00a6a3602a40e200341d80b6a200341a00e6a10b70520033502e00b42208620032802d80b2202ad841004024020032802dc0b450d00200210290b200341e2c289ab063602a00e200341203602a80e2003200341b00a6a41206a3602a40e200341d80b6a200341a00e6a10b70520033502e00b42208620032802d80b2202ad841004024020032802dc0b450d00200210290b200341203602a80e2003200341f00a6a3602a40e200341e9dabdf3063602a00e200341d80b6a200341a00e6a10b70520033502e00b42208620032802d80b2202ad841004024020032802dc0b450d00200210290b200341203602a80e2003200341900b6a3602a40e200341f0c2c98b063602a00e200341d80b6a200341a00e6a10b70520033502e00b42208620032802d80b2202ad841004024020032802dc0b450d00200210290b200341203602a80e2003200341b00b6a3602a40e200341e1ea91cb063602a00e200341d80b6a200341a00e6a10b70520033502e00b42208620032802d80b2202ad841004024020032802dc0b450d00200210290b200341d0066a10b2022000420037030820004200370300200424000f0b024020032802ec02450d00200210290b4106210341e9dbc90021024180800c21014103210b0c020b4117210341fcdbc90021024180800421014103210b0c010b410021014102210b0b20004200370308200041206a20033602002000411c6a2002360200200041186a20014180800c71200b724180187236020020004201370300200424000f0b4100210b4102210a024002400240024020022d0000450d000c010b20022d000141ff01714102470d002001280204210a200341b0066a41186a22084200370300200341b0066a41106a22064200370300200341b0066a41086a22024200370300200342003703b00641eea1c800ad4280808080f001841001220129000021072001290008210c200110292002200c370300200320073703b00641fda3c800ad4280808080e000841001220129000821072001290000210c2001102920034190066a41106a200c37030020034190066a41186a200737030020034190066a41086a22012002290300370300200320032903b006370390064100210b200341c0016a20034190066a41204180a6cc004100410010c7010240024020032802c0014101470d00410e21064195d1c80021080c010b200341800e6a41186a4200370300200341800e6a41106a22054200370300200341800e6a41086a220b4200370300200342003703800e41b3e6ca00ad4280808080e00084100122092900002107200b200941086a290000370300200320073703800e2009102941c9e6ca00ad4280808080e000841001220929000021072001200941086a290000370300200320073703900620091029200520032903900622073703002002200b2903003703002006200737030020082001290300370300200320032903800e3703b006200341b8016a200341b0066a412010fc0120032802bc01410020032802b8011b200a4f0d024107210641a3d1c800210841808004210b0b4103210a0b200041206a20063602002000411c6a2008360200200041186a200b4180800471200a7241801a72360200420121070c010b42002107200341b0066a41186a4200370300200341b0066a41106a4200370300200341b0066a41086a22024200370300200342003703b00641eea1c800ad4280808080f0018410012201290000210c2001290008210d200110292002200d3703002003200c3703b00641fda3c800ad4280808080e0008410012201290008210c2001290000210d2001102920034190066a41106a200d37030020034190066a41186a200c37030020034190066a41086a2002290300370300200320032903b006370390062003200a3602c00320034190066aad4280808080800484200341c0036aad4280808080c0008410030b2000200737030020004200370308200424000f0b2002411a6a290100210c200241196a2d00002105200241186a2d0000210f200241166a2f01002110200241156a2d00002114200241146a2d00002115200241126a2f01002113200241116a2d00002111200241106a2d000021172002410e6a2f010021182002410d6a2d000021192002410c6a2d0000211a2002410a6a2f01002141200241096a2d00002142200241086a2d00002143200241066a2f01002144200241056a2d00002145200241046a2d00002146200241026a2f0100214720014198026a280200211620014194026a280200210a20014190026a280200210b2001418c026a280200210820014188026a2802002106200141186a290300210d200141086a290300210720022d0001210920022d00002102200341c0036a200141206a41e80110e4071a0240024020020d00200941ff01714101470d0020034190096a410c6a20034190056a290300370200200341a4096a20034198056a290300370200200341ac096a200341a0056a290300370200200341e7e485f30636029009200320032903880537029409200341d0066a410c6a200a360200200341d8066a200b360200200320163602e006200320083602d406200320063602d006200341d80b6a20034190096a200341d0066a10b604024020032802980c450d00200341a00e6a41066a200341d80b6a41d00010e4071a200341b00a6a200341a00e6a41d60010e4071a200341f0076a200341b00a6a41066a41d00010e4071a41201027220e0d020c610b4180801021034118210241fdd4c80021014103210b0c560b0240200a450d00200a410c6c21022008210303400240200341046a280200450d00200328020010290b2003410c6a2103200241746a22020d000b0b0240200b450d00200b410c6c450d00200810290b410021034102210b0c550b200e200c370018200e20053a0017200e200f3a0016200e20103b0014200e20143a0013200e20153a0012200e20133b0010200e20113a000f200e20173a000e200e20183b000c200e20193a000b200e201a3a000a200e20413b0008200e20423a0007200e20433a0006200e20443b0004200e20453a0003200e20463a0002200e20473b00002003200d3703b80a200320073703b00a200341b00a6a41106a200341f0076a41d00010e4072102200320163602940b200320063602900b41d00010272201450d5e200341b0066a41086a220b200241086a290300370300200341b0066a41106a220a200241106a290300370300200341b0066a41186a2208200241186a290300370300200320022903003703b006200341e00a6a290300210c200341b00a6a41386a2903002112200341f00a6a290300211b200341b00a6a41c8006a290300211c200341a00e6a200341800b6a10ee02200141386a201c3703002001201b370330200141286a20123703002001200c370320200141186a2008290300370300200141106a200a290300370300200141086a200b290300370300200120032903b006370300200120032903a00e370340200141c8006a200341a00e6a41086a280200360200410810272202450d5e20022007370000200241084110102b2202450d5e2002200d3700082003429080808080023702dc0d200320023602d80d200341a00e6a41c5cdc20010e902200341d80b6a20032802a00e220b20032802a80e108b0320032902dc0b420020032802d80b22021b210c2002410120021b2105024020032802a40e450d00200b10290b2003200c4220883e02b406200320053602b006200341d0016a200341b0066a10c8014100210620032802d0010d4f20032802d401220f20032802b406220a41306e22022002200f4b1bad42307e2212422088a70d512012a72202417f4c0d510240024020020d00410821060c010b200210272206450d510b41002109200341003602900d200320063602880d2003200241306e220236028c0d200f450d4f4100210941002114024003400240200a221041084f0d00201021020c500b200320032802b006220a41086a3602b006201041786a22024108490d4f201441016a2114200a29000021122003200a41106a3602b006200a290008211b41002102200341003a00c00e201041706a21080340200341003a00b00320082002460d02200341a00e6a20026a200a20026a220b41106a2d00003a00002003200b41116a3602b0062003200241016a220b3a00c00e200b2102200b4120470d000b20034190096a41086a200341a00e6a41086a290300221c37030020034190096a41106a200341a00e6a41106a290300221d37030020034190096a41186a200341a00e6a41186a290300221e370300200341e8026a41186a2215201e370300200341e8026a41106a2213201d370300200341e8026a41086a2211201c370300200320032903a00e221c3703d80b2003201c370390092003201c3703e80202402009200328028c0d470d00200341880d6a2009410110900120032802880d210620032802900d21090b2008200b6b210a2006200941306c6a2202201b37030820022012370300200220032903e802370310200241186a2011290300370300200241206a2013290300370300200241286a20152903003703002003200941016a22093602900d2014200f470d000b20032010200b6b41706a3602b406200328028c0d21020c500b200341003602b406200241ff0171450d4e200341003a00c00e0c4e0b2001411c6a280200210e200141186a280200210f200141146a28020021102001410c6a2802002114200141086a28020021134100210b4102210a02400240024020022d0000450d000c010b20022d000141ff01714102470d00200141246a2802002115200141106a280200210a200341800e6a41186a22084200370300200341800e6a41106a22024200370300200341800e6a41086a22014200370300200342003703800e41b1dcc900ad4280808080f000841001220b29000021072001200b41086a290000370300200320073703800e200b1029418886ca00ad4280808080c0018410012206290000210720034190066a41086a220b200641086a29000037030020032007370390062006102920022003290390062207370300200341b0066a41086a22092001290300370300200341b0066a41106a22052007370300200341b0066a41186a2211200b290300370300200320032903800e3703b006200341e0016a200341b0066a412010fc01200341c0036a20032802e401410020032802e0011b2217201510b805200341d8016a20032802c003220620032802c8034180a6cc004100410010c70120032802d8012116024020032802c403450d00200610290b200842003703002002420037030020014200370300200342003703800e41c6b7c700ad42808080808001841001220629000021072001200641086a290000370300200320073703800e2006102941dcb7c700ad4280808080c00084100122062900002107200b200641086a2900003703002003200737039006200610292002200329039006370000200241086a200b290300370000200920012903003703002005200229030037030020112008290300370300200320032903800e3703b006200341c0036a200341b0066a109e0320032802c0032202410120021b211120032902c403420020021b21070240201641014622010d00201120154105746a410020152007422088a7491b22020d020b41a0b7c70041b3b7c70020011b21084113410a20011b21062001411074210b4103210a200742ffffff3f83500d00201110290b02402014450d00201310290b0240200e450d00200e410c6c21022010210303400240200341046a280200450d00200328020010290b2003410c6a2103200241746a22020d000b0b0240200f450d00200f410c6c450d00201010290b20004200370308200041206a20063602002000411c6a2008360200200041186a200b200a7241801e7236020020004201370300200424000f0b200241086a290000210c200241106a290000210d20022900002112200341b0066a41186a200241186a290000221b370300200341b0066a41106a200d370300200341b0066a41086a200c370300200320123703b006200341cd036a200c370000200341d5036a200d370000200341dd036a201b370000200341003a00c403200341083a00c003200320123700c503200341c0036a10cb01200341003602c803200342013703c003200a200341c0036a10710240024020032802c403220b20032802c80322026b200a490d0020032802c00321010c010b2002200a6a22012002490d53200b41017422082001200820014b1b22084100480d5302400240200b0d00024020080d00410121010c020b200810272201450d600c010b20032802c0032101200b2008460d002001200b2008102b2201450d5f0b200320083602c403200320013602c0030b200120026a2013200a10e4071a20032002200a6a3602c803200e200341c0036a1071200e450d172010200e410c6c6a210520102101034020012802002109200141086a2802002202200341c0036a10710240024020032802c403220a20032802c803220b6b2002490d0020032802c0032108200a21060c010b200b20026a2208200b490d54200a41017422062008200620084b1b22064100480d5402400240200a0d00024020060d00410121080c020b200610272208450d610c010b20032802c0032108200a2006460d002008200a2006102b2208450d600b200320063602c403200320083602c0030b2008200b6a2009200210e4071a2003200b20026a22023602c8032001410c6a22012005470d000c4c0b0b200341c0036a41306a200141386a290300370300200341c0036a41286a200141306a290300370300200341c0036a41206a200141286a290300370300200341c0036a41186a200141206a290300370300200341c0036a41106a200141186a290300370300200341c0036a41086a200141106a2903003703002003200141086a2903003703c003200341a00e6a41206a200241206a290200370300200341a00e6a41186a200241186a290200370300200341a00e6a41106a200241106a290200370300200341a00e6a41086a200241086a290200370300200320022902003703a00e2000200341c0036a200341a00e6a10b905200424000f0b200341c0036a41306a200141386a290300370300200341c0036a41286a200141306a290300370300200341c0036a41206a200141286a290300370300200341c0036a41186a200141206a290300370300200341c0036a41106a200141186a290300370300200341c0036a41086a200141106a2903003703002003200141086a2903003703c003200341a00e6a41206a200241206a290200370300200341a00e6a41186a200241186a290200370300200341a00e6a41106a200241106a290200370300200341a00e6a41086a200241086a290200370300200320022902003703a00e2000200341c0036a200341a00e6a10ba05200424000f0b200141146a2802002106200141106a280200210b2001410c6a28020021082002411a6a290100210c200241196a2d00002109200241186a2d00002105200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002114200241116a2d00002115200241106a2d000021132002410e6a2f010021112002410d6a2d000021162002410c6a2d000021172002410a6a2f01002118200241096a2d00002119200241086a2d0000211a200241066a2f01002141200241056a2d00002142200241046a2d0000214341022150200241026a2f01002144200141386a290300210d200141306a28020021512001412c6a280200214f200141206a2d000021462001411e6a2f010021472001411c6a2d000021482001411a6a2f01002149200141186a2d0000214a2001410a6a2f0100214b200141226a290100210720022d0001210a20022d0000210220012d0021214c20012d001d214d20012d0019214e20012d00092145024002400240024002400240200141086a2d00000e06000102030405000b200341c0036a41146a4101360200200342013702c40320034198e3ca003602c003200341043602b40a200341cce3ca003602b00a2003200341b00a6a3602d003200341c0036a4180a6cc001040000b200141346a28020021012003200da722093602f0070240200a200241ff01714100477241ff01710d000240200141e500490d0041002802d8a74c450d00200341ac0e6a4101360200200341013602a40e200341b0e3c8003602a00e2003200136029009200320034190096a3602a80e41002802888040210241002802848040210a41002802dca74c210920034180046a418003360200200341f8036a42de80808010370300200341f4036a41dde3c800360200200341ec036a4211370200200341e8036a41cce3c800360200200341e0036a4202370300200341d0036a4203370300200341c8036a4111360200200341dc036a200341a00e6a360200200341b4e3c8003602cc03200341cce3c8003602c403200341013602c003200a4180a4c000200941024622091b200341c0036a20024198a4c00020091b28021011020020032802f00721090b200341800e6a41186a4200370300200341800e6a41106a22054200370300200341800e6a41086a22024200370300200342003703800e41a6d4c800ad4280808080b002841001220a290000210c2002200a41086a2900003703002003200c3703800e200a102941f0edca00ad4280808080f000841001220a290000210c20034190066a41086a220e200a41086a2900003703002003200c37039006200a10292005200329039006220c370300200341b0066a41086a2002290300370300200341b0066a41106a200c370300200341b0066a41186a200e290300370300200320032903800e3703b006200341c0036a200341b0066a108d0220032802c0032202410120021b210a0240200920032902c403420020021b220c422088220da722024f0d0041002802d8a74c4102490d00200341ac0e6a4101360200200341013602a40e2003200236029009200320034190096a3602a80e2003200341f0076a3602a00e41002802888040210941002802848040210541002802dca74c210e20034180046a418903360200200341f8036a42de80808010370300200341f4036a41dde3c800360200200341ec036a4211370200200341e8036a41cce3c800360200200341e0036a4202370300200341d0036a4203370300200341c8036a4111360200200341dc036a200341a00e6a36020020034190d5c9003602cc03200341cce3c8003602c403200341023602c00320054180a4c000200e410246220e1b200341c0036a20094198a4c000200e1b2802101102000b204f200110bb05204f2001200a200210bc0502400240204541ff01710d00200341b0066a41186a4200370300200341b0066a41106a4200370300200341b0066a41086a22024200370300200342003703b00641a6d4c800ad4280808080b002841001220b2900002107200b2900082112200b102920022012370300200320073703b00641f8d7ca00ad4280808080d000841001220b2900082107200b2900002112200b1029200341d80d6a41106a2012370300200341d80d6a41186a2007370300200341d80d6a41086a2002290300370300200320032903b0063703d80d200341d80d6aad428080808080048410040c010b200320073703d8032003204c3a00d703200320463a00d603200320473b01d4032003204d3a00d303200320483a00d203200320493b01d0032003204e3a00cf032003204a3a00ce03200320064110763b01cc03200320064108763a00cb03200320063a00ca032003200b4110763b01c8032003200b4108763a00c7032003200b3a00c603200320084110763b01c403200320084108763a00c303200320083a00c2032003204b3b01c00320034190066a41186a420037030020034190066a41106a2206420037030020034190066a41086a220b4200370300200342003703900641a6d4c800ad4280808080b0028410012208290000210720034190096a41086a2202200841086a290000370300200320073703900920081029200b200229030037030020032003290390093703900641f8d7ca00ad4280808080d000841001220829000021072002200841086a29000037030020032007370390092008102920062003290390092207370300200341880d6a41086a200b290300370300200341880d6a41106a2007370300200341880d6a41186a200229030037030020032003290390063703880d412010272202450d52200220032903c003370000200241186a200341c0036a41186a290300370000200241106a200341c0036a41106a290300370000200241086a200341c0036a41086a290300370000200341880d6aad42808080808004842002ad42808080808004841003200210290b200d42c0de810a7e2001ad42b0db067e7c21070240205141ffffff3f71450d00204f10290b200742809591c7397c21070240200c42ffffff3f83500d00200a10290b200041106a20073703002000420137030820004200370300200424000f0b0240205141ffffff3f71450d00204f10290b200320032900b00a3703d80b2003200341b70a6a2900003700df0b200041186a41023a000020004200370308200020032903d80b370019200041206a20032900df0b37000020004201370300200424000f0b2003200c3703f00d200320093a00ef0d200320053a00ee0d2003200e3b01ec0d2003200f3a00eb0d200320103a00ea0d200320143b01e80d200320153a00e70d200320133a00e60d200320113b01e40d200320163a00e30d200320173a00e20d200320183b01e00d200320193a00df0d2003201a3a00de0d200320413b01dc0d200320423a00db0d200320433a00da0d200320443b01d80d0240024002400240200a41ff01714101470d00200241ff01710d0020034190096a41186a200341d80d6a41186a29030037030020034190096a41106a200341d80d6a41106a29030037030020034190096a41086a200341d80d6a41086a290300370300200320032903d80d37039009200341800e6a41186a4200370300200341800e6a41106a220a4200370300200341800e6a41086a22024200370300200342003703800e41a6d4c800ad4280808080b002841001220129000021072002200141086a290000370300200320073703800e2001102941f0edca00ad4280808080f0008410012201290000210720034190066a41086a2206200141086a290000370300200320073703900620011029200a2003290390062207370300200341b0066a41086a2002290300370300200341b0066a41106a2007370300200341b0066a41186a2006290300370300200320032903800e3703b006200341c0036a200341b0066a108d0220032902c403420020032802c00322021b2207422088220ca741057421012002410120021b22062102024002400340024020010d004100210341eeebca002102410921010c020b024020034190096a2002460d00200141606a2101200220034190096a412010e707210a200241206a2102200a0d010b0b200341003602c803200342013703c0032008200341c0036a10bf0220032802c8032101024020032802c403450d0020032802c00310290b2001200b4d0d014109210341e7d5c8002102411321010b4103210b200742ffffff3f83500d02200610290c020b200341003602c803200342013703c0032008200341c0036a10bf0220032802c403210b200341d80b6a41186a220a20033502c80342208620032802c003220ead841010220241186a290000370300200341d80b6a41106a2209200241106a290000370300200341d80b6a41086a2205200241086a290000370300200320022900003703d80b200210290240200b450d00200e10290b200341c0036a200841a80210e4071a200341a00e6a410d6a20034190096a41086a290300370000200341a00e6a41156a20034190096a41106a290300370000200341a00e6a411d6a20034190096a41186a290300370000200341013a00a40e20032003290390093700a50e200341023a00a00e200341b00a6a200341c0036a200341a00e6a10c50120034190066a41086a2202200529030037030020034190066a41106a220b200929030037030020034190066a41186a2209200a290300370300200320032903d80b37039006200341b00a6a41186a2d0000210a200341cb0a6a2d0000210520032903b00a211220032903b80a210d20032902cc0a211b20032f00c90a210e200341053a00c4032003410b3a00c003200341c0036a410d6a2002290300370000200341c0036a41156a200b290300370000200341c0036a411d6a2009290300370000200341eb036a20053a0000200341e9036a200e3b0000200341ec036a201b370200200341e8036a41044104200a200d4202511b20124201521b3a000020032003290390063700c503200341e5036a20032f01d0063b0000200341e7036a200341d0066a41026a2d00003a0000200341f4036a20032902a00e370200200341fc036a200341a00e6a41086a29020037020020034184046a200341a00e6a41106a2902003702002003418c046a200341a00e6a41186a280200360200200341c0036a10cb01200da70d024200210c0c030b4102210b0b200810cc0120081029200041206a20013602002000411c6a2002360200200020033a001a200041133a0019200041186a200b3a00002000420037030820004201370300200424000f0b427f2001ad42a01f7e200c42c0a9077e7c4280d8f1167c220c200341c00a6a2903007c220d200d200c541b210d4201210c0b0240200742ffffff3f83500d00200610290b20081029200041106a200d3703002000200c37030820004200370300200424000f0b2003200b3602f007410221010240200241ff0171450d000c4a0b200a41ff01714101470d492003200c3703a809200320093a00a709200320053a00a6092003200e3b01a4092003200f3a00a309200320103a00a209200320143b01a009200320153a009f09200320133a009e09200320113b019c09200320163a009b09200320173a009a09200320183b019809200320193a0097092003201a3a009609200320413b019409200320423a009309200320433a009209200320443b019009200341800e6a41186a4200370300200341800e6a41106a22094200370300200341800e6a41086a22024200370300200342003703800e41a6d4c800ad4280808080b002841001220129000021072002200141086a290000370300200320073703800e2001102941f0edca00ad4280808080f0008410012201290000210720034190066a41086a220a200141086a29000037030020032007370390062001102920092003290390062207370300200341b0066a41086a2002290300370300200341b0066a41106a2007370300200341b0066a41186a200a290300370300200320032903800e3703b006200341c0036a200341b0066a108d0220032902c403420020032802c00322021b2207422088220ca741057421012002410120021b220521020340024020010d004109214641eeebca002145410021020c490b024020034190096a2002460d00200141606a2101200220034190096a412010e707210a200241206a2102200a0d010b0b200341003602c803200342013703c003200b200341c0036a10bf0220032802c8032101024020032802c403450d0020032802c00310290b0240200120064d0d004113214641e7d5c8002145410921020c480b200341003602c803200342013703c003200b200341c0036a10bf0220032802c403210a200341d80b6a41186a220620033502c80342208620032802c0032210ad841010220241186a290000370300200341d80b6a41106a220e200241106a290000370300200341d80b6a41086a220f200241086a290000370300200320022900003703d80b200210290240200a450d00201010290b200341c0036a41186a2006290300370300200341c0036a41106a200e290300370300200341c0036a41086a200f290300370300200320032903d80b3703c003200341a00e6a200341c0036a10bd0520034180026a20032802a00e220220032802a80e4180a6cc004100410010c701200328028002210a024020032802a40e450d00200210290b41012102200a4101460d17024002400240024020084102490d00200341800e6a41186a22064200370300200341800e6a41106a220e4200370300200341800e6a41086a22024200370300200342003703800e41a6d4c800ad4280808080b002841001220a290000210d2002200a41086a2900003703002003200d3703800e200a1029419fdec900ad42808080809001841001220a290000210d20034190066a41086a220f200a41086a2900003703002003200d37039006200a10292009200329039006370000200941086a200f290300370000200341b0066a41086a2002290300370300200341b0066a41106a200e290300370300200341b0066a41186a2006290300370300200320032903800e3703b006200341c0036a200341b0066a412010ce010240024020032802c003220a0d0041002102200341003602a80e200342013703a00e4101210a410021060c010b200320032902c403220d3702a40e2003200a3602a00e200d422088a72102200da721060b20034190066a41186a220e200341d80b6a41186a29030037030020034190066a41106a220f200341d80b6a41106a29030037030020034190066a41086a2210200341d80b6a41086a290300370300200320032903d80b37039006024020022006470d00200341a00e6a20024101109e0120032802a00e210a20032802a80e21020b200a20024105746a2206200329039006370000200641186a200e290300370000200641106a200f290300370000200641086a20102903003700002003200241016a22063602a80e20032802a40e2102200641e4004b0d0320034190066a41186a420037030020034190066a41106a420037030020034190066a41086a220e4200370300200342003703900641a6d4c800ad4280808080b002841001220f290000210d200f2900082112200f1029200e20123703002003200d37039006419fdec900ad42808080809001841001220f290008210d200f2900002112200f1029200341b0066a41106a2012370300200341b0066a41186a200d370300200341b0066a41086a200e29030037030020032003290390063703b00602400240200a0d00200341b0066aad428080808080048410040c010b200341203602c4032003200341b0066a3602c003200a2006200341c0036a10cf01200241ffffff3f71450d00200a10290b200341b0066a41186a220a4200370300200341b0066a41106a220e4200370300200341b0066a41086a22024200370300200342003703b00641a6d4c800ad4280808080b00284220d1001220f2900002112200f290008211b200f10292002201b370300200320123703b00641a0b9ca00ad4280808080d0018422121001220f290008211b200f290000211c200f102920034190066a41106a220f201c37030020034190066a41186a2210201b37030020034190066a41086a22142002290300370300200320032903b00637039006200341f8016a20034190066a412010fc0120032802fc01211320032802f8012111200a4200370300200e420037030020024200370300200342003703b006200d10012215290000211b2015290008211c201510292002201c3703002003201b3703b006201210012215290008211b2015290000211c20151029200f201c3703002010201b37030020142002290300370300200320032903b00637039006200341f0016a20034190066a412010fc0120032802f001211520032802f4012116200a4200370300200e420037030020024200370300200342003703b006200d1001220a290000210d200a290008211b200a10292002201b3703002003200d3703b00620121001220a290008210d200a2900002112200a1029200f20123703002010200d37030020142002290300370300200320032903b006370390062003201641016a410120151b3602c00320034190066aad4280808080800484200341c0036aad4280808080c000841003200341c0036a200b41a80210e4071a200341a00e6a41186a200341d80b6a41186a290300370300200341a00e6a41106a200341d80b6a41106a290300370300200341a00e6a41086a200341d80b6a41086a290300370300200320032903d80b3703a00e200341b00a6a200341a00e6a10bd0520032802b00a210220033502b80a210d200342013703a00e200341003602a80e200341c0036a200341a00e6a10bf0220032802a40e210b200d4220862002ad8420033502a80e42208620032802a00e220aad8410030240200b450d00200a10290b024020032802b40a450d00200210290b200341c0036a10cc01200341800e6a41186a220a4200370300200341800e6a41106a220e4200370300200341800e6a41086a22024200370300200342003703800e41b3e6ca00ad4280808080e000841001220b290000210d2002200b41086a2900003703002003200d3703800e200b102941c9e6ca00ad4280808080e000841001220b290000210d20034190066a41086a220f200b41086a2900003703002003200d37039006200b10292009200329039006370000200941086a200f290300370000200341b0066a41086a2002290300370300200341b0066a41106a200e290300370300200341b0066a41186a200a290300370300200320032903800e3703b006200341e8016a200341b0066a412010fc0120032802ec01210b20032802e801210a412010272202450d602002200329039009370000200241186a20034190096a41186a290300370000200241106a20034190096a41106a290300370000200241086a20034190096a41086a290300370000200341dc036a4100360200200341cc036a4281808080103702002003200b41c093066a41c09306200a1b3602e0034201210d200342013702d403200320023602c803200320083602c40320032013410020111b220a3602c003200341a00e6a41186a200341d80b6a41186a290300370300200341a00e6a41106a200341d80b6a41106a290300370300200341a00e6a41086a200341d80b6a41086a290300370300200320032903d80b3703a00e200341b00a6a200341a00e6a10be0520032802b00a210b200320032802b80a3602a40e2003200b3602a00e200341c0036a200341a00e6a10bf05024020032802b40a450d00200b10290b20021029200341cd036a20034190096a41086a290300370000200341d5036a20034190096a41106a290300370000200341dd036a20034190096a41186a290300370000200341e5036a20032903d80b370000200341ed036a200341d80b6a41086a290300370000200341f5036a200341d80b6a41106a290300370000200341fd036a200341d80b6a41186a2903003700002003418c046a200836020020034188046a200a360200200341003a00c4032003410b3a00c00320032003290390093700c5032001ad42f02e7e200c42b0db067e7c2006ad42b0901f7e7c4280aba186027c210c200341c0036a10cb01200742ffffff3f8350450d010c020b200341800e6a41186a22084200370300200341800e6a41106a22064200370300200341800e6a41086a22024200370300200342003703800e41a6d4c800ad4280808080b002841001220a290000210d2002200a41086a2900003703002003200d3703800e200a102941f0edca00ad4280808080f000841001220a290000210d20034190066a41086a220e200a41086a2900003703002003200d37039006200a10292009200329039006370000200941086a200e290300370000200341b0066a41086a2002290300370300200341b0066a41106a2006290300370300200341b0066a41186a2008290300370300200320032903800e3703b006200341c0036a200341b0066a108d020240024020032802c003220a0d00410021020c010b20032902c403220d422088a72102200d42ffffff3f83500d00200a10290b200341c0036a200b41a80210e4071a200341ac0e6a2002360200200341a00e6a41086a22024101360200200341003a00a40e200341023a00a00e200341b00a6a200341c0036a200341a00e6a10c501200341880d6a41086a220b200341d80b6a41086a290300370300200341880d6a41106a220a200341d80b6a41106a290300370300200341880d6a41186a2208200341d80b6a41186a290300370300200320032903d80b3703880d200341b00a6a41186a2d00002106200341cb0a6a2d0000210920032903b00a211b20032903b80a211220032902cc0a210d20032f00c90a210e2003410b3a00c003200341043a00c403200341cd036a200b290300370000200341d5036a200a290300370000200341dd036a2008290300370000200341eb036a20093a0000200341e9036a200e3b0000200341ec036a200d3702004201210d200341e8036a41044104200620124202511b201b4201521b3a0000200320032903880d3700c503200341e5036a20032f01d0063b0000200341e7036a200341d0066a41026a2d00003a0000200341f4036a20032902a00e370200200341fc036a200229020037020020034184046a200341a00e6a41106a2902003702002003418c046a200341a00e6a41186a280200360200200341c0036a10cb01024002402012a70d004200210d0c010b427f2001ad42b8177e200c42e0b60d7e7c42c0e3d5257c220c200341b00a6a41106a2903007c22122012200c541b210c0b200742ffffff3f83500d010b200510290b20032802f0071029200041106a200c3703002000200d37030820004200370300200424000f0b0240200241ffffff3f71450d00200a10290b41102146418dd6c80021454107210241032101200742ffffff3f83500d490c480b200320073e00f10b200341f70b6a20074230883c0000200341f50b6a20074220883d00002003204c3a00f00b200320463a00ef0b200320473b00ed0b2003204d3a00ec0b200320483a00eb0b200320493b00e90b2003204e3a00e80b2003204a3a00e70b200320063600e30b2003200b3600df0b200320083600db0b2003204b3b00d90b200320453a00d80b2003200c3703f00d200320093a00ef0d200320053a00ee0d2003200e3b01ec0d2003200f3a00eb0d200320103a00ea0d200320143b01e80d200320153a00e70d200320133a00e60d200320113b01e40d200320163a00e30d200320173a00e20d200320183b01e00d200320193a00df0d2003201a3a00de0d200320413b01dc0d200320423a00db0d200320433a00da0d200320443b01d80d0240200a41ff01714101470d00200241ff01710d002007423888a7210e200341b00a6a41186a200341d80d6a41186a290300370300200341b00a6a41106a200341d80d6a41106a290300370300200341b00a6a41086a200341d80d6a41086a290300370300200320032903d80d3703b00a200341800e6a41186a4200370300200341800e6a41106a220b4200370300200341800e6a41086a22024200370300200342003703800e41a6d4c800ad4280808080b002841001220129000021072002200141086a290000370300200320073703800e2001102941f0edca00ad4280808080f0008410012201290000210720034190066a41086a220a200141086a290000370300200320073703900620011029200b2003290390062207370300200341b0066a41086a2002290300370300200341b0066a41106a2007370300200341b0066a41186a200a290300370300200320032903800e3703b006200341c0036a200341b0066a108d0220032902c403420020032802c00322021b2207422088220da741057421012002410120021b220621020340024020010d004109210341eeebca002102410021010c470b0240200341b00a6a2002460d00200141606a21012002200341b00a6a412010e707210b200241206a2102200b0d010b0b20034190096a200341d80b6a10c005200341c0036a200328029009220120032802980910c10520032802940921020240024020032802c8032209450d00200341e0036a280200210b200341dc036a280200210f200341d8036a2802002115200341d4036a2802002114200341d0036a280200210520032802cc03211020032903c003210c02402002450d00200110290b200341bc0e6a200f360200200341b80e6a2015360200200341b00e6a2005360200200341ac0e6a20103602002003200b3602c00e200320143602b40e200320093602a80e2003200c3703a00e204f200ca7460d01410a210341c4d6c8002102410321010c460b02402002450d00200110290b410f210341ced6c8002102410221010c460b410021014100210b4100211302402005450d002005410574210a4100210b2009210202400340200341b00a6a2002460d01200b2002200341b00a6a412010e70722084100476a210b2008450d01200241206a2102200a41606a220a0d000b410021130c010b410121130b410021020240200f450d00200f410574210a410021012014210202400340200341b00a6a2002460d0120012002200341b00a6a412010e70722084100476a21012008450d01200241206a2102200a41606a220a0d000b410021020c010b410121020b02400240200e0d002002450d010c450b20130d4420034190066a41186a220a200341b00a6a41186a29030037030020034190066a41106a2208200341b00a6a41106a29030037030020034190066a41086a220f200341b00a6a41086a290300370300200320032903b00a37039006024020052010470d00200341a80e6a20104101109e0120032802b00e210520032802a80e21090b200920054105746a220b200329039006370000200b41186a200a290300370000200b41106a2008290300370000200b41086a200f2903003700002003200541016a22083602b00e20032802bc0e210a2002450d43200a20014d0d1920032802b40e220b200a417f6a220a4105746a2202290000210c200229000821122002290010211b200241186a290000211c2003200a3602bc0e200b20014105746a220241186a201c3700002002201b370010200220123700082002200c3700000c430b200341b0066a41186a2201200341b00a6a41186a290300370300200341b0066a41106a220a200341b00a6a41106a290300370300200341b0066a41086a2208200341b00a6a41086a290300370300200320032903b00a3703b0060240200f2015470d00200341b40e6a20154101109e0120032802bc0e210f20032802b40e21140b2014200f4105746a220220032903b006370000200241186a2001290300370000200241106a200a290300370000200241086a2008290300370000200320032802bc0e41016a220a3602bc0e20032802b00e21082013450d422008200b4d0d1920032802a80e22012008417f6a22084105746a2202290000210c200229000821122002290010211b200241186a290000211c200320083602b00e2001200b4105746a220241186a201c3700002002201b370010200220123700082002200c3700000c420b4102210b0c450b200320073e00a909200341af096a20074230883c0000200341ad096a20074220883d00002003204c3a00a809200320463a00a709200320473b00a5092003204d3a00a409200320483a00a309200320493b00a1092003204e3a00a0092003204a3a009f092003200636009b092003200b3600970920032008360093092003204b3b009109200320453a0090090240200241ff0171450d000c3f0b200a41ff01714101470d3e200341a00e6a20034190096a10c005200341c0036a20032802a00e220120032802a80e10c10520032802a40e21020240024020032802c803220a450d00200341e0036a2802002110200341dc036a2802002108200341d8036a2802002109200341d4036a280200210e200341d0036a280200210b20032802cc03210520032903c003210702402002450d00200110290b4113210241032150204f2007a7460d01410a210141c4d6c80021064103210b0c3f0b02402002450d00200110290b410f210141ced6c80021064102210b41132102410321500c3f0b2007422088a72114200341800e6a41186a4200370300200341800e6a41106a220f4200370300200341800e6a41086a22014200370300200342003703800e41a6d4c800ad4280808080b0028410012206290000210c2001200641086a2900003703002003200c3703800e2006102941f0edca00ad4280808080f0008410012206290000210c20034190066a41086a2215200641086a2900003703002003200c3703900620061029200f200329039006220c370300200341b0066a41086a2001290300370300200341b0066a41106a200c370300200341b0066a41186a2015290300370300200320032903800e3703b006200341c0036a200341b0066a108d020240024020032802c00322010d00410021060c010b20032902c403220c422088a72106200c42ffffff3f83500d00200110290b024002400240200b20144f22150d004100200620086b2201200120064b1b2014490d00200341800e6a41186a22114200370300200341800e6a41106a2216420037030041082101200341800e6a41086a22154200370300200342003703800e41b3e6ca00ad4280808080e0008410012213290000210c2015201341086a2900003703002003200c3703800e2013102941c9e6ca00ad4280808080e0008410012213290000210c20034190066a41086a2217201341086a2900003703002003200c3703900620131029200f200329039006370000200f41086a2017290300370000200341b0066a41086a2015290300370300200341b0066a41106a220f2016290300370300200341b0066a41186a22152011290300370300200320032903800e3703b00620034188026a200341b0066a412010fc01200328028c0241002003280288021b20104f0d01419dd6c80021064106210b0c400b200341c0036a20034190096a2051200d10c20520032802c0034101470d01200341cc036a28020021010c3e0b20154200370300200f4200370300200341b0066a41086a22024200370300200342003703b00641a6d4c800ad4280808080b0028410012201290000210c2001290008211220011029200220123703002003200c3703b00641f8d7ca00ad4280808080d0008410012201290008210c200129000021122001102920034190066a41106a201237030020034190066a41186a200c37030020034190066a41086a2002290300370300200320032903b00637039006200341c0036a20034190066a412010cd0120032d00c00321012015200341d9036a290000370300200f200341d1036a2900003703002002200341c9036a290000370300200320032900c1033703b006024020014101460d0020062008200b6a6b21020c3c0b200341d80d6a41186a200341b0066a41186a290300220c370300200341d80d6a41106a200341b0066a41106a2903002212370300200341d80d6a41086a2002290300221b370300200320032903b006221c3703d80d200341c0036a41186a200c370300200341c0036a41106a2012370300200341c0036a41086a201b3703002003201c3703c003200b4105742101200a210202400340024020010d00410021150c020b41012115200341c0036a2002460d01200141606a21012002200341c0036a412010e707210f200241206a2102200f0d000b0b20062008200b6a6b21022015450d3b2002200b6a2102200821010c3c0b200341f0056a350200210c200341a00e6a200341c0036a41086a41a80210e4071a200341cc0a6a2008360200200341b00a6a41186a2009360200200341b00a6a41106a200b360200200341bc0a6a2005360200200320103602d00a2003200e3602c40a2003200a3602b80a200320073703b00a200341d80b6a41186a20034190096a41186a290300370300200341d80b6a41106a20034190096a41106a290300370300200341d80b6a41086a20034190096a41086a29030037030020032003290390093703d80b200341c0036a200341a00e6a41a80210e4071a200c42c03e7e2006ad4290a10f7e7c42c0fa9dc3007c210720152006200341b00a6a200341d80b6a200341c0036a10c305210c0c3f0b200341c0036a41286a200141306a290300370300200341c0036a41206a200141286a290300370300200341c0036a41186a200141206a290300370300200341c0036a41106a200141186a290300370300200341c0036a41086a200141106a2903003703002003200141086a2903003703c003200341a00e6a41206a200241206a290200370300200341a00e6a41186a200241186a290200370300200341a00e6a41106a200241106a290200370300200341a00e6a41086a200241086a290200370300200320022902003703a00e2000200341c0036a200341a00e6a10c405200424000f0b200341ca0d6a220e200141076a2d00003a0000200341a00e6a41086a220f2001411c6a290200370300200341a00e6a41106a2210200141246a290200370300200341a00e6a41186a2001412c6a290200370300200341c00e6a200141346a290200370300200341c80e6a2001413c6a290200370300200341d00e6a200141c4006a2d00003a0000200320012f00053b01c80d2003200141146a2902003703a00e200141086a280200210b2001410c6a2802002106200141106a280200210820022f0001200241036a2d00004110747221142002410c6a2802002109200241086a2802002105200241046a280200211520022d0000210a0240024002400240024002400240024020012d00040e080001020304050607000b200341c0036a41146a4101360200200342013702c40320034198e3ca003602c003200341043602b40a200341cce3ca003602b00a2003200341b00a6a3602d003200341c0036a4180a6cc001040000b200341c70a6a200f290300370000200341cf0a6a20102d00003a0000200320032f01c80d3b01b00a200320083600bb0a200320063600b70a2003200b3600b30a200320032903a00e3700bf0a2003200e2d00003a00b20a0240024002400240200a417f6a220241034b0d00024020020e0400010102000b200541017420094d0d00201541ff0171450d010b2014200a4100477241ff01710d010b200341800e6a41186a4200370300200341800e6a41106a220b4200370300200341800e6a41086a22024200370300200342003703800e419ad6ca00ad4280808080b002841001220129000021072002200141086a290000370300200320073703800e2001102941f0edca00ad4280808080f0008410012201290000210720034190066a41086a220a200141086a290000370300200320073703900620011029200b2003290390062207370300200341b0066a41086a2002290300370300200341b0066a41106a2007370300200341b0066a41186a200a290300370300200320032903800e3703b006200341c0036a200341b0066a108d02024020032802c00322080d0041002109200341003602e00b200342013703d80b410121080c3f0b200320032902c40322073702dc0b200320083602d80b2007a7210941002102024002402007422088a7220641014b0d0020060e024001400b2006210103402001410176220b20026a220a20022008200a4105746a200341b00a6a412010e7074101481b21022001200b6b220141014b0d000b0b0240200820024105746a200341b00a6a412010e7072201450d00200341c0036a41186a200341b00a6a41186a290300370300200341c0036a41106a200341b00a6a41106a290300370300200341c0036a41086a200341b00a6a41086a290300370300200320032903b00a3703c0032001411f7620026a220b20064b0d1f200341c0036a21010c400b0240200941ffffff3f71450d00200810290b41832a21030c010b41822a21030b20004200370308200041206a410d3602002000411c6a4180e8c900360200200041186a200336020020004201370300200424000f0b200341e7066a200f290300370000200341ef066a20102d00003a0000200320032f01c80d3b01d006200320083600db06200320063600d7062003200b3600d306200320032903a00e3700df062003200e2d00003a00d20602400240200a417f6a220241034b0d00024020020e0400010102000b200541017420094d0d00201541ff0171450d010b2014200a4100477241ff01710d1e0b200341800e6a41186a4200370300200341800e6a41106a220b4200370300200341800e6a41086a22024200370300200342003703800e419ad6ca00ad4280808080b002841001220129000021072002200141086a290000370300200320073703800e2001102941f0edca00ad4280808080f0008410012201290000210720034190066a41086a220a200141086a290000370300200320073703900620011029200b2003290390062207370300200341b0066a41086a2002290300370300200341b0066a41106a2007370300200341b0066a41186a200a290300370300200320032903800e3703b006200341c0036a200341b0066a108d0220032802c0032201410120011b21084100210202400240024020032902c403420020011b2207422088a7220641014b0d0020060e020201020b2006210103402001410176220b20026a220a20022008200a4105746a200341d0066a412010e7074101481b21022001200b6b220141014b0d000b0b200820024105746a200341d0066a412010e7070d00200220064f0d1d200820024105746a2201200141206a2002417f7320066a41057410e5071a200341c0036a41186a22094200370300200341c0036a41106a220b4200370300200341c0036a41086a22014200370300200342003703c003419ad6ca00ad4280808080b00284220c1001220a290000210d20034190096a41086a2202200a41086a2900003703002003200d37039009200a10292001200229030037030020032003290390093703c00341f0edca00ad4280808080f000841001220a290000210d2002200a41086a2900003703002003200d37039009200a1029200b200329039009220d370300200341d80b6a41086a2001290300370300200341d80b6a41106a200d370300200341d80b6a41186a2002290300370300200320032903c0033703d80b200341203602c4032003200341d80b6a3602c00320082006417f6a2202200341c0036a10b9012009200341d0066a41186a290300370300200b200341d0066a41106a2903003703002001200341d0066a41086a290300370300200320032903d0063703c003200341c0036a41012008200210c50520034190066a41186a220a420037030020034190066a41106a2209420037030020034190066a41086a220142003703002003420037039006200c1001220b290000210c200b290008210d200b10292001200d3703002003200c3703900641f8d7ca00ad4280808080d000841001220b290008210c200b290000210d200b1029200341d80d6a41106a200d370300200341d80d6a41186a200c370300200341d80d6a41086a200129030037030020032003290390063703d80d200341c0036a200341d80d6a412010cd0120032d00c003210b200a200341d9036a2900003703002009200341d1036a2900003703002001200341c9036a290000370300200320032900c103370390060240200b4101470d00200341880d6a41186a200a290300220c370300200341880d6a41106a2009290300220d370300200341880d6a41086a200129030022123703002003200329039006221b3703880d200341b00a6a41186a200c370300200341b00a6a41106a200d370300200341b00a6a41086a20123703002003201b3703b00a4100210102400240024002402006417f6a220b41014b0d00200b0e020201020b03402002410176220b20016a220a20012008200a4105746a200341b00a6a412010e7074101481b21012002200b6b220241014b0d000b0b200820014105746a200341b00a6a412010e707450d010b20034190096a41186a420037030020034190096a41106a220a420037030020034190096a41086a220142003703002003420037039009419ad6ca00ad4280808080b002841001220b290000210c200341d80d6a41086a2202200b41086a2900003703002003200c3703d80d200b102920012002290300370300200320032903d80d3703900941f8d7ca00ad4280808080d000841001220b290000210c2002200b41086a2900003703002003200c3703d80d200b1029200a20032903d80d220c370300200341f0076a41086a2001290300370300200341f0076a41106a200c370300200341f0076a41186a200229030037030020032003290390093703f007200341f0076aad428080808080048410040c010b200341d9036a200341c80a6a290300370000200341d1036a200341c00a6a290300370000200341c9036a200341b80a6a290300370000200320032903b00a3700c103200341013a00c003200341c0036a10c6050b2003418d023b01c003200341c0036a10cb010240200742ffffff3f83500d00200810290b2000420037030820004200370300200424000f0b0240200742ffffff3f83500d00200810290b4183aa0421030c3a0b200341ff026a200f29030037000020034187036a20102d00003a0000200320032f01c80d3b01e802200320083600f302200320063600ef022003200b3600eb02200320032903a00e3700f7022003200e2d00003a00ea02200341d0066a41186a200341c90e6a290000370300200341d0066a41106a200341c10e6a290000370300200341d0066a41086a200341b90e6a290000370300200320032900b10e3703d006024002400240200a417f6a220241034b0d00024020020e0400010102000b200541017420094d0d00201541ff0171450d010b410021092014200a4100477241ff01710d010b200341e8026a200341d0066a412010e707450d37200341800e6a41186a4200370300200341800e6a41106a220b4200370300200341800e6a41086a22024200370300200342003703800e419ad6ca00ad4280808080b002841001220129000021072002200141086a290000370300200320073703800e2001102941f0edca00ad4280808080f0008410012201290000210720034190066a41086a220a200141086a290000370300200320073703900620011029200b2003290390062207370300200341b0066a41086a2002290300370300200341b0066a41106a2007370300200341b0066a41186a200a290300370300200320032903800e3703b006200341c0036a200341b0066a108d0220032802c0032201410120011b21084109210541eeebca00210e418080042109410021020240024020032902c403420020011b2207422088a7220641014b0d0020060e023701370b2006210103402001410176220b20026a220a20022008200a4105746a200341e8026a412010e7074101481b21022001200b6b220141014b0d000b0b200820024105746a220f200341e8026a412010e7070d35410021010240200641014b0d0020060e023735370b2006210b0340200b410176220a20016a22092001200820094105746a200341d0066a412010e7074101481b2101200b200a6b220b41014b0d000c350b0b410221030c370b024002400240200a417f6a220241034b0d00024020020e0400010102000b200541017420094d0d00201541ff0171450d010b2014200a4100477241ff01710d010b200b200810bb05200341800e6a41186a4200370300200341800e6a41106a22094200370300200341800e6a41086a22014200370300200342003703800e419ad6ca00ad4280808080b00284220710012202290000210c2001200241086a2900003703002003200c3703800e2002102941f0edca00ad4280808080f000841001220a290000210c20034190066a41086a2202200a41086a2900003703002003200c37039006200a10292009200329039006220c370300200341b0066a41086a2001290300370300200341b0066a41106a200c370300200341b0066a41186a2002290300370300200320032903800e3703b006200341c0036a200341b0066a108d02200b200820032802c0032201410120011b220520032902c403420020011b220c422088a710bc0520034190066a41186a220a420037030020034190066a41106a2209420037030020024200370300200342003703900620071001220129000021072001290008210d200110292002200d370300200320073703900641f8d7ca00ad4280808080d000841001220129000821072001290000210d20011029200341d80d6a41106a200d370300200341d80d6a41186a2007370300200341d80d6a41086a200229030037030020032003290390063703d80d200341c0036a200341d80d6a412010cd0120032d00c0032101200a200341d9036a2900003703002009200341d1036a2900003703002002200341c9036a290000370300200320032900c10337039006024020014101470d00200341880d6a41186a200a2903002207370300200341880d6a41106a2009290300220d370300200341880d6a41086a200229030022123703002003200329039006221b3703880d200341b00a6a41186a2007370300200341b00a6a41106a200d370300200341b00a6a41086a20123703002003201b3703b00a410021020240024002400240200841014b0d0020080e020201020b2008210103402001410176220a20026a22092002200b20094105746a200341b00a6a412010e7074101481b21022001200a6b220141014b0d000b0b200b20024105746a200341b00a6a412010e707450d010b20034190096a41186a420037030020034190096a41106a2209420037030020034190096a41086a220142003703002003420037039009419ad6ca00ad4280808080b002841001220a2900002107200341d80d6a41086a2202200a41086a290000370300200320073703d80d200a102920012002290300370300200320032903d80d3703900941f8d7ca00ad4280808080d000841001220a29000021072002200a41086a290000370300200320073703d80d200a1029200920032903d80d2207370300200341f0076a41086a2001290300370300200341f0076a41106a2007370300200341f0076a41186a200229030037030020032003290390093703f007200341f0076aad428080808080048410040c010b200341d9036a200341c80a6a290300370000200341d1036a200341c00a6a290300370000200341c9036a200341b80a6a290300370000200320032903b00a3700c103200341013a00c003200341c0036a10c6050b0240200c42ffffff3f83500d00200510290b20034190096a41186a420037030020034190096a41106a2209420037030020034190096a41086a220142003703002003420037039009419ad6ca00ad4280808080b002841001220a2900002107200341d80d6a41086a2202200a41086a290000370300200320073703d80d200a102920012002290300370300200320032903d80d3703900941f0edca00ad4280808080f000841001220a29000021072002200a41086a290000370300200320073703d80d200a1029200920032903d80d2207370300200341f0076a41086a2001290300370300200341f0076a41106a2007370300200341f0076a41186a200229030037030020032003290390093703f007200341203602c4032003200341f0076a3602c003200b2008200341c0036a10b9010240200641ffffff3f71450d00200b10290b2003418d063b01c003200341c0036a10cb012000420037030820004200370300200424000f0b0240200641ffffff3f71450d00200b10290b20004200370308200041186a410236020020004201370300200424000f0b200241106a2902002107200241186a2f010021012002411a6a290100210c200341e7066a200f290300370000200341ef066a20102d00003a00002003200e2d00003a00d206200320032f01c80d3b01d006200320083600db06200320063600d7062003200b3600d306200320032903a00e3700df062003200c3703f00d200320013b01ee0d200320073701e60d200320144108763b01d80d200320093a00e20d200320094110763b01e40d200320094108763a00e30d200320053a00de0d200320054110763b01e00d200320054108763a00df0d200320153a00da0d200320154110763b01dc0d200320154108763a00db0d0240201441ff01714101470d00200a0d00200341d80b6a41186a200341d80d6a41186a290300370300200341d80b6a41106a200341d80d6a41106a290300370300200341d80b6a41086a200341d80d6a41086a290300370300200320032903d80d3703d80b200341d80b6a200341d0066a412010e707450d2f200341800e6a41186a4200370300200341800e6a41106a220b4200370300200341800e6a41086a22024200370300200342003703800e419ad6ca00ad4280808080b002841001220129000021072002200141086a290000370300200320073703800e2001102941f0edca00ad4280808080f0008410012201290000210720034190066a41086a220a200141086a290000370300200320073703900620011029200b2003290390062207370300200341b0066a41086a2002290300370300200341b0066a41106a2007370300200341b0066a41186a200a290300370300200320032903800e3703b006200341c0036a200341b0066a108d0220032802c0032201410120011b21084109210641eeebca002109418080042105410021020240024020032902c403420020011b2207422088a7220e41014b0d00200e0e022f012f0b200e210103402001410176220b20026a220a20022008200a4105746a200341d80b6a412010e7074101481b21022001200b6b220141014b0d000b0b200820024105746a220f200341d80b6a412010e7070d2d410021010240200e41014b0d00200e0e022f2d2f0b200e210b0340200b410176220a20016a22062001200820064105746a200341d0066a412010e7074101481b2101200b200a6b220b41014b0d000c2d0b0b41002105410221030c2f0b200341c70a6a200f290300370000200341cf0a6a20102d00003a0000200320032f01c80d3b01b00a200320083600bb0a200320063600b70a2003200b3600b30a200320032903a00e3700bf0a2003200e2d00003a00b20a02400240200a417f6a220241034b0d00024020020e0400010102000b200541017420094d0d00201541ff0171450d010b2014200a4100477241ff01710d1b0b200341800e6a41186a4200370300200341800e6a41106a220b4200370300200341800e6a41086a22024200370300200342003703800e419ad6ca00ad4280808080b002841001220129000021072002200141086a290000370300200320073703800e2001102941f0edca00ad4280808080f0008410012201290000210720034190066a41086a220a200141086a290000370300200320073703900620011029200b2003290390062207370300200341b0066a41086a2002290300370300200341b0066a41106a2007370300200341b0066a41186a200a290300370300200320032903800e3703b006200341c0036a200341b0066a108d0220032802c0032201410120011b21084100210202400240024020032902c403420020011b2207422088a7220141014b0d0020010e020201020b03402001410176220b20026a220a20022008200a4105746a200341b00a6a412010e7074101481b21022001200b6b220141014b0d000b0b200820024105746a200341b00a6a412010e7070d000240200742ffffff3f83500d00200810290b20034190096a41186a420037030020034190096a41106a220a420037030020034190096a41086a220142003703002003420037039009419ad6ca00ad4280808080b002841001220b2900002107200341d80d6a41086a2202200b41086a290000370300200320073703d80d200b102920012002290300370300200320032903d80d3703900941f8d7ca00ad4280808080d000841001220b29000021072002200b41086a290000370300200320073703d80d200b1029200a20032903d80d2207370300200341f0076a41086a2001290300370300200341f0076a41106a2007370300200341f0076a41186a200229030037030020032003290390093703f007412010272202450d4c200220032903b00a370000200241186a200341b00a6a41186a2201290300370000200241106a200341b00a6a41106a220b290300370000200241086a200341b00a6a41086a220a290300370000200341f0076aad42808080808004842002ad4280808080800484100320021029200341d9036a2001290300370000200341d1036a200b290300370000200341c9036a200a290300370000200320032903b00a3700c103200341013a00c003200341c0036a10c6052000420037030820004200370300200424000f0b0240200742ffffff3f83500d00200810290b4183aa0421030c290b02400240200a417f6a220241034b0d00024020020e0400010102000b200541017420094d0d00201541ff0171450d010b2014200a4100477241ff0171450d0020004200370308200041186a410236020020004201370300200424000f0b20034190096a41186a420037030020034190096a41106a220a420037030020034190096a41086a220142003703002003420037039009419ad6ca00ad4280808080b002841001220b2900002107200341d80d6a41086a2202200b41086a290000370300200320073703d80d200b102920012002290300370300200320032903d80d3703900941f8d7ca00ad4280808080d000841001220b29000021072002200b41086a290000370300200320073703d80d200b1029200a20032903d80d2207370300200341f0076a41086a2001290300370300200341f0076a41106a2007370300200341f0076a41186a200229030037030020032003290390093703f007200341f0076aad42808080808004841004200341003a00c003200341c0036a10c6052000420037030820004200370300200424000f0b200341c0036a41386a200141c0006a290300370300200341c0036a41306a200141386a290300370300200341c0036a41286a200141306a290300370300200341c0036a41206a200141286a290300370300200341c0036a41186a200141206a290300370300200341c0036a41106a200141186a290300370300200341c0036a41086a200141106a2903003703002003200141086a2903003703c003200341a00e6a41206a200241206a290200370300200341a00e6a41186a200241186a290200370300200341a00e6a41106a200241106a290200370300200341a00e6a41086a200241086a290200370300200320022902003703a00e2000200341c0036a200341a00e6a10c705200424000f0b200141146a2802002105200141106a280200210a2001410c6a2802002108200141086a280200210b20012802042106200341e8026a200141186a41c80010e4071a20022d0001210920022d0000210102400240024020060e03000102000b200341c0036a41146a4101360200200342013702c40320034198e3ca003602c003200341043602b40a200341cce3ca003602b00a2003200341b00a6a3602d003200341c0036a4180a6cc001040000b2003200a3602c803200320083602c4032003200b3602c003200341a00e6a20012009200341c0036a10c8050240024020032d00a00e4104460d0020032802a00e21022000411c6a20032902a40e370200200041186a2002360200420121070c010b420021070b2000420037030820002007370300200424000f0b2002411a6a2901002107200241196a2d00002106200241186a2d0000210e200241166a2f0100210f200241156a2d00002110200241146a2d00002114200241126a2f01002115200241116a2d00002113200241106a2d000021112002410e6a2f010021162002410d6a2d000021172002410c6a2d000021182002410a6a2f01002119200241096a2d0000211a200241086a2d00002141200241066a2f01002142200241056a2d00002143200241046a2d00002144200241026a2f01002145200341d0066a200341e8026a41c80010e4071a024002400240200141ff01710d00200941ff01714101470d00200341d80d6a41186a4200370300200341d80d6a41106a22094200370300200341d80d6a41086a22024200370300200342003703d80d41b1dcc900ad4280808080f0008410012201290000210c2002200141086a2900003703002003200c3703d80d2001102941b8dcc900ad4280808080a0018410012201290000210c20034190066a41086a2246200141086a2900003703002003200c37039006200110292009200329039006220c370300200341880d6a41086a2002290300370300200341880d6a41106a200c370300200341880d6a41186a2046290300370300200320032903d80d3703880d200341c0036a200341880d6a108d0220032802c003210220032902c403210c200341a00e6a410c6a20034180076a290200370200200341b40e6a20034188076a290200370200200341bc0e6a20034190076a290200370200200341f0c2c98b063602a00e200320032902f8063702a40e200341b00a6a410c6a2005360200200341b00a6a41086a200a360200200320083602b40a2003200b3602b00a200320032802d0063602c00a200c420020021b210c2002410120021b2146200341c0036a200341a00e6a200341b00a6a10b6042003280280040d01200ca7220b0d024125210341b4bbc7002102410021010c280b02402005450d002005410c6c21022008210303400240200341046a280200450d00200328020010290b2003410c6a2103200241746a22020d000b0b41022101200a450d26200a410c6c450d26200810290c270b20032802c0032102200341f0076a200341c0036a41047241cc0010e4071a20034190096a200341f0076a41cc0010e4071a412010272201450d5720012007370018200120063a00172001200e3a00162001200f3b0014200120103a0013200120143a0012200120153b0010200120133a000f200120113a000e200120163b000c200120173a000b200120183a000a200120193b00082001201a3a0007200120413a0006200120423b0004200120433a0003200120443a0002200120453b0000200320023602a00e200341a00e6a41047220034190096a41cc0010e4071a2003200c422088a73602f40e2003200b3602f00e41d00010272202450d57200341800e6a41086a220a200341a00e6a41086a290300370300200341800e6a41106a2208200341a00e6a41106a290300370300200341800e6a41186a2206200341a00e6a41186a290300370300200320032903a00e3703800e200341a00e6a41286a2903002107200341d00e6a290300210d200341a00e6a41386a290300211220032903c00e211b200341c0036a200341e00e6a10ee02200241386a20123703002002200d370330200241286a20073703002002201b370320200241186a2006290300370300200241106a2008290300370300200241086a200a290300370300200220032903800e370300200220032903c003370340200241c8006a200341c0036a41086a28020036020041041027220a450d49200a200b36000020034284808080c0003702dc0b2003200a3602d80b200341c0036a41e5cdc20010e902200341b00a6a20032802c003220820032802c803108b0320032902b40a420020032802b00a220a1b2107200a4101200a1b2106024020032802c403450d00200810290b200320074220883e02b40a200320063602b00a200341c0036a200341b00a6a10c905200341c0036a41086a280200210820032802c403210920032802c003210a200341c0036a41e5cdc200200341d80b6a10ea02200341b00a6a20032802c003221020032802c80310ce0120084100200a1b210f20094100200a1b210e20032902b40a420020032802b00a22081b210d200a4104200a1b21052008410120081b2108024020032802c403450d00201010290b200341d80d6a41206a200f360200200341f40d6a200e360200200341d80d6a41106a200d370300200341d80d6a41086a200341d80b6a41086a280200360200200320032903d80b3703d80d200320053602f00d200320083602e40d02402007a7450d00200610290b200341d80b6a41086a220a200241086a290300370300200341d80b6a41106a200241106a290300370300200341d80b6a41186a200241186a290300370300200341d80b6a41206a200241206a290300370300200341d80b6a41286a2206200241286a290300370300200341d80b6a41306a2209200241306a290300370300200341d80b6a41386a220f200241386a290300370300200341b0036a41086a2210200241cc006a280200360200200320022903003703d80b200320022902443703b00320022802402214450d1e200341880d6a41386a2215200f290300370300200341880d6a41306a22132009290300370300200341880d6a41286a22112006290300370300200341880d6a41206a2216200341d80b6a41206a2217290300370300200341880d6a41186a2218200341d80b6a41186a2219290300370300200341880d6a41106a221a200341d80b6a41106a2241290300370300200341880d6a41086a2242200a290300370300200341f80c6a41086a22432010280200360200200320032903d80b3703880d200320032903b0033703f80c200f2015290300370300200920132903003703002006201129030037030020172016290300370300201920182903003703002041201a290300370300200a2042290300370300200320032903880d3703d80b200320143602980c2003419c0c6a220a20032903f80c370200200a41086a204328020036020041041027220a450d49200a200b360000200341c0036a410c6a220641002900e5cd42370000200641086a41002900edcd4237000020034284808080c0003702c4032003200a3602c0032003200341d80b6a3602dc03200341800e6a200341c0036a10ca05200a1029200341c0036a200341800e6a10d50220034190026a20032802c003220620032802c8034180a6cc004100410010c701200328029002210a024020032802c403450d00200610290b0240200a4101460d00200341b00a6a200341d80b6a41d00010e4071a41201027220a450d4a200342013702b4062003200a3602b006200341b0066a41004101109e0120034190066a41086a220820032802b806220a41016a36020020032802b006200a4105746a220a2001290000370000200a41086a200141086a290000370000200a41106a200141106a290000370000200a41186a200141186a290000370000200320032903b00637039006200341c0036a200341b00a6a41d00010e4071a20034190046a220a41086a2008280200360200200a200329039006370200200341b00a6a200341800e6a10d50220032802b00a210a200320032802b80a3602b4062003200a3602b006200341c0036a200341b0066a10e402024020032802b40a450d00200a10290b0240200328028404220a450d00200a41306c450d0020032802800410290b024020032802940441ffffff3f71450d0020032802900410290b20034190066a41186a200341800e6a41186a29030037030020034190066a41106a200341800e6a41106a29030037030020034190066a41086a200341800e6a41086a290300370300200320032903800e370390064100210a024020032802f80d220f41014b0d000240200f0e020022000b200341b0066a41186a20034190066a41186a290300370300200341b0066a41106a20034190066a41106a290300370300200341b0066a41086a20034190066a41086a29030037030020032003290390063703b0064100210a0c220b200f21080340200a20084101762206200a6a22092005200941246c6a280200200b4b1b210a200820066b220841014b0d000c210b0b200328029c0c220b450d1e200b41306c450d1e20032802980c10290c1e0b410021014125210341b4bbc7002102200b41ffffff3f710d230c250b418230210102400240024020022d00000d0020022d000141ff01714102470d0042002107200341800e6a41186a22084200370300200341800e6a41106a220b4200370300200341800e6a41086a22024200370300200342003703800e41f182cc00ad4280808080c00184221210012201290000210c2001290008210d200110292002200d3703002003200c3703800e41ac84cc00ad4280808080900184220d10012201290000210c20034190066a41086a220a200141086a2900003703002003200c3703900620011029200b200329039006220c370300200341b0066a41086a22062002290300370300200341b0066a41106a2209200c370300200341b0066a41186a2205200a290300370300200320032903800e3703b00620034198026a200341b0066a41204180a6cc004100410010c70141833021012003280298024101470d010b200041206a41133602002000411c6a41eaa3c800360200200041186a2001360200420121070c010b20084200370300200b420037030020024200370300200342003703800e201210012201290000210c2001290008211220011029200220123703002003200c3703800e200d10012201290000210c200a200141086a2900003703002003200c3703900620011029200b200329039006370000200b41086a200a290300370000200620022903003703002009200b29030037030020052008290300370300200320032903800e3703b006200341013a00b003200341b0066aad4280808080800484200341b0036aad4280808080108410030b2000200737030020004200370308200424000f0b200341d80b6a41086a2245200141206a290300370300200341d80b6a41106a2246200141286a2903003703002003200141186a2903003703d80b200141146a2802002108200141106a280200210a2001410c6a280200210b2002411a6a2901002107200241196a2d00002109200241186a2d00002105200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002114200241116a2d00002115200241106a2d000021132002410e6a2f010021112002410d6a2d000021162002410c6a2d000021172002410a6a2f01002118200241096a2d00002119200241086a2d0000211a200241066a2f01002141200241056a2d00002142200241046a2d0000214341022149200241026a2f01002144200141096a2f0000214720022d0001210620022d0000210220012d000b21480240024002400240024002400240200141086a2d00000e0700010203040506000b200341c0036a41146a4101360200200342013702c40320034198e3ca003602c003200341043602b40a200341cce3ca003602b00a2003200341b00a6a3602d003200341c0036a4180a6cc001040000b410021010240024002402006200241ff01714100477241ff0171450d00410221030c010b41d482cc00ad4280808080d000841001220229000021072002290008210c2002102941fab1c400ad4280808080b0018410012202290000210d2002290008211220021029200320123702c8062003200d3702c0062003200c3702b806200320073702b00641002101200341b8026a200341b0066a41204180a6cc004100410010c70141ab9dc4002102024020032802b8024101460d00200341800e6a41186a22094200370300200341800e6a41106a22014200370300200341800e6a41086a22024200370300200342003703800e41b3e6ca00ad4280808080e00084220c1001220829000021072002200841086a290000370300200320073703800e2008102941c9e6ca00ad4280808080e00084220d10012206290000210720034190066a41086a2208200641086a29000037030020032007370390062006102920012003290390062207370300200341b0066a41086a22062002290300370300200341b0066a41106a22052007370300200341b0066a41186a220e2008290300370300200320032903800e3703b006200341b0026a200341b0066a412010fc0120032802b40241a08d066e410020032802b0021b200a4d0d0241bc9dc40021024180800421010b410321030b20004200370308200041206a41113602002000411c6a2002360200200041186a200141808004712003724180327236020020004201370300200424000f0b41d482cc00ad4280808080d0008422071001220f2900002112200f290008211b200f102941d982cc00ad4280808080e00184221c1001220f290000211d200f290008211e200f10292003201e3702c8062003201d3702c0062003201b3702b806200320123702b006200341a8026a200341b0066a412010fc0120032802a802211020032802ac02211420071001220f2900002112200f290008211b200f1029201c1001220f290000211c200f290008211d200f10292003201d3702c8062003201c3702c0062003201b3702b806200320123702b0062003201441016a410120101b22103602c003200341b0066aad4280808080800484200341c0036aad4280808080c000841003200942003703002001420037030020024200370300200342003703800e200c1001220f290000210c2002200f41086a2900003703002003200c3703800e200f1029200d1001220f290000210c2008200f41086a2900003703002003200c37039006200f10292001200329039006370000200141086a20082903003700002006200229030037030020052001290300370300200e2009290300370300200320032903800e3703b006200341a0026a200341b0066a412010fc0120032802a402210120032802a002210820071001220229000021072002290008210c2002102941fab1c400ad4280808080b0018410012202290000210d2002290008211220021029200320123702c8062003200d3702c0062003200c3702b806200320073702b006200341203602c4032003200341b0066a3602c003200a2001410020081b200b6a2202200341c0036a10c901200341d4036a2002360200200341c0036a41106a200a360200200341cc036a2010360200200341c0036a41086a41013a00002003410f3a00c003200341c0036a10cb012000420037030820004200370300200424000f0b024002400240200241ff01710d00200641ff01714101470d002046290300210c20032903e00b210d20032802d80b2102200320193a00b7062003201a3a00b606200320413b01b406200320423a00b306200320433a00b206200320443b01b006200320153a00bf06200320133a00be06200320113b01bc06200320163a00bb06200320173a00ba06200320183b01b806200320093a00c706200320053a00c6062003200e3b01c4062003200f3a00c306200320103a00c206200320143b01c006200320073702c806200341c8036a20032902b006370300200341c0036a41106a20032902b806370300200341d8036a20032902c006370300200341e0036a20073703002003200b3602c403200341003602c003200341a00e6a200341c0036a200a20082002200d200c10eb0420032d00a00e22024104460d0220032f00a10e20032d00a30e41107472210120032902a40e21070c010b410221020b200042003703082000411c6a2007370200200041186a200141087420027236020020004201370300200424000f0b2000420037030820004200370300200424000f0b02400240200241ff01710d00200641ff01714101470d002045290300210c20032903d80b210d200320073703b80e200320093a00b70e200320053a00b60e2003200e3b01b40e2003200f3a00b30e200320103a00b20e200320143b01b00e200320153a00af0e200320133a00ae0e200320113b01ac0e200320163a00ab0e200320173a00aa0e200320183b01a80e200320193a00a70e2003201a3a00a60e200320413b01a40e200320423a00a30e200320433a00a20e200320443b01a00e2003200341a00e6a3602b00a200341c0036a200341b00a6a10aa0420032802c0034101460d014100210b4102210a4119210241032101410d210341cd9dc40021080c1f0b41002102410221014100210a4100210b0c1e0b200320032802c4033602c403200341013602c003200341b00a6a200341c0036a200b200a2008200d200c10eb0420032d00b00a22014104470d1c2000420037030820004200370300200424000f0b02400240200241ff01710d00200641ff01714101470d0020032900e10b210c20032d00e00b210220032d00df0b210120032f00dd0b210620032d00dc0b214520032d00db0b214620032f00d90b214920032d00d80b214a200320073703b80e200320093a00b70e200320053a00b60e2003200e3b01b40e2003200f3a00b30e200320103a00b20e200320143b01b00e200320153a00af0e200320133a00ae0e200320113b01ac0e200320163a00ab0e200320173a00aa0e200320183b01a80e200320193a00a70e2003201a3a00a60e200320413b01a40e200320423a00a30e200320433a00a20e200320443b01a00e2003200c3702c806200320023a00c706200320013a00c606200320063b01c406200320453a00c306200320463a00c206200320493b01c0062003204a3a00bf06200320084118763a00be06200320084108763b01bc06200320083a00bb062003200a4118763a00ba062003200a4108763b01b8062003200a3a00b7062003200b4118763a00b6062003200b4108763b01b4062003200b3a00b306200320483a00b206200320473b01b0062003200341a00e6a3602b00a200341c0036a200341b00a6a10aa04024020032802c0034101470d0020032802c4032102200341c0036a41186a220b200341b0066a41186a290200370300200341c0036a41106a220a200341b0066a41106a290200370300200341c0036a41086a2208200341b0066a41086a290200370300200320032902b0063703c003200341b00a6a200210c20420033502b80a210720032802b00a2101412010272202450d4b200220032903c003370000200241186a200b290300370000200241106a200a290300370000200241086a200829030037000020074220862001ad842002ad4280808080800484100320021029024020032802b40a450d00200110290b2000420037030820004200370300200424000f0b4183b20821030c010b4182b20821030b20004200370308200041206a410d3602002000411c6a41cd9dc400360200200041186a200336020020004201370300200424000f0b200141c0006a280200214e2001413c6a280200214a200141386a280200214b200141346a280200214f200141306a280200214c20032802ec0b214d200341a7066a2045290300370000200341af066a20462d00003a00002003200836009b062003200a360097062003200b36009306200320483a009206200320473b019006200320032903d80b37009f06410021010240200241ff0171450d000c1a0b200641ff01714101470d19200320073703c80a200320093a00c70a200320053a00c60a2003200e3b01c40a2003200f3a00c30a200320103a00c20a200320143b01c00a200320153a00bf0a200320133a00be0a200320113b01bc0a200320163a00bb0a200320173a00ba0a200320183b01b80a200320193a00b70a2003201a3a00b60a200320413b01b40a200320423a00b30a200320433a00b20a200320443b01b00a200341a00e6a204c10c304200341c0036a20032802a00e220120032802a80e10c804200341d0066a41026a220b20032d00c7033a0000200341f80c6a41086a220a200341e4036a280200360200200320032f00c5033b01d0062003200341dc036a2902003703f80c02400240024002400240024020032d00c40322024103460d00200341f4036a2802002110200341f0036a2802002106200341ec036a280200210e200341e8036a2802002114200341d8036a2802002109200341d4036a280200210f200341d0036a2802002115200341cc036a2802002105200341c0036a41086a280200210820032802c0032113200341e8026a41026a200b2d00003a000020034190096a41086a200a280200360200200320032f01d0063b01e802200320032903f80c37039009024020032802a40e450d00200110290b200341880d6a41026a200341e8026a41026a2d000022013a0000200341f0076a41086a220b20034190096a41086a280200360200200320032f01e802220a3b01880d20032003290390093703f007200341b40e6a2009360200200341b00e6a200f360200200341ac0e6a2015360200200341a00e6a41086a22152005360200200341d00e6a2010360200200341cc0e6a2006360200200341c80e6a200e360200200341c40e6a2014360200200320023a00a00e2003200a3b00a10e200320013a00a30e200320083602a40e200341b80e6a20032903f007370300200341c00e6a200b280200360200200241014b0d0320020e020102010b024020032802a40e450d00200110290b4180800c2101410321494111210b41da9dc40021020c1e0b418080102101410d210b41eb9dc40021022015200341b00a6a412010e7070d022008204d470d02204e4180a0014d0d034180803021014110210b41edd3c8002102410321490c1d0b4180801421014111210b41f89dc40021022006450d01200e1029410321490c1c0b02402005450d00200810290b4180801421014111210b41f89dc40021022009450d00200f10290b410321490c1a0b0240204f41808080054d0d004180802c2101410c210b41e1d3c8002102410321490c1a0b200341f4036a204e360200200341f0036a204a360200200341ec036a204b360200200341e8036a204f360200200341cd036a20034198066a290300370000200341d5036a200341a0066a290300370000200341dd036a200341a8066a290300370000200341013a00c403200320133602c00320032003290390063700c503200341f0076a204c10c30420033502f807210720032802f0072102410410272201450d4720034204370294092003200136029009200341c0036a20034190096a10c404200328029409210120074220862002ad84200335029809422086200328029009220bad84100302402001450d00200b10290b024020032802f407450d00200210290b0240204a450d00204b10290b2000420037030820004200370300200424000f0b20032802d80b2105200341a00e6a200b10c304200341c0036a20032802a00e220220032802a80e10c804200341d0066a41026a20032d00c7033a0000200341f80c6a41086a200341e4036a280200360200200320032f00c5033b01d0062003200341dc036a2902003703f80c024002400240024020032d00c40322094103460d00200341c0036a41346a2802002119200341c0036a41306a2802002113200341ec036a2802002117200341c0036a41286a2802002111200341c0036a41186a280200210f200341c0036a41146a2802002114200341c0036a41106a2802002116200341c0036a410c6a2802002110200341c0036a41086a280200211520032802c0032118200341e8026a41026a2201200341d0066a41026a22062d00003a000020034190096a41086a220e200341f80c6a41086a280200360200200320032f01d0063b01e802200320032903f80c37039009024020032802a40e450d00200210290b200341880d6a41026a20012d000022023a0000200341f0076a41086a200e2802002201360200200320032f01e802220e3b01880d200320032903900922073703f007200620023a0000200341b0036a41086a20013602002003200e3b01d006200320073703b00341949ec4002102410f21014183b21c2106200941014b0d0220090e020301030b024020032802a40e450d00200210290b41da9dc4002102411121014183b20c21060c020b200341bf0e6a200341b0036a41086a2d00003a0000200320032f01d0063b01a00e2003200f3600b30e200320143600af0e200320163600ab0e200320103600a70e200320153600a30e200320032903b0033700b70e2003200341d2066a2d00003a00a20e0240024020052011470d002005ad422086200aad84101022022900002107200241086a290000210c200241106a290000210d200341c0036a41186a200241186a290000370300200341c0036a41106a200d370300200341c0036a41086a200c370300200320073703c00320021029200341c0036a200341a00e6a412010e707450d010b02402013450d00201710290b41899ec4002102410b21014183b21821060c020b200341800e6a41186a4200370300200341800e6a41106a22064200370300200341800e6a41086a22024200370300200342003703800e41b3e6ca00ad4280808080e000841001220129000021072002200141086a290000370300200320073703800e2001102941c9e6ca00ad4280808080e0008410012201290000210720034190066a41086a2209200141086a29000037030020032007370390062001102920062003290390062207370300200341b0066a41086a2002290300370300200341b0066a41106a2007370300200341b0066a41186a2009290300370300200320032903800e3703b006200341c0026a200341b0066a412010fc010240201820032802c40241a08d066e410020032802c0021b4b0d00200341c0036a200b10c30420033502c80342208620032802c0032202ad841004024020032802c403450d00200210290b200320053602b80a200320083602b40a2003200a3602b00a200320193602c803200320133602c403200320173602c00320034190096a200b4100200341b00a6a200341c0036a10c9040c1a0b200341dc036a2019360200200341d8036a2013360200200341d4036a2017360200200341d0036a2005360200200341cc036a2008360200200341c0036a41086a200a360200200341023a00c403200320183602c00320034190096a200b10c30420033502980921072003280290092102410410272201450d48200342043702b40a200320013602b00a200341c0036a200341b00a6a10c40420032802b40a210120074220862002ad8420033502b80a42208620032802b00a220bad84100302402001450d00200b10290b0240200328029409450d00200210290b02402008450d00200a10290b2013450d19201710290c190b02402010450d00201510290b200f450d00201410290b02402008450d00200a10290b20004200370308200041206a20013602002000411c6a2002360200200041186a200636020020004201370300200424000f0b200341c0036a200141046a41c80010e4071a200341a00e6a41206a200241206a290200370300200341a00e6a41186a200241186a290200370300200341a00e6a41106a200241106a290200370300200341a00e6a41086a200241086a290200370300200320022902003703a00e2000200341c0036a200341a00e6a10cb05200424000f0b200341c80d6a41026a22092001410b6a2d00003a0000200320012f00093b01c80d2003200141186a2802003602d80d20032001411c6a2d00003a00dc0d200320012f011e3b01f80c200141286a2903002107200141206a290300211d200141c0006a290300210d200141386a2903002112200141d0006a290300211b200141c8006a290300211c200141086a2d0000210b2001410c6a2802002105200141106a2802002106200141146a280200210e200141306a290300210c200141d8006a280200210f200141dc006a280200211020012d001d2115200341e8026a41086a2214200141e8006a2802003602002003200141e0006a2903003703e80220022d0001210820022d0000210a02400240024002400240200b0e050001020304000b200341c0036a41146a4101360200200342013702c40320034198e3ca003602c003200341043602b40a200341cce3ca003602b00a2003200341b00a6a3602d003200341c0036a4180a6cc001040000b2003418c0d6a20032d00dc0d3a0000200341800e6a41026a20092d00003a0000200320032f01c80d3b01800e200320032802d80d3602880d200320032f01f80c3b01b006200341e7036a201b370000200341d7036a200d370000200320074238883c00c603200320074228883d01c403200320074208883e02c0032003201c3700df03200320123700cf03200320103600f3032003200f3600ef032003200c3700c703200341ff036a20142f01003b0000200320032903e8023700f703024002400240200a41ff01710d00200841ff01714102470d00412010272202450d4a2002201d370017200220032f01800e3b00002002200e36000b2002200636000720022005360003200220032802880d36000f200220153a0014200220032f01b0063b00152002411f6a20073c0000200241026a200341800e6a41026a2d00003a0000200241136a2003418c0d6a2d00003a0000200341d0066a200241201096042002102941002102200341a00e6a200341c0036a20032802d006220920032802d8064180a6cc004100109704024002400240024020032d00a00e4101470d00200341b00a6a410f6a2202200341b10e6a280000360000200341b00a6a41086a2201200341aa0e6a290100370300200341f0076a410f6a220b2002280000360000200341f0076a41086a22022001290300370300200341e10b6a2002290300370000200341e80b6a200b280000360000200320032d00a10e3a00d80b200320032901a20e3700d90b200341a00e6a200341d80b6a10ac0420032802a00e220120032802a80e109a0441ff01712102024020032802a40e450d00200110290b20024102470d01200341b00a6a41106a200341d80b6a41106a280200360200200341b00a6a41086a200341d80b6a41086a290300370300200320032903d80b3703b00a200341b30e6a200341880d6a41046a2d00003a0000200341bf0e6a20073c00002003200341800e6a41026a2d00003a00a20e200320032f01800e3b01a00e2003200e3600ab0e200320063600a70e200320053600a30e200320032802880d3600af0e200320153a00b40e2003201d3700b70e200320032f01b0063b00b50e20034190096a200341b00a6a200341a00e6a10ad0420032d00900922014104470d03024020032802d406450d00200910290b2000420037030820004200370300200424000f0b411b210b410321014118210a41c9eac300210820032802d4060d010c040b41052102411b210b410321014110210a419febc300210820032802d406450d030b200910290c020b20032f00910920032d00930941107472220b41ffffff077122024110762106200241087621022003290294092207422088a7210a2007a7210820032802d406450d02200910290c020b410221010b0b20004200370308200041206a200a3602002000411c6a2008360200200041186a2006411074200241ff017141087472200b41ff01717241087420017236020020004201370300200424000f0b200341f0076a41046a220120032d00dc0d3a0000200320032f01c80d3b01d006200320032802d80d3602f007200320092d00003a00d2062008200a41ff01714100477241ff01710d16200341800e6a41186a220a4200370300200341800e6a41106a22084200370300200341800e6a41086a22024200370300200342003703800e41c087cc00ad4280808080e00084221e1001220b290000212b2002200b41086a2900003703002003202b3703800e200b102941c497c400ad4280808080d00084222b1001220b290008212a200b2900002123200b1029200341b0066a41106a22092023370300200341b0066a41186a2210202a370300200341b0066a41086a22142002290300370300200320032903800e3703b006200341c8026a200341b0066a412010e301200341c8026a41106a290300212a20032903d002212320032802c802210b200a42003703002008420037030020024200370300200342003703800e201e1001220a290000212e2002200a41086a2900003703002003202e3703800e200a1029202b1001220a290008212b200a290000212e200a10292009202e3703002010202b37030020142002290300370300200320032903800e3703b006200320234200200b1b222b201d7c22233703c0032003202a4200200b1b20077c2023202b54ad7c3703c803200341b0066aad4280808080800484200341c0036aad222b42808080808002841003200341a00e6a41026a220b20032d00d2063a0000200341c0036a41046a20012d00003a0000200320032f01d0063b01a00e200320032802f0073602c003201e10012202290000212a20034190066a41086a200241086a2900003703002003202a3703900620021029201e10012202290008211e20022d0007210a20022d0006210820022f0004210920022d0003211020022d0002211420022f0000211320021029411410272202450d46200220032f01a00e3b00002002200e36000b2002200636000720022005360003200220032802c00336000f200241026a200b2d00003a0000200241136a200341c4036a2d00003a0000411410272201450d4620012002290000370000200141106a220b200241106a280000360000200141086a2211200241086a29000037000020021029413410272202450d462002201e3700182002200a3a0017200220083a0016200220093b0014200220103a0013200220143a0012200220133b00102002200329039006370000200241086a20034190066a41086a29030037000020022001290000370020200241286a2011290000370000200241306a200b28000036000020011029200320073703c8032003201d3703c0032002ad4280808080c00684202b42808080808002841003200210290240200c4201520d00200341a00e6a41026a220120032d00d2063a0000200341c0036a41046a220b200341f0076a41046a2d00003a0000200320032f01d0063b01a00e200320032802f0073602c00341c087cc00ad4280808080e0008410012202290000210720034190066a41086a200241086a29000037030020032007370390062002102941dfb3c700ad4280808080f0008410012202290008210720022d0007210a20022d0006210820022f0004210920022d0003211020022d0002211420022f0000211320021029411410272202450d47200220032f01a00e3b00002002200e36000b2002200636000720022005360003200220032802c00336000f200241026a20012d00003a0000200241136a200b2d00003a0000411410272201450d4720012002290000370000200141106a220b200241106a280000360000200141086a2211200241086a29000037000020021029413410272202450d47200220073700182002200a3a0017200220083a0016200220093b0014200220103a0013200220143a0012200220133b00102002200329039006370000200241086a20034190066a41086a29030037000020022001290000370020200241286a2011290000370000200241306a200b28000036000020011029412410272201450d472001201c370010200120123700002001200f360020200141186a201b3700002001200d3700082002ad4280808080c006842001ad4280808080c00484100320011029200210290b0240201541ff01714102460d00200341d3036a200341f4076a2d00003a0000200320032d00d2063a00c203200320032f01d0063b01c0032003200e3600cb03200320063600c703200320053600c303200320032802f0073600cf03200341a00e6a200341c0036a10990420032802a00e210120033502a80e2107200320154101713a00b003410110272202450d55200220032d00b0033a000020074220862001ad842002ad4280808080108410032002102920032802a40e450d00200110290b2000420037030820004200370300200424000f0b200141f4006a2802002113200141f0006a280200210b200141ec006a28020021012003418c0d6a20032d00dc0d3a0000200341800e6a41026a20092d00003a0000200320032f01c80d3b01800e200320032802d80d3602880d200320032f01f80c3b01b006200341e7036a201b370000200341d7036a200d370000200320074238883c00c603200320074228883d01c403200320074208883e02c0032003201c3700df03200320123700cf03200320103600f3032003200f3600ef032003200c3700c703200341ff036a20142f01003b0000200320032903e8023700f703024002400240024002400240200a41ff01710d00200841ff01714102470d00412010272202450d4b2002201d370017200220032f01800e3b00002002200e36000b2002200636000720022005360003200220032802880d36000f200220153a0014200220032f01b0063b00152002411f6a20073c0000200241026a200341800e6a41026a2d00003a0000200241136a2003418c0d6a2d00003a0000200341d0066a2002412010960420021029200341a00e6a200341c0036a20032802d006220820032802d8062001201310970420032d00a00e4101470d01200341b00a6a410f6a2202200341b10e6a280000360000200341b00a6a41086a220a200341aa0e6a290100370300200341f0076a410f6a22092002280000360000200341f0076a41086a2202200a29030037030020034190096a41086a220a200229030037030020034190096a410f6a22022009280000360000200320032901a20e37039009200320032d00a10e22093a00a00e200341a90e6a200a290300370000200341b00e6a200228000036000020032003290390093700a10e200341b00a6a200341a00e6a10990420032802b00a220a20032802b80a109a0441ff01712102024020032802b40a450d00200a10290b20024102460d04024041c40141c701200241017122021b2013470d0041b584cc0041f985cc0020021b22022001460d0520022001201310e707450d050b024020032802d406450d00200810290b41052103411b210a4103210241102108419febc3002106200b0d020c030b0240200b450d00200110290b410221020c040b024020032802d406450d00200810290b41002103411b210a410321024118210841c9eac3002106200b450d010b200110290b0c010b200341b90a6a20034190096a41086a290300370000200341b00a6a41106a2003419f096a280000360000200320093a00b00a20032003290390093700b10a2003200341800e6a41026a2d00003a00a20e200320032f01800e3b01a00e2003200e3600ab0e200320063600a70e200320053600a30e200341b30e6a200341880d6a41046a2d00003a0000200341bf0e6a20073c0000200320153a00b40e200320032802880d3600af0e2003201d3700b70e200320032f01b0063b00b50e200341d80b6a200341b00a6a200341a00e6a10ad04024020032d00d80b22024104470d00024020032802d406450d00200810290b0240200b450d00200110290b2000420037030820004200370300200424000f0b20032f00d90b20032d00db0b41107472220a41ffffff0771210620032902dc0b2207422088210c024020032802d406450d00200810290b2006411076210920064108762103200ca721082007a72106200b450d00200110290b20004200370308200041206a20083602002000411c6a2006360200200041186a2009411074200341ff017141087472200a41ff01717241087420027236020020004201370300200424000f0b200241026a29010021072002410a6a290100210c200241126a290100210d20032002411a6a2901003703980e2003200d3703900e2003200c3703880e200320073703800e02400240200841ff01714101470d00200a41ff01710d00200341a00e6a41186a200341800e6a41186a290300370300200341a00e6a41106a200341800e6a41106a290300370300200341a00e6a41086a200341800e6a41086a290300370300200320032903800e3703a00e200341d0066a200341a00e6a109c04200341c0036a20032802d006220220032802d806109d04200341b00a6a41086a2201200341ca036a290100370300200341b00a6a410f6a220b200341d1036a280000360000200320032901c2033703b00a0240024020032d00c0034101470d0020032d00c103210f200341f0076a410f6a200b280000360000200341f0076a41086a2001290300370300200320032903b00a3703f007024020032802d406450d00200210290b20034190096a410f6a2202200341f0076a410f6a28000036000020034190096a41086a2201200341f0076a41086a290300370300200341d80b6a41086a220b2001290300370300200341d80b6a410f6a22012002280000360000200320032903f00722073703d80b200341c9036a200b290300370000200341d0036a20012800003600002003200f3a00c003200320073700c103200341b00a6a200341c0036a10990420032802b00a220220032802b80a109a0441ff01712110024020032802b40a450d00200210290b024020104102460d004100210b4105210a411b21024103210141102108419febc300210941c40141c701201041017122101b200e470d0441b584cc0041f985cc0020101b22102005460d0020102005200e10e7070d040b200341b90a6a200341d80b6a41086a290300370000200341b00a6a41106a200341e70b6a2800003600002003200f3a00b00a200320032903d80b3700b10a200341c0036a41186a200341a00e6a41186a290300370300200341c0036a41106a200341a00e6a41106a290300370300200341c0036a41086a200341a00e6a41086a290300370300200320032903a00e3703c00320034190096a200341b00a6a200341c0036a10ad0420032d00900922014104470d01200341c0036a200341a00e6a109c0420033502c80342208620032802c0032202ad841004024020032802c403450d00200210290b02402006450d00200510290b2000420037030820004200370300200424000f0b024020032802d406450d00200210290b4100210b4102210a411b2102410321014110210841f1eac30021090c020b20032f00910920032d0093094110747241ffffff07712202411076210b2002410876210a2003290294092207422088a721082007a721090c010b41002102410221014100210a4100210b0b02402006450d00200510290b20004200370308200041206a20083602002000411c6a2009360200200041186a200b411074200a4108744180fe037172200241ff01717241087420017236020020004201370300200424000f0b2002411a6a2901002107200241196a2d0000210a200241186a2d00002108200241166a2f01002106200241156a2d00002109200241146a2d00002105200241126a2f0100210e200241116a2d0000210f200241106a2d000021102002410e6a2f010021142002410d6a2d000021152002410c6a2d000021132002410a6a2f01002111200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d00002119200241046a2d0000211a200241026a2f01002141200141216a290000210c200141206a2d000021422001411d6a2f000021432001411c6a2d00002144200141196a2f00002145200141186a2d00002146200141156a2f00002147200141146a2d00002148200141116a2f00002149200141106a2d0000214a2001410d6a2f0000214b2001410c6a2d0000214c200141096a2f0000214d20022d0001210b20022d0000210220012d001f214e20012d001b214f20012d0017215020012d0013215120012d000f215220012d000b21530240024002400240200141086a2d00000e0400010203000b200341c0036a41146a4101360200200342013702c40320034198e3ca003602c003200341043602b40a200341cce3ca003602b00a2003200341b00a6a3602d003200341c0036a4180a6cc001040000b02400240024002400240200241ff01710d00200b41ff01714101460d010b200341023a00a00e0c010b200320073703d8032003200a3a00d703200320083a00d603200320063b01d403200320093a00d303200320053a00d2032003200e3b01d0032003200f3a00cf03200320103a00ce03200320143b01cc03200320153a00cb03200320133a00ca03200320113b01c803200320163a00c703200320173a00c603200320183b01c403200320193a00c3032003201a3a00c203200320413b01c003200341a00e6a200341c0036a10cc0520032d00a00e4104460d010b20032802a00e21022000411c6a20032902a40e370200200041186a2002360200420121070c010b420021070b2000420037030820002007370300200424000f0b02400240024002400240200241ff01710d00200b41ff01714101460d010b200341023a00a00e0c010b2003200c3703d803200320423a00d7032003204e3a00d603200320433b01d403200320443a00d3032003204f3a00d203200320453b01d003200320463a00cf03200320503a00ce03200320473b01cc03200320483a00cb03200320513a00ca03200320493b01c8032003204a3a00c703200320523a00c6032003204b3b01c4032003204c3a00c303200320533a00c2032003204d3b01c003200341a00e6a200341c0036a10cc0520032d00a00e4104460d010b20032802a00e21022000411c6a20032902a40e370200200041186a2002360200420121070c010b420021070b2000420037030820002007370300200424000f0b0240024002400240200241ff01710d00200b41ff01714101470d00200141c8006a290300211b200141c0006a290300211c200141386a290300210d200141306a2903002112200141d0006a280200210b200320073703b80e2003200a3a00b70e200320083a00b60e200320063b01b40e200320093a00b30e200320053a00b20e2003200e3b01b00e2003200f3a00af0e200320103a00ae0e200320143b01ac0e200320153a00ab0e200320133a00aa0e200320113b01a80e200320163a00a70e200320173a00a60e200320183b01a40e200320193a00a30e2003201a3a00a20e200320413b01a00e41002102024020124280a094a58d1d544100200d501b450d0041022101411c210b4103210a410921034198b3c70021080c030b2003200c3703d803200320423a00d7032003204e3a00d603200320433b01d403200320443a00d3032003204f3a00d203200320453b01d003200320463a00cf03200320503a00ce03200320473b01cc03200320483a00cb03200320513a00ca03200320493b01c8032003204a3a00c703200320523a00c6032003204b3b01c4032003204c3a00c303200320533a00c2032003204d3b01c003200341b00a6a200341c0036a10cd0541002102200341e0026a20032802b00a220120032802b80a4180a6cc004100410010c70120032802e002210a024020032802b40a450d00200110290b410121010240200a4101470d00411c210b4103210a4117210341a1b3c70021080c030b200341b00a6a200341a00e6a200341c0036a2012200d410110e00320032d00b00a220a4104470d01200341d80b6a200341c0036a2012200d201c201b200b10af0420032d00d80b4104460d03200341b00a6a41086a200341d80b6a41086a280200360200200320032903d80b3703b00a41a095c8004137200341b00a6a41d895c80041e895c800103a000b4100210b4102210a41002101410021020c010b20032f00b10a20032d00b30a4110747241ffffff0771220b4110762102200b410876210120032902b40a2207422088a721032007a721080b20004200370308200041206a20033602002000411c6a2008360200200041186a200241107420014108744180fe037172200b41ff017172410874200a7236020020004201370300200424000f0b2000420037030820004200370300200424000f0b200341f8036a2001413c6a280200360200200341f0036a200141346a290200370300200341e8036a2001412c6a290200370300200341c0036a41206a200141246a290200370300200341c0036a41186a2001411c6a290200370300200341c0036a41106a200141146a290200370300200341c0036a41086a2001410c6a290200370300200320012902043703c003200341a00e6a41206a200241206a290200370300200341a00e6a41186a200241186a290200370300200341a00e6a41106a200241106a290200370300200341a00e6a41086a200241086a290200370300200320022902003703a00e2000200341c0036a200341a00e6a108904200424000f0b20004200370308200041186a410236020020004201370300200424000f0b200610cc0120061029200041186a41023602000c570b200041206a410e3602002000411c6a41e1b4c800360200200041186a20013602000c560b419d9bc500413041b8a1cc001033000b410221020c520b410121064180f8c40021084108210a0c4d0b4180800421014180f8c400210b410821080c4a0b20004200370308200041186a410236020020004201370300200424000f0b200341800e6a41186a220e4200370300200341800e6a41106a22014200370300200341800e6a41086a22024200370300200342003703800e41dcbec500ad4280808080800184221210012209290000211b2009290008212a200910292002202a3703002003201b3703800e419fe3c200ad4280808080d00184221b10012205290000212a20034190066a41086a2209200541086a2900003703002003202a37039006200510292001200329039006222a370300200341b0066a41086a220f2002290300370300200341b0066a41106a2210202a370300200341b0066a41186a22142009290300370300200320032903800e3703b006200341f8006a200341b0066a412010e301200341f8006a41106a290300212a200329038001212320032802782105200e42003703002001420037030020024200370300200342003703800e20121001220e2900002112200e290008212e200e10292002202e370300200320123703800e201b1001220e29000021122009200e41086a2900003703002003201237039006200e102920012003290390062212370300200f20022903003703002010201237030020142009290300370300200320032903800e3703b0062003427f202a420020051b22122007200d7d200c201c54ad7d7c2023420020051b221b200c201c7d7c222a201b542202ad7c221b2002201b201254201b2012511b22021b3703c8032003427f202a20021b3703c003200341c0036a2102200341b0066a21010c450b20004200370308200041186a410236020020004201370300200424000f0b20032802c803210220032802c403210620032802c00321080c330b4111214641ddd6c80021450c2f0b2001200a103e000b200b2008103e000b200b20061041000b200220061042000b4182aa0421030c1c0b4182aa0421030c0e0b200041186a41023602002000420037030820004201370300200424000f0b2000420037030820004200370300200424000f0b0240204a450d00204b10290b20004200370308200041206a200b3602002000411c6a2002360200200041186a20014180803c712049724180327236020020004201370300200424000f0b20032f00b10a20032d00b30a4110747241ffffff07712202411076210b2002410876210a20032902b40a2207422088a721032007a721080b20004200370308200041206a20033602002000411c6a2008360200200041186a200b411074200a4108744180fe037172200241ff01717241087420017236020020004201370300200424000f0b20021029200341003602c80d024020032802dc0d450d0020032802d80d10290b0240200d42ffffff3f83500d00200810290b0240200e450d00200e41246c450d00200510290b200110290c020b02402005200a41246c6a2802002208200b460d00200a2008200b496a210a0b200341b0066a41186a20034190066a41186a290300370300200341b0066a41106a20034190066a41106a290300370300200341b0066a41086a20034190066a41086a29030037030020032003290390063703b006200f200a4f0d00200a200f1041000b0240200f200e470d00200341d80d6a41186a200e410110960120032802f00d21050b2005200a41246c6a220841246a2008200f200a6b41246c10e5071a2008200b360200200820032903b0063702042008410c6a200341b0066a41086a2206290300370200200841146a200341b0066a41106a22092903003702002008411c6a200341b0066a41186a22052903003702002003200f41016a3602f80d200520034190066a41186a290300370300200920034190066a41106a290300370300200620034190066a41086a29030037030020032003290390063703b006024020032802ec0d220a20032802e80d470d00200341d80d6a410c6a200a4101109e0120032802ec0d210a0b20032802e40d220e200a4105746a220820032903b006370000200841186a2005290300370000200841106a2009290300370000200841086a20062903003700002003200a41016a220a3602ec0d20021029200341c80d6a200e200e200a4105746a10ce05200341c0036a41206a200341d80d6a41206a2802002202360200200341c0036a41186a200341d80d6a41186a2903002207370300200341c0036a41106a200341d80d6a41106a290300370300200341c0036a41086a200341d80d6a41086a290300370300200320032903d80d3703c003200341d80b6a2007a72208200210cf05200341b00a6a41e5cdc20010e90220032802b00a2102200320032802b80a36028c0d200320023602880d20032802d80b220a20032802e00b200341880d6a10a104024020032802b40a450d00200210290b024020032802dc0b450d00200a10290b200341b00a6a41e5cdc200200341c0036a10ea0220032802b00a2102200320032802b80a3602dc0b200320023602d80b20032802cc03220a200341d4036a280200200341d80b6a10cf01024020032802b40a450d00200210290b024020032802c403450d0020032802c00310290b0240200341d0036a28020041ffffff3f71450d00200a10290b0240200341dc036a2802002202450d00200241246c450d00200810290b20032802c80d21082001102920080d010b0240200341e40e6a2802002202450d00200241306c450d0020032802e00e10290b200ca7220b0d014118210341d9bbc7002102410021010c040b200341d00d6a280200210a20032802cc0d2109200341003602c803200342043703c003200341c0036a4100200a10980120032802c003210620032802c803210502400240200a0d0020032802c4032101200841002006200520032802f00e10ec0221050c010b200620054102746a2102200a210103402002418094ebdc03360200200241046a21022001417f6a22010d000b20032802c40321012008200a20062005200a6a20032802f00e10ec0221050b410410272202450d262002200b360000200341c8036a4284808080c000370300200341d0036a41002900e5cd42370300200341d8036a41002900edcd42370300200341e0036a20053a0000200320023602c403200341053a00c003200341c0036a10cb010240200141ffffffff0371450d00200610290b0240200a450d00200a41e0006c2101200841d4006a210203400240200241706a280200220b450d00200b41306c450d002002416c6a28020010290b0240200228020041ffffff3f71450d002002417c6a28020010290b200241e0006a2102200141a07f6a22010d000b0b02402009450d00200941e0006c450d00200810290b0240200341e40e6a2802002202450d00200241306c450d0020032802e00e10290b0240200ca72203450d00200341ffffff3f71450d00204610290b2000420037030820004200370300200424000f0b410021014118210341d9bbc7002102200b41ffffff3f71450d020b204610290c010b0b20004200370308200041206a20033602002000411c6a2002360200200041186a200136020020004201370300200424000f0b20004200370308200041206a41093602002000411c6a41eeebca00360200200041186a200336020020004201370300200424000f0b200820014105746a200341d0066a412010e7070d01410d21064180e8c9002109410021050b0240200742ffffff3f83500d00200810290b410321030c020b20034190066a41186a2201200341d0066a41186a29030037030020034190066a41106a220b200341d0066a41106a29030037030020034190066a41086a220a200341d0066a41086a290300370300200320032903d006370390062002200e4f0d02200f200329039006370000200f41186a2001290300370000200f41106a200b290300370000200f41086a200a2903003700002008200e10bb0520034190096a41186a220a420037030020034190096a41106a220b420037030020034190096a41086a220142003703002003420037039009419ad6ca00ad4280808080b00284220c10012206290000210d200341d80d6a41086a2202200641086a2900003703002003200d3703d80d2006102920012002290300370300200320032903d80d3703900941f0edca00ad4280808080f0008410012206290000210d2002200641086a2900003703002003200d3703d80d20061029200b20032903d80d220d370300200341f0076a41086a22052001290300370300200341f0076a41106a220f200d370300200341f0076a41186a2210200229030037030020032003290390093703f007200341203602c4032003200341f0076a3602c0032008200e200341c0036a10b901200341c0036a41186a200341d80b6a41186a290300370300200341c0036a41106a200341d80b6a41106a290300370300200341c0036a41086a200341d80b6a41086a290300370300200320032903d80b3703c00341012109200341c0036a41012008200e10c505200a4200370300200b4200370300200142003703002003420037039009200c10012206290000210c2002200641086a2900003703002003200c3703d80d2006102920012002290300370300200320032903d80d3703900941f8d7ca00ad4280808080d0008410012206290000210c2002200641086a2900003703002003200c3703d80d20061029200b20032903d80d220c37030020052001290300370300200f200c3703002010200229030037030020032003290390093703f007200341c0036a200341f0076a412010cd0120032d00c0032102200a200341c0036a41196a290000370300200b200341c0036a41116a2900003703002001200341c0036a41096a290000370300200320032900c103370390090240024020024101460d0041002109200341003a00b00a0c010b200341b00a6a41096a20034198096a290300370000200341b00a6a41116a200341a0096a290300370000200341b00a6a41196a200341a8096a290300370000200341013a00b00a20032003290390093700b10a0b200341d9036a200341f00b6a290300370000200341d1036a200341e80b6a290300370000200341c9036a200341e00b6a290300370000200320032903d80b3700c103200341013a00c00302402009450d00200341b00a6a410172200341c0036a410172412010e7070d0020034190096a41186a2206420037030020034190096a41106a2209420037030020034190096a41086a220142003703002003420037039009419ad6ca00ad4280808080b002841001220a290000210c200341d80d6a41086a2202200a41086a2900003703002003200c3703d80d200a102920012002290300370300200320032903d80d3703900941f8d7ca00ad4280808080d000841001220a290000210c2002200a41086a2900003703002003200c3703d80d200a1029200b20032903d80d370000200b41086a2002290300370000200341f0076a41086a2001290300370300200341f0076a41106a2009290300370300200341f0076a41186a200629030037030020032003290390093703f007412010272202450d1f200220032903d006370000200241186a200341d0066a41186a2201290300370000200241106a200341d0066a41106a220b290300370000200241086a200341d0066a41086a220a290300370000200341f0076aad42808080808004842002ad4280808080800484100320021029200341d9036a2001290300370000200341d1036a200b290300370000200341c9036a200a290300370000200320032903d0063700c103200341013a00c003200341c0036a10c6050b200742ffffff3f83500d00200810290b2003418d083b01c003200341c0036a10cb012000420037030820004200370300200424000f0b20004200370308200041206a20063602002000411c6a2009360200200041186a2005418080047120037241802a7236020020004201370300200424000f0b2002200e41b0e1ca001036000b200820014105746a200341d0066a412010e7070d01410d21054180e8c900210e410021090b0240200742ffffff3f83500d00200810290b410321030c020b200341b0066a41186a2201200341d0066a41186a290300370300200341b0066a41106a220b200341d0066a41106a290300370300200341b0066a41086a220a200341d0066a41086a290300370300200320032903d0063703b006200220064f0d02200f20032903b006370000200f41186a2001290300370000200f41106a200b290300370000200f41086a200a2903003700002008200610bb0520034190066a41186a420037030020034190066a41106a420037030020034190066a41086a220142003703002003420037039006419ad6ca00ad4280808080b00284220c10012202290000210d2002290008211220021029200120123703002003200d3703900641f0edca00ad4280808080f0008410012202290008210d2002290000211220021029200341d80d6a41106a2012370300200341d80d6a41186a200d370300200341d80d6a41086a2202200129030037030020032003290390063703d80d200341203602c4032003200341d80d6a3602c00320082006200341c0036a10b901200341c0036a41186a200341e8026a41186a290300370300200341c0036a41106a200341e8026a41106a290300370300200341c0036a41086a200341e8026a41086a290300370300200320032903e8023703c003200341c0036a41012008200610c50520034190096a41186a2209420037030020034190096a41106a220b420037030020034190096a41086a220142003703002003420037039009200c1001220a290000210c2002200a41086a2900003703002003200c3703d80d200a102920012002290300370300200320032903d80d3703900941f8d7ca00ad4280808080d000841001220a290000210c2002200a41086a2900003703002003200c3703d80d200a1029200b20032903d80d220c370300200341f0076a41086a2001290300370300200341f0076a41106a200c370300200341f0076a41186a200229030037030020032003290390093703f007200341c0036a200341f0076a412010cd0120032d00c00321022009200341d9036a290000370300200b200341d1036a2900003703002001200341c9036a290000370300200320032900c10337039009024020024101470d00200341d80b6a41186a20034190096a41186a290300220c370300200341d80b6a41106a20034190096a41106a290300220d370300200341d80b6a41086a20034190096a41086a29030022123703002003200329039009221b3703d80b200341b00a6a41186a200c370300200341b00a6a41106a200d370300200341b00a6a41086a20123703002003201b3703b00a41002102024020064101460d004100210203402006410176220120026a220b20022008200b4105746a200341b00a6a412010e7074101481b2102200620016b220641014b0d000b0b0240200820024105746a200341b00a6a412010e707450d00200341880d6a41186a4200370300200341880d6a41106a220a4200370300200341880d6a41086a22014200370300200342003703880d419ad6ca00ad4280808080b002841001220b290000210c20034190096a41086a2202200b41086a2900003703002003200c37039009200b10292001200229030037030020032003290390093703880d41f8d7ca00ad4280808080d000841001220b290000210c2002200b41086a2900003703002003200c37039009200b1029200a200329039009220c370300200341c0036a41086a2001290300370300200341c0036a41106a200c370300200341c0036a41186a2002290300370300200320032903880d3703c003200341c0036aad428080808080048410040c010b200341d9036a200341c80a6a290300370000200341d1036a200341c00a6a290300370000200341c9036a200341b80a6a290300370000200320032903b00a3700c103200341013a00c003200341c0036a10c6050b2003418d043b01c003200341c0036a10cb01200742ffffff3f83500d00200810290b2000420037030820004200370300200424000f0b20004200370308200041206a20053602002000411c6a200e360200200041186a2009418080047120037241802a7236020020004201370300200424000f0b2002200641a0e1ca001036000b20004200370308200041206a41093602002000411c6a41eeebca00360200200041186a200336020020004201370300200424000f0b200341c0036a41186a200341b00a6a41186a290300370300200341c0036a41106a200341b00a6a41106a290300370300200341c0036a41086a200341b00a6a41086a290300370300200320032903b00a3703c00341002106200341c0036a21014100210b0b024020062009470d00200341d80b6a20064101109e0120032802dc0b210920032802d80b21080b2008200b4105746a220241206a20022006200b6b41057410e5071a20022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a2900003700002003200641016a3602e00b20034190096a41186a420037030020034190096a41106a220a420037030020034190096a41086a220142003703002003420037039009419ad6ca00ad4280808080b002841001220b2900002107200341d80d6a41086a2202200b41086a290000370300200320073703d80d200b102920012002290300370300200320032903d80d3703900941f0edca00ad4280808080f000841001220b29000021072002200b41086a290000370300200320073703d80d200b1029200a20032903d80d2207370300200341f0076a41086a2001290300370300200341f0076a41106a2007370300200341f0076a41186a200229030037030020032003290390093703f007200341203602c4032003200341f0076a3602c00320032802d80b20032802e00b200341c0036a10b901200341c0036a41186a200341b00a6a41186a290300370300200341c0036a41106a200341b00a6a41106a290300370300200341c0036a41086a200341b00a6a41086a290300370300200320032903b00a3703c0034180a6cc00410020032802d80b220220032802e00b10c5052003410d3b01c003200341c0036a10cb010240200941ffffff3f71450d00200210290b2000420037030820004200370300200424000f0b200220086a2101200b21020b200341c0036a20034190096a2051200d10c205024020032802c0034101460d00200341f0056a350200210c200341a00e6a200341c0036a41086a41a80210e4071a200341cd036a20034190096a41086a220f290300370000200341d5036a20034190096a41106a2215290300370000200341dd036a20034190096a41186a2213290300370000200341ec036a2001360200200341e8036a2002360200200341063a00c4032003410b3a00c00320032003290390093700c503200341c0036a10cb01200341cc0a6a2008360200200341b00a6a41186a2009360200200341b00a6a41106a200b360200200341bc0a6a2005360200200320103602d00a2003200e3602c40a2003200a3602b80a200320073703b00a200341d80b6a41186a2013290300370300200341d80b6a41106a2015290300370300200341d80b6a41086a200f29030037030020032003290390093703d80b200341c0036a200341a00e6a41a80210e4071a200c42c03e7e2006ad4290a10f7e7c4280eb93cf007c2107200220144f2006200341b00a6a200341d80b6a200341c0036a10c305210c0c040b200341cc036a28020021010b20032802c803210620032d00c703210820032d00c603210b20032d00c503210220032d00c40321500b0240200541ffffff3f71450d00200a10290b200941ffffff3f71450d00200e10290b200020083a001b2000200b3a001a200020023a001920004200370308200041206a20013602002000411c6a2006360200200041186a20503a000020004201370300200424000f0b20004201370308200041106a427f2007200c7c220c200c2007541b37030020004200370300200424000f0b200341e5036a20032903d80b370000200341cd036a200341b00a6a41086a290300370000200341d5036a200341b00a6a41106a290300370000200341dd036a200341b00a6a41186a290300370000200341ed036a200341d80b6a41086a290300370000200341f5036a200341d80b6a41106a290300370000200341fd036a200341d80b6a41186a290300370000200341013a00c4032003410b3a00c003200320032903b00a3700c5032003418c046a200a36020020034188046a200836020020034185046a200e3a0000200341c0036a10cb01200341c0036a41206a200341a00e6a41206a280200360200200341c0036a41186a200341a00e6a41186a290300370300200341c0036a41106a200341a00e6a41106a290300370300200341c0036a41086a200341a00e6a41086a290300370300200320032903a00e3703c00320034190096a200341d80b6a10c005200328029009210220032003280298093602f407200320023602f007200341c0036a200341f0076a10bf050240200328029409450d00200210290b0240200341cc036a28020041ffffff3f71450d0020032802c80310290b0240200341d8036a28020041ffffff3f71450d0020032802d40310290b200d42a0c21e7e4280aaead5007c210c0240200742ffffff3f83500d00200610290b200041106a200c3703002000420137030820004200370300200424000f0b410d210341b7d6c8002102410421010b0240201041ffffff3f71450d00200910290b201541ffffff3f71450d00201410290b4103210b200742ffffff3f83500d00200610290b200041206a20033602002000411c6a2002360200200020013a001a200041133a0019200041186a200b3a00002000420037030820004201370300200424000f0b41032101200742ffffff3f83500d010b200510290b200b10cc01200b1029200041206a20463602002000411c6a2045360200200041003a001b200020023a001a200041133a0019200041186a20013a00002000420037030820004201370300200424000f0b200341c0036a2017201510b80520032802c0032101200320032802c8033602a40e200320013602a00e20082002200341a00e6a10a104024020032802c403450d00200110290b02402006450d00200810290b0240200742ffffff3f83500d00201110290b02402014450d00201310290b0240200e450d00200e410c6c21022010210303400240200341046a280200450d00200328020010290b2003410c6a2103200241746a22020d000b0b0240200f450d00200f410c6c450d00201010290b2000420037030820004200370300200424000f0b200320023602b4060b0240200328028c0d2202450d00200241306c450d00200610290b410021060b200341a00e6a41c5cdc200200341d80d6a10ea02200341d80b6a20032802a00e220820032802a80e10ce012009410020061b210a2002410020061b210f20032902dc0b420020032802d80b22021b21122006410820061b21092002410120021b210b024020032802a40e450d00200810290b200341d0066a41206a200a360200200341ec066a200f360200200341d0066a41106a2012370300200341d0066a41086a200341d80d6a41086a280200360200200320032903d80d3703d006200320093602e8062003200b3602dc060240200ca7450d00200510290b200341d80b6a41086a2202200141086a290300370300200341d80b6a41106a200141106a290300370300200341d80b6a41186a200141186a290300370300200341d80b6a41206a200141206a290300370300200341d80b6a41286a220a200141286a290300370300200341d80b6a41306a2208200141306a290300370300200341d80b6a41386a2206200141386a290300370300200341b0036a41086a2205200141cc006a280200360200200320012903003703d80b200320012902443703b0030240024002400240024020012802402210450d00200341880d6a41386a22142006290300370300200341880d6a41306a22062008290300370300200341880d6a41286a2208200a290300370300200341880d6a41206a220a200341d80b6a41206a290300370300200341880d6a41186a2215200341d80b6a41186a290300370300200341880d6a41106a2213200341d80b6a41106a290300370300200341880d6a41086a22112002290300370300200341f80c6a41086a22022005280200360200200320032903d80b3703880d200320032903b0033703f80c20034190096a41386a201429030037030020034190096a41306a200629030037030020034190096a41286a200829030037030020034190096a41206a200a29030037030020034190096a41186a201529030037030020034190096a41106a201329030037030020034190096a41086a2011290300370300200320032903880d37039009200320103602d009200341d4096a220a20032903f80c370200200a41086a2002280200360200410810272202450d1320022007370000200241084110102b2202450d132002200d370008200341ac0e6a220a41002900c5cd42370000200a41086a41002900cdcd423700002003429080808080023702a40e200320023602a00e200320034190096a3602bc0e200341e8026a200341a00e6a10ca0520021029200341a00e6a200341e8026a10d502200341c8016a20032802a00e220a20032802a80e4180a6cc004100410010c70120032802c8012102024020032802a40e450d00200a10290b024020024101460d00200341d80b6a20034190096a41d00010e4071a412010272202450d06200342013702dc0d200320023602d80d200341d80d6a41004101109e01200341800e6a41086a220b20032802e00d220241016a36020020032802d80d20024105746a2202200e290000370000200241086a200e41086a290000370000200241106a200e41106a290000370000200241186a200e41186a290000370000200320032903d80d3703800e200341a00e6a200341d80b6a41d00010e4071a200341f00e6a220241086a200b280200360200200220032903800e370200200341d80b6a200341e8026a10d50220032802d80b2102200320032802e00b3602dc0d200320023602d80d200341a00e6a200341d80d6a10e402024020032802dc0b450d00200210290b024020032802e40e2202450d00200241306c450d0020032802e00e10290b024020032802f40e41ffffff3f71450d0020032802f00e10290b200341d80d6a41186a200341e8026a41186a290300370300200341d80d6a41106a200341e8026a41106a290300370300200341d80d6a41086a200341e8026a41086a290300370300200320032903e8023703d80d41002102024020032802f006221041014b0d00024020100e020004000b20034190066a41186a200341d80d6a41186a29030037030020034190066a41106a200341d80d6a41106a29030037030020034190066a41086a200341d80d6a41086a290300370300200320032903d80d37039006410021020c040b2010210b03400240417f2009200b410176220820026a220641306c6a2205290300220c200752200c2007541b220a0d00417f2005290308220c200d52200c200d541b210a0b20022006200a4101461b2102200b20086b220b41014d0d030c000b0b20032802d4092202450d00200241306c450d0020032802d00910290b20011029200341003602c80d024020032802d406450d0020032802d00610290b0240201242ffffff3f83500d00200b10290b0240200f450d00200f41306c450d00200910290b200e10290c020b024002400240417f2009200241306c6a220a290300220c200752200c2007541b220b0d0041ff01210b200a290308220c200d540d01200c200d52210b0b200b450d010b2002200b41ff017141ff01466a21020b20034190066a41186a200341d80d6a41186a29030037030020034190066a41106a200341d80d6a41106a29030037030020034190066a41086a200341d80d6a41086a290300370300200320032903d80d37039006201020024f0d00200220101041000b02402010200f470d00200341d0066a41186a200f410110900120032802e80621090b2009200241306c6a220b41306a200b201020026b41306c10e5071a200b200d370308200b2007370300200b200329039006370310200b41186a20034190066a41086a290300370300200b41206a20034190066a41106a290300370300200b41286a20034190066a41186a2903003703002003201041016a3602f006200341b0066a41186a2208200341d80d6a41186a290300370300200341b0066a41106a2206200341d80d6a41106a290300370300200341b0066a41086a2209200341d80d6a41086a290300370300200320032903d80d3703b006024020032802e406220220032802e006470d00200341dc066a20024101109e0120032802e40621020b20032802dc06220a20024105746a220b20032903b006370000200b41186a2008290300370000200b41106a2006290300370000200b41086a20092903003700002003200241016a22023602e40620011029200341c80d6a200a200a20024105746a10ce05200341a00e6a41206a200341d0066a41206a2802002202360200200341a00e6a41106a200341d0066a41106a290300370300200341a00e6a41086a200341d0066a41086a290300370300200341a00e6a41186a200341d0066a41186a290300220c370300200320032903d0063703a00e200241306c4104722201417f4c0d0320011027220b450d02200341003602e00b200320013602dc0b2003200b3602d80b2002200341d80b6a10710240024020020d0020032802e00b210120032802dc0b210a20032802d80b210f0c010b200ca72213200241306c6a2111410020032802e00b22056b210820032802dc0b210a410021020340200520026a2106201320026a2201290300210c02400240200a20086a4108490d0020032802d80b210b200a21090c010b200641086a220b2006490d08200a4101742209200b2009200b4b1b22094100480d0802400240200a0d00024020090d004101210b0c020b20091027220b450d150c010b20032802d80b210b200a2009460d00200b200a2009102b220b450d140b200320093602dc0b2003200b3602d80b0b200b20056a20026a200c3700002003200641086a220a3602e00b200141086a290300210c0240200920086a41786a41074b0d00200a41086a220f200a490d082009410174220a200f200a200f4b1b220a4100480d080240024020090d000240200a0d004101210b0c020b200a1027220b450d150c010b2009200a460d00200b2009200a102b220b450d140b2003200a3602dc0b2003200b3602d80b0b200b20056a20026a41086a200c3700002003200641106a220a3602e00b41201027220b450d04200b200141106a290000370000200b41186a2210200141286a290000370000200b41106a2214200141206a290000370000200b41086a2215200141186a29000037000002400240200820032802dc0b22096a41706a4120490d0020032802d80b210f2009210a0c010b200a41206a220f200a490d082009410174220a200f200a200f4b1b220a4100480d080240024020090d000240200a0d004101210f0c020b200a1027220f450d150c010b20032802d80b210f2009200a460d00200f2009200a102b220f450d140b2003200a3602dc0b2003200f3602d80b0b200f20056a20026a220941106a200b290000370000200941286a2010290000370000200941206a2014290000370000200941186a20152900003700002003200641306a3602e00b200b1029200841506a2108200241306a2102200141306a2011470d000b200520026a21010b200341d80b6a41c5cdc20010e90220032802d80b2102200320032802e00b360294092003200236029009200f200120034190096a10a104024020032802dc0b450d00200210290b0240200a450d00200f10290b200341d80b6a41c5cdc200200341a00e6a10ea0220032802d80b2102200320032802e00b36029409200320023602900920032802ac0e2201200341b40e6a28020020034190096a10cf01024020032802dc0b450d00200210290b024020032802a40e450d0020032802a00e10290b0240200341b00e6a28020041ffffff3f71450d00200110290b0240200341bc0e6a2802002202450d00200241306c450d0020032802b80e10290b20032802c80d2108200e102920080d010b0240200341840b6a2802002202450d00200241306c450d0020032802800b10290b4180801421034116210241e7d4c80021014103210b0c050b20164101201641014b1b2202418094ebdc036e220120022001418094ebdc036c476a22014101200141014b1b220120024b0d02200341d00d6a280200210a20032802cc0d2109200341003602a80e200342043703a00e200341a00e6a4100200a1098012002200a41036c220b2002200b491b20016ead428094ebdc037e200220016ead8042ffffffff0f83220c200c7e220c42808090bbbad6adf00d200c42808090bbbad6adf00d541b428094ebdc0380210c20032802a00e210620032802a80e210502400240200a0d0020032802a40e2101200841002006200520032802900b10ec02210b0c010b200ca7210b200620054102746a2102200a210103402002200b360200200241046a21022001417f6a22010d000b20032802a40e21012008200a20062005200a6a20032802900b10ec02210b0b410810272202450d0e20022007370000200241084110102b2202450d0e2002200d370008200341a80e6a42908080808002370300200341a00e6a41106a41002900c5cd42370300200341b80e6a41002900cdcd42370300200341c00e6a200b3a0000200320023602a40e200341053a00a00e200341a00e6a10cb010240200141ffffffff0371450d00200610290b0240200a450d00200a41e0006c2101200841d4006a210203400240200241706a280200220b450d00200b41306c450d002002416c6a28020010290b0240200228020041ffffff3f71450d002002417c6a28020010290b200241e0006a2102200141a07f6a22010d000b0b02402009450d00200941e0006c450d00200810290b0240200341840b6a2802002202450d00200241306c450d0020032802800b10290b2000420037030820004200370300200424000f0b1039000b1038000b41f0a6c700411941dcaac7001033000b1032000b20004200370308200041206a20023602002000411c6a2001360200200041186a20034180801c71200b7241801c7236020020004201370300200424000f0b024020032802cc032202450d00200241246c21012016210203400240024020022d0000220b41044b0d00024002400240200b0e050400010204040b2002410c6a280200450d03200241086a28020010290c030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b200241086a280200450d00200241046a28020010290b200241246a21022001415c6a22010d000b0b024020032802c8032202450d00200241246c450d00201610290b02402044200a460d000340200810d3020240200841046a2802002202450d00200241246c450d00200828020010290b200841f0006a2108200941907f6a22090d000b0b02402005450d00200541f0006c450d00200f10290b02402003280294092203450d00200341c4006c450d00201110290b4103210b0c040b2044200a460d00200f200641f0006c6a210b0340200a220241046a220110d302200241f0006a210a0240200241086a2802002202450d00200241246c450d00200128020010290b200b200a470d000b0b02402005450d00200541f0006c450d00200f10290b200341b0066a41186a4200370300200341b0066a41106a4200370300200341b0066a41086a22024200370300200342003703b00641e4bec500ad4280808080a001841001220129000021072001290008210c200110292002200c370300200320073703b006418cb2c400ad4280808080e000841001220129000821072001290000210c2001102920034190066a41106a200c37030020034190066a41186a200737030020034190066a41086a2002290300370300200320032903b00637039006200341c0036a2011201310bb01201c20033502c80342208620032802c0032202ad841003024020032802c403450d00200210290b02402003280294092203450d00200341c4006c450d00201110290b420021070c030b200641f0006c2102200f41046a21030340200310d3020240200341046a2802002201450d00200141246c450d00200328020010290b200341f0006a2103200241907f6a22020d000b0b2005450d00200541f0006c450d00200f10290b200041206a200e3602002000411c6a2015360200200041186a2014411074200b7241801072360200420121070b2000200737030020004200370308200424000f0b2001ad42808080808004842002ad4280808080800284100320032903f002211b20032903e80221120b200341f0076a41106a21020240024002402012201d56201b201e56201b201e5122011b0d002012201d54201b201e5420011b450d02200341800e6a41186a220f4200370300200341800e6a41106a22094200370300200341800e6a41086a22014200370300200342003703800e41dcbec500ad4280808080800184222a1001220529000021232005290008212e200510292001202e370300200320233703800e419fe3c200ad4280808080d0018422231001220e290000212e20034190066a41086a2205200e41086a2900003703002003202e37039006200e10292009200329039006222e370300200341b0066a41086a22102001290300370300200341b0066a41106a2214202e370300200341b0066a41186a22152005290300370300200320032903800e3703b006200341e0006a200341b0066a412010e301200341e0006a41106a290300212e2003290368212d2003280260210e200f42003703002009420037030020014200370300200342003703800e202a1001220f290000212a200f290008212c200f10292001202c3703002003202a3703800e20231001220f290000212a2005200f41086a2900003703002003202a37039006200f10292009200329039006222a370300201020012903003703002014202a37030020152005290300370300200320032903800e3703b00620034200202e4200200e1b222a201d201254ad201b201e7d7c7c202d4200200e1b2223201d20127d222d54ad7d222e2023202d7d222d202356202e202a56202e202a511b22011b3703c80320034200202d20011b3703c003200341c0036a2101200341b0066a21090c010b200341800e6a41186a220f4200370300200341800e6a41106a22094200370300200341800e6a41086a22014200370300200342003703800e41dcbec500ad4280808080800184222a1001220529000021232005290008212e200510292001202e370300200320233703800e419fe3c200ad4280808080d0018422231001220e290000212e20034190066a41086a2205200e41086a2900003703002003202e37039006200e10292009200329039006222e370300200341b0066a41086a22102001290300370300200341b0066a41106a2214202e370300200341b0066a41186a22152005290300370300200320032903800e3703b006200341c8006a200341b0066a412010e301200341c8006a41106a290300212e2003290350212d2003280248210e200f42003703002009420037030020014200370300200342003703800e202a1001220f290000212a200f290008212c200f10292001202c3703002003202a3703800e20231001220f290000212a2005200f41086a2900003703002003202a37039006200f10292009200329039006222a370300201020012903003703002014202a37030020152005290300370300200320032903800e3703b0062003427f202e4200200e1b222a201b201e7d2012201d54ad7d7c202d4200200e1b22232012201d7d7c222e2023542201ad7c222320012023202a542023202a511b22011b3703c8032003427f202e20011b3703c003200341c0036a2101200341b0066a21090b2009ad42808080808004842001ad428080808080028410030b2003200c3703f0072003201b370388082003201237038008200320073703f80720032802f80c210120034190096a41186a200241086a290300222a37030020034190096a41206a2209200241106a290300370300200341b8096a2205200241186a290300370300200341c0096a220e200241206a29030037030020032007370398092003200c370390092003200229030022233703a00902400240427f200c20237c22232023200c5422022007202a7c2002ad7c222a200754202a2007511b22021b22234280c8afa025544100427f202a20021b222e501b0d0020034190096a41106a2903002131200e2903002130200529030021232009290300212e200329039809212d200329039009212c4201212a20032903a809212f0c010b4200212a02402023202e84500d002023202e10d402200341f8036a202e370300200341f0036a2023370300200341c0036a41086a41013a0000200341c9036a2001290000370000200341d1036a200141086a290000370000200341d9036a200141106a290000370000200341e1036a200141186a290000370000200341033a00c003200341c0036a10cb010b0b200341800c6a202e370300200341880c6a2023370300200341e80b6a202d370300200341900c6a2030370300200341f00b6a20313703002003202f3703f80b200320243703980c2003202c3703e00b200320064100202b42015122021b22063a00a40c20032008410020021b22083602a00c2003202a4201512202ad3703d80b0240024020020d00200aad422086200bad8410040c010b410410272202450d0120022008360000200320063a00b003200241044108102b2202450d01200220032d00b0033a0004200241084115102b2202450d012002202c3700052002410d6a202d370000200341f80b6a290300212d200341f00b6a290300212c20024115412a102b2202450d012002202c3700152002411d6a202d3700002002412a41d400102b2202450d012002202e3700252002412d6a20233700002002413d6a200341980c6a2903003700002002200341900c6a290300370035200aad422086200bad842002ad4280808080d008841003200210290b201c201d7c221d201c542202200d201e7c2002ad7c221c200d54201c200d511b21020240200328028c0d450d00200b10290b427f201c20021b210d427f201d20021b211c202a4201522102024002400240202b4201510d0020020d004103210b200341a00e6a21020c010b202b4201522002410173720d014104210b200341b00a6a21020b200241086a200b3a0000200241096a20032903d006370000200241003a0000200241116a200341d0066a41086a290300370000200241196a200341e0066a290300370000200241216a200341e8066a290300370000200210cb010b0240201c200d844200520d00200341f8036a2007370300200341f0036a200c370300200341c0036a41086a41003a0000200341c9036a2001290000370000200341d1036a200141086a290000370000200341d9036a200141106a290000370000200341e1036a200141186a290000370000200341033a00c003200341c0036a10cb010b20034188046a201b37030020034180046a2012370300200341f8036a2007370300200341f0036a200c370300200341c0036a41086a41033a0000200341c9036a20032903d006370000200341d1036a200341d0066a41086a290300370000200341d9036a200341e0066a290300370000200341e1036a200341e8066a290300370000200341033a00c003200341c0036a10cb012000420037030820004200370300200424000f0b1030000b024020032802f407450d00200610290b20024104470d00200341c8036a200a360200200341013a00c403200341023a00c003200341c0036a10cb012000420037030820004200370300200424000f0b20004200370308200041206a20083602002000411c6a200b360200200041186a2001418080047120027241800a7236020020004201370300200424000f0b0240200328029409450d00200910290b200241ff01714104470d00200341e8036a2043360200200341cd036a200341b80a6a290300370000200341d5036a200341c00a6a290300370000200341dd036a200341c80a6a290300370000200341003a00c403200341023a00c003200320032903b00a3700c503200341c0036a10cb012000420037030820004200370300200424000f0b20004200370308200041206a200a3602002000411c6a2008360200200041186a20014118742006411074418080fc077172200b4108744180fe037172200241ff01717236020020004201370300200424000f0b41042102410021050240201041ff01714104460d00201021020c010b200341f0036a4200370300200341e8036a4280d0dbc3f402370300200341c0036a41106a200341b00a6a41086a290300370300200341c0036a41186a200341b00a6a41106a290300370300200341e0036a200341b00a6a41186a290300370300200342013703c003200320032903b00a3703c8032003200f3602a40e2003200e3602a00e200341c0036a41086a200341a00e6a10b305410121050b024020032802f407450d00200e10290b02402005450d00200341e8036a200a360200200341cd036a200341e00b6a290300370000200341d5036a200341e80b6a290300370000200341dd036a200341f00b6a290300370000200341003a00c403200341023a00c003200320032903d80b3700c503200341c0036a10cb010c020b200241ff01714104460d010b20004200370308200041206a20013602002000411c6a200b360200200041186a2008411874200641ff017141107472200941ff017141087472200241ff01717236020020004201370300200424000f0b2000420037030820004200370300200424000f0b420121070b2000200737030020004200370308200424000f0b41002103410221020b20004200370308200041206a200b3602002000411c6a2001360200200041186a20034180801c7120027236020020004201370300200424000f0b02402009450d00200a10290b02402005450d00200e10290b41032105200f450d05200f410c6c450d05201310290c050b2005450d00200e10290b2009450d010b200a10290b2001450d00200210290b410321054102210b411d210141e0e4ca0021020b200b41ff0171411074210302402008450d00200610290b20004200370308200041206a20013602002000411c6a2002360200200041186a200320057236020020004201370300200424000ba50403027f017e057f230041306b2202240041e0a7c800ad4280808080900184100122032900002104200241086a200341086a290000370300200220043703002003102941e9a7c800ad4280808080e00084100122032900002104200241106a41086a200341086a2900003703002002200437031020031029200241206a2001280200200128020810eb0202400240024002402002280228220541206a2206417f4c0d00200228022021070240024020060d0041002103410121010c010b200610272201450d02200621030b024002402003410f4d0d00200321080c010b200341017422084110200841104b1b22084100480d03024020030d002008102722010d010c050b20032008460d00200120032008102b2201450d040b20012002290300370000200141086a200241086a2903003700000240024020084170714110460d00200821030c010b200841017422034120200341204b1b22034100480d0320082003460d00200120082003102b2201450d040b20012002290310370010200141186a200241106a41086a29030037000002400240200341606a2005490d00200321080c010b200541206a22082005490d03200341017422092008200920084b1b22084100480d0320032008460d00200120032008102b2201450d040b200141206a2007200510e4071a20002006360208200020083602042000200136020002402002280224450d00200710290b200241306a24000f0b1038000b1039000b1032000b1030000b9d0102017f017e230041106b2206240002402002ad4220862001ad842004ad4220862003ad84200510242207422088a72204450d002007a722052d0000220341014b0d00410021010240024020030e020100010b2004417f6a4104490d0120052800012102410121010b200510292000200236020420002001360200200641106a24000f0b41e891cc00412e200641086a419893cc00419892cc00103a000bcf0201067f0240024020012802042202450d00200128020022032d0000210420012002417f6a2205360204410121062001200341016a3602000240200441037122074103460d0002400240024020070e03000102000b20044102762107410021060c040b41012106024020050d000c040b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d03200141fcff03714102762107410021060c030b20054103490d01200341036a2d0000210620032f0001210720012002417c6a3602042001200341046a3602002007200641107472410874200472220141808004492106200141027621070c020b0240200441034d0d000c020b20054104490d012003280001210720012002417b6a3602042001200341056a36020020074180808080044921060c010b410121060b20002007360204200020063602000b3601017f02404108102722030d001039000b200320013600042003200036000020022902002003ad42808080808001841003200310290b850204017f017e027f017e230041206b220224002002200010c001200235020821032002280200210420012802b40221050240410110272200450d0020024201370214200220003602100240024020054102470d00200041003a00002002410136021842808080801021060c010b200041013a0000200241013602182001200241106a10e302200235021842208621060b2002280214210020034220862004ad84200620022802102205ad84101402402000450d00200510290b02402002280204450d00200410290b024020012802b4024102460d00024020012802a8022200450d00200141ac026a280200450d00200010290b200110cc010b200241206a24000f0b1039000bc81106047f017e037f017e097f027e23004190026b22012400200141c8016a41186a4200370300200141c8016a41106a22024200370300200141c8016a41086a22034200370300200142003703c80141b3e6ca00ad4280808080e00084100122042900002105200141e8016a41086a2206200441086a290000370300200120053703e8012004102920032006290300370300200120012903e8013703c80141c9e6ca00ad4280808080e000841001220429000021052006200441086a290000370300200120053703e80120041029200220012903e8012205370300200141a8016a41086a2003290300370300200141a8016a41106a2005370300200141a8016a41186a2006290300370300200120012903c8013703a801200141086a200141a8016a412010fc0102400240024002402001280208450d00200128020c450d00200141c8016a41186a22044200370300200141c8016a41106a22074200370300200141c8016a41086a22034200370300200142003703c80141b3e6ca00ad4280808080e000842205100122082900002109200141e8016a41086a2206200841086a290000370300200120093703e8012008102920032006290300370300200120012903e8013703c80141c0a4cb00ad4280808080e001841001220829000021092006200841086a290000370300200120093703e80120081029200220012903e801370000200241086a220a2006290300370000200141a8016a41086a22082003290300370300200141a8016a41106a220b2007290300370300200141a8016a41186a220c2004290300370300200120012903c8013703a801200141203602fc012001200141a8016a3602f801200141e8016a200141a8016aad428080808080048422091007108b020240024020012802e801220d0d004103210e0c010b20012802ec01210f02400240024020062802002210450d00200d2d0000221141024b0d004101210e0240024020110e03000401000b2010417f6a4104490d01200d28000121124100210e0c030b4102210e0c010b200141003602d001200142013703c8012001410d360284022001200141f8016a360280022001200141c8016a36028c02200141246a410136020020014201370214200141f4eaca00360210200120014180026a3602202001418c026a41a8a3c800200141106a10371a20013502d00142208620013502c801841008024020012802cc01450d0020012802c80110290b4103210e0b0b200f450d00200d10290b200141003602d001200142013703c801200141c8016a41004100109e01200820012802d00136020020014194016a2012360200200120012903c8013703a80120014102200e200e4103461b220e36029001200141106a200041800110e4071a200141a0016a2008280200360200200120012903a80137039801200442003703002007420037030020034200370300200142003703c80120051001220029000021052006200041086a290000370300200120053703e8012000102920032006290300370300200120012903e8013703c80141e0a2cb00ad4280808080a0018422131001220029000021052006200041086a290000370300200120053703e80120001029200220012903e801370000200a200629030037000020082003290300370300200b2007290300370300200c2004290300370300200120012903c8013703a8012001200141a8016a412010fc0102402001280204410020012802001b220641016a22072006490d00200141c8016a41186a22044200370300200141c8016a41106a22004200370300200141c8016a41086a22034200370300200142003703c80141b3e6ca00ad4280808080e000842205100122082900002114200141e8016a41086a2206200841086a290000370300200120143703e8012008102920032006290300370300200120012903e8013703c80120131001220829000021132006200841086a290000370300200120133703e80120081029200220012903e801370000200241086a22082006290300370000200141a8016a41086a220a2003290300370300200141a8016a41106a220b2000290300370300200141a8016a41186a220c2004290300370300200120012903c8013703a801200120073602c8012009200141c8016aad4280808080c000841003200442003703002000420037030020034200370300200142003703c80120051001220729000021052006200741086a290000370300200120053703e8012007102920032006290300370300200120012903e8013703c80141eaf9ca00ad4280808080e000841001220729000021052006200741086a290000370300200120053703e80120071029200220012903e80137000020082006290300370000200a2003290300370300200b2000290300370300200c2004290300370300200120012903c8013703a801200141003602d001200142013703c8010240200e41024b0d00024002400240200e0e03000102000b410110272206450d05200141013602cc01200120063602c801200641003a0000200141013602d0010240024020012802cc012203417f6a4104490d004101210620012802c80121020c010b41012106200341017422024105200241054b1b22044100480d0720012802c8012102024020032004460d00200220032004102b2202450d0720012802d00121060b200120043602cc01200120023602c8010b200220066a20123600002001200641046a3602d0010c020b410110272206450d04200141013602cc01200120063602c801200641013a0000200141013602d0010c010b410110272206450d03200141013602cc01200120063602c801200641023a0000200141013602d0010b200141106a200141c8016a10e905200128029801200141a0016a280200200141c8016a10850620012802cc012106200920013502d00142208620012802c8012202ad84101402402006450d00200210290b200141106a10ad072001419c016a28020041ffffff3f71450d0420012802980110290c040b200141106a10ad072001419c016a28020041ffffff3f71450d0320012802980110290c030b200010ad070c020b1030000b1032000b20014190026a24000bea1501047f0240024020002802002201411a4b0d0002400240024002400240024002400240024002400240024002400240024002400240024020010e1b00011313131302031304130506130708090a0b0c0d130e0f101311000b200041086a280200417e6a220141074b0d1202400240024002400240024020010e080018010218030405000b200041106a280200450d172000410c6a28020010290f0b200041106a280200450d162000410c6a28020010290f0b200041106a280200450d152000410c6a28020010290f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141186a2101200241686a22020d000b0b200041106a2802002201450d14200141186c450d14200028020c10290f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d132001410c6c450d13200028020c10290f0b200041106a280200450d122000410c6a28020010290f0b024020002d0004220141034b0d000240024020010e0414001401140b200041186a220128020010cc01200128020010290f0b02402000410c6a280200450d00200041086a28020010290b200041246a220128020010cc01200128020010290f0b2000410c6a280200450d11200041086a28020010290f0b02402000410c6a2802002201450d00200141f0006c2102200028020441046a21010340200110d3020240200141046a2802002203450d00200341246c450d00200128020010290b200141f0006a2101200241907f6a22020d000b0b200041086a2802002201450d10200141f0006c450d10200028020410290f0b0240200041086a2d0000220141174b0d000240024002400240024020010e18151515151515001515151515150115150203151515151504150b200041106a28020041ffffff3f71450d142000410c6a28020010290f0b200041106a28020041ffffff3f71450d132000410c6a28020010290f0b200041146a28020041ffffffff0371450d12200041106a28020010290f0b200041146a2802002201450d11200141246c450d11200041106a28020010290f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010290b200041186a1087020f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010290b200041186a1087020f0b20002802042201450d0e200041086a280200450d0e200110290f0b024020004194026a2802002202450d002000418c026a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b20004190026a2802002201450d0d2001410c6c450d0d200028028c0210290f0b02402000410c6a280200450d00200041086a28020010290b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b200041186a2802002201450d0c2001410c6c450d0c200028021410290f0b200041086a2d0000416d6a220141034b0d0b024002400240024020010e0400010203000b200041106a280200450d0e2000410c6a28020010290f0b200041106a280200450d0d2000410c6a28020010290f0b200041106a280200450d0c2000410c6a28020010290f0b200041106a280200450d0b2000410c6a28020010290f0b200041086a2d0000417f6a220141024b0d0a02400240024020010e03000102000b200041306a28020041ffffff3f71450d0c2000412c6a28020010290f0b2000410c6a220128020010cc01200128020010290f0b200041106a220128020010cc01200128020010290f0b200041086a2d0000417f6a220141024b0d0902400240024020010e03000102000b200041306a28020041ffffff3f71450d0b2000412c6a28020010290f0b2000410c6a220128020010cc01200128020010290f0b200041106a220128020010cc01200128020010290f0b200041086a2d00004101470d08200041106a28020041ffffff3f71450d082000410c6a28020010290f0b20002d00044104470d072000410c6a28020041ffffff3f71450d07200041086a28020010290f0b200041086a2d0000417c6a220141024b0d060240024020010e03000801000b200041306a280200450d072000412c6a28020010290f0b200041306a280200450d062000412c6a28020010290f0b02402000280204220141014b0d00024020010e020700070b0240200041106a2802002201450d00200041086a280200220320014190026c6a210403400240200341d0006a280200450d00200328024c10290b0240200341186a2802002202450d00200328021021012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b0240200341146a28020041ffffffff0071450d00200328021010290b0240200328021c2201450d00200341206a280200450d00200110290b0240200341fc016a2802002201450d00200141c1006c450d0020032802f80110290b20034190026a210120034188026a41003602002003280284022102200341013602840202402003418c026a280200450d00200210290b2001210320012004470d000b0b2000410c6a2802002201450d0620014190026c450d06200028020810290f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d052001410c6c450d05200028020c10290f0b200041086a2d000022014105490d04024020014105470d002000413c6a280200450d05200041386a28020010290f0b200041146a280200450d04200041106a28020010290f0b20002d0004417f6a220141034b0d030240024020010e0400050501000b0240200041106a280200450d002000410c6a28020010290b2000411c6a280200450d04200041186a28020010290f0b02402000410c6a280200450d00200041086a28020010290b200041186a280200450d03200041146a28020010290f0b0240200041086a2d0000220141034b0d00024020010e0404040400040b200041f0006a280200450d03200041ec006a28020010290f0b200041106a280200450d022000410c6a28020010290f0b024020002d0004220141044b0d00024002400240024020010e050600010203060b0240200041106a2802002202450d00200041086a2802002101200241a8026c21020340200110c201200141a8026a2101200241d87d6a22020d000b0b2000410c6a2802002201450d05200141a8026c450d05200028020810290f0b200041086a220128020010cc01200128020010290f0b02402000410c6a28020041ffffff3f71450d00200041086a28020010290b200041206a220128020010cc01200128020010290f0b2000412c6a28020041ffffff3f71450d02200041286a28020010290c020b2000412c6a28020041ffffff3f71450d01200041286a28020010290f0b0240200041086a2d0000220141034b0d000240024020010e0403000103030b2000410c6a220128020010cc01200128020010290f0b2000410c6a220128020010cc01200128020010290f0b2000412c6a220128020010cc01200128020010290f0b0bd50302047f047e230041f0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022040d00200041003a00000c010b200341186a28020021052003280214210641002101200341003a006802400240034020052001460d01200341c8006a20016a200420016a2d00003a00002003200141016a22023a00682002210120024120470d000b200341206a41186a200341c8006a41186a2903002207370300200341206a41106a200341c8006a41106a2903002208370300200341206a41086a200341c8006a41086a290300220937030020032003290348220a370320200041196a2007370000200041116a2008370000200041096a20093700002000200a370001410121010c010b0240200141ff0171450d00200341003a00680b4100210120034100360228200342013703202003410d3602442003200341086a3602402003200341206a36026c200341dc006a41013602002003420137024c200341f4eaca003602482003200341c0006a360258200341ec006a41a8a3c800200341c8006a10371a200335022842208620033502208410082003280224450d00200328022010290b200020013a00002006450d00200410290b200341f0006a24000bbe0201017f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d00200041003602000c010b200328021421022003200341106a41086a28020036022420032001360220200341c8006a200341206a1096020240024020032802480d0020034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b200041003602000c010b20002003290348370200200041086a200341c8006a41086a2802003602000b2002450d00200110290b200341e0006a24000be503010a7f230041106b22032400024020014105744104722204417f4c0d000240200410272205450d002003410036020820032004360204200320053602002001200310710240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020052104412010272201450d0220012000290000370000200141186a2209200041186a290000370000200141106a220a200041106a290000370000200141086a220b200041086a29000037000002400240200620046b4120490d00200441206a21050c010b024002400240200441206a22052004490d002006410174220c2005200c20054b1b220c4100480d000240024020060d000240200c0d00410121070c020b200c102721070c040b2006200c470d020b200c21060c030b1032000b20072006200c102b21070b200c210620070d001030000b200041206a2100200720046a22042001290000370000200441186a2009290000370000200441106a200a290000370000200441086a200b29000037000020011029200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100302402006450d00200710290b200341106a24000f0b1039000b1038000bd60202057f027e230041d0006b220224002002412036020420022001360200200241086a2001ad42808080808004841007108b0202400240200228020822010d00200042023703000c010b200228020c210302400240200241106a28020022044104490d0020044104460d0020012d0004220541014b0d0020012800002106420021070240024020050e020100010b2004417b6a4108490d0120012900052108420121070b20002008370308200041106a20063602000c010b20024100360220200242013703182002410d36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241f4eaca003602382002200241286a360248200241346a41a8a3c800200241386a10371a200235022042208620023502188410080240200228021c450d00200228021810290b420221070b200020073703002003450d00200110290b200241d0006a24000bcd0b030e7f047e087f230041a0046b220324002003200236021420032001360210200341186a2002ad4220862001ad841007108b0202400240200328021822040d00200041003602000c010b200328021c21052003200341206a280200220136022c2003200436022802400240024020014104490d0020032001417c6a36022c2003200441046a36022820042800002106200341086a200341286a10c80120032802080d00200328020c21072003410036024820034100360240200341c0006a41086a210802400240024002402007450d00200341d4016a2109200328022c210a200341b8016a210b4100210c034041002101200341003a00e001200c41016a210c024002400340200a2001460d01200341c0016a20016a2003280228220d2d00003a00002003200d41016a3602282003200141016a22023a00e0012002210120024120470d000b20034190016a41086a220e200341c0016a41086a29030037030020034190016a41106a220f200341c0016a41106a29030037030020034190016a41186a2210200341c0016a41186a290300370300200320032903c001370390012003200a20026b220136022c200141044f0d010c050b2003410036022c200141ff0171450d04200341003a00e001410021010c050b200341d0006a41086a200e2903002211370300200341d0006a41106a200f2903002212370300200341d0006a41186a20102903002213370300200320032903900122143703502003200d41056a36022820032001417c6a220a36022c200d2800012115200341f0006a41186a22162013370300200341f0006a41106a22172012370300200341f0006a41086a22182011370300200320143703700240024020032802402219450d002003280244211a0c010b200341c0016a410041e00210e6071a200b410036020020034190016a41206a2201420037030020104200370300200f4200370300200e4200370300200342003703900141940310272219450d034100211a201941003b010620194100360200201941086a200341c0016a41e00210e4071a20194190036a200b28020036020020194188036a200129030037020020194180036a2010290300370200201941f8026a200f290300370200201941f0026a200e29030037020020192003290390013702e80220034100360244200320193602400b024002400340201941086a210220192f0106221b41057421014100210d024003402001450d01200341f0006a2002412010e707221c450d03200141606a2101200d41016a210d200241206a2102201c417f4a0d000b200d417f6a211b0b0240201a450d00201a417f6a211a2019201b4102746a4194036a28020021190c010b0b201020162903002211370300200f20172903002212370300200e201829030022133703002003200329037022143703900120092014370200200941086a2013370200200941106a2012370200200941186a2011370200200320083602d0012003201b3602cc01200320193602c401200341003602c0012003200341c0006a3602c801200341c0016a201510d2011a0c010b2019200d4102746a41e8026a20153602000b200c2007470d000b0b410121010c020b1030000b410021010b200341306a41086a20082802002202360200200320032903402211370330200341c0016a41086a2002360200200320113703c00120010d01200341c0016a10d4010b41002101200341003602980120034201370390012003410d3602742003200341106a360270200320034190016a360250200341d4016a4101360200200342013702c401200341f4eaca003602c0012003200341f0006a3602d001200341d0006a41a8a3c800200341c0016a10371a200335029801422086200335029001841008200328029401450d0120032802900110290c010b20034190016a41086a200341c0016a41086a2802002201360200200320032903c00122113703900120002006360204200041086a2011370200200041106a2001360200410121010b200020013602002005450d00200410290b200341a0046a24000bed0701087f23004190046b2202240020002802102203200328020041016a360200200241086a2203200041086a29020037030020022000290200370300200241306a41186a2000412c6a290000370300200241306a41106a200041246a290000370300200241306a41086a2000411c6a29000037030020022000290014370330200241d0006a2002200241306a200110fe0402400240024020022d00504101470d002003200241d9006a290000370300200241106a200241e1006a290000370300200241186a200241e9006a29000037030020022002290051370300200241d0006a412c6a280200210120024188016a280200210420024184016a280200210320024180016a2802002105200228028c012106200241f8006a28020022002802002207450d0120002f01042108200241f4006a2802002109200241d0006a410172210003402002200841ffff037136022c20022001360228200220073602242002200941016a360220200241306a41186a200241186a2201290300370300200241306a41106a200241106a2207290300370300200241306a41086a200241086a220829030037030020022002290300370330200241d0006a200241206a200241306a20052003200410ff0420022d00504101470d032008200041086a2900003703002007200041106a2900003703002001200041186a29000037030020022000290000370300200228027c2101200228028801210420022802840121032002280280012105200228027822082802002207450d0220082f01042108200228027421090c000b0b200241d0006a41086a280200200241d0006a41106a2802004102746a41e8026a21060c010b200241d0006a410272410041be0310e6071a02400240024041c40310272200450d0020004100360200200041046a200241d0006a41c00310e4071a200020012802002207360294032001200036020020012001280204220841016a360204200741003b010420072000360200200241d0006a41186a200241186a290300370300200241d0006a41106a200241106a290300370300200241d0006a41086a200241086a2903003703002002200229030037035020082004470d0120002f01062201410a4b0d02200020014105746a220441206a200241d0006a41186a290300370000200441186a200241d0006a41106a290300370000200441106a200241d0006a41086a290300370000200441086a2002290350370000200020014102746a41e8026a20053602002000200141016a22014102746a4194036a2003360200200020013b0106200320013b0104200320003602000c030b1030000b41b69cc800413041b8a1cc001033000b418f9cc800412741b8a1cc001033000b20024190046a240020060bef0403057f027e027f230041c0006b22022400200041086a28020022032001107102400240024020002802002204450d00024020002802042205450d002005210020042106034020062802940321062000417f6a22000d000b200421000340200020002f01064102746a4194036a28020021002005417f6a22050d000b200241186a2105200621040c020b200241186a2105200421000c010b410021042002410036021c200241186a21050c010b2002200036021c200241246a20002f010636020020024100360220200241003602180b200241086a41086a200541086a2902002207370300200220052902002208370308200241306a2007370300200242003703202002200436021c20024100360218200220083703282002200336023802402003450d00034020022003417f6a360238200241186a410020041b2206280200210020062802082109024002400240200628020c2205200628020422032f01064f0d00200321040c010b0240034020032802002204450d01200041016a210020032f0104210520042103200520042f0106490d020c000b0b2009ad2107410021040c010b2005ad4220862009ad8421070b2007422088a7220941016a21052007a7210a0240024020000d00200421030c010b200420054102746a4194036a2802002103410021052000417f6a2200450d00034020032802940321032000417f6a22000d000b0b2006200536020c2006200a36020820062003360204200641003602002001200420094105746a41086a412010722002200420094102746a41e8026a28020036023c20012002413c6a4104107220022802382203450d01200228021c21040c000b0b200241c0006a24000bb50201047f024020002802002201450d0020002802082102024020002802042200450d00034020012802940321012000417f6a22000d000b0b02402002450d004100210303400240024002402001450d002002417f6a2102200320012f0106490d0141002104034002400240200128020022000d0041002103410021000c010b200441016a210420012f010421030b2001102920002101200320002f01064f0d000b200341016a2103024020040d00200021010c030b200020034102746a4194036a2802002101410021032004417f6a2200450d02034020012802940321012000417f6a22000d000c030b0b41a79dc800412b41e0f6c4001033000b200341016a21030b20020d000b0b2001450d0020012802002100200110292000450d00034020002802002101200010292001210020010d000b0b0ba20703027f017e067f230041e0006b2203240041eebec500ad4280808080f00084100122042900002105200341086a41086a200441086a2900003703002003200537030820041029419db8c000ad4280808080b00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041029200320013602382003200341386aad4280808080c000841002220429000037034820041029200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a10750240024002400240412010272204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410022202290000370348200210292001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a1075200410292003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210272204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001102722040d010c050b200b2001460d002004200b2001102b2204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b102b2204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b2001102b2204450d040b200441206a200a200710e4071a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10272204450d050c010b2001200b460d0020042001200b102b2204450d040b200420066a2009200810e4071a200020023602082000200b360204200020043602000240200328023c450d00200910290b0240200328022c450d00200a10290b200341e0006a24000f0b1039000b1038000b1032000b1030000ba20703027f017e067f230041e0006b2203240041eebec500ad4280808080f00084100122042900002105200341086a41086a200441086a2900003703002003200537030820041029418ab8c000ad4280808080b00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041029200320013602382003200341386aad4280808080c000841002220429000037034820041029200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a10750240024002400240412010272204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410022202290000370348200210292001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a1075200410292003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210272204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001102722040d010c050b200b2001460d002004200b2001102b2204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b102b2204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b2001102b2204450d040b200441206a200a200710e4071a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10272204450d050c010b2001200b460d0020042001200b102b2204450d040b200420066a2009200810e4071a200020023602082000200b360204200020043602000240200328023c450d00200910290b0240200328022c450d00200a10290b200341e0006a24000f0b1039000b1038000b1032000b1030000ba20703027f017e067f230041e0006b2203240041eebec500ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004102941ffb7c000ad4280808080b00184100122042900002105200341186a41086a200441086a2900003703002003200537031820041029200320013602382003200341386aad4280808080c000841002220429000037034820041029200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a10750240024002400240412010272204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410022202290000370348200210292001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a1075200410292003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210272204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001102722040d010c050b200b2001460d002004200b2001102b2204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b102b2204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b2001102b2204450d040b200441206a200a200710e4071a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10272204450d050c010b2001200b460d0020042001200b102b2204450d040b200420066a2009200810e4071a200020023602082000200b360204200020043602000240200328023c450d00200910290b0240200328022c450d00200a10290b200341e0006a24000f0b1039000b1038000b1032000b1030000bb10503027f017e047f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941e9b7c000ad4280808080e00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000bb10503027f017e047f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941f5b7c000ad4280808080a00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000bfc0403027f017e057f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941b8f6c100ad4280808080d00284100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bc20503027f017e047f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a200341086a290000370300200220043703002003102941efb7c000ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100522012900002104200241306a41086a200141086a2900003703002002200437033020011029200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a1075200310292002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a20002001360208200020083602042000200336020002402002280224450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000bb10503027f017e047f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941b0b8c000ad4280808080d00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000bda0503027f017e047f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941bdb8c000ad4280808080900184100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240410410272203450d00200341044120102b2203450d0320032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200128022021052003412041c000102b2201450d032001200536002020022001ad4280808080c004841002220329000037033820031029200241cc006a200141246a360200200220013602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200110292002280230220641206a2203417f4c0d01200228022821070240024020030d0041002105410121010c010b200310272201450d01200321050b024002402005410f4d0d00200521080c010b200541017422084110200841104b1b22084100480d03024020050d002008102722010d010c050b20052008460d00200120052008102b2201450d040b20012002290308370000200141086a200241086a41086a2903003700000240024020084170714110460d00200821050c010b200841017422054120200541204b1b22054100480d0320082005460d00200120082005102b2201450d040b20012002290318370010200141186a200241186a41086a29030037000002400240200541606a2006490d00200521080c010b2006415f4b0d03200541017422082003200820034b1b22084100480d0320052008460d00200120052008102b2201450d040b200141206a2007200610e4071a2000200336020820002008360204200020013602000240200228022c450d00200710290b200241d0006a24000f0b1039000b1038000b1032000b1030000bb10503027f017e047f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941b8dcc900ad4280808080a00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000b890603027f017e047f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241186a41086a200341086a290000370300200220043703182003102941b0b8c000ad4280808080d00184100122032900002104200241286a41086a200341086a2900003703002002200437032820031029200128020021010240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad428080808080048410022201290000370348200110292002410c6a200341206a360200200220033602082002200241c8006a41086a3602042002200241c8006a360200200241386a20021075200310292002280240220541206a2201417f4c0d01200228023821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290318370000200341086a200241186a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290328370010200341186a200241286a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a0240200228023c450d00200610290b20022003200110e001200241286a41086a2207200241086a280200360200200220022903003703280240200228020c2201450d002000200229032837020020002002290310370210200041086a20072802003602000b2000200136020c02402008450d00200310290b200241d0006a24000f0b1039000b1038000b1032000b1030000ba20503067f017e027f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d002000410036020c0c010b200328021421042003200341186a2802002202360224200320013602200240024020024104490d002003200141046a36022020032002417c6a220536022420054104490d00200128000021062003200141086a3602202003200241786a220536022420054104490d00200128000421052003200241746a36022420032001410c6a360220200128000821072003200341206a10c80120032802000d002003280224220820032802044102742202490d0002400240024002402002417f4c0d000240024020020d00420021094101210a0c010b2002102d220a450d02200a2003280220220b200210e4071a2003200820026b3602242003200b20026a3602202002ad21090b200a450d04024020092002ad422086842209422088a722020d002009a721020c030b0240200a2002724103710d002009a722024103710d0020024102762208450d032009422288a7210b0c040b2009a7450d04200a10290c040b1038000b1039000b4100210b02402002450d00200a10290b410021084104210a0b41000d00200a450d00200020083602102000200a36020c200020073602082000200536020420002006360200200041146a200b3602000c010b20034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b2000410036020c0b2004450d00200110290b200341e0006a24000bda0b04047f017e027f027e23004190026b2201240020014180026a200010d801200141d8006a200128028002220020012802880210cd01200141e0016a41086a2202200141e1006a290000370300200141e0016a41106a2203200141e9006a290000370300200141e0016a41186a2204200141f1006a290000370300200120012900593703e0010240024002400240024002400240024020012d00584101470d00200141386a41186a2004290300370300200141386a41106a2003290300370300200141386a41086a2002290300370300200120012903e0013703380240200128028402450d00200010290b200141d8006a41186a2202200141386a41186a290300370300200141d8006a41106a2203200141386a41106a290300370300200141d8006a41086a2204200141386a41086a2903003703002001200129033837035841eebec500ad4280808080f00084100122002900002105200141b0016a41086a200041086a290000370300200120053703b0012000102941efb7c000ad4280808080e00084100122002900002105200141c0016a41086a200041086a290000370300200120053703c00120001029412010272200450d0420002001290358370000200041186a2002290300370000200041106a2003290300370000200041086a20042903003700002000ad428080808080048410052202290000210520014180026a41086a200241086a290000370300200120053703800220021029200141ec016a200041206a360200200120003602e801200120014180026a41106a3602e401200120014180026a3602e001200141d0016a200141e0016a10752000102920012802d801220641206a2202417f4c0d0520012802d00121070240024020020d0041002103410121000c010b200210272200450d05200221030b024002402003410f4d0d00200321040c010b200341017422044110200441104b1b22044100480d07024020030d002004102722000d010c090b20032004460d00200020032004102b2200450d080b200020012903b001370000200041086a200141b0016a41086a2903003700000240024020044170714110460d00200421030c010b200441017422034120200341204b1b22034100480d0720042003460d00200020042003102b2200450d080b200020012903c001370010200041186a200141c0016a41086a29030037000002400240200341606a2006490d00200321040c010b2006415f4b0d07200341017422042002200420024b1b22044100480d0720032004460d00200020032004102b2200450d080b200041206a2007200610e4071a024020012802d401450d00200710290b200141d8006a2000200210e20120012802782203450d01200141f0006a290300210820014188016a280200210620014184016a280200210720012903682109200128027c210202402004450d00200010290b02402002450d00200241186c450d00200310290b200641ffffffff0371450d03200710290c030b200128028402450d01200010290c010b2004450d00200010290b42002109420021080b200141d8006a41186a4200370300200141d8006a41106a22034200370300200141d8006a41086a220042003703002001420037035841dcbec500ad42808080808001841001220229000021052000200241086a2900003703002001200537035820021029419fe3c200ad4280808080d00184100122022900002105200141386a41086a2204200241086a2900003703002001200537033820021029200320012903382205370300200141e0016a41086a2000290300370300200141e0016a41106a2005370300200141e0016a41186a2004290300370300200120012903583703e001200141206a200141e0016a412010e301200141106a2001290328200141206a41106a290300427f420010e00720012009200820012903104200200128022022001b220542012005420156200141106a41086a290300420020001b22054200522005501b22001b2005420020001b10e0072001290300210520014190026a240020050f0b1039000b1038000b1032000b1030000b970b06047f057e027f017e027f027e230041f0016b220324002003200236026420032001360260200341e8006a2002ad4220862001ad841007108b02024002400240200328026822040d00200041003602200c010b200328026c21052003200341f0006a280200220636029c01200320043602980141002101200341003a00e8010240024002400240034020062001460d01200341c8016a20016a200420016a22022d00003a00002003200241016a360298012003200141016a22023a00e8012002210120024120470d000b200341a8016a41086a200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200341a8016a41186a200341c8016a41186a290300370300200320032903c8013703a8012003200620026b36029c01200341c8006a20034198016a1084022003290348a70d02200341c8006a41106a290300210720032903502108200341306a20034198016a1084022003290330a70d02200341306a41106a29030021092003290338210a200341286a20034198016a10c80120032802280d02200328022c2206200328029c0141186e2201200120064b1bad42187e220b422088a7450d010c050b2003410036029c01200141ff0171450d01200341003a00e8010c010b200ba72202417f4c0d03024002400240024002400240024020020d004108210c0c010b20021027220c450d010b41002101200341003602d0012003200c3602c8012003200241186e22023602cc0102400240024002402006450d0041002101200341206a210d0340200341106a20034198016a1084022003290310a70d02200d290300210b2003290318210e200341086a20034198016a10c80120032802080d02200328020c210f0240200120032802cc01470d00200341c8016a20014101108f0120032802c801210c20032802d00121010b200c200141186c6a2202200f3602102002200b3703082002200e3703002003200141016a22013602d0012006417f6a22060d000b20032802cc0121020b200c450d08200320034198016a10c80120032802000d06200328029c01220d20032802044102742206490d062006417f4c0d0b20060d014200210b4101210f0c020b20032802cc012201450d07200141186c0d060c070b2006102d220f450d01200f2003280298012210200610e4071a2003200d20066b36029c012003201020066a360298012006ad210b0b200f450d030240200b2006ad42208684220b422088a722060d00200ba721060c020b0240200f2006724103710d00200ba722064103710d002006410276220d450d02200b422288a721100c030b200ba7450d03200f10290c030b1039000b4100211002402006450d00200f10290b4100210d4104210f0b41000d00200f450d00200341f8006a41186a200341a8016a41186a290300220b370300200341f8006a41106a200341a8016a41106a290300220e370300200341f8006a41086a200341a8016a41086a2903002211370300200320032903a8012212370378200041186a20093703002000200a3703102000200737030820002008370300200041346a2010360200200041306a200d3602002000412c6a200f360200200041286a2001360200200020023602242000200c360220200041386a2012370300200041c0006a2011370300200041c8006a200e370300200041d0006a200b3703000c030b2002450d01200241186c450d010b200c10290b200341003602b001200342013703a8012003410d36027c2003200341e0006a3602782003200341a8016a3602a401200341dc016a4101360200200342013702cc01200341f4eaca003602c8012003200341f8006a3602d801200341a4016a41a8a3c800200341c8016a10371a20033502b00142208620033502a801841008024020032802ac01450d0020032802a80110290b200041003602200b2005450d00200410290b200341f0016a24000f0b1038000ba80202017f037e230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad841007108b0202400240200328020822010d00420021040c010b200328020c210202400240200341086a41086a2802004110490d00200141086a290000210520012900002106420121040c010b20034100360220200342013703182003410d36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341f4eaca003602382003200341286a360248200341346a41a8a3c800200341386a10371a200335022042208620033502188410080240200328021c450d00200328021810290b420021040b2002450d00200110290b2000200637030820002004370300200041106a2005370300200341d0006a24000bd80301067f230041106b2202240020024100360208200242013703000240412010272203450d0020032000290038370000200341086a200041c0006a290000370000200341106a200041c8006a290000370000200341186a200041d0006a29000037000020022003360200200242a080808080043702042002200036020c2002410c6a200210e5012002200041106a36020c2002410c6a200210e50120002802202103200041286a28020022042002107102402004450d002003200441186c6a210403402002200336020c2002410c6a200210e501200341106a200210e6012004200341186a2203470d000b0b200028022c2105200041346a28020022032002107102400240024020022802042206200228020822046b20034102742200490d0020022802002103200621070c010b200420006a22032004490d01200641017422072003200720034b1b22074100480d010240024020060d00024020070d00410121030c020b2007102722030d010c040b2002280200210320062007460d00200320062007102b2203450d030b20022007360204200220033602000b200320046a2005200010e4071a2001290200200420006aad4220862003ad84100302402007450d00200310290b200241106a24000f0b1032000b1030000ba50403017f027e027f230041e0006b220224000240024020002802002200290300220342c000544100200041086a29030022045022051b0d0002400240024020034280800154410020051b0d00200342808080800454410020051b0d01411020047920037942c0007c20044200521ba741037622056b4104490d022002413320054102746b3a00482001200241c8006a41011072200029030021032002200041086a290300220437030820022003370300200541706a21000340200220033c00482001200241c8006a410110722003420888200442388684210320044208882104200041016a22052000492106200521002006450d000b20022003370300200220043703082003200484500d04200241286a41146a4109360200200241346a410e360200200241106a41146a410336020020022002360240200241d0f8ca00360244200241c8006a41146a410036020020024203370214200241aca5cc003602102002410e36022c20024180a6cc003602582002420137024c20024188f8ca003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a4180a6cc001040000b20022003a74102744101723b01482001200241c8006a410210720c030b20022003a74102744102723602482001200241c8006a410410720c020b41c4f7ca00413641b8a1cc001033000b20022003a74102743a00482001200241c8006a410110720b200241e0006a24000bb30101027f230041106b2202240002400240024002402000280200220341c000490d00200341808001490d012003418080808004490d02200241033a00032001200241036a41011072200220002802003602042001200241046a410410720c030b200220034102743a00032001200241036a410110720c020b200220034102744101723b010a20012002410a6a410210720c010b2002200341027441027236020c20012002410c6a410410720b200241106a24000b130020004118360204200041a0c9c0003602000bab0407047f017e017f017e017f017e037f230041d0006b22002400200041206a41186a22014200370300200041206a41106a22024200370300200041206a41086a220342003703002000420037032041eebec500ad4280808080f000842204100122052900002106200041c0006a41086a2207200541086a290000370300200020063703402005102920032007290300370300200020002903403703204180fac100ad428080808080018422081001220529000021062007200541086a2900003703002000200637034020051029200220002903402206370300200041086a22092003290300370300200041106a220a2006370300200041186a220b2007290300370300200020002903203703000240024002404100200010b3012205200541ff01714104461b41ff0171417f6a220541024b0d0020050e03010001010b2001420037030020024200370300200342003703002000420037032020041001220529000021062007200541086a2900003703002000200637034020051029200320072903003703002000200029034037032020081001220529000021062007200541086a290000370300200020063703402005102920022000290340370000200241086a200729030037000020092003290300370300200a2002290300370300200b200129030037030020002000290320370300410110272207450d01200741013a00002000ad42808080808004842007ad428080808010841003200710290b200041d0006a24000f0b1030000b3400200041eebec50036020420004100360200200041146a4124360200200041106a41e8d9c100360200200041086a42073702000b2b01017f02404101102722020d001030000b200042818080801037020420002002360200200241023a00000b2b01017f02404101102722020d001030000b200042818080801037020420002002360200200241003a00000b5301017f0240411010272202450d002002420037000820024200370000200241104120102b2202450d0020024200370010200042a0808080800437020420002002360200200241186a42003700000f0b1030000b940302047f017e230041206b2203240002400240200241d8006c4104722204417f4c0d00200410272205450d0120034100360208200320043602042003200536020020022003107102402002450d002001200241d8006c6a210603402003200141386a41201072200129030021072003200141086a290300370318200320073703102003200341106a4110107220012802202102200128022822042003107102402004450d002002200441306c6a210403402003200241201072200241206a29030021072003200241286a290300370318200320073703102003200341106a411010722004200241306a2202470d000b0b200141d8006a2105200128022c2102200141346a28020022042003107102402004450d002004410574210403402003200241201072200241206a2102200441606a22040d000b0b200129031021072003200141186a290300370318200320073703102003200341106a411010722005210120052006470d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1038000b1039000b3301017f02404110102722020d001039000b2002420037000820024200370000200042908080808002370204200020023602000b860101027f230041206b220224002002410c6a410036020020024200370300200241003602182002420137031002404104102722030d001030000b200341003600002002200336021020024284808080c00037021420024104722203200241106a10d301200041086a200228021836020020002002290310370200200310d401200241206a24000be90101047f230041106b220224002002410036020c02400240410110272203450d000240024002400240200228020c220441c000490d00200441808001490d012004418080808004490d02200341033a0000200228020c210441052105200341014105102b2203450d05200320043600010c030b200320044102743a0000410121050c020b41022105200341014102102b2203450d03200320044102744101723b00000c010b41042105200341014104102b2203450d02200320044102744102723600000b200020053602082000200536020420002003360200200241106a24000f0b1039000b1030000bf60301087f230041c0006b22022400200241186a4200370300200241106a22034200370300200241086a4200370300200241286a22044100360200200242003703002002420837032020024100360238200242013703302002200236023c2002413c6a200241306a10e5012002200336023c2002413c6a200241306a10e5012002280220210320042802002204200241306a10710240024002402004450d00200441306c210503400240024020022802342206200228023822046b4120490d00200441206a2107200228023021080c010b200441206a22072004490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009102722080d010c060b2002280230210820062009460d00200820062009102b2208450d050b20022009360234200220083602300b200820046a2204200341106a290000370000200441186a200341286a290000370000200441106a200341206a290000370000200441086a200341186a290000370000200220073602382002200336023c2002413c6a200241306a10e501200341306a2103200541506a22050d000b0b20002002290330370200200041086a200241306a41086a280200360200024020022802242203450d00200341306c450d00200228022010290b200241c0006a24000f0b1032000b1030000b2c01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241043600000b2d01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241d4003600000b130020004102360204200041d0a2c2003602000b2c01017f02404104102722020d001039000b20004284808080c000370204200020023602002002411c3600000b2c01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241063600000bb53310047f017e017f017e017f017e057f017e0b7f017e017f017e0a7f017e017f077e230041a0036b22012400200141a0026a41186a22024200370300200141a0026a41106a22034200370300200141a0026a41086a22044200370300200142003703a00241eebec500ad4280808080f000842205100122062900002107200141c8006a41086a2208200641086a290000370300200120073703482006102920042008290300370300200120012903483703a00241f0f5c100ad428080808090018422071001220629000021092008200641086a2900003703002001200937034820061029200320012903482209370300200141a0016a41086a220a2004290300370300200141a0016a41106a220b2009370300200141a0016a41186a220c2008290300370300200120012903a0023703a001200141a0026a200141a0016a10d0012003280200210d20012903a0022109200242003703002003420037030020044200370300200142003703a00220051001220629000021052008200641086a290000370300200120053703482006102920042008290300370300200120012903483703a00220071001220629000021052008200641086a2900003703002001200537034820061029200320012903482205370300200a2004290300370300200b2005370300200c2008290300370300200120012903a0023703a00102400240410410272208450d0020084100200d41016a20094202511b220e360000200841044108102b2208450d0041002102200841003a0004200141a0016aad220f42808080808004842008ad4280808080d00084100320081029200141a0026a41186a220a4200370300200141a0026a41106a220b4200370300200141a0026a41086a22044200370300200142003703a00241eebec500ad4280808080f00084100122062900002105200141c8006a41086a2208200641086a290000370300200120053703482006102920042008290300370300200120012903483703a00241f0fbc100ad4280808080a001841001220629000021052008200641086a290000370300200120053703482006102920032001290348370000200341086a2008290300370000200141a0016a41086a2004290300370300200141a0016a41106a200b290300370300200141a0016a41186a200a290300370300200120012903a0023703a00120014180016a200141a0016a10f80102400240024020012802800122100d002001410036028002200142043703f8010c010b2001290284012105200120103602f801200120053702fc012005422088a722082005a72202470d010b200141f8016a20024101108d0120012802f801211020012802800221080b201020084103746a220420003602042004200e3602002001200841016a2211360280020240024002400240200e411d4f0d00201121120c010b024020110d004100211220014100360280020c010b200e41646a2104200841ffffffff017141016a2106410021132010210802400340200828020020044f0d01200841086a21082006201341016a2213470d000b0b0240024020112013490d004100211220014100360280022013450d012013410374211420014198026aad4280808080c0008421052001419c026a211520014188026a41086a21162010210c0340200c280200210d41eebec500ad4280808080f00084220710012208290000210920014180016a41086a2200200841086a290000370300200120093703800120081029418ab8c000ad4280808080b00284100122082900002109200141c8006a41086a220a200841086a29000037030020012009370348200810292001200d3602980220012005100222082900003703880220081029200120153602ac02200120163602a402200120014198026a3602a802200120014188026a3602a002200141a0016a200141a0026a107520012802a801220b41206a2204417f4c0d0720012802a00121170240024020040d0041002106410121080c010b200410272208450d06200421060b024002402006410f4d0d00200621020c010b200641017422024110200241104b1b22024100480d05024020060d002002102722080d010c080b20062002460d00200820062002102b2208450d070b2008200129038001370000200841086a20002903003700000240024020024170714110460d00200221060c010b200241017422064120200641204b1b22064100480d0520022006460d00200820022006102b2208450d070b20082001290348370010200841186a200a29030037000002400240200641606a200b490d00200621020c010b2004200b490d05200641017422022004200220044b1b22024100480d0520062002460d00200820062002102b2208450d070b200841206a2017200b10e4071a024020012802a401450d00201710290b2004ad4220862008ad84100602402002450d00200810290b20071001220829000021072000200841086a290000370300200120073703800120081029419db8c000ad4280808080b00284100122082900002107200a200841086a29000037030020012007370348200810292001200d3602980220012005100222082900003703880220081029200120153602ac02200120163602a402200120014198026a3602a802200120014188026a3602a002200141a0016a200141a0026a107520012802a801220b41206a2204417f4c0d0720012802a001210d0240024020040d0041002106410121080c010b200410272208450d06200421060b024002402006410f4d0d00200621020c010b200641017422024110200241104b1b22024100480d05024020060d00200210272208450d080c010b20062002460d00200820062002102b2208450d070b2008200129038001370000200841086a20002903003700000240024020024170714110460d00200221060c010b200241017422064120200641204b1b22064100480d0520022006460d00200820022006102b2208450d070b20082001290348370010200841186a200a29030037000002400240200641606a200b490d00200621020c010b200b415f4b0d05200641017422022004200220044b1b22024100480d0520062002460d00200820062002102b2208450d070b200841206a200d200b10e4071a024020012802a401450d00200d10290b2004ad4220862008ad84100602402002450d00200810290b200c41086a210c201441786a22140d000c020b0b201320111044000b201120136b2202450d0002402013450d002010201020134103746a200241037410e5071a0b20012002360280022010280204210a200141a0026a41186a4200370300200141a0026a41106a22004200370300200141a0026a41086a22084200370300200142003703a00241b1dcc900ad4280808080f0008410012204290000210520014180016a41086a2206200441086a2900003703002001200537038001200410292008200629030037030020012001290380013703a00241a7adc000ad4280808080b00184100122042900002105200141c8006a41086a2206200441086a2900003703002001200537034820041029200020012903482205370300200141a0016a41086a2008290300370300200141a0016a41106a2005370300200141a0016a41186a2006290300370300200120012903a0023703a001200141a0026a200141a0016a412010f9014101210420012902a40221050240024020012802a00222084101460d00200841014621040c010b2005422088a7220b200a200a200b4b1b22062005a72208490d000240200620084d0d000340200141a0026a200810fa0120013502a80242208620012802a0022204ad841004200841016a2108024020012802a402450d00200410290b20062008470d000b0b200a200b4921042005428080808070832006ad8421050b2001200537028c0220012004360288020240024020040d00200141a0026a41186a22064200370300200141a0026a41106a220a4200370300200141a0026a41086a22084200370300200142003703a00241b1dcc900ad4280808080f0008410012204290000210520014180016a41086a220b200441086a2900003703002001200537038001200410292008200b29030037030020012001290380013703a00241a7adc000ad4280808080b00184100122042900002105200141c8006a41086a220b200441086a290000370300200120053703482004102920002001290348370000200041086a200b290300370000200141a0016a41086a2008290300370300200141a0016a41106a200a290300370300200141a0016a41186a2006290300370300200120012903a0023703a001200f428080808080048410040c010b200141a0026a41186a22064200370300200141a0026a41106a220a4200370300200141a0026a41086a22084200370300200142003703a00241b1dcc900ad4280808080f0008410012204290000210520014180016a41086a220b200441086a2900003703002001200537038001200410292008200b29030037030020012001290380013703a00241a7adc000ad4280808080b00184100122042900002105200141c8006a41086a220b200441086a290000370300200120053703482004102920002001290348370000200041086a200b290300370000200141a0016a41086a2008290300370300200141a0016a41106a200a290300370300200141a0016a41186a2006290300370300200120012903a0023703a001200141203602a4022001200141a0016a3602a00220014188026a410472200141a0026a10fb010b200221120b20012802fc012115200141a0026a41186a22024200370300200141a0026a41106a22004200370300200141a0026a41086a22044200370300200142003703a00241eebec500ad4280808080f00084100122062900002105200141c8006a41086a2208200641086a290000370300200120053703482006102920042008290300370300200120012903483703a00241f0fbc100ad4280808080a001841001220629000021052008200641086a290000370300200120053703482006102920032001290348370000200341086a2008290300370000200141a0016a41086a2004290300370300200141a0016a41106a2000290300370300200141a0016a41186a2002290300370300200120012903a0023703a0010240024020100d00200f428080808080048410040c010b20124103744104722208417f4c0d04200810272204450d02200141003602a802200120083602a402200120043602a0022012200141a0026a10710240024020120d0020012802a802210820012802a00221020c010b201020124103746a2114410020012802a802220b6b210020012802a4022104410021080340200b20086a210a201020086a220c280200210d02400240200420006a4104490d0020012802a0022102200421060c010b200a41046a2206200a490d04200441017422022006200220064b1b22064100480d040240024020040d00024020060d00410121020c020b200610272202450d080c010b20012802a002210220042006460d00200220042006102b2202450d070b200120063602a402200120023602a0020b2002200b6a20086a200d3600002001200a41046a22043602a802200c41046a280200210d02400240200620006a417c6a41034d0d00200621040c010b200441046a22172004490d04200641017422042017200420174b1b22044100480d040240024020060d00024020040d00410121020c020b200410272202450d080c010b20062004460d00200220062004102b2202450d070b200120043602a402200120023602a0020b2002200b6a20086a41046a200d3600002001200a41086a3602a802200041786a2100200841086a2108200c41086a2014470d000b200b20086a21080b20012802a4022104200f42808080808004842008ad4220862002ad84100302402004450d00200210290b201541ffffffff0171450d00201010290b200141a0026a41186a22184200370300200141a0026a41106a22194200370300200141a0026a41086a221a4200370300200142003703a00241eebec500ad4280808080f00084221b100122082900002105200141c8006a41086a221c200841086a2900003703002001200537034820081029201a201c290300370300200120012903483703a00241b0fec100ad4280808080e00284221d100122082900002105201c200841086a290000370300200120053703482008102920032001290348370000200341086a221e201c290300370000200141a0016a41086a221f201a290300370300200141a0016a41106a22202019290300370300200141a0016a41186a22212018290300370300200120012903a0023703a001200141c0006a200141a0016a412010fc01200128024421220240200128024022234101470d00024020224100200e41646a22082008200e4b1b22244f0d00200141d8016a2125200141a0016a41246a2100200141a0026a41286a2117202221260340200141a0016a202610fd01200141a0026a20012802a001220820012802a801220410fe010240024020012802a00222270d0042002128410821270c010b2004ad4220862008ad84100420012902a40221280b024020012802a401450d00200810290b20272028422088a7220841d8006c6a210b2027210202402008450d000340200141a0016a41186a2208200241186a290300370300200141a0016a41106a2204200241106a290300370300200141a0016a41086a2206200241086a2903003703002002280220210a20022903002105200141a0026a41206a220d200241c4006a2902003703002017200241cc006a290200370300200141a0026a41306a2210200241d4006a280200360200200141a0026a41086a22142002412c6a290200370300200141a0026a41106a2215200241346a290200370300200141a0026a41186a220c2002413c6a290200370300200120053703a0012001200241246a2902003703a002200241d8006a2102200a450d0120014180016a41186a2216200829030037030020014180016a41106a2213200429030037030020014180016a41086a220e2006290300370300200141c8006a41086a22122014290300370300200141c8006a41106a22142015290300370300200141c8006a41186a2215200c290300370300200141c8006a41206a2211200d290300370300200141c8006a41286a220d2017290300370300200141c8006a41306a22292010280200360200200120012903a00137038001200120012903a00237034820082016290300370300200420132903003703002006200e29030037030020002001290348370200200041086a2012290300370200200041106a2014290300370200200041186a2015290300370200200041206a2011290300370200200041286a200d290300370200200041306a202928020036020020012001290380013703a0012001200a3602c0012001420037038002200142003703f80120012008290300370390022001200429030037038802202520012903a001200629030020014188026a200141f8016a10ff01024020012802c8012208450d00200841306c2104200a210803402008200841206a290300200841286a29030020014188026a200141f8016a10ff01200841306a2108200441506a22040d000b0b200141f8016a41086a290300212a20012903f801212b20012802cc01210d02400240200129038802220720014188026a41086a290300220584500d0020012802d4012208450d00200141306a202b2007202b200754202a200554202a2005511b22041b222c202a200520041b222d2008ad420010e00720084105742104200141306a41086a29030021092001290330212e202c2105202d2107200d210803402008202e20052005202e56200720095620072009511b22061b222f2009200720061b2230108002200720307d2005202f54ad7d21072005202f7d2105200841206a2108200441606a22040d000b200141186a427f202b202c7d220920057c220520052009542208202a202d7d202b202c54ad7d220520077c2008ad7c220720055420072005511b22081b427f200720081b1081022001290318a7450d01200141186a41106a290300210520012903202107200142f0f2bda1a7ee9cb9f90037039802200141a0026a20014198026a108202200141a0026a20072005108002200c2005370300200120073703b002200141063a00a8022001410e3a00a002200141a0026a10cb010c010b2001202b202a1081022001290300a7450d00200141106a290300210520012903082107200142f0f2bda1a7ee9cb9f90037039802200141a0026a20014198026a108202200141a0026a20072005108002200c2005370300200120073703b002200141063a00a8022001410e3a00a002200141a0026a10cb010b024020012802c4012208450d00200841306c450d00200a10290b024020012802d00141ffffff3f71450d00200d10290b2002200b470d000b200b21020b2028a721040240200b2002460d0003400240200241246a2802002208450d00200841306c450d00200241206a28020010290b200241d8006a21080240200241306a28020041ffffff3f71450d002002412c6a28020010290b20082102200b2008470d000b0b202641016a212602402004450d00200441d8006c450d00202710290b20262024470d000b0b20222024202220244b1b21220b2018420037030020194200370300201a4200370300200142003703a002201b100122082900002105201c200841086a2900003703002001200537034820081029201a201c290300370300200120012903483703a002201d100122082900002105201c200841086a290000370300200120053703482008102920032001290348370000201e201c290300370000201f201a2903003703002020201929030037030020212018290300370300200120012903a0023703a0010240024020230d00200f428080808080048410040c010b200120223602a002200f4280808080800484200141a0026aad4280808080c0008410030b200141a0036a24000f0b1032000b1039000b1030000b1038000bed0401097f230041e0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b020240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c8010240024020022802000d0020022802042205200228022422064103762201200120054b1b22014103742207417f4c0d030240024020010d00410421080c010b200710272208450d050b200241003602502002200136024c200220083602480240024002402005450d004100210103402002410036022820064104490d0320022002280220220741046a36022020072800002109200241003602282006417c6a4104490d022002200741086a3602202007280004210702402001200228024c470d00200241c8006a20014101108d0120022802482108200228025021010b200641786a2106200820014103746a220a2007360204200a20093602002002200141016a22013602502005417f6a22050d000b200220063602240b2008450d022000200229024c370204200020083602000c030b2006417c6a21060b20022006360224200228024c41ffffffff0171450d00200810290b20024100360230200242013703282002410d36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241f4eaca003602482002200241386a360258200241c4006a41a8a3c800200241c8006a10371a200235023042208620023502288410080240200228022c450d00200228022810290b200041003602000b2004450d00200310290b200241e0006a24000f0b1038000b1039000bbb0201037f230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad841007108b0202400240200328020822010d00200041003602000c010b200341106a2802002102200328020c2104200341003602380240024020024104490d0020012800002105200341003602382002417c714104460d00200041086a200128000436020020002005360204410121020c010b20034100360220200342013703182003410d36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341f4eaca003602382003200341286a360248200341346a41a8a3c800200341386a10371a200335022042208620033502188410080240200328021c450d00200328021810290b410021020b200020023602002004450d00200110290b200341d0006a24000bfc0403027f017e057f230041d0006b2202240041b1dcc900ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941f5a7c800ad4280808080a00284100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000b3c01017f02404108102722020d001039000b200220002802003600002002200028020436000420012902002002ad42808080808001841003200210290b8f0201037f230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad841007108b0202400240200328020822040d00410021010c010b200328020c210502400240200341106a2802004104490d0020042800002102410121010c010b4100210120034100360220200342013703182003410d36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341f4eaca003602382003200341286a360248200341346a41a8a3c800200341386a10371a200335022042208620033502188410080240200328021c450d00200328021810290b0b2005450d00200410290b2000200236020420002001360200200341d0006a24000bfc0403027f017e057f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a41086a200341086a29000037030020022004370308200310294198fbc100ad4280808080800284100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000b800b06057f017e077f017e037f037e230041e0016b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b020240024002400240200328021022040d00200041003602000c010b200328021421052003200341186a280200360224200320043602202003200341206a10c80102400240024020032802000d00200328020422062003280224220741d8006e2201200120064b1bad42d8007e2208422088a70d042008a72201417f4c0d040240024020010d00410821090c010b200110272209450d060b4100210a20034100360230200320093602282003200141d8006e36022c02402006450d004100210b034041002101200341003a00d801200b41016a210b02400240024002400240034020072001460d01200341b8016a20016a2003280220220c2d00003a00002003200c41016a3602202003200141016a22023a00d8012002210120024120470d000b20034198016a41086a220d200341b8016a41086a29030037030020034198016a41106a220e200341b8016a41106a29030037030020034198016a41186a220f200341b8016a41186a290300370300200320032903b801370398012003200720026b220136022420014110490d032003200c41116a3602202003200141706a360224200c41096a2900002108200c2900012110200341b8016a200341206a10f40520032802b801220c450d0320032802c001211120032802bc012102200341b8016a200341206a10960220032802b80122070d012002450d03200241306c0d020c030b20034100360224200141ff0171450d02200341003a00d8010c020b20032802bc01211220032802242201410f4b0d020240201241ffffff3f71450d00200710290b2002450d01200241306c450d010b200c10290b200341d8006a41086a200341f8006a41086a2903003703000240200a450d00200a41d8006c2102200941306a210103400240200141746a280200220c450d00200c41306c450d00200141706a28020010290b0240200128020041ffffff3f71450d002001417c6a28020010290b200141d8006a2101200241a87f6a22020d000b0b200328022c2201450d03200141d8006c450d03200910290c030b20032802c0012113200341d8006a41086a200d2903002214370300200341d8006a41106a200e2903002215370300200341d8006a41186a200f2903002216370300200341386a41186a220d2016370300200341386a41106a220e2015370300200341386a41086a220f20143703002003200141706a36022420032003280220220141106a3602202003200329039801221437035820032014370338200141086a2900002114200129000021150240200a200328022c470d00200341286a200a4101108c01200328022821092003280230210a0b2009200a41d8006c6a2201201537031020012008370308200120103703002001200c360220200141186a2014370300200141346a2013360200200141306a20123602002001412c6a2007360200200141286a2011360200200141246a2002360200200141386a2003290338370200200141c0006a200f290300370200200141c8006a200e290300370200200141d0006a200d2903003702002003200a41016a220a360230200b2006460d01200328022421070c000b0b20090d010b200341003602a00120034201370398012003410d36027c2003200341086a360278200320034198016a360258200341cc016a4101360200200342013702bc01200341f4eaca003602b8012003200341f8006a3602c801200341d8006a41a8a3c800200341b8016a10371a20033502a0014220862003350298018410080240200328029c01450d0020032802980110290b200041003602000c010b2000200329022c370204200020093602000b2005450d00200410290b200341e0016a24000f0b1038000b1039000bd01e020f7f147e230041d0056b22052400200541286a200010d801200541d0046a20052802282206200528023010cd01200541d0036a41086a2207200541d9046a290000370300200541d0036a41106a2208200541e1046a290000370300200541d0036a41186a2209200541e9046a290000370300200520052900d1043703d0034100210a024020052d00d0044101470d00200541d0026a41186a2009290300370300200541d0026a41106a2008290300370300200541d0026a41086a2007290300370300200520052903d0033703d0024101210a0b0240200528022c450d00200610290b024002400240200a450d00200541086a41186a200541d0026a41186a2206290300370300200541086a41106a200541d0026a41106a2207290300370300200541086a41086a200541d0026a41086a2208290300370300200520052903d002370308200541e0016a200541086a10db01200541d0046a20052802e001220920052802e80110e20120054190016a41086a220b200541d0046a41086a29030037030020054190016a41106a220c200541d0046a41106a29030037030020054190016a41186a220d200541d0046a41186a290300370300200541d0036a41086a220e200541fc046a290200370300200541d0036a41106a220f20054184056a290200370300200541d0036a41186a22102005418c056a290200370300200541d0036a41206a221120054194056a290200370300200541d0036a41286a22122005419c056a290200370300200541d0036a41306a2213200541a4056a280200360200200520052903d00437039001200520052902f4043703d003024020052802f004220a450d0020054198026a41186a200d29030037030020054198026a41106a200c29030037030020054198026a41086a200b2903003703002008200e2903003703002007200f29030037030020062010290300370300200541d0026a41206a2011290300370300200541d0026a41286a2012290300370300200541d0026a41306a2013280200360200200520052903900137039802200520052903d0033703d0020b024020052802e401450d00200910290b200a450d00200541cc006a20052903d002370200200541286a41186a220620054198026a41186a290300370300200541286a41106a220720054198026a41106a290300370300200541286a41086a220820054198026a41086a290300370300200541d4006a200541d0026a41086a290300370200200541dc006a200541d0026a41106a290300370200200541e4006a200541d0026a41186a290300370200200541ec006a200541f0026a290300370200200541f4006a200541d0026a41286a290300370200200541fc006a20054180036a28020036020020052005290398023703282005200a36024820082903002114200529032821150240024020072903002216200120162001542006290300221720025420172002511b22071b22182017200220071b22198450450d002015211a2014211b0c010b2006201720197d2016201854ad7d221c3703002005201620187d221a37033802400240201a4280c8afa02556201c420052201c501b450d0020182116201921170c010b200541c0006a420037030020054200370338201c20027c201a20017c2201201a54ad7c21020b20054200201420177d2015201654ad7d2218201520167d221c201556201820145620182014511b22061b221b37033020054200201c20061b221a370328200220177d2001201654ad7d2102200120167d21010b02400240200541286a41286a28020022060d004100210a410021060c010b200641186c21084100210603400240200a2903002216200120012016562002200a41086a220929030022175620022017511b22071b22182017200220071b221984500d00200a201620187d221a370300200a201720197d2016201854ad7d221c37030802400240201a4280c8afa02556201c420052201c501b450d002001211c20182116201921170c010b200a4200370308200a42003703002002201c7c2001201a7c221c200154ad7c21020b200541286a41086a220742002007290300220120177d20052903282218201654ad7d2219201820167d221a201856201920015620192001511b22071b221b37030020054200201a20071b221a370328200220177d201c201654ad7d2102201c20167d210120092903002117200a29030021160b024020162017844200520d00200a41186a210a200641016a2106200841686a22080d010b0b2005280250220a2006490d020b200541003602500240200a20066b220a450d0002402006450d00200528024822072007200641186c6a200a41186c10e5071a0b2005200a3602500b024042002015201a7d221620162015562014201b7d2015201a54ad7d221620145620162014511b220a1b220242002016200a1b220184500d0020054180016a200010a80220054190016a2005280280012206200528028801220710a902200529039001211b2005420037039001200541d8016a280200210820052d00dc01210902400240201b4201510d004200211c200541e0016a41306a4200370300200541e0016a41286a4200370300200541e0016a41206a4200370300200541e0016a41186a4200370300200541f0016a4200370300200541e8016a4200370300200542003703e0014200211942002117420021164200211d0c010b200541c8016a290300211820054190016a41306a290300211a20054190016a41206a290300211920054190016a41186a290300211c200541d0016a290300211d20052903a00121162005290398012117200541e0016a41206a20054190016a41286a290300370300200541e0016a41286a201a370300200541e0016a41306a2018370300200541f0016a201c370300200520193703f801200520173703e001200520163703e8010b20052017200220172017200256201620015620162001511b220a1b221a7d22143703e0012005201620012016200a1b221e7d2017201a54ad7d22183703e801200541e0016a41106a210a024002402002201a7d221f2001201e7d2002201a54ad7d22208450450d004200211a4200212020022121200121220c010b200541f8016a201920202019201c201f56201920205620192020511b220b1b22237d201c201f201c200b1b221554ad7d3703002005201c20157d3703f001202020237d201f201554ad7d21202023201e7c2015201a7c2221201554ad7c2122201f20157d211a0b20054198026a41186a200a41086a290300221537030020054198026a41206a220b200a41106a290300370300200541c0026a220c200a41186a290300370300200541c8026a220d200a41206a2903003703002005200a290300221f3703a8022005201437039802200520183703a00202400240427f2014201f7c221f201f201454220a201820157c200aad7c221520185420152018511b220a1b221f4280c8afa025544100427f2015200a1b221e501b0d00200541a8026a2903002124200d2903002125200c290300211f200b290300211e20052903a002212320052903980221264201211520052903b00221270c010b420021150240201f201e84500d00201f201e10d40220054188056a201e37030020054180056a201f370300200541d0046a41086a41013a0000200541d9046a2000290000370000200541e1046a200041086a290000370000200541e9046a200041106a290000370000200541f1046a200041186a290000370000200541033a00d004200541d0046a10cb010b0b200541b8016a201e370300200541c0016a201f370300200541a0016a2023370300200541c8016a2025370300200541a8016a2024370300200520273703b0012005201d3703d0012005202637039801200520094100201b420151220a1b22093a00dc01200520084100200a1b22083602d80120052015420151220aad3703900102400240200a0d002007ad4220862006ad8410040c010b41041027220a450d04200a2008360000200a41044108102b220a450d04200a20093a0004200a41084115102b220a450d04200a2026370005200a410d6a2023370000200541b0016a2903002123200541a8016a2903002126200a4115412a102b220a450d04200a2026370015200a411d6a2023370000200a412a41d400102b220a450d04200a201e370025200a412d6a201f370000200a413d6a200541d0016a290300370000200a200541c8016a2903003700352007ad4220862006ad84200aad4280808080d008841003200a10290b2017201c7c221c201754220a201620197c200aad7c221720165420172016511b210a0240200528028401450d00200610290b427f2017200a1b2116427f201c200a1b21172015420152210a024002400240201b4201510d00200a0d0041032106200541d0036a210a0c010b201b420152200a410173720d0141042106200541d0026a210a0b200a41086a20063a0000200a41003a0000200a41096a2000290000370000200a41116a200041086a290000370000200a41196a200041106a290000370000200a41216a200041186a290000370000200a10cb010b024020172016844200520d0020054188056a201837030020054180056a2014370300200541d0046a41086a41003a0000200541d9046a2000290000370000200541e1046a200041086a290000370000200541e9046a200041106a290000370000200541f1046a200041186a290000370000200541033a00d004200541d0046a10cb010b2004427f2004290300221620217c22172017201654220a200441086a2206290300221620227c200aad7c221720165420172016511b220a1b3703002006427f2017200a1b3703000240201a202084500d002003420020032903002216201a7d22172017201656200341086a220a290300221720207d2016201a54ad7d221620175620162017511b22061b370300200a4200201620061b3703000b200542f3e885db96cddbb3203703d002200541d0026a200541286a41386a2005290328200541286a41086a290300411f10aa02200541d0046a200541086a10db0120052802d004210a200520052802d8043602d4032005200a3602d003200541286a200541d0036a10e401024020052802d404450d00200a10290b200541d0046a41386a200137030020054180056a2002370300200541d0046a41086a41023a0000200541d9046a2000290000370000200541e1046a200041086a290000370000200541e9046a200041106a290000370000200541f1046a200041186a290000370000200541043a00d004200541d0046a10cb010b0240200528024c220a450d00200a41186c450d00200528024810290b200541d8006a28020041ffffffff0371450d00200528025410290b200541d0056a24000f0b2006200a1044000b1030000bb80908017f037e037f017e017f017e047f037e230041e0016b22032400200320023703582003200137035002400240200120028450450d0042002104420021050c010b2003200036021c200341206a2000200341d0006a2003411c6a10de03024020032903204201520d00200341306a2903002105200329032821040c010b200341c8006a2903002105200341c0006a290300210420032903284201520d00200341206a41106a290300210620034198016a200341206a41186a29030037030020034190016a2006370300200341e0006a41086a41003a0000200341e9006a2000290000370000200341f1006a200041086a290000370000200341f9006a200041106a29000037000020034181016a200041186a290000370000200341033a0060200341e0006a10cb010b200341e0006a41186a22074200370300200341e0006a41106a22084200370300200341e0006a41086a220942003703002003420037036041dcbec500ad4280808080800184220a1001220b2900002106200341d0006a41086a2200200b41086a29000037030020032006370350200b10292009200029030037030020032003290350370360419fe3c200ad4280808080d00184220c1001220b29000021062000200b41086a29000037030020032006370350200b1029200820032903502206370300200341206a41086a220d2009290300370300200341206a41106a220e2006370300200341206a41186a220f2000290300370300200320032903603703202003200341206a412010e301200220057d2001200454ad7d200520027d2004200154ad7d200420015820052002582005200251220b1b22101b2111200120047d200420017d20101b2112200341106a2903004200200328020022101b21062003290308420020101b21130240024020042001562005200256200b1b0d0020074200370300200842003703002009420037030020034200370360200a1001220b29000021012000200b41086a29000037030020032001370350200b10292009200029030037030020032003290350370360200c1001220b29000021012000200b41086a29000037030020032001370350200b102920082003290350370000200841086a2000290300370000200d2009290300370300200e2008290300370300200f20072903003703002003200329036037032020034200200620117d2013201254ad7d2201201320127d2202201356200120065620012006511b22001b37036820034200200220001b370360200341e0006a21000c010b20074200370300200842003703002009420037030020034200370360200a1001220b29000021012000200b41086a29000037030020032001370350200b10292009200029030037030020032003290350370360200c1001220b29000021012000200b41086a29000037030020032001370350200b102920082003290350370000200841086a2000290300370000200d2009290300370300200e2008290300370300200f2007290300370300200320032903603703202003427f200620117c201320127c22022013542200ad7c22012000200120065420012006511b22001b3703682003427f200220001b370360200341e0006a21000b200341206aad42808080808004842000ad42808080808002841003200341e0016a24000bd70408027f017e037f017e017f027e037f017e230041f0006b2203240020012002844200522204ad2105024020040d00200341c0006a41186a22064200370300200341c0006a41106a22074200370300200341c0006a41086a220842003703002003420037034041dcbec500ad428080808080018422091001220a290000210b200341e0006a41086a2204200a41086a2900003703002003200b370360200a10292008200429030037030020032003290360370340419fe3c200ad4280808080d00184220b1001220a290000210c2004200a41086a2900003703002003200c370360200a102920072003290360220c370300200341206a41086a220d2008290300370300200341206a41106a220e200c370300200341206a41186a220f200429030037030020032003290340370320200341086a200341206a412010e301200341086a41106a290300210c200329031021102003280208210a2006420037030020074200370300200842003703002003420037034020091001220629000021092004200641086a29000037030020032009370360200610292008200429030037030020032003290360370340200b1001220629000021092004200641086a2900003703002003200937036020061029200720032903602209370300200d2008290300370300200e2009370300200f2004290300370300200320032903403703202003200c4200200a1b370348200320104200200a1b370340200341206aad4280808080800484200341c0006aad428080808080028410030b2000200137030820002005370300200041106a2002370300200341f0006a24000b970201057f230041306b22022400024002400240410410272203450d00200341edde91e306360000410c210420034104410c102b2205450d0120052001290000370004200241003a002820052106410021030340200241003a002f2002412f6a20062004410047220110e4071a024020040d00200241003a002f0b20042001490d03200241086a20036a20022d002f3a00002002200341016a22033a0028200420016b2104200620016a210620034120470d000b20002002290308370000200041186a200241086a41186a290300370000200041106a200241086a41106a290300370000200041086a200241086a41086a29030037000020051029200241306a24000f0b1039000b1030000b2001200441a896cc00104c000b990707017f047e027f017e057f047e017f23004190026b22022400200241c0006a200110840202400240024002400240024002402002290340a70d00200241c0006a41106a290300210320022903482104200241286a20011084022002290328a70d03200241286a41106a290300210520022903302106200241206a200110c80120022802200d0220022802242207200128020441306e2208200820074b1bad42307e2209422088a7450d010c060b200041003602200c040b2009a72208417f4c0d040240024020080d004108210a0c010b20081027220a450d030b4100210b200241003602602002200a3602582002200841306e36025c0240024002402007450d004100210c03404100210d200241003a008802200c41016a210c2001280204417f6a210803402008417f460d03200241e8016a200d6a2001280200220e2d00003a0000200120083602042001200e41016a3602002002200d41016a220e3a0088022008417f6a2108200e210d200e4120470d000b200241c8016a41186a2208200241e8016a41186a290300370300200241c8016a41106a220d200241e8016a41106a290300370300200241c8016a41086a220e200241e8016a41086a290300370300200220022903e8013703c801200241086a20011084022002290308a70d03200241086a41106a29030021092002290310210f20024188016a41086a200e290300221037030020024188016a41106a200d290300221137030020024188016a41186a20082903002212370300200241e8006a41086a220d2010370300200241e8006a41106a220e2011370300200241e8006a41186a22132012370300200220022903c801221037038801200220103703680240200b200228025c470d00200241d8006a200b41011090012002280258210a2002280260210b0b200a200b41306c6a220820093703082008200f37030020082002290368370310200841186a200d290300370300200841206a200e290300370300200841286a20132903003703002002200b41016a220b360260200c2007470d000b0b200a450d02200229025c210920002004370300200020093702242000200a3602202000200637031020002003370308200041186a20053703000c050b200d41ff0171450d00200241003a0088020b20024188016a41086a200241a8016a41086a290300370300200228025c2201450d00200141306c450d00200a10290b200041003602200c020b200041003602200c010b1039000b20024190026a24000f0b1038000bde0506067f017e017f017e017f017e230041206b220224000240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200024002400240200541037122074103460d0002400240024020070e03000102000b2005410276ad21080c040b410121072006450d0220042d0001210620012003417e6a3602042001200441026a3602002006410874200572220141ffff0371418002490d02200141fcff0371410276ad21080c030b4101210720064103490d01200441036a2d0000210620042f0001210920012003417c6a3602042001200441046a3602002009200641107472410874200572220141808004490d012001410276ad21080c020b024020054102762209410c4b0d0002400240024020090e0d00030303010303030303030302000b20064104490d052004350001210820012003417b6a3602042001200441056a36020020084280808080045421074200210a0c060b20064108490d04200429000121082001200341776a3602042001200441096a3602002008428080808080808080015421074200210a0c050b20064110490d03200441096a290000210a2004290001210820012003416f6a3602042001200441116a360200200a428080808080808080015421070c040b200941046a220641104b0d022003417e6a2103200441026a21044100210541012107200241186a210b420021084200210a03402003417f460d01200241106a2004417f6a3100004200200541037441f8007110ea0720012003360204200120043602002003417f6a2103200441016a2104200b290300200a84210a20022903102008842108200541016a220541ff01712006490d000b2002427f427f41e80020094103746b41f8007110eb072008200229030058200a200241086a290300220c58200a200c511b21070c030b0c020b4200210a410021070c010b410121070b20002008370308200041106a200a37030020002007ad370300200241206a24000bd53901037f230041106b2202240020002802002103200028020822042001107102402004450d00200320044103746a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a41021072200341086a22032004470d000b0b200028020c2103200041146a28020022042001107102402004450d0020032004410c6c6a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a410210722003410c6a22032004470d000b0b20002802182103200041206a28020022042001107102402004450d00200320044104746a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a41021072200341106a22032004470d000b0b200028022421032000412c6a28020022042001107102402004450d002003200441146c6a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a41021072200341146a22032004470d000b0b20002802302103200041386a28020022042001107102402004450d002003200441186c6a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a41021072200341186a22032004470d000b0b200028023c2103200041c4006a28020022042001107102402004450d0020032004411c6c6a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a410210722002200341166a2f01003b010c20012002410c6a410210722002200341186a2f01003b010c20012002410c6a410210722003411c6a22032004470d000b0b20002802482103200041d0006a28020022042001107102402004450d00200320044105746a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a410210722002200341166a2f01003b010c20012002410c6a410210722002200341186a2f01003b010c20012002410c6a4102107220022003411a6a2f01003b010c20012002410c6a4102107220022003411c6a2f01003b010c20012002410c6a41021072200341206a22032004470d000b0b20002802542103200041dc006a28020022042001107102402004450d002003200441246c6a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a410210722002200341166a2f01003b010c20012002410c6a410210722002200341186a2f01003b010c20012002410c6a4102107220022003411a6a2f01003b010c20012002410c6a4102107220022003411c6a2f01003b010c20012002410c6a4102107220022003411e6a2f01003b010c20012002410c6a410210722002200341206a2f01003b010c20012002410c6a41021072200341246a22032004470d000b0b20002802602103200041e8006a28020022042001107102402004450d002003200441286c6a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a410210722002200341166a2f01003b010c20012002410c6a410210722002200341186a2f01003b010c20012002410c6a4102107220022003411a6a2f01003b010c20012002410c6a4102107220022003411c6a2f01003b010c20012002410c6a4102107220022003411e6a2f01003b010c20012002410c6a410210722002200341206a2f01003b010c20012002410c6a410210722002200341226a2f01003b010c20012002410c6a410210722002200341246a2f01003b010c20012002410c6a41021072200341286a22032004470d000b0b200028026c2103200041f4006a28020022042001107102402004450d0020032004412c6c6a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a410210722002200341166a2f01003b010c20012002410c6a410210722002200341186a2f01003b010c20012002410c6a4102107220022003411a6a2f01003b010c20012002410c6a4102107220022003411c6a2f01003b010c20012002410c6a4102107220022003411e6a2f01003b010c20012002410c6a410210722002200341206a2f01003b010c20012002410c6a410210722002200341226a2f01003b010c20012002410c6a410210722002200341246a2f01003b010c20012002410c6a410210722002200341266a2f01003b010c20012002410c6a410210722002200341286a2f01003b010c20012002410c6a410210722003412c6a22032004470d000b0b2000280278210320004180016a28020022042001107102402004450d002003200441306c6a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a410210722002200341166a2f01003b010c20012002410c6a410210722002200341186a2f01003b010c20012002410c6a4102107220022003411a6a2f01003b010c20012002410c6a4102107220022003411c6a2f01003b010c20012002410c6a4102107220022003411e6a2f01003b010c20012002410c6a410210722002200341206a2f01003b010c20012002410c6a410210722002200341226a2f01003b010c20012002410c6a410210722002200341246a2f01003b010c20012002410c6a410210722002200341266a2f01003b010c20012002410c6a410210722002200341286a2f01003b010c20012002410c6a4102107220022003412a6a2f01003b010c20012002410c6a4102107220022003412c6a2f01003b010c20012002410c6a41021072200341306a22032004470d000b0b20002802840121032000418c016a28020022042001107102402004450d002003200441346c6a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a410210722002200341166a2f01003b010c20012002410c6a410210722002200341186a2f01003b010c20012002410c6a4102107220022003411a6a2f01003b010c20012002410c6a4102107220022003411c6a2f01003b010c20012002410c6a4102107220022003411e6a2f01003b010c20012002410c6a410210722002200341206a2f01003b010c20012002410c6a410210722002200341226a2f01003b010c20012002410c6a410210722002200341246a2f01003b010c20012002410c6a410210722002200341266a2f01003b010c20012002410c6a410210722002200341286a2f01003b010c20012002410c6a4102107220022003412a6a2f01003b010c20012002410c6a4102107220022003412c6a2f01003b010c20012002410c6a4102107220022003412e6a2f01003b010c20012002410c6a410210722002200341306a2f01003b010c20012002410c6a41021072200341346a22032004470d000b0b200028029001210320004198016a28020022042001107102402004450d002003200441386c6a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a410210722002200341166a2f01003b010c20012002410c6a410210722002200341186a2f01003b010c20012002410c6a4102107220022003411a6a2f01003b010c20012002410c6a4102107220022003411c6a2f01003b010c20012002410c6a4102107220022003411e6a2f01003b010c20012002410c6a410210722002200341206a2f01003b010c20012002410c6a410210722002200341226a2f01003b010c20012002410c6a410210722002200341246a2f01003b010c20012002410c6a410210722002200341266a2f01003b010c20012002410c6a410210722002200341286a2f01003b010c20012002410c6a4102107220022003412a6a2f01003b010c20012002410c6a4102107220022003412c6a2f01003b010c20012002410c6a4102107220022003412e6a2f01003b010c20012002410c6a410210722002200341306a2f01003b010c20012002410c6a410210722002200341326a2f01003b010c20012002410c6a410210722002200341346a2f01003b010c20012002410c6a41021072200341386a22032004470d000b0b200028029c012103200041a4016a28020022042001107102402004450d0020032004413c6c6a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a410210722002200341166a2f01003b010c20012002410c6a410210722002200341186a2f01003b010c20012002410c6a4102107220022003411a6a2f01003b010c20012002410c6a4102107220022003411c6a2f01003b010c20012002410c6a4102107220022003411e6a2f01003b010c20012002410c6a410210722002200341206a2f01003b010c20012002410c6a410210722002200341226a2f01003b010c20012002410c6a410210722002200341246a2f01003b010c20012002410c6a410210722002200341266a2f01003b010c20012002410c6a410210722002200341286a2f01003b010c20012002410c6a4102107220022003412a6a2f01003b010c20012002410c6a4102107220022003412c6a2f01003b010c20012002410c6a4102107220022003412e6a2f01003b010c20012002410c6a410210722002200341306a2f01003b010c20012002410c6a410210722002200341326a2f01003b010c20012002410c6a410210722002200341346a2f01003b010c20012002410c6a410210722002200341366a2f01003b010c20012002410c6a410210722002200341386a2f01003b010c20012002410c6a410210722003413c6a22032004470d000b0b20002802a8012103200041b0016a28020022042001107102402004450d00200320044106746a210403402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a410210722002200341166a2f01003b010c20012002410c6a410210722002200341186a2f01003b010c20012002410c6a4102107220022003411a6a2f01003b010c20012002410c6a4102107220022003411c6a2f01003b010c20012002410c6a4102107220022003411e6a2f01003b010c20012002410c6a410210722002200341206a2f01003b010c20012002410c6a410210722002200341226a2f01003b010c20012002410c6a410210722002200341246a2f01003b010c20012002410c6a410210722002200341266a2f01003b010c20012002410c6a410210722002200341286a2f01003b010c20012002410c6a4102107220022003412a6a2f01003b010c20012002410c6a4102107220022003412c6a2f01003b010c20012002410c6a4102107220022003412e6a2f01003b010c20012002410c6a410210722002200341306a2f01003b010c20012002410c6a410210722002200341326a2f01003b010c20012002410c6a410210722002200341346a2f01003b010c20012002410c6a410210722002200341366a2f01003b010c20012002410c6a410210722002200341386a2f01003b010c20012002410c6a4102107220022003413a6a2f01003b010c20012002410c6a4102107220022003413c6a2f01003b010c20012002410c6a41021072200341c0006a22032004470d000b0b20002802b4012103200041bc016a28020022002001107102402000450d002003200041c4006c6a210003402002200328020036020c20012002410c6a410410722002200341046a2f01003b010c20012002410c6a410210722002200341066a2f01003b010c20012002410c6a410210722002200341086a2f01003b010c20012002410c6a4102107220022003410a6a2f01003b010c20012002410c6a4102107220022003410c6a2f01003b010c20012002410c6a4102107220022003410e6a2f01003b010c20012002410c6a410210722002200341106a2f01003b010c20012002410c6a410210722002200341126a2f01003b010c20012002410c6a410210722002200341146a2f01003b010c20012002410c6a410210722002200341166a2f01003b010c20012002410c6a410210722002200341186a2f01003b010c20012002410c6a4102107220022003411a6a2f01003b010c20012002410c6a4102107220022003411c6a2f01003b010c20012002410c6a4102107220022003411e6a2f01003b010c20012002410c6a410210722002200341206a2f01003b010c20012002410c6a410210722002200341226a2f01003b010c20012002410c6a410210722002200341246a2f01003b010c20012002410c6a410210722002200341266a2f01003b010c20012002410c6a410210722002200341286a2f01003b010c20012002410c6a4102107220022003412a6a2f01003b010c20012002410c6a4102107220022003412c6a2f01003b010c20012002410c6a4102107220022003412e6a2f01003b010c20012002410c6a410210722002200341306a2f01003b010c20012002410c6a410210722002200341326a2f01003b010c20012002410c6a410210722002200341346a2f01003b010c20012002410c6a410210722002200341366a2f01003b010c20012002410c6a410210722002200341386a2f01003b010c20012002410c6a4102107220022003413a6a2f01003b010c20012002410c6a4102107220022003413c6a2f01003b010c20012002410c6a4102107220022003413e6a2f01003b010c20012002410c6a410210722002200341c0006a2f01003b010c20012002410c6a41021072200341c4006a22032000470d000b0b200241106a24000bec990106097f017e067f037e3f7f027e230041d0036b22022400200241f8006a200110c8010240024002400240024002400240024002400240024002400240024002400240024002400240024020022802780d00200228027c220320012802044103762204200420034b1b22054103742204417f4c0d020240024020050d00410421060c010b200410272206450d040b41002104200241003602980320022005360294032002200636029003024002402003450d00410021040340200128020422054104490d0220012802002207280000210820012005417c6a22093602042001200741046a220736020020094102490d0220072f0000210920012005417a6a3602042001200741026a36020002402004200228029403470d0020024190036a20044101108d01200228029003210620022802980321040b200620044103746a220520093b0104200520083602002002200441016a2204360298032003417f6a22030d000b20022802940321050b2006450d01200241f0006a200110c8012002280270450d020c130b20022802940341ffffffff0171450d00200610290b200041003602000c120b2002280274220a2001280204410c6e22072007200a4b1bad420c7e220b422088a70d00200ba72203417f4c0d000240024020030d004104210c0c010b20031027220c450d020b4100210720024100360298032002200c3602900320022003410c6e220d36029403024002400240200a450d00410021070340200128020422034104490d0220012802002209280000210e20012003417c6a220d3602042001200941046a2208360200200d4102490d0220082f0000210f20012003417a6a220d3602042001200841026a360200200d4102490d0220092f0006210d2001200341786a22083602042001200941086a220936020020084102490d0220092f000021082001200341766a3602042001200941026a36020002402007200228029403470d0020024190036a20074101109d01200228029003210c20022802980321070b200c2007410c6c6a220320083b01082003200f3b01042003200e360200200341066a200d3b01002002200741016a220736029803200a417f6a220a0d000b200228029403210d0b200c450d12200241e8006a200110c8012002280268450d010c110b2002280294032201450d112001410c6c450d11200c10290c110b4104210f200228026c220e200128020441047622032003200e4b1b22034104742209417f4c0d0002402003450d0020091027220f450d020b41002108200241003602980320022003360294032002200f36029003024002400240200e450d00410021080340200128020422034104490d0220012802002209280000211020012003417c6a22113602042001200941046a220a36020020114102490d02200a330000210b20012003417a6a22113602042001200a41026a36020020114102490d02200933000621122001200341786a22113602042001200941086a220a36020020114102490d02200a33000021132001200341766a22113602042001200a41026a36020020114102490d02200933000a21142001200341746a220a36020420012009410c6a2209360200200a4102490d0220092f0000210a2001200341726a3602042001200941026a3602002014423086201342208684201242108684200b84210b02402008200228029403470d0020024190036a20084101109c01200228029003210f20022802980321080b200f20084104746a2203200a3b010c2003200b370204200320103602002002200841016a220836029803200e417f6a220e0d000b20022802940321030b200f450d11200241e0006a200110c8012002280260450d010c100b20022802940341ffffffff0071450d10200f10290c100b20022802642210200128020441146e2209200920104b1bad42147e220b422088a70d00200ba72209417f4c0d000240024020090d00410421150c010b200910272215450d020b4100210e200241003602980320022015360290032002200941146e2211360294030240024002402010450d004100210e0340200128020422094104490d022001280200220a280000211620012009417c6a22173602042001200a41046a221136020020174102490d0220112f0000211820012009417a6a22173602042001201141026a36020020174102490d02200a2f000621192001200941786a22173602042001200a41086a221136020020174102490d0220112f0000211a2001200941766a22173602042001201141026a36020020174102490d02200a2f000a211b2001200941746a22173602042001200a410c6a221136020020174102490d0220112f0000211c2001200941726a22173602042001201141026a36020020174102490d02200a2f000e21172001200941706a22113602042001200a41106a220a36020020114102490d02200a2f0000211120012009416e6a3602042001200a41026a3602000240200e200228029403470d0020024190036a200e410110a0012002280290032115200228029803210e0b2015200e41146c6a220920113b0110200920183b0104200920163602002009410e6a20173b01002009410c6a201c3b01002009410a6a201b3b0100200941086a201a3b0100200941066a20193b01002002200e41016a220e360298032010417f6a22100d000b20022802940321110b2015450d10200241d8006a200110c8012002280258450d010c0f0b2002280294032201450d0f200141146c450d0f201510290c0f0b200228025c2217200128020441186e2209200920174b1bad42187e220b422088a70d00200ba72209417f4c0d000240024020090d00410421180c010b200910272218450d020b41002110200241003602980320022018360290032002200941186e2216360294030240024002402017450d00410021100340200128020422094104490d022001280200220a280000211a20012009417c6a22193602042001200a41046a221636020020194102490d0220162f0000211b20012009417a6a22193602042001201641026a36020020194102490d02200a2f0006211c2001200941786a22193602042001200a41086a221636020020194102490d0220162f0000211d2001200941766a22193602042001201641026a36020020194102490d02200a2f000a211e2001200941746a22193602042001200a410c6a221636020020194102490d0220162f0000211f2001200941726a22193602042001201641026a36020020194102490d02200a2f000e21202001200941706a22193602042001200a41106a221636020020194102490d0220162f0000212120012009416e6a22193602042001201641026a36020020194102490d02200a2f0012211920012009416c6a22163602042001200a41146a220a36020020164102490d02200a2f0000211620012009416a6a3602042001200a41026a36020002402010200228029403470d0020024190036a20104101109901200228029003211820022802980321100b2018201041186c6a220920163b01142009201b3b01042009201a360200200941126a20193b0100200941106a20213b01002009410e6a20203b01002009410c6a201f3b01002009410a6a201e3b0100200941086a201d3b0100200941066a201c3b01002002201041016a2210360298032017417f6a22170d000b20022802940321160b2018450d0f200241d0006a200110c8012002280250450d010c0e0b2002280294032201450d0e200141186c450d0e201810290c0e0b200228025422192001280204411c6e2209200920194b1bad421c7e220b422088a70d00200ba72209417f4c0d000240024020090d004104211b0c010b20091027221b450d020b4100211720024100360298032002201b3602900320022009411c6e221a360294030240024002402019450d00410021170340200128020422094104490d022001280200220a280000211d20012009417c6a221c3602042001200a41046a221a360200201c4102490d02201a2f0000211e20012009417a6a221c3602042001201a41026a360200201c4102490d02200a2f0006211f2001200941786a221c3602042001200a41086a221a360200201c4102490d02201a2f000021202001200941766a221c3602042001201a41026a360200201c4102490d02200a2f000a21212001200941746a221c3602042001200a410c6a221a360200201c4102490d02201a2f000021222001200941726a221c3602042001201a41026a360200201c4102490d02200a2f000e21232001200941706a221c3602042001200a41106a221a360200201c4102490d02201a2f0000212420012009416e6a221c3602042001201a41026a360200201c4102490d02200a2f0012212520012009416c6a221c3602042001200a41146a221a360200201c4102490d02201a2f0000212620012009416a6a221c3602042001201a41026a360200201c4102490d02200a2f0016211c2001200941686a221a3602042001200a41186a220a360200201a4102490d02200a2f0000211a2001200941666a3602042001200a41026a36020002402017200228029403470d0020024190036a20174101109401200228029003211b20022802980321170b201b2017411c6c6a2209201a3b01182009201e3b01042009201d360200200941166a201c3b0100200941146a20263b0100200941126a20253b0100200941106a20243b01002009410e6a20233b01002009410c6a20223b01002009410a6a20213b0100200941086a20203b0100200941066a201f3b01002002201741016a2217360298032019417f6a22190d000b200228029403211a0b201b450d0e200241c8006a200110c8012002280248450d010c0d0b2002280294032201450d0d2001411c6c450d0d201b10290c0d0b200228024c221c200128020441057622092009201c4b1b2209410574220a417f4c0d000240024020090d004104211e0c010b200a1027221e450d020b41002119200241003602980320022009360294032002201e36029003024002400240201c450d00410021190340200128020422094104490d022001280200220a280000212020012009417c6a221f3602042001200a41046a221d360200201f4102490d02201d2f0000212120012009417a6a221f3602042001201d41026a360200201f4102490d02200a2f000621222001200941786a221f3602042001200a41086a221d360200201f4102490d02201d2f000021232001200941766a221f3602042001201d41026a360200201f4102490d02200a2f000a21242001200941746a221f3602042001200a410c6a221d360200201f4102490d02201d2f000021252001200941726a221f3602042001201d41026a360200201f4102490d02200a2f000e21262001200941706a221f3602042001200a41106a221d360200201f4102490d02201d2f0000212720012009416e6a221f3602042001201d41026a360200201f4102490d02200a2f0012212820012009416c6a221f3602042001200a41146a221d360200201f4102490d02201d2f0000212920012009416a6a221f3602042001201d41026a360200201f4102490d02200a2f0016212a2001200941686a221f3602042001200a41186a221d360200201f4102490d02201d2f0000212b2001200941666a221f3602042001201d41026a360200201f4102490d02200a2f001a211f2001200941646a221d3602042001200a411c6a220a360200201d4102490d02200a2f0000211d2001200941626a3602042001200a41026a36020002402019200228029403470d0020024190036a20194101109501200228029003211e20022802980321190b201e20194105746a2209201d3b011c200920213b0104200920203602002009411a6a201f3b0100200941186a202b3b0100200941166a202a3b0100200941146a20293b0100200941126a20283b0100200941106a20273b01002009410e6a20263b01002009410c6a20253b01002009410a6a20243b0100200941086a20233b0100200941066a20223b01002002201941016a221936029803201c417f6a221c0d000b20022802940321090b201e450d0d200241c0006a200110c8012002280240450d010c0c0b20022802940341ffffff3f71450d0c201e10290c0c0b2002280244221f200128020441246e220a200a201f4b1bad42247e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421210c010b200a10272221450d020b4100211d200241003602980320022021360290032002200a41246e222036029403024002400240201f450d004100211d03402001280204220a4104490d022001280200221c28000021232001200a417c6a22223602042001201c41046a222036020020224102490d0220202f000021242001200a417a6a22223602042001202041026a36020020224102490d02201c2f000621252001200a41786a22223602042001201c41086a222036020020224102490d0220202f000021262001200a41766a22223602042001202041026a36020020224102490d02201c2f000a21272001200a41746a22223602042001201c410c6a222036020020224102490d0220202f000021282001200a41726a22223602042001202041026a36020020224102490d02201c2f000e21292001200a41706a22223602042001201c41106a222036020020224102490d0220202f0000212a2001200a416e6a22223602042001202041026a36020020224102490d02201c2f0012212b2001200a416c6a22223602042001201c41146a222036020020224102490d0220202f0000212c2001200a416a6a22223602042001202041026a36020020224102490d02201c2f0016212d2001200a41686a22223602042001201c41186a222036020020224102490d0220202f0000212e2001200a41666a22223602042001202041026a36020020224102490d02201c2f001a212f2001200a41646a22223602042001201c411c6a222036020020224102490d0220202f000021302001200a41626a22223602042001202041026a36020020224102490d02201c2f001e21222001200a41606a22203602042001201c41206a221c36020020204102490d02201c2f000021202001200a415e6a3602042001201c41026a3602000240201d200228029403470d0020024190036a201d41011096012002280290032121200228029803211d0b2021201d41246c6a220a20203b0120200a20243b0104200a2023360200200a411e6a20223b0100200a411c6a20303b0100200a411a6a202f3b0100200a41186a202e3b0100200a41166a202d3b0100200a41146a202c3b0100200a41126a202b3b0100200a41106a202a3b0100200a410e6a20293b0100200a410c6a20283b0100200a410a6a20273b0100200a41086a20263b0100200a41066a20253b01002002201d41016a221d36029803201f417f6a221f0d000b20022802940321200b2021450d0c200241386a200110c8012002280238450d010c0b0b2002280294032201450d0b200141246c450d0b202110290c0b0b200228023c2222200128020441286e220a200a20224b1bad42287e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421230c010b200a10272223450d020b4100211f200241003602980320022023360290032002200a41286e2224360294030240024002402022450d004100211f03402001280204220a4104490d022001280200221c28000021262001200a417c6a22253602042001201c41046a222436020020254102490d0220242f000021272001200a417a6a22253602042001202441026a36020020254102490d02201c2f000621282001200a41786a22253602042001201c41086a222436020020254102490d0220242f000021292001200a41766a22253602042001202441026a36020020254102490d02201c2f000a212a2001200a41746a22253602042001201c410c6a222436020020254102490d0220242f0000212b2001200a41726a22253602042001202441026a36020020254102490d02201c2f000e212c2001200a41706a22253602042001201c41106a222436020020254102490d0220242f0000212d2001200a416e6a22253602042001202441026a36020020254102490d02201c2f0012212e2001200a416c6a22253602042001201c41146a222436020020254102490d0220242f0000212f2001200a416a6a22253602042001202441026a36020020254102490d02201c2f001621302001200a41686a22253602042001201c41186a222436020020254102490d0220242f000021312001200a41666a22253602042001202441026a36020020254102490d02201c2f001a21322001200a41646a22253602042001201c411c6a222436020020254102490d0220242f000021332001200a41626a22253602042001202441026a36020020254102490d02201c2f001e21342001200a41606a22253602042001201c41206a222436020020254102490d0220242f000021352001200a415e6a22253602042001202441026a36020020254102490d02201c2f002221252001200a415c6a22243602042001201c41246a221c36020020244102490d02201c2f000021242001200a415a6a3602042001201c41026a3602000240201f200228029403470d0020024190036a201f410110ad012002280290032123200228029803211f0b2023201f41286c6a220a20243b0124200a20273b0104200a2026360200200a41226a20253b0100200a41206a20353b0100200a411e6a20343b0100200a411c6a20333b0100200a411a6a20323b0100200a41186a20313b0100200a41166a20303b0100200a41146a202f3b0100200a41126a202e3b0100200a41106a202d3b0100200a410e6a202c3b0100200a410c6a202b3b0100200a410a6a202a3b0100200a41086a20293b0100200a41066a20283b01002002201f41016a221f360298032022417f6a22220d000b20022802940321240b2023450d0b200241306a200110c8012002280230450d010c0a0b2002280294032201450d0a200141286c450d0a202310290c0a0b200228023422252001280204412c6e220a200a20254b1bad422c7e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421260c010b200a10272226450d020b41002122200241003602980320022026360290032002200a412c6e2227360294030240024002402025450d004100212203402001280204220a4104490d022001280200221c28000021292001200a417c6a22283602042001201c41046a222736020020284102490d0220272f0000212a2001200a417a6a22283602042001202741026a36020020284102490d02201c2f0006212b2001200a41786a22283602042001201c41086a222736020020284102490d0220272f0000212c2001200a41766a22283602042001202741026a36020020284102490d02201c2f000a212d2001200a41746a22283602042001201c410c6a222736020020284102490d0220272f0000212e2001200a41726a22283602042001202741026a36020020284102490d02201c2f000e212f2001200a41706a22283602042001201c41106a222736020020284102490d0220272f000021302001200a416e6a22283602042001202741026a36020020284102490d02201c2f001221312001200a416c6a22283602042001201c41146a222736020020284102490d0220272f000021322001200a416a6a22283602042001202741026a36020020284102490d02201c2f001621332001200a41686a22283602042001201c41186a222736020020284102490d0220272f000021342001200a41666a22283602042001202741026a36020020284102490d02201c2f001a21352001200a41646a22283602042001201c411c6a222736020020284102490d0220272f000021362001200a41626a22283602042001202741026a36020020284102490d02201c2f001e21372001200a41606a22283602042001201c41206a222736020020284102490d0220272f000021382001200a415e6a22283602042001202741026a36020020284102490d02201c2f002221392001200a415c6a22283602042001201c41246a222736020020284102490d0220272f0000213a2001200a415a6a22283602042001202741026a36020020284102490d02201c2f002621282001200a41586a22273602042001201c41286a221c36020020274102490d02201c2f000021272001200a41566a3602042001201c41026a36020002402022200228029403470d0020024190036a20224101109301200228029003212620022802980321220b20262022412c6c6a220a20273b0128200a202a3b0104200a2029360200200a41266a20283b0100200a41246a203a3b0100200a41226a20393b0100200a41206a20383b0100200a411e6a20373b0100200a411c6a20363b0100200a411a6a20353b0100200a41186a20343b0100200a41166a20333b0100200a41146a20323b0100200a41126a20313b0100200a41106a20303b0100200a410e6a202f3b0100200a410c6a202e3b0100200a410a6a202d3b0100200a41086a202c3b0100200a41066a202b3b01002002202241016a2222360298032025417f6a22250d000b20022802940321270b2026450d0a200241286a200110c8012002280228450d010c090b2002280294032201450d092001412c6c450d09202610290c090b200228022c2228200128020441306e220a200a20284b1bad42307e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421290c010b200a10272229450d020b41002125200241003602980320022029360290032002200a41306e222a360294030240024002402028450d004100212503402001280204220a4104490d022001280200221c280000212c2001200a417c6a222b3602042001201c41046a222a360200202b4102490d02202a2f0000212d2001200a417a6a222b3602042001202a41026a360200202b4102490d02201c2f0006212e2001200a41786a222b3602042001201c41086a222a360200202b4102490d02202a2f0000212f2001200a41766a222b3602042001202a41026a360200202b4102490d02201c2f000a21302001200a41746a222b3602042001201c410c6a222a360200202b4102490d02202a2f000021312001200a41726a222b3602042001202a41026a360200202b4102490d02201c2f000e21322001200a41706a222b3602042001201c41106a222a360200202b4102490d02202a2f000021332001200a416e6a222b3602042001202a41026a360200202b4102490d02201c2f001221342001200a416c6a222b3602042001201c41146a222a360200202b4102490d02202a2f000021352001200a416a6a222b3602042001202a41026a360200202b4102490d02201c2f001621362001200a41686a222b3602042001201c41186a222a360200202b4102490d02202a2f000021372001200a41666a222b3602042001202a41026a360200202b4102490d02201c2f001a21382001200a41646a222b3602042001201c411c6a222a360200202b4102490d02202a2f000021392001200a41626a222b3602042001202a41026a360200202b4102490d02201c2f001e213a2001200a41606a222b3602042001201c41206a222a360200202b4102490d02202a2f0000213b2001200a415e6a222b3602042001202a41026a360200202b4102490d02201c2f0022213c2001200a415c6a222b3602042001201c41246a222a360200202b4102490d02202a2f0000213d2001200a415a6a222b3602042001202a41026a360200202b4102490d02201c2f0026213e2001200a41586a222b3602042001201c41286a222a360200202b4102490d02202a2f0000213f2001200a41566a222b3602042001202a41026a360200202b4102490d02201c2f002a212b2001200a41546a222a3602042001201c412c6a221c360200202a4102490d02201c2f0000212a2001200a41526a3602042001201c41026a36020002402025200228029403470d0020024190036a2025410110ab01200228029003212920022802980321250b2029202541306c6a220a202a3b012c200a202d3b0104200a202c360200200a412a6a202b3b0100200a41286a203f3b0100200a41266a203e3b0100200a41246a203d3b0100200a41226a203c3b0100200a41206a203b3b0100200a411e6a203a3b0100200a411c6a20393b0100200a411a6a20383b0100200a41186a20373b0100200a41166a20363b0100200a41146a20353b0100200a41126a20343b0100200a41106a20333b0100200a410e6a20323b0100200a410c6a20313b0100200a410a6a20303b0100200a41086a202f3b0100200a41066a202e3b01002002202541016a2225360298032028417f6a22280d000b200228029403212a0b2029450d09200241206a200110c8012002280220450d010c080b2002280294032201450d08200141306c450d08202910290c080b2002280224222b200128020441346e220a200a202b4b1bad42347e220b422088a70d00200ba7220a417f4c0d0002400240200a0d004104212c0c010b200a1027222c450d020b4100212820024100360298032002202c360290032002200a41346e222d36029403024002400240202b450d004100212803402001280204220a4104490d022001280200221c280000212f2001200a417c6a222e3602042001201c41046a222d360200202e4102490d02202d2f000021302001200a417a6a222e3602042001202d41026a360200202e4102490d02201c2f000621312001200a41786a222e3602042001201c41086a222d360200202e4102490d02202d2f000021322001200a41766a222e3602042001202d41026a360200202e4102490d02201c2f000a21332001200a41746a222e3602042001201c410c6a222d360200202e4102490d02202d2f000021342001200a41726a222e3602042001202d41026a360200202e4102490d02201c2f000e21352001200a41706a222e3602042001201c41106a222d360200202e4102490d02202d2f000021362001200a416e6a222e3602042001202d41026a360200202e4102490d02201c2f001221372001200a416c6a222e3602042001201c41146a222d360200202e4102490d02202d2f000021382001200a416a6a222e3602042001202d41026a360200202e4102490d02201c2f001621392001200a41686a222e3602042001201c41186a222d360200202e4102490d02202d2f0000213a2001200a41666a222e3602042001202d41026a360200202e4102490d02201c2f001a213b2001200a41646a222e3602042001201c411c6a222d360200202e4102490d02202d2f0000213c2001200a41626a222e3602042001202d41026a360200202e4102490d02201c2f001e213d2001200a41606a222e3602042001201c41206a222d360200202e4102490d02202d2f0000213e2001200a415e6a222e3602042001202d41026a360200202e4102490d02201c2f0022213f2001200a415c6a222e3602042001201c41246a222d360200202e4102490d02202d2f000021402001200a415a6a222e3602042001202d41026a360200202e4102490d02201c2f002621412001200a41586a222e3602042001201c41286a222d360200202e4102490d02202d2f000021422001200a41566a222e3602042001202d41026a360200202e4102490d02201c2f002a21432001200a41546a222e3602042001201c412c6a222d360200202e4102490d02202d2f000021442001200a41526a222e3602042001202d41026a360200202e4102490d02201c2f002e212e2001200a41506a222d3602042001201c41306a221c360200202d4102490d02201c2f0000212d2001200a414e6a3602042001201c41026a36020002402028200228029403470d0020024190036a2028410110ae01200228029003212c20022802980321280b202c202841346c6a220a202d3b0130200a20303b0104200a202f360200200a412e6a202e3b0100200a412c6a20443b0100200a412a6a20433b0100200a41286a20423b0100200a41266a20413b0100200a41246a20403b0100200a41226a203f3b0100200a41206a203e3b0100200a411e6a203d3b0100200a411c6a203c3b0100200a411a6a203b3b0100200a41186a203a3b0100200a41166a20393b0100200a41146a20383b0100200a41126a20373b0100200a41106a20363b0100200a410e6a20353b0100200a410c6a20343b0100200a410a6a20333b0100200a41086a20323b0100200a41066a20313b01002002202841016a222836029803202b417f6a222b0d000b200228029403212d0b202c450d08200241186a200110c8012002280218450d010c070b2002280294032201450d07200141346c450d07202c10290c070b200228021c222e200128020441386e220a200a202e4b1bad42387e220b422088a70d00200ba7220a417f4c0d0002400240200a0d004104212f0c010b200a1027222f450d020b4100212b20024100360298032002202f360290032002200a41386e223036029403024002400240202e450d004100212b03402001280204220a4104490d022001280200221c28000021322001200a417c6a22313602042001201c41046a223036020020314102490d0220302f000021332001200a417a6a22313602042001203041026a36020020314102490d02201c2f000621342001200a41786a22313602042001201c41086a223036020020314102490d0220302f000021352001200a41766a22313602042001203041026a36020020314102490d02201c2f000a21362001200a41746a22313602042001201c410c6a223036020020314102490d0220302f000021372001200a41726a22313602042001203041026a36020020314102490d02201c2f000e21382001200a41706a22313602042001201c41106a223036020020314102490d0220302f000021392001200a416e6a22313602042001203041026a36020020314102490d02201c2f0012213a2001200a416c6a22313602042001201c41146a223036020020314102490d0220302f0000213b2001200a416a6a22313602042001203041026a36020020314102490d02201c2f0016213c2001200a41686a22313602042001201c41186a223036020020314102490d0220302f0000213d2001200a41666a22313602042001203041026a36020020314102490d02201c2f001a213e2001200a41646a22313602042001201c411c6a223036020020314102490d0220302f0000213f2001200a41626a22313602042001203041026a36020020314102490d02201c2f001e21402001200a41606a22313602042001201c41206a223036020020314102490d0220302f000021412001200a415e6a22313602042001203041026a36020020314102490d02201c2f002221422001200a415c6a22313602042001201c41246a223036020020314102490d0220302f000021432001200a415a6a22313602042001203041026a36020020314102490d02201c2f002621442001200a41586a22313602042001201c41286a223036020020314102490d0220302f000021452001200a41566a22313602042001203041026a36020020314102490d02201c2f002a21462001200a41546a22313602042001201c412c6a223036020020314102490d0220302f000021472001200a41526a22313602042001203041026a36020020314102490d02201c2f002e21482001200a41506a22313602042001201c41306a223036020020314102490d0220302f000021492001200a414e6a22313602042001203041026a36020020314102490d02201c2f003221312001200a414c6a22303602042001201c41346a221c36020020304102490d02201c2f000021302001200a414a6a3602042001201c41026a3602000240202b200228029403470d0020024190036a202b410110aa01200228029003212f200228029803212b0b202f202b41386c6a220a20303b0134200a20333b0104200a2032360200200a41326a20313b0100200a41306a20493b0100200a412e6a20483b0100200a412c6a20473b0100200a412a6a20463b0100200a41286a20453b0100200a41266a20443b0100200a41246a20433b0100200a41226a20423b0100200a41206a20413b0100200a411e6a20403b0100200a411c6a203f3b0100200a411a6a203e3b0100200a41186a203d3b0100200a41166a203c3b0100200a41146a203b3b0100200a41126a203a3b0100200a41106a20393b0100200a410e6a20383b0100200a410c6a20373b0100200a410a6a20363b0100200a41086a20353b0100200a41066a20343b01002002202b41016a222b36029803202e417f6a222e0d000b20022802940321300b202f450d07200241106a200110c8012002280210450d010c060b2002280294032201450d06200141386c450d06202f10290c060b2002280214222e2001280204413c6e220a200a202e4b1bad423c7e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421320c010b200a10272232450d020b41002131200241003602980320022032360290032002200a413c6e223336029403024002400240202e450d004100213103402001280204220a4104490d022001280200221c28000021352001200a417c6a22343602042001201c41046a223336020020344102490d0220332f000021362001200a417a6a22343602042001203341026a36020020344102490d02201c2f000621372001200a41786a22343602042001201c41086a223336020020344102490d0220332f000021382001200a41766a22343602042001203341026a36020020344102490d02201c2f000a21392001200a41746a22343602042001201c410c6a223336020020344102490d0220332f0000213a2001200a41726a22343602042001203341026a36020020344102490d02201c2f000e213b2001200a41706a22343602042001201c41106a223336020020344102490d0220332f0000213c2001200a416e6a22343602042001203341026a36020020344102490d02201c2f0012213d2001200a416c6a22343602042001201c41146a223336020020344102490d0220332f0000213e2001200a416a6a22343602042001203341026a36020020344102490d02201c2f0016213f2001200a41686a22343602042001201c41186a223336020020344102490d0220332f000021402001200a41666a22343602042001203341026a36020020344102490d02201c2f001a21412001200a41646a22343602042001201c411c6a223336020020344102490d0220332f000021422001200a41626a22343602042001203341026a36020020344102490d02201c2f001e21432001200a41606a22343602042001201c41206a223336020020344102490d0220332f000021442001200a415e6a22343602042001203341026a36020020344102490d02201c2f002221452001200a415c6a22343602042001201c41246a223336020020344102490d0220332f000021462001200a415a6a22343602042001203341026a36020020344102490d02201c2f002621472001200a41586a22343602042001201c41286a223336020020344102490d0220332f000021482001200a41566a22343602042001203341026a36020020344102490d02201c2f002a21492001200a41546a22343602042001201c412c6a223336020020344102490d0220332f0000214a2001200a41526a22343602042001203341026a36020020344102490d02201c2f002e214b2001200a41506a22343602042001201c41306a223336020020344102490d0220332f0000214c2001200a414e6a22343602042001203341026a36020020344102490d02201c2f0032214d2001200a414c6a22343602042001201c41346a223336020020344102490d0220332f0000214e2001200a414a6a22343602042001203341026a36020020344102490d02201c2f003621342001200a41486a22333602042001201c41386a221c36020020334102490d02201c2f000021332001200a41466a3602042001201c41026a36020002402031200228029403470d0020024190036a20314101109b01200228029003213220022802980321310b20322031413c6c6a220a20333b0138200a20363b0104200a2035360200200a41366a20343b0100200a41346a204e3b0100200a41326a204d3b0100200a41306a204c3b0100200a412e6a204b3b0100200a412c6a204a3b0100200a412a6a20493b0100200a41286a20483b0100200a41266a20473b0100200a41246a20463b0100200a41226a20453b0100200a41206a20443b0100200a411e6a20433b0100200a411c6a20423b0100200a411a6a20413b0100200a41186a20403b0100200a41166a203f3b0100200a41146a203e3b0100200a41126a203d3b0100200a41106a203c3b0100200a410e6a203b3b0100200a410c6a203a3b0100200a410a6a20393b0100200a41086a20383b0100200a41066a20373b01002002203141016a223136029803202e417f6a222e0d000b20022802940321330b2032450d06200241086a200110c8012002280208450d010c050b2002280294032201450d052001413c6c450d05203210290c050b200228020c222e2001280204410676220a200a202e4b1b221c410674220a417f4c0d0002400240201c0d00410421350c010b200a10272235450d020b4100213420024100360298032002201c360294032002203536029003024002400240202e450d004100213403402001280204220a4104490d022001280200221c28000021382001200a417c6a22373602042001201c41046a2236360200200241003b01d00220374102490d0220362f000021392001200a417a6a22373602042001203641026a360200200241003b01d00220374102490d02201c2f0006213a2001200a41786a22373602042001201c41086a2236360200200241003b01d00220374102490d0220362f0000213b2001200a41766a22373602042001203641026a360200200241003b01d002203741014d0d02201c2f000a213c2001200a41746a22373602042001201c410c6a2236360200200241003b01d00220374102490d0220362f0000213d2001200a41726a22373602042001203641026a360200200241003b01d00220374102490d02201c2f000e213e2001200a41706a22373602042001201c41106a2236360200200241003b01d00220374102490d0220362f0000213f2001200a416e6a22373602042001203641026a360200200241003b01d00220374102490d02201c2f001221402001200a416c6a22373602042001201c41146a2236360200200241003b01d00220374102490d0220362f000021412001200a416a6a22373602042001203641026a360200200241003b01d00220374102490d02201c2f001621422001200a41686a22373602042001201c41186a2236360200200241003b01d00220374102490d0220362f000021432001200a41666a22373602042001203641026a360200200241003b01d00220374102490d02201c2f001a21442001200a41646a22373602042001201c411c6a2236360200200241003b01d00220374102490d0220362f000021452001200a41626a22373602042001203641026a360200200241003b01d00220374102490d02201c2f001e21462001200a41606a22373602042001201c41206a2236360200200241003b01d00220374102490d0220362f000021472001200a415e6a22373602042001203641026a360200200241003b01d00220374102490d02201c2f002221482001200a415c6a22373602042001201c41246a2236360200200241003b01d00220374102490d0220362f000021492001200a415a6a22373602042001203641026a360200200241003b01d00220374102490d02201c2f0026214a2001200a41586a22373602042001201c41286a2236360200200241003b01d00220374102490d0220362f0000214b2001200a41566a22373602042001203641026a360200200241003b01d00220374102490d02201c2f002a214c2001200a41546a22373602042001201c412c6a2236360200200241003b01d00220374102490d0220362f0000214d2001200a41526a22373602042001203641026a360200200241003b01d00220374102490d02201c2f002e214e2001200a41506a22373602042001201c41306a2236360200200241003b01d00220374102490d0220362f0000214f2001200a414e6a22373602042001203641026a360200200241003b01d00220374102490d02201c2f003221502001200a414c6a22373602042001201c41346a2236360200200241003b01d00220374102490d0220362f000021512001200a414a6a22373602042001203641026a360200200241003b01d00220374102490d02201c2f003621522001200a41486a22373602042001201c41386a2236360200200241003b01d00220374102490d0220362f000021532001200a41466a22373602042001203641026a360200200241003b01d00220374102490d02201c2f003a21372001200a41446a22363602042001201c413c6a221c36020020364102490d02201c2f000021362001200a41426a3602042001201c41026a36020002402034200228029403470d0020024190036a20344101109101200228029003213520022802980321340b203520344106746a220a20363b013c200a20393b0104200a2038360200200a413a6a20373b0100200a41386a20533b0100200a41366a20523b0100200a41346a20513b0100200a41326a20503b0100200a41306a204f3b0100200a412e6a204e3b0100200a412c6a204d3b0100200a412a6a204c3b0100200a41286a204b3b0100200a41266a204a3b0100200a41246a20493b0100200a41226a20483b0100200a41206a20473b0100200a411e6a20463b0100200a411c6a20453b0100200a411a6a20443b0100200a41186a20433b0100200a41166a20423b0100200a41146a20413b0100200a41126a20403b0100200a41106a203f3b0100200a410e6a203e3b0100200a410c6a203d3b0100200a410a6a203c3b0100200a41086a203b3b0100200a41066a203a3b01002002203441016a223436029803202e417f6a222e0d000b200228029403211c0b2035450d052002200110c8012002280200450d010c040b20022802940341ffffff1f71450d04203510290c040b2002280204223e200128020441c4006e220a200a203e4b1bad42c4007e220b422088a70d00200ba7220a417f4c0d0002400240200a0d004104213d0c010b200a1027223d450d020b20024100360288012002203d360280012002200a41c4006e36028401024002400240203e450d00410021404100213f03402001280204223b4104490d03203f41016a213f417c212e2001280200223c28000021412001203b417c6a3602042001203c41046a3602004100210a200241003a00cc03410021380340200241003b01ce03203b202e6a22364102490d03203c200a6a223741046a2f0000213920012036417e6a22363602042001203741066a2237360200200241003b01ce0320364102490d0320024190036a200a6a223a20393b0100203a41026a20372f00003b010020012036417e6a3602042001203741026a3602002002203841016a22383a00cc03202e417c6a212e200a41046a220a413c470d000b200241d0026a41386a223620024190036a41386a280200360200200241d0026a41306a223720024190036a41306a290300370300200241d0026a41286a223820024190036a41286a290300370300200241d0026a41206a223920024190036a41206a290300370300200241d0026a41186a223a20024190036a41186a290300370300200241d0026a41106a224220024190036a41106a290300370300200241d0026a41086a224320024190036a41086a29030037030020022002290390033703d002203b202e6a41014d0d03203c200a6a222e41046a2f0000213c2001203b200a6b417a6a3602042001202e41066a36020020024190026a41086a220a204329030037030020024190026a41106a222e204229030037030020024190026a41186a223b203a29030037030020024190026a41206a223a203929030037030020024190026a41286a2239203829030037030020024190026a41306a2238203729030037030020024190026a41386a22372036280200360200200220022903d00237039002200241d0016a41086a200a290300220b370300200241d0016a41106a202e2903002212370300200241d0016a41186a203b2903002213370300200241d0016a41206a203a2903002214370300200241d0016a41286a20392903002254370300200241d0016a41306a20382903002255370300200241d0016a41386a2037280200220a36020020024190016a41086a222e200b37030020024190016a41106a2236201237030020024190016a41186a2237201337030020024190016a41206a2238201437030020024190016a41286a2239205437030020024190016a41306a223a205537030020024190016a41386a223b200a3602002002200229039002220b3703d0012002200b3703900102402040200228028401470d0020024180016a20404101109f01200228028001213d20022802880121400b203d204041c4006c6a220a2041360200200a200229039001370204203b280200213b203a290300210b20392903002112203829030021132037290300211420362903002154202e2903002155200a203c3b0140200a410c6a2055370200200a41146a2054370200200a411c6a2014370200200a41246a2013370200200a412c6a2012370200200a41346a200b370200200a413c6a203b3602002002204041016a224036028801203f203e470d000b0b203d450d04200229028401210b2000200536020420002006360200200041b8016a200b370200200041b4016a203d360200200041b0016a2034360200200041ac016a201c360200200041a8016a2035360200200041a4016a2031360200200041a0016a20333602002000419c016a203236020020004198016a202b36020020004194016a203036020020004190016a202f3602002000418c016a202836020020004188016a202d36020020004184016a202c36020020004180016a2025360200200041fc006a202a360200200041f8006a2029360200200041f4006a2022360200200041f0006a2027360200200041ec006a2026360200200041e8006a201f360200200041e4006a2024360200200041e0006a2023360200200041dc006a201d360200200041d8006a2020360200200041d4006a2021360200200041d0006a2019360200200041cc006a2009360200200041c8006a201e360200200041c4006a2017360200200041c0006a201a3602002000413c6a201b360200200041386a2010360200200041346a2016360200200041306a20183602002000412c6a200e360200200041286a2011360200200041246a2015360200200041206a20083602002000411c6a2003360200200041186a200f360200200041146a2007360200200041106a200d3602002000410c6a200c360200200041086a20043602000c130b203841ff0171450d00200241003a00cc030b200241d0016a41386a20024190026a41386a280200360200200241d0016a41306a20024190026a41306a290300370300200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d02200141c4006c450d02203d10290c020b1038000b1039000b200041003602000240201c41ffffff1f71450d00203510290b02402033450d002033413c6c450d00203210290b02402030450d00203041386c450d00202f10290b0240202d450d00202d41346c450d00202c10290b0240202a450d00202a41306c450d00202910290b02402027450d002027412c6c450d00202610290b02402024450d00202441286c450d00202310290b02402020450d00202041246c450d00202110290b0240200941ffffff3f71450d00201e10290b0240201a450d00201a411c6c450d00201b10290b02402016450d00201641186c450d00201810290b02402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d0e200610290c0e0b2000410036020002402033450d002033413c6c450d00203210290b02402030450d00203041386c450d00202f10290b0240202d450d00202d41346c450d00202c10290b0240202a450d00202a41306c450d00202910290b02402027450d002027412c6c450d00202610290b02402024450d00202441286c450d00202310290b02402020450d00202041246c450d00202110290b0240200941ffffff3f71450d00201e10290b0240201a450d00201a411c6c450d00201b10290b02402016450d00201641186c450d00201810290b02402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d0d200610290c0d0b2000410036020002402030450d00203041386c450d00202f10290b0240202d450d00202d41346c450d00202c10290b0240202a450d00202a41306c450d00202910290b02402027450d002027412c6c450d00202610290b02402024450d00202441286c450d00202310290b02402020450d00202041246c450d00202110290b0240200941ffffff3f71450d00201e10290b0240201a450d00201a411c6c450d00201b10290b02402016450d00201641186c450d00201810290b02402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d0c200610290c0c0b200041003602000240202d450d00202d41346c450d00202c10290b0240202a450d00202a41306c450d00202910290b02402027450d002027412c6c450d00202610290b02402024450d00202441286c450d00202310290b02402020450d00202041246c450d00202110290b0240200941ffffff3f71450d00201e10290b0240201a450d00201a411c6c450d00201b10290b02402016450d00201641186c450d00201810290b02402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d0b200610290c0b0b200041003602000240202a450d00202a41306c450d00202910290b02402027450d002027412c6c450d00202610290b02402024450d00202441286c450d00202310290b02402020450d00202041246c450d00202110290b0240200941ffffff3f71450d00201e10290b0240201a450d00201a411c6c450d00201b10290b02402016450d00201641186c450d00201810290b02402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d0a200610290c0a0b2000410036020002402027450d002027412c6c450d00202610290b02402024450d00202441286c450d00202310290b02402020450d00202041246c450d00202110290b0240200941ffffff3f71450d00201e10290b0240201a450d00201a411c6c450d00201b10290b02402016450d00201641186c450d00201810290b02402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d09200610290c090b2000410036020002402024450d00202441286c450d00202310290b02402020450d00202041246c450d00202110290b0240200941ffffff3f71450d00201e10290b0240201a450d00201a411c6c450d00201b10290b02402016450d00201641186c450d00201810290b02402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d08200610290c080b2000410036020002402020450d00202041246c450d00202110290b0240200941ffffff3f71450d00201e10290b0240201a450d00201a411c6c450d00201b10290b02402016450d00201641186c450d00201810290b02402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d07200610290c070b200041003602000240200941ffffff3f71450d00201e10290b0240201a450d00201a411c6c450d00201b10290b02402016450d00201641186c450d00201810290b02402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d06200610290c060b200041003602000240201a450d00201a411c6c450d00201b10290b02402016450d00201641186c450d00201810290b02402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d05200610290c050b2000410036020002402016450d00201641186c450d00201810290b02402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d04200610290c040b2000410036020002402011450d00201141146c450d00201510290b0240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d03200610290c030b200041003602000240200341ffffffff0071450d00200f10290b0240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d02200610290c020b200041003602000240200d450d00200d410c6c450d00200c10290b200541ffffffff0171450d01200610290c010b20004100360200200541ffffffff0171450d00200610290b200241d0036a24000bf70301017f0240200041046a28020041ffffffff0171450d00200028020010290b0240200041106a2802002201450d002001410c6c450d00200028020c10290b02402000411c6a28020041ffffffff0071450d00200028021810290b0240200041286a2802002201450d00200141146c450d00200028022410290b0240200041346a2802002201450d00200141186c450d00200028023010290b0240200041c0006a2802002201450d002001411c6c450d00200028023c10290b0240200041cc006a28020041ffffff3f71450d00200028024810290b0240200041d8006a2802002201450d00200141246c450d00200028025410290b0240200041e4006a2802002201450d00200141286c450d00200028026010290b0240200041f0006a2802002201450d002001412c6c450d00200028026c10290b0240200041fc006a2802002201450d00200141306c450d00200028027810290b024020004188016a2802002201450d00200141346c450d0020002802840110290b024020004194016a2802002201450d00200141386c450d0020002802900110290b0240200041a0016a2802002201450d002001413c6c450d00200028029c0110290b0240200041ac016a28020041ffffff1f71450d0020002802a80110290b0240200041b8016a2802002201450d00200141c4006c450d0020002802b40110290b0be49301032a7f047e247f23004180026b22042400200441b8016a4200370300200441b0016a22054280808080c000370300200441a0016a420037030020044198016a22064280808080c00037030020044188016a420037030020044180016a22074280808080c000370300200441f0006a4200370300200441e8006a22084280808080c000370300200441d8006a4200370300200441d0006a22094280808080c000370300200441c0006a4200370300200441386a220a4280808080c000370300200441286a4200370300200441206a220b4280808080c000370300200441106a4200370300200442043703a8012004420437039001200442043703782004420437036020044204370348200442043703302004420437031820044280808080c000370308200442043703002001280200220c2001280208220d412c6c220e6a210f20012802042110200c2101024002400240200d450d00200441bc016a2111200441b4016a2112200441a8016a2113200441a4016a21142004419c016a211520044190016a21162004418c016a211720044184016a2118200441f8006a2119200441f4006a211a200441ec006a211b200441e0006a211c200441dc006a211d200441d4006a211e200441c8006a211f200441c4006a21202004413c6a2121200441306a21222004412c6a2123200441246a2124200441186a2125200441146a21262004410c6a2127200441086a2128200e41546a210d200441e0016a41086a2129200441e0016a41106a212a200441e0016a41186a212b200c210e0340200e280208212c200e280204212d2029200e41146a290200370300202a200e411c6a290200370300202b200e41246a2902003703002004200e29020c3703e001200e412c6a2101200e280200220e450d01200441c0016a41186a202b290300222e370300200441c0016a41106a202a290300222f370300200441c0016a41086a20292903002230370300200420042903e00122313703c001202b202e370300202a202f37030020292030370300200420313703e001024002400240202c41104d0d00410121320c010b024002400240024002400240024002400240024002400240024002400240024002400240202c0e11000102030405060708090a0b0c0d0e0f10000b0240202d450d00202d41226c450d00200e10290b2001200f460d150c120b4102213220022802082233450d102002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a22340d000c120b0b20032802082234450d102003280200212c203441057421354100213402400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a22350d000c120b0b2034418080044f0d1002402004280208222c2004280204470d002004202c4101108d012004280208212c0b2004280200202c4103746a222c20343b0104202c20333602002028212c0c0f0b4102213220022802082233450d0f2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a22340d000c110b0b2003280208222c450d0f41002135202c4105742237213620032802002234212c02400340200e202c460d012035202c200e412010e70722384100476a21352038450d01202c41206a212c203641606a22360d000c110b0b203541ffff034b0d0f200e41226a2136200e2f012021394100212c0240034020362034460d01202c20342036412010e70722384100476a212c2038450d01203441206a2134203741606a22370d000c110b0b202c41ffff034b0d0f0240200428021422322004280210470d00202720324101109d01200428021421320b200428020c2032410c6c6a2232202c3b0108203220353b010420322033360200203241066a20393b01002026212c0c0e0b4102213220022802082233450d0e2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a22340d000c100b0b2003280208222c450d0e41002134202c410574223a213520032802002238212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a22350d000c100b0b203441ffff034b0d0e200e41226a2136200e2f0120213b41002135203a21372038212c024003402036202c460d012035202c2036412010e70722394100476a21352039450d01202c41206a212c203741606a22370d000c100b0b203541ffff034b0d0e200e41c4006a2136200e41c2006a2f010021394100212c0240034020362038460d01202c20382036412010e70722374100476a212c2037450d01203841206a2138203a41606a223a0d000c100b0b202c41ffff034b0d0e024020042802202232200428021c470d00202520324101109c01200428022021320b200428021820324104746a2232202c3b010c203220343b0104203220333602002032410a6a20393b0100203241086a20353b0100203241066a203b3b0100200b212c0c0d0b4102213220022802082233450d0d2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a22340d000c0f0b0b2003280208222c450d0d41002134202c410574223b213520032802002237212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a22350d000c0f0b0b203441ffff034b0d0d200e41226a2136200e2f0120213c41002135203b21382037212c024003402036202c460d012035202c2036412010e70722394100476a21352039450d01202c41206a212c203841606a22380d000c0f0b0b203541ffff034b0d0d200e41c4006a2138200e41c2006a2f0100213d41002136203b21392037212c024003402038202c460d012036202c2038412010e707223a4100476a2136203a450d01202c41206a212c203941606a22390d000c0f0b0b203641ffff034b0d0d200e41e6006a2138200e41e4006a2f0100213a4100212c0240034020382037460d01202c20372038412010e70722394100476a212c2039450d01203741206a2137203b41606a223b0d000c0f0b0b202c41ffff034b0d0d0240200428022c22322004280228470d0020242032410110a001200428022c21320b2004280224203241146c6a2232202c3b0110203220343b0104203220333602002032410e6a203a3b01002032410c6a20363b01002032410a6a203d3b0100203241086a20353b0100203241066a203c3b01002023212c0c0c0b4102213220022802082233450d0c2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a22340d000c0e0b0b2003280208222c450d0c41002134202c410574223b213520032802002239212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a22350d000c0e0b0b203441ffff034b0d0c200e41226a2136200e2f0120213d41002135203b21382039212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a22380d000c0e0b0b203541ffff034b0d0c200e41c4006a2138200e41c2006a2f0100213e41002136203b21372039212c024003402038202c460d012036202c2038412010e707223a4100476a2136203a450d01202c41206a212c203741606a22370d000c0e0b0b203641ffff034b0d0c200e41e6006a2137200e41e4006a2f0100213f41002138203b213a2039212c024003402037202c460d012038202c2037412010e707223c4100476a2138203c450d01202c41206a212c203a41606a223a0d000c0e0b0b203841ffff034b0d0c200e4188016a2137200e4186016a2f0100213c4100212c0240034020372039460d01202c20392037412010e707223a4100476a212c203a450d01203941206a2139203b41606a223b0d000c0e0b0b202c41ffff034b0d0c0240200428023822322004280234470d00202220324101109901200428023821320b2004280230203241186c6a2232202c3b0114203220343b010420322033360200203241126a203c3b0100203241106a20383b01002032410e6a203f3b01002032410c6a20363b01002032410a6a203e3b0100203241086a20353b0100203241066a203d3b0100200a212c0c0b0b4102213220022802082233450d0b2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a22340d000c0d0b0b2003280208222c450d0b41002134202c410574223c21352003280200223a212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a22350d000c0d0b0b203441ffff034b0d0b200e41226a2136200e2f0120213e41002135203c2138203a212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a22380d000c0d0b0b203541ffff034b0d0b200e41c4006a2138200e41c2006a2f0100213f41002136203c2137203a212c024003402038202c460d012036202c2038412010e70722394100476a21362039450d01202c41206a212c203741606a22370d000c0d0b0b203641ffff034b0d0b200e41e6006a2137200e41e4006a2f0100214041002138203c2139203a212c024003402037202c460d012038202c2037412010e707223b4100476a2138203b450d01202c41206a212c203941606a22390d000c0d0b0b203841ffff034b0d0b200e4188016a2139200e4186016a2f0100214141002137203c213b203a212c024003402039202c460d012037202c2039412010e707223d4100476a2137203d450d01202c41206a212c203b41606a223b0d000c0d0b0b203741ffff034b0d0b200e41aa016a2139200e41a8016a2f0100213d4100212c024003402039203a460d01202c203a2039412010e707223b4100476a212c203b450d01203a41206a213a203c41606a223c0d000c0d0b0b202c41ffff034b0d0b0240200428024422322004280240470d00202120324101109401200428024421320b200428023c2032411c6c6a2232202c3b0118203220343b010420322033360200203241166a203d3b0100203241146a20373b0100203241126a20413b0100203241106a20383b01002032410e6a20403b01002032410c6a20363b01002032410a6a203f3b0100203241086a20353b0100203241066a203e3b01002020212c0c0a0b4102213220022802082233450d0a2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a22340d000c0c0b0b2003280208222c450d0a41002134202c410574223c21352003280200223a212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a22350d000c0c0b0b203441ffff034b0d0a200e41226a2136200e2f0120213f41002135203c2138203a212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a22380d000c0c0b0b203541ffff034b0d0a200e41c4006a2138200e41c2006a2f0100214041002136203c2137203a212c024003402038202c460d012036202c2038412010e70722394100476a21362039450d01202c41206a212c203741606a22370d000c0c0b0b203641ffff034b0d0a200e41e6006a2137200e41e4006a2f0100214141002138203c2139203a212c024003402037202c460d012038202c2037412010e707223b4100476a2138203b450d01202c41206a212c203941606a22390d000c0c0b0b203841ffff034b0d0a200e4188016a2139200e4186016a2f0100214241002137203c213b203a212c024003402039202c460d012037202c2039412010e707223d4100476a2137203d450d01202c41206a212c203b41606a223b0d000c0c0b0b203741ffff034b0d0a200e41aa016a213b200e41a8016a2f0100214341002139203c213d203a212c02400340203b202c460d012039202c203b412010e707223e4100476a2139203e450d01202c41206a212c203d41606a223d0d000c0c0b0b203941ffff034b0d0a200e41cc016a213b200e41ca016a2f0100213e4100212c02400340203b203a460d01202c203a203b412010e707223d4100476a212c203d450d01203a41206a213a203c41606a223c0d000c0c0b0b202c41ffff034b0d0a024020042802502232200428024c470d00201f20324101109501200428025021320b200428024820324105746a2232202c3b011c203220343b0104203220333602002032411a6a203e3b0100203241186a20393b0100203241166a20433b0100203241146a20373b0100203241126a20423b0100203241106a20383b01002032410e6a20413b01002032410c6a20363b01002032410a6a20403b0100203241086a20353b0100203241066a203f3b01002009212c0c090b4102213220022802082233450d092002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a22340d000c0b0b0b2003280208222c450d0941002134202c410574223d21352003280200223b212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a22350d000c0b0b0b203441ffff034b0d09200e41226a2136200e2f0120214041002135203d2138203b212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a22380d000c0b0b0b203541ffff034b0d09200e41c4006a2138200e41c2006a2f0100214141002136203d2137203b212c024003402038202c460d012036202c2038412010e70722394100476a21362039450d01202c41206a212c203741606a22370d000c0b0b0b203641ffff034b0d09200e41e6006a2137200e41e4006a2f0100214241002138203d2139203b212c024003402037202c460d012038202c2037412010e707223a4100476a2138203a450d01202c41206a212c203941606a22390d000c0b0b0b203841ffff034b0d09200e4188016a2139200e4186016a2f0100214341002137203d213a203b212c024003402039202c460d012037202c2039412010e707223c4100476a2137203c450d01202c41206a212c203a41606a223a0d000c0b0b0b203741ffff034b0d09200e41aa016a213a200e41a8016a2f0100214441002139203d213c203b212c02400340203a202c460d012039202c203a412010e707223e4100476a2139203e450d01202c41206a212c203c41606a223c0d000c0b0b0b203941ffff034b0d09200e41cc016a213c200e41ca016a2f010021454100213a203d213e203b212c02400340203c202c460d01203a202c203c412010e707223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c0b0b0b203a41ffff034b0d09200e41ee016a213c200e41ec016a2f0100213f4100212c02400340203c203b460d01202c203b203c412010e707223e4100476a212c203e450d01203b41206a213b203d41606a223d0d000c0b0b0b202c41ffff034b0d090240200428025c22322004280258470d00201e20324101109601200428025c21320b2004280254203241246c6a2232202c3b0120203220343b0104203220333602002032411e6a203f3b01002032411c6a203a3b01002032411a6a20453b0100203241186a20393b0100203241166a20443b0100203241146a20373b0100203241126a20433b0100203241106a20383b01002032410e6a20423b01002032410c6a20363b01002032410a6a20413b0100203241086a20353b0100203241066a20403b0100201d212c0c080b4102213220022802082233450d082002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a22340d000c0a0b0b2003280208222c450d0841002134202c410574223d21352003280200223b212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a22350d000c0a0b0b203441ffff034b0d08200e41226a2136200e2f0120214141002135203d2138203b212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a22380d000c0a0b0b203541ffff034b0d08200e41c4006a2138200e41c2006a2f0100214241002136203d2137203b212c024003402038202c460d012036202c2038412010e70722394100476a21362039450d01202c41206a212c203741606a22370d000c0a0b0b203641ffff034b0d08200e41e6006a2137200e41e4006a2f0100214341002138203d2139203b212c024003402037202c460d012038202c2037412010e707223a4100476a2138203a450d01202c41206a212c203941606a22390d000c0a0b0b203841ffff034b0d08200e4188016a2139200e4186016a2f0100214441002137203d213a203b212c024003402039202c460d012037202c2039412010e707223c4100476a2137203c450d01202c41206a212c203a41606a223a0d000c0a0b0b203741ffff034b0d08200e41aa016a213a200e41a8016a2f0100214541002139203d213c203b212c02400340203a202c460d012039202c203a412010e707223e4100476a2139203e450d01202c41206a212c203c41606a223c0d000c0a0b0b203941ffff034b0d08200e41cc016a213c200e41ca016a2f010021464100213a203d213e203b212c02400340203c202c460d01203a202c203c412010e707223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c0a0b0b203a41ffff034b0d08200e41ee016a213e200e41ec016a2f010021474100213c203d213f203b212c02400340203e202c460d01203c202c203e412010e70722404100476a213c2040450d01202c41206a212c203f41606a223f0d000c0a0b0b203c41ffff034b0d08200e4190026a213e200e418e026a2f010021404100212c02400340203e203b460d01202c203b203e412010e707223f4100476a212c203f450d01203b41206a213b203d41606a223d0d000c0a0b0b202c41ffff034b0d080240200428026822322004280264470d00201c2032410110ad01200428026821320b2004280260203241286c6a2232202c3b0124203220343b010420322033360200203241226a20403b0100203241206a203c3b01002032411e6a20473b01002032411c6a203a3b01002032411a6a20463b0100203241186a20393b0100203241166a20453b0100203241146a20373b0100203241126a20443b0100203241106a20383b01002032410e6a20433b01002032410c6a20363b01002032410a6a20423b0100203241086a20353b0100203241066a20413b01002008212c0c070b4102213220022802082233450d072002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a22340d000c090b0b2003280208222c450d0741002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a22350d000c090b0b203441ffff034b0d07200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a22380d000c090b0b203541ffff034b0d07200e41c4006a2138200e41c2006a2f0100214341002136203d2137203c212c024003402038202c460d012036202c2038412010e70722394100476a21362039450d01202c41206a212c203741606a22370d000c090b0b203641ffff034b0d07200e41e6006a2137200e41e4006a2f0100214441002138203d2139203c212c024003402037202c460d012038202c2037412010e707223a4100476a2138203a450d01202c41206a212c203941606a22390d000c090b0b203841ffff034b0d07200e4188016a2139200e4186016a2f0100214541002137203d213a203c212c024003402039202c460d012037202c2039412010e707223b4100476a2137203b450d01202c41206a212c203a41606a223a0d000c090b0b203741ffff034b0d07200e41aa016a213a200e41a8016a2f0100214641002139203d213b203c212c02400340203a202c460d012039202c203a412010e707223e4100476a2139203e450d01202c41206a212c203b41606a223b0d000c090b0b203941ffff034b0d07200e41cc016a213b200e41ca016a2f010021474100213a203d213e203c212c02400340203b202c460d01203a202c203b412010e707223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c090b0b203a41ffff034b0d07200e41ee016a213e200e41ec016a2f010021484100213b203d213f203c212c02400340203e202c460d01203b202c203e412010e70722404100476a213b2040450d01202c41206a212c203f41606a223f0d000c090b0b203b41ffff034b0d07200e4190026a213f200e418e026a2f010021494100213e203d2140203c212c02400340203f202c460d01203e202c203f412010e70722414100476a213e2041450d01202c41206a212c204041606a22400d000c090b0b203e41ffff034b0d07200e41b2026a213f200e41b0026a2f010021414100212c02400340203f203c460d01202c203c203f412010e70722404100476a212c2040450d01203c41206a213c203d41606a223d0d000c090b0b202c41ffff034b0d070240200428027422322004280270470d00201b20324101109301200428027421320b200428026c2032412c6c6a2232202c3b0128203220343b010420322033360200203241266a20413b0100203241246a203e3b0100203241226a20493b0100203241206a203b3b01002032411e6a20483b01002032411c6a203a3b01002032411a6a20473b0100203241186a20393b0100203241166a20463b0100203241146a20373b0100203241126a20453b0100203241106a20383b01002032410e6a20443b01002032410c6a20363b01002032410a6a20433b0100203241086a20353b0100203241066a20423b0100201a212c0c060b4102213220022802082233450d062002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a22340d000c080b0b2003280208222c450d0641002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a22350d000c080b0b203441ffff034b0d06200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a22380d000c080b0b203541ffff034b0d06200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010e70722394100476a21362039450d01202c41206a212c203741606a22370d000c080b0b203641ffff034b0d06200e41e6006a2137200e41e4006a2f0100214541002138203d2139203c212c024003402037202c460d012038202c2037412010e707223a4100476a2138203a450d01202c41206a212c203941606a22390d000c080b0b203841ffff034b0d06200e4188016a2139200e4186016a2f0100214641002137203d213a203c212c024003402039202c460d012037202c2039412010e707223b4100476a2137203b450d01202c41206a212c203a41606a223a0d000c080b0b203741ffff034b0d06200e41aa016a213a200e41a8016a2f0100214741002139203d213b203c212c02400340203a202c460d012039202c203a412010e707223e4100476a2139203e450d01202c41206a212c203b41606a223b0d000c080b0b203941ffff034b0d06200e41cc016a213b200e41ca016a2f010021484100213a203d213e203c212c02400340203b202c460d01203a202c203b412010e707223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c080b0b203a41ffff034b0d06200e41ee016a213e200e41ec016a2f010021494100213b203d213f203c212c02400340203e202c460d01203b202c203e412010e70722404100476a213b2040450d01202c41206a212c203f41606a223f0d000c080b0b203b41ffff034b0d06200e4190026a213f200e418e026a2f0100214a4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010e70722414100476a213e2041450d01202c41206a212c204041606a22400d000c080b0b203e41ffff034b0d06200e41b2026a2140200e41b0026a2f0100214b4100213f203d2141203c212c024003402040202c460d01203f202c2040412010e70722434100476a213f2043450d01202c41206a212c204141606a2241450d080c000b0b203f41ffff034b0d06200e41d4026a2140200e41d2026a2f010021434100212c024003402040203c460d01202c203c2040412010e70722414100476a212c2041450d01203c41206a213c203d41606a223d450d080c000b0b202c41ffff034b0d0602402004280280012232200428027c470d0020192032410110ab0120042802800121320b2004280278203241306c6a2232202c3b012c203220343b0104203220333602002032412a6a20433b0100203241286a203f3b0100203241266a204b3b0100203241246a203e3b0100203241226a204a3b0100203241206a203b3b01002032411e6a20493b01002032411c6a203a3b01002032411a6a20483b0100203241186a20393b0100203241166a20473b0100203241146a20373b0100203241126a20463b0100203241106a20383b01002032410e6a20453b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002007212c0c050b4102213220022802082233450d052002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a2234450d070c000b0b2003280208222c450d0541002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a2235450d070c000b0b203441ffff034b0d05200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a2238450d070c000b0b203541ffff034b0d05200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010e70722394100476a21362039450d01202c41206a212c203741606a2237450d070c000b0b203641ffff034b0d05200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010e707223a4100476a2138203a450d01202c41206a212c203941606a2239450d070c000b0b203841ffff034b0d05200e4188016a2139200e4186016a2f0100214741002137203d213a203c212c024003402039202c460d012037202c2039412010e707223b4100476a2137203b450d01202c41206a212c203a41606a223a450d070c000b0b203741ffff034b0d05200e41aa016a213a200e41a8016a2f0100214841002139203d213b203c212c02400340203a202c460d012039202c203a412010e707223e4100476a2139203e450d01202c41206a212c203b41606a223b450d070c000b0b203941ffff034b0d05200e41cc016a213b200e41ca016a2f010021494100213a203d213e203c212c02400340203b202c460d01203a202c203b412010e707223f4100476a213a203f450d01202c41206a212c203e41606a223e450d070c000b0b203a41ffff034b0d05200e41ee016a213e200e41ec016a2f0100214a4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010e70722404100476a213b2040450d01202c41206a212c203f41606a223f450d070c000b0b203b41ffff034b0d05200e4190026a213f200e418e026a2f0100214b4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010e70722414100476a213e2041450d01202c41206a212c204041606a2240450d070c000b0b203e41ffff034b0d05200e41b2026a2140200e41b0026a2f0100214c4100213f203d2141203c212c024003402040202c460d01203f202c2040412010e70722434100476a213f2043450d01202c41206a212c204141606a2241450d070c000b0b203f41ffff034b0d05200e41d4026a2141200e41d2026a2f0100214d41002140203d2143203c212c024003402041202c460d012040202c2041412010e70722454100476a21402045450d01202c41206a212c204341606a2243450d070c000b0b204041ffff034b0d05200e41f6026a2141200e41f4026a2f010021454100212c024003402041203c460d01202c203c2041412010e70722434100476a212c2043450d01203c41206a213c203d41606a223d450d070c000b0b202c41ffff034b0d050240200428028c012232200428028801470d0020182032410110ae01200428028c0121320b200428028401203241346c6a2232202c3b0130203220343b0104203220333602002032412e6a20453b01002032412c6a20403b01002032412a6a204d3b0100203241286a203f3b0100203241266a204c3b0100203241246a203e3b0100203241226a204b3b0100203241206a203b3b01002032411e6a204a3b01002032411c6a203a3b01002032411a6a20493b0100203241186a20393b0100203241166a20483b0100203241146a20373b0100203241126a20473b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002017212c0c040b4102213220022802082233450d042002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a2234450d060c000b0b2003280208222c450d0441002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a2235450d060c000b0b203441ffff034b0d04200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a2238450d060c000b0b203541ffff034b0d04200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010e70722394100476a21362039450d01202c41206a212c203741606a2237450d060c000b0b203641ffff034b0d04200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010e707223a4100476a2138203a450d01202c41206a212c203941606a2239450d060c000b0b203841ffff034b0d04200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010e707223b4100476a2137203b450d01202c41206a212c203a41606a223a450d060c000b0b203741ffff034b0d04200e41aa016a213a200e41a8016a2f0100214941002139203d213b203c212c02400340203a202c460d012039202c203a412010e707223e4100476a2139203e450d01202c41206a212c203b41606a223b450d060c000b0b203941ffff034b0d04200e41cc016a213b200e41ca016a2f0100214a4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010e707223f4100476a213a203f450d01202c41206a212c203e41606a223e450d060c000b0b203a41ffff034b0d04200e41ee016a213e200e41ec016a2f0100214b4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010e70722404100476a213b2040450d01202c41206a212c203f41606a223f450d060c000b0b203b41ffff034b0d04200e4190026a213f200e418e026a2f0100214c4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010e70722414100476a213e2041450d01202c41206a212c204041606a2240450d060c000b0b203e41ffff034b0d04200e41b2026a2140200e41b0026a2f0100214d4100213f203d2141203c212c024003402040202c460d01203f202c2040412010e70722434100476a213f2043450d01202c41206a212c204141606a2241450d060c000b0b203f41ffff034b0d04200e41d4026a2141200e41d2026a2f0100214e41002140203d2143203c212c024003402041202c460d012040202c2041412010e70722454100476a21402045450d01202c41206a212c204341606a2243450d060c000b0b204041ffff034b0d04200e41f6026a2143200e41f4026a2f0100214f41002141203d2145203c212c024003402043202c460d012041202c2043412010e70722474100476a21412047450d01202c41206a212c204541606a2245450d060c000b0b204141ffff034b0d04200e4198036a2143200e4196036a2f010021474100212c024003402043203c460d01202c203c2043412010e70722454100476a212c2045450d01203c41206a213c203d41606a223d450d060c000b0b202c41ffff034b0d0402402004280298012232200428029401470d0020162032410110aa0120042802980121320b200428029001203241386c6a2232202c3b0134203220343b010420322033360200203241326a20473b0100203241306a20413b01002032412e6a204f3b01002032412c6a20403b01002032412a6a204e3b0100203241286a203f3b0100203241266a204d3b0100203241246a203e3b0100203241226a204c3b0100203241206a203b3b01002032411e6a204b3b01002032411c6a203a3b01002032411a6a204a3b0100203241186a20393b0100203241166a20493b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002006212c0c030b4102213220022802082233450d032002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a2234450d050c000b0b2003280208222c450d0341002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a2235450d050c000b0b203441ffff034b0d03200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a2238450d050c000b0b203541ffff034b0d03200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010e70722394100476a21362039450d01202c41206a212c203741606a2237450d050c000b0b203641ffff034b0d03200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010e707223a4100476a2138203a450d01202c41206a212c203941606a2239450d050c000b0b203841ffff034b0d03200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010e707223b4100476a2137203b450d01202c41206a212c203a41606a223a450d050c000b0b203741ffff034b0d03200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010e707223e4100476a2139203e450d01202c41206a212c203b41606a223b450d050c000b0b203941ffff034b0d03200e41cc016a213b200e41ca016a2f0100214b4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010e707223f4100476a213a203f450d01202c41206a212c203e41606a223e450d050c000b0b203a41ffff034b0d03200e41ee016a213e200e41ec016a2f0100214c4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010e70722404100476a213b2040450d01202c41206a212c203f41606a223f450d050c000b0b203b41ffff034b0d03200e4190026a213f200e418e026a2f0100214d4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010e70722414100476a213e2041450d01202c41206a212c204041606a2240450d050c000b0b203e41ffff034b0d03200e41b2026a2140200e41b0026a2f0100214e4100213f203d2141203c212c024003402040202c460d01203f202c2040412010e70722434100476a213f2043450d01202c41206a212c204141606a2241450d050c000b0b203f41ffff034b0d03200e41d4026a2141200e41d2026a2f0100214f41002140203d2143203c212c024003402041202c460d012040202c2041412010e70722454100476a21402045450d01202c41206a212c204341606a2243450d050c000b0b204041ffff034b0d03200e41f6026a2143200e41f4026a2f0100215041002141203d2145203c212c024003402043202c460d012041202c2043412010e70722474100476a21412047450d01202c41206a212c204541606a2245450d050c000b0b204141ffff034b0d03200e4198036a2145200e4196036a2f0100215141002143203d2147203c212c024003402045202c460d012043202c2045412010e70722494100476a21432049450d01202c41206a212c204741606a2247450d050c000b0b204341ffff034b0d03200e41ba036a2145200e41b8036a2f010021494100212c024003402045203c460d01202c203c2045412010e70722474100476a212c2047450d01203c41206a213c203d41606a223d450d050c000b0b202c41ffff034b0d03024020042802a401223220042802a001470d00201520324101109b0120042802a40121320b200428029c012032413c6c6a2232202c3b0138203220343b010420322033360200203241366a20493b0100203241346a20433b0100203241326a20513b0100203241306a20413b01002032412e6a20503b01002032412c6a20403b01002032412a6a204f3b0100203241286a203f3b0100203241266a204e3b0100203241246a203e3b0100203241226a204d3b0100203241206a203b3b01002032411e6a204c3b01002032411c6a203a3b01002032411a6a204b3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002014212c0c020b4102213220022802082233450d022002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a2234450d040c000b0b2003280208222c450d0241002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a2235450d040c000b0b203441ffff034b0d02200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a2238450d040c000b0b203541ffff034b0d02200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010e70722394100476a21362039450d01202c41206a212c203741606a2237450d040c000b0b203641ffff034b0d02200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010e707223a4100476a2138203a450d01202c41206a212c203941606a2239450d040c000b0b203841ffff034b0d02200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010e707223b4100476a2137203b450d01202c41206a212c203a41606a223a450d040c000b0b203741ffff034b0d02200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010e707223e4100476a2139203e450d01202c41206a212c203b41606a223b450d040c000b0b203941ffff034b0d02200e41cc016a213b200e41ca016a2f0100214c4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010e707223f4100476a213a203f450d01202c41206a212c203e41606a223e450d040c000b0b203a41ffff034b0d02200e41ee016a213e200e41ec016a2f0100214d4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010e70722404100476a213b2040450d01202c41206a212c203f41606a223f450d040c000b0b203b41ffff034b0d02200e4190026a213f200e418e026a2f0100214e4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010e70722414100476a213e2041450d01202c41206a212c204041606a2240450d040c000b0b203e41ffff034b0d02200e41b2026a2140200e41b0026a2f0100214f4100213f203d2141203c212c024003402040202c460d01203f202c2040412010e70722434100476a213f2043450d01202c41206a212c204141606a2241450d040c000b0b203f41ffff034b0d02200e41d4026a2141200e41d2026a2f0100215041002140203d2143203c212c024003402041202c460d012040202c2041412010e70722454100476a21402045450d01202c41206a212c204341606a2243450d040c000b0b204041ffff034b0d02200e41f6026a2143200e41f4026a2f0100215141002141203d2145203c212c024003402043202c460d012041202c2043412010e70722474100476a21412047450d01202c41206a212c204541606a2245450d040c000b0b204141ffff034b0d02200e4198036a2145200e4196036a2f0100215241002143203d2147203c212c024003402045202c460d012043202c2045412010e70722494100476a21432049450d01202c41206a212c204741606a2247450d040c000b0b204341ffff034b0d02200e41ba036a2147200e41b8036a2f0100215341002145203d2149203c212c024003402047202c460d012045202c2047412010e707224b4100476a2145204b450d01202c41206a212c204941606a2249450d040c000b0b204541ffff034b0d02200e41dc036a2147200e41da036a2f0100214b4100212c024003402047203c460d01202c203c2047412010e70722494100476a212c2049450d01203c41206a213c203d41606a223d450d040c000b0b202c41ffff034b0d02024020042802b001223220042802ac01470d0020132032410110910120042802b00121320b20042802a80120324106746a2232202c3b013c203220343b0104203220333602002032413a6a204b3b0100203241386a20453b0100203241366a20533b0100203241346a20433b0100203241326a20523b0100203241306a20413b01002032412e6a20513b01002032412c6a20403b01002032412a6a20503b0100203241286a203f3b0100203241266a204f3b0100203241246a203e3b0100203241226a204e3b0100203241206a203b3b01002032411e6a204d3b01002032411c6a203a3b01002032411a6a204c3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002005212c0c010b4102213220022802082233450d012002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010e70722354100476a21332035450d01202c41206a212c203441606a2234450d030c000b0b2003280208222c450d0141002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010e70722364100476a21342036450d01202c41206a212c203541606a2235450d030c000b0b203441ffff034b0d01200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010e70722374100476a21352037450d01202c41206a212c203841606a2238450d030c000b0b203541ffff034b0d01200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010e70722394100476a21362039450d01202c41206a212c203741606a2237450d030c000b0b203641ffff034b0d01200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010e707223a4100476a2138203a450d01202c41206a212c203941606a2239450d030c000b0b203841ffff034b0d01200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010e707223b4100476a2137203b450d01202c41206a212c203a41606a223a450d030c000b0b203741ffff034b0d01200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010e707223e4100476a2139203e450d01202c41206a212c203b41606a223b450d030c000b0b203941ffff034b0d01200e41cc016a213b200e41ca016a2f0100214c4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010e707223f4100476a213a203f450d01202c41206a212c203e41606a223e450d030c000b0b203a41ffff034b0d01200e41ee016a213e200e41ec016a2f0100214e4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010e70722404100476a213b2040450d01202c41206a212c203f41606a223f450d030c000b0b203b41ffff034b0d01200e4190026a213f200e418e026a2f0100214f4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010e70722414100476a213e2041450d01202c41206a212c204041606a2240450d030c000b0b203e41ffff034b0d01200e41b2026a2140200e41b0026a2f010021504100213f203d2141203c212c024003402040202c460d01203f202c2040412010e70722434100476a213f2043450d01202c41206a212c204141606a2241450d030c000b0b203f41ffff034b0d01200e41d4026a2141200e41d2026a2f0100215141002140203d2143203c212c024003402041202c460d012040202c2041412010e70722454100476a21402045450d01202c41206a212c204341606a2243450d030c000b0b204041ffff034b0d01200e41f6026a2143200e41f4026a2f0100215241002141203d2145203c212c024003402043202c460d012041202c2043412010e70722474100476a21412047450d01202c41206a212c204541606a2245450d030c000b0b204141ffff034b0d01200e4198036a2145200e4196036a2f0100215341002143203d2147203c212c024003402045202c460d012043202c2045412010e70722494100476a21432049450d01202c41206a212c204741606a2247450d030c000b0b204341ffff034b0d01200e41ba036a2147200e41b8036a2f0100215441002145203d2149203c212c024003402047202c460d012045202c2047412010e707224b4100476a2145204b450d01202c41206a212c204941606a2249450d030c000b0b204541ffff034b0d01200e41dc036a2149200e41da036a2f0100215541002147203d214b203c212c024003402049202c460d012047202c2049412010e707224d4100476a2147204d450d01202c41206a212c204b41606a224b450d030c000b0b204741ffff034b0d01200e41fe036a2149200e41fc036a2f0100214d4100212c024003402049203c460d01202c203c2049412010e707224b4100476a212c204b450d01203c41206a213c203d41606a223d450d030c000b0b202c41ffff034b0d01024020042802bc01223220042802b801470d00201220324101109f0120042802bc0121320b20042802b401203241c4006c6a2232202c3b0140203220343b0104203220333602002032413e6a204d3b01002032413c6a20473b01002032413a6a20553b0100203241386a20453b0100203241366a20543b0100203241346a20433b0100203241326a20533b0100203241306a20413b01002032412e6a20523b01002032412c6a20403b01002032412a6a20513b0100203241286a203f3b0100203241266a20503b0100203241246a203e3b0100203241226a204f3b0100203241206a203b3b01002032411e6a204e3b01002032411c6a203a3b01002032411a6a204c3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002011212c0b202c202c28020041016a3602000240202d450d00202d41226c450d00200e10290b2001200f460d040c010b200041013a0000200020323a00010240202d450d00202d41226c450d00200e10290b0240200f2001460d0003400240200141046a280200220e450d00200e41226c450d00200128020010290b2001412c6a2101200d41546a220d0d000b0b02402010450d002010412c6c450d00200c10290b20041087020c040b200d41546a210d2001210e0c000b0b200f2001460d0003402001220d412c6a21010240200d41046a280200220e450d00200e41226c450d00200d28020010290b200f2001470d000b0b02402010450d002010412c6c450d00200c10290b200041046a200441c00110e4071a200041003a00000b20044180026a24000bdb0401097f230041c0016b2202240020024188016a200110db01200241306a200228028801220320022802900110e20120024198016a41086a2204200241ec006a29020037030020024198016a41106a2205200241f4006a29020037030020024198016a41186a2206200241fc006a29020037030020024198016a41206a220720024184016a2802003602002002200241e4006a290200370398010240024020022802502208450d00200241e0006a2802002109200241dc006a280200210a20022802542101200241086a41206a2007280200360200200241086a41186a2006290300370300200241086a41106a2005290300370300200241086a41086a200429030037030020022002290398013703080240200228028c01450d00200310290b200241306a41106a200241086a41106a290300370300200241306a41086a200241086a41086a290300370300200241306a41186a200241086a41186a290300370300200241306a41206a200241086a41206a28020036020020024198016a41086a2002413c6a29020037030020024198016a41106a200241c4006a29020037030020024198016a41186a200241cc006a29020037030020022002290308370330200220022902343703980102402001450d00200141186c450d00200810290b0240200941ffffffff0371450d00200a10290b2000200229039801370001200041196a200241b0016a290300370000200041116a200241a8016a290300370000200041096a200241a0016a290300370000410121010c010b0240200228028c01450d00200310290b410021010b200020013a0000200241c0016a24000b8b4917047f017e017f017e047f017e027f017e067f017e017f017e027f017e037f027e027f037e017f017e047f017e017f23004180046b22062400200641f8026a41186a22074200370300200641f8026a41106a22084200370300200641f8026a41086a22094200370300200642003703f80241eebec500ad4280808080f00084220a1001220b290000210c200641a8026a41086a220d200b41086a2900003703002006200c3703a802200b10292009200d290300370300200620062903a8023703f80241eab8c000ad42808080809002841001220b290000210c200641b8026a41086a220e200b41086a2900003703002006200c3703b802200b1029200820062903b802220c370300200641b8036a41086a220b2009290300370300200641b8036a41106a220f200c370300200641b8036a41186a2210200e290300370300200620062903f8023703b803200641e0016a200641b8036a10b1010240024020062802e001417d71450d00420121110c010b200742003703002008420037030020094200370300200642003703f802200a10012212290000210c200d201241086a2900003703002006200c3703a802201210292009200d290300370300200620062903a8023703f80241a8fac100ad4280808080b002841001220d290000210c200e200d41086a2900003703002006200c3703b802200d1029200820062903b802370000200841086a200e290300370000200b2009290300370300200f200829030037030020102007290300370300200620062903f8023703b803200641203602bc022006200641b8036a3602b802200641e8016a200641b8036aad4280808080800484220a1007108b020240024020062802e80122090d00410021130c010b20062802ec01210b02400240200641f0016a2802004104490d00410121132009280000220f418194ebdc03490d010b41002113200641003602900220064201370388022006410d3602e4032006200641b8026a3602e003200620064188026a3602a8022006418c036a4101360200200642013702fc02200641f4eaca003602f8022006200641e0036a36028803200641a8026a41a8a3c800200641f8026a10371a200635029002422086200635028802841008200628028c02450d0020062802880210290b200b450d00200910290b42002111200641f8026a41186a220e4200370300200641f8026a41106a220d4200370300200641f8026a41086a22094200370300200642003703f80241eebec500ad4280808080f000841001220b290000210c200641a8026a41086a2207200b41086a2900003703002006200c3703a802200b102920092007290300370300200620062903a8023703f80241f0f5c100ad42808080809001841001220b290000210c200641b8026a41086a2207200b41086a2900003703002006200c3703b802200b1029200820062903b802370000200841086a2007290300370000200641b8036a41086a2009290300370300200641b8036a41106a200d290300370300200641b8036a41186a200e290300370300200620062903f8023703b803200641f8026a200641b8036a10d00142c0f0f50b211420062903f8024202510d00200641f8026a200d280200221510da01200641d8016a20062802f802220b20062802800310fc0120062802dc01210d20062802d8012109024020062802fc02450d00200b10290b024002400240024020090d0041e5a4c200ad4280808080e0068410084100201541646a2209200920154b1b2116428084afdf002114201521170c010b4100201541646a2209200920154b1b2116428084afdf0021140240200d20054b0d00201521170c010b200641f8026a41186a220d4200370300200641f8026a41106a220e4200370300200641f8026a41086a22094200370300200642003703f80241eebec500ad4280808080f000841001220b290000210c200641a8026a41086a2207200b41086a2900003703002006200c3703a802200b102920092007290300370300200620062903a8023703f80241f0fbc100ad4280808080a001841001220b290000210c200641b8026a41086a2207200b41086a2900003703002006200c3703b802200b1029200820062903b802370000200841086a2007290300370000200641b8036a41086a2009290300370300200641b8036a41106a200e290300370300200641b8036a41186a200d290300370300200620062903f8023703b803200641f8026a200641b8036a10f80120062802f8022209410420091b220e20062902fc02420020091b220c422088a741037422096a210b03402009450d02200941786a2109200b417c6a210d200b41786a210b200d28020020054b0d000b200e20096a280200211742c0f4a4eb002114200c42ffffffff0183500d00200e10290b42002111200641f8026a41186a22184200370300200641f8026a41106a22194200370300200641f8026a41086a221a4200370300200642003703f80241eebec500ad4280808080f00084221b10012209290000210c200641a8026a41086a221c200941086a2900003703002006200c3703a80220091029201a201c290300370300200620062903a8023703f80241b0fec100ad4280808080e00284220c10012209290000211d200641b8026a41086a221e200941086a2900003703002006201d3703b80220091029200820062903b802370000200841086a2209201e290300370000200641b8036a41086a2210201a290300370300200641b8036a41106a22122019290300370300200641b8036a41186a221f2018290300370300200620062903f8023703b803200641d0016a200641b8036a412010fc0120062802d401210d20062802d001210e2018420037030020194200370300201a4200370300200642003703f802201b1001220b290000211d201c200b41086a2900003703002006201d3703a802200b1029201a201c290300370300200620062903a8023703f802200c1001220b290000210c201e200b41086a2900003703002006200c3703b802200b1029200820062903b8023700002009201e2903003700002010201a29030037030020122019290300370300201f2018290300370300200620062903f8023703b8032006200d2015200e4101461b3602f802200a200641f8026aad221d4280808080c0008410032018420037030020194200370300201a4200370300200642003703f802201b1001220b290000210c201c200b41086a2900003703002006200c3703a802200b1029201a201c290300370300200620062903a8023703f80241f4f3c100ad4280808080d001841001220b290000210c201e200b41086a2900003703002006200c3703b802200b1029200820062903b8023700002009201e2903003700002010201a29030037030020122019290300370300201f2018290300370300200620062903f8023703b803200641f8026a200641b8036a108d0220062902fc02420020062802f80222081b21202008410120081b212120042002200220044b1b2222450d01200f410020131b2123200641a8036aad4280808080c000842124201d428080808080028421252020422088a74105742126200641a8036a41046a2127200641e0036a41086a21044100211303402001201341e0006c6a210d03402013220e41016a21132001200e41e0006c6a21072026210920212108024003402009450d010240200d2008460d0020082007412010e707210b200941606a2109200841206a2108200b0d010b0b200d41e0006a210d20132022490d010c040b0b2003200e4102746a2802002108200642003703b002200642003703a802200641c0016a2007290320220c200741286a290300428094ebdc03420010e007200641a0016a2007290330220a200741386a290300428094ebdc03420010e007200641b0016a20062903c001221d200641c0016a41086a29030022284280ec94a37c427f10d507200641f0006a201d20282008ad2229420010d50720064190016a20062903a001221d200641a0016a41086a29030022284280ec94a37c427f10d50720064180016a201d20282029420010d507200642003703c002200642003703b8022029200a2006290390017c7e221d428094ebdc0380212802400240024002400240200629037042002029200c20062903b0017c7e220c428094ebdc0380220aa7417f200c428080808080c0b2cd3b541b200c200a4280ec94a37c7e7c4280cab5ee01566a2209ad7d85200641f0006a41086a29030042002009410047ad7d8584500d00200629038001210a20064180016a41086a290300212a200641e8016a2017200710d60120062802e8012109200620062802f001220b3602f403200620093602f00320064188026a200bad4220862009ad841007108b0202400240200628028802220b0d004200210c0c010b200628028c02210e0240024020062802900222054104490d00200b280000220d418094ebdc034b0d004201210c2005417c6a410f4b0d010b200641003602c003200642013703b8032006410d3602e4032006200641f0036a3602e0032006200641b8036a3602a8032006410136028c03200642013702fc02200641f4eaca003602f8022006200641e0036a36028803200641a8036a41a8a3c800200641f8026a10371a20063502c00342208620063502b803841008024020062802bc03450d0020062802b80310290b4200210c202b210d0b0240200e450d00200b10290b200d212b0b024020062802ec01450d00200910290b2008202b4100200c4200521b220f4d0d02200641f8026a2017200710d601200635028003212c20062802f802210b4110102722090d010c040b200642003703f001200642003703e80120064200370390022006420037038802200641f0036a200710dc01200641b8036a20062802f003220920062802f80310e00120042010280200360200200620062903b8033703e003024020062802c4032208450d00200641a8036a41086a2004280200360200200620062903e0033703a80320062903c803210c0b024020062802f403450d00200910290b0240024020080d00200642003703c80320064280808080c0003703c003200620163602bc03200641003602b803200641f0036a200710dc0120062802f0032108200620062802f8033602e403200620083602e003200641b8036a200641e0036a108e02024020062802f403450d00200810290b20042010280200360200200620062903b8033703e00320062903c803210c410421080c010b2004200641a8036a41086a280200360200200620062903a8033703e0030b201a20062903e003370200201a41086a2004280200360200200641003a00a403200620073602fc02200620163602f802200620233602a0032006200c370390032006200836028c03200620064188026a36029c032006200641e8016a36029803200641b8036a200641f8026a2017108f02024020062802c0034102460d0020062802b803200628028003470d00201a201510880121082006410120062d00a40320081b22083a00a403200641b8036a200710de0120063502c00342208620062802b8032209ad841004024020062802bc03450d00200910290b200641b8036a200710d90120063502c00342208620062802b8032209ad841004024020062802bc03450d00200910290b0240200710900241ff017122094102460d002009410171450d0010e8010b200841ff0171450d00200628029403220f41027421084101210d200628028c032109200628028003210220062802f80221052006280284032207210b02400340024020080d00200620072005200720054b1b360284030c020b200d417f6a210d2008417c6a2108200b20054b210e200b20092802006b210b200941046a2109200e0d000b200f21080240200f200e200d6b2209490d002006200936029403200921080b200620072005200720054b1b3602840341000d002002200f6b2209200220086b4f0d00200f20086b210b20062802fc0221080340201f200841186a2900003703002012200841106a2900003703002010200841086a290000370300200620082900003703b803200620093602d803200641f0036a200641b8036a10dd0120063502f80342208620062802f003220dad841004024020062802f403450d00200d10290b200941016a2109200b417f6a220b0d000b0b200641b8036a20062802fc0210dc0120062802b8032108200620062802c0033602f403200620083602f003201a200641f0036a108e0220062802bc03450d00200810290b20062802900341ffffffff0371450d01200628028c0310290c010b200920083600000240200941104120102b2208450d002008200a2028a7417f201d428080808080c0b2cd3b541b201d20284280ec94a37c7e7c4280cab5ee01566aad7c220c3700042008410c6a202a200c200a54ad7c221d370000202c422086200bad842008ad4280808080c00284100320081029024020062802fc02450d00200b10290b20064188026a200710dc01200641b8036a200628028802220920062802900210e00120042010280200360200200620062903b8033703e003024020062802c4032208450d00200641e8016a41086a2004280200360200200620062903e0033703e80120062903c803210a0b0240200628028c02450d00200910290b0240024020080d00200642003703c80320064280808080c0003703c003200620163602bc03200641003602b80320064188026a200710dc01200628028802210820062006280290023602f403200620083602f003200641b8036a200641f0036a108e020240200628028c02450d00200810290b200641f0036a41086a2010280200360200200620062903b8033703f00320062903c803210a410421080c010b200641f0036a41086a200641e8016a41086a280200360200200620062903e8013703f0030b201a20062903f003370200201a41086a222d200641f0036a41086a280200360200200641003a00a403200620073602fc02200620163602f802200620233602a0032006200a370390032006200836028c032006200641b8026a36029c032006200641a8026a36029803200641e8006a200641f8026a2017200c201d10910202400240024020062802684101470d00200628026c200628028003460d010b20062d00a40321080c010b201a201510880121082006410120062d00a40320081b22083a00a403200641b8036a200710de0120063502c00342208620062802b8032209ad841004024020062802bc03450d00200910290b200641b8036a200710d90120063502c00342208620062802b8032209ad841004024020062802bc03450d00200910290b200710900241ff017122094102460d002009410171450d0010e8010b0240200841ff0171450d00200628029403222e41027421084101210d200628028c032109200628028003212f20062802f80221052006280284032202210b02400340024020080d00200620022005200220054b1b360284030c020b200d417f6a210d2008417c6a2108200b20054b210e200b20092802006b210b200941046a2109200e0d000b202e21080240202e200e200d6b2209490d002006200936029403200921080b200620022005200220054b1b3602840341000d00202f202e6b2209202f20086b4f0d00202e20086b210b20062802fc0221080340201f200841186a2900003703002012200841106a2900003703002010200841086a290000370300200620082900003703b803200620093602d80320064188026a200641b8036a10dd01200635029002422086200628028802220dad8410040240200628028c02450d00200d10290b200941016a2109200b417f6a220b0d000b0b200641b8036a20062802fc0210dc0120062802b8032108200620062802c00336028c022006200836028802201a20064188026a108e0220062802bc03450d00200810290b024020062802900341ffffffff0371450d00200628028c0310290b200641003602d002200642083703c802200642003703f001200642003703e801200641c8026a4100200741c8006a220828020010900102400240200828020022080d004200210a20062802d002210e20062802c802210d4200211d0c010b20072802402202200841306c6a2130200fad212a034020064200370390022006420037038802200641c0006a2002290300221d200241086a290300428094ebdc03420010e007200641306a2006290340220c200641c0006a41086a290300220a4280ec94a37c427f10d507200641206a200c200a202a420010d507200641106a200c200a2029420010d507200641f8026a2017200241106a220f10d501200641d0006a20062802f802220920062802800310e3014200200641106a41086a2903002006290310220a2029201d20062903307c221d7e220c428094ebdc03802228a7417f200c428080808080c0b2cd3b541b200c20284280ec94a37c7e7c4280cab5ee01566aad7c220c200a54ad7c220a200641206a41086a29030020062903202228202a201d7e221d428094ebdc0380222ca7417f201d428080808080c0b2cd3b541b201d202c4280ec94a37c7e7c4280cab5ee01566aad7c221d202854ad7c7d200c201d54ad7d2228200c201d7d221d200c562028200a562028200a511b22081b210a4200201d20081b210c200641d0006a41106a290300211d2006290358212820062802502108024020062802fc02450d00200910290b200641b8036a2017200f10d50120062802b803210920063502c003212c20062028420020081b2228200c7c220c3703f8022006201d420020081b200a7c200c202854ad7c220a37038003202c4220862009ad8420251003024020062802bc03450d00200910290b200641f0036a200f10dc01200641b8036a20062802f003220920062802f80310e00120042010280200360200200620062903b8033703e003024020062802c4032208450d00200641a8036a41086a2004280200360200200620062903e0033703a80320062903c80321310b024020062802f403450d00200910290b0240024020080d00200642003703c80320064280808080c0003703c003200620163602bc03200641003602b803200641f0036a200f10dc0120062802f0032108200620062802f8033602e403200620083602e003200641b8036a200641e0036a108e02024020062802f403450d00200810290b20042010280200360200200620062903b8033703e00320062903c803211d410421080c010b2004200641a8036a41086a280200360200200620062903a8033703e0032031211d0b201a20062903e003370200202d2004280200360200200641003a00a4032006200f3602fc02200620163602f802200620233602a0032006201d370390032006200836028c03200620064188026a36029c032006200641e8016a36029803200641086a200641f8026a2017200c200a1091020240024020062802084101470d00200628020c200628028003470d00201a201510880121082006410120062d00a40320081b22083a00a4030c010b20062d00a40321080b0240200841ff0171450d00200628029403222f41027421084101210d200628028c032109200628028003213220062802f8022105200628028403222e210b02400340024020080d002006202e2005202e20054b1b360284030c020b200d417f6a210d2008417c6a2108200b20054b210e200b20092802006b210b200941046a2109200e0d000b202f21080240202f200e200d6b2209490d002006200936029403200921080b2006202e2005202e20054b1b3602840341000d002032202f6b2209203220086b4f0d00202f20086b210b20062802fc0221080340201f200841186a2900003703002012200841106a2900003703002010200841086a290000370300200620082900003703b803200620093602d803200641f0036a200641b8036a10dd0120063502f80342208620062802f003220dad841004024020062802f403450d00200d10290b200941016a2109200b417f6a220b0d000b0b200641b8036a20062802fc0210dc0120062802b8032108200620062802c0033602f403200620083602f003201a200641f0036a108e0220062802bc03450d00200810290b024020062802900341ffffffff0371450d00200628028c0310290b200241306a2102200f41086a290000210c200f290000210a2018200f41186a2900003703002019200f41106a290000370300201a200c3703002006200a3703f80220064188026a41086a290300210c200629038802210a024020062802d002220920062802cc02470d00200641c8026a2009410110900120062802d00221090b20062802c802220d200941306c6a2208200a370320200820062903f802370300200841286a200c370300200841086a201a290300370300200841106a2019290300370300200841186a20182903003703002006200941016a220e3602d00220022030470d000b200641e8016a41086a290300211d20062903e801210a0b201c290300212820062903a802210c200641e8016a41086a2208200741086a290300370300200641e8016a41106a2209200741106a290300370300200641e8016a41186a220b200741186a290300370300200620072903003703e801200d450d01201e290300212920062903b802212a20062802cc02212f20064188026a41186a2202200b29030037030020064188026a41106a222e200929030037030020064188026a41086a22322008290300370300200620062903e80137038802024002402007280258220541ffffff3f712005470d002005410574220b417f4c0d002007280250210802400240200b0d00410121090c010b200b10272209450d060b2006410036028003200620093602f8022006200b4105763602fc02200641f8026a41002005109e01200628028003210f0240024020050d0020062802f80221300c010b20062802f8022230200f4105746a2109034020092008290000370000200941186a200841186a290000370000200941106a200841106a290000370000200941086a200841086a290000370000200941206a2109200841206a2108200b41606a220b0d000b200541057441606a410576200f6a41016a210f0b20062802fc02212d201f20022903003703002012202e2903003703002010203229030037030020062006290388023703b803201b10012208290000212c201c200841086a2900003703002006202c3703a802200810294198fbc100ad428080808080028410012208290000212c201e200841086a2900003703002006202c3703b80220081029200620153602a80320062024100222082900003703e003200810292006202736028403200620043602fc022006200641a8036a360280032006200641e0036a3602f802200641f0036a200641f8026a107520062802f803220741206a2209417f4c0d0020062802f00321020240024020090d0041002108410121050c010b200910272205450d06200921080b024002402008410f4d0d002008210b0c010b2008410174220b4110200b41104b1b220b4100480d02024020080d00200b102722050d010c040b2008200b460d0020052008200b102b2205450d030b200520062903a802370000200541086a201c29030037000002400240200b4170714110460d00200b21080c010b200b41017422084120200841204b1b22084100480d02200b2008460d002005200b2008102b2205450d030b200520062903b802370010200541186a201e29030037000002400240200841606a2007490d002008212e0c010b2007415f4b0d022008410174220b2009200b20094b1b222e4100480d022008202e460d0020052008202e102b2205450d030b200c200a7c220a200c542108200541206a2002200710e4071a024020062802f403450d00200210290b200ead210c2028201d7c211d2008ad2128200641f8026a2005200910fe010240024020062802f80222070d0041002102200641003602c002200642083703b802410821074100210b0c010b200620062902fc02222c3702bc02200620073602b802202c422088a7210b202ca721020b200c42c097e8b2017e210c201d20287c211d2018201f29030037030020192012290300370300201a2010290300370300200620062903b8033703f8020240200b2002470d00200641b8026a200b4101108c0120062802bc02210220062802b802210720062802c002210b0b200c20147c210c2007200b41d8006c22326a2208200a370310200820293703082008202a3703002008203036022c2008200d360220200841186a201d370300200841346a200f360200200841306a202d360200200841286a200e360200200841246a202f360200200820062903f802370338200841c0006a201a290300370300200841c8006a2019290300370300200841d0006a20182903003703002006200b41016a22083602c0020240024020070d002009ad4220862005ad8410040c010b200641f8026a2007200810ed012009ad4220862005ad8420063502800342208620062802f8022209ad841003024020062802fc02450d00200910290b02402008450d00200741306a2108203241d8006a210903400240200841746a280200220b450d00200b41306c450d00200841706a28020010290b0240200828020041ffffff3f71450d002008417c6a28020010290b200841d8006a2108200941a87f6a22090d000b0b2002450d00200241d8006c450d00200710290b200c42c097e8b2017c210c0240202e450d00200510290b200c42c0b2cd3b7c21140c040b1038000b1032000b1030000b201442808c8d9e027c21140b20132022490d010c030b0b1039000b4200211142c0d1e1232114200c42ffffffff0183500d01200e10290c010b202042ffffff3f83500d00202110290b200020143703082000201137030020064180046a24000bb10201067f230041206b22022400024002402001422088a722030d00410121040c010b2001a721040b200220033602142002200436021002402003450d0020042d0000210520022003417f6a3602142002200441016a360210200541014b0d0041002106024002400240024020050e020100010b200241086a200241106a10c80120022802080d0320022802142205200228020c2203490d032003417f4c0d010240024020030d0042002101410121060c010b2003102d2206450d03200620022802102207200310e4071a2002200520036b3602142002200720036a3602102003ad21010b2006450d0320012003ad4220868421010b200020013702042000200636020020041029200241206a24000f0b1038000b1039000b41e891cc00412e200241186a419893cc00419892cc00103a000bbd0101047f230041106b22022400200028020421032000280200210041012104200128021841acb9c40041012001411c6a28020028020c1100002105200241003a0005200220053a00042002200136020002402003450d0003402002200036020c20022002410c6a41c0a3c80010631a200041016a21002003417f6a22030d000b20022d000421050b0240200541ff01710d0020022802002200280218419cc9c00041012000411c6a28020028020c11000021040b200241106a240020040bbf0201027f230041e0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b0202400240200228021022010d00200041003602000c010b200228021421032002200241106a41086a28020036022420022001360220200241c8006a200241206a1096020240024020022802480d0020024100360230200242013703282002410d36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241f4eaca003602482002200241386a360258200241c4006a41a8a3c800200241c8006a10371a200235023042208620023502288410080240200228022c450d00200228022810290b200041003602000c010b20002002290348370200200041086a200241c8006a41086a2802003602000b2003450d00200110290b200241e0006a24000b8f0301067f230041106b220224002002410036020820024201370300200028020021030240410410272204450d002004200336000020024284808080c0003702042002200436020020002802042103200441044108102b2204450d00200420033600042002428880808080013702042002200436020020002802082103200441084110102b2204450d002004200336000820024290808080c00137020420022004360200200028020c2105200041146a28020022002002107102400240024020022802042206200228020822046b20004102742203490d0020022802002100200621070c010b200420036a22002004490d01200641017422072000200720004b1b22074100480d010240024020060d00024020070d00410121000c020b2007102722000d010c040b2002280200210020062007460d00200020062007102b2200450d030b20022007360204200220003602000b200020046a2005200310e4071a2001290200200420036aad4220862000ad84100302402007450d00200010290b200241106a24000f0b1032000b1030000bbd0101057f2001280208210302402001410c6a280200220420024b0d002000410036020820002004ad4220862003ad843702000f0b024002402001411c6a2802002205450d00200141146a2802002101200541027421062003417f6a2103034002402004200128020022076b220520024b0d00200420024b0d030b200141046a21012003417f6a2103200521042006417c6a22060d000b0b200041023602080f0b2000200736020c2000410136020820002005ad4220862003ad843702000b8d0e07047f017e047f017e047f017e017f23004190016b22012400200141e0006a41186a4200370300200141e0006a41106a22024200370300200141e0006a41086a220342003703002001420037036041b1dcc900ad4280808080f000841001220429000021052003200441086a290000370300200120053703602004102941b8dcc900ad4280808080a00184100122042900002105200141d0006a41086a2206200441086a2900003703002001200537035020041029200220012903502205370300200141306a41086a2003290300370300200141306a41106a2005370300200141306a41186a200629030037030020012001290360370330200141e0006a200141306a108d0220012802602203410120031b210741022108024002402001290264420020031b2205422088a72203450d002003410574210241002104200721030240034020002003460d01200420032000412010e70722064100476a21042006450d01200341206a2103200241606a22020d000c020b0b200141e0006a41186a4200370300200141e0006a41106a22094200370300200141e0006a41086a220042003703002001420037036041b1dcc900ad4280808080f0008410012202290000210a200141d0006a41086a2203200241086a2900003703002001200a370350200210292000200329030037030020012001290350370360419887ca00ad4280808080a0028410012202290000210a2003200241086a2900003703002001200a3703502002102920092001290350220a370300200141306a41086a2000290300370300200141306a41106a200a370300200141306a41186a200329030037030020012001290360370330200141206a200141306a108f030240024002402001280220220b0d004100210c20014100360218200142043703104104210b4100210d410021030c010b2001290224210a2001200b3602102001200a370214200aa7210d4100210302400240200a422088a7220c41014b0d00200c0e020201020b200c2100034020032000410176220220036a22062004200b20064102746a280200491b2103200020026b220041014b0d000b0b4100210802402004200b20034102746a2802002200470d00410021060c020b2003200420004b6a21030b200141e0006a41186a22084200370300200141e0006a41106a220e4200370300200141e0006a41086a220242003703002001420037036041b1dcc900ad4280808080f0008410012206290000210a200141d0006a41086a2200200641086a2900003703002001200a37035020061029200220002903003703002001200129035037036041b8dcc900ad4280808080a0018410012206290000210a2000200641086a2900003703002001200a3703502006102920092001290350370000200941086a2000290300370000200141306a41086a2002290300370300200141306a41106a200e290300370300200141306a41186a20082903003703002001200129036037033041002100200141d4006a41003a000020014100360250200141086a200141306a4120200141d0006a4105410010c70102402001280208450d002001200128020c2200410520004105491b3602642001200141d0006a3602602001200141e0006a10c8014100200128020420012802001b21000b20002000418094ebdc036e22024180ec94a37c6c6aad4280fd87d1007e220f428094ebdc0380210a200c2003490d0220024180fd87d1006c200f200a4280ec94a37c7e7c4280cab5ee015672200aa76a21020240200c200d470d00200141106a200d41011098012001280214210d2001280210210b0b200b20034102746a220041046a2000200c20036b41027410e5071a20002004360200410121062001200c41016a220c360218200c20024b21080b200141e0006a41186a220e4200370300200141e0006a41106a22104200370300200141e0006a41086a220042003703002001420037036041b1dcc900ad4280808080f0008410012202290000210a200141d0006a41086a2203200241086a2900003703002001200a370350200210292000200329030037030020012001290350370360419887ca00ad4280808080a0028410012202290000210a2003200241086a2900003703002001200a3703502002102920092001290350370000200941086a2003290300370000200141306a41086a2000290300370300200141306a41106a2010290300370300200141306a41186a200e2903003703002001200129036037033002400240200b0d00200141306aad428080808080048410040c010b200141203602642001200141306a360260200b200c200141e0006a10a304200d41ffffffff0371450d00200b10290b2006450d00200141e8006a2004ad37030020014102360260200141e0006a10e1062001410136026020012004360264200141e0006a10d0030b0240200542ffffff3f83500d00200710290b20014190016a240020080f0b2003200c1041000b9a0d04047f017e027f067e230041d0026b22052400200541c8016a20012002108f0202400240024002400240024020052802d0014102460d0020052802c8012106200541c8016a41086a2001280204220741086a290000370300200541c8016a41106a200741106a290000370300200541c8016a41186a200741186a290000370300200520063602e801200520072900003703c801200541f0016a200541c8016a10dd0120052802f0012108200520052802f801220736028402200520083602800220054188026a2007ad4220862008ad841007108b020240024020052802880222070d00420021090c010b200528028c02210a02400240024020054188026a41086a280200220b4110490d00200b4170714110470d010b200541003602a00220054201370398022005410d3602ac02200520054180026a3602a802200520054198026a3602b402200541cc026a4101360200200542013702bc02200541f4eaca003602b8022005200541a8026a3602c802200541b4026a41a8a3c800200541b8026a10371a20053502a0024220862005350298028410080240200528029c02450d0020052802980210290b420021090c010b200741186a290000210c200741086a290000210d2007290010210e2007290000210f420121090b200a450d00200710290b200d4200200942005222071b210d200f420020071b210f024020052802f401450d00200810290b200c420020071b210c200e420020071b210e200f200354200d200454200d2004511b0d01200f200385200d2004858450450d03200541b8016a20032004428094ebdc03420010e007200541a8016a20052903b801220d200541b8016a41086a290300220f4280ec94a37c427f10d50720054198016a200d200f20013502282209420010d50720054188016a4200200529039801220f200920052903a80120037c7e220d428094ebdc03802209a7417f200d428080808080c0b2cd3b541b200d20094280ec94a37c7e7c4280cab5ee01566aad7c220d200e7d22092009200d5620054198016a41086a290300200d200f54ad7c220f200c7d200d200e54ad7d220d200f56200d200f511b22021b220f4200200d20021b428094ebdc03420010e007200541f8006a200529038801220d20054188016a41086a29030022094280ec94a37c427f10d507200541e8006a200d20094280cab5ee01420010d507200541e8006a41086a29030020052903682209200f20052903787c220d420188220fa7417f200d4280cab5ee017e220d428080808080c0b2cd3b541b200d200f4280ec94a37c7e7c4280cab5ee01566aad7c220d200954ad7c210f410021020c020b410021010c040b200541c8006a20032004428094ebdc03420010e007200541d8006a20032004428094ebdc03420010d607200541386a2005290348200541c8006a41086a29030020013502282209420010d507200541286a420020052903382210200920052903587e2209428094ebdc03802211a7417f2009428080808080c0b2cd3b541b200920114280ec94a37c7e7c4280cab5ee01566aad7c2209200e7d22112011200956200541386a41086a2903002009201054ad7c2210200c7d2009200e54ad7d220920105620092010511b22071b22104200200920071b428094ebdc03420010e007200541186a20052903282209200541286a41086a29030022114280ec94a37c427f10d507200541086a200920114280cab5ee01420010d507200128022422072003200f7d220920072903007c2211370300200741086a22072004200d7d2003200f54ad7d20072903007c2011200954ad7c370300200141106a2207200728020022072002200720024b1b360200200541086a41086a2903002005290308220f201020052903187c220d4201882209a7417f200d4280cab5ee017e220d428080808080c0b2cd3b541b200d20094280ec94a37c7e7c4280cab5ee01566aad7c220d200f54ad7c210f410121020b02400240200d200f84500d002001280220220220022903002209200d7c2210370300200241086a22022002290300200f7c2010200954ad7c370300200c200f7c200e200d7c220d200e54ad7c210c200d210e0c010b2002450d010b200141013a002c200541b8026a200541c8016a10dd0120053502c002210d20052802b8022102411010272201450d012001200337000020012004370008200141104120102b2201450d012001200e370010200141186a200c370000200d4220862002ad842001ad428080808080048410032001102920052802bc02450d00200210290b410121010c010b1030000b2000200636020420002001360200200541d0026a24000bfc0403027f017e057f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941e0f9c100ad4280808080e00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bfc0403027f017e057f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941f4f8c100ad4280808080b00284100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000ba65a0f047f017e017f017e027f017e057f027e017f017e037f017e087f047e047f230041d0046b22022400200241e0006a41186a22034200370300200241e0006a41106a22044200370300200241e0006a41086a220542003703002002420037036041eebec500ad4280808080f000842206100122072900002108200241e0026a41086a2209200741086a290000370300200220083703e0022007102920052009290300370300200220022903e00237036041c4f5c100ad4280808080a0018422081001220a290000210b200241a0036a41086a2207200a41086a2900003703002002200b3703a003200a1029200420022903a003220b37030020024180046a41086a220c200529030037030020024180046a41106a220d200b37030020024180046a41186a220e20072903003703002002200229036037038004200241306a20024180046a412010fc012002280230210f200228023421102003420037030020044200370300200542003703002002420037036020061001220a290000210b2009200a41086a2900003703002002200b3703e002200a102920052009290300370300200220022903e00237036020081001220a29000021082007200a41086a290000370300200220083703a003200a1029200420022903a0032208370300200c2005290300370300200d2008370300200e2007290300370300200220022903603703800441012105410021032002201041016a4100200f1b220a36026020024180046aad42808080808004842211200241e0006aad22124280808080c00084100320061001220d29000021062009200d41086a290000370300200220063703e002200d102941b8f6c100ad4280808080d002841001220929000021062007200941086a290000370300200220063703a003200910292002200a3602e0032002200241e0036aad4280808080c00084100222092900003703800420091029200241ec006a200241e4036a3602002002200c3602642002200241e0036a360268200220024180046a360260200241a0026a200241e0006a107502400240024002400240024002400240024002400240024002400240024020022802a802220d41206a220c417f4c0d0020022802a002210e0240200c450d00200c10272205450d07200c21030b024002402003410f4d0d00200321070c010b200341017422094110200941104b1b22074100480d0b024020030d002007102722050d010c100b20032007460d00200520032007102b2205450d0f0b200520022903e002370000200541086a200241e0026a41086a2903003700000240024020074170714110460d00200721090c010b200741017422094120200941204b1b22094100480d0b20072009460d00200520072009102b2205450d0f0b200520022903a003370010200541186a200241a0036a41086a29030037000002400240200941606a200d490d00200921070c010b200d41206a2207200d490d0b200941017422032007200320074b1b22074100480d0b20092007460d00200520092007102b2205450d0f0b200541206a200e200d10e4071a024020022802a402450d00200e10290b20022001360260200cad4220862005ad8420124280808080c00084100302402007450d00200510290b200241e0006a41186a22034200370300200241e0006a41106a22134200370300200241e0006a41086a220542003703002002420037036041eebec500ad4280808080f000842206100122072900002108200241e0026a41086a2209200741086a290000370300200220083703e0022007102920052009290300370300200220022903e00237036041c8f2c100ad4280808080c001841001220c2900002108200241a0036a41086a2207200c41086a290000370300200220083703a003200c1029200420022903a003370000200441086a200729030037000020024180046a41086a200529030037030020024180046a41106a201329030037030020024180046a41186a20032903003703002002200229036037038004200241286a20024180046a412010fc010240200a200228022c41016a41d50020022802281b6b220c200a4b0d00200c1095020b2002200a36023c2003420037030020134200370300200542003703002002420037036020061001220a29000021062009200a41086a290000370300200220063703e002200a102920052009290300370300200220022903e0023703604180ffc100ad4280808080d001841001220929000021062007200941086a290000370300200220063703a00320091029201320022903a0032206370300200241c0006a41086a2005290300370300200241c0006a41106a2006370300200241c0006a41186a200729030037030020022002290360370340200241203602e4012002200241c0006a3602e001200241e8016a200241c0006aad428080808080048422141007108b0220022802e8012215450d0520022802ec0121162002200241e8016a41086a2802003602fc01200220153602f801200241e0006a200241f8016a10960220022802602217450d03200241e0006a41086a350200211820022802642119200241206a200241f8016a10c80120022802200d012002280224221a20022802fc01220741d0006e22052005201a4b1bad42d0007e2206422088a70d002006a72205417f4c0d000240024020050d004108211b0c010b20051027221b450d070b4100210a20024100360288022002201b360280022002200541d0006e221c360284020240201a450d00200241a4046a211d200241e0006a41206a211e4100210a4100210302400340200241003a00c003200341016a210341002105024002400240034020072005460d01200241a0036a20056a20022802f80122092d00003a00002002200941016a3602f8012002200541016a22093a00c0032009210520094120470d000b200241e0036a41086a2205200241a0036a41086a220c290300370300200241e0036a41106a220d200241a0036a41106a220e290300370300200241e0036a41186a2201200241a0036a41186a220f290300370300200220022903a0033703e0032002200720096b3602fc0120024180046a200241f8016a10830220022802a00422090d01410021090c020b200241003602fc010240200541ff0171450d00200241003a00c0030b410021090c010b201e200229038004370300200241e0006a41186a22072001290300370300200241e0006a41106a2201200d290300370300200241e0006a41086a220d2005290300370300201e41086a20024180046a41086a290300370300201e41106a20024180046a41106a290300370300201e41186a20024180046a41186a290300370300200241b0046a41086a201d41086a280200360200200220022903e0033703602002201d2902003703b004200241a0036a41386a200241e0006a41386a290300370300200241a0036a41306a200241e0006a41306a290300370300200241a0036a41286a200241e0006a41286a290300370300200241a0036a41206a201e290300370300200f2007290300370300200e2001290300370300200c200d290300370300200220022903603703a0030b200241e0026a41386a2205200241a0036a41386a290300370300200241e0026a41306a2207200241a0036a41306a290300370300200241e0026a41286a220c200241a0036a41286a290300370300200241e0026a41206a220d200241a0036a41206a290300370300200241e0026a41186a220e200241a0036a41186a290300370300200241e0026a41106a2201200241a0036a41106a290300370300200241e0026a41086a220f200241a0036a41086a290300370300200241c0046a41086a2210200241b0046a41086a280200360200200220022903a0033703e002200220022903b0043703c00402402009450d00200241a0026a41386a221f2005290300370300200241a0026a41306a22202007290300370300200241a0026a41286a2207200c290300370300200241a0026a41206a220c200d290300370300200241a0026a41186a220d200e290300370300200241a0026a41106a220e2001290300370300200241a0026a41086a2201200f29030037030020024190026a41086a220f2010280200360200200220022903e0023703a002200220022903c004370390020240200a200228028402470d0020024180026a200a410110ac01200228028002211b200228028802210a0b201b200a41d0006c6a220520022903a002370300200e2903002106200d2903002108200c290300210b2007290300212120202903002122201f29030021232001290300212420052009360240200541086a20243703002005200229039002370244200541cc006a200f280200360200200541386a2023370300200541306a2022370300200541286a2021370300200541206a200b370300200541186a2008370300200541106a20063703002002200a41016a220a360288022003201a460d0220022802fc0121070c010b0b0240200a450d00200a41d0006c2109201b41c4006a21050340024020052802002207450d00200741306c450d002005417c6a28020010290b200541d0006a2105200941b07f6a22090d000b0b2002280284022205450d03200541d0006c450d03201b10290c030b200228028402211c0b201b450d010240024020022802fc012205450d0020022005417f6a3602fc01200220022802f801220541016a3602f80120052d000022094103490d010b0240200a450d00200a41d0006c2109201b41c4006a21050340024020052802002207450d00200741306c450d002005417c6a28020010290b200541d0006a2105200941b07f6a22090d000b0b0240201c450d00201c41d0006c450d00201b10290b201941ffffff3f71450d040c030b20184220862019ad8421230c040b1038000b201941ffffff3f71450d010b201710290b200241003602a803200242013703a0032002410d3602e4022002200241e0016a3602e0022002200241a0036a3602a002200241f4006a410136020020024201370264200241f4eaca003602602002200241e0026a360270200241a0026a41a8a3c800200241e0006a10371a20023502a80342208620023502a003841008024020022802a403450d0020022802a00310290b410321090b02402016450d00201510290b20094103460d00201410040c040b200241003602c804200242083703c004200241003602b804200242013703b00441eebec500ad4280808080f00084100122052900002106200241e0026a41086a2209200541086a290000370300200220063703e0022005102941b8dcc900ad4280808080a00184100122052900002106200241a0036a41086a2207200541086a290000370300200220063703a00320051029412010272205450d00200520022903e002370000200520022903a003370010200541086a2009290300370000200541186a220a2007290300370000412010272209450d0020092005290000370000200941186a200a290000370000200941106a200541106a290000370000200941086a200541086a290000370000200241c0006a41026a220a200241e0006a41026a2d00003a0000200220022f00603b0140200241e0036a41106a42a0808080800437030041002107200241003a00f803200220053602ec03200242a080808080043702e403200220093602e003200241fb036a200a2d00003a0000200220022f01403b00f903200241e0006a200241e0036a10b601024020022802604101470d00200241e0006a410472210a410121154108211a410021030340200241a0036a41206a200a41206a280200360200200241a0036a41186a2205200a41186a2902002206370300200241a0036a41106a2209200a41106a2902002208370300200241a0036a41086a221f200a41086a290200220b3703002002200a29020022213703a003200241a0026a41186a22012006370300200241a0026a41106a220f2008370300200241a0026a41086a2210200b370300200220213703a002200241e0006a41186a220c2005290300370300200241e0006a41106a220d2009290300370300200241e0006a41086a220e201f290300370300200220022903a003370360200241a0026a10e1012106412010272209450d0a200920022903a002370000200941186a2001290300370000200941106a200f290300370000200941086a2010290300370000200241e0026a41086a200e2903002208370300200241e0026a41106a200d290300220b370300200241e0026a41186a200c29030022213703002002200229036022223703e00220024180046a41186a221f202137030020024180046a41106a2220200b37030020024180046a41086a221e200837030020022022370380040240200320022802c404470d00200241c0046a2003410110a80120022802c004211a20022802c80421030b201a200341386c6a22052006370300201e290300210620202903002108201f290300210b20022903800421212005412c6a4281808080103702002005200936022820052021370308200541206a200b370300200541186a2008370300200541106a20063703002002200341016a22033602c804200c2001290300370300200d200f290300370300200e2010290300370300200220022903a0023703600240200720022802b404470d00200241b0046a20074101109e0120022802b004211520022802b80421070b201520074105746a22052002290360370000200541186a200c290300370000200541106a200d290300370000200541086a200e2903003700002002200741016a22073602b804200241e0006a200241e0036a10b60120022802604101460d000b0b024020022802e403450d0020022802e00310290b024020022802f003450d0020022802ec0310290b41eebec500ad4280808080f00084100122052900002106200241e0026a41086a2209200541086a290000370300200220063703e0022005102941f5b7c000ad4280808080a00184100122052900002106200241a0036a41086a2207200541086a290000370300200220063703a00320051029412010272205450d00200520022903e002370000200520022903a003370010200541086a2009290300370000200541186a220a2007290300370000412010272209450d0020092005290000370000200941186a200a290000370000200941106a200541106a290000370000200941086a200541086a290000370000200241a0026a41026a220a200241e0006a41026a2d00003a0000200220022f00603b01a002200241e0006a41106a220742a080808080043703002002200536026c200242a0808080800437026420022009360260200241003a0078200241fb006a200a2d00003a0000200220022f01a0023b0079200241c0046a200241e0006a109702200241e0006a41186a220a420037030020074200370300200241e0006a41086a220542003703002002420037036041eebec500ad4280808080f000842206100122092900002108200241e0026a41086a2203200941086a290000370300200220083703e0022009102920052003290300370300200220022903e002370360419cf3c100ad4280808080e001841001220c2900002108200241a0036a41086a2209200c41086a290000370300200220083703a003200c1029201320022903a003370000201341086a220d2009290300370000200241c0006a41086a220e2005290300370300200241c0006a41106a22012007290300370300200241c0006a41186a220f200a29030037030020022002290360370340200241186a200241c0006a412010fc01200228021c21102002280218211f200a420037030020074200370300200542003703002002420037036020061001220c29000021062003200c41086a290000370300200220063703e002200c102920052003290300370300200220022903e00237036041c4f3c100ad4280808080d002841001220329000021062009200341086a290000370300200220063703a00320031029201320022903a003370000200d2009290300370000200e200529030037030020012007290300370300200f200a29030037030020022002290360370340200241106a200241c0006a412010fc01200228021421072002280210210a2009200241b0046a41086a280200360200200220022903b0043703a0032005200241c0046a41086a280200360200200220022903c00437036020024180046a20104100201f1b20074104200a1b22054101200541014b1b200241a0036a200241e0006a109802024020022802800422250d00410321090c040b20024194046a280200210a20024180046a41106a28020021262002418c046a280200212720024180046a41086a280200210520022802840421282002410036026820024201370360200241e0006a4100200541306c220741306e109e012002280268210c0240024020070d00200228026021170c010b20022802602217200c4105746a210520252109034020052009290000370000200541186a200941186a290000370000200541106a200941106a290000370000200541086a200941086a290000370000200c41016a210c200541206a2105200941306a2109200741506a22070d000b0b200235026421242002410036029802200242043703900220024190026a4100200a412c6c2205412c6d109301202720056a2101200228029802210e20022802900221190240200a0d00202721050c020b200241e0006a410c6a210a2019200e412c6c6a2109200241a0036a410c6a210d200241e0006a4104722103200241e0026a41206a210f200241e0026a41186a2110200241e0026a41106a211f200241e0026a41086a212020272105034020052802002107200f200541246a29020037030020102005411c6a290200370300201f200541146a29020037030020202005410c6a2902003703002002200541046a2902003703e002024020070d002005412c6a21050c030b200320022903e002370200200341086a2020290300370200200341106a201f290300370200200341186a2010290300370200200341206a200f29030037020020022007360260200a10e1012106200241e0036a41086a221e200a41086a290200370300200241e0036a41106a2215200a41106a290200370300200241e0036a41186a221a200a41186a2902003703002002200a2902003703e003200228026421162002280268211d200242003703b804200220063703b004200242003703482002420037034020022007201d41246c6a3602ac02200220073602a802200220163602a402200220073602a0022002200241c0006a3602b4022002200241b0046a3602b002200241c0046a200241a0026a1099020240024020022903b0042206200229034022087d222320065620022903b804220b200229034822217d2006200854ad7d2222200b562022200b511b4101470d00200820067d22222008562021200b7d2008200654ad7d220620215620062021511b0d0120022802c8042207450d01200741306c20022802c0046a41706a220742002007290300220820227d220b200b200856200741086a2207290300220b20067d2008202254ad7d2206200b562006200b511b22161b37030020074200200620161b3703000c010b20022802c8042207450d00200741306c20022802c0046a41706a2207427f2007290300220620237c220820082006542216200741086a2207290300220620227c2016ad7c220820065420082006511b22161b3703002007427f200820161b3703000b200d20022903e003370200200241a0036a41086a2207200241c0046a41086a280200360200200d41186a201a290300370200200d41106a2015290300370200200d41086a201e290300370200200220022903c00422063703a003200941286a200241a0036a41286a280200360200200941206a200241a0036a41206a290300370200200941186a200241a0036a41186a290300370200200941106a200241a0036a41106a290300370200200941086a200729030037020020092006370200200e41016a210e2009412c6a21092005412c6a22052001470d000b2002200e360298020c020b1039000b2002200e3602980220052001460d00034020052209412c6a21050240200941046a2802002207450d00200741246c450d00200928020010290b20012005470d000b0b02402026450d002026412c6c450d00202710290b2002280294022103200241e0006a2017200c2019200e109a02024002402002280260220a0d00410021054100210a4100210d0c010b2002280268210d02400240200228026422090d00200a21050c010b20092105200a2107034020072802c80521072005417f6a22050d000b200a21050340200520052f01064102746a41c8056a28020021052009417f6a22090d000b2007210a0b20052f010621090b200241fc006a2009360200200241f8006a4100360200200241f4006a20053602002002200d3602800120024100360270200242003703682002200a36026420024100360260200cad2106200220024180026a36028401200241a0036a200241e0006a109b0220022802a003211b20022802a403211c20022802a803210a0240200e450d00200e412c6c21092019210503400240200541046a2802002207450d00200741306c450d00200528020010290b2005412c6a2105200941546a22090d000b0b2006422086210602402003450d002003412c6c450d00201910290b20062024842123410021092028450d00202841306c450d00202510290b200241e0006a41186a22074200370300200241e0006a41106a22034200370300200241e0006a41086a220542003703002002420037036041eebec500ad4280808080f0008422081001220c2900002106200241e0026a41086a220d200c41086a290000370300200220063703e002200c10292005200d290300370300200220022903e00237036041d0ffc100ad4280808080b001841001220c2900002106200241a0036a41086a220e200c41086a290000370300200220063703a003200c1029201320022903a003370000201341086a200e290300370000200241c0006a41086a2005290300370300200241c0006a41106a2003290300370300200241c0006a41186a200729030037030020022002290360370340201410044100210c20094103460d03200220093a00e801200742003703002003420037030020054200370300200242003703602008100122092900002106200d200941086a290000370300200220063703e002200910292005200d290300370300200220022903e00237036041eab8c000ad4280808080900284100122092900002106200e200941086a290000370300200220063703a00320091029200420022903a003370000200441086a200e29030037000020024180046a41086a200529030037030020024180046a41106a200329030037030020024180046a41186a20072903003703002002200229036037038004410110272205450d04200541003a000020112005ad4280808080108410032005102942002108200241e0006a41186a22274200370300200241e0006a41106a22264200370300200241e0006a41086a221942003703002002420037036041eebec500ad4280808080f00084220610012205290000210b200241e0026a41086a2228200541086a2900003703002002200b3703e0022005102920192028290300370300200220022903e00237036041c6b8c000ad4280808080a0028410012205290000210b200241a0036a41086a2201200541086a2900003703002002200b3703a00320051029200420022903a003370000200441086a2209200129030037000020024180046a41086a2220201929030037030020024180046a41106a221e202629030037030020024180046a41186a221520272903003703002002200229036037038004201110042027420037030020264200370300201942003703002002420037036020061001220529000021062028200541086a290000370300200220063703e0022005102920192028290300370300200220022903e00237036041d8b8c000ad4280808080a002841001220529000021062001200541086a290000370300200220063703a00320051029200420022903a0033700002009200129030037000020202019290300370300201e202629030037030020152027290300370300200220022903603703800420111004201b200a41d0006c6a211f0240200a0d00201b210d420021060c020b200241e0026a41106a211a200241a0026a41106a210f200241c4026a2104200241e0006a41206a210e4200210842002106201b210d0340200241a0036a41386a220a200d220541386a290300370300200241a0036a41306a2203200541306a290300370300200241a0036a41286a220c200541286a290300370300200241a0036a41206a2210200541206a290300370300200241a0036a41186a2209200541186a290300370300200241a0036a41106a2207200541106a2903003703002001200541086a2903003703002005290300210b200241c0046a41086a2216200541cc006a2802003602002002200b3703a0032002200541c4006a2902003703c004200541d0006a210d200541c0006a2802002205450d02200241e0006a41386a200a290300370300200241e0006a41306a2003290300370300200241e0006a41286a200c290300370300200e2010290300370300202720092903003703002026200729030037030020192001290300370300200220022903a003370360200241e0036a41186a2009290300370300200241e0036a41106a2007290300370300200241e0036a41086a2001290300370300200220022903a0033703e003200241a0026a41186a221d200e41186a290300370300200f200e41106a290300370300200241a0026a41086a2213200e41086a290300220b370300200220053602c0022002200e29030022213703a002200420022903c004370200200441086a201628020036020020024180046a200228023c200241e0036a10d70120023502880421222002280280042110200241003602e802200242013703e0022002200241a0026a360240200241c0006a200241e0026a10e5012002200f360240200241c0006a200241e0026a10e50120022802c002210520022802c8022209200241e0026a107102402009450d00200941306c210303400240024020022802e402220a20022802e80222096b4120490d0020022802e00221070c010b200941206a22072009490d04200a410174220c2007200c20074b1b220c4100480d0402400240200a0d000240200c0d00410121070c020b200c10272207450d0a0c010b20022802e0022107200a200c460d002007200a200c102b2207450d090b2002200c3602e402200220073602e0020b200720096a2207200541106a290000370000200741186a200541286a290000370000200741106a200541206a290000370000200741086a200541186a2900003700002002200941206a3602e80220022005360240200241c0006a200241e0026a10e501200541306a2105200341506a22030d000b0b20022802e402210520224220862010ad8420023502e80242208620022802e0022209ad84100302402005450d00200910290b0240200228028404450d00201010290b2015201d290300370300201e200f29030037030020202013290300370300200220022903a0023703800420022802cc02210720022802c402210a20022802c0022109024020022802c802220541c100490d0020092005410041202005676b109c0241c00021050b200241e0026a41186a2015290300370300201a201e2903003703002028202029030037030020022002290380043703e0022002200736028c0320022005360288032002200a360284032002200936028003200241b0046a200228023c200241e0036a109d0220023502b804212220022802b004211020024100360248200242013703402002200241e0026a3602900220024190026a200241c0006a10e5012002201a3602900220024190026a200241c0006a10e50120022802800321052002280288032209200241c0006a107102402009450d00200941306c21030340024002402002280244220a200228024822096b4120490d00200228024021070c010b200941206a22072009490d04200a410174220c2007200c20074b1b220c4100480d0402400240200a0d000240200c0d00410121070c020b200c10272207450d0a0c010b20022802402107200a200c460d002007200a200c102b2207450d090b2002200c360244200220073602400b200720096a2207200541106a290000370000200741186a200541286a290000370000200741106a200541206a290000370000200741086a200541186a2900003700002002200941206a360248200220053602900220024190026a200241c0006a10e501200541306a2105200341506a22030d000b0b2006200b7c200820217c220b2008542205ad7c21082002280244210920224220862010ad84200235024842208620022802402207ad84100302402009450d00200710290b2008200651210920082006542107024020022802b404450d00201010290b2005200720091b210502402002280284032209450d00200941306c450d0020022802800310290b427f200820051b2106427f200b20051b2108200d201f470d000c030b0b1032000b201f200d460d000340200d220541d0006a210d0240200541c4006a2802002209450d00200941306c450d00200541c0006a28020010290b201f200d470d000b0b0240201c450d00201c41d0006c450d00201b10290b200241a0036a200228023c10920220022802a003210520023502a803210b2002200637036820022008370360200b4220862005ad84201242808080808002841003024020022802a403450d00200510290b02402023422088a72203410574220a450d00200241a0036aad210b201721050340200241e0006a200510de01200241086a200228026022072002280268109e02200228020c410020022802081b210902402002280264450d00200710290b200241e0006a200228023c2005109f022002350268210620022802602107200241003a00a5030240024002400240200941c000490d00200941808001490d012009418080808004490d02200241053a00a503200241033a00a003200220093600a1034280808080d00021080c030b200241013a00a503200220094102743a00a00342808080801021080c020b200241023a00a503200220094102744101723b01a00342808080802021080c010b200241043a00a503200220094102744102723602a0034280808080c00021080b20064220862007ad842008200b841003024020022d00a503450d00200241003a00a5030b02402002280264450d00200710290b200541206a2105200a41606a220a0d000b0b200241e9006a20022d00e8013a0000200241e8006a220541043a0000200241043a0060200241e0006a10cb01024041002802d8a74c4103490d00200241b4036a410c360200200241ac036a410f3602002002410c3602a403200220033602e00220022002413c6a3602b0032002200241e8016a3602a8032002200241e0026a3602a00341002802888040210941002802848040210741002802dca74c210a200241a0016a41991736020020024198016a42db8080801037030020024194016a41eec5c0003602002002418c016a420e37020020024188016a41e0c5c00036020020024180016a4203370300200241f0006a420337030020054107360200200241fc006a200241a0036a3602002002419ca5c20036026c200241bcc1c2003602642002410336026020074180a4c000200a41024622051b200241e0006a20094198a4c00020051b2802101102000b2017210c0b200020233702042000200c360200200241d0046a24000f0b1030000bd71704027f017e077f017e230041d0006b2201240041eebec500ad4280808080f00084100122022900002103200141086a41086a200241086a290000370300200120033703082002102941ffb7c000ad4280808080b00184100122022900002103200141186a41086a200241086a2900003703002001200337031820021029200120003602342001200141346aad22034280808080c000841002220229000037033820021029200141cc006a200141386a3602002001200141386a41086a22043602442001200141346a3602482001200141386a360240200141286a200141c0006a107502400240024002402001280230220541206a2206417f4c0d00200128022821070240024020060d0041002108410121020c010b200610272202450d02200621080b024002402008410f4d0d00200821090c010b200841017422094110200941104b1b22094100480d03024020080d002009102722020d010c050b20082009460d00200220082009102b2202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020094170714110460d00200921080c010b200941017422084120200841204b1b22084100480d0320092008460d00200220092008102b2202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200841606a2005490d00200821090c010b200541206a22092005490d032008410174220a2009200a20094b1b22094100480d0320082009460d00200220082009102b2202450d040b200241206a2007200510e4071a0240200128022c450d00200710290b2006ad4220862002ad84100602402009450d00200210290b41eebec500ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002102941acf7c100ad4280808080a0028410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002102920012000360234200120034280808080c000841002220229000037033820021029200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a10752001280230220541206a2208417f4c0d00200128022821070240024020080d0041002109410121020c010b200810272202450d02200821090b024002402009410f4d0d00200921060c010b200941017422064110200641104b1b22064100480d03024020090d00200610272202450d050c010b20092006460d00200220092006102b2202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020064170714110460d00200621090c010b200641017422094120200941204b1b22094100480d0320062009460d00200220062009102b2202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200941606a2005490d00200921060c010b2005415f4b0d03200941017422062008200620084b1b22064100480d0320092006460d00200220092006102b2202450d040b200241206a2007200510e4071a0240200128022c450d00200710290b2008ad4220862002ad84100602402006450d00200210290b41eebec500ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002102941a8f8c100ad4280808080a0028410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002102920012000360234200120034280808080c000841002220229000037033820021029200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a10752001280230220541206a2208417f4c0d00200128022821070240024020080d0041002109410121020c010b200810272202450d02200821090b024002402009410f4d0d00200921060c010b200941017422064110200641104b1b22064100480d03024020090d00200610272202450d050c010b20092006460d00200220092006102b2202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020064170714110460d00200621090c010b200641017422094120200941204b1b22094100480d0320062009460d00200220062009102b2202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200941606a2005490d00200921060c010b2005415f4b0d03200941017422062008200620084b1b22064100480d0320092006460d00200220092006102b2202450d040b200241206a2007200510e4071a0240200128022c450d00200710290b2008ad4220862002ad84100602402006450d00200210290b41eebec500ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002102941f4f8c100ad4280808080b0028410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002102920012000360234200120034280808080c000841002220229000037033820021029200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a10752001280230220541206a2208417f4c0d00200128022821070240024020080d0041002109410121020c010b200810272202450d02200821090b024002402009410f4d0d00200921060c010b200941017422064110200641104b1b22064100480d03024020090d00200610272202450d050c010b20092006460d00200220092006102b2202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020064170714110460d00200621090c010b200641017422094120200941204b1b22094100480d0320062009460d00200220062009102b2202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200941606a2005490d00200921060c010b2005415f4b0d03200941017422062008200620084b1b22064100480d0320092006460d00200220092006102b2202450d040b200241206a2007200510e4071a0240200128022c450d00200710290b2008ad4220862002ad84100402402006450d00200210290b200141c0006a200010af01200135024842208620012802402202ad84100402402001280244450d00200210290b41eebec500ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002102941e0f9c100ad4280808080e0018410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002102920012000360234200120034280808080c000841002220229000037033820021029200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a10752001280230220641206a2208417f4c0d00200128022821050240024020080d0041002104410121020c010b200810272202450d02200821040b024002402004410f4d0d00200421090c010b200441017422094110200941104b1b22094100480d03024020040d00200910272202450d050c010b20042009460d00200220042009102b2202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020094170714110460d00200921040c010b200941017422044120200441204b1b22044100480d0320092004460d00200220092004102b2202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200441606a2006490d00200421090c010b2006415f4b0d03200441017422092008200920084b1b22094100480d0320042009460d00200220042009102b2202450d040b200241206a2005200610e4071a0240200128022c450d00200510290b2008ad4220862002ad84100402402009450d00200210290b200141c0006a200010da01200135024842208620012802402202ad84100402402001280244450d00200210290b200141d0006a24000f0b1038000b1039000b1032000b1030000ba20401097f230041e0006b220224002002200110c80102400240024002402002280200450d00200041003602000c010b2002280204220320012802044105762204200420034b1b22044105742205417f4c0d010240024020040d00410121060c010b200510272206450d030b41002107200241003602102002200436020c20022006360208024002402003450d0041002108034041002105200241003a0058200841016a21082001280204417f6a210403402004417f460d03200241386a20056a200128020022092d00003a0000200120043602042001200941016a3602002002200541016a22093a00582004417f6a21042009210520094120470d000b200241186a41186a2205200241386a41186a290300370300200241186a41106a2209200241386a41106a290300370300200241186a41086a220a200241386a41086a2903003703002002200229033837031802402007200228020c470d00200241086a20074101109e0120022802082106200228021021070b200620074105746a22042002290318370000200441186a2005290300370000200441106a2009290300370000200441086a200a2903003700002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c010b0240200541ff0171450d00200241003a00580b20004100360200200228020c41ffffff3f71450d00200610290b200241e0006a24000f0b1038000b1039000be80808097f017e0c7f017e017f017e017f037e230041f0016b22022400200241086a41186a200141186a280200360200200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241e8006a200241086a10b701024020022d0098014102460d00200041046a21030340200241a0016a41286a200241e8006a41286a280200360200200241a0016a41206a200241e8006a41206a2201290300370300200241a0016a41186a2204200241e8006a41186a2205290300370300200241a0016a41106a2206200241e8006a41106a2207290300370300200241a0016a41086a2208200241e8006a41086a2209290300370300200220022903683703a0012001280200210a0240200229028c01220b422088a7220c450d00200228029401210d4100210e200a21014100210f024002400340200220013602cc01200241d0016a200241cc016a10df01024002400240024020022802dc012210450d0020022802d8012111024020022802e00141ffffffff0371450d00201010290b2011200d4b0d010b200e0d014100210e0c020b200e41016a210e0c010b200f200e6b2210200c4f0d02200241d0016a41186a22112001200e4105746b221041186a2212290000370300200241d0016a41106a2213201041106a2214290000370300200241d0016a41086a2215201041086a2216290000370300200220102900003703d001200141086a22172900002118200141106a2219290000211a200141186a221b290000211c201020012900003700002012201c3700002014201a37000020162018370000201b20112903003700002019201329030037000020172015290300370000200120022903d0013700000b200141206a2101200c200f41016a220f460d020c000b0b2010200c4180bdc7001036000b200e417f6a200c4f0d00200b42ffffffff0f83200c200e6bad42208684210b0b200241c8006a41186a22012004290300370300200241c8006a41106a220e2006290300370300200241c8006a41086a220f2008290300370300200220022903a001370348200a450d01200520012903003703002007200e2903003703002009200f29030037030020022002290348370368200241e8006a10e1012118200241286a41186a2001290300221a370300200241286a41106a200e290300221c370300200241286a41086a200f290300221d37030020022002290348221e3703282005201a3703002007201c3703002009201d3703002002201e3703680240200041086a220f280200220e2003280200470d002000200e410110a8010b2000280200200e41386c6a22012002290368370308200120183703002001200a360228200141106a2009290300370300200141186a2007290300370300200141206a20052903003703002001412c6a200b370200200f200e41016a360200200241e8006a200241086a10b70120022d0098014102470d000b0b0240200228020c450d00200228020810290b0240200241186a280200450d00200228021410290b200241f0016a24000bab2104027f017e107f077e23004190026b2205240020054100360238200541003602300240024002400240200441086a280200200341086a28020022066aad42e0007e2207422088a70d002007a72208417f4c0d0041082109024002402008450d00200810272209450d010b20054100360248200520093602402005200841e0006e3602442003280204210a2003280200210b2005410036029801200542083703900120054190016a410020064105742209410575108c01200528029801210c02402006450d00200941606a410576210d200528029001200c41d8006c6a210e200541f0016a2108200541e8016a210f41002106200b21030340200541a0016a41186a2210200341186a2211290000370300200541a0016a41106a2212200341106a2213290000370300200541a0016a41086a2214200341086a2215290000370300200520032900003703a001200541e0006a41186a2011290000370300200541e0006a41106a2013290000370300200541e0006a41086a201529000037030020052003290000370360200541306a200541e0006a200610d702200541c0016a41086a4200370300200541c0016a41106a4200370300200541c0016a41186a4200370300200541c0016a41206a4200370300200f4200370300200841186a2010290300370000200841106a2012290300370000200841086a2014290300370000200820052903a001370000200542003703c001200e200541c0016a41d00010e407220e41d0006a41003a0000200e41d8006a210e200341206a2103200641016a2106200941606a22090d000b200c200d6a41016a210c0b2005200c360298010240200a41ffffff3f71450d00200b10290b200541d0006a41086a20054190016a41086a2802002203360200200520052903900137035020032002490d032004280204210620042802002103200541c0006a2005280248200441086a28020041386c220941386d10a7012005280240210e20052802482108200541d4016a200541d0006a3602002005200320096a3602cc01200520033602c801200520063602c401200520033602c0012005200541306a3602d001200541e0006a41086a20083602002005200541c8006a3602642005200e200841e0006c6a360260200541c0016a200541e0006a10d8022001ad42307e2207422088a70d012007a72208417f4c0d01200528025821030240024020080d00410821040c010b200810272204450d010b20054100360218200520043602102005200841306e3602142001412c6c2208417f4c0d010240024020080d00410421160c010b200810272216450d010b4100210b2005410036022820052001360224200520163602202003200120032001491b2217450d024100210b200541c0016a41186a210a200541c0016a41106a210f200541c0016a41086a210d4100210203402005280250210602402003450d00200341d8006c21082006210303400240200341d0006a2d00000d0002400240200341206a2903002218200341286a29030022198450450d0042002107427f2118427f21190c010b427f21072005427f427f2018201910e007200541086a2903002119200529030021180b2003201837030020032019370308200341106a2007370300200341186a20073703000b200341d8006a2103200841a87f6a22080d000b0b0240024020052802482203450d0020052802402209200341e0006c6a21120340024020092802382203450d00200341c8006c2106200928023041206a210303402005280258220e200328020022084d0d0402402005280250200841d8006c6a22082d00500d0020082903202207200841286a290300221884500d00200541c0016a2009290310200941186a2903002009290300200941086a2903002007201810d202200820082903002207427f2007427f20052903c80120052802c001410146220e1b22197c221820182007542210200841086a22112903002207427f200f290300200e1b221a7c2010ad7c221820075420182007511b220e1b2019201a845022101b37030020112007427f2018200e1b20101b3703000b200341c8006a2103200641b87f6a22060d000b0b200941e0006a22092012470d000b200528025021060b200241016a2102200528025841d8006c2103200641a87f6a210803402003450d05200341a87f6a2103200841d8006a2108200641d0006a2109200641d8006a220e210620092d00000d000b02402003450d00200841186a2903002107200841106a2903002118200841086a29030021192008290300211a4100210603400240200e20066a220941d0006a2d00000d00200941086a290300221b2019201a2019201820072009290300221c201b200941106a290300221d200941186a290300221e10d90241ff017141014622101b2119201c201a20101b211a201e200720101b2107201d201820101b21182009200820101b21080b2003200641d8006a2206470d000b2008450d050b200841013a0050024020052802482203450d0020052802402206200341e0006c6a21012008410c6a2114200841306a21150340200641e0006a210c024020062802382209450d0020062802302103200941c8006c210903400240024020142003460d00200341246a2015412010e7070d010b200641186a220e290300211a200841086a2210290300210720062903102119200829030021182008290310211b200341186a200841186a2211290300370300200341106a201b3703002003200742002007201a7d2018201954ad7d221b201820197d221c201856201b200756201b2007511b22121b2019201a845022131b370308200320184200201c20121b20131b37030020102903002107201129030021182008290300211920062008290310370320200641286a201837030020062019370310200e20073703000b200341c8006a2103200941b87f6a22090d000b0b200c2106200c2001470d000b0b200a200841c8006a290000370300200f200841c0006a290000370300200d200841386a290000370300200520082900303703c001200841286a2903002107200829032021180240200b2005280214470d00200541106a200b4101109001200528021021042005280218210b0b2004200b41306c6a220320052903c001370300200d2903002119200f290300211a200a290300211b20032018370320200341286a2007370300200341186a201b370300200341106a201a370300200341086a20193703002005200b41016a220b360218200220174f0d04200528025821030c010b0b2008200e418cf0c9001036000b1039000b1038000b024020052802482203450d0020052802402214200341e0006c6a2102200b41306c210c200541ec006a220b41186a210a200b41106a210d200b41086a2117410021010340200b201429003c370000200a201441d4006a290000370000200d201441cc006a2900003700002017201441c4006a2900003700002005410036026820054204370360024020142802382203450d0020142802302212200341c8006c6a2115201441106a210f410021114104211303402012221041246a2106201041c8006a211241002109200c210820042103024003402008450d01024020062003460d0020032006412010e707210e200941016a2109200841506a2108200341306a2103200e0d010b0b418094ebdc0321080240200f201010da020d004100210302402010290310201429032085201041186a290300201441286a29030085844200520d00200541c0016a428094ebdc0342002010290300201041086a290300200f290300200f41086a29030010d202427f20052903c80120052802c00141014622031b221842ffffffff0f56427f200541c0016a41106a29030020031b22074200522007501b0d012018a7220341ff93ebdc034b0d010b200321080b200541c0016a41186a22062010413c6a290000370300200541c0016a41106a2209201041346a290000370300200541c0016a41086a220e2010412c6a290000370300200520102900243703c001024020112005280264470d00200541e0006a2011410110960120052802602113200528026821110b2013201141246c6a220320052903c001370200200e2903002107200929030021182006290300211920032008360220200341186a2019370200200341106a2018370200200341086a20073702002005201141016a22113602680b20122015470d000b024002402011450d0002400240201141246c22060d00410021030c010b201341206a2108410021030340417f200320082802006a220920092003491b2103200841246a21082006415c6a22060d000b0b02404100418094ebdc0320036b22032003418094ebdc034b1b221020116e2203418094ebdc032003418094ebdc03491b220e450d00201341206a210341002108034020112008460d032005417f20032802002206200e6a220920092006491b22063602c0012005418094ebdc033602c4012003200541c0016a2006418094ebdc034b4102746a280200360200200341246a21032011200841016a2208470d000b0b02402010200e20116c6b220e450d004100210303402005417f2013200320117041246c6a2208280220220641016a220920092006491b22063602c0012005418094ebdc033602c4012008200541c0016a2006418094ebdc034b4102746a280200360220200341016a2203200e490d000b0b200541c0016a41286a2208200541e0006a41286a280200360200200541c0016a41206a2206200541e0006a41206a290300370300200541c0016a41186a2209200541e0006a41186a290300370300200541c0016a41106a220e200541e0006a41106a290300370300200541c0016a41086a2210200541e0006a41086a290300370300200520052903603703c001024020012005280224470d00200541206a2001410110930120052802202116200528022821010b20162001412c6c6a220320052903c001370200200341286a2008280200360200200341206a2006290300370200200341186a2009290300370200200341106a200e290300370200200341086a20102903003702002005200141016a22013602280c020b20052802642203450d01200341246c450d01201310290c010b20082011419cf0c9001036000b201441e0006a22142002470d000b0b200541c0016a41086a2203200541106a41086a280200360200200541d4016a200541206a41086a28020036020020002005290310370200200520052903203702cc01200041086a2003290300370200200041106a200541c0016a41106a290300370200024020052802542203450d00200341d8006c450d00200528025010290b024020052802482203450d00200341e0006c2108200528024041346a21030340024020032802002206450d00200641c8006c450d002003417c6a28020010290b200341e0006a2103200841a07f6a22080d000b0b024020052802442203450d00200341e0006c450d00200528024010290b200541306a10d4010c010b20004100360200024020052802542203450d00200341d8006c450d00200528025010290b024020052802482203450d00200341e0006c2108200528024041346a21030340024020032802002206450d00200641c8006c450d002003417c6a28020010290b200341e0006a2103200841a07f6a22080d000b0b024020052802442203450d00200341e0006c450d00200528024010290b200541306a10d401200428020021060240200441086a2802002203450d00200341386c21082006412c6a210303400240200328020041ffffff3f71450d002003417c6a28020010290b200341386a2103200841486a22080d000b0b200441046a2802002203450d00200341386c450d00200610290b20054190026a24000b990b04077f047e087f017e230041f0016b22022400024002400240200141086a220328020022042001410c6a2802002205460d0003402003200441246a2206360200200441206a2802002107200241d0016a41186a200441186a290000370300200241d0016a41106a200441106a290000370300200241d0016a41086a200441086a290000370300200220042900003703d00120070d022006210420052006470d000b0b200041003602082000420837020020012802042204450d01200441246c450d01200128020010290c010b200241d0006a200128021022082903002209200841086a290300428094ebdc03420010e007200241c0006a2002290350220a200241d0006a41086a290300220b4280ec94a37c427f10d507200241306a200a200b2007ad220c420010d507200141146a280200220d427f200d290300220a2002290330220b200c200920022903407c7e2209428094ebdc0380220ca7417f2009428080808080c0b2cd3b541b2009200c4280ec94a37c7e7c4280cab5ee01566aad7c22097c220c200c200a542206200d41086a2207290300220a200241306a41086a2903002009200b54ad7c220c7c2006ad7c220b200a54200b200a511b22061b3703002007427f200b20061b37030020024190016a41086a2206200241d0016a41086a29030037030020024190016a41106a2207200241d0016a41106a29030037030020024190016a41186a2203200241d0016a41186a290300370300200220022903d00137039001200241f0006a41186a220e2003290300370300200241f0006a41106a22032007290300370300200241f0006a41086a2207200629030037030020022002290390013703700240024041301027220f450d00200f2009370320200f2002290370370300200f41286a200c370300200f41186a200e290300370300200f41106a2003290300370300200f41086a200729030037030020024281808080103702642002200f36026020012802042110200128020021112005415c6a2004460d01200541b87f6a2112200241d0016a41186a2107200241d0016a41106a2105200241d0016a41086a2103410121010340200441c4006a280200210620072004413c6a2900003703002005200441346a29000037030020032004412c6a2900003703002002200441246a220e2900003703d0010240024020060d0020122004460d040c010b200241206a20082903002209200841086a290300428094ebdc03420010e007200241106a2002290320220a200241206a41086a290300220b4280ec94a37c427f10d5072002200a200b2006ad220c420010d507200d427f200d290300220a2002290300220b200c200920022903107c7e2209428094ebdc0380220ca7417f2009428080808080c0b2cd3b541b2009200c4280ec94a37c7e7c4280cab5ee01566aad7c22097c220c200c200a542206200d41086a2213290300220a200241086a2903002009200b54ad7c220c7c2006ad7c220b200a54200b200a511b22061b3703002013427f200b20061b37030020024190016a41086a2206200329030037030020024190016a41106a2213200529030037030020024190016a41186a22142007290300370300200220022903d0013703900120072014290300370300200520132903003703002003200629030037030020022002290390013703d001024020012002280264470d00200241e0006a200141011090012002280260210f0b200f200141306c6a220620022903d0013703002003290300210a2005290300210b2007290300211520062009370320200641286a200c370300200641186a2015370300200641106a200b370300200641086a200a3703002002200141016a220136026820122004460d030b200e21040c000b0b1039000b02402010450d00201041246c450d00201110290b20002002290360370200200041086a200241e0006a41086a2802003602000b200241f0016a24000ba028030f7f047e1b7f230022052106200541e00b6b41607122072400200741003602182007410036021002400240024002402002450d00200120024105746a2108200741e0056a41027221094100210a034020074200370348200742003703402007410036025820074208370350200741a8026a41186a220b200141186a290000370300200741a8026a41106a220c200141106a290000370300200741a8026a41086a220d200141086a290000370300200720012900003703a80202400240200a450d002007280214210e0c010b200741e0056a410041e00210e6071a200741f8026a410041e00210e6071a41c8051027220a450d054100210e200a41003b0106200a4100360200200a41086a200741e0056a41e00210e4071a200a41e8026a200741f8026a41e00210e4071a200741003602142007200a3602100b200141206a21010240024002400240024002400340200a41066a210f200a2f01062210410574210241002111200a41086a22122105024003402002450d01200741a8026a2005412010e7072213450d03200241606a2102201141016a2111200541206a21052013417f4a0d000b2011417f6a21100b0240200e450d00200e417f6a210e200a20104102746a41c8056a280200210a0c010b0b200741f0006a41186a2202200b290300370300200741f0006a41106a200c2903002214370300200741f0006a41086a200d2903002215370300200720072903a80222163703702007200728021841016a360218200c2014370300200d2015370300200b2002290300370300200720163703a80220072903582114200729035021152007290348211620072903402117200f2f01002205410b490d01200741e0056a410041e00210e6071a200741f8026a410041e00210e6071a41c80510272218450d0a201841003b010620184100360200201841086a200741e0056a41e00210e4072105201841e8026a200741f8026a41e00210e4072111200741e0056a41086a2219200a41b0046a290300370300200741e0056a41106a221a200a41b8046a290300370300200741e0056a41186a221b200a41c0046a2903003703002007200a41db016a2900003703e0022007200a41e0016a2900003700e5022007200a41a8046a2903003703e0052007200a41c8016a2f00003b01f4022007200a41ca016a2d00003a00f602200a41cb016a280000211c200a41cf016a280000211d200a41d3016a280000211e200a41d7016a280000211f2005200a41e8016a200a2f010641796a2202410574221310e40721052011200a41c8046a201310e4072111200a41063b0106201820023b0106200720072f01f4023b01dc02200720072d00f6023a00de02200720072903e0023703c802200720072900e5023700cd02200741f8026a41186a2220201b290300370300200741f8026a41106a2221201a290300370300200741f8026a41086a22222019290300370300200720072903e0053703f8020240024020104107490d002005201041057441c07e6a220e6a2005201041796a221341057422106a2205200241ffff037120136b41057410e5071a200541186a200b290300370000200541106a200c290300370000200541086a200d290300370000200520072903a8023700002011200e6a201120106a2202201841066a220f2f010020136b41057410e5071a200241186a20143703002002201537031020022016370308200220173703000c010b20122010410574220541206a22116a201220056a2202200f2f010020106b41057410e5071a200241186a200b290300370000200241106a200c290300370000200241086a200d290300370000200220072903a802370000200a41e8026a220220116a200220056a2202200f2f010020106b41057410e5071a200241186a20143703002002201537031020022016370308200220173703000b200f200f2f010041016a3b010020074190026a41026a220220072d00de023a0000200741d8016a41086a22232022290300370300200741d8016a41106a22242021290300370300200741d8016a41186a22252020290300370300200720072f01dc023b019002200720072903c8023703c801200720072900cd023700cd01200720072903f8023703d801200741a4016a41026a222620022d00003a0000200720072f0190023b01a401200720072900cd0137009501200720072903c80137039001200741a8016a41186a22272025290300370300200741a8016a41106a22282024290300370300200741a8016a41086a22292023290300370300200720072903d8013703a8010240200a280200220e0d004100212a200741106a21020c040b200a2f0104210f4100212a0340200741a4026a41026a222b20262d00003a0000200720072f01a4013b01a402200720072903900137039002200720072900950137009502200b2027290300370300200c2028290300370300200d2029290300370300200720072903a8013703a80241000d03200f41ffff0371210a024002400240200e2f01062202410b490d002009410041f20510e6071a41f80510272213450d0e20134100360200201341046a200741e0056a41f40510e4071a2007200e2f00c8013b01f4022007200e41ca016a2d00003a00f6022007200e41db016a2900003703e0022007200e41e0016a2900003700e502200e41cb016a280000212c200e41cf016a280000212d200e41d3016a280000212e200e41d7016a280000212f201b200e41c0046a290300370300201a200e41b8046a2903003703002019200e41b0046a2903003703002007200e2903a8043703e005201341086a200e41e8016a200e2f0106220241796a2205410574221110e4072130201341e8026a200e41c8046a201110e4072131201341c8056a200e41e4056a2002417a6a221041027410e4072112200e41063b0106201320053b010602402010450d00410021022012210503402005280200221120023b010420112013360200200541046a21052010200241016a2202470d000b0b2020201b2903003703002021201a29030037030020222019290300370300200720072903e0053703f802200720072f01f4023b01dc02200720072d00f6023a00de02200720072903e0023703c802200720072900e5023700cd02200741dc056a41026a221020072d00de023a0000200720072f01dc023b01dc05200720072903c8023703c801200720072900cd023700cd01201b2020290300370300201a202129030037030020192022290300370300200720072903f8023703e005200f41ffff037122054107490d012030200a417a6a2211410574220f6a2030200a41796a220241057422326a220520132f010620026b41057410e5071a200541186a2007290095023700002005201f36000f2005201e36000b2005201d3600072005201c360003200541026a202b2d00003a0000200520072f01a4023b000020052007290390023700132031200f6a203120326a220520132f0106220f20026b41057410e5071a200541186a200b290300370300200541106a200c290300370300200541086a200d290300370300200520072903a8023703002013200f41016a22053b0106200a410274221c20126a416c6a201220114102746a220f200541ffff0371220a20116b41027410e5071a200f2018360200200a2011490d022013201c6a41b0056a2105034020052802002211200241016a22023b010420112013360200200541046a21052002200a490d000c030b0b200e41086a2205200a41016a221141057422136a2005200a41057422106a22052002200a6b410574220f10e5071a2005201f36000f2005201e36000b2005201d3600072005201c360003200541026a202b2d00003a0000200520072f01a4023b00002005200729039002370013200541186a200729009502370000200e41e8026a220520136a200520106a2205200f10e5071a200541186a200b290300370300200541106a200c290300370300200541086a200d290300370300200520072903a802370300200e200241016a22023b0106200a410274200e41c8056a22056a41086a200520114102746a2205200241ffff037120116b41027410e5071a20052018360200200a200e2f010622024f0d07201820113b01042018200e360200201120024f0d072002417f6a2113200e2011417f6a22024102746a41d0056a2105034020052802002211200241026a3b01042011200e360200200541046a21052013200241016a2202470d000c080b0b200e41086a2202200a41016a2211410574220f6a2002200a41057422126a2202200e2f01062230200a6b410574223110e5071a2002201f36000f2002201e36000b2002201d3600072002201c360003200241026a202b2d00003a0000200220072f01a4023b00002002200729039002370013200241186a200729009502370000200e41e8026a2202200f6a200220126a2202203110e5071a200241186a200b290300370300200241106a200c290300370300200241086a200d290300370300200220072903a802370300200e203041016a22023b0106200a4102742212200e41c8056a220f6a41086a200f20114102746a220f200241ffff037120116b41027410e5071a200f20183602002005200e2f010622114f0d00200e20126a41cc056a2102034020022802002205200a41016a220a3b01042005200e360200200241046a21022011200a470d000b0b202a41016a212a2007418c026a41026a220220102d00003a0000202320192903003703002024201a2903003703002025201b290300370300200720072f01dc053b018c02200720072903c8013703f801200720072900cd013700fd01200720072903e0053703d801202620022d00003a0000200720072f018c023b01a401200720072900fd0137009501200720072903f80137039001202720252903003703002028202429030037030020292023290300370300200720072903d8013703a8010240200e28020022020d00200741106a2102202c211c202f211f202e211e202d211d201321180c050b200e2f0104210f202c211c202f211f202e211e202d211d2002210e201321180c000b0b200a20114105746a22024180036a2205290300211520052007290358370300200241f8026a2205290300211420052007290350370300200241f0026a2205290300211620052007290348370300200241e8026a2202290300211720022007290340370300200720153703f805200720143703f005200720163703e805200720173703e0052014a72202450d0420072802f4052205450d04200541306c450d04200210290c040b20122010410574221141206a22136a201220116a2202200520106b41057410e5071a200241186a200b290300370000200241106a200c290300370000200241086a200d290300370000200220072903a802370000200a41e8026a220220136a200220116a2202200a2f010620106b41057410e5071a200241186a2014370300200220153703102002201637030820022017370300200a200a2f010641016a3b0106200741003602f0050c030b41cc9ec800413541b8a1cc001033000b2009410041f20510e6071a41f80510272205450d0620054100360200200541046a200741e0056a41f40510e4071a2005200228020022113602c8052002200536020020022002280204221341016a360204201141003b010420112005360200200741a8026a41026a220a20262d00003a0000200720072f01a4013b01a80220072007290390013703f80220072007290095013700fd02201b2027290300370300201a202829030037030020192029290300370300200720072903a8013703e0052013202a470d0520052f01062211410a4b0d04200520114105746a2202410a6a200a2d00003a0000200241086a20072f01a8023b0000200241176a201f360000200241136a201e3600002002410f6a201d3600002002410b6a201c3600002002411b6a20072903f802370000200241206a20072900fd02370000200241e8026a20072903e005370300200241f0026a2019290300370300200241f8026a201a29030037030020024180036a201b2903003703002005201141016a22024102746a41c8056a2018360200200520023b0106201820023b0104201820053602000b200741003602f0050b20012008460d012007280210210a0c000b0b0240024020040d004100210b0c010b20032004412c6c6a210d4100210b034020032202412c6a21030240200228020841306c2205450d002002280200220a20056a210c2002410c6a21120340200a41306a210f0240024002402007280210220e450d00200728021421010340200e41086a2105200e2f01062210410574210241002111024003402002450d01200a2005412010e7072213450d04200241606a2102201141016a2111200541206a21052013417f4a0d000b2011417f6a21100b2001450d012001417f6a2101200e20104102746a41c8056a280200210e0c000b0b417f200b41016a22022002200b491b210b0c010b200e20114105746a220241e8026a2205427f20052903002214200a2903207c221520152014542205200241f0026a22112903002214200a41286a22132903007c2005ad7c221520145420152014511b22051b3703002011427f201520051b37030020122900002114200741e0056a41086a220e201241086a290000370300200741e0056a41106a2201201241106a290000370300200741e0056a41186a2210201241186a290000370300200720143703e00520132903002114200a2903202115200241f8026a2113024020024180036a22052802002211200241fc026a280200470d00201320114101109001200528020021110b2013280200201141306c6a220220072903e00537030020022015370320200241186a2010290300370300200241106a2001290300370300200241086a200e290300370300200241286a20143703002005200528020041016a3602000b200f210a200f200c470d000b0b2003200d470d000b0b200020072903103702002000200b36020c200041086a200741106a41086a280200360200200624000f0b418f9cc800412741b8a1cc001033000b41b69cc800413041b8a1cc001033000b1030000be91105077f017e047f017e097f230041a0026b2202240002400240024002400240024002400240024020012802202203450d0020012003417f6a220436022020012802042203450d02200128020821052001280200210602402001410c6a280200220720032f0106490d00034002400240200328020022080d002005ad2109410021080c010b200641016a210620033301044220862005ad8421090b200310292009a72105200821032009422088a7220720082f01064f0d000b200821030b20024190016a41186a220a200320074105746a220841206a29000037030020024190016a41106a220b200841186a29000037030020024190016a41086a220c200841106a2900003703002002200841086a29000037039001200241f0016a41086a220d20084184036a2802003602002002200841fc026a2902003703f001200741016a2107200841f0026a2903002109200841e8026a290300210e200841f8026a280200210f02402006450d00200320074102746a41c8056a2802002103410021072006417f6a2208450d00034020032802c80521032008417f6a22080d000b0b200241186a41186a200a290300370300200241186a41106a200b290300370300200241186a41086a200c29030037030020024190026a41086a200d2802003602002002200229039001370318200220022903f001370390022001200736020c200120053602082001200336020420014100360200200f0d010b20024180016a41003602000c060b200241b8016a2009370300200241c0016a200f360200200241c4016a20022903900237020020024190016a41186a200241186a41186a29030037030020024190016a41106a200241186a41106a29030037030020024190016a41086a200241186a41086a290300370300200241cc016a20024190026a41086a2802003602002002200e3703b0012002200229031837039001200241c0006a200141246a20024190016a10a20220024180016a280200450d0520024190016a200241c0006a41d00010e4071a417f200441016a220320032004491bad42d0007e2209422088a70d012009a72203417f4c0d01200310272210450d02201020024190016a41d00010e4072108200241013602102002200341d0006e36020c20022008360208200241186a41206a200141206a2902002209370300200241186a41186a200141186a290200370300200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318024002402009a72203450d0020022003417f6a220f360238200228021c2203450d0520022802202105200228021821070240200241246a280200220620032f0106490d00034002400240200328020022080d002005ad2109410021080c010b200741016a210720033301044220862005ad8421090b200310292009a72105200821032009422088a7220620082f01064f0d000b200821030b20024190016a41186a2201200320064105746a220841206a29000037030020024190016a41106a220b200841186a29000037030020024190016a41086a220c200841106a2900003703002002200841086a2900003703900120024190026a41086a220d20084184036a2802003602002002200841fc026a29020037039002200641016a2106200841f0026a2903002109200841e8026a290300210e200841f8026a280200210a02402007450d00200320064102746a41c8056a2802002103410021062007417f6a2208450d00034020032802c80521032008417f6a22080d000b0b200241f0016a41186a2001290300370300200241f0016a41106a200b290300370300200241f0016a41086a200c290300370300200241e0016a41086a200d28020036020020022002290390013703f00120022002290390023703e00120022006360224200220053602202002200336021c20024100360218200a450d002002413c6a2111200241c4016a2104200241b8016a2112410121010340200420022903e0013702002012200937030020024190016a41186a220b200241f0016a41186a221329030037030020024190016a41106a220c200241f0016a41106a221429030037030020024190016a41086a220d200241f0016a41086a2215290300370300200441086a200241e0016a41086a22162802003602002002200e3703b001200220022903f001370390012002200a3602c001200241c0006a201120024190016a10a202200228028001450d0220024190016a200241c0006a41d00010e4071a02402001200228020c470d00200241086a2001417f200f41016a22082008200f491b10ac01200228020821100b2010200141d0006c6a20024190016a41d00010e4071a2002200141016a2201360210200f450d012002200f417f6a220f3602382003450d07410021070240200620032f0106490d00034002400240200328020022080d002005ad2109410021080c010b200741016a210720033301044220862005ad8421090b200310292009a72105200821032009422088a7220620082f01064f0d000b200821030b200b200320064105746a220841206a290000370300200c200841186a290000370300200d200841106a2900003703002002200841086a29000037039001200841f8026a280200210a20024190026a41086a221720084184036a2802003602002002200841fc026a29020037039002200641016a2106200841f0026a2903002109200841e8026a290300210e02402007450d00200320064102746a41c8056a2802002103410021062007417f6a2208450d00034020032802c80521032008417f6a22080d000b0b2013200b2903003703002014200c2903003703002015200d2903003703002016201728020036020020022002290390013703f00120022002290390023703e00120022006360224200220053602202002200336021c20024100360218200a0d000b0b20024100360280010b200241186a10b902200041086a200241086a41086a280200360200200020022903083702000c060b41a79dc800412b41e0f6c4001033000b1038000b1039000b41a79dc800412b41e0f6c4001033000b41a79dc800412b41e0f6c4001033000b2000410036020820004208370200200110b9020b200241a0026a24000bd62c080a7f017e017f047e147f017e017f017e230041d0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110f4042003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00410241012000200a41306c6a220d290300220e200d41506a220f290300221056200d41086a2903002211200f41086a29030022125620112012511b220f1b200f200d41306a29030022132010200e200f1b221056200d41386a290300220e20122011200f1b221156200e2011511b22141b2013201020141b2000200a200a417f6a2215200f1b221641306c6a220d29030056200e201120141b2211200d41086a29030022125620112012511b22176a2000200c41306c6a220d290300220e200d41506a2218290300221056200d41086a2903002211201841086a29030022125620112012511b22186a2000200c410172221941306c6a220d29030022132010200e20181b221056200d41086a290300220e2012201120181b221156200e2011511b221a6a20132010201a1b2000200c200c417f6a221b20181b221c41306c6a220d29030056200e2011201a1b2211200d41086a29030022125620112012511b221d6a2000200b41306c6a220d290300220e200d41506a221e290300221056200d41086a2903002211201e41086a29030022125620112012511b221e6a200d41306a29030022132010200e201e1b221056200d41386a290300220e20122011201e1b221156200e2011511b221f6a20132010201f1b2000200b200b417f6a2220201e1b222141306c6a220d29030056200e2011201f1b2211200d41086a29030022125620112012511b22066a210d2021200b41016a2020200b201e1b201f1b20061b210b201c2019201b200c20181b201a1b201d1b210c2016200a41016a2015200a200f1b20141b20171b210a0b200d2000200c41306c6a220f290300220e2000200a41306c6a2218290300221056200f41086a2903002211201841086a29030022125620112012511b220f6a2000200b41306c6a220d29030022132010200e200f1b221056200d41086a290300220e20122011200f1b221156200e2011511b220d6a211820132010200d1b2000200c200a200f1b222141306c6a221e29030058200e2011200d1b2211201e41086a29030022125820112012511b450d01200b200a200c200f1b200d1b21210c020b2000200110f5040c0f0b201841016a2218410c490d0002402001410176220b450d002000200141306c6a41506a210a2000210c0340200441a0026a41286a220f200c41286a220d290300370300200441a0026a41206a2218200c41206a221e290300370300200441a0026a41186a2214200c41186a221a290300370300200441a0026a41106a221f200c41106a2215290300370300200441a0026a41086a2216200c41086a22172903003703002004200c2903003703a002200a41086a22192903002111200a41106a221b2903002112200a41186a221c290300210e200a41206a221d2903002110200a41286a22202903002113200c200a290300370300200d2013370300201e2010370300201a200e37030020152012370300201720113703002020200f290300370300201d2018290300370300201c2014290300370300201b201f29030037030020192016290300370300200a20042903a002370300200c41306a210c200a41506a210a200b417f6a220b0d000b0b20012021417f736a21214101210a0c010b201845210a0b0240200a452009724101710d002000200110f6040d0d0b2002450d02202120014f0d01024020022903002000202141306c6a220a29030056200241086a2903002211200a41086a220c29030022125620112012511b450d0020002108200121070c040b200441a0026a41286a221a200041286a2218290300370300200441a0026a41206a221f200041206a221e290300370300200441a0026a41186a2215200041186a2214290300370300200441a0026a41106a2216200041106a220b290300370300200441a0026a41086a2217200041086a220f290300370300200420002903003703a002200c2903002111200a41106a220d2903002112200a41186a2219290300210e200a41206a221b2903002110200a41286a221c29030021132000200a29030037030020182013370300201e20103703002014200e370300200b2012370300200f2011370300201c201a290300370300201b201f29030037030020192015290300370300200d2016290300370300200c2017290300370300200a20042903a002370300200f29030021112000290300210e200441186a221c2018290300370300200441106a221d201e290300370300200441086a222020142903003703002004200b290300370300200041506a2119200041306a211b4100210c2001210b03400240200c200b417f6a220f4f0d00201b200c41306c6a210a0340200e200a290300582011200a41086a29030022125820112012511b450d01200a41306a210a200f200c41016a220c470d000b200f210c0b2019200b41306c6a210a02400340200c200b417f6a220b4f0d01200a2903002112200a41086a210f200a41506a220d210a200e2012562011200f29030022125620112012511b0d000b201a201b200c41306c6a220a41286a220f290300370300201f200a41206a22212903003703002015200a41186a22062903003703002016200a41106a22222903003703002017200a41086a22232903003703002004200a2903003703a002200d41386a22242903002112200d41c0006a22252903002110200d41c8006a22262903002113200d41d0006a22272903002128200d41d8006a2229290300212a200a200d41306a220d290300370300200f202a370300202120283703002006201337030020222010370300202320123703002029201a2903003703002027201f290300370300202620152903003703002025201629030037030020242017290300370300200d20042903a002370300200c41016a210c0c010b0b2000200e370300200020113703082000200429030037031020142020290300370300201e201d2903003703002018201c29030037030002402001200c41016a220a490d002000200a41306c6a21002001200a6b220141154f0d010c0c0b0b200a200141c499c500104c000b2021200141fc99c5001036000b2007450d010b202120074f0d01200441a0026a41286a221f200841286a2222290300370300200441a0026a41206a2215200841206a2223290300370300200441a0026a41186a2216200841186a2224290300370300200441a0026a41106a2217200841106a2225290300370300200441a0026a41086a2219200841086a2226290300370300200420082903003703a0022008202141306c6a220a41086a220c2903002111200a41106a220b2903002112200a41186a220f290300210e200a41206a220d2903002110200a41286a220029030021132008200a29030037030020222013370300202320103703002024200e37030020252012370300202620113703002000201f290300370300200d2015290300370300200f2016290300370300200b2017290300370300200c2019290300370300200a20042903a0023703002026290300211120082903002112200441186a22272022290300370300200441106a22292023290300370300200441086a2205202429030037030020042025290300370300200841306a21184100211c2007417f6a220f450d022018210a0340200a290300201256200a41086a290300220e201156200e2011511b450d03200a41306a210a200f201c41016a221c470d000b200f211c0c020b410041004180bdc7001036000b202120074190bdc7001036000b2008200741306c6a210a200f210b02400340200a2101200b220c201c4d22060d01200c417f6a210b200141506a220a290300201258200a41086a290300220e201158200e2011511b0d000b0b0240200c201c490d00200f200c490d024180012114410021004100210f4100210d4100210b418001211a2018201c41306c6a220921180340200120186b220a41306e210c0240200a41afe0004b221b0d00200c41807f6a200c200f200049200b200d49221e72221d1b210a0240201d450d00201a200a201e1b211a200a2014201e1b21140c010b200a200a410176221a6b21140b0240200b200d470d000240201a0d00200441206a220d210b0c010b4100210c200441206a220b210d2018210a0340200d200c3a0000200d410041014102200a2903002210201285200a41086a290300220e20118584501b2010201254200e201154200e2011511b1b41027441e499c5006a2802006a210d200a41306a210a201a200c41016a220c470d000b0b0240200f2000470d00024020140d00200441a0016a2200210f0c010b200141506a210a4100210c200441a0016a220f210003402000200c3a00002000410041014102200a2903002210201285200a41086a290300220e20118584501b2010201254200e201154200e2011511b1b41027441f099c5006a2802006a2100200a41506a210a2014200c41016a220c470d000b0b02402000200f6b220a200d200b6b220c200c200a4b1b221e450d00201f2018200b2d000041306c6a220a41286a2903003703002015200a41206a2903003703002016200a41186a2903003703002017200a41106a2903003703002019200a41086a2903003703002004200a2903003703a0022018200b2d000041306c6a220a2001200f2d0000417f7341306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a2903003703000240201e4101460d00201e417f6a211e03402001200f2d0000417f7341306c6a220a2018200b2d000141306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a2903003703002018200b2d000141306c6a220a2001200f2d0001417f7341306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a290300370300200f41016a210f200b41016a210b201e417f6a221e0d000b0b2001200f2d0000417f7341306c6a220a20042903a002370300200a41286a201f290300370300200a41206a2015290300370300200a41186a2016290300370300200a41106a2017290300370300200a41086a2019290300370300200f41016a210f200b41016a210b0b2018201a41306c6a2018200b200d461b21182001410020146b41306c6a2001200f2000461b2101201b0d000b02400240200b200d4f0d002001210a0340201f2018200d417f6a220d2d000041306c6a220c41286a220f2903003703002015200c41206a22002903003703002016200c41186a22012903003703002017200c41106a221e2903003703002019200c41086a22142903003703002004200c2903003703a002200a41506a220a41086a221a290300210e200a41106a221b2903002110200a41186a221d2903002113200a41206a22202903002128200a41286a2221290300212a200c200a290300370300200f202a3703002000202837030020012013370300201e20103703002014200e3703002021201f29030037030020202015290300370300201d2016290300370300201b2017290300370300201a2019290300370300200a20042903a002370300200b200d490d000c020b0b2018210a200f20004f0d0003402000417f6a22002d0000210c201f200a41286a220b2903003703002015200a41206a220d2903003703002016200a41186a22182903003703002017200a41106a221e2903003703002019200a41086a22142903003703002004200a2903003703a0022001200c417f7341306c6a220c41086a221a290300210e200c41106a221b2903002110200c41186a221d2903002113200c41206a22202903002128200c41286a2221290300212a200a200c290300370300200b202a370300200d202837030020182013370300201e20103703002014200e3703002021201f29030037030020202015290300370300201d2016290300370300201b2017290300370300201a2019290300370300200c20042903a002370300200a41306a210a200f2000490d000b0b2008201137030820082012370300200820042903003703102024200529030037030020232029290300370300202220272903003703002007200a20096b41306e201c6a22014d0d03201f202229030037030020152023290300370300201620242903003703002017202529030037030020192026290300370300200420082903003703a0022008200141306c6a220a41086a220c2903002111200a41106a220b2903002112200a41186a220f290300210e200a41206a220d2903002110200a41286a220029030021132008200a29030037030020222013370300202320103703002024200e37030020252012370300202620113703002000201f290300370300200d2015290300370300200f2016290300370300200b2017290300370300200c2019290300370300200a20042903a002370300200720016b220c450d04200c20012001200c4b1b210b2007410376210f200a41306a2100024002402001200c417f6a220c490d002000200c200a2003109c02200821000c010b2008200120022003109c02200a2102200c21010b200b200f4f2105200141154f0d010c050b0b201c200c41d499c500104c000b200c200f41d499c500104b000b200120074190bdc7001036000b4189a7c700411c41b8a1cc001033000b20014102490d00200041a07f6a210d410021184101210c0340200c41016a210f02402000200c41306c6a220b290300220e200b41506a220a29030058200b41086a221e2903002211200a41086a221429030022125820112012511b0d00200441186a221a200b41286a221f290300370300200441106a2215200b41206a2216290300370300200441086a2217200b41186a22192903003703002004200b290310370300200b200a290300370300201e2014290300370300200b41106a200a41106a2903003703002019200a41186a2903003703002016200a41206a290300370300201f200a41286a2903003703002000200c417f6a221e41306c6a211402400240201e0d004100211e0c010b2018210c200d210a200e200b41a07f6a220b290300582011200b41086a29030022125820112012511b0d00024002400340200a4188016a200a41d8006a290300370300200a4180016a200a41d0006a290300370300200a41f8006a200a41c8006a290300370300200a41f0006a200a41c0006a290300370300200a41e8006a200a41386a290300370300200a41e0006a200a41306a290300370300200c4101460d01200a2903002112200a41086a210b200c417f6a210c200a41506a210a200e2012562011200b29030022125620112012511b0d000c020b0b4100210c0b2000200c41306c6a2114200c211e0b2014200e370300201420113703082000201e41306c6a220a41286a201a290300370300200a41206a2015290300370300200a41186a2017290300370300200a20042903003703100b201841016a2118200d41306a210d200f210c200f2001470d000b0b200441d0026a24000ba20703027f017e067f230041e0006b2203240041eebec500ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004102941acf7c100ad4280808080a00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041029200320013602382003200341386aad4280808080c000841002220429000037034820041029200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a10750240024002400240412010272204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410022202290000370348200210292001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a1075200410292003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210272204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001102722040d010c050b200b2001460d002004200b2001102b2204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b102b2204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b2001102b2204450d040b200441206a200a200710e4071a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10272204450d050c010b2001200b460d0020042001200b102b2204450d040b200420066a2009200810e4071a200020023602082000200b360204200020043602000240200328023c450d00200910290b0240200328022c450d00200a10290b200341e0006a24000f0b1039000b1038000b1032000b1030000bac0201037f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d00410021020c010b200328021421042003200341186a280200360224200320013602202003200341206a10c8010240024020032802000d0020032802042105410121020c010b4100210220034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b0b2004450d00200110290b2000200536020420002002360200200341e0006a24000ba20703027f017e067f230041e0006b2203240041eebec500ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004102941a8f8c100ad4280808080a00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041029200320013602382003200341386aad4280808080c000841002220429000037034820041029200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a10750240024002400240412010272204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410022202290000370348200210292001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a1075200410292003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210272204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001102722040d010c050b200b2001460d002004200b2001102b2204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b102b2204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b2001102b2204450d040b200441206a200a200710e4071a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10272204450d050c010b2001200b460d0020042001200b102b2204450d040b200420066a2009200810e4071a200020023602082000200b360204200020043602000240200328023c450d00200910290b0240200328022c450d00200a10290b200341e0006a24000f0b1039000b1038000b1032000b1030000be70403057f017e037f23004180016b22022400200241206a41186a22034200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032041eebec500ad4280808080f000841001220629000021072005200641086a290000370300200220073703202006102941f0f5c100ad4280808080900184100122062900002107200241086a2208200641086a2900003703002002200737030020061029200420022903002207370300200241e0006a41086a22062005290300370300200241e0006a41106a22092007370300200241e0006a41186a220a200829030037030020022002290320370360200241206a200241e0006a10d0010240024020022903204202520d00200041003602200c010b200241d0006a2004280200200110d701200241206a20022802502208200228025810a102200a2003290300370300200920042903003703002006200529030037030020022002290320370360200241cc006a280200210402400240200228024022050d0042002107200241186a4200370300200241106a420037030041082105200241086a4200370300200242003703000c010b200241086a200241e0006a41086a290300370300200241106a200241e0006a41106a290300370300200241186a200241e0006a41186a29030037030020022002290360370300200229024421070b02402002280254450d00200810290b2000200229030037030020002007370224200020053602202000412c6a2004360200200041186a200241186a290300370300200041106a200241106a290300370300200041086a200241086a2903003703000b20024180016a24000b860301017f230041f0006b220324002003200236020420032001360200200341086a2002ad4220862001ad841007108b0202400240200328020822010d00200041003602200c010b200328020c21022003200341086a41086a28020036024c20032001360248200341186a200341c8006a1083020240024020032802380d0020034100360258200342013703502003410d360264200320033602602003200341d0006a36026c2003412c6a41013602002003420137021c200341f4eaca003602182003200341e0006a360228200341ec006a41a8a3c800200341186a10371a2003350258422086200335025084100802402003280254450d00200328025010290b200041003602200c010b20002003290318370300200041286a200341186a41286a290300370300200041206a200341186a41206a290300370300200041186a200341186a41186a290300370300200041106a200341186a41106a290300370300200041086a200341186a41086a2903003703000b2002450d00200110290b200341f0006a24000b880a0a047f017e027f037e017f027e067f017e037f017e230041e0016b22032400200241346a2802002104200241306a2802002105200241386a2802002106200341c0006a41186a200241186a290000370300200341c0006a41106a200241106a290000370300200341c0006a41086a200241086a29000037030020032002290000370340024002402006ad42307e2207422088a70d002007a72202417f4c0d000240024020020d00410821080c010b200210272208450d020b4100210920034100360268200320083602602003200241306e3602640240024020060d004200210a4200210b4200210c420021070c010b200641306c210d200341b0016a41106a21064200210a4200210b4200210c42002107200521020340200241286a290300210e200241206a290300210f200341f0006a41186a2210200241186a290300370300200341f0006a41106a2211200241106a290300370300200341f0006a41086a2212200241086a29030037030020032002290300370370200341b0016a41186a2213420037030020064200370300200341b0016a41086a22144200370300200342003703b00141dcbec500ad42808080808001841001221529000021162014201541086a290000370300200320163703b00120151029419fe3c200ad4280808080d00184100122152900002116200341d0016a41086a2217201541086a290000370300200320163703d00120151029200620032903d001370000200641086a201729030037000020034190016a41086a2215201429030037030020034190016a41106a2217200629030037030020034190016a41186a22182013290300370300200320032903b00137039001200341286a20034190016a412010e301200341186a2003290330200341286a41106a290300427f420010e007200341086a20032903184200200328022822191b221642012016420156200341186a41086a290300420020191b22164200522016501b22191b2016420020191b200f200e10d5072018201029030037030020172011290300370300201520122903003703002003200329037037039001200341086a41086a29030021162003290308210e0240024020034190016a200341c0006a412010e707450d0020132018290300370300200620172903003703002014201529030037030020032003290390013703b001024020092003280264470d00200341e0006a2009410110900120032802602108200328026821090b2008200941306c6a221520163703082015200e370300201520032903b001370310201541186a2014290300370300201541206a2006290300370300201541286a20132903003703002003200941016a22093602680c010b427f200b20167c200a200e7c221a200a542214ad7c220f2014200f200b54200f200b511b22141b210b427f201a20141b210a0b200241306a2102427f200720167c200c200e7c2216200c542214ad7c220c2014200c200754200c2007511b22141b2107427f201620141b210c200d41506a220d0d000b0b02402004450d00200441306c450d00200510290b2000200c37032020002003290340370000200041386a200b370300200041306a200a370300200041286a2007370300200041c0006a2003290360370200200041186a200341c0006a41186a290300370000200041106a200341c0006a41106a290300370000200041086a200341c0006a41086a290300370000200041c8006a200341e0006a41086a280200360200200341e0016a24000f0b1038000b1039000bc41502087f047e230041d0016b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220341174b0d0020030e180102030405060708090a0b0c0d0e0f101112131415161718010b419cf7ca00412841b8a1cc001033000b200041013a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000c170b200041023a0000200041106a200141106a290300370300200041086a200141086a2903003703000c160b200041033a0000200041106a200141106a290300370300200041086a200141086a2903003703000c150b200041043a0000200041046a200141046a2802003602000c140b200041053a0000200041046a200141046a2802003602000c130b2001410c6a280200220441ffffff3f712004470d1320044105742203417f4c0d13200141046a28020021050240024020030d00410121060c010b200310272206450d150b41002101200241003602182002200636021020022003410576360214200241106a41002004109e012002280218210702402004450d0020044105742108200228021020074105746a21090340200920016a2203200520016a2206290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a2900003700002008200141206a2201470d000b200441057441606a41057620076a41016a21070b200241086a200736020020022002290310220a3703002000410c6a2007360200200041046a200a370200200041063a00000c120b200041073a00000c110b200041083a0000200020012d00013a00010c100b200041093a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c0f0b2000410a3a0000200041046a200141046a2802003602000c0e0b2000410b3a00000c0d0b2000410c3a00000c0c0b2001410c6a280200220441ffffff3f712004470d0c20044105742203417f4c0d0c200141046a28020021050240024020030d00410121060c010b200310272206450d0e0b41002101200241003602182002200636021020022003410576360214200241106a41002004109e012002280218210702402004450d0020044105742108200228021020074105746a21090340200920016a2203200520016a2206290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a2900003700002008200141206a2201470d000b200441057441606a41057620076a41016a21070b200241086a200736020020022002290310220a3703002000410c6a2007360200200041046a200a3702002000410d3a00000c0b0b2000410e3a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c0a0b2000410f3a00000c090b200141106a280200220341ffffffff03712003470d0920034102742206417f4c0d09200141046a2802002105200141086a28020021084104210102402006450d00200610272201450d0b0b200241003602182002200136021020022006410276360214200241106a410020031098012002280210200228021822014102746a2008200341027410e4071a200241086a200120036a220136020020022002290310220a370300200041046a2005360200200041086a200a370200200041106a2001360200200041103a00000c080b200141106a2802002203ad42247e220a422088a70d08200aa72206417f4c0d08200141046a2802002108200141086a28020021010240024020060d00410421050c010b200610272205450d0a0b20024100360218200220053602102002200641246e360214200241106a410020031096012002280218210602402003450d00200341246c21052002280210200641246c6a21030340200141086a290200210a200141106a290200210b200141186a290200210c2001290200210d200341206a200141206a280200360200200341186a200c370200200341106a200b370200200341086a200a3702002003200d370200200341246a2103200641016a2106200141246a21012005415c6a22050d000b0b200241086a200636020020022002290310220a370300200041046a2008360200200041086a200a370200200041106a2006360200200041113a00000c070b200041123a0000200041046a200141046a2802003602000c060b200041133a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c050b200041143a0000200041106a200141106a290300370300200041086a200141086a2903003703000c040b200041153a0000200041046a200141046a2902003702000c030b200041163a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c020b2001410c6a280200220320036a22062003490d022006417f4c0d02200141046a28020021050240024020060d00410221080c010b200610272208450d040b200241003602182002200836021020022006410176360214200241106a4100200310a9012002280210200228021822064101746a2005200341017410e4071a200241086a2205200620036a36020020022002290310370300200241106a200141106a10a402200041046a20022903003702002000410c6a2005280200360200200141d8016a2f0100210320012902d001210a200041106a200241106a41c00110e4071a200041d8016a20033b0100200041d0016a200a370300200041173a000020004188026a200141e0016a220141286a29030037030020004180026a200141206a290300370300200041f8016a200141186a290300370300200041f0016a200141106a290300370300200041e8016a200141086a290300370300200041e0016a20012903003703000c010b2001410c6a280200220320036a22062003490d012006417f4c0d01200141046a28020021050240024020060d00410221080c010b200610272208450d030b200241003602182002200836021020022006410176360214200241106a4100200310a9012002280210200228021822064101746a2005200341017410e4071a200241086a2205200620036a36020020022002290310370300200241106a200141106a10a402200041046a20022903003702002000410c6a2005280200360200200141d8016a2f0100210320012902d001210a200041106a200241106a41c00110e4071a200041d8016a20033b0100200041d0016a200a370300200041183a000020004188026a200141e0016a220141286a29030037030020004180026a200141206a290300370300200041f8016a200141186a290300370300200041f0016a200141106a290300370300200041e8016a200141086a290300370300200041e0016a20012903003703000b200241d0016a24000f0b1038000b1039000bc11702057f017e23004180026b22022400024002402001280208220341ffffffff01712003470d0020034103742204417f4c0d00200128020021050240024020040d00410421060c010b200410272206450d020b200241003602f801200220063602f001200220044103763602f401200241f0016a41002003108d0120022802f00120022802f80122044103746a2005200341037410e4071a200041086a200420036a360200200020022903f001370200200141146a2802002204ad420c7e2207422088a70d002007a72203417f4c0d00200128020c21064104210502402003450d00200310272205450d020b200241003602f801200220053602f00120022003410c6e3602f401200241f0016a41002004109d0120022802f00120022802f8012205410c6c6a2006200310e4071a200241086a200520046a360200200220022903f001370300200141206a280200220341ffffffff00712003470d0020034104742204417f4c0d00200128021821064104210502402004450d00200410272205450d020b200241003602f801200220053602f001200220044104763602f401200241f0016a41002003109c0120022802f00120022802f80122044104746a2006200341047410e4071a200241186a200420036a360200200220022903f0013703102001412c6a2802002204ad42147e2207422088a70d002007a72203417f4c0d00200128022421050240024020030d00410421060c010b200310272206450d020b200241003602f801200220063602f0012002200341146e3602f401200241f0016a4100200410a00120022802f00120022802f801220641146c6a2005200310e4071a200241286a200620046a360200200220022903f001370320200141386a2802002204ad42187e2207422088a70d002007a72203417f4c0d00200128023021050240024020030d00410421060c010b200310272206450d020b200241003602f801200220063602f0012002200341186e3602f401200241f0016a4100200410990120022802f00120022802f801220641186c6a2005200310e4071a200241386a200620046a360200200220022903f001370330200141c4006a2802002204ad421c7e2207422088a70d002007a72203417f4c0d00200128023c21050240024020030d00410421060c010b200310272206450d020b200241003602f801200220063602f00120022003411c6e3602f401200241f0016a4100200410940120022802f00120022802f8012206411c6c6a2005200310e4071a200241c8006a200620046a360200200220022903f001370340200141d0006a280200220341ffffff3f712003470d0020034105742204417f4c0d00200128024821050240024020040d00410421060c010b200410272206450d020b200241003602f801200220063602f001200220044105763602f401200241f0016a4100200310950120022802f00120022802f80122044105746a2005200341057410e4071a200241d8006a200420036a360200200220022903f001370350200141dc006a2802002204ad42247e2207422088a70d002007a72203417f4c0d00200128025421050240024020030d00410421060c010b200310272206450d020b200241003602f801200220063602f0012002200341246e3602f401200241f0016a4100200410960120022802f00120022802f801220641246c6a2005200310e4071a200241e8006a200620046a360200200220022903f001370360200141e8006a2802002204ad42287e2207422088a70d002007a72203417f4c0d00200128026021050240024020030d00410421060c010b200310272206450d020b200241003602f801200220063602f0012002200341286e3602f401200241f0016a4100200410ad0120022802f00120022802f801220641286c6a2005200310e4071a200241f8006a200620046a360200200220022903f001370370200141f4006a2802002204ad422c7e2207422088a70d002007a72203417f4c0d00200128026c21050240024020030d00410421060c010b200310272206450d020b200241003602f801200220063602f00120022003412c6e3602f401200241f0016a4100200410930120022802f00120022802f8012206412c6c6a2005200310e4071a20024188016a200620046a360200200220022903f0013703800120014180016a2802002204ad42307e2207422088a70d002007a72203417f4c0d00200128027821050240024020030d00410421060c010b200310272206450d020b200241003602f801200220063602f0012002200341306e3602f401200241f0016a4100200410ab0120022802f00120022802f801220641306c6a2005200310e4071a20024198016a200620046a360200200220022903f001370390012001418c016a2802002204ad42347e2207422088a70d002007a72203417f4c0d0020012802840121050240024020030d00410421060c010b200310272206450d020b200241003602f801200220063602f0012002200341346e3602f401200241f0016a4100200410ae0120022802f00120022802f801220641346c6a2005200310e4071a200241a8016a200620046a360200200220022903f0013703a00120014198016a2802002204ad42387e2207422088a70d002007a72203417f4c0d0020012802900121050240024020030d00410421060c010b200310272206450d020b200241003602f801200220063602f0012002200341386e3602f401200241f0016a4100200410aa0120022802f00120022802f801220641386c6a2005200310e4071a200241b8016a200620046a360200200220022903f0013703b001200141a4016a2802002204ad423c7e2207422088a70d002007a72203417f4c0d00200128029c0121050240024020030d00410421060c010b200310272206450d020b200241003602f801200220063602f00120022003413c6e3602f401200241f0016a41002004109b0120022802f00120022802f8012206413c6c6a2005200310e4071a200241c8016a200620046a360200200220022903f0013703c001200141b0016a280200220341ffffff1f712003470d0020034106742204417f4c0d0020012802a80121050240024020040d00410421060c010b200410272206450d020b200241003602f801200220063602f001200220044106763602f401200241f0016a4100200310910120022802f00120022802f80122044106746a2005200341067410e4071a200241d8016a200420036a360200200220022903f0013703d001200141bc016a2802002204ad42c4007e2207422088a70d002007a72203417f4c0d0020012802b40121010240024020030d00410421050c010b200310272205450d020b200241003602f801200220053602f0012002200341c4006e3602f401200241f0016a41002004109f0120022802f00120022802f801220541c4006c6a2001200310e4071a200241e0016a41086a2201200520046a360200200220022903f0013703e001200041146a200241086a2802003602002000200229030037020c20002002290310370218200041206a200241106a41086a280200360200200020022903203702242000412c6a200241206a41086a28020036020020002002290330370230200041386a200241306a41086a280200360200200041c4006a200241c0006a41086a2802003602002000200229034037023c200041d0006a200241d0006a41086a28020036020020002002290350370248200041dc006a200241e0006a41086a28020036020020002002290360370254200041e8006a200241f0006a41086a28020036020020002002290370370260200041f4006a20024180016a41086a280200360200200020022903800137026c20004180016a20024190016a41086a28020036020020002002290390013702782000418c016a200241a0016a41086a280200360200200020022903a0013702840120004198016a200241b0016a41086a280200360200200020022903b00137029001200041a4016a200241c0016a41086a280200360200200020022903c00137029c01200041b0016a200241d0016a41086a280200360200200020022903d0013702a801200041bc016a2001280200360200200020022903e0013702b40120024180026a24000f0b1038000b1039000b9ddc0206017f037e147f017e127f087e230041800c6b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e19000102030405060708090a0b0c0d0e0f101112131415161718000b200341d40a6a4101360200200342013702c40a20034198e3ca003602c00a200341043602bc07200341cce3ca003602b8072003200341b8076a3602d00a200341c00a6a4180a6cc001040000b200141306a2903002104200141286a2903002105200141196a2900002106200141186a2d00002107200141176a2d00002108200141156a2f00002109200141146a2d0000210a200141136a2d0000210b200141116a2f0000210c200141106a2d0000210d2001410f6a2d0000210e2001410d6a2f0000210f2001410c6a2d000021102001410b6a2d00002111200141096a2f00002112200141086a2d00002113200141076a2d00002114200141056a2f00002115200141046a2d00002116200141036a2d00002117200141026a2d00002118200141216a2d0000211920012d0001211a2002411a6a290100211b200241196a2d0000211c200241186a2d0000211d200241166a2f0100211e200241156a2d0000211f200241146a2d00002120200241126a2f01002121200241116a2d00002122200241106a2d000021232002410e6a2f010021242002410d6a2d000021252002410c6a2d000021262002410a6a2f01002127200241096a2d00002128200241086a2d00002129200241066a2f0100212a200241056a2d0000212b200241046a2d0000212c200241026a2f0100212d41012101024020022d00000d0020022d000141014721010b2003201b3701c0092003201c3a00bf092003201d3a00be092003201e3b01bc092003201f3a00bb09200320203a00ba09200320213b01b809200320223a00b709200320233a00b609200320243b01b409200320253a00b309200320263a00b209200320273b01b009200320283a00af09200320293a00ae092003202a3b01ac092003202b3a00ab092003202c3a00aa092003202d3b01a8090240024020010d00200341900a6a41186a200341a8096a41186a290100370300200341900a6a41106a200341a8096a41106a290100370300200341900a6a41086a200341a8096a41086a290100370300200320032901a8093703900a200341c00a6a200341900a6a10d801200341206a20032802c00a220120032802c80a4180a6cc004100410010c70120032802202102024020032802c40a450d00200110290b024020024101470d0041cab4c0002102410d210141808008211c4103211d0c020b200320063703d007200320073a00cf07200320083a00ce07200320093b01cc072003200a3a00cb072003200b3a00ca072003200c3b01c8072003200d3a00c7072003200e3a00c6072003200f3b01c407200320103a00c307200320113a00c207200320123b01c007200320133a00bf07200320143a00be07200320153b01bc07200320163a00bb07200320173a00ba07200320183a00b9072003201a3a00b807200341c00a6a200341b8076a10db01200341186a20032802c00a220120032802c80a4180a6cc004100410010c70120032802182102024020032802c40a450d00200110290b024020024101470d00410d210141bdb4c00021024180800c211c4103211d0c020b024020054280c8afa0255441002004501b450d00411121014181b4c00021024180801c211c4103211d0c020b200341c00a6a200341900a6a10d80120033502c80a211b20032802c00a2101412010272202450d19200220032903b807370000200241186a200341b8076a41186a290300370000200241106a200341b8076a41106a290300370000200241086a200341b8076a41086a290300370000201b4220862001ad842002ad4280808080800484100320021029024020032802c40a450d00200110290b200341c00a6a200341900a6a10a60220033502c80a211b20032802c00a210102400240201941037122024103470d0041012102420021064101211c0c010b024002400240024020020e03000102000b4100211c0c020b4101211c0c010b4102211c0b2003201c3a009007410110272202450d4f2002201c3a00004100211c42808080801021060b201b4220862001ad8420062002ad8410030240201c0d00200210290b024020032802c40a450d00200110290b200341900a6a10a70241eebec500ad4280808080f00084221b10012202280000210120022900042106200228000c211c2002102941c4f5c100ad4280808080a0018410012202290000212e2002290008212f200210292003202f370190092003202e370188092003201c36018409200320063701fc08200320013601f808200341106a200341f8086a412010fc01200328021421012003280210211c201b10012202280000211d2002290004211b200228000c211e2002102941c8f2c100ad4280808080c001841001220229000021062002290008212e200210292003202e3701900920032006370188092003201e360184092003201b3701fc082003201d3601f808200341086a200341f8086a412010fc01200328020c21022003280208211d200341f8086a200341900a6a10a802200341c00a6a20032802f808221e20032802800910a902410020014100201c1b221c200241d400201d1b6b22022002201c4b1b2102200341c00a6a41106a290300420020032903c00a42015122011b211b20032903c80a420020011b2106024020032802fc08450d00201e10290b200341c00a6a41086a41063a0000200341c90a6a20032903900a370000200341d10a6a200341900a6a41086a2201290300370000200341d90a6a200341900a6a41106a221d290300370000200341e10a6a200341900a6a41186a221e290300370000200341f80a6a221f201b20042006200554201b200454201b2004511b22201b221b370300200341f00a6a2006200520201b2204370300200341043a00c00a200341c00a6a10cb0120012f01002120201d2f01002121201e290300210520032f01900a212220032d00920a212320032d00930a212420032f01940a212520032d00960a212620032d00970a212720032d009a0a212820032d009b0a212920032f019c0a212a20032d009e0a212b20032d009f0a212c20032d00a20a212d20032d00a30a210720032f01a40a210820032d00a60a210920032d00a70a210a2003410036028009200342043703f808200341f8086a41004100201c20026b221e201e201c4b1b109801200328028009211d0240201c20024d0d0020032802f808201d4102746a2101034020012002360200200141046a2101201c200241016a2202470d000b201e201d6a211d0b20034190076a41086a2202201d360200200341900b6a20053703002003418f0b6a200a3a00002003418e0b6a20093a00002003418c0b6a20083b01002003418b0b6a20073a00002003418a0b6a202d3a0000200341880b6a20213b0100200341870b6a202c3a0000200341860b6a202b3a0000200341840b6a202a3b0100200341830b6a20293a0000200341820b6a20283a0000200341800b6a20203b0100200341ff0a6a20273a0000200341fe0a6a20263a0000200341fc0a6a20253b0100200341fb0a6a20243a0000200341fa0a6a20233a0000200320032903f80837039007200320223b01f80a200341c00a6a41186a201b370300200341e80a6a4100360200200341f40a6a2002280200360200200320043703d00a2003201b3703c80a200320043703c00a200342083703e00a20032003290390073702ec0a200342f3e885db96cddbb3203703c809200341c8096a201f2004201b411f10aa02200341f8086a200341b8076a10db0120032802f80821022003200328028009360294072003200236029007200341c00a6a20034190076a10e401024020032802fc08450d00200210290b024020032802e40a2202450d00200241186c450d0020032802e00a10290b0240200341f00a6a28020041ffffffff0371450d0020032802ec0a10290b20004200370308200042003703000c510b4102211d4100211c0b20004200370308200041206a20013602002000411c6a2002360200200041186a201c4180801c71201d7241801272360200200042013703000c4f0b200141106a290300212e200141086a290300212f2002411a6a2901002106200241196a2d00002120200241186a2d00002121200241166a2f01002122200241156a2d00002123200241146a2d00002124200241126a2f01002125200241116a2d00002126200241106a2d00002127410e21012002410e6a2f010021282002410d6a2d000021292002410c6a2d0000212a2002410a6a2f0100212b200241096a2d0000212c200241086a2d0000212d200241066a2f01002107200241056a2d00002108200241046a2d00002109200241026a2f0100210a20022d0001211f20022d0000211e41eebec500ad4280808080f0008410012202280000211c2002290004211b200228000c211d2002102941eab8c000ad42808080809002841001220229000021042002290008210520021029200320053701900920032004370188092003201d360184092003201b3701fc082003201c3601f808200341286a200341f8086a10b10141032102024002402003280228417d71450d0041ecb0c000211c418080f000211d0c010b0240201e41ff01710d00201f41ff01714101470d00200320063703880a200320203a00870a200320213a00860a200320223b01840a200320233a00830a200320243a00820a200320253b01800a200320263a00ff09200320273a00fe09200320283b01fc09200320293a00fb092003202a3a00fa092003202b3b01f8092003202c3a00f7092003202d3a00f609200320073b01f409200320083a00f309200320093a00f2092003200a3b01f009200341b8076a200341f0096a10d801200341c00a6a20032802b807221d20032802c00710cd01200341d90a6a290000211b200341d80a6a2d0000211e200341d70a6a2d0000211f200341d50a6a2f00002120200341d40a6a2d00002121200341d30a6a2d00002122200341d10a6a2f00002123200341d00a6a2d00002124200341cf0a6a2d00002125200341cd0a6a2f00002126200341cc0a6a2d00002127200341cb0a6a2d00002128200341c90a6a2f0000212941082101200341c00a6a41086a2d0000212a20032d00c70a212b20032f00c50a212c20032d00c40a212d20032d00c30a210720032d00c20a210820032d00c10a210920032d00c00a211c024020032802bc07450d00201d10290b0240201c41ff01714101460d0041d7b4c000211c41808004211d0c020b2003201b3703a80a2003201e3a00a70a2003201f3a00a60a200320203b01a40a200320213a00a30a200320223a00a20a200320233b01a00a200320243a009f0a200320253a009e0a200320263b019c0a200320273a009b0a200320283a009a0a200320293b01980a2003202a3a00970a2003202b3a00960a2003202c3b01940a2003202d3a00930a200320073a00920a200320083a00910a200320093a00900a200341a8096a200341900a6a10db01200341c00a6a20032802a809220120032802b00910e201200341f8086a41086a221c200341fc0a6a290200370300200341f8086a41106a221d200341840b6a290200370300200341f8086a41186a221e2003418c0b6a290200370300200341f8086a41206a221f200341940b6a2802003602002003200341f40a6a2902003703f8080240024020032802e00a2220450d00200341c00a6a41186a2903002105200341c00a6a41086a2903002104200341f00a6a2802002102200341ec0a6a2802002121200341e80a6a280200212220032903d00a210620032903c00a211b20032802e40a212320034190076a41206a201f28020036020020034190076a41186a201e29030037030020034190076a41106a201d29030037030020034190076a41086a201c290300370300200320032903f80837039007024020032802ac09450d00200110290b200341c8096a41086a220120034190076a41086a290300370300200341c8096a41106a221c20034190076a41106a290300370300200341c8096a41186a221d20034190076a41186a290300370300200341c8096a41206a221e20034190076a41206a280200360200200341b8076a41186a2005370300200341e8076a2002360200200341e0076a2022360200200341dc076a202336020020032003290390073703c809200320063703c8072003201b3703b807200320213602e407200320203602d807200320043703c0072003418c086a201e28020036020020034184086a201d290300370200200341fc076a201c290300370200200341f4076a2001290300370200200341ec076a20032903c809370200200341f8086a200341f0096a10a802200341c00a6a20032802f808220120032802800910a902200341c00a6a41106a290300420020032903c00a42015122021b210520032903c80a420020021b2106024020032802fc08450d0020011029200341b8076a41086a290300210420032903b807211b0b2006201b7d2230200656200520047d2006201b54ad7d220620055620062005511b0d01200341b8076a41186a22022903002131200320032903c8072232202f20302030202f562006202e562006202e511b22011b22057c222f3703c80720022031202e200620011b22067c202f203254ad7c37030020032005201b7c221b3703b8072003200620047c201b200554ad7c22043703c007200341c00a6a41386a2006370300200341f00a6a2005370300200341c00a6a41086a41063a0000200341c90a6a20032903f009370000200341d10a6a200341f0096a41086a290300370000200341d90a6a200341800a6a290300370000200341e10a6a200341f0096a41186a290300370000200341043a00c00a200341c00a6a10cb01200342f3e885db96cddbb3203703900720034190076a200341b8076a41386a201b2004411f10aa02200341c00a6a200341900a6a10db0120032802c00a2102200320032802c80a3602fc08200320023602f808200341b8076a200341f8086a10e401024020032802c40a450d00200210290b024020032802dc072202450d00200241186c450d0020032802d80710290b20032802e80741ffffffff0371450d5120032802e40710290c510b024020032802ac09450d00200110290b41dfb4c000211c410d21014100211d0c020b024020032802dc072202450d00200241186c450d0020032802d80710290b20032802e80741ffffffff0371450d4f20032802e40710290c4f0b410221024100211d0b20004200370308200041206a20013602002000411c6a201c360200200041186a201d418080fc007120027241801272360200200042013703000c4e0b200141106a290300212e200141086a290300212f2002411a6a2901002106200241196a2d00002120200241186a2d00002121200241166a2f01002122200241156a2d00002123200241146a2d00002124200241126a2f01002125200241116a2d00002126200241106a2d00002127410e21012002410e6a2f010021282002410d6a2d000021292002410c6a2d0000212a2002410a6a2f0100212b200241096a2d0000212c200241086a2d0000212d200241066a2f01002107200241056a2d00002108200241046a2d00002109200241026a2f0100210a20022d0001211f20022d0000211e41eebec500ad4280808080f0008410012202280000211c2002290004211b200228000c211d2002102941eab8c000ad42808080809002841001220229000021042002290008210520021029200320053701900920032004370188092003201d360184092003201b3701fc082003201c3601f808200341386a200341f8086a10b10141032102024002402003280238417d71450d0041ecb0c000211c418080f000211d0c010b0240201e41ff01710d00201f41ff01714101470d00200320063703a80a200320203a00a70a200320213a00a60a200320223b01a40a200320233a00a30a200320243a00a20a200320253b01a00a200320263a009f0a200320273a009e0a200320283b019c0a200320293a009b0a2003202a3a009a0a2003202b3b01980a2003202c3a00970a2003202d3a00960a200320073b01940a200320083a00930a200320093a00920a2003200a3b01900a200341f0096a200341900a6a10db01200341c00a6a20032802f009221f20032802f80910e201200341f8086a41086a2220200341fc0a6a290200370300200341f8086a41106a2221200341840b6a290200370300200341f8086a41186a22222003418c0b6a290200370300200341f8086a41206a2223200341940b6a2802003602002003200341f40a6a2902003703f8080240024020032802e00a221d450d00200341c00a6a41186a290300211b200341c00a6a41086a2903002105200341f00a6a280200211e200341ec0a6a2802002124200341e80a6a280200210120032903d00a210420032903c00a210620032802e40a211c20034190076a41206a202328020036020020034190076a41186a202229030037030020034190076a41106a202129030037030020034190076a41086a2020290300370300200320032903f80837039007024020032802f409450d00201f10290b200341c8096a41086a221f20034190076a41086a290300370300200341c8096a41106a222020034190076a41106a290300370300200341c8096a41186a222120034190076a41186a290300370300200341c8096a41206a222220034190076a41206a280200360200200341b8076a41186a201b370300200341e8076a201e360200200341e0076a2001360200200341dc076a201c36020020032003290390073703c809200320043703c807200320063703b807200320243602e4072003201d3602d807200320053703c0072003418c086a202228020036020020034184086a2021290300370200200341fc076a2020290300370200200341f4076a201f290300370200200341ec076a20032903c8093702002001411f4d0d010240201c450d00201c41186c450d00201d102920032802e807211e0b41f5b3c000211c410c210141808020211d201e41ffffffff0371450d0320032802e40710290c030b024020032802f409450d00201f10290b41dfb4c000211c410d21014100211d0c020b200341b8076a41206a210202402004202f2004202f54201b202e54201b202e511b221e1b2205201b202e201e1b2206844200510d00200341b8076a41186a4200201b20067d2004200554ad7d222e200420057d222f4280c8afa025544100202e501b221e1b37030020034200202f201e1b3703c80741eebec500ad4280808080f000841001221f2800002120201f290004212e201f28000c2121201f102941c4f5c100ad4280808080a001841001221f290000212f201f2900082130201f102920032030370190092003202f3701880920032021360184092003202e3701fc08200320203601f808200341306a200341f8086a412010fc01201b2006201e1b211b20042005201e1b21042003280234411c6a411c20032802301b211e02402001201c470d002002201c4101108f0120032802e007210120032802d807211d0b201d200141186c6a2201201b370308200120043703002001201e360210200320032802e00741016a3602e007200342f3e885db96cddbb3203703900720034190076a200341b8076a41386a20032903b807200341b8076a41086a290300411f10aa02200341c00a6a200341900a6a10db0120032802c00a2101200320032802c80a3602fc08200320013602f808200341b8076a200341f8086a10e401024020032802c40a450d00200110290b200341c00a6a41386a201b370300200341f00a6a2004370300200341c00a6a41086a41073a0000200341c90a6a20032903f007370000200341d10a6a200341f8076a290300370000200341d90a6a20034180086a290300370000200341e10a6a20034188086a290300370000200341043a00c00a200341c00a6a10cb010b0240200241046a2802002201450d00200141186c450d00200228020010290b024020032802e80741ffffffff0371450d0020032802e40710290b20004200370308200042003703000c4f0b410221024100211d0b20004200370308200041206a20013602002000411c6a201c360200200041186a201d418080fc007120027241801272360200200042013703000c4d0b2002411a6a2901002106200241196a2d00002121200241186a2d00002122200241166a2f01002123200241156a2d00002124200241146a2d00002125200241126a2f01002126200241116a2d00002127200241106a2d00002128410e211c2002410e6a2f010021292002410d6a2d0000212a2002410c6a2d0000212b2002410a6a2f0100212c200241096a2d0000212d200241086a2d00002107200241066a2f01002108200241056a2d00002109200241046a2d0000210a200241026a2f0100211e200141046a280200210b20022d0001212020022d0000211f41eebec500ad4280808080f000841001220228000021012002290004211b200228000c211d2002102941eab8c000ad42808080809002841001220229000021042002290008210520021029200320053701900920032004370188092003201d360184092003201b3701fc08200320013601f808200341c8006a200341f8086a10b101024002402003280248417d71450d0041ecb0c000211d4189382102410321010c010b0240201f41ff01710d00202041ff01714101470d00200320063703880a200320213a00870a200320223a00860a200320233b01840a200320243a00830a200320253a00820a200320263b01800a200320273a00ff09200320283a00fe09200320293b01fc092003202a3a00fb092003202b3a00fa092003202c3b01f8092003202d3a00f709200320073a00f609200320083b01f409200320093a00f3092003200a3a00f2092003201e3a00f0092003201e4108763a00f109200341900a6a200341f0096a10db01200341c00a6a20032802900a220220032802980a10e201200341f8086a41086a2201200341fc0a6a290200370300200341f8086a41106a221c200341840b6a290200370300200341f8086a41186a221d2003418c0b6a290200370300200341f8086a41206a221e200341940b6a2802003602002003200341f40a6a2902003703f80802400240024020032802e00a221f450d00200341c00a6a41186a290300211b200341c00a6a41086a290300212e200341f00a6a2802002120200341ec0a6a2802002121200341e80a6a280200212220032903d00a210420032903c00a212f20032802e40a212320034190076a41206a201e28020036020020034190076a41186a201d29030037030020034190076a41106a201c29030037030020034190076a41086a2001290300370300200320032903f80837039007024020032802940a450d00200210290b200341c8096a41086a220220034190076a41086a290300370300200341c8096a41106a220120034190076a41106a290300370300200341c8096a41186a221c20034190076a41186a290300370300200341c8096a41206a221d20034190076a41206a280200360200200341b8076a41186a221e201b370300200341e8076a2020360200200341e0076a2022360200200341dc076a202336020020032003290390073703c809200320043703c8072003202f3703b807200320213602e4072003201f3602d8072003202e3703c0072003418c086a201d28020036020020034184086a2220201c290300370200200341fc076a22212001290300370200200341f4076a22222002290300370200200341ec076a20032903c809370200200341900a6a41186a20034188086a2223290300370300200341900a6a41106a20034180086a2224290300370300200341900a6a41086a200341f8076a2225290300370300200320032903f0073703900a41eebec500ad4280808080f000841001220228000021012002290004211b200228000c211c2002102941c4f5c100ad4280808080a001841001220229000021042002290008210520021029200320053701900920032004370188092003201c360184092003201b3701fc08200320013601f808200341c0006a200341f8086a412010fc0120032802404101460d01201e290300213020032903c807213120032802e007211c0c020b024020032802940a450d00200210290b410d211c41dfb4c000211d41092102410321010c030b2003280244211d200341f8086a41086a200341e4076a221f41086a2802003602002003201f2902003703f80820032802d8072126201e2903002130200341f2076a2d00002127200341f3076a2d0000212820222f01002129200341f6076a2d0000212a200341f7076a2d0000212b20252f01002125200341fa076a2d0000212c200341fb076a2d0000212d20212f01002107200341fe076a2d00002108200341ff076a2d0000210920242f0100212420034182086a2d0000210a20034183086a2d0000210c20202f0100210d20034186086a2d0000210e20034187086a2d0000210f2023290300213220032903c807213120032f01f007212320032802dc072121202f211b202e210402400240024020032802e0072222450d002026202241186c6a211e202241186c41686a2101202f211b202e2104202621020340200241086a290300210620022903002105201d200241106a280200221c490d024200200420067d201b200554ad7d2206201b20057d2205201b56200620045620062004511b221c1b210442002005201c1b211b200141686a2101200241186a2202201e470d000b0b410821204100210202402021450d00202141186c450d00202610290b4100211c0c010b411810272220450d18202020053703002020201c3602102020200637030820034281808080103702c40a200320203602c00a0240024020010d004101211c0c010b200241186a2110202241186c20266a41686a21114101211c03402010210202400340200241086a290300210620022903002105201d200241106a2802002201490d014200200420067d201b200554ad7d2206201b20057d2205201b56200620045620062004511b22011b21044200200520011b211b200241186a2202201e470d000c030b0b0240201c20032802c40a470d00200341c00a6a201c4101108f0120032802c00a21200b200241186a21102020201c41186c6a2222200136021020222006370308202220053703002003201c41016a221c3602c80a20112002470d000b0b02402021450d00202141186c450d00202610290b20032802c40a21020b201f20032903f808370200200341d0076a2030370300201f41086a200341f8086a41086a280200360200200320313703c8072003201b3703b8072003201c3602e007200320023602dc07200320203602d80720032032370388082003200f3a0087082003200e3a0086082003200d3b0184082003200c3a0083082003200a3a008208200320243b018008200320093a00ff07200320083a00fe07200320073b01fc072003202d3a00fb072003202c3a00fa07200320253b01f8072003202b3a00f7072003202a3a00f607200320293b01f407200320283a00f307200320273a00f207200320233b01f007200320043703c0070b02400240201c0d002031203084500d010b200342f3e885db96cddbb3203703900720034190076a200341f0076a20032903b807200341c0076a290300411f10aa02200341c00a6a200341f0096a10db0120032802c00a2102200320032802c80a3602fc08200320023602f808200341b8076a200341f8086a10e401024020032802c40a450d00200210290b420121040c4d0b200341c00a6a200341900a6a200b10ab02024020032d00c00a22014104470d00200342f3e885db96cddbb3203703a809200341a8096a200341900a6a10ac02420021040c4d0b20032d00c30a411074210220032f00c10a211e200341c80a6a280200211c20032802c40a211d024020032802dc07221f450d00201f41186c450d0020032802d80710290b201e200272210220032802e80741ffffffff0371450d0120032802e40710290c010b410221010b200020023b00192000201d36021c200042003703082000411b6a20024110763a0000200041206a201c360200200041186a20013a0000200042013703000c4c0b2002411a6a2901002106200241196a2d00002121200241186a2d00002122200241166a2f01002123200241156a2d00002124200241146a2d00002125200241126a2f01002126200241116a2d00002127200241106a2d00002128410e211c2002410e6a2f010021292002410d6a2d0000212a2002410c6a2d0000212b2002410a6a2f0100212c200241096a2d0000212d200241086a2d00002107200241066a2f01002108200241056a2d00002109200241046a2d0000210a200241026a2f0100210b200141046a280200211f20022d0001212020022d0000211e41eebec500ad4280808080f000841001220228000021012002290004211b200228000c211d2002102941eab8c000ad42808080809002841001220229000021042002290008210520021029200320053701900920032004370188092003201d360184092003201b3701fc08200320013601f808200341d0006a200341f8086a10b10141032102024002402003280250417d71450d0041ecb0c0002101418092f000211d0c010b0240201e41ff01710d00202041ff01714101470d00200320063703a80a200320213a00a70a200320223a00a60a200320233b01a40a200320243a00a30a200320253a00a20a200320263b01a00a200320273a009f0a200320283a009e0a200320293b019c0a2003202a3a009b0a2003202b3a009a0a2003202c3b01980a2003202d3a00970a200320073a00960a200320083b01940a200320093a00930a2003200a3a00920a2003200b3b01900a200341f0096a200341900a6a10db01200341c00a6a20032802f009221e20032802f80910e201200341f8086a41086a2220200341fc0a6a290200370300200341f8086a41106a2221200341840b6a290200370300200341f8086a41186a22222003418c0b6a290200370300200341f8086a41206a2223200341940b6a2802003602002003200341f40a6a2902003703f808024020032802e00a2201450d00200341c00a6a41186a290300211b200341c00a6a41086a2903002104200341f00a6a280200211c200341ec0a6a280200211d200341e80a6a280200212420032903d00a210520032903c00a210620032802e40a210220034190076a41206a202328020036020020034190076a41186a202229030037030020034190076a41106a202129030037030020034190076a41086a2020290300370300200320032903f80837039007024020032802f409450d00201e10290b200341c8096a41086a221e20034190076a41086a290300370300200341c8096a41106a222020034190076a41106a290300370300200341c8096a41186a222120034190076a41186a290300370300200341c8096a41206a222220034190076a41206a280200360200200341b8076a41186a201b370300200341e8076a201c360200200341e0076a2024360200200341dc076a200236020020032003290390073703c809200320053703c807200320063703b8072003201d3602e407200320013602d807200320043703c0072003418c086a202228020036020020034184086a2021290300370200200341fc076a2020290300370200200341f4076a201e290300370200200341ec076a20032903c809370200200341c00a6a200341f0076a221e10d90120033502c80a42208620032802c00a2220ad841004024020032802c40a450d00202010290b200341c00a6a201e10de0120033502c80a211b20032802c00a211e200341003a00fd080240024002400240201f41c000490d00201f41808001490d01201f418080808004490d02200341053a00fd08200341033a00f8082003201f3600f9084280808080d00021040c030b200341013a00fd082003201f4102743a00f80842808080801021040c020b200341023a00fd082003201f4102744101723b01f80842808080802021040c010b200341043a00fd082003201f4102744102723602f8084280808080c00021040b201b422086201ead842004200341f8086aad841003024020032d00fd08450d00200341003a00fd080b024020032802c40a450d00201e10290b02402002450d00200241186c450d00200110290b0240201c41ffffffff0371450d00201d10290b20004200370308200042003703000c4e0b024020032802f409450d00201e10290b41dfb4c0002101410d211c418012211d0c010b41022102418012211d0b20004200370308200041206a201c3602002000411c6a2001360200200041186a201d200272360200200042013703000c4b0b2001410c6a2802002122200141086a280200211e200141046a280200211d2002411a6a2901002106200241196a2d00002123200241186a2d00002124200241166a2f01002125200241156a2d00002126200241146a2d00002127200241126a2f01002128200241116a2d00002129200241106a2d0000212a410e21012002410e6a2f0100212b2002410d6a2d0000212c2002410c6a2d0000212d2002410a6a2f01002107200241096a2d00002108200241086a2d00002109200241066a2f0100210a200241056a2d0000210b200241046a2d0000210c200241026a2f0100210d20022d0001212120022d0000212041eebec500ad4280808080f0008410012202280000211c2002290004211b200228000c211f2002102941eab8c000ad42808080809002841001220229000021042002290008210520021029200320053701900920032004370188092003201f360184092003201b3701fc082003201c3601f808200341e0006a200341f8086a10b10141032102024002402003280260417d71450d0041ecb0c000211c411c211f0c010b0240202041ff01710d00202141ff01714101470d00200320063703880a200320233a00870a200320243a00860a200320253b01840a200320263a00830a200320273a00820a200320283b01800a200320293a00ff092003202a3a00fe092003202b3b01fc092003202c3a00fb092003202d3a00fa09200320073b01f809200320083a00f709200320093a00f6092003200a3b01f4092003200b3a00f3092003200c3a00f2092003200d3b01f009200341900a6a200341f0096a10db01200341c00a6a20032802900a220120032802980a10e201200341f8086a41086a221c200341fc0a6a290200370300200341f8086a41106a221f200341840b6a290200370300200341f8086a41186a22202003418c0b6a290200370300200341f8086a41206a2221200341940b6a2802003602002003200341f40a6a2902003703f8080240024020032802e00a2228450d00200341c00a6a41186a290300211b200341c00a6a41086a2903002104200341f00a6a2802002129200341ec0a6a280200212a200341e80a6a280200212320032903d00a210520032903c00a210620032802e40a212720034190076a41206a202128020036020020034190076a41186a202029030037030020034190076a41106a201f29030037030020034190076a41086a201c290300370300200320032903f80837039007024020032802940a450d00200110290b200341c8096a41086a220120034190076a41086a290300370300200341c8096a41106a221c20034190076a41106a290300370300200341c8096a41186a221f20034190076a41186a290300370300200341c8096a41206a222020034190076a41206a280200360200200341b8076a41186a201b370300200341e8076a2029360200200341e0076a2023360200200341dc076a202736020020032003290390073703c809200320053703c807200320063703b8072003202a3602e407200320283602d807200320043703c0072003418c086a202028020036020020034184086a201f290300370200200341fc076a201c290300370200200341f4076a2001290300370200200341ec076a20032903c80937020020220d0102402027450d00202741186c450d00202810290b0240202941ffffffff0371450d00202a10290b41b1b4c000211c410c21014104211f0c030b024020032802940a450d00200110290b41dfb4c000211c410d21014100211f0c020b024020224105742202450d00200341c00a6a41186a2201201d41186a290000370300200341c00a6a41106a221c201d41106a290000370300200341c00a6a41086a221f201d41086a2900003703002003201d2900003703c00a412010272225450d15202520032903c00a370000202541186a2001290300370000202541106a201c290300370000202541086a201f29030037000020034281808080103702fc08200320253602f8080240201d20026a201d41206a2202470d00410121020c460b200341900a6a41186a221f200241186a290000370300200341900a6a41106a2220200241106a290000370300200341900a6a41086a2221200241086a290000370300200320022900003703900a202241057421264102210241c00021014101211c0340200341c00a6a41186a2222201f290300370300200341c00a6a41106a22232020290300370300200341c00a6a41086a22242021290300370300200320032903900a3703c00a02402002417f6a201c470d00200341f8086a201c4101109e0120032802f80821250b202520016a41606a221c20032903c00a370000201c41186a2022290300370000201c41106a2023290300370000201c41086a2024290300370000200320023602800920262001460d4620024110460d46201f201d20016a221c41186a2900003703002020201c41106a2900003703002021201c41086a2900003703002003201c2900003703900a200141206a2101200241016a210220032802fc08211c0c000b0b41002102201e41ffffff3f710d1e0c430b410221020b201e41ffffff3f71450d46201d10290c460b2002411a6a2901002106200241196a2d00002120200241186a2d00002121200241166a2f01002122200241156a2d00002123200241146a2d00002124200241126a2f01002125200241116a2d00002126200241106a2d00002127410e21012002410e6a2f010021282002410d6a2d000021292002410c6a2d0000212a2002410a6a2f0100212b200241096a2d0000212c200241086a2d0000212d200241066a2f01002107200241056a2d00002108200241046a2d00002109200241026a2f0100210a20022d0001211f20022d0000211e41eebec500ad4280808080f0008410012202280000211c2002290004211b200228000c211d2002102941eab8c000ad42808080809002841001220229000021042002290008210520021029200320053701900920032004370188092003201d360184092003201b3701fc082003201c3601f808200341e8006a200341f8086a10b10141032102024002402003280268417d71450d0041ecb0c000211c418092f000211d0c010b0240201e41ff01710d00201f41ff01714101470d00200320063703a80a200320203a00a70a200320213a00a60a200320223b01a40a200320233a00a30a200320243a00a20a200320253b01a00a200320263a009f0a200320273a009e0a200320283b019c0a200320293a009b0a2003202a3a009a0a2003202b3b01980a2003202c3a00970a2003202d3a00960a200320073b01940a200320083a00930a200320093a00920a2003200a3b01900a200341f0096a200341900a6a10db01200341c00a6a20032802f009221e20032802f80910e201200341f8086a41086a221f200341fc0a6a290200370300200341f8086a41106a2220200341840b6a290200370300200341f8086a41186a22212003418c0b6a290200370300200341f8086a41206a2222200341940b6a2802003602002003200341f40a6a2902003703f808024020032802e00a2201450d00200341c00a6a41186a290300211b200341c00a6a41086a2903002104200341f00a6a280200211c200341ec0a6a280200211d200341e80a6a280200212320032903d00a210520032903c00a210620032802e40a210220034190076a41206a202228020036020020034190076a41186a202129030037030020034190076a41106a202029030037030020034190076a41086a201f290300370300200320032903f80837039007024020032802f409450d00201e10290b200341c8096a41086a221e20034190076a41086a290300370300200341c8096a41106a221f20034190076a41106a290300370300200341c8096a41186a222020034190076a41186a290300370300200341c8096a41206a222120034190076a41206a280200360200200341b8076a41186a201b370300200341e8076a201c360200200341e0076a2023360200200341dc076a200236020020032003290390073703c809200320053703c807200320063703b8072003201d3602e407200320013602d807200320043703c0072003418c086a202128020036020020034184086a2020290300370200200341fc076a201f290300370200200341f4076a201e290300370200200341ec076a20032903c809370200200341c00a6a200341f0076a221e10de0120033502c80a42208620032802c00a221fad841004024020032802c40a450d00201f10290b200341c00a6a201e10d90120033502c80a42208620032802c00a221ead841004024020032802c40a450d00201e10290b02402002450d00200241186c450d00200110290b0240201c41ffffffff0371450d00201d10290b20004200370308200042003703000c4c0b024020032802f409450d00201e10290b41dfb4c000211c410d2101418012211d0c010b41022102418012211d0b20004200370308200041206a20013602002000411c6a201c360200200041186a201d200272360200200042013703000c490b0240024020022d00000d0020022d00014101470d0020012d0001212d200241196a2d0000211c200241186a2d0000211d200241166a2f0100211e200241156a2d0000211f200241146a2d00002120200241126a2f01002121200241116a2d00002122200241106a2d000021232002410e6a2f010021242002410d6a2d000021252002410c6a2d000021262002410a6a2f01002127200241096a2d00002128200241086a2d00002129200241066a2f0100212a200241056a2d0000212b200241046a2d0000212c200241026a2f0100210120032002411a6a2901003703a80a2003201c3a00a70a2003201d3a00a60a2003201e3b01a40a2003201f3a00a30a200320203a00a20a200320213b01a00a200320223a009f0a200320233a009e0a200320243b019c0a200320253a009b0a200320263a009a0a200320273b01980a200320283a00970a200320293a00960a2003202a3b01940a2003202b3a00930a2003202c3a00920a200320013a00900a200320014108763a00910a200341f0096a200341900a6a10db01200341c00a6a20032802f009220120032802f80910e201200341f8086a41086a221f200341fc0a6a290200370300200341f8086a41106a2220200341840b6a290200370300200341f8086a41186a22212003418c0b6a290200370300200341f8086a41206a2222200341940b6a2802003602002003200341f40a6a2902003703f808024020032802e00a221c450d00200341c00a6a41186a290300211b200341c00a6a41086a2903002104200341f00a6a280200211d200341ec0a6a280200211e200341e80a6a280200212320032903d00a210520032903c00a210620032802e40a210220034190076a41206a202228020036020020034190076a41186a202129030037030020034190076a41106a202029030037030020034190076a41086a201f290300370300200320032903f80837039007024020032802f409450d00200110290b200341c8096a41086a220120034190076a41086a290300370300200341c8096a41106a221f20034190076a41106a290300370300200341c8096a41186a222020034190076a41186a290300370300200341c8096a41206a222120034190076a41206a280200360200200341b8076a41186a201b370300200341e8076a201d360200200341e0076a2023360200200341dc076a200236020020032003290390073703c809200320053703c807200320063703b8072003201e3602e4072003201c3602d807200320043703c0072003418c086a202128020036020020034184086a2020290300370200200341fc076a201f290300370200200341f4076a2001290300370200200341ec076a20032903c809370200200341c00a6a200341f0076a10a60220033502c80a211b20032802c00a211f02400240202d41037122014103470d004101210142002104410121200c010b024002400240024020010e03000102000b410021200c020b410121200c010b410221200b200320203a009007410110272201450d49200120203a00004100212042808080801021040b201b422086201fad8420042001ad841003024020200d00200110290b024020032802c40a450d00201f10290b02402002450d00200241186c450d00201c10290b0240201d41ffffffff0371450d00201e10290b20004200370308200042003703000c4b0b024020032802f409450d00200110290b41831221020c010b41821221020b20004200370308200041206a410d3602002000411c6a41dfb4c000360200200041186a2002360200200042013703000c480b200141196a2900002104200141186a2d00002107200141176a2d00002108200141156a2f00002109200141146a2d0000210a200141136a2d0000210b200141116a2f0000210c200141106a2d0000210d2001410f6a2d0000210e2001410d6a2f0000210f2001410c6a2d000021102001410b6a2d00002111200141096a2f00002112200141086a2d00002113200141076a2d00002114200141056a2f00002115200141046a2d00002116200141036a2d00002117200141026a2d0000211820012d0001211a2002411a6a290100211b200241196a2d0000211c200241186a2d0000211d200241166a2f0100211e200241156a2d0000211f200241146a2d00002120200241126a2f01002121200241116a2d00002122200241106a2d000021232002410e6a2f010021242002410d6a2d000021252002410c6a2d000021262002410a6a2f01002127200241096a2d00002128200241086a2d00002129200241066a2f0100212a200241056a2d0000212b200241046a2d0000212c200241026a2f0100212d41012101024020022d00000d0020022d000141014721010b2003201b370190092003201c3a008f092003201d3a008e092003201e3b018c092003201f3a008b09200320203a008a09200320213b018809200320223a008709200320233a008609200320243b018409200320253a008309200320263a008209200320273b018009200320283a00ff08200320293a00fe082003202a3b01fc082003202b3a00fb082003202c3a00fa082003202d3b01f8080240024020010d00200341f0096a41186a200341f8086a41186a290100370300200341f0096a41106a200341f8086a41106a290100370300200341f0096a41086a200341f8086a41086a290100370300200320032901f8083703f009200341b8076a200341f0096a10d801200341c00a6a20032802b807220120032802c00710cd0120032802bc0721020240024020032d00c00a4101470d00200341d90a6a290000211b200341c00a6a41186a2d0000211c200341d70a6a2d0000211d200341d50a6a2f0000211e200341d40a6a2d0000211f200341d30a6a2d00002120200341d10a6a2f00002121200341c00a6a41106a2d00002122200341cf0a6a2d00002123200341cd0a6a2f00002124200341cc0a6a2d00002125200341cb0a6a2d00002126200341c90a6a2f00002127200341c00a6a41086a2d0000212820032d00c70a212920032f00c50a212a20032d00c40a212b20032d00c30a212c20032d00c20a212d20032d00c10a211902402002450d00200110290b2003201b3703e0092003201c3a00df092003201d3a00de092003201e3b01dc092003201f3a00db09200320203a00da09200320213b01d809200320223a00d709200320233a00d609200320243b01d409200320253a00d309200320263a00d209200320273b01d009200320283a00cf09200320293a00ce092003202a3b01cc092003202b3a00cb092003202c3a00ca092003202d3a00c909200320193a00c809200320043703a807200320073a00a707200320083a00a607200320093b01a4072003200a3a00a3072003200b3a00a2072003200c3b01a0072003200d3a009f072003200e3a009e072003200f3b019c07200320103a009b07200320113a009a07200320123b019807200320133a009707200320143a009607200320153b019407200320163a009307200320173a009207200320183a0091072003201a3a009007200341c00a6a20034190076a10db01200341f0006a20032802c00a220120032802c80a4180a6cc004100410010c70120032802702102024020032802c40a450d00200110290b20024101470d0141bdb4c0002102410d21014180800c211c4103211d0c030b02402002450d00200110290b41d7b4c00021024108210141808004211c4103211d0c020b20034190076a200341c8096a412010e707450d3f200341c00a6a200341f0096a10d80120033502c80a211b20032802c00a2101412010272202450d112002200329039007370000200241186a20034190076a41186a290300370000200241106a20034190076a41106a290300370000200241086a20034190076a41086a290300370000201b4220862001ad842002ad4280808080800484100320021029024020032802c40a450d00200110290b200341a8096a200341c8096a10db01200341c00a6a20032802a809220120032802b009221c10e201024020032802e00a2202450d00201cad4220862001ad8410040b200341b8076a41086a221c200341fc0a6a290200370300200341b8076a41106a221d200341840b6a290200370300200341b8076a41186a221e2003418c0b6a290200370300200341b8076a41206a221f200341940b6a2802003602002003200341f40a6a2902003703b807200341c00a6a41186a290300211b200341c00a6a41086a2903002104200341f00a6a2802002120200341ec0a6a2802002121200341e80a6a280200212220032903d00a210520032903c00a210620032802e40a2123200341f8086a41206a2224201f280200360200200341f8086a41186a221f201e290300370300200341f8086a41106a221e201d290300370300200341f8086a41086a221d201c290300370300200320032903b8073703f80802402002450d00200341900a6a41206a2024280200360200200341900a6a41186a201f290300370300200341900a6a41106a201e290300370300200341900a6a41086a201d290300370300200320032903f8083703900a024020032802ac09450d00200110290b200341c00a6a41186a201b370300200341f00a6a2020360200200341e80a6a2022360200200341e40a6a2023360200200341f40a6a20032903900a370200200341fc0a6a200341900a6a41086a290300370200200341840b6a200341900a6a41106a2903003702002003418c0b6a200341900a6a41186a290300370200200341940b6a200341900a6a41206a280200360200200320053703d00a200320043703c80a200320063703c00a200320213602ec0a200320023602e00a200341f8086a20034190076a10db01200335028009211b20032802f808211f200341003602c007200342013703b807412010272202450d47200220032903f80a370000200241086a200341800b6a290300370000200241106a200341880b6a290300370000200241186a200341900b6a290300370000200320023602b807200342a080808080043702bc072003200341c00a6a3602a809200341a8096a200341b8076a10e5012003200341c00a6a41106a3602a809200341a8096a200341b8076a10e50120032802e00a210220032802e80a2201200341b8076a107102402001450d002002200141186c6a21010340200320023602a809200341a8096a200341b8076a10e501200241106a200341b8076a10e6012001200241186a2202470d000b0b20032802ec0a212020032802f40a2202200341b8076a10710240024020032802bc07221e20032802c00722016b2002410274221c490d0020032802b8072102201e211d0c010b2001201c6a22022001490d45201e410174221d2002201d20024b1b221d4100480d4502400240201e0d000240201d0d00410121020c020b201d10272202450d4a0c010b20032802b8072102201e201d460d002002201e201d102b2202450d490b2003201d3602bc07200320023602b8070b200220016a2020201c10e4071a201b422086201fad842001201c6aad4220862002ad8410030240201d450d00200210290b024020032802fc08450d00201f10290b024020032802e40a2202450d00200241186c450d0020032802e00a10290b20032802f00a41ffffffff0371450d4020032802ec0a10290c400b20032802ac09450d3f200110290c3f0b4102211d4100211c0b20004200370308200041206a20013602002000411c6a2002360200200041186a201c4180800c71201d7241801272360200200042013703000c470b0240024020022d000120022d000041004772450d00200041186a41023602004201211b0c010b200141046a280200210141eebec500ad4280808080f0008410012202280000211c2002290004211b200228000c211d20021029419cf3c100ad4280808080e001841001220229000021042002290008210520021029200320053701900920032004370188092003201d360184092003201b3701fc082003201c3601f808200320013602c00a200341f8086aad4280808080800484200341c00a6aad4280808080c0008410034200211b0b2000201b370300200042003703080c460b024020022d000120022d0000410047720d0041eebec500ad4280808080f000841001220228000021012002290004211b200228000c211c200210294180fac100ad42808080808001841001220229000021042002290008210520021029200320053701900920032004370188092003201c360184092003201b3701fc08200320013601f808200341023a009007410110272202450d43200220032d0090073a0000200341f8086aad42808080808004842002ad4280808080108410032002102920004200370308200042003703000c460b20004200370308200041186a4102360200200042013703000c450b024020022d000120022d0000410047720d0041eebec500ad4280808080f000841001220228000021012002290004211b200228000c211c200210294180fac100ad42808080808001841001220229000021042002290008210520021029200320053701900920032004370188092003201c360184092003201b3701fc08200320013601f808200341013a009007410110272202450d42200220032d0090073a0000200341f8086aad42808080808004842002ad4280808080108410032002102920004200370308200042003703000c450b20004200370308200041186a4102360200200042013703000c440b200141086a280200211c200141046a280200211d024020022d000120022d0000410047720d002001410c6a280200210141eebec500ad4280808080f0008410012202280000211e2002290004211b200228000c211f2002102941f4f3c100ad4280808080d001841001220229000021042002290008210520021029200320053701900920032004370188092003201f360184092003201b3701fc082003201e3601f808200341203602c40a2003200341f8086a3602c00a201d2001200341c00a6a10b9010240201c41ffffff3f71450d00201d10290b20004200370308200042003703000c440b0240201c41ffffff3f71450d00201d10290b20004200370308200041186a4102360200200042013703000c430b200141246a280200211c200341d80a6a200141196a290000370300200341c00a6a41106a200141116a290000370300200341c00a6a41086a200141096a290000370300200320012900013703c00a02400240024020022d000120022d0000410047720d00200341b8076a200341c00a6a201c10ab0220032d00b80722024104460d0220032f00b90720032d00bb07411074722101200341b8076a41086a35020042208620033502bc0784211b0c010b410221020b200042003703082000411c6a201b370200200041186a2001410874200272360200200042013703000c430b200342f3e885db96cddbb3203703900a200341900a6a200341c00a6a10ac0220004200370308200042003703000c420b024020022d000120022d0000410047720d0041eebec500ad4280808080f000841001220228000021012002290004211b200228000c211c200210294180fac100ad42808080808001841001220229000021042002290008210520021029200320053701900920032004370188092003201c360184092003201b3701fc08200320013601f808200341033a009007410110272202450d3f200220032d0090073a0000200341f8086aad42808080808004842002ad4280808080108410032002102920004200370308200042003703000c420b20004200370308200041186a4102360200200042013703000c410b200241036a2d0000211c20022f0001211d200141106a280200211e2001410c6a2802002127200141086a2802002126200141046a28020021280240024020022d0000221f417f6a220141034b0d00024020010e0400010102000b200241046a2d00000d00200241086a2802004102742002410c6a28020041036c4f0d010b201d201c41107472201f4100477241ff0171450d004102212041801221020c360b410321200240201e0d0041b1b4c000211c410c21014180921021020c360b201e41016a210120262102024003402001417f6a22014102490d01200241046a211c2002280200211d200241046a2102201d201c280200490d000b419eb3c000211c411221014180923421020c360b200341c00a6a202810fd01200341b8076a20032802c00a220120032802c80a10fe0120032902bc07420020032802b80722021b211b024020032802c40a450d00200110290b2002410820021b21250240201e410274221f20266a417c6a280200201b422088a722024f0d0041002101417f211c2026211d03402001201d28020022206a2202201b422088a722214f0d0b2025200241d8006c6a220228022c212320022802202124200241306a2802002122200241246a280200211e2002200241d8006a201c20216a20206b41d8006c10e5071a0240201e450d00201e41306c450d00202410290b0240202241ffffff3f71450d00202310290b201d41046a211d201b4280808080707c211b201c41016a211c2001417f6a2101201f417c6a221f0d000b0240202741ffffffff0371450d00202610290b200341b8076a202810fd0120032802b807210220033502c0072104200341c00a6a2025201b422088a7220110ed0120044220862002ad8420033502c80a42208620032802c00a221cad841003024020032802c40a450d00201c10290b024020032802bc07450d00200210290b02402001450d00202541306a2102201b422088a741d8006c210103400240200241746a280200221c450d00201c41306c450d00200241706a28020010290b0240200228020041ffffff3f71450d002002417c6a28020010290b200241d8006a2102200141a87f6a22010d000b0b0240201ba72202450d00200241d8006c450d00202510290b20004200370308200042003703000c410b02402002450d00200241d8006c2101202541306a210203400240200241746a280200221c450d00201c41306c450d00200241706a28020010290b0240200228020041ffffff3f71450d002002417c6a28020010290b200241d8006a2102200141a87f6a22010d000b0b4192b4c000211c41112101418092182102201ba7221d450d35201d41d8006c450d35202510290c350b2001410c6a280200211c200141086a280200211f4102211d024020022d00000d0020022d00014101470d00200141106a2802002120200141046a280200211d2002411a6a290100211b200241196a2d0000211e200241186a2d00002121200241166a2f01002122200241156a2d00002123200241146a2d00002124200241126a2f01002125200241116a2d00002126200241106a2d000021272002410e6a2f010021282002410d6a2d000021292002410c6a2d0000212a2002410a6a2f0100212b200241086a2d0000212c200241066a2f0100212d200241056a2d00002107200241046a2d00002108200241026a2f010021012003200241096a2d00003a00af092003202c3a00ae092003202d3b01ac09200320073a00ab09200320083a00aa09200320013a00a809200320014108763a00a909200320263a00b709200320273a00b609200320283b01b409200320293a00b3092003202a3a00b2092003202b3b01b0092003201e3a00bf09200320213a00be09200320223b01bc09200320233a00bb09200320243a00ba09200320253b01b8092003201b3701c009200341e0096a201b370300200341c8096a41106a20032901b809370300200341c8096a41086a20032901b009370300200320032901a8093703c8090240202041104d0d0041b0b3c0002102411a211e410c21010c330b41eebec500ad4280808080f000841001220228000021012002290004211b200228000c211e20021029419c81c200ad4280808080a001841001220229000021042002290008210520021029200320053701900920032004370188092003201e360184092003201b3701fc08200320013601f808200341a8026a200341f8086a412010fc0141cab3c00021024112211e410b210120032802a802450d32201d20032802ac024f0d3241eebec500ad4280808080f000841001222128000021222021290004211b202128000c21232021102941c4f5c100ad4280808080a0018410012221290000210420212900082105202110292003200537019009200320043701880920032023360184092003201b3701fc08200320223601f808200341a0026a200341f8086a412010fc0120032802a002450d32201d20032802a40222224b0d3241eebec500ad4280808080f000841001222128000021232021290004211b202128000c21242021102941c8f2c100ad4280808080c0018410012221290000210420212900082105202110292003200537019009200320043701880920032024360184092003201b3701fc08200320233601f80820034198026a200341f8086a412010fc01201d41002022200328029c0241d4002003280298021b6b2221202120224b1b2221490d32200341c00a6a201d10930220034180026a20032802c00a222320032802c80a10e30120034190026a290300210620032903880221052003280280022122024020032802c40a450d00202310290b2022450d32200341900a6a200341c8096a10db01200341c00a6a20032802900a220220032802980a10e201200341f8086a41086a2201200341fc0a6a290200370300200341f8086a41106a221e200341840b6a290200370300200341f8086a41186a22222003418c0b6a290200370300200341f8086a41206a2223200341940b6a2802003602002003200341f40a6a2902003703f8080240024020032802e00a2224450d00200341c00a6a41186a290300211b200341c00a6a41086a2903002104200341f00a6a2802002125200341ec0a6a2802002126200341e80a6a280200212720032903d00a212e20032903c00a212f20032802e40a212820034190076a41206a202328020036020020034190076a41186a202229030037030020034190076a41106a201e29030037030020034190076a41086a2001290300370300200320032903f80837039007024020032802940a450d00200210290b200341b8076a41186a201b370300200341e8076a2025360200200341e0076a2027360200200341dc076a2028360200200341ec076a200329039007370200200341f4076a20034198076a290300370200200341fc076a200341a0076a29030037020020034184086a20034190076a41186a2903003702002003418c086a200341b0076a2802003602002003202e3703c8072003202f3703b807200320263602e407200320243602d807200320043703c00741eebec500ad4280808080f000841001220228000021012002290004211b200228000c211e2002102941eab8c000ad42808080809002841001220229000021042002290008212e200210292003202e3701900920032004370188092003201e360184092003201b3701fc08200320013601f808200341f8016a200341f8086a10b10120032802f801417d71450d01200341c00a6a200341f0076a10a60220032802c00a220220032802c80a10ad0241ff0171211e024020032802c40a450d00200210290b201e41034b0d0141ecb0c0002102411c2101201e0e042e01012e2e0b024020032802940a450d00200210290b41dfb4c0002102410d211e410021010c330b20032802e4072102024020032802ec0722220d00410021014100211e0c2f0b410021014100211e03400240024002402021200228020022234b0d0020010d01410021010c020b200141016a21010c010b201e20016b222420224f0d0c200220014102746b2224280200212520242023360200200220253602000b200241046a21022022201e41016a221e470d000b024002402001450d0020032802ec072223202220016b2202490d01200320023602ec07200221230c010b20032802ec0721230b20032802e4072102410021010240202341014b0d004100211e20230e022f2c2f0b2023211e03402001201e410176222120016a2222201d200220224102746a280200491b2101201e20216b221e41014b0d000c2c0b0b201c450d29201c41246c450d29201f10290c320b4102211c024020022d00000d0020022d00014101470d00200141046a280200211c2002411a6a290100211b200241196a2d0000211d200241186a2d0000211e200241166a2f0100211f200241156a2d00002120200241146a2d00002121200241126a2f01002122200241116a2d00002123200241106a2d000021242002410e6a2f010021252002410d6a2d000021262002410c6a2d000021272002410a6a2f01002128200241086a2d00002129200241066a2f0100212a200241056a2d0000212b200241046a2d0000212c200241026a2f010021012003200241096a2d00003a00af09200320293a00ae092003202a3b01ac092003202b3a00ab092003202c3a00aa09200320013a00a809200320014108763a00a909200320233a00b709200320243a00b609200320253b01b409200320263a00b309200320273a00b209200320283b01b0092003201d3a00bf092003201e3a00be092003201f3b01bc09200320203a00bb09200320213a00ba09200320223b01b8092003201b3701c009200341e0096a201b370300200341d8096a20032901b809370300200341c8096a41086a20032901b009370300200320032901a8093703c80941eebec500ad4280808080f000841001220228000021012002290004211b200228000c211d20021029419c81c200ad4280808080a001841001220229000021042002290008210520021029200320053701900920032004370188092003201d360184092003201b3701fc08200320013601f808200341e0036a200341f8086a412010fc0141cab3c00021024112211d4180802c210120032802e003450d2020032802e403201c4d0d2041eebec500ad4280808080f000841001221e280000211f201e290004211b201e28000c2120201e102941c4f5c100ad4280808080a001841001221e2900002104201e2900082105201e10292003200537019009200320043701880920032020360184092003201b3701fc082003201f3601f808200341d8036a200341f8086a412010fc0120032802d803450d2020032802dc03221f201c490d2041eebec500ad4280808080f000841001221e2800002120201e290004211b201e28000c2121201e102941c8f2c100ad4280808080c001841001221e2900002104201e2900082105201e10292003200537019009200320043701880920032021360184092003201b3701fc08200320203601f808200341d0036a200341f8086a412010fc014100201f20032802d40341d40020032802d0031b6b221e201e201f4b1b221e201c4b0d20200341c00a6a201c109302200341b8036a20032802c00a222020032802c80a10e301200341c8036a290300210420032903c003211b20032802b803211f024020032802c40a450d00202010290b201f450d20200341900a6a200341c8096a10db01200341c00a6a20032802900a220220032802980a10e201200341f8086a41086a2201200341fc0a6a290200370300200341f8086a41106a221d200341840b6a290200370300200341f8086a41186a221f2003418c0b6a290200370300200341f8086a41206a2220200341940b6a2802003602002003200341f40a6a2902003703f8080240024020032802e00a2221450d00200341c00a6a41186a2903002105200341c00a6a41086a2903002106200341f00a6a2802002122200341ec0a6a2802002123200341e80a6a280200212420032903d00a212e20032903c00a212f20032802e40a212520034190076a41206a202028020036020020034190076a41186a201f29030037030020034190076a41106a201d29030037030020034190076a41086a2001290300370300200320032903f80837039007024020032802940a450d00200210290b200341b8076a41186a2005370300200341e8076a2022360200200341e0076a2024360200200341dc076a2025360200200341ec076a200329039007370200200341f4076a20034198076a290300370200200341fc076a200341a0076a29030037020020034184086a20034190076a41186a2903003702002003418c086a200341b0076a2802003602002003202e3703c8072003202f3703b807200320233602e407200320213602d807200320063703c00741eebec500ad4280808080f0008410012202280000210120022900042105200228000c211d2002102941eab8c000ad42808080809002841001220229000021062002290008212e200210292003202e3701900920032006370188092003201d36018409200320053701fc08200320013601f808200341b0036a200341f8086a10b10120032802b003417d71450d01200341c00a6a200341f0076a10a60220032802c00a220220032802c80a10ad0241ff0171211d024020032802c40a450d00200210290b201d41034b0d0141ecb0c0002102418080f0002101201d0e0421010121210b024020032802940a450d00200210290b41dfb4c0002102410d211d410021014103211c0c240b20032802e4072102024020032802ec07221f0d00410021014100211d0c230b410021014100211d0340024002400240201e200228020022204b0d0020010d01410021010c020b200141016a21010c010b201d20016b2221201f4f0d0c200220014102746b2221280200212220212020360200200220223602000b200241046a2102201f201d41016a221d470d000b024002402001450d0020032802ec072220201f20016b2202490d01200320023602ec07200221200c010b20032802ec0721200b20032802e4072102410021010240202041014b0d004100211d20200e02231f230b2020211d03402001201d410176221e20016a221f201c2002201f4102746a280200491b2101201d201e6b221d41014b0d000c1f0b0b410021010c220b200141246a280200211e20022d0001211f20022d0000211d20034188076a200141196a29000037030020034180076a200141116a290000370300200341f8066a200141096a290000370300200320012900013703f00641eebec500ad4280808080f000841001220228000021012002290004211b200228000c211c2002102941eab8c000ad42808080809002841001220229000021042002290008210520021029200320053701c009200320043701b8092003201c3601b4092003201b3701ac09200320013601a809200341d0066a200341a8096a10b10120032802d006417d710d09024002400240201d41ff01710d00201f41ff01714101470d00200341f0096a41186a200341f0066a41186a290300370300200341f0096a41106a200341f0066a41106a290300370300200341f0096a41086a200341f0066a41086a290300370300200320032903f0063703f00941eebec500ad4280808080f000841001220228000021012002290004211b200228000c211c2002102941c4f5c100ad4280808080a001841001220229000021042002290008210520021029200320053701c009200320043701b8092003201c3601b4092003201b3701ac09200320013601a809200341c8066a200341a8096a412010fc0141cab3c0002102411221014180802c211c20032802c806450d0220032802cc06221f201e490d0241eebec500ad4280808080f0008422061001221d2800002120201d290004211b201d28000c2121201d102941c8f2c100ad4280808080c001841001221d2900002104201d2900082105201d1029200320053701c009200320043701b809200320213601b4092003201b3701ac09200320203601a809200341c0066a200341a8096a412010fc01201e4100201f20032802c40641d40020032802c0061b6b221d201d201f4b1b221f490d0220061001221d2800002120201d290004211b201d28000c2121201d1029419c81c200ad4280808080a001841001221d2900002104201d2900082105201d1029200320053701c009200320043701b809200320213601b4092003201b3701ac09200320203601a809200341b8066a200341a8096a412010fc01024020032802b8064101470d0020032802bc06201e4b0d030b200341c00a6a201e109302200341a0066a20032802c00a222020032802c80a10e301200341b0066a290300210420032903a806211b20032802a006211d024020032802c40a450d00202010290b201d450d02200341b8076a200341f0096a10d801200341c00a6a20032802b807220120032802c00710cd01200341d90a6a2900002105200341d80a6a2d0000211c200341d70a6a2d0000211d200341d50a6a2f00002120200341d40a6a2d00002121200341d30a6a2d00002122200341d10a6a2f00002123200341d00a6a2d00002124200341cf0a6a2d00002125200341cd0a6a2f00002126200341cc0a6a2d00002127200341cb0a6a2d00002128200341c90a6a2f00002129200341c80a6a2d0000212a20032d00c70a212b20032f00c50a212c20032d00c40a212d20032d00c30a210720032d00c20a210820032d00c10a210920032d00c00a2102024020032802bc07450d00200110290b200241ff01714101470d01200320053703e0092003201c3a00df092003201d3a00de09200320203b01dc09200320213a00db09200320223a00da09200320233b01d809200320243a00d709200320253a00d609200320263b01d409200320273a00d309200320283a00d209200320293b01d0092003202a3a00cf092003202b3a00ce092003202c3b01cc092003202d3a00cb09200320073a00ca09200320083a00c909200320093a00c809200341900a6a200341c8096a10db01200341c00a6a20032802900a220120032802980a10e201200341f8086a41086a221c200341fc0a6a290200370300200341f8086a41106a221d200341840b6a290200370300200341f8086a41186a22202003418c0b6a290200370300200341f8086a41206a2221200341940b6a2802003602002003200341f40a6a2902003703f80802400240024020032802e00a2222450d00200341c00a6a41186a2903002105200341c00a6a41086a2903002106200341f00a6a2802002123200341ec0a6a2802002102200341e80a6a280200212420032903d00a212e20032903c00a212f20032802e40a212520034190076a41206a202128020036020020034190076a41186a202029030037030020034190076a41106a201d29030037030020034190076a41086a201c290300370300200320032903f80837039007024020032802940a450d00200110290b200341b8076a41186a2005370300200341e8076a2023360200200341e0076a2024360200200341dc076a2025360200200341ec076a2201200329039007370200200341f4076a20034198076a290300370200200341fc076a200341a0076a29030037020020034184086a20034190076a41186a2903003702002003418c086a200341b0076a2802003602002003202e3703c8072003202f3703b807200320023602e407200320223602d807200320063703c00702402001280200221d0d00410021014100211c0c030b410021014100211c0340024002400240201f200228020022204b0d0020010d01410021010c020b200141016a21010c010b201c20016b2221201d4f0d12200220014102746b2221280200212220212020360200200220223602000b200241046a2102201d201c41016a221c470d000b024002402001450d0020032802ec072220201d20016b2202490d01200320023602ec07200221200c010b20032802ec0721200b20032802e40721024100210102400240202041014b0d004100211c20200e020401040b2020211c03402001201c410176221d20016a221f201e2002201f4102746a280200491b2101201c201d6b221c41014b0d000b0b4103211d201e200220014102746a280200221c470d010c1e0b024020032802940a450d00200110290b41dfb4c0002102410d21014103211d4100211c0c1e0b20202001201e201c4b6a2201490d0f2020211c0b0240201c20032802e807470d00200341e4076a201c410110980120032802e40721020b200220014102746a220241046a2002201c20016b41027410e5071a2002201e3602002003201c41016a3602ec07200341900a6a201e200341f0076a2220109d02200341c00a6a20032802900a220220032802980a10a1020240024020032802e00a222a0d0042002105410021294108212a41002124420021064200212f420021300c010b200341c80a6a2903002130200341d80a6a2903002106200341e80a6a280200212420032903c00a212f20032903d00a210520032802e40a21290b024020032802940a450d00200210290b200341c00a6a200341c8096a10db0120032802c00a2102200320032802c80a3602940a200320023602900a200341b8076a200341900a6a10e401024020032802c40a450d00200210290b20034190076a201e10ae024104211d20034190076a410472212b024002402003280294072221450d00200328029007212520034190076a41086a28020021220340202141086a210120212f0106222341057421024100211c0240024003402002450d0120202001412010e707221f450d02200241606a2102201c41016a211c200141206a2101201f417f4a0d000b201c417f6a21230b2022450d022022417f6a2122202120234102746a4194036a28020021210c010b0b2021201c4102746a41e8026a2802002201450d0020254101202541014b1b2202418094ebdc036e221c2002201c418094ebdc036c476a221c4101201c41014b1b221c20024b0d1120034188066a201b2004428094ebdc03420010e007200341f8056a200329038806220420034188066a41086a290300222e4280ec94a37c427f10d507200341e8056a2004202e2002200120022001491b201c6ead428094ebdc037e2002201c6ead8042ffffffff0f832231420010d507200341c00a6a201e200341f0096a109f0220034198066a20032802c00a220120032802c80a109e02200341e8056a41086a29030020032903e80522042031201b20032903f8057c7e221b428094ebdc0380222ea7417f201b428080808080c0b2cd3b541b201b202e4280ec94a37c7e7c4280cab5ee01566aad7c221b200454ad7c212e200328029c0641002003280298061b2102024020032802c40a450d00200110290b200341c0056a201b202e428094ebdc03420010e007200341b0056a20032903c0052204200341c0056a41086a29030022314280ec94a37c427f10d507200341a0056a200420312002ad2232420010d50720034190056a201b20032903a00522312032201b20032903b0057c7e2204428094ebdc03802232a7417f2004428080808080c0b2cd3b541b200420324280ec94a37c7e7c4280cab5ee01566aad7c22047d2233202e200341a0056a41086a2903002004203154ad7c22347d201b200454ad7d428094ebdc03420010e00720034180056a200329039005223120034190056a41086a29030022324280ec94a37c427f10d507200341f0046a2031203220052006202f203010af02ad2205420010d507200341d0056a202020032903f004220620047c221b20332003290380057c223320057e2204428094ebdc03802205a7417f2004428080808080c0b2cd3b541b200420054280ec94a37c7e7c4280cab5ee01566aad7c2204200341f0046a41086a29030020347c201b200654ad7c2004201b54ad7c10b002200341d0056a41106a290300211b20032903d805210420032903d0052205a74101470d01200341f8076a290300210520034180086a290300210620034188086a290300212e20032903f0072134200341f80a6a201b370300200341f00a6a2004370300200341e10a6a202e370000200341d90a6a2006370000200341d10a6a2005370000200341c90a6a2034370000200341c00a6a41086a220141013a0000200341043a00c00a200341c00a6a10cb01200341c00a6a41186a221e4200370300200341c00a6a41106a221c420037030020014200370300200342003703c00a41dcbec500ad428080808080018422051001221d2900002106200341f8086a41086a2202201d41086a290000370300200320063703f808201d102920012002290300370300200320032903f8083703c00a419fe3c200ad4280808080d0018422061001221d290000212e2002201d41086a2900003703002003202e3703f808201d1029201c20032903f808222e370300200341900a6a41086a221f2001290300370300200341900a6a41106a2220202e370300200341900a6a41186a22212002290300370300200320032903c00a3703900a200341c0046a200341900a6a412010e301200341c0046a41106a290300212e20032903c804213420032802c004211d201e4200370300201c420037030020014200370300200342003703c00a20051001221e29000021052002201e41086a290000370300200320053703f808201e102920012002290300370300200320032903f8083703c00a20061001221e29000021052002201e41086a290000370300200320053703f808201e1029201c20032903f8082205370300201f20012903003703002020200537030020212002290300370300200320032903c00a3703900a2003427f202e4200201d1b2205201b7c20344200201d1b221b20047c2204201b542202ad7c221b2002201b200554201b2005511b22021b3703c80a2003427f200420021b3703c00a200341c00a6a2102200341900a6a21010c1b0b202b10d4012029450d1c202941306c450d1c202a10290c1c0b20054201520d1a200341c00a6a41186a221e4200370300200341c00a6a41106a221c4200370300200341c00a6a41086a22014200370300200342003703c00a41dcbec500ad428080808080018422051001221d2900002106200341f8086a41086a2202201d41086a290000370300200320063703f808201d102920012002290300370300200320032903f8083703c00a419fe3c200ad4280808080d0018422061001221d290000212e2002201d41086a2900003703002003202e3703f808201d1029201c20032903f808222e370300200341900a6a41086a221f2001290300370300200341900a6a41106a2220202e370300200341900a6a41186a22212002290300370300200320032903c00a3703900a200341d8046a200341900a6a412010e301200341d8046a41106a290300212e20032903e004213420032802d804211d201e4200370300201c420037030020014200370300200342003703c00a20051001221e29000021052002201e41086a290000370300200320053703f808201e102920012002290300370300200320032903f8083703c00a20061001221e29000021052002201e41086a290000370300200320053703f808201e1029201c20032903f8082205370300201f20012903003703002020200537030020212002290300370300200320032903c00a3703900a2003427f202e4200201d1b2205201b7c20344200201d1b221b20047c2204201b542202ad7c221b2002201b200554201b2005511b22021b3703c80a2003427f200420021b3703c00a200341c00a6a2102200341900a6a21010c190b4102211d4100211c0c1d0b41d7b4c00021024108210141808004211c0b4103211d0c1b0b200141106a290300211b200141086a290300212e2002411a6a290100212f200241196a2d00002120200241186a2d00002121200241166a2f01002122200241156a2d00002123200241146a2d00002124200241126a2f01002125200241116a2d00002126200241106a2d00002127410e21012002410e6a2f010021282002410d6a2d000021292002410c6a2d0000212a2002410a6a2f0100212b200241096a2d0000212c200241086a2d0000212d200241066a2f01002107200241056a2d00002108200241046a2d00002109200241026a2f0100210a20022d0001211f20022d0000211e41eebec500ad4280808080f0008410012202280000211c20022900042104200228000c211d2002102941eab8c000ad42808080809002841001220229000021052002290008210620021029200320063701900920032005370188092003201d36018409200320043701fc082003201c3601f808200341d8066a200341f8086a10b10141ecb0c00021024103211c024020032802d806417d71450d00411c211d0c150b201e41ff01710d10201f41ff01714101470d102003202f3703880a200320203a00870a200320213a00860a200320223b01840a200320233a00830a200320243a00820a200320253b01800a200320263a00ff09200320273a00fe09200320283b01fc09200320293a00fb092003202a3a00fa092003202b3b01f8092003202c3a00f7092003202d3a00f609200320073b01f409200320083a00f309200320093a00f2092003200a3b01f009200341b8076a200341f0096a10db01200341c00a6a20032802b807220220032802c00710e201200341f8086a41086a221e200341fc0a6a290200370300200341f8086a41106a221f200341840b6a290200370300200341f8086a41186a22202003418c0b6a290200370300200341f8086a41206a2221200341940b6a2802003602002003200341f40a6a2902003703f80820032802e00a221d450d12200341c00a6a41186a290300212f200341c00a6a41086a2903002134200341f00a6a2802002123200341ec0a6a2802002124200341e80a6a280200210120032903d00a213020032903c00a213520032802e40a212220034190076a41206a202128020036020020034190076a41186a202029030037030020034190076a41106a201f29030037030020034190076a41086a201e290300370300200320032903f80837039007024020032802bc07450d00200210290b200341c8096a41106a20034190076a41106a2903002204370300200341900a6a41086a220220034190076a41086a290300370300200341900a6a41106a221e2004370300200341900a6a41186a221f20034190076a41186a290300370300200341900a6a41206a222020034190076a41206a28020036020020032003290390073703900a2001450d11200341b8076a41206a2020280200360200200341b8076a41186a201f290300370300200341b8076a41106a201e290300370300200341b8076a41086a2002290300370300200320032903900a3703b807200141186c201d6a41686a2102420021314200213202400340024020010d00410021010c020b02402002290300220420317c2205202e58200241086a290300223320327c2005200454ad7c2206201b582006201b51221c1b0d0020022004202e20317d22057d37030020022033201b20327d202e203154ad7d221b7d2004200554ad7d370308201b202f7c200520307c2230200554ad7c212f0c020b2001417f6a21012033202f7c200420307c2230200454ad7c212f200241686a210220052131200621322005202e542006201b54201c1b0d000b0b200341c00a6a41186a202f370300200341f00a6a2023360200200341e80a6a2001360200200341e40a6a2022360200200341f40a6a20032903b807370200200341fc0a6a200341c0076a290300370200200341840b6a200341c8076a2903003702002003418c0b6a200341b8076a41186a290300370200200341940b6a200341d8076a280200360200200320303703d00a200320353703c00a200320243602ec0a2003201d3602e00a200320343703c80a200342f3e885db96cddbb3203703900720034190076a200341f80a6a20352034411f10aa02200341b8076a200341f0096a10db0120032802b8072102200320032802c0073602fc08200320023602f808200341c00a6a200341f8086a10e401024020032802bc07450d00200210290b20033502e80a42d086037e211b024020032802e40a2202450d00200241186c450d0020032802e00a10290b201b4280f3e893017c211b024020032802f00a41ffffffff0371450d0020032802ec0a10290b200041106a201b37030020004201370308200042003703000c3c0b20022d000120022d0000410047720d0b200141046a280200211c41eebec500ad4280808080f0008422061001220228000021012002290004211b200228000c211d2002102941c4f5c100ad4280808080a001841001220229000021042002290008210520021029200320053701900920032004370188092003201d360184092003201b3701fc08200320013601f808200341e8066a200341f8086a412010fc01024020032802e8064101470d0020032802ec062101200610012202280000211d2002290004211b200228000c211e2002102941c8f2c100ad4280808080c0018422041001220229000021052002290008210620021029200320063701900920032005370188092003201e360184092003201b3701fc082003201d3601f808200341e0066a200341f8086a412010fc0102404100200120032802e40641d40020032802e0061b6b2202200220014b1b220241002001201c6b221d201d20014b1b22014f0d00034020021095022001200241016a2202470d000b0b41eebec500ad4280808080f000841001220228000021012002290004211b200228000c211d2002102920041001220229000021042002290008210520021029200320053701900920032004370188092003201d360184092003201b3701fc08200320013601f8082003201c3602c00a200341f8086aad4280808080800484200341c00a6aad4280808080c0008410030b20004200370308200042003703000c3b0b200141246a280200211c200341b8076a41186a200141196a290000370300200341b8076a41106a200141116a290000370300200341c0076a200141096a290000370300200320012900013703b807200341900a6a200341b8076a10a802200341c00a6a20032802900a220120032802980a10a902200341c00a6a41106a290300420020032903c00a42015122021b211b20032903c80a420020021b2104200341e00a6a290300420020021b2105200341c00a6a41186a290300420020021b2106024020032802940a450d00200110290b427f200420067c220620062004542202201b20057c2002ad7c2204201b542004201b511b22021b427f200420021b844200520d0b200341c00a6a200341b8076a201c10ab02024020032d00c00a22024104470d00200342f3e885db96cddbb3203703f808200341f8086a200341b8076a10ac0220004200370308200042003703000c3b0b200341c00a6a41086a280200210120032802c40a211c20032f00c10a20032d00c30a41107472410874221f4180fe0371211d201f418080fc0771211e201f418080807871211f0c0d0b200141d8016a2f0100211e200141d4016a280200211f200141d0016a28020021202001410c6a2802002121200141086a280200211c200141046a280200211d200341b8076a200141106a41c00110e4071a200341a0096a20014188026a29030037030020034198096a20014180026a290300370300200341f8086a41186a200141f8016a290300370300200341f8086a41106a200141f0016a290300370300200341f8086a41086a200141e8016a2903003703002003200141e0016a2903003703f8080240024002400240024020022d00000d0020022d00014101460d010b20034190076a41186a41023a00004200211b20034200370398072003420137039007200341b8076a1087020240201c41808080807872418080808078460d00201d10290b0c010b200320213602d0092003201c3602cc092003201d3602c809200341c00a6a200341b8076a41c00110e4071a200341900a6a41286a200341f8086a41286a290300370300200341900a6a41206a200341f8086a41206a290300370300200341900a6a41186a200341f8086a41186a290300370300200341900a6a41106a200341f8086a41106a290300370300200341900a6a41086a200341f8086a41086a290300370300200320032903f8083703900a20034190076a200341c8096a200341c00a6a4101200341900a6a2020201f201e10b102200329039807211b20034190076a41106a29030021042003290390074201520d010b200341c80a6a20034190076a41206a2903002205370300200320034190076a41186a29030022063703c00a200041206a2005370300200041186a2006370300420121050c010b420021050b2000201b37030820002005370300200041106a20043703000c390b200141d8016a2f0100211e200141d4016a280200211f200141d0016a28020021202001410c6a2802002121200141086a280200211c200141046a280200211d200341b8076a200141106a41c00110e4071a200341a0096a20014188026a29030037030020034198096a20014180026a290300370300200341f8086a41186a200141f8016a290300370300200341f8086a41106a200141f0016a290300370300200341f8086a41086a200141e8016a2903003703002003200141e0016a2903003703f8080240024002400240024020022d00000d0020022d000141ff01714102460d010b20034190076a41186a41023a00004200211b20034200370398072003420137039007200341b8076a1087020240201c41808080807872418080808078460d00201d10290b0c010b200320213602d0092003201c3602cc092003201d3602c809200341c00a6a200341b8076a41c00110e4071a200341900a6a41286a200341f8086a41286a290300370300200341900a6a41206a200341f8086a41206a290300370300200341900a6a41186a200341f8086a41186a290300370300200341900a6a41106a200341f8086a41106a290300370300200341900a6a41086a200341f8086a41086a290300370300200320032903f8083703900a20034190076a200341c8096a200341c00a6a4102200341900a6a2020201f201e10b102200329039807211b20034190076a41106a29030021042003290390074201520d010b200341c80a6a20034190076a41206a2903002205370300200320034190076a41186a29030022063703c00a200041206a2005370300200041186a2006370300420121050c010b420021050b2000201b37030820002005370300200041106a20043703000c380b1039000b200220211042000b202420224180bdc7001036000b2021201f4180bdc7001036000b41ecb0c0002102410e21014103211d418080f000211c0c110b2021201d4180bdc7001036000b200120201041000b41f0a6c700411941dcaac7001033000b20004200370308200041186a4102360200200042013703000c2f0b4100211f41808028211e41032102410c210141dcb3c000211c418012211d0c010b201d10290c240b20004200370308200041206a20013602002000411c6a201c360200200041186a201d200272201e72201f72360200200042013703000c2c0b4102211c0c030b02402022450d00202241186c450d00201d10290b41e8b3c00021024109211d202341ffffffff0371450d0120241029410d21010c020b024020032802bc07450d00200210290b41dfb4c00021024100211d0b410d21010b2000201d3a001a200041093a001920004200370308200041206a20013602002000411c6a2002360200200041186a201c3a0000200042013703000c270b2001ad42808080808004842002ad428080808080028410030b0240202441306c2202450d00202a20026a2123202a41286a2102200341900a6aad42808080808004842135200341c90a6a211f200341c00a6a41106a2101200341f80a6a2128034020034198046a20312032200241586a221c290300201c41086a290300202f203010af02ad221b420010d507200341a8046a200241686a221e2003290398042204201b20337e221b428094ebdc03802205a7417f201b428080808080c0b2cd3b541b201b20054280ec94a37c7e7c4280cab5ee01566aad7c221b20034198046a41086a290300201b200454ad7c10b002200341a8046a41106a290300211b20032903b004210402400240024020032903a8042205a74101470d00200241786a2900002105201e29000021062002290000212e2003200241706a290000223437018009200320063701f80820032005370188092003202e37019009201f2006370000201f41086a2034370000201f41106a2005370000201f41186a202e370000200320043703f00a2028201b370300200341013a00c80a200341043a00c00a200341c00a6a10cb01200341c00a6a41186a2220420037030020014200370300200341c00a6a41086a221d4200370300200342003703c00a41dcbec500ad42808080808001842205100122212900002106200341f8086a41086a221c202141086a290000370300200320063703f80820211029201d201c290300370300200320032903f8083703c00a419fe3c200ad4280808080d00184220610012221290000212e201c202141086a2900003703002003202e3703f80820211029200120032903f808370000200141086a2224201c290300370000200341900a6a41086a2225201d290300370300200341900a6a41106a22262001290300370300200341900a6a41186a22272020290300370300200320032903c00a3703900a200341e8036a200341900a6a412010e301200341e8036a41106a290300212e20032903f003213420032802e80321212020420037030020014200370300201d4200370300200342003703c00a2005100122222900002105201c202241086a290000370300200320053703f80820221029201d201c290300370300200320032903f8083703c00a2006100122222900002105201c202241086a290000370300200320053703f80820221029200120032903f8083700002024201c2903003700002025201d2903003703002026200129030037030020272020290300370300200320032903c00a3703900a2003427f202e420020211b2205201b7c2034420020211b221b20047c2204201b54221cad7c221b201c201b200554201b2005511b221c1b3703c80a2003427f2004201c1b3703c00a200341c00a6a211c0c010b20054201520d01200341c00a6a41186a2220420037030020014200370300200341c00a6a41086a221d4200370300200342003703c00a41dcbec500ad42808080808001842205100122212900002106200341f8086a41086a221c202141086a290000370300200320063703f80820211029201d201c290300370300200320032903f8083703c00a419fe3c200ad4280808080d00184220610012221290000212e201c202141086a2900003703002003202e3703f80820211029200120032903f808370000200141086a2224201c290300370000200341900a6a41086a2225201d290300370300200341900a6a41106a22262001290300370300200341900a6a41186a22272020290300370300200320032903c00a3703900a20034180046a200341900a6a412010e30120034180046a41106a290300212e200329038804213420032802800421212020420037030020014200370300201d4200370300200342003703c00a2005100122222900002105201c202241086a290000370300200320053703f80820221029201d201c290300370300200320032903f8083703c00a2006100122222900002105201c202241086a290000370300200320053703f80820221029200120032903f8083700002024201c2903003700002025201d2903003703002026200129030037030020272020290300370300200320032903c00a3703900a2003427f202e420020211b2205201b7c2034420020211b221b20047c2204201b54221cad7c221b201c201b200554201b2005511b221c1b3703c80a2003427f2004201c1b3703c00a200341c00a6a211c0b2035201cad428080808080028410030b200241306a2102201e41206a2023470d000b0b202b10d40102402029450d00202941306c450d00202a10290b024020032802dc072202450d00200241186c450d0020032802d80710290b20032802e80741ffffffff0371450d0220032802e40710290c020b024020032802dc072202450d00200241186c450d0020032802d80710290b4190b3c0002102410e210141808038211c20032802e80741ffffffff0371450d0020032802e40710290b201d4104470d010b20004200370308200042003703000c220b20004200370308200041206a20013602002000411c6a2002360200200041186a201c418080fc0071201d7241801272360200200042013703000c210b201c200220014102746a280200221d470d024190b3c00021024180803821010b024020032802dc07221c450d00201c41186c450d0020032802d80710290b024020032802e80741ffffffff0371450d0020032802e40710290b410e211d0b4103211c0c020b20202001201c201d4b6a2201490d022020211d0b0240201d20032802e807470d00200341e4076a201d410110980120032802e40721020b200220014102746a220241046a2002201d20016b41027410e5071a2002201c3602002003201d41016a3602ec07200341c00a6a200341c8096a10db0120032802c00a2102200320032802c80a3602940a200320023602900a200341b8076a200341900a6a10e401024020032802c40a450d00200210290b20034190076a201c10ae02200341c00a6a201c200341f0076a221e109f02200341a8036a20032802c00a220220032802c80a109e0220032802a803212320032802ac032124024020032802c40a450d00200210290b200341900a6a201c201e109d02200341c00a6a20032802900a220220032802980a10a1020240024020032802e00a22260d00420021054108212641002122420021064200212e4200212f0c010b200341c80a6a2903002106200341d80a6a290300212f20032903c00a210520032903d00a212e20032802e40a21220b024020032802940a450d00200210290b202e202f2005200610af02212502400240200328029407221f0d00410021010c010b20034190076a41086a28020021200340201f41086a2101201f2f0106222141057421024100211c0240024003402002450d01201e2001412010e707221d450d02200241606a2102201c41016a211c200141206a2101201d417f4a0d000b201c417f6a21210b024020200d00410021010c030b2020417f6a2120201f20214102746a4194036a280200211f0c010b0b201f201c4102746a41e8026a28020021010b20032802900722024101200241014b1b2202418094ebdc036e221c2002201c418094ebdc036c476a221c4101201c41014b1b221c20024b0d0220034180036a201b2004428094ebdc03420010e007200341f0026a200329038003220420034180036a41086a29030022054280ec94a37c427f10d5072003418094ebdc033602c40a20032025ad4100418094ebdc032024410020231b221d6b221f201f418094ebdc034b1bad7e428094ebdc0380a7221f3602c00a200341c00a6a201f418094ebdc034b4102746a280200211f2003418094ebdc033602c40a2003417f201d201f6a221f201f201d491b221d3602c00a200341c00a6a201d418094ebdc034b4102746a35020021062003418094ebdc033602c40a200320062002200120022001491b201c6ead428094ebdc037e2002201c6ead8042ffffffff0f837e428094ebdc0380a722023602c00a200341e0026a20042005200341c00a6a2002418094ebdc034b4102746a3502002206420010d50720034190036a201e20032903e00222042006201b20032903f0027c7e221b428094ebdc03802205a7417f201b428080808080c0b2cd3b541b201b20054280ec94a37c7e7c4280cab5ee01566aad7c221b200341e0026a41086a290300201b200454ad7c10b00220034190036a41106a290300211b200329039803210402402003290390032205a74101470d0020032903c809210520032903d009210620032903d809212e20032903e009212f200341f80a6a201b370300200341f00a6a2004370300200341e10a6a202f370000200341d90a6a202e370000200341d10a6a2006370000200341c90a6a2005370000200341c00a6a41086a220141013a0000200341043a00c00a200341c00a6a10cb01200341c00a6a41186a221e4200370300200341c00a6a41106a221c420037030020014200370300200342003703c00a41dcbec500ad428080808080018422051001221d2900002106200341f8086a41086a2202201d41086a290000370300200320063703f808201d102920012002290300370300200320032903f8083703c00a419fe3c200ad4280808080d0018422061001221d290000212e2002201d41086a2900003703002003202e3703f808201d1029201c20032903f808222e370300200341900a6a41086a221f2001290300370300200341900a6a41106a2220202e370300200341900a6a41186a22212002290300370300200320032903c00a3703900a200341b0026a200341900a6a412010e301200341b0026a41106a290300212e20032903b802212f20032802b002211d201e4200370300201c420037030020014200370300200342003703c00a20051001221e29000021052002201e41086a290000370300200320053703f808201e102920012002290300370300200320032903f8083703c00a20061001221e29000021052002201e41086a290000370300200320053703f808201e1029201c20032903f8082205370300201f20012903003703002020200537030020212002290300370300200320032903c00a3703900a2003427f202e4200201d1b2205201b7c202f4200201d1b221b20047c2204201b542202ad7c221b2002201b200554201b2005511b22021b3703c80a2003427f200420021b3703c00a200341c00a6a2102200341900a6a21010c040b20054201520d04200341c00a6a41186a221e4200370300200341c00a6a41106a221c4200370300200341c00a6a41086a22014200370300200342003703c00a41dcbec500ad428080808080018422051001221d2900002106200341f8086a41086a2202201d41086a290000370300200320063703f808201d102920012002290300370300200320032903f8083703c00a419fe3c200ad4280808080d0018422061001221d290000212e2002201d41086a2900003703002003202e3703f808201d1029201c20032903f808222e370300200341900a6a41086a221f2001290300370300200341900a6a41106a2220202e370300200341900a6a41186a22212002290300370300200320032903c00a3703900a200341c8026a200341900a6a412010e301200341c8026a41106a290300212e20032903d002212f20032802c802211d201e4200370300201c420037030020014200370300200342003703c00a20051001221e29000021052002201e41086a290000370300200320053703f808201e102920012002290300370300200320032903f8083703c00a20061001221e29000021052002201e41086a290000370300200320053703f808201e1029201c20032903f8082205370300201f20012903003703002020200537030020212002290300370300200320032903c00a3703900a2003427f202e4200201d1b2205201b7c202f4200201d1b221b20047c2204201b542202ad7c221b2002201b200554201b2005511b22021b3703c80a2003427f200420021b3703c00a200341c00a6a2102200341900a6a21010c030b200041206a201d3602002000411c6a2002360200200041186a2001418080fc0071201c72418012723602004201211b0c040b200120201041000b41f0a6c700411941dcaac7001033000b2001ad42808080808004842002ad428080808080028410030b20034190076a410472210202402022450d00202241306c450d00202610290b200210d401024020032802dc072202450d00200241186c450d0020032802d80710290b024020032802e80741ffffffff0371450d0020032802e40710290b4200211b0b2000201b370300200042003703080c160b0c080b201d200220014102746a280200221e470d014190b3c0002102410e21010b024020032802dc07221d450d00201d41186c450d0020032802d80710290b024020032802e80741ffffffff0371450d0020032802e40710290b410e211e0c050b20232001201d201e4b6a2201490d012023211e0b0240201e20032802e807470d00200341e4076a201e410110980120032802e40721020b200220014102746a220241046a2002201e20016b41027410e5071a2002201d3602002003201e41016a3602ec07200341c00a6a200341c8096a10db0120032802c00a2102200320032802c80a3602940a200320023602900a200341b8076a200341900a6a10e401024020032802c40a450d00200210290b20034190076a201d10ae020240202041246c22020d00410021290c030b201f20026a2227415c6a212c200341f0076a2124201f2101410021290340200121020340200241206a2802002101200341900a6a41186a200241186a290000370300200341900a6a41106a200241106a290000370300200341900a6a41086a200241086a290000370300200320022900003703900a200341c00a6a201d200341900a6a109f02200341f0016a20032802c00a221e20032802c80a109e0220032802f001212520032802f4012126024020032802c40a450d00201e10290b200341f8086a201d200341900a6a109d02200341c00a6a20032802f808222220032802800910a1020240024020032802e00a22200d004200211b41002121410821204100211e420021040c010b200341c00a6a41086a290300210420032903c00a211b20032802e40a212120032802e80a211e0b024020032802fc08450d00202210290b02400240201e20014d0d002020200141306c6a2201450d0002402024200141106a221e460d00201e2024412010e7070d020b2001290300200141086a290300201b200410af02212d0240024020032802940722280d004100211e0c010b200328029807212a0340202841086a211e20282f0106222b4105742101410021220240024003402001450d01200341900a6a201e412010e7072223450d02200141606a2101202241016a2122201e41206a211e2023417f4a0d000b2022417f6a212b0b0240202a0d004100211e0c030b202a417f6a212a2028202b4102746a4194036a28020021280c010b0b202820224102746a41e8026a280200211e0b20032802900722014101200141014b1b2201418094ebdc036e222220012022418094ebdc036c476a22224101202241014b1b222220014b0d052003418094ebdc033602c40a20032001201e2001201e491b20226ead428094ebdc037e200120226ead8042ffffffff0f834100418094ebdc032026410020251b6b22012001418094ebdc034b1bad7e428094ebdc0380a722013602c00a200341c00a6a2001418094ebdc034b4102746a350200211b2003418094ebdc033602c40a2003201b202dad7e428094ebdc0380a722013602c00a200341c00a6a2001418094ebdc034b4102746a28020021012003418094ebdc033602c40a2003417f202920016a220120012029491b22013602c00a200341c00a6a2001418094ebdc034b4102746a28020021290b02402021450d00202141306c450d00202010290b200241246a2101202c2002460d050c020b200241246a210202402021450d00202141306c450d00202010290b20272002460d040c000b0b0b200120231041000b41f0a6c700411941dcaac7001033000b0240201c450d00201c41246c450d00201f10290b200341c8016a20052006428094ebdc03420010e007200341b8016a20032903c801221b200341c8016a41086a29030022044280ec94a37c427f10d507200341a8016a201b20042029ad2206420010d507200341d8016a200341b8076a41386a20032903a80122042006200520032903b8017c7e221b428094ebdc03802205a7417f201b428080808080c0b2cd3b541b201b20054280ec94a37c7e7c4280cab5ee01566aad7c221b200341a8016a41086a290300201b200454ad7c10b002200341d8016a41106a290300211b20032903e001210402400240024020032903d8012205a74101470d0020032903c809210520032903d009210620032903d809212e20032903e009212f200341c00a6a41386a201b370300200341f00a6a2004370300200341e10a6a202f370000200341d90a6a202e370000200341d10a6a2006370000200341c90a6a2005370000200341c00a6a41086a220141013a0000200341043a00c00a200341c00a6a10cb01200341c00a6a41186a221e4200370300200341c00a6a41106a221c420037030020014200370300200342003703c00a41dcbec500ad428080808080018422051001221d2900002106200341f8086a41086a2202201d41086a290000370300200320063703f808201d102920012002290300370300200320032903f8083703c00a419fe3c200ad4280808080d0018422061001221d290000212e2002201d41086a2900003703002003202e3703f808201d1029201c20032903f808222e370300200341900a6a41086a221f2001290300370300200341900a6a41106a2220202e370300200341900a6a41186a22212002290300370300200320032903c00a3703900a200341f8006a200341900a6a412010e301200341f8006a41106a290300212e200329038001212f2003280278211d201e4200370300201c420037030020014200370300200342003703c00a20051001221e29000021052002201e41086a290000370300200320053703f808201e102920012002290300370300200320032903f8083703c00a20061001221e29000021052002201e41086a290000370300200320053703f808201e1029201c20032903f8082205370300201f20012903003703002020200537030020212002290300370300200320032903c00a3703900a2003427f202e4200201d1b2205201b7c202f4200201d1b221b20047c2204201b542202ad7c221b2002201b200554201b2005511b22021b3703c80a2003427f200420021b3703c00a200341c00a6a2102200341900a6a21010c010b20054201520d01200341c00a6a41186a221e4200370300200341c00a6a41106a221c4200370300200341c00a6a41086a22014200370300200342003703c00a41dcbec500ad428080808080018422051001221d2900002106200341f8086a41086a2202201d41086a290000370300200320063703f808201d102920012002290300370300200320032903f8083703c00a419fe3c200ad4280808080d0018422061001221d290000212e2002201d41086a2900003703002003202e3703f808201d1029201c20032903f808222e370300200341900a6a41086a221f2001290300370300200341900a6a41106a2220202e370300200341900a6a41186a22212002290300370300200320032903c00a3703900a20034190016a200341900a6a412010e30120034190016a41106a290300212e200329039801212f200328029001211d201e4200370300201c420037030020014200370300200342003703c00a20051001221e29000021052002201e41086a290000370300200320053703f808201e102920012002290300370300200320032903f8083703c00a20061001221e29000021052002201e41086a290000370300200320053703f808201e1029201c20032903f8082205370300201f20012903003703002020200537030020212002290300370300200320032903c00a3703900a2003427f202e4200201d1b2205201b7c202f4200201d1b221b20047c2204201b542202ad7c221b2002201b200554201b2005511b22021b3703c80a2003427f200420021b3703c00a200341c00a6a2102200341900a6a21010b2001ad42808080808004842002ad428080808080028410030b20034190076a41047210d401024020032802dc072202450d00200241186c450d0020032802d80710290b024020032802e80741ffffffff0371450d0020032802e40710290b4200211b0c020b0240201c450d00201c41246c450d00201f10290b4103211d0b200041206a201e3602002000411c6a2002360200200041186a200141ff0171411074201d72418012723602004201211b0b2000201b370300200042003703080c0b0b0240202741ffffffff0371450d00202610290b20004200370308200041206a20013602002000411c6a201c360200200041186a2002202072360200200042013703000c0a0b20004200370308200042003703000c090b41012125410021230c010b0240201e41ffffff3f71450d00201d10290b2025450d0220032802fc0841ffffff3f7121230b41eebec500ad4280808080f0008410012201280000211c2001290004211b200128000c211d2001102941c4f5c100ad4280808080a001841001220129000021042001290008210520011029200320053701900920032004370188092003201d360184092003201b3701fc082003201c3601f808200341d8006a200341f8086a412010fc01200328025c212420032802582126200341c00a6a200341f0076a220110de0120033502c80a42208620032802c00a221cad841004024020032802c40a450d00201c10290b200341900a6a200110d90120033502980a211b20032802900a2122200341003602c80a200342013703c00a2002200341c00a6a10710240024020020d0020032802c40a211d20032802c80a21010c010b2002410574211f410020032802c80a22016b211e20032802c00a212120032802c40a211d202521200340202021020240201d201e6a411f4b0d00200141206a221c2001490d03201d4101742220201c2020201c4b1b221c4100480d030240024002400240201d0d000240201c0d00410121210c020b201c102721210c030b201d201c470d010b201c211d0c020b2021201d201c102b21210b201c211d2021450d060b200241206a2120202120016a221c2002290000370000201c41186a200241186a290000370000201c41106a200241106a290000370000201c41086a200241086a290000370000201e41606a211e200141206a2101201f41606a221f0d000b2003201d3602c40a200320013602c80a200320213602c00a0b02400240201d20016b4104490d0020032802c00a211c201d21020c010b200141046a22022001490d01201d410174221c2002201c20024b1b22024100480d0102400240201d0d00024020020d004101211c0c020b20021027221c450d060c010b20032802c00a211c201d2002460d00201c201d2002102b221c450d050b200320023602c40a2003201c3602c00a0b201c20016a2024410020261b3600002003200141046a22013602c80a4100211d200341003a0090070240024020022001460d00200121020c010b200241016a22012002490d012002410174221d2001201d20014b1b22014100480d010240024020020d0041002102024020010d004101211c0c020b20011027221c450d060c010b20022001460d00201c20022001102b221c450d050b200320013602c40a2003201c3602c00a20032d009007211d0b201c20026a201d3a000020032802c40a2101201b4220862022ad84200241016aad42208620032802c00a2202ad84100302402001450d00200210290b024020032802940a450d00202210290b02402023450d00202510290b024020032802dc072202450d00200241186c450d0020032802d80710290b024020032802e80741ffffffff0371450d0020032802e40710290b20004200370308200042003703000c060b1032000b02402027450d00202741186c450d00202810290b0240202941ffffffff0371450d00202a10290b410121020b20004200370308200041206a20013602002000411c6a201c360200200041186a201f41ff017141107420027241801272360200200042013703000c030b1030000b0240202f20032903b807220558202e200341b8076a41086a290300221b58202e201b511b0d00200341f00a6a202f20057d370300200341c00a6a41086a41083a0000200341c90a6a20032903900a370000200341d10a6a200341900a6a41086a290300370000200341d90a6a200341a00a6a290300370000200341e10a6a200341a80a6a290300370000200341f80a6a202e201b7d202f200554ad7d370300200341043a00c00a200341c00a6a10cb010b024020032802dc072202450d00200241186c450d0020032802d80710290b024020032802e80741ffffffff0371450d0020032802e40710290b200041106a4280a7f2a60137030020002004370308200042003703000c010b20004200370308200042003703000b200341800c6a24000bb10503027f017e047f230041d0006b2202240041eebec500ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941e8f4c100ad4280808080d00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000bb00305037f017e017f077e017f230041e0006b220124002001200010a802200141106a200128020022022001280208220310a9020240024020012903104201510d004200210441002105420021064200210742002108420021094200210a4200210b4200210c4100210d0c010b200141206a290300210c200141306a290300210a200141286a2903002109200141c0006a2903002108200141386a2903002107200141d0006a2903002106200141c8006a2903002104200141d8006a28020021052001290318210b20012d005c210d0b0240410410272200450d0020002005360000200041044108102b2200450d002000417f200d411874220541808080086a220d200d2005491b4118763a0004200041084115102b2200450d002000200b3700052000410d6a200c37000020004115412a102b2200450d00200020093700152000411d6a200a3700002000412a41d400102b2200450d0020002004370035200020073700252000413d6a20063700002000412d6a20083700002003ad4220862002ad842000ad4280808080d0088410032000102902402001280204450d00200210290b200141e0006a24000f0b1030000bc20503027f017e047f230041d0006b2202240041b3e6ca00ad4280808080e00084100122032900002104200241086a200341086a290000370300200220043703002003102941b9e6ca00ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100522012900002104200241306a41086a200141086a2900003703002002200437033020011029200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a1075200310292002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a20002001360208200020083602042000200336020002402002280224450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000ba10404037f047e027f037e230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad841007108b0202400240200328020822010d00200042003703000c010b200328020c2102024002400240200341106a28020022044104490d0020044104460d002004417b6a4110490d002004416b6a4110490d002004415b6a4110490d002004414b6a410f4b0d010b20034100360220200342013703182003410d36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341f4eaca003602382003200341286a360248200341346a41a8a3c800200341386a10371a200335022042208620033502188410080240200328021c450d00200328021810290b200042003703000c010b2001280000210420012d000421052001410d6a2900002106200129000521072001411d6a290000210820012900152109200341186a41026a200341386a41026a2d0000220a3a0000200320032f0038220b3b01182001412d6a290000210c2001290025210d2001290035210e200041c0006a2001413d6a290000370300200041386a200e370300200041306a200c370300200041286a200d370300200041206a2008370300200041186a2009370300200041106a200637030020002007370308200020053a004c200041c8006a2004360200200042013703002000200b3b004d200041cf006a200a3a00000b2002450d00200110290b200341d0006a24000b9c0f03037f017e0d7f230022052106200541e0016b41607122052400024002402002200384500d00200441ff01712207450d002000290000210841002109024020074101460d004102410120044101711b21090b20052002370300200520093a00182005200837031020052003370308200541c0016a200110df03200541a0016a20052802c001220720052802c80110e60320052902a401420020052802a00122041b2102024020052802c401450d00200710290b2004410820041b210a2002a7210b0240024002402002422088a7220c450d00200a200c4105746a210d200541a0016a411072210e200541a0016a411972210f410021070340200541e8006a41106a2210200a20076a220441106a290300370300200541e8006a41086a2211200441086a290300370300200520042903003703682005200441196a28000036023820052004411c6a28000036003b200441186a2d000022124103460d01200f2005280238360000200f41036a200528003b360000200520102903003703b001200520112903003703a801200520052903683703a001200520123a00b80102400240200e2000460d00200e2900002000290000510d00200520052903b801220237039801200520052903b00137039001200520052903a80137038801200520052903a001370380010c010b200541033a00d80120052005290318220237039801200520052903103703900120052005290308370388012005200529030037038001200520052903d001370310200520052903c801370308200520052903c001370300200520052903d80122033703182003a721090b2002a7221041ff01714103470d02200741206a2107200441206a200d470d000b0b200541003602a801200542083703a001200b41ffffff3f71450d01200a10290c010b200541d0006a41106a220f200529039001370300200541d0006a41086a22112005290388013703002005200528009c0136004320052005280099013602402005200529038001370350200520052802403602482005200528004336004b41201027220e450d02200e2005290350370300200e20103a0018200e2005280248360019200e411c6a200528004b360000200e41106a200f290300370300200e41086a2011290300370300200542818080801037022c2005200e3602280240200c41057441606a2007460d00200441206a2110200c410574200a6a41606a211320054180016a4119722114200541a0016a4110722112200541a0016a411972210f4101210c0340201021040340200541e8006a41106a2210200441106a290300370300200541e8006a41086a2211200441086a29030037030020052004290300370368200441186a2d000021072005200441196a28000036023820052004411c6a28000036003b20074103460d02200f2005280238360000200f41036a200528003b360000200520102903003703b001200520112903003703a801200520052903683703a001200520073a00b8010240024020122000460d0020122900002000290000510d00200520052903b801220237039801200520052903b00137039001200520052903a80137038801200520052903a001370380010c010b200541033a00d80120052005290318220237039801200520052903103703900120052005290308370388012005200529030037038001200520052903d001370310200520052903c801370308200520052903c001370300200520052903d80122033703182003a721090b02402002a7220741ff01714103470d00200441206a2204200d470d010c030b0b200541d0006a41106a2210200529039001370300200541d0006a41086a2211200529038801370300200520142800003602402005201441036a2800003600432005200529038001370350200520052802403602482005200528004336004b200541c0016a41086a22152011290300370300200541c0016a41106a22112010290300370300200520052903503703c001200520052802483602a0012005200528004b3600a3010240200c200528022c470d00200541286a200c10a1012005280228210e0b200441206a2110201529030021022011290300210320052903c0012108200e200c4105746a221120073a001820112008370300201120052802a0013600192011411c6a20052800a301360000201141106a2003370300201141086a20023703002005200c41016a220c36023020132004470d000b0b0240200b41ffffff3f71450d00200a10290b200541a0016a41086a200541286a41086a280200360200200520052903283703a0010b02400240200941ff01714103470d0020052802a801210420052802a0012107200541a0016a21050c010b200541c0016a41186a220f2005290318370300200541c0016a41106a22102005290310370300200541c0016a41086a22112005290308370300200520052903003703c001024020052802a801220420052802a401470d00200541a0016a200410a10120052802a80121040b20052802a001220720044105746a220020052903c001370300200041086a2011290300370300200041106a2010290300370300200041186a200f2903003703002005200441016a22043602a801200541a0016a21050b20012007200410e703200541046a28020041ffffff3f71450d00200528020010290b200624000f0b1039000bd80803067f017e027f230041a0016b22032400200341e8006a200110d801200341f8006a20032802682204200328027010cd01200341086a41086a220520034182016a290100370300200341086a41106a22062003418a016a290100370300200341086a41176a220720034191016a2900003700002003200329017a37030802400240024020032d00784101470d0020032d00792108200341c8006a41176a2007290000370000200341c8006a41106a2006290300370300200341c8006a41086a2005290300370300200320032903083703480240200328026c450d00200410290b200341286a41176a2204200341c8006a41176a290000370000200341286a41106a2205200341c8006a41106a290300370300200341116a200341d0006a290300370000200341196a2005290300370000200341206a2004290000370000200320083a000820032003290348370009200341c8006a200110dc01200341f8006a20032802482204200328025010e0012003290388012109200328028401210a200328027821080240200328024c450d00200410290b0240200a450d00200a2009422088a741027422046a210b0240024020040d00410121040c010b200b200a6b417c6a41027641026a21040b200420024b0d02200341f8006a200110dc0120033502800142208620032802782204ad8410040240200328027c450d00200410290b4100210420082107200a2106024003402004417e712105410221040240024020054102460d00200821050c010b2006450d02200b2006460d02200641046a2106410321042007417f6a220721050b200341f8006a41186a200141186a290000370300200341f8006a41106a200141106a290000370300200341f8006a41086a200141086a290000370300200320053602980120032001290000370378200341c8006a200341f8006a10dd01200335025042208620032802482205ad841004200328024c450d00200510290c000b0b200942ffffffff0383500d00200a10290b200341f8006a200110d80120033502800142208620032802782204ad8410040240200328027c450d00200410290b200341f8006a200341086a10db0120033502800142208620032802782204ad8410040240200328027c450d00200410290b200341f8006a200110a60220033502800142208620032802782204ad8410040240200328027c450d00200410290b200341f8006a200110de0120033502800142208620032802782204ad8410040240200328027c450d00200410290b200341f8006a200110d90120033502800142208620032802782204ad8410040240200328027c450d00200410290b200110b202200041043a00000c020b0240200328026c450d00200410290b200041086a4108360200200041046a41d7b4c000360200200041026a41013a000020004183123b01000c010b0240200942ffffffff0383500d00200a10290b20004183123b0100200041086a4116360000200041046a41c1b0c000360000200041026a411e3a00000b200341a0016a24000bea0306037f017e0d7f027e017f017e230041306b22022400200241106a200110df03200220022802102203200228021810e60320022902044200200228020022041b210502402002280214450d00200310290b2004410820041b2106024002402005422088a722070d00410021070c010b200041706a210841002103200621044100210902400240034002400240024020082004460d00200441106a220a2900002000290000510d0020030d01410021030c020b200341016a21030c010b200920036b220b20074f0d02200241106a41186a220c200420034105746b220b41186a220d290300370300200241106a41106a220e200b41106a220f290300370300200241106a41086a2210200b41086a22112903003703002002200b290300370310200441086a22122903002113200a2903002114200441186a22152903002116200b2004290300370300200d2016370300200f2014370300201120133703002015200c290300370300200a200e29030037030020122010290300370300200420022903103703000b200441206a21042007200941016a2209460d020c000b0b200b20074180bdc7001036000b2003417f6a20074f0d00200542ffffffff0f832105200720036b21070b20012006200710e7030240200542ffffff3f83500d00200610290b200241306a24000b800201027f230041d0006b220224002002200136020420022000360200200241086a2001ad4220862000ad841007108b0202400240200228020822010d00410321000c010b200228020c210302400240200241106a280200450d0020012d000022004103490d010b20024100360220200242013703182002410d36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241f4eaca003602382002200241286a360248200241346a41a8a3c800200241386a10371a200235022042208620023502188410080240200228021c450d00200228021810290b410321000b2003450d00200110290b200241d0006a240020000be10503027f017e057f230041e0006b2202240041eebec500ad4280808080f00084100122032900002104200241206a41086a200341086a290000370300200220043703202003102941f7c4c000ad4280808080800284100122032900002104200241c0006a41086a200341086a2900003703002002200437034020031029200220013602542002200241d4006aad4280808080c000841002220329000037035820031029200241146a200241d8006a3602002002200241d8006a41086a36020c2002200241d4006a3602102002200241d8006a360208200241306a200241086a107502400240024002402002280238220541206a2206417f4c0d00200228023021070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290320370000200341086a200241206a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290340370010200341186a200241c0006a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a02402002280234450d00200710290b200241086a2003200610d101200241c0006a41086a2201200241086a410c6a2902003703002002200229020c3703400240024020022802084101460d00200042003702002000410c6a41003602000c010b20002002290340370200200041086a20012903003702000b02402008450d00200310290b200241e0006a24000f0b1038000b1039000b1032000b1030000bbb0302027f037e230041d0006b22042400200441386a20024201200242015620034200522003501b22051b22022003420020051b2203428094ebdc03420010e007200441286a20042903382206200441386a41086a2903002207428094ebdc03420010d507200441186a20022003200620022004290328852003200441286a41086a2903008584420052ad7c22084201200842015620072008200654ad7c22064200522006501b22051b22082006420020051b220710e00702400240024020042903182206428080808010544100200441186a41086a290300501b450d00200441086a200220002002200054200320015420032001511b22051b2003200120051b2008200710e00720042903082203428080808010544100200441086a41086a290300501b450d012006a7450d02200441d0006a2400200342ffffffff0f83428094ebdc037e200642ffffffff0f8380a70f0b2004411136024c200441ecaac70036024841f1a8c70041de00200441c8006a41a8a7c70041d0a9c700103a000b2004411136024c200441ecaac70036024841f1a8c70041de00200441c8006a41a8a7c70041ccaac700103a000b41f0a6c700411941dcaac7001033000be119020c7f087e23004190046b2204240020044190036a200110a6024100200428029003220520042802980310ad0241ff0171220620064103461b21060240200428029403450d00200510290b0240024002400240024020060e03000201000b200441a0016a200110d80120044190036a20042802a001220620042802a80110cd0120044180026a41086a220520044199036a29000037030020044180026a41106a2207200441a1036a29000037030020044180026a41186a2208200441a9036a29000037030020042004290091033703800202400240024020042d0090034101470d0020044180016a41186a200829030037030020044180016a41106a200729030037030020044180016a41086a2005290300370300200420042903800237038001024020042802a401450d00200610290b200441e0016a41186a20044180016a41186a290300370300200441e0016a41106a20044180016a41106a290300370300200441e0016a41086a20044180016a41086a29030037030020042004290380013703e001200441c0006a200441e0016a10db0120044190036a20042802402209200428024810e201200441a0016a41086a220520044190036a41086a290300370300200441a0016a41106a220720044190036a41106a290300370300200441a0016a41186a220820044190036a41186a29030037030020044180026a41086a220a200441bc036a29020037030020044180026a41106a220b200441c4036a29020037030020044180026a41186a220c200441cc036a29020037030020044180026a41206a220d200441d4036a29020037030020044180026a41286a220e200441dc036a29020037030020044180026a41306a220f200441e4036a28020036020020042004290390033703a001200420042902b4033703800220042802b0032206450d01200441e0026a41186a2008290300370300200441e0026a41106a2007290300370300200441e0026a41086a2005290300370300200441086a41086a200a290300370300200441086a41106a200b290300370300200441086a41186a200c290300370300200441086a41206a200d290300370300200441086a41286a200e290300370300200441086a41306a200f280200360200200420042903a0013703e002200420042903800237030802402004280244450d00200910290b20044180026a41186a200441e0016a41186a290300221037030020044180026a41106a200441e0016a41106a290300221137030020044180026a41086a200441e0016a41086a2903002212370300200420042903e00122133703800220044190036a41186a201037030020044190036a41106a201137030020044190036a41086a201237030020044190036a41286a200441e0026a41086a290300221437030020044190036a41306a200441e0026a41106a290300221537030020044190036a41386a200441e0026a41186a29030022163703002004201337039003200420042903e00222173703b003200441c0006a41386a2016370300200441c0006a41306a2015370300200441c0006a41286a2014370300200441e0006a2017370300200441c0006a41186a2010370300200441c0006a41106a2011370300200441c0006a41086a2012370300200420133703400c020b20042802a401450d04200610290c040b02402004280244450d00200910290b20044180026a41186a200441e0016a41186a29030037030020044180026a41106a200441e0016a41106a29030037030020044180026a41086a200441e0016a41086a290300370300200420042903e001370380020b2006450d02200441a0016a41386a2207200441c0006a41386a290300370300200441a0016a41306a2208200441c0006a41306a290300370300200441a0016a41286a220a200441c0006a41286a290300370300200441a0016a41206a220b200441c0006a41206a290300370300200441a0016a41186a200441c0006a41186a2205290300370300200441a0016a41106a200441c0006a41106a220c290300370300200441a0016a41086a200441c0006a41086a220d290300370300200420042903403703a001200441e0016a41186a2005290300370300200441e0016a41106a200c290300370300200441e0016a41086a200d290300370300200420042903403703e00120044180026a41186a2205200729030037030020044180026a41106a2207200829030037030020044180026a41086a2208200a290300370300200420063602a0022004200b29030037038002200441a4026a2004290308370200200441ac026a200441086a41086a290300370200200441b4026a200441086a41106a290300370200200441bc026a200441086a41186a290300370200200441c4026a200441086a41206a290300370200200441cc026a200441086a41286a290300370200200441d4026a200441086a41306a2802003602002005290300211020072007290300221120027c22123703002005201020037c2012201154ad7c3703002008200829030020037c200429038002221020027c2211201054ad7c221237030020042011370380022004200337038801200420023703800102400240200220038450450d004200210342002110420021020c010b200420013602dc02200441e0026a200120044180016a200441dc026a10b302024020042802e0024101470d004200211020042903e8022103420121020c010b20044188036a290300211020044180036a29030021034200210220042903e8024201520d00200441e0026a41106a2903002113200441c8036a200441e0026a41186a290300370300200441c0036a201337030020044190036a41086a41003a000020044199036a2001290000370000200441a1036a200141086a290000370000200441a9036a200141106a290000370000200441b1036a200141186a290000370000200441033a00900320044190036a10cb010b200442f3e885db96cddbb3203703800120044180016a20044180026a41386a20112012411f10aa0220044190036a200441e0016a10db01200428029003210120042004280298033602e402200420013602e00220044180026a200441e0026a10e4010240200428029403450d00200110290b024020042802a4022201450d00200141186c450d0020042802a00210290b0240200441b0026a28020041ffffffff0371450d0020042802ac0210290b200242018521020c030b200441a0016a200110d80120044190036a20042802a001220120042802a80110cd0120044180026a41086a220620044199036a29000037030020044180026a41106a2205200441a1036a29000037030020044180026a41186a2207200441a9036a290000370300200420042900910337038002024020042d0090034101470d00200441c0006a41186a2007290300370300200441c0006a41106a2005290300370300200441c0006a41086a20062903003703002004200429038002370340024020042802a401450d00200110290b200441a0016a41186a200441c0006a41186a290300370300200441a0016a41106a200441c0006a41106a290300370300200441a0016a41086a200441c0006a41086a290300370300200420042903403703a001200420023703082004200337031002400240200220038450450d004200210242002103420021100c010b2004200441a0016a3602e00220044180026a200441a0016a200441086a200441e0026a10b30202402004280280024101470d00420021102004290388022103420121020c010b200441a8026a2903002110200441a0026a2903002103420021022004290388024201520d0020044180026a41106a2903002111200441c8036a20044180026a41186a290300370300200441c0036a201137030020044190036a41086a41003a000020044199036a20042903a001370000200441a1036a200441a0016a41086a290300370000200441a9036a200441a0016a41106a290300370000200441b1036a200441a0016a41186a290300370000200441033a00900320044190036a10cb010b200242018521020c030b20042802a401450d0120011029420021020c020b200420023703a001200420033703a80102400240200220038450450d004200210342002110420021020c010b2004200136024020044180026a2001200441a0016a200441c0006a10b30202402004280280024101470d00420021102004290388022103420121020c010b200441a8026a2903002110200441a0026a2903002103420021022004290388024201520d0020044180026a41106a2903002111200441c8036a20044180026a41186a290300370300200441c0036a201137030020044190036a41086a41003a000020044199036a2001290000370000200441a1036a200141086a290000370000200441a9036a200141106a290000370000200441b1036a200141186a290000370000200441033a00900320044190036a10cb010b200242018521020c010b420021020b2000200337030820002002370300200041106a201037030020044190046a24000b845d08137f017e017f027e117f017e067f077e230041c0036b22082400200820033a005f20084180016a41286a200441286a29030037030020084180016a41206a200441206a29030037030020084180016a41186a200441186a29030037030020084180016a41106a200441106a29030037030020084180016a41086a200441086a2903003703002008200429030037038001200841c0026a20084180016a200510b40220084180036a41086a2205200841c0026a41106a29030037030020084180036a41106a2203200841c0026a41186a29030037030020084180036a41186a2209200841c0026a41206a290300370300200820082903c80237038003024002400240024002400240024002400240024002400240024002400240024002400240024020082903c0024201510d00200141086a280200210a200241bc016a280200210b200241b0016a280200210c200241a4016a280200210d20024198016a280200210e2002418c016a280200210f20024180016a2802002110200241f4006a2802002111200241e8006a2802002112200241dc006a2802002113200241d0006a2802002114200241c4006a2802002115200241386a28020021162002412c6a2802002117200241206a2802002118200241146a2802002119200241086a280200211a200841a0036a41086a22034200370300200842003703a00341eebec500ad4280808080f0008410012209290000211b200841b0036a41086a221c200941086a2900003703002008201b3703b003200910292003201c290300370300200820082903b0033703a00341c6b8c000ad4280808080a0028410012209290000211b2009290008211d20091029200520032903003703002008201d370398032008201b37039003200820082903a00337038003200841c4026a41003a0000200841003602c002200841d0006a20084180036a4120200841c0026a4105410010c7012008280250450d01200820082802542205410520054105491b360284012008200841c0026a36028001200841c8006a20084180016a10c80120082802480d01200828024c2203200741ffff0371470d02200841a0036a41086a22054200370300200842003703a00341eebec500ad4280808080f00084221e10012209290000211b200841b0036a41086a221c200941086a2900003703002008201b3703b003200910292005201c290300370300200820082903b0033703a003419cf3c100ad4280808080e0018410012209290000211b2009290008211d2009102920084180036a41086a221f20052903003703002008201d370398032008201b37039003200820082903a00337038003200841c0006a20084180036a412010fc01200a20032008280244410020082802401b2209200920034b1b470d0320054200370300200842003703a003201e10012203290000211b201c200341086a2900003703002008201b3703b003200310292005201c290300370300200820082903b0033703a00341d8b8c000ad4280808080a0028410012203290000211b2003290008211d20031029201f20052903003703002008201d370398032008201b37039003200820082903a00337038003200841c4026a41003a0000200841003602c002200841386a20084180036a4120200841c0026a4105410010c7012008280238450d042008200828023c2205410520054105491b360284012008200841c0026a36028001200841306a20084180016a10c80120082802300d0420082802342006470d05200841a0036a41086a22054200370300200842003703a00341eebec500ad4280808080f0008410012203290000211b200841b0036a41086a2209200341086a2900003703002008201b3703b0032003102920052009290300370300200820082903b0033703a00341c6b8c000ad4280808080a0028410012203290000211b2003290008211d2003102920084180036a41086a20052903003703002008201d370398032008201b37039003200820082903a0033703800320084180016a20084180036a108d0202402008280280012205450d002008200829028401221b3702642008200536026020012802002120200128020421210240200a0d00412021220c0a0b41142122201b422088a720202f010022014d0d0920084188016a2203200520014105746a220141096a29000037030020084190016a2205200141116a29000037030020084197016a2209200141186a290000370000200820012900013703800120012d000021014120212241201027221c450d0b201c20013a0000201c200829038001370001201c41096a2003290300370000201c41116a2005290300370000201c41186a20092900003700002008428180808010370284032008201c3602800341012109200a4101460d0841142122200828026820202f010222014d0d08200841c0026a41086a2223200828026020014105746a220141096a290000370300200841c0026a41106a2224200141116a290000370300200841c0026a41176a2225200141186a290000370000200820012900013703c002202041046a211f200a410174417c6a210520012d00002126412121034102210941012101034020084180016a41176a2227202529000037000020084180016a41106a2228202429030037030020084180016a41086a22292023290300370300200820082903c0023703800102402009417f6a2001470d0020084180036a20014101109e01200828028003211c0b201c20036a2201417f6a20263a00002001200829038001370000200141086a2029290300370000200141106a2028290300370000200141176a20272900003700002008200936028803024020050d00412021220c0a0b2008280268201f2f010022014d0d092023200828026020014105746a220141096a2900003703002024200141116a2900003703002025200141186a290000370000200820012900013703c0022005417e6a2105201f41026a211f200341206a2103200941016a210920012d0000212620082802840321010c000b0b200041113a001a2000420037030820004201370300200041206a41133602002000411c6a41d0b2c000360200200041186a4183123b01000c060b200020082903800337030820004201370300200041206a2009290300370300200041186a2003290300370300200041106a20052903003703000c050b200041206a41133602002000411c6a41d0b2c000360200200041113a001a200041186a4183123b010020004200370308200042013703000c040b2000411b3a001a2000420037030820004201370300200041206a41193602002000411c6a41fab0c000360200200041186a4183123b01000c030b200041123a001a2000420037030820004201370300200041206a41183602002000411c6a41b8b2c000360200200041186a4183123b01000c020b200041206a41133602002000411c6a41d0b2c000360200200041113a001a200041186a4183123b010020004200370308200042013703000c010b2000411b3a001a2000420037030820004201370300200041206a41193602002000411c6a41fab0c000360200200041186a4183123b01000b2002108702200141046a28020041808080807872418080808078460d0b200128020010290c0b0b0240202141808080807872418080808078460d00202010290b20082802840341ffffff3f7121230c010b410021234101211c0240202141808080807872418080808078460d00202010290b410021090b024020224120460d0002402023450d00201c10290b41c1b0c000210441162105411e21010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020220e20000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000b20084194016a4101360200200842013702840120084198e3ca0036028001200841043602c402200841bcd4c8003602c0022008200841c0026a3602900120084180016a4180a6cc001040000b41dfb4c0002104410d2105410021010c1d0b41d7b4c000210441082105410121010c1c0b41cab4c0002104410d2105410221010c1b0b41bdb4c0002104410d2105410321010c1a0b41b1b4c0002104410c2105410421010c190b41a3b4c0002104410e2105410521010c180b4192b4c000210441112105410621010c170b4181b4c000210441112105410721010c160b41f5b3c0002104410c2105410821010c150b41e8b3c0002104410d2105410921010c140b41dcb3c0002104410c2105410a21010c130b41cab3c000210441122105410b21010c120b41b0b3c0002104411a2105410c21010c110b419eb3c000210441122105410d21010c100b4190b3c0002104410e2101410e21050c0f0b41f9b2c000210441172105410f21010c0e0b41e3b2c0002104411021010c0d0b41d0b2c000210441132105411121010c0c0b41b8b2c000210441182105411221010c0b0b41a5b2c000210441132101411321050c0a0b4191b2c000210441142101411421050c090b41fbb1c0002104411521010c080b41e4b1c000210441172105411621010c070b41cbb1c000210441192105411721010c060b41b6b1c000210441152105411821010c050b41a5b1c000210441112105411921010c040b4193b1c000210441122105411a21010c030b41fab0c000210441192105411b21010c020b41ecb0c0002104410e2105411c21010c010b41d7b0c000210441152105411d21010b200020013a001a2000420037030820004201370300200041206a20053602002000411c6a2004360200200041186a4183123b0100200828026441ffffff3f71450d08200828026010290c080b200841a0036a41086a22014200370300200842003703a00341eebec500ad4280808080f0008410012205290000211b200841b0036a41086a2203200541086a2900003703002008201b3703b0032005102920012003290300370300200820082903b0033703a00341d8b8c000ad4280808080a0028410012205290000211b2005290008211d2005102920084180036a41086a20012903003703002008201d370398032008201b37039003200820082903a0033703800320084180016a20084180036a108d02024020082802800122250d00200041113a001a2000420037030820004201370300200041206a41133602002000411c6a41d0b2c000360200200041186a4183123b010002402023450d00201c10290b200828026441ffffff3f71450d082008280260102920021087020c090b2008200829028401221b3702742008202536027020084180016a200241c00110e4071a200841c0026a20084180016a200841f0006a200841e0006a10b502201ba72128024020082d00c0024101470d00200820082d00c1023a00b003024041002802d8a74c4102490d0020084110360284032008200841b0036a3602800341002802888040210241002802848040210441002802dca74c2101200841c0016a418c15360200200841b8016a42db80808010370300200841b4016a41eec5c000360200200841ac016a420e370200200841a8016a41e0c5c000360200200841a0016a420137030020084190016a420137030020084188016a41073602002008419c016a20084180036a360200200841f4a5c20036028c01200841bcc1c20036028401200841023602800120044180a4c000200141024622011b20084180016a20024198a4c00020011b2802101102000b200041206a41143602002000411c6a4191b2c000360200200041143a001a200041186a4183123b010020004200370308200042013703000c070b20082802c402222a200841c0026a410c6a280200222b412c6c222c6a212d200841c0026a41086a222e280200212f0240202c450d0020084180036a41086a212941eebec500ad4280808080f00084211b41b8dcc900ad4280808080a001842130202a21220340201b10012202290000211d200841b0036a41086a2224200241086a2900003703002008201d3703b00320021029203010012202290008211d200228000421212002280000213120021029412010272202450d0220022022410c6a2201290000370000200241186a200141186a2232290000370000200241106a200141106a2233290000370000200241086a200141086a223429000037000020082002ad42808080808004841002220529000037038003200510292008200241206a36028c0120082002360288012008202936028401200820084180036a36028001200841c0026a20084180016a10752002102920082802c802222641206a2205417f4c0d0720082802c00221270240024020050d0041002103410121020c010b200510272202450d03200521030b024002402003410f4d0d002003211f0c010b2003410174221f4110201f41104b1b221f4100480d04024020030d00201f102722020d010c080b2003201f460d0020022003201f102b2202450d070b200220082903b003370000200241086a202429030037000002400240201f4170714110460d00201f21030c010b201f41017422034120200341204b1b22034100480d04201f2003460d002002201f2003102b2202450d070b2002201d370018200220213600142002203136001002400240200341606a2026490d002003211f0c010b2026415f4b0d042003410174221f2005201f20054b1b221f4100480d042003201f460d0020022003201f102b2202450d070b200241206a2027202610e4071a024020082802c402450d00202710290b200841286a200220054180a6cc004100410010c701200828022821210240201f450d00200210290b201b10012202290000211d2024200241086a2900003703002008201d3703b0032002102941f5b7c000ad4280808080a0018410012202290008211d200228000421312002280000213520021029412010272202450d0220022001290000370000200241186a2032290000370000200241106a2033290000370000200241086a203429000037000020082002ad42808080808004841002220529000037038003200510292008200241206a36028c0120082002360288012008202936028401200820084180036a36028001200841c0026a20084180016a10752002102920082802c802222641206a2205417f4c0d0720082802c00221270240024020050d0041002103410121020c010b200510272202450d03200521030b024002402003410f4d0d002003211f0c010b2003410174221f4110201f41104b1b221f4100480d04024020030d00201f10272202450d080c010b2003201f460d0020022003201f102b2202450d070b200220082903b003370000200241086a202429030037000002400240201f4170714110460d00201f21030c010b201f41017422034120200341204b1b22034100480d04201f2003460d002002201f2003102b2202450d070b2002201d370018200220313600142002203536001002400240200341606a2026490d002003211f0c010b2026415f4b0d042003410174221f2005201f20054b1b221f4100480d042003201f460d0020022003201f102b2202450d070b200241206a2027202610e4071a024020082802c402450d00202710290b20084180016a2002200510b702024020082d009001220541024622240d0020082802800121202008280284012136200829038801211e0b0240201f450d00200210290b024002400240024002402021410146220220054102472203460d002002450d010240202241086a2802004101470d000240202228020022022001460d0020022001412010e7070d010b20022f012041ffff03460d030b200041183a001a2000420037030820004201370300200041206a41153602002000411c6a41b6b1c000360200200041186a4183123b010020054102460d0a203641ffffff3f710d090c0a0b024041002802d8a74c450d0041002802888040210241002802848040210441002802dca74c2101200841c0016a419b15360200200841b8016a42db80808010370300200841b4016a41eec5c000360200200841ac016a420e370200200841a8016a41e0c5c000360200200841a0016a42003703002008419c016a4180a6cc0036020020084190016a420137030020084188016a4107360200200841fca5c20036028c01200841bcc1c20036028401200841013602800120044180a4c000200141024622011b20084180016a20024198a4c00020011b2802101102000b200041153a001a2000420037030820004201370300200041206a41163602002000411c6a41fbb1c000360200200041186a4183123b010020054102460d09203641ffffff3f71450d090c080b02402003450d00024020222802082202450d002022280200221f200241226c6a2126201e422088a72127201ea7410574212403402008201f22053602c002200541226a211f2024210120202102024002400340024020010d004117210241e4b1c0002104411621010c020b024020052002460d0020022005412010e7072103200141606a2101200241206a210220030d010b0b20084180016a200841c0026a10df01200828028c012202450d012008280288012101024020082802900141ffffffff0371450d00200210290b200120274d0d014119210241cbb1c0002104411721010b200020013a001a2000420037030820004201370300200041206a20023602002000411c6a2004360200200041186a4183123b0100203641ffffff3f710d0b0c0c0b201f2026470d000b0b203641ffffff3f71450d030c020b4184a6c20041fd004184a7c2001057000b20240d01203641ffffff3f71450d010b202010290b2022412c6a2222202d470d000b0b2008410036028803200842043703800320084180036a4100202c412c6d109301200828028003210120082802880321022008202d36028c012008202a360288012008202f360284012008202a360280012008200841b0036a36029001202e2002360200200820084180036a41086a3602c402200820012002412c6c6a3602c00220084180016a200841c0026a10b802200828028403212020084180016a201c200920082802800322312008280288032221109a022008280288012129200828028401212220082802800121270240024002400240024002400240200828028c010d002027450d022022450d012022210220272101034020012802c80521012002417f6a22020d000b20272102202221050340200220022f01064102746a41c8056a28020021022005417f6a22050d000b20084180016a21050c030b200041193a001a2000420037030820004201370300200041206a41113602002000411c6a41a5b1c000360200200041186a4183123b01000c040b20084180016a210520272101202721020c010b41002101200841003602840120084180016a21050c010b20082002360284012008418c016a20022f0106360200200841003602880120084100360280010b20084180036a41086a200541086a290200221b37030020082005290200221d3703800320084180016a41186a201b370300420021372008420037038801200820013602840120084100360280012008201d37039001200820293602a0010240024020290d00427f21384200211e4200213942002130427f213a0c010b20082029417f6a3602a00120084180016a410020011b221f2802002105201f28020821240240024002400240201f28020c2203201f28020422022f01064f0d00200221010c010b034020022802002201450d02200541016a210520022f0104210320012102200320012f01064f0d000b0b2003ad4220862024ad84211b0c010b2024ad211b410021010b201b422088a7222441016a2103201ba721260240024020050d00200121020c010b200120034102746a41c8056a2802002102410021032005417f6a2205450d00034020022802c80521022005417f6a22050d000b0b201f200336020c201f2026360208201f2002360204201f4100360200200120244105746a41e8026a2102427f2138427f213a4200213942002130420021374200211e0340200841086a200241086a290300221b42002002290300221d420010d507200841186a201d4200201d420010d507427f201e427f200841186a41086a290300223b2008290308223c203c7c7c223c201b2008290310223d84203d84420052203c203b547222021b7c2037427f200829031820021b7c223b2037542202ad7c223720022037201e542037201e511b22021b211e427f203b20021b2137201b203a201d203854201b203a54201b203a511b22021b213a201d203820021b2138427f2030201b7c2039201d7c221d2039542202ad7c221b2002201b203054201b2030511b22021b2130427f201d20021b213920082802a0012202450d0120082002417f6a3602a00120084180016a41002008280284011b221f2802002105201f2802082124024002400240201f28020c2203201f28020422022f01064f0d00200221010c010b0240034020022802002201450d01200541016a210520022f0104210320012102200320012f0106490d020c000b0b2024ad211b410021010c010b2003ad4220862024ad84211b0b201b422088a7222441016a2103201ba721260240024020050d00200121020c010b200120034102746a41c8056a2802002102410021032005417f6a2205450d00034020022802c80521022005417f6a22050d000b0b201f200336020c201f2026360208201f2002360204201f4100360200200120244105746a41e8026a21020c000b0b200841e8026a201e370300200841c0026a41186a2030370300200820373703e002200820393703d002200820383703c0022008203a3703c802200841c0026a2004460d01200841c0026a2004413010e707450d012000411a3a001a2000420037030820004201370300200041206a41123602002000411c6a4193b1c000360200200041186a4183123b01000b0240024020270d004100212920084194016a410036020020084100360284010c010b0240024020220d00202721020c010b2022210220272104034020042802c80521042002417f6a22020d000b202721020340200220022f01064102746a41c8056a28020021022022417f6a22220d000b200421270b2008419c016a20022f010636020020084198016a410036020020084194016a200236020020084100360290012008420037038801200820273602840120084100360280010b200820293602a00120084180016a10b90202402021450d002021412c6c21042031210203400240200241046a2802002200450d00200041306c450d00200228020010290b2002412c6a2102200441546a22040d000b0b2020450d072020412c6c450d07203110290c070b0240024020270d004100212741002102410021290c010b0240024020220d00202721020c010b2022210220272104034020042802c80521042002417f6a22020d000b202721020340200220022f01064102746a41c8056a28020021022022417f6a22220d000b200421270b20022f010621040b2008419c016a2201200436020020084198016a410036020020084194016a2002360200200820293602a00120084100360290012008420037038801200820273602840120084100360280012008200841b0036a3602a401200841f0026a20084180016a109b02024041002802d8a74c4103490d002008418c036a41113602002008410f360284032008200841c0026a360288032008200841df006a3602800341002802888040210241002802848040210441002802dca74c2105200841c0016a41db15360200200841b8016a42db80808010370300200841b4016a41eec5c000360200200841ac016a420e370200200841a8016a41e0c5c000360200200841a0016a420237030020084190016a420337030020084188016a4107360200200120084180036a36020020084194a7c20036028c01200841bcc1c20036028401200841033602800120044180a4c000200541024622011b20084180016a20024198a4c00020011b2802101102000b20082802f802212420082802f402212920082802f002212620082d005f2127200841a0036a41086a22024200370300200842003703a00341eebec500ad4280808080f0008410012204290000211b200841b0036a41086a2201200441086a2900003703002008201b3703b0032004102920022001290300370300200820082903b0033703a0034180ffc100ad4280808080d0018410012204290000211b2004290008211d2004102920084180036a41086a20022903003703002008201d370398032008201b37039003200820082903a0033703800320084100360288012008420137038001200920084180016a107102402009450d002009410574211f410020082802880122046b21052008280284012103201c2102034002400240200320056a4120490d0020082802800121010c010b200441206a22012004490d04200341017422092001200920014b1b22094100480d040240024020030d00024020090d00410121010c020b200910272201450d090c010b200828028001210120032009460d00200120032009102b2201450d080b20082009360284012008200136028001200921030b200120046a22012002290000370000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a2900003700002008200441206a220436028801200541606a2105200241206a2102201f41606a221f0d000b0b202420084180016a107102402024450d002026202441d0006c6a21222026211f034002400240200828028401220120082802880122026b4120490d0020082802800121040c010b200241206a22042002490d04200141017422052004200520044b1b22054100480d040240024020010d00024020050d00410121040c020b200510272204450d090c010b200828028001210420012005460d00200420012005102b2204450d080b200820053602840120082004360280010b200420026a2204201f290000370000200441186a201f41186a290000370000200441106a201f41106a290000370000200441086a201f41086a2900003700002008200241206a360288012008201f41206a3602b003200841b0036a20084180016a10e5012008201f41306a3602b003200841b0036a20084180016a10e501201f2802402102201f280248220420084180016a107102402004450d00200441306c2103034002400240200828028401220520082802880122046b4120490d0020082802800121010c010b200441206a22012004490d06200541017422092001200920014b1b22094100480d060240024020050d00024020090d00410121010c020b200910272201450d0b0c010b200828028001210120052009460d00200120052009102b2201450d0a0b200820093602840120082001360280010b200120046a2201200241106a290000370000200141186a200241286a290000370000200141106a200241206a290000370000200141086a200241186a2900003700002008200441206a36028801200820023602b003200841b0036a20084180016a10e501200241306a2102200341506a22030d000b0b2022201f41d0006a221f470d000b0b024002400240024002400240202741024b0d0020270e03010203010b2008280288012102200828028401210120082802800121040c040b410021050c020b410121050c010b410221050b200820053a00b0030240024020082802840122012008280288012202460d0020082802800121040c010b200241016a22042002490d03200241017422012004200120044b1b22014100480d030240024020020d0041002102024020010d00410121040c020b200110272204450d080c010b200828028001210420022001460d00200420022001102b2204450d070b200820013602840120082004360280010b200420026a20053a00002008200241016a2202360288010b20084180036aad4280808080800484221b2002ad4220862004ad84100302402001450d00200410290b02402023450d00201c10290b02402024450d00202441d0006c2104202641c4006a21020340024020022802002201450d00200141306c450d002002417c6a28020010290b200241d0006a2102200441b07f6a22040d000b0b02402029450d00202941d0006c450d00202610290b20084180016a41286a2205200841c0026a41286a29030037030020084180016a41206a2203200841c0026a41206a29030037030020084180016a41186a2209200841c0026a41186a29030037030020084180016a41106a221c200841c0026a41106a29030037030020084180016a41086a2204200841c0026a41086a290300370300200820082903c00237038001200841a0036a41086a22024200370300200842003703a00341eebec500ad4280808080f0008410012201290000211d200841b0036a41086a221f200141086a2900003703002008201d3703b003200110292002201f290300370300200820082903b0033703a00341d0ffc100ad4280808080b0018410012201290000211d2001290008211e2001102920084180036a41086a20022903003703002008201e370398032008201d37039003200820082903a00337038003413010272202450d002002200829038001370000200241286a2005290300370000200241206a2003290300370000200241186a2009290300370000200241106a201c290300370000200241086a2004290300370000201b2002ad428080808080068410032002102920084189016a20082d005f3a0000200441053a0000200841043a00800120084180016a10cb01200041106a427f4200427f427f427f2006ad42c0fc157e2007ad42ffff038342f0b9267e7c417f417f417f417f417f417f417f417f417f417f417f417f417f417f417f201a20196a22022002201a491b220220186a220420042002491b220220176a220420042002491b220220166a220420042002491b220220156a220420042002491b220220146a220420042002491b220220136a220420042002491b220220126a220420042002491b220220116a220420042002491b220220106a220420042002491b2202200f6a220420042002491b2202200e6a220420042002491b2202200d6a220420042002491b2202200c6a220420042002491b2202200b6a220420042002491b2202ad221b4280b0e32d7e7c200aad221d4280a4e8037e7c201b42c0f0f50b7e7c428084afdf007c221b417f417f417f417f417f417f417f417f417f417f417f417f417f417f201a417f201920196a220420042019491b6a22042004201a491b2204417f2018ad42037e221ea7201e422088a71b6a220120012004491b2204417f2017410274201741ffffffff03712017471b6a220120012004491b2204417f2016ad42057e221ea7201e422088a71b6a220120012004491b2204417f2015ad42067e221ea7201e422088a71b6a220120012004491b2204417f2014ad42077e221ea7201e422088a71b6a220120012004491b2204417f2013410374201341ffffffff01712013471b6a220120012004491b2204417f2012ad42097e221ea7201e422088a71b6a220120012004491b2204417f2011ad420a7e221ea7201e422088a71b6a220120012004491b2204417f2010ad420b7e221ea7201e422088a71b6a220120012004491b2204417f200fad420c7e221ea7201e422088a71b6a220120012004491b2204417f200ead420d7e221ea7201e422088a71b6a220120012004491b2204417f200dad420e7e221ea7201e422088a71b6a220120012004491b2204417f200cad420f7e221ea7201e422088a71b6a220120012004491bad42c0f0f50b7e221e7c22302030201b541b221b2002200a6aad4280e1eb177e7c22302030201b541b221b42c0f4a4eb007c22302030201b541b221b201e7d221e201e201b561b221b201d42c0f0f50b7e7c221d201d201b541b370300200042013703082000420037030002402021450d002021412c6c21042031210203400240200241046a2802002200450d00200041306c450d00200228020010290b2002412c6a2102200441546a22040d000b0b02402020450d002020412c6c450d00203110290b0240202841ffffff3f71450d00202510290b200828026441ffffff3f71450d08200828026010290c080b1039000b1032000b202010290b0240202b450d00202b412c6c2104202a210203400240200241046a2802002200450d00200041226c450d00200228020010290b2002412c6a2102200441546a22040d000b0b202f450d02202f412c6c450d02202a10290c020b1030000b1038000b0240202841ffffff3f71450d00202510290b02402023450d00201c10290b200828026441ffffff3f71450d01200828026010290c010b20021087020b200841c0036a24000bb00305037f017e017f077e017f230041e0006b220124002001200010a802200141106a200128020022022001280208220310a9020240024020012903104201510d004200210441002105420021064200210742002108420021094200210a4200210b4200210c4100210d0c010b200141206a290300210c200141306a290300210a200141286a2903002109200141c0006a2903002108200141386a2903002107200141d0006a2903002106200141c8006a2903002104200141d8006a28020021052001290318210b20012d005c210d0b0240410410272200450d0020002005360000200041044108102b2200450d0020004100200d411874220541808080786a220d200d20054b1b4118763a0004200041084115102b2200450d002000200b3700052000410d6a200c37000020004115412a102b2200450d00200020093700152000411d6a200a3700002000412a41d400102b2200450d0020002004370035200020073700252000413d6a20063700002000412d6a20083700002003ad4220862002ad842000ad4280808080d0088410032000102902402001280204450d00200210290b200141e0006a24000f0b1030000bd60c06047f027e027f067e037f067e23004180036b22042400200328020021052004200110a80220044180016a200428020022062004280208220710a9022004290380012108420021092004420037038001200441c8016a280200210a20042d00cc01210b02400240200842015122030d00200441106a41306a4200370300200441106a41286a4200370300200441106a41206a4200370300200441106a41186a4200370300200441206a4200370300200441186a4200370300200442003703104200210c4200210d4200210e4200210f0c010b200441b8016a290300211020044180016a41306a290300211120044180016a41206a290300210c20044180016a41186a2903002109200441c0016a290300210f200429039001210e200429038801210d200441106a41206a20044180016a41286a290300370300200441106a41286a2011370300200441106a41306a2010370300200441206a20093703002004200c3703282004200d3703102004200e3703180b02400240024002400240427f200d20097c22092009200d542212200e200c7c2012ad7c2209200e542009200e511b22121b427f200920121b8450450d0041a5e2c200ad4280808080b00184210e41838c1c21120c010b200d200229030022107c2209200d542212200e200241086a29030022117c2012ad7c220d200e54200d200e511b4101470d0141839dc500ad4280808080800184210e41838c0821120b200e4280807c832108200e42088842ff0183210c200ea72103410121020c010b200420093703102004200d370318200441c8006a41186a200441206a220241086a290300220e370300200441c8006a41206a2212200241106a290300370300200441f0006a2213200241186a290300370300200441f8006a2214200241206a2903003703002004200d3703502004200937034820042002290300220c37035802400240427f2009200c7c220c200c2009542202200d200e7c2002ad7c220e200d54200e200d511b22021b220c4280c8afa025544100427f200e20021b220e501b0d00200441c8006a41106a2903002115201429030021162013290300210e2012290300210c2004290350211720042903482118420121192004290360211a0c010b420021190240200c200e84500d00200c200e10d402200441b8026a200e370300200441b0026a200c37030020044180026a41086a41013a000020044189026a200529000037000020044191026a200541086a29000037000020044199026a200541106a290000370000200441a1026a200541186a290000370000200441033a00800220044180026a10cb010b0b200441a8016a200c370300200441b0016a200e37030020044190016a2017370300200441b8016a201637030020044198016a20153703002004201a3703a0012004200f3703c0012004201837038801410021022004200b4100200842015122121b22053a00cc012004200a410020121b220a3602c801200420194201512212ad37038001024020120d002007ad4220862006ad8410044200210c420021080c010b410410272212450d012012200a360000201241044108102b2212450d01201220053a0004201241084115102b2212450d01201220183700052012410d6a2017370000200441a0016a290300210820044198016a290300210f20124115412a102b2212450d012012200f3700152012411d6a20083700002012412a41d400102b2212450d012012200c3700252012412d6a200e3700002012413d6a200441c0016a2903003700002012200441b8016a2903003700352007ad4220862006ad842012ad4280808080d00884100320121029420021084201210c0b02402004280204450d00200610290b024002402002450d0020002012360204200041086a200c4208862003ad42ff018384200884370200410121010c010b024002400240200341ff017122030d00200c4200510d004103210220044180026a21030c010b2003450d01200c4200520d014104210220044180016a21030b200341086a20023a0000200341003a0000200341096a2001290000370000200341116a200141086a290000370000200341196a200141106a290000370000200341216a200141186a290000370000200310cb010b200041286a2011370300200041206a2010370300200041186a200d370300200041106a2009370300200041086a4200370300410021010b2000200136020020044180036a24000f0b1030000bc90c06047f017e017f017e047f0a7e23004190016b22032400200341386a41186a22044200370300200341386a41106a22054200370300200341386a41086a220642003703002003420037033841eebec500ad4280808080f000842207100122082900002109200341d8006a41086a220a200841086a29000037030020032009370358200810292006200a2903003703002003200329035837033841eab8c000ad4280808080900284100122082900002109200a200841086a2900003703002003200937035820081029200520032903582209370300200341186a41086a220b2006290300370300200341186a41106a220c2009370300200341186a41186a220d200a29030037030020032003290338370318200341106a200341186a10b1010240024002402003280210417d71450d00200442003703002005420037030020064200370300200342003703382007100122082900002109200a200841086a29000037030020032009370358200810292006200a2903003703002003200329035837033841c4f5c100ad4280808080a00184100122082900002109200a200841086a290000370300200320093703582008102920052003290358370000200541086a200a290300370000200b2006290300370300200c2005290300370300200d200429030037030020032003290338370318200341086a200341186a412010fc0120032802084101470d01200328020c2002460d012000410f3a001a2000420137030820004201370300200041206a41173602002000411c6a41f9b2c000360200200041186a4183123b0100200041106a4280e1eb173703000c020b2000410f3a001a2000420137030820004201370300200041206a41173602002000411c6a41f9b2c000360200200041186a4183123b0100200041106a42c0f0f50b3703000c010b42002109200341386a41186a22044200370300200341386a41106a220b4200370300200341386a41086a220642003703002003420037033841eebec500ad4280808080f00084100122082900002107200341d8006a41086a220a200841086a29000037030020032007370358200810292006200a2903003703002003200329035837033841d0ffc100ad4280808080b00184100122082900002107200a200841086a290000370300200320073703582008102920052003290358370000200541086a200a290300370000200341186a41086a2006290300370300200341186a41106a200b290300370300200341186a41186a2004290300370300200320032903383703182003412036026c2003200341186a360268200341f0006a200341186aad42808080808004841007108b02024002402003280270220a0d000c010b20032802742105024002400240200341f0006a41086a28020022064110490d00200641707122064110460d0020064120470d010b20034100360260200342013703582003410d360284012003200341e8006a360280012003200341d8006a36028c01200341cc006a41013602002003420137023c200341f4eaca00360238200320034180016a3602482003418c016a41a8a3c800200341386a10371a200335026042208620033502588410080240200328025c450d00200328025810290b420021090c010b200a41086a290000210e200a290000210f200a41286a2900002107200a41186a2900002110200a2900202111200a2900102112420121090b2005450d00200a10290b0240024002402009500d00200141286a2903002109200141186a2903002113200141086a290300211420012903202115200129031021162001290300211741031027220a450d01200a417f20152011852009200785844200522015201154200920075420092007511b22081b3a0002200a417f20162012852013201085844200522016201254201320105420132010511b1b22063a0001200a417f2017200f852014200e85844200522017200f542014200e542014200e511b1b22053a000002400240200541014b0d000240024020050e020001000b200641014b0d0120060e020200020b200a10290c020b200a10290c030b200a10292008450d020b20004200370300200041086a42003703000c020b1030000b200041103a001a2000420137030820004201370300200041206a41163602002000411c6a41e3b2c000360200200041186a4183123b0100200041106a42c0d1e1233703000b20034190016a24000bf6c8010e077f017e057f017e0b7f017e037f017e017f017e017f017e017f017e230041d0016b220424002004200336020c20044100360218200442043703102001280204210520012802002106024002400240024002400240024002400240024020012802082203450d0020034103742107200441b0016a41106a2108200441b0016a41176a21092006210a03402002280208200a290200220ba722034d0d07200441b0016a41086a220c200228020020034105746a220341096a2900003703002008200341116a2900003703002009200341186a290000370000200420032900013703b00120032d0000210d412210272203450d02200428020c220e280208200b422088a741ffff0371220f4d0d06200441c0006a41106a2210200e280200200f4105746a220e41116a290000370300200441c0006a41176a220f200e41186a290000370000200441c0006a41086a200e41096a2900002211370300200e290001210b2003200e2d00003a00002003200b370001200341096a2011370000200341ffff033b0120200341116a2010290300370000200341186a200f2900003700002004200b37034020044190016a41176a220f200929000037000020044190016a41106a2210200829030037030020044190016a41086a2212200c290300370300200420042903b0013703900102402004280218220e2004280214470d00200441106a200e41011093012004280218210e0b200a41086a210a2004280210200e412c6c6a220e200d3a000c200e428180808010370204200e2003360200200e410d6a200429039001370000200e41156a2012290300370000200e411d6a2010290300370000200e41246a200f2900003700002004200428021841016a360218200741786a22070d000b0b0240200541ffffffff0171450d00200610290b200128020c2113200141106a2802002114200141146a2802002203450d0320132003410c6c6a211520044190016a41106a210720044190016a41176a210c2013210a034002400240200a41066a2f0100220841ffff03460d002002280208200a28020022034b0d0120004181043b01000c050b200041013b01000c040b200a41086a2f01002109200a41046a2f0100210e20044190016a41086a2210200228020020034105746a220341096a2900003703002007200341116a290000370300200c200341186a290000370000200420032900013703900120032d0000211241c40010272203450d01200428020c220d280208220f200e4d0d02200441b0016a41086a2206200d280200220d200e4105746a220e41096a290000370300200441b0016a41106a2205200e41116a290000370300200441b0016a41176a2216200e41186a2900003700002004200e2900013703b0010240200f20094d0d00200e2d0000210f200441c0006a41086a2217200d20094105746a220e41096a290000370300200441c0006a41106a2209200e41116a290000370300200441c0006a41176a220d200e41186a290000370000200e290001210b200e2d0000210e2003200f3a0000200320042903b001370001200341096a2006290300370000200341116a2005290300370000200341186a20162900003700002003200e3a0022200320083b01202004200b370340200320042903403700232003412b6a2017290300370000200341336a20092903003700002003413a6a200d29000037000020032008417f733b0142200441206a41176a2208200c290000370000200441206a41106a22092007290300370300200441206a41086a220d2010290300370300200420042903900137032002402004280218220e2004280214470d00200441106a200e41011093012004280218210e0b2004280210200e412c6c6a220e20123a000c200e428280808020370204200e2003360200200e410d6a2004290320370000200e41156a200d290300370000200e411d6a2009290300370000200e41246a20082900003700002004200428021841016a360218200a410c6a220a2015470d010c050b0b20004181043b0100200310290c020b1030000b20004181043b0100200310290b4100210641012102200441106a210802402014450d002014410c6c450d00201310290b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f4101211041012112410121140c040b02402014450d002014410c6c450d00201310290b200128021821172001411c6a28020021150240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141206a2802002203450d00201720034104746a2116200441c0006a41086a210e200441c0006a41106a210a200441c0006a41176a2108201721090240024003402009410c6a2f0100210c2009280200210d2004200941046a290200220b3703800102400240200428020c2203280208200ba741ffff037122074d0d00200e200328020020074105746a220341096a290000370300200a200341116a2900003703002008200341186a2900003700002004200329000137034020032d00002107412210272203450d06200320073a0000200320042903403700012003200b421088a722123b0120200341096a200e290300370000200341116a200a290300370000200341186a20082900003700002004428180808010370294012004200336029001200428020c220f28020820042f01840122104b0d0141000d004122450d00200310290b20004181043b01000c3a0b20042f0186012107200441b0016a41176a2206200f28020020104105746a220341186a290000370000200441b0016a41106a2210200341116a290000370300200441b0016a41086a220f200341096a290000220b3703002004200329000122113703b00120032d0000210520082006290000370000200a2010290300370300200e200b3703002004201137034020044190016a4101410110a601200428029001220320053a0022200341236a20042903403700002003412b6a200e290300370000200341336a200a2903003700002003413a6a2008290000370000200341c2006a20073b01002004410236022820042004280294012210360224200420033602200240417f2012411074221220074110746a220720072012491b411076220741ffff03470d00200041013b01000c030b200428020c2212280208200c4d0d012007417f732106200e2012280200200c4105746a220741096a290000370300200a200741116a2900003703002008200741186a290000370000200420072900013703404102210c20072d00002107024020104102470d00200441206a4102410110a601200428022021032004280228210c0b2003200c41226c6a220320073a000020032004290340370001200320063b0120200341096a200e290300370000200341116a200a290300370000200341186a20082900003700002004200428022841016a36022802402002280208200d4d0d0020022802002103200f200441206a41086a280200360200200e2003200d4105746a220341096a290000370300200a200341116a2900003703002008200341186a290000370000200420042903203703b0012004200329000137034020032d000021070240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a220320042903b001370200200320073a000c200341086a200f2802003602002003410d6a2004290340370000200341156a200e2903003700002003411d6a200a290300370000200341246a20082900003700002004200428021841016a360218200941106a22092016470d010c040b0b20004181043b0100200428022421100c010b20004181043b01000b2010450d36201041226c450d36200428022010290c360b0240201541ffffffff0071450d00201710290b20012802242118200141286a280200211902402001412c6a2802002203450d002018200341146c6a211a2004418a016a211b20044180016a41086a211c200441c0006a41106a2107200441c0006a41176a210c20182115024002400240034020152f01102114201528020021132015290104210b201c2015410c6a2801003602002004200b3703800102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f018201210e200441c0006a41086a220d2003280200200a4105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d0000210341221027220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200d290300370000200f41116a2007290300370000200f41186a200c2900003700002004428180808010370294012004200f360290010240200428020c220328020820042f018401220a4b0d00410221034101210a0c390b201541146a2115417f200e411074220e20042f01860122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201b21080340200c201629000037000020072005290300370300200d2012290300370300200420042903b0013703400240200e417f6a2003470d0020044190016a2003410110a601200428029001210f0b200f200a6a220941606a20173a0000200941616a22032004290340370000200c290000210b20072903002111200d290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e360298010240200a41e400470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d0000211720042802940121030c000b0b410221030c380b200428029401210a20034103470d362004200e3602282004200a3602242004200f3602200240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200d200328020020144105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d000021090240200a200e470d00200441206a200e410110a6012004280220210f2004280228210e0b200f200e41226c6a220320093a000020032004290340370001200c290000210b20072903002111200d290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b3700002004200428022841016a360228200228020820134d0d03200228020021032012200441206a41086a280200360200200d200320134105746a220341096a2900003703002007200341116a290000370300200c200341186a290000370000200420042903203703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200d2903003700002003411d6a2007290300370000200341246a200c2900003700002004200428021841016a3602182015201a470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b01002004280224210a0b200a450d34200a41226c450d34200428022010290c340b02402019450d00201941146c450d00201810290b20012802302118200141346a28020021190240200141386a2802002203450d002018200341186c6a211a2004419a016a211b20044190016a41086a211c200441c0006a41106a2107200441c0006a41176a210c20182115024002400240034020152f01142114201528020021132015290104210b201c2015410c6a2901003703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220d2003280200200a4105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d0000210341221027220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200d290300370000200f41116a2007290300370000200f41186a200c29000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c350b201541186a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201b21080340200c201629000037000020072005290300370300200d2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a22032004290340370000200c290000210b20072903002111200d290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a418601470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c340b2004280224210a20034103470d322004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200d200328020020144105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a000020032004290340370001200c290000210b20072903002111200d290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200d200320134105746a220341096a2900003703002007200341116a290000370300200c200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200d2903003700002003411d6a2007290300370000200341246a200c2900003700002004200428021841016a3602182015201a470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d30200a41226c450d3020042802800110290c300b02402019450d00201941186c450d00201810290b200128023c2119200141c0006a280200211e0240200141c4006a2802002203450d0020192003411c6c6a21182004419a016a211a20044190016a41106a211c20044190016a41086a211b200441c0006a41176a210720192115024002400240034020152f01182114201528020021132015410c6a29010021112015290104210b201c201541146a280100360200201b20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221027220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c310b2015411c6a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201a2108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41a801470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c300b2004280224210a20034103470d2e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152018470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d2c200a41226c450d2c20042802800110290c2c0b0240201e450d00201e411c6c450d00201910290b20012802482119200141cc006a280200211e0240200141d0006a2802002203450d00201920034105746a21182004419a016a211a20044190016a41106a211c20044190016a41086a211b200441c0006a41176a210720192115024002400240034020152f011c2114201528020021132015410c6a29010021112015290104210b201c201541146a290100370300201b20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221027220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c2d0b201541206a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201a2108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41ca01470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c2c0b2004280224210a20034103470d2a2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152018470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d28200a41226c450d2820042802800110290c280b0240201e41ffffff3f71450d00201910290b2001280254211f200141d8006a280200211e0240200141dc006a2802002203450d00201f200341246c6a21192004419a016a211820044190016a41186a211c20044190016a41106a211b20044190016a41086a211a200441c0006a41176a2107201f2115024002400240034020152f01202114201528020021132015410c6a2901002111201541146a290100211d2015290104210b201c2015411c6a280100360200201b201d370300201a20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221027220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c290b201541246a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e20182108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41ec01470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c280b2004280224210a20034103470d262004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152019470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d24200a41226c450d2420042802800110290c240b0240201e450d00201e41246c450d00201f10290b2001280260211f200141e4006a280200211e0240200141e8006a2802002203450d00201f200341286c6a2119200441ca006a2118200441c0006a41186a211c200441c0006a41106a211b200441c0006a41086a211a200441b0016a41176a2107201f2115024002400240034020152f01242114201528020021132015410c6a2901002111201541146a290100211d2015290104210b201c2015411c6a290100370300201b201d370300201a20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221027220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c250b201541286a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20182108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a418e02470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c240b2004280224210a20034103470d222004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152019470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d20200a41226c450d2020042802800110290c200b0240201e450d00201e41286c450d00201f10290b200128026c211f200141f0006a28020021200240200141f4006a2802002203450d00201f2003412c6c6a211e200441ca006a2119200441e0006a211c200441c0006a41186a211b200441c0006a41106a211a200441c0006a41086a2118200441b0016a41176a2107201f2115024002400240034020152f01282114201528020021132015410c6a2901002111201541146a290100211d2015411c6a29010021212015290104210b201c201541246a280100360200201b2021370300201a201d370300201820113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221027220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c210b2015412c6a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20192108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41b002470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c200b2004280224210a20034103470d1e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201e470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d1c200a41226c450d1c20042802800110290c1c0b02402020450d002020412c6c450d00201f10290b20012802782120200141fc006a280200211f024020014180016a2802002203450d002020200341306c6a211e200441ca006a2119200441e0006a211c200441c0006a41186a211b200441c0006a41106a211a200441c0006a41086a2118200441b0016a41176a210720202115024002400240034020152f012c2114201528020021132015410c6a2901002111201541146a290100211d2015411c6a29010021212015290104210b201c201541246a290100370300201b2021370300201a201d370300201820113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221027220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c1d0b201541306a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20192108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41d202470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c1c0b2004280224210a20034103470d1a2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201e470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d18200a41226c450d1820042802800110290c180b0240201f450d00201f41306c450d00202010290b200128028401212020014188016a280200212202402001418c016a2802002203450d002020200341346c6a211f200441ca006a211e200441e8006a211c200441e0006a211b200441c0006a41186a211a200441c0006a41106a2118200441c0006a41086a2119200441b0016a41176a210720202115024002400240034020152f01302114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015290104210b201c2015412c6a280100360200201b2023370300201a20213703002018201d370300201920113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221027220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c190b201541346a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201e2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41f402470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c180b2004280224210a20034103470d162004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201f470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d14200a41226c450d1420042802800110290c140b02402022450d00202241346c450d00202010290b200128029001212020014194016a2802002122024020014198016a2802002203450d002020200341386c6a211f200441ca006a211e200441e8006a211c200441e0006a211b200441c0006a41186a211a200441c0006a41106a2118200441c0006a41086a2119200441b0016a41176a210720202115024002400240034020152f01342114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015290104210b201c2015412c6a290100370300201b2023370300201a20213703002018201d370300201920113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221027220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c150b201541386a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201e2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a419603470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c140b2004280224210a20034103470d122004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201f470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d10200a41226c450d1020042802800110290c100b02402022450d00202241386c450d00202010290b200128029c012124200141a0016a28020021220240200141a4016a2802002203450d0020242003413c6c6a2120200441ca006a211f200441f0006a211c200441e8006a211b200441e0006a211a200441c0006a41186a2118200441c0006a41106a2119200441c0006a41086a211e200441b0016a41176a210720242115024002400240034020152f01382114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015412c6a29010021252015290104210b201c201541346a280100360200201b2025370300201a2023370300201820213703002019201d370300201e20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221027220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c110b2015413c6a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201f2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41b803470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c100b2004280224210a20034103470d0e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152020470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d0c200a41226c450d0c20042802800110290c0c0b02402022450d002022413c6c450d00202410290b20012802a8012122200141ac016a28020021240240200141b0016a2802002203450d00202220034106746a2120200441ca006a211f200441f0006a211c200441e8006a211b200441e0006a211a200441c0006a41186a2118200441c0006a41106a2119200441c0006a41086a211e200441b0016a41176a210720222115024002400240034020152f013c2114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015412c6a29010021252015290104210b201c201541346a290100370300201b2025370300201a2023370300201820213703002019201d370300201e20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221027220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c0e0b201541c0006a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201f2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41da03470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c0d0b2004280224210a20034103470d0b2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152020470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d09200a41226c450d0920042802800110290c090b0240202441ffffff1f71450d00202210290b20012802b4012126200141b8016a2802002124200141bc016a2802002203450d022026200341c4006c6a2122200441ca006a2120200441f8006a211c200441f0006a211b200441e8006a211a200441e0006a2118200441c0006a41186a2119200441c0006a41106a211e200441c0006a41086a211f200441b0016a41176a21072026211502400240034020152f01402114201528020021132015410c6a290100210b201541146a29010021112015411c6a290100211d201541246a29010021212015412c6a2901002123201541346a290100212520152901042127201c2015413c6a280100360200201b2025370300201a2023370300201820213703002019201d370300201e2011370300201f200b3703002004202737034002400240200428020c220328020820042f0140220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221027220f450d05200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c090b201541c4006a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20202108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110a6012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41fc03470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c080b2004280224210a20034103470d062004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110a601200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109301200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152022470d010c060b0b200041013b01000c030b20004181043b01000c020b20004181043b0100200428028401210a0c010b1039000b200a450d03200a41226c450d0320042802800110290c030b02402024450d00202441c4006c450d00202610290b200041003a0000200041046a20042903103702002000410c6a200441186a2802003602000c370b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b41002102200441106a210802402024450d00202441c4006c450d00202610290b41002109410021050c060b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100210941012102200441106a21080240202441ffffff1f710d00410021050c040b20221029410021050c030b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100210541012102200441106a210802402022450d002022413c6c450d00202410290b410121090b410021160c030b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100211641012102200441106a210802402022450d00202241386c450d00202010290b41012109410121050b410021170c030b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100211741012102200441106a210802402022450d00202241346c450d00202010290b4101210941012105410121160b410021150c030b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100211541012102200441106a21080240201f450d00201f41306c450d00202010290b410121094101210541012116410121170b410021070c030b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100210741012102200441106a210802402020450d002020412c6c450d00201f10290b41012109410121054101211641012117410121150b4100210c0c030b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100210c41012102200441106a21080240201e450d00201e41286c450d00201f10290b4101210941012105410121164101211741012115410121070b410021000c030b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100210041012102200441106a21080240201e450d00201e41246c450d00201f10290b4101210941012105410121164101211741012115410121074101210c0b4100210d0c030b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100210d41012102200441106a21080240201e41ffffff3f71450d00201910290b4101210941012105410121164101211741012115410121074101210c410121000b4100210f0c030b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100210f41012102200441106a21080240201e450d00201e411c6c450d00201910290b4101210941012105410121164101211741012115410121074101210c410121004101210d0b410021100c030b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100211041012102200441106a210802402019450d00201941186c450d00201810290b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f0b410021120c030b200a450d00200a41226c450d00200f10290b200041013a0000200020033a00010b4100211241012102200441106a210802402019450d00201941146c450d00201810290b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f410121100b41002114410021060c040b4100211441012102200441106a21080240201541ffffffff0071450d00201710290b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f4101211041012112410021060c030b20004181043b0100200310290c010b20004181043b01000b41012102200441106a21080240200541ffffffff0171450d00200610290b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f410121104101211241012114410121060b02402004280218220e450d0020042802102103200e412c6c210e03400240200341046a280200220a450d00200a41226c450d00200328020010290b2003412c6a2103200e41546a220e0d000b0b0240200841046a2802002203450d002003412c6c450d00200828020010290b02402006450d00200141106a2802002203450d002003410c6c450d00200128020c10290b02402014450d002001411c6a28020041ffffffff0071450d00200128021810290b02402012450d00200141286a2802002203450d00200341146c450d00200128022410290b02402010450d00200141346a2802002203450d00200341186c450d00200128023010290b0240200f450d00200141c0006a2802002203450d002003411c6c450d00200128023c10290b0240200d450d00200141cc006a28020041ffffff3f71450d00200128024810290b02402000450d00200141d8006a2802002203450d00200341246c450d00200128025410290b0240200c450d00200141e4006a2802002203450d00200341286c450d00200128026010290b02402007450d00200141f0006a2802002203450d002003412c6c450d00200128026c10290b02402015450d00200141fc006a2802002203450d00200341306c450d00200128027810290b02402017450d0020014188016a2802002203450d00200341346c450d0020012802840110290b02402016450d0020014194016a2802002203450d00200341386c450d0020012802900110290b02402005450d00200141a0016a2802002203450d002003413c6c450d00200128029c0110290b02402009450d00200141ac016a28020041ffffff1f71450d0020012802a80110290b2002450d00200141b8016a2802002203450d00200341c4006c450d0020012802b40110290b200441d0016a24000bd30101017f230041106b22022400024002400240024020002d00000e03010200010b2002200128021841d993cc0041132001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c020b2002200128021841ec93cc0041142001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b20022001280218418094cc0041152001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040b200241106a240020000bb00401087f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d00200041023a00100c010b200328021421042003200341106a41086a28020036022420032001360220200341c8006a200341206a109602024002400240024020032802482205450d00200328024c2106024002400240200328022422024104490d00200341c8006a41086a280200210720032002417c6a220836022420032003280220220941046a220a3602202008450d012009280000210920032002417b6a3602242003200a41016a360220200a2d0000220a41014b0d0141002102200a0e020504050b200641ffffff3f710d010c020b200641ffffff3f71450d010b200510290b20034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b410221020c020b410121020b200341386a41026a200341286a41026a2d0000220a3a0000200341c8006a41026a200a3a0000200320032f002822083b01382000200936020c200020073602082000200636020420002005360200200320083b0148200041136a200a3a0000200020083b00110b200020023a00102004450d00200110290b200341e0006a24000bc70f080f7f017e087f017e027f037e047f057e230041d0026b22022400200141086a2802002103200128020421042000280204210520002802002106024020002802082207200028020c2208460d0020012802002109200241f0006a410c6a210a200241f0006a410472210b200241c8006a41086a210c200241c8006a41106a210d200241c8006a41186a210e200241c8006a41206a210f0340200c20072200410c6a290200370300200d200041146a290200370300200e2000411c6a290200370300200f200041246a290200370300200220002902043703482000412c6a210720002802002210450d01200b2002290348370200200b41086a200c290300370200200b41106a200d290300370200200b41186a200e290300370200200b41206a200f29030037020020022010360270200a10e1012111200241a0016a41086a2212200a41086a290200370300200241a0016a41106a2213200a41106a290200370300200241a0016a41186a2214200a41186a2902003703002002200a2902003703a00120022802742115024002400240200228027841226c2201450d00201021000340200041206a2f01002116200241b0026a41186a2217200041186a290000370300200241b0026a41106a2218200041106a290000370300200241b0026a41086a2219200041086a290000370300200220002900003703b00220160d02200041226a21002001415e6a22010d000b0b4200211a4108211b4100211c02402015450d00201541226c450d00201010294200211a0b4200211d410021000c010b200241386a2011420042ffff03420010e007200241286a2002290338221e200241386a41086a290300221f4281807c427f10d507200241186a201e201f2016ad420010d507200241d0016a41086a22202019290300370300200241d0016a41106a22212018290300370300200241d0016a41186a22222017290300370300200220022903b002221d3703f0012002201d3703d0012016200229032820117ca722236c221641ffff036e211c2002290318211d200241186a41086a29030021240240024041301027221b450d00201b201d201c417f20164180807c491b2016201c4181807c6c6a41ffff014b6aad42ffff03837c221a370320201b20022903d001370300201b41286a2024201a201d54ad7c221d370300201b41186a2022290300370300201b41106a2021290300370300201b41086a202029030037030020024281808080103702c4012002201b3602c001024020014122470d004101211c0c020b200141bc7f6a21214101211c410021160340200020166a220141c2006a2f0100212020172001413a6a2900003703002018200141326a29000037030020192001412a6a2900003703002002200141226a2900003703b0020240024020200d0020212016460d040c010b200241086a201e201f2020ad420010d507200241f0016a41086a20192903002224370300200241f0016a41106a20182903002225370300200241f0016a41186a20172903002226370300200220022903b00222273703f001201720263703002018202537030020192024370300200220273703b002201a20022903082225202020236c220141ffff036e2220417f20014180807c491b200120204181807c6c6a41ffff014b6aad42ffff03837c22247c2226201a542201201d200241086a41086a2903002024202554ad7c22257c2001ad7c221a201d54201a201d511b21010240201c20022802c401470d00200241c0016a201c410110900120022802c001211b0b427f201a20011b211d427f202620011b211a201b201c41306c6a220120022903b00237030020192903002126201829030021272017290300212820012024370320200141286a2025370300200141186a2028370300200141106a2027370300200141086a20263703002002201c41016a221c3602c80120212016460d030b201641226a21160c000b0b1039000b02402015450d00201541226c450d00201010290b20022802c40121000b024002402011201a7d22252011564200201d2011201a54ad7c7d22244200522024501b4101470d00201a20117d2224201a56201d201a201154ad7d2225201d56201a20115a1b0d01201c450d01201c41306c201b6a41706a220142002001290300221d20247d221a201a201d56200141086a2201290300221a20257d201d202454ad7d221d201a56201d201a511b22171b37030020014200201d20171b3703000c010b201c450d00201c41306c201b6a41706a2201427f2001290300221d20257c221a201a201d542217200141086a2201290300221d20247c2017ad7c221a201d54201a201d511b22171b3703002001427f201a20171b3703000b200241b0026a41186a22012014290300370300200241b0026a41106a22172013290300370300200241b0026a41086a22182012290300370300200220022903a0013703b002200920003602042009201c3602082009201b360200200920022903b00237020c200941146a20182903003702002009411c6a2017290300370200200941246a2001290300370200200341016a21032009412c6a210920072008470d000b200821070b20042003360200200820076b2200412c6d210102402000450d002001412c6c210003400240200741046a2802002201450d00200141226c450d00200728020010290b2007412c6a2107200041546a22000d000b0b02402005450d002005412c6c450d00200610290b200241d0026a24000b880303057f017e027f02400240024020002802202201450d00034020002001417f6a36022020002802042201450d0320002802082102200028020021030240200028020c220420012f0106490d00034002400240200128020022050d002002ad2106410021050c010b200341016a210320013301044220862002ad8421060b200110292006a72102200521012006422088a7220420052f01064f0d000b200521010b200441016a2107200120044105746a220541fc026a2802002104200541f8026a280200210802402003450d00200120074102746a41c8056a2802002101410021072003417f6a2205450d00034020012802c80521012005417f6a22050d000b0b2000200736020c2000200236020820002001360204200041003602002008450d0202402004450d00200441306c450d00200810290b200028022022010d000b0b200028020421010b02402001450d0020012802002105200110292005450d00034020052802002101200510292001210520010d000b0b0f0b41a79dc800412b41e0f6c4001033000bc00101037f230041106b2202240041012103200128021841acb9c40041012001411c6a28020028020c1100002104200241003a0005200220043a0004200220013602002002200036020c20022002410c6a41d0a3c800106321012002200041106a36020c20012002410c6a41d0a3c800106321012002200041206a36020c20012002410c6a41d0a3c80010631a024020022d00040d0020022802002200280218419cc9c00041012000411c6a28020028020c11000021030b200241106a240020030b13002000411f360204200041eca8c2003602000bff1001067f230041106b22022400024002400240024002400240024002400240024020012d00000e06010402030500010b2002410036020820024201370300410110272203450d082002410136020420022003360200200341003a000020024101360208200141046a28020021042001410c6a2802002201200210710240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d08200541017422072006200720064b1b22074100480d080240024020050d00024020070d00410121060c020b2007102722060d010c0b0b2002280200210620052007460d00200620052007102b2206450d0a0b20022007360204200220063602000b200620036a2004200110e4071a2002200320016a3602080c050b2002410036020820024201370300410110272203450d072002410136020420022003360200200341023a000020024101360208412010272203450d0520032001290001370000200341186a200141196a290000370000200341106a200141116a290000370000200341086a200141096a2900003700000240024020022802042206417f6a4120490d00200228020021010c010b200641017422014121200141214b1b22054100480d0720022802002101024020062005460d00200120062005102b2201450d090b20022005360204200220013602000b20012003290000370001200141196a200341186a290000370000200141116a200341106a290000370000200141096a200341086a29000037000020024121360208200310290c040b2002410036020820024201370300410110272203450d062002410136020420022003360200200341043a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0620022802002103024020062005460d00200320062005102b2203450d080b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210710240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d06200541017422072006200720064b1b22074100480d060240024020050d00024020070d00410121060c020b200710272206450d090c010b2002280200210620052007460d00200620052007102b2206450d080b20022007360204200220063602000b200620036a2004200110e4071a2002200320016a3602080c030b2002410036020820024201370300410110272203450d052002410136020420022003360200200341053a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0520022802002103024020062005460d00200320062005102b2203450d070b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210710240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d05200541017422072006200720064b1b22074100480d050240024020050d00024020070d00410121060c020b200710272206450d080c010b2002280200210620052007460d00200620052007102b2206450d070b20022007360204200220063602000b200620036a2004200110e4071a2002200320016a3602080c020b2002410036020820024201370300410110272203450d042002410136020420022003360200200341063a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0420022802002103024020062005460d00200320062005102b2203450d060b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210710240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d04200541017422072006200720064b1b22074100480d040240024020050d00024020070d00410121060c020b200710272206450d070c010b2002280200210620052007460d00200620052007102b2206450d060b20022007360204200220063602000b200620036a2004200110e4071a2002200320016a3602080c010b2002410036020820024201370300410110272203450d032002410136020420022003360200200341073a00002002410136020820022802002103024020022802044101470d00200341014102102b2203450d0420024102360204200220033602000b200341003a0001200241023602082002280200210320022802042106024020012802044101460d00024020064102470d00200341024104102b2203450d0520024104360204200220033602000b200341003a0002200241033602080c010b024020064102470d00200341024104102b2203450d0420024104360204200220033602000b200341013a000220024103360208200141086a28020021050240024020022802042206417d6a4104490d00200228020021030c010b200641017422034107200341074b1b22044100480d0320022802002103024020062004460d00200320062004102b2203450d050b20022004360204200220033602000b20032005360003200241073602082001410c6a2802002106024002402002280204220341796a4104490d00200228020021010c010b20034101742201410b2001410b4b1b22054100480d0320022802002101024020032005460d00200120032005102b2201450d050b20022005360204200220013602000b200120063600072002410b3602080b200020022201290200370200200041086a200141086a280200360200200241106a24000f0b1039000b1032000b1030000ba30f010c7f230041c0006b22022400024002400240024041c20310272203450d00200241c20336020420022003360200200341003b00002002410236020802400240200128020022032903684202520d00024020022802044102470d00200228020041024104102b2201450d0620024104360204200220013602000b200228020041043a00022002200228020841016a3602080c010b024020022802044102470d00200228020041024104102b2201450d0520024104360204200220013602000b20022802004184013a000220022002280208220141016a2204360208024002402002280204220520046b4120490d00200141216a210120022802002106200521070c010b200441206a22012004490d04200541017422062001200620014b1b22074100480d040240024020050d00024020070d00410121060c020b2007102722060d010c070b2002280200210620052007460d00200620052007102b2206450d060b20022007360204200220063602000b200620046a22042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a29000037000020022001360208024020032d0020220441024b0d000240024002400240024020040e03000102000b410021050c020b410121050c010b41022105200241023a001041c10021040c010b200220053a001041c00021040b024020072001470d00200141016a22072001490d05200141017422082007200820074b1b22074100480d050240024020010d0041002101024020070d00410121060c020b200710272206450d080c010b20012007460d00200620012007102b2206450d070b20022007360204200220063602000b200620016a20053a00002002200141016a2201360208024002402002280204220720016b2004490d00200228020021060c010b200120046a22062001490d05200741017422052006200520064b1b22054100480d050240024020070d00024020050d00410121060c020b200510272206450d080c010b2002280200210620072005460d00200620072005102b2206450d070b20022005360204200220063602000b200620016a200341216a200410e4071a2002200120046a3602080b200341e8006a200210be020b20034198016a200210bf0220022802082103410410272201450d0020024204370214200220013602102003417e6a200241106a10712002280208220341014d0d012002280218210120022802142108200220022802102205360224200241286a200520016a2206360200200241023602102002411c6a2002280200220441026a2207360200410021012002410036020820022003417e6a22033602142002200736021820022002360220200241246a21090240024002402003450d0020052103034020032006460d032002200341016a360224200420016a20032d00003a00002002200228020841016a36020820014101460d02200141016a210120022802242103200228022821060c000b0b2002200910c0020c010b024020022802282207200228022422036b2201450d00024002402002280220220441046a280200220a2002280214220b2002280210220c6a22066b2001490d00200428020021060c010b200620016a220d2006490d05200a4101742206200d2006200d4b1b220d4100480d0502400240200a0d000240200d0d00410121060c020b200d10272206450d080c010b20042802002106200a200d460d002006200a200d102b2206450d070b20042006360200200441046a200d3602000b2006200c20016a22016a2006200c6a200b10e5071a20022001360210200120042802082206460d00200620036a417f732007200c6a6a2101200428020020066a2106034020032007460d022002200341016a360224200620032d00003a00002004200428020841016a3602082001450d01200641016a21062001417f6a210120022802242103200228022821070c000b0b2002410036023820024201370330200241306a200910c002200228023421092002280230210c024020022802382203450d00024002402002280220220441046a28020022072002280214220a200228021022066a22016b2003490d00200428020021010c010b200120036a220b2001490d0520074101742201200b2001200b4b1b220b4100480d050240024020070d000240200b0d00410121010c020b200b10272201450d080c010b200428020021012007200b460d0020012007200b102b2201450d070b20042001360200200441046a200b3602000b2001200620036a22076a200120066a200a10e5071a20022007360210200720042802082201460d00200120066b2107200428020020016a2101200c210603402003450d01200120062d00003a00002004200428020841016a360208200641016a2106200141016a210120072003417f6a2203470d000b0b2009450d00200c10290b02402002280218200228021c2203460d00200220033602180b024020022802142203450d000240200228021022042002280220220741086a22062802002201460d002007280200220720016a200720046a200310e5071a0b2006200320016a3602000b02402008450d00200510290b20002002290300370200200041086a200241086a280200360200200241c0006a24000f0b1039000b410220031044000b1032000b1030000bb50103027f027e017f230041106b2202240020014180a6cc0041001072200041186a21030240024020002903004201520d002002200041106a29030020002903082204420c882205420120054201561b80a741047420047aa7417f6a22064101200641014b1b2206410f2006410f491b723b010c20012002410c6a410210720c010b200241003a000f20012002410f6a410110720b20002802282001107120022003360208200241086a200110e501200241106a24000bca6303057f017e017f230041206b220224000240024020002802002203411b4b0d00024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e1c000102030405060708090a0b0c0d0e0f101112131415161718191a1b000b200241003a00102001200241106a41011072200041086a280200417f6a220341094b0d1b024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a00042001200241046a4101107220022000410c6a2802003602102001200241106a410410720c240b200241013a00042001200241046a410110722000410c6a2802002103200041146a28020022002001107120012003200010720c230b200241023a00042001200241046a410110722002200041106a2903003703102001200241106a410810720c220b200241033a00042001200241046a410110722000410c6a2802002103200041146a28020022002001107120012003200010720c210b200241043a00042001200241046a410110722000410c6a2802002103200041146a28020022002001107120012003200010720c200b200241053a00042001200241046a4101107202402000410c6a2802004101460d00200241003a00042001200241046a410110720c200b200241013a00042001200241046a410110722002200041106a2802003602102001200241106a410410722002200041146a2802003602102001200241106a410410720c1f0b200241063a00042001200241046a410110722000410c6a2802002103200041146a2802002200200110712000450d1e2003200041186c6a2104034020032802002100200341086a28020022052001107120012000200510722003410c6a2802002100200341146a2802002205200110712001200020051072200341186a22032004470d000c1f0b0b200241073a00042001200241046a410110722000410c6a2802002103200041146a2802002200200110712000450d1d20032000410c6c6a2104034020032802002100200341086a28020022052001107120012000200510722003410c6a22032004470d000c1e0b0b200241083a00042001200241046a410110722000410c6a2802002103200041146a28020022052001107120012003200510722002200041186a2802003602102001200241106a410410720c1c0b200241093a00042001200241046a410110720c1b0b200241013a00102001200241106a4101107220002d0004417f6a220341034b0d1a024002400240024020030e0400010203000b200241003a00042001200241046a410110722002200041086a2802003602102001200241106a41041072024002402000410c6a2802004101460d00200241003a00042001200241046a410110720c010b200241013a00042001200241046a410110722002200041106a2802003602102001200241106a410410722002200041146a2802003602102001200241106a410410720b200220002d00053a00042001200241046a410110722000280218200110bf020c1d0b200241013a00042001200241046a410110722002200041086a2802003602102001200241106a4104107220022000410c6a2802003602102001200241106a410410720c1c0b200241023a00042001200241046a41011072200041086a2802002103200041106a28020022052001107120012003200510722002200041146a2802003602102001200241106a4104107202400240200041186a2802004101460d00200241003a00042001200241046a410110720c010b200241013a00042001200241046a4101107220022000411c6a2802003602102001200241106a410410722002200041206a2802003602102001200241106a410410720b200220002d00053a00042001200241046a410110722000280224200110bf020c1b0b200241033a00042001200241046a41011072200041086a2802002103200041106a28020022002001107120012003200010720c1a0b200241023a00102001200241106a41011072200110e4050c190b200241033a00102001200241106a41011072200241003a00102001200241106a41011072200041086a200110e5050c180b200241043a00102001200241106a4101107220002d0004417f6a220341034b0d17200041046a21050240024002400240024020030e0400010203000b200241003a00042001200241046a410110722002200041086a280200360210200241106a21000c030b200241013a00042001200241046a410110722001200541016a412010722002200041286a280200360210200241106a21000c020b200241023a00042001200241046a410110722002200041086a280200360210200241106a21000c010b200241033a00042001200241046a410110722001200541016a412010722002200041286a280200360210200241106a21000b20012000410410720c170b200241053a00102001200241106a41011072200041086a22032d0000417f6a220541034b0d160240024002400240024020050e0400010203000b200241003a00042001200241046a410110722001200341016a41201072200041306a2103200221000c030b200241013a00042001200241046a410110722001200341016a412010722002200041306a360204200241046a200110e501200041c0006a2103200241086a21000c020b200241023a00042001200241046a410110722001200341016a412010722001200341216a41201072200041d0006a21032002410c6a21000c010b200241033a00042001200241046a410110722001200341016a41201072200041306a2103200241106a21000b200020033602002000200110e5010c160b200241063a00102001200241106a41011072200241003a00102001200241106a41011072200028020421032000410c6a2802002200200110712000450d152003200041f0006c6a21060340412010272200450d1720002003290010370000200041186a200341286a290000370000200041106a200341206a290000370000200041086a200341186a2900003700002001200041201072200010292003200110e601412010272200450d1720002003290030370000200041186a200341c8006a290000370000200041106a200341c0006a290000370000200041086a200341386a290000370000200120004120107220001029412010272200450d17200341f0006a210420002003290050370000200041186a200341e8006a290000370000200041106a200341e0006a290000370000200041086a200341d8006a29000037000020012000412010722000102920032802042100200328020c22032001107102402003450d00200341246c21030340200241106a200010bc022001200228021022052002280218107202402002280214450d00200510290b200041246a21002003415c6a22030d000b0b2004210320042006470d000c160b0b200241073a00102001200241106a41011072200041086a22052d0000417f6a220341174b0d1402400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e18000102030405060708090a0b0c0d0e0f1011121314151617000b200241003a00102001200241106a410110722001200541016a412010722002200041306a360210200241106a200110e50120002d0029220041024b0d2b02400240024020000e03000102000b200241003a00102001200241106a410110720c2d0b200241013a00102001200241106a410110720c2c0b200241023a00102001200241106a410110720c2b0b200241013a00102001200241106a410110722002200041106a360210200241106a200110e5010c2a0b200241023a00102001200241106a410110722002200041106a360210200241106a200110e5010c290b200241033a00102001200241106a4101107220022000410c6a2802003602102001200241106a410410720c280b200241043a00102001200241106a410110720240024002402000410c6a280200220341c000490d00200341808001490d012003418080808004490d02200241033a00042001200241046a410110722002200028020c3602102001200241106a410410720c2a0b200220034102743a00042001200241046a410110720c290b200220034102744101723b01102001200241106a410210720c280b200220034102744102723602102001200241106a410410720c270b200241053a00102001200241106a410110722000410c6a2802002103200041146a2802002200200110712000450d262000410574210003402001200341201072200341206a2103200041606a22000d000c270b0b200241063a00102001200241106a410110720c250b200241073a00102001200241106a4101107220052d0001220041024b0d2402400240024020000e03000102000b200241003a00102001200241106a410110720c260b200241013a00102001200241106a410110720c250b200241023a00102001200241106a410110720c240b200241083a00102001200241106a410110722001200541016a412010720c230b200241093a00102001200241106a410110722000410c6a200110e6010c220b2002410a3a00102001200241106a410110720c210b2002410b3a00102001200241106a410110720c200b2002410c3a00102001200241106a410110722000410c6a2802002103200041146a2802002200200110712000450d1f2000410574210003402001200341201072200341206a2103200041606a22000d000c200b0b2002410d3a00102001200241106a410110722001200541016a4120107220022000412c6a2802003602102001200241106a410410720c1e0b2002410e3a00102001200241106a410110720c1d0b2002410f3a00102001200241106a4101107220022000410c6a2802003602102001200241106a41041072200041106a2802002103200041186a28020022002001107120012003200041027410720c1c0b200241103a00102001200241106a4101107220022000410c6a2802003602102001200241106a41041072200041106a2802002103200041186a2802002200200110712000450d1b2003200041246c6a2100034020012003412010722002200341206a2802003602102001200241106a410410722000200341246a2203470d000c1c0b0b200241113a00102001200241106a4101107220022000410c6a2802003602102001200241106a410410720c1a0b200241123a00102001200241106a410110722001200541016a4120107220022000412c6a2802003602102001200241106a410410720c190b200241133a00102001200241106a410110722002200041106a360210200241106a200110e5010c180b200241143a00102001200241106a410110722000410c6a200110e601200041106a200110e6010c170b200241153a00102001200241106a410110722001200541016a4120107220022000412c6a2802003602102001200241106a410410720c160b200241163a00102001200241106a410110722000410c6a2802002103200041146a2802002205200110712001200320054101741072200041186a20011085022001200041e8016a413010722002200041d8016a2802003602102001200241106a41041072200041dc016a210302400240200041e0016a2f0100220041c000490d00200041808001490d01200220004102744102723602102001200241106a410410722003200110e6010c170b200220004102743a00102001200241106a410110722003200110e6010c160b200220004102744101723b01102001200241106a410210722003200110e6010c150b200241173a00102001200241106a410110722000410c6a2802002103200041146a2802002205200110712001200320054101741072200041186a20011085022001200041e8016a413010722002200041d8016a2802003602102001200241106a41041072200041dc016a210302400240200041e0016a2f0100220041c000490d00200041808001490d01200220004102744102723602102001200241106a410410722003200110e6010c160b200220004102743a00102001200241106a410110722003200110e6010c150b200220004102744101723b01102001200241106a410210722003200110e6010c140b200241083a00102001200241106a41011072200110e4050c130b200241093a00102001200241106a4101107202402000280204450d00200241003a00042001200241046a410110722001200041106a412010722001200041306a412010722001200041d0006a412010722001200041f0006a41201072200120004190016a41201072200028020421032000410c6a28020022002001107120012003200010720c130b200241013a00042001200241046a410110720c120b2002410a3a00102001200241106a41011072200241003a00102001200241106a41011072200041046a200110e6010c110b2002410b3a00102001200241106a41011072200241003a00102001200241106a410110722002200041086a2903003703102001200241106a4108107202400240200041106a2903004201510d00200241003a00042001200241046a41011072200220002903183703102001200241106a410810722001200041e8016a41201072200041206a200110e60520004184016a200110e6050c010b200241013a00042001200241046a41011072200220002903183703102001200241106a410810722001200041e8016a41201072200041206a200110e60520004184016a200110e6050b200220004188026a2802003602102001200241106a410410722000418c026a280200210320004194026a28020022052001107102402005450d0020032005410c6c6a2106034020032802002105200341086a28020022042001107120012005200410722003410c6a22032006470d000b0b200220004198026a2802003602102001200241106a410410720c100b2002410c3a00102001200241106a41011072200241003a00102001200241106a41011072200220002802043602102001200241106a41041072200041086a2802002103200041106a2802002205200110712001200320051072200041146a28020021032000411c6a28020022052001107102402005450d0020032005410c6c6a2106034020032802002105200341086a28020022042001107120012005200410722003410c6a22032006470d000b0b2002200041206a2802003602102001200241106a410410722002200041246a2802003602102001200241106a410410722002200041286a2802003602102001200241106a4104107220012000412c6a41c00010720c0f0b2002410d3a00102001200241106a41011072200110e4050c0e0b2002410e3a00102001200241106a41011072200041086a22032d0000417f6a2205411e4b0d0d024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e1f000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e000b200241003a00102001200241106a41011072412010272205450d2c20052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a2900003700002001200541201072200510292002200041306a360210200241106a200110e5010c2b0b200241013a00102001200241106a410110722000410c6a200110e601200041106a200110e6010c2a0b200241023a00102001200241106a410110722000410c6a200110e601200041106a200110e7050c290b200241033a00102001200241106a410110722000410c6a200110e601200041106a200110e7050c280b200241043a00102001200241106a4101107220022000410c6a2802003602102001200241106a410410720c270b200241053a00102001200241106a41011072412010272200450d2720002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201072200010290c260b200241063a00102001200241106a41011072412010272200450d2620002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201072200010290c250b200241073a00102001200241106a41011072412010272200450d2520002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201072200010290c240b200241083a00102001200241106a41011072412010272205450d2420052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a29000037000020012005412010722005102920022000412c6a2802003602102001200241106a410410722002200041306a2802003602102001200241106a410410720c230b200241093a00102001200241106a41011072412010272200450d2320002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201072200010290c220b2002410a3a00102001200241106a410110722000410c6a200110e6010c210b2002410b3a00102001200241106a4101107220022000410c6a2802003602102001200241106a410410720c200b2002410c3a00102001200241106a410110722001200341016a412010720c1f0b2002410d3a00102001200241106a410110720c1e0b2002410e3a00102001200241106a410110722001200341016a412010720c1d0b2002410f3a00102001200241106a410110722001200341016a41201072024020002d0029220341064b0d000240024002400240024002400240024020030e0700010203040506000b200241003a00040c060b200241013a00040c050b200241023a00040c040b200241033a00040c030b200241043a00040c020b200241053a00040c010b200241063a00040b2001200241046a410110720b200029033021072002200041386a290300370318200220073703102001200241106a411010720c1c0b200241103a00102001200241106a410110720c1b0b200241113a00102001200241106a410110720c1a0b200241123a00102001200241106a410110722000410c6a2802002103200041146a28020022002001107120012003200010720c190b200241133a00102001200241106a410110722000410c6a2802002103200041146a28020022002001107120012003200010720c180b200241143a00102001200241106a410110722000410c6a2802002103200041146a28020022002001107120012003200010720c170b200241153a00102001200241106a410110722000410c6a2802002103200041146a28020022002001107120012003200010720c160b200241163a00102001200241106a41011072412010272205450d1620052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a2900003700002001200541201072200510292000412c6a200110e6010c150b200241173a00102001200241106a410110722001200341016a412010720c140b200241183a00102001200241106a410110722001200341016a412010720c130b200241193a00102001200241106a4101107220022000410c6a2802003602102001200241106a410410720c120b2002411a3a00102001200241106a410110722001200341016a4120107220022000412c6a2802003602102001200241106a410410720c110b2002411b3a00102001200241106a410110722001200341016a41201072024020002d0029220341064b0d000240024002400240024002400240024020030e0700010203040506000b200241003a00040c060b200241013a00040c050b200241023a00040c040b200241033a00040c030b200241043a00040c020b200241053a00040c010b200241063a00040b2001200241046a410110720b200029033021072002200041386a290300370318200220073703102001200241106a411010720c100b2002411c3a00102001200241106a410110720c0f0b2002411d3a00102001200241106a4101107220022000410c6a2802003602102001200241106a410410720c0e0b2002411e3a00102001200241106a41011072412010272205450d0e20052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a29000037000020012005412010722005102920022000412c6a2802003602102001200241106a410410720c0d0b2002410f3a00102001200241106a41011072200041086a200110e8050c0c0b200241103a00102001200241106a41011072200041086a200110e8050c0b0b200241113a00102001200241106a41011072200041086a22052d0000417f6a220341054b0d0a02400240024002400240024020030e06000102030405000b200241003a00042001200241046a410110722000410c6a2802002103200041146a280200220520011071200041186a210402402005450d002005410574210003402001200341201072200341206a2103200041606a22000d000b0b20022004360210200241106a200110e5010c0f0b200241013a00042001200241046a410110720c0e0b200241023a00042001200241046a410110722001200041146a412010722000410c6a200110e601200041106a200110e6010c0d0b200241033a00042001200241046a410110722000410c6a200110e6010c0c0b200241043a00042001200241046a410110722000410c6a280200220341024b0d0b02400240024020030e03000102000b200241003a00042001200241046a410110720c0d0b200241013a00042001200241046a410110720c0c0b200241023a00042001200241046a41011072200041106a200110e6010c0b0b200241053a00042001200241046a410110722001200541016a412010722002200541216a2d00003a00042001200241046a410110720c0a0b200241123a00102001200241106a4101107220002d0004417f6a220341064b0d09200041046a2105024002400240024002400240024020030e0700010203040506000b200241003a00042001200241046a410110722001200541016a412010720c0f0b200241013a00042001200241046a410110722001200541016a412010720c0e0b200241023a00042001200241046a410110722001200541016a412010722001200541216a412010720c0d0b200241033a00042001200241046a41011072200041086a2802002103200041106a2802002200200110712000450d0c2000410574210003402001200341201072200341206a2103200041606a22000d000c0d0b0b200241043a00042001200241046a410110722001200541016a412010720c0b0b200241053a00042001200241046a410110722001200541016a412010720c0a0b200241063a00042001200241046a410110720c090b200241133a00102001200241106a41011072200041086a22032d0000417f6a220541074b0d080240024002400240024002400240024020050e080001020304050607000b200241003a00042001200241046a410110722002200041306a360210200241106a200110e5012001200341016a412010720c0f0b200241013a00042001200241046a410110722000410c6a200110e6010c0e0b200241023a00042001200241046a410110722000410c6a200110e6010c0d0b200241033a00042001200241046a410110722000412c6a2802002105200041346a28020022002001107120012005200010722001200341016a412010720c0c0b200241043a00042001200241046a41011072412010272200450d0c20002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201072200010290c0b0b200241053a00042001200241046a410110722000412c6a2802002105200041346a28020022042001107120012005200410722001200341016a41201072200041386a29030021072002200041c0006a290300370318200220073703102001200241106a411010720c0a0b200241063a00042001200241046a41011072412010272205450d0a20052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a290000370000200120054120107220051029200041306a29030021072002200041386a290300370318200220073703102001200241106a411010720c090b200241073a00042001200241046a41011072412010272200450d0920002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201072200010290c080b200241143a00102001200241106a410110722000280204417f6a220341014b0d070240024020030e020001000b200241003a00102001200241106a41011072200041086a2802002103200041106a2802002200200110712000450d08200320004190026c6a2108034020032205200110a50420052802f801210020052802800222032001107102402003450d002000200341c1006c6a2103034020024102410120002d00004101461b3a00042001200241046a410110722001200041016a41c0001072200041c1006a22002003470d000b0b20054190026a2103200528028402210420054188026a28020022064103762200200110710240024020000d00410021050c010b410121052000410820064107716b22064d0d0041024101200020066b22004107711b20004103766a21050b200120042005107220032008470d000c090b0b200241013a00102001200241106a410110722001200041c0006a41201072200041e0006a200110a004200041c1016a200110a0042002200041086a2802003602102001200241106a410410722000410c6a2802002103200041146a28020022052001107102402005450d0020032005410c6c6a2106034020032802002105200341086a28020022042001107120012005200410722003410c6a22032006470d000b0b2002200041186a2802003602102001200241106a4104107220022000411c6a2802003602102001200241106a41041072412010272203450d08200341186a200041386a290000370000200341106a200041306a290000370000200341086a200041286a2900003700002003200041206a2900003700002001200341201072200310290c070b200241153a00102001200241106a41011072200241003a00102001200241106a410110720c060b200241163a00102001200241106a41011072200041086a22052d0000417f6a220341054b0d0502400240024002400240024020030e06000102030405000b200241003a00042001200241046a410110722000410c6a200110e601200041106a200110e6010c0a0b200241013a00042001200241046a410110722000410c6a200110e601200041106a200110e601200041146a200110e601200041186a200110e6012002200041206a360210200241106a200110e5010c090b200241023a00042001200241046a410110722000410c6a200110e601200041106a200110e601200041146a200110e6012002200041186a360210200241106a200110e5010c080b200241033a00042001200241046a410110722001200541016a412010720c070b200241043a00042001200241046a410110722000412c6a200110e601200041306a200110e601412010272203450d0720032005290001370000200341186a200541196a290000370000200341106a200541116a290000370000200341086a200541096a2900003700002001200341201072200310292002200041346a2802003602102001200241106a41041072200041386a2802002103200041c0006a28020022002001107120012003200010720c060b200241053a00042001200241046a410110722000410c6a200110e601200041106a2802002103200041186a28020022002001107120012003200010720c050b200241173a00102001200241106a4101107220002d0004417f6a220341064b0d04024002400240024002400240024020030e0700010203040506000b200241003a00042001200241046a41011072200041086a200110e601200220002d00054101463a00042001200241046a410110722000410c6a2802002103200041146a2802002205200110712001200320051072200041186a2802002103200041206a28020022002001107120012003200010720c0a0b200241013a00042001200241046a41011072200041086a200110e6010c090b200241023a00042001200241046a410110722002200041086a2802003602102001200241106a410410720c080b200241033a00042001200241046a41011072200041086a2802002103200041106a2802002205200110712001200320051072200041146a28020021032000411c6a28020022002001107120012003200010720c070b200241043a00042001200241046a41011072200041c8006a200110e6012001200041046a220341016a41201072412010272200450d07200041186a200341396a290000370000200041106a200341316a290000370000200041086a200341296a2900003700002000200341216a2900003700002001200041201072200010290c060b200241053a00042001200241046a410110720c050b200241063a00042001200241046a41011072200041086a200110e6010c040b200241183a00102001200241106a41011072200041086a22032d0000417f6a220541034b0d03024002400240024020050e0400010203000b200241003a00042001200241046a410110722001200341016a412010722001200341216a41c10010720c060b200241013a00042001200241046a410110722001200341016a41141072200041206a29030021072002200041286a290300370318200220073703102001200241106a4110107202400240200041306a2903004201510d00200241003a00042001200241046a410110720c010b200241013a00042001200241046a41011072200041386a29030021072002200041c0006a290300370318200220073703102001200241106a41101072200041c8006a29030021072002200041d0006a290300370318200220073703102001200241106a411010722002200041d8006a2802003602102001200241106a410410720b024020032d001522004102470d00200241003a00042001200241046a410110720c060b200241013a00042001200241046a41011072024020004101460d00200241003a00042001200241046a410110720c060b200241013a00042001200241046a410110720c050b200241023a00042001200241046a410110722001200341016a412010722001200341216a41c1001072200041ec006a2802002103200041f4006a28020022002001107120012003200010720c040b200241033a00042001200241046a410110722000410c6a2802002103200041146a28020022002001107120012003200010720c030b200241193a00102001200241106a41011072200041086a22052d0000417f6a220341024b0d0202400240024020030e03000102000b200241003a00042001200241046a410110720c040b200241013a00042001200241046a410110722001200541016a412010720c030b200241023a00042001200241046a410110722001200541016a41201072200041306a29030021072002200041386a290300370318200220073703102001200241106a41101072200041c0006a29030021072002200041c8006a290300370318200220073703102001200241106a411010722002200041d0006a2802003602102001200241106a410410720c020b2002411a3a00102001200241106a4101107220002d0004417f6a220341044b0d01200041046a21040240024002400240024020030e050001020304000b200241003a00042001200241046a41011072200041086a2802002103200041106a2802002200200110712000450d05200041a8026c210003402003200110bf02200341a8026a2103200041d87d6a22000d000c060b0b200241013a00042001200241046a41011072200220002f01063b01102001200241106a41021072200041086a280200200110bf020c040b200241023a00042001200241046a41011072200220002f01063b01102001200241106a41021072200041086a2802002103200041106a28020022052001107102402005450d002005410574210503402001200341201072200341206a2103200541606a22050d000b0b0240024020002802144101460d00200241003a00042001200241046a410110720c010b200241013a00042001200241046a410110722002200041186a2802003602102001200241106a4104107220022000411c6a2802003602102001200241106a410410720b2000280220200110bf020c030b200241033a00042001200241046a41011072200220002f01263b01102001200241106a41021072200041286a2802002103200041306a28020022052001107102402005450d002005410574210503402001200341201072200341206a2103200541606a22050d000b0b200441016a21030240024020002802344101460d00200241003a00042001200241046a410110720c010b200241013a00042001200241046a410110722002200041386a2802003602102001200241106a4104107220022000413c6a2802003602102001200241106a410410720b20012003412010720c020b200241043a00042001200241046a41011072200220002f01263b01102001200241106a41021072200041286a2802002103200041306a280200220520011071200441016a210402402005450d002005410574210503402001200341201072200341206a2103200541606a22050d000b0b200220002802343602102001200241106a410410722002200041386a2802003602102001200241106a4104107220012004412010720c010b2002411b3a00102001200241106a41011072200041086a22052d0000417f6a220341034b0d00024002400240024020030e0400010203000b200241003a00042001200241046a410110722000410c6a280200200110bf020c030b200241013a00042001200241046a410110722000410c6a280200200110bf022002200041106a2903003703102001200241106a410810720c020b200241023a00042001200241046a410110722001200541016a412010720c010b200241033a00042001200241046a410110722001200541016a412010722000412c6a280200200110bf020b200241206a24000f0b1039000bbc0201057f024002400240200041046a2802002202200041086a28020022036b20012802042204200128020022056b22064f0d00200320066a22052003490d01200241017422042005200420054b1b22054100480d010240024020020d00024020050d00410121040c020b2005102722040d010c040b2000280200210420022005460d00200420022005102b2204450d03200041086a28020021030b20002004360200200041046a200536020020012802002105200128020421040b024020052004460d00200028020021042001200541016a360200200420036a20052d00003a0000200341016a2103200128020022052001280204460d0003402001200541016a360200200420036a20052d00003a0000200341016a2103200128020022052001280204470d000b0b200041086a20033602000f0b1032000b1030000b9e06020a7f017e230041d0016b2202240041002103200241003a00c0012001280204417f6a2104024002400240024003402004417f460d01200241a0016a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c0012004417f6a21042005210320054120470d000b20024180016a41186a2204200241a0016a41186a220329030037030020024180016a41106a2205200241a0016a41106a220629030037030020024180016a41086a2207200241a0016a41086a2208290300370300200220022903a00137038001200241a0016a200110830220022802c0012209450d01200241c0006a41186a220a2004290300370300200241c0006a41106a220b2005290300370300200241c0006a41086a22052007290300370300200241c0006a41286a22072008290300370300200241c0006a41306a22082006290300370300200241c0006a41386a220620032903003703002002200229038001370340200220022903a001370360200241c4016a2802002104200241a0016a41286a290300210c200241086a2005290300370300200241106a200b290300370300200241186a200a290300370300200241206a22032002290360370300200241286a22052007290300370300200241306a22072008290300370300200241386a2208200629030037030020022002290340370300200241c0006a20011096022002280240450d02200241a0016a41086a2201200241c0006a41086a280200360200200220022903403703a001200041386a2008290300370300200041306a2007290300370300200041286a2005290300370300200041206a2003290300370300200041186a200241186a290300370300200041106a200241106a290300370300200041086a200241086a29030037030020002002290300370300200041c8006a200c3703002000200436024420002009360240200041d0006a20022903a001370300200041d8006a20012802003602000c030b200341ff0171450d00200241003a00c0010b200041003602400c010b200041003602402004450d00200441306c450d00200910290b200241d0016a24000bef07010a7f200220016b210341242104024002402000280200220541244b0d00200521060c010b2000410c6a2802002106200521040b024002400240024002400240024002400240024002400240200420066b2003490d00200521060c010b200620036a22042006490d0341002103024020044102490d00417f2004417f6a677621030b200341016a22062003490d034124210302400240200541244b0d00200041056a2107200521040c010b2000410c6a2802002104200041086a2802002107200521030b200420064b0d07024020064125490d0020032006470d03200521060c010b20054125490d01200041003a0004200041056a2007200410e4071a2000200436020020071029200028020021060b200641254f0d03200621050b200041056a210341242106200021070c040b02400240200541244b0d00200610272203450d0720032007200410e4071a0c010b200720032006102b2203450d060b200041013a0004200020063602002000410c6a22072004360200200041086a20033602000c020b41a4a1cc00411141b8a1cc001033000b2000410c6a22072802002104200041086a28020021030b200421050b0240200520064f0d00034020022001460d04200320056a20012d00003a0000200141016a21012006200541016a2205470d000b200621050b2007200536020020012002460d03200141016a2105200041056a21082000410c6a210920012d000021030340024002402000280200220641244b22070d0041242104200621010c010b20092802002101200621040b02400240024020012004470d000240024020070d004124210a200621040c010b200928020021042006210a0b200a2004470d0002400240200441016a220b2004490d004100210a0240200b4102490d00417f200b417f6a6776210a0b200a41016a2204200a490d000240024020070d004124210c2008210b2006210a0c010b200028020c210a2000280208210b2006210c0b200a20044b0d010240024020044125490d00200c2004470d010c040b20064125490d04200041003a00042008200b200a10e4071a2000200a360200200b1029200028020021060c030b0240024020070d00200410272206450d092006200b200a10e4071a0c010b200b200c2004102b2206450d080b2000200a36020c20002006360208200041013a000420002004360200200921040c040b41a4a1cc00411141b8a1cc001033000b41e6a1cc00412041b8a1cc001033000b20064125490d0020002802082106200921040c010b20002104200821060b2004200141016a360200200620016a20033a000020022005460d0420052d00002103200541016a21050c000b0b41e6a1cc00412041b8a1cc001033000b1030000b200720053602000b0b80520c017f017e017f027e017f017e037f017e027f017e017f037e230041d0076b2206240002400240024002400240024002400240024002400240200129032022074202520d0041808e082108024020012802500e1c05050505050605050505050505050606060606060206060605000505050b200141d8006a2d00004103460d050c040b200641b0036a41186a200141186a290000370300200641b0036a41106a200141106a290000370300200641b0036a41086a200141086a290000370300200620012900003703b003200141c0006a2903002109200141386a290300210a200141c8006a280200210b2001290328210c41808e0821080240024020012802500e1c03030303030403030303030303030404040404040104040403000303030b200141d8006a2d00004103460d030c020b200141d4006a2802004101460d010c020b200141d4006a2802004101460d020c030b10c402220841ff01714102470d0010c4021a10c402220841ff01714102470d00200641e8066a41186a220d4200370300200641e8066a41106a220e4200370300200641e8066a41086a22084200370300200642003703e80641b3e6ca00ad4280808080e000841001220f29000021102008200f41086a290000370300200620103703e806200f102941c9e6ca00ad4280808080e000841001220f2900002110200641a8066a41086a2211200f41086a290000370300200620103703a806200f1029200e20062903a8062210370300200641d0036a41086a2008290300370300200641d0036a41106a220f2010370300200641d0036a41186a22122011290300370300200620062903e8063703d003200641c8026a200641d0036a412010fc0102400240024020074201520d00200c4200510d010b200641d0026a200641b0036a10a802200641d0036a20062802d002221120062802d80210a9022008200f290300370300200e2012290300370300200d200641d0036a41206a290300370300200641e8066a41206a200641d0036a41286a290300370300200641e8066a41286a2208200641d0036a41306a290300370300200641e8066a41306a220e200641d0036a41386a290300370300200641e8066a41386a220f20064190046a290300370300200620062903d8033703e8060240024020062903d0034201510d00200641a8066a41386a4200370300200641a8066a41306a4200370300200641a8066a41286a4200370300200641c8066a4200370300200641c0066a4200370300200641b8066a4200370300200641b0066a4200370300200642003703a806410021084100210e0c010b200641a8066a41086a200641e8066a41086a290300370300200641a8066a41106a200641e8066a41106a290300370300200641a8066a41186a200641e8066a41186a290300370300200641a8066a41206a200641e8066a41206a290300370300200641a8066a41286a2008290300370300200641a8066a41306a200e290300370300200641a8066a41386a200f290300370300200620062903e8063703a80620064198046a2802002108200628029c04210e0b024020062802d402450d00201110290b2008200b470d01200641d0036a41386a200641a8066a41386a290300370300200641d0036a41306a200641a8066a41306a290300370300200641d0036a41286a200641a8066a41286a290300370300200641d0036a41206a200641a8066a41206a290300370300200641d0036a41186a200641a8066a41186a290300370300200641d0036a41106a200641a8066a41106a290300370300200641d0036a41086a200641a8066a41086a290300370300200620062903a8063703d0032006200e360294042006200b41016a36029004200641b0036a200641d0036a10c5024180122108200341ff01714102460d0220022003200510c602220841ff01714102470d02200641b8026a200520022004200a200910c70202400240024002400240024002400240024002400240024002400240024020062903b8022207200641b8026a41086a290300220c8450450d00420021100c010b200641003a00af072006200c3703d802200620073703d00241012108200641014111200a200984501b3a00ae072006200641b0036a3602a8072006200641b0036a36029806200620064198066a3602e0032006200641ae076a3602dc032006200641a8076a3602d8032006200641af076a3602d4032006200641d0026a3602d003200641e8066a200641b0036a200641d0036a10c8020240024020062802e8064101470d004200210c20062903f00621070c010b20064190076a290300210c20064188076a2903002107024020062903f0064201510d00410021080c010b200641e8066a41106a2903002110200628029806210520064188046a200641e8066a41186a29030037030020064180046a201037030041002108200641d0036a41086a41003a0000200641d9036a2005290000370000200641e1036a200541086a290000370000200641e9036a200541106a290000370000200641f1036a200541186a290000370000200641033a00d003200641d0036a10cb010b4201211020080d010b200641a8066a41186a200641b0036a41186a290300370300200641a8066a41106a200641b0036a41106a290300370300200641a8066a41086a200641b0036a41086a290300370300200620062903b0033703a806200641d0036a200141d0006a220410c90220062d00d0034101460d01200641fc036a280200210f200641f8036a280200210b200641f4036a280200210d200641ec036a280200210e200641d0036a41186a28020021110240200641f0036a2802002208450d002008410c6c21052011210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b0240200e450d00200e410c6c450d00201110290b0240200f450d00200f410c6c2105200d210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b200b450d02200b410c6c450d02200d10290c020b41800221080c0e0b20062d00d10322054102470d010b200641d0036a200410ca0220062d00d0034101460d01200641fc036a280200210f200641f8036a280200210b200641f4036a280200210d200641ec036a280200210e200641e8036a28020021110240200641f0036a2802002208450d002008410c6c21052011210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b0240200e450d00200e410c6c450d00201110290b0240200f450d00200f410c6c2105200d210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b200b450d02200b410c6c450d02200d10290c020b20062f01d203410874210b02402010500d00200641d0036a41186a220f4200370300200641d0036a41106a22044200370300200641d0036a41086a22034200370300200642003703d00341dcbec500ad428080808080018422021001220e290000210920064198066a41086a2208200e41086a2900003703002006200937039806200e10292003200829030037030020062006290398063703d003419fe3c200ad4280808080d0018422091001220e290000210a2008200e41086a2900003703002006200a37039806200e10292004200629039806220a370300200641e8066a41086a220d2003290300370300200641e8066a41106a2211200a370300200641e8066a41186a22122008290300370300200620062903d0033703e806200641a0026a200641e8066a412010e301200641a0026a41106a290300210a20062903a802211020062802a002210e200f42003703002004420037030020034200370300200642003703d00320021001220f29000021022008200f41086a2900003703002006200237039806200f10292003200829030037030020062006290398063703d00320091001220f29000021022008200f41086a2900003703002006200237039806200f102920042006290398062202370300200d20032903003703002011200237030020122008290300370300200620062903d0033703e80620064200200a4200200e1b2202200c7d20104200200e1b220c200754ad7d2209200c20077d2207200c56200920025620092002511b22081b3703d80320064200200720081b3703d003200641e8066aad4280808080800484200641d0036aad428080808080028410030b200b20057221080c0b0b20062d00d10322054102470d010b200641d0036a200410cb0220062d00d0034101460d01200641fc036a280200210f200641f8036a280200210b200641f4036a280200210d200641ec036a280200210e200641e8036a28020021110240200641f0036a2802002208450d002008410c6c21052011210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b0240200e450d00200e410c6c450d00201110290b0240200f450d00200f410c6c2105200d210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b200b450d02200b410c6c450d02200d10290c020b20062f01d203410874210b02402010500d00200641d0036a41186a220f4200370300200641d0036a41106a22044200370300200641d0036a41086a22034200370300200642003703d00341dcbec500ad428080808080018422021001220e290000210920064198066a41086a2208200e41086a2900003703002006200937039806200e10292003200829030037030020062006290398063703d003419fe3c200ad4280808080d0018422091001220e290000210a2008200e41086a2900003703002006200a37039806200e10292004200629039806220a370300200641e8066a41086a220d2003290300370300200641e8066a41106a2211200a370300200641e8066a41186a22122008290300370300200620062903d0033703e80620064188026a200641e8066a412010e30120064188026a41106a290300210a2006290390022110200628028802210e200f42003703002004420037030020034200370300200642003703d00320021001220f29000021022008200f41086a2900003703002006200237039806200f10292003200829030037030020062006290398063703d00320091001220f29000021022008200f41086a2900003703002006200237039806200f102920042006290398062202370300200d20032903003703002011200237030020122008290300370300200620062903d0033703e80620064200200a4200200e1b2202200c7d20104200200e1b220c200754ad7d2209200c20077d2207200c56200920025620092002511b22081b3703d80320064200200720081b3703d003200641e8066aad4280808080800484200641d0036aad428080808080028410030b200b20057221080c080b20062d00d10322054102470d010b200641d0036a200641b0036a200410cc0220062d00d0034101460d01200641fc036a280200210e200641f8036a2802002104200641f4036a280200210f200641ec036a280200210b200641e8036a280200210d0240200641f0036a2802002208450d002008410c6c2105200d210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b0240200b450d00200b410c6c450d00200d10290b0240200e450d00200e410c6c2105200f210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b2004450d022004410c6c450d02200f10290c020b20062f01d203410874210b02402010500d00200641d0036a41186a220f4200370300200641d0036a41106a22044200370300200641d0036a41086a22034200370300200642003703d00341dcbec500ad428080808080018422021001220e290000210920064198066a41086a2208200e41086a2900003703002006200937039806200e10292003200829030037030020062006290398063703d003419fe3c200ad4280808080d0018422091001220e290000210a2008200e41086a2900003703002006200a37039806200e10292004200629039806220a370300200641e8066a41086a220d2003290300370300200641e8066a41106a2211200a370300200641e8066a41186a22122008290300370300200620062903d0033703e806200641f0016a200641e8066a412010e301200641f0016a41106a290300210a20062903f801211020062802f001210e200f42003703002004420037030020034200370300200642003703d00320021001220f29000021022008200f41086a2900003703002006200237039806200f10292003200829030037030020062006290398063703d00320091001220f29000021022008200f41086a2900003703002006200237039806200f102920042006290398062202370300200d20032903003703002011200237030020122008290300370300200620062903d0033703e80620064200200a4200200e1b2202200c7d20104200200e1b220c200754ad7d2209200c20077d2207200c56200920025620092002511b22081b3703d80320064200200720081b3703d003200641e8066aad4280808080800484200641d0036aad428080808080028410030b200b20057221080c050b20062d00d10322054102470d010b200641f8056a41086a200641a8066a41086a2903002213370300200641f0026a41186a200641a8066a41186a290300370300200641f0026a41106a200641a8066a41106a290300370300200641f0026a41086a2013370300200620062903a80622133703f805200620133703f00220064190036a41186a200641b0036a41186a29030037030020064190036a41106a200641b0036a41106a29030037030020064190036a41086a200641b0036a41086a290300370300200620062903b003370390034101210d0c090b20062f01d203410874210b02402010500d00200641d0036a41186a220f4200370300200641d0036a41106a22044200370300200641d0036a41086a22034200370300200642003703d00341dcbec500ad428080808080018422021001220e290000210920064198066a41086a2208200e41086a2900003703002006200937039806200e10292003200829030037030020062006290398063703d003419fe3c200ad4280808080d0018422091001220e290000210a2008200e41086a2900003703002006200a37039806200e10292004200629039806220a370300200641e8066a41086a220d2003290300370300200641e8066a41106a2211200a370300200641e8066a41186a22122008290300370300200620062903d0033703e806200641d8016a200641e8066a412010e301200641d8016a41106a290300210a20062903e001211020062802d801210e200f42003703002004420037030020034200370300200642003703d00320021001220f29000021022008200f41086a2900003703002006200237039806200f10292003200829030037030020062006290398063703d00320091001220f29000021022008200f41086a2900003703002006200237039806200f102920042006290398062202370300200d20032903003703002011200237030020122008290300370300200620062903d0033703e80620064200200a4200200e1b2202200c7d20104200200e1b220c200754ad7d2209200c20077d2207200c56200920025620092002511b22081b3703d80320064200200720081b3703d003200641e8066aad4280808080800484200641d0036aad428080808080028410030b200b20057221080c020b41a094cc00411941bc94cc001033000b4180064180042008200b4b1b21080b200020083b0001200041013a0000200041036a20084110763a00000c040b10c402220841ff01714102470d0010c402220841ff01714102470d0010c4021a10c402220841ff01714102470d0010c402220841ff01714102470d0020022003200510c602220841ff01714102470d004200210a200641d0036a41106a4200370300200641a8066a41086a22044200370300200641a8066a41106a220b4200370300200641a8066a41186a220e4200370300200642003703a806200128025041746a2208410c4b0d020240024020080e0d00040404040404040404040401000b200641d0036a200141d4006a10cd02024020062d00d0034101460d00200641fc036a2802002111200641f8036a280200210f200641f4036a2802002112200641ec036a280200210d200641e8036a28020021140240200641f0036a2802002208450d002008410c6c21052014210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b0240200d450d00200d410c6c450d00201410290b02402011450d002011410c6c21052012210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b200f450d04200f410c6c450d04201210290c040b20062d00d10322084102460d030c020b200641d0036a200141d8006a10ce02024020062d00d0034101460d00200641fc036a2802002111200641f8036a280200210f200641f4036a2802002112200641ec036a280200210d200641e8036a28020021140240200641f0036a2802002208450d002008410c6c21052014210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b0240200d450d00200d410c6c450d00201410290b02402011450d002011410c6c21052012210803400240200841046a280200450d00200828020010290b2008410c6a2108200541746a22050d000b0b200f450d03200f410c6c450d03201210290c030b20062d00d10322084102460d020c010b200020083b0001200041013a0000200041036a20084110763a00000c020b20062f01d2032103200041013a0000200041036a20034108763a0000200020034108742008723b00010c010b200641f0026a41186a200e290300370300200641f0026a41106a200b290300370300200641f0026a41086a2004290300370300200620062903a8063703f0024100210d42002109420021100c010b200141d0006a10cc010c010b200641d0026a41186a220820064190036a41186a290300370300200641d0026a41106a220520064190036a41106a290300370300200641d0026a41086a220420064190036a41086a29030037030020062006290390033703d002200641b0036a41186a220b200641f0026a41186a290300370300200641b0036a41106a220e200641f0026a41106a290300370300200641b0036a41086a220f200641f0026a41086a290300370300200620062903f0023703b003200641d0036a200141d0006a41a80210e4071a200641b0076a41186a22112008290300370300200641b0076a41106a22082005290300370300200641b0076a41086a22052004290300370300200620062903d0023703b007410221010240200d450d00200641f8056a41186a2011290300370300200641f8056a41106a2008290300370300200641f8056a41086a2005290300370300200620062903b0073703f805410121010b200641f2066a200641f8056a41086a2208290300370100200641fa066a200641f8056a41106a220529030037010020064182076a200641f8056a41186a2204290300370100200620013a00e906200620062903f8053701ea06200641003a00e806200641a8066a200641d0036a200641e8066a10c501200641a8066a41106a290300211520062903b00621132004200b2903003703002005200e2903003703002008200f290300370300200620062903b0033703f8050240024002400240200341ff01714102470d0020062903a8064201520d0020134202510d00200641a8066a41186a2d000041ff01714104470d010b024020134201520d004200200220157d221620162002561b2216500d00200641b0016a10cf02200620062903b0013703e806200620062903b8013703b007200641b0076a200641e8066a200341ff01714101461b220142002001290300221720167d221620162017561b370300200641e0036a20062903b007370300200620062903e8063703d803200642013703d003200641d8036a10d0020b200641b0076a41186a200641f8056a41186a290300370300200641b0076a41106a200641f8056a41106a290300370300200641b0076a41086a200641f8056a41086a290300370300200620062903f8053703b00702402010500d00420021160240024020134201520d004280c0a8ca9a3a21104200200220157d221320132002561b221642ffbfa8ca9a3a560d010b201621100b200641d0036a41186a4200370300200641d0036a41106a22034200370300200641d0036a41086a22014200370300200642003703d00341cdcac800ad4280808080a002841001220829000021022001200841086a290000370300200620023703d0032008102941b8cbc800ad428080808090028410012208290000210220064190036a41086a2205200841086a29000037030020062002370390032008102920032006290390032202370300200641e8066a41086a2001290300370300200641e8066a41106a2002370300200641e8066a41186a2005290300370300200620062903d0033703e8062010428094ebdc038022024280e892267e2215201020024280ec94a37c7e7c4280e892267e2202428094ebdc03802210a7417f2002428080808080c0b2cd3b541b200220104280ec94a37c7e7c4280cab5ee01566aad7c2213201554ad211520064198016a200641e8066a10d10241002101024002402006280298010d004200211642002102420021100c010b20062903a0012102024020064198016a41106a2903002216427f570d00201621100c010b428080808080808080807f420020162002420052ad7c7d20022016428080808080808080807f85845022011b21104200420020027d20011b2102410121010b200641d0036a200220102013201542808090bbbad6adf00d420010d2020240024020062802d0034101460d00200641e0036a2903002102200641d8036a29030021102001450d012010200284500d010b2016423f87427f85221021020b2006427f201020137c221320132010542201200220157c2001ad7c221020025420102002511b22011b2202370390032006427f201020011b22103703980302402002201084500d002006200641b0076a3602f002200641e8066a200641b0076a20064190036a200641f0026a10b30220062802e8064101460d0020064190076a290300210220064188076a29030021100240200641e8066a41086a2903004201520d00200641e8066a41106a290300211320064188046a200641e8066a41186a29030037030020064180046a2013370300200641d0036a41086a41003a0000200641d9036a20062903b007370000200641e1036a200641b0076a41086a290300370000200641e9036a200641b0076a41106a290300370000200641f1036a200641b0076a41186a290300370000200641033a00d003200641d0036a10cb010b20072010542201200c200254200c2002511b0d03200c20027d2001ad7d210c200720107d21070b200641e8006a427f200720072007200a20072007200a56200c200956200c2009511b22011b22027d542208200c2009200c20011b22097d2007200254ad7d220220097c2008ad7c220c200254200c2002511b22011b427f200c20011b1081022006290368a7450d00200641e8006a41106a2903002107200641306a2006290370220242004204420010d507200641206a420042002002420010d507200641c0006a2006290330200641306a41086a290300220c200742028620062903207c7c22094205420010e007200641d0006a42b3e6cc99b3e6cc993320062903402007200742ffffffffffffffff3f83522006290328420052722009200c547222011b220c20022002200c56200742b3e6cc99b3e6cc9933200641c0006a41086a29030020011b220c562007200c511b22011b2209200c200720011b220c1081022007200c7d2002200954ad7d2107200220097d210202402006290350a7450d00200641d0006a41106a290300210c20062903582109200642f0f2bda1a7ee9cb9f9003703e806200641d0036a200641e8066a108202200641d0036a2009200c108002200641e8036a200c370300200641e0036a2009370300200641d0036a41086a41063a00002006410e3a00d003200641d0036a10cb010b200641086a200220071081022006290308a7450d00200641086a41106a290300210720062903102102200641e8066a10bc01200641d0036a10bc01200641d0036a2002200710800220064188046a200737030020064180046a2002370300200641d0036a41086a41043a0000200641d9036a20062903e806370000200641e1036a200641e8066a41086a290300370000200641e9036a200641e8066a41106a290300370000200641f1036a20064180076a290300370000200641033a00d003200641d0036a10cb010b200041086a20062903a806370300200041003a0000200041286a200641a8066a41206a290300370300200041206a200641a8066a41186a290300370300200041186a200641a8066a41106a290300370300200041106a200641a8066a41086a290300370300200641d0076a24000f0b41801021052010500d01200641d0036a41186a220b4200370300200641d0036a41106a22034200370300200641d0036a41086a22084200370300200642003703d00341dcbec500ad42808080808001842202100122042900002109200641b0076a41086a2201200441086a290000370300200620093703b0072004102920082001290300370300200620062903b0073703d003419fe3c200ad4280808080d00184220910012204290000210a2001200441086a2900003703002006200a3703b00720041029200320062903b007220a370300200641e8066a41086a220e2008290300370300200641e8066a41106a220f200a370300200641e8066a41186a220d2001290300370300200620062903d0033703e806200641c0016a200641e8066a412010e301200641c0016a41106a290300210a20062903c801211020062802c0012104200b42003703002003420037030020084200370300200642003703d00320021001220b29000021022001200b41086a290000370300200620023703b007200b102920082001290300370300200620062903b0073703d00320091001220b29000021022001200b41086a290000370300200620023703b007200b1029200320062903b0072202370300200e2008290300370300200f2002370300200d2001290300370300200620062903d0033703e80620064200200a420020041b2202200c7d2010420020041b220c200754ad7d2209200c20077d2207200c56200920025620092002511b22011b3703d80320064200200720011b3703d003200641e8066aad4280808080800484200641d0036aad428080808080028410030c010b200641e8066a41186a22044200370300200641e8066a41106a22034200370300200641e8066a41086a22084200370300200642003703e80641dcbec500ad4280808080800184220910012205290000210a20064198066a41086a2201200541086a2900003703002006200a37039806200510292008200129030037030020062006290398063703e806419fe3c200ad4280808080d00184220a1001220529000021132001200541086a29000037030020062013370398062005102920032006290398062213370300200641d0036a41086a220b2008290300370300200641d0036a41106a220e2013370300200641d0036a41186a220f2001290300370300200620062903e8063703d00320064180016a200641d0036a412010e30120064180016a41106a290300211320062903880121152006280280012105200442003703002003420037030020084200370300200642003703e80620091001220429000021092001200441086a2900003703002006200937039806200410292008200129030037030020062006290398063703e806200a1001220429000021092001200441086a29000037030020062009370398062004102920032006290398062209370300200b2008290300370300200e2009370300200f2001290300370300200620062903e8063703d0032006427f2013420020051b22092002200c7d2010200754ad7d7c2015420020051b2202201020077d7c220c2002542201ad7c22072001200720095420072009511b22011b3703f0062006427f200c20011b3703e806200641d0036aad4280808080800484200641e8066aad4280808080800284100341800221050b200020053b0001200041013a0000200041036a41003a00000b200641d0076a24000b040041020bb90204027f017e017f027e230041106b220224002002200010a8022001280240210320023502082104200228020021050240410410272200450d002000200336000020012d00442103200041044108102b2200450d00200020033a0004200141086a290300210620012903002107200041084115102b2200450d00200020073700052000410d6a2006370000200141186a29030021062001290310210720004115412a102b2200450d00200020073700152000411d6a2006370000200141286a2903002106200129032021072000412a41d400102b2200450d00200020073700252000412d6a2006370000200020012903303700352000413d6a200141386a29030037000020044220862005ad842000ad4280808080d0088410032000102902402002280204450d00200510290b200241106a24000f0b1030000be50603017f047e067f230041e0006b22032400200341306a20012002109803024002400240024020032903302204a7220241ff01714101460d00200310cf022003290308210520032903002106024002400240200141ff01710e03010004010b4100210141800c2102200042c0b2cd3b7c22072000540d05200520077c22072005540d05427f200620077c220020002006541b4281c0a8ca9a3a5a0d0120062100200721050c040b4100210141800c2102200042c0b2cd3b7c22072000540d04200620077c22002006540d0420004280b0def7d32b560d042007428090a7f0ea25560d040c030b20062100200721052007428090cad2c60e560d030c020b200241087641ff017121012004421088a741087421020c020b427f2006427f200042c0b2cd3b7c220720072000541b7c220020002006541b21000b200341306a41186a22084200370300200341306a41106a22094200370300200341306a41086a220242003703002003420037033041b3e6ca00ad4280808080e0008422061001220a2900002107200341d0006a41086a2201200a41086a29000037030020032007370350200a1029200220012903003703002003200329035037033041e8a0cb00ad42808080808002841001220a29000021072001200a41086a29000037030020032007370350200a1029200920032903502207370300200341106a41086a220b2002290300370300200341106a41106a220c2007370300200341106a41186a220d20012903003703002003200329033037031020032004422088a7360230200341106aad42808080808004842204200341306aad4280808080c0008410032008420037030020094200370300200242003703002003420037033020061001220a29000021062001200a41086a29000037030020032006370350200a1029200220012903003703002003200329035037033041b4a0cb00ad4280808080b001841001220a29000021062001200a41086a29000037030020032006370350200a1029200920032903502206370300200b2002290300370300200c2006370300200d2001290300370300200320032903303703100240410810272201450d0020012000370000200141084110102b2201450d002001200537000820042001ad428080808080028410032001102941022101410021020c010b1030000b200341e0006a240020022001720bad0604027f017e017f037e23004180016b220624000240200341ff01710d00200641086a2001ad420042c0843d420010d507200641d0006a41186a4200370300200641d0006a41106a22074200370300200641d0006a41086a220342003703002006420037035041cdcac800ad4280808080a002841001220129000021082003200141086a290000370300200620083703502001102941b8cbc800ad4280808080900284100122012900002108200641f0006a41086a2209200141086a2900003703002006200837037020011029200720062903702208370300200641306a41086a2003290300370300200641306a41106a2008370300200641306a41186a200929030037030020062006290350370330200641086a41086a29030020024280c0a8ca9a3a20024280c0a8ca9a3a541b2202428094ebdc038022084280e892267e220a200220084280ec94a37c7e7c4280e892267e2202428094ebdc03802208a7417f2002428080808080c0b2cd3b541b200220084280ec94a37c7e7c4280cab5ee01566aad7c2202200a54ad7c2006290308220820027c220a200854ad7c210b200641186a200641306a10d102410021030240024020062802180d004200210c42002102420021080c010b200629032021020240200641186a41106a290300220c427f570d00200c21080c010b428080808080808080807f4200200c2002420052ad7c7d2002200c428080808080808080807f85845022031b21084200420020027d20031b2102410121030b200641d0006a20022008200a200b42808090bbbad6adf00d420010d2020240024020062802504101460d00200641e0006a2903002102200641d8006a29030021082003450d012008200284500d010b200c423f87427f85220821020b427f427f427f2002200b7c2008200a7c220a2008542203ad7c22082003200820025420082002511b22031b220b427f200a20031b22024280ade2047c22082002542203ad7c220a2003200a200b54200820025a1b22031b220220057c427f200820031b220520047c22082005542203ad7c22042003200420025420042002511b22031b2105427f200820031b21040b200020043703002000200537030820064180016a24000be30f06077f027e037f0a7e017f037e23004180036b2203240020022802102104200228020c21052002280208210620022802042107200228020021022003200110a80220034180016a200328020022082003280208220910a902200329038001210a4200210b2003420037038001200341c8016a280200210c20032d00cc01210d02400240200a420151220e0d00200341106a41306a4200370300200341106a41286a4200370300200341106a41206a4200370300200341106a41186a4200370300200341206a4200370300200341186a4200370300200342003703104200210f4200211042002111420021120c010b200341b8016a290300211320034180016a41306a290300211420034180016a41206a290300210f20034180016a41186a290300210b200341c0016a290300211220032903900121112003290388012110200341106a41206a20034180016a41286a290300370300200341106a41286a2014370300200341106a41306a2013370300200341206a200b3703002003200f37032820032010370310200320113703180b024002400240024002402010200229030022157d22142010562011200241086a29030022167d2010201554ad7d221320115620132011511b450d0041cbe2c200ad4280808080b00284211141838c0c21040c010b02402010200b7c22174280c8afa0255441002011200f7c22182017200b54ad7c501b0d002014200b7c220b42ffc7afa025562013200f7c200b201454ad7c220b420052200b501b0d0020072d00004101460d0041b0e2c200ad4280808080900184211141838c1421040c010b2015201684500d0120052d00002105200341c8006a200628020010a80220034180026a20032802482206200328025010a9022003290380024201512107200341b0026a290300210f200341a8026a2903002116200341c0026a290300210b200341b8026a29030021150240200328024c450d00200610290b200b420020071b210b2015420020071b21150240200541ff01714101460d00200f420020071b210f2016420020071b2116024020054101710d0020162115200f210b0c010b200f200b2016201556200f200b56200f200b511b22071b210b2016201520071b21150b2015201458200b201358200b2013511b0d0141dee2c200ad4280808080d00284211141838c0421040b20114280807c83210b201142088842ff018321102011a7210e410121020c010b2003201437031020032013370318200241086a290300210f2002290300211520042802002104200341c8006a41186a200341206a220241086a290300220b370300200341c8006a41206a2205200241106a290300370300200341f0006a2206200241186a290300370300200341f8006a2219200241206a2903003703002003201337035020032014370348200320022903002216370358427f20172017201054220220182002ad7c221020115420102011511b22021b427f201020021b8450210202400240427f201420167c2211201120145422072013200b7c2007ad7c221120135420112013511b22071b22104280c8afa025544100427f201120071b2211501b0d00200341c8006a41106a29030021182019290300211a200629030021102005290300210b20032903502117200329034821164201211b2003290360211c0c010b4200211b02402010201184500d002010201110d402200341b8026a2011370300200341b0026a201037030020034180026a41086a41013a000020034189026a200429000037000020034191026a200441086a29000037000020034199026a200441106a290000370000200341a1026a200441186a290000370000200341033a00800220034180026a10cb010b0b2002ad2111200341a8016a200b370300200341b0016a201037030020034190016a2017370300200341b8016a201a37030020034198016a20183703002003201c3703a001200320123703c0012003201637038801410021022003200d4100200a42015122041b220d3a00cc012003200c410020041b220c3602c8012003201b4201512204ad37038001024020040d002009ad4220862008ad841004420021104200210b0c010b410410272204450d012004200c360000200441044108102b2204450d012004200d3a0004200441084115102b2204450d01200420163700052004410d6a2017370000200341a0016a290300210a20034198016a290300211720044115412a102b2204450d01200420173700152004411d6a200a3700002004412a41d400102b2204450d012004200b3700252004412d6a20103700002004413d6a200341c0016a2903003700002004200341b8016a2903003700352009ad4220862008ad842004ad4280808080d008841003200410294200210b420121100b02402003280204450d00200810290b024002402002450d0020002004360204200041086a2010420886200ead42ff018384200b84370200410121020c010b024002400240200e41ff017122020d0020104200510d004103210e20034180026a21020c010b2002450d0120104200520d014104210e20034180016a21020b200241086a200e3a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a290000370000200210cb010b200041286a200f370300200041206a2015370300200041186a2013370300200041106a2014370300200041086a2011370300410021020b2000200236020020034180036a24000f0b1030000bc71705067f017e0a7f027e017f23004190016b220224004104210302400240024002400240024002400240024002400240024020012802004117460d00410021040c010b41002104200141046a22052d00004105470d00200241e0006a200141c8006a28020010dc0620022802602203200228026810900641ff0171210402402002280264450d00200310290b0240024002400240024002400240024020044102460d002004410171450d00200241e0006a41186a4200370300200241e0006a41106a22064200370300200241e0006a41086a220342003703002002420037036041d787cc00ad428080808090018410012207290000210820024180016a41086a2204200741086a29000037030020022008370380012007102920032004290300370300200220022903800137036041eb87cc00ad4280808080f001841001220729000021082004200741086a29000037030020022008370380012007102920062002290380012208370300200241c0006a41086a2003290300370300200241c0006a41106a2008370300200241c0006a41186a200429030037030020022002290360370340200241206a200241c0006a10fd050240200228022022090d0020024100360218200242043703100c030b2002290224210820022009360210200220083702142008422088a7220a450d01200a417f6a210b0c040b200041800e3b0001200041013a0000200041036a41013a00000c110b2008a7450d0041002104200a210b0c010b200241106a41004101109d01200228021021092002280218220b21040b20092004410c6c6a22044100360208200442043702002002200b41016a220a360218200a200b490d010b200241e0006a41186a220c4200370300200241e0006a41106a220d4200370300200241e0006a41086a220342003703002002420037036041d787cc00ad428080808090018410012207290000210820024180016a41086a2204200741086a29000037030020022008370380012007102920032004290300370300200220022903800137036041e087cc00ad4280808080b001841001220729000021082004200741086a2900003703002002200837038001200710292006200229038001370000200641086a2004290300370000200241c0006a41086a2003290300370300200241c0006a41106a200d290300370300200241c0006a41186a200c29030037030020022002290360370340200241086a200241c0006a412010fc01024002402009200b410c6c6a220e41086a220f2802002204200228020c410020022802081b4f0d00200e28020021100240200441014b0d00024020040e020300030b2001280248210d410021030c040b2001280248210d41002103034020032004410176220720036a220c200d2010200c41246c6a280200491b2103200420076b220441014b0d000c040b0b200041800c3b0001200041013a0000200041036a41003a00000c0d0b2001280248210d410021030c020b200b410041ece2c8001036000b200d2010200341246c6a2802002204460d032003200d20044b6a21030b200241e0006a200d10ce0420022802602211450d0320022802642112200241e0006a41086a22073502004220862011ad84101022042900002108200441086a2900002113200441106a2900002114200241206a41186a200441186a290000370300200241206a41106a2014370300200241206a41086a201337030020022008370320200410290240200241206a200541216a2215460d00200241206a2015412010e7070d020b200241e0006a41186a200541196a290000370300200241e0006a41106a200541116a2900003703002007200541096a29000037030020022005290001370360200f28020022042003490d0420012802482107024020042009200b410c6c6a41046a280200470d00200e200441011096012002280218210a200228021021090b200e280200200341246c6a220141246a2001200420036b41246c10e5071a20012007360200200120022903603702042001410c6a200241e0006a41086a2203290300370200200141146a200241e0006a41106a22072903003702002001411c6a200241e0006a41186a220c2903003702004101210d200f200441016a3602002002280214210e200c420037030020074200370300200342003703002002420037036041d787cc00ad428080808090018410012204290000210820024180016a41086a2201200441086a29000037030020022008370380012004102920032001290300370300200220022903800137036041eb87cc00ad4280808080f001841001220429000021082001200441086a2900003703002002200837038001200410292006200229038001370000200641086a2001290300370000200241c0006a41086a2003290300370300200241c0006a41106a2007290300370300200241c0006a41186a200c29030037030020022002290360370340200a410c6c41046a2201417f4c0d054100210402402001450d0020011027220d450d08200121040b200241003602682002200d36026020022004360264200a200241e0006a10710240200a450d002009200a410c6c6a210b2009210603402006280200210120062802082204200241e0006a107102402004450d002001200441246c6a21054100200228026822046b210d20022802642103034020012802002110024002402003200d6a4104490d002002280260210c200321070c010b200441046a22072004490d0b2003410174220c2007200c20074b1b22074100480d0b0240024020030d00024020070d004101210c0c020b20071027220c0d010c0f0b2002280260210c20032007460d00200c20032007102b220c450d0e0b200220073602642002200c3602600b200c20046a20103600002002200441046a2203360268024002402007200d6a417c6a411f4d0d00200721030c010b200341206a22102003490d0b200741017422032010200320104b1b22034100480d0b0240024020070d00024020030d004101210c0c020b20031027220c450d0f0c010b20072003460d00200c20072003102b220c450d0e0b200220033602642002200c3602600b200c20046a220741046a200141046a2900003700002007411c6a2001411c6a290000370000200741146a200141146a2900003700002007410c6a2001410c6a2900003700002002200441246a2204360268200d415c6a210d200141246a22012005470d000b0b2006410c6a2206200b470d000b0b20022802642101200241c0006aad4280808080800484200235026842208620022802602204ad84100302402001450d00200410290b0240200a450d00200a410c6c21042009210103400240200141046a2802002203450d00200341246c450d00200128020010290b2001410c6a2101200441746a22040d000b0b0240200e450d00200e410c6c450d00200910290b410c10272203450d08412010272201450d0720012015290000370000200141186a2207201541186a290000370000200141106a220c201541106a290000370000200141086a220d201541086a290000370000412010272204450d0820042001290000370000200441186a2007290000370000200441106a200c290000370000200441086a200d29000037000020011029200342a080808080043702042003200436020002402012450d00201110290b410121040b200041003a0000200041306a41013a00002000412c6a2004360200200041286a2004360200200041246a2003360200200041206a4100360200200041186a4204370300200041106a427f370300200041086a4200370300200041316a2002280060360000200041346a200241e3006a2800003600000c090b20004180063b0001200041013a0000200041036a41003a00002012450d07201110290c070b200041800e3b0001200041013a0000200041036a41003a00000c060b200041800e3b0001200041013a0000200041036a41013a00000c050b200320041041000b1038000b1032000b1039000b1030000b0240200a450d00200a410c6c21042009210103400240200141046a2802002203450d00200341246c450d00200128020010290b2001410c6a2101200441746a22040d000b0b20022802142201450d002001410c6c450d00200910290b20024190016a24000bcd1304057f017e077f017e230041f0026b22022400024002400240024002400240024020012802004114470d0020012802044102470d00200241e8006a41186a22034200370300200241e8006a41106a22044200370300200241e8006a41086a220542003703002002420037036841b1dcc900ad4280808080f000841001220629000021072005200641086a290000370300200220073703682006102941b8dcc900ad4280808080a00184100122062900002107200241d0016a41086a2208200641086a290000370300200220073703d00120061029200420022903d0012207370300200241086a22092005290300370300200241106a220a2007370300200241186a220b200829030037030020022002290368370300200241e8006a2002108d02200229026c4200200228026822061b21072006410120061b210c02400240200141086a220d2802002001411c6a220e280200470d002003420037030020044200370300200542003703002002420037036841cd87cc00ad4280808080a0018410012206290000210f2005200641086a2900003703002002200f3703682006102941d983cc00ad4280808080b0018410012206290000210f2008200641086a2900003703002002200f3703d00120061029200420022903d001220f37030020092005290300370300200a200f370300200b200829030037030020022002290368370300200241e8006a2002109e0320022802682205410120051b210a41800e2109200229026c420020051b220f422088a72205450d06200141c0006a21042005410574210841002106200a2105034020042005460d02200620052004412010e70722034100476a21062003450d02200541206a2105200841606a22080d000c070b0b20004180083b0001200041013a0000200041036a41003a00000c060b20062007422088a722054f0d01200241186a200c20064105746a220541186a290000370300200241106a200541106a290000370300200241086a200541086a29000037030020022005290000370300200241e8006a200210a0020240024002402002280288012205450d000240200228028c012206450d00200641306c450d00200510290b0240024002400240200141e0006a2d00000e03010200010b20024180016a200d41f1006a290000370300200241f8006a200d41e9006a290000370300200241f0006a200d41e1006a2900003703002002200d41d9006a29000037036841022106200241e8006a21050c020b20024180016a200d41f1006a290000370300200241f8006a200d41e9006a290000370300200241f0006a200d41e1006a2900003703002002200d41d9006a29000037036841002106200241e8006a21050c010b20024180016a200d41f1006a290000370300200241f8006a200d41e9006a290000370300200241f0006a200d41e1006a2900003703002002200d41d9006a29000037036841012106200241e8006a21050b200241196a200541186a290000370000200241116a200541106a290000370000200241096a200541086a290000370000200220063a000020022005290000370001200241296a200d4181016a290000370000200241316a200d4189016a290000370000200241396a200d4191016a290000370000200241c1006a200d4199016a290000370000200241c9006a200d41a1016a290000370000200241d1006a200d41a9016a290000370000200241d9006a200d41b1016a2900003700002002200d41f9006a2900003700210240024002400240200d2d00b9010e03010200010b200241d0016a41186a200d41d2016a290000370300200241d0016a41106a200d41ca016a290000370300200241d0016a41086a200d41c2016a2900003703002002200d41ba016a2900003703d00141022106200241d0016a21050c020b200241d0016a41186a200d41d2016a290000370300200241d0016a41106a200d41ca016a290000370300200241d0016a41086a200d41c2016a2900003703002002200d41ba016a2900003703d00141002106200241d0016a21050c010b200241d0016a41186a200d41d2016a290000370300200241d0016a41106a200d41ca016a290000370300200241d0016a41086a200d41c2016a2900003703002002200d41ba016a2900003703d001200241d0016a2105410121060b20024181016a200541186a290000370000200241f9006a200541106a290000370000200241f1006a200541086a290000370000200220063a00682002200529000037006920024191016a200d41e2016a29000037000020024199016a200d41ea016a290000370000200241a1016a200d41f2016a290000370000200241a9016a200d41fa016a290000370000200241b1016a200d4182026a290000370000200241b9016a200d418a026a290000370000200241c1016a200d4192026a2900003700002002200d41da016a29000037008901200241a0026a410c6a200441086a290200370200200241b4026a200441106a290200370200200241bc026a200441186a290200370200200241f0c2c98b063602a002200220042902003702a40220012802082105200241e0026a2001410c6a10b504200241c8026a410c6a200241e0026a41086a280200360200200220053602c802200220022903e0023702cc022002200141186a2802003602d802200241d0016a200241a0026a200241c8026a10b6042002280290022205450d0502402002280294022201450d00200141306c450d00200510290b41042105200d280200200e280200470d062002200e200410920641ff017122054106470d06200241e8006a200e200410920641ff017122054106470d064103210520022d0000220141024b0d0620024101722104200241e8006a41017221060240024002400240024002400240024020010e03000102000b20022d0068417f6a220141014b0d0d20010e020802080b20022d0068220141024b0d0c20010e03020c04020b20022d0068220141014b0d0b20010e020204020b20042006412010e7070d0a0c060b20062004412010e7070d090c050b20062004412010e7070d080c040b20042006412010e7070d070c030b20042006412010e707450d020c060b41808e0421090c060b20042006412010e7070d040b0240200f42ffffff3f83500d00200a10290b200742ffffff3f83500d00200c10290b200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a4200370300200041316a2002280068360000200041346a200241eb006a2800003600000c050b2006200541d0c9c7001036000b410521050b200541107441800e7221090b200020093b0001200041013a0000200041036a20094110763a0000200f42ffffff3f83500d00200a10290b200742ffffff3f83500d00200c10290b200241f0026a24000bfb1703057f037e037f23004190056b22022400024002402001280200410b460d00200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a42003703000c010b200241a8026a410c6a200141f0016a290200370200200241bc026a200141f8016a290200370200200241c4026a20014180026a290200370200200241e7e485f3063602a8022002200141e8016a22032902003702ac0220014188026a2802002104200241386a2001418c026a10b504200241a0016a410c6a200241c0006a280200360200200220043602a001200220022903383702a401200220014198026a2802003602b00120024190036a200241a8026a200241a0016a10b604024020022802d00322050d00200041800e3b0001200041013a0000200041036a41023a00000c010b024020022802d4032206450d00200641306c450d00200510290b20012903082107200141186a2903002108200141106a290300210920024188026a41186a200341186a29000037030020024188026a41106a200341106a29000037030020024188026a41086a200341086a29000037030020022003290000370388020240024020094201520d00200241a8026a410c6a2001412c6a290200370200200241a8026a41146a200141346a290200370200200241a8026a411c6a2001413c6a290200370200200241a8026a412c6a200141cc006a290200370200200241a8026a41346a200141d4006a290200370200200241a8026a413c6a200141dc006a290200370200200241a8026a41c4006a200141e4006a290200370200200241a8026a41cc006a200141ec006a290200370200200241a8026a41d4006a200141f4006a290200370200200241a8026a41dc006a200141fc006a2902003702002002200141246a2902003702ac022002200141206a2802003602a8022002200141c4006a2902003702cc0220024190036a410c6a20014190016a29020037020020024190036a41146a20014198016a29020037020020024190036a411c6a200141a0016a290200370200200220014188016a29020037029403200220014184016a280200360290034101210520024190036a2103200241a8026a21060c010b200241a8026a410c6a2001412c6a290200370200200241a8026a41146a200141346a290200370200200241a8026a411c6a2001413c6a290200370200200241a8026a412c6a200141cc006a290200370200200241a8026a41346a200141d4006a290200370200200241a8026a413c6a200141dc006a290200370200200241a8026a41c4006a200141e4006a290200370200200241a8026a41cc006a200141ec006a290200370200200241a8026a41d4006a200141f4006a290200370200200241a8026a41dc006a200141fc006a2902003702002002200141246a2902003702ac022002200141206a2802003602a8022002200141c4006a2902003702cc0220024190036a410c6a20014190016a29020037020020024190036a41146a20014198016a29020037020020024190036a411c6a200141a0016a290200370200200220014188016a29020037029403200220014184016a280200360290034100210520024190036a2103200241a8026a21060b200341dc006a200141e0016a290200370200200341d4006a200141d8016a290200370200200341cc006a200141d0016a290200370200200341c4006a200141c8016a2902003702002003413c6a200141c0016a290200370200200341346a200141b8016a2902003702002003412c6a200141b0016a2902003702002003200141a8016a290200370224200241186a41086a220a20024188026a41086a290300370300200241186a41106a220b20024188026a41106a290300370300200241186a41186a220c20024188026a41186a2903003703002002200229038802370318200241a0016a200641e40010e4071a200241386a200341e40010e4071a0240024002402005450d00200220083703900320024190036a41086a200241a0016a41e40010e4072101200241fc036a200241386a41e40010e4072103200241f8046a200c29030037030020024190036a41e0016a200b29030037030020024190036a41d8016a200a290300370300200220022903183703e004024020024190036a410c6a20024180046a412010e7070d0020022802980320022802fc03460d020b200241cc026a200141206a280200360200200241c4026a200141186a290200370200200241bc026a200141106a290200370200200241a8026a410c6a200141086a290200370200200241013602a802200220012902003702ac0220024100360288052002420137038005200220073703980220022008370388022002200241a8026a3602900220024188026a20024180056a10b704200241bc036a2002350288054220862002280280052205ad84200241e0046a2206101221010240200228028405450d00200510290b20014101470d01200241cc026a200341206a280200360200200241c4026a200341186a290200370200200241bc026a200341106a290200370200200241b4026a200341086a290200370200200241013602a802200220032902003702ac02200229039003210820024100360288052002420137038005200220073703980220022008370388022002200241a8026a3602900220024188026a20024180056a10b704200241a0046a2002350288054220862002280280052203ad842006101221010240200228028405450d00200310290b20014101470d010c020b200220083703900320024190036a41086a200241a0016a41e40010e4072101200241fc036a200241386a41e40010e4072103200241f8046a200c29030037030020024190036a41e0016a200b29030037030020024190036a41d8016a200a290300370300200220022903183703e004024020024190036a410c6a20024180046a412010e7070d0020022802980320022802fc03460d010b200241cc026a200141206a280200360200200241c4026a200141186a290200370200200241bc026a200141106a290200370200200241a8026a410c6a200141086a290200370200200241003602a802200220012902003702ac0220024100360288052002420137038005200220073703980220022008370388022002200241a8026a3602900220024188026a20024180056a10b704200241bc036a2002350288054220862002280280052205ad84200241e0046a2206101221010240200228028405450d00200510290b20014101470d00200241cc026a200341206a280200360200200241c4026a200341186a290200370200200241bc026a200341106a290200370200200241b4026a200341086a290200370200200241003602a802200220032902003702ac02200229039003210820024100360288052002420137038005200220073703980220022008370388022002200241a8026a3602900220024188026a20024180056a10b704200241a0046a2002350288054220862002280280052203ad842006101221010240200228028405450d00200310290b20014101460d010b200041800e3b0001200041013a0000200041036a41013a00000c010b0240024020074200520d0020024190036a420010b8042002200228029003220520022802980310fc0141002103200228020421062002280200210102402002280294030d000c020b200510290c010b20024190036a2007427f7c10b804200241106a200228029003220320022802980310fc0120022802142105200228021021010240200228029403450d00200310290b41012103024020014101460d00200041800e3b0001200041013a0000200041036a41033a00000c020b20024190036a200710b804200241086a200228029003220a20022802980310fc01200228020c210620022802082101200228029403450d00200a10290b024020014101460d00200041800e3b0001200041013a0000200041036a41033a00000c010b0240200420064b0d000240200420054d410220031b22014102460d0020014101710d010b200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a42003703000c010b200041800e3b0001200041013a0000200041036a41043a00000b20024190056a24000bd30402057f027e230041f0006b220324000240024020022802004118470d00200241086a2d00004104470d00200341c8006a2001109c04200341306a200328024822042003280250109d04200341d8006a41086a2003413b6a290000370300200341d8006a41106a2205200341c3006a2f00003b0100200320032900333703584101210120032d0032210620032d003121070240024020032d00304101460d00410021010c010b200341186a41106a20052f01003b0100200341186a41086a200341d8006a41086a290300370300200320032903583703180b0240200328024c450d00200410290b02402001450d00200341106a200341186a41106a2f010022013b0100200341086a200341186a41086a29030022083703002003200329031822093703002003413a6a2008370100200341c2006a20013b0100200320063a0031200320073a003020032009370132200341d8006a200341306a109904200328025822042003280260109a0441ff017121010240200328025c450d00200410290b20014102460d010240200241146a280200220441c40141c701200141017122011b470d00200228020c220241b584cc0041f985cc0020011b2201460d0220022001200410e707450d020b200041800e3b0001200041013a0000200041036a41033a00000c020b200041800e3b0001200041013a0000200041036a41013a00000c010b200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a42003703000b200341f0006a24000b8f1804057f017e077f017e230041f0006b2202240020012802202103200241086a41186a4200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030841b1dcc900ad4280808080f000841001220629000021072005200641086a290000370300200220073703082006102941b8dcc900ad4280808080a00184100122062900002107200241e0006a41086a2208200641086a2900003703002002200737036020061029200420022903602207370300200241c0006a41086a2005290300370300200241c0006a41106a2007370300200241c0006a41186a200829030037030020022002290308370340200241086a200241c0006a108d0220022802082205410120051b2106024002400240024002400240024002402003200229020c420020051b2207422088a7490d00200742ffffff3f83500d01200610290c010b2003200620034105746a10930621030240200742ffffff3f83500d00200610290b20030d010b200241086a41186a22054200370300200241086a41106a22064200370300200241086a41086a220342003703002002420037030841b1dcc900ad4280808080f000841001220829000021072003200841086a2900003703002002200737030820081029418886ca00ad4280808080c00184100122082900002107200241e0006a41086a2209200841086a290000370300200220073703602008102920042002290360370000200441086a22082009290300370000200241c0006a41086a220a2003290300370300200241c0006a41106a220b2006290300370300200241c0006a41186a220c2005290300370300200220022903083703402002200241c0006a412010fc01200128021c2002280204410020022802001b220d470d012005420037030020064200370300200342003703002002420037030841c6b7c700ad42808080808001841001220e29000021072003200e41086a29000037030020022007370308200e102941dcb7c700ad4280808080c000841001220e29000021072009200e41086a29000037030020022007370360200e10292004200229036037000020082009290300370000200a2003290300370300200b2006290300370300200c200529030037030020022002290308370340200241086a200241c0006a109e0320022802082204410120041b210c2001280224200229020c420020041b2207422088a72205470d0202402001280220220620054f0d00200c20064105746a220e0d040b20004180083b0001200041013a0000200041036a41003a00000c040b20004180063b0001200041013a0000200041036a41003a00000c040b20004180063b0001200041013a0000200041036a41003a00000c030b200041800e3b0001200041013a0000200041036a410a3a00000c010b2002410036021020024201370308200128020021030240410410272204450d002002410436020c2002200436020820042003360000200241043602102001280204210a2001410c6a2802002204200241086a1071024002400240200228020c2209200228021022036b2004490d00200228020821080c010b200320046a22082003490d012009410174220b2008200b20084b1b220b4100480d010240024020090d000240200b0d00410121080c020b200b102722080d010c040b200228020821082009200b460d0020082009200b102b2208450d030b2002200b36020c200220083602080b200820036a200a200410e4071a2002200320046a360210200141106a2802002103200141186a2802002204200241086a10710240024020040d00200228020c210920022802102104200d210b0c010b20032004410c6c6a210b03402003280200210a200341086a2802002204200241086a107102400240200228020c2206200228021022056b2004490d0020022802082108200621090c010b200520046a22082005490d03200641017422092008200920084b1b22094100480d030240024020060d00024020090d00410121080c020b200910272208450d060c010b2002280208210820062009460d00200820062009102b2208450d050b2002200936020c200220083602080b200820056a200a200410e4071a2002200520046a22043602102003410c6a2203200b470d000b2001280224210520012802202106200128021c210b0b02400240200920046b4104490d00200441046a2103200228020821082009210a0c010b200441046a22032004490d01200941017422082003200820034b1b220a4100480d010240024020090d000240200a0d00410121080c020b200a10272208450d040c010b200228020821082009200a460d0020082009200a102b2208450d030b2002200a36020c200220083602080b200820046a200b360000200220033602100240200a20036b41034b0d00200341046a22042003490d01200a41017422092004200920044b1b22044100480d0102400240200a0d00024020040d00410121080c020b200410272208450d040c010b200a2004460d002008200a2004102b2208450d030b2002200436020c200220083602080b200820036a20063600002002200341046a220636021002400240200228020c220920066b4104490d0020022802082104200921080c010b200641046a22042006490d01200941017422082004200820044b1b22084100480d010240024020090d00024020080d00410121040c020b200810272204450d040c010b2002280208210420092008460d00200420092008102b2204450d030b2002200836020c200220043602080b200420066a2005360000200141286a200341086aad4220862004ad84200e1017210302402008450d00200410290b0240024020034101470d00200241086a41086a427f3703002002413c6a4108360200200241286a4200370300200241206a4280808080c0003703002002427f370308200241c6b7c700360238200241013a003020024204370318411010272204450d0120024210370244200220043602404108200241c0006a10710240024020022802442208200228024822066b4108490d00200641086a210420022802402103200821050c010b200641086a22042006490d03200841017422032004200320044b1b22054100480d030240024020080d00024020050d00410121030c020b200510272203450d060c010b2002280240210320082005460d00200320082005102b2203450d050b20022005360244200220033602400b200320066a42c9dabdf2c6ad9ab7e500370000200220043602480240200520046b41034b0d00200441046a22062004490d03200541017422082006200820064b1b22064100480d030240024020050d00024020060d00410121030c020b200610272203450d060c010b20052006460d00200320052006102b2203450d050b20022006360244200220033602400b200320046a200d3600002002200441046a2203360248024002402002280244220920036b4120490d00200441246a210820022802402105200921060c010b200341206a22082003490d03200941017422042008200420084b1b22064100480d030240024020090d00024020060d00410121050c020b200610272205450d060c010b2002280240210520092006460d00200520092006102b2205450d050b20022006360244200220053602400b200241316a2109200520036a2204200e290000370000200441186a200e41186a290000370000200441106a200e41106a290000370000200441086a200e41086a2900003700000240200228022c22042002280228470d00200241246a20044101109d01200228022c21040b20022802242004410c6c6a220420083602082004200636020420042005360200200241c0006a41086a2204200241086a41186a2903003703002002200228022c41016a36022c200241c0006a41106a2203200241086a41206a29030037030020022002290318370340200220092900003703602002200941076a2900003700672002290308210f200041106a42b009370300200041086a200f370300200041306a41013a0000200041186a2002290340370300200041206a2004290300370300200041286a2003290300370300200041003a0000200041316a2002280260360000200041346a2002280063360000200742ffffff3f83500d05200c10290c050b20004180083b0001200041013a0000200041036a41003a00000c030b1039000b1032000b1030000b200742ffffff3f83500d00200c10290b200241f0006a24000ba50d02077f027e23004180016b2202240002400240024002400240024002400240024020012d0000417f6a220341024b0d0002400240024020030e03000301000b412010272203450d0520032001290001370000200341186a200141196a290000370000200341106a200141116a290000370000200341086a200141096a290000370000200241d8006a200341201096042003102941002104200241286a200141216a2002280258220320022802604180a6cc004100109704200241c0006a41086a200241336a290000370300200241c0006a41106a2002413b6a2f00003b01002002200229002b37034020022d002a210520022d0029210620022d002821010240200228025c450d00200310290b0c010b412010272203450d0420032001290001370000200341186a200141196a290000370000200341106a200141116a290000370000200341086a200141096a290000370000200241d8006a2003412010960420031029200241286a200141216a200228025822072002280260200141e4006a2203280200200141ec006a2201280200109704200241c0006a41086a200241336a290000370300200241c0006a41106a2002413b6a2f00003b01002002200229002b370340200128020021082003280200210420022d002a210520022d0029210620022d00282101200228025c450d00200710290b200241106a41106a200241c0006a41106a2f010022033b0100200241106a41086a200241c0006a41086a290300220937030020022002290340220a370310200241286a41106a220720033b0100200241286a41086a220320093703002002200a370328200141ff01714101470d04200241ca006a2003290300370100200241d2006a20072f01003b0100200220053a0041200220063a004020022002290328370142200241286a200241c0006a109804200241086a2002280228220320022802304180a6cc004100410010c701200228020821010240200228022c450d00200310290b20014101470d05200241286a41106a200241c0006a41106a280200360200200241286a41086a200241c0006a41086a29030037030020022002290340370328200241d8006a200241286a109904200228025822032002280260109a0441ff017121010240200228025c450d00200310290b20014102460d0102402004450d0041c40141c701200141017122011b2008470d0041b584cc0041f985cc0020011b22012004460d0320012004200810e707450d030b200041800e3b0001200041013a0000200041036a41033a00000c080b200041003b0001200041013a0000200041036a41003a00000c070b2004450d00200041800e3b0001200041013a0000200041036a41033a00000c060b410c10272206450d04200241286a41106a200241c0006a41106a280200360200200241286a41086a200241c0006a41086a29030037030020022002290340370328410a10272201450d002002420a37025c200220013602584106200241d8006a107102400240200228025c2204200228026022076b4106490d00200741066a210120022802582103200421050c010b200741066a22012007490d04200441017422032001200320014b1b22054100480d040240024020040d00024020050d00410121030c020b2005102722030d010c070b2002280258210320042005460d00200320042005102b2203450d060b2002200536025c200220033602580b200320076a220741002800dcf043360000200741046a41002f00e0f0433b00002002200136026002400240200520016b4114490d00200141146a21070c010b200141146a22072001490d04200541017422042007200420074b1b22044100480d040240024020050d00024020040d00410121030c020b200410272203450d070c010b20052004460d00200320052004102b2203450d060b2002200436025c200220033602580b200320016a22012002290328370000200141106a200241286a41106a280200360000200141086a200241286a41086a290300370000200241f0006a41086a2007360200200220022903582209370370200641086a200736020020062009370200200041306a41013a0000200041286a428180808010370200200041246a2006360200200041206a4100360200200041186a4204370300200041106a427f370300200041086a42e400370300200041003a0000200041316a2002280058360000200041346a200241db006a2800003600000c050b1039000b200041800e3b0001200041013a0000200041036a41003a00000c030b200041800e3b0001200041013a0000200041036a41013a00000c020b1032000b1030000b20024180016a24000ba50404047f017e017f027e23004180016b22012400200141286a41186a4200370300200141286a41106a22024200370300200141286a41086a220342003703002001420037032841b3e6ca00ad4280808080e000841001220429000021052003200441086a290000370300200120053703282004102941b4a0cb00ad4280808080b00184100122042900002105200141c8006a41086a2206200441086a2900003703002001200537034820041029200220012903482205370300200141086a41086a2003290300370300200141086a41106a2005370300200141086a41186a2006290300370300200120012903283703082001412036025c2001200141086a360258200141e0006a200141086aad42808080808004841007108b0202400240200128026022030d00420021070c010b2001280264210402400240200141e0006a41086a28020022024108490d002003290000210520024178714108460d0020032900082108420121070c010b20014100360250200142013703482001410d3602742001200141d8006a3602702001200141c8006a36027c2001413c6a41013602002001420137022c200141f4eaca003602282001200141f0006a360238200141fc006a41a8a3c800200141286a10371a200135025042208620013502488410080240200128024c450d00200128024810290b420021070b2004450d00200310290b200020084200200742005222031b37030820002005420020031b37030020014180016a24000bc20203047f017e017f230041d0006b22012400200141206a41186a4200370300200141206a41106a22024200370300200141206a41086a220342003703002001420037032041b3e6ca00ad4280808080e000841001220429000021052003200441086a290000370300200120053703202004102941b4a0cb00ad4280808080b00184100122042900002105200141c0006a41086a2206200441086a2900003703002001200537034020041029200220012903402205370300200141086a2003290300370300200141106a2005370300200141186a200629030037030020012001290320370300200029030021050240410810272203450d002003200537000020002903082105200341084110102b2200450d00200020053700082001ad42808080808004842000ad4280808080800284100320001029200141d0006a24000f0b1030000bad0204017f017e017f027e230041d0006b220224002002412036020420022001360200200241086a2001ad42808080808004841007108b0202400240200228020822010d00420021030c010b200228020c210402400240200241086a41086a2802004110490d00200141086a290000210520012900002106420121030c010b20024100360220200242013703182002410d36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241f4eaca003602382002200241286a360248200241346a41a8a3c800200241386a10371a200235022042208620023502188410080240200228021c450d00200228021810290b420021030b2004450d00200110290b2000200637030820002003370300200041106a2005370300200241d0006a24000bef3007017f017e017f027e017f027e1c7f23004180036b2207240002400240024002402001200284500d002003200484500d004201210820074198016a200320012003200156200420025620042002511b22091b220a2004200220091b220b20054201200542015620064200522006501b220c1b220520064200200c1b220610e00720074188016a200729039801220d20074198016a41086a290300220e2005200610d5072002200420091b21022001200320091b2104200a20072903880185200b20074188016a41086a290300858450450d01200d210a200e210b420021060c020b20004100360200200041106a4200370300200041086a42003703000c020b200741f8006a200420022005200610e007200741e8006a20072903782201200741f8006a41086a29030022032005200610d5074200200620042007290368852002200741e8006a41086a29030085845022091b21064201200520091b21082003200220091b21022001200420091b21040b200741386a200b42002004420010d507200741c8006a20024200200a420010d507200741d8006a200a42002004420010d5070240024002400240024002400240024002400240024002400240024002400240200b420052200242005271200729034042005272200729035042005272200741d8006a41086a2903002201200729033820072903487c7c2203200154724101470d00411010272209450d0d2007420437029c02200720093602980220074198026a41004104109801200741f0026a41086a220920072802a002220c41046a360200200728029802200c4102746a220c200a3e020c200c200a4220883e0208200c200b3e0204200c200b4220883e020020072007290398023703f002200741f0026a10c607200741a8016a41086a2009280200360200200720072903f0023703a80141101027220c450d0d2007420437029c022007200c3602980220074198026a41004104109801200920072802a002220c41046a360200200728029802200c4102746a220c20043e020c200c20044220883e0208200c20023e0204200c20024220883e020020072007290398023703f002200741f0026a10c607200741b8016a41086a2009280200360200200720072903f0023703b801411010272209450d0d2007420437029c02200720093602980220074198026a41004104109801200741f0026a41086a220c20072802a002220941046a36020020072802980220094102746a22092008a7220f36020c200920084220883e0208200920063e0204200920064220883e020020072007290398023703f002200741f0026a10c607200c280200211020072802f402211120072802f0022112200c200741b8016a41086a280200360200200720072903b8013703f00220074198026a41086a200741a8016a41086a280200360200200720072903a80137039802200741c8016a20074198026a200741f0026a10c807024020072802f40241ffffffff0371450d0020072802f00210290b200741c8016a10c60720104101460d0120072802cc01211320072802c80121142010450d0a2012280200450d0a024020072802d0012215450d002014280200450d0b201520104d0d0b200720103602d401201520106b221641016a22174101201741014b1b221841ffffffff03712018470d0320184102742219417f4c0d032019102d221a450d0e201041ffffffff03712010470d032010410274221b417f4c0d03201b102d221c450d0e4101210f410221092012280200220c67221d211e0240200c41ffffffff034b0d0041022109201d210c4101210f034020094101200c4101711b200f6c210f200c41034b211f200920096c2109200c410176221e210c201f0d000b0b200720153602f802200720133602f402200720143602f0024104211f41041027220c450d0f200c20094101201e4101461b200f6c220f360200200742818080801037029c022007200c36029802200741d8016a200741f0026a20074198026a10c807200c10290240201b450d00201b1027221f450d0f0b200741003602a0022007201b410276222036029c022007201f3602980220074198026a4100201010980120072802980220072802a00222094102746a2012201041027410e4071a200741f8026a200920106a36020020072007290398023703f002410410272209450d0f2009200f360200200742818080801037029c022007200936029802200741e8016a200741f0026a20074198026a10c80720091029024020072802d40120176a220920072802e001220c4d0d00200741003602a002200742043703980220074198026a41002009200c6b220c10980120072802a00221090240200c450d0020072802980220094102746a4100200c41027410e6071a2009200c6a21090b200741f0026a41086a220c200936020020072007290398023703f00220072802d801211f200741f0026a200920072802e001220f10980120072802f002200c28020022094102746a201f200f41027410e4071a200c2009200f6a220936020020074198026a41086a220c2009360200200720072903f00237039802024020072802dc0141ffffffff0371450d0020072802d80110290b200741d8016a41086a200c28020036020020072007290398023703d8010b20194102762121200741e8016a10c607024002400240024002400240024002400240024003402007201622223602f401024020072802e001220920072802d401220c20226a220f417f736a221f2009490d00201f200941cc8bcc001036000b0240024002400240024002400240024002400240024002400240024020092009200f6b220f4d0d0020072802f00122092009200c6b220c4d0d0120072802e801200c4102746a35020022024200510d02202220224100476b211620072802d8012209201f4102746a35020021012009200f4102746a3502002104200741003602f80120072004200142208684200280220137038002200741003602880220072004200120027e7d42ffffffff0f83370390022007200741f4016a3602ac022007200741d8016a3602a8022007200741d4016a3602a4022007200741e8016a3602a002200720074188026a36029c022007200741f8016a3602980220074198026a10c9071a034020072802880241016a41004c0d04024020072903900242ffffffff0f560d0020074198026a10c9070d010b0b200729038002210220072802f401210920072802d401210c200741003a00f8022007200c20096a3602f402200720093602f0022007200741d8016a3602fc02200741b0026a200741f0026a10cc0720072802f001220941ffffffff03712009470d1c2009410274220c417f4c0d1c20072802e801210f02400240200c0d004104211f0c010b200c1027221f450d280b200741003602f8022007201f3602f0022007200c4102763602f402200741f0026a4100200910980120072802f00220072802f802221f4102746a200f200c10e4071a200741e0026a41086a2223201f20096a360200200720072903f0023703e002410810272209450d2820092002a72224360204200920024220883e020020074282808080203702f402200720093602f002200741c0026a200741e0026a200741f0026a10c8072009102920072802b802221920072802c8022225201920254b1b22144101201441014b1b220c41ffffffff0371200c470d1c200c4102742226417f4c0d1c20072802b402212720072802b00221280240024020260d00410421290c010b2026102d2229450d280b2014450d062025417f6a221b20254b211520072802c002212a2019417f6a221720194b0d04200c417f6a2109202920266a417c6a211e4100210f4200210203404100211f024020192017200f6b22134d0d004100211f201320174b0d00202820134102746a280200211f0b201fad21044100211f024020150d002025201b200f6b22134d0d002013201b4b0d00202a20134102746a280200211f0b024002402004201fad22037d22012004560d00200120027d220a2001560d00200a42ffffffff0f832104420021020c010b20044280808080108420027d20037d2104420121020b200c20094d0d09201e20043e0200201e417c6a211e2009417f6a2109200f41016a220f2014490d000c060b0b200f200941cc8bcc001036000b200c200941cc8bcc001036000b41b08bcc00411941b08acc001033000b41cc8ccc004118200741f0026a41e48ccc0041f48ccc00103a000b200c417f6a2109202920266a417c6a211f4100211e4200210203404100210f024020150d004100210f2025201b201e6b22134d0d004100210f2013201b4b0d00202a20134102746a280200210f0b024002404200200fad22017d22044200520d00200420027d22032004560d00200342ffffffff0f832104420021020c010b428080808010200220017c7d2104420121020b200c20094d0d04201f20043e0200201f417c6a211f2009417f6a2109201e41016a221e2014490d000b0b41012113200250450d010b410021130b0240202741ffffffff0371450d00202810290b20072802d401221f20072802f401220f6a2215201f490d05200f20154f0d01200f417f7321090340200c200c200f6a20096a221e4d0d03200920072802e00122146a220f20094f0d0420072802d801200f4102746a2029201e4102746a2802003602002009417f6a210920072802f401210f201f417f6a221f0d000c050b0b2009200c41dc8bcc001036000b201f450d020c030b20252019202520194b1b22074101200741014b1b200f6a20096a200c41cc8bcc001036000b200f201441dc8bcc001036000b200c200c2015417f7322096a200f6a220f4d0d0220072802e001220c20096a2209200c4f0d0320072802d80120094102746a2029200f4102746a28020036020020072802f401210f0b2018200f417f736a220920184f0d03201a20094102746a202436020002402013450d00201820072802f401417f736a220920184f0d05201a20094102746a22092009280200417f6a36020020072802f401210920072802d401210c200741003a00f8022007200c20096a3602f402200720093602f0022007200741d8016a3602fc02200741d0026a200741f0026a10cc0720072802f001220941ffffffff03712009470d0f2009410274220c417f4c0d0f20072802e801210f02400240200c0d004104211f0c010b200c1027221f450d1b0b200741003602f8022007201f3602f0022007200c4102763602f402200741f0026a4100200910980120072802f00220072802f802221f4102746a200f200c10e4071a2023201f20096a360200200720072903f0023703e002200741f0026a200741e0026a200741d0026a10c707024020072802d401220920072802f40122146a220c2009490d00024002402014200c4f0d00200c417f73210920072802f002211320072802f802210f2014211f0340200f200f201f6a20096a221f4d0d0a200920072802e00122156a221e20094f0d0b20072802d801201e4102746a2013201f4102746a280200360200200941016a210920072802f401211f2014200c417f6a220c490d000c020b0b20090d0120072802f802210f2014211f0b201f2014417f7322096a220c200f6a221f200c4f0d0920072802e001220c20096a2209200c4f0d0a20072802d80120094102746a20072802f002201f4102746a2802003602000b024020072802f40241ffffffff0371450d0020072802f00210290b20072802d40241ffffffff0371450d0020072802d00210290b02402026450d00202910290b024020072802c40241ffffffff0371450d0020072802c00210290b20220d000b0240201d0d0020072802e001211020072802dc01212020072802d801210f201c1029410021090c130b4101210920072802d401220c4101460d114100200c6b2114201d411f7121134100201d6b411f7121152010410274201c6a417c6a210c417f210903400240200920072802e001221f6a220f2009490d00200f201f41cc8bcc001036000b201f200f417f6a221e4d0d09201020096a221f20104f0d0a200c20072802d801221f201e4102746a280200201574201f200f4102746a28020020137672360200200c417c6a210c20142009417f6a2209460d110c000b0b200f200c41cc8bcc001036000b2009200c41dc8bcc001036000b2009201841dc8bcc001036000b2009201841cc8bcc001036000b201f200f41cc8bcc001036000b201e201541dc8bcc001036000b201f200f41cc8bcc001036000b2009200c41dc8bcc001036000b200f417f6a201f41cc8bcc001036000b201f201041dc8bcc001036000b4100410041bc8ccc001036000b200741286a200729035820032008200610e00720004100360200200041106a200741286a41086a290300370300200041086a20072903283703000c0f0b20074198026a41086a200741c8016a41086a280200221f360200200720072903c80137039802201f4101201f41014b1b221e41ffffffff0371201e470d00201e410274221b417f4c0d0002400240201b0d00410421170c010b201b102d2217450d0c0b201f450d022017201e410274201f4102746b6a210c201f417f6a2114201e201f6b2113200f4101200f41014b1bad21024200210441002109200728029802210f0340201e201320096a22154d0d02200c2004422086200f35020084220420028022013e020020142009460d03200c41046a210c200f41046a210f2004200120027e7d2104201f200941016a22094b0d000b2009201f41cc8bcc001036000b1038000b2015201e41dc8bcc001036000b2007201e3602f8022007201b4102763602f402200720173602f002200728029c0241ffffffff0371450d0720072802980210290c070b20072802d40121090b20072802e001220c200c20096b220f4d0d012010201020096b22094d0d02201c20094102746a20072802d801200f4102746a280200201d411f717636020041012109201c210f0b024020072802ec0141ffffffff0371450d0020072802e80110290b2009450d0320072802dc0141ffffffff0371450d0320072802d80110290c030b200f200c41cc8bcc001036000b2009201041dc8bcc001036000b4100211a0240201341ffffffff0371450d00201410290b0b410410272209450d022009410036020041041027220c450d02200c41003602004101211e02400240201a0d002009211a4101212141012118200c210f41012120410121100c010b20091029200c10290b2007201836028002200720213602fc012007201a3602f801200720103602a0022007202036029c022007200f3602980220074198026a10c607420021020240024020072802a00222094105744180014d0d00421d21040c010b4100211e024020090d00420021040c010b200728029802220c200941027422096a417c6a220f280200211f0240200c200f470d00201fad21040c010b200c41786a210f201fad2104200741206a211f4120210c420021020340200741186a200f20096a3502004200200c41e0007110ea07201f29030020027c2007290318220220047c2204200254ad7c2102200c41206a210c2009417c6a22094104470d000b0b0240200728029c0241ffffffff0371450d0020072802980210290b201e0d030240200420084201882006423f8684562002200642018822045620022004511b450d0020074188026a41086a200741f8016a41086a280200360200200720072903f80137038802411010272209450d022007420437029c02200720093602980220074198026a41004104109801200741f0026a41086a220920072802a002220c41046a360200200728029802200c4102746a220c428080808010370208200c420037020020072007290398023703f002200741f0026a10c60720074198026a41086a2009280200360200200720072903f00237039802200741f8016a20074188026a20074198026a10c707200728029c0241ffffffff0371450d0020072802980210290b200741f0026a41086a200741f8016a41086a280200360200200720072903f8013703f0020b200741f0026a10c60720074198026a41086a2209200741f0026a41086a280200360200200720072903f0023703980220074198026a10c6074200210202400240200928020022094105744180014d0d00421d21044101211e0c010b4100211e024020090d00420021040c010b200728029802220c200941027422096a417c6a220f280200211f0240200c200f470d00201fad21040c010b200c41786a210f201fad2104200741106a211f4120210c420021020340200741086a200f20096a3502004200200c41e0007110ea07201f29030020027c2007290308220220047c2204200254ad7c2102200c41206a210c2009417c6a22094104470d000b0b0240200728029c0241ffffffff0371450d0020072802980210290b02400240201e450d00200041c88ecc00360204200041086a4119360200410121090c010b200041106a2002370300200041086a2004370300410021090b20002009360200201141ffffffff0371450d03201210290c030b1039000b1030000b200720043e029c022007419c8ccc003602980241f88dcc00412f20074198026a41a88ecc0041b88ecc00103a000b20074180036a24000bb10101027f024020002802082201450d0020002802002100200141246c210103400240024020002d0000220241044b0d0002400240024020020e050400010204040b2000410c6a280200450d03200041086a28020010290c030b2000410c6a280200450d02200041086a28020010290c020b2000410c6a280200450d01200041086a28020010290c010b200041086a280200450d00200041046a28020010290b200041246a21002001415c6a22010d000b0b0b800508017f017e047f017e017f017e037f017e23004180016b22022400200241186a2000200110810202402002290318a7450d00200241186a41106a290300210320022903202100200241d0006a41186a22044200370300200241d0006a41106a22054200370300200241d0006a41086a220642003703002002420037035041dcbec500ad42808080808001842201100122072900002108200241f0006a41086a2209200741086a29000037030020022008370370200710292006200929030037030020022002290370370350419fe3c200ad4280808080d00184220810012207290000210a2009200741086a2900003703002002200a3703702007102920052002290370220a370300200241306a41086a220b2006290300370300200241306a41106a220c200a370300200241306a41186a220d2009290300370300200220022903503703302002200241306a412010e301200241106a290300210a2002290308210e200228020021072004420037030020054200370300200642003703002002420037035020011001220429000021012009200441086a2900003703002002200137037020041029200620092903003703002002200229037037035020081001220429000021012009200441086a2900003703002002200137037020041029200520022903702201370300200b2006290300370300200c2001370300200d20092903003703002002200229035037033020024200200a420020071b220120037d200e420020071b2203200054ad7d2208200320007d2200200356200820015620082001511b22091b37035820024200200020091b370350200241306aad4280808080800484200241d0006aad428080808080028410030b20024180016a24000bb10503027f017e047f230041d0006b2202240041f5bec500ad4280808080800184100122032900002104200241086a41086a200341086a2900003703002002200437030820031029418cc1c200ad4280808080f00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000bbd920110027f017e087f017e017f027e037f017e0a7f037e087f027e017f027e037f017e23004180116b22002400200041003602b810200042083703b010200041003602c810200042013703c01041eebec500ad4280808080f00084100122012900002102200041b8016a41086a2203200141086a290000370300200020023703b8012001102941b8dcc900ad4280808080a00184100122012900002102200041f00a6a41086a2204200141086a290000370300200020023703f00a20011029024002400240024002400240412010272201450d00200120002903b801370000200120002903f00a370010200141086a2003290300370000200141186a22052004290300370000412010272203450d0020032001290000370000200341186a2005290000370000200341106a200141106a290000370000200341086a200141086a290000370000200041e0076a41026a2204200041f00c6a41026a2d00003a0000200020002f00f00c3b01e007200041a8096a41106a42a0808080800437030041002106200041003a00c009200020013602b409200042a080808080043702ac09200020033602a809200041c3096a20042d00003a0000200020002f01e0073b00c109200041f00c6a200041a8096a10b6010240024002400240024020002802f00c4101470d00200041f00c6a410472210741012108410821094100210a0340200041b8036a41206a200741206a280200360200200041b8036a41186a2201200741186a2902002202370300200041b8036a41106a2205200741106a290200220b370300200041b8036a41086a220c200741086a290200220d37030020002007290200220e3703b803200041b8016a41186a220f2002370300200041b8016a41106a2210200b370300200041b8016a41086a2211200d3703002000200e3703b801200041f00c6a41186a22032001290300370300200041f00c6a41106a22042005290300370300200041f00c6a41086a2205200c290300370300200020002903b8033703f00c200041b8016a10e101210241201027220c450d02200c20002903b801370000200c41186a200f290300370000200c41106a2010290300370000200c41086a2011290300370000200041f00a6a41086a2005290300220b370300200041f00a6a41106a2004290300220d370300200041f00a6a41186a2003290300220e370300200020002903f00c22123703f00a2003200e3703002004200d3703002005200b370300200020123703f00c0240200a20002802b410470d00200041b0106a200a410110a80120002802b010210920002802b810210a0b2009200a41386c6a22012002370300200529030021022004290300210b2003290300210d20002903f00c210e2001412c6a4281808080103702002001200c3602282001200e370308200141206a200d370300200141186a200b370300200141106a20023703002000200a41016a220a3602b8102003200f2903003703002004201029030037030020052011290300370300200020002903b8013703f00c0240200620002802c410470d00200041c0106a20064101109e0120002802c010210820002802c81021060b200820064105746a220120002903f00c370000200141186a2003290300370000200141106a2004290300370000200141086a20052903003700002000200641016a22063602c810200041f00c6a200041a8096a10b60120002802f00c4101460d000b0b024020002802ac09450d0020002802a80910290b024020002802b809450d0020002802b40910290b41eebec500ad4280808080f00084100122012900002102200041b8016a41086a2203200141086a290000370300200020023703b8012001102941f5b7c000ad4280808080a00184100122012900002102200041f00a6a41086a2204200141086a290000370300200020023703f00a20011029412010272201450d04200120002903b801370000200120002903f00a370010200141086a2003290300370000200141186a22052004290300370000412010272203450d0420032001290000370000200341186a2005290000370000200341106a200141106a290000370000200341086a200141086a290000370000200041e0056a41026a2205200041f00c6a41026a2d00003a0000200020002f00f00c3b01e005200041f00c6a41106a220442a08080808004370300200041003a00880d200020013602fc0c200042a080808080043702f40c200020033602f00c2000418b0d6a20052d00003a0000200020002f01e0053b00890d200041b0106a200041f00c6a109702200041f00c6a41186a2206420037030020044200370300200041f00c6a41086a22014200370300200042003703f00c41eebec500ad4280808080f00084220210012205290000210b200041b8016a41086a2203200541086a2900003703002000200b3703b8012005102920012003290300370300200020002903b8013703f00c419cf3c100ad4280808080e001841001220c290000210b200041f00a6a41086a2205200c41086a2900003703002000200b3703f00a200c1029200420002903f00a220b370300200041b8036a41086a22072001290300370300200041b8036a41106a220a200b370300200041b8036a41186a220f2005290300370300200020002903f00c3703b803200041b0016a200041b8036a412010fc0120002802b401211320002802b0012114200642003703002004420037030020014200370300200042003703f00c20021001220c29000021022003200c41086a290000370300200020023703b801200c102920012003290300370300200020002903b8013703f00c41c4f3c100ad4280808080d002841001220329000021022005200341086a290000370300200020023703f00a20031029200420002903f00a220237030020072001290300370300200a2002370300200f2005290300370300200020002903f00c3703b803200041a8016a200041b8036a412010fc0120002802ac01210520002802a801210c20002802c010211520002802c410211620002802b010211720002802b410211820002802c810210120002802b8102119200041003602e807200041003602e007201920016aad42e0007e2202422088a70d052002a72203417f4c0d054108210402402003450d00200310272204450d050b20054104200c1b221a41014b211b200041003602b009200020043602a8092000200341e0006e3602ac09200041003602f80a200042083703f00a200041f00a6a410020014105742205410575108c0120002802f80a210902402001450d00200541606a410576211c20002802f00a200941d8006c6a210c200041a00d6a2103200041980d6a210841002104201521010340200041d0106a41186a2206200141186a2207290000370300200041d0106a41106a220a200141106a220f290000370300200041d0106a41086a2210200141086a2211290000370300200020012900003703d010200041b8036a41186a2007290000370300200041b8036a41106a200f290000370300200041b8036a41086a2011290000370300200020012900003703b803200041e0076a200041b8036a200410d702200041f00c6a41086a4200370300200041f00c6a41106a4200370300200041f00c6a41186a4200370300200041f00c6a41206a420037030020084200370300200341186a2006290300370300200341106a200a290300370300200341086a2010290300370300200320002903d010370300200042003703f00c200c200041f00c6a41d00010e407220c41d0006a41003a0000200c41d8006a210c200141206a2101200441016a2104200541606a22050d000b2009201c6a41016a21090b201a4101201b1b2101200020093602f80a0240201641ffffff3f71450d00201510290b200041b8016a41086a200041f00a6a41086a2802002203360200200020002903f00a3703b8010240024020032001490d00200041a8096a20002802b009201941386c220341386d10a70120002802a809210420002802b0092101200041840d6a200041b8016a3602002000201720036a3602fc0c200020173602f80c200020183602f40c200020173602f00c2000200041e0076a3602800d200041b8036a41086a20013602002000200041b0096a3602bc0320002004200141e0006c6a3602b803200041f00c6a200041b8036a10d8022013410020141b2218ad42307e2202422088a70d072002a72203417f4c0d0720002802c00121010240024020030d00410821080c010b200310272208450d070b200041003602f810200020083602f0102000200341306e3602f4102018412c6c2203417f4c0d070240024020030d00410421130c010b200310272213450d070b41002117200041003602a806200020183602a406200020133602a006410021142001201820012018491b221c0d010c040b024020002802bc012201450d00200141d8006c450d0020002802b80110290b024020002802b0092201450d00200141e0006c210320002802a80941346a21010340024020012802002204450d00200441c8006c450d002001417c6a28020010290b200141e0006a2101200341a07f6a22030d000b0b024020002802ac092201450d00200141e0006c450d0020002802a80910290b200041e0076a10d40102402019450d00201941386c21032017412c6a210103400240200128020041ffffff3f71450d002001417c6a28020010290b200141386a2101200341486a22030d000b0b410021082018450d02201841386c450d02201710290c040b200041f0056a41186a2116200041f0056a41106a211a200041f0056a41086a211b41002115034020002802b801210402402001450d00200141d8006c21032004210103400240200141d0006a2d00000d0002400240200141206a290300220b200141286a290300220d8450450d0042002102427f210b427f210d0c010b427f210220004198016a427f427f200b200d10e00720004198016a41086a290300210d200029039801210b0b2001200b3703002001200d370308200141106a2002370300200141186a20023703000b200141d8006a2101200341a87f6a22030d000b0b0240024020002802b0092201450d0020002802a8092205200141e0006c6a210a0340024020052802382201450d00200141c8006c2104200528023041206a2101034020002802c001220c200128020022034d0d04024020002802b801200341d8006c6a22032d00500d0020032903202202200341286a290300220b84500d00200041f00c6a2005290310200541186a2903002005290300200541086a2903002002200b10d202200320032903002202427f2002427f20002903f80c20002802f00c410146220c1b220d7c220b200b2002542206200341086a22072903002202427f200041f00c6a41106a290300200c1b220e7c2006ad7c220b200254200b2002511b220c1b200d200e845022061b37030020072002427f200b200c1b20061b3703000b200141c8006a2101200441b87f6a22040d000b0b200541e0006a2205200a470d000b20002802b80121040b201541016a211520002802c00141d8006c2101200441a87f6a210303402001450d05200141a87f6a2101200341d8006a2103200441d0006a2105200441d8006a220c210420052d00000d000b02402001450d00200341186a2903002102200341106a290300210b200341086a290300210d2003290300210e4100210403400240200c20046a220541d0006a2d00000d00200541086a2903002212200d200e200d200b20022005290300221d2012200541106a290300221e200541186a290300221f10d90241ff017141014622061b210d201d200e20061b210e201f200220061b2102201e200b20061b210b2005200320061b21030b2001200441d8006a2204470d000b2003450d050b200341013a0050024020002802b0092201450d0020002802a8092204200141e0006c6a21192003410c6a2110200341306a21110340200441e0006a2109024020042802382205450d0020042802302101200541c8006c210503400240024020102001460d00200141246a2011412010e7070d010b200441186a220c290300210e200341086a220629030021022004290310210d2003290300210b20032903102112200141186a200341186a2207290300370300200141106a20123703002001200242002002200e7d200b200d54ad7d2212200b200d7d221d200b56201220025620122002511b220a1b200d200e8450220f1b3703082001200b4200201d200a1b200f1b370300200629030021022007290300210b2003290300210d20042003290310370320200441286a200b3703002004200d370310200c20023703000b200141c8006a2101200541b87f6a22050d000b0b2009210420092019470d000b0b2016200341c8006a290000370300201a200341c0006a290000370300201b200341386a290000370300200020032900303703f005200341286a29030021022003290320210b0240201420002802f410470d00200041f0106a2014410110900120002802f010210820002802f81021140b2008201441306c6a220120002903f005370300201b290300210d201a290300210e201629030021122001200b370320200141286a2002370300200141186a2012370300200141106a200e370300200141086a200d3703002000201441016a22143602f8102015201c4f0d0420002802c00121010c010b0b2003200c418cf0c9001036000b1030000b0c010b024020002802b0092201450d0020002802a8092210200141e0006c6a2115201441306c2119200041c4036a221841186a2116201841106a211a201841086a211b4100211703402018201029003c3700002016201041d4006a290000370000201a201041cc006a290000370000201b201041c4006a290000370000200041003602c003200042023703b803024020102802382201450d002010280230220a200141c8006c6a2111201041106a2109410021074102210f0340200a220641246a2104200641c8006a210a410021052019210320082101024003402003450d01024020042001460d0020012004412010e707210c200541016a2105200341506a2103200141306a2101200c0d010b0b41ffff03210302402009200610da020d00410021032006290310201029032085200641186a290300201041286a29030085844200520d00200041f00c6a42ffff0342002006290300200641086a2903002009290300200941086a29030010d202427f20002903f80c20002802f00c41014622011b2202a7417f200242808004544100427f200041f00c6a41106a29030020011b501b1b21030b200041f00a6a41186a22042006413c6a290000370300200041f00a6a41106a2205200641346a290000370300200041f00a6a41086a220c2006412c6a290000370300200020062900243703f00a0240200720002802bc03470d00200041b8036a2007410110a60120002802b803210f20002802c00321070b200f200741226c6a220120002903f00a370100200c29030021022005290300210b2004290300210d200120033b0120200141186a200d370100200141106a200b370100200141086a20023701002000200741016a22073602c0030b200a2011470d000b0240024002402007450d002007417f200741808004491b210602400240200741226c22040d00410021030c010b200f41206a2101410021030340417f2003411074220320012f01004110746a220520052003491b4110762103200141226a21012004415e6a22040d000b0b200641ffff03712201450d012003417f73220a41ffff0371220320016e210c0240200120034b0d00200f41206a210141002103034020072003460d042001417f20012f01004110742204200c4110746a220520052004491b4110763b0100200141226a21012007200341016a2203470d000b0b0240200a200c20066c6b41ffff03712205450d00410021010340200f200120077041226c6a2203417f20032f01204110742203418080046a220420042003491b4110763b0120200141016a22012005490d000b0b200041f00c6a41286a2203200041b8036a41286a280200360200200041f00c6a41206a2204200041b8036a41206a290300370300200041f00c6a41186a2205200041b8036a41186a290300370300200041f00c6a41106a220c200041b8036a41106a290300370300200041f00c6a41086a2206200041b8036a41086a290300370300200020002903b8033703f00c0240201720002802a406470d00200041a0066a2017410110930120002802a006211320002802a80621170b20132017412c6c6a220120002903f00c370200200141286a2003280200360200200141206a2004290300370200200141186a2005290300370200200141106a200c290300370200200141086a20062903003702002000201741016a22173602a8060c030b20002802bc032201450d02200141226c450d02200f10290c020b41d0dbc900411941a0f1c9001033000b20032007419cf0c9001036000b201041e0006a22102015470d000b20002802a40621180b20002802f4102105024020002802bc012201450d00200141d8006c450d0020002802b80110290b024020002802b0092201450d00200141e0006c210320002802a80941346a21010340024020012802002204450d00200441c8006c450d002001417c6a28020010290b200141e0006a2101200341a07f6a22030d000b0b024020002802ac092201450d00200141e0006c450d0020002802a80910290b200041e0076a10d4010b024020080d00410321050c060b200041e0076a41186a220c4200370300200041e0076a41106a22204200370300200041e0076a41086a22014200370300200042003703e00741eebec500ad4280808080f00084220b1001220329000021022001200341086a290000370300200020023703e0072003102941c6b8c000ad4280808080a00284100122042900002102200041f0056a41086a2203200441086a290000370300200020023703f00520041029202020002903f0052202370300200041a0066a41086a22072001290300370300200041a0066a41106a220a2002370300200041a0066a41186a220f2003290300370300200020002903e0073703a006200041f00a6a200041a0066a108d0202400240024020002802f00a2206450d00200020002902f40a220d3702c405200020063602c005200c42003703002020420037030020014200370300200042003703e007200b1001220429000021022001200441086a290000370300200020023703e0072004102941d8b8c000ad4280808080a002841001220429000021022003200441086a290000370300200020023703f00520041029202020002903f005370000202041086a200329030037000020072001290300370300200a2020290300370300200f200c290300370300200020002903e0073703a006200041f00a6a200041a0066a108d02024020002802f00a2201450d00200020002902f40a3702d405200020013602d005200041003602f80a200042013703f00a200041f00a6a4100201441306c220441306d109e0120002802f80a212102402014450d0020002802f00a20214105746a2101200821030340200341086a2900002102200341106a290000210b2003290000210d200141186a200341186a290000370000200141106a200b370000200141086a20023700002001200d370000202141016a2121200141206a2101200341306a2103200441506a22040d000b0b200020213602f80a02402005450d00200541306c450d00200810290b20002802f40a212220002802f00a2123200041003602e807200042043703e007200041e0076a41002017412c6c2203412c6d10930120002802e007210420002802e80721012000201320036a3602fc0a200020133602f80a200020183602f40a200020133602f00a2000200041a0066a3602800b200041a8096a41086a20013602002000200041e0076a41086a3602ac09200020042001412c6c6a3602a809200041f00a6a200041a8096a10b802200041e0056a41086a20002802e8072201360200200020002903e00722023703e005200041f00a6a202320212002a722242001109a02200041b0106a41086a200041f00a6a41086a220a280200360200200020002903f00a3703b01010092203280000210420031029200441067022250d02410021260c030b200d42ffffff3f83500d00200610290b02402005450d00200541306c450d00200810290b02402017450d002017412c6c21032013210103400240200141046a2802002204450d00200441226c450d00200128020010290b2001412c6a2101200341546a22030d000b0b410521052018450d072018412c6c450d07201310290c070b41002126024003402001450d0120242001412c6c6a212742002128420021290240034002400240202441086a222a28020041306c22030d004200210b420021020c010b202428020041206a21014200210b420021020340427f2002200141086a2903007c200b20012903007c220d200b542204ad7c220b2004200b200254200b2002511b22041b2102427f200d20041b210b200141306a2101200341506a22030d000b0b2000200041b0106a3602e0074200212b4200212c02400240202a28020022014102490d002024280200210802400240200141306c22050d004200210e4200210d0c010b200841206a21014200210e200521034200210d0340427f200d200141086a2903007c200e20012903007c2212200e542204ad7c220e2004200e200d54200e200d511b22041b210d427f201220041b210e200141306a2101200341506a22030d000b0b2024410c6a2106200820056a21112008210f0240024002400240024002400240024003400240200f220c2011470d004100212d4108212e0c020b200c41306a210f200c41206a290300200c41286a29030084500d0020002802b0102207450d0020002802b41021100340200741086a210320072f010622094105742101410021040240024003402001450d01200c2003412010e7072205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21090b2010450d022010417f6a2110200720094102746a41c8056a28020021070c010b0b0b200720044105746a220141f0026a2903002112200141e8026a290300211d41101027222e450d0f202e201d370300202e201237030820004281808080103702f40a2000202e3602f00a4101211902400340200f220c2011460d01200c41306a210f200c41206a290300200c41286a29030084500d0020002802e00722012802002207450d00200128020421100340200741086a210320072f010622094105742101410021040240024003402001450d01200c2003412010e7072205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21090b2010450d022010417f6a2110200720094102746a41c8056a28020021070c010b0b200720044105746a220141f0026a2903002112200141e8026a290300211d0240201920002802f40a470d00200041f00a6a2019410110920120002802f00a212e0b202e20194104746a220120123703082001201d3703002000201941016a22193602f80a0c000b0b20002802f40a212d20190d010b200b212b2002212c0c010b20194104742203450d01202e2109024020194101460d00202e41106a2101200341706a2103202e21090340200920012009290300200129030056200941086a2903002212200141086a290300221d562012201d511b1b2109200141106a2101200341706a22030d000b2009450d020b20002802e007211803402008220c2011460d03200c41306a210820182802002219450d002019210720182802042217210f0340200741086a210320072f010622104105742101410021040240024003402001450d01200c2003412010e7072205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d02200f417f6a210f200720104102746a41c8056a28020021070c010b0b0b200720044105746a220141f0026a2903002112200141e8026a290300211d024020082011460d0003402008220c41306a2108201921072017210f02400340200741086a210320072f010622104105742101410021040240024003402001450d01200c2003412010e7072205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d02200f417f6a210f200720104102746a41c8056a28020021070c010b0b200720044105746a220141f0026a290300221e2012201d200141e8026a290300221f562012201e562012201e511b22011b2112201f201d20011b211d0b20082011470d000b0b427f4200200941086a290300221e20127d20092903002212201d54ad7d221f2012201d7d221d201256201f201e56201f201e511b22011b221242002002200d7d200b200e54ad7d220d200b200e7d220e200b56200d200256200d2002511b22031b7c4200201d20011b220d4200200e20031b7c220e200d542201ad7c220d2001200d201254200d2012511b22011b212c427f200e20011b212b0b202428020021010240202a280200220341306c2204450d00200120046a211c03402001210c024020002802e00722012802002207450d002001280204210f0340200741086a210320072f010622104105742101410021040240024003402001450d01200c2003412010e7072205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d02200f417f6a210f200720104102746a41c8056a28020021070c010b0b200720044105746a220141e8026a220342002003290300220d200c29032022127d220e200e200d56200141f0026a2203290300220e200c41286a2903007d200d201254ad7d220d200e56200d200e511b22041b37030020034200200d20041b37030020014180036a222f2802002207450d00200141f8026a28020021014100210341002104034002400240024020062001460d0020012006412010e707450d0020030d01410021030c020b200341016a21030c010b200420036b220520074f0d07200041f00a6a41286a220f2001200341506c6a220541286a2210290300370300200041f00a6a41206a2211200541206a2208290300370300200041f00a6a41186a2209200541186a2219290300370300200041f00a6a41106a2217200541106a2218290300370300200a200541086a2215290300370300200020052903003703f00a200141086a2216290300210d200141106a221a290300210e200141186a221b2903002112200141206a2213290300211d200141286a2214290300211e200520012903003703002010201e3703002008201d370300201920123703002018200e3703002015200d3703002014200f29030037030020132011290300370300201b2009290300370300201a20172903003703002016200a290300370300200120002903f00a3703000b200141306a21012007200441016a2204470d000b2003450d00202f280200200720036b2201490d00202f20013602000b200c4200370320200c41286a4200370300200c41306a2201201c470d000b202a2802002103202428020021010b2000200041e0076a3602a8092000200041a8096a3602f00a20012003200041f00a6a410041202003676b10db02202a2802002215417f6a21182024280200220c201541306c22016a2109024020010d004200210d4200210e0c050b20002802e007221728020021194200210d410021084200210e200c2107034002402019450d00201728020421102019210f0340200f41086a2103200f2f010622114105742101410021040240024003402001450d0120072003412010e7072205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21110b2010450d022010417f6a2110200f20114102746a41c8056a280200210f0c010b0b200041e8006a200f20044105746a220141f0026a290300223042002008ad2212420010d50720004188016a200141e8026a290300221e42002012420010d507200041f8006a42004200201e420010d5074200427f20002903880120002903702000290380018442005220004188016a41086a2903002212200029036820002903787c7c221d2012547222011b2212200d7d221f201f201256427f201d20011b221d200e7d2012200d54ad7d2212201d562012201d511b22011b200b564200201220011b221220025620122002511b0d05427f200e20307c200d201e7c2212200d542201ad7c220d2001200d200e54200d200e511b22011b210e427f201220011b210d0b200841016a2108200741306a22072009470d000c050b0b41f8f1c900413041a8f2c9001057000b41b8f2c900413241ecf2c9001057000b200520074180bdc7001036000b41002008417f6a2201200120084b1b21180b201520184d0d01200041386a200c201841306c6a220141286a290300221e4200201841016a2211ad2212420010d507200041d8006a2001290320221d42002012420010d507200041c8006a42004200201d420010d5074200427f2002200e7c200b200d7c220d200b542201ad7c220b2001200b200254200b2002511b22011b2202427f200041d8006a41086a290300220b200029033820002903487c7c220e2000290340200029035084420052200e200b547222031b7d427f200d20011b220b427f200029035820031b220e54ad7d220d200b200e7d220e200b56200d200256200d2002511b22011b211f4200200e20011b213002400340200c2009460d012011417f6a2111024020002802e00722012802002207450d002001280204210f0340200741086a210320072f010622104105742101410021040240024003402001450d01200c2003412010e7072205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d02200f417f6a210f200720104102746a41c8056a28020021070c010b0b200041286a2030201f2012420010e007200c41286a220f4200427f200041286a41086a2903002202201e7c2000290328220b201d7c220d200b542201ad7c220b2001200b200254200b2002511b22051b2202200720044105746a220141f0026a22032903007d427f200d20051b220b200141e8026a2204290300220e54ad7d220d200b200e7d220e200b56200d200256200d2002511b22051b220b370300200c4200200e20051b22023703202004427f2004290300220d20027c22022002200d54220520032903002202200b7c2005ad7c220b200254200b2002511b22051b3703002003427f200b20051b370300200041d0106a41186a2207200641186a290000370300200041d0106a41106a2210200641106a290000370300200041d0106a41086a2208200641086a290000370300200020062900003703d010200141f8026a2105200f2903002102200c290320210b024020014180036a22032802002204200141fc026a280200470d00200520044101109001200328020021040b2005280200200441306c6a220120002903d0103703002001200b370320200141186a2007290300370300200141106a2010290300370300200141086a2008290300370300200141286a20023703002003200328020041016a3602000b200c41306a210c20110d000b0b202d41ffffffff0071450d00202e10290b202c2029202b202856202c202956202c2029511b22011b2129202b202820011b21282024412c6a22242027460d020c010b0b2018201541fcf2c9001036000b0240202641016a222620254f0d002028202984500d0020002802e005212420002802e80521010c010b0b20002802e805210120002802e00521240c010b202641016a2126410021010b200020263602ec05200041e0056a10dc0220002802e405212a200041003602c810200042043703c010200041c0106a41002001412c6c2203412c6d109301202420036a211a20002802c810211502400240024020010d002024210f0c010b20002802c0102015412c6c6a2111200041a0066a41186a211b200041a0066a41106a2113200041a0066a41086a21142024210f0340200f2802082104200f2802042116200f2802002118201b200f41246a2902003703002013200f411c6a2902003703002014200f41146a2902003703002000200f29020c3703a006200f412c6a210f2018450d01200041f0056a41186a221c201b290300370300200041f0056a41106a222f2013290300370300200041f0056a41086a222e2014290300370300200020002903a0063703f0052018200441306c22036a21050240024020030d00420021024200210b0c010b201841206a2101420021024200210b0340200141086a290300200b7c2001290300220b20027c2202200b54ad7c210b200141306a2101200341506a22030d000b0b02400240024020052018460d00200441306c2103201821010340200141286a290300210d200141206a290300210e200041d0106a41186a220c200141186a290300370300200041d0106a41106a2206200141106a290300370300200041d0106a41086a2207200141086a290300370300200020012903003703d010200e200d2002200b10dd02220441ffff03710d02200141306a2101200341506a22030d000b0b4200210d410021014102211002402016450d00201641306c450d00201810294200210d0b4200211d410021050c010b200041e0076a41086a22052007290300370300200041e0076a41106a220a2006290300370300200041e0076a41186a2208200c290300370300200020002903d010220d3703a8092000200d3703e007412210272210450d04201020002903e007370100201020043b0120201041186a2008290300370100201041106a200a290300370100201041086a200529030037010020004281808080103702f410200020103602f0102004ad210d0240024020034130470d00200d42ffff0383210d4200211d410121050c010b200341a07f6a2117200d42ffff0383210e4200211d41012105410021040340200120046a220341d8006a290300210d200341d0006a2903002112200c200341c8006a2903003703002006200341c0006a2903003703002007200341386a2903003703002000200341306a2903003703d010024002402012200d2002200b10dd02220a41ffff03710d00200e210d20172004460d030c010b200041a8096a41086a2007290300220d370300200041a8096a41106a20062903002212370300200041a8096a41186a200c290300221e370300200020002903d010221f3703a809200041f00a6a41186a2208201e370300200041f00a6a41106a22092012370300200041f00a6a41086a2219200d3703002000201f3703f00a200e200aad42ffff03837c220d200e54ad210e0240200520002802f410470d00200041f0106a2005410110a60120002802f01021100b201d200e7c211d2010200541226c6a220320002903f00a3701002019290300210e200929030021122008290300211e2003200a3b0120200341186a201e370100200341106a2012370100200341086a200e3701002000200541016a22053602f81020172004460d020b200441306a2104200d210e0c000b0b02402016450d00201641306c450d00201810290b20002802f41021010b0240024042ffff03200d7d220b42ffff03564200201d200d42ffff0356ad7c7d220242005220025022031b4101470d00200d4281807c7c2202200d56201d200d42ffff0354ad7d220b201d56200d42feff03561b0d012005450d01200541226c20106a417e6a2203410020032f010041107422032002a7417f200242808004544100200b501b1b4110746b2204200420034b1b4110763b01000c010b2005450d00200541226c20106a417e6a2204417f20042f01004110742204200ba7417f200b4280800454410020031b1b4110746a220320032004491b4110763b01000b200041f00a6a41186a2203201c290300370300200041f00a6a41106a2204202f290300370300200041f00a6a41086a220c202e290300370300200020002903f0053703f00a201120013602042011200536020820112010360200201120002903f00a37020c201141146a200c2903003702002011411c6a2004290300370200201141246a2003290300370200201541016a21152011412c6a2111200f201a470d000b200020153602c8100c010b200020153602c810200f201a460d000340200f2201412c6a210f0240200141046a2802002203450d00200341306c450d00200128020010290b201a200f470d000b0b0240202a450d00202a412c6c450d00202410290b2015ad422c7e2202422088a70d012002a72201417f4c0d0120002802c410211720002802c01021090240024020010d00410421030c010b200110272203450d010b200041003602e807200020033602e00720002001412c6e3602e407200041e0076a4100201510930120002802e80721010240024020150d0020002802e00721080c010b20092015412c6c6a211120002802e00722082001412c6c6a210620012015410274417c6a4102766a2119200041fc0a6a2107200041d0106a41186a210a200041d0106a41106a210f200041d0106a41086a21102009210c0340200a200c41246a290200370300200f200c411c6a2902003703002010200c41146a2902003703002000200c29020c3703d010200c2802082203ad42227e2202422088a70d032002a72204417f4c0d03200c28020021010240024020040d00410221050c010b200410272205450d030b200c412c6a210c200041003602b009200020053602a8092000200441226e3602ac09200041a8096a4100200310a60120002802b009210402402003450d00200341226c210520002802a809200441226c6a21030340200141086a2901002102200141106a290100210b200141186a290100210d2001290100210e200341206a200141206a2f01003b0100200341186a200d370100200341106a200b370100200341086a20023701002003200e370100200341226a2103200441016a2104200141226a21012005415e6a22050d000b0b200041f00a6a41086a22012004360200200020002903a80922023703f00a200741186a200a290300370200200741106a200f290300370200200741086a2010290300370200200720002903d010370200200641286a200041f00a6a41286a280200360200200641206a200041f00a6a41206a290300370200200641186a200041f00a6a41186a290300370200200641106a200041f00a6a41106a290300370200200641086a2001290300370200200620023702002006412c6a2106200c2011470d000b201941016a21010b20002802e407210441002103200041003602e807200042043703e007200041e0076a41002001412c6c2205412c6d10930120002802e007210c20002802e80721012000200820056a3602fc0a200020083602f80a200020043602f40a200020083602f00a2000200041a0066a3602800b200041a8096a41086a20013602002000200041e0076a41086a3602ac092000200c2001412c6c6a3602a809200041f00a6a200041a8096a10b80220002802e4072111200041f00a6a2023202120002802e007221920002802e8072208109a0220002802f80a211020002802f40a210a02400240024020002802f00a220f450d000240200a450d00200a2101200f2103034020032802c80521032001417f6a22010d000b200f2101200a21040340200120012f01064102746a41c8056a28020021012004417f6a22040d000b200041f00a6a21040c020b200041f00a6a2104200f2103200f21010c010b200041003602f40a200041f00a6a21040c010b200020013602f40a200041fc0a6a20012f0106360200200041003602f80a200041003602f00a0b200041a8096a41086a200441086a290200220237030020002004290200220b3703a809200041f00a6a41186a20023703004200211d200042003703f80a200020033602f40a200041003602f00a2000200b3703800b200020103602900b0240024020100d00427f211e4200210d4200211f4200210e427f21120c010b20002010417f6a3602900b200041f00a6a410020031b220c2802002104200c28020821060240024002400240200c28020c2205200c28020422012f01064f0d00200121030c010b034020012802002203450d02200441016a210420012f0104210520032101200520032f01064f0d000b0b2005ad4220862006ad8421020c010b2006ad2102410021030b2002422088a7220641016a21052002a721070240024020040d00200321010c010b200320054102746a41c8056a2802002101410021052004417f6a2204450d00034020012802c80521012004417f6a22040d000b0b200c200536020c200c2007360208200c2001360204200c4100360200200320064105746a41e8026a2101427f211e427f21124200211f4200210e4200211d4200210d0340200041086a200141086a290300220242002001290300220b420010d507200041186a200b4200200b420010d507427f200d427f200041186a41086a29030022302000290308222c202c7c7c222c20022000290310222984202984420052202c2030547222011b7c201d427f200029031820011b7c2230201d542201ad7c221d2001201d200d54201d200d511b22011b210d427f203020011b211d20022012200b201e54200220125420022012511b22011b2112200b201e20011b211e427f200e20027c201f200b7c220b201f542201ad7c220220012002200e542002200e511b22011b210e427f200b20011b211f20002802900b2201450d0120002001417f6a3602900b200041f00a6a410020002802f40a1b220c2802002104200c2802082106024002400240200c28020c2205200c28020422012f01064f0d00200121030c010b0240034020012802002203450d01200441016a210420012f0104210520032101200520032f0106490d020c000b0b2006ad2102410021030c010b2005ad4220862006ad8421020b2002422088a7220641016a21052002a721070240024020040d00200321010c010b200320054102746a41c8056a2802002101410021052004417f6a2204450d00034020012802c80521012004417f6a22040d000b0b200c200536020c200c2007360208200c2001360204200c4100360200200320064105746a41e8026a21010c000b0b20004198066a200d370300200041f0056a41186a200e3703002000201d370390062000201f370380062000201e3703f005200020123703f80502400240200f0d0041002110200041840b6a4100360200200041003602f40a0c010b02400240200a0d00200f21010c010b200a2101200f2103034020032802c80521032001417f6a22010d000b200f21010340200120012f01064102746a41c8056a2802002101200a417f6a220a0d000b2003210f0b2000418c0b6a20012f0106360200200041880b6a4100360200200041840b6a2001360200200041003602800b200042003703f80a2000200f3602f40a200041003602f00a0b200020103602900b200041f00a6a10b90202402008450d002008412c6c21032019210103400240200141046a2802002204450d00200441306c450d00200128020010290b2001412c6a2101200341546a22030d000b0b02402011450d002011412c6c450d00201910290b200020153602d810200020173602d410200020093602d010200041f00a6a200041d0106a200041d0056a200041c0056a10880220002d00f00a4101460d02200041a8096a41026a200041f00a6a41047241c00110e4071a200041e0076a200041a8096a41c20110e4071a200041a0066a200041e0076a41026a41c00110e4071a202120216a22012021490d012001417f4c0d010240024020010d00410221070c010b200110272207450d010b200041003602e807200020073602e007200020014101763602e40702402021450d00202320214105746a211120002802c805220a410574210f20002802c0052110410021062023210c0340200c41086a2900002102200c41106a290000210b200c290000210d200041f00a6a41186a200c41186a290000370300200041f00a6a41106a200b370300200041f00a6a41086a20023703002000200d3703f00a200a450d05200c41206a210c41002103200f21042010210102400340200041f00a6a2001460d0120032001200041f00a6a412010e70722054100476a21032005450d01200141206a2101200441606a22040d000c070b0b200341ffff034b0d050240200620002802e407470d00200041e0076a2006410110a90120002802e007210720002802e80721060b200720064101746a20033b01002000200641016a22063602e807200c2011470d000b0b0240202241ffffff3f71450d00202310290b20002802d805210620002802c8052107024041002802d8a74c4103490d00200041b4096a4111360200200041013602ac092000200041f0056a3602b0092000200041ec056a3602a80941002802888040210141002802848040210341002802dca74c2104200041b00b6a41fc01360200200041a80b6a42e980808010370300200041a40b6a41e4c1c2003602002000419c0b6a4221370200200041980b6a41c3c1c200360200200041900b6a4202370300200041800b6a4202370300200041f80a6a41073602002000418c0b6a200041a8096a360200200041acc1c2003602fc0a200041bcc1c2003602f40a200041033602f00a20034180a4c000200441024622041b200041f00a6a20014198a4c00020041b2802101102000b200041f00a6a41286a200041f0056a41286a290300370300200041f00a6a41206a200041f0056a41206a290300370300200041f00a6a41186a200041f0056a41186a290300370300200041f00a6a41106a200041f0056a41106a290300370300200041f00a6a41086a200041f0056a41086a290300370300200041a80b6a200041e0076a41086a280200360200200020002903f0053703f00a200020002903e0073703a00b200041ac0b6a200041a0066a41c00110e4071a200041f60c6a200041f00a6a41fc0110e4071a0240024020002802b01022050d004100210c200041840b6a4100360200200041003602f40a0c010b20002802b810210c0240024020002802b41022030d00200521010c010b2003210120052104034020042802c80521042001417f6a22010d000b200521010340200120012f01064102746a41c8056a28020021012003417f6a22030d000b200421050b2000418c0b6a20012f0106360200200041880b6a4100360200200041840b6a2001360200200041003602800b200042003703f80a200020053602f40a200041003602f00a0b2000200c3602900b200041f00a6a10b902024020002802d40541ffffff3f71450d0020002802d00510290b024020002802c40541ffffff3f71450d0020002802c00510290b200041b8036a200041f00c6a41820210e4071a200041b8016a200041be036a41fc0110e4071a200041d0106a41086a2205200041f0016a280200360200200020002903e8013703d010200041f00a6a200041f4016a41c00110e4071a200041a8096a41286a220c200041b8036a412e6a2201290100370300200041a8096a41206a220a200041b8036a41266a290100370300200041a8096a41186a220f200041b8036a411e6a290100370300200041a8096a41106a2210200041b8036a41166a290100370300200041a8096a41086a2211200041b8036a410e6a290100370300200020002901be033703a809200041e0076a41186a22084200370300200041e0076a41106a22094200370300200041e0076a41086a22034200370300200042003703e00741eebec500ad4280808080f000841001220429000021022003200441086a290000370300200020023703e0072004102941c4f5c100ad4280808080a00184100122042900002102200041f0056a41086a2219200441086a290000370300200020023703f00520041029202020002903f005370000202041086a2019290300370000200041a0066a41086a2003290300370300200041a0066a41106a2009290300370300200041a0066a41186a2008290300370300200020002903e0073703a0062000200041a0066a412010fc012000280204210320002802002104200041c3016a2005280200360000200041f00c6a410e6a2011290300370100200041f00c6a41166a2010290300370100200041f00c6a411e6a200f290300370100200041f00c6a41266a200a290300370100200041f00c6a412e6a2205200c290300370100200020002903d0103700bb01200020002903a8093701f60c2000200041b8016a41076a2900003700e707200020002900b8013703e00720012005290100370100200041b8036a41286a2205200041f00c6a41286a290100370300200041b8036a41206a220c200041f00c6a41206a290100370300200041b8036a41186a220a200041f00c6a41186a290100370300200041b8036a41106a220f200041f00c6a41106a290100370300200041b8036a41086a2210200041f00c6a41086a290100370300200020002901f00c3703b803200041900e6a41183a0000200041073602880e200042023703d80d200041980e6a20002900e707370000200020002903e0073700910e200041a00e6a200041f00a6a41c00110e4071a200041e80f6a20073b0100200041e40f6a2006360200200041e00f6a2003410020041b360200200041f20f6a2010290300370100200041fa0f6a200f29030037010020004182106a200a2903003701002000418a106a200c29030037010020004192106a200529030037010020004198106a2001290100370100200020002903b8033701ea0f2000200041f00c6a3602a006200041b8016a200041a0066a10bd0220002802b80120002802bc0120002802c00110de022101200041880e6a10cc014104410820011b21050c050b1039000b1038000b20002d00f10a21050240024020002802b010220c0d0041002106200041840b6a4100360200200041003602f40a0c010b20002802b81021060240024020002802b41022030d00200c21010c010b20032101200c2104034020042802c80521042001417f6a22010d000b200c21010340200120012f01064102746a41c8056a28020021012003417f6a22030d000b2004210c0b2000418c0b6a20012f0106360200200041880b6a4100360200200041840b6a2001360200200041003602800b200042003703f80a2000200c3602f40a200041003602f00a0b200020063602900b200041f00a6a10b902202241ffffff3f71450d01202310290c010b0240202241ffffff3f71450d00202310290b024020002802e40741808080807872418080808078460d00200710290b200041a0066a1087020240024020002802b01022050d004100210c200041840b6a4100360200200041003602f40a0c010b20002802b810210c0240024020002802b41022030d00200521010c010b2003210120052104034020042802c80521042001417f6a22010d000b200521010340200120012f01064102746a41c8056a28020021012003417f6a22030d000b200421050b2000418c0b6a20012f0106360200200041880b6a4100360200200041840b6a2001360200200041003602800b200042003703f80a200020053602f40a200041003602f00a0b2000200c3602900b200041f00a6a10b902410721050b024020002802d40541ffffff3f71450d0020002802d00510290b20002802c40541ffffff3f71450d0020002802c00510290b20004180116a240020050bf70c01087f230041c0046b22032400200341206a41186a200141186a290000370300200341206a41106a200141106a290000370300200341206a41086a200141086a290000370300200320012900003703200240024002400240024020002802002204450d00200028020421050c010b4100210520034180016a410041e00210e6071a200341f8006a22014100360200200341f0006a22064200370300200341d0006a41186a4200370300200341d0006a41106a4200370300200341d0006a41086a42003703002003420037035041940310272204450d01200441003b010620044100360200200441086a20034180016a41e00210e4071a20044190036a200128020036020020044188036a200629030037020020044180036a200341e8006a290300370200200441f8026a200341e0006a290300370200200441f0026a200341d0006a41086a290300370200200420032903503702e80220004100360204200020043602000b2003200036025820032004360254200320053602500240034020042f01062207410574210841002101410021060240024002400240034020082001460d010240200341206a200420016a41086a412010e70722090d0041002101200521090c030b200141206a2101200641016a21062009417f4a0d000b2006417f6a21070b20050d014101210141002109200721060b20034180016a41106a20063602002003418c016a200036020020034180016a41086a20043602002003200036025820032004360254200320053602502003200936028401200320013602800102402001450d00200341186a2201200341206a41186a2207290300370300200341106a2208200341206a41106a290300370300200341086a2205200341206a41086a290300370300200320032903203703002000200028020841016a3602082003200636024c200320003602482003200436024420032009360240200341d0006a41186a2001290300370300200341d0006a41106a2008290300370300200341d0006a41086a20052903003703002003200329030037035020034180016a200341c0006a200341d0006a200210fe0420032d0080014101470d04200341206a41086a220520034189016a290000370300200341206a41106a220020034191016a290000370300200720034199016a2900003703002003200329008101370320200341ac016a2802002106200341b8016a2802002108200341b4016a2802002109200341b0016a2802002104200341a8016a28020022012802002207450d0220012f01042102200341a4016a280200210a20034180016a410172210103402003200241ffff037136024c20032006360248200320073602442003200a41016a360240200341d0006a41186a200341206a41186a2206290300370300200341d0006a41106a2000290300370300200341d0006a41086a20052903003703002003200329032037035020034180016a200341c0006a200341d0006a20042009200810ff0420032d0080014101470d052005200141086a2900003703002000200141106a2900003703002006200141186a2900003703002003200129000037032020032802ac01210620032802b801210820032802b401210920032802b001210420032802a80122022802002207450d0320022f0104210220032802a401210a0c000b0b200420064102746a41e8026a20023602000c030b2005417f6a2105200420074102746a4194036a28020021040c010b0b20034180016a410272410041be0310e6071a41c40310272201450d0120014100360200200141046a20034180016a41c00310e4071a200120062802002205360294032006200136020020062006280204220041016a360204200541003b01042005200136020020034180016a41186a200341206a41186a29030037030020034180016a41106a200341206a41106a29030037030020034180016a41086a200341206a41086a290300370300200320032903203703800120002008470d0220012f01062206410a4b0d03200120064105746a220841206a20034180016a41186a290300370000200841186a20034180016a41106a290300370000200841106a20034180016a41086a290300370000200841086a200329038001370000200120064102746a41e8026a20043602002001200641016a22064102746a4194036a2009360200200120063b0106200920063b0104200920013602000b200341c0046a24000f0b1030000b41b69cc800413041b8a1cc001033000b418f9cc800412741b8a1cc001033000bac0b060f7f017e037f017e0b7f037e23004180016b22022400200141086a2802002103200128020421042000280204210520002802002106024020002802082207200028020c2208460d00200041146a28020021092001280200210a2000280210210b200241086a210c0340200c200741106a290300370300200241106a2201200741186a290300370300200241186a220d200741206a29030037030020022007290308370300200741386a210e02402007280228220f0d00200e21070c020b200741306a28020021002007412c6a280200211020072903002111200241206a41186a2212200d290300370300200241206a41106a22132001290300370300200241206a41086a2214200c29030037030020022002290300370320024002402000ad42c8007e2215422088a70d002015a72207417f4c0d0002400240024020070d00410821160c010b200710272216450d010b200741c8006e2117024020000d00410021180c030b200f20004105746a211941002118200f211a0340200241c0006a41186a221b201a41186a290000370300200241c0006a41106a221c201a41106a290000370300200241c0006a41086a221d201a41086a2900003703002002201a2900003703400240200b280200221e450d00200b280204211f0340201e41086a2100201e2f010622204105742107410021010240024003402007450d01200241c0006a2000412010e707220d450d02200741606a2107200141016a2101200041206a2100200d417f4a0d000b2001417f6a21200b201f450d02201f417f6a211f201e20204102746a4194036a280200211e0c010b0b0240024002402009280208220d201e20014102746a41e8026a220028020022074d0d002009280200200741d8006c6a2207427f2007290320221520117c222120212015542201200741286a220729030022222001ad7c2223202254202120155a1b22011b3703202007427f202320011b370300200241e0006a41186a2201201b290300370300200241e0006a41106a220d201c290300370300200241e0006a41086a221e201d2903003703002002200229034037036020002802002100024020182017460d002017211f201821170c030b024002400240201741016a22072017490d002017410174221f2007201f20074b1bad42c8007e2215422088a70d002015a722074100480d00024020170d0020070d02410821160c050b201741c8006c221f2007460d040240201f0d0020070d02410821160c050b2016201f2007102b2216450d020c040b1032000b2007102722160d020b1030000b2007200d4190f1c9001036000b200741c8006e211f0b2016201741c8006c6a2207420037030020072000360220200741186a4200370300200741106a4200370300200741086a4200370300200720022903603702242007412c6a201e290300370200200741346a200d2903003702002007413c6a2001290300370200201841016a2118201f21170b201a41206a221a2019460d030c000b0b1039000b1038000b0240201041ffffff3f71450d00200f10290b200241e0006a41186a22072012290300370300200241e0006a41106a22002013290300370300200241e0006a41086a20142903002215370300200220022903202221370360200a4200370310200a41186a4200370300200a4200370308200a2011370300200a41286a4200370300200a4201370320200a2018360238200a2017360234200a2016360230200a202137023c200a41c4006a2015370200200a41cc006a2000290300370200200a41d4006a2007290300370200200341016a2103200a41e0006a210a200e2107200e2008470d000b200821070b20042003360200200820076b220041386d210102402000450d00200141386c21002007412c6a210703400240200728020041ffffff3f71450d002007417c6a28020010290b200741386a2107200041486a22000d000b0b02402005450d00200541386c450d00200610290b20024180016a24000b870701047f230041d0006b2208240002400240024002402002200685200320078584500d00200220038450450d01410121090c020b417f20002004852001200585844200522000200454200120055420012005511b1b21090c010b0240200620078450450d0041ff0121090c010b411010272209450d012008420437024420082009360240200841c0006a41004104109801200841306a41086a22092008280248220a41046a3602002008280240200a4102746a220a20003e020c200a20004220883e0208200a20013e0204200a20014220883e020020082008290340370330200841306a10c607200841106a41086a220b20092802003602002008200829033037031041101027220a450d01200842043702442008200a360240200841c0006a4100410410980120092008280248220a41046a3602002008280240200a4102746a220a20063e020c200a20064220883e0208200a20073e0204200a20074220883e020020082008290340370330200841306a10c607200841206a41086a200928020036020020082008290330370320200841c0006a41086a200b280200360200200820082903103703402008200841c0006a200841206a10c8070240200828022441ffffffff0371450d00200828022010290b411010272209450d012008420437024420082009360240200841c0006a41004104109801200841306a41086a22092008280248220a41046a3602002008280240200a4102746a220a20043e020c200a20044220883e0208200a20053e0204200a20054220883e020020082008290340370330200841306a10c607200841106a41086a220b20092802003602002008200829033037031041101027220a450d01200842043702442008200a360240200841c0006a4100410410980120092008280248220a41046a3602002008280240200a4102746a220a20023e020c200a20024220883e0208200a20033e0204200a20034220883e020020082008290340370330200841306a10c607200841206a41086a200928020036020020082008290330370320200841c0006a41086a200b28020036020020082008290310370340200841306a200841c0006a200841206a10c8070240200828022441ffffffff0371450d00200828022010290b2008200841306a10ca0721090240200828023441ffffffff0371450d00200828023010290b200828020441ffffffff0371450d00200828020010290b200841d0006a240020090f0b1039000bbb0703017f067e017f230041d0006b22022400024002400240200029031022032001290310220485200041186a2903002205200141186a29030022068584500d00200041086a290300210720002903002108411010272200450d022002420437024420022000360240200241c0006a41004104109801200241306a41086a22092002280248220041046a360200200228024020004102746a220020083e020c200020084220883e0208200020073e0204200020074220883e020020022002290340370330200241306a10c607200241106a41086a200928020036020020022002290330370310411010272200450d022002420437024420022000360240200241c0006a41004104109801200241306a41086a22092002280248220041046a360200200228024020004102746a220020043e020c200020044220883e0208200020063e0204200020064220883e020020022002290340370330200241306a10c607200241206a41086a200928020036020020022002290330370320200241c0006a41086a200241106a41086a280200360200200220022903103703402002200241c0006a200241206a10c8070240200228022441ffffffff0371450d00200228022010290b200141086a290300210420012903002106411010272200450d022002420437024420022000360240200241c0006a41004104109801200241306a41086a22002002280248220141046a360200200228024020014102746a220120063e020c200120064220883e0208200120043e0204200120044220883e020020022002290340370330200241306a10c607200241106a41086a2209200028020036020020022002290330370310411010272201450d022002420437024420022001360240200241c0006a4100410410980120002002280248220141046a360200200228024020014102746a220120033e020c200120034220883e0208200120053e0204200120054220883e020020022002290340370330200241306a10c607200241206a41086a200028020036020020022002290330370320200241c0006a41086a200928020036020020022002290310370340200241306a200241c0006a200241206a10c8070240200228022441ffffffff0371450d00200228022010290b2002200241306a10ca0721000240200228023441ffffffff0371450d00200228023010290b200041ff017121000240200228020441ffffffff0371450d00200228020010290b20004521000c010b2000290300200129030085200041086a290300200141086a29030085845021000b200241d0006a240020000f0b1039000be86a05157f047e047f017e0d7f230041e0026b220524000240024020014115490d004101210641012107024002400240034020012108200021092006200771410173210a02400240024002400240024003400240024002402004450d00024020064101710d002000200110f7042004417f6a21040b2001410276220b41036c210c200b410174210d200141314b0d012002280200280200280200220e280200210f410021100c020b20002001200210f8040c0e0b02400240024002402002280200280200280200220e280200220f0d0041002111200c417f6a21120c010b200b41016a2113200b417f6a21102000200b41306c6a2114200e2802042115200f211102400340201141086a211620112f010622174105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21170b024020150d004200211a4200211b0c030b2015417f6a2115201120174102746a41c8056a28020021110c010b0b201120184105746a221241f0026a290300211b201241e8026a290300211a0b0240200f0d0041002111200c417f6a21120c010b2000201041306c6a2114200e2802042115200f211102400340201141086a211620112f010622174105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21170b024020150d004200211c4200211d0c030b2015417f6a2115201120174102746a41c8056a28020021110c010b0b201120184105746a221241f0026a290300211d201241e8026a290300211c0b2010200b201a201c54201b201d54201b201d511b22111b211e0240200f0d00201e210b200c417f6a21120c010b200b201020111b211f2000201341306c6a2114200e2802042115200f210b02400340200b41086a2116200b2f010622174105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21170b024020150d004200211a4200211b0c030b2015417f6a2115200b20174102746a41c8056a280200210b0c010b0b200b20184105746a221241f0026a290300211b201241e8026a290300211a0b0240200f0d00201e210b200c417f6a21120c010b2000201e41306c6a2114200e2802042115200f210b02400340200b41086a2116200b2f010622174105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21170b024020150d004200211c4200211d0c030b2015417f6a2115200b20174102746a41c8056a280200210b0c010b0b200b20184105746a221241f0026a290300211d201241e8026a290300211c0b4102410120111b2011201a201c54201b201d54201b201d511b22121b21112013201e20121b210b0240200f450d002000200b41306c6a2114200e2802042117200f211502400340201541086a211620152f010622104105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21100b024020170d004200211a4200211b0c030b2017417f6a2117201520104102746a41c8056a28020021150c010b0b201520184105746a221241f0026a290300211b201241e8026a290300211a0b200f450d002000201f41306c6a2114200e2802042117200f211502400340201541086a211620152f010622104105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21100b024020170d004200211c4200211d0c030b2017417f6a2117201520104102746a41c8056a28020021150c010b0b201520184105746a221241f0026a290300211d201241e8026a290300211c0b201f200b201a201c54201b201d54201b201d511b22121b210b201120126a2111200f450d00200d410172211e200d417f6a21132000200d41306c6a2114200e2802042117200f211502400340201541086a211620152f010622104105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21100b024020170d004200211a4200211b0c030b2017417f6a2117201520104102746a41c8056a28020021150c010b0b201520184105746a221241f0026a290300211b201241e8026a290300211a0b200f450d002000201341306c6a2114200e2802042117200f211502400340201541086a211620152f010622104105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21100b024020170d004200211c4200211d0c030b2017417f6a2117201520104102746a41c8056a28020021150c010b0b201520184105746a221241f0026a290300211d201241e8026a290300211c0b2013200d201a201c54201b201d54201b201d511b22121b2110201120126a21110240200f450d00200d201320121b21132000201e41306c6a2114200e2802042115200f210d02400340200d41086a2116200d2f010622174105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21170b024020150d004200211a4200211b0c030b2015417f6a2115200d20174102746a41c8056a280200210d0c010b0b200d20184105746a221241f0026a290300211b201241e8026a290300211a0b200f450d002000201041306c6a2114200e2802042115200f210d02400340200d41086a2116200d2f010622174105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21170b024020150d004200211c4200211d0c030b2015417f6a2115200d20174102746a41c8056a280200210d0c010b0b200d20184105746a221241f0026a290300211d201241e8026a290300211c0b201e2010201a201c54201b201d54201b201d511b22121b210d201120126a2111200f450d012000200d41306c6a2114200e2802042117200f211502400340201541086a211620152f010622104105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21100b024020170d004200211a4200211b0c030b2017417f6a2117201520104102746a41c8056a28020021150c010b0b201520184105746a221241f0026a290300211b201241e8026a290300211a0b200f450d012000201341306c6a2114200e2802042117200f211502400340201541086a211620152f010622104105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21100b024020170d004200211c4200211d0c030b2017417f6a2117201520104102746a41c8056a28020021150c010b0b201520184105746a221241f0026a290300211d201241e8026a290300211c0b2013200d201a201c54201b201d54201b201d511b22121b210d201120126a2111200c417f6a2112200f450d02200c41016a211e2000200c41306c6a2115200e2802042110200f211702400340201741086a211820172f010622134105742116410021190240024003402016450d0120152018412010e7072214450d02201641606a2116201941016a2119201841206a21182014417f4a0d000b2019417f6a21130b024020100d004200211a4200211b0c030b2010417f6a2110201720134102746a41c8056a28020021170c010b0b201720194105746a221641f0026a290300211b201641e8026a290300211a0b200f450d022000201241306c6a2115200e2802042110200f211702400340201741086a211820172f010622134105742116410021190240024003402016450d0120152018412010e7072214450d02201641606a2116201941016a2119201841206a21182014417f4a0d000b2019417f6a21130b024020100d004200211c4200211d0c030b2010417f6a2110201720134102746a41c8056a28020021170c010b0b201720194105746a221641f0026a290300211d201641e8026a290300211c0b2012200c201a201c54201b201d54201b201d511b22161b2113200c201220161b2112201120166a21110240200f450d002000201e41306c6a2115200e2802042110200f211702400340201741086a211820172f0106220c4105742116410021190240024003402016450d0120152018412010e7072214450d02201641606a2116201941016a2119201841206a21182014417f4a0d000b2019417f6a210c0b024020100d004200211a4200211b0c030b2010417f6a21102017200c4102746a41c8056a28020021170c010b0b201720194105746a221641f0026a290300211b201641e8026a290300211a0b200f450d002000201341306c6a2115200e2802042110200f211702400340201741086a211820172f0106220c4105742116410021190240024003402016450d0120152018412010e7072214450d02201641606a2116201941016a2119201841206a21182014417f4a0d000b2019417f6a210c0b024020100d004200211c4200211d0c030b2010417f6a21102017200c4102746a41c8056a28020021170c010b0b201720194105746a221641f0026a290300211d201641e8026a290300211c0b201e2013201a201c54201b201d54201b201d511b22161b210c201120166a2111200f450d032000200c41306c6a2115200e2802042110200f211702400340201741086a211820172f010622134105742116410021190240024003402016450d0120152018412010e7072214450d02201641606a2116201941016a2119201841206a21182014417f4a0d000b2019417f6a21130b024020100d004200211a4200211b0c030b2010417f6a2110201720134102746a41c8056a28020021170c010b0b201720194105746a221641f0026a290300211b201641e8026a290300211a0b200f450d042000201241306c6a2115200e2802042110200f21170340201741086a211820172f010622134105742116410021190240024003402016450d0120152018412010e7072214450d02201641606a2116201941016a2119201841206a21182014417f4a0d000b2019417f6a21130b2010450d062010417f6a2110201720134102746a41c8056a28020021170c010b0b201720194105746a221641f0026a290300211d201641e8026a290300211c0c050b4200211a4200211b2013210c0c030b2010210d0b200c417f6a21120b4200211a4200211b0b4200211c4200211d0b2012200c201a201c54201b201d54201b201d511b22161b210c201120166a21100b02400240200f450d002000200d41306c6a2114200e2802042115200f211102400340201141086a211620112f010622174105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21170b024020150d004200211a4200211b0c030b2015417f6a2115201120174102746a41c8056a28020021110c010b0b201120184105746a221241f0026a290300211b201241e8026a290300211a0b200f450d002000200b41306c6a2114200e2802042115200f211102400340201141086a211620112f010622174105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21170b024020150d004200211c4200211d0c030b2015417f6a2115201120174102746a41c8056a28020021110c010b0b201120184105746a221241f0026a290300211d201241e8026a290300211c0b200b200d201a201c54201b201d54201b201d511b22121b2115201020126a21100240200f450d00200d200b20121b21202000200c41306c6a2114200e280204210d200f211102400340201141086a211620112f0106220b4105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210b0b0240200d0d004200211a4200211b0c030b200d417f6a210d2011200b4102746a41c8056a28020021110c010b0b201120184105746a221241f0026a290300211b201241e8026a290300211a0b200f450d002000201541306c6a2114200e280204210d200f211102400340201141086a211620112f0106220b4105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210b0b0240200d0d004200211c4200211d0c030b200d417f6a210d2011200b4102746a41c8056a28020021110c010b0b201120184105746a221241f0026a290300211d201241e8026a290300211c0b200c2015201a201c54201b201d54201b201d511b22121b210d201020126a2110200f450d012000200d41306c6a2114200e280204210b200f211102400340201141086a211620112f010622154105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21150b0240200b0d004200211d4200211b0c030b200b417f6a210b201120154102746a41c8056a28020021110c010b0b201120184105746a221241f0026a290300211b201241e8026a290300211d0b200f450d012000202041306c6a2114200e28020421110340200f41086a2116200f2f0106220b4105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210b0b2011450d032011417f6a2111200f200b4102746a41c8056a280200210f0c010b0b201d200f20184105746a221241e8026a2903005a201b201241f0026a290300221d5a201b201d511b0d010240201041016a2210410c4f0d002020210d20104521120c030b024020014101762218450d002000200141306c6a41506a2112200021160340200541b0026a41286a2219201641286a2214290300370300200541b0026a41206a220f201641206a2211290300370300200541b0026a41186a220d201641186a220b290300370300200541b0026a41106a2215201641106a2217290300370300200541b0026a41086a220e201641086a2210290300370300200520162903003703b002201241086a220c290300211b201241106a2213290300211d201241186a221e290300211a201241206a221f290300211c201241286a2221290300212220162012290300370300201420223703002011201c370300200b201a3703002017201d3703002010201b37030020212019290300370300201f200f290300370300201e200d29030037030020132015290300370300200c200e290300370300201220052903b002370300201241506a2112201641306a21162018417f6a22180d000b0b20012020417f736a210d410121120c020b2015210d0b20104521120b0240201245200a724101710d0020002001200210f9040d0d0b02402003450d00200d20014f0d03024020022802002802002802002215280200220f450d0020152802042111200f211402400340201441086a211620142f0106220b4105742112410021180240024003402012450d0120032016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210b0b024020110d004200211d4200211b0c030b2011417f6a21112014200b4102746a41c8056a28020021140c010b0b201420184105746a221241f0026a290300211b201241e8026a290300211d0b200f450d002000200d41306c6a2114201528020421110340200f41086a2116200f2f0106220b4105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210b0b2011450d022011417f6a2111200f200b4102746a41c8056a280200210f0c010b0b201d200f20184105746a221241e8026a29030054201b201241f0026a290300221d54201b201d511b450d0020002109200121080c030b200541b0026a41286a2213200041286a2223290300370300200541b0026a41206a221e200041206a2224290300370300200541b0026a41186a221f200041186a2225290300370300200541b0026a41106a2221200041106a2207290300370300200541b0026a41086a2220200041086a2226290300370300200520002903003703b0022000200d41306c6a221241086a2216290300211b201241106a2218290300211d201241186a2219290300211a201241206a2214290300211c201241286a220f290300212220002012290300370300202320223703002024201c3703002025201a3703002007201d3703002026201b370300200f20132903003703002014201e2903003703002019201f2903003703002018202129030037030020162020290300370300201220052903b002370300200541b0016a41286a22272023290300370300200541b0016a41206a22282024290300370300200541b0016a41186a22292025290300370300200541b0016a41106a222a2007290300370300200541b0016a41086a222b2026290300370300200520002903003703b001200041306a210c4100210d200121150340200228020021100240200d2015417f6a22174f0d002010280200280200220e280200210b03400240200b450d00200e280204210f200b211402400340201441086a211620142f010622114105742112410021180240024003402012450d01200541b0016a2016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21110b0240200f0d004200211d4200211b0c030b200f417f6a210f201420114102746a41c8056a28020021140c010b0b201420184105746a221241f0026a290300211b201241e8026a290300211d0b200b450d00200c200d41306c6a2114200e2802042111200b210f0340200f41086a2116200f2f010622154105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21150b2011450d022011417f6a2111200f20154102746a41c8056a280200210f0c010b0b201d200f20184105746a221241e8026a2903005a201b201241f0026a290300221d5a201b201d511b450d020b200d41016a220d2017470d000b2017210d0b02400340200d201722154f0d0102402010280200280200220e280200220f450d002015417f6a2117200e2802042111200f211402400340201441086a211620142f0106220b4105742112410021180240024003402012450d01200541b0016a2016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210b0b024020110d004200211d4200211b0c030b2011417f6a21112014200b4102746a41c8056a28020021140c010b0b201420184105746a221241f0026a290300211b201241e8026a290300211d0b200f450d002000201541306c6a2114200e28020421110340200f41086a2116200f2f0106220b4105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210b0b2011450d022011417f6a2111200f200b4102746a41c8056a280200210f0c010b0b201d200f20184105746a221241e8026a29030054201b201241f0026a290300221d54201b201d511b0d010b0b2013200c200d41306c6a221241286a2218290300370300201e201241206a2219290300370300201f201241186a22142903003703002021201241106a220f2903003703002020201241086a2211290300370300200520122903003703b0022000201541306c6a221641086a220b290300211b201641106a2217290300211d201641186a220e290300211a201641206a2210290300211c201641286a222c290300212220122016290300370300201820223703002019201c3703002014201a370300200f201d3703002011201b370300202c20132903003703002010201e290300370300200e201f29030037030020172021290300370300200b2020290300370300201620052903b002370300200d41016a210d0c010b0b200020052903b0013703002023202729030037030020242028290300370300202520292903003703002007202a2903003703002026202b2903003703002001200d41016a2212490d042000201241306c6a2100200120126b220141154f0d010c0c0b0b2008450d030b200d20084f0d03200541b0026a41286a2221200941286a2226290300370300200541b0026a41206a2220200941206a2227290300370300200541b0026a41186a222c200941186a2228290300370300200541b0026a41106a2223200941106a2229290300370300200541b0026a41086a2224200941086a222a290300370300200520092903003703b0022009200d41306c6a221241086a2216290300211b201241106a2218290300211d201241186a2219290300211a201241206a2214290300211c201241286a220f290300212220092012290300370300202620223703002027201c3703002028201a3703002029201d370300202a201b370300200f2021290300370300201420202903003703002019202c2903003703002018202329030037030020162024290300370300201220052903b002370300200541286a222b2026290300370300200541206a22062027290300370300200541186a220a2028290300370300200541106a222d2029290300370300200541086a222e202a29030037030020052009290300370300200941306a21002002280200210e02402008417f6a22100d00410021250c050b200e2802002802002215280200210b410021250340200b450d052000202541306c6a211420152802042111200b210f02400340200f41086a2116200f2f0106220d4105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210d0b024020110d004200211d4200211b0c030b2011417f6a2111200f200d4102746a41c8056a280200210f0c010b0b200f20184105746a221241f0026a290300211b201241e8026a290300211d0b200b450d052015280204210f200b21140340201441086a211620142f010622114105742112410021180240024003402012450d0120052016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21110b200f450d07200f417f6a210f201420114102746a41c8056a28020021140c010b0b201d201420184105746a221241e8026a29030054201b201241f0026a290300221d54201b201d511b450d05202541016a22252010470d000b201021250c040b200d200141fc99c5001036000b2012200141c499c500104c000b410041004180bdc7001036000b200d20084190bdc7001036000b20102112024003402012221520254d22070d01024002400240200e280200280200221728020022110d004200211c4200211d0c010b2009201541306c6a21142017280204210d2011210f02400340200f41086a2116200f2f0106220b4105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210b0b0240200d0d004200211c4200211d0c030b200d417f6a210d200f200b4102746a41c8056a280200210f0c010b0b200f20184105746a221241f0026a290300211d201241e8026a290300211c0b2011450d00201728020421140340201141086a211620112f0106220f4105742112410021180240024003402012450d0120052016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210f0b2014450d022014417f6a21142011200f4102746a41c8056a28020021110c010b0b201120184105746a221241f0026a290300211b201241e8026a290300211a0c010b4200211a4200211b0b2015417f6a2112201c201a5a201d201b5a201d201b511b0d000b0b20152025490d0320102015490d022000201541306c6a210c418001211e4100210e4100210d4100211741002111418001211f2000202541306c6a222f21100340200c20106b221241306e21160240201241afe0004b22010d00201641807f6a2016200d200e49201120174922187222191b211202402019450d00201f201220181b211f2012201e20181b211e0c010b20122012410176221f6b211e0b024020112017470d000240201f0d00200541306a221721110c010b41002115200541306a2117201021140340201720153a0000201541016a21150240024002402002280200280200280200221328020022110d004200211a4200211b0c010b2013280204210b2011210f02400340200f41086a2116200f2f010622004105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21000b0240200b0d004200211a4200211b0c030b200b417f6a210b200f20004102746a41c8056a280200210f0c010b0b200f20184105746a221241f0026a290300211b201241e8026a290300211a0b2011450d002013280204210f0340201141086a211620112f0106220b4105742112410021180240024003402012450d0120052016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210b0b200f450d02200f417f6a210f2011200b4102746a41c8056a28020021110c010b0b201120184105746a221241f0026a290300211d201241e8026a290300211c0c010b4200211c4200211d0b2017201a201c5a201b201d5a201b201d511b6a2117201441306a21142015201f470d000b200541306a21110b0240200d200e470d000240201e0d00200541b0016a220e210d0c010b41002115200541b0016a210e200c21140340200e20153a0000201441506a2114201541016a211502400240024020022802002802002802002213280200220d0d004200211a4200211b0c010b2013280204210b200d210f02400340200f41086a2116200f2f010622004105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21000b0240200b0d004200211a4200211b0c030b200b417f6a210b200f20004102746a41c8056a280200210f0c010b0b200f20184105746a221241f0026a290300211b201241e8026a290300211a0b200d450d002013280204210f0340200d41086a2116200d2f0106220b4105742112410021180240024003402012450d0120052016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210b0b200f450d02200f417f6a210f200d200b4102746a41c8056a280200210d0c010b0b200d20184105746a221241f0026a290300211d201241e8026a290300211c0c010b4200211c4200211d0b200e201a201c54201b201d54201b201d511b6a210e2015201e470d000b200541b0016a210d0b0240200e200d6b2212201720116b2216201620124b1b2218450d002021201020112d000041306c6a221241286a2903003703002020201241206a290300370300202c201241186a2903003703002023201241106a2903003703002024201241086a290300370300200520122903003703b002201020112d000041306c6a2212200c200d2d0000417f7341306c6a2216290300370300201241286a201641286a290300370300201241206a201641206a290300370300201241186a201641186a290300370300201241106a201641106a290300370300201241086a201641086a290300370300024020184101460d002018417f6a21180340200c200d2d0000417f7341306c6a2212201020112d000141306c6a2216290300370300201241286a201641286a290300370300201241206a201641206a290300370300201241186a201641186a290300370300201241106a201641106a290300370300201241086a201641086a290300370300201020112d000141306c6a2212200c200d2d0001417f7341306c6a2216290300370300201241286a201641286a290300370300201241206a201641206a290300370300201241186a201641186a290300370300201241106a201641106a290300370300201241086a201641086a290300370300200d41016a210d201141016a21112018417f6a22180d000b0b200c200d2d0000417f7341306c6a221220052903b002370300201241286a2021290300370300201241206a2020290300370300201241186a202c290300370300201241106a2023290300370300201241086a2024290300370300200d41016a210d201141016a21110b2010201f41306c6a201020112017461b2110200c4100201e6b41306c6a200c200d200e461b210c20010d000b02400240201120174f0d00200c21120340202120102017417f6a22172d000041306c6a221641286a22182903003703002020201641206a2219290300370300202c201641186a22142903003703002023201641106a220f2903003703002024201641086a220d290300370300200520162903003703b002201241506a221241086a220b290300211b201241106a2215290300211d201241186a220e290300211a201241206a2200290300211c201241286a220c290300212220162012290300370300201820223703002019201c3703002014201a370300200f201d370300200d201b370300200c202129030037030020002020290300370300200e202c29030037030020152023290300370300200b2024290300370300201220052903b00237030020112017490d000c020b0b20102112200d200e4f0d000340200e417f6a220e2d000021162021201241286a22182903003703002020201241206a2219290300370300202c201241186a22142903003703002023201241106a220f2903003703002024201241086a2211290300370300200520122903003703b002200c2016417f7341306c6a221641086a220b290300211b201641106a2215290300211d201641186a2217290300211a201641206a2200290300211c201641286a2210290300212220122016290300370300201820223703002019201c3703002014201a370300200f201d3703002011201b37030020102021290300370300200020202903003703002017202c29030037030020152023290300370300200b2024290300370300201620052903b002370300201241306a2112200d200e490d000b0b200920052903003703002026202b290300370300202720062903003703002028200a2903003703002029202d290300370300202a202e290300370300024020082012202f6b41306e20256a22014d0d002021202629030037030020202027290300370300202c2028290300370300202320292903003703002024202a290300370300200520092903003703b0022009200141306c6a221241086a2216290300211b201241106a2218290300211d201241186a2219290300211a201241206a2214290300211c201241286a220f290300212220092012290300370300202620223703002027201c3703002028201a3703002029201d370300202a201b370300200f2021290300370300201420202903003703002019202c2903003703002018202329030037030020162024290300370300201220052903b002370300200820016b2216450d0220162001200120164b1b211820084103762119201241306a21000240024020012016417f6a2216490d002000201620022012200410db02200921000c010b2009200120022003200410db0220122103201621010b201820194f2106200141154f0d010c050b0b200120084190bdc7001036000b4189a7c700411c41b8a1cc001033000b2015201041d499c500104b000b2025201541d499c500104c000b20014102490d004101211703402017220e41016a2117024020022802002802002802002210280200220d450d00200e417f6a210c2000200e41306c6a221441506a210f2010280204210b200d211102400340201141086a211620112f010622154105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a21150b0240200b0d004200211d4200211b0c030b200b417f6a210b201120154102746a41c8056a28020021110c010b0b201120184105746a221241f0026a290300211b201241e8026a290300211d0b200d450d00201028020421110340200d41086a2116200d2f0106220b4105742112410021180240024003402012450d01200f2016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210b0b2011450d022011417f6a2111200d200b4102746a41c8056a280200210d0c010b0b201d200d20184105746a221241e8026a2903005a201b201241f0026a290300221d5a201b201d511b0d00200541b0016a41286a2215201441286a2212290300370300200541b0016a41206a2210201441206a2216290300370300200541b0016a41186a2213201441186a2218290300370300200541b0016a41106a2203201441106a2219290300370300200541b0016a41086a221e201441086a2211290300370300200520142903003703b0012014200f2903003703002011200f41086a2903003703002019200f41106a2903003703002018200f41186a2903003703002016200f41206a2903003703002012200f41286a29030037030002400240200c0d004100210c0c010b2002280200280200280200221f280200220f450d00200e417e6a210b201f2802042111200f211402400340201441086a211620142f0106220d4105742112410021180240024003402012450d01200541b0016a2016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210d0b024020110d004200211d4200211b0c030b2011417f6a21112014200d4102746a41c8056a28020021140c010b0b201420184105746a221241f0026a290300211b201241e8026a290300211d0b200f450d002000200b41306c6a2114201f28020421110340200f41086a2116200f2f0106220d4105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210d0b2011450d022011417f6a2111200f200d4102746a41c8056a280200210f0c010b0b200c2112201d200f20184105746a221641e8026a2903005a201b201641f0026a290300221d5a201b201d511b0d00024003402000201241306c6a22122000200b220c41306c6a2216290300370300201241286a201641286a290300370300201241206a201641206a290300370300201241186a201641186a290300370300201241106a201641106a290300370300201241086a201641086a290300370300200c450d012002280200280200280200220e280200220f450d02200c417f6a210b200e2802042111200f211402400340201441086a211620142f0106220d4105742112410021180240024003402012450d01200541b0016a2016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210d0b024020110d004200211d4200211b0c030b2011417f6a21112014200d4102746a41c8056a28020021140c010b0b201420184105746a221241f0026a290300211b201241e8026a290300211d0b200f450d022000200b41306c6a2114200e28020421110340200f41086a2116200f2f0106220d4105742112410021180240024003402012450d0120142016412010e7072219450d02201241606a2112201841016a2118201641206a21162019417f4a0d000b2018417f6a210d0b2011450d042011417f6a2111200f200d4102746a41c8056a280200210f0c010b0b200c2112201d200f20184105746a221641e8026a29030054201b201641f0026a290300221d54201b201d511b0d000c020b0b4100210c0b2000200c41306c6a221220052903b001370300201241286a2015290300370300201241206a2010290300370300201241186a2013290300370300201241106a2003290300370300201241086a201e2903003703000b20172001470d000b0b200541e0026a24000bece20102517f0d7e230041d0106b22012400200141003602102001410036020802400240200041086a22022802002203450d00200141f8076a4102722104200141fd026a2105200141d0026a41206a2106200141386a41206a2107200141f8076a41206a2108200141186a41186a2109200141186a41106a210a4100210b034002400240024002402002280200220c200b4d0d0020092000280200200b412c6c220d6a220e41246a290000370300200a200e411c6a290000370300200141186a41086a220f200e41146a2900003703002001200e29000c370318200e280200210c200e280208210e2001410036028008200142013703f807200141f8076a4100200e109e01200128028008211002400240200e41306c22110d0020012802f80721120c010b20012802f807221220104105746a210e0340200e200c290000370000200e41186a200c41186a290000370000200e41106a200c41106a290000370000200e41086a200c41086a290000370000201041016a2110200e41206a210e200c41306a210c201141506a22110d000b0b20012802fc07211320104102490d0302402010417f6a221420106c410176220c41ffffff1f71200c470d00200c410674220c417f4c0d00024002400240200c0d00410121150c010b200c10272215450d010b201241206a2116200c4106762117410021184100210c03400240200c41016a221920104f0d002012200c4105746a21112014211a2016210e0340200141f8076a41086a221b201141086a290000370300200141f8076a41106a221c201141106a290000370300200141f8076a41186a221d201141186a290000370300200120112900003703f8072008200e290000370000200841086a200e41086a290000370000200841106a200e41106a290000370000200841186a200e41186a290000370000024020182017470d00201741016a220c2017490d072017410174221e200c201e200c4b1b220c41ffffff1f71200c470d07200c410674220c4100480d0702400240024020170d00200c0d01410121150c020b20174106742217200c460d01024020170d00200c0d01410121150c020b20152017200c102b2215450d0e0c010b200c10272215450d0d0b200c41067621170b201520184106746a220c20012903f807370000200c41386a200141f8076a41386a290300370000200c41306a200141f8076a41306a290300370000200c41286a200141f8076a41286a290300370000200c41206a2008290300370000200c41186a201d290300370000200c41106a201c290300370000200c41086a201b290300370000200e41206a210e201841016a2118201a417f6a221a0d000b0b2014417f6a2114201641206a21162019210c20192010470d000b2018450d04201520184106746a211f2015211e02400340200141386a41386a201e41386a290000370300200141386a41306a201e41306a290000370300200141386a41286a201e41286a2900003703002007201e41206a290000370300200141386a41186a201e41186a220c290000370300200141386a41106a201e41106a220e290000370300200141386a41086a201e41086a22112900003703002001201e290000370338200141f8006a41186a2218200c290000370300200141f8006a41106a220c200e290000370300200141f8006a41086a220e20112900003703002001201e29000037037820014198016a41186a200741186a221129000037030020014198016a41106a200741106a221a29000037030020014198016a41086a200741086a221b2900003703002001200729000037039801200141d0026a41186a22202018290300370300200141d0026a41106a2221200c290300370300200141d0026a41086a2222200e29030037030020062007290000370000200641086a201b290000370000200641106a201a290000370000200641186a2011290000370000200120012903783703d002024002402001280208221b450d00200128020c211c0c010b200141f8076a410041c00510e6071a200141e8046a410041e00210e6071a41a8081027221b450d0b4100211c201b41003b0106201b4100360200201b41086a200141f8076a41c00510e4071a201b41c8056a200141e8046a41e00210e4071a2001410036020c2001201b3602080b201e41c0006a211e02400240024002400240024002400240024002400240024002400240024003400240201b2f0106221a410674220e450d00201b41286a210c41002111034002400240200141d0026a200c41606a412010e7072218450d00201841004e0d012011211a0c030b2006200c412010e7072218450d04201841004e0d002011211a0c020b201141016a2111200c41c0006a210c200e41406a220e0d000b0b201c450d02201c417f6a211c201b201a4102746a41a8086a280200211b0c000b0b20022802002219200b4d0d0320002802002210200d6a220c28020841306c221a450d0c201b201141057422146a41c8056a211d200c280200210c4100211803404101210e0240200141f8006a200c460d00200c200141f8006a412010e707450d00024020014198016a200c470d004101210e0c010b200c20014198016a412010e70745210e0b200c41306a210c200e20186a2118201a41506a221a0d000b20184102470d0c2019412c6c210e03402010210c200e450d0d0240200c410c6a2218201d460d00200e41546a210e200c412c6a21102018201d412010e7070d010b0b0240200c41086a280200220e450d00200e41306c2110200141f8006a200c28020022186b211a20014198016a20186b21194100210c0340201a200c460d032018200c6a220e200141f8006a412010e707450d032019200c460d03200e20014198016a412010e707450d032010200c41306a220c470d000b0b4108211a410021160c090b200141b8016a41386a220c200141d0026a41386a290300370300200141b8016a41306a220e200141d0026a41306a290300370300200141b8016a41286a2211200141d0026a41286a290300370300200141b8016a41206a22182006290300370300200141b8016a41186a221c2020290300370300200141b8016a41106a221d2021290300370300200141b8016a41086a22102022290300370300200120012903d0023703b8012001200128021041016a360210200141a0036a41386a2223200c290300370300200141a0036a41306a2224200e290300370300200141a0036a41286a22252011290300370300200141a0036a41206a22262018290300370300200141a0036a41186a2227201c290300370300200141a0036a41106a2228201d290300370300200141a0036a41086a22292010290300370300200120012903b8013703a003200141d0076a41186a222a2009290300370300200141d0076a41106a222b200a290300370300200141d0076a41086a222c200f290300370300200120012903183703d0070240201b2f0106220e410b490d00200141f8076a410041c00510e6071a200141e8046a410041e00210e6071a41a8081027220c450d18200c41003b0106200c4100360200200c41086a200141f8076a41c00510e407210e200c41c8056a200141e8046a41e00210e4072118200141f8076a41086a2210201b41a3036a290000370300200141f8076a41106a2219201b41ab036a290000370300200141f8076a41186a2214201b41b3036a2900003703002008201b41bb036a290000370300200141f8076a41256a2216201b41c0036a2900003700002001201b4188036a2f00003b0188042001201b418a036a2d00003a008a042001201b419b036a2900003703f807201b418b036a280000212d201b418f036a280000212e201b4193036a280000212f201b4197036a2800002130200141c8046a41186a2231201b41a0076a290000370300200141c8046a41106a2232201b4198076a290000370300200141c8046a41086a2233201b4190076a2900003703002001201b290088073703c804200e201b41c8036a201b2f010641796a221141067410e407210e2018201b41a8076a201141057410e4072118201b41063b0106200c20113b0106200141e0036a41026a221c20012d008a043a0000200141e8046a41086a22342010290300370300200141e8046a41106a22352019290300370300200141e8046a41186a22362014290300370300200141e8046a41206a22372008290300370300200141e8046a41256a22382016290000370000200120012f0188043b01e003200120012903f8073703e804200141a8046a41186a22392031290300370300200141a8046a41106a223a2032290300370300200141a8046a41086a223b2033290300370300200120012903c8043703a80402400240201a4107490d00200e201a417a6a221d4106746a200e201a41796a221a4106746a220e201141ffff0371201a6b41067410e5071a200e41386a2023290300370000200e41306a2024290300370000200e41286a2025290300370000200e41206a2026290300370000200e41186a2027290300370000200e41106a2028290300370000200e41086a2029290300370000200e20012903a0033700002018201d4105746a2018201a4105746a220e200c2f0106201a6b41057410e5071a200e41186a202a290300370000200e41106a202b290300370000200e41086a202c290300370000200e20012903d007370000200c200c2f010641016a3b01060c010b201b41086a220e201a41016a22114106746a200e201a4106746a220e201b2f0106201a6b41067410e5071a200e41386a2023290300370000200e41306a2024290300370000200e41286a2025290300370000200e41206a2026290300370000200e41186a2027290300370000200e41106a2028290300370000200e41086a2029290300370000200e20012903a003370000201b41c8056a220e20114105746a200e201a4105746a220e201b2f0106201a6b41057410e5071a200e41186a202a290300370000200e41106a202b290300370000200e41086a202c290300370000200e20012903d007370000201b201b2f010641016a3b01060b200520012903a804370000200141f4076a41026a220e201c2d00003a000020222034290300370300202120352903003703002020203629030037030020062037290300370300200141d0026a41256a22252038290000370000200541086a2211203b290300370000200541106a2218203a290300370000200541186a221a2039290300370000200120012f01e0033b01f407200120012903e8043703d002200141ac026a41026a223c200e2d00003a0000200141f8016a41086a223d2022290300370300200141f8016a41106a223e2021290300370300200141f8016a41186a223f2020290300370300200141f8016a41206a22402006290300370300200141f8016a41256a22412025290000370000200120012f01f4073b01ac02200120012903d0023703f801200141b0026a41186a2242201a290000370300200141b0026a41106a22432018290000370300200141b0026a41086a22442011290000370300200120052900003703b0020240201b28020022180d004100211c200141086a210e200c21110c0c0b201b2f0104212341002145200c2146034020014184046a41026a2247203c2d00003a00002022203d2903003703002021203e2903003703002020203f2903003703002006204029030037030020252041290000370000200120012f01ac023b018404200120012903f8013703d00220014188046a41186a2248204229030037030020014188046a41106a2249204329030037030020014188046a41086a224a2044290300370300200120012903b0023703880441000d03202341ffff0371211c02400240024020182f0106220c410b490d002004410041d20810e6071a41d8081027221a450d1c201a4100360200201a41046a200141f8076a41d40810e4071a200141d0076a41026a224b2018418a036a2d00003a00002010201841a3036a2900003703002019201841ab036a2900003703002014201841b3036a2900003703002008201841bb036a2900003703002016201841c0036a290000370000200120184188036a2f00003b01d00720012018419b036a2900003703f8072018418b036a280000214c2018418f036a280000214d20184193036a280000214e20184197036a280000214f2031201841a0076a290000370300203220184198076a290000370300203320184190076a29000037030020012018290088073703c804201a41086a201841c8036a20182f0106220e41796a220c41067410e4072150201a41c8056a201841a8076a200c41057410e4072151201a41a8086a201841c4086a200e417a6a221d41027410e4072124201841063b0106201a200c3b01060240201d450d004100210c2024210e0340200e2802002211200c3b01042011201a360200200e41046a210e201d200c41016a220c470d000b0b2034201029030037030020352019290300370300203620142903003703002037200829030037030020382016290000370000203b2033290300370300203a203229030037030020392031290300370300200120012f01d0073b01f407200120012903f8073703e804200120012903c8043703a8042001204b2d00003a00f607200141cc076a41026a221d20012d00f6073a00002010203429030037030020192035290300370300201420362903003703002008203729030037030020162038290000370000200120012f01f4073b01cc07200120012903e8043703f807202a2039290300370300202b203a290300370300202c203b290300370300200120012903a8043703d007202341ffff037122234107490d012050201c417a6a22114106746a2050201c41796a220c4106746a220e201a2f0106200c6b41067410e5071a200e203036000f200e202f36000b200e202e360007200e202d360003200e41026a20472d00003a0000200e20012f0184043b0000200e20012903d002370013200e411b6a2022290300370000200e41236a2021290300370000200e412b6a2020290300370000200e41336a2006290300370000200e41386a2025290000370000205120114105746a2051200c4105746a220e201a2f01062223200c6b41057410e5071a200e41186a2048290300370000200e41106a2049290300370000200e41086a204a290300370000200e200129038804370000201a202341016a220e3b0106201c410274222d20246a416c6a202420114102746a2223200e41ffff0371221c20116b41027410e5071a20232046360200201c2011490d02201a202d6a4190086a210e0340200e2802002211200c41016a220c3b01042011201a360200200e41046a210e200c201c490d000c030b0b201841086a220e201c41016a22114106746a200e201c4106746a220e200c201c6b41067410e5071a200e203036000f200e202f36000b200e202e360007200e202d360003200e41026a20472d00003a0000200e20012f0184043b0000200e20012903d002370013200e411b6a2022290300370000200e41236a2021290300370000200e412b6a2020290300370000200e41336a2006290300370000200e41386a2025290000370000201841c8056a220c20114105746a200c201c4105746a220c20182f0106220e201c6b41057410e5071a200c41186a2048290300370000200c41106a2049290300370000200c41086a204a290300370000200c2001290388043700002018200e41016a220c3b0106201c410274201841a8086a220e6a41086a200e20114102746a220e200c41ffff0371221a20116b41027410e5071a200e20463602000240201c201a4f0d0020182011417f6a220c4102746a41ac086a210e0340200e2802002211200c41016a220c3b010420112018360200200e41046a210e200c201a490d000b0b41001a200141086a1a201b1a0c0f0b201841086a220c201c41016a220e4106746a200c201c4106746a220c20182f0106201c6b41067410e5071a200c203036000f200c202f36000b200c202e360007200c202d360003200c41026a20472d00003a0000200c20012f0184043b0000200c20012903d002370013200c411b6a2022290300370000200c41236a2021290300370000200c412b6a2020290300370000200c41336a2006290300370000200c41386a2025290000370000201841c8056a220c200e4105746a200c201c4105746a220c20182f01062211201c6b41057410e5071a200c41186a2048290300370000200c41106a2049290300370000200c41086a204a290300370000200c2001290388043700002018201141016a220c3b0106201c410274222d201841a8086a22116a41086a2011200e4102746a2224200c41ffff03712211200e6b41027410e5071a20242046360200202320114f0d002018202d6a41ac086a210c0340200c280200220e201c41016a221c3b0104200e2018360200200c41046a210c2011201c470d000b0b204541016a210c20014180046a41026a220e201d2d00003a000020292010290300370300202820192903003703002027201429030037030020262008290300370300200141a0036a41256a22112016290000370000200141e0036a41086a221c202c290300370300200141e0036a41106a221d202b290300370300200141e0036a41186a2223202a290300370300200120012f01cc073b018004200120012903f8073703a003200120012903d0073703e003203c200e2d00003a0000203d2029290300370300203e2028290300370300203f20272903003703002040202629030037030020412011290000370000200120012f0180043b01ac02200120012903a0033703f801204220232903003703002043201d2903003703002044201c290300370300200120012903e0033703b00202402018280200220e0d00204d212e204e212f204f213020181a200141086a220e1a204c212d200c211c201a21110c0d0b20182f01042123200141086a1a204d212e204e212f204f213020181a204c212d200e2118201a2146200c21450c000b0b201b41086a220c201a41016a22114106746a200c201a4106746a220c200e201a6b41067410e5071a200c41386a2023290300370000200c41306a2024290300370000200c41286a2025290300370000200c41206a2026290300370000200c41186a2027290300370000200c41106a2028290300370000200c41086a2029290300370000200c20012903a003370000201b41c8056a220c20114105746a200c201a4105746a220c201b2f0106201a6b41057410e5071a200c41186a202a290300370000200c41106a202b290300370000200c41086a202c290300370000200c20012903d007370000201b201b2f010641016a3b01060c0b0b200141f8076a41086a22232018200c6a220e41086a290300370300200141f8076a41106a2224200e41106a290300370300200141f8076a41186a2226200e41186a2903003703002001200e2903003703f807200e41286a2903002152200e41206a290300215341301027221a450d0e201a2053370320201a20012903f807370300201a41286a2052370300201a41186a2026290300370300201a41106a2024290300370300201a41086a202329030037030020014281808080103702ec042001201a3602e8040240201041506a200c470d0020012802ec0421160c080b200e41306a2119201820106a220e41506a21224101211003402019210c024002400340200141f8006a200c460d01200c200141f8006a412010e707450d0120014198016a200c460d01200c20014198016a412010e707450d01200e200c41306a220c470d000c020b0b200c41286a2903002152200c41206a2903002153200141d0076a41186a2216200c41186a290300370300200141d0076a41106a2220200c41106a290300370300200141d0076a41086a2221200c41086a2903003703002001200c2903003703d0070240201020012802ec04470d00200141e8046a2010410110900120012802e804211a0b200c41306a2119201a201041306c6a221820012903d00737030020212903002154202029030021552016290300215620182053370320201841286a2052370300201841186a2056370300201841106a2055370300201841086a20543703002001201041016a22103602f0042022200c470d010b0b20012802ec04211620104102490d0720104102470d0441e00010272219450d0e200142023702d402200120193602d00202402002280200220c200b4d0d000240024002402000280200200d6a220c28020841306c22100d004102210c0c010b200c280200210c41002118034002400240200141f8006a200c460d00200c200141f8006a412010e707210e20014198016a200c460d00200e450d00200c20014198016a412010e7070d010b200141e8046a41186a2220200c41186a290300370300200141e8046a41106a2221200c41106a290300370300200141e8046a41086a2222200c41086a2903003703002001200c2903003703e804200c41286a2903002152200c41206a29030021530240201820012802d402470d00200141d0026a2018410110900120012802d002211920012802d80221180b2019201841306c6a220e20012903e804370300202229030021542021290300215520202903002156200e2053370320200e41286a2052370300200e41186a2056370300200e41106a2055370300200e41086a20543703002001201841016a22183602d8020b200c41306a210c201041506a22100d000b20184102460d0120012802d402210c0b200c450d0a200c41306c450d0a201910290c0a0b02402019201a460d00201a2019412010e707450d00200141f8076a41286a220c201a41286a220e2903003703002008201a41206a22182903003703002026201a41186a22102903003703002024201a41106a22202903003703002023201a41086a22212903003703002001201a2903003703f807200e201a41d8006a22222903003703002018201a41d0006a220e2903003703002010201a41c8006a22182903003703002020201a41c0006a22102903003703002021201a41386a2220290300370300201a201a2903303703002022200c290300370300200e2008290300370300201820262903003703002010202429030037030020202023290300370300201a20012903f8073703300b2001427f3703f0042001427f3703e80441002110200141003602a0032001410036028008200142083703f807200141f8076a4100410410900120012802f8072236200128028008222141306c6a210c02402019450d00200141e8046a41086a290300215420012903e8042157410021204100211003400240201920206a220e41206a2903002253205756200e41286a290300225220545620522054511b0d00200120533703e804200120103602a003200120523703f00420532157205221540b200c20206a2218200e290300370300200e41086a2903002155200e41106a2903002156200e41186a2903002158201841286a2052370300201841206a2053370300201841186a2058370300201841106a2056370300201841086a2055370300201041016a2110202041306a222041e000470d000b202120106a2121200c20206a210c0b0240201a450d00201a41e0006a2219201a460d00200141e8046a41086a290300215420012903e8042157201a210e0340200e41306a21180240200e41206a2903002253205756200e41286a290300225220545620522054511b0d00200120533703e804200120103602a003200120523703f00420532157205221540b200c200e290300370300200e41086a2903002155200e41106a2903002156200e41186a2903002158200c41286a2052370300200c41206a2053370300200c41186a2058370300200c41106a2056370300200c41086a2055370300200c41306a210c201041016a2110202141016a21212018210e20192018470d000b0b20012802fc07212520012802a003210e41041027220c450d17200c200e3602000240024020012802a003220e4102490d00410410272218450d192018200e410171410373220e360200200c41044108102b2235450d192035200e417e6a36020420012802a003210c201841044108102b2229450d19200c417e6a210c0c010b410410272218450d1820184101200e6b360200200c41044108102b2235450d1820354103200e6b36020420012802a003210c201841044108102b2229450d18200c41026a210c0b2029200c360204410410272234450d0f02400240202928020022224102490d002026201d41186a2900003703002024201d41106a2900003703002023201d41086a2900003703002001201d2900003703f8070c010b202620092903003703002024200a2903003703002023200f290300370300200120012903183703f8070b02402002280200220c450d0020002802002220200c412c6c6a21272036202241306c6a2110034002400240200141f8076a2020410c6a220c460d00200c200141f8076a412010e7070d010b2020280208210c0240202120224d0d00200c41306c210e4100211820202802002228210c02400340200e450d032010200c460d01200c2010412010e7072119201841016a2118200e41506a210e200c41306a210c20190d000b20194541016a41017120186a417f6a21180b2028201841306c6a220c427f200c290320225220012903e8047c22532053205254220e200c41286a220c2903002252200141e8046a41086a2903007c200ead7c225320525420532052511b220e1b370320200c427f2053200e1b3703000c010b200c0d0a0b2020412c6a22202027470d000b0b02400240202928020422224102490d002026201d41186a2900003703002024201d41106a2900003703002023201d41086a2900003703002001201d2900003703f8070c010b202620092903003703002024200a2903003703002023200f290300370300200120012903183703f8070b02402002280200220c450d0020002802002220200c412c6c6a21272036202241306c6a2110034002400240200141f8076a2020410c6a220c460d00200c200141f8076a412010e7070d010b2020280208210c0240202120224b0d00200c0d0b0c010b200c41306c210e4100211820202802002228210c02400340200e450d022010200c460d01200c2010412010e7072119201841016a2118200e41506a210e200c41306a210c20190d000b20194541016a41017120186a417f6a21180b2028201841306c6a220c427f200c290320225220012903e8047c22532053205254220e200c41286a220c2903002252200141e8046a41086a2903007c200ead7c225320525420532052511b220e1b370320200c427f2053200e1b3703000b2020412c6a22202027470d000b0b20291029203528020022224102490d032026201d41186a2900003703002024201d41106a2900003703002023201d41086a2900003703002001201d2900003703f8070c040b200b200c41f485c3001036000b41cc9ec800413541b8a1cc001033000b200b201941e485c3001036000b202620092903003703002024200a2903003703002023200f290300370300200120012903183703f8070b024002402002280200220c0d0041012129410021280c010b20002802002220200c412c6c6a212a2036202241306c6a21104101212941002128034002400240200141f8076a2020410c6a220c460d00200c200141f8076a412010e7070d010b202041086a222c280200212702400240202120224d0d00202741306c210e410021182020280200222b210c02400340200e450d042010200c460d01200c2010412010e7072119201841016a2118200e41506a210e200c41306a210c20190d000b20194541016a41017120186a417f6a21180b4200202b201841306c6a220c290320225220012903e80422547d22532053205256200c41286a2903002253200141e8046a41086a2903007d2052205454ad7d225220535620522053511b220e1b225342002052200e1b225284500d01200c41206a220c2053370300200c20523703080c020b2027450d010c050b200c200c41306a20272018417f736a41306c10e5071a202c2027417f6a360200024020292028470d00202941016a220c2029490d112029410174220e200c200e200c4b1b220c41ffffffff0371200c470d11200c410274220c4100480d110240024002400240024020290d00200c0d010c030b2029410274220e200c460d03200e0d01200c450d020b200c10272234450d190c020b2034200e200c102b2234450d180c010b410421344100210c0b200c41027621290b203420284102746a2022360200202841016a21280b2020412c6a2220202a470d000b0b02400240203528020422224102490d002026201d41186a2900003703002024201d41106a2900003703002023201d41086a2900003703002001201d2900003703f8070c010b202620092903003703002024200a2903003703002023200f290300370300200120012903183703f8070b02402002280200220c450d0020002802002220200c412c6c6a212a2036202241306c6a2110034002400240200141f8076a2020410c6a220c460d00200c200141f8076a412010e7070d010b202041086a222c28020021270240202120224b0d0020270d050c010b202741306c210e410021182020280200222b210c02400340200e450d022010200c460d01200c2010412010e7072119201841016a2118200e41506a210e200c41306a210c20190d000b20194541016a41017120186a417f6a21180b02404200202b201841306c6a220c290320225220012903e80422547d22532053205256200c41286a2903002253200141e8046a41086a2903007d2052205454ad7d225220535620522053511b220e1b225342002052200e1b225284500d00200c41206a220c2053370300200c20523703080c010b200c200c41306a20272018417f736a41306c10e5071a202c2027417f6a360200024020292028470d00202941016a220c2029490d112029410174220e200c200e200c4b1b220c41ffffffff0371200c470d11200c410274220c4100480d1102400240024002402029450d002029410274220e200c460d030240200e450d002034200e200c102b2234450d1b0c040b200c0d010c020b200c450d010b200c10272234450d180c010b410421344100210c0b200c41027621290b203420284102746a2022360200202841016a21280b2020412c6a2220202a470d000b0b203510292034417c6a21182028410274220e210c024003400240200c0d00410021180c020b200c417c6a210c201841046a221828020041014b0d000b0b2034210c024003400240200e0d004100210c0c020b200e417c6a210e200c2802002110200c41046a210c20104102490d000b4101210c0b0240202941ffffffff0371450d00203410290b024002400240024020180d00200c450d01201d2001290318370000201d41186a2009290300370000201d41106a200a290300370000201d41086a200f2903003700000c030b200c450d0220012001280210417f6a360210201b41086a210c02400240201c450d00201c417f6a210e200c20114106746a2118201b20114102746a41a8086a280200210c02400340200c2f01062111200e450d01200e417f6a210e200c20114102746a41a8086a280200210c0c000b0b200c410020111b221b41086a220e2011417f6a410020111b22114106746a220c2900002152200c2900082153200c2900102154200c41186a2900002155200c2900202156200c41286a2900002158200c41306a2900002157200c41386a290000215941012137200c200e201141016a221c4106746a2011417f73220e201b2f01066a41067410e5071a201b41c8056a221020114105746a220c290000215a200c290008215b200c290010215c200c41186a290000215d200c2010201c4105746a200e201b2f01066a41057410e5071a201b201b2f0106417f6a3b0106201841386a2059370000201841306a2057370000201841286a205837000020182056370020201841186a2055370000201820543700102018205337000820182052370000201d41186a205d370000201d205c370010201d205b370008201d205a370000201b2f0106210c0c010b200c20114106746a200c201141016a220e4106746a2011417f73220c201b2f01066a41067410e5071a201b41c8056a221820146a2018200e4105746a200c201b2f01066a41057410e5071a201b201b2f0106417f6a220c3b0106410021370b200c41ffff037141044b0d0141002128200141086a210e201b210c410021220240024002400240024002400240024002400240024002400240024002400340200c280200221c450d1102400240200c33010422524200520d0041002127201c4100201c2f0106220c1b211c42002052422086200c1b200ead8421520c010b2052422086200ead844280808080707c2152410121270b02400240201c41a8086a220e2052422088a7221841016a220c410274222a6a221d28020022142f01062219200e2018410274222b6a222928020022102f010622206a2233410b490d0020270d052019450d01201441c0006a2900002158201441386a2900002157201441306a2900002159201441286a290000215a201441206a2900002153201441186a2900002154201441106a290000215520142900082156201441086a201441c8006a201941067441406a10e5071a201441e0056a290000215e201441d8056a290000215b201441d0056a290000215c20142900c805215d201441c8056a201441e8056a201941057441606a10e5071a20220d03410021100c040b202241016a2122201c2f01062121200141f8076a41386a222c201c41086a223420184106746a220e41386a290000370300200141f8076a41306a2235200e41306a290000370300200141f8076a41286a2231200e41286a2900003703002008200e41206a2900003703002026200e41186a2900003703002024200e41106a2900003703002023200e41086a2900003703002001200e2900003703f807200e2034200c4106746a20212018417f7322346a41067410e5071a201041086a223220204106746a220e41386a202c290300370000200e41306a2035290300370000200e41286a2031290300370000200e41206a2008290300370000200e41186a2026290300370000200e41106a2024290300370000200e41086a2023290300370000200e20012903f8073700002032202041016a22214106746a201441086a201941067410e4071a201c2f0106212c200141d0076a41186a2235201c41c8056a223120184105746a220e41186a290000370300200141d0076a41106a2218200e41106a290000370300200141d0076a41086a2232200e41086a2900003703002001200e2900003703d007200e2031200c4105746a2034202c6a41057410e5071a201041c8056a222c20204105746a220e41186a2035290300370000200e41106a2018290300370000200e41086a2032290300370000200e20012903d007370000202c20214105746a201441c8056a201941057410e4071a201d202941086a412c202a6b10e5071a0240200c201c2f0106221d4f0d00201c202b6a41ac086a210e0340200e2802002218200c3b01042018201c360200200e41046a210e201d200c41016a220c470d000b201c2f0106211d0b201c201d417f6a3b01062010201920102f01066a41016a3b0106024020224102490d00201020214102746a41a8086a201441a8086a201941027441046a10e4071a2021203341026a4f0d00201941016a2118201020204102746a41ac086a210c2021210e0340200c280200221d200e3b0104201d2010360200200c41046a210c200e41016a210e2018417f6a22180d000b0b20141029024020282027417f73724101710d0020224101470d102021410020271b20116a2111201c202b6a41a8086a280200211b0b2052a7210e201c220c2f01062218450d064101212820184105490d010c120b0b41879dc800412041b8a1cc001033000b20142802a8082110201441a8086a220c201441ac086a201941027410e5071a4100210e201041003602000340200c280200221d200e3b0104201d2014360200200c41046a210c2019200e41016a220e470d000b2022417f6a211d20142f010621190b20142019417f6a3b0106201c20184106746a220c41206a220e2900002152200e2053370000200c41186a220e2900002153200e2054370000200c41106a220e2900002154200e2055370000200c41086a220e2900002155200e2056370000200c41c0006a220e2900002156200e2058370000200c41386a220e2900002158200e2057370000200c41306a220e2900002157200e2059370000200c41286a220c2900002159200c205a370000201c20184105746a220c41d8056a220e290000215a200e205b370000200c41d0056a220e290000215b200e205c370000200c41c8056a220e290000215c200e205d370000200c41e0056a220c290000215d200c205e3700002029280200210c02402022450d002010450d052022417f6a201d470d06200c2f01062218410a4b0d07200c20184106746a220e41c0006a2056370000200e41386a2058370000200e41306a2057370000200e41286a2059370000200e41206a2052370000200e41186a2053370000200e41106a2054370000200e41086a2055370000200c20184105746a220e41e0056a205d370000200e41d8056a205a370000200e41d0056a205b370000200e41c8056a205c370000200c201841016a220e4102746a41a8086a22182010360200200c200c2f010641016a3b010620182802002218200e3b01042018200c3602000c020b200c2f01062218410b4f0d07200c20184106746a220e41c0006a2056370000200e41386a2058370000200e41306a2057370000200e41286a2059370000200e41206a2052370000200e41186a2053370000200e41106a2054370000200e41086a2055370000200c20184105746a220e41d8056a205a370000200e41d0056a205b370000200e41c8056a205c370000200e41e0056a205d370000200c200c2f010641016a3b01060c010b0240024002402020450d0020102020417f6a220e4105746a220c41e0056a290000215e200c41d8056a290000215b200c41d0056a290000215c200c41c8056a290000215d2010200e4106746a220c41c0006a2900002158200c41386a2900002157200c41306a2900002159200c41286a290000215a200c41206a2900002153200c41186a2900002154200c41106a2900002155200c41086a290000215620220d014100210e0c020b41879dc800412041b8a1cc001033000b201020204102746a41a8086a280200220e41003602002022417f6a211920102f010621200b20102020417f6a3b0106201c20184106746a220c41206a2210290000215220102053370000200c41186a2210290000215320102054370000200c41106a2210290000215420102055370000200c41086a2210290000215520102056370000200c41c0006a2210290000215620102058370000200c41386a2210290000215820102057370000200c41306a2210290000215720102059370000200c41286a220c2900002159200c205a370000201c20184105746a220c41d8056a2218290000215a2018205b370000200c41d0056a2218290000215b2018205c370000200c41c8056a2218290000215c2018205d370000200c41e0056a220c290000215d200c205e370000201d280200211802402022450d00200e450d082022417f6a2019470d09024020182f0106220c410a4b0d00201841c8006a201841086a200c41067410e5071a201841386a2058370000201841306a2057370000201841286a2059370000201841186a2053370000201841106a205437000020182055370008201841c0006a2056370000201841206a2052370000201841e8056a201841c8056a200c41057410e5071a201841e0056a205d370000201841d8056a205a370000201841d0056a205b3700002018205c3700c805201841ac086a201841a8086a220c20182f010641027441046a10e5071a2018200e3602a808201820182f010641016a220e3b0106200e41ffff037141016a211d4100210e0340200c280200221c200e3b0104201c2018360200200c41046a210c201d200e41016a220e470d000c030b0b418f9cc800412741b8a1cc001033000b20182f0106220c410b4f0d09201841c8006a201841086a200c41067410e5071a201841386a2058370000201841306a2057370000201841286a2059370000201841186a2053370000201841106a205437000020182055370008201841c0006a2056370000201841206a2052370000201841e8056a201841c8056a200c41057410e5071a201841e0056a205d370000201841d8056a205a370000201841d0056a205b3700002018205c3700c805201820182f010641016a3b01060b2028417f732027710d010c0c0b0240200e2802042218450d00200e280200221c2802a808210c200e2018417f6a360204200e200c360200200c4100360200201c10290c0c0b41e69cc800412141b8a1cc001033000b2011201b2f0106490d084100210e024003400240201b280200220c0d00410021114100210c0c020b200e41016a210e201b2f01042111200c211b2011200c2f01064f0d000b0b201141016a21110240200e0d00200c211b0c0b0b200c20114102746a41a8086a280200211b41002111200e417f6a220c450d0a0340201b2802a808211b200c417f6a220c0d000c0b0b0b41a79dc800412b41bc9ec8001033000b41b69cc800413041b8a1cc001033000b418f9cc800412741b8a1cc001033000b418f9cc800412741b8a1cc001033000b41a79dc800412b41d49dc8001033000b41b69cc800413041b8a1cc001033000b418f9cc800412741b8a1cc001033000b419cf7ca00412841b8a1cc001033000b201141016a21110c010b41a486c300412941b8a1cc001033000b2037450d002011201b2f0106490d000340201b280200220c450d01201b2f0104210e200c211b200e200c2f01064f0d000b0b02402025450d00202541306c450d00203610290b20012802d402220c450d00200c41306c450d0020012802d00210290b2016450d05201641306c450d05201a10290c050b20222021419486c3001036000b20222021418486c3001036000b201d2001290318370000201d41186a2009290300370000201d41106a200a290300370000201d41086a200f2903003700000b2016450d01201641306c450d01201a10290c010b2004410041d20810e6071a41d8081027220c450d0c200c4100360200200c41046a200141f8076a41d40810e4071a200c200e28020022183602a808200e200c360200200e200e280204221a41016a360204201841003b01042018200c360200200141d0026a41026a221d203c2d00003a00002010203d2903003703002019203e2903003703002014203f2903003703002008204029030037030020162041290000370000200120012f01ac023b01d002200120012903f8013703f807203620422903003703002035204329030037030020342044290300370300200120012903b0023703e804201a201c470d01200c2f01062218410a4b0d03200c20184106746a220e410a6a201d2d00003a0000200e41086a20012f01d0023b0000200e41176a2030360000200e41136a202f360000200e410f6a202e360000200e410b6a202d360000200e41c0006a2016290000370000200e413b6a2008290300370000200e41236a2010290300370000200e411b6a20012903f807370000200e41336a2014290300370000200e412b6a2019290300370000200c20184105746a220e41e0056a2036290300370000200e41d8056a2035290300370000200e41d0056a2034290300370000200e41c8056a20012903e804370000200c201841016a220e4102746a41a8086a2011360200200c200e3b01062011200c3602002011200e3b010441001a201b1a0b201e201f470d010c070b0b41b69cc800413041b8a1cc001033000b418f9cc800412741b8a1cc001033000b1039000b1038000b200b200c41d485c3001036000b1032000b201741ffffff1f71450d00201510290b200b41016a210b0240201341ffffff3f71450d00201210290b200b2003470d000b2001280208220c450d00200128021021180240200128020c220e450d000340200c2802a808210c200e417f6a220e0d000b0b02402018450d00410021110340024002400240200c450d002018417f6a21182011200c2f0106490d0141002108034002400240200c280200220e0d00410021114100210e0c010b200841016a2108200c2f010421110b200c1029200e210c2011200e2f01064f0d000b201141016a2111024020080d00200e210c0c030b200e20114102746a41a8086a280200210c410021112008417f6a220e450d020340200c2802a808210c200e417f6a220e0d000c030b0b41a79dc800412b41e0f6c4001033000b201141016a21110b20180d000b0b200c450d00200c280200210e200c1029200e450d000340200e280200210c200e1029200c210e200c0d000b0b200141003602d004200141003602c804024020022802002251450d00200141c8046a41086a213e2000280200210c200141e8046a41186a2137200141d0076a41106a2143200141d0076a41086a2144200141d0026a41016a223b41286a2147203b41206a2148200141f5026a21492051210e41002126024002400340200e20264d0d01200141d0076a41186a2246200c2026412c6c223d6a221141246a29000037030020432011411c6a2900003703002044201141146a2900003703002001201129000c3703d00702402011280208450d00410021320340200c203d6a280200210c200141386a41186a22152046290300370300200141386a41106a22062043290300370300200141386a41086a221e2044290300370300200120012903d007370338200141003a0058200141b8016a41186a2210200c203241306c6a220c41186a290000370300200141b8016a41106a2207200c41106a290000370300200141b8016a41086a2219200c41086a29000037030041012114200141013a00d8012001200c2900003703b8010240024020012802c80422170d0041002117410021160c010b2017211a20012802cc04221b211c02400340201a41286a210c201a2f0106221d41216c210e41002108024002400340200821110240200e0d00201d21110c020b02400240200141386a200c41606a412010e7072208450d0041012118200841004e0d010c030b200c2d00002208450d03417f410120081b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201c0d00410121140c030b201c417f6a211c201a20114102746a41a0036a280200211a0c010b0b410021140b2017211a0340201a41286a210c201a2f0106221c41216c210e41002108024002400340200821110240200e0d00201c21110c020b02400240200141b8016a200c41606a412010e7072208450d0041012118200841004e0d010c030b200c2d000022084101460d03417f4101200841014b1b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201b0d00410021160c030b201b417f6a211b201a20114102746a41a0036a280200211a0c010b0b201a20114102746a41f4026a21160b200141a0036a41186a22382015290300370300200141a0036a41106a22392006290300370300200141a0036a41086a223a201e290300370300200120012903383703a003200141003a00c003024002402017450d0020012802cc04211a0c010b200141f8076a410041eb0210e6071a2047410036000020484200370000203b41186a4200370000203b41106a4200370000203b41086a4200370000203b420037000041a00310272217450d074100211a201741003b010620174100360200201741086a200141f8076a41eb0210e4071a20174198036a204929000037000020174193036a200141d0026a41206a2900003700002017418b036a200141d0026a41186a29000037000020174183036a200141d0026a41106a290000370000201741fb026a200141d0026a41086a290000370000201720012900d0023700f302200141003602cc04200120173602c8040b024002400340201741286a210c20172f0106221b41216c210e4100210802400340200821110240200e0d00201b21110c020b02400240200141a0036a200c41606a412010e7072208450d0041012118200841004e0d010c030b200c2d00002208450d04417f410120081b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201a450d00201a417f6a211a201720114102746a41a0036a28020021170c010b0b203720012903a003370000203741086a203a290300370000203741106a2039290300370000203741186a2038290300370000203741206a200141a0036a41206a2d00003a00002001203e3602fc04200120113602f804200120173602f0044100210c200141003602ec042001200141c8046a3602f4040c010b2001203e3602fc04200120113602f804200120173602f0042001201a3602ec042001200141c8046a3602f4044101210c0b2001200c3602e804200141f8076a41086a222c201e290300370300200141f8076a41106a22342006290300370300200141f8076a41186a22352015290300370300200141f8076a41206a221d200141386a41206a2d00003a0000200120012903383703f80741341027220c450d06200c4200370208200c428180808010370200200c20012903f807370210200c20012f00d0023b0031200c41186a202c290300370200200c41206a2034290300370200200c41286a2035290300370200200c41306a201d2d00003a0000200c41336a200141d0026a41026a22152d00003a0000024002400240024002400240024002400240024002400240200141e8046a200c10d903280200221c28020041016a220c41014d0d00201c200c3602002001201c360288042038201029030037030020392007290300370300203a2019290300370300200120012903b8013703a003200141013a00c0030240024020012802c8042217450d0020012802cc04211a0c010b200141f8076a410041eb0210e6071a2047410036000020484200370000203b41186a4200370000203b41106a4200370000203b41086a4200370000203b420037000041a00310272217450d134100211a201741003b010620174100360200201741086a200141f8076a41eb0210e4071a20174198036a204929000037000020174193036a200141d0026a41206a2900003700002017418b036a200141d0026a41186a29000037000020174183036a200141d0026a41106a290000370000201741fb026a200141d0026a41086a290000370000201720012900d0023700f302200141003602cc04200120173602c8040b024002400340201741286a210c20172f0106221b41216c210e4100210802400340200821110240200e0d00201b21110c020b02400240200141a0036a200c41606a412010e7072208450d0041012118200841004e0d010c030b200c2d000022084101460d04417f4101200841014b1b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201a450d00201a417f6a211a201720114102746a41a0036a28020021170c010b0b203720012903a003370000203741086a203a290300370000203741106a2039290300370000203741186a2038290300370000203741206a200141a0036a41206a2d00003a00002001203e3602fc04200120113602f804200120173602f0044100210c200141003602ec042001200141c8046a3602f4040c010b2001203e3602fc04200120113602f804200120173602f0042001201a3602ec042001200141c8046a3602f4044101210c0b2001200c3602e804202c20192903003703002034200729030037030020352010290300370300201d200141b8016a41206a2d00003a0000200120012903b8013703f80741341027220c450d12200c4200370208200c428180808010370200200c20012903f807370210200c20012f00d0023b0031200c41186a202c290300370200200c41206a2034290300370200200c41286a2035290300370200200c41306a201d2d00003a0000200c41336a20152d00003a0000200141e8046a200c10d903280200220c28020041016a220e41014d0d00200c200e3602002001200c3602a80402400240024002400240024002400240024002400240024002402014450d0020160d01200141a8046a201c10da030c170b2016450d01200141f8076a201c10db032001280284082140200128028008214c20012802fc07212e20012802f807212d200141f8076a200c10db032001280284082141200128028008214d20012802fc0721420240202d20012802f807223c460d00202d28020841016a220c41004c0d08202d200c360208203c280208220c41016a220e41004c0d07203c200e360208202d41106a203c41106a412010e7070d09202d2d0030203c2d0030470d09203c200c360208202d202d280208417f6a3602080b20400d02410021180c030b20014188046a200c10da030c150b200141a8046a201c10da030c140b202e417c6a211b20404102742108204141027421112042417c6a211c4100211803402011450d0102400240201b20086a280200220c201c20116a280200220e460d00200c28020841016a221741004c0d05200c2017360208200e280208221741016a221a41004c0d04200e201a360208200c41106a200e41106a412010e7070d01200c2d0030200e2d0030470d01200e2017360208200c200c280208417f6a3602080b2011417c6a2111201841016a21182008417c6a22080d010c020b0b200e2017360208200c200c280208417f6a3602080b2001410036028008200142043703f807204020186b2117202e2040410274222a6a2111204120186b225041016a210e20414102742129024020420d004100210c202e450d072017450d0720172011202e6b410276220c200c20174b1b210c0c070b204220296a211b202e450d054100210c410021080240200e450d00200e201b20426b41027622082008200e4b1b21080b02402017450d0020172011202e6b410276220c200c20174b1b210c0b2008200c6a220c20084f0d06410421214100211841002115204221080340024002402008450d000240200e0d004100210e0c010b200e417f6a210e201b2008460d002008280200220c28020041016a221a41014d0d0b200c201a360200200c450d00200841046a21080c010b2017450d092011202e6b410276220c4100200c20176b22082008200c4b1b220c4d0d092011200c4102746b417c6a2211280200220c28020041016a220841014d0d0a200c2008360200200c450d092017417f6a2117410021080b0240201520012802fc07470d0002400240024020080d0020170d014100211a0c020b4100211c4100211a0240200e450d00200e201b20086b410276221a201a200e4b1b211a0b02402017450d0020172011202e6b410276221c201c20174b1b211c0b417f201a201c6a221c201c201a491b211a0c010b20172011202e6b410276221a201a20174b1b211a0b200141f8076a2015417f201a41016a221c201c201a491b10980120012802f80721210b202120186a200c3602002001201541016a221536028008201841046a21180c000b0b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b203c200c360208202d202d280208417f6a360208024020412040204020414b220c1b220e450d00204dad4220862042ad842252204cad422086202ead842253200c1b2254a7221a200e410274220e6a211720532052200c1b2252a7211b20402041200c1b211c41012111200e2118201a210c201a210802400340024002402011450d002017200c6b41027620114d0d03200c20114102746a210c0c010b2017200c460d020b200c200828020010da03200c41046a210c41002111200841046a21082018417c6a22180d000b0b0240201c0d0041004100419087c3001036000b201a201b28020010da03201c4102742111201b210c0340200c28020022082008280200417f6a3602000240200c28020022082802000d000240200828020c2218450d0020182018280200417f6a360200200828020c22182802000d00201841086a10dc03200828020c22182018280204417f6a360204200828020c22082802040d00200810290b200c28020022082008280204417f6a360204200c28020022082802040d00200810290b200c41046a210c2011417c6a22110d000b024020524280808080f0ffffff3f83500d00201b10290b201a210c0340200c28020022112011280200417f6a3602000240200c28020022112802000d000240201128020c2208450d0020082008280200417f6a360200201128020c22082802000d00200841086a10dc03201128020c22082008280204417f6a360204201128020c22112802040d00201110290b200c28020022112011280204417f6a360204200c28020022112802040d00201110290b200c41046a210c200e417c6a220e0d000b024020544280808080f0ffffff3f83500d00201a10290b203c203c280200417f6a220c360200203241016a2132200c0d0d0240203c28020c220c450d00200c200c280200417f6a360200203c28020c220c2802000d00200c41086a10dc03203c28020c220c200c280204417f6a360204203c28020c220c2802040d00200c10290b203c203c280204417f6a220c360204200c0d0d203c10290c0d0b41004100418087c3001036000b0240200e0d004100210c0c010b200e201b20426b410276220c200c200e4b1b210c0b200141f8076a4100200c10980120012802f807222120012802800822154102746a210c02402042450d00200e450d00204220414102746a211b2041417f7320186a21082042210e0340201b200e460d01200e280200221828020041016a221a41014d0d032018201a360200200c2018360200201541016a2115200c41046a210c200e41046a210e200841016a221820084f211a20182108201a0d000b0b0240202e450d002017450d0002402011202e6b410276220e20174d0d00200e2017417f736a2208200e4f0d01201120084102746b417c6a21110b2011202e460d0003402011417c6a2211280200220e28020041016a220841014d0d03200e2008360200200c200e360200201541016a2115200c41046a210c202e2011470d000b0b20012015360280080b20012802fc07214f200141f8016a41186a224a4200370300200141f8016a41106a22454200370300200141f8016a41086a224b4200370300200142003703f8012038420037030020394200370300203a4200370300200142003703a003410021070240024020150d00427f2152427f2155410021204100212b4100213341002122410021270c010b2015417f6a2119427f215241002120427f21554100212b427f2153427f21544100211a0240024002400240024003402021201a4102746a280200220c28020841016a220e41004c0d01201a41016a211b0240200c2d00300d00200c200e360208200141d0026a41186a221c200c41286a290000370300200141d0026a41106a221d200c41206a290000370300200141d0026a41086a2206200c41186a290000370300200c200c280208417f6a3602082001200c2900103703d0022015201b41002019201a4b1b220c4d0d032021200c4102746a280200220c28020841016a220e41004c0d04200c200e3602082037200c41286a290000370300200141e8046a41106a221e200c41206a290000370300200141e8046a41086a2210200c41186a290000370300200c200c280208417f6a3602082001200c2900103703e8042015201a2015201a1b417f6a220c4d0d052021200c4102746a280200220c28020841016a220e41004c0d06200c200e3602082035200c41286a2900003703002034200c41206a290000370300202c200c41186a290000370300200c200c280208417f6a3602082001200c2900103703f807200041086a280200412c6c220e2111200028020022082118024003402018210c2011450d010240200141d0026a200c410c6a2217460d00201141546a2111200c412c6a21182017200141d0026a412010e7070d010b0b200c41086a28020041306c2111200c280200211803402018210c2011450d010240200141e8046a200c460d00201141506a2111200c41306a2118200c200141e8046a412010e7070d010b0b2052200c41206a2903002258582054200c41286a29030022565820542056511b0d00204a20372903003703002045201e290300370300204b2010290300370300203a20062903003703002039201d2903003703002038201c290300370300200120012903e8043703f801200120012903d0023703a0034101212b2058215220562155201a212020562153205621540b03402008210c200e450d010240200141d0026a200c410c6a2211460d00200e41546a210e200c412c6a21082011200141d0026a412010e7070d010b0b200c41086a28020041306c210e200c280200211103402011210c200e450d010240200141f8076a200c460d00200e41506a210e200c41306a2111200c200141f8076a412010e7070d010b0b205321542052200c41206a2903002258582053200c41286a29030022565820532056511b0d00204a203529030037030020452034290300370300204b202c290300370300203a20062903003703002039201d2903003703002038201c290300370300200120012903f8073703f801200120012903d0023703a0034100212b2058215220562155201a212020562153205621540b201b211a201b2015470d000b20152133202b2122202021270c050b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b200c201541a087c3001036000b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b200c201541b087c3001036000b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b200141003602d802200142043703d002202720226a214e0240024020330d00410121164100210c0c010b2015417f6a213f41012116204e4101712124410021072033210c4100211d02400240024002400240034002400240024002400240024002400240200c201d4d0d002021201d4102746a2228280200221428020841016a220c41004c0d01201d41016a21232014200c36020820142d00300d072015201d2015201d1b417f6a220c4d0d022021200c4102746a2231280200223628020841016a220c41004c0d032036200c3602080240200041086a222f280200220c0d002023210c201d211c0c070b20002802002217200c412c6c6a2106203641106a210e201441106a211a202b45201d20204671212520240d044100211b201d211c034002400240201a2017410c6a220c460d00200c201a412010e7070d010b201741086a2219280200221041306c2111410021082017280200221e210c024003402011450d02200e200c460d01200c200e412010e7072118200841016a2108201141506a2111200c41306a210c20180d000b20184541016a41017120086a417f6a21080b0240427f201e200841306c6a220c290320225420527c225320532054542211200c41286a290300225320557c2011ad7c225620535420562053511b22111b4200205420527d22582058205456205320557d2054205254ad7d225420535620542053511b22181b201c410171221e1b2253427f205620111b4200205420181b201e1b225484500d00200c41206a220c2053370300200c20543703080c010b200c200c41306a20102008417f736a41306c10e5071a20192010417f6a36020041002122410020162026201b461b211602402025450d00202021272020211c0c010b2015201d4d0d0b2028280200220c28020041016a221141014d0d11200c20113602002031280200221128020041016a220841014d0d11201120083602000240200720012802d402470d00200141d0026a20074101108d0120012802d80221070b20012802d00220074103746a220820113602042008200c3602002001200741016a22073602d802202b212220202127201d211c0b201b41016a211b2017412c6a22172006470d000c060b0b201d200c41c087c3001036000b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b200c201541d087c3001036000b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b4100211b201d211c034002400240201a2017410c6a220c460d00200c201a412010e7070d010b201741086a2219280200221041306c2111410021082017280200221e210c024003402011450d02200e200c460d01200c200e412010e7072118200841016a2108201141506a2111200c41306a210c20180d000b20184541016a41017120086a417f6a21080b02404200201e200841306c6a220c290320225420527d22532053205456200c41286a290300225320557d2054205254ad7d225620535620562053511b22111b427f205420527c225820582054542218205320557c2018ad7c225420535420542053511b22181b201c410171221e1b22534200205620111b427f205420181b201e1b225484500d00200c41206a220c2053370300200c20543703080c010b200c200c41306a20102008417f736a41306c10e5071a20192010417f6a36020041002122410020162026201b461b211602402025450d00202021272020211c0c010b2015201d4d0d062028280200220c28020041016a22114102490d0c200c20113602002031280200221128020041016a22084102490d0c201120083602000240200720012802d402470d00200141d0026a20074101108d0120012802d80221070b20012802d00220074103746a220820113602042008200c3602002001200741016a22073602d802202b212220202127201d211c0b201b41016a211b2017412c6a22172006470d000b0b201c41016a210c0b2015200c4100203f201c4b1b220c4d0d032021200c4102746a280200222528020841016a220c41004c0d042025200c3602080240202f280200220e450d0020002802002217200e412c6c6a2106202b410146201d202046712131202541106a2108201441106a211b4100211a202120234100203f201d4b1b222f4102746a2130034002400240201b2017410c6a220c460d00200c201b412010e7070d010b201741086a2219280200221041306c210e410021112017280200221e210c02400340200e450d022008200c460d01200c2008412010e7072118201141016a2111200e41506a210e200c41306a210c20180d000b20184541016a41017120116a417f6a21110b201e201141306c6a220c2903202154200c41286a2903002153024002400240201c410171450d0020240d014200205320557d2054205254ad7d2256205420527d2258205456205620535620562053511b220e1b215342002058200e1b21540c020b024020240d00427f205320557c205420527c2256205454220ead7c2254200e205420535420542053511b220e1b2153427f2056200e1b21540c020b4200205320557d2054205254ad7d2256205420527d2258205456205620535620562053511b220e1b215342002058200e1b21540c010b427f205320557c205420527c2256205454220ead7c2254200e205420535420542053511b220e1b2153427f2056200e1b21540b02402054205384500d00200c41206a220c2054370300200c20533703080c010b200c200c41306a20102011417f736a41306c10e5071a20192010417f6a360200410020162026201a461b21164101212202402031450d00202021272020211c0c010b2015201d4d0d082028280200220c28020041016a220e41014d0d0b200c200e3602002015202f4d0d092030280200220e28020041016a221141014d0d0b200e20113602000240200720012802d402470d00200141d0026a20074101108d0120012802d80221070b20012802d00220074103746a2211200e3602042011200c3602002001200741016a22073602d802202b212220202127201d211c0b201a41016a211a2017412c6a22172006470d000b2025280208210c0b2025200c417f6a36020820362036280208417f6a3602082014280208210c0b2014200c417f6a3602082015210c2023211d20232033470d000b2015210c0c050b201d201541e087c3001036000b200c201541f087c3001036000b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b201d2015418088c3001036000b202f2015419088c3001036000b024020224101470d002027200c417f6a460d090b41c0001027220e450d12200e20012903a003370000200e20012903f801370020200e41186a2038290300370000200e41106a2039290300370000200e41086a203a290300370000200e41286a204b290300370000200e41306a2045290300370000200e41386a204a2903003700000240204e20504b0d002041417f6a221b450d0702402041450d004100210c41012111024002400340201121082042200c4102746a2217280200220c280200221141016a221841014d0d05200c20183602000240200c28020841016a41004c0d00200c20113602002037200c41286a290000370300200141e8046a41106a200c41206a290000370300200141e8046a41086a200c41186a2900003703002001200c2900103703e80420082041460d02204220084102746a221a280200220c280200221141016a221841014d0d06200c2018360200200c28020841016a41004c0d03200c20113602002035200c41286a2900003703002034200c41206a290000370300202c200c41186a2900003703002001200c2900103703f8074100210c02400340200c41c000460d01200e200c6a2111200c41206a210c2011200141e8046a412010e7070d000b4100210c0340200c41c000460d01200e200c6a2111200c41206a210c2011200141f8076a412010e7070d000c0e0b0b201a201728020010da032008201b460d0c200841016a21112008210c0c010b0b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b2008204141d088c3001036000b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b4100410041c088c3001036000b2040417f6a221b450d052040450d014100210c41012111034020112108202e200c4102746a2217280200220c280200221141016a221841014d0d01200c2018360200200c28020841016a41004c0d03200c20113602002037200c41286a290000370300200141e8046a41106a200c41206a290000370300200141e8046a41086a200c41186a2900003703002001200c2900103703e80420082040460d04202e20084102746a221a280200220c280200221141016a221841014d0d01200c2018360200200c28020841016a41004c0d05200c20113602002035200c41286a2900003703002034200c41206a290000370300202c200c41186a2900003703002001200c2900103703f8074100210c02400340200c41c000460d01200e200c6a2111200c41206a210c2011200141e8046a412010e7070d000b4100210c0340200c41c000460d01200e200c6a2111200c41206a210c2011200141f8076a412010e7070d000c080b0b201a201728020010da032008201b460d06200841016a21112008210c0c000b0b00000b4100410041a088c3001036000b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b2008204041b088c3001036000b41cc8ccc004118200141e0036a41f086c30041f48ccc00103a000b20014188046a20012802a80410da030c010b200141a8046a20012802880410da030b200e10290b20012802d002221b20074103746a210820012802d402211c201b210e02400240024002402007450d00201b2111024003402011280200220c450d01024002400240200c201141046a280200220e10dd030d00200e200c10dd03450d02200e2802080d08200e41086a2117200e417f360208200e410c6a2118200e28020c221a450d01201a201a280200417f6a3602002018280200221a2802000d01201a41086a10dc032018280200221a201a280204417f6a3602042018280200221a2802040d01201a10290c010b200c2802080d06200c41086a2117200c417f360208200c410c6a2118200c28020c221a450d00201a201a280200417f6a3602002018280200221a2802000d00201a41086a10dc032018280200221a201a280204417f6a3602042018280200221a2802040d00201a10290b201841003602002017201728020041016a3602000b200e200e280200417f6a2218360200024020180d000240200e28020c2218450d0020182018280200417f6a360200200e28020c22182802000d00201841086a10dc03200e28020c22182018280204417f6a360204200e28020c22182802040d00201810290b200e200e280204417f6a221836020420180d00200e10290b200c200c280200417f6a220e3602000240200e0d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d00200e41086a10dc03200c28020c220e200e280204417f6a360204200c28020c220e2802040d00200e10290b200c200c280204417f6a220e360204200e0d00200c10290b201141086a22112008470d000c030b0b201141086a210e0b2008200e460d000340200e220c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2211450d0020112011280200417f6a360200200e28020c22112802000d00201141086a10dc03200e28020c22112011280204417f6a360204200e28020c220e2802040d00200e10290b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10290b200c41086a210e200c41046a220c28020022112011280200417f6a3602000240200c28020022112802000d000240201128020c2218450d0020182018280200417f6a360200201128020c22182802000d00201841086a10dc03201128020c22182018280204417f6a360204201128020c22112802040d00201110290b200c28020022112011280204417f6a360204200c280200220c2802040d00200c10290b2008200e470d000b0b0240201c41ffffffff0171450d00201b10290b02402015450d002015410274210e2021210c0340200c28020022112011280200417f6a3602000240200c28020022112802000d000240201128020c2208450d0020082008280200417f6a360200201128020c22082802000d00200841086a10dc03201128020c22082008280204417f6a360204201128020c22112802040d00201110290b200c28020022112011280204417f6a360204200c28020022112802040d00201110290b200c41046a210c200e417c6a220e0d000b0b0240204f41ffffffff0371450d00202110290b02402041450d002042210c0340200c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2211450d0020112011280200417f6a360200200e28020c22112802000d00201141086a10dc03200e28020c22112011280204417f6a360204200e28020c220e2802040d00200e10290b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10290b200c41046a210c2029417c6a22290d000b0b0240204d41ffffffff0371450d00204210290b203c203c280200417f6a220c3602000240200c0d000240203c28020c220c450d00200c200c280200417f6a360200203c28020c220c2802000d00200c41086a10dc03203c28020c220c200c280204417f6a360204203c28020c220c2802040d00200c10290b203c203c280204417f6a220c360204200c0d00203c10290b201641ff0171210802402040450d00202e210c0340200c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2211450d0020112011280200417f6a360200200e28020c22112802000d00201141086a10dc03200e28020c22112011280204417f6a360204200e28020c220e2802040d00200e10290b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10290b200c41046a210c202a417c6a222a0d000b0b203220086a2132204c41ffffffff0371450d02202e10290c020b41c78dcc004110200141e0036a41c8a7c70041e88dcc00103a000b41c78dcc004110200141e0036a41c8a7c70041e88dcc00103a000b202d202d280200417f6a220c3602000240200c0d000240202d28020c220c450d00200c200c280200417f6a360200202d28020c220c2802000d00200c41086a10dc03202d28020c220c200c280204417f6a360204202d28020c220c2802040d00200c10290b202d202d280204417f6a220c360204200c0d00202d10290b20012802a804220c200c280200417f6a220e3602000240200e0d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d00200e41086a10dc03200c28020c220e200e280204417f6a360204200c28020c220e2802040d00200e10290b200c200c280204417f6a220e360204200e0d00200c10290b200128028804220c200c280200417f6a220e360200200e0d010240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d00200e41086a10dc03200c28020c220e200e280204417f6a360204200c28020c220e2802040d00200e10290b200c200c280204417f6a220e360204200e0d01200c10290c010b200c200c280200417f6a220e3602000240200e0d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d00200e41086a10dc03200c28020c220e200e280204417f6a360204200c28020c220e2802040d00200e10290b200c200c280204417f6a220e360204200e0d00200c10290b203241016a2132201c201c280200417f6a220c360200200c0d000240201c28020c220c450d00200c200c280200417f6a360200201c28020c220c2802000d00200c41086a10dc03201c28020c220c200c280204417f6a360204201c28020c220c2802040d00200c10290b201c201c280204417f6a220c360204200c0d00201c10290b0240200041086a280200220e20264d0d002000280200220c203d6a28020820324d0d020c010b0b2026200e41e086c3001036000b202641016a22262051470d000b20012802c804220c450d0220012802d0042117024020012802cc04220e450d000340200c2802a003210c200e417f6a220e0d000b0b2017450d014100211102400340200c450d014100210802402011200c2f0106490d00034002400240200c280200220e0d00410021114100210e0c010b200841016a2108200c2f010421110b200c1029200e210c2011200e2f01064f0d000b200e210c0b201141016a210e200c20114102746a41f4026a2802002118200c201141216c6a41286a2d0000211a0240024020080d00200e21110c010b200c200e4102746a41a0036a280200210c410021112008417f6a220e450d000340200c2802a003210c200e417f6a220e0d000b0b201a41ff01714102460d032017417f6a211720182018280200417f6a220e3602000240200e0d000240201828020c220e450d00200e200e280200417f6a360200201828020c220e2802000d00200e41086a10dc03201828020c220e200e280204417f6a360204201828020c220e2802040d00200e10290b20182018280204417f6a220e360204200e0d00201810290b20170d000c030b0b41a79dc800412b41e0f6c4001033000b2026200e41d086c3001036000b200c450d00200c280200210e200c1029200e450d000340200e280200210c200e1029200c210e200c0d000b0b200141d0106a24000f0b1030000bad0302027f037e230041d0006b22042400200441386a20024201200242015620034200522003501b22051b22022003420020051b220342ffff03420010e007200441286a20042903382206200441386a41086a290300220742ffff03420010d507200441186a20022003200620022004290328852003200441286a41086a2903008584420052ad7c22084201200842015620072008200654ad7c22064200522006501b22051b22082006420020051b220610e0070240024002402004290318220742808004544100200441186a41086a290300501b450d00200441086a200220002002200054200320015420032001511b22051b2003200120051b2008200610e0072004290308220342808004544100200441086a41086a290300501b450d012007a741ffff037122050d0241f0a6c700411941dcaac7001033000b2004411136024c200441ecaac70036024841f1a8c70041de00200441c8006a41a8a7c70041d0a9c700103a000b2004411136024c200441ecaac70036024841f1a8c70041de00200441c8006a41a8a7c70041ccaac700103a000b200441d0006a24002003a741ffff037141ffff036c20056e0b810103017f017e027f230041106b220324000240024002402002ad4220862000ad8410232204428080808010540d00410121022004a722052d0000220641014b0d0020060e020102010b41e891cc00412e200341086a419893cc00419892cc00103a000b410021020b2005102902402001450d00200010290b200341106a240020020b3400200041f5bec50036020420004100360200200041146a4104360200200041106a4180c4c200360200200041086a42083702000bcd0e05067f017e017f017e057f230041f0026b2202240002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002005417f6a220541024b0d0420050e03010203010b200042033703000c040b024020064104490d002004280001210720012003417b6a22053602042001200441056a36020020054108490d00200429000521082001200341736a220936020420012004410d6a36020041002105200241003a0028200341726a21030240034020092005460d01200241086a20056a200420056a2206410d6a2d00003a00002001200336020420012006410e6a3602002002200541016a22063a00282003417f6a21032006210520064120470d000b20024190026a41086a200241086a41086a290300220a370300200241f0016a41186a2204200241086a41186a290300370300200241f0016a41106a2205200241086a41106a290300370300200241f0016a41086a2203200a37030020022002290308220a370390022002200a3703f001200241086a200110e10220022d00084101460d01200241a8016a2201200241c1006a290000370300200241a0016a2206200241396a29000037030020024198016a2209200241316a29000037030020024190016a220b200241296a290000370300200241f0006a41186a220c200241216a290000370300200241f0006a41106a220d200241196a290000370300200241f0006a41086a220e200241116a290000370300200241d0016a41086a220f2003290300370300200241d0016a41106a22032005290300370300200241d0016a41186a2205200429030037030020022002290009370370200220022903f0013703d001200241b0016a41186a22042005290300370300200241b0016a41106a22052003290300370300200241b0016a41086a2203200f290300370300200220022903d0013703b001200041106a20073602002000200837030820004200370300200020022903b0013702142000411c6a2003290300370200200041246a20052903003702002000412c6a2004290300370200200020022903703702342000413c6a200e290300370200200041c4006a200d290300370200200041cc006a200c290300370200200041d4006a200b290300370200200041dc006a2009290300370200200041e4006a2006290300370200200041ec006a20012903003702000c050b200541ff0171450d00200241003a00280b200042033703000c030b024020064104490d002004280001210620012003417b6a22053602042001200441056a36020020054108490d0020004201370300200429000521082001200341736a36020420012004410d6a360200200041106a200636020020002008370308200041146a200241086a41e40010e4071a0c030b200042033703000c020b024020064104490d002004280001210720012003417b6a22053602042001200441056a36020020054108490d00200429000521082001200341736a220936020420012004410d6a36020041002105200241003a0028200341726a21030240034020092005460d01200241086a20056a200420056a2206410d6a2d00003a00002001200336020420012006410e6a3602002002200541016a22063a00282003417f6a21032006210520064120470d000b20024190026a41086a200241086a41086a290300220a370300200241f0016a41186a2204200241086a41186a290300370300200241f0016a41106a2205200241086a41106a290300370300200241f0016a41086a2203200a37030020022002290308220a370390022002200a3703f001200241086a200110e10220022d00084101460d01200241a8016a2201200241c1006a290000370300200241a0016a2206200241396a29000037030020024198016a2209200241316a29000037030020024190016a220b200241296a290000370300200241f0006a41186a220c200241216a290000370300200241f0006a41106a220d200241196a290000370300200241f0006a41086a220e200241116a290000370300200241d0016a41086a220f2003290300370300200241d0016a41106a22032005290300370300200241d0016a41186a2205200429030037030020022002290009370370200220022903f0013703d001200241b0016a41186a22042005290300370300200241b0016a41106a22052003290300370300200241b0016a41086a2203200f290300370300200220022903d0013703b001200041106a20073602002000200837030820004202370300200020022903b0013702142000411c6a2003290300370200200041246a20052903003702002000412c6a2004290300370200200020022903703702342000413c6a200e290300370200200041c4006a200d290300370200200041cc006a200c290300370200200041d4006a200b290300370200200041dc006a2009290300370200200041e4006a2006290300370200200041ec006a20012903003702000c030b200541ff0171450d00200241003a00280b200042033703000c010b200042033703000b200241f0026a24000ba311010c7f23004190036b2202240041002103200241003a0088032001280204417f6a2104024002400240024003402004417f460d01200241c8026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a0088032004417f6a210420052103200541c000470d000b200241386a2204200241c8026a41386a290300370300200241306a2201200241c8026a41306a290300370300200241286a2203200241c8026a41286a290300370300200241206a2205200241c8026a41206a2206290300370300200241186a2207200241c8026a41186a290300370300200241106a2208200241c8026a41106a290300370300200241086a2209200241c8026a41086a290300370300200220022903c80237030020024190016a41186a200429030037030020024190016a41106a200129030037030020024190016a41086a20032903003703002002200529030037039001200241a8026a41186a2007290300370300200241a8026a41106a2008290300370300200241a8026a41086a22042009290300370300200220022903003703a802200241c8026a200241a8026a106f4101210120022d00c8024101460d0120024188026a410f6a200241a8026a410f6a29000037000020024188026a41086a2004290000370300200220022900a80237038802410221030c020b0240200341ff0171450d00200241003a0088030b200041013a00000c020b200241a6026a20022d00cb023a000020024188026a41086a200241d5026a29000037030020024197026a200241dc026a29000037000020024184026a20062d00003a0000200220022f00c9023b01a402200220022900cd02370388022002200241e4026a280200360280024100210120022d00cc0221030b200241fc016a41026a2205200241a4026a41026a2d00003a0000200241e0016a41086a220720024188026a41086a290300370300200241e0016a410f6a220820024188026a410f6a290000370000200241d8016a41046a220920024180026a41046a2d00003a0000200220022f01a4023b01fc0120022002290388023703e00120022002280280023602d801200241e0016a210402400240024020010d00200241d4016a41026a20052d00003a0000200241b8016a41086a2007290300370300200241b8016a410f6a2008290000370000200241b0016a41046a20092d00003a0000200220022f01fc013b01d401200220022903e0013703b801200220022802d8013602b001200241a8026a41186a20024190016a41186a290300370300200241a8026a41106a20024190016a41106a290300370300200241a8026a41086a20024190016a41086a29030037030020022002290390013703a802200241c8026a200241a8026a106f410121050240024020022d00c8024101460d0020024188026a410f6a200241a8026a410f6a29000037000020024188026a41086a200241a8026a41086a290000370300200220022900a80237038802410221010c010b200241a6026a20022d00cb023a000020024190026a200241d5026a29000037030020024197026a200241dc026a29000037000020024184026a200241e8026a2d00003a0000200220022f00c9023b01a402200220022900cd02370388022002200241e4026a280200360280024100210520022d00cc0221010b200241fc016a41026a2207200241a4026a41026a22082d00003a0000200241e0016a41086a220920024188026a41086a2206290300370300200241e0016a410f6a220a20024188026a410f6a220b290000370000200241d8016a41046a220c20024180026a41046a220d2d00003a0000200220022f01a4023b01fc0120022002290388023703e00120022002280280023602d8012005450d01200121030b200241c8026a410f6a2004410f6a290000370000200241c8026a41086a200441086a290000370300200220042900003703c802410121040c010b2002418c016a41026a20072d00003a000020062009290300370300200b200a290000370000200d200c2d00003a00002008200241d4016a41026a2d00003a0000200220022f01fc013b018c01200220022903e00137038802200220022802d80136028002200220022f01d4013b01a402200241c8026a410f6a2204200241b8016a410f6a290000370000200241c8026a41086a2205200241b8016a41086a290300370300200220022903b8013703c802200241e0016a41046a200241b0016a41046a2d00003a0000200220022802b0013602e001200241a8026a410f6a2004290000370000200241a8026a41086a2005290300370300200220022903c8023703a802410021040b20024188016a41026a2205200241a4026a41026a2d00003a0000200241f0006a41086a2207200241a8026a41086a290300370300200241f0006a410f6a2208200241a8026a410f6a290000370000200241e8006a41046a2209200241e0016a41046a2d00003a0000200241e4006a41026a22062002418c016a41026a2d00003a0000200220022f01a4023b018801200220022903a802370370200220022802e001360268200220022f018c013b0164200241c8006a410f6a220a20024188026a410f6a290000370000200241c8006a41086a220b20024188026a41086a290300370300200241c0006a41046a220c20024180026a41046a2d00003a000020022002290388023703482002200228028002360240024020040d00200020022f0188013b0001200041046a20033a0000200041056a20022903703700002000411c6a2002280268360000200041216a20022f01643b0000200041036a20052d00003a00002000410d6a2007290300370000200041146a2008290000370000200041206a20092d00003a0000200041236a20062d00003a0000200041246a20013a0000200041003a0000200041256a20022903483700002000412d6a200b290300370000200041346a200a2900003700002000413c6a2002280240360000200041c0006a200c2d00003a00000c010b200041013a00000b20024190036a24000bd50101037f230041106b2203240002400240200241c8026c4104722204417f4c0d00200410272205450d0120034100360208200320043602042003200536020020022003107102402002450d00200241c8026c2102034002400240200141b4026a2802004102470d00200341003a000f20032003410f6a410110720c010b200341013a000f20032003410f6a410110722001200310e3020b200141c8026a2101200241b87d6a22020d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1038000b1039000bec0101037f230041106b220224000240024020002802a80222030d00200241003a00072001200241076a41011072200241076a21030c010b200241013a00072001200241076a41011072200041b0026a2802002204200110712001200320041072200241076a21030b200220002d00c0023a000720012003410110722000200110bf020240024020002802b4024101460d00200241003a000720012003410110720c010b200241013a000720012003410110722002200041b8026a2802003602082001200241086a410410722002200041bc026a28020036020c20012002410c6a410410720b200241106a24000bbc0601087f230041106b2202240020024100360208200242013703000240412010272203450d00200241203602042002200336020020032000290000370000200341086a200041086a290000370000200341106a200041106a290000370000200341186a200041186a290000370000200241203602082002200041206a36020c2002410c6a200210e5012002200041306a36020c2002410c6a200210e501200041c0006a2802002103200041c8006a280200220420021071024002402004450d00200441306c210503400240024020022802042206200228020822046b4120490d00200441206a2107200228020021080c010b200441206a22072004490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009102722080d010c060b2002280200210820062009460d00200820062009102b2208450d050b20022009360204200220083602000b200820046a2204200341106a290000370000200441186a200341286a290000370000200441106a200341206a290000370000200441086a200341186a290000370000200220073602082002200336020c2002410c6a200210e501200341306a2103200541506a22050d000b0b20002802502103200041d8006a2802002204200210710240024020040d002002280208210420022802042109200228020021050c010b200441057421004100200228020822046b210620022802042108034002400240200820066a4120490d0020022802002105200821090c010b200441206a22072004490d03200841017422052007200520074b1b22094100480d030240024020080d00024020090d00410121050c020b200910272205450d060c010b2002280200210520082009460d00200520082009102b2205450d050b2002200936020420022005360200200921080b200520046a22072003290000370000200741186a200341186a290000370000200741106a200341106a290000370000200741086a200341086a2900003700002002200441206a2204360208200641606a2106200341206a2103200041606a22000d000b0b20012902002004ad4220862005ad84100302402009450d00200510290b200241106a24000f0b1032000b1030000b804802077f027e230041106b220224000240024002400240024002400240024002400240024002400240024041b00410272203450d000240024020002802004102470d00200341003a0000410121040c010b200341013a00000240024020002802004101460d00200341003a00012003200041086a2900003700022003410a6a200041106a290000370000200341126a200041186a2900003700002003411a6a200041206a29000037000020022000280204220436020c412221050c010b200341013a000120022000280204220436020c410221050b200320056a2004360000200320054104726a2204200041306a29030037000820042000290328370000200541147221040b0240024020002802384102460d0041b00421050240200441b004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d0420042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a21040240024020002802384101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22076b4120490d00200541216a2104200621080c010b41000d0620064101742205200741206a2204200520044b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320076a2205200041c0006a2206290000370000200541186a200641186a290000370000200541106a200641106a290000370000200541086a200641086a29000037000020022000413c6a280200220736020c2002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a00002002200028023c220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a2007360000200041e8006a29030021092000290360210a024002402006200441046a22086b410f4d0d00200621050c010b41000d0420064101742205200841106a2207200520074b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b41b00421050240200441b004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d0320042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b0240024020002802704102460d00024020052004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a21040240024020002802704101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b41000d0620064101742208200441206a2207200820074b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a2204200041f8006a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041f4006a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a000020022000280274220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a2007360000200041a0016a2903002109200029039801210a024002402006200441046a22086b410f4d0d00200621050c010b41000d0420064101742205200841106a2207200520074b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b0240024020002802a8014102460d00024020052004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a21040240024020002802a8014101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b41000d0620064101742208200441206a2207200820074b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a2204200041b0016a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041ac016a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a0000200220002802ac01220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a2007360000200041d8016a290300210920002903d001210a024002402006200441046a22086b410f4d0d00200621050c010b41000d0420064101742205200841106a2207200520074b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b0240024020002802e0014102460d00024020052004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a21040240024020002802e0014101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b41000d0620064101742208200441206a2207200820074b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a2204200041e8016a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041e4016a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a0000200220002802e401220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a200736000020004190026a2903002109200029038802210a024002402006200441046a22086b410f4d0d00200621050c010b41000d0420064101742205200841106a2207200520074b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b024002402000280298024102460d00024020052004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a2104024002402000280298024101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b41000d0620064101742208200441206a2207200820074b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a2204200041a0026a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a29000037000020022000419c026a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a00002002200028029c02220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a2007360000200041c8026a290300210920002903c002210a024002402006200441046a22086b410f4d0d00200621050c010b41000d0420064101742205200841106a2207200520074b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b0240024020002802d0024102460d00024020052004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a21040240024020002802d0024101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b41000d0620064101742208200441206a2207200820074b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a2204200041d8026a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041d4026a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a0000200220002802d402220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a200736000020004180036a290300210920002903f802210a024002402006200441046a22086b410f4d0d00200621050c010b200841106a22052008490d04200641017422072005200720054b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b024002402000280288034102460d00024020052004470d00200441016a22052004490d04200441017422062005200620054b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a2104024002402000280288034101460d000240024020052004460d0020052106200421050c010b200541016a22042005490d06200541017422062004200620044b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b200441206a22082004490d06200641017422072008200720084b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a220420004190036a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a29000037000020022000418c036a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b200541016a22042005490d05200541017422062004200620044b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a00002002200028028c03220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b200441046a22062004490d04200841017422072006200720064b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a2007360000200041b8036a290300210920002903b003210a024002402006200441046a22086b410f4d0d00200621050c010b200841106a22052008490d04200641017422072005200720054b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d00200441016a22052004490d03200441017422062005200620054b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b024020002802c0034102460d00024020052004470d00200441016a22052004490d03200441017422062005200620054b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41013a0000200441016a2104024020002802c0034101460d00024020052004460d0020052106200421050c070b200541016a22042005490d09200541017422062004200620044b1b22064100480d09024020050d00410021052006102722030d070c0d0b20052006460d06200320052006102b22030d060c0c0b024020052004460d0020052108200421050c050b200541016a22042005490d08200541017422062004200620044b1b22084100480d08024020050d0041002105200810272203450d0c0c050b20052008460d04200320052008102b2203450d0b0c040b20052004470d02200441016a22052004490d07200441017422062005200620054b1b22054100480d07024020040d0041002104024020050d00410121030c040b200510272203450d0b0c030b20042005460d02200320042005102b2203450d0a0c020b1039000b1032000b200320046a41003a0000200441016a21040c030b200320056a41013a0000200220002802c403220736020c200541016a21042002410c6a21050c010b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b200441206a22082004490d03200641017422072008200720084b1b22084100480d03024020060d00024020080d00410121030c020b200810272203450d070c010b20062008460d00200320062008102b2203450d060b200320046a2204200041c8036a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041c4036a280200220736020c200541216a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b200441046a22062004490d02200841017422072006200720064b1b22064100480d020240024020080d00024020060d00410121030c020b200610272203450d070c010b20082006460d00200320082006102b2203450d060b200528020021070b200320046a2007360000200041f0036a290300210920002903e803210a024002402006200441046a22086b410f4d0d00200621050c010b200841106a22052008490d02200641017422072005200720054b1b22054100480d02024020060d00024020050d00410121030c020b200510272203450d060c010b20062005460d00200320062005102b2203450d050b200320086a220620093700082006200a370000200441146a21040b024002400240024020002802f8034102460d00024020052004470d00200441016a22052004490d05200441017422062005200620054b1b22054100480d05024020040d0041002104024020050d00410121030c020b200510272203450d090c010b20042005460d00200320042005102b2203450d080b200320046a41013a0000200441016a2104024020002802f8034101460d00024020052004460d0020052106200421050c040b200541016a22042005490d05200541017422062004200620044b1b22064100480d05024020050d0041002105200610272203450d090c040b20052006460d03200320052006102b2203450d080c030b024020052004460d0020052108200421050c020b200541016a22042005490d04200541017422062004200620044b1b22084100480d04024020050d0041002105200810272203450d080c020b20052008460d01200320052008102b2203450d070c010b024020052004470d00200441016a22052004490d04200441017422002005200020054b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d080c010b20042005460d00200320042005102b2203450d070b200320046a41003a0000200441016a21000c050b200320056a41013a0000200220002802fc03220736020c200541016a21042002410c6a21050c010b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b200441206a22082004490d02200641017422072008200720084b1b22084100480d02024020060d00024020080d00410121030c020b200810272203450d060c010b20062008460d00200320062008102b2203450d050b200320046a220420004180046a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041fc036a280200220736020c200541216a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b200441046a22062004490d01200841017422072006200720064b1b22064100480d010240024020080d00024020060d00410121030c020b200610272203450d060c010b20082006460d00200320082006102b2203450d050b200528020021070b200320046a2007360000200041a8046a290300210920002903a004210a02402006200441046a22006b410f4d0d00200621050c020b200041106a22052000490d00200641017422082005200820054b1b22054100480d00024020060d00024020050d00410121030c030b200510272203450d040c020b20062005460d01200320062005102b2203450d030c010b1032000b200320006a220020093700082000200a370000200441146a21000b20012902002000ad4220862003ad84100320050d010c020b1030000b200310290b200241106a24000f0b1030000ba50301067f230041106b22022400024002400240200128020022030d00410121040c010b0240200141086a28020041056a2204417f4c0d0020040d0141002104410121050c020b1038000b2004102722050d001039000b200241003602082002200536020020022004360204024002400240024020030d00024020040d00410110272205450d0420024101360204200220053602000b200541003a0000410121040c010b024020040d00410110272205450d0320024101360204200220053602000b200541013a000020024101360208200141086a2802002204200210710240024020022802042206200228020822056b2004490d00200228020021010c010b200520046a22012005490d02200641017422072001200720014b1b22074100480d020240024020060d00024020070d00410121010c020b2007102722010d010c050b2002280200210120062007460d00200120062007102b2201450d040b20022007360204200220013602000b200120056a2003200410e4071a200520046a21040b20002002290300370200200041086a2004360200200241106a24000f0b1032000b1030000bf74902097f027e230041106b22022400024002400240024002400240024002400240410141b104200128020022034103461b220410272205450d00024020034103470d00200541003a0000410121010c070b200541013a0000410221060240024020034102470d00200541003a00010c010b200541013a00010240024020012802004101460d00200541003a0002024002402004417d6a411f4d0d00200421070c010b20052004200441017422064123200641234b1b2207102b2205450d0c0b2005200141086a22042900003700032005411b6a200441186a290000370000200541136a200441106a2900003700002005410b6a200441086a29000037000020022001280204220836020c2002410c6a2109412321060c010b200541013a000220022001280204220836020c2002410c6a210941032106200421070b2006410472210a02400240200720066b41034d0d00200721030c010b20074101742204200a2004200a4b1b22034100480d0320072003460d00200520072003102b2205450d0a200928020021080b200520066a200836000020064114722106200141306a290300210b2001290328210c024002402003200a6b410f4d0d00200321040c010b200341017422042006200420064b1b22044100480d0320032004460d00200520032004102b2205450d0a0b2005200a6a2203200b3700082003200c3700000b0240024020012802384102460d00024020042006470d0041000d0420064101742204200641016a2203200420034b1b22044100480d0420062004460d00200520062004102b2205450d0b0b200520066a41013a0000200641016a21060240024020012802384101460d000240024020042006460d0020042103200621040c010b41000d0620044101742206200441016a2203200620034b1b22034100480d06024020040d00410021042003102722050d010c0e0b20042003460d00200520042003102b2205450d0d0b200520046a41003a0000024002402003200441016a22066b411f4d0d002003210a0c010b41000d062003410174220a200641206a2207200a20074b1b220a4100480d06024020030d000240200a0d00410121050c020b200a10272205450d0e0c010b2003200a460d0020052003200a102b2205450d0d0b200520066a2206200141c0006a2203290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a29000037000020022001413c6a280200220736020c200441216a21062002410c6a21040c010b0240024020042006460d002004210a200621040c010b41000d0520044101742206200441016a2203200620034b1b220a4100480d05024020040d0041002104200a10272205450d0d0c010b2004200a460d0020052004200a102b2205450d0c0b200520046a41013a00002002200128023c220736020c200441016a21062002410c6a21040b02400240200a20066b41034d0d00200a21030c010b41000d04200a4101742203200641046a2207200320074b1b22034100480d0402400240200a0d00024020030d00410121050c020b200310272205450d0d0c010b200a2003460d002005200a2003102b2205450d0c0b200428020021070b200520066a2007360000200141e8006a290300210b2001290360210c024002402003200641046a220a6b410f4d0d00200321040c010b41000d0420034101742204200a41106a2207200420074b1b22044100480d04024020030d00024020040d00410121050c020b200410272205450d0c0c010b20032004460d00200520032004102b2205450d0b0b2005200a6a2203200b3700082003200c370000200641146a21060c010b024020042006470d0041000d0320064101742204200641016a2203200420034b1b22044100480d0320062004460d00200520062004102b2205450d0a0b200520066a41003a0000200641016a21060b0240024020012802704102460d00024020042006470d0041000d0420064101742204200641016a2203200420034b1b22044100480d04024020060d0041002106024020040d00410121050c020b200410272205450d0c0c010b20062004460d00200520062004102b2205450d0b0b200520066a41013a0000200641016a21060240024020012802704101460d000240024020042006460d0020042103200621040c010b41000d0620044101742206200441016a2203200620034b1b22034100480d06024020040d0041002104200310272205450d0e0c010b20042003460d00200520042003102b2205450d0d0b200520046a41003a0000024002402003200441016a22066b411f4d0d002003210a0c010b41000d062003410174220a200641206a2207200a20074b1b220a4100480d06024020030d000240200a0d00410121050c020b200a10272205450d0e0c010b2003200a460d0020052003200a102b2205450d0d0b200520066a2206200141f8006a2203290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a2900003700002002200141f4006a280200220736020c200441216a21062002410c6a21040c010b0240024020042006460d002004210a200621040c010b41000d0520044101742206200441016a2203200620034b1b220a4100480d05024020040d0041002104200a10272205450d0d0c010b2004200a460d0020052004200a102b2205450d0c0b200520046a41013a000020022001280274220736020c200441016a21062002410c6a21040b02400240200a20066b41034d0d00200a21030c010b41000d04200a4101742203200641046a2207200320074b1b22034100480d0402400240200a0d00024020030d00410121050c020b200310272205450d0d0c010b200a2003460d002005200a2003102b2205450d0c0b200428020021070b200520066a2007360000200141a0016a290300210b200129039801210c024002402003200641046a220a6b410f4d0d00200321040c010b41000d0420034101742204200a41106a2207200420074b1b22044100480d04024020030d00024020040d00410121050c020b200410272205450d0c0c010b20032004460d00200520032004102b2205450d0b0b2005200a6a2203200b3700082003200c370000200641146a21060c010b024020042006470d0041000d0320064101742204200641016a2203200420034b1b22044100480d03024020060d0041002106024020040d00410121050c020b200410272205450d0b0c010b20062004460d00200520062004102b2205450d0a0b200520066a41003a0000200641016a21060b0240024020012802a8014102460d00024020042006470d0041000d0420064101742204200641016a2203200420034b1b22044100480d04024020060d0041002106024020040d00410121050c020b200410272205450d0c0c010b20062004460d00200520062004102b2205450d0b0b200520066a41013a0000200641016a21060240024020012802a8014101460d000240024020042006460d0020042103200621040c010b41000d0620044101742206200441016a2203200620034b1b22034100480d06024020040d0041002104200310272205450d0e0c010b20042003460d00200520042003102b2205450d0d0b200520046a41003a0000024002402003200441016a22066b411f4d0d002003210a0c010b41000d062003410174220a200641206a2207200a20074b1b220a4100480d06024020030d000240200a0d00410121050c020b200a10272205450d0e0c010b2003200a460d0020052003200a102b2205450d0d0b200520066a2206200141b0016a2203290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a2900003700002002200141ac016a280200220736020c200441216a21062002410c6a21040c010b0240024020042006460d002004210a200621040c010b41000d0520044101742206200441016a2203200620034b1b220a4100480d05024020040d0041002104200a10272205450d0d0c010b2004200a460d0020052004200a102b2205450d0c0b200520046a41013a0000200220012802ac01220736020c200441016a21062002410c6a21040b02400240200a20066b41034d0d00200a21030c010b41000d04200a4101742203200641046a2207200320074b1b22034100480d0402400240200a0d00024020030d00410121050c020b200310272205450d0d0c010b200a2003460d002005200a2003102b2205450d0c0b200428020021070b200520066a2007360000200141d8016a290300210b20012903d001210c024002402003200641046a220a6b410f4d0d00200321040c010b41000d0420034101742204200a41106a2207200420074b1b22044100480d04024020030d00024020040d00410121050c020b200410272205450d0c0c010b20032004460d00200520032004102b2205450d0b0b2005200a6a2203200b3700082003200c370000200641146a21060c010b024020042006470d0041000d0320064101742204200641016a2203200420034b1b22044100480d03024020060d0041002106024020040d00410121050c020b200410272205450d0b0c010b20062004460d00200520062004102b2205450d0a0b200520066a41003a0000200641016a21060b0240024020012802e0014102460d00024020042006470d0041000d0420064101742204200641016a2203200420034b1b22044100480d04024020060d0041002106024020040d00410121050c020b200410272205450d0c0c010b20062004460d00200520062004102b2205450d0b0b200520066a41013a0000200641016a21060240024020012802e0014101460d000240024020042006460d0020042103200621040c010b41000d0620044101742206200441016a2203200620034b1b22034100480d06024020040d0041002104200310272205450d0e0c010b20042003460d00200520042003102b2205450d0d0b200520046a41003a0000024002402003200441016a22066b411f4d0d002003210a0c010b41000d062003410174220a200641206a2207200a20074b1b220a4100480d06024020030d000240200a0d00410121050c020b200a10272205450d0e0c010b2003200a460d0020052003200a102b2205450d0d0b200520066a2206200141e8016a2203290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a2900003700002002200141e4016a280200220736020c200441216a21062002410c6a21040c010b0240024020042006460d002004210a200621040c010b41000d0520044101742206200441016a2203200620034b1b220a4100480d05024020040d0041002104200a10272205450d0d0c010b2004200a460d0020052004200a102b2205450d0c0b200520046a41013a0000200220012802e401220736020c200441016a21062002410c6a21040b02400240200a20066b41034d0d00200a21030c010b41000d04200a4101742203200641046a2207200320074b1b22034100480d0402400240200a0d00024020030d00410121050c020b200310272205450d0d0c010b200a2003460d002005200a2003102b2205450d0c0b200428020021070b200520066a200736000020014190026a290300210b200129038802210c024002402003200641046a220a6b410f4d0d00200321040c010b41000d0420034101742204200a41106a2207200420074b1b22044100480d04024020030d00024020040d00410121050c020b200410272205450d0c0c010b20032004460d00200520032004102b2205450d0b0b2005200a6a2203200b3700082003200c370000200641146a21060c010b024020042006470d0041000d0320064101742204200641016a2203200420034b1b22044100480d03024020060d0041002106024020040d00410121050c020b200410272205450d0b0c010b20062004460d00200520062004102b2205450d0a0b200520066a41003a0000200641016a21060b024002402001280298024102460d00024020042006470d0041000d0420064101742204200641016a2203200420034b1b22044100480d04024020060d0041002106024020040d00410121050c020b200410272205450d0c0c010b20062004460d00200520062004102b2205450d0b0b200520066a41013a0000200641016a2106024002402001280298024101460d000240024020042006460d0020042103200621040c010b41000d0620044101742206200441016a2203200620034b1b22034100480d06024020040d0041002104200310272205450d0e0c010b20042003460d00200520042003102b2205450d0d0b200520046a41003a0000024002402003200441016a22066b411f4d0d002003210a0c010b41000d062003410174220a200641206a2207200a20074b1b220a4100480d06024020030d000240200a0d00410121050c020b200a10272205450d0e0c010b2003200a460d0020052003200a102b2205450d0d0b200520066a2206200141a0026a2203290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a29000037000020022001419c026a280200220736020c200441216a21062002410c6a21040c010b0240024020042006460d002004210a200621040c010b41000d0520044101742206200441016a2203200620034b1b220a4100480d05024020040d0041002104200a10272205450d0d0c010b2004200a460d0020052004200a102b2205450d0c0b200520046a41013a00002002200128029c02220736020c200441016a21062002410c6a21040b02400240200a20066b41034d0d00200a21030c010b41000d04200a4101742203200641046a2207200320074b1b22034100480d0402400240200a0d00024020030d00410121050c020b200310272205450d0d0c010b200a2003460d002005200a2003102b2205450d0c0b200428020021070b200520066a2007360000200141c8026a290300210b20012903c002210c024002402003200641046a220a6b410f4d0d00200321040c010b41000d0420034101742204200a41106a2207200420074b1b22044100480d04024020030d00024020040d00410121050c020b200410272205450d0c0c010b20032004460d00200520032004102b2205450d0b0b2005200a6a2203200b3700082003200c370000200641146a21060c010b024020042006470d0041000d0320064101742204200641016a2203200420034b1b22044100480d03024020060d0041002106024020040d00410121050c020b200410272205450d0b0c010b20062004460d00200520062004102b2205450d0a0b200520066a41003a0000200641016a21060b0240024020012802d0024102460d00024020042006470d0041000d0420064101742204200641016a2203200420034b1b22044100480d04024020060d0041002106024020040d00410121050c020b200410272205450d0c0c010b20062004460d00200520062004102b2205450d0b0b200520066a41013a0000200641016a21060240024020012802d0024101460d000240024020042006460d0020042103200621040c010b200441016a22062004490d06200441017422032006200320064b1b22034100480d06024020040d0041002104200310272205450d0e0c010b20042003460d00200520042003102b2205450d0d0b200520046a41003a0000024002402003200441016a22066b411f4d0d002003210a0c010b200641206a220a2006490d0620034101742207200a2007200a4b1b220a4100480d06024020030d000240200a0d00410121050c020b200a10272205450d0e0c010b2003200a460d0020052003200a102b2205450d0d0b200520066a2206200141d8026a2203290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a2900003700002002200141d4026a280200220736020c200441216a21062002410c6a21040c010b0240024020042006460d002004210a200621040c010b200441016a22062004490d05200441017422032006200320064b1b220a4100480d05024020040d0041002104200a10272205450d0d0c010b2004200a460d0020052004200a102b2205450d0c0b200520046a41013a0000200220012802d402220736020c200441016a21062002410c6a21040b02400240200a20066b41034d0d00200a21030c010b200641046a22032006490d04200a41017422072003200720034b1b22034100480d0402400240200a0d00024020030d00410121050c020b200310272205450d0d0c010b200a2003460d002005200a2003102b2205450d0c0b200428020021070b200520066a200736000020014180036a290300210b20012903f802210c024002402003200641046a220a6b410f4d0d00200321040c010b200a41106a2204200a490d04200341017422072004200720044b1b22044100480d04024020030d00024020040d00410121050c020b200410272205450d0c0c010b20032004460d00200520032004102b2205450d0b0b2005200a6a2203200b3700082003200c370000200641146a21060c010b024020042006470d0041000d0320064101742204200641016a2203200420034b1b22044100480d03024020060d0041002106024020040d00410121050c020b200410272205450d0b0c010b20062004460d00200520062004102b2205450d0a0b200520066a41003a0000200641016a21060b02402001280288034102460d00024020042006470d00200641016a22042006490d03200641017422032004200320044b1b22044100480d03024020060d0041002106024020040d00410121050c020b200410272205450d0b0c010b20062004460d00200520062004102b2205450d0a0b200520066a41013a0000200641016a2106024002402001280288034101460d000240024020042006460d0020042103200621040c010b200441016a22062004490d05200441017422032006200320064b1b22034100480d05024020040d0041002104200310272205450d0d0c010b20042003460d00200520042003102b2205450d0c0b200520046a41003a0000024002402003200441016a22066b411f4d0d002003210a0c010b200641206a220a2006490d0520034101742207200a2007200a4b1b220a4100480d05024020030d000240200a0d00410121050c020b200a10272205450d0d0c010b2003200a460d0020052003200a102b2205450d0c0b200520066a220620014190036a2203290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a29000037000020022001418c036a280200220736020c200441216a21062002410c6a21040c010b0240024020042006460d002004210a200621040c010b200441016a22062004490d04200441017422032006200320064b1b220a4100480d04024020040d0041002104200a10272205450d0c0c010b2004200a460d0020052004200a102b2205450d0b0b200520046a41013a00002002200128028c03220736020c200441016a21062002410c6a21040b02400240200a20066b41034d0d00200a21030c010b200641046a22032006490d03200a41017422072003200720034b1b22034100480d0302400240200a0d00024020030d00410121050c020b200310272205450d0c0c010b200a2003460d002005200a2003102b2205450d0b0b200428020021070b200520066a2007360000200141b8036a290300210b20012903b003210c024002402003200641046a220a6b410f4d0d00200321040c010b200a41106a2204200a490d03200341017422072004200720044b1b22044100480d03024020030d00024020040d00410121050c020b200410272205450d0b0c010b20032004460d00200520032004102b2205450d0a0b2005200a6a2203200b3700082003200c370000200641146a21060c040b20042006470d02200641016a22042006490d04200641017422032004200320044b1b22044100480d04024020060d0041002106024020040d00410121050c040b200410272205450d090c030b20062004460d02200520062004102b22050d020c070b1039000b1032000b200520066a41003a0000200641016a21060b0240024002400240024020012802c0034102460d00024020042006470d00200641016a22042006490d06200641017422032004200320044b1b22044100480d06024020060d0041002106024020040d00410121050c020b200410272205450d0a0c010b20062004460d00200520062004102b2205450d090b200520066a41013a0000200641016a2106024020012802c0034101460d00024020042006460d0020042103200621040c040b200441016a22062004490d06200441017422032006200320064b1b22034100480d06024020040d0041002104200310272205450d0a0c040b20042003460d03200520042003102b2205450d090c030b024020042006460d002004210a200621040c020b200441016a22062004490d05200441017422032006200320064b1b220a4100480d05024020040d0041002104200a10272205450d090c020b2004200a460d0120052004200a102b2205450d080c010b024020042006470d00200641016a22042006490d05200641017422032004200320044b1b22044100480d05024020060d0041002106024020040d00410121050c020b200410272205450d090c010b20062004460d00200520062004102b2205450d080b200520066a41003a0000200641016a21060c030b200520046a41013a0000200220012802c403220736020c200441016a21062002410c6a21040c010b200520046a41003a0000024002402003200441016a22066b411f4d0d002003210a0c010b200641206a220a2006490d0320034101742207200a2007200a4b1b220a4100480d03024020030d000240200a0d00410121050c020b200a10272205450d070c010b2003200a460d0020052003200a102b2205450d060b200520066a2206200141c8036a2203290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a2900003700002002200141c4036a280200220736020c200441216a21062002410c6a21040b02400240200a20066b41034d0d00200a21030c010b200641046a22032006490d02200a41017422072003200720034b1b22034100480d0202400240200a0d00024020030d00410121050c020b200310272205450d070c010b200a2003460d002005200a2003102b2205450d060b200428020021070b200520066a2007360000200141f0036a290300210b20012903e803210c024002402003200641046a220a6b410f4d0d00200321040c010b200a41106a2204200a490d02200341017422072004200720044b1b22044100480d02024020030d00024020040d00410121050c020b200410272205450d060c010b20032004460d00200520032004102b2205450d050b2005200a6a2203200b3700082003200c370000200641146a21060b024002400240024020012802f8034102460d00024020042006470d00200641016a22042006490d05200641017422032004200320044b1b22044100480d05024020060d0041002106024020040d00410121050c020b200410272205450d090c010b20062004460d00200520062004102b2205450d080b200520066a41013a0000200641016a2106024020012802f8034101460d00024020042006460d0020042103200621040c040b200441016a22062004490d05200441017422032006200320064b1b22034100480d05024020040d0041002104200310272205450d090c040b20042003460d03200520042003102b2205450d080c030b024020042006460d002004210a200621040c020b200441016a22062004490d04200441017422032006200320064b1b220a4100480d04024020040d0041002104200a10272205450d080c020b2004200a460d0120052004200a102b2205450d070c010b024020042006470d00200641016a22042006490d04200641017422012004200120044b1b22044100480d04024020060d0041002106024020040d00410121050c020b200410272205450d080c010b20062004460d00200520062004102b2205450d070b200520066a41003a0000200641016a21010c050b200520046a41013a0000200220012802fc03220736020c200441016a21062002410c6a21040c010b200520046a41003a0000024002402003200441016a22066b411f4d0d002003210a0c010b200641206a220a2006490d0220034101742207200a2007200a4b1b220a4100480d02024020030d000240200a0d00410121050c020b200a10272205450d060c010b2003200a460d0020052003200a102b2205450d050b200520066a220620014180046a2203290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a2900003700002002200141fc036a280200220736020c200441216a21062002410c6a21040b02400240200a20066b41034d0d00200a21030c010b200641046a22032006490d01200a41017422072003200720034b1b22034100480d0102400240200a0d00024020030d00410121050c020b200310272205450d060c010b200a2003460d002005200a2003102b2205450d050b200428020021070b200520066a2007360000200141a8046a290300210b20012903a004210c02402003200641046a22016b410f4d0d00200321040c020b200141106a22042001490d002003410174220a2004200a20044b1b22044100480d00024020030d00024020040d00410121050c030b200410272205450d040c020b20032004460d01200520032004102b2205450d030c010b1032000b200520016a2201200b3700082001200c370000200641146a21010b200020013602082000200436020420002005360200200241106a24000f0b1030000b1030000b6401037f024041094101200128020022024101461b220310272204450d000240024020020d00200441003a0000410121010c010b200441013a000020042001290204370001410921010b2000200136020820002003360204200020043602000f0b1039000b960503027f017e057f230041d0006b2202240041f5bec500ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941ccc8c200ad4280808080a00284100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240411010272203450d0020032001290000370000200341086a200141086a29000037000020022003ad42808080808002841002220129000037033820011029200241cc006a200341106a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2206417f4c0d01200228022821070240024020060d0041002101410121030c010b200610272203450d01200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1039000b1038000b1032000b1030000bbc0603027f017e077f230041d0006b2203240041f5bec500ad4280808080800184100122042900002105200341086a41086a200441086a290000370300200320053703082004102941f8c7c200ad4280808080e00284100122042900002105200341186a41086a200441086a29000037030020032005370318200410290240024002400240411010272204450d0020042001290000370000200441086a200141086a29000037000020032004ad42808080808002841002220129000037033820011029200341cc006a200441106a360200200320043602482003200341386a41086a3602442003200341386a360240200341286a200341c0006a107520041029200341c0006a2002280200200228020810eb022003280230220641206a2207200328024822086a2201417f4c0d01200328024021092003280228210a0240024020010d004100210b410121040c010b200110272204450d012001210b0b02400240200b410f4d0d00200b21020c010b200b41017422024110200241104b1b22024100480d030240200b0d002002102722040d010c050b200b2002460d002004200b2002102b2204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020024170714110460d002002210b0c010b2002410174220b4120200b41204b1b220b4100480d032002200b460d0020042002200b102b2204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2006490d00200b21020c010b200641206a22022006490d03200b410174220c2002200c20024b1b22024100480d03200b2002460d002004200b2002102b2204450d040b200441206a200a200610e4071a02400240200220076b2008490d002002210b0c010b20012007490d032002410174220b2001200b20014b1b220b4100480d03024020020d000240200b0d00410121040c020b200b10272204450d050c010b2002200b460d0020042002200b102b2204450d040b200420076a2009200810e4071a200020013602082000200b3602042000200436020002402003280244450d00200910290b0240200328022c450d00200a10290b200341d0006a24000f0b1039000b1038000b1032000b1030000bf00201057f230041206b220324000240024002400240200241046a2204417f4c0d000240024020040d0041012105410021040c010b200410272205450d020b2003410036021820032005360210200320043602142002200341106a10710240024020032802142206200328021822056b2002490d0020032802102104200621070c010b200520026a22042005490d03200641017422072004200720044b1b22074100480d030240024020060d00024020070d00410121040c020b2007102722040d010c060b2003280210210420062007460d00200420062007102b2204450d050b20032007360214200320043602100b200420056a2001200210e4071a2003200520026a2202ad4220862004ad8410022205290000370308200510292003411c6a200420026a360200200320043602182003200341106a3602142003200341086a3602102000200341106a107502402007450d00200410290b200341206a24000f0b1038000b1039000b1032000b1030000b860c04047f017e077f077e23004190016b22052400200520002001200220032004108a02024002400240024020052802000d00410121060c010b200541f0006a41186a4200370300200541f0006a41106a22074200370300200541f0006a41086a220642003703002005420037037041f5bec500ad42808080808001841001220829000021092006200841086a2900003703002005200937037020081029419bc1c200ad4280808080800284100122082900002109200541d0006a41086a220a200841086a2900003703002005200937035020081029200720052903502209370300200541306a41086a2006290300370300200541306a41106a2009370300200541306a41186a200a29030037030020052005290370370330200541f0006a200541306a10ed02024002402005280270220b0d004100210c20054100360218200542043703104104210b4100210d0c010b2005200529027422093702142005200b3602102009422088a7210d2009a7210c0b2001ad42e0007e2209422088a70d012009a72206417f4c0d010240024020060d00410821080c010b200610272208450d030b20054100360228200520083602202005200641e0006e360224200541206a4100200110a7012005280228210e02402001450d002000200141e0006c6a210f2005280220200e41e0006c6a2106200141057441606a4105762110200541346a21010340200541f0006a41086a2208200041086a290300370300200541f0006a41106a2207200041106a290300370300200541f0006a41186a220a200041186a29030037030020052000290300370370200041206a2903002109200041286a2903002111200041306a2903002112200041386a2903002113200541e0006a200041c0006a10ee02200541d0006a200041d0006a10ef02200141086a200541d0006a41086a28020036020020012005290350370200200a2903002114200729030021152008290300211620052903702117200641386a2013370300200641306a2012370300200641286a2011370300200641206a2009370300200641086a201637030020062017370300200641106a2015370300200641c0006a2005290360370300200641c8006a200541e0006a41086a280200360200200641186a2014370300200641cc006a2005290230370200200641d4006a200541306a41086a290200370200200641e0006a2106200041e0006a2200200f470d000b200e20106a41016a210e0b200541f8006a200e36020020052005290320370370200341ffffffff03712003470d0120034102742206417f4c0d010240024020060d00410421000c010b200610272200450d030b200541003602382005200036023020052006410276360234200541306a410020031098012005280230200528023822064102746a2002200341027410e4071a200541d0006a41086a2201200620036a220636020020054184016a20063602002005200529033037027c0240200d200c470d00200541106a200d41011094012005280214210c2005280210210b2005280218210d0b200b200d411c6c6a22062005290370370200200541f0006a41086a22002903002109200541f0006a41106a2208290300211120062004360218200641106a2011370200200641086a20093702002005200d41016a2207360218200541f0006a41186a420037030020084200370300200042003703002005420037037041f5bec500ad42808080808001841001220629000021092000200641086a2900003703002005200937037020061029419bc1c200ad42808080808002841001220629000021092001200641086a2900003703002005200937035020061029200820052903502209370300200541306a41086a2000290300370300200541306a41106a2009370300200541306a41186a20012903003703002005200529037037033002400240200b0d00200541306aad428080808080048410040c010b200541f0006a200b200710f002200541306aad4280808080800484200535027842208620052802702206ad84100302402005280274450d00200610290b200b200710f102200c450d00200c411c6c450d00200b10290b410021060b20054190016a240020060f0b1038000b1039000bef1104047f017e137f047e23004180036b220224002002412036022420022001360220200241286a2001ad42808080808004841007108b020240024002400240200228022822030d00200041003602000c010b200228022c21042002200241306a28020036023c20022003360238200241186a200241386a10c8010240024020022802180d00200228021c2205200228023c411c6e2201200120054b1bad421c7e2206422088a70d032006a72201417f4c0d030240024020010d00410421070c010b200110272207450d050b200241003602482002200736024020022001411c6e36024402400240024002400240024002402005450d00200241a0026a41c4006a2108410021094100210a0340200241106a200241386a10c80120022802100d072002280214220b200228023c41e0006e22012001200b4b1bad42e0007e2206422088a70d0b2006a72201417f4c0d0b0240024020010d004108210c0c010b20011027220c450d0d0b200241003602582002200c3602502002200141e0006e3602540240024002400240200b450d004100210d0340200241a0026a200241386a10c102200241e0016a41386a2201200241a0026a41386a290300370300200241e0016a41306a220e200241a0026a41306a290300370300200241e0016a41286a220f200241a0026a41286a290300370300200241e0016a41206a2210200241a0026a41206a290300370300200241e0016a41186a2211200241a0026a41186a290300370300200241e0016a41106a2212200241a0026a41106a290300370300200241e0016a41086a2213200241a0026a41086a290300370300200241c0016a41086a2214200841086a290200370300200241c0016a41106a2215200841106a290200370300200241c0016a41186a2216200841186a280200360200200220022903a0023703e001200220082902003703c00120022802e0022217450d0220024180016a41386a2218200129030037030020024180016a41306a2219200e29030037030020024180016a41286a220e200f29030037030020024180016a41206a220f201029030037030020024180016a41186a2210201129030037030020024180016a41106a2211201229030037030020024180016a41086a22122013290300370300200241e0006a41086a22132014290300370300200241e0006a41106a22142015290300370300200241e0006a41186a22152016280200360200200220022903e00137038001200220022903c0013703600240200d2002280254470d00200241d0006a200d410110a7012002280250210c2002280258210d0b200c200d41e0006c6a2201200229038001370300200141106a2011290300370300200141086a2012290300370300201929030021062018290300211a200e290300211b200f290300211c2010290300211d200141c0006a2017360200200141186a201d370300200141206a201c370300200141286a201b370300200141c4006a2002290360370200200141386a201a370300200141306a2006370300200141cc006a2013290300370200200141d4006a2014290300370200200141dc006a20152802003602002002200d41016a220d360258200b417f6a220b0d000b0b200c450d0a20022902542106200241086a200241386a10c80120022802080d07200228020c220b200228023c220d41027622012001200b4b1b2201410274220e417f4c0d0e20010d014104210f0c020b0240200d450d00200d41e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010290b0240200128020041ffffff3f71450d002001417c6a28020010290b200141e0006a2101200d41a07f6a220d0d000b0b20022802542201450d09200141e0006c0d080c090b200e1027220f450d0d0b200241003602a802200220013602a4022002200f3602a0020240200b450d00410021010340200d4104490d0520022002280238220e41046a360238200e280000220e418094ebdc034b0d040240200120022802a402470d00200241a0026a2001410110980120022802a002210f20022802a80221010b200d417c6a210d200f20014102746a200e3602002002200141016a22013602a802200b417f6a220b0d000b2002200d36023c0b200f450d0420022902a402211a200d4104490d05200a41016a210a2002200d417c6a36023c20022002280238220141046a3602382001280000210d024020092002280244470d00200241c0006a2009410110940120022802402107200228024821090b20072009411c6c6a2201200d360218200120063702042001200c360200200141106a201a3702002001410c6a200f3602002002200941016a2209360248200a2005470d000b0b2007450d0620002002290244370204200020073602000c070b200d417c6a210d0b2002200d36023c20022802a40241ffffffff0371450d00200f10290b02402006422088a72201450d00200141e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010290b0240200128020041ffffff3f71450d002001417c6a28020010290b200141e0006a2101200d41a07f6a220d0d000b0b2006a72201450d02200141e0006c0d010c020b0240201a42ffffffff0383500d00200f10290b02402006422088a72201450d00200141e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010290b0240200128020041ffffff3f71450d002001417c6a28020010290b200141e0006a2101200d41a07f6a220d0d000b0b2006a72201450d01200141e0006c450d010b200c10290b2007200910f10220022802442201450d002001411c6c450d00200710290b200241003602e801200242013703e0012002410d360284012002200241206a360280012002200241e0016a3602c001200241b4026a4101360200200242013702a402200241f4eaca003602a002200220024180016a3602b002200241c0016a41a8a3c800200241a0026a10371a20023502e80142208620023502e001841008024020022802e401450d0020022802e00110290b200041003602000b2004450d00200310290b20024180036a24000f0b1038000b1039000bb10203027f017e027f230041106b220224000240024020012802082203ad42307e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510272206450d020b20024100360208200220063602002002200541306e3602042002410020031090012002280208210502402003450d002001200341306c6a21062002280200200541306c6a21030340200320012903003703002003200141086a290300370308200341106a200141106a290300370300200341186a200141186a290300370300200341206a200141206a290300370300200341286a200141286a290300370300200341306a2103200541016a2105200141306a22012006470d000b0b20002002290300370200200041086a2005360200200241106a24000f0b1038000b1039000ba10201087f230041106b22022400024002402001280208220341ffffff3f712003470d0020034105742204417f4c0d00200128020021050240024020040d00410121060c010b200410272206450d020b41002101200241003602082002200636020020022004410576360204200241002003109e012002280208210702402003450d0020034105742108200228020020074105746a21090340200920016a2204200520016a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002008200141206a2201470d000b200341057441606a41057620076a41016a21070b20002002290300370200200041086a2007360200200241106a24000f0b1038000b1039000bfe0301067f230041106b22032400024002402002411c6c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410272205450d020b20034100360208200320053602002003200436020420022003107102402002450d0020012002411c6c6a2106034020012802002105200128020822022003107102402002450d002005200241e0006c6a2107034020032005412010722003200541206a36020c2003410c6a200310e5012003200541306a36020c2003410c6a200310e50120052802402102200528024822042003107102402004450d00200441306c210403402003200241106a412010722003200236020c200241306a21022003410c6a200310e501200441506a22040d000b0b200541e0006a210820052802502102200528025822042003107102402004450d002004410574210403402003200241201072200241206a2102200441606a22040d000b0b2008210520082007470d000b0b2001411c6a2105200128020c2102200128021422042003107102402004450d002004410274210403402003200228020036020c20032003410c6a41041072200241046a21022004417c6a22040d000b0b2003200128021836020c20032003410c6a410410722005210120052006470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1038000b1039000bd90101037f02402001450d0020002001411c6c6a21020340024020002802082201450d00200141e0006c2103200028020041d4006a210103400240200141706a2802002204450d00200441306c450d002001416c6a28020010290b0240200128020041ffffff3f71450d002001417c6a28020010290b200141e0006a2101200341a07f6a22030d000b0b0240200041046a2802002201450d00200141e0006c450d00200028020010290b2000411c6a21010240200041106a28020041ffffffff0371450d00200028020c10290b2001210020012002470d000b0b0b804802077f027e230041106b220224000240024002400240024002400240024002400240024002400240024041b00410272203450d000240024020002802004102470d00200341003a0000410121040c010b200341013a00000240024020002802004101460d00200341003a00012003200041086a2900003700022003410a6a200041106a290000370000200341126a200041186a2900003700002003411a6a200041206a29000037000020022000280204220436020c412221050c010b200341013a000120022000280204220436020c410221050b200320056a2004360000200320054104726a2204200041306a29030037000820042000290328370000200541147221040b0240024020002802384102460d0041b00421050240200441b004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d0420042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a21040240024020002802384101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22076b4120490d00200541216a2104200621080c010b41000d0620064101742205200741206a2204200520044b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320076a2205200041c0006a2206290000370000200541186a200641186a290000370000200541106a200641106a290000370000200541086a200641086a29000037000020022000413c6a280200220736020c2002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a00002002200028023c220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a2007360000200041e8006a29030021092000290360210a024002402006200441046a22086b410f4d0d00200621050c010b41000d0420064101742205200841106a2207200520074b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b41b00421050240200441b004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d0320042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b0240024020002802704102460d00024020052004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a21040240024020002802704101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b41000d0620064101742208200441206a2207200820074b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a2204200041f8006a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041f4006a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a000020022000280274220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a2007360000200041a0016a2903002109200029039801210a024002402006200441046a22086b410f4d0d00200621050c010b41000d0420064101742205200841106a2207200520074b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b0240024020002802a8014102460d00024020052004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a21040240024020002802a8014101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b41000d0620064101742208200441206a2207200820074b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a2204200041b0016a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041ac016a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a0000200220002802ac01220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a2007360000200041d8016a290300210920002903d001210a024002402006200441046a22086b410f4d0d00200621050c010b41000d0420064101742205200841106a2207200520074b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b0240024020002802e0014102460d00024020052004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a21040240024020002802e0014101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b41000d0620064101742208200441206a2207200820074b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a2204200041e8016a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041e4016a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a0000200220002802e401220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a200736000020004190026a2903002109200029038802210a024002402006200441046a22086b410f4d0d00200621050c010b41000d0420064101742205200841106a2207200520074b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b024002402000280298024102460d00024020052004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a2104024002402000280298024101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b41000d0620064101742208200441206a2207200820074b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a2204200041a0026a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a29000037000020022000419c026a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a00002002200028029c02220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a2007360000200041c8026a290300210920002903c002210a024002402006200441046a22086b410f4d0d00200621050c010b41000d0420064101742205200841106a2207200520074b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b0240024020002802d0024102460d00024020052004470d0041000d0420044101742205200441016a2206200520064b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a21040240024020002802d0024101460d000240024020052004460d0020052106200421050c010b41000d0620054101742204200541016a2206200420064b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b41000d0620064101742208200441206a2207200820074b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a2204200041d8026a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041d4026a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b41000d0520054101742204200541016a2206200420064b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a0000200220002802d402220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b41000d0420084101742206200441046a2207200620074b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a200736000020004180036a290300210920002903f802210a024002402006200441046a22086b410f4d0d00200621050c010b200841106a22052008490d04200641017422072005200720054b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d0041000d0320044101742205200441016a2206200520064b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b024002402000280288034102460d00024020052004470d00200441016a22052004490d04200441017422062005200620054b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d110c010b20042005460d00200320042005102b2203450d100b200320046a41013a0000200441016a2104024002402000280288034101460d000240024020052004460d0020052106200421050c010b200541016a22042005490d06200541017422062004200620044b1b22064100480d06024020050d0041002105200610272203450d130c010b20052006460d00200320052006102b2203450d120b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b200441206a22082004490d06200641017422072008200720084b1b22084100480d06024020060d00024020080d00410121030c020b200810272203450d130c010b20062008460d00200320062008102b2203450d120b200320046a220420004190036a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a29000037000020022000418c036a280200220736020c200541216a21042002410c6a21050c010b0240024020052004460d0020052108200421050c010b200541016a22042005490d05200541017422062004200620044b1b22084100480d05024020050d0041002105200810272203450d120c010b20052008460d00200320052008102b2203450d110b200320056a41013a00002002200028028c03220736020c200541016a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b200441046a22062004490d04200841017422072006200720064b1b22064100480d040240024020080d00024020060d00410121030c020b200610272203450d120c010b20082006460d00200320082006102b2203450d110b200528020021070b200320046a2007360000200041b8036a290300210920002903b003210a024002402006200441046a22086b410f4d0d00200621050c010b200841106a22052008490d04200641017422072005200720054b1b22054100480d04024020060d00024020050d00410121030c020b200510272203450d110c010b20062005460d00200320062005102b2203450d100b200320086a220620093700082006200a370000200441146a21040c010b024020052004470d00200441016a22052004490d03200441017422062005200620054b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41003a0000200441016a21040b024020002802c0034102460d00024020052004470d00200441016a22052004490d03200441017422062005200620054b1b22054100480d03024020040d0041002104024020050d00410121030c020b200510272203450d100c010b20042005460d00200320042005102b2203450d0f0b200320046a41013a0000200441016a2104024020002802c0034101460d00024020052004460d0020052106200421050c070b200541016a22042005490d09200541017422062004200620044b1b22064100480d09024020050d00410021052006102722030d070c0d0b20052006460d06200320052006102b22030d060c0c0b024020052004460d0020052108200421050c050b200541016a22042005490d08200541017422062004200620044b1b22084100480d08024020050d0041002105200810272203450d0c0c050b20052008460d04200320052008102b2203450d0b0c040b20052004470d02200441016a22052004490d07200441017422062005200620054b1b22054100480d07024020040d0041002104024020050d00410121030c040b200510272203450d0b0c030b20042005460d02200320042005102b2203450d0a0c020b1039000b1032000b200320046a41003a0000200441016a21040c030b200320056a41013a0000200220002802c403220736020c200541016a21042002410c6a21050c010b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b200441206a22082004490d03200641017422072008200720084b1b22084100480d03024020060d00024020080d00410121030c020b200810272203450d070c010b20062008460d00200320062008102b2203450d060b200320046a2204200041c8036a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041c4036a280200220736020c200541216a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b200441046a22062004490d02200841017422072006200720064b1b22064100480d020240024020080d00024020060d00410121030c020b200610272203450d070c010b20082006460d00200320082006102b2203450d060b200528020021070b200320046a2007360000200041f0036a290300210920002903e803210a024002402006200441046a22086b410f4d0d00200621050c010b200841106a22052008490d02200641017422072005200720054b1b22054100480d02024020060d00024020050d00410121030c020b200510272203450d060c010b20062005460d00200320062005102b2203450d050b200320086a220620093700082006200a370000200441146a21040b024002400240024020002802f8034102460d00024020052004470d00200441016a22052004490d05200441017422062005200620054b1b22054100480d05024020040d0041002104024020050d00410121030c020b200510272203450d090c010b20042005460d00200320042005102b2203450d080b200320046a41013a0000200441016a2104024020002802f8034101460d00024020052004460d0020052106200421050c040b200541016a22042005490d05200541017422062004200620044b1b22064100480d05024020050d0041002105200610272203450d090c040b20052006460d03200320052006102b2203450d080c030b024020052004460d0020052108200421050c020b200541016a22042005490d04200541017422062004200620044b1b22084100480d04024020050d0041002105200810272203450d080c020b20052008460d01200320052008102b2203450d070c010b024020052004470d00200441016a22052004490d04200441017422002005200020054b1b22054100480d04024020040d0041002104024020050d00410121030c020b200510272203450d080c010b20042005460d00200320042005102b2203450d070b200320046a41003a0000200441016a21000c050b200320056a41013a0000200220002802fc03220736020c200541016a21042002410c6a21050c010b200320056a41003a0000024002402006200541016a22046b411f4d0d00200621080c010b200441206a22082004490d02200641017422072008200720084b1b22084100480d02024020060d00024020080d00410121030c020b200810272203450d060c010b20062008460d00200320062008102b2203450d050b200320046a220420004180046a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002002200041fc036a280200220736020c200541216a21042002410c6a21050b02400240200820046b41034d0d00200821060c010b200441046a22062004490d01200841017422072006200720064b1b22064100480d010240024020080d00024020060d00410121030c020b200610272203450d060c010b20082006460d00200320082006102b2203450d050b200528020021070b200320046a2007360000200041a8046a290300210920002903a004210a02402006200441046a22006b410f4d0d00200621050c020b200041106a22052000490d00200641017422082005200820054b1b22054100480d00024020060d00024020050d00410121030c030b200510272203450d040c020b20062005460d01200320062005102b2203450d030c010b1032000b200320006a220020093700082000200a370000200441146a21000b20012902002000ad4220862003ad84100320050d010c020b1030000b200310290b200241106a24000f0b1030000b990101027f230041106b2202240002400240200028022022034102470d00200241003a000b20012002410b6a410110720c010b200241013a000b20012002410b6a410110722001200041201072024020034101460d00200241003a000b20012002410b6a410110720c010b200241013a000b20012002410b6a410110722002200028022436020c20012002410c6a410410720b200241106a24000bbd0401047f230041106b22022400024002400240024020002d00000e03010200010b200041046a280200220341ffff03200341ffff03491b220041c0006a41ff0020002003413e2000413e491b2204461b2103200020046b2100410121040340024002400240200441ff01714102470d00200321050c010b410021052004410171450d00410021040c010b2000450d04024002402000418002490d00200041817e6a210041ff0121030c010b2000417f6a2103410021000b410221040b200220033a000f20012002410f6a41011072200521030c000b0b200241003a000f20012002410f6a410110720c010b200041046a280200220341ffff03200341ffff03491b22042003413e2004413e491b22056b2103024020002d00010d00200441807f7341bf7f20042005461b2100410121040340024002400240200441ff01714102470d00200021050c010b410021052004410171450d00410021040c010b2003450d0302402003418002490d00200341817e6a210341ff012100410221040c010b2003417f6a210041022104410021030b200220003a000f20012002410f6a41011072200521000c000b0b200441406a417f20042005461b2100410121040340024002400240200441ff01714102470d00200021050c010b410021052004410171450d00410021040c010b2003450d02024002402003418002490d00200341817e6a210341ff0121000c010b2003417f6a2100410021030b410221040b200220003a000f20012002410f6a41011072200521000c000b0b200241106a24000be90d02097f027e230041e0006b22022400200241386a41002902a4a045370300200241306a410029029ca045370300200241286a4100290294a045370300200241206a410029028ca045370300200241186a4100290284a045370300200241106a41002902fc9f45370300200241086a41002902f49f45370300200241002902ec9f453703002002410036024820024201370340200241d0006a200210f60220022802502103024002400240024020022802442204200228024822056b20022802582206490d00200228024021070c010b200520066a22072005490d01200441017422082007200820074b1b22084100480d010240024020040d00024020080d00410121070c020b2008102722070d010c040b2002280240210720042008460d00200720042008102b2207450d030b20022008360244200220073602400b200720056a2003200610e4071a2002200520066a36024802402002280254450d00200310290b200241d0006a200241106a10f602200228025021080240024020022802442204200228024822056b20022802582203490d0020022802402106200421070c010b200520036a22062005490d01200441017422072006200720064b1b22074100480d010240024020040d00024020070d00410121060c020b200710272206450d040c010b2002280240210620042007460d00200620042007102b2206450d030b20022007360244200220063602400b200620056a2008200310e4071a2002200520036a220336024802402002280254450d00200810290b02400240200720036b4104490d00200341046a21050c010b200341046a22052003490d01200741017422042005200420054b1b22044100480d010240024020070d00024020040d00410121060c020b200410272206450d040c010b20072004460d00200620072004102b2206450d030b20022004360244200220063602400b200620036a41003600002002200536024820022802242103024002402002280244220720056b4104490d00200228024021060c010b200541046a22062005490d01200741017422042006200420064b1b22044100480d010240024020070d00024020040d00410121060c020b200410272206450d040c010b2002280240210620072004460d00200620072004102b2206450d030b20022004360244200220063602400b200620056a20033600002002200541046a220636024820022802282104024002402002280244220320066b4104490d00200228024021070c010b200641046a22072006490d01200341017422082007200820074b1b22084100480d010240024020030d00024020080d00410121070c020b200810272207450d040c010b2002280240210720032008460d00200720032008102b2207450d030b20022008360244200220073602400b200720066a20043600002002200541086a360248200241306a2802002108200241386a200241346a200228022c4101461b2802002205200241c0006a10710240024020050d00200228024821040c010b20082005410c6c6a21092002280244210620022802482104034002400240200620046b4108490d00200441086a210520022802402103200621070c010b200441086a22052004490d03200641017422072005200720054b1b22074100480d030240024020060d00024020070d00410121030c020b200710272203450d060c010b2002280240210320062007460d00200320062007102b2203450d050b20022007360244200220033602400b200320046a200829000037000020022005360248200841086a280200210402400240200720056b41034d0d00200721060c010b200541046a22062005490d032007410174220a2006200a20064b1b22064100480d030240024020070d00024020060d00410121030c020b200610272203450d060c010b20072006460d00200320072006102b2203450d050b20022006360244200220033602400b200320056a20043600002002200541046a220436024820092008410c6a2208470d000b0b200228023c2107024002402002280244220620046b4104490d00200228024021050c010b200441046a22052004490d01200641017422032005200320054b1b22034100480d010240024020060d00024020030d00410121050c020b200310272205450d040c010b2002280240210520062003460d00200520062003102b2205450d030b20022003360244200220053602400b200520046a2007360000200441046aad210b2002350240210c02402002280200450d00200241086a280200450d00200228020410290b200b422086210b02402002280210450d00200241186a280200450d00200241146a28020010290b200b200c84210b0240200228022c450d0020022802342205450d002005410c6c450d00200228023010290b200241e0006a2400200b0f0b1032000b1030000bd80401067f20012802042102024002400240024020012802004101470d002001410c6a280200220141046a2203417f4c0d0102400240024002400240024002400240024002402003450d00200310272204450d0c200141c000490d04200141808001490d052001418080808004490d0620030d010b41012103410110272204450d07200441033a0000410521050c010b200441033a000002402003417f6a41034d0d00200321050c020b200341017422064105200641054b1b22054100480d0720032005460d010b200420032005102b2204450d050b20042001360001410521060c030b024020030d0041012103410110272204450d040b200420014102743a000041012106200321050c020b02400240200341014d0d00200321050c010b200341017422064102200641024b1b2105024020030d002005102722040d010c040b20032005460d00200420032005102b2204450d030b41022106200420014102744101723b00000c010b02400240200341034d0d00200321050c010b200341017422064104200641044b1b22054100480d03024020030d002005102722040d010c030b20032005460d00200420032005102b2204450d020b20042001410274410272360000410421060b0240200520066b2001490d00200521030c060b200620016a22032006490d01200541017422072003200720034b1b22034100480d0120052003460d05200420052003102b22040d050b1030000b1032000b20002002200141086a280200108a010f0b1038000b1039000b200420066a2002200110e4071a2000200620016a36020820002003360204200020043602000bec1c03057f017e037f230041d00d6b22022400024002402001450d00200220003602080c010b20024180a6cc003602080b2002200136020c200241f8096a200241086a10f8020240024020022802fc092203450d00200241f8096a410c6a280200210120022802800a210420022802f8092100200241a8066a200241f8096a41106a41e00010e4071a200241f8096a200241086a10f90220022802f8090d0102402001450d00200141246c21002003210103400240024020012d0000220541044b0d0002400240024020050e050400010204040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b2004450d00200441246c450d00200310290b2002418c0a6a4102360200200241b4066a4104360200200242023702fc09200241a0d1c2003602f809200241043602ac0620024198d1c2003602a806200241003602f40220024180a6cc003602f0022002200241a8066a3602880a2002200241f0026a3602b006200241f8096a41b0d1c2001040000b200241f0026a41086a2205200241f8096a41086a280200360200200220022903f8093703f002200241f8096a200241a8066a41e00010e4071a200241206a200241f8096a41e00010e4071a200241106a41086a22062005280200360200200220022903f00237031020024180016a410c6a200136020020024180016a41086a20043602002002200336028401200220003602800120024180016a41106a200241206a41e00010e4072101200241f8016a2006280200360200200220022903103703f00120024180016a10fa020240024002402002280280012200450d0020024180026a2000417f6a10fb02200241f8096a200228028002220020022802880210cd01200241a8066a41086a200241810a6a290000370300200241a8066a41106a2205200241890a6a290000370300200241a8066a41186a2204200241910a6a290000370300200220022900f9093703a8060240024020022d00f8094101460d00200241f0026a41186a4200370300200241f0026a41106a4200370300200241f8026a4200370300200242003703f0020c010b200241f0026a41186a2004290300370300200241f0026a41106a2005290300370300200241f0026a41086a200241a8066a41086a290300370300200220022903a8063703f0020b0240200228028402450d00200010290b200241f0026a2001412010e7070d00200241f8016a280200210120022802f0012100200241003602b006200242043703a806200241a8066a41002001109d0120022802b006210402402001450d00200141c0036c21052001410674210320022802a8062004410c6c6a21010340200220003602f002200241f8096a200241f0026a10bd02200141086a200241f8096a41086a280200360200200120022903f8093702002001410c6a2101200041c0036a2100200541c07c6a22050d000b200341406a41067620046a41016a21040b200241f0026a41086a2004360200200220022903a80622073703f002200241a8066a41086a2004360200200220073703a806200241f8096a200241a8066a10fc020240200241d0016a2201200241f8096a412010e707450d0041b495cc00ad4280808080e0018410082001ad4280808080800484100a200241f8096aad4280808080800484100a0b02402001200241f8096a412010e7070d00100b200241f4016a280200210620022802f001210320022802f801210520024180026a20024180016a41f00010e4071a2003200541c0036c6a21002002280280022108200321010240024002402005450d00200241a8066a41f0006a21042003210102400340200241c0056a200141e80010e4071a200141e8006a2903002107200241f0026a200141f0006a41d00210e4071a20074203510d01200241a8066a200241c0056a41e80010e4071a20022007370390072004200241f0026a41d00210e4071a2002200241a8066a3602e809200241f8096a200241e8096a10bd0220022802800a2105024020022802fc09450d0020022802f80910290b200241f8096a200241a8066a41c00310e4071a200241003602b80d200241e8096a200241f8096a2005200241b80d6a10fd0220022d00e8094101460d04200141c0036a22012000470d000c030b0b200141c0036a21010b20002001460d00034020014198016a10c2012000200141c0036a2201470d000b0b02402006450d00200641c0036c450d00200310290b10fe02200810ff020240100c4101470d00200241f8096a108003200220024180026a410c6a28020022043602c80d20022802840221032002200241f8096a410c6a28020022013602cc0d20042001470d052004450d0420022802fc0921064100210541dfcfc200ad4280808080c0028421070340024002400240024002400240024002400240200320056a22012d00002208200620056a22002d0000470d0002400240024002400240024020080e06000102030405000b20032006460d0d200141016a200041016a412010e7070d050c060b024020032006460d00200141016a280000200041016a280000470d050b200141106a2802002208200041106a280200470d04200141086a2802002209200041086a280200220a460d0a2009200a200810e7070d040c0a0b024020032006460d00200141016a280000200041016a280000470d040b200141106a2802002208200041106a280200470d03200141086a2802002209200041086a280200220a460d082009200a200810e7070d030c080b024020032006460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a2802002209200041086a280200220a460d062009200a200810e7070d020c060b200141046a2802002208200041046a280200470d012008450d04200141086a280200200041086a280200470d012001410c6a2802002000410c6a280200470d010c040b2001410c6a28020022082000410c6a280200470d00200141046a2802002209200041046a280200220a460d022009200a200810e707450d020b20071008200241a8066a200110bc0220023502b00642208620022802a8062208ad84100a024020022802ac06450d00200810290b200241a8066a200010bc0220023502b00642208620022802a8062208ad84100a024020022802ac06450d00200810290b20012d000020002d00002208470d06024020080e06000605040302000b20032006460d070b200141016a200041016a412010e7070d050c060b2001410c6a28020022082000410c6a280200470d04200141046a2802002201200041046a2802002200460d0520012000200810e7070d040c050b200141046a2802002208200041046a280200470d032008450d04200141086a280200200041086a280200470d032001410c6a2802002000410c6a280200460d040c030b024020032006460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a2802002201200041086a2802002200460d0320012000200810e7070d020c030b024020032006460d00200141016a280000200041016a280000470d020b200141106a2802002208200041106a280200470d01200141086a2802002201200041086a2802002200460d0220012000200810e7070d010c020b024020032006460d00200141016a280000200041016a280000470d010b200141106a2802002208200041106a280200470d00200141086a2802002201200041086a2802002200460d0120012000200810e707450d010b41c8abc700412741b8a1cc001033000b200541246a21052004417f6a22040d000c050b0b4197acc700411e41b8a1cc001033000b200220022f00e90920022d00eb09411074721081032002280200200228020441b8a1cc001033000b4199abc700412441b8a1cc001033000b41fdaac700411c41b8a1cc001033000b024020024180026a41306a2201200241f8096a41306a2200412010e707450d0041b495cc00ad4280808080e0018410082001ad4280808080800484100a2000ad4280808080800484100a0b024020012000412010e707450d0041efabc700412841b8a1cc001033000b024020022802840a2200450d0020022802fc092101200041246c210003400240024020012d0000220541044b0d0002400240024020050e050400010204040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b0240200241800a6a2802002201450d00200141246c450d0020022802fc0910290b0240200228028c022200450d002002280284022101200041246c210003400240024020012d0000220541044b0d0002400240024020050e050400010204040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b024020024188026a2802002201450d00200141246c450d0020022802840210290b200241d00d6a240042010f0b200241f0026a41146a4109360200200241f0026a410c6a4112360200200241c0056a41146a41033602002002200241c80d6a3602b80d2002200241cc0d6a3602e809200241a8066a41146a4100360200200242033702c405200241aca5cc003602c005200241123602f40220024180a6cc003602b806200242013702ac06200241c0abc7003602a8062002200241f0026a3602d0052002200241a8066a360280032002200241e8096a3602f8022002200241b80d6a3602f002200241c0056a4180a6cc001040000ba00a03077f037e057f230041d0026b2202240041002103200241003a00c8022001280204417f6a210402400240024002400240024003402004417f460d01200241a8026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8022004417f6a21042005210320054120470d000b200241e8006a41086a200241a8026a41086a290300370300200241e8006a41106a200241a8026a41106a290300370300200241e8006a41186a200241a8026a41186a290300370300200220022903a8023703682002200110c80120022802000d022002280204210641002104200241003a00c80220012802042107417f2103034020072004460d02200241a8026a20046a200128020022082d00003a00002001200720036a3602042001200841016a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241a8016a41086a200241a8026a41086a2903002209370300200241a8016a41106a200241a8026a41106a290300220a370300200241a8016a41186a200241a8026a41186a290300220b37030020024188016a41086a200937030020024188016a41106a200a37030020024188016a41186a200b370300200220022903a80222093703a801200220093703880141002104200241003a00c802200720056b210c200720036a21030340200c2004460d04200241a8026a20046a200820046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241e8016a41086a200241a8026a41086a2903002209370300200241e8016a41106a200241a8026a41106a290300220a370300200241e8016a41186a200241a8026a41186a290300220b370300200241c8016a41086a22042009370300200241c8016a41106a2203200a370300200241c8016a41186a2205200b370300200220022903a80222093703e801200220093703c801200241a8026a200110ba0420022802a8022201450d04200241c8006a41086a2208200241e8006a41086a290300370300200241c8006a41106a2207200241e8006a41106a290300370300200241c8006a41186a220c200241e8006a41186a290300370300200241286a41086a220d20024188016a41086a290300370300200241286a41106a220e20024188016a41106a290300370300200241286a41186a220f20024188016a41186a29030037030020022002290368370348200220022903880137032820022902ac022109200241086a41186a22102005290300370300200241086a41106a22052003290300370300200241086a41086a22032004290300370300200220022903c801370308200020093702082000200136020420002006360200200041106a2002290348370200200041186a2008290300370200200041206a2007290300370200200041286a200c290300370200200041306a2002290328370200200041386a200d290300370200200041c0006a200e290300370200200041c8006a200f290300370200200041e8006a2010290300370200200041e0006a2005290300370200200041d8006a2003290300370200200041d0006a20022903083702000c050b0240200341ff0171450d00200241003a00c8020b200041003602040c040b0240200441ff0171450d00200241003a00c8020b200041003602040c030b200041003602040c020b0240200441ff0171450d00200241003a00c8020b200041003602040c010b200041003602040b200241d0026a24000bff0303037f017e037f230041d00a6b22022400200241086a200110c80102400240024002402002280208450d00200041003602000c010b200228020c2203200128020441c0036e2204200420034b1bad42c0037e2205422088a70d012005a72206417f4c0d010240024020060d00410821070c010b200610272207450d030b4100210420024100360218200220073602102002200641c0036e360214024002402003450d0020024190076a41f0006a2108034020024190076a2001108703200241a8066a20024190076a41e80010e4071a20022903f8072105200241d8036a200841d00210e4071a20054203510d02200241f0026a200241a8066a41e80010e4071a200241206a200241d8036a41d00210e4071a024020042002280214470d00200241106a200410a40120022802102107200228021821040b2007200441c0036c6a200241f0026a41e80010e40722062005370368200641f0006a200241206a41d00210e4071a2002200441016a22043602182003417f6a22030d000b0b20002002290310370200200041086a200241106a41086a2802003602000c010b2000410036020002402004450d00200441c0036c210320074198016a21040340200410c201200441c0036a2104200341c07c6a22030d000b0b20022802142204450d00200441c0036c450d00200710290b200241d00a6a24000f0b1038000b1039000bb8550b057f017e017f017e037f017e037f017e0f7f077e097f230022012102200141a0026b41607122032400200341286a2000109c03200341e0006a41186a4200370300200341e0006a41106a22044200370300200341e0006a41086a220142003703002003420037036041b3e6ca00ad4280808080e000841001220529000021062001200541086a29000037030020032006370360200510294180a4cb00ad4280808080a00284100122052900002106200341386a41086a2207200541086a290000370300200320063703382005102920042003290338220637030020034180026a41086a200129030037030020034180026a41106a200637030020034180026a41186a20072903003703002003200329036037038002200341203602dc01200320034180026a3602d801200341c0016a20034180026aad428080808080048422081007108b020240024002400240024002400240024020032802c00122050d00410221010c010b20032802c40121092003200341c0016a41086a28020036025420032005360250200341206a200341d0006a10c8010240024020032802200d00200341186a200341d0006a10c80120032802180d002003280254220a200328021c2201490d002001417f4c0d040240024020010d004100210a410121070c010b2001102d2207450d0420072003280250220b200110e4071a2003200a20016b3602542003200b20016a3602502001210a0b2007450d002001ad422086200aad842106410121010c010b200341003602f001200342013703e8012003410d36023c2003200341d8016a3602382003200341e8016a36024c200341f4006a410136020020034201370264200341f4eaca003602602003200341386a360270200341cc006a41a8a3c800200341e0006a10371a20033502f00142208620033502e801841008024020032802ec01450d0020032802e80110290b410221010b2009450d00200510290b0240024020014102460d004100210502402006422088a72006a7220920014101461b4108470d0041012105200741aca0c500460d00200729000042f0deb1db968cd9b7f4005121050b02402009450d00200710290b20050d010b200341f4016a41002902f49f45370200200341003602e801200341002902ec9f453702ec01200341e0006a41186a22074200370300200341e0006a41106a22094200370300200341e0006a41086a220142003703002003420037036041b3e6ca00ad4280808080e000841001220529000021062001200541086a29000037030020032006370360200510294180a4cb00ad4280808080a00284100122052900002106200341386a41086a220a200541086a290000370300200320063703382005102920042003290338370000200441086a200a29030037000020034180026a41086a200129030037030020034180026a41106a200929030037030020034180026a41186a20072903003703002003200329036037038002200341003602c801200342013703c0014100200341c0016a1071200341e0006a200341e8016a41047210f6022003280260210b024002400240024002400240024020032802c401220a20032802c80122056b20032802682207490d0020032802c0012101200a21090c010b200520076a22012005490d01200a41017422092001200920014b1b22094100480d0102400240200a0d00024020090d00410121010c020b2009102722010d010c0e0b20032802c0012101200a2009460d002001200a2009102b2201450d0d0b200320093602c401200320013602c0010b200120056a200b200710e4071a2003200520076a22053602c80102402003280264450d00200b10290b20082005ad4220862001ad84100302402009450d00200110290b200341e0006a41186a22074200370300200341e0006a41106a22094200370300200341e0006a41086a220142003703002003420037036041c99fc500ad4280808080900184100122052900002106200341d0006a41086a220a200541086a29000037030020032006370350200510292001200a29030037030020032003290350370360419094c700ad4280808080e00184100122052900002106200341386a41086a220a200541086a290000370300200320063703382005102920042003290338370000200441086a200a29030037000020034180026a41086a200129030037030020034180026a41106a200929030037030020034180026a41186a2007290300370300200320032903603703800220034120360254200320034180026a360250200341c0016a20081007108b02024020032802c0012201450d0020032802c401210702400240200341c0016a41086a280200450d0020012d00000d00410121050c010b41002105200341003602f001200342013703e8012003410d36023c2003200341d0006a3602382003200341e8016a3602d801200341f4006a410136020020034201370264200341f4eaca003602602003200341386a360270200341d8016a41a8a3c800200341e0006a10371a20033502f00142208620033502e80184100820032802ec01450d0020032802e80110290b02402007450d00200110290b42c0f0f50b210620050d050b200341e0006a41186a220a4200370300200341e0006a41106a220b4200370300200341e0006a41086a220142003703002003420037036041c99fc500ad4280808080900184220610012205290000210c200341d0006a41086a2207200541086a2900003703002003200c370350200510292001200729030037030020032003290350370360419094c700ad4280808080e0018410012205290000210c200341386a41086a2209200541086a2900003703002003200c3703382005102920042003290338370000200441086a200929030037000020034180026a41086a200129030037030020034180026a41106a200b29030037030020034180026a41186a200a2903003703002003200329036037038002410110272201450d0b200141003a000020082001ad4280808080108410032001102920061001220129000021062007200141086a290000370300200320063703502001102941d29fc500ad42808080809001841001220129000021062009200141086a2900003703002003200637033820011029412010272207450d062007200329035037000020072003290338370010200741086a2205200341d0006a41086a290300370000200741186a2209200341386a41086a290300370000412010272201450d0620012007290000370000200141186a2009290000370000200141106a200741106a290000370000200141086a2005290000370000200341e0006a2001ad42808080808004841015108b0220032802602205450d0242a08080808004210620034188026a210d200341f8006a210e03402006210c20012109200521010240024020032902642206422088a722054120490d0020072001460d0120072001412010e707450d010b02402006a7450d00200110290b20092101200c21060c030b0240200ca7450d00200910290b20034180026a2001200510fb0502402003280290022209450d00200329029402220ca7210a02400240024020054178714120470d0041002802d8a74c450d0141002802888040210541002802848040210b41002802dca74c210f200341e6003602a001200342dc8080801037039801200341db9fc000360294012003421337028c01200341c89fc00036028801200342003703800120034180a6cc0036027c20034201370370200341c09fc00036026c20034113360268200341c89fc00036026420034101360260200b4180a4c000200f410246220f1b200341e0006a20054198a4c000200f1b2802101102000c010b2005417c714128460d002003290380022110200e200d290300370300200320103703702003200c37026420032009360260200320053602ec01200320013602e801200341e0006a200341e8016a10d005200a41ffffff3f71450d020c010b200a41ffffff3f71450d010b200910290b200341e0006a2006428080808070832001ad841015108b02200328026022050d000c020b0b1032000b2006a7450d010b200110290b200710294280c0a8ca9a3a21060b200610fc050b20002802002211200041106a200041d0006a200341286a4101109d03200341e0006a41186a22074200370300200341e0006a41106a22094200370300200341e0006a41086a220142003703002003420037036041d787cc00ad4280808080900184100122052900002106200341d0006a41086a2200200541086a2900003703002003200637035020051029200120002903003703002003200329035037036041eb87cc00ad4280808080f00184100122052900002106200341386a41086a2200200541086a290000370300200320063703382005102920042003290338370000200441086a200029030037000020034180026a41086a200129030037030020034180026a41106a200929030037030020034180026a41186a20072903003703002003200329036037038002200341e8016a20034180026a10fd0502400240024020032802e80122090d0041002107200341003602c801200342043703c001410421094100210141002105410021124100210d410421130c010b20032902ec012106200320093602c001200320063702c4012006a7210702402006422088a7220141024f0d004104211341002112200121054100210d0c010b200928020821122009280204210d2009280200211320092009410c6a2001417f6a2201410c6c10e5071a200320013602c80141012105200141014b0d010b0340024020052007470d00200341c0016a20074101109d0120032802c001210920032802c801220121050b20092005410c6c6a22054100360208200542043702002003200141016a22013602c801200141014b0d0120032802c4012107200121050c000b0b200341e8016a41086a2207200341c0016a41086a280200360200200320032903c00122063703e801024002402006a722090d00200341e0006a41186a22074200370300200341e0006a41106a22094200370300200341e0006a41086a220142003703002003420037036041d787cc00ad4280808080900184100122052900002106200341d0006a41086a2200200541086a2900003703002003200637035020051029200120002903003703002003200329035037036041eb87cc00ad4280808080f00184100122052900002106200341386a41086a2200200541086a290000370300200320063703382005102920042003290338370000200441086a200029030037000020034180026a41086a200129030037030020034180026a41106a200929030037030020034180026a41186a20072903003703002003200329036037038002200810040c010b200341e0006a41186a22004200370300200341e0006a41106a220a4200370300200341e0006a41086a220142003703002003420037036041d787cc00ad4280808080900184100122052900002106200341d0006a41086a220b200541086a29000037030020032006370350200510292001200b2903003703002003200329035037036041eb87cc00ad4280808080f00184100122052900002106200341386a41086a220b200541086a290000370300200320063703382005102920042003290338370000200441086a200b29030037000020034180026a41086a200129030037030020034180026a41106a200a29030037030020034180026a41186a2000290300370300200320032903603703800220034120360264200320034180026a360260200341e8016a200341e0006a10ee05024020072802002201450d002001410c6c21052009210103400240200141046a2802002207450d00200741246c450d00200128020010290b2001410c6a2101200541746a22050d000b0b20032802ec012201450d002001410c6c450d00200910290b200341e0006a41186a22074200370300200341e0006a41106a22094200370300200341e0006a41086a220142003703002003420037036041d787cc00ad4280808080900184100122052900002106200341d0006a41086a2200200541086a29000037030020032006370350200510292001200029030037030020032003290350370360419a88cc00ad4280808080a00184100122052900002106200341386a41086a2200200541086a290000370300200320063703382005102920042003290338370000200441086a200029030037000020034180026a41086a200129030037030020034180026a41106a200929030037030020034180026a41186a20072903003703002003200329036037038002200341e0006a20034180026a10fd0520032902644200200328026022051b2206422088a7220e410c6c21012005410420051b220f41746a2105410121090240034020092107024020010d004100210a0c020b200141746a2101200741016a2109200541146a21002005410c6a220a210520002802002200450d000b200341e0006a41086a200a2802002201410c6a290200370300200341f0006a200141146a290200370300200320012902043703602001411c6a2802002114200141206a28020021152001280200210b2001200141246a2000417f6a220541246c10e5071a200a41086a20053602004101210a0b200341e8016a41106a200341e0006a41106a2205290300370300200341e8016a41086a200341e0006a41086a2201290300370300200320032903603703e8012003200f3602d801200320063702dc01200341e0006a41186a2200420037030020054200370300200142003703002003420037036041d787cc00ad428080808090018410012209290000210c200341d0006a41086a2216200941086a2900003703002003200c370350200910292001201629030037030020032003290350370360419a88cc00ad4280808080a0018410012209290000210c200341386a41086a2216200941086a2900003703002003200c3703382009102920042003290338370000200441086a201629030037000020034180026a41086a200129030037030020034180026a41106a200529030037030020034180026a41186a2000290300370300200320032903603703800220034120360264200320034180026a360260200341d8016a200341e0006a10ee052006a721000240200e450d00200e410c6c2105200f210103400240200141046a2802002209450d00200941246c450d00200128020010290b2001410c6a2101200541746a22050d000b0b02402000450d002000410c6c450d00200f10290b200341c0016a41086a220f200341e8016a41086a220e290300370300200341c0016a41106a2216200341e8016a41106a2217290300370300200320032903e8013703c001410021000240200a450d00201241246c2101201321050340024020010d00410121000c020b2001415c6a210120052802002109200541246a21052009200b470d000b410021000b200341e0006a41186a22094200370300200341e0006a41106a220a4200370300200341e0006a41086a220142003703002003420037036041d787cc00ad4280808080900184100122052900002106200341d0006a41086a2218200541086a2900003703002003200637035020051029200120182903003703002003200329035037036041cd87cc00ad4280808080a00184100122052900002106200341386a41086a2218200541086a290000370300200320063703382005102920042003290338370000200441086a201829030037000020034180026a41086a200129030037030020034180026a41106a200a29030037030020034180026a41186a20092903003703002003200329036037038002200341e0006a20034180026a412010c0042003280260210120032902642106200341003602582003420437035020172016290300370300200e200f290300370300200320032903c0013703e8012001410420011b22162006420020011b2206422088a741027422016a21182006a721192013201241246c22056a211a02400240024020014102752201200541246d6a22052001490d00200520006a220120054f0d010b2007417f6a211b2003200b360284022003200036028002200320032903e801370388022003200341f0016a290300370290022003200341f8016a29030037039802200d45200d41246c4572211c410021054104211d410421174100211e201321092016211f4101210a03400240024002400240200a4101470d00201821012016210a2019210e0240201f450d0020162018470d02201b21012015210a2014210e201941ffffffff0371450d00201f1029201b21012015210a2014210e0b0240201a2009460d00200941146a29020021062009410c6a290200210c200941206a280200210b2009411c6a280200210f200929020421084101210d4100211f20092112200941246a210920012118200a2116200e21190c030b4100210a201c0d00201310290b20004102460d052003410036026020032903980221062003200329037837039802200329039002210c2003200329037037039002200329038802210820032003290368370388022003290380022110200320032903602220370380022010a74101470d052010422088a7210e2020a721004101210d2014210f2015210b200721120c020b4102210d20162112201641046a21160b2012280200210e4101210a410021120b0240201e2003280254470d0002400240200a4101460d004100210120004102460d01200041014621010c010b024020004102460d000240201f0d00417f201a20096b41246d220120004101466a221720172001491b21010c020b417f417f201820166b4102752201201a20096b41246d6a221720172001491b220120004101466a221720172001491b21010c010b0240201f450d00417f201820166b4102752201201a20096b41246d6a221720172001491b21010c010b201a20096b41246d21010b200341d0006a201e417f200141016a221720172001491b1093012003280250221d21170b201720056a2201200e360200200141286a2012360200200141246a200d360200200141206a200b3602002001411c6a200f360200200141146a20063702002001410c6a200c370200200141046a20083702002003201e41016a221e3602582005412c6a21050c000b0b200341d0006a410020011093012003280250211d2003280258211e2003200b360284022003200036028002200320032903e801370388022003200341f0016a290300370290022003200341f8016a29030037039802201d201e412c6c6a2101024020182016460d00201e201820166b417c6a4102766a210020162105034020052802002109200141246a4102360200200120093602002001412c6a21012018200541046a2205470d000b200041016a211e0b0240201941ffffffff0371450d00201610290b02402013450d000240201a2013460d00200341f8006a2109200341f0006a2100200341e8006a210a2013210503402005280200210b20092005411c6a2902003703002000200541146a290200370300200a2005410c6a2902003703002003200541046a2902003703602001200b360200200141046a20032903603702002001410c6a200a290300370200200141146a20002903003702002001411c6a2009290300370200200141246a42013702002001412c6a2101201e41016a211e200541246a2205201a470d000b0b200d450d00200d41246c450d00201310290b200329038802210c2003290390022108200329039802211020032903800221062003410036026002402006a74101470d002015ad4220862014ad8421212006422088a7210520032903782120200329037021222003290368212320032903602106034020202124202221252023212620012005360200200141046a200c370200200141286a2007360200200141246a41013602002001411c6a20213702002001410c6a2008370200200141146a2010370200200341003602602001412c6a2101201e41016a211e2006a721092006422088a72105200329037821202003290370212220032903682123200329036021062026210c202521082024211020094101460d000b0b2003201e3602580b20032802542127201e4115490d03201e410176ad422c7e2206422088a70d012006a72228417f4c0d01202810272229450d004100210120034100360288022003420437038002201d41546a212a201d412c6a212b201d41fc7e6a212c410421074100212d201e211803402018210f410021184101210b0240200f417f6a2200450d00024002400240024002400240201d2000412c6c6a280200200f412c6c220e201d6a41a87f6a2802002205490d00200f417e6a210d202c200e6a2100410021184100210903400240200d2009470d00200f210b0c080b200941016a210920052000280200220a4f210b200041546a2100200a2105200b0d000b200941016a210b2009417f73200f6a21000c010b202c200e6a210902400340024020004101470d00410021000c020b2000417f6a210020052009280200220a49210b200941546a2109200a2105200b0d000b0b200f2000490d01200f201e4b0d02200f20006b220b410176220a450d00201d2000412c6c6a2105202a200e6a21090340200341e0006a41286a220d200541286a220e280200360200200341e0006a41206a2212200541206a2216290200370300200341e0006a41186a2217200541186a2218290200370300200341e0006a41106a221f200541106a2219290200370300200341e0006a41086a2214200541086a221529020037030020032005290200370360200941086a221a2902002106200941106a2213290200210c200941186a221b2902002108200941206a221c2902002110200941286a222e280200212f20052009290200370200200e202f36020020162010370200201820083702002019200c37020020152006370200202e200d280200360200201c2012290300370200201b20172903003702002013201f290300370200201a2014290300370200200920032903603702002005412c6a2105200941546a2109200a417f6a220a0d000b0b024020000d00200021180c050b0240200b41094d0d00200021180c050b200f201e4b0d02200f20006b210a202b2000412c6c6a210d0340200f2000417f6a2218490d040240200f20186b220b4102490d00201d2000412c6c6a2205280200201d2018412c6c6a220028020022164f0d00200341e0006a41206a2217200041246a290200370300200341e0006a41186a221f2000411c6a290200370300200341e0006a41106a2219200041146a290200370300200341e0006a41086a22142000410c6a29020037030020002902042106200041286a200541286a28020036020020032006370360200041206a200541206a290200370200200041186a200541186a290200370200200041106a200541106a290200370200200041086a200541086a29020037020020002005290200370200410121090240200b4103490d00200028025820164f0d004102210e200d211203402012220541546a22092005290200370200200941286a200541286a280200360200200941206a200541206a290200370200200941186a200541186a290200370200200941106a200541106a290200370200200941086a200541086a290200370200200a200e2209460d01200941016a210e2005412c6a22122802002016490d000b0b2005201636020020002009412c6c6a22052003290360370204200541246a20172903003702002005411c6a201f290300370200200541146a20192903003702002005410c6a20142903003702000b2018450d05200d41546a210d200a41016a210a20182100200b410a4f0d050c000b0b2000200f4180cac700104c000b200f201e4180cac700104b000b200f2000417f6a2218490d00200f201e4190cac700104b000b2018200f4190cac700104c000b0240202d200328028402470d0020034180026a202d4101108d0120032802800221072003280288022201212d0b2007202d4103746a2205200b360204200520183602002003200141016a2201360288022001212d024020014102490d000240024003400240024002400240024020072001417f6a4103746a2205280200450d00200141037420076a220a41746a2802002200200528020422094b0d010b20014103490d022005280204210920072001417d6a22124103746a28020421050c010b4102212d200141024d0d0620072001417d6a22124103746a2802042205200920006a4d0d004103212d200141034d0d06200a41646a280200200520006a4b0d050b20052009490d010b2001417e6a21120b02400240024002400240024002402001201241016a22164d0d00200120124d0d0120072012410374221f6a2201280204221920012802006a22012007201641037422146a22052802002217490d022001201e4b0d03201d2017412c6c6a220d2005280204220e412c6c22056a21092001412c6c2107200120176b220a200e6b2201200e4f0d04202920092001412c6c220510e407220f20056a2100200e4101480d0520014101480d05202a20076a21052009210103402005200141546a2209200041546a220a200a280200200928020049220b1b2207290200370200200541286a200741286a280200360200200541206a200741206a290200370200200541186a200741186a290200370200200541106a200741106a290200370200200541086a200741086a2902003702002000200a200b1b21000240200d20092001200b1b2201490d00200f21070c080b200541546a2105200f2107200f2000490d000c070b0b2016200141a0cac7001036000b2012200141b0cac7001036000b2017200141c0cac700104c000b2001201e41c0cac700104b000b2029200d200510e407220f20056a21000240200e4101480d00200a200e4c0d00201d20076a210b200f2107200d210103402001200920072009280200200728020049220a1b2205290200370200200141286a200541286a280200360200200141206a200541206a290200370200200141186a200541186a290200370200200141106a200541106a290200370200200141086a200541086a29020037020020072007412c6a200a1b21072001412c6a21012009412c6a2009200a1b2209200b4f0d03200020074b0d000c030b0b200d2101200f21070c010b20092101200f21070b20012007200020076b22052005412c706b10e4071a0240200328028802220120124d0d002003280280022207201f6a22052019200e6a36020420052017360200200120164d0d02200720146a2205200541086a20012016417f736a41037410e5071a20032001417f6a220136028802200141014b0d010c030b0b2012200141d0cac7001036000b201620011042000b2001212d0b2018450d030c000b0b1039000b1038000b024020032802840241ffffffff0171450d00200710290b2028412c7021012028412c490d0120282001460d01202910290c010b201e4102490d00201e417f6a2107201d201e412c6c6a210a4101210003400240024002400240201e20072201417f6a2207490d00201e20076b22054102490d03201d2001412c6c6a2201280200201d2007412c6c6a2209280200220d4f0d03200341e0006a41206a220e200941246a290200370300200341e0006a41186a22122009411c6a290200370300200341e0006a41106a2216200941146a290200370300200341e0006a41086a22172009410c6a29020037030020092902042106200941286a200141286a28020036020020032006370360200941206a200141206a290200370200200941186a200141186a290200370200200941106a200141106a290200370200200941086a200141086a290200370200200920012902003702004101210b20054103490d022009280258200d4f0d024100210b200a210503402005220141546a22052001290200370200200541286a200141286a280200360200200541206a200141206a290200370200200541186a200141186a290200370200200541106a200141106a290200370200200541086a200141086a2902003702002000200b220f460d02200f417f6a210b2001412c6a2205280200200d4f0d020c000b0b2007201e41f0c9c700104c000b4102200f6b210b0b2001200d3602002009200b412c6c6a22012003290360370204200141246a200e2903003702002001411c6a2012290300370200200141146a20162903003702002001410c6a20172903003702000b200a41546a210a2000417f6a210020070d000b0b200341e0006a41186a22074200370300200341e0006a41106a22094200370300200341e0006a41086a220142003703002003420037036041d787cc00ad4280808080900184100122052900002106200341d0006a41086a2200200541086a2900003703002003200637035020051029200120002903003703002003200329035037036041fa87cc00ad4280808080e00084100122052900002106200341386a41086a2200200541086a290000370300200320063703382005102920042003290338370000200441086a200029030037000020034180026a41086a200129030037030020034180026a41106a200929030037030020034180026a41186a2007290300370300200320032903603703800220034120360264200320034180026a360260201d201e200341e0006a10f00302402027450d002027412c6c450d00201d10290b427f201110bb0422064280e497d0127c220c200c2006541b10fc054100410010fe0520032802282109024020032802302201450d00200141246c21052009210103400240024020012d0000220741044b0d0002400240024020070e050400010204040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012005415c6a22050d000b0b0240200328022c2201450d00200141246c450d00200910290b200224000f0b1030000bfc0403027f017e057f230041d0006b2202240041b3e6ca00ad4280808080e00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941c0e6ca00ad4280808080900184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bf104020b7f037e230041206b22022400024002400240024020012802082203410c6c41046a2204417f4c0d00200128020021050240024020040d0041012106410021040c010b200410272206450d020b2002410036020820022006360200200220043602042003200210710240024020030d002002280208210420022802042107200228020021080c010b20052003410c6c6a21092005210603402006280200210a200641086a280200220420021071024002402002280204220b2002280208220c6b2004490d0020022802002108200b21070c010b200c20046a2208200c490d05200b41017422072008200720084b1b22074100480d0502400240200b0d00024020070d00410121080c020b2007102722080d010c080b20022802002108200b2007460d002008200b2007102b2208450d070b20022007360204200220083602000b2008200c6a200a200410e4071a2002200c20046a22043602082006410c6a22062009470d000b0b2004ad4220862008ad84101b2204290000210d200441086a290000210e200441106a290000210f200241186a2206200441186a290000370300200241106a220c200f370300200241086a220b200e3703002002200d37030020041029200041186a2006290300370000200041106a200c290300370000200041086a200b2903003700002000200229030037000002402007450d00200810290b02402003450d002003410c6c21062005210403400240200441046a280200450d00200428020010290b2004410c6a2104200641746a22060d000b0b0240200141046a2802002204450d002004410c6c450d00200510290b200241206a24000f0b1038000b1039000b1032000b1030000bd70902057f057e230041b00a6b2204240020044188066a200141c00310e4071a20044188036a20044188066a109603410121050240024002400240024020042d0088034101460d00200441106a20044188036a41086a41f80210e4071a024020032802002201450d00200341086a280200210620032802042107200441086a41a6e5ca00411010fc014100210520044188066a200428020c410020042802081b108a032004280288062108200420042802900636028c0320042008360288032001200620044188036a10a1040240200428028c06450d00200810290b2007450d00200110290b200441c8096a200441e0006a10c30120044188066a200441106a41f80210e4071a20044188036a20044188066a20042903c809220920042d00d00920042d00d109200210c302200441800a6a41086a20044188036a410c6a290200370300200441800a6a41106a20044188036a41146a290200370300200441800a6a41186a20044188036a411c6a290200370300200441800a6a41206a20044188036a41246a290200370300200441a80a6a200441b4036a2802003602002004200429028c033703800a024020042d0088034101460d00200441d8096a41206a200441800a6a41246a290200370300200441d8096a41186a200441800a6a411c6a290200370300200441d8096a41106a200441800a6a41146a290200220a370300200441d8096a41086a200441800a6a410c6a290200220b370300200420042902840a220c3703d809200420042903d0093703800a20092009200a200b501b220d200d2009561b210941072102410021080240200c4201520d00200441f0096a220210ff0541e0a3c800ad4280808080a001841008419aa1c000ad4280808080e00184100802400240200b4201510d004190a1c000ad4280808080a0018410080c010b200a10160b20044193036a200241086a2800003600002004200229000037008b0341012108410f21020b20044188036a20026a22022009370000200220042903800a37000820044188066a41086a20083a000020044191066a20042900880337000020044199066a20044188036a41086a290000370000200441a1066a20044188036a41106a29000037000020044188066a41206a2004419f036a290000370000200441003a00880620044188066a10cb01200441a6e5ca00411010fc012004200428020441016a410120042802001b22023602880641a6e5ca00ad428080808080028420044188066aad4280808080c0008410034100200210fe05200420042900f109370388062004200441d8096a41206a28000036008f0602400240200c4201510d00410421020c010b200441f0096a2d000021022004200428008f0636008f0320042004290388063703880320042004290388033703800a2004200428008f033600870a0b200041003a0000200041046a20023a0000200041056a20042903800a3700002000410c6a20042800870a3600002001450d0520050d030c050b200020042f00890320042d008b034110747222023b0001200041013a0000200041036a20024110763a000020054521000c010b200020042f0089033b0001200041013a0000200041036a20042d008b033a000020032802002101410021000b20000d0220010d010c020b200341046a280200450d01200110290c010b200341046a280200450d00200110290b200441b00a6a24000bdc0203067f017e017f230041e0006b22002400200041086a41a6e5ca00411010fc01200028020c21010240200028020822024101470d0041a6e5ca00ad428080808080028410040b200041306a41186a4200370300200041306a41106a22034200370300200041306a41086a220442003703002000420037033041b3e6ca00ad4280808080e000841001220529000021062004200541086a2900003703002000200637033020051029419ca0cb00ad4280808080e00184100122052900002106200041d0006a41086a2207200541086a2900003703002000200637035020051029200320002903502206370300200041106a41086a2004290300370300200041106a41106a2006370300200041106a41186a20072903003703002000200029033037031020002001410020021b360230200041106aad4280808080800484200041306aad4280808080c0008410034101200010fe05200041e0006a24000b961f0d057f017e057f017e077f017e057f017e027f017e027f037e077f230041900e6b22012400200141b0056a41186a22024200370300200141b0056a41106a22034200370300200141b0056a41086a22044200370300200142003703b00541cd87cc00ad4280808080a001841001220529000021062004200541086a290000370300200120063703b0052005102941ac84cc00ad428080808090018410012205290000210620014180016a41086a2207200541086a29000037030020012006370380012005102920032001290380012206370300200141e0096a41086a22082004290300370300200141e0096a41106a22092006370300200141e0096a41186a220a2007290300370300200120012903b0053703e009200141b0056a200141e0096a412010c004024020012802b005220b450d000240024020012902b405220c422088a7220d0d004100210e200b210f0c010b200b41046a210f200b28020021104101210e0b200141b0056a41186a22114200370300200141b0056a41106a22124200370300200141b0056a41086a22134200370300200142003703b00541d787cc00ad42808080809001842214100122052900002106200141d0006a41086a2215200541086a290000370300200120063703502005102920132015290300370300200120012903503703b00541fa87cc00ad4280808080e000841001220529000021062015200541086a2900003703002001200637035020051029201220012903502206370300200141e0096a41086a22162013290300370300200141e0096a41106a22172006370300200141e0096a41186a22182015290300370300200120012903b0053703e009200141b0056a200141e0096a10a60320012802b0052205410420051b2119024020012902b405420020051b221a422088a72205450d00200b200d4102746a211b20192005412c6c6a211c200141e0096aad4280808080800484211d2019210503402005280200211e20112005411c6a2902003703002012200541146a29020037030020132005410c6a290200370300200120052902043703b005200541246a280200220d4103460d01200541286a280200211f200141106a41186a20112903002206370300200141106a41106a20122903002220370300200141106a41086a20132903002221370300200120012903b0052222370310200141306a41186a22232006370300200141306a41106a22242020370300200141306a41086a2225202137030020012022370330024002400240024002400240200e4101470d002010201e460d010b200d4101470d0320014180016a41186a220d202329030037030020014180016a41106a2226202429030037030020014180016a41086a222420252903003703002001200129033037038001201f41024b0d03201142003703002012420037030020134200370300200142003703b00520141001222329000021062015202341086a290000370300200120063703502023102920132015290300370300200120012903503703b005419a88cc00ad4280808080a0018422201001222329000021062015202341086a290000370300200120063703502023102920122001290350370000201241086a22272015290300370000201620132903003703002017201229030037030020182011290300370300200120012903b0053703e009200141b0056a200141e0096a10fd0520012802b00522280d01410021232001410036026820014204370360410421280c020b0240200f201b470d004100210e201b210f0c030b200f28020021104101210e200f41046a210f0c020b20012902b405210620012028360260200120063702642006422088a721230b2018200d290300370300201720262903003703002016202429030037030020012001290380013703e0090240024020234103490d00410321242001410336026820234103460d01202841246a210d2023410c6c415c6a212303400240200d41046a2802002225450d00202541246c450d00200d28020010290b200d410c6a210d202341746a22230d000c020b0b200141e0006a2023410320236b2229109d012001280260222820012802682224410c6c6a210d0240024020294102490d002023417e6a21230340200141003602b805200142043703b005200141b0056a41004100109601201520012802b8052225360200200120012903b0052206370350200d41086a2025360200200d2006370200202441016a2124200d410c6a210d202341016a222520234f21262025212320260d000b2029450d010b200d4204370200200d4100360208202441016a21240b200120243602680b2024201f4d0d01201120182903003703002012201729030037030020132016290300370300200120012903e0093703b0052028201f410c6c6a220d41086a21230240200d2802082224200d41046a280200470d00200d20244101109601202328020021240b200d280200202441246c6a220d20012903b005370204200d201e360200200d410c6a2013290300370200200d41146a2012290300370200200d411c6a20112903003702002023202328020041016a360200200141f0006a41086a200141e0006a41086a280200360200200120012903602206370370201142003703002012420037030020134200370300200142003703b00520141001220d29000021212015200d41086a29000037030020012021370350200d102920132015290300370300200120012903503703b00520201001220d29000021202015200d41086a29000037030020012020370350200d10292012200129035037000020272015290300370000201620132903003703002017201229030037030020182011290300370300200120012903b0053703e00902402006a722250d00201d10040c010b200141203602b4052001200141e0096a3602b005200141f0006a200141b0056a10ee0502402001280278220d450d00200d410c6c21232025210d03400240200d41046a2802002224450d00202441246c450d00200d28020010290b200d410c6a210d202341746a22230d000b0b2001280274220d450d00200d410c6c450d00202510290b2005412c6a2205201c470d010c020b0b201f202441a0e3c8001036000b0240201aa72205450d002005412c6c450d00201910290b200c42ffffffff0383500d00200b10290b200242003703002003420037030020044200370300200142003703b00541d482cc00ad4280808080d000841001220529000021062004200541086a290000370300200120063703b0052005102941fab1c400ad4280808080b001841001220529000021062007200541086a290000370300200120063703800120051029200320012903800122063703002008200429030037030020092006370300200a2007290300370300200120012903b0053703e009200141306a200141e0096a412010f90102400240024002400240024020012802304101470d002000200141386a2802006b220d41e7074b0d00200d20004b0d0041d482cc00ad4280808080d0008410012205290000210620014180016a41086a200541086a2900003703002001200637038001200510294185b2c400ad4280808080f00084100122052900002106200141e0096a41086a200541086a290000370300200120063703e009200510292001200d3602502001200141d0006aad4280808080c000841002220529000037031020051029200141bc056a200141d4006a3602002001200141106a41086a3602b4052001200141d0006a3602b8052001200141106a3602b005200141306a200141b0056a10752001280238221141206a2223417f4c0d01200128023021240240024020230d0041002112410121050c010b202310272205450d03202321120b024002402012410f4d0d00201221130c010b201241017422134110201341104b1b22134100480d04024020120d002013102722050d010c070b20122013460d00200520122013102b2205450d060b2005200129038001370000200541086a20014180016a41086a2903003700000240024020134170714110460d00201321120c010b201341017422124120201241204b1b22124100480d0420132012460d00200520132012102b2205450d060b200520012903e009370010200541186a200141e0096a41086a29030037000002400240201241606a2011490d00201221130c010b201141206a22132011490d04201241017422152013201520134b1b22134100480d0420122013460d00200520122013102b2205450d060b200541206a2024201110e4071a02402001280234450d00202410290b200141086a200520234180a6cc004100410010c7012001280208211202402013450d00200510290b20124101460d0002400240200d417f6a2205200d4b0d00200141306a200510b904200141b0056a20012802302212200128023810bc0420012802b0052105200141e0096a200141b0056a41047241ac0410e4071a024020054103460d0020014180016a200141e0096a41ac0410e4071a02402001280234450d00201210290b200120053602b005200141b0056a41047220014180016a41ac0410e4071a0c020b2001280234450d00201210290b200141023602a809200141023602f008200141023602b8082001410236028008200141023602c8072001410236029007200141023602d806200141023602a006200141023602e805200141023602b0050b200141e0096a200d10b90420012802e0092105200120012802e809360284012001200536028001200141b0056a20014180016a10e50220012802e409450d00200510290b200141b0056a41186a22234200370300200141b0056a41106a220d4200370300200141b0056a41086a22054200370300200142003703b00541f182cc00ad4280808080c001841001221229000021062005201241086a290000370300200120063703b0052012102941ac84cc00ad4280808080900184220610012213290000212020014180016a41086a2212201341086a290000370300200120203703800120131029200d2001290380012220370300200141e0096a41086a22112005290300370300200141e0096a41106a22242020370300200141e0096a41186a22152012290300370300200120012903b0053703e009200141e0096aad4280808080800484100420234200370300200d420037030020054200370300200142003703b00541cd87cc00ad4280808080a001841001221329000021202005201341086a290000370300200120203703b0052013102920061001221329000021062012201341086a290000370300200120063703800120131029200d2001290380012206370300201120052903003703002024200637030020152012290300370300200120012903b0053703e0092001200141e0096a41204180a6cc004100410010c70120012802004101470d03200010e006200141900e6a24000f0b1038000b1039000b1032000b41efb6c700413141b8a1cc001033000b1030000be51b08047f017e017f017e047f017e047f017e230041f0016b22012400200141a8016a41186a22024200370300200141a8016a41106a22034200370300200141a8016a41086a22044200370300200142003703a80141b3e6ca00ad4280808080e000842205100122062900002107200141c8016a41086a2208200641086a290000370300200120073703c8012006102920042008290300370300200120012903c8013703a80141c0a4cb00ad4280808080e001841001220629000021072008200641086a290000370300200120073703c80120061029200320012903c801220737030020014188016a41086a2206200429030037030020014188016a41106a2209200737030020014188016a41186a220a2008290300370300200120012903a8013703880120014188016aad428080808080048422071004200242003703002003420037030020044200370300200142003703a80120051001220b290000210c2008200b41086a2900003703002001200c3703c801200b102920042008290300370300200120012903c8013703a801419ca0cb00ad4280808080e001841001220b290000210c2008200b41086a2900003703002001200c3703c801200b1029200320012903c801220c370300200620042903003703002009200c370300200a2008290300370300200120012903a8013703880120071004200242003703002003420037030020044200370300200142003703a80120051001220b290000210c2008200b41086a2900003703002001200c3703c801200b102920042008290300370300200120012903c8013703a80141e8a0cb00ad42808080808002841001220b290000210c2008200b41086a2900003703002001200c3703c801200b1029200320012903c801220c370300200620042903003703002009200c370300200a2008290300370300200120012903a8013703880120071004200242003703002003420037030020044200370300200142003703a80120051001220b290000210c2008200b41086a2900003703002001200c3703c801200b102920042008290300370300200120012903c8013703a80141c9e6ca00ad4280808080e000841001220b290000210c2008200b41086a2900003703002001200c3703c801200b1029200320012903c801220c370300200620042903003703002009200c370300200a2008290300370300200120012903a80137038801200120014188016a412010fc012001280204210d02402001280200220e4101470d00200710040b200242003703002003420037030020044200370300200142003703a80120051001220b29000021052008200b41086a290000370300200120053703c801200b102920042008290300370300200120012903c8013703a80141cfe6ca00ad4280808080a001841001220b29000021052008200b41086a290000370300200120053703c801200b1029200320012903c801370000200341086a20082903003700002006200429030037030020092003290300370300200a2002290300370300200120012903a80137038801200141c8016a20014188016a412010cd01024002400240024020012d00c80122080d00200141c0016a200141e1016a290000370300200141b8016a200141d9016a290000370300200141b0016a200141d1016a290000370300200120012900c9013703a8010c010b20071004200141a8016a41186a2204200141e1016a290000370300200141a8016a41106a2202200141d9016a290000370300200141a8016a41086a2206200141d1016a290000370300200120012900c9013703a80120084101460d010b200141206a4200370300200141186a4200370300200141106a4200370300200142003703080c010b200141086a41186a2004290300370300200141086a41106a2002290300370300200141086a41086a2006290300370300200120012903a8013703080b200141a8016a41186a22064200370300200141a8016a41106a22094200370300200141a8016a41086a22044200370300200142003703a80141b3e6ca00ad4280808080e00084100122022900002105200141c8016a41086a2208200241086a290000370300200120053703c8012002102920042008290300370300200120012903c8013703a80141e7e6ca00ad4280808080e000841001220229000021052008200241086a290000370300200120053703c80120021029200320012903c801370000200341086a200829030037000020014188016a41086a200429030037030020014188016a41106a200929030037030020014188016a41186a2006290300370300200120012903a80137038801200141c8016a20014188016a10cf030240024020012802c801220f0d004100210a20014100360230200142043703284104210f410021100c010b200710042001200f360228200120012902cc01220537022c2005422088a7210a2005a721100b200d4100200e1b2106200141a8016a41186a22024200370300200141a8016a41106a22094200370300200141a8016a41086a22084200370300200142003703a80141b3e6ca00ad4280808080e000841001220b2900002105200141c8016a41086a2204200b41086a290000370300200120053703c801200b102920082004290300370300200120012903c8013703a80141d9e6ca00ad4280808080e001841001220b29000021052004200b41086a290000370300200120053703c801200b1029200320012903c801370000200341086a200429030037000020014188016a41086a200829030037030020014188016a41106a200929030037030020014188016a41186a2002290300370300200120012903a80137038801200141c8016a20014188016a412010cd01024002400240024020012d00c80122030d002002200141e1016a2900003703002009200141d9016a2900003703002008200141d1016a290000370300200120012900c9013703a8010c010b200710042002200141e1016a2900003703002009200141d9016a2900003703002008200141d1016a290000370300200120012900c9013703a80120034101460d010b200141d0006a4200370300200141c8006a4200370300200141c0006a4200370300200142003703380c010b200141386a41186a200141a8016a41186a290300370300200141386a41106a200141a8016a41106a290300370300200141386a41086a200141a8016a41086a290300370300200120012903a8013703380b0240200641e112490d002006419f6d6a2208450d00200141c8016a200810fb0220013502d00142208620012802c8012208ad84100420012802cc01450d00200810290b41012109024010192207422088a72202450d002007a721090b41002108200141003a00e801200921030240024002400240034020022008460d01200141c8016a20086a20032d00003a00002001200841016a22043a00e801200341016a21032004210820044120470d000b200141d8006a41086a200141c8016a41086a290300370300200141d8006a41106a200141c8016a41106a290300370300200141d8006a41186a200141c8016a41186a290300370300200120012903c80137035802402002450d00200910290b412010272208450d0220082001290308370000200841186a2204200141086a41186a290300370000200841106a2202200141086a41106a290300370000200841086a2209200141086a41086a290300370000412010272203450d0320032008290000370000200341186a2004290000370000200341106a2002290000370000200341086a200929000037000020081029200141f8006a2003ad4280808080800484101a108b0220031029024020012802782204450d0020014180016a2802002102200128027c210b41002108200141003a00e801034020022008460d03200141c8016a20086a200420086a2d00003a00002001200841016a22033a00e8012003210820034120470d000b20014188016a41086a200141c8016a41086a2203290300220737030020014188016a41106a200141c8016a41106a2202290300220537030020014188016a41186a200141c8016a41186a2209290300220c370300200120012903c80122113703880120032007370300200220053703002009200c370300200120113703c801200141a8016a41026a220d20014185016a41026a2d00003a0000200120012f0085013b01a8010240200a2010470d00200141286a201041011096012001280228210f2001280230210a0b200f200a41246c6a220841003a0000200820012903c80137000120092903002107200229030021052003290300210c200820012f01a8013b0021200841236a200d2d00003a0000200841096a200c370000200841116a2005370000200841196a20073700002001200a41016a360230200b450d00200410290b200020012903083700102000200636020020002001290358370030200041286a200141086a41186a290300370000200041206a200141086a41106a290300370000200041186a200141086a41086a290300370000200041386a200141d8006a41086a290300370000200041c0006a200141d8006a41106a290300370000200041c8006a200141d8006a41186a290300370000200041e8006a200141386a41186a290300370000200041e0006a200141386a41106a290300370000200041d8006a200141386a41086a290300370000200020012903383700502000410c6a200141286a41086a28020036020020002001290328370204200141f0016a24000f0b0240200841ff0171450d00200141003a00e8010b41ebb6cb00412c200141c8016a418cf7ca004198b7cb00103a000b0240200841ff0171450d00200141003a00e8010b41ebb6cb00412c200141c8016a418cf7ca0041a8b7cb00103a000b1039000b1030000b8f0201027f20014180feff07714108762102024002402001410171450d00411f210341919bcc00210102400240200241ff01710e03000103000b41c100210341d09acc0021010c020b41c1002103418f9acc0021010c010b411f210341f099cc002101024002400240024002400240024002400240200241ff01710e0a00060102030405090708000b4120210341d099cc0021010c080b4127210341f098cc0021010c070b4117210341d998cc0021010c060b41ba98cc0021010c050b41262103419498cc0021010c040b412b210341e997cc0021010c030b41392103419799cc0021010c020b413b210341ae97cc0021010c010b41d100210341dd96cc0021010b20002003360204200020013602000bba0201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210420034120710d012004ad2001104621000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141b88ac0004102200220006a4180016a410020006b104921000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141b88ac0004102200220006a4180016a410020006b104921000b20024180016a240020000f0b200441800141a88ac000104c000b200441800141a88ac000104c000bb10301037f23004180026b22022400024002402001450d00200220003602000c010b20024180a6cc003602000b20022001360204200241f8006a200210f8020240200228027c450d00200241086a200241f8006a41f00010e4071a200241086a10fa02200228020c21030240200241086a410c6a2802002201450d00200141246c21002003210103400240024020012d0000220441044b0d0002400240024020040e050400010204040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b0240200241106a2802002201450d00200141246c450d00200310290b20024180026a240042010f0b200241f4016a41043602002002411c6a41023602002002420237020c200241a0d1c200360208200241043602ec01200241e8d1c2003602e801200241003602fc0120024180a6cc003602f8012002200241e8016a3602182002200241f8016a3602f001200241086a41b0d1c2001040000bd40402087f017e230041106b22022400200210850302400240024002402002280208220341046a2204417f4c0d0020022802002105024002400240024002400240024002402004450d00200410272206450d09200341c000490d04200341808001490d052003418080808004490d0620040d010b41012104410110272206450d0a200641033a0000410521070c010b200641033a000002402004417f6a4104490d00200421070c020b200441017422084105200841054b1b22074100480d0820042007460d010b200620042007102b2206450d080b20062003360001410521080c030b024020040d0041012104410110272206450d070b200620034102743a000041012108200421070c020b02400240200441014d0d00200421070c010b200441017422084102200841024b1b2107024020040d002007102722060d010c070b20042007460d00200620042007102b2206450d060b41022108200620034102744101723b00000c010b02400240200441034d0d00200421070c010b200441017422084104200841044b1b22074100480d04024020040d00200710272206450d060c010b20042007460d00200620042007102b2206450d050b20062003410274410272360000410421080b0240200720086b20034f0d00200820036a22042008490d03200741017422092004200920044b1b22044100480d0320072004460d00200620072004102b2206450d040b200620086a2005200310e4071a200820036aad4220862006ad84210a02402002280204450d00200228020010290b200241106a2400200a0f0b1038000b1039000b1032000b1030000b9c38010f7f230041d0006b2201240020014100360238200142043703300240410810272202450d0020024115360204200241e7acc700360200200141306a41004101108d01200128023020012802384103746a20022902003702002001200128023841016a36023820021029410810272202450d00200241103602042002418ae4ca00360200200141306a20012802384101108d01200128023020012802384103746a20022902003702002001200128023841016a36023820021029410810272202450d002002410e360204200241a4e4ca00360200200141306a20012802384101108d01200128023020012802384103746a20022902003702002001200128023841016a36023820021029410810272202450d002002410c360204200241b2e4ca00360200200141306a20012802384101108d01200128023020012802384103746a20022902003702002001200128023841016a36023820021029410810272202450d0020024108360204200241f7e3ca00360200200141306a20012802384101108d01200128023020012802384103746a20022902003702002001200128023841016a36023820021029410810272202450d002002410a3602042002419ae4ca00360200200141306a20012802384101108d01200128023020012802384103746a20022902003702002001200128023841016a36023820021029410810272202450d002002410b360204200241ffe3ca00360200200141306a20012802384101108d01200128023020012802384103746a20022902003702002001200128023841016a36023820021029410810272202450d0020024118360204200241af9fc800360200200141306a20012802384101108d01200128023020012802384103746a20022902003702002001200128023841016a36023820021029410810272202450d0020024116360204200241fdd3c800360200200141306a20012802384101108d01200128023020012802384103746a20022902003702002001200128023841016a36023820021029410810272202450d0020024119360204200241bfb0c700360200200141306a20012802384101108d01200128023020012802384103746a20022902003702002001200128023841016a36023820021029410810272202450d002002411a360204200241f49ec400360200200141306a20012802384101108d01200128023020012802384103746a20022902003702002001200128023841016a36023820021029410810272202450d0020024112360204200241afebc300360200200141306a20012802384101108d01200128023020012802384103746a200229020037020020012001280238220341016a22043602382002102920012802342105200128023021062001410036023820014204370330200141306a410020044103742202410375109d0120012802382107024020042003490d00200620026a210820012802302007410c6c6a210220062104034020042802002203450d01200241086a200441046a280200360200200241046a2003360200200241003602002002410c6a2102200741016a2107200441086a22042008470d000b0b200120073602380240200541ffffffff0171450d00200610290b200128023421092001280230210a2001410036022820014201370320410410272202450d002001410436022420012002360220200241edcad18b063600002001410436022820012802202102024020012802244104470d00200241044108102b2202450d0120014108360224200120023602200b2002410b3a000420014105360228411f200141206a107141b4a4c500210b02400340200b2802042105200b2802082203200141206a10710240024020012802242206200128022822086b2003490d0020012802202104200621020c010b200820036a22022008490d02200641017422042002200420024b1b22024100480d020240024020060d00024020020d00410121040c020b2002102722040d010c050b2001280220210420062002460d00200420062002102b2204450d040b20012002360224200120043602200b200420086a2005200310e4071a2001200820036a220336022802400240200b28020c4102470d000240024020022003460d00200321020c010b200241016a22032002490d04200241017422082003200820034b1b22034100480d040240024020020d0041002102024020030d00410121040c020b200310272204450d070c010b20022003460d00200420022003102b2204450d060b20012003360224200120043602200b200420026a41003a00002001200241016a22023602280c010b0240024020022003460d00200321020c010b200241016a22032002490d03200241017422082003200820034b1b22034100480d030240024020020d0041002102024020030d00410121040c020b200310272204450d060c010b20022003460d00200420022003102b2204450d050b20012003360224200120043602200b200420026a41013a00002001200241016a36022802400240200b28020c4101470d00200b2802142106200b2802182202200141206a10710240024020012802242208200128022822046b2002490d00200128022021030c010b200420026a22032004490d05200841017422052003200520034b1b22054100480d050240024020080d00024020050d00410121030c020b200510272203450d080c010b2001280220210320082005460d00200320082005102b2203450d070b20012005360224200120033602200b200320046a2006200210e4071a2001200420026a360228200b28022021020240200b28021c4101470d002002200b280228200141206a10740c020b2002200b41246a280200200141206a10740c010b200141306a200b2802101103002001280234210620012802382202200141206a10710240024020012802242208200128022822046b2002490d00200128022021030c010b200420026a22032004490d04200841017422052003200520034b1b22054100480d040240024020080d00024020050d00410121030c020b200510272203450d070c010b2001280220210320082005460d00200320082005102b2203450d060b20012005360224200120033602200b200320046a2006200210e4071a2001200420026a360228200128024021030240200128023c4101460d0020032001280244200141206a10740c010b200320012802482202200141206a107402402002450d00200241d8006c21084100210403400240200320046a220241346a280200450d002002413c6a280200450d00200241386a28020010290b0240200241c4006a280200450d00200241cc006a28020041ffffffff0171450d00200241c8006a28020010290b2008200441d8006a2204470d000b0b20012802442202450d00200241d8006c450d00200310290b200128022821020b2001280224210402400240200b28022c4102470d000240024020042002460d00200128022021040c010b200241016a22042002490d04200241017422032004200320044b1b22034100480d040240024020020d0041002102024020030d00410121040c020b200310272204450d070c010b2001280220210420022003460d00200420022003102b2204450d060b20012003360224200120043602200b200420026a41003a00002001200241016a22023602280c010b0240024020042002460d00200128022021040c010b200241016a22042002490d03200241017422032004200320044b1b22034100480d030240024020020d0041002102024020030d00410121040c020b200310272204450d060c010b2001280220210420022003460d00200420022003102b2204450d050b20012003360224200120043602200b200420026a41013a00002001200241016a36022802400240200b28022c4101470d00200b2802302104200b2802382202200141206a10712002450d012002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10710240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d062006410174220d2008200d20084b1b220d4100480d060240024020060d000240200d0d00410121080c020b200d10272208450d090c010b200128022021082006200d460d0020082006200d102b2208450d080b2001200d360224200120083602200b200820036a200c200410e4071a2001200320046a360228200241706a200141206a10702002200141206a10732002412c6a2102200541546a22050d000c020b0b200141186a200b28023011030020012802182104200128021c2202200141206a10712002450d002002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10710240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d052006410174220d2008200d20084b1b220d4100480d050240024020060d000240200d0d00410121080c020b200d10272208450d080c010b200128022021082006200d460d0020082006200d102b2208450d070b2001200d360224200120083602200b200820036a200c200410e4071a2001200320046a360228200241706a200141206a10702002200141206a10732002412c6a2102200541546a22050d000b0b200128022821020b2001280224210402400240200b28023c4102470d000240024020042002460d00200128022021040c010b200241016a22042002490d04200241017422032004200320044b1b22034100480d040240024020020d0041002102024020030d00410121040c020b200310272204450d070c010b2001280220210420022003460d00200420022003102b2204450d060b20012003360224200120043602200b200420026a41003a00002001200241016a3602280c010b0240024020042002460d00200128022021040c010b200241016a22042002490d03200241017422032004200320044b1b22034100480d030240024020020d0041002102024020030d00410121040c020b200310272204450d060c010b2001280220210420022003460d00200420022003102b2204450d050b20012003360224200120043602200b200420026a41013a00002001200241016a3602280240200b28023c4101470d00200b2802402104200b2802482202200141206a10712002450d012002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10710240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d052006410174220d2008200d20084b1b220d4100480d050240024020060d000240200d0d00410121080c020b200d10272208450d080c010b200128022021082006200d460d0020082006200d102b2208450d070b2001200d360224200120083602200b200820036a200c200410e4071a2001200320046a360228200241706a200141206a10732002200141206a10732002412c6a2102200541546a22050d000c020b0b200141106a200b2802401103002001280210210420012802142202200141206a10712002450d002002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10710240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d042006410174220d2008200d20084b1b220d4100480d040240024020060d000240200d0d00410121080c020b200d10272208450d070c010b200128022021082006200d460d0020082006200d102b2208450d060b2001200d360224200120083602200b200820036a200c200410e4071a2001200320046a360228200241706a200141206a10732002200141206a10732002412c6a2102200541546a22050d000b0b02400240200b28024c4101470d00200b280250210e200b2802582202200141206a10712002450d01200241386c210f410021080340200e20086a220241046a280200210c200241086a2802002204200141206a10710240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d052005410174220d2006200d20064b1b220d4100480d050240024020050d000240200d0d00410121060c020b200d10272206450d080c010b200128022021062005200d460d0020062005200d102b2206450d070b2001200d360224200120063602200b200620036a200c200410e4071a2001200320046a360228200241106a280200210c200241146a2802002204200141206a10710240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d052005410174220d2006200d20064b1b220d4100480d050240024020050d000240200d0d00410121060c020b200d10272206450d080c010b200128022021062005200d460d0020062005200d102b2206450d070b2001200d360224200120063602200b200620036a200c200410e4071a2001200320046a36022802400240200241186a2802004101470d002002411c6a280200210c200241246a2802002204200141206a10710240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d072005410174220d2006200d20064b1b220d4100480d070240024020050d000240200d0d00410121060c020b200d10272206450d0a0c010b200128022021062005200d460d0020062005200d102b2206450d090b2001200d360224200120063602200b200620036a200c200410e4071a2001200320046a3602280c010b200141306a2002411c6a280200200241206a28020028020c1102002001280230210520012802382204200141206a1071024002402001280224220c200128022822036b2004490d00200128022021060c010b200320046a22062003490d06200c410174220d2006200d20064b1b220d4100480d0602400240200c0d000240200d0d00410121060c020b200d10272206450d090c010b20012802202106200c200d460d002006200c200d102b2206450d080b2001200d360224200120063602200b200620036a2005200410e4071a2001200320046a3602282001280234450d00200510290b200241286a200141206a1073200f200841386a2208470d000c020b0b200141086a200b2802501103002001280208210e200128020c2202200141206a10712002450d00200241386c210f410021080340200e20086a220241046a280200210c200241086a2802002204200141206a10710240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d042005410174220d2006200d20064b1b220d4100480d040240024020050d000240200d0d00410121060c020b200d10272206450d070c010b200128022021062005200d460d0020062005200d102b2206450d060b2001200d360224200120063602200b200620036a200c200410e4071a2001200320046a360228200241106a280200210c200241146a2802002204200141206a10710240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d042005410174220d2006200d20064b1b220d4100480d040240024020050d000240200d0d00410121060c020b200d10272206450d070c010b200128022021062005200d460d0020062005200d102b2206450d060b2001200d360224200120063602200b200620036a200c200410e4071a2001200320046a36022802400240200241186a2802004101470d002002411c6a280200210c200241246a2802002204200141206a10710240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d062005410174220d2006200d20064b1b220d4100480d060240024020050d000240200d0d00410121060c020b200d10272206450d090c010b200128022021062005200d460d0020062005200d102b2206450d080b2001200d360224200120063602200b200620036a200c200410e4071a2001200320046a3602280c010b200141306a2002411c6a280200200241206a28020028020c1102002001280230210520012802382204200141206a1071024002402001280224220c200128022822036b2004490d00200128022021060c010b200320046a22062003490d05200c410174220d2006200d20064b1b220d4100480d0502400240200c0d000240200d0d00410121060c020b200d10272206450d080c010b20012802202106200c200d460d002006200c200d102b2206450d070b2001200d360224200120063602200b200620036a2005200410e4071a2001200320046a3602282001280234450d00200510290b200241286a200141206a1073200f200841386a2208470d000b0b02400240200b28025c4101470d00200b2802602104200b2802682202200141206a10712002450d012002411c6c21052004410c6a21020340200241786a280200210c2002417c6a2802002204200141206a10710240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d052006410174220d2008200d20084b1b220d4100480d050240024020060d000240200d0d00410121080c020b200d10272208450d080c010b200128022021082006200d460d0020082006200d102b2208450d070b2001200d360224200120083602200b200820036a200c200410e4071a2001200320046a3602282002200141206a10732002411c6a2102200541646a22050d000c020b0b2001200b2802601103002001280200210420012802042202200141206a10712002450d002002411c6c21052004410c6a21020340200241786a280200210c2002417c6a2802002204200141206a10710240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d042006410174220d2008200d20084b1b220d4100480d040240024020060d000240200d0d00410121080c020b200d10272208450d070c010b200128022021082006200d460d0020082006200d102b2208450d060b2001200d360224200120083602200b200820036a200c200410e4071a2001200320046a3602282002200141206a10732002411c6a2102200541646a22050d000b0b200b41ec006a220b41c8bec500470d000b02400240200128022420012802282202460d00200128022021040c010b200241016a22042002490d01200241017422032004200320044b1b22034100480d010240024020020d0041002102024020030d00410121040c020b200310272204450d040c010b2001280220210420022003460d00200420022003102b2204450d030b20012003360224200120043602200b200420026a41043a00002001200241016a3602282007200141206a107102402007450d002007410c6c2105200a41086a210403402004417c6a280200210c20042802002202200141206a10710240024020012802242206200128022822036b2002490d00200128022021080c010b200320026a22082003490d032006410174220d2008200d20084b1b220d4100480d030240024020060d000240200d0d00410121080c020b200d10272208450d060c010b200128022021082006200d460d0020082006200d102b2208450d050b2001200d360224200120083602200b200820036a200c200210e4071a2001200320026a3602282004410c6a2104200541746a22050d000b0b20002001290320370200200041086a200141206a41086a28020036020002402009450d002009410c6c450d00200a10290b200141d0006a24000f0b1032000b1030000bbe0601057f230041800b6b22022400024002402001450d00200220003602080c010b20024180a6cc003602080b2002200136020c200241b0076a200241086a10870302400240024002402002290398084203510d00200241206a200241b0076a41c00310e4071a200241e0036a200241206a41c00310e4071a2002200241e0036a3602b007200241a0076a200241b0076a10bd0220022802a8072101200241b0076a200241e0036a41c00310e4071a200241f80a6a20022802a807360200200220022903a0073703f00a200241106a200241b0076a2001200241f00a6a10fd024101410220022d001022034101461b220010272201450d01200241003602b807200220003602b407200220013602b0070240024020034101470d00200141013a0000200241013602b807200241106a410172200241b0076a10880320022802b807210020022802b00721010c010b200141003a0000200241013602b8070240024020022d001422044104460d00200141013a000141022103200241023602b80702400240024002400240024020040e0400010203000b410021040c030b410121040c020b200241023a00e003410221040c020b200241033a00e00341042100200141024104102b2201450d07200141033a0002200220013602b00720024284808080303702b407200220022d001522033a00e003024041010d0041062100200141034106102b2201450d08200241063602b407200220013602b0070b200120033a000341042103200241043602b80720022d001621040b200220043a00e0030b024020002003470d0041000d070240200020004101742205200041016a2206200520064b1b2205460d00200120002005102b2201450d070b200220053602b407200220013602b0070b200120036a20043a0000200341017221000c010b200141003a0001410221000b200220003602b8070b200241800b6a24002000ad4220862001ad840f0b2002412c6a4104360200200241f4036a4102360200200242023702e403200241a0d1c2003602e0032002410436022420024180d2c2003602202002410036021420024180a6cc003602102002200241206a3602f0032002200241106a360228200241e0036a41b0d1c2001040000b1039000b1030000b1032000b8b1304057f017e047f047e23004180086b22022400200241206a200110c801024002400240024002400240024020022802200d0020012802042203450d01200128020022042d0000210520012003417f6a3602042001200441016a360200200541ff00714104470d024100210620054118744118754100480d03420221070c040b200042033703680c050b200042033703680c040b200042033703680c030b200241003a00c8042003417f6a2108200321050240024002400240024002400240024002400240034020082006460d01200241a8046a20066a200420066a220941016a2d00003a000020012005417e6a3602042001200941026a3602002002200641016a22093a00c8042005417f6a21052009210620094120470d000b200241d8066a41186a200241a8046a41186a290300370300200241d8066a41106a200241a8046a41106a290300370300200241d8066a41086a200241a8046a41086a290300370300200220022903a8043703d8062003417f6a2009460d08200420096a220441016a2d0000210620012005417e6a3602042001200441026a360200200641024b0d0820060e03010203010b200641ff0171450d07200241003a00c8040c070b41002106200241003a00e8042003417e6a210a200920036b41026a210b200320096b417d6a210902400340200b20066a450d01200241a8046a20066a200420066a220841026a2d00003a0000200120093602042001200841036a3602002002200641016a22083a00e8042009417f6a2109200a417f6a210a20082106200841c000470d000b200241c0076a41386a200241a8046a41386a2903002207370300200241c0076a41306a200241a8046a41306a290300220c370300200241c0076a41286a200241a8046a41286a290300220d370300200241c0076a41206a200241a8046a41206a290300220e370300200241c0076a41186a200241a8046a41186a290300220f37030020024180026a41086a200241a8046a41086a29030037030020024180026a41106a200241a8046a41106a29030037030020024180026a41186a200f37030020024180026a41206a200e37030020024180026a41286a200d37030020024180026a41306a200c37030020024180026a41386a2007370300200220022903a80437038002200520086b417e6a2105200420086a41026a2109410021060c030b200641ff0171450d06200241003a00e804420221070c070b41002106200241003a00e8042003417e6a210a200920036b41026a210b200320096b417d6a210902400340200b20066a450d01200241a8046a20066a200420066a220841026a2d00003a0000200120093602042001200841036a3602002002200641016a22083a00e8042009417f6a2109200a417f6a210a20082106200841c000470d000b200241c0076a41386a200241a8046a41386a2903002207370300200241c0076a41306a200241a8046a41306a290300220c370300200241c0076a41286a200241a8046a41286a290300220d370300200241c0076a41206a200241a8046a41206a290300220e370300200241c0076a41186a200241a8046a41186a290300220f37030020024180026a41086a200241a8046a41086a29030037030020024180026a41106a200241a8046a41106a29030037030020024180026a41186a200f37030020024180026a41206a200e37030020024180026a41286a200d37030020024180026a41306a200c37030020024180026a41386a2007370300200220022903a80437038002200520086b417e6a2105200420086a41026a2109410121060c020b200641ff0171450d05200241003a00e804420221070c060b41002106200241003a00e9042003417e6a210a200920036b41026a210b200320096b417d6a21090340200b20066a450d02200241a8046a20066a200420066a220841026a2d00003a0000200120093602042001200841036a3602002002200641016a22083a00e9042009417f6a2109200a417f6a210a20082106200841c100470d000b20024180026a200241a8046a41c10010e4071a200520086b417e6a210541022106200420086a41026a21090b200241ff066a20024180026a41c10010e4071a2005450d032009310000210d20012005417f6a22043602042001200941016a360200200d50450d01420021070c020b200641ff0171450d02200241003a00e904420221070c030b2004450d012009310001210e20012005417e6a3602042001200941026a3602004202200d420f8386220c4204540d0142012107200e420886200d84420488200c420c88220d4201200d4201561b7e220d200c5a0d010b200241186a200110c80120022802180d00200228021c2105200220011084022002290300a70d00200241106a290300210f2002290308210e200241c0076a41186a200241d8066a41186a290300370300200241c0076a41106a200241d8066a41106a290300370300200241c0076a41086a200241d8066a41086a290300370300200220022903d8063703c007200241a8046a200241ff066a41c10010e4071a200241f8016a41046a200241d2066a41046a2f01003b0100200220022801d2063602f8010c010b420221070b200241d8016a41186a2209200241c0076a41186a290300370300200241d8016a41106a2204200241c0076a41106a290300370300200241d8016a41086a2208200241c0076a41086a290300370300200220022903c0073703d80120024197016a200241a8046a41c10010e4071a20024190016a41046a2203200241f8016a41046a2f01003b0100200220022802f8013602900120074202510d01200241f0006a41186a2009290300370300200241f0006a41106a2004290300370300200241f0006a41086a2008290300370300200220022903d8013703702002412f6a20024197016a41c10010e4071a200241286a41046a20032f01003b010020022002280290013602280b200241a8046a200110e40320022802a804210120024180026a200241a8046a41047241a40210e4071a02402001411c460d0020002002290370370300200020063a0020200041186a200241f0006a41186a290300370300200041106a200241f0006a41106a290300370300200041086a200241f0006a41086a290300370300200041216a2002412f6a41c10010e4071a200041e6006a200241286a41046a2f01003b01002000200228022836016220004188016a200f37030020004180016a200e37030020004198016a200136020020004190016a2005360200200041f8006a200d3703002000200c370370200020073703682000419c016a20024180026a41a40210e4071a0c020b200042033703680c010b200042033703680b20024180086a24000bb30301027f230041106b220224000240024020002d00004101460d00200241003a000e20012002410e6a4101107220002d0001220341094b0d010240024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a000f2002410f6a21000c090b200241013a000f2002410f6a21000c080b200241023a000f2002410f6a21000c070b200241033a000f2002410f6a21000c060b200241043a000f2002410f6a21000c050b200241053a000f2002410f6a21000c040b200241063a000f2002410f6a21000c030b200241073a000f20012002410f6a410110722002200041026a2d00003a000f2002410f6a21000c020b200241083a000f2002410f6a21000c010b200241093a000f2002410f6a21000b20012000410110720c010b200241013a000e20012002410e6a4101107220002d0001220341024b0d0002400240024020030e03000102000b200241003a000e20012002410e6a410110720c020b200241013a000e20012002410e6a410110720c010b200241023a000e20012002410e6a410110722002200041026a2d00003a000e20012002410e6a410110720b200241106a24000bcb1305047f017e017f017e0b7f23004180026b2202240010fe02200241106a41186a22034200370300200241106a41106a22044200370300200241106a41086a220542003703002002420037031041b3e6ca00ad4280808080e0008422061001220729000021082005200741086a290000370300200220083703102007102941c9e6ca00ad4280808080e00084100122072900002108200241b0016a41086a2209200741086a290000370300200220083703b00120071029200420022903b0012208370300200241d0016a41086a220a2005290300370300200241d0016a41106a220b2008370300200241d0016a41186a220c2009290300370300200220022903103703d001200241086a200241d0016a412010fc0141002107200228020c410020022802081b10ff022003420037030020044200370300200542003703002002420037031020061001220d2900002108200241f0016a41086a220e200d41086a290000370300200220083703f001200d10292005200e290300370300200220022903f001370310419ca0cb00ad4280808080e001841001220d2900002108200e200d41086a290000370300200220083703f001200d1029200420022903f0012208370300200a2005290300370300200b2008370300200c200e290300370300200220022903103703d0012002200241d0016a412010fc012002280204210d2002280200210f200241003602b801200242043703b001200241b0016a4100200d4100200f1b2210109d0120022802b801211102402010450d0020022802b0012011410c6c6a210d0340200241d0016a2007108a03200241106a20022802d001221220022802d8012213108b0302402002280210220f450d002013ad4220862012ad8410040b200741016a210720022902144200200f1b2108200f4101200f1b210f024020022802d401450d00201210290b200d200f360200200d41046a2008370200200d410c6a210d20102007470d000b201120106a21110b20024180016a41086a2011360200200220022903b001220837038001200520113602002002200837031020024190016a200241106a10fc02200241b0016a41186a20024190016a41186a290300370300200241b0016a41106a20024190016a41106a290300370300200920024190016a41086a29030037030020022002290390013703b001200342003703002004420037030020054200370300200242003703102006100122072900002108200e200741086a290000370300200220083703f001200710292005200e290300370300200220022903f00137031041d9e6ca00ad4280808080e00184100122072900002108200e200741086a290000370300200220083703f00120071029200420022903f001370000200441086a200e290300370000200a2005290300370300200b2004290300370300200c2003290300370300200220022903103703d001024002400240412010272207450d00200720022903b001370000200741186a200241b0016a41186a290300370000200741106a200241b0016a41106a290300370000200741086a200241b0016a41086a290300370000200241d0016aad42808080808004842007ad4280808080800484100320071029200241106a108003200241003602b801200242013703b001412010272207450d0020072002290320370000200741186a200241386a290300370000200741106a200241106a41206a290300370000200741086a200241106a41186a29030037000041201027220d450d02200241203602b4012002200d3602b001200d2007290000370000200d41086a200741086a290000370000200d41106a200741106a290000370000200d41186a200741186a290000370000200241203602b80120071029200241106a200241b0016a10e601412010272207450d0020072002290340370000200741186a200241d8006a290300370000200741106a200241d0006a290300370000200741086a200241c8006a2903003700000240024020022802b401221020022802b80122136b4120490d00201341206a210d20022802b001210f201021120c010b201341206a220d2013490d022010410174220f200d200f200d4b1b22124100480d020240024020100d00024020120d004101210f0c020b20121027220f0d010c050b20022802b001210f20102012460d00200f20102012102b220f450d040b200220123602b4012002200f3602b0010b200f20136a22132007290000370000201341186a200741186a290000370000201341106a200741106a290000370000201341086a200741086a2900003700002002200d3602b80120071029412010272207450d0020072002290360370000200741186a200241f8006a290300370000200741106a200241f0006a290300370000200741086a200241e8006a29030037000002402012200d6b411f4b0d00200d41206a2213200d490d02201241017422102013201020134b1b22134100480d020240024020120d00024020130d004101210f0c020b20131027220f450d050c010b20122013460d00200f20122013102b220f450d040b200220133602b4012002200f3602b0010b200f200d6a220f2007290000370000200f41186a200741186a290000370000200f41106a200741106a290000370000200f41086a200741086a2900003700002002200d41206a3602b80120071029200228021421032002411c6a2802002211200241b0016a10710240024020110d0020022802b801210d20022802b00121050c010b201141246c210e20022802b401210f20022802b8012107200321130340200241d0016a201310bc0220022802d001210402400240200f20076b20022802d8012210490d00200720106a210d20022802b0012105200f21120c010b200720106a220d2007490d04200f4101742212200d2012200d4b1b22124100480d0402400240200f0d00024020120d00410121050c020b201210272205450d070c010b20022802b0012105200f2012460d002005200f2012102b2205450d060b200220123602b401200220053602b0010b200520076a2004201010e4071a2002200d3602b801024020022802d401450d00200410290b201341246a21132012210f200d2107200e415c6a220e0d000b0b200dad42208621082005ad210602402011450d00201141246c210d2003210703400240024020072d0000220f41044b0d00024002400240200f0e050400010204040b2007410c6a280200450d03200741086a28020010290c030b2007410c6a280200450d02200741086a28020010290c020b2007410c6a280200450d01200741086a28020010290c010b200741086a280200450d00200741046a28020010290b200741246a2107200d415c6a220d0d000b0b200820068421080240200241186a2802002207450d00200741246c450d00200310290b20024180026a240020080f0b1039000b1032000b1030000bfc0403027f017e057f230041d0006b2202240041b3e6ca00ad4280808080e00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941b0a1cb00ad4280808080d00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000ba30303037f017e027f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b020240024002400240200328021022010d00200041003602000c010b200328021421022003200341186a280200360224200320013602202003200341206a10c80102400240024020032802000d002003280224220420032802042205490d002005417f4c0d040240024020050d0042002106410121070c010b2005102d2207450d06200720032802202208200510e4071a2003200420056b3602242003200820056a3602202005ad21060b20070d010b20034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b200041003602000c010b200020062005ad42208684370204200020073602000b2002450d00200110290b200341e0006a24000f0b1038000b1039000bc51405017f017e027f017e097f23004190066b22022400024002402001450d00200220003602200c010b20024180a6cc003602200b20022001360224200241186a200241206a10c8010240024020022802180d00200228021c21012002200241206a36028005200241003a0048200241003602f802200241003602f0022002200136025c200241003602582002200241c8006a360264200220024180056a360260200241d8006a200241f0026a108d03200241a8056a41086a20022802f8022201360200200220022903f00222033703a80520022d00482100200241d8006a41086a22042001360200200220033703582000450d01200241d8006a108e030b200241fc026a4104360200200241ec006a41023602002002420237025c200241a0d1c200360258200241043602f40220024198d2c2003602f002200241003602ac0520024180a6cc003602a8052002200241f0026a3602682002200241a8056a3602f802200241d8006a41b0d1c2001040000b200241286a41086a20042802002201360200200220022903582203370328200241386a41086a2001360200200220033703382002410036025020024208370348200241d8006a200241386a1089010240024002400240024020022802584101460d00200241d8006a41086a22012903002103200241d8006a41186a4200370300200241d8006a41106a22054200370300200142003703002002420037035841ccbec500ad42808080809001841001220029000021062001200041086a290000370300200220063703582000102941aafac400ad42808080803084100122002900002106200241a8056a41086a2204200041086a290000370300200220063703a80520001029200520022903a8052206370300200241f0026a41086a2001290300370300200241f0026a41106a2006370300200241f0026a41186a2004290300370300200220022903583703f002200241086a200241f0026a10b5012002280208210020022903102106200241c8006a410010a401200228024822072002280250220441c0036c6a220141033602980120014202370368200141a0016a2003200642b8177c42b81720001b220620032006561b3703002002200441016a22083602500240024020022802382209450d00200228023c210a2009210b02400340200b41086a2100200b2f0106220c4103742101410021040240024003402001450d014193c1c2002000410810e707220d450d02200141786a2101200441016a2104200041086a2100200d417f4a0d000b2004417f6a210c0b200a450d02200a417f6a210a200b200c4102746a41e4016a280200210b0c010b0b200b41e0006a2004410c6c6a22012802084104490d002001280200280000210d200241d8006a41186a22044200370300200241d8006a41106a220b4200370300200241d8006a41086a220142003703002002420037035841eea1c800ad4280808080f001841001220029000021032001200041086a290000370300200220033703582000102941fda1c800ad4280808080b00184100122002900002103200241a8056a41086a220a200041086a290000370300200220033703a80520001029200520022903a805370000200541086a200a290300370000200241f0026a41086a2001290300370300200241f0026a41106a200b290300370300200241f0026a41186a2004290300370300200220022903583703f002200241d8006a200241f0026a108f0320022802582201410420011b2104410021000240200229025c420020011b2203422088a72201450d00200141027420046a417c6a2201450d002001280200200d4721000b0240200342ffffffff0383500d00200410290b2000450d0002402008200228024c470d00200241c8006a200810a40120022802482107200228025021080b2007200841c0036c6a200241f0026a41e80010e407220142023703682001419c016a200d3602002001410a36029801200120022903a805370370200141f8006a200241b0056a29030037030020014180016a200241b8056a29030037030020014188016a200241c0056a29030037030020014190016a200241c8056a290300370300200141a8016a200241d8006a41940210e4071a2002200841016a22083602500b2009450d00200228023c210b0340200941086a210020092f0106220a4103742101410021040240024003402001450d0141feacc7002000410810e707220d450d02200141786a2101200441016a2104200041086a2100200d417f4a0d000b2004417f6a210a0b200b450d02200b417f6a210b2009200a4102746a41e4016a28020021090c010b0b200220092004410c6c6a220141e8006a2802003602ac052002200141e0006a2802003602a805200241d8006a200241a8056a109003200228025822000d012002412936025c200241d78fcc003602584186adc7004125200241d8006a419cbbc70041acadc700103a000b41bcadc700412a41acadc7001057000b200241d8006a41086a2802002104200228025c210d200241d8006a200241f0026a41900210e4071a02402008200228024c470d00200241c8006a200810a40120022802482107200228025021080b2007200841c0036c22096a200241a8056a41e80010e407220142023703682001200229038005370370200141f8006a20024180056a41086a29030037030020014180016a20024190056a29030037030020014188016a20024198056a29030037030020014190016a200241a0056a290300370300200141a8016a2004360200200141a4016a200d360200200141a0016a2000360200200142948080801037039801200141ac016a200241d8006a41900210e4071a200228024c210e200241386a108e03200941c4036a2201417f4c0d01200110272200450d02200241003602f802200220013602f402200220003602f002200841016a220f200241f0026a107102400240200f0d0020022802f802210020022802f002210a0c010b200841c0036c41c0036a210520022802f402210420022802f8022101200721090340200220093602a805200241d8006a200241a8056a10bd022002280258210c02400240200420016b2002280260220b490d002001200b6a210020022802f002210a2004210d0c010b2001200b6a22002001490d062004410174220d2000200d20004b1b220d4100480d060240024020040d000240200d0d004101210a0c020b200d1027220a0d010c090b20022802f002210a2004200d460d00200a2004200d102b220a450d080b2002200d3602f4022002200a3602f0020b200a20016a200c200b10e4071a200220003602f8020240200228025c450d00200c10290b200941c0036a2109200d210420002101200541c07c6a22050d000b0b2000ad4220862103200aad21060240200f450d0020074198016a2101200841c0036c41c0036a21000340200110c201200141c0036a2101200041c07c6a22000d000b0b200320068421030240200e450d00200e41c0036c450d00200710290b20024190066a240020030f0b200241f8026a200241e4006a2902003703002002200229025c3703f00241c0fac4004128200241f0026a41b0fac40041e8fac400103a000b1038000b1039000b1032000b1030000bd40505067f017e047f017e027f23004180026b22022400024002400240024002402000280200220320002802044f0d00200028020c2104200141086a2105200241a0016a4102722106024003402000200341016a360200200241186a2000280208280200220710ab0420022d00184101460d0120022900192108200241086a200710c80120022802080d012007280204200228020c2203490d012003417f4c0d0302400240024020030d0041002107410121090c010b2003102d2209450d0820072802042003490d0120092007280200200310e4071a2007280204220a2003490d062007200a20036b3602042007200728020020036a360200200321070b20022008370310024002402001280200220b450d002001280204210c0c010b2006410041da0010e6071a200241186a410041840110e6071a41e4011027220b450d074100210c200b4100360200200b41046a200241a0016a41dc0010e4071a200b41e0006a200241186a41840110e4071a200141003602042001200b3602000b2003ad4220862007ad84210d024002400340200b41086a2107200b2f0106220e41037421034100210a024003402003450d01200241106a2007410810e707220f450d03200341786a2103200a41016a210a200741086a2107200f417f4a0d000b200a417f6a210e0b0240200c450d00200c417f6a210c200b200e4102746a41e4016a280200210b0c010b0b2002200837022c200220053602282002200e360224200220013602202002200b36021c200241003602182002200d3702a401200220093602a001200241186a200241a0016a1092030c010b200b200a410c6c6a220341e4006a2207280200210a2007200d370200200341e0006a22072802002103200720093602002003450d00200a450d00200310290b200028020022032000280204490d010c030b0b200910290b200441013a00000b20024180026a24000f0b1038000b2003200a41ccafc000104c000b1030000b1039000be60203047f017e017f024020002802002201450d0020002802082102024020002802042200450d00034020012802e40121012000417f6a22000d000b0b02402002450d0041002103024003402001450d01410021040240200320012f0106490d00034002400240200128020022000d0041002103410021000c010b200441016a210420012f010421030b2001102920002101200320002f01064f0d000b200021010b200341016a210020012003410c6c6a220341e4006a2902002105200341e0006a28020021060240024020040d00200021030c010b200120004102746a41e4016a2802002101410021032004417f6a2200450d00034020012802e40121012000417f6a22000d000b0b2006450d022002417f6a210202402005a7450d00200610290b20020d000c020b0b41a79dc800412b41e0f6c4001033000b2001450d0020012802002100200110292000450d00034020002802002101200010292001210020010d000b0b0ba20403047f017e027f230041e0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b0202400240200228021022010d00200041003602000c010b200228021421032002200241186a280200360224200220013602202002200241206a10c8010240024020022802000d002002280224220420022802044102742205490d0002400240024002402005417f4c0d000240024020050d0042002106410121070c010b2005102d2207450d02200720022802202208200510e4071a2002200420056b3602242002200820056a3602202005ad21060b2007450d04024020062005ad422086842206422088a722050d002006a721050c030b024020072005724103710d002006a722054103710d0020054102762204450d032006422288a721080c040b2006a7450d04200710290c040b1038000b1039000b4100210802402005450d00200710290b41002104410421070b41000d002007450d002000200436020420002007360200200041086a20083602000c010b20024100360230200242013703282002410d36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241f4eaca003602482002200241386a360258200241c4006a41a8a3c800200241c8006a10371a200235023042208620023502288410080240200228022c450d00200228022810290b200041003602000b2003450d00200110290b200241e0006a24000bfb390c037f017e227f027e047f017e157f047e017f027e0f7f027e23004180086b22022400200241206a200110c80102400240024002402002280220450d00200041003602000c010b2002280224220320012802044190026e2204200420034b1bad4290027e2205422088a70d022005a72204417f4c0d020240024020040d00410821060c010b200410272206450d020b2002410036023020022006360228200220044190026e36022c024002402003450d004100210741002108034002400240200128020422094104490d002001280200220a280000210b20012009417c6a220c3602042001200a41046a36020041002104200241003a00d8072009417b6a210902400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400340200c2004460d01200241b8076a20046a200a20046a220d41046a2d00003a0000200120093602042001200d41056a3602002002200441016a220d3a00d8072009417f6a2109200d2104200d4120470d000b200241f8046a41086a220e200241b8076a41086a220f290300370300200241f8046a41106a2210200241b8076a41106a2211290300370300200241f8046a41186a2212200241b8076a41186a2213290300370300200220022903b8073703f804200241186a200110c80120022802180d1c2001280204200228021c2209490d1c2009417f4c0d2320090d014100210d410121140c020b200441ff0171450d1b200241003a00d8070c1b0b2009102d2214450d2020012802042009490d0120142001280200200910e4071a200128020422042009490d0c2001200420096b3602042001200128020020096a3602002009210d0b2014450d1941002104200241003a00d8072009ad422086200dad842205422088a721152005a721162001280204210c417f210902400340200c2004460d01200241b8076a20046a2001280200220a2d00003a00002001200c20096a3602042001200a41016a3602002002200441016a220d3a00d8072009417f6a2109200d2104200d4120470d000b20024198056a41186a2217201329030037030020024198056a41106a2218201129030037030020024198056a41086a2219200f290300370300200220022903b8073703980541002104200241003a00f807200d200c6b211a200c200d6b21090340201a20046a450d03200241b8076a20046a200a20046a220d41016a2d00003a000020012009417f6a22093602042001200d41026a3602002002200441016a220d3a00f807200d2104200d41c000470d000b200241f8066a41386a221b200241b8076a41386a221c290300370300200241f8066a41306a221d200241b8076a41306a221e290300370300200241f8066a41286a221f200241b8076a41286a2220290300370300200241f8066a41206a2221200241b8076a41206a2222290300370300200241f8066a41186a221a2013290300370300200241f8066a41106a22232011290300370300200241f8066a41086a2224200f290300370300200220022903b8073703f80641002104200241003a00d807200a200d6a210a03402009450d04200241b8076a20046a200a20046a220d41016a2d00003a000020012009417f6a22093602042001200d41026a3602002002200441016a220d3a00d807200d2104200d4120470d000b200241b8056a41086a2225200f290300370300200241b8056a41106a22262011290300370300200241b8056a41186a22272013290300370300200220022903b8073703b80520094110490d0a200a200d6a220441096a2900002128200441016a29000021292001200941706a3602042001200441116a360200200241b8076a200110f60520022802b8072209450d0a20022902bc0721054100210d200241003a00d8072001280204417f6a210403402004417f460d05200241b8076a200d6a2001280200220c2d00003a0000200120043602042001200c41016a3602002002200d41016a220a3a00d8072004417f6a2104200a210d200a4120470d000b200241f8056a41086a222a200f290300370300200241f8056a41106a222b2011290300370300200241f8056a41186a222c2013290300370300200220022903b8073703f8052004417f460d08200c2d0001210d200120043602042001200c41026a360200200d41014b0d084100212d200d0e020605060b0240200441ff0171450d00200241003a00d8070b2016450d190b201410290c180b0240200441ff0171450d00200241003a00f8070b2016450d17201410290c170b0240200441ff0171450d00200241003a00d8070b2016450d16201410290c160b0240200d41ff0171450d00200241003a00d8070b02402005422088a72204450d002004410474210d2009210403400240200441046a280200450d00200428020010290b200441106a2104200d41706a220d0d000b0b200542ffffffff008350450d040c050b200241106a200110c80120022802100d02200128020420022802142204490d022004417f4c0d1b0240024020040d004100210d4101212d0c010b2004102d222d450d1b20012802042004490d02202d2001280200200410e4071a2001280204220d2004490d082001200d20046b3602042001200128020020046a3602002004210d0b202d450d022004ad422086200dad84212e0b200241d8046a41186a222f202c290300370300200241d8046a41106a2230202b290300370300200241d8046a41086a2231202a290300370300200241b8046a41086a2232200e290300370300200241b8046a41106a22332010290300370300200241b8046a41186a22342012290300370300200220022903f8053703d804200220022903f8043703b80420024198046a41186a2235201729030037030020024198046a41106a2236201829030037030020024198046a41086a22372019290300370300200220022903980537039804200241d8036a41386a2238201b290300370300200241d8036a41306a2239201d290300370300200241d8036a41286a223a201f290300370300200241d8036a41206a223b2021290300370300200241d8036a41186a223c201a290300370300200241d8036a41106a223d2023290300370300200241d8036a41086a223e2024290300370300200220022903f8063703d803200241b8036a41186a223f2027290300370300200241b8036a41106a22402026290300370300200241b8036a41086a22412025290300370300200220022903b8053703b803200241086a200110c8012005422088a721102005a72112202ea721172002280208450d040c110b202d10290b02402005422088a72204450d002004410474210d2009210403400240200441046a280200450d00200428020010290b200441106a2104200d41706a220d0d000b0b200542ffffffff0083500d010b200910290b2016450d0f201410290c0f0b200228020c2242200128020441c1006e2204200420424b1bad42c1007e2205422088a70d152005a72204417f4c0d150240024020040d00410121190c010b200410272219450d150b41002118200241003602a00520022019360298052002200441c1006e220436029c05024002400240024002400240024002402042450d00410021184100214303402001280204220d450d042001280200220c2d000021042001200d417f6a220e3602042001200c41016a3602002004417f6a220441014b0d0402400240024020040e020001000b41002104200241003a00f807200d417e6a210d02400340200e2004460d01200241b8076a20046a200c20046a220a41016a2d00003a00002001200d3602042001200a41026a3602002002200441016a220a3a00f807200d417f6a210d200a2104200a41c000470d000b201b201c2903002205370300201d201e2903002244370300201f20202903002245370300202120222903002246370300201a20132903002247370300200241b8066a41086a200f290300370300200241b8066a41106a2011290300370300200241b8066a41186a2047370300200241b8066a41206a2046370300200241b8066a41286a2045370300200241b8066a41306a2044370300200241b8066a41386a2005370300200220022903b8073703b806410021480c020b200441ff01710d050c060b41002104200241003a00f807200d417e6a210d0340200e2004460d04200241b8076a20046a200c20046a220a41016a2d00003a00002001200d3602042001200a41026a3602002002200441016a220a3a00f807200d417f6a210d200a2104200a41c000470d000b201b201c2903002205370300201d201e2903002244370300201f20202903002245370300202120222903002246370300201a20132903002247370300200241b8066a41086a200f290300370300200241b8066a41106a2011290300370300200241b8066a41186a2047370300200241b8066a41206a2046370300200241b8066a41286a2045370300200241b8066a41306a2044370300200241b8066a41386a2005370300200220022903b8073703b806410121480b204341016a2143200241f8056a41386a200241b8066a41386a2903002205370300200241f8056a41306a200241b8066a41306a2903002244370300200241f8056a41286a200241b8066a41286a2903002245370300200241f8056a41206a200241b8066a41206a2903002246370300202c200241b8066a41186a2903002247370300202b200241b8066a41106a2903002249370300202a200241b8066a41086a290300224a3703002025204a3703002026204937030020272047370300200241b8056a41206a220d2046370300200241b8056a41286a220a2045370300200241b8056a41306a220c2044370300200241b8056a41386a220e2005370300200220022903b80622053703f805200220053703b80502402018200228029c05470d0020024198056a2018410110a201200228029805211920022802a00521180b2019201841c1006c6a220420483a0000200420022903b805370001200441096a2025290300370000200441116a2026290300370000200441196a2027290300370000200441216a200d290300370000200441296a200a290300370000200441316a200c290300370000200441396a200e2903003700002002201841016a22183602a00520432042470d000b200228029c0521040b2019450d132002200110c80120022802000d062002280204220a41076a220c410376220d0d034100211b410121214180a6cc00211d4101211f0c040b200441ff0171450d010b200241003a00f8070b200228029c052204450d10200441c1006c450d10201910290c100b200d102d221d450d172001280204200d490d01201d2001280200200d10e40721212001280204220e200d490d0d2001200e200d6b36020420012001280200200d6a360200200d1027221f450d17200d211b202121210b02400240201b200d490d00201b210e0c010b201b410174220e200d200e200d4b1b220e4100480d050240201b0d00200e1027221f0d010c0f0b201b200e460d00201f201b200e102b221f450d0e0b201f201d200d10e407211d2002200d3602f804200c4188808080024f0d052002200c417871224236029805200c41ffffffff014b0d0602400240200d0d004100211f0c010b4101211f200d4101460d00204241786a41037641016a211f0b2002201f3602b8052002201d201f6a220d3602f805200d201d490d07200c41f8ffffff0171220d200a490d0b2002200a3602f805200a41ffffffff014b0d09200e41ffffffff0171200e470d082002200e410374220c3602b806200c200a490d0a201d4101200d1b210d0240201b450d00202110290b200d450d01202e422088a7214b200a410374214c201a202f2903003703002023203029030037030020242031290300370300200241b8066a41086a2032290300370300200241b8066a41106a2033290300370300200241b8066a41186a2034290300370300202a2037290300370300202b2036290300370300202c2035290300370300200220022903d8043703f806200220022903b8043703b80620022002290398043703f805201c2038290300370300201e20392903003703002020203a2903003703002022203b2903003703002013203c2903003703002011203d290300370300200f203e2903003703002027203f2903003703002026204029030037030020252041290300370300200220022903d8033703b807200220022903b8033703b805200d214d200e214e2018214f2004215020192151201521522016215320142154200b215520172156202d215720102158201221592029215a2028215b0c110b201d10290b02402004450d00200441c1006c450d00201910290b02402016450d00201410290b02402010450d002010410474210d2009210403400240200441046a280200450d00200428020010290b200441106a2104200d41706a220d0d000b0b0240201241ffffffff0071450d00200910290b202d450d0e2017450d0e0c0d0b2009200441ccafc000104c000b2004200d41ccafc000104c000b1032000b20024184076a4101360200200241cc076a4102360200200242023702bc0720024188b9c8003602b80720024184b9c80036028007200241013602fc062002200241f8066a3602c8072002200241f8046a3602f806200241b8076a4180a6cc001040000b20024184076a4101360200200241cc076a4102360200200242023702bc07200241f8cdc2003602b807200241c0b9c80036028007200241013602fc062002200241f8066a3602c807200220024198056a3602f806200241b8076a4180a6cc001040000b200241b8076a41146a4113360200200241b8076a410c6a4114360200200241f8066a41146a4103360200200241f8066a410c6a4103360200200241a0cec20036028007200241033602fc0620024188cec2003602f806200241133602bc072002201d3602b8062002200241b8076a360288072002200241f8056a3602c8072002200241b8056a3602c0072002200241b8066a3602b807200241f8066a4180a6cc001040000b4198b9c800411841b0b9c8001057000b20024184076a4101360200200241cc076a4102360200200242023702bc07200241c4b9c8003602b807200241c0b9c80036028007200241013602fc062002200241f8066a3602c8072002200241f8056a3602f806200241b8076a4180a6cc001040000b20024184076a4101360200200241cc076a4102360200200242023702bc07200241d4b9c8003602b807200241013602fc062002200241f8066a3602c8072002200241b8066a360280072002200241f8056a3602f806200241b8076a4180a6cc001040000b41e4b9c800412641b8a1cc001033000b200d200e41ccafc000104c000b1030000b02402016450d00201410290b02402010450d002010410474210d2009210403400240200441046a280200450d00200428020010290b200441106a2104200d41706a220d0d000b0b0240201241ffffffff0071450d00200910290b202d450d012017450d010b202d10290b410021090b20024198036a41186a2204200241f8066a41186a29030037030020024198036a41106a220d200241f8066a41106a29030037030020024198036a41086a220a200241f8066a41086a290300370300200241f8026a41086a220c200241b8066a41086a290300370300200241f8026a41106a220b200241b8066a41106a290300370300200241f8026a41186a220f200241b8066a41186a290300370300200241d8026a41086a2211200241f8056a41086a290300370300200241d8026a41106a2213200241f8056a41106a290300370300200241d8026a41186a220e200241f8056a41186a290300370300200220022903f80637039803200220022903b8063703f802200220022903f8053703d80220024198026a41386a2210200241b8076a41386a29030037030020024198026a41306a2212200241b8076a41306a29030037030020024198026a41286a221a200241b8076a41286a29030037030020024198026a41206a2214200241b8076a41206a29030037030020024198026a41186a2216200241b8076a41186a29030037030020024198026a41106a2215200241b8076a41106a29030037030020024198026a41086a2217200241b8076a41086a290300370300200241f8016a41086a2218200241b8056a41086a290300370300200241f8016a41106a2219200241b8056a41106a290300370300200241f8016a41186a221b200241b8056a41186a290300370300200220022903b80737039802200220022903b8053703f8012009450d02200841016a2108200241d8016a41186a221d2004290300370300200241d8016a41106a221f200d290300370300200241d8016a41086a220d200a290300370300200241b8016a41086a220a200c290300370300200241b8016a41106a220c200b290300370300200241b8016a41186a220b200f29030037030020024198016a41086a220f201129030037030020024198016a41106a2211201329030037030020024198016a41186a2213200e29030037030020022002290398033703d801200220022903f8023703b801200220022903d80237039801200241d8006a41386a220e2010290300370300200241d8006a41306a22102012290300370300200241d8006a41286a2212201a290300370300200241d8006a41206a221a2014290300370300200241d8006a41186a22142016290300370300200241d8006a41106a22162015290300370300200241d8006a41086a22152017290300370300200241386a41086a22172018290300370300200241386a41106a22182019290300370300200241386a41186a2219201b2903003703002002200229039802370358200220022903f80137033802402007200228022c470d00200241286a2007410110a50120022802282106200228023021070b200620074190026c6a2204205b3703082004205a37030020042009360210200441246a204b360200200441206a20563602002004411c6a2057360200200441186a2058360200200441146a2059360200200d2903002105201f2903002128201d290300212920022903d801212e200441d4006a2052360200200441d0006a2053360200200441cc006a2054360200200441c8006a2055360200200441c0006a2029370200200441386a2028370200200441306a2005370200200441286a202e370200200441f0006a200b290300370200200441e8006a200c290300370200200441e0006a200a290300370200200441d8006a20022903b80137020020044190016a201329030037020020044188016a201129030037020020044180016a200f290300370200200441f8006a200229039801370200200441b0016a2014290300370200200441a8016a2016290300370200200441a0016a201529030037020020044198016a2002290358370200200441c8016a2010290300370200200441c0016a2012290300370200200441b8016a201a290300370200200441d0016a200e290300370200200441f0016a2019290300370200200441e8016a2018290300370200200441e0016a2017290300370200200441d8016a20022903383702002004418c026a204e36020020044188026a204c36020020044184026a204d36020020044180026a204f360200200441fc016a2050360200200441f8016a20513602002002200741016a220736023020082003470d000b0b20002002290328370200200041086a200241286a41086a2802003602000c010b2000410036020002402007450d00200620074190026c6a21012006210d03400240200d41d0006a280200450d00200d28024c10290b0240200d41186a2802002209450d00200d28021021042009410474210903400240200441046a280200450d00200428020010290b200441106a2104200941706a22090d000b0b0240200d41146a28020041ffffffff0071450d00200d28021010290b0240200d28021c2204450d00200d41206a280200450d00200410290b0240200d41fc016a2802002204450d00200441c1006c450d00200d2802f80110290b200d4190026a2104200d4188026a4100360200200d280284022109200d4101360284020240200d418c026a280200450d00200910290b2004210d20042001470d000b0b200228022c2204450d0020044190026c450d00200610290b20024180086a24000f0b1039000b1038000bd92109087f017e0c7f017e017f027e017f037e017f230041e0026b22022400024002402001450d00200220003602180c010b20024180a6cc003602180b2002200136021c200241f8006a200241186a10f80202400240200228027c2203450d0020024184016a28020021042002280280012105200241f8006a200241186a10f902200228027822060d0102402004450d00200441246c21002003210103400240024020012d0000220741044b0d0002400240024020070e050400010204040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b2005450d00200541246c450d00200310290b2002418c026a41043602002002418c016a41023602002002420237027c200241a0d1c2003602782002410436028402200241b4d2c200360280022002410036026420024180a6cc00360260200220024180026a360288012002200241e0006a36028802200241f8006a41b0d1c2001040000b200241f8006a41086a22012802002108200228027c2109200241106a200241186a10c8010240024020022802100d00200228021421002002200241186a360250200241003a0020200241003602880220024100360280022002200036027c200241003602782002200241206a360284012002200241d0006a36028001200241f8006a20024180026a108d03200241e0006a41086a20022802880222003602002002200229038002220a37036020022d00202107200120003602002002200a3703782007450d01200241f8006a108e030b2002418c026a41043602002002418c016a41023602002002420237027c200241a0d1c2003602782002410436028402200241b4d2c200360280022002410036026420024180a6cc00360260200220024180026a360288012002200241e0006a36028802200241f8006a41b0d1c2001040000b200241306a41086a200241f8006a41086a220b280200220136020020022002290378220a370330200241c0006a41086a20013602002002200a370340200241013b015c2002410036025820024100360250200241d0006a41086a210c02400240024002400240024002402008450d002006200841c0036c6a210d200241e0006a410472210e20024180026a410272210f200241f8006a41106a2110200621110340201141e8006a2903004202520d01024020112802980141034722120d00024002400240024020022802402213450d0020112903a001210a200228024421140340201341086a210020132f010622154103742101410021070240024003402001450d0141cf8fcc002000410810e7072216450d02200141786a2101200741016a2107200041086a21002016417f4a0d000b2007417f6a21150b2014450d022014417f6a2114201320154102746a41e4016a28020021130c010b0b0240201341e0006a2007410c6c6a220128020841074b0d00201742808080807083422984210a41d78fcc0021140c020b200a42f02e8020012802002900002217510d034131211841a0e8c20021140c020b201742808080807083421c84210a418090cc0021140b200aa721180b0240024020022d005d450d0041b8d0c2002101413121000c010b200241d0006a108e032002410036025820024100360250200242e2c289abb68edbb7f40037036020024180026a410272410041da0010e6071a200241f8006a410041840110e6071a41e40110272216450d0a20164100360200201641046a20024180026a41dc0010e4071a201641e0006a200241f8006a41840110e4071a200241003602542002201636025020162f010622114103742113417f210041002101024002400340024020132001470d00201121000c020b200241e0006a201620016a41086a410810e7072207450d02200141086a2101200041016a2100200741004e0d000b0b200242e2c289abb68edbb7f40037028c012002200c3602880120022000360284012002201636027c200241003602782002200241d0006a3602800120024180026a20142018108a01200241f8006a20024180026a10920320024180023b015c200241206a41086a200241d0006a41086a290300370300200220022903503703200c070b41e9d0c2002101412d21000b2002200036027c2002200136027841f3cfc2004122200241f8006a4198d0c20041a8d0c200103a000b20120d0020112903a001210a200241f8006a200241c0006a10890102400240024020022802784101460d002002290380012119200241f8006a41186a2200420037030020104200370300200b42003703002002420037037841ccbec500ad428080808090018410012201290000211a200b200141086a2900003703002002201a3703782001102941aafac400ad4280808080308410012201290000211a200241e0006a41086a2207200141086a2900003703002002201a3703602001102920102002290360370000201041086a200729030037000020024180026a41086a200b29030037030020024180026a41106a201029030037030020024180026a41186a20002903003703002002200229037837038002200220024180026a10b501200a201942b0ea017c560d01200a200229030842b8177c42b81720022802001b22195a0d032019422088211a4200210a0c020b2002290380012219422088211a200228027c221bad422086420184210a201c4280808080708320023502880184221c211d0c010b201d428080808070832018ad84211d41f89ac500ad21194225211a4100211b4201210a0b2002201d3703702002201a422086201942ffffffff0f8384221e3703682002201bad422086200a42ffffffff0f838437036002400240024020022d005d450d0041b8d0c2002101413121000c010b024002400240200aa722154101470d00200241d0006a108e032002410036025820024100360250200242f4d2b59bc7ae98b8303703200c010b20022802502113200242f4d2b59bc7ae98b8303703202013450d00200228025421140c010b200f410041da0010e6071a200241f8006a410041840110e6071a41e40110272213450d0b4100211420134100360200201341046a20024180026a41dc0010e4071a201341e0006a200241f8006a41840110e4071a20024100360254200220133602500b2019a7211f201aa7211202400340201341086a210020132f01062218410374210141002107024003402001450d01200241206a2000410810e7072216450d03200141786a2101200741016a2107200041086a21002016417f4a0d000b2007417f6a21180b02402014450d002014417f6a2114201320184102746a41e4016a28020021130c010b0b200242f4d2b59bc7ae98b83037028c012002200c3602880120022018360284012002201336027c200241003602782002200241d0006a360280014101102721010240201541014622160d002001450d0c200141003a0000200141014109102b2201450d0c2001201e37000141092107410921000c030b2001450d0b200141013a000020024180026a200e10f60220022802800221140240024020022802880222130d0041012107201341016a21000c010b201341016a22002013490d0920004102200041024b1b22074100480d09200141012007102b2201450d0c0b200141016a2014201310e4071a200228028402450d02201410290c020b41e9d0c2002101412d21000b2002200036027c2002200136027841f3cfc2004122200241f8006a4198d0c20041a8d0c200103a000b200220003602880220022007360284022002200136028002200241f8006a20024180026a1092032002200a3c005d200241003a005c20160d032015450d00201b450d002012450d00201f10290b201141c0036a2211200d470d000b0b200241206a41086a200c290300370300200220022903503703200c010b200241206a41086a200241d0006a41086a29030037030020022002290350370320201b450d002012450d00201f10290b200241c0006a108e0302402004450d00200441246c21002003210103400240024020012d0000220741044b0d0002400240024020070e050400010204040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b02402005450d00200541246c450d00200310290b02402008450d00200841c0036c210020064198016a21010340200110c201200141c0036a2101200041c07c6a22000d000b0b02402009450d00200941c0036c450d00200610290b200241003602682002420137036020022d002c2100410110272201450d032002410136026420022001360260200120003a00002002410136026820022d002d2100200141014102102b2201450d032002410236026420022001360260200120003a00012002410236026820022802282200200241e0006a107102400240024020022802202201450d00024020022802242216450d002016210720012113034020132802e40121132007417f6a22070d000b200121070340200720072f01064102746a41e4016a28020021072016417f6a22160d000b200241f8006a2116201321010c020b200241f8006a2116200121070c010b410021012002410036027c200241f8006a21160c010b2002200736027c20024184016a20072f01063602002002410036028001200241003602780b20024180026a41086a201641086a290200220a3703002002201629020022173703800220024190016a200a37030020024200370380012002200136027c20024100360278200220173703880120022000360298012000450d01034020022000417f6a36029801200241f8006a410020011b2213280200210720132802082114024002400240201328020c2216201328020422002f01064f0d00200021010c010b0240034020002802002201450d01200741016a210720002f0104211620012100201620012f0106490d020c000b0b2014ad210a410021010c010b2016ad4220862014ad84210a0b200a422088a7221441016a2116200aa721180240024020070d00200121000c010b200120164102746a41e4016a2802002100410021162007417f6a2207450d00034020002802e40121002007417f6a22070d000b0b2013201636020c2013201836020820132000360204201341003602000240024020022802642216200228026822006b4108490d00200228026021070c010b200041086a22072000490d02201641017422132007201320074b1b22134100480d020240024020160d00024020130d00410121070c020b2013102722070d010c070b2002280260210720162013460d00200720162013102b2207450d060b20022013360264200220073602600b200720006a200120144103746a41086a2900003700002002200041086a360268200141e0006a2014410c6c6a2201280200211320012802082201200241e0006a10710240024020022802642216200228026822006b2001490d00200228026021070c010b200020016a22072000490d02201641017422142007201420074b1b22144100480d020240024020160d00024020140d00410121070c020b201410272207450d070c010b2002280260210720162014460d00200720162014102b2207450d060b20022014360264200220073602600b200720006a2013200110e4071a2002200020016a22013602682002280298012200450d03200228027c21010c000b0b1032000b20022802682101200228026021070b200241206a108e03200241e0026a24002001ad4220862007ad840f0b1030000bc91305027f017e067f037e0a7f230041b0036b2202240020002802102203200328020041016a36020020002902142104200028020c2105200028020821062000280200210320002802042100200241f0016a41086a2207200141086a280200360200200220012902003703f001024002400240024002400240024020002f01062201410b490d00200241d0026a410272410041da0010e6071a200241386a410041840110e6071a41e40110272208450d0420084100360200200841046a200241d0026a41dc0010e4071a200841e0006a200241386a41840110e4072107200241386a41086a2209200041b0016a280200360200200220002902a8013703382000413f6a2d0000210a200041386a350000210b2000413c6a330000210c2000413e6a310000210d200841086a200041c0006a20002f010641796a220141037410e407210e2007200041b4016a2001410c6c10e4072107200041063b0106200820013b0106200241d0026a41086a2009280200360200200220022903383703d002200b200c200d4210868442208684210b0240024020054107490d002005410374200e6a41506a200e200541796a22094103746a220e200141ffff037120096b41037410e5071a200e20043700002005410c6c20076a220541b87f6a200541ac7f6a2205200841066a22012f010020096b410c6c10e5071a200541086a200241f0016a41086a280200360200200520022903f0013702000c010b200041086a20054103746a220741086a2007200041066a22012f010020056b41037410e5071a20072004370000200041e0006a2005410c6c6a2207410c6a200720012f010020056b410c6c10e5071a200741086a200241f0016a41086a280200360200200720022903f0013702000b200120012f010041016a3b0100200241286a41086a220f200241d0026a41086a22102802002205360200200241086a221120053602002002200a3a0017200220022903d00222043703282002200b3e02102002200b4230883c00162002200b4220883d01142002200437030020022903102104200028020022090d01410021120c020b200020054103746a220341106a200341086a2203200120056b41037410e5071a2003200437000020002005410c6c6a220341ec006a200341e0006a220120002f010620056b410c6c10e5071a200341e8006a2007280200360200200120022903f001370200200020002f010641016a3b01060c020b20002f01042113200241d0026a41027221144100210002400340200220093602242002200341016a2212360220200f20112802003602002002200229030037032820032000470d01201341ffff0371210702400240024020092f01062203410b490d002014410041da0010e6071a200241f0016a200241d0026a41dc0010e4071a200241386a410041b40110e6071a41940210272201450d0720014100360200200141046a200241f0016a41dc0010e4071a200141e0006a200241386a41b40110e40721002009290038210b200241386a41086a220e200941b0016a280200360200200220092902a801370338200141086a200941c0006a20092f0106220541796a220341037410e40721152000200941b4016a2003410c6c10e4072116200141e4016a20094180026a2005417a6a220a41027410e4072117200941063b0106200120033b01060240200a450d00410021032017210003402000280200220520033b010420052001360200200041046a2100200a200341016a2203470d000b0b2010200e280200220336020020022002290338220c3703d002200e20033602002002200c370338201341ffff037122004107490d0120152007417a6a22004103746a2015200741796a22034103746a220520012f010620036b41037410e5071a200520043700002007410c6c20166a220541b87f6a200541ac7f6a220520012f0106220a20036b410c6c10e5071a200541086a200f280200360200200520022903283702002001200a41016a22053b01062007410274221320176a416c6a201720004102746a220a200541ffff0371220720006b41027410e5071a200a200836020020072000490d02200120136a41cc016a2100034020002802002205200341016a22033b010420052001360200200041046a210020032007490d000c030b0b200941086a2205200741016a22004103746a200520074103746a2205200320076b220141037410e5071a2005200437000020092007410c6c6a220541ec006a200541e0006a220a2001410c6c10e5071a200541e8006a200241286a41086a280200360200200a20022903283702002009200341016a22033b01062007410274200941e4016a22056a41086a200520004102746a2205200341ffff0371220120006b41027410e5071a20052008360200201341ffff037120014f0d0520092000417f6a22034102746a41e8016a2100034020002802002205200341016a22033b010420052009360200200041046a210020032001490d000c060b0b200941086a2203200741016a220a4103746a200320074103746a220320092f0106220520076b221341037410e5071a20032004370000200941e0006a2007410c6c6a2203410c6a20032013410c6c10e5071a200341086a200f280200360200200320022903283702002009200541016a22033b010620074102742217200941e4016a22056a41086a2005200a4102746a2213200341ffff03712205200a6b41027410e5071a20132008360200200020054f0d00200920176a41e8016a2103034020032802002200200741016a22073b010420002009360200200341046a210320052007470d000b0b200241106a41086a200e280200220336020020112003360200200220022903382204370310200220043703000240200928020022030d0020012108200b21040c030b20092f0104211320032109200b21042001210820122100201221030c000b0b41cc9ec800413541b8a1cc001033000b200241d0026a410272410041da0010e6071a200241f0016a200241d0026a41dc0010e4071a200241386a410041b40110e6071a41940210272203450d0120034100360200200341046a200241f0016a41dc0010e4071a200341e0006a200241386a41b40110e40721052003200628020022003602e4012006200336020020062006280204220141016a360204200041003b010420002003360200200241386a41086a200241086a2802003602002002200229030037033820012012470d0220032f01062200410a4b0d0320052000410c6c6a22052002290338370200200320004103746a41086a2004370000200541086a200241386a41086a2802003602002003200041016a22004102746a41e4016a2008360200200320003b0106200820003b0104200820033602000b200241b0036a24000f0b1030000b41b69cc800413041b8a1cc001033000b418f9cc800412741b8a1cc001033000bbf0101067f230041206b2202240020024180a6cc00410010940302400240412010272203450d0020032002290300370000200341186a2204200241186a290300370000200341106a2205200241106a290300370000200341086a2206200241086a290300370000412010272207450d0120072003290000370000200741186a2004290000370000200741106a2005290000370000200741086a200629000037000020031029200241206a24002007ad42808080808004840f0b1039000b1030000be51b06037f017e077f017e277f027e230041a00d6b220324002003200236020c20032001360208200341206a41186a22044200370300200341206a41106a22024200370300200341206a41086a220142003703002003420037032041b3e6ca00ad4280808080e000841001220529000021062001200541086a290000370300200320063703202005102941c9e6ca00ad4280808080e00084100122072900002106200341106a41086a2205200741086a2900003703002003200637031020071029200220032903102206370300200341800d6a41086a22082001290300370300200341800d6a41106a22092006370300200341800d6a41186a220a2005290300370300200320032903203703800d2003200341800d6a412010fc012003280204210b2003280200210c200442003703002002420037030020014200370300200342003703204188a2c800ad42808080808003841001220729000021062001200741086a290000370300200320063703202007102941a0a2c800ad4280808080e001841001220729000021062005200741086a29000037030020032006370310200710292002200329031022063703002008200129030037030020092006370300200a2005290300370300200320032903203703800d200341206a200341800d6a412010ce0120032802202201410120011b210d0240024002402003290224420020011b220e422088a722020d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b200341206a410041e00c10e6071a200b417f6a41d100704130200c1b2101200d41206a210f200d20024105746a21104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f410021204100212141002122410021234100212441002125410021264100212741002128410021294100212a4100212b4100212c4100212d4100212e4100212f4100210b200d21024100213041d1002131024003402030210720022105024002402001450d00200141016a2101200521020340024020102002470d00200d21020b2002220541206a21022001417f6a22010d000b20050d010c030b024020052010460d00200541206a21020c010b200f2102200d21050b0240024002400240200328020c220141056a2204417f4c0d00200328020821320240024020040d00410021044101210c0c010b20041027220c450d020b200341003602182003200c36021020032004360214024020040d0041011027220c450d08200341013602142003200c3602100b200c20073a0000200341013602182001200341106a10710240024020032802142233200328021822306b2001490d00200328021021042033210c0c010b203020016a22042030490d032033410174220c2004200c20044b1b220c4100480d030240024020330d000240200c0d00410121040c020b200c102722040d010c0a0b200328021021042033200c460d0020042033200c102b2204450d090b2003200c360214200320043602100b200420306a2032200110e4071a2003203020016a2230360218412010272201450d0120012005290000370000200141186a2232200541186a290000370000200141106a2234200541106a290000370000200141086a2235200541086a29000037000002400240200c20306b411f4d0d00200c21330c010b203041206a22052030490d03200c41017422332005203320054b1b22334100480d0302400240200c0d00024020330d00410121040c020b203310272204450d0a0c010b200c2033460d002004200c2033102b2204450d090b20032033360214200320043602100b200420306a22052001290000370000200541186a2032290000370000200541106a2034290000370000200541086a20352900003700002003203041206a2205360218200110292005ad4220862004ad84101022012900002106200141086a2900002136200141106a2900002137200a200141186a2900003703002009203737030020082036370300200320063703800d2001102902402033450d00200410290b2031417f6a2131200741016a2130200341206a20074103704105746a220120032903800d370000200141186a200a290300370000200141106a2009290300370000200141086a20082903003700004100210503402007200741036e2204417d6c6a4102470d04200341206a20056a220141df006a2d0000220b2001411f6a2d0000220c71200b200c722001413f6a2d000071722128200141de006a2d0000220b2001411e6a2d0000220c71200b200c722001413e6a2d000071722127200141dd006a2d0000220b2001411d6a2d0000220c71200b200c722001413d6a2d000071722126200141dc006a2d0000220b2001411c6a2d0000220c71200b200c722001413c6a2d000071722125200141db006a2d0000220b2001411b6a2d0000220c71200b200c722001413b6a2d000071722124200141da006a2d0000220b2001411a6a2d0000220c71200b200c722001413a6a2d000071722123200141d9006a2d0000220b200141196a2d0000220c71200b200c72200141396a2d000071722122200141d8006a2d0000220b200141186a2d0000220c71200b200c72200141386a2d000071722121200141d7006a2d0000220b200141176a2d0000220c71200b200c72200141376a2d000071722120200141d6006a2d0000220b200141166a2d0000220c71200b200c72200141366a2d00007172211f200141d5006a2d0000220b200141156a2d0000220c71200b200c72200141356a2d00007172211e200141d4006a2d0000220b200141146a2d0000220c71200b200c72200141346a2d00007172211d200141d3006a2d0000220b200141136a2d0000220c71200b200c72200141336a2d00007172211c200141d2006a2d0000220b200141126a2d0000220c71200b200c72200141326a2d00007172211b200141d1006a2d0000220b200141116a2d0000220c71200b200c72200141316a2d00007172211a200141d0006a2d0000220b200141106a2d0000220c71200b200c72200141306a2d000071722119200141cf006a2d0000220b2001410f6a2d0000220c71200b200c722001412f6a2d000071722118200141ce006a2d0000220b2001410e6a2d0000220c71200b200c722001412e6a2d000071722117200141cd006a2d0000220b2001410d6a2d0000220c71200b200c722001412d6a2d000071722116200141cc006a2d0000220b2001410c6a2d0000220c71200b200c722001412c6a2d000071722115200141cb006a2d0000220b2001410b6a2d0000220c71200b200c722001412b6a2d000071722114200141ca006a2d0000220b2001410a6a2d0000220c71200b200c722001412a6a2d000071722113200141c9006a2d0000220b200141096a2d0000220c71200b200c72200141296a2d000071722112200141c8006a2d0000220b200141086a2d0000220c71200b200c72200141286a2d000071722111200141c7006a2d0000220b200141076a2d0000220c71200b200c72200141276a2d000071722129200141c6006a2d0000220b200141066a2d0000220c71200b200c72200141266a2d00007172212a200141c5006a2d0000220b200141056a2d0000220c71200b200c72200141256a2d00007172212b200141c4006a2d0000220b200141046a2d0000220c71200b200c72200141246a2d00007172212c200141c3006a2d0000220b200141036a2d0000220c71200b200c72200141236a2d00007172212d200141c2006a2d0000220b200141026a2d0000220c71200b200c72200141226a2d00007172212e200141c1006a2d0000220b200141016a2d0000220c71200b200c72200141216a2d00007172212f200141c0006a2d0000220b20012d0000220c71200b200c72200141206a2d00007172210b200541800c460d04200341206a20052004410574200741096e41e0006c6b6a6a220141ff006a20283a0000200141fe006a20273a0000200141fd006a20263a0000200141fc006a20253a0000200141fb006a20243a0000200141fa006a20233a0000200141f9006a20223a0000200141f8006a20213a0000200141f7006a20203a0000200141f6006a201f3a0000200141f5006a201e3a0000200141f4006a201d3a0000200141f3006a201c3a0000200141f2006a201b3a0000200141f1006a201a3a0000200141f0006a20193a0000200141ef006a20183a0000200141ee006a20173a0000200141ed006a20163a0000200141ec006a20153a0000200141eb006a20143a0000200141ea006a20133a0000200141e9006a20123a0000200141e8006a20113a0000200141e7006a20293a0000200141e6006a202a3a0000200141e5006a202b3a0000200141e4006a202c3a0000200141e3006a202d3a0000200141e2006a202e3a0000200141e1006a202f3a0000200141e0006a200b3a000020042107200541e0006a220541e00c470d000c040b0b1038000b1039000b1032000b4100210120310d000b0b200020283a001f200020273a001e200020263a001d200020253a001c200020243a001b200020233a001a200020223a0019200020213a0018200020203a00172000201f3a00162000201e3a00152000201d3a00142000201c3a00132000201b3a00122000201a3a0011200020193a0010200020183a000f200020173a000e200020163a000d200020153a000c200020143a000b200020133a000a200020123a0009200020113a0008200020293a00072000202a3a00062000202b3a00052000202c3a00042000202d3a00032000202e3a00022000202f3a00012000200b3a00000b0240200e42ffffff3f83500d00200d10290b200341a00d6a24000f0b1030000bce6e03097f087e067f23004180146b220224000240024020010d002002200136023420024180a6cc003602300c010b2002200136023420022001417f6a360234200220003602302002200041016a36023020002d0000220341034f0d00200241f00a6a200241306a1087030240024002400240024002400240024002400240024020022903d80b4203510d00200241f0006a200241f00a6a41c00310e4071a200241b0046a200241f0006a41c00310e4071a2002200241b0046a3602f007200241f00a6a200241f0076a10bd0220022802f80a2100024020022802f40a450d0020022802f00a10290b200241f00a6a200241b0046a41c00310e4071a200241f0076a200241f00a6a10960341012101024020022d00f0074101460d00200241f00a6a200241f8076a41f80210e4071a200241b00e6a200241c00b6a220410c30102400240024020022903900b4202520d00200241d00e6a41206a22014200370300200241d00e6a41186a22054280808080c000370300200241013a00f80e200242043703e00e2002427f3703d80e200242003703d00e02400240024020022802c00b0e1c02020202020b02020202020202020b0b0b0b0b0b010b0b0b02000202020b200241c80b6a2d00004103470d010c0a0b200241c40b6a2802004101470d090b200241f0076a41206a22064200370300200241f0076a41186a22074280808080c000370300200220022800c813360298132002200241cb136a28000036009b132002419c086a200228009b13360000200241013a00980820024204370380082002427f3703f807200242003703f007200220022802981336009908200241b80f6a200241d00e6a200241f0076a109703200241d00e6a41286a2208200241b80f6a41286a2903003703002001200241b80f6a41206a2903003703002005200241b80f6a41186a290300370300200241d00e6a41106a2209200241b80f6a41106a290300370300200241d00e6a41086a220a200241b80f6a41086a290300370300200220022903b80f3703d00e2006420037030020074280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f007200241e80f6a200241d00e6a200241f0076a1097032008200241e80f6a41286a2903003703002001200241e80f6a41206a2903003703002005200241e80f6a41186a2903003703002009200241e80f6a41106a290300370300200a200241e80f6a41086a290300370300200220022903e80f3703d00e2006420037030020074280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f00720024198106a200241d00e6a200241f0076a109703200820024198106a41286a290300370300200120024198106a41206a290300370300200520024198106a41186a290300370300200920024198106a41106a290300370300200a20024198106a41086a29030037030020022002290398103703d00e2006420037030020074280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f007200241c8106a200241d00e6a200241f0076a1097032008200241c8106a41286a2903003703002001200241c8106a41206a2903003703002005200241c8106a41186a2903003703002009200241c8106a41106a290300370300200a200241c8106a41086a290300370300200220022903c8103703d00e2006420037030020074280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f007200241f8106a200241d00e6a200241f0076a1097032008200241f8106a41286a2903003703002001200241f8106a41206a2903003703002005200241f8106a41186a2903003703002009200241f8106a41106a290300370300200a200241f8106a41086a290300370300200220022903f8103703d00e2006420037030020074280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f007200241a8116a200241d00e6a200241f0076a1097032008200241a8116a41286a2903003703002001200241a8116a41206a2903003703002005200241a8116a41186a2903003703002009200241a8116a41106a290300370300200a200241a8116a41086a290300370300200220022903a8113703d00e20022903b00e210b200241c8136a20022d00b80e220120001098030240024020022903c813220ca741ff01714101460d00200141ff01710d0341800c2105427f200b42c0b2cd3b7c220c200c200b541b428090a7f0ea25560d01200241c8136a21050c040b200c420888a721050b20022802e00e21030240200241e80e6a2802002200450d002000410c6c21012003210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b0240200241e40e6a2802002200450d002000410c6c450d00200310290b20022802ec0e21030240200241f40e6a2802002200450d002000410c6c21012003210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b200241f00e6a2802002200450d092000410c6c450d09200310290c090b200241d00e6a41206a22014200370300200241d00e6a41186a22054280808080c000370300200241013a00f80e200242043703e00e427f210b2002427f3703d80e200242003703d00e02400240024020022802c00b0e1c02020202020902020202020202020909090909090109090902000202020b200241c80b6a2d00004103470d010c080b200241c40b6a2802004101470d070b200241f0076a41206a22064200370300200241f0076a41186a22034280808080c000370300200220022800c813360298132002200241cb136a28000036009b132002419c086a200228009b13360000200241013a00980820024204370380082002427f3703f807200242003703f007200220022802981336009908200241880f6a200241d00e6a200241f0076a109703200241d00e6a41286a2207200241880f6a41286a2903003703002001200241880f6a41206a2903003703002005200241880f6a41186a290300370300200241d00e6a41106a2208200241880f6a41106a290300370300200241d00e6a41086a2209200241880f6a41086a290300370300200220022903880f3703d00e2006420037030020034280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f007200241b80f6a200241d00e6a200241f0076a1097032007200241b80f6a41286a2903003703002001200241b80f6a41206a2903003703002005200241b80f6a41186a2903003703002008200241b80f6a41106a2903003703002009200241b80f6a41086a290300370300200220022903b80f3703d00e2006420037030020034280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f007200241e80f6a200241d00e6a200241f0076a1097032007200241e80f6a41286a2903003703002001200241e80f6a41206a2903003703002005200241e80f6a41186a2903003703002008200241e80f6a41106a2903003703002009200241e80f6a41086a290300370300200220022903e80f3703d00e2006420037030020034280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f00720024198106a200241d00e6a200241f0076a109703200720024198106a41286a290300370300200120024198106a41206a290300370300200520024198106a41186a290300370300200820024198106a41106a290300370300200920024198106a41086a29030037030020022002290398103703d00e20034200370300200241f0076a41106a22034200370300200241f0076a41086a22014200370300200242003703f00741b3e6ca00ad4280808080e0008410012205290000210c2001200541086a2900003703002002200c3703f0072005102941c9e6ca00ad4280808080e0008410012205290000210c20024198136a41086a2206200541086a2900003703002002200c37039813200510292003200229039813220c370300200241c8136a41086a22052001290300370300200241c8136a41106a2201200c370300200241c8136a41186a2006290300370300200220022903f0073703c813200241286a200241c8136a412010fc01200228022c410020022802281bad210c024020022903900b4201520d0020022903980b220b4200510d05200c200241a00b6a290300220d200d200c541b220e200b7c200e200d7d200b827d210b0b200241f0076a41206a4200370300200241f0076a41186a4280808080c000370300200241013a0098082002420437038008200242003703f00720024200200b200c7d220c200c200b561b3703f807200241c8106a200241d00e6a200241f0076a109703200241c8136a41286a200241c8106a41286a290300370300200241c8136a41206a200241c8106a41206a290300370300200241c8136a41186a200241c8106a41186a2903003703002001200241c8106a41106a2903003703002005200241c8106a41086a290300370300200220022903c8103703c81320024198136a200241f00a6a10a802200241f0076a200228029813220120022802a01310a902200241b8086a280200410020022903f0074201511b21050240200228029c13450d00200110290b024002400240024002400240024002400240024020022802b80b22032005490d00410c10272206450d17410410272201450d15200141044120102b2201450d17200120022903f00a370000200141186a200241f00a6a41186a290300370000200141106a200241f00a6a41106a290300370000200141086a200241f00a6a41086a2903003700002001412041c000102b2201450d1720012003360020200642c0808080c004370204200620013602000240024020052003490d0041002101410421050c010b410c10272205450d18410410272201450d16200141044120102b2201450d18200120022903f00a370000200141186a200241f00a6a41186a290300370000200141106a200241f00a6a41106a290300370000200141086a200241f00a6a41086a2903003700002001412041c000102b2201450d1820012003417f6a360020200542c0808080c00437020420052001360200410121010b200241d00e6a41206a2207428180808010370300200241d00e6a41186a22032001360200200241e40e6a2001360200200241fc0e6a200241eb126a280000360000200241013a00f80e200220063602ec0e200220053602e00e2002427f3703d80e200220022903b00e220b3703d00e200220022800e8123600f90e200241f8106a200241c8136a200241d00e6a109703200241d00e6a41286a200241f8106a41286a2903003703002007200241f8106a41206a2903003703002003200241f8106a41186a290300370300200241d00e6a41106a200241f8106a41106a290300370300200241d00e6a41086a200241f8106a41086a290300370300200220022903f8103703d00e418012210120022d00b80e22054102460d04200241c8136a2005200010980320022903c813220ca741ff01714101460d0320050d0141800c2101427f200b42c0b2cd3b7c220c200c200b541b428090a7f0ea25560d04200241c8136a2101200b210c0c020b200241003a003b20024180063b0039200241013a003820022802d81321050240200241e0136a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b0240200241dc136a2802002200450d002000410c6c450d00200510290b20022802e41321050240200241ec136a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b200241e8136a2802002200450d122000410c6c450d12200510290c120b427f210c200241c8136a21010b200241f0076a41206a4200370300200241f0076a41186a4280808080c00037030020022001280000360298132002200141036a28000036009b13200241f0076a412c6a200228009b13360000200241013a00980820024204370380082002427f3703f8072002200c3703f007200220022802981336009908200241a8116a200241d00e6a200241f0076a10970320024198136a41286a200241a8116a41286a29030037030020024198136a41206a200241a8116a41206a29030037030020024198136a41186a200241a8116a41186a29030037030020024198136a41106a200241a8116a41106a29030037030020024198136a41086a200241a8116a41086a290300370300200220022903a81137039813200241186a2000200b20022d00b90e20022903a80b220d200241b00b6a290300220e10c70202402002290318220b200241186a41086a290300220c84500d0041002100200241003a00ff132002200c3703f0122002200b3703e812200241014111200d200e84501b3a00fe132002200241f00a6a3602c00e2002200241f00a6a36028812200220024188126a360280082002200241fe136a3602fc072002200241c00e6a3602f8072002200241ff136a3602f4072002200241e8126a3602f007200241d00e6a200241f00a6a200241f0076a10c8020240024020022802d00e4101470d004200210e20022903d80e210d410121000c010b200241f80e6a290300210e200241f00e6a290300210d20022903d80e4201520d00200241d00e6a41106a290300210f2002280288122101200241a8086a200241d00e6a41186a290300370300200241a0086a200f37030041002100200241f0076a41086a41003a0000200241f9076a200129000037000020024181086a200141086a29000037000020024189086a200141106a29000037000020024191086a200141186a290000370000200241033a00f007200241f0076a10cb010b20000d03200241f0076a41186a22064200370300200241f0076a41106a22054200370300200241f0076a41086a22014200370300200242003703f00741dcbec500ad4280808080800184220f100122032900002110200241e8126a41086a2200200341086a290000370300200220103703e8122003102920012000290300370300200220022903e8123703f007419fe3c200ad4280808080d0018422101001220329000021112000200341086a290000370300200220113703e81220031029200520022903e8122211370300200241d00e6a41086a22072001290300370300200241d00e6a41106a22082011370300200241d00e6a41186a22092000290300370300200220022903f0073703d00e2002200241d00e6a412010e301200241106a29030021112002290308211220022802002103200642003703002005420037030020014200370300200242003703f007200f10012206290000210f2000200641086a2900003703002002200f3703e8122006102920012000290300370300200220022903e8123703f007201010012206290000210f2000200641086a2900003703002002200f3703e81220061029200520022903e812220f370300200720012903003703002008200f37030020092000290300370300200220022903f0073703d00e200242002011420020031b220f200e7d2012420020031b220e200d54ad7d2210200e200d7d220d200e562010200f562010200f511b22001b3703f80720024200200d20001b3703f007200241d00e6aad4280808080800484200241f0076aad428080808080028410030b200241c8136a41206a22004200370300200241c8136a41186a22014280808080c000370300200241c8136a412c6a200241b8126a41036a280000360000200242043703d813200220022800b8123600f1132002427f3703d0132002200b427f200c501b3703c813200241013a00f013200241d8116a20024198136a200241c8136a109703200241c8136a41286a200241d8116a41286a2903003703002000200241d8116a41206a2903003703002001200241d8116a41186a290300370300200241c8136a41106a200241d8116a41106a290300370300200241c8136a41086a200241d8116a41086a290300370300200220022903d8113703c813200241f0076a200410c90220022d00f0074101460d03200241d00e6a41286a2201200241a0086a2205290300370300200241d00e6a41206a2203200241f0076a41286a2206290300370300200241d00e6a41186a2207200241f0076a41206a2208290300370300200241d00e6a41106a2209200241f0076a41186a220a290300370300200241d00e6a41086a2213200241f0076a41106a2214290300370300200220022903f8073703d00e20024188126a200241c8136a200241d00e6a109703200241c8136a41286a221520024188126a41286a290300370300200241c8136a41206a221620024188126a41206a290300370300200241c8136a41186a220020024188126a41186a290300370300200241c8136a41106a221720024188126a41106a290300370300200241c8136a41086a221820024188126a41086a29030037030020022002290388123703c813200241f0076a200410ca0220022d00f0074101460d042001200529030037030020032006290300370300200720082903003703002009200a29030037030020132014290300370300200220022903f8073703d00e200241b8126a200241c8136a200241d00e6a1097032015200241b8126a41286a2903003703002016200241b8126a41206a2903003703002000200241b8126a41186a2903003703002017200241b8126a41106a2903003703002018200241b8126a41086a290300370300200220022903b8123703c813200241f0076a200410cb0220022d00f0074101460d05200241d00e6a41286a2200200241f0076a41306a2201290300370300200241d00e6a41206a2205200241f0076a41286a2203290300370300200241d00e6a41186a2206200241f0076a41206a2207290300370300200241d00e6a41106a2208200241f0076a41186a2209290300370300200241d00e6a41086a220a200241f0076a41106a2213290300370300200220022903f8073703d00e200241e8126a200241c8136a200241d00e6a109703200241c8136a41286a200241e8126a41286a290300370300200241c8136a41206a200241e8126a41206a290300370300200241c8136a41186a2214200241e8126a41186a290300370300200241c8136a41106a200241e8126a41106a290300370300200241c8136a41086a200241e8126a41086a290300370300200220022903e8123703c813200241f0076a200241f00a6a200410cc0220022d00f0074101460d0620002001290300370300200520032903003703002006200729030037030020082009290300370300200a2013290300370300200220022903f8073703d00e20024198136a200241c8136a200241d00e6a109703200241386a41086a200229039813370300200241386a41106a20024198136a41086a290300370300200241386a41186a20024198136a41106a290300370300200241386a41206a20024198136a41186a290300370300200241386a41286a20024198136a41206a290300370300200241386a41306a20024198136a41286a290300370300200241003a00380c100b200c420888a721010b200241013a0038200220013b0039200220014110763a003b20022802e00e2105024020032802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b0240200241e40e6a2802002200450d002000410c6c450d00200510290b20022802ec0e21050240200241f40e6a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b200241f00e6a2802002200450d0e2000410c6c450d0e200510290c0e0b200241003a003b20024180023b0039200241013a003820022802a81321050240200241b0136a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b0240200241ac136a2802002200450d002000410c6c450d00200510290b20022802b41321050240200241bc136a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b200241b8136a2802002200450d0d2000410c6c450d0d200510290c0d0b200220022d00f3073a003b200220022f00f1073b0039200241013a003820022802d81321050240200241e0136a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b0240200241dc136a2802002200450d002000410c6c450d00200510290b20022802e41321050240200241ec136a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b200241e8136a2802002200450d0c2000410c6c450d0c200510290c0c0b200220022d00f3073a003b200220022f00f1073b0039200241013a003820022802d8132105024020002802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b0240200241dc136a2802002200450d002000410c6c450d00200510290b20022802e41321050240200241ec136a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b200241e8136a2802002200450d0b2000410c6c450d0b200510290c0b0b200220022d00f3073a003b200220022f00f1073b0039200241013a003820022802d81321050240200241e0136a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b0240200241dc136a2802002200450d002000410c6c450d00200510290b20022802e41321050240200241ec136a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b200241e8136a2802002200450d0a2000410c6c450d0a200510290c0a0b200220022d00f3073a003b200220022f00f1073b0039200241013a003820022802d8132105024020142802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b0240200241dc136a2802002200450d002000410c6c450d00200510290b20022802e41321050240200241ec136a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b200241e8136a2802002200450d092000410c6c450d09200510290c090b427f4200200141ff01714102471b210b200241c8136a21050b200241f0076a41206a22004200370300200241f0076a41186a22014280808080c00037030020022005280000360298132002200541036a28000036009b132002419c086a200228009b13360000200241013a00980820024204370380082002427f3703f8072002200b3703f007200220022802981336009908200241d8116a200241d00e6a200241f0076a109703200241d00e6a41286a2205200241d8116a41286a290300370300200241d00e6a41206a2206200241d8116a41206a290300370300200241d00e6a41186a2207200241d8116a41186a290300370300200241d00e6a41106a2208200241d8116a41106a290300370300200241d00e6a41086a2209200241d8116a41086a290300370300200220022903d8113703d00e2000420037030020014280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f00720024188126a200241d00e6a200241f0076a109703200520024188126a41286a290300370300200620024188126a41206a290300370300200720024188126a41186a290300370300200820024188126a41106a290300370300200920024188126a41086a29030037030020022002290388123703d00e2000420037030020014280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f007200241b8126a200241d00e6a200241f0076a1097032005200241b8126a41286a2903003703002006200241b8126a41206a2903003703002007200241b8126a41186a2903003703002008200241b8126a41106a2903003703002009200241b8126a41086a290300370300200220022903b8123703d00e2000420037030020014280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f007200241e8126a200241d00e6a200241f0076a1097032005200241e8126a41286a2903003703002006200241e8126a41206a2903003703002007200241e8126a41186a2903003703002008200241e8126a41106a2903003703002009200241e8126a41086a290300370300200220022903e8123703d00e2000420037030020014280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f00720024198136a200241d00e6a200241f0076a109703200520024198136a41286a290300370300200620024198136a41206a290300370300200720024198136a41186a290300370300200820024198136a41106a290300370300200920024198136a41086a29030037030020022002290398133703d00e2000420037030020014280808080c000370300200241013a00980820024204370380082002427f3703f807200242003703f007200241c8136a200241d00e6a200241f0076a109703200241940f6a2201200241c8136a41086a290300370200200220022903c81337028c0f200241dc136a2802002105200241c8136a41186a2802002100200241c8136a41206a2802002106200241ec136a280200210720022802d813210820022802e413210920022903f013210b200241c00e6a41086a20012902003703002002200229028c0f3703c00e0240024020022802c00b41796a220141114b0d00024002400240024020010e12000404040401040404040404040404040402000b0240200241c80b6a2d00004118460d0041002101200241003a00d30e200241003b00d10e200241013a00d00e0c050b2002200241980d6a3602d81102400240200341014b0d00200241f0076a41286a200241a80d6a220141286a290300370300200241f0076a41206a200141206a290300370300200241f0076a41186a200141186a290300370300200241f0076a41106a200141106a290300370300200241f0076a41086a200141086a290300370300200220012903003703f007200241c8136a200241f0076a20022802980d10b40220022903c8134201520d01200241e8126a41186a200241c8136a41206a290300220d370300200241e8126a41106a200241c8136a41186a290300220c370300200241e8126a41086a200241c8136a41106a290300370300200220022903d0133703e812200241b8126a41086a200d3e02002002200c3703b81220022d00ba124100200ca741ff01714103461b2101024041002802d8a74c4104490d002002411536028c122002200241b8126a3602881241002802888040210341002802848040210a41002802dca74c2113200241b0086a41bb1b360200200241a8086a42db80808010370300200241a4086a41eec5c0003602002002419c086a420e37020020024198086a41e0c5c00036020020024190086a420137030020024180086a4202370300200241f8076a41073602002002418c086a20024188126a360200200241dcbec2003602fc07200241bcc1c2003602f407200241043602f007200a4180a4c000201341024622131b200241f0076a20034198a4c00020131b2802101102000b200220013a00d30e200241800e3b00d10e200241013a00d00e0c040b024041002802d8a74c4104490d0041002802888040210141002802848040210341002802dca74c210a200241b0086a41b01b360200200241a8086a42db80808010370300200241a4086a41eec5c0003602002002419c086a420e37020020024198086a41e0c5c00036020020024190086a42003703002002418c086a4180a6cc0036020020024180086a4201370300200241f8076a4107360200200241d4bec2003602fc07200241bcc1c2003602f407200241043602f00720034180a4c000200a410246220a1b200241f0076a20014198a4c000200a1b2802101102000b200241003a00d30e200241003b00d10e200241013a00d00e0c030b024041002802d8a74c4104490d00200241163602cc132002200241d8116a3602c81341002802888040210141002802848040210341002802dca74c210a200241b0086a41c31b360200200241a8086a42db80808010370300200241a4086a41eec5c0003602002002419c086a420e37020020024198086a41e0c5c00036020020024190086a420137030020024180086a4202370300200241f8076a41073602002002418c086a200241c8136a360200200241ecbec2003602fc07200241bcc1c2003602f407200241043602f00720034180a4c000200a410246220a1b200241f0076a20014198a4c000200a1b2802101102000b200241a4086a410f36020020024190086a420037030020024188086a4280808080c000370300200241fcbec2003602a008200241013a00980820024204370380082002427f3703f8072002427f20022903a80d427f200241b00d6a290300501b220c42ffffffffffffffffff007c220d200d200c541b3703f00720022802d8112115411710272201450d0e200242173702cc13200220013602c813410f200241c8136a10710240024020022802cc13221420022802d01322136b410f490d002013410f6a210120022802c81321032014210a0c010b2013410f6a22012013490d10201441017422032001200320014b1b220a4100480d100240024020140d000240200a0d00410121030c020b200a102722030d010c130b20022802c81321032014200a460d0020032014200a102b2203450d120b2002200a3602cc13200220033602c8130b200320136a221341002900fcbe42370000201341076a4100290083bf42370000200220013602d013201528020021130240200a20016b41034b0d00200141046a22142001490d10200a41017422152014201520144b1b22144100480d1002400240200a0d00024020140d00410121030c020b201410272203450d130c010b200a2014460d002003200a2014102b2203450d120b200220143602cc13200220033602c8130b20024199086a210a200320016a2013360000200141046a210320022802c813211320022802cc13211402402002280294082201200228029008470d002002418c086a20014101109d0120022802940821010b200228028c082001410c6c6a220120033602082001201436020420012013360200200241d0136a2201200241f0076a41186a290300370300200220022802940841016a36029408200241c8136a41106a2203200241f0076a41206a290300370300200241d00e6a41106a42960137030020022002290380083703c8132002200a2900003703e8122002200a41076a2900003700ef12200220022903f0073703d80e200241d00e6a41186a20022903c813370300200241d00e6a41206a2001290300370300200241f80e6a2003290300370300200241800f6a41003a0000200241840f6a20022800eb12360000200241810f6a20022802e812360000200241003a00d00e0c080b200241d00e6a200241c40b6a10cd020c010b200241d00e6a200241c80b6a10ce020b20022d00d00e4101470d0520022f00d10e20022d00d30e4110747221010c010b200241003a00d30e418102210120024181023b00d10e200241013a00d00e0b200241013a0038200220013b0039200220014110763a003b02402000450d002000410c6c21012008210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b02402005450d002005410c6c450d00200810290b02402007450d002007410c6c21012009210003400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b2006450d072006410c6c450d07200910290c070b200220022d00f3073a003b200220022f00f1073b0039200241013a00380c070b200241fc006a4104360200200241c4046a4102360200200242023702b404200241a0d1c2003602b00420024104360274200241ccd2c200360270200241003602f40720024180a6cc003602f0072002200241f0006a3602c0042002200241f0076a360278200241b0046a41b0d1c2001040000b41a094cc00411941bc94cc001033000b20024198136a41286a2201200241d00e6a41306a29030037030020024198136a41206a2203200241d00e6a41286a29030037030020024198136a41186a220a200241d00e6a41206a221329030037030020024198136a41106a2214200241d00e6a41186a221529030037030020024198136a41086a2216200241d00e6a41106a290300370300200220022903d80e37039813200241d00e6a41086a200241c00e6a41086a290300370300200241f40e6a20073602002013200636020020152000360200200241e40e6a2005360200200220022903c00e3703d00e2002200b3703f80e200220093602ec0e200220083602e00e200241f0076a41286a2001290300370300200241f0076a41206a2003290300370300200241f0076a41186a200a290300370300200241f0076a41106a2014290300370300200241f0076a41086a201629030037030020022002290398133703f007200241c8136a200241d00e6a200241f0076a109703200241386a41086a20022903c813370300200241386a41106a200241c8136a41086a290300370300200241386a41186a200241c8136a41106a290300370300200241386a41206a200241c8136a41186a290300370300200241386a41286a200241c8136a41206a290300370300200241386a41306a200241c8136a41286a290300370300200241003a00380c030b200241023a003b200241800e3b0039200241013a00380c020b41808e0821050b200241013a0038200220053b0039200220054110763a003b0b200410cc0120022d003821010b410110272200450d00200242013702f40a200220003602f00a02400240200141ff01714101470d00200041013a0000200241013602f80a200241386a410172200241f00a6a10880320022802f80a21000c010b200041003a0000200241013602f80a200241c0006a290300210b024020022802f40a2201417f6a41074b0d00200141017422054109200541094b1b22054100480d03024020012005460d00200020012005102b2200450d050b200220053602f40a200220003602f00a0b2000200b370001200241093602f80a200241d0006a2802002101200241d8006a2802002200200241f00a6a107102402000450d0020012000410c6c6a2108034020012802002106200141086a2802002200200241f00a6a10710240024020022802f40a220320022802f80a22056b2000490d0020022802f00a21040c010b200520006a22042005490d05200341017422072004200720044b1b22074100480d050240024020030d00024020070d00410121040c020b200710272204450d080c010b20022802f00a210420032007460d00200420032007102b2204450d070b200220073602f40a200220043602f00a0b200420056a2006200010e4071a2002200520006a3602f80a2001410c6a22012008470d000b0b200241dc006a2802002101200241e4006a2802002200200241f00a6a10710240024020000d0020022802f40a210620022802f80a21000c010b20012000410c6c6a2108034020012802002107200141086a2802002200200241f00a6a10710240024020022802f40a220420022802f80a22056b2000490d0020022802f00a2103200421060c010b200520006a22032005490d05200441017422062003200620034b1b22064100480d050240024020040d00024020060d00410121030c020b200610272203450d080c010b20022802f00a210320042006460d00200320042006102b2203450d070b200220063602f40a200220033602f00a0b200320056a2007200010e4071a2002200520006a22003602f80a2001410c6a22012008470d000b0b200241c8006a290300210b02400240200620006b4108490d0020022802f00a21010c010b200041086a22012000490d03200641017422052001200520014b1b22054100480d030240024020060d00024020050d00410121010c020b200510272201450d060c010b20022802f00a210120062005460d00200120062005102b2201450d050b200220053602f40a200220013602f00a0b200120006a200b3700002002200041086a22003602f80a200241e8006a2d00002105024020022802f40a2000470d00200041016a22042000490d03200041017422032004200320044b1b22044100480d030240024020000d0041002100024020040d00410121010c020b200410272201450d060c010b20002004460d00200120002004102b2201450d050b200220043602f40a200220013602f00a0b200120006a20053a00002002200041016a22003602f80a0b2000ad42208620023502f00a84210b024020022d00380d000240200241d8006a2802002201450d00200241d0006a28020021002001410c6c210103400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b0240200241d4006a2802002200450d002000410c6c450d00200228025010290b0240200241e4006a2802002201450d00200241dc006a28020021002001410c6c210103400240200041046a280200450d00200028020010290b2000410c6a2100200141746a22010d000b0b200241e0006a2802002200450d002000410c6c450d00200228025c10290b20024180146a2400200b0f0b1039000b1032000b1030000b200241bc046a4104360200200241840b6a4102360200200242023702f40a200241a0d1c2003602f00a200241043602b404200241ccd2c2003602b0042002410036027420024180a6cc003602702002200241b0046a3602800b2002200241f0006a3602b804200241f00a6a41b0d1c2001040000bd00a04017f017e077f027e230041e0116b220224004202210302400240024002400240024020012903684202520d00200241b0076a20014198016a41a80210e4071a0c010b200241066a200141206a41c20010e4071a200241c8006a41186a200141186a290000370300200241c8006a41106a200141106a290000370300200241c8006a41086a200141086a29000037030020022001290000370348200241d80a6a20014198016a41a80210e4071a200241800d6a41286a2204200141e8006a220141286a290300370300200241800d6a41206a2205200141206a290300370300200241800d6a41186a2206200141186a290300370300200241800d6a41106a2207200141106a290300370300200241800d6a41086a2208200141086a290300370300200220012903003703800d200241c00e6a200241800d6a10820620022d00c00e210120022f00c10e210920022d00c30e210a200241f80d6a200241c00e6a41047241c80010e4071a20014101460d01200241b00d6a200241f80d6a41c80010e4071a200241c00e6a200241d80a6a41a80210e4071a20024190116a200429030037030020024188116a200529030037030020024180116a2006290300370300200241f8106a2007290300370300200241f0106a2008290300370300200220022903800d3703e810200241c00e6a41d8026a200241b00d6a41c80010e4071a200241b0076a41046a200241c00e6a41a00310e4071a20024188046a200241b0076a41a40310e4071a200241e8006a20024188046a41046a41a00310e4071a410810272201450d03200242083702b407200220013602b007200241e8006a200241b0076a10bf0220024190036a200241b0076a10be02200241e8006a41d8026a200241b0076a10800620022802b407210520022802b00721010240024020022802b80722044180024b0d00200241066a20012004200241c8006a10d60621040c010b2004ad4220862001ad84101022042900002103200441086a290000210b200441106a290000210c200241b0076a41186a200441186a290000370300200241b0076a41106a200c370300200241b0076a41086a200b370300200220033703b00720041029200241066a200241b0076a4120200241c8006a10d60621040b02402005450d00200110290b2004450d02200241c00e6a41086a200241c8006a41086a290300370300200241c00e6a41106a200241c8006a41106a290300370300200241c00e6a41186a200241c8006a41186a29030037030020024188046a41086a200241a0036a29030037030020024188046a41106a200241a8036a29030037030020024188046a41186a200241b0036a290300370300200241a8046a200241b8036a290300370300200220022903483703c00e200220024198036a290300370388042002290390032103200241b0076a200241e8006a41a80210e4071a0b200041086a20022903c00e370300200041286a2003370300200041306a200229038804370300200041206a200241c00e6a41186a290300370300200041186a200241c00e6a41106a290300370300200041106a200241c00e6a41086a290300370300200041386a20024188046a41086a290300370300200041c0006a20024188046a41106a290300370300200041c8006a20024188046a41186a290300370300200041d0006a20024188046a41206a290300370300200041d8006a200241b0076a41a80210e4071a200041003a00000c030b200241d80a6a10cc01200041036a2009200a4110747222014110763a0000200020013b0001200041013a00000c020b20004180083b0001200041013a0000200041036a41003a0000200241e8006a10cc010c010b1039000b200241e0116a24000bc10304017f027e067f017e230041206b22032400200229030021042001290300210520022802102106200141106a200141186a2207280200200241186a22082802002209109d0120012802102007280200220a410c6c6a20062009410c6c10e4071a200841003602002007200a20096a2209360200200341086a200936020020032001290210370300200228021c21082001411c6a200141246a2207280200200241246a220a2802002209109d01200128021c2007280200220b410c6c6a20082009410c6c10e4071a200a41003602002007200b20096a2209360200200341106a41086a20093602002003200129021c370310427f200520047c220420042005541b2105200229030822042001290308220c200c2004561b21040240024020012d0028450d004101210120022d00280d010b410021010b20002005370300200020032903003702102000200329031037021c200020013a002820002004370308200041186a200341086a280200360200200041246a200341106a41086a2802003602000240200241146a2802002201450d002001410c6c450d00200610290b0240200241206a2802002201450d002001410c6c450d00200810290b200341206a24000b920303047f017e017f230041e0006b22032400200341306a41186a4200370300200341306a41106a22044200370300200341306a41086a220542003703002003420037033041b3e6ca00ad4280808080e000841001220629000021072005200641086a290000370300200320073703302006102941e8a0cb00ad4280808080800284100122062900002107200341d0006a41086a2208200641086a2900003703002003200737035020061029200420032903502207370300200341106a41086a2005290300370300200341106a41106a2007370300200341106a41186a200829030037030020032003290330370310200341086a200341106a412010fc014100210502400240417f200328020c410020032802081b220620026a220220022006491b22064280808080f28ba80942808080c0f588fe06200141ff01711b22072007428094ebdc038022074280ec94a37c7e7c4280cab5ee01562007a76a4b0d00200041046a20063602000c010b200041800c3b0001200041036a41003a0000410121050b200020053a0000200341e0006a24000b1c00200128021841b09bcc00410f2001411c6a28020028020c1100000b0e002000280200350200200110460bc73f09057f017e057f017e047f017e037f017e0d7f230022022103200241c0046b41607122022400024002402001450d00200220003602400c010b20024180a6cc003602400b20022001360244200241c0026a200241c0006a10f802024002400240024002400240024020022802c402450d00200241c8006a200241c0026a41f00010e4071a200241b8016a200241c8006a109c032002280248200241d8006a20024198016a200241b8016a4100109d03410041002802dca74c2201410120011b3602dca74c0240200141014b0d000240024020010e020001000b410041f8a0c000360288804041004180a6cc003602848040410041023602dca74c0c010b034041002802dca74c4101460d000b0b2002410020022802482201417f6a2200200020014b1b22043602c401100d4101470d01200241c0026a41186a22054200370300200241c0026a41106a22004200370300200241c0026a41086a22014200370300200242003703c00241c6b7c700ad42808080808001841001220629000021072001200641086a290000370300200220073703c0022006102941ceb7c700ad4280808080e00184100122082900002107200241f0016a41086a2206200841086a290000370300200220073703f00120081029200020022903f0012207370300200241e0036a41086a22092001290300370300200241e0036a41106a220a2007370300200241e0036a41186a220b2006290300370300200220022903c0023703e003200241386a200241e0036a412010fc01410021080240200228023c410020022802381b220c20044d0d00200241e0036a2100200241c8016a21010c060b200542003703002000420037030020014200370300200242003703c00241b1dcc900ad4280808080f00084220710012208290000210d2001200841086a2900003703002002200d3703c00220081029418886ca00ad4280808080c0018410012208290000210d2006200841086a2900003703002002200d3703f00120081029200020022903f001220d37030020092001290300370300200a200d370300200b2006290300370300200220022903c0023703e003200241306a200241e0036a412010fc012002280234210e2002280230210f200542003703002000420037030020014200370300200242003703c00220071001220829000021072001200841086a290000370300200220073703c0022008102941b8dcc900ad4280808080a001841001220829000021072006200841086a290000370300200220073703f00120081029200020022903f001220737030020092001290300370300200a2007370300200b2006290300370300200220022903c0023703e003200241c8016a200241e0036a108d020240024020022802c80122010d00410021100c010b20022902cc012207422088a72110200742ffffff3f83500d00200110290b200241c0026a41186a22084200370300200241c0026a41106a22054200370300200241c0026a41086a22014200370300200242003703c00241c6b7c700ad42808080808001841001220629000021072001200641086a290000370300200220073703c0022006102941dcb7c700ad4280808080c00084100122062900002107200241f0016a41086a2209200641086a290000370300200220073703f00120061029200020022903f001370000200041086a2009290300370000200241e0036a41086a2001290300370300200241e0036a41106a2005290300370300200241e0036a41186a2008290300370300200220022903c0023703e003200241c0026a200241e0036a109e0320022802c002211120022902c4022112200241c0026a41e9dabdf306109f0320022802c002210820022802c402210902400240024020022802c80222000d004100211341012114410021150c010b02400240024020004105742201410575220641ffffff3f712006470d0020014100480d0020010d01410121140c020b1032000b200110272214450d020b200820016a210a2000410574210520014105762113410021010340200820016a22002900002107200041086a290000210d200041106a2900002116201420016a220641186a200041186a290000370000200641106a2016370000200641086a200d370000200620073700002005200141206a2201470d000b200a20086b41606a41057641016a21150b0240200941ffffff3f71450d00200810290b20154115490d0402404101450d0020154104744160712217417f4c0d000240201710272218450d00200241003602e803200242043703e003201441606a2119201441a07f6a211a41042106410021014100211b2015211c0340201c210b4100211c4101210a0240200b417f6a2205450d00024002400240024002400240201420054105746a200b410574221d20146a41406a412010e7074100480d00200b417e6a2109201a201d6a21004100211c410021080340024020092008470d00200b210a0c080b200841016a2108200041206a2000412010e7072105200041606a21002005417f4a0d000b200841016a210a2008417f73200b6a21050c010b201a201d6a210002400340024020054101470d00410021050c020b2005417f6a2105200041206a2000412010e7072108200041606a210020084100480d000b0b200b2005490d01200b20154b0d02200b20056b220a4101762209450d002019201d6a2100201420054105746a21080340200241c0026a41186a221d200841186a221e290000370300200241c0026a41106a221f200841106a2220290000370300200241c0026a41086a220c200841086a221c290000370300200220082900003703c002200041086a22212900002107200041106a2222290000210d200041186a2223290000211620082000290000370000201e20163700002020200d370000201c20073700002023201d2903003700002022201f2903003700002021200c290300370000200020022903c002370000200041606a2100200841206a21082009417f6a22090d000b0b0240200a41094d0d002005211c0c050b024020050d002005211c0c050b200b20154b0d02200b20056b2109201420054105746a211d0340200b2005417f6a221c490d040240200b201c6b220a4102490d00201420054105746a22002014201c4105746a2205412010e707417f4a0d00200241c0026a41186a220c200541186a2208290000370300200241c0026a41106a2221200541106a221e290000370300200241c0026a41086a2222200541086a221f290000370300200220052900003703c00220052000290000370000201f200041086a290000370000201e200041106a2900003700002008200041186a290000370000410121200240200a4103490d00200541c0006a200241c0026a412010e707417f4a0d0041022108201d210002400340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a221e29000037000020092008460d01200041c0006a211f20082120201e2100200841016a2108201f200241c0026a412010e707417f4a0d020c000b0b200821200b200520204105746a220020022903c002370000200041186a200c290300370000200041106a2021290300370000200041086a20222903003700000b201c450d05201d41606a211d200941016a2109201c2105200a410a4f0d050c000b0b2005200b4180cac700104c000b200b20154180cac700104b000b200b2005417f6a221c490d00200b20154190cac700104b000b201c200b4190cac700104c000b0240201b20022802e403470d00200241e0036a201b4101108d0120022802e003210620022802e8032201211b0b2006201b4103746a2200200a3602042000201c3602002002200141016a22013602e8032001211b024020014102490d000240024003400240024002400240024020062001417f6a4103746a2200280200450d00200141037420066a220941746a2802002205200028020422084b0d010b20014103490d022000280204210820062001417d6a221f4103746a28020421000c010b4102211b200141024d0d0620062001417d6a221f4103746a2802042200200820056a4d0d004103211b200141034d0d06200941646a280200200020056a4b0d050b20002008490d010b2001417e6a211f0b02400240024002400240024002402001201f41016a22204d0d002001201f4d0d012006201f41037422216a2201280204222220012802006a22012006202041037422236a2200280200220c490d02200120154b0d032014200c4105746a221d2000280204221e41057422006a2108200141057421062001200c6b2209201e6b2201201e4f0d04201820082001410574220010e407220b20006a2105201e4101480d0520014101480d05201920066a21062008210103402006200141606a2208200541606a220920092008412010e707410048220a1b2200290000370000200641186a200041186a290000370000200641106a200041106a290000370000200641086a200041086a29000037000020052009200a1b21050240201d20082001200a1b2201490d00200b21000c080b200641606a2106200b2100200b2005490d000c070b0b2020200141a0cac7001036000b201f200141b0cac7001036000b200c200141c0cac700104c000b2001201541c0cac700104b000b2018201d200010e407220b20006a21050240201e4101480d002009201e4c0d00201420066a210a200b2100201d2101034020012008200020082000412010e70741004822091b2206290000370000200141186a200641186a290000370000200141106a200641106a290000370000200141086a200641086a2900003700002000200041206a20091b2100200141206a2101200841206a200820091b2208200a4f0d03200520004b0d000c030b0b201d2101200b21000c010b20082101200b21000b20012000200520006b41607110e4071a024020022802e8032201201f4d0d0020022802e003220620216a22002022201e6a3602042000200c360200200120204d0d02200620236a2200200041086a20012020417f736a41037410e5071a20022001417f6a22013602e803200141014b0d010c030b0b201f200141d0cac7001036000b202020011042000b2001211b0b201c450d060c000b0b1039000b1038000b1030000b200241ec036a4104360200200241dc006a41023602002002420237024c200241a0d1c200360248200241043602e403200241e8d2c2003602e003200241003602f40120024180a6cc003602f0012002200241e0036a3602582002200241f0016a3602e803200241c8006a41b0d1c2001040000b41002802d8a74c4105490d042002410c3602e4032002200241c4016a3602e00341002802888040210141002802848040210041002802dca74c210620024180036a418103360200200241f8026a42dd80808010370300200241f4026a4198cbc700360200200241ec026a4210370200200241e8026a4188cbc700360200200241e0026a4201370300200241d0026a4202370300200241c0026a41086a4108360200200241dc026a200241e0036a360200200241f0cac7003602cc0220024180cbc7003602c402200241053602c00220004180a4c000200641024622061b200241c0026a20014198a4c00020061b2802101102000c040b024020022802e40341ffffffff0171450d00200610290b2017450d01201810290c010b20154102490d0020142015417f6a22004105746a21054101210603400240024002400240201520002201417f6a2200490d00201520006b22094102490d03201420014105746a2201201420004105746a2208412010e707417f4a0d03200241c0026a41186a221e200841186a220a290000370300200241c0026a41106a221f200841106a220b290000370300200241c0026a41086a2220200841086a221d290000370300200220082900003703c00220082001290000370000201d200141086a290000370000200b200141106a290000370000200a200141186a2900003700004101210120094103490d02200841c0006a200241c0026a412010e707417f4a0d0241002109200521010340200141186a200141386a290000370000200141106a200141306a290000370000200141086a200141286a2900003700002001200141206a220b29000037000020062009220a460d02200a417f6a2109200141c0006a211d200b2101201d200241c0026a412010e707417f4a0d020c000b0b2000201541f0c9c700104c000b4102200a6b21010b200820014105746a220120022903c002370000200141186a201e290300370000200141106a201f290300370000200141086a20202903003700000b200541606a21052006417f6a210620000d000b0b200220103602e801200220043602e4012002200e4100200f1b22013602e001200220153602dc01200220133602d801200220143602d401200241003602d0012002201036028004200220043602fc03200220013602f803200220153602f403200220133602f003200220143602ec03200241003602e80320022011410120111b22083602e003200220083602c801200220082012420020111b2207422088a74105746a22013602e403200220013602cc012007a7210c200241e0036a2100200241c8016a21010b20024198026a41086a2206200141086a29020037030020024198026a41106a220a200141106a29020037030020024198026a41186a220b200141186a29020037030020024198026a41206a221d200141206a280200360200200241f0016a41086a221e200241c0026a41086a2205290200370300200241f0016a41106a221f200241c0026a41106a290200370300200241f0016a41186a2220200241c0026a41186a290200370300200241f0016a41206a221c200241c0026a41206a2902003703002002200129020037039802200220022902c0023703f001200241c8016a41206a2201200241e0036a41206a290200370300200241c8016a41186a2214200241e0036a41186a290200370300200241c8016a41106a2221200241e0036a41106a290200370300200241c8016a41086a2222200241e0036a41086a290200370300200220022902e0033703c8012005200c360200200220083602c402200241013602c002200241cc026a2208200229039802370200200241d4026a22052006290300370200200241dc026a2209200a290300370200200241e4026a220a200b290300370200200241ec026a201d280200360200200241003602f002200241f4026a20022903f001370200200241fc026a201e29030037020020024184036a201f2903003702002002418c036a202029030037020020024194036a201c2903003702002002410036029c03200241c0036a2001290300370300200241b8036a2014290300370300200241b0036a2021290300370300200241a8036a2022290300370300200241a0036a20022903c80137030020024190036a211d200241f8026a21012002419c036a2114200241f0026a212020024180036a211e20024188036a211f410021060340024002402006450d00200241286a202010a0030240200228022822064108460d00200228022c211c0c020b024020022802f0022206450d00024020022802f40241ffffff3f71450d00200610290b20022802880341ffffff3f71450d0020022802840310290b20012000290200370200200141086a200041086a290200370200200141106a200041106a290200370200200141186a200041186a290200370200200141206a200041206a2802003602002002200c3602f402200241003602f0020b2009290200210d200920022903f80337020020052902002116200520022903f00337020020082902002112200820022903e803370200200241d0036a41086a220b200a41086a280200360200200241003602e0032002200a2902003703d00320022902c4022107200220022903e0033702c40202402007a72206450d00201d20022903d00337020020012012370300201e2016370300201d41086a200b280200360200201f200d370300200220073703f0020c020b0240200228029c030d00410821060c010b200241206a201410a0032002280224211c200228022021060b02400240200641796a220b41014b0d000240200b0e020200020b024020022802c002450d0020022802c4022201450d00024020022802c80241ffffff3f71450d00200110290b200241dc026a28020041ffffff3f71450d00200241d8026a28020010290b024020022802f0022201450d00024020022802f40241ffffff3f71450d00200110290b20022802880341ffffff3f71450d0020022802840310290b200228029c032201450d030240200241a0036a28020041ffffff3f71450d00200110290b200241b4036a28020041ffffff3f71450d03200241b0036a28020010290c030b2002201c3602cc03200220063602c80341002802d8a74c4104490d00200241173602dc032002410c3602d4032002200241c8036a3602d8032002200241c4016a3602d00341002802888040210641002802848040210b41002802dca74c211c200241f8023602a004200242dd808080103703980420024198cbc700360294042002421037028c0420024188cbc700360288042002420237038004200242023703f003200241e0cac7003602ec03200241083602e80320024180cbc7003602e403200241043602e00320064198a4c000201c410246221c1b28021021062002200241d0036a3602fc03200b4180a4c000201c1b200241e0036a20061102000b20022802f00221060c000b0b200241c0026a41186a4200370300200241c0026a41106a22064200370300200241c0026a41086a22014200370300200242003703c00241eebec500ad4280808080f000841001220029000021072001200041086a290000370300200220073703c0022000102941eab8c000ad4280808080900284100122002900002107200241f0016a41086a2208200041086a290000370300200220073703f00120001029200620022903f0012207370300200241e0036a41086a2001290300370300200241e0036a41106a2007370300200241e0036a41186a2008290300370300200220022903c0023703e003200241186a200241e0036a10b101024020022802184101470d00200228021c2004470d00200241f0016a410041bec0c200ad4280808080800384100e108b0202400240024020022802f0012201450d00200241f8016a2802004104490d00024002402001280000220020044d0d004105210041f5c0c20021060c010b200041056a2004490d014112210041fac0c20021060b20022802f401450d01200110290c010b2002200436029802200220043602c801200241e0036a41086a200241f0016a41086a280200360200200220022903f0013703e003200241c0026a200241e0036a10e60220022802c4022101410041bec0c200ad428080808080038420023502c80242208620022802c0022206ad84200241c8016aad4280808080c00084100f210002402001450d00200610290b024020022802e0032201450d0020022802e403450d00200110290b20004101460d01411f210041d6c0c20021060b200220003602f401200220063602f00141002802d8a74c4104490d01200241043602e4032002200241f0016a3602e00341002802888040210141002802848040210041002802dca74c210620024180036a41b20a360200200241f8026a42db80808010370300200241f4026a41eec5c000360200200241ec026a420e370200200241e8026a41e0c5c000360200200241e0026a4201370300200241d0026a4202370300200241c8026a4107360200200241dc026a200241e0036a360200200241ecc7c0003602cc02200241bcc1c2003602c402200241043602c00220004180a4c000200641024622061b200241c0026a20014198a4c00020061b2802101102000c010b024010d60241ff017122014108470d0041002802d8a74c4104490d0141002802888040210141002802848040210041002802dca74c210620024180036a41b70a360200200241f8026a42db80808010370300200241f4026a41eec5c000360200200241ec026a420e370200200241e8026a41e0c5c000360200200241e0026a4200370300200241dc026a4180a6cc00360200200241d0026a4201370300200241c8026a410736020020024184c8c0003602cc02200241bcc1c2003602c402200241043602c00220004180a4c000200641024622061b200241c0026a20014198a4c00020061b2802101102000c010b200220013a00f00141002802d8a74c450d002002410f3602e4032002200241f0016a3602e00341002802888040210141002802848040210041002802dca74c210620024180036a41b50a360200200241f8026a42db80808010370300200241f4026a41eec5c000360200200241ec026a420e370200200241e8026a41e0c5c000360200200241e0026a4201370300200241d0026a4201370300200241c8026a4107360200200241dc026a200241e0036a360200200241fcc7c0003602cc02200241bcc1c2003602c402200241013602c00220004180a4c000200641024622061b200241c0026a20014198a4c00020061b2802101102000b20022802b8012108024020022802c0012201450d00200141246c21002008210103400240024020012d0000220641044b0d0002400240024020060e050400010204040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b024020022802bc012201450d00200141246c450d00200810290b200228024c21080240200241c8006a410c6a2802002201450d00200141246c21002008210103400240024020012d0000220641044b0d0002400240024020060e050400010204040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b0240200241d0006a2802002202450d00200241246c450d00200810290b2003240042010b8504010d7f230041306b220224002002410036020820024204370300024002400240024002402001410c6a28020041246c2203450d002001280204210141042104410021050340024020012d00004101470d00200141106a2802002206417f4c0d03200141036a2d00002107200141016a2f00002108200141086a2802002109200141046a2d0000210a0240024020060d004100210b4101210c0c010b20061027220c450d052006210b0b02400240200b2006490d00200b210d0c010b200b410174220d2006200d20064b1b220d4100480d060240200b0d00200d1027220c0d010c080b200b200d460d00200c200b200d102b220c450d070b20082007411074722107200c2009200610e407210c200241206a41086a2208200241106a41086a29020037030020022002290210370320200e41807e71200a72210e024020052002280204470d0020022005410110960120022802002104200228020821050b2004200541246c6a220b2006360210200b200d36020c200b200c360208200b200e360204200b20073b0001200b41013a0000200b41036a20074110763a0000200b2002290320370214200b411c6a20082903003702002002200541016a22053602080b200141246a21012003415c6a22030d000b0b20002002290300370200200041086a200241086a280200360200200241306a24000f0b1038000b1039000b1032000b1030000baa1407027f017e037f017e017f017e047f230041d0006b220524004102200510fe05410021062005410036022041a6e5ca00ad4280808080800284200541206aad4280808080c0008422071003200541206a41186a22084200370300200541206a41106a22094200370300200541206a41086a220a42003703002005420037032041b3e6ca00ad4280808080e00084220b1001220c290000210d200541c0006a41086a220e200c41086a2900003703002005200d370340200c1029200a200e2903003703002005200529034037032041c9e6ca00ad4280808080e000841001220c290000210d200e200c41086a2900003703002005200d370340200c102920092005290340220d370300200541086a220f200a290300370300200541106a2210200d370300200541186a2211200e29030037030020052005290320370300200520003602202005ad4280808080800484220d200710032008420037030020094200370300200a420037030020054200370320200b1001220c2900002107200e200c41086a29000037030020052007370340200c1029200a200e2903003703002005200529034037032041e7e6ca00ad4280808080e000841001220c2900002107200e200c41086a29000037030020052007370340200c1029200920052903402207370300200f200a290300370300201020073703002011200e2903003703002005200529032037030002400240024002402003280208220e41246c41046a220a417f4c0d002003280200210802400240200a0d00410121030c010b200a10272203450d03200a21060b200541003602482005200336024020052006360244200e200541c0006a107102400240200e0d002005280248210a2005280244210c2005280240210f0c010b200e41246c2111200528024421032005280248210e0340200541206a200810bc0220052802202110024002402003200e6b20052802282206490d00200e20066a210a2005280240210f2003210c0c010b200e20066a220a200e490d042003410174220c200a200c200a4b1b220c4100480d040240024020030d000240200c0d004101210f0c020b200c1027220f0d010c080b2005280240210f2003200c460d00200f2003200c102b220f450d070b2005200c3602442005200f3602400b200f200e6a2010200610e4071a2005200a36024802402005280224450d00201010290b200841246a2108200c2103200a210e2011415c6a22110d000b0b200d200aad422086200fad8410030240200c450d00200f10290b200541206a41186a220c4200370300200541206a41106a22084200370300200541206a41086a220a42003703002005420037032041b3e6ca00ad4280808080e00084100122032900002107200541c0006a41086a220e200341086a2900003703002005200737034020031029200a200e2903003703002005200529034037032041cfe6ca00ad4280808080a00184100122032900002107200e200341086a290000370300200520073703402003102920092005290340370000200941086a200e290300370000200541086a200a290300370300200541106a2008290300370300200541186a200c2903003703002005200529032037030041201027220e450d02200e2001290000370000200e41186a200141186a290000370000200e41106a200141106a290000370000200e41086a200141086a290000370000200d200ead42808080808004841003200e1029200541206a2000417f6a10fb02200535022821072005280220210a41201027220e450d02200e2001290000370000200e41186a200141186a290000370000200e41106a200141106a290000370000200e41086a200141086a2900003700002007422086200aad84200ead42808080808004841003200e102902402005280224450d00200a10290b200541206a41186a220c4200370300200541206a41106a22084200370300200541206a41086a220a42003703002005420037032041b3e6ca00ad4280808080e00084220710012203290000210b200541c0006a41086a220e200341086a2900003703002005200b37034020031029200a200e2903003703002005200529034037032041d9e6ca00ad4280808080e0018410012203290000210b200e200341086a2900003703002005200b3703402003102920092005290340370000200941086a200e290300370000200541086a200a290300370300200541106a2008290300370300200541186a200c2903003703002005200529032037030041201027220e450d02200e2002290000370000200e41186a200241186a290000370000200e41106a200241106a290000370000200e41086a200241086a290000370000200d200ead42808080808004841003200e1029200541206a41186a22034200370300200541206a41106a220c4200370300200541206a41086a220a4200370300200542003703202007100122082900002107200541c0006a41086a220e200841086a2900003703002005200737034020081029200a200e2903003703002005200529034037032041b4a0cb00ad4280808080b00184100122082900002107200e200841086a290000370300200520073703402008102920092005290340370000200941086a2208200e290300370000200541086a2206200a290300370300200541106a220f200c290300370300200541186a2210200329030037030020052005290320370300200d100402402004450d0020034200370300200c4200370300200a42003703002005420037032041b3e6ca00ad4280808080e00084220710012211290000210b200e201141086a2900003703002005200b37034020111029200a200e2903003703002005200529034037032041eaf9ca00ad4280808080e0008410012211290000210b200e201141086a2900003703002005200b37034020111029200920052903403700002008200e2903003700002006200a290300370300200f200c2903003703002010200329030037030020052005290320370300200d100420034200370300200c4200370300200a420037030020054200370320200710012211290000210b200e201141086a2900003703002005200b37034020111029200a200e2903003703002005200529034037032041e0a2cb00ad4280808080a0018410012211290000210b200e201141086a2900003703002005200b37034020111029200920052903403700002008200e2903003700002006200a290300370300200f200c2903003703002010200329030037030020052005290320370300200d100420034200370300200c4200370300200a4200370300200542003703202007100122112900002107200e201141086a2900003703002005200737034020111029200a200e2903003703002005200529034037032041f0f9ca00ad4280808080b00184100122112900002107200e201141086a2900003703002005200737034020111029200920052903403700002008200e2903003700002006200a290300370300200f200c2903003703002010200329030037030020052005290320370300200d10060b200541d0006a24000f0b1038000b1032000b1039000b1030000b8b06010d7f23004190016b220224002002412036021420022001360210200241186a2001ad42808080808004841007108b020240024002400240200228021822030d00200041003602000c010b200228021c21042002200241206a28020036022c20022003360228200241086a200241286a10c8010240024020022802080d00200228020c2205200228022c22064105762201200120054b1b22014105742207417f4c0d030240024020010d00410121080c010b200710272208450d050b41002109200241003602402002200136023c20022008360238024002402005450d004100210a03402006210b41002101200241003a008801200a41016a210a0340200b2001460d03200241e8006a20016a200228022822072d00003a00002002200741016a3602282002200141016a22073a0088012007210120074120470d000b200241c8006a41186a220c200241e8006a41186a290300370300200241c8006a41106a220d200241e8006a41106a290300370300200241c8006a41086a220e200241e8006a41086a2903003703002002200229036837034802402009200228023c470d00200241386a20094101109e0120022802382108200228024021090b200b20076b2106200820094105746a22012002290348370000200141186a200c290300370000200141106a200d290300370000200141086a200e2903003700002002200941016a2209360240200a2005470d000b2002200b20076b36022c0b2008450d012000200229023c370204200020083602000c020b2002410036022c0240200141ff0171450d00200241003a0088010b200228023c41ffffff3f71450d00200810290b20024100360250200242013703482002410d36023c2002200241106a3602382002200241c8006a360234200241fc006a41013602002002420137026c200241f4eaca003602682002200241386a360278200241346a41a8a3c800200241e8006a10371a200235025042208620023502488410080240200228024c450d00200228024810290b200041003602000b2004450d00200310290b20024190016a24000f0b1038000b1039000bf30505017f017e0a7f017e027f230041e0006b220224002002200136020c0240024002402002410c6a10202203422088a722010d0020004100360208200042013702000c010b2002200136021420022003a722043602102002200241106a10c80120022802000d0102400240024020022802042205200228021422064105762201200120054b1b22014105742207417f4c0d0002400240024020010d00410121080c010b200710272208450d010b2001ad21032005450d024100210903402006210a200241003a0058200941016a2109410021010240024002400340200a2001460d01200241386a20016a200228021022072d00003a00002002200741016a3602102002200141016a22073a00582007210120074120470d000b200241186a41186a220b200241386a41186a290300370300200241186a41106a220c200241386a41106a290300370300200241186a41086a220d200241386a41086a290300370300200220022903383703182003422088220ea722012003a7460d012001210f0c020b200241003602140240200141ff0171450d00200241003a00580b200342ffffff3f83500d08200810290c080b0240024002400240200141016a22062001490d00200ea7220f4101742210200620062010491b220641ffffff3f712006470d00200641057422064100480d00024020010d0020060d02410121080c040b2006200f4105742201460d03024020010d0020060d02410121080c040b200820012006102b2208450d020c030b1032000b2006102722080d010b1030000b2006410576ad21030b200a20076b21062008200f4105746a22012002290318370000200141186a200b290300370000200141106a200c290300370000200141086a200d290300370000200342ffffffff0f83200f41016aad42208684210320092005470d000b2002200a20076b3602140c030b1039000b1038000b2008450d020b2000200337020420002008360200200410290b200241e0006a24000f0b41e891cc00412e200241386a41d891cc0041dc90cc00103a000bb723030b7f047e0b7f230041c0066b2202240002400240024020012802082203200128020c2204460d002001200341206a22053602082001280210210620024180036a41186a200341186a29000037030020024180036a41106a200341106a29000037030020024180036a41086a200341086a2900003703002002200329000037038003200128021421074100210802400240024002402001411c6a280200220941014b0d0020090e020201020b2009210a0340200a410176220b20086a220c20082007200c4105746a20024180036a412010e7074101481b2108200a200b6b220a41014b0d000b0b200720084105746a20024180036a412010e7070d002006210c0c010b2001200641016a220c3602104108210820052004460d020240200941014d0d0003402001200541206a220336020820024180036a41186a200541186a29000037030020024180036a41106a200541106a29000037030020024180036a41086a200541086a2900003703002002200529000037038003410021082009210a0340200a410176220520086a220b20082007200b4105746a20024180036a412010e7074101481b2108200a20056b220a41014b0d000b200720084105746a20024180036a412010e707450d022001200c41016a220c3602102003210520032004460d030c000b0b0240024020090e020100010b03402001200541206a220836020820024180036a41186a200541186a29000037030020024180036a41106a200541106a29000037030020024180036a41086a200541086a29000037030020022005290000370380030240200720024180036a412010e7070d00410021080c030b2001200c41016a220c3602102008210520042008460d030c000b0b2001200436020820012006200420036b41406a4105766a41026a3602100c020b024002400240024002400240024002400240200920084d0d00200241086a41186a200720084105746a220841186a290000220d370300200241086a41106a200841106a290000220e370300200241086a41086a200841086a290000220f3703002002200829000022103703082001200c41016a360210200141286a2802002111200141206a2802002108200141246a280200210a200241286a41186a200d370300200241286a41106a200e370300200241286a41086a200f370300200220103703282002200a360254200220083602502002200c36024c20024180036a41186a420037030020024180036a41106a2205420037030020024180036a41086a22084200370300200242003703800341b1dcc900ad4280808080f000841001220a290000210d2008200a41086a2900003703002002200d37038003200a102941b8dcc900ad4280808080a001841001220a290000210d200241c0026a41086a220b200a41086a2900003703002002200d3703c002200a1029200520022903c002220d370300200241d8006a41086a2008290300370300200241d8006a41106a200d370300200241d8006a41186a200b290300370300200220022903800337035820024180036a200241d8006a108d022002280280032208410120081b210a02400240200c200229028403420020081b220d422088a7490d00200d42ffffff3f83500d01200a1029200228024c210c0c010b200c200a200c4105746a10930621050240200d42ffffff3f83500d00200a10290b41022108200228024c210c20050d0c0b2002280254210620022802502112411b10272208450d01200841176a41002800f3ce47360000200841106a41002900ecce47370000200841086a41002900e4ce47370000200841002900dcce4737000041041027220a450d01200a200c3600002008411b4136102b2209450d082009200a28000036001b200a1029200241c0026a41002009ad4280808080f00384220d100e108b02024002400240024020022802c0022208450d00200241c8026a280200220a4104490d00200a417c714104460d0041000d0020082800002012470d002008280004220a41036a20064b0d010b410410272208450d0b20082012360000200841044108102b2208450d0b20082006360004200241d8006a41086a200241c0026a41086a280200360200200220022903c00237035820024180036a200241d8006a10e602200228028403210a4100200d200235028803422086200228028003220bad842008ad4280808080800184100f21050240200a450d00200b10290b02402002280258220a450d00200228025c450d00200a10290b200810294104210820054101460d022006210a0c010b024020022802c402450d00200810290b410121080b20091029200a210c0c0c0b20024180036a1094062002280280032213450d0320024194036a280200211420024190036a28020021152002418c036a280200211620024188036a2802002117200228028403211820024100360288032002420137038003410410272208450d0820024104360284032002200836028003200820063600002002410436028803201720024180036a107102400240200228028403220520022802880322086b2017490d00200228028003210a0c010b200820176a220a2008490d082005410174220b200a200b200a4b1b220b4100480d080240024020050d000240200b0d004101210a0c020b200b1027220a0d010c0b0b200228028003210a2005200b460d00200a2005200b102b220a450d0a0b2002200b360284032002200a360280030b200a20086a2013201710e4071a2002200820176a36028803201420024180036a10712014450d0220162014410c6c6a21032016210a0340200a2802002104200a41086a280200220820024180036a107102400240200228028403220b20022802880322056b2008490d002002280280032107200b21010c010b200520086a22072005490d09200b41017422012007200120074b1b22014100480d0902400240200b0d00024020010d00410121070c020b200110272207450d0c0c010b2002280280032107200b2001460d002007200b2001102b2207450d0b0b200220013602840320022007360280030b200720056a2004200810e4071a2002200520086a220836028803200a410c6a220a2003470d000c050b0b2008200941cccec7001036000b1039000b200228028403210120022802880321080c010b41012108410521060c010b02400240200120086b4104490d00200228028003210a200121050c010b200841046a220a2008490d0320014101742205200a2005200a4b1b22054100480d030240024020010d00024020050d004101210a0c020b20051027220a450d060c010b200228028003210a20012005460d00200a20012005102b220a450d050b20022005360284032002200a360280030b200a20086a20123600002002200841046a220b3602880302402005200b6b41034b0d00200b41046a2207200b490d03200541017422012007200120074b1b22074100480d030240024020050d00024020070d004101210a0c020b20071027220a450d060c010b20052007460d00200a20052007102b220a450d050b20022007360284032002200a360280030b200a200b6a200c3600002002200841086a22053602880302400240200228028403220b20056b4104490d00200228028003210a200b21070c010b200541046a220a2005490d03200b4101742207200a2007200a4b1b22074100480d0302400240200b0d00024020070d004101210a0c020b20071027220a450d060c010b200228028003210a200b2007460d00200a200b2007102b220a450d050b20022007360284032002200a360280030b200a20056a201136000020024180036a41e9dabdf306200241286a200a2008410c6a109506410121080240024020022d0080034101460d00410321050c010b200241fe026a20022d0083033a0000200241c0026a41086a20024194036a290200370300200241d0026a2002419c036a290200370300200241d8026a200241a4036a290200370300200241e0026a200241ac036a290200370300200241e8026a200241b4036a290200370300200241ed026a200241b9036a290000370000200220022f0081033b01fc02200220024180036a410c6a2902003703c00220024180036a41086a280200210b4100210820022802840321050b200241bc026a41026a2201200241fc026a41026a2d00003a000020024180026a41086a2204200241c0026a41086a29030037030020024180026a41106a2203200241c0026a41106a29030037030020024180026a41186a2219200241c0026a41186a29030037030020024180026a41206a221a200241c0026a41206a29030037030020024180026a41286a221b200241c0026a41286a29030037030020024180026a41306a200241c0026a41306a290300370300200220022f01fc023b01bc02200220022903c00237038002024020080d00200241fc016a41026a20012d00003a000020024180036a41086a200429030037030020024180036a41106a200329030037030020024180036a41186a201929030037030020024180036a41206a201a29030037030020024180036a41286a201b29030037030020024180036a412d6a20024180026a412d6a290000370000200220022f01bc023b01fc0120022002290380023703800302402007450d00200a10290b200220022f01fc013b01c0022002200241fe016a2d00003a00c202410021080c020b02402007450d00200a10290b02402018450d00201310290b02402014450d002014410c6c210a2016210803400240200841046a280200450d00200828020010290b2008410c6a2108200a41746a220a0d000b0b4101210802402015450d002015410c6c450d00201610290b20052106200b21130b0b200241c0016a41086a220a20024180036a41086a290300370300200241c0016a41106a220720024180036a41106a290300370300200241c0016a41186a220120024180036a41186a290300370300200241c0016a41206a220420024180036a41206a290300370300200241c0016a41286a220320024180036a41286a290300370300200241c0016a412d6a221920024180036a412d6a290000370000200220022d00c2023a00fa01200220022f01c0023b01f80120022002290380033703c00102400240024020080d00200241d8006a41186a2014360200200241d8006a41146a2015360200200241d8006a41106a2016360200200241d8006a410c6a2017360200200241d8006a41086a201836020020024182016a20022d00fa013a000020024187016a200b36000020024183016a20053600002002418b016a20022903c00137000020024193016a200a2903003700002002419b016a2007290300370000200241a3016a2001290300370000200241ab016a2004290300370000200241b3016a2003290300370000200241b8016a20192900003700002002201136027c2002200c360278200220123602742002201336025c20022006360258200220022f01f8013b018001024041002802d8a74c4103490d00200241c0026a411c6a4118360200200241c0026a41146a410c360200200241c0026a410c6a410c3602002002410c3602c4022002200241d8006a3602d8022002200241d0006a3602d0022002200241d4006a3602c8022002200241cc006a3602c00241002802888040210841002802848040210a41002802dca74c2105200241c0036a418204360200200241b8036a42dd80808010370300200241b4036a4198cbc700360200200241ac036a4210370200200241a8036a4188cbc700360200200241a0036a420437030020024190036a420437030020024180036a41086a410836020020024180036a411c6a200241c0026a360200200241f8cec70036028c0320024180cbc700360284032002410336028003200a4180a4c000200541024622051b20024180036a20084198a4c00020051b2802101102000b2002410c36029804200242023703e8032002419c046a200241d8006a41e80010e4071a200220024180036a36028002200241c0026a20024180026a10bd0220022802c00220022802c40220022802c80210de02210a20024198046a10cc014107210841062106200a0d010c020b4107210820064107460d010b410410272208450d0220082012360000200841044108102b2208450d02200841003600044100200d2008ad4280808080800184101820081029200621080b200910292013210c0c040b1032000b1030000b410821080b0b2000200c36020420002008360200200241c0066a24000bef0401017f230041306b220224000240024002400240024002400240024020002802000e0701020304050600010b2001411c6a2802002100200128021821012002412c6a410036020020024180a6cc003602282002420137021c200241a0ccc70036021820012000200241186a103721010c060b2002200041046a36020c200241123602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420137021c200241a8ccc7003602182002200241106a36022820012000200241186a103721010c050b2002200041046a36020c200241123602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420237021c200241b0ccc7003602182002200241106a36022820012000200241186a103721010c040b2002200028020436020c200241013602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420237021c200241c0ccc7003602182002200241106a36022820012000200241186a103721010c030b2001411c6a2802002100200128021821012002412c6a410036020020024180a6cc003602282002420137021c200241d0ccc70036021820012000200241186a103721010c020b2001411c6a2802002100200128021821012002412c6a410036020020024180a6cc003602282002420137021c200241d8ccc70036021820012000200241186a103721010c010b2001411c6a2802002100200128021821012002412c6a410036020020024180a6cc003602282002420137021c200241e0ccc70036021820012000200241186a103721010b200241306a240020010ba90504047f017e057f017e230041d0006b22022400200241206a41186a4200370300200241206a41106a22034200370300200241206a41086a220442003703002002420037032041cd87cc00ad4280808080a001841001220529000021062004200541086a290000370300200220063703202005102941d983cc00ad4280808080b00184100122052900002106200241c0006a41086a2207200541086a2900003703002002200637034020051029200320022903402206370300200241086a2004290300370300200241106a2006370300200241186a200729030037030020022002290320370300200241206a2002109e03024020022902244200200228022022051b2206422088a722044105744104722203417f4c0d000240200310272207450d002005410120051b21082002410036022820022003360224200220073602202004200241206a10710240024020040d0020022802282103200228022021090c010b2004410574210a2002280220210920022802242107200228022821032008210b0340200b2104024002402007200322056b4120490d00200541206a21030c010b024002400240200541206a22032005490d002007410174220b2003200b20034b1b220b4100480d000240024020070d000240200b0d00410121090c020b200b102721090c040b2007200b470d020b200b21070c030b1032000b20092007200b102b21090b200b210720090d001030000b200441206a210b200920056a22052004290000370000200541186a200441186a290000370000200541106a200441106a290000370000200541086a200441086a290000370000200a41606a220a0d000b2002200736022420022003360228200220093602200b2003ad4220862009ad84210c0240200642ffffff3f83500d00200810290b200241d0006a2400200c0f0b1039000b1038000bbe05020c7f017e230041306b22022400200210a403024002400240024002400240200228020822034103744104722204417f4c0d002002280204210520022802002106200410272207450d012002410036020820022004360204200220073602002003200210712003450d02200341037421082006210303400240024020032802004101460d0002400240200228020420022802082204460d00200228020021070c010b200441016a22072004490d07200441017422092007200920074b1b22094100480d070240024020040d0041002104024020090d00410121070c020b2009102722070d010c0b0b2002280200210720042009460d00200720042009102b2207450d0a0b20022009360204200220073602000b200720046a41003a0000200441016a21040c010b024002402002280204220720022802082204460d00200228020021090c010b200441016a22072004490d06200441017422092007200920074b1b22074100480d060240024020040d0041002104024020070d00410121090c020b200710272209450d0a0c010b2002280200210920042007460d00200920042007102b2209450d090b20022007360204200220093602000b200920046a41013a00002002200441016a220a360208200341046a280200210b02402007200a6b41034b0d00200a41046a220c200a490d062007410174220d200c200d200c4b1b220c4100480d060240024020070d000240200c0d00410121090c020b200c10272209450d0a0c010b2007200c460d0020092007200c102b2209450d090b2002200c360204200220093602000b2009200a6a200b360000200441056a21040b200341086a210320022004360208200841786a22080d000c050b0b1038000b1039000b200228020821040c010b1032000b2004ad422086200235020084210e0240200541ffffffff0171450d00200610290b200241306a2400200e0f0b1030000ba30b07057f017e047f027e047f017e077f230041e0006b22012400200141c0006a41186a22024200370300200141c0006a41106a22034200370300200141c0006a41086a220442003703002001420037034041d787cc00ad42808080809001841001220529000021062004200541086a290000370300200120063703402005102941fa87cc00ad4280808080e00084100122072900002106200141086a2205200741086a2900003703002001200637030020071029200320012903002206370300200141206a41086a22082004290300370300200141206a41106a22092006370300200141206a41186a220a200529030037030020012001290340370320200141c0006a200141206a10a60320012802402107200129024421062002420037030020034200370300200442003703002001420037034041cd87cc00ad4280808080a0018410012202290000210b2004200241086a2900003703002001200b3703402002102941d983cc00ad4280808080b0018410012202290000210b2005200241086a2900003703002001200b3703002002102920032001290300220b370300200820042903003703002009200b370300200a2005290300370300200120012903403703202006420020071b220c422088a7210d200141c0006a200141206a109e0320012902444200200128024022041b2206422088210b0240200642ffffff3f83500d002004410120041b10290b200ba721044100210e0240200d450d002004417f6a200d6e210e0b2007410420071b210f2001410036024820014204370340200141c0006a41002004108d012001280248210802400240024002400240024020040d00200128024021090c010b2001280240220920084103746a21030240200e450d00200e200d6c210a410021050340410021070240200a20054d0d002005200e6e2207200d4f0d04200f2007412c6c6a2802002102410121070b20032007360200200341046a2002360200200341086a21032004200541016a2205470d000b200820056a21080c010b20042105034020034100360200200341086a21032005417f6a22050d000b200820046a21080b20012802442110200141c0006a41dbbcc70041141094034100210341204100412020044102746b2205200541204b1b22056bad422086200141c0006a20056aad84101022052900002106200541086a290000210b200541106a2900002111200141186a2212200541186a290000370300200141106a22132011370300200141086a2214200b3703002001200637030020051029200141206a41186a22152012290300370300200141206a41106a22162013290300370300200141206a41086a221720142903003703002001200129030037032041002004417f6a2205200520044b1b2202450d032001ad4280808080800484210b034002402003411c71220541046a220741204d0d002007412041f0bcc700104b000b200120056a2800002004410120041b220a70210702402005411c470d00200141c0006a41186a220d200b1010220541186a290000370300200141c0006a41106a220e200541106a290000370300200141c0006a41086a2218200541086a29000037030020012005290000370340200510292012200d2903003703002013200e29030037030020142018290300370300200120012903403703000b200a417f6a220520084f0d02200720084f0d03200920054103746a220529020021062005200920074103746a220729020037020020072006370200200341046a21032004417f6a21042002417f6a22020d000c040b0b2007200d41bceec9001036000b200520084180bdc7001036000b200720084190bdc7001036000b2000200836020820002010360204200020093602002000200129032037000c200041146a20172903003700002000411c6a2016290300370000200041246a20152903003700000240200ca72204450d002004412c6c450d00200f10290b200141e0006a24000bc80204047f017e017f017e230041d0006b22022400200241206a41186a4200370300200241206a41106a22034200370300200241206a41086a220442003703002002420037032041d787cc00ad42808080809001841001220529000021062004200541086a290000370300200220063703202005102941fa87cc00ad4280808080e00084100122052900002106200241c0006a41086a2207200541086a2900003703002002200637034020051029200320022903402206370300200241086a2004290300370300200241106a2006370300200241186a200729030037030020022002290320370300200241206a200210a603200241206a20022802202204410420041b22052002290224420020041b2206422088a710a7032002350228422086200235022084210802402006a72204450d002004412c6c450d00200510290b200241d0006a240020080bbe0904057f017e0c7f027e230041c0016b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b0202400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c8010240024020022802000d000240024002402002280204220520022802242206412c6e2201200120054b1bad422c7e2207422088a70d002007a72201417f4c0d000240024020010d00410421080c010b200110272208450d020b41002109200241003602302002200836022820022001412c6e36022c02402005450d004100210a034020064104490d0420022006417c6a220b36022420022002280220220c41046a2201360220200b450d04200c280000210d20022006417b6a220b3602242002200141016a36022020012d0000220141014b0d044102210e0240024020010e020100010b41002101200241003a00b8012006417b6a210f417a210b02400240024002400340200f2001460d0120024198016a20016a200c20016a220e41056a2d00003a000020022006200b6a3602242002200e41066a3602202002200141016a220e3a00b801200b417f6a210b200e2101200e4120470d000b200241f8006a41186a221020024198016a41186a290300370300200241f8006a41106a221120024198016a41106a290300370300200241f8006a41086a221220024198016a41086a2903003703002002200229039801370378200f200e460d0920022006200b6a220b3602242002200c200e6a220141066a220f360220200141056a2d0000220c41014b0d09200c0e020102010b200141ff0171450d08200241003a00b8010c080b4100210e0c010b200b4104490d0620022006200e6b41766a220b36022420022001410a6a360220200f28000021134101210e0b200241d8006a41186a2010290300370300200241d8006a41106a2011290300370300200241d8006a41086a2012290300370300200220022903783703580b200a41016a210a200241386a41186a2206200241d8006a41186a290300370300200241386a41106a220c200241d8006a41106a290300370300200241386a41086a220f200241d8006a41086a2903003703002002200229035837033802402009200228022c470d00200241286a2009410110930120022802282108200228023021090b20082009412c6c6a2201200d3602002001200229033837020420062903002107200c2903002114200f2903002115200141286a2013360200200141246a200e3602002001410c6a2015370200200141146a20143702002001411c6a20073702002002200941016a2209360230200b2106200a2005470d000b0b2008450d032000200229022c370204200020083602000c040b1038000b1039000b200228022c2201450d002001412c6c450d00200810290b2002410036028001200242013703782002410d36025c2002200241086a3602582002200241f8006a360238200241ac016a41013602002002420137029c01200241f4eaca00360298012002200241d8006a3602a801200241386a41a8a3c80020024198016a10371a20023502800142208620023502788410080240200228027c450d00200228027810290b200041003602000b2004450d00200310290b200241c0016a24000bc20101037f230041106b22032400024002402002412c6c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410272205450d020b20034100360208200320053602002003200436020420022003107102402002450d0020012002412c6c6a210203402003200128020036020c20032003410c6a41041072200141046a200310f3022001412c6a22012002470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1038000b1039000bf10203047f017e017f230041e0006b22022400200241306a41186a4200370300200241306a41106a22034200370300200241306a41086a220442003703002002420037033041b3e6ca00ad4280808080e000841001220529000021062004200541086a290000370300200220063703302005102941c9e6ca00ad4280808080e00084100122052900002106200241d0006a41086a2207200541086a2900003703002002200637035020051029200320022903502206370300200241106a41086a2004290300370300200241106a41106a2006370300200241106a41186a200729030037030020022002290330370310200241086a200241106a412010fc0120022802082105200228020c21030240410410272204450d0020044180808005360000200441044108102b2204450d0020044180a001360004200441084110102b2204450d0020042003410020051b2205417f6a410020051b360008200241e0006a24002004ad4280808080c001840f0b1030000b990b04037f017e037f017e230041e0006b22022400024002400240024020014104490d0020004180a6cc0020011b2800002103200241086a41186a4200370300200241086a41106a22044200370300200241086a41086a220142003703002002420037030841b3e6ca00ad4280808080e000841001220029000021052001200041086a290000370300200220053703082000102941c9e6ca00ad4280808080e00084100122002900002105200241d0006a41086a2206200041086a2900003703002002200537035020001029200420022903502205370300200241306a41086a2001290300370300200241306a41106a2005370300200241306a41186a2006290300370300200220022903083703302002200241306a412010fc010240024002402002280200450d00200228020422010d010b41022104200241023602240c010b200241086a20032001417f6a10aa03200228022421040b410110272201450d01200242013702342002200136023002400240024020044102470d00200141003a0000410121000c010b200141013a00002002410136023820022802182107200241206a2802002200200241306a10710240024020022802342203200228023822066b2000490d00200228023021010c010b200620006a22012006490d05200341017422082001200820014b1b22084100480d050240024020030d00024020080d00410121010c020b2008102722010d010c080b2002280230210120032008460d00200120032008102b2201450d070b20022008360234200220013602300b200120066a2007200010e4071a2002200620006a2206360238200241106a290300210520022903082109024002402002280234220320066b410f4d0d00200321000c010b200641106a22002006490d05200341017422072000200720004b1b22004100480d050240024020030d00024020000d00410121010c020b200010272201450d080c010b20032000460d00200120032000102b2201450d070b20022000360234200220013602300b200120066a22032005370008200320093700002002200641106a2206360238024020044101460d000240024020002006460d00200621000c010b200041016a22042000490d06200041017422062004200620044b1b22044100480d060240024020000d0041002100024020040d00410121010c020b200410272201450d090c010b20002004460d00200120002004102b2201450d080b20022004360234200220013602300b200120006a41003a00002002200041016a2200360238200228023021010c020b0240024020002006460d00200621000c010b200041016a22042000490d05200041017422062004200620044b1b22044100480d050240024020000d0041002100024020040d00410121010c020b200410272201450d080c010b20002004460d00200120002004102b2201450d070b20022004360234200220013602300b200120006a41013a00002002200041016a220436023820022802282103024002402002280234220620046b4104490d00200228023021010c010b200441046a22012004490d05200641017422072001200720014b1b22074100480d050240024020060d00024020070d00410121010c020b200710272201450d080c010b2002280230210120062007460d00200120062007102b2201450d070b20022007360234200220013602300b200120046a2003360000200041056a21000b200220003602380b2000ad4220862001ad842105024020022802244102460d002002411c6a280200450d00200228021810290b200241e0006a240020050f0b2002413c6a41043602002002411c6a41023602002002420237020c200241a0d1c2003602082002410436023420024180d3c2003602302002410036025420024180a6cc003602502002200241306a3602182002200241d0006a360238200241086a41b0d1c2001040000b1039000b1032000b1030000bf20a04047f017e047f017e230041b0016b22032400200341386a41186a4200370300200341386a41106a22044200370300200341386a41086a220542003703002003420037033841b3e6ca00ad4280808080e000841001220629000021072005200641086a290000370300200320073703382006102941c9e6ca00ad4280808080e0008410012206290000210720034188016a41086a2208200641086a29000037030020032007370388012006102920042003290388012207370300200341186a41086a22062005290300370300200341186a41106a2007370300200341186a41186a200829030037030020032003290338370318200341106a200341186a412010fc01024002400240024002400240200241016a2003280214410020032802101b470d0041d787cc00ad42808080809001841001220529000021072008200541086a290000370300200320073703880120051029419588cc00ad4280808080d000841001220529000021072006200541086a2900003703002003200737031820051029200320013602a4012003200341a4016aad4280808080c00084100222052900003703a80120051029200341c4006a200341a8016a3602002003200341a8016a41086a36023c2003200341a4016a3602402003200341a8016a36023820034198016a200341386a107520032802a001220941206a2204417f4c0d02200328029801210a0240024020040d0041002106410121050c010b200410272205450d04200421060b024002402006410f4d0d00200621080c010b200641017422084110200841104b1b22084100480d05024020060d002008102722050d010c070b20062008460d00200520062008102b2205450d060b2005200329038801370000200541086a20034188016a41086a2903003700000240024020084170714110460d00200821060c010b200841017422064120200641204b1b22064100480d0520082006460d00200520082006102b2205450d060b20052003290318370010200541186a200341186a41086a29030037000002400240200641606a2009490d00200621080c010b200941206a22082009490d052006410174220b2008200b20084b1b22084100480d0520062008460d00200520062008102b2205450d060b200541206a200a200910e4071a0240200328029c01450d00200a10290b2005200410900641ff0171210602402008450d00200510290b41022105410021080240024020064102470d000c010b02402006410171450d000c010b200341386a2001108906200341086a20032802382209200328024010fc01200328020c2104200328020821060240200328023c450d00200910290b02402006450d00200420024b0d010b200341186a200110cb04200341386a20032802182209200328022010cc040240024020032802444102470d004104210641002108410021040c010b200328023c41ffffffff0371210420032802382106200328024021080b0240200328021c450d00200910290b024002402008450d00200628020041c093066a210802402004450d00200610290b20082002490d01410021080c020b2004450d00200610290b200241c0f0006a2106410121080b20034198016a200110ce040240200328029801450d00200320013602a801200341186a200341a8016a10cc0320034188016a200341186a10a802200341386a200328028801220120032802900110a902200341c8006a2903004200200329033842015122051b21072003290340420020051b210c0240200328028c01450d00200110290b200020073703082000200c3703002000200329039801370210200041186a200341a0016a28020036020020002006360220200821050b2000200536021c0c010b2000410236021c0b200341b0016a24000f0b1038000b1039000b1032000b1030000bf80305017f017e017f017e037f230041306b22022400024002400240024020014104490d00200220004180a6cc0020011b28000010ac03200241186a200228020022012002280208108b03200229021c21032002280218210002402002280204450d00200110290b410110272201450d0120024201370204200220013602000240024020000d0041002104200141003a000042808080801021050c010b200141013a0000200241013602082003422088a72204200210710240024020022802042206200228020822076b2004490d00200228020021010c010b200720046a22012007490d04200641017422082001200820014b1b22084100480d040240024020060d00024020080d00410121010c020b2008102722010d010c070b2002280200210120062008460d00200120062008102b2201450d060b20022008360204200220013602000b200120076a2000200410e4071a200720046aad4220862105200021040b20052001ad84210502402000450d002003a7450d00200410290b200241306a240020050f0b200241246a4104360200200241146a410236020020024202370204200241a0d1c2003602002002410436021c200241a0d3c2003602182002410036022c20024180a6cc003602282002200241186a3602102002200241286a360220200241b0d1c2001040000b1039000b1032000b1030000bfc0403027f017e057f230041d0006b2202240041cd87cc00ad4280808080a00184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941e483cc00ad4280808080c00084100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bef1c07097f017e057f017e027f027e047f230041e0116b22022400024002402001450d00200220003602000c010b20024180a6cc003602000b20022001360204200241c0036a200210f9020240024020022802c0032203450d002003200241c0036a41086a280200220441c0036c6a210520022802c4032106024002400240024020040d00200321070c010b200241c0036a4198016a2108200241d80a6a4198016a2109200241c0036a41f0006a210a200321070340200241d8026a200741e80010e4071a2007290368210b200241086a200741f0006a41d00210e4071a200741c0036a2107200b4203510d01200241c0036a200241d8026a41e80010e4071a2002200b3703a804200a200241086a41d00210e4071a2002200241c0036a3602d80a200241c80a6a200241d80a6a10bd02200220022802d00a3602c40a200220022802c80a220c3602c00a20024180076a200241c00a6a1087030240024020022903e8074203520d00024020022802cc0a450d00200c10290b200810cc010c010b200241d80a6a20024180076a41c00310e4071a410121004100210d024020022802f00b22014114470d0020022802f40b4101470d0020022802f80b210e20022802fc0b210f0240024020022802800c22104190026c22010d004108210d420021110c010b20014190026dad42f8017e220b422088a70d06200ba722004100480d060240024020000d004108210d0c010b20001027220d450d090b200041f8016ead21110b200e20016a21124100211302400240024020100d00200e21100c010b4200210b200e2101200d21000340200141086a2903002114200141106a280200211020012903002115200241980e6a200141146a41e40110e4071a024020100d0020014190026a21100c020b2001418c026a280200211620014184026a2802002117200141fc016a2802002118200141f8016a2802002119200241fc0f6a200241980e6a41e40110e4071a02402018450d00201841c1006c450d00201910290b02402016450d00201710290b2000201537030020002014370308200041106a2010360200200041146a200241fc0f6a41e40110e4071a200041f8016a2100200b4280808080107c210b201341016a211320014190026a22012012470d000b2011200b8421140c010b20112013ad42208684211420102012460d0003400240201041d0006a280200450d00201028024c10290b0240201041186a2802002200450d00201028021021012000410474210003400240200141046a280200450d00200128020010290b200141106a2101200041706a22000d000b0b0240201041146a28020041ffffffff0071450d00201028021010290b0240201028021c2201450d00201041206a280200450d00200110290b0240201041fc016a2802002201450d00200141c1006c450d0020102802f80110290b20104190026a210120104188026a41003602002010280284022100201041013602840202402010418c026a280200450d00200010290b2001211020012012470d000b0b0240200f450d00200f4190026c450d00200e10290b4100210020022802f00b21010b0240024020014114470d00024020022802f40b4101470d002000450d02024020022802800c2201450d0020022802f80b221020014190026c6a211803400240201041d0006a280200450d00201028024c10290b0240201041186a2802002200450d00201028021021012000410474210003400240200141046a280200450d00200128020010290b200141106a2101200041706a22000d000b0b0240201041146a28020041ffffffff0071450d00201028021010290b0240201028021c2201450d00201041206a280200450d00200110290b0240201041fc016a2802002201450d00200141c1006c450d0020102802f80110290b20104190026a210120104188026a41003602002010280284022100201041013602840202402010418c026a280200450d00200010290b2001211020012018470d000b0b20022802fc0b2201450d0220014190026c450d0220022802f80b10290c020b024020022802840c2200450d0020022802fc0b21012000410c6c210003400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b20022802800c2201450d012001410c6c450d0120022802fc0b10290c010b200910cc010b024020022802cc0a450d00200c10290b200810cc01200d0d030b20072005470d000b200521070b4100210d0b024020052007460d002003200441c0036c6a2101034020074198016a10c2012001200741c0036a2207470d000b0b02402006450d00200641c0036c450d00200310290b0240024002400240200d0d00410121010c010b2014422088a741f8016c4105722201417f4c0d010b200110272200450d01200241003602e00a200220013602dc0a200220003602d80a02400240200d0d00200041003a0000200241013602e00a0c010b200041013a0000200241013602e00a2014422088a72201200241d80a6a10712001450d00200141f8016c2105410021160340200d20166a220141c8006a28020021120240024020022802dc0a220020022802e00a22186b4104490d0020022802d80a2110200021070c010b201841046a22102018490d05200041017422072010200720104b1b22074100480d050240024020000d00024020070d00410121100c020b2007102722100d010c090b20022802d80a211020002007460d00201020002007102b2210450d080b200220073602dc0a200220103602d80a0b201020186a20123600002002201841046a22123602e00a412010272200450d03200041186a2213200141f0006a290000370000200041106a2217200141e8006a290000370000200041086a2219200141e0006a2900003700002000200141d8006a29000037000002400240200720126b4120490d00201841246a21180c010b201241206a22182012490d052007410174220c2018200c20184b1b220c4100480d050240024020070d000240200c0d00410121100c020b200c10272210450d090c010b2007200c460d0020102007200c102b2210450d080b2002200c3602dc0a200220103602d80a0b201020126a22102000290000370000201041186a2013290000370000201041106a2017290000370000201041086a2019290000370000200220183602e00a20001029200141cc006a2802002113200141d4006a2802002210200241d80a6a10710240024020022802dc0a221220022802e00a22186b2010490d0020022802d80a2100201221070c010b201820106a22002018490d05201241017422072000200720004b1b22074100480d050240024020120d00024020070d00410121000c020b200710272200450d090c010b20022802d80a210020122007460d00200020122007102b2200450d080b200220073602dc0a200220003602d80a0b200020186a2013201010e4071a2002201820106a22103602e00a02400240200720106b411f4d0d00200721180c010b201041206a22182010490d05200741017422122018201220184b1b22184100480d050240024020070d00024020180d00410121000c020b201810272200450d090c010b20072018460d00200020072018102b2200450d080b200220183602dc0a200220003602d80a0b200020106a2207200141f8006a290000370000200741186a20014190016a290000370000200741106a20014188016a290000370000200741086a20014180016a2900003700002002201041206a22133602e00a02400240201820136b41c000490d00201041e0006a2107201821120c010b201341c0006a22072013490d05201841017422102007201020074b1b22124100480d050240024020180d00024020120d00410121000c020b201210272200450d090c010b20182012460d00200020182012102b2200450d080b200220123602dc0a200220003602d80a0b200020136a221020014198016a290000370000201041386a200141d0016a290000370000201041306a200141c8016a290000370000201041286a200141c0016a290000370000201041206a200141b8016a290000370000201041186a200141b0016a290000370000201041106a200141a8016a290000370000201041086a200141a0016a290000370000200220073602e00a412010272210450d03201041186a2218200141f0016a290000370000201041106a2213200141e8016a290000370000201041086a2217200141e0016a2900003700002010200141d8016a2900003700000240201220076b411f4b0d00200741206a22192007490d052012410174220c2019200c20194b1b22194100480d050240024020120d00024020190d00410121000c020b201910272200450d090c010b20122019460d00200020122019102b2200450d080b200220193602dc0a200220003602d80a0b200020076a22002010290000370000200041186a2018290000370000200041106a2013290000370000200041086a20172900003700002002200741206a3602e00a201010292001200241d80a6a10ae032005201641f8016a2216470d000b0b20023502e00a42208620023502d80a84210b0240200d450d0002402014422088a72201450d00200d200141f8016c6a2107200d2101034002402001221041d0006a280200450d00201028024c10290b0240201041186a2802002200450d00201028021021012000410474210003400240200141046a280200450d00200128020010290b200141106a2101200041706a22000d000b0b0240201041146a28020041ffffffff0071450d00201028021010290b201041f8016a21010240201028021c2200450d00201041206a280200450d00200010290b20012007470d000b0b2014a72201450d00200141f8016c450d00200d10290b200241e0116a2400200b0f0b1038000b1039000b1032000b2002418c076a4104360200200241ec0a6a4102360200200242023702dc0a200241a0d1c2003602d80a2002410436028407200241b8d3c200360280072002410036020c20024180a6cc00360208200220024180076a3602e80a2002200241086a36028807200241d80a6a41b0d1c2001040000b1030000bee0203017f017e047f230041106b22022400200029030021032002200041086a29030037030820022003370300200120024110107220002802102104200041186a28020022052001107102402005450d0020054104742105034002402004410c6a2d000022064103714103460d004100210702400240024020060e03020001020b410121070c010b410221070b200220073a000020012002410110720b20042802002107200441086a2802002206200110712001200720061072200441106a2104200541706a22050d000b0b0240412010272204450d0020042000290028370000200441186a200041c0006a290000370000200441106a200041386a290000370000200441086a200041306a29000037000020012004412010722004102902400240200028021c22040d00200241003a000020012002410110720c010b200241013a00002001200241011072200041246a28020022052001107120012004200510720b200241106a24000f0b1039000bff0504057f017e067f017e230041a0016b22022400200241d8006a41186a22034200370300200241d8006a41106a22044200370300200241d8006a41086a220542003703002002420037035841b1dcc900ad4280808080f000841001220629000021072005200641086a2900003703002002200737035820061029418886ca00ad4280808080c00184100122082900002107200241f8006a41086a2206200841086a2900003703002002200737037820081029200420022903782207370300200241106a41086a22092005290300370300200241106a41106a220a2007370300200241106a41186a220b200629030037030020022002290358370310200241086a200241106a412010fc01200228020c210c2002280208210d2003420037030020044200370300200542003703002002420037035841b3e6ca00ad4280808080e000841001220829000021072005200841086a290000370300200220073703582008102941cfe6ca00ad4280808080a001841001220829000021072006200841086a290000370300200220073703782008102920042002290378220737030020092005290300370300200a2007370300200b200629030037030020022002290358370310200241f8006a200241106a412010cd0120022d00782106200320024191016a290000370300200420024189016a290000370300200520024181016a29000037030020022002290079370358200c4100200d1b21080240024020064101460d00200241386a41186a4200370300200241386a41106a4200370300200241386a41086a4200370300200242003703380c010b200241386a41186a2003290300370300200241386a41106a2004290300370300200241386a41086a2005290300370300200220022903583703380b2002411c6a200241c0006a290300370200200241246a200241c8006a2903003702002002412c6a200241d0006a2903003702002002200836021020022002290338370214200241f8006a200241106a10b00320023502800121072002350278210e200241a0016a2400200e2007422086840bc70101057f20012802002102024002400240410410272203450d0020032002360000412010272202450d0120022001290004370000200241186a22042001411c6a290000370000200241106a2205200141146a290000370000200241086a22062001410c6a290000370000200341044124102b22010d020b1030000b1039000b200120022900003700042001411c6a2004290000370000200141146a20052900003700002001410c6a200629000037000020021029200042a4808080c004370204200020013602000ba50a07027f017e047f017e017f047e027f230041e0006b220224002002411436020c200241d3d5c800360208200241106a41d3d5c800ad4280808080c002841007108b02024002400240024002400240200228021022030d0042002104410821050c010b200228021421062002200241186a2802002207360224200220033602200240024002402007450d0020022007417f6a3602242002200341016a36022020032d00002107200241c8006a200241206a10b20320022802482208450d00200229024c2109200741ff01714101460d012009a72207450d00200741286c450d00200810290b20024100360230200242013703282002410d36023c2002200241086a3602382002200241286a36024441012107200241dc006a41013602002002420137024c200241f4eaca003602482002200241386a360258200241c4006a41a8a3c800200241c8006a10371a200235023042208620023502288410080240200228022c450d00200228022810290b4102210a0c010b4101210a410021070b02402006450d00200310290b4108200820071b21054200200920071b210420070d00200a4101460d0020052802082203ad42287e2209422088a70d012009a72207417f4c0d01200528020021060240024020070d00410821050c010b200710272205450d030b02400240024002400240200741286e220820034f0d002008410174220a2003200a20034b1bad42287e2209422088a70d082009a7220a4100480d08200741274d0d01200841286c2207200a460d022007450d0120052007200a102b2205450d090c020b2008ad210b20030d02420021090c030b200a10272205450d070b200a41286ead210b0b200341286c210a42002109410021080340200620086a22032903002104200341086a290300210c200341106a290300210d200341186a290300210e200520086a220741206a200341206a290300370300200741186a200e370300200741106a200d370300200741086a200c3703002007200437030020094280808080107c2109200a200841286a2208470d000b0b200b20098421040b2004422088a7220341286c4104722207417f4c0d00200710272208450d01200241003602502002200736024c200220083602482003200241c8006a10712002280250210702402003450d002005200341286c6a210f200228024c210620052103034002400240200620076b4120490d00200741206a2108200228024821102006210a0c010b200741206a22082007490d052006410174220a2008200a20084b1b220a4100480d050240024020060d000240200a0d00410121100c020b200a10272210450d080c010b200228024821102006200a460d0020102006200a102b2210450d070b2002200a36024c200220103602480b201020076a22072003290000370000200741186a200341186a290000370000200741106a200341106a290000370000200741086a200341086a29000037000020022008360250200341206a290300210902400240200a20086b4108490d00200841086a2107200a21060c010b200841086a22072008490d05200a41017422062007200620074b1b22064100480d0502400240200a0d00024020060d00410121100c020b200610272210450d080c010b200a2006460d002010200a2006102b2210450d070b2002200636024c200220103602480b201020086a200937000020022007360250200f200341286a2203470d000b0b2007ad422086200235024884210902402004a72203450d00200341286c450d00200510290b200241e0006a240020090f0b1038000b1039000b1032000b1030000bbb0504037f017e087f037e23004180016b220224002002200110c80102400240024002402002280200450d00200041003602000c010b20022802042203200128020441286e2204200420034b1bad42287e2205422088a70d012005a72204417f4c0d010240024020040d00410821060c010b200410272206450d030b4100210720024100360210200220063602082002200441286e36020c0240024002402003450d0041002108034041002104200241003a0078200841016a210820012802042109417f210a034020092004460d03200241d8006a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a0078200a417f6a210a200c2104200c4120470d000b200241386a41186a2204200241d8006a41186a290300370300200241386a41106a220a200241d8006a41106a290300370300200241386a41086a220d200241d8006a41086a290300370300200220022903583703382009200c6b220c4108490d03200b29000121052001200b41096a3602002001200c41786a360204200241186a41086a220c200d290300370300200241186a41106a2209200a290300370300200241186a41186a220a20042903003703002002200229033837031802402007200228020c470d00200241086a2007410110a30120022802082106200228021021070b2006200741286c6a22042002290318370300200c290300210e2009290300210f200a290300211020042005370320200441186a2010370300200441106a200f370300200441086a200e3703002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c020b200441ff0171450d00200241003a00780b20004100360200200228020c2204450d00200441286c450d00200610290b20024180016a24000f0b1038000b1039000bac1603037f017e057f230041c0096b22022400024002402001450d00200220003602200c010b20024180a6cc003602200b20022001360224200241b8046a200241206a10b40302400240024002400240024020022903c0044202510d00200241286a200241b8046a41800210e4071a200241186a200241206a10c8010240024020022802180d0020022802242203200228021c2201490d002001417f4c0d010240024020010d0041002103410121000c010b2001102d2200450d08200020022802202204200110e4071a2002200320016b3602242002200420016a360220200121030b2000450d00200241a8026a200241286a41800210e4071a20022001ad4220862003ad8422054220883e02fc08200220003602f808200241b8046a200241f8086a10b5032005a721030240024020022802bc0422010d000c010b200241b0086a200241c8046a280200360200200220022903c0043703a80820022802b80421040b02402003450d00200010290b200241b8046a41086a2200200241a8086a41086a280200360200200220022903a8083703b8042001450d03200241a8046a41086a22032000280200360200200220022903b8043703a804200241b8046a200241a8026a41800210e4071a200241b8066a41086a20022903a804370300200241c8066a2003280200360200200220013602bc06200220043602b80641002101200241003602d006200241106a200241d0066a10b603200241a8086a200228021022002002280214220428020c2203110200024020022d00cc084103460d00410021010340200241a8086a20002003110200200141016a210120022d00cc084103470d000b0b2000200428020011030002402004280204450d00200010290b2001450d042002200241b8066a3602e4062002200241b8046a3602e0062002200241d0066a3602dc062002200241dc066a3602ec062002200241e0066a3602e806200241086a200241d0066a10b603200228020821012002200228020c22003602f406200220013602f0062002200241e8066a3602f8062002200241f8066a36028007200241e0076a2001200028020c1102000240024020022d0084084103460d00200241f1086a21000340200241f8086a200241e0076a41c80010e4071a200241a8086a20024180076a200241f8086a10b70320022d00f00822014102470d02200241e0076a20022802f00620022802f40628020c11020020022d0084084103470d000b0b20022802f00620022802f4062802001103004104210641002107024020022802f406280204450d0020022802f00610290b410021010c060b20024190076a200241a8086a41c80010e4071a200241dc076a41026a2203200041026a2d00003a0000200220002f000022003b01fc06200220003b01dc07200241a8086a20022802f00620022802f40628021011020041cc0010272206450d07200620024190076a41c80010e407220020013a0048200020022f01dc073b0049200041cb006a20032d00003a000020024180076a41086a2208200241f0066a41086a280200360200200220022903f006220537038007200220083602dc07200241e0076a2005a720022802840728020c1102000240024020022d0084084103470d0041012107410121010c010b200241f1086a210441012107410121010340200241f8086a200241e0076a41c80010e4071a200241a8086a200241dc076a200241f8086a10b703024020022d00f00822004102470d00200241e0076a20022802800720022802840728020c11020020022d0084084103470d010c020b20024190076a200241a8086a41c80010e4071a2002418c076a41026a2203200441026a2d00003a0000200220042f000022093b01fc06200220093b018c07200241a8086a20024190076a41c80010e4071a200241e0076a41026a220920032d00003a0000200220022f018c073b01e007024020012007470d00200241f8086a2002280280072002280284072802101102000240024002400240200741016a22032007490d002007410174220a2003200a20034b1bad42cc007e2205422088a70d002005a722034100480d00024020070d0020030d02410421060c040b200741cc006c22072003460d03024020070d0020030d02410421060c040b200620072003102b2206450d020c030b1032000b2003102722060d010b1030000b200341cc006e21070b2006200141cc006c6a200241a8086a41c80010e407220320003a0048200341cb006a20092d00003a0000200320022f01e0073b0049200220083602dc07200241e0076a20022802800720022802840728020c110200200141016a210120022d0084084103470d000b0b200228028007200228028407280200110300200228028407280204450d0520022802800710290c050b200241b4026a4104360200200241cc046a4102360200200242023702bc04200241a0d1c2003602b804200241043602ac02200241ccd3c2003602a802200241003602ac0820024180a6cc003602a8082002200241a8026a3602c8042002200241a8086a3602b002200241b8046a41b0d1c2001040000b1038000b200241346a4104360200200241bc026a4102360200200242023702ac02200241a0d1c2003602a8022002410436022c200241ccd3c200360228200241003602ac0820024180a6cc003602a8082002200241286a3602b8022002200241a8086a360230200241a8026a41b0d1c2001040000b410021000c020b024020022802d0062201450d0020022802d4062200450d00200041226c450d00200110290b20022802bc0621030240200241b8066a410c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b4100210020022802c0062201450d012001410c6c450d01200310290c010b02402001450d00200141cc006c2100200641c9006a21010340024002402001417f6a2d00004101460d0041002802d8a74c4103490d01200241193602fc082002200141bb7f6a3602f80841002802888040210341002802848040210441002802dca74c210920024199023602e808200242e4808080103703e008200241c8b8c4003602dc082002421c3702d408200241acb8c4003602d008200242013703c808200242023703b8082002418cb8c4003602b4082002411c3602b008200241acb8c4003602ac08200241033602a80820034198a4c000200941024622091b28021021032002200241f8086a3602c40820044180a4c00020091b200241a8086a20031102000c010b200220013602e00741002802d8a74c450d002002411a36028409200241193602fc082002200141bb7f6a3602f8082002200241e0076a3602800941002802888040210341002802848040210441002802dca74c21092002419a023602e808200242e4808080103703e008200241c8b8c4003602dc082002421c3702d408200241acb8c4003602d008200242023703c808200242023703b8082002419cb8c4003602b4082002411c3602b008200241acb8c4003602ac08200241013602a80820034198a4c000200941024622091b28021021032002200241f8086a3602c40820044180a4c00020091b200241a8086a20031102000b200141cc006a2101200041b47f6a22000d000b0b02402007450d00200741cc006c450d00200610290b024020022802d0062201450d0020022802d4062200450d00200041226c450d00200110290b0240200241b8066a410c6a2802002200450d0020022802bc0621012000410c6c210003400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b4101210020022802c0062201450d002001410c6c450d0020022802bc0610290b410110272201450d00200120003a0000200241c0096a24002001ad428080808010840f0b1039000bff2d07037f017e037f017e067f057e0d7f23004190086b220224000240024002400240024002400240200128020422034108490d002001280200220429000021052001200341786a22063602042001200441086a22073602002006450d0520072d000021062001200341776a22083602042001200741016a360200200641014b0d0502400240024002400240024002400240024020060e020001000b20084108490d092007290001210920012003416f6a220a3602042001200741096a36020041002107200241003a0028200321060240024002400240024002400340200a2007460d01200241086a20076a200420076a220841116a2d00003a000020012006416e6a3602042001200841126a3602002002200741016a22083a00282006417f6a21062008210720084120470d000b200241d0056a41086a200241086a41086a290300370300200241d0056a41106a200241086a41106a290300370300200241d0056a41186a200241086a41186a290300370300200220022903083703d00541002107200241003a0028200420086a210b2006416e6a210a200320086b416f6a210c2003210d0340200c2007460d02200241086a20076a200b20076a220e41116a2d00003a00002001200a3602042001200e41126a3602002002200741016a220e3a0028200a417f6a210a200d417f6a210d200e2107200e4120470d000b20024190076a41086a220d200241086a41086a29030037030020024190076a41106a220c200241086a41106a29030037030020024190076a41186a220f200241086a41186a29030037030020022002290308370390072006200e6b220a416f6a4104490d122008200e6a2107200b200e6a220641116a280000210b2001200a416b6a360204200241f0066a41086a200d290300370300200241f0066a41106a200c290300370300200241f0066a41186a200f2903003703002001200641156a36020020022002290390073703f00641002106200241003a00482003416b6a210e200441156a210d200a416a6a21080340200e2007460d03200241086a20066a200d20076a220a2d00003a0000200120083602042001200a41016a3602002002200641016a220a3a00482008417f6a2108200741016a2107200a2106200a41c000470d000b200241d0076a41386a200241086a41386a2903002210370300200241d0076a41306a200241086a41306a2903002211370300200241d0076a41286a200241086a41286a2903002212370300200241d0076a41206a200241086a41206a2903002213370300200241f0056a41086a200241086a41086a290300370300200241f0056a41106a200241086a41106a290300370300200241f0056a41186a200241086a41186a290300370300200241f0056a41206a2013370300200241f0056a41286a2012370300200241f0056a41306a2011370300200241f0056a41386a2010370300200220022903083703f005200241d0066a41186a2206200241f0066a41186a290300370300200241d0066a41106a2208200241f0066a41106a290300370300200241d0066a41086a220a200241f0066a41086a290300370300200220022903f0063703d006200241b0066a41186a2006290300370300200241b0066a41106a2008290300370300200241b0066a41086a200a290300370300200220022903d0063703b00641002106200241003a0028200420076a41156a2104200320076b41666a210703402007417b460d04200241086a20066a20042d00003a00002001200741046a3602042001200441016a22043602002002200641016a22083a00282007417f6a21072008210620084120470d000b20024190076a41086a2208200241086a41086a29030037030020024190076a41106a2203200241086a41106a29030037030020024190076a41186a220a200241086a41186a2903003703002002200229030837039007200741056a4104490d052004280000210e2001200741016a3602042001200441046a2206360200200241f0066a41086a2008290300370300200241f0066a41106a2003290300370300200241f0066a41186a200a29030037030020022002290390073703f00641002104200241003a004803402007417f460d05200241086a20046a20062d00003a0000200120073602042001200641016a22063602002002200441016a22083a00482007417f6a210720082104200841c000470d000b200241d0076a41386a200241086a41386a2903002210370300200241d0076a41306a200241086a41306a2903002211370300200241d0076a41286a200241086a41286a2903002212370300200241d0076a41206a200241086a41206a2903002213370300200241d0076a41186a200241086a41186a290300221437030020024190046a41086a2201200241086a41086a29030037030020024190046a41106a2207200241086a41106a29030037030020024190046a41186a2204201437030020024190046a41206a2206201337030020024190046a41286a2208201237030020024190046a41306a2203201137030020024190046a41386a220a20103703002002200229030837039004200241d0066a41186a220d200241f0066a41186a290300370300200241d0066a41106a220c200241f0066a41106a290300370300200241d0066a41086a220f200241f0066a41086a290300370300200220022903f0063703d006200241d0046a41186a2215200d290300370300200241d0046a41106a220d200c290300370300200241d0046a41086a220c200f290300370300200220022903d0063703d004200241f0036a41186a220f200241d0056a41186a290300370300200241f0036a41106a2216200241d0056a41106a290300370300200241f0036a41086a2217200241d0056a41086a290300370300200220022903d0053703f003200241b0056a41186a2218200241b0066a41186a290300370300200241b0056a41106a2219200241b0066a41106a290300370300200241b0056a41086a221a200241b0066a41086a290300370300200220022903b0063703b005200241f0046a41386a221b200241f0056a41386a290300370300200241f0046a41306a221c200241f0056a41306a290300370300200241f0046a41286a221d200241f0056a41286a290300370300200241f0046a41206a221e200241f0056a41206a290300370300200241f0046a41186a221f200241f0056a41186a290300370300200241f0046a41106a2220200241f0056a41106a290300370300200241f0046a41086a2221200241f0056a41086a290300370300200220022903f0053703f004200241f8016a41106a200b3602002002200937038002200241a4026a20182903003702002002419c026a201929030037020020024194026a201a290300370200200220022903b00537028c02200241e4026a201b290300370200200241dc026a201c290300370200200241d4026a201d290300370200200241cc026a201e290300370200200241c4026a201f290300370200200241bc026a2020290300370200200241b4026a2021290300370200200220022903f0043702ac02200241ec026a200e36020020024188036a201529030037030020024180036a200d290300370300200241f8026a200c290300370300200241f0026a20022903d004370300200241c8036a200a290300370300200241c0036a2003290300370300200241b8036a2008290300370300200241b0036a2006290300370300200241a8036a2004290300370300200241a0036a200729030037030020024198036a200129030037030020024190036a200229039004370300200241e8036a200f290300370300200241e0036a2016290300370300200241d8036a2017290300370300200241d0036a20022903f00337030042002109200242003703f801200241f8016a41086a21010c070b0240200741ff0171450d00200241003a00280b200242013703f8010c120b200741ff0171450d10200241003a00280c100b200641ff0171450d0f200241003a00480c0f0b200641ff0171450d01200241003a00280c010b200441ff0171450d00200241003a00480b200242013703f8010c0d0b20084108490d092007290001210920012003416f6a220a3602042001200741096a36020041002107200241003a0028200321060340200a2007460d02200241086a20076a200420076a220841116a2d00003a000020012006416e6a3602042001200841126a3602002002200741016a22083a00282006417f6a21062008210720084120470d000b200241d0056a41086a200241086a41086a290300370300200241d0056a41106a200241086a41106a290300370300200241d0056a41186a200241086a41186a290300370300200220022903083703d00541002107200241003a0028200420086a210b2006416e6a210a200320086b416f6a210c2003210d0340200c2007460d03200241086a20076a200b20076a220e41116a2d00003a00002001200a3602042001200e41126a3602002002200741016a220e3a0028200a417f6a210a200d417f6a210d200e2107200e4120470d000b20024190076a41086a220d200241086a41086a29030037030020024190076a41106a220c200241086a41106a29030037030020024190076a41186a220f200241086a41186a29030037030020022002290308370390072006200e6b220a416f6a4104490d0a2008200e6a2107200b200e6a220641116a280000210b2001200a416b6a360204200241f0066a41086a200d290300370300200241f0066a41106a200c290300370300200241f0066a41186a200f2903003703002001200641156a36020020022002290390073703f00641002106200241003a00482003416b6a210e200441156a210d200a416a6a21080340200e2007460d04200241086a20066a200d20076a220a2d00003a0000200120083602042001200a41016a3602002002200641016a220a3a00482008417f6a2108200741016a2107200a2106200a41c000470d000b200241d0076a41386a200241086a41386a2903002210370300200241d0076a41306a200241086a41306a2903002211370300200241d0076a41286a200241086a41286a2903002212370300200241d0076a41206a200241086a41206a2903002213370300200241f0056a41086a200241086a41086a290300370300200241f0056a41106a200241086a41106a290300370300200241f0056a41186a200241086a41186a290300370300200241f0056a41206a2013370300200241f0056a41286a2012370300200241f0056a41306a2011370300200241f0056a41386a2010370300200220022903083703f005200241d0066a41186a2206200241f0066a41186a290300370300200241d0066a41106a2208200241f0066a41106a290300370300200241d0066a41086a220a200241f0066a41086a290300370300200220022903f0063703d006200241b0066a41186a2006290300370300200241b0066a41106a2008290300370300200241b0066a41086a200a290300370300200220022903d0063703b00641002106200241003a0028200420076a41156a2104200320076b41666a210703402007417b460d05200241086a20066a20042d00003a00002001200741046a3602042001200441016a22043602002002200641016a22083a00282007417f6a21072008210620084120470d000b20024190076a41086a2208200241086a41086a29030037030020024190076a41106a2203200241086a41106a29030037030020024190076a41186a220a200241086a41186a2903003703002002200229030837039007200741056a4104490d062004280000210e2001200741016a3602042001200441046a2206360200200241f0066a41086a2008290300370300200241f0066a41106a2003290300370300200241f0066a41186a200a29030037030020022002290390073703f00641002104200241003a004803402007417f460d06200241086a20046a20062d00003a0000200120073602042001200641016a22063602002002200441016a22083a00482007417f6a210720082104200841c000470d000b200241d0076a41386a200241086a41386a2903002210370300200241d0076a41306a200241086a41306a2903002211370300200241d0076a41286a200241086a41286a2903002212370300200241d0076a41206a200241086a41206a2903002213370300200241d0076a41186a200241086a41186a290300221437030020024190046a41086a2201200241086a41086a29030037030020024190046a41106a2207200241086a41106a29030037030020024190046a41186a2204201437030020024190046a41206a2206201337030020024190046a41286a2208201237030020024190046a41306a2203201137030020024190046a41386a220a20103703002002200229030837039004200241d0066a41186a220d200241f0066a41186a290300370300200241d0066a41106a220c200241f0066a41106a290300370300200241d0066a41086a220f200241f0066a41086a290300370300200220022903f0063703d006200241d0046a41186a2215200d290300370300200241d0046a41106a220d200c290300370300200241d0046a41086a220c200f290300370300200220022903d0063703d004200241f0036a41186a220f200241d0056a41186a290300370300200241f0036a41106a2216200241d0056a41106a290300370300200241f0036a41086a2217200241d0056a41086a290300370300200220022903d0053703f003200241b0056a41186a2218200241b0066a41186a290300370300200241b0056a41106a2219200241b0066a41106a290300370300200241b0056a41086a221a200241b0066a41086a290300370300200220022903b0063703b005200241f0046a41386a221b200241f0056a41386a290300370300200241f0046a41306a221c200241f0056a41306a290300370300200241f0046a41286a221d200241f0056a41286a290300370300200241f0046a41206a221e200241f0056a41206a290300370300200241f0046a41186a221f200241f0056a41186a290300370300200241f0046a41106a2220200241f0056a41106a290300370300200241f0046a41086a2221200241f0056a41086a290300370300200220022903f0053703f004200241f8016a41106a200b3602002002200937038002200241a4026a20182903003702002002419c026a201929030037020020024194026a201a290300370200200220022903b00537028c02200241e4026a201b290300370200200241dc026a201c290300370200200241d4026a201d290300370200200241cc026a201e290300370200200241c4026a201f290300370200200241bc026a2020290300370200200241b4026a2021290300370200200220022903f0043702ac02200241ec026a200e36020020024188036a201529030037030020024180036a200d290300370300200241f8026a200c290300370300200241f0026a20022903d004370300200241c8036a200a290300370300200241c0036a2003290300370300200241b8036a2008290300370300200241b0036a2006290300370300200241a8036a2004290300370300200241a0036a200729030037030020024198036a200129030037030020024190036a200229039004370300200241e8036a200f290300370300200241e0036a2016290300370300200241d8036a2017290300370300200241d0036a20022903f003370300200242003703f801200241f8016a41086a2101420121090b200241086a200141f00110e4071a2000200937030820002005370300200041106a200241086a41f00110e4071a0c0c0b0240200741ff0171450d00200241003a00280b200242013703f8010c0a0b200741ff0171450d07200241003a00280c070b200641ff0171450d06200241003a00480c060b200641ff0171450d01200241003a00280c010b200441ff0171450d00200241003a00480b200242013703f8010c050b200042023703080c050b200242013703f8010c030b200242013703f8010c020b200242013703f8010c010b200242013703f8010b200042023703080b20024190086a24000ba90201067f230041106b22022400024002400240200128020422034104490d0020012802002204280000210520012003417c6a3602042001200441046a36020020022001109e04200228020022030d01200041003602040c020b200041003602040c010b200241086a2802002106200228020421040240200128020422074104490d002000200436020820002003360204200020053602002000410c6a200636020020012802002203280000210420012007417c6a3602042001200341046a360200200041106a20043602000c010b2000410036020402402006450d002006410c6c21002003210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b2004450d002004410c6c450d00200310290b200241106a24000bb01f050a7f037e077f017e177f23004180056b2202240020024180026a41e6d2cdc306109f032002280280022103200228028402210402400240024020022802880222050d004101210641002107410021080c010b02400240024020054105742208410575220941ffffff3f712009470d0020084100480d0020080d01410121060c020b1032000b200810272206450d020b200320086a210a2005410574210b20084105762107410021080340200320086a2205290000210c200541086a290000210d200541106a290000210e200620086a220941186a200541186a290000370000200941106a200e370000200941086a200d3700002009200c370000200b200841206a2208470d000b200a20036b41606a41057641016a21080b0240200441ffffff3f71450d00200310290b200620084105746a210f0240024020012802002210450d0020024100360208200241003602000240024002402008450d00200241c8016a41026a211120024180026a4102722112200241c8016a4101722113200241f8016a211441002108200621150340201541186a290000210d201541106a290000210e2015290000210c200241106a41086a201541086a2900002216370300200241106a41106a200e370300200241106a41186a200d3703002002200c370380022002200c3703102013200c370000201341086a2016370000201341106a200e370000201341186a200d370000200241013a00c801201341206a200241106a41206a2d00003a0000024002402008450d00200228020421050c010b20024180026a410041f60210e6071a41800310272208450d0741002105200841003b010620084100360200200841086a20024180026a41f60210e4071a20024100360204200220083602000b2002200836025c200220053602582002200236026020024180026a200241d8006a200241c8016a10e90402400240024002402002280280024101470d002002280290022108200228028c02211720022802880221182002280284022119200241d8006a41206a2205200241c8016a41206a221a2f01003b0100200241d8006a41186a2204200241c8016a41186a221b290300370300200241d8006a41106a220a200241c8016a41106a221c290300370300200241d8006a41086a221d200241c8016a41086a221e290300370300200220022903c8013703582002200228020841016a360208201a20052f01003b0100201b2004290300370300201c200a290300370300201e201d290300370300200220022903583703c801024020182f01062204410b490d0020024180026a410041f60210e6071a41800310272205450d0b200541003b010620054100360200200541086a20024180026a41f60210e40721092002201841d4016a2f00003b01c4012002201841d6016a2d00003a00c6012002201841e7016a290000370380022002201841ee016a29000037008702201841d7016a280000211f201841db016a2800002120201841df016a2800002121201841e3016a28000021222009201841f6016a20182f010641796a220341226c10e4072109201841063b0106200520033b0106200241c0016a41026a222320022d00c6013a0000200220022f01c4013b01c00120022002290380023703b00120022002290087023700b7010240024020084107490d00200841226c20096a220941b47e6a200941927e6a2209200341ffff037120086b41226c41ee016a10e5071a200941206a201a2f01003b0000200941186a201b290300370000200941106a201c290300370000200941086a201e290300370000200920022903c801370000200520052f010641016a3b01060c010b201841086a200841226c6a220941226a200920182f010620086b41226c10e5071a200941206a201a2f01003b0000200941186a201b290300370000200941106a201c290300370000200941086a201e290300370000200920022903c801370000201820182f010641016a3b01060b200241ac016a41026a20232d000022083a000020024194016a41026a222420083a0000200220022900b70137009f01200220022903b00137039801200220022f01c00122083b01ac012002200229009f0137008701200220022903980137038001200220083b0194010240201828020022040d0041002108200521090c040b20182f010421254100210820052126201921270340202320242d00003a0000200220022f0194013b01c001200220022903800137039801200220022900870137009f0120272008470d03202541ffff0371210b02400240024020042f01062208410b490d002012410041f80210e6071a201141286a4200370100201141206a4200370100201141186a4200370100201141106a4200370100201141086a42003701002011420037010041b00310272209450d0f20094100360200200941046a20024180026a41fa0210e4071a200941ae036a20142f01003b0100200941a6036a200241c8016a41286a2901003701002009419e036a201a29010037010020094196036a201b2901003701002009418e036a201c29010037010020094186036a201e290100370100200920022901c8013701fe02200241b0016a41026a221d200441d6016a2d00003a00002002200441d4016a2f00003b01b0012002200441e7016a290000370380022002200441ee016a29000037008702200441d7016a2800002128200441db016a2800002129200441df016a280000212a200441e3016a280000212b200941086a200441f6016a20042f0106220841796a220541226c10e407212c20094180036a2004419c036a2008417a6a220a41027410e407212d200441063b0106200920053b01060240200a450d0041002108202d210503402005280200220320083b010420032009360200200541046a2105200a200841016a2208470d000b0b200220022f01b00122083b01c40120022002290380023703c80120022002290087023700cf012002201d2d000022053a00c601201d20053a0000200220083b01b001200220022903c80137038002200220022900cf0137008702202541ffff037122054107490d01200b41226c202c6a220841b47e6a200841927e6a220820092f0106200b6b41226c41ee016a10e5071a2008202236000f2008202136000b200820203600072008201f360003200841026a20232d00003a0000200820022f01c0013b000020082002290398013700132008411a6a200229009f01370000200920092f010641016a22053b0106200b4102742225202d6a416c6a202d200b417a6a22084102746a2203200541ffff0371220a20086b41027410e5071a20032026360200200a2008490d02200b41796a2108200920256a41e8026a2105034020052802002203200841016a22083b010420032009360200200541046a21052008200a490d000c030b0b2004200b41226c6a2205412a6a200541086a22092008200b6b41226c10e5071a200541176a2022360000200541136a20213600002005410f6a20203600002005410b6a201f3600002005410a6a20232d00003a0000200920022f01c0013b00002005411b6a200229039801370000200541226a200229009f01370000200420042f010641016a22053b0106200b41027420044180036a22096a41086a2009200b41016a22084102746a2209200541ffff0371220320086b41027410e5071a20092026360200200b20034f0d0720042008417f6a22084102746a4184036a2105034020052802002209200841016a22083b010420092004360200200541046a210520082003490d000c080b0b200441086a200b41226c6a220841226a200820042f0106200b6b41226c10e5071a2008202236000f2008202136000b200820203600072008201f360003200841026a20232d00003a0000200820022f01c0013b000020082002290398013700132008411a6a200229009f01370000200420042f010641016a22083b0106200b410274222d20044180036a22036a41086a2003200b41016a220a4102746a2225200841ffff03712203200a6b41027410e5071a20252026360200200520034f0d002004202d6a4184036a2108034020082802002205200b41016a220b3b010420052004360200200841046a21082003200b470d000b0b202741016a21082024201d2d00003a0000200220022f01b0013b0194012002200229038002370380012002200229008702370087010240200428020022050d0020292120202a2121202b21222028211f0c050b20042f0104212520292120202a2121202b21222028211f2005210420092126200821270c000b0b2018200841226c6a2205412a6a200541086a220a200420086b41226c10e5071a200541286a201a2f01003b0000200541206a201b290300370000200541186a201c290300370000200541106a201e290300370000200a20022903c801370000201820182f010641016a3b01060b2009211920032118200b21170c020b41cc9ec800413541b8a1cc001033000b2012410041f80210e6071a201141286a4200370100201141206a4200370100201141186a4200370100201141106a4200370100201141086a42003701002011420037010041b00310272205450d0720054100360200200541046a20024180026a41fa0210e4071a200541ae036a20142f01003b0100200541a6036a200241c8016a41286a2901003701002005419e036a201a29010037010020054196036a201b2901003701002005418e036a201c29010037010020054186036a201e290100370100200520022901c8013701fe02200520172802002203360280032017200536020020172017280204220b41016a360204200341003b010420032005360200201120242d00003a0000200220022903800137038002200220022900870137008702200220022f0194013b01c801200b2008470d0320052f01062203410a4b0d042005200341226c6a2208410a6a20112d00003a0000200841086a20022f01c8013b0000200841176a2022360000200841136a20213600002008410f6a20203600002008410b6a201f3600002008411b6a200229038002370000200841226a2002290087023700002005200341016a22084102746a4180036a2009360200200520083b0106200920083b0104200920053602000b201541206a2215200f460d012002280200210820192109201821032017210b0c000b0b02402007450d00200610290b200241c8016a41086a200241086a280200220836020020022002290300220c3703c80120024180026a41086a220520083602002002200c37038002200141086a2802002109411810272208450d042008410036020820082010360200200820022903800237020c20082010200941226c6a360204200841146a200528020036020041a4f5c90021050c030b41b69cc800413041b8a1cc001033000b418f9cc800412741b8a1cc001033000b411410272208450d01200841003602102008200f36020c200820063602082008200736020420082006360200418cf3c90021050b200020053602042000200836020020024180056a24000f0b1030000b9d3505027f047e087f017e027f230041a01c6b2203240020012802002101200341106a200241c80010e4071a20012802002802002204280200220241106a220129030021052002290300210620022903082107200341a0106a41186a200241f8016a290000370300200341a0106a41106a200241f0016a290000370300200341a8106a200241e8016a2900003703002003200241e0016a2900003703a010420121080240024020074201520d00200341f0126a410c6a200141146a290000370200200341f0126a41146a2001411c6a290000370200200341f0126a411c6a200141246a290000370200200341f0126a412c6a200141346a290000370200200341f0126a41346a2001413c6a290000370200200341f0126a413c6a200141c4006a290000370200200341f0126a41c4006a200141cc006a290000370200200341f0126a41cc006a200141d4006a290000370200200341f0126a41d4006a200141dc006a290000370200200341f0126a41dc006a200141e4006a29000037020020032001410c6a2900003702f4122003200241186a2802003602f01220032001412c6a29000037029413200341900a6a410c6a20024188016a290000370200200341900a6a41146a20024190016a290000370200200341900a6a411c6a20024198016a290000370200200320024180016a2900003702940a2003200228027c3602900a200341900a6a2101200341f0126a21090c010b200341f0126a410c6a200141146a290000370200200341f0126a41146a2001411c6a290000370200200341f0126a411c6a200141246a290000370200200341f0126a412c6a200141346a290000370200200341f0126a41346a2001413c6a290000370200200341f0126a413c6a200141c4006a290000370200200341f0126a41c4006a200141cc006a290000370200200341f0126a41cc006a200141d4006a290000370200200341f0126a41d4006a200141dc006a290000370200200341f0126a41dc006a200141e4006a29000037020020032001410c6a2900003702f4122003200241186a2802003602f01220032001412c6a29000037029413200341900a6a410c6a20024188016a290000370200200341900a6a41146a20024190016a290000370200200341900a6a411c6a20024198016a290000370200200320024180016a2900003702940a2003200228027c3602900a42002108200341900a6a2101200341f0126a21090b200141dc006a200241d8016a290000370000200141d4006a200241d0016a290000370000200141cc006a200241c8016a290000370000200141c4006a200241c0016a2900003700002001413c6a200241b8016a290000370000200141346a200241b0016a2900003700002001412c6a200241a8016a2900003700002001200241a0016a290000370024200341e8006a41086a200341a0106a41086a290300370300200341e8006a41106a200341a0106a41106a290300370300200341e8006a41186a200341a0106a41186a290300370300200320032903a010370368200341f0016a200941e40010e4071a20034188016a200141e40010e4071a200428020422022802002109200341d8006a200241046a10b5042002280210210a200341a0106a200341106a410472220b10a802200341900a6a20032802a010220220032802a81010a902200341f0126a41086a2201200341900a6a41106a290300370300200341f0126a41106a2204200341900a6a41186a290300370300200341f0126a41186a220c200341900a6a41206a290300370300200341f0126a41206a220d200341900a6a41286a290300370300200341f0126a41286a220e200341900a6a41306a290300370300200341f0126a41306a220f200341900a6a41386a290300370300200341f0126a41386a2210200341d00a6a290300370300200320032903980a3703f0120240024020032903900a4201510d00200341d8026a41386a4200370300200341d8026a41306a4200370300200341d8026a41286a4200370300200341d8026a41206a4200370300200341d8026a41186a4200370300200341d8026a41106a4200370300200341d8026a41086a4200370300200342003703d80241002110410021040c010b200341d8026a41086a2001290300370300200341d8026a41106a2004290300370300200341d8026a41186a200c290300370300200341d8026a41206a200d290300370300200341d8026a41286a200e290300370300200341d8026a41306a200f290300370300200341d8026a41386a2010290300370300200320032903f0123703d802200341d80a6a280200210420032802dc0a21100b024020032802a410450d00200210290b200341e0086a200341f0016a41e40010e4071a200341fc076a20034188016a41e40010e4071a200341d8076a41186a200341e8006a41186a290300370300200341d8076a41106a200341e8006a41106a290300370300200341d8076a41086a200341e8006a41086a290300370300200341c8076a41086a200341d8006a41086a280200360200200320032903683703d807200320032903583703c807024002400240024020032d00340e03010200010b200341e8096a200341d5006a2d00003a0000200341c8096a41186a200341cd006a290000370300200341c8096a41106a200341c5006a290000370300200341c8096a41086a2003413d6a2900003703002003200341356a2900003703c8094102210f0c020b200341c8096a41186a200341cd006a290000370300200341c8096a41106a200341c5006a290000370300200341c8096a41086a2003413d6a2900003703002003200341356a2900003703c8094100210f0c010b200341c8096a41186a200341cd006a290000370300200341c8096a41106a200341c5006a290000370300200341c8096a41086a2003413d6a2900003703002003200341356a2900003703c8094101210f0b200341f0096a41186a2003412c6a290200370300200341f0096a41106a200341246a290200370300200341f0096a41086a2003411c6a290200370300200320032902143703f009200341900a6a41186a4200370300200341900a6a41106a220c4200370300200341900a6a41086a22024200370300200342003703900a41b3e6ca00ad4280808080e000841001220129000021072002200141086a290000370300200320073703900a2001102941c9e6ca00ad4280808080e00084100122012900002107200341a0176a41086a220d200141086a290000370300200320073703a01720011029200c20032903a0172207370300200341f0126a41086a22012002290300370300200341f0126a41106a22022007370300200341f0126a41186a220c200d290300370300200320032903900a3703f012200341086a200341f0126a412010fc01200328020c210d2003280208210e200c200537030020022008370300200120063703002003410b3602f012200341f0126a41206a200341e0086a41e40010e4071a200341f4136a200341fc076a41e40010e4071a200341f8146a200936020020034188156a200a360200200341f0146a200341d8076a41186a290300370300200341e8146a200341d8076a41106a290300370300200341e0146a200341d8076a41086a290300370300200341d8146a20032903d807370300200341fc146a20032903c80737020020034184156a200341c8076a41086a2802003602002003418c156a20032902bc0737020020034194156a200341bc076a41086a280200360200200341b81a6a41206a22014200370300200341b81a6a41106a22094200200d4100200e1bad2208427f7c220520052008561b42ff0f83370300200342003703d01a200320043602e01a20034280103703c01a42012105200342013703b81a200341b01b6a200341b81a6a10820620032d00b01b210220032f00b11b210a20032d00b31b210c200341c8196a200341b01b6a41047241c80010e4071a0240024020024101470d00200341f0126a10cc012003200a200c4110747222023b01c819200320024110763a00ca19024041002802d8a74c4102490d002003411b3602b41b2003200341c8196a3602b01b41002802888040210241002802848040210141002802dca74c2109200341b0136a41ef04360200200341a8136a42b480808010370300200341a4136a4198a5c7003602002003419c136a421037020020034198136a4188a5c70036020020034190136a4201370300200341f0126a41106a4201370300200341f8126a41103602002003418c136a200341b01b6a36020020034180a5c7003602fc1220034188a5c7003602f412200341023602f01220014180a4c000200941024622091b200341f0126a20024198a4c00020091b2802101102000b420221050c010b200341e81a6a200341c8196a41c80010e4071a200341b01b6a41206a200341b81a6a41286a290300370300200341b01b6a41186a2001290300370300200341b01b6a41106a200341b81a6a41186a290300370300200341b01b6a41086a2009290300370300200320032903c01a3703b01b200341b01b6a41286a200341e81a6a41c80010e4071a200341900a6a41046a200341f0126a41a80210e4072102200341c8196a200341b01b6a41f00010e4071a200341f0126a200241a80210e4071a200341a0176a200341f0126a41a80210e4071a200341b0166a200341c8196a41f00010e4071a0b200341f0126a200341a0176a41a80210e4071a200341b01b6a200341b0166a41f00010e4071a4202210802400240024020054202510d00200341900a6a200341f0126a41a80210e4071a200341c0156a200341b01b6a41f00010e4071a200320053703b80c200341c00c6a200341c0156a41f00010e4072101200341b0166a41206a200341c8096a41206a2d00003a0000200341b0166a41186a200341c8096a41186a290300370300200341b0166a41106a200341c8096a41106a290300370300200341b0166a41086a200341c8096a41086a290300370300200320032903c8093703b016410810272202450d02200342083702f412200320023602f012200341900a6a200341f0126a10bf02200341900a6a41a8026a200341f0126a10be02200341e80c6a200341f0126a10800620032802f412210a20032802f012210902400240024020032802f81222024180024b0d00200341f0126a41206a200341b0166a41206a2d00003a0000200341f0126a41186a220c200341b0166a41186a290300370300200341f0126a41106a220d200341b0166a41106a290300370300200341f0126a41086a220e200341b0166a41086a290300370300200320032903b0163703f012200f4101470d01200341b01b6a41186a200c2903002208370300200341b01b6a41106a200d2903002205370300200341e81a6a41106a2005370300200341e81a6a41186a2008370300200341e81a6a41086a200e2903002206370300200320032903f01222073703e81a200341c0156a41186a2008370300200341c0156a41106a2005370300200341c0156a41086a2006370300200320073703c015200341f0126a41e6d2cdc306200341c0156a2009200210950620032d00f0124101470d01200341b01b6a41386a200341a9136a2900002208370300200341b01b6a41306a200341a1136a2900002205370300200341b01b6a41286a20034199136a2900002206370300200341b01b6a41206a20034191136a2900002207370300200341b01b6a41186a20034189136a2900002211370300200341c8196a41086a2202200341f9126a290000370300200341c8196a41106a220c20034181136a290000370300200341c8196a41186a220d2011370300200341c8196a41206a220e2007370300200341c8196a41286a220f2006370300200341c8196a41306a22122005370300200341c8196a41386a22132008370300200320032900f1123703c819200341a0176a41386a2013290300370300200341a0176a41306a2012290300370300200341a0176a41286a200f290300370300200341a0176a41206a200e290300370300200341a0176a41186a200d290300370300200341a0176a41106a200c290300370300200341a0176a41086a2002290300370300200320032903c8193703a017410121020c020b2002ad4220862009ad84101022022900002108200241086a2900002105200241106a2900002106200341b81a6a41186a200241186a290000370300200341b81a6a41106a2006370300200341b81a6a41086a2005370300200320083703b81a20021029200341f0126a41206a200341b0166a41206a2d00003a0000200341f0126a41186a2202200341b0166a41186a290300370300200341f0126a41106a220c200341b0166a41106a290300370300200341f0126a41086a220d200341b0166a41086a290300370300200320032903b0163703f012200f4101470d00200341b01b6a41186a20022903002208370300200341b01b6a41106a200c2903002205370300200341e81a6a41106a2005370300200341e81a6a41186a2008370300200341e81a6a41086a200d2903002206370300200320032903f01222073703e81a200341c0156a41186a2008370300200341c0156a41106a2005370300200341c0156a41086a2006370300200320073703c015200341f0126a41e6d2cdc306200341c0156a200341b81a6a412010950620032d00f0124101470d00200341b01b6a41386a200341a9136a2900002208370300200341b01b6a41306a200341a1136a2900002205370300200341b01b6a41286a20034199136a2900002206370300200341b01b6a41206a20034191136a2900002207370300200341b01b6a41186a20034189136a2900002211370300200341c8196a41086a2202200341f9126a290000370300200341c8196a41106a220c20034181136a290000370300200341c8196a41186a220d2011370300200341c8196a41206a220e2007370300200341c8196a41286a220f2006370300200341c8196a41306a22122005370300200341c8196a41386a22132008370300200320032900f1123703c819200341a0176a41386a2013290300370300200341a0176a41306a2012290300370300200341a0176a41286a200f290300370300200341a0176a41206a200e290300370300200341a0176a41186a200d290300370300200341a0176a41106a200c290300370300200341a0176a41086a2002290300370300200320032903c8193703a017410121020c010b410321020b0240200a450d00200910290b200341f0126a200341a0176a41c10010e4071a024020024103460d00200341fb066a200341f0126a41c10010e4071a20032903b80c2108200341f0126a200341900a6a41a80210e4071a200341d0066a41206a200141206a290300370300200341d0066a41186a200141186a290300370300200341d0066a41106a200141106a290300370300200341d0066a41086a200141086a290300370300200341a0156a200341f0096a41086a290300370300200341a8156a200341f0096a41106a290300370300200341b0156a200341f0096a41186a290300370300200320012903003703d006200320032903f00937039815200341a0106a200341f0126a41c80210e4071a0c020b200341900a6a10cc01420221080b0b200341900a6a200341a0106a41c80210e4071a200341f0126a200341fb066a41c10010e4071a200341a0176a41206a2201200341d0066a41206a290300370300200341a0176a41186a2209200341d0066a41186a290300370300200341a0176a41106a220a200341d0066a41106a290300370300200341a0176a41086a220c200341d0066a41086a290300370300200320032903d0063703a01702400240024020084202510d00200341d00d6a200341900a6a41c80210e4071a200341c7036a200341f0126a41c10010e4071a20034198036a41206a220d200129030037030020034198036a41186a2201200929030037030020034198036a41106a2209200a29030037030020034198036a41086a220a200c290300370300200320032903a0173703980320034188046a200341d00d6a41c80210e4071a200341a0176a200341d00d6a41a80210e4071a200341c0156a41086a220c200341b8066a290300370300200341c0156a41106a220e200341c0066a290300370300200341c0156a41186a220f200341c8066a290300370300200320032903b0063703c015200341b01b6a200341c7036a41c10010e4071a200341c8196a41206a2212200d290300370300200341c8196a41186a220d2001290300370300200341c8196a41106a22012009290300370300200341c8196a41086a2209200a29030037030020032003290398033703c819200341b0166a41086a200c290300370300200341b0166a41106a200e290300370300200341b0166a41186a200f290300370300200320032903c0153703b01620034188046a200341b01b6a41c10010e4071a200341f0126a41206a2012290300370300200341f0126a41186a200d290300370300200341f0126a41106a2001290300370300200341f0126a41086a2009290300370300200320032903c8193703f01220034198136a200341a0176a41a80210e4071a200341a0106a200341f0126a41d00210e4071a20084203520d01410121020c020b410221020c010b200341900a6a41186a2209200341b0166a41186a290300370300200341900a6a41106a220a200341b0166a41106a290300370300200341900a6a41086a220c200341b0166a41086a290300370300200320032903b0163703900a200320023a00b00a200341b10a6a20034188046a41c10010e4071a200341f60a6a200341e4086a2f01003b0100200320032801e0083601f20a200341d00d6a200341a0106a41d00210e4071a200320083703f80a200341800b6a200341d00d6a41d00210e4071a2003200341900a6a3602a010200341f0126a200341a0106a10bd0220032802f01220032802f41220032802f81210de022101200341a80b6a10cc014101210220010d00200341900a6a41386a200341d8026a41386a290300370300200341900a6a41306a200341d8026a41306a290300370300200341900a6a41286a200341d8026a41286a290300370300200341900a6a41206a200341d8026a41206a2903003703002009200341d8026a41186a290300370300200a200341d8026a41106a290300370300200c200341d8026a41086a290300370300200320032903d8023703900a200320103602d40a2003200441016a3602d00a200b200341900a6a10c502410021020b200341900a6a200341106a41c80010e4071a41022101024020024102460d002000200341900a6a41c80010e4071a200241017121010b200020013a0048200341a01c6a24000f0b1039000b040041000b0d00200141fcacc7004102104d0bcc3508047f017e017f017e027f027e117f057e230041f0046b22022400024002400240024002400240024020014108490d0041002103200241003a00a00320004180a6cc0020011b41086a2100200141786a2104034020042003460d0720024180036a20036a200020036a2d00003a00002002200341016a22013a00a0032001210320014120470d000b200241086a41186a20024180036a41186a22052903002206370300200241086a41106a20024180036a41106a2207290300220837030041082109200241086a41086a20024180036a41086a220a290300220b3703002002200229038003220c370308200241286a41186a2006370300200241286a41106a2008370300200241286a41086a200b3703002002200c3703282005420037030020074200370300200a4200370300200242003703800341b1dcc900ad4280808080f000842206100122032900002108200a200341086a290000370300200220083703800320031029418886ca00ad4280808080c00184100122012900002108200241a0026a41086a2203200141086a290000370300200220083703a00220011029200720022903a0022208370300200241c8006a41086a2200200a290300370300200241c8006a41106a22042008370300200241c8006a41186a220d200329030037030020022002290380033703482002200241c8006a412010fc012002280204210e2002280200210f2005420037030020074200370300200a420037030020024200370380032006100122012900002106200a200141086a29000037030020022006370380032001102941b8dcc900ad4280808080a001841001220129000021062003200141086a290000370300200220063703a00220011029200720022903a00222063703002000200a29030037030020042006370300200d2003290300370300200220022903800337034820024180036a200241c8006a108d02200229028403420020022802800322031b2206a721102003410120031b211102402006422088a72203450d00200341057441406a210020024180036a41206a211220112103034020024190046a41186a2201200341186a220429000037030020024190046a41106a220d200341106a221329000037030020024190046a41086a2214200341086a22152900003703002002200329000037039004200241b0046a41186a22162004290000370300200241b0046a41106a22042013290000370300200241b0046a41086a22132015290000370300200220032900003703b004200520012903003703002007200d290300370300200a2014290300370300200220022903900437038003200241c0016a20024180036a10a002200241d0046a41186a2016290300370300200241d0046a41106a2004290300370300200241d0046a41086a2013290300370300200220022903b0043703d004024020022802e0012201450d00201220022903c001370300201241186a200241c0016a41186a290300370300201241106a200241c0016a41106a290300370300201241086a200241c0016a41086a29030037030020024180036a41186a2204200241d0046a41186a29030037030020024180036a41106a220d200241d0046a41106a29030037030020024180036a41086a2213200241d0046a41086a290300370300200220022903d00437038003200241c0016a41286a290300210620022802e4012107200241a0026a41386a220520024180036a41386a2214290300370300200241a0026a41306a220920024180036a41306a2215290300370300200241a0026a41286a221220024180036a41286a2216290300370300200241a0026a41206a221720024180036a41206a220a290300370300200241a0026a41186a22182004290300370300200241a0026a41106a2219200d290300370300200241a0026a41086a221a201329030037030020022002290380033703a002200241c8006a41386a221b2005290300370300200241c8006a41306a22052009290300370300200241c8006a41286a22092012290300370300200241c8006a41206a22122017290300370300200241c8006a41186a22172018290300370300200241c8006a41106a22182019290300370300200241c8006a41086a2219201a290300370300200220022903a0023703482014201b2903003703002015200529030037030020162009290300370300200a201229030037030020042017290300370300200d201829030037030020132019290300370300200220022903483703800341d00010272209450d062009200229038003370300200920063702482009200736024420092001360240200941386a2014290300370300200941306a2015290300370300200941286a2016290300370300200941206a200a290300370300200941186a2004290300370300200941106a200d290300370300200941086a20132903003703002002428180808010370284042002200936028004024020004160470d00410121140c050b200341206a210320024180036a41206a210441012114034020024190046a41186a220d200341186a220129000037030020024190046a41106a2213200341106a221529000037030020024190046a41086a2216200341086a220a2900003703002002200329000037039004200241b0046a41186a22072001290000370300200241b0046a41106a22052015290000370300200241b0046a41086a2215200a290000370300200220032900003703b00420024180036a41186a2201200d29030037030020024180036a41106a220d201329030037030020024180036a41086a22132016290300370300200220022903900437038003200241c0016a20024180036a10a002200241d0046a41186a22162007290300370300200241d0046a41106a220a2005290300370300200241d0046a41086a22072015290300370300200220022903b0043703d0040240024020022802e0012205450d00200420022903c001370300200441186a200241c0016a41186a290300370300200441106a200241c0016a41106a290300370300200441086a200241c0016a41086a29030037030020012016290300370300200d200a29030037030020132007290300370300200220022903d0043703800320022802e401210720022903e8012106200241a0026a41386a221220024180036a41386a2215290300370300200241a0026a41306a221720024180036a41306a2216290300370300200241a0026a41286a221820024180036a41286a220a290300370300200241a0026a41206a22192004290300370300200241a0026a41186a221a2001290300370300200241a0026a41106a221b200d290300370300200241a0026a41086a221c201329030037030020022002290380033703a002200241c8006a41386a221d2012290300370300200241c8006a41306a22122017290300370300200241c8006a41286a22172018290300370300200241c8006a41206a22182019290300370300200241c8006a41186a2219201a290300370300200241c8006a41106a221a201b290300370300200241c8006a41086a221b201c290300370300200220022903a0023703482015201d29030037030020162012290300370300200a20172903003703002004201829030037030020012019290300370300200d201a2903003703002013201b290300370300200220022903483703800302402014200228028404470d0020024180046a2014410110ac0120022802800421090b20132903002108200d290300210b2001290300210c2004290300211e200a290300211f201629030021202015290300212120022903800321222009201441d0006c6a22012006370248200120073602442001200536024020012022370300200141386a2021370300200141306a2020370300200141286a201f370300200141206a201e370300200141186a200c370300200141106a200b370300200141086a20083703002002201441016a22143602880420000d010c070b2000450d060b200341206a2103200041606a21000c000b0b200341206a2103200041606a22004140470d000b0b0240201041ffffff3f71450d00201110290b41002103410021140c020b200241d4006a410436020020024194036a41023602002002420237028403200241a0d1c200360280032002410436024c200241f8d3c200360248200241003602a40220024180a6cc003602a0022002200241c8006a360290032002200241a0026a36025020024180036a41b0d1c2001040000b0240201041ffffff3f71450d00201110290b20022802840421030b200220143602d804200220033602d404200220093602d00420024180036a200241d0046a10bb034100210302402002280280034101460d00200241b0046a41106a20024198036a280200360200200241b0046a41086a20024180036a41106a290300370300200220024180036a41086a2903003703b0042002419c036a2802002103200241a0026a200241a0036a41e00010e4071a0b200241d0046a41086a2201200241b0046a41086a290300370300200241d0046a41106a2200200241b0046a41106a280200360200200220022903b0043703d00420024180036a200241a0026a41e00010e4071a0240024002402003450d00200241c8006a41106a2000280200360200200241c8006a41086a2001290300370300200220022903d004370348200241c0016a20024180036a41e00010e4071a200241dc006a2003360200200241c8006a41186a200241c0016a41e00010e4071a200241c0016a41186a200241286a41186a290300370300200241c0016a41106a200241286a41106a290300370300200241c0016a41086a200241286a41086a290300370300200220022903283703c001024002400240200241a0016a2203200241fc006a412010e707450d0020024180036a41186a200341186a29000037030020024180036a41106a200341106a29000037030020024180036a41086a200341086a2900003703002002200329000037038003200241c8006a20024180036a10bc032201450d01200128020c4101480d010b200242003703b804200242043703b004412410272201450d05200141e7e485f3063600002002200136028003200242a4808080c00037028403412020024180036a107102400240200228028403220420022802880322006b4120490d0020022802800321012004210d0c010b200041206a22012000490d072004410174220d2001200d20014b1b220d4100480d070240024020040d000240200d0d00410121010c020b200d102722010d010c0a0b20022802800321012004200d460d0020012004200d102b2201450d090b2002200d3602840320022001360280030b200120006a220420022903c001370000200441186a200241c0016a41186a290300370000200441106a200241c0016a41106a290300370000200441086a200241c0016a41086a29030037000020024194036a200341086a2902003702002002419c036a200341106a290200370200200241a4036a200341186a29020037020020024188a8c800360284032002200329020037028c032002200241b0046a360288032002200241c8006a3602800341002104200241003602d8042002200041206a3602d404200220013602d004200241a0026a20024180036a200241d0046a10bd03024002400240024020022802a0024101470d00024020022802a40222002d0000221341034b0d00024020130e0403030003030b200041086a280200450d02200041046a28020010290c020b200041286a280200450d01200041246a28020010290c010b20022802a4022213450d0141002100410021040240200241a0026a41086a2903002206422088a74104490d0020132800002100410121040b2006a7450d02201310290c020b200010290b0b0240200d450d00200110290b02402004450d00200220003602800420024194036a200341086a2902003702002002419c036a200341106a290200370200200241a4036a200341186a29020037020020024188a8c800360284032002200329020037028c032002200241b0046a360288032002200241c8006a36028003200242043702d404200220024180046a3602d004200241a0026a20024180036a200241d0046a10bd030240024020022802a0024101470d00024020022802a40222032d0000220141034b0d00024020010e0403030003030b200341086a280200450d02200341046a28020010290c020b200341286a280200450d01200341246a2802001029200310290c020b20022802a4022200450d01200241a0026a41086a2903002106200220003602900420022006422088a722043602940441002103200241003a00c002024002400240034020042003460d01200241a0026a20036a200020036a22012d00003a00002002200141016a360290042002200341016a22013a00c0022001210320014120470d000b200241d0046a41086a2203200241a0026a41086a220d290300370300200241d0046a41106a2213200241a0026a41106a2215290300370300200241d0046a41186a2216200241a0026a41186a290300370300200220022903a0023703d0042002200420016b36029404200241a0026a20024190046a10830220022802c00222010d01410021010c020b4100210120024100360294040240200341ff0171450d00200241003a00c0020b0c010b20024180036a41186a201629030037030020024180036a41106a201329030037030020024180036a41086a2003290300370300200241a8036a200d290300370300200241b0036a2015290300370300200220022903d00437038003200220022903a0023703a003200241c4026a28020021030b02402006a7450d00200010290b2001450d0102402003450d00200341306c450d00200110290b20022802b8042103200241003602b80420022802b404211520022802b0042116200242043703b0042002410036028803200242043703800320024180036a4100200341306c220141306d109d0120022802880321000240024020030d0020022000360288030c010b201620016a2113200341306c2104201641306a21032002280280032000410c6c6a210102400340200341546a280200220d450d01200141046a200341586a2902003702002001200d3602002001410c6a2101200341306a2103200041016a2100200441506a22040d000b201321030b2002200036028803201320036b450d000340200341306a21010240200341086a280200450d00200341046a28020010290b2001210320132001470d000b0b02402015450d00201541306c450d00201610290b2002290284032106200228028003210a024020022802b8042203450d00200341306c210120022802b00441046a210303400240200341046a280200450d00200328020010290b200341306a2103200141506a22010d000b0b20022802b4042203450d03200341306c450d0320022802b00410290c030b200310290b024020022802b8042203450d00200341306c210120022802b00441046a210303400240200341046a280200450d00200328020010290b200341306a2103200141506a22010d000b0b20022802b4042203450d00200341306c450d0020022802b00410294100210a0c010b4100210a0b024020022802582200450d00200228025c220141046a2103200020016a41016a21042001280200417f7341808182847871210d200228026021010240034002400240200d450d00200d21000c010b0340200320044f0d03200141c0016a210120032802002100200341046a220d21032000418081828478712200418081828478460d000b2000418081828478732100200d21030b2000417f6a200071210d200120006841037641306c6a220041246a280200450d00200028022010290c000b0b02402002280258220341086a200341056a490d00200341016aad42307e422088a71a0b200228025c10290b0240200241f4006a280200450d00200228027010290b200a450d0020024100360288032002420137038003410410272203450d05200241043602840320022003360280032003200e4100200f1b36000020024104360288032006422088a7220720024180036a10710240024020070d00200228028403211320022802880321030c010b200a2007410c6c6a2116200a2101034020012802002115200141086a280200220320024180036a107102400240200228028403220420022802880322006b2003490d00200228028003210d200421130c010b200020036a220d2000490d0720044101742213200d2013200d4b1b22134100480d070240024020040d00024020130d004101210d0c020b20131027220d450d0a0c010b200228028003210d20042013460d00200d20042013102b220d450d090b20022013360284032002200d360280030b200d20006a2015200310e4071a2002200020036a2203360288032001410c6a22012016470d000b0b02400240201320036b4104490d0020022802800321000c010b200341046a22012003490d05201341017422002001200020014b1b22014100480d050240024020130d00024020010d00410121000c020b200110272200450d080c010b200228028003210020132001460d00200020132001102b2200450d070b200220013602840320022000360280030b2006a72104200020036a20143600002002200341046a36028803200229028403210602402007450d002007410c6c2101200a210303400240200341046a280200450d00200328020010290b2003410c6a2103200141746a22010d000b0b02402004450d002004410c6c450d00200a10290b20000d010b410021000c010b2006422088a721012006a7210d0b410110272203450d00200242013702840320022003360280030240024020000d0041002101200341003a000042808080801021060c010b200341013a00002002410136028803200120024180036a107102400240200228028403221320022802880322046b2001490d0020022802800321030c010b200420016a22032004490d03201341017422142003201420034b1b22144100480d030240024020130d00024020140d00410121030c020b201410272203450d060c010b200228028003210320132014460d00200320132014102b2203450d050b200220143602840320022003360280030b200320046a2000200110e4071a200420016aad4220862106200021010b20062003ad84210602402000450d00200d450d00200110290b200241f0046a240020060f0b1039000b1032000b1030000b0240200341ff0171450d00200241003a00a0030b20024194036a4102360200200241d4006a41043602002002420237028403200241a0d1c200360280032002410436024c200241f8d3c200360248200241003602a40220024180a6cc003602a0022002200241c8006a360290032002200241a0026a36025020024180036a41b0d1c2001040000b992205027f027e067f027e177f230041a0086b220224000240024002400240410110272203450d00200341003a000041004100350280804042adfed5e4d485fda8d8007e200241c0056aad7c421f8922043e02808040200241086a41206a4100360200200241086a41186a4204370300200241086a41146a418cc5c000360200200241003602182002418080c000ad220537030820022004370310200241c0056a41186a220641b4e0c800ad4280808080108422041010220741186a290000370300200241c0056a41106a2208200741106a290000370300200241c0056a41086a2209200741086a290000370300200220072900003703c00520071029200241086a412c6a428180808010370200200241d4006a2006290300370200200241cc006a2008290300370200200241086a413c6a200929030037020020022003360230200220022903c00537023c200241e0006a41186a22034200370300200241e0006a41106a220a4200370300200241e0006a41086a220b420037030020024200370360200620041010220741186a2900003703002008200741106a2900003703002009200741086a290000370300200220072900003703c0052007102920032006290300370300200a2008290300370300200b2009290300370300200220022903c0053703602004101022072900002104200741086a290000210c200741106a290000210d2006200741186a2900003703002008200d3703002009200c370300200220043703c00520071029412010272207450d0041004100350280804042adfed5e4d485fda8d8007e200241f8066aad7c421f8922043e0280804020024180016a412c6a420037020020024180016a41206a410036020020024180016a41186a420437030020024180016a41146a418cc5c000360200200241b4016a420037020020024180016a41c8006a419ca8c80036020020024180016a41c0006a410836020020024180016a413c6a20073602002002410036029001200241013a00d001200220053703800120022004370388012002200241e0006a3602cc012002200241086a3602c401200241043602a801200241e9016a2006290300370000200241e1016a2008290300370000200241d9016a2009290300370000200241d1016a20022903c005370000200241003602f4012001280200220e2001280208220641d0006c22086a210f20012802042110200e21072006450d0120024198026a41046a2111200241c0056a41046a2112200e4194016a2113200841b07f6a2114200241c0056a41306a2115200241c0056a41206a211620024180036a41206a211720024180036a41c0006a2118200241e0036a211920024180046a211a200241c0056a410172211b2002419c076a211c4100211d200e21070340200241a0046a41386a200741386a2208290300370300200241a0046a41306a200741306a2201290300370300200241a0046a41286a200741286a2203290300370300200241a0046a41206a200741206a220a290300370300200241a0046a41186a200741186a220b290300370300200241a0046a41106a200741106a221e290300370300200241a0046a41086a200741086a221f290300370300200220072903003703a004200741c0006a2802002106200741c4006a2802002109200741c8006a2902002104200241c0056a41386a2220200829030037030020152001290300370300200241c0056a41286a220820032903003703002016200a290300370300200241c0056a41186a2221200b290300370300200241c0056a41106a2222201e290300370300200241c0056a41086a221e201f290300370300200220072903003703c005200741d0006a21072006450d0320024180036a41386a2201202029030037030020024180036a41306a2203201529030037030020024180036a41286a220a200829030037030020024180036a41206a2208201629030037030020024180036a41186a220b202129030037030020024180036a41106a221f202229030037030020024180036a41086a2220201e290300370300200220022903c00537038003201241386a2001290300370200201241306a2003290300370200201241286a200a290300370200201241206a2008290300370200201241186a200b290300370200201241106a201f290300370200201241086a20202903003702002012200229038003370200200241f8066a200241c0056a41c40010e4071a20024198026a41086a200241f8066a41086a29020037030020024198026a41106a200241f8066a41106a29020037030020024198026a41186a200241f8066a41186a29020037030020024198026a41206a200241f8066a41206a280200360200200241f8016a41086a2208201c41086a290200370300200241f8016a41106a2201201c41106a290200370300200241f8016a41186a2203201c41186a290200370300200220022902f806370398022002201c2902003703f801200241c0026a41186a220a201141186a290000370300200241c0026a41106a220b201141106a290000370300200241c0026a41086a221f201141086a290000370300200220112900003703c002200241e0026a41186a22202003290300370300200241e0026a41106a22232001290300370300200241e0026a41086a22242008290300370300200220022903f8013703e002200241e8066a200241c0026a10b505200241c0056a20022802e806220320022802f00610b60520022d00c0052101200241f8066a201b41a00110e4071a41002108024020014101470d00200241a0046a200241f8066a41a00110e4071a410121080b024020022802ec06450d00200310290b0240024002402008450d0020024180036a200241a0046a41a00110e4071a2021200a2903003703002022200b290300370300201e201f290300370300201620022903e002370300201641086a2024290300370300201641106a2023290300370300201641186a2020290300370300200220022903c0023703c005200220043703880620022009360284062002200636028006416c2103024002400240024002400340410021064180a6cc00210b0240024002400240200341e8a1c5006a280000220841e0ea91cb064a0d00200841f0c2c98b06460d01200841e2c289ab06470d03412021062017210b0c030b200841e1ea91cb06460d010240200841e9dabdf306460d00200841e7e485f306470d034120210620024180036a210b0c030b412021062018210b0c020b412021062019210b0c010b41202106201a210b0b2006410472220110272209450d0a20092008360000200241043602a804200220013602a404200220093602a0042006200241a0046a10710240024020022802a404220a20022802a80422096b2006490d0020022802a0042108200a21010c010b200920066a22082009490d03200a41017422012008200120084b1b22014100480d0302400240200a0d00024020010d00410121080c020b200110272208450d080c010b20022802a0042108200a2001460d002008200a2001102b2208450d070b200220013602a404200220083602a0040b200820096a200b200610e4071a2002201d3602a004200241f8066a20024180016a2008200920066a200241a0046a410410ab0602402001450d00200810290b20022802fc0621060240024020022802f8064101470d00024020062d0000220841034b0d00024020080e0403030003030b200641086a280200450d02200641046a28020010290c020b200641286a280200450d01200641246a28020010290c010b02402006450d00200228028007450d00200610290b200341046a2203450d020c010b0b20061029200041086a411a360200200041c4a8c800360204200041013602000c030b2002201d36029c08200241003602a804200242013703a004412010272206450d03200241203602a404200220063602a004200620022903c005370000200641086a201e290300370000200641106a2022290300370000200641186a2021290300370000200241203602a804200220163602e806200241e8066a200241a0046a10e501200220153602e806200241e8066a200241a0046a10e50120022802800621062002280288062208200241a0046a107102402008450d00200841306c210a03400240024020022802a404220320022802a80422086b4120490d00200841206a210920022802a00421010c010b200841206a22092008490d03200341017422012009200120094b1b220b4100480d030240024020030d000240200b0d00410121010c020b200b102722010d010c080b20022802a00421012003200b460d0020012003200b102b2201450d070b2002200b3602a404200220013602a0040b200120086a2208200641106a290000370000200841186a200641286a290000370000200841106a200641206a290000370000200841086a200641186a290000370000200220093602a804200220063602e806200241e8066a200241a0046a10e501200641306a2106200a41506a220a0d000b0b20022802a4042106200241f8066a20024180016a2002419c086a410420022802a004220820022802a80410ab0602402006450d00200810290b024020022802f8064101470d00024020022802fc0622062d0000220841034b0d00024020080e0404040004040b200641086a280200450d03200641046a28020010290c030b200641286a280200450d02200641246a28020010290c020b024020022802fc062206450d00200228028007450d00200610290b02402002280284062206450d00200641306c450d0020022802800610290b2007200f460d050c060b1032000b20061029200041086a411a360200200041c4a8c800360204200041013602000b02402002280284062206450d00200641306c450d0020022802800610290b0240200f2007460d000340024020132802002206450d00200641306c450d002013417c6a28020010290b201341d0006a2113201441b07f6a22140d000b0b02402010450d00201041d0006c450d00200e10290b20024180016a10c506024020022802182209450d00200228021c220841046a2106200920086a41016a21072008280200417f734180818284787121012002280220210802400340024002402001450d00200121090c010b0340200620074f0d03200841c0016a210820062802002109200641046a220121062009418081828478712209418081828478460d000b2009418081828478732109200121060b2009417f6a2009712101200820096841037641306c6a220941246a280200450d00200928022010290c000b0b02402002280218220641086a200641056a490d00200641016aad42307e422088a71a0b200228021c10290b2002280234450d08200228023010290c080b1030000b02402009450d00200941306c450d00200610290b2007200f470d010b200f21070c030b201d41016a211d201441b07f6a2114201341d0006a21130c000b0b1039000b200241c0056a41386a200241a0046a41386a290300370300200241c0056a41306a200241a0046a41306a290300370300200241c0056a41286a200241a0046a41286a290300370300200241c0056a41206a200241a0046a41206a290300370300200241c0056a41186a200241a0046a41186a290300370300200241c0056a41106a200241a0046a41106a290300370300200241c0056a41086a200241a0046a41086a290300370300200220022903a0043703c0050b0240200f2007460d0003402007220641d0006a21070240200641c4006a2802002208450d00200841306c450d00200641c0006a28020010290b200f2007470d000b0b02402010450d00201041d0006c450d00200e10290b20024180016a10c506200241c0056a200241086a41d80010e4071a200241b0066a200241f8006a290300370300200241a8066a200241f0006a290300370300200241a0066a200241e0006a41086a2903003703002002200229036037039806200041086a200241c0056a41f80010e4071a200041003602000b200241a0086a24000bdb0303017f047e097f230041106b220224002002200041086a29030022032000290300220485220520044218898520054210868520054225897c220542a0cbbf9599b5a19f0a7c2206200129001885200129000020068542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852001290008200542efcdddd088a580a21e7c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852001290010200542bed0fb8bf894dfa4327c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85420042adfed5e4d485fda8d800420010d507200241086a29030020022903007c200320047c85a722074119762208410874200872220841107420087221092000280210220a2007712108200041186a280200210b200041146a280200210c4100210d024003400240200c20086a280000220e2009732200417f73200041fffdfb776a71418081828478712200450d00024003402001200b20006841037620086a200a71220f41306c6a2207460d0120012007412010e707450d012000417f6a2000712200450d020c000b0b200b200f41306c6a41206a21000c020b200d41046a220d20086a200a712108200e200e4101747141808182847871450d000b410021000b200241106a240020000bc81c021f7f037e230041e0036b22032400200228020821042002280200210520022802042106200341186a2207200141246a290000370300200341106a22082001411c6a290000370300200341086a2209200141146a2900003703002003200129000c3703002006410174210a2003410772210b200341c8016a41186a210c200341c8016a410c6a210d200341c8016a41206a210e2001280204210f200128020021102006211120052112200421134100211441002115024002400240024002400240024002400240024002400240024002400340200420156a2216410176210402400240024002400240024002400240024002402016410171450d0020112004490d02200420114f0d04200341013a00d001200320123602c801200320043602cc012003201220046a2d000041f001713a00d1010c010b20112004490d02200341003a00d001200320043602cc01200320123602c8010b200341b8036a20102003200341c8016a200f28020c110400024020032802b80322170d00200341c8016a41086a2213200341086a290300370300200341c8016a41106a2206200341106a290300370300200341c8016a41186a2211200341186a290300370300200320032903003703c801413010272204450d17200420032903c80137000120042003290020370021200420144100473a0000200441096a2013290300370000200441116a2006290300370000200441196a2011290300370000200441286a200341276a29000037000020004101360200200020043602040c160b20032802c003210420032802bc03211802402001280208221128020c20144b0d002004417f4c0d0e0240024020040d0041002112410121190c010b200410272219450d12200421120b0240024020122004490d00201221160c010b201241017422162004201620044b1b22164100480d13024020120d002016102722190d010c190b20122016460d00201920122016102b2219450d180b20192017200410e4072119200c2007290300370300200341c8016a41106a221a2008290300370300200341c8016a41086a221b2009290300370300200320032903003703c801024020112802082212201141046a280200470d0020112012410110ab01201128020821120b2011280200201241306c6a2212201936020420122014360200201220032903c8013702102012410c6a2004360200201241086a2016360200201241186a201b290300370200201241206a201a290300370200201241286a200c2903003702002011201128020841016a3602080b200341c8016a2017200410870420032d00c8014101460d13201441016a2114034020032802e401211c20032802e001211d20032802dc01211e20032802d801211220032802d401211120032802d001211620032802cc012104200341206a200e41a80110e4071a2003280294032119200328029003211a024002400240024020040e051710000102170b410021040240201141017420126b221f200a20136b22192019201f4b1b2220450d000340201320046a2219410176221a20064f0d09201220046a221b410176222120114f0d0a2005201a6a2d0000221a410f71201a41f0017141047620194101711b201620216a2d00002219410f712019410476201b4101711b470d01200441016a22042020490d000b0b02402004201f460d00200042003702002018450d1a0c190b201f21040c020b2003201c3602dc012003201d3602d8012003201e3602d401200320123602d001200320113602cc01200320163602c801200c200341206a41a80110e4071a02400240200a2013460d00201341017622042006490d012004200641b4a0cc001036000b02400240201a0d00410021040c010b2019417f4c0d120240024020190d0041002113410121040c010b201910272204450d16201921130b0240024020132019490d00201321060c010b201341017422062019200620194b1b22064100480d17024020130d00200610272204450d1d0c010b20132006460d00200420132006102b2204450d1c0b2004201a201910e4071a2019ad4220862006ad8421220b20002004360204200041086a20223702000c0e0b0240200341c8016a200520046a2d00002204410f71200441047620134101711b410c6c6a2204280200221e4102470d00200041003602040c0e0b2004280204211d200441086a280200211c4101211f410121040c010b20032802a0032120200328029c03211f20032802980321042003201c3602d0012003201d3602cc012003201e3602c801200d200341206a41a80110e4071a200320043602840320032019360280032003201a3602fc02410021040240201141017420126b221c200a20136b221e201e201c4b1b221d450d000340201320046a2219410176221a20064f0d09201220046a221b410176222120114f0d0a2005201a6a2d0000221a410f71201a41f0017141047620194101711b201620216a2d00002219410f712019410476201b4101711b470d01200441016a2204201d490d000b0b024002400240024002402004201c470d00201e201c470d01201f0d02410021040c030b200041003602040c0f0b201c20136a220441017622112006490d022011200641b4a0cc001036000b2020417f4c0d110240024020200d0041002113410121040c010b202010272204450d15202021130b0240024020132020490d00201321060c010b201341017422062020200620204b1b22064100480d16024020130d00200610272204450d1c0c010b20132006460d00200420132006102b2204450d1b0b2004201f202010e4071a2020ad4220862006ad8421220b20002004360204200041086a20223702000c0c0b0240200341c8016a200520116a2d00002211410f71201141047620044101711b410c6c6a2211280200221e4102470d00200041003602040c0c0b201c41016a211f201c41016a21042011280204211d201141086a280200211c0b200420156a21152013201f6a21130240201e450d00200341c8016a201d201c10870420032d00c8014101460d150c010b0b02400240201c4120460d00200341c8016a41086a22162009290300370300200341c8016a41106a22192008290300370300200c2007290300370300200320032903003703c801201c417f4c0d0f02400240201c0d0041002104410121120c010b201c10272212450d13201c21040b024002402004201c490d00200421110c010b20044101742211201c2011201c4b1b22114100480d14024020040d00201110272212450d1a0c010b20042011460d00201220042011102b2212450d190b2012201d201c10e4072112413010272204450d18200441043a0000200420032903c801370001200420032f00aa033b00212004201c36002c2004201136002820042012360024200441096a2016290300370000200441116a2019290300370000200441196a200c290300370000200441236a200341aa036a41026a2d00003a0000410121110c010b201d41026a2d00002111201d410f6a2900002122201d41176a2900002123201d2800032104201d2f00002112201d2900072124200c201d411f6a2d00003a0000200341c8016a41106a2023370300200341c8016a41086a2022370300200341aa036a41026a20113a0000200320243703c801200320123b01aa03410021110b200341dc036a41026a2212200341aa036a41026a2d00003a0000200341b8036a41086a2216200341c8016a41086a290300370300200341b8036a41106a2219200341c8016a41106a290300370300200341b8036a41186a221a200c280200360200200320032f01aa033b01dc03200320032903c8013703b803024020110d00200b20032903b803370000200b41086a2016290300370000200b41106a2019290300370000200b41186a201a2d00003a0000200320032f01dc033b010020032004360003200320122d00003a00022018450d08201710290c080b200041013602002000200436020420180d140c150b2004201141f4a0cc00104b000b200420114184a1cc00104b000b200420114194a1cc001036000b201a200641b4a0cc001036000b2021201141b4a0cc001036000b201a200641b4a0cc001036000b2021201141b4a0cc001036000b2002280208210420022802042111200228020021120c000b0b200041003602000c020b200041003602000c010b4100211c0240201141017420126b200a20136b2201470d004100211c41002104024002402001450d00410021040340201220046a2219410176221a20114f0d06201320046a221b410176222120064f0d072016201a6a2d0000221a410f71201a41f0017141047620194101711b200520216a2d00002219410f712019410476201b4101711b470d012001200441016a2204470d000c020b0b20042001470d010b201d417f4c0d0202400240201d0d00410021044101211c0c010b201d1027221c450d06201d21040b024002402004201d490d00200421130c010b20044101742213201d2013201d4b1b22134100480d07024020040d0020131027221c450d0d0c010b20042013460d00201c20042013102b221c450d0c0b201c201e201d10e4071a201dad4220862013ad8421220b2000201c36020420004100360200200041086a20223702000b02402018450d00201710290b200341e0036a24000f0b1038000b201a201141b4a0cc001036000b2021200641b4a0cc001036000b1039000b1032000b2000420037020020180d010c020b20032d00c9012113200341b8036a41086a2206200341086a290300370300200341b8036a41106a2211200341106a290300370300200341b8036a41186a2212200341186a290300370300200320032903003703b803413010272204450d02200441033a0000200420032903b803370001200420133a0021200420032901aa03370122200441096a2006290300370000200441116a2011290300370000200441196a2012290300370000200441286a200341b0036a29010037010020004101360200200020043602042018450d010b201710290b200341e0036a24000f0b1030000b8c0f05047f017e017f017e077f23004190016b22022400200241c8006a41186a22034200370300200241c8006a41106a22044200370300200241c8006a41086a220542003703002002420037034841c8bec500ad4280808080c0008422061001220729000021082005200741086a290000370300200220083703482007102941d983cc00ad4280808080b00184100122092900002108200241286a41086a2207200941086a2900003703002002200837032820091029200420022903282208370300200241f0006a41086a220a2005290300370300200241f0006a41106a220b2008370300200241f0006a41186a220c200729030037030020022002290348370370200241c8006a200241f0006a10bf0320022802482109200229024c21082003420037030020044200370300200542003703002002420037034820061001220329000021062005200341086a290000370300200220063703482003102941b8f1c200ad4280808080a001841001220329000021062007200341086a2900003703002002200637032820031029200420022903282206370300200a2005290300370300200b2006370300200c200729030037030020022002290348370370200241c8006a200241f0006a10c00320022d00482105200c200241e1006a290000370300200b200241d9006a290000370300200a200241d1006a290000370300200220022900493703700240024020054101460d00200241286a41186a4200370300200241286a41106a420037030020074200370300200242003703280c010b200241286a41186a200c290300370300200241286a41106a200b2903003703002007200a290300370300200220022903703703280b200241086a41086a200241286a41086a290300370300200241086a41106a200241286a41106a290300370300200241086a41186a200241286a41186a2903003703002002200229032837030820024100360250200242013703480240410810272205450d002002410836024c20022005360248200542f02e37000020024108360250200541084110102b2205450d00200542e0123700082002411036024c20022005360248200241103602500240024002404100450d00411021070c010b411041017422074118200741184b1b22074100480d010240024041100d002007102722050d010c040b41102007460d00200541102007102b2205450d030b2002200736024c200220053602480b2005420137001020024118360250024020074138714118470d00200741017422044120200441204b1b22044100480d010240024020070d00200410272205450d040c010b20072004460d00200520072004102b2205450d030b2002200436024c200220053602480b2009410820091b210d20054204370018200241203602502008420020091b2208422088a72205200241c8006a10712002280250210302402005450d00200d200541286c6a210e410020036b210b200228024c2104410021050340200320056a210c024002402004200b6a4120490d002002280248210a200421090c010b200c41206a2207200c490d03200441017422092007200920074b1b22094100480d030240024020040d00024020090d004101210a0c020b20091027220a450d060c010b2002280248210a20042009460d00200a20042009102b220a450d050b2002200936024c2002200a3602480b200a20036a20056a2204200d20056a2207290000370000200441186a200741186a290000370000200441106a200741106a290000370000200441086a200741086a2900003700002002200c41206a2204360250200741206a2903002106024002402009200b6a41606a41074d0d00200921040c010b200441086a220f2004490d0320094101742204200f2004200f4b1b22044100480d030240024020090d00024020040d004101210a0c020b20041027220a450d060c010b20092004460d00200a20092004102b220a450d050b2002200436024c2002200a3602480b200a20036a20056a41206a20063700002002200c41286a360250200b41586a210b200541286a2105200e200741286a470d000b200320056a21030b02400240200228024c220420036b4120490d0020022802482107200421050c010b200341206a22052003490d01200441017422072005200720054b1b22054100480d010240024020040d00024020050d00410121070c020b200510272207450d040c010b2002280248210720042005460d00200720042005102b2207450d030b2002200536024c200220073602480b200720036a22042002290308370000200441186a200241086a41186a290300370000200441106a200241086a41106a290300370000200441086a200241086a41086a2903003700002002200341206a22043602500240024020052004460d00200421050c010b200541016a22042005490d01200541017422092004200920044b1b22044100480d010240024020050d0041002105024020040d00410121070c020b200410272207450d040c010b20052004460d00200720052004102b2207450d030b2002200436024c200220073602480b200720056a41023a0000200541016aad422086200235024884210602402008a72205450d00200541286c450d00200d10290b20024190016a240020060f0b1032000b1030000b980704057f017e087f037e230041a0016b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b020240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c8010240024020022802000d00200228020422052002280224220641286e2201200120054b1bad42287e2207422088a70d032007a72201417f4c0d030240024020010d00410821080c010b200110272208450d050b4100210920024100360230200220083602282002200141286e36022c02400240024002402005450d004100210a034041002101200241003a009801200a41016a210a034020062001460d03200241f8006a20016a2002280220220b2d00003a00002002200b41016a3602202002200141016a220c3a009801200c2101200c4120470d000b200241d8006a41186a2201200241f8006a41186a290300370300200241d8006a41106a220d200241f8006a41106a290300370300200241d8006a41086a220e200241f8006a41086a290300370300200220022903783703582006200c6b220c4108490d03200241386a41086a220f200e290300370300200241386a41106a220e200d290300370300200241386a41186a220d2001290300370300200220022903583703382002200b41096a360220200b290001210702402009200228022c470d00200241286a2009410110a30120022802282108200228023021090b200c41786a21062008200941286c6a22012002290338370300200f2903002110200e2903002111200d290300211220012007370320200141186a2012370300200141106a2011370300200141086a20103703002002200941016a2209360230200a2005470d000b2002200c41786a3602240b2008450d032000200229022c370204200020083602000c040b20024100360224200141ff0171450d01200241003a0098010c010b2002200c3602240b200228022c2201450d00200141286c450d00200810290b20024100360260200242013703582002410d36023c2002200241086a3602382002200241d8006a3602282002418c016a41013602002002420137027c200241f4eaca003602782002200241386a36028801200241286a41a8a3c800200241f8006a10371a200235026042208620023502588410080240200228025c450d00200228025810290b200041003602000b2004450d00200310290b200241a0016a24000f0b1038000b1039000bd60302057f047e230041f0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b0202400240200228021022030d00200041003a00000c010b200241186a28020021042002280214210541002101200241003a006802400240034020042001460d01200241c8006a20016a200320016a2d00003a00002002200141016a22063a00682006210120064120470d000b200241206a41186a200241c8006a41186a2903002207370300200241206a41106a200241c8006a41106a2903002208370300200241206a41086a200241c8006a41086a290300220937030020022002290348220a370320200041196a2007370000200041116a2008370000200041096a20093700002000200a370001410121010c010b0240200141ff0171450d00200241003a00680b4100210120024100360228200242013703202002410d3602442002200241086a3602402002200241206a36026c200241dc006a41013602002002420137024c200241f4eaca003602482002200241c0006a360258200241ec006a41a8a3c800200241c8006a10371a200235022842208620023502208410082002280224450d00200228022010290b200020013a00002005450d00200310290b200241f0006a24000b2b02017e017f10b401210202404108102722030d001039000b200320023700002003ad42808080808001840b9b0b04047f017e0a7f017e230041b0016b2202240020024188016a41186a420037030020024188016a41106a2203420037030020024188016a41086a220442003703002002420037038801418ebfc500ad4280808080a002841001220529000021062004200541086a29000037030020022006370388012005102941dcb7c700ad4280808080c00084100122052900002106200241e8006a41086a2207200541086a2900003703002002200637036820051029200320022903682206370300200241106a41086a2004290300370300200241106a41106a2006370300200241106a41186a20072903003703002002200229038801370310200241203602342002200241106a360230200241386a200241106aad42808080808004841007108b020240024002400240200228023822080d00410021070c010b200228023c21092002200241386a41086a28020036024c20022008360248200241086a200241c8006a10c8010240024020022802080d00200228020c220a200228024c220b41057622042004200a4b1b22044105742205417f4c0d040240024020040d00410121070c010b200510272207450d040b4100210c200241003602602002200436025c2002200736025802400240200a450d004100210d0340200b210341002104200241003a00a801200d41016a210d034020032004460d0320024188016a20046a200228024822052d00003a00002002200541016a3602482002200441016a22053a00a8012005210420054120470d000b200241e8006a41186a220e20024188016a41186a290300370300200241e8006a41106a220f20024188016a41106a290300370300200241e8006a41086a221020024188016a41086a29030037030020022002290388013703680240200c200228025c470d00200241d8006a200c4101109e01200228025821072002280260210c0b200320056b210b2007200c4105746a22042002290368370000200441186a200e290300370000200441106a200f290300370000200441086a20102903003700002002200c41016a220c360260200d200a470d000b2002200320056b36024c0b200229025c21062007450d010c020b2002410036024c0240200441ff0171450d00200241003a00a8010b0240200228025c41ffffff3f71450d00200710290b0b4100210720024100360270200242013703682002410d36025c2002200241306a3602582002200241e8006a3602542002419c016a41013602002002420137028c01200241f4eaca00360288012002200241d8006a36029801200241d4006a41a8a3c80020024188016a10371a20023502704220862002350268841008200228026c450d00200228026810290b2009450d00200810290b2006420020071b2206422088a7220441057422094104722205417f4c0d01200510272203450d002007410120071b210a20024100360290012002200536028c012002200336028801200420024188016a10710240024020040d002002280290012105200228028801210d0c010b410020022802900122056b2107200228028801210d200228028c012108200a210c0340200c21040240200820076a411f4b0d00024002400240200541206a22032005490d002008410174220c2003200c20034b1b22034100480d000240024020080d00024020030d004101210d0c020b20031027210d0c040b20082003470d020b200321080c030b1032000b200d20082003102b210d0b20032108200d0d001030000b200441206a210c200d20056a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a290000370000200741606a2107200541206a2105200941606a22090d000b2002200836028c0120022005360290012002200d360288010b2005ad422086200dad8421110240200642ffffff3f83500d00200a10290b200241b0016a240020110f0b1039000b1038000bb91204037f017e027f017e230041e0026b220224000240024020010d002002200136020c20024180a6cc003602080c010b20022001417f6a36020c2002200041016a36020820002d0000220141014b0d004100210002400240024002400240024020010e020100010b2002200241086a10c80120022802000d05200228020c220320022802042201490d052001417f4c0d010240024020010d0041002103410121000c010b2001102d2200450d03200020022802082204200110e4071a2002200320016b36020c2002200420016a360208200121030b2000450d052001ad4220862003ad8421050b410021030240024020000d00410021040c010b2005422088a72201417f4c0d010240024020010d0041002106410121040c010b200110272204450d03200121060b0240024020062001490d00200621070c010b200641017422072001200720014b1b22074100480d04024020060d002007102722040d010c060b20062007460d00200420062007102b2204450d050b20042000200110e4071a2005428080808070832007ad8421080b2002200837021420022004360210200241b0016a41e7e485f306200241106a10c4030240024020000d000c010b2005422088a72201417f4c0d010240024020010d0041002104410121030c010b200110272203450d03200121040b0240024020042001490d00200421060c010b200441017422062001200620014b1b22064100480d04024020040d00200610272203450d060c010b20042006460d00200320042006102b2203450d050b20032000200110e4071a2005428080808070832006ad8421080b2002200837021420022003360210200241d0016a41e2c289ab06200241106a10c503410021030240024020000d00410021040c010b2005422088a72201417f4c0d010240024020010d0041002106410121040c010b200110272204450d03200121060b0240024020062001490d00200621070c010b200641017422072001200720014b1b22074100480d04024020060d00200710272204450d060c010b20062007460d00200420062007102b2204450d050b20042000200110e4071a2005428080808070832007ad8421080b2002200837021420022004360210200241f0016a41e9dabdf306200241106a10c5030240024020000d000c010b2005422088a72201417f4c0d010240024020010d0041002104410121030c010b200110272203450d03200121040b0240024020042001490d00200421060c010b200441017422062001200620014b1b22064100480d04024020040d00200610272203450d060c010b20042006460d00200320042006102b2203450d050b20032000200110e4071a2005428080808070832006ad8421080b200220083702142002200336021020024190026a41f0c2c98b06200241106a10c5030240024020000d00410021030c010b2005422088a72201417f4c0d010240024020010d0041002104410121030c010b200110272203450d03200121040b0240024020042001490d00200421060c010b200441017422062001200620014b1b22064100480d04024020040d00200610272203450d060c010b20042006460d00200320042006102b2203450d050b20032000200110e4071a2005428080808070832006ad8421080b200220083702d402200220033602d002200241b0026a41e1ea91cb06200241d0026a10c503200241106a41086a2203200241b0016a41086a290300370300200241106a41106a2204200241b0016a41106a290300370300200241106a41186a2206200241b0016a41186a290300370300200241386a200241d0016a41086a290300370300200241c0006a200241d0016a41106a290300370300200241c8006a200241d0016a41186a290300370300200241d8006a200241f0016a41086a290300370300200241e0006a200241f0016a41106a290300370300200241e8006a200241f0016a41186a290300370300200220022903b001370310200220022903d001370330200220022903f00137035020024188016a20024190026a41186a29030037030020024180016a20024190026a41106a290300370300200241f8006a20024190026a41086a29030037030020024198016a200241b0026a41086a290300370300200241a0016a200241b0026a41106a290300370300200241a8016a200241b0026a41186a2903003703002002200229039002370370200220022903b00237039001412010272201450d0320012002290310370000200141186a2006290300370000200141106a2004290300370000200141086a20032903003700002001412041c000102b2201450d032001200241106a41206a2203290000370020200141386a200341186a290000370000200141306a200341106a290000370000200141286a200341086a290000370000200141c000418001102b2201450d032001200241106a41c0006a22032900003700402001200241f0006a2204290000370060200141d8006a200341186a290000370000200141d0006a200341106a290000370000200141c8006a200341086a290000370000200141e8006a200441086a290000370000200141f0006a200441106a290000370000200141f8006a200441186a2900003700002001418001418002102b2201450d03200120024190016a22032900003700800120014198016a200341186a29000037000020014190016a200341106a29000037000020014188016a200341086a29000037000002402000450d002005a7450d00200010290b41a40110272200450d01200242a4013702142002200036021041a001200241106a10710240024020022802142206200228021822036b41a001490d00200341a0016a2104200228021021000c010b200341a0016a22042003490d03200641017422002004200020044b1b22074100480d030240024020060d00024020070d00410121000c020b200710272200450d060c010b2002280210210020062007460d00200020062007102b2200450d050b20022007360214200220003602100b200020036a200141a00110e4071a20011029200241e0026a24002004ad4220862000ad840f0b1038000b1039000b1032000b1030000b200241bc026a4104360200200241246a410236020020024202370214200241a0d1c200360210200241043602b4022002419cd4c2003602b002200241003602940220024180a6cc00360290022002200241b0026a360220200220024190026a3602b802200241106a41b0d1c2001040000bfa0103037f037e037f230041306b220324002003200136020c200341106a200210e602200328021421042003410c6a200335021842208620032802102205ad84101c22012900002106200141086a2900002107200141106a2900002108200341106a41186a2209200141186a290000370300200341106a41106a220a2008370300200341106a41086a220b20073703002003200637031020011029200041186a2009290300370000200041106a200a290300370000200041086a200b2903003700002000200329031037000002402004450d00200510290b024020022802002200450d00200241046a280200450d00200010290b200341306a24000bfa0103037f037e037f230041306b220324002003200136020c200341106a200210e602200328021421042003410c6a200335021842208620032802102205ad84101f22012900002106200141086a2900002107200141106a2900002108200341106a41186a2209200141186a290000370300200341106a41106a220a2008370300200341106a41086a220b20073703002003200637031020011029200041186a2009290300370000200041106a200a290300370000200041086a200b2903003700002000200329031037000002402004450d00200510290b024020022802002200450d00200241046a280200450d00200010290b200341306a24000bc80d03037f017e077f23004180036b22022400024002402001450d00200220003602080c010b20024180a6cc003602080b2002200136020c2002200241086a10c801024002400240024020022802000d00200228020c220320022802042201490d0002402001417f4c0d000240024020010d0041002103410121000c010b2001102d2200450d03200020022802082204200110e4071a2002200320016b36020c2002200420016a360208200121030b2000450d0120022001ad4220862003ad8422054220883e02dc02200220003602d802200241b0016a200241d8026a10c7030240024020022d00b0014101470d00410021060c010b200241106a200241b0016a41017241a00110e4071a200241b0016a200241106a41a00110e4071a200241003602e802200242043703e002412010272201450d03200120022903b001370000200141186a200241b0016a41186a290300370000200141106a200241b0016a41106a290300370000200141086a200241b0016a41086a290300370000200241e0026a41004101109c0120022802e402210720022802e002220620022802e80222044104746a220341e7e485f30636020c200342a08080808004370204200320013602002002200441016a22013602e802200241f0026a200241b0016a41206a10c803024020012007470d00200241e0026a20074101109c0120022802e402210720022802e002210620022802e80221010b200620014104746a220320022903f002370200200341e2c289ab0636020c200341086a200241f0026a41086a2802003602002002200141016a22013602e802200241f0026a200241f0016a10c803024020012007470d00200241e0026a20074101109c0120022802e402210720022802e002210620022802e80221010b200620014104746a220320022903f002370200200241f0026a41086a22042802002108200341e9dabdf30636020c200341086a20083602002002200141016a22013602e802200241f0026a20024190026a10c803024020012007470d00200241e0026a20074101109c0120022802e402210720022802e002210620022802e80221010b200620014104746a220320022903f00237020020042802002104200341f0c2c98b0636020c200341086a20043602002002200141016a22013602e802200241f0026a200241b0026a10c803024020012007470d00200241e0026a20074101109c0120022802e402210720022802e002210620022802e80221010b200620014104746a220320022903f002370200200241f0026a41086a2802002104200341e1ea91cb0636020c200341086a2004360200200141016a21090b02402005a7450d00200010290b0240024020060d00410121010c010b20094104744105722201417f4c0d010b200110272200450d02200241003602b801200220013602b401200220003602b0010240024020060d00200041003a000041012100200241013602b8010c010b200041013a0000200241013602b8012009200241b0016a1071024020090d0020022802b80121000c010b200620094104746a210a2006210103402001280200210b200141086a2802002200200241b0016a10710240024020022802b401220c20022802b80122086b2000490d0020022802b0012103200c21040c010b200820006a22032008490d06200c41017422042003200420034b1b22044100480d0602400240200c0d00024020040d00410121030c020b2004102722030d010c090b20022802b0012103200c2004460d002003200c2004102b2203450d080b200220043602b401200220033602b0010b200320086a200b200010e4071a2002200820006a22003602b8010240200420006b41034b0d00200041046a22082000490d062004410174220c2008200c20084b1b22084100480d060240024020040d00024020080d00410121030c020b200810272203450d090c010b20042008460d00200320042008102b2203450d080b200220083602b401200220033602b0010b200320006a2001410c6a2800003600002002200041046a22003602b801200141106a2201200a470d000b0b2000ad42208620023502b00184210502402006450d0002402009450d00200941047421002006210103400240200141046a280200450d00200128020010290b200141106a2101200041706a22000d000b0b200741ffffffff0071450d00200610290b20024180036a240020050f0b1038000b2002411c6a4104360200200241c4016a4102360200200242023702b401200241a0d1c2003602b00120024104360214200241bcd4c200360210200241003602f40220024180a6cc003602f0022002200241106a3602c0012002200241f0026a360218200241b0016a41b0d1c2001040000b1039000b1032000b1030000bc40b01087f23004190036b2202240041002103200241003a002820012802042204417f6a2105417f2106024002400240024002400240034020042003460d01200241086a20036a200128020022072d00003a00002001200420066a3602042001200741016a22083602002002200341016a22093a00282005417f6a21052006417f6a21062009210320094120470d000b200241a8016a41086a200241086a41086a290300370300200241a8016a41106a200241086a41106a290300370300200241a8016a41186a200241086a41186a290300370300200220022903083703a80141002106200241003a0028200420096b210303402003450d02200241086a20066a20082d00003a000020012003417f6a22033602042001200841016a22083602002002200641016a22093a00282009210620094120470d000b200241c8016a41086a200241086a41086a290300370300200241c8016a41106a200241086a41106a290300370300200241c8016a41186a200241086a41186a290300370300200220022903083703c80141002106200241003a0028200520096b2103200720096a210503402003417f460d03200241086a20066a200820066a2d00003a0000200120033602042001200520066a41026a3602002002200641016a22093a00282003417f6a21032009210620094120470d000b200241e8016a41086a200241086a41086a290300370300200241e8016a41106a200241086a41106a290300370300200241e8016a41186a200241086a41186a290300370300200220022903083703e80141002104200241003a0028200820096a2106200520096a210803402003417f460d04200241086a20046a20062d00003a0000200120033602042001200820046a41026a3602002002200441016a22093a00282003417f6a2103200641016a21062009210420094120470d000b20024188026a41086a200241086a41086a29030037030020024188026a41106a200241086a41106a29030037030020024188026a41186a200241086a41186a290300370300200220022903083703880241002109200241003a00880303402003417f460d05200241e8026a20096a20062d00003a0000200120033602042001200641016a22063602002002200941016a22083a0088032003417f6a21032008210920084120470d000b200241a8026a41086a2201200241e8026a41086a290300370300200241a8026a41106a2203200241e8026a41106a290300370300200241a8026a41186a2206200241e8026a41186a290300370300200241086a41086a200241a8016a41086a290300370300200241086a41106a200241a8016a41106a290300370300200241086a41186a200241a8016a41186a290300370300200220022903e8023703a802200220022903a801370308200241c0006a200241c8016a41186a290300370300200241386a200241c8016a41106a290300370300200241306a200241c8016a41086a290300370300200220022903c801370328200241e0006a200241e8016a41186a290300370300200241d8006a200241e8016a41106a290300370300200241d0006a200241e8016a41086a290300370300200220022903e80137034820024180016a20024188026a41186a290300370300200241f8006a20024188026a41106a290300370300200241f0006a20024188026a41086a2903003703002002200229038802370368200241a0016a200629030037030020024198016a200329030037030020024190016a2001290300370300200220022903a80237038801200041016a200241086a41a00110e4071a200041003a00000c050b0240200341ff0171450d00200241003a00280b200041013a00000c040b0240200641ff0171450d00200241003a00280b200041013a00000c030b0240200641ff0171450d00200241003a00280b200041013a00000c020b0240200441ff0171450d00200241003a00280b200041013a00000c010b0240200941ff0171450d00200241003a0088030b200041013a00000b20024190036a24000b5f01017f02404120102722020d001039000b200042a080808080043702042000200236020020022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a2900003700000bb70302037f047e23004180016b2202240041002103200241003a004020004180a6cc0020011b210402400240034020012003460d01200241206a20036a200420036a2d00003a00002002200341016a22003a00402000210320004120470d000b200241186a200241206a41186a22032903002205370300200241106a200241206a41106a22002903002206370300200241086a200241206a41086a2201290300220737030020022002290320220837030020032005370300200020063703002001200737030020022008370320200241f0006a200241206a10ca03200241206a20022802702203200228027810a90220022903202105200241e8006a280200210002402002280274450d00200310290b4104102722030d011039000b0240200341ff0171450d00200241003a00400b200241346a41023602002002410c6a410436020020024202370224200241a0d1c20036022020024104360204200241d8d4c2003602002002410036027420024180a6cc00360270200220023602302002200241f0006a360208200241206a41b0d1c2001040000b20032000410020054201511b36000020024180016a24002003ad4280808080c000840bc20503027f017e047f230041d0006b2202240041b3e6ca00ad4280808080e00084100122032900002104200241086a200341086a290000370300200220043703002003102941b9e6ca00ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100522012900002104200241306a41086a200141086a2900003703002002200437033020011029200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a1075200310292002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a20002001360208200020083602042000200336020002402002280224450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000ba50503027f037e027f230041b0076b22022400024002402001450d00200220003602100c010b20024180a6cc003602100b20022001360214200241e0036a200241106a10870302400240024020022903c8044203510d00200241186a200241e0036a41c00310e4071a200228021422014104490d0120022802102200280000210320022001417c6a3602142002200041046a360210200241e0036a200241186a41c00310e4071a200241a0076a200241f8046a220110c3012002200320022903a007220420022d00a9074200420010c70241082100200241086a29030021052002290300210620022d00a8072103200110cc01410810272201450d022001200437000002400240200341024d0d00410821030c010b024002400240024020030e03000102000b410021030c020b410121030c010b410221030b200220033a00e00341102100200141084110102b2201450d03200120033a0008410921030b200341107221070240200020036b410f4b0d002000200041017422082007200820074b1b2208460d00200120002008102b2201450d030b200120036a2200200537000820002006370000200241b0076a24002007ad4220862001ad840f0b200241ac076a41043602002002412c6a41023602002002420237021c200241a0d1c200360218200241043602a407200241f0d4c2003602a007200241003602dc0320024180a6cc003602d8032002200241a0076a3602282002200241d8036a3602a807200241186a41b0d1c2001040000b200241ac076a4104360200200241f4036a4102360200200242023702e403200241a0d1c2003602e003200241043602a407200241f0d4c2003602a007200241003602dc0320024180a6cc003602d8032002200241a0076a3602f0032002200241d8036a3602a807200241e0036a41b0d1c2001040000b1030000bdd0201057f230041d0006b22022400024002400240410410272203450d00200341f0c2c98b063600002001280200210441082101200341044108102b2205450d0120052004360004200241003a004820052106410021030340200241003a0008200241086a20062001410047220410e4071a024020010d00200241003a00080b20012004490d03200241286a20036a20022d00083a00002002200341016a22033a0048200120046b2101200620046a210620034120470d000b200241086a41186a2201200241286a41186a290300370300200241086a41106a2203200241286a41106a290300370300200241086a41086a2204200241286a41086a2903003703002002200229032837030820051029200041186a2001290300370000200041106a2003290300370000200041086a200429030037000020002002290308370000200241d0006a24000f0b1039000b1030000b2004200141a896cc00104c000bfc0403027f017e057f230041d0006b2202240041c8bec500ad4280808080c00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941e0f3c200ad4280808080900284100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bd60402067f047e230041f0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b0202400240200228021022030d00200041023a00000c010b2002280214210402400240200241186a2802002205450d0020032d0000220641014b0d004100210102400240024020060e020100010b41002101200241003a0068200341016a21072005417f6a2106034020062001460d02200241c8006a20016a200720016a2d00003a00002002200141016a22053a00682005210120054120470d000b200241206a41186a200241c8006a41186a290300370300200241206a41106a200241c8006a41106a290300370300200241206a41086a200241c8006a41086a29030037030020022002290348370320410121010b200241c8006a41186a200241206a41186a2903002208370300200241c8006a41106a200241206a41106a2903002209370300200241c8006a41086a200241206a41086a290300220a37030020022002290320220b370348200041196a2008370000200041116a2009370000200041096a200a3700002000200b3700010c020b200141ff0171450d00200241003a00680b20024100360228200242013703202002410d3602442002200241086a3602402002200241206a36026c200241dc006a41013602002002420137024c200241f4eaca003602482002200241c0006a360258200241ec006a41a8a3c800200241c8006a10371a2002350228422086200235022084100802402002280224450d00200228022010290b410221010b200020013a00002004450d00200310290b200241f0006a24000bb10201037f230041e0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b0202400240200228021022010d00200041003602000c010b200228021421032002200241186a28020036022420022001360220200241c8006a200241206a10ba0402400240200228024822040d0020024100360230200242013703282002410d36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241f4eaca003602482002200241386a360258200241c4006a41a8a3c800200241c8006a10371a200235023042208620023502288410080240200228022c450d00200228022810290b200041003602000c010b2000200229024c370204200020043602000b2003450d00200110290b200241e0006a24000bde0b02087f017e230041e0006b220124002001410036024020014201370338024002402000280200220241024b0d0002400240024002400240024020020e03000102000b410110272202450d062001410136023c20012002360238200241013a000020014101360240200028020421022000410c6a2802002203200141386a10710240024020030d00200128024021040c010b2002200341286c6a210520012802402104034002400240200128023c220620046b4120490d00200441206a210320012802382107200621080c010b200441206a22032004490d05200641017422072003200720034b1b22084100480d050240024020060d00024020080d00410121070c020b2008102722070d010c0b0b2001280238210720062008460d00200720062008102b2207450d0a0b2001200836023c200120073602380b200720046a22042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020012003360240200241206a29030021090240200820036b41074b0d00200341086a22042003490d05200841017422062004200620044b1b22044100480d050240024020080d00024020040d00410121070c020b200410272207450d0b0c010b20082004460d00200720082004102b2207450d0a0b2001200436023c200120073602380b200720036a20093700002001200341086a22043602402005200241286a2202470d000b0b02400240200128023c220320046b4120490d00200128023821020c010b200441206a22022004490d03200341017422072002200720024b1b22074100480d030240024020030d00024020070d00410121020c020b200710272202450d090c010b2001280238210220032007460d00200220032007102b2202450d080b2001200736023c200120023602380b200220046a2202200041106a2203290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a2900003700002001200441206a3602400c050b410110272202450d052001410136023c20012002360238200241023a0000200141013602402000280204210702400240200128023c2203417f6a4104490d00200128023821020c010b200341017422024105200241054b1b22044100480d0220012802382102024020032004460d00200220032004102b2202450d070b2001200436023c200120023602380b20022007360001200141053602400c040b410110272202450d042001410136023c20012002360238200241033a000020014101360240200128023821020240200128023c4101470d00200241014102102b2202450d052001410236023c200120023602380b200241013a0001200141023602402000290308210902400240200128023c2203417e6a4108490d00200128023821020c010b20034101742202410a2002410a4b1b22074100480d0120012802382102024020032007460d00200220032007102b2202450d060b2001200736023c200120023602380b200220093700022001410a36024020002903102109200128023c220341766a41074b0d01200341017422024112200241124b1b22074100480d0020012802382102024020032007460d00200220032007102b2202450d050b2002200937000a2001200736023c2001200236023820014112360240200041186a2d000021070c020b1032000b20012802382202200937000a20014112360240200041186a2d0000210720034112470d00200241124124102b2202450d022001412436023c200120023602380b200220073a0012200141133602400b200141246a200141386a41086a2802003600002001200129033837001c200141c4006a200141206a290000370000200141cc006a2001290208370200200141d4006a200141086a41086a290200370200200141c28289aa04360039200141023a00382001200129001937003d200141386a10d303024020002802000d00200041086a2802002202450d00200241286c450d00200028020410290b200141e0006a24000f0b1030000bd46c05017f1a7e037f0a7e057f230041901f6b22022400200131001221032001310011210420013100102105200131000f2106200131000d2107200131000e2108200131001f2109200131001e210a200131001d210b200131001c210c200131001b210d200131001a210e200131000c210f200131000b2110200131000a211120013100092112200131000721132001310008211420013100192115200131001821162001310017211720013100162118200131001321192001310014211a2001310015211b200220013100014208862001310000842001310002421086842001310003421886842001310004422086842001310005422886842001310006221c4230868442ffffffffffffff03833703901c20022019201a42088684201b4210868420184218868420174220868420164228868420154230868442018842ffffffffffffff03833703a81c2002201c201342088684201442108684201242188684201142208684201042288684200f4230868442038842ffffffffffffff03833703981c20022016201542088684200e42108684200d42188684200c42208684200b42288684200a42308684200942388684420c8842ffffffffffffff03833703b01c2002200f20074208868420084210868420064218868420054220868420044228868420034230868420194238868442068842ffffffffffffff03833703a01c200241b81c6a200241901c6a106a4100211d4101211e03402001201d6a2d0000200241b81c6a201d6a2d000073221f4100201f6b72417f7341800171410776106d201e71211e201d41016a221d4120470d000b201e106d211d200241c81e6a200241901c6a106a20022d00c81e410171106d211e4200210e0240201d41ff0171450d004200210e201e41ff01714101460d00200241d81c6a200241901c6a4101106b200242f0ffffffffffff3f20022903f81c220f7d221542ffffffffffffff038342f0ffffffffffff3f20022903f01c22167d22194233887c3703a01d2002201942ffffffffffffff038342f0ffffffffffff3f20022903e81c22197d22034233887c3703981d2002200342ffffffffffffff038342f0ffffffffffff3f20022903e01c22037d22044233887c3703901d2002200442ffffffffffffff038342d1fdffffffffff3f20022903d81c22047d22054233887c3703881d2002201542338842137e200542ffffffffffffff03837c3703801d2002200f3703c81d200220163703c01d200220193703b81d200220033703b01d2002200442017c3703a81d200241d01d6a200241a81d6a4101106b20024180196a200241801d6a4101106b4200210e200241e0186a200229038819220f420042ca8e9ae5dec6ac02420010d50720024190186a200229039019221642137e22054200428092f58893f9b701420010d507200241c0176a200229039819220342137e2204420042c486ffe299c731420010d507200241f0166a20022903a019220642137e2219420042d6fff8ffd98b8601420010d50720024180166a2002290380192215420042c2a2aaa7fcfa9503420010d507200241f0156a2015420042ca8e9ae5dec6ac02420010d507200241f0186a200f42137e4200428092f58893f9b701420010d507200241a0186a2005420042c486ffe299c731420010d507200241d0176a2004420042d6fff8ffd98b8601420010d50720024180176a2019420042c2a2aaa7fcfa9503420010d50720024180186a2016420042ca8e9ae5dec6ac02420010d507200241b0176a20044200428092f58893f9b701420010d507200241e0166a2019420042c486ffe299c731420010d50720024190166a2015420042d6fff8ffd98b8601420010d507200241d0186a200f420042c2a2aaa7fcfa9503420010d507200241a0176a2003420042ca8e9ae5dec6ac02420010d507200241d0166a20194200428092f58893f9b701420010d507200241a0166a2015420042c486ffe299c731420010d507200241c0186a200f420042d6fff8ffd98b8601420010d507200241f0176a2016420042c2a2aaa7fcfa9503420010d507200241c0166a2006420042ca8e9ae5dec6ac02420010d507200241b0166a20154200428092f58893f9b701420010d507200241b0186a200f420042c486ffe299c731420010d507200241e0176a2016420042d6fff8ffd98b8601420010d50720024190176a2003420042c2a2aaa7fcfa9503420010d507200241d0156a20022903b016221720022903c0167c220f20022903b0187c221520022903e0177c22162002290390177c221920022903d016221820022903a0177c220320022903a0167c220420022903c0187c220520022903f0177c220620022903b017221a2002290380187c220720022903e0167c22082002290390167c220920022903d0187c220a200229039018221b20022903e0187c220b20022903c0177c220c20022903f0167c220d2002290380167c221020022903f018221c20022903f0157c221120022903a0187c221220022903d0177c22132002290380177c2214423388200241f0186a41086a290300200241f0156a41086a2903007c2011201c54ad7c200241a0186a41086a2903007c2012201154ad7c200241d0176a41086a2903007c2013201254ad7c20024180176a41086a2903007c2014201354ad7c420d86847c221142338820024190186a41086a290300200241e0186a41086a2903007c200b201b54ad7c200241c0176a41086a2903007c200c200b54ad7c200241f0166a41086a2903007c200d200c54ad7c20024180166a41086a2903007c2010200d54ad7c2011201054ad7c420d86847c220b423388200241b0176a41086a29030020024180186a41086a2903007c2007201a54ad7c200241e0166a41086a2903007c2008200754ad7c20024190166a41086a2903007c2009200854ad7c200241d0186a41086a2903007c200a200954ad7c200b200a54ad7c420d86847c2207423388200241d0166a41086a290300200241a0176a41086a2903007c2003201854ad7c200241a0166a41086a2903007c2004200354ad7c200241c0186a41086a2903007c2005200454ad7c200241f0176a41086a2903007c2006200554ad7c2007200654ad7c420d86847c220542ffffffffffffff038320022903f01d22067d42f0ffffffffffff3f7c220842ffffffffffffff0383200742ffffffffffffff038320022903e81d22047d42f0ffffffffffff3f7c22074233887c220c420020022903e01d220342137e2209420010d507200241e0136a200842338842137e2005423388200241b0166a41086a290300200241c0166a41086a2903007c200f201754ad7c200241b0186a41086a2903007c2015200f54ad7c200241e0176a41086a2903007c2016201554ad7c20024190176a41086a2903007c2019201654ad7c2005201954ad7c420d868442137e201442feffffffffffff03837c221542ffffffffffffff038320022903d01d22167d42d0fdffffffffff3f7c220d42ffffffffffffff03837c220f420020022903d81d2219420010d50720024180156a200742ffffffffffffff0383200b42ffffffffffffff038320037d42f0ffffffffffff3f7c22054233887c220a4200200442137e2207420010d507200241b0146a200542ffffffffffffff03832015423388201142ffffffffffffff03837c20197d42f0ffffffffffff3f7c22154233887c22084200200642137e2205420010d50720024190136a201542ffffffffffffff0383200d4233887c221542002016420010d507200241e0156a200c4200201942137e420010d507200241f0136a20164200200f420010d50720024190156a200a42002009420010d507200241c0146a200842002007420010d507200241a0136a201542002005420010d507200241c0156a200c42002007420010d507200241d0136a200f42002003420010d507200241f0146a200a42002005420010d507200241a0146a200842002016420010d50720024180136a201542002019420010d507200241b0156a200c42002005420010d507200241c0136a200f42002004420010d507200241e0146a200a42002016420010d50720024190146a200842002019420010d507200241f0126a201542002003420010d507200241a0156a200c42002016420010d507200241b0136a200f42002006420010d507200241d0146a200a42002019420010d50720024180146a200842002003420010d507200241e0126a201542002004420010d507200220022903c015221220022903d0137c221620022903f0147c221920022903a0147c22032002290380137c220420022903d015221320022903e0137c22052002290380157c220620022903b0147c22072002290390137c220920022903e015221420022903f0137c220b2002290390157c220d20022903c0147c221020022903a0137c2211423388200241e0156a41086a290300200241f0136a41086a2903007c200b201454ad7c20024190156a41086a2903007c200d200b54ad7c200241c0146a41086a2903007c2010200d54ad7c200241a0136a41086a2903007c2011201054ad7c420d86847c220b423388200241d0156a41086a290300200241e0136a41086a2903007c2005201354ad7c20024180156a41086a2903007c2006200554ad7c200241b0146a41086a2903007c2007200654ad7c20024190136a41086a2903007c2009200754ad7c200b200954ad7c420d86847c220542ffffffffffffff03833703b01e200220022903b015221020022903c0137c220620022903e0147c22072002290390147c220920022903f0127c220d2005423388200241c0156a41086a290300200241d0136a41086a2903007c2016201254ad7c200241f0146a41086a2903007c2019201654ad7c200241a0146a41086a2903007c2003201954ad7c20024180136a41086a2903007c2004200354ad7c2005200454ad7c420d86847c221642ffffffffffffff03833703b81e200220022903a015221220022903b0137c221920022903d0147c22032002290380147c220420022903e0127c22052016423388200241b0156a41086a290300200241c0136a41086a2903007c2006201054ad7c200241e0146a41086a2903007c2007200654ad7c20024190146a41086a2903007c2009200754ad7c200241f0126a41086a2903007c200d200954ad7c2016200d54ad7c420d86847c221642ffffffffffffff03833703c01e20022016423388200241a0156a41086a290300200241b0136a41086a2903007c2019201254ad7c200241d0146a41086a2903007c2003201954ad7c20024180146a41086a2903007c2004200354ad7c200241e0126a41086a2903007c2005200454ad7c2016200554ad7c420d868442137e201142ffffffffffffff03837c221642ffffffffffffff03833703a01e20022016423388200b42ffffffffffffff03837c3703a81e200241e81e6a41106a4200370300200241e81e6a41186a4200370300200241e81e6a41206a4200370300200242003703f01e200242013703e81e20024180196a200241e81e6a200241a01e6a106c20024190106a2002290388192216420020022903b01d2206420010d507200241a0106a200241a8196a2903002219420020022903b81d220942137e2211420010d50720024180116a20024180196a41206a2903002203420020022903c01d220d42137e2210420010d507200241e0116a20024180196a41186a2903002204420020022903c81d221242137e220b420010d507200241d0126a20024180196a41106a2903002205420020022903a81d2207420010d50720024190126a200742002016420010d507200241d00f6a20194200200642137e420010d507200241b0106a200342002011420010d50720024190116a200442002010420010d507200241f0116a20054200200b420010d507200241e0106a201642002009420010d507200241f0106a201942002010420010d507200241d0116a20034200200b420010d507200241c0126a200442002007420010d50720024180106a200542002006420010d507200241b0116a20164200200d420010d507200241c0116a20194200200b420010d507200241b0126a200342002007420010d507200241f00f6a200442002006420010d507200241d0106a200542002009420010d50720024180126a201642002012420010d507200241a0126a201942002007420010d507200241e00f6a200342002006420010d507200241c0106a200442002009420010d507200241a0116a20054200200d420010d507200241800f6a20022903a01222202002290380127c220620022903e00f7c220720022903c0107c220920022903a0117c220b20022903c011222120022903b0117c220d20022903b0127c221020022903f00f7c221120022903d0107c221220022903f010222220022903e0107c221320022903d0117c221420022903c0127c22172002290380107c221820022903a01022232002290390107c221a2002290380117c221b20022903e0117c221c20022903d0127c222420022903d00f22252002290390127c222620022903b0107c22272002290390117c222820022903f0117c2229423388200241d00f6a41086a29030020024190126a41086a2903007c2026202554ad7c200241b0106a41086a2903007c2027202654ad7c20024190116a41086a2903007c2028202754ad7c200241f0116a41086a2903007c2029202854ad7c420d86847c2226423388200241a0106a41086a29030020024190106a41086a2903007c201a202354ad7c20024180116a41086a2903007c201b201a54ad7c200241e0116a41086a2903007c201c201b54ad7c200241d0126a41086a2903007c2024201c54ad7c2026202454ad7c420d86847c221a423388200241f0106a41086a290300200241e0106a41086a2903007c2013202254ad7c200241d0116a41086a2903007c2014201354ad7c200241c0126a41086a2903007c2017201454ad7c20024180106a41086a2903007c2018201754ad7c201a201854ad7c420d86847c2213423388200241c0116a41086a290300200241b0116a41086a2903007c200d202154ad7c200241b0126a41086a2903007c2010200d54ad7c200241f00f6a41086a2903007c2011201054ad7c200241d0106a41086a2903007c2012201154ad7c2013201254ad7c420d86847c221042ffffffffffffff0383220d4200200842137e2212420010d507200241c00a6a2010423388200241a0126a41086a29030020024180126a41086a2903007c2006202054ad7c200241e00f6a41086a2903007c2007200654ad7c200241c0106a41086a2903007c2009200754ad7c200241a0116a41086a2903007c200b200954ad7c2010200b54ad7c420d868442137e202942ffffffffffffff03837c220742ffffffffffffff0383220642002015420010d507200241a00e6a201342ffffffffffffff0383220b4200200a42137e2211420010d507200241a00d6a201a42ffffffffffffff038322094200200c42137e2210420010d507200241e00b6a2007423388202642ffffffffffffff03837c22074200200f420010d507200241b0096a200d4200201542137e420010d507200241d00a6a200f42002006420010d507200241900e6a200b42002012420010d507200241900d6a200942002011420010d507200241f00b6a200742002010420010d507200241900f6a200d42002011420010d507200241b00a6a200642002008420010d507200241b00e6a200b42002010420010d507200241b00d6a20094200200f420010d507200241d00b6a200742002015420010d507200241a00f6a200d42002010420010d507200241a00a6a20064200200a420010d507200241c00e6a200b4200200f420010d507200241c00d6a200942002015420010d507200241c00b6a200742002008420010d507200241b00f6a200d4200200f420010d507200241900a6a20064200200c420010d507200241d00e6a200b42002015420010d507200241d00d6a200942002008420010d507200241b00b6a20074200200a420010d507200241800c6a20022903b01c420186220f4200200942137e2212420010d507200241a00b6a20022903901c420186221542002007420010d507200241b00c6a20022903a81c42018622084200200b42137e2211420010d507200241f00c6a20022903a01c420186220a4200200d42137e2210420010d507200241f0096a20022903981c420186220c42002006420010d507200241800a6a200642002015420010d507200241e00a6a200f4200200742137e420010d507200241900c6a200842002012420010d507200241c00c6a200a42002011420010d507200241800d6a200c42002010420010d507200241e00d6a201542002009420010d507200241a00c6a200f42002011420010d507200241e00c6a200842002010420010d507200241e0096a200a42002006420010d507200241900b6a200c42002007420010d507200241e00e6a20154200200b420010d507200241d00c6a200f42002010420010d507200241d0096a200842002006420010d507200241800b6a200a42002007420010d507200241f00d6a200c42002009420010d507200241c00f6a20154200200d420010d507200241c0096a200f42002006420010d507200241f00a6a200842002007420010d507200241800e6a200a42002009420010d507200241f00e6a200c4200200b420010d507200241c0076a2019420020022903900f221820022903b00a7c220f20022903b00e7c221520022903b00d7c220720022903d00b7c220820022903800f221220022903c00a7c220620022903a00e7c220920022903a00d7c220a20022903e00b7c220b20022903b009221320022903d00a7c220c20022903900e7c220d20022903900d7c221020022903f00b7c2211423388200241b0096a41086a290300200241d00a6a41086a2903007c200c201354ad7c200241900e6a41086a2903007c200d200c54ad7c200241900d6a41086a2903007c2010200d54ad7c200241f00b6a41086a2903007c2011201054ad7c420d86847c220c423388200241800f6a41086a290300200241c00a6a41086a2903007c2006201254ad7c200241a00e6a41086a2903007c2009200654ad7c200241a00d6a41086a2903007c200a200954ad7c200241e00b6a41086a2903007c200b200a54ad7c200c200b54ad7c420d86847c220942ffffffffffffff0383220642137e221a420010d507200241a0076a2016420020022903b00f221b20022903900a7c220a20022903d00e7c220b20022903d00d7c220d20022903b00b7c221020022903a00f221c20022903a00a7c221220022903c00e7c221320022903c00d7c221420022903c00b7c22172009423388200241900f6a41086a290300200241b00a6a41086a2903007c200f201854ad7c200241b00e6a41086a2903007c2015200f54ad7c200241b00d6a41086a2903007c2007201554ad7c200241d00b6a41086a2903007c2008200754ad7c2009200854ad7c420d86847c2215423388200241a00f6a41086a290300200241a00a6a41086a2903007c2012201c54ad7c200241c00e6a41086a2903007c2013201254ad7c200241c00d6a41086a2903007c2014201354ad7c200241c00b6a41086a2903007c2017201454ad7c2015201754ad7c420d86847c2207423388200241b00f6a41086a290300200241900a6a41086a2903007c200a201b54ad7c200241d00e6a41086a2903007c200b200a54ad7c200241d00d6a41086a2903007c200d200b54ad7c200241b00b6a41086a2903007c2010200d54ad7c2007201054ad7c420d868442137e201142ffffffffffffff03837c220a423388200c42ffffffffffffff03837c220f420010d507200241f0076a20034200201542ffffffffffffff0383220842137e2209420010d507200241b0086a20044200200742ffffffffffffff0383220b42137e2207420010d507200241d0066a20054200200a42ffffffffffffff03832215420010d507200241e0066a201542002016420010d507200241b0076a20194200200f42137e420010d507200241d0076a20034200201a420010d50720024180086a200442002009420010d507200241c0086a200542002007420010d507200241d0086a201642002006420010d507200241e0076a201942002009420010d507200241a0086a200342002007420010d507200241c0066a200442002015420010d50720024190076a20054200200f420010d50720024180096a201642002008420010d50720024190086a201942002007420010d507200241e0056a200342002015420010d50720024180076a20044200200f420010d507200241e0086a200542002006420010d507200241a0096a20164200200b420010d50720024180056a201942002015420010d507200241f0066a20034200200f420010d507200241f0086a200442002006420010d50720024190096a200542002008420010d50720022d008019211d200220022903c009221720022903c00f7c220f20022903f00a7c221520022903800e7c221620022903f00e7c221920022903d00c221820022903e00e7c220320022903d0097c220420022903800b7c220520022903f00d7c220620022903a00c221a20022903e00d7c220720022903e00c7c220820022903e0097c220920022903900b7c220a20022903800c221b20022903a00b7c220b20022903b00c7c220c20022903f00c7c220d20022903f0097c221020022903e00a221c20022903800a7c221120022903900c7c221220022903c00c7c221320022903800d7c2214423388200241e00a6a41086a290300200241800a6a41086a2903007c2011201c54ad7c200241900c6a41086a2903007c2012201154ad7c200241c00c6a41086a2903007c2013201254ad7c200241800d6a41086a2903007c2014201354ad7c420d86847c2211423388200241800c6a41086a290300200241a00b6a41086a2903007c200b201b54ad7c200241b00c6a41086a2903007c200c200b54ad7c200241f00c6a41086a2903007c200d200c54ad7c200241f0096a41086a2903007c2010200d54ad7c2011201054ad7c420d86847c220b423388200241a00c6a41086a290300200241e00d6a41086a2903007c2007201a54ad7c200241e00c6a41086a2903007c2008200754ad7c200241e0096a41086a2903007c2009200854ad7c200241900b6a41086a2903007c200a200954ad7c200b200a54ad7c420d86847c2209423388200241d00c6a41086a290300200241e00e6a41086a2903007c2003201854ad7c200241d0096a41086a2903007c2004200354ad7c200241800b6a41086a2903007c2005200454ad7c200241f00d6a41086a2903007c2006200554ad7c2009200654ad7c420d86847c2203423388200241c0096a41086a290300200241c00f6a41086a2903007c200f201754ad7c200241f00a6a41086a2903007c2015200f54ad7c200241800e6a41086a2903007c2016201554ad7c200241f00e6a41086a2903007c2019201654ad7c2003201954ad7c420d868442137e201442ffffffffffffff03837c220f423388201142ffffffffffffff03837c22073703801e2002200f42ffffffffffffff038322083703f81d2002200342ffffffffffffff038322063703981e2002200942ffffffffffffff038322093703901e2002200b42ffffffffffffff0383220a3703881e200241c0076a41086a2903002118200241a0076a41086a290300211a20022903c007211520022903a007210b200241f0076a41086a290300211b20022903f007210d200241b0086a41086a290300211c20022903b0082110200241d0066a41086a290300212420022903d0062111200241e0066a41086a2903002126200241b0076a41086a290300212720022903e006211220022903b0072116200241d0076a41086a290300212820022903d007211320024180086a41086a29030021292002290380082114200241c0086a41086a290300212020022903c008211720022903d008210320022903e007211920022903a008210420022903c0062105200229039007210c200241c81e6a200241f81d6a106a20022d00c81e410171106d211e200241f0056a20022903a01d220f4200200c20052004201920037c22037c22047c22057c220c20112010200d2015200b7c220b7c220d7c22107c2211201720142013201620127c22127c22137c22147c2217423388202020292028202720267c2012201654ad7c7c2013201254ad7c7c2014201354ad7c7c2017201454ad7c420d86847c22164233882024201c201b2018201a7c200b201554ad7c7c200d200b54ad7c7c2010200d54ad7c7c2011201054ad7c2016201154ad7c420d86847c220d42ffffffffffffff0383220b42137e221c420010d507200241d0046a20022903801d22154200200229038005222420022903a0097c221020022903f0067c221120022903f0087c22122002290390097c221320022903900822262002290380097c221420022903e0057c22182002290380077c221a20022903e0087c221b200d423388200241e0076a41086a290300200241d0086a41086a2903007c2003201954ad7c200241a0086a41086a2903007c2004200354ad7c200241c0066a41086a2903007c2005200454ad7c20024190076a41086a2903007c200c200554ad7c200d200c54ad7c420d86847c220342338820024190086a41086a29030020024180096a41086a2903007c2014202654ad7c200241e0056a41086a2903007c2018201454ad7c20024180076a41086a2903007c201a201854ad7c200241e0086a41086a2903007c201b201a54ad7c2003201b54ad7c420d86847c220442338820024180056a41086a290300200241a0096a41086a2903007c2010202454ad7c200241f0066a41086a2903007c2011201054ad7c200241f0086a41086a2903007c2012201154ad7c20024190096a41086a2903007c2013201254ad7c2004201354ad7c420d868442137e201742ffffffffffffff03837c2205423388201642ffffffffffffff03837c2216420010d507200241a0056a20022903981d22194200200342ffffffffffffff0383220d42137e2210420010d507200241b0036a20022903901d22034200200442ffffffffffffff0383221142137e220c420010d50720024180046a20022903881d22044200200542ffffffffffffff03832205420010d50720024190046a200542002015420010d507200241e0046a200f4200201642137e420010d50720024180066a20194200201c420010d507200241b0056a200342002010420010d507200241c0036a20044200200c420010d50720024190066a20154200200b420010d50720024190056a200f42002010420010d507200241a0036a20194200200c420010d507200241f0036a200342002005420010d507200241c0046a200442002016420010d507200241c0056a20154200200d420010d507200241c0026a200f4200200c420010d507200241e0036a201942002005420010d507200241b0046a200342002016420010d507200241a0066a20044200200b420010d507200241f0046a201542002011420010d507200241d0036a200f42002005420010d507200241a0046a201942002016420010d507200241b0066a20034200200b420010d507200241d0056a20044200200d420010d507200241d0026a42f0ffffffffffff3f20067d221342ffffffffffffff038342f0ffffffffffff3f20097d221a4233887c2006854200201ead42ff01837d220483200685220f4200200229039005221b2002290390067c221620022903a0037c221920022903f0037c220320022903c0047c220520022903f005221420022903d0047c221520022903a0057c220620022903b0037c220b2002290380047c220c20022903e00422172002290390047c220d2002290380067c221020022903b0057c221120022903c0037c2212423388200241e0046a41086a29030020024190046a41086a2903007c200d201754ad7c20024180066a41086a2903007c2010200d54ad7c200241b0056a41086a2903007c2011201054ad7c200241c0036a41086a2903007c2012201154ad7c420d86847c220d423388200241f0056a41086a290300200241d0046a41086a2903007c2015201454ad7c200241a0056a41086a2903007c2006201554ad7c200241b0036a41086a2903007c200b200654ad7c20024180046a41086a2903007c200c200b54ad7c200d200c54ad7c420d86847c220b42ffffffffffffff0383220642137e221c420010d507200241c0016a201342338842137e42d0fdffffffffff3f20087d222442ffffffffffffff03837c2008852004832008852215420020022903d003222620022903f0047c220820022903a0047c220c20022903b0067c221020022903d0057c221120022903c002222720022903c0057c221320022903e0037c221420022903b0047c221720022903a0067c2218200b42338820024190056a41086a29030020024190066a41086a2903007c2016201b54ad7c200241a0036a41086a2903007c2019201654ad7c200241f0036a41086a2903007c2003201954ad7c200241c0046a41086a2903007c2005200354ad7c200b200554ad7c420d86847c2203423388200241c0026a41086a290300200241c0056a41086a2903007c2013202754ad7c200241e0036a41086a2903007c2014201354ad7c200241b0046a41086a2903007c2017201454ad7c200241a0066a41086a2903007c2018201754ad7c2003201854ad7c420d86847c2205423388200241d0036a41086a290300200241f0046a41086a2903007c2008202654ad7c200241a0046a41086a2903007c200c200854ad7c200241b0066a41086a2903007c2010200c54ad7c200241d0056a41086a2903007c2011201054ad7c2005201154ad7c420d868442137e201242ffffffffffffff03837c220c423388200d42ffffffffffffff03837c2216420010d507200241f0016a201a42ffffffffffffff038342f0ffffffffffff3f200a7d220d4233887c20098520048320098522194200200342ffffffffffffff0383220842137e220b420010d507200241206a200d42ffffffffffffff038342f0ffffffffffff3f20077d220d4233887c200a85200483200a8522034200200542ffffffffffffff0383220a42137e2209420010d507200241f0006a200d42ffffffffffffff038320244233887c20078520048320078522044200200c42ffffffffffffff03832205420010d50720024180016a200542002015420010d507200241d0016a200f4200201642137e420010d507200241e0026a20194200201c420010d50720024180026a20034200200b420010d507200241306a200442002009420010d507200241f0026a201542002006420010d507200241e0016a200f4200200b420010d507200241106a201942002009420010d507200241e0006a200342002005420010d507200241b0016a200442002016420010d50720024190026a201542002008420010d5072002200f42002009420010d507200241d0006a201942002005420010d507200241a0016a200342002016420010d50720024180036a200442002006420010d507200241b0026a20154200200a420010d507200241c0006a200f42002005420010d50720024190016a201942002016420010d50720024190036a200342002006420010d507200241a0026a200442002008420010d5072002200f3703981e200220193703901e200220033703881e200220043703801e200220153703f81d200220063703b01e200220083703b81e2002200a3703c01e200220053703a01e200220163703a81e200220022903e001220b20022903f0027c220f20022903107c221520022903607c221620022903b0017c221920022903d002220c20022903c0017c220320022903f0017c220420022903207c220520022903707c220620022903d001220d2002290380017c220720022903e0027c22082002290380027c220920022903307c220a423388200241d0016a41086a29030020024180016a41086a2903007c2007200d54ad7c200241e0026a41086a2903007c2008200754ad7c20024180026a41086a2903007c2009200854ad7c200241306a41086a2903007c200a200954ad7c420d86847c2207423388200241d0026a41086a290300200241c0016a41086a2903007c2003200c54ad7c200241f0016a41086a2903007c2004200354ad7c200241206a41086a2903007c2005200454ad7c200241f0006a41086a2903007c2006200554ad7c2007200654ad7c420d86847c220342ffffffffffffff03833703f81e2002200229030022092002290390027c220420022903507c220520022903a0017c22062002290380037c22082003423388200241e0016a41086a290300200241f0026a41086a2903007c200f200b54ad7c200241106a41086a2903007c2015200f54ad7c200241e0006a41086a2903007c2016201554ad7c200241b0016a41086a2903007c2019201654ad7c2003201954ad7c420d86847c220f42ffffffffffffff03833703801f20022002290340220b20022903b0027c22152002290390017c22162002290390037c221920022903a0027c2203200f423388200241086a29030020024190026a41086a2903007c2004200954ad7c200241d0006a41086a2903007c2005200454ad7c200241a0016a41086a2903007c2006200554ad7c20024180036a41086a2903007c2008200654ad7c200f200854ad7c420d86847c220f42ffffffffffffff03833703881f2002200f423388200241c0006a41086a290300200241b0026a41086a2903007c2015200b54ad7c20024190016a41086a2903007c2016201554ad7c20024190036a41086a2903007c2019201654ad7c200241a0026a41086a2903007c2003201954ad7c200f200354ad7c420d868442137e200a42ffffffffffffff03837c220f42ffffffffffffff03833703e81e2002200f423388200742ffffffffffffff03837c3703f01e201d450d00200241c81e6a200241e81e6a106a20022d00c81e410171106d41ff01714101460d0020024198196a420037030020024190196a420037030020024188196a42003703002002420037038019200241c81e6a200241a01e6a106a20022d00c81e221d4100201d6b72417f7341800171410776106d410171211e4101211d0340200241c81e6a201d6a2d000020024180196a201d6a2d000073221f4100201f6b72417f7341800171410776106d201e71211e201d41016a221d4120470d000b4200210e201e106d41ff01714101460d0020024180196a41206a200241f81d6a41206a29030037030020024180196a41186a200241f81d6a41186a29030037030020024180196a41106a200241f81d6a41106a29030037030020024180196a41086a200241f81d6a41086a290300370300200241b0196a200241a01e6a41086a290300370300200241b8196a200241a01e6a41106a290300370300200241c0196a200241a01e6a41186a290300370300200241c8196a200241a01e6a41206a290300370300200220022903f81d37038019200220022903a01e3703a819200241c01b6a20024180196a41d00010e4071a200241a01b6a41086a4200370300200241a01b6a41106a4200370300200241a01b6a41186a4200370300200241f81a6a41086a200241e81e6a41086a290300370300200241f81a6a41106a200241e81e6a41106a290300370300200241f81a6a41186a200241e81e6a41186a290300370300200241f81a6a41206a200241e81e6a41206a290300370300200242003703a01b200220022903e81e3703f81a4201210e0b02400240200e4200520d00200241a01a6a410f6a20024180196a410f6a2201290000370000200241a01a6a41086a20024180196a41086a221e29000037030020022002290080193703a01a20024180196a200241a01a6a41d30010e4071a200241e81e6a41186a200241801a6a41186a290000370300200241e81e6a41106a200241801a6a41106a290000370300200241e81e6a41086a200241801a6a41086a290000370300200241c01b6a41086a200241d8196a41086a290000370300200241c01b6a41106a200241d8196a41106a290000370300200241c01b6a41186a200241d8196a41186a290000370300200241c01b6a41206a200241d8196a41206a290000370300200220022900801a3703e81e200220022900d8193703c01b4101211d200041013a000420002002290080193700052000410d6a201e290000370000200041146a20012900003700000c010b200241a01a6a410372200241c01b6a41d00010e4071a200241801a6a41186a221d200241a01b6a41186a290300370300200241801a6a41106a221e200241a01b6a41106a290300370300200241801a6a41086a221f200241a01b6a41086a290300370300200241d8196a41086a222a200241f81a6a41086a290300370300200241d8196a41106a222b200241f81a6a41106a290300370300200241d8196a41186a222c200241f81a6a41186a290300370300200241d8196a41206a222d200241f81a6a41206a290300370300200220022903a01b3703801a200220022903f81a3703d81920024180196a200241a01a6a41d30010e4071a200241e81e6a41186a222e201d290300370300200241e81e6a41106a221d201e290300370300200241e81e6a41086a221e201f290300370300200241c01b6a41086a221f202a290300370300200241c01b6a41106a222a202b290300370300200241c01b6a41186a222b202c290300370300200241c01b6a41206a222c202d290300370300200220022903801a3703e81e200220022903d8193703c01b200041086a20024180196a41036a41d00010e4071a200041d8006a4201370300200041e0006a20022903e81e370000200041e8006a201e290300370000200041f0006a201d290300370000200041f8006a202e29030037000020004180016a20022903c01b37000020004188016a201f29030037000020004190016a202a29030037000020004198016a202b290300370000200041a0016a202c290300370000200041c0016a200141186a290000370000200041b8016a200141106a290000370000200041b0016a200141086a290000370000200041a8016a20012900003700004100211d0b2000201d360200200241901f6a24000bf18f020a067f1a7e037f017e017f307e057f157e017f057e23004180cb006b22042400200441d8c6006a200341d00110e4071a200441d8c6006a41d8a7c7004109200241a0016a412010830120044188c5006a200441d8c6006a41d00110e4071a200441a8c8006a41386a22054200370300200441a8c8006a41306a22064200370300200441a8c8006a41286a22074200370300200441a8c8006a41206a22024200370300200441a8c8006a41186a22034200370300200441a8c8006a41106a22084200370300200441a8c8006a41086a22094200370300200442003703a84820044188c5006a41929fc8004107200441a8c8006a41c0001085012008310000210a2009310000210b2003310000210c20043100ba48210d20043100b948210e20043100b748210f20043100b548211020043100b648211120043100c748211220043100c648211320043100c548211420043100c448211520043100c348211620043100c248211720043100b448211820043100b348211920043100b248211a20043100b148211b20043100af48211c20043100c148211d20043100bf48211e20043100be48211f20043100bb48212020043100bc48212120043100bd482122200420043100a94842088620043100a8488420043100aa484210868420043100ab484218868420043100ac484220868420043100ad484228868420043100ae4822234230868442ffffffffffffff03833703b04a20042020202142088684202242108684201f42188684201e42208684200c42288684201d4230868442018842ffffffffffffff03833703c84a20042023201c42088684200b42108684201b42188684201a4220868420194228868420184230868442038842ffffffffffffff03833703b84a2004200c201d42088684201742108684201642188684201542208684201442288684201342308684201242388684420c8842ffffffffffffff03833703d04a20042018201042088684201142108684200f42188684200a42208684200e42288684200d4230868420204238868442068842ffffffffffffff03833703c04a200441e8c8006a200441b0ca006a106e2006310000210a2007310000210b2005310000210c20043100da48210d20043100d948210e20043100d748210f20043100d548211020043100d648211120043100e748211220043100e648211320043100e548211420043100e448211520043100e348211620043100e248211720043100d448211820043100d348211920043100d248211a20043100d148211b20043100cf48211c20043100e148211d20043100df48211e20043100de48211f20043100db48212020043100dc48212120043100dd482122200420043100c94842088620023100008420043100ca484210868420043100cb484218868420043100cc484220868420043100cd484228868420043100ce4822234230868442ffffffffffffff03833703d84a20042020202142088684202242108684201f42188684201e42208684200c42288684201d4230868442018842ffffffffffffff03833703f04a20042023201c42088684200b42108684201b42188684201a4220868420194228868420184230868442038842ffffffffffffff03833703e04a2004200c201d42088684201742108684201642188684201542208684201442288684201342308684201242388684420c8842ffffffffffffff03833703f84a20042018201042088684201142108684200f42188684200a42208684200e42288684200d4230868420204238868442068842ffffffffffffff03833703e84a200441d8c6006a200441d8ca006a106e200441a8356a20042903d047220c420042fabaabb1878ad401420010d507200441f8356a200441d8c6006a4198016a2903002218420042968c8a82a4c39824420010d507200441c8366a200441d8c6006a4190016a290300221d420042d587a4ceaceea43d420010d50720044198376a200441d8c6006a4188016a2903002220420042edd39cadab84b215420010d507200441e8376a200441d8c6006a4180016a290300220a420042d9e2cbb5c2f2a603420010d50720044198356a200c420042d9e2cbb5c2f2a603420010d507200441e8356a20184200428ee0b9a98cbfbd1f420010d507200441b8366a201d420042968c8a82a4c39824420010d50720044188376a2020420042d587a4ceaceea43d420010d507200441d8376a200a420042edd39cadab84b215420010d507200441b8356a200c420042d2808e80cce8f301420010d50720044188366a2018420042d587a4ceaceea43d420010d507200441d8366a201d420042edd39cadab84b215420010d507200441a8376a2020420042d9e2cbb5c2f2a603420010d507200441f8376a200a420042fabaabb1878ad401420010d507200441c8356a200c420042f7f281baccf19c03420010d50720044198366a2018420042edd39cadab84b215420010d507200441e8366a201d420042d9e2cbb5c2f2a603420010d507200441b8376a2020420042fabaabb1878ad401420010d50720044188386a200a420042d2808e80cce8f301420010d507200441d8356a200c420042ffdb95eed98d9001420010d507200441a8366a2018420042d9e2cbb5c2f2a603420010d507200441f8366a201d420042fabaabb1878ad401420010d507200441c8376a2020420042d2808e80cce8f301420010d50720044198386a200a420042f7f281baccf19c03420010d507200441b8386a20042903b849220c4200200441d8c6006a41d8006a22072903002218420010d507200441c8396a200441e8c8006a41f0006a290300221d4200200441d8c6006a41e0006a290300220e42137e2212420010d507200441883a6a200441e8c8006a41e8006a29030022204200200441d8c6006a41e8006a290300221042137e2211420010d507200441c83a6a200441e8c8006a41e0006a290300220a4200200441d8c6006a41f0006a290300221342137e220f420010d507200441f8386a200441e8c8006a41d8006a290300220b420020042903a847220d420010d507200441a8386a200d4200200c420010d507200441b8396a201d4200201842137e420010d507200441f8396a202042002012420010d507200441b83a6a200a42002011420010d507200441f83a6a200b4200200f420010d507200441c8386a200c4200200e420010d507200441d8396a201d42002011420010d507200441983a6a20204200200f420010d50720044188396a200a4200200d420010d507200441883b6a200b42002018420010d507200441d8386a200c42002010420010d507200441e8396a201d4200200f420010d50720044198396a20204200200d420010d507200441d83a6a200a42002018420010d507200441983b6a200b4200200e420010d507200441e8386a200c42002013420010d507200441a8396a201d4200200d420010d507200441a83a6a202042002018420010d507200441e83a6a200a4200200e420010d507200441a83b6a200b42002010420010d507200441a8336a200441e8c8006a4198016a290300220c4200200429038836221a20042903b8357c221d20042903d8367c222020042903a8377c220a20042903f8377c220b20042903f835221420042903a8357c221820042903c8367c220d2004290398377c220e20042903e8377c220f20042903e83522152004290398357c221020042903b8367c22112004290388377c221220042903d8377c2213423388200441e8356a41086a29030020044198356a41086a2903007c2010201554ad7c200441b8366a41086a2903007c2011201054ad7c20044188376a41086a2903007c2012201154ad7c200441d8376a41086a2903007c2013201254ad7c420d86847c2210423388200441f8356a41086a290300200441a8356a41086a2903007c2018201454ad7c200441c8366a41086a2903007c200d201854ad7c20044198376a41086a2903007c200e200d54ad7c200441e8376a41086a2903007c200f200e54ad7c2010200f54ad7c420d86847c220d42ffffffffffffff0383220e42137e221b420010d50720044188336a20042903e0492218420020042903a836221c20042903d8357c220f20042903f8367c221120042903c8377c22122004290398387c2214200429039836221e20042903c8357c221520042903e8367c221620042903b8377c22172004290388387c2219200d42338820044188366a41086a290300200441b8356a41086a2903007c201d201a54ad7c200441d8366a41086a2903007c2020201d54ad7c200441a8376a41086a2903007c200a202054ad7c200441f8376a41086a2903007c200b200a54ad7c200d200b54ad7c420d86847c220a42338820044198366a41086a290300200441c8356a41086a2903007c2015201e54ad7c200441e8366a41086a2903007c2016201554ad7c200441b8376a41086a2903007c2017201654ad7c20044188386a41086a2903007c2019201754ad7c200a201954ad7c420d86847c220b423388200441a8366a41086a290300200441d8356a41086a2903007c200f201c54ad7c200441f8366a41086a2903007c2011200f54ad7c200441c8376a41086a2903007c2012201154ad7c20044198386a41086a2903007c2014201254ad7c200b201454ad7c420d868442137e201342ffffffffffffff03837c220d423388201042ffffffffffffff03837c221d420010d507200441d8336a200441e8c8006a4190016a29030022204200200a42ffffffffffffff0383221042137e2211420010d50720044198346a200441e8c8006a4188016a290300220a4200200b42ffffffffffffff0383221242137e220f420010d507200441b8326a200441e8c8006a4180016a290300220b4200200d42ffffffffffffff0383220d420010d507200441c8326a200d42002018420010d50720044198336a200c4200201d42137e420010d507200441b8336a20204200201b420010d507200441e8336a200a42002011420010d507200441a8346a200b4200200f420010d507200441b8346a20184200200e420010d507200441c8336a200c42002011420010d50720044188346a20204200200f420010d507200441a8326a200a4200200d420010d507200441f8326a200b4200201d420010d507200441e8346a201842002010420010d507200441f8336a200c4200200f420010d507200441c8316a20204200200d420010d507200441e8326a200a4200201d420010d507200441c8346a200b4200200e420010d50720044188356a201842002012420010d507200441f82f6a200c4200200d420010d507200441d8326a20204200201d420010d507200441d8346a200a4200200e420010d507200441f8346a200b42002010420010d507200441c8c4006a20042903e848221220042903904922137c220c420020042903e0462214200441d8c6006a41306a222429030022157c2218420010d50720044198c0006a2004290388492216200441e8c8006a41c8006a29030022177c221d420020042903e8462219200441d8c6006a41386a2225290300221a7c220e42137e221b420010d507200441b8c1006a200429038049221c200441e8c8006a41c0006a290300221e7c2220420020042903f046221f200441d8c6006a41c0006a222629030022217c221042137e2211420010d507200441d8c2006a20042903f8482222200441e8c8006a41386a29030022237c220a420020042903f8462227200441d8c6006a41c8006a222829030022297c222a42137e220f420010d507200441f8c3006a20042903f048222b200441e8c8006a41306a290300222c7c220b420020042903d846222d200429038047222e7c220d420010d507200441d8c4006a200d4200200c420010d507200441a8c0006a201d4200201842137e420010d507200441c8c1006a20204200201b420010d507200441e8c2006a200a42002011420010d50720044188c4006a200b4200200f420010d507200441b8c4006a200c4200200e420010d50720044188c0006a201d42002011420010d507200441a8c1006a20204200200f420010d507200441c8c2006a200a4200200d420010d507200441e8c3006a200b42002018420010d507200441a8c4006a200c42002010420010d507200441f83f6a201d4200200f420010d50720044198c1006a20204200200d420010d507200441b8c2006a200a42002018420010d507200441d8c3006a200b4200200e420010d50720044198c4006a200c4200202a420010d507200441e83f6a201d4200200d420010d50720044188c1006a202042002018420010d507200441a8c2006a200a4200200e420010d507200441c8c3006a200b42002010420010d507200441f83e6a201720167d42f0ffffffffffff3f7c221d42338842137e201320127d42d0fdffffffffff3f7c220b42ffffffffffffff03837c220c4200201520147d42f0ffffffffffff3f7c222042ffffffffffffff0383202e202d7d42d0fdffffffffff3f7c220d4233887c2218420010d507200441c83f6a201d42ffffffffffffff0383201e201c7d42f0ffffffffffff3f7c220a4233887c221d4200201a20197d42f0ffffffffffff3f7c220f42ffffffffffffff038320204233887c220e42137e2212420010d507200441e8c0006a200a42ffffffffffffff0383202320227d42f0ffffffffffff3f7c220a4233887c222042002021201f7d42f0ffffffffffff3f7c221342ffffffffffffff0383200f4233887c221042137e2211420010d50720044188c2006a200a42ffffffffffffff0383202c202b7d42f0ffffffffffff3f7c22144233887c220a4200202920277d42f0ffffffffffff3f7c221542ffffffffffffff038320134233887c221342137e220f420010d507200441a8c3006a201442ffffffffffffff0383200b4233887c220b4200201542338842137e200d42ffffffffffffff03837c220d420010d507200441883f6a200d4200200c420010d507200441d83f6a201d4200201842137e420010d507200441f8c0006a202042002012420010d50720044198c2006a200a42002011420010d507200441b8c3006a200b4200200f420010d507200441e83e6a200c4200200e420010d507200441b83f6a201d42002011420010d507200441d8c0006a20204200200f420010d507200441f8c1006a200a4200200d420010d50720044198c3006a200b42002018420010d507200441d83e6a200c42002010420010d507200441a83f6a201d4200200f420010d507200441c8c0006a20204200200d420010d507200441e8c1006a200a42002018420010d50720044188c3006a200b4200200e420010d507200441a83e6a200c42002013420010d507200441983f6a201d4200200d420010d507200441b8c0006a202042002018420010d507200441d8c1006a200a4200200e420010d507200441f8c2006a200b42002010420010d507200441882d6a20042903e83f222b2004290398447c220c2004290388417c221820042903a8427c221d20042903c8437c222020042903f83f221c20042903a8447c220a2004290398417c220b20042903b8427c220d20042903d8437c220e200429038840221e20042903b8447c220f20042903a8417c221020042903c8427c221120042903e8437c2212200429039840221f20042903c8447c221320042903b8417c221420042903d8427c221520042903f8437c221620042903a840222120042903d8447c221720042903c8417c221920042903e8427c221a2004290388447c221b423388200441a8c0006a41086a290300200441d8c4006a41086a2903007c2017202154ad7c200441c8c1006a41086a2903007c2019201754ad7c200441e8c2006a41086a2903007c201a201954ad7c20044188c4006a41086a2903007c201b201a54ad7c420d86847c221742338820044198c0006a41086a290300200441c8c4006a41086a2903007c2013201f54ad7c200441b8c1006a41086a2903007c2014201354ad7c200441d8c2006a41086a2903007c2015201454ad7c200441f8c3006a41086a2903007c2016201554ad7c2017201654ad7c420d86847c221342338820044188c0006a41086a290300200441b8c4006a41086a2903007c200f201e54ad7c200441a8c1006a41086a2903007c2010200f54ad7c200441c8c2006a41086a2903007c2011201054ad7c200441e8c3006a41086a2903007c2012201154ad7c2013201254ad7c420d86847c220f423388200441f83f6a41086a290300200441a8c4006a41086a2903007c200a201c54ad7c20044198c1006a41086a2903007c200b200a54ad7c200441b8c2006a41086a2903007c200d200b54ad7c200441d8c3006a41086a2903007c200e200d54ad7c200f200e54ad7c420d86847c220a42ffffffffffffff0383222c20042903983f222d20042903a83e7c220b20042903b8407c220d20042903d8417c220e20042903f8427c221020042903a83f222e20042903d83e7c221120042903c8407c221220042903e8417c22142004290388437c221520042903b83f222f20042903e83e7c221620042903d8407c221920042903f8417c221a2004290398437c221c20042903c83f223020042903f83e7c221e20042903e8407c221f2004290388427c222120042903a8437c222220042903d83f223120042903883f7c222320042903f8407c22272004290398427c222920042903b8437c222a423388200441d83f6a41086a290300200441883f6a41086a2903007c2023203154ad7c200441f8c0006a41086a2903007c2027202354ad7c20044198c2006a41086a2903007c2029202754ad7c200441b8c3006a41086a2903007c202a202954ad7c420d86847c2223423388200441c83f6a41086a290300200441f83e6a41086a2903007c201e203054ad7c200441e8c0006a41086a2903007c201f201e54ad7c20044188c2006a41086a2903007c2021201f54ad7c200441a8c3006a41086a2903007c2022202154ad7c2023202254ad7c420d86847c221e423388200441b83f6a41086a290300200441e83e6a41086a2903007c2016202f54ad7c200441d8c0006a41086a2903007c2019201654ad7c200441f8c1006a41086a2903007c201a201954ad7c20044198c3006a41086a2903007c201c201a54ad7c201e201c54ad7c420d86847c2216423388200441a83f6a41086a290300200441d83e6a41086a2903007c2011202e54ad7c200441c8c0006a41086a2903007c2012201154ad7c200441e8c1006a41086a2903007c2014201254ad7c20044188c3006a41086a2903007c2015201454ad7c2016201554ad7c420d86847c221142ffffffffffffff0383222e7d42f0ffffffffffff3f7c222f42338842137e200a423388200441e83f6a41086a29030020044198c4006a41086a2903007c200c202b54ad7c20044188c1006a41086a2903007c2018200c54ad7c200441a8c2006a41086a2903007c201d201854ad7c200441c8c3006a41086a2903007c2020201d54ad7c200a202054ad7c420d868442137e201b42ffffffffffffff03837c223042ffffffffffffff038322312011423388200441983f6a41086a290300200441a83e6a41086a2903007c200b202d54ad7c200441b8c0006a41086a2903007c200d200b54ad7c200441d8c1006a41086a2903007c200e200d54ad7c200441f8c2006a41086a2903007c2010200e54ad7c2011201054ad7c420d868442137e202a42ffffffffffffff03837c222d42ffffffffffffff038322327d42d0fdffffffffff3f7c223342ffffffffffffff03837c220c420020042903a839222920042903e8387c221820042903a83a7c221d20042903e83a7c222020042903a83b7c220a20042903e839222a20042903d8387c220b2004290398397c220d20042903d83a7c220e20042903983b7c221020042903d839222b20042903c8387c221120042903983a7c22122004290388397c221420042903883b7c221520042903c839223420042903b8387c221920042903883a7c221a20042903c83a7c221b20042903f8387c221c20042903b839223520042903a8387c221f20042903f8397c222120042903b83a7c222220042903f83a7c2227423388200441b8396a41086a290300200441a8386a41086a2903007c201f203554ad7c200441f8396a41086a2903007c2021201f54ad7c200441b83a6a41086a2903007c2022202154ad7c200441f83a6a41086a2903007c2027202254ad7c420d86847c221f423388200441c8396a41086a290300200441b8386a41086a2903007c2019203454ad7c200441883a6a41086a2903007c201a201954ad7c200441c83a6a41086a2903007c201b201a54ad7c200441f8386a41086a2903007c201c201b54ad7c201f201c54ad7c420d86847c2219423388200441d8396a41086a290300200441c8386a41086a2903007c2011202b54ad7c200441983a6a41086a2903007c2012201154ad7c20044188396a41086a2903007c2014201254ad7c200441883b6a41086a2903007c2015201454ad7c2019201554ad7c420d86847c2211423388200441e8396a41086a290300200441d8386a41086a2903007c200b202a54ad7c20044198396a41086a2903007c200d200b54ad7c200441d83a6a41086a2903007c200e200d54ad7c200441983b6a41086a2903007c2010200e54ad7c2011201054ad7c420d86847c220b423388200441a8396a41086a290300200441e8386a41086a2903007c2018202954ad7c200441a83a6a41086a2903007c201d201854ad7c200441e83a6a41086a2903007c2020201d54ad7c200441a83b6a41086a2903007c200a202054ad7c200b200a54ad7c420d868442137e202742ffffffffffffff03837c2234423388201f42ffffffffffffff03837c420186223520042903f82f22362004290388357c221820042903d8327c221d20042903d8347c222020042903f8347c220a20042903f833223720042903e8347c220d20042903c8317c220e20042903e8327c221020042903c8347c221220042903c833223820042903b8347c22142004290388347c221520042903a8327c221a20042903f8327c221b20042903a83322392004290388337c221c20042903d8337c221f2004290398347c222120042903b8327c2222200429039833223a20042903c8327c222720042903b8337c222920042903e8337c222a20042903a8347c222b42338820044198336a41086a290300200441c8326a41086a2903007c2027203a54ad7c200441b8336a41086a2903007c2029202754ad7c200441e8336a41086a2903007c202a202954ad7c200441a8346a41086a2903007c202b202a54ad7c420d86847c2227423388200441a8336a41086a29030020044188336a41086a2903007c201c203954ad7c200441d8336a41086a2903007c201f201c54ad7c20044198346a41086a2903007c2021201f54ad7c200441b8326a41086a2903007c2022202154ad7c2027202254ad7c420d86847c221c423388200441c8336a41086a290300200441b8346a41086a2903007c2014203854ad7c20044188346a41086a2903007c2015201454ad7c200441a8326a41086a2903007c201a201554ad7c200441f8326a41086a2903007c201b201a54ad7c201c201b54ad7c420d86847c2214423388200441f8336a41086a290300200441e8346a41086a2903007c200d203754ad7c200441c8316a41086a2903007c200e200d54ad7c200441e8326a41086a2903007c2010200e54ad7c200441c8346a41086a2903007c2012201054ad7c2014201254ad7c420d86847c220d423388200441f82f6a41086a29030020044188356a41086a2903007c2018203654ad7c200441d8326a41086a2903007c201d201854ad7c200441d8346a41086a2903007c2020201d54ad7c200441f8346a41086a2903007c200a202054ad7c200d200a54ad7c420d868442137e202b42ffffffffffffff03837c2218423388202742ffffffffffffff03837c221d7d42f0ffffffffffff3f7c222042ffffffffffffff0383203442018642feffffffffffff0783221f201842ffffffffffffff038322217d42d0fdffffffffff3f7c22184233887c220a420010d507200441f82e6a202f42ffffffffffffff0383200f42ffffffffffffff0383220e201642ffffffffffffff038322107d42f0ffffffffffff3f7c22154233887c22124200201942018642feffffffffffff07832216201c42ffffffffffffff0383221b7d42f0ffffffffffff3f7c221942ffffffffffffff038320204233887c220f42137e221a420010d507200441d8306a201542ffffffffffffff0383201342ffffffffffffff03832220201e42ffffffffffffff038322227d42f0ffffffffffff3f7c22154233887c22134200201142018642feffffffffffff0783221e201442ffffffffffffff038322297d42f0ffffffffffff3f7c221c42ffffffffffffff038320194233887c221942137e2211420010d507200441e8276a201542ffffffffffffff03832030423388201742ffffffffffffff03837c2217202d423388202342ffffffffffffff03837c22237d42f0ffffffffffff3f7c22154233887c22144200200b42018642feffffffffffff0783222b200d42ffffffffffffff0383222d7d42f0ffffffffffff3f7c220b42ffffffffffffff0383201c4233887c221c42137e220d420010d507200441c8266a201542ffffffffffffff038320334233887c22154200200b42338842137e201842ffffffffffffff03837c2218420010d507200441d8266a20184200200c420010d507200441982d6a20124200200a42137e222f420010d507200441882f6a20134200201a420010d507200441e8306a201442002011420010d507200441f8276a20154200200d420010d507200441c8306a201242002011420010d507200441d82e6a200c4200200f420010d507200441d8276a20134200200d420010d507200441b8266a201442002018420010d507200441f82c6a20154200200a420010d50720044198306a200c42002019420010d507200441c8276a20124200200d420010d50720044188256a201342002018420010d507200441e82c6a20144200200a420010d507200441c82e6a20154200200f420010d507200441f8266a200c4200201c420010d507200441d8236a201242002018420010d507200441d82c6a20134200200a420010d507200441b82e6a20144200200f420010d50720044188306a201542002019420010d50720044188326a202e202c7c222a4200201b20167c220b42137e222c420010d507200441d82f6a203220317c22164200201d20357c221d420010d507200441a8316a2010200e7c222742002029201e7c220e42137e221e420010d507200441f82b6a202220207c22224200202d202b7c221042137e221b420010d507200441f82d6a202320177c221742002021201f7c2220420010d507200441882e6a202042002016420010d507200441e82f6a202a4200201d42137e420010d50720044198326a20274200202c420010d507200441b8316a20224200201e420010d507200441882c6a20174200201b420010d507200441f8316a20164200200b420010d50720044198316a202a4200201e420010d507200441e82b6a20274200201b420010d507200441e82d6a202242002020420010d507200441c82f6a20174200201d420010d50720044188316a20164200200e420010d507200441882b6a202a4200201b420010d507200441d82d6a202742002020420010d507200441b82f6a20224200201d420010d507200441e8316a20174200200b420010d507200441a82a6a201642002010420010d507200441c82d6a202a42002020420010d507200441a82f6a20274200201d420010d507200441d8316a20224200200b420010d507200441f8306a20174200200e420010d507200441c82c6a20204200200a420010d50720044198286a20104200201a420010d507200441a8306a200e42002011420010d507200441a8276a200b4200200d420010d507200441d81f6a201d42002018420010d507200441e81f6a201842002020420010d507200441a8286a20104200202f420010d507200441e82e6a200e4200201a420010d507200441b8306a200b42002011420010d507200441b8276a201d4200200d420010d50720044188286a201042002011420010d507200441b82d6a20204200200f420010d50720044198276a200e4200200d420010d507200441c81f6a200b42002018420010d507200441b82c6a201d4200200a420010d50720044188276a20104200200d420010d507200441a82d6a202042002019420010d507200441b81f6a200e42002018420010d507200441a82c6a200b4200200a420010d507200441a82e6a201d4200200f420010d507200441e8266a20204200201c420010d507200441881f6a201042002018420010d507200441982c6a200e4200200a420010d507200441982e6a200b4200200f420010d507200441982f6a201d42002019420010d507200441c8226a20042903d823222e20042903f8267c221820042903d82c7c221d20042903b82e7c220b2004290388307c220d20042903c827222c2004290398307c22202004290388257c220a20042903e82c7c220e20042903c82e7c220f20042903c830222d20042903d82e7c221020042903d8277c221120042903b8267c221920042903f82c7c221a20042903f82e222f20042903882d7c221b20042903d8307c221c20042903e8277c221e20042903c8267c221f20042903982d223020042903d8267c222120042903882f7c222320042903e8307c222920042903f8277c222b423388200441982d6a41086a290300200441d8266a41086a2903007c2021203054ad7c200441882f6a41086a2903007c2023202154ad7c200441e8306a41086a2903007c2029202354ad7c200441f8276a41086a2903007c202b202954ad7c420d86847c2221423388200441f82e6a41086a290300200441882d6a41086a2903007c201b202f54ad7c200441d8306a41086a2903007c201c201b54ad7c200441e8276a41086a2903007c201e201c54ad7c200441c8266a41086a2903007c201f201e54ad7c2021201f54ad7c420d86847c221b423388200441c8306a41086a290300200441d82e6a41086a2903007c2010202d54ad7c200441d8276a41086a2903007c2011201054ad7c200441b8266a41086a2903007c2019201154ad7c200441f82c6a41086a2903007c201a201954ad7c201b201a54ad7c420d86847c2210423388200441c8276a41086a29030020044198306a41086a2903007c2020202c54ad7c20044188256a41086a2903007c200a202054ad7c200441e82c6a41086a2903007c200e200a54ad7c200441c82e6a41086a2903007c200f200e54ad7c2010200f54ad7c420d86847c220e42ffffffffffffff0383220a4200200429039831222f20042903f8317c220f20042903e82b7c221120042903e82d7c221920042903c82f7c221a200429038832223020042903d82f7c222020042903a8317c221c20042903f82b7c221e20042903f82d7c221f20042903e82f223120042903882e7c22232004290398327c222920042903b8317c222c20042903882c7c222d423388200441e82f6a41086a290300200441882e6a41086a2903007c2023203154ad7c20044198326a41086a2903007c2029202354ad7c200441b8316a41086a2903007c202c202954ad7c200441882c6a41086a2903007c202d202c54ad7c420d86847c222342338820044188326a41086a290300200441d82f6a41086a2903007c2020203054ad7c200441a8316a41086a2903007c201c202054ad7c200441f82b6a41086a2903007c201e201c54ad7c200441f82d6a41086a2903007c201f201e54ad7c2023201f54ad7c420d86847c221c42ffffffffffffff0383222042137e222c420010d507200441f8206a200e423388200441d8236a41086a290300200441f8266a41086a2903007c2018202e54ad7c200441d82c6a41086a2903007c201d201854ad7c200441b82e6a41086a2903007c200b201d54ad7c20044188306a41086a2903007c200d200b54ad7c200e200d54ad7c420d868442137e202b42ffffffffffffff03837c222e42ffffffffffffff0383220b420020042903c82d223020042903a82a7c221820042903a82f7c221d20042903d8317c220d20042903f8307c220e20042903882b22312004290388317c221e20042903d82d7c221f20042903b82f7c222920042903e8317c222b201c42338820044198316a41086a290300200441f8316a41086a2903007c200f202f54ad7c200441e82b6a41086a2903007c2011200f54ad7c200441e82d6a41086a2903007c2019201154ad7c200441c82f6a41086a2903007c201a201954ad7c201c201a54ad7c420d86847c220f423388200441882b6a41086a29030020044188316a41086a2903007c201e203154ad7c200441d82d6a41086a2903007c201f201e54ad7c200441b82f6a41086a2903007c2029201f54ad7c200441e8316a41086a2903007c202b202954ad7c200f202b54ad7c420d86847c2211423388200441c82d6a41086a290300200441a82a6a41086a2903007c2018203054ad7c200441a82f6a41086a2903007c201d201854ad7c200441d8316a41086a2903007c200d201d54ad7c200441f8306a41086a2903007c200e200d54ad7c2011200e54ad7c420d868442137e202d42ffffffffffffff03837c221d423388202342ffffffffffffff03837c2218420010d507200441f8236a201042ffffffffffffff0383220d4200200f42ffffffffffffff0383220e42137e221a420010d507200441a8256a201b42ffffffffffffff0383220f4200201142ffffffffffffff0383221142137e2219420010d50720044198226a202e423388202142ffffffffffffff03837c22104200201d42ffffffffffffff0383221d420010d507200441b8226a200a4200201842137e420010d50720044188216a201d4200200b420010d507200441e8236a200d4200202c420010d50720044198256a200f4200201a420010d507200441a8226a201042002019420010d507200441d8226a200a4200201a420010d507200441e8206a200b42002020420010d50720044188246a200d42002019420010d507200441b8256a200f4200201d420010d50720044188226a201042002018420010d507200441e8226a200a42002019420010d507200441d8206a200b4200200e420010d50720044198246a200d4200201d420010d507200441c8256a200f42002018420010d507200441f8216a201042002020420010d507200441f8226a200a4200201d420010d507200441c8206a200b42002011420010d507200441a8246a200d42002018420010d507200441d8256a200f42002020420010d507200441e8216a20104200200e420010d507200441981e6a201d20042903881f223620042903e8267c221920042903982c7c221a20042903982e7c221b20042903982f7c221c200429038827223720042903a82d7c221e20042903b81f7c221f20042903a82c7c222120042903a82e7c2223200429038828223820042903b82d7c22292004290398277c222b20042903c81f7c222c20042903b82c7c222d200429039828223920042903c82c7c222e20042903a8307c222f20042903a8277c223020042903d81f7c223120042903a828223a20042903e81f7c223220042903e82e7c223320042903b8307c223420042903b8277c2235423388200441a8286a41086a290300200441e81f6a41086a2903007c2032203a54ad7c200441e82e6a41086a2903007c2033203254ad7c200441b8306a41086a2903007c2034203354ad7c200441b8276a41086a2903007c2035203454ad7c420d86847c223242338820044198286a41086a290300200441c82c6a41086a2903007c202e203954ad7c200441a8306a41086a2903007c202f202e54ad7c200441a8276a41086a2903007c2030202f54ad7c200441d81f6a41086a2903007c2031203054ad7c2032203154ad7c420d86847c222e42338820044188286a41086a290300200441b82d6a41086a2903007c2029203854ad7c20044198276a41086a2903007c202b202954ad7c200441c81f6a41086a2903007c202c202b54ad7c200441b82c6a41086a2903007c202d202c54ad7c202e202d54ad7c420d86847c222942338820044188276a41086a290300200441a82d6a41086a2903007c201e203754ad7c200441b81f6a41086a2903007c201f201e54ad7c200441a82c6a41086a2903007c2021201f54ad7c200441a82e6a41086a2903007c2023202154ad7c2029202354ad7c420d86847c221e423388200441881f6a41086a290300200441e8266a41086a2903007c2019203654ad7c200441982c6a41086a2903007c201a201954ad7c200441982e6a41086a2903007c201b201a54ad7c200441982f6a41086a2903007c201c201b54ad7c201e201c54ad7c420d868442137e203542ffffffffffffff03837c221a42ffffffffffffff038322347c22194200201a423388203242ffffffffffffff03837c223520187d42f0ffffffffffff3f7c221c42ffffffffffffff03832034201d7d42d0fdffffffffff3f7c22214233887c221a420010d507200441c81d6a2011201e42ffffffffffffff038322367c221b4200202e42ffffffffffffff0383223720207d42f0ffffffffffff3f7c221e42ffffffffffffff0383201c4233887c222342137e222d420010d507200441981f6a200e202942ffffffffffffff038322387c221c42002038200e7d42f0ffffffffffff3f7c221f42ffffffffffffff0383201e4233887c222b42137e222c420010d507200441981d6a202020377c221e4200203620117d42f0ffffffffffff3f7c222e42ffffffffffffff0383201f4233887c222f42137e2229420010d507200441c81c6a201820357c221f4200202e42338842137e202142ffffffffffffff03837c2221420010d507200441d81c6a202142002019420010d507200441d81d6a201b4200201a42137e420010d507200441e81e6a201c4200202d420010d507200441a81f6a201e4200202c420010d507200441a81d6a201f42002029420010d507200441b81d6a201b4200202c420010d507200441b81e6a201942002023420010d507200441881d6a201c42002029420010d507200441b81c6a201e42002021420010d507200441881e6a201f4200201a420010d507200441f81c6a201b42002029420010d507200441a81e6a20194200202b420010d507200441d81b6a201c42002021420010d507200441f81d6a201e4200201a420010d507200441d81e6a201f42002023420010d507200441e81c6a20194200202f420010d507200441f81a6a201b42002021420010d507200441e81d6a201c4200201a420010d507200441c81e6a201e42002023420010d507200441f81e6a201f4200202b420010d507200420042903d822222e20042903e8207c22192004290388247c221a20042903b8257c221b2004290388227c221c20042903c822222f20042903f8207c221e20042903f8237c221f20042903a8257c22212004290398227c222320042903b82222302004290388217c222920042903e8237c222b2004290398257c222c20042903a8227c222d423388200441b8226a41086a29030020044188216a41086a2903007c2029203054ad7c200441e8236a41086a2903007c202b202954ad7c20044198256a41086a2903007c202c202b54ad7c200441a8226a41086a2903007c202d202c54ad7c420d86847c2229423388200441c8226a41086a290300200441f8206a41086a2903007c201e202f54ad7c200441f8236a41086a2903007c201f201e54ad7c200441a8256a41086a2903007c2021201f54ad7c20044198226a41086a2903007c2023202154ad7c2029202354ad7c420d86847c221e42ffffffffffffff03833703984a200420042903e822222c20042903d8207c221f2004290398247c222120042903c8257c222320042903f8217c222b201e423388200441d8226a41086a290300200441e8206a41086a2903007c2019202e54ad7c20044188246a41086a2903007c201a201954ad7c200441b8256a41086a2903007c201b201a54ad7c20044188226a41086a2903007c201c201b54ad7c201e201c54ad7c420d86847c221942ffffffffffffff03833703a04a200420042903f822222e20042903c8207c221a20042903a8247c221b20042903d8257c221c20042903e8217c221e2019423388200441e8226a41086a290300200441d8206a41086a2903007c201f202c54ad7c20044198246a41086a2903007c2021201f54ad7c200441c8256a41086a2903007c2023202154ad7c200441f8216a41086a2903007c202b202354ad7c2019202b54ad7c420d86847c221942ffffffffffffff03833703a84a20042019423388200441f8226a41086a290300200441c8206a41086a2903007c201a202e54ad7c200441a8246a41086a2903007c201b201a54ad7c200441d8256a41086a2903007c201c201b54ad7c200441e8216a41086a2903007c201e201c54ad7c2019201e54ad7c420d868442137e202d42ffffffffffffff03837c221942ffffffffffffff03833703884a20042019423388202942ffffffffffffff03837c3703904a200441981e6a41086a290300213b200441c81d6a41086a290300213c20042903981e213320042903c81d2119200441981f6a41086a290300213d20042903981f2139200441981d6a41086a290300213e20042903981d213a200441c81c6a41086a290300213f20042903c81c2140200441d81c6a41086a2903002141200441d81d6a41086a290300214220042903d81c214320042903d81d211a200441e81e6a41086a290300214420042903e81e2145200441a81f6a41086a290300214620042903a81f2147200441a81d6a41086a290300214820042903a81d214920042903b81d211b20042903b81e212f20042903881d213020042903b81c213120042903881e2132200441b81d6a41086a290300214a200441b81e6a41086a290300214b200441881d6a41086a290300214c200441b81c6a41086a290300214d200441881e6a41086a290300214e20042903f81c211c20042903a81e212b20042903d81b212c20042903f81d212d20042903d81e212e200441f81c6a41086a290300214f200441a81e6a41086a2903002150200441d81b6a41086a2903002151200441f81d6a41086a2903002152200441d81e6a41086a290300215320042903e81c211f20042903f81a211e20042903e81d212120042903c81e212320042903f81e2129200441e81c6a41086a2903002154200441f81a6a41086a2903002155200441e81d6a41086a2903002156200441c81e6a41086a2903002157200441f81e6a41086a2903002158200441d8ca006a20044188ca006a4101106b200441b8196a202920232021201e201f7c221f7c22217c22237c2229202e202d202c201c202b7c222b7c222c7c222d7c222e203220312030201b202f7c222f7c22307c22317c22322040203a2039201920337c22337c22397c223a7c2240204920472045201a20437c22437c22457c22477c2249423388204820462044204220417c2043201a54ad7c7c2045204354ad7c7c2047204554ad7c7c2049204754ad7c420d86847c221a423388203f203e203d203c203b7c2033201954ad7c7c2039203354ad7c7c203a203954ad7c7c2040203a54ad7c201a204054ad7c420d86847c2233423388204e204d204c204a204b7c202f201b54ad7c7c2030202f54ad7c7c2031203054ad7c7c2032203154ad7c2033203254ad7c420d86847c222f423388205320522051204f20507c202b201c54ad7c7c202c202b54ad7c7c202d202c54ad7c7c202e202d54ad7c202f202e54ad7c420d86847c221c423388205820572056205520547c201f201e54ad7c7c2021201f54ad7c7c2023202154ad7c7c2029202354ad7c201c202954ad7c420d868442137e204942ffffffffffffff03837c222d42ffffffffffffff03832219420020042903e04a221b420010d507200441b81a6a201c42ffffffffffffff0383222b420020042903e84a221e42137e222e420010d507200441981b6a202f42ffffffffffffff03832229420020042903f04a222142137e222c420010d507200441f81b6a203342ffffffffffffff03832223420020042903f84a222f42137e221f420010d507200441881a6a202d423388201a42ffffffffffffff03837c221a420020042903d84a221c420010d507200441c8196a201c42002019420010d507200441a81a6a202b4200201b42137e420010d507200441881b6a20294200202e420010d507200441e81b6a20234200202c420010d507200441981a6a201a4200201f420010d507200441a8196a20194200201e420010d507200441c81a6a202b4200202c420010d507200441a81b6a20294200201f420010d507200441881c6a20234200201c420010d507200441f8196a201a4200201b420010d50720044198196a201942002021420010d507200441d81a6a202b4200201f420010d507200441b81b6a20294200201c420010d507200441981c6a20234200201b420010d507200441e8196a201a4200201e420010d50720044188196a20194200202f420010d507200441e81a6a202b4200201c420010d507200441c81b6a20294200201b420010d507200441a81c6a20234200201e420010d507200441d8196a201a42002021420010d507200420042903c81a223320042903a8197c221b20042903a81b7c221c20042903881c7c221e20042903f8197c221f20042903b81a223920042903b8197c222120042903981b7c222c20042903f81b7c222d20042903881a7c222e20042903a81a223a20042903c8197c222f20042903881b7c223020042903e81b7c223120042903981a7c2232423388200441a81a6a41086a290300200441c8196a41086a2903007c202f203a54ad7c200441881b6a41086a2903007c2030202f54ad7c200441e81b6a41086a2903007c2031203054ad7c200441981a6a41086a2903007c2032203154ad7c420d86847c222f423388200441b81a6a41086a290300200441b8196a41086a2903007c2021203954ad7c200441981b6a41086a2903007c202c202154ad7c200441f81b6a41086a2903007c202d202c54ad7c200441881a6a41086a2903007c202e202d54ad7c202f202e54ad7c420d86847c222142ffffffffffffff03833703c04a200420042903d81a22312004290398197c222c20042903b81b7c222d20042903981c7c222e20042903e8197c22302021423388200441c81a6a41086a290300200441a8196a41086a2903007c201b203354ad7c200441a81b6a41086a2903007c201c201b54ad7c200441881c6a41086a2903007c201e201c54ad7c200441f8196a41086a2903007c201f201e54ad7c2021201f54ad7c420d86847c221b42ffffffffffffff03833703c84a200420042903e81a22332004290388197c221c20042903c81b7c221e20042903a81c7c221f20042903d8197c2221201b423388200441d81a6a41086a29030020044198196a41086a2903007c202c203154ad7c200441b81b6a41086a2903007c202d202c54ad7c200441981c6a41086a2903007c202e202d54ad7c200441e8196a41086a2903007c2030202e54ad7c201b203054ad7c420d86847c221b42ffffffffffffff03833703d04a2004201b423388200441e81a6a41086a29030020044188196a41086a2903007c201c203354ad7c200441c81b6a41086a2903007c201e201c54ad7c200441a81c6a41086a2903007c201f201e54ad7c200441d8196a41086a2903007c2021201f54ad7c201b202154ad7c420d868442137e203242ffffffffffffff03837c221b42ffffffffffffff03833703b04a2004201b423388202f42ffffffffffffff03837c3703b84a200441e8c8006a41106a22054200370300200441e8c8006a41186a22064200370300200441e8c8006a41206a22594200370300200442003703f048200442013703e848200441d8c6006a200441e8c8006a200441b0ca006a106c200441a8116a20042903e046221b420020042903904a222c420010d507200441b8146a200441d8c6006a41286a225a290300221c420020042903984a222e42137e2232420010d507200441d8156a200441d8c6006a41206a225b290300221e420020042903a04a223042137e2231420010d507200441f8166a200441d8c6006a41186a225c290300221f420020042903a84a223342137e222f420010d50720044198186a200441d8c6006a41106a225d2903002221420020042903884a222d420010d507200441b8116a202d4200201b420010d507200441c8146a201c4200202c42137e420010d507200441e8156a201e42002032420010d50720044188176a201f42002031420010d507200441a8186a20214200202f420010d50720044198116a201b4200202e420010d507200441a8146a201c42002031420010d507200441c8156a201e4200202f420010d507200441e8166a201f4200202d420010d50720044188186a20214200202c420010d507200441b8106a201b42002030420010d50720044198146a201c4200202f420010d507200441b8156a201e4200202d420010d507200441d8166a201f4200202c420010d507200441f8176a20214200202e420010d507200441d80f6a201b42002033420010d50720044188146a201c4200202d420010d507200441a8156a201e4200202c420010d507200441c8166a201f4200202e420010d507200441e8176a202142002030420010d507200441b83c6a20124200202242137e222e420010d507200441e83b6a200c42002017420010d507200441b83e6a20134200202742137e222d420010d507200441e83c6a20144200202a42137e222c420010d507200441b83d6a201542002016420010d507200441c83c6a20124200201742137e420010d507200441f83b6a20164200200c420010d507200441c83e6a20134200202e420010d507200441883e6a20144200202d420010d507200441f83c6a20154200202c420010d507200441a83c6a20124200202d420010d507200441d83b6a200c42002022420010d507200441d83c6a20134200202c420010d507200441d83d6a201442002016420010d507200441a83d6a201542002017420010d507200441983c6a20124200202c420010d507200441c83b6a200c42002027420010d507200441c83d6a201342002016420010d507200441f83d6a201442002017420010d507200441983d6a201542002022420010d507200441883c6a201242002016420010d507200441b83b6a200c4200202a420010d507200441983e6a201342002017420010d507200441e83d6a201442002022420010d507200441883d6a201542002027420010d507200441e8136a201b4200201a420010d50720044188156a201c4200202342137e2213420010d507200441a8166a201e4200202942137e2212420010d507200441c8176a201f4200202b42137e220c420010d507200441e8186a202142002019420010d507200441f8136a20194200201b420010d50720044198156a201c4200201a42137e420010d507200441b8166a201e42002013420010d507200441d8176a201f42002012420010d507200441f8186a20214200200c420010d507200441d8136a201b42002023420010d507200441f8146a201c42002012420010d50720044198166a201e4200200c420010d507200441b8176a201f42002019420010d507200441d8186a20214200201a420010d507200441f8126a201b42002029420010d507200441e8146a201c4200200c420010d50720044188166a201e42002019420010d507200441a8176a201f4200201a420010d507200441c8186a202142002023420010d50720044198126a201b4200202b420010d507200441d8146a201c42002019420010d507200441f8156a201e4200201a420010d50720044198176a201f42002023420010d507200441b8186a202142002029420010d507200441980f6a200429038814222e20042903d80f7c220c20042903a8157c221220042903c8167c221320042903e8177c2214200429039814222c20042903b8107c221520042903b8157c221620042903d8167c221720042903f8177c221920042903a814222d2004290398117c221a20042903c8157c221b20042903e8167c221c2004290388187c221e20042903b814222f20042903a8117c221f20042903d8157c222120042903f8167c22222004290398187c222320042903c814223020042903b8117c222720042903e8157c22292004290388177c222a20042903a8187c222b423388200441c8146a41086a290300200441b8116a41086a2903007c2027203054ad7c200441e8156a41086a2903007c2029202754ad7c20044188176a41086a2903007c202a202954ad7c200441a8186a41086a2903007c202b202a54ad7c420d86847c222a423388200441b8146a41086a290300200441a8116a41086a2903007c201f202f54ad7c200441d8156a41086a2903007c2021201f54ad7c200441f8166a41086a2903007c2022202154ad7c20044198186a41086a2903007c2023202254ad7c202a202354ad7c420d86847c221f423388200441a8146a41086a29030020044198116a41086a2903007c201a202d54ad7c200441c8156a41086a2903007c201b201a54ad7c200441e8166a41086a2903007c201c201b54ad7c20044188186a41086a2903007c201e201c54ad7c201f201e54ad7c420d86847c221a42338820044198146a41086a290300200441b8106a41086a2903007c2015202c54ad7c200441b8156a41086a2903007c2016201554ad7c200441d8166a41086a2903007c2017201654ad7c200441f8176a41086a2903007c2019201754ad7c201a201954ad7c420d86847c221542ffffffffffffff03832222420020042903a83c222f20042903d83b7c221620042903d83c7c221720042903d83d7c221920042903a83d7c221c20042903b83c223020042903e83b7c221b20042903b83e7c221e20042903e83c7c222120042903b83d7c222320042903c83c223120042903f83b7c222720042903c83e7c222920042903883e7c222c20042903f83c7c222d423388200441c83c6a41086a290300200441f83b6a41086a2903007c2027203154ad7c200441c83e6a41086a2903007c2029202754ad7c200441883e6a41086a2903007c202c202954ad7c200441f83c6a41086a2903007c202d202c54ad7c420d86847c2227423388200441b83c6a41086a290300200441e83b6a41086a2903007c201b203054ad7c200441b83e6a41086a2903007c201e201b54ad7c200441e83c6a41086a2903007c2021201e54ad7c200441b83d6a41086a2903007c2023202154ad7c2027202354ad7c420d86847c221e42ffffffffffffff0383221b42137e222c420010d507200441f80c6a201542338820044188146a41086a290300200441d80f6a41086a2903007c200c202e54ad7c200441a8156a41086a2903007c2012200c54ad7c200441c8166a41086a2903007c2013201254ad7c200441e8176a41086a2903007c2014201354ad7c2015201454ad7c420d868442137e202b42ffffffffffffff03837c222e42ffffffffffffff03832223420020042903883c223020042903b83b7c220c20042903983e7c221220042903e83d7c221320042903883d7c221420042903983c223120042903c83b7c221520042903c83d7c222120042903f83d7c222920042903983d7c222b201e423388200441a83c6a41086a290300200441d83b6a41086a2903007c2016202f54ad7c200441d83c6a41086a2903007c2017201654ad7c200441d83d6a41086a2903007c2019201754ad7c200441a83d6a41086a2903007c201c201954ad7c201e201c54ad7c420d86847c2216423388200441983c6a41086a290300200441c83b6a41086a2903007c2015203154ad7c200441c83d6a41086a2903007c2021201554ad7c200441f83d6a41086a2903007c2029202154ad7c200441983d6a41086a2903007c202b202954ad7c2016202b54ad7c420d86847c2215423388200441883c6a41086a290300200441b83b6a41086a2903007c200c203054ad7c200441983e6a41086a2903007c2012200c54ad7c200441e83d6a41086a2903007c2013201254ad7c200441883d6a41086a2903007c2014201354ad7c2015201454ad7c420d868442137e202d42ffffffffffffff03837c2213423388202742ffffffffffffff03837c2212420010d507200441f80f6a201a42ffffffffffffff038322274200201642ffffffffffffff0383221e42137e2214420010d507200441d8106a201f42ffffffffffffff038322294200201542ffffffffffffff0383222142137e220c420010d507200441c80d6a202e423388202a42ffffffffffffff03837c222a4200201342ffffffffffffff03832213420010d507200441880f6a20224200201242137e420010d507200441880d6a201342002023420010d507200441e80f6a20274200202c420010d507200441c8106a202942002014420010d507200441d80d6a202a4200200c420010d507200441a80f6a202242002014420010d507200441e80c6a20234200201b420010d50720044188106a20274200200c420010d507200441e8106a202942002013420010d507200441b80d6a202a42002012420010d507200441b80f6a20224200200c420010d507200441a80c6a20234200201e420010d50720044198106a202742002013420010d507200441f8106a202942002012420010d507200441a80d6a202a4200201b420010d507200441c80f6a202242002013420010d507200441f80b6a202342002021420010d507200441a8106a202742002012420010d50720044188116a20294200201b420010d507200441980d6a202a4200201e420010d507200441d80a6a20042903d81422452004290398127c220c20042903f8157c22152004290398177c221620042903b8187c221720042903e814224020042903f8127c22142004290388167c221920042903a8177c221a20042903c8187c221c20042903f814224320042903d8137c221f2004290398167c222b20042903b8177c222c20042903d8187c222d200429038815224720042903e8137c222e20042903a8167c222f20042903c8177c223020042903e8187c2231200429039815224920042903f8137c223220042903b8167c223320042903d8177c223920042903f8187c223a42338820044198156a41086a290300200441f8136a41086a2903007c2032204954ad7c200441b8166a41086a2903007c2033203254ad7c200441d8176a41086a2903007c2039203354ad7c200441f8186a41086a2903007c203a203954ad7c420d86847c223242338820044188156a41086a290300200441e8136a41086a2903007c202e204754ad7c200441a8166a41086a2903007c202f202e54ad7c200441c8176a41086a2903007c2030202f54ad7c200441e8186a41086a2903007c2031203054ad7c2032203154ad7c420d86847c222e423388200441f8146a41086a290300200441d8136a41086a2903007c201f204354ad7c20044198166a41086a2903007c202b201f54ad7c200441b8176a41086a2903007c202c202b54ad7c200441d8186a41086a2903007c202d202c54ad7c202e202d54ad7c420d86847c221f423388200441e8146a41086a290300200441f8126a41086a2903007c2014204054ad7c20044188166a41086a2903007c2019201454ad7c200441a8176a41086a2903007c201a201954ad7c200441c8186a41086a2903007c201c201a54ad7c201f201c54ad7c420d86847c221942ffffffffffffff03832214420020042903a80f224720042903e80c7c221a2004290388107c222b20042903e8107c222c20042903b80d7c222d20042903980f224920042903f80c7c221c20042903f80f7c222f20042903d8107c223020042903c80d7c223120042903880f223b20042903880d7c223320042903e80f7c223920042903c8107c224020042903d80d7c2243423388200441880f6a41086a290300200441880d6a41086a2903007c2033203b54ad7c200441e80f6a41086a2903007c2039203354ad7c200441c8106a41086a2903007c2040203954ad7c200441d80d6a41086a2903007c2043204054ad7c420d86847c2233423388200441980f6a41086a290300200441f80c6a41086a2903007c201c204954ad7c200441f80f6a41086a2903007c202f201c54ad7c200441d8106a41086a2903007c2030202f54ad7c200441c80d6a41086a2903007c2031203054ad7c2033203154ad7c420d86847c222f42ffffffffffffff0383221c42137e2240420010d507200441b80a6a2019423388200441d8146a41086a29030020044198126a41086a2903007c200c204554ad7c200441f8156a41086a2903007c2015200c54ad7c20044198176a41086a2903007c2016201554ad7c200441b8186a41086a2903007c2017201654ad7c2019201754ad7c420d868442137e203a42ffffffffffffff03837c224542ffffffffffffff03832215420020042903c80f224920042903f80b7c220c20042903a8107c22162004290388117c221720042903980d7c221920042903b80f223b20042903a80c7c22302004290398107c223120042903f8107c223920042903a80d7c223a202f423388200441a80f6a41086a290300200441e80c6a41086a2903007c201a204754ad7c20044188106a41086a2903007c202b201a54ad7c200441e8106a41086a2903007c202c202b54ad7c200441b80d6a41086a2903007c202d202c54ad7c202f202d54ad7c420d86847c221a423388200441b80f6a41086a290300200441a80c6a41086a2903007c2030203b54ad7c20044198106a41086a2903007c2031203054ad7c200441f8106a41086a2903007c2039203154ad7c200441a80d6a41086a2903007c203a203954ad7c201a203a54ad7c420d86847c222b423388200441c80f6a41086a290300200441f80b6a41086a2903007c200c204954ad7c200441a8106a41086a2903007c2016200c54ad7c20044188116a41086a2903007c2017201654ad7c200441980d6a41086a2903007c2019201754ad7c202b201954ad7c420d868442137e204342ffffffffffffff03837c222f423388203342ffffffffffffff03837c220c420010d507200441880b6a201f42ffffffffffffff038322164200201a42ffffffffffffff0383222c42137e222d420010d507200441c80b6a202e42ffffffffffffff038322174200202b42ffffffffffffff0383222b42137e221f420010d507200441e8096a2045423388203242ffffffffffffff03837c22194200202f42ffffffffffffff0383221a420010d507200441f8096a201a42002015420010d507200441c80a6a20144200200c42137e420010d507200441e80a6a201642002040420010d507200441980b6a20174200202d420010d507200441d80b6a20194200201f420010d507200441b80c6a20154200201c420010d507200441f80a6a20144200202d420010d507200441b80b6a20164200201f420010d507200441d8096a20174200201a420010d507200441a80a6a20194200200c420010d507200441880c6a20154200202c420010d507200441a80b6a20144200201f420010d507200441f8086a20164200201a420010d507200441980a6a20174200200c420010d507200441c80c6a20194200201c420010d507200441e80b6a20154200202b420010d50720044198086a20144200201a420010d507200441880a6a20164200200c420010d507200441d80c6a20174200201c420010d507200441980c6a20194200202c420010d50720044188096a2021420020042903f80a224520042903b80c7c220c20042903b80b7c221a20042903d8097c221c20042903a80a7c221f20042903d80a223320042903b80a7c222b20042903880b7c222c20042903c80b7c222d20042903e8097c222e20042903c80a223920042903f8097c222f20042903e80a7c223020042903980b7c223120042903d80b7c2232423388200441c80a6a41086a290300200441f8096a41086a2903007c202f203954ad7c200441e80a6a41086a2903007c2030202f54ad7c200441980b6a41086a2903007c2031203054ad7c200441d80b6a41086a2903007c2032203154ad7c420d86847c222f423388200441d80a6a41086a290300200441b80a6a41086a2903007c202b203354ad7c200441880b6a41086a2903007c202c202b54ad7c200441c80b6a41086a2903007c202d202c54ad7c200441e8096a41086a2903007c202e202d54ad7c202f202e54ad7c420d86847c222c42ffffffffffffff0383222b42137e2233420010d507200441e8076a20134200200429039808224720042903e80b7c222d20042903880a7c222e20042903d80c7c223020042903980c7c223120042903a80b224920042903880c7c223920042903f8087c223a20042903980a7c224020042903c80c7c2243202c423388200441f80a6a41086a290300200441b80c6a41086a2903007c200c204554ad7c200441b80b6a41086a2903007c201a200c54ad7c200441d8096a41086a2903007c201c201a54ad7c200441a80a6a41086a2903007c201f201c54ad7c202c201f54ad7c420d86847c220c423388200441a80b6a41086a290300200441880c6a41086a2903007c2039204954ad7c200441f8086a41086a2903007c203a203954ad7c200441980a6a41086a2903007c2040203a54ad7c200441c80c6a41086a2903007c2043204054ad7c200c204354ad7c420d86847c221a42338820044198086a41086a290300200441e80b6a41086a2903007c202d204754ad7c200441880a6a41086a2903007c202e202d54ad7c200441d80c6a41086a2903007c2030202e54ad7c200441980c6a41086a2903007c2031203054ad7c201a203154ad7c420d868442137e203242ffffffffffffff03837c222e423388202f42ffffffffffffff03837c221c420010d507200441b8086a201e4200200c42ffffffffffffff0383222d42137e222c420010d507200441c8066a201b4200201a42ffffffffffffff0383223942137e221f420010d50720044198076a20124200202e42ffffffffffffff0383221a420010d507200441a8076a201a42002013420010d507200441f8076a20214200201c42137e224d420010d50720044198096a201e42002033420010d507200441c8086a201b4200202c420010d507200441d8066a20124200201f420010d507200441a8096a20134200202b420010d507200441a8086a20214200202c420010d507200441b8066a201e4200201f420010d50720044188076a201b4200201a420010d507200441d8076a20124200201c420010d507200441d8086a20134200202d420010d507200441a8066a20214200201f420010d507200441f8066a201e4200201a420010d507200441c8076a201b4200201c420010d507200441b8096a20124200202b420010d50720044188086a201342002039420010d507200441e8066a20214200201a420010d507200441b8076a201e4200201c420010d507200441c8096a201b4200202b420010d507200441e8086a20124200202d420010d507200441e8296a2011420042a0d69f90da80b1cb00420010d507200441e8286a201d4200429db1bce4dfb435420010d507200441c82a6a200e420042badf96dcb5c3bac700420010d507200441a82b6a2020420042a7ecfac2b5f7ea19420010d507200441b8296a2018420042b0c1bad0f4e48603420010d507200441d8296a2011420042a7a7fbf49beaf607420010d507200441f8286a201d420042b0c1bad0f4e48603420010d507200441b82a6a200e420042a0d69f90da80b1cb00420010d507200441982b6a2020420042badf96dcb5c3bac700420010d507200441c8296a2018420042a7ecfac2b5f7ea19420010d507200441f8296a2011420042badf96dcb5c3bac700420010d507200441d8286a201d420042e098f4e5e9ebfb03420010d507200441d82a6a200e420042a7ecfac2b5f7ea19420010d507200441b82b6a2020420042b0c1bad0f4e48603420010d507200441a8296a20184200429db1bce4dfb435420010d507200441882a6a2011420042a7ecfac2b5f7ea19420010d507200441c8286a201d4200429e9981b4dab2e103420010d507200441e82a6a200e420042b0c1bad0f4e48603420010d507200441c82b6a20204200429db1bce4dfb435420010d50720044198296a2018420042e098f4e5e9ebfb03420010d507200441982a6a2011420042b0c1bad0f4e48603420010d507200441b8286a201d4200429df893c0a486ae01420010d507200441f82a6a200e4200429db1bce4dfb435420010d507200441d82b6a2020420042e098f4e5e9ebfb03420010d50720044188296a20184200429e9981b4dab2e103420010d507200420042903a808223b20042903a8097c220c20042903b8067c222e2004290388077c222f20042903d8077c2230200429038809223c20042903e8077c223120042903b8087c223220042903c8067c223a2004290398077c224020042903f807223d20042903a8077c22432004290398097c224520042903c8087c224720042903d8067c2249423388200441f8076a41086a290300200441a8076a41086a2903007c2043203d54ad7c20044198096a41086a2903007c2045204354ad7c200441c8086a41086a2903007c2047204554ad7c200441d8066a41086a2903007c2049204754ad7c420d86847c224342338820044188096a41086a290300200441e8076a41086a2903007c2031203c54ad7c200441b8086a41086a2903007c2032203154ad7c200441c8066a41086a2903007c203a203254ad7c20044198076a41086a2903007c2040203a54ad7c2043204054ad7c420d86847c223142ffffffffffffff03833703e846200420042903a806224720042903d8087c223220042903f8067c223a20042903c8077c224020042903b8097c22452031423388200441a8086a41086a290300200441a8096a41086a2903007c200c203b54ad7c200441b8066a41086a2903007c202e200c54ad7c20044188076a41086a2903007c202f202e54ad7c200441d8076a41086a2903007c2030202f54ad7c2031203054ad7c420d86847c220c42ffffffffffffff03833703f046200420042903e806223b2004290388087c222e20042903b8077c222f20042903c8097c223020042903e8087c2231200c423388200441a8066a41086a290300200441d8086a41086a2903007c2032204754ad7c200441f8066a41086a2903007c203a203254ad7c200441c8076a41086a2903007c2040203a54ad7c200441b8096a41086a2903007c2045204054ad7c200c204554ad7c420d86847c220c42ffffffffffffff03833703f8462004200c423388200441e8066a41086a29030020044188086a41086a2903007c202e203b54ad7c200441b8076a41086a2903007c202f202e54ad7c200441c8096a41086a2903007c2030202f54ad7c200441e8086a41086a2903007c2031203054ad7c200c203154ad7c420d868442137e204942ffffffffffffff03837c220c42ffffffffffffff03833703d8462004200c423388204342ffffffffffffff03837c3703e046200441e8296a41086a290300214e200441e8286a41086a290300214f20042903e829210c20042903e8282141200441c82a6a41086a290300215020042903c82a2142200441a82b6a41086a290300215120042903a82b2144200441b8296a41086a290300215220042903b8292146200441d8296a41086a2903002153200441f8286a41086a290300215420042903d829212e20042903f8282148200441b82a6a41086a290300215520042903b82a214a200441982b6a41086a290300215620042903982b214b200441c8296a41086a290300215720042903c829214c20042903f829212f20042903d828213c20042903d82a213d20042903b82b213e20042903a829213f200441f8296a41086a2903002158200441d8286a41086a290300215e200441d82a6a41086a290300215f200441b82b6a41086a2903002160200441a8296a41086a290300216120042903882a213020042903c828214520042903e82a214720042903c82b2149200429039829213b200441882a6a41086a2903002162200441c8286a41086a2903002163200441e82a6a41086a2903002164200441c82b6a41086a290300216520044198296a41086a290300216620042903982a213120042903b828213220042903f82a213a20042903d82b21402004290388292143200441982a6a41086a2903002167200441b8286a41086a2903002168200441f82a6a41086a2903002169200441d82b6a41086a290300216a20044188296a41086a290300216b200441b0ca006a200441d8c6006a106a20044188066a200b20432040203a203120327c22327c223a7c22407c2243203b20492047203020457c22457c22477c22497c223b203f203e203d202f203c7c223c7c223d7c223e7c223f204620442042200c20417c22417c22427c22447c2246204c204b204a202e20487c22487c224a7c224b7c224c423388205720562055205320547c2048202e54ad7c7c204a204854ad7c7c204b204a54ad7c7c204c204b54ad7c420d86847c2248423388205220512050204e204f7c2041200c54ad7c7c2042204154ad7c7c2044204254ad7c7c2046204454ad7c2048204654ad7c420d86847c224142338820612060205f2058205e7c203c202f54ad7c7c203d203c54ad7c7c203e203d54ad7c7c203f203e54ad7c2041203f54ad7c420d86847c223c423388206620652064206220637c2045203054ad7c7c2047204554ad7c7c2049204754ad7c7c203b204954ad7c203c203b54ad7c420d86847c222f423388206b206a2069206720687c2032203154ad7c7c203a203254ad7c7c2040203a54ad7c7c2043204054ad7c202f204354ad7c420d868442137e204c42ffffffffffffff03837c223242ffffffffffffff038385420020042d00b04a410171106dad42ff01837d220c83200b85222e4200201c420010d507200441c8036a200a202f42ffffffffffffff038385200c83200a85222f42002033420010d50720044198046a200d203c42ffffffffffffff038385200c83200d8522304200202c420010d507200441e8046a200f204142ffffffffffffff038385200c83200f8522314200201f420010d507200441b8056a20102032423388204842ffffffffffffff03837c85200c8320108522324200201a420010d50720044198066a201a4200202e420010d507200441d8036a202f4200204d420010d507200441a8046a203042002033420010d507200441f8046a20314200202c420010d507200441c8056a20324200201f420010d507200441f8056a202e4200202b420010d507200441b8036a202f4200202c420010d50720044188046a20304200201f420010d507200441d8046a20314200201a420010d507200441a8056a20324200201c420010d507200441e8056a202e4200202d420010d507200441a8036a202f4200201f420010d507200441f8036a20304200201a420010d507200441c8046a20314200201c420010d50720044198056a20324200202b420010d507200441d8056a202e42002039420010d50720044198036a202f4200201a420010d507200441e8036a20304200201c420010d507200441b8046a20314200202b420010d50720044188056a20324200202d420010d50720044198236a200a420042a0d69f90da80b1cb00420010d507200441a8206a200b4200429db1bce4dfb435420010d507200441c8246a200d420042badf96dcb5c3bac700420010d507200441f8256a200f420042a7ecfac2b5f7ea19420010d507200441c8216a2010420042b0c1bad0f4e48603420010d50720044188236a200a420042a7a7fbf49beaf607420010d507200441b8206a200b420042b0c1bad0f4e48603420010d507200441b8246a200d420042a0d69f90da80b1cb00420010d507200441e8256a200f420042badf96dcb5c3bac700420010d507200441d8216a2010420042a7ecfac2b5f7ea19420010d507200441a8236a200a420042badf96dcb5c3bac700420010d50720044198206a200b420042e098f4e5e9ebfb03420010d507200441d8246a200d420042a7ecfac2b5f7ea19420010d50720044188266a200f420042b0c1bad0f4e48603420010d507200441b8216a20104200429db1bce4dfb435420010d507200441b8236a200a420042a7ecfac2b5f7ea19420010d50720044188206a200b4200429e9981b4dab2e103420010d507200441e8246a200d420042b0c1bad0f4e48603420010d50720044198266a200f4200429db1bce4dfb435420010d507200441a8216a2010420042e098f4e5e9ebfb03420010d507200441c8236a200a420042b0c1bad0f4e48603420010d507200441f81f6a200b4200429df893c0a486ae01420010d507200441f8246a200d4200429db1bce4dfb435420010d507200441a8266a200f420042e098f4e5e9ebfb03420010d50720044198216a20104200429e9981b4dab2e103420010d507200441f8116a201442004288f5a7f5b28623420010d507200441980e6a2015420042b9a6dff282e9ba01420010d507200441d8126a2016420042edd5d7bc83fb803c420010d507200441b8136a2017420042edc19ab7ab9cc0c700420010d507200441e80e6a2019420042ea81f582a8b53f420010d50720044188126a2014420042bbda9284b7cbdd1b420010d507200441a80e6a2015420042ea81f582a8b53f420010d507200441e8126a201642004288f5a7f5b28623420010d507200441c8136a2017420042edd5d7bc83fb803c420010d507200441f80e6a2019420042edc19ab7ab9cc0c700420010d507200441e8116a2014420042edd5d7bc83fb803c420010d507200441880e6a2015420042d8f8d29390ec01420010d507200441c8126a2016420042edc19ab7ab9cc0c700420010d507200441a8136a2017420042ea81f582a8b53f420010d507200441d80e6a2019420042b9a6dff282e9ba01420010d507200441d8116a2014420042edc19ab7ab9cc0c700420010d507200441f80d6a2015420042ff91f789b6a19403420010d507200441b8126a2016420042ea81f582a8b53f420010d50720044198136a2017420042b9a6dff282e9ba01420010d507200441c80e6a2019420042d8f8d29390ec01420010d507200441c8116a2014420042ea81f582a8b53f420010d507200441e80d6a2015420042fff5f38289d9e103420010d507200441a8126a2016420042b9a6dff282e9ba01420010d50720044188136a2017420042d8f8d29390ec01420010d507200441b80e6a2019420042ff91f789b6a19403420010d507200420042903b803222f20042903f8057c22142004290388047c221520042903d8047c221620042903a8057c221720042903c80322302004290388067c22192004290398047c221a20042903e8047c221c20042903b8057c221f20042903d80322312004290398067c222b20042903a8047c222c20042903f8047c222d20042903c8057c222e423388200441d8036a41086a29030020044198066a41086a2903007c202b203154ad7c200441a8046a41086a2903007c202c202b54ad7c200441f8046a41086a2903007c202d202c54ad7c200441c8056a41086a2903007c202e202d54ad7c420d86847c222b423388200441c8036a41086a29030020044188066a41086a2903007c2019203054ad7c20044198046a41086a2903007c201a201954ad7c200441e8046a41086a2903007c201c201a54ad7c200441b8056a41086a2903007c201f201c54ad7c202b201f54ad7c420d86847c221942ffffffffffffff03833703e846200420042903a803222d20042903e8057c221a20042903f8037c221c20042903c8047c221f2004290398057c222c2019423388200441b8036a41086a290300200441f8056a41086a2903007c2014202f54ad7c20044188046a41086a2903007c2015201454ad7c200441d8046a41086a2903007c2016201554ad7c200441a8056a41086a2903007c2017201654ad7c2019201754ad7c420d86847c221442ffffffffffffff03833703f0462004200429039803222f20042903d8057c221520042903e8037c221620042903b8047c22172004290388057c22192014423388200441a8036a41086a290300200441e8056a41086a2903007c201a202d54ad7c200441f8036a41086a2903007c201c201a54ad7c200441c8046a41086a2903007c201f201c54ad7c20044198056a41086a2903007c202c201f54ad7c2014202c54ad7c420d86847c221442ffffffffffffff03833703f8462004201442338820044198036a41086a290300200441d8056a41086a2903007c2015202f54ad7c200441e8036a41086a2903007c2016201554ad7c200441b8046a41086a2903007c2017201654ad7c20044188056a41086a2903007c2019201754ad7c2014201954ad7c420d868442137e202e42ffffffffffffff03837c221442ffffffffffffff03833703d84620042014423388202b42ffffffffffffff03837c3703e04620044198236a41086a2903002141200441a8206a41086a2903002142200429039823211520042903a820213c200441c8246a41086a290300214420042903c824213d200441f8256a41086a290300214620042903f825213e200441c8216a41086a290300214820042903c821213f20044188236a41086a290300214a200441b8206a41086a290300214b200429038823211620042903b820214c200441b8246a41086a290300214d20042903b824214e200441e8256a41086a290300214f20042903e8252150200441d8216a41086a290300215120042903d821215220042903a8232117200429039820215320042903d8242154200429038826215520042903b8212156200441a8236a41086a290300215720044198206a41086a2903002158200441d8246a41086a290300215e20044188266a41086a290300215f200441b8216a41086a290300216020042903b8232119200429038820216120042903e8242162200429039826216320042903a8212164200441b8236a41086a290300216520044188206a41086a2903002166200441e8246a41086a290300216720044198266a41086a2903002168200441a8216a41086a290300216920042903c823211a20042903f81f216a20042903f824216b20042903a826216c200429039821216d200441c8236a41086a290300216e200441f81f6a41086a290300216f200441f8246a41086a2903002170200441a8266a41086a290300217120044198216a41086a2903002172200441b0ca006a200441d8c6006a106a20042d00b04a410171106d2173200441f8026a202320042903c811227420042903e80d7c221420042903a8127c221c2004290388137c221f20042903b80e7c222b20042903d811227520042903f80d7c222c20042903b8127c222d2004290398137c222e20042903c80e7c222f20042903e811227620042903880e7c223020042903c8127c223120042903a8137c223220042903d80e7c223320042903f811227720042903980e7c223920042903d8127c223a20042903b8137c224020042903e80e7c2243200429038812227820042903a80e7c224520042903e8127c224720042903c8137c224920042903f80e7c223b42338820044188126a41086a290300200441a80e6a41086a2903007c2045207854ad7c200441e8126a41086a2903007c2047204554ad7c200441c8136a41086a2903007c2049204754ad7c200441f80e6a41086a2903007c203b204954ad7c420d86847c2245423388200441f8116a41086a290300200441980e6a41086a2903007c2039207754ad7c200441d8126a41086a2903007c203a203954ad7c200441b8136a41086a2903007c2040203a54ad7c200441e80e6a41086a2903007c2043204054ad7c2045204354ad7c420d86847c2239423388200441e8116a41086a290300200441880e6a41086a2903007c2030207654ad7c200441c8126a41086a2903007c2031203054ad7c200441a8136a41086a2903007c2032203154ad7c200441d80e6a41086a2903007c2033203254ad7c2039203354ad7c420d86847c2230423388200441d8116a41086a290300200441f80d6a41086a2903007c202c207554ad7c200441b8126a41086a2903007c202d202c54ad7c20044198136a41086a2903007c202e202d54ad7c200441c80e6a41086a2903007c202f202e54ad7c2030202f54ad7c420d86847c222c423388200441c8116a41086a290300200441e80d6a41086a2903007c2014207454ad7c200441a8126a41086a2903007c201c201454ad7c20044188136a41086a2903007c201f201c54ad7c200441b80e6a41086a2903007c202b201f54ad7c202c202b54ad7c420d868442137e203b42ffffffffffffff03837c227442ffffffffffffff038385200c8320238522144200203542f0ffffffffffff3f2018206d206c206b201a206a7c221c7c221f7c22237c222b206420632062201920617c222d7c222e7c222f7c2231205620552054201720537c22327c22337c223a7c2240203f203e203d2015203c7c22437c22477c22497c223b20522050204e2016204c7c223c7c223d7c223e7c223f4233882051204f204d204a204b7c203c201654ad7c7c203d203c54ad7c7c203e203d54ad7c7c203f203e54ad7c420d86847c2216423388204820462044204120427c2043201554ad7c7c2047204354ad7c7c2049204754ad7c7c203b204954ad7c2016203b54ad7c420d86847c22434233882060205f205e205720587c2032201754ad7c7c2033203254ad7c7c203a203354ad7c7c2040203a54ad7c2043204054ad7c420d86847c2232423388206920682067206520667c202d201954ad7c7c202e202d54ad7c7c202f202e54ad7c7c2031202f54ad7c2032203154ad7c420d86847c2217423388207220712070206e206f7c201c201a54ad7c7c201f201c54ad7c7c2023201f54ad7c7c202b202354ad7c2017202b54ad7c420d868442137e203f42ffffffffffffff03837c2215423388201642ffffffffffffff03837c85200c8320188522167d221a42ffffffffffffff038342d0fdffffffffff3f201d201542ffffffffffffff038385200c83201d8522197d221c4233887c20168542002073ad42ff01837d2215832016857d42f0ffffffffffff3f7c222342ffffffffffffff0383203442f0ffffffffffff3f2011201742ffffffffffffff038385200c83201185221f7d222b42338842137e201c42ffffffffffffff03837c2019852015832019857d42d0fdffffffffff3f7c222d4233887c2216420010d507200441386a2022202c42ffffffffffffff038385200c8320228522174200203742f0ffffffffffff3f2020204342ffffffffffffff038385200c8320208522197d222242ffffffffffffff0383201a4233887c2019852015832019857d42f0ffffffffffff3f7c222c42ffffffffffffff038320234233887c221c42137e222e420010d50720044188016a2027203042ffffffffffffff038385200c8320278522194200203842f0ffffffffffff3f200e203242ffffffffffffff038385200c83200e85221a7d222742ffffffffffffff038320224233887c201a85201583201a857d42f0ffffffffffff3f7c222f42ffffffffffffff0383202c4233887c222242137e2223420010d507200441d8016a2029203942ffffffffffffff038385200c83202985221a42002036202b42ffffffffffffff038320274233887c201f85201583201f857d42f0ffffffffffff3f7c221542ffffffffffffff0383202f4233887c222742137e221f420010d507200441a8026a202a2074423388204542ffffffffffffff03837c85200c83202a85220c4200201542338842137e202d42ffffffffffffff03837c2215420010d50720044188036a201542002014420010d507200441c8006a20174200201642137e420010d50720044198016a20194200202e420010d507200441e8016a201a42002023420010d507200441b8026a200c4200201f420010d507200441e8026a20144200201c420010d507200441286a201742002023420010d507200441f8006a20194200201f420010d507200441c8016a201a42002015420010d50720044198026a200c42002016420010d507200441d8026a201442002022420010d507200441186a20174200201f420010d507200441e8006a201942002015420010d507200441b8016a201a42002016420010d50720044188026a200c4200201c420010d507200441c8026a201442002027420010d507200441086a201742002015420010d507200441d8006a201942002016420010d507200441a8016a201a4200201c420010d507200441f8016a200c42002022420010d50720042004290308223120042903c8027c220c20042903587c221420042903a8017c221520042903f8017c22162004290318223220042903d8027c221720042903687c221920042903b8017c221a2004290388027c221c2004290328223320042903e8027c221f20042903787c222220042903c8017c22232004290398027c22272004290338223920042903f8027c22292004290388017c222a20042903d8017c222b20042903a8027c222c2004290348223a2004290388037c222d2004290398017c222e20042903e8017c222f20042903b8027c2230423388200441c8006a41086a29030020044188036a41086a2903007c202d203a54ad7c20044198016a41086a2903007c202e202d54ad7c200441e8016a41086a2903007c202f202e54ad7c200441b8026a41086a2903007c2030202f54ad7c420d86847c222d423388200441386a41086a290300200441f8026a41086a2903007c2029203954ad7c20044188016a41086a2903007c202a202954ad7c200441d8016a41086a2903007c202b202a54ad7c200441a8026a41086a2903007c202c202b54ad7c202d202c54ad7c420d86847c2229423388200441286a41086a290300200441e8026a41086a2903007c201f203354ad7c200441f8006a41086a2903007c2022201f54ad7c200441c8016a41086a2903007c2023202254ad7c20044198026a41086a2903007c2027202354ad7c2029202754ad7c420d86847c221f423388200441186a41086a290300200441d8026a41086a2903007c2017203254ad7c200441e8006a41086a2903007c2019201754ad7c200441b8016a41086a2903007c201a201954ad7c20044188026a41086a2903007c201c201a54ad7c201f201c54ad7c420d86847c2217423388200441086a41086a290300200441c8026a41086a2903007c200c203154ad7c200441d8006a41086a2903007c2014200c54ad7c200441a8016a41086a2903007c2015201454ad7c200441f8016a41086a2903007c2016201554ad7c2017201654ad7c420d868442137e203042ffffffffffffff03837c220c42ffffffffffffff038322143703d8462004200c423388202d42ffffffffffffff03837c22153703e0462004201742ffffffffffffff038322163703f8462004201f42ffffffffffffff038322173703f0462004202942ffffffffffffff038322193703e846200441b0ca006a200441d8c6006a106a200442f0ffffffffffff3f20167d221a42ffffffffffffff038342f0ffffffffffff3f20177d221c4233887c201685420020042d00b04a410171106dad42ff01837d220c832016853703f8462004201c42ffffffffffffff038342f0ffffffffffff3f20197d22164233887c201785200c832017853703f0462004201642ffffffffffffff038342f0ffffffffffff3f20157d22164233887c201985200c832019853703e8462004201642ffffffffffffff038342d0fdffffffffff3f20147d22164233887c201585200c832015853703e0462004201a42338842137e201642ffffffffffffff03837c201485200c832014853703d846200441e8c4006a200441d8c6006a106a20044188c5006a1086012006200141186a2900003703002005200141106a290000370300200441e8c8006a41086a2273200141086a290000370300200420012900003703e848200441d8c6006a200441e8c8006a10d103200441d8c6006a41086a290300210c205d2903002114205c2903002115205b2903002119205a290300211a20242903002116202529030021172026290300211c2028290300211f200441a8c7006a290300212220042802dc46212420042802d846210120044188c5006a200741f00010e4071a02400240024020014101460d00200441d8c6006a20044188c5006a41f00010e4071a20042014200c4233887c22234233882023201454ad420d8684222920157c222742ffffffffffffff03833703e84a200420274233882027202954ad420d8684222920197c222742ffffffffffffff03833703f04a200420274233882027202954ad420d86842229201a7c222742ffffffffffffff03833703f84a200420274233882027202954ad420d868442137e200c42ffffffffffffff03837c222742ffffffffffffff03833703d84a20042027423388202342ffffffffffffff03837c3703e04a20024200370300200342003703002008420037030020094200370300200442003703a84820594200370300200642003703002005420037030020734200370300200442003703e8482004201720164233887c22234233882023201754ad420d86842229201c7c22274233882027202954ad420d8684222a201f7c22294233882029202a54ad420d8684222b20227c222a42ffffffffffffff03833703a8452004202942ffffffffffffff03833703a0452004202742ffffffffffffff0383370398452004202a423388202a202b54ad420d868442137e201642ffffffffffffff03837c2227423388202342ffffffffffffff03837c370390452004202742ffffffffffffff03833703884520044188ca006a200441d8ca006a106a200441b0ca006a200441a8c8006a106a41002101410121020340200441b0ca006a20016a2d000020044188ca006a20016a2d0000732203410020036b72417f7341800171410776106d2002712102200141016a22014120470d000b2002106d210820044188ca006a200441e8c8006a106a200441b0ca006a20044188c5006a106a41002101410121020340200441b0ca006a20016a2d000020044188ca006a20016a2d0000732203410020036b72417f7341800171410776106d2002712102200141016a22014120470d000b2002106d200872106d41ff01714101460d01200041a0016a202137030020004198016a201e37030020004190016a201b37030020004188016a201237030020004180016a2013370300200041f8006a2036370300200041f0006a2038370300200041e8006a2037370300200041e0006a2035370300200041d8006a2034370300200041d0006a2011370300200041c8006a200e370300200041c0006a2020370300200041386a2018370300200041306a201d370300200041286a200a370300200041206a200d370300200041186a200f370300200041106a2010370300200041086a200b37030020004190026a202237030020004188026a201f37030020004180026a201c370300200041f8016a2017370300200041f0016a2016370300200041e8016a201a370300200041e0016a2019370300200041d8016a2015370300200041d0016a2014370300200041c8016a200c370300200041c0016a200441e8c4006a41186a290300370300200041b8016a200441e8c4006a41106a290300370300200041b0016a200441e8c4006a41086a290300370300200041a8016a20042903e84437030020004198026a200441d8c6006a41f00010e4071a200041003602000c020b2000202436020420004101360200200041186a20153e0200200041106a2014370200200041086a200c3702000c010b20004101360200200041013a00040b20044180cb006a24000b8d0403037f017e017f23004180016b22012400200141086a41206a200041206a280200360200200141086a41186a200041186a290200370300200141086a41106a200041106a290200370300200141086a41086a200041086a29020037030020012000290200370308200141d0006a41186a4200370300200141d0006a41106a22024200370300200141d0006a41086a220042003703002001420037035041b3e6ca00ad4280808080e000841001220329000021042000200341086a290000370300200120043703502003102941e7e6ca00ad4280808080e00084100122032900002104200141f0006a41086a2205200341086a2900003703002001200437037020031029200220012903702204370300200141306a41086a2000290300370300200141306a41106a2004370300200141306a41186a200529030037030020012001290350370330200141d0006a200141086a10bc0220012802542100200141306aad4280808080800484200135025842208620012802502203ad84101402402000450d00200310290b0240024020012d0008220041044b0d0002400240024020000e050400010204040b200141146a280200450d03200141106a28020010290c030b200141146a280200450d02200141106a28020010290c020b200141146a280200450d01200141106a28020010290c010b200141106a280200450d00200128020c10290b20014180016a24000b3400200041c8bec50036020420004100360200200041146a410b360200200041106a41dce8c200360200200041086a42043702000b910101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002404120102722060d001039000b20062002290300370000200042a0808080800437020420002006360200200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000200241206a24000b130020004102360204200041b480c3003602000b2d01017f02404108102722020d001039000b20004288808080800137020420002002360200200242f02e3700000b2d01017f02404108102722020d001039000b20004288808080800137020420002002360200200242e0123700000bce21011d7f230041b0046b220224000240024002400240024002400240024020002802004101460d00200041146a2802002203200328020041016a360200200041106a28020021042000410c6a2802002105200041086a280200210320002802042106200241e0006a41206a2207200041386a2d00003a0000200241e0006a41186a2208200041306a290000370300200241e0006a41106a2209200041286a290000370300200241e0006a41086a220a200041206a2900003703002002200041186a29000037036020032f0106220b410b490d01200241c0016a410041eb0210e6071a200241d9006a4100360000200241306a41216a4200370000200241c9006a4200370000200241c1006a4200370000200241396a42003700002002420037003141a0031027220c450d05200c41003b0106200c4100360200200c41086a200241c0016a41eb0210e4072107200c4198036a200241d5006a290000370000200c4193036a200241306a41206a290000370000200c418b036a200241306a41186a290000370000200c4183036a200241306a41106a290000370000200c41fb026a200241306a41086a290000370000200c20022900303700f3022002200341ce016a2f00003b01182002200341d0016a2d00003a001a200341d1016a280000210d200341d5016a280000210e200341d9016a280000210f200341dd016a28000021102002200341e7016a2900003701c6012002200341e1016a2900003703c001200328028c0321112007200341ef016a20032f010641796a220041216c10e4072107200c41f4026a20034190036a200041027410e4072108200341063b0106200c20003b01062002412c6a41026a20022d001a3a0000200220022f01183b012c200220022903c001370330200220022901c6013701360240024020044107490d00200441216c20076a220741ba7e6a200741997e6a2207200041ffff0371200441796a22096b41216c10e5071a200741206a200241e0006a41206a2d00003a0000200741186a200241e0006a41186a290300370000200741106a200241e0006a41106a290300370000200741086a200241e0006a41086a29030037000020072002290360370000200441027420086a41686a2107200820094102746a2112200c41066a22002f010020096b21040c010b200341086a200441216c6a220741216a2007200341066a22002f010020046b41216c10e5071a200741206a200241e0006a41206a2d00003a0000200741186a200241e0006a41186a290300370000200741106a200241e0006a41106a290300370000200741086a200241e0006a41086a29030037000020072002290360370000200341f4026a20044102746a221241046a210720002f010020046b21040b20072012200441027410e5071a20122001360200200241146a41026a2002412c6a41026a22132d000022013a0000200020002f010041016a3b0100200241106a41026a221420013a000020022002290136370196012002200229033037039001200220022f012c22003b0114200220003b0110200220022903900137030020022002290196013701060240200328020022070d00410021000c040b20032f01042115200241c0016a4102722116200241306a41016a210a410021000340201320142d00003a0000200220022f01103b012c200220022903003703182002200229010637011e20062000470d03201541ffff0371210802400240024020072f01062200410b490d00200a41286a4100360000200a41206a4200370000200a41186a4200370000200a41106a4200370000200a41086a4200370000200a42003700002016410041ed0210e6071a200241e0006a41086a22004200370300200241e0006a41106a22034200370300200241e0006a41186a22044200370300200241e0006a41206a22094200370300200241e0006a41286a220b420037030020024190016a41256a2217200241306a41256a29000037000020024190016a41206a2218200241306a41206a29000037030020024190016a41186a2219200241306a41186a29000037030020024190016a41106a221a200241306a41106a29000037030020024190016a41086a221b200241306a41086a29000037030020024200370360200220022900303703900141d00310272201450d0920014100360200200141046a200241c0016a41ef0210e4071a20014198036a201729000037000020014193036a20182903003700002001418b036a201929030037000020014183036a201a290300370000200141fb026a201b29030037000020012002290390013700f302200120022903603702a003200141a8036a2000290300370200200141b0036a2003290300370200200141b8036a2004290300370200200141c0036a2009290300370200200141c8036a200b29030037020020024190016a41026a220b200741d0016a2d00003a00002002200741ce016a2f00003b0190012002200741e1016a2900003703c0012002200741e7016a2900003701c601200741d1016a2800002118200741d5016a2800002119200741d9016a280000211a200741dd016a280000211b200728028c03211c200141086a200741ef016a20072f0106220341796a220041216c10e407211d200141f4026a20074190036a200041027410e407211e200141a0036a200741bc036a2003417a6a220941027410e4072117200741063b0106200120003b010602402009450d00410021002017210303402003280200220420003b010420042001360200200341046a21032009200041016a2200470d000b0b200220022f01900122003b0130200220022903c001370360200220022901c6013701662002200b2d000022033a0032200b20033a0000200220003b019001200220022903603703c001200220022901663701c601201541ffff037122034107490d01200841216c201d6a220041ba7e6a200041997e6a220320012f0106200841796a22006b41216c10e5071a2003201036000f2003200f36000b2003200e3600072003200d360003200341026a20132d00003a0000200320022f012c3b000020032002290318370013200341196a200229011e370000201e2008417a6a220341027422046a201e20004102746a220920012f0106221520006b41027410e5071a200920113602002001201541016a22093b01062008410274221520176a416c6a201720046a2204200941ffff0371220820036b41027410e5071a2004200c36020020082003490d02200120156a4188036a2103034020032802002204200041016a22003b010420042001360200200341046a210320002008490d000c030b0b2007200841216c6a220341296a200341086a2201200020086b41216c10e5071a200341176a2010360000200341136a200f3600002003410f6a200e3600002003410b6a200d3600002003410a6a2002412c6a41026a2d00003a0000200120022f012c3b00002003411b6a2002290318370000200341216a200229011e370000200741f4026a2203200841016a220041027422016a2003200841027422046a220320072f0106220920086b41027410e5071a200320113602002007200941016a22033b01062004200741a0036a22086a41086a200820016a2201200341ffff0371220420006b41027410e5071a2001200c360200201541ffff037120044f0d0720072000417f6a22004102746a41a4036a2103034020032802002201200041016a22003b010420012007360200200341046a210320002004490d000c080b0b200741086a200841216c6a220041216a200020072f010620086b41216c10e5071a2000201036000f2000200f36000b2000200e3600072000200d360003200041026a20132d00003a0000200020022f012c3b000020002002290318370013200041196a200229011e370000200741f4026a2204200841016a220941027422156a2004200841027422006a220420072f0106221720086b41027410e5071a200420113602002007201741016a22043b01062000200741a0036a22176a41086a201720156a2215200441ffff0371220420096b41027410e5071a2015200c360200200320044f0d00200720006a41a4036a2100034020002802002203200841016a22083b010420032007360200200041046a210020042008470d000b0b200641016a21002014200b2d00003a0000200220022f0190013b0110200220022903c001370300200220022901c6013701060240200728020022030d002018210d201b2110201a210f2019210e2001210c201c21110c050b20072f010421152018210d201b2110201a210f2019210e20032107201c21112001210c200021060c000b0b20012001280200417f6a2203360200200041086a280200200041106a2802004102746a41f4026a211220030d030240200128020c2200450d0020002000280200417f6a360200200128020c22002802000d00200041086a10dc03200128020c22002000280204417f6a360204200128020c22002802040d00200010290b20012001280204417f6a220036020420000d03200110290c030b2003200441216c6a220041296a200041086a220c200b20046b41216c10e5071a200041286a20072d00003a0000200041206a2008290300370000200041186a2009290300370000200041106a200a290300370000200c2002290360370000200320044102746a220041f8026a200041f4026a221220032f010620046b41027410e5071a20122001360200200320032f010641016a3b01060c020b41cc9ec800413541b8a1cc001033000b200241b9016a4100360000200241b1016a4200370000200241a9016a4200370000200241a1016a420037000020024199016a42003700002002420037009101200241c0016a410272410041ed0210e6071a200241e0006a41086a22014200370300200241e0006a41106a22044200370300200241e0006a41186a22074200370300200241e0006a41206a2208420037030020024188016a22094200370300200241306a41256a220a20024190016a41256a290000370000200241306a41206a220b20024190016a41206a290000370300200241306a41186a220620024190016a41186a290000370300200241306a41106a221520024190016a41106a290000370300200241306a41086a221720024190016a41086a29000037030020024200370360200220022900900137033041d00310272203450d0120034100360200200341046a200241c0016a41ef0210e4071a20034198036a200a29000037000020034193036a200b2903003700002003418b036a200629030037000020034183036a2015290300370000200341fb026a2017290300370000200320022903303700f302200320022903603702a003200341a8036a2001290300370200200341b0036a2004290300370200200341b8036a2007290300370200200341c0036a2008290300370200200341c8036a20092903003702002003200528020022013602a0032005200336020020052005280204220441016a360204200141003b010420012003360200200241e0006a41026a200241106a41026a2d00003a0000200220022f01103b0160200220022903003703c001200220022901063701c60120042000470d0220032f01062201410a4b0d032003200141216c6a2200410a6a200241e0006a41026a2d00003a0000200041086a20022f01603b0000200041176a2010360000200041136a200f3600002000410f6a200e3600002000410b6a200d3600002000411b6a20022903c001370000200041216a20022901c6013700002003200141016a22004102746a41a0036a200c360200200320014102746a41f4026a2011360200200320003b0106200c20003b0104200c20033602000b200241b0046a240020120f0b1030000b41b69cc800413041b8a1cc001033000b418f9cc800412741b8a1cc001033000bc30101027f230041106b2202240002400240200128020041016a220341014d0d0020012003360200200028020022002802080d012000417f3602080240200028020c2203450d0020032003280200417f6a360200200028020c22032802000d00200341086a10dc03200028020c22032003280204417f6a360204200028020c22032802040d00200310290b2000200136020c2000200028020841016a360208200241106a24000f0b00000b41c78dcc004110200241086a41c8a7c70041e88dcc00103a000b9909010d7f230041306b220224002002410036021020024204370308200241003602202002420437031802400240024002400240200128020041016a220341014d0d0020012003360200200241086a4100410110980120022802082204200228021022034102746a20013602002002200341016a22053602102001280200220341016a41014d0d002001200341016a360200200241186a4100410110980120022802182206200228022022034102746a20013602002002200341016a2207360220200128020041016a220841014d0d00200120083602000340200841016a220341014d0d0120012003360200200128020841016a220341004c0d02200141086a210920012003360208200128020c2208450d0502402007450d002007410274210a200841106a210b2006210c0340200c28020022032008460d07200328020841016a220d41004c0d052003200d3602082008280208220d41016a220e41004c0d062008200e3602080240200341106a200b412010e7070d0020032d003020082d0030470d002008200d36020820032003280208417f6a3602080c080b200c41046a210c2008200d36020820032003280208417f6a360208200a417c6a220a0d000b200128020c21080b200828020041016a220341014d0d012008200336020002402005200228020c470d00200241086a2005410110980120022802082104200228021021050b200420054102746a20083602002002200541016a2205360210200128020c220328020041016a220841014d0d012003200836020020012001280200417f6a2208360200024020080d00200910dc0320012001280204417f6a220836020420080d00200110290b200328020041016a220841014d0d012003200836020002402007200228021c470d00200241186a2007410110980120022802182106200228022021070b200620074102746a200336020020012001280208417f6a36020820012001280200417f6a22083602002002200741016a2207360220024020080d00200910dc0320012001280204417f6a220836020420080d00200110290b20032802002108200321010c000b0b00000b41cc8ccc004118200241286a41b8a7c70041f48ccc00103a000b41cc8ccc004118200241286a41b8a7c70041f48ccc00103a000b41cc8ccc004118200241286a41b8a7c70041f48ccc00103a000b20012001280208417f6a36020820012001280200417f6a2203360200024020030d00200910dc0320012001280204417f6a220336020420030d00200110290b20002001360200200020022903083702042000410c6a200241086a41086a28020036020002402007450d00200741027421082006210303402003280200220c200c280200417f6a36020002402003280200220c2802000d000240200c28020c2201450d0020012001280200417f6a360200200c28020c22012802000d00200141086a10dc03200c28020c22012001280204417f6a360204200c28020c220c2802040d00200c10290b2003280200220c200c280204417f6a3602042003280200220c2802040d00200c10290b200341046a21032008417c6a22080d000b0b0240200228021c41ffffffff0371450d00200610290b200241306a24000b5401017f024020002802042201450d0020012001280200417f6a360200200028020422012802000d00200141086a10dc03200028020422012001280204417f6a360204200028020422002802040d00200010290b0ba50201047f230041106b22022400410021030240024002400240024002400240200028020841016a220441004c0d00200028020c2205450d0620002004360208024020052001470d00410121030c060b200528020841016a220341004c0d01200520033602082001280208220441016a220341004c0d0220012003360208200541106a200141106a412010e7070d034101210320052d003020012d0030470d030c040b41cc8ccc004118200241086a41b8a7c70041f48ccc00103a000b41cc8ccc004118200241086a41b8a7c70041f48ccc00103a000b41cc8ccc004118200241086a41b8a7c70041f48ccc00103a000b410021030b2001200436020820052005280208417f6a360208200028020821040b20002004417f6a3602080b200241106a240020030bbe110c047f027e027f067e017f037e037f027e027f017e017f027e230041b0036b2204240020032802002105200441206a200110a802200441a0016a200428022022062004280228220710a90220042903a001210842002109200442003703a001200441e8016a280200210a20042d00ec01210b02400240200842015122030d00200441306a41306a4200370300200441306a41286a4200370300200441306a41206a4200370300200441306a41186a4200370300200441c0006a4200370300200441386a4200370300200442003703304200210c4200210d4200210e4200210f0c010b200441d8016a2903002110200441a0016a41306a2903002111200441a0016a41206a290300210c200441a0016a41186a2903002109200441e0016a290300210f20042903b001210e20042903a801210d200441306a41206a200441a0016a41286a290300370300200441306a41286a2011370300200441306a41306a2010370300200441c0006a20093703002004200c3703482004200d3703302004200e3703380b427f200e200c7c200d20097c220c200d542212ad7c220920122009200e542009200e511b22121b2113427f200c20121b2114420021090240024002402002290300221542ffc7afa02556200241086a290300220c420052200c501b0d00201420138450450d0041002103410021124200210e410121020c010b4200200e200c7c200d20157c2210200d542202ad7c220d2002200d200e54200d200e511b22021b210e4200201020021b2111024020024101470d002011421088200e423086842109200e421088210e2011420888a721122011a72103410121020c010b200441b0026a41186a22164200370300200441b0026a41106a22174200370300200441b0026a41086a22124200370300200442003703b00241dcbec500ad42808080808001842209100122182900002119200441a0026a41086a2202201841086a290000370300200420193703a0022018102920122002290300370300200420042903a0023703b002419fe3c200ad4280808080d00184221910012218290000211a2002201841086a2900003703002004201a3703a00220181029201720042903a002221a370300200441e8006a41086a221b2012290300370300200441e8006a41106a221c201a370300200441e8006a41186a22182002290300370300200420042903b002370368200441086a200441e8006a412010e301200441086a41106a290300211a2004290310211d2004280208211e201642003703002017420037030020124200370300200442003703b00220091001221629000021092002201641086a290000370300200420093703a0022016102920122002290300370300200420042903a0023703b00220191001221629000021092002201641086a290000370300200420093703a00220161029201720042903a0022209370300201b2012290300370300201c200937030020182002290300370300200420042903b0023703682004201a4200201e1b3703b8022004201d4200201e1b3703b002200441e8006aad4280808080800484200441b0026aad428080808080028410032004200e370338200420113703302018200441c0006a220241086a2903002209370300200441e8006a41206a2212200241106a29030037030020044190016a2217200241186a29030037030020044198016a2218200241206a2903003703002004200e3703702004201137036820042002290300221937037802400240427f201120197c221920192011542202200e20097c2002ad7c2209200e542009200e511b22021b220e4280c8afa025544100427f200920021b2209501b0d00201c290300210e2018290300210920172903002111201229030021192004290370211a2004290368211d4201211f20042903800121200c010b4200211f0240200e200984500d00200e200910d402200441e8026a2009370300200441e0026a200e370300200441b0026a41086a41013a0000200441b9026a2005290000370000200441c1026a200541086a290000370000200441c9026a200541106a290000370000200441d1026a200541186a290000370000200441033a00b002200441b0026a10cb010b0b200441c8016a2019370300200441d0016a2011370300200441b0016a201a370300200441d8016a2009370300200441b8016a200e370300200420203703c0012004200f3703e0012004201d3703a801410021022004200b4100200842015122121b22053a00ec012004200a410020121b220a3602e8012004201f4201512212ad3703a001201420138450ad42308621094200210e024020120d002007ad4220862006ad841004410021120c010b410410272202450d012002200a360000200241044108102b2202450d01200220053a0004200241084115102b2202450d012002201d3700052002410d6a201a370000200441c0016a2903002108200441b8016a290300211320024115412a102b2202450d01200220133700152002411d6a20083700002002412a41d400102b2202450d01200220193700252002412d6a20113700002002413d6a200441e0016a2903003700002002200441d8016a2903003700352007ad4220862006ad842002ad4280808080d0088410032002102941012112410021020b02402004280224450d00200610290b024002402002450d00200041106a200e42108620094230888437030020002012ad42ff01834208862003ad42ff0183842009421086843703084201210e0c010b2009423088200e42108684210e024002400240200341ff017122020d00201241ff0171450d0041032103200441b0026a21020c010b2002450d01201241ff01710d0141042103200441a0016a21020b200241086a20033a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a290000370000200210cb010b2000200e370308200041286a200c370300200041206a2015370300200041186a200d370300200041106a20103703004200210e0b2000200e370300200441b0036a24000f0b1030000bc20503027f017e047f230041d0006b2202240041dcbec500ad4280808080800184100122032900002104200241086a200341086a290000370300200220043703002003102941f891c700ad4280808080d00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100522012900002104200241306a41086a200141086a2900003703002002200437033020011029200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a1075200310292002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a20002001360208200020083602042000200336020002402002280224450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000ba6210b037f027e037f047e027f027e027f077e017f027e047f23004190086b22062400200620043703102006200337030820062001360204200620053a001f024002400240024002400240024020012002460d002003200484500d0020012002412010e707450d00200641206a200210a802200641306a200628022022072006280228220810a902200629033021094200210a20064200370330200641f8006a280200210b20062d007c210c024002402009420151220d0d0020064180016a41386a420037030020064180016a41306a420037030020064180016a41286a4200370300200641a0016a420037030020064180016a41186a420037030020064190016a420037030020064188016a420037030020064200370380014200210e4200210f420021100c010b200641306a41386a2903002103200641306a41306a2903002104200641306a41206a290300210e200641306a41186a290300210a200641f0006a2903002111200629034021102006290338210f200641a0016a200641306a41286a29030037030020064180016a41286a200437030020064180016a41306a200337030020064190016a200a3703002006200e37039801200620113703b8012006200f3703800120062010370388010b200641c0036a2006280204221210a802200641d0036a20062802c003221320062802c803220110a90220062903d003211442002115200642003703d00320064198046a280200211620062d009c04211702400240201442015122050d00200641a0046a41306a4200370300200641a0046a41286a4200370300200641a0046a41206a4200370300200641a0046a41186a4200370300200641a0046a41106a4200370300200641a8046a4200370300200642003703a004420021184200210442002103420021190c010b20064188046a2903002111200641d0036a41306a290300211a200641d0036a41206a2903002118200641d0036a41186a290300211520064190046a290300211920062903e003210320062903d8032104200641a0046a41206a200641d0036a41286a290300370300200641a0046a41286a201a370300200641a0046a41306a2011370300200641a0046a41106a2015370300200620183703b804200620043703a004200620033703a8040b024020042006290308221b7d221a2004562003200641086a41086a290300221c7d2004201b54ad7d221120035620112003511b450d0041cbe2c20021054280808080b002210341808c0c21010c030b2006201a3703a004200620113703a8040240200629038001221d201b7c221e201d54221f20064180016a41086a2903002220201c7c201fad7c221d202054201d2020511b450d0041839dc500210542808080808001210341808c0821010c030b2006201e3703800120064198016a29030021202006201d370388010240427f201e2006290390017c22212021201e54221f201d20207c201fad7c2220201d542020201d511b221f1b4280c8afa025544100427f2020201f1b501b450d0041b9e2c20021054280808080a002210341808c1021010c030b0240201b201c84500d00200641d8046a200628020410a80220064190076a20062802d804222220062802e00410a902200641c0076a2903004200200629039007420151221f1b211b200641b8076a2903004200201f1b211d024020062802dc04450d00202210290b201d201a56201b201156201b2011511b0d020b0240024020062d001f4101460d00201a4280c8afa0255441002011501b0d010c050b200641d8046a200628020410a80220064190076a20062802d804221f20062802e00410a90220062d00dc072122200629039007211b024020062802dc04450d00201f10290b201a42ffc7afa0255620114200522011501b0d04201b4201520d04202241ff0171450d040b41b0e2c200210542808080809001210341808c1421010c020b200041043a00000c050b41dee2c20021054280808080d002210341808c0421010b200141037221162005ad221142088842ff018321042011428080fcff0f83200384211b4101211f0c010b200641d8046a41186a200641a0046a41186a290300221b370300200641d8046a41206a2223200641a0046a41206a290300370300200641d8046a41286a2224200641a0046a41286a290300370300200641d8046a41306a2225200641a0046a41306a290300370300200620062903b004221d3703e8042006201a3703d804200620113703e004427f200420157c22152015200454221f200320187c201fad7c220420035420042003511b221f1b427f2004201f1b8450211f02400240427f201a201d7c22032003201a5422222011201b7c2022ad7c220320115420032011511b22221b22044280c8afa025544100427f200320221b2203501b0d00200641e8046a290300211c20252903002118202429030021042023290300211b20062903e004211520062903d804211d4201212020062903f004211e0c010b4200212002402004200384500d002004200310d402200641c8076a2003370300200641c0076a200437030020064190076a41086a41013a000020064199076a2012290000370000200641a1076a201241086a290000370000200641a9076a201241106a290000370000200641b1076a201241186a290000370000200641033a00900720064190076a10cb010b0b201fad2103200641f8036a201b37030020064180046a2004370300200641e0036a201537030020064188046a2018370300200641e8036a201c3703002006201e3703f00320062019370390042006201d3703d8034100211f200620174100201442015122221b22173a009c0420062016410020221b222236029804200620204201512216ad3703d003024020160d002001ad4220862013ad841004420021044200211b0c010b410410272216450d0120162022360000201641044108102b2216450d01201620173a0004201641084115102b2216450d012016201d3700052016410d6a2015370000200641f0036a2903002114200641e8036a290300211520164115412a102b2216450d01201620153700152016411d6a20143700002016412a41d400102b2216450d012016201b3700252016412d6a20043700002016413d6a20064190046a290300370000201620064188046a2903003700352001ad4220862013ad842016ad4280808080d008841003201610294200211b420121040b024020062802c403450d00201310290b20064180016a41106a210102400240201f0d00024002400240200541ff017122050d0020044200510d004103211620064190066a21050c010b2005450d0120044200520d014104211620064190056a21050b200541086a20163a0000200541003a0000200541096a2012290000370000200541116a201241086a290000370000200541196a201241106a290000370000200541216a201241186a290000370000200510cb010b410421164100210520034201520d01200641c8076a2011370300200641c0076a201a3703004100210520064190076a41086a41003a000020064199076a2012290000370000200641a1076a201241086a290000370000200641a9076a201241106a290000370000200641b1076a201241186a290000370000200641033a00900720064190076a10cb010c010b20044208862005ad42ff018384201b842103201641807e7121050b20064190056a41086a2212200141086a29030037030020064190056a41106a221f200141106a29030037030020064190056a41186a2213200141186a29030037030020064190056a41206a2217200141206a290300370300200620012903003703900520064180016a41086a2903002104200629038001211102400240201641ff017122014104460d0020034280807c83211a200342088842ff01832110200520017221012003a7210d410121050c010b20062903b801211420064190066a41186a2012290300221a37030020064190066a41206a201f290300370300200641b8066a22122013290300370300200641c0066a221620172903003703002006200629039005221b3703a00620062011370390062006200437039806427f200f200a7c22032003200f5422012010200e7c2001ad7c220320105420032010511b22011b427f200320011b8450210102400240427f2011201b7c2203200320115422052004201a7c2005ad7c220320045420032004511b22051b22104280c8afa025544100427f200320051b2203501b0d00200641a0066a290300210f2016290300211520122903002110200641b0066a290300211a200629039806211b200629039006210a4201210e20062903a806211d0c010b4200210e02402010200384500d002010200310d402200641c8076a2003370300200641c0076a201037030020064190076a41086a41013a000020064199076a2002290000370000200641a1076a200241086a290000370000200641a9076a200241106a290000370000200641b1076a200241186a290000370000200641033a00900720064190076a10cb010b0b2001ad2103200641d8006a201a370300200641e0006a2010370300200641c0006a201b370300200641e8006a2015370300200641c8006a200f3703002006201d370350200620143703702006200a370338410021052006200c4100200942015122011b22123a007c2006200b410020011b22163602782006200e4201512201ad370330024020010d002008ad4220862007ad841004420021104200211a0c010b410410272201450d0120012016360000200141044108102b2201450d01200120123a0004200141084115102b2201450d012001200a3700052001410d6a201b370000200641d0006a290300211b200641c8006a290300210920014115412a102b2201450d01200120093700152001411d6a201b3700002001412a41d400102b2201450d012001201a3700252001412d6a20103700002001413d6a200641f0006a2903003700002001200641e8006a2903003700352008ad4220862007ad842001ad4280808080d008841003200110294200211a420121100b02402006280224450d00200710290b02400240024020050d00024002400240200d41ff017122010d0020104200510d0041032105200641c0026a21010c010b2001450d0120104200520d0141042105200641c0016a21010b200141086a20053a0000200141003a0000200141096a2002290000370000200141116a200241086a290000370000200141196a200241106a290000370000200141216a200241186a290000370000200110cb010b20034201520d01200641c8076a2004370300200641c0076a201137030020064190076a41086a41003a000020064199076a2002290000370000200641a1076a200241086a290000370000200641a9076a200241106a290000370000200641b1076a200241186a290000370000200641033a00900720064190076a10cb010c010b200141ff01714104470d010b2006280204210120062903082103200641e8076a200641086a41086a290300370300200641e0076a200337030020064190076a41086a41023a000020064199076a2001290000370000200641a1076a200141086a290000370000200641a9076a200141106a290000370000200641b1076a200141186a290000370000200641b9076a2002290000370000200641c1076a200241086a290000370000200641c9076a200241106a290000370000200641d1076a200241186a290000370000200641033a00900720064190076a10cb01200041043a00000c020b2000200141087622023b0001200020013a0000200041036a20024110763a0000200041046a2010420886200dad42ff018384201a843700000c010b1030000b20064190086a24000b130020004105360204200041888bc3003602000b3400200041ddbfc50036020420004100360200200041146a4101360200200041106a41b4b7c300360200200041086a42073702000bbe1504057f017e077f037e230041c0076b22022400024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541044b0d0620050e050102030405010b200041063a00000c110b200241086a200110c801024020022802080d00200228020c2204200128020441a8026e2203200320044b1bad42a8027e2207422088a70d0a2007a72205417f4c0d0a0240024020050d00410821080c010b200510272208450d0c0b4100210320024100360248200220083602402002200541a8026e360244024002402004450d0020024198056a4104722109034020024198056a200110e4032002280298052105200241f0026a200941a40210e4071a2005411c460d02200241cc006a200241f0026a41a40210e4071a024020032002280244470d00200241c0006a20034101109a0120022802402108200228024821030b2008200341a8026c6a22062005360200200641046a200241cc006a41a40210e4071a2002200341016a22033602482004417f6a22040d000b0b2008450d0120022902442107200041013a0000200020022f003d3b0001200041086a2007370000200041046a2008360000200041106a2002290210370200200041036a2002413f6a2d00003a0000200041186a200241106a41086a290200370200200041206a200241106a41106a290200370200200041286a200241106a41186a290200370200200041306a200241106a41206a290200370200200041386a200241106a41286a2802003602000c120b02402003450d00200341a8026c2103200821010340200110c201200141a8026a2101200341d87d6a22030d000b0b20022802442201450d00200141a8026c450d00200810290b200041063a00000c100b024020064102490d0020042f0001210520012003417d6a3602042001200441036a36020020024198056a200110e4032002280298052101200241f0026a20024198056a41047241a40210e4071a2001411c460d0020024198056a200241f0026a41a40210e4071a41a80210272203450d0e20032001360200200341046a20024198056a41a40210e4071a200041046a2003360200200041026a20053b0100200041023a0000200041086a200229024c370200200041106a200241cc006a41086a290200370200200041186a200241cc006a41106a290200370200200041206a200241cc006a41186a290200370200200041286a200241cc006a41206a290200370200200041306a200241cc006a41286a290200370200200041386a200241cc006a41306a2802003602000c100b200041063a00000c0f0b024002400240024020064102490d0020042f0001210620012003417d6a3602042001200441036a36020020024198056a20011096022002280298052203450d0d200228029c05210520012802042204450d03200241a0056a280200210a200128020022092d0000210820012004417f6a220b3602042001200941016a360200200841014b0d034100210c20080e020201020b200041063a00000c110b200b4104490d012009280001210d20012004417b6a22083602042001200941056a36020020084104490d012009280005210e2001200441776a3602042001200941096a3602004101210c0b20024198056a200110e4032002280298052101200241f0026a20024198056a41047241a40210e4071a2001411c460d0b20024198056a200241f0026a41a40210e4071a41a80210272204450d0d20042001360200200441046a20024198056a41a40210e4071a2000411c6a2004360200200041186a200e360200200041146a200d360200200041106a200c3602002000410c6a200a360200200041086a2005360200200041046a2003360200200041026a20063b0100200041033a0000200041206a200229024c370200200041286a200241cc006a41086a290200370200200041306a200241cc006a41106a290200370200200041386a200241cc006a41186a2802003602000c0f0b200041063a0000200541ffffff3f71450d0e0c0d0b024002400240024020064102490d0020042f0001210920012003417d6a3602042001200441036a36020020024198056a20011096022002280298052206450d0e200228029c05210820012802042203450d03200241a0056a280200210a200128020022042d0000210520012003417f6a220b3602042001200441016a360200200541014b0d034100210c20050e020201020b200041063a00000c100b200b4104490d012004280001210d20012003417b6a22053602042001200441056a36020020054104490d012004280005210e2001200341776a220b3602042001200441096a3602004101210c0b41002105200241003a00b805200b417f6a2103024003402003417f460d0120024198056a20056a200128020022042d00003a0000200120033602042001200441016a3602002002200541016a22043a00b8052003417f6a21032004210520044120470d000b200241f0026a41186a20024198056a41186a2903002207370300200241f0026a41106a20024198056a41106a290300220f370300200241f0026a41086a20024198056a41086a2903002210370300200220022903980522113703f002200041043a000020002011370001200041096a2010370000200041116a200f370000200041196a2007370000200041386a200e360200200041346a200d360200200041306a200c3602002000412c6a200a360200200041286a2008360200200041246a2006360200200041226a20093b01000c0f0b0240200541ff0171450d00200241003a00b8050b200041063a0000200841ffffff3f71450d0e200610290c0e0b200041063a0000200841ffffff3f71450d0d200610290c0d0b20064102490d0120042f0001210a20012003417d6a3602042001200441036a36020020024198056a20011096022002280298052209450d02200228029c05210b200128020422054104490d04200241a0056a280200210d20012802002206280000210c20012005417c6a22033602042001200641046a36020020034104490d042006280004210e2001200541786a22083602042001200641086a36020041002103200241003a00b805200541776a2105034020082003460d0420024198056a20036a200620036a220441086a2d00003a0000200120053602042001200441096a3602002002200341016a22043a00b8052005417f6a21052004210320044120470d000b200241f0026a41186a20024198056a41186a2903002207370300200241f0026a41106a20024198056a41106a290300220f370300200241f0026a41086a20024198056a41086a2903002210370300200220022903980522113703f002200041053a000020002011370001200041096a2010370000200041116a200f370000200041196a2007370000200041346a200e360200200041306a200c3602002000412c6a200d360200200041286a200b360200200041246a2009360200200041226a200a3b01000c0c0b200041063a00000c0b0b200041063a00000c0a0b200041063a00000c090b0240200341ff0171450d00200241003a00b8050b200041063a0000200b41ffffff3f71450d08200910290c080b200041063a0000200b41ffffff3f71450d07200910290c070b1038000b1039000b200041063a00000c040b200041063a0000200541ffffff3f71450d030c020b200041063a00000c020b1030000b200310290b200241c0076a24000be5c20208087f027e047f077e0d7f027e037f037e23004190126b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002005411b4b0d1f200141046a210720050e1c0102030405060708090a0b0c0d0e0f101112131415161718191d1e20010b2000411c3602000c660b02402006450d0020042d0001210520012003417e6a22083602042001200441026a360200200541094b0d00410a21094200210a4200210b02400240024002400240024002400240024002400240024020050e0a00010203040506070809000b20084104490d0b2004280002210620012003417a6a3602042001200441066a3602002006418194ebdc034f0d0b410121094200210b0c080b2002200110c80120022802000d0a200728020020022802042204490d0a2004417f4c0d2b0240024020040d004200210b410121060c010b2004102d2206450d2420072802002004490d0a20062001280200200410e4071a200128020422032004490d2d2001200320046b3602042001200128020020046a3602002004ad210b0b2006450d0a200b2004ad42208684220b422088210a410221090c070b20084108490d092004290002210b2001200341766a36020420012004410a6a360200200b422088210a410321090c060b200241086a200110c80120022802080d082007280200200228020c2204490d082004417f4c0d290240024020040d004200210b410121060c010b2004102d2206450d2220072802002004490d0820062001280200200410e4071a200128020422032004490d2c2001200320046b3602042001200128020020046a3602002004ad210b0b2006450d08200b2004ad42208684220b422088210a410421090c050b200241106a200110c80120022802100d07200728020020022802142204490d072004417f4c0d280240024020040d004200210b410121060c010b2004102d2206450d2120072802002004490d0720062001280200200410e4071a200128020422032004490d2c2001200320046b3602042001200128020020046a3602002004ad210b0b2006450d07200b2004ad42208684220b422088210a410521090c040b2008450d0620042d0002210520012003417d6a22073602042001200441036a360200200541014b0d06410021060240024020050e020100010b20074104490d072004350003210b2001200341796a22053602042001200441076a36020020054104490d072004350007210a2001200341756a36020420012004410b6a360200200a422086200b84210b410121060b200b422088210a410621090c030b200241286a200110c80120022802280d05200228022c2209200728020041186e2204200420094b1bad42187e220b422088a70d26200ba72204417f4c0d260240024020040d00410421060c010b200410272206450d1f0b41002105200241003602c80d200220063602c00d2002200441186e3602c40d024002400240024002402009450d000340200241206a200110c80120022802200d05200728020020022802242204490d052004417f4c0d2c0240024020040d004100210c4101210d0c010b2004102d220d450d2520072802002004490d05200d2001280200200410e4071a200128020422032004490d312001200320046b3602042001200128020020046a3602002004210c0b200241186a200110c80120022802180d032007280200200228021c2203490d032003417f4c0d2c0240024020030d004100210e410121080c010b2003102d2208450d2520072802002003490d0320082001280200200310e4071a2001280204220e2003490d322001200e20036b3602042001200128020020036a3602002003210e0b2004ad422086200cad84210b2003ad422086200ead84210a0240200520022802c40d470d00200241c00d6a2005410110990120022802c00d210620022802c80d21050b2006200541186c6a2204200836020c2004200b3702042004200d360200200441106a200a3702002002200541016a22053602c80d2009417f6a22090d000b0b2006450d0920022902c40d220a420020061b210b200a422088420020061b210a410721090c060b200810290b200c450d010b200d10290b02402005450d00200541186c21042006210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141186a2101200441686a22040d000b0b20022802c40d2201450d05200141186c0d040c050b200241c00d6a2001109e0420022802c00d2206450d0441082109200241c00d6a41086a350200220a42208620023502c40d84210b0c010b200241306a200110c80120022802300d03200728020020022802342204490d032004417f4c0d240240024020040d004200210b410121060c010b2004102d2206450d1d20072802002004490d0320062001280200200410e4071a200128020422032004490d2b2001200320046b3602042001200128020020046a3602002004ad210b0b2006450d03200b2004ad42208684210b200728020022044104490d0120012802002203280000210d20012004417c6a3602042001200341046a360200200b422088210a410921090b20004100360200200041186a200d3602002000410c6a2006360200200041086a2009360200200041106a200a422086200b42ffffffff0f8384370200200041206a200241e80f6a41880210e4071a0c680b200ba7450d010b200610290b2000411c3602000c650b2006450d6220042d0001210520012003417e6a22063602042001200441026a360200200541034b0d6202400240024002400240024020050e0400010203000b20064104490d672004280002210520012003417a6a22063602042001200441066a3602002006450d6720042d0006210d2001200341796a22083602042001200441076a220c360200200d41014b0d674100210602400240200d0e020100010b20084104490d68200428000721092001200341756a220636020420012004410b6a36020020064104490d68200428000b21072001200341716a220836020420012004410f6a220c360200410121060b2008450d67200c2d0000210320012008417f6a3602042001200c41016a360200200241e80f6a200110e40320022802e80f2101200241c00d6a200241e80f6a41047241a40210e4071a2001411c460d67200241e80f6a200241c00d6a41a40210e4071a41a802102722040d030c680b200241003602e80f20064104490d662004280002210520012003417a6a22063602042001200441066a360200200241003602e80f20064104490d66200428000621062001200341766a36020420012004410a6a36020020022802d409210820022802d80921014102210c4100210e410021074100210f410021040c030b200241386a200110c80120022802380d652007280200200228023c2204490d652004417f4c0d220240024020040d004200210b410121050c010b2004102d2205450d1b20072802002004490d6520052001280200200410e4071a200128020422032004490d2a2001200320046b3602042001200128020020046a3602002004ad210b0b2005450d652004ad422086200b84220ba721060240024002400240200728020022034104490d0020012802002204280000210720012003417c6a220d3602042001200441046a2209360200200d450d0120092d0000210c20012003417b6a220e3602042001200941016a220f360200200c41014b0d014100210402400240200c0e020100010b200e4104490d022009280001210d2001200341776a22043602042001200941056a36020020044104490d02200928000521082001200341736a220e3602042001200941096a220f360200410121040b200e450d03200f2d000021032001200e417f6a3602042001200f41016a360200200241e80f6a200110e40320022802e80f210c200241c00d6a200241e80f6a41047241a40210e4071a200c411c470d020b2006450d680c670b20060d660c670b200241e80f6a200241c00d6a41a40210e4071a41a80210272201450d67200b422088a721092001200c360200200141046a200241e80f6a41a40210e4071a2007418080807871210e4103210c4100210f0c030b20060d640c650b200241c0006a200110c80120022802400d64200728020020022802442204490d642004417f4c0d210240024020040d004200210b410121050c010b2004102d2205450d1a20072802002004490d6420052001280200200410e4071a200128020422032004490d2a2001200320046b3602042001200128020020046a3602002004ad210b0b2005450d64200b2004ad42208684220b422088a7210920022800c90b210120022800c50b210820022800c10b210d200ba721064104210c4100210e410021074100210f410021040c010b20042001360200200441046a200241e80f6a41a40210e4071a2004418080807871210f2007418080807871210e4101210c0b200020033a00052000200c3a000420004101360200200041246a2001360200200041206a20083602002000411c6a200d360200200041086a2005360200200041186a200f200441ffffff077172360200200041146a200e200741ffffff0771723602002000410c6a2009ad4220862006ad84370200200041286a200241a8076a41800210e4071a0c640b02402006450d0020012003417e6a3602042001200441026a3602000b2000411c3602000c630b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241c8006a200110aa052002290348a70d002002290350210b20004103360200200041086a200b370300200041106a200241e80f6a41980210e4071a0c630b2000411c3602000c620b02402006450d0020042d0001210520012003417e6a22063602042001200441026a360200200541034b0d00024002400240024020050e0400010203000b20064104490d032004280002210d20012003417a6a3602042001200441066a36020020022802ec092204411876210120022f01ea0922034108762107200241d0096a41186a310000210a20022902e009210b20022802d809210520022802dc09210620022d00e9092108410121090c600b41002105200241003a00e00d2003417e6a2109417d21060240034020092005460d01200241c00d6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200241bf096a20022800d30d22064118763a0000200241bb096a20022800cf0d22054118763a0000200220022900d70d220b3c00c009200220063a00bc09200220053a00b809200220022900c70d22103703b009200220064108763b00bd09200220054108763b00b9092002200b4208883e00c1092002200b422888200241df0d6a310000220a421886843e00c509200320076b2203417e6a4104490d0320022800c30d210d20022f00c10d210c20022d00c00d210e41022109200420076a220741026a280000210420012003417a6a3602042001200741066a36020020044118762101410021070c610b200541ff0171450d02200241003a00e00d0c020b20064104490d012004280002210d20012003417a6a3602042001200441066a36020020022f01ec09200241ee096a2d0000411074722104200241e8096a310000210a20022903e009210b20022802d809210520022802dc09210620022d00e909210820022d00ea09210320022d00eb09210720022d00ef092101410321090c5e0b41002105200241003a00e00d2003417e6a2109417d21060240034020092005460d01200241c00d6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b41042109200320076b2203417e6a4104490d01200241df0d6a310000210a20022900d70d210b20022800d30d210620022800cf0d210520022900c70d211020022800c30d210d20022f00c10d210c20022d00c00d210e200420076a220741026a280000210420012003417a6a3602042001200741066a36020020044118762101410021070c5f0b200541ff0171450d00200241003a00e00d0b2000411c3602000c610b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541034b0d00024002400240024020050e0400010203000b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241df0d6a310000210b20022900d70d210a20022800d30d210d20022800cf0d210820022900c70d211020022800c30d210c20022f00c10d210e20022d00c00d210f200241d8006a20011084022002290358a70d04200241e8006a2903002111200229036021124101210141002106410021070c5f0b200541ff0171450d03200241003a00e00d0c030b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241df0d6a310000210b20022900d70d210a20022800d30d210d20022800cf0d210820022900c70d211020022800c30d210c20022f00c10d210e20022d00c00d210f20024188016a2001108402200229038801a70d0320024188016a41106a29030021112002290390012112200241f0006a20011084022002290370a70d03200241f0006a41106a29030021132002290378211442002115410221014100210642002116410021070c5e0b200541ff0171450d02200241003a00e00d0c020b41002105200241003a00e00d410220036b21092003417d6a2106024002400340200920056a450d01200241c00d6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200241df0d6a310000210b20022900d70d210a20022800d30d210d20022800cf0d210820022900c70d211020022800c30d210c20022f00c10d210e20022d00c00d210f41002105200241003a00e00d200420076a2109200720036b41026a21030340200320056a450d02200241c00d6a20056a200920056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a00e00d2006417f6a21062004210520044120470d000b200241bf096a20022800d30d22044118763a0000200241bb096a20022800cf0d22034118763a0000200220022900d70d22143c00c009200220043a00bc09200220033a00b809200220022900c70d3703b009200220044108763b00bd09200220034108763b00b909200220144208883e00c10920022014422888200241df0d6a3100002213421886843e00c50920022800c30d210320022f00c10d210420022d00c00d2105200241a0016a200110840220022903a001a70d0320022903a8012115200241b0016a2903002216423888a721072016421888a72106200241b0096a41086a290300211120022903b0092112410321010c5e0b200541ff0171450d02200241003a00e00d0c020b200541ff0171450d01200241003a00e00d0c010b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241df0d6a310000210b20022900d70d210a20022800d30d210d20022800cf0d210820022900c70d211020022800c30d210c20022f00c10d210e20022d00c00d210f200241b8016a200110840220022903b801a70d01200241c8016a290300211120022903c0012112200241e8096a330100200241ea096a31000042108684211620022903e009211520022d00ef09210720022800eb092106410421010c5c0b200541ff0171450d00200241003a00e00d0b2000411c3602000c600b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241d0016a200110c80120022802d0010d0020022802d4012206200728020041f0006e2204200420064b1bad42f0007e220b422088a70d1b200ba72203417f4c0d1b0240024020030d00410421090c010b200310272209450d140b41002104200241003602d809200220093602d0092002200341f0006e3602d409024002402006450d00200241c00d6a41086a210d0340200241c00d6a200110f80220022802c40d210320022802c00d2107200241a8076a200d41e80010e4071a2003450d02200241c00b6a200241a8076a41e80010e4071a0240200420022802d409470d00200241d0096a2004410110970120022802d009210920022802d80921040b2009200441f0006c6a2205200336020420052007360200200541086a200241c00b6a41e80010e4071a2002200441016a22043602d8092006417f6a22060d000b0b2009450d0120022902d409210b2000200936020420004106360200200041086a200b370200200041106a200241e80f6a41980210e4071a0c610b02402004450d00200441f0006c2104200941046a21010340200110d3020240200141046a2802002203450d00200341246c450d00200128020010290b200141f0006a2101200441907f6a22040d000b0b20022802d4092201450d00200141f0006c450d00200910290b2000411c3602000c5f0b2006450d5220042d0001210520012003417e6a22173602042001200441026a360200200541174b0d524107210f0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e180001020304056e060708090a0b0c0d0e0f10111213141516000b41002105200241003a00e00d2003417e6a21092003417d6a21030240034020092005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241df0d6a310000211320022900d70d211020022800d30d211820022800cf0d210820022900c70d211420022800c30d210920022f00c10d210e20022d00c00d210d200241d8016a200110840220022903d801a70d6920072802002204450d69200241e8016a290300210a20022903e001210b200128020022032d0000211920012004417f6a3602044101210f2001200341016a360200201941024b0d69200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241d0096a41046a2f01003b0100200220022801d0093602a0072010422888201342188684a721062010420888a7211a2014422088a7211b2010a7211c2014a7210c0c6e0b200541ff0171450d68200241003a00e00d0c680b200241f0016a200110840220022903f001a70d6720024180026a290300210b20022903f801210a200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241c00d6a41046a2f01003b0100200220022801c00d3602a007200a422088a7211b200b422088a72118200aa7210c200ba721084102210f0c6b0b20024188026a2001108402200229038802a70d6620024198026a290300210b200229039002210a200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241c00d6a41046a2f01003b0100200220022801c00d3602a007200a422088a7211b200b422088a72118200aa7210c200ba721084103210f0c6a0b4104210f20174104490d652004280002210920012003417a6a3602042001200441066a360200200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241c00d6a41046a2f01003b0100200220022801c00d3602a0070c680b200241a0026a200110c80120022802a0020d6420022802a4022109200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241c00d6a41046a2f01003b0100200220022801c00d3602a0074105210f0c670b200241c00d6a200110960220022802c00d2209450d63200241c80d6a280200211b20022802c40d210c200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241d0096a41046a2f01003b0100200220022801d0093602a0074106210f0c650b2017450d6220042d0002210d20012003417d6a3602042001200441036a360200200d41024b0d62200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241c00d6a41046a2f01003b0100200220022801c00d3602a0074108210f4100211a4100210641002118410021084100211b0c670b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241df0d6a310000211020022800d30d211820022800cf0d210820022800c30d210920022f00c10d210e20022d00c00d210d20022900c70d210a20022900d70d210b200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241d0096a41046a2f00003b0100200220022800d0093602a007200b422888201042188684a72106200b420888a7211a200a422088a7211b200ba7211c200aa7210c4109210f0c630b200541ff0171450d61200241003a00e00d0c610b200241a8026a200110c80120022802a8020d6020022802ac022109200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241c00d6a41046a2f01003b0100200220022801c00d3602a007410a210f0c630b410b210f0c640b410c210f0c630b200241c00d6a200110960220022802c00d2209450d5d20022902c40d210b200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241d0096a41046a2f01003b0100200220022801d0093602a007200b422088a7211b200ba7210c410d210f0c5f0b41002105200241003a00e00d2003417e6a2109417d21060240034020092005460d01200241c00d6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200320076b2203417e6a4104490d5d200241df0d6a310000211020022900d70d210b20022800d30d211820022800cf0d210820022900c70d210a20022800c30d210920022f00c10d210e20022d00c00d210d200420076a220441026a280000211d20012003417a6a3602042001200441066a360200200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241d0096a41046a2f01003b0100200220022801d0093602a007200b422888201042188684a72106200b420888a7211a200a422088a7211b200ba7211c200aa7210c410e210f0c5e0b200541ff0171450d5c200241003a00e00d0c5c0b410f210f0c600b20174104490d5a2004280002210920012003417a6a3602042001200441066a360200200241b0026a200110c80120022802b0020d5a200728020020022802b4024102742204490d5a2004417f4c0d210240024020040d004200210b4101210c0c010b2004102d220c450d1a20072802002004490d2c200c2001280200200410e4071a200128020422032004490d2b2001200320046b3602042001200128020020046a3602002004ad210b0b200c450d5a0240200b2004ad42208684220b422088a722010d00200ba721010c580b0240200c2001724103710d00200ba722014103710d002001410276221b450d58200b422288a721080c590b200ba7450d5a200c10290c5a0b20174104490d592004280002210920012003417a6a3602042001200441066a360200200241b8026a200110c80120022802b8020d5920022802bc02220e200728020041246e22042004200e4b1bad42247e220b422088a70d20200ba72204417f4c0d200240024020040d004104210c0c010b20041027220c450d190b41002108200241003602d8092002200c3602d0092002200441246e221b3602d409024002400240200e450d00200241c00d6a411f6a2118410021084100210f0340200241003a00e00d200f41016a210f20072802002106417f210341002104034020062004460d03200241c00d6a20046a2001280200220d2d00003a00002001200620036a3602042001200d41016a3602002002200441016a22053a00e00d2003417f6a21032005210420054120470d000b200620056b22044104490d032018310000210b20022900d70d210a20022800d30d210320022800cf0d210520022900c70d211020022800c30d210620022f00c10d211b20022d00c00d2119200d280001211e2001200d41056a36020020012004417c6a3602040240200820022802d409470d00200241d0096a2008410110960120022802d009210c20022802d80921080b200c200841246c6a2204200a3700172004201e360220200420033600132004200536000f20042010370007200420063600032004201b3b0001200420193a00002004411f6a200b3c00002002200841016a22083602d809200f200e470d000b20022802d409211b0b200c450d5b200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241b0096a41046a2f01003b0100200220022801b0093602a0074111210f0c5a0b200441ff0171450d00200241003a00e00d0b20022802d4092201450d59200141246c450d59200c10290c590b20174104490d582004280002210920012003417a6a3602042001200441066a360200200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241c00d6a41046a2f01003b0100200220022801c00d3602a0074112210f0c5b0b41002105200241003a00e00d2003417e6a2109417d21060240034020092005460d01200241c00d6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200320076b2203417e6a4104490d58200241c00d6a411f6a310000211020022900d70d210b20022800d30d210520022800cf0d210620022900c70d210a20022800c30d210920022f00c10d210e20022d00c00d210d200420076a220441026a280000211d20012003417a6a3602042001200441066a3602002002200b3700e709200241d0096a411f6a20103c0000200220053600e309200220063600df092002200e4108763a00d2092002200e410874200d41ff0171723b01d009200220093600d3092002200a3700d70920022900df092114200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241b0096a41046a2f01003b0100200220022801b0093602a007200b422888201042188684a72106200b420888a7211a200a422088a7211b2014422088a72118200ba7211c200aa7210c2014a721084113210f0c590b200541ff0171450d57200241003a00e00d0c570b200241c0026a200110840220022903c002a70d56200241d0026a290300210b20022903c802210a200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241c00d6a41046a2f01003b0100200220022801c00d3602a007200a422088a7211b200b422088a72118200aa7210c200ba721084114210f0c5a0b200241e0026a200110c80120022802e0020d5520022802e4022109200241d8026a200110c80120022802d8020d5520022802dc02210c200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241c00d6a41046a2f01003b0100200220022801c00d3602a0074115210f4100211a410021060c5a0b41002105200241003a00e00d2003417e6a2109417d21060240034020092005460d01200241c00d6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200220022900d70d220b3e00e709200220022900cf0d3700df09200220022900c70d3700d709200220022800c30d22093600d309200220022f00c10d3b00d109200220022d00c00d3a00d0092002200b4220883e00eb092002200241df0d6a2d00003a00ef09200320076b2203417e6a4104490d55200420076a220441026a280000211d20012003417a6a3602042001200441066a360200200241b0096a41186a200241d0096a410772220141186a2d00003a0000200241b0096a41106a200141106a2900002210370300200241b0096a41086a200141086a290000220b37030020022001290000220a3703b00920022f01d009210120022d00d209210420022800c509210620022800c109211a200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241ca096a41046a2f01003b0100200220022801ca093602a0072001200441107472220d410876210e2010a7211c200ba72108200a422088a7211b200b422088a72118200aa7210c4116210f0c560b200541ff0171450d54200241003a00e00d0c540b200241f8026a200110c80120022802f8020d53200728020020022802fc024101742204490d532004417f4c0d1a0240024020040d0041002103410121090c010b2004102d2209450d1320072802002004490d5020092001280200200410e4071a200128020422032004490d262001200320046b3602042001200128020020046a360200200421030b2009450d5302402004ad4220862003ad84220b422088a722040d00200ba721040c4e0b024020092004724101710d00200ba722044101710d002004410176220c450d4e200b422188a7211b0c4f0b200ba70d4f0c530b20024190036a200110c8012002280290030d5220072802002002280294034101742204490d522004417f4c0d190240024020040d0041002103410121090c010b2004102d2209450d1220072802002004490d4f20092001280200200410e4071a200128020422032004490d262001200320046b3602042001200128020020046a360200200421030b2009450d5202402004ad4220862003ad84220b422088a722040d00200ba721040c4b0b024020092004724101710d00200ba722044101710d002004410176220c450d4b200b422188a7211b0c4c0b200ba70d4e0c520b02402006450d0020012003417e6a3602042001200441026a3602000b2000411c3602000c5d0b2006450d2620042d0001210520012003417e6a3602042001200441026a360200200541014b0d26410021040240024020050e020001000b200241e80f6a200110c70320022d00e80f4101460d27200241c00d6a200241e80f6a41017241a00110e4071a20024198036a200110c8012002280298030d272007280200200228029c032203490d272003417f4c0d180240024020030d004200210b410121040c010b2003102d2204450d1120072802002003490d2720042001280200200310e4071a200128020422052003490d262001200520036b3602042001200128020020036a3602002003ad210b0b2004450d27200b2003ad42208684210b200241a8076a200241c00d6a41a00110e4071a0b200241c00b6a200241a8076a41a00110e4071a200041086a200b3702002000200436020420004109360200200041106a200241c00b6a41a00110e4071a200041b0016a200241d0096a41f80010e4071a0c5c0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241a0036a200110c80120022802a0030d0020022802a40321012000410a36020020002001360204200041086a200241e80f6a41a00210e4071a0c5c0b2000411c3602000c5b0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241c00b6a200110b40320022903c80b220b4202510d0020022903c00b210a200241d0096a200241c00b6a41106a220441f00110e4071a200241c00b6a200110b50320022802c40b450d00200241b0096a41106a22012004280200360200200241b0096a41086a2204200241c00b6a41086a290300370300200220022903c00b3703b009200241e80f6a200241d0096a41f00110e4071a200241e8116a2001280200360200200241e0116a2004290300370300200220022903b0093703d811200241c00d6a200241e80f6a41880210e4071a200241a8076a200241c00d6a41880210e4071a200041106a200b370200200041086a200a3702002000410b360200200041186a200241a8076a41880210e4071a0c5b0b2000411c3602000c5a0b02402006450d0020042d0001210520012003417e6a22063602042001200441026a36020020050d0020064104490d002004280002210520012003417a6a3602042001200441066a360200200241b8036a200110c80120022802b8030d00200728020020022802bc032204490d002004417f4c0d1502400240024002400240024002400240024020040d0041002103410121060c010b2004102d2206450d1520072802002004490d0120062001280200200410e4071a200128020422032004490d2d2001200320046b3602042001200128020020046a360200200421030b2006450d07200241b0036a200110c8012004ad4220862003ad84220aa7210e024020022802b0030d0020022802b403220d2007280200410c6e22042004200d4b1bad420c7e220b422088a70d1d200ba72204417f4c0d1d0240024020040d00410421080c010b200410272208450d160b41002103200241003602c80d200220083602c00d20022004410c6e22093602c40d024002400240200d450d00410021030340200241a8036a200110c80120022802a8030d03200728020020022802ac032204490d032004417f4c0d210240024020040d004100210c410121090c010b2004102d2209450d1a20072802002004490d0320092001280200200410e4071a2001280204220c2004490d332001200c20046b3602042001200128020020046a3602002004210c0b2004ad422086200cad84210b0240200320022802c40d470d00200241c00d6a20034101109d0120022802c00d210820022802c80d21030b20082003410c6c6a2204200b370204200420093602002002200341016a22033602c80d200d417f6a220d0d000b20022802c40d21090b2008450d022006450d0a200728020022074104490d042001280200220c280000211820012007417c6a22043602042001200c41046a36020020044104490d05200c280004211b2001200741786a22043602042001200c41086a36020020044104490d06200a422088a72119200c280008211e2001200741746a220f3602042001200c410c6a36020041002104200241003a00800e200741736a21070340200f2004460d08200241c00d6a20046a200c20046a220d410c6a2d00003a0000200120073602042001200d410d6a3602002002200441016a220d3a00800e2007417f6a2107200d2104200d41c000470d000b200d41ff017141c000490d082006450d0a200241fb0d6a2d0000210120022f00f90d2104200241db0d6a2d0000210720022f00d90d210d200241e80d6a290300210b20022903e00d210a20022802fc0d210c20022d00f80d210f20022802f40d211f20022f01f20d212020022d00f00d212120022802dc0d211c20022d00d80d211a20022903d00d211020022802cc0d211d20022802c80d211720022802c40d212220022802c00d2123200020022d00f10d3a005d200020053602042000410c360200200041e7006a200420014110747222014110763a0000200041e5006a20013b0000200041c7006a200d20074110747222014110763a0000200041c5006a20013b0000200041d4006a200b370200200041cc006a200a370200200041e8006a200c360200200041e4006a200f3a0000200041e0006a201f360200200041de006a20203b0100200041dc006a20213a0000200041c8006a201c360200200041c4006a201a3a00002000413c6a2010370200200041386a201d360200200041346a2017360200200041306a20223602002000412c6a2023360200200041286a201e360200200041246a201b360200200041206a20183602002000411c6a2003360200200041186a2009360200200041146a2008360200200041106a20193602002000410c6a200e360200200041086a2006360200200041ec006a200241e80f6a41bc0110e4071a0c640b200910290b02402003450d002003410c6c21042008210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b20022802c40d2201450d002001410c6c450d00200810290b200e450d070b200610290c060b0240200e450d00200610290b02402003450d002003410c6c21042008210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b2009450d052009410c6c0d040c050b0240200e450d00200610290b02402003450d002003410c6c21042008210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b2009450d042009410c6c0d030c040b0240200e450d00200610290b02402003450d002003410c6c21042008210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b2009450d032009410c6c0d020c030b200441ff0171450d00200241003a00800e0b0240200e450d00200610290b02402003450d002003410c6c21042008210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b2009450d012009410c6c450d010b200810290b2000411c3602000c590b02402006450d0020012003417e6a3602042001200441026a3602000b2000411c3602000c580b02402006450d0020042d0001210520012003417e6a22183602042001200441026a3602002005411e4b0d00410e210c02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e1f000102030405060708090a0b0c610d0e0f101112131415161718191a1b1c1d000b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241a8076a41086a200241d70d6a290000220b370300200241ca096a41026a220420022d00c20d3a0000200241c00b6a41086a2203200b370300200241c00b6a41106a2205200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01ca092002200b3703c00b20022800cb0d210920022800c70d210d20022800c30d2106200241c0036a200110840220022903c003a70d1e200241c0036a41106a290300210a20022903c803210b200241a0076a41026a20042d00003a0000200241d0096a41086a2003290300370300200241d0096a41106a20052d00003a0000200220022f01ca093b01a007200220022903c00b3703d0094101210c0c610b200541ff0171450d1d200241003a00e00d0c1d0b200241e0036a200110c80120022802e0030d1c20022802e4032106200241d8036a200110c80120022802d8030d1c20022802dc03210d4102210c200241a0076a41026a200241a8076a41026a2d00003a0000200241d0096a41086a200241c00d6a41086a290200370300200241d0096a41106a200241c00d6a41106a2d00003a0000200220022f00a8073b01a007200220022902c00d3703d0090c5f0b200241e8036a200110c80120022802e8030d1b20022802ec032106200241c00d6a200110ab0520022d00c00d4102460d1b200241d0096a41086a200241c00d6a41106a290300370300200241d0096a41106a200241d80d6a2d00003a0000200241a0076a41026a200241a8076a41026a2d00003a00002002200241c00d6a41086a2903003703d009200220022f00a8073b01a007200241d90d6a2d00002108200241da0d6a2f0100210f200241dc0d6a280200210e200241e00d6a290300210b20022802c40d210920022802c00d210d4200210a4103210c0c5e0b200241f0036a200110c80120022802f0030d1a20022802f4032106200241c00d6a200110ab0520022d00c00d4102460d1a200241d0096a41086a200241c00d6a41106a290300370300200241d0096a41106a200241d80d6a2d00003a0000200241a0076a41026a200241a8076a41026a2d00003a00002002200241c00d6a41086a2903003703d009200220022f00a8073b01a007200241d90d6a2d00002108200241da0d6a2f0100210f200241dc0d6a280200210e200241e00d6a290300210b20022802c40d210920022802c00d210d4200210a4104210c0c5d0b20184104490d192004280002210620012003417a6a3602042001200441066a360200200241a0076a41026a200241a8076a41026a2d00003a0000200241d0096a41086a200241c00d6a41086a290200370300200241d0096a41106a200241c00d6a41106a2d00003a0000200220022f00a8073b01a007200220022902c00d3703d0094105210c0c5c0b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241a8076a41086a200241d70d6a290000220b370300200241a2076a20022d00c20d3a0000200241d0096a41086a200b370300200241e0096a200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01a0072002200b3703d00920022800cb0d210920022800c70d210d20022800c30d21064106210c0c5c0b200541ff0171450d18200241003a00e00d0c180b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241a8076a41086a200241d70d6a290000220b370300200241a2076a20022d00c20d3a0000200241d0096a41086a200b370300200241e0096a200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01a0072002200b3703d00920022800cb0d210920022800c70d210d20022800c30d21064107210c0c5b0b200541ff0171450d17200241003a00e00d0c170b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b4108210c200241a8076a41086a200241d70d6a290000220b370300200241a2076a20022d00c20d3a0000200241d0096a41086a200b370300200241e0096a200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01a0072002200b3703d00920022800cb0d210920022800c70d210d20022800c30d21060c5a0b200541ff0171450d16200241003a00e00d0c160b41002105200241003a00e00d2003417e6a2109417d21060240034020092005460d01200241c00d6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200241a8076a41086a200241d70d6a290000220b370300200241ca096a41026a20022d00c20d3a0000200241c00b6a41086a200b370300200241d00b6a200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01ca092002200b3703c00b200320076b2203417e6a4104490d1620022800cb0d210920022800c70d210d20022800c30d2106200420076a220441026a280000210e20012003417a6a22053602042001200441066a220736020020054104490d16200241a0076a41026a200241ca096a41026a2d00003a00002007350000210b2001200341766a36020420012004410a6a360200200241d0096a41086a200241c00b6a41086a290300370300200241d0096a41106a200241c00b6a41106a2d00003a0000200220022f01ca093b01a007200220022903c00b3703d0094200210a4109210c0c590b200541ff0171450d15200241003a00e00d0c150b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241a8076a41086a200241d70d6a290000220b370300200241a2076a20022d00c20d3a0000200241d0096a41086a200b370300200241e0096a200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01a0072002200b3703d00920022800cb0d210920022800c70d210d20022800c30d2106410a210c0c580b200541ff0171450d14200241003a00e00d0c140b200241f8036a200110c80120022802f8030d1320022802fc032106200241a0076a41026a200241a8076a41026a2d00003a0000200241d0096a41086a200241c00d6a41086a290200370300200241d0096a41106a200241c00d6a41106a2d00003a0000200220022f00a8073b01a007200220022902c00d3703d009410b210c0c560b20184104490d122004280002210620012003417a6a3602042001200441066a360200200241a0076a41026a200241a8076a41026a2d00003a0000200241d0096a41086a200241c00d6a41086a290200370300200241d0096a41106a200241c00d6a41106a2d00003a0000200220022f00a8073b01a007200220022902c00d3703d009410c210c0c550b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241a8076a41086a200241d70d6a290000220b370300200241a2076a20022d00c20d3a0000200241d0096a41086a200b370300200241e0096a200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01a0072002200b3703d00920022800cb0d210920022800c70d210d20022800c30d2106410d210c0c550b200541ff0171450d11200241003a00e00d0c110b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241a8076a41086a200241d70d6a290000220b370300200241a2076a20022d00c20d3a0000200241d0096a41086a200b370300200241e0096a200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01a0072002200b3703d00920022800cb0d210920022800c70d210d20022800c30d2106410f210c0c540b200541ff0171450d10200241003a00e00d0c100b41002105200241003a00e00d2003417e6a2109417d21070240034020092005460d01200241c00d6a20056a200420056a220641026a2d00003a00002001200320076a3602042001200641036a3602002002200541016a220e3a00e00d2007417f6a2107200e2105200e4120470d000b200241a8076a41086a200241d70d6a290000220b370300200241ca096a41026a20022d00c20d3a0000200241c00b6a41086a200b370300200241d00b6a200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01ca092002200b3703c00b2003417e6a200e460d1020022800cb0d210920022800c70d210d20022800c30d21062004200e6a220441026a2d000021082001200320076a22053602042001200441036a360200200841074f0d104110210c20054110490d10200241a0076a41026a200241ca096a41026a2d00003a00002004410b6a290000210a200441036a290000210b20012003200e6b416d6a3602042001200441136a360200200241d0096a41086a200241c00b6a41086a290300370300200241d0096a41106a200241c00b6a41106a2d00003a0000200220022f01ca093b01a007200220022903c00b3703d0090c530b200541ff0171450d0f200241003a00e00d0c0f0b4111210c0c510b4112210c0c500b20024180046a200110c8012002280280040d0c20072802002002280284042204490d0c2004417f4c0d1f02400240024020040d004200210b410121060c010b2004102d2206450d1920072802002004490d0120062001280200200410e4071a200128020422032004490d332001200320046b3602042001200128020020046a3602002004ad210b0b2006450d0d200241a0076a41026a200241a8076a41026a2d00003a0000200241d0096a41086a200241c00d6a41086a290300370300200241d0096a41106a200241c00d6a41106a2d00003a0000200220022f00a8073b01a007200220022903c00d3703d009200b2004ad42208684220b422088a72109200ba7210d4113210c0c500b200610290c0c0b20024188046a200110c8012002280288040d0b2007280200200228028c042204490d0b2004417f4c0d1e02400240024020040d004200210b410121060c010b2004102d2206450d1820072802002004490d0120062001280200200410e4071a200128020422032004490d332001200320046b3602042001200128020020046a3602002004ad210b0b2006450d0c200241a0076a41026a200241a8076a41026a2d00003a0000200241d0096a41086a200241c00d6a41086a290300370300200241d0096a41106a200241c00d6a41106a2d00003a0000200220022f00a8073b01a007200220022903c00d3703d009200b2004ad42208684220b422088a72109200ba7210d4114210c0c4f0b200610290c0b0b20024190046a200110c8012002280290040d0a20072802002002280294042204490d0a2004417f4c0d1d02400240024020040d004200210b410121060c010b2004102d2206450d1720072802002004490d0120062001280200200410e4071a200128020422032004490d332001200320046b3602042001200128020020046a3602002004ad210b0b2006450d0b200241a0076a41026a200241a8076a41026a2d00003a0000200241d0096a41086a200241c00d6a41086a290300370300200241d0096a41106a200241c00d6a41106a2d00003a0000200220022f00a8073b01a007200220022903c00d3703d009200b2004ad42208684220b422088a72109200ba7210d4115210c0c4e0b200610290c0a0b20024198046a200110c8012002280298040d092007280200200228029c042204490d092004417f4c0d1c02400240024020040d004200210b410121060c010b2004102d2206450d1620072802002004490d0120062001280200200410e4071a200128020422032004490d332001200320046b3602042001200128020020046a3602002004ad210b0b2006450d0a200241a0076a41026a200241a8076a41026a2d00003a0000200241d0096a41086a200241c00d6a41086a290300370300200241d0096a41106a200241c00d6a41106a2d00003a0000200220022f00a8073b01a007200220022903c00d3703d009200b2004ad42208684220b422088a72109200ba7210d4116210c0c4d0b200610290c090b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b4117210c200241a8076a41086a200241c00d6a41176a290000220b370300200241ca096a41026a220420022d00c20d3a0000200241c00b6a41086a2203200b370300200241c00b6a41106a2205200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01ca092002200b3703c00b20022800cb0d210920022800c70d210d20022800c30d2106200241a0046a200110c80120022802a0040d0920022802a404210e200241a0076a41026a20042d00003a0000200241d0096a41086a2003290300370300200241d0096a41106a20052d00003a0000200220022f01ca093b01a007200220022903c00b3703d0090c4c0b200541ff0171450d08200241003a00e00d0c080b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241a8076a41086a200241d70d6a290000220b370300200241a2076a20022d00c20d3a0000200241d0096a41086a200b370300200241e0096a200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01a0072002200b3703d00920022800cb0d210920022800c70d210d20022800c30d21064118210c0c4b0b200541ff0171450d07200241003a00e00d0c070b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241a8076a41086a200241d70d6a290000220b370300200241a2076a20022d00c20d3a0000200241d0096a41086a200b370300200241e0096a200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01a0072002200b3703d00920022800cb0d210920022800c70d210d20022800c30d21064119210c0c4a0b200541ff0171450d06200241003a00e00d0c060b20184104490d052004280002210620012003417a6a3602042001200441066a360200200241a0076a41026a200241a8076a41026a2d00003a0000200241d0096a41086a200241c00d6a41086a290300370300200241d0096a41106a200241c00d6a41106a2d00003a0000200220022f00a8073b01a007200220022903c00d3703d009411a210c0c480b41002105200241003a00e00d2003417e6a2109417d21060240034020092005460d01200241c00d6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200241a8076a41086a200241d70d6a290000220b370300200241ca096a41026a220520022d00c20d3a0000200241c00b6a41086a2208200b370300200241c00b6a41106a220c200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01ca092002200b3703c00b200320076b2203417e6a4104490d0520022800cb0d210920022800c70d210d20022800c30d2106200420076a220441026a280000210e20012003417a6a3602042001200441066a360200200241a0076a41026a20052d00003a0000200241d0096a41086a2008290300370300200241d0096a41106a200c2d00003a0000200220022f01ca093b01a007200220022903c00b3703d009411b210c0c480b200541ff0171450d04200241003a00e00d0c040b41002105200241003a00e00d2003417e6a2109417d21070240034020092005460d01200241c00d6a20056a200420056a220641026a2d00003a00002001200320076a3602042001200641036a3602002002200541016a220c3a00e00d2007417f6a2107200c2105200c4120470d000b200241a8076a41086a200241d70d6a290000220b370300200241ca096a41026a20022d00c20d3a0000200241c00b6a41086a200b370300200241d00b6a200241df0d6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01ca092002200b3703c00b2003417e6a200c460d0420022800cb0d210920022800c70d210d20022800c30d21062004200c6a220441026a2d000021082001200320076a22053602042001200441036a360200200841074f0d0420054110490d04200241a0076a41026a200241ca096a41026a2d00003a00002004410b6a290000210a200441036a290000210b20012003200c6b416d6a3602042001200441136a360200200241d0096a41086a200241c00b6a41086a290300370300200241d0096a41106a200241c00b6a41106a2d00003a0000200220022f01ca093b01a007200220022903c00b3703d009411c210c0c470b200541ff0171450d03200241003a00e00d0c030b411d210c0c450b20184104490d012004280002210620012003417a6a3602042001200441066a360200200241a0076a41026a200241a8076a41026a2d00003a0000200241d0096a41086a200241c00d6a41086a290300370300200241d0096a41106a200241c00d6a41106a2d00003a0000200220022f00a8073b01a007200220022903c00d3703d009411e210c0c440b41002105200241003a00e00d2003417e6a2109417d21060240034020092005460d01200241c00d6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200241a8076a41086a200241d70d6a290000220b370300200241ca096a41026a220520022d00c20d3a0000200241c00b6a41086a2208200b370300411f210c200241c00b6a41106a220f200241c00d6a411f6a2d00003a0000200220022900cf0d220b3703a807200220022f01c00d3b01ca092002200b3703c00b200320076b2203417e6a4104490d0120022800cb0d210920022800c70d210d20022800c30d2106200420076a220441026a280000210e20012003417a6a3602042001200441066a360200200241a0076a41026a20052d00003a0000200241d0096a41086a2008290300370300200241d0096a41106a200f2d00003a0000200220022f01ca093b01a007200220022903c00b3703d0090c440b200541ff0171450d00200241003a00e00d0b2000411c3602000c570b200241a8076a200110ac05024020022d00a8074106460d00200241c00b6a41306a200241a8076a41306a290300220b370300200241c00b6a41286a200241a8076a41286a290300220a370300200241c00b6a41206a200241a8076a41206a2903002210370300200241c00b6a41186a200241a8076a41186a2903002214370300200241c00d6a410c6a200241a8076a41086a290300370200200241c00d6a41146a200241a8076a41106a290300370200200241c00d6a411c6a2014370200200241c00d6a41246a2010370200200241c00d6a412c6a200a370200200241c00d6a41346a200b370200200220022903a8073702c40d2000410f360200200020022902c00d3702042000410c6a200241c00d6a41086a290200370200200041146a200241c00d6a41106a2902003702002000411c6a200241c00d6a41186a290200370200200041246a200241c00d6a41206a2902003702002000412c6a200241c00d6a41286a290200370200200041346a200241c00d6a41306a2902003702002000413c6a200241f80d6a280200360200200041c0006a200241e80f6a41e80110e4071a0c570b2000411c3602000c560b200241a8076a200110ac05024020022d00a8074106460d00200241c00b6a41306a200241a8076a41306a290300220b370300200241c00b6a41286a200241a8076a41286a290300220a370300200241c00b6a41206a200241a8076a41206a2903002210370300200241c00b6a41186a200241a8076a41186a2903002214370300200241c00d6a410c6a200241a8076a41086a290300370200200241c00d6a41146a200241a8076a41106a290300370200200241c00d6a411c6a2014370200200241c00d6a41246a2010370200200241c00d6a412c6a200a370200200241c00d6a41346a200b370200200220022903a8073702c40d20004110360200200020022902c00d3702042000410c6a200241c00d6a41086a290200370200200041146a200241c00d6a41106a2902003702002000411c6a200241c00d6a41186a290200370200200041246a200241c00d6a41206a2902003702002000412c6a200241c00d6a41286a290200370200200041346a200241c00d6a41306a2902003702002000413c6a200241f80d6a280200360200200041c0006a200241e80f6a41e80110e4071a0c560b2000411c3602000c550b2006450d3e20042d0001210520012003417e6a2220360204410221062001200441026a360200200541054b0d3e410021084100210d02400240024002400240024020050e06000501020304000b200241c00d6a200110960220022802c00d2209450d43200241c80d6a280200210d20022802c40d2107200241a8046a2001108402024020022903a804a70d0020022903b0042214421888200241b8046a290300221042288684210b200d41187621082010421888210a2010422088a721192014a7211e41012106420021100c050b200741ffffff3f71450d43200910290c430b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241df0d6a310000211020022900c70d210b20022800c30d210820022f00c10d210520022d00c00d210620022800cf0d210320022800d30d210420022900d70d210a200241c8046a200110c80120022802c8040d4320022802cc042109200241c0046a200110c80120022802c0040d43200a4228882010421886842110200a420888a7211f20022802c40421072002200341087622013b00b909200241bb096a20014110763a0000200220033a00b8092002200aa73a00c0092002200441087622184110763a00bf092008410876211e200220043a00bc092004411076210f2005410874200672210d20023100b809210a20022f00bf09211b20022800b9092119410321060c040b200541ff0171450d42200241003a00e00d0c420b200241d0046a200110c80120022802d0040d4120022802d40421094200210b41042106410021084100210d410021194200210a410021070c020b2020450d4020042d0002210520012003417d6a3602042001200441036a360200200541024b0d404200210b41052106410021084100210d410021194200210a410021090240024020050e03030001030b4200210b410121094100210d410021194200210a0c020b200241d8046a200110c80120022802d8040d4020022802dc0421074200210b410221094100210d410021194200210a0c010b41002105200241003a00e00d2003417e6a21092003417d6a2106024002400240034020092005460d01200241c00d6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b2003417e6a2007460d4220022900d70d210b200241df0d6a2d0000211820022800d30d210520022800cf0d210d20022900c70d211020022800c30d210920022f00c10d210c20022d00c00d210e200420076a220341026a2d00002104200120063602042001200341036a360200200441014b0d42200b422088a72101200ba721034100210f20040e020201020b200541ff0171450d41200241003a00e00d0c410b4101210f0b200220013600eb09200220033600e709200220053600e3092002200d3600df0920022900df09221342188820022900e709221442288684210b2014421888210a2010423888a721082010422088a7210d2014422088a721192010a721072013a7211e410621060b2000201b3b012a2000200f3a00292000200c3b000a2000200e3a000920004111360200200041306a20103701002000412c6a201f360100200041286a20183a0000200041106a20073602002000410c6a2009360200200041086a20063a0000200041146a2008411874200d41ffffff077172360200200041186a200b421886201ead42ffffff078384370200200041206a2019ad422086200a42ff0183421886200b4228888484370200200041386a200241e80f6a41f00110e4071a0c540b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541064b0d004107210d02400240024002400240024020050e0700010203040543000b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b20022900d70d220a422888200241df0d6a31000042188684a7210620022800d30d220f410876210e20022800cf0d220c4108762108200a420888a7211820022900c70d210b20022800c30d210920022f00c10d211a20022d00c00d211d200aa7211c4101210d0c430b200541ff0171450d05200241003a00e00d0c050b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b20022900d70d220a422888200241df0d6a31000042188684a7210620022800d30d220f410876210e20022800cf0d220c4108762108200a420888a7211820022900c70d210b20022800c30d210920022f00c10d211a20022d00c00d211d200aa7211c4102210d0c420b200541ff0171450d04200241003a00e00d0c040b41002105200241003a00e00d410220036b21092003417d6a2106024002400340200920056a450d01200241c00d6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200241d0096a411f6a200241c00d6a411f6a3100003c0000200220022900d70d3700e709200220022900cf0d3700df09200220022900c70d3700d709200220022800c30d22093600d309200220022f00c10d3b00d109200220022d00c00d3a00d00941002105200241003a00e00d200420076a210d200720036b41026a2103200241d0096a41077221070340200320056a450d02200241c00d6a20056a200d20056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a00e00d2006417f6a21062004210520044120470d000b200241df0d6a2d0000212120022900d70d210a20022800d30d212020022800cf0d211f20022800c30d211b20022900c70d211020022d00c00d210120022f00c10d2104200241b0096a41086a2203200741086a290000370300200241b0096a41106a2205200741106a290000370300200241b0096a41186a200741186a2d00003a0000200220072900003703b0092001200441087472210720022f01d00920022d00d20941107472221d410876211a20022f00bd09200241bf096a2d000041107472210e20022f00b909200241bb096a2d00004110747221082010422088a7211e20052d0000211c20032d0000210c20022800c509210620022800c109211820022d00bc09210f20022903b009210b2010a721194103210d0c420b200541ff0171450d04200241003a00e00d0c040b200541ff0171450d03200241003a00e00d0c030b200241c00d6a200110960220022802c00d2209450d0220022902c40d210b4104210d410021084100210e41002106410021180c3f0b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b20022900d70d220a422888200241df0d6a31000042188684a7210620022800d30d220f410876210e20022800cf0d220c4108762108200a420888a7211820022900c70d210b20022800c30d210920022f00c10d211a20022d00c00d211d200aa7211c4105210d0c3f0b200541ff0171450d01200241003a00e00d0c010b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b20022900d70d220a422888200241df0d6a31000042188684a7210620022800d30d220f410876210e20022800cf0d220c4108762108200a420888a7211820022900c70d210b20022800c30d210920022f00c10d211a20022d00c00d211d200aa7211c4106210d0c3e0b200541ff0171450d00200241003a00e00d0b2000411c3602000c530b2006450d3720042d0001210520012003417e6a3602042001200441026a360200200541074b0d370240024002400240024002400240024020050e080001020304050607000b200241e0046a200110840220022903e004a70d3e200241f0046a290300211020022903e804210b41002103200241003a00e00d2007280200417f6a2104024003402004417f460d01200241c00d6a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00e00d2004417f6a21042005210320054120470d000b200b42808080807083210a2010a7220341107621012003410876210720022900d70d2214422088a721092010422088a7210d200241df0d6a2d0000210820022800d30d210520022800cf0d210620022900c70d211020022800c30d210c20022f00c10d210e20022d00c00d210f2014a721184101211b0c420b200341ff0171450d3e200241003a00e00d0c3e0b200241f8046a200110c80120022802f8040d3d20022802fc04210c4102211b0c3e0b20024180056a200110c8012002280280050d3c200228028405210c4103211b0c3d0b20024188056a200110c8012002280288050d3b2007280200200228028c052203490d3b2003417f4c0d110240024020030d004200210b410121040c010b2003102d2204450d0a20072802002003490d3b20042001280200200310e4071a200128020422052003490d282001200520036b3602042001200128020020036a3602002003ad210b0b2004450d3b41002105200241003a00e00d200b2003ad42208684220b42808080807083210a2007280200417f6a2103200ba72107024003402003417f460d01200241c00d6a20056a200128020022062d00003a0000200120033602042001200641016a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b20022900d70d2214422088a72109200241df0d6a2d0000210820022800d30d210520022800cf0d210620022900c70d211020022800c30d210c20022f00c10d210e20022d00c00d210f2014a721184104211b4100210341002107410021010c3f0b0240200541ff0171450d00200241003a00e00d0b2007450d3b0c3a0b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b20022900d70d220b422088a72109200241df0d6a2d0000210820022800d30d210520022800cf0d210620022900c70d211020022800c30d210c20022f00c10d210e20022d00c00d210f200ba721184105211b0c390b200541ff0171450d3a200241003a00e00d0c3a0b20024190056a200110c8012002280290050d3920072802002002280294052205490d392005417f4c0d0f0240024020050d004200210b410121040c010b2005102d2204450d0820072802002005490d3920042001280200200510e4071a200128020422032005490d272001200320056b3602042001200128020020056a3602002005ad210b0b2004450d3941002103200241003a00e00d200b2005ad42208684220b42808080807083210a200ba7210d20072802002109417f210502400240034020092003460d01200241c00d6a20036a200128020022082d00003a00002001200920056a3602042001200841016a3602002002200341016a22073a00e00d2005417f6a21052007210320074120470d000b200241bf096a20022800d30d22054118763a0000200241bb096a20022800cf0d22064118763a0000200220022900d70d22143c00c009200220053a00bc09200220063a00b809200220022900c70d22103703b009200220054108763b00bd09200220064108763b00b909200220144208883e00c10920022014422888200241df0d6a3100002213421886843e00c509200920076b22074110490d0120022800c30d210c20022f00c10d210e20022d00c00d210f2008280005210d2008280009211e200828000d2119200828000121032001200841116a3602002001200741706a36020420034110762101200341087621072014422088a721092014a721182013a721084106211b0c3e0b200341ff0171450d00200241003a00e00d0b200d0d380c390b41002105200241003a00e00d2003417e6a2109417d21060240034020092005460d01200241c00d6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200320076b2209417e6a4110490d39200241df0d6a310000210a20022900d70d211420022800d30d210520022800cf0d210620022900c70d211020022800c30d210c20022f00c10d210e20022d00c00d210f200420076a2204410e6a280000210d200441026a290000210b2004410a6a280000210320012009416e6a3602042001200441126a360200200aa741ff017121082003411076210120034108762107200b42808080807083210a2014422088a721092014a721184107211b0c3c0b200541ff0171450d38200241003a00e00d0c380b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b20022900d70d220b422088a72109200241df0d6a2d0000210820022800d30d210520022800cf0d210620022900c70d211020022800c30d210c20022f00c10d210e20022d00c00d210f200ba721184108211b0c360b200541ff0171450d37200241003a00e00d0c370b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541014b0d0002400240024002400240024020050e020001000b200241c00d6a200110900320022802c00d2207450d05200241c80d6a280200211720022802c40d211d200241a8076a200241e80f6a41e10010e4071a200220022f01d0093b018807410121010c010b41002105200241003a0088102003417e6a21092003417d6a2103034020092005460d02200241e80f6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0088102003417f6a21032006210520064120470d000b20024187106a310000211020022900ff0f210a20022800fb0f210c20022800f70f210820022900ef0f210b20022800eb0f210d20022f00e90f210920022d00e80f2106200241e80f6a2001109f0420022d00e80f220e4103460d04200241a1106a290000212420024199106a290000211520024191106a290000211620024189106a2900002112200241f90f6a2900002113200241f10f6a2900002114200241c1106a2900002125200241bd106a280000211a200241b9106a280000211c200241b5106a2800002121200241b1106a2800002120200241ad106a280000211f200241a9106a280000211e20024181106a290000211120022f00ef0f211920022d00ee0f211b20022d00ed0f211820022800e90f210f200241e80f6a2001109f0420022d00e80f4103460d04200241c00d6a200241e80f6a41e10010e4071a200241e80f6a200110b50320022802ec0f221d450d04200241f40f6a280200212220022802f00f2117200728020022034104490d03200241f80f6a280200212620022802e80f210720012802002227280000212320012003417c6a22283602042001202741046a36020041002104200241003a0088102003417b6a2103034020282004460d03200241e80f6a20046a202720046a220541046a2d00003a0000200120033602042001200541056a3602002002200441016a22053a0088102003417f6a21032005210420054120470d000b20024187106a310000212920022900ff0f212a20022800fb0f212820022800f70f212720022900ef0f212b20022800eb0f210520022f00e90f210320022d00e80f2104200241a8076a200241c00d6a41e10010e4071a200220022f01b0093b018807410221010b200241c00b6a200241a8076a41e10010e4071a200220022f0188073b01ca0920004199016a2024370000200020153700910120004189016a20163700002000201237008101200041f1006a201337000020002014370069200041df006a20103c0000200041d7006a200a3700002000413f6a20293c0000200041376a202a370000200020253700b9012000201a3600b5012000201c3600b101200020213600ad01200020203600a9012000201f3600a5012000201e3600a10120002011370079200020193b00672000201b3a0066200020183a00652000200f360061200041e0006a200e3a0000200041d3006a200c360000200041cf006a2008360000200041c7006a200b370000200041c3006a200d360000200041c1006a20093b0000200041c0006a20063a0000200041336a20283600002000412f6a2027360000200041276a202b370000200041236a2005360000200041216a20033b0000200041206a20043a00002000411c6a2023360200200041186a2026360200200041146a2022360200200041106a20173602002000410c6a201d360200200041086a20073602002000200136020420004114360200200041c1016a200241c00b6a41e10010e4071a200020022f01ca093b00a2020c550b200541ff0171450d02200241003a0088100c020b200441ff0171450d00200241003a0088100b02402022450d002022410c6c2104201d210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b2017450d002017410c6c450d00201d10290b2000411c3602000c510b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d0020004115360200200041046a200241e80f6a41a40210e4071a0c510b2000411c3602000c500b2006450d3120042d0001210520012003417e6a3602042001200441026a360200200541054b0d310240024002400240024002400240024002400240024020050e06000102030405000b200241a0056a200110c80120022802a0050d3b20022802a405210420024198056a200110c8012002280298050d3b200228029c05210341012101410021070c050b200241d8056a200110c80120022802d8050d3a20022802dc052104200241d0056a200110c80120022802d0050d3a20022802d4052103200241c8056a200110c80120022802c8050d3a20022802cc052105200241c0056a200110c80120022802c0050d3a20022802c4052106200241a8056a200110840220022903a805a70d3a20022903b005210b200241bc076a200241b8056a290300370200200220053602a8072002200b3702b407200220063602ac0720022802d809210e41022101410021070c060b20024188066a200110c8012002280288060d39200228028c06210420024180066a200110c8012002280280060d392002280284062103200241f8056a200110c80120022802f8050d3920022802fc052105200241e0056a200110840220022903e005a70d39200241f0056a290300210b20022903e805210a200241be076a41003a0000200241b4076a200b370200200241003b01bc07200241003600bf07200220022d00b0093a00c3072002200a3702ac07200220053602a80720022800b109210d20022800b509210820022800b909210920022800bd09210c20022800c109210720022800c509210e410321010c060b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b200241d0096a411f6a200241c00d6a411f6a3100003c0000200220022900d70d3700e709200220022900cf0d3700df09200241b0076a20022900e309370300200241b5076a200241e8096a290000370000200220022900c70d220b3700d709200220022900db093703a80720022800c30d210420022f00c10d210520022d00c00d2106200ba7210341042101410021074100210c0c040b200541ff0171450d38200241003a00e00d0c380b200241a0066a200110c80120022802a0060d3720022802a406210c20024198066a200110c8012002280298060d37200228029c06210d41002104200241003a00e00d20072802002106417f2103024002400240034020062004460d01200241c00d6a20046a200128020022092d00003a00002001200620036a3602042001200941016a3602002002200441016a22053a00e00d2003417f6a21032005210420054120470d000b200620056b22034104490d3a200241df0d6a310000210a20022900d70d211020022800d30d210e20022800cf0d210f20022900c70d210b20022800c30d210420022f00c10d210520022d00c00d2106200928000121082001200941056a36020020012003417c6a36020420024190066a200110c8012002280290060d3a20072802002002280294062203490d3a2003417f4c0d1320030d0142002114410121090c020b200441ff0171450d39200241003a00e00d0c390b2003102d2209450d0920072802002003490d0620092001280200200310e4071a200128020422072003490d292001200720036b3602042001200128020020036a3602002003ad21140b2009450d37200241bc076a200a3c0000200220103702b4072002200c3602c0072002200e3602b0072002200f3602ac072002200b4220883e02a80720142003ad42208684220a422088a72107200aa7210c200ba72103410521010c040b200241b0066a200110c80120022802b0060d3620022802b4062104200241a8066a200110c80120022802a8060d36200728020020022802ac062205490d362005417f4c0d0f0240024020050d004200210b410121030c010b2005102d2203450d0820072802002005490d2a20032001280200200510e4071a200128020422062005490d292001200620056b3602042001200128020020056a3602002005ad210b0b2003450d362002200b2005ad422086843703a80741062101410021074100210c0b0b0b0b200241c00b6a41186a200241a8076a41186a280200220f360200200241c00b6a41106a200241a8076a41106a290300220b370300200241c00b6a41086a200241a8076a41086a290300220a370300200220022903a80722103703c00b200041106a20033602002000410c6a2004360200200020053b000a200020063a0009200041086a20013a000020004116360200200041146a20103702002000411c6a200a370200200041246a200b3702002000412c6a200f360200200041c4006a200e3602002000413c6a2007ad422086200cad84370200200041386a2009360200200041346a2008360200200041306a200d360200200041c8006a200241e80f6a41e00110e4071a0c500b200910290c310b2006450d2f20042d0001210520012003417e6a22223602042001200441026a36020041062109200541064b0d2f4200211002400240024002400240024002400240024020050e0700010203040805000b200241c8066a200110c80120022802c8060d3720072802002203450d3720022802cc06210d200128020022052d0000210420012003417f6a3602042001200541016a360200200441014b0d37410021080240024020040e020100010b410121080b200241c0066a200110c80120022802c0060d37200728020020022802c4062204490d372004417f4c0d1102400240024020040d004200210b4101210e0c010b2004102d220e450d0b20072802002004490d01200e2001280200200410e4071a200128020422032004490d2e2001200320046b3602042001200128020020046a3602002004ad210b0b200e450d38200241b8066a200110c801200b2004ad42208684220ba7211e024020022802b8060d00200728020020022802bc062204490d002004417f4c0d1302400240024020040d004200210a410121180c010b2004102d2218450d0d20072802002004490d0120182001280200200410e4071a200128020422032004490d312001200320046b3602042001200128020020046a3602002004ad210a0b2018450d01200b422088a7210f200a2004ad42208684220b428080808070832110200ba7211b410121094100210c0c0a0b201810290b201e450d380b200e10290c370b200241d0066a200110c80120022802d0060d3620022802d406210d410221090c040b20224104490d352004280002210d20012003417a6a3602042001200441066a360200410321090c030b200241e0066a200110c80120022802e0060d34200728020020022802e4062204490d342004417f4c0d0e02400240024020040d004200210b4101210d0c010b2004102d220d450d0820072802002004490d01200d2001280200200410e4071a200128020422032004490d2d2001200320046b3602042001200128020020046a3602002004ad210b0b200d450d35200241d8066a200110c801200b2004ad42208684220ba7210e024020022802d8060d00200728020020022802dc06221b490d00201b417f4c0d10024002400240201b0d00410021184101210f0c010b201b102d220f450d0a2007280200201b490d01200f2001280200201b10e4071a20012802042204201b490d3020012004201b6b36020420012001280200201b6a360200201b21180b200f450d01200b422088a7211e4200210b410421094100211d410021174200210a420021100c060b200f10290b200e450d350b200d10290c340b200241e8066a200110c80120022802e8060d3320022802ec06210c41002104200241003a00e00d20072802002107417f210302400240034020072004460d01200241c00d6a20046a200128020022062d00003a00002001200720036a3602042001200641016a3602002002200441016a22053a00e00d2003417f6a21032005210420054120470d000b200241df0d6a310000210b20022900d70d211420022800d30d211820022800cf0d210f20022900c70d211320022800c30d210d20022f00c10d211920022d00c00d210841002104200241003a00e00d200720056b2109200720036a2103034020092004460d02200241c00d6a20046a200620046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00e00d2003417f6a21032005210420054120470d000b200241d0096a41186a200241c00d6a41186a2903002211370300200241d0096a41106a200241c00d6a41106a290300370300200241d0096a41086a200241c00d6a41086a290300370300200220022903c00d22123703d0092014428080808070832110200ba741ff0171211a2013422088a7211e200241df096a290000210a20022800d309211c20022900d709210b20022d00e709212120022f00e909211d20022800eb09212020022d00ef09211f2012a721062014a7211b2013a7210e2011a72117410521090c050b200441ff0171450d34200241003a00e00d0c340b200441ff0171450d33200241003a00e00d0c330b200241f0066a200110c80120022802f0060d3220022802f406210d410721090b0b0b200041003b0045200020063b00252000201d3b003e200020173a003d200020193b0106200020083a0005200020093a000420004117360200200041c7006a41003a0000200041276a20064110763a0000200041346a200a3700002000412c6a200b370000200041c8006a200c360200200041c4006a201f3a0000200041c0006a20203600002000413c6a20213a0000200041286a201c360000200041246a201a3a0000200041186a2018360200200041146a200f360200200041106a201e3602002000410c6a200e360200200041086a200d3602002000411c6a2010201bad84370200200041cc006a200241e80f6a41dc0110e4071a0c4e0b2006450d2d20042d0001210520012003417e6a22063602042001200441026a360200200541034b0d2d024002400240024020050e0400010203000b41002105200241003a00e00d410220036b21092003417d6a2106024002400340200920056a450d01200241c00d6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200241d0096a411f6a200241c00d6a411f6a3100003c0000200220022900d70d3700e709200220022900cf0d3700df09200220022900c70d3700d709200220022800c30d22083600d309200220022f00c10d3b00d109200220022d00c00d3a00d00941002105200241003a00810e200420076a2109200720036b41026a2103200241d0096a41077221070340200320056a450d02200241c00d6a20056a200920056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a00810e2006417f6a210620042105200441c100470d000b200241e70d6a2900002111200241d70d6a290000211420022900df0d211220022900cf0d211320022f00ff0d210420022800fb0d210320022800f70d210620022800f30d210920022800ef0d210520022900c70d211020023502c00d210b20023301c40d210a20023100c60d2116200241b0096a41086a220d200741086a290000370300200241b0096a41106a220c200741106a290000370300200241b0096a41186a2201200741186a2d00003a0000200220072900003703b00920022f01d00920022d00d20941107472220f4108762118200b200a20164210868442208684420886200131000084211620022f00b909200241bb096a2d0000411074722101200c290300210b200d2d0000210e20022f01be09211b20022d00bd09210720022d00bc09210c20022903b009210a410121190c300b200541ff0171450d31200241003a00e00d0c310b200541ff0171450d30200241003a00810e0c300b200241003a00d40d2006450d2f20042d0002210520012003417d6a22063602042001200441036a360200200241013a00d40d200220053a00c00d20060d090c2e0b41002105200241003a00e00d410220036b210d2003417d6a210602400240024002400340200d20056a450d01200241c00d6a20056a200420056a220941026a2d00003a0000200120063602042001200941036a3602002002200541016a22093a00e00d2006417f6a21062009210520094120470d000b200241df0d6a310000211620022900d70d210b20022800d30d210c20022800cf0d210e20022900c70d210a20022800c30d210820022f00c10d211820022d00c00d210f41002105200241003a00810e200420096a210d200920036b41026a21030340200320056a450d02200241c00d6a20056a200d20056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a00810e2006417f6a210620042105200441c100470d000b200241e70d6a2900002111200241d70d6a290000211420022900df0d211220022900cf0d211320022f00ff0d210420022800fb0d210320022800f70d210620022800f30d210920022800ef0d210520022900c70d211020023502c00d212420023301c40d212520023100c60d212b200241f8066a200110c80120022802f8060d32200728020020022802fc06221b490d32201b417f4c0d0d201b0d02420021154101210d0c030b200541ff0171450d31200241003a00e00d0c310b200541ff0171450d30200241003a00810e0c300b201b102d220d450d022007280200201b490d04200d2001280200201b10e4071a20012802042207201b490d2920012007201b6b36020420012001280200201b6a360200201bad21150b200d450d2e2015201bad42208684211520242025202b4210868442208684420886201642ff0183842116200e4108762101200c411076211b200c4108762107410321190c2c0b20024180076a200110c8012002280280070d2d20072802002002280284072204490d2d2004417f4c0d080240024020040d004200210b410121080c010b2004102d2208450d0120072802002004490d0220082001280200200410e4071a200128020422032004490d292001200320046b3602042001200128020020046a3602002004ad210b0b2008450d2d200b2004ad42208684210a41042119410021010c2b0b1039000b200810290c2b0b200d10290c2a0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d0041012107024002400240024020050e03020001020b41002105200241003a00e00d2003417e6a21072003417d6a21030240034020072005460d01200241c00d6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00e00d2003417f6a21032006210520064120470d000b20022900d70d220a422088a7210f200241df0d6a2d0000210e20022800d30d210920022800cf0d210d20022900c70d210b20022800c30d210820022f00c10d210620022d00c00d210c200aa72118410221070c020b200541ff0171450d03200241003a00e00d0c030b41002105200241003a00e00d2003417e6a2109417d2106034020092005460d02200241c00d6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00e00d2006417f6a21062007210520074120470d000b200320076b2203417e6a4110490d02200241df0d6a310000211220022900d70d211120022800d30d210920022800cf0d210d20022900c70d210b20022800c30d210820022f00c10d210620022d00c00d210c200420076a2204410a6a2900002110200441026a290000210a20012003416e6a22053602042001200441126a220736020020054110490d022004411a6a29000021132007290000211420012003415e6a22053602042001200441226a220736020020054104490d022007280000211b20012003415a6a3602042001200441266a3602002011422088a7210f201242ff0183a7210e2011a72118410321070b200020063b000a2000200c3a000920004119360200200041c8006a2013370200200041c0006a2014370200200041386a2010370200200041306a200a370200200041286a200ead3c0000200041d0006a201b3602002000411c6a2009360000200041186a200d360000200041106a200b3700002000410c6a2008360000200041086a20073a0000200041206a200fad4220862018ad84370000200041d8006a200241e80f6a41d00110e4071a0c4b0b200541ff0171450d00200241003a00e00d0b2000411c3602000c490b200241c00d6a200110e303024020022d00c00d4106460d00200241a8076a41386a2201200241c00d6a41386a280200360200200241a8076a41306a200241c00d6a41306a290300220b370300200241a8076a41286a200241c00d6a41286a290300220a370300200241a8076a41206a200241c00d6a41206a2903002210370300200241a8076a41186a200241c00d6a41186a2903002214370300200241a8076a41106a200241c00d6a41106a2903002213370300200241a8076a41086a200241c00d6a41086a2903002211370300200220022903c00d22123703a8072000411a360200200020123702042000410c6a2011370200200041146a20133702002000411c6a2014370200200041246a20103702002000412c6a200a370200200041346a200b3702002000413c6a2001280200360200200041c0006a200241e80f6a41e80110e4071a0c490b2000411c3602000c480b2000411c3602000c470b200241a8076a200110ad0520022d00a8074105470d222000411c3602000c460b20042d0003210520012003417c6a22063602042001200441046a360200200241023a00d40d200220053a00c10d2006450d2420042d0004210520012003417b6a22063602042001200441056a360200200241033a00d40d200220053a00c20d2006450d2420042d0005210520012003417a6a22063602042001200441066a360200200241043a00d40d200220053a00c30d2006450d2420042d000621052001200341796a22063602042001200441076a360200200241053a00d40d200220053a00c40d2006450d2420042d000721052001200341786a22063602042001200441086a360200200241063a00d40d200220053a00c50d2006450d2420042d000821052001200341776a22063602042001200441096a360200200241073a00d40d200220053a00c60d2006450d2420042d000921052001200341766a220636020420012004410a6a360200200241083a00d40d200220053a00c70d2006450d2420042d000a21052001200341756a220636020420012004410b6a360200200241093a00d40d200220053a00c80d2006450d2420042d000b21052001200341746a220636020420012004410c6a3602002002410a3a00d40d200220053a00c90d2006450d2420042d000c21052001200341736a220636020420012004410d6a3602002002410b3a00d40d200220053a00ca0d2006450d2420042d000d21052001200341726a220636020420012004410e6a3602002002410c3a00d40d200220053a00cb0d2006450d2420042d000e21052001200341716a220636020420012004410f6a3602002002410d3a00d40d200220053a00cc0d2006450d2420042d000f21052001200341706a22063602042001200441106a3602002002410e3a00d40d200220053a00cd0d2006450d2420042d0010210520012003416f6a22063602042001200441116a3602002002410f3a00d40d200220053a00ce0d2006450d2420042d0011210520012003416e6a22063602042001200441126a360200200241103a00d40d200220053a00cf0d2006450d2420042d0012210520012003416d6a22063602042001200441136a360200200241113a00d40d200220053a00d00d2006450d2420042d0013210520012003416c6a22063602042001200441146a360200200241123a00d40d200220053a00d10d2006450d2420042d0014210520012003416b6a22063602042001200441156a360200200241133a00d40d200220053a00d20d2006450d2420042d0015210520012003416a6a22063602042001200441166a360200200241143a00d40d200220053a00d30d200220022900c70d3703c00b2002200241cc0d6a2900003700c50b200641104f0d220c250b1038000b2004200341ccafc000104c000b2004200341ccafc000104c000b2004200341ccafc000104c000b2004200341ccafc000104c000b2003200e41ccafc000104c000b2004200341ccafc000104c000b2004200341ccafc000104c000b2004200341ccafc000104c000b2004200341ccafc000104c000b200c10290c2e0b2004200341ccafc000104c000b2004200341ccafc000104c000b2003200541ccafc000104c000b200410290b2000411c3602000c350b2004200341ccafc000104c000b2004200c41ccafc000104c000b2004200341ccafc000104c000b2004200341ccafc000104c000b2004200341ccafc000104c000b2004200341ccafc000104c000b2003200541ccafc000104c000b2005200341ccafc000104c000b2003200741ccafc000104c000b2005200641ccafc000104c000b200310290c0c0b2004200341ccafc000104c000b2004200341ccafc000104c000b2004200341ccafc000104c000b201b200441ccafc000104c000b201b200741ccafc000104c000b2004200341ccafc000104c000b200241c00b6a41206a200241a8076a41206a290300220b370300200241c00b6a41186a200241a8076a41186a290300220a370300200241c00d6a410c6a200241a8076a41086a290300370200200241c00d6a41146a200241a8076a41106a290300370200200241c00d6a411c6a200a370200200241c00d6a41246a200b370200200220022903a8073702c40d2000411b360200200020022902c00d3702042000410c6a200241c00d6a41086a290200370200200041146a200241c00d6a41106a2902003702002000411c6a200241c00d6a41186a290200370200200041246a200241c00d6a41206a2902003702002000412c6a200241e80d6a280200360200200041306a200241e80f6a41f80110e4071a0c230b20022d00c20d210d20022f01c00d210f20022800c30d210820022903c00b210a20022802c80b210e20022d00cc0b210c2004411e6a29000021162004290016210b20012003415a6a22053602042001200441266a3602002005450d0220042d002621062001200341596a22093602042001200441276a2218360200200641014b0d02420021100240024020060e020100010b20094110490d032004412f6a2900002114200429002721132001200341496a22053602042001200441376a36020020054110490d032004413f6a2900002111200429003721122001200341b97f6a22053602042001200441c7006a36020020054104490d03200428004721052001200341b57f6a22093602042001200441cb006a2218360200420121100b20104202510d022009450d0220182d0000210420012009417f6a22033602042001201841016a360200200441014b0d02410221070240024020040e020100010b2003450d0320182d0001210420012009417e6a3602042001201841026a360200200441014b0d0341002107024020040e020100010b410121070b200f200d41107472220f4108762118200e410876210120022902d4092115410221190b2000201b3b011e200020073a001d200020183b000a2000200f3a000920004118360200200041d0006a2011370200200041c8006a2012370200200041c0006a2014370200200041386a2013370200200041286a2016370200200041206a200b370200200041f0006a2015370200200041ec006a200d360200200041e8006a2004360200200041e4006a2003360200200041e0006a2006360200200041dc006a2009360200200041d8006a2005360200200041306a20103702002000411c6a200c3a0000200041106a200a3702002000410c6a2008360200200041086a20193a0000200041186a2001410874200e41ff017172360200200041f8006a200241e80f6a41b00110e4071a0c210b200241003a00d40d0b2000411c3602000c1f0b2000411c3602000c1e0b2000411c3602000c1d0b4200210b410021030c030b200410290b2000411c3602000c1a0b4200210b4100210841002109410021030b41002107410021014200210a0b2000200e3b000a2000200f3a000920004113360200200041286a2008ad3c0000200041c4006a2019360200200041c0006a201e3602002000413c6a200d3602002000412c6a20043602002000411c6a2005360200200041186a2006360200200041106a20103702002000410c6a200c360200200041086a201b3a0000200041306a200a200b42ffffffff0f8384370200200041206a2009ad4220862018ad84370200200041386a200141107420074108744180fe037172200341ff017172360200200041c8006a200241e80f6a41e00110e4071a0c170b200020073b0025200041003b0046200041003a00452000201a3b00062000201d3a00052000200d3a000420004112360200200041276a20074110763a0000200041c4006a20213a00002000413c6a200a370000200041386a2020360000200041346a201f360000200041306a201e3600002000412c6a2019360000200041286a201b3600002000410c6a200b370000200041086a2009360000200041246a2006411876ad3c0000200041186a200e410874200f41ff017172360000200041146a2008410874200c41ff0171723600002000411c6a2006ad4228862018ad42088684201cad42ff018384370000200041c8006a200241e80f6a41e00110e4071a0c160b2000411c3602000c150b20024198076a41026a200241a0076a41026a2d000022013a0000200241b0096a41086a2204200241d0096a41086a290300370300200241b0096a41106a2203200241d0096a41106a2d00003a0000200220022f01a00722053b019807200220022903d0093703b009200041086a200c3a00002000410e360200200020053b00092000410b6a20013a0000200041146a2009360200200041106a200d3602002000410c6a2006360200200041386a200a370200200041306a200b3702002000412c6a200e3602002000200f3b012a200020083a0029200041186a20022903b009370200200041206a2004290300370200200041286a20032d00003a0000200041c0006a200241e80f6a41e80110e4071a0c140b4100210c02402004450d00200910290b410221094100211b0b41000d062009450d06200241e80f6a2001108602024002400240024020022802e80f450d00200241c00d6a200241e80f6a41c00110e4071a200728020022034110490d012001280200220441086a2900002114200429000021102001200441106a3602002001200341706a220536020420054110490d01200441186a2900002111200429001021132001200341606a22053602042001200441206a36020020054110490d01200441286a2900002116200429002021122001200341506a22053602042001200441306a36020020054104490d022004280030211e20012003414c6a3602042001200441346a36020020024188036a200110ae0520022f0188030d0320022f018a03211f20024180036a200110c8012002280280030d032002280284032120200241e00d6a290300210a200241d40d6a280200211d200241d00d6a310000212420022903d80d210b20022f01d20d212120022d00d10d211920022802c40d211820022802c00d210820022903c80d2115200241a8076a200241e80d6a41980110e4071a200241a0076a41046a200241d0096a41046a2f01003b0100200220022801d0093602a0072015422888202442188684a721062015420888a7211a2015a7211c4118210f0c0f0b200c0d050c090b200241c00d6a108702200c41808080807872418080808078470d040c080b200241c00d6a108702200c0d030c070b200241c00d6a108702200c41808080807872418080808078460d060c020b4100210c02402004450d00200910290b410221094100211b0b41000d042009450d04200241e80f6a2001108602024002400240024020022802e80f450d00200241c00d6a200241e80f6a41c00110e4071a200728020022034110490d012001280200220441086a2900002114200429000021102001200441106a3602002001200341706a220536020420054110490d01200441186a2900002111200429001021132001200341606a22053602042001200441206a36020020054110490d01200441286a2900002116200429002021122001200341506a22053602042001200441306a36020020054104490d022004280030211e20012003414c6a3602042001200441346a360200200241f0026a200110ae0520022f01f0020d0320022f01f202211f200241e8026a200110c80120022802e8020d0320022802ec022120200241e00d6a290300210a200241d40d6a280200211d200241d00d6a310000212420022903d80d210b20022f01d20d212120022d00d10d211920022802c40d211820022802c00d210820022903c80d2115200241a8076a200241e80d6a41980110e4071a200241a0076a41046a200241d0096a41046a2f01003b0100200220022801d0093602a0072015422888202442188684a721062015420888a7211a2015a7211c4117210f0c0d0b200c0d030c070b200241c00d6a108702200c41808080807872418080808078470d020c060b200241c00d6a108702200c0d010c050b200241c00d6a108702200c41808080807872418080808078460d040b200910290c030b4100211b02402001450d00200c10290b4104210c410021080b41000d01200c450d01200241a8076a200241e80f6a41980110e4071a200241a0076a41046a200241c00d6a41046a2f01003b0100200220022801c00d3602a0074110210f0b4100211a410021060c050b2000411c3602000c0b0b0c030b4100211a410021060c020b4100211a4100210641002118410021084100211b0c010b4100211a410021060b200241c00b6a200241a8076a41980110e4071a20024198076a41046a2201200241a0076a41046a2f01003b0100200220022802a00736029807200041386a200a370200200041306a200b370200200041286a2006411876ad3c0000200041206a2006ad422886201aad42088684201cad42ff018384370200200041186a2018ad4220862008ad84370200200041106a201bad422086200cad843702002000412c6a201d360200200020213b012a200020193a00292000410c6a20093602002000200e3b010a2000200d3a0009200041086a200f3a000020004107360200200041c0006a200241c00b6a41980110e4071a20004190026a201637020020004188026a201237020020004180026a2011370200200041f8016a2013370200200041f0016a2014370200200041e8016a2010370200200041e0016a201f3b0100200041dc016a2020360200200041d8016a201e36020020002002280298073601e201200041e6016a20012f01003b010020004198026a200229038807370300200041a0026a20024188076a41086a2903003703000c060b200020043b002a200020053a00292000200e3b000a2000200f3a000920004105360200200041d0006a2015370200200041c8006a2013370200200041c0006a2014370200200041386a2011370200200041306a2012370200200041286a200b3c0000200041206a200a3700002000412c6a20033600002000411c6a200d360000200041186a2008360000200041106a20103700002000410c6a200c360000200041086a20013a0000200041d8006a2007ad4238862006ad42188684201642ffffff078384370200200041e0006a200241e80f6a41c80110e4071a0c050b0b200020083a00252000200c3b00062000200e3a0005200020093a000420004104360200200041246a200a3c00002000411c6a200b370200200041186a2006360200200041146a20053602002000410c6a2010370200200041086a200d360200200041286a2001411874200441ffffff07717236020020002007410874200341ff0171723b00262000412c6a200241e80f6a41fc0110e4071a0c030b200510290b2000411c3602000c010b1030000b20024190126a24000bf90c07027f017e027f027e097f047e017f230022042105200441a0016b4160712204240002402002200384500d002000290000210620044180016a200110df03200441e0006a200428028001220720042802880110e60320042902644200200428026022081b21090240200428028401450d00200710290b4201210a2008410820081b210b2009a7210c0240024002402009422088a72208450d00200b2008410574220d6a210e200441e0006a41106a210f200441e0006a41196a21104100210702400340200441c0006a41106a2211200b20076a220841106a290300370300200441c0006a41086a2212200841086a290300370300200420082903003703402004200841196a28000036022820042008411c6a28000036002b200841186a2d000022134103460d02200f2011290300370300200441e0006a41086a201229030037030020102004280228360000201041036a200428002b36000020042004290340370360200420133a00780240024002400240200f2000460d00200f2900002000290000510d00200420102800003602582004201041036a28000036005b200441e8006a290300211420042903602115200429037021160c010b200aa72111200441033a009801200429039001210620042903800121092004290388012117200429039801210a201141ff01714103460d01200441e8006a2903002214200320042903602215200256201420035620142003511b220f1b211420152002200f1b2115201341022013201141ff0171461b21132004290370211620092102201721030b2004200428005b36003320042004280258360230200420042802303602382004200428003336003b0240412010272218450d0020182015370300201820133a00182018201637031020182004280238360019201820143703082018411c6a200428003b360000200442818080801037021c20042018360218200d41606a2007460d02200841206a2108200d20076b41406a2110200441e0006a41106a2111200441e0006a41196a2112410121130340200441c0006a41106a220f200841106a290300370300200441c0006a41086a220e200841086a29030037030020042008290300370340200841186a2d000021072004200841196a28000036022820042008411c6a28000036002b20074103460d032011200f290300370300200441e0006a41086a220f200e29030037030020122004280228360000201241036a220e200428002b36000020042004290340370360200420073a007802400240024020112000460d0020112900002000290000510d00200420122800003602582004200e28000036005b200f2903002114200429036021152004290370211620022109200321170c010b200aa7210e200441033a009801200429039001210620042903800121092004290388012117200429039801210a0240200e41ff0171220e4103460d00200f2903002214200320042903602215200256201420035620142003511b220f1b211420152002200f1b2115200741022007200e461b2107200429037021160c010b2010450d070c010b2004200428005b36003320042004280258360230200420042802303602382004200428003336003b2004200428003b36008301200420042802383602800102402013200428021c470d00200441186a201310a101200428021821180b201820134105746a220f20073a0018200f2016370310200f200428028001360019200f411c6a200428008301360000200f2014370308200f20153703002004201341016a22133602202010450d060b200841206a2108201041606a211020092102201721030c000b0b1039000b200741206a21072009210220172103200841206a200e470d010c040b0b20022109200321170b0240200c41ffffff3f71450d00200b10290b20044180016a41086a200441186a41086a28020036020020042004290318370380010c020b20022109200321170b20044100360288012004420837038001200c41ffffff3f71450d00200b10290b02400240200a42ff01834203854200520d002004280288012108200428028001210720044180016a21040c010b02402004280288012208200428028401470d0020044180016a200810a10120042802880121080b200428028001220720084105746a220020063703102000201737030820002009370300200041186a200a3703002004200841016a22083602880120044180016a21040b20012007200810e703200441046a28020041ffffff3f71450d00200428020010290b200524000b990604067f017e027f057e230041f0006b220324002003200236021420032001360210200341186a2002ad4220862001ad841007108b020240024002400240200328021822040d00200041003602000c010b200328021c21052003200341206a28020036022c20032004360228200341086a200341286a10c8010240024020032802080d00200328020c2206200328022c4105762201200120064b1b22014105742202417f4c0d040240024020010d00410821070c010b200210272207450d040b41002102200341003602502003200136024c20032007360248024002402006450d000340200341306a200341286a10ab040240024020032d00304101460d0041032108200328022c22014110490d01200329003121092003200141706a220a36022c20032003280228220b41106a360228200a450d01200b41086a290000210c200b290000210d20032001416f6a36022c2003200b41116a36022841032108200b2d0010220141034f0d01200320032800303602402003200341306a41036a2800003600432009210e200d210f200c2110200121080c010b410321080b200320032802403602682003200328004336006b20084103460d022003200328006b3600632003200328026836026002402002200328024c470d00200341c8006a200210a10120032802482107200328025021020b200720024105746a220120083a00182001200e370310200120032802603600192001411c6a2003280063360000200120103703082001200f3703002003200241016a22023602502006417f6a22060d000b0b2007450d012000200329024c370204200020073602000c020b200328024c41ffffff3f71450d00200710290b20034100360238200342013703302003410d3602442003200341106a3602402003200341306a360268200341dc006a41013602002003420137024c200341f4eaca003602482003200341c0006a360258200341e8006a41a8a3c800200341c8006a10371a2003350238422086200335023084100802402003280234450d00200328023010290b200041003602000b2005450d00200410290b200341f0006a24000f0b1039000b1038000bf40f08037f027e027f067e047f037e037f037e230041e0046b22032400200341086a200010a802200341186a200328020822042003280210220510a902200329031821064200210720034200370318200341e0006a280200210820032d006421090240024020064201510d00200341e8006a41386a4200370300200341e8006a41306a4200370300200341e8006a41286a4200370300200341e8006a41206a4200370300200341e8006a41186a4200370300200341f8006a4200370300200341f0006a4200370300200342003703684200210a4200210b4200210c0c010b200341186a41386a290300210d200341186a41306a290300210e200341186a41206a290300210a200341186a41186a2903002107200341d8006a290300210f2003290328210c2003290320210b200341e8006a41206a200341186a41286a290300370300200341e8006a41286a200e370300200341e8006a41306a200d370300200341f8006a20073703002003200a370380012003200f3703a0012003200b3703682003200c3703700b4200210f200341a0016a22104200370300200341e8006a41306a4200370300200341e8006a41286a221142003703002003420037038801200341e8006a41106a211202402002450d00200241057421134200210f420021144200211542002116200121170340024002400240201741186a22182d00002219417f6a41ff017141014b0d0020112016201741086a290300220d20152017290300220e562016200d562016200d511b22191b221637030020032015200e20191b22153703880120182d000022194102460d010b201941ff01710d01201741086a290300210d2017290300210e0b2010200f200d2014200e56200f200d56200f200d511b22191b220f37030020032014200e20191b2214370398010b201741206a2117201341606a22130d000b0b200341a8016a41186a201241086a290300220d370300200341a8016a41206a2219201241106a290300370300200341a8016a41286a201241186a290300370300200341a8016a41306a201241206a29030037030020032012290300220e3703b8012003200b3703a8012003200c3703b00102400240427f200b200e7c220e200e200b542217200c200d7c2017ad7c220d200c54200d200c511b22171b220e4280c8afa025544100427f200d20171b2216501b0d00200341b8016a290300211a200341d8016a290300211b200341d0016a290300210e2019290300211620032903b001211420032903a80121154201210d20032903c001211c0c010b4200210d0240200e201684500d00200e201610d40220034198046a201637030020034190046a200e370300200341e0036a41086a41013a0000200341e9036a2000290000370000200341f1036a200041086a290000370000200341f9036a200041106a29000037000020034181046a200041186a290000370000200341033a00e003200341e0036a10cb010b0b200341c0006a2016370300200341c8006a200e370300200341286a2014370300200341d0006a201b370300200341306a201a3703002003201c3703382003200f37035820032015370320200320094100200642015122171b22193a006420032008410020171b22133602602003200d4201512217ad37031802400240024020170d002005ad4220862004ad8410040c010b410410272217450d0120172013360000201741044108102b2217450d01201720193a0004201741084115102b2217450d01201720153700052017410d6a2014370000200341386a290300210f200341306a290300211420174115412a102b2217450d01201720143700152017411d6a200f3700002017412a41d400102b2217450d01201720163700252017412d6a200e3700002017413d6a200341d8006a2903003700002017200341d0006a2903003700352005ad4220862004ad842017ad4280808080d008841003201710290b200b20077c220f200b542217200c200a7c2017ad7c220e200c54200e200c511b21170240200328020c450d00200410290b427f200e20171b210e427f200f20171b210f200d420152211702400240024020064201510d0020170d0041032119200341e0026a21170c010b20064201522017410173720d0141042119200341e0016a21170b201741086a20193a0000201741003a0000201741096a2000290000370000201741116a200041086a290000370000201741196a200041106a290000370000201741216a200041186a290000370000201710cb010b0240200f200e844200520d0020034198046a200c37030020034190046a200b370300200341e0036a41086a41003a0000200341e9036a2000290000370000200341f1036a200041086a290000370000200341f9036a200041106a29000037000020034181046a200041186a290000370000200341033a00e003200341e0036a10cb010b200341e0036a200010df03200320032802e003221920032802e8034180a6cc004100410010c70120032802002117024020032802e403450d00201910290b024002402002450d00200341e0026a200010df0320032802e002211920033502e802210d200341e0036a2001200210e803200d4220862019ad8420033502e80342208620032802e0032213ad841003024020032802e403450d00201310290b024020032802e402450d00201910290b20174101460d01200010a7020c010b200341e0036a200010df0320033502e80342208620032802e0032219ad841004024020032802e403450d00201910290b20174101470d00200010b2020b200341e0046a24000f0b1030000bdb0102037f017e230041206b220324000240024020024105744104722204417f4c0d00200410272205450d0120034100360208200320043602042003200536020020022003107102402002450d002002410574210203402003200141106a41081072200129030021062003200141086a290300370318200320063703102003200341106a411010722003200141186a2d00003a00102003200341106a41011072200141206a2101200241606a22020d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1038000b1039000ba2200e037f017e037f057e037f017e027f017e017f037e017f017e037f047e23004190096b220624002006200437031020062003370308200620053a001f0240024002400240024002400240024002400240024002402003200484500d0020012002460d0320012002412010e707450d03200641a0016a200210a802200641b0016a20062802a001220720062802a801220810a90220062903b001210942002104200642003703b001200641f8016a280200210a20062d00fc01210b2009420151220c0d0120064180026a41386a420037030020064180026a41306a420037030020064180026a41286a4200370300200641a0026a420037030020064180026a41186a420037030020064190026a420037030020064188026a42003703002006420037038002420021034200210d4200210e0c020b20004100360200200041106a4200370300200041086a42003703000c0a0b200641b0016a41386a290300210f200641b0016a41306a2903002110200641b0016a41206a290300210e200641b0016a41186a290300210d200641f0016a290300211120062903c001210320062903b8012104200641a0026a200641b0016a41286a29030037030020064180026a41286a201037030020064180026a41306a200f37030020064190026a200d3703002006200e37039802200620113703b802200620043703800220062003370388020b4200211020064180026a41106a21050240427f2004200d7c220d200d20045422122003200e7c2012ad7c220420035420042003511b22121b427f200420121b844200520d0020064190066a41206a200541206a29030037030020064190066a41186a200541186a29030037030020064190066a41106a200541106a29030037030020064190066a41086a200541086a290300370300200620052903003703900641a5e2c200ad4280808080b00184210341838c1c21050c040b200641c0046a200110a802200641d0046a20062802c004221320062802c804221410a90220062903d0042115200642003703d00420064198056a280200211620062d009c05211702400240201542015122120d004200210d200641a0056a41306a4200370300200641a0056a41286a4200370300200641a0056a41206a4200370300200641a0056a41186a4200370300200641b0056a4200370300200641a8056a4200370300200642003703a005420021034200210e42002104420021180c010b20064188056a290300210f200641d0046a41306a2903002110200641d0046a41206a2903002103200641d0046a41186a290300210d20064190056a290300211820062903e004210420062903d804210e200641a0056a41206a200641d0046a41286a290300370300200641a0056a41286a2010370300200641a0056a41306a200f370300200641b0056a200d370300200620033703b8052006200e3703a005200620043703a8050b200641086a41086a29030022102003200d2006290308221156200320105620032010511b22191b211a2011200d20191b210f0240024020062d001f4101470d0020052119200629039002221b200f7c221c201b54221d20064198026a290300221e201a7c201dad7c221b201e54201b201e511b0d010c030b20064180026a2119200629038002221b200f7c221c201b54221d20064180026a41086a290300221e201a7c201dad7c221b201e54201b201e511b4101470d020b41839dc500211241839dc500ad42808080808001842203428080fcff8f0183210f200342088842ff0183210d410121190c020b02402005450d0020064190076a200110a80220064190086a200628029007220220062802980710a902200641b0086a290300420020062903900842015122011b210e200641a8086a290300420020011b210d0240200628029407450d00200210290b20004100360200200041106a42002004200e7d2003200d54ad7d220e2003200d7d220d200356200e200456200e2004511b22011b370300200041086a4200200d20011b3703000c080b20062003370390062006200437039806200620013602c00320064190076a200120064190066a200641c0036a10ea03200641b0076a290300210320062903a807210402402006290390074201520d00200629039807210d200641c8086a20064190076a41106a290300370300200641c0086a200d37030020064190086a41086a41003a000020064199086a2001290000370000200641a1086a200141086a290000370000200641a9086a200141106a290000370000200641b1086a200141186a290000370000200641033a00900820064190086a10cb010b200041106a2003370300200041086a2004370300200041003602000c070b2019201c3703002019201b370308200641a0056a41186a2003201a7d200d200f54ad7d3703002006200d200f7d3703b005200641d8056a41186a200641b0056a221941086a290300221b370300200641d8056a41206a221f201941106a29030037030020064180066a2220201941186a29030037030020064188066a2221201941206a29030037030020062019290300221c3703e8052006200e3703d805200620043703e0052010201a7d21102011200f54ad211e427f200e200d7c220d200d200e542219200420037c2019ad7c220320045420032004511b22191b427f200320191b8450211902400240427f200e201c7c22032003200e54221d2004201b7c201dad7c220320045420032004511b221d1b220d4280c8afa025544100427f2003201d1b2203501b0d00200641d8056a41106a2903002122202129030021232020290300210d201f290300211a20062903e005211b20062903d805211c4201212420062903f00521250c010b420021240240200d200384500d00200d200310d402200641c8086a2003370300200641c0086a200d37030020064190086a41086a41013a000020064199086a2001290000370000200641a1086a200141086a290000370000200641a9086a200141106a290000370000200641b1086a200141186a290000370000200641033a00900820064190086a10cb010b0b2010201e7d21102011200f7d21032019ad2111200641f8046a201a37030020064180056a200d370300200641e0046a201b37030020064188056a2023370300200641e8046a2022370300200620253703f00420062018370390052006201c3703d804410021192006201741002015420151221d1b22173a009c05200620164100201d1b221d36029805200620244201512216ad3703d004024020160d002014ad4220862013ad8410044200210d4200210f0c010b410410272216450d042016201d360000201641044108102b2216450d04201620173a0004201641084115102b2216450d042016201c3700052016410d6a201b370000200641f0046a290300210f200641e8046a290300211520164115412a102b2216450d04201620153700152016411d6a200f3700002016412a41d400102b2216450d042016201a3700252016412d6a200d3700002016413d6a20064190056a290300370000201620064188056a2903003700352014ad4220862013ad842016ad4280808080d008841003201610294200210f4201210d0b024020062802c404450d00201310290b0240024020190d00024002400240201241ff017122120d00200d4200510d004103211920064190076a21120c010b2012450d01200d4200520d014104211920064190066a21120b201241086a20193a0000201241003a0000201241096a2001290000370000201241116a200141086a290000370000201241196a200141106a290000370000201241216a200141186a290000370000201210cb010b4100211220114201520d01200641c8086a2004370300200641c0086a200e3703004100211220064190086a41086a41003a000020064199086a2001290000370000200641a1086a200141086a290000370000200641a9086a200141106a290000370000200641b1086a200141186a290000370000200641033a00900820064190086a10cb010c010b200d4208862012ad42ff018384200f84210342002110410121120b20064180026a41086a2903002104200629038002210d20062903b802210e20064190066a41206a2201200541206a29030037030020064190066a41186a2219200541186a29030037030020064190066a41106a2213200541106a29030037030020064190066a41086a2216200541086a290300370300200620052903003703900641838c0821052012450d010b20034280807c83210d200342088842ff018321042003a7210c410121010c010b20064190076a41186a2016290300220f37030020064190076a41206a2013290300370300200641b8076a22052019290300370300200641c0076a22122001290300370300200620062903900622113703a0072006200d37039007200620043703980702400240427f200d20117c22112011200d5422012004200f7c2001ad7c220d200454200d2004511b22011b22044280c8afa025544100427f200d20011b220d501b0d00200641a0076a290300211a2012290300211520052903002104200641b0076a290300210d200629039807210f20062903900721114201211b20062903a80721180c010b4200211b02402004200d84500d002004200d10d402200641c8086a200d370300200641c0086a200437030020064190086a41086a41013a000020064199086a2002290000370000200641a1086a200241086a290000370000200641a9086a200241106a290000370000200641b1086a200241186a290000370000200641033a00900820064190086a10cb010b0b200641d8016a200d370300200641e0016a2004370300200641c0016a200f370300200641e8016a2015370300200641c8016a201a370300200620183703d0012006200e3703f001200620113703b801410021012006200b4100200942015122051b22123a00fc012006200a410020051b22193602f8012006201b4201512205ad3703b001024020050d002008ad4220862007ad8410044200210441838c0821054200210d0c010b410410272205450d0120052019360000200541044108102b2205450d01200520123a0004200541084115102b2205450d01200520113700052005410d6a200f370000200641d0016a290300210e200641c8016a290300210f20054115412a102b2205450d012005200f3700152005411d6a200e3700002005412a41d400102b2205450d012005200d3700252005412d6a20043700002005413d6a200641f0016a2903003700002005200641e8016a2903003700352008ad4220862007ad842005ad4280808080d008841003200510294200210d4201210441838c0821050b024020062802a401450d00200710290b20010d01024002400240200c41ff017122010d0020044200510d0041032105200641c0036a21010c010b2001450d0120044200520d0141042105200641c0026a21010b200141086a20053a0000200141003a0000200141096a2002290000370000200141116a200241086a290000370000200141196a200241106a290000370000200141216a200241186a290000370000200110cb010b200041106a2010370300200041086a2003370300200041003602000c020b1030000b20002005360204200041086a2004420886200cad42ff018384200d84370200200041013602000b20064190096a24000b8f0c06037f027e027f0c7e037f067e23004180036b22042400200328020021052004200110a80220044180016a200428020022032004280208220610a9022004290380012107420021082004420037038001200441c8016a280200210920042d00cc01210a0240024020074201510d00200441106a41306a4200370300200441106a41286a4200370300200441106a41206a4200370300200441106a41186a4200370300200441206a4200370300200441186a4200370300200442003703104200210b4200210c4200210d4200210e0c010b200441b8016a290300210f20044180016a41306a290300211020044180016a41206a290300210b20044180016a41186a2903002108200441c0016a290300210e200429039001210d200429038801210c200441106a41206a20044180016a41286a290300370300200441106a41286a2010370300200441106a41306a200f370300200441206a20083703002004200b3703282004200c3703102004200d3703180b200441106a41186a200b200241086a2903002211200b20082002290300221256200b201156200b2011511b22021b22137d20082012200820021b221054ad7d22143703002004200820107d22153703202004427f200d20137c200c20107c2216200c542202ad7c220f2002200f200d54200f200d511b22021b220f3703182004427f201620021b2216370310200441c8006a41186a2014370300200441c8006a41206a2217200441106a41206a290300370300200441c8006a41286a2218200441106a41286a290300370300200441c8006a41306a2219200441106a41306a2903003703002004200f370350200420163703482004201537035802400240427f201620157c221520152016542202200f20147c2002ad7c2214200f542014200f511b22021b22154280c8afa025544100427f201420021b221a501b0d00200441d8006a290300211b2019290300211c201829030021152017290300211a2004290350211d2004290348211e420121142004290360211f0c010b4200211402402015201a84500d002015201a10d402200441b8026a201a370300200441b0026a201537030020044180026a41086a41013a000020044189026a200529000037000020044191026a200541086a29000037000020044199026a200541106a290000370000200441a1026a200541186a290000370000200441033a00800220044180026a10cb010b0b200441a8016a201a370300200441b0016a201537030020044190016a201d370300200441b8016a201c37030020044198016a201b3703002004201f3703a0012004200e3703c0012004201e370388012004200a4100200742015122021b22053a00cc0120042009410020021b22093602c801200420144201512202ad3703800102400240024020020d002006ad4220862003ad8410040c010b410410272202450d0120022009360000200241044108102b2202450d01200220053a0004200241084115102b2202450d012002201e3700052002410d6a201d370000200441a0016a290300211d20044198016a290300211e20024115412a102b2202450d012002201e3700152002411d6a201d3700002002412a41d400102b2202450d012002201a3700252002412d6a20153700002002413d6a200441c0016a2903003700002002200441b8016a2903003700352006ad4220862003ad842002ad4280808080d008841003200210290b201120137d21112012201054ad2113427f200c20087c22082008200c542202200d200b7c2002ad7c2208200d542008200d511b22021b427f200820021b8450210202402004280204450d00200310290b201120137d210d2002ad2108201220107d210b2014420152210202400240024020074201510d0020020d004103210320044180026a21020c010b20074201522002410173720d014104210320044180016a21020b200241086a20033a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a290000370000200210cb010b2000200b3703182000201637030820002008370300200041206a200d370300200041106a200f37030020044180036a24000f0b1030000b1300200041043602042000418cb9c3003602000b3400200041dcbec50036020420004100360200200041146a4104360200200041106a41f0d2c300360200200041086a42083702000b830101017f0240411010272202450d002002420037000820024200370000200241104120102b2202450d0020024200370010200241186a42003700002002412041c000102b2202450d002002420037003020024200370020200042c0808080800837020420002002360200200241386a4200370000200241286a42003700000f0b1030000b130020004101360204200041e8dac3003602000b900301077f230041106b220324000240024002400240200141027441046a2204417f4c0d000240024020040d0041012105410021040c010b200410272205450d020b2003410036020820032005360200200320043602042001200310710240024020010d002003280208210120032802042106200328020021070c010b200141027421084100200328020822016b21052003280204210403402000280200210902400240200420056a4104490d0020032802002107200421060c010b200141046a22072001490d05200441017422062007200620074b1b22064100480d050240024020040d00024020060d00410121070c020b2006102722070d010c080b2003280200210720042006460d00200720042006102b2207450d070b2003200636020420032007360200200621040b200041046a2100200720016a20093600002003200141046a22013602082005417c6a21052008417c6a22080d000b0b20022902002001ad4220862007ad84100302402006450d00200710290b200341106a24000f0b1038000b1039000b1032000b1030000bf40201067f230041106b2203240002400240024002402001412c6c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410272205450d020b20034100360208200320053602002003200436020420012003107102402001450d0020002001412c6c6a21060340200028020021070240024020032802042205200328020822016b4104490d00200328020021040c010b200141046a22042001490d05200541017422082004200820044b1b22084100480d050240024020050d00024020080d00410121040c020b2008102722040d010c080b2003280200210420052008460d00200420052008102b2204450d070b20032008360204200320043602000b200420016a20073600002003200141046a360208200041046a200310f3022000412c6a22002006470d000b0b200328020421002002290200200335020842208620032802002201ad84100302402000450d00200110290b200341106a24000f0b1038000b1039000b1032000b1030000bb904010b7f230041106b22032400024002400240024020014103744104722204417f4c0d00200410272205450d012003410036020820032004360204200320053602002001200310710240024020010d0020032802082101200328020021060c010b200020014103746a21074100200328020822086b210920032802042104410021010340200820016a210a200020016a220b280200210c02400240200420096a4104490d0020032802002106200421050c010b200a41046a2205200a490d05200441017422062005200620054b1b22054100480d050240024020040d00024020050d00410121060c020b2005102722060d010c080b2003280200210620042005460d00200620042005102b2206450d070b20032005360204200320063602000b200620086a20016a200c3600002003200a41046a2204360208200b41046a280200210c02400240200520096a417c6a41034d0d00200521040c010b200441046a220d2004490d0520054101742204200d2004200d4b1b22044100480d050240024020050d00024020040d00410121060c020b200410272206450d080c010b20052004460d00200620052004102b2206450d070b20032004360204200320063602000b200620086a20016a41046a200c3600002003200a41086a360208200941786a2109200141086a2101200b41086a2007470d000b200820016a21010b2003280204210420022902002001ad4220862006ad84100302402004450d00200610290b200341106a24000f0b1038000b1039000b1032000b1030000b1c00200128021841b09bcc00410f2001411c6a28020028020c1100000b960503037f027e057f230041106b220224002002410036020820024201370300200028021021030240410410272204450d0020024104360204200220043602002004200336000020024104360208200041146a2802002103200441044108102b2204450d0020024108360204200420033600042002200436020020024108360208200041086a290300210520002903002106200441084118102b2204450d0020042006370008200441106a200537000020022004360200200242988080808003370204024041000d00200441184138102b2204450d010b20042000290024370018200441206a2000412c6a290000370000200441286a200041346a290000370000200441306a2000413c6a29000037000020024138360204200220043602002002413836020820002802182104200041206a28020022002002107102400240024020000d002002280208210020022802042107200228020021080c010b200041057421094100200228020822006b210a2002280204210b034002400240200b200a6a4120490d0020022802002108200b21070c010b200041206a22032000490d03200b41017422082003200820034b1b22074100480d0302400240200b0d00024020070d00410121080c020b2007102722080d010c060b20022802002108200b2007460d002008200b2007102b2208450d050b20022007360204200220083602002007210b0b200820006a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200041206a2200360208200a41606a210a200441206a2104200941606a22090d000b0b20012902002000ad4220862008ad84100302402007450d00200810290b200241106a24000f0b1032000b1030000b1100419cf7ca00412841b8a1cc001033000bbd0c03037f017e077f230041306b22022400024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b419cf7ca00412841b8a1cc001033000b2001410c6a2802002204ad42a8027e2205422088a70d052005a72203417f4c0d05200141046a28020021064108210102402003450d00200310272201450d070b20024100360218200220013602102002200341a8026e360214200241106a41002004109a0120022802102103200241206a41086a200228021822013602002002200241106a41086a36022420022003200141a8026c6a36022020062006200441a8026c6a200241206a10f603200241086a200228021822033602002002200229031022053703002000410c6a2003360200200041046a2005370200200041013a00000c040b200141026a2f0100210441a80210272203450d062003200141046a28020010f703200041046a2003360200200041026a20043b0100200041023a00000c030b2001410c6a280200220741ffffff3f712007470d0320074105742204417f4c0d03200141026a2f01002108200141046a28020021090240024020040d00410121060c010b200410272206450d050b41002103200241003602282002200636022020022004410576360224200241206a41002007109e012002280228210a02402007450d002007410574210b2002280220200a4105746a210c0340200c20036a2204200920036a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a290000370000200b200341206a2203470d000b200741057441606a410576200a6a41016a210a0b200241186a2204200a36020020022002290320370310200141186a2802002106200141146a28020021092001280210210b41a80210272203450d0520032001411c6a28020010f703200041026a20083b01002000411c6a2003360200200041186a2006360200200041146a2009360200200041106a200b360200200041033a0000200041046a20022903103702002000410c6a20042802003602000c020b2001412c6a280200220741ffffff3f712007470d0220074105742204417f4c0d02200141226a2f01002108200141246a28020021090240024020040d00410121060c010b200410272206450d040b41002103200241003602282002200636022020022004410576360224200241206a41002007109e012002280228210a02402007450d002007410574210b2002280220200a4105746a210c0340200c20036a2204200920036a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a290000370000200b200341206a2203470d000b200741057441606a410576200a6a41016a210a0b200241186a200a360200200220022903202205370310200041226a20083b0100200041246a20053702002000412c6a200a360200200041043a0000200041386a200141386a280200360200200041306a200129023037020020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c010b2001412c6a280200220741ffffff3f712007470d0120074105742204417f4c0d01200141226a2f01002108200141246a28020021090240024020040d00410121060c010b200410272206450d030b41002103200241003602282002200636022020022004410576360224200241206a41002007109e012002280228210a02402007450d002007410574210b2002280220200a4105746a210c0340200c20036a2204200920036a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a290000370000200b200341206a2203470d000b200741057441606a410576200a6a41016a210a0b200241186a200a360200200220022903202205370310200041226a20083b0100200041246a20053702002000412c6a200a360200200041053a0000200041306a20012902303702002000200141016a290000370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000b200241306a24000f0b1038000b1039000b1030000bec3c130d7f017e077f027e017f037e027f017e017f037e057f047e047f047e047f037e017f027e027f230041f0046b22032400200241086a2802002104200228020421050240024002400240024020002001460d0020022802002102200341f1026a2106200341a8036a2107200341ed026a210820034180036a2109200341e0026a210a200341ac036a210b200341dc026a210c03404115210d4100210e02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002802000e1c01020c03040506070c08090a0b0c0d0e0f101112131a141516171800010b200341d0026a200041086a10f803200341d0016a41086a200c41086a290200370300200341d0016a41106a200c41106a2d00003a0000200341cc016a41026a200841026a2d00003a00002003200c2902003703d001200320082f00003b01cc0120032802d802210f20032903d002211020032802f002211120032802f4022112411b210d0c190b200341d0026a200041086a10f903200341d0016a41086a200c41086a2802003602002003200c2902003703d00120032802d802210f20032903d00221104100210e4100210d0c180b200341d0026a200041046a10fa03200341d0016a41086a200a41086a290200370300200341d0016a41106a200a41106a2d00003a0000200341cc016a41026a200641026a2d00003a00002003200a2902003703d001200320062f00003b01cc0120032802d002220e410876211320032802dc02210f20032902d40221104101210d0c160b200041086a29030021104103210d0c160b02400240024002400240024020002d0004417f6a220f41034b0d00200f0e0401020304010b419cf7ca00412841b8a1cc001033000b200041086a280200210f4101210e201421110c030b200041106a2800002115200041086a2900002110200041076a2d0000210f20002f00052113200341d0026a41106a200041246a2d00003a0000200341d0026a41086a2000411c6a2900003703002003200041146a2900003703d0022013200f411074722116200041286a28020021112010a7210f2010422088a721174102210e0c020b200041086a280200210f4103210e201421110c010b200041106a2800002115200041086a2900002110200041076a2d0000210f20002f00052113200341d0026a41106a200041246a2d00003a0000200341d0026a41086a2000411c6a2900003703002003200041146a2900003703d0022013200f411074722116200041286a28020021112010a7210f2010422088a721174104210e0b200341d0016a41106a200341d0026a41106a2d00003a0000200341d0016a41086a200341d0026a41086a290300370300200341cc016a41026a200341026a2d00003a0000200320032903d0023703d001200320032f00003b01cc012017ad422086200fad8421104104210d201121142015210f201621130c150b02400240024002400240024002400240200041086a22132d0000417f6a220f41034b0d00200f0e0401020304010b419cf7ca00412841b8a1cc001033000b200041106a280000210f2000410d6a33000021102000410f6a310000211820003500092119200341d0026a41106a200041246a2d00003a0000200341d8026a2000411c6a290000370300200341026a2013411f6a2d00003a00002003200041146a2900003703d00220032013411d6a2f00003b0100201a41807e71200041286a2d000072211a20192010201842108684422086842110200041386a290300211b200041306a29030021194201211c0c030b200041106a280000210f2000410d6a33000021102000410f6a310000211820003500092119200341d0026a41106a200041246a2d00003a0000200341d8026a2000411c6a290000370300200341026a2013411f6a2d00003a00002003200041146a2900003703d00220032013411d6a2f00003b0100201a41807e71200041286a2d000072211a20192010201842108684422086842110200041386a290300211b200041306a2903002119200041c0006a2903002118200041c8006a290300221da7211e201d422088a7211f4202211c0c030b200041106a280000210f2000410d6a33000021102000410f6a310000211820003500092119200341d0026a41106a200041246a2d00003a0000200341d8026a2000411c6a290000370300200341026a2013411f6a2d00003a00002003200041146a2900003703d00220032013411d6a2f00003b0100201e41807e71200041c8006a2d000072211e20192010201842108684422086842110200041386a290000211b200041306a2900002119200041d8006a2903002120200041d0006a290300211d200041c0006a29000021182000412c6a2800002112200041286a280000211a4203211c2021211f0c030b200041106a280000210f2000410d6a33000021102000410f6a310000211820003500092119200341d0026a41106a200041246a2d00003a0000200341d8026a2000411c6a290000370300200341026a2013411f6a2d00003a00002003200041146a2900003703d00220032013411d6a2f00003b0100201a41807e71200041286a2d000072211a20192010201842108684422086842110200041386a290300211b200041306a29030021194204211c0b202221182021211f0b2023211d20242120202521120b200341d0016a41106a200341d0026a41106a2d00003a0000200341d0016a41086a200341d0026a41086a290300370300200341cc016a41026a200341026a2d00003a0000200320032903d0023703d001200320032f01003b01cc012010420886201c8421102018422888a721264105210d20182122201f2121201d21232020212420122125201a2111201e21270c140b200341d0026a200041046a10fb0320032802d002220e410876211320032902d40221104106210d0c120b200341d0026a200041086a10a302200341d0016a41086a200c41086a290200370300200341d0016a41106a200c41106a2d00003a0000200341cc016a41026a200841026a2d00003a00002003200c2902003703d001200320082f00003b01cc0120034180036a290300211b200341a0036a29030021202003418c036a31000021182003418f036a2d0000211320032903f8022119200329039803211d20032802d802210f20032903d002211020032802f002211120032802f40221122003280290032127200328029403211f200335028803211c20032f008d03210d2003200741b80110e4071a200d2013411074722126201c20184220868421184107210d0c120b0240024020002802040d004100210e0c010b200341086a2000411c6a290000370300200041106a280200210f200341106a200041246a2d00003a0000200341d2016a200041276a2d00003a00002003200041146a290000370300200320002f00253b01d0012000412c6a2802002128200041286a2802002129200041386a290200212a200041306a290200212b200041d8006a290200212c200041d0006a290200212d200041c8006a2802002127200041cc006a280200212e200041c0006a3502002110200041c4006a3100002118200041c5006a2f0000212f200041c7006a2d00002130200341d0026a41086a200041e8006a290000370300200a200041f0006a290000370000200a41086a200041f8006a290000370000200a41106a20004180016a290000370000200a41186a20004188016a2900003700002003200041e0006a2900003703d002200941186a200041a8016a290000370000200941106a200041a0016a290000370000200941086a20004198016a290000370000200920004190016a2900003700002000410c6a2802002213417f4c0d15200028020421110240024020130d004100210d4101210e0c010b20131027220e450d182013210d0b02400240200d2013490d00200d21260c010b200d41017422262013202620134b1b22264100480d170240200d0d0020261027220e0d010c1a0b200d2026460d00200e200d2026102b220e450d190b202f203041107472213120102018422086842132200e2011201310e4071a200341b8026a41106a200341106a2d00003a0000200341b8026a41086a200341086a290300370300200341b4026a41026a200341d0016a41026a2d00003a0000200320032903003703b802200320032f01d0013b01b402200341e4016a200341d0026a41d00010e4071a2013ad4220862026ad8421100b200341d0016a41106a200341b8026a41106a2d00003a0000200341d0016a41086a200341b8026a41086a290300370300200341cc016a41026a200341b4026a41026a2d00003a0000200320032903b8023703d001200320032f01b4023b01cc012003200341e4016a41d00010e4071a200e41087621134109210d202b2119202a211b203221182028211220312126202d211d202c2120202e211f202921110c110b2000280204220e4108762113410a210d0c100b200341d0026a200041086a10fc03200341d0016a41086a200c41086a290200370300200341d0016a41106a200c41106a2d00003a0000200341cc016a41026a200841026a2d00003a00002003200c2902003703d001200320082f00003b01cc0120034180036a290300211b200341a0036a29030021202003418c036a31000021182003418f036a2d0000211320032903f8022119200329039803211d20032802d802210f20032903d002211020032802f002211120032802f40221122003280290032127200328029403211f200335028803211c20032f008d03210d2003200741c00110e4071a200d2013411074722126201c2018422086842118410b210d0c0f0b200341d0026a200041046a10fd03200341d0016a41086a200a41086a290200370300200341d0016a41106a200a41106a2d00003a0000200341cc016a41026a200641026a2d00003a00002003200a2902003703d001200320062f00003b01cc0120034184036a290200211b200341a4036a290200212020034190036a310000211820034193036a2d0000210d20032902fc022119200329029c03211d20032802dc02210f20032902d402211020032802f402211120032802f80221122003280294032127200328029803211f200335028c03211c20032f009103212620032802d002210e200341086a200b41086a2802003602002003200b290200370300200e41087621132026200d411074722126201c2018422086842118410c210d0c0e0b10f403000b200341d0026a200041086a10fe03200341d0016a41086a200c41086a290200370300200341d0016a41106a200c41106a2d00003a0000200341cc016a41026a200841026a2d00003a00002003200c2902003703d001200320082f00003b01cc0120034180036a290300211b20032903f802211920032802d802210f20032903d002211020032802f002211120032802f4022112410e210d0c0c0b200341d0026a200041086a10ff03200341d0016a41086a200c41086a290200370300200341d0016a41106a200c41106a2d00003a0000200341cc016a41026a200841026a2d00003a00002003200c2902003703d001200320082f00003b01cc0120034180036a290300211b20032903f802211920032802d802210f20032903d002211020032802f002211120032802f4022112410f210d0c0b0b200341d0026a200041086a10ff03200341d0016a41086a200c41086a2902003703004110210d200341d0016a41106a200c41106a2d00003a0000200341cc016a41026a200841026a2d00003a00002003200c2902003703d001200320082f00003b01cc0120034180036a290300211b20032903f802211920032802d802210f20032903d002211020032802f002211120032802f40221120c0a0b200341d0026a200041086a108004200341d0016a41086a200c41086a290200370300200341d0016a41106a200c41106a2d00003a0000200341cc016a41026a200841026a2d00003a00002003200c2902003703d001200320082f00003b01cc0120032802d802210f20032903d002211020032802f002211120032802f402211220032903f80221194111210d0c090b0240024002400240024002400240024020002d0004417f6a220d41064b0d004107210e200d0e0701020304050607010b419cf7ca00412841b8a1cc001033000b200041106a280200210f200041086a2902002110200041076a2d0000211320002f0005210d200341d0026a41106a200041246a2d00003a0000200341d0026a41086a2000411c6a2902003703002003200041146a2902003703d002200d20134110747221134101210e0c050b200041106a280200210f200041086a2902002110200041076a2d0000211320002f0005210d200341d0026a41106a200041246a2d00003a0000200341d0026a41086a2000411c6a2902003703002003200041146a2902003703d002200d20134110747221134102210e0c040b200041106a280200210f200041086a2902002110200041076a2d0000211320002f0005210d200341d0026a41106a200041246a2d00003a0000200341d0026a41086a2000411c6a290200370300200341026a200041046a222741236a2d00003a00002003200041146a2902003703d0022003202741216a2f00003b0100200041c0006a350000200041c4006a310000422086842133200d2013411074722113200041386a2900002134200041306a29000021352000412c6a2800002136200041286a28000021374103210e0c030b200041106a280200223041ffffff3f712030470d0e2030410574220f417f4c0d0e200041086a280200210e02400240200f0d004101210d0c010b200f1027220d450d110b41002113200341003602d8022003200d3602d0022003200f4105763602d402200341d0026a41002030109e0120032802d802210f02402030450d002030410574212620032802d002200f4105746a212f0340202f20136a220d200e20136a2227290000370000200d41186a202741186a290000370000200d41106a202741106a290000370000200d41086a202741086a2900003700002026201341206a2213470d000b203041057441606a410576200f6a41016a210f0b20032903d00221104104210e0c020b200041106a280200210f200041086a2902002110200041076a2d0000211320002f0005210d200341d0026a41106a200041246a2d00003a0000200341d0026a41086a2000411c6a2902003703002003200041146a2902003703d002200d20134110747221134105210e0c010b200041106a280200210f200041086a2902002110200041076a2d0000211320002f0005210d200341d0026a41106a200041246a2d00003a0000200341d0026a41086a2000411c6a2902003703002003200041146a2902003703d002200d20134110747221134106210e0b200341d0016a41106a200341d0026a41106a2d00003a0000200341d0016a41086a200341d0026a41086a290300370300200341cc016a41026a200341026a2d00003a0000200320032903d0023703d001200320032f01003b01cc014112210d203521192034211b2033211820362112203721110c070b200341d0026a200041086a108204200341d0016a41086a200c41086a290200370300200341d0016a41106a200c41106a2d00003a0000200341cc016a41026a200841026a2d00003a00002003200c2902003703d001200320082f00003b01cc0120032f008d032003418f036a2d00004110747221262003350288032003418c036a31000042208684211820034180036a290300211b20032903f802211920032802d802210f20032903d002211020032802f002211120032802f40221124113210d0c070b200341d0026a200041046a108304200341d0016a41086a200a41086a290200370300200341d0016a41106a200a41106a2d00003a0000200341cc016a41026a200641026a2d00003a00002003200a2902003703d001200320062f00003b01cc0120034184036a290200211b200341a4036a290200212020034190036a310000211820034193036a2d0000210d20032902fc022119200329029c03211d20032802dc02210f20032902d402211020032802f402211120032802f80221122003280294032127200328029803211f200335028c03211c20032f009103212620032802d002210e2003200b41c40110e4071a200e41087621132026200d411074722126201c20184220868421184114210d0c060b200341d0026a200041086a108404200341d0016a41086a200c41086a290200370300200341d0016a41106a200c41106a2d00003a0000200341cc016a41026a200841026a2d00003a00002003200c2902003703d001200320082f00003b01cc0120032f008d032003418f036a2d00004110747221262003350288032003418c036a31000042208684211820034180036a290300211b20032903f802211920032802d802210f20032903d002211020032802f002211120032802f40221124116210d0c050b200341d0026a200041046a108504200341d0016a41086a200a41086a290200370300200341d0016a41106a200a41106a2d00003a0000200341cc016a41026a200641026a2d00003a00002003200a2902003703d001200320062f00003b01cc0120032802d002220e410876211320032f00910320034193036a2d0000411074722126200335028c0320034190036a31000042208684211820034184036a290200211b20032902fc02211920032802dc02210f20032902d402211020032802f402211120032802f802211220032802940321274117210d0c040b200341d0026a200041086a108604200341d0016a41086a200c41086a290200370300200341d0016a41106a200c41106a2d00003a0000200341cc016a41026a200841026a2d00003a00002003200c2902003703d001200320082f00003b01cc0120034180036a290300211b200341a0036a29030021202003418c036a31000021182003418f036a2d0000211320032903f8022119200329039803211d20032802d802210f20032903d002211020032802f002211120032802f40221122003280290032127200328029403211f200335028803211c20032f008d03210d200341106a200741106a290200370300200341086a200741086a29020037030020032007290200370300200d2013411074722126201c20184220868421184118210d0c030b0240024002400240200041086a220f2d0000417f6a221341024b0d004201211020130e03030102030b419cf7ca00412841b8a1cc001033000b200041106a28000021382000410d6a33000021102000410f6a310000211820003500092119200341d0026a41106a200041246a2d00003a0000200341d8026a2000411c6a290000370300200341026a200f411f6a2d00003a00002003200041146a2900003703d0022003200f411d6a2f00003b0100203941807e71200041286a2d00007221392019201020184210868442208684213a420221100c010b200041106a28000021382000410d6a33000021102000410f6a310000211820003500092119200341d0026a41106a200041246a2d00003a0000200341d8026a2000411c6a290000370300200341026a200f411f6a2d00003a00002003200041146a2900003703d0022003200f411d6a2f00003b0100203b42808080807083200041d0006a35020084213b203941807e71200041286a2d00007221392019201020184210868442208684213a200041c0006a290300223c422888200041c8006a290300221042188684a7213d200041386a290300213e200041306a290300213f2010a721402010422088a72141420321100b200341d0016a41106a200341d0026a41106a2d00003a0000200341d0016a41086a200341d0026a41086a290300370300200341cc016a41026a200341026a2d00003a0000200320032903d0023703d001200320032f01003b01cc01203a42088620108421104119210d203f2119203e211b203c2118203d2126203b211d2041211f203921112038210f204021270c020b200341d0026a200041046a10f503200341d0016a41086a200a41086a290200370300200341d0016a41106a200a41106a2d00003a0000200341cc016a41026a200641026a2d00003a00002003200a2902003703d001200320062f00003b01cc0120032802d002220e410876211320034184036a290200211b20032902fc02211920032802dc02210f20032902d402211020032802f402211120032802f8022112411a210d0b0b200341d0026a41106a222f200341d0016a41106a2d00003a0000200341d0026a41086a2230200341d0016a41086a290300370300200320032903d0013703d00220022013410874200e41ff017172360204200220103703082002200f360210200220032f01cc013b00252002200d360200200241276a200341ce016a2d00003a0000200220032903d0023702142002411c6a2030290300370200200241246a202f2d00003a0000200241c7006a20264110763a0000200220263b0045200241c4006a20184220883c0000200220183e0040200241d8006a20203702002002201d370250200241386a201b370000200220193700302002201f36024c200220273602482002201236002c20022011360028200241e0006a200341c80110e4071a200441016a2104200241a8026a2102200041a8026a22002001470d000b0b20052004360200200341f0046a24000f0b1038000b1032000b1039000b1030000bf01f03047f067e027f230041c0036b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c01020c03040506070c08090a0b0c0d0e0f1011121314151617181900010b200241a0016a200141086a10f8032000411b360200200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c190b200241a0016a200141086a10f90320004100360200200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c180b200241a0016a200141046a10fa0320004101360200200041246a200241c0016a2802003602002000411c6a200241b8016a290300370200200041146a200241b0016a2903003702002000410c6a200241a8016a290300370200200020022903a0013702040c170b20004103360200200041086a200141086a2903003703000c160b02400240024002400240024020012d0004417f6a220341034b0d00200141046a210420030e0401020304010b419cf7ca00412841b8a1cc001033000b200141086a2802002103410121050c030b41022105200241026a200441036a2d00003a0000200241a0016a41086a200141146a290200370300200241b0016a2001411c6a290200370300200241b8016a200141246a2d00003a0000200220042f00013b010020022001410c6a2902003703a001200141086a2802002103200141286a28020021010c020b200141086a2802002103410321050c010b200241026a200441036a2d00003a0000200241a0016a41086a200141146a290200370300200241b0016a2001411c6a290200370300200241b8016a200141246a2d00003a0000200220042f00013b010020022001410c6a2902003703a001200141086a2802002103200141286a2802002101410421050b200020053a0004200020022f01003b000520004104360200200041086a20033602002000410c6a20022903a001370200200041286a2001360200200041076a200241026a2d00003a0000200041146a200241a0016a41086a2903003702002000411c6a200241b0016a290300370200200041246a200241b8016a2802003602000c150b02400240024002400240024002400240200141086a22032d0000417f6a220541034b0d0020050e0401020304010b419cf7ca00412841b8a1cc001033000b200241a8016a200341096a290000370300200241b0016a200341116a290000370300200241b8016a200341196a290000370300200220032900013703a001200141386a2903002106200141306a2903002107410121010c030b200241a8016a200341096a290000370300200241b0016a200341116a290000370300200241b8016a200341196a290000370300200220032900013703a001200141c8006a2903002108200141c0006a2903002109200141386a2903002106200141306a2903002107410221010c030b200241a8016a200341096a290000370300200241b0016a200341116a290000370300200241b8016a200341196a290000370300200220032900013703a0012002200341216a2800003602002002200341246a280000360003200141c8006a3100002108200141c0006a2902002109200141386a2902002106200141306a2902002107200141d8006a290300210a200141d0006a290300210b410321010c030b200241a8016a200341096a290000370300200241b0016a200341116a290000370300200241b8016a200341196a290000370300200220032900013703a001200141386a2903002106200141306a2903002107410421010b0b0b200020022903a0013700092000200228020036002920004105360200200041d8006a200a370300200041d0006a200b370300200041c8006a2008370300200041c0006a2009370300200041386a2006370300200041306a2007370300200041086a20013a00002000412c6a2002280003360000200041116a200241a0016a41086a290300370000200041196a200241b0016a290300370000200041216a200241b8016a2903003700000c140b200241a0016a200141046a10fb03200041063602002000410c6a200241a8016a280200360200200020022903a0013702040c130b200241a0016a200141086a10a302200041086a200241a0016a41900210e4071a200041073602000c120b024002402001280204220c0d00410021030c010b200241a0016a41186a200141286a290000370300200241a0016a41106a200141206a290000370300200241a8016a200141186a290000370300200241a0016a41286a200141386a290000370300200241a0016a41306a200141c0006a290000370300200241a0016a41386a200141c8006a290000370300200241a0016a41c8006a200141d8006a290000370300200241a0016a41d0006a200141e0006a290000370300200241a0016a41d8006a200141e8006a2900003703002002200141106a2900003703a0012002200141306a2900003703c0012002200141d0006a2900003703e001200241a0016a41f8006a20014188016a290000370300200241a0016a41f0006a20014180016a290000370300200241a0016a41e8006a200141f8006a290000370300200241a0016a4198016a200141a8016a290000370300200241a0016a4190016a200141a0016a290000370300200241a0016a4188016a20014198016a2900003703002002200141f0006a29000037038002200220014190016a2900003703a0022001410c6a2802002201417f4c0d130240024020010d0041002105410121030c010b200110272203450d15200121050b0240024020052001490d00200521040c010b200541017422042001200420014b1b22044100480d16024020050d002004102722030d010c180b20052004460d00200320052004102b2203450d170b2003200c200110e4071a2002200241a0016a41a00110e4071a0b200020033602042000410c6a2001360200200041086a2004360200200041106a200241a00110e4071a200041093602000c110b2000410a360200200020012802043602040c100b200241a0016a200141086a10fc03200041086a200241a0016a41980210e4071a2000410b3602000c0f0b200241a0016a200141046a10fd03200041046a200241a0016a41e80010e4071a2000410c3602000c0e0b10f403000b200241a0016a200141086a10fe032000410e360200200041386a200241a0016a41306a290300370300200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c0c0b200241a0016a200141086a10ff032000410f360200200041386a200241a0016a41306a290300370300200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c0b0b200241a0016a200141086a10ff0320004110360200200041386a200241a0016a41306a290300370300200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c0a0b200241a0016a200141086a10800420004111360200200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c090b200241a0016a200141046a108104200041046a200241a0016a41c40010e4071a200041123602000c080b200241a0016a200141086a10820420004113360200200041c0006a200241a0016a41386a290300370300200041386a200241a0016a41306a290300370300200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c070b200241a0016a200141046a108304200041046a200241a0016a41a00210e4071a200041143602000c060b200041153602000c050b200241a0016a200141086a10840420004116360200200041c0006a200241a0016a41386a290300370300200041386a200241a0016a41306a290300370300200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c040b200241a0016a200141046a108504200041046a200241a0016a41c80010e4071a200041173602000c030b200241a0016a200141086a108604200041086a200241a0016a41f00010e4071a200041183602000c020b4102210c0240024002400240200141086a22032d0000417f6a220d41024b0d0041012105200d0e03030201030b419cf7ca00412841b8a1cc001033000b200141c8006a2903002107200141c0006a2903002106200141386a2903002109200141306a2903002108200141d0006a28020021044103210c0b200241b8016a200341196a290000370300200241b0016a200341116a290000370300200241a8016a200341096a290000370300200220032900013703a001200c21050b200020022903a0013700092000200228000036002920004119360200200041c8006a2007370300200041c0006a2006370300200041386a2009370300200041306a2008370300200041086a20053a0000200041d0006a2004360200200041116a200241a0016a41086a290300370000200041196a200241b0016a290300370000200041216a200241b8016a2903003700002000412c6a200241036a2800003600000c010b200241a0016a200141046a10f5032000411a3602002000413c6a200241d8016a280200360200200041346a200241d0016a2903003702002000412c6a200241c8016a290300370200200041246a200241c0016a2903003702002000411c6a200241b8016a290300370200200041146a200241b0016a2903003702002000410c6a200241a8016a290300370200200020022903a0013702040b200241c0036a24000f0b1038000b1039000b1032000b1030000b940301057f230041206b22022400024002400240024002400240024020012d0000417f6a220341034b0d0020030e0401020304010b419cf7ca00412841b8a1cc001033000b41a80210272203450d042003200141046a28020010a806200041013a0000200041046a20033602000c030b41a80210272203450d032003200141046a28020010a806200041046a2003360200200041023a0000200041086a200141086a2903003703000c020b200041033a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c010b200241186a2204200141196a290000370300200241106a2205200141116a290000370300200241086a2206200141096a2900003703002002200129000137030041a80210272203450d012003200141246a28020010a806200041246a2003360200200041043a0000200041196a2004290300370000200041116a2005290300370000200041096a2006290300370000200020022903003700010b200241206a24000f0b1030000ba00a03057f017e017f230041306b2202240002400240024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0020030e0a0102030405060708090a010b419cf7ca00412841b8a1cc001033000b20004101360200200020012802043602040c090b2001410c6a2802002203417f4c0d09200128020421040240024020030d0041002101410121050c010b200310272205450d0b200321010b0240024020012003490d00200121060c010b200141017422062003200620034b1b22064100480d0c024020010d002006102722050d010c0e0b20012006460d00200520012006102b2205450d0d0b20052004200310e40721012000410c6a2003360200200041086a200636020020002001360204200041023602000c080b20004103360200200041086a200141086a2903003703000c070b2001410c6a2802002203417f4c0d07200128020421040240024020030d0041002101410121050c010b200310272205450d09200321010b0240024020012003490d00200121060c010b200141017422062003200620034b1b22064100480d0a024020010d00200610272205450d0c0c010b20012006460d00200520012006102b2205450d0b0b20052004200310e40721012000410c6a2003360200200041086a200636020020002001360204200041043602000c060b2001410c6a2802002203417f4c0d06200128020421040240024020030d0041002101410121050c010b200310272205450d08200321010b0240024020012003490d00200121060c010b200141017422062003200620034b1b22064100480d09024020010d00200610272205450d0b0c010b20012006460d00200520012006102b2205450d0a0b20052004200310e40721012000410c6a2003360200200041086a200636020020002001360204200041053602000c050b20004106360200200020012902043702042000410c6a2001410c6a2802003602000c040b2001410c6a2802002205ad42187e2207422088a70d042007a72206417f4c0d04200128020421030240024020060d00410421010c010b200610272201450d060b20024100360210200220013602082002200641186e36020c200241086a410020051099012002280210210402402005450d002003200541186c6a21062002280208200441186c6a2101200541037441786a4103762108200241186a410c6a21050340200241186a200310f10520052003410c6a10f105200141106a200241186a41106a290300370200200141086a200241186a41086a29030037020020012002290318370200200141186a2101200341186a22032006470d000b200420086a41016a21040b200241206a20043602002002200229030822073703182000410c6a200436020020002007370204200041073602000c030b200241186a200141046a10b504200041083602002000410c6a200241186a41086a280200360200200020022903183702040c020b2001410c6a2802002203417f4c0d02200128020421080240024020030d0041002106410121040c010b200310272204450d04200321060b0240024020062003490d00200621050c010b200641017422052003200520034b1b22054100480d05024020060d00200510272204450d070c010b20062005460d00200420062005102b2204450d060b20042008200310e40721062000410c6a2003360200200041086a20053602002000200636020420004109360200200041106a20012802103602000c010b2000410a3602000b200241306a24000f0b1038000b1039000b1032000b1030000bdd0501097f02400240024002400240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b419cf7ca00412841b8a1cc001033000b200141106a28020021032001410c6a2802002104200141086a2802002105200141046a280200210620012d0001210741a80210272202450d062002200141146a28020010c401200041106a20033602002000410c6a2004360200200041086a2005360200200041046a2006360200200041146a2002360200200020073a0001200041013a00000f0b200041023a0000200041046a200141046a2902003702000f0b2001410c6a2802002202417f4c0d01200141046a28020021060240024020020d0041002103410121050c010b200210272205450d03200221030b0240024020032002490d00200321040c010b200341017422042002200420024b1b22044100480d04024020030d002004102722050d010c060b20032004460d00200520032004102b2205450d050b20052006200210e40721052001411c6a2802002106200141186a280200210720012d00012108200128021421092001280210210a41a80210272203450d042003200141206a28020010c4012000411c6a2006360200200041186a2007360200200041146a2009360200200041106a200a3602002000410c6a2002360200200041086a2004360200200041046a2005360200200041206a2003360200200020083a0001200041033a00000f0b2001410c6a2802002202417f4c0d00200141046a28020021050240024020020d0041002101410121040c010b200210272204450d02200221010b0240024020012002490d00200121030c010b200141017422032002200320024b1b22034100480d03024020010d00200310272204450d050c010b20012003460d00200420012003102b2204450d040b20042005200210e40721012000410c6a2002360200200041086a2003360200200041046a2001360200200041043a00000f0b1038000b1039000b1032000b1030000ba10e03027f017e177f230041a0016b22022400024002400240024020012802082203ad42f0007e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410421010c010b200510272201450d020b20024100360208200220013602002002200541f0006e3602042002410020031097012002280208210502402003450d002006200341f0006c6a21072002280200200541f0006c6a21082005200341047441706a4104766a21090340200241d0006a41086a220a200641186a290000370300200241d0006a41106a220b200641206a290000370300200241d0006a41186a220c200641286a290000370300200241306a41086a220d200641386a29000037030020062900102104200241306a41106a220e200641c0006a290000370300200241306a41186a220f200641c8006a290000370300200241106a41186a2210200641e8006a290000370300200241106a41106a2211200641e0006a290000370300200241106a41086a2212200641d8006a290000370300200220043703502002200629003037033020022006290050370310200628020c2205ad42247e2204422088a70d022004a72203417f4c0d0220062802002113200628020421140240024020030d00410421010c010b200310272201450d040b20024100360278200220013602702002200341246e360274200241f0006a410020051096012002280278211502402005450d00200541246c21162002280270201541246c6a211741002101034002400240024002400240024002400240201420016a22032d00000e06010203040500010b2003410c6a2802002218417f4c0d0b200341046a28020021190240024020180d0041002103410121050c010b201810272205450d0d201821030b0240024020032018490d002003211a0c010b2003410174221a2018201a20184b1b221a4100480d0e024020030d00201a102722050d010c100b2003201a460d0020052003201a102b2205450d0f0b200220052019201810e40736009301410521190c050b2002200341046a28000036009b012002200341016a280000360298012002200341146a290000370380012002200341196a290000370085012002200228029801360290012002200228009b0136009301200341086a280000211a2003410c6a2800002118200341106a2800002105410021190c050b200341106a2802002205417f4c0d09200341086a2802002119200341016a280000211b0240024020050d00410021034101211a0c010b20051027221a450d0b200521030b0240024020032005490d00200321180c010b200341017422182005201820054b1b22184100480d0c024020030d0020181027221a450d0e0c010b20032018460d00201a20032018102b221a450d0d0b201a2019200510e4071a2002201b36029001410121190c040b200341106a2802002205417f4c0d08200341086a2802002119200341016a280000211b0240024020050d00410021034101211a0c010b20051027221a450d0a200521030b0240024020032005490d00200321180c010b200341017422182005201820054b1b22184100480d0b024020030d0020181027221a450d0d0c010b20032018460d00201a20032018102b221a450d0c0b201a2019200510e4071a2002201b36029001410221190c030b200341106a2802002205417f4c0d07200341086a2802002119200341016a280000211b0240024020050d00410021034101211a0c010b20051027221a450d09200521030b0240024020032005490d00200321180c010b200341017422182005201820054b1b22184100480d0a024020030d0020181027221a450d0c0c010b20032018460d00201a20032018102b221a450d0b0b201a2019200510e4071a2002201b36029001410321190c020b410421192002200341046a280200360093012003410c6a2802002118200341086a280200211a0b0b201720016a220320193a0000200341016a200228029001360000200341046a200228009301360000200341106a20053602002003410c6a2018360200200341086a201a360200200341146a2002290380013702002003411c6a20024180016a41086a290300370200201541016a21152016200141246a2201470d000b0b20024180016a41086a2015360200200220022903702204370380012008410c6a20153602002008200437020420082002290350370210200841186a200a29030037020020082013360200200841206a200b290300370200200841286a200c29030037020020082002290330370230200841386a200d290300370200200841c0006a200e290300370200200841c8006a200f290300370200200841e8006a2010290300370200200841e0006a2011290300370200200841d8006a201229030037020020082002290310370250200841f0006a2108200641f0006a22062007470d000b200941016a21050b20002002290300370200200041086a2005360200200241a0016a24000f0b1038000b1039000b1032000b1030000b9e0a03027f047e047f230041e0036b22022400200141106a220329030021042001290300210520012903082106200241f0016a41186a200141f8016a290000370300200241f0016a41106a200141f0016a290000370300200241f8016a200141e8016a2900003703002002200141e0016a2900003703f001420121070240024020064201520d0020024190026a410c6a200341146a29020037020020024190026a41146a2003411c6a29020037020020024190026a411c6a200341246a29020037020020024190026a412c6a200341346a29020037020020024190026a41346a2003413c6a29020037020020024190026a413c6a200341c4006a29020037020020024190026a41c4006a200341cc006a29020037020020024190026a41cc006a200341d4006a29020037020020024190026a41d4006a200341dc006a29020037020020024190026a41dc006a200341e4006a29020037020020022003410c6a290200370294022002200141186a2802003602900220022003412c6a2902003702b402200241f8026a410c6a20014188016a290200370200200241f8026a41146a20014190016a290200370200200241f8026a411c6a20014198016a290200370200200220014180016a2902003702fc022002200128027c3602f802200241f8026a210320024190026a21080c010b20024190026a410c6a200341146a29020037020020024190026a41146a2003411c6a29020037020020024190026a411c6a200341246a29020037020020024190026a412c6a200341346a29020037020020024190026a41346a2003413c6a29020037020020024190026a413c6a200341c4006a29020037020020024190026a41c4006a200341cc006a29020037020020024190026a41cc006a200341d4006a29020037020020024190026a41d4006a200341dc006a29020037020020024190026a41dc006a200341e4006a29020037020020022003410c6a290200370294022002200141186a2802003602900220022003412c6a2902003702b402200241f8026a410c6a20014188016a290200370200200241f8026a41146a20014190016a290200370200200241f8026a411c6a20014198016a290200370200200220014180016a2902003702fc022002200128027c3602f80242002107200241f8026a210320024190026a21080b200341dc006a200141d8016a290200370200200341d4006a200141d0016a290200370200200341cc006a200141c8016a290200370200200341c4006a200141c0016a2902003702002003413c6a200141b8016a290200370200200341346a200141b0016a2902003702002003412c6a200141a8016a2902003702002003200141a0016a290200370224200241086a2209200241f0016a41086a290300370300200241106a220a200241f0016a41106a290300370300200241186a220b200241f0016a41186a290300370300200220022903f00137030020024188016a200841e40010e4071a200241206a200341e40010e4071a2001280280022103200241f8026a20014184026a10b504200041106a2004370300200020073703082000200537030020014190026a2802002101200041186a20024188016a41e40010e4071a200041fc006a200241206a41e40010e4071a200020033602800220004190026a2001360200200041f8016a200b290300370300200041f0016a200a290300370300200041e8016a2009290300370300200041e0016a200229030037030020004184026a20022903f8023702002000418c026a200241f8026a41086a280200360200200241e0036a24000ba50301077f230041106b2202240002400240024002402001410c6a2802002203417f4c0d0020012802042104200128020021050240024020030d0041002106410121070c010b200310272207450d02200321060b0240024020062003490d00200621080c010b200641017422082003200820034b1b22084100480d03024020060d002008102722070d010c050b20062008460d00200720062008102b2207450d040b20072004200310e40721062002200141106a10f3052000410c6a2003360200200041086a20083602002000200636020420002005360200200041106a2002290300370200200041186a200241086a280200360200200020012802243602242000200129021c37021c20002001290228370228200041306a200141306a290200370200200041386a200141386a290200370200200041c0006a200141c0006a290200370200200041c8006a200141c8006a290200370200200041d0006a200141d0006a290200370200200041d8006a200141d8006a290200370200200041e0006a200141e0006a290200370200200241106a24000f0b1038000b1039000b1032000b1030000bce1503037f027e027f230041106b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203411e4b0d0020030e1f0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f010b419cf7ca00412841b8a1cc001033000b200041013a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c1e0b200041023a0000200041046a200141046a2902003702000c1d0b200141046a28020021044101210302400240200141086a2d00004101470d00200141286a2903002105200141206a29030021060c010b200141096a2d000041017121072001410a6a2d00002108410021030b200041033a0000200041286a2005370300200041206a2006370300200041106a20012903103703002000410a6a20083a0000200041096a20073a0000200041086a20033a0000200041046a20043602002000410b6a2002280006360000200041186a200141186a2903003703002000410f6a200241066a41046a2d00003a00000c1c0b200141046a28020021044101210302400240200141086a2d00004101470d00200141286a2903002105200141206a29030021060c010b200141096a2d000041017121072001410a6a2d00002108410021030b200041043a0000200041286a2005370300200041206a2006370300200041106a20012903103703002000410a6a20083a0000200041096a20073a0000200041086a20033a0000200041046a20043602002000410b6a200228000b360000200041186a200141186a2903003703002000410f6a2002410b6a41046a2d00003a00000c1b0b200041053a0000200041046a200141046a2802003602000c1a0b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c190b200041073a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c180b200041083a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c170b200041093a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2902003702000c160b2000410a3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c150b2000410b3a0000200041046a200141046a2802003602000c140b2000410c3a0000200041046a200141046a2802003602000c130b2000410d3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c120b2000410e3a00000c110b2000410f3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c100b200041103a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000c0f0b200041113a00000c0e0b200041123a00000c0d0b2001410c6a2802002203417f4c0d0d200141046a28020021070240024020030d0041002101410121080c010b200310272208450d0f200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d10024020010d002004102722080d010c120b20012004460d00200820012004102b2208450d110b20082007200310e40721012000410c6a2003360200200041086a2004360200200041046a2001360200200041133a00000c0c0b2001410c6a2802002203417f4c0d0c200141046a28020021070240024020030d0041002101410121080c010b200310272208450d0e200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d0f024020010d00200410272208450d110c010b20012004460d00200820012004102b2208450d100b20082007200310e40721012000410c6a2003360200200041086a2004360200200041046a2001360200200041143a00000c0b0b2001410c6a2802002203417f4c0d0b200141046a28020021070240024020030d0041002101410121080c010b200310272208450d0d200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d0e024020010d00200410272208450d100c010b20012004460d00200820012004102b2208450d0f0b20082007200310e40721012000410c6a2003360200200041086a2004360200200041046a2001360200200041153a00000c0a0b2001410c6a2802002203417f4c0d0a200141046a28020021070240024020030d0041002101410121080c010b200310272208450d0c200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d0d024020010d00200410272208450d0f0c010b20012004460d00200820012004102b2208450d0e0b20082007200310e40721012000410c6a2003360200200041086a2004360200200041046a2001360200200041163a00000c090b200041173a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c080b200041183a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c070b200041193a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c060b2000411a3a0000200041046a200141046a2802003602000c050b2000411b3a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c040b2000411c3a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000c030b2000411d3a00000c020b2000411e3a0000200041046a200141046a2802003602000c010b2000411f3a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000b200241106a24000f0b1038000b1039000b1032000b1030000b8a0701097f230041306b22022400024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b419cf7ca00412841b8a1cc001033000b2001412c6a280200220441ffffff3f712004470d0520044105742205417f4c0d05200141246a28020021060240024020050d00410121070c010b200510272207450d070b41002103200241003602182002200736021020022005410576360214200241106a41002004109e012002280218210802402004450d0020044105742109200228021020084105746a210a0340200a20036a2205200620036a2207290000370000200541186a200741186a290000370000200541106a200741106a290000370000200541086a200741086a2900003700002009200341206a2203470d000b200441057441606a41057620086a41016a21080b200241086a220520083602002002200229031037030041002103024020012d00014101470d00200241286a2001411a6a290000370300200241206a200141126a290000370300200241106a41086a2001410a6a2900003703002002200141026a290000370310410121030b200020033a0001200041013a0000200041246a2002290300370200200041026a2002290310370000200041306a20012802303602002000412c6a20052802003602002000410a6a200241106a41086a290300370000200041126a200241206a2903003700002000411a6a200241286a2903003700000c040b41a80210272203450d062003200141046a28020010f703200041046a2003360200200041023a0000200041086a200141086a2802003602000c030b200141046a280200210541a80210272203450d052003200141086a28020010f703200041086a2003360200200041046a2005360200200041033a00002000410c6a2001410c6a2802003602000c020b200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00004100473a00000c010b200041053a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041306a200141306a290300370300200041246a200141246a2902003702000b200241306a24000f0b1038000b1039000b1030000b910502097f017e230041206b22022400024002400240024002400240024002400240024020012d0000417f6a220341054b0d0020030e06010203040506010b419cf7ca00412841b8a1cc001033000b2001410c6a280200220441ffffff3f712004470d0620044105742205417f4c0d06200141046a28020021060240024020050d00410121070c010b200510272207450d080b41002103200241003602182002200736021020022005410576360214200241106a41002004109e012002280218210802402004450d0020044105742109200228021020084105746a210a0340200a20036a2205200620036a2207290000370000200541186a200741186a290000370000200541106a200741106a290000370000200541086a200741086a2900003700002009200341206a2203470d000b200441057441606a41057620086a41016a21080b200241086a200836020020022002290310220b370300200041046a200b3702002000410c6a2008360200200041013a0000200041186a200141186a290300370300200041106a20012903103703000c050b200041023a00000c040b200041033a0000200041046a200141046a2902003702002000410c6a2001410c6a290200370200200041146a200141146a2902003702002000411c6a2001411c6a290200370200200041246a200141246a2902003702000c030b200041043a0000200041046a200141046a2802003602000c020b200041053a0000200041046a200141046a2902003702000c010b200041063a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00004100473a00000b200241206a24000f0b1038000b1039000ba60602087f017e230041206b220224000240024002400240024002400240024002400240024020012d0000417f6a220341064b0d0020030e0701020304050607010b419cf7ca00412841b8a1cc001033000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c060b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c050b200041033a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000c040b2001410c6a280200220441ffffff3f712004470d0420044105742203417f4c0d04200141046a28020021050240024020030d00410121060c010b200310272206450d060b41002101200241003602182002200636021020022003410576360214200241106a41002004109e012002280218210702402004450d0020044105742108200228021020074105746a21090340200920016a2203200520016a2206290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a2900003700002008200141206a2201470d000b200441057441606a41057620076a41016a21070b200241086a200736020020022002290310220a3703002000410c6a2007360200200041046a200a370200200041043a00000c030b200041053a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c020b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c010b200041073a00000b200241206a24000f0b1038000b1039000bde0701057f024002400240024002400240024002400240024002400240024020012d0000417f6a220241074b0d0020020e080102030405060708010b419cf7ca00412841b8a1cc001033000b200041013a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000f0b200041023a0000200041046a200141046a2802003602000f0b200041033a0000200041046a200141046a2802003602000f0b2001412c6a2802002202417f4c0d04200141246a28020021030240024020020d0041002104410121050c010b200210272205450d06200221040b0240024020042002490d00200421060c010b200441017422062002200620024b1b22064100480d07024020040d002006102722050d010c090b20042006460d00200520042006102b2205450d080b20052003200210e40721042000412c6a2002360200200041286a2006360200200041246a2004360200200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000f0b200041053a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2001412c6a2802002202417f4c0d02200141246a28020021030240024020020d0041002104410121050c010b200210272205450d04200221040b0240024020042002490d00200421060c010b200441017422062002200620024b1b22064100480d05024020040d00200610272205450d070c010b20042006460d00200520042006102b2205450d060b20052003200210e40721042000412c6a2002360200200041286a2006360200200041246a2004360200200041063a0000200041386a200141386a290300370300200041306a200129033037030020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000f0b200041073a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000f0b200041083a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b1038000b1039000b1032000b1030000bd22408027f017e187f017e067f017e0e7f017e230041a0036b22022400024002400240024002400240024002402001280200417f6a220341014b0d0020030e020102010b419cf7ca00412841b8a1cc001033000b2001410c6a2802002203ad4290027e2204422088a70d022004a72205417f4c0d02200128020421060240024020050d00410821010c010b200510272201450d040b2002410036024820022001360240200220054190026e360244200241c0006a4100200310a5012002280248210702402003450d00200620034190026c6a2108200228024020074190026c6a2109200241a0026a41186a210a200241a0026a41106a210b200241a0026a41086a210c200241e0026a41286a210d200241e0026a41206a210e03402006280248210f200a200641f0006a290000370300200b200641e8006a290000370300200c200641e0006a290000370300200220062900583703a002200641d4006a2802002210417f4c0d04200628024c21050240024020100d0041002103410121010c010b201010272201450d06201021030b0240024020032010490d00200321110c010b200341017422122010201220104b1b22114100480d07024020030d002011102722010d010c090b20032011460d00200120032011102b2201450d080b20012005201010e4072113200241c0026a41186a221420064190016a290000370300200241c0026a41106a221520064188016a290000370300200241c0026a41086a221620064180016a290000370300200220062900783703c002200241e0026a41386a2212200641d0016a290000370300200241e0026a41306a2217200641c8016a290000370300200d200641c0016a290000370300200e200641b8016a290000370300200241e0026a41186a2218200641b0016a290000370300200241e0026a41106a2219200641a8016a290000370300200241e0026a41086a2205200641a0016a29000037030020022006290098013703e002200241186a221a200641f0016a290000370300200241106a221b200641e8016a290000370300200241086a221c200641e0016a290000370300200220062900d801370300200641086a29030021042006290300211d200241b0016a200641106a10f005200241f0006a41186a221e200641c0006a290000370300200241f0006a41106a221f200641386a290000370300200241f0006a41086a2220200641306a2900003703002002200629002837037002400240200628021c22210d00410021220c010b200641246a2802002203417f4c0d050240024020030d0041002101410121220c010b200310272222450d07200321010b0240024020012003490d00200121230c010b200141017422232003202320034b1b22234100480d08024020010d00202310272222450d0a0c010b20012023460d00202220012023102b2222450d090b20222021200310e4071a2003ad4220862023ad8421240b20024190026a41086a2221200241b0016a41086a2223280200360200200241f0016a41086a22252020290300370300200241f0016a41106a2226201f290300370300200241f0016a41186a2227201e290300370300200241d0016a41086a2228200c290300370300200241d0016a41106a2229200b290300370300200241d0016a41186a222a200a290300370300200220022903b00137039002200220022903703703f001200220022903a0023703d001200241b0016a41186a222b2014290300370300200241b0016a41106a222c201529030037030020232016290300370300200220022903c0023703b001200241f0006a41386a222d2012290300370300200241f0006a41306a222e2017290300370300200241f0006a41286a222f200d290300370300200241f0006a41206a2230200e290300370300201e2018290300370300201f201929030037030020202005290300370300200220022903e002370370200241d0006a41186a2231201a290300370300200241d0006a41106a2232201b290300370300200241d0006a41086a221b201c290300370300200220022903003703502006280280022216ad42c1007e2233422088a70d042033a72201417f4c0d0420062802f80121030240024020010d00410121140c010b200110272214450d060b20024100360208200220143602002002200141c1006e36020420024100201610a2012002280208211a02402016450d002003201641c1006c6a21152002280200201a41c1006c6a2101034020032d000021142012200341396a2900003703002017200341316a290000370300200d200341296a290000370300200e200341216a2900003703002018200341196a2900003703002019200341116a2900003703002005200341096a2900003703002002200341016a2900003703e002200120143a0000200141016a20022903e002370000200141096a2005290300370000200141116a2019290300370000200141196a2018290300370000200141216a200e290300370000200141296a200d290300370000200141316a2017290300370000200141396a2012290300370000200141c1006a2101200341c1006a22032015470d000b201a20166a211a0b2005201a360200200220022903003703e00220062802840221180240024020064188026a280200220141037622120d004101211741002103410021120c010b4101210302402012410820014107716b22174d0d0041024101201220176b22034107711b20034103766a21030b200310272217450d0602404101450d00200321120c010b200341017422122003201220034b1b22124100480d07024020030d00201210272217450d090c010b20032012460d00201720032012102b2217450d080b20172018200310e407210320092002290390023703102009202236021c200941186a2021280200360200200920043703082009201d3703002009202437022020092010360254200920113602502009201336024c2009200f360248200920022903f001370328200941306a2025290300370300200941386a2026290300370300200941c0006a2027290300370300200941f0006a202a290300370300200941e8006a2029290300370300200941e0006a2028290300370300200920022903d001370358200920022903b00137037820094180016a202329030037030020094188016a202c29030037030020094190016a202b290300370300200941d0016a202d290300370300200941c8016a202e290300370300200941c0016a202f290300370300200941b8016a2030290300370300200941b0016a201e290300370300200941a8016a201f290300370300200941a0016a20202903003703002009200229037037039801200941f0016a2031290300370300200941e8016a2032290300370300200941e0016a201b290300370300200920022903503703d80120094180026a2005280200360200200920022903e0023703f8012009201236028c0220092001360288022009200336028402200741016a210720094190026a210920064190026a22062008470d000b0b200241e8026a20073602002002200229034022043703e0022000410c6a200736020020002004370204200041013602000c010b200241a0026a41186a200141d4006a290000370300200241a0026a41106a200141cc006a290000370300200241a0026a41086a200141c4006a29000037030020022001413c6a2900003703a002200141046a21030240024002400240200141dc006a2d00000e03010200010b200241e0026a41186a200341f1006a290000370300200241e0026a41106a200341e9006a290000370300200241e0026a41086a200341e1006a2900003703002002200341d9006a2900003703e0024102210d200241e0026a21050c020b200241e0026a41186a200341f1006a290000370300200241e0026a41106a200341e9006a290000370300200241e0026a41086a200341e1006a2900003703002002200341d9006a2900003703e0024100210d200241e0026a21050c010b200241e0026a41186a200341f1006a290000370300200241e0026a41106a200341e9006a290000370300200241e0026a41086a200341e1006a2900003703002002200341d9006a2900003703e0024101210d200241e0026a21050b200241c0026a41186a200541186a290000370300200241c0026a41106a200541106a290000370300200241c0026a41086a200541086a290000370300200220052900003703c002200241e0026a41086a20034181016a290000370300200241e0026a41106a20034189016a290000370300200241e0026a41186a20034191016a29000037030020024180036a20034199016a29000037030020024188036a200341a1016a29000037030020024190036a200341a9016a29000037030020024198036a200341b1016a2900003703002002200341f9006a2900003703e002024002400240024020032d00b9010e03010200010b200241f0006a41186a200341d2016a290000370300200241f0006a41106a200341ca016a290000370300200241f0006a41086a200341c2016a2900003703002002200341ba016a2900003703704102210e200241f0006a21050c020b200241f0006a41186a200341d2016a290000370300200241f0006a41106a200341ca016a290000370300200241f0006a41086a200341c2016a2900003703002002200341ba016a2900003703704100210e200241f0006a21050c010b200241f0006a41186a200341d2016a290000370300200241f0006a41106a200341ca016a290000370300200241f0006a41086a200341c2016a2900003703002002200341ba016a2900003703704101210e200241f0006a21050b200241b0016a41186a2212200541186a290000370300200241b0016a41106a2217200541106a290000370300200241b0016a41086a2218200541086a290000370300200220052900003703b001200241086a2205200341e2016a290000370300200241106a2219200341ea016a290000370300200241186a2209200341f2016a290000370300200241206a2214200341fa016a290000370300200241286a220620034182026a290000370300200241306a22152003418a026a290000370300200241386a221020034192026a2900003703002002200341da016a29000037030020012802042103200241d0006a200141086a10b504200241f0016a41086a2216200241a0026a41086a290300370300200241f0016a41106a221e200241a0026a41106a290300370300200241f0016a41186a221f200241a0026a41186a290300370300200241d0016a41086a2220200241c0026a41086a290300370300200241d0016a41106a221a200241c0026a41106a290300370300200241d0016a41186a2223200241c0026a41186a290300370300200241f0006a41386a2222200241e0026a41386a290300370300200241f0006a41306a2211200241e0026a41306a290300370300200241f0006a41286a2207200241e0026a41286a290300370300200241f0006a41206a220a200241e0026a41206a290300370300200241f0006a41186a220b200241e0026a41186a290300370300200241f0006a41106a220c200241e0026a41106a290300370300200241f0006a41086a220f200241e0026a41086a290300370300200220022903a0023703f001200220022903c0023703d001200220022903e002370370200141146a290200210420002003360204200041086a2002290350370200200041106a200241d0006a41086a280200360200200041146a20043702002000413c6a20022903f001370200200041c4006a2016290300370200200041cc006a201e290300370200200041d4006a201f2903003702002000411c6a2001411c6a290200370200200041246a200141246a2902003702002000412c6a2001412c6a290200370200200041346a200141346a290200370200200041dc006a200d3a0000200041f5006a2023290300370000200041ed006a201a290300370000200041e5006a2020290300370000200020022903d00137005d200041b5016a2022290300370000200041ad016a2011290300370000200041a5016a20072903003700002000419d016a200a29030037000020004195016a200b2903003700002000418d016a200c29030037000020004185016a200f2903003700002000200229037037007d2000200e3a00bd01200041d6016a2012290300370000200041ce016a2017290300370000200041c6016a2018290300370000200020022903b0013700be0120004196026a20102903003700002000418e026a201529030037000020004186026a2006290300370000200041fe016a2014290300370000200041f6016a2009290300370000200041ee016a2019290300370000200041e6016a2005290300370000200020022903003700de01200041023602000b200241a0036a24000f0b1038000b1039000b1032000b1030000b930701087f230041206b2202240002400240024002400240024002400240024002400240024020012d0000417f6a220341054b0d0020030e06010203040506010b419cf7ca00412841b8a1cc001033000b200041013a0000200041046a200141046a2902003702000c050b200041023a0000200041206a200141206a290300370300200041186a200141186a2903003703002000410c6a2001410c6a290200370200200041046a200141046a2902003702000c040b200041033a0000200041186a200141186a290300370300200041106a200141106a2903003703002000410c6a2001410c6a280200360200200041046a200141046a2902003702000c030b200041043a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c020b200141286a2802002104200141246a2802002105200241186a200141196a290000370300200241106a200141116a290000370300200241086a200141096a29000037030020022001290001370300200141386a2802002203417f4c0d02200141306a28020021062001412c6a28020021070240024020030d0041002101410121080c010b200310272208450d04200321010b0240024020012003490d00200121090c010b200141017422092003200920034b1b22094100480d05024020010d002009102722080d010c070b20012009460d00200820012009102b2208450d060b20082006200310e4072101200041286a2004360200200041246a2005360200200041386a2003360200200041346a2009360200200041306a20013602002000412c6a2007360200200041053a000020002002290300370001200041096a200241086a290300370000200041116a200241106a290300370000200041196a200241186a2903003700000c010b200141106a2802002203417f4c0d01200141086a2802002104200141046a28020021050240024020030d0041002101410121080c010b200310272208450d03200321010b0240024020012003490d00200121090c010b200141017422092003200920034b1b22094100480d04024020010d00200910272208450d060c010b20012009460d00200820012009102b2208450d050b20082004200310e4072101200041106a20033602002000410c6a2009360200200041086a2001360200200041046a2005360200200041063a00000b200241206a24000f0b1038000b1039000b1032000b1030000bbc0801097f02400240024002400240024002400240024002400240024020012d0000417f6a220241064b0d0020020e0701020304050607010b419cf7ca00412841b8a1cc001033000b200141106a2802002202417f4c0d06200141086a2802002103200141046a280200210420012d000121050240024020020d0041002106410121070c010b200210272207450d08200221060b0240024020062002490d00200621080c010b200641017422082002200820024b1b22084100480d09024020060d002008102722070d010c0b0b20062008460d00200720062008102b2207450d0a0b20072003200210e40721092001411c6a2802002206417f4c0d062001280214210a0240024020060d0041002101410121030c010b200610272203450d08200621010b0240024020012006490d00200121070c010b200141017422072006200720064b1b22074100480d09024020010d00200710272203450d0b0c010b20012007460d00200320012007102b2203450d0a0b2003200a200610e40721012000411c6a2006360200200041186a2007360200200041146a2001360200200041106a20023602002000410c6a2008360200200041086a2009360200200041046a2004360200200041013a00002000200541ff01714101463a00010f0b200041023a0000200041046a200141046a2802003602000f0b200041033a0000200041046a200141046a2802003602000f0b2001410c6a2802002202417f4c0d03200141046a28020021030240024020020d0041002106410121070c010b200210272207450d05200221060b0240024020062002490d00200621080c010b200641017422082002200820024b1b22084100480d06024020060d00200810272207450d080c010b20062008460d00200720062008102b2207450d070b20072003200210e4072104200141186a2802002206417f4c0d03200128021021050240024020060d0041002101410121030c010b200610272203450d05200621010b0240024020012006490d00200121070c010b200141017422072006200720064b1b22074100480d06024020010d00200710272203450d080c010b20012007460d00200320012007102b2203450d070b20032005200610e4072101200041186a2006360200200041146a2007360200200041106a20013602002000410c6a2002360200200041086a2008360200200041046a2004360200200041043a00000f0b20002001290001370001200041c4006a200141c4006a280200360200200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a290000370000200041053a00000f0b200041063a00000f0b200041073a0000200041046a200141046a2802003602000f0b1038000b1039000b1032000b1030000bcd0803037f037e027f230041f0006b22022400024002400240024002400240024002400240024020012d0000417f6a220341034b0d0020030e0401020304010b419cf7ca00412841b8a1cc001033000b20002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a41c10010e4071a200041013a00000c030b200241086a41106a2203200141116a280000360200200241086a41086a2204200141096a29000037030020022001290001370308200141206a2903002105200141186a2903002106420021070240200141286a2903004201520d00200241286a41206a200141d0006a290300370300200241286a41186a200141c8006a290300370300200241286a41106a200141c0006a290300370300200241286a41086a200141386a2903003703002002200141306a290300370328420121070b20002002290308370001200041206a2005370300200041186a2006370300200041286a2007370300200041306a2002290328370300200041096a2004290300370000200041116a2003280200360000200041386a200241286a41086a290300370300200041c0006a200241286a41106a290300370300200041c8006a200241286a41186a290300370300200041d0006a200241286a41206a29030037030020012d00152101200041023a0000200041156a4102200141004720014102461b3a00000c020b200241206a200141196a290000370300200241186a200141116a290000370300200241106a200141096a29000037030020022001290001370308200241286a200141216a41c10010e4071a200141ec006a2802002203417f4c0d02200141e4006a28020021080240024020030d0041002101410121090c010b200310272209450d04200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d05024020010d002004102722090d010c070b20012004460d00200920012004102b2209450d060b20092008200310e4072101200041196a200241206a290300370000200041116a200241186a290300370000200041096a200241106a29030037000020002002290308370001200041216a200241286a41c10010e4071a200041ec006a2003360200200041e8006a2004360200200041e4006a2001360200200041033a00000c010b2001410c6a2802002203417f4c0d01200141046a28020021080240024020030d0041002101410121090c010b200310272209450d03200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d04024020010d00200410272209450d060c010b20012004460d00200920012004102b2209450d050b20092008200310e40721012000410c6a2003360200200041086a2004360200200041046a2001360200200041043a00000b200241f0006a24000f0b1038000b1039000b1032000b1030000bbd1103077f017e0e7f230041e0076b2203240041002104200341003602a803200320023602a403200320013602a0034101210541012106024002400240024002400240024002400240024002400240024002400240024002400240024002402002450d0041012107200341013602a803024020012d000022080d000c020b0240024002400240024002400240024002400240024002400240200841c00171220741c001460d0002402007418001460d0041012106200741c000470d0e410121072008413f712204413f470d0541022107414121044101210603402007417f6a20024f0d0f200320073602a803200120076a417f6a2d0000220841ff01470d05200441817e6a2104200741016a2207418302470d000b2007417f6a210741ffff032104410121090c0c0b4200210a410121072008413f712204413f470d0641022107414121044101210603402007417f6a20024f0d0e200320073602a803200120076a417f6a2d0000220841ff01470d06200441817e6a2104200741016a2207418302470d000b2007417f6a21074200210a0c010b428002210a410121072008413f712204413f470d0541022107414121044101210603402007417f6a20024f0d0d200320073602a803200120076a417f6a2d0000220841ff01470d02200441817e6a2104200741016a2207418302470d000b2007417f6a2107428002210a0b200a50210841ffff032104410121090c050b200820046b21040c030b200820046b21040b200441017122090d060c070b200820046b21040b200a50210820044101712209450d010b200720024f0d0141002106200120076a2d000041104f0d050b410121062007200441016a4101766a220b20024b0d042003200b3602a803200b41026a220420024b0d04200320043602a803200b417e4f0d012001200b6a2f0000210c410021044100210d024020080d00200341106a200341a0036a10880420032802100d0520032802a803220e20032802146a220f20032802a4034b0d052003200f3602a8034101210d0b200341023602f402200341023602e802200341023602dc02200341023602d002200341023602c402200341023602b802200341023602ac02200341023602a00220034102360294022003410236028802200341023602fc01200341023602f001200341023602e401200341023602d801200341023602cc01200341023602c001200341c0016a210603400240200c41012004410f71747141ffff0371450d00200341086a200341a0036a1088040240024020032802080d0020032802a8032210200328020c22116a220820032802a4034d0d010b410121060c070b200320083602a803200641086a2008360200200641046a2010360200200620114120473602000b2006410c6a2106200441016a22044110470d000b200341a0066a200341c0016a41c00110e4071a410421040c050b200720024190dcc30010360c060b200b200441f0dbc300104c000b200720024f0d0341002106200120076a2d000041104f0d010b410121062007200441016a4101766a220b20024b0d002003200b3602a8032003200341a0036a10880420032802000d0020032802a803220d20032802046a220e20032802a4034b0d002003200e3602a803200341a0066a200341c0016a41c00110e4071a410121040c010b200341a0036a200341a0066a41c00110e4071a200020063a00010c0e0b200341a0036a200341a0066a41c00110e4071a200341c0016a41186a200f360200200341c0016a41146a200e360200200341c0016a41106a200d360200200341c0016a410c6a2009360200200341c0016a41086a200b360200200320073602c401200320043602c001200341c0016a411c6a200341a0036a41c00110e4072112410021054100211320040e050c020101030c0b200720024180dcc3001036000b000b200b2007490d01200b20024b0d02200e200d490d03200e20024b0d04200b20076b2114200120076a21152001200d6a2116200e200d6b2117410121130c090b200341023602d407200341023602c807200341023602bc07200341023602b007200341023602a40720034102360298072003410236028c072003410236028007200341023602f406200341023602e806200341023602dc06200341023602d006200341023602c406200341023602b806200341023602ac06200341023602a006410021060340410221080240201220066a2204280200410246220c0d0041002004200c1b220841086a2802002104200841046a28020021100240024020082802004101470d0020042010490d0841012108200420024d0d012004200241b8a2cc00104b000b20042010490d0841002108200420024b0d090b200420106b2111200120106a21100b200341a0066a20066a22042008360200200441086a2011360200200441046a20103602002006410c6a220641c001460d080c000b0b2007200b41b0a3cc00104c000b200b200241b0a3cc00104b000b200d200e41c0a3cc00104c000b200e200241c0a3cc00104b000b2010200441b8a2cc00104c000b2010200441c8a2cc00104c000b2004200241c8a2cc00104b000b02400240200d4101460d00410021080c010b200f200e490d03200f20024b0d04200f200e6b21062001200e6a21080b200b2007490d04200b20024b0d05200341a8066a280200211820032802a406211720032802a0062116200341186a200341ac066a41a80110e4071a200b20076b2114200120076a2115200341dc076a2802002110200341d8076a280200211120032802d407210c410421130b2000411c6a2018360200200041186a2017360200200041146a2016360200200041106a20093602002000410c6a2014360200200041086a2015360200200041046a2013360200200041206a200341186a41a80110e4071a200041d8016a2006360200200041d4016a2008360200200041d0016a2010360200200041cc016a2011360200200041c8016a200c3602000b200020053a0000200341e0076a24000f0b200e200f41d0a3cc00104c000b200f200241d0a3cc00104b000b2007200b41b0a3cc00104c000b200b200241b0a3cc00104b000b890301077f41012102024002402001280208220341016a2204200128020422054d0d000c010b0240024002400240200320054f0d002001280200220620036a2d00002107200120043602080240200741037122084103460d0002400240024020080e03000102000b20074102762108410021020c070b0240200341026a220320054d0d000c070b200120033602082004417f460d03200620046a2d0000410874200772220141ffff0371418002490d06200141fcff03714102762108410021020c060b200341046a220320054b0d05200120033602082004417d4f0d03200620046a22012f0000200141026a2d000041107472410874200772220141808004492102200141027621080c050b0240200741034d0d000c050b200341056a220320054b0d04200120033602082004417c4f0d03200620046a28000022084180808080044921020c040b2003200541d09ccc001036000b417f200341dc9bcc00104c000b2004200341dc9bcc00104c000b2004200341dc9bcc00104c000b20002008360204200020023602000bc5a60107117f017e057f027e157f027e047f230041f00f6b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341940d6a4101360200200342013702840d20034198e3ca003602800d2003410436029c05200341cce3ca0036029805200320034198056a3602900d200341800d6a4180a6cc001040000b200341e00c6a41086a200241186a290200370300200341ed0c6a2002411d6a2900003700002003200241106a2902003703e00c200241046a28020021042001410c6a2802002105200141086a2802002106200141046a28020021072002410c6a2802002108200241086a28020021094102210a200241026a2f0100210b20022d0001210c410121010240024002400240024020022d0000220d0e0400010204000b024002400240200c0e03000102000b4100210a410021010c050b200341c80f6a41106a200341e00c6a41106a2f01003b0100200341c80f6a41086a200341e00c6a41086a290300370300200320032903e00c3703c80f4101210a0b410021010c030b41012101200441ff01714101470d01200341f0026a410d6a200341e00c6a410d6a290000370000200341f0026a41086a200341e00c6a41086a290300370300200320032903e00c3703f0020c010b41012101200441ff01714101470d00200341f0026a410d6a200341e00c6a410d6a290000370000200341f0026a41086a200341e00c6a41086a290300370300200320032903e00c3703f0020b0b2004410876210e2007200541a8026c6a21022001200a7241ff01710d2820072101024002402005450d00200341e8096a41106a210f200341800d6a410472211020034198056a4104722111200441ff017121124100210a2007210103402001280200210520034198056a200141046a221341a40210e4071a200341800d6a201341a40210e4071a02402005411c470d00200141a8026a21010c2d0b200341e8096a200341800d6a41a40210e4071a200341c0076a200341e8096a41a40210e4071a200341f0026a200341c0076a41a40210e4071a200341c8006a200341f0026a41a40210e4071a20032005360298052011200341c8006a41a40210e4071a200320053602800d2010200341c8006a41a40210e4071a02400240024002400240200d0e0400010203000b41022105024002400240200c0e03000102000b410021050c010b200341c80f6a41106a200341e00c6a41106a2f01003b0100200341c80f6a41086a200341e00c6a41086a290300370300200320032903e00c3703c80f410121050b200f20032903c80f370000200f41086a200341c80f6a41086a290300370000200f41106a200341c80f6a41106a2f01003b0000200320083602f409200320093602f009200320043602ec092003200b3b01ea09200320053a00e909200341003a00e8090c030b4102210502400240024020120e03000102000b410021050c010b200341f0026a410d6a200341e00c6a410d6a290000370000200341f0026a41086a200341e00c6a41086a290300370300200320032903e00c3703f002410121050b200f20032903f002370200200f41086a200341f0026a41086a290300370200200f41106a200341f0026a41106a290300370200200320083602f409200320093602f009200320053a00ec09200341013a00e8092003200e3b00ed092003200e4110763a00ef090c020b4102210502400240024020120e03000102000b410021050c010b200341f0026a410d6a200341e00c6a410d6a290000370000200341f0026a41086a200341e00c6a41086a290300370300200320032903e00c3703f002410121050b200f20032903f002370200200f41086a200341f0026a41086a290300370200200f41106a200341f0026a41106a290300370200200320083602f409200320093602f009200320053a00ec09200341023a00e8092003200e3b00ed092003200e4110763a00ef090c010b200341033a00e809200320043602ec090b200341c0076a200341800d6a200341e8096a10c50120032903c0074201510d02200a41016a210a200141a8026a22012002470d000b200221010b200341800d6a20034198056a41a40210e4071a0c2a0b200141a8026a21010c2b0b410a210f4102210a200141046a280200210520022d00000d2420022d00014101470d242002411a6a2901002114200241196a2d00002113200241186a2d00002104200241166a2f01002107200241156a2d0000210e200241146a2d0000210d200241126a2f01002108200241116a2d00002109200241106a2d000021062002410e6a2f010021102002410d6a2d000021112002410c6a2d0000210c2002410a6a2f0100210b200241096a2d00002112200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f01002102200141026a2f010021194103210a02400240024020052802000e1c02020202022702020202020202022727272727270127272702000202020b4103210a200541086a2d00004103470d010c260b20052802044101470d250b411210272201450d03200141086a41002900a8dc43370000200141002900a0dc43370000200141124130102b2201450d1520012014370028200120133a0027200120043a0026200120073b00242001200e3a00232001200d3a0022200120083b0020200120093a001f200120063a001e200120103b001c200120113a001b2001200c3a001a2001200b3b0018200120123a0017200120153a0016200120163b0014200120173a0013200120183a0012200120023b00102001413041e000102b2202450d15200220193b00302002ad4280808080a00684101022012900002114200141086a290000211a200141106a290000211b200341e00c6a41186a220a200141186a290000370300200341e00c6a41106a220f201b370300200341e00c6a41086a2213201a370300200320143703e00c2001102920021029200341093a00a00d2003410a3a00a00d2003410b3a00a00d200320032f01e00c3b01800d200320032801e20c3601820d200320032f01e60c3b01860d200320132f01003b01880d200320032d00ea0c3a008a0d2003410c3a00a00d200320032d00eb0c3a008b0d2003410d3a00a00d200320032d00ec0c3a008c0d2003410e3a00a00d200320032d00ed0c3a008d0d2003410f3a00a00d200320032d00ee0c3a008e0d200341103a00a00d200320032d00ef0c3a008f0d200341113a00a00d2003200f2d00003a00900d200320032d00f10c3a00910d200341123a00a00d200341133a00a00d200320032d00f20c3a00920d200341143a00a00d200320032d00f30c3a00930d200341153a00a00d200320032d00f40c3a00940d200341163a00a00d200320032d00f50c3a00950d200341173a00a00d200320032d00f60c3a00960d200341183a00a00d200320032d00f70c3a00970d200341193a00a00d2003200a2d00003a00980d200320032d00f90c3a00990d2003411a3a00a00d2003411b3a00a00d200320032d00fa0c3a009a0d2003411c3a00a00d200320032d00fb0c3a009b0d2003411d3a00a00d200320032d00fc0c3a009c0d2003411e3a00a00d200320032d00fd0c3a009d0d2003411f3a00a00d200320032d00fe0c3a009e0d200341203a00a00d200320032d00ff0c3a009f0d20034198056a41186a220120032903980d37030020034198056a41106a220220032903900d37030020034198056a41086a220a20032903880d370300200320032903800d37039805200341c0076a41186a220f2001290300370300200341c0076a41106a22012002290300370300200341c0076a41086a2202200a29030037030020032003290398053703c007200341800d6a200541a80210e4071a20034198056a410a6a200229030037010020034198056a41126a200129030037010020034198056a411a6a200f29030037010020034180023b019805200320032903c00737019a05200341e8096a200341800d6a20034198056a10c50120032903e8094201520d2220032903f0094202510d22200341e8096a41206a280200210f200341e8096a411c6a2802002104200341e8096a41186a280200220a4180808078712101200a4180807c712102200a41807e7121130c230b200141086a280200210f200141046a28020021072001411c6a28020021054102210a024020022d00000d0020022d00014101470d002001410c6a2802002119200141186a280200211c200141146a280200211d200141106a280200211e200141026a2f0100211f200241196a2d00002101200241186a2d0000210a200241166a2f01002113200241156a2d00002104200241146a2d0000210e200241126a2f0100210d200241116a2d00002108200241106a2d000021092002410e6a2f010021062002410d6a2d000021102002410c6a2d000021112002410a6a2f0100210c200241096a2d0000210b200241086a2d00002112200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820032002411a6a2901003703a80c200320013a00a70c2003200a3a00a60c200320133b01a40c200320043a00a30c2003200e3a00a20c2003200d3b01a00c200320083a009f0c200320093a009e0c200320063b019c0c200320103a009b0c200320113a009a0c2003200c3b01980c2003200b3a00970c200320123a00960c200320153b01940c200320163a00930c200320173a00920c200320183b01900c02400240024020052802000e1c16161616160216161616161616160202020202020002020216011616160b20052802044101470d010c150b200541086a2d00004103470d140b410a21014182d5c2002102410c21134103210a0c140b0c130b200141286a280200210a200141246a28020021044102210520022d00000d0d20022d00014101470d0d200141196a2900002114200141186a2d0000211f200141176a2d0000211e200141156a2f0000211d200141146a2d0000211c200141136a2d00002120200141116a2f00002121200141106a2d000021222001410f6a2d000021232001410d6a2f000021242001410c6a2d000021252001410b6a2d00002126200141096a2f00002127200141086a2d00002128200141076a2d00002129200141056a2f0000212a200141046a2d0000212b200141036a2d0000212c2001412c6a280200210f200141386a280200212d200141346a280200212e200141306a280200212f200141226a2f0100210720012f00012130200241196a2d00002101200241186a2d00002105200241166a2f01002113200241156a2d0000210e200241146a2d0000210d200241126a2f01002108200241116a2d00002109200241106a2d000021062002410e6a2f010021102002410d6a2d000021112002410c6a2d0000210c2002410a6a2f0100210b200241096a2d00002112200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211920032002411a6a290100370360200320013a005f200320053a005e200320133b015c2003200e3a005b2003200d3a005a200320083b0158200320093a0057200320063a0056200320103b0154200320113a00532003200c3a00522003200b3b0150200320123a004f200320153a004e200320163b014c200320173a004b200320183a004a200320193b0148024020070d0041abd6c200210f410d210241032105410021010c0f0b410321050240200f0d0041fad5c200210f41112102410321010c0f0b0240200f41e3004d0d0041e8d5c200210f41122102410421010c0f0b2003200f3602f0092003200a3602ec09200320043602e809200341800d6a41186a200341c8006a41186a290300370300200341800d6a41106a2202200341c8006a41106a290300370300200341800d6a41086a2201200341c8006a41086a290300370300200320032903483703800d20034198056a200341e8096a200341800d6a108a0402402003280298054101460d0020034198056a41086a2205280200210e200328029c052104200120034198056a410c6a280200360200200320073b018c0d200320043602840d200341a0dcc3003602800d200341e00c6a200341800d6a108b04200341083a00a00d2003410b3a00a00d2003410c3a00a00d200320032f01e00c3b01800d200320032801e20c3601820d200320032d00e60c3a00860d200320032800e70c3600870d200320032d00eb0c3a008b0d2003410d3a00a00d200320032d00ec0c3a008c0d2003410e3a00a00d200320032d00ed0c3a008d0d2003410f3a00a00d200320032d00ee0c3a008e0d200320032d00ef0c3a008f0d200341103a00a00d200341113a00a00d200320032d00f00c3a00900d200341123a00a00d200320032d00f10c3a00910d200341133a00a00d200320032d00f20c3a00920d200341143a00a00d200320032d00f30c3a00930d200341153a00a00d200320032d00f40c3a00940d200341163a00a00d200320032d00f50c3a00950d200341173a00a00d200320032d00f60c3a00960d200320032d00f70c3a00970d200341183a00a00d200341193a00a00d200320032d00f80c3a00980d2003411a3a00a00d200320032d00f90c3a00990d2003411b3a00a00d200320032d00fa0c3a009a0d2003411c3a00a00d200320032d00fb0c3a009b0d2003411d3a00a00d200320032d00fc0c3a009c0d2003411e3a00a00d200320032d00fd0c3a009d0d2003411f3a00a00d200320032d00fe0c3a009e0d200320032d00ff0c3a009f0d200341203a00a00d20034198056a41186a220a20032903980d37030020034198056a41106a220f20032903900d370300200520032903880d370300200320032903800d37039805200341f0026a41186a200a290300370300200341f0026a41106a200f290300370300200341f0026a41086a200529030037030020032003290398053703f002200320143703f80c2003201f3a00f70c2003201e3a00f60c2003201d3b01f40c2003201c3a00f30c200320203a00f20c200320213b01f00c200320223a00ef0c200320233a00ee0c200320243b01ec0c200320253a00eb0c200320263a00ea0c200320273b01e80c200320283a00e70c200320293a00e60c2003202a3b01e40c2003202b3a00e30c2003202c3a00e20c200320303b01e00c20034198056a200341f0026a200341e00c6a108c04200341800d6a200328029805220f20032802a005108d04200341e00c6a41086a2001290300370300200341e00c6a41106a2002290300370300200341c0076a41086a200341a80d6a290300370300200341c0076a41106a200341b00d6a290300370300200341c0076a41186a200341b80d6a290300370300200341c0076a41206a2201200341c00d6a290300370300200320032903800d3703e00c2003200341800d6a41206a2903003703c007200328029c0d210a024020032802980d2205450d00200341b00c6a41106a200341e00c6a41106a290300370300200341b00c6a41086a200341e00c6a41086a290300370300200341e8096a41086a200341c0076a41086a290300370300200341e8096a41106a200341c0076a41106a290300370300200341e8096a41186a200341c0076a41186a290300370300200341e8096a41206a2001290300370300200320032903e00c3703b00c200320032903c0073703e8090b0240200328029c05450d00200f10290b0240024020050d0041032105411d2113200741014b0d01418bd6c200210f41112102410221010c0e0b200341b4056a200a36020020034198056a41206a20032903e80937030020034198056a41106a200341b00c6a41106a29030037030020034198056a41086a200341b00c6a41086a290300370300200341c0056a200341e8096a41086a290300370300200341c8056a200341e8096a41106a290300370300200341d0056a200341e8096a41186a290300370300200341d8056a200341e8096a41206a290300370300200320032903b00c37039805200320053602b0050240202f4101460d00410b210241add5c200210f410921010c0d0b410e2102419fd5c200210f410a210120032802a805202e470d0c200341ac056a280200202d470d0c024020032802b805220d2007490d0041112102418bd6c200210f410221010c0d0b410021010240200d41014b0d000240200d0e02000a000b200341800d6a41186a200341c8006a41186a290300370300200341800d6a41106a200341c8006a41106a290300370300200341800d6a41086a200341c8006a41086a290300370300200320032903483703800d4100210f200341800d6a21020c0a0b200d210203402002410176220f20016a22132001200520134105746a200341c8006a412010e7074101481b21012002200f6b220241014b0d000c090b0b0240202f4101470d00418cd5c200210f41132102410b21010c0d0b200341386a2007ad42004280cab5ee01420010d50720032003290338221b4280bcc1960b7c221a3703c0072003200341386a41086a290300201a201b54ad7c221b3703c8072003200341c8006a3602900c2003200341c8006a3602e00c2003200341e00c6a3602880d2003200341900c6a3602840d2003200341c0076a3602800d20034198056a200341c8006a200341800d6a108e04024002402003280298054101470d00200341a4056a280200210220034198056a41086a280200210f20032d009f05210a20032d009e05210120032d009d05211320032d009c0521050c010b41042105024020034198056a41086a2903004201520d0020034198056a41106a290300213120032802e00c2101200341b80d6a20034198056a41186a290300370300200341b00d6a2031370300200341800d6a41086a41003a0000200341890d6a2001290000370000200341910d6a200141086a290000370000200341990d6a200141106a290000370000200341a10d6a200141186a290000370000200341033a00800d200341800d6a10cb010b0b200541ff01714104470d0d200341c80f6a41106a220241003b0100200341c80f6a41086a22054200370300200342003703c80f41b3e6ca00ad4280808080e00084100122012f0000210a200320012f000e3b01c80f20012900022131200128000a210f2001102941c9e6ca00ad4280808080e00084100122012900002132200341800d6a41086a2213200141086a290000370300200320323703800d20011029200341d20f6a2013290300370100200320032903800d3701ca0f200341ae056a2005290300370100200341b6056a20022f01003b01002003200f3601a2052003203137019a052003200a3b019805200320032903c80f3701a605200341306a20034198056a412010fc012003280234210220032802302105200341286a41a6e5ca00411010fc01200328022c210a2003280228210f20032f0148211320032d004a210720032d004b210d20032f014c210820032d004e210920032d004f210620032f0150211020032d0052211120032d0053210c20032f0154210b20032d0056211220032d0057211520032f0158211620032d005a211720032d005b211820032f015c211920032d005e212f20032d005f212e20032903602131412010272201450d1420012003290348370000200141186a200341c8006a41186a290300370000200141106a200341c8006a41106a290300370000200141086a200341c8006a41086a290300370000200341940d6a200a4100200f1b360200200341bc0d6a2031370200200341bb0d6a202e3a0000200341ba0d6a202f3a0000200341b80d6a20193b0100200341b70d6a20183a0000200341b60d6a20173a0000200341b40d6a20163b0100200341b30d6a20153a0000200341b20d6a20123a0000200341b00d6a200b3b0100200341af0d6a200c3a0000200341ae0d6a20113a0000200341ac0d6a20103b0100200341ab0d6a20063a0000200341aa0d6a20093a0000200341a80d6a20083b0100200341a70d6a200d3a0000200341a60d6a20073a00002003201b3703880d2003201a3703800d20032002410020051b3602900d200320133b01a40d2003419c0d6a428180808010370200200320013602980d200320143703f80c2003201f3a00f70c2003201e3a00f60c2003201d3b01f40c2003201c3a00f30c200320203a00f20c200320213b01f00c200320223a00ef0c200320233a00ee0c200320243b01ec0c200320253a00eb0c200320263a00ea0c200320273b01e80c200320283a00e70c200320293a00e60c2003202a3b01e40c2003202b3a00e30c2003202c3a00e20c200320303b01e00c20034198056a200341f0026a200341e00c6a108c042003280298052101200320032802a0053602c407200320013602c007200341800d6a200341c0076a10f3030240200328029c05450d00200110290b0240200328029c0d41ffffff3f71450d0020032802980d10290b200341a50d6a20032903f0023700002003418d0d6a200341c8006a41086a290300370000200341950d6a200341c8006a41106a2903003700002003419d0d6a200341c8006a41186a290300370000200341ad0d6a200341f0026a41086a290300370000200341b50d6a200341f0026a41106a290300370000200341bd0d6a200341f0026a41186a290300370000200341023a00840d200341133a00800d200320032903483700850d200341dd0d6a2014370000200341dc0d6a201f3a0000200341db0d6a201e3a0000200341d90d6a201d3b0000200341d80d6a201c3a0000200341d70d6a20203a0000200341d50d6a20213b0000200341d40d6a20223a0000200341d30d6a20233a0000200341d10d6a20243b0000200341d00d6a20253a0000200341cf0d6a20263a0000200341cd0d6a20273b0000200341cc0d6a20283a0000200341cb0d6a20293a0000200341c90d6a202a3b0000200341c80d6a202b3a0000200341c70d6a202c3a0000200341c50d6a20303b0000200341800d6a10cb010c090b42002114200328029c05220541ff01714104460d102005411876210a2005411076210120054108762113200341a4056a280200210220034198056a41086a280200210f0c0f0b2001412c6a280200210a200141286a2802002105200141246a2802002113200141346a2802002107200141306a2802002104200141226a2f0100210f200341b00c6a41186a200141196a290000370300200341b00c6a41106a200141116a290000370300200341b00c6a41086a200141096a290000370300200320012900013703b00c4102210120022d00000d0120022d00014101470d01200241196a2d00002101200241186a2d0000210e200241166a2f0100210d200241156a2d00002108200241146a2d00002109200241126a2f01002106200241116a2d00002110200241106a2d000021112002410e6a2f0100210c2002410d6a2d0000210b2002410c6a2d000021122002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d00002119200241046a2d0000211f200241026a2f0100211e20032002411a6a290100370360200320013a005f2003200e3a005e2003200d3b015c200320083a005b200320093a005a200320063b0158200320103a0057200320113a00562003200c3b01542003200b3a0053200320123a0052200320153b0150200320163a004f200320173a004e200320183b014c200320193a004b2003201f3a004a2003201e3b01480240200f41ffff03710d0041abd6c200210f410d210a41032101410021020c030b410321010240200a0d0041fad5c200210f4111210a410321020c030b0240200a41e3004d0d0041e8d5c200210f4112210a410421020c030b2003200a3602f009200320053602ec09200320133602e809200341800d6a41186a200341c8006a41186a290300370300200341800d6a41106a2202200341c8006a41106a290300370300200341800d6a41086a2201200341c8006a41086a290300370300200320032903483703800d20034198056a200341e8096a200341800d6a108a0402402003280298054101460d0020034198056a41086a2205280200210e200328029c052113200120034198056a410c6a2802003602002003200f3b018c0d200320133602840d200341a0dcc3003602800d200341e00c6a200341800d6a108b04200341083a00a00d2003410b3a00a00d2003410c3a00a00d200320032f01e00c3b01800d200320032801e20c3601820d200320032d00e60c3a00860d200320032800e70c3600870d200320032d00eb0c3a008b0d2003410d3a00a00d200320032d00ec0c3a008c0d2003410e3a00a00d200320032d00ed0c3a008d0d2003410f3a00a00d200320032d00ee0c3a008e0d200320032d00ef0c3a008f0d200341103a00a00d200341113a00a00d200320032d00f00c3a00900d200341123a00a00d200320032d00f10c3a00910d200341133a00a00d200320032d00f20c3a00920d200341143a00a00d200320032d00f30c3a00930d200341153a00a00d200320032d00f40c3a00940d200341163a00a00d200320032d00f50c3a00950d200341173a00a00d200320032d00f60c3a00960d200320032d00f70c3a00970d200341183a00a00d200341193a00a00d200320032d00f80c3a00980d2003411a3a00a00d200320032d00f90c3a00990d2003411b3a00a00d200320032d00fa0c3a009a0d2003411c3a00a00d200320032d00fb0c3a009b0d2003411d3a00a00d200320032d00fc0c3a009c0d2003411e3a00a00d200320032d00fd0c3a009d0d2003411f3a00a00d200320032d00fe0c3a009e0d200320032d00ff0c3a009f0d200341203a00a00d20034198056a41186a220a20032903980d37030020034198056a41106a220f20032903900d370300200520032903880d370300200320032903800d37039805200341f0026a41186a200a290300370300200341f0026a41106a200f290300370300200341f0026a41086a200529030037030020032003290398053703f0022003200341b00c6a41186a2903003703f80c2003200341b00c6a41106a2903003703f00c2003200341b00c6a41086a2903003703e80c200320032903b00c3703e00c200341e00f6a200341f0026a200341e00c6a108c04200341800d6a20032802e00f220a20032802e80f108d04200341e00c6a41086a2001290300370300200341e00c6a41106a2002290300370300200341c0076a41086a200341a80d6a290300370300200341c0076a41106a200341b00d6a290300370300200341c0076a41186a200341b80d6a290300370300200341c0076a41206a2202200341c00d6a290300370300200320032903800d3703e00c2003200341800d6a41206a2903003703c00702400240024020032802980d2201450d00200328029c0d2105200341c80f6a41106a220f200341e00c6a41106a290300370300200341c80f6a41086a220d200341e00c6a41086a290300370300200341e8096a41086a2208200341c0076a41086a290300370300200341e8096a41106a2209200341c0076a41106a290300370300200341e8096a41186a2206200341c0076a41186a290300370300200341e8096a41206a2002290300370300200320032903e00c3703c80f200320032903c0073703e809024020032802e40f450d00200a10290b200341900c6a41166a200f2903002214370100410e210a200341900c6a410e6a200d290300370100200341a80f6a41166a22022014370100200341a80f6a41106a200341900c6a41106a290100370300200320032903c80f3701960c200341a80f6a41086a200341900c6a41086a290100370300200320032901900c3703a80f20034198056a41106a220d200229010037030020034198056a41086a200341a80f6a410e6a290100370300200320032901ae0f37039805200341b4056a2005360200200320013602b005200341d8056a200341e8096a41206a290300370300200341d0056a2006290300370300200341c8056a2009290300370300200341c0056a200829030037030020034198056a41206a20032903e809370300419fd5c200210f410a21020240200d2802002004470d00200341ac056a2802002007470d00200341bc056a2202200341c8006a412010e707450d03410821024180f8c400210f4108210a0b200541ffffff3f71450d01200110290c010b024020032802e40f450d00200a10290b41b8d5c200210f4108210a410721020b0240200e41ffffff3f71450d00201310290b4100210541803a2113410321010c050b2003290398052114200320034198056a41086a290300221a3703c807200320143703c00702402014201a84500d00200320023602e00c200341e8096a2002200341c0076a200341e00c6a10ea0320032903e8094201520d0020032903f0092114200341b80d6a200341e8096a41106a290300370300200341b00d6a2014370300200341800d6a41086a41003a0000200341890d6a2002290000370000200341910d6a200241086a290000370000200341990d6a200241106a290000370000200341a10d6a200241186a290000370000200341033a00800d200341800d6a10cb010b200341e00c6a41186a200341b00c6a41186a2201290300370300200341e00c6a41106a200341b00c6a41106a2202290300370300200341e00c6a41086a200341b00c6a41086a290300370300200320032903b00c3703e00c200341800d6a200341f0026a200341e00c6a108c0420033502880d42208620032802800d2205ad841004024020032802840d450d00200510290b200341a50d6a20032903f0023700002003418d0d6a200341c8006a41086a290300370000200341950d6a200341c8006a41106a2903003700002003419d0d6a200341c8006a41186a290300370000200341ad0d6a200341f0026a41086a290300370000200341b50d6a200341f0026a41106a290300370000200341bd0d6a200341f0026a41186a290300370000200341053a00840d200341133a00800d200320032903483700850d200341e80d6a2004360200200341ec0d6a2007360200200341dd0d6a2001290300370000200341d50d6a2002290300370000200341cd0d6a200341b00c6a41086a290300370000200341c50d6a20032903b00c370000200341800d6a10cb01024020032802b40541ffffff3f71450d0020032802b00510290b0240200e41ffffff3f71450d00201310290b420021140c050b42002114200328029c05220141ff01714104460d042001418080807871210520014110762102200141807e712113200341a4056a280200210a20034198056a41086a280200210f0c030b1039000b0b0240200541ffffff3f71450d00201310290b4100210541803a21130b200041206a200a3602002000411c6a200f360200200041186a2005200241ff01714110747220134180fe037172200141ff017172360200420121140b200042003703080c250b0240200520014105746a200341c8006a412010e707220f0d00410f2102419cd6c200210f410121010c040b200341800d6a41186a200341c8006a41186a290300370300200341800d6a41106a200341c8006a41106a290300370300200341800d6a41086a200341c8006a41086a290300370300200320032903483703800d200341800d6a2102200d200f411f7620016a220f490d020b0240200d200a470d0020034198056a41186a200a4101109e0120032802b00521050b2005200f4105746a220141206a2001200d200f6b41057410e5071a200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a290000370000200120022900003700002003200d41016a3602b805200341800d6a20034198056a41c80010e4071a200320143703f80c2003201f3a00f70c2003201e3a00f60c2003201d3b01f40c2003201c3a00f30c200320203a00f20c200320213b01f00c200320223a00ef0c200320233a00ee0c200320243b01ec0c200320253a00eb0c200320263a00ea0c200320273b01e80c200320283a00e70c200320293a00e60c2003202a3b01e40c2003202b3a00e30c2003202c3a00e20c200320303b01e00c200341c0076a200341f0026a200341e00c6a108c0420032802c0072101200320032802c8073602e40c200320013602e00c200341800d6a200341e00c6a10f303024020032802c407450d00200110290b02402003419c0d6a28020041ffffff3f71450d0020032802980d10290b200341a50d6a20032903f0023700002003418d0d6a200341c8006a41086a290300370000200341950d6a200341c8006a41106a2903003700002003419d0d6a200341c8006a41186a290300370000200341ad0d6a200341f0026a41086a290300370000200341b50d6a200341f0026a41106a290300370000200341bd0d6a200341f0026a41186a290300370000200341033a00840d200341133a00800d200320032903483700850d200341ec0d6a202d360200200341e80d6a202e360200200341dd0d6a2014370000200341dc0d6a201f3a0000200341db0d6a201e3a0000200341d90d6a201d3b0000200341d80d6a201c3a0000200341d70d6a20203a0000200341d50d6a20213b0000200341d40d6a20223a0000200341d30d6a20233a0000200341d10d6a20243b0000200341d00d6a20253a0000200341cf0d6a20263a0000200341cd0d6a20273b0000200341cc0d6a20283a0000200341cb0d6a20293a0000200341c90d6a202a3b0000200341c80d6a202b3a0000200341c70d6a202c3a0000200341c50d6a20303b0000200341800d6a10cb010b0240200e41ffffff3f71450d00200410290b420021140c070b200f200d1041000b0240200a41ffffff3f71450d00200510290b41032105411d21130b0b200e41ffffff3f71450d02200410290c020b0b411d21130240200a41ffffff3f710d000c010b200410290b200041206a20023602002000411c6a200f360200200041186a200a411874200141ff017141107472201341ff017141087472200541ff017172360200420121140b200042003703080c1a0b024002400240024002400240201f41ffff0371450d002019450d01201941e4004f0d02200320193602f0092003200f3602ec09200320073602e809200341800d6a41186a200341900c6a41186a290300370300200341800d6a41106a200341900c6a41106a290300370300200341800d6a41086a2201200341900c6a41086a290300370300200320032903900c3703800d20034198056a200341e8096a200341800d6a108a042003280298054101460d0320034198056a41086a22022802002127200328029c052108200120034198056a410c6a2802003602002003201f3b018c0d200320083602840d200341a0dcc3003602800d200341e00c6a200341800d6a108b04200341083a00a00d2003410b3a00a00d2003410c3a00a00d200320032f01e00c3b01800d200320032801e20c3601820d200320032d00e60c3a00860d200320032800e70c3600870d200320032d00eb0c3a008b0d2003410d3a00a00d200320032d00ec0c3a008c0d2003410e3a00a00d200320032d00ed0c3a008d0d2003410f3a00a00d200320032d00ee0c3a008e0d200320032d00ef0c3a008f0d200341103a00a00d200341113a00a00d200320032d00f00c3a00900d200341123a00a00d200320032d00f10c3a00910d200341133a00a00d200320032d00f20c3a00920d200341143a00a00d200320032d00f30c3a00930d200341153a00a00d200320032d00f40c3a00940d200341163a00a00d200320032d00f50c3a00950d200341173a00a00d200320032d00f60c3a00960d200320032d00f70c3a00970d200341183a00a00d200341193a00a00d200320032d00f80c3a00980d2003411a3a00a00d200320032d00f90c3a00990d2003411b3a00a00d200320032d00fa0c3a009a0d2003411c3a00a00d200320032d00fb0c3a009b0d2003411d3a00a00d200320032d00fc0c3a009c0d2003411e3a00a00d200320032d00fd0c3a009d0d2003411f3a00a00d200320032d00fe0c3a009e0d200341203a00a00d200320032d00ff0c3a009f0d20034198056a41186a220120032903980d37030020034198056a41106a220a20032903900d370300200220032903880d370300200320032903800d37039805200341b00c6a41186a2001290300370300200341b00c6a41106a200a290300370300200341b00c6a41086a200229030037030020032003290398053703b00c200341003602880d200342013703800d2005200341800d6a10bf0220032802840d210220033502880d42208620032802800d220aad8410102201290018211420012d0017210720012d0016210920012f0014210620012d0013211020012d0012211120012f0010210c20012d000f210b20012d000e211220012f000c211520012d000b211620012d000a211720012f0008211820012d0007212020012d0006212120012f0004212220012d0003212320012d0002212420012f000021252001102902402002450d00200a10290b200320143703f80c200320073a00f70c200320093a00f60c200320063b01f40c200320103a00f30c200320113a00f20c2003200c3b01f00c2003200b3a00ef0c200320123a00ee0c200320153b01ec0c200320163a00eb0c200320173a00ea0c200320183b01e80c200320203a00e70c200320213a00e60c200320223b01e40c200320233a00e30c200320243a00e20c200320253b01e00c20034198056a200341b00c6a200341e00c6a108c04200341800d6a200328029805220120032802a005108d04200341e00c6a41086a2202200341800d6a41086a290300370300200341e00c6a41106a220a200341800d6a41106a290300370300200341c0076a41086a220f200341a80d6a290300370300200341c0076a41106a2213200341b00d6a290300370300200341c0076a41186a2204200341b80d6a290300370300200341c0076a41206a200341c00d6a290300370300200320032903800d3703e00c2003200341800d6a41206a2903003703c007200328029c0d210d024020032802980d220e450d00200341a80f6a41106a200a290300370300200341a80f6a41086a2002290300370300200341f0026a41086a200f290300370300200341f0026a41106a2013290300370300200341f0026a41186a2004290300370300200341f0026a41206a200341c0076a41206a290300370300200320032903e00c3703a80f200320032903c0073703f0020b0240200328029c05450d00200110290b200e0d04410121264100211d4201211b201e4101470d054200211441132101418cd5c2002102410b2113411d21044103210a0c100b410d210141abd6c2002102410021134103210a0c050b4111210141fad5c20021024103210a410321130c040b4112210141e8d5c2002102410421134103210a0c030b200341a4056a280200210120034198056a41086a280200210220032d009f05210f20032d009e05211320032d009d05210420032d009c05210a200510cc0120051029420021140c050b200341b4056a200d36020020034198056a41206a20032903f00237030020034198056a41106a200341a80f6a41106a29030037030020034198056a41086a200341a80f6a41086a290300370300200341c0056a200341f0026a41086a290300370300200341c8056a200341f0026a41106a290300370300200341d0056a200341f0026a41186a290300370300200341d8056a200341f0026a41206a290300370300200320032903a80f370398052003200e3602b005410121264201211b0240201e4101460d00410b210141add5c200210241092113200d210a0c080b410e2101419fd5c2002102410a2113024020032802a805201d460d00200d210a0c080b0240200341ac056a280200201c460d00200d210a0c080b41002101024002400240024020032802b805221341014b0d0020130e020201020b2013210203402002410176220a20016a220f2001200e200f4105746a200341900c6a412010e7074101481b21012002200a6b220241014b0d000b0b200e20014105746a200341900c6a412010e7072202450d012002411f7620016a21010b201f417f6a41ffff0371201341ffff03714b0d090c070b201f41ffff0371201341ffff03714d0d0641012113410f2101419cd6c2002102200d210a410121260c070b024002400240201f41ffff037141014b0d00200341800d6a200541a80210e4071a200341a2056a200341b80c6a290300370100200341aa056a200341b00c6a41106a290300370100200341b2056a200341b00c6a41186a29030037010020034180023b019805200320032903b00c37019a05200341e8096a200341800d6a20034198056a10c50120032903f009211420032903e8094201520d01200341880a6a2802002101200341840a6a2802002102200341e8096a41186a2d0000210a200341e8096a41106a290300211a20032d00830a210f20032d00820a211320032d00810a21042014a70d022003418c0a6a28020021074201211b0c070b200341186a201fad42ffff038342004280cab5ee01420010d5072003200329031822314280bcc1960b7c221a3703e8092003200341186a41086a290300201a203154ad7c22313703f0092003200341900c6a3602482003200341900c6a3602c0072003200341c0076a3602880d2003200341c8006a3602840d2003200341e8096a3602800d20034198056a200341900c6a200341800d6a108e04024002402003280298054101470d00200341a4056a280200210120034198056a41086a280200210220032d009f05210f20032d009e05211320032d009d05210420032d009c05210a0c010b4104210a024020034198056a41086a2903004201520d0020034198056a41106a290300213220032802c0072101200341b80d6a20034198056a41186a290300370300200341b00d6a2032370300200341800d6a41086a41003a0000200341890d6a2001290000370000200341910d6a200141086a290000370000200341990d6a200141106a290000370000200341a10d6a200141186a290000370000200341033a00800d200341800d6a10cb010b0b410121260240200a41ff01714104460d00420021140c0d0b200341c80f6a41106a220241003b0100200341c80f6a41086a220a4200370300200342003703c80f41b3e6ca00ad4280808080e00084100122012f0000210f200320012f000e3b01c80f2001290002211b200128000a21132001102941c9e6ca00ad4280808080e00084100122012900002132200341800d6a41086a2204200141086a290000370300200320323703800d20011029200341d20f6a2004290300370100200320032903800d3701ca0f200341ae056a200a290300370100200341b6056a20022f01003b0100200320133601a2052003201b37019a052003200f3b019805200320032903c80f3701a605200341106a20034198056a412010fc01200328021421022003280210210a200341086a41a6e5ca00411010fc01200328020c210f2003280208211320032f01900c210420032d00920c211f20032d00930c211e20032f01940c211d20032d00960c211c20032d00970c212820032f01980c212920032d009a0c212a20032d009b0c212b20032f019c0c212c20032d009e0c213020032d009f0c212f20032f01a00c212e20032d00a20c212d20032d00a30c213320032f01a40c213420032d00a60c213520032d00a70c213620032903a80c211b412010272201450d03200120032903900c370000200141186a200341900c6a41186a290300370000200141106a200341900c6a41106a290300370000200141086a200341900c6a41086a290300370000200341940d6a200f410020131b360200200341bc0d6a201b370200200341bb0d6a20363a0000200341ba0d6a20353a0000200341b80d6a20343b0100200341b70d6a20333a0000200341b60d6a202d3a0000200341b40d6a202e3b0100200341b30d6a202f3a0000200341b20d6a20303a0000200341b00d6a202c3b0100200341af0d6a202b3a0000200341ae0d6a202a3a0000200341ac0d6a20293b0100200341ab0d6a20283a0000200341aa0d6a201c3a0000200341a80d6a201d3b0100200341a70d6a201e3a0000200341a60d6a201f3a0000200320313703880d2003201a3703800d200320024100200a1b3602900d200320043b01a40d2003419c0d6a428180808010370200200320013602980d200320143703f80c200320073a00f70c200320093a00f60c200320063b01f40c200320103a00f30c200320113a00f20c2003200c3b01f00c2003200b3a00ef0c200320123a00ee0c200320153b01ec0c200320163a00eb0c200320173a00ea0c200320183b01e80c200320203a00e70c200320213a00e60c200320223b01e40c200320233a00e30c200320243a00e20c200320253b01e00c20034198056a200341b00c6a200341e00c6a108c042003280298052101200320032802a0053602ec09200320013602e809200341800d6a200341e8096a10f3030240200328029c05450d00200110290b0240200328029c0d41ffffff3f71450d0020032802980d10290b200341a50d6a20032903b00c3700002003418d0d6a200341900c6a41086a290300370000200341950d6a200341900c6a41106a2903003700002003419d0d6a200341900c6a41186a290300370000200341ad0d6a200341b00c6a41086a290300370000200341b50d6a200341b00c6a41106a290300370000200341bd0d6a200341b00c6a41186a290300370000200341023a00840d200341133a00800d200320032903900c3700850d200341dd0d6a2014370000200341dc0d6a20073a0000200341db0d6a20093a0000200341d90d6a20063b0000200341d80d6a20103a0000200341d70d6a20113a0000200341d50d6a200c3b0000200341d40d6a200b3a0000200341d30d6a20123a0000200341d10d6a20153b0000200341d00d6a20163a0000200341cf0d6a20173a0000200341cd0d6a20183b0000200341cc0d6a20203a0000200341cb0d6a20213a0000200341c90d6a20223b0000200341c80d6a20233a0000200341c70d6a20243a0000200341c50d6a20253b00002019ad4290a10f7e4280fd87d1007c211a200341800d6a10cb014100211d4200211b420121140c0b0b4200211b024020144201510d00420021140c060b427f427f427f200341f8096a290300221442c0caba157c221a201a2014541b22142019ad4290a10f7e7c221a201a2014541b221442c0b2cd3b7c221a201a2014541b211a420121140c050b427f427f427f201a42c0caba157c22142014201a541b22142019ad4290a10f7e7c221a201a2014541b221442c0b2cd3b7c221a201a2014541b211a420121144201211b0c040b200510cc012005102942002114411d2104200f41ffffff3f71450d01200710290c010b1030000b0b0c090b410021264100211d0c050b200341800d6a200541a80210e4071a200341f2096a200341b00c6a41086a290300370100200341fa096a200341c00c6a290300370100200341820a6a200341c80c6a29030037010020034180023b01e809200320032903b00c3701ea09200341c0076a200341800d6a200341e8096a10c501200329039805211a200320034198056a41086a290300221b3703502003201a3703480240201a201b84500d002003200341bc056a22013602e00c200341e8096a2001200341c8006a200341e00c6a10ea0320032903e8094201520d0020032903f009211a200341b80d6a200341e8096a41106a290300370300200341b00d6a201a370300200341800d6a41086a41003a0000200341890d6a2001290000370000200341910d6a200141086a290000370000200341990d6a200141106a290000370000200341a10d6a200141186a290000370000200341033a00800d200341800d6a10cb010b200320143703f80c200320073a00f70c200320093a00f60c200320063b01f40c200320103a00f30c200320113a00f20c2003200c3b01f00c2003200b3a00ef0c200320123a00ee0c200320153b01ec0c200320163a00eb0c200320173a00ea0c200320183b01e80c200320203a00e70c200320213a00e60c200320223b01e40c200320233a00e30c200320243a00e20c200320253b01e00c200341800d6a200341b00c6a200341e00c6a108c0420033502880d42208620032802800d2201ad841004024020032802840d450d00200110290b200341e8096a41186a200341900c6a41186a290300370300200341e8096a41106a200341900c6a41106a290300370300200341e8096a41086a200341900c6a41086a290300370300200320032903900c3703e809200341800d6a41186a200341b00c6a41186a290300370300200341800d6a41106a200341b00c6a41106a290300370300200341800d6a41086a200341b00c6a41086a290300370300200320032903b00c3703800d200341c0076a41186a2d0000210220032903c807211b20032903c007211a200320032900d9073703482003200341e0076a28000036004f02400240201a4201510d00410421010c010b2003200328004f3600cf0f200320032903483703c80f41042101201b4202510d00200320032800cf0f3600e70f200320032903c80f3703e00f200221010b200341c8006a41086a2202200341e8096a41086a290300370300200341c8006a41106a220a200341e8096a41106a290300370300200341c8006a41186a220f200341e8096a41186a290300370300200341e00c6a41086a2213200341800d6a41086a290300370300200341e00c6a41106a2204200341800d6a41106a290300370300200341e00c6a41186a2219200341800d6a41186a290300370300200320032903e809370348200320032903800d3703e00c200320032800e70f3600d70c200320032903e00f3703d00c2003418d0d6a2002290300370000200341950d6a200a2903003700002003419d0d6a200f290300370000200341a50d6a20032903e00c370000200341ad0d6a2013290300370000200341b50d6a2004290300370000200341bd0d6a2019290300370000200341043a00840d200341133a00800d200320032903483700850d200341dd0d6a2014370000200341dc0d6a20073a0000200341db0d6a20093a0000200341d90d6a20063b0000200341d80d6a20103a0000200341d70d6a20113a0000200341d50d6a200c3b0000200341d40d6a200b3a0000200341d30d6a20123a0000200341d10d6a20153b0000200341d00d6a20163a0000200341cf0d6a20173a0000200341cd0d6a20183b0000200341cc0d6a20203a0000200341cb0d6a20213a0000200341c90d6a20223b0000200341c80d6a20233a0000200341c70d6a20243a0000200341c50d6a20253b0000200341f00d6a20013a0000200341ec0d6a201c360200200341e80d6a201d360200200341e70d6a200341ea096a2d00003a0000200341e50d6a20032f00e8093b0000200341f80d6a20032800d70c360000200341f10d6a20032903d00c370000200341800d6a10cb01410021264200211b20032802b405210a0b420021140240200a41ffffff3f710d000c020b20032802b00510290c010b200341800d6a41186a200341900c6a41186a290300370300200341800d6a41106a200341900c6a41106a290300370300200341800d6a41086a200341900c6a41086a290300370300200320032903900c3703800d20132001490d03200e210202402013200d470d0020034198056a41186a200d4101109e0120032802b00521020b200220014105746a220241206a2002201320016b41057410e5071a200241186a200341800d6a41186a290300370000200241106a200341800d6a41106a290300370000200241086a200341800d6a41086a290300370000200220032903800d3700002003201341016a3602b805200341800d6a20034198056a41c80010e4071a200320143703f80c200320073a00f70c200320093a00f60c200320063b01f40c200320103a00f30c200320113a00f20c2003200c3b01f00c2003200b3a00ef0c200320123a00ee0c200320153b01ec0c200320163a00eb0c200320173a00ea0c200320183b01e80c200320203a00e70c200320213a00e60c200320223b01e40c200320233a00e30c200320243a00e20c200320253b01e00c200341e8096a200341b00c6a200341e00c6a108c0420032802e8092101200320032802f0093602c407200320013602c007200341800d6a200341c0076a10f303024020032802ec09450d00200110290b02402003419c0d6a28020041ffffff3f71450d0020032802980d10290b200341a50d6a20032903b00c3700002003418d0d6a200341900c6a41086a290300370000200341950d6a200341900c6a41106a2903003700002003419d0d6a200341900c6a41186a290300370000200341ad0d6a200341b00c6a41086a290300370000200341b50d6a200341b00c6a41106a290300370000200341bd0d6a200341b00c6a41186a290300370000200341033a00840d200341133a00800d200320032903900c3700850d200341ec0d6a201c360200200341e80d6a201d360200200341dd0d6a2014370000200341dc0d6a20073a0000200341db0d6a20093a0000200341d90d6a20063b0000200341d80d6a20103a0000200341d70d6a20113a0000200341d50d6a200c3b0000200341d40d6a200b3a0000200341d30d6a20123a0000200341d10d6a20153b0000200341d00d6a20163a0000200341cf0d6a20173a0000200341cd0d6a20183b0000200341cc0d6a20203a0000200341cb0d6a20213a0000200341c90d6a20223b0000200341c80d6a20233a0000200341c70d6a20243a0000200341c50d6a20253b00002019ad4290a10f7e4280fd87d1007c211a200341800d6a10cb01410121264200211b420121140b4101211d411d21044103210a0b0b0240202741ffffff3f71450d00200810290b200d41ffffff3f71450d01200e45201d720d01200e10290c010b200120131041000b02402026450d00200510cc010b20051029201b50450d0020002014370308200041106a201a370300420021140c0c0b2000200f3a001b200020133a001a200020043a001920002014370308200041246a2007360200200041206a20013602002000411c6a2002360200200041186a200a3a0000200041106a201a370300420121140c0b0b4104210a4100210141002102410021130b2005102942002114200a41ff01714104460d020c010b200510cc01200510294100210141808030210241803a21134182d5c20021040b200041206a200f3602002000411c6a2004360200200041186a20012002418080fc07717220134180fe037172200a41ff017172360200420121140b200042003703080c060b2007210102402005450d00200341e8096a41106a211320034198056a4104722110200441ff017121114100210a2007210103402001280200210520034198056a200141046a220f41a40210e4071a200341800d6a200f41a40210e4071a02400240024002402005411c460d00200341e8096a200341800d6a41a40210e4071a200341c0076a200341e8096a41a40210e4071a200341f0026a200341c0076a41a40210e4071a200341c8006a200341f0026a41a40210e4071a20032005360298052010200341c8006a41a40210e4071a024020050e1c04040404040304040404040404040303030303030203030304000404040b20032d00a0054103460d020c030b200141a8026a21010c050b200328029c054101460d010b200341880d6a200a360200200341063a00840d200341133a00800d200141a8026a2101200341800d6a10cb0120034198056a10cc010c060b200341800d6a20034198056a41a80210e4071a02400240024002400240200d0e0400010203000b41022105024002400240200c0e03000102000b410021050c010b200341c80f6a41106a200341e00c6a41106a2f01003b0100200341c80f6a41086a200341e00c6a41086a290300370300200320032903e00c3703c80f410121050b201320032903c80f370000201341086a200341c80f6a41086a290300370000201341106a200341c80f6a41106a2f01003b0000200320083602f409200320093602f009200320043602ec092003200b3b01ea09200320053a00e909200341003a00e8090c030b4102210502400240024020110e03000102000b410021050c010b200341f0026a410d6a200341e00c6a410d6a290000370000200341f0026a41086a200341e00c6a41086a290300370300200320032903e00c3703f002410121050b201320032903f002370200201341086a200341f0026a41086a290300370200201341106a200341f0026a41106a290300370200200320083602f409200320093602f009200320053a00ec09200341013a00e8092003200e3b00ed092003200e4110763a00ef090c020b4102210502400240024020110e03000102000b410021050c010b200341f0026a410d6a200341e00c6a410d6a290000370000200341f0026a41086a200341e00c6a41086a290300370300200320032903e00c3703f002410121050b201320032903f002370200201341086a200341f0026a41086a290300370200201341106a200341f0026a41106a290300370200200320083602f409200320093602f009200320053a00ec09200341023a00e8092003200e3b00ed092003200e4110763a00ef090c010b200341033a00e809200320043602ec090b200341c0076a200341800d6a200341e8096a10c50120032903c0074201510d03200a41016a210a200141a8026a22012002470d000b200221010b200341800d6a20034198056a41a40210e4071a0b024020022001460d000340200110c2012002200141a8026a2201470d000b0b02402006450d00200641a8026c450d00200710290b200341013a00840d200341133a00800d200341800d6a10cb010c030b200141a8026a21010b200341e8096a41186a200341e0076a2903002214370300200341e8096a41106a200341c0076a41186a290300221a370300200341e8096a41086a200341c0076a41106a290300370300200320032903c8073703e809200341800d6a41086a200a3602002003418c0d6a201a370200200341940d6a20143e0200200341003a00840d200341133a00800d200341800d6a10cb010b024020022001460d000340200110c2012002200141a8026a2201470d000b0b2006450d00200641a8026c450d00200710290b42002114200042003703080b20002014370300200341f00f6a24000b8f0403027f017e077f230041306b22032400200341086a200141086a28020022043602002003200129020022053703002005a72106024002400240024020040d00410021070c010b200441057421084100210941002107200621010240034002402009450d0020092001412010e7074100480d004115210a41d3d5c200210b4105210c0c020b024020012002412010e707220941004a0d004113210a41c0d5c200210b4106210c20022001460d022009450d02200741016a21070b20012109200141206a2101200841606a2208450d020c000b0b2000200c3a0006200041833a3b0104200041013602002000410c6a200a360200200041086a200b360200200328020441ffffff3f71450d01200610290c010b200341106a41186a200241186a290000370300200341106a41106a200241106a290000370300200341106a41086a200241086a2900003703002003200229000037031020042007490d01024020042003280204470d00200320044101109e01200328020021060b200620074105746a220141206a2001200420076b41057410e5071a200141186a200341106a41186a290300370000200141106a200341106a41106a290300370000200141086a200341106a41086a290300370000200120032903103700002003200441016a22013602082000410c6a200136020020002003290300370204200041003602000b200341306a24000f0b200720041041000bba0502087f037e230041106b2202240002400240200141086a28020022034105744116722204417f4c0d000240200410272205450d00200520012802002206290000370000200541086a200641086a290000370000200241103602082002200436020420022005360200200141046a280200210720032002107102400240024020030d0020022802042106200228020821040c010b20034105742108200228020021092002280204210620022802082104034020072105024002402006200422036b4120490d00200341206a21040c010b200341206a22042003490d03200641017422072004200720044b1b22074100480d03024002400240024020060d00024020070d00410121090c020b2007102721090c030b20062007470d010b200721060c020b200920062007102b21090b200721062009450d060b200541206a2107200920036a22032005290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a290000370000200841606a22080d000b2002200636020420022004360208200220093602000b20012f010c210802400240200620046b4102490d00200441026a210520022802002103200621070c010b200441026a22052004490d01200641017422032005200320054b1b22074100480d010240024020060d00024020070d00410121030c020b200710272203450d060c010b2002280200210320062007460d00200320062007102b2203450d050b20022007360204200220033602000b200320046a20083b00002005ad4220862003ad8410102205290000210a200541086a290000210b200541106a290000210c200041186a200541186a290000370000200041106a200c370000200041086a200b3700002000200a3700002005102902402007450d00200310290b200241106a24000f0b1032000b1039000b1038000b1030000bf30703027f017e067f230041e0006b2203240041ddbfc500ad4280808080f00084100122042900002105200341086a200441086a2900003703002003200537030020041029418cb8c300ad4280808080900184100122042900002105200341106a41086a200441086a29000037030020032005370310200410290240024002400240412010272204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020032004ad42808080808004841002220129000037034020011029200341dc006a2206200441206a360200200320043602582003200341c0006a41086a3602542003200341c0006a360250200341206a200341d0006a107520041029412010272204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a2900003700002004ad4280808080800484100522012900002105200341c0006a41086a200141086a29000037030020032005370340200110292006200441206a360200200320043602582003200341c0006a41106a3602542003200341c0006a360250200341306a200341d0006a1075200410292003280228220741206a2206200328023822086a2201417f4c0d01200328023021092003280220210a0240024020010d004100210b410121040c010b200110272204450d012001210b0b02400240200b410f4d0d00200b21020c010b200b41017422024110200241104b1b22024100480d030240200b0d002002102722040d010c050b200b2002460d002004200b2002102b2204450d040b20042003290300370000200441086a200341086a2903003700000240024020024170714110460d002002210b0c010b2002410174220b4120200b41204b1b220b4100480d032002200b460d0020042002200b102b2204450d040b20042003290310370010200441186a200341106a41086a29030037000002400240200b41606a2007490d00200b21020c010b2007415f4b0d03200b41017422022006200220064b1b22024100480d03200b2002460d002004200b2002102b2204450d040b200441206a200a200710e4071a02400240200220066b2008490d002002210b0c010b20012006490d032002410174220b2001200b20014b1b220b4100480d03024020020d000240200b0d00410121040c020b200b10272204450d050c010b2002200b460d0020042002200b102b2204450d040b200420066a2009200810e4071a200020013602082000200b3602042000200436020002402003280234450d00200910290b02402003280224450d00200a10290b200341e0006a24000f0b1039000b1038000b1032000b1030000b850604067f027e027f057e23004190016b220324002003200236020420032001360200200341086a2002ad4220862001ad841007108b0202400240200328020822020d00200041003602180c010b200328020c21042003200341106a280200220136023c200320023602380240024020014104490d002003200241046a36023820032001417c6a220536023c20054104490d00200228000021062003200241086a3602382003200141786a220536023c20054110490d00200228000421072003200141686a220836023c2003200241186a360238200241106a29000021092002290008210a41002101200341003a0088010240034020082001460d01200341e8006a20016a200220016a220541186a2d00003a00002003200541196a3602382003200141016a22053a0088012005210120054120470d000b200341c8006a41086a2201200341e8006a41086a290300370300200341c8006a41106a220b200341e8006a41106a290300370300200341c8006a41186a220c200341e8006a41186a290300370300200320032903683703482003200820056b36023c200341e8006a200341386a10960220032802682205450d01200341186a41086a2001290300220d370300200341186a41106a200b290300220e370300200341186a41186a200c290300220f370300200320032903482210370318200329026c2111200020093703082000200a3703002000201137021c200020053602182000200736021420002006360210200041246a20103702002000412c6a200d370200200041346a200e3702002000413c6a200f3702000c020b2003410036023c200141ff0171450d00200341003a0088010b20034100360250200342013703482003410d36021c200320033602182003200341c8006a360244200341fc006a41013602002003420137026c200341f4eaca003602682003200341186a360278200341c4006a41a8a3c800200341e8006a10371a200335025042208620033502488410080240200328024c450d00200328024810290b200041003602180b2004450d00200210290b20034190016a24000bdb1005067f027e037f0b7e027f230041b0036b22032400200228020821042002280204210520022802002106200341086a200110a802200341b0016a200328020822072003280210220810a90220032903b00121094200210a200342003703b001200341f8016a280200210b20032d00fc01210c024002402009420151220d0d00200341186a41306a4200370300200341186a41286a4200370300200341186a41206a4200370300200341186a41186a4200370300200341286a4200370300200341206a4200370300200342003703184200210e4200210f42002110420021110c010b200341e8016a2903002112200341b0016a41306a2903002113200341b0016a41206a2903002110200341b0016a41186a290300210f200341f0016a290300211120032903c001210e20032903b801210a200341186a41206a200341b0016a41286a290300370300200341186a41286a2013370300200341186a41306a2012370300200341286a200f370300200320103703302003200a3703182003200e3703200b200341186a41106a21020240024002400240024002400240200a200629030022137d2214200a56200e200641086a29030022157d200a201354ad7d2212200e562012200e511b450d004280808080b002211341cbe2c200210d4180800c21060c010b2003201437031820032012370320200f20137c2216200f542206201020157c2006ad7c221720105420172010511b4101470d0142808080808001211341839dc500210d4180800821062014210a2012210e0b200341d0006a41206a200241206a290300370300200341d0006a41186a200241186a290300370300200341d0006a41106a200241106a290300370300200341d0006a41086a200241086a290300370300200320022903003703500c010b200341186a41186a2017370300200320163703282013201584500d01200341f8006a200528020010a802200341b0026a2003280278220520032802800110a902200341e0026a290300420020032903b00242015122061b2113200341d8026a290300420020061b21150240200328027c450d00200510290b2015201458201320125820132012511b0d01200341d0006a41206a200241206a290300370300200341d0006a41186a200241186a290300370300200341d0006a41106a200241106a290300370300200341d0006a41086a200241086a2903003703002003200229030037035041dee2c200210d4280808080d00221134180800421062014210a2012210e0b20064180800c7141830c722106200dad221242088842ff018321102013201284428080fcffff03832113410121020c010b200341d0006a41206a200241206a2903002217370300200341d0006a41186a200241186a2903002216370300200341d0006a41106a200241106a2903002218370300200341d0006a41086a200241086a290300221337030020032002290300221537035020042802002102200341f8006a41186a2013370300200341f8006a41206a22052018370300200341a0016a22192016370300200341a8016a221a20173703002003201537038801200320143703782003201237038001427f200a200f7c220f200f200a542206200e20107c2006ad7c220a200e54200a200e511b22061b427f200a20061b8450210602400240427f201420157c220a200a2014542204201220137c2004ad7c220a201254200a2012511b22041b220e4280c8afa025544100427f200a20041b220a501b0d00200341f8006a41106a2903002115201a29030021172019290300210a2005290300210e2003290380012110200329037821134201211620032903900121180c010b420021160240200e200a84500d00200e200a10d402200341e8026a200a370300200341e0026a200e370300200341b0026a41086a41013a0000200341b9026a2002290000370000200341c1026a200241086a290000370000200341c9026a200241106a290000370000200341d1026a200241186a290000370000200341033a00b002200341b0026a10cb010b0b2006ad210f200341d8016a200e370300200341e0016a200a370300200341c0016a2010370300200341e8016a2017370300200341c8016a2015370300200320183703d001200320113703f001200320133703b801410021022003200c4100200942015122061b22043a00fc012003200b410020061b220b3602f801200320164201512206ad3703b001024020060d002008ad4220862007ad841004420021102014210a2012210e420021130c010b410410272206450d012006200b360000200641044108102b2206450d01200620043a0004200641084115102b2206450d01200620133700052006410d6a2010370000200341d0016a2903002110200341c8016a290300211320064115412a102b2206450d01200620133700152006411d6a20103700002006412a41d400102b2206450d012006200e3700252006412d6a200a3700002006413d6a200341f0016a2903003700002006200341e8016a2903003700352008ad4220862007ad842006ad4280808080d0088410032006102942002113420121102014210a2012210e0b0240200328020c450d00200710290b024002402002450d0020002006360204200041086a2010420886200dad42ff018384201384370200410121020c010b024002400240200d41ff017122020d0020104200510d004103210d200341b0026a21020c010b2002450d0120104200520d014104210d200341b0016a21020b200241086a200d3a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a290000370000200210cb010b200041186a200e370300200041106a200a370300200041086a200f370300410021020b20002002360200200341b0036a24000f0b1030000b13002000410d360204200041b0dcc3003602000bc11603107f057e057f230022062107200641e0016b41607122062400200241ffff03200241ffff03491b210202400240024002400240024002400240024020040d00200241017641036a220810272209450d01200641003602202006200836021c20062009360218200620023602a401200641013b01a001200641a0016a200641186a10f402200141086a280200210a2001280204210b20012802002102024020012d000c0d00410021010c050b2001410d6a2d0000410f71210c0c030b200241017641036a220c10272209450d00200641003602202006200c36021c20062009360218200620023602a40120064181023b01a001200641a0016a200641186a10f402200141086a280200210a2001280204210b20012802002102024020012d000c0d00410021010c050b2001410d6a2d0000410f7121080c010b1039000b410121010c020b410121010b03400240024020010e020001010b02402002200a490d00200641186a21010c040b200b20026a2d0000210c200241016a2102410121010c010b024020062802202201200628021c470d00200141016a22082001490d05200141017422092008200920084b1b22084100480d050240024020010d00024020080d00410121090c020b2008102722090d010c060b2006280218210920012008460d00200920012008102b2209450d050b2006200836021c200620093602180b200628021820016a200c3a00002006200141016a360220410021010c000b0b03400240024020010e020001010b02402002200a490d00200641186a21010c030b200b20026a2d00002108200241016a2102410121010c010b024020062802202201200628021c470d00200141016a220c2001490d0420014101742209200c2009200c4b1b220c4100480d040240024020010d000240200c0d00410121090c020b200c10272209450d050c010b200628021821092001200c460d0020092001200c102b2209450d040b2006200c36021c200620093602180b200628021820016a20083a00002006200141016a360220410021010c000b0b200641086a41086a200141086a280200220d360200200620012902003703080240200d200628020c470d00200d41016a2201200d490d02200d41017422022001200220014b1b22014100480d0202400240200d0d00024020010d00410121020c020b200110272202450d030c010b20062802082102200d2001460d002002200d2001102b2202450d020b2006200136020c200620023602080b2006280208220e200d6a41003a00002006200628021041016a220136021002402001200628020c470d00200141016a22022001490d02200141017422082002200820024b1b22024100480d020240024020010d00024020020d004101210e0c020b20021027220e450d030c010b20012002460d00200e20012002102b220e450d020b2006200236020c2006200e3602080b200e20016a41003a00002006200628021041016a220f36021002402004450d002005200641086a107102400240200628020c2202200628021022016b2005490d00200120056a210f2006280208210e0c010b200120056a220f2001490d0320024101742208200f2008200f4b1b22084100480d030240024020020d00024020080d004101210e0c020b20081027220e450d040c010b2006280208210e20022008460d00200e20022008102b220e450d030b2006200836020c2006200e3602080b200e20016a2004200510e4071a2006200f3602100b02400240024002402003280200220120032802042210470d0041002103410021010c010b200341106a28020021112003280208210a200328020c221241096a2113200641186a4101722108200641a0016a4101722114200641e0006a4101722102201241046a2115410021034101210b024002400340200641023a00a0012001290200211620062903b801211720062903b001211820062903a8012119200120062903a0013702002001290208211a200120193702082001290210211920012018370210200141186a220c2902002118200c201737020020062018370378200620193703702006201a37036820062016370360200141206a280200211b200641a0016a41176a220c200241176a290000370000200641a0016a41106a2204200241106a290000370300200641a0016a41086a2205200241086a290000370300200620022900003703a00102402016a7221c41ff0171221d4103470d0020034180fe037141087621010c050b200641c0006a41176a2209200c290000370000200641c0006a41106a221e2004290300370300200641c0006a41086a20052903002216370300200620062903a0012217370340200641e0006a41176a221f2009290000370000200641e0006a41106a220c201e290300370300200641e0006a41086a2209201637030020062017370360024002400240201d4102470d00200641023a0018200641e0006a41186a200841186a290000370300200c200841106a2900003703002009200841086a290000370300200620082900003703604100211d0c010b024002402015280200221d41244b0d002013211e0c010b2012280210211d201228020c211e0b2006201d360294012006201e360290012006201228020036029801201128020028020020064190016a4101200a109104211d2011280204280200211e20142006290360370000201441086a2009290300370000201441106a200c290300370000201441176a201f2900003700002006201c3a00a0012006201b3602c001200641186a201e200641a0016a20112802002802001092042011280200280200201d10930420062d0018221d4103460d01200641e0006a41186a221e200841186a290000370300200c200841106a2900003703002009200841086a29000037030020062008290000370360024002400240201d410371417f6a221b41014b0d004100211d201b0e020103010b4120200641086a107102400240200628020c2205200628021022046b4120490d002006280208210e0c010b200441206a221d2004490d0c2005410174220e201d200e201d4b1b221d4100480d0c0240024020050d000240201d0d004101210e0c020b201d1027220e450d0d0c010b2006280208210e2005201d460d00200e2005201d102b220e450d0c0b2006201d36020c2006200e3602080b200e20046a22052006290360370000200541186a201e290300370000200541106a200c290300370000200541086a2009290300370000200441206a210f0c010b200628023c211d200641a0016a41186a201e2903003703002004200c29030037030020052009290300370300200620062903603703a001201d41214f0d04201d200641086a107102400240200628020c22092006280210220c6b201d490d002006280208210e0c010b200c201d6a2204200c490d0b200941017422052004200520044b1b22044100480d0b0240024020090d00024020040d004101210e0c020b20041027220e450d0c0c010b2006280208210e20092004460d00200e20092004102b220e450d0b0b2006200436020c2006200e3602080b200e200c6a200641a0016a201d10e4071a200c201d6a210f0b2006200f360210200b211d0b200a41016a210a200b410174210b201d2003722103200141246a22012010460d030c010b0b20034180fe037141087621010c040b201d412041a4e5c300104b000b20034180fe037141087621010b200641033a0060200641b7016a2006290078370000200641a0016a41106a2006290071370300200641a8016a2006290069370300200620062900613703a0010b200641033a00180b200d41026a210202400240200d417d4b0d00200f2002490d01200e200d6a220220013a0001200220033a0000200041086a200641086a41086a28020036020020002006290308370200200724000f0b200d200241b4e5c300104c000b2002200f41b4e5c300104b000b1030000b1032000be309010d7f230041106b2204240002400240024002400240024020010d00410021010c010b200141086a28020022054101762106200141046a2802002107024002400240024020054101710d00200720064f0d012006200741b09fcc00104c000b200720064b0d012006200741c09fcc001036000b200720066b2108200128020020066a21090c010b20002001280200220120066a2d0000410f7110d1072007200641016a22066b2108200120066a21090b2000280200220121060240200141244d0d002000410c6a28020021060b02400240024002402006410174200028022c460d00200121060240200141244d0d002000410c6a28020021060b2008450d032006417f6a2106200141244b0d01200041056a210a2001210b0c020b0240200141244d0d002000410c6a28020021010b20042000200810d207024020042802004101470d00200441086a2802000d0541a4a1cc00411141b8a1cc001033000b2000280200220a21060240200a41244d0d002000410c6a28020021060b024020062001490d0002400240200a41244b0d00200041056a210a0c010b200041086a280200210a0b200a20016a220a20086a200a200620016b10e5071a200a2009200810e4071a200620086a21010240200028020041244b0d00200020013602000c040b2000410c6a20013602000c030b41c8a1cc00411e41b8a1cc001033000b2000410c6a280200210b200041086a280200210a0b200b20064d0d03200a20066a2d0000210a02400240200141244b0d00200041056a210b0c010b2000410c6a2802002101200041086a280200210b0b200120064d0d04200b20066a200a4170713a000020092d0000210a024002402000280200220141244b0d00200041056a210b0c010b2000410c6a2802002101200041086a280200210b0b200120064d0d05200b20066a220120012d0000200a410476723a000002402008417f6a220c450d00200041056a210d2000410c6a210e410021010340024002400240024020082001460d00200141016a220620084f0d01200920016a22012d0000210b200141016a2d0000210f0240200028020c20002802002201200141244b22101b220a2001412420101b470d0020042000410110d207024020042802004101470d00200441086a2802000d0a41a4a1cc00411141b8a1cc001033000b200028020021010b200f410476200b41047472210b200141244b0d02200d21012000210f0c030b2008200841909fcc001036000b200141016a200841a09fcc001036000b20002802082101200e210f0b200f200a41016a3602002001200a6a200b3a000020062101200c2006470d000b0b2009200c6a2d0000210a41242106024002402000280200220b41244b0d00200021010c010b2000410c6a2101200b21060b0240200128020022012006470d0020042000410110d20720042802004101470d00200441086a2802000d0341a4a1cc00411141b8a1cc001033000b200a410474210602400240200028020041244b0d00200041056a210a2000210b0c010b2000410c6a210b200041086a280200210a0b200b200141016a360200200a20016a20063a00000b2000200028022c20084101746a36022c200741017420056b21010b02402002450d002000200310d107200141016a21010b200441106a240020010f0b1030000b2006200b41e09ecc001036000b2006200141f09ecc001036000b2006200141809fcc001036000bd81803077f067e077f23002204210520044180036b416071220424002004200336021420042001360210024002400240024002400240024002400240024002400240024020022d00004101460d00200241046a28020021020240200141c0006a220628020022072007417f6a200141386a22082802002203200141346a22092802006b716b4101470d002001413c6a108b0120092802002209200828020022034d0d0002402003200720096b220a490d00200128023c22032006280200200a6b22074102746a200320094102746a200a41027410e4071a200141346a2007360200200141386a28020021030c010b200128023c220920074102746a2009200341027410e4071a200141386a2203200328020020076a22033602000b20082006280200417f6a200341016a713602002001413c6a28020020034102746a2002360200200141306a280200220320024d0d022001280228200241fc006c6a2201290210210b200120042903b0023702102001290208210c200120042903a802370208200441003a00a002200441003602a4022001290200210d200120042903a002370200200441d8006a2001290240220e370300200441386a22032001290220370300200441f8006a2001290260370300200141186a2202290200210f200220042903b802370200200441186a41d8006a2207200141d8006a290200370300200441186a41d0006a2208200141d0006a290200370300200441186a41c8006a2206200141c8006a290200370300200441186a41386a200141386a2902002210370300200441186a41306a200141306a290200370300200441186a41286a2209200141286a290200370300200441186a41186a220a200f370300200441186a41e8006a200141e8006a290200370300200441186a41f0006a200141f0006a290200370300200441186a41f8006a200141f8006a2802003602002004200b3703282004200c3703202004200d370318200da7221141ff01714101460d01200ba72112200ca72102200b422088a72113200c422088a72101200e422088a721142010a72115200441b0016a41086a22162003290300370300200441b0016a41106a22172009290300370300200441b0016a41186a200441c8006a29030037030020044198016a41086a200829030037030020044198016a41106a20072802003602002004200a2903003703b0012004200629030037039801200441d4006a290200220b422088a721032004200441106a3602d4012004200441146a3602d001200ba7210702400240024002400240200d422088a70e050102030400010b200441ac026a2013360200200441a0026a41086a2012360200200441a0026a41106a20042903b001370300200441a0026a41186a2016290300370300200441c0026a2017290300370300200441c8026a200441b0016a41186a290300370300200420023602a002200420013602a40202400240200141244b0d00200441a9026a21130c010b20042802b00221010b200241017621080240024020024101710d0020012008490d0941002106410021090c010b200120084d0d0941012109201320086a2d0000410f712106200841016a21080b200441e5026a20063a0000200441e0026a200120086b360200200420093a00e402200441003602d802200420042f01d8013b01e6022004201320086a3602dc0220044188026a200441d0016a3602002004410036028002200420153602f8012004201541c0046a3602fc01200141017420026b21012004200441a0026a36028402024002402007450d00200441e8016a200441d8026a2001200441f8016a200720141090042003450d01200710290c010b200441e8016a200441d8026a2001200441f8016a410020141090040b2015102920042802a40241244d0d0e20042802ac0210290c0e0b410110272201450d08200141003a000020044281808080103702ec01200420013602e8010c0d0b200441ac026a2013360200200441a0026a41086a2012360200200441a0026a41106a20042903b001370300200441a0026a41186a2016290300370300200441c0026a2017290300370300200441c8026a200441b0016a41186a290300370300200420023602a002200420013602a40202400240200141244b0d00200441a9026a21130c010b20042802b00221010b2002410176210802400240200241017122020d0020012008490d0a41002102410021060c010b200120084d0d0a201320086a2d0000410f712106200841016a21080b20044180026a200120086b360200200420063a00f901200420023a00f8012004201320086a3602fc01200420042f01d8013b01fa01200441d8026a200441f8016a10a5062003200441d8026a10710240024020042802dc02220820042802e00222016b2003490d0020042802d80221020c010b200120036a22022001490d0b200841017422062002200620024b1b22064100480d0b0240024020080d00024020060d00410121020c020b2006102722020d010c0e0b20042802d802210220082006460d00200220082006102b2202450d0d0b200420063602dc02200420023602d8020b200220016a2015200310e4071a200441f0016a200120036a360200200420042903d8023703e80102402007450d00201510290b20042802a40241244d0d0c20042802ac0210290c0c0b200441ac026a2013360200200441a0026a41086a2012360200200441a0026a41106a20042903b001370300200441a0026a41186a2016290300370300200441c0026a2017290300370300200441c8026a200441b0016a41186a290300370300200420023602a002200420013602a40202400240200141244b0d00200441a9026a21130c010b20042802b00221010b200420023602e001200420013602dc01200420133602d801200441e8016a200441d8016a10a60620042802d001280200200441d8016a41002004109104210120042802d4012802002100200441e4026a2014360200200441d8026a41106a200429039801370300200441f0026a200441a0016a290300370300200441f8026a20044198016a41106a2802003602002004200b3702dc02200420153602d802200441f8016a2000200441d8026a20042802d00128020010920420042802d0012802002001109304419cf7ca00412841b8a1cc001033000b419cf7ca00412841b8a1cc001033000b200041003a000020002002290001370001200041196a200241196a290000370000200041116a200241116a290000370000200041096a200241096a2900003700000c0a0b20002004290019370001200041003a0000200041196a200441186a41196a290000370000200041116a200441186a41116a290000370000200041096a200441186a41096a2900003700000c0a0b20022003418095c8001036000b2008200141b09fcc00104c000b2008200141c09fcc001036000b1039000b2008200141b09fcc00104c000b2008200141c09fcc001036000b1032000b1030000b0240024020042802f0012201411f4b0d0020042802e8012102200441a0026a20016a4100412020016b10e6071a200441a0026a2002200110e4071a200041246a2001360200200041196a200441b8026a290000370000200041116a200441b0026a290000370000200041096a200441a8026a290000370000200020042900a002370001410121010c010b2004280210220241c8006a2802002108200228024421062004280214220228022c2209410176210720022802002103024002400240024002402009410171450d0002400240200341244b0d00200241056a21092003210a0c010b2002410c6a280200210a200241086a28020021090b200a2007490d0202400240200341244b0d00200241056a21020c010b2002410c6a2802002103200241086a28020021020b200320074d0d0320044181026a200220076a2d000041f001713a0000200420093602f801410121020c010b02400240200341244b0d00200241056a21020c010b2002410c6a2802002103200241086a28020021020b20032007490d03200420023602f801410021020b200420023a008002200420073602fc01200441a0026a2006200441f8016a20042802e801220220012008280214110500200020042903a002370001200041096a200441a8026a290300370000200041116a200441b0026a290300370000200041196a200441b8026a29030037000020042802102201200128027441016a360274410021010c030b2007200a41b09ecc00104b000b2007200341c09ecc001036000b2007200341d09ecc00104b000b200020013a0000024020042802ec01450d00200210290b201141ff01710d010b200524000f0b2004413c6a10a706200524000b9d0301057f02402001450d0002400240200028022c220220014d0d00200220016b2203410176200341017122046a21052000280200220121020240200141244d0d002000410c6a28020021020b200520024f0d012000410c6a2106200520026b41016a2102034002400240200141244b0d00200021050c010b20062802002101200621050b02402001450d0020052001417f6a3602000b2002450d02200241016a2102200028020021010c000b0b024002402000280200220141244b0d00200021020c010b2000410c6a220228020021010b02402001450d00200241003602000b2000410036022c0c010b2000200336022c2004450d00024002402000280200220141244b0d00200041056a2106200121050c010b200041086a28020021062000410c6a28020021050b2005417f6a2102024002402005450d00200620026a2d0000210502400240200141244b0d00200041056a21000c010b2000410c6a2802002101200041086a28020021000b200120024d0d01200020026a20054170713a00000f0b2002200541909ecc001036000b2002200141a09ecc001036000b0b130020004108360204200041c4e5c3003602000b130020004106360204200041c8ecc3003602000b990301067f41012103024002400240024020024101742204417f4c0d00410021054100210602402004450d00200410272203450d02200421060b02402002450d0041002105034020012d000021070240024020052006460d00200621040c010b200641016a22042006490d05200641017422082004200820044b1b22044100480d05024020060d00024020040d00410121030c020b2004102722030d010c070b20062004460d00200320062004102b2203450d060b200320056a413041d700200741a001491b20074104766a3a000002400240200541016a22082004460d0020042106200821040c010b200441016a22062004490d05200441017422082006200820064b1b22064100480d05024020040d00024020060d00410121030c020b200610272203450d070c010b20042006460d00200320042006102b2203450d060b200141016a2101200320046a413041d7002007410f712204410a491b20046a3a0000200541026a21052002417f6a22020d000b0b2000200536020820002006360204200020033602000f0b1038000b1039000b1032000b1030000ba00d02097f037e230041a0026b220624000240024002400240200320056a41216a22070d0041012108410021094100210a0c010b410021094100210b4101210803402007410a6e210c024002402009200b460d00200b210a0c010b200b41016a220a200b490d03200b410174220d200a200d200a4b1b220a4100480d0302400240200b0d000240200a0d00410121080c020b200a102722080d010c060b200b200a460d002008200b200a102b2208450d050b200a210b0b200820096a2007200c41766c6a4130723a0000200941016a2109200741094b210d200c2107200d0d000b0b411a210d0240411a1027220c450d00200c41186a41002f00faf0433b0000200c41106a41002900f2f043370000200c41086a41002900eaf043370000200c41002900e2f0433700000240024020090d00411a21090c010b2009411a6a220b2009490d02200b4134200b41344b1b220d4100480d02200c411a200d102b220c450d03200820096a210e2008417f6a2107200c411a6a210b0340200b200720096a2d00003a0000200b41016a210b2009417f6a22090d000b200e20086b411a6a21090b0240200a450d00200810290b02400240200d20096b41204d0d00200d21070c010b200941216a220b2009490d02200d4101742207200b2007200b4b1b22074100480d02200d2007460d00200c200d2007102b220c450d030b200c20096a220b4100290090a445370000200b41206a41002d00b0a4453a0000200b41186a41002900a8a445370000200b41106a41002900a0a445370000200b41086a4100290098a445370000024002402007200941216a220b6b2003490d00200721090c010b200b20036a2209200b490d022007410174220a2009200a20094b1b22094100480d02024020070d00024020090d004101210c0c020b20091027220c450d040c010b20072009460d00200c20072009102b220c450d030b200c200b6a2002200310e4071a024002402009200b20036a220b6b2005490d00200921070c010b200b20056a2207200b490d022009410174220a2007200a20074b1b22074100480d02024020090d00024020070d004101210c0c020b20071027220c450d040c010b20092007460d00200c20092007102b220c450d030b200c200b6a2004200510e4071a200b20056aad422086200cad8410112209290000210f200941086a2900002110200941106a2900002111200641186a200941186a290000370300200641106a2011370300200641086a20103703002006200f3703002009102902402007450d00200c10290b41002109200641206a41106a4100360200200641206a41086a420037030020064200370320200641d8016a20012006109b04024020062d00d8014101460d00200641d0016a20064191026a290000370300200641c8016a20064189026a290000370300200641c0016a20064181026a290000370300200641b8016a200641f9016a290000370300200641b0016a200641f1016a290000370300200641a8016a200641e9016a290000370300200641a0016a200641e1016a290000370300200620062900d90137039801410121090b200641d8016a41386a220b20064198016a41386a290300370300200641d8016a41306a220720064198016a41306a290300370300200641d8016a41286a220c20064198016a41286a290300370300200641d8016a41206a220a20064198016a41206a290300370300200641d8016a41186a220d20064198016a41186a290300370300200641d8016a41106a220820064198016a41106a290300370300200641d8016a41086a220320064198016a41086a29030037030020062006290398013703d801024002402009450d00200641d8006a41386a200b290300370300200641d8006a41306a2007290300370300200641d8006a41286a200c290300370300200641d8006a41206a200a290300370300200641d8006a41186a200d290300370300200641d8006a41106a2008290300370300200641d8006a41086a2003290300370300200620062903d801370358200641d8006aad428080808080088410112209290000210f200941086a2900002110200941106a2900002111200641386a41186a200941186a290000370300200641386a41106a2011370300200641386a41086a20103703002006200f37033820091029200641206a41106a200641d4006a2802002209360200200641206a41086a200641cc006a290200220f370300200620062902442210370320200041116a2009360000200041096a200f37000020002010370001410121090c010b410021090b200020093a0000200641a0026a24000f0b1039000b1032000b1030000be90205017f017e017f017e017f230041206b2202240041c087cc00ad4280808080e000842203100122042900002105200241086a200441086a29000037030020022005370300200410292003100122042900002103200241106a41086a200441086a29000037030020022003370310200410290240411410272204450d0020042001290000370000200441106a2206200141106a280000360000200441086a200141086a290000370000411410272201450d0020012004290000370000200141106a2006280000360000200141086a2206200441086a29000037000020041029413410272204450d002004200229031037001020042002290300370000200441086a200241086a290300370000200441186a200241106a41086a290300370000200042b4808080c0063702042000200436020020042001290000370020200441286a2006290000370000200441306a200141106a28000036000020011029200241206a24000f0b1039000bef0203027f017e017f230041206b2202240041c087cc00ad4280808080e00084100122032900002104200241086a200341086a290000370300200220043703002003102941c687cc00ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240411410272203450d0020032001290000370000200341106a2205200141106a280000360000200341086a200141086a290000370000411410272201450d0020012003290000370000200141106a2005280000360000200141086a2205200341086a29000037000020031029413410272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042b4808080c0063702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a28000036000020011029200241206a24000f0b1039000b940201037f230041d0006b220224002002200136020420022000360200200241086a2001ad4220862000ad841007108b0202400240200228020822010d00410221000c010b200228020c210302400240200241106a280200450d0020012d0000220441014b0d0041002100024020040e020200020b410121000c010b20024100360220200242013703182002410d36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241f4eaca003602382002200241286a360248200241346a41a8a3c800200241386a10371a200235022042208620023502188410080240200228021c450d00200228021810290b410221000b2003450d00200110290b200241d0006a240020000bba0503017f017e037f23004190016b22032400024020012002101d2204422088a72201450d002004a722052d0000220241014b0d002001417f6a210602400240024020020e020001000b41002101200341003a008801200541016a21070240034020062001460d01200341c8006a20016a200720016a2d00003a00002003200141016a22023a00880120022101200241c000470d000b200341106a200341d1006a290000370300200341186a200341d9006a290000370300200341206a200341e1006a290000370300200341286a200341e9006a290000370300200341306a200341f1006a290000370300200341386a200341f9006a2900003703002003413f6a20034180016a2900003700002003200329004937030820032d0048210241002106200341086a21010c020b200141ff0171450d02200341003a0088010c020b2006450d0120052d0001220241034f0d01200341086a41376a200341c8006a41376a290000370000200341086a41306a200341c8006a41306a290000370300200341086a41286a200341c8006a41286a290000370300200341086a41206a200341c8006a41206a290000370300200341086a41186a200341c8006a41186a290000370300200341086a41106a200341c8006a41106a290000370300200341086a41086a200341c8006a41086a2900003703002003200329004837030841012106200341086a21010b200020023a0001200020063a0000200041026a20012900003700002000410a6a200141086a290000370000200041126a200141106a2900003700002000411a6a200141186a290000370000200041226a200141206a2900003700002000412a6a200141286a290000370000200041326a200141306a290000370000200041396a200141376a2900003700002005102920034190016a24000f0b41e891cc00412e200341c8006a419893cc00419892cc00103a000b9f0303027f017e027f230041206b2202240041c087cc00ad4280808080e00084100122032900002104200241086a200341086a290000370300200220043703002003102941fcf0c300ad4280808080900184100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000bc50602027f027e230041f0006b220324002003200236020420032001360200200341086a2002ad4220862001ad841007108b0202400240200328020822010d00200041003a00000c010b200341106a2802002102200328020c2104200341003a0054024002402002450d00200320012d00003a0040200341013a0054024020024101460d00200320012d00013a0041200341023a005420024102460d00200320012d00023a0042200341033a005420024103460d00200320012d00033a0043200341043a005420024104460d00200320012d00043a0044200341053a005420024105460d00200320012d00053a0045200341063a005420024106460d00200320012d00063a0046200341073a005420024107460d00200320012d00073a0047200341083a005420024108460d00200320012d00083a0048200341093a005420024109460d00200320012d00093a00492003410a3a00542002410a460d00200320012d000a3a004a2003410b3a00542002410b460d00200320012d000b3a004b2003410c3a00542002410c460d00200320012d000c3a004c2003410d3a00542002410d460d00200320012d000d3a004d2003410e3a00542002410e460d00200320012d000e3a004e2003410f3a00542002410f460d00200320012d000f3a004f200341103a005420024110460d00200320012d00103a0050200341113a005420024111460d00200320012d00113a0051200341123a005420024112460d00200320012d00123a0052200341133a005420024113460d00200341186a41086a200341c0006a41086a2903002205370300200320012d00133a0053200341186a41106a200341c0006a41106a2802002202360200200320032903402206370318200041116a2002360000200041096a200537000020002006370001410121020c020b200341003a00540b20034100360220200342013703182003410d360234200320033602302003200341186a36023c200341d4006a410136020020034201370244200341f4eaca003602402003200341306a3602502003413c6a41a8a3c800200341c0006a10371a200335022042208620033502188410080240200328021c450d00200328021810290b410021020b200020023a00002004450d00200110290b200341f0006a24000ba00403037f017e047f230041206b22022400200241086a200110c801024002400240024002402002280208450d00200041003602000c010b200228020c22032001280204410c6e2204200420034b1bad420c7e2205422088a70d012005a72204417f4c0d010240024020040d00410421060c010b200410272206450d030b41002107200241003602182002200636021020022004410c6e3602140240024002402003450d0003402002200110c80120022802000d03200128020420022802042204490d032004417f4c0d050240024020040d0041002108410121090c010b2004102d2209450d0720012802042004490d0320092001280200200410e4071a200128020422082004490d082001200820046b3602042001200128020020046a360200200421080b2004ad4220862008ad842105024020072002280214470d00200241106a20074101109d0120022802102106200228021821070b20062007410c6c6a22042005370204200420093602002002200741016a22073602182003417f6a22030d000b0b20002002290310370200200041086a200241106a41086a2802003602000c020b200910290b2000410036020002402007450d002007410c6c21012006210403400240200441046a280200450d00200428020010290b2004410c6a2104200141746a22010d000b0b20022802142204450d002004410c6c450d00200610290b200241206a24000f0b1038000b1039000b2004200841ccafc000104c000bd10b010b7f230041d0016b2202240002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a3602002005417f6a220541024b0d000240024002400240024020050e03000102000b41002105200241003a00a8012003417f6a2106417e21070240034020062005460d0120024188016a20056a200420056a220841016a2d00003a00002001200320076a3602042001200841026a3602002002200541016a22083a00a8012007417f6a21072008210520084120470d000b200241c8006a41186a20024188016a41186a290300370300200241c8006a41106a20024188016a41106a290300370300200241c8006a41086a20024188016a41086a29030037030020022002290388013703482008417f7320036a2107200420086a41016a210841002106200241c8006a21050c030b200541ff0171450d04200241003a00a8010c040b41002105200241003a00a8012003417f6a2106417e21070240034020062005460d0120024188016a20056a200420056a220841016a2d00003a00002001200320076a3602042001200841026a3602002002200541016a22083a00a8012007417f6a21072008210520084120470d000b200241c8006a41186a20024188016a41186a290300370300200241c8006a41106a20024188016a41106a290300370300200241c8006a41086a20024188016a41086a29030037030020022002290388013703482008417f7320036a210741012106200420086a41016a2108200241c8006a21050c020b200541ff0171450d03200241003a00a8010c030b41002105200241003a00a8012003417f6a2106417e2107034020062005460d0220024188016a20056a200420056a220841016a2d00003a00002001200320076a3602042001200841026a3602002002200541016a22083a00a8012007417f6a21072008210520084120470d000b200241c8006a41186a20024188016a41186a290300370300200241c8006a41106a20024188016a41106a290300370300200241c8006a41086a20024188016a41086a29030037030020022002290388013703482008417f7320036a2107200420086a41016a210841022106200241c8006a21050b200241286a41086a200541086a290000370300200241286a41106a200541106a290000370300200241286a41186a200541186a2900003703002002200529000037032841002105200241003a00c8012007417f6a2103034020072005460d0320024188016a20056a200820056a22042d00003a0000200120033602042001200441016a3602002002200541016a22043a00c8012003417f6a210320042105200441c000470d000b200241c8006a41386a220120024188016a41386a290300370300200241c8006a41306a220520024188016a41306a290300370300200241c8006a41286a220320024188016a41286a290300370300200241c8006a41206a220420024188016a41206a290300370300200241c8006a41186a220720024188016a41186a290300370300200241c8006a41106a220820024188016a41106a290300370300200241c8006a41086a220920024188016a41086a290300370300200241086a41086a220a200241286a41086a290300370300200241086a41106a220b200241286a41106a290300370300200241086a41186a220c200241286a41186a290300370300200220022903880137034820022002290328370308200020063a000020002002290308370001200041096a200a290300370000200041116a200b290300370000200041196a200c290300370000200041216a2002290348370000200041296a2009290300370000200041316a2008290300370000200041396a2007290300370000200041c1006a2004290300370000200041c9006a2003290300370000200041d1006a2005290300370000200041d9006a20012903003700000c030b200541ff0171450d00200241003a00a8010b200041033a00000c010b0240200541ff0171450d00200241003a00c8010b200041033a00000b200241d0016a24000bee0201027f230041106b220224000240024020002d0000220341024b0d0002400240024020030e03000102000b200241013a000f20012002410f6a41011072412010272203450d0320032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201072200310290c020b200241023a000f20012002410f6a41011072412010272203450d0220032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201072200310290c010b200241033a000f20012002410f6a41011072412010272203450d0120032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201072200310290b2001200041216a41c0001072200241106a24000f0b1039000bb10201057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d0041012105410021040c010b200410272205450d020b2003410036020820032005360200200320043602042001200310710240024020032802042206200328020822056b2001490d0020032802002104200621070c010b200520016a22042005490d03200641017422072004200720044b1b22074100480d030240024020060d00024020070d00410121040c020b2007102722040d010c060b2003280200210420062007460d00200420062007102b2204450d050b20032007360204200320043602000b200420056a2000200110e4071a2002290200200520016aad4220862004ad84100302402007450d00200410290b200341106a24000f0b1038000b1039000b1032000b1030000ba20201057f230041106b220324000240024002400240200141047422044104722205417f4c0d00200510272206450d012003410036020820032005360204200320063602002001200310710240024020032802042207200328020822056b2004490d0020032802002101200721060c010b200520046a22012005490d03200741017422062001200620014b1b22064100480d030240024020070d00024020060d00410121010c020b2006102722010d010c060b2003280200210120072006460d00200120072006102b2201450d050b20032006360204200320013602000b200120056a2000200410e4071a2002290200200520046aad4220862001ad84100302402006450d00200110290b200341106a24000f0b1038000b1039000b1032000b1030000bb60201057f230041106b2203240002400240024002402001410274220441046a2205417f4c0d000240024020050d0041012106410021050c010b200510272206450d020b2003410036020820032006360200200320053602042001200310710240024020032802042207200328020822016b2004490d0020032802002105200721060c010b200120046a22052001490d03200741017422062005200620054b1b22064100480d030240024020070d00024020060d00410121050c020b2006102722050d010c060b2003280200210520072006460d00200520072006102b2205450d050b20032006360204200320053602000b200520016a2000200410e4071a2002290200200120046aad4220862005ad84100302402006450d00200510290b200341106a24000f0b1038000b1039000b1032000b1030000ba30301067f230041106b22032400024020014105744104722204417f4c0d000240200410272205450d002003410036020820032004360204200320053602002001200310710240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020002101024002402006200522046b4120490d00200441206a21050c010b024002400240200441206a22052004490d00200641017422002005200020054b1b22004100480d000240024020060d00024020000d00410121070c020b2000102721070c040b20062000470d020b200021060c030b1032000b200720062000102b21070b2000210620070d001030000b200141206a2100200720046a22042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a290000370000200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100302402006450d00200710290b200341106a24000f0b1039000b1038000b930201037f230041106b220224002002200028024836020c20012002410c6a410410720240412010272203450d0020032000290058370000200341186a200041f0006a290000370000200341106a200041e8006a290000370000200341086a200041e0006a290000370000200120034120107220031029200028024c2103200041d4006a28020022042001107120012003200410722001200041f8006a41201072200120004198016a41c0001072412010272203450d00200320002900d801370000200341186a200041f0016a290000370000200341106a200041e8016a290000370000200341086a200041e0016a2900003700002001200341201072200310292000200110ae03200241106a24000f0b1039000b13002000410436020420004188f1c3003602000b3400200041c087cc0036020420004100360200200041146a4105360200200041106a41fc93c400360200200041086a42063702000b130020004101360204200041c09bc4003602000bbb0201067f230041106b22022400024002400240412510272203450d0020024225370204200220033602004121200210710240024020022802042204200228020822036b4121490d00200341216a2105200228020021060c010b200341216a22052003490d02200441017422062005200620054b1b22074100480d020240024020040d00024020070d00410121060c020b2007102722060d010c050b2002280200210620042007460d00200620042007102b2206450d040b20022007360204200220063602000b200620036a22034100290090a445370000200341206a41002d00b0a4453a0000200341186a41002900a8a445370000200341106a41002900a0a445370000200341086a4100290098a44537000020002002290300370200200041086a2005360200200241106a24000f0b1039000b1032000b1030000bcb0101037f2001280200210202400240412010272203450d0020032002290000370000200341186a200241186a290000370000200341106a200241106a29000037000041082101200341086a200241086a2900003700000240200341c2ecc300460d00200328000041f0c2c98b06470d020b2003280004210402400240034020014120460d01200320016a2102200141016a210120022d0000450d000b410021010c010b20002004360204410121010b20002001360200200310290f0b1039000b20004100360200200310290bf00204027f017e017f077e0240024020012802042202450d0020012802002203310000210420012002417f6a22053602042001200341016a3602002005450d012003310001210620012002417e6a22053602042001200341026a3602002005450d012003310002210720012002417d6a22053602042001200341036a3602002005450d012003310003210820012002417c6a22053602042001200341046a3602002005450d012003310004210920012002417b6a22053602042001200341056a3602002005450d012003310005210a20012002417a6a22053602042001200341066a3602002005450d012003310006210b2001200241796a22053602042001200341076a3602002005450d01200041003a00002003310007210c2001200241786a3602042001200341086a3602002000200c423886200b42308684200a422886842009422086842008421886842007421086842006420886842004843700010f0b200041013a00000f0b200041013a00000bef0203027f017e017f230041206b2202240041c087cc00ad4280808080e00084100122032900002104200241086a200341086a290000370300200220043703002003102941c687cc00ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240411410272203450d0020032001290000370000200341106a2205200141106a280000360000200341086a200141086a290000370000411410272201450d0020012003290000370000200141106a2005280000360000200141086a2205200341086a29000037000020031029413410272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042b4808080c0063702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a28000036000020011029200241206a24000f0b1039000ba0120b027f027e017f017e017f017e017f027e017f047e057f230041b0026b2203240020034188016a2001109804200341306a200328028801220420032802900110e301200341c0006a290300210520032903382106200328023021070240200328028c01450d00200410290b0240024002400240024002402007450d004200210820034188016a41186a420037030020034188016a41106a2209420037030020034188016a41086a22074200370300200342003703880141c087cc00ad4280808080e0008410012204290000210a2007200441086a2900003703002003200a370388012004102941c497c400ad4280808080d0008410012204290000210a20034188026a41086a220b200441086a2900003703002003200a37038802200410292009200329038802220a370300200341d8006a41086a2007290300370300200341d8006a41106a200a370300200341d8006a41186a200b2903003703002003200329038801370358200341186a200341d8006a412010e30120032903204200200328021822071b220a20067d220c200a56200341186a41106a290300420020071b220d20057d200a200654ad7d220a200d56200a200d511b0d03200341c8006a200110ae042003280248210720032003280250220436029c02200320073602980220034188026a2004ad4220862007ad841007108b0220032802880222040d010c020b2000419b023b0001200041086a4110360200200041046a41e1eac3003602000c030b200328028c02210e02400240024020034188026a41086a280200220b4110490d00200b4170714110460d00200b417c714120470d010b20034100360260200342013703582003410d3602a402200320034198026a3602a0022003200341d8006a3602ac022003419c016a41013602002003420137028c01200341f4eaca00360288012003200341a0026a36029801200341ac026a41a8a3c80020034188016a10371a200335026042208620033502588410080240200328025c450d00200328025810290b420021080c010b200441086a290000210f20042900002110200441186a29000021112004290010210d2004280020210b420121080b200e450d00200410290b0240200328024c450d00200710290b42002112024020084200510d0020034188016a20022010200f200d2011200b10af0420032d0088014104460d002000419b063b0001200041086a4112360200200041046a4181ebc3003602000c020b2003200637038802200320053703900202400240200620058450450d004200210f0c010b20032002360248200341d8006a200220034188026a200341c8006a10de03024020032903584201520d00200341e8006a290300210f200329036021120c010b20034180016a290300210f200341f8006a290300211220032903604201520d00200341d8006a41106a290300210d200341c0016a200341d8006a41186a290300370300200341b8016a200d37030020034188016a41086a41003a000020034191016a200229000037000020034199016a200241086a290000370000200341a1016a200241106a290000370000200341a9016a200241186a290000370000200341033a00880120034188016a10cb010b20034188016a41186a220e420037030020034188016a41106a220b420037030020034188016a41086a22044200370300200342003703880141dcbec500ad4280808080800184220d10012213290000210820034188026a41086a2207201341086a29000037030020032008370388022013102920042007290300370300200320032903880237038801419fe3c200ad4280808080d0018422081001221329000021112007201341086a290000370300200320113703880220131029200b2003290388022211370300200341d8006a41086a22132004290300370300200341d8006a41106a22142011370300200341d8006a41186a2215200729030037030020032003290388013703582003200341d8006a412010e301200341106a29030021112003290308211020032802002116200e4200370300200b4200370300200442003703002003420037038801200d10012217290000210d2007201741086a2900003703002003200d370388022017102920042007290300370300200320032903880237038801200810012217290000210d2007201741086a2900003703002003200d3703880220171029200b200329038802220d370300201320042903003703002014200d3703002015200729030037030020032003290388013703582003427f2011420020161b220d200f7c2010420020161b220820127c22122008542216ad7c220820162008200d542008200d511b22161b370390012003427f201220161b37038801200341d8006aad4280808080800484220d20034188016aad428080808080028422081003200e4200370300200b420037030020044200370300200342003703880141c087cc00ad4280808080e000841001221629000021122004201641086a29000037030020032012370388012016102941c497c400ad4280808080d000841001221629000021122007201641086a2900003703002003201237038802201610292009200329038802370000200941086a2007290300370000201320042903003703002014200b2903003703002015200e29030037030020032003290388013703582003200a370390012003200c37038801200d2008100320034188016a20011098042003350290014220862003280288012207ad8410040240200328028c01450d00200710290b20034188016a200110ae042003350290014220862003280288012207ad8410040240200328028c01450d00200710290b20034188016a200110ac042003350290014220862003280288012207ad8410040240200328028c01450d00200710290b20034188016a41106a200537030020034188016a41086a200637030020034188016a41186a2002290000370300200341a8016a200241086a290000370300200341b0016a200241106a290000370300200341b8016a200241186a290000370300200341c0016a2001290000370300200341c8016a200141086a290000370300200341d0016a200141106a280000360200200341113a00880120034188016a10cb01410421010c020b2000419b083b0001200041086a410c360200200041046a4193ebc3003602000b410321010b200020013a0000200341b0026a24000bef0203027f017e017f230041206b2202240041c087cc00ad4280808080e00084100122032900002104200241086a200341086a290000370300200220043703002003102941dfb3c700ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240411410272203450d0020032001290000370000200341106a2205200141106a280000360000200341086a200141086a290000370000411410272201450d0020012003290000370000200141106a2005280000360000200141086a2205200341086a29000037000020031029413410272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042b4808080c0063702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a28000036000020011029200241206a24000f0b1039000bfc0202047f017e230041c0006b2207240041042108024002402002200384500d00200741206a200110cd05200741086a2007280220220920072802284180a6cc004100410010c7012007280208210a02402007280224450d00200910290b0240200a4101470d002000419c023b0001200041086a4117360200200041046a41a1b3c700360200410321080c010b200741206a200110cd052007350228210b2007280220210941101027220a450d01200a2002370000200a2003370008200a41104120102b220a450d01200a2004370010200a41186a2005370000200a412041c000102b220a450d01200a2006360020200b4220862009ad84200aad4280808080c004841003200a102902402007280224450d00200910290b200741206a41186a200141186a290000370300200741206a41106a200141106a290000370300200741206a41086a200141086a29000037030020072001290000370320200741106a200741206a10cc050b200020083a0000200741c0006a24000f0b1030000b800503017f047e097f230041106b220324002003200141086a29030022042001290300220585220620054218898520064210868520064225897c220642a0cbbf9599b5a19f0a7c2207200229001885200229000020078542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852002290008200642efcdddd088a580a21e7c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852002290010200642bed0fb8bf894dfa4327c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85420042adfed5e4d485fda8d800420010d507200341086a29030020032903007c200420057c852205a7220841197622094108742009722209411074200972210a2001280210220b200871210c200141186a280200210d200141146a280200210e4100210f024003400240200e200c6a2800002210200a732208417f73200841fffdfb776a71418081828478712208450d0002400340200d200868410376200c6a200b7141306c6a22092002460d0120092002412010e707450d012008417f6a2008712208450d020c000b0b200020093602042000410c6a41013a0000200041086a20013602002000410d6a2002290000370000200041156a200241086a2900003700002000411d6a200241106a290000370000200041256a200241186a290000370000410021080c020b200f41046a220f200c6a200b71210c201020104101747141808182847871450d000b200041106a2001360200200041086a2005370300200041146a20022900003700002000411c6a200241086a290000370000200041246a200241106a2900003700002000412c6a200241186a290000370000410121080b20002008360200200341106a24000ba70903017f027e147f230041f0006b220224002002200041086a2903002203200029030022047c37031820022003200485220320044218898520034210868520034225897c3703102001200241106a10b20420022903182002290310852204421988a7220541ff0071220641087420067222064110742006722107200141256a2108200041106a21092000280210220a2004a7220b71210c200141cd006a2d0000210d2001412c6a280200210e200141286a280200210f200041186a2802002110200041146a28020021112001280220211241002113200141cc006a2d000041ff017121140240034002402011200c6a28000022152007732206417f73200641fffdfb776a71418081828478712206450d000240024020124125490d000340024002402010200668410376200c6a200a7141d0006c6a22162001460d0020012016412010e7070d010b024002402016280220221741244b0d00201641206a41056a21180c010b201628022c2117201628022821180b200e2017470d000240200f2018460d00200f2018200e10e7070d010b2014201641cc006a2d0000470d002014450d03200d41ff0171201641cd006a2d000041ff0171460d030b2006417f6a20067122060d000c030b0b024020140d000340024002402010200668410376200c6a200a7141d0006c6a22162001460d0020012016412010e7070d010b024002402016280220221741244b0d00201641206a41056a21180c010b201628022c2117201628022821180b20122017470d00024020082018460d0020082018201210e7070d010b201641cc006a2d0000450d030b2006417f6a20067122060d000c030b0b0340024002402010200668410376200c6a200a7141d0006c6a22162001460d0020012016412010e7070d010b024002402016280220221741244b0d00201641206a41056a21180c010b201628022c2117201628022821180b20122017470d00024020082018460d0020082018201210e7070d010b2014201641cc006a2d0000470d00200d41ff0171201641cd006a2d0000460d020b2006417f6a2006712206450d020c000b0b201241244d0d02200f10290c020b201341046a2213200c6a200a71210c201520154101747141808182847871450d000b2002200036020c200241106a200141d00010e4071a41002106200b21160340200641046a22062016200a7122016a2116201120016a28000041808182847871220c450d000b02402011200c6841037620016a200a7122066a2c000022164100480d0020112011280200418081828478716841037622066a2d000021160b024020164101712201450d002000411c6a2802000d00200241e0006a20092002410c6a10b304200028021421112000280210210a410021060340200641046a2206200b200a7122166a210b201120166a28000041808182847871220c450d000b2011200c6841037620166a200a7122066a2c00004100480d002011280200418081828478716841037621060b2000200028021c20016b36021c20002802182116201120066a200541ff007122013a00002006417c6a200a7120116a41046a20013a00002016200641d0006c6a200241106a41d00010e4071a200041206a2206200628020041016a3602000b200241f0006a24000ba40604017f027e027f017e230041e0006b22022400200241d0006a20002902182001290300220342a0cbbf9599b5a19f0a7c220485200029020020048542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852000290208200342efcdddd088a580a21e7c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852000290210200342bed0fb8bf894dfa4327c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85420042adfed5e4d485fda8d800420010d5072001200241d8006a29030020022903507c2203370300024002402000280220220541244b0d00200041256a21060c010b2000412c6a2802002105200041286a28020021060b200241c0006a20032005ad220485420042adfed5e4d485fda8d800420010d5072001200442adfed5e4d485fda8d8007e20022903407c200241c0006a41086a2903007c220437030002400240024002400240200541084b0d00200541014b0d0120050d02420021030c030b0240200541104b0d00200241306a2006290000200485420042adfed5e4d485fda8d800420010d507200241386a29030020022903307c200520066a41786a2900008521030c040b200520066a41786a2900002107200421030340200629000020038542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e2004852104200641086a2106200342cf829ebbefefde82147c2103200541786a220541084b0d000b200420078521030c030b0240200541034b0d00200520066a417e6a33000042108620063300008420048521030c030b200520066a417c6a35000042208620063500008420048521030c020b200631000021030b200320048521030b200241206a2003420042adfed5e4d485fda8d800420010d5072001200241206a41086a29030020022903207c22033703000240200041cc006a3100002204500d00200241106a2003200485420042adfed5e4d485fda8d800420010d507200241106a41086a29030020022903107c200041cd006a3100008521030b20022003420042adfed5e4d485fda8d800420010d5072001200241086a29030020022903007c370300200241e0006a24000bdf0e06097f017e067f017e017f027e230041306b22032400024002400240024002400240024002402001280210220441016a22052004490d00200128020022062107024020064108490d00200641016a41037641076c21070b200520074101764d0d032005200741016a2207200520074b1b22050d01418cc5c0002108410021094104210a4100210b0c020b41b4a1c000411c41d0a1c0001033000b024002400240024020054108490d00200541ffffffff01712005470d02200541037441076e21060c010b200541016a21060b417f2006417f6a6776220b41086a2206200b41056a2205490d04200b41016a2207ad42d0007e220c422088a70d042006417c712206200ca76a22082006490d042008102722080d011030000b41b4a1c000411c41d0a1c0001033000b200b200741037641076c200b4108491b2109200841ff01200510e60720066a210a20012802002106200128021021040b2001280204220541046a210d200620056a41016a210e2005280200417f7341808182847871210f200128020821102002280200221141086a2112024003400240200f0d000340200d200e4f0d03201041c0026a2110200d2802002106200d41046a2205210d2006418081828478712206418081828478460d000b200641808182847873210f2005210d0b2003201229030022132011290300220c7c37032820032013200c852213200c4218898520134210868520134225897c3703202010200f6841037641d0006c6a2214200341206a10b2042003290328200329032085220ca72106410021050340200541046a22052006200b7122076a2106200820076a280000418081828478712202450d000b200f417f6a21050240200820026841037620076a200b7122066a2c00004100480d002008280200418081828478716841037621060b2005200f71210f200820066a200ca741197622053a00002006417c6a200b7120086a41046a20053a0000200a200641d0006c6a201441d00010e4071a0c000b0b200120043602102001200a360208200041003602002001200920046b36020c2001280204210520012008360204200128020021062001200b3602002006450d040240200641086a200641056a490d00200641016aad42d0007e422088a71a0b200510290c040b200641016a21074100210541002106024003400240024020054101710d00200620074f0d0320062105200641016a21060c010b200641036a220520064922080d022005200749220b450d022007200641046a20081b2007200b1b21060b200128020420056a220520052802002205410776417f73418182840871200541fffefdfb07726a360200410121050c000b0b20012802042106200128020041016a220541044f0d01200641046a2006200510e5071a0c020b41b4a1c000411c41d0a1c0001033000b200620056a20062800003600000b417f2106024002402001280200220541016a220a2005490d002002280200220f41086a21144100210403402004221041016a21040240201020012802046a2d0000418001470d000240034020012802082106200320142903002213200f290300220c7c37032820032013200c852213200c4218898520134210868520134225897c3703202006201041d0006c6a220d200341206a10b2042001280204210b20012802002108410021062003290328200329032085220ca7220e21050340200641046a2206200520087122076a2105200b20076a280000418081828478712202450d000b0240200b20026841037620076a20087122066a2c00004100480d00200b280200418081828478716841037621060b20062008200e7122056b201020056b732008714104490d01200b20066a22052d000021072005200ca741197622023a00002006417c6a200871200b6a41046a20023a00000240200741ff01460d002001280208200641d0006c6a2206290200210c2006200d290200370200200641186a220529020021132005200d41186a2207290200370200200641106a220529020021152005200d41106a2208290200370200200641086a220529020021162005200d41086a220b290200370200200d200c370200200b20163702002008201537020020072013370200200641386a2205290200210c2005200d41386a2207290200370200200641306a220529020021132005200d41306a2208290200370200200641286a220529020021152005200d41286a220b290200370200200629022021162006200d290220370220200d20163702202007200c37020020082013370200200b2015370200200641c8006a2205290000210c2005200d41c8006a2207290000370000200629004021132006200d290040370040200d20133700402007200c3700000c010b0b2001280204220520106a41ff013a0000200520012802002010417c6a716a41046a41ff013a00002001280208200641d0006c6a200d41d00010e4071a0c010b200b20106a200ca741197622063a000020082010417c6a71200b6a41046a20063a00000b2004200a470d000b200128020022064108490d010b200641016a41037641076c21060b200041003602002001200620012802106b36020c0b200341306a24000b13002000410d3602042000419caac4003602000b920203027f017e037f230041206b220224000240024020012802082203ad420c7e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410421060c010b200510272206450d020b200241003602082002200636020020022005410c6e360204200241002003109d012002280208210702402003450d002003410c6c210620022802002007410c6c6a21052003410274417c6a41027621030340200241106a200110f105200541086a200241106a41086a280200360200200520022903103702002005410c6a21052001410c6a2101200641746a22060d000b200720036a41016a21070b20002002290300370200200041086a2007360200200241206a24000f0b1038000b1039000b8c1a06067f017e027f037e057f057e230041e0036b2203240020012800002104200341106a41186a2001411c6a290000370300200341106a41106a200141146a290000370300200341106a41086a2001410c6a2900003703002003200129000437031020022802002105200341a0036a41186a22064200370300200341a0036a41106a22074200370300200341a0036a41086a22014200370300200342003703a00341b1dcc900ad4280808080f000841001220829000021092001200841086a290000370300200320093703a00320081029418886ca00ad4280808080c00184100122082900002109200341c0036a41086a220a200841086a290000370300200320093703c00320081029200720032903c0032209370300200341d0006a41086a220b2001290300370300200341d0006a41106a2009370300200341d0006a41186a200a290300370300200320032903a003370350200341086a200341d0006a412010fc01410021080240024002402005200328020c410020032802081b460d00200341d0006a200510c006200341c8026a41086a200341d0006a410c6a290200370300200341c8026a41106a200341d0006a41146a290200370300200341c8026a41186a200341d0006a411c6a290200370300200320032902543703c802024020032802504101470d00200341a0036a41086a2208200341c8026a41086a2903002209370300200341a0036a41106a2207200341c8026a41106a290300220c370300200341a0036a41186a2205200341c8026a41186a290300220d370300200320032903c802220e3703a003200341f4006a2802002101200341a8026a41186a220a200d370300200341a8026a41106a2206200c370300200341a8026a41086a220b20093703002003200e3703a80220012002280210460d020b200041003602402002280204210702402002410c6a2802002201450d002001410c6c21082007210103400240200141046a280200450d00200128020010290b2001410c6a2101200841746a22080d000b0b200241086a2802002201450d022001410c6c450d02200710290c020b200b4120360200200320043602502003200341106a360254200341c8026a200341d0006a10b705200341d0006a20032802c802220520032802d00210cd012001200341d9006a2900003703002007200341e1006a2900003703002006200341e9006a290000370300200320032900513703a003024020032d00504101470d00200341306a41186a200341a0036a41186a290300370300200341306a41106a200341a0036a41106a290300370300200341306a41086a200341a0036a41086a290300370300200320032903a003370330410121080b024020032802cc02450d00200510290b2002410c6a2802002101200241086a28020021052002280204210a0240024020080d002000410036024002402001450d002001410c6c2108200a210103400240200141046a280200450d00200128020010290b2001410c6a2101200841746a22080d000b0b2005450d032005410c6c0d010c030b20022802102106200341c8016a41186a2208200341306a41186a2903002209370300200341c8016a41106a2202200341306a41106a290300220c370300200341c8016a41086a2204200341306a41086a290300220d37030020032003290330220e3703c801200341d0006a41186a220b2009370300200341d0006a41106a220f200c370300200341d0006a41086a200d3703002003200e370350200341c8026a200341d0006a10a002200341e8016a41186a22102008290300370300200341e8016a41106a22082002290300370300200341e8016a41086a2004290300370300200320032903c8013703e801024020032802e80222110d002000410036024002402001450d002001410c6c2108200a210103400240200141046a280200450d00200128020010290b2001410c6a2101200841746a22080d000b0b2005450d032005410c6c0d010c030b20034188026a41186a201029030037030020034188026a41106a200829030037030020034188026a41086a200341e8016a41086a290300370300200320032903e80137038802200341a8026a41186a200341c8026a41186a290300370300200341a8026a41106a200341c8026a41106a290300370300200341a8026a41086a200341c8026a41086a290300370300200320032903c8023703a802200341f0026a290300210c20032802ec022104200341a0036a41186a22104200370300200341a0036a41106a22124200370300200341a0036a41086a22084200370300200342003703a00341b1dcc900ad4280808080f000841001220229000021092008200241086a290000370300200320093703a0032002102941b8dcc900ad4280808080a00184100122022900002109200341c0036a41086a2213200241086a290000370300200320093703c00320021029200720032903c003370000200741086a2013290300370000200341d0006a41086a2008290300370300200f2012290300370300200b2010290300370300200320032903a003370350200341d0036a200341d0006a108d020240024020032802d00322020d00410021080c010b20032902d4032209422088a72108200942ffffff3f83500d00200210290b024020082006470d0020002003290388022209370300200041206a20032903a802220d370300200341d0006a41186a20034188026a41186a290300220e370300200341d0006a41106a20034188026a41106a2903002214370300200341d0006a41086a20034188026a41086a2903002215370300200341d0006a41286a200341a8026a41086a2903002216370300200341d0006a41306a200341a8026a41106a2903002217370300200341d0006a41386a200341a8026a41186a2903002218370300200041086a2015370300200041106a2014370300200041186a200e370300200041286a2016370300200041306a2017370300200041386a2018370300200320093703502003200d370370200041c8006a200c370300200020043602442000201136024002402001450d002001410c6c2108200a210103400240200141046a280200450d00200128020010290b2001410c6a2101200841746a22080d000b0b2005450d032005410c6c0d010c030b2000410036024002402004450d00200441306c450d00201110290b02402001450d002001410c6c2108200a210103400240200141046a280200450d00200128020010290b2001410c6a2101200841746a22080d000b0b2005450d022005410c6c450d020b200a10290c010b2005200a290300370300200720062903003703002008200b290300370300200320032903a8023703a0032002410c6a280200210a200228020421060240410110272208450d00200841003a000041004100350280804042adfed5e4d485fda8d8007e200341d0006aad7c421f8922093e02808040200341c8026a41206a4100360200200341c8026a41186a4204370300200341dc026a418cc5c000360200200341003602d8022003418080c000ad3703c802200320093703d002200341d0006a41186a220741b4e0c800ad428080808010841010220141186a290000370300200341d0006a41106a2205200141106a290000370300200341d0006a41086a220b200141086a2900003703002003200129000037035020011029200341f4026a42818080801037020020034194036a20072903003702002003418c036a200529030037020020034184036a200b290300370200200320083602f002200320032903503702fc020240200a450d002006200a410c6c6a210841002802b0a140210741002902a8a140210920062101034020034188026a41086a20073602002003200937038802200341d0006a200341c8026a20034188026a2001280200200141086a28020010c1062001410c6a22012008470d000b0b200341d0006a200341c8026a41d80010e4071a200341c0016a200341a0036a41186a290300370300200341b8016a200341a0036a41106a290300370300200341b0016a200341a0036a41086a290300370300200320032903a0033703a8012000200341d0006a2004200341106a412010c206024020032802602207450d00200341e4006a280200220841046a2101200720086a41016a21002008280200417f73418081828478712105200341e8006a280200210802400340024002402005450d00200521070c010b0340200120004f0d03200841c0016a210820012802002107200141046a220521012007418081828478712207418081828478460d000b2007418081828478732107200521010b2007417f6a2007712105200820076841037641306c6a220741246a280200450d00200728022010290c000b0b02402003280260220141086a200141056a490d00200141016aad42307e422088a71a0b200328026410290b0240200341fc006a280200450d00200328027810290b0240200a450d00200a410c6c21082006210103400240200141046a280200450d00200128020010290b2001410c6a2101200841746a22080d000b0b200241086a2802002201450d012001410c6c450d01200610290c010b1039000b200341e0036a24000bd90301037f230041106b220224000240024020002802082203280200220441024b0d0002400240024020040e03000102000b200241003a00082001200241086a41011072412010272204450d03200441186a200341206a290000370000200441106a200341186a290000370000200441086a200341106a2900003700002004200341086a290000370000200120044120107220041029200220032802043602082001200241086a410410720c020b200241013a00082001200241086a41011072412010272204450d02200441186a200341206a290000370000200441106a200341186a290000370000200441086a200341106a2900003700002004200341086a290000370000200120044120107220041029200220032802043602082001200241086a410410720c010b200241023a00082001200241086a41011072412010272204450d01200441186a200341206a290000370000200441106a200341186a290000370000200441086a200341106a2900003700002004200341086a290000370000200120044120107220041029200220032802043602082001200241086a410410720b200220002903003703082001200241086a41081072200220002903103703082001200241086a41081072200241106a24000f0b1039000bf90403027f017e067f230041d0006b2202240041fce2c800ad4280808080f00184100122032900002104200241086a200341086a290000370300200220043703002003102941c4f4c800ad4280808080c00184100122032900002104200241106a41086a200341086a2900003703002002200437031020031029200220013703302002200241306aad42808080808001841002220329000037033820031029200241cc006a200241306a41086a3602002002200241386a41086a3602442002200241306a3602482002200241386a360240200241206a200241c0006a107502400240024002402002280228220541206a2206417f4c0d00200228022021070240024020060d0041002108410121030c010b200610272203450d02200621080b024002402008410f4d0d00200821090c010b200841017422094110200941104b1b22094100480d03024020080d002009102722030d010c050b20082009460d00200320082009102b2203450d040b20032002290300370000200341086a200241086a2903003700000240024020094170714110460d00200921080c010b200941017422084120200841204b1b22084100480d0320092008460d00200320092008102b2203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821090c010b200541206a22092005490d032008410174220a2009200a20094b1b22094100480d0320082009460d00200320082009102b2203450d040b200341206a2007200510e4071a20002006360208200020093602042000200336020002402002280224450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bfc0403027f017e057f230041d0006b2202240041d482cc00ad4280808080d00084100122032900002104200241086a41086a200341086a29000037030020022004370308200310294185b2c400ad4280808080f00084100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bba0e05037f017e0d7f017e017f230041b0016b22022400200241106a200110c80102400240024002402002280210450d00200041003602000c010b20022802142203200128020441246e2204200420034b1bad42247e2205422088a70d022005a72204417f4c0d020240024020040d00410421060c010b200410272206450d020b4100210720024100360220200220063602182002200441246e36021c02402003450d0020024188016a41046a2108200241f5006a210920024188016a410772210a2002419b016a220b41056a210c4100210d0340024002400240024002402001280204220e450d002001280200220f2d000021042001200e417f6a22103602042001200f41016a360200200441074b0d00024002400240024002400240024020040e080007010703040205000b200241086a200110c80120022802080d062001280204200228020c220e490d06200e417f4c0d0f0240200e0d00410121044101450d07410021110c090b200e102d2204450d0e2001280204200e490d0520042001280200200e10e40721112001280204220f200e490d072001200f200e6b36020420012001280200200e6a3602002011450d06200e21110c080b41002104200241003a00a801200e417e6a210e0240034020102004460d0120024188016a20046a200f20046a221141016a2d00003a00002001200e3602042001201141026a3602002002200441016a22113a00a801200e417f6a210e2011210420114120470d000b200241f8006a41086a200a41086a2800003602002002200a2900003703782002200b2900003703682002200c29000037006d20022f018801210e20022d008a012111200228008b012104200941026a20024185016a41026a2d00003a0000200920022f0085013b000020044108762112200e201141107472210e410021110c0a0b200441ff0171450d05200241003a00a8010c050b20024188016a200110ed05200228028c012211450d0420022f01880120022d008a0141107472210e20022d008b012104200220022903900137027c20022011360278410121110c080b20024188016a200110ed05200228028c012211450d0320022f01880120022d008a0141107472210e20022d008b012104200220022903900137027c20022011360278410221110c070b20024188016a200110ed05200228028c012211450d0220022f01880120022d008a0141107472210e20022d008b012104200220022903900137027c20022011360278410321110c060b2010450d01200f2d000121042001200e417e6a22113602042001200f41026a36020020040d012011450d01200f2d000221112001200e417d6a22103602042001200f41036a360200201141014b0d014100210442002113420021050240024020110e020100010b20104104490d02200f35000321052001200e41796a22043602042001200f41076a36020020044104490d02200f35000721132001200e41756a3602042001200f410b6a36020020134220862113410121040b200241e8006a41086a200841086a290200370300200220022802880136028001200220052013843703782002200829020037036841042111410021120c040b200410290b200241d8006a41086a200241f8006a41086a280200360200200241c8006a41086a200241e8006a41086a29030037030020022002290378370358200220022903683703482000410036020002402007450d00200741246c21042006210103400240024020012d0000220e41044b0d00024002400240200e0e050400010204040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012004415c6a22040d000b0b200228021c2201450d06200141246c450d06200610290c060b200e200f41ccafc000104c000b200241e8006a41086a200841086a2902003703002002200e36027c200220113602782002200228028801360280012002200829020037036820044108762112410521110b0b200d41016a210d200241d8006a41086a200241f8006a41086a280200220f360200200241c8006a41086a200241e8006a41086a2903002205370300200241386a41086a2210200f360200200241286a41086a220f200537030020022002290378220537035820022002290368221337034820022005370338200220133703282012410874200441ff017172211402402007200228021c470d00200241186a2007410110960120022802182106200228022021070b2006200741246c6a220420143600042004200e3b0001200420113a0000200441036a200e4110763a0000200441106a201028020036000020042002290338370008200420022903283700142004411c6a200f2903003700002002200741016a2207360220200d2003470d000b0b20002002290318370200200041086a200241186a41086a2802003602000b200241b0016a24000f0b1039000b1038000b98ac0114057f017e057f017e037f027e087f037e017f017e057f027e0d7f017e017f017e027f037e017f017e230022012102200141c0176b41607122012400200141e0086a41186a4200370300200141e0086a41106a22034200370300200141e0086a41086a22044200370300200142003703e00841d482cc00ad4280808080d00084100122052900002106200141c80d6a41086a2207200541086a290000370300200120063703c80d2005102920042007290300370300200120012903c80d3703e00841fab1c400ad4280808080b001841001220529000021062007200541086a290000370300200120063703c80d20051029200320012903c80d2206370300200141a80d6a41086a2004290300370300200141a80d6a41106a2006370300200141a80d6a41186a2007290300370300200120012903e0083703a80d200141d80d6a200141a80d6a412010f901200041a08d066e210802400240024002400240024020012802d80d4101470d0020012902dc0d2206422088a741e8076a2000470d00200141d80d6a4180a6cc00410010940320014188176a20012802d80d41e8077010b904200141d80d6a200128028817220420012802901710bc0420012802d80d210720014188126a200141d80d6a41047241ac0410e4071a0240024020074103460d00200141e0086a20014188126a41ac0410e4071a0240200128028c17450d00200410290b200120073602b004200141b0046a410472200141e0086a41ac0410e4071a0c010b0240200128028c17450d00200410290b200141023602a808200141023602f007200141023602b8072001410236028007200141023602c8062001410236029006200141023602d805200141023602a005200141023602e804200141023602b0040b2006a72109410021070340200141d80d6a200710b90420013502e00d42208620012802d80d2204ad841004024020012802dc0d450d00200410290b200741016a220741e807470d000b200141e0086a41186a220a4200370300200141e0086a41106a220b4200370300200141e0086a41086a22044200370300200142003703e00841d482cc00ad4280808080d00084100122052900002106200141c80d6a41086a2207200541086a290000370300200120063703c80d2005102920042007290300370300200120012903c80d3703e00841fab1c400ad4280808080b001841001220529000021062007200541086a290000370300200120063703c80d20051029200320012903c80d370000200341086a2007290300370000200141a80d6a41086a2004290300370300200141a80d6a41106a200b290300370300200141a80d6a41186a200a290300370300200120012903e0083703a80d200141a80d6aad4280808080800484220c100420012802b004210720014188126a200141b0046a41047241ac0410e4071a20074103460d00200120073602d80d200141d80d6a41047220014188126a41ac0410e4071a20014188126a210a200141b9046a210d200141d80d6a210720014198046a41106a210e0340024002400240200a2007460d0020072802002104200741386a2205210720044102460d03200141b0046a200541486a220f10bd0420014198046a20012802b004220720012802b804220410e301200e290300210620012903a0042110024020012903980422114201520d002004ad4220862007ad8410040b2011a72104024020012802b404450d00200710290b2005210720044101470d03200f2802004101470d0120014188176a2005414c6a10cc030c020b200141b0046a200141d80d6a41b00410e4071a200141d8096a4200370300200141d0096a4200370300200141b8096a4200370300200141b0096a4200370300200141e0086a41386a4200370300200141e0086a41306a4200370300200141e0086a41186a4200370300200141c8096a4100360200200141a8096a4100360200200141e0086a41286a4100360200200142003703f008200142013703c009200142013703a0092001420137038009200141003602e808200142013703e00841002104024003400240200141b0046a200441386c6a22072802004102460d0020014188046a200741286a290300200741306a2903002004410873410f71410274419482cc006a350200420010d507410110272205450d0920014188046a41086a29030021062001290388042110200520043a0000200141e0086a20044105746a2207410472210a02402007280204450d00200728020010290b200a4101360200200720053602002007201037031020074101360208200741186a20063703000b02402004450d00200141e0086a20044105746a221241086a211320124104722114201241106a210a41002105200141e0086a21070340024020042005220b41016a22056b220d20044d0d00411b2107418ba6c70021040c0d0b0240200b41024d0d004115210741bca6c70021040c0d0b024002400240024002400240200b0e03000102000b200d4103490d030c100b200d41014b0d0f4107210e200d0e020301030b4109210e200d0d0e0c020b4108210e0c010b200d41046a210e0b02400240200141b0046a200e41ff017141386c6a220b2802004102460d00200141f8036a200b41286a290300200b41306a290300200e410873410f71410274419482cc006a350200420010d507200741106a290300221020012903f8037c2206200a29030058200741186a290300200141f8036a41086a2903007c2006201054ad7c2210200a41086a29030022115820102011511b0d01200741086a280200220b417f4c0d052007280200211502400240200b0d00410021164101210d0c010b200b1027220d450d0b200b21160b024002402016200b490d002016210f0c010b2016410174220f200b200f200b4b1b220f4100480d0c024020160d00200f1027220d0d010c0e0b2016200f460d00200d2016200f102b220d450d0d0b200d2015200b10e40721160240200b200f470d00200b41016a220f200b490d0c200b4101742215200f2015200f4b1b220f4100480d0c0240200b0d00200f1027220d450d0e0c010b200b200f460d002016200b200f102b220d450d0d0b200d200b6a200e3a0000200b41016a210b02402014280200450d00201228020010290b200a20063703002014200f3602002012200d3602002013200b360200200a20103703080c010b200741106a220d290300200a29030058200741186a220f2903002206200a41086a29030022105820062010511b0d00200741086a280200220b417f4c0d042007280200211702400240200b0d004100210e410121150c010b200b10272215450d0a200b210e0b02400240200e200b490d00200e21160c010b200e4101742216200b2016200b4b1b22164100480d0b0240200e0d00201610272215450d0d0c010b200e2016460d002015200e2016102b2215450d0c0b20152017200b10e407210e200f2903002106200d290300211002402014280200450d00201228020010290b200a2010370300201420163602002012200e3602002013200b360200200a20063703080b200741206a210720042005470d000b0b200441016a22044104470d000b20012802c809210f20012802c409211520012802c0092112024020012802e408450d0020012802e00810290b0240200128028409450d0020012802800910290b024020012802a409450d0020012802a00910290b024002400240200f0d004100211841082119410021050c010b200f41ffffff1f71200f470d08200f41067422074100480d08200710272219450d0920074106762118200141e0086a410872210a41002105201921070340201220056a2d0000220b410a460d01200142013703e008200141b0046a200b41386c6a2204280200220e4102460d0241002004200e4102461b22042903102110200420012903f00837031020042903082111200420012903e80837030820042903002106200420012903e0083703002004290328211a20044200370328200441186a220e290300211b200e20012903f808370300200441306a220e290300211c200e4200370300200120103703f008200120113703e808200120063703e0082001201b3703f8082004290320211020014188176a41106a2214200a41106a29020037030020014188176a41086a2216200a41086a2902003703002001200a29020037038817410021042006422088a7220d210e02402006a70d0010be04210e200141e0166a41106a2014290300370300200141e0166a41086a201629030037030020012001290388173703e016410121040b2007201c3703082007201a370300200741146a200d360200200741106a2004360200200141e0166a41106a2903002106200141e0166a41086a290300211120012903e016211a2007413c6a200b3a0000200741186a201a370300200741206a2011370300200741286a2006370300200741386a200e360200200741306a20103703002007413d6a20012f00b8163b00002007413f6a200141b8166a41026a2d00003a0000200741c0006a2107200f200541016a2205470d000b0b02402015450d00201210290b200141e0086a41186a22174200370300200141e0086a41106a221d4200370300200141e0086a41086a22154200370300200142003703e00841d482cc00ad4280808080d00084221e100122072900002106200141c80d6a41086a221f200741086a290000370300200120063703c80d200710292015201f290300370300200120012903c80d3703e00841d982cc00ad4280808080e00184100122072900002106201f200741086a290000370300200120063703c80d20071029200320012903c80d370000200341086a2220201f290300370000200141a80d6a41086a22122015290300370300200141a80d6a41106a2221201d290300370300200141a80d6a41186a22222017290300370300200120012903e0083703a80d200141f0036a200141a80d6a412010fc01200141bc046a20012802f403410020012802f0031b360200200141b0046a41086a220f41023a00002001410f3a00b004200141b0046a10cb0102402005450d00201920054106746a2123200141b0046aad42808080808002842124200141e0086aad42808080808004842125200920086b222620094b2127200141b9046a2128200141b0046a41106a210d20014188176a4104722113200141b0046a4105722129200141b0046a41036a212a200141b0046a41186a2116200141b0046a41206a212b200141b0046a41286a212c200141e8046a212d201921050340200541086a29030021062005290300211020052802102104200d200541246a29020037030020162005412c6a290200370300202b200541346a280200360200200f2005411c6a2902003703002001200541146a2902003703b00420044102460d01200141b8166a41086a200f2903002211370300200141b8166a41106a200d290300221a370300200141b8166a41186a2016290300221b370300200141b8166a41206a202b280200220a360200200120012903b004221c3703b81620052d003c212e20052802382107200141e0166a41206a220b200a360200200141e0166a41186a220a201b370300200141e0166a41106a220e201a370300200141e0166a41086a221420113703002001201c3703e016200120073602841702400240024002400240024002400240024020040d00200141c8036a200710bf04201020012903c80322117d221a2010562006200141c8036a41086a2903007d2010201154ad7d221120065620112006511b450d014200211a420021110c020b20014188176a41206a222f200b28020036020020014188176a41186a2230200a29030037030020014188176a41106a2231200e29030037030020014188176a41086a22322014290300370300200120012903e01637038817200141013a00bf17200141083a00be17200120133602b017200120103703a80d200120063703b00d02400240201020068450450d004200211141002107420021330c010b200120133602c80d2001200141c80d6a3602c0042001200141be176a3602bc042001200141b0176a3602b8042001200141bf176a3602b4042001200141a80d6a3602b004200141e0086a2013200141b0046a10c802024020012802e0084101470d0020012903e8082111410121070c010b200141e0086a41286a290300213320012903800921114100210720012903e8084201520d0020012903f008211a20012802c80d2107202d201729030037030020282007290000370000202841086a200741086a290000370000202841106a200741106a290000370000202841186a200741186a2900003700002001201a3703e00441002107200141003a00b804200141033a00b004200141b0046a10cb010b20070d0720164200370300200d4200370300200f4200370300200142003703b00441dcbec500ad4280808080800184221a10012207290000211b2012200741086a2900003703002001201b3703a80d20071029200f2012290300370300200120012903a80d3703b004419fe3c200ad4280808080d00184221b10012207290000211c2012200741086a2900003703002001201c3703a80d20071029200d20012903a80d370000200d41086a223420122903003700002015200f290300370300201d200d29030037030020172016290300370300200120012903b0043703e008200141d8036a200141e0086a412010e301200141d8036a41106a290300211c20012903e003213520012802d803210720164200370300200d4200370300200f4200370300200142003703b004201a10012204290000211a2012200441086a2900003703002001201a3703a80d20041029200f2012290300370300200120012903a80d3703b004201b10012204290000211a2012200441086a2900003703002001201a3703a80d20041029200d20012903a80d370000203420122903003700002015200f290300370300201d200d29030037030020172016290300370300200120012903b0043703e00820014200201c420020071b221a20337d2035420020071b221b201154ad7d221c201b20117d2211201b56201c201a56201c201a511b22071b3703b80420014200201120071b3703b00420252024100320174200370300201d420037030020154200370300200142003703e008201e100122072900002111201f200741086a290000370300200120113703c80d200710292015201f290300370300200120012903c80d3703e00841e782cc00ad4280808080a00184221a100122072900002111201f200741086a290000370300200120113703c80d20071029200320012903c80d3700002020201f290300370000201220152903003703002021201d29030037030020222017290300370300200120012903e0083703a80d200141b0046a200141a80d6a412010c004024020012802b00422140d0041002136200141003602b817200142043703b017410421140c040b20012902b4042111200120143602b017200120113702b4172011a7213602402011422088a7223741014b0d00024020370e020500050b4100210420012802841721070c030b4100210420012802841721072037210a03402004200a410176220b20046a220e20072014200e4102746a280200491b2104200a200b6b220a41014b0d000c030b0b20014188176a20014184176a10cc03200141013a00bf17200141083a00be172001201a3703a80d200120113703b00d200120014188176a3602b01702400240201a20118450450d004200211b41002104420021380c010b200120014188176a3602c80d2001200141c80d6a3602c0042001200141be176a3602bc042001200141b0176a3602b8042001200141bf176a3602b4042001200141a80d6a3602b004200141e0086a20014188176a200141b0046a10c802024020012802e0084101470d0020012903e808211b410121040c010b200141e0086a41286a2903002138200129038009211b4100210420012903e8084201520d0020012903f008211c20012802c80d2104202d201729030037030020282004290000370000202841086a200441086a290000370000202841106a200441106a290000370000202841186a200441186a2900003700002001201c3703e00441002104200141003a00b804200141033a00b004200141b0046a10cb010b20040d0620164200370300200d4200370300200f4200370300200142003703b00441dcbec500ad4280808080800184221c1001220429000021352012200441086a290000370300200120353703a80d20041029200f2012290300370300200120012903a80d3703b004419fe3c200ad4280808080d0018422351001220429000021392012200441086a290000370300200120393703a80d20041029200d20012903a80d370000200d41086a220b20122903003700002015200f290300370300201d200d29030037030020172016290300370300200120012903b0043703e008200141b0036a200141e0086a412010e301200141b0036a41106a290300213920012903b803213a20012802b003210420164200370300200d4200370300200f4200370300200142003703b004201c1001220a290000211c2012200a41086a2900003703002001201c3703a80d200a1029200f2012290300370300200120012903a80d3703b00420351001220a290000211c2012200a41086a2900003703002001201c3703a80d200a1029200d20012903a80d370000200b20122903003700002015200f290300370300201d200d29030037030020172016290300370300200120012903b0043703e008200142002039420020041b221c20387d203a420020041b2235201b54ad7d22392035201b7d221b2035562039201c562039201c511b22041b3703b80420014200201b20041b3703b0042025202410030b202c200637030020162011370300200120103703d0042001201a3703c004200120073602bc042001202e3a00b904200141043a00b8042001410f3a00b004200141b0046a10cb010c040b2007201420044102746a280200220a460d0220042007200a4b6a220420374d0d01200420371041000b410021372001280284172107410021040b024020372036470d00200141b0176a2036410110980120012802b417213620012802b01721140b201420044102746a220a41046a200a203720046b41027410e5071a200a20073602002001203741016a22373602b8170b20174200370300201d420037030020154200370300200142003703e008201e100122042900002111201f200441086a290000370300200120113703c80d200410292015201f290300370300200120012903c80d3703e008201a100122042900002111201f200441086a290000370300200120113703c80d20041029200320012903c80d3700002020201f290300370000201220152903003703002021201d29030037030020222017290300370300200120012903e0083703a80d0240024020140d00200c10040c010b200141203602b4042001200141a80d6a3602b00420142037200141b0046a10ef03203641ffffffff0371450d00201410290b2001280288172104200141b0046a41c0006a2006370300200d20132900003700002034201341086a220e290000370000200d41106a201341106a2214290000370000200d41186a201341186a2237290000370000200120103703e804200120043602bc0441032104200141033a00b804200120073602e0042001410f3a00b0042001202e3a00b904200141b0046a10cb010240024002400240202e410f710e0a00000000010101020203000b410021040c020b410121040c010b410221040b200141a80d6a200420096a223610c104200141b0046a20012802a80d220a20012802b00d223410c0040240024002400240024020012802b00422040d004100210b200141003602e808200142043703e0080c010b200120012902b40422113702e408200120043602e0082011422088a7220b2011a7223b460d002004200b4102746a20073602002001200b41016a220b3602e8080c010b200141e0086a200b410110980120012802e008220420012802e808220b4102746a20073602002001200b41016a220b3602e8082004450d0120012802e408213b0b200120343602b4042001200a3602b0042004200b200141b0046a10ef03203b41ffffffff0371450d01200410290c010b2034ad422086200aad8410040b024020012802ac0d450d00200a10290b200141b0046a200710c20420013502b804211120012802b004210a412010272204450d0a20042013290000370000200441186a2037290000370000200441106a2014290000370000200441086a200e2900003700002011422086200aad842004ad4280808080800484100320041029024020012802b404450d00200a10290b202a41206a202f280200360000202a41186a2030290300370000202a41106a2031290300370000202a41086a2032290300370000202a2001290388173700002015200f290000370300201d200d29000037030020172016290000370300200141e0086a411f6a2204200141b0046a411f6a290000370000200120012900b0043703e008200141003a00b404200120363602b004202920012903e008370000202941086a2015290300370000202941106a201d290300370000202941186a20172903003700002029411f6a2004290000370000200141c80d6a200710c30420013502d00d211120012802c80d210441041027220a450d0a200142043702ac0d2001200a3602a80d200141b0046a200141a80d6a10c40420012802ac0d210a20114220862004ad8420013502b00d42208620012802a80d220bad8410030240200a450d00200b10290b20012802cc0d450d00200410290b20270d0041032104410321140240024002400240024002400240024002400240202e410f710e0a00010203040506070809000b41002104410021140c080b41002114410121040c070b41002114410221040c060b410021140c050b41012104410121140c040b41012114410221040c030b410121140c020b410221040b410221140b20014188176a200710c504200141b0046a200128028817222e200128029017223710c604202620146a21070240024020012802b004220e0d004100210b200141003602e808200142083703e0084108210e0c010b200120012902b40422113702e4082001200e3602e0082011422088a7210b0b202620046a210a024002402007200b4b0d00200b21040c010b200141e0086a200b2007200b6b223010920120012802e008220e20012802e80822044104746a212f02400240024020304102490d00202f41002007200b417f736a223041047410e6071a200e200420096a20146a2008200b6a6b4104746a41706a212f203020046a21040c010b2030450d010b202f4200370308202f4200370300200441016a21040b200120043602e8080b02402007200a4b0d000340024002400240200420074b0d0020042007470d010240200420012802e408470d00200141e0086a2004410110920120012802e008210e20012802e80821040b200e20044104746a220b2006370308200b20103703002001200441016a22043602e8080c020b200e20074104746a220b200b290300221120102011201056200b41086a220b290300221120065620112006511b22141b370300200b2011200620141b3703000c010b200141c4046a4101360200200142013702b40420014198e3ca003602b004200141043602ac0d200141d8b2c4003602a80d2001200141a80d6a3602c004200141b0046a4180a6cc001040000b2007200a4f210b20072007200a496a2207200a4d200b410173710d000b0b20012802e4082107200120373602b4042001202e3602b004200e2004200141b0046a10a2040240200741ffffffff0071450d00200e10290b200128028c17450d00202e10290b200541c0006a22052023470d000b0b2018450d05201910290c050b419ee2ca00413341d4e2ca001057000b1038000b20014188176a41186a200541506a220741186a29000037030020014188176a41106a200741106a29000037030020014188176a41086a200741086a29000037030020012007290000370388170b200120103703e016200120063703e81602402010200684500d00200120014188176a3602b816200141e0086a20014188176a200141e0166a200141b8166a10ea0320012903e0084201520d0020012903e8082106200141b0046a41386a200b290300370300200d200129038817370000200d41086a20014188176a41086a290300370000200d41106a20014188176a41106a290300370000200d41186a20014188176a41186a290300370000200120063703e004200141003a00b804200141033a00b004200141b0046a10cb010b200521070c000b0b0240200841e0f2796c410020006b470d00200141e40d6a2008360200200141d80d6a41086a41003a00002001410f3a00d80d200141d80d6a10cb01200141e0086a41186a220a4200370300200141e0086a41106a220b4200370300200141e0086a41086a22044200370300200142003703e00841d482cc00ad4280808080d00084100122052900002106200141c80d6a41086a2207200541086a290000370300200120063703c80d2005102920042007290300370300200120012903c80d3703e00841e782cc00ad4280808080a001841001220529000021062007200541086a290000370300200120063703c80d20051029200320012903c80d370000200341086a2007290300370000200141a80d6a41086a2004290300370300200141a80d6a41106a200b290300370300200141a80d6a41186a200a290300370300200120012903e0083703a80d200141d80d6a200141a80d6a412010c00420012802d80d2207410420071b220e20012902dc0d420020071b2206422088a741027422046a2105200e21070240024003402004450d0120012007280200220a3602b0042004417c6a2104200741046a2107200141b0046a10c704450d000b41041027220b450d03200b200a36020020014281808080103702dc0d2001200b3602d80d4101210a0240034020052007460d012001200728020022043602b004200741046a2107200141b0046a10c704450d000240200a20012802dc0d470d00200141d80d6a200a410110980120012802d80d210b0b200b200a4102746a20043602002001200a41016a220a3602e00d0c000b0b20012802dc0d210f0c010b4104210b4100210a4100210f0b0240200642ffffffff0383500d00200e10290b200141e0086a41186a220e4200370300200141e0086a41106a220d4200370300200141e0086a41086a22044200370300200142003703e00841d482cc00ad4280808080d00084100122052900002106200141c80d6a41086a2207200541086a290000370300200120063703c80d2005102920042007290300370300200120012903c80d3703e00841e782cc00ad4280808080a001841001220529000021062007200541086a290000370300200120063703c80d20051029200320012903c80d370000200341086a2007290300370000200141a80d6a41086a2004290300370300200141a80d6a41106a200d290300370300200141a80d6a41186a200e290300370300200120012903e0083703a80d02400240200b0d00200141a80d6aad428080808080048410040c010b200141203602dc0d2001200141a80d6a3602d80d200b200a200141d80d6a10ef03200f41ffffffff0371450d00200b10290b200141b0046a200810c104200141d80d6a20012802b004220720012802b804220410c0040240024020012802d80d22080d0042002106410421080c010b2004ad4220862007ad84100420012902dc0d21060b024020012802b404450d00200710290b02402006422088a72207450d0020074102742105200821070340200141b0046a2007280200220a10c304200141d80d6a20012802b004220b20012802b80410c804024020012d00dc0d2204410346220d0d0020012802840e210320012802880e211720012802e00d211620012802e40d210f20012802e80d211320012802ec0d211220012802f00d211420012802f40d21150b024020012802b404450d00200b10290b4101210e024002402004410371417e6a220b41014b0d000240200b0e020002000b200120133602b8042001200f3602b404200120163602b004200120153602e00d200120143602dc0d200120123602d80d20014188126a200a4100200141b0046a200141d80d6a10c904200141d80d6a200a10c30420013502e00d42208620012802d80d220aad841004024020012802dc0d450d00200a10290b4100210e200d0d010b0240200441024b0d000240024020040e03030100030b200e450d020240200f450d00201610290b2014450d02201210290c020b2017450d01200310290c010b0240200f450d00201610290b2014450d00201210290b200741046a21072005417c6a22050d000b0b200642ffffffff0383500d00200810290b4200213a200141d80d6a41186a220a4200370300200141d80d6a41106a222e4200370300200141d80d6a41086a22044200370300200142003703d80d41cd87cc00ad4280808080a00184221010012205290000210620014188126a41086a2207200541086a2900003703002001200637038812200510292004200729030037030020012001290388123703d80d41ac84cc00ad42808080809001841001220529000021062007200541086a290000370300200120063703881220051029202e2001290388122206370300200141b0046a41086a22052004290300370300200141b0046a41106a220b2006370300200141b0046a41186a220e2007290300370300200120012903d80d3703b004200141b0046aad22334280808080800484221110040240024002400240024020004181ce18490d00200a4200370300202e420037030020044200370300200142003703d80d20101001220a29000021062004200a41086a290000370300200120063703d80d200a102941b8bcc700ad4280808080f001841001220a29000021062007200a41086a2900003703002001200637038812200a1029202e200129038812220637030020052004290300370300200b2006370300200e2007290300370300200120012903d80d3703b004200141d80d6a200141b0046a10ca04200041ffb1676a210e20012802d80d2207410420071b21370240024020012902dc0d420020071b2206422088a722290d004100211d0c010b203741046a2107202941037441786a41037641016a21044100211d024003402007280200200e4b0d01200741086a21072004201d41016a221d470d000b0b201d20294b0d020b0240201d4103742207450d00203720076a212b203721160340200141b0046a2016280200220d10cb04200141d80d6a20012802b004221520012802b804220810cc040240024020012802e40d22144102470d0041002117410421124104211f4100210f41042113410021140c010b20012802e80d210320012802dc0d211720012802e00d210f20012802d80d2212211f201221130b201641086a2116200f410274210a4101210520132107024002400340200a2204450d012005417f6a21052004417c6a210a2007280200210b200741046a2107200b200e4b0d000b0240200f200b200e4d220741016a410171220a20056b220b490d002013200b4102746a28020021030240200a200f6b2005470d0041002107410121140c030b201f200f4102746a417c6a2107200a410274210503402001200728020036028c122001200d36028812200141d80d6a20014188126a10cd0420013502e00d42208620012802d80d220aad841004024020012802dc0d450d00200a10290b2007417c6a21072004200541046a2205470d000b41012114200b210f0c010b200741016a41017120056b200f1043000b41002107200f0d00200141d80d6a200d10ce04024020012802d80d22040d00410121070c010b4100210720012802dc0d450d00200410290b200120033602e80d2001200f3602e00d200120173602dc0d200120123602d80d200120143602e40d0240024020144102470d002008ad4220862015ad8410040c010b2001200836028c122001201536028812200141d80d6a20014188126a10cf0420144102460d00201741ffffffff0371450d00201210290b024020012802b404450d00201510290b02402007450d00200141d80d6a200d10cb0420013502e00d42208620012802d80d2207ad84100420012802dc0d450d00200710290b2016202b470d000b0b200642ffffffff0f83210602402029201d6b2207450d000240201d450d0020372037201d4103746a200741037410e5071a0b2007ad42208620068421060b200141d80d6a41186a220a4200370300200141d80d6a41106a220b4200370300200141d80d6a41086a22044200370300200142003703d80d41cd87cc00ad4280808080a0018410012205290000211020014188126a41086a2207200541086a2900003703002001201037038812200510292004200729030037030020012001290388123703d80d41b8bcc700ad4280808080f001841001220529000021102007200541086a290000370300200120103703881220051029202e200129038812370000202e41086a2007290300370000200141b0046a41086a2004290300370300200141b0046a41106a200b290300370300200141b0046a41186a200a290300370300200120012903d80d3703b004024020370d00201110040c010b200141203602dc0d2001200141b0046a3602d80d20372006422088a7200141d80d6a10f103200642ffffffff0183500d00203710290b200041808c15700d03200142f0f2bda1a7ee9cb9f9003703d80d200141b0046a200141d80d6a10820220014188126a200141b0046a10a802200141d80d6a200128028812220420012802901210a902200141d80d6a41106a2203290300420020012903d80d42015122071b211020012903e00d420020071b21060240200128028c12450d00200410290b20014200201020064280c8afa02554ad7d221120064280b8d0df5a7c221a2006562011201056200642ffc7afa025561b22071b22063703c01620014200201a20071b22103703b816200141d80d6a41186a2208200637030020032010370300200141d80d6a41086a220f41013a00002001410e3a00d80d200141d80d6a10cb01200141003a008417200142003703e816200142003703e0162008420037030020034200370300200f4200370300200142003703d80d4197dec900ad4280808080800184222410012207290000210620014188126a41086a2215200741086a290000370300200120063703881220071029200f201529030037030020012001290388123703d80d4184baca00ad428080808090018422251001220729000021062015200741086a29000037030020012006370388122007102920032001290388122206370300200141b0046a41086a2216200f290300370300200141b0046a41106a2006370300200141b0046a41186a22172015290300370300200120012903d80d3703b004200141d80d6a200141b0046a108f0320012802d80d2207410420071b211f20012902dc0d420020071b2235422088221ea72214450d02200141e10d6a210b200141f0046a210e200141d0046a2112200141900e6a211320014188096a211d201f210741002104410021050340200141e0086a2007280200220d10d004200141d80d6a20012802e008220a20012802e80810d10420012903d80d2110200141b0046a200f41e00010e4071a42002106024020104201520d0020014188126a200141b0046a41e00010e4071a420121060b024020012802e408450d00200a10290b024002400240200650450d00200441016a21040c010b200141b0046a20014188126a41e00010e4071a024020012903b816221120012903b004221a54220a200141b8166a41086a2903002206201629030022105420062010511b0d0020012011201a7d3703b8162001200620107d200aad7d3703c016200141d80d6a200d10d00420013502e00d42208620012802d80d220aad841004024020012802dc0d450d00200a10290b20012903c004210620012017290300221037039017200120063703881702402006201084500d00200120123602a80d200141e0086a201220014188176a200141a80d6a10ea0320012903e0084201520d0020012903e80821062013200141e0086a41106a290300370300200b2012290000370000200b41086a201241086a290000370000200b41106a201241106a290000370000200b41186a201241186a290000370000200120063703880e200141003a00e00d200141033a00d80d200141d80d6a10cb010b20012903b004210620012016290300221037039017200120063703881702400240200620108450450d00420021114200211a420021104200211b0c010b2001200e3602a80d200141e0086a200e20014188176a200141a80d6a10de030240024020012903e0084201520d00200141e0086a41106a290300211b20012903e80821100c010b201d290300211b200129038009211020012903e8084201520d0020012903f00821062013200141e0086a41186a290300370300200b200e290000370000200b41086a200e41086a290000370000200b41106a200e41106a290000370000200b41186a200e41186a290000370000200120063703880e200141003a00e00d200141033a00d80d200141d80d6a10cb010b2016290300211a20012903b00421110b200141e0166a41086a220a427f200a2903002206201b7c20012903e016221b20107c221c201b54220aad7c2210200a201020065420102006511b220a1b3703002001427f201c200a1b3703e0162013201a370300200b200e290000370000200b41086a200e41086a290000370000200b41106a200e41106a290000370000200b41186a200e41186a290000370000200120113703880e200141023a00e00d2001410e3a00d80d2001200d3602840e200141d80d6a10cb01200441016a21040c010b200141013a008417024020040d00410021040c010b200520046b220a20144f0d01200720044102746b220a280200210d200a20072802003602002007200d3602000b200741046a21072014200541016a2205460d030c010b0b200a20144180bdc7001036000b201d20291044000b2004417f6a20144f0d00203542ffffffff0f832135201420046b21140b20084200370300200141d80d6a41106a22044200370300200f4200370300200142003703d80d20241001220729000021062015200741086a290000370300200120063703881220071029200f201529030037030020012001290388123703d80d20251001220729000021062015200741086a2900003703002001200637038812200710292003200129038812370000200341086a20152903003700002016200f290300370300200141b0046a41106a200429030037030020172008290300370300200120012903d80d3703b004200141203602dc0d2001200141b0046a3602d80d201f2014200141d80d6a10a3040240203542ffffffff0383500d00201f10290b024020012d0084170d004200211b200141a0036a20012903b8162206200141b8166a41086a2207290300221042c0843d420010e00720014190036a20012903a0032211200141a0036a41086a290300221a42c0fb42427f10d50720014180036a2011201a4290ce00420010d50720072010201020014180036a41086a290300200129038003221120062001290390037c221a42e40080221ca7417f201a4290ce007e221a428080808080c8d007541b201a201c42c0fb427e7c42a0c21e566aad7c221a201154ad7c2211201a200656201120105620112010511b22041b22117d20062006201a20041b221054ad7d3703002001200620107d3703b81602400240201020118450450d004200211c0c010b200141d80d6a41186a220b4200370300200141d80d6a41106a22054200370300200141d80d6a41086a22044200370300200142003703d80d41dcbec500ad428080808080018422061001220a290000211a20014188176a41086a2207200a41086a2900003703002001201a37038817200a10292004200729030037030020012001290388173703d80d419fe3c200ad4280808080d00184221a1001220a290000211b2007200a41086a2900003703002001201b37038817200a10292005200129038817221b370300200141e0086a41086a220e2004290300370300200141e0086a41106a220d201b370300200141e0086a41186a220f2007290300370300200120012903d80d3703e008200141e8026a200141e0086a412010e301200141e8026a41106a290300211b20012903f002211c20012802e802210a200b42003703002005420037030020044200370300200142003703d80d20061001220b29000021062007200b41086a2900003703002001200637038817200b10292004200729030037030020012001290388173703d80d201a1001220b29000021062007200b41086a2900003703002001200637038817200b102920052001290388172206370300200e2004290300370300200d2006370300200f2007290300370300200120012903d80d3703e00820014200201b4200200a1b220620117d201c4200200a1b221a201054ad7d221b201a20107d221c201a56201b200656201b2006511b22071b3703e00d20014200201c20071b3703d80d200141e0086aad4280808080800484200141d80d6aad428080808080028410032006201120071b211c201a201020071b211b0b200141e0166a41086a2207427f20072903002206201c7c20012903e016221a201b7c221b201a542207ad7c221a2007201a200654201a2006511b22071b3703002001427f201b20071b3703e016200141f00d6a2011370300200141e80d6a2010370300200141d80d6a41086a41043a00002001410e3a00d80d200141d80d6a10cb010b200142f0f2bda1a7ee9cb9f9003703d80d20014188126a200141d80d6a108202200141e8166a290300211020012903e016210641002107200141003a00c80d200141023a00b017200120103703e808200120063703e008200120014188126a3602a80d02400240200620108450450d00420021114200211a0c010b200120014188126a36028817200120014188176a3602e80d2001200141b0176a3602e40d2001200141a80d6a3602e00d2001200141c80d6a3602dc0d2001200141e0086a3602d80d200141b0046a20014188126a200141d80d6a10c80241012107024020012802b0044101470d004200211a20012903b80421110c010b200141d8046a290300211a200141d0046a29030021114100210720012903b8044201520d00200141b0046a41106a290300211b2001280288172104200141900e6a200141b0046a41186a290300370300200141880e6a201b37030041002107200141d80d6a41086a41003a0000200141e10d6a2004290000370000200141e90d6a200441086a290000370000200141f10d6a200441106a290000370000200141f90d6a200441186a290000370000200141033a00d80d200141d80d6a10cb010b0240024020070d00200141d80d6a41186a220a4200370300200141d80d6a41106a22044200370300200141d80d6a41086a22054200370300200142003703d80d41dcbec500ad428080808080018422241001220b290000211b20014188176a41086a2207200b41086a2900003703002001201b37038817200b10292005200729030037030020012001290388173703d80d419fe3c200ad4280808080d0018422251001220b290000211b2007200b41086a2900003703002001201b37038817200b10292004200129038817221b370300200141e0086a41086a220b2005290300370300200141e0086a41106a220e201b370300200141e0086a41186a220d2007290300370300200120012903d80d3703e008200141b8026a200141e0086a412010e3012010201a7d2006201154ad7d201a20107d2011200654ad7d2011200658201a201058201a201051220f1b22141b210c200620117d201120067d20141b2135200141b8026a41106a290300420020012802b80222141b211b20012903c002420020141b211c024002402011200656201a201056200f1b0d00200a42003703002004420037030020054200370300200142003703d80d20241001220f29000021062007200f41086a2900003703002001200637038817200f10292005200729030037030020012001290388173703d80d20251001220f29000021062007200f41086a2900003703002001200637038817200f10292004200129038817370000200441086a2007290300370000200b2005290300370300200e2004290300370300200d200a290300370300200120012903d80d3703e0082001427f201b200c7c201c20357c2210201c542207ad7c220620072006201b542006201b511b22071b3703e00d2001427f201020071b3703d80d200141d80d6a21070c010b200a42003703002004420037030020054200370300200142003703d80d20241001220f29000021062007200f41086a2900003703002001200637038817200f10292005200729030037030020012001290388173703d80d20251001220f29000021062007200f41086a2900003703002001200637038817200f10292004200129038817370000200441086a2007290300370000200b2005290300370300200e2004290300370300200d200a290300370300200120012903d80d3703e00820014200201b200c7d201c203554ad7d2206201c20357d2210201c562006201b562006201b511b22071b3703e00d20014200201020071b3703d80d200141d80d6a21070b200141e0086aad42808080808004842007ad428080808080028410030c010b41b8efc900ad4280808080a009841008200141d80d6a41186a220b4200370300200141d80d6a41106a22054200370300200141d80d6a41086a22044200370300200142003703d80d41dcbec500ad428080808080018422111001220a290000211a200141e0086a41086a2207200a41086a2900003703002001201a3703e008200a102920042007290300370300200120012903e0083703d80d419fe3c200ad4280808080d00184221a1001220a290000211b2007200a41086a2900003703002001201b3703e008200a1029200520012903e008221b370300200141b0046a41086a220e2004290300370300200141b0046a41106a220d201b370300200141b0046a41186a220f2007290300370300200120012903d80d3703b004200141d0026a200141b0046a412010e301200141d0026a41106a290300211b20012903d802211c20012802d002210a200b42003703002005420037030020044200370300200142003703d80d20111001220b29000021112007200b41086a290000370300200120113703e008200b102920042007290300370300200120012903e0083703d80d201a1001220b29000021112007200b41086a290000370300200120113703e008200b1029200520012903e0082211370300200e2004290300370300200d2011370300200f2007290300370300200120012903d80d3703b0042001427f201b4200200a1b221120107c201c4200200a1b221020067c221a2010542207ad7c22062007200620115420062011511b22071b3703e00d2001427f201a20071b3703d80d20334280808080800484200141d80d6aad428080808080028410030b20012903b8162106200141f00d6a200141b8166a41086a290300370300200141e80d6a2006370300200141d80d6a41086a41053a00002001410e3a00d80d201e42c097e8b2017e201e4280bfdf80017e7c4280e59af7007c213a200141d80d6a10cb010b4200213c0240200041c09306700d0010d2044280c0a8ca9a3a213c0b0240024020004180ce1870450d004280fbc6d2022110200141b0046a210b0c010b200141d80d6a41186a4200370300200141d80d6a41106a22054200370300200141d80d6a41086a22074200370300200142003703d80d41c99fc500ad428080808090018410012204290000210620014188126a41086a220a200441086a2900003703002001200637038812200410292007200a29030037030020012001290388123703d80d41b092c700ad4280808080d0028410012204290000210620014188176a41086a220a200441086a29000037030020012006370388172004102920052001290388172206370300200141b0046a41086a2007290300370300200141b0046a41106a2006370300200141b0046a41186a200a290300370300200120012903d80d3703b00402400240024002400240200141b0046a10b201220741ff01714102460d0020334280808080800484100420074101710d010b200141d80d6a200010d30420012d00d80d4104460d02200141b0046a200010d4040c010b200141d80d6a200010d40420012d00d80d4104460d01200141b0046a200010d3040b20012d00b0044104460d01411610d5041a200141b0026a411610d6040c010b200141043a00b0040b4280c0a8ca9a3a2110200141b0046a210b0b200141d80d6a41186a220f4200370300200141d80d6a41106a220442003703004108210d200141d80d6a41086a22074200370300200142003703d80d41c99fc500ad428080808090018422061001220a290000211120014188126a41086a2205200a41086a2900003703002001201137038812200a10292007200529030037030020012001290388123703d80d41ac8fc700ad4280808080d001841001220e290000211120014188176a41086a220a200e41086a2900003703002001201137038817200e102920042001290388172211370300200141b0046a41086a22142007290300370300200141b0046a41106a22162011370300200141b0046a41186a2212200a290300370300200120012903d80d3703b004200141a8026a200b412010fc0120012802ac02211520012802a8022113200f42003703002004420037030020074200370300200142003703d80d20061001220e29000021062005200e41086a2900003703002001200637038812200e10292007200529030037030020012001290388123703d80d41948fc700ad4280808080f00184100122052900002106200a200541086a2900003703002001200637038817200510292004200129038817220637030020142007290300370300201620063703002012200a290300370300200120012903d80d3703b004200141a0026a200b412010fc0120012802a402210720012802a0022104200120003602b81620012007410020041b22123602e40820012015410020131b22153602e0082001200141b8166a3602e808200141d80d6a200141e0086a200141e0086a41086a10d7040240024020012d00b80e22074103460d00200141b0046a200141d80d6a41e00010e4071a2001200141d80d6a41e4006a28000036008b12200120012800b90e3602881241e8001027220d450d02200d200141b0046a41e00010e407220420073a00602004200128028812360061200441e4006a200128008b1236000020014188126a41086a220e200141e0086a41086a280200360200200120012903e00837038812200141d80d6a20014188126a200e10d704024020012d00b80e220b4103470d004101210a410121040c020b41c9012105200141b90e6a220f41036a21144101210a410121040340200141b0046a200141d80d6a41e00010e4071a200120142800003600e3162001200f2800003602e016200141d80d6a200141b0046a41e00010e4071a200120012800e31636008b17200120012802e0163602881702402004200a470d00200a41016a2207200a490d05200a41017422162007201620074b1bad42e8007e2206422088a70d052006a722074100480d05024002400240200a0d0020070d014108210d0c020b200a41e8006c220a2007460d010240200a0d0020070d014108210d0c020b200d200a2007102b220d450d080c010b20071027220d450d070b200741e8006e210a0b200d20056a2207419f7f6a200141d80d6a41e00010e4071a2007417f6a200b3a00002007200128028817360000200741036a200128008b17360000200141d80d6a20014188126a200e10d704200541e8006a2105200441016a210420012d00b80e220b4103470d000c020b0b4100210a410021040b4100201220156b2207200720124b1bad22064280e1eb177e20107c200642c0b19f057e7c210602402004450d00200d280200210e200141d80d6a200d41046a41dc0010e4071a2001200d41e1006a2800003602b0042001200d41e4006a2800003600b304200d41e0006a2d000022164103460d00200d200441e8006c6a2113200141e8046a2115200141d80d6a41086a210f200141d80d6a410172212e20014188126a41046a2117200141d80d6a41096a211d200141d80d6a41106a210b20014189056a220341036a210841dcbec500ad42808080808001842139200141d8046a211f200d2105034020014188126a200141d80d6a41dc0010e4071a200120012800b3043600e316200120012802b0043602e016200141b0046a201741d80010e4071a200320012802e016360000200820012800e316360000200120163a008805200141d80d6a41186a22124200370300200b4200370300200f4200370300200142003703d80d2039100122072900002106200f200741086a290000370300200120063703d80d20071029419fe3c200ad4280808080d0018410012207290000210620014188176a41086a2204200741086a290000370300200120063703881720071029200b200129038817370000200b41086a2004290300370000200141e0086a41086a200f290300370300200141e0086a41106a200b290300370300200141e0086a41186a2012290300370300200120012903d80d3703e00820014188026a200141e0086a412010e30120014188026a41106a29030021112001280288022104200129039002211a200141b0046a41186a2903002138200141b0046a41086a290300210c20012903c004212520012903b004212441002107024020012903d0042233420288201f290300221c423e86842206201c420288221084500d004100210720062033852010201c8584500d00410021070340200141f8016a2033201c200741046a41fe007110eb07200741026a210720012903f8012206200141f8016a41086a290300221084500d0120062033852010201c85844200520d000b0b2011420020041b211e201a420020041b2135200541e8006a21144200211a420021100340200141d8016a2010420186201a423f888422104200201a420186221a4201842206420010d507200141e8016a200642002006420010d5070240201020012903e001221184201184420052200141e8016a41086a290300221120012903d801221b201b7c7c221b201154720d0020012903e8012111200141c8016a2033201c200741ff007110eb0720102010201120012903c80156201b200141c8016a41086a290300221156201b2011511b22041b2110201a200620041b211a0b02402007450d0041002007417e6a2204200420074b1b21070c010b0b4100210702402035420288201e423e86842206201e420288221184500d0020062035852011201e8584500d00410021070340200141b8016a2035201e200741046a41fe007110eb07200741026a210720012903b8012206200141b8016a41086a290300221184500d0120062035852011201e85844200520d000b0b4200211142002106034020014198016a20064201862011423f88842206420020114201862211420184221b420010d507200141a8016a201b4200201b420010d5070240200620012903a001221c84201c84420052200141a8016a41086a290300221c200129039801223320337c7c2233201c54720d0020012903a801211c20014188016a2035201e200741ff007110eb0720062006201c20012903880156203320014188016a41086a290300221c562033201c511b22041b21062011201b20041b21110b02402007450d0041002007417e6a2204200420074b1b21070c010b0b02400240024002400240201a201084500d00024002400240201641ff01710e03000102000b0340200141386a20252038201a201010e0072011221c20062233844200510d04200141386a41086a290300210620012903382111200141286a2024200c201c203310e00720112001290328221e542006200141286a41086a290300221b542006201b5122071b0d06201e201154201b20065420071b0d03200141186a20112006201a201010d507200141086a201e201b201c203310d5072024200129030822067d221b200c200141086a41086a2903007d2024200654ad7d220684500d032038200141186a41086a2903007d211e202520012903182211542107202520117d2111201a21242010210c201b211a20062110201c2125203321382011201e2007ad7d22068450450d000c060b0b03402010211b201a211c20112006844200510d04200141e8006a2024200c201c201b10e007200141f8006a202520382011200610e007200129037822332001290368221e54200141f8006a41086a2903002210200141e8006a41086a290300221a542010201a5122071b0d05201e203354201a20105420071b0d02200141d8006a203320102011200610d507200141c8006a201e201a201c201b10d5072024200129034822107d2233200c200141c8006a41086a2903007d2024201054ad7d221084500d022038200141d8006a41086a2903007d211e20252001290358221a5421072025201a7d211a201121242006210c2033211120102106201c2125201b2138201a201e2007ad7d22108450450d000c050b0b2024202556200c203856200c2038511b0d030b2001200e3602e40d200141053a00e00d200141093a00d80d200141d80d6a10cb01410021070c030b4180aac400411941a0f1c9001033000b4180aac400411941a0f1c9001033000b2001200e3602e40d200141043a00e00d200141093a00d80d200141d80d6a10cb0102400240024020012802e4042207450d0020014188176a201510d804200141d80d6a2001280288172216200128029017221210d904200720006a2104024020012d00d80d22074103712237410346222b0d00024020070e03000100000b02400240202b0d0020370e03010001010b20012802800e450d0020012802fc0d10290b202e20012f00b8163b0000202e41026a200141b8166a41026a2d00003a000041002107200141003a00d80d200120043602dc0d200f200141e0086a41c80010e4071a0c020b200120043602900e2001410136028c0e20074102470d012012ad4220862016ad8410040c020b2012201541186a290000370300200b201541106a290000370300200f201541086a290000370300200120152900003703d80d200141e0086a200141d80d6a200e10da04410121070c020b200141003602e808200142013703e008200141d80d6a200141e0086a10db0420012802e408212b2012ad4220862016ad8420013502e80842208620012802e0082212ad8410030240202b450d00201210290b0240200741037122074103460d0020070e03010001010b20012802800e450d0020012802fc0d10290b0240200128028c17450d00201610290b410c10272207450d032007200e360008200742e4cab5fbb6ccdcb0e3003700002001428c808080c00137028c172001200736028817201d2015290000370000201d41086a201541086a290000370000201d41106a201541106a290000370000201d41186a201541186a2900003700002001411f3a00e00d2001410e3602d80d2001200e3602840e200141e0086a20014188176a2004410020012001413f200141d80d6a10dc044101210720012802e0084101470d004194a3c700ad4280808080a0068410080b200120003602dc0d200120073a00d90d200141013a00d80d200141b0046a200e10dd0420012802b0042107200120012802b8043602e408200120073602e008200141d80d6a200141e0086a10de04024020012802b404450d00200710290b4280c0a8ca9a3a210620142013460d012005280268210e200141d80d6a200541ec006a41dc0010e4071a2001200541c9016a2800003602b0042001200541cc016a2800003600b304200541c8016a21072014210520072d000022164103470d000b0b0240200a450d00200a41e8006c450d00200d10290b200010df04211020022400427f203a427f203c427f200620107c221020102006541b7c22062006203c541b7c22062006203a541b0f0b1039000b1032000b1030000b4113210741d1a6c70021040b2001200736028c17200120043602881741a4b2c400412220014188176a4194b2c40041c8b2c400103a000be20c040a7f027e017f017e230041900f6b220324002003200236020420032001360200200341086a2002ad4220862001ad841007108b0202400240200328020822040d00200041033602000c010b200341086a41086a2802002105200328020c2106200341003a00f808200421024100210702400240024003400240024002402005450d0020022d0000220141014b0d002005417f6a2108200241016a21090240024020010e020001000b20034180096a41186a200341a0096a41186a29030037030020034180096a41106a200341a0096a41106a29030037030020034180096a41086a200341a0096a41086a290300370300200320032903a009370380094102210a200821050c030b0240024002402008450d00200241026a21092005417e6a210120022d0001220a41014b0d010240024002400240200a0e020001000b41002101200341003a00e0092005417e6a210a02400340200a2001460d01200341c0096a20016a200220016a41026a2d00003a00002003200141016a22093a00e0092009210120094120470d000b200341f00e6a41186a220a200341c0096a41186a290300370300200341f00e6a41106a220b200341c0096a41106a290300370300200341f00e6a41086a220c200341c0096a41086a290300370300200320032903c0093703f00e200220096a2102200520096b2209417e6a220141044f0d02200241026a21094102210a0c060b200220016a41026a2109200141ff0171450d03200341003a00e0090c030b20014104490d0320022800022108200341d00e6a41186a200341c0096a41186a290200370300200341d00e6a41106a200341c0096a41106a290200370300200341d00e6a41086a200341c0096a41086a290200370300200320032902c0093703d00e2005417a6a2101200241066a21094101210a0c010b200241026a2800002108200341d00e6a41186a200a290300370300200341d00e6a41106a200b290300370300200341d00e6a41086a200c290300370300200320032903f00e3703d00e2009417a6a2101200241066a21094100210a0b200341b00e6a41086a2202200341d00e6a41086a290300370300200341b00e6a41106a2205200341d00e6a41106a290300370300200341b00e6a41186a220b200341d00e6a41186a290300370300200320032903d00e3703b00e20014110490d01200941086a290000210d2009290000210e200341c0096a41186a200b290300370300200341c0096a41106a2005290300370300200341c0096a41086a2002290300370300200320032903b00e3703c009200941106a2109200141706a21012008210f0c020b410021010b4102210a0b200341f00d6a41086a2202200341c0096a41086a290300370300200341f00d6a41106a2205200341c0096a41106a290300370300200341f00d6a41186a2208200341c0096a41186a290300370300200320032903c0093703f00d200a4102470d010b20034180096a41186a200341a0096a41186a2903003703000240200741ff0171450d00200341003a00f8080b410321020c030b200341a0096a41186a2008290300221037030020034180096a41086a200229030037030020034180096a41106a200529030037030020034180096a41186a2010370300200320032903f00d37038009200121050b20092102200341c8046a200741386c6a2201200a360200200141086a200329038009370200200141106a20034180096a41086a290300370200200141186a20034180096a41106a290300370200200141206a20034180096a41186a290300370200200141306a200d370200200141286a200e3702002001200f3602042003200741016a22013a00f808200121072001410a470d000b20032802c8042102200341c0096a200341c8046a41047241ac0410e4071a0240200141ff017141094b0d00410321020c010b200341186a200341c0096a41ac0410e4071a20024103470d010b200341003602c809200342013703c0092003410d36021c200320033602182003200341c0096a3602f00e200341dc046a4101360200200342013702cc04200341f4eaca003602c8042003200341186a3602d804200341f00e6a41a8a3c800200341c8046a10371a20033502c80942208620033502c00984100820032802c409450d0120032802c00910290c010b200341c8046a200341186a41ac0410e4071a200041046a200341c8046a41ac0410e4071a0b200020023602002006450d00200410290b200341900f6a24000bc60603027f017e057f230041d0006b2202240041d482cc00ad4280808080d00084100122032900002104200241086a41086a200341086a29000037030020022004370308200310294195b3c400ad4280808080f00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310292001280200210541011027210302400240024020054101460d002003450d02200341003a000041212105200341014121102b2203450d02200341196a200141206a290000370000200341116a200141186a290000370000200341096a200141106a2900003700002003200141086a29000037000120022001280204360240200241c0006a21060c010b2003450d0141012105200341013a000020022001280204360240200241c0006a21060b200320052005410174220720054104722201200720014b1b102b2203450d00200320056a200628020036000020022001ad4220862003ad841002220529000037033820051029200241cc006a200320016a360200200220033602482002200241c0006a3602442002200241386a360240200241286a200241c0006a1075200310290240024002402002280230220741206a2206417f4c0d00200228022821080240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121050c010b200141017422054110200541104b1b22054100480d03024020010d002005102722030d010c050b20012005460d00200320012005102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020054170714110460d00200521010c010b200541017422014120200141204b1b22014100480d0320052001460d00200320052001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2007490d00200121050c010b200741206a22052007490d03200141017422092005200920054b1b22054100480d0320012005460d00200320012005102b2203450d040b200341206a2008200710e4071a2000200636020820002005360204200020033602000240200228022c450d00200810290b200241d0006a24000f0b1038000b1039000b1032000b1030000b940407047f017e017f017e017f017e057f230041e0006b22002400200041306a41186a22014200370300200041306a41106a22024200370300200041306a41086a220342003703002000420037033041d787cc00ad42808080809001842204100122052900002106200041d0006a41086a2207200541086a29000037030020002006370350200510292003200729030037030020002000290350370330418088cc00ad4280808080a0018422061001220529000021082007200541086a2900003703002000200837035020051029200220002903502208370300200041106a41086a22092003290300370300200041106a41106a220a2008370300200041106a41186a220b200729030037030020002000290330370310200041086a200041106a412010fc01200028020c210c2000280208210d2001420037030020024200370300200342003703002000420037033020041001220529000021042007200541086a2900003703002000200437035020051029200320072903003703002000200029035037033020061001220529000021042007200541086a290000370300200020043703502005102920022000290350220437030020092003290300370300200a2004370300200b2007290300370300200020002903303703102000200c41e807200d1b220741016a360230200041106aad4280808080800484200041306aad4280808080c000841003200041e0006a240020070b9f0205027f017e027f037e017f230041206b22022400200241106a200110c504200220022802102203200228021810c60420022902044200200228020022011b210402402002280214450d00200310290b2001410820011b21052004a72106024002402004422088a72203450d00200541086a290300210420052903002107024020034101460d00200541106a2101200341047441706a210303402004200141086a290300220820072001290300220956200420085620042008511b220a1b210420072009200a1b2107200141106a2101200341706a22030d000b0b200641ffffffff0071450d01200510290c010b0240200641ffffffff0071450d00200510290b42002107420021040b2000200737030020002004370308200241206a24000bbe0201017f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d00200041003602000c010b200328021421022003200341106a41086a28020036022420032001360220200341c8006a200341206a10f5050240024020032802480d0020034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b200041003602000c010b20002003290348370200200041086a200341c8006a41086a2802003602000b2002450d00200110290b200341e0006a24000bfc0403027f017e057f230041d0006b2202240041d482cc00ad4280808080d00084100122032900002104200241086a41086a200341086a29000037030020022004370308200310294189b3c400ad4280808080c00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bfc0403027f017e057f230041d0006b2202240041d482cc00ad4280808080d00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941efb1c400ad4280808080b00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bfc0403027f017e057f230041d0006b2202240041d482cc00ad4280808080d00084100122032900002104200241086a41086a200341086a29000037030020022004370308200310294181a0c400ad4280808080a00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bf40201037f230041106b220224002002200028020036020020012002410410720240024020002d0004220341024b0d0002400240024020030e03000102000b200241003a00072001200241076a4101107220012000410c6a412010722002200041086a2802003602082001200241086a410410720c020b200241013a00072001200241076a41011072412010272203450d02200341186a2000411d6a290000370000200341106a200041156a290000370000200341086a2000410d6a2900003700002003200041056a2900003700002001200341201072200310292002200041286a28020036020c20012002410c6a410410722000412c6a2802002103200041346a28020022002001107120012003200010720c010b200241023a00072001200241076a41011072200041086a2802002103200041106a2802002204200110712001200320041072200041146a28020021032000411c6a28020022002001107120012003200010720b200241106a24000f0b1039000bfc0403027f017e057f230041d0006b2202240041d482cc00ad4280808080d00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941e7b1c400ad4280808080800184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000ba40403037f017e027f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d00200041003602000c010b200328021421022003200341186a280200360224200320013602202003200341206a10c8010240024020032802000d002003280224220420032802044104742205490d0002400240024002402005417f4c0d000240024020050d0042002106410121070c010b2005102d2207450d02200720032802202208200510e4071a2003200420056b3602242003200820056a3602202005ad21060b2007450d04024020062005ad422086842206422088a722050d002006a721050c030b024020074107712005410f71720d002006a72205410f710d0020054104762204450d032006422488a721080c040b2006a7450d04200710290c040b1038000b1039000b4100210802402005450d00200710290b41002104410821070b41000d002007450d002000200436020420002007360200200041086a20083602000c010b20034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b200041003602000b2002450d00200110290b200341e0006a24000bf61507047f017e027f027e017f047e037f230041a0026b22012400200141a0016a2000280200220210c504200141f0006a20012802a001220320012802a80110c60420012902744200200128027022041b2105024020012802a401450d00200310290b2004410820041b21030240024002400240024002402005422088a7220641014b0d0020060e020201020b200341086a22072903002108200329030021092003200341106a2204200641047441706a10e5072102200141a0016a200028020010c50420012802a0012103200120012802a8013602742001200336027020022006417f6a220a200141f0006a10a204024020012802a401450d00200310290b2007290300210b2002290300210c0240200a4101460d00200641047441606a21030340200b200441086a290300220d200c2004290300220e56200b200d56200b200d511b22061b210b200c200e20061b210c200441106a2104200341706a22030d000b0b0240200542ffffffff0083500d00200210290b410121042009200c7d220d2009562008200b7d2009200c54ad7d220b200856200b2008511b0d04200141386a200010cc032001200d3703582001200b370360200d200b8450450d0242002105420021080c030b200141f0006a200210c304200141a0016a200128027022062001280278220010c804024020012d00a40122044103460d002000ad4220862006ad8410040b200141d0016a2802002100200141cc016a280200210f200141b8016a2802002107200141b4016a2802002110200141ac016a280200210a200141a8016a280200211102402001280274450d00200610290b02400240200441034b0d00024020040e0402000102020b2000450d01200f10290c010b0240200a450d00201110290b2007450d00201010290b024020044103470d00200141a0016a200210e8040b200141d8006a200210c204200141a0016a200128025822042001280260220010cd01024020012d00a0012206450d002000ad4220862004ad8410040b200141f0006a41186a200141b9016a290000220b370300200141f0006a41106a200141b1016a290000220c370300200141f0006a41086a200141a9016a290000220d370300200120012900a101220e370370200141a0016a41186a2200200b370300200141a0016a41106a2207200c370300200141a0016a41086a220a200d3703002001200e3703a0010240024020064101460d00200141386a41186a4200370300200141386a41106a4200370300200141386a41086a4200370300200142003703380c010b200141386a41186a2000290300370300200141386a41106a2007290300370300200141386a41086a200a290300370300200120012903a0013703380b0240200128025c450d00200410290b2003290300210b2001200341086a290300220c3703602001200b37035802400240200b200c8450450d004200210c4200210d0c010b2001200141386a36026c200141f0006a200141386a200141d8006a200141ec006a10de03024020012903704201520d0020014180016a290300210d2001290378210c0c010b20014198016a290300210d20014190016a290300210c20012903784201520d00200141f0006a41106a290300210b200141d8016a200141f0006a41186a290300370300200141d0016a200b370300200141a0016a41086a41003a0000200141a9016a2001290338370000200141b1016a200141386a41086a290300370000200141b9016a200141386a41106a290300370000200141c1016a200141386a41186a290300370000200141033a00a001200141a0016a10cb010b200141a0016a41186a220a4200370300200141a0016a41106a22004200370300200141a0016a41086a22064200370300200142003703a00141dcbec500ad4280808080800184220b10012207290000210e200141d8006a41086a2204200741086a2900003703002001200e3703582007102920062004290300370300200120012903583703a001419fe3c200ad4280808080d00184220e1001220729000021082004200741086a2900003703002001200837035820071029200020012903582208370300200141f0006a41086a220f2006290300370300200141f0006a41106a22102008370300200141f0006a41186a22112004290300370300200120012903a001370370200141206a200141f0006a412010e301200141206a41106a29030021082001290328210920012802202107200a42003703002000420037030020064200370300200142003703a001200b1001220a290000210b2004200a41086a2900003703002001200b370358200a102920062004290300370300200120012903583703a001200e1001220a290000210b2004200a41086a2900003703002001200b370358200a102920002001290358220b370300200f20062903003703002010200b37030020112004290300370300200120012903a0013703702001427f2008420020071b220b200d7c2009420020071b220d200c7c220e200d542204ad7c220c2004200c200b54200c200b511b22041b3703a8012001427f200e20041b3703a001200141f0006aad4280808080800484200141a0016aad42808080808002841003200141a0016a200210c50420013502a80142208620012802a0012204ad84100420012802a401450d00200410290b41002104200542ffffffff0083500d02200310290c020b2001200141386a36026c200141f0006a200141386a200141d8006a200141ec006a10de03024020012903704201520d0020014180016a2903002108200129037821050c010b20014198016a290300210820014190016a290300210520012903784201520d00200141f0006a41106a290300210b200141d8016a200141f0006a41186a290300370300200141d0016a200b370300200141a0016a41086a41003a0000200141a9016a2001290338370000200141b1016a200141386a41086a290300370000200141b9016a200141386a41106a290300370000200141c1016a200141386a41186a290300370000200141033a00a001200141a0016a10cb010b200141a0016a41186a22074200370300200141a0016a41106a22004200370300200141a0016a41086a22064200370300200142003703a00141dcbec500ad4280808080800184220b10012202290000210c200141d8006a41086a2203200241086a2900003703002001200c3703582002102920062003290300370300200120012903583703a001419fe3c200ad4280808080d00184220c10012202290000210d2003200241086a2900003703002001200d3703582002102920002001290358220d370300200141f0006a41086a220a2006290300370300200141f0006a41106a220f200d370300200141f0006a41186a22102003290300370300200120012903a001370370200141086a200141f0006a412010e301200141086a41106a290300210d2001290310210e20012802082102200742003703002000420037030020064200370300200142003703a001200b10012207290000210b2003200741086a2900003703002001200b3703582007102920062003290300370300200120012903583703a001200c10012207290000210b2003200741086a2900003703002001200b3703582007102920002001290358220b370300200a2006290300370300200f200b37030020102003290300370300200120012903a0013703702001427f200d420020021b220b20087c200e420020021b220c20057c220d200c542203ad7c220c2003200c200b54200c200b511b22031b3703a8012001427f200d20031b3703a001200141f0006aad4280808080800484200141a0016aad428080808080028410030b200141a0026a240020040bfa0b06077f017e017f027e017f057e23004180016b220324002003200236021c20032001360218200341206a2002ad4220862001ad841007108b0202400240200328022022010d00200041033a00040c010b200328022421042003200341286a28020022053602342003200136023002400240024002400240024020054104490d002001280000210620032005417c6a22023602342003200141046a3602302002450d0020012d0004210220032005417b6a3602342003200141056a360230200241024b0d0002400240024020020e03000102000b41002102200341003a00782005417b6a2107417a21080240034020072002460d01200341d8006a20026a200120026a220941056a2d00003a00002003200520086a3602342003200941066a3602302003200241016a22093a00782008417f6a21082009210220094120470d000b2003200329006b220a3703482003200341f0006a29000037004d200520096b2202417b6a4104490d03200341e6006a2d0000210820032f0164210b2003350067210c200328026021072003290358210d2003280051210e2003290049210f200120096a220941056a28000021052003200241776a3602342003200941096a360230200c421886200b200841107472ad42ffffff078384200a42ff018342388684210a410021020c060b200241ff0171450d02200341003a00780c020b41002102200341003a00782005417b6a2107417a210802400240034020072002460d01200341d8006a20026a200120026a220941056a2d00003a00002003200520086a3602342003200941066a3602302003200241016a22093a00782008417f6a21082009210220094120470d000b2003200341f0006a29000037004d2003200329006b370348200520096b2202417b6a4104490d032003290358210f2003350260210d200341e6006a310000210c20033301642110200341d4006a310000211120033502502112200328006721072003290348210a200120096a220541056a280000210e2003200241776a3602342003200541096a3602302003200341306a10c80120032802000d032003280234220520032802042202490d032002417f4a0d010c050b200241ff0171450d02200341003a00780c020b0240024020020d0042002113410121090c010b2002102d2209450d03200920032802302208200210e4071a2003200520026b3602342003200820026a3602302002ad21130b2009450d01200d420886200f423888842010200c4210868442288684210d200f421888a72105200fa72108201220114220868442ffffffffff1f83210f20132002ad42208684210c410121020c050b200341106a200341306a10c80120032802100d002003280234220820032802142202490d002002417f4c0d020240024020020d004200210a410121050c010b2002102d2205450d02200520032802302209200210e4071a2003200820026b3602342003200920026a3602302002ad210a0b2005450d00200a2002ad42208684210d200341086a200341306a10c801024020032802080d0020032802342208200328020c2202490d002002417f4c0d030240024020020d004200210a410121070c010b2002102d2207450d03200720032802302209200210e4071a2003200820026b3602342003200920026a3602302002ad210a0b2007450d00200a2002ad42208684210a410221020c040b200da7450d00200510290b20034100360250200342013703482003410d36023c2003200341186a3602382003200341c8006a360244200341ec006a41013602002003420137025c200341f4eaca003602582003200341386a360268200341c4006a41a8a3c800200341d8006a10371a200335025042208620033502488410080240200328024c450d00200328024810290b410321020c040b1039000b1038000b0b200020083b000520002006360200200041076a20084110763a0000200041306a200c3700002000412c6a2009360000200041286a200e360000200041206a200f370000200041186a200a370000200041146a20073600002000410c6a200d370000200041086a20053600000b200020023a00042004450d00200110290b20034180016a24000bcd0b03057f017e067f23004180016b22052400200541d0006a200110dc0641002106200541086a2005280250220720052802584180a6cc004100410010c7012005280208210802402005280254450d00200710290b02400240024020084101470d004111210841b3d3c80021010c010b024020020d00200541d0006a41186a4200370300200541d0006a41106a22094200370300200541d0006a41086a220642003703002005420037035041d787cc00ad428080808090018410012207290000210a200541f0006a41086a2208200741086a2900003703002005200a37037020071029200620082903003703002005200529037037035041cd87cc00ad4280808080a0018410012207290000210a2008200741086a2900003703002005200a3703702007102920092005290370220a370300200541306a41086a2006290300370300200541306a41106a200a370300200541306a41186a200829030037030020052005290350370330200541206a200541306a412010c00402400240024002400240024002402005280220220b0d004100210820054100360218200542043703104100210c4100210d0c010b2005290224210a2005200b3602102005200a370214200aa7210c41002108024002400240200a422088a7220d41014b0d00200d0e020201020b200d2106034020082006410176220720086a220e200b200e4102746a28020020014b1b2108200620076b220641014b0d000b0b4101210e200b20084102746a28020022062001460d03200d200820062001496a2208490d040b200d200c470d010b200541106a200c41011098012005280214210c2005280210210b0b200b20084102746a220641046a2006200d20086b41027410e5071a200620013602002005200d41016a220d3602184106210e0b200541d0006a41186a220f4200370300200541d0006a41106a22104200370300200541d0006a41086a220642003703002005420037035041d787cc00ad428080808090018410012207290000210a200541f0006a41086a2208200741086a2900003703002005200a37037020071029200620082903003703002005200529037037035041cd87cc00ad4280808080a0018410012207290000210a2008200741086a2900003703002005200a3703702007102920092005290370370000200941086a2008290300370000200541306a41086a2006290300370300200541306a41106a2010290300370300200541306a41186a200f29030037030020052005290350370330200b0d01200541306aad428080808080048410040c020b2008200d1041000b200541203602542005200541306a360250200b200d200541d0006a10ef03200c41ffffffff0371450d00200b10290b200e4106460d0041edd3c800210141102108410421060240024002400240200e417f6a0e050001020305000b41b3d3c800210141112108410021060c040b41c4d3c8002101410e2108410121060c030b41d2d3c8002101410f2108410221060c020b41e1d3c8002101410c2108410321060c010b2004280208210e2004280204210b20042802002108200328020421042003280208210d20032802002106200541d0006a200110ac032005280250210720052005280258360234200520073602302006200d200541306a10a10402402005280254450d00200710290b02402004450d00200610290b200541d0006a2001108f062005280250210620052005280258360234200520063602302008200e200541306a10a10402402005280254450d00200610290b0240200b450d00200810290b200541d0006a200110dc062005350258210a200528025021010240410110272208450d00200820023a0000200a4220862001ad842008ad4280808080108410032008102902402005280254450d00200110290b200041043a00000c020b1030000b20004183343b0100200041086a2008360200200041046a2001360200200041026a20063a00000240200441046a280200450d00200428020010290b200341046a280200450d00200328020010290b20054180016a24000bdf0401097f230041e0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b020240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c8010240024020022802000d0020022802042205200228022422064103762201200120054b1b22074103742201417f4c0d030240024020070d00410421080c010b200110272208450d050b41002101200241003602502002200736024c200220083602480240024002402005450d00034020064104490d0320022002280220220741046a3602202006417c6a4104490d02200728000021092002200741086a3602202007280004210702402001200228024c470d00200241c8006a20014101108d0120022802482108200228025021010b200641786a2106200820014103746a220a2007360204200a20093602002002200141016a22013602502005417f6a22050d000b200220063602240b2008450d022000200229024c370204200020083602000c030b2006417c6a21060b20022006360224200228024c41ffffffff0171450d00200810290b20024100360230200242013703282002410d36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241f4eaca003602482002200241386a360258200241c4006a41a8a3c800200241c8006a10371a200235023042208620023502288410080240200228022c450d00200228022810290b200041003602000b2004450d00200310290b200241e0006a24000f0b1038000b1039000bfc0403027f017e057f230041d0006b2202240041cd87cc00ad4280808080a00184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941cfbcc700ad4280808080c00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000b980503037f017e077f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d002000410236020c0c010b200328021421042003200341186a280200360224200320013602202003200341206a10c8010240024020032802000d002003280224220520032802044102742202490d00024002400240024002402002417f4c0d000240024020020d0042002106410121070c010b2002102d2207450d02200720032802202208200210e4071a2003200520026b22053602242003200820026a3602202002ad21060b2007450d0502402002ad4220862006842206422088a722020d002006a721020c030b024020072002724103710d002006a722024103710d0020024102762208450d032006422288a721090c040b2006a70d040c050b1038000b1039000b4100210902402002450d00200710290b41002108410421070b41000d012007450d0102402005450d0020032005417f6a220a36022420032003280220220b41016a360220200b2d0000220c41014b0d004100210202400240200c0e020100010b200a4104490d0120032005417b6a3602242003200b41056a360220200b280001210d410121020b2000200d3602102000200936020820002008360204200020073602000c030b2008450d010b200710290b20034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b410221020b2000200236020c2004450d00200110290b200341e0006a24000ba10503027f017e057f230041d0006b2202240041cd87cc00ad4280808080a00184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941c7bcc700ad4280808080800184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029024002400240410410272203450d002003200128020036000020012802042105200341044108102b2201450d022001200536000420022001ad42808080808001841002220329000037033820031029200241cc006a200141086a360200200220013602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a10752001102902402002280230220641206a2207417f4c0d00200228022821080240024020070d0041002103410121010c010b200710272201450d02200721030b024002402003410f4d0d00200321050c010b200341017422054110200541104b1b22054100480d03024020030d002005102722010d010c050b20032005460d00200120032005102b2201450d040b20012002290308370000200141086a200241086a41086a2903003700000240024020054170714110460d00200521030c010b200541017422034120200341204b1b22034100480d0320052003460d00200120052003102b2201450d040b20012002290318370010200141186a200241186a41086a29030037000002400240200341606a2006490d00200321050c010b200641206a22052006490d03200341017422092005200920054b1b22054100480d0320032005460d00200120032005102b2201450d040b200141206a2008200610e4071a2000200736020820002005360204200020013602000240200228022c450d00200810290b200241d0006a24000f0b1038000b1039000b1032000b1030000b830803027f017e067f230041f0006b2202240041cd87cc00ad4280808080a00184100122032900002104200241106a41086a200341086a290000370300200220043703102003102941f283cc00ad4280808080d00084100122032900002104200241206a41086a200341086a2900003703002002200437032020031029200220013602402002200241c0006aad4280808080c000841002220329000037034820031029200241e4006a200241c4006a3602002002200241c8006a41086a36025c2002200241c0006a3602602002200241c8006a360258200241306a200241d8006a107502400240024002402002280238220541206a2201417f4c0d00200228023021060240024020010d0041002107410121030c010b200110272203450d03200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d02024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290310370000200341086a200241106a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0220082007460d00200320082007102b2203450d040b20032002290320370010200341186a200241206a41086a29030037000002400240200741606a2005490d00200721080c010b200541206a22082005490d02200741017422092008200920084b1b22084100480d0220072008460d00200320072008102b2203450d040b200341206a2006200510e4071a02402002280234450d00200610290b2002200136024420022003360240200241106a2001ad4220862003ad841007108b0202400240024020022802102201450d00200228021421052002200241186a28020036024c20022001360248200241086a200241c8006a10c8010240024020022802080d00200228024c2209200228020c2206490d002006417f4c0d050240024020060d0042002104410121070c010b2006102d2207450d0820072002280248220a200610e4071a2002200920066b36024c2002200a20066a3602482006ad21040b2007450d0020042006ad4220868421040c010b4100210720024100360228200242013703202002410d3602342002200241c0006a3602302002200241206a360254200241ec006a41013602002002420137025c200241f4eaca003602582002200241306a360268200241d4006a41a8a3c800200241d8006a10371a2002350228422086200235022084100802402002280224450d00200228022010290b0b02402005450d00200110290b20070d010b200041003602000c010b20002004370204200020073602000b02402008450d00200310290b200241f0006a24000f0b1038000b1032000b1039000b1030000b830601077f230041106b220224002002410036020820024201370300200028020021032000280208220420021071024002400240024020022802042205200228020822066b20044102742207490d0020022802002108200521040c010b200620076a22042006490d01200541017422082004200820044b1b22044100480d010240024020050d00024020040d00410121080c020b2004102722080d010c040b2002280200210820052004460d00200820052004102b2208450d030b20022004360204200220083602000b200820066a2003200710e4071a2002200620076a220636020802400240200028020c4101460d000240024020042006460d00200621040c010b200441016a22002004490d03200441017422062000200620004b1b22004100480d030240024020040d0041002104024020000d00410121080c020b200010272208450d060c010b20042000460d00200820042000102b2208450d050b20022000360204200220083602000b200820046a41003a00002002200441016a220836020820022802042100200228020021040c010b0240024020042006460d00200621040c010b200441016a22062004490d02200441017422072006200720064b1b22064100480d020240024020040d0041002104024020060d00410121080c020b200610272208450d050c010b20042006460d00200820042006102b2208450d040b20022006360204200220083602000b200820046a41013a00002002200441016a220636020820002802102105024002402002280204220720066b4104490d00200441056a210820022802002104200721000c010b200641046a22082006490d02200741017422042008200420084b1b22004100480d020240024020070d00024020000d00410121040c020b200010272204450d050c010b2002280200210420072000460d00200420072000102b2204450d040b20022000360204200220043602000b200420066a2005360000200220083602080b20012902002008ad4220862004ad84100302402000450d00200410290b200241106a24000f0b1032000b1030000bfc0403027f017e057f230041d0006b220224004197dec900ad4280808080800184100122032900002104200241086a41086a200341086a2900003703002002200437030820031029419fdec900ad4280808080900184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000be70804067f027e077f027e230041e0016b220324002003200236020420032001360200200341086a2002ad4220862001ad841007108b0202400240200328020822040d00200042003703000c010b200341106a2802002105200328020c210641002101200341003a00d801200541706a21070240024002400240034020052001460d01200341b8016a20016a200420016a2d00003a00002003200141016a22023a00d8012007417f6a21072002210120024120470d000b200341d8006a41086a200341b8016a41086a290300370300200341d8006a41106a200341b8016a41106a290300370300200341d8006a41186a200341b8016a41186a290300370300200320032903b801370358200520026b22084110490d02200420026a22052900002109200541086a290000210a41002101200341003a00d801200841706a2108034020082001460d02200341b8016a20016a200520016a41106a2d00003a00002003200141016a22023a00d8012002210120024120470d000b200341f8006a41086a220b200341b8016a41086a2201290300370300200341f8006a41106a220c200341b8016a41106a2208290300370300200341f8006a41186a220d200341b8016a41186a220e290300370300200320032903b801370378200720026b410f4d0d02200341386a41086a2207200341d8006a41086a290300370300200341386a41106a220f200341d8006a41106a290300370300200341386a41186a2210200341d8006a41186a290300370300200341186a41086a2211200b290300370300200341186a41106a220b200c290300370300200341186a41186a220c200d2903003703002003200329035837033820032003290378370318200520026a220241106a2900002112200241186a2900002113200120072903003703002008200f290300370300200e201029030037030020034198016a41086a2202201129030037030020034198016a41106a2207200b29030037030020034198016a41186a2205200c290300370300200320032903383703b8012003200329031837039801200041206a2013370300200041186a2012370300200041106a200a37030020002009370308200041286a20032903b801370300200041306a2001290300370300200041386a2008290300370300200041c0006a200e290300370300200041c8006a200329039801370300200041d0006a2002290300370300200041d8006a2007290300370300200041e0006a2005290300370300420121090c030b200141ff0171450d01200341003a00d8010c010b200141ff0171450d00200341003a00d8010b200341003602a00120034201370398012003410d36027c20032003360278200320034198016a360258200341cc016a4101360200200342013702bc01200341f4eaca003602b8012003200341f8006a3602c801200341d8006a41a8a3c800200341b8016a10371a20033502a0014220862003350298018410080240200328029c01450d0020032802980110290b420021090b200020093703002006450d00200410290b200341e0016a24000bf59c0107047f017e087f047e1a7f017e0e7f230041f0056b22002400200041d8036a41186a4200370300200041d8036a41106a22014200370300200041d8036a41086a22024200370300200042003703d8034196ebca00ad42808080808002841001220329000021042002200341086a290000370300200020043703d8032003102941e0f8ca00ad4280808080a00184100122032900002104200041a8056a41086a2205200341086a290000370300200020043703a80520031029200120002903a8052204370300200041a0036a41086a2002290300370300200041a0036a41106a2004370300200041a0036a41186a2005290300370300200020002903d8033703a003200041d8036a200041a0036a108d020240024020002802d80322020d0041002106200041003602c002200042013703b802410121020c010b200020002902dc0322043702bc02200020023602b8022004422088a721060b024002400240200641ffffff3f712006470d0020064105742203417f4c0d000240024020030d00410121050c010b200310272205450d020b200041003602e003200020053602d803200020034105763602dc03200041d8036a41002006109e0120002802e00321070240024020060d0020002802d80321080c010b2006410574210520002802d803220820074105746a2103034020032002290000370000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a290000370000200341206a2103200241206a2102200541606a22050d000b200641057441606a41057620076a41016a21070b20002802dc032109200041d8036a41186a22054200370300200041d8036a41106a220a4200370300200041d8036a41086a22024200370300200042003703d8034196ebca00ad42808080808002841001220329000021042002200341086a290000370300200020043703d8032003102941f0edca00ad4280808080f00084100122032900002104200041a8056a41086a220b200341086a290000370300200020043703a80520031029200120002903a805370000200141086a200b290300370000200041a0036a41086a2002290300370300200041a0036a41106a200a290300370300200041a0036a41186a2005290300370300200020002903d8033703a003200041d8036a200041a0036a10a90720002802d803210220002902dc032104200041003602e003200042013703d803200041d8036a41002004420020021b2204422088a7220341306c220a41306d109e012004a7210b2002410820021b210c20002802e003210502402003450d0020002802d80320054105746a2102200c21030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000200541016a2105200241206a2102200341306a2103200a41506a220a0d000b0b200020053602e0030240200b450d00200b41306c450d00200c10290b20002802dc03210320002802d8032102200041b8026a20062005109e0120002802b80220002802c002220a4105746a2002200541057410e4071a2000200a20056a220b3602c0020240200341ffffff3f71450d00200210290b200041d8036a41186a22054200370300200041d8036a41106a220a4200370300200041d8036a41086a22024200370300200042003703d8034196ebca00ad42808080808002841001220329000021042002200341086a290000370300200020043703d8032003102941eaf8ca00ad4280808080900184100122032900002104200041a8056a41086a2206200341086a290000370300200020043703a80520031029200120002903a805370000200141086a2006290300370000200041a0036a41086a2002290300370300200041a0036a41106a200a290300370300200041a0036a41186a2005290300370300200020002903d8033703a003200041d8036a200041a0036a10a90720002802d803210220002902dc032104200041003602e003200042013703d803200041d8036a41002004420020021b2204422088a7220341306c220a41306d109e012004a721062002410820021b210120002802e003210502402003450d0020002802d80320054105746a2102200121030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000200541016a2105200241206a2102200341306a2103200a41506a220a0d000b0b200020053602e00302402006450d00200641306c450d00200110290b20002802dc03210320002802d8032102200041b8026a200b2005109e0120002802b80220002802c002220a4105746a2002200541057410e4071a2000200a20056a3602c0020240200341ffffff3f71450d00200210290b4196ebca00ad4280808080800284100122022900002104200041d0056a41086a2203200241086a290000370300200020043703d0052002102941f7edca00ad4280808080e00084100122022900002104200041a8056a41086a2205200241086a290000370300200020043703a80520021029412010272202450d01200220002903d005370000200220002903a805370010200241086a2003290300370000200241186a220a2005290300370000412010272203450d0120032002290000370000200341186a200a290000370000200341106a200241106a290000370000200341086a200241086a29000037000020004190036a41026a2205200041d8036a41026a2d00003a0000200020002f00d8033b019003200041f0026a41106a42a08080808004370300200041003a008803200020023602fc02200042a080808080043702f402200020033602f0022000418b036a20052d00003a0000200020002f0190033b0089032000200041a8056a36028c03200041d8036a200041f0026a109107024002402000280288042205450d00200041a0036a41186a220a200041d8036a41186a290300370300200041a0036a41106a2206200041d8036a41106a290300370300200041a0036a41086a220b200041d8036a41086a290300370300200020002903d8033703a00320004180046a290300210d20002903f803210e200029028c04210f200041d0056a41186a4200370300200041d0056a41106a22014200370300200041d0056a41086a22024200370300200042003703d00541dcbec500ad42808080808001841001220329000021042002200341086a290000370300200020043703d00520031029419fe3c200ad4280808080d0018410012203290000210420004198056a41086a220c200341086a29000037030020002004370398052003102920012000290398052204370300200041f8046a41086a2002290300370300200041f8046a41106a2004370300200041f8046a41186a200c290300370300200020002903d0053703f804200041a0026a200041f8046a412010e30120004190026a20002903a802200041a0026a41106a290300427f420010e00720002802a0022102200041a8056a41186a2203200a290300370300200041a8056a41106a2006290300370300200041a8056a41086a200b290300370300200020002903a0033703a80520004190026a41086a29030021042000290390022110413810272211450d0320004180026a200e200d2010420020021b2210420120104201562004420020021b22044200522004501b22021b2004420020021b10e007201120002903a8053703082011200f37022c20112005360228201141106a200041a8056a41086a2202290300370300201141186a200041a8056a41106a2205290300370300201141206a2003290300370300201120002903800237030020004281808080103702cc02200020113602c8022003200041f0026a41186a2903003703002005200041f0026a41106a2903003703002002200041f0026a41086a290300370300200020002903f0023703a805200041d8036a200041a8056a10910702400240200028028804220b0d00410121120c010b200041d8036a41286a21134138210a41012106410121030340200041a0036a41186a220c200041d8036a41186a290300370300200041a0036a41106a2214200041d8036a41106a290300370300200041a0036a41086a2215200041d8036a41086a290300370300200020002903d8033703a0032013290300210d200029028c04210e20002903f803210f200041d0056a41186a22164200370300200041d0056a41106a22174200370300200041d0056a41086a22024200370300200042003703d00541dcbec500ad42808080808001841001220529000021042002200541086a290000370300200020043703d00520051029419fe3c200ad4280808080d0018410012205290000210420004198056a41086a2218200541086a2900003703002000200437039805200510292001200029039805370000200141086a2018290300370000200041f8046a41086a2002290300370300200041f8046a41106a2017290300370300200041f8046a41186a2016290300370300200020002903d0053703f804200041e8016a200041f8046a412010e301200041d8016a20002903f001200041e8016a41106a290300427f420010e007200041c8016a200f200d20002903d801420020002802e80122021b220442012004420156200041d8016a41086a290300420020021b22044200522004501b22021b2004420020021b10e007200041d8046a41186a2205200c290300370300200041d8046a41106a220c2014290300370300200041d8046a41086a22142015290300370300200020002903a0033703d80420002903c8012104024020032006470d00200041c8026a2006410110a80120002802c80221110b2011200a6a22022004370300200241086a20002903d80437030020052903002104200c290300210d2014290300210f2002412c6a200e370200200241286a200b360200200241106a200f370300200241186a200d370300200241206a20043703002000200341016a22023602d002200041d8036a200041a8056a1091070240200028028804220b450d00200a41386a210a20002802cc022106200221030c010b0b200341016a21120b024020002802ac05450d0020002802a80510290b0240200041b8056a280200450d0020002802b40510290b20002802cc0221190c010b024020002802f402450d0020002802f00210290b41082111410021120240200028028003450d0020002802fc0210290b410021190b200041a8056a41086a200041b8026a41086a280200360200200020002903b8023703a8052012ad42387e2204422088a70d002004a72202417f4c0d000240024020020d00410821030c010b200210272203450d020b200041003602a803200020033602a0032000200241386e3602a403200041a0036a4100201210a80120002802a803210102402012450d00201241386c210a20002802a003200141386c6a2102201241037441786a410376210b200041d8036a41286a2106200041d8036a41086a2105201121030340200541186a200341206a290300370300200541106a200341186a290300370300200541086a200341106a2903003703002005200341086a290300370300200020032903003703d8032006200341286a10ef02200241306a200041d8036a41306a290300370300200241286a2006290300370300200241206a200041d8036a41206a290300370300200241186a200041d8036a41186a290300370300200241106a200041d8036a41106a290300370300200241086a2005290300370300200220002903d803370300200241386a2102200341386a2103200a41486a220a0d000b2001200b6a41016a21010b4108210a200041d8036a41086a22022001360200200020002903a0033703d803200041c8026a41214100200041a8056a200041d8036a1098020240024020002802c802220b0d0041012118200041013a00dc032000410c3a00d803200041d8036a10cb01200041a0036a2101200041d8036a21060c010b200041dc026a2802002101200041c8026a41106a280200211a200041d4026a280200211b200041c8026a41086a280200211420002802cc02210c42002104200041d8036a41186a4200370300200041d8036a41106a221c420037030020024200370300200042003703d8034196ebca00ad428080808080028410012203290000210d200041d0056a41086a2205200341086a2900003703002000200d3703d0052003102920022005290300370300200020002903d0053703d80341f0edca00ad4280808080f0008410012203290000210d200041a8056a41086a2205200341086a2900003703002000200d3703a80520031029201c20002903a805220d370300200041a0036a41086a2002290300370300200041a0036a41106a200d370300200041a0036a41186a2005290300370300200020002903d8033703a003200041d8036a200041a0036a10a907024020002802d8032202450d00200041a0036aad4280808080800484100420002902dc0321042002210a0b200041003602e003200042013703d803200041d8036a41002004422088a7220241306c220541306d109e012004a7210620002802e003211d02402002450d0020002802d803201d4105746a2102200a21030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000201d41016a211d200241206a2102200341306a2103200541506a22050d000b0b2000201d3602e00302402006450d00200641306c450d00200a10290b20002802dc03211e20002802d803211f42002104200041d8036a41186a22054200370300200041d8036a41106a220642003703004108210a200041d8036a41086a22024200370300200042003703d8034196ebca00ad428080808080028410012203290000210d200041d0056a41086a2215200341086a2900003703002000200d3703d0052003102920022015290300370300200020002903d0053703d80341eaf8ca00ad428080808090018410012203290000210d200041a8056a41086a2215200341086a2900003703002000200d3703a80520031029201c20002903a805370000201c41086a2015290300370000200041a0036a41086a2002290300370300200041a0036a41106a2006290300370300200041a0036a41186a2005290300370300200020002903d8033703a003200041d8036a200041a0036a10a907024020002802d8032202450d00200041a0036aad4280808080800484100420002902dc0321042002210a0b200041003602e003200042013703d803200041d8036a41002004422088a7220241306c220541306d109e012004a7210620002802e003212002402002450d0020002802d80320204105746a2102200a21030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000202041016a2120200241206a2102200341306a2103200541506a22050d000b0b200020203602e00302402006450d00200641306c450d00200a10290b20002802dc03212120002802d8032122024002400240201441306c2203450d00200b21020340200241286a2903002104200241206a290300210d200041d0056a41186a200241186a290000370300200041d0056a41106a200241106a290000370300200041d0056a41086a200241086a290000370300200020022900003703d005200d2004844200520d02200241306a2102200341506a22030d000b0b41012123410021240240200c450d00200c41306c450d00200b10290b410021250c010b200041a8056a41086a2205200041d0056a41086a290300370300200041a8056a41106a220a200041d0056a41106a290300370300200041a8056a41186a2206200041d0056a41186a290300370300200020002903d00522043703a003200020043703a805412010272223450d03202320002903a805370000202341186a2006290300370000202341106a200a290300370000202341086a200529030037000020004281808080103702dc03200020233602d8030240024020034130470d00410121240c010b200241306a2105200b201441306c6a220641506a21144101212403402005210202400340200241286a2903002104200241206a290300210d200041d0056a41186a2203200241186a290000370300200041d0056a41106a2205200241106a290000370300200041d0056a41086a220a200241086a290000370300200020022900003703d005200d2004844200520d012006200241306a2202470d000c030b0b200041f8046a41086a200a2903002204370300200041f8046a41106a2005290300220d370300200041f8046a41186a2003290300220e370300200020002903d005220f3703f804200041a0036a41186a220a200e370300200041a0036a41106a2215200d370300200041a0036a41086a221620043703002000200f3703a0030240202420002802dc03470d00200041d8036a20244101109e0120002802d80321230b200241306a2105202320244105746a220320002903a003370000200341186a200a290300370000200341106a2015290300370000200341086a20162903003700002000202441016a22243602e00320142002470d000b0b0240200c450d00200c41306c450d00200b10290b20002802dc0321250b2000410036029803200042043703900320004190036a41002001412c6c2202412c6d109301201b20026a21162000280298032126200028029003212702400240024020010d00201b21020c010b200041d8036a410c6a210a20272026412c6c6a2103200041a0036a410c6a210b200041d0056a41106a210c200041d8036a4104722106200041a8056a41206a2117200041a8056a41186a2118200041a8056a41086a2113201b21020340200228020021052017200241246a29020037030020182002411c6a290200370300200041a8056a41106a2201200241146a29020037030020132002410c6a2902003703002000200241046a2902003703a805024020050d002002412c6a21020c020b200620002903a805370200200641086a2013290300370200200641106a2001290300370200200641186a2018290300370200200641206a2017290300370200200020053602d803200041f8046a200a10ac07200041d0056a20002802f804222820002802800510fb05200041d0056a41086a2214290300210420002802e005210120002903d005210d20002802e4052115024020002802fc04450d00202810290b2004420020011b210e200d420020011b210d02402001450d00201541ffffff3f71450d002001410120011b10290b200041d0056a41186a22284200370300200c420037030020144200370300200042003703d00541dcbec500ad42808080808001841001220129000021042014200141086a290000370300200020043703d00520011029419fe3c200ad4280808080d0018410012201290000210420004198056a41086a2215200141086a290000370300200020043703980520011029200c200029039805370000200c41086a2015290300370000200041f8046a41086a2014290300370300200041f8046a41106a200c290300370300200041f8046a41186a2028290300370300200020002903d0053703f804200041b0016a200041f8046a412010e301200041a0016a20002903b801200041b0016a41106a290300427f420010e00720004190016a200d200e20002903a001420020002802b00122011b220442012004420156200041a0016a41086a290300420020011b22044200522004501b22011b2004420020011b10e007200041d8046a41086a2201200a41086a290200370300200041d8046a41106a2214200a41106a290200370300200041d8046a41186a2228200a41186a2902003703002000200a2902003703d80420002802dc03212920002802e003212a200042003703f80220002000290390013703f0022000420037038005200042003703f80420002005202a41246c6a3602dc05200020053602d805200020293602d405200020053602d0052000200041f8046a3602e4052000200041f0026a3602e00520004198056a200041d0056a1099020240024020002903f002220420002903f804220d7d222b20045620002903f802220e200029038005220f7d2004200d54ad7d2210200e562010200e511b4101470d00200d20047d2210200d56200f200e7d200d200454ad7d2204200f562004200f511b0d0120002802a0052205450d01200541306c2000280298056a41706a220542002005290300220d20107d220e200e200d56200541086a2205290300220e20047d200d201054ad7d2204200e562004200e511b22291b37030020054200200420291b3703000c010b20002802a0052205450d00200541306c2000280298056a41706a2205427f20052903002204202b7c220d200d2004542229200541086a2205290300220420107c2029ad7c220d200454200d2004511b22291b3703002005427f200d20291b3703000b200b20002903d804370200200041a0036a41086a22052015280200360200200b41186a2028290300370200200b41106a2014290300370200200b41086a2001290300370200200020002903980522043703a003200341286a200041a0036a41286a280200360200200341206a200041a0036a41206a290300370200200341186a200041a0036a41186a290300370200200341106a200041a0036a41106a290300370200200341086a200529030037020020032004370200202641016a21262003412c6a21032002412c6a22022016470d000b20002026360298030c010b200020263602980320022016460d00034020022203412c6a21020240200341046a2802002205450d00200541246c450d00200328020010290b20162002470d000b0b0240201a450d00201a412c6c450d00201b10290b200028029403212c200041d8036a2023202420272026109a0220004190036a41086a200041d8036a41086a2216280200360200200020002903d80337039003200041003602a803200042083703a003200041a0036a41002024410574220241057510900120002802a803212d20002802a003212e02402002450d00202320026a2113202e202d41306c6a2101200041d0056a41106a211541dcbec500ad4280808080800184210f2023210b0340200b41086a2900002104200b41106a290000210d200b290000210e200041d8036a41186a2217200b41186a290000370300200041d8036a41106a2218200d370300201620043703002000200e3703d803024002402000280290032206450d00200b41206a210b200028029403210c0340200641086a210320062f01062214410574210241002105024003402002450d01200041d8036a2003412010e707220a450d04200241606a2102200541016a2105200341206a2103200a417f4a0d000b2005417f6a21140b200c450d01200c417f6a210c200620144102746a41c8056a28020021060c000b0b41cceec90041da0041a8efc9001057000b200041d8046a41186a220a2017290300370300200041d8046a41106a220c2018290300370300200041d8046a41086a22142016290300370300200020002903d8033703d804200620054105746a220241f0026a290300210d200241e8026a290300210e200041d0056a41186a2205420037030020154200370300200041d0056a41086a22024200370300200042003703d005200f1001220329000021042002200341086a290000370300200020043703d00520031029419fe3c200ad4280808080d0018410012203290000210420004198056a41086a2206200341086a2900003703002000200437039805200310292015200029039805370000201541086a2006290300370000200041f8046a41086a2002290300370300200041f8046a41106a2015290300370300200041f8046a41186a2005290300370300200020002903d0053703f804200041f8006a200041f8046a412010e301200041e8006a200029038001200041f8006a41106a290300427f420010e007200041d8006a20002903684200200028027822021b220442012004420156200041e8006a41086a290300420020021b22044200522004501b22021b2004420020021b200e200d10d507200141186a200a290300370300200141106a200c290300370300200141086a2014290300370300200120002903d804370300200141286a200041d8006a41086a29030037030020012000290358370320202d41016a212d200141306a2101200b2013470d000b0b2000202d3602a8030240202541ffffff3f71450d00202310290b20002802a403212f02400240202d410d202d410d491b22300d00200041003602e003200042083703d803200041d8036a4100410010900120002802e00321240c010b203041306c220510272202450d03200041003602e003200020303602dc03200020023602d803200041d8036a4100203010900120002802d80320002802e003222441306c6a2102202e21030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102202441016a2124200341306a2103200541506a22050d000b200020243602e0030b20002802dc03213120002802d80321170240024020244115490d002024410176ad42307e2204422088a70d032004a72232417f4c0d03203210272233450d04200041003602a803200042043703a003201741506a2134201741f07e6a21354104210541002103410021362024212803402028210b410021284101210c0240200b417f6a2206450d000240024002400240024002402017200641306c6a200b41306c220220176a41a07f6a412010e7074100480d00200b417e6a2101203520026a2102410021284100210a034002402001200a470d00200b210c0c080b200a41016a210a200241306a2002412010e7072106200241506a21022006417f4a0d000b200a41016a210c200a417f73200b6a21060c010b2035200b41066c41037422146a210202400340024020064101470d00410021060c020b2006417f6a2106200241306a2002412010e707210a200241506a2102200a4100480d000b0b200b2006490d01200b20244b0d02200b20066b220c4101762201450d00203420146a21022017200641306c6a210a0340200041d8036a41286a2214200a41286a2215290300370300200041d8036a41206a2216200a41206a2218290300370300200041d8036a41186a2213200a41186a2228290300370300200041d8036a41106a2229200a41106a222a290300370300200041d8036a41086a2223200a41086a221b2903003703002000200a2903003703d803200241086a221a2903002104200241106a2225290300210d200241186a2237290300210e200241206a2238290300210f200241286a22392903002110200a2002290300370300201520103703002018200f3703002028200e370300202a200d370300201b200437030020392014290300370300203820162903003703002037201329030037030020252029290300370300201a2023290300370300200220002903d803370300200241506a2102200a41306a210a2001417f6a22010d000b0b024020060d00200621280c050b0240200c41094d0d00200621280c050b200b20244b0d02200b20066b21012017200641306c6a21140340200b2006417f6a2228490d040240200b20286b220c4102490d002017200641306c6a22022017202841306c6a2206412010e707417f4a0d002006290300210420062002290300370300200041d8036a41286a2213200641286a220a290300370300200041d8036a41206a2229200641206a2215290300370300200041d8036a41186a222a200641186a2216290300370300200041d8036a41106a2223200641106a2218290300370300200041d8036a41086a221b200641086a221a290300370300201a200241086a2903003703002018200241106a2903003703002016200241186a2903003703002015200241206a290300370300200a200241286a290300370300200020043703d803410121180240200c4103490d00200641e0006a200041d8036a412010e707417f4a0d004102210a2014210202400340200241286a200241d8006a290300370300200241206a200241d0006a290300370300200241186a200241c8006a290300370300200241106a200241c0006a290300370300200241086a200241386a2903003703002002200241306a22152903003703002001200a460d01200241e0006a2116200a211820152102200a41016a210a2016200041d8036a412010e707417f4a0d020c000b0b200a21180b2006201841306c6a220220002903d803370300200241286a2013290300370300200241206a2029290300370300200241186a202a290300370300200241106a2023290300370300200241086a201b2903003703000b2028450d05201441506a2114200141016a210120282106200c410a4f0d050c000b0b2006200b4180cac700104c000b200b20244180cac700104b000b200b2006417f6a2228490d00200b20244190cac700104b000b2028200b4190cac700104c000b0240203620002802a403470d00200041a0036a20364101108d0120002802a003210520002802a803220321360b200520364103746a2202200c360204200220283602002000200341016a22033602a80320032136024020034102490d000240024003400240024002400240024020052003417f6a4103746a2202280200450d00200341037420056a220141746a28020022062002280204220a4b0d010b20034103490d022002280204210a20052003417d6a22164103746a28020421020c010b41022136200341024d0d0620052003417d6a22164103746a2802042202200a20066a4d0d0041032136200341034d0d06200141646a280200200220066a4b0d050b2002200a490d010b2003417e6a21160b02400240024002400240024002402003201641016a22184d0d00200320164d0d012005201641037422296a2202280204222a20022802006a22022005201841037422236a22032802002213490d02200220244b0d032017201341306c6a22142003280204221541306c22036a210a200241306c2105200220136b220120156b220220154f0d042033200a200241306c220310e407220c20036a210620154101480d0520024101480d05203420056a2103200a210203402003200241506a220a200641506a22012001200a412010e707410048220b1b2205290300370300200341286a200541286a290300370300200341206a200541206a290300370300200341186a200541186a290300370300200341106a200541106a290300370300200341086a200541086a29030037030020062001200b1b210602402014200a2002200b1b2202490d00200c21050c080b200341506a2103200c2105200c2006490d000c070b0b2018200341a0cac7001036000b2016200341b0cac7001036000b2013200241c0cac700104c000b2002202441c0cac700104b000b20332014200310e407220c20036a2106024020154101480d00200120154c0d00201720056a210b200c21052014210203402002200a2005200a2005412010e70741004822011b2203290300370300200241286a200341286a290300370300200241206a200341206a290300370300200241186a200341186a290300370300200241106a200341106a290300370300200241086a200341086a2903003703002005200541306a20011b2105200241306a2102200a41306a200a20011b220a200b4f0d03200620054b0d000c030b0b20142102200c21050c010b200a2102200c21050b20022005200620056b220320034130706b10e4071a024020002802a803220220164d0d0020002802a003220520296a2203202a20156a36020420032013360200200220184d0d02200520236a2203200341086a20022018417f736a41037410e5071a20002002417f6a22033602a803200341014b0d010c030b0b2016200241d0cac7001036000b201820021042000b200321360b20280d000b024020002802a40341ffffffff0171450d00200510290b2032413070210220324130490d0120322002460d01203310290c010b20244102490d002024417f6a2103202441306c20176a41506a21064101210503400240024002400240202420032202417f6a2203490d00202420036b22014102490d032017200241306c6a22022017200341306c6a220a412010e707417f4a0d03200a2903002104200a2002290300370300200041d8036a41286a2215200a41286a220b290300370300200041d8036a41206a2216200a41206a220c290300370300200041d8036a41186a2218200a41186a2214290300370300200041d8036a41106a2213200a41106a2228290300370300200041d8036a41086a2229200a41086a222a290300370300202a200241086a2903003703002028200241106a2903003703002014200241186a290300370300200c200241206a290300370300200b200241286a290300370300200020043703d8034101210220014103490d02200a41e0006a200041d8036a412010e707417f4a0d0241002101200621020340200241286a200241d8006a290300370300200241206a200241d0006a290300370300200241186a200241c8006a290300370300200241106a200241c0006a290300370300200241086a200241386a2903003703002002200241306a220c29030037030020052001220b460d02200b417f6a2101200241e0006a2114200c21022014200041d8036a412010e707417f4a0d020c000b0b2003202441f0c9c700104c000b4102200b6b21020b200a200241306c6a220220002903d803370300200241286a2015290300370300200241206a2016290300370300200241186a2018290300370300200241106a2013290300370300200241086a20292903003703000b200641506a21062005417f6a210520030d000b0b200041003602e003200042083703d803200041d8036a4100202441306c221341306e222810920120002802e003210b0240024020130d0020002802d80321010c010b20002802d8032201200b4104746a21022013210520172103034020022003360200200241086a4200370300200241106a2102200b41016a210b200341306a2103200541506a22050d000b0b2011201241386c6a211520002802dc03212902400240024020120d002011210c0c010b200b41014b2118201121020340200241386a210c20022802282216450d0102402002412c6a290200220e422088a74105742203450d002002290300210d024020180d000240200b0e020200020b2001280200210542102104201621020340024020052002412010e7070d0020012001290308200d200442ffffffff0f837e7c3703080b200241206a21022004427f7c2104200341606a22030d000c020b0b201620036a21144200210420162106024003400240200b450d0041002102200b210303402003410176220520026a220a20022001200a4104746a2802002006412010e7074101481b2102200320056b220341014b0d000b200120024104746a22032802002006412010e7070d00200b20024d0d0220032003290308200d421020047d42ffffffff0f837e7c3703080b200442017c21042014200641206a2206460d020c000b0b2002200b41f4f8ca001036000b0240200e42ffffff3f83500d00201610290b200c2102200c2015470d000c020b0b2015200c460d000340200c41386a21020240200c412c6a28020041ffffff3f71450d00200c41286a28020010290b2002210c20152002470d000b0b02402019450d00201941386c450d00201110290b201720136a210c024002400240200b450d0020012802002203450d000240200b4101460d002001200b4104746a2106200141106a210220012903082104034020022802002205450d012004200241086a290300220d2004200d56220a1b210420032005200a1b2103200241106a22022006470d000b0b0240202941ffffffff0071450d00200110290b20030d01410021130c020b41002113202941ffffffff0071450d01200110290c010b200041f0026a41186a200341186a290000370300200041f0026a41106a200341106a290000370300200041f0026a41086a200341086a290000370300200020032900003703f002410121130b200041003602e003200042013703d803200041d8036a41002028109e0120002802e0032105024002402017200c4722380d0020002802d80321230c010b202441306c210a20002802d803222320054105746a210220172103034020022003290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200541016a2105200241206a2102200341306a2103200a41506a220a0d000b0b20002802dc032139200041003602e003200042083703d803200041d8036a4100202e202d41306c22026a2203202e203041306c220a6a6b41306e10900120002802e003210b02400240202d410d4b0d0020002802d803211b0c010b200a20026b210a20002802d803221b200b41306c6a2102200341506a21030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102200341506a2103200b41016a210b200a41306a220a0d000b0b20002802dc03211a200041003602e003200042013703d803200041d8036a4100200b109e0120002802e003210a02400240200b41306c22060d0020002802d803210c0c010b20002802d803220c200a4105746a2102201b2103034020022003290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200a41016a210a200241206a2102200341306a2103200641506a22060d000b0b20002802dc032133200041d8036a20232005201f201d10e506200041ec036a280200221541ffffff3f712015470d0120154105742201417f4c0d01200041e8036a280200213620002802e403211420002802dc03212d20002802d80321340240024020010d00410121020c010b200110272202450d030b200041003602e003200020023602d8032000200141057622283602dc03200041d8036a41002015109e0120002802e00321160240024020150d0020002802d80321180c010b2015410574210620002802d803221820164105746a210220142103034020022003290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200241206a2102200341206a2103200641606a22060d000b201541057441606a41057620166a41016a21160b20002802dc032102201820162023200510ef060240200241ffffff3f71450d00201810290b200041a8056a41186a2202200041f0026a41186a290300370300200041a8056a41106a2203200041f0026a41106a290300370300200041a8056a41086a2205200041f0026a41086a290300370300200020002903f0023703a8050240024020130d00200041d0056a41186a4200370300200041d0056a41106a22054200370300200041d0056a41086a22024200370300200042003703d0054193d4c800ad4280808080b002841001220329000021042002200341086a290000370300200020043703d0052003102941f8d7ca00ad4280808080d0008410012203290000210420004198056a41086a2206200341086a29000037030020002004370398052003102920052000290398052204370300200041d8046a41086a2002290300370300200041d8046a41106a2004370300200041d8046a41186a2006290300370300200020002903d0053703d804200041d8046aad428080808080048410040c010b200041d8036a41186a2002290300370300200041d8036a41106a2003290300370300200041d8036a41086a2005290300370300200020002903a8053703d803200041f8046a41186a4200370300200041f8046a41106a22054200370300200041f8046a41086a22024200370300200042003703f8044193d4c800ad4280808080b002841001220329000021042002200341086a290000370300200020043703f8042003102941f8d7ca00ad4280808080d00084100122032900002104200041d0056a41086a2206200341086a290000370300200020043703d00520031029200520002903d0052204370300200041a0036a41086a2002290300370300200041a0036a41106a2004370300200041a0036a41186a2006290300370300200020002903f8043703a003412010272202450d03200220002903d803370000200241186a200041d8036a41186a290300370000200241106a200041d8036a41106a290300370000200241086a200041d8036a41086a290300370000200041a0036aad42808080808004842002ad42808080808004841003200210290b0240024020010d00410121030c010b200110272203450d030b41002102200041003602e003200020283602dc03200020033602d803200041d8036a41002015109e0120002802e003211602402015450d002015410574210620002802d80320164105746a21010340200120026a2203201420026a2205290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a2900003700002006200241206a2202470d000b201541057441606a41057620166a41016a21160b20004180056a2016360200200020002903d8033703f804200041d8036a200c200a2022202010e506200041ec036a2802002103200041e8036a280200210520002802e4032102024020002802dc0341ffffff3f71450d0020002802d80310290b200041f8046a200028028005200341057422034105752206109e0120002802f804223720002802800522014105746a2002200310e4071a2000200120066a2225360280050240200541ffffff3f71450d00200210290b02402007450d00200820074105746a2115200041e1036a212a024020240d00200a410574211820004190046a21132008210a0340200a41086a2900002104200a41106a290000210d200a290000210e200041a8056a41186a2206200a41186a290000370300200041a8056a41106a2201200d370300200041a8056a41086a221620043703002000200e3703a805200a41206a210a20182103200c21020240024003402003450d01200041a8056a2002460d02200341606a21032002200041a8056a412010e7072105200241206a210220050d000c020b0b200042003703d80520004280a094a58d1d3703d0052000200041a8056a3602d804200041a0036a200041a8056a200041d0056a200041d8046a10a905200041a0036a41206a290300210420002903b803210d024020002903a0034201520d0020002903a803210e2013200041a0036a41106a290300370300202a20002903a805370000202a41086a2016290300370000202a41106a2001290300370000202a41186a20062903003700002000200e37038804200041003a00e003200041033a00d803200041d8036a10cb010b200041286a200d20041081022000290328a7450d00200041286a41106a29030021042000290330210d200042f0f2bda1a7ee9cb9f9003703a003200041d8036a200041a0036a108202200041d8036a200d2004108002200041d8036a41186a20043703002000200d3703e803200041063a00e0032000410e3a00d803200041d8036a10cb010b200a2015470d000c020b0b200a41057421282024410146212920004190046a211d200821010340200141086a2900002104200141106a290000210d2001290000210e200041a8056a41186a2216200141186a290000370300200041a8056a41106a2218200d370300200041a8056a41086a221320043703002000200e3703a80541002103024020290d0041002103202421050340200041d8036a41186a20172005410176220a20036a220641306c6a220241186a290000370300200041d8036a41106a200241106a290000370300200041d8036a41086a200241086a290000370300200020022900003703d80320062003200041d8036a200041a8056a412010e7074101481b21032005200a6b220541014b0d000b0b200141206a2101200041d8036a41186a220a2017200341306c6a220241186a290000370300200041d8036a41106a200241106a290000370300200041d8036a41086a200241086a290000370300200020022900003703d80320282103200c21020240200041d8036a200041a8056a412010e707450d00024003402003450d01200041a8056a2002460d02200341606a21032002200041a8056a412010e7072105200241206a210220050d000c020b0b200042003703d80520004280a094a58d1d3703d0052000200041a8056a3602d804200041a0036a200041a8056a200041d0056a200041d8046a10a905200041a0036a41206a290300210420002903b803210d024020002903a0034201520d0020002903a803210e201d200041a0036a41106a290300370300202a20002903a805370000202a41086a2013290300370000202a41106a2018290300370000202a41186a20162903003700002000200e37038804200041003a00e003200041033a00d803200041d8036a10cb010b200041c0006a200d20041081022000290340a7450d00200041c0006a41106a29030021042000290348210d200042f0f2bda1a7ee9cb9f9003703a003200041d8036a200041a0036a108202200041d8036a200d2004108002200a20043703002000200d3703e803200041063a00e0032000410e3a00d803200041d8036a10cb010b20012015470d000b0b0240200941ffffff3f71450d00200810290b20002802fc04211602402025450d0020254105742103200041e1036a210520004190046a2115203721020340200241086a2900002104200241106a290000210d2002290000210e200041a8056a41186a220a200241186a290000370300200041a8056a41106a2206200d370300200041a8056a41086a220120043703002000200e3703a805200042003703d80520004280a094a58d1d3703d0052000200041a8056a3602d804200041a0036a200041a8056a200041d0056a200041d8046a10a905200041a0036a41206a290300210420002903b803210d024020002903a0034201520d0020002903a803210e2015200041a0036a41106a290300370300200520002903a805370000200541086a2001290300370000200541106a2006290300370000200541186a200a2903003700002000200e37038804200041003a00e003200041033a00d803200041d8036a10cb010b200041106a200d200410810202402000290310a7450d00200041106a41106a29030021042000290318210d200042f0f2bda1a7ee9cb9f9003703a003200041d8036a200041a0036a108202200041d8036a200d2004108002200041d8036a41186a20043703002000200d3703e803200041063a00e0032000410e3a00d803200041d8036a10cb010b200241206a2102200341606a22030d000b0b0240201641ffffff3f71450d00203710290b200041d8036a41186a22034200370300200041d8036a41106a22054200370300200041d8036a41086a22024200370300200042003703d8034196ebca00ad4280808080800284220410012206290000210d200041d0056a41086a220a200641086a2900003703002000200d3703d005200610292002200a290300370300200020002903d0053703d80341f0edca00ad4280808080f0008410012201290000210d200041a8056a41086a2206200141086a2900003703002000200d3703a80520011029201c20002903a805370000201c41086a22152006290300370000200041a0036a41086a22162002290300370300200041a0036a41106a22182005290300370300200041a0036a41186a22132003290300370300200020002903d8033703a003200041203602dc032000200041a0036a3602d80320172024200041d8036a10c906200342003703002005420037030020024200370300200042003703d8032004100122012900002104200a200141086a290000370300200020043703d005200110292002200a290300370300200020002903d0053703d80341eaf8ca00ad42808080809001841001220a29000021042006200a41086a290000370300200020043703a805200a1029201c20002903a80537000020152006290300370000201620022903003703002018200529030037030020132003290300370300200020002903d8033703a003200041203602dc032000200041a0036a3602d803201b200b200041d8036a10c9062024ad42307e2204422088a70d012004a72202417f4c0d010240024020020d00410821030c010b200210272203450d030b200041003602e003200020033602d8032000200241306e3602dc03200041d8036a4100202410900120002802e00321050240024020380d0020002802d80321010c010b202441306c210a20002802d8032201200541306c6a2102201721030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102200541016a2105200341306a2103200a41506a220a0d000b0b2005ad42307e2204422088a70d012004a72202417f4c0d0120002802dc0321060240024020020d00410821030c010b200210272203450d030b200041003602e003200020033602d8032000200241306e3602dc03200041d8036a4100200510900120002802e003210a0240200541306c2205450d0020002802d803200a41306c6a2102200121030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102200a41016a210a200341306a2103200541506a22050d000b0b200041ab036a200a360000200020002903d8033700a303200041a7036a29000021042000410c3a00d803200041d8036a410c6a2004370000200041003a00dc03200020002900a0033700dd03200041d8036a10cb0102402006450d00200641306c450d00200110290b0240203641ffffff3f71450d00201410290b0240202d41ffffff3f71450d00203410290b0240203341ffffff3f71450d00200c10290b0240201a450d00201a41306c450d00201b10290b0240203941ffffff3f71450d00202310290b02402031450d00203141306c450d00201710290b0240202f450d00202f41306c450d00202e10290b02400240200028029003220a0d0041002106200041ec036a4100360200200041003602dc030c010b20002802980321060240024020002802940322030d00200a21020c010b20032102200a2105034020052802c80521052002417f6a22020d000b200a21020340200220022f01064102746a41c8056a28020021022003417f6a22030d000b2005210a0b200041f4036a20022f0106360200200041f0036a4100360200200041ec036a2002360200200041003602e803200042003703e0032000200a3602dc03200041003602d8030b200020063602f803200041d8036a10b90202402026450d002026412c6c21032027210203400240200241046a2802002205450d00200541306c450d00200228020010290b2002412c6a2102200341546a22030d000b0b0240202c450d00202c412c6c450d00202710290b0240202141ffffff3f71450d00202210290b41002118200041d8036a2106200041a0036a2101201e41ffffff3f71450d00201f10290b200041d8036a41186a220b4200370300200041d8036a41106a22024200370300200041d8036a41086a22034200370300200042003703d8034196ebca00ad428080808080028422041001220a290000210d200041d0056a41086a2205200a41086a2900003703002000200d3703d005200a1029200641086a220c2005290300370000200620002903d00537000041e0f8ca00ad4280808080a0018410012214290000210d200041a8056a41086a220a201441086a2900003703002000200d3703a80520141029200220002903a805220d370300200041a0036a41086a22142003290300370300200041a0036a41106a2215200d370300200041a0036a41186a2216200a290300370300200020002903d8033703a0032001ad42808080808004841004200b42003703002002420037030020034200370300200042003703d803200410012217290000210d2005201741086a2900003703002000200d3703d00520171029200c2005290300370000200620002903d00537000041d4e9cb00ad4280808080e00184220d10012217290000210e200a201741086a2900003703002000200e3703a80520171029200220002903a805220e370300201420032903003703002015200e3703002016200a290300370300200020002903d8033703a003200041086a2001412010fc0120002802082117200028020c2113200b42003703002002420037030020034200370300200042003703d80320041001220129000021042005200141086a290000370300200020043703d00520011029200c2005290300370000200620002903d005370000200d100122052900002104200a200541086a290000370300200020043703a80520051029200220002903a805220437030020142003290300370300201520043703002016200a290300370300200020002903d8033703a0032000201341016a410120171b3602d803200041a0036aad4280808080800484200041d8036aad4280808080c0008410030240024020002802c80222020d0020180d010c040b2018450d03024020002802cc022203450d00200341306c450d00200210290b200041d4026a280200210a0240200041dc026a2802002202450d002002412c6c2103200a210203400240200241046a2802002205450d00200541246c450d00200228020010290b2002412c6a2102200341546a22030d000b0b200041d8026a2802002202450d002002412c6c450d00200a10290b02402012450d00201241386c21032011412c6a210203400240200228020041ffffff3f71450d002002417c6a28020010290b200241386a2102200341486a22030d000b0b02402019450d00201941386c450d00201110290b200941ffffff3f71450d02200810290c020b1038000b1039000b200041f0056a24000b930605047f017e017f017e0a7f230041f0016b22022400200241d0006a41186a22034200370300200241d0006a41106a22044200370300200241d0006a41086a220542003703002002420037035041c99fc500ad42808080809001842206100122072900002108200241f0006a41086a2209200741086a2900003703002002200837037020071029200520092903003703002002200229037037035041d892c700ad4280808080c001841001220729000021082009200741086a2900003703002002200837037020071029200420022903702208370300200241306a41086a220a2005290300370300200241306a41106a220b2008370300200241306a41186a220c200929030037030020022002290350370330200241f0006a200241306a10a305410321070240024020022d009001220d4103470d00411610d5042109200241086a411610d60420022903082108200041026a20093a0000200041113a0001200041046a20083702000c010b200241306aad428080808080048422081004200241106a41086a220e2009290300370300200241106a41106a220f200241f0006a41106a2210290300370300200241106a41186a2211200241f0006a41186a2212290300370300200220022903703703102003420037030020044200370300200542003703002002420037035020061001220729000021062009200741086a2900003703002002200637037020071029200520092903003703002002200229037037035041b092c700ad4280808080d002841001220729000021062009200741086a290000370300200220063703702007102920042002290370370000200441086a2009290300370000200a2005290300370300200b2004290300370300200c200329030037030020022002290350370330200241013a00702008200241f0006aad428080808010841003200941023a0000200241093a0070200241f0006a10cb01201220112903003703002010200f2903003703002009200e2903003703002002200229031037037020014180ce186a200241f0006a200d4180840710a405410421070b200020073a0000200241f0016a24000bf31b06057f017e017f017e127f097e230022022103200241a0046b41607122022400200241a0016a41186a4200370300200241a0016a41106a22044200370300200241a0016a41086a22054200370300200242003703a00141c99fc500ad4280808080900184100122062900002107200241f8006a41086a2208200641086a290000370300200220073703782006102920052008290300370300200220022903783703a00141a88dc700ad4280808080b001841001220629000021072008200641086a2900003703002002200737037820061029200420022903782207370300200241d8006a41086a2005290300370300200241d8006a41106a2007370300200241d8006a41186a2008290300370300200220022903a001370358200241203602b4022002200241d8006a3602b002200241b8026a200241d8006aad428080808080048422091007108b02024002400240024002400240024020022802b802220a0d004100210b0c010b20022802bc02210c2002200241b8026a41086a2802003602cc022002200a3602c802200241d0006a200241c8026a10c8010240024020022802500d002002280254220d20022802cc02220e41c4006e22082008200d4b1bad42c4007e2207422088a70d042007a72208417f4c0d040240024020080d004104210b0c010b20081027220b450d040b200241003602d8022002200b3602d0022002200841c4006e3602d40202400240200d450d004100210f41002110034002400240200e4104490d00200220022802c802221141046a3602c8022011280000211241002108200241003a00c001200e417c6a21060240024002400240034020062008460d01200241a0016a20086a201120086a220541046a2d00003a00002002200541056a3602c8022002200841016a22053a00c0012005210820054120470d000b20024180046a41186a2213200241a0016a41186a221429030037030020024180046a41106a2215200241a0016a41106a221629030037030020024180046a41086a2217200241a0016a41086a2218290300370300200220022903a0013703800441002108200241003a00c001201120056a21192005200e6b41046a210e0340200e20086a450d02200241a0016a20086a201920086a221141046a2d00003a00002002201141056a3602c8022002200841016a22113a00c0012006417f6a21062011210820114120470d000b200241f8006a41186a22082014290300370300200241f8006a41106a22112016290300370300200241f8006a41086a220e2018290300370300200241e0036a41086a22192017290300370300200241e0036a41106a221a2015290300370300200241e0036a41186a221b2013290300370300200220022903a00137037820022002290380043703e0032014201b2903003703002016201a29030037030020182019290300370300200220022903e0033703a00120132008290300370300201520112903003703002017200e2903003703002002200229037837038004200620056b210e410021082012211a0c050b200841ff0171450d020c010b200841ff0171450d010b200241003a00c0010b4100210e0b410121080b200241c0036a41086a2205200241a0016a41086a290300370300200241c0036a41106a2206200241a0016a41106a290300370300200241c0036a41186a2211200241a0016a41186a290300370300200241a0036a41086a221920024180046a41086a290300370300200241a0036a41106a221220024180046a41106a290300370300200241a0036a41186a221320024180046a41186a290300370300200220022903a0013703c00320022002290380043703a00320080d02201041016a211020024180036a41186a2214201129030037030020024180036a41106a2211200629030037030020024180036a41086a22062005290300370300200241e0026a41086a22052019290300370300200241e0026a41106a22192012290300370300200241e0026a41186a22122013290300370300200220022903c00337038003200220022903a0033703e0020240200f20022802d402470d00200241d0026a200f4101109f0120022802d002210b20022802d802210f0b200b200f41c4006c6a2208201a36020020082002290380033702042008410c6a2006290300370200200841146a20112903003702002008411c6a2014290300370200200820022903e0023702242008412c6a2005290300370200200841346a20192903003702002008413c6a20122903003702002002200f41016a220f3602d8022010200d470d000b2002200e3602cc020b20022902d4022107200b450d010c020b2002200e3602cc02024020022802d4022208450d00200841c4006c450d00200b10290b0b4100210b2002410036028001200242013703782002410d360284042002200241b0026a360280042002200241f8006a3602e003200241b4016a4101360200200242013702a401200241f4eaca003602a001200220024180046a3602b001200241e0036a41a8a3c800200241a0016a10371a2002350280014220862002350278841008200228027c450d00200228027810290b200c450d00200a10290b200b4104200b1b2110024020074200200b1b221c422088a7220b450d00200241386a201028020010a505200241386a41106a2903004200200228023822081b21072002290340420020081b211d0240200b4101470d002002201d3703a00141002111200241003602b001200220073703a8010c040b201041c4006a2108200b41c4006c41bc7f6a210e41002111200241206a41106a21192010210f410121060340200241206a200828020010a505200720192903004200200228022022051b221e201d2002290328420020051b221f562007201e562007201e511b22051b2107201d201f20051b211d200f200820051b210f2011200620051b2111200641016a2106200841c4006a2108200e41bc7f6a220e0d000b2002201d3703a001200220113602b001200220073703a801200f0d030b411610d5042108200241186a411610d60420022903182107200041026a20083a000020004183223b0100200041046a2007370200201ca72202450d03200241c4006c450d0320101029200324000f0b1039000b1038000b2011200b4f0d012010201141c4006c6a220841186a2206290200211d2010200b417f6a221141c4006c6a220541c0006a280200210f200541206a290200211e200541286a290200211f200541306a2902002120200541386a29020021212005290200212220052902082107200529021021232006200541186a290200370200200829021021242008202337021020082902082123200820073702082008290200210720082022370200200841386a2021370200200841306a2020370200200841286a201f370200200841206a2205280200210b2005201e370200200841c0006a200f360200200220243703b001200220233703a801200220073703a0012002201d3703b80120024180046a41186a20022802bc0136020020024180046a41106a20022902b40137030020024180046a41086a20022902ac01370300200220022902a40137038004200241a0016a41186a220f4200370300200241a0016a41106a220e4200370300200241a0016a41086a22054200370300200242003703a00141c99fc500ad428080808090018410012206290000211d200241f8006a41086a2208200641086a2900003703002002201d3703782006102920052008290300370300200220022903783703a00141a88dc700ad4280808080b0018410012206290000211d2008200641086a2900003703002002201d3703782006102920042002290378370000200441086a2008290300370000200241d8006a41086a2005290300370300200241d8006a41106a200e290300370300200241d8006a41186a200f290300370300200220022903a001370358200241a0016a2010201110a605200920023502a80142208620022802a0012208ad841003024020022802a401450d00200810290b2007a7210e0240201ca72208450d00200841c4006c450d00201010290b200241f8006a200e10a705200241a0016a20022802782208200228028001220510a805024020022802a001220f450d002005ad4220862008ad8410040b200228027c210502400240200f0d002005450d01200810290c010b200241b8016a2903002107200241b0016a290300211d200241a8016a280200211920022802a401211002402005450d00200810290b02402019410574450d00201d200784500d00200241a9016a210520194105742106200241d8016a2111200f210803402002201d3703e003200220073703e803200220083602c003200241f8006a2008200241e0036a200241c0036a10ea03024020022903784201520d00200229038001211e200841186a290000211f200841106a290000211c200841086a2900002109200829000021202011200241f8006a41106a29030037030020052020370000200541086a2009370000200541106a201c370000200541186a201f370000200241003a00a801200241033a00a0012002201e3703d001200241a0016a10cb010b200841206a2108200641606a22060d000b0b200241c8016a2007370300200241c0016a201d370300200241a0016a41186a22082019360200200241b4016a2010360200200241a0016a41106a2205200f360200200241ac016a200e360200200241a0016a41086a220641013a0000200241093a00a001200241a0016a10cb01200820024180046a41186a280200360200200520024180046a41106a290300370300200620024180046a41086a29030037030020022002290380043703a0012002200b3602bc0120014180ce186a200241a0016a41004180840710a4050b200041043a00000b200324000f0b2011200b103e000be50301027f230041206b22012400412621020240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710e28000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627000b200141146a41013602002001420137020420014198e3ca003602002001410436021c200141bcd4c8003602182001200141186a36021020014180a6cc001040000b410021020c250b410121020c240b410221020c230b410321020c220b410421020c210b410521020c200b410621020c1f0b410721020c1e0b410821020c1d0b410921020c1c0b410a21020c1b0b410b21020c1a0b410c21020c190b410d21020c180b410e21020c170b410f21020c160b411021020c150b411121020c140b411221020c130b411321020c120b411421020c110b411521020c100b411621020c0f0b411721020c0e0b411821020c0d0b411921020c0c0b411a21020c0b0b411b21020c0a0b411c21020c090b411d21020c080b411e21020c070b411f21020c060b412021020c050b412121020c040b412221020c030b412321020c020b412421020c010b412521020b200141206a240020020bf00501037f230041206b22022400419b9cc5002103410f21040240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141ff017122010e28000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627000b200241146a41013602002002420137020420024198e3ca003602002002410436021c200241bcd4c8003602182002200241186a36021020024180a6cc001040000b41c19fc5002103410821040c250b41ced6c80021030c240b41b99fc5002103410821040c230b41b19fc5002103410821040c220b41a29fc50021030c210b41ddd6c8002103411121040c200b418f9fc5002103411321040c1f0b41fe9ec5002103411121040c1e0b41f39ec5002103410b21040c1d0b41e99ec5002103200121040c1c0b41dc9ec5002103410d21040c1b0b41d09ec5002103200121040c1a0b41c69ec5002103410a21040c190b41ba9ec5002103410c21040c180b41a99ec5002103411121040c170b419e9ec5002103410b21040c160b419dd6c8002103410821040c150b41969ec5002103410821040c140b41879ec50021030c130b41f69dc5002103411121040c120b41e79dc50021030c110b41dc9dc5002103410b21040c100b41d39dc5002103410921040c0f0b41c99dc5002103410a21040c0e0b41c29dc5002103410721040c0d0b41b99dc5002103410921040c0c0b41b09dc5002103410921040c0b0b41a89dc5002103410821040c0a0b419c9dc5002103410c21040c090b418b9dc5002103411121040c080b41839dc5002103410821040c070b41fa9cc5002103410921040c060b41e99cc5002103411121040c050b41dc9cc5002103410d21040c040b41d29cc5002103410a21040c030b41c19cc5002103411121040c020b41b99cc5002103410821040c010b41aa9cc50021030b2000200436020420002003360200200241206a24000bf21201277f230041f0046b220324000240024002402001280200220420012802044f0d00200341d7036a210520034184026a21062003418c046a2107200341d0036a4101722108200341b1046a220941036a210a03402001200441016a360200200341c0026a200410dd04200341d0036a20032802c002220b20032802c80210d305200341b8046a41086a220c200841086a290000370300200341b8046a41106a220d200841106a290000370300200341b8046a41186a220e200841186a290000370300200341b8046a41206a220f200841206a290000370300200341b8046a41286a2210200841286a290000370300200341b8046a412f6a22112008412f6a290000370000200341e8026a41086a2212200741086a290000370300200341e8026a41106a2213200741106a290000370300200341e8026a41186a2214200741186a290000370300200341e8026a41206a2215200741206a280000360200200320082900003703b804200320072900003703e802200328028804211620032d00d0032117200320092800003602d8012003200a2800003600db010240201741024622180d0020032d00b004211920034180026a412f6a201129000037000020034180026a41286a201029030037030020034180026a41206a200f29030037030020034180026a41186a200e29030037030020034180026a41106a200d29030037030020034180026a41086a200c290300370300200341a8036a41086a2012290300370300200341a8036a41106a2013290300370300200341a8036a41186a2014290300370300200341a8036a41206a2015280200360200200320032903b80437038002200320032903e8023703a803200320032800db013600a303200320032802d8013602a0032016211a0b024020032802c402450d00200b10290b200c20034180026a41086a221b290300370300200d20034180026a41106a221c290300370300200e20034180026a41186a221d290300370300200f20034180026a41206a221e290300370300201020034180026a41286a221f290300370300201120034180026a412f6a290000370000200341d8016a41086a2220200341a8036a41086a220b290300370300200341d8016a41106a2221200341a8036a41106a2216290300370300200341d8016a41186a2222200341a8036a41186a2223290300370300200341d8016a41206a2224200341a8036a41206a222528020036020020032003290380023703b804200320032903a8033703d801200320032800a3033600d301200320032802a0033602d001200341d0036a41086a2226200c290300370300200341d0036a41106a2227200d290300370300200341d0036a41186a220d200e290300370300200341d0036a41206a220e200f290300370300200341d0036a41286a220f2010290300370300200341d0036a412f6a2011290000370000200320032903b8043703d003200b2020290300370300201620212903003703002023202229030037030020252024280200360200200320032903d8013703a803200320032800d3013600a303200320032802d0013602a00302400240024020180d002017410171450d010b4103210c0c010b20062005290000370000200641286a200541286a290000370000200641206a200541206a290000370000200641186a200541186a290000370000200641106a200541106a290000370000200641086a200541086a290000370000200341c0026a41086a2210200b290300370300200341c0026a41106a22112016290300370300200341c0026a41186a22172023290300370300200341c0026a41206a220b2025280200360200200320032903a8033703c0022012201b2902003703002013201c2902003703002014201d2902003703002015201e290200370300200341e8026a41286a2216201f290200370300200341e8026a41306a222320034180026a41306a280200360200200320032800a3033600bb02200320032802a0033602b80220032003290280023703e8024103210c201941ff01714103460d002026201229030037030020272013290300370300200d2014290300370300200e2015290300370300200f2016290300370300200341d0036a41306a22162023280200360200201b2010290300370300201c2011290300370300201d2017290300370300201e200b280200360200200320032903e8023703d003200320032903c00237038002200320032800bb023600ab03200320032802b8023602a8034103210c201a2002280200280200470d0020034198016a41306a201628020036020020034198016a41286a200f29030037030020034198016a41206a200e29030037030020034198016a41186a200d29030037030020034198016a41106a202729030037030020034198016a41086a2026290300370300200341f0006a41086a201b290300370300200341f0006a41106a201c290300370300200341f0006a41186a201d290300370300200341f0006a41206a201e280200360200200320032903d003370398012003200329038002370370200320032800ab0336006b200320032802a80336026820042128201a21292019210c0b200c41ff01714103470d02200128020022042001280204490d000b0b200041033a00600c010b200341306a41306a220820034198016a41306a280200360200200341306a41286a220720034198016a41286a290300370300200341306a41206a220d20034198016a41206a290300370300200341306a41186a220e20034198016a41186a290300370300200341306a41106a220f20034198016a41106a290300370300200341306a41086a221020034198016a41086a290300370300200341086a41086a2211200341f0006a41086a290300370300200341086a41106a2201200341f0006a41106a290300370300200341086a41186a2204200341f0006a41186a290300370300200341086a41206a2205200341f0006a41206a2802003602002003200329039801370330200320032903703703082003200328006b3600032003200328026836020020002028360200200020032903303702042000410c6a2010290300370200200041146a200f2903003702002000411c6a200e290300370200200041246a200d2903003702002000412c6a2007290300370200200041346a2008280200360200200020293602382000200329030837023c200041c4006a2011290300370200200041cc006a2001290300370200200041d4006a2004290300370200200041dc006a20052802003602002000200c3a0060200041e4006a2003280003360000200020032802003600610b200341f0046a24000b9f0303027f017e027f230041206b2202240041c99fc500ad4280808080900184100122032900002104200241086a200341086a290000370300200220043703002003102941c08ec700ad4280808080900184100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000bd70b06057f017e057f017e027f037e230041a0016b220324002003200236021420032001360210200341186a2002ad4220862001ad841007108b020240024002400240200328021822010d00200041023a00000c010b200328021c21042003200341206a280200220236024c20032001360248024002402002450d0020012d0000210520032002417f6a220636024c2003200141016a360248200541014b0d000240024002400240024020050e020001000b20064104490d04200341c4006a41026a200341d8006a41026a2d00003a0000200341286a41086a200341f8006a41086a290300370300200341286a41106a200341f8006a41106a290300370300200341286a41186a200341f8006a41186a280200360200200320032f00583b0144200320032903783703282001280001210520032002417b6a36024c2003200141056a360248410021020c010b200341086a200341c8006a10c80120032802080d03200328024c2207200328020c2205490d032005417f4c0d060240024020050d0042002108410121090c010b2005102d2209450d08200920032802482202200510e4071a2003200720056b220736024c2003200220056a3602482005ad21080b2009450d0341002102200341003a0098012005ad4220862008842208422088a7210a2008a7210b417f21050240024002400240034020072002460d01200341f8006a20026a2003280248220c2d00003a00002003200720056a36024c2003200c41016a3602482003200241016a22063a0098012005417f6a21052006210220064120470d000b200341d2006a20032d007a3a0000200341e0006a20034187016a290000370300200341d8006a41106a2003418f016a290000370300200341f0006a20034197016a2d00003a0000200320032f01783b01502003200329007f370358200720066b22024110490d01200328007b21052003200c41116a3602482003200241706a220d36024c200d4104490d05200c41096a290000210e200c29000121082003200c41156a36024820032002416c6a36024c2007416c6a2006460d05200c28001121062003200c41166a36024820032002416b6a220f36024c200c2d0015221041014b0d054100210d20100e020302030b200241ff0171450d00200341003a0098010b200b0d040c050b200f4104490d022003200c411a6a3602482003200241676a36024c200c28001621074101210d0b200341c4006a41026a200341d0006a41026a2d00003a0000200341286a41086a200341d8006a41086a290300370300200341286a41106a200341d8006a41106a290300370300200341286a41186a200341d8006a41186a2d00003a0000200341c3006a200341d5006a41026a2d00003a0000200320032f01503b014420032003290358370328200320032f00553b0041410121020b200341d8006a41026a200341c4006a41026a2d0000220c3a0000200341f8006a41086a200341286a41086a2903002211370300200341f8006a41106a200341286a41106a2903002212370300200341f8006a41186a200341286a41186a2802002210360200200320032f0144220f3b0158200320032903282213370378200041036a200c3a00002000200f3b0001200041046a2005360000200041c8006a200e370000200041c0006a2008370000200041086a2013370000200041106a2011370000200041186a2012370000200041206a2010360000200041386a2007360000200041346a200d360000200041306a20063600002000412c6a200a360000200041286a200b360000200041246a20093600000c030b200b450d010b200910290b20034100360230200342013703282003410d36025c2003200341106a3602582003200341286a3602502003418c016a41013602002003420137027c200341f4eaca003602782003200341d8006a36028801200341d0006a41a8a3c800200341f8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b410221020b200020023a00002004450d00200110290b200341a0016a24000f0b1038000b1039000b981303077f057e057f230041d0086b22032400200341f8006a200110d804200341f8056a20032802782204200328028001220510d90441022106024020032d00f805220741024622080d002005ad4220862004ad8410040b200341a8036a411f6a220520034198066a280000360000200341a8036a41186a220920034191066a290000370300200341a8036a41106a20034189066a290000220a370300200341a8036a41086a20034181066a290000220b370300200320032900f905220c3703a803200341c0066a290300210d200341b8066a290300210e2003419c066a280200210f200341a0066a2802002110200341a4066a2802002111200341f8056a411f6a22122005280000360000200341f8056a41186a22052009290300370300200341f8056a41106a2209200a370300200341f8056a41086a2213200b3703002003200c3703f805024020080d00200341306a411f6a2012280000360000200341306a41186a2005290300370300200341306a41106a2009290300370300200341306a41086a2013290300370300200320032903f805370330200721060b0240200328027c450d00200410290b0240024002400240200641037122064103460d0020060e03010001010b200341d8006a41186a200341306a41186a290300370300200341d8006a41106a200341306a41106a290300370300200341d8006a41086a200341306a41086a29030037030020032003290330370358200320113602a4032003200f3602a003200341f8006a200341a0036a10e40302402003280278411c460d00200341a8036a200341f8006a41a80210e4071a2003200e3703d0052003200d3703d8050240200e200d84500d002003200341d8006a3602a408200341a8086a200341d8006a200341d0056a200341a4086a10ea0320032903a8084201520d0020032903b008210a200341b0066a200341a8086a41106a290300370300200341a8066a200a370300200341f8056a41086a41003a000020034181066a200329035837000020034189066a200341d8006a41086a29030037000020034191066a200341d8006a41106a29030037000020034199066a200341f0006a290300370000200341033a00f805200341f8056a10cb010b200341f8056a41086a2206410c3a0000200341a1066a2003290358370000200341f8056a41096a2207200129000037000020034189066a200141086a29000037000020034191066a200141106a29000037000020034199066a200141186a290000370000200341a9066a200341d8006a41086a290300370000200341b1066a200341d8006a41106a290300370000200341b9066a200341d8006a41186a290300370000200341093a00f805200341d0066a200d370300200341c8066a200e370300200341f8056a10cb01200341f8056a200341a8036a41a80210e4071a200341003b01a808200341d0056a200341f8056a200341a8086a10c50120032903d005210a200341f8056a410c6a20023602002007200a503a0000200641073a0000200341093a00f805200341f8056a10cb01200041043a000020100d020c030b2003200e3703a8082003200d3703b0080240024002400240200e200d844200520d00200342003703d805200342003703d0050c010b2003200341d8006a3602d005200341a8036a200341d8006a200341a8086a200341d0056a10a905200341c8036a290300210a20032903c003210b024020032903a8034201520d0020032903b003210c200341b0066a200341a8036a41106a290300370300200341a8066a200c370300200341f8056a41086a41003a000020034181066a200329035837000020034189066a200341d8006a41086a29030037000020034191066a200341d8006a41106a29030037000020034199066a200341f0006a290300370000200341033a00f805200341f8056a10cb010b2003200b3703d0052003200a3703d805200b200a844200520d010b200341f8056a41186a22054200370300200341f8056a41106a22044200370300200341f8056a41086a22074200370300200342003703f80541dcbec500ad4280808080800184220a10012208290000210b200341a8086a41086a2206200841086a2900003703002003200b3703a8082008102920072006290300370300200320032903a8083703f805419fe3c200ad4280808080d00184220b10012208290000210c2006200841086a2900003703002003200c3703a80820081029200420032903a808220c370300200341a8036a41086a22092007290300370300200341a8036a41106a2212200c370300200341a8036a41186a22132006290300370300200320032903f8053703a803200341106a200341a8036a412010e301200341106a41106a290300210c2003290318210d20032802102108200542003703002004420037030020074200370300200342003703f805200a10012205290000210a2006200541086a2900003703002003200a3703a8082005102920072006290300370300200320032903a8083703f805200b10012205290000210a2006200541086a2900003703002003200a3703a80820051029200420032903a808220a370300200920072903003703002012200a37030020132006290300370300200320032903f8053703a8032003200c420020081b370380062003200d420020081b3703f805200341a8036aad4280808080800484200341f8056aad428080808080028410030c010b200342f0f2bda1a7ee9cb9f9003703a803200341f8056a200341a8036a108202200341f8056a200b200a10800220034190066a200a37030020034188066a200b37030020034180066a41063a00002003410e3a00f805200341f8056a10cb010b200341f8056a41086a410d3a0000200341a4066a20023602002001290000210a200341093a00f805200341f8056a41096a200a37000020034189066a200141086a29000037000020034191066a200141106a29000037000020034199066a200141186a290000370000200341f8056a10cb01411510d5042101200341086a411510d6042003290308210a200041026a20013a000020004183223b0100200041046a200a37020020100d010c020b200341f8056a41086a410e3a0000200341a4066a20023602002001290000210a200341093a00f805200341f8056a41096a200a37000020034189066a200141086a29000037000020034191066a200141106a29000037000020034199066a200141186a290000370000200341f8056a10cb01411310d5042101200341286a411310d6042003290328210a200041026a20013a000020004183223b0100200041046a200a3702000240200741037122014103460d0020010e03020002020b2010450d010b200f10290b200341d0086a24000b880202037f017e230041106b220224000240024020002d00004101460d00200241003a000020012002410110722002200041046a28020036020020012002410410720c010b200241013a00002001200241011072200041246a28020021032000412c6a28020022042001107120012003200410722001200041016a41201072200041c0006a29030021052002200041c8006a2903003703082002200537030020012002411010722002200041306a28020036020020012002410410720240200041346a2802004101460d00200241003a000020012002410110720c010b200241013a000020012002410110722002200041386a28020036020020012002410410720b200241106a24000ba20601067f230041f0026b22082400200841186a200110c601200841106a2008280218220920082802204180a6cc004100410010c7012008280210210a0240200828021c450d00200910290b024002400240024002400240200a4101460d000240024020034101460d004100210b0c010b2004410047200541014b71210b2005417f6a210c0b2001280208220a417f4c0d012001280200210d02400240200a0d0041002109410121050c010b200a10272205450d03200a21090b024002402009200a490d00200921030c010b20094101742203200a2003200a4b1b22034100480d04024020090d002003102722050d010c070b20092003460d00200520092003102b2205450d060b2005200d200a10e4072109200841186a200741a80210e4071a200841d4026a200c360200200841d0026a2004360200200841c8026a200a360200200841c4026a2003360200200820063a00d8022008200b3602cc02200820093602c0022002200841186a10ca01200841186a200210c001200828022021092008280218210a41002107200841e4026a41003a0000200841003602e002200841086a200a2009200841e0026a4105410010c7010240024020082802080d000c010b2008200828020c2207410520074105491b3602ec022008200841e0026a3602e8022008200841e8026a10c8012008280204417f6a210920082802004521070b0240200828021c450d00200a10290b20082009410020071b220a3602e402200820023602e002200841186a200110c60120082802182107200820082802203602ec02200820073602e802200841e0026a200841e8026a10fb010240200828021c450d00200710290b200841246a200a360200200841186a41086a20023602002008410036021c200841013a0018200841186a10cb01200041086a200a3602002000200236020420004100360200200141046a280200450d04200128020010290c040b200041003a000620004183043b0104200041013602002000410c6a4110360200200041086a41bbb8c800360200200710cc01200141046a280200450d03200128020010290c030b1038000b1039000b1032000b200841f0026a24000f0b1030000bfc0403027f017e057f230041d0006b2202240041c99fc500ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941db9fc500ad4280808080800284100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000ba60203027f017e017f230041106b22022400200241003602082002420137030002400240024020002d00004101460d00410110272203450d02200341003a0000200220033602002002428180808010370204200041086a200210c606200235020842208621042002280204452103200228020021000c010b410110272203450d01200341013a000020022003360200200242818080801037020420002d00012105200341014102102b2203450d01200320053a000120022003360200200242828080802037020420002802042105200341024106102b2200450d01200020053600022002200036020020024286808080e000370204410021034280808080e00021040b200129020020042000ad841003024020030d00200010290b200241106a24000f0b1030000b8ce9010c017f017e047f017e017f017e037f017e287f047e067f037e230041f00d6b2201240010bf01024002400240024002400240024002400240024020004101470d0042002102200141b8046a21030c010b42002102200141d8046a41186a4200370300200141d8046a41106a22044200370300200141d8046a41086a22054200370300200142003703d80441c8bec500ad4280808080c000841001220629000021072005200641086a290000370300200120073703d804200610294194f1c200ad4280808080b00184100122062900002107200141c8086a41086a2208200641086a290000370300200120073703c80820061029200420012903c8082207370300200141b8046a41086a2005290300370300200141b8046a41106a2007370300200141b8046a41186a2008290300370300200120012903d8043703b804200141a8046a200141b8046a10b501200141b8046a2103420020012903b004420020012802a8041b220710b4017d220920092007561b42e012540d00200141b00c6a41186a220a4200370300200141b00c6a41106a220b4200370300200141b00c6a41086a22054200370300200142003703b00c41b1dcc900ad4280808080f0008422071001220c290000210920014188076a41086a2206200c41086a2900003703002001200937038807200c10292005200629030037030020012001290388073703b00c418886ca00ad4280808080c0018422091001220c290000210d2006200c41086a2900003703002001200d37038807200c1029200b200129038807220d370300200141900b6a41086a220e2005290300370300200141900b6a41106a220f200d370300200141900b6a41186a22102006290300370300200120012903b00c3703900b200141a0046a200141900b6a412010fc0120012802a404211120012802a0042112200a4200370300200b420037030020054200370300200142003703b00c20071001220c290000210d2006200c41086a2900003703002001200d37038807200c10292005200629030037030020012001290388073703b00c41a886ca00ad4280808080d001841001220c290000210d2006200c41086a2900003703002001200d37038807200c1029200b200129038807220d370300200e2005290300370300200f200d37030020102006290300370300200120012903b00c3703900b200141900b6a10b2012113200a4200370300200b420037030020054200370300200142003703b00c20071001220c290000210d2005200c41086a2900003703002001200d3703b00c200c102920091001220c29000021092008200c41086a290000370300200120093703c808200c1029200b20012903c80822093703002006200529030037030020014188076a41106a220c200937030020014188076a41186a220e2008290300370300200120012903b00c3703880720014198046a20014188076a412010fc01200128029c0421142001280298042115200a4200370300200b420037030020054200370300200142003703b00c41c6b7c700ad42808080808001841001220f29000021092005200f41086a290000370300200120093703b00c200f102941dcb7c700ad4280808080c000841001220f29000021092008200f41086a290000370300200120093703c808200f1029200b20012903c808220937030020062005290300370300200c2009370300200e2008290300370300200120012903b00c37038807200141b00c6a20014188076a109e0320012802b00c211620012902b40c2102200a4200370300200b420037030020054200370300200142003703b00c20071001220a29000021072005200a41086a290000370300200120073703b00c200a102941b8dcc900ad4280808080a001841001220a29000021072008200a41086a290000370300200120073703c808200a1029200b20012903c808220737030020062005290300370300200c2007370300200e2008290300370300200120012903b00c37038807200141b00c6a20014188076a108d0220012802b00c2205410120051b211720012902b40c420020051b2207a721180240024002402007422088a72205450d002017200541057422196a211a200141dc066a211b200141b00c6a41206a210f20014190066a410472210c200141e8056a41047221064100210a410221050340200141b8056a41186a2017200a6a220841186a220e290000370300200141b8056a41106a200841106a2210290000370300200141b8056a41086a200841086a221c290000370300200120082900003703b80520062008290000370000200641086a201c290000370000200641106a2010290000370000200641186a200e29000037000020012005417e6a22103602e8054100210e0240201020061093060d0020014190066a41206a200141e8056a41206a28020036020020014190066a41186a200141e8056a41186a29030037030020014190066a41106a200141e8056a41106a29030037030020014190066a41086a200141e8056a41086a290300370300200120012903e80537039006200141b8046a41186a220e200c41186a221c290200370300200141b8046a41106a221d200c41106a221e290200370300200141b8046a41086a221f200c41086a22202902003703002001200c2902003703b804200141b00c6a41186a2210201c290000370300200141b00c6a41106a221c201e290000370300200141b00c6a41086a221e20202900003703002001200c2900003703b00c200141b8066a200141b00c6a10a002200141d8046a41186a2220200e290300370300200141d8046a41106a2221201d290300370300200141d8046a41086a221d201f290300370300200120012903b8043703d80420012802d806220e450d00200f20012903b806370300200f41186a200141b8066a41186a290300370300200f41106a200141b8066a41106a290300370300200f41086a200141b8066a41086a29030037030020102020290300370300201c2021290300370300201e201d290300370300200141d8056a41086a221d201b41086a280200360200200120012903d8043703b00c2001201b2902003703d805200141900b6a41386a221f200141b00c6a41386a290300370300200141900b6a41306a2220200141b00c6a41306a290300370300200141900b6a41286a2221200141b00c6a41286a290300370300200141900b6a41206a2222200f290300370300200141900b6a41186a22232010290300370300200141900b6a41106a2210201c290300370300200141900b6a41086a221c201e290300370300200120012903b00c3703900b20014188076a41386a201f29030037030020014188076a41306a202029030037030020014188076a41286a202129030037030020014188076a41206a202229030037030020014188076a41186a202329030037030020014188076a41106a201029030037030020014188076a41086a201c290300370300200120012903900b37038807200141f8066a41086a201d280200360200200120012903d8053703f8060b200141c8086a41086a20014188076a41086a290300370300200141c8086a41106a20014188076a41106a290300370300200141c8086a41186a20014188076a41186a290300370300200141c8086a41206a20014188076a41206a290300370300200141c8086a41286a20014188076a41286a290300370300200141c8086a41306a20014188076a41306a290300370300200141c8086a41386a20014188076a41386a290300370300200141e8066a41086a200141f8066a41086a28020036020020012001290388073703c808200120012903f8063703e806200e0d02200541016a21052019200a41206a220a470d000b0b2001410036028005200142083703f804201841ffffff3f71450d01201710290c010b200141f0096a41386a2206200141c8086a41386a290300370300200141f0096a41306a220c200141c8086a41306a290300370300200141f0096a41286a2210200141c8086a41286a290300370300200141f0096a41206a221c200141c8086a41206a290300370300200141f0096a41186a221e200141c8086a41186a290300370300200141f0096a41106a221d200141c8086a41106a290300370300200141f0096a41086a221f200141c8086a41086a290300370300200141a8056a41086a2220200141e8066a41086a280200360200200120012903c8083703f009200120012903e8063703a80520014198056a41086a22212020280200360200200120012903a80537039805200141b00c6a41086a2220201f290300370300200141b00c6a41106a221f201d290300370300200141b00c6a41186a221d201e290300370300200141b00c6a41206a221b201c290300370300200141b00c6a41286a221c2010290300370300200141b00c6a41306a2210200c290300370300200141b00c6a41386a220c2006290300370300200120012903f0093703b00c20014188076a41086a2206202128020036020020012001290398053703880741d0001027221e450d02201e20012903b00c370300201e200e360240201e200129038807370244201e41386a200c290300370300201e41306a2010290300370300201e41286a201c290300370300201e41206a201b290300370300201e41186a201d290300370300201e41106a201f290300370300201e41086a2020290300370300201e41cc006a2006280200360200200142818080801037028c052001201e360288050240201941606a200a460d00200841206a21062019200a6b41606a211c200141dc066a211b20014190066a410472210c200141e8056a41047221080340200141b8056a41186a200641186a220a290000370300200141b8056a41106a200641106a220e290000370300200141b8056a41086a200641086a2210290000370300200120062900003703b80520062900002107200841186a200a29000037000020082007370000200841086a2010290000370000200841106a200e29000037000020012005417f6a220e3602e8054100210a0240200e20081093060d0020014190066a41206a200141e8056a41206a28020036020020014190066a41186a200141e8056a41186a29030037030020014190066a41106a200141e8056a41106a29030037030020014190066a41086a200141e8056a41086a290300370300200120012903e80537039006200141b8046a41186a220a200c41186a2210290200370300200141b8046a41106a221d200c41106a2219290200370300200141b8046a41086a221f200c41086a22202902003703002001200c2902003703b804200141b00c6a41186a220e2010290000370300200141b00c6a41106a22102019290000370300200141b00c6a41086a221920202900003703002001200c2900003703b00c200141b8066a200141b00c6a10a002200141d8046a41186a2220200a290300370300200141d8046a41106a2221201d290300370300200141d8046a41086a221d201f290300370300200120012903b8043703d80420012802d806220a450d00200f20012903b806370300200f41186a200141b8066a41186a290300370300200f41106a200141b8066a41106a290300370300200f41086a200141b8066a41086a290300370300200e2020290300370300201020212903003703002019201d290300370300200141d8056a41086a221d201b41086a280200360200200120012903d8043703b00c2001201b2902003703d805200141900b6a41386a221f200141b00c6a41386a290300370300200141900b6a41306a2220200141b00c6a41306a290300370300200141900b6a41286a2221200141b00c6a41286a290300370300200141900b6a41206a2222200141b00c6a41206a290300370300200141900b6a41186a2223200e290300370300200141900b6a41106a220e2010290300370300200141900b6a41086a22102019290300370300200120012903b00c3703900b20014188076a41386a201f29030037030020014188076a41306a202029030037030020014188076a41286a202129030037030020014188076a41206a202229030037030020014188076a41186a202329030037030020014188076a41106a200e29030037030020014188076a41086a2010290300370300200120012903900b37038807200141f8066a41086a201d280200360200200120012903d8053703f8060b200141c8086a41086a20014188076a41086a290300370300200141c8086a41106a20014188076a41106a290300370300200141c8086a41186a20014188076a41186a290300370300200141c8086a41206a20014188076a41206a290300370300200141c8086a41286a20014188076a41286a290300370300200141c8086a41306a20014188076a41306a290300370300200141c8086a41386a20014188076a41386a290300370300200141e8066a41086a200141f8066a41086a28020036020020012001290388073703c808200120012903f8063703e8060240200a0d00200641206a2106200541016a2105201c41606a221c0d010c020b0b200141f0096a41386a2224200141c8086a41386a2220290300370300200141f0096a41306a2225200141c8086a41306a2221290300370300200141f0096a41286a2226200141c8086a41286a221b290300370300200141f0096a41206a2227200141c8086a41206a2222290300370300200141f0096a41186a2228200141c8086a41186a2223290300370300200141f0096a41106a2229200141c8086a41106a222a290300370300200141f0096a41086a222b200141c8086a41086a222c290300370300200141a8056a41086a222d200141e8066a41086a222e280200360200200120012903c8083703f009200120012903e8063703a80520014198056a41086a222f202d280200360200200120012903a80537039805200641206a2106200141dc066a213020014190066a410472210c200141e8056a41047221084101210e410121310340200141b00c6a41086a2219202b290300370300200141b00c6a41106a221d2029290300370300200141b00c6a41186a221f2028290300370300200141b00c6a41206a22322027290300370300200141b00c6a41286a22332026290300370300200141b00c6a41306a22342025290300370300200141b00c6a41386a22352024290300370300200120012903f0093703b00c20014188076a41086a221c202f28020036020020012001290398053703880702402031200e470d0020014188056a200e410110ac01200128028805211e0b201e203141d0006c6a220e20012903b00c370300201d2903002107201f29030021092032290300210d20332903002136203429030021372035290300213820192903002139200e200a360240200e41086a2039370300200e200129038807370244200e41cc006a201c280200360200200e41386a2038370300200e41306a2037370300200e41286a2036370300200e41206a200d370300200e41186a2009370300200e41106a20073703002001203141016a2231360290052006201a460d010340200141b8056a41186a200641186a220a290000370300200141b8056a41106a200641106a220e290000370300200141b8056a41086a200641086a2210290000370300200120062900003703b805200120053602e80520102900002107200e29000021092006290000210d200841186a200a290000370000200841106a2009370000200841086a20073700002008200d3700004100210a0240200520081093060d0020014190066a41206a200141e8056a41206a28020036020020014190066a41186a200141e8056a41186a29030037030020014190066a41106a200141e8056a41106a29030037030020014190066a41086a200141e8056a41086a290300370300200120012903e80537039006200141b8046a41186a220a200c41186a220e290200370300200141b8046a41106a2210200c41106a223a290200370300200141b8046a41086a223b200c41086a223c2902003703002001200c2902003703b804201f200e290000370300201d203a2900003703002019203c2900003703002001200c2900003703b00c200141b8066a200141b00c6a10a002200141d8046a41186a220e200a290300370300200141d8046a41106a223a2010290300370300200141d8046a41086a2210203b290300370300200120012903b8043703d80420012802d806220a450d00200f20012903b806370300200f41186a200141b8066a41186a290300370300200f41106a200141b8066a41106a290300370300200f41086a200141b8066a41086a290300370300201f200e290300370300201d203a29030037030020192010290300370300200141d8056a41086a220e203041086a280200360200200120012903d8043703b00c200120302902003703d805200141900b6a41386a22102035290300370300200141900b6a41306a223a2034290300370300200141900b6a41286a223b2033290300370300200141900b6a41206a223c2032290300370300200141900b6a41186a223d201f290300370300200141900b6a41106a223e201d290300370300200141900b6a41086a223f2019290300370300200120012903b00c3703900b20014188076a41386a201029030037030020014188076a41306a203a29030037030020014188076a41286a203b29030037030020014188076a41206a203c29030037030020014188076a41186a203d29030037030020014188076a41106a203e290300370300201c203f290300370300200120012903900b37038807200141f8066a41086a200e280200360200200120012903d8053703f8060b202c201c290300370300202a20014188076a41106a290300370300202320014188076a41186a290300370300202220014188076a41206a290300370300201b20014188076a41286a290300370300202120014188076a41306a290300370300202020014188076a41386a290300370300202e200141f8066a41086a28020036020020012001290388073703c808200120012903f8063703e8060240200a0d00200541016a2105201a200641206a2206470d010c030b0b20242020290300370300202520212903003703002026201b29030037030020272022290300370300202820232903003703002029202a290300370300202b202c290300370300202d202e280200360200200120012903c8083703f009200120012903e8063703a805202f202d280200360200200120012903a80537039805200641206a2106200541016a2105200128028c05210e0c000b0b0240201841ffffff3f71450d00201710290b200141f8046a41086a20014188056a41086a28020036020020012001290388053703f8040b200141b00c6a41186a220a4200370300200141b00c6a41106a220c4200370300200141b00c6a41086a22054200370300200142003703b00c41b1dcc900ad4280808080f000841001220629000021072005200641086a290000370300200120073703b00c20061029418886ca00ad4280808080c00184100122062900002107200141c8086a41086a2208200641086a290000370300200120073703c80820061029200b20012903c808370000200b41086a200829030037000020014188076a41086a2206200529030037030020014188076a41106a200c29030037030020014188076a41186a200a290300370300200120012903b00c3703880720014190046a20014188076a412010fc01200128029404210a200128029004210c41c6b7c700ad42808080808001841001220529000021072006200541086a29000037030020012007370388072005102941c8f7c700ad4280808080a002841001220529000021072008200541086a290000370300200120073703c80820051029410021082001200a4100200c1b3602b8062001200141b8066aad22074280808080c00084100222052900003703f00920051029200141bc0c6a200141bc066a3602002001200141f0096a41086a220f3602b40c2001200141b8066a3602b80c2001200141f0096a3602b00c200141900b6a200141b00c6a107520012802980b220c41206a2206417f4c0d0220012802900b210e0240024020060d00410121050c010b200610272205450d02200621080b024002402008410f4d0d002008210a0c010b2008410174220a4110200a41104b1b220a4100480d04024020080d00200a102722050d010c0a0b2008200a460d0020052008200a102b2205450d090b2005200129038807370000200541086a20014188076a41086a29030037000002400240200a4170714110460d00200a21080c010b200a41017422084120200841204b1b22084100480d04200a2008460d002005200a2008102b2205450d090b200520012903c808370010200541186a200141c8086a41086a29030037000002400240200841606a200c490d002008210a0c010b200c415f4b0d042008410174220a2006200a20064b1b220a4100480d042008200a460d0020052008200a102b2205450d090b200541206a200e200c10e4071a024020012802940b450d00200e10290b2006ad4220862005ad8410060240200a450d00200510290b200141b00c6a41186a220a4200370300200141b00c6a41106a220c4200370300200141b00c6a41086a22054200370300200142003703b00c41b1dcc900ad4280808080f000841001220629000021092005200641086a290000370300200120093703b00c20061029418886ca00ad4280808080c00184100122062900002109200141c8086a41086a2208200641086a290000370300200120093703c80820061029200b20012903c808370000200b41086a200829030037000020014188076a41086a2206200529030037030020014188076a41106a200c29030037030020014188076a41186a200a290300370300200120012903b00c3703880720014188046a20014188076a412010fc01200128028c04210a200128028804210c41c6b7c700ad42808080808001841001220529000021092006200541086a29000037030020012009370388072005102941e0c9c700ad4280808080e001841001220529000021092008200541086a290000370300200120093703c80820051029410021082001200a4100200c1b3602b806200120074280808080c00084100222052900003703f00920051029200141bc0c6a200141bc066a3602002001200f3602b40c2001200141b8066a3602b80c2001200141f0096a3602b00c200141900b6a200141b00c6a107520012802980b220c41206a2206417f4c0d0220012802900b210e0240024020060d00410121050c010b200610272205450d02200621080b024002402008410f4d0d002008210a0c010b2008410174220a4110200a41104b1b220a4100480d04024020080d00200a10272205450d0a0c010b2008200a460d0020052008200a102b2205450d090b2005200129038807370000200541086a20014188076a41086a29030037000002400240200a4170714110460d00200a21080c010b200a41017422084120200841204b1b22084100480d04200a2008460d002005200a2008102b2205450d090b200520012903c808370010200541186a200141c8086a41086a29030037000002400240200841606a200c490d002008210a0c010b200c415f4b0d042008410174220a2006200a20064b1b220a4100480d042008200a460d0020052008200a102b2205450d090b200541206a200e200c10e4071a024020012802940b450d00200e10290b2006ad4220862005ad8410060240200a450d00200510290b2002420020161b21070240024002400240024002400240200128028005450d00200141b00c6a200141f8046a10f20520014193076a200141b00c6a41086a280200360000200120012903b00c37008b07200141bc0c6a2001418f076a290000370000200141023a00b40c200141083a00b00c20012001290088073700b50c200141b00c6a10cb01200141a0066a200141f8046a41086a28020036020020012007422088a7223a3602940620012014410020151b220c36029006200120012903f80437039806200141e8066a20014190066a41086a10f20520012802e806212c20012802ec06212e20012802f0062108410410272205450d082005200c36000020014284808080c0003702cc08200120053602c808200141b00c6a41d5cdc20010e90220014188076a20012802b00c220620012802b80c108b03200129028c07420020012802880722051b21092005410120051b210a024020012802b40c450d00200610290b200120094220883e028c072001200a36028807200141b00c6a20014188076a10c905200141b00c6a41086a280200210620012802b40c210e20012802b00c2105200141b00c6a41d5cdc200200141c8086a10ea0220014188076a20012802b00c221020012802b80c10ce012006410020051b210f200e410020051b210e200129028c07420020012802880722061b210d2005410420051b21052006410120061b2122024020012802b40c450d00201010290b200141900a6a200f3602002001418c0a6a200e360200200141800a6a200d370300200141f0096a41086a200141c8086a41086a280200360200200120012903c8083703f009200120053602880a200120223602fc0902402009a7450d00200a10290b2008450d01200d422088a7211c200141880a6a211a200141f0096a410c6a212a202c200841d0006c6a211e200141b00c6a41d0006a211b200141b00c6a410c6a2119200141c8086a41c4006a211d41002123202c210e0340200141b00c6a41386a2206200e220541386a290300370300200141b00c6a41306a2208200541306a290300370300200141b00c6a41286a220a200541286a290300370300200141b00c6a41206a220f200541206a290300370300200141b00c6a41186a2210200541186a290300370300200141b00c6a41106a2217200541106a290300370300200141b00c6a41086a221f200541086a290300370300200141d8056a41086a2220200541cc006a280200360200200120052903003703b00c2001200541c4006a2902003703d805200541d0006a210e200541c0006a2802002205450d03200141900b6a41386a22212006290300370300200141900b6a41306a22062008290300370300200141900b6a41286a2208200a290300370300200141900b6a41206a220a200f290300370300200141900b6a41186a220f2010290300370300200141900b6a41106a22102017290300370300200141900b6a41086a2217201f290300370300200141a8056a41086a221f2020280200360200200120012903b00c3703900b200120012903d8053703a805200141c8086a41386a2021290300370300200141c8086a41306a2006290300370300200141c8086a41286a2008290300370300200141c8086a41206a200a290300370300200141c8086a41186a200f290300370300200141c8086a41106a2010290300370300200141c8086a41086a2017290300370300200120012903900b3703c8082001200536028809201d20012903a805370200201d41086a201f280200360200410410272205450d092005200c360000201941002900d5cd42370000201941086a41002900ddcd4237000020014284808080c0003702b40c200120053602b00c2001200141c8086a3602cc0c200141b8066a200141b00c6a10ca0520051029200141b00c6a200141b8066a10d50220014180046a20012802b00c220620012802b80c4180a6cc004100410010c7012001280280042105024020012802b40c450d00200610290b024002400240024020054101460d0020014188076a200141c8086a41d00010e4071a200141003602f005200142013703e805200141e8056a41004100109e01200141b8056a41086a221720012802f005360200200120012903e8053703b805200141b00c6a20014188076a41d00010e4071a201b41086a2017280200360200201b20012903b80537020020014188076a200141b8066a10d502200128028807210520012001280290073602ec05200120053602e805200141b00c6a200141e8056a10e4020240200128028c07450d00200510290b024020012802f40c2205450d00200541306c450d0020012802f00c10290b024020012802840d41ffffff3f71450d0020012802800d10290b200141b8056a41186a221f200141b8066a41186a290300370300200141b8056a41106a2220200141b8066a41106a2903003703002017200141b8066a41086a290300370300200120012903b8063703b80520012802880a210f41002105024020012802900a221041014b0d00024020100e020003000b200141b8046a41186a201f290300370300200141b8046a41106a2020290300370300200141b8046a41086a2017290300370300200120012903b8053703b804410021050c030b20102106034020052006410176220820056a220a200f200a41246c6a280200200c4b1b2105200620086b220641014b0d000c020b0b200128028c092205450d02200541306c450d0220012802880910290c020b0240200f200541246c6a2802002206200c460d0020052006200c496a21050b200141b8046a41186a201f290300370300200141b8046a41106a2020290300370300200141b8046a41086a2017290300370300200120012903b8053703b804201020054f0d00200520101041000b02402010200128028c0a470d00201a2010410110960120012802840a211c20012802880a210f0b200f200541246c6a220641246a2006201020056b41246c10e5071a2006200c360200200620012903b8043702042006410c6a200141b8046a41086a290300370200200641146a200141b8046a41106a2903003702002006411c6a200141b8046a41186a2903003702002001201041016a3602900a200141d8046a41186a2206201f290300370300200141d8046a41106a22082020290300370300200141d8046a41086a220a2017290300370300200120012903b8053703d8040240201c20012802800a470d00202a201c4101109e0120012802840a211c0b20012802fc092222201c4105746a220520012903d804370000200541186a2006290300370000200541106a2008290300370000200541086a200a290300370000410121232001201c41016a221c3602840a0b200e201e470d000b201e210e0c020b200141013a00b40c200141083a00b00c200141b00c6a10cb0120012802fc042205450d05200541d0006c450d0520012802f80410290c050b202e450d01202e41d0006c450d01202c10290c010b0240201e200e460d000340200e220541d0006a210e0240200541c4006a2802002206450d00200641306c450d00200541c0006a28020010290b201e200e470d000b0b0240202e450d00202e41d0006c450d00202c10290b2023410171450d00200141f8066a20222022201c4105746a10ce05200141b00c6a41206a200141f0096a41206a2802002205360200200141b00c6a41186a200141f0096a41186a2903002209370300200141b00c6a41106a200141f0096a41106a290300370300200141b00c6a41086a200141f0096a41086a290300370300200120012903f0093703b00c200141c8086a2009a72208200510cf0520014188076a41d5cdc20010e902200128028807210520012001280290073602940b200120053602900b20012802c808220620012802d008200141900b6a10a1040240200128028c07450d00200510290b024020012802cc08450d00200610290b20014188076a41d5cdc200200141b00c6a10ea02200128028807210520012001280290073602cc08200120053602c80820012802bc0c2206200141c40c6a280200200141c8086a10cf010240200128028c07450d00200510290b024020012802b40c450d0020012802b00c10290b0240200141c00c6a28020041ffffff3f71450d00200610290b0240200141cc0c6a2802002205450d00200541246c450d00200810290b20012802f806220e0d010c020b200141003602f806024020012802f409450d0020012802f00910290b024020012802800a41ffffff3f71450d00202210290b200128028c0a2205450d01200541246c450d0120012802880a10290c010b20012802fc0621104100210802400240203a410a6e417f7320014180076a280200220a6a2206200a4b0d00203a4101203a41014b1b2205418094ebdc036e220820052008418094ebdc036c476a22084101200841014b1b220820054b0d0120012005200641036c220620052006491b20086ead428094ebdc037e200520086ead8042ffffffff0f834280bbb0217e428094ebdc0380a722053602b00c2001418094ebdc033602b40c200141b00c6a2005418094ebdc034b4102746a28020021080b200141003602b80c200142043703b00c200141b00c6a4100200a10980120012802b00c210f20012802b80c211c02400240200a0d0020012802b40c2106200e4100200f201c200c10ec0221080c010b200f201c4102746a2105200a2106034020052008360200200541046a21052006417f6a22060d000b20012802b40c2106200e200a200f201c200a6a200c10ec0221080b410410272205450d042005200c360000200141b80c6a4284808080c000370300200141c00c6a41002900d5cd42370300200141c80c6a41002900ddcd42370300200141d00c6a20083a0000200120053602b40c200141053a00b00c200141b00c6a10cb010240200641ffffffff0371450d00200f10290b0240200a450d00200a41e0006c2106200e41d4006a210503400240200541706a2802002208450d00200841306c450d002005416c6a28020010290b0240200528020041ffffff3f71450d002005417c6a28020010290b200541e0006a2105200641a07f6a22060d000b0b02402010450d00201041e0006c450d00200e10290b200128029806210a0240200141a0066a2802002205450d00200541d0006c2106200a41c4006a21050340024020052802002208450d00200841306c450d002005417c6a28020010290b200541d0006a2105200641b07f6a22060d000b0b2001419c066a2802002205450d02200541d0006c450d02200a10290c020b41f0a6c700411941dcaac7001033000b200128029806210a0240200141a0066a2802002205450d00200541d0006c2106200a41c4006a21050340024020052802002208450d00200841306c450d002005417c6a28020010290b200541d0006a2105200641b07f6a22060d000b0b02402001419c066a2802002205450d00200541d0006c450d00200a10290b41ce9bcc00ad4280808080c00184100841bf9bcc00ad4280808080f0018410080b0240200742ffffff3f83500d002016410120161b10290b2011410020121b210e20014188076a41186a420037030020014188076a41106a2208420037030020014188076a41086a22054200370300200142003703880741eebec500ad4280808080f000841001220629000021072005200641086a29000037030020012007370388072006102941f0f5c100ad4280808080900184100122062900002107200141c8086a41086a220a200641086a290000370300200120073703c80820061029200820012903c8082207370300200141b00c6a41086a220c2005290300370300200141b00c6a41106a220f2007370300200141b00c6a41186a2210200a29030037030020012001290388073703b00c20014188076a200141b00c6a10d001024020012903880722074202510d002001290390072109200141b00c6a2008280200221c41016a10da01200141f8036a20012802b00c220820012802b80c10fc0120012802fc03210a20012802f8032106024020012802b40c450d00200810290b20064101470d00200a200e41016a470d0020074201520d00200141b8056a41186a22174200370300200141b8056a41106a22064200370300200141b8056a41086a22084200370300200142003703b80541ccbec500ad42808080809001841001220a29000021072008200a41086a290000370300200120073703b805200a102941aafac400ad428080808030841001221e290000210720014188076a41086a220a201e41086a2900003703002001200737038807201e102920062001290388072207370300200141b00c6a41086a22192008290300370300200141b00c6a41106a221d2007370300200141b00c6a41186a221f200a290300370300200120012903b8053703b00c200141e8036a200141b00c6a10b501200141c0036a20012903f003420020012802e8031b220742e80780220d420042e807420010d507200141b00c6a201c109202200141d0036a20012802b00c222020012802b80c10e30120012903c00322022007200d4298787e7c42ff07837c2207427f200141c0036a41086a2903002007200254ad7c501b20097d2136200141d0036a41106a290300420020012802d003221e1b210720012903d8034200201e1b2102024020012802b40c450d00202010290b201742003703002006420037030020084200370300200142003703b80541dcbec500ad42808080808001841001221e29000021092008201e41086a290000370300200120093703b805201e1029419fe3c200ad4280808080d001841001221e2900002109200a201e41086a2900003703002001200937038807201e10292006200129038807370000200641086a200a29030037000020192008290300370300201d2006290300370300201f2017290300370300200120012903b8053703b00c200141a8036a200141b00c6a412010e30120014198036a20012903b003420020012802a80322061b2209200141a8036a41106a290300420020061b220d428094ebdc03420010e00720014188036a200129039803223820014198036a41086a29030022394280ec94a37c427f10d507200d200720022009562007200d562007200d511b22061b21072009200220061b210220012903880320097c21372036428086ebc7f5002036428086ebc7f500541b42058842ffffffff0f83428094ebdc037e4298ac9fd6038021404100210841d87d210602400240024002400340200141f8026a2038203920064190a4c5006a3502002209420010d5072008200220012903f802220d200920377e2209428094ebdc03802236a7417f2009428080808080c0b2cd3b541b200920364280ec94a37c7e7c4280cab5ee01566aad7c22095a2007200141f8026a41086a2903002009200d54ad7c220d5a2007200d51220a1b6a210820022009542007200d54200a1b0d01200641086a22060d000b200141e8026a2038203942e8aafa0b420010d507200141f0026a29030020012903e8022209203742e8aafa0b7e2207428094ebdc0380220da7417f2007428080808080c0b2cd3b541b2007200d4280ec94a37c7e7c4280cab5ee01566aad7c2207200954ad7c21090c010b02402008417f6a220620084d0d00200141e8016a2038203942c0f0f50b420010d507200141f0016a29030020012903e801220920374228802207a7417f203742c0f0f50b7e220d428080808080c0b2cd3b541b200d20074280ec94a37c7e7c4280cab5ee01566aad7c2207200954ad7c21090c010b200641244b0d01200141d8026a203820392006410374220a41e8a1c5006a2802002217ad2209420010d507200141b8026a200220012903d802220d200920377e2209428094ebdc03802236a7417f2009428080808080c0b2cd3b541b200920364280ec94a37c7e7c4280cab5ee01566aad7c220920022009562007200141d8026a41086a2903002009200d54ad7c220d562007200d511b22061b22362009200220061b22097d22412007200d20061b200d200720061b7d2036200954ad7d41002008410374221e41e8a1c5006a280200220820176b2217201720084b1b22084101200841014b1bad220d420010e007200141a8026a20012903b8022207200141b8026a41086a2903002209200d420010d507200141c8026a20382039200a41eca1c5006a2802002208ad2236420010d507200141f8016a20094200201e41eca1c5006a280200220a2008200a20084b22171b2008200a20171b6bad2202420010d50720014198026a200742002002420010d50720014188026a420042002007420010d507427f200141c8026a41086a29030020012903c8022209203620377e2207428094ebdc03802236a7417f2007428080808080c0b2cd3b541b200720364280ec94a37c7e7c4280cab5ee01566aad7c2207200954ad7c2209427f427f20014198026a41086a290300223620012903f8012001290388027c7c22422001290380022001290390028442005220422036547222171b2242427f20012903980220171b2236204120012903a8027d20027e200d807c220d2036542217ad7c220220172002204254200d20365a1b22171b22367c2007427f200d20171b220d7c22412007542217ad7c22022017200220095420022009511b22171b4200200920367d2007200d54ad7d22022007200d7d220d200756200220095620022009511b221e1b200a20084d20067322061b2109427f204120171b4200200d201e1b20061b21070b200141a8016a203820394280c2d72f420010d507200141d8016a20072009428094ebdc03420010e00720014198016a20012903a801220d2037420a802209a7417f20374280c2d72f7e2202428080808080c0b2cd3b541b200220094280ec94a37c7e7c4280cab5ee01566aad7c2209200141a8016a41086a2903002009200d54ad7c428094ebdc03420010e007200141c8016a20012903d801220d200141d8016a41086a29030022024280ec94a37c427f10d507200141b8016a200d20022040420010d50720014188016a200129039801220d20014198016a41086a29030022024280ec94a37c427f10d507200141f8006a200d20022040420010d507200141bc0c6a201c360200200141b00c6a41086a41003a0000200141c00c6a20012903b801220d2040200720012903c8017c7e2207428094ebdc03802202a7417f2007428080808080c0b2cd3b541b200720024280ec94a37c7e7c4280cab5ee01566aad7c2207370300200141c80c6a200141b8016a41086a2903002007200d54ad7c2202370300200141d80c6a4200200141f8006a41086a2903002001290378220d204020092001290388017c7e2209428094ebdc03802236a7417f2009428080808080c0b2cd3b541b200920364280ec94a37c7e7c4280cab5ee01566aad7c2209200d54ad7c220d20027d2009200754ad7d2236200920077d22372009562036200d562036200d511b22061b2209370300200141d00c6a4200203720061b220d370300200141043a00b00c200141b00c6a10cb0120014188076a201c10930220012802880721062001350290072136200120023703b80c200120073703b00c20364220862006ad84200141b00c6aad2202428080808080028410030240200128028c07450d00200610290b02400240200d2009844200520d0020014200370390072001420037038807200141b8046aad428080808080048421360c010b200141d8046a41186a220a4200370300200141d8046a41106a221c4200370300200141d8046a41086a22084200370300200142003703d80441dcbec500ad42808080808001842207100122172900002136200141c8086a41086a2206201741086a290000370300200120363703c8082017102920082006290300370300200120012903c8083703d804419fe3c200ad4280808080d0018422361001221729000021372006201741086a290000370300200120373703c80820171029200420012903c808370000200441086a22192006290300370000200141b8046a41086a221d2008290300370300200141b8046a41106a221f201c290300370300200141b8046a41186a2220200a290300370300200120012903d8043703b804200141e0006a200141b8046a412010e301200141e0006a41106a29030021372001290368213820012802602117200a4200370300201c420037030020084200370300200142003703d80420071001221e29000021072006201e41086a290000370300200120073703c808201e102920082006290300370300200120012903c8083703d80420361001221e29000021072006201e41086a290000370300200120073703c808201e1029200420012903c80837000020192006290300370000201d2008290300370300201f201c2903003703002020200a290300370300200120012903d8043703b8042001427f2037420020171b220720097c2038420020171b2237200d7c22382037542206ad7c22362006203620075420362007511b22061b3703b80c2001427f203820061b3703b00c200141b8046aad42808080808004842236200242808080808002841003024020060d002001200d3703880720012009370390070c030b20012037427f85220d3703880720012007427f852209370390072037200783427f520d020b200141d8046a41186a220a4200370300200141d8046a41106a221c4200370300200141d8046a41086a22084200370300200142003703d80441dcbec500ad42808080808001842207100122172900002109200141c8086a41086a2206201741086a290000370300200120093703c8082017102920082006290300370300200120012903c8083703d804419fe3c200ad4280808080d00184220910012217290000210d2006201741086a2900003703002001200d3703c80820171029200420012903c808370000200441086a22192006290300370000200141b8046a41086a221d2008290300370300200141b8046a41106a221f201c290300370300200141b8046a41186a2220200a290300370300200120012903d8043703b804200141c8006a200141b8046a412010e301200141c8006a41106a290300210d2001290350213720012802482117200a4200370300201c420037030020084200370300200142003703d80420071001221e29000021072006201e41086a290000370300200120073703c808201e102920082006290300370300200120012903c8083703d80420091001221e29000021072006201e41086a290000370300200120073703c808201e1029200420012903c80837000020192006290300370000201d2008290300370300201f201c2903003703002020200a290300370300200120012903d8043703b8042001200d420020171b3703b80c20012037420020171b3703b00c20362002428080808080028410030c020b20064125418cc3c2001036000b200142f0f2bda1a7ee9cb9f90037038807200141b00c6a20014188076a108202200141b00c6a200d2009108002200141c80c6a2009370300200141c00c6a200d370300200141b80c6a41063a00002001410e3a00b00c200141b00c6a10cb010b20104200370300200f4200370300200c4200370300200142003703b00c41b1dcc900ad4280808080f000841001220629000021072005200641086a290000370300200120073703880720061029200c200529030037030020012001290388073703b00c4182f0c900ad4280808080a001841001220629000021072005200641086a290000370300200120073703880720061029200b200129038807370000200b41086a2005290300370000200141900b6a41086a200c290300370300200141900b6a41106a200f290300370300200141900b6a41186a2010290300370300200120012903b00c3703900b200141203602ec052001200141900b6a3602e805200141b8066a200141900b6aad428080808080048422071007108b020240024020012802b806220c0d004100210a0c010b20012802bc06210f2001200141c0066a280200360294062001200c36029006200141c0006a20014190066a10c8010240024020012802400d0020012802442210200128029406220841c0016e2205200520104b1bad42c0017e2209422088a70d052009a72205417f4c0d050240024020050d004101210a0c010b20051027220a450d050b200141003602f8092001200a3602f0092001200541c0016e3602f40902402010450d00200141b00c6a41206a211e200141c8086a4101722119410021174100211c0240034041002105200141003a00e808201c41016a211c02400340200141003a00b80520082005460d01200141c8086a20056a20012802900622062d00003a00002001200641016a360290062001200541016a22063a00e8082006210520064120470d000b200141d8046a41086a2205200141c8086a41086a290300370300200141d8046a41106a221d200141c8086a41106a290300370300200141d8046a41186a221f200141c8086a41186a290300370300200120012903c8083703d8042001200820066b36029406200141c8086a20014190066a10c70320012d00c8084101460d02200141b00c6a41186a201f290300370300200141b00c6a41106a201d290300370300200141b00c6a41086a2005290300370300200120012903d8043703b00c201e201941a00110e4071a20014188076a200141b00c6a41c00110e4071a0240201720012802f409470d00200141f0096a20174101108e0120012802f009210a20012802f80921170b200a201741c0016c6a20014188076a41c00110e4071a2001201741016a22173602f809201c2010460d0320012802940621080c010b0b2001410036029406200541ff0171450d00200141003a00e8080b024020012802f4092205450d00200541c0016c450d00200a10290b0c010b20012902f4092109200a0d010b4100210a200141003602900720014201370388072001410d3602cc082001200141e8056a3602c808200120014188076a3602f009200141c40c6a4101360200200142013702b40c200141f4eaca003602b00c2001200141c8086a3602c00c200141f0096a41a8a3c800200141b00c6a10371a200135029007422086200135028807841008200128028c07450d0020012802880710290b200f450d00200c10290b2013201341ff0171410247712123200141003602b80c200142013703b00c200141b00c6a410020094200200a1b2236422088a7221a41c0016c222c41c0016e109e01200a4101200a1b212020012802b80c210820012802b00c211b0240201a450d00201b20084105746a2105202c210a20202106034020052006290000370000200541186a200641186a290000370000200541106a200641106a290000370000200541086a200641086a290000370000200841016a2108200541206a2105200641c0016a2106200a41c07e6a220a0d000b0b20012802b40c212e200141b00c6a41186a220c4200370300200141b00c6a41106a220a4200370300200141b00c6a41086a22064200370300200142003703b00c41b1dcc900ad4280808080f0008422091001220f290000210d20014188076a41086a2205200f41086a2900003703002001200d37038807200f10292006200529030037030020012001290388073703b00c41b8dcc900ad4280808080a001841001220f290000210d2005200f41086a2900003703002001200d37038807200f1029200b200129038807370000200b41086a220f2005290300370000200141900b6a41086a22102006290300370300200141900b6a41106a221c200a290300370300200141900b6a41186a2217200c290300370300200120012903b00c3703900b200141203602b40c2001200141900b6a3602b00c201b2008200141b00c6a10b90102402023450d00200c4200370300200a420037030020064200370300200142003703b00c200910012208290000210d2005200841086a2900003703002001200d37038807200810292006200529030037030020012001290388073703b00c419887ca00ad4280808080a0028410012208290000210d2005200841086a2900003703002001200d3703880720081029200b200129038807370000200f200529030037000020102006290300370300201c200a2903003703002017200c290300370300200120012903b00c3703900b200141b00c6a200141900b6a108f0320012802b00c2208450d002007100420012902b40c42ffffffff0383500d00200810290b200c4200370300200a420037030020064200370300200142003703b00c20091001220829000021092005200841086a2900003703002001200937038807200810292006200529030037030020012001290388073703b00c418886ca00ad4280808080c001841001220829000021092005200841086a290000370300200120093703880720081029200b200129038807370000200f200529030037000020102006290300370300201c200a2903003703002017200c290300370300200120012903b00c3703900b2001200e41016a22223602b00c2007200141b00c6aad22024280808080c000841003200141d8046a41186a22084200370300200141d8046a41106a220c4200370300200141d8046a41086a22054200370300200142003703d80441eebec500ad4280808080f000841001220629000021092005200641086a290000370300200120093703d8042006102941f0f5c100ad4280808080900184100122062900002109200141c8086a41086a220f200641086a290000370300200120093703c80820061029200420012903c808370000200441086a200f290300370000200141b8046a41086a2005290300370300200141b8046a41106a200c290300370300200141b8046a41186a2008290300370300200120012903d8043703b804200141b00c6a200141b8046a10d001200141b00c6a4100200a28020041016a20012903b00c4202511b10da01200141386a20012802b00c220820012802b80c10fc01200128023c210620012802382105024020012802b40c450d00200810290b024020054101470d00024020062022460d00200620224f0d0141ecb4c000ad428080808080068410080b202210f7010b200141b8056a41186a220c4200370300200141b8056a41106a22064200370300200141b8056a41086a22084200370300200142003703b80541b1dcc900ad4280808080f0008422091001220a290000210d200141c8086a41086a2205200a41086a2900003703002001200d3703c808200a102920082005290300370300200120012903c8083703b80541a7adc000ad4280808080b00184220d1001220f290000213720014188076a41086a220a200f41086a2900003703002001203737038807200f102920062001290388072237370300200141b00c6a41086a22102008290300370300200141b00c6a41106a221c2037370300200141b00c6a41186a2217200a290300370300200120012903b8053703b00c20014188076a200141b00c6a412010f901200e41026a212102400240200128028807410146220f450d00200135028c0721370c010b2021ad223742208620378421374101210f0b2001200f3602900b2001203742ffffffff0f83200e41036aad422086843702940b200c42003703002006420037030020084200370300200142003703b80520091001220e29000021092005200e41086a290000370300200120093703c808200e102920082005290300370300200120012903c8083703b805200d1001220e2900002109200a200e41086a2900003703002001200937038807200e10292006200129038807370000200641086a200a29030037000020102008290300370300201c20062903003703002017200c290300370300200120012903b8053703b00c2001412036028c072001200141b00c6a36028807200141900b6a41047220014188076a10fb01200141d8046a41186a220a4200370300200141d8046a41106a220c4200370300200141d8046a41086a22064200370300200142003703d80441eebec500ad4280808080f000841001220829000021092005200841086a290000370300200120093703c8082008102920062005290300370300200120012903c8083703d80441c4f5c100ad4280808080a001841001220829000021092005200841086a290000370300200120093703c80820081029200420012903c808370000200441086a2005290300370000200141b8046a41086a2006290300370300200141b8046a41106a200c290300370300200141b8046a41186a200a290300370300200120012903d8043703b804200141306a200141b8046a412010fc010240024020012802304101460d00200141e8056a20211094020c010b200141b00c6a200128023410da01200141286a20012802b00c220620012802b80c10fc01200128022c210a20012802282105024020012802b40c450d00200610290b024020050d0041e5a4c200ad4280808080e0068410084100210a0b200141d8046a41186a220c4200370300200141d8046a41106a220e4200370300200141d8046a41086a22064200370300200142003703d80441eebec500ad4280808080f00084100122082900002109200141c8086a41086a2205200841086a290000370300200120093703c8082008102920062005290300370300200120012903c8083703d8044180fac100ad42808080808001841001220829000021092005200841086a290000370300200120093703c80820081029200420012903c808370000200441086a2005290300370000200141b8046a41086a2006290300370300200141b8046a41106a200e290300370300200141b8046a41186a200c290300370300200120012903d8043703b80441002021200a6b2205200520214b1b21060240024002404100200141b8046a10b3012205200541ff01714104461b41ff0171220541034b0d00024020050e0400020103000b200641064f0d020b0240200641016a4106490d00200141d8046a41186a220a4200370300200141d8046a41106a220c4200370300200141d8046a41086a22064200370300200142003703d80441eebec500ad4280808080f00084100122082900002109200141c8086a41086a2205200841086a290000370300200120093703c8082008102920062005290300370300200120012903c8083703d80441b480c200ad4280808080d002841001220829000021092005200841086a290000370300200120093703c80820081029200420012903c808370000200441086a2005290300370000200141b8046a41086a2006290300370300200141b8046a41106a200c290300370300200141b8046a41186a200a290300370300200120012903d8043703b804200141013a00b805200141b8046aad4280808080800484200141b8056aad4280808080108410030b200141003602e8050c020b200141d8046a41186a220a4200370300200141d8046a41106a220c4200370300200141d8046a41086a22064200370300200142003703d80441eebec500ad4280808080f00084100122082900002109200141c8086a41086a2205200841086a290000370300200120093703c8082008102920062005290300370300200120012903c8083703d8044180fac100ad42808080808001841001220829000021092005200841086a290000370300200120093703c80820081029200420012903c808370000200441086a2005290300370000200141b8046a41086a2006290300370300200141b8046a41106a200c290300370300200141b8046a41186a200a290300370300200120012903d8043703b804200141b8046aad428080808080048410040b200141d8046a41186a220a4200370300200141d8046a41106a220c4200370300200141d8046a41086a22064200370300200142003703d80441eebec500ad4280808080f00084100122082900002109200141c8086a41086a2205200841086a290000370300200120093703c8082008102920062005290300370300200120012903c8083703d80441b480c200ad4280808080d002841001220829000021092005200841086a290000370300200120093703c80820081029200420012903c808370000200441086a2005290300370000200141b8046a41086a2006290300370300200141b8046a41106a200c290300370300200141b8046a41186a200a290300370300200120012903d8043703b804200141003a00b805200141b8046aad4280808080800484200141b8056aad428080808010841003200141e8056a20211094020b024002400240024020012802e805222a450d00200141d8046a41186a22084200370300200141d8046a41106a220a4200370300200141d8046a41086a22054200370300200142003703d80441eebec500ad4280808080f00084100122062900002109200141c8086a41086a221d200641086a290000370300200120093703c808200610292005201d290300370300200120012903c8083703d80441c4f5c100ad4280808080a00184100122062900002109201d200641086a290000370300200120093703c80820061029200420012903c808370000200441086a201d290300370000200141b8046a41086a2005290300370300200141b8046a41106a200a290300370300200141b8046a41186a2008290300370300200120012903d8043703b804200141206a200141b8046a412010fc0120012001280224410020012802201b3602b805200141e8056a41086a280200210520012802ec0521162001410036029806200142083703900620014190066a41002005410574220e41057510ac01200128029806210c20012802900621040240200e450d002004200c41d0006c6a2105200141b00c6a41206a2108202a21060340200141f0096a41086a220f200641086a290000370300200141f0096a41106a2210200641106a290000370300200141f0096a41186a221c200641186a290000370300200120062900003703f009200141b8066a20012802b805200141f0096a10d70120014188076a20012802b806221920012802c00610a102200141c8086a41186a221720014188076a41186a290300370300200141c8086a41106a221e20014188076a41106a290300370300201d20014188076a41086a29030037030020012001290388073703c8080240024020012802a807220a0d00200141900b6a41186a4200370300200141900b6a41106a42003703004108210a200141900b6a41086a4200370300200142003703900b410021174100211e0c010b200141900b6a41086a201d290300370300200141900b6a41106a201e290300370300200141900b6a41186a2017290300370300200120012903c8083703900b20012802ac07211720012802b007211e20012802b407211f0b024020012802bc06450d00201910290b200641206a2106200820012903900b370300200141b00c6a41086a2219200f290300370300200141b00c6a41106a220f2010290300370300200141b00c6a41186a2210201c290300370300200841186a200141900b6a41186a290300370300200841106a200141900b6a41106a290300370300200841086a200141900b6a41086a290300370300200120012903f0093703b00c200541386a200141b00c6a41386a290300370300200541306a200141b00c6a41306a290300370300200541286a200141b00c6a41286a290300370300200541206a2008290300370300200541186a2010290300370300200541106a200f290300370300200541086a2019290300370300200520012903b00c370300200541cc006a201f360200200541c8006a201e360200200541c4006a2017360200200541c0006a200a360200200541d0006a2105200c41016a210c200e41606a220e0d000b0b2001200c360298060240201641ffffff3f71450d00202a10290b2004450d00200128029406210e200141003602b80c200142013703b00c200141b00c6a4100200c109e0120012802b80c21080240200c41d0006c22050d0020012802b00c212a0c020b200420056a210a20012802b00c222a20084105746a210520042106034020052006290000370000200541186a200641186a290000370000200541106a200641106a290000370000200541086a200641086a290000370000200841016a2108200541206a2105200a200641d0006a2206470d000c020b0b200141900b6a41002021417f6a2205200520214b1b10fa01200141b00c6a20012802900b220520012802980b10c30620014188076a41086a2206200141bc0c6a29020037030020014188076a41106a2208200141c40c6a29020037030020014188076a41186a220a200141cc0c6a290200370300200120012902b40c370388070240024020012802b00c4101470d00200141d40c6a280200210c200141c8086a41186a200a290300370300200141c8086a41106a2008290300370300200141c8086a41086a200629030037030020012001290388073703c808024020012802940b450d00200510290b200141b00c6a41186a200141c8086a41186a290300370300200141b00c6a41106a200141c8086a41106a290300370300200141b00c6a41086a200141c8086a41086a290300370300200120012903c8083703b00c20014188076a202110fa0120013502900721092001280288072108410410272206450d06412010272205450d06200520012903b00c370000200541186a220a200141b00c6a41186a290300370000200541106a220e200141b00c6a41106a290300370000200541086a220f200141b00c6a41086a290300370000200641044120102b2206450d0d20062005290000370000200641186a200a290000370000200641106a200e290000370000200641086a200f290000370000200510292006412041c000102b2205450d0d2005200c36002020094220862008ad842005ad4280808080c00484100320051029200128028c07450d01200810290c010b20012802940b450d00200510290b410121164100212a0c010b200120083602b80c20012902b40c210d2001200c360290072001200e36028c072001200436028807200141b00c6a20014188076a10bb030240024020012802b00c4101470d0020012902b40c210941cbb8c800ad4280808080f006841008200910080c010b200141b00c6a41186a280200210e200141cc0c6a280200210f200141b00c6a41206a2802002106200141b00c6a41306a2802002119200141e40c6a280200211020014188076a200141b00c6a41386a41c80010e4071a200141c8086a41186a200141c8076a290300370300200141d8086a20014188076a41386a290300370300200141d0086a20014188076a41306a290300370300200120012903b0073703c808200141900b6a202110fa0120013502980b210920012802900b210a410410272208450d04412010272205450d04200520012903c808370000200541186a221c200141c8086a41186a290300370000200541106a2217200141c8086a41106a290300370000200541086a221e200141c8086a41086a290300370000200841044120102b2208450d0b20082005290000370000200841186a201c290000370000200841106a2017290000370000200841086a201e290000370000200510292008412041c000102b2205450d0b2005200c3600202009422086200aad842005ad4280808080c00484100320051029024020012802940b450d00200a10290b0240200e450d00200f41046a2105200f200e41016a221c6a210a200f280200417f7341808182847871210c0240034002400240200c450d00200c21080c010b03402005200a4f0d03200641c0016a210620052802002108200541046a220c21052008418081828478712208418081828478460d000b2008418081828478732108200c21050b2008417f6a200871210c200620086841037641306c6a220841246a280200450d00200828022010290c000b0b0240200e41086a200e41056a490d00201cad42307e422088a71a0b200f10290b2010450d00201910290b202a4521164101211f200d2109202a2121202a0d010b200141b00c6a41186a4200370300200141b00c6a41106a22084200370300200141b00c6a41086a22054200370300200142003703b00c41b1dcc900ad4280808080f000841001220629000021092005200641086a290000370300200120093703b00c2006102941b8dcc900ad4280808080a00184100122062900002109200141c8086a41086a220a200641086a290000370300200120093703c80820061029200820012903c808220937030020014188076a41086a200529030037030020014188076a41106a200937030020014188076a41186a200a290300370300200120012903b00c37038807200141b00c6a20014188076a108d0220012902b40c420020012802b00c22051b21092005410120051b21214100211f0b2001201f3a00b80420012020202c6a3602dc04200120203602d8042001200141d8046a3602bc052001200141b8046a3602b805200141003602f005200142013703e805200141e8056a41002009422088a722054105742206410575108e0120012802f005211920012802e805211d02402005450d00201d201941c0016c6a21082019200641606a4105766a213a200141b00c6a41206a211c200141f0096a4180016a212c200141f0096a41e0006a2104200141f0096a41c0006a2119200141f0096a41206a211e20014188076a4101722117202121050340200141b8066a41186a220a200541186a290000370300200141b8066a41106a220c200541106a290000370300200141b8066a41086a220e200541086a290000370300200120052900003703b80620014190066a200141b8066a10b50520014188076a200128029006221020012802980610b60520012d008807210f200141c8086a201741a00110e4071a02400240200f4101470d00200141900b6a200141c8086a41a00110e4071a0240200128029406450d00201010290b200141f0096a200141900b6a41a00110e4071a0c010b0240200128029406450d00201010290b200141f0096a410041a00110e6071a0b024020012802b8052d00000d0020012802bc052210280200220f2010280204460d002010200f41c0016a36020002400240200141f0096a200f41206a2210460d002010200141f0096a412010e7070d010b0240201e200f41c0006a2210460d002010201e412010e7070d010b02402019200f41e0006a2210460d0020102019412010e7070d010b02402004200f4180016a2210460d0020102004412010e7070d010b202c200f41a0016a220f460d01200f202c412010e707450d010b20012802b80541013a00000b200541206a2105200141b00c6a41186a200a290300370300200141b00c6a41106a200c290300370300200141b00c6a41086a200e290300370300200120012903b8063703b00c201c200141f0096a41a00110e4071a2008200141b00c6a41c00110e40741c0016a2108200641606a22060d000b203a41016a21190b200120193602f0050240200942ffffff3f83500d00202110290b2019ad42c0017e2209422088a70d022009a72205417f4c0d0220012802ec05212120012d00b804212c0240024020050d00410121060c010b200510272206450d020b200141003602900720012006360288072001200541c0016e36028c0720014188076a41002019108e01200128029007210f0240024020190d0020012802880721170c010b201d201941c0016c6a211c2001280288072217200f41c0016c6a2110200141b00c6a41a0016a2106200141b00c6a4180016a2108200141b00c6a41e0006a210a200141b00c6a41c0006a210c200141b00c6a41206a210e201d21050340200141b00c6a41186a200541186a290000370300200141b00c6a41106a200541106a290000370300200141b00c6a41086a200541086a290000370300200120052900003703b00c200e41186a200541386a290000370000200e41106a200541306a290000370000200e41086a200541286a290000370000200e200541206a290000370000200c200541c0006a290000370000200c41086a200541c8006a290000370000200c41106a200541d0006a290000370000200c41186a200541d8006a290000370000200a200541e0006a290000370000200a41086a200541e8006a290000370000200a41106a200541f0006a290000370000200a41186a200541f8006a290000370000200820054180016a290000370000200841086a20054188016a290000370000200841106a20054190016a290000370000200841186a20054198016a2900003700002006200541a0016a290000370000200641086a200541a8016a290000370000200641186a200541b8016a290000370000200641106a200541b0016a290000370000200f41016a210f2010200141b00c6a41c00110e40741c0016a2110200541c0016a2205201c470d000b0b200128028c072104200141b00c6a41186a220a4200370300200141b00c6a41106a220c4200370300200141b00c6a41086a22064200370300200142003703b00c41b1dcc900ad4280808080f0008410012208290000210920014188076a41086a2205200841086a2900003703002001200937038807200810292006200529030037030020012001290388073703b00c4182f0c900ad4280808080a001841001220829000021092005200841086a290000370300200120093703880720081029200b200129038807370000200b41086a2005290300370000200141900b6a41086a2006290300370300200141900b6a41106a200c290300370300200141900b6a41186a200a290300370300200120012903b00c3703900b200f41c0016c4104722205417f4c0d02200510272206450d01200141003602b80c200120053602b40c200120063602b00c200f200141b00c6a107102400240200f0d0020012802b80c210520012802b40c210f20012802b00c21060c010b2017200f41c0016c6a211e410020012802b80c220e6b210a20012802b40c210f410021080340200e20086a210c02400240200f200a6a4120490d0020012802b00c2106200f21100c010b200c41206a2205200c490d06200f41017422062005200620054b1b22104100480d0602400240200f0d00024020100d00410121060c020b201010272206450d0d0c010b20012802b00c2106200f2010460d002006200f2010102b2206450d0c0b200120103602b40c200120063602b00c0b2006200e6a20086a220f201720086a2205290000370000200f41186a200541186a290000370000200f41106a200541106a290000370000200f41086a200541086a2900003700002001200c41206a220f3602b80c024002402010200a6a41606a411f4d0d002010210f0c010b200f41206a221c200f490d062010410174220f201c200f201c4b1b220f4100480d060240024020100d000240200f0d00410121060c020b200f10272206450d0d0c010b2010200f460d0020062010200f102b2206450d0c0b2001200f3602b40c200120063602b00c0b2006200e6a20086a221041206a200541206a290000370000201041386a200541386a290000370000201041306a200541306a290000370000201041286a200541286a2900003700002001200c41c0006a22103602b80c02400240200f200a6a41406a411f4d0d00200f21100c010b201041206a221c2010490d06200f4101742210201c2010201c4b1b22104100480d0602400240200f0d00024020100d00410121060c020b201010272206450d0d0c010b200f2010460d002006200f2010102b2206450d0c0b200120103602b40c200120063602b00c0b2006200e6a20086a220f41c0006a200541c0006a290000370000200f41d8006a200541d8006a290000370000200f41d0006a200541d0006a290000370000200f41c8006a200541c8006a2900003700002001200c41e0006a220f3602b80c024002402010200a6a41a07f6a411f4d0d002010210f0c010b200f41206a221c200f490d062010410174220f201c200f201c4b1b220f4100480d060240024020100d000240200f0d00410121060c020b200f10272206450d0d0c010b2010200f460d0020062010200f102b2206450d0c0b2001200f3602b40c200120063602b00c0b2006200e6a20086a221041e0006a200541e0006a290000370000201041f8006a200541f8006a290000370000201041f0006a200541f0006a290000370000201041e8006a200541e8006a2900003700002001200c4180016a22103602b80c02400240200f200a6a41807f6a411f4d0d00200f21100c010b201041206a221c2010490d06200f4101742210201c2010201c4b1b22104100480d0602400240200f0d00024020100d00410121060c020b201010272206450d0d0c010b200f2010460d002006200f2010102b2206450d0c0b200120103602b40c200120063602b00c0b2006200e6a20086a220f4180016a20054180016a290000370000200f4198016a20054198016a290000370000200f4190016a20054190016a290000370000200f4188016a20054188016a2900003700002001200c41a0016a220f3602b80c024002402010200a6a41e07e6a411f4d0d002010210f0c010b200f41206a221c200f490d062010410174220f201c200f201c4b1b220f4100480d060240024020100d000240200f0d00410121060c020b200f10272206450d0d0c010b2010200f460d0020062010200f102b2206450d0c0b2001200f3602b40c200120063602b00c0b2006200e6a20086a221041a0016a200541a0016a290000370000201041b8016a200541b8016a290000370000201041b0016a200541b0016a290000370000201041a8016a200541a8016a2900003700002001200c41c0016a3602b80c200a41c07e6a210a200841c0016a2108200541c0016a201e470d000b200e20086a21050b20072005ad4220862006ad8410030240200f450d00200610290b02402004450d00200441c0016c450d00201710290b200141b00c6a41186a220a4200370300200141b00c6a41106a220c4200370300200141b00c6a41086a22064200370300200142003703b00c41b1dcc900ad4280808080f0008410012208290000210920014188076a41086a2205200841086a2900003703002001200937038807200810292006200529030037030020012001290388073703b00c41a886ca00ad4280808080d001841001220829000021092005200841086a290000370300200120093703880720081029200b200129038807370000200b41086a2005290300370000200141900b6a41086a2006290300370300200141900b6a41106a200c290300370300200141900b6a41186a200a290300370300200120012903b00c3703900b2001202c3a00b00c20072002428080808010841003200120223602b40c200141063a00b00c200141b00c6a10cb0120232020201a201d201910e60602402021450d00202141c0016c450d00201d10290b0240201f2016720d00200d42ffffff3f83500d00202a10290b0240202e41ffffff3f71450d00201b10290b4280c0a8ca9a3a21022036a72205450d00200541c0016c450d00202010290b42002107200141d8046a41186a220c4200370300200141d8046a41106a22064200370300200141d8046a41086a22054200370300200142003703d80441eebec500ad4280808080f000841001220829000021092005200841086a290000370300200120093703d8042008102941eab8c000ad4280808080900284100122082900002109200141c8086a41086a220a200841086a290000370300200120093703c80820081029200620012903c8082209370300200141b8046a41086a22082005290300370300200141b8046a41106a220e2009370300200141b8046a41186a220f200a290300370300200120012903d8043703b804200141186a200310b1012001280218417d710d06200c42003703002006420037030020054200370300200142003703d80441f5bec500ad428080808080018422371001221029000021072005201041086a290000370300200120073703d80420101029419bc1c200ad42808080808002842238100122102900002107200a201041086a290000370300200120073703c80820101029200620012903c808370000200641086a200a29030037000020082005290300370300200e2006290300370300200f200c290300370300200120012903d8043703b804200141b00c6a200310ed02200120012802b00c2205410420051b22203602900b024020012902b40c420020051b2236422088a7220c0d00420021070c060b4100210642002107202021054100210803400240024002400240200742ffbfcbacf622560d00200141086a2005280200200541086a2802002005410c6a280200200541146a280200200541186a280200108a022001290308a7450d010b20060d01410021060c020b200641016a2106200720012903107c21070c010b200820066b220a200c4f0d05200141b00c6a41186a220e2005200641646c6a220a41186a220f280200360200200141b00c6a41106a2210200a41106a221c290200370300200141b00c6a41086a2217200a41086a221e2902003703002001200a2902003703b00c200541086a22192902002109200541106a220b290200210d200541186a221d280200211f200a2005290200370200200f201f360200201c200d370200201e2009370200201d200e280200360200200b201029030037020020192017290300370200200520012903b00c3702000b2005411c6a2105200c200841016a2208460d050c000b0b1039000b1038000b1032000b200a200c4180bdc7001036000b2006450d00200c2006490d002020200c20066b220c411c6c6a200610f102203642ffffffff0f8321360b20012802900b2105200141b8056a41186a4200370300200141b8056a41106a220a4200370300200141b8056a41086a22064200370300200142003703b80520371001220829000021092006200841086a290000370300200120093703b805200810292038100122082900002109200141c8086a41086a220e200841086a290000370300200120093703c80820081029200a20012903c8082209370300200141b00c6a41086a2006290300370300200141b00c6a41106a2009370300200141b00c6a41186a200e290300370300200120012903b8053703b00c024020050d00200141b00c6aad428080808080048410040c010b2036a7210620014188076a2005200c10f002200141b00c6aad42808080808004842001350290074220862001280288072208ad8410030240200128028c07450d00200810290b2005200c10f1022006450d002006411c6c450d00200510290b200010b0012109200141f00d6a2400427f2002427f200720097c220920092007541b7c220720072002541b0f0b1030000b130020004101360204200041a4b3c4003602000b3400200041e4bec50036020420004100360200200041146a4103360200200041106a41a4b4c400360200200041086a420a3702000b9b0902097f037e230041206b220224002002410036020820024201370300024002400240412010272203450d0020032001290010370000200341186a2204200141286a290000370000200341106a2205200141206a290000370000200341086a2206200141186a290000370000412010272207450d02200241203602042002200736020020072003290000370000200741086a2006290000370000200741106a2005290000370000200741186a200429000037000020024120360208200310292001200210e601412010272203450d0020032001290030370000200341186a200141c8006a290000370000200341106a200141c0006a290000370000200341086a200141386a2900003700000240024020022802042208200228020822066b4120490d00200641206a210720022802002104200821050c010b200641206a22072006490d02200841017422042007200420074b1b22054100480d020240024020080d00024020050d00410121040c020b2005102722040d010c050b2002280200210420082005460d00200420082005102b2204450d040b20022005360204200220043602000b200420066a22062003290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a2900003700002002200736020820031029412010272203450d0020032001290050370000200341186a200141e8006a290000370000200341106a200141e0006a290000370000200341086a200141d8006a2900003700000240200520076b411f4b0d00200741206a22062007490d02200541017422082006200820064b1b22064100480d020240024020050d00024020060d00410121040c020b200610272204450d050c010b20052006460d00200420052006102b2204450d040b20022006360204200220043602000b200420076a22042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a2900003700002002200741206a36020820031029200128020421052001410c6a2802002201200210710240024020010d002002280208210320022802042104200228020021080c010b200141246c210920022802042107200228020821010340200241106a200510bc022002280210210a02400240200720016b20022802182206490d00200120066a210320022802002108200721040c010b200120066a22032001490d04200741017422042003200420034b1b22044100480d040240024020070d00024020040d00410121080c020b200410272208450d070c010b2002280200210820072004460d00200820072004102b2208450d060b20022004360204200220083602000b200820016a200a200610e4071a2002200336020802402002280214450d00200a10290b200541246a210520042107200321012009415c6a22090d000b0b2003ad4220862008ad8410102201290000210b200141086a290000210c200141106a290000210d200041186a200141186a290000370000200041106a200d370000200041086a200c3700002000200b3700002001102902402004450d00200810290b200241206a24000f0b1039000b1032000b1030000b13002000410636020420004180bac4003602000b3400200041d482cc0036020420004100360200200041146a4109360200200041106a41d4d6c400360200200041086a42053702000b4d01027f230041106b220224000240410110272203450d00200341003a0000200041086a4101360200200241013602042002200336020020002002290300370200200241106a24000f0b1039000b2401017f230041b0046b22022400200241033602002000200210e702200241b0046a24000b2201017f230041106b22022400200241003602002000200210e802200241106a24000b930d04067f017e047f017e230041e0006b22022400200241306a200110dc06410221030240200228023022042002280238220510900641ff017122064102460d002005ad4220862004ad841004200621030b02402002280234450d00200410290b41022003410171200341024622031b21040240024002400240024002400240024020030d0020044101710d04200241306a41186a4200370300200241306a41106a22074200370300200241306a41086a220442003703002002420037033041d787cc00ad4280808080900184100122052900002108200241d0006a41086a2203200541086a2900003703002002200837035020051029200420032903003703002002200229035037033041cd87cc00ad4280808080a001841001220529000021082003200541086a2900003703002002200837035020051029200720022903502208370300200241106a41086a2004290300370300200241106a41106a2008370300200241106a41186a200329030037030020022002290330370310200241306a200241106a412010c0044101210920022802302203410420031b210a2002290234420020031b2208422088a7220b41014b0d0141002103200b0e020302030b41b3d3c8002103411121014100210502400240024020040e03000201000b200241c4006a41013602002002420137023420024198e3ca0036023020024104360214200241bcd4c8003602102002200241106a360240200241306a4180a6cc001040000b41c4d3c8002103410e2101410121050b2000411a3a0001200041086a2001360200200041046a2003360200200041026a20053a00000c050b41002103200b2104034020032004410176220520036a2206200a20064102746a28020020014b1b2103200420056b220441014b0d000b0b200a20034102746a22042802002001470d002003200b4f0d022004200441046a2003417f73200b6a41027410e5071a200842ffffffff0f832108200b417f6a210b410021090b200241306a41186a22064200370300200241306a41106a220c4200370300200241306a41086a220442003703002002420037033041d787cc00ad428080808090018410012205290000210d200241d0006a41086a2203200541086a2900003703002002200d37035020051029200420032903003703002002200229035037033041cd87cc00ad4280808080a0018410012205290000210d2003200541086a2900003703002002200d3703502005102920072002290350370000200741086a2003290300370000200241106a41086a2004290300370300200241106a41106a200c290300370300200241106a41186a200629030037030020022002290330370310200241203602342002200241106a360230200a200b200241306a10ef030240200842ffffffff0383500d00200a10290b2009450d002000419a023b0001200041086a410e360200200041046a41c4d3c8003602000c020b200241106a200110ac03200241306a2002280210220420022802182205108b03024020022802302203450d002005ad4220862004ad8410040b2002290234210802402002280214450d00200410290b200241306a2001108f06200235023842208620022802302204ad84100402402002280234450d00200410290b200241306a2001108906200241086a200228023022042002280238220610fc010240200228020822054101470d002006ad4220862004ad8410040b02402002280234450d00200410290b024020054101470d00200241306a2001108a06200235023842208620022802302204ad8410042002280234450d00200410290b02402003450d00200241306a41186a4200370300200241306a41106a22064200370300200241306a41086a220442003703002002420037033041b3e6ca00ad4280808080e0008410012205290000210d2004200541086a2900003703002002200d3703302005102941c9e6ca00ad4280808080e0008410012205290000210d200241d0006a41086a220a200541086a2900003703002002200d3703502005102920062002290350220d370300200241106a41086a2004290300370300200241106a41106a200d370300200241106a41186a200a290300370300200220022903303703102002200241106a412010fc012002280204210420022802002105200220083702342002200336023020012004410020051b200241306a108b060b200241306a200110dc06200235023842208620022802302203ad84100402402002280234450d00200310290b410421030c020b2003200b1042000b410321030b200020033a0000200241e0006a24000bfc02010b7f200241016a210320022d00002104200128020821052001280204210620012802002107034020062f0106220841226c2109410021024100210a0240024002400340200a210b024020092002470d002008210b0c020b024002402004200620026a220c41086a2d0000220a460d004101210c2004200a4f0d010c030b02400240024020040e03000102000b02402003200c41096a412010e707220a0d004100210d0c060b4101210c200a41004e0d020c040b02402003200c41096a412010e707220a0d004100210d0c050b4101210c200a41004e0d010c030b4100210d2003200c41096a412110e707220a450d03417f4101200a4100481b210c0b200b41016a210a200241226a2102200c417f470d000b0b20070d014101210d410021070b200020073602042000200d360200200041106a200b3602002000410c6a2005360200200041086a20063602000f0b2001200536020820012007417f6a220736020020012006200b4102746a4180036a28020022063602040c000b0b130020004107360204200041a4f2c4003602000bab2c06047f017e017f017e067f047e230041e0166b2207240020074198126a41186a2208420037030020074198126a41106a2209420037030020074198126a41086a220a4200370300200742003703981241d482cc00ad4280808080d00084220b1001220c290000210d200741e80d6a41086a220e200c41086a2900003703002007200d3703e80d200c1029200a200e290300370300200720072903e80d3703981241d982cc00ad4280808080e001841001220c290000210d200e200c41086a2900003703002007200d3703e80d200c1029200920072903e80d220d370300200741d8006a41086a220c200a290300370300200741d8006a41106a220f200d370300200741d8006a41186a2210200e2903003703002007200729039812370358200741d0006a200741d8006a412010fc01024002400240024002400240024002402007280254410020072802501b2002470d002008420037030020094200370300200a42003703002007420037039812200b10012202290000210d200e200241086a2900003703002007200d3703e80d20021029200a200e290300370300200720072903e80d3703981241fab1c400ad4280808080b0018410012202290000210d200e200241086a2900003703002007200d3703e80d20021029200920072903e80d370000200941086a200e290300370000200c200a290300370300200f2009290300370300201020082903003703002007200729039812370358200741b8096a200741d8006a412010f90120072802b8094101470d0241eda5c700210e411e210a20072802bc09220941036a2004490d06200320044b0d06200920034b0d06200420036b220e20044d0d01418ba6c700210e411b210a0c060b20004183323b0100200041086a4111360200200041046a41b79ec400360200200041026a41093a00000c060b0240200320096b220a20034d0d0041a6a6c700210e4116210a0c050b0240200a41034d0d0041bca6c700210e4115210a0c050b02400240024002400240200a0e0400010203000b200e4104490d050c070b200e41034f0d06200e41046a21020c050b200e41014b0d0541072102200e0e020401040b200e0d04410921020c030b410821020c020b20004183323b0100200041086a410a360200200041046a41c89ec400360200200041026a410a3a00000c040b200e21020b20074198126a41186a2208420037030020074198126a41106a220a420037030020074198126a41086a220e4200370300200742003703981241b3e6ca00ad4280808080e0008410012209290000210d200e200941086a2900003703002007200d370398122009102941c9e6ca00ad4280808080e000841001220c290000210d200741e80d6a41086a2209200c41086a2900003703002007200d3703e80d200c1029200a20072903e80d220d370300200741d8006a41086a2204200e290300370300200741d8006a41106a2203200d370300200741d8006a41186a220f20092903003703002007200729039812370358200741c8006a200741d8006a412010fc01200728024c21102007280248211120084200370300200a4200370300200e4200370300200742003703981241d482cc00ad4280808080d000841001220c290000210d200e200c41086a2900003703002007200d37039812200c102941fab1c400ad4280808080b001841001220c290000210d2009200c41086a2900003703002007200d3703e80d200c1029200a20072903e80d220d3703002004200e2903003703002003200d370300200f20092903003703002007200729039812370358200741b8096a200741d8006a412010f9010240024020072802b8094101460d00410021120c010b410021122010410020111b220e200741b8096a41086a2802006b220a200e4b0d00200a4100200a41e807491b21120b20074188056a201210b90420074198126a200728028805220e20072802900510bc04200728029812210c200741e80d6a20074198126a41047241ac0410e4071a024002400240200c4103460d00200741b8096a200741e80d6a41ac0410e4071a0240200728028c05450d00200e10290b20074188056a200741b8096a41ac0410e4071a0c010b0240200728028c05450d00200e10290b02402012417f6a220e20124b0d00200741c8166a200e10b90420074198126a20072802c816220e20072802d01610bc04200728029812210c200741e80d6a20074198126a41047241ac0410e4071a0240200c4103460d0020074188056a200741e80d6a41ac0410e4071a20072802cc16450d02200e10290c020b20072802cc16450d00200e10290b4102210c200741023602d0042007410236029804200741023602e003200741023602a803200741023602f002200741023602b8022007410236028002200741023602c8012007410236029001200741023602580c010b2007200c360258200741d8006a41047220074188056a41ac0410e4071a0b0240024002400240200741d8006a200241ff0171221341386c6a220f2802004102460d00200f41286a290300200554200f41306a290300220d200654200d2006511b450d010b200141086a21102002410f7121114100210e41002109024002400340200741d8006a200e6a210a0240200c410246220c0d004100200a200c1b220c28020022022001280200470d000240024020020d000240200c41086a22022010460d0020022010412010e7070d030b200c2802042001280204470d020c010b200c2802042001280204470d010b024002400240200941094b0d004100210c0240024002400240024002400240024020090e0a0a0900010203040506070a0b4102210c0c090b4103210c0c080b4104210c0c070b4105210c0c060b4106210c0c050b4107210c0c040b4108210c0c030b4109210c0c020b41f8f5c40041c50020074198126a41c0f6c40041d0f6c400103a000b4101210c0b41032103410321084103210202400240024002400240024002400240024002400240024002400240024002400240024002400240024020110e0a0001020304050607080a000b410021084100210241032104200c0e0a0a0b0c0d0e0f101112130a0b410021024101210841032104200c0e0a090a0b0c0d0e0f101112090b410021024102210841032104200c0e0a08090a0b0c0d0e0f1011080b410021020c050b410121084101210241032104200c0e0a060708090a0b0c0d0e0f060b410121024102210841032104200c0e0a05060708090a0b0c0d0e050b410121020c020b410221084102210241032104200c0e0a030405060708090a0b0c030b410221020b410321080b41032104200c0e0a00010203040506070809000b41002103410021040c080b41002104410121030c070b41002104410221030c060b410021040c050b41012103410121040c040b41012104410221030c030b410121040c020b410221030b410221040b200220034b0d02200420084b0d020b200e41f803460d02200e41386a210e200941016a2109200a41386a280200210c0c000b0b20004183323b0100200041086a4114360200200041046a41a39ec400360200200041026a41083a00000c060b4200210d4200210b024020012802004101470d00200741386a200128020410bf04200741c0006a290300210b2007290338210d0b20074198126a200110bd04200741206a200728029812220a20072802a01210e301200741306a2903002114200729032821152007280220210e0240200728029c12450d00200a10290b0240200520154200200e1b2216200d7c220d7d2215200556200620144200200e1b200b7c200d201654ad7c7d2005200d54ad7d220d200656200d2006511b0d000240024020012802004101470d00200741b8096a200141046a10cc030c010b200741b8096a41186a200141206a290000370300200741b8096a41106a200141186a290000370300200741b8096a41086a200141106a2900003703002007200141086a2900003703b8090b20072015370388052007200d370390052007200741b8096a3602d8164104210e02402015200d84500d002007200741b8096a3602dc162007200741dc166a3602a0122007200741d8166a36029c12200720074188056a36029812200741e80d6a200741b8096a20074198126a108e04024020072802e80d4101470d00200720072900ed0d370398122007200741f40d6a28000036009f1220072d00ec0d210e0c010b4104210e200741e80d6a41086a2903004201520d00200741e80d6a41106a290300210b20072802dc16210a200741d0126a200741e80d6a41186a290300370300200741c8126a200b37030020074198126a41086a41003a0000200741a1126a200a290000370000200741a9126a200a41086a290000370000200741b1126a200a41106a290000370000200741b9126a200a41186a290000370000200741033a00981220074198126a10cb010b20072007290398123703c8162007200728009f123600cf160240200e41ff01714104460d002000200e3a0000200020072903c816370001200041086a20072800cf163600000c070b200741e80d6a200110bd0420072802e80d210e20073502f00d210b200720063703a0122007200537039812200b422086200ead8420074198126aad42808080808002841003024020072802ec0d450d00200e10290b0240024020012802004101470d0020074198126a200141046a10cc030c010b20074198126a41186a200141206a29000037030020074198126a41106a200141186a29000037030020074198126a41086a200141106a2900003703002007200141086a290000370398120b200741e80d6a41186a20074198126a41186a290300220b370300200741e80d6a41106a20074198126a41106a2903002214370300200741e80d6a41086a20074198126a41086a220e2903002216370300200720072903981222173703e80d200741e0126a2006370300200741d8126a2005370300200741d0126a200d370300200741c8126a2015370300200e41053a0000200741a1126a2017370000200741a9126a2016370000200741b1126a2014370000200741b9126a200b370000200741c1126a20072800b809360000200741c4126a200741bb096a2800003600002007410f3a00981220074198126a10cb010b200f290310210b200f2001290210370310200f2903082115200f2001290208370308200f290300210d200f2001290200370300200f41186a220e2903002114200e200141186a290200370300200741d8006a201341386c6a220e41306a2006370200200e41286a2005370200200e41206a220e2902002106200e200141206a290200370200200da7220e4102460d02200d422088a7210a200741b8096a41206a20063703002007200d3703b809200741b8096a41186a2014370300200720153703c0092007200b3703c809200741c0096a21092007280258220c4102460d01200c200e470d010240200e4101460d00200741e0006a2009412010e7070d02200728025c200a460d030c020b200728025c200a470d010c020b200041043a00000c040b0240200728029001220c4102460d00200c200e470d000240200e4101460d0020074198016a2009412010e7070d0120074194016a280200200a460d020c010b20074194016a280200200a460d010b024020072802c801220c4102460d00200c200e470d000240200e4101460d00200741d0016a2009412010e7070d01200741cc016a280200200a460d020c010b200741cc016a280200200a460d010b0240200728028002220c4102460d00200c200e470d000240200e4101460d0020074188026a2009412010e7070d0120074184026a280200200a460d020c010b20074184026a280200200a460d010b024020072802b802220c4102460d00200c200e470d000240200e4101460d00200741c0026a2009412010e7070d01200741bc026a280200200a460d020c010b200741bc026a280200200a460d010b024020072802f002220c4102460d00200c200e470d000240200e4101460d00200741f8026a2009412010e7070d01200741f4026a280200200a460d020c010b200741f4026a280200200a460d010b024020072802a803220c4102460d00200c200e470d000240200e4101460d00200741b0036a2009412010e7070d01200741ac036a280200200a460d020c010b200741ac036a280200200a460d010b024020072802e003220c4102460d00200c200e470d000240200e4101460d00200741e8036a2009412010e7070d01200741e4036a280200200a460d020c010b200741e4036a280200200a460d010b0240200728029804220c4102460d00200c200e470d000240200e4101460d00200741a0046a2009412010e7070d012007419c046a280200200a460d020c010b2007419c046a280200200a460d010b024020072802d004220c4102460d00200c200e470d000240200e4101460d00200741d8046a2009412010e7070d01200741d4046a280200200a460d020c010b200741d4046a280200200a460d010b20074198126a200741b8096a10bd04200741086a200728029812220a20072802a012220910e301200741186a290300210b2007290310210d0240200729030822064201520d002009ad422086200aad8410040b2006a721090240200728029c12450d00200a10290b20094101470d0002400240200e4101470d0020074188056a200741b8096a41047210cc030c010b20074188056a41186a200741d8096a29030037030020074188056a41106a200741b8096a41186a29030037030020074188056a41086a200741b8096a41106a2903003703002007200741b8096a41086a290300370388050b2007200d3703c8162007200b3703d0160240200d200b84500d00200720074188056a3602dc16200741e80d6a20074188056a200741c8166a200741dc166a10ea0320072903e80d4201520d0020072903f00d2106200741d0126a200741e80d6a41106a290300370300200741c8126a200637030020074198126a41086a41003a0000200741a1126a200729038805370000200741a9126a20074188056a41086a290300370000200741b1126a20074188056a41106a290300370000200741b9126a200741a0056a290300370000200741033a00981220074198126a10cb010b02400240200e4101470d0020074198126a200741b8096a41047210cc030c010b20074198126a41186a200741d8096a29030037030020074198126a41106a200741b8096a41186a29030037030020074198126a41086a200741b8096a41106a2903003703002007200741b8096a41086a290300370398120b200741e80d6a41186a20074198126a41186a2903002206370300200741e80d6a41106a20074198126a41106a2903002205370300200741e80d6a41086a20074198126a41086a220e2903002215370300200720072903981222143703e80d200741d0126a200b370300200741c8126a200d370300200e41063a0000200741a1126a2014370000200741a9126a2015370000200741b1126a2005370000200741b9126a2006370000200741c1126a20072800c816360000200741c4126a200741cb166a2800003600002007410f3a009812200741d8126a200729038805370300200741e0126a20074188056a41086a29030037030020074198126a10cb010b20074198126a201210b904200728029812210e200720072802a0123602ec0d2007200e3602e80d200741d8006a200741e80d6a10f2020240200728029c12450d00200e10290b200041043a00000c020b41d1a6c700210e4113210a0b200041003a0000200041086a200a360200200041046a200e3602000b200741e0166a24000b0d00200141fcacc7004102104d0b1f0002402000280200450d00200041086a280200450d00200028020410290b0b130020004104360204200041d8fbc4003602000b3400200041d5bec50036020420004100360200200041146a4101360200200041106a41f88ac500360200200041086a42073702000b130020004101360204200041b08cc5003602000b3400200041ccbec50036020420004100360200200041146a4102360200200041106a41e093c500360200200041086a42093702000b130020004101360204200041a096c5003602000b2d01017f02404108102722020d001039000b20004288808080800137020420002002360200200242b8173700000b88090b107f017e017f017e017f017e017f017e017f017e017f230041306b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200241286a22082000200441306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e2903003703002013201029030037030020052002290300370300024020032001490d00200321040c030b2006410d7420067322044111762004732204410574200473220620077122044100200120042001491b6b220520014f0d01200241286a22082000200341306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e29030037030020132010290300370300200520022903003703002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200241286a22032000200441306c6a220141286a2204290300370300200241206a2206200141206a2207290300370300200241186a2208200141186a2209290300370300200241106a220a200141106a220b290300370300200241086a220c200141086a220d290300370300200220012903003703002000200541306c6a22002903002112200041086a22052903002114200041106a220e2903002116200041186a220f2903002118200041206a2210290300211a2004200041286a22112903003703002007201a37030020092018370300200b2016370300200d2014370300200120123703002011200329030037030020102006290300370300200f2008290300370300200e200a2903003703002005200c290300370300200020022903003703000b200241306a24000f0b200520014190bdc7001036000b200420014180bdc7001036000bf20907077f027e0b7f017e017f027e017f230041306b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d02200520062000200641306c6a22072903002000200541306c6a220829030056200741086a2903002209200841086a290300220a562009200a511b1b21060b200620014f0d03200420014f0d022000200441306c6a22042903002000200641306c6a220529030056200441086a22072903002209200541086a2208290300220a562009200a511b450d03200241286a220b200441286a220c290300370300200241206a220d200441206a220e290300370300200241186a220f200441186a2210290300370300200241106a2211200441106a2212290300370300200241086a221320072903003703002002200429030037030020082903002109200541106a2214290300210a200541186a22152903002116200541206a2217290300211820052903002119200c200541286a221a290300370300200e2018370300201020163703002012200a3703002007200937030020042019370300201a200b2903003703002017200d2903003703002015200f290300370300201420112903003703002008201329030037030020052002290300370300200621040c000b0b2006200141d89ac5001036000b2004200141e89ac5001036000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241286a220b200041286a2205290300370300200241206a220c200041206a2206290300370300200241186a220d200041186a2208290300370300200241106a220e200041106a2210290300370300200241086a220f200041086a2211290300370300200220002903003703002000200741306c6a22042903002109200441086a290300210a200441106a2903002116200441186a2903002118200441206a29030021192005200441286a2903003703002006201937030020082018370300201020163703002011200a3703002000200937030041002105024002400240034020042002290300370300200441286a200b290300370300200441206a200c290300370300200441186a200d290300370300200441106a200e290300370300200441086a200f2903003703002005410174220441017221060240200441026a220420074f0d00200620074f0d02200420062000200641306c6a22082903002000200441306c6a221029030056200841086a2903002209201041086a290300220a562009200a511b1b21060b200620074f0d03200520074f0d022000200541306c6a22052903002000200641306c6a220429030056200541086a22082903002209200441086a2210290300220a562009200a511b450d03200b200541286a2211290300370300200c200541206a2212290300370300200d200541186a2213290300370300200e200541106a2214290300370300200f20082903003703002002200529030037030020102903002109200441106a290300210a200441186a2903002116200441206a2903002118200429030021192011200441286a29030037030020122018370300201320163703002014200a3703002008200937030020052019370300200621050c000b0b2006200741d89ac5001036000b2005200741e89ac5001036000b200741014b0d000b0b200241306a24000f0b200720014190bdc7001036000bb40c050b7f017e017f037e0f7f230041306b22022400200041e0006a2103200041c07e6a21042001417f6a2105200041306a2106410021072001413249210841012109024003400240024020092001490d004100210a0c010b4101210a2000200941306c220b6a220c290300220d200c41506a220e29030056200c41086a290300220f200e41086a290300221056200f2010511b0d002006200b6a210a03404101210c20052009460d03200941016a2109200a2903002211200d58210c200a41086a2903002210200f51210e2010200f58210b200a41306a210a2011210d2010210f200c200b200e1b0d000b2009200149210a0b2009200146210c20080d0120092001460d010240024002400240024002402009417f6a220c20014f0d00200a450d012000200c41306c6a220a290300210f200a2000200941306c22126a220c290300370300200241286a2213200a41286a2214290300370300200241206a2215200a41206a2216290300370300200241186a220b200a41186a2217290300370300200241106a2218200a41106a2219290300370300200241086a221a200a41086a220e290300370300200e200c41086a221b2903003703002019200c41106a221c2903003703002017200c41186a221d2903003703002016200c41206a221e2903003703002014200c41286a221f2903003703002002200f370300200c2002290300370300201f2013290300370300201e2015290300370300201d200b290300370300201c2018290300370300201b201a29030037030020094102490d05200a290300220d20002009417e6a221541306c6a221329030058200e290300220f201341086a2220290300221058200f2010511b0d05200a2013290300370300200e2020290300370300200a29031021102019201341106a290300370300200b201429030037030020182016290300370300201a20172903003703002017201341186a2903003703002016201341206a2903003703002014201341286a29030037030020022010370300024020150d00410021150c050b200d20002009417d6a220e41306c6a220a29030058200f200a41086a290300221058200f2010511b0d04200420126a210a0340200a4188016a200a41d8006a290300370300200a4180016a200a41d0006a290300370300200a41f8006a200a41c8006a290300370300200a41f0006a200a41c0006a290300370300200a41e8006a200a41386a290300370300200a41e0006a200a41306a290300370300200e450d03200a2903002110200a41086a2113200a41506a210a200e417f6a210e200d201056200f2013290300221056200f2010511b0d000b200e41016a21150c030b200c20014180bdc7001036000b200920014190bdc7001036000b410021150b2000201541306c6a21130b2013200d3703002013200f3703082000201541306c6a220a2002290300370310200a41286a200b290300370300200a41206a2018290300370300200a41186a201a2903003703000b200741016a21070240200120096b22134102490d00200c290330200c290300220d58200c41386a2903002210201b290300220f582010200f511b0d00200c200c41306a220a290300370300201b200a41086a290300370300200c2903102110201c200a41106a290300370300200b201f2903003703002018201e290300370300201a201d290300370300201d200a41186a290300370300201e200a41206a290300370300201f200a41286a290300370300200220103703004101210e024020134103490d00200c290360200d58200c41e8006a2903002210200f582010200f511b0d00200320126a210e4103211b02400340200e220a41506a220e200a290300370300200e41286a200a41286a290300370300200e41206a200a41206a290300370300200e41186a200a41186a290300370300200e41106a200a41106a290300370300200e41086a200a41086a2903003703002013201b2214460d01201441016a211b200a41306a220e290300200d56200a41386a2903002210200f562010200f511b0d000b0b2014417f6a210e0b200a200d370300200a200f370308200c200e41306c6a220a41286a200b290300370300200a41206a2018290300370300200a41186a201a290300370300200a20022903003703100b20074105470d000b4100210c0b200241306a2400200c0b88090b107f017e017f017e017f017e017f017e017f017e017f230041306b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200241286a22082000200441306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e2903003703002013201029030037030020052002290300370300024020032001490d00200321040c030b2006410d7420067322044111762004732204410574200473220620077122044100200120042001491b6b220520014f0d01200241286a22082000200341306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e29030037030020132010290300370300200520022903003703002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200241286a22032000200441306c6a220141286a2204290300370300200241206a2206200141206a2207290300370300200241186a2208200141186a2209290300370300200241106a220a200141106a220b290300370300200241086a220c200141086a220d290300370300200220012903003703002000200541306c6a22002903002112200041086a22052903002114200041106a220e2903002116200041186a220f2903002118200041206a2210290300211a2004200041286a22112903003703002007201a37030020092018370300200b2016370300200d2014370300200120123703002011200329030037030020102006290300370300200f2008290300370300200e200a2903003703002005200c290300370300200020022903003703000b200241306a24000f0b200520014190bdc7001036000b200420014180bdc7001036000bfc1407087f027e077f027e047f017e017f230041306b22032400024020014101762204450d0003402004417f6a22042105024003402005410174220641017221070240200641026a220820014f0d00024002400240200720014f0d00024020022802002802002802002209280200220a0d004200210b4200210c0c020b2000200741306c6a210d2009280204210e200a210f02400340200f41086a2110200f2f010622114105742106410021120240024003402006450d01200d2010412010e7072213450d02200641606a2106201241016a2112201041206a21102013417f4a0d000b2012417f6a21110b0240200e0d004200210b4200210c0c030b200e417f6a210e200f20114102746a41c8056a280200210f0c010b0b200f20124105746a220641f0026a290300210c200641e8026a290300210b0b200a450d012000200841306c6a210d2009280204210f0340200a41086a2110200a2f0106220e4105742106410021120240024003402006450d01200d2010412010e7072213450d02200641606a2106201241016a2112201041206a21102013417f4a0d000b2012417f6a210e0b200f450d03200f417f6a210f200a200e4102746a41c8056a280200210a0c010b0b200a20124105746a220641f0026a2903002114200641e8026a29030021150c020b2007200141d89ac5001036000b42002115420021140b20082007200b201554200c201454200c2014511b1b21070b200720014f0d010240200520014f0d0020022802002802002802002211280200220f450d022000200541306c6a210d2011280204210a200f210502400340200541086a211020052f0106220e4105742106410021120240024003402006450d01200d2010412010e7072213450d02200641606a2106201241016a2112201041206a21102013417f4a0d000b2012417f6a210e0b0240200a0d00420021144200210c0c030b200a417f6a210a2005200e4102746a41c8056a28020021050c010b0b200520124105746a220641f0026a290300210c200641e8026a29030021140b200f450d022000200741306c6a21052011280204210a0340200f41086a2110200f2f0106220e4105742106410021120240024003402006450d0120052010412010e7072213450d02200641606a2106201241016a2112201041206a21102013417f4a0d000b2012417f6a210e0b200a450d04200a417f6a210a200f200e4102746a41c8056a280200210f0c010b0b2014200f20124105746a220641e8026a29030054200c200641f0026a290300221454200c2014511b450d02200341286a2206200d41286a2210290300370300200341206a2212200d41206a2213290300370300200341186a220f200d41186a220a290300370300200341106a220e200d41106a2211290300370300200341086a2208200d41086a22092903003703002003200d2903003703002005290300210c200541086a22162903002114200541106a22172903002115200541186a2218290300210b200541206a2219290300211a2010200541286a221b2903003703002013201a370300200a200b3703002011201537030020092014370300200d200c370300201b2006290300370300201920122903003703002018200f2903003703002017200e2903003703002016200829030037030020052003290300370300200721050c010b0b2005200141e89ac5001036000b20040d000b0b0240024020014102490d002001211103402011417f6a221120014f0d02200341286a2209200041286a2206290300370300200341206a2216200041206a2210290300370300200341186a2217200041186a2212290300370300200341106a2218200041106a2213290300370300200341086a2219200041086a2205290300370300200320002903003703002000201141306c6a220d290300210c200d41086a2903002114200d41106a2903002115200d41186a290300210b200d41206a290300211a2006200d41286a2903003703002010201a3703002012200b37030020132015370300200520143703002000200c3703004100210502400340200d2003290300370300200d41286a2009290300370300200d41206a2016290300370300200d41186a2017290300370300200d41106a2018290300370300200d41086a20192903003703002005410174220641017221070240200641026a221b20114f0d00024002400240200720114f0d00024020022802002802002802002204280200220a0d00420021154200210c0c020b2000200741306c6a210d2004280204210e200a210f02400340200f41086a2110200f2f010622084105742106410021120240024003402006450d01200d2010412010e7072213450d02200641606a2106201241016a2112201041206a21102013417f4a0d000b2012417f6a21080b0240200e0d00420021154200210c0c030b200e417f6a210e200f20084102746a41c8056a280200210f0c010b0b200f20124105746a220641f0026a290300210c200641e8026a29030021150b200a450d012000201b41306c6a210d2004280204210f0340200a41086a2110200a2f0106220e4105742106410021120240024003402006450d01200d2010412010e7072213450d02200641606a2106201241016a2112201041206a21102013417f4a0d000b2012417f6a210e0b200f450d03200f417f6a210f200a200e4102746a41c8056a280200210a0c010b0b200a20124105746a220641f0026a2903002114200641e8026a290300210b0c020b2007201141d89ac5001036000b4200210b420021140b201b20072015200b54200c201454200c2014511b1b21070b200720114f0d010240200520114f0d0020022802002802002802002208280200220f450d022000200541306c6a21052008280204210a200f210d02400340200d41086a2110200d2f0106220e4105742106410021120240024003402006450d0120052010412010e7072213450d02200641606a2106201241016a2112201041206a21102013417f4a0d000b2012417f6a210e0b0240200a0d00420021144200210c0c030b200a417f6a210a200d200e4102746a41c8056a280200210d0c010b0b200d20124105746a220641f0026a290300210c200641e8026a29030021140b200f450d022000200741306c6a210d2008280204210a0340200f41086a2110200f2f0106220e4105742106410021120240024003402006450d01200d2010412010e7072213450d02200641606a2106201241016a2112201041206a21102013417f4a0d000b2012417f6a210e0b200a450d04200a417f6a210a200f200e4102746a41c8056a280200210f0c010b0b2014200f20124105746a220641e8026a29030054200c200641f0026a290300221454200c2014511b450d022009200541286a22062903003703002016200541206a22102903003703002017200541186a22122903003703002018200541106a22132903003703002019200541086a220f29030037030020032005290300370300200d290300210c200d41086a2903002114200d41106a2903002115200d41186a290300210b200d41206a290300211a2006200d41286a2903003703002010201a3703002012200b37030020132015370300200f20143703002005200c370300200721050c010b0b2005201141e89ac5001036000b201141014b0d000b0b200341306a24000f0b201120014190bdc7001036000bfc1e03107f027e107f230041306b22032400410021042001413249210541012106024003400240024020062001490d00410021070c010b20022802002802002802002208280200210941012107034002402009450d002006417f6a210a2000200641306c6a210b2008280204210c2009210d02400340200d41086a210e200d2f0106220f4105742110410021110240024003402010450d01200b200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a210f0b0240200c0d0042002113420021140c030b200c417f6a210c200d200f4102746a41c8056a280200210d0c010b0b200d20114105746a221041f0026a2903002114201041e8026a29030021130b2009450d002000200a41306c6a210b2008280204210c2009210d0340200d41086a210e200d2f0106220f4105742110410021110240024003402010450d01200b200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a210f0b200c450d02200c417f6a210c200d200f4102746a41c8056a280200210d0c010b0b2013200d20114105746a221041e8026a2903005a2014201041f0026a29030022135a20142013511b450d020b41012110200641016a2206200149210720062001470d000c030b0b2006200146211020050d0120062001460d0102400240024002402006417f6a221020014f0d002007410171450d012000201041306c6a220b2903002114200b2000200641306c6a220d290300370300200341286a2207200b41286a2215290300370300200341206a2208200b41206a2216290300370300200341186a220a200b41186a2217290300370300200341106a2218200b41106a2219290300370300200341086a221a200b41086a221b290300370300201b200d41086a221c2903003703002019200d41106a221d2903003703002017200d41186a221e2903003703002016200d41206a221f2903003703002015200d41286a222029030037030020032014370300200d200329030037030020202007290300370300201f2008290300370300201e200a290300370300201d2018290300370300201c201a29030037030020064102490d03200228020028020028020022212802002209450d0320002006417e6a222241306c6a210c202128020421232009210f02400340200f41086a210e200f2f010622244105742110410021110240024003402010450d01200b200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21240b024020230d0042002113420021140c030b2023417f6a2123200f20244102746a41c8056a280200210f0c010b0b200f20114105746a221041f0026a2903002114201041e8026a29030021130b2009450d032021280204210f0340200941086a210e20092f010622234105742110410021110240024003402010450d01200c200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21230b200f450d05200f417f6a210f200920234102746a41c8056a28020021090c010b0b2013200920114105746a221041e8026a2903005a2014201041f0026a29030022135a20142013511b0d03200b2903002114200b200c2903003703002007201529030037030020082016290300370300200a201729030037030020182019290300370300201a201b290300370300201b200c41086a2903003703002019200c41106a2903003703002017200c41186a2903003703002016200c41206a2903003703002015200c41286a29030037030020032014370300024020220d00410021220c030b20022802002802002802002216280200220c450d022006417d6a21152016280204210f200c210b02400340200b41086a210e200b2f010622094105742110410021110240024003402010450d012003200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21090b0240200f0d0042002113420021140c030b200f417f6a210f200b20094102746a41c8056a280200210b0c010b0b200b20114105746a221041f0026a2903002114201041e8026a29030021130b200c450d022000201541306c6a210b2016280204210f0340200c41086a210e200c2f010622094105742110410021110240024003402010450d01200b200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21090b200f450d04200f417f6a210f200c20094102746a41c8056a280200210c0c010b0b202221102013200c20114105746a220e41e8026a2903005a2014200e41f0026a29030022135a20142013511b0d02024003402000201041306c6a221020002015222241306c6a220e290300370300201041286a200e41286a290300370300201041206a200e41206a290300370300201041186a200e41186a290300370300201041106a200e41106a290300370300201041086a200e41086a2903003703002022450d0120022802002802002802002216280200220c450d042022417f6a21152016280204210f200c210b02400340200b41086a210e200b2f010622094105742110410021110240024003402010450d012003200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21090b0240200f0d0042002113420021140c030b200f417f6a210f200b20094102746a41c8056a280200210b0c010b0b200b20114105746a221041f0026a2903002114201041e8026a29030021130b200c450d042000201541306c6a210b2016280204210f0340200c41086a210e200c2f010622094105742110410021110240024003402010450d01200b200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21090b200f450d06200f417f6a210f200c20094102746a41c8056a280200210c0c010b0b202221102013200c20114105746a220e41e8026a290300542014200e41f0026a29030022135420142013511b0d000c040b0b410021220c020b201020014180bdc7001036000b200620014190bdc7001036000b2000202241306c6a22102003290300370300201041286a2007290300370300201041206a2008290300370300201041186a200a290300370300201041106a2018290300370300201041086a201a2903003703000b200441016a21040240200120066b22164102490d0020022802002802002802002217280200220f450d00200d41306a210b20172802042109200f210c02400340200c41086a210e200c2f010622154105742110410021110240024003402010450d01200b200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21150b024020090d0042002113420021140c030b2009417f6a2109200c20154102746a41c8056a280200210c0c010b0b200c20114105746a221041f0026a2903002114201041e8026a29030021130b200f450d002017280204210c0340200f41086a210e200f2f010622094105742110410021110240024003402010450d01200d200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21090b200c450d02200c417f6a210c200f20094102746a41c8056a280200210f0c010b0b2013200f20114105746a221041e8026a2903005a2014201041f0026a29030022135a20142013511b0d00200d2903002114200d200b290300370300200720202903003703002008201f290300370300200a201e2903003703002018201d290300370300201a201c290300370300201c200b41086a290300370300201d200b41106a290300370300201e200b41186a290300370300201f200b41206a2903003703002020200b41286a2903003703002003201437030041012109024020164103490d0020022802002802002802002219280200220f450d00200d41e0006a210b20192802042115200f210c02400340200c41086a210e200c2f010622174105742110410021110240024003402010450d01200b200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21170b024020150d0042002113420021140c030b2015417f6a2115200c20174102746a41c8056a280200210c0c010b0b200c20114105746a221041f0026a2903002114201041e8026a29030021130b200f450d002019280204210b0340200f41086a210e200f2f0106220c4105742110410021110240024003402010450d012003200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a210c0b200b450d02200b417f6a210b200f200c4102746a41c8056a280200210f0c010b0b2013200f20114105746a221041e8026a2903005a2014201041f0026a29030022135a20142013511b0d004102211702400340200d201741306c6a221041506a220e2010290300370300200e41286a201041286a290300370300200e41206a201041206a290300370300200e41186a201041186a290300370300200e41106a201041106a290300370300200e41086a201041086a290300370300201741016a221b2016460d01024020022802002802002802002219280200220c0d00201721090c030b200d201b41306c6a210b20192802042109200c210f02400340200f41086a210e200f2f010622154105742110410021110240024003402010450d01200b200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21150b024020090d0042002113420021140c030b2009417f6a2109200f20154102746a41c8056a280200210f0c010b0b200f20114105746a221041f0026a2903002114201041e8026a29030021130b0240200c0d00201721090c030b2019280204210b0340200c41086a210e200c2f0106220f4105742110410021110240024003402010450d012003200e412010e7072212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a210f0b0240200b0d00201721090c050b200b417f6a210b200c200f4102746a41c8056a280200210c0c010b0b20172109201b21172013200c20114105746a221041e8026a290300542014201041f0026a29030022135420142013511b0d000c020b0b201721090b200d200941306c6a22102003290300370300201041286a2007290300370300201041206a2008290300370300201041186a200a290300370300201041106a2018290300370300201041086a201a2903003703000b20044105470d000b410021100b200341306a240020100bde2003147f037e067f230041c0026b220524000240024020014115490d004101210641012107024002400240034020012108200021092006200771410173210a024002400240024002400240034002400240024002402004450d00024020064101710d002000200110fb042004417f6a21040b2001410276220b41036c210c200b410174210d4100210e024020014132490d00200b200b417f6a220e2000200b4105746a2000200e4105746a412010e707220f41004822101b2211200b41016a2212200e200b20101b220b200020124105746a2000200b4105746a412010e70741004822121b220b2000200b4105746a200020114105746a412010e70722114100481b210b200d200d417f6a220e2000200d4105746a2000200e4105746a412010e707221341004822141b2215200d4101722216200e200d20141b220d200020164105746a2000200d4105746a412010e70722144100481b220d2000200d4105746a200020154105746a412010e70722154100481b210d200c200c417f6a220e2000200c4105746a2000200e4105746a412010e707221641004822171b2218200c41016a2207200e200c20171b220c200020074105746a2000200c4105746a412010e707220e4100481b220c2000200c4105746a200020184105746a412010e70722174100481b210c4102410120101b200f411f7620121b2011411f766a2013411f766a2014411f766a2015411f766a2016411f766a200e411f766a2017411f766a210e0b2000200d4105746a2000200b4105746a412010e7072210411f76200e6a2000200c4105746a2000200b200d201041004822101b220f4105746a412010e7072211411f766a210e2000200c200f20114100481b220c4105746a2000200d200b20101b22174105746a412010e707417f4c0d01200c21170c020b2000200110fc040c0f0b200e41016a220e410c490d0002402001410176220c450d00200020014105746a41606a210b2000210d0340200541206a41186a220e200d41186a2210290000370300200541206a41106a220f200d41106a2211290000370300200541206a41086a2212200d41086a22132900003703002005200d290000370320200b41086a22142900002119200b41106a2215290000211a200b41186a2216290000211b200d200b2900003700002010201b3700002011201a370000201320193700002016200e2903003700002015200f29030037000020142012290300370000200b2005290320370000200b41606a210b200d41206a210d200c417f6a220c0d000b0b20012017417f736a21174101210b0c010b200e45210b0b0240200b45200a724101710d002000200110fd040d0d0b2003450d02201720014f0d0102402003200020174105746a220b412010e70741004e0d0020002109200121080c040b200541206a41186a2213200041186a220f290000370300200541206a41106a2214200041106a2211290000370300200541206a41086a2215200041086a221229000037030020052000290000370320200b41086a220d2900002119200b41106a220c290000211a200b41186a220e290000211b2000200b290000370000200f201b3700002011201a37000020122019370000200e2013290300370000200c2014290300370000200d2015290300370000200b2005290320370000200541c0016a41186a2218200f290000370300200541c0016a41106a22072011290000370300200541c0016a41086a221c2012290000370300200520002900003703c001200041606a2116200041206a21174100210d2001210c03400240200d200c417f6a220e4f0d002017200d4105746a210b0340200541c0016a200b412010e707417f4c0d01200b41206a210b200e200d41016a220d470d000b200e210d0b2016200c4105746a210b02400340200d200c417f6a220c4f0d01200541c0016a200b412010e707210e200b41606a2210210b200e4100480d000b20132017200d4105746a220b41186a220e2900003703002014200b41106a221d2900003703002015200b41086a221e2900003703002005200b290000370320201041286a221f2900002119201041306a2220290000211a201041386a2221290000211b200b201041206a2210290000370000200e201b370000201d201a370000201e20193700002021201329030037000020202014290300370000201f201529030037000020102005290320370000200d41016a210d0c010b0b200020052903c001370000200f2018290300370000201120072903003700002012201c29030037000002402001200d41016a220b490d002000200b4105746a21002001200b6b220141154f0d010c0c0b0b200b200141c499c500104c000b2017200141fc99c5001036000b2008450d010b201720084f0d01200541206a41186a2214200941186a221c290000370300200541206a41106a2215200941106a221d290000370300200541206a41086a2216200941086a221e29000037030020052009290000370320200920174105746a220b41086a220d2900002119200b41106a220c290000211a200b41186a220e290000211b2009200b290000370000201c201b370000201d201a370000201e2019370000200e2014290300370000200c2015290300370000200d2016290300370000200b2005290320370000200541186a221f201c290000370300200541106a2220201d290000370300200541086a2221201e29000037030020052009290000370300200941206a210f410021182008417f6a220e450d02200f210b0340200b2005412010e70741004e0d03200b41206a210b200e201841016a2218470d000b200e21180c020b410041004180bdc7001036000b201720084190bdc7001036000b200920084105746a210d200e210c02400340200d2101200c220b20184d22070d01200b417f6a210c200141606a220d2005412010e707417f4a0d000b0b0240200b2018490d00200e200b490d024180012112410021004100210d410021104100210b4180012113200f20184105746a2206210f034002402001200f6b220c419fc0004b22170d00200c410576220c41807f6a200c200d200049200b201049220e7222111b210c02402011450d002013200c200e1b2113200c2012200e1b21120c010b200c200c41017622136b21120b0240200b2010470d00024020130d00200541c0006a2210210b0c010b4100210c200541c0006a220b2110200f210e03402010200c3a00002010200e2005412010e707417f73411f766a2110200e41206a210e2013200c41016a220c470d000b0b0240200d2000470d00024020120d00200541c0016a2200210d0c010b200141606a210c4100210e200541c0016a220d210003402000200e3a00002000200c2005412010e707411f766a2100200c41606a210c2012200e41016a220e470d000b0b02402000200d6b220c2010200b6b220e200e200c4b1b2211450d002014200f200b2d00004105746a220c41186a2900003703002015200c41106a2900003703002016200c41086a2900003703002005200c290000370320200f200b2d00004105746a220c2001200d2d0000417f734105746a220e290000370000200c41186a200e41186a290000370000200c41106a200e41106a290000370000200c41086a200e41086a290000370000024020114101460d002011417f6a211103402001200d2d0000417f734105746a220c200f200b2d00014105746a220e290000370000200c41186a200e41186a290000370000200c41106a200e41106a290000370000200c41086a200e41086a290000370000200f200b2d00014105746a220c2001200d2d0001417f734105746a220e290000370000200c41186a200e41186a290000370000200c41106a200e41106a290000370000200c41086a200e41086a290000370000200d41016a210d200b41016a210b2011417f6a22110d000b0b2001200d2d0000417f734105746a220c2005290320370000200c41186a2014290300370000200c41106a2015290300370000200c41086a2016290300370000200d41016a210d200b41016a210b0b200120124105746b2001200d2000461b2101200f20134105746a200f200b2010461b210f20170d000b02400240200b20104f0d002001210c03402014200f2010417f6a22102d00004105746a220d41186a220e2900003703002015200d41106a22002900003703002016200d41086a22012900003703002005200d290000370320200c41606a220c41086a22112900002119200c41106a2212290000211a200c41186a2213290000211b200d200c290000370000200e201b3700002000201a37000020012019370000201320142903003700002012201529030037000020112016290300370000200c2005290320370000200b2010490d000c020b0b200f210c200d20004f0d0003402000417f6a22002d0000210b2014200c41186a220e2900003703002015200c41106a22102900003703002016200c41086a220f2900003703002005200c2900003703202001200b417f734105746a220b41086a22112900002119200b41106a2212290000211a200b41186a2213290000211b200c200b290000370000200e201b3700002010201a370000200f2019370000201320142903003700002012201529030037000020112016290300370000200b2005290320370000200c41206a210c200d2000490d000b0b20092005290300370000201c201f290300370000201d2020290300370000201e20212903003700002008200c20066b41057620186a22014d0d032014201c2900003703002015201d2900003703002016201e29000037030020052009290000370320200920014105746a220b41086a220d2900002119200b41106a220c290000211a200b41186a220e290000211b2009200b290000370000201c201b370000201d201a370000201e2019370000200e2014290300370000200c2015290300370000200d2016290300370000200b2005290320370000200820016b220d450d04200d20012001200d4b1b210c2008410376210e200b41206a2100024002402001200d417f6a220d490d002000200d2002200b200410fa04200921000c010b2009200120022003200410fa04200b2103200d21010b200c200e4f2106200141154f0d010c050b0b2018200b41d499c500104c000b200b200e41d499c500104b000b200120084190bdc7001036000b4189a7c700411c41b8a1cc001033000b20014102490d00200041606a210e4101210c03400240200c220b41016a220c4102490d002000200b4105746a22102000200b417f6a220d4105746a220b412010e707417f4a0d00200541c0016a41186a220f201041186a2211290000370300200541c0016a41106a2212201041106a2213290000370300200541c0016a41086a2214201041086a2215290000370300200520102900003703c0012010200b2900003700002015200b41086a2900003700002013200b41106a2900003700002011200b41186a290000370000410021100240200d450d00200e210b03400240200541c0016a200b412010e7074100480d00200d21100c020b200b41206a200b290000370000200b41386a200b41186a290000370000200b41306a200b41106a290000370000200b41286a200b41086a290000370000200b41606a210b200d417f6a220d0d000b0b200020104105746a220b20052903c001370000200b41186a200f290300370000200b41106a2012290300370000200b41086a20142903003700000b200e41206a210e200c2001470d000b0b200541c0026a24000beb050a067f017e017f017e017f017e017f017e017f017e230041206b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200020044105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c37000020052008370000024020032001490d00200321040c030b2006410d7420067322054111762005732205410574200573220620077122054100200120052001491b6b220520014f0d01200020034105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c370000200520083700002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200020044105746a22012900002108200020054105746a220041086a2205290000210a200041106a2204290000210c200041186a2203290000210e20012000290000370000200141186a220629000021102006200e370000200141106a2206290000210e2006200c370000200141086a2201290000210c2001200a370000200320103700002004200e3700002005200c370000200020083700000b200241206a24000f0b200520014190bdc7001036000b200420014180bdc7001036000be90609067f017e017f017e017f027e017f017e027f230041206b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d0220052006200020064105746a200020054105746a412010e7074100481b21060b200620014f0d03200420014f0d02200020044105746a2204200020064105746a2205412010e70741004e0d03200541086a22072900002108200541106a2209290000210a200541186a220b290000210c2004290000210d20042005290000370000200441186a220e290000210f200e200c370000200441106a220e290000210c200e200a370000200441086a2204290000210a20042008370000200b200f3700002009200c3700002007200a3700002005200d370000200621040c000b0b2006200141d89ac5001036000b2004200141e89ac5001036000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241186a2209200041186a2204290000370300200241106a220b200041106a2205290000370300200241086a220e200041086a2203290000370300200020074105746a220641086a2900002108200641106a290000210a200641186a290000210c2000290000210d200020062900003700002004200c3700002005200a370000200320083700002002200d37030041002105024002400240034020062002290300370000200641186a2009290300370000200641106a200b290300370000200641086a200e2903003700002005410174220641017221040240200641026a220620074f0d00200420074f0d0220062004200020044105746a200020064105746a412010e7074100481b21040b200420074f0d03200520074f0d02200020054105746a2205200020044105746a2206412010e70741004e0d032009200541186a2203290000370300200b200541106a2210290000370300200e200541086a2211290000370300200641086a2900002108200641106a290000210a200641186a290000210c2005290000210d200520062900003700002003200c3700002010200a370000201120083700002002200d370300200421050c000b0b2004200741d89ac5001036000b2005200741e89ac5001036000b200741014b0d000b0b200241206a24000f0b200720014190bdc7001036000bd408030b7f017e0a7f230041c0006b22022400200041c0006a2103200041a07f6a21042001417f6a2105200141324921064101210741002108024003400240024020072001490d00410021090c010b41012109200020074105746a220a200a41606a412010e7074100480d0003404101210b20052007460d03200741016a2107200a41206a220b200a412010e7072109200b210a2009417f4a0d000b200720014921090b2007200146210b20060d0120072001460d010240024002402007417f6a220a20014f0d0002402009450d0020002007410574220c6a220b290000210d200b2000200a4105746a220a290000370000200a200d370000200b41086a220e290000210d200e200a41086a220f290000370000200f200d370000200b41106a2210290000210d2010200a41106a22112900003700002011200d370000200b41186a2212290000210d2012200a41186a22132900003700002013200d37000020074102490d03200a20002007417e6a22094105746a2214412010e707417f4a0d03200a290000210d200a2014290000370000200241206a41186a22152013290000370300200241206a41106a22162011290000370300200241206a41086a2217200f290000370300200f201441086a2900003700002011201441106a2900003700002013201441186a2900003700002002200d3703204100210f2009450d022004200c6a210a03400240200241206a200a412010e7074100480d002009210f0c040b200a41206a200a290000370000200a41386a200a41186a290000370000200a41306a200a41106a290000370000200a41286a200a41086a290000370000200a41606a210a2009417f6a22090d000c030b0b200720014190bdc7001036000b200a20014180bdc7001036000b2000200f4105746a220a2002290320370000200a41186a2015290300370000200a41106a2016290300370000200a41086a20172903003700000b200841016a21080240200120076b220f4102490d00200b41206a220a200b412010e707417f4a0d00200b290000210d200b200a290000370000200241206a41186a22112012290000370300200241206a41106a22132010290000370300200241206a41086a2214200e290000370300200e200a41086a2900003700002010200a41106a2900003700002012200a41186a2900003700002002200d3703204101210a0240200f4103490d00200b41c0006a200241206a412010e707417f4a0d002003200c6a210a4103210e02400340200a41606a2209200a290000370000200941186a200a41186a290000370000200941106a200a41106a290000370000200941086a200a41086a290000370000200f200e2209460d01200941016a210e200a41206a220a200241206a412010e7074100480d000b0b2009417f6a210a0b200b200a4105746a220a2002290320370000200a41186a2011290300370000200a41106a2013290300370000200a41086a20142903003700000b20084105470d000b4100210b0b200241c0006a2400200b0b8709010f7f23004190036b2204240002400240200141046a28020022052f01062206410b490d002001280208210720012802002108200441306a410041e00210e6071a200441286a22064100360200200441206a22094200370300200441186a220a4200370300200441106a220b4200370300200441086a220c42003703002004420037030002404194031027220d450d00200d41003b0106200d4100360200200d41086a200441306a41e00210e407210e200d4190036a2006280200360200200d4188036a2009290300370200200d4180036a200a290300370200200d41f8026a200b290300370200200d41f0026a200c290300370200200d20042903003702e802200441306a41086a2209200541d0016a290000370300200441306a41106a220f200541d8016a290000370300200441306a41186a2210200541e0016a290000370300200420052900c8013703302005280280032111200e200541e8016a20052f010641796a220641057410e407210e200d41e8026a20054184036a200641027410e4072112200541063b0106200d20063b0106200a2010290300370300200b200f290300370300200c20092903003703002004200429033037030002400240200128020c22014107490d00200d41066a210a200e2001417a6a220c4105746a200e200141796a22014105746a220b200641ffff037120016b41057410e5071a200b41186a200241186a290000370000200b41106a200241106a290000370000200b41086a200241086a290000370000200b20022900003700002012200c4102746a2106201220014102746a21020c010b200541086a220a200141016a220b4105746a200a20014105746a2206200541066a220a2f010020016b41057410e5071a200641186a200241186a290000370000200641106a200241106a290000370000200641086a200241086a29000037000020062002290000370000200541e8026a220620014102746a21022006200b4102746a2106200121010b20062002200a2f010020016b41027410e5071a20022003360200200041013a00002000200236023c200041386a4100360200200041346a200d360200200041306a20113602002000412c6a2007360000200041286a2005360000200041246a200836000020002004290300370001200041096a200441086a290300370000200041116a200441106a290300370000200041196a200441186a290300370000200a200a2f010041016a3b01000c020b1030000b200541086a220a200128020c220d41016a220b4105746a200a200d4105746a220a2006200d6b41057410e5071a200a41186a200241186a290000370000200a41106a200241106a290000370000200a41086a200241086a290000370000200a2002290000370000200541e8026a2202200b4102746a2002200d4102746a220220052f0106200d6b41027410e5071a20022003360200200520052f010641016a3b0106200441306a410b6a200141086a280000360000200041003a00002000200236023c200041106a200d3600002004200129000037003320002004290030370001200041086a200441376a2900003700000b20044190036a24000be60b020f7f047e23004180046b220624000240024020012802002207417f6a2005470d000240024002400240200141046a28020022082f01062209410b490d002001280208210a200641c0006a410272410041be0310e6071a41c4031027220b450d05200b4100360200200b41046a200641c0006a41c00310e4071a200641c0006a41186a220c200841e0016a290000370300200641c0006a41106a220d200841d8016a290000370300200641c0006a41086a220e200841d0016a290000370300200620082900c801370340200828028003210f200b41086a200841e8016a20082f0106221041796a220541057410e4072111200b41e8026a20084184036a200541027410e4072112200b4194036a200841b0036a2010417a6a221341027410e4072114200841063b0106200b20053b010602402013450d00410021052014211003402010280200220920053b01042009200b360200201041046a21102013200541016a2205470d000b0b200641206a41186a200c2903002215370300200641206a41106a200d2903002216370300200641206a41086a200e2903002217370300200620062903402218370320200641186a2015370300200641106a2016370300200641086a201737030020062018370300200128020c22054107490d0120112005417a6a22014105746a2011200541796a22104105746a2209200b2f010620106b41057410e5071a200941186a200241186a290000370000200941106a200241106a290000370000200941086a200241086a290000370000200920022900003700002012200141027422096a201220104102746a2213200b2f010620106b41027410e5071a20132003360200200b200b2f010641016a22133b01062005410274220220146a416c6a201420096a2205201341ffff037120016b41027410e5071a200520043602002001200b2f010622134b0d022002200b6a41fc026a2105034020052802002209201041016a22103b01042009200b360200200541046a210520102013490d000c030b0b200841086a2205200128020c221341016a22104105746a200520134105746a2205200920136b41057410e5071a200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a29000037000020052002290000370000200841e8026a22092010410274220b6a2009201341027422056a220920082f010620136b41027410e5071a20092003360200200820082f010641016a22093b0106200520084194036a22026a41086a2002200b6a220b200941ffff037120106b41027410e5071a200b20043602000240201020082f0106220b4b0d00200820056a4198036a210520132110034020052802002209201041016a22103b010420092008360200200541046a21052010200b490d000b0b200041003a0000200041046a2001290200370200200041106a20133602002000410c6a200141086a2802003602000c020b200841086a2210200541016a22094105746a201020054105746a221020082f010620056b41057410e5071a201041186a200241186a290000370000201041106a200241106a290000370000201041086a200241086a29000037000020102002290000370000200841e8026a2213200941027422016a2013200541027422106a221320082f010620056b41027410e5071a20132003360200200820082f010641016a22133b0106201020084194036a22026a41086a200220016a2201201341ffff037120096b41027410e5071a20012004360200200520082f010622134f0d00200820106a4198036a2110034020102802002209200541016a22053b010420092008360200201041046a211020132005470d000b0b20002006290300370001200041013a00002000412c6a200a360200200041286a2008360200200041246a2007360200200041386a2007360200200041346a200b360200200041306a200f360200200041096a200641086a290300370000200041116a200641106a290300370000200041196a200641186a2903003700000b20064180046a24000f0b41cc9ec800413541b8a1cc001033000b1030000b8b0503027f017e057f230041d0006b2202240041d5bec500ad4280808080f00084100122032900002104200241086a200341086a290000370300200220043703002003102941d08bc500ad4280808080800184100122032900002104200241106a41086a200341086a29000037030020022004370310200310292002200136022c2002412c6aad4280808080c00084100522032900002104200241306a41086a200341086a2900003703002002200437033020031029200241cc006a200241306a3602002002200241c0006a36024420022002412c6a3602482002200241306a360240200241206a200241c0006a107502400240024002402002280228220541206a2206417f4c0d00200228022021070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a20002006360208200020083602042000200336020002402002280224450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000b130020004105360204200041f0e6ca003602000b130020004103360204200041f09fc8003602000b130020004102360204200041b4f8c4003602000b130020004105360204200041ace3c2003602000b130020004109360204200041fcb8c0003602000b130020004101360204200041d4aac0003602000b130020004101360204200041b4adc0003602000b13002000410336020420004190a8c0003602000b130020004103360204200041e0b7c7003602000b3400200041c99fc50036020420004100360200200041146a410f360200200041106a41e882c700360200200041086a42093702000b13002000411f36020420004180f2c5003602000b130020004111360204200041c4e1c5003602000b130020004108360204200041d0d5c5003602000b130020004127360204200041e4bfc5003602000b1300200041073602042000418cd7c8003602000b13002000410536020420004180eeca003602000b130020004106360204200041d0e8c9003602000b13002000410b360204200041a8dec9003602000b1300200041073602042000418ca0c4003602000b130020004102360204200041a488cc003602000b130020004101360204200041c4ebc3003602000b130020004102360204200041e8b3c7003602000b130020004107360204200041ecd6c2003602000b1300200041033602042000418cb1c7003602000b2d01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241e4003600000b3601017f02404110102722020d001039000b2002420037000820024280c2d72f370000200042908080808002370204200020023602000b2e01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241c093063600000b2d01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241880e3600000b3801017f02404110102722020d001039000b2002420037000820024280a094a58d1d370000200042908080808002370204200020023602000b2e01017f02404104102722020d001039000b20004284808080c0003702042000200236020020024180ce183600000b2e01017f02404104102722020d001039000b20004284808080c000370204200020023602002002418084073600000b7c01017f230041f0006b22022400200241106a4200370300200241186a4200370300200241206a4200370300200241286a4200370300200241306a4200370300200241386a4200370300200241c0006a410036020020024108360204200241086a4200370300200241003a00002000200210a105200241f0006a24000b8d1802097f027e230041206b220224002002410036020820024201370300024002400240024020012d00004101460d00410110272203450d032002410136020420022003360200200341003a000020024101360208200141046a28020021042001410c6a2802002203200210710240024020030d0020022802042105200228020821060c010b2004200341306c6a2107200228020421052002280208210603402004280200210802400240200520066b4104490d00200641046a2103200228020021090c010b200641046a22032006490d05200541017422092003200920034b1b220a4100480d050240024020050d000240200a0d00410121090c020b200a102722090d010c080b200228020021092005200a460d0020092005200a102b2209450d070b2002200a360204200220093602000b200920066a20083600002002200336020802400240200441086a2d00004101460d00200241003a00100240024020022802042003460d00200228020021050c010b200341016a22052003490d07200341017422062005200620054b1b22064100480d070240024020030d0041002103024020060d00410121050c020b200610272205450d0a0c010b2002280200210520032006460d00200520032006102b2205450d090b20022006360204200220053602000b200520036a41003a00002002200341016a22033602082002200441096a2d00004100474107742004410a6a2d00007222063a00100240024020022802042003460d00200228020021050c010b200341016a22052003490d07200341017422092005200920054b1b22094100480d070240024020030d0041002103024020090d00410121050c020b200910272205450d0a0c010b2002280200210520032009460d00200520032009102b2205450d090b20022009360204200220053602000b200520036a20063a00002002200341016a2203360208200441106a290300210b2002200441186a2903003703182002200b370310200241106a2109200228020421060c010b200241013a00100240024020022802042003460d00200228020021050c010b200341016a22052003490d06200341017422062005200620054b1b22064100480d060240024020030d0041002103024020060d00410121050c020b200610272205450d090c010b2002280200210520032006460d00200520032006102b2205450d080b20022006360204200220053602000b200520036a41013a00002002200341016a2205360208200441186a290300210b200441106a290300210c024002402002280204220920056b4110490d00200341116a210320022802002108200921060c010b200541106a22032005490d06200941017422062003200620034b1b22064100480d060240024020090d00024020060d00410121080c020b200610272208450d090c010b2002280200210820092006460d00200820092006102b2208450d080b20022006360204200220083602000b200820056a2205200b3700082005200c37000020022003360208200441206a290300210b2002200441286a2903003703182002200b370310200241106a21090b02400240200620036b4110490d0020022802002108200621050c010b200341106a22052003490d05200641017422082005200820054b1b22054100480d050240024020060d00024020050d00410121080c020b200510272208450d080c010b2002280200210820062005460d00200820062005102b2208450d070b20022005360204200220083602000b200820036a22062009290000370000200641086a200941086a2900003700002002200341106a22063602082007200441306a2204470d000b0b200141186a290300210b2001290310210c02400240200520066b4110490d0020022802002103200521040c010b200641106a22032006490d03200541017422042003200420034b1b22044100480d030240024020050d00024020040d00410121030c020b200410272203450d060c010b2002280200210320052004460d00200320052004102b2203450d050b20022004360204200220033602000b200320066a2205200b3700082005200c3700002002200641106a2209360208200141286a290300210b200141206a290300210c02400240200420096b410f4d0d00200421050c010b200941106a22052009490d03200441017422082005200820054b1b22054100480d030240024020040d00024020050d00410121030c020b200510272203450d060c010b20042005460d00200320042005102b2203450d050b20022005360204200220033602000b200320096a2204200b3700082004200c3700002002200641206a2204360208200141c0006a28020021090240200520046b41034b0d00200441046a22082004490d032005410174220a2008200a20084b1b22084100480d030240024020050d00024020080d00410121030c020b200810272203450d060c010b20052008460d00200320052008102b2203450d050b20022008360204200220033602000b200320046a20093600002002200641246a22033602082001290330210b2002200141386a2903003703182002200b370310200241106a21040c010b410110272203450d022002410136020420022003360200200341013a000020024101360208200141306a290300210b200141286a290300210c0240024020022802042205417f6a4110490d0020022802002103200521040c010b200541017422034111200341114b1b22044100480d0220022802002103024020052004460d00200320052004102b2203450d040b20022004360204200220033602000b2003200c370001200341096a200b37000020024111360208024002402004416f6a411f4d0d00200421050c010b200441017422054131200541314b1b22054100480d02024020042005460d00200320042005102b2203450d040b20022005360204200220033602000b20032001290001370011200341296a200141196a290000370000200341216a200141116a290000370000200341196a200141096a2900003700004131210420024131360208024020012d0021220641064b0d000240024002400240024002400240024020060e0700010203040506000b410021040c060b410121040c050b410221040c040b410321040c030b410421040c020b410521040c010b410621040b200220043a0010024020054131470d002003413141e200102b2203450d04200241e200360204200220033602000b200320043a00314132210420024132360208200228020421050b200141c0006a290300210b2001290338210c02400240200520046b4110490d0020022802002103200521060c010b20054101742203200441106a2206200320064b1b22064100480d020240024020050d00200610272203450d050c010b2002280200210320052006460d00200320052006102b2203450d040b20022006360204200220033602000b200320046a2205200b3700082005200c3700002002200441106a2209360208200141d0006a290300210b200141c8006a290300210c02400240200620096b410f4d0d00200621050c010b20064101742205200441206a2208200520084b1b22054100480d020240024020060d00200510272203450d050c010b20062005460d00200320062005102b2203450d040b20022005360204200220033602000b200320096a2206200b3700082006200c3700002002200441206a2206360208200141e8006a28020021090240200520066b41034b0d0020054101742208200441246a220a2008200a4b1b22084100480d020240024020050d00200810272203450d050c010b20052008460d00200320052008102b2203450d040b20022008360204200220033602000b200320066a20093600002002200441246a22033602082001290358210b2002200141e0006a2903003703182002200b370310200241106a21040b024002402002280204220620036b4110490d00200228020021050c010b200341106a22052003490d01200641017422092005200920054b1b22094100480d010240024020060d00024020090d00410121050c020b200910272205450d040c010b2002280200210520062009460d00200520062009102b2205450d030b20022009360204200220053602000b200520036a22052004290000370000200541086a200441086a2900003700002002200341106a2203360208200041086a200336020020002002290300370200200241206a24000f0b1032000b1030000b4d01027f230041106b2202240002404104102722030d001039000b2002420437020420022003360200410020021071200041086a200228020836020020002002290300370200200241106a24000bfe0301057f230041f0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b0202400240200228021022030d00200041033a00200c010b200241186a28020021042002280214210541002101200241003a0068024002400240034020042001460d01200241c8006a20016a200320016a2d00003a00002002200141016a22063a00682006210120064120470d000b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a2903003703002002200229034837032820042006460d01200320066a2d0000220141034f0d0120002002290328370000200041186a200241286a41186a290300370000200041106a200241286a41106a290300370000200041086a200241286a41086a2903003700000c020b200141ff0171450d00200241003a00680b20024100360230200242013703282002410d3602242002200241086a3602202002200241286a36026c200241dc006a41013602002002420137024c200241f4eaca003602482002200241206a360258200241ec006a41a8a3c800200241c8006a10371a200235023042208620023502288410080240200228022c450d00200228022810290b410321010b200020013a00202005450d00200310290b200241f0006a24000b8c0707047f017e017f017e017f017e047f230041e0016b22042400200441d8006a41186a22054200370300200441d8006a41106a22064200370300200441d8006a41086a220742003703002004420037035841c99fc500ad4280808080900184220810012209290000210a200441c8006a41086a220b200941086a2900003703002004200a370348200910292007200b2903003703002004200429034837035841948fc700ad4280808080f00184220a10012209290000210c200b200941086a2900003703002004200c3703482009102920062004290348220c370300200441106a41086a22092007290300370300200441106a41106a220d200c370300200441106a41186a220e200b29030037030020042004290358370310200441086a200441106a412010fc01200428020c210f20042802082110200542003703002006420037030020074200370300200442003703582008100122052900002108200b200541086a29000037030020042008370348200510292007200b29030037030020042004290348370358200a100122052900002108200b200541086a290000370300200420083703482005102920062004290348220837030020092007290300370300200d2008370300200e200b290300370300200420042903583703102004200f410020101b220b41016a360258200441106aad4280808080800484200441d8006aad4280808080c0008410032004413f6a4200370000200441376a42003700002004412f6a4200370000200441276a42003700002004411f6a420037000020044200370017200441d8006a41096a22062009290000370000200441e9006a200d290000370000200441f1006a200e290000370000200441f9006a200441106a41206a29000037000020044181016a200441386a29000037000020044188016a420037000020044194016a200336020020044190016a200036020020044198016a2001290000370300200441a0016a200141086a290000370300200441a8016a200141106a290000370300200441b0016a200141186a290000370300200441003a005820042004290010370059200441b8016a20023a0000200441c8006a200b10dd0420042802482101200420042802503602dc01200420013602d801200441d8006a200441d8016a10de040240200428024c450d00200110290b200441e4006a200b360200200741033a0000200441093a0058200620023a0000200441d8006a10cb01200441e0016a24000bd10102027f047e230041c0006b22022400200241306a200110a705200241106a20022802302201200228023810a8050240024020022802102203450d0020022902142104200241286a2903002105200241206a290300210602402002280234450d00200110290b2002200620052004422088420010d507200241086a29030021054201210620022903002107200442ffffff3f83500d01200310290c010b02402002280234450d00200110290b420021060b2000200737030820002006370300200041106a2005370300200241c0006a24000b900201037f230041206b2203240002400240200241c4006c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410272205450d020b20034100360208200320053602002003200436020420022003107102402002450d002001200241c4006c6a21050340200320012802003602102003200341106a41041072412010272202450d032003422037021420032002360210200341106a200141046a220141201072200328021421022003200328021022042003280218107202402002450d00200410290b2003200141206a41201072200141c0006a22012005470d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1038000b1039000bfc0403027f017e057f230041d0006b2202240041c99fc500ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941d29fc500ad4280808080900184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000ba70302057f017e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d00200041003602000c010b200328021421022003200341186a28020036022420032001360220200341c8006a200341206a1096020240024020032802482204450d00200328024c21050240200328022422064110490d002003200641706a36022420032003280220220641106a360220200341c8006a41086a280200210720062900002108200041186a200641086a290000370300200041106a2008370300200041086a200736020020002005360204200020043602000c020b200541ffffff3f71450d00200410290b20034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b200041003602000b2002450d00200110290b200341e0006a24000be70b06037f027e027f0a7e037f067e23004180036b22042400200328020021052004200110a80220044180016a200428020022032004280208220610a9022004290380012107420021082004420037038001200441c8016a280200210920042d00cc01210a0240024020074201510d00200441106a41306a4200370300200441106a41286a4200370300200441106a41206a4200370300200441106a41186a4200370300200441206a4200370300200441186a4200370300200442003703104200210b4200210c4200210d4200210e0c010b200441b8016a290300210f20044180016a41306a290300211020044180016a41206a290300210b20044180016a41186a2903002108200441c0016a290300210e200429039001210d200429038801210c200441106a41206a20044180016a41286a290300370300200441106a41286a2010370300200441106a41306a200f370300200441206a20083703002004200b3703282004200c3703102004200d3703180b200441106a41186a200b200241086a2903002210200b20082002290300221156200b201056200b2010511b22021b22127d20082011200820021b220f54ad7d221337030020042008200f7d2214370320200441c8006a41186a2013370300200441c8006a41206a2215200441106a41206a290300370300200441c8006a41286a2216200441106a41286a290300370300200441c8006a41306a2217200441106a41306a290300370300200420143703582004200c3703482004200d37035002400240427f200c20147c22142014200c542202200d20137c2002ad7c2213200d542013200d511b22021b22144280c8afa025544100427f201320021b2218501b0d00200441d8006a29030021192017290300211a20162903002114201529030021182004290350211b2004290348211c420121132004290360211d0c010b4200211302402014201884500d002014201810d402200441b8026a2018370300200441b0026a201437030020044180026a41086a41013a000020044189026a200529000037000020044191026a200541086a29000037000020044199026a200541106a290000370000200441a1026a200541186a290000370000200441033a00800220044180026a10cb010b0b200441a8016a2018370300200441b0016a201437030020044190016a201b370300200441b8016a201a37030020044198016a20193703002004201d3703a0012004200e3703c0012004201c370388012004200a4100200742015122021b22053a00cc0120042009410020021b22093602c801200420134201512202ad3703800102400240024020020d002006ad4220862003ad8410040c010b410410272202450d0120022009360000200241044108102b2202450d01200220053a0004200241084115102b2202450d012002201c3700052002410d6a201b370000200441a0016a290300211b20044198016a290300211c20024115412a102b2202450d012002201c3700152002411d6a201b3700002002412a41d400102b2202450d01200220183700252002412d6a20143700002002413d6a200441c0016a2903003700002002200441b8016a2903003700352006ad4220862003ad842002ad4280808080d008841003200210290b201020127d21102011200f54ad2114427f200c20087c22082008200c542202200d200b7c2002ad7c2208200d542008200d511b22021b427f200820021b8450210202402004280204450d00200310290b201020147d21082002ad210b2011200f7d21102013420152210202400240024020074201510d0020020d004103210320044180026a21020c010b20074201522002410173720d014104210320044180016a21020b200241086a20033a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a290000370000200210cb010b2000200f3703182000200c3703082000200b370300200041306a2008370300200041286a2010370300200041206a2012370300200041106a200d37030020044180036a24000f0b1030000bb50404057f017e017f017e0240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602000240200441037122064103460d00024002400240024020060e03000102000b2004410276ad21070c020b41012106024020050d000c050b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d04200141fcff0371410276ad21070c010b410121060240200541034f0d000c040b200341036a2d0000210520032f0001210820012002417c6a3602042001200341046a3602002008200541107472410874200472220141808004490d032001410276ad21070b410021060c020b02402004410276220841044b0d000240024020080e050002020201000b20054104490d022003350001210720012002417b6a3602042001200341056a36020020074280808080045421060c030b20054108490d01200329000121072001200241776a3602042001200341096a3602002007428080808080808080015421060c020b200841046a220541084b0d002002417e6a2102200341026a2103410021044200210741012106034002402002417f470d000c030b2003417f6a310000210920012002360204200120033602002002417f6a2102200341016a210320092004410374413871ad862007842107200441016a220441ff01712005490d000b2007427f412820084103746b413871ad885821060c010b410121060b2000200737030820002006ad3703000b840402067f047e230041206b21020240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a2207360200200541014b0d0320050e020102010b200041023a00000f0b02402006450d0020042d0001210520012003417e6a22063602042001200441026a360200200541ff0071220741064b0d0020064110490d00200041003a0000200041086a2004290002370300200041026a20073a0000200020054107763a0001200041036a2002280009360000200041186a2002290310370300200041106a2004410a6a29000037030020012003416e6a3602042001200441126a360200200041076a2002410d6a2d00003a0000200041206a200241106a41086a2903003703000f0b200041023a00000f0b200241106a41086a220542003703002002420037031020064110490d01200741086a29000021082007290000210920012003416f6a22063602042001200441116a2207360200200542003703002002420037031020064110490d01200741086a290000210a2007290000210b20012003415f6a3602042001200441216a360200200041206a200a370300200041186a200b370300200041106a2008370300200041086a2009370300200041013a000020002002280009360001200041046a2002410c6a2800003600000f0b200041023a00000f0b200041023a00000bd813020b7f057e230041f0056b22022400024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541044b0d0620050e050102030405010b200041063a00000c0b0b200241c8036a20011096020240024020022802c8032206450d0020022802cc032107024020012802042204450d00200241d0036a2802002108200128020022092d0000210520012004417f6a22033602042001200941016a220a360200200541014b0d004100210b02400240024020050e020100010b41002105200241003a00e8032004417f6a210b417e21030340200b2005460d02200241c8036a20056a200920056a220a41016a2d00003a00002001200420036a3602042001200a41026a3602002002200541016a220a3a00e8032003417f6a2103200a2105200a4120470d000b200241a0016a41186a200241c8036a41186a290300370300200241a0016a41106a200241c8036a41106a290300370300200241a0016a41086a200241c8036a41086a290300370300200220022903c8033703a001200a417f7320046a21034101210b2009200a6a41016a210a0b200241c0006a41186a2205200241a0016a41186a290300370300200241c0006a41106a2204200241a0016a41106a290300370300200241c0006a41086a2209200241a0016a41086a290300370300200220022903a00137034020034104490d03200a280000210c20012003417c6a3602042001200a41046a36020020024180016a41086a2009290300220d37030020024180016a41106a2004290300220e37030020024180016a41186a2005290300220f370300200220022903402210370380012000200b3a0001200041013a0000200041026a20103700002000410a6a200d370000200041126a200e3700002000411a6a200f370000200041306a200c3602002000412c6a2008360100200041286a2007360100200041246a20063601000c0e0b200541ff0171450d00200241003a00e8030b200041063a0000200741ffffff3f71450d0c200610290c0c0b200041063a00000c0b0b200041063a0000200741ffffff3f71450d0a200610290c0a0b200241c8036a200110e40320022802c8032105200241a0016a200241c8036a41047241a40210e4071a024002402005411c460d00200241c8036a200241a0016a41a40210e4071a41a802102722030d010c0a0b200041063a00000c0a0b20032005360200200341046a200241c8036a41a40210e4071a2002200110c801024020022802000d0020022802042101200041023a0000200020022f0080013b0001200041086a2001360200200041046a20033602002000410c6a2002290240370200200041036a20024180016a41026a2d00003a0000200041146a200241c0006a41086a2902003702002000411c6a200241d0006a290200370200200041246a200241d8006a2902003702002000412c6a200241e0006a290200370200200041346a200241e8006a2802003602000c0a0b200041063a0000200310cc01200310290c090b200241106a200110c80120022802100d052002280214210a200241c8036a200110e40320022802c8032105200241a0016a200241c8036a41047241a40210e4071a2005411c460d04200241c8036a200241a0016a41a40210e4071a41a80210272203450d0720032005360200200341046a200241c8036a41a40210e4071a200241086a200110c801024020022802080d00200228020c2101200041033a0000200020022f0080013b00012000410c6a2001360200200041086a2003360200200041046a200a360200200041106a2002290340370300200041036a20024182016a2d00003a0000200041186a200241c0006a41086a290300370300200041206a200241c0006a41106a290300370300200041286a200241c0006a41186a290300370300200041306a200241c0006a41206a2903003703000c090b200041063a0000200310cc01200310290c080b41002105200241003a00e8032003417f6a21092003417e6a21030240024002400240034020092005460d01200241c8036a20056a200420056a220a41016a2d00003a0000200120033602042001200a41026a3602002002200541016a220a3a00e8032003417f6a2103200a2105200a4120470d000b200241c0006a41086a200241c8036a41086a290300370300200241c0006a41106a200241c8036a41106a290300370300200241c0006a41186a200241c8036a41186a290300370300200220022903c803370340200241186a200110c80120022802180d0120012802042203450d01200228021c21042001280200220a2d0000210520012003417f6a3602042001200a41016a360200200541014b0d014100210120050e020302030b200541ff0171450d00200241003a00e8030b200041063a00000c090b410121010b20024180016a41186a200241c0006a41186a290300220d37030020024180016a41106a200241c0006a41106a290300220e37030020024180016a41086a200241c0006a41086a290300220f37030020022002290340221037038001200041043a000020002010370001200041096a200f370000200041116a200e370000200041196a200d370000200041246a2004360200200041216a20013a0000200041286a2002290370370300200041306a200241f0006a41086a2903003703000c070b41002105200241003a00e8032003417f6a21092003417e6a21030240034020092005460d01200241c8036a20056a200420056a220a41016a2d00003a0000200120033602042001200a41026a3602002002200541016a220a3a00e8032003417f6a2103200a2105200a4120470d000b200241c0006a41086a200241c8036a41086a290300370300200241c0006a41106a200241c8036a41106a290300370300200241c0006a41186a200241c8036a41186a290300370300200220022903c803370340200241386a200110c8012002280238450d020c050b200541ff0171450d04200241003a00e8030c040b200041063a00000c050b200228023c2105200241286a200110aa052002290328a70d022002290330210d200241206a200110c80120022802200d022002280224210120024180016a41186a200241c0006a41186a290300220e37030020024180016a41106a200241c0006a41106a290300220f37030020024180016a41086a200241c0006a41086a290300221037030020022002290340221137038001200041053a000020002011370001200041096a2010370000200041116a200f370000200041196a200e370000200041216a20022f00703b0000200041236a200241f2006a2d00003a0000200041306a200d370300200041286a2001360200200041246a20053602000c040b200041063a00000c030b200041063a00000c020b200041063a00000c010b1030000b200241f0056a24000bab0b04057f017e017f037e230041a0056b2202240002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541034b0d0520050e0401020304010b200041053a00000c070b200241f8026a200110e40320022802f8022101200241d0006a200241f8026a41047241a40210e4071a024002402001411c460d00200241f8026a200241d0006a41a40210e4071a41a802102722050d010c070b200041053a00000c070b20052001360200200541046a200241f8026a41a40210e4071a200041013a0000200020022f00103b0001200041036a200241126a2d00003a0000200041046a2005360200200041086a2002290330370300200041106a200241306a41086a290300370300200041186a200241306a41106a290300370300200041206a200241306a41186a2903003703000c060b200241f8026a200110e40320022802f8022105200241d0006a200241f8026a41047241a40210e4071a2005411c460d03200241f8026a200241d0006a41a40210e4071a41a80210272203450d0420032005360200200341046a200241f8026a41a40210e4071a0240200128020422054108490d002001280200220629000021072001200541786a3602042001200641086a360200200041023a0000200020022f00103b0001200041036a200241106a41026a2d00003a0000200041086a2007370300200041046a2003360200200041106a2002290330370300200041186a200241306a41086a290300370300200041206a200241306a41106a2903003703000c060b200041053a0000200310cc01200310290c050b41002105200241003a0098032003417f6a21082003417e6a21030240034020082005460d01200241f8026a20056a200420056a220641016a2d00003a0000200120033602042001200641026a3602002002200541016a22063a0098032003417f6a21032006210520064120470d000b200241306a41086a200241f8026a41086a2903002207370300200241306a41106a200241f8026a41106a2903002209370300200241306a41186a200241f8026a41186a290300220a370300200220022903f802220b370330200041033a00002000200b370001200041096a2007370000200041116a2009370000200041196a200a370000200041216a2002280010360000200041246a200241106a41036a2800003600000c050b0240200541ff0171450d00200241003a0098030b200041053a00000c040b41002105200241003a0098032003417f6a21082003417e6a210302400240034020082005460d01200241f8026a20056a200420056a220641016a2d00003a0000200120033602042001200641026a3602002002200541016a22063a0098032003417f6a21032006210520064120470d000b200241306a41086a200241f8026a41086a290300370300200241306a41106a200241f8026a41106a290300370300200241306a41186a200241f8026a41186a290300370300200220022903f802370330200241f8026a200110e40320022802f8022101200241d0006a200241f8026a41047241a40210e4071a2001411c460d01200241f8026a200241d0006a41a40210e4071a41a80210272205450d0420052001360200200541046a200241f8026a41a40210e4071a200241106a41186a200241306a41186a2903002207370300200241106a41106a200241306a41106a2903002209370300200241106a41086a200241306a41086a290300220a37030020022002290330220b370310200041043a00002000200b370001200041096a200a370000200041116a2009370000200041196a2007370000200041216a20022f000d3b0000200041236a2002410f6a2d00003a0000200041246a20053602000c050b200541ff0171450d00200241003a0098030b200041053a00000c030b200041053a00000c020b200041053a00000c010b1030000b200241a0056a24000b8d0201067f024002400240200128020422020d00410121030c010b200128020022042d0000210520012002417f6a2206360204410121032001200441016a360200200541037122074103460d0002400240024020070e03020100020b20064103490d02200441036a2d0000210720042f0001210620012002417c6a3602042001200441046a360200200620074110747241087420057222024180807c6a41ffff0b4b0d0320024102762101410021030c030b2006450d0120042d0001210320012002417e6a3602042001200441026a360200200341087420057241ffff03712201418002492103200141027621010c020b20054102762101410021030c010b0b200020013b0102200020033b01000b892903137f067e127f230041f0036b220324000240024002400240024002400240024002400240024002400240024020012d00000e050001020304000b200341b4016a4101360200200342013702a40120034198e3ca003602a001200341043602cc03200341cce3ca003602c8032003200341c8036a3602b001200341a0016a4180a6cc001040000b200141046a280200210120022d00000d0320022d00014101470d03200241196a2d00002104200241186a2d00002105200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a290100370370200320043a006f200320053a006e200320063b016c200320073a006b200320083a006a200320093b01682003200a3a00672003200b3a00662003200c3b01642003200d3a00632003200e3a00622003200f3b0160200320103a005f200320113a005e200320123b015c200320133a005b200320143a005a200320153b01584188dac700ad4280808080c00084100122022900002116200229000821172002102941b789cb00ad428080808030841001220229000021182002290008211920021029200320193701e003200320183701d803200320173701d003200320163701c803200341a0016a200341c8036a412010cd010240024020032d00a0014101460d00200341e0036a4200370300200341d8036a4200370300200341d0036a4200370300200342003703c8030c010b200320032900a1013703c8032003200341b9016a2900003703e0032003200341a9016a2900003703d0032003200341b1016a2900003703d8030b0240200341d8006a200341c8036a412010e7070d00200341a0016a200141a80210e4071a200341003b01c803200341f8006a200341a0016a200341c8036a10c50120032003290091013703a0012003200341f8006a41206a2800003600a701024020032903784201510d00410421020c0b0b20034190016a2d000021042003290380012116200320032800a70136003f200320032903a0013703384104210220164202510d0a2003200328003f36000f20032003290338370308200421020c0a0b200110cc012001102941833c21020c080b200141046a280200210120022d00000d0320022d00014101470d03200241196a2d00002104200241186a2d00002105200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a290100370370200320043a006f200320053a006e200320063b016c200320073a006b200320083a006a200320093b01682003200a3a00672003200b3a00662003200c3b01642003200d3a00632003200e3a00622003200f3b0160200320103a005f200320113a005e200320123b015c200320133a005b200320143a005a200320153b01584188dac700ad4280808080c00084100122022900002116200229000821172002102941b789cb00ad428080808030841001220229000021182002290008211920021029200320193701e003200320183701d803200320173701d003200320163701c803200341a0016a200341c8036a412010cd010240024020032d00a0014101460d00200341e0036a4200370300200341d8036a4200370300200341d0036a4200370300200342003703c8030c010b200320032900a1013703c8032003200341b9016a2900003703e0032003200341a9016a2900003703d0032003200341b1016a2900003703d8030b0240200341d8006a200341c8036a412010e7070d00200341a0016a200141a80210e4071a200341003b01c803200341f8006a200341a0016a200341c8036a10c50120032003290091013703a0012003200341f8006a41206a2800003600a701024020032903784201510d00410421020c080b20034190016a2d000021042003290380012116200320032800a70136003f200320032903a0013703384104210220164202510d072003200328003f36000f20032003290338370308200421020c070b200110cc012001102941833c21020c050b200341086a41186a200141196a290000370300200341086a41106a200141116a290000370300200341086a41086a200141096a290000370300200320012900013703080240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a290100370370200320013a006f200320043a006e200320053b016c200320063a006b200320073a006a200320083b0168200320093a00672003200a3a00662003200b3b01642003200c3a00632003200d3a00622003200e3b01602003200f3a005f200320103a005e200320113b015c200320123a005b200320133a005a200320143b01584188dac700ad4280808080c00084100122022900002116200229000821172002102941b789cb00ad428080808030841001220229000021182002290008211920021029200320193701e003200320183701d803200320173701d003200320163701c803200341a0016a200341c8036a412010cd010240024020032d00a0014101460d00200341e0036a4200370300200341d8036a4200370300200341d0036a4200370300200342003703c8030c010b200320032900a1013703c8032003200341b9016a2900003703e0032003200341a9016a2900003703d0032003200341b1016a2900003703d8030b0240200341d8006a200341c8036a412010e707450d0041833c21020c020b200341f8006a41186a2201200341086a41186a290300370300200341f8006a41106a2204200341086a41106a290300370300200341f8006a41086a2205200341086a41086a290300370300200320032903083703784188dac700ad4280808080c000842216100122022900002117200229000821182002102941b789cb00ad42808080803084221910012202290000211a2002290008211b200210292003201b3701e0032003201a3701d803200320183701d003200320173701c803200341a0016a200341c8036a412010cd010240024020032d00a0014101460d004100210242002117410021064100210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f4100211041002111410021124100211341002114410021154100211c0c010b200341a0016a41086a2d00002111200341a9016a2f00002110200341ab016a2d0000210f200341ac016a2d0000210e200341ad016a2f0000210d200341af016a2d0000210c200341a0016a41106a2d0000210b200341b1016a2f0000210a200341b3016a2d00002109200341b4016a2d00002108200341b5016a2f00002107200341b7016a2d00002106200341a0016a41186a2d00002102200341b9016a290000211720032f00a101211c20032d00a301211520032d00a401211420032f00a501211320032d00a70121120b200341bd016a2017370000200341bc016a20023a0000200341bb016a20063a0000200341b9016a20073b0000200341a0016a41186a220220083a0000200341b7016a20093a0000200341b5016a200a3b0000200341b3016a200c3a0000200341b1016a200d3b0000200341a0016a41106a2206200e3a0000200341af016a200f3a0000200341ad016a20103b0000200341ac016a20113a0000200341ab016a20123a0000200341a9016a20133b0000200341a0016a41086a220720143a0000200341143a00a001200341a0016a41146a200b3a0000200320153a00a7012003201c3b00a501200341013a00a401200341a0016a10cb01200220012903003703002006200429030037030020072005290300370300200320032903783703a001201610012202290000211620022900082117200210292019100122022900002118200229000821192002102920032019370150200320183701482003201737014020032016370138412010272202450d05200220032903a001370000200241186a200341a0016a41186a290300370000200241106a200341a0016a41106a290300370000200241086a200341a0016a41086a290300370000200341386aad42808080808004842002ad42808080808004841003200210290c0a0b41823c21020b20004200370308200041206a410b3602002000411c6a41d8b0c700360200200041186a2002360200420121160c090b200141246a28020021040240024002400240024020022d00000d0020022d00014101470d00200141196a290000211a200141186a2d0000211c200141176a2d0000211d200141156a2f0000211e200141146a2d0000211f200141136a2d00002120200141116a2f00002121200141106a2d000021222001410f6a2d000021232001410d6a2f000021242001410c6a2d000021252001410b6a2d00002126200141096a2f00002127200141086a2d00002128200141076a2d00002129200141056a2f0000212a200141046a2d0000212b200141036a2d0000212c20012f0001212d200241196a2d00002101200241186a2d00002105200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a290100370370200320013a006f200320053a006e200320063b016c200320073a006b200320083a006a200320093b01682003200a3a00672003200b3a00662003200c3b01642003200d3a00632003200e3a00622003200f3b0160200320103a005f200320113a005e200320123b015c200320133a005b200320143a005a200320153b01584188dac700ad4280808080c00084100122022900002116200229000821172002102941b789cb00ad428080808030841001220229000021182002290008211920021029200320193701e003200320183701d803200320173701d003200320163701c803200341a0016a200341c8036a412010cd010240024020032d00a0014101460d00200341e0036a4200370300200341d8036a4200370300200341d0036a4200370300200342003703c8030c010b200320032900a1013703c8032003200341b9016a2900003703e0032003200341a9016a2900003703d0032003200341b1016a2900003703d8030b0240200341d8006a200341c8036a412010e707450d00200410cc012004102941833c21020c020b2003201a3701502003201c3a004f2003201d3a004e2003201e3b014c2003201f3a004b200320203a004a200320213b0148200320223a0047200320233a0046200320243b0144200320253a0043200320263a0042200320273b0140200320283a003f200320293a003e2003202a3b013c2003202b3a003b2003202c3a003a2003202d3b0138200341a0016a200441a80210e4071a200341d2036a2003290140370100200341da036a2003290148370100200341e2036a200329015037010020034180023b01c803200320032901383701ca03200341f8006a200341a0016a200341c8036a10c5014101210220032903784201520d04200341a0016a41186a20034198016a290300370300200341a0016a41106a2202200341f8006a41186a290300370300200341a8016a200341f8006a41106a29030037030020032003290380013703a001200210ff0541e0a3c800ad4280808080a001841008419aa1c000ad4280808080e00184100820032903a0014201510d024190a1c000ad4280808080a0018410080c030b200410cc012004102941823c21020b20004200370308200041206a410b3602002000411c6a41d8b0c700360200200041186a2002360200420121160c0b0b20032903a80110160b410021020b200320023a00a501200341023a00a401200341143a00a001200341a0016a10cb01200410290c070b200110cc012001102941823c21020c040b200110cc012001102941823c21020c010b1039000b20004200370308200041206a410b3602002000411c6a41d8b0c700360200200041186a2002360200420121160c040b200320032903083703282003200328000f36002f200341a0016a41086a20023a0000200341a9016a2003290328370000200341a0016a41106a200328002f360000200341003a00a401200320032f00353b00a5012003200341376a2d00003a00a701200341143a00a001200341a0016a41146a20032902c803370200200341bc016a200341c8036a41086a290200370200200341c4016a200341c8036a41106a280200360200200341a0016a10cb01200110290c020b20004200370308200041206a410b3602002000411c6a41d8b0c700360200200041186a2002360200420121160c020b200320032903083703282003200328000f36002f200341a0016a41086a20023a0000200341a9016a2003290328370000200341a0016a41106a200328002f360000200341003a00a401200320032f00353b00a5012003200341376a2d00003a00a701200341143a00a001200341a0016a41146a20032902c803370200200341bc016a200341c8036a41086a290200370200200341c4016a200341c8036a41106a280200360200200341a0016a10cb01200110290b42002116200042003703080b20002016370300200341f0036a24000bb90403027f017e077f230041306b2202240041e0a7c800ad4280808080900184100122032900002104200241086a200341086a290000370300200220043703002003102941e9a7c800ad4280808080e00084100122032900002104200241106a41086a200341086a2900003703002002200437031020031029200241206a20012802002205200128020810eb0202400240024002402002280228220641206a2207417f4c0d00200228022021080240024020070d0041002109410121030c010b200710272203450d02200721090b024002402009410f4d0d002009210a0c010b2009410174220a4110200a41104b1b220a4100480d03024020090d00200a102722030d010c050b2009200a460d0020032009200a102b2203450d040b20032002290300370000200341086a200241086a29030037000002400240200a4170714110460d00200a21090c010b200a41017422094120200941204b1b22094100480d03200a2009460d002003200a2009102b2203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200941606a2006490d002009210a0c010b200641206a220a2006490d032009410174220b200a200b200a4b1b220a4100480d032009200a460d0020032009200a102b2203450d040b200341206a2008200610e4071a200020073602082000200a3602042000200336020002402002280224450d00200810290b0240200141046a280200450d00200510290b200241306a24000f0b1038000b1039000b1032000b1030000bb30505037f017e037f017e027f230041e0026b22022400200241286a41086a200141086a28020036020020022001290200370328200241186a200241286a10b005200241286a200228021822012002280220220310f9010240200228022822044101470d002003ad4220862001ad8410040b200229022c21050240200228021c450d00200110290b0240024020044101470d00200241086a2005a7220610c001200241286a200228020822072002280210220410c10120022802282201410820011b21080240200229022c420020011b2209422088a722012005422088a7220a4d0d002008200a41c8026c6a2203450d002008200a41c8026c6a220441b4026a2107024020042802b4024102460d00024020042802a802220b450d002008200a41c8026c6a41ac026a280200450d00200b10290b200310cc010b2003200241286a41b40210e4071a20074102360200200441c0026a200241206a290300370300200420022903183703b80220022802102104200228020821070b0240024020080d002004ad4220862007ad8410040c010b200241286a2008200110e2022004ad4220862007ad84200235023042208620022802282204ad8410030240200228022c450d00200410290b02402001450d00200141c8026c21042008210103400240200141b4026a2802004102460d000240200141a8026a2802002203450d00200141ac026a280200450d00200310290b200110c2010b200141c8026a2101200441b87d6a22040d000b0b2009a72201450d00200141c8026c450d00200810290b0240200228020c450d00200710290b200241346a200a360200200241306a20063602002002410136022c200241013a0028200241286a10cb01200041043a00000c010b20004183043b0100200041086a410e360200200041046a41e1b4c800360200200041026a41013a00000b200241e0026a24000bbb0402097f057e230041f0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022040d00200042003703000c010b200341186a28020021052003280214210641002101200341003a0068024002400240034020052001460d01200341c8006a20016a200420016a2d00003a00002003200141016a22023a00682002210120024120470d000b200341286a41186a2201200341c8006a41186a2207290300370300200341286a41106a2208200341c8006a41106a2209290300370300200341286a41086a220a200341c8006a41086a220b29030037030020032003290348370328200520026b410f4d0d01200b200a290300220c37030020092008290300220d37030020072001290300220e37030020032003290328220f370348200420026a22012900002110200041306a200141086a290000370300200041286a2010370300200041206a200e370300200041186a200d370300200041106a200c3703002000200f3703084201210c0c020b200141ff0171450d00200341003a00680b20034100360230200342013703282003410d3602242003200341086a3602202003200341286a36026c200341dc006a41013602002003420137024c200341f4eaca003602482003200341206a360258200341ec006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b4200210c0b2000200c3703002006450d00200410290b200341f0006a24000ba90102017f027e02400240411010272202450d00200241104120102b2202450d0120022000290000370000200241186a200041186a290000370000200241106a200041106a290000370000200241086a200041086a290000370000200041286a2903002103200029032021042002412041c000102b2200450d0120002004370020200041286a200337000020012902002000ad42808080808006841003200010290f0b1039000b1030000bb90603027f017e057f23004180016b2202240041b3e6ca00ad4280808080e00084100122032900002104200241306a41086a200341086a290000370300200220043703302003102941c0e6ca00ad4280808080900184100122032900002104200241d0006a41086a200341086a2900003703002002200437035020031029200220013602742002200241f4006aad4280808080c000841002220329000037037820031029200241146a200241f8006a3602002002200241f8006a41086a36020c2002200241f4006a3602102002200241f8006a360208200241c0006a200241086a107502400240024002402002280248220541206a2206417f4c0d00200228024021070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290330370000200341086a200241306a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290350370010200341186a200241d0006a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a02402002280244450d00200710290b200241086a2003200610cd01200241d0006a41086a2201200241116a290000370300200241d0006a41106a2206200241196a290000370300200241d0006a41186a2205200241216a290000370300200220022900093703500240024020022d00084101460d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002002290350370000200041186a2005290300370000200041106a2006290300370000200041086a20012903003700000b02402008450d00200310290b20024180016a24000f0b1038000b1039000b1032000b1030000bb10503027f017e047f230041d0006b2202240041b1dcc900ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941c2dcc900ad4280808080800184100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000bd60201027f23004180036b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d00200041003a00000c010b200328021421042003200341186a2802003602ec02200320013602e802200341c0016a200341e8026a10c703410121020240024020032d00c0014101470d004100210220034100360228200342013703202003410d3602f4022003200341086a3602f0022003200341206a3602fc02200341d4016a4101360200200342013702c401200341f4eaca003602c0012003200341f0026a3602d001200341fc026a41a8a3c800200341c0016a10371a200335022842208620033502208410082003280224450d01200328022010290c010b200341206a200341c0016a41017241a00110e4071a200041016a200341206a41a00110e4071a0b200020023a00002004450d00200110290b20034180036a24000be60703027f017e057f230041d0006b2202240041b1dcc900ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003102941cadcc900ad4280808080800184100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240200141086a28020041046a2203417f4c0d000240024020030d0041012105410021030c010b200310272205450d020b2002410036024820022005360240200220033602440240200341034b0d00200341017422064104200641044b1b22064100480d030240024020030d002006102722050d010c060b20032006460d00200520032006102b2205450d050b20022006360244200220053602400b2005200128000036000020024104360248200141046a2802002107200141086a2802002201200241c0006a10710240024020022802442208200228024822056b2001490d0020022802402103200821060c010b200520016a22032005490d03200841017422062003200620034b1b22064100480d030240024020080d00024020060d00410121030c020b200610272203450d060c010b2002280240210320082006460d00200320082006102b2203450d050b20022006360244200220033602400b200320056a2007200110e4071a2002200520016a2201ad4220862003ad841002220529000037033820051029200241cc006a200320016a360200200220033602482002200241c0006a3602442002200241386a360240200241286a200241c0006a107502402006450d00200310290b2002280230220841206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121050c010b200141017422054110200541104b1b22054100480d03024020010d00200510272203450d050c010b20012005460d00200320012005102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020054170714110460d00200521010c010b200541017422014120200141204b1b22014100480d0320052001460d00200320052001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2008490d00200121050c010b200841206a22052008490d03200141017422092005200920054b1b22054100480d0320012005460d00200320012005102b2203450d040b200341206a2007200810e4071a2000200636020820002005360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bf60603027f017e077f230041e0006b2203240041c6b7c700ad4280808080800184100122042900002105200341086a41086a200441086a290000370300200320053703082004102941c8f7c700ad4280808080a00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041029200320013602382003200341386aad4280808080c000841002220429000037034820041029200341dc006a2204200341386a41046a3602002003200341c8006a41086a22013602542003200341386a3602582003200341c8006a360250200341286a200341d0006a1075200320023602442003200341c4006aad4280808080c0008410022202290000370348200210292004200341c4006a41046a360200200320013602542003200341c4006a3602582003200341c8006a360250200341386a200341d0006a107502400240024002402003280230220641206a2207200328024022086a2202417f4c0d00200328023821092003280228210a0240024020020d004100210b410121040c010b200210272204450d022002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001102722040d010c050b200b2001460d002004200b2001102b2204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b102b2204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2006490d00200b21010c010b200641206a22012006490d03200b410174220c2001200c20014b1b22014100480d03200b2001460d002004200b2001102b2204450d040b200441206a200a200610e4071a02400240200120076b2008490d002001210b0c010b20022007490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10272204450d050c010b2001200b460d0020042001200b102b2204450d040b200420076a2009200810e4071a200020023602082000200b360204200020043602000240200328023c450d00200910290b0240200328022c450d00200a10290b200341e0006a24000f0b1038000b1039000b1032000b1030000bdaf50105027f037e117f057e0c7f230022032104200341a0066b416071220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e20000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000b200341b4056a4101360200200342013702a40520034198e3ca003602a005200341043602a403200341cce3ca003602a0032003200341a0036a3602b005200341a0056a4180a6cc001040000b200141306a2903002105200141286a290300210620034180036a41186a200141196a29000037030020034180036a41106a200141116a29000037030020034180036a41086a200141096a29000037030020032001290001370380032002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109024020022d0000450d002003200737029405200320013a009305200320083a009205200320093b0190050c490b200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820022d000121022003200737039005200241ff01714101470d48200320073703b804200320013a00b704200320083a00b604200320093b01b4042003200a3a00b3042003200b3a00b2042003200c3b01b0042003200d3a00af042003200e3a00ae042003200f3b01ac04200320103a00ab04200320113a00aa04200320123b01a804200320133a00a704200320143a00a604200320153b01a404200320163a00a304200320173a00a204200320183b01a0044100210120064280a094a58d1d5441002005501b0d1e200320063703e002200320053703e8022003200341a0046a360290052003200341a0046a3602c0022003200341c0026a3602a805200320034190056a3602a4052003200341e0026a3602a005200341a0036a200341a0046a200341a0056a108e040240024020032802a0034101470d0020032f00a50320032d00a703411074722101200341a8036a290300210720032d00a40321020c010b410421020240200341a0036a41086a2903004201520d00200341a0036a41106a290300210720032802c0022101200341d8056a200341a0036a41186a290300370300200341d0056a2007370300200341a0056a41086a41003a0000200341a9056a2001290000370000200341b1056a200141086a290000370000200341b9056a200141106a290000370000200341c1056a200141186a290000370000200341033a00a005200341a0056a10cb010b0b0240200241ff01714104470d0041c99fc500ad428080808090018422071001220229000021192002290008211a2002102941908dc700ad4280808080f00184221b10012202290000211c2002290008211d200210292003201d3701f8022003201c3701f0022003201a3701e802200320193701e002200341186a200341e0026a412010fc01200328021c21012003280218210820071001220229000021072002290008211920021029201b10012202290000211a2002290008211b200210292003201b3701f8022003201a3701f002200320193701e802200320073701e00220032001410020081b220941016a3602a005200341e0026aad42808080808004842207200341a0056aad4280808080c0008410032003200341a0046a3602e002200341a0036a200910a70520033502a803211920032802a003210c411810272202450d36200342183702a405200320023602a0054101200341a0056a107120032802e002210120032802a005210a0240024020032802a405220b20032802a80522086b4120490d00200b21020c010b200841206a22022008490d38200b410174220d2002200d20024b1b22024100480d380240200b0d00024020020d004101210a0c020b20021027220a0d010c4a0b200b2002460d00200a200b2002102b220a450d490b2003200a3602a005200a20086a220a2001290000370000200a41186a200141186a290000370000200a41106a200141106a290000370000200a41086a200141086a2900003700002003200841206a220a3602a805200320023602a405024002402002200a6b4110490d0020032802a00521012002210b0c010b200a41106a2201200a490d382002410174220b2001200b20014b1b220b4100480d380240024020020d000240200b0d00410121010c020b200b10272201450d4b0c010b20032802a00521012002200b460d0020012002200b102b2201450d4a0b2003200b3602a405200320013602a0050b2001200a6a22022005370008200220063700002019422086200cad84200841306aad4220862001ad8410030240200b450d00200110290b024020032802a403450d00200c10290b200341a0056a41086a20034180036a41086a290300370300200341a0056a41106a20034180036a41106a290300370300200341a0056a41186a20034180036a41186a290300370300200341a0036a41086a200341a0046a41086a290300370300200341a0036a41106a200341a0046a41106a290300370300200341a0036a41186a200341a0046a41186a29030037030020032003290380033703a005200320032903a0043703a00341c99fc500ad42808080809001841001220229000021192002290008211a2002102941a88dc700ad4280808080b0018410012202290000211b2002290008211c200210292003201c3701f8022003201b3701f0022003201a3701e802200320193701e002410410272201450d3620012009360000412010272202450d36200220032903a005370000200241186a2208200341a0056a41186a290300370000200241106a220a200341a0056a41106a290300370000200241086a220b200341a0056a41086a290300370000200141044124102b2201450d48200120022900003700042001411c6a2008290000370000200141146a200a2900003700002001410c6a200b290000370000200210292001412441c800102b2202450d48200220032903a0033700242002413c6a200341a0036a41186a290300370000200241346a200341a0036a41106a2903003700002002412c6a200341a0036a41086a29030037000020072002ad4280808080c00884101420021029200341a0056a41186a2005370300200341a0056a41106a2006370300200341a0056a410c6a2009360200200341a0056a41086a41003a0000200341093a00a005200341a0056a10cb010c470b200141ffffff077122084110762101200841087621092007422088a721032007a7210a0c490b200141086a280200211e200141046a280200211f2002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d002003200737029405200320013a009305200320083a009205200320093b019005410121020c010b20022d000121022003200737039005200241ff017141014721020b200320073701f802200320013a00f702200320083a00f602200320093b01f4022003200a3a00f3022003200b3a00f2022003200c3b01f0022003200d3a00ef022003200e3a00ee022003200f3b01ec02200320103a00eb02200320113a00ea02200320123b01e802200320133a00e702200320143a00e602200320153b01e402200320163a00e302200320173a00e202200320183b01e002024020020d0020034180036a41186a200341e0026a41186a29010037030020034180036a41106a200341e0026a41106a29010037030020034180036a41086a200341e0026a41086a290100370300200320032901e00237038003200341a0056a201f10a70520032802a805210820032802a005210241002101200341a4036a41003a0000200341003602a003200341386a20022008200341a0036a4105410010c701024002402003280238450d000240200328023c2201410520014105491b2201450d002001417f6a210a024020032d00a003220141037122094103460d0002400240024020090e03000102000b20014102762109410121010c050b200a450d0220032d00a103410874200172220141ffff0371418002490d02200141fcff03714102762109410121010c040b200a4103490d0120032f00a10320032d00a30341107472410874200172220141ffff034d0d0120014102762109410121010c030b200141034b0d00200a4104490d004101210120032800a103220941ffffffff034b0d020b41f0a7c000ad428080808080048410082008ad4220862002ad84100a410021010b0b024020032802a405450d00200210290b2001450d1f024002402009201e4b0d00200341c0026a201f10a705200341a0056a20032802c002220220032802c80210a805200341a0036a41086a2201200341ac056a290200370300200341a0036a41106a2208200341b4056a290200370300200341a0036a41186a2209200341bc056a280200360200200320032902a4053703a003024020032802a005220a450d00200341e0026a41186a2009280200360200200341e0026a41106a2008290300370300200341e0026a41086a2001290300370300200320032903a0033703e002024020032802c402450d00200210290b200341bc046a200341e0026a41186a280200360200200341b4046a200341f0026a290300370200200341ac046a200341e8026a2903003702002003200a3602a004200320032903e0023702a40420032903b00421072003200341a0046a41186a29030022053703e802200320073703e002200320034180036a36029005024020072005844200510d00200320034180036a3602c0022003200341c0026a3602a805200320034190056a3602a4052003200341e0026a3602a005200341a0036a20034180036a200341a0056a108e040240024020032802a0034101470d0020032f00a50320032d00a703411074722201411076210820014108762109200341a0036a41086a290300210720032d00a40321020c010b4104210202400240200341a0036a41086a2903004201510d00410021010c010b200341a0036a41106a290300210720032802c0022108200341d8056a200341a0036a41186a290300370300200341d0056a200737030041002101200341a0056a41086a41003a0000200341a9056a2008290000370000200341b1056a200841086a290000370000200341b9056a200841106a290000370000200341c1056a200841186a290000370000200341033a00a005200341a0056a10cb010b41002109410021080b200241ff01714104470d030b200329039803210720032d009703210820032d009603210920032f019403210b20032d009303210c20032d009203210d20032f019003210e20032d008f03210f20032d008e03211020032f018c03211120032d008b03211220032d008a03211320032f018803211420032d008703211520032d008603211620032f018403211720032d008303211820032d008203211e20032f0180032120024020032802a804220120032802a404470d00200341a0046a20014101109e0120032802a004210a20032802a80421010b200a20014105746a22022007370018200220083a0017200220093a00162002200b3b00142002200c3a00132002200d3a00122002200e3b00102002200f3a000f200220103a000e200220113b000c200220123a000b200220133a000a200220143b0008200220153a0007200220163a0006200220173b0004200220183a00032002201e3a0002200220203b00002003200141016a3602a804200341a0056a41186a200341a0046a41186a290300370300200341a0056a41106a200341a0046a41106a290300370300200341a8056a20032903a804370300200320032903a0043703a005200341a0036a201f10a70520032802a0032102200320032802a8033602e402200320023602e002200341a0056a200341e0026a10d005024020032802a403450d00200210290b20032802a40541ffffff3f71450d4920032802a00510290c490b024020032802c402450d00200210290b410210d5042109200341306a410210d6042003280234210a2003280230210b4103210241112101410021080c470b412610d5042109200341286a412610d6044103210241112101410021082003280228210b200328022c210a0c460b20074220882105024020032802a40441ffffff3f71450d00200a10290b2005a7210a2007a7210b0c450b4102210241002108410021010c440b200141046a2802002108200341a0036a41206a200141286a290300370300200341a0036a41186a200141206a290300370300200341a0036a41106a200141186a290300370300200341a0036a41086a200141106a2903003703002003200141086a2903003703a0030240024002400240024020022d00000d0020022d000141ff01714101460d010b200341023a0080030c010b200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211f20032002411a6a2901003703b804200320013a00b704200320093a00b6042003200a3b01b4042003200b3a00b3042003200c3a00b2042003200d3b01b0042003200e3a00af042003200f3a00ae04200320103b01ac04200320113a00ab04200320123a00aa04200320133b01a804200320143a00a704200320153a00a604200320163b01a404200320173a00a304200320183a00a2042003201f3b01a004200341a0056a41206a200341a0036a41206a290300370300200341a0056a41186a200341a0036a41186a290300370300200341a0056a41106a200341a0036a41106a290300370300200341a0056a41086a200341a0036a41086a290300370300200320032903a0033703a00520034180036a200341a0046a2008200341a0056a10d10520032d0080034104460d0120032902840321070b20032802800321032000411c6a2007370200200041186a2003360200420121070c010b420021070b200042003703080c480b200141046a2802002108200341a0036a41206a200141286a290300370300200341a0036a41186a200141206a290300370300200341a0036a41106a200141186a290300370300200341a0036a41086a200141106a2903003703002003200141086a2903003703a00320022d00000d1d20022d000141ff01714101470d1d2002411a6a2901002107200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a00e702200320143a00e602200320153b01e402200320163a00e302200320173a00e202200320183b01e0022003200e3a00ef022003200f3a00ee02200320103b01ec02200320113a00eb02200320123a00ea02200320133b01e802200320013a00f702200320093a00f6022003200a3b01f4022003200b3a00f3022003200c3a00f2022003200d3b01f002200320073701f802200341a0046a41186a2007370300200341a0046a41106a20032901f002370300200341a0046a41086a20032901e802370300200320032901e0023703a004200341a0056a200341a0046a10d2050240024020032d00a00522024102460d0020024101460d010b410310d5042102200341c0006a410310d604200320023a00c20220034183223b01c002200320032903403702c4020c420b200341a0056a41186a2d00002102200341b7056a2d00002101200341b5056a2f00002109200341b4056a2d0000210a200341b3056a2d0000210b200341b1056a2f0000210c200341a0056a41106a2d0000210d200341af056a2d0000210e200341ad056a2f0000210f200341ac056a2d00002110200341ab056a2d00002111200341a9056a2f00002112200341a0056a41086a2d0000211320032d00a705211420032f00a505211520032d00a405211620032d00a305211720032d00a205211820032d00a105211f2003200341b9056a29000037039803200320023a009703200320013a009603200320093b0194032003200a3a0093032003200b3a0092032003200c3b0190032003200d3a008f032003200e3a008e032003200f3b018c03200320103a008b03200320113a008a03200320123b018803200320133a008703200320143a008603200320153b018403200320163a008303200320173a008203200320183a0081032003201f3a008003200341a0056a41206a200341a0036a41206a290300370300200341a0056a41186a200341a0036a41186a290300370300200341a0056a41106a200341a0036a41106a290300370300200341a0056a41086a200341a0036a41086a290300370300200320032903a0033703a005200341c0026a20034180036a2008200341a0056a10d10520032d00c0024104460d430c410b4102210a20022d0000417f6a220b41034b0d3e200141046a280200210c02400240200b0e0400414101000b200241046a2d00000d3f200241086a28020041036c2002410c6a280200410174490d3f0b200341a0036a200c10dd04200341a0056a20032802a003220120032802a80310d30520032802a40321020240024020032d00a00522084102460d00200341f8056a2903002107200341f7056a2d00002109200341f6056a2d0000210a200341f4056a2f0100210b200341f3056a2d0000210d200341f2056a2d0000210e200341f0056a2f0100210f200341ef056a2d00002110200341ee056a2d00002111200341ec056a2f01002112200341eb056a2d00002113200341ea056a2d00002114200341e8056a2f01002115200341e7056a2d00002116200341e6056a2d00002117200341e4056a2f01002118200341e3056a2d0000211f200341e2056a2d0000211e200341e0056a2f0100212002402002450d00200110290b2008450d01200341143a00a005200341a0056a21020c3f0b02402002450d00200110290b200341143a00a005200341a0056a21020c3e0b200320073703b805200320093a00b7052003200a3a00b6052003200b3b01b4052003200d3a00b3052003200e3a00b2052003200f3b01b005200320103a00af05200320113a00ae05200320123b01ac05200320133a00ab05200320143a00aa05200320153b01a805200320163a00a705200320173a00a605200320183b01a4052003201f3a00a3052003201e3a00a205200320203b01a005200341a0036a200341a0056a10d405200341d8006a20032802a003220120032802a8034180a6cc004100410010c70120032802582102024020032802a403450d00200110290b024020024101460d00200320073703b805200320093a00b7052003200a3a00b6052003200b3b01b4052003200d3a00b3052003200e3a00b2052003200f3b01b005200320103a00af05200320113a00ae05200320123b01ac05200320133a00ab05200320143a00aa05200320153b01a805200320163a00a705200320173a00a605200320183b01a4052003201f3a00a3052003201e3a00a205200320203b01a005200341a0036a200341a0056a10d40520032802a003210220033502a8032107200341013a00e00220074220862002ad84200341e0026aad428080808010841003024020032802a403450d00200210290b200341ac056a200c360200200341a8056a41063a0000200341093a00a005200341a0056a10cb01200341a0056a200c10dd0420033502a80542208620032802a0052202ad84100420032802a405450d43200210290c430b410510d5042101200341d0006a410510d6044103210a20032802502109200328025421080c3f0b200341b8036a200141196a290000370300200341b0036a200141116a290000370300200341a8036a200141096a290000370300200320012900013703a003024002400240024020022d0000417f6a220141034b0d000240024020010e0400020201000b200241086a2802004101742002410c6a280200490d01200241046a28020041ff01710d010b41c99fc500ad4280808080900184221a100122022900002107200229000821052002102941d892c700ad4280808080c001841001220229000021062002290008211920021029200320193701f802200320063701f002200320053701e802200320073701e002200341f8006a200341e0026a41204180a6cc004100410010c70120032802784101460d01200341a0056a41186a2201200341a0036a41186a290300370300200341a0056a41106a2208200341a0036a41106a290300370300200341a0056a41086a2209200341a0036a41086a290300370300200320032903a0033703a005201a100122022d000f210a20022d000e210b20022f000c210c20022d000b210d20022d000a210e20022f0008210f20022d0007211020022d0006211120022f0004211220022d0003211320022d0002211420022f0000211520021029419c93c700ad428080808090018410012202290008210720022d0007211620022d0006211720022f0004211820022d0003211f20022d0002211e20022f0000212020021029412010272202450d34200220032903a005370000200241186a2001290300370000200241106a2008290300370000200241086a2009290300370000412010272201450d3420012002290000370000200141186a2208200241186a290000370000200141106a2209200241106a290000370000200141086a2221200241086a2900003700002002102941c00010272202450d3420022007370018200220163a0017200220173a0016200220183b00142002201f3a00132002201e3a0012200220203b00102002200a3a000f2002200b3a000e2002200c3b000c2002200d3a000b2002200e3a000a2002200f3b0008200220103a0007200220113a0006200220123b0004200220133a0003200220143a0002200220153b0000200241386a2008290000370000200241306a2009290000370000200241286a20212900003700002002200129000037002020011029200341a0056a200241c00010d50520032802a005210920032903a805210720032802a40521082002102902402008450d00200341a0056a41186a4200370300200341a0056a41106a220a4200370300200341a0056a41086a22024200370300200342003703a00541b3e6ca00ad4280808080e000841001220129000021052002200141086a290000370300200320053703a0052001102941c9e6ca00ad4280808080e00084100122012900002105200341e0026a41086a220b200141086a290000370300200320053703e00220011029200a20032903e0022205370300200341a0046a41086a2002290300370300200341a0046a41106a2005370300200341a0046a41186a200b290300370300200320032903a0053703a004200341f0006a200341a0046a412010fc0102402003280274410020032802701b20094f0d00410710d5042102200341e8006a410710d60420032802682101200328026c2103200742ffffff3f83500d04200810290c040b200742ffffff3f83500d00200810290b200341a0056a41186a200341a0036a41186a290300370300200341a0056a41106a200341a0036a41106a290300370300200341a0056a41086a200341a0036a41086a290300370300200320032903a0033703a005200341003a00c00541c99fc500ad4280808080900184100122022900002107200229000821052002102941d892c700ad4280808080c001841001220229000021062002290008211920021029200320193701f802200320063701f002200320053701e802200320073701e002200341203602a4042003200341e0026a3602a004200341a0056a200341a0046a10d6050c450b410221080c020b410610d5042102200341e0006a410610d60420032802602101200328026421030b410321080b20004200370308200041206a20033602002000411c6a2001360200200041186a200241ff017141107420087241802272360200420121070c450b200341a0036a41186a200141196a290000370300200341b0036a200141116a290000370300200341a0036a41086a200141096a290000370300200320012900013703a0030240024020022d0000417f6a220141034b0d00024020010e0400010102000b200241046a2d00000d00200241086a28020041056c2002410c6a28020041036c4f0d010b20004200370308200041186a4102360200420121070c450b200341a0056a41186a200341a0036a41186a290300370300200341a0056a41106a200341a0036a41106a290300370300200341a0056a41086a200341a0036a41086a290300370300200320032903a0033703a005200341023a00c00541c99fc500ad4280808080900184100122022900002107200229000821052002102941d892c700ad4280808080c001841001220229000021062002290008211920021029200320193701f802200320063701f002200320053701e802200320073701e002200341203602a4042003200341e0026a3602a004200341a0056a200341a0046a10d6050c400b200341a0036a41186a200141196a290000370300200341b0036a200141116a290000370300200341a8036a200141096a290000370300200320012900013703a0030240024020022d0000417f6a220141034b0d00024020010e0400010102000b200241086a2802002002410c6a280200490d00200241046a28020041ff0171450d010b20004200370308200041186a4102360200420121070c440b200341a0056a41186a200341a0036a41186a290300370300200341a0056a41106a200341a0036a41106a290300370300200341a0056a41086a200341a0036a41086a290300370300200320032903a0033703a005200341013a00c00541c99fc500ad4280808080900184100122022900002107200229000821052002102941d892c700ad4280808080c001841001220229000021062002290008211920021029200320193701f802200320063701f002200320053701e802200320073701e002200341203602a4042003200341e0026a3602a004200341a0056a200341a0046a10d6050c3f0b200141286a280200210d200141246a2802002108200341c0026a41086a220a2002411c6a2800003602002003200241146a2900003703c0022002410c6a280000210b200241086a280000210c200241046a280000210920022d0000210220034198036a200141196a29000037030020034190036a200141116a29000037030020034180036a41086a200141096a290000370300200320012900013703800302400240200841880e490d0020034190056a41086a200a280200360200200320032903c0023703900520024102470d01200941ff01710d3641002109200c41036c200b4101744f0d350c340b2002417e6a220241024b0d3520020e03333534330b20024104460d330c340b20034198036a200141196a29000037030020034180036a41106a200141116a29000037030020034180036a41086a200141096a290000370300200320012900013703800341022101024020022d00004102470d00200241236a2d00002109200241216a2f0000210a2002411f6a2d0000210b2002411d6a2f0000210c2002410f6a2d0000210d2002410d6a2f0000210e2002410b6a2d0000210f200241096a2f00002110200241076a2d00002111200241056a2f00002112200241246a2802002113200241206a2d00002114200241116a2900002107200241106a2d000021152002410c6a2d00002116200241086a2d00002117200241046a2d000021082003200241196a28000036029805200320073703900520084101470d002003200a20094110747222023b01bc03200341be036a20024110763a00002003200c200b4110747222023b01b803200341ba036a20024110763a00002003200e200d4110747222023b01a803200341a0036a410a6a20024110763a000020032007a722023b01ac03200341ae036a20024110763a0000200320133a00bf03200320143a00bb0320032003290294053703b003200320153a00ab03200320163a00a703200320173a00a303200320074218883c00af0320032010200f4110747222023b01a403200320024110763a00a6032003201220114110747222023b01a003200320024110763a00a20341c99fc500ad4280808080900184100122022900002107200229000821052002102941d892c700ad4280808080c001841001220229000021062002290008211920021029200320193701f802200320063701f002200320053701e802200320073701e002200341a0056a200341e0026a10a3050240024020032d00c0054103460d0020032903a005210720032903a805210520032903b0052106200320032903b8053703b805200320063703b005200320053703a805200320073703a00520034180036a200341a0056a412010e707450d01410210d5042102200341b0016a410210d60420032802b401210820032802b00121030c320b410a10d504210220034198016a410a10d604200328029c0121082003280298012103410321010c320b200341a0046a20034180036a10d705200341a0056a20032802a004220220032802a80410d50520032903a805210720032802a405210e024020032802a404450d00200210290b0240200e0d004100210f200341003602c802200342013703c0024101210e0c2c0b2003200e3602c002200320073702c4022007a7210f41002102024002402007422088a7220a41014b0d00200a0e022d012d0b200a210103402001410176220820026a22092002200e20094105746a200341a0036a412010e7074101481b2102200120086b220141014b0d000b0b0240200e20024105746a200341a0036a412010e7072201450d00200341a0056a41186a200341a0036a41186a290300370300200341a0056a41106a200341a0036a41106a290300370300200341a0056a41086a200341a0036a41086a290300370300200320032903a0033703a0052001411f7620026a2208200a4b0d1a200341a0056a21010c2d0b410b10d5042102200341a8016a410b10d60420032802ac01210820032802a8012103200f41ffffff3f71450d30200e1029410321010c310b0c300b20022d000120022d0000410047720d18200341ac056a200141046a2802002202360200200341a8056a41063a0000200341093a00a005200341a0056a10cb01200341a0056a200210dd0420033502a80542208620032802a0052202ad84100420032802a405450d3c200210290c3c0b0240024020022d000120022d000041004772450d004102210241802221010c010b200141046a2802002101410c10272202450d2b20022001360008200242e4cab5fbb6ccdcb0e3003700002003428c808080c0013702a405200320023602a005200341a0036a200341a0056a10b10520032d00a0034104460d3c410210d5042102200341b8016a410210d604200241ff01714110744180227221014103210220032802b801210820032802bc0121030b20004200370308200041206a20033602002000411c6a2008360200200041186a2001200272360200420121070c3f0b200341c0026a41186a200141196a290000370300200341c0026a41106a200141116a290000370300200341c0026a41086a200141096a290000370300200320012900013703c0022002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d002003200737029405200320013a009305200320083a009205200320093b019005410121020c010b20022d000121022003200737039005200241ff017141014721020b0240024020020d00200341e0026a200341c0026a10d805200341a0056a20032802e002221f20032802e802222010d905200341c0056a2d000021020240024020032d00a005221e4102470d00200341023a0080030c010b200320032d00a3053a008303200320032f00a1053b008103200320032902a405370284032003201e3a0080032003200341b8056a290300370398032003200341ac056a29020037028c032003200341b4056a280200360294030b200320013a00b704200320083a00b604200320093b01b4042003200a3a00b3042003200b3a00b2042003200c3b01b0042003200d3a00af042003200e3a00ae042003200f3b01ac04200320103a00ab04200320113a00aa04200320123b01a804200320133a00a704200320143a00a604200320153b01a404200320163a00a304200320173a00a204200320183b01a004200320073703b804200341b8056a200329039803370300200341a0056a41206a20023a0000200341023a00a00320032003290390033703b00520032003290388033703a805200320032903800322053703a005200320032903b80337039803200320032903b00337039003200320032903a80337038803200320032903a00337038003024002402005a7410371417f6a220141014b0d0041192102024020010e020002000b410c21020c010b411a2102200341a0056a410172200341a0046a412010e7070d00200320032903a00437008103200341013a0080032003200341b7046a290000370098032003200341b0046a290300370091032003200341a8046a2903003700890320032003290398033703b80520032003290390033703b00520032003290388033703a805200320032903800322053703a005024002402005a7220241ff01714102470d002020ad422086201fad8410040c010b410110272201450d3f200120023a0000200141014121102b2202450d3f200220032900a10537000120022007423888a73a0020200241186a20032900b805370000200241116a20032900b105370000200241096a20032900a9053700002020ad422086201fad842002ad42808080809004841003200210290b412821020b024020032802e402450d00201f10290b20024128460d3c200210d5042101200341c0016a200210d604200141ff017141107441802272210220032802c401210120032802c0012103410321080c010b4102210841802221020b20004200370308200041206a20013602002000411c6a2003360200200041186a2002200872360200420121070c3e0b20022d00000d1620022d000141ff01714101470d16200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820032002411a6a2901003703b803200320013a00b703200320083a00b603200320093b01b4032003200a3a00b3032003200b3a00b2032003200c3b01b0032003200d3a00af032003200e3a00ae032003200f3b01ac03200320103a00ab03200320113a00aa03200320123b01a803200320133a00a703200320143a00a603200320153b01a403200320163a00a303200320173a00a203200320183b01a003200341a0046a200341a0036a10d805200341a0056a20032802a004220220032802a804220110d905024020032d00a0054102460d00200341a0036a10b2020b2001ad4220862002ad84100420032802a404450d39200210290c390b200341c0026a41186a200141196a290000370300200341c0026a41106a200141116a290000370300200341c0026a41086a200141096a290000370300200320012900013703c0022002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d002003200737029405200320013a009305200320083a009205200320093b019005410121020c010b20022d000121022003200737039005200241ff017141014721020b0240024020020d00200341e0026a200341c0026a10d805200341a0056a20032802e002221f20032802e802222010d905200341c0056a2d000021020240024020032d00a005221e4102470d00200341023a0080030c010b200320032d00a3053a008303200320032f00a1053b008103200320032902a405370284032003201e3a0080032003200341b8056a290300370398032003200341ac056a29020037028c032003200341b4056a280200360294030b200320013a00b704200320083a00b604200320093b01b4042003200a3a00b3042003200b3a00b2042003200c3b01b0042003200d3a00af042003200e3a00ae042003200f3b01ac04200320103a00ab04200320113a00aa04200320123b01a804200320133a00a704200320143a00a604200320153b01a404200320163a00a304200320173a00a204200320183b01a004200320073703b804200341b8056a200329039803370300200341a0056a41206a20023a0000200341023a00a00320032003290390033703b00520032003290388033703a805200320032903800322053703a005200320032903b80337039803200320032903b00337039003200320032903a80337038803200320032903a00337038003411b210202402005a741ff01714101470d00410d2102200341a0056a410172200341a0046a412010e7070d00200320032903a00437008103200341003a0080032003200341b7046a290000370098032003200341b0046a290300370091032003200341a8046a2903003700890320032003290398033703b80520032003290390033703b00520032003290388033703a805200320032903800322053703a005024002402005a7220241ff01714102470d002020ad422086201fad8410040c010b410110272201450d3d200120023a0000200141014121102b2202450d3d200220032900a10537000120022007423888a73a0020200241186a20032900b805370000200241116a20032900b105370000200241096a20032900a9053700002020ad422086201fad842002ad42808080809004841003200210290b412821020b024020032802e402450d00201f10290b20024128460d3a200210d5042101200341c8016a200210d604200141ff017141107441802272210220032802cc01210120032802c8012103410321080c010b4102210841802221020b20004200370308200041206a20013602002000411c6a2003360200200041186a2002200872360200420121070c3c0b200141306a2903002107200141286a2903002105200141216a2d00002108200341a0046a41186a200141196a290000370300200341a0046a41106a200141116a290000370300200341a0046a41086a200141096a290000370300200320012900013703a0044102210102400240024020022d0000450d000c010b024020022d000141ff01714101460d000c010b2002411a6a2901002106200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a00e702200320143a00e602200320153b01e402200320163a00e302200320173a00e202200320183b01e0022003200e3a00ef022003200f3a00ee02200320103b01ec02200320113a00eb02200320123a00ea02200320133b01e802200320013a00f702200320093a00f6022003200a3b01f4022003200b3a00f3022003200c3a00f2022003200d3b01f002200320063701f802200341a0036a41186a2006370300200341a0036a41106a20032901f002370300200341a0036a41086a20032901e802370300200320032901e0023703a003200341a0056a41186a200341a0046a41186a290300370300200341a0056a41106a200341a0046a41106a290300370300200341a0056a41086a200341a0046a41086a290300370300200320032903a0043703a00520034180036a200341a0036a200341a0056a20082005200710da0520032802840321012003280280034101470d0120034180036a41086a29030021070b2000411c6a2007370200200041186a200136020020004200370308420121070c3c0b20004201370308200041106a2001ad220742c0b2cd3b7e200742a0b1ee037e7c42c0c0a4d2017c370300420021070c3b0b4102210102400240024020022d0000450d000c010b024020022d000141ff01714101460d000c010b2002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f010021172003200241096a2d00003a00e702200320133a00e602200320143b01e402200320153a00e302200320163a00e202200320173b01e0022003200d3a00ef022003200e3a00ee022003200f3b01ec02200320103a00eb02200320113a00ea02200320123b01e802200320013a00f702200320083a00f602200320093b01f4022003200a3a00f3022003200b3a00f2022003200c3b01f002200320073701f802200341b8056a2007370300200341a0056a41106a20032901f002370300200341a0056a41086a20032901e802370300200320032901e0023703a005200341a0036a200341a0056a10db0520032802a403210120032802a0034101470d01200341a0036a41086a29030021070b200042003703082000411c6a2007370200200041186a2001360200420121070c3b0b20004201370308200041106a2001ad220742c0b2cd3b7e20074280a4e8037e7c42c0f9f886017c370300420021070c3a0b024020022d000120022d000041004772450d0020004200370308200041186a4102360200420121070c3a0b41c99fc500ad4280808080900184100122022900002107200229000821052002102941a88dc700ad4280808080b001841001220229000021062002290008211920021029200320193701f802200320063701f002200320053701e802200320073701e002200341e0026aad428080808080048410040c350b200141086a2802002108200141046a28020021090240024020022d00000d0020022d000141ff01714101470d002001410c6a2802002101200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d0000211f200241046a2d0000211e200241026a2f0100212020032002411a6a2901003703b8052003200a3a00b7052003200b3a00b6052003200c3b01b4052003200d3a00b3052003200e3a00b2052003200f3b01b005200320103a00af05200320113a00ae05200320123b01ac05200320133a00ab05200320143a00aa05200320153b01a805200320163a00a705200320173a00a605200320183b01a4052003201f3a00a3052003201e3a00a205200320203b01a005200320013602a803200320083602a403200320093602a003200341a0046a200341a0056a200341a0036a10dc0520032d00a00422024104460d3620032902a404210720032f00a10420032d00a3044110747241087421030c010b410221024100210302402008450d00200910290b0b200042003703082000411c6a2007370200200041186a2003200272360200420121070c380b200141086a2802002108200141046a28020021090240024020022d00004101470d002001410c6a280200210a200241236a2d0000210b200241216a2f0000210c2002411f6a2d0000210d2002411d6a2f0000210e2002410f6a2d0000210f2002410d6a2f000021102002410b6a2d00002111200241096a2f00002112200241076a2d00002113200241056a2f00002114200241246a3502002106200241206a3100002119200241116a2900002107200241106a2d000021152002410c6a2d00002116200241086a2d00002117200241046a2d000021012003200241196a28000036029805200320073703900520014101470d00200320163a00e702200320173a00e302200320153a00eb02200320032902940522053d01f002200320054238883c00f702200320054230883c00f602200320054220883d01f402200320054218883c00f302200320054210883c00f2022003201220114110747222023b01e402200320024110763a00e6022003201420134110747222023b01e002200320024110763a00e202200320073d01ec02200320074218883c00ef0220032010200f4110747222023b01e802200320024110763a00ea0220032007a74110763a00ee0220032019421886200e200d41107472ad42ffffff078384200c200b41107472ad42ffffff07834220868420064238868422073701f802200341b8056a2007370300200341a0056a41106a20032901f002370300200341a0056a41086a20032901e802370300200320032901e0023703a0052003200a3602a803200320083602a403200320093602a003200341a0046a200341a0056a200341a0036a10dc0520032d00a00422024104460d3520032902a404210720032f00a10420032d00a3044110747241087421030c010b410221024100210302402008450d00200910290b0b200042003703082000411c6a2007370200200041186a2003200272360200420121070c370b200141086a2802002108200141046a28020021090240024020022d00000d0020022d000141ff01714101470d002001410c6a2802002101200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d0000211f200241046a2d0000211e200241026a2f0100212020032002411a6a2901003703b8052003200a3a00b7052003200b3a00b6052003200c3b01b4052003200d3a00b3052003200e3a00b2052003200f3b01b005200320103a00af05200320113a00ae05200320123b01ac05200320133a00ab05200320143a00aa05200320153b01a805200320163a00a705200320173a00a605200320183b01a4052003201f3a00a3052003201e3a00a205200320203b01a005200320013602a803200320083602a403200320093602a003200341a0046a200341a0056a200341a0036a10dd0520032d00a00422024104460d3420032902a404210720032f00a10420032d00a3044110747241087421030c010b410221024100210302402008450d00200910290b0b200042003703082000411c6a2007370200200041186a2003200272360200420121070c360b200141086a2802002108200141046a28020021090240024020022d00004101470d002001410c6a280200210a200241236a2d0000210b200241216a2f0000210c2002411f6a2d0000210d2002411d6a2f0000210e2002410f6a2d0000210f2002410d6a2f000021102002410b6a2d00002111200241096a2f00002112200241076a2d00002113200241056a2f00002114200241246a3502002106200241206a3100002119200241116a2900002107200241106a2d000021152002410c6a2d00002116200241086a2d00002117200241046a2d000021012003200241196a28000036029805200320073703900520014101470d00200320163a00e702200320173a00e302200320153a00eb02200320032902940522053d01f002200320054238883c00f702200320054230883c00f602200320054220883d01f402200320054218883c00f302200320054210883c00f2022003201220114110747222023b01e402200320024110763a00e6022003201420134110747222023b01e002200320024110763a00e202200320073d01ec02200320074218883c00ef0220032010200f4110747222023b01e802200320024110763a00ea0220032007a74110763a00ee0220032019421886200e200d41107472ad42ffffff078384200c200b41107472ad42ffffff07834220868420064238868422073701f802200341b8056a2007370300200341a0056a41106a20032901f002370300200341a0056a41086a20032901e802370300200320032901e0023703a0052003200a3602a803200320083602a403200320093602a003200341a0046a200341a0056a200341a0036a10dd0520032d00a00422024104460d3320032902a404210720032f00a10420032d00a3044110747241087421030c010b410221024100210302402008450d00200910290b0b200042003703082000411c6a2007370200200041186a2003200272360200420121070c350b200141246a280200211f200341c0026a41186a200141196a290000370300200341c0026a41106a200141116a290000370300200341c0026a41086a200141096a290000370300200320012900013703c0022002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d002003200737029405200320013a009305200320083a009205200320093b019005410121020c010b20022d000121022003200737039005200241ff017141014721020b200320073701f802200320013a00f702200320083a00f602200320093b01f4022003200a3a00f3022003200b3a00f2022003200c3b01f0022003200d3a00ef022003200e3a00ee022003200f3b01ec02200320103a00eb02200320113a00ea02200320123b01e802200320133a00e702200320143a00e602200320153b01e402200320163a00e302200320173a00e202200320183b01e002024020020d0020034180036a41186a200341e0026a41186a29010037030020034180036a41106a200341e0026a41106a29010037030020034180036a41086a200341e0026a41086a290100370300200320032901e00237038003200341a4046a41003b0100200341003602a004200341a0056a41186a200341c0026a41186a290300370300200341a0056a41106a200341c0026a41106a290300370300200341a0056a41086a200341c0026a41086a290300370300200320032903c0023703a005200341a0036a200341a0056a10de0520034198026a20032802a003220120032802a803200341a0046a4106410010c70102402003280298020d00411310d5042102200341d0016a411310d60420032903d00121070c1d0b2003200328029c022202410620024106491b22023602a4052003200341a0046a3602a005200341003a00e0020240024002402002450d0020032002417f6a3602a4052003200341a0046a4101723602a00520032d00a004220241014b0d0020020e020102010b41c6a3c700ad42808080809005841008411310d5042102200341d8016a411310d60420032802dc01210820032802d80121090c1d0b411310d504210220034190026a411310d604200328029402210820032802900221090c1c0b20034188026a200341a0056a10c8012003280288020d1a200328028c022102024020032802a403450d00200110290b0240024002402002201f4b0d00200341a0036a200341c0026a10d804200341a0056a20032802a003220120032802a80310d90420032802a40321020240024020032d00a00522084102460d00200341e8056a2903002105200341e0056a2903002106200341d8056a2802002122200341d4056a2802002123200341d0056a2802002109200341c8056a280200210a200341c4056a2802002124200341b9056a2900002107200341b8056a2d0000210b200341b7056a2d0000210c200341b5056a2f0000210d200341b4056a2d0000210e200341b3056a2d0000210f200341b1056a2f00002110200341b0056a2d00002111200341af056a2d00002112200341ad056a2f00002113200341ac056a2d00002114200341ab056a2d00002115200341a9056a2f00002116200341a8056a2d0000211720032d00a705211820032f00a505211f20032d00a405211e20032d00a305212020032f00a105212102402002450d00200110290b2008450d010240200a450d00202410290b200320073703b8032003200b3a00b7032003200c3a00b6032003200d3b01b4032003200e3a00b3032003200f3a00b203200320103b01b003200320113a00af03200320123a00ae03200320133b01ac03200320143a00ab03200320153a00aa03200320163b01a803200320173a00a703200320183a00a6032003201f3b01a4032003201e3a00a303200320203a00a203200320213b01a003200341a0056a41186a4200370300200341a0056a41106a22084200370300200341a0056a41086a22024200370300200342003703a00541b3e6ca00ad4280808080e000841001220129000021072002200141086a290000370300200320073703a0052001102941c9e6ca00ad4280808080e00084100122012900002107200341e0026a41086a220a200141086a290000370300200320073703e00220011029200820032903e0022207370300200341a0046a41086a2002290300370300200341a0046a41106a2007370300200341a0046a41186a200a290300370300200320032903a0053703a004200341f8016a200341a0046a412010fc0120032802fc01410020032802f8011b2202200941808407410020034180036a200341a0036a412010e7071b6a4180ce186a490d0302402023450d00200220224d0d050b200341a0056a200341a0036a20034180036a20062005410010e903200341a0056a200341c0026a10d80420033502a80542208620032802a0052202ad841004024020032802a405450d00200210290b200341a0056a41086a410f3a0000200341c9056a20032903a003370000200341b1056a200341c0026a41086a290300370000200341b9056a200341c0026a41106a290300370000200341c1056a200341c0026a41186a290300370000200341d1056a200341a0036a41086a290300370000200341d9056a200341a0036a41106a290300370000200341e1056a200341a0036a41186a290300370000200341093a00a005200341a0056a41096a20032903c00237000020034190066a200637030020034198066a200537030020034181066a20034180036a41186a290300370000200341f9056a20034180036a41106a290300370000200341f1056a20034180036a41086a290300370000200341e9056a200329038003370000200341a0056a10cb010c360b2002450d00200110290b411310d5042102200341e8016a411310d60420032802e801210820032802ec012101410321030c200b412610d5042102200341e0016a412610d60420032802e001210820032802e4012101410321030c1f0b41112102200341113a00a005200341a0056a21010c1a0b41122102200341123a00a005200341a0056a21010c190b410221030c1c0b20034180036a41186a200141196a29000037030020034190036a200141116a29000037030020034188036a200141096a29000037030020032001290001370380032002411a6a2901002107024020022d0000450d00200241166a2f01002101200241186a2d00002108200241196a2d000021022003200737029405200320023a009305200320083a009205200320013b0190050c170b20022d000121022003200737039005200241ff01714101470d16200341c0026a20034180036a10df05200341a0056a20032802c002220920032802c802220a10e00520032d00a0052102200341a0046a200341a0056a41017241ef0010e4071a0240024020024102470d00200341b0036a4200370300200341b8036a4200370300200341c0036a4200370300200341c8036a4200370300200341d0036a4200370300200341d8036a420037030041002102200341e0036a4100360200200341083602a403200341a0036a41086a4200370300200341003a00a0030c010b200320023a00a003200341a0036a410172200341a0046a41ef0010e4071a200241014621020b200341a0056a41186a4200370300200341a0056a41106a220b4200370300200341a0056a41086a22014200370300200342003703a00541b3e6ca00ad4280808080e000841001220829000021072001200841086a290000370300200320073703a0052008102941c9e6ca00ad4280808080e00084100122082900002107200341e0026a41086a220c200841086a290000370300200320073703e00220081029200b20032903e0022207370300200341a0046a41086a2001290300370300200341a0046a41106a2007370300200341a0046a41186a200c290300370300200320032903a0053703a004200341a0026a200341a0046a412010fc010240200341f8036a200341d0036a20021b220128021020032802a402410020032802a0021b4b0d0020014200370300200141106a4100360200200141086a42003703000b024002402002450d00200341d0036a2903002106200341c8036a29030021190c010b200341d8036a290300210620032903d0032119200341ac036a28020041306c2201450d0020032802a40341206a21020340200241706a22082903002105200841086a29030021070240200241686a2d00004101470d00427f2007200241086a2903007c200520022903007c221a2005542208ad7c22052008200520075420052007511b22081b2107427f201a20081b21050b200620072005201954200720065420072006511b22081b21062019200520081b2119200241306a2102200141506a22010d000b0b200341a0056a200341a0036a41f00010e4071a0240024020032d00a00522024102470d00200aad4220862009ad8410040c010b200341a0046a200341a0056a10a105200aad4220862009ad8420033502a80442208620032802a0042201ad841003024020032802a404450d00200110290b20020d00200341a8056a2802002202450d00200241306c450d0020032802a40510290b024020032802c402450d00200910290b02402019200684500d00200342e4cab5fbb6ccdcb0e3003703a005200341a0056a20034180036a20192006410210aa020c300b200342e4cab5fbb6ccdcb0e3003703a005200341a0056a20034180036a10ac020c2f0b20022d00000d0c20022d000141ff01714101470d0c200141196a2900002105200141186a2d00002109200141176a2d0000210a200141156a2f0000210b200141146a2d0000210c200141136a2d0000210d200141116a2f0000210e200141106a2d0000210f2001410f6a2d000021102001410d6a2f000021112001410c6a2d000021122001410b6a2d00002113200141096a2f00002114200141086a2d00002115200141076a2d00002116200141056a2f00002117200141046a2d00002118200141036a2d0000211f20012f00012101200241196a3100002106200241186a3100002119200241166a330100211a200241156a310000211b200241146a310000211c200241126a330100211d200241116a2d00002108200241106a2d0000211e2002410e6a2f010021202002410d6a2d000021212002410c6a2d000021242002410a6a2f01002123200241096a2d00002122200241086a2d00002125200241066a2f01002126200241056a2d00002127200241046a2d00002128200241026a2f01002129200341be036a2002411a6a29010022074230883c0000200341ae036a201e3a0000200341aa036a20243a000020032007a722023b01b803200341ba036a20024110763a0000200320203b01ac03200320233b01a803200320253a00a603200320263b01a403200320283a00a203200320293b01a003200320083a00af03200320213a00ab03200320223a00a703200320273a00a303200320074220883d01bc03200320074238883c00bf03200320074218883c00bb032003201d201c42108684201b42188684201a422086842019423086842006423886843703b003200341a0046a200341a0036a10d805200341a0056a20032802a004220820032802a804221e10d9050240024020032d00a0054102460d00200320032900a1053701e0022003200341b9056a2900003701f8022003200341a9056a2900003701e8022003200341b1056a2900003701f00220014180fe037141087621020c010b20014180fe03714108762102200341a0036a10a7020b200320153a00e702200320163a00e602200320173b01e402200320183a00e3022003201f3a00e20220032002410874200141ff0171723b01e0022003200f3a00ef02200320103a00ee02200320113b01ec02200320123a00eb02200320133a00ea02200320143b01e802200320093a00f7022003200a3a00f6022003200b3b01f4022003200c3a00f3022003200d3a00f2022003200e3b01f002200320053701f802200341b8056a2005370300200341b0056a20032901f002370300200341a0056a41086a20032901e802370300200320032901e0023703a005410110272202450d2f200241003a0000200241014121102b2202450d2f200220032903a005370001200241196a200341b8056a290300370000200241116a200341b0056a290300370000200241096a200341a8056a290300370000201ead4220862008ad842002ad428080808090048410032002102920032802a404450d2e200810290c2e0b0240024002400240024020022d00000d0020022d000141ff01714101460d010b200341023a00a0030c010b200141046a2802002101200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211f20032002411a6a2901003703b805200320083a00b705200320093a00b6052003200a3b01b4052003200b3a00b3052003200c3a00b2052003200d3b01b0052003200e3a00af052003200f3a00ae05200320103b01ac05200320113a00ab05200320123a00aa05200320133b01a805200320143a00a705200320153a00a605200320163b01a405200320173a00a305200320183a00a2052003201f3b01a005200341a0036a200341a0056a2001410010e10520032d00a0034104460d0120032902a40321070b20032802a00321032000411c6a2007370200200041186a2003360200420121070c010b420021070b200042003703080c310b200141246a2802002108200341a0036a41186a200141196a290000370300200341a0036a41106a200141116a290000370300200341a0036a41086a200141096a290000370300200320012900013703a0030240024020022d00000d0020022d000141ff01714101470d00200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211f20032002411a6a2901003703b805200320013a00b705200320093a00b6052003200a3b01b4052003200b3a00b3052003200c3a00b2052003200d3b01b0052003200e3a00af052003200f3a00ae05200320103b01ac05200320113a00ab05200320123a00aa05200320133b01a805200320143a00a705200320153a00a605200320163b01a405200320173a00a305200320183a00a2052003201f3b01a005200341a0046a200341a0036a2008200341a0036a200341a0056a412010e70741004710e10520032d00a00422024104460d2e20032902a404210720032f00a10420032d00a3044110747241087421030c010b41022102410021030b200042003703082000411c6a2007370200200041186a2003200272360200420121070c300b200141306a2903002107200141286a2903002105200141216a2d00002108200341a0046a41186a200141196a290000370300200341a0046a41106a200141116a290000370300200341a0046a41086a200141096a290000370300200320012900013703a0044102210120022d00000d1020022d000141ff01714101470d102002411a6a2901002106200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a00e702200320143a00e602200320153b01e402200320163a00e302200320173a00e202200320183b01e0022003200e3a00ef022003200f3a00ee02200320103b01ec02200320113a00eb02200320123a00ea02200320133b01e802200320013a00f702200320093a00f6022003200a3b01f4022003200b3a00f3022003200c3a00f2022003200d3b01f002200320063701f802200341a0036a41186a2006370300200341a0036a41106a20032901f002370300200341a0036a41086a20032901e802370300200320032901e0023703a003200341a0056a200341a0036a10d20520032d00a00522024102460d0a20024101470d0a200341a0056a41186a2d00002102200341b7056a2d00002101200341b5056a2f00002109200341b4056a2d0000210a200341b3056a2d0000210b200341b1056a2f0000210c200341a0056a41106a2d0000210d200341af056a2d0000210e200341ad056a2f0000210f200341a0056a410c6a2d00002110200341ab056a2d00002111200341a9056a2f00002112200341a0056a41086a2d0000211320032d00a705211420032f00a505211520032d00a405211620032d00a305211720032d00a205211820032d00a105211f2003200341b9056a2900003703b803200320023a00b703200320013a00b603200320093b01b4032003200a3a00b3032003200b3a00b2032003200c3b01b0032003200d3a00af032003200e3a00ae032003200f3b01ac03200320103a00ab03200320113a00aa03200320123b01a803200320133a00a703200320143a00a603200320153b01a403200320163a00a303200320173a00a203200320183a00a1032003201f3a00a003200341a0056a41186a200341a0046a41186a290300370300200341a0056a41106a200341a0046a41106a290300370300200341a0056a41086a200341a0046a41086a290300370300200320032903a0043703a00520034180036a200341a0036a200341a0056a20082005200710da05200328028403210102402003280280034101470d0020034180036a41086a280200210920034180036a410c6a280200210a2001411876210320014110762108200141087621020c120b20004201370308200041106a2001ad220742c0b2cd3b7e20074280a4e8037e7c4280f19e9b027c370300420021070c2f0b4102210120022d00000d0d20022d000141ff01714101470d0d2002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f010021172003200241096a2d00003a00e702200320133a00e602200320143b01e402200320153a00e302200320163a00e202200320173b01e0022003200d3a00ef022003200e3a00ee022003200f3b01ec02200320103a00eb02200320113a00ea02200320123b01e802200320013a00f702200320083a00f602200320093b01f4022003200a3a00f3022003200b3a00f2022003200c3b01f002200320073701f802200341a0036a41186a2007370300200341a0036a41106a20032901f002370300200341a0036a41086a20032901e802370300200320032901e0023703a003200341a0056a200341a0036a10d20520032d00a00522024102460d0a20024101470d0a200341a0056a41186a2d00002102200341b7056a2d00002101200341b5056a2f00002108200341b4056a2d00002109200341b3056a2d0000210a200341b1056a2f0000210b200341a0056a41106a2d0000210c200341af056a2d0000210d200341ad056a2f0000210e200341a0056a410c6a2d0000210f200341ab056a2d00002110200341a9056a2f00002111200341a0056a41086a2d0000211220032d00a705211320032f00a505211420032d00a405211520032d00a305211620032d00a205211720032d00a10521182003200341b9056a2900003703b805200320023a00b705200320013a00b605200320083b01b405200320093a00b3052003200a3a00b2052003200b3b01b0052003200c3a00af052003200d3a00ae052003200e3b01ac052003200f3a00ab05200320103a00aa05200320113b01a805200320123a00a705200320133a00a605200320143b01a405200320153a00a305200320163a00a205200320173a00a105200320183a00a005200341a0036a200341a0056a10db0520032802a4032101024020032802a0034101470d00200341a0036a41086a2802002109200341a0036a410c6a280200210a2001411876210320014110762108200141087621020c0f0b20004201370308200041106a2001ad220742c0b2cd3b7e20074280a4e8037e7c42c0899a96017c370300420021070c2e0b20022d00000d0a20022d000141ff01714101470d0a200141046a28020021182002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f010021172003200241096a2d00003a00e702200320133a00e602200320143b01e402200320153a00e302200320163a00e202200320173b01e0022003200d3a00ef022003200e3a00ee022003200f3b01ec02200320103a00eb02200320113a00ea02200320123b01e802200320013a00f702200320083a00f602200320093b01f4022003200a3a00f3022003200b3a00f2022003200c3b01f002200320073701f802200341a0036a41186a2007370300200341a0036a41106a20032901f002370300200341a0036a41086a20032901e802370300200320032901e0023703a003200341a0056a200341a0036a10d2050240024020032d00a00522024102460d0020024101460d010b410310d5042102200341b8026a410310d604200320023a00820320034183223b018003200320032903b802370284030c0c0b200341a0056a41186a2d00002102200341b7056a2d00002101200341b5056a2f00002108200341b4056a2d00002109200341b3056a2d0000210a200341b1056a2f0000210b200341a0056a41106a2d0000210c200341af056a2d0000210d200341ad056a2f0000210e200341ac056a2d0000210f200341ab056a2d00002110200341a9056a2f00002111200341a0056a41086a2d0000211220032d00a705211320032f00a505211420032d00a405211520032d00a305211620032d00a205211720032d00a105211f2003200341b9056a2900003703b804200320023a00b704200320013a00b604200320083b01b404200320093a00b3042003200a3a00b2042003200b3b01b0042003200c3a00af042003200d3a00ae042003200e3b01ac042003200f3a00ab04200320103a00aa04200320113b01a804200320123a00a704200320133a00a604200320143b01a404200320153a00a304200320163a00a204200320173a00a1042003201f3a00a00420034180036a200341a0046a2018410010e10520032d0080034104460d290c0b0b200141246a2802002108200341a0036a41186a2209200141196a290000370300200341a0036a41106a220a200141116a290000370300200341a0036a41086a220b200141096a290000370300200320012900013703a003024002400240024020022d000120022d000041004772450d00200341023a00a0040c010b200341a0056a41186a2009290300370300200341a0056a41106a200a290300370300200341a0056a41086a200b290300370300200320032903a0033703a005200341a0046a200341a0056a200810da0420032d00a0044104460d0120032902a40421070b20032802a00421032000411c6a2007370200200041186a2003360200420121070c010b420021070b200042003703080c2c0b410110d5042109200341106a410110d60441032102411121082003280210210a200328021421030c2a0b410210d5042109200341206a410210d6044103210241112101410021082003280220210b2003280224210a0c250b200341023a00c0020c230b2008200a1041000b20004200370308200041186a4102360200420121070c270b20004200370308200041186a4102360200420121070c260b20004200370308200041186a4102360200420121070c250b41032101410310d5042108200341a8026a410310d6044111210220032802a802210920032802ac02210a0c060b41032101410310d5042108200341b0026a410310d6044111210220032802b002210920032802b402210a0c030b200341023a0080030b20032802800321022000411c6a200329028403370200200041186a200236020020004200370308420121070c210b0b200020033a001b200020083a001a200020023a001920004200370308200041206a200a3602002000411c6a2009360200200041186a20013a0000420121070c1f0b0b200041206a200a3602002000411c6a2009360200200020033a001b200020083a001a200020023a0019200041186a20013a000020004200370308420121070c1d0b200041186a410236020020004200370308420121070c1c0b200210d5042102200341f0016a20012d000010d60420032802f401210120032802f0012108410321030c030b41c6a3c700ad42808080809005841008411310d504210220034180026a411310d604200328028402210820032802800221090b2008ad4220862009ad8421070b024020032802a403450d00200110290b2007422088a721012007a72108410321030b20004200370308200041206a20013602002000411c6a2008360200200041186a200241ff017141107420037241802272360200420121070c170b200341a0056a41186a200341a0036a41186a290300370300200341a0056a41106a200341a0036a41106a290300370300200341a0056a41086a200341a0036a41086a290300370300200320032903a0033703a0054100210a200341a0056a2101410021080b0240200a200f470d00200341c0026a200a4101109e0120032802c402210f20032802c002210e0b200e20084105746a220241206a2002200a20086b41057410e5071a20022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a2900003700002003200a41016a22023602c802200341a0056a41186a4200370300200341a0056a41106a22094200370300200341a0056a41086a22014200370300200342003703a00541b3e6ca00ad4280808080e000841001220829000021072001200841086a290000370300200320073703a0052008102941c9e6ca00ad4280808080e00084100122082900002107200341e0026a41086a220a200841086a290000370300200320073703e00220081029200920032903e0022207370300200341a0046a41086a2001290300370300200341a0046a41106a2007370300200341a0046a41186a200a290300370300200320032903a0053703a004200341a0016a200341a0046a412010fc0120032802a401210920032802a001210a200341a0046a20034180036a10d7052002410574220b41047241046a2201417f4c0d0220033502a804210720032802a0042110200110272208450d002008200941c093066a41c09306200a1b2211360000200341043602a805200320013602a405200320083602a0052002200341a0056a10710240024020020d0020032802a805210120032802a405210920032802a005210d0c010b410020032802a80522016b210a20032802a005210d20032802a4052109200e210c0340200c210202402009200a6a411f4b0d00200141206a22082001490d042009410174220c2008200c20084b1b22084100480d04024002400240024020090d00024020080d004101210d0c020b20081027210d0c030b20092008470d010b200821090c020b200d20092008102b210d0b20082109200d450d150b200241206a210c200d20016a22082002290000370000200841186a200241186a290000370000200841106a200241106a290000370000200841086a200241086a290000370000200a41606a210a200141206a2101200b41606a220b0d000b200320093602a405200320013602a8052003200d3602a0050b20074220862010ad842001ad422086200dad84100302402009450d00200d10290b024020032802a404450d00201010290b0240200f41ffffff3f71450d00200e10290b200341a0056a41086a410a3a0000200341c9056a200329038003370000200341093a00a005200341a0056a41096a20032903a003370000200341b1056a200341a0036a41086a290300370000200341b9056a200341a0036a41106a290300370000200341c1056a200341a0036a41186a290300370000200341d1056a20034180036a41086a290300370000200341d9056a20034180036a41106a290300370000200341e1056a20034180036a41186a290300370000200341ec056a2011360200200341a0056a10cb0141c99fc500ad4280808080900184100122022900002107200229000821052002102941d892c700ad4280808080c001841001220229000021062002290008211920021029200320193701f802200320063701f002200320053701e802200320073701e002200341e0026aad428080808080048410040c110b1039000b1032000b1038000b410321010b20004200370308200041206a20083602002000411c6a2003360200200041186a200241ff017141107420017241802272360200420121070c100b200941ff01710d01200c200b490d010b41c99fc500ad4280808080900184100122022900002107200229000821052002102941d892c700ad4280808080c001841001220229000021062002290008211920021029200320193701f802200320063701f002200320053701e802200320073701e002200341a0056a200341e0026a10a30520032d00c00522024103460d0120032f01a005210120032d00a205210920032d00a305210a20032f01a405210b20032d00a605210c20032d00a705210e20032f01a805210f20032d00aa05211020032d00ab05211120032f01ac05211220032d00ae05211320032d00af05211420032f01b005211520032d00b205211620032d00b305211720032f01b405211820032d00b605211f20032d00b705211e200320032903b8053703b8032003201e3a00b7032003201f3a00b603200320183b01b403200320173a00b303200320163a00b203200320153b01b003200320143a00af03200320133a00ae03200320123b01ac03200320113a00ab03200320103a00aa032003200f3b01a8032003200e3a00a7032003200c3a00a6032003200b3b01a4032003200a3a00a303200320093a00a203200320013a00a00341082109200320014108763a00a103024002402002450d0020034180036a200341a0036a412010e707450d0641092109200341093a00a005200341a0056a21010c010b200341083a00a005200341a0056a21010b200910d504210220034188016a20012d000010d604200328028c01210120032802880121030c020b410221080c020b410210d504210220034180016a410210d604200328028401210120032802800121030b410321080b20004200370308200041206a20013602002000411c6a2003360200200041186a200241ff017141107420087241802272360200420121070c0a0b41c99fc500ad4280808080900184100122012900002107200129000821052001102941d892c700ad4280808080c001841001220129000021062001290008211920011029200320193701f802200320063701f002200320053701e802200320073701e002200341e0026aad4280808080800484100442002107200341a0056a41186a220b4200370300200341a0056a41106a22094200370300200341a0056a41086a22014200370300200342003703a00541b3e6ca00ad4280808080e000841001220a29000021052001200a41086a290000370300200320053703a005200a102941c9e6ca00ad4280808080e000841001220a2900002105200341e0026a41086a220c200a41086a290000370300200320053703e002200a1029200920032903e0022205370300200341a0046a41086a2001290300370300200341a0046a41106a2005370300200341a0046a41186a200c290300370300200320032903a0053703a00420034190016a200341a0046a412010fc01200328029401210a200328029001210c200b20034180036a41186a290300370300200920034180036a41106a290300370300200120034180036a41086a29030037030020032003290380033703a005200a4100200c1b20086a200341a0056a2002200d10a405200042003703080c090b411410d5042101200341c8006a20022d000010d604200328024c2108200328024821094103210a0c010b0b20004200370308200041206a20083602002000411c6a2009360200200041186a200141ff0171411074200a7241802272360200420121070c060b20032802c00221022000411c6a20032902c402370200200041186a200236020020004200370308420121070c050b20004200370308200041206a200a3602002000411c6a200b360200200041186a2008411874200941ff01714110747220014108744180fe037172200241ff017172360200420121070c040b42002107200042003703080c030b1030000b4102210241002101410021080b20004200370308200041206a20033602002000411c6a200a360200200041186a2001411874200941ff01714110747220084108744180fe037172200241ff017172360200420121070b20002007370300200424000bb26f08027f017e177f017e017f017e017f037e23004180076b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341bc046a4101360200200342013702ac0420034198e3ca003602a8042003410436028402200341cce3ca0036028002200320034180026a3602b804200341a8046a4180a6cc001040000b20012d000121042001411a6a2900002105200141196a2d00002106200141186a2d00002107200141166a2f00002108200141156a2d00002109200141146a2d0000210a200141126a2f0000210b200141116a2d0000210c200141106a2d0000210d2001410e6a2f0000210e2001410d6a2d0000210f2001410c6a2d000021102001410a6a2f00002111200141096a2d00002112200141086a2d00002113200141066a2f00002114200141056a2d00002115200141046a2d00002116200141026a2f000021172001412c6a2802002118200141286a2802002119200141246a280200211a2003200141306a2802002201360268024020022d000120022d0000410047720d000240201841e500490d0041002802d8a74c450d002003418c026a41013602002003410136028402200341b0e3c80036028002200320183602d8012003200341d8016a3602880241002802888040210141002802848040210241002802dca74c211b200341e8046a418003360200200341e0046a42de80808010370300200341dc046a41dde3c800360200200341d4046a4211370200200341d0046a41cce3c800360200200341c8046a4202370300200341b8046a4203370300200341b0046a4111360200200341c4046a20034180026a360200200341b4e3c8003602b404200341cce3c8003602ac04200341013602a80420024180a4c000201b410246221b1b200341a8046a20014198a4c000201b1b280210110200200328026821010b200341a8046a41186a4200370300200341a8046a41106a22024200370300200341a8046a41086a221b4200370300200342003703a8044193d4c800ad4280808080b002841001221c290000211d201b201c41086a2900003703002003201d3703a804201c102941f0edca00ad4280808080f000841001221c290000211d200341c8006a41086a221e201c41086a2900003703002003201d370348201c102920022003290348221d37030020034180026a41086a201b29030037030020034180026a41106a201d37030020034180026a41186a201e290300370300200320032903a80437038002200341a8046a20034180026a108d0220032802a804221b4101201b1b211c0240200120032902ac044200201b1b221d422088221fa7221b4f0d0041002802d8a74c4102490d002003418c026a410136020020034101360284022003201b3602d8012003200341d8016a360288022003200341e8006a3602800241002802888040210141002802848040211e41002802dca74c2120200341e8046a418903360200200341e0046a42de80808010370300200341dc046a41dde3c800360200200341d4046a4211370200200341d0046a41cce3c800360200200341c8046a4202370300200341b8046a4203370300200341b0046a4111360200200341c4046a20034180026a36020020034190d5c9003602b404200341cce3c8003602ac04200341023602a804201e4180a4c000202041024622201b200341a8046a20014198a4c00020201b2802101102000b201a201810bb05200341a8046a201a2018201c201b10e5062002280200210120032802ac04210220032802a804211b20032802b404221e200341bc046a280200201a201810ef060240200141ffffff3f71450d00201e10290b0240200241ffffff3f71450d00201b10290b02400240200441ff01710d00200341c8006a41186a4200370300200341c8006a41106a22064200370300200341c8006a41086a22024200370300200342003703484193d4c800ad4280808080b00284100122042900002105200341d8016a41086a2201200441086a290000370300200320053703d8012004102920022001290300370300200320032903d80137034841f8d7ca00ad4280808080d000841001220429000021052001200441086a290000370300200320053703d80120041029200620032903d801220537030020034180026a41086a200229030037030020034180026a41106a200537030020034180026a41186a2001290300370300200320032903483703800220034180026aad428080808080048410040c010b200320053703c004200320063a00bf04200320073a00be04200320083b01bc04200320093a00bb042003200a3a00ba042003200b3b01b8042003200c3a00b7042003200d3a00b6042003200e3b01b4042003200f3a00b304200320103a00b204200320113b01b004200320123a00af04200320133a00ae04200320143b01ac04200320153a00ab04200320163a00aa04200320173b01a804200341286a41186a4200370300200341286a41106a22064200370300200341286a41086a22024200370300200342003703284193d4c800ad4280808080b0028410012204290000210520034180026a41086a2201200441086a29000037030020032005370380022004102920022001290300370300200320032903800237032841f8d7ca00ad4280808080d000841001220429000021052001200441086a29000037030020032005370380022004102920062003290380022205370300200341c8006a41086a2002290300370300200341c8006a41106a2005370300200341c8006a41186a200129030037030020032003290328370348412010272201450d06200120032903a804370000200141186a200341a8046a41186a290300370000200141106a200341a8046a41106a290300370000200141086a200341a8046a41086a290300370000200341c8006aad42808080808004842001ad42808080808004841003200110290b201f42c0de810a7e2018ad42b0db067e7c21050240201941ffffff3f71450d00201a10290b200542809591c7397c21050240201d42ffffff3f83500d00201c10290b200041106a200537030020004201370308200042003703000c1b0b0240201941ffffff3f71450d00201a10290b200320032900e0063703b8012003200341e7066a2900003700bf01200041186a41023a000020004200370308200020032903b801370019200041206a20032900bf01370000200042013703000c1a0b200141086a2802002119200141046a280200211a20032002411a6a29010037039802410221012003200241026a2901003703800220032002410a6a290100370388022003200241126a29010037039002024002400240024020022d00014101470d0020022d000041ff01710d00200341b8016a41186a20034180026a41186a2218290300370300200341b8016a41106a20034180026a41106a2204290300370300200341b8016a41086a20034180026a41086a220629030037030020032003290380023703b801200341a8046a41186a4200370300200341a8046a41106a22074200370300200341a8046a41086a22014200370300200342003703a8044193d4c800ad4280808080b002841001220229000021052001200241086a290000370300200320053703a8042002102941f0edca00ad4280808080f00084100122022900002105200341c8006a41086a2208200241086a2900003703002003200537034820021029200720032903482205370300200620012903003703002004200537030020182008290300370300200320032903a80437038002200341a8046a20034180026a108d0220032902ac04420020032802a80422011b2205422088221da741057421022001410120011b22042101024002400340024020020d004100210241eeebca002118410921190c020b0240200341b8016a2001460d00200241606a21022001200341b8016a412010e7072118200141206a210120180d010b0b200341003602b004200342013703a804201a200341a8046a10bf0220032802b0042102024020032802ac04450d0020032802a80410290b200220194d0d014109210241e7d5c8002118411321190b41032101200542ffffff3f83500d02200410290c020b200341003602b004200342013703a804201a200341a8046a10bf0220032802ac042118200341e0066a41186a221920033502b00442208620032802a8042208ad841010220141186a290000370300200341e0066a41106a2206200141106a290000370300200341e0066a41086a2207200141086a290000370300200320012900003703e0062001102902402018450d00200810290b200341a8046a201a41a80210e4071a2003418d026a200341b8016a41086a29030037000020034195026a200341b8016a41106a2903003700002003419d026a200341b8016a41186a290300370000200341013a008402200320032903b80137008502200341013a008002200341d8016a200341a8046a20034180026a10c501200341c8006a41186a2019290300370300200341c8006a41106a2006290300370300200341c8006a41086a2007290300370300200320032903e006370348200341d8016a41186a2d0000211820032903e001211f20032903d8012121200320032900f1013703a8042003200341f8016a2800003600af040240024020214201510d00410421010c010b200320032800af043600af01200320032903a8043703a80141042101201f4202510d00200320032800af0136009f01200320032903a80137039801201821010b200341286a41086a2218200341c8006a41086a290300370300200341286a41106a2219200341c8006a41106a290300370300200341286a41186a2206200341c8006a41186a290300370300200320032903483703282003200329039801370388012003200328009f0136008f01200341053a00ac042003410a3a00a804200341b5046a2018290300370000200341bd046a2019290300370000200341c5046a2006290300370000200341d0046a20013a0000200320032903283700ad04200341cd046a20032f0095013b0000200341cf046a20034197016a2d00003a0000200341d1046a200329038801370000200341d8046a200328008f01360000200341f4046a200341e8006a41186a280200360200200341ec046a200341e8006a41106a290200370200200341e4046a200341e8006a41086a290200370200200341dc046a2003290268370200200341a8046a10cb01201fa70d024200211d0c030b0b201a10cc01201a1029200041206a20193602002000411c6a2018360200200020023a001a200041123a0019200041186a20013a000020004200370308200042013703000c1b0b427f2002ad42a01f7e201d42c0a9077e7c4280d8f1167c221d200341d8016a41106a2903007c221f201f201d541b211f4201211d0b0240200542ffffff3f83500d00200410290b201a1029200041106a201f3703002000201d370308200042003703000c190b2001410c6a2802002119200141046a28020021042003200141086a280200221a3602b4014102210120022d00000d1620022d00014101470d16200241196a2d00002101200241186a2d00002118200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a2901003703d001200320013a00cf01200320183a00ce01200320063b01cc01200320073a00cb01200320083a00ca01200320093b01c8012003200a3a00c7012003200b3a00c6012003200c3b01c4012003200d3a00c3012003200e3a00c2012003200f3b01c001200320103a00bf01200320113a00be01200320123b01bc01200320133a00bb01200320143a00ba01200320153b01b801200341a8046a41186a4200370300200341a8046a41106a22064200370300200341a8046a41086a22014200370300200342003703a8044193d4c800ad4280808080b002841001220229000021052001200241086a290000370300200320053703a8042002102941f0edca00ad4280808080f00084100122022900002105200341c8006a41086a2218200241086a290000370300200320053703482002102920062003290348220537030020034180026a41086a200129030037030020034180026a41106a200537030020034180026a41186a2018290300370300200320032903a80437038002200341a8046a20034180026a108d0220032902ac04420020032802a80422011b2205422088221da741057421022001410120011b220721010340024020020d004109211941eeebca002118410021020c160b0240200341b8016a2001460d00200241606a21022001200341b8016a412010e7072118200141206a210120180d010b0b200341003602b004200342013703a804201a200341a8046a10bf0220032802b0042118024020032802ac04450d0020032802a80410290b0240201820194d0d004113211941e7d5c8002118410921020c150b200341003602b004200342013703a804201a200341a8046a10bf0220032802ac042102200341e0066a41186a221920033502b00442208620032802a804220aad841010220141186a290000370300200341e0066a41106a2208200141106a290000370300200341e0066a41086a2209200141086a290000370300200320012900003703e0062001102902402002450d00200a10290b200341a8046a41186a2019290300370300200341a8046a41106a2008290300370300200341a8046a41086a2009290300370300200320032903e0063703a80420034180026a200341a8046a108107200341186a20032802800222022003280288024180a6cc004100410010c701200328021821010240200328028402450d00200210290b4101210220014101460d03024002400240024020044102490d00200341a8046a41186a22194200370300200341a8046a41106a22084200370300200341a8046a41086a22014200370300200342003703a8044193d4c800ad4280808080b0028410012202290000211f2001200241086a2900003703002003201f3703a80420021029419fdec900ad428080808090018410012202290000211f200341c8006a41086a2209200241086a2900003703002003201f3703482002102920062003290348370000200641086a200929030037000020034180026a41086a200129030037030020034180026a41106a200829030037030020034180026a41186a2019290300370300200320032903a80437038002200341a8046a20034180026a412010ce010240024020032802a80422020d0041002101200341003602702003420137036841012102410021190c010b200320032902ac04221f37026c20032002360268201f422088a72101201fa721190b200341286a41186a2208200341e0066a41186a290300370300200341286a41106a2209200341e0066a41106a290300370300200341286a41086a220a200341e0066a41086a290300370300200320032903e006370328024020012019470d00200341e8006a20014101109e0120032802682102200328027021010b200220014105746a22192003290328370000201941186a2008290300370000201941106a2009290300370000201941086a200a2903003700002003200141016a2208360270200328026c2119200841e4004b0d03200341286a41186a4200370300200341286a41106a220b4200370300200341286a41086a22094200370300200342003703284193d4c800ad4280808080b002841001220a290000211f200341d8016a41086a2201200a41086a2900003703002003201f3703d801200a102920092001290300370300200320032903d801370328419fdec900ad42808080809001841001220a290000211f2001200a41086a2900003703002003201f3703d801200a1029200b20032903d801221f370300200341c8006a41086a2009290300370300200341c8006a41106a201f370300200341c8006a41186a2001290300370300200320032903283703480240024020020d00200341c8006aad428080808080048410040c010b200341203602ac042003200341c8006a3602a80420022008200341a8046a10cf01201941ffffff3f71450d00200210290b200341c8006a41186a22094200370300200341c8006a41106a22194200370300200341c8006a41086a22024200370300200342003703484193d4c800ad4280808080b00284221f1001220a2900002121200341d8016a41086a2201200a41086a290000370300200320213703d801200a102920022001290300370300200320032903d80137034841a0b9ca00ad4280808080d0018422211001220a29000021222001200a41086a290000370300200320223703d801200a1029201920032903d8012222370300200341286a41086a220a2002290300370300200341286a41106a220b2022370300200341286a41186a220c200129030037030020032003290348370328200341106a200341286a412010fc012003280214210e2003280210210f20094200370300201942003703002002420037030020034200370348201f1001220d29000021222001200d41086a290000370300200320223703d801200d102920022001290300370300200320032903d80137034820211001220d29000021222001200d41086a290000370300200320223703d801200d1029201920032903d8012222370300200a2002290300370300200b2022370300200c200129030037030020032003290348370328200341086a200341286a412010fc012003280208210d200328020c211020094200370300201942003703002002420037030020034200370348201f10012209290000211f2001200941086a2900003703002003201f3703d8012009102920022001290300370300200320032903d801370348202110012209290000211f2001200941086a2900003703002003201f3703d80120091029201920032903d801221f370300200a2002290300370300200b201f370300200c2001290300370300200320032903483703282003201041016a4101200d1b3602a804200341286aad4280808080800484200341a8046aad4280808080c000841003200341a8046a201a41a80210e4071a20034180026a41186a200341e0066a41186a29030037030020034180026a41106a200341e0066a41106a29030037030020034180026a41086a200341e0066a41086a290300370300200320032903e00637038002200341d8016a20034180026a10810720032802d801210120033502e001211f20034201370380022003410036028802200341a8046a20034180026a10bf022003280284022102201f4220862001ad84200335028802422086200328028002221aad84100302402002450d00201a10290b024020032802dc01450d00200110290b200341a8046a10cc01200341a8046a41186a221a4200370300200341a8046a41106a22194200370300200341a8046a41086a22014200370300200342003703a80441b3e6ca00ad4280808080e0008410012202290000211f2001200241086a2900003703002003201f3703a8042002102941c9e6ca00ad4280808080e0008410012202290000211f200341c8006a41086a2209200241086a2900003703002003201f3703482002102920062003290348370000200641086a200929030037000020034180026a41086a2202200129030037030020034180026a41106a2206201929030037030020034180026a41186a2219201a290300370300200320032903a80437038002200320034180026a412010fc012003280204211a20032802002109412010272201450d08200120032903b801370000200141186a200341b8016a41186a290300370000200141106a200341b8016a41106a290300370000200141086a200341b8016a41086a290300370000200341c4046a4100360200200341b4046a4281808080103702002003201a41c093066a41c0930620091b3602c8044201211f200342013702bc04200320013602b004200320043602ac042003200e4100200f1b221a3602a8042019200341e0066a41186a2903003703002006200341e0066a41106a2903003703002002200341e0066a41086a290300370300200320032903e00637038002200341d8016a20034180026a10f00620032802d8012102200320032802e001360284022003200236028002200341a8046a20034180026a10bf05024020032802dc01450d00200210290b20011029200341b5046a200341b8016a41086a290300370000200341bd046a200341b8016a41106a290300370000200341c5046a200341b8016a41186a290300370000200341cd046a20032903e006370000200341d5046a200341e0066a41086a290300370000200341dd046a200341e0066a41106a290300370000200341e5046a200341e0066a41186a290300370000200341f4046a2004360200200341f0046a201a360200200341003a00ac042003410a3a00a804200320032903b8013700ad042018ad42f02e7e201d42b0db067e7c2008ad42b0901f7e7c4280aba186027c211d200341a8046a10cb01200542ffffff3f8350450d010c020b200341a8046a41186a22194200370300200341a8046a41106a22044200370300200341a8046a41086a22014200370300200342003703a8044193d4c800ad4280808080b0028410012202290000211f2001200241086a2900003703002003201f3703a8042002102941f0edca00ad4280808080f0008410012202290000211f200341c8006a41086a2208200241086a2900003703002003201f3703482002102920062003290348370000200641086a200829030037000020034180026a41086a200129030037030020034180026a41106a200429030037030020034180026a41186a2019290300370300200320032903a80437038002200341d8016a20034180026a108d020240024020032802d80122020d00410021010c010b20032902dc01221f422088a72101201f42ffffff3f83500d00200210290b200341a8046a201a41a80210e4071a2003418c026a200136020020034180026a41086a22014101360200200341003a008402200341013a008002200341d8016a200341a8046a20034180026a10c50120034180026a41186a200341e0066a41186a29030037030020034180026a41106a200341e0066a41106a2903003703002001200341e0066a41086a290300370300200320032903e00637038002200341d8016a41186a2d0000210220032903e001211f20032903d8012121200320032900f1013703a8042003200341f8016a2800003600af040240024020214201510d00410421010c010b200320032800af043600af01200320032903a8043703a80141042101201f4202510d00200320032800af0136009f01200320032903a80137039801200221010b200341c8006a41086a220220034180026a41086a290300370300200341c8006a41106a221a20034180026a41106a290300370300200341c8006a41186a221920034180026a41186a29030037030020032003290380023703482003200329039801370388012003200328009f0136008f01200341043a00ac042003410a3a00a804200341b5046a2002290300370000200341bd046a201a290300370000200341c5046a2019290300370000200341d0046a20013a0000200320032903483700ad04200341cd046a20032f0095013b0000200341cf046a20034197016a2d00003a0000200341d1046a200329038801370000200341d8046a200328008f01360000200341f4046a200341e8006a41186a280200360200200341ec046a200341e8006a41106a290200370200200341e4046a200341e8006a41086a290200370200200341dc046a2003290268370200200341a8046a10cb0102400240201fa70d004200211f0c010b427f2018ad42b8177e201d42e0b60d7e7c42c0e3d5257c221d200341d8016a41106a2903007c221f201f201d541b211d4201211f0b200542ffffff3f83500d010b200710290b20032802b4011029200041106a201d3703002000201f370308200042003703000c190b0240201941ffffff3f71450d00200210290b41102119418dd6c80021184107210241032101200542ffffff3f83500d170c150b200141216a2d00002115200141246a2802002114200341e0066a41186a200141196a290000370300200341e0066a41106a200141116a290000370300200341e0066a41086a200141096a290000370300200320012900013703e0062002411a6a2901002105200241196a2d00002118200241186a2d0000211a200241166a2f01002119200241156a2d00002104200241146a2d00002106200241126a2f01002107200241116a2d00002108200241106a2d000021092002410e6a2f0100210a2002410d6a2d0000210b2002410c6a2d0000210c2002410a6a2f0100210d200241096a2d0000210e200241086a2d0000210f200241066a2f01002110200241056a2d00002111200241046a2d00002112200241026a2f0100211341012101024020022d00000d0020022d000141014721010b2003200537039802200320183a0097022003201a3a009602200320193b019402200320043a009302200320063a009202200320073b019002200320083a008f02200320093a008e022003200a3b018c022003200b3a008b022003200c3a008a022003200d3b0188022003200e3a0087022003200f3a008602200320103b018402200320113a008302200320123a008202200320133b018002024020010d00200341d8016a41186a20034180026a41186a2218290300370300200341d8016a41106a20034180026a41106a221a290300370300200341d8016a41086a20034180026a41086a221929030037030020032003290380023703d801200341a8046a41186a4200370300200341a8046a41106a22044200370300200341a8046a41086a22014200370300200342003703a8044193d4c800ad4280808080b002841001220229000021052001200241086a290000370300200320053703a8042002102941f0edca00ad4280808080f00084100122022900002105200341c8006a41086a2206200241086a290000370300200320053703482002102920042003290348220537030020192001290300370300201a200537030020182006290300370300200320032903a80437038002200341a8046a20034180026a108d0220032902ac04420020032802a80422011b2205422088221fa741057421022001410120011b220421010340024020020d004109210141eeebca002102410021180c140b0240200341d8016a2001460d00200241606a21022001200341d8016a412010e7072118200141206a210120180d010b0b200341b8016a200341e0066a108207200341a8046a20032802b801220220032802c00110c10520032802bc0121010240024020032802b0042206450d00200341c8046a2802002118200341c4046a2802002108200341c0046a280200210b200341bc046a280200210a200341b8046a280200210720032802b404210920032903a804211d02402001450d00200210290b2003419c026a200836020020034198026a200b36020020034190026a20073602002003418c026a2009360200200320183602a0022003200a3602940220032006360288022003201d370380022014201da7460d01410a210141c4d6c8002102410321180c130b02402001450d00200210290b410f210141ced6c8002102410221180c130b41002102410021184100210c02402007450d002007410574211a410021182006210102400340200341d8016a2001460d0120182001200341d8016a412010e70722194100476a21182019450d01200141206a2101201a41606a221a0d000b4100210c0c010b4101210c0b4100210102402008450d002008410574211a41002102200a210102400340200341d8016a2001460d0120022001200341d8016a412010e70722194100476a21022019450d01200141206a2101201a41606a221a0d000b410021010c010b410121010b02400240201541ff01710d002001450d010c120b200c0d11200341286a41186a221a200341d8016a41186a290300370300200341286a41106a2219200341d8016a41106a290300370300200341286a41086a2208200341d8016a41086a290300370300200320032903d801370328024020072009470d0020034188026a20094101109e01200328029002210720032802880221060b200620074105746a22182003290328370000201841186a201a290300370000201841106a2019290300370000201841086a20082903003700002003200741016a221936029002200328029c02211a2001450d10201a20024d0d062003280294022218201a417f6a221a4105746a2201290000211d2001290008212120012900102122200141186a29000021232003201a36029c02201820024105746a220141186a202337000020012022370010200120213700082001201d3700000c100b200341c8006a41186a2202200341d8016a41186a290300370300200341c8006a41106a221a200341d8016a41106a290300370300200341c8006a41086a2219200341d8016a41086a290300370300200320032903d80137034802402008200b470d0020034194026a200b4101109e01200328029c022108200328029402210a0b200a20084105746a22012003290348370000200141186a2002290300370000200141106a201a290300370000200141086a20192903003700002003200328029c0241016a221a36029c022003280290022119200c450d0f201920184d0d0620032802880222022019417f6a22194105746a2201290000211d2001290008212120012900102122200141186a29000021232003201936029002200220184105746a220141186a202337000020012022370010200120213700082001201d3700000c0f0b4102211a0c120b200141286a280200211a200141306a2903002105200141246a2802002118200341b8016a41186a200141196a290000370300200341c8016a200141116a290000370300200341c0016a200141096a290000370300200320012900013703b8014102210120022d00000d0a20022d00014101470d0a20034180026a200341b8016a108207200341a8046a200328028002220220032802880210c10520032802840221010240024020032802b0042206450d00200341c8046a280200210c200341c4046a2802002104200341c0046a2802002107200341bc046a280200210a200341b8046a280200211920032802b404210820032903a804211d02402001450d00200210290b41122102410321012018201da7460d01410a211841c4d6c80021044103211a0c0a0b02402001450d00200210290b410f211841ced6c80021044102211a41122102410321010c0c0b201d422088a7210d200341a8046a41186a4200370300200341a8046a41106a220b4200370300200341a8046a41086a22184200370300200342003703a8044193d4c800ad4280808080b0028410012209290000211f2018200941086a2900003703002003201f3703a8042009102941f0edca00ad4280808080f0008410012209290000211f200341c8006a41086a220e200941086a2900003703002003201f37034820091029200b2003290348221f37030020034180026a41086a201829030037030020034180026a41106a201f37030020034180026a41186a200e290300370300200320032903a80437038002200341d8016a20034180026a108d020240024020032802d80122180d00410021090c010b20032902dc01221f422088a72109201f42ffffff3f83500d00201810290b0240024002402019200d4f220e0d004100200920046b2218201820094b1b200d490d00200341a8046a41186a22104200370300200341a8046a41106a2211420037030041082118200341a8046a41086a220e4200370300200342003703a80441b3e6ca00ad4280808080e000841001220f290000211f200e200f41086a2900003703002003201f3703a804200f102941c9e6ca00ad4280808080e000841001220f290000211f200341c8006a41086a2212200f41086a2900003703002003201f370348200f1029200b2003290348370000200b41086a201229030037000020034180026a41086a200e29030037030020034180026a41106a201129030037030020034180026a41186a2010290300370300200320032903a80437038002200341206a20034180026a412010fc012003280224410020032802201b200c4f0d01419dd6c80021044106211a0c0b0b200341a8046a200341b8016a201a200510830720032802a8044101470d01200341b4046a28020021180c090b200341c8006a41186a220e4200370300200341c8006a41106a22184200370300200341c8006a41086a22014200370300200342003703484193d4c800ad4280808080b002841001220b290000211f200341d8016a41086a2202200b41086a2900003703002003201f3703d801200b102920012002290300370300200320032903d80137034841f8d7ca00ad4280808080d000841001220b290000211f2002200b41086a2900003703002003201f3703d801200b1029201820032903d801221f370300200341286a41086a2001290300370300200341286a41106a201f370300200341286a41186a200229030037030020032003290348370328200341a8046a200341286a412010cd0120032d00a8042102200e200341c1046a2900003703002018200341b9046a2900003703002001200341b1046a290000370300200320032900a904370348024020024101460d002009200420196a6b21010c070b20034180026a41186a200341c8006a41186a290300221f37030020034180026a41106a200341c8006a41106a290300222137030020034180026a41086a2001290300222237030020032003290348222337038002200341a8046a41186a201f370300200341a8046a41106a2021370300200341a8046a41086a2022370300200320233703a804201941057421022006210102400340024020020d004100210b0c020b4101210b200341a8046a2001460d01200241606a21022001200341a8046a412010e7072118200141206a210120180d000b0b2009200420196a6b2101200b450d06200120196a2101200421020c070b200341d8066a350200210520034180026a200341a8046a41086a41a80210e4071a200341f4016a2004360200200341d8016a41186a2007360200200341d8016a41106a2019360200200341e4016a20083602002003200c3602f8012003200a3602ec01200320063602e0012003201d3703d801200341e0066a41186a200341b8016a41186a290300370300200341e0066a41106a200341b8016a41106a290300370300200341e0066a41086a200341b8016a41086a290300370300200320032903b8013703e006200341a8046a20034180026a41a80210e4071a200542c03e7e2009ad4290a10f7e7c42c0fa9dc3007c2105200e2009200341d8016a200341e0066a200341a8046a108407211d0c090b1039000b4111211941ddd6c80021180c100b1030000b2002201a103e000b20182019103e000b200120046a2102201921010b200341a8046a200341b8016a201a2005108307024020032802a8044101460d00200341d8066a350200210520034180026a200341a8046a41086a41a80210e4071a200341b5046a200341b8016a41086a2218290300370000200341bd046a200341b8016a41106a221a290300370000200341c5046a200341b8016a41186a220b290300370000200341d4046a2002360200200341d0046a2001360200200341063a00ac042003410a3a00a804200320032903b8013700ad04200341a8046a10cb01200341f4016a2004360200200341d8016a41186a2007360200200341d8016a41106a2019360200200341e4016a20083602002003200c3602f8012003200a3602ec01200320063602e0012003201d3703d801200341e0066a41186a200b290300370300200341e0066a41106a201a290300370300200341e0066a41086a2018290300370300200320032903b8013703e006200341a8046a20034180026a41a80210e4071a200542c03e7e2009ad4290a10f7e7c4280eb93cf007c21052001200d4f2009200341d8016a200341e0066a200341a8046a108407211d0c030b200341b4046a28020021180b20032802b004210420032d00af04211920032d00ae04211a20032d00ad04210220032d00ac0421010b0240200841ffffff3f71450d00200610290b200741ffffff3f71450d02200a10290c020b20004201370308200041106a427f2005201d7c221d201d2005541b370300420021050c020b0b200020193a001b2000201a3a001a200020023a001920004200370308200041206a20183602002000411c6a2004360200200041186a20013a0000420121050b200020053703000c090b200341cd046a20032903e006370000200341b5046a200341d8016a41086a290300370000200341bd046a200341d8016a41106a290300370000200341c5046a200341d8016a41186a290300370000200341d5046a200341e0066a41086a290300370000200341dd046a200341e0066a41106a290300370000200341e5046a200341e0066a41186a290300370000200341013a00ac042003410a3a00a804200320032903d8013700ad04200341f4046a201a360200200341f0046a2019360200200341ed046a20153a0000200341a8046a10cb01200341a8046a41206a20034180026a41206a280200360200200341a8046a41186a20034180026a41186a290300370300200341a8046a41106a20034180026a41106a290300370300200341a8046a41086a20034180026a41086a29030037030020032003290380023703a804200341b8016a200341e0066a10820720032802b8012101200320032802c00136024c20032001360248200341a8046a200341c8006a10bf05024020032802bc01450d00200110290b0240200341b4046a28020041ffffff3f71450d0020032802b00410290b0240200341c0046a28020041ffffff3f71450d0020032802bc0410290b201f42a0c21e7e4280aaead5007c211d0240200542ffffff3f83500d00200410290b200041106a201d37030020004201370308200042003703000c080b410d210141b7d6c8002102410421180b0240200941ffffff3f71450d00200610290b200b41ffffff3f71450d00200a10290b4103211a200542ffffff3f83500d00200410290b200041206a20013602002000411c6a2002360200200020183a001a200041123a0019200041186a201a3a000020004200370308200042013703000c040b41032101200542ffffff3f83500d020b200710290c010b0b201a10cc01201a1029200041206a20193602002000411c6a2018360200200041003a001b200020023a001a200041123a0019200041186a20013a000020004200370308200042013703000b20034180076a24000bf61407157f017e017f017e017f017e017f230041306b220224000240024020014115490d00024002402001410176220341ffffff3f712003470d0020034105742204417f4c0d000240200410272205450d002002410036020820024204370300200041606a2106200041a07f6a210741042108410021094100210a2001210b0340200b210c4100210b4101210d0240200c417f6a220e450d000240024002400240024002402000200e4105746a200c410574220f20006a41406a412010e7074100480d004102200c6b210e2007200f6a21034101210d03400240200e200d6a4101470d004100210b200c210d0c080b200d41016a210d200341206a2003412010e7072110200341606a21032010417f4a0d000b200c200d6b210e0c010b2007200f6a2103024003400240200e4101470d004100210e0c020b200e417f6a210e200341206a2003412010e7072110200341606a210320104100480d000b0b200c200e490d01200c20014b0d02200c200e6b220d4101762211450d002006200f6a21032000200e4105746a21100340200241106a41186a220f201041186a2212290000370300200241106a41106a2213201041106a2214290000370300200241106a41086a2215201041086a221629000037030020022010290000370310200341086a220b2900002117200341106a22182900002119200341186a221a290000211b201020032900003700002012201b3700002014201937000020162017370000201a200f29030037000020182013290300370000200b201529030037000020032002290310370000200341606a2103201041206a21102011417f6a22110d000b0b0240200e0d00200e210b0c050b0240200d41094d0d00200e210b0c050b200c20014b0d02200c200e6b21112000200e4105746a210f0340200c200e417f6a220b490d040240200c200b6b220d4102490d002000200e4105746a22032000200b4105746a220e412010e707417f4a0d00200e2900002117200e2003290000370000200241106a41186a2215200e41186a2210290000370300200241106a41106a2216200e41106a2212290000370300200241106a41086a2218200e41086a22132900003703002013200341086a2900003700002012200341106a2900003700002010200341186a29000037000020022017370310410121140240200d4103490d00200e41c0006a200241106a412010e707417f4a0d0041022110200f210302400340200341186a200341386a290000370000200341106a200341306a290000370000200341086a200341286a2900003700002003200341206a221229000037000020112010460d01200341c0006a21132010211420122103201041016a21102013200241106a412010e707417f4a0d020c000b0b201021140b200e20144105746a22032002290310370000200341186a2015290300370000200341106a2016290300370000200341086a20182903003700000b200b450d05200f41606a210f201141016a2111200b210e200d410a4f0d050c000b0b200e200c4180cac700104c000b200c20014180cac700104b000b200c200e417f6a220b490d00200c20014190cac700104b000b200b200c4190cac700104c000b0240200a2002280204470d002002200a4101108d012002280200210820022802082209210a0b2008200a4103746a2203200d3602042003200b3602002002200941016a22093602082009210a024020094102490d00034002400240024002400240200820092214417f6a22094103746a2203280200450d00201441037420086a221141746a280200220d200328020422104b0d010b20144103490d022003280204211020082014417d6a22034103746a280204210e0c010b4102210a0240201441024b0d0020142109200b450d090c060b20082014417d6a22034103746a280204220e2010200d6a4d0d004103210a0240201441034b0d0020142109200b450d090c060b201141646a280200200e200d6a4d0d00201421092014210a0c040b200e2010490d010b2014417e6a21030b02400240024002400240024002402014200341016a22184d0d00201420034d0d0120082003410374221a6a2203280204220a20032802006a220320082018410374221c6a22102802002216490d02200320014b0d03200020164105746a22132010280204221541057422106a210d2003410574210e200320166b220c20156b220320154f0d042005200d2003410574221010e407221220106a211120154101480d0520034101480d052006200e6a210e200d21030340200e200341606a220d201141606a220c200c200d412010e707410048220f1b2210290000370000200e41186a201041186a290000370000200e41106a201041106a290000370000200e41086a201041086a2900003700002011200c200f1b211102402013200d2003200f1b2203490d00201221100c080b200e41606a210e2012211020122011490d000c070b0b2018201441a0cac7001036000b2003201441b0cac7001036000b2016200341c0cac700104c000b2003200141c0cac700104b000b20052013201010e407221220106a2111024020154101480d00200c20154c0d002000200e6a210f201221102013210303402003200d2010200d2010412010e707410048220c1b220e290000370000200341186a200e41186a290000370000200341106a200e41106a290000370000200341086a200e41086a2900003700002010201041206a200c1b2110200341206a2103200d41206a200d200c1b220d200f4f0d03201120104b0d000c030b0b20132103201221100c010b200d2103201221100b20032010201120106b41607110e4071a2008201a6a2203200a20156a360204200320163602002008201c6a2203200341086a20142018417f736a41037410e5071a20022009360208200941014b0d000b2009210a200b450d040c010b200b450d030c000b0b1039000b1038000b0240200228020441ffffffff0171450d00200810290b2004450d01200510290c010b20014102490d002001417f6a2110200141057420006a41206a210f410121110340024002400240024020102203417f6a221020014b0d00200120106b220e4102490d03200020034105746a2203200020104105746a220c412010e707417f4a0d03200c2900002117200c2003290000370000200241106a41186a2213200c41186a220d290000370300200241106a41106a2214200c41106a2212290000370300200241106a41086a2208200c41086a22152900003703002015200341086a2900003700002012200341106a290000370000200d200341186a2900003700002002201737031041012103200e4103490d02200c41c0006a200241106a412010e707417f4a0d0241002112200f21030340200341406a220e200341606a220d290000370000200e41186a200d41186a290000370000200e41106a200d41106a290000370000200e41086a200d41086a29000037000020112012220e460d02200e417f6a21122003200241106a412010e707210d200341206a2103200d417f4a0d020c000b0b2010200141f0c9c700104c000b4102200e6b21030b200c20034105746a22032002290310370000200341186a2013290300370000200341106a2014290300370000200341086a20082903003700000b200f41606a210f2011417f6a211120100d000b0b200241306a24000bfc0701137f230041c0006b22042400200441003602082004420137030020044100360218200442013703102002410020031b21052000410020011b2106200241206a200220031b2107200041206a200020011b2108200020014105746a2109200220034105746a210a4101210b4101210c4100210d4101210e4101210f410021100340200b2111200e2112201021132007210320052102024002400340024020020d00410021052006450d020c030b02402006450d000240024020022006460d0020022006412010e70722140d010b2003200341206a2003200a4622021b210741002008200820094622141b21064100200320021b21052011210b2012210e201321102008200841206a20141b21080c050b02402014417f4c0d00200221050c040b200441206a41186a2214200241186a290000370300200441206a41106a2215200241106a290000370300200441206a41086a2216200241086a29000037030020042002290000370320024020132004280214470d00200441106a20134101109e01200428021821132004280210221121122011210f0b200f20134105746a22022004290320370000200241186a2014290300370000200241106a2015290300370000200241086a20162903003700002004201341016a2213360218410020032003200a4622141b21022003200341206a20141b21030c010b0b200441206a41186a2203200541186a290000370300200441206a41106a2213200541106a290000370300200441206a41086a2206200541086a29000037030020042005290000370320024020102004280214470d00200441106a20104101109e01200428021821102004280210220b210e0b200e20104105746a22022004290320370000200241186a2003290300370000200241106a2013290300370000200241086a20062903003700002004201041016a221036021841002106410020072007200a4622021b2105200e210f2007200741206a20021b21070c020b2004280204210220042802142103201120132000200110c5050240200341ffffff3f71450d00201110290b0240200241ffffff3f71450d00200c10290b200441c0006a24000f0b200441206a41186a2214200641186a290000370300200441206a41106a2215200641106a290000370300200441206a41086a2216200641086a290000370300200420062900003703200240200d2004280204470d002004200d4101109e012004280200210c2004280208210d0b200c200d4105746a22022004290320370000200241186a2014290300370000200241106a2015290300370000200241086a20162903003700002004200d41016a220d36020841002008200820094622021b21062011210b2012210e201321102008200841206a20021b2108200321070c000b0b9f0303027f017e027f230041206b2202240041a6d4c800ad4280808080b00284100122032900002104200241086a200341086a290000370300200220043703002003102941a4a1c900ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000b9f0303027f017e027f230041206b2202240041a6d4c800ad4280808080b00284100122032900002104200241086a200341086a290000370300200220043703002003102941f7edca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000ba10701087f230041106b220224002002410036020820024201370300200028020021030240410410272204450d002002410436020420022004360200200420033600002002410436020820002802042103200441044108102b2204450d002002410836020420042003360004200220043602002002410836020820002802082104200041106a280200220320021071024002402003450d00200341057421052002280204210620022802082103034002400240200620036b4120490d00200341206a2107200228020021080c010b200341206a22072003490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009102722080d010c060b2002280200210820062009460d00200820062009102b2208450d050b2002200936020420022008360200200921060b200820036a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200736020820072103200441206a2104200541606a22050d000b0b200028021421042000411c6a2802002203200210710240024020030d0020022802042109200228020821030c010b200341057421054100200228020822036b210820022802042106034002400240200620086a4120490d0020022802002107200621090c010b200341206a22072003490d03200641017422092007200920074b1b22094100480d030240024020060d00024020090d00410121070c020b200910272207450d060c010b2002280200210720062009460d00200720062009102b2207450d050b2002200936020420022007360200200921060b200720036a22072004290000370000200741186a200441186a290000370000200741106a200441106a290000370000200741086a200441086a2900003700002002200341206a2203360208200841606a2108200441206a2104200541606a22050d000b0b2000280220210602400240200920036b4104490d0020022802002104200921070c010b200341046a22042003490d01200941017422072004200720044b1b22074100480d010240024020090d00024020070d00410121040c020b200710272204450d040c010b2002280200210420092007460d00200420092007102b2204450d030b20022007360204200220043602000b200420036a20063600002001290200200341046aad4220862004ad84100302402007450d00200410290b200241106a24000f0b1032000b1030000b9f0303027f017e027f230041206b2202240041a6d4c800ad4280808080b00284100122032900002104200241086a200341086a290000370300200220043703002003102941f7edca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000bd304010a7f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d00200041003602080c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d002003200141046a36022020032002417c6a220536022420054104490d00200128000021062003200241786a3602242003200141086a36022020012800042107200341c8006a200341206a10960220032802482202450d00200341c8006a41086a2802002108200328024c2105200341c8006a200341206a1096020240024020032802482209450d00200328024c210a2003280224220b41044f0d030240200a41ffffff3f71450d00200910290b200541ffffff3f710d010c020b200541ffffff3f71450d010b200210290b20034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b200041003602080c010b200341d0006a280200210c2000200536020c200020023602082000200736020420002006360200200041206a200328022022022800003602002000411c6a200c360200200041186a200a360200200041146a2009360200200041106a20083602002003200b417c6a3602242003200241046a3602200b2004450d00200110290b200341e0006a24000ba00401037f230041e00b6b22042400200441086a200110870720042004280208220520042802104180a6cc004100410010c701024002400240024002402004280200450d002004280204220620024d0d01200041093a000620004183263b0104200041013602002000410c6a4113360200200041086a41e7d5c8003602000c020b200041023a000620004183263b0104200041013602002000410c6a410f360200200041086a41ced6c8003602000c010b200441b0096a200110870720044188076a20042802b009220220042802b8091086072004280288072101200441bc096a20044188076a41047241a40210e4071a024002402001411c460d00200441e4046a200441bc096a41a40210e4071a024020042802b409450d00200210290b200441c0026a200441e4046a41a40210e4071a20042001360218200441186a410472200441c0026a41a40210e4071a20044188076a200441186a10c3012004290388072003560d01200041086a200441186a41a80210e4071a20004100360200200041b0026a2006360200200428020c450d040c030b024020042802b409450d00200210290b2000410c6a410f360200200041086a41ced6c800360200200041023a000620004183263b0104200041013602000c010b200041083a000620004183263b0104200041013602002000410c6a4113360200200041086a41fad5c800360200200441186a10cc010b200428020c450d010b200510290b200441e00b6a24000b8f0f0b017f017e037f017e017f027e037f027e057f027e067f230041c0036b220524000240024020000d002005413d6a200341086a290000370000200541c5006a200341106a290000370000200541cd006a200341186a290000370000200541033a00342005410b3a003020052003290000370035200541306a10cb0142002106410121070c010b2005413d6a200341086a2200290000370000200541c5006a200341106a2208290000370000200541cd006a200341186a2209290000370000200541023a00342005410b3a003020052003290000370035200541306a10cb01200541306a200410c3012005290330210a2002280204210b200541306a200441a80210e4071a200541e4026a2001360200200541d8026a41086a200b360200200541003a00dc02200541023a00d802200541086a200541306a200541d8026a10c501200541306a41186a2009290000370300200541306a41106a2008290000370300200541306a41086a200029000037030020052003290000370330200541086a41186a2d000021012005290310210c2005290308210d200520052900213703d8022005200541286a2800003600df0202400240200d4201510d00410421000c010b200520052800df0236008703200520052903d8023703800341042100200c4202510d0020052005280087033600b70320052005290380033703b003200121000b200541d8026a41086a2201200541306a41086a290300370300200541d8026a41106a2208200541306a41106a290300370300200541d8026a41186a2209200541306a41186a290300370300200520052903303703d802200520052903b0033703a003200520052800b7033600a703200541043a00342005410b3a00302005413d6a2001290300370000200541c5006a2008290300370000200541cd006a2009290300370000200541d8006a20003a0000200520052903d802370035200541d5006a20052f00b0033b0000200541d7006a200541b2036a2d00003a0000200541d9006a20052903a003370000200541e0006a20052800a703360000200541fc006a20054180036a41186a280200360200200541f4006a20054180036a41106a290200370200200541ec006a20054180036a41086a290200370200200541e4006a200529028003370200200541306a10cb01200541086a41106a290300200a200ca71b2106410021070b200541306a2003108707200535023842208620052802302200ad84100402402005280234450d00200010290b200541306a200310c005200535023842208620052802302200ad84100402402005280234450d00200010290b200541d8026a41186a220e4200370300200541d8026a41106a220f4200370300200541d8026a41086a22104200370300200542003703d80241a6d4c800ad4280808080b00284221110012200290000210c2010200041086a2900003703002005200c3703d80220001029419fdec900ad4280808080900184221210012200290000210c200541086a41086a2213200041086a2900003703002005200c37030820001029200f2005290308220c370300200541306a41086a22142010290300370300200541306a41106a2215200c370300200541306a41186a22162013290300370300200520052903d802370330200541d8026a200541306a412010ce0120052802d8022200410120001b2117024020052902dc02420020001b22184220882219a72209450d0041002101201721004100210802400240034002400240024020032000460d0020002003412010e707450d0020010d01410021010c020b200141016a21010c010b200820016b220b20094f0d02200e200020014105746b220b41186a221a290000370300200f200b41106a221b2900003703002010200b41086a221c2900003703002005200b2900003703d802200041086a221d290000210c200041106a221e290000210a200041186a221f290000210d200b2000290000370000201a200d370000201b200a370000201c200c370000201f200e290300370000201e200f290300370000201d2010290300370000200020052903d8023700000b200041206a21002009200841016a2208460d020c000b0b200b20094180bdc7001036000b2001417f6a20094f0d00200920016bad2219422086201842ffffffff0f838421180b20164200370300201542003703002014420037030020054200370330201110012200290000210c2014200041086a2900003703002005200c37033020001029201210012200290000210c2013200041086a2900003703002005200c3703082000102920152005290308220c37030020102014290300370300200f200c370300200e2013290300370300200520052903303703d802201942017c210c0240024020170d00200541d8026aad428080808080048410040c010b200541203602342005200541d8026a36023020172019a7200541306a10cf01201842ffffff3f83500d00201710290b427f200642c0b6fc9a017c220a200a2006541b220a200c42ffffffff0f834290f41d7e7c210c02402007450d00200410cc010b200c200a54210002402002410c6a28020041ffffff3f71450d00200228020810290b427f200c20001b210c0240200241186a28020041ffffff3f71450d00200228021410290b200541c0036a2400200c0bed6405057f027e107f057e117f230041c0036b22032400024002400240024002400240024002400240024002400240024002400240024020012d00000e0700010905040302000b200341d4026a4101360200200342013702c40220034198e3ca003602c0022003410436028402200341cce3ca0036028002200320034180026a3602d002200341c0026a4180a6cc001040000b200141086a2802002104200141046a2802002105410221064100210720022d00000d0a20022d00014101470d0a200141186a2903002108200141106a29030021092001410c6a2802002101200241196a2d00002107200241186a2d00002106200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211920032002411a6a2901003703e801200320073a00e701200320063a00e6012003200a3b01e4012003200b3a00e3012003200c3a00e2012003200d3b01e0012003200e3a00df012003200f3a00de01200320103b01dc01200320113a00db01200320123a00da01200320133b01d801200320143a00d701200320153a00d601200320163b01d401200320173a00d301200320183a00d201200320193b01d0010240200141104d0d004114210241eaecca0021014180800c21070c0a0b024020010d0041072102418aedca0021014180800421070c0a0b4196ebca00ad4280808080800284221a10012202290000211b2002290008211c2002102941e0f8ca00ad4280808080a0018410012202290000211d2002290008211e200210292003201e3701d8022003201d3701d0022003201c3701c8022003201b3701c00241002106200341f4016a220741003a0000200341003602f001200341386a200341c0026a4120200341f0016a4105410010c7014100210a02402003280238450d002003200328023c2202410520024105491b360284022003200341f0016a36028002200341306a20034180026a10c8014100200328023420032802301b210a0b201a10012202290000211a2002290008211b2002102941f0edca00ad4280808080f0008410012202290000211c2002290008211d200210292003201d3701d8022003201c3701d0022003201b3701c8022003201a3701c002200741003a0000200341003602f001200341286a200341c0026a4120200341f0016a4105410010c70102402003280228450d002003200328022c2202410520024105491b360284022003200341f0016a36028002200341206a20034180026a10c8014100200328022420032802201b21060b4196ebca00ad428080808080028410012202290000211a2002290008211b2002102941eaf8ca00ad428080808090018410012202290000211c2002290008211d200210292003201d3701d8022003201c3701d0022003201b3701c8022003201a3701c00241002107200341f4016a41003a0000200341003602f001200341186a200341c0026a4120200341f0016a4105410010c7014100210b02402003280218450d002003200328021c2202410520024105491b360284022003200341f0016a36028002200341106a20034180026a10c8014100200328021420032802101b210b0b410c210202402006200a6a200b6a22060d004191edca0021010c0a0b0240200120064d0d0041feecca0021014180800821070c0a0b024020094281c8afa0255441002008501b450d00410a210241e0ecca0021014180801021070c0a0b200341c0026a200341d0016a10ac07200341086a20032802c002220720032802c8024180a6cc004100410010c70120032802082102024020032802c402450d00200710290b024020024101460d00200342003703b80120034280e8eda1ba013703b0012003200341d0016a3602bc022003200341d0016a3602f0012003200341f0016a3602c8022003200341bc026a3602c4022003200341b0016a3602c00220034180026a200341d0016a200341c0026a108e0402402003280280024101470d0020032d0084024104460d01410f210241d1ecca0021014180801421070c0b0b20034180026a41086a2903004201520d0020034180026a41106a290300211a20032802f0012102200341f8026a20034180026a41186a290300370300200341f0026a201a370300200341c0026a41086a41003a0000200341c9026a2002290000370000200341d1026a200241086a290000370000200341d9026a200241106a290000370000200341e1026a200241186a290000370000200341033a00c002200341c0026a10cb010b20034180026a200341d0016a10a802200341c0026a200328028002220720032802880210a902200341d0026a290300420020032903c00242015122021b211a20032903c802420020021b211b200341e0026a290300420020021b211c200341d8026a290300420020021b211d0240200328028402450d00200710290b200342f0d0c9abc6add9b1f4003703c002200341c0026a200341d0016a427f201b201d7c221d201d201b542202201a201c7c2002ad7c221b201a54201b201a511b22021b221a2009201a200954427f201b20021b221a200854201a2008511b22021b2209201a200820021b2208411e10aa0220034180026a200341d0016a10ac0702402001410574220d4114722207417f4c0d00200335028802211a200328028002210e0240200710272202450d002002200937000020022008370008200341103602c802200320073602c402200320023602c0022001200341c0026a1071410020032802c802220c6b210620032802c002210b20032802c402210a4100210203400240200a20066a411f4b0d00024002400240200c20026a220741206a22012007490d00200a41017422072001200720014b1b22014100480d0002400240200a0d00024020010d004101210b0c020b20011027210b0c040b200a2001470d020b2001210a0c030b1032000b200b200a2001102b210b0b2001210a200b0d001030000b200b200c6a20026a2201200520026a2207290000370000200141186a200741186a290000370000200141106a200741106a290000370000200141086a200741086a290000370000200641606a2106200d200241206a2202470d000b201a422086200ead84200c20026aad422086200bad8410030240200a450d00200b10290b0240200328028402450d00200e10290b200441ffffff3f71450d06200510290c060b1039000b1038000b420021080240024020022d000120022d000041004772450d00410221020c010b200141216a2d00002107200141096a2900002109200141116a290000211a2001290001211b2003200141196a2900003703e8012003201a3703e001200320093703d8012003201b3703d0014196ebca00ad42808080808002841001220229000021092002290008211a2002102941eaf8ca00ad428080808090018410012202290000211b2002290008211c200210292003201c3701d8022003201b3701d0022003201a3701c802200320093701c002200341f4016a41003a0000200341003602f001200341a8016a200341c0026a4120200341f0016a4105410010c70102400240024020032802a801450d00200320032802ac012202410520024105491b360284022003200341f0016a36028002200341a0016a20034180026a10c801200741ff017141004720032802a40141004720032802a001457173450d010c020b200741ff01710d010b200341f0016a200341d0016a10c407024020032d00f0014101460d0020032d00f1012102200342003703b80120034280a094a58d1d3703b0012003200341d0016a3602bc0220034180026a200341d0016a200341b0016a200341bc026a10a905200341a0026a2903002108200329039802210902402003290380024201520d00200329038802211a200341f8026a20034180026a41106a290300370300200341f0026a201a370300200341c0026a41086a41003a0000200341c9026a20032903d001370000200341d1026a200341d0016a41086a290300370000200341d9026a200341d0016a41106a290300370000200341e1026a200341e8016a290300370000200341033a00c002200341c0026a10cb010b20034188016a200920081081020240200329038801a7450d0020034188016a41106a29030021082003290390012109200342f0f2bda1a7ee9cb9f90037038002200341c0026a20034180026a108202200341c0026a20092008108002200341d8026a2008370300200341c0026a41106a2009370300200341c8026a41063a00002003410e3a00c002200341c0026a10cb010b200341cd026a200341d8016a290300370000200341d5026a200341d0016a41106a290300370000200341dd026a200341e8016a290300370000200341023a00c4022003410c3a00c002200320032903d0013700c502200341c0026a10cb01200241ff01710d0610d2040c060b20032802f401220241187621012002411076210420024108762105200341fc016a2802002107200341f0016a41086a28020021060c010b4201210841032102411421054110210441a6ebca002106411221070b200020013a001b200020043a001a200020053a001920002008370308200041206a20073602002000411c6a2006360200200041186a20023a0000200041106a42c08be40e3703000c0b0b411121064102210702400240024020022d00000d0020022d00014101470d00200141086a2802002119200141046a2802002101200241196a2d00002107200241186a2d00002104200241166a2f01002105200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820032002411a6a2901003703e801200320073a00e701200320043a00e601200320053b01e4012003200a3a00e3012003200b3a00e2012003200c3b01e0012003200d3a00df012003200e3a00de012003200f3b01dc01200320103a00db01200320113a00da01200320123b01d801200320133a00d701200320143a00d601200320153b01d401200320163a00d301200320173a00d201200320183b01d00102400240024002400240024002400240024020010e03000102000b200341c0026a200341d0016a10c40720032d00c0024101460d02200342003703b80120034280a094a58d1d3703b0012003200341d0016a3602f00120034180026a200341d0016a200341b0016a200341f0016a10ea0302402003290380024201520d002003290388022108200341f8026a20034180026a41106a290300370300200341f0026a2008370300200341c0026a41086a41003a0000200341c9026a20032903d001370000200341d1026a200341d0016a41086a290300370000200341d9026a200341d0016a41106a290300370000200341e1026a200341e8016a290300370000200341033a00c002200341c0026a10cb010b200341cd026a200341d8016a290300370000200341d5026a200341e0016a290300370000200341dd026a200341e8016a290300370000200341033a00c4022003410c3a00c002200320032903d0013700c502200341c0026a10cb010c0d0b200341c0026a41186a4200370300200341c0026a41106a22074200370300200341c0026a41086a22024200370300200342003703c0024196ebca00ad42808080808002841001220129000021082002200141086a290000370300200320083703c0022001102941eaf8ca00ad4280808080900184100122012900002108200341f0016a41086a2204200141086a290000370300200320083703f00120011029200720032903f001220837030020034180026a41086a200229030037030020034180026a41106a200837030020034180026a41186a2004290300370300200320032903c00237038002200341c0026a20034180026a10a90720032902c402420020032802c00222021b2208422088a7220a41306c2101410021072002410820021b220521020240024003402001450d02200341d0016a2002460d01200741016a2107200141506a21012002200341d0016a412010e7072104200241306a210220040d000b20044541016a41017120076a417f6a21070b2005200741306c6a2202200241306a2007417f73200a6a41306c10e5071a200342003703b80120034280a094a58d1d3703b0012003200341d0016a3602f00120034180026a200341d0016a200341b0016a200341f0016a10ea0302402003290380024201520d002003290388022109200341f8026a20034180026a41106a290300370300200341c0026a41306a2009370300200341c0026a41086a41003a0000200341c9026a20032903d001370000200341d1026a200341d0016a41086a290300370000200341d9026a200341d0016a41106a290300370000200341e1026a200341e8016a290300370000200341033a00c002200341c0026a10cb010b4196ebca00ad42808080808002841001220229000021092002290008211a2002102941eaf8ca00ad428080808090018410012202290000211b2002290008211c200210292003201c3701d8022003201b3701d0022003201a3701c802200320093701c00220034120360284022003200341c0026a360280022005200a417f6a20034180026a10c9062008a72202450d0d200241306c450d0d200510290c0d0b2008a72202450d06200241306c450d04200510290c040b200341c0026a41186a4200370300200341c0026a41106a22074200370300200341c0026a41086a22024200370300200342003703c0024196ebca00ad42808080808002841001220129000021082002200141086a290000370300200320083703c0022001102941e0f8ca00ad4280808080a00184100122012900002108200341f0016a41086a2204200141086a290000370300200320083703f00120011029200720032903f001220837030020034180026a41086a200229030037030020034180026a41106a200837030020034180026a41186a2004290300370300200320032903c00237038002200341c0026a20034180026a108d0220032802c0022202410120021b210a201920032902c402420020021b2208422088a722054f0d012008a72202450d05200241ffffff3f71450d030c020b20032802c402220741ff01714104460d0a200341cc026a2802002106200341c8026a28020021022007418080807871210520074180807c712104200741807e7121010c070b02402005450d002005410574210741002101200a21020340200341d0016a2002460d0420012002200341d0016a412010e70722044100476a21012004450d04200241206a2102200741606a22070d000b0b2008a72202450d03200241ffffff3f71450d010b200a10290b41b8ebca002102410321070c030b200a20014105746a2202200241206a2001417f7320056a41057410e5071a200342003703b80120034280a094a58d1d3703b0012003200341d0016a3602f00120034180026a200341d0016a200341b0016a200341f0016a10ea0302402003290380024201520d002003290388022109200341f8026a20034180026a41106a290300370300200341f0026a2009370300200341c0026a41086a41003a0000200341c9026a20032903d001370000200341d1026a200341d0016a41086a290300370000200341d9026a200341d0016a41106a290300370000200341e1026a200341e8016a290300370000200341033a00c002200341c0026a10cb010b4196ebca00ad42808080808002841001220229000021092002290008211a2002102941e0f8ca00ad4280808080a0018410012202290000211b2002290008211c200210292003201c3701d8022003201b3701d0022003201a3701c802200320093701c00220034120360284022003200341c0026a36028002200a2005417f6a20034180026a10b901200842ffffff3f83500d06200a10290c060b410321070b41b8ebca0021020b41802821014180803c2104410021050b20004200370308200041206a20063602002000411c6a2002360200200041186a20052004418080fc07717220014180fe037172200741ff0171723602000c0a0b41022107024002400240024020022d00000d0020022d00014101470d00200141046a2802002117200241196a2d00002101200241186a2d00002107200241166a2f01002106200241156a2d00002104200241146a2d00002105200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703e801200320013a00e701200320073a00e601200320063b01e401200320043a00e301200320053a00e2012003200a3b01e0012003200b3a00df012003200c3a00de012003200d3b01dc012003200e3a00db012003200f3a00da01200320103b01d801200320113a00d701200320123a00d601200320133b01d401200320143a00d301200320153a00d201200320163b01d0014196ebca00ad4280808080800284100122022900002108200229000821092002102941e0f8ca00ad4280808080a0018410012202290000211a2002290008211b200210292003201b3701d8022003201a3701d002200320093701c802200320083701c002200341f4016a41003a0000200341003602f00120034180016a200341c0026a4120200341f0016a4105410010c7010240200328028001450d0020032003280284012202410520024105491b360284022003200341f0016a36028002200341f8006a20034180026a10c80120032802780d00200328027c20174d0d004115210241d9ebca002101418080342106410321070c040b200341c0026a41186a4200370300200341c0026a41106a22054200370300200341c0026a41086a22024200370300200342003703c0024196ebca00ad42808080808002841001220129000021082002200141086a290000370300200320083703c0022001102941e0f8ca00ad4280808080a00184100122012900002108200341f0016a41086a2207200141086a290000370300200320083703f00120011029200520032903f001220837030020034180026a41086a200229030037030020034180026a41106a200837030020034180026a41186a2007290300370300200320032903c00237038002200341c0026a20034180026a108d0220032802c0022201410120011b21044100210a41002102024020032902c402420020011b2208422088a7220141014b0d004100210b20010e020302030b03402001410176220720026a22062002200420064105746a200341d0016a412010e7074101481b2102200120076b220141014b0d000c020b0b410021060c020b0240200420024105746a200341d0016a412010e70722010d004101210a2002210b0c010b2001411f7620026a210b0b0240200842ffffff3f83500d00200410290b02400240200a450d004113210241a9ecca0021014180802021060c010b410c21020240200341d0016a10a607450d00419decca002101418080242106410321070c020b200341c0026a41186a22064200370300200341c0026a41106a22044200370300200341c0026a41086a22014200370300200342003703c0024196ebca00ad42808080808002841001220729000021082001200741086a290000370300200320083703c0022007102941eaf8ca00ad4280808080900184100122072900002108200341f0016a41086a220a200741086a290000370300200320083703f00120071029200520032903f001370000200541086a200a29030037000020034180026a41086a200129030037030020034180026a41106a200429030037030020034180026a41186a2006290300370300200320032903c00237038002200341c0026a20034180026a10a90720032902c402420020032802c00222011b2208422088a741306c2107410021062001410820011b220a2101024003402007450d010240200341d0016a2001460d00200641016a2106200741506a21072001200341d0016a412010e7072104200141306a210120040d010b0b4191ecca0021014180802821062008a72207450d01200741306c450d01200a1029410321070c020b02402008a72202450d00200241306c450d00200a10290b200342003703b80120034280a094a58d1d3703b0012003200341d0016a3602bc022003200341d0016a3602f0012003200341f0016a3602c8022003200341bc026a3602c4022003200341b0016a3602c00220034180026a200341d0016a200341c0026a108e04024002402003280280024101470d0020032d0084024104460d01411a210241f7ebca0021014180802c2106410321070c030b20034180026a41086a2903004201520d0020034180026a41106a290300210820032802f0012102200341f8026a20034180026a41186a290300370300200341f0026a2008370300200341c0026a41086a41003a0000200341c9026a2002290000370000200341d1026a200241086a290000370000200341d9026a200241106a290000370000200341e1026a200241186a290000370000200341033a00c002200341c0026a10cb010b20032903e801210820032d00e701210420032d00e601210a20032f01e401210c20032d00e301210d20032d00e201210e20032f01e001210f20032d00df01211020032d00de01211120032f01dc01211220032d00db01211320032d00da01211420032f01d801211520032d00d701211620032d00d601211720032f01d401211820032d00d301211920032d00d201211f20032f01d0012120200341c0026a41186a22074200370300200341c0026a41106a22064200370300200341c0026a41086a22024200370300200342003703c0024196ebca00ad42808080808002841001220129000021092002200141086a290000370300200320093703c0022001102941e0f8ca00ad4280808080a00184100122012900002109200341f0016a41086a2221200141086a290000370300200320093703f00120011029200520032903f001370000200541086a202129030037000020034180026a41086a200229030037030020034180026a41106a200629030037030020034180026a41186a2007290300370300200320032903c00237038002200341c0026a20034180026a108d020240024020032802c00222010d00410021062003410036028802200342013703800241012101410021070c010b200320032902c40222093702840220032001360280022009422088a721072009a721060b02402007200b490d00024020072006470d0020034180026a20064101109e01200328028402210620032802800221010b2001200b4105746a220241206a20022007200b6b41057410e5071a20022008370018200220043a00172002200a3a00162002200c3b00142002200d3a00132002200e3a00122002200f3b0010200220103a000f200220113a000e200220123b000c200220133a000b200220143a000a200220153b0008200220163a0007200220173a0006200220183b0004200220193a00032002201f3a0002200220203b00002003200741016a2207360288024196ebca00ad4280808080800284100122022900002108200229000821092002102941e0f8ca00ad4280808080a0018410012202290000211a2002290008211b200210292003201b3701d8022003201a3701d002200320093701c802200320083701c002024020010d00200341c0026aad428080808080048410040c050b200341203602b4012003200341c0026a3602b00120012007200341b0016a10b901200641ffffff3f71450d04200110290c040b200b20071041000b410321070b20004200370308200041206a20023602002000411c6a2001360200200041186a20064180803c71200772418028723602000c090b410221070240024020022d00000d0020022d00014101460d010b4100210241002106410021010c030b200141246a2902002108200141236a2d00002107200141226a2d00002106200141206a2f010021042001411f6a2d000021052001411e6a2d0000210a2001411c6a2f0100210b2001411b6a2d0000210c2001411a6a2d0000210d200141186a2f0100210e200141176a2d0000210f200141166a2d00002110200141146a2f01002111200141136a2d00002112200141126a2d00002113200141106a2f010021142001410f6a2d000021152001410e6a2d000021162001410c6a2f01002117200141086a2802002122200141046a2802002123200241196a2d00002101200241186a2d00002118200241166a2f01002119200241156a2d0000211f200241146a2d00002120200241126a2f01002121200241116a2d00002124200241106a2d000021252002410e6a2f010021262002410d6a2d000021272002410c6a2d000021282002410a6a2f01002129200241096a2d0000212a200241086a2d0000212b200241066a2f0100212c200241056a2d0000212d200241046a2d0000212e200241026a2f0100212f20032002411a6a2901003703c801200320013a00c701200320183a00c601200320193b01c4012003201f3a00c301200320203a00c201200320213b01c001200320243a00bf01200320253a00be01200320263b01bc01200320273a00bb01200320283a00ba01200320293b01b8012003202a3a00b7012003202b3a00b6012003202c3b01b4012003202d3a00b3012003202e3a00b2012003202f3b01b001200320083703e801200320073a00e701200320063a00e601200320043b01e401200320053a00e3012003200a3a00e2012003200b3b01e0012003200c3a00df012003200d3a00de012003200e3b01dc012003200f3a00db01200320103a00da01200320113b01d801200320123a00d701200320133a00d601200320143b01d401200320153a00d301200320163a00d201200320173b01d0010240200341b0016a200341d0016a412010e7070d0041bcecca002105410a21044180801c21060c020b200341c0026a200341b0016a10ac07200341f0006a20032802c002220120032802c8024180a6cc004100410010c70120032802702102024020032802c402450d00200110290b024020024101460d0041c6ecca002105410b21044180801821060c020b4196ebca00ad4280808080800284100122022900002108200229000821092002102941e0f8ca00ad4280808080a0018410012202290000211a2002290008211b200210292003201b3701d8022003201a3701d002200320093701c802200320083701c002200341f4016a41003a0000200341003602f001200341e8006a200341c0026a4120200341f0016a4105410010c70102402003280268450d002003200328026c2202410520024105491b360284022003200341f0016a36028002200341e0006a20034180026a10c80120032802600d00200328026420224d0d0041d9ebca002105411521044180803421060c020b20034180026a200341d0016a10ac07200341c0026a200328028002220120032802880210fb0520032902d402420020032802d00222021b21080240200328028402450d00200110290b2002410120021b210a41032107418028210141002102024002402008422088a722060d0041c6ecca002105410b21044180801821060c010b0240202320064f0d0041c9ebca002105411021044180803821060c010b200a20064105746a210e200341c0026a41106a21054196ebca00ad42808080808002842109200a210702400240024003402007200e460d010240200710a6070d00200741206a2110200341c0026a41186a220c420037030020054200370300200341c0026a41086a220b4200370300200342003703c002200910012202290000211a200b200241086a2900003703002003201a3703c0022002102941eaf8ca00ad428080808090018410012202290000211a200341f0016a41086a220d200241086a2900003703002003201a3703f00120021029200520032903f001370000200541086a2211200d29030037000020034180026a41086a2212200b29030037030020034180026a41106a2213200529030037030020034180026a41186a2214200c290300370300200320032903c00237038002200341c0026a20034180026a10a90720032902c402420020032802c00222021b221a422088a741306c2101410021062002410820021b220f2102024003402001450d01024020072002460d0020022007412010e7072104200641016a2106200141506a2101200241306a210220040d010b0b201aa72202450d01200241306c450d01200f10290c010b0240201aa72202450d00200241306c450d00200f10290b200c420037030020054200370300200b4200370300200342003703c002200910012202290000211a200b200241086a2900003703002003201a3703c0022002102941e0f8ca00ad4280808080a0018410012202290000211a200d200241086a2900003703002003201a3703f00120021029200520032903f0013700002011200d2903003700002012200b290300370300201320052903003703002014200c290300370300200320032903c00237038002200341c0026a20034180026a108d0220032802c0022201410120011b210b4100210202400240024020032902c402420020011b221a422088a7220141014b0d0020010e020201020b03402001410176220620026a22042002200b20044105746a2007412010e7074101481b2102200120066b220141014b0d000b0b200b20024105746a2007412010e7074521020b0240201a42ffffff3f83500d00200b10290b201021072002450d010b0b200342003703f80120034280e8eda1ba013703f0012003200341b0016a3602bc0220034180026a200341b0016a200341f0016a200341bc026a10a905200341a0026a2903002109200329039802211a02402003290380024201520d00200329038802211b200341f8026a20034180026a41106a290300370300200341f0026a201b370300200341c0026a41086a41003a0000200341c9026a20032903b001370000200341d1026a200341b0016a41086a290300370000200341d9026a200341b0016a41106a290300370000200341e1026a200341c8016a290300370000200341033a00c002200341c0026a10cb010b200341c8006a201a200910810202402003290348a7450d00200341c8006a41106a29030021092003290350211a200342f0f2bda1a7ee9cb9f90037038002200341c0026a20034180026a108202200341c0026a201a2009108002200341d8026a2009370300200341c0026a41106a201a370300200341c8026a41063a00002003410e3a00c002200341c0026a10cb010b200341c0026a200341b0016a10ac0720033502c80242208620032802c0022202ad841004024020032802c402450d00200210290b41002102200341b0016a21010c010b200341c0026a200341d0016a200341b0016a4280e8eda1ba014200410010e90320032802c0024101460d01200341c0026a200341d0016a10ac0720033502c80242208620032802c0022202ad841004024020032802c402450d00200210290b41012102200341d0016a21010b200342f0d0c9abc6add9b1f4003703c002200341c0026a200110ac02200341cd026a200341d0016a41086a290300370000200341d5026a200341d0016a41106a290300370000200341dd026a200341d0016a41186a290300370000200341e5026a20032903b001370000200341ed026a200341b0016a41086a290300370000200341f5026a200341b0016a41106a290300370000200341fd026a200341b0016a41186a29030037000020034185036a20023a0000200341043a00c4022003410c3a00c002200320032903d0013700c502200341c0026a10cb01200842ffffff3f83500d02200a10290c020b200341cc026a2802002104200341c8026a280200210520032802c4022207418080807871210220074180807c712106200741807e7121010b0240200842ffffff3f83500d00200a10290b200741ff01714104470d020b420021080c030b410321074180282101410021020b20004200370308200041206a20043602002000411c6a2005360200200041186a20022006418080fc07717220014180fe037172200741ff0171723602000c050b0240024020022d00000d0020022d00014101470d002002411a6a2901002108200241196a2d00002101200241186a2d00002107200241166a2f01002106200241156a2d00002104200241146a2d00002105200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f010021152003200241096a2d00003a00c702200320113a00c602200320123b01c402200320133a00c302200320143a00c202200320153b01c0022003200b3a00cf022003200c3a00ce022003200d3b01cc022003200e3a00cb022003200f3a00ca02200320103b01c802200320013a00d702200320073a00d602200320063b01d402200320043a00d302200320053a00d2022003200a3b01d002200320083701d802200341e8016a2008370300200341e0016a20032901d002370300200341d8016a20032901c802370300200320032901c0023703d001200341c0026a200341d0016a10ac07200341c0006a20032802c002220120032802c8024180a6cc004100410010c70120032802402102024020032802c402450d00200110290b024020024101470d00200341c0026a200341d0016a10ac0720033502c80242208620032802c0022202ad841004024020032802c402450d00200210290b200342f0d0c9abc6add9b1f4003703c002200341c0026a200341d0016a10ac0242002108200342003703b80120034280e8eda1ba013703b0012003200341d0016a3602f00120034180026a200341d0016a200341b0016a200341f0016a10ea032003290380024201520d032003290388022109200341f8026a20034180026a41106a290300370300200341f0026a2009370300200341c0026a41086a41003a0000200341c9026a20032903d001370000200341d1026a200341d0016a41086a290300370000200341d9026a200341d0016a41106a290300370000200341e1026a200341e8016a290300370000200341033a00c002200341c0026a10cb01200042003703080c080b4183a81821020c010b4182a81821020b20004200370308200041206a410b3602002000411c6a41c6ecca00360200200041186a20023602000c040b200020083703080c040b410321060c010b0b0240200441ffffff3f71450d00200510290b20004200370308200041206a20023602002000411c6a2001360200200041186a20074180801c71200672418028723602000b420121080b20002008370300200341c0036a24000bad1206087f017e047f017e057f077e230022042105200441e0016b416071220424000240200341e500490d0041002802d8a74c450d00200441ec006a410136020020044101360264200441b0e3c800360260200420033602482004200441c8006a36026841002802888040210641002802848040210741002802dca74c2108200441c0016a41a806360200200441b8016a42de80808010370300200441b4016a41dde3c800360200200441ac016a4211370200200441a8016a41cce3c800360200200441a0016a420237030020044190016a420337030020044188016a41113602002004419c016a200441e0006a360200200441b4e3c80036028c01200441cce3c80036028401200441013602800120074180a4c000200841024622081b20044180016a20064198a4c00020081b2802101102000b024002400240200141ffffff3f712001470d0020014105742207417f4c0d000240024020070d00410121080c010b200710272208450d020b4100210620044100360288012004200836028001200420074105763602840120044180016a41002001109e01200428028801210902402001450d002001410574210a20042802800120094105746a210b0340200b20066a2207200020066a2208290000370000200741186a200841186a290000370000200741106a200841106a290000370000200741086a200841086a290000370000200a200641206a2206470d000b200141057441606a41057620096a41016a21090b200441186a41086a20093602002004200429038001220c370318200ca7200920044180016a410041202009676b10fa0420044180016a41186a2201420037030020044180016a41106a220d420037030020044180016a41086a220e4200370300200442003703800141a6d4c800ad4280808080b0028410012206290000210c200e200641086a2900003703002004200c3703800120061029419fdec900ad428080808090018410012206290000210c200441c8006a41086a220f200641086a2900003703002004200c37034820061029200d2004290348220c370300200441e0006a41086a200e290300370300200441e0006a41106a200c370300200441e0006a41186a200f290300370300200420042903800137036020044180016a200441e0006a412010ce012004280280012206410120061b2110200429028401420020061b2211422088a72206450d0220064105742109200441e0006a410c72211220044180016a410c6a210020044180016a411472211320044180016a41087221142010210603402001200641186a290000370300200d200641106a290000370300200e200641086a2900003703002004200629000037038001200441286a20044180016a10be0520044180016a2004280228220b2004280230221510c105200f200041086a290200370300200441c8006a41106a220a200041106a2802003602002004200029020037034820042802a001210702402004280288012208450d00200429038001210c20122004290348370200201241086a200f290300370200201241106a200a2802003602002004200c370360200721160b2004200836026820044100360288012004290378211720042004290398012218370378200429037021192004200429039001221a3703702004290360211b2004200429038001221c3703602004290368210c2004200429038801221d370368201da7210802400240200ca7220a0d00201d210c201a211920182117201621070c010b2004201b370380012004200c37038801200420193703900120042017370398012004200a2019a74105746a3602542004200a3602502004200c422088a736024c2004200a3602482004200441186a360258200441386a200441c8006a10f905201441086a200441386a41086a22162802003602002014200429033837020020042019422088a7220a2017422088a74105746a3602542004200a36025020042017a736024c2004200a3602482004200441186a360258200441386a200441c8006a10f905201341086a201628020036020020132004290338370200200429038801210c200429038001211c2004290398012117200429039001211902402008450d002018a7210a0240201d422088a741ffffff3f71450d00200810290b200a41ffffff3f71450d00201a422088a710290b2004201c3703602004200c3703682004201937037020042017370378200ca721080b2004200c370388012004201937039001200120173703002004201c37038001200420073602a001200ca7210a0240024020080d002015ad422086200bad8410040c010b2004201536024c2004200b36024820044180016a200441c8006a10e4060b0240200a450d002017a721080240200c422088a741ffffff3f71450d00200a10290b200841ffffff3f71450d002019422088a710290b0240200428022c450d00200b10290b200641206a210620072116200941606a22090d000c030b0b1038000b1039000b0240201142ffffff3f83500d00201010290b20044180016a41186a220a420037030020044180016a41106a2208420037030020044180016a41086a22074200370300200442003703800141a6d4c800ad4280808080b00284220c10012200290000211c200441c8006a41086a2206200041086a2900003703002004201c3703482000102920072006290300370300200420042903483703800141f0edca00ad4280808080f0008410012200290000211c2006200041086a2900003703002004201c3703482000102920082004290348221c370300200441e0006a41086a220b2007290300370300200441e0006a41106a2201201c370300200441e0006a41186a22092006290300370300200420042903800137036020044120360284012004200441e0006a360280012002200320044180016a10d506200a420037030020084200370300200742003703002004420037038001200c10012200290000210c2006200041086a2900003703002004200c3703482000102920072006290300370300200420042903483703800141f8d7ca00ad4280808080d0008410012200290000210c2006200041086a2900003703002004200c3703482000102920082004290348220c370300200b20072903003703002001200c370300200920062903003703002004200429038001370360200441e0006aad428080808080048410040240200428021c41ffffff3f71450d00200428021810290b200524000bec0502057f017e23004190016b2201240020002d00002102200141186a2203200041196a290000370300200141106a2204200041116a290000370300200141086a2205200041096a2900003703002001200029000137030002400240024020020d00200141f0006a41186a4200370300200141f0006a41106a22034200370300200141f0006a41086a220042003703002001420037037041a6d4c800ad4280808080b002841001220229000021062000200241086a290000370300200120063703702002102941f8d7ca00ad4280808080d00084100122022900002106200141206a41086a2204200241086a2900003703002001200637032020021029200320012903202206370300200141c0006a41086a2000290300370300200141c0006a41106a2006370300200141c0006a41186a200429030037030020012001290370370340200141c0006aad428080808080048410040c010b200141206a41186a2003290300370300200141206a41106a2004290300370300200141206a41086a200529030037030020012001290300370320200141f0006a41186a4200370300200141f0006a41106a22034200370300200141f0006a41086a220042003703002001420037037041a6d4c800ad4280808080b002841001220229000021062000200241086a290000370300200120063703702002102941f8d7ca00ad4280808080d00084100122022900002106200141e0006a41086a2204200241086a2900003703002001200637036020021029200320012903602206370300200141c0006a41086a2000290300370300200141c0006a41106a2006370300200141c0006a41186a200429030037030020012001290370370340412010272200450d0120002001290320370000200041186a200141206a41186a290300370000200041106a200141206a41106a290300370000200041086a200141206a41086a290300370000200141c0006aad42808080808004842000ad42808080808004841003200010290b20014190016a24000f0b1039000bf78d0107017f017e127f017e117f097e0d7f230041d0086b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0900010203040506070a000b200341d4076a4101360200200342013702c40720034198e3ca003602c007200341043602b406200341cce3ca003602b0062003200341b0066a3602d007200341c0076a4180a6cc001040000b0240024020022d00000d0020022d00014101470d00200141196a2900002104200141186a2d00002105200141176a2d00002106200141156a2f00002107200141146a2d00002108200141136a2d00002109200141116a2f0000210a200141106a2d0000210b2001410f6a2d0000210c2001410d6a2f0000210d2001410c6a2d0000210e2001410b6a2d0000210f200141096a2f00002110200141086a2d00002111200141076a2d00002112200141056a2f00002113200141046a2d00002114200141036a2d0000211520012f000121162002411a6a2901002117200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d0000211c200241126a2f0100211d200241116a2d0000211e200241106a2d0000211f2002410e6a2f010021202002410d6a2d000021212002410c6a2d000021222002410a6a2f01002123200241096a2d00002124200241086a2d00002125200241066a2f01002126200241056a2d00002127200241046a2d00002128200241026a2f01002102200341286a200141286a2903002229200141306a290300222a42c0843d420010e007200341186a2003290328222b200341286a41086a290300222c42c0fb42427f10d507200341086a202b202c42d08603420010d5072003201737038804200320183a008704200320193a0086042003201a3b0184042003201b3a0083042003201c3a0082042003201d3b0180042003201e3a00ff032003201f3a00fe03200320203b01fc03200320213a00fb03200320223a00fa03200320233b01f803200320243a00f703200320253a00f603200320263b01f403200320273a00f303200320283a00f203200320023b01f0032003200341086a41086a2903002003290308222b202920032903187c2217421480222ca7417f201742d086037e2217428080808080c8d007541b2017202c42c0fb427e7c42a0c21e566aad7c2217202b54ad7c222b420020174280a094a58d1d56202b420052202b501b22011b222b37038005200320174280a094a58d1d20011b22173703f8042003200341f0036a3602e0012003200341f0036a3602e8022003200341e8026a3602c8072003200341e0016a3602c4072003200341f8046a3602c007200341b0066a200341f0036a200341c0076a108e040240024020032802b0064101470d0020032d00b4064104460d0141832c21010c030b200341b0066a41086a2903004201520d00200341b0066a41106a290300212c20032802e8022101200341f8076a200341b0066a41186a290300370300200341f0076a202c370300200341c0076a41086a41003a0000200341c9076a2001290000370000200341d1076a200141086a290000370000200341d9076a200141106a290000370000200341e1076a200141186a290000370000200341033a00c007200341c0076a10cb010b4197dec900ad4280808080800184222c10012201290000212d2001290008212e2001102941a0b9ca00ad4280808080d00184222f1001220129000021302001290008213120011029200320313703900520032030370388052003202e370380052003202d3703f8042003200341f8046a412010fc012003280204210220032802002118202c10012201290000212c2001290008212d20011029202f10012201290000212e2001290008212f200110292003202f370390052003202e370388052003202d370380052003202c3703f80420032002410020181b220241016a3602c007200341f8046aad4280808080800484200341c0076aad4280808080c000841003200341c0076a41186a2219200341f0036a41186a290300370300200341c0076a41106a221a200341f0036a41106a290300370300200341c0076a41086a221b200341f0036a41086a290300370300200320032903f0033703c007200341b0066a200210d00420033502b806212c20032802b0062118412010272201450d1b200120032903c007370000200141186a2019290300370000200141106a201a290300370000200141086a201b2903003700002001412041c000102b2201450d1b20012029370020200141286a202a370000200141c000418001102b2201450d1b2001201737005020012004370048200120053a0047200120063a0046200120073b0044200120083a0043200120093a00422001200a3b00402001200b3a003f2001200c3a003e2001200d3b003c2001200e3a003b2001200f3a003a200120103b0038200120113a0037200120123a0036200120133b0034200120143a0033200120153a0032200120163b0030200141d8006a202b370000202c4220862018ad842001ad4280808080800c84100320011029024020032802b406450d00201810290b200341cc076a2002360200200341c8076a41003a00002003410e3a00c007200341c0076a10cb010c100b41822c21010b20004200370308200041206a411c3602002000411c6a41a3ddc900360200200041186a2001360200420121170c180b200241036a2d0000211820022f00012119200141046a280200211b02400240024020022d0000221a417f6a220141034b0d00024020010e0400010102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b4182ac0421012019201841107472201a4100477241ff01710d010b4197dec900ad4280808080800184100122012d000f211d20012d000e211e20012f000c211f20012d000b212020012d000a212120012f0008212220012d0007212320012d0006212420012f0004212520012d0003212620012d0002212720012f0000212820011029419fdec900ad428080808090018410012201290008211720012d0007210520012d0006210620012f0004210720012d0003210820012d0002210920012f0000210a200110292003201b3602c0012003200341c0016aad4280808080c00084100222012900003703800620011029200341cc076a200341c4016a360200200320034188066a3602c4072003200341c0016a3602c807200320034180066a3602c007200341f0036a200341c0076a107520032802f803221a41206a2202417f4c0d0a20032802f003211c0240024020020d0041002118410121010c010b200210272201450d0a200221180b024002402018410f4d0d00201821190c010b201841017422194110201941104b1b22194100480d08024020180d002019102722010d010c1b0b20182019460d00200120182019102b2201450d1a0b2001201d3a000f2001201e3a000e2001201f3b000c200120203a000b200120213a000a200120223b0008200120233a0007200120243a0006200120253b0004200120263a0003200120273a0002200120283b00000240024020194170714110460d00201921180c010b201941017422184120201841204b1b22184100480d0820192018460d00200120192018102b2201450d1a0b20012017370018200120053a0017200120063a0016200120073b0014200120083a0013200120093a00122001200a3b001002400240201841606a201a490d00201821190c010b201a415f4b0d08201841017422192002201920024b1b22194100480d0820182019460d00200120182019102b2201450d1a0b200141206a201c201a10e4071a024020032802f403450d00201c10290b200341c0076a2001200210d104024020032903c00742015222180d002002ad4220862001ad8410040b200341f0036a200341c8076a41e00010e4071a200341c0076a200341f0036a41e00010e4071a024020180d00200341e8026a200341c0076a41e00010e4071a02402019450d00200110290b200341b0066a41066a200341e8026a41e00010e4071a200341f8046a200341b0066a41e60010e4071a200341e0016a200341f8046a41066a41e00010e4071a20032903f00121172003200341f8016a290300222b37038005200320173703f804024002402017202b8450450d00420021294200212c0c010b2003200341e0016a41206a22013602f003200341b0066a2001200341f8046a200341f0036a10a905200341b0066a41206a290300212c20032903c806212920032903b0064201520d0020032903b8062104200341f8076a200341b0066a41106a290300370300200341f0076a2004370300200341c0076a41086a41003a0000200341c9076a2001290000370000200341d1076a200141086a290000370000200341d9076a200141106a290000370000200341e1076a200141186a290000370000200341033a00c007200341c0076a10cb010b200341386a2029202c10810202402003290338a7450d00200341386a41106a29030021292003290340212c200342f0f2bda1a7ee9cb9f9003703b006200341c0076a200341b0066a108202200341c0076a202c2029108002200341d8076a2029370300200341c0076a41106a202c370300200341c8076a41063a00002003410e3a00c007200341c0076a10cb010b200341d8076a202b370300200341c0076a41106a2017370300200341cc076a201b360200200341c8076a41033a00002003410e3a00c007200341c0076a10cb010c0f0b02402019450d00200110290b4183ac0421010b20004200370308200041206a41143602002000411c6a418fddc900360200200041186a2001360200420121170c170b200241036a2d0000211920022f0001211a200141046a28020021010240024020022d0000221b417f6a221841034b0d00024020180e0400010102000b200241046a2d00000d00200241086a28020041056c2002410c6a28020041036c4f0d010b4182ac042102201a201941107472201b4100477241ff01710d050b200341c0076a200110d004200341d0006a20032802c007220220032802c8074180a6cc004100410010c70120032802502118024020032802c407450d00200210290b4183ac04210220184101470d044197dec900ad42808080808001841001220229000021172002290008212b200210294184baca00ad42808080809001841001220229000021292002290008212c200210292003202c3703900520032029370388052003202b37038005200320173703f804200341c0076a200341f8046a108f0302400240024020032802c00722020d0041002119200341003602b806200342043703b0060c010b20032902c4072117200320023602b006200320173702b4062017422088a722182017a72219470d010b200341b0066a2019410110980120032802b406211920032802b006210220032802b80621180b200220184102746a20013602002003201841016a22183602b8064197dec900ad42808080808001841001220129000021172001290008212b200110294184baca00ad42808080809001841001220129000021292001290008212c200110292003202c3703900520032029370388052003202b37038005200320173703f804024020020d00200341f8046aad428080808080048410040c0d0b200341203602c4072003200341f8046a3602c00720022018200341c0076a10a304201941ffffffff0371450d0c200210290c0c0b2001412c6a280200211e200141286a2802002118200141246a280200211d200341e0016a41186a200141196a290000370300200341e0016a41106a200141116a290000370300200341e0016a41086a200141096a290000370300200320012900013703e0014102210120022d00000d1320022d00014101470d13200241196a2d00002101200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d0000211c200241126a2f0100211f200241116a2d00002120200241106a2d000021212002410e6a2f010021222002410d6a2d000021232002410c6a2d000021242002410a6a2f01002125200241096a2d00002126200241086a2d00002127200241066a2f01002128200241056a2d00002105200241046a2d00002106200241026a2f0100210720032002411a6a29010037038003200320013a00ff02200320193a00fe022003201a3b01fc022003201b3a00fb022003201c3a00fa022003201f3b01f802200320203a00f702200320213a00f602200320223b01f402200320233a00f302200320243a00f202200320253b01f002200320263a00ef02200320273a00ee02200320283b01ec02200320053a00eb02200320063a00ea02200320073b01e8020240201e41818001490d004183ddc900211c410c211b410321014116211a410221190c150b201ead222c422086201dad84101022012900002117200141086a290000212b200141106a2900002129200341f0036a41186a200141186a290000370300200341f0036a41106a2029370300200341f0036a41086a202b370300200320173703f00320011029200341c0076a200341f0036a10a307200341f0006a20032802c007220220032802c8074180a6cc004100410010c70120032802702101024020032802c407450d00200210290b20014101460d122003200341e0016a3602c4072003200341f0036a3602c007200341f8046a200341c0076a108106200341c0076a200341f8046a10a407200341e8006a20032802c007220220032802c8074180a6cc004100410010c70120032802682101024020032802c407450d00200210290b20014101460d12200341d8006a202c42004280c2d72f420010d50720032003290358222b4280c8afa0257c2217370380062003200341d8006a41086a2903002017202b54ad7c222b370388062003200341e8026a3602a0062003200341e8026a3602c0012003200341c0016a3602c8072003200341a0066a3602c407200320034180066a3602c007200341b0066a200341e8026a200341c0076a108e040240024020032802b0064101470d00200341bc066a280200211b200341b0066a41086a280200211c20032d00b706210220032d00b606211920032d00b506211a20032d00b40621010c010b410421010240200341b0066a41086a2903004201520d00200341b0066a41106a290300212920032802c0012102200341f8076a200341b0066a41186a290300370300200341f0076a2029370300200341c0076a41086a41003a0000200341c9076a2002290000370000200341d1076a200241086a290000370000200341d9076a200241106a290000370000200341e1076a200241186a290000370000200341033a00c007200341c0076a10cb010b0b200141ff01714104470d14200341c0076a200341f0036a10a30720032802c0072101200320032802c8073602b406200320013602b006201d201e200341b0066a10a104024020032802c407450d00200110290b200341f0076a202b370300200341e8076a201737030020034188086a4100360200200341c0076a41106a200341e8026a41086a290300370300200341c0076a41186a200341e8026a41106a290300370300200341e0076a200341e8026a41186a29030037030020034194086a200341f0036a41086a2903003702002003419c086a200341f0036a41106a290300370200200341a4086a200341f0036a41186a290300370200200342013703c007200320032903e8023703c8072003420837038008200341003602f807200320032903f00337028c08200341c4086a200341e0016a41186a290300370200200341bc086a200341e0016a41106a290300370200200341b4086a200341e0016a41086a290300370200200320032903e0013702ac08200341b0066a200341f8046a10a40720032802b0062101200320032802b806360284062003200136028006200341c0076a20034180066a10a107024020032802b406450d00200110290b200341c0076a41086a41073a0000200341c9076a20032903f804370000200341d1076a200341f8046a41086a290300370000200341d9076a200341f8046a41106a290300370000200341e1076a200341f8046a41186a2903003700002003410e3a00c007200341c0076a10cb012018450d0b201d10290c0b0b200341d8016a200141196a290000370300200341d0016a200141116a290000370300200341c8016a200141096a290000370300200320012900013703c001024020022d00014101470d0020022d000041ff01710d0020032002411a6a290100370398062003200241026a2901003703800620032002410a6a290100370388062003200241126a29010037039006200341a0066a200341c0016a10a407200341c0076a20032802a006220120032802a80610a50720032903c0072117200341f8046a200341c8076a41880110e4071a0240024020174202510d00200341f0036a200341f8046a41880110e4071a024020032802a406450d00200110290b200341e8026a200341f0036a41880110e4071a200341e0016a200341e8026a41880110e4071a200320173703b006200341b0066a41086a200341e0016a41880110e4071a200341f0036a41186a2201200341b0066a41206a290300370300200341f0036a41106a2202200341b0066a41186a290300370300200341f0036a41086a2218200341b0066a41106a290300370300200320032903b8063703f00320174201520d01200341e0066a290300212b200341d8066a2903002129200341c0076a410e6a2018290300370100200341c0076a41166a2002290300370100200341c0076a411e6a20012903002217370100200341f8046a411e6a22192017370100200320032903f0033701c607200341f8046a41086a200341c0076a41086a290100370300200341f8046a41106a200341c0076a41106a290100370300200341f8046a41186a200341c0076a41186a290100370300200320032901c0073703f804200120192901003703002002200341f8046a41166a2901003703002018200341f8046a410e6a290100370300200320032901fe043703f003200341f0036a20034180066a412010e7070d01200341c0076a200341fc066a10a30720033502c80742208620032802c0072201ad841004024020032802c407450d00200110290b200341c0076a200341c0016a10a40720033502c80742208620032802c0072201ad841004024020032802c407450d00200110290b200320293703e8022003202b3703f00202402029202b84500d00200320034180066a3602e001200341f8046a20034180066a200341e8026a200341e0016a10ea0320032903f8044201520d002003290380052117200341f8076a200341f8046a41106a290300370300200341f0076a2017370300200341c0076a41086a41003a0000200341c9076a200329038006370000200341d1076a20034180066a41086a290300370000200341d9076a20034180066a41106a290300370000200341e1076a20034198066a290300370000200341033a00c007200341c0076a10cb010b200341c0076a41086a410a3a0000200341c9076a20032903c001370000200341d1076a200341c0016a41086a290300370000200341d9076a200341d0016a290300370000200341e1076a200341d8016a2903003700002003410e3a00c007200341c0076a10cb01200341f4066a2802002201450d0d200141306c450d0d20032802f00610290c0d0b024020032802a406450d00200110290b41eddcc9002101410a21024180801021180c110b41e4dcc900210141092102418080142118200341f4066a2802002219450d10201941306c450d1020032802f0061029410321190c110b41022119410021180c100b200141386a2903002117200141306a290300212b2001412c6a280200211a200141286a2802002118200141246a280200211920034180036a200141196a290000370300200341f8026a200141116a290000370300200341f0026a200141096a290000370300200320012900013703e80220032002411a6a290100370390052003200241026a2901003703f80420032002410a6a290100370380052003200241126a290100370388050240024020022d00014101470d0020022d000041ff01710d00200341f0036a41186a200341f8046a41186a2202290300370300200341f0036a41106a200341f8046a41106a221b290300370300200341f0036a41086a200341f8046a41086a221c290300370300200320032903f8043703f0034182ac0c2101200341f0036a10a607450d0f201aad4220862019ad84101022012900002129200141086a290000212c200141106a29000021042002200141186a290000370300201b2004370300201c202c370300200320293703f80420011029200341c0076a200341f8046a10a307200341f8006a20032802c007220220032802c8074180a6cc004100410010c70120032802782101024020032802c407450d00200210290b20014101460d012003200341e8026a3602c4072003200341f8046a3602c007200341b0066a200341c0076a108106200341c0076a200341f8046a10a30720032802c0072101200320032802c8073602e401200320013602e0012019201a200341e0016a10a104024020032802c407450d00200110290b20032903b006212920032903b806212c20032903c0062104200341e1076a20032903c806370000200341d9076a2004370000200341d1076a202c370000200341c9076a2029370000200341c0076a41086a41073a00002003410e3a00c007200341c0076a10cb01413010272201450d162001202b370320200120032903f003370000200141286a2017370300200141186a200341f0036a41186a290300370000200141106a200341f0036a41106a290300370000200141086a200341f0036a41086a29030037000020034184086a42818080801037020020034194086a200341f8046a41086a2903003702002003419c086a200341f8046a41106a290300370200200341a4086a200341f8046a41186a2903003702002003200136028008200341003602f807200342003703c007200320032903f80437028c08200341b4086a200341e8026a41086a290300370200200341bc086a200341e8026a41106a290300370200200341c4086a200341e8026a41186a290300370200200320032903e8023702ac08200341e0016a200341b0066a10a40720032802e0012102200320032802e801360284062003200236028006200341c0076a20034180066a10a107024020032802e401450d00200210290b200110292018450d0b201910290c0b0b4182ac0c21010c0e0b4183ac0c21010c0d0b200141306a2903002117200141286a290300212b200341c0016a41186a200141196a290000370300200341c0016a41106a200141116a290000370300200341c0016a41086a200141096a290000370300200320012900013703c0014182ac1021010240024002400240024002400240024020022d00000d0020022d00014101470d00200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d0000211c200241126a2f0100211d200241116a2d0000211e200241106a2d0000211f2002410e6a2f010021202002410d6a2d000021212002410c6a2d000021222002410a6a2f01002123200241096a2d00002124200241086a2d00002125200241066a2f01002126200241056a2d00002127200241046a2d00002128200241026a2f0100210520032002411a6a29010037039806200320183a009706200320193a0096062003201a3b0194062003201b3a0093062003201c3a0092062003201d3b0190062003201e3a008f062003201f3a008e06200320203b018c06200320213a008b06200320223a008a06200320233b018806200320243a008706200320253a008606200320263b018406200320273a008306200320283a008206200320053b01800620034180066a10a607450d00200341f8046a41186a200341c0016a41186a290300370300200341f8046a41106a200341c0016a41106a290300370300200341f8046a41086a200341c0016a41086a290300370300200320032903c0013703f804200341a0066a200341f8046a10a707200341c0076a20032802a006220120032802a80610a50720032903c0072129200341f8046a200341c0076a41086a41880110e4071a024020294202510d00200341f0036a200341f8046a41880110e4071a024020032802a406450d00200110290b200341e8026a200341f0036a41880110e4071a200341e0016a200341e8026a41880110e4071a200320293703b006200341b0066a41086a200341e0016a41880110e4071a200341f0036a41186a20034180066a41186a290300370300200341f0036a41106a20034180066a41106a290300370300200341f0036a41086a20034180066a41086a29030037030020032003290380063703f00320032802f006211a41002101200341f8066a280200221f41014b0d020240201f0e020004000b200341c0076a41186a200341f0036a41186a290300370300200341c0076a41106a200341f0036a41106a290300370300200341c0076a41086a200341f0036a41086a290300370300200320032903f0033703c00741002118200341c0076a21020c040b024020032802a406450d00200110290b4183ac1021010b200041206a410a3602002000411c6a41eddcc900360200200041186a200136020020004200370308420121170c190b201f210203402002410176221820016a22192001201a201941306c6a200341f0036a412010e7074101481b2101200220186b220241014b0d000b0b201a200141306c6a2202200341f0036a412010e7072218450d01200341c0076a41186a200341f0036a41186a290300370300200341c0076a41106a200341f0036a41106a290300370300200341c0076a41086a200341f0036a41086a290300370300200320032903f0033703c007200341c0076a2102201f2018411f7620016a2218490d040b0240201f200341f4066a280200470d00200341f0066a201f410110900120032802f006211a0b201a201841306c6a220141306a2001201f20186b41306c10e5071a200141286a20173703002001202b370320200141186a200241186a290300370300200141106a200241106a290300370300200141086a200241086a290300370300200120022903003703002003201f41016a221f3602f8060c010b201f20014d0d0120032901f203212920032901fa03212c200328018204211820032f01860421192003290388042104200220032f01f0033b0100201a200141306c6a2201202b37032020012004370318200120193b0116200120183601122001202c37010a20012029370102200141286a20173703000b200341c0076a10a80720032802c007210a0240201f450d00200a20032802c80722014105746a211b20032802f0062120200a410020011b2102200a41206a200a20011b21014100211e4100211c0340201c221d41016a211c2020201d41306c6a211a024002400340024020020d00410021020c020b2002201a412010e707221841004a0d01410020012001201b4622191b21022001200141206a20191b2219210120184100480d000b024002400240201e0d004100211e0c010b201d201e6b2201201f4f0d01200341f8046a41286a22182020200141306c6a220141286a221d290300370300200341f8046a41206a2221200141206a2222290300370300200341f8046a41186a2223200141186a2224290300370300200341f8046a41106a2225200141106a2226290300370300200341f8046a41086a2227200141086a2228290300370300200320012903003703f804201a41086a22052903002117201a41106a2206290300212b201a41186a22072903002129201a41206a2208290300212c201a2903002104201d201a41286a22092903003703002022202c370300202420293703002026202b37030020282017370300200120043703002009201829030037030020082021290300370300200720232903003703002006202529030037030020052027290300370300201a20032903f8043703000b201921010c020b2001201f4180bdc7001036000b201e41016a211e0b201c201f470d000b201e417f6a201f4f0d002003201f201e6b3602f8060b024020032802c40741ffffff3f71450d00200a10290b200341f8046a41186a4200370300200341f8046a41106a22184200370300200341f8046a41086a22014200370300200342003703f8044196ebca00ad42808080808002841001220229000021172001200241086a290000370300200320173703f8042002102941f0edca00ad4280808080f00084100122022900002117200341e8026a41086a2219200241086a290000370300200320173703e80220021029201820032903e8022217370300200341c0076a41086a2001290300370300200341c0076a41106a2017370300200341c0076a41186a2019290300370300200320032903f8043703c007200341f8046a200341c0076a10a90720032802f804210120032902fc042117200341003602c807200342013703c007200341c0076a41002017420020011b2217422088a7220241306c221941306d109e012017a7211a2001410820011b211b20032802c807211802402002450d0020032802c00720184105746a2101201b21020340200241086a2900002117200241106a290000212b20022900002129200141186a200241186a290000370000200141106a202b370000200141086a201737000020012029370000201841016a2118200141206a2101200241306a2102201941506a22190d000b0b200320183602c8070240201a450d00201a41306c450d00201b10290b024020032802c40741ffffff3f71450d0020032802c00710290b024020032802f806201841016a410176490d0020032802e8064101460d00200341c0076a41186a4200370300200341c0076a41106a22184200370300200341c0076a41086a22014200370300200342003703c00741b3e6ca00ad4280808080e000841001220229000021172001200241086a290000370300200320173703c0072002102941c9e6ca00ad4280808080e00084100122022900002117200341e8026a41086a2219200241086a290000370300200320173703e80220021029201820032903e8022217370300200341f8046a41086a22022001290300370300200341f8046a41106a22182017370300200341f8046a41186a221a2019290300370300200320032903c0073703f80420034180016a200341f8046a412010fc01200341ec066a20032802840141c0f0006a41c0f0002003280280011b360200200341013602e806201a200341c0016a41186a22192903003703002018200341c0016a41106a221a2903003703002002200341c0016a41086a2218290300370300200320032903c0013703f804200141083a00002003410e3a00c007200341c9076a20032903c001370000200341d1076a2018290300370000200341d9076a201a290300370000200341e1076a2019290300370000200341c0076a10cb010b200341c0076a200341b0066a41900110e4071a200341f8046a200341c0016a10a40720032802f804210120032003280280053602f403200320013602f003200341c0076a200341f0036a10a107024020032802fc04450d00200110290b20034184086a2802002201450d0a200141306c450d0a20032802800810290c0a0b2001201f41f4d8ca001036000b2018201f1041000b20004200370308200041206a41143602002000411c6a418fddc900360200200041186a2002360200420121170c110b1032000b4102211820022d00000d0720022d00014101470d07200141186a2d0000210f200141176a2d00002110200141156a2f00002111200141146a2d00002112200141136a2d00002113200141116a2f00002114200141106a2d000021152001410f6a2d000021162001410d6a2f000021322001410c6a2d000021332001410b6a2d00002134200141096a2f00002135200141086a2d00002136200141076a2d00002137200141056a2f00002138200141046a2d00002139200141036a2d0000213a20012f0001213b2003200141196a290000222a370390052003200f3a008f05200320103a008e05200320113b018c05200320123a008b05200320133a008a05200320143b018805200320153a008705200320163a008605200320323b018405200320333a008305200320343a008205200320353b018005200320363a00ff04200320373a00fe04200320383b01fc04200320393a00fb042003203a3a00fa042003203b3b01f80420034180066a200341f8046a10a707200341c0076a200328028006220120032802880610a50720032903c0072117200341f8046a200341c8076a41880110e4071a0240024002400240024020174202510d00200341f0036a200341f8046a41880110e4071a0240200328028406450d00200110290b200341e8026a200341f0036a41880110e4071a200341e0016a200341e8026a41880110e4071a200320173703b006200341b0066a41086a200341e0016a41880110e4071a20032802e8064101460d0141dbdcc9002119410621010c020b0240200328028406450d00200110290b41eddcc9002119410a2102410421010c020b200341c0076a41186a4200370300200341c0076a41106a22184200370300200341c0076a41086a22014200370300200342003703c00741b3e6ca00ad4280808080e000841001220229000021172001200241086a290000370300200320173703c0072002102941c9e6ca00ad4280808080e00084100122022900002117200341e8026a41086a2219200241086a290000370300200320173703e80220021029201820032903e8022217370300200341f8046a41086a2001290300370300200341f8046a41106a2017370300200341f8046a41186a2019290300370300200320032903c0073703f804200341b8016a200341f8046a412010fc0120032802bc01410020032802b8011b200341ec066a2802004f0d0241d2dcc9002119410721010b41092102200341f4066a2802002218450d00201841306c450d0020032802f00610290b410321180c090b200341c0076a200341fc066a10a30720033502c80742208620032802c0072201ad841004024020032802c407450d00200110290b2003202a3703d8072003200f3a00d707200320103a00d607200320113b01d407200320123a00d307200320133a00d207200320143b01d007200320153a00cf07200320163a00ce07200320323b01cc07200320333a00cb07200320343a00ca07200320353b01c807200320363a00c707200320373a00c607200320383b01c407200320393a00c3072003203a3a00c2072003203b3b01c007200341f8046a200341c0076a10a70720033502800542208620032802f8042201ad841004024020032802fc04450d00200110290b200341c0076a200341b0066a41900110e4071a20034188086a280200212820034184086a280200213c2003280280082124200341f0036a10a80720032802f003210a0240024020280d00410021280c010b200a20032802f80322014105746a211b200a410020011b2102200a41206a200a20011b21014100211e4100211c0340201c221d41016a211c2024201d41306c6a211a024002400340024020020d00410021020c020b2002201a412010e707221841004a0d01410020012001201b4622191b21022001200141206a20191b2219210120184100480d000b024002400240201e0d004100211e0c010b201d201e6b220120284f0d01200341f8046a41286a22182024200141306c6a220141286a221d290300370300200341f8046a41206a221f200141206a2220290300370300200341f8046a41186a2221200141186a2222290300370300200341f8046a41106a2223200141106a2225290300370300200341f8046a41086a2226200141086a2227290300370300200320012903003703f804201a41086a22052903002117201a41106a2206290300212b201a41186a22072903002129201a41206a2208290300212c201a2903002104201d201a41286a22092903003703002020202c370300202220293703002025202b3703002027201737030020012004370300200920182903003703002008201f290300370300200720212903003703002006202329030037030020052026290300370300201a20032903f8043703000b201921010c020b200120284180bdc7001036000b201e41016a211e0b201c2028470d000b201e450d0020282028201e6b220120282001491b21280b024020032802f40341ffffff3f71450d00200a10290b20284115490d032028410176ad42307e2217422088a70d012017a7223d417f4c0d01203d1027220b450d0041002102200341003602f803200342043703f003202441506a210e202441907f6a213e410421184100210c2028212303402023211b410021234101211c0240201b417f6a220d450d000240024002400240024002402024200d41306c6a220141206a290300201b41306c221a20246a41406a2219290300222b54200141286a2903002229201941086a29030022175420292017511b0d00201b417e6a211e203e201a6a2101410021234100211903400240201e2019470d00201b211c0c080b202b2001290300222c5a211a2017200141086a290300222951211c201720295a211d200141506a2101201941016a2119202c212b20292117201a201d201c1b0d000b201941016a211c2019417f73201b6a211a0c010b203e201b41066c410374221e6a2101200d211a024003400240201a4101470d004100211a0c020b202b2001290300222c5421192017200141086a290300222951211c2017202954211d200141506a2101201a417f6a211a202c212b202921172019201d201c1b0d000b0b201b201a490d02201b20284b0d01201b201a6b221c410176221d450d00200e201e6a21012024201a41306c6a21190340200341f8046a41286a221e201941286a221f290300370300200341f8046a41206a2220201941206a2221290300370300200341f8046a41186a2222201941186a2223290300370300200341f8046a41106a2225201941106a2226290300370300200341f8046a41086a2227201941086a2205290300370300200320192903003703f804200141086a22062903002117200141106a2207290300212b200141186a22082903002129200141206a2209290300212c200141286a220a290300210420192001290300370300201f20043703002021202c370300202320293703002026202b37030020052017370300200a201e29030037030020092020290300370300200820222903003703002007202529030037030020062027290300370300200120032903f804370300200141506a2101201941306a2119201d417f6a221d0d000b0b0240201a0d00201a21230c050b0240201c41094d0d00201a21230c050b201b20284b0d022024201a41306c6a211f0340201b201a417f6a2223490d040240201b20236b221c4102490d002024201a41306c6a220141206a221d2903002024202341306c6a221941206a221e29030022295a200141286a2220290300222b201941286a222129030022175a202b2017511b0d002019290300212b20192001290300370300200341f8046a41186a2222201941186a2225290300370300200341f8046a41106a2226201941106a2227290300370300200341f8046a41086a2205201941086a22062903003703002006200141086a2903003703002027200141106a2903003703002025200141186a290300370300201e201d290300370300202120202903003703002003202b3703f8040240201c4103490d00200d211d201f211e20194180016a29030020295a20194188016a290300222b20175a202b2017511b0d0002400340201e220141286a200141d8006a290300370300200141206a200141d0006a290300370300200141186a200141c8006a290300370300200141106a200141c0006a290300370300200141086a200141386a2903003703002001200141306a221e290300370300201a201d417f6a221d460d0120014180016a29030020295a20014188016a290300222b20175a202b2017511b450d000b0b200141306a21010b20012029370320200120032903f804370300200141286a2017370300200141186a2022290300370300200141106a2026290300370300200141086a20052903003703000b2023450d05201f41506a211f2023211a201c410a4f0d050c000b0b201b20284180cac700104b000b201a201b4180cac700104c000b201b201a417f6a2223490d00201b20284190cac700104b000b2023201b4190cac700104c000b0240200c20032802f403470d00200341f0036a200c4101108d0120032802f003211820032802f8032202210c0b2018200c4103746a2201201c360204200120233602002003200241016a22023602f8032002210c024020024102490d000240024003400240024002400240024020182002417f6a4103746a2201280200450d00200241037420186a221b41746a280200221a200128020422194b0d010b20024103490d022001280204211920182002417d6a22204103746a28020421010c010b4102210c200241024d0d0620182002417d6a22204103746a28020422012019201a6a4d0d004103210c200241034d0d06201b41646a2802002001201a6a4b0d050b20012019490d010b2002417e6a21200b02400240024002400240024002402002202041016a22214d0d00200220204d0d012018202041037422256a2201280204222620012802006a22012018202141037422276a22022802002222490d02200120284b0d032024202241306c6a221e2002280204221f41306c22026a2119200141306c2118200120226b221b201f6b2201201f4f0d04200b2019200141306c220210e407221b20026a211a201f4101480d0520014101480d05200e20186a21182019210103402018200141506a221c201a41506a221d201a41706a2202290300200141706a221929030054200241086a2903002217201941086a290300222b542017202b511b22191b2202290300370300201841086a200241086a290300370300201841106a200241106a290300370300201841186a200241186a290300370300201841206a200241206a290300370300201841286a200241286a290300370300201a201d20191b211a0240201e201c200120191b2201490d00201b21020c080b201841506a2118201b2102201b201a490d000c070b0b2021200241a0cac7001036000b2020200241b0cac7001036000b2022200141c0cac700104c000b2001202841c0cac700104b000b200b201e200210e407221d20026a211a0240201f4101480d00201b201f4c0d00202420186a211c201d2102201e21010340200120192002201941206a290300200241206a29030054201941286a2903002217200241286a290300222b542017202b511b221b1b2218290300370300200141086a201841086a290300370300200141106a201841106a290300370300200141186a201841186a290300370300200141206a201841206a290300370300200141286a201841286a2903003703002002200241306a201b1b2102200141306a2101201941306a2019201b1b2219201c4f0d03201a20024b0d000c030b0b201e2101201d21020c010b20192101201b21020b20012002201a20026b221820184130706b10e4071a024020032802f803220120204d0d0020032802f003221820256a22022026201f6a36020420022022360200200120214d0d02201820276a2202200241086a20012021417f736a41037410e5071a20032001417f6a22023602f803200241014b0d010c030b0b2020200141d0cac7001036000b202120011042000b2002210c0b2023450d030c000b0b1039000b1038000b024020032802f40341ffffffff0171450d00201810290b203d4130702101203d4130490d01203d2001460d01200b10290c010b20284102490d002028417f6a21182024202841306c6a211a4100211b0340024002400240202820182201417f6a2218490d00202820186b22194102490d022024200141306c6a220141206a221c2903002024201841306c6a220241206a221d29030022295a200141286a221e290300222b200241286a221f29030022175a202b2017511b0d022002290300212b20022001290300370300200341f8046a41186a2220200241186a2221290300370300200341f8046a41106a2222200241106a2223290300370300200341f8046a41086a2225200241086a22262903003703002026200141086a2903003703002023200141106a2903003703002021200141186a290300370300201d201c290300370300201f201e2903003703002003202b3703f80420194103490d01201b2119201a211c20024180016a29030020295a20024188016a290300222b20175a202b2017511b0d010340201c220141506a22022001290300370300200241286a200141286a290300370300200241206a200141206a290300370300200241186a200141186a290300370300200241106a200141106a290300370300200241086a200141086a2903003703002019417f6a2219450d02200141306a211c200141d0006a29030020295a200141d8006a290300222b20175a202b2017511b0d020c000b0b2018202841f0c9c700104c000b20012029370320200120032903f804370300200141286a2017370300200141186a2020290300370300200141106a2022290300370300200141086a20252903003703000b201b41016a211b201a41506a211a20180d000b0b200342f0f2bda1a7ee9cb9f9003703f804200341e0016a200341f8046a108202200342f0f2bda1a7ee9cb9f9003703f804200341f0036a200341f8046a108202200341e8026a200341f0036a10a802200341f8046a20032802e802220120032802f00210a90220032903f804211720034188056a290300212b2003290380052129024020032802ec02450d00200110290b2028202841017622014d0d014200202b4200201742015122021b222b2029420020021b22174280c8afa02554ad7d222920174280b8d0df5a7c222c2017562029202b56201742ffc7afa025561b22021b22172024200141306c6a220141286a290300222b200129032022294200202c20021b222c56202b201756202b2017511b22011b212b202c202920011b2117024020032903c0074201520d00200341e8026a41186a200341c0076a41206a290300370300200341e8026a41106a200341c0076a41186a290300370300200341f0026a200341c0076a41106a290300370300200320032903c8073703e802200341c0076a41286a29030021292003200341c0076a41306a290300222c37038806200320293703800602402029202c84500d002003200341e8026a3602c001200341f0036a200341e8026a20034180066a200341c0016a10ea0320032903f0034201520d0020032903f8032129200341b0056a200341f0036a41106a290300370300200341a8056a2029370300200341f8046a41086a41003a000020034181056a20032903e80237000020034189056a200341e8026a41086a29030037000020034191056a200341e8026a41106a29030037000020034199056a20034180036a290300370000200341033a00f804200341f8046a10cb010b200341e8026a200341ac086a412010e707450d00200341a8016a2017202b42e400420010e00720034198016a20032903a8012229200341a8016a41086a290300222c429c7f427f10d50720034188016a2029202c4214420010d507200341f8046a200341e0016a200341e8026a200329038801222c20172003290398017ca741ff0071220141056e2202200141146c2002419c7f6c6a41fcff037141324b6aad7c222920034188016a41086a2903002029202c54ad7c222c410010e003202b202c7d2017202954ad7d212b201720297d21170b200341f8046a200341e0016a200341ac086a2017202b410010e00320034199056a202a37000020034198056a200f3a000020034197056a20103a000020034195056a20113b000020034194056a20123a000020034193056a20133a000020034191056a20143b000020034190056a20153a00002003418f056a20163a00002003418d056a20323b00002003418c056a20333a00002003418b056a20343a000020034189056a20353b000020034188056a20363a000020034187056a20373a000020034185056a20383b000020034184056a20393a000020034183056a203a3a0000200341f8046a41096a203b3b000020034180056a41093a00002003410e3a00f804200341c8056a2017370300200341d0056a202b370300200341b9056a200341c4086a290200370000200341b1056a200341bc086a290200370000200341a9056a200341b4086a290200370000200341a1056a20032902ac08370000200341f8046a10cb01203c450d00203c41306c450d00202410290b42002117200042003703080c090b200120284184d9ca001036000b0b20004200370308200041206a20023602002000411c6a2019360200200041186a200141ff017141107420187241802c72360200420121170c060b02402018450d00201910290b20004200370308200041206a410c3602002000411c6a41f7dcc900360200200041186a2001360200420121170c050b410321190b20004200370308200041206a20023602002000411c6a2001360200200041186a20184180801c7120197241802c72360200420121170c030b41f7dcc900211c410c211b4116211a41032119410321010c010b0b02402018450d00201d10290b20004200370308200041206a201b3602002000411c6a201c360200200041186a2002411874201941ff017141107472201a41ff017141087472200141ff017172360200420121170b20002017370300200341d0086a24000f0b1030000bf3cb0111037f017e057f017e177f027e087f037e0a7f017e047f017e047f027e027f027e087f230041800b6b2204240002400240024002400240024002400240200141ff01710d00200241ff01714102470d00200441d0036a41186a22054200370300200441d0036a41106a22064200370300200441d0036a41086a22014200370300200442003703d00341cd87cc00ad4280808080a00184100122022900002107200441f8056a41086a2208200241086a290000370300200420073703f8052002102920012008290300370300200420042903f8053703d00341ac84cc00ad4280808080900184100122022900002107200441a8016a41086a2208200241086a290000370300200420073703a80120021029200620042903a8012207370300200441a0066a41086a22022001290300370300200441a0066a41106a22092007370300200441a0066a41186a220a2008290300370300200420042903d0033703a006200441d0006a200441a0066a41204180a6cc004100410010c70120042802504101460d01200542003703002006420037030020014200370300200442003703d00341d787cc00ad42808080809001841001220829000021072001200841086a290000370300200420073703d0032008102941fa87cc00ad4280808080e00084100122082900002107200441a0086a41086a2205200841086a290000370300200420073703a00820081029200620042903a00822073703002002200129030037030020092007370300200a2005290300370300200420042903d0033703a006200441a0086a200441a0066a10a60320042802a0082201410420011b210b200341086a280200220c20042902a408420020011b220d422088a7220e4b0d03200c41ffffffff0371200c460d020c070b200041023a00000c040b200041832e3b0100200041086a4112360200200041046a4181aec700360200200041026a41003a00000c030b200c4102742201417f4c0d040240024002400240024020010d004104210f0c010b20011027220f450d010b41002108200441003602602004200f36025820042001410276220536025c200441d0036a41186a22104200370300200441d0036a41106a22114200370300200441d0036a41086a22124200370300200442003703d00341b3e6ca00ad4280808080e000841001220129000021072012200141086a290000370300200420073703d0032001102941c9e6ca00ad4280808080e00084100122012900002107200441a0086a41086a2202200141086a290000370300200420073703a00820011029200620042903a008370000200641086a22132002290300370000200441a0066a41086a22142012290300370300200441a0066a41106a22152011290300370300200441a0066a41186a22162010290300370300200420042903d0033703a006200441c8006a200441a0066a412010fc010240200e450d0020032802002217200c4190026c6a2118024002400240200c450d00200b200e412c6c6a21094100211941012101200b21082017211a0340201a2802482105024002400240024020014101710d00200220054f0d010b201a4190026a211b20082101034020092001460d02200128020021022001412c6a2208210120022005470d000b200841786a2802004102460d02201a41a0016a2008460d02200841586a201a41f8006a412010e707450d02200041832e3b0100200041086a410f360200200041046a41c7aec700360200200041026a41043a0000200441d8006a21010c050b200041832e3b0100200041086a410f360200200041046a41a8aec700360200200041026a41023a0000200441d8006a21010c040b200041832e3b0100200041086a4110360200200041046a41b7aec700360200200041026a41033a0000200441d8006a21010c030b0240201a280218221c450d00201a280210211d200441a0086a2005108806200441d0036a20042802a008220220042802a80810f90120042802d403410020042802d003410146220a1b210120042802d803211e024020042802a408450d00200210290b024002402001201c6a22014101460d004105211f41d6aec700212041092121200141e4004b0d01201e4100200a1b2102201c410474210a201d41086a21010340200128020020026a2102200141106a2101200a41706a220a0d000b200241a09c014b0d010b200541e807490d01201c410474210103402001450d02200141706a2101201d2d000c2102201d41106a211d20024102470d000b4106211f41dfaec7002120411421210b200041832e3b0100200041086a2021360200200041046a2020360200200041026a201f3a0000200441d8006a21010c030b201a280248210202402019200428025c470d00200441d8006a201941011098012004280258210f200428026021190b200f20194102746a20023602002004201941016a221936026041002101201b211a201b2018470d000b0b200441d0036a41186a22084200370300200441d0036a41106a22054200370300200441d0036a41086a22014200370300200442003703d00341cd87cc00ad4280808080a00184100122022900002107200441f8056a41086a2209200241086a290000370300200420073703f8052002102920012009290300370300200420042903f8053703d00341d983cc00ad4280808080b00184100122022900002107200441a8016a41086a2209200241086a290000370300200420073703a80120021029200620042903a801370000200641086a2009290300370000200441a0066a41086a2001290300370300200441a0066a41106a2005290300370300200441a0066a41186a2008290300370300200420042903d0033703a006200441a0086a200441a0066a109e0320042802a008211b20042902a4082107200441a0086a10a40320042802a408212220042802a008212320042802a8082101200441d0076a41186a200441c4086a290200370300200441d0076a41106a200441bc086a290200370300200441d0076a41086a200441b4086a290200370300200420042902ac083703d0072001200141ffffffff0171470d0a20014103742202417f4c0d0a0240024020020d004104210a0c010b20021027220a450d040b200441003602a8082004200a3602a0082004200241037622243602a40802400240200141037422010d00410021080c010b202320016a2119410021082023210f4100211a03400240200f2802004101470d00024002400240200841014b0d000240024020080e020001000b200f280204211d410021010c030b200f280204211d410021010c010b200f280204211d4100210120082102034020012002410176220520016a2209200a20094103746a280204201d4b1b2101200220056b220241014b0d000b0b0240200a20014103746a2802042202201d460d0020012002201d496a21010b200820014f0d00200120081041000b0240200820042802a408470d00200441a0086a20084101108d0120042802a008210a0b200a20014103746a220241086a2002200820016b41037410e5071a2002201d3602042002201a3602002004200841016a22083602a8080b201a41016a211a2019200f41086a220f470d000b20042802a40821240b200441d0036a41186a22024200370300200441d0036a41106a22054200370300200441d0036a41086a22014200370300200442003703d00341b3e6ca00ad4280808080e0008422251001220929000021262001200941086a290000370300200420263703d0032009102941c9e6ca00ad4280808080e000841001221d2900002126200441a0086a41086a2209201d41086a290000370300200420263703a008201d1029200620042903a008370000200641086a220f2009290300370000200441a0066a41086a221a2001290300370300200441a0066a41106a22192005290300370300200441a0066a41186a221c2002290300370300200420042903d0033703a006200441c0006a200441a0066a412010fc012004280244212720042802402128200242003703002005420037030020014200370300200442003703d00320251001221d29000021252001201d41086a290000370300200420253703d003201d102941cfe6ca00ad4280808080a001841001221d29000021252009201d41086a290000370300200420253703a008201d1029200620042903a008370000200f2009290300370000201a200129030037030020192005290300370300201c2002290300370300200420042903d0033703a006200441a0086a200441a0066a412010cd0120042d00a00821092002200441b9086a2900003703002005200441b1086a2900003703002001200441a9086a290000370300200420042900a1083703d0030240024020094101460d0020044180086a41186a420037030020044180086a41106a420037030020044180086a41086a420037030020044200370380080c010b20044180086a41186a200229030037030020044180086a41106a200529030037030020044180086a41086a2001290300370300200420042903d003370380080b200441d0036a41186a22024200370300200441d0036a41106a22054200370300200441d0036a41086a22014200370300200442003703d00341b1dcc900ad4280808080f000841001220929000021252001200941086a290000370300200420253703d00320091029418886ca00ad4280808080c001841001221d2900002125200441a0086a41086a2209201d41086a290000370300200420253703a008201d1029200620042903a008370000200641086a221c2009290300370000200441a0066a41086a221d2001290300370300200441a0066a41106a220f2005290300370300200441a0066a41186a221a2002290300370300200420042903d0033703a006200441386a200441a0066a412010fc01200428023c211e2004280238211f200242003703002005420037030020014200370300200442003703d00341b3e6ca00ad4280808080e000841001221929000021252001201941086a290000370300200420253703d0032019102941cfe6ca00ad4280808080a001841001221929000021252009201941086a290000370300200420253703a00820191029200620042903a008370000201c2009290300370000201d2001290300370300200f2005290300370300201a2002290300370300200420042903d0033703a006200441a0086a200441a0066a412010cd0120042d00a00821092002200441b9086a2900003703002005200441b1086a2900003703002001200441a9086a290000370300200420042900a1083703d003201e4100201f1b21190240024020094101460d00201a4200370300200f4200370300201d4200370300200442003703a0060c010b201a2002290300370300200f2005290300370300201d2001290300370300200420042903d0033703a0060b20074200201b1b2107201b4101201b1b2129200441a8016a410c6a200441a0066a41086a222a290300370200200441bc016a200441a0066a41106a222b290300370200200441c4016a200441a0066a41186a222c290300370200200420193602a801200420042903a0063702ac01200441003602900120044201370388014101212d200c450d01202941606a212e200a410c6a2120200441a0086aad4280808080800284212f200441a0066aad42808080808004842130200441d0036aad4280808080c0008421312007422088a72132200441a0086a4101722133200441a0086a41106a2134200441a9086a213541002102024003402017211c41f3aec700211a4183ae1c211b4110211e20022008460d01201c4190026a2117201c280248210f20022109024002400240024002400240024002400240034002400240200820094d0d00200a2009410374221d6a221928020421052008200941016a22024d0d012020201d6a2101034020012802002005470d02200141086a21012008200241016a2202470d000b200821020c010b20092008419083cc001036000b20022009490d010240200820024f0d0020022008418083cc00104b000b02402005200f460d002002210920022008460d0c0c010b0b024020044180086a201c41d8006a2205460d00200520044180086a412010e707450d0041aab0c700211a4183aec800211b4115211e0c0b0b200441d0036a41186a22364200370300200441d0036a41106a22374200370300200441d0036a41086a22384200370300200442003703d00341b3e6ca00ad4280808080e000841001220129000021252038200141086a290000370300200420253703d0032001102941c9e6ca00ad4280808080e00084100122012900002125200441a0086a41086a2221200141086a290000370300200420253703a00820011029200620042903a008370000200641086a2021290300370000202a2038290300370300202b2037290300370300202c2036290300370300200420042903d0033703a006200441306a200441a0066a412010fc010240201c4180026a2239280200221a200220096b220141017620014101716a4f0d004183afc700211a4183ae20211b4116211e0c0b0b0240201a20324d0d004199afc700211a4183ae24211b4117211e0c0b0b0240201c41d4006a221a2802004180a0014d0d0041edd3c800211a4183ae38211b0c0b0b200441a0086a201c2802482004280234417f6a417f20042802301b221b10aa0320042802bc08222d4102460d01201a2802002201417f4c0d1520042802b408213a20042802b008213b20042903a808213c20042802a408213d20042802a008213e201c28024c211f0240024020010d00410021094101211e0c010b20011027221e450d0f200121090b0240024020092001490d002009213f0c010b2009410174220c2001200c20014b1b223f4100480d10024020090d00203f1027221e0d010c120b2009203f460d00201e2009203f102b221e450d110b201e201f200110e4072140202c201c4190016a290000370300202b201c4188016a290000370300202a201c4180016a2900003703002004201c2900783703a006201c41086a221e2903002125201c2903002141200441f8056a201c41106a10f005200441a0086a41186a2242201c41c0006a2900003703002034201c41386a2900003703002021201c41306a2900003703002004201c2900283703a00802400240201c28021c22430d004100210c0c010b201c41246a2802002201417f4c0d160240024020010d00410021094101210c0c010b20011027220c450d10200121090b0240024020092001490d002009211f0c010b2009410174221f2001201f20014b1b221f4100480d11024020090d00201f1027220c450d130c010b2009201f460d00200c2009201f102b220c450d120b200c2043200110e4071a2001ad422086201fad8421260b20382021290300370300200428028006214320042802fc05214420042802f8052145200441a0086a200f108906200441286a20042802a008221f20042802a80810fc01200428022c210920042802282101024020042802a408450d00201f10290b024020014101470d002009201b4b0d00200441d0036a200f108a06200441a0086a20042802d003220920042802d803221f108b03024020042802a0082201450d00201fad4220862009ad8410040b20042902a4082146024020042802d403450d00200910290b200441a0086a200f10890620043502a80842208620042802a0082209ad841004024020042802a408450d00200910290b2046420020011b21462001410120011b2109200441a0086a200f10ac03200441d0036a20042802a008221f20042802a808108b0320042902d403204720042802d00322011b2147024020042802a408450d00201f10290b200441a0086a200f10ac0320042802a008211f200420042802a8083602d4032004201f3602d00320092046422088a7200441d0036a10a1042047a7410020011b21482047422088a7410020011b21492001410120011b2101024020042802a408450d00201f10290b200420493602a808200420483602a408200420013602a008200f201b200441a0086a108b062046a7450d00200910290b2026a721490240200c450d00410021480240202d4101460d004188b0c700211a4183aec000211b4115211e0c0a0b02402026422088a722094181808005490d0041f2afc700211a4183ae3c211b4116211e0c0a0b200441a0086a200f10890620042802a008210120043502a80821462004201b41c0f0006a3602d00320464220862001ad8420311003024020042802a408450d00200110290b200441a0086a200f108a0620042802a0082101200420042802a8083602d403200420013602d003200c2009200441d0036a10a10420042802a408450d00200110290b200c4521480240203dad422086203ead84204154203c202554203c2025511b450d00419db0c700211a4183aec400211b410d211e0c090b2004200f3602e006200441f8056a200441e0066a10cc0341002101200441003a00d006200441083a00cf06200420413703a006200420253703a8062004200441f8056a3602f007024002400240204120258450450d0042002125420021410c010b2004200441f8056a3602f0062004200441f0066a3602b0082004200441cf066a3602ac082004200441f0076a3602a8082004200441d0066a3602a4082004200441a0066a3602a008200441d0036a200441f8056a200441a0086a10c802024020042802d0034101470d004200214120042903d80321254101210120042802d40321090c020b200441d0036a41286a290300214120042903f00321254100210120042903d8034201520d0020042903e003213c20042802f0062101200441a0086a41386a203629030037030020352001290000370000203541086a200141086a290000370000203541106a200141106a290000370000203541186a200141186a2900003700002004203c3703d00841002101200441003a00a808200441033a00a008200441a0086a10cb010b0b0240024020010d00204242003703002034420037030020214200370300200442003703a00841dcbec500ad4280808080800184223c1001220129000021462038200141086a290000370300200420463703d0032001102920212038290300370300200420042903d0033703a008419fe3c200ad4280808080d00184224610012209290000214a200441f0066a41086a2201200941086a2900003703002004204a3703f00620091029203420042903f006370000203441086a221b2001290300370000202a2021290300370300202b2034290300370300202c2042290300370300200420042903a0083703a006200441106a200441a0066a412010e301200441106a41106a290300214a2004290318214b20042802102109204242003703002034420037030020214200370300200442003703a008203c1001220f290000213c2038200f41086a2900003703002004203c3703d003200f102920212038290300370300200420042903d0033703a00820461001220f290000213c2001200f41086a2900003703002004203c3703f006200f1029203420042903f006370000201b2001290300370000202a2021290300370300202b2034290300370300202c2042290300370300200420042903a0083703a00620044200204a420020091b223c20417d204b420020091b2241202554ad7d2246204120257d22252041562046203c562046203c511b22011b3703a80820044200202520011b3703a0082030202f10030c010b200941ff01714104470d030b200441003602a808200442013703a008201c2802482109410410272201450d10200441043602a408200420013602a00820012009360000200441043602a808412010272201450d0e20012005290000370000200141186a221b200541186a290000370000200141106a221f200541106a290000370000200141086a223d200541086a2900003700000240024020042802a408220f20042802a80822056b4120490d0020042802a00821090c010b200541206a22092005490d10200f410174223e2009203e20094b1b223e4100480d1002400240200f0d000240203e0d00410121090c020b203e10272209450d130c010b20042802a0082109200f203e460d002009200f203e102b2209450d1220042802a80821050b2004203e3602a408200420093602a0080b200920056a22092001290000370000200941186a201b290000370000200941106a201f290000370000200941086a203d2900003700002004200541206a3602a80820011029201c28024c211b201a2802002201200441a0086a10710240024020042802a408220f20042802a80822056b2001490d0020042802a00821090c010b200520016a22092005490d10200f410174221a2009201a20094b1b221a4100480d1002400240200f0d000240201a0d00410121090c020b201a10272209450d130c010b20042802a0082109200f201a460d002009200f201a102b2209450d1220042802a80821050b2004201a3602a408200420093602a0080b200920056a201b200110e4071a2004200520016a22013602a8080240024020042802a408220920016b4120490d0020042802a00821052009210f0c010b200141206a22052001490d102009410174220f2005200f20054b1b220f4100480d100240024020090d000240200f0d00410121050c020b200f10272205450d130c010b20042802a00821052009200f460d0020052009200f102b2205450d1220042802a80821010b2004200f3602a408200420053602a0080b200520016a2209201c41f8006a221a290000370000200941186a201a41186a290000370000200941106a201a41106a290000370000200941086a201a41086a2900003700002004200141206a22093602a8080240200f20096b413f4b0d00200941c0006a22012009490d10200f410174221a2001201a20014b1b22014100480d1002400240200f0d00024020010d00410121050c020b200110272205450d130c010b200f2001460d002005200f2001102b2205450d1220042802a80821090b200420013602a408200420053602a0080b200520096a2201201c4198016a2205290000370000200141386a200541386a290000370000200141306a200541306a290000370000200141286a200541286a290000370000200141206a200541206a290000370000200141186a200541186a290000370000200141106a200541106a290000370000200141086a200541086a2900003700002004200941c0006a3602a808412010272201450d0e2001201c41d8016a2205290000370000200141186a221a200541186a290000370000200141106a221b200541106a290000370000200141086a221f200541086a2900003700000240024020042802a408220f20042802a80822056b4120490d0020042802a00821090c010b200541206a22092005490d10200f410174223d2009203d20094b1b223d4100480d1002400240200f0d000240203d0d00410121090c020b203d10272209450d130c010b20042802a0082109200f203d460d002009200f203d102b2209450d1220042802a80821050b2004203d3602a408200420093602a0080b200920056a22092001290000370000200941186a201a290000370000200941106a201b290000370000200941086a201f2900003700002004200541206a3602a80820011029201e2903002125201c29030021410240024020042802a408220920042802a80822016b4110490d0020042802a00821050c010b200141106a22052001490d102009410174220f2005200f20054b1b220f4100480d100240024020090d000240200f0d00410121050c020b200f10272205450d130c010b20042802a00821052009200f460d0020052009200f102b2205450d1220042802a80821010b2004200f3602a408200420053602a0080b200520016a22052025370008200520413700002004200141106a3602a808201c2802102101201c2802182205200441a0086a107102402005450d002005410474211b034002402001410c6a2d000022054103714103460d004100210f02400240024020050e03020001020b4101210f0c010b4102210f0b0240024020042802a40820042802a8082205460d0020042802a00821090c010b200541016a22092005490d132005410174221a2009201a20094b1b221a4100480d130240024020050d00410021050240201a0d00410121090c020b201a10272209450d160c010b20042802a00821092005201a460d0020092005201a102b2209450d1520042802a80821050b2004201a3602a408200420093602a0080b200920056a200f3a00002004200541016a3602a8080b2001280200211e200141086a2802002205200441a0086a10710240024020042802a408221a20042802a80822096b2005490d0020042802a008210f0c010b200920056a220f2009490d12201a410174221f200f201f200f4b1b221f4100480d1202400240201a0d000240201f0d004101210f0c020b201f1027220f450d150c010b20042802a008210f201a201f460d00200f201a201f102b220f450d1420042802a80821090b2004201f3602a4082004200f3602a0080b200141106a2101200f20096a201e200510e4071a2004200920056a3602a808201b41706a221b0d000b0b412010272201450d0e2001201c41286a2205290000370000200141186a221a200541186a290000370000200141106a221b200541106a290000370000200141086a221e200541086a2900003700000240024020042802a408220f20042802a80822056b4120490d0020042802a00821090c010b200541206a22092005490d10200f410174221f2009201f20094b1b221f4100480d1002400240200f0d000240201f0d00410121090c020b201f10272209450d130c010b20042802a0082109200f201f460d002009200f201f102b2209450d1220042802a80821050b2004201f3602a408200420093602a0080b200920056a22092001290000370000200941186a201a290000370000200941106a201b290000370000200941086a201e2900003700002004200541206a3602a8082001102920042802a408210520042802a808210102400240201c28021c220f0d000240024020052001460d0020042802a00821050c010b200141016a22052001490d12200141017422092005200920054b1b22094100480d120240024020010d0041002101024020090d00410121050c020b200910272205450d150c010b20042802a008210520012009460d00200520012009102b2205450d1420042802a80821010b200420093602a408200420053602a0080b200520016a41003a0000200141016a21010c010b0240024020052001460d0020042802a00821050c010b200141016a22052001490d11200141017422092005200920054b1b22094100480d110240024020010d0041002101024020090d00410121050c020b200910272205450d140c010b20042802a008210520012009460d00200520012009102b2205450d1320042802a80821010b200420093602a408200420053602a0080b200520016a41013a00002004200141016a3602a808201c41246a2802002201200441a0086a10710240024020042802a408221a20042802a80822056b2001490d0020042802a00821090c010b200520016a22092005490d11201a410174221b2009201b20094b1b221b4100480d1102400240201a0d000240201b0d00410121090c020b201b10272209450d140c010b20042802a0082109201a201b460d002009201a201b102b2209450d1320042802a80821050b2004201b3602a408200420093602a0080b200920056a200f200110e4071a200520016a21010b20042802a408210520362001ad42208620042802a0082209ad841010220141186a2900003703002037200141106a2900003703002038200141086a290000370300200420012900003703d0032001102902402005450d00200910290b4100213d200441003602f006200441003602f8052002410374201d6b212d201c280288022101201c28028402211d4100213e4100211e4100211f0340201e417f6a2109202e201e4105746a211b034020014108490d074101210f200441013602e00620042001410376221a3602f00702400240201a41014b0d0020012105410021010240201a0e020002000b200441ac066a4101360200200441b4086a4102360200200442023702a408200441e4a7c7003602a008200441013602a4062004200441a0066a3602b0082004200441f0076a3602a8062004200441e0066a3602a006200441a0086a4180a6cc001040000b2001410771220f4108722105201d200f4107466a210f200141016a410771200141786a4178717221010b201d410120051b211a201b41206a211b200941016a2109200f211d4101200541077174201a2d000071450d000b2039280200201f4d0d05200941016a211e201f41016a214c201c2802f801201f41c1006c6a214d202d21052019211d0340024020050d0041b0afc700211a4117211e4183ae28211b0c090b200541786a2105201d280200211a201d41086a211d201a2009470d000b02400240204d2d00004101470d00200441f8056a2105203e0d01203320042903d003370000203341086a2038290300370000203341106a2037290300370000203341186a2036290300370000200441013a00a008200441f8056a200441a0086a200441a8016a108c0620042802f805213e0c010b200441f0066a2105203d0d00203320042903d003370000203341086a2038290300370000203341106a2037290300370000203341186a2036290300370000200441003a00a008200441f0066a200441a0086a200441a8016a108c0620042802f006213d0b200920324f0d04200f211d204c211f204d41016a2005350208422086200535020084201b10174101460d000b41c7afc700211a4110211e4183ae2c211b0c060b20092002418083cc00104c000b41e4afc700211a4183ae34211b410e211e0c080b2009410876410874200941ff017172211b2025422088a7211e2025a7211a0c050b2009203241f4bbc7001036000b4183afc700211a4116211e4183ae20211b0c010b2039280200201f460d0141d7afc700211a410d211e4183ae30211b0b0240203e450d0020042802fc05450d00203e10290b203d450d0120042802f406450d01203d10290c010b204220362903003703002034203729030037030020212038290300370300200420042903d0033703a00802402004280290012201200428028c01470d0020044188016a20014101109e0120042802900121010b200428028801222d20014105746a220520042903a008370000200541086a2021290300370000200541106a2034290300370000200541186a20422903003700002004200141016a360290010240203e450d0020042802fc05450d00203e10290b0240203d450d0020042802f406450d00203d10290b0240203f450d00204010290b0240203a450d00203b10290b02402043450d00204341047421052045210103400240200141046a280200450d00200128020010290b200141106a2101200541706a22050d000b0b0240204441ffffffff0071450d00204510290b0240200c450d002049450d00200c10290b20172018470d010c040b0b0240203f450d00204010290b0240203a450d00203b10290b02402043450d00204341047421022045210103400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b0240204441ffffffff0071450d00204510290b2048204945720d00200c10290b0240200428028c0141ffffff3f71450d0020042802880110290b0240202441ffffffff0171450d00200a10290b0240202241ffffffff0171450d00202310290b0240200742ffffff3f83500d00202910290b20044190076a41186a200441b0076a41186a29020037030020044190076a41106a200441b0076a41106a29020037030020044190076a41086a200441b0076a41086a290200370300200420042902b00737039007200041086a201e360200200041046a201a3602002000201b360200200441d8006a21010b200141046a28020041ffffffff0371450d06200128020010290c060b2027410020281b2149200441d0036a41186a22084200370300200441d0036a41106a22054200370300200441d0036a41086a22014200370300200442003703d00341b1dcc900ad4280808080f000841001220229000021252001200241086a290000370300200420253703d00320021029418886ca00ad4280808080c00184100122022900002125200441a0086a41086a2209200241086a290000370300200420253703a00820021029200620042903a008370000200641086a2009290300370000202a2001290300370300202b2005290300370300202c2008290300370300200420042903d0033703a006200441086a200441a0066a412010fc01200428020c214e2004280208214f200441003602a808200442043703a008200441a0086a4100200e109801200e412c6c210520042802a008225020042802a80822084102746a2101200b2102034020012002280200360200200841016a2108200141046a21012002412c6a2102200541546a22050d000b200441b0076a41086a200441d0076a41086a290300370300200441b0076a41106a200441d0076a41106a290300370300200441b0076a41186a200441d0076a41186a290300370300200420083602a808200420042903d0073703b00720042902a4082131200428028c01215120042802900121520240202441ffffffff0171450d00200a10290b0240202241ffffffff0171450d00202310290b0240200742ffffff3f83500d00202910290b200441e8006a41086a200441b0076a41086a2903002207370300200441e8006a41106a200441b0076a41106a2903002225370300200441e8006a41186a200441b0076a41186a2903002226370300200420042903b0072241370368200341086a280200210c2003280200213420044188016a41186a202637030020044188016a41106a202537030020044188016a41086a2007370300200420413703880120044180086a20494132702253108d06200428028008210520042004280288082201360294072004200536029007200441f8056a2001ad4220862005ad8422071007108b02024002400240024020042802f8052208450d0020042802fc05210a2004200441f8056a41086a28020022013602b407200420083602b00702400240024020014104490d002004200841046a3602b00720042001417c6a22023602b40720024104490d00200835000021252004200141786a22093602b4072004200841086a3602b00741002101200441003a00c0080240034020092001460d01200441a0086a20016a200820016a220241086a2d00003a00002004200241096a3602b0072004200141016a22023a00c0082002210120024120470d000b200441d0036a41086a200441a0086a41086a290300370300200441d0036a41106a200441a0086a41106a290300370300200441d0036a41186a200441a0086a41186a2903003703002004200920026b3602b407200420042903a0083703d003200441a0086a200441b0076a10f50520042802a0082202450d0120042802a408211d200441a0086a200441b0076a10960220042802a008221a0d02201d41ffffffff0371450d01200210290c010b200441003602b407200141ff0171450d00200441003a00c0080b41002102200441003602d803200442013703d0032004410d3602d407200420044190076a3602d0072004200441d0036a3602a80141012101200441b4086a4101360200200442013702a408200441f4eaca003602a0082004200441d0076a3602b008200441a8016a41a8a3c800200441a0086a10371a20043502d80342208620043502d003841008024020042802d403450d0020042802d00310290b0c010b200441a8016a41086a200441d0036a41086a290300370300200441a8016a41106a200441d0036a41106a29030037030020042802a408210f410021010b0240200a450d00200810290b2001450d010b2004280284080d010c020b20071004200428028408210102402002450d0002402001450d00200510290b41f182cc00ad4280808080c00184100122012900002107200441a0066a41086a200141086a290000370300200420073703a0062001102941edc4c800ad4280808080d00284100122012900002107200441a8016a41086a200141086a290000370300200420073703a80120011029200420253e02f8052004200441f8056aad4280808080c00084100222012900003703d00720011029200441ac086a200441fc056a3602002004200441d0076a41086a3602a4082004200441f8056a3602a8082004200441d0076a3602a008200441d0036a200441a0086a107520042802d803220a41206a2208417f4c0d0b20042802d00321190240024020080d0041002105410121010c010b200810272201450d05200821050b024002402005410f4d0d00200521090c010b200541017422094110200941104b1b22094100480d06024020050d00200910272201450d080c010b20052009460d00200120052009102b2201450d070b200120042903a006370000200141086a200441a0066a41086a2903003700000240024020094170714110460d00200921050c010b200941017422054120200541204b1b22054100480d0620092005460d00200120092005102b2201450d070b200120042903a801370010200141186a200441a8016a41086a29030037000002400240200541606a200a490d00200521090c010b200a415f4b0d06200541017422092008200920084b1b22094100480d0620052009460d00200120052009102b2201450d070b200141206a2019200a10e4071a024020042802d403450d00201910290b2008ad4220862001ad84100602402009450d00200110290b0240201d41ffffffff0371450d00200210290b200f41ffffff3f71450d02201a10290c020b2001450d010b200510290b200441a0086a41186a4200370300200441a0086a41106a22084200370300200441a0086a41086a22014200370300200442003703a00841b1dcc900ad4280808080f000841001220229000021072001200241086a290000370300200420073703a0082002102941b8dcc900ad4280808080a00184100122022900002107200441a8016a41086a2205200241086a290000370300200420073703a80120021029200820042903a8012207370300200441d0036a41086a2001290300370300200441d0036a41106a2007370300200441d0036a41186a2005290300370300200420042903a0083703d003200441a0086a200441d0036a108d020240024020042802a00822010d00200441003602d806200442013703d0060c010b200420042902a4083702d406200420013602d0060b02402052200c2052200c491b223b450d0020044180086aad4280808080c00084213c20044180086a41046a2140200441d0076a41086a2136200441a0086a41086a2128200441a0086a4104722148200441a0086a41146a2133200441a0086a410172211a200441f8056a41146a21212004418c086a214c20044180086a410472214d200441a8016a41106a210e200441a0066a41106a211e200441980a6a2127200441f8096a2129200441b8096a213820044198096a212c200441f8086a212b200441a0086a41286a212a200441a0086a41106a2142200441d0036a41206a2123410021240340200441003602e806200442013703e006203420244190026c6a220f280284022108200f4188026a2802002105200441a0066a41186a22204200370300201e4200370300200441a0066a41086a221b4200370300200442003703a00641b1dcc900ad4280808080f00084100122012900002107201b200141086a290000370300200420073703a0062001102941b8dcc900ad4280808080a00184100122012900002107200441f0066a41086a2222200141086a290000370300200420073703f00620011029201e20042903f006370000201e41086a2022290300370000200441d0036a41086a221f201b290300370300200441d0036a41106a2217201e290300370300200441d0036a41186a22182020290300370300200420042903a0063703d003200441a0086a200441d0036a108d020240024020042802a00822010d0041002102200441003602b807200442013703b0070c010b200420042902a40822073702b407200420013602b0072007a721020b200441a8016a41186a221c4200370300200e4200370300200441a8016a41086a22194200370300200442003703a80141eebec500ad4280808080f000841001220129000021072019200141086a290000370300200420073703a8012001102941f0f5c100ad4280808080900184100122012900002107201f200141086a290000370300200420073703d00320011029200e20042903d003370000200e41086a201f290300370000202820192903003703002042200e290300370300200441a0086a41186a201c290300370300200420042903a8013703a008200441d0036a200441a0086a10d001203720042802e00320042903d00342025122011b2137024020010d00200441d0076a203710af01200441a0086a20042802d007223220042802d807222e10d101201f204841086a223f290200370300200420482902003703d0030240024020042802a0084101460d002004410036028c0820044200370380080c010b20044180086a41086a201f290300370300200420042903d003370380080b2004410036028006200420053602fc05200420083602f8052004200441b0076a36028c062004200441e0066a360288062004200441d0066a36028406200441a0086a200441f8056a2021108e06024020042d00a0084101470d000340201b201a41086a2900002207370300201e201a41106a29000022253703002020201a41186a29000022263703002004201a29000022413703a006201c2026370300200e202537030020192007370300200420413703a801024002402004280284082209450d00200428028808210a0c010b200441a0086a410041e00210e6071a200441d0036a41286a22014100360200202342003703002018420037030020174200370300201f4200370300200442003703d00341940310272209450d094100210a200941003b010620094100360200200941086a200441a0086a41e00210e4071a20094190036a200128020036020020094188036a202329030037020020094180036a2018290300370200200941f8026a2017290300370200200941f0026a201f290300370200200920042903d0033702e802200441003602880820042009360284080b024002400340200941086a210220092f0106221d410574210141002108024003402001450d01200441a8016a2002412010e7072205450d03200141606a2101200841016a2108200241206a21022005417f4a0d000b2008417f6a211d0b0240200a450d00200a417f6a210a2009201d4102746a4194036a28020021090c010b0b2018201c29030022073703002017200e2903002225370300201f20192903002226370300200420042903a80122413703d00320332041370200203341086a2026370200203341106a2025370200203341186a20073702002004204c3602b0082004201d3602ac082004204d3602a808200420093602a408200441003602a008200441a0086a410010d20121010c010b200920084102746a41e8026a21010b2001200128020041146a360200200420042802800841146a36028008200441a0086a200441f8056a2021108e0620042d00a0084101460d000b0b203f20044180086a41086a2903003702002048200429038008370200200441013602a008200441003602d803200442013703d00320042802a4082102410410272201450d0620012002360000200420013602d00320044284808080c0003702d4032028200441d0036a10d30120042802d4032101202ead4220862032ad8420043502d80342208620042802d0032202ad84100302402001450d00200210290b202810d401024020042802d407450d00203210290b20042802b40721020b0240200241ffffff3f71450d0020042802b00710290b200f280248210a20044180086a41186a221d200f41f0006a29000037030020044180086a41106a2232200f41e8006a29000037030020044180086a41086a222e200f41e0006a2900003703002004200f29005837038008200f41d4006a2802002201417f4c0d0a200f28024c21090240024020010d0041002102410121080c010b200110272208450d04200121020b0240024020022001490d00200221050c010b200241017422052001200520014b1b22054100480d05024020020d00200510272208450d070c010b20022005460d00200820022005102b2208450d060b20082009200110e407213f200441f8056a41186a2243200f4190016a290000370300200441f8056a41106a223d200f4188016a290000370300200441f8056a41086a223e200f4180016a2900003703002004200f2900783703f805200441d0036a41386a2235200f41d0016a290000370300200441d0036a41306a2245200f41c8016a290000370300200441d0036a41286a2239200f41c0016a2900003703002023200f41b8016a2900003703002018200f41b0016a2900003703002017200f41a8016a290000370300201f200f41a0016a2900003703002004200f290098013703d0032020200f41f0016a290000370300201e200f41e8016a290000370300201b200f41e0016a2900003703002004200f2900d8013703a006200f41086a2903002107200f290300212520044190076a200f41106a10f005201c200f41c0006a290000370300200e200f41386a2900003703002019200f41306a2900003703002004200f2900283703a80102400240200f28021c223a0d00410021080c010b200f41246a2802002202417f4c0d0b0240024020020d0041002109410121080c010b200210272208450d05200221090b0240024020092002490d002009210f0c010b2009410174220f2002200f20024b1b220f4100480d06024020090d00200f10272208450d080c010b2009200f460d0020082009200f102b2208450d070b2008203a200210e4071a2002ad422086200fad8421470b200441f0076a41086a220920044190076a41086a220228020036020020362019290300370300200441d0076a41106a220f200e290300370300200441d0076a41186a223a201c290300370300200441b0076a41086a2244202e290300370300200441b0076a41106a222e2032290300370300200441b0076a41186a2232201d29030037030020042004290390073703f007200420042903a8013703d00720042004290380083703b00720044190076a41186a221d204329030037030020044190076a41106a2243203d2903003703002002203e290300370300200420042903f80537039007200441a8016a41386a223d2035290300370300200441a8016a41306a223e2045290300370300200441a8016a41286a22352039290300370300200441a8016a41206a22452023290300370300201c2018290300370300200e20172903003703002019201f290300370300200420042903d0033703a801200441f0066a41186a221f2020290300370300200441f0066a41106a2220201e2903003703002022201b290300370300200420042903a0063703f006200420073703a808200420253703a008204220042903f007370300204241086a2009280200360200200420473703c008200420083602bc08202a20042903d007370300202a41086a2036290300370300202a41106a200f290300370300202a41186a203a290300370300200420013602f408200420053602f0082004203f3602ec082004200a3602e808202b41186a2032290300370300202b41106a202e290300370300202b41086a2044290300370300202b20042903b007370300202c41186a201d290300370300202c41106a2043290300370300202c41086a2002290300370300202c200429039007370300203841386a203d290300370300203841306a203e290300370300203841286a2035290300370300203841206a2045290300370300203841186a201c290300370300203841106a200e290300370300203841086a2019290300370300203820042903a801370300202941186a201f290300370300202941106a2020290300370300202941086a2022290300370300202920042903f006370300202741086a200441e0066a41086a280200360200202720042903e006370200200441003602ac0a200442013702a40a41f182cc00ad4280808080c00184100122012900002107201b200141086a290000370300200420073703a0062001102941edc4c800ad4280808080d002841001220129000021072019200141086a290000370300200420073703a8012001102920042049360280082004203c100222012900003703d00720011029200420403602dc03200420363602d403200420044180086a3602d8032004200441d0076a3602d003200441f8056a200441d0036a1075412010272201450d032001202d20244105746a2202290000370000200141186a2208200241186a290000370000200141106a2205200241106a290000370000200141086a2209200241086a290000370000412010272202450d0320022001290000370000200241186a221d2008290000370000200241106a220f2005290000370000200241086a2220200929000037000020011029200428028006220541c0006a221f417f4c0d0a20042802f805210a02400240201f0d00410021084101211c0c010b201f1027221c450d04201f21080b024002402008410f4d0d00200821010c010b200841017422014110200141104b1b22014100480d05024020080d0020011027221c450d070c010b20082001460d00201c20082001102b221c450d060b201c20042903a006370000201c41086a201b2903003700000240024020014170714110460d00200121090c010b200141017422084120200841204b1b22094100480d0520012009460d00201c20012009102b221c450d060b200541206a2101201c20042903a801370010201c41186a201929030037000002400240200941606a2005490d00200921080c010b2005415f4b0d05200941017422082001200820014b1b22084100480d0520092008460d00201c20092008102b221c450d060b201c41206a200a200510e4071a02400240200820016b411f4d0d00200821190c010b200141206a22052001490d05200841017422092005200920054b1b22194100480d05024020080d00024020190d004101211c0c020b20191027221c450d070c010b20082019460d00201c20082019102b221c450d060b201c20016a22012002290000370000200141186a201d290000370000200141106a200f290000370000200141086a202029000037000020021029024020042802fc05450d00200a10290b200441003602d803200442013703d003200441a0086a200441d0036a10a50420042802980a210a20042802a00a2201200441d0036a107102402001450d002001410574211d410020042802d80322026b210520042802d003210f20042802d40321090340200a21010240200920056a411f4b0d00200241206a22082002490d072009410174220a2008200a20084b1b22084100480d07024002400240024020090d00024020080d004101210f0c020b20081027210f0c030b20092008470d010b200821090c020b200f20092008102b210f0b20082109200f450d080b200141206a210a200f20026a22082001290000370000200841186a200141186a290000370000200841106a200141106a290000370000200841086a200141086a290000370000200541606a2105200241206a2102201d41606a221d0d000b200420093602d403200420023602d8032004200f3602d0030b20042802a40a210a20042802ac0a2201200441d0036a10710240024020010d0020042802d803210220042802d403210520042802d003210f0c010b2001410574211d410020042802d80322026b210920042802d003210f20042802d40321050340200a21010240200520096a411f4b0d00200241206a22082002490d072005410174220a2008200a20084b1b22084100480d07024002400240024020050d00024020080d004101210f0c020b20081027210f0c030b20052008470d010b200821050c020b200f20052008102b210f0b20082105200f450d080b200141206a210a200f20026a22082001290000370000200841186a200141186a290000370000200841106a200141106a290000370000200841086a200141086a290000370000200941606a2109200241206a2102201d41606a221d0d000b200420053602d403200420023602d8032004200f3602d0030b201fad422086201cad842002ad422086200fad84100302402005450d00200f10290b02402019450d00201c10290b024020042802f008450d0020042802ec0810290b024020042802b8082202450d0020042802b00821012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b024020042802b40841ffffffff0071450d0020042802b00810290b024020042802bc082201450d0020042802c008450d00200110290b0240200428029c0a41ffffff3f71450d0020042802980a10290b202441016a2124024020042802a80a41ffffff3f71450d0020042802a40a10290b2024203b490d000b0b200441d0036a2053108d0620043502d803210720042802d003211a200441003602a808200442013703a008410410272201450d03200441043602a408200420013602a00820012049360000200441043602a808200141044108102b2201450d03200441083602a4082001204e4100204f1b360004200420013602a008200441083602a808200141084128102b2201450d032001200429038801370008200141106a20044190016a290300370000200141186a20044188016a41106a290300370000200141206a20044188016a41186a290300370000200441283602a408200420013602a008200441283602a8082031422088a72201200441a0086a107102402001450d002001410274211d410020042802a80822016b210220042802a40821052050210803402008280200210f02400240200520026a4104490d0020042802a00821090c010b200141046a22092001490d052005410174220a2009200a20094b1b220a4100480d050240024020050d000240200a0d00410121090c020b200a10272209450d080c010b20042802a00821092005200a460d0020092005200a102b2209450d070b2004200a3602a408200420093602a008200a21050b200841046a2108200920016a200f3600002004200141046a22013602a8082002417c6a2102201d417c6a221d0d000b0b202d2052200441a0086a10850620042802a40821012007422086201aad8420043502a80842208620042802a0082202ad84100302402001450d00200210290b024020042802d403450d00201a10290b024020042802d40641ffffff3f71450d0020042802d00610290b0240203142ffffffff0383500d00205010290b0240205141ffffff3f71450d00202d10290b200441d0036a41186a22084200370300200441d0036a41106a22054200370300200441d0036a41086a22014200370300200442003703d00341cd87cc00ad4280808080a00184100122022900002107200441f8056a41086a2209200241086a290000370300200420073703f8052002102920012009290300370300200420042903f8053703d003419f84cc00ad4280808080d00184100122022900002107200441a8016a41086a2209200241086a290000370300200420073703a80120021029200620042903a801370000200641086a2009290300370000200441a0066a41086a2001290300370300200441a0066a41106a2005290300370300200441a0066a41186a2008290300370300200420042903d0033703a006200441a0086a200441a0066a412010c0040240024020042802a008221f0d0041002120200441003602880820044204370380084104211f4100211d0c010b20042902a40821072004201f3602800820042007370284082007422088a721202007a7211d0b0240024002400240200c450d002034200c4190026c6a2117200441a0066aad4280808080c000842125200441a0066a41046a211c200441d0076a41086a211e200441a0086a410472211841cd87cc00ad4280808080a0018421260340200441a0086a2034280248221b108f0620042802a0082101200420042802a8083602d403200420013602d003203428024c203441d4006a280200200441d0036a10a104024020042802a408450d00200110290b024020342802182209450d0020342802102108200441d0036a201b108806200441a0086a20042802d003220a20042802d803221d10f9014100210220042802a808410020042802a008410146220f1b211a200841086a210120042802a408210e2009410474221921050340200128020020026a2102200141106a2101200541706a22050d000b20042002201a6a3602a808200441013602a0082004200e4100200f1b20096a3602a4082004201d3602ac012004200a3602a8012018200441a8016a10fb01024020042802d403450d00200a10290b03402026100122012900002107200441f8056a41086a220f200141086a290000370300200420073703f8052001102941f783cc00ad4280808080a00284100122012900002107200441a8016a41086a221a200141086a290000370300200420073703a801200110292004201b3602a00620042025100222012900003703d007200110292004201c3602ac082004201e3602a4082004200441a0066a3602a8082004200441d0076a3602a008200441d0036a200441a0086a107520042802d803220a41206a2202417f4c0d0f20042802d003211d0240024020020d0041002105410121010c010b200210272201450d09200221050b024002402005410f4d0d00200521090c010b200541017422094110200941104b1b22094100480d0a024020050d00200910272201450d0c0c010b20052009460d00200120052009102b2201450d0b0b200120042903f805370000200141086a200f2903003700000240024020094170714110460d00200921050c010b200941017422054120200541204b1b22054100480d0a20092005460d00200120092005102b2201450d0b0b200120042903a801370010200141186a201a29030037000002400240200541606a200a490d002005211a0c010b200a415f4b0d0a200541017422092002200920024b1b221a4100480d0a2005201a460d0020012005201a102b2201450d0b0b200141206a201d200a10e4071a024020042802d403450d00201d10290b41002105200441003602a808200442013703a00802402008410c6a2d000022094103714103460d0002400240024020090e03020001020b410121050c010b410221050b410110272209450d0b200920053a0000200420093602a00820044281808080103702a4080b2008280200210e200841086a2802002205200441a0086a10710240024020042802a408220f20042802a808220a6b2005490d0020042802a0082109200f211d0c010b200a20056a2209200a490d0a200f410174221d2009201d20094b1b221d4100480d0a02400240200f0d000240201d0d00410121090c020b201d10272209450d0d0c010b20042802a0082109200f201d460d002009200f201d102b2209450d0c0b2004201d3602a408200420093602a0080b2009200a6a200e200510e4071a2002ad4220862001ad84200a20056aad4220862009ad8410140240201d450d00200910290b0240201a450d00200110290b200841106a2108201941706a22190d000b41002101024002400240202041014b0d0020200e020201020b20202102034020012002410176220820016a2205201b201f20054102746a280200491b2101200220086b220241014b0d000b0b0240201b201f20014102746a2802002202470d004184bcc700ad4280808080c0048410080c020b20202001201b20024b6a2201490d040b02402020200428028408470d0020044180086a20204101109801200428028008211f0b201f20014102746a220241046a2002202020016b41027410e5071a2002201b3602002004202041016a2220360288080b20344190026a22342017470d000b200428028408211d0b200441d0036a41186a22024200370300200441d0036a41106a22084200370300200441d0036a41086a22014200370300200442003703d00341cd87cc00ad4280808080a001842207100122092900002125200441f8056a41086a2205200941086a290000370300200420253703f8052009102920012005290300370300200420042903f8053703d003419f84cc00ad4280808080d0018422251001220a2900002126200441a8016a41086a2209200a41086a290000370300200420263703a801200a1029200620042903a801370000200641086a220f2009290300370000200441a0066a41086a221a2001290300370300200441a0066a41106a22192008290300370300200441a0066a41186a220e2002290300370300200420042903d0033703a006200441203602a4082004200441a0066a3602a008201f2020200441a0086a10ef030240201d41ffffffff0371450d00201f10290b200242003703002008420037030020014200370300200442003703d00320071001220a29000021072005200a41086a290000370300200420073703f805200a102920012005290300370300200420042903f8053703d00320251001220529000021072009200541086a290000370300200420073703a80120051029200620042903a801370000200f2009290300370000201a200129030037030020192008290300370300200e2002290300370300200420042903d0033703a006200441a0086a200441a0066a412010c00420042802a0082201410420011b212a024020042902a408420020011b2241422088a722240d004100211f0c030b202a20244102746a2138200441a0066aad4280808080c000842126200441a0066a41046a2123200441d0076a41086a2134200441a0066a41086a2105200441a0086a410672211b4100211f4100211e41002121202a210f0340201f2117200441a0086a200f280200108806200441d0036a20042802a008220920042802a80810f90120042802d003410146210120042802d403210220042802d8032108024020042802a408450d00200910290b2002410020011b211c2008410020011b212002400240201e0d00410121010c010b201c201e6a41e50049202020216a41a19c01497121010b201741016a211f0240201c450d002001450d00200441a0086a200f28020010880620043502a80842208620042802a0082201ad841004024020042802a408450d00200110290b41cd87cc00ad4280808080a00184100122012900002107200441f8056a41086a221a200141086a290000370300200420073703f8052001102941f783cc00ad4280808080a00284100122012900002107200441a8016a41086a2219200141086a290000370300200420073703a801200110292004200f2802003602a00620042026100222012900003703d00720011029200420233602ac08200420343602a4082004200441a0066a3602a8082004200441d0076a3602a008200441d0036a200441a0086a107520042802d803220a41206a2202417f4c0d0d20042802d003211d0240024020020d0041002108410121010c010b200210272201450d07200221080b024002402008410f4d0d00200821090c010b200841017422094110200941104b1b22094100480d08024020080d00200910272201450d0a0c010b20082009460d00200120082009102b2201450d090b200120042903f805370000200141086a201a2903003700000240024020094170714110460d00200921080c010b200941017422084120200841204b1b22084100480d0820092008460d00200120092008102b2201450d090b200120042903a801370010200141186a201929030037000002400240200841606a200a490d00200821090c010b200a415f4b0d08200841017422092002200920024b1b22094100480d0820082009460d00200120082009102b2201450d090b200141206a201d200a10e4071a024020042802d403450d00201d10290b200420023602fc05200420013602f805200441a8016a2002ad4220862001ad8422251007108b020240024020042802a80122080d00410021020c010b20042802ac01210a200420042802b0013602a406200420083602a006200441a0086a200441a0066a10f6050240024020042802a00822020d00200441003602d803200442013703d0032004410d3602d4072004200441f8056a3602d0072004200441d0036a36028008200441013602b408200442013702a408200441f4eaca003602a0082004200441d0076a3602b00820044180086a41a8a3c800200441a0086a10371a20043502d80342208620043502d00384100820042802d403450d0120042802d00310290c010b20042902a40821070b0240200a450d00200810290b024020020d00410021020c010b202510040b2007420020021b21072002410420021b211802402009450d00200110290b20182007422088a722014104746a210802400240024020010d00201821010c010b20182101034002402001410c6a2d0000221a4103470d00200141106a21010c020b200141046a280200210920012802002102200141086a280200210a2004200f280200221d3602b0072004200a3602d407200420023602d007200441a8016a200441d0076a10e403024020042802a801411c460d00200441d0036a200441a8016a41a80210e4071a4103210a024002400240201a4103710e03010200010b4100210a4100210e0c010b200441a0086a200441b0076a10cc0320044180086a41086a201b41086a29010037030020044180086a41106a201b41106a29010037030020044180086a41186a201b41186a2f01003b01002004201b2901003703800820042801a208211d20042f01a00821194101210e4100210a0b200441a0086a200441d0036a41a80210e4071a2005200429038008370200200541086a20044180086a41086a290300370200200541106a20044180086a41106a290300370200200541186a20044180086a41186a2903003702002004201d3602a406200420193b01a2062004200e3a00a1062004200a3a00a006200441f8056a200441a0086a200441a0066a10c5010b02402009450d00200210290b200141106a22012008470d000c020b0b20082001460d000340200141106a21020240200141046a280200450d00200128020010290b2002210120082002470d000b0b0240200742ffffffff0083500d00201810290b201c201e6a221e41e3004b0d03202020216a2221419f9c014b0d030b200f41046a220f2038470d000c020b0b200120201041000b20172024490d00201f202441a8bcc700104c000b200441d0036a41186a22084200370300200441d0036a41106a22054200370300200441d0036a41086a22014200370300200442003703d00341cd87cc00ad4280808080a00184100122022900002107200441f8056a41086a2209200241086a290000370300200420073703f8052002102920012009290300370300200420042903f8053703d003419f84cc00ad4280808080d00184100122022900002107200441a8016a41086a2209200241086a290000370300200420073703a80120021029200620042903a801370000200641086a2009290300370000200441a0066a41086a2001290300370300200441a0066a41106a2005290300370300200441a0066a41186a2008290300370300200420042903d0033703a0062024201f6b220241027441046a2201417f4c0d080240024020010d0041012108410021010c010b200110272208450d020b200441003602a808200420083602a008200420013602a4082002200441a0086a10710240024020020d0020042802a808210120042802a408210a20042802a00821090c010b202a201f4102746a21082024410274201f4102746b211d410020042802a80822016b210520042802a408210203402008280200210f02400240200220056a4104490d0020042802a00821092002210a0c010b200141046a22092001490d052002410174220a2009200a20094b1b220a4100480d050240024020020d000240200a0d00410121090c020b200a10272209450d080c010b20042802a00821092002200a460d0020092002200a102b2209450d070b2004200a3602a408200420093602a008200a21020b200841046a2108200920016a200f3600002004200141046a22013602a8082005417c6a2105201d417c6a221d0d000b0b200441a0066aad42808080808004842001ad4220862009ad8410030240200a450d00200910290b0240204142ffffffff0383500d00202a10290b20042802602108200428025c21052004280258210f0b201042003703002011420037030020124200370300200442003703d00341cd87cc00ad4280808080a00184100122012900002107200441f8056a41086a2202200141086a290000370300200420073703f8052001102920122002290300370300200420042903f8053703d00341ac84cc00ad4280808080900184100122012900002107200441a8016a41086a2202200141086a290000370300200420073703a80120011029200620042903a80137000020132002290300370000201420122903003703002015201129030037030020162010290300370300200420042903d0033703a006200441203602a4082004200441a0066a3602a008200f2008200441a0086a10ef030240200541ffffffff0371450d00200f10290b200041043a00000240200da72201450d002001412c6c450d00200b10290b0240200c450d0020032802002208200c4190026c6a210503400240200841d0006a280200450d00200828024c10290b0240200841186a2802002202450d00200828021021012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b0240200841146a28020041ffffffff0071450d00200828021010290b0240200828021c2201450d00200841206a280200450d00200110290b0240200841fc016a2802002201450d00200141c1006c450d0020082802f80110290b20084190026a210120084188026a41003602002008280284022102200841013602840202402008418c026a280200450d00200210290b2001210820012005470d000b0b200341046a2802002201450d0620014190026c450d06200328020010290c060b1039000b1032000b1030000b200041832e3b0100200041086a4115360200200041046a4193aec700360200200041026a41013a00000b200da72201450d002001412c6c450d00200b10290b024020032802082201450d002003280200220820014190026c6a210503400240200841d0006a280200450d00200828024c10290b0240200841186a2802002202450d00200828021021012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b0240200841146a28020041ffffffff0071450d00200828021010290b0240200828021c2201450d00200841206a280200450d00200110290b0240200841fc016a2802002201450d00200141c1006c450d0020082802f80110290b20084190026a210120084188026a41003602002008280284022102200841013602840202402008418c026a280200450d00200210290b2001210820012005470d000b0b200341046a2802002201450d0020014190026c450d00200328020010290b200441800b6a24000f0b1038000bec0403037f017e087f230041e0006b220224002002200110c80102400240024002402002280200450d00200041003602000c010b20022802042203200128020441246e2204200420034b1bad42247e2205422088a70d012005a72204417f4c0d010240024020040d00410421060c010b200410272206450d030b4100210720024100360210200220063602082002200441246e36020c0240024002402003450d00410021080340200128020422094104490d03200841016a21082001280200220a280000210b20012009417c6a220c3602042001200a41046a36020041002104200241003a00582009417b6a21090340200c2004460d03200241386a20046a200a20046a220d41046a2d00003a0000200120093602042001200d41056a3602002002200441016a220d3a00582009417f6a2109200d2104200d4120470d000b200241186a41186a2209200241386a41186a290300370300200241186a41106a220d200241386a41106a290300370300200241186a41086a220a200241386a41086a2903003703002002200229033837031802402007200228020c470d00200241086a2007410110960120022802082106200228021021070b2006200741246c6a2204200b360200200420022903183702042004410c6a200a290300370200200441146a200d2903003702002004411c6a20092903003702002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c020b200441ff0171450d00200241003a00580b20004100360200200228020c2204450d00200441246c450d00200610290b200241e0006a24000f0b1038000b1039000bb30802077f037e230041106b220224000240024002400240200128020841146a2203417f4c0d000240024020030d0041012104410021030c010b200310272204450d020b20024100360208200220043602002002200336020402402003410f4b0d00200341017422054110200541104b1b22054100480d030240024020030d002005102722040d010c060b20032005460d00200420032005102b2204450d050b20022005360204200220043602000b2004200129000c370000200441086a200141146a290000370000200241103602082001280200210620012802082203200210710240024020022802042207200228020822086b2003490d0020022802002104200721050c010b200820036a22042008490d03200741017422052004200520044b1b22054100480d030240024020070d00024020050d00410121040c020b200510272204450d060c010b2002280200210420072005460d00200420072005102b2204450d050b20022005360204200220043602000b200420086a2006200310e4071a2002200820036a2208360208200128021c210302400240200520086b4120490d00200841206a21070c010b200841206a22072008490d03200541017422012007200120074b1b22014100480d030240024020050d00024020010d00410121040c020b200110272204450d060c010b20052001460d00200420052001102b2204450d050b20022001360204200220043602000b200420086a22012003290000370000200141186a200341186a290000370000200141106a200341106a290000370000200141086a200341086a290000370000200220073602082002200341206a36020c2002410c6a200210e5012002200341306a36020c2002410c6a200210e501200341c0006a2802002101200341c8006a28020022032002107102402003450d00200341306c210803400240024020022802042205200228020822036b4120490d00200228020021040c010b200341206a22042003490d05200541017422072004200720044b1b22074100480d050240024020050d00024020070d00410121040c020b200710272204450d080c010b2002280200210420052007460d00200420052007102b2204450d070b20022007360204200220043602000b200420036a2204200141106a290000370000200441186a200141286a290000370000200441106a200141206a290000370000200441086a200141186a2900003700002002200341206a3602082002200136020c2002410c6a200210e501200141306a2101200841506a22080d000b0b20022802042103200235020842208620022802002204ad84101022012900002109200141086a290000210a200141106a290000210b200041186a200141186a290000370000200041106a200b370000200041086a200a370000200020093700002001102902402003450d00200410290b200241106a24000f0b1038000b1039000b1032000b1030000bc7560a087f027e047f027e017f017e0b7f017e047f027e230022032104200341a0026b416071220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e080001020304050607000b200341b4016a4101360200200342013702a40120034198e3ca003602a0012003410436027c200341cce3ca003602782003200341f8006a3602b001200341a0016a4180a6cc001040000b200141186a2802002105200141146a28020021062001410c6a2802002107200141086a280200210802400240024020022d000120022d0000410047720d00200141106a280200220241808080054b0d012001411c6a28020022094180a0014d0d02200341d0006a4110360200200341edd3c80036024c200341043a004a20034183343b01480c140b200341023a00480c130b200341d0006a410c360200200341e1d3c80036024c200341033a004a20034183343b01480c120b200141046a280200210a20012d0001210120032002360280012003200736027c20032008360278200320093602a801200320053602a401200320063602a001200341c8006a200a200141ff0171410047200341f8006a200341a0016a10c90420032d00484104470d124200210b0c130b024002400240024020022d000120022d000041004772450d00200341023a00a0010c010b200341a0016a200141046a28020010e80420032d00a0014104460d0120032902a401210b0b20032802a00121012000411c6a200b370200200041186a20013602004201210b0c010b4200210b0b200042003703080c130b024020022d000120022d000041004772450d0020004200370308200041186a41023602004201210b0c130b200141046a28020021074200210b200341b8016a4200370300200341b0016a22064200370300200341a0016a41086a22024200370300200342003703a00141d787cc00ad428080808090018410012205290000210c200341f8006a41086a2201200541086a2900003703002003200c3703782005102920022001290300370300200320032903783703a00141e087cc00ad4280808080b0018410012205290000210c2001200541086a2900003703002003200c3703782005102920062003290378220c370300200320032903a001370320200320022903003703282003200c37033020032001290300370338200320073602a001200341206aad4280808080800484200341a0016aad4280808080c0008410030c0c0b200141186a280200210d200141146a2802002109200141106a280200210e2001410c6a280200210f200141086a280200210a200141046a280200211020032002411a6a2901003703b801410221012003200241026a2901003703a00120032002410a6a2901003703a8012003200241126a2901003703b0010240024020022d00014101470d0020022d000041ff01710d00200341c8006a41186a200341a0016a41186a290300370300200341c8006a41106a200341a0016a41106a290300370300200341c8006a41086a200341a0016a41086a290300370300200320032903a0013703482003420037032820034280a0e5b9c291013703202003200341c8006a3602742003200341c8006a3602682003200341e8006a3602a8012003200341f4006a3602a4012003200341206a3602a001200341f8006a200341c8006a200341a0016a108e040240024020032802784101470d0020034184016a2802002105200341f8006a41086a280200210720032d007f210620032d007e210820032d007d210220032d007c21010c010b410421010240200341f8006a41086a2903004201520d00200341f8006a41106a290300210b20032802682102200341d8016a200341f8006a41186a290300370300200341d0016a200b370300200341a0016a41086a41003a0000200341a9016a2002290000370000200341b1016a200241086a290000370000200341b9016a200241106a290000370000200341c1016a200241186a290000370000200341033a00a001200341a0016a10cb010b0b200141ff01714104470d0f411a210241032101200f41808080054d0d0141e1d3c8002107410c2105410321080c0f0b0c0e0b0240200d4180a0014d0d0041edd3c800210741102105410421080c0e0b10be0421022003200f360280012003200a36027c200320103602782003200d3602a801200320093602a4012003200e3602a001200341206a20024101200341f8006a200341a0016a10c904200341a0016a41186a2207200341c8006a41186a290300370300200341a0016a41106a2206200341c8006a41106a290300370300200341a0016a41086a2208200341c8006a41086a290300370300200320032903483703a001200341f8006a200210db06200335028001210b20032802782105412010272201450d03200120032903a001370000200141186a2007290300370000200141106a2006290300370000200141086a2008290300370000200b4220862005ad842001ad42808080808004841003200110290240200328027c450d00200510290b200341a8016a2002360200200341003602a401200341103a00a001200341a0016a10cb010c0a0b024020022d00000d0020022d00014101460d0a0b20004200370308200041186a41023602004201210b0c100b41002105024002402002280200220141ff017122074103460d0041022106410021080c010b200341a0016a200241046a280200200120074103461b220710dc0620032802a001220120032802a80110900641ff01712102024020032802a401450d00200110290b4102210141022002410171200241024622021b210602400240024020020d0020064101710d0241d2d3c8002107410f21020c010b41b3d3c80021074111210241002105410021010240024020060e03000201000b200341b4016a4101360200200342013702a40120034198e3ca003602a0012003410436027c200341bcd4c8003602782003200341f8006a3602b001200341a0016a4180a6cc001040000b41c4d3c8002107410e2102410121010b4103210641803421080c010b200341a0016a200710e804200341a0016a41086a2101024020032d00a00122064104470d002003420037033820034200370330200342003703282003420037032041d787cc00ad4280808080900184221110012205290000210b200341f8006a41086a2202200541086a2900003703002003200b370378200510292003200229030037032820032003290378370320419a88cc00ad4280808080a00184221210012205290000210b2002200541086a2900003703002003200b3703782005102920012003290328370300200341a0016a41106a22092003290378220b370300200341a0016a41186a220a20022903003703002003200b370330200320032903203703a001200341f8006a200341a0016a10fd0520032802782201410420011b21130240200329027c420020011b2214422088a72215450d0020132015410c6c6a21162013211703400240201741086a22182802002208450d00201728020021014100210241002105034002400240024020072001280200460d0020020d01410021020c020b200241016a21020c010b200520026b220620084f0d09200341a0016a41206a220e20012002415c6c6a220641206a2210280200360200200a200641186a220f2902003703002009200641106a220d290200370300200341a0016a41086a2219200641086a221a290200370300200320062902003703a001200141206a221b280200211c200141186a221d290200210b200141106a221e290200210c200141086a221f290200212020062001290200370200201a2020370200200d200c370200200f200b3702002010201c360200201b200e280200360200201d200a290300370200201e2009290300370200201f2019290300370200200120032903a0013702000b200141246a21012008200541016a2205470d000b2002450d002018280200200820026b2201490d00201820013602000b2017410c6a22172016470d000b0b200320133602482003201437024c20034200370338200342003703302003420037032820034200370320201110012202290000210b200341f8006a41086a2201200241086a2900003703002003200b370378200210292003200129030037032820032003290378370320201210012202290000210b2001200241086a2900003703002003200b37037820021029200341206a41107222212003290378370000202141086a2001290300370000200341a0016a41086a200329032837030020092003290330370300200a2003290338370300200320032903203703a0012003412036027c2003200341a0016a360278200341c8006a200341f8006a10ee052014a7210602402015450d002015410c6c21022013210103400240200141046a2802002205450d00200541246c450d00200128020010290b2001410c6a2101200241746a22020d000b0b02402006450d002006410c6c450d00201310290b2003420037033820034200370330200342003703282003420037032041d787cc00ad4280808080900184221110012201290000210b200341f8006a41086a2213200141086a2900003703002003200b37037820011029200320132903003703282003200329037837032041eb87cc00ad4280808080f00184221210012201290000210b2013200141086a2900003703002003200b3703782001102920212003290378370000202141086a22222013290300370000200341a0016a41086a22092003290328370300200341a0016a41106a220a2003290330370300200341a0016a41186a220e2003290338370300200320032903203703a001200341f8006a200341a0016a10fd0520032802782201410420011b21150240200329027c420020011b2214422088a72223450d0020152023410c6c6a21162015211703400240201741086a22182802002208450d00201728020021014100210241002105034002400240024020072001280200460d0020020d01410021020c020b200241016a21020c010b200520026b220620084f0d0a200341a0016a41206a221020012002415c6c6a220641206a220f280200360200200e200641186a220d290200370300200a200641106a22192902003703002009200641086a221a290200370300200320062902003703a001200141206a221b280200211c200141186a221d290200210b200141106a221e290200210c200141086a221f290200212020062001290200370200201a20203702002019200c370200200d200b370200200f201c360200201b2010280200360200201d200e290300370200201e200a290300370200201f2009290300370200200120032903a0013702000b200141246a21012008200541016a2205470d000b2002450d002018280200200820026b2201490d00201820013602000b2017410c6a22172016470d000b0b200320153602482003201437024c20034200370338200342003703302003420037032820034200370320201110012201290000210b2013200141086a2900003703002003200b370378200110292003201329030037032820032003290378370320201210012201290000210b2013200141086a2900003703002003200b37037820011029202120032903783700002022201329030037000020092003290328370300200a2003290330370300200e2003290338370300200320032903203703a0012003412036027c2003200341a0016a360278200341c8006a200341f8006a10ee052014a7210602402023450d002023410c6c21022015210103400240200141046a2802002205450d00200541246c450d00200128020010290b2001410c6a2101200241746a22020d000b0b02402006450d002006410c6c450d00201510290b2003420037033820034200370330200342003703282003420037032041d787cc00ad4280808080900184220b10012201290000210c200341f8006a41086a2206200141086a2900003703002003200c37037820011029200320062903003703282003200329037837032041fa87cc00ad4280808080e00084220c1001220129000021202006200141086a290000370300200320203703782001102920212003290378370000202141086a220a2006290300370000200341a0016a41086a220e2003290328370300200341b0016a22102003290330370300200341b8016a220f2003290338370300200320032903203703a001200341f8006a200341a0016a10a60320032802782201410420011b21080240200329027c420020011b2220422088a72209450d002009412c6c2102200821010340024020012802002007470d00200141246a22052802004102460d00200541003602000b2001412c6a2101200241546a22020d000b0b20034200370338200342003703302003420037032820034200370320200b10012201290000210b2006200141086a2900003703002003200b370378200110292003200629030037032820032003290378370320200c10012201290000210b2006200141086a2900003703002003200b3703782001102920212003290378370000200a2006290300370000200e200329032837030020102003290330370300200f2003290338370300200320032903203703a0012003412036027c2003200341a0016a36027820082009200341f8006a10f00302402020a72201450d002001412c6c450d00200810290b200341e8006a200710db06200341a0016a200328026822012003280270220510cd01024020032d00a0012202450d002005ad4220862001ad8410040b200341f8006a41186a200341b9016a290000220b370300200341f8006a41106a200341b1016a290000220c370300200341f8006a41086a200341a9016a2900002220370300200320032900a10122143703782003200b3703382003200c37033020032020370328200320143703200240024020024101460d00200341c8006a41186a4200370300200341c8006a41106a4200370300200341c8006a41086a4200370300200342003703480c010b200341c8006a41186a2003290338370300200341c8006a41106a2003290330370300200341c8006a41086a2003290328370300200320032903203703480b0240200328026c450d00200110290b4200210b2003420037032820034280a0e5b9c291013703202003200341c8006a360268200341f8006a200341c8006a200341206a200341e8006a10ea03024020032903784201520d00200329038001210c200341d8016a200341f8006a41106a290300370300200341d0016a200c370300200341a0016a41086a41003a0000200341a9016a2003290348370000200341b1016a200341c8006a41086a290300370000200341b9016a200341c8006a41106a290300370000200341c1016a200341e0006a290300370000200341033a00a001200341a0016a10cb010b200341a8016a2007360200200341003602a401200341103a00a001200341a0016a10cb010c0b0b2001280200210220032802a401210720032d00a201210120032d00a101410874210820032d00a30141187421050b20004200370308200041206a20023602002000411c6a2007360200200041186a2005200141ff0171411074722008722006723602004201210b0c0f0b410221052002280200220741ff017122064103470d0920064103462105200241046a2802002102200341a0016a200141046a280200220810dd06200341186a20032802a001220920032802a80110fc01200328021c210620032802182101024020032802a401450d00200910290b2002200720051b21070240024020014101470d0020062007460d010b200341a0016a200710dd0620032802a001210120033502a801210b20032008360278200b4220862001ad84200341f8006aad4280808080c00084100320032802a401450d08200110290c080b200341a0016a200710c304200341106a20032802a001220220032802a8014180a6cc004100410010c70120032802102101024020032802a401450d00200210290b0240024020014101460d00200341a0016a200810c30441002105200341086a20032802a001220220032802a8014180a6cc004100410010c70120032802082101024020032802a401450d00200210290b20014101470d0141d29ec400450d010c0b0b4100210541d29ec4000d0a0b200341a0016a200810dd0620033502a80142208620032802a0012201ad841004024020032802a401450d00200110290b2003420037033820034200370330200342003703282003420037032041d787cc00ad4280808080900184221110012201290000210b200341f8006a41086a2215200141086a2900003703002003200b370378200110292003201529030037032820032003290378370320419a88cc00ad4280808080a00184221210012201290000210b2015200141086a2900003703002003200b37037820011029200341a0016a41086a220a2003290328370300200341a0016a41106a220e2003290378220b370300200341a0016a41186a221020152903003703002003200b370330200320032903203703a001200341f8006a200341a0016a10fd0520032802782201410420011b21230240200329027c420020011b2214422088a72222450d0020232022410c6c6a21212023211803400240201841086a22162802002209450d002018280200210141002102410021050340024002400240200720012802002206460d0020082006460d0020020d01410021020c020b200241016a21020c010b200520026b220620094f0d08200341a0016a41206a220f20012002415c6c6a220641206a220d2802003602002010200641186a2219290200370300200e200641106a221a290200370300200a200641086a221b290200370300200320062902003703a001200141206a221c280200211d200141186a221e290200210b200141106a221f290200210c200141086a2217290200212020062001290200370200201b2020370200201a200c3702002019200b370200200d201d360200201c200f280200360200201e2010290300370200201f200e2903003702002017200a290300370200200120032903a0013702000b200141246a21012009200541016a2205470d000b2002450d002016280200200920026b2201490d00201620013602000b2018410c6a22182021470d000b0b200320233602482003201437024c20034200370338200342003703302003420037032820034200370320201110012201290000210b2015200141086a2900003703002003200b370378200110292003201529030037032820032003290378370320201210012201290000210b2015200141086a2900003703002003200b37037820011029200341206a41107222132003290378370000201341086a2015290300370000200a2003290328370300200e200329033037030020102003290338370300200320032903203703a0012003412036027c2003200341a0016a360278200341c8006a200341f8006a10ee052014a7210602402022450d002022410c6c21022023210103400240200141046a2802002205450d00200541246c450d00200128020010290b2001410c6a2101200241746a22020d000b0b02402006450d002006410c6c450d00202310290b2003420037033820034200370330200342003703282003420037032041d787cc00ad4280808080900184221110012201290000210b200341f8006a41086a2215200141086a2900003703002003200b37037820011029200320152903003703282003200329037837032041eb87cc00ad4280808080f00184221210012201290000210b2015200141086a2900003703002003200b3703782001102920132003290378370000201341086a22242015290300370000200341a0016a41086a220a2003290328370300200341a0016a41106a220e2003290330370300200341a0016a41186a22102003290338370300200320032903203703a001200341f8006a200341a0016a10fd0520032802782201410420011b21230240200329027c420020011b2214422088a72222450d0020232022410c6c6a21212023211803400240201841086a22162802002209450d002018280200210141002102410021050340024002400240200720012802002206460d0020082006460d0020020d01410021020c020b200241016a21020c010b200520026b220620094f0d09200341a0016a41206a220f20012002415c6c6a220641206a220d2802003602002010200641186a2219290200370300200e200641106a221a290200370300200a200641086a221b290200370300200320062902003703a001200141206a221c280200211d200141186a221e290200210b200141106a221f290200210c200141086a2217290200212020062001290200370200201b2020370200201a200c3702002019200b370200200d201d360200201c200f280200360200201e2010290300370200201f200e2903003702002017200a290300370200200120032903a0013702000b200141246a21012009200541016a2205470d000b2002450d002016280200200920026b2201490d00201620013602000b2018410c6a22182021470d000b0b200320233602482003201437024c20034200370338200342003703302003420037032820034200370320201110012201290000210b2015200141086a2900003703002003200b370378200110292003201529030037032820032003290378370320201210012201290000210b2015200141086a2900003703002003200b370378200110292013200329037837000020242015290300370000200a2003290328370300200e200329033037030020102003290338370300200320032903203703a0012003412036027c2003200341a0016a360278200341c8006a200341f8006a10ee052014a7210602402022450d002022410c6c21022023210103400240200141046a2802002205450d00200541246c450d00200128020010290b2001410c6a2101200241746a22020d000b0b02402006450d002006410c6c450d00202310290b2003420037033820034200370330200342003703282003420037032041d787cc00ad4280808080900184220b10012201290000210c200341f8006a41086a2206200141086a2900003703002003200c37037820011029200320062903003703282003200329037837032041fa87cc00ad4280808080e00084220c1001220129000021202006200141086a290000370300200320203703782001102920132003290378370000201341086a220e2006290300370000200341a0016a41086a22102003290328370300200341b0016a220f2003290330370300200341b8016a220d2003290338370300200320032903203703a001200341f8006a200341a0016a10a60320032802782201410420011b21090240200329027c420020011b2220422088a7220a450d00200a412c6c210220092101034002400240200128020022052007460d0020082005470d010b200141246a22052802004102460d00200541003602000b2001412c6a2101200241546a22020d000b0b20034200370338200342003703302003420037032820034200370320200b10012201290000210b2006200141086a2900003703002003200b370378200110292003200629030037032820032003290378370320200c10012201290000210b2006200141086a2900003703002003200b3703782001102920132003290378370000200e200629030037000020102003290328370300200f2003290330370300200d2003290338370300200320032903203703a0012003412036027c2003200341a0016a3602782009200a200341f8006a10f00302402020a72201450d002001412c6c450d00200910290b2003420037033820034200370330200342003703282003420037032041d787cc00ad4280808080900184220b10012202290000210c200341f8006a41086a2201200241086a2900003703002003200c37037820021029200320012903003703282003200329037837032041cd87cc00ad4280808080a00184220c1001220229000021202001200241086a290000370300200320203703782002102920132003290378370000201341086a22062001290300370000200341a0016a41086a22092003290328370300200341b0016a220a2003290330370300200341b8016a220e2003290338370300200320032903203703a001200341f8006a200341a0016a412010c00420032802782202410420021b2205200329027c420020021b2220422088a722102007200810de0620034200370338200342003703302003420037032820034200370320200b10012202290000210b2001200241086a2900003703002003200b370378200210292003200129030037032820032003290378370320200c10012202290000210b2001200241086a2900003703002003200b37037820021029201320032903783700002006200129030037000020092003290328370300200a2003290330370300200e2003290338370300200320032903203703a0012003412036027c2003200341a0016a36027820052010200341f8006a10ef030240202042ffffffff0383500d00200510290b200341f8006a200710dc062003280278220120032802800122061090062105200341a0016a200810dc0620032802a001220220032802a8012209109006210a02400240200541ff0171220e4102470d002009ad4220862002ad8410040c010b410110272205450d062005200e4101463a00002009ad4220862002ad842005ad428080808010841003200510290b200a41ff01712105024020032802a401450d00200210290b0240024020054102470d002006ad4220862001ad8410040c010b410110272202450d06200220054101463a00002006ad4220862001ad842002ad428080808010841003200210290b0240200328027c450d00200110290b200341c8006a200710db06200341a0016a200328024822052003280250220910cd01200341a9016a2201290000210b200341b1016a2202290000210c200341b9016a220a290000212020032d00a001210e20032900a1012114200341f8006a200810db06200341a0016a20032802782206200328028001221010cd0120032d00a001210f200a2900002111200229000021122001290000212520032900a1012126412010272201450d002001200c4200200e41ff017141014622021b3700102001200b420020021b37000820012014420020021b370000200141186a2020420020021b3700002010ad4220862006ad842001ad42808080808004841003200110290240200328027c450d00200610290b412010272201450d00200120264200200f41014622021b37000020012025420020021b37000820012012420020021b370010200141186a2011420020021b3700002009ad4220862005ad842001ad42808080808004841003200110290240200328024c450d00200510290b200341206a200710c204200341c8006a200810c204200341f8006a200335022842208620032802202202ad84220b1007108b02200341a0016a200335025042208620032802482205ad84220c1007108b02024020032802a0012201450d0020032802a4012106200b200341a8016a3502004220862001ad8410032006450d07200110290c070b200b10040c060b1039000b200620084180bdc7001036000b200620084180bdc7001036000b200620094180bdc7001036000b200620094180bdc7001036000b1030000b0240024020032802782201450d00200328027c2106200c20034180016a3502004220862001ad8410032006450d01200110290c010b200c10040b0240200328024c450d00200510290b02402003280224450d00200210290b200341206a200710c504200341c8006a200810c504200341f8006a200335022842208620032802202202ad84220b1007108b02200341a0016a200335025042208620032802482205ad84220c1007108b020240024020032802a0012201450d0020032802a4012106200b200341a8016a3502004220862001ad8410032006450d01200110290c010b200b10040b0240024020032802782201450d00200328027c2106200c20034180016a3502004220862001ad8410032006450d01200110290c010b200c10040b0240200328024c450d00200510290b02402003280224450d00200210290b200341a0016a41186a220a4200370300200341a0016a41106a22054200370300200341a0016a41086a22024200370300200342003703a00141d482cc00ad4280808080d00084220b10012206290000210c200341c8006a41086a2201200641086a2900003703002003200c3703482006102920022001290300370300200320032903483703a00141e782cc00ad4280808080a00184220c1001220629000021202001200641086a2900003703002003202037034820061029200520032903482220370300200341f8006a41086a220e2002290300370300200341f8006a41106a22102020370300200341f8006a41186a220f2001290300370300200320032903a001370378200341a0016a200341f8006a412010c00420032802a0012206410420061b220920032902a401420020061b2220422088a722062007200810de06200a42003703002005420037030020024200370300200342003703a001200b10012207290000210b2001200741086a2900003703002003200b3703482007102920022001290300370300200320032903483703a001200c10012207290000210b2001200741086a2900003703002003200b3703482007102920052003290348220b370300200e20022903003703002010200b370300200f2001290300370300200320032903a001370378200341203602a4012003200341f8006a3602a00120092006200341a0016a10ef03202042ffffffff0383500d00200910290b4200210b0b2000200b3703080c050b20004200370308200041206a41223602002000411c6a41d29ec400360200200041186a20053602004201210b0c040b02402009450d00200e10290b0240200a450d00201010290b20004200370308200041206a20053602002000411c6a2007360200200041186a2006411874200841ff017141107472200241ff017141087472200141ff0171723602004201210b0c030b02402005450d00200610290b2007450d00200810290b200328024821012000411c6a200329024c370200200041186a20013602004201210b0b200042003703080b2000200b370300200424000bad0905037f017e027f047e017f230041a0026b22022400200241c8006a200110cd052002280248210320022002280250220436028c022002200336028802200241f8006a2004ad4220862003ad841007108b0202400240200228027822040d00420021050c010b200228027c2106024002400240200241f8006a41086a28020022074110490d0020074170714110460d002007417c714120470d010b20024100360260200242013703582002410d36029402200220024188026a360290022002200241d8006a36029c022002419c016a41013602002002420137028c01200241f4eaca0036028801200220024190026a360298012002419c026a41a8a3c80020024188016a10371a200235026042208620023502588410080240200228025c450d00200228025810290b420021050c010b200441086a290000210820042900002109200441186a290000210a2004290010210b20042800202107420121050b2006450d00200410290b0240200228024c450d00200310290b02400240024002402005500d0020024188016a41186a420037030020024188016a41106a2206420037030020024188016a41086a22034200370300200242003703880141b3e6ca00ad4280808080e000841001220429000021052003200441086a29000037030020022005370388012004102941c9e6ca00ad4280808080e00084100122042900002105200241f8006a41086a220c200441086a2900003703002002200537037820041029200620022903782205370300200241d8006a41086a2003290300370300200241d8006a41106a2005370300200241d8006a41186a200c2903003703002002200229038801370358200241306a200241d8006a412010fc01200241106a200a420041002002280234410020022802301b220320076b2204200420034b1bad2205420010d507200241206a20054200200b420010d507200242004200200b420010d5072002290308200229031884420052200241206a41086a2903002205200229030020022903107c7c220b200554720d0142002009200229032022057d220a200a2009562008200b7d2009200554ad7d220520085620052008511b22031b220b4200200520031b220584500d01200242f6cacda397cddbb320370340200241c0006a2001200b2005410610aa02200241c0016a2005370300200241b8016a200b37030020024188016a41086a41003a000020024191016a200129000037000020024199016a200141086a290000370000200241a1016a200141106a290000370000200241a9016a200141186a290000370000200241123a00880120024188016a21010c020b2000411c3b0001200041086a410a360200200041046a41b8b3c700360200410321010c020b200242f6cacda397cddbb320370338200241386a200110ac0220024188016a200110cd052002350290014220862002280288012203ad8410040240200228028c01450d00200310290b20024188016a41086a41013a000020024191016a200129000037000020024199016a200141086a290000370000200241a1016a200141106a290000370000200241a9016a200141186a290000370000200241123a00880120024188016a21010b200110cb01410421010b200020013a0000200241a0026a24000bbc0505017f017e017f017e047f230041d0006b2202240041dfb3c700ad4280808080f000842203100122042900002105200241086a200441086a29000037030020022005370300200410292003100122042900002103200241106a41086a200441086a29000037030020022003370310200410290240024002400240412010272204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a2900003700002004ad4280808080800484100522012900002103200241306a41086a200141086a2900003703002002200337033020011029200241cc006a200441206a360200200220043602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a1075200410292002280228220641206a2201417f4c0d01200228022021070240024020010d0041002108410121040c010b200110272204450d01200121080b024002402008410f4d0d00200821090c010b200841017422094110200941104b1b22094100480d03024020080d002009102722040d010c050b20082009460d00200420082009102b2204450d040b20042002290300370000200441086a200241086a2903003700000240024020094170714110460d00200921080c010b200941017422084120200841204b1b22084100480d0320092008460d00200420092008102b2204450d040b20042002290310370010200441186a200241106a41086a29030037000002400240200841606a2006490d00200821090c010b2006415f4b0d03200841017422092001200920014b1b22094100480d0320082009460d00200420082009102b2204450d040b200441206a2007200610e4071a20002001360208200020093602042000200436020002402002280224450d00200710290b200241d0006a24000f0b1039000b1038000b1032000b1030000bb317021b7f057e23004180046b2203240002400240024020012002460d00200341d4036a21040340200341f0036a200110d50220034190036a20032802f003220520032802f80310f805200341d0026a41086a220620034190036a41086a290300370300200341d0026a41106a220720034190036a41106a290300370300200341d0026a41186a220820034190036a41186a290300370300200341d0026a41206a220920034190036a41206a290300370300200341d0026a41286a220a20034190036a41286a290300370300200341d0026a41306a220b20034190036a41306a290300370300200341d0026a41386a220c20034190036a41386a290300370300200341b0026a41086a220d200441086a290200370300200341b0026a41106a220e200441106a290200370300200341b0026a41186a220f200441186a28020036020020032003290390033703d002200320042902003703b002024020032802d0032210450d00200341f0016a41386a200c290300370300200341f0016a41306a200b290300370300200341f0016a41286a200a290300370300200341f0016a41206a2009290300370300200341f0016a41186a2008290300370300200341f0016a41106a2007290300370300200341f0016a41086a2006290300370300200341d0016a41086a200d290300370300200341d0016a41106a200e290300370300200341d0016a41186a200f280200360200200320032903d0023703f001200320032903b0023703d0010b024020032802f403450d00200510290b20100d022002200141206a2201470d000b0b20004100360208200042083702000c010b200341306a41386a2204200341f0016a41386a290300370300200341306a41306a2205200341f0016a41306a290300370300200341306a41286a2206200341f0016a41286a290300370300200341306a41206a2207200341f0016a41206a290300370300200341306a41186a2208200341f0016a41186a290300370300200341306a41106a2209200341f0016a41106a290300370300200341306a41086a220a200341f0016a41086a290300370300200341106a41086a220b200341d0016a41086a290300370300200341106a41106a220c200341d0016a41106a290300370300200341106a41186a220d200341d0016a41186a280200360200200320032903f001370330200320032903d00137031020034190016a41086a220e200a29030037030020034190016a41106a220a200929030037030020034190016a41186a2209200829030037030020034190016a41206a2208200729030037030020034190016a41286a2207200629030037030020034190016a41306a2206200529030037030020034190016a41386a22052004290300370300200341f0006a41086a2204200b290300370300200341f0006a41106a220b200c290300370300200341f0006a41186a220c200d28020036020020032003290330370390012003200329031037037020034190036a41086a220d200e29030037030020034190036a41106a220e200a29030037030020034190036a41186a220a200929030037030020034190036a41206a2209200829030037030020034190036a41286a2208200729030037030020034190036a41306a2207200629030037030020034190036a41386a22062005290300370300200320032903900137039003200341d0026a41086a22052004290300370300200341d0026a41106a2204200b290300370300200341d0026a41186a220b200c280200360200200320032903703703d0020240024041e00010272211450d00201120032903900337030020112010360240201120032903d002370244201141386a2006290300370300201141306a2007290300370300201141286a2008290300370300201141206a2009290300370300201141186a200a290300370300201141106a200e290300370300201141086a200d290300370300201141cc006a2005290300370200201141d4006a2004290300370200201141dc006a200b280200360200200342818080801037020420032011360200200241606a2001460d01200241406a211220034190036a41c4006a2110410121080340200341f0036a200141206a221310d50220034190036a20032802f003220420032802f80310f805200341d0026a41086a220520034190036a41086a220a290300370300200341d0026a41106a220620034190036a41106a220b290300370300200341d0026a41186a220720034190036a41186a220c290300370300200341d0026a41206a221420034190036a41206a220d290300370300200341d0026a41286a221520034190036a41286a220e290300370300200341d0026a41306a221620034190036a41306a220f290300370300200341d0026a41386a221720034190036a41386a2202290300370300200341b0026a41086a2218201041086a290200370300200341b0026a41106a2219201041106a290200370300200341b0026a41186a221a201041186a28020036020020032003290390033703d002200320102902003703b002024020032802d0032209450d00200341f0016a41386a2017290300370300200341f0016a41306a2016290300370300200341f0016a41286a2015290300370300200341f0016a41206a2014290300370300200341f0016a41186a2007290300370300200341f0016a41106a2006290300370300200341f0016a41086a2005290300370300200341d0016a41086a2018290300370300200341d0016a41106a2019290300370300200341d0016a41186a201a280200360200200320032903d0023703f001200320032903b0023703d0010b024020032802f403450d00200410290b0240024020090d0020122001460d040c010b200341306a41386a2204200341f0016a41386a290300370300200341306a41306a2214200341f0016a41306a290300370300200341306a41286a2215200341f0016a41286a290300370300200341306a41206a2216200341f0016a41206a290300370300200341306a41186a2217200341f0016a41186a290300370300200341306a41106a2218200341f0016a41106a290300370300200341306a41086a2219200341f0016a41086a290300370300200341106a41086a221a200341d0016a41086a290300370300200341106a41106a221b200341d0016a41106a290300370300200341106a41186a221c200341d0016a41186a280200360200200320032903f001370330200320032903d00137031020034190016a41086a221d201929030037030020034190016a41106a2219201829030037030020034190016a41186a2218201729030037030020034190016a41206a2217201629030037030020034190016a41286a2216201529030037030020034190016a41306a2215201429030037030020034190016a41386a22142004290300370300200341f0006a41086a2204201a290300370300200341f0006a41106a221a201b290300370300200341f0006a41186a221b201c280200360200200320032903303703900120032003290310370370200a201d290300370300200b2019290300370300200c2018290300370300200d2017290300370300200e2016290300370300200f201529030037030020022014290300370300200320032903900137039003200520042903003703002006201a2903003703002007201b280200360200200320032903703703d002024020082003280204470d0020032008410110a701200328020021110b2011200841e0006c6a2204200329039003370300200441106a200b290300370300200441086a200a290300370300200f290300211e2002290300211f200e2903002120200d2903002121200c2903002122200441c0006a2009360200200441186a2022370300200441206a2021370300200441286a2020370300200441c4006a20032903d002370200200441386a201f370300200441306a201e370300200441cc006a2005290300370200200441d4006a2006290300370200200441dc006a20072802003602002003200841016a220836020820122001460d030b201321010c000b0b1039000b20002003290300370200200041086a200341086a2802003602000b20034180046a24000bf304010a7f230041106b220324000240024002400240200241246c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410272205450d020b20034100360208200320053602002003200436020420022003107102402002450d002001200241246c6a2106200328020421052003280208210203402001280200210402400240200520026b4104490d0020032802002107200521080c010b200241046a22082002490d05200541017422072008200720084b1b22084100480d050240024020050d00024020080d00410121070c020b2008102722070d010c080b2003280200210720052008460d00200720052008102b2207450d070b20032008360204200320073602000b200720026a20043600002003200241046a2209360208412010272204450d03200441186a220a2001411c6a290000370000200441106a220b200141146a290000370000200441086a220c2001410c6a2900003700002004200141046a29000037000002400240200820096b4120490d00200241246a2102200821050c010b200941206a22022009490d05200841017422052002200520024b1b22054100480d050240024020080d00024020050d00410121070c020b200510272207450d080c010b20082005460d00200720082005102b2207450d070b20032005360204200320073602000b200720096a22082004290000370000200841186a200a290000370000200841106a200b290000370000200841086a200c2900003700002003200236020820041029200141246a22012006470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1038000b1039000b1032000b1030000be30402087f027e230041106b2202240002400240200028020822034105744114722204417f4c0d000240200410272205450d002002410036020820022004360204200220053602002000280200210620032002107102400240024020030d0020022802042107200228020821050c010b20034105742108200228020021092002280204210720022802082105034020062103024002402007200522046b4120490d00200441206a21050c010b200441206a22052004490d03200741017422062005200620054b1b22064100480d03024002400240024020070d00024020060d00410121090c020b2006102721090c030b20072006470d010b200621070c020b200920072006102b21090b200621072009450d060b200341206a2106200920046a22042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a290000370000200841606a22080d000b2002200736020420022005360208200220093602000b200041186a290300210a2000290310210b02400240200720056b4110490d00200541106a210620022802002103200721040c010b200541106a22062005490d01200741017422032006200320064b1b22044100480d010240024020070d00024020040d00410121030c020b200410272203450d060c010b2002280200210320072004460d00200320072004102b2203450d050b20022004360204200220033602000b200320056a2205200a3700082005200b37000020012902002006ad4220862003ad84100302402004450d00200310290b200241106a24000f0b1032000b1039000b1038000b1030000bab2306087f057e027f067e047f077e230041e0056b2204240020044180036a200210dd0420044180046a200428028003220520042802880310d30520044190036a41086a2206200441c0046a29030037030020044190036a41106a2207200441c8046a29030037030020044190036a41186a2208200441d0046a29030037030020044190036a41206a2209200441d8046a29030037030020044190036a41286a220a200441e0046a2903003703002004200441b8046a29030037039003024002400240024020042d008004220b4102460d00200441b0046a290300210c20044180046a41286a290300210d20044180046a41206a290300210e20044180046a41186a290300210f20044180046a41106a29030021102004418c046a280200211120044180046a41086a2802002112200441f0046a41286a200a290300370300200441f0046a41206a2009290300370300200441f0046a41186a2008290300370300200441f0046a41106a2007290300370300200441f0046a41086a200629030037030020042004290390033703f0040240200428028403450d00200510290b200441d0026a41086a2206200441f0046a41086a2903002213370300200441d0026a41106a2207200441f0046a41106a2903002214370300200441d0026a41186a2208200441f0046a41186a2903002215370300200441d0026a41206a2209200441f0046a41206a2903002216370300200441d0026a41286a220a200441f0046a41286a2903002217370300200420042903f00422183703d00220044180046a41286a2219201737030020044180046a41206a221a201637030020044180046a41186a221b201537030020044180046a41106a2205201437030020044180046a41086a221c20133703002004201837038004200b450d01411410d5042102200441e0016a411410d60420042802e401210320042802e00121050c020b0240200428028403450d00200510290b411410d5042102200441086a411410d604200428020c2103200428020821050c010b20044198026a41286a2019290300221337030020044198026a41206a201a2903002214370300200441e8016a41086a220b201c290300370300200441e8016a41106a22192005290300370300200441e8016a41186a221a201b290300370300200441e8016a41206a221b2014370300200441e8016a41286a221c201337030020042004290380043703e801200a201c2903003703002009201b2903003703002008201a290300370300200720192903003703002006200b290300370300200420042903e8013703d002200341186a2903002118200341086a2903002114200341206a290300211d200341106a290300211320032d0000210720044190036a200110a80220044180046a200428029003220920042802980310a902427f2013201d7c201420187c22162014542206ad7c22152006201520135420152013511b22061b2013200741014622081b2115427f201620061b201420081b21172005290300420020042903800442015122051b2116200429038804420020051b211e0240200428029403450d00200910290b0240024002400240024002400240024002400240024002402017201e56201520165620152016511b0d002011ad4220862012ad84211620044198026a200110df0520044180046a200428029802220b20042802a002221a10e00520042d0080042105200441f0046a20044180046a41017241ef0010e4071a024020054102470d004108210a20044190036a41086a4200370300200441a0036a221b4200370300200441a8036a4200370300200441b0036a4200370300200441b8036a4200370300200441c0036a4200370300200441c8036a420037030041002105200441d0036a4100360200200441003a009003200441083602940320044190036a4104722119410021080c060b200420053a00900320044190036a410172200441f0046a41ef0010e4071a02402005450d00411e21032004411e3a00800420044180046a21060c080b200441a0036a211b20044190036a4104722119200428029403210a41002105024002402004419c036a280200221c41014b0d0041002108201c0e020701070b201c2106034020052006410176220820056a2209200a200941306c6a28020020024b1b2105200620086b220641014b0d000b0b024002400240200a200541306c6a28020022062002460d00201c41e4004b0d01200520062002496a2105201c21080c080b201c20054d0d01200a200541306c6a220541186a290300211f200541106a290300211e0240024020052d000822064101470d0020044180016a200541206a2903002220200541286a2903002221420a420010e00720044190016a201e201f420a420010e007200d201e7d2222200d56200c201f7d200d201e54ad7d221e200c56201e200c511b0d05202220207d2223202256201e20217d2022202054ad7d221f201e56201f201e511b0d052016200429039001220c7d2222201656201020044190016a41086a2903007d2016200c54ad7d221e201056201e2010511b450d012023210d201f210c0c050b200541096a2d00002108024002402005410a6a2d0000220941ff0171450d00200441c0016a201f42002009ad42ff01832222420010d507200441d0016a201e42002022420010d507200441b0016a42004200201e420010d507427f200441d8016a290300222220042903c00120042903b0017c7c222020042903c80120042903b8018442005220202022547222091b2121427f20042903d00120091b21220c010b200441a0016a201e201f420a420010e007200441a8016a290300212120042903a00121220b200d201e7d2220200d56200c201f7d200d201e54ad7d221e200c56201e200c511b0d0402400240200841ff01710d00200f20227d220d200f56200e20217d200f202254ad7d220c200e56200c200e511b0d01200d210f200c210e201621232010211f0c080b201620227d2223201656201020217d2016202254ad7d221f201056201f2010511b450d070b2020210d201e210c0c040b0240200f20042903800122167d2210200f56200e20044180016a41086a2903007d200f201654ad7d2216200e562016200e511b450d002023210d201f210c20222116201e21100c040b2023210d201f210c2010210f2016210e20222116201e21100c060b41272103200441273a00800420044180046a21060c030b2005201c41f0a4c7001036000b412110d5042102200441106a412110d60420042903102113200041026a20023a000020004183223b0100200041046a20133702000c0c0b41202103200441203a00800420044180046a21060b410021050c040b0240024020060d00200841ff01714102460d004200201e200441b8036a2903007d2020200441b0036a290300220c54ad7d22162020200c7d220d2020562016201e562016201e511b22061b210c4200200d20061b210d200441a8036a290300211020042903a0032116024020084101710d004200200e20107d200f201654ad7d2210200f20167d2216200f562010200e562010200e511b22061b210e4200201620061b210f0c020b4200201f20107d2023201654ad7d2210202320167d22162023562010201f562010201f511b22061b21104200201620061b21160c020b2020210d201e210c0b20232116201f21100b200541086a22052003290300370300200541206a200341206a290300370300200541186a200341186a290300370300200541106a200341106a290300370300200541086a200341086a2903003703000c010b200441a4046a200341206a2902003702002004419c046a200341186a29020037020020044194046a200341106a2902003702002004418c046a200341086a290200370200200420032902003702840420082005490d020240200820044190036a41086a280200470d002019200841011090012019280200210a0b200a200541306c6a220641306a2006200820056b41306c10e5071a2006200236020020062004290280043702042006410c6a20044188046a290200370200200641146a20044190046a2902003702002006411c6a20044198046a290200370200200641246a200441a0046a2902003702002006412c6a200441a8046a2802003602002004200841016a36029c030b02400240024020074101470d00200441206a2018201d420a420010e007200441306a20142013420a420010e007200d20147c221f200d542203200c20137c2003ad7c221e200c54201e200c511b0d02201f20187c2214201f542203201e201d7c2003ad7c2213201e542013201e511b0d02201620042903307c221d20165422032010200441306a41086a2903007c2003ad7c221820105420182010511b0d01200f20042903207c220d200f542203200e200441206a41086a2903007c2003ad7c220c200e54200c200e511b450d062014210d2013210c201d2116201821100c020b20032d0001210502400240200341026a2d0000220341ff0171450d00200441e0006a201342002003ad42ff01832218420010d507200441f0006a201442002018420010d507200441d0006a420042002014420010d507427f200441f8006a2903002218200429036020042903507c7c221d2004290368200429035884420052201d2018547222031b2118427f200429037020031b211d0c010b200441c0006a20142013420a420010e007200441c8006a29030021182004290340211d0b200d20147c2214200d542203200c20137c2003ad7c2213200c542013200c511b0d010240200541ff01710d00200f201d7c220c200f542203200e20187c2003ad7c2218200e542018200e511b0d01200c210f2018210e2016211d201021180c050b2016201d7c221d2016542203201020187c2003ad7c221820105420182010511b450d040b2014210d2013210c0b411f21032004411f3a00800420044180046a210620042d00900321050b200310d5042107200441186a20062d000010d604200428021c210820042802182106410321030240200541ff01710d0020044198036a2802002205450d00200541306c450d0020042802940310290b200d2114200c2113200f210d200e210c2016211d201021180c030b200520081041000b024020070d00200541ff01714102460d00427f2013200441b8036a2903007c2014200441b0036a2903007c22162014542203ad7c22142003201420135420142013511b22031b2113427f201620031b2114201b41086a2903002116201b290300210c024020054101710d00427f200e20167c200f200c7c220d200f542203ad7c221620032016200e542016200e511b22031b210c427f200d20031b210d0c020b427f201820167c201d200c7c220c201d542203ad7c22162003201620185420162018511b22031b2118427f200c20031b211d0b200f210d200e210c0b20044180046a20044190036a41f00010e4071a024020042d00800422034102470d00201aad422086200bad841004410421030c010b200441f0046a20044180046a10a105201aad422086200bad8420043502f80442208620042802f0042205ad841003024020042802f404450d00200510290b024020030d0020044188046a2802002203450d00200341306c450d0020042802840410290b410421030b0240200428029c02450d00200b10290b024020034104470d00200442e4cab5fbb6ccdcb0e3003703c802200441c8026a20012017201510e503200441b0046a201337030020044180046a41286a201437030020044180046a41206a200c37030020044180046a41186a200d37030020044180046a41106a2018370300200441b8046a20042903d002370300200441c0046a200441d8026a290300370300200441c8046a200441d0026a41106a290300370300200441d0046a200441d0026a41186a290300370300200441d8046a200441d0026a41206a290300370300200441e0046a200441d0026a41286a2903003703002004201d37038804200441003a00800420044190036a200210dd04200428029003210220042004280298033602f404200420023602f00420044180046a200441f0046a10de040240200428029403450d00200210290b200041043a00000c020b200041113a0001200020033a0000200041086a2008360000200041046a2006360000200041026a20073a00000c010b200041046a2003ad4220862005ad843702002000200241ff0171411074418322723602000b200441e0056a24000b810703047f017e027f23004180016b22022400200241186a2203200141186a290000370300200241106a2204200141106a290000370300200241086a2205200141086a2900003703002002200129000037030041c99fc500ad4280808080900184100122012900002106200241286a41086a200141086a290000370300200220063703282001102941a891c700ad4280808080d00084100122012900002106200241386a41086a200141086a29000037030020022006370338200110290240024002400240412010272201450d0020012002290300370000200141186a2003290300370000200141106a2004290300370000200141086a200529030037000020022001ad42808080808004841002220329000037037820031029200241e4006a200141206a360200200220013602602002200241f8006a41086a36025c2002200241f8006a360258200241c8006a200241d8006a1075200110292002280250220741206a2203417f4c0d01200228024821080240024020030d0041002104410121010c010b200310272201450d01200321040b024002402004410f4d0d00200421050c010b200441017422054110200541104b1b22054100480d03024020040d002005102722010d010c050b20042005460d00200120042005102b2201450d040b20012002290328370000200141086a200241286a41086a2903003700000240024020054170714110460d00200521040c010b200541017422044120200441204b1b22044100480d0320052004460d00200120052004102b2201450d040b20012002290338370010200141186a200241386a41086a29030037000002400240200441606a2007490d00200421050c010b2007415f4b0d03200441017422052003200520034b1b22054100480d0320042005460d00200120042005102b2201450d040b200141206a2008200710e4071a0240200228024c450d00200810290b20022001200310d905200241e0006a2203200241096a290000370300200241e8006a2204200241116a290000370300200241f0006a2207200241196a290000370300200220022900013703580240024020022d000022084102470d00200041023a00000c010b200020083a000020002002290358370001200041096a2003290300370000200041116a2004290300370000200041196a20072903003700000b02402005450d00200110290b20024180016a24000f0b1039000b1038000b1032000b1030000be00903067f067e057f230041a0016b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022040d00200041023a00000c010b2003280214210502400240200341186a2802002206450d0020042d0000220141014b0d002006417f6a210202400240024020010e020001000b20024104490d022004280001210741002101200341003a0098012006417b6a21080240034020082001460d01200341f8006a20016a200420016a41056a2d00003a00002003200141016a22023a0098012002210120024120470d000b200341d8006a41186a200341f8006a41186a290300370300200341d8006a41106a200341f8006a41106a290300370300200341d8006a41086a200341f8006a41086a290300370300200320032903783703582006417b6a2002460d03200420026a220141056a2d0000220841034f0d03200620026b2202417a6a4104490d03200241766a4110490d03200241666a4110490d03200241566a4110490d03200141066a2800002106200141126a29000021092001410a6a290000210a200341286a41086a200341d8006a41086a290300370300200341286a41106a200341d8006a41106a290300370300200341286a41186a200341d8006a41186a29030037030020032003290358370328200320032800503602202003200341d3006a280000360023200141326a290000210b2001412a6a290000210c200141226a290000210d2001411a6a290000210e200320032f014e3b014c410021010c020b200141ff0171450d02200341003a0098010c020b2002450d0120042d0001220141014b0d012006417e6a2108410021020240024020010e020100010b410121020b200841034d0d01200341286a41086a200341f8006a41086a290300370300200341286a41106a200341f8006a41106a290300370300200341286a41186a200341f8006a41186a29030037030020032003290378370328200320032800583602202003200341d8006a41036a2800003600232004280002210f410121010b200341f8006a41086a2210200341286a41086a290300370300200341f8006a41106a2211200341286a41106a290300370300200341f8006a41186a2212200341286a41186a290300370300200320032f014c22133b015020032003290328370378200320032802203602582003200328002336005b200041306a200b370000200041286a200c370000200041206a200d370000200041186a200e370000200041106a2009370000200041086a200a370000200020023a00012000413c6a2006360000200041386a2007360000200041046a200f360000200041026a20133b0000200041e0006a20083a0000200041c0006a2003290378370000200041c8006a2010290300370000200041d0006a2011290300370000200041d8006a2012290300370000200041e1006a2003280258360000200041e4006a200328005b3600000c010b20034100360260200342013703582003410d36022c2003200341086a3602282003200341d8006a3602502003418c016a41013602002003420137027c200341f4eaca003602782003200341286a36028801200341d0006a41a8a3c800200341f8006a10371a200335026042208620033502588410080240200328025c450d00200328025810290b410221010b200020013a00002005450d00200410290b200341a0016a24000b9f0303027f017e027f230041206b2202240041c99fc500ad4280808080900184100122032900002104200241086a200341086a290000370300200220043703002003102941e893c700ad4280808080d00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000bde0201037f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d00200041003602040c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d0020032002417c6a3602242003200141046a36022020012800002102200341c8006a200341206a109602200328024822050d010b20034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b200041003602040c010b2000200329024c37020820002005360204200020023602000b2004450d00200110290b200341e0006a24000ba10202067f017e230041106b2202240002400240412010272203450d0020032000290000370000200341186a2204200041186a290000370000200341106a2205200041106a290000370000200341086a2206200041086a290000370000412010272207450d0120072003290000370000200741186a2004290000370000200741106a2005290000370000200741086a2006290000370000200310290240024020002d0020220341024d0d004280808080800421080c010b024002400240024020030e03000102000b410021030c020b410121030c010b410221030b200220033a000f2007412041c000102b2207450d02200720033a00204280808080900421080b200129020020082007ad84100320071029200241106a24000f0b1039000b1030000b9f0303027f017e027f230041206b2202240041c99fc500ad4280808080900184100122032900002104200241086a200341086a2900003703002002200437030020031029419c93c700ad4280808080900184100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000bb10503027f017e047f230041d0006b2202240041c99fc500ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941a891c700ad4280808080d00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000bab0602057f047e23004190016b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022040d00200041023a00000c010b2003280214210502400240200341186a2802002201450d0020042d0000220241014b0d002001417f6a2106024002400240024020020e020001000b41002101200341003a008801200441016a21070240034020062001460d01200341e8006a20016a200720016a2d00003a00002003200141016a22023a0088012002210120024120470d000b200341c8006a41186a200341e8006a41186a2903002208370300200341206a41086a200341e8006a41086a290300370300200341206a41106a200341e8006a41106a290300370300200341206a41186a200837030020032003290368370320410021010c020b200141ff0171450d03200341003a0088010c030b41002101200341003a008801200441016a2107034020062001460d02200341e8006a20016a200720016a2d00003a00002003200141016a22023a0088012002210120024120470d000b200341c8006a41186a200341e8006a41186a2903002208370300200341206a41086a200341e8006a41086a290300370300200341206a41106a200341e8006a41106a290300370300200341206a41186a200837030020032003290368370320410121010b200341e8006a41186a200341206a41186a2903002208370300200341e8006a41106a200341206a41106a2903002209370300200341e8006a41086a200341206a41086a290300220a37030020032003290320220b370368200041196a2008370000200041116a2009370000200041096a200a3700002000200b3700010c020b200141ff0171450d00200341003a0088010b20034100360250200342013703482003410d3602242003200341086a3602202003200341c8006a360244200341fc006a41013602002003420137026c200341f4eaca003602682003200341206a360278200341c4006a41a8a3c800200341e8006a10371a200335025042208620033502488410080240200328024c450d00200328024810290b410221010b200020013a00002005450d00200410290b20034190016a24000b9b2308047f027e047f077e037f087e157f017e23002206210720064180056b41607122062400024002400240024020012002460d0020012002412010e707450d00200641b0016a200110a80220064180046a20062802b001220820062802b80110a90220064190046a290300420020062903800442015122091b210a200629038804420020091b210b024020062802b401450d00200810290b200b200454200a200554200a2005511b450d01412110d5042103200641106a412110d60420062903102105200020033a000620004183223b0104200041086a20053702000c020b412510d5042103200641086a412510d60420062903082105200020033a000620004183223b0104200041086a20053702000c010b200641a0016a200110df0520064180046a20062802a001220c20062802a801220d10e00520064190036a41026a220920062d0083043a0000200641c8036a41086a220820064180046a41e0006a290300370300200641c8036a41106a220e20064180046a41e8006a290300370300200620062f0081043b019003200620064180046a41d8006a2903003703c8030240024020062d008004220f4102470d00200641b0016a41c0006a220941003602004200210b200641b0016a41106a4200370300200641b0016a41186a4200370300200641b0016a41206a4200370300200641b0016a41286a4200370300200641b0016a41306a4200370300200641b0016a41386a4200370300200641083602b401200641b0016a41086a4200370300200641003a00b001200641b0016a41d0006a2903002110200641b0016a41c8006a2903002111200929030021124200210a42002113420021140c010b20064180046a41d0006a290300211020064180046a41c8006a290300211120064180046a41386a290300211420064180046a41286a290300210a20064180046a41206a290300210b20064180046a41186a290300211520064180046a41106a290300211620064180046a41306a290300211320064180046a410c6a280200211720064180046a41086a28020021182006280284042119200641b0016a41c0006a20064180046a41c0006a2903002212370300200641b0016a41386a2014370300200641b0016a41286a200a370300200641b0016a41206a200b370300200641b0016a41186a2015370300200641b0016a41106a2016370300200641b0016a41d0006a2010370300200641b0016a41c8006a2011370300200641b0016a41306a2013370300200641b0016a410c6a2017360200200641b0016a41086a2018360200200641b0016a41d8006a20062903c803370300200641b0016a41e0006a2008290300370300200641b0016a41e8006a200e2903003703002006200f3a00b001200620062f0190033b00b101200620193602b401200620092d00003a00b3010b2006200241106a2900003700b1022006200241176a2900003700b8022006200241086a2900003700a902200620022900003700a10220062903b802211a2006200641c8016a2209290300221b3703b80220062903b002211c200620062903c001221d3703b00220062903a802211e200620062903b801221f3703a802200641013a00a00220062903a0022115200620062903b00122163703a002200231001f2120200641e8016a4200370300200641e0016a2005370300200641d8016a20043703002009201a370300200620202003ad222142ff0183420886843703d0012006201c3703c0012006201e3703b801200620153703b00120064188026a2209290300211a2009420037030020064180026a4200370300200641f8016a4200370300200642003703f00120064198026a2208280200210f20064190026a220e290300211c20084100360200200e42003703000240024002400240024002402016a741ff01714101460d002016422088a7210f201fa721082015a7210e201f422088a70d02200641e8016a200641c0016a200e41ff017141014622171b220e201b370308200e201d370300200e200b370310200e41186a200a3703002009200641b0016a41306a20171b22092012a736021020092014370308200920133703002008450d01200841306c450d01200f10290c010b20064180046a41176a200641a0026a410172220841176a29000037000020064180046a41106a200841106a29000037030020064180046a41086a200841086a2900003703002006200b3c009f04200620082900003703800402400240200b420888200a42388684220ba741ff0171450d00200641f8006a20134200200b42ff0183220b420010d50720064188016a200a4200200b420010d507200641e8006a42004200200a420010d507427f20064190016a290300220b200629037820062903687c7c22152006290380012006290370844200522015200b547222081b210b427f20062903880120081b21150c010b200641d8006a200a2013420a420010e007200641e0006a290300210b200629035821150b20064180046a2015200b200a201310e2051a200641e8016a200641c0016a20062d00b001410146220e1b2208201137031020082012370308200841186a2010370300200820143703002009200641e0016a200e1b2209201a3703002009201c3703082009200f3602100b02400240200341ff0171450d00200641386a20054200202142ff0183220a420010d507200641c8006a20044200200a420010d507200641286a420042002004420010d507427f200641d0006a290300220a200629033820062903287c7c220b2006290340200629033084420052200b200a547222031b2121427f200629034820031b211b0c010b200641186a20042005420a420010e007200641206a29030021212006290318211b0b200641d0026a200210df0520064180046a20062802d002222220062802d802222310e00520064190036a41026a220320062d0083043a000041082124200641c8036a41086a200641e0046a290300370300200641c8036a41106a2209200641e8046a290300370300200620062f0081043b0190032006200641d8046a2903003703c803200641d0046a2903002114200641c8046a290300211c0240024020062d00800422254102470d004200211f41002125420021104200211d4200212042002111420021124200211a41002126410021270c010b200641c0046a2903002110200641b8046a290300211f200641a8046a2903002111200641a0046a290300212020064198046a290300211a20064180046a41106a2903002112200641b0046a290300211d2006418c046a280200212620064180046a41086a28020021272006280284042124200641fc026a41026a20032d00003a0000200641e0026a41086a200641c8036a41086a290300370300200641e0026a41106a2009290300370300200620062f0190033b01fc02200620062903c8033703e0020b4101210320254101460d01427f201120057c202020047c220b2020542203ad7c220a2003200a201154200a2011511b22031b2111427f200b20031b2120427f201a20217c2012201b7c220b2012542203ad7c220a2003200a201a54200a201a511b22031b211a427f200b20031b21120240202641306c2203450d00202420036a2119200641b8046a210920064180046a410172222841036a2129202421030340200341306a21080240200341086a2d00004101710d00200341096a2d0000212a20064180036a200328020010dd0420064180046a2006280280032203200628028803222b10d305200641c8036a41086a222c200941086a222d290000370300200641c8036a41106a222e200941106a222f290000370300200641c8036a41186a2230200941186a2231290000370300200641c8036a41206a2232200941206a2233290000370300200641c8036a41286a2234200941286a2235290000370300200620282800003602f803200620292800003600fb03200620092900003703c80320064180046a41306a210e20064180046a41206a210f20064180046a41106a2117024020062d00800422184102472236450d00200e290300210a200f29030021152017290300211320062903a804210b200629039804211e200629038804211620064190036a41086a202c29030037030020064190036a41106a202e29030037030020064190036a41186a203029030037030020064190036a41206a203229030037030020064190036a41286a2034290300370300200620062800fb033600c303200620062802f8033602c003200620062903c8033703900320180d00427f200a20057c200b20047c2237200b54222cad7c220b202c200b200a54200b200a511b222c1b210a427f2037202c1b210b0240202a4101710d00427f201520217c201e201b7c2237201e54222cad7c221e202c201e201554201e2015511b222c1b2115427f2037202c1b211e0c010b427f201320217c2016201b7c2237201654222cad7c2216202c201620135420162013511b222c1b2113427f2037202c1b21160b202820062802c0033600002009200629039003370300200e200a370300200f201537030020172013370300202920062800c303360000202d20064190036a41086a290300370300202f20064190036a41106a290300370300203120064190036a41186a290300370300203320064190036a41206a290300370300203520064190036a41286a2903003703002006200b3703a8042006201e370398042006201637038804200620183a0080040240024020360d00202bad4220862003ad8410040c010b2006202b3602cc03200620033602c80320064180046a200641c8036a10e3050b200628028403450d00200310290b2008210320192008470d000b0b202621030c020b412310d504210320064198016a412310d604200341ff01714110742103200629039801210502402008450d00200841306c450d00200f10290b200341832272210341012109200e41ff01710d02201ea72208450d02200841306c450d022015422088a710290c020b427f201420057c201c20047c220b201c542209ad7c220a2009200a201454200a2014511b22091b2114427f200b20091b211c427f201020217c201f201b7c220b201f542209ad7c220a2009200a201054200a2010511b22091b2110427f200b20091b211f0b200641d0046a2014370300200641c8046a201c370300200641c0046a2010370300200641b8046a201f370300200641a8046a2011370300200641a0046a202037030020064198046a201a37030020064180046a41106a2012370300200641b0046a201d3703002006418c046a202636020020064180046a41086a2027360200200641d8046a20062903e002370300200641e0046a200641e0026a41086a290300370300200641e8046a200641e0026a41106a290300370300200620062f01fc023b00810420062024360284042006200641fc026a41026a2d00003a008304200620253a0080040240024020254102470d002023ad4220862022ad8410040c010b200641c8036a20064180046a10a1052023ad4220862022ad8420063502d00342208620062802c8032209ad841003024020062802cc03450d00200910290b20250d002027450d00202741306c450d00202410290b024020062802d402450d00202210290b200642e4cab5fbb6ccdcb0e3003703c802200641c8026a20012004200510e50320064180046a200641b0016a41f00010e4071a024020062d00800422094102470d00200dad422086200cad841004410021090c010b200641c8036a20064180046a10a105200dad422086200cad8420063502d00342208620062802c8032208ad841003024020062802cc03450d00200810290b024020090d0020064188046a2802002209450d00200941306c450d0020062802840410290b410021090b024020062802a401450d00200c10290b024020090d0020064180046a41086a41083a0000200641a9046a200229000037000020012900002105200641093a00800420064180046a41096a200537000020064191046a200141086a29000037000020064199046a200141106a290000370000200641a1046a200141186a290000370000200641b1046a200241086a290000370000200641b9046a200241106a290000370000200641c1046a200241186a29000037000020064180046a10cb0120002003360204410021060c020b20002003360204200041086a20053702000b410121060b20002006360200200724000b870e0b057f017e017f057e027f057e017f027e017f037e027f230022022103200241c0046b41607122022400200241d0006a200110df05200241b0036a200228025022042002280258220510e00520022d00b0032106200241d0016a200241b0036a41017241ef0010e4071a0240024020064102470d0042002107200241f0006a4200370300200241f8006a420037030020024180016a420037030020024188016a420037030020024190016a420037030020024198016a420037030041002108200241a0016a410036020020024108360264200241e0006a41086a4200370300200241003a006042002109410021064200210a4200210b4200210c0c010b200220063a0060200241e0006a410172200241d0016a41ef0010e4071a20024180016a290300220d420888a72106200241c0016a290300210920024190016a290300210b20024188016a290300210a20024198016a290300210c200241c8016a280200210e200da72108420021070b20024198016a4200370300200241e0006a41306a420037030020024188016a4200370300200241f8006a220f290300210d200f4200370300200241083602e402200241003a00e002200241003602c0022002290370211020024200370370200229036821112002420037036820024200370380012002200d3703f802200220103703f002200220113703e80220022903d80221122002200241b8016a220f29030022133703d80220022903d00221142002200241b0016a221529030022163703d00220022903c80221172002200241a8016a221829030022193703c80220022903e002210d2002200229036022103703e0022002200d37036020022903c002211a200220022903a001221b3703c002200f201237030020152014370300201820173703002002201a3703a001200da7210f02400240024002402010a741ff017122154101470d00200241a7036a20022900f802370000200241a0036a20022900f10237030020024190036a41086a20022900e902370300200220022900e10237039003200220083a00af03200641ff0171450d01200241286a200b42002006ad42ff0183220d420010d507200241386a200a4200200d420010d507200241186a42004200200a420010d507427f200241c0006a290300220d200229032820022903187c7c221120022903302002290320844200522011200d547222151b210d427f200229033820151b21110c020b412210d5042101200241c8006a412210d604200141ff017121012002290348210b024020150d002011a72206450d00200641306c450d002010422088a710290b200141107421010240200f41ff01710d0041010d0041010d00200d422088a710290b200141832272210102402002280254450d00200410290b20002001360204200041086a200b370200410121020c020b200241086a200a200b420a420010e007200241106a290300210d200229030821110b20024190036a2011200d200a200b10e2052108200241b0036a41186a4200370300200241b0036a41106a221c4200370300200241b0036a41086a22154200370300200242003703b00341b3e6ca00ad4280808080e0008410012218290000210d2015201841086a2900003703002002200d3703b0032018102941c9e6ca00ad4280808080e0008410012218290000210d200241b0046a41086a221d201841086a2900003703002002200d3703b00420181029201c20022903b004220d370300200241d0016a41086a2015290300370300200241d0016a41106a200d370300200241d0016a41186a201d290300370300200220022903b0033703d0012002200241d0016a412010fc01200228020421152002280200211820024198016a200241e0006a41106a200f41ff0171410146221c1b220f41186a2016370300200f2019370310200f201b370308200f200c370300200241b8016a20024190016a201c1b220f2007201384220d200a200d200a562009200b562009200b511b221c1b370300200f2009200b201c1b370308200f200e200641187441187541027441d4a7c0006a280200418084076c2015410020181b6a2206200e20064b1b360210200241b0036a200241e0006a41f00010e4071a0240024020022d00b00322064102470d002005ad4220862004ad8410040c010b200241d0016a200241b0036a10a1052005ad4220862004ad8420023502d80142208620022802d001220ead841003024020022802d401450d00200e10290b20060d00200241b8036a2802002206450d00200641306c450d0020022802b40310290b02402002280254450d00200410290b200241b0036a41086a41093a0000200241b0036a41096a2001290000370000200241c1036a200141086a290000370000200241c9036a200141106a290000370000200241d1036a200141186a290000370000200241093a00b003200241b0036a10cb0120002008360204410021020b20002002360200200324000b8d0c05027f017e027f037e027f23004190026b22032400200241086a2802002204ad220542208620022802002206ad84101022072900002108200741086a2900002109200741106a290000210a200341286a41186a200741186a290000370300200341286a41106a200a370300200341286a41086a20093703002003200837032820071029200341e0006a200341286a10d804200341206a2003280260220b20032802684180a6cc004100410010c7012003280220210702402003280264450d00200b10290b024002400240024020074101460d00200341106a200542004280c2d72f420010d5072003200341186a29030022083703880220032003290310220937038002200320013602584104210702402004450d002003200136025c2003200341dc006a3602682003200341d8006a360264200320034180026a360260200341e0016a2001200341e0006a108e04024020032802e0014101470d00200320032900e5013703602003200341ec016a28000036006720032d00e40121070c010b41042107200341e0016a41086a2903004201520d00200341e0016a41106a290300210a200328025c210b20034198016a200341e0016a41186a29030037030020034190016a200a370300200341e0006a41086a41003a0000200341e9006a200b290000370000200341f1006a200b41086a290000370000200341f9006a200b41106a29000037000020034181016a200b41186a290000370000200341033a0060200341e0006a10cb010b200320032903603703482003200328006736004f200741ff01714104470d01200341e0006a41186a4200370300200341e0006a41106a22044200370300200341e0006a41086a220742003703002003420037036041b3e6ca00ad4280808080e000841001220b290000210a2007200b41086a2900003703002003200a370360200b102941c9e6ca00ad4280808080e000841001220b290000210a20034180026a41086a2206200b41086a2900003703002003200a37038002200b10292004200329038002220a370300200341e0016a41086a220b2007290300370300200341e0016a41106a2207200a370300200341e0016a41186a22042006290300370300200320032903603703e001200341086a200341e0016a412010fc01200328020c21062003280208210c2003418b026a200241086a2800003600002003200229000037008302200341a8016a2008370300200341a0016a200937030020034181016a20032900800237000020034188016a20034187026a29000037000020034194016a410036020020034190016a20064100200c1b360200200341e9006a200141086a290000370000200341f1006a200141106a290000370000200341f9006a200141186a290000370000200341013a0060200320012900003700612004200341286a41186a2903003703002007200341286a41106a290300370300200b200341286a41086a290300370300200320032903283703e001200341c8006a200341e0016a10de05200328024821072003350250210a200341003602e801200342013703e001200341e0006a200341e0016a10db0420032802e4012102200a4220862007ad8420033502e80142208620032802e001220bad84100302402002450d00200b10290b0240200328024c450d00200710290b024020034188016a280200450d0020034184016a28020010290b200341b8016a2008370300200341b0016a2009370300200341e0006a41086a410b3a0000200341f1006a200341286a41086a290300370000200341f9006a200341286a41106a29030037000020034181016a200341286a41186a29030037000020034189016a200129000037000020034191016a200141086a29000037000020034199016a200141106a290000370000200341a1016a200141186a290000370000200341093a0060200341e0006a41096a2003290328370000200341e0006a10cb01200041043a00000c030b410f10d50421072003410f10d60420032903002108200041026a20073a000020004183223b0100200041046a20083702000c010b200020073a000020002003290348370001200041086a200328004f3600000b200241046a280200450d00200610290b20034190026a24000b910d03037f037e057f23004190026b22032400200235020842208620022802002204ad84101022052900002106200541086a2900002107200541106a2900002108200341306a41186a2209200541186a290000370300200341306a41106a220a2008370300200341306a41086a220b20073703002003200637033020051029200341003a008002200341e0006a41186a2009290300370300200341e0006a41106a200a290300370300200341e0006a41086a200b29030037030020032003290330370360200341e0016a200341e0006a10de05200341286a20032802e001220b20032802e80120034180026a4101410010c701024002400240024020032802280d00411010d50421052003411010d604200328020421092003280200210a20032802e401450d01200b10290c010b0240024002400240200328022c450d0020032d008002220c41014b0d004104210d200c0e020301030b41c6a3c700ad4280808080900584100841102105200341103a0060200341e0006a21090c010b410f21052003410f3a0060200341e0006a21090b200510d5042105200341206a20092d000010d604200328022421092003280220210a4103210d0b024020032802e401450d00200b10290b200d4104470d00200341e0016a200341306a10d804200341e0006a20032802e001220920032802e80110d90420032802e401210502400240024020032d0060220a4102460d0020034188016a280200210b20034184016a280200210d2003350264210602402005450d00200910290b200a450d014201210742801e2106200b450d02200d10290c020b02402005450d00200910290b411010d5042105200341086a411010d60420032903082106200041026a20053a000020004183223b0100200041046a20063702000c030b200642208642801e842106420021070b02402007200684a741ff01714101460d00200341e0006a41186a4200370300200341e0006a41106a220a4200370300200341e0006a41086a220542003703002003420037036041b3e6ca00ad4280808080e000841001220929000021072005200941086a290000370300200320073703602009102941c9e6ca00ad4280808080e0008410012209290000210720034180026a41086a220b200941086a290000370300200320073703800220091029200a2003290380022207370300200341e0016a41086a22092005290300370300200341e0016a41106a22052007370300200341e0016a41186a220a200b290300370300200320032903603703e001200341186a200341e0016a412010fc01200328021c210b200328021821042003418b026a200241086a2800003600002003200229000037008302200341a8016a4200370300200341a0016a420037030020034181016a20032900800237000020034188016a20034187026a29000037000020034198016a20064220883e020020034194016a410136020020034190016a200b410020041b360200200341e9006a200141086a290000370000200341f1006a200141106a290000370000200341f9006a200141186a290000370000200341013a006020032001290000370061200a200341306a41186a2903003703002005200341306a41106a2903003703002009200341306a41086a290300370300200320032903303703e001200341d0006a200341e0016a10de052003280250210520033502582106200341003602e801200342013703e001200341e0006a200341e0016a10db0420032802e401210220064220862005ad8420033502e80142208620032802e0012209ad84100302402002450d00200910290b02402003280254450d00200510290b024020034188016a280200450d0020034184016a28020010290b200341b8016a4200370300200341b0016a4200370300200341e0006a41086a410b3a0000200341f1006a200341306a41086a290300370000200341f9006a200341306a41106a29030037000020034181016a200341306a41186a29030037000020034189016a200129000037000020034191016a200141086a29000037000020034199016a200141106a290000370000200341a1016a200141186a290000370000200341093a0060200341e0006a41096a2003290330370000200341e0006a10cb01200041043a00000c030b410f10d5042105200341106a410f10d60420032903102106200041026a20053a000020004183223b0100200041046a20063702000c010b20004183223b0100200041086a2009360200200041046a200a360200200041026a20053a00000b200241046a280200450d00200410290b20034190026a24000b9f0303027f017e027f230041206b2202240041c99fc500ad4280808080900184100122032900002104200241086a200341086a290000370300200220043703002003102941c08ec700ad4280808080900184100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000bb10503027f017e047f230041d0006b2202240041c99fc500ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941bc90c700ad4280808080800184100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000bbb1005057f017e067f077e017f230041c0016b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b020240024002400240200328021022020d00200041023a00000c010b200328021421042003200341186a280200220536025420032002360250024002402005450d0020022d0000210120032005417f6a22063602542003200241016a360250200141014b0d00024002400240024020010e020001000b2003200341d0006a10c80120032802000d03200328020422062003280254220141306e2207200720064b1bad42307e2208422088a70d062008a72207417f4c0d060240024020070d00410821090c010b200710272209450d080b4100210a20034100360268200320093602602003200741306e220b36026402402006450d002006417f6a210720034198016a41017221064100210a02400240034020014104490d0120032802502205350000210820032001417c6a3602542003200541046a36025020034198016a200341d0006a10ab0520032d00980122054102460d01200341f0006a411f6a220b2006411f6a290000370000200341f0006a41186a220c200641186a290000370300200341f0006a41106a220d200641106a290000370300200341f0006a41086a220e200641086a290000370300200320062900003703700240200a2003280264470d00200341e0006a200a4101109001200328026021092003280268210a0b2009200a41306c6a220120053a000820012008370300200141096a2003290370370000200141116a200e290300370000200141196a200d290300370000200141216a200c290300370000200141286a200b2900003700002003200a41016a220a3602682007450d022007417f6a2107200328025421010c000b0b20032802642201450d05200141306c450d05200910290c050b2003280264210b0b2009450d0302400240200328025422014110490d0020032003280250220641106a3602502003200141706a220736025420074110490d00200641086a290000210f200629000021102003200641206a3602502003200141606a220736025420074104490d01200641186a2900002108200629001021112003200641246a36025020032001415c6a220736025420074110490d0120062800202107200341386a2006412c6a290000370300200341cc006a41026a200341dd006a41026a2d00003a000020032011370320200320032f005d3b014c20032007360240200320062900243703302003200837032820032001414c6a3602542003200641346a360250410021010c030b200b450d04200b41306c450d04200910290c040b200b450d03200b41306c450d03200910290c030b20064110490d0220032005416f6a220a3602542003200241116a360250200241096a29000021082002290001211141002101200341003a00b801416e21060340200a2001460d0220034198016a20016a200220016a220741116a2d00003a00002003200520066a3602542003200741126a3602502003200141016a22073a00b8012006417f6a21062007210120074120470d000b200341e2006a20032d009a013a0000200320032f0198013b01602005416f6a2007460d02200341af016a290000210f20032900a7012110200328009b012109200328009f01210b20032800a301210a20032d00b701210d200220076a220141116a2d0000210c2003200520066a22063602542003200141126a360250200c41074f0d0220064110490d022003200141226a220e3602502003200520076b2207415e6a220636025420064110490d022001411a6a2900002112200141126a29000021132003200141326a220536025020032007414e6a220636025420064104490d022001412a6a2900002114200e2900002115200528000021062003200141366a220e36025020032007414a6a220536025420054110490d02200341cc006a41026a200341e0006a41026a2d00003a0000200341c0006a2012370300200341206a41106a2008370300200320032f01603b014c2003200741ba7f6a3602542003200141c6006a36025020032013370338200320113703282003200c3a00212003200d3a0020200320032801703601222003200341f4006a2f01003b01262001413e6a2900002111200e2900002108410121010b200341f0006a41026a200341cc006a41026a2d000022073a000020034198016a41086a2205200341206a41086a29030037030020034198016a41106a220c200341206a41106a29030037030020034198016a41186a220d200341206a41186a29030037030020034198016a41206a220e200341206a41206a290300370300200320032f014c22163b01702003200329032037039801200041186a200f370000200041106a2010370000200041036a20073a0000200020163b00012000410c6a200a360000200041086a200b360000200041046a2009360000200041e8006a2006360000200041e0006a2011370000200041d8006a2008370000200041d0006a2014370000200041c8006a2015370000200041206a200329039801370000200041286a2005290300370000200041306a200c290300370000200041386a200d290300370000200041c0006a200e2903003700000c020b200141ff0171450d00200341003a00b8010b20034100360228200342013703202003410d3602742003200341086a3602702003200341206a360260200341ac016a41013602002003420137029c01200341f4eaca00360298012003200341f0006a3602a801200341e0006a41a8a3c80020034198016a10371a2003350228422086200335022084100802402003280224450d00200328022010290b410221010b200020013a00002004450d00200210290b200341c0016a24000f0b1038000b1039000bf01c08077f067e0a7f017e017f057e017f067e23004190046b22042400200441a8026a200210dd04200441d8026a20042802a802220520042802b00210d305200441c8036a41086a220620044198036a290300370300200441c8036a41106a2207200441a0036a290300370300200441c8036a41186a2208200441a8036a290300370300200441c8036a41206a2209200441b0036a290300370300200441c8036a41286a220a200441b8036a290300370300200420044190036a2903003703c80320044188036a290300210b200441d8026a41286a290300210c200441d8026a41206a290300210d200441d8026a41186a290300210e200441d8026a41106a290300210f200441d8026a41086a290300211020042802dc02211120042d00d9022112024020042d00d80222134102460d0020044188016a41286a200a29030037030020044188016a41206a200929030037030020044188016a41186a200829030037030020044188016a41106a200729030037030020044188016a41086a2006290300370300200420042903c803370388010b024020042802ac02450d00200510290b200441b8016a41286a220520044188016a41286a290300370300200441b8016a41206a220620044188016a41206a290300370300200441b8016a41186a220720044188016a41186a290300370300200441b8016a41106a221420044188016a41106a290300370300200441b8016a41086a221520044188016a41086a29030037030020042004290388013703b801200441e8016a200110df05200441d8026a20042802e801221620042802f00110e005200441a8026a41026a220120042d00db023a0000200441c8036a41086a200441a4036a290200370300200441c8036a41106a2217200441ac036a290200370300200441c8036a41186a2218200441b4036a290200370300200441c8036a41206a2219200441bc036a290200370300200441c8036a41286a221a200441c4036a280200360200200420042f00d9023b01a80220042004419c036a2902003703c8030240024020042d00d80222094102470d004200211b4100210a4100211c4200211d4200211e4200211f42002120420021214100212241082108410021090c010b20044190036a290300212120044188036a2903002120200441d8026a41286a290300211f200441d8026a41206a290300211e200441d8026a41186a290300211d200441d8026a41106a290300211b20044198036a2802002122200441e4026a280200211c200441d8026a41086a280200210a20042802dc022108200441a4026a41026a20012d00003a0000200441f8016a41086a200441c8036a41086a290300370300200441f8016a41106a2017290300370300200441f8016a41186a2018290300370300200441f8016a41206a2019290300370300200441f8016a41286a201a280200360200200420042f01a8023b01a402200420042903c8033703f8010b200441a8026a41286a2005290300370300200441a8026a41206a2006290300370300200441a8026a41186a2007290300370300200441a8026a41106a2014290300370300200441a8026a41086a2015290300370300200420042903b8013703a80202400240024020090d00410021010240024002400240024002400240024002400240201c41014b0d00201c0e020201020b201c2105034020012005410176220620016a22072008200741306c6a28020020024b1b2101200520066b220541014b0d000b0b2008200141306c6a2802002002470d00024002402013410371417f6a220541014b0d0020050e020109010b200441c8036a41286a200441a8026a41286a290300370300200441c8036a41206a200441a8026a41206a290300370300200441c8036a41186a200441a8026a41186a290300370300200441c8036a41106a200441a8026a41106a290300370300200441c8036a41086a200441a8026a41086a290300370300200420042903a8023703c8030240024020030d00201c20014d0d042008200141306c6a220541186a2903002123200541106a29030021240240024020052d000822064101470d00200441106a200541206a2903002225200541286a2903002226420a420010e007200441206a20242023420a420010e007200c20247d2227200c56200b20237d200c202454ad7d2224200b562024200b511b0d01202720257d2228202756202420267d2027202554ad7d220c202456200c2024511b0d0120102004290320220b7d2224201056200f200441206a41086a2903007d2010200b54ad7d220b200f56200b200f511b0d01200e2004290310220f7d2210200e56200d200441106a41086a2903007d200e200f54ad7d220f200d56200f200d511b0d010c0b0b200541096a2d00002107024002402005410a6a2d0000220541ff0171450d00200441d0006a202342002005ad42ff01832227420010d507200441e0006a202442002027420010d507200441c0006a420042002024420010d507427f200441e8006a2903002227200429035020042903407c7c2228200429035820042903488442005220282027547222051b2125427f200429036020051b21270c010b200441306a20242023420a420010e007200441386a2903002125200429033021270b200c20247d2228200c56200b20237d200c202454ad7d220c200b56200c200b511b0d000240200741ff01710d00200e20277d2226200e56200d20257d200e202754ad7d2223200d562023200d511b0d0120102124200f210b2026210e2023210d0c0a0b201020277d2224201056200f20257d2010202754ad7d220b200f56200b200f511b450d090b41202101200441203a00d802200441d8026a21060c010b411d21012004411d3a00d802200441d8026a21060b200110d5042105200441086a20062d000010d604200428020c2106200428020821070c050b201c20014d0d022008200141306c6a22052d00080d07201241ff0171410047200541096a2d00004573450d07200541186a290300210c200541106a290300210f2008200141306c6a410a6a2c00002107200441d8026a41186a4200370300200441d8026a41106a22024200370300200441d8026a41086a22054200370300200442003703d80241b3e6ca00ad4280808080e0008410012206290000210b2005200641086a2900003703002004200b3703d8022006102941c9e6ca00ad4280808080e0008410012206290000210b20044180046a41086a2214200641086a2900003703002004200b37038004200610292002200429038004220b370300200441c8036a41086a2005290300370300200441c8036a41106a200b370300200441c8036a41186a2014290300370300200420042903d8023703c803200441f8006a200441c8036a412010fc01200428027c410020042802781b200741027441d4a7c0006a280200418084076c20116a22054f0d0720030d032021200c2020200f562021200c562021200c511b22061b21212020200f20061b212020222005202220054b1b21220c070b411c10d504210520044180016a411c10d604200428028001210720042802840121060c030b2001201c41f0a3c7001036000b2001201c4180a4c7001036000b411d10d5042105200441f0006a411d10d60420042802702107200428027421060b41032101200a450d04200a41306c450d04200810290c040b024020060d00200741ff01714102460d004200200c201f7d2028201e54ad7d220f2028201e7d2210202856200f200c56200f200c511b22051b210c4200201020051b2128024020074101710d004200200d201d7d200e201b54ad7d220f200e201b7d2210200e56200f200d56200f200d511b22051b210f4200201020051b21100c020b4200200b201d7d2024201b54ad7d220f2024201b7d2210202456200f200b56200f200b511b22051b210b4200201020051b21240b200e2110200d210f0b20044188036a200c370300200441d8026a41286a2028370300200441d8026a41206a200f370300200441d8026a41186a2010370300200441d8026a41106a200b37030020044190036a20042903c80337030020044198036a200441d0036a290300370300200441a0036a200441c8036a41106a290300370300200441a8036a200441c8036a41186a290300370300200441b0036a200441c8036a41206a290300370300200441b8036a200441c8036a41286a290300370300200420243703e002200441003a00d80220044180046a200210dd04200428028004210520042004280288043602fc03200420053602f803200441d8026a200441f8036a10de04200428028404450d00200510290b201c20014d0d022008200141306c6a2205200541306a201c2001417f736a41306c10e5071a201c417f6a211c0b20044190036a202137030020044188036a2020370300200441d8026a41286a201f370300200441d8026a41206a201e370300200441d8026a41186a201d370300200441d8026a41106a201b37030020044198036a2022360200200441e4026a201c360200200441d8026a41086a200a3602002004419c036a20042903f801370200200441a4036a200441f8016a41086a290300370200200441ac036a200441f8016a41106a290300370200200441b4036a200441f8016a41186a290300370200200441bc036a200441f8016a41206a290300370200200441c4036a200441f8016a41286a280200360200200420042f01a4023b00d902200420083602dc022004200441a4026a41026a2d00003a00db02200420093a00d8020240024020094102470d0020043502f00142208620042802e8012216ad8410040c010b20043502f001212120042802e8012116200441c8036a200441d8026a10a10520214220862016ad8420043502d00342208620042802c8032201ad84100320042802cc03450d00200110290b0240200a450d0020090d00200a41306c450d00200810290b410421010b024020042802ec01450d00201610290b0240024020014104470d00200041043a00000c010b200041113a0001200020013a0000200041086a2006360000200041046a2007360000200041026a20053a00000b20044190046a24000f0b2001201c1042000be80e08057f027e017f017e027f087e157f067e230041a0026b220524002005200010df05200541306a200528020022062005280208220710e005200541b0016a41026a220020052d00333a000041082108200541e8016a41086a20054190016a290300370300200541e8016a41106a220920054198016a290300370300200520052f00313b01b001200520054188016a2903003703e80120054180016a290300210a200541f8006a290300210b0240024020052d0030220c4102470d004200210d4100210e4100210f4200211042002111420021124200211342002114420021154100210c0c010b200541f0006a2903002115200541e8006a2903002114200541d8006a2903002112200541d0006a2903002111200541c8006a2903002110200541306a41106a290300210d200541e0006a29030021132005413c6a280200210f200541306a41086a280200210e200528023421082005412c6a41026a20002d00003a0000200541106a41086a200541e8016a41086a290300370300200541106a41106a2009290300370300200520052f01b0013b012c200520052903e8013703100b4101210002400240200c4101460d004200201220047d2011200354ad7d2216201120037d2217201156201620125620162012511b22001b21124200201720001b21114200201020027d200d200154ad7d2216200d20017d2217200d56201620105620162010511b22001b21104200201720001b210d0240200f41306c2200450d00200820006a2118200541e8006a2109200541306a410172221941036a211a200821000340200041306a211b0240200041086a2d00004101710d00200041096a2d0000211c200541a0016a200028020010dd04200541306a20052802a001220020052802a801221d10d305200541e8016a41086a221e200941086a221f290000370300200541e8016a41106a2220200941106a2221290000370300200541e8016a41186a2222200941186a2223290000370300200541e8016a41206a2224200941206a2225290000370300200541e8016a41286a2226200941286a222729000037030020052019280000360298022005201a28000036009b02200520092900003703e801200541306a41306a2128200541306a41206a2129200541306a41106a212a024020052d0030222b410247222c450d00202829030021172029290300212d202a290300212e200529035821162005290348212f20052903382130200541b0016a41086a201e290300370300200541b0016a41106a2020290300370300200541b0016a41186a2022290300370300200541b0016a41206a2024290300370300200541b0016a41286a20262903003703002005200528009b023600e30120052005280298023602e001200520052903e8013703b001202b0d004200201720047d2016200354ad7d2231201620037d2232201656203120175620312017511b221e1b211742002032201e1b21160240201c4101710d004200202d20027d202f200154ad7d2231202f20017d2232202f562031202d562031202d511b221e1b212d42002032201e1b212f0c010b4200202e20027d2030200154ad7d2231203020017d22322030562031202e562031202e511b221e1b212e42002032201e1b21300b201920052802e001360000200920052903b001370300202820173703002029202d370300202a202e370300201a20052800e301360000201f200541b0016a41086a2903003703002021200541b0016a41106a2903003703002023200541b0016a41186a2903003703002025200541b0016a41206a2903003703002027200541b0016a41286a290300370300200520163703582005202f370348200520303703382005202b3a003002400240202c0d00201dad4220862000ad8410040c010b2005201d3602ec01200520003602e801200541306a200541e8016a10e3050b20052802a401450d00200010290b201b21002018201b470d000b0b200f21000c010b4200200a20047d200b200354ad7d2216200b20037d2217200b562016200a562016200a511b22091b210a4200201720091b210b4200201520027d2014200154ad7d2216201420017d2217201456201620155620162015511b22091b21154200201720091b21140b20054180016a200a370300200541f8006a200b370300200541f0006a2015370300200541e8006a2014370300200541d8006a2012370300200541d0006a2011370300200541c8006a2010370300200541306a41106a200d370300200541e0006a20133703002005413c6a200f360200200541306a41086a200e36020020054188016a200529031037030020054190016a200541106a41086a29030037030020054198016a200541106a41106a290300370300200520052f012c3b00312005200836023420052005412c6a41026a2d00003a00332005200c3a003002400240200c4102470d002007ad4220862006ad8410040c010b200541e8016a200541306a10a1052007ad4220862006ad8420053502f00142208620052802e8012209ad841003024020052802ec01450d00200910290b200c0d00200e450d00200e41306c450d00200810290b02402005280204450d00200610290b200541a0026a240020000ba60203027f017e017f230041106b22022400200241003602082002420137030002400240024020002d00004101460d00410110272203450d02200341003a0000200220033602002002428180808010370204200041086a200210c606200235020842208621042002280204452103200228020021000c010b410110272203450d01200341013a000020024281808080103702042002200336020020002d00012105200341014102102b2203450d01200320053a000120024282808080203702042002200336020020002802042105200341024106102b2200450d01200020053600022002200036020020024286808080e000370204410021034280808080e00021040b200129020020042000ad841003024020030d00200010290b200241106a24000f0b1030000b4a01037f230041106b220124002001410036020820014201370300200110e405200128020421022000200128020022032001280208107202402002450d00200310290b200141106a24000bd40303017f017e027f230041e0006b22022400024002402000290300220342c000540d00024002400240200342808001540d002003428080808004540d014108200379a741037622046b4104490d022002411320044102746b3a00482001200241c8006a41011072200220002903002203370308200441786a21000340200220033c00482001200241c8006a4101107220034208882103200041016a22042000492105200421002005450d000b200220033703082003500d04200241286a41146a4109360200200241346a411c360200200241106a41146a41033602002002200241086a36024020024180f8ca00360244200241c8006a41146a410036020020024203370214200241aca5cc003602102002411c36022c20024180a6cc003602582002420137024c20024188f8ca003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a4180a6cc001040000b20022003a74102744101723b01482001200241c8006a410210720c030b20022003a74102744102723602482001200241c8006a410410720c020b41c4f7ca00413641b8a1cc001033000b20022003a74102743a00482001200241c8006a410110720b200241e0006a24000b890101027f230041106b2202240002404120102722030d001039000b20032000290004370000200341186a2000411c6a290000370000200341106a200041146a290000370000200341086a2000410c6a2900003700002001200341201072200310292002200028020036020c20012002410c6a410410722001200041246a41c0001072200241106a24000bcb0102017f017e230041106b220224000240024020002d00004101460d00200241003a00002001200241011072200220002d0001410047410774200041026a2d0000723a00002001200241011072200029030821032002200041106a290300370308200220033703000c010b200241013a00002001200241011072200029030821032002200041106a290300370308200220033703002001200241101072200041186a29030021032002200041206a290300370308200220033703000b2001200241101072200241106a24000bd60401037f230041106b220224000240024020002d0000417f6a220341044b0d000240024002400240024020030e050001020304000b200241003a000b20012002410b6a41011072200041246a28020021032000412c6a28020022042001107102402004450d002004410574210403402001200341201072200341206a2103200441606a22040d000b0b0240024020002d00014101460d00200241003a000b20012002410b6a410110720c010b200241013a000b20012002410b6a410110722001200041026a412010720b2002200028023036020c20012002410c6a410410720c040b200241013a000b20012002410b6a41011072200041046a280200200110bf02200041086a200110e6010c030b200241023a000b20012002410b6a41011072200041046a200110e601200041086a280200200110bf022000410c6a200110e6010c020b200241033a000b20012002410b6a41011072412010272203450d0220032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a290000370000200120034120107220031029200041246a200110e6012002200041216a2d00003a000b20012002410b6a410110720c010b200241043a000b20012002410b6a41011072412010272203450d0120032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a290000370000200120034120107220031029200041246a200110e601200041306a200110e505200041286a200110e6010b200241106a24000f0b1039000bcb4003037f017e017f230041106b220224000240024020002d0000220341144b0d0002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e15000102030405060708090a0b0c0d0e0f1011121314000b200241003a00002001200241011072200041086a2d0000220341044b0d140240024002400240024020030e050001020304000b200241003a000020012002410110722002200041106a29030037030020012002410810720240200041186a2d0000220341024b0d00024002400240024020030e03000102000b200241003a00000c020b200241013a00000c010b200241023a00000b20012002410110720b2002200041196a2d00003a000020012002410110720c180b200241013a00002001200241011072024002400240024002402000410c6a2d00000e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a0000200120024101107220022000410d6a2d00003a0000200120024101107220022000410e6a2d00003a00000b20012002410110722002200029031837030020012002410810720240200041206a2d0000220341024b0d00024002400240024020030e03000102000b200241003a00000c020b200241013a00000c010b200241023a00000b20012002410110720b2002200041216a2d00003a000020012002410110720c170b200241023a000020012002410110720c160b200241033a000020012002410110722001200041096a412010720c150b200241043a000020012002410110722001200041096a412010720c140b200241013a00002001200241011072200041046a280200220341024b0d1302400240024020030e03000102000b200241003a000020012002410110722002200041086a280200360200200120024104107220022000410c6a28020036020020012002410410720c150b200241013a000020012002410110722002200041086a280200360200200120024104107220022000410c6a28020036020020012002410410720c140b200241023a000020012002410110722002200041086a280200360200200120024104107220022000410c6a280200360200200120024104107202400240200041106a28020022030d00200241003a000020012002410110720c010b200241013a00002001200241011072200041186a28020022042001107120012003200410720b024020002d001c22034104460d00200241013a000020012002410110720240024002400240024020030e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a0000200120024101107220022000411d6a2d00003a0000200120024101107220022000411e6a2d00003a00000b20012002410110720c140b200241003a000020012002410110720c130b200241023a000020012002410110720240200041046a2d00004101460d00200241003a000020012002410110722001200041056a412010722002200041286a28020036020020012002410410720c130b200241013a000020012002410110722002200041086a28020036020020012002410410720c120b200241033a00002001200241011072200041086a2d0000220341044b0d1102400240024002400240024020030e050001020304000b200241003a000020012002410110722001200041096a41201072200041306a29030021052002200041386a290300370308200220053703000c040b200241013a000020012002410110722001200041096a41201072200041306a29030021052002200041386a290300370308200220053703000c030b200241023a000020012002410110722001200041096a412010722001200041296a41201072200041d0006a29030021052002200041d8006a290300370308200220053703000c020b200241033a000020012002410110722001200041096a41201072200041306a29030021052002200041386a290300370308200220053703002001200241101072200041c0006a29030021052002200041c8006a290300370308200220053703000c010b200241043a000020012002410110722001200041096a41201072200041306a29030021052002200041386a290300370308200220053703000b20012002411010720c110b200241043a00002001200241011072200041086a2d0000220341084b0d1002400240024002400240024002400240024020030e09000102030405060708000b200241003a0000200120024101107220022000410c6a2802003602002001200241041072200041106a29030021052002200041186a290300370308200220053703002001200241101072200041206a29030021052002200041286a2903003703082002200537030020012002411010720c180b200241013a000020012002410110722001200041096a41201072200041306a29030021052002200041386a2903003703082002200537030020012002411010720c170b200241023a000020012002410110722001200041096a41201072200041306a29030021052002200041386a2903003703082002200537030020012002411010720c160b200241033a0000200120024101107220022000410c6a28020036020020012002410410720c150b200241043a00002001200241011072200041096a2d0000220041024b0d1402400240024020000e03000102000b200241003a000020012002410110720c160b200241013a000020012002410110720c150b200241023a000020012002410110720c140b200241053a00002001200241011072200041096a2d0000220041024b0d1302400240024020000e03000102000b200241003a000020012002410110720c150b200241013a000020012002410110720c140b200241023a000020012002410110720c130b200241063a000020012002410110722001200041096a41201072200041306a29030021052002200041386a2903003703082002200537030020012002411010720c120b200241073a000020012002410110722001200041096a41201072200041306a29030021052002200041386a2903003703082002200537030020012002411010720c110b200241083a000020012002410110722001200041096a41201072200041306a29030021052002200041386a2903003703082002200537030020012002411010720c100b200241053a00002001200241011072200241003a000020012002410110722001200041106a41101072200041046a28020021032000410c6a28020022042001107120012003200410722002200041206a2d00003a000020012002410110720c0f0b200241063a00002001200241011072200241003a000020012002410110722002200041046a28020036020020012002410410720c0e0b200241073a00002001200241011072200041046a280200220341024b0d0d02400240024020030e03000102000b200241003a00002001200241011072200041086a2802002103200041106a2802002200200110712000450d0f2003200041286c6a2100034020012003412010722002200341206a29030037030020012002410810722000200341286a2203470d000c100b0b200241013a000020012002410110720c0e0b200241023a000020012002410110720c0d0b200241083a00002001200241011072200041046a2d0000220341024b0d0c02400240024020030e03000102000b200241003a000020012002410110722001200041056a412010720c0e0b200241013a000020012002410110720c0d0b200241023a00002001200241011072200041086a2802002104200041106a2802002200200110712000450d0c2004200041d0006c6a2106034020012004412010722002200441206a3602002002200110e5012002200441306a3602002002200110e501200428024021002004280248220320011071200441d0006a210402402003450d00200341306c210303402001200041106a41201072200220003602002002200110e501200041306a2100200341506a22030d000b0b20062004470d000c0d0b0b200241093a00002001200241011072200041086a2d0000220341104b0d0b0240024002400240024002400240024002400240024002400240024002400240024020030e11000102030405060708090a0b0c0d0e0f10000b200241003a0000200120024101107220022000410c6a2802003602002001200241041072200041106a29030021052002200041186a2903003703082002200537030020012002411010720c1b0b200241013a0000200120024101107220022000410c6a2802003602002001200241041072200041206a29030021052002200041286a290300370308200220053703002001200241101072200041106a2802002103200041186a2802002200200110712000450d1a2000410574210003402001200341201072200341206a2103200041606a22000d000c1b0b0b200241023a000020012002410110720c190b200241033a0000200120024101107220022000410c6a2802003602002001200241041072200041096a2d0000220041024b0d1802400240024020000e03000102000b200241003a000020012002410110720c1a0b200241013a000020012002410110720c190b200241023a000020012002410110720c180b200241043a0000200120024101107220022000410c6a28020036020020012002410410720c170b200241053a0000200120024101107220022000410c6a28020036020020012002410410720c160b200241063a0000200120024101107220022000410c6a28020036020020012002410410720c150b200241073a0000200120024101107220022000410c6a28020036020020012002410410722002200041096a2d00003a000020012002410110720c140b200241083a000020012002410110722001200041096a412010722001200041296a412010720c130b200241093a000020012002410110722001200041096a412010720c120b2002410a3a000020012002410110722001200041096a41201072412010272203450d12200341186a200041c1006a290000370000200341106a200041396a290000370000200341086a200041316a2900003700002003200041296a2900003700002001200341201072200310292002200041cc006a28020036020020012002410410720c110b2002410b3a00002001200241011072412010272203450d11200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201072200310292001200041296a41201072200041d0006a29030021052002200041d8006a2903003703082002200537030020012002411010720c100b2002410c3a00002001200241011072412010272203450d10200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201072200310292001200041296a41201072200041d0006a29030021052002200041d8006a2903003703082002200537030020012002411010720c0f0b2002410d3a00002001200241011072412010272203450d0f200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a29000037000020012003412010722003102920022000412c6a28020036020020012002410410720c0e0b2002410e3a00002001200241011072412010272203450d0e200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a29000037000020012003412010722003102920022000412c6a28020036020020012002410410720c0d0b2002410f3a00002001200241011072412010272203450d0d200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201072200310292001200041296a41201072200041f0006a29030021052002200041f8006a2903003703082002200537030020012002411010722001200041c9006a412010720c0c0b200241103a000020012002410110722001200041096a412010720c0b0b2002410a3a00002001200241011072200041046a200110ea050c0a0b2002410b3a00002001200241011072200041046a200110ea050c090b2002410c3a00002001200241011072200041046a2d0000220341044b0d080240024002400240024020030e050001020304000b200241003a00002001200241011072200041086a2802002103200041106a2802002200200110712000450d0c2003200041306c6a210003402001200341201072200341206a29030021052002200341286a2903003703082002200537030020012002411010722000200341306a2203470d000c0d0b0b200241013a000020012002410110720c0b0b200241023a000020012002410110722001200041056a412010720c0a0b200241033a000020012002410110722001200041056a412010720c090b200241043a000020012002410110722001200041056a412010722001200041256a412010722002200041c5006a2d00003a000020012002410110720c080b2002410d3a0000200120024101107220002d0001220041054b0d07024002400240024002400240024020000e06000102030405000b200241003a00000c050b200241013a00000c040b200241023a00000c030b200241033a00000c020b200241043a00000c010b200241053a00000b20012002410110720c070b2002410e3a00002001200241011072200041086a2d00002203410a4b0d060240024002400240024002400240024002400240024020030e0b000102030405060708090a000b200241003a0000200120024101107220022000410c6a28020036020020012002410410720c100b200241013a00002001200241011072200041106a29030021052002200041186a2903003703082002200537030020012002411010720c0f0b200241023a0000200120024101107220022000412c6a2802003602002001200241041072200041306a29030021052002200041386a2903003703082002200537030020012002411010722001200041096a412010720c0e0b200241033a0000200120024101107220022000410c6a2802003602002001200241041072200041106a29030021052002200041186a2903003703082002200537030020012002411010720c0d0b200241043a00002001200241011072200041106a29030021052002200041186a2903003703082002200537030020012002411010720c0c0b200241053a00002001200241011072200041106a29030021052002200041186a2903003703082002200537030020012002411010720c0b0b200241063a00002001200241011072200041106a29030021052002200041186a2903003703082002200537030020012002411010720c0a0b200241073a00002001200241011072412010272203450d0a200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201072200310290c090b200241083a00002001200241011072412010272203450d09200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201072200310290c080b200241093a00002001200241011072412010272203450d08200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201072200310292001200041296a41201072200041d0006a29030021052002200041d8006a2903003703082002200537030020012002411010720c070b2002410a3a00002001200241011072412010272203450d07200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201072200310290c060b2002410f3a00002001200241011072200041086a2d0000220341064b0d05024002400240024002400240024020030e0700010203040506000b200241003a0000200120024101107220022000410c6a28020036020020012002410410720c0b0b200241013a0000200120024101107220022000410c6a28020036020020012002410410722002200041106a28020036020020012002410410722002200041146a28020036020020012002410410720c0a0b200241023a0000200120024101107220022000410c6a28020036020020012002410410720c090b200241033a000020012002410110722001200041106a4120107220022000410c6a28020036020020012002410410720240200041096a2d00002203410f7141094b0d000240024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a00000c090b200241013a00000c080b200241023a00000c070b200241033a00000c060b200241043a00000c050b200241053a00000c040b200241063a00000c030b200241073a00000c020b200241083a00000c010b200241093a00000b20012002410110720b200220002802303602002001200241041072200029033821052002200041c0006a2903003703082002200537030020012002411010720c080b200241043a0000200120024101107220022000410c6a28020036020020012002410410720240200041096a2d00002203410f7141094b0d000240024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a00000c090b200241013a00000c080b200241023a00000c070b200241033a00000c060b200241043a00000c050b200241053a00000c040b200241063a00000c030b200241073a00000c020b200241083a00000c010b200241093a00000b20012002410110720b200029031021052002200041186a290300370308200220053703002001200241101072200029032021052002200041286a2903003703082002200537030020012002411010720c070b200241053a000020012002410110722001200041096a41201072200041306a29030021052002200041386a290300370308200220053703002001200241101072200041c0006a29030021052002200041c8006a2903003703082002200537030020012002411010720c060b200241063a000020012002410110722001200041096a41201072200041306a29030021052002200041386a2903003703082002200537030020012002411010720c050b200241103a000020012002410110720240200041046a2802004101460d00200241003a000020012002410110722002200028020836020020012002410410720c050b200241013a000020012002410110722002200028020836020020012002410410720c040b200241113a00002001200241011072200241003a000020012002410110722001200041186a412010722001200041386a41141072200041086a29030021052002200041106a2903003703082002200537030020012002411010720c030b200241123a00002001200241011072200041096a21030240200041086a2d00004101460d00200241003a000020012002410110722001200341201072200041306a29030021052002200041386a2903003703082002200537030020012002411010720c030b200241013a0000200120024101107220012003412010720c020b200241133a00002001200241011072200041046a2d0000220341064b0d01024002400240024002400240024020030e0700010203040506000b200241003a000020012002410110722002200041086a2802003602002001200241041072024002400240024002402000410c6a2d00000e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a0000200120024101107220022000410d6a2d00003a0000200120024101107220022000410e6a2d00003a00000b20012002410110720c070b200241013a000020012002410110720c060b200241023a000020012002410110722001200041056a412010722001200041256a412010722001200041c5006a412010720c050b200241033a000020012002410110722001200041056a412010722002200041e8006a28020036020020012002410410722002200041ec006a28020036020020012002410410722001200041256a412010722001200041c5006a412010720c040b200241043a000020012002410110722001200041056a412010722002200041e8006a28020036020020012002410410722002200041ec006a28020036020020012002410410722001200041256a412010722001200041c5006a412010720240200041f0006a2d00004104460d00200241013a000020012002410110720240024002400240024020002d00700e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a000020012002410110722002200041f1006a2d00003a000020012002410110722002200041f2006a2d00003a00000b20012002410110720c040b200241003a000020012002410110720c030b200241053a000020012002410110722001200041056a412010722002200041e8006a28020036020020012002410410722002200041ec006a28020036020020012002410410722001200041256a412010722001200041c5006a412010720c020b200241063a000020012002410110722002200041086a28020036020020012002410410720c010b200241143a00002001200241011072200041046a2d0000220341024b0d0002400240024020030e03000102000b200241003a000020012002410110720240200041086a2d000022034104460d00200241013a000020012002410110720240024002400240024020030e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a000020012002410110722002200041096a2d00003a0000200120024101107220022000410a6a2d00003a00000b20012002410110720c030b200241003a000020012002410110720c020b200241013a000020012002410110722001200041056a412010720c010b200241023a000020012002410110722002200041056a2d00003a000020012002410110720b200241106a24000f0b1039000bcf0a01027f230041106b220224000240024020002d0000220341064b0d00024002400240024002400240024020030e0700010203040506000b200241003a000c20012002410c6a410110722001200041016a412010722002200041c4006a28020036020c20012002410c6a41041072412010272203450d07200341186a200041396a290000370000200341106a200041316a290000370000200341086a200041296a2900003700002003200041216a2900003700002001200341201072200310292002200041c8006a28020036020c20012002410c6a410410720c060b200241013a000c20012002410c6a410110722001200041016a41201072412010272203450d06200341186a200041396a290000370000200341106a200041316a290000370000200341086a200041296a2900003700002003200041216a2900003700002001200341201072200310292002200041c1006a2d00003a000c20012002410c6a410110722002200041c4006a28020036020c20012002410c6a410410722002200041c8006a28020036020c20012002410c6a410410720c050b200241023a000c20012002410c6a41011072412010272203450d0520032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201072200310290c040b200241033a000c20012002410c6a41011072412010272203450d0420032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201072200310290c030b200241043a000c20012002410c6a41011072412010272203450d0320032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a290000370000200120034120107220031029024020002d00244104460d00200241013a000c20012002410c6a410110720240024002400240024020002d00240e0400010203000b200241003a000c2002410c6a21000c030b200241013a000c2002410c6a21000c020b200241023a000c2002410c6a21000c010b200241033a000c20012002410c6a410110722002200041256a2d00003a000c20012002410c6a410110722002200041266a2d00003a000c2002410c6a21000b20012000410110720c030b200241003a000c20012002410c6a410110720c020b200241053a000c20012002410c6a41011072412010272203450d0220032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a290000370000200120034120107220031029024020002d00244104460d00200241013a000c20012002410c6a410110720240024002400240024020002d00240e0400010203000b200241003a000c2002410c6a21000c030b200241013a000c2002410c6a21000c020b200241023a000c2002410c6a21000c010b200241033a000c20012002410c6a410110722002200041256a2d00003a000c20012002410c6a410110722002200041266a2d00003a000c2002410c6a21000b20012000410110720c020b200241003a000c20012002410c6a410110720c010b200241063a000c20012002410c6a41011072412010272203450d0120032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201072200310292002200041246a28020036020c20012002410c6a410410722002200041286a28020036020c20012002410c6a410410720b200241106a24000f0b1039000b4d01017f230041206b22002400200041146a41013602002000420137020420004198e3ca003602002000410436021c200041cce3ca003602182000200041186a36021020004180a6cc001040000bfa0202017f027e230041206b2202240042808bd6ed00210302400240024002400240024020012d00000e06000102030504000b200241146a41013602002002420137020420024198e3ca003602002002410436021c200241cce3ca003602182002200241186a36021020024180a6cc001040000b200141306a35020042c0de810a7e2001412c6a35020042b0db067e7c42809591c7397c21030c030b2002200141046a28020010c301427f200141086a35020042a01f7e42808ece1c7c220320022903007c220420042003541b21030c020b0240200141046a28020041014b0d002002200141086a28020010c301427f200135020c42b8177e42c0c694307c220320022903007c220420042003541b21030c020b200135020c42f02e7e4280c2e9a3027c21030c010b427f427f200141286a35020042c03e7e42c0dfb8ba017c2203200141306a2903007c220420042003541b220342c0dcae177c220420042003541b21030b200041013b010820002003370300200241206a24000b9e0303077f017e017f230041106b220224000240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002006450d0020042d0001210720012003417e6a22063602042001200441026a3602002006450d0020042d0002210820012003417d6a22063602042001200441036a36020020060d010b200041003602040c010b20042d0003210620012003417c6a3602042001200441046a360200200241086a200110c801024020022802080d002001280204200228020c2204490d002004417f4c0d02024002400240024020040d0042002109410121030c010b2004102d2203450d0120012802042004490d0220032001280200200410e4071a2001280204220a2004490d062001200a20046b3602042001200128020020046a3602002004ad21090b2003450d02200020092004ad4220868437020820002003360204200020074108742005722008411074722006411874723602000c030b1039000b200310290b200041003602040b200241106a24000f0b1038000b2004200a41ccafc000104c000bff0401097f230041106b22022400024002400240024020002802082203410c6c41046a2204417f4c0d00200028020021050240024020040d0041012100410021040c010b200410272200450d020b20024100360208200220003602002002200436020420032002107102402003450d0020052003410c6c6a2106034020052802002103200528020822042002107102402004450d002003200441246c6a2107200228020421002002280208210403402003280200210802400240200020046b4104490d00200228020021092000210a0c010b200441046a220a2004490d0720004101742209200a2009200a4b1b220a4100480d070240024020000d000240200a0d00410121090c020b200a102722090d010c0a0b200228020021092000200a460d0020092000200a102b2209450d090b2002200a360204200220093602000b200920046a20083600002002200441046a220836020802400240200a20086b4120490d00200441246a2104200a21000c010b200841206a22042008490d07200a41017422002004200020044b1b22004100480d0702400240200a0d00024020000d00410121090c020b200010272209450d0a0c010b200a2000460d002009200a2000102b2209450d090b20022000360204200220093602000b200920086a220a200341046a290000370000200a41186a2003411c6a290000370000200a41106a200341146a290000370000200a41086a2003410c6a29000037000020022004360208200341246a22032007470d000b0b2005410c6a22052006470d000b0b200228020421042001290200200235020842208620022802002203ad84100302402004450d00200310290b200241106a24000f0b1038000b1039000b1032000b1030000bb70204027f017e027f037e230041106b220224000240024020012802082203ad42287e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510272206450d020b20024100360208200220063602002002200541286e36020420024100200310a3012002280208210502402003450d00200341286c21062002280200200541286c6a21030340200141086a2903002104200141106a2903002107200141186a290300210820012903002109200341206a200141206a290300370300200341186a2008370300200341106a2007370300200341086a200437030020032009370300200341286a2103200541016a2105200141286a2101200641586a22060d000b0b20002002290300370200200041086a2005360200200241106a24000f0b1038000b1039000bab0201057f230041206b22022400024002402001280208220341ffffffff00712003470d0020034104742204417f4c0d00200128020021014104210502402004450d00200410272205450d020b200241003602082002200536020020022004410476360204200241002003109c012002280208210502402003450d0020034104742106200228020020054104746a21030340410221040240024002402001410c6a2d00004103710e03000102000b410021040c010b410121040b200241106a200110f10520032002290310370200200220043a001c200341086a200241106a41086a290300370200200541016a2105200341106a2103200141106a2101200641706a22060d000b0b20002002290300370200200041086a2005360200200241206a24000f0b1038000b1039000bc80101047f02400240024020012802082202417f4c0d00200128020021030240024020020d0041002101410121040c010b200210272204450d02200221010b0240024020012002490d00200121050c010b02400240200141017422052002200520024b1b22054100480d00024020010d002005102722040d030c060b20012005470d01200121050c020b1032000b200420012005102b2204450d030b20042003200210e40721012000200236020820002005360204200020013602000f0b1038000b1039000b1030000bfe0304027f017e067f077e230041c0006b220224000240024020012802082203ad42d0007e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510272206450d020b20024100360208200220063602002002200541d0006e36020420024100200310ac012002280208210702402003450d002001200341d0006c6a21082002280200200741d0006c6a2105200341047441706a41047621090340200241206a41086a2203200141086a290300370300200241206a41106a2206200141106a290300370300200241206a41186a220a200141186a29030037030020022001290300370320200141206a2903002104200141286a290300210b200141306a290300210c200141386a290300210d200241106a200141c0006a10ee02200a290300210e2006290300210f2003290300211020022903202111200541386a200d370300200541306a200c370300200541286a200b370300200541206a2004370300200541086a201037030020052011370300200541106a200f370300200541186a200e370300200541c0006a2002290310370300200541c8006a200241106a41086a280200360200200541d0006a2105200141d0006a22012008470d000b200720096a41016a21070b20002002290300370200200041086a2007360200200241c0006a24000f0b1038000b1039000b920203027f017e037f230041206b220224000240024020012802082203ad420c7e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410421060c010b200510272206450d020b200241003602082002200636020020022005410c6e360204200241002003109d012002280208210702402003450d002003410c6c210620022802002007410c6c6a21052003410274417c6a41027621030340200241106a200110f105200541086a200241106a41086a280200360200200520022903103702002005410c6a21052001410c6a2101200641746a22060d000b200720036a41016a21070b20002002290300370200200041086a2007360200200241206a24000f0b1038000b1039000bcf0504037f017e087f047e23004180016b220224002002200110c80102400240024002402002280200450d00200041003602000c010b20022802042203200128020441306e2204200420034b1bad42307e2205422088a70d012005a72204417f4c0d010240024020040d00410821060c010b200410272206450d030b4100210720024100360210200220063602082002200441306e36020c0240024002402003450d0041002108034041002104200241003a0078200841016a210820012802042109417f210a034020092004460d03200241d8006a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a0078200a417f6a210a200c2104200c4120470d000b200241386a41186a2204200241d8006a41186a290300370300200241386a41106a220a200241d8006a41106a290300370300200241386a41086a220d200241d8006a41086a290300370300200220022903583703382009200c6b220c4110490d03200b41096a2900002105200b290001210e2001200c41706a3602042001200b41116a360200200241186a41086a220c200d290300370300200241186a41106a2209200a290300370300200241186a41186a220a20042903003703002002200229033837031802402007200228020c470d00200241086a2007410110900120022802082106200228021021070b2006200741306c6a22042002290318370300200c290300210f20092903002110200a29030021112004200e370320200441286a2005370300200441186a2011370300200441106a2010370300200441086a200f3703002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c020b200441ff0171450d00200241003a00780b20004100360200200228020c2204450d00200441306c450d00200610290b20024180016a24000f0b1038000b1039000bd30201077f230041206b22022400200241086a200110c80102400240024002402002280208450d00200041003602000c010b200228020c220320012802044102762204200420034b1b22054102742204417f4c0d010240024020050d00410421060c010b200410272206450d030b41002104200241003602182002200536021420022006360210024002402003450d000340200128020422054104490d0220012802002207280000210820012005417c6a3602042001200741046a360200024020042002280214470d00200241106a2004410110980120022802102106200228021821040b200620044102746a20083602002002200441016a22043602182003417f6a22030d000b0b20002002290310370200200041086a200241106a41086a2802003602000c010b20004100360200200228021441ffffffff0371450d00200610290b200241206a24000f0b1038000b1039000bfe0503097f017e017f230041306b22022400200241086a200110c80102400240024002402002280208450d00200041003602000c010b41042103200228020c220420012802044104762205200520044b1b22064104742205417f4c0d0202402006450d00200510272203450d020b41002105200241003602182002200636021420022003360210024002402004450d00034002400240200128020422060d00410321070c010b200128020022072d0000210820012006417f6a3602042001200741016a3602000240200841024d0d00410321070c010b2002200110c80102402002280200450d00410321070c010b02402001280204200228020422064f0d00410321070c010b2006417f4c0d06024002400240024020060d00410021094101210a0c010b2006102d220a450d0820012802042006490d02200a2001280200200610e4071a200128020422072006490d012001200720066b3602042001200128020020066a360200200621090b41032107200a450d022006ad4220862009ad84210b2002412a6a41026a2002412d6a41026a2d00003a0000200220022f002d3b012a200a210c200821070c020b2006200741ccafc000104c000b200a1029410321070b200241266a41026a22062002412a6a41026a2d00003a0000200220022f012a3b012620074103460d02200241226a41026a220820062d00003a0000200220022f01263b0122024020052002280214470d00200241106a20054101109c0120022802102103200228021821050b200320054104746a220620073a000c2006200b3702042006200c360200200620022f01223b000d2006410f6a20082d00003a00002002200541016a22053602182004417f6a22040d000b0b20002002290310370200200041086a200241106a41086a2802003602000c010b2000410036020002402005450d00200541047421062003210503400240200541046a280200450d00200528020010290b200541106a2105200641706a22060d000b0b200228021441ffffffff0071450d00200310290b200241306a24000f0b1039000b1038000bfa0101067f23004180016b220224002001410c6a2802002103200141086a280200210420012802002205210602402005410471450d0020012005410872220636020020040d00200141086a4281808080a0013702000b2001200641047236020020002802002100410021060340200220066a41ff006a2000410f712207413072200741d7006a2007410a491b3a00002006417f6a2106200041047622000d000b024020064180016a2200418101490d00200041800141a88ac000104c000b200141b88ac0004102200220066a4180016a410020066b104921062001200336020c200141086a20043602002001200536020020024180016a240020060bb10201017f230041a0016b220324002003200236020420032001360200200341086a2002ad4220862001ad841007108b0202400240200328020822010d00200041003602400c010b200328020c21022003200341106a28020036027c20032001360278200341186a200341f8006a10c1020240024020032802580d00200341003602880120034201370380012003410d360294012003200336029001200320034180016a36029c012003412c6a41013602002003420137021c200341f4eaca00360218200320034190016a3602282003419c016a41a8a3c800200341186a10371a2003350288014220862003350280018410080240200328028401450d0020032802800110290b200041003602400c010b2000200341186a41e00010e4071a0b2002450d00200110290b200341a0016a24000bf707040c7f017e047f037e23004190016b220224000240024002400240200141086a220328020022042001410c6a2802002205460d002001280210220628020021072006280208220841014b210903402003200441206a220a360200200241f0006a41186a200441186a290000370300200241f0006a41106a200441106a290000370300200241f0006a41086a200441086a29000037030020022004290000370370410021040240024020090d0020080e020401040b2008210b0340200b410176220c20046a220d20042007200d4105746a200241f0006a412010e7074101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241f0006a412010e7070d02200a2104200a2005470d000b0b2000410036020820004201370200200128020441ffffff3f71450d01200128020010290c010b200241d0006a41086a2204200241f0006a41086a290300370300200241d0006a41106a220b200241f0006a41106a290300370300200241d0006a41186a220c200241f0006a41186a29030037030020022002290370220e3703102002200e37035041201027220f450d01200f2002290350370000200f41186a200c290300370000200f41106a200b290300370000200f41086a200429030037000020024281808080103702042002200f36020020012802042110200128020021110240200a2005460d00410121120340200628020821032006280200210702400340200241f0006a41186a2208200a41186a290000370300200241f0006a41106a2209200a41106a290000370300200241f0006a41086a2201200a41086a2900003703002002200a290000370370200a41206a210a4100210402400240200341014b0d0020030e020301030b2003210b0340200b410176220c20046a220d20042007200d4105746a200241f0006a412010e7074101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241f0006a412010e7070d01200a2005470d000c030b0b200241d0006a41086a2001290300220e370300200241d0006a41106a20092903002213370300200241d0006a41186a20082903002214370300200220022903702215370350200241106a41186a220b2014370300200241106a41106a220c2013370300200241106a41086a220d200e37030020022015370310024020122002280204470d00200220124101109e012002280200210f0b200f20124105746a22042002290310370000200441186a200b290300370000200441106a200c290300370000200441086a200d2903003700002002201241016a2212360208200a2005470d000b0b0240201041ffffff3f71450d00201110290b20002002290300370200200041086a200241086a2802003602000b20024190016a24000f0b1039000baa0704057f017e0a7f027e23004180016b22032400200341306a2001200228020c220411020002400240024002402003280230450d00200341d8006a41106a200341306a41106a290300370300200341d8006a41086a200341306a41086a290300370300200341d8006a41186a200341306a41186a290300370300200341d8006a41206a200341306a41206a280200360200200341106a41086a200341e4006a290200370300200341106a41106a200341ec006a290200370300200341106a41186a200341f4006a290200370300200320032903303703582003200329025c370310200341d8006a200120022802102205110200417f2003280258220641016a220720072006491bad42287e2208422088a70d022008a72206417f4c0d02200610272209450d032009200329031037030020094201370320200941186a200341106a41186a220a290300370300200941106a200341106a41106a220b290300370300200941086a200341106a41086a220c29030037030020034101360208200320093602002003200641286e2207360204200341306a2001200411020002402003280230450d00200341d8006a41047221064102210d41c800210e0340200341d8006a41206a200341306a41206a280200360200200341d8006a41186a220f200341306a41186a290300370300200341d8006a41106a2210200341306a41106a290300370300200341d8006a41086a2211200341306a41086a29030037030020032003290330370358200c200641086a290200370300200b200641106a290200370300200a200641186a29020037030020032006290200370310200f200a2903003703002010200b2903003703002011200c290300370300200320032903103703580240200d417f6a2007470d00200341306a2001200511020020032007417f2003280230221241016a220920092012491b10a301200328020021090b2009200e6a221241606a220720032903583703002011290300210820102903002113200f290300211420124201370300200741186a2014370300200741106a2013370300200741086a20083703002003200d360208200341306a200120041102002003280230450d01200e41286a210e200d41016a210d200328020421070c000b0b2001200228020011030002402002280204450d00200110290b20002003290300370200200041086a200341086a2802003602000c010b2000410036020820004208370200200120022802001103002002280204450d00200110290b20034180016a24000f0b1038000b1039000bf80202027f037e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022010d00200041003602100c010b200328021421042003200341106a41086a28020022023602242003200136022002400240024020024110490d002003200241706a3602242003200141106a360220200141086a290000210520012900002106200341c8006a200341206a109602200328024822020d010b20034100360230200342013703282003410d36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341f4eaca003602482003200341386a360258200341c4006a41a8a3c800200341c8006a10371a200335023042208620033502288410080240200328022c450d00200328022810290b200041003602100c010b200329024c2107200020053703082000200637030020002007370214200020023602100b2004450d00200110290b200341e0006a24000b5502017f017e230041306b22012400200141086a10cf0220012903082102200141286a2001290310370300200142013703182001427f200220007c220020002002541b370320200141206a10d002200141306a24000bf10905047f017e0c7f027e037f230041e0016b220224002002412036021c20022001360218200241206a2001ad42808080808004841007108b0202400240200228022022030d00200041003602000c010b200228022421042002200241286a28020036023420022003360230200241106a200241306a10c8010240024020022802100d00024002400240200228021422052002280234410c6e2201200120054b1bad420c7e2206422088a70d002006a72201417f4c0d000240024020010d00410421070c010b200110272207450d020b200241003602402002200736023820022001410c6e36023c02402005450d0041002108410021090340200241086a200241306a10c80120022802080d04200228020c220a2002280234220b41246e22012001200a4b1bad42247e2206422088a70d022006a72201417f4c0d020240024020010d004104210c0c010b20011027220c450d040b200241003602502002200c3602482002200141246e36024c02400240200a450d004100210d4100210e0240024002400340200b220f4104490d02200e41016a210e20022002280230220b41046a360230200b280000211041002101200241003a00d801200f417c6a2111034020112001460d02200241b8016a20016a200b20016a221241046a2d00003a00002002201241056a3602302002200141016a22123a00d8012012210120124120470d000b200241f8006a41086a200241b8016a41086a2903002206370300200241f8006a41106a200241b8016a41106a2903002213370300200241f8006a41186a200241b8016a41186a2903002214370300200241d8006a41086a22152006370300200241d8006a41106a22162013370300200241d8006a41186a22172014370300200220022903b8012206370378200220063703580240200d200228024c470d00200241c8006a200d41011096012002280248210c2002280250210d0b201120126b210b200c200d41246c6a22012010360200200120022903583702042001410c6a2015290300370200200141146a20162903003702002001411c6a20172903003702002002200d41016a220d360250200e200a470d000b2002200f20126b417c6a3602340c040b20024100360234200141ff0171450d01200241003a00d8010c010b2002200f3602340b200228024c2201450d06200141246c450d06200c10290c060b200c450d050b200229024c2106200941016a210902402008200228023c470d00200241386a20084101109d0120022802382107200228024021080b20072008410c6c6a220120063702042001200c3602002002200841016a220836024020092005470d000b0b2007450d032000200229023c370204200020073602000c040b1038000b1039000b02402008450d002008410c6c21122007210103400240200141046a280200220b450d00200b41246c450d00200128020010290b2001410c6a2101201241746a22120d000b0b200228023c2201450d002001410c6c450d00200710290b200241003602a00120024201370398012002410d36027c2002200241186a360278200220024198016a360258200241cc016a4101360200200242013702bc01200241f4eaca003602b8012002200241f8006a3602c801200241d8006a41a8a3c800200241b8016a10371a20023502a0014220862002350298018410080240200228029c01450d0020022802980110290b200041003602000b2004450d00200310290b200241e0016a24000ba60305017f017e037f017e017f230041d0006b2202240042002103200241206a41186a4200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032041b3e6ca00ad4280808080e000841001220629000021072005200641086a290000370300200220073703202006102941c0a4cb00ad4280808080e00184100122062900002107200241c0006a41086a2208200641086a2900003703002002200737034020061029200420022903402207370300200241086a2005290300370300200241106a2007370300200241186a200829030037030020022002290320370300024002400240200041024d0d0041012105410121060c010b024002400240024020000e03000102000b410110272205450d0441002106200541003a0000200541014105102b2205450d04200520013600014280808080d00021030c030b410110272205450d03200541013a00000c010b410110272205450d02200541023a00000b4100210642808080801021030b2002ad428080808080048420032005ad841003024020060d00200510290b200241d0006a24000f0b1030000b8b0101017f41d096cc00ad4280808080d001841008024002400240024020002d00000e0400010203000b200041046a29020010080f0b41c296cc00ad4280808080e0018410080f0b41b896cc00ad4280808080a0018410080f0b20003100011016200041026a31000010160240200041046a2802002201450d00200041086a3502004220862001ad8410080b0be40101027f230041106b22022400200220002802003602082001200241086a410410722002200028020436020c20012002410c6a410410720240412010272203450d0020032000290008370000200341186a200041206a290000370000200341106a200041186a290000370000200341086a200041106a290000370000200120034120107220031029412010272203450d0020032000290028370000200341186a200041c0006a290000370000200341106a200041386a290000370000200341086a200041306a290000370000200120034120107220031029200241106a24000f0b1039000bcb0202057f037e2001280200210202400240412010272203450d0020032002290000370000200341186a2204200241186a290000370000200341106a2205200241106a290000370000200341086a2206200241086a290000370000412010272202450d0120022003290000370000200241186a2004290000370000200241106a2005290000370000200241086a200629000037000020031029200128020421012002412041c000102b2203450d0120032001290000370020200341386a200141186a290000370000200341306a200141106a290000370000200341286a200141086a2900003700002003ad4280808080800884101022022900002107200241086a2900002108200241106a2900002109200041186a200241186a290000370000200041106a2009370000200041086a20083700002000200737000020021029200310290f0b1039000b1030000bca0c02097f037e230041d0016b2202240041002103200241386a410010fb0220024198016a20022802382204200228024010cd01200241f8006a41086a2205200241a4016a290200370300200241f8006a41106a2206200241ac016a290200370300200241f8006a41156a2207200241b1016a2900003700002002200229029c013703780240024020022d0098014101460d00200241d8006a41156a4200370000200241d8006a41106a4200370300200241d8006a41086a4200370300200242003703580c010b20022f00990120022d009b01411074722103200241d8006a41156a2007290000370000200241d8006a41106a2006290300370300200241d8006a41086a2005290300370300200220022903783703580b0240200228023c450d00200410290b200241186a41086a200241d8006a41086a2205290300370300200241186a41106a200241d8006a41106a290300370300200241186a41156a200241d8006a41156a29000037000020022002290358370318200241f8006a41156a22064200370000200241f8006a41106a22074200370300200241f8006a41086a220842003703002002420037037841b3e6ca00ad4280808080e00084100122042f00002109200441026a2d0000210a2002200441086a29000037007d200220042900033703782004102941c9e6ca00ad4280808080e0008410012204290000210b2005200441086a2900003703002002200b3703582004102920062005290300220b370000200241b0016a200b3700002002200229035837008501200241a3016a2008290300370000200241ab016a20072903003700002002200a3a009a01200220093b0198012002200229037837009b01200241106a20024198016a412010fc01410021040240024020012903004201520d002001290308220c4200510d012002280214410020022802101b2105417f21042005ad220d200141106a290300220b200b200d541b220d200d200b7d200c827d220b42ffffffff0f560d00200ba721040b20024198016a200410fb02200241086a200228029801220120022802a0014180a6cc004100410010c701200228020821050240200228029c01450d00200110290b410121010240024020054101470d00200241c0016a200410fb0220024198016a20022802c001220120022802c80110cd01200241f8006a41086a2205200241a4016a290200370300200241f8006a41106a2206200241ac016a290200370300200241f8006a41156a2207200241b1016a2900003700002002200229029c013703780240024020022d0098014101460d00200241d8006a41156a4200370000200241d8006a41106a4200370300200241d8006a41086a420037030020024200370358410021040c010b20022f00990120022d009b01411074722104200241d8006a41156a2007290000370000200241d8006a41106a2006290300370300200241d8006a41086a2005290300370300200220022903783703580b024020022802c401450d00200110290b200241386a41156a2201200241d8006a41156a290000370000200241386a41106a2205200241d8006a41106a29030037030020024198016a41086a2206200241d8006a41086a29030037030020024198016a41106a2207200529030037030020024198016a41156a22052001290000370000200241f8006a41086a2201200241186a41086a290300370300200241f8006a41106a2208200241186a41106a290300370300200241f8006a41156a2209200241186a41156a2900003700002002200229035837039801200220022903183703782000410e6a20034110763a00002000410c6a20033b0100200041046a42003702002000412e6a20044110763a00002000412c6a20043b01002000410f6a2002290378370000200041176a20012903003700002000411f6a2008290300370000200041246a20092900003700002000412f6a200229039801370000200041376a20062903003700002000413f6a2007290300370000200041c4006a2005290000370000410021010c010b20024198016a41156a200241386a41156a29000037000020024198016a41106a200241386a41106a29000037030020024198016a41086a200241386a41086a2900003703002002200229003837039801200041036a41003a0000200041800a3b00010b200020013a0000200241d0016a24000f0b41a094cc00411941bc94cc001033000b850605027f027e017f027e027f230041a0016b220224002000280200210002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0220054290ce005441002004501b450d012005a72103412721000c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d02200141b88ac0004102200241206a20006a41800120006b104921000c060b41272100200241186a21060340200241106a200520044290ce00420010e0072002200229031022072006290300220842f0b17f427f10d507200241206a20006a2203417c6a200520022903007ca7220941ffff037141e4006e220a41017441fa85c0006a2f00003b00002003417e6a200a419c7f6c20096a41ffff037141017441fa85c0006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000c040b0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d01200141b88ac0004102200241206a20006a41800120006b104921000c040b200041800141a88ac000104c000b200041800141a88ac000104c000b2007a721030b02400240200341e3004a0d00200321090c010b200241206a2000417e6a22006a2003200341ffff037141e4006e2209419c7f6c6a41ffff037141017441fa85c0006a2f00003b00000b024002402009410a480d00200241206a2000417e6a22006a200941017441fa85c0006a2f00003b00000c010b200241206a2000417f6a22006a200941306a3a00000b20014180a6cc004100200241206a20006a412720006b104921000b200241a0016a240020000bc30202027f017e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120042001104621000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d02200141b88ac0004102200220006a4180016a410020006b104921000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d02200141b88ac0004102200220006a4180016a410020006b104921000b20024180016a240020000f0b200341800141a88ac000104c000b200341800141a88ac000104c000b820101017f200120021071024002402001450d00200141057421030340412010272201450d0220012000290000370000200141186a200041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200220014120107220011029200041206a2100200341606a22030d000b0b0f0b1039000bee19021e7f037e230041e0036b22032400200228020821042002280200210520022802042106200341186a2207200141206a290000370300200341106a2208200141186a290000370300200341086a2209200141106a290000370300200320012900083703002006410174210a2003410772210b200341c8016a41186a210c200341c8016a410c6a210d200341c8016a41206a210e2001280204210f200128020021102006211120052112200421134100211441002115024002400240024002400240024002400240024002400240024002400340200420156a2204410176210102400240024002400240024002400240024002402004410171450d0020112001490d02200120114f0d04200341013a00d001200320123602c801200320013602cc012003201220016a2d000041f001713a00d1010c010b20112001490d02200341003a00d001200320013602cc01200320123602c8010b200341b8036a20102003200341c8016a200f28020c11040002400240024020032802b80322160d00200341c8016a41086a2213200341086a290300370300200341c8016a41106a2206200341106a290300370300200341c8016a41186a2204200341186a290300370300200320032903003703c8014130102722010d010c190b20032802bc032117200341c8016a201620032802c00310870420032d00c8014101460d15201441016a21140c010b200120032903c80137000120012003290020370021200120144100473a0000200141096a2013290300370000200141116a2006290300370000200141196a2004290300370000200141286a200341276a29000037000020004101360200200020013602040c160b034020032802e401211820032802e001211920032802dc01211a20032802d801211120032802d401210420032802d001211220032802cc012101200341206a200e41a80110e4071a200328029403211b200328029003211c024002400240024020010e051710000102170b410021010240200441017420116b221d200a20136b221b201b201d4b1b221e450d000340201320016a221b410176221c20064f0d09201120016a221f410176222020044f0d0a2005201c6a2d0000221c410f71201c41f00171410476201b4101711b201220206a2d0000221b410f71201b410476201f4101711b470d01200141016a2201201e490d000b0b02402001201d460d00200042003702002017450d1a0c190b201d21010c020b200320183602dc01200320193602d8012003201a3602d401200320113602d001200320043602cc01200320123602c801200c200341206a41a80110e4071a02400240200a2013460d00201341017622012006490d012001200641b4a0cc001036000b02400240201c0d00410021010c010b201b417f4c0d1402400240201b0d0041002113410121010c010b201b10272201450d16201b21130b024002402013201b490d00201321060c010b20134101742206201b2006201b4b1b22064100480d17024020130d00200610272201450d1d0c010b20132006460d00200120132006102b2201450d1c0b2001201c201b10e4071a201bad4220862006ad8421210b20002001360204200041086a20213702000c0e0b0240200341c8016a200520016a2d00002201410f71200141047620134101711b410c6c6a2201280200221a4102470d00200041003602040c0e0b20012802042119200141086a28020021184101211d410121010c010b20032802a003211e200328029c03211d2003280298032101200320183602d001200320193602cc012003201a3602c801200d200341206a41a80110e4071a20032001360284032003201b360280032003201c3602fc02410021010240200441017420116b2218200a20136b221a201a20184b1b2219450d000340201320016a221b410176221c20064f0d09201120016a221f410176222020044f0d0a2005201c6a2d0000221c410f71201c41f00171410476201b4101711b201220206a2d0000221b410f71201b410476201f4101711b470d01200141016a22012019490d000b0b0240024002400240024020012018470d00201a2018470d01201d0d02410021010c030b200041003602040c0f0b201820136a220141017622042006490d022004200641b4a0cc001036000b201e417f4c0d1302400240201e0d0041002113410121010c010b201e10272201450d15201e21130b024002402013201e490d00201321060c010b20134101742206201e2006201e4b1b22064100480d16024020130d00200610272201450d1c0c010b20132006460d00200120132006102b2201450d1b0b2001201d201e10e4071a201ead4220862006ad8421210b20002001360204200041086a20213702000c0c0b0240200341c8016a200520046a2d00002204410f71200441047620014101711b410c6c6a2204280200221a4102470d00200041003602040c0c0b201841016a211d201841016a210120042802042119200441086a28020021180b200120156a21152013201d6a21130240201a450d00200341c8016a2019201810870420032d00c8014101460d150c010b0b0240024020184120460d00200341c8016a41086a22122009290300370300200341c8016a41106a221b2008290300370300200c2007290300370300200320032903003703c8012018417f4c0d110240024020180d0041002101410121110c010b201810272211450d13201821010b0240024020012018490d00200121040c010b200141017422042018200420184b1b22044100480d14024020010d00200410272211450d1a0c010b20012004460d00201120012004102b2211450d190b20112019201810e4072111413010272201450d18200141043a0000200120032903c801370001200120032f00aa033b00212001201836002c2001200436002820012011360024200141096a2012290300370000200141116a201b290300370000200141196a200c290300370000200141236a200341aa036a41026a2d00003a0000410121040c010b201941026a2d000021042019410f6a2900002121201941176a29000021222019280003210120192f0000211120192900072123200c2019411f6a2d00003a0000200341c8016a41106a2022370300200341c8016a41086a2021370300200341aa036a41026a20043a0000200320233703c801200320113b01aa03410021040b200341dc036a41026a2211200341aa036a41026a2d00003a0000200341b8036a41086a2212200341c8016a41086a290300370300200341b8036a41106a221b200341c8016a41106a290300370300200341b8036a41186a221c200c280200360200200320032f01aa033b01dc03200320032903c8013703b803024020040d00200b20032903b803370000200b41086a2012290300370000200b41106a201b290300370000200b41186a201c2d00003a0000200320032f01dc033b010020032001360003200320112d00003a00022017450d08201610290c080b200041013602002000200136020420170d140c150b2001201141f4a0cc00104b000b200120114184a1cc00104b000b200120114194a1cc001036000b201c200641b4a0cc001036000b2020200441b4a0cc001036000b201c200641b4a0cc001036000b2020200441b4a0cc001036000b2002280208210420022802042111200228020021120c000b0b200041003602000c020b200041003602000c010b4100211e0240200441017420116b200a20136b2218470d004100211e41002101024002402018450d00410021010340201120016a221b410176221c20044f0d05201320016a221f410176222020064f0d062012201c6a2d0000221c410f71201c41f00171410476201b4101711b200520206a2d0000221b410f71201b410476201f4101711b470d012018200141016a2201470d000c020b0b20012018470d010b2019417f4c0d040240024020190d00410021014101211e0c010b20191027221e450d06201921010b0240024020012019490d00200121130c010b200141017422132019201320194b1b22134100480d07024020010d0020131027221e450d0d0c010b20012013460d00201e20012013102b221e450d0c0b201e201a201910e4071a2019ad4220862013ad8421210b2000201e36020420004100360200200041086a20213702000b02402017450d00201610290b200341e0036a24000f0b201c200441b4a0cc001036000b2020200641b4a0cc001036000b1038000b1039000b1032000b2000420037020020170d010c020b20032d00c9012113200341b8036a41086a2206200341086a290300370300200341b8036a41106a2204200341106a290300370300200341b8036a41186a2211200341186a290300370300200320032903003703b803413010272201450d02200141033a0000200120032903b803370001200120133a0021200120032901aa03370122200141096a2006290300370000200141116a2004290300370000200141196a2011290300370000200141286a200341b0036a29010037010020004101360200200020013602042017450d010b201610290b200341e0036a24000f0b1030000b02000bfc0403027f017e057f230041d0006b2202240041cd87cc00ad4280808080a00184100122032900002104200241086a41086a200341086a2900003703002002200437030820031029418984cc00ad4280808080e00284100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bfc0403027f017e057f230041d0006b2202240041cd87cc00ad4280808080a00184100122032900002104200241086a41086a200341086a29000037030020022004370308200310294187bbc700ad4280808080a00284100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bfc0403027f017e057f230041d0006b2202240041cd87cc00ad4280808080a00184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941e883cc00ad4280808080a00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bb10a03067f017e017f230041f0006b22032400200341106a200010cb04200341c0006a200328021022042003280218220510cc04200341e0006a41086a2206200341c0006a41086a2802003602002003200329034037036002400240200328024c22074102470d0041002108200341003602282003420437032041002106410021070c010b200341306a2003280250360200200341206a41086a2006280200220636020020032003290360370320200328022421080b2003200736022c024020062008470d00200341206a200841011098010b2003280220220741046a2007200641027410e5071a200720013602002003200641016a360228200341c8006a2003290328370300200341c0006a41106a200341206a41106a2802003602002003200329032037034002400240200328024c4102470d002005ad4220862004ad8410040c010b2003200536026420032004360260200341c0006a200341e0006a10cf04200328024441ffffffff0371450d00200328024010290b02402003280214450d00200410290b2003200136026420032000360260200228020421072002280200210620022802082104200341c0006a200341e0006a10cd0420032802402102200320032802483602242003200236022020062004200341206a10a10402402003280244450d00200210290b02402007450d00200610290b200341c0006a41186a4200370300200341c0006a41106a22074200370300200341c0006a41086a220242003703002003420037034041cd87cc00ad4280808080a001841001220629000021092002200641086a290000370300200320093703402006102941b8bcc700ad4280808080f00184100122062900002109200341e0006a41086a2204200641086a2900003703002003200937036020061029200720032903602209370300200341206a41086a2002290300370300200341206a41106a2009370300200341206a41186a200429030037030020032003290340370320200341106a200341206a10ca04024002400240024002400240200328021022080d00410021022003410036020820034204370300410021050c010b20032003290214220937020420032008360200410021020240024002402009422088a7220541014b0d0020050e020201020b20052106034020022006410176220720026a2204200820044103746a41046a28020020014b1b2102200620076b220641014b0d000b0b0240200820024103746a41046a28020022062001460d00200220062001496a21020b200220054b0d030b20052009a7220a470d010b200320054101108d012003280204210a200328020021080b200820024103746a220641086a2006200520026b41037410e5071a20062001360204200620003602002003200541016a2201360208200341c0006a41186a4200370300200341c0006a41106a22074200370300200341c0006a41086a220242003703002003420037034041cd87cc00ad4280808080a001841001220629000021092002200641086a290000370300200320093703402006102941b8bcc700ad4280808080f00184100122062900002109200341e0006a41086a2204200641086a2900003703002003200937036020061029200720032903602209370300200341206a41086a2002290300370300200341206a41106a2009370300200341206a41186a20042903003703002003200329034037032020080d01200341206aad428080808080048410040c020b200220051041000b200341203602442003200341206a36024020082001200341c0006a10f103200a41ffffffff0171450d00200810290b200341f0006a24000be60601067f0240024002400240024020012d0000220341024d0d0041012101410021040c010b02400240024020030e03000102000b410110272205450d03200541013a0000412010272203450d0420032001290001370000200341186a2206200141196a290000370000200341106a2207200141116a290000370000200341086a2208200141096a29000037000041212104200541014121102b2201450d0320012003290000370001200141196a2006290000370000200141116a2007290000370000200141096a2008290000370000200310290c020b410110272205450d02200541023a0000412010272203450d0320032001290001370000200341186a2206200141196a290000370000200341106a2207200141116a290000370000200341086a2208200141096a29000037000041212104200541014121102b2201450d0220012003290000370001200141196a2006290000370000200141116a2007290000370000200141096a2008290000370000200310290c010b410110272205450d01200541033a0000412010272203450d0220032001290001370000200341186a2206200141196a290000370000200341106a2207200141116a290000370000200341086a2208200141096a29000037000041212104200541014121102b2201450d0120012003290000370001200141196a2006290000370000200141116a2007290000370000200141096a2008290000370000200310290b20022802002103410410272205450d0020052003360000412010272203450d0120032002290004370000200341186a22062002411c6a290000370000200341106a2207200241146a290000370000200341086a22082002410c6a290000370000200541044124102b2202450d00200220032900003700042002411c6a2006290000370000200241146a20072900003700002002410c6a20082900003700002003102920044101742203200441246a2206200320064b1b2105024020040d00200510272201450d010c030b20042005460d02200120042005102b22010d020b1030000b1039000b200120046a22032002290000370000200341206a200241206a280000360000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a290000370000200210292000200636020820002005360204200020013602000bfc0403027f017e057f230041d0006b2202240041f182cc00ad4280808080c00184100122032900002104200241086a41086a200341086a29000037030020022004370308200310294182c5c800ad4280808080800284100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bef0602077f047e230041f0006b22032400024002400240200128020422044108490d000340200128020021052003410136026c20032004410376220636020802400240200641014b0d004100210741012108024020060e020002000b200341346a4101360200200341dc006a41023602002003420237024c200341e4a7c7003602482003410136022c2003200341286a3602582003200341086a3602302003200341ec006a360228200341c8006a4180a6cc001040000b200441016a410771200441786a4178717221072005410120041b2205200441077122044107466a2108200441087221040b2005410120041b2d000021062001200736020420012008360200200128020821050240024020064101200441077174710d00410021040c010b0240200128020c220628020820054d0d0020012802102104200341c8006a41186a2207200628020020054105746a220641186a290000370300200341c8006a41106a2208200641106a290000370300200341c8006a41086a2209200641086a29000037030020032006290000370348024020042802082206200441046a280200470d00200420064101109e01200428020821060b200428020020064105746a22062003290348370000200641186a2007290300370000200641106a2008290300370000200641086a20092903003700002004200428020841016a3602080b4100210402402002280200220628020820054d0d00200341c8006a41086a200628020020054105746a220441086a290000370300200341c8006a41106a200441106a290000370300200341c8006a41186a200441186a29000037030020032004290000370348410121040b200128020821050b2001200541016a360208200341286a41086a200341c8006a41086a290300370300200341286a41106a200341c8006a41106a290300370300200341286a41186a200341c8006a41186a2903003703002003200329034837032820040d022001280204220441084f0d000b0b200041003a00000c010b200341086a41186a200341286a41186a290300220a370300200341086a41106a200341286a41106a290300220b370300200341086a41086a200341286a41086a290300220c37030020032003290328220d370308200041196a200a370000200041116a200b370000200041096a200c3700002000200d370001200041013a00000b200341f0006a24000bfc0403027f017e057f230041d0006b2202240041cd87cc00ad4280808080a00184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941f283cc00ad4280808080d00084100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000b940201037f230041d0006b220224002002200136020420022000360200200241086a2001ad4220862000ad841007108b0202400240200228020822010d00410221000c010b200228020c210302400240200241106a280200450d0020012d0000220441014b0d0041002100024020040e020200020b410121000c010b20024100360220200242013703182002410d36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241f4eaca003602382002200241286a360248200241346a41a8a3c800200241386a10371a200235022042208620023502188410080240200228021c450d00200228021810290b410221000b2003450d00200110290b200241d0006a240020000b130020004113360204200041e8bdc7003602000b8b0301037f230041d0006b22032400024002400240024020002d00000e03010200010b200341c8006a200041196a290000370300200341c0006a200041116a290000370300200341386a200041096a2900003703002003200029000137033041022104200341306a21050c020b200341c8006a200041196a290000370300200341c0006a200041116a290000370300200341386a200041096a2900003703002003200029000137033041002104200341306a21050c010b200341c8006a200041196a290000370300200341c0006a200041116a290000370300200341386a200041096a2900003703002003200029000137033041012104200341306a21050b200341216a200541186a290000370000200341196a200541106a290000370000200341116a200541086a290000370000200320043a000820032005290000370009200341306a200341086a2001108c06200041216a200335023842208620032802302205ad8420021017210002402003280234450d00200510290b200341d0006a24004106410220004101461b0b8c0a03047f017e047f23004190016b22022400200241d8006a41186a4200370300200241d8006a41106a22034200370300200241d8006a41086a220442003703002002420037035841b1dcc900ad4280808080f000841001220529000021062004200541086a2900003703002002200637035820051029418886ca00ad4280808080c00184100122052900002106200241f8006a41086a2207200541086a2900003703002002200637037820051029200320022903782206370300200241386a41086a2004290300370300200241386a41106a2006370300200241386a41186a200729030037030020022002290358370338200241106a200241386a412010fc01200241d8006a2002280214410020022802101b2203200010b805200241086a2002280258220420022802604180a6cc004100410010c701200228020821050240200228025c450d00200410290b410121040240024002400240024020054101460d0041c6b7c700ad4280808080800184100122042900002106200241f8006a41086a200441086a290000370300200220063703782004102941e0c9c700ad4280808080e00184100122042900002106200241386a41086a200441086a2900003703002002200637033820041029200220033602282002200241286aad4280808080c00084100222042900003703880120041029200241e4006a22052002412c6a360200200220024188016a41086a220036025c2002200241286a360260200220024188016a360258200241186a200241d8006a1075412010272204450d0120042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020022004ad42808080808004841002220129000037038801200110292005200441206a360200200220043602602002200036025c200220024188016a360258200241286a200241d8006a1075200410292002280220220741206a2200200228023022086a2201417f4c0d02200228022821092002280218210a0240024020010d0041002103410121040c010b200110272204450d02200121030b024002402003410f4d0d00200321050c010b200341017422054110200541104b1b22054100480d04024020030d002005102722040d010c060b20032005460d00200420032005102b2204450d050b20042002290378370000200441086a200241f8006a41086a2903003700000240024020054170714110460d00200521030c010b200541017422034120200341204b1b22034100480d0420052003460d00200420052003102b2204450d050b20042002290338370010200441186a200241386a41086a29030037000002400240200341606a2007490d00200321050c010b2007415f4b0d04200341017422052000200520004b1b22054100480d0420032005460d00200420032005102b2204450d050b200441206a200a200710e4071a02400240200520006b2008490d00200521030c010b20012000490d04200541017422032001200320014b1b22034100480d04024020050d00024020030d00410121040c020b200310272204450d060c010b20052003460d00200420052003102b2204450d050b200420006a2009200810e4071a0240200228022c450d00200910290b0240200228021c450d00200a10290b20022004200110fc01200228020421012002280200210502402003450d00200410290b200141004720054100477121040b20024190016a240020040f0b1039000b1038000b1032000b1030000bae0707017f017e067f017e047f017e027f230041306b220124000240024010222202422088a722030d00410121040c010b2002a721040b2001200336022420012004360220024002400240024002402003450d0020042d0000210520012003417f6a3602242001200441016a360220200541014b0d00024020050e020004000b200141186a200141206a10c80120012802180d0020012802242206200128021c2205490d002005417f4c0d020240024020050d0042002102410121070c010b2005102d2207450d02200720012802202208200510e4071a2001200620056b3602242001200820056a3602202005ad21020b2007450d00200141106a200141206a10c8012005ad4220862002842209a7210a024020012802100d002001280214220b2001280224410c6e22052005200b4b1bad420c7e2202422088a70d032002a72205417f4c0d030240024020050d004104210c0c010b20051027220c450d030b2005410c6ead21020240200b450d000340200141086a200141206a10c80102400240024020012802080d0020012802242206200128020c2205490d002005417f4c0d080240024020050d004100210d410121080c010b2005102d2208450d0820082001280220220d200510e4071a2001200620056b3602242001200d20056a3602202005210d0b2002422088220ea722062002a7470d02024002400240200641016a220f2006490d00200ea74101742210200f200f2010491bad420c7e220e422088a70d00200ea7220f4100480d00024020060d00200f0d024104210c0c050b2006410c6c2206200f460d04024020060d00200f0d024104210c0c050b200c2006200f102b220c450d020c040b1032000b200f1027220c0d020b1030000b02402002422088a72205450d002005410c6c2106200c210503400240200541046a280200450d00200528020010290b2005410c6a2105200641746a22060d000b0b2002a72205450d042005410c6c450d04200c10290c040b2002422088220ea72106200f410c6ead21020b200c2006410c6c6a22062005ad422086200dad8437020420062008360200200e422086200242ffffffff0f83844280808080107c2102200b417f6a220b0d000b0b200c450d002007450d012009422088a721050c050b200a450d00200710290b41e891cc00412e200141286a419893cc00419892cc00103a000b1039000b1038000b410021070b2000200a36020420002007360200200041106a20023702002000410c6a200c360200200041086a200536020002402003450d00200410290b200141306a24000b970403017f017e017f23004190016b22052400200520013602040240200541046a20022004ad4220862003ad8410212206422088a72201450d002006a722072d0000220341014b0d004100210202400240024020030e020100010b41002102200541003a008801200741016a21042001417f6a2101034020012002460d02200541c8006a20026a200420026a2d00003a00002005200241016a22033a00880120032102200341c000470d000b200541086a41386a200541c8006a41386a290300370300200541086a41306a200541c8006a41306a290300370300200541086a41286a200541c8006a41286a290300370300200541086a41206a200541c8006a41206a290300370300200541086a41186a200541c8006a41186a290300370300200541086a41106a200541c8006a41106a290300370300200541086a41086a200541c8006a41086a29030037030020052005290348370308410121020b200020023a000020002005290308370001200041096a200541106a290300370000200041116a200541186a290300370000200041196a200541206a290300370000200041216a200541286a290300370000200041296a200541306a290300370000200041316a200541386a290300370000200041396a200541c0006a2903003700002007102920054190016a24000f0b200241ff0171450d00200541003a0088010b41e891cc00412e200541c8006a419893cc00419892cc00103a000bac0501077f23004190016b2202240002400240024002402000410c6a2802002203417f4c0d0020002802042104200028020021050240024020030d0041002106410121070c010b200310272207450d02200321060b0240024020062003490d00200621080c010b200641017422082003200820034b1b22084100480d03024020060d002008102722070d010c050b20062008460d00200720062008102b2207450d040b20072004200310e4072106200241f8006a200041106a10f305200241106a410c6a2003360200200241106a41086a22032008360200200241206a2002290378370300200241286a2208200241f8006a41086a280200360200200241106a41306a200041306a290200370300200241106a41386a200041386a290200370300200241106a41c0006a200041c0006a290200370300200241106a41c8006a200041c8006a290200370300200241106a41d0006a200041d0006a290200370300200241106a41d8006a200041d8006a290200370300200241106a41e0006a200041e0006a2902003703002002200636021420022005360210200220002802243602342002200029021c37022c200220002902283703382002410c6a411d360200200241acbbc700360200200241043602042001411c6a28020021002002200241106a360208200128021821062002418c016a41023602002002420237027c200241d0cfc700360278200220023602880120062000200241f8006a1037210602402003280200450d00200228021410290b024020082802002203450d00200228022021002003410c6c210303400240200041046a280200450d00200028020010290b2000410c6a2100200341746a22030d000b0b0240200241246a2802002200450d002000410c6c450d00200228022010290b20024190016a240020060f0b1038000b1039000b1032000b1030000b980201027f230041206b22022400200220012802184180a6cc0041002001411c6a28020028020c1100003a00102002200136020841012101200241013a00112002410036020c200220003602182002200041286a36021c200241086a200241186a41e0cfc70010622002411c6a41f0cfc70010621a20022d0010210002400240200228020c22030d00200021010c010b0240200041ff01710d00024020034101470d0020022d001141ff0171450d00200228020822002d00004104710d0041012101200028021841a79fc00041012000411c6a28020028020c1100000d010b20022802082201280218418ee5c80041012001411c6a28020028020c11000021010b200220013a00100b200241206a2400200141ff01714100470b130020004104360204200041c8d0c7003602000b340020004188dac70036020420004100360200200041146a4101360200200041106a418cdac700360200200041086a42043702000b130020004103360204200041a0dbc7003602000b3400200041dfb3c70036020420004100360200200041146a4101360200200041106a41fcecc700360200200041086a42073702000b130020004101360204200041a4eec7003602000b130020004101360204200041d0efc7003602000b3400200041c6b7c70036020420004100360200200041146a4104360200200041106a419cf4c700360200200041086a42083702000b2201017f230041106b22022400200241003602002000200210e602200241106a24000b13002000410236020420004180fdc7003602000b3400200041cd87cc0036020420004100360200200041146a410c360200200041106a41d480c800360200200041086a420a3702000b2c01017f02404108102722020d001039000b20024200370000200042888080808001370204200020023602000b2b01017f02404104102722020d001039000b200042848080801037020420002002360200200241003a00000be40101047f230041106b2202240020024100360208200242013703004100200210710240024002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d01200341017422052004200520044b1b22054100480d010240024020030d0041002103024020050d00410121040c020b2005102722040d010c040b2002280200210420032005460d00200420032005102b2204450d030b20022005360204200220043602000b200420036a41003a0000200041086a200341016a36020020002002290300370200200241106a24000f0b1032000b1030000b8b05010a7f02400240200141086a280200220241036a2203417f4c0d0020012d000021044101210541002106024002402003450d00200310272205450d01200321060b200241017420046a220741ffff03200741ffff03491b220341c0006a41ff0020032007413e2003413e491b2207461b2108200320076b2109410021034101210a02400240034020082107024002400240200a41ff01714102470d00200721080c010b41002108200a410171450d004100210a0c010b2009450d0202402009418002490d00200941817e6a210941ff0121074102210a0c010b2009417f6a21074102210a410021090b024020062003470d00200341016a22062003490d032003410174220b2006200b20064b1b22064100480d03024020030d0041002103024020060d00410121050c020b2006102722050d010c070b20032006460d00200520032006102b2205450d060b200520036a20073a0000200341016a21030c000b0b02402004450d0020012d00012107024020032006470d00200341016a22092003490d022003410174220a2009200a20094b1b22064100480d02024020030d00024020060d00410121050c020b200610272205450d060c010b20032006460d00200520032006102b2205450d050b200520036a2007410f713a0000200341016a21030b2001280204210902400240200620036b2002490d00200621070c010b200320026a22072003490d012006410174220a2007200a20074b1b22074100480d01024020060d00024020070d00410121050c020b200710272205450d050c010b20062007460d00200520062007102b2205450d040b200520036a2009200210e4071a2000200320026a36020820002007360204200020053602000f0b1032000b1039000b1038000b1030000bb70101057f20012802082202410176210320012802042104024002400240024020024101710d0020042003490d02200128020020036a210141002102410021050c010b200420034d0d024101210520012802002202200341016a22066a2101200220036a2d0000410f712102200621030b200020053a000c20002001360204200041003602002000410d6a20023a0000200041086a200420036b3602000f0b2003200441b09fcc00104c000b2003200441c09fcc001036000bd60101017f024002402000280200220141034b0d0002400240024020010e0404000102040b0240200041086a28020041244d0d00200041106a28020010290b200041386a280200450d03200041346a28020010290f0b200041086a28020041244d0d02200041106a28020010290f0b20002802041029200041086a2802002201450d012000410c6a280200450d01200110290c010b0240200041086a28020041244d0d00200041106a28020010290b200041346a2802001029200041386a2802002201450d002000413c6a280200450d00200110290f0b0be12203047f067e037f230041c0036b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c01020c03040506070c08090a0b0c0d0e0f1011121314151617181900010b200241a0016a200141086a10f8032000411b360200200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c190b200241a0016a200141086a10f90320004100360200200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c180b200241a0016a200141046a10fa0320004101360200200041246a200241c0016a2802003602002000411c6a200241b8016a290300370200200041146a200241b0016a2903003702002000410c6a200241a8016a290300370200200020022903a0013702040c170b20004103360200200041086a200141086a2903003703000c160b02400240024002400240024020012d0004417f6a220341034b0d00200141046a210420030e0401020304010b419cf7ca00412841b8a1cc001033000b200141086a2802002103410121050c030b41022105200241026a200441036a2d00003a0000200241a0016a41086a200141146a290200370300200241b0016a2001411c6a290200370300200241b8016a200141246a2d00003a0000200220042f00013b010020022001410c6a2902003703a001200141086a2802002103200141286a28020021010c020b200141086a2802002103410321050c010b200241026a200441036a2d00003a0000200241a0016a41086a200141146a290200370300200241b0016a2001411c6a290200370300200241b8016a200141246a2d00003a0000200220042f00013b010020022001410c6a2902003703a001200141086a2802002103200141286a2802002101410421050b200020053a0004200020022f01003b000520004104360200200041086a20033602002000410c6a20022903a001370200200041286a2001360200200041076a200241026a2d00003a0000200041146a200241a0016a41086a2903003702002000411c6a200241b0016a290300370200200041246a200241b8016a2802003602000c150b02400240024002400240024002400240200141086a22032d0000417f6a220541034b0d0020050e0401020304010b419cf7ca00412841b8a1cc001033000b200241a8016a200341096a290000370300200241b0016a200341116a290000370300200241b8016a200341196a290000370300200220032900013703a001200141386a2903002106200141306a2903002107410121010c030b200241a8016a200341096a290000370300200241b0016a200341116a290000370300200241b8016a200341196a290000370300200220032900013703a001200141c8006a2903002108200141c0006a2903002109200141386a2903002106200141306a2903002107410221010c030b200241a8016a200341096a290000370300200241b0016a200341116a290000370300200241b8016a200341196a290000370300200220032900013703a0012002200341216a2800003602002002200341246a280000360003200141c8006a3100002108200141c0006a2902002109200141386a2902002106200141306a2902002107200141d8006a290300210a200141d0006a290300210b410321010c030b200241a8016a200341096a290000370300200241b0016a200341116a290000370300200241b8016a200341196a290000370300200220032900013703a001200141386a2903002106200141306a2903002107410421010b0b0b200020022903a0013700092000200228020036002920004105360200200041d8006a200a370300200041d0006a200b370300200041c8006a2008370300200041c0006a2009370300200041386a2006370300200041306a2007370300200041086a20013a00002000412c6a2002280003360000200041116a200241a0016a41086a290300370000200041196a200241b0016a290300370000200041216a200241b8016a2903003700000c140b200241a0016a200141046a10fb03200041063602002000410c6a200241a8016a280200360200200020022903a0013702040c130b200241a0016a200141086a10a302200041086a200241a0016a41900210e4071a200041073602000c120b024002402001280204220c0d00410021030c010b200241a0016a41186a200141286a290000370300200241a0016a41106a200141206a290000370300200241a8016a200141186a290000370300200241a0016a41286a200141386a290000370300200241a0016a41306a200141c0006a290000370300200241a0016a41386a200141c8006a290000370300200241a0016a41c8006a200141d8006a290000370300200241a0016a41d0006a200141e0006a290000370300200241a0016a41d8006a200141e8006a2900003703002002200141106a2900003703a0012002200141306a2900003703c0012002200141d0006a2900003703e001200241a0016a41f8006a20014188016a290000370300200241a0016a41f0006a20014180016a290000370300200241a0016a41e8006a200141f8006a290000370300200241a0016a4198016a200141a8016a290000370300200241a0016a4190016a200141a0016a290000370300200241a0016a4188016a20014198016a2900003703002002200141f0006a29000037038002200220014190016a2900003703a0022001410c6a2802002201417f4c0d130240024020010d0041002105410121030c010b200110272203450d15200121050b0240024020052001490d00200521040c010b200541017422042001200420014b1b22044100480d16024020050d002004102722030d010c180b20052004460d00200320052004102b2203450d170b2003200c200110e4071a2002200241a0016a41a00110e4071a0b200020033602042000410c6a2001360200200041086a2004360200200041106a200241a00110e4071a200041093602000c110b2000410a360200200020012802043602040c100b200241a0016a200141086a10fc03200041086a200241a0016a41980210e4071a2000410b3602000c0f0b200141106a2802002203417f4c0d0f200141086a280200210d2001280204210e0240024020030d00410021054101210c0c010b20031027220c450d11200321050b0240024020052003490d00200521040c010b200541017422042003200420034b1b22044100480d12024020050d0020041027220c450d140c010b20052004460d00200c20052004102b220c450d130b200c200d200310e4072105200241a0016a200141146a10f305200041106a20033602002000410c6a2004360200200041086a20053602002000200e360204200041146a20022903a0013702002000411c6a200241a0016a41086a280200360200200041286a2001280228360200200041206a20012902203702002000412c6a2001412c6a2201290200370200200041346a200141086a2902003702002000413c6a200141106a290200370200200041c4006a200141186a290200370200200041cc006a200141206a290200370200200041d4006a200141286a290200370200200041dc006a200141306a290200370200200041e4006a200141386a2902003702002000410c3602000c0e0b10f403000b200241a0016a200141086a10fe032000410e360200200041386a200241a0016a41306a290300370300200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c0c0b200241a0016a200141086a10ff032000410f360200200041386a200241a0016a41306a290300370300200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c0b0b200241a0016a200141086a10ff0320004110360200200041386a200241a0016a41306a290300370300200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c0a0b200241a0016a200141086a10800420004111360200200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c090b200241a0016a200141046a108104200041046a200241a0016a41c40010e4071a200041123602000c080b200241a0016a200141086a10820420004113360200200041c0006a200241a0016a41386a290300370300200041386a200241a0016a41306a290300370300200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c070b200241a0016a200141046a108304200041046a200241a0016a41a00210e4071a200041143602000c060b200041153602000c050b200241a0016a200141086a10840420004116360200200041c0006a200241a0016a41386a290300370300200041386a200241a0016a41306a290300370300200041306a200241a0016a41286a290300370300200041286a200241a0016a41206a290300370300200041206a200241a0016a41186a290300370300200041186a200241a0016a41106a290300370300200041106a200241a0016a41086a290300370300200041086a20022903a0013703000c040b200241a0016a200141046a108504200041046a200241a0016a41c80010e4071a200041173602000c030b200241a0016a200141086a108604200041086a200241a0016a41f00010e4071a200041183602000c020b4102210c0240024002400240200141086a22032d0000417f6a220d41024b0d0041012105200d0e03030201030b419cf7ca00412841b8a1cc001033000b200141c8006a2903002109200141c0006a2903002108200141386a2903002107200141306a2903002106200141d0006a28020021044103210c0b200241b8016a200341196a290000370300200241b0016a200341116a290000370300200241a8016a200341096a290000370300200220032900013703a001200c21050b200020022903a0013700092000200228000036002920004119360200200041c8006a2009370300200041c0006a2008370300200041386a2007370300200041306a2006370300200041086a20053a0000200041d0006a2004360200200041116a200241a0016a41086a290300370000200041196a200241b0016a290300370000200041216a200241b8016a2903003700002000412c6a200241036a2800003600000c010b200241a0016a200141046a10f5032000411a3602002000413c6a200241d8016a280200360200200041346a200241d0016a2903003702002000412c6a200241c8016a290300370200200041246a200241c0016a2903003702002000411c6a200241b8016a290300370200200041146a200241b0016a2903003702002000410c6a200241a8016a290300370200200020022903a0013702040b200241c0036a24000f0b1038000b1039000b1032000b1030000ba50302047f017e23004180016b2202240002400240024002402000410c6a22032802002204200041106a280200470d002002200141fc0010e407210120002802082204200041046a280200470d02024002400240200441016a22032004490d00200441017422052003200520034b1bad42fc007e2206422088a70d002006a722034100480d00024020040d0020030d02410421050c050b20002802002105200441fc006c22042003460d04024020040d0020030d02410421050c050b200520042003102b2205450d020c040b1032000b2003102722050d020b1030000b2003200041186a280200417f6a200441016a71360200200041146a28020020044102746a28020021042002200141fc0010e407210102402000280208220320044d0d002000280200200441fc006c6a220041246a200041046a20002d00001b10a7062000200141fc0010e4071a0c030b20042003419095c8001036000b20002005360200200041046a200341fc006e360200200028020821040b2000280200200441fc006c6a200141fc0010e4071a20002000280208220441016a3602080b20024180016a240020040b130020004101360204200041d496c8003602000bfe0902037f047e23004190016b22062400024002400240024002402005450d0041002107200641003602080240024020012d00504101460d00200141d4006a28020021080c010b200641166a200141d3006a2d00003a0000200641206a200141e0006a290000370300200641286a200141e8006a290000370300200641306a200141f0006a2d00003a00002006200141d1006a2f00003b01142006200141d8006a290000370318200141d4006a2800002108410121070b200641e8006a41086a2006290318370300200641e8006a41106a200641186a41086a290300370300200641e8006a41186a200641186a41106a29030037030020064188016a200641186a41186a280200360200200620073a0068200620062f01143b00692006200836026c2006200641166a2d00003a006b200641003602502006200336024c200620023602482005417f4c0d02200510272202450d0320022004200510e4072102200620053602602006200536025c20062002360258200641386a2001200641e8006a200641c8006a200641d8006a200641086a10ac06200628023c210520062802384101460d01200141003a00502000200629030837020420004100360200200141d4006a20053602002000410c6a200641106a2802003602000c040b410121050240024020012d00504101460d00200141d4006a2802002104410021050c010b2006410a6a200141d3006a2d00003a0000200641206a200141e0006a290000370300200641286a200141e8006a290000370300200641306a200141f0006a2d00003a00002006200141d1006a2f00003b01082006200141d8006a290000370318200141d4006a28000021040b200641003602402006200336023c2006200236023820064100360248200641e8006a41086a2006290318370300200641e8006a41106a200641186a41086a290300370300200641e8006a41186a200641186a41106a29030037030020064188016a200641186a41186a280200360200200620053a0068200620062f01083b00692006200641086a41026a2d00003a006b2006200436026c200641d8006a2001200641e8006a200641386a200641c8006a10ad06200628025c210502400240024020062802584101460d00200641d8006a41086a2d000041ff01714102470d0141b4e0c800ad42808080801084220910102205290000210a200541086a290000210b200541106a290000210c200641e8006a41186a2202200541186a290000370300200641e8006a41106a2203200c370300200641e8006a41086a2204200b3703002006200a37036820051029200141013a0050200141d1006a2006290368370000200141d9006a2004290300370000200141e1006a2003290300370000200141e9006a2002290300370000200220091010220541186a2900003703002003200541106a2900003703002004200541086a2900003703002006200529000037036820051029200128024c22012006290368370000200141186a2002290300370000200141106a2003290300370000200141086a20042903003700000c020b200041013602002000200536020420062802482201450d05200628024c450d05200110290c050b200141003a0050200141d4006a20053602000b20002006290348370204200041003602002000410c6a200641d0006a2802003602000c030b200041013602002000200536020420062802082201450d02200628020c450d02200110290c020b1038000b1039000b20064190016a24000bca2f03087f0c7e0a7f230022062107200641e0076b4160712206240002400240024002400240024002400240024002400240024020022d00004101470d00200641b8046a200241196a290000370300200641b0046a200241116a290000370300200641a8046a200241096a290000370300200620022900013703a004200328020822084101762102200328020421092003280200210a024002402008410171450d0020092002490d04200220094f0d062006200a360288072006200236028c0720064191076a200a20026a2d000041f001713a0000200641013a0090070c010b20092002490d04200641003a0090072006200236028c072006200a360288070b200641e0036a2001200641a0046a20064188076a10ae0620062802e403210220062802e0034101470d0120004101360200200020023602040240200441046a280200450d00200428020010290b200724000f0b200241046a28020021020b0240200141c0006a220b28020022082008417f6a200141386a220a2802002209200141346a220c2802006b716b4101470d002001413c6a108b01200c280200220c200a28020022094d0d00024020092008200c6b220d490d00200128023c2209200b280200200d6b22084102746a2009200c4102746a200d41027410e4071a200141346a2008360200200141386a28020021090c010b200128023c220c20084102746a200c200941027410e4071a200141386a2209200928020020086a22093602000b200a200b280200417f6a200941016a713602002001413c6a28020020094102746a2002360200200141306a280200220920024d0d032001280228200241fc006c6a2202290210210e200220062903b0043702102002290208210f200220062903a804370208200641003a00a004200641003602a40420022902002110200220062903a004370200200241186a22092902002111200920062903b80437020020022902402112200241c8006a2902002113200241d0006a2902002114200241d8006a290200211520022902202116200241286a2902002117200241306a2902002118200241386a290200211920064180036a41086a2209200241e8006a29020037030020064180036a41106a220a200241f0006a29020037030020064180036a41186a2208200241f8006a280200360200200620113703f8032006200e3703f0032006200f3703e803200620103703e003200620193703d803200620183703d003200620173703c803200620163703c003200620153703b803200620143703b003200620133703a803200620123703a003200620022902603703800320064190046a41086a2202200441086a2802003602002006200429020037039004024002400240024002400240024002402010a7220b41ff01714101470d002003280200210c2003280204211a2003280208210d20064188066a41186a20062802fc0336020020064188066a41106a20062902f40337030020064188066a41086a20062902ec03370300200620062902e40337038806200641bc076a2015370200200641b4076a201437020020064188076a41246a2013370200200641a4076a201237020020064188076a41186a20062802dc0336020020064188076a41106a20062902d40337030020064188076a41086a20062902cc03370300200620062902c4033703880720064188076a413c6a20062903800337020020064188076a41c4006a2009290300370200200641d4076a200a290300370200200641dc076a2008280200360200200641c8056a41086a200228020036020020062006290390043703c805200641a0046a200120064188076a2003200641c8056a200510af0620062802a404210220062802a0044101460d072010420888a721052016a72108200641e8066a41186a2203200641c0046a280200360200200641e8066a41106a220a200641a0046a41186a290300370300200641e8066a41086a221b200641a0046a41106a221c290300370300200641c8066a41086a221d200641cd046a290000370300200641c8066a41106a221e200641d5046a290000370300200641c8066a41176a221f200641a0046a413c6a290000370000200620062900c5043703c8062006200641a0046a41086a22202903003703e806200641a0046a41246a2d00002104200641a8066a41086a2221200641ed046a290000370300200641a8066a41106a2222200641f5046a290000370300200641a8066a41176a2223200641fc046a280000360000200620062900e5043703a806200641a0046a41c4006a2d0000210920020e03030201030b200641bc076a2019370200200641b4076a201837020020064188076a41246a2017370200200641a4076a201637020020064188076a41186a20062802fc0336020020064188076a41106a20062902f40337030020064188076a41086a20062902ec0337030020064188076a413c6a20062903a00337020020064188076a41c4006a20062903a803370200200641d4076a20062903b003370200200641dc076a20062802b803360200200620062902e40337038807200641c8056a41086a200228020036020020062006290390043703c805200641a0046a200120064188076a2003200641c8056a200510af0620062802a404210220062802a0044101460d06200641e8066a41186a2209200641c0046a280200360200200641e8066a41106a2208200641a0046a41186a290300370300200641e8066a41086a220c200641a0046a41106a290300370300200641c8066a41086a220d200641cd046a290000370300200641c8066a41106a221a200641d5046a290000370300200641c8066a41176a221b200641a0046a413c6a290000370000200620062900c5043703c8062006200641a0046a41086a2903003703e806200641a0046a41246a2d0000210420064188066a41086a221c200641ed046a29000037030020064188066a41106a221d200641f5046a29000037030020064188066a41176a221e200641fc046a280000360000200620062900e50437038806200641a0046a41c4006a2d0000210a410221034100210520020e03030405030b200d410176210202400240200d410171450d00201a2002490d0c2002201a4f0d01200c20026a2d00004170712103410121040c0f0b0240201a2002490d00410021040c0f0b2002201a4184a1cc00104b000b2002201a4194a1cc001036000b200641e8056a41086a20064188066a41086a290300370300200641e8056a41106a20064188066a41106a290300370300200641e8056a41186a20064188066a41186a280200360200200641ab046a201b290300370000200641b3046a200a290300370000200641bb046a200328020036000020064188076a41176a201f29000037000020064188076a41106a201e29030037030020064188076a41086a201d29030037030020062006290388063703e805200620062903e8063700a304200620062903c80637038807200641a8056a41176a2023280000360000200641a8056a41106a2022290300370300200641a8056a41086a2021290300370300200641c8056a41176a200641a0046a41176a290000370000200641c8056a41106a201c290000370300200641c8056a41086a2020290000370300200620062903a8063703a805200620062900a0043703c80541012103410021052004210a200821040c0d0b200d410176210202400240200d410171450d00201a2002490d0b2002201a4f0d01200c20026a2d0000417071210d4101211a0c0c0b0240201a2002490d004100211a0c0c0b2002201a4184a1cc00104b000b2002201a4194a1cc001036000b410121050b200641e8056a41186a2009280200360200200641e8056a41106a2008290300370300200641e8056a41086a200c290300370300200641c8056a41086a200d290300370300200641c8056a41106a201a290300370300200641c8056a41176a201b29000037000020064188076a41086a201c29030037030020064188076a41106a201d29030037030020064188076a41176a201e280000360000200620062903e8063703e805200620062903c8063703c805200620062903880637038807410021030b0c090b410121030c090b2002200941f4a0cc00104b000b200220094184a1cc00104b000b200220094194a1cc001036000b20022009418095c8001036000b2002201a41f4a0cc00104b000b2002201a41f4a0cc00104b000b41002103200641003a00a404200641003602a004200641a0046a200c200c20026a10b00620064188076a41286a220c200641a0046a41286a221b28020036020020064188076a41206a221c200641a0046a41206a29030037030020064188076a41186a221d200641a0046a41186a29030037030020064188076a41106a2202200641a0046a41106a29030037030020064188076a41086a220a200641a0046a41086a290300370300200620062903a00437038807200641ab046a20064188066a41086a290300370000200641b3046a20064188066a41106a290300370000200641bb046a20064188066a41186a28020036000020062006290388063700a304200620083a00bf04200620053b01a004200620054110763a00a204201b200a290300370300200641d0046a2002290300370300200641d8046a201d290300370300200641e0046a201c290300370300200641e8046a200c28020036020020062006290388073703c004200641ed046a200d3a0000200641ec046a201a3a0000200641ee046a20062f01a8053b01002001200641a0046a10b104200641e8056a41086a200641e8066a41086a290300370300200641e8056a41106a200641e8066a41106a290300370300200641e8056a41186a200641e8066a41186a280200360200200641c8056a41086a200641c8066a41086a290300370300200641c8056a41106a200641c8066a41106a290300370300200641c8056a41176a200641c8066a41176a290000370000200620062903e8063703e805200620062903c8063703c80520064188076a41176a200641a8066a41176a2800003600002002200641a8066a41106a290300370300200a200641a8066a41086a290300370300200620062903a80637038807410121052009210a0c010b200641003a00a404200641003602a004200641a0046a200c200c20026a10b00620064188076a41286a2202200641a0046a41286a220a28020036020020064188076a41206a220c200641a0046a41206a29030037030020064188076a41186a220d200641a0046a41186a29030037030020064188076a41106a221a200641a0046a41106a29030037030020064188076a41086a221b200641a0046a41086a290300370300200620062903a00437038807200641ab046a20064188066a41086a290300370000200641b3046a20064188066a41106a290300370000200641bb046a20064188066a41186a28020036000020062006290388063700a304200620083a00bf04200620053b01a004200620054110763a00a204200a201b290300370300200641d0046a201a290300370300200641d8046a200d290300370300200641e0046a200c290300370300200641e8046a200228020036020020062006290388073703c004200641ed046a20033a0000200641ec046a20043a0000200641ee046a20062f01c8053b01002001200641a0046a10b104410221030b200641e8066a41186a200641e8056a41186a280200360200200641e8066a41106a200641e8056a41106a290300370300200641e8066a41086a200641e8056a41086a290300370300200641a0046a41086a200641c8056a41086a290300370300200641a0046a41106a200641c8056a41106a290300370300200641a0046a41176a200641c8056a41176a290000370000200641c8066a41086a20064188076a41086a290300370300200641c8066a41106a20064188076a41106a290300370300200641c8066a41176a20064188076a41176a290000370000200620062903e8053703e806200620062903c8053703a00420062006290388073703c80620064188066a41176a200641a8056a41176a28000036000020064188066a41106a200641a8056a41106a29030037030020064188066a41086a200641a8056a41086a290300370300200620062903a805370388062003200b41807e71722102410021030b200641e0026a41086a2208200641e8066a41086a290300370300200641e0026a41106a220b200641e8066a41106a290300370300200641e0026a41186a220c200641e8066a41186a280200360200200641c0026a41086a220d200641a0046a41086a290300370300200641c0026a41106a221a200641a0046a41106a290300370300200641c0026a41176a221b200641a0046a41176a290000370000200620062903e8063703e002200620062903a0043703c002200641a0026a41176a221c200641c8066a41176a290000370000200641a0026a41106a221d200641c8066a41106a290300370300200641a0026a41086a221e200641c8066a41086a29030037030020064180026a41086a221f20064188066a41086a29030037030020064180026a41106a222020064188066a41106a29030037030020064180026a41176a222120064188066a41176a280000360000200620062903c8063703a0022006200629038806370380020240024020030d00200641e0016a41186a200c280200360200200641e0016a41106a200b290300370300200641e0016a41086a2008290300370300200641c0016a41086a200d290300370300200641c0016a41106a201a290300370300200641c0016a41176a201b290000370000200641a0016a41086a201e290300370300200641a0016a41106a201d290300370300200641a0016a41176a201c290000370000200620062903e0023703e001200620062903c0023703c001200620062903a0023703a00120064180016a41176a202128000036000020064180016a41106a202029030037030020064180016a41086a201f290300370300200620062903800237038001200241ff01714102460d01200641e0006a41186a2203200641e0016a41186a280200360200200641e0006a41106a2208200641e0016a41106a290300370300200641e0006a41086a220b200641e0016a41086a290300370300200641c0006a41086a220c200641c0016a41086a290300370300200641c0006a41106a220d200641c0016a41106a290300370300200641c0006a41176a221a200641c0016a41176a290000370000200641206a41086a221b200641a0016a41086a290300370300200641206a41106a221c200641a0016a41106a290300370300200641206a41176a221d200641a0016a41176a290000370000200620062903e001370360200620062903c001370340200620062903a001370320200641176a221e20064180016a41176a280000360000200641106a221f20064180016a41106a290300370300200641086a222020064180016a41086a2903003703002006200629038001370300200641c0036a41086a2221200b290300370300200641c0036a41106a220b2008290300370300200641c0036a41186a22082003280200360200200620062903603703c00320064188076a41086a2203200c29030037030020064188076a41106a220c200d29030037030020064188076a41176a220d201a2900003700002006200629034037038807200641e0036a41086a221a201b290300370300200641e0036a41106a221b201c290300370300200641e0036a41176a221c201d290000370000200620062903203703e003200641a0036a41176a221d201e280000360000200641a0036a41106a221e201f290300370300200641a0036a41086a221f2020290300370300200620062903003703a003200641c0046a20043a0000200620023a00a004200620024118763a00a304200620024108763b00a104200641ac046a2021290300370200200641b4046a200b290300370200200641bc046a2008280200360200200620062903c0033702a404200641c1046a200629038807370000200641c9046a2003290300370000200641d1046a200c290300370000200641d8046a200d290000370000200641e0046a200a3a0000200641f8046a201c290000370000200641f1046a201b290300370000200641e9046a201a290300370000200641e1046a20062903e00337000020064180056a20093a000020064198056a201d28000036000020064191056a201e29030037000020064189056a201f29030037000020064181056a20062903a003370000200141286a200641a0046a10a9062106200041086a20053a00002000200636020420004100360200200724000f0b2000410136020020002002360204200724000f0b419c98c800411841b498c8001057000bca2304087f0c7e027f087e230022052106200541e0026b41607122052400024002400240024002400240024002400240024020022d00004101470d00200541f8006a200241196a290000370300200541f0006a200241116a290000370300200541e8006a200241096a290000370300200520022900013703602003280208220741017621022003280204210820032802002109024002402007410171450d0020082002490d06200220084f0d0820052009360288022005200236028c0220054191026a200920026a2d000041f001713a0000200541013a0090020c010b20082002490d06200541003a0090022005200236028c0220052009360288020b200541c0006a2001200541e0006a20054188026a10ae062005280244210220052802404101460d03200141c0006a220a28020022092009417f6a200141386a22072802002208200141346a220b2802006b716b4101470d022001413c6a108b01200b280200220b200728020022084d0d0220082009200b6b220c490d01200128023c2208200a280200200c6b22094102746a2008200b4102746a200c41027410e4071a200141346a2009360200200141386a28020021080c020b200241046a28020021020240200141c0006a220a28020022092009417f6a200141386a22072802002208200141346a220b2802006b716b4101470d002001413c6a108b01200b280200220b200728020022084d0d00024020082009200b6b220c490d00200128023c2208200a280200200c6b22094102746a2008200b4102746a200c41027410e4071a200141346a2009360200200141386a28020021080c010b200128023c220b20094102746a200b200841027410e4071a200141386a2208200828020020096a22083602000b2007200a280200417f6a200841016a713602002001413c6a28020020084102746a2002360200200141306a280200220820024d0d0620012802282108200541003a0060200541003602642008200241fc006c6a2202290200210d20022005290360370200200241186a2208290200210e20082005290378370200200241106a2208290200210f20082005290370370200200241086a2208290200211020082005290368370200200f422088200e4220868421112010422088200f422086842112200d4220882010422086842113200241e0006a2108200241c0006a2109200241206a2102200e4220882114200da72107200d420888a7210b0c080b200128023c220b20094102746a200b200841027410e4071a200141386a2208200828020020096a22083602000b2007200a280200417f6a200841016a713602002001413c6a28020020084102746a2002360200200141306a280200220820024d0d0520012802282108200541003a0060200541003602642008200241fc006c6a2202290200210d20022005290360370200200241186a2208290200210e20082005290378370200200241106a2208290200210f20082005290370370200200241086a2208290200211020082005290368370200200f422088200e4220868421112010422088200f422086842112200d4220882010422086842113200241e0006a2108200241c0006a2109200241206a2102200e4220882114200da72107200d420888a7210b0c060b2000410136020020002002360204200624000f0b2002200841f4a0cc00104b000b200220084184a1cc00104b000b200220084194a1cc001036000b20022008418095c8001036000b20022008418095c8001036000b200241186a290200210d200241106a290200210e200241086a290200210f200941186a290200211020022902002115200929020021162009290208211720092902102118200541206a41086a2202200841086a290200370300200541206a41106a2209200841106a290200370300200541206a41186a220a200841186a280200360200200520103703582005201837035020052017370348200520163703402005200829020037032002400240024002400240024002400240024002400240024002400240200741ff01714101470d0020032802002108200328020421192003280208211a200541bc026a2010370200200541b4026a201837020020054188026a41246a2017370200200541a4026a201637020020054188026a41186a200d4220883e0200200541c4026a200529032037020020054188026a41c4006a2002290300370200200541d4026a2009290300370200200541dc026a200a2802003602002005200e422088200d42208684370398022005200f422088200e422086843703900220052015422088200f4220868437038802200541e0006a200120054188026a2003200410b10620054182026a41026a220320054187016a2d00003a0000200541fe016a41026a2204200541a7016a2d00003a0000200520052f0085013b018202200520052f00a5013b01fe012005280264210220052802604101460d0720054180016a350200210d200541e0006a41186a290300210e200541e0006a41106a290300210f200541e0006a41086a2903002110200541a0016a350200211620054198016a290300211720054190016a290300211820054188016a290300211b200541b0016a290300211c200541a8016a290300211d200541b8016a290300211e200541e0006a41246a2d00002109200541e0006a41c4006a2d0000210c2015a7210a200541fa016a41026a20032d00003a0000200541f6016a41026a20042d00003a0000200520052f0182023b01fa01200520052f01fe013b01f60120020e03030201030b200541bc026a200d370200200541b4026a200e37020020054188026a41246a200f370200200541a4026a201537020020054188026a41186a20143e0200200541c4026a200529034037020020054188026a41c4006a2005290348370200200541d4026a2005290350370200200541dc026a2005280258360200200520113703980220052012370390022005201337038802200541e0006a200120054188026a2003200410b1064102210320054182026a41026a220820054187016a2d00003a0000200541fe016a41026a2204200541a7016a2d00003a0000200520052f0085013b018202200520052f00a5013b01fe012005280264210220052802604101460d0620054180016a350200210d200541e0006a41186a290300210e200541e0006a41106a290300210f200541e0006a41086a2903002110200541a0016a350200211620054198016a290300211720054190016a290300211820054188016a290300211b200541b0016a290300211f200541a8016a2903002120200541b8016a2903002121200541e0006a41246a2d00002109200541e0006a41c4006a2d00002119200541fa016a41026a20082d00003a0000200541f6016a41026a20042d00003a0000200520052f0182023b01fa01200520052f01fe013b01f6014100211a20020e03030405030b201a410176210202400240201a410171450d0020192002490d08200220194f0d01200820026a2d00004170712103410121090c0b0b024020192002490d00410021090c0b0b200220194184a1cc00104b000b200220194194a1cc001036000b200541ee016a41026a200541fa016a41026a2d00003a0000200541e0006a41026a200541f6016a41026a2d00003a0000200520052f01fa013b01ee01200520052f01f6013b0160410121034100211a201b21202018211f20172121201621152010211b200f2118200e2117200d2116201321102012210f2011210e2014210d20092119200a21090c090b201a410176210202400240201a410171450d0020192002490d07200220194f0d01200820026a2d000041707121044101211a0c080b024020192002490d004100211a0c080b200220194184a1cc00104b000b200220194194a1cc001036000b4101211a0b200541f2016a41026a200541fa016a41026a2d00003a0000200541ee016a41026a200541f6016a41026a2d00003a0000200520052f01fa013b01f201200520052f01f6013b01ee0142002115410021030b4200211e0c050b4200211e410121030c050b2002201941f4a0cc00104b000b2002201941f4a0cc00104b000b41002103200541003a006420054100360260200541e0006a2008200820026a10b00620054188026a41286a200541e0006a41286a2202280200220836020020054188026a41206a200541e0006a41206a290300221537030020054188026a41186a200541e0006a41186a290300221f37030020054188026a41106a200541e0006a41106a290300222037030020054188026a41086a200541e0006a41086a290300222137030020052005290360222237038802200541fb006a20143e0000200541f3006a2011370000200541eb006a20123700002002202137030020054190016a202037030020054198016a201f370300200541a0016a2015370300200541a8016a2008360200200541ad016a20043a0000200541ac016a201a3a0000200520133700632005200a3a007f20052022370380012005200b3b01602005200b4110763a0062200541ae016a20052f0186023b01002001200541e0006a10b104200541f2016a41026a200541fa016a41026a2d00003a0000200541ee016a41026a200541f6016a41026a2d00003a0000200520052f01fa013b01f201200520052f01f6013b01ee01420021154101211a201d2120201c211f201e2121200c21190c010b200541003a006420054100360260200541e0006a2008200820026a10b00620054188026a41286a200541e0006a41286a2202280200220836020020054188026a41206a200541e0006a41206a290300220d37030020054188026a41186a200541e0006a41186a290300220e37030020054188026a41106a200541e0006a41106a290300220f37030020054188026a41086a200541e0006a41086a290300221037030020052005290360221637038802200541fb006a20143e0000200541f3006a2011370000200541eb006a20123700002002201037030020054190016a200f37030020054198016a200e370300200541a0016a200d370300200541a8016a2008360200200541ad016a20033a0000200541ac016a20093a0000200520133700632005200a3a007f20052016370380012005200b3b01602005200b4110763a0062200541ae016a20052f01f2013b01002001200541e0006a10b104410221030b20054188026a41026a200541f2016a41026a2d00003a000020054182026a41026a200541ee016a41026a2d00003a0000200541fe016a41026a200541e0006a41026a2d00003a0000200520052f01f2013b018802200520052f01ee013b018202200520052f01603b01fe012003200741807e71722102410021030b410221082005411c6a41026a220720054188026a41026a22042d00003a0000200541186a41026a220a20054182026a41026a2d00003a0000200541146a41026a220b200541fe016a41026a2d00003a0000200520052f0188023b011c200520052f0182023b0118200520052f01fe013b0114024020030d00200541106a41026a220320072d00003a00002005410c6a41026a2207200a2d00003a0000200541086a41026a220a200b2d00003a0000200520052f011c220b3b0110200520052f01183b010c200520052f01143b0108200420032d00003a00002005200b3b018802200541c0006a41026a20072d00003a0000200520052f010c3b0140200541206a41026a200a2d00003a0000200520052f01083b01200240200241ff01714102460d00200541ec006a200f3702002005418c016a201837020020054184016a201b370200200541ac016a201f370200200541a4016a202037020020054180016a20093a000020054181016a20052f0188023b0000200541a0016a20193a0000200541a1016a20052f01403b0000200541c0016a200c3a0000200541c1016a20052f01203b0000200541f4006a200e37020020054194016a2017370200200541b4016a202137020020054183016a20054188026a41026a2d00003a0000200541a3016a200541c0006a41026a2d00003a0000200541c3016a200541206a41026a2d00003a0000200541fc006a200d3e02002005419c016a20163e0200200541bc016a20153e02002005201037026420052002360260200541cc016a201c370200200541c4016a201d370200200541d4016a201e370200201a4101712108200141286a200541e0006a10a90621030b200041086a20083a00002000200336020420004100360200200624000f0b2000410136020020002002360204200624000bf50403047f017e027f230041d0026b22042400200141c8006a280200210520012802442106200441d0016a41086a2207200341086a280200360200200420032902003703d001200441086a20062002200441d0016a200528020c1104000240024002400240200428020822030d002007200241086a290000370300200441d0016a41106a2201200241106a290000370300200441d0016a41186a2203200241186a290000370300200420022900003703d001413010272202450d01200241013a0000200220042903d0013700012002200429005c370021200241096a200441d8016a290300370000200241116a2001290300370000200241196a2003290300370000200241286a200441e3006a29000037000020004101360200200020023602040c030b200429020c2108200441b0016a41186a200241186a2209290000370300200441b0016a41106a200241106a220a290000370300200441b0016a41086a200241086a290000370300200420022900003703b001200441d0016a200441b0016a20032008422088a7200141286a220610b20620042802d401210120042802d0012105200441dc006a200741d40010e4071a20054101470d0120004101360200200020013602042008a7450d02200310290c020b1030000b200441086a200441dc006a41d40010e4071a200420013602f401200441d0016a41286a200441086a41d40010e4071a200441e9016a2009290000370000200441e1016a200a290000370000200441d9016a200241086a290000370000200441013a00d001200420022900003700d1012006200441d0016a10a906210220004100360200200020023602042008a7450d00200310290b200441d0026a24000b8e5903117f057e077f230022062107200641e0046b41607122062400200641086a200341086a2802003602002006200329020037030002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022802000e050104000203010b200641f0006a2002412c6a290200370300200641e8006a200241246a290200370300200641c8006a41186a2002411c6a290200370300200641c8006a41106a2208200241146a290200370300200641c8006a41086a2002410c6a2902003703002006200229020437034820064196016a200241376a2d00003a0000200641f8006a41086a200241c4006a290200370300200641f8006a41106a200241cc006a290200370300200641f8006a41186a200241d4006a280200360200200620022f00353b01940120062002413c6a290200370378200241346a2d00002109200241386a280200210a02400240200628024c220b41244b0d00200641d1006a210c0c010b2008280200210b200641c8006a410c6a280200210c0b20062006280248220d3602a0012006200c360298012006280204210e2006280208210f2006200b36029c01200b4101742210200d6b2211200e410174200f6b2202200220114b1b2212450d0541002102200628020021130340200f20026a22084101762214200e4f0d07200d20026a22154101762216200b4f0d08201320146a2d00002214410f71201441f0017141047620084101711b200c20166a2d00002208410f71200841047620154101711b470d05200241016a22022012490d000c1f0b0b4101211520062802042203200628020822144101762216490d072006280200210241002108200641003a00e403200641003602e003200641e0036a200220166a200220036a10b006200641286a41086a200641f4036a290200370300200641386a200641fc036a290200370300200641c0006a20064184046a2902003703002006200641ec036a29020037032820144101712102200641e0036a41086a280200211420062802e403211620062802e003210320042902042117200428020021110c210b200241106a280200210d2002410c6a280200210c200241086a280200210b20022802042102024002402006280204221441017420062802082208460d00200841017622152014490d012015201441b4a0cc001036000b02400240200b0d002004280208211420042802002103410021080c010b2004280200210341002108200d20042802082214470d00024002402003200b470d00410121080c010b200b2003200d10e7074521080b200d21140b20042802042116024020052802002215450d00200541046a280200450d00201510290b2005200c3602042005200b360200200541086a200d360200200641286a41086a200641e0036a41086a290200370300200641286a41106a200641e0036a41106a290200370300200641286a41186a200641e0036a41186a290200370300200641106a41086a20064188036a41086a290200370300200641106a41106a20064188036a41106a280200360200200620062902e0033703282006200629028803370310410321150c210b200628020020156a2d000021142003200328020841016a36020820022014410f71201441047620084101711b221541246c6a22142902102118201420062903f00337021020142902082119201420062903e80337020820142902002117200641023a00e003201420062903e003370200201441186a2208290200211a200820062903f80337020002400240024002402017a741ff01714102470d002003280204221620032802082205410176220e490d0b2003280200210341002108200641003a008c03200641003602880320064188036a2003200e6a200320166a10b006200641b0026a41286a20064188036a41286a2802002203360200200641b0026a41206a20064188036a41206a2903002217370300200641b0026a41186a20064188036a41186a2903002218370300200641b0026a41106a20064188036a41106a2903002219370300200641b0026a41086a20064188036a41086a290300221a370300200641ec036a200629038803221b370200200641f4036a201a370200200641fc036a2019370200200641e0036a41246a20183702002006418c046a201737020020064194046a2003360200200641013602e403200641e0036a41086a20054101713602002006201b3703b002200641a0046a200441086a28020036020020064198046a2004290200370300200641003a00e0032002201541246c6a41046a200141286a200641e0036a10a906360200201441003a00000c010b20064180046a2014280220360200200641e0036a41186a201a370300200620193703e803200620173703e003200620183703f00320064188036a41086a200441086a2802003602002006200429020037038803200641b0026a2001200641e0036a200320064188036a200510ac0620062802b402210320062802b0024101460d01200641b0026a41086a2d0000211641002108201441003a00002002201541246c6a41046a2003360200201641ff0171450d020b41032115200b2103200c2116200d21140c220b20004101360200200020033602040240200b450d00200c450d00200b10290b200210290c1f0b2000428080808010370200200041186a200d360200200041146a200c360200200041106a200b3602002000410c6a2002360200200041086a4103360200200724000f0b200641d8026a2002412c6a290200370300200641d0026a200241246a290200370300200641c8026a2002411c6a290200370300200641c0026a2208200241146a290200370300200641b0026a41086a2002410c6a290200370300200620022902043703b002200241346a2802002111200241386a28020021092002413c6a280200211c200241c0006a280200211d0240024020062802b402220b41244b0d00200641b9026a210d0c010b2008280200210b200641b0026a410c6a280200210d0b200620062802b002220c3602a0012006200d360298012006280204210e2006280208210f2006200b36029c01410021020240200b410174200c6b220a200e410174200f6b22102010200a4b1b2212450d00200628020021130340200f20026a22084101762214200e4f0d09200c20026a22154101762216200b4f0d0a201320146a2d00002214410f71201441f0017141047620084101711b200d20166a2d00002208410f71200841047620154101711b470d01200241016a22022012490d000b0b02400240024002402002200a470d00200a2010460d010b2002200a490d01200f20026a22144101762208200e490d022008200e41b4a0cc001036000b4100210802402009450d00201d2004280208470d000240200428020022022009470d00410121080c010b20092002201d10e7074521080b200b200c4101762202490d0b200641003a00e403200641003602e003200641e0036a200d20026a200d200b6a10b00620064188036a41086a2215200641f4036a29020037030020064188036a41106a220d200641fc036a29020037030020064188036a41186a220e20064184046a2902003703002006200641ec036a29020037038803200c4101712102200641e0036a41086a220c280200211420062802e403211620062802e00321032004280208210b20042902002117024020052802002204450d00200541046a280200450d00200410290b2005201c36020420052009360200200541086a201d360200200641286a41086a2015290300370300200641286a41106a200d290300370300200641286a41186a200e290300370300200641106a41086a200c290200370300200641106a41106a200641e0036a41106a2802003602002006200629038803370328200620062902e0033703100c1b0b200b200c200241016a22136a22084101762203490d0b200641003a00e403200641003602e003200641e0036a200d20036a200d200b6a10b006200641a8016a41286a200641e0036a41286a2802002203360200200641a8016a41206a200641e0036a41206a2903002217370300200641a8016a41186a200641e0036a41186a2903002218370300200641a8016a41106a200641e0036a41106a2903002219370300200641a8016a41086a200641e0036a41086a2214290300221a370300200620062903e003221b3703a801200641c8006a41086a2216201a370300200641c8006a41106a22052019370300200641c8006a41186a220e2018370300200641c8006a41206a220f2017370300200641c8006a41286a221220033602002006201b370348200c20026a220c4101762203200b4f0d0c200d20036a2d0000210310b606211520142008410171360200200641ec036a22142006290348370200200641f4036a2016290300370200200641fc036a2005290300370200200641e0036a41246a200e2903003702002006418c046a200f29030037020020064194046a2012280200360200200641a4046a201d360200200641a0046a201c3602002006419c046a200936020020064198046a2011360200200641043602e403200641a8046a2006290278370300200641b0046a200641f8006a41086a290200370300200641b8046a200641f8006a41106a280200360200200641003a00e00320152003410f712003410476200c4101711b41246c6a2203200141286a2216200641e0036a10a906360204200341003a00000240024020062802042203410174200628020822086b2002460d00200820026a220e410176220b2003490d01200b200341b4a0cc001036000b200641e0036a20064198016a200210b706200641286a41086a200641e0036a41186a290300370300200641286a41106a20064180046a290300370300200641286a41186a20064188046a2903003703002006200641e0036a41106a29030037032820142802002114200641e0036a41086a28020021162004280208210b2004290200211720062802e403210320062802e003210241002108201521110c1b0b2003200820136a220f410176220d490d0d20062802002214200b6a2d0000210b41002108200641003a00e403200641003602e003200641e0036a2014200d6a201420036a10b006200641d8016a41286a200641e0036a41286a22032802002212360200200641d8016a41206a200641e0036a41206a2214290300221737030020064188036a410c6a200641e0036a41086a220d2903003702002006419c036a200641e0036a41106a220c290300370200200641a4036a200641e0036a41186a220529030037020020064188036a41246a2017370200200641b4036a2012360200200620062903e00322173703d8012006200f410171360288032006201737028c03200d20062902880337030020064198046a2004290200370300200641a0046a200441086a280200360200200641013602e403200c20064188036a41086a290200370300200520064188036a41106a290200370300201420064188036a41186a290200370300200320064188036a41206a29020037030020064190046a20064188036a41286a290200370300200641003a00e0032015200b410f71200b41f00171410476200e4101711b41246c6a22042016200641e0036a10a906360204200441003a0000200641e0036a20064198016a200210b706200641286a41086a2005290300370300200641286a41106a2014290300370300200641286a41186a20032903003703002006200c290300370328200641e0036a410c6a2802002114200d280200211620062802e403210320062802e003210242002117201521110c1a0b200628020020086a2d000021082003200220032802086a41016a36020820112008410f71200841047620144101711b221441246c6a22022902102118200220062903f00337021020022902082119200220062903e80337020820022902002117200641023a00e003200220062903e003370200200241186a2208290200211a200820062903f80337020002402017a741ff01714102470d0020032802042208200328020822154101762216490d0e20032802002103200641003a008c03200641003602880320064188036a200320166a200320086a10b006200641d8016a41286a20064188036a41286a2802002203360200200641d8016a41206a20064188036a41206a2903002217370300200641d8016a41186a20064188036a41186a2903002218370300200641d8016a41106a20064188036a41106a2903002219370300200641d8016a41086a20064188036a41086a290300221a370300200641ec036a200629038803221b370200200641f4036a201a370200200641fc036a2019370200200641e0036a41246a20183702002006418c046a201737020020064194046a2003360200200641013602e403200641e0036a41086a20154101713602002006201b3703d801200641a0046a200441086a28020036020020064198046a2004290200370300200641003a00e0032011201441246c6a41046a200141286a200641e0036a10a906360200200241003a00000c190b20064180046a2002280220360200200641e0036a41186a201a370300200620193703e803200620173703e003200620183703f00320064188036a41086a200441086a2802003602002006200429020037038803200641d8016a2001200641e0036a200320064188036a200510ac0620062802dc0121030240024020062802d8014101460d00200641d8016a41086a2d00002108200241003a00002011201441246c6a41046a2003360200200841ff01710d1a200b200c4101762202490d10200641003a00e403200641003602e003200641e0036a200d20026a200d200b6a10b00620064188036a41286a200641e0036a41286a280200220236020020064188036a41206a200641e0036a41206a290300221737030020064188036a41186a200641e0036a41186a290300221837030020064188036a41106a200641e0036a41106a290300221937030020064188036a41086a200641e0036a41086a290300221a370300200620062903e003221b370388032000410c6a200c410171360200200041086a41043602002000428080808010370200200041106a201b370200200041186a201a370200200041206a2019370200200041286a2018370200200041306a2017370200200041386a2002360200200041c8006a201d360200200041c4006a201c360200200041c0006a20093602002000413c6a20113602000c010b200041013602002000200336020402402009450d00201c450d00200910290b201110290b20062802b40241244d0d1d200641bc026a2802001029200724000f0b200641d8026a2002412c6a290200370300200641d0026a200241246a290200370300200641c8026a2002411c6a290200370300200641c0026a2208200241146a290200370300200641b0026a41086a2002410c6a290200370300200620022902043703b0022002413c6a2802002109200241386a280200211d200241346a28020021100240024020062802b402220b41244b0d00200641b9026a210d0c010b2008280200210b200641b0026a410c6a280200210d0b410021020240200b41017420062802b002220c6b22112006280204220e4101742006280208220f6b220a200a20114b1b2212450d00200628020021130340200f20026a22084101762214200e4f0d10200c20026a22154101762216200b4f0d11201320146a2d00002214410f71201441f0017141047620084101711b200d20166a2d00002208410f71200841047620154101711b470d01200241016a22022012490d000b0b02400240024002400240024020022011470d002011200a460d010b200220114f0d0210b6062114200c20026a22154101762208200b4f0d15200b201541016a220f410176220c490d16200d20086a2d0000211641002108200641003a00e403200641003602e003200641e0036a200d200c6a200d200b6a10b00620064188036a41286a200641e0036a41286a2212280200221336020020064188036a41206a200641e0036a41206a2211290300221737030020064188036a41186a200641e0036a41186a220b290300221837030020064188036a41106a220a200641e0036a41106a220d290300221937030020064188036a41086a221c200641e0036a41086a220c290300221a370300200620062903e003221b37038803200641ec036a220e201b370200200641e0036a41146a221e201a370200200641e0036a411c6a221f2019370200200641e0036a41246a22202018370200200641e0036a412c6a22212017370200200641e0036a41346a22222013360200200641a0046a221320093602002006419c046a2209201d360200200641e0036a41386a2010360200200641013602e403200c200f410171360200200641003a00e00320142016410f71201641047620154101711b41246c6a2215200141286a200641e0036a10a906360204201541003a0000200641e0036a2006200210b70620064198016a41086a2202200e280200360200200641c8006a41086a2215200b290300370300200641c8006a41106a22162011290300370300200641c8006a41186a220f2012290300370300200620062902e403370398012006200d290300370348200620062802e00336028c032006410436028803201c200629039801370300200a200228020036020020064188036a41386a410036020020064188036a41346a201436020020064188036a41146a200629034837020020064188036a411c6a201529030037020020064188036a41246a201629030037020020064188036a412c6a200f290300370200200641cc036a200629027837020020064188036a41cc006a200641f8006a41086a29020037020020064188036a41d4006a200641f8006a41106a280200360200200641286a41086a220f200441086a28020036020020062004290200370328200641e0036a200120064188036a2003200641286a200510af06200641d8016a41086a22052020290200370300200641d8016a41106a22122021290200370300200641d8016a41186a220120222902003703002006201f2902003703d801200c2802002115200e2802002102200d2802002103201e2802002116200b28020021142009280200211120132903002117200641a8046a280200210b20062802e403210d20062802e0032104200641a8016a41106a220c200641bc046a280200360200200641a8016a41086a220e200641e0036a41d4006a2902003703002006200641e0036a41cc006a2902003703a80120044101460d01200641286a41186a2001290300370300200641286a41106a2012290300370300200f2005290300370300200641106a41086a200e290300370300200641106a41106a200c280200360200200620062903d801370328200620062903a8013703100c040b41002102024020092004280208470d000240201020042802002202470d00410121020c010b20102002200910e7074521020b024020052802002203450d00200541046a280200450d00200310290b2005201d36020420052010360200200541086a200936020020020d02200641e0036a200641b0026a10b806200641286a41086a200641e0036a41186a290300370300200641286a41106a20064180046a290300370300200641286a41186a20064188046a2903003703002006200641e0036a41106a290300370328200641ec036a2802002114200641e0036a41086a2802002116200429020421172004280200211120062802e403210320062802e003210241002108410121150c030b200041013602002000200d3602040c190b200b200c4101762202490d1441002108200641003a00e403200641003602e003200641e0036a200d20026a200d200b6a10b006200641d8016a41286a2202200641e0036a41286a280200360200200641d8016a41206a2214200641e0036a41206a290300370300200641d8016a41186a2215200641e0036a41186a220b290300370300200641d8016a41106a2216200641e0036a41106a220d290300370300200641d8016a41086a220e200641e0036a41086a220f290300370300200620062903e0033703d80110b606211220064188036a41086a20062903d80137030020064188036a41106a200e29030037030020064188036a41186a201629030037030020064188036a41206a201529030037030020064188036a41286a2014290300370300200641b8036a200228020036020020064188036a41c0006a200936020020064188036a413c6a201d360200200641c0036a201036020020064188036a41346a20123602002006200c41017136028c032006410436028803200641286a41086a220c200441086a28020036020020062004290200370328200641e0036a200120064188036a2003200641286a200510af06200641c8006a41086a220520064184046a290200370300200641c8006a41106a220e2006418c046a290200370300200641c8006a41186a2212200641e0036a41346a2902003703002006200641fc036a290200370348200f2802002115200641ec036a2802002102200d2802002103200641f4036a2802002116200b2802002114200641e0036a413c6a2802002111200641e0036a41c0006a2903002117200641a8046a280200210b20062802e403210d20062802e0032104200641a8016a41106a220f200641bc046a280200360200200641a8016a41086a2213200641b4046a2902003703002006200641ac046a2902003703a801024020044101460d00200641286a41186a2012290300370300200641286a41106a200e290300370300200c2005290300370300200641106a41086a2013290300370300200641106a41106a200f28020036020020062006290348370328200620062903a8013703100c020b200041013602002000200d3602040c180b200641e0036a200641b0026a10b806200641286a41086a200641e0036a41186a290300370300200641286a41106a20064180046a290300370300200641286a41186a20064188046a2903003703002006200641e0036a41106a290300370328200641ec036a2802002114200641e0036a41086a2802002116200429020421172004280200211120062802e403210320062802e003210241012115410121080b20062802b40241244d0d1e200641bc026a28020010290c1e0b20020d190b2010200d460d12200d4101762202200b4f0d11200c20026a2d0000210210b60621140240024020114101460d00200b200d41016a22154101762216490d1541002108200641003a00e403200641003602e003200641e0036a200c20166a200c200b6a10b00620064188036a41286a200641e0036a41286a280200221636020020064188036a41206a200641e0036a41206a290300221737030020064188036a41186a200641e0036a41186a290300221837030020064188036a41106a200641e0036a41106a290300221937030020064188036a41086a200641e0036a41086a220b290300221a370300200620062903e003221b37038803200b2015410171360200200641ec036a201b370200200641f4036a201a370200200641fc036a201937020020064184046a20183702002006418c046a201737020020064194046a201636020020064198046a20093a0000200641023602e40320064199046a20062f0194013b00002006419b046a20064194016a41026a2d00003a00002006419c046a200a360200200641b8046a200641f8006a41186a280200360200200641b0046a200641f8006a41106a290300370300200641a8046a200641f8006a41086a290300370300200641a0046a2006290378370300200641003a00e003200141286a200641e0036a10a906210a0c010b20064188036a41026a20064194016a41026a2d00003a0000200641e0036a41086a200641f8006a41086a290300370300200641e0036a41106a200641f8006a41106a290300370300200641e0036a41186a200641f8006a41186a280200360200200620062f0194013b018803200620062903783703e003200921080b20142002410f712002410476200d4101711b41246c6a220220083a0000200220062f0188033b00012002200a360204200220062903e003370208200241036a2006418a036a2d00003a0000200241106a200641e0036a41086a2215290300370200200241186a200641e0036a41106a2216290300370200200241206a200641e0036a41186a220b2802003602004100210820064188036a41086a41003602002006201436028c032006410336028803200641a8016a41086a200441086a280200360200200620042902003703a801200641e0036a200120064188036a2003200641a8016a200510af06200641b0026a41086a220d200641e0036a41246a290200370300200641b0026a41106a220c2006418c046a290200370300200641b0026a41186a220520064194046a2902003703002006200641fc036a2902003703b00220152802002115200641ec036a280200210220162802002103200641f4036a2802002116200b28020021142006419c046a2802002111200641a0046a2903002117200641a8046a280200210b20062802e403210e20062802e0032104200641d8016a41106a220f200641bc046a280200360200200641d8016a41086a2212200641b4046a2902003703002006200641ac046a2902003703d801024020044101460d00200641286a41186a2005290300370300200641286a41106a200c290300370300200641286a41086a200d290300370300200641106a41086a2012290300370300200641106a41106a200f280200360200200620062903b002370328200620062903d8013703100c1c0b200041013602002000200e3602040c190b2014200e41b4a0cc001036000b2016200b41b4a0cc001036000b2016200341c4a0cc00104c000b200e201641c4a0cc00104c000b2014200e41b4a0cc001036000b2016200b41b4a0cc001036000b2002200b41c4a0cc00104c000b2003200b41c4a0cc00104c000b2003200b41b4a0cc001036000b200d200341c4a0cc00104c000b2016200841c4a0cc00104c000b2002200b41c4a0cc00104c000b2014200e41b4a0cc001036000b2016200b41b4a0cc001036000b2008200b41b4a0cc001036000b200c200b41c4a0cc00104c000b2002200b41c4a0cc00104c000b2002200b41b4a0cc001036000b41c498c800412a41b8a1cc001033000b2016200b41c4a0cc00104c000b20062802b40241244d0d05200641bc026a2802001029200724000f0b200b200c4101762202490d0141002108200641003a00e403200641003602e003200641e0036a200d20026a200d200b6a10b006200641286a41086a200641f4036a290200370300200641386a200641fc036a290200370300200641c0006a20064184046a2902003703002006200641ec036a290200370328200c4101712102201cad4220862009ad842117200641e0036a41086a280200211420062802e403211620062802e0032103201d210b0b024020062802b40241244d0d00200641bc026a28020010290b410421150c050b2002200b41c4a0cc00104c000b024002400240024020022011460d00200b200d20026a22084101762214490d0241002111200641003a00e403200641003602e003200641e0036a200c20146a200c200b6a10b006200641a8016a41286a2214200641e0036a41286a280200360200200641a8016a41206a2216200641e0036a41206a290300370300200641a8016a41186a220b200641e0036a41186a290300370300200641a8016a41106a220d200641e0036a41106a290300370300200641a8016a41086a220c200641e0036a41086a220e290300370300200620062903e0033703a8012003200328020820026a360208200641bc036a20093a00002006200841017136028c0341022115200641023602880320064188036a41086a220820062903a80137030020064188036a41106a220f200c29030037030020064188036a41186a220c200d29030037030020064188036a41206a220d200b29030037030020064188036a41286a220b2016290300370300200641b8036a2014280200360200200641bf036a20064194016a41026a2d00003a0000200620062f0194013b00bd03200641c0036a200a360200200641dc036a200641f8006a41186a280200360200200641d4036a200641f8006a41106a290300370200200641cc036a200641f8006a41086a290300370200200641c4036a2006290378370200200641286a41086a2214200441086a28020036020020062004290200370328200641e0036a200120064188036a2003200641286a200510af0620062802e403211620062802e0032103200641b0026a200e41d80010e4071a20034101460d01200641d8016a200641b0026a41d80010e4071a20064188036a20064198016a200210b706200641e0036a410472200641d8016a41d80010e4071a200641003a00e003200141286a200641e0036a10a90621022014200c290300370300200641286a41106a200d290300370300200641286a41186a200b2903003703002006200f2903003703282002ad21172008280200211620064194036a28020021142006280288032102200628028c032103410021080c060b2003200328020820116a360208200641e0036a41086a2006290378370300200641e0036a41106a200641f8006a41086a290300370300200641e0036a41186a200641f8006a41106a29030037030020064180046a200641f8006a41186a280200360200200620093a00e003200620062f0194013b00e103200620064196016a2d00003a00e3032006200a3602e40320064188036a41086a200441086a2802003602002006200429020037038803200641b0026a2001200641e0036a200320064188036a200510ac0620062802b4022115024020062802b0024101460d00200b200d4101762202490d03200641b0026a41086a2d0000210341002111200641003a00e403200641003602e003200641e0036a200c20026a200c200b6a10b006200641286a41086a200641f4036a290200370300200641386a200641fc036a290200370300200641c0006a20064184046a2902003703002006200641ec036a290200370328200d4101712102200341ff0171452108200641e0036a41086a280200211420062802e403211620062802e00321032015ad2117410221150c060b20004101360200200020153602040c030b20004101360200200020163602040c020b2014200b41c4a0cc00104c000b2002200b41c4a0cc00104c000b200628024c41244d0d00200641d4006a2802001029200724000f0b200724000f0b200628024c41244d0d00200641d4006a28020010290b20002008360204200041186a2014360200200041146a2016360200200041106a20033602002000410c6a2002360200200041086a20153602002000411c6a2006290328370200200041c8006a200b360200200041c0006a20173702002000413c6a2011360200200041cc006a2006290310370200200041246a200641286a41086a2903003702002000412c6a200641286a41106a290300370200200041346a200641286a41186a290300370200200041d4006a200641106a41086a290300370200200041dc006a200641106a41106a28020036020020004100360200200724000baf0301077f230041106b2203240020032000200220016b10d207024002400240024020032802004101470d00200341086a2802000d0141a4a1cc00411141b8a1cc001033000b41242104024002402000280200220541244b0d00200041056a210620052107200021080c010b2000410c6a22082802002107200041086a2802002106200521040b0240200720044f0d00034020022001460d03200620076a20012d00003a0000200141016a2101200741016a22072004490d000b0b2008200736020020012002460d02200141016a2107200041056a21092000410c6a210820012d000021060340024002402000280200220441244b0d0041242105200421010c010b20082802002101200421050b024020012005470d0020032000410110d207024020032802004101470d00200341086a2802000d0341a4a1cc00411141b8a1cc001033000b200028020021040b02400240200441244b0d0020092104200021050c010b20002802082104200821050b2005200141016a360200200420016a20063a000020022007460d0320072d00002106200741016a21070c000b0b1030000b200820073602000b200341106a24000bdd37070b7f017e027f017e057f037e017f230022052106200541e0036b41607122052400200328020821072003280200210820032802042109200541d8006a41086a220a2002411c6a290200370300200541d8006a41106a220b200241246a290200370300200541d8006a41186a220c2002412c6a290200370300200541c0006a41086a220d200241cc006a290200370300200541c0006a41106a220e200241d4006a2802003602002005200241146a2902003703582005200241c4006a2902003703402009410174210f2002413c6a2902002110200241386a2802002111200241346a28020021122002410c6a2902002113200241086a280200211420022802042115410221160240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022802000e051d070001021d0b200541f8006a41086a2013370300200541f8006a41106a22172005290358370300200541f8006a41186a200a29030037030020054198016a200b290300370300200541a0016a200c290300370300200520153602782005201436027c200541a8016a41106a200e280200360200200541a8016a41086a200d290300370300200520052903403703a80102400240201441244b0d0020054181016a210c2014210b0c010b2013422088a7210c200528028801210b0b410021020240200f20076b2218200b41017420156b220e200e20184b1b220d450d000340201520026a22184101762216200b4f0d0f200720026a220f410176220a20094f0d10200c20166a2d00002216410f71201641f0017141047620184101711b2008200a6a2d00002218410f712018410476200f4101711b470d01200241016a2202200d490d000b0b2002200e460d07200541206a41186a201741186a290200370300200541206a41106a201741106a290200370300200541206a41086a201741086a290200370300200541086a41086a200541a8016a41086a290300370300200541086a41106a200541a8016a41106a280200360200200520052903a8013703082005201729020037032041022118410121160c1c0b200f2007470d0320140d014101211641032118410021140c1b0b200f2007470d0320110d01200541206a41186a200541d8006a41186a290300370300200541206a41106a200541d8006a41106a290300370300200541206a41086a200541d8006a41086a290300370300200520052903583703204101211641042118410021110c1a0b024020042802002202450d00200441046a280200450d00200210290b20042013370204200420143602004100211620054188036a41086a41003602002005201536028c032005410336028803200541206a41086a2202200341086a28020036020020052003290200370320200541a0026a200120054188036a200541206a10b306200541f8006a41086a2207200541c0026a290300370300200541f8006a41106a2209200541c8026a290300370300200541f8006a41186a2208200541d0026a29030037030020054180026a41086a2203200541f0026a29030037030020054180026a41106a220f200541f8026a2802003602002005200541a0026a41186a2903003703782005200541e8026a2903003703800220052802a4022118024020052802a0024101460d00200541a0026a41086a2802002115200541ac026a2802002114200541a0026a41106a2903002113200541d8026a2802002112200541dc026a2802002111200541e0026a2903002110200541206a41186a2008290300370300200541206a41106a200929030037030020022007290300370300200541086a41086a2003290300370300200541086a41106a200f2802003602002005200529037837032020052005290380023703080c1a0b200041013602000c1a0b20054180026a41186a2202200541d8006a41186a29030037030020054180026a41106a2207200541d8006a41106a29030037030020054180026a41086a2209200541d8006a41086a2903003703002005200529035837038002024020042802002208450d00200441046a280200450d00200810290b200420103702042004201136020020054188036a410c6a201337020020054188036a41086a20143602002005419c036a200529038002370200200541a4036a2009290300370200200541ac036a2007290300370200200541b4036a20022903003702004100211620054188036a41386a4100360200200541bc036a20123602002005201536028c032005410436028803200541206a41086a200341086a28020036020020052003290200370320200541a0026a200120054188036a200541206a10b306200541f8006a41086a200541c0026a290300370300200541f8006a41106a200541c8026a290300370300200541f8006a41186a200541d0026a290300370300200541e8016a41086a200541f0026a290300370300200541e8016a41106a200541f8026a2802003602002005200541a0026a41186a2903003703782005200541e8026a2903003703e80120052802a4022118024020052802a0024101460d00200541a0026a41086a2802002115200541a0026a410c6a2802002114200541a0026a41106a2903002113200541a0026a41386a2802002112200541dc026a2802002111200541e0026a2903002110200541206a41186a200541f8006a41186a290300370300200541206a41106a200541f8006a41106a290300370300200541206a41086a200541f8006a41086a290300370300200541086a41086a200541e8016a41086a290300370300200541086a41106a200541e8016a41106a28020036020020052005290378370320200520052903e8013703080c190b200041013602000c190b410121162007410176220220094f0d0a2015200820026a2d00002202410f71200241047620074101711b220941246c6a22022902102119200220052903b0023702102002290208211a200220052903a80237020820022902002110200541023a00a002200220052903a002370200200241186a2207290200211b200720052903b8023702004103211802402010a741ff01714102470d000c180b20022802202107200541e8016a41086a200341086a220828020022163602002008201641016a360200200520032902003703e801200541a0026a41186a201b370300200541c0026a2007360200200520193703b0022005201a3703a802200520103703a00220054188036a2001200541a0026a2003200410ad06200528028c0321070240024002402005280288034101460d0020054188036a41086a2d0000220841ff01714102470d0120054188036a410c6a201337020020054188036a41086a20143602002005201536028c032005410336028803200541206a41086a2202200541e8016a41086a280200360200200520052903e801370320200541a0026a200120054188036a200541206a10b306200541f8006a41086a2207200541c0026a290300370300200541f8006a41106a2209200541c8026a290300370300200541f8006a41186a2208200541d0026a29030037030020054180026a41086a2203200541f0026a29030037030020054180026a41106a2216200541f8026a2802003602002005200541a0026a41186a2903003703782005200541e8026a2903003703800220052802a402211820052802a0024101460d02200541a0026a41086a2802002115200541a0026a410c6a2802002114200541a0026a41106a2903002113200541d8026a2802002112200541dc026a2802002111200541e0026a2903002110200541206a41186a2008290300370300200541206a41106a200929030037030020022007290300370300200541086a41086a2003290300370300200541086a41106a20162802003602002005200529037837032020052005290380023703080c060b200041013602002000200736020402402014450d002013a7450d00201410290b20151029200624000f0b200241003a00002015200941246c6a41046a20073602002008417f7341017121160c180b200041013602000c180b200541f8006a41086a2013370300200541f8006a41106a22172005290358370300200541f8006a41186a200541d8006a41086a29030037030020054198016a200541d8006a41106a290300370300200541a0016a200541d8006a41186a290300370300200520153602782005201436027c02400240201441244b0d0020054181016a210c2014210b0c010b2013422088a7210c200528028801210b0b410021020240200f20076b221c200b41017420156b220e200e201c4b1b220d450d000340201520026a22184101762216200b4f0d0c200720026a220f410176220a20094f0d0d200c20166a2d00002216410f71201641f0017141047620184101711b2008200a6a2d00002218410f712018410476200f4101711b470d01200241016a2202200d490d000b0b0240024002402002200e470d00200e201c460d010b2002200e4f0d01200541206a41186a201741186a290200370300200541206a41106a201741106a290200370300200541206a41086a201741086a2902003703002005201729020037032041042118410121160c180b2011450d06024020042802002202450d00200441046a280200450d00200210290b2004201037020420042011360200200541b4036a200541f8006a41286a290300370200200541ac036a200541f8006a41206a290300370200200541a4036a200541f8006a41186a2903003702002005419c036a200541f8006a41106a29030037020020054188036a410c6a200541f8006a41086a2903003702004100211620054188036a41386a4100360200200541bc036a20123602002005200529037837028c03200541043602880320054180026a41086a2202200341086a2802003602002005200329020037038002200541a0026a200120054188036a20054180026a10b30620054188036a41086a2209200541a0026a41206a29030037030020054188036a41106a2208200541a0026a41286a29030037030020054188036a41186a2203200541d0026a2903003703002005200541a0026a41186a29030037038803200541a0026a41086a2802002115200541a0026a410c6a2802002114200541a0026a41106a2903002113200541a0026a41386a2802002112200541dc026a2802002111200541e0026a290300211020052802a402211820052802a00221072002200541f0026a29030037030020054180026a41106a220f200541f8026a2802003602002005200541e8026a2903003703800220074101460d04200541206a41186a2003290300370300200541206a41106a2008290300370300200541206a41086a2009290300370300200541086a41086a2002290300370300200541086a41106a200f280200360200200520052903880337032020052005290380023703080c170b200720026a2215410176220720094f0d0f410421182012200820076a2d00002207410f71200741047620154101711b220941246c6a22152902102119201520052903b0023702102015290208211a201520052903a80237020820152902002113200541023a00a002201520052903a002370200201541186a2207290200211b200720052903b80237020002402013a741ff01714102470d00200541206a41086a201741086a290200370300200541206a41106a201741106a290200370300200541206a41186a201741186a29020037030020052017290200370320410121160c160b20152802202107200541d0016a41086a200341086a220828020022183602002008200220186a41016a360200200520032902003703d001200541a0026a41186a201b370300200541c0026a2007360200200520193703b0022005201a3703a802200520133703a00220054188036a2001200541a0026a2003200410ad06200528028c0321022005280288034101460d040240024020054188036a41086a2d0000220741ff01714102470d00200541b4036a200541f8006a41286a290300370200200541ac036a200541f8006a41206a290300370200200541a4036a200541f8006a41186a2903003702002005419c036a200541f8006a41106a29030037020020054188036a410c6a200541f8006a41086a29030037020020054188036a413c6a201037020020054188036a41386a2011360200200541bc036a20123602002005200529037837028c032005410436028803200541206a41086a2202200541d0016a41086a280200360200200520052903d001370320200541a0026a200120054188036a200541206a10b30620054180026a41086a2207200541a0026a41206a29030037030020054180026a41106a2209200541a0026a41286a29030037030020054180026a41186a2208200541d0026a290300370300200541e8016a41086a2203200541f0026a290300370300200541e8016a41106a2216200541f8026a2802003602002005200541a0026a41186a290300370380022005200541e8026a2903003703e80120052802a402211820052802a0024101470d01200041013602000c190b201541003a0000410421182012200941246c6a41046a2002360200200541206a41086a201741086a290200370300200541206a41106a201741106a290200370300200541206a41186a201741186a290200370300200520172902003703202007417f7341017121160c160b200541a0026a41086a2802002115200541a0026a410c6a2802002114200541a0026a41106a2903002113200541a0026a41386a2802002112200541a0026a413c6a2802002111200541e0026a2903002110200541206a41186a2008290300370300200541206a41106a200929030037030020022007290300370300200541086a41086a2003290300370300200541086a41106a20162802003602002005200529038002370320200520052903e8013703080c020b200541a0026a41086a2013370300200541a0026a41106a22012005290358370300200541a0026a41186a200a290300370300200541c0026a200b290300370300200541c8026a200c290300370300200520153602a002200520143602a40202400240201441244b0d00200541a9026a210d2014210b0c010b2013422088a7210d20052802b002210b0b200b41017420156b200f20076b220c470d1241002102200c450d110340201520026a22034101762218200b4f0d0c200720026a220f410176220a20094f0d0d200d20186a2d00002218410f71201841f0017141047620034101711b2008200a6a2d00002203410f712003410476200f4101711b470d12200c200241016a2202470d000c140b0b200541c0016a41086a200341086a220228020036020020022007200e6a360200200520032902003703c001200541a0026a41086a2010370300200541a0026a41106a20052903a801370300200541b8026a200541a8016a41086a290300370300200541c0026a200541a8016a41106a280200360200200520113602a402200520123602a00220054188036a2001200541a0026a2003200410ad06200528028c032111024002402005280288034101460d0020054188036a41086a2d0000220241ff01714102470d01200528027c41244b0d06410221160c160b2000410136020020002011360204200528027c41244d0d1720054184016a2802001029200624000f0b41012116024020024101710d00200541206a41086a201741086a290200370300200541206a41106a201741106a290200370300200541206a41186a201741186a290200370300200541086a41086a200541d0016a41086a290200370300200541086a41106a200541d0016a41106a280200360200200520052902d0013703082005201729020037032041022118410021122005290380012113200528027c2114200528027821150c150b200541b4036a200541f8006a41286a290300370200200541ac036a200541f8006a41206a290300370200200541a4036a200541f8006a41186a2903003702002005419c036a200541f8006a41106a29030037020020054188036a410c6a200541f8006a41086a29030037020020054188036a41386a2011360200200541bc036a41003602002005200529037837028c03200541cc036a20052902d001370200200541d4036a200541d0016a41086a290200370200200541dc036a200541d0016a41106a2802003602002005410236028803200541206a41086a2202200541c0016a41086a280200360200200520052903c001370320200541a0026a200120054188036a200541206a10b30620054180026a41086a2207200541a0026a41206a29030037030020054180026a41106a2209200541a0026a41286a29030037030020054180026a41186a2208200541d0026a290300370300200541e8016a41086a2203200541f0026a290300370300200541e8016a41106a2216200541f8026a2802003602002005200541a0026a41186a290300370380022005200541e8026a2903003703e80120052802a402211820052802a0024101460d0c200541a0026a41086a2802002115200541a0026a410c6a2802002114200541a0026a41106a2903002113200541a0026a41386a2802002112200541dc026a2802002111200541e0026a2903002110200541206a41186a2008290300370300200541206a41106a200929030037030020022007290300370300200541086a41086a2003290300370300200541086a41106a20162802003602002005200529038002370320200520052903e8013703080b410021160c130b200041013602000c130b20004101360200200020023602042011450d0c2010a70d0b0c0c0b200541206a41186a201741186a290200370300200541206a41106a201741106a290200370300200541206a41086a201741086a290200370300200520172902003703204100211141042118410121160c100b20054184016a2802001029410221160c0f0b2016200b41b4a0cc001036000b200a200941b4a0cc001036000b2002200941b4a0cc001036000b2016200b41b4a0cc001036000b200a200941b4a0cc001036000b2018200b41b4a0cc001036000b200a200941b4a0cc001036000b200041013602000c080b2007200941b4a0cc001036000b201110290b20121029200528027c41244d0d0620054184016a2802001029200624000f0b2002200c460d010b200541206a41186a200141186a290200370300200541206a41106a200141106a290200370300200541206a41086a200141086a29020037030020052001290200370320201042ffffffff0f83211041012118410121160c020b2010a7210202400240200428020022070d00201421070c010b0240200441046a2802000d00201421070c010b2007102920052802a40221070b2004201136020420042012360200200441086a20023602000240200741244b0d00410121180c020b200541ac026a2802001029410121180c010b2005290380012113200528027c2114200528027821150b20002016360204200041146a2013370200200041106a20143602002000410c6a2015360200200041086a20183602002000411c6a2005290320370200200041c4006a2010370200200041c0006a20113602002000413c6a2012360200200041cc006a2005290308370200200041246a200541206a41086a2903003702002000412c6a200541206a41106a290300370200200041346a200541206a41186a290300370200200041d4006a200541086a41086a290300370200200041dc006a200541086a41106a28020036020020004100360200200624000f0b200020183602040b200624000baaa50120047f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e027f017e067f017e067f017e230041b00e6b22052400200541086a2002200310870402400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020052d00084101470d0020052d00092102200541900e6a41086a2203200141086a290000370300200541900e6a41106a2204200141106a290000370300200541900e6a41186a2206200141186a290000370300200520012900003703900e4130102722010d010c2c0b200541d4016a2802002107200541d0016a2802002108200541c8016a2903002109200541c4016a280200210a200541bc016a290200210b200541b8016a280200210c200541b0016a290300210d200541ac016a280200210e200541a4016a290200210f200541a0016a280200211020054198016a290300211120054194016a28020021122005418c016a290200211320054188016a280200211420054180016a2903002115200541fc006a2802002116200541f4006a2902002117200541f0006a2802002118200541e8006a2903002119200541e4006a280200211a200541dc006a290200211b200541086a41d0006a280200211c200541086a41c8006a290300211d200541086a41c4006a280200211e200541086a413c6a290200211f200541086a41386a2802002120200541086a41306a2903002121200541346a28020021222005412c6a22232902002124200541086a41206a2802002125200541246a22262802002127200541086a41186a28020021022005411c6a22282802002129200541086a410c6a222a290200212b200541086a41086a222c28020021064100212d200528020c0e051502030401150b200141033a0000200120052903900e370001200120023a0021200120052901e00d370122200141096a2003290300370000200141116a2004290300370000200141196a2006290300370000200141286a200541e60d6a29010037010020004101360200200020013602040c290b200541e0016a280200212e200541dc016a280200212d200541d8016a2802002123410221030240024020294102470d00410021024100212f0c010b200541900e6a41186a222f200141186a290000370300200541900e6a41106a2230200141106a290000370300200541900e6a41086a2231200141086a290000370300200520012900003703900e200541e00d6a41086a2027360200200520023602e40d200520293602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012102024020052802084101460d00202f200541286a2903003703002030200541086a41186a2903003703002031200541086a41106a2903003703002005200541086a41086a2903003703900e410021020b200341807e71212f0b200541c0066a41186a2230200541900e6a41186a290300370300200541c0066a41106a2229200541900e6a41106a290300370300200541c0066a41086a2231200541900e6a41086a290300370300200520052903900e3703c006202f200341ff017172212f20020d03200541a0066a41186a2030290300370300200541a0066a41106a2029290300370300200541a0066a41086a2031290300370300200520052903c0063703a006410221024100210341002130024020254102460d00200541900e6a41186a2230200141186a290000370300200541900e6a41106a2229200141106a290000370300200541900e6a41086a2231200141086a290000370300200520012900003703900e200520243702e40d200520253602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210241012103024020052802084101460d002030200541286a2903003703002029200541086a41186a2903003703002031200541086a41106a2903003703002005200541086a41086a2903003703900e410021030b200241807e7121300b20054180076a41186a2229200541900e6a41186a29030037030020054180076a41106a2231200541900e6a41106a29030037030020054180076a41086a2226200541900e6a41086a290300370300200520052903900e370380072030200241ff017172210220030d04200541e0066a41186a2029290300370300200541e0066a41106a2031290300370300200541e0066a41086a202629030037030020052005290380073703e006410221034100213041002129024020224102460d00200541900e6a41186a2229200141186a290000370300200541900e6a41106a2231200141106a290000370300200541900e6a41086a2226200141086a290000370300200520012900003703900e200520213702e40d200520223602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012130024020052802084101460d002029200541286a2903003703002031200541086a41186a2903003703002026200541086a41106a2903003703002005200541086a41086a2903003703900e410021300b200341807e7121290b200541c0076a41186a2231200541900e6a41186a290300370300200541c0076a41106a2226200541900e6a41106a290300370300200541c0076a41086a2228200541900e6a41086a290300370300200520052903900e3703c0072029200341ff017172212920300d05200541a0076a41186a2031290300370300200541a0076a41106a2026290300370300200541a0076a41086a2028290300370300200520052903c0073703a007410221034100213041002131024020204102460d00200541900e6a41186a2231200141186a290000370300200541900e6a41106a2226200141106a290000370300200541900e6a41086a2228200141086a290000370300200520012900003703900e2005201f3702e40d200520203602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012130024020052802084101460d002031200541286a2903003703002026200541086a41186a2903003703002028200541086a41106a2903003703002005200541086a41086a2903003703900e410021300b200341807e7121310b20054180086a41186a2226200541900e6a41186a29030037030020054180086a41106a2228200541900e6a41106a29030037030020054180086a41086a222a200541900e6a41086a290300370300200520052903900e370380082031200341ff017172213120300d06200541e0076a41186a2026290300370300200541e0076a41106a2028290300370300200541e0076a41086a202a29030037030020052005290380083703e0074102210341002130410021260240201e4102460d00200541900e6a41186a2226200141186a290000370300200541900e6a41106a2228200141106a290000370300200541900e6a41086a222a200141086a290000370300200520012900003703900e2005201d3702e40d2005201e3602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012130024020052802084101460d002026200541286a2903003703002028200541086a41186a290300370300202a200541086a41106a2903003703002005200541086a41086a2903003703900e410021300b200341807e7121260b200541c0086a41186a2228200541900e6a41186a290300370300200541c0086a41106a222a200541900e6a41106a290300370300200541c0086a41086a2227200541900e6a41086a290300370300200520052903900e3703c0082026200341ff017172212620300d07200541a0086a41186a2028290300370300200541a0086a41106a202a290300370300200541a0086a41086a2027290300370300200520052903c0083703a0084102210341002130410021280240201c4102460d00200541900e6a41186a2228200141186a290000370300200541900e6a41106a222a200141106a290000370300200541900e6a41086a2227200141086a290000370300200520012900003703900e2005201b3702e40d2005201c3602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012130024020052802084101460d002028200541286a290300370300202a200541086a41186a2903003703002027200541086a41106a2903003703002005200541086a41086a2903003703900e410021300b200341807e7121280b20054180096a41186a222a200541900e6a41186a29030037030020054180096a41106a2227200541900e6a41106a29030037030020054180096a41086a222c200541900e6a41086a290300370300200520052903900e370380092028200341ff017172212820300d08200541e0086a41186a202a290300370300200541e0086a41106a2027290300370300200541e0086a41086a202c29030037030020052005290380093703e00841022103410021304100212a0240201a4102460d00200541900e6a41186a222a200141186a290000370300200541900e6a41106a2227200141106a290000370300200541900e6a41086a222c200141086a290000370300200520012900003703900e200520193702e40d2005201a3602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012130024020052802084101460d00202a200541286a2903003703002027200541086a41186a290300370300202c200541086a41106a2903003703002005200541086a41086a2903003703900e410021300b200341807e71212a0b200541c0096a41186a2227200541900e6a41186a290300370300200541c0096a41106a222c200541900e6a41106a290300370300200541c0096a41086a2225200541900e6a41086a290300370300200520052903900e3703c009202a200341ff017172212a20300d09200541a0096a41186a2027290300370300200541a0096a41106a202c290300370300200541a0096a41086a2025290300370300200520052903c0093703a009410221034100213041002127024020184102460d00200541900e6a41186a2227200141186a290000370300200541900e6a41106a222c200141106a290000370300200541900e6a41086a2225200141086a290000370300200520012900003703900e200520173702e40d200520183602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012130024020052802084101460d002027200541286a290300370300202c200541086a41186a2903003703002025200541086a41106a2903003703002005200541086a41086a2903003703900e410021300b200341807e7121270b200541800a6a41186a222c200541900e6a41186a290300370300200541800a6a41106a2225200541900e6a41106a290300370300200541800a6a41086a2222200541900e6a41086a290300370300200520052903900e3703800a2027200341ff017172212720300d0a200541e0096a41186a202c290300370300200541e0096a41106a2025290300370300200541e0096a41086a2022290300370300200520052903800a3703e00941022103410021304100212c024020164102460d00200541900e6a41186a222c200141186a290000370300200541900e6a41106a2225200141106a290000370300200541900e6a41086a2222200141086a290000370300200520012900003703900e200520153702e40d200520163602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012130024020052802084101460d00202c200541286a2903003703002025200541086a41186a2903003703002022200541086a41106a2903003703002005200541086a41086a2903003703900e410021300b200341807e71212c0b200541c00a6a41186a2225200541900e6a41186a290300370300200541c00a6a41106a2222200541900e6a41106a290300370300200541c00a6a41086a2220200541900e6a41086a290300370300200520052903900e3703c00a202c200341ff017172212c20300d0b200541a00a6a41186a2025290300370300200541a00a6a41106a2022290300370300200541a00a6a41086a2020290300370300200520052903c00a3703a00a410221034100213041002125024020144102460d00200541900e6a41186a2225200141186a290000370300200541900e6a41106a2222200141106a290000370300200541900e6a41086a2220200141086a290000370300200520012900003703900e200520133702e40d200520143602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012130024020052802084101460d002025200541286a2903003703002022200541086a41186a2903003703002020200541086a41106a2903003703002005200541086a41086a2903003703900e410021300b200341807e7121250b200541800b6a41186a2222200541900e6a41186a290300370300200541800b6a41106a2220200541900e6a41106a290300370300200541800b6a41086a221e200541900e6a41086a290300370300200520052903900e3703800b2025200341ff017172212520300d0c200541e00a6a41186a2022290300370300200541e00a6a41106a2020290300370300200541e00a6a41086a201e290300370300200520052903800b3703e00a410221034100213041002122024020124102460d00200541900e6a41186a2222200141186a290000370300200541900e6a41106a2220200141106a290000370300200541900e6a41086a221e200141086a290000370300200520012900003703900e200520113702e40d200520123602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012130024020052802084101460d002022200541286a2903003703002020200541086a41186a290300370300201e200541086a41106a2903003703002005200541086a41086a2903003703900e410021300b200341807e7121220b200541c00b6a41186a2220200541900e6a41186a290300370300200541c00b6a41106a221e200541900e6a41106a290300370300200541c00b6a41086a221c200541900e6a41086a290300370300200520052903900e3703c00b2022200341ff017172212220300d0d200541a00b6a41186a2020290300370300200541a00b6a41106a201e290300370300200541a00b6a41086a201c290300370300200520052903c00b3703a00b410221034100213041002120024020104102460d00200541900e6a41186a2220200141186a290000370300200541900e6a41106a221e200141106a290000370300200541900e6a41086a221c200141086a290000370300200520012900003703900e2005200f3702e40d200520103602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012130024020052802084101460d002020200541286a290300370300201e200541086a41186a290300370300201c200541086a41106a2903003703002005200541086a41086a2903003703900e410021300b200341807e7121200b200541800c6a41186a221e200541900e6a41186a290300370300200541800c6a41106a221c200541900e6a41106a290300370300200541800c6a41086a221a200541900e6a41086a290300370300200520052903900e3703800c2020200341ff017172212020300d0e200541e00b6a41186a201e290300370300200541e00b6a41106a201c290300370300200541e00b6a41086a201a290300370300200520052903800c3703e00b41022130410021034100211e0240200e4102460d00200541900e6a41186a221e200141186a290000370300200541900e6a41106a221c200141106a290000370300200541900e6a41086a221a200141086a290000370300200520012900003703900e2005200d3702e40d2005200e3602e00d200541086a200541900e6a200541e00d6a200410b506200528020c213041012103024020052802084101460d00201e200541286a290300370300201c200541086a41186a290300370300201a200541086a41106a2903003703002005200541086a41086a2903003703900e410021030b203041807e71211e203041ff017121300b200541c00c6a41186a221c200541900e6a41186a290300370300200541c00c6a41106a221a200541900e6a41106a290300370300200541c00c6a41086a2218200541900e6a41086a290300370300200520052903900e3703c00c201e203072213020030d0f200541a00c6a41186a201c290300370300200541a00c6a41106a201a290300370300200541a00c6a41086a2018290300370300200520052903c00c3703a00c4102211e410021034100211c0240200c4102460d00200541900e6a41186a221c200141186a290000370300200541900e6a41106a221a200141106a290000370300200541900e6a41086a2218200141086a290000370300200520012900003703900e2005200b3702e40d2005200c3602e00d200541086a200541900e6a200541e00d6a200410b506200528020c211e41012103024020052802084101460d00201c200541286a290300370300201a200541086a41186a2903003703002018200541086a41106a2903003703002005200541086a41086a2903003703900e410021030b201e41807e71211c201e41ff0171211e0b200541800d6a41186a221a200541900e6a41186a290300370300200541800d6a41106a2218200541900e6a41106a290300370300200541800d6a41086a2216200541900e6a41086a290300370300200520052903900e3703800d201c201e72211e20030d10200541e00c6a41186a201a290300370300200541e00c6a41106a2018290300370300200541e00c6a41086a2016290300370300200520052903800d3703e00c4102211c410021034100211a0240200a4102460d00200541900e6a41186a221a200141186a290000370300200541900e6a41106a2218200141106a290000370300200541900e6a41086a2216200141086a290000370300200520012900003703900e200520093702e40d2005200a3602e00d200541086a200541900e6a200541e00d6a200410b506200528020c211c41012103024020052802084101460d00201a200541286a2903003703002018200541086a41186a2903003703002016200541086a41106a2903003703002005200541086a41086a2903003703900e410021030b201c41807e71211a201c41ff0171211c0b200541c00d6a41186a2218200541900e6a41186a290300370300200541c00d6a41106a2216200541900e6a41106a290300370300200541c00d6a41086a2214200541900e6a41086a290300370300200520052903900e3703c00d201a201c72211c20030d24200541a00d6a41186a2018290300370300200541a00d6a41106a2016290300370300200541a00d6a41086a2014290300370300200520052903c00d3703a00d4102210320084102470d1141002101410021040c120b41002101200541003a000c20054100360208200541086a20062006202ba76a10b006200541900e6a41086a2028290200370300200541a00e6a2026290200370300200541900e6a41186a20232902003703002005202a2902003703900e2002417f4c0d13200529020c21322005280208212f0240024020020d00410121030c010b200210272203450d25200221010b0240024020012002490d00200121300c010b200141017422042002200420024b1b22304100480d26024020010d00203010272203450d2a0c010b20012030460d00200320012030102b2203450d290b202b422088a7213120032029200210e4071a20054180026a41186a200541900e6a41186a29030037030020054180026a41106a200541900e6a41106a29030037030020054180026a41086a200541900e6a41086a290300370300200520052903900e370380024101212d0c120b200541003a000c20054100360208200541086a20062006202ba76a10b006200541e00d6a41086a2028290200370300200541e00d6a41106a22302026290200370300200541e00d6a41186a20232902003703002005202a2902003703e00d202c2802002106200528020c21312005280208212f200541900e6a41186a200141186a290000370300200541900e6a41106a200141106a290000370300200541900e6a41086a200141086a290000370300200520012900003703900e200541a00d6a41086a2027360200200520023602a40d200520293602a00d200541086a200541900e6a200541a00d6a200410b506200541c00d6a41086a2026290200370300200541c00d6a41106a22012023280200360200200520282902003703c00d200528020c2103024020052802084101460d00202c2903002124200541086a41106a280200212e200541e8016a41106a2001280200360200200541e8016a41086a200541c00d6a41086a29030037030020054180026a41086a200541e00d6a41086a29030037030020054180026a41106a203029030037030020054180026a41186a200541e00d6a41186a290300370300200520052903c00d3703e801200520052903e00d370380022006ad4220862031ad8421322024422088a72102202b422088a721312024a721304102212d0c120b2000410136020020002003360204202f41244d0d26200610290c260b410221034100212f4100212e024020064102460d00200541900e6a41186a222f200141186a290000370300200541900e6a41106a2230200141106a290000370300200541900e6a41086a2231200141086a290000370300200520012900003703900e2005202b3702e40d200520063602e00d200541086a200541900e6a200541e00d6a200410b506200528020c21034101212e024020052802084101460d00202f200541286a2903003703002030200541086a41186a2903003703002031200541086a41106a2903003703002005200541086a41086a2903003703900e4100212e0b200341807e71212f0b200541c0066a41186a2230200541900e6a41186a290300370300200541c0066a41106a2231200541900e6a41106a290300370300200541c0066a41086a222d200541900e6a41086a290300370300200520052903900e3703c006200341ff0171202f722106202e0d12200541a0066a41186a2030290300370300200541a0066a41106a2031290300370300200541a0066a41086a202d290300370300200520052903c0063703a006410221030240024020294102470d004100212e410021020c010b200541900e6a41186a222e200141186a290000370300200541900e6a41106a222f200141106a290000370300200541900e6a41086a2230200141086a290000370300200520012900003703900e200541e00d6a41086a2027360200200520023602e40d200520293602e00d200541086a200541900e6a200541e00d6a200410b506200528020c210341012102024020052802084101460d00202e200541286a290300370300202f200541086a41186a2903003703002030200541086a41106a2903003703002005200541086a41086a2903003703900e410021020b200341807e71212e0b20054180076a41186a222f200541900e6a41186a29030037030020054180076a41106a2230200541900e6a41106a29030037030020054180076a41086a2229200541900e6a41086a290300370300200520052903900e37038007200341ff0171202e72210320020d13200541e0066a41186a202f290300370300200541e0066a41106a2030290300370300200541e0066a41086a202929030037030020052005290380073703e006410221024100212f4100212e024020254102460d00200541900e6a41186a222f200141186a290000370300200541900e6a41106a2230200141106a290000370300200541900e6a41086a2229200141086a290000370300200520012900003703900e200520243702e40d200520253602e00d200541086a200541900e6a200541e00d6a200410b506200528020c21024101212e024020052802084101460d00202f200541286a2903003703002030200541086a41186a2903003703002029200541086a41106a2903003703002005200541086a41086a2903003703900e4100212e0b200241807e71212f0b200541c0076a41186a2230200541900e6a41186a290300370300200541c0076a41106a2229200541900e6a41106a290300370300200541c0076a41086a2231200541900e6a41086a290300370300200520052903900e3703c007200241ff0171202f722102202e0d14200541a0076a41186a2030290300370300200541a0076a41106a2029290300370300200541a0076a41086a2031290300370300200520052903c0073703a0074102212e410021304100212f024020224102460d00200541900e6a41186a2230200141186a290000370300200541900e6a41106a2229200141106a290000370300200541900e6a41086a2231200141086a290000370300200520012900003703900e200520213702e40d200520223602e00d200541086a200541900e6a200541e00d6a200410b506200528020c212e4101212f024020052802084101460d002030200541286a2903003703002029200541086a41186a2903003703002031200541086a41106a2903003703002005200541086a41086a2903003703900e4100212f0b202e41807e7121300b20054180086a41186a2229200541900e6a41186a29030037030020054180086a41106a2231200541900e6a41106a29030037030020054180086a41086a222d200541900e6a41086a290300370300200520052903900e37038008202e41ff0171203072212e202f0d15200541e0076a41186a2029290300370300200541e0076a41106a2031290300370300200541e0076a41086a202d29030037030020052005290380083703e0074102212f4100212941002130024020204102460d00200541900e6a41186a2229200141186a290000370300200541900e6a41106a2231200141106a290000370300200541900e6a41086a222d200141086a290000370300200520012900003703900e2005201f3702e40d200520203602e00d200541086a200541900e6a200541e00d6a200410b506200528020c212f41012130024020052802084101460d002029200541286a2903003703002031200541086a41186a290300370300202d200541086a41106a2903003703002005200541086a41086a2903003703900e410021300b202f41807e7121290b200541c0086a41186a2231200541900e6a41186a290300370300200541c0086a41106a222d200541900e6a41106a290300370300200541c0086a41086a2223200541900e6a41086a290300370300200520052903900e3703c008202f41ff0171202972212f20300d16200541a0086a41186a2031290300370300200541a0086a41106a202d290300370300200541a0086a41086a2023290300370300200520052903c0083703a0084102213041002131410021290240201e4102460d00200541900e6a41186a2231200141186a290000370300200541900e6a41106a222d200141106a290000370300200541900e6a41086a2223200141086a290000370300200520012900003703900e2005201d3702e40d2005201e3602e00d200541086a200541900e6a200541e00d6a200410b506200528020c213041012129024020052802084101460d002031200541286a290300370300202d200541086a41186a2903003703002023200541086a41106a2903003703002005200541086a41086a2903003703900e410021290b203041807e7121310b20054180096a41186a222d200541900e6a41186a29030037030020054180096a41106a2223200541900e6a41106a29030037030020054180096a41086a2226200541900e6a41086a290300370300200520052903900e37038009203041ff0171203172213020290d17200541e0086a41186a202d290300370300200541e0086a41106a2023290300370300200541e0086a41086a202629030037030020052005290380093703e008410221294100212d410021310240201c4102460d00200541900e6a41186a222d200141186a290000370300200541900e6a41106a2223200141106a290000370300200541900e6a41086a2226200141086a290000370300200520012900003703900e2005201b3702e40d2005201c3602e00d200541086a200541900e6a200541e00d6a200410b506200528020c212941012131024020052802084101460d00202d200541286a2903003703002023200541086a41186a2903003703002026200541086a41106a2903003703002005200541086a41086a2903003703900e410021310b202941807e71212d0b200541c0096a41186a2223200541900e6a41186a290300370300200541c0096a41106a2226200541900e6a41106a290300370300200541c0096a41086a2228200541900e6a41086a290300370300200520052903900e3703c009202941ff0171202d72212920310d18200541a0096a41186a2023290300370300200541a0096a41106a2026290300370300200541a0096a41086a2028290300370300200520052903c0093703a00941022131410021234100212d0240201a4102460d00200541900e6a41186a2223200141186a290000370300200541900e6a41106a2226200141106a290000370300200541900e6a41086a2228200141086a290000370300200520012900003703900e200520193702e40d2005201a3602e00d200541086a200541900e6a200541e00d6a200410b506200528020c21314101212d024020052802084101460d002023200541286a2903003703002026200541086a41186a2903003703002028200541086a41106a2903003703002005200541086a41086a2903003703900e4100212d0b203141807e7121230b200541800a6a41186a2226200541900e6a41186a290300370300200541800a6a41106a2228200541900e6a41106a290300370300200541800a6a41086a222a200541900e6a41086a290300370300200520052903900e3703800a203141ff01712023722123202d0d19200541e0096a41186a2026290300370300200541e0096a41106a2028290300370300200541e0096a41086a202a290300370300200520052903800a3703e00941022131410021264100212d024020184102460d00200541900e6a41186a2226200141186a290000370300200541900e6a41106a2228200141106a290000370300200541900e6a41086a222a200141086a290000370300200520012900003703900e200520173702e40d200520183602e00d200541086a200541900e6a200541e00d6a200410b506200528020c21314101212d024020052802084101460d002026200541286a2903003703002028200541086a41186a290300370300202a200541086a41106a2903003703002005200541086a41086a2903003703900e4100212d0b203141807e7121260b200541c00a6a41186a2228200541900e6a41186a290300370300200541c00a6a41106a222a200541900e6a41106a290300370300200541c00a6a41086a2227200541900e6a41086a290300370300200520052903900e3703c00a203141ff01712026722126202d0d1a200541a00a6a41186a2028290300370300200541a00a6a41106a202a290300370300200541a00a6a41086a2027290300370300200520052903c00a3703a00a41022131410021284100212d024020164102460d00200541900e6a41186a2228200141186a290000370300200541900e6a41106a222a200141106a290000370300200541900e6a41086a2227200141086a290000370300200520012900003703900e200520153702e40d200520163602e00d200541086a200541900e6a200541e00d6a200410b506200528020c21314101212d024020052802084101460d002028200541286a290300370300202a200541086a41186a2903003703002027200541086a41106a2903003703002005200541086a41086a2903003703900e4100212d0b203141807e7121280b200541800b6a41186a222a200541900e6a41186a290300370300200541800b6a41106a2227200541900e6a41106a290300370300200541800b6a41086a222c200541900e6a41086a290300370300200520052903900e3703800b203141ff01712028722128202d0d1b200541e00a6a41186a202a290300370300200541e00a6a41106a2027290300370300200541e00a6a41086a202c290300370300200520052903800b3703e00a410221314100212d4100212a024020144102460d00200541900e6a41186a222a200141186a290000370300200541900e6a41106a2227200141106a290000370300200541900e6a41086a222c200141086a290000370300200520012900003703900e200520133702e40d200520143602e00d200541086a200541900e6a200541e00d6a200410b506200528020c21314101212d024020052802084101460d00202a200541286a2903003703002027200541086a41186a290300370300202c200541086a41106a2903003703002005200541086a41086a2903003703900e4100212d0b203141807e71212a0b200541c00b6a41186a2227200541900e6a41186a290300370300200541c00b6a41106a222c200541900e6a41106a290300370300200541c00b6a41086a2225200541900e6a41086a290300370300200520052903900e3703c00b202a203141ff017172212a202d0d1c200541a00b6a41186a2027290300370300200541a00b6a41106a202c290300370300200541a00b6a41086a2025290300370300200520052903c00b3703a00b410221314100212d41002127024020124102460d00200541900e6a41186a2227200141186a290000370300200541900e6a41106a222c200141106a290000370300200541900e6a41086a2225200141086a290000370300200520012900003703900e200520113702e40d200520123602e00d200541086a200541900e6a200541e00d6a200410b506200528020c21314101212d024020052802084101460d002027200541286a290300370300202c200541086a41186a2903003703002025200541086a41106a2903003703002005200541086a41086a2903003703900e4100212d0b203141807e7121270b200541800c6a41186a222c200541900e6a41186a290300370300200541800c6a41106a2225200541900e6a41106a290300370300200541800c6a41086a2222200541900e6a41086a290300370300200520052903900e3703800c2027203141ff0171722127202d0d1d200541e00b6a41186a202c290300370300200541e00b6a41106a2025290300370300200541e00b6a41086a2022290300370300200520052903800c3703e00b4102212d410021314100212c024020104102460d00200541900e6a41186a222c200141186a290000370300200541900e6a41106a2225200141106a290000370300200541900e6a41086a2222200141086a290000370300200520012900003703900e2005200f3702e40d200520103602e00d200541086a200541900e6a200541e00d6a200410b506200528020c212d41012131024020052802084101460d00202c200541286a2903003703002025200541086a41186a2903003703002022200541086a41106a2903003703002005200541086a41086a2903003703900e410021310b202d41807e71212c202d41ff0171212d0b200541c00c6a41186a2225200541900e6a41186a290300370300200541c00c6a41106a2222200541900e6a41106a290300370300200541c00c6a41086a2220200541900e6a41086a290300370300200520052903900e3703c00c202c202d72212d20310d1e200541a00c6a41186a2025290300370300200541a00c6a41106a2022290300370300200541a00c6a41086a2020290300370300200520052903c00c3703a00c4102212c41002131410021250240200e4102460d00200541900e6a41186a2225200141186a290000370300200541900e6a41106a2222200141106a290000370300200541900e6a41086a2220200141086a290000370300200520012900003703900e2005200d3702e40d2005200e3602e00d200541086a200541900e6a200541e00d6a200410b506200528020c212c41012131024020052802084101460d002025200541286a2903003703002022200541086a41186a2903003703002020200541086a41106a2903003703002005200541086a41086a2903003703900e410021310b202c41807e712125202c41ff0171212c0b200541800d6a41186a2222200541900e6a41186a290300370300200541800d6a41106a2220200541900e6a41106a290300370300200541800d6a41086a221e200541900e6a41086a290300370300200520052903900e3703800d2025202c72212c20310d1f200541e00c6a41186a2022290300370300200541e00c6a41106a2020290300370300200541e00c6a41086a201e290300370300200520052903800d3703e00c4102212541002131410021220240200c4102460d00200541900e6a41186a2222200141186a290000370300200541900e6a41106a2220200141106a290000370300200541900e6a41086a221e200141086a290000370300200520012900003703900e2005200b3702e40d2005200c3602e00d200541086a200541900e6a200541e00d6a200410b506200528020c212541012131024020052802084101460d002022200541286a2903003703002020200541086a41186a290300370300201e200541086a41106a2903003703002005200541086a41086a2903003703900e410021310b202541807e712122202541ff017121250b200541c00d6a41186a2220200541900e6a41186a290300370300200541c00d6a41106a221e200541900e6a41106a290300370300200541c00d6a41086a221c200541900e6a41086a290300370300200520052903900e3703c00d2022202572212520310d20200541a00d6a41186a2020290300370300200541a00d6a41106a201e290300370300200541a00d6a41086a201c290300370300200520052903c00d3703a00d4102212241002131410021200240200a4102460d00200541900e6a41186a2222200141186a290000370300200541900e6a41106a2220200141106a290000370300200541900e6a41086a221e200141086a290000370300200520012900003703900e200520093702840e2005200a3602800e200541086a200541900e6a200541800e6a200410b506200528020c210141012131024020052802084101460d002022200541286a2903003703002020200541086a41186a290300370300201e200541086a41106a2903003703002005200541086a41086a2903003703900e410021310b200141807e712120200141ff017121220b200541e00d6a41186a2204200541900e6a41186a290300370300200541e00d6a41106a221e200541900e6a41106a290300370300200541e00d6a41086a221c200541900e6a41086a290300370300200520052903900e3703e00d20202022722101024020310d00200541a0026a41186a2004290300370300200541a0026a41106a201e290300370300200541a0026a41086a201c29030037030020054180066a41086a200541a0066a41086a29030037030020054180066a41106a200541a0066a41106a29030037030020054180066a41186a200541a0066a41186a290300370300200541e0056a41086a200541e0066a41086a290300370300200541e0056a41106a200541e0066a41106a290300370300200541e0056a41186a200541e0066a41186a290300370300200520052903e00d3703a002200520052903a00637038006200520052903e0063703e005200541c0056a41186a200541a0076a41186a290300370300200541c0056a41106a200541a0076a41106a290300370300200541c0056a41086a200541a0076a41086a290300370300200541a0056a41086a200541e0076a41086a290300370300200541a0056a41106a200541e0076a41106a290300370300200541a0056a41186a200541e0076a41186a29030037030020054180056a41086a200541a0086a41086a29030037030020054180056a41106a200541a0086a41106a29030037030020054180056a41186a200541a0086a41186a290300370300200520052903a0073703c005200520052903e0073703a005200520052903a00837038005200541e0046a41186a200541e0086a41186a290300370300200541e0046a41106a200541e0086a41106a290300370300200541e0046a41086a200541e0086a41086a290300370300200541c0046a41186a200541a0096a41186a290300370300200541c0046a41106a200541a0096a41106a290300370300200541c0046a41086a200541a0096a41086a290300370300200541a0046a41186a200541e0096a41186a290300370300200541a0046a41106a200541e0096a41106a290300370300200541a0046a41086a200541e0096a41086a290300370300200520052903e0083703e004200520052903a0093703c004200520052903e0093703a00420054180046a41186a200541a00a6a41186a29030037030020054180046a41106a200541a00a6a41106a29030037030020054180046a41086a200541a00a6a41086a290300370300200520052903a00a37038004200541e0036a41186a200541e00a6a41186a290300370300200541e0036a41106a200541e00a6a41106a290300370300200541e0036a41086a200541e00a6a41086a290300370300200520052903e00a3703e003200541c0036a41186a200541a00b6a41186a290300370300200541c0036a41106a200541a00b6a41106a290300370300200541c0036a41086a200541a00b6a41086a290300370300200520052903a00b3703c003200541a0036a41186a200541e00b6a41186a290300370300200541a0036a41106a200541e00b6a41106a290300370300200541a0036a41086a200541e00b6a41086a290300370300200520052903e00b3703a00320054180036a41186a200541a00c6a41186a29030037030020054180036a41106a200541a00c6a41106a29030037030020054180036a41086a200541a00c6a41086a290300370300200520052903a00c37038003200541e0026a41186a200541e00c6a41186a290300370300200541e0026a41106a200541e00c6a41106a290300370300200541e0026a41086a200541e00c6a41086a290300370300200520052903e00c3703e002200541c0026a41186a200541a00d6a41186a290300370300200541c0026a41106a200541a00d6a41106a290300370300200541c0026a41086a200541a00d6a41086a290300370300200520052903a00d3703c00241c00410272231450d2720312006360200203120052903800637020420312003360224203120052903e0053702282031410c6a20054180066a41086a290300370200203141146a20054180066a41106a2903003702002031411c6a20054180066a41186a290300370200203141306a200541e0056a41086a290300370200203141386a200541e0056a41106a290300370200203141c0006a200541e0056a41186a290300370200203120023602482031202e36026c203120052903c00537024c203141d4006a200541c0056a41086a290300370200203141dc006a200541c0056a41106a290300370200203141e4006a200541c0056a41186a290300370200203120052903a005370270203141f8006a200541a0056a41086a29030037020020314180016a200541a0056a41106a29030037020020314188016a200541a0056a41186a2903003702002031202f36029001203120303602b401203141ac016a20054180056a41186a290300370200203141a4016a20054180056a41106a2903003702002031419c016a20054180056a41086a290300370200203120052903800537029401203141d0016a200541e0046a41186a290300370200203141c8016a200541e0046a41106a290300370200203141c0016a200541e0046a41086a290300370200203120052903e0043702b801203120293602d801203141f4016a200541c0046a41186a290300370200203141ec016a200541c0046a41106a290300370200203141e4016a200541c0046a41086a290300370200203120052903c0043702dc01203120233602fc0120314198026a200541a0046a41186a29030037020020314190026a200541a0046a41106a29030037020020314188026a200541a0046a41086a290300370200203120052903a00437028002203120263602a002203141bc026a20054180046a41186a290300370200203141b4026a20054180046a41106a290300370200203141ac026a20054180046a41086a29030037020020312005290380043702a402203120283602c402203141e0026a200541e0036a41186a290300370200203141d8026a200541e0036a41106a290300370200203141d0026a200541e0036a41086a290300370200203120052903e0033702c8022031202a3602e80220314184036a200541c0036a41186a290300370200203141fc026a200541c0036a41106a290300370200203141f4026a200541c0036a41086a290300370200203120052903c0033702ec022031202736028c03203141a8036a200541a0036a41186a290300370200203141a0036a200541a0036a41106a29030037020020314198036a200541a0036a41086a290300370200203120052903a003370290032031202d3602b003203141cc036a20054180036a41186a290300370200203141c4036a20054180036a41106a290300370200203141bc036a20054180036a41086a29030037020020312005290380033702b4032031202c3602d403203141f0036a200541e0026a41186a290300370200203141e8036a200541e0026a41106a290300370200203141e0036a200541e0026a41086a290300370200203120052903e0023702d803203120253602f80320314194046a200541c0026a41186a2903003702002031418c046a200541c0026a41106a29030037020020314184046a200541c0026a41086a290300370200203120052903c0023702fc032031200136029c04203141b8046a200541a0026a41186a290300370200203141b0046a200541a0026a41106a290300370200203141a8046a200541a0026a41086a290300370200203120052903a0023702a0044103212d024020080d004100212f0c120b2007417f4c0d120240024020070d00410021014101212f0c010b20071027222f450d24200721010b0240024020012007490d00200121020c010b200141017422022007200220074b1b22024100480d25024020010d0020021027222f450d290c010b20012002460d00202f20012002102b222f450d280b202f2008200710e4071a2007ad4220862002ad8421320c110b20004101360200200020013602040c250b200041013602002000202f3602040c240b20004101360200200020023602040c230b20004101360200200020293602040c220b20004101360200200020313602040c210b20004101360200200020263602040c200b20004101360200200020283602040c1f0b200041013602002000202a3602040c1e0b20004101360200200020273602040c1d0b200041013602002000202c3602040c1c0b20004101360200200020253602040c1b0b20004101360200200020223602040c1a0b20004101360200200020203602040c190b20004101360200200020303602040c180b200041013602002000201e3602040c170b200541900e6a41186a221a200141186a290000370300200541900e6a41106a2218200141106a290000370300200541900e6a41086a2216200141086a290000370300200520012900003703900e200541800e6a41086a2023360200200520073602840e200520083602800e200541086a200541900e6a200541800e6a200410b506200528020c210341012101024020052802084101460d00201a200541286a2903003703002018200541086a41186a2903003703002016200541086a41106a2903003703002005200541086a41086a2903003703900e410021010b200341807e712104200341ff017121030b200541e00d6a41186a2223200541900e6a41186a290300370300200541e00d6a41106a221a200541900e6a41106a290300370300200541e00d6a41086a2218200541900e6a41086a290300370300200520052903900e3703e00d2004200372210420010d14200541a0026a41186a2023290300370300200541a0026a41106a201a290300370300200541a0026a41086a201829030037030020054180066a41086a200541a0066a41086a29030037030020054180066a41106a200541a0066a41106a29030037030020054180066a41186a200541a0066a41186a290300370300200541e0056a41086a200541e0066a41086a290300370300200541e0056a41106a200541e0066a41106a290300370300200541e0056a41186a200541e0066a41186a290300370300200520052903e00d3703a002200520052903a00637038006200520052903e0063703e005200541c0056a41186a200541a0076a41186a290300370300200541c0056a41106a200541a0076a41106a290300370300200541c0056a41086a200541a0076a41086a290300370300200541a0056a41086a200541e0076a41086a290300370300200541a0056a41106a200541e0076a41106a290300370300200541a0056a41186a200541e0076a41186a29030037030020054180056a41086a200541a0086a41086a29030037030020054180056a41106a200541a0086a41106a29030037030020054180056a41186a200541a0086a41186a290300370300200520052903a0073703c005200520052903e0073703a005200520052903a00837038005200541e0046a41186a200541e0086a41186a290300370300200541e0046a41106a200541e0086a41106a290300370300200541e0046a41086a200541e0086a41086a290300370300200541c0046a41186a200541a0096a41186a290300370300200541c0046a41106a200541a0096a41106a290300370300200541c0046a41086a200541a0096a41086a290300370300200541a0046a41186a200541e0096a41186a290300370300200541a0046a41106a200541e0096a41106a290300370300200541a0046a41086a200541e0096a41086a290300370300200520052903e0083703e004200520052903a0093703c004200520052903e0093703a00420054180046a41186a200541a00a6a41186a29030037030020054180046a41106a200541a00a6a41106a29030037030020054180046a41086a200541a00a6a41086a290300370300200520052903a00a37038004200541e0036a41186a200541e00a6a41186a290300370300200541e0036a41106a200541e00a6a41106a290300370300200541e0036a41086a200541e00a6a41086a290300370300200520052903e00a3703e003200541c0036a41186a200541a00b6a41186a290300370300200541c0036a41106a200541a00b6a41106a290300370300200541c0036a41086a200541a00b6a41086a290300370300200520052903a00b3703c003200541a0036a41186a200541e00b6a41186a290300370300200541a0036a41106a200541e00b6a41106a290300370300200541a0036a41086a200541e00b6a41086a290300370300200520052903e00b3703a00320054180036a41186a200541a00c6a41186a29030037030020054180036a41106a200541a00c6a41106a29030037030020054180036a41086a200541a00c6a41086a290300370300200520052903a00c37038003200541e0026a41186a200541e00c6a41186a290300370300200541e0026a41106a200541e00c6a41106a290300370300200541e0026a41086a200541e00c6a41086a290300370300200520052903e00c3703e002200541c0026a41186a200541a00d6a41186a290300370300200541c0026a41106a200541a00d6a41106a290300370300200541c0026a41086a200541a00d6a41086a290300370300200520052903a00d3703c00241c00410272203450d162003202f360200200320052903800637020420032002360224200320052903e0053702282003410c6a20054180066a41086a290300370200200341146a20054180066a41106a2903003702002003411c6a20054180066a41186a290300370200200341306a200541e0056a41086a290300370200200341386a200541e0056a41106a290300370200200341c0006a200541e0056a41186a290300370200200320293602482003203136026c200320052903c00537024c200341d4006a200541c0056a41086a290300370200200341dc006a200541c0056a41106a290300370200200341e4006a200541c0056a41186a290300370200200320052903a005370270200341f8006a200541a0056a41086a29030037020020034180016a200541a0056a41106a29030037020020034188016a200541a0056a41186a2903003702002003202636029001200320283602b401200341ac016a20054180056a41186a290300370200200341a4016a20054180056a41106a2903003702002003419c016a20054180056a41086a290300370200200320052903800537029401200341d0016a200541e0046a41186a290300370200200341c8016a200541e0046a41106a290300370200200341c0016a200541e0046a41086a290300370200200320052903e0043702b8012003202a3602d801200341f4016a200541c0046a41186a290300370200200341ec016a200541c0046a41106a290300370200200341e4016a200541c0046a41086a290300370200200320052903c0043702dc01200320273602fc0120034198026a200541a0046a41186a29030037020020034190026a200541a0046a41106a29030037020020034188026a200541a0046a41086a290300370200200320052903a004370280022003202c3602a002200341bc026a20054180046a41186a290300370200200341b4026a20054180046a41106a290300370200200341ac026a20054180046a41086a29030037020020032005290380043702a402200320253602c402200341e0026a200541e0036a41186a290300370200200341d8026a200541e0036a41106a290300370200200341d0026a200541e0036a41086a290300370200200320052903e0033702c802200320223602e80220034184036a200541c0036a41186a290300370200200341fc026a200541c0036a41106a290300370200200341f4026a200541c0036a41086a290300370200200320052903c0033702ec022003202036028c03200341a8036a200541a0036a41186a290300370200200341a0036a200541a0036a41106a29030037020020034198036a200541a0036a41086a290300370200200320052903a00337029003200320303602b003200341cc036a20054180036a41186a290300370200200341c4036a20054180036a41106a290300370200200341bc036a20054180036a41086a29030037020020032005290380033702b4032003201e3602d403200341f0036a200541e0026a41186a290300370200200341e8036a200541e0026a41106a290300370200200341e0036a200541e0026a41086a290300370200200320052903e0023702d8032003201c3602f80320034194046a200541c0026a41186a2903003702002003418c046a200541c0026a41106a29030037020020034184046a200541c0026a41086a290300370200200320052903c0023702fc032003200436029c04200341b8046a200541a0026a41186a290300370200200341b0046a200541a0026a41106a290300370200200341a8046a200541a0026a41086a290300370200200320052903a0023702a00441002130200541003a000c20054100360208200541086a20062006202ba76a10b006200541900e6a41086a2204200541086a41146a290200370300200541900e6a41106a2206200541086a411c6a290200370300200541900e6a41186a22292005412c6a2902003703002005200541086a410c6a2902003703900e200529020c21322005280208212f02400240202d0d000c010b202e417f4c0d0202400240202e0d0041002101410121300c010b202e10272230450d14202e21010b024002402001202e490d00200121020c010b20014101742202202e2002202e4b1b22024100480d15024020010d00200210272230450d190c010b20012002460d00203020012002102b2230450d180b2030202d202e10e4071a0b202b422088a7213120054180026a41186a202929030037030020054180026a41106a200629030037030020054180026a41086a2004290300370300200520052903900e370380024104212d0b2000202d360204200041106a20323702002000410c6a202f360200200041086a2031360200200041186a200529038002370200200041c4006a202e360200200041386a2003360200200041c8006a20052903e801370200200041206a20054180026a41086a290300370200200041286a20054180026a41106a290300370200200041306a20054180026a41186a290300370200200041d0006a200541e8016a41086a290300370200200041d8006a200541e8016a41106a2802003602002000413c6a2002ad4220862030ad84370200200041003602000c140b1038000b20004101360200200020063602040c120b20004101360200200020033602040c110b20004101360200200020023602040c100b200041013602002000202e3602040c0f0b200041013602002000202f3602040c0e0b20004101360200200020303602040c0d0b20004101360200200020293602040c0c0b20004101360200200020233602040c0b0b20004101360200200020263602040c0a0b20004101360200200020283602040c090b200041013602002000202a3602040c080b20004101360200200020273602040c070b200041013602002000202d3602040c060b200041013602002000202c3602040c050b20004101360200200020253602040c040b200041013602002000201c3602040c030b1039000b1032000b20004101360200200020043602040b200541b00e6a24000f0b1030000bde7f08057f017e037f047e247f037e1c7f057e230022042105200441c0056b416071220424000240024002400240024002400240024002400240024002402002280200417e6a220641024b0d000240024020060e03010003010b20022802042207415c6a21082002410c6a2902002109200241086a280200210a417f210603402006410f460d09200641016a2106200841246a22082d00004102460d000b200841246a210b2006210c024003400240200c41016a220c410f4d0d00200a0d0d200420063a00b002200441003a00c404200441003602c004200441c0046a200441b0026a200441b1026a10b00620044180046a41286a200441c0046a41286a28020036020020044180046a41206a200441c0046a41206a29030037030020044180046a41186a200441c0046a41186a29030037030020044180046a41106a200441c0046a41106a29030037030020044180046a41086a200441c0046a41086a290300370300200420042903c004370380040240200641ff0171410f4b0d00200441023a00c0042008290200210920042903d804210d20042903d004210e20042903c804210f200820042903c004370200200829020821102008200f3702082008290210210f2008200e370210200841186a2206290200210e2006200d3702002009a741ff01714102460d03200841206a2802002106200441fc046a2010370200200441f4046a2009370200200441c0046a41086a20042903800437030020044194056a200636020020044184056a200f370200200441c0046a41106a20044180046a41086a290300370300200441c0046a41186a20044180046a41106a290300370300200441c0046a41206a20044180046a41186a290300370300200441c0046a41286a20044180046a41206a290300370300200441f0046a20044180046a41286a2802003602002004418c056a200e37020020044282808080103703c004200441b0026a41086a200341086a280200360200200420032902003703b00220002001200441c0046a200441b0026a10b3060c0d0b2006411041ec97c8001036000b200b2d00002111200b41246a210b20114102460d000c0c0b0b41c797c800412441ec97c8001057000b200441286a2002412c6a290200370300200441206a200241246a290200370300200441186a2002411c6a290200370300200441106a2208200241146a290200370300200441086a2002410c6a29020037030020042002290204370300200441de006a200241376a2d00003a0000200441c0006a41086a200241c4006a290200370300200441c0006a41106a200241cc006a290200370300200441c0006a41186a200241d4006a2802003602002004200241356a2f00003b015c20042002413c6a290200370340200241346a2d0000210a200241386a280200210c024002402004280204220641244b0d00200441096a210b200621080c010b2004410c6a280200210b200828020021080b2008417f6a21110240024002400240024002402008450d00200b20116a2d00002107200328020821082003280204210b200328020021110240200641244d0d00200441106a28020021060b200820064101742004280200417f736a6a220641017621080240024002402006410171450d00200b2008490d042008200b490d012008200b4194a1cc001036000b200b20084f0d012008200b4184a1cc00104b000b201120086a22062d00002112200441003a00c404200441003602c004200441c0046a2011200610c20220044180046a41286a200441c0046a41286a28020036020020044180046a41206a200441c0046a41206a29030037030020044180046a41186a200441c0046a41186a29030037030020044180046a41106a200441c0046a41106a29030037030020044180046a41086a200441c0046a41086a290300370300200420042903c00422093703800441242113024002402009a7220641244b0d0020044180046a210b0c010b2004418c046a210b200621130b200b280200220b2013470d054124211402400240200641244b0d00200621130c010b2004418c046a2802002113200621140b20142013470d040240201341016a22152013490d0041002114024020154102490d00417f2015417f6a677621140b201441016a22132014490d004124211502400240200641244b0d0020044180046a4105722116200621140c010b2004418c046a280200211420044188046a2802002116200621150b201420134b0d040240024020134125490d0020152013470d010c070b20064125490d06200441003a00840420044180046a4105722016201410e4071a2004201436028004201610290c060b02400240200641244b0d00201310272206450d0c20062016201410e4071a0c010b201620152013102b2206450d0b0b2004418c046a201436020020044188046a2006360200200441013a00840420042013360280040c050b41a4a1cc00411141b8a1cc001033000b200741047421134102210b410121070c050b20114100418c98c8001036000b2008200b41f4a0cc00104b000b41e6a1cc00412041b8a1cc001033000b20042802800421060b20124170712007410f7172210702400240200641244b0d0020044180046a410572210620044180046a21130c010b2004418c046a211320044188046a28020021060b2013200b41016a3602002006200b6a20073a0000200441c8046a2004418d046a290000370300200441d0046a20044195046a290000370300200441d8046a2004419d046a290000370300200441df046a200441a4046a29000037000020042004290085043703c00420042d008404210b2004280280042106410021070b200441ed006a200441c8046a290300370000200441f5006a200441d0046a290300370000200441fd006a200441d8046a290300370000200441e0006a41246a200441df046a29000037000020042006360260200420042903c0043700652004200b3a006402400240200b41ff01714102470d004100210b0c010b0240200641244b0d00200441e0006a410572210b0c010b200441ec006a2802002106200441e8006a280200210b0b20062008200b1b2112200b2011200b1b2111024002400240024002400240024002400240200a410171450d00200441cf046a200441c8006a290300370000200441d7046a200441d0006a290300370000200441df046a200441d8006a2d00003a0000200420042f015c3b01c0042004200c3600c304200420042903403700c7042004200441dc006a41026a2d00003a00c20420044189046a20133a0000200420073a00880420042012360284042004201136028004200441b0026a2001200441c0046a20044180046a10ae0620042802b402210620042802b0024101460d04200141c0006a220a280200220b200b417f6a200141386a220c2802002208200141346a22142802006b716b4101470d022001413c6a108b0120142802002214200c28020022084d0d022008200b20146b2215490d01200128023c2208200a28020020156b220b4102746a200820144102746a201541027410e4071a200141346a200b360200200141386a28020021080c020b0240200141c0006a220a28020022082008417f6a200141386a220b2802002206200141346a22142802006b716b4101470d002001413c6a108b0120142802002214200b28020022064d0d0002402006200820146b2215490d00200128023c2206200a28020020156b22084102746a200620144102746a201541027410e4071a200141346a2008360200200141386a28020021060c010b200128023c221420084102746a2014200641027410e4071a200141386a2206200628020020086a22063602000b200b200a280200417f6a200641016a713602002001413c6a28020020064102746a200c360200200141306a2802002206200c4d0d062001280228200c41fc006c6a22062d0010210c20062d0008210a20062d0004211420062d0002211520062d0001211620062d000021172006411f6a2d000021182006411e6a2d000021192006411d6a2d0000211a2006411c6a2d0000211b2006411b6a2d0000211c2006411a6a2d0000211d200641196a2d0000211e200641186a22082d0000211f200641176a2d00002120200641166a2d00002121200641156a2d00002122200641146a2d00002123200641136a2d00002124200641126a2d00002125200641116a2d000021262006410f6a2d000021272006410e6a2d000021282006410d6a2d000021292006410c6a2d0000212a2006410b6a2d0000212b2006410a6a2d0000212c200641096a2d0000212d200641076a2d0000212e200641066a2d0000212f200641056a2d00002130200641036a2d00002131200820042903d804370200200620042903d004370210200620042903c804370208200441003a00c004200441003602c404200620042903c004370200200641e0006a2108200641c0006a210b200641206a21060c020b200128023c2214200b4102746a2014200841027410e4071a200141386a22082008280200200b6a22083602000b200c200a280200417f6a200841016a713602002001413c6a28020020084102746a2006360200200141306a280200220820064d0d052001280228200641fc006c6a22062d0010210c20062d0008210a20062d0004211420062d0002211520062d0001211620062d000021172006411f6a2d000021182006411e6a2d000021192006411d6a2d0000211a2006411c6a2d0000211b2006411b6a2d0000211c2006411a6a2d0000211d200641196a2d0000211e200641186a22082d0000211f200641176a2d00002120200641166a2d00002121200641156a2d00002122200641146a2d00002123200641136a2d00002124200641126a2d00002125200641116a2d000021262006410f6a2d000021272006410e6a2d000021282006410d6a2d000021292006410c6a2d0000212a2006410b6a2d0000212b2006410a6a2d0000212c200641096a2d0000212d200641076a2d0000212e200641066a2d0000212f200641056a2d00002130200641036a2d00002131200820042903d804370200200620042903d004370210200620042903c804370208200441003a00c004200441003602c404200620042903c004370200200641e0006a2108200641c0006a210b200641206a21060b200441a0016a41086a2232200841096a290000370300200441a0016a41106a2233200841116a290000370300200441a0016a41176a2234200841186a2800003600002004200b29021022353703d0012004200b29020822363703c8012004200b290200220f3703c001200420082900013703a0012004200b41186a29020022373703d8014101210b200641186a29020021092006290210210d2006290208210e20062902002210a72106201741ff01714101470d0120082d00002108200441c0046a41176a2034280000360000200441c0046a41106a2033290300370300200441c0046a41086a2032290300370300200420042903a0013703c004200ea722174180fe037141087621322010422088a722334180fe03714108762134200da722384180fe03714108762139200e422088a7223a4180fe0371410876213b2009a7223c4180fe0371410876213d200d422088a7223e4180fe0371410876213f2009422088a722404180fe037141087621412010423888a721422010423088a72143200e423888a72144200e423088a72145200d423888a72146200d423088a72147200e422086220e423888a72148200e423088a721492009423888a7214a2009423088a7214b200d422086220d423888a7214c200d423088a7214d20094220862209423888a7214e2009423088a7214f200fa721500c020b2000410136020020002006360204024020042d00644102460d00200428026041244d0d00200441e8006a28020010290b200428020441244d0d072004410c6a28020010290c070b200441c0046a41176a20042800d801360000200441c0046a41106a20042900d101370300200441c0046a41086a20042900c901370300200420042900c1013703c004200fa721084100210b20092137200621502014213320302134202f2143202e2142200a2117202d2132202c2149202b2148202a213a2029213b2028214520272144200c2138202621392025214d2024214c2023213e2022213f2021214720202146201f213c201e213d201d214f201c214e201b2140201a21412019214b2018214a2010210f200e2136200d21350b200441e0016a41086a2251200441c0046a41086a290300370300200441e0016a41106a2252200441c0046a41106a290300370300200441e0016a41176a2253200441c0046a41176a2800003600002004200f370380022004203637038802200420042903c0043703e00120042035370390022004203737039802024002400240024002400240203341ff017120344108747241ffff0371204341ff0171204241087472411074722234417f6a223341014b0d0020330e020201020b20044180036a41086a20042900890237030020044180036a41106a20042900910237030020044180036a41176a200429009802370000200441e0026a41086a2051290300370300200441e0026a41106a2052290300370300200441e0026a41176a2053280000360000200420042900810237038003200420042903e0013703e002200b0d02200441b0026a210b200441c0036a210c200441e0036a21112050210620082150410021030c030b200441b0026a41186a200429038002370300200441b0026a41206a200429038802370300200441b0026a41286a200429039002370300200441b0026a41106a203c41ff0171203d4108747241ffff0371204f41ff0171204e4108747241107472ad204041ff017120414108747241ffff0371204b41ff0171204a4108747241107472ad422086843703002004201741ff017120324108747241ffff0371204941ff0171204841087472411074722232ad203a41ff0171203b4108747241ffff0371204541ff0171204441087472411074722217ad422086843703b0022004203841ff017120394108747241ffff0371204d41ff0171204c4108747241107472ad203e41ff0171203f4108747241ffff0371204741ff017120464108747241107472ad422086843703b802200441e0036a41176a200441e0016a41176a280000360000200441e0036a41106a200441e0016a41106a290300370300200441e0036a41086a200441e0016a41086a290300370300200420042903e0013703e0030240200b450d00200441003a00c404200441003602c004200441c0046a2011201120126a10c20220044180046a41286a200441c0046a41286a220b280200221136020020044180046a41206a200441c0046a41206a290300220937030020044180046a41186a200441c0046a41186a2212290300220d37030020044180046a41106a200441c0046a41106a2217290300220e37030020044180046a41086a200441c0046a41086a290300220f370300200420042903c004221037038004200b200f370300200441f0046a200e370300200441f8046a200d37030020044180056a200937030020044188056a20113602002004418d056a20133a00002004418c056a20073a0000200441de046a20183a00002017202641ff017120254108747241ffff0371202441ff017120234108747241107472ad202241ff017120214108747241ffff0371202041ff0171201f4108747241107472ad42208684370300200441dc046a201a41ff01712019410874723b01002012201e41ff0171201d4108747241ffff0371201c41ff0171201b4108747241107472360200200420063a00df04200420103703e0042004201641ff017120154108747241ffff0371203141ff017120144108747241107472ad203041ff0171202f4108747241ffff0371202e41ff0171200a4108747241107472ad422086843703c0042004202d41ff0171202c4108747241ffff0371202b41ff0171202a4108747241107472ad202941ff017120284108747241ffff0371202741ff0171200c4108747241107472ad422086843703c8042001200441c0046a10b10420042802b402211720042802b00221320b20044180046a41286a200441286a29030037030020044180046a41206a200441206a29030037030020044180046a41186a200441186a29030037030020044180046a41106a200441106a29030037030020044180046a41086a200441086a290300370300200420042903003703800402400240201741244b0d00200441b9026a21060c010b200441c0026a2802002117200441bc026a28020021060b200441c0046a41086a2017360200200420063602c404200420323602c00420044180046a200441c0046a10b406200441ec046a200441a8046a290300370200200441c0046a41246a200441a0046a290300370200200441dc046a20044198046a290300370200200441d4046a20044180046a41106a290300370200200441c0046a410c6a20044180046a41086a290300370200200441fc046a20083a0000200441f4046a203737020020044185056a200441e0036a41086a2903003700002004418d056a200441e0036a41106a29030037000020044194056a200441f7036a28000036000020042004290380043702c404200420042903e0033700fd04200441023602c004200441c0036a41086a200341086a280200360200200420032902003703c00320002001200441c0046a200441c0036a10b30620042802b40241244d0d03200441b0026a410c6a28020010290c030b20044180046a41186a20042903800237030020044180046a41206a20042903880237030020044180046a41286a20042903900237030020044180046a41106a203c41ff0171203d4108747241ffff0371204f41ff0171204e4108747241107472ad204041ff017120414108747241ffff0371204b41ff0171204a4108747241107472ad422086843703002004201741ff017120324108747241ffff0371204941ff0171204841087472411074722217ad203a41ff0171203b4108747241ffff0371204541ff0171204441087472411074722203ad42208684370380042004203841ff017120394108747241ffff0371204d41ff0171204c4108747241107472ad203e41ff0171203f4108747241ffff0371204741ff017120464108747241107472ad4220868437038804200441c2036a20042d00e2013a000020042004290398023703e003200420042f01e0013b01c0030240200b450d00200441003a00c404200441003602c004200441c0046a2011201120126a10c202200441b0026a41286a200441c0046a41286a220b2802002211360200200441b0026a41206a200441c0046a41206a2903002209370300200441b0026a41186a200441c0046a41186a2203290300220d370300200441b0026a41106a200441c0046a41106a2212290300220e370300200441b0026a41086a200441c0046a41086a290300220f370300200420042903c00422103703b002200b200f370300200441f0046a200e370300200441f8046a200d37030020044180056a200937030020044188056a20113602002004418d056a20133a00002004418c056a20073a0000200441de046a20183a00002012202641ff017120254108747241ffff0371202441ff017120234108747241107472ad202241ff017120214108747241ffff0371202041ff0171201f4108747241107472ad42208684370300200441dc046a201a41ff01712019410874723b01002003201e41ff0171201d4108747241ffff0371201c41ff0171201b4108747241107472360200200420063a00df04200420103703e0042004201641ff017120154108747241ffff0371203141ff017120144108747241107472ad203041ff0171202f4108747241ffff0371202e41ff0171200a4108747241107472ad422086843703c0042004202d41ff0171202c4108747241ffff0371202b41ff0171202a4108747241107472ad202941ff017120284108747241ffff0371202741ff0171200c4108747241107472ad422086843703c8042001200441c0046a10b104200428028404210320042802800421170b200441c0046a41286a200441286a290300370300200441c0046a41206a200441206a290300370300200441c0046a41186a200441186a290300370300200441c0046a41106a200441106a290300370300200441c0046a41086a200441086a290300370300200420042903003703c00402400240200341244b0d0020044189046a21060c010b20044190046a28020021032004418c046a28020021060b200441b0026a41086a2003360200200420063602b402200420173602b002200441c0046a200441b0026a10b40620004101360204200041086a20042903c004370200200041106a200441c0046a41086a290300370200200041186a200441c0046a41106a290300370200200041206a200441c0046a41186a290300370200200041286a200441c0046a41206a290300370200200041306a200441c0046a41286a290300370200200041c0006a20083a0000200041386a20042903e003370200200020042f01c0033b0041200041c3006a200441c2036a2d00003a00002000410036020020042802840441244d0d022004418c046a28020010290c020b200441ce026a20183a0000200441b0026a41106a202641ff017120254108747241ffff0371202441ff017120234108747241107472ad202241ff017120214108747241ffff0371202041ff0171201f4108747241107472ad42208684370000200441cc026a201a41ff01712019410874723b0000200441c8026a201e41ff0171201d4108747241ffff0371201c41ff0171201b41087472411074723600002004201641ff017120154108747241ffff0371203141ff017120144108747241107472ad203041ff0171202f4108747241ffff0371202e41ff0171200a4108747241107472ad422086843700b0022004202d41ff0171202c4108747241ffff0371202b41ff0171202a4108747241107472ad202941ff017120284108747241ffff0371202741ff0171200c4108747241107472ad422086843700b80241012103200441e0036a210b200441c0036a2111200441a0036a210c0b200b20343600032011200429038003370000200c20042903e002370000201141086a20044180036a41086a290300370000201141106a20044180036a41106a290300370000201141176a20044180036a41176a290000370000200c41086a200441e0026a41086a290300370000200c41106a200441e0026a41106a290300370000200c41176a200441e0026a41176a280000360000200b201741ff017120324108747241ffff0371204941ff017120484108747241107472ad203a41ff0171203b4108747241ffff0371204541ff017120444108747241107472ad42208684370007200b410f6a203841ff017120394108747241ffff0371204d41ff0171204c4108747241107472ad203e41ff0171203f4108747241ffff0371204741ff017120464108747241107472ad42208684370000200b41176a203c41ff0171203d4108747241ffff0371204f41ff0171204e4108747241107472ad204041ff017120414108747241ffff0371204b41ff0171204a4108747241107472ad4220868437000020044180046a41286a220b200441286a29030037030020044180046a41206a220c200441206a29030037030020044180046a41186a2211200441186a29030037030020044180046a41106a220a200441106a29030037030020044180046a41086a2207200441086a2903003703002004200429030037038004200441c9046a200441b0026a41086a290000370000200441d1046a200441b0026a41106a290000370000200441c0046a41186a200441b0026a41176a290000370000200441c0046a41206a20063a0000200420033a00c004200420042900b0023700c104200441e1046a20042900e003370000200441e9046a200441e0036a41086a290000370000200441f1046a200441e0036a41106a290000370000200441c0046a41386a200441e0036a41176a29000037000020044180056a20503a000020044198056a200441c0036a41176a29000037000020044191056a200441c0036a41106a29000037000020044189056a200441c0036a41086a29000037000020044181056a20042900c003370000200441a0056a20083a0000200441b8056a200441a0036a41176a280000360000200441b1056a200441a0036a41106a290000370000200441a9056a200441a0036a41086a290000370000200441a1056a20042900a003370000200141286a200441c0046a10a90621062000428080808020370200200041086a200429038004370200200041106a2007290300370200200041186a200a290300370200200041206a2011290300370200200041286a200c290300370200200041306a200b2903003702002000413c6a2006360200200041386a41003a00000b20042d00644102460d0c200428026041244d0d0c200441e8006a28020010290c0c0b200c2006418095c8001036000b20062008418095c8001036000b200041046a200241d80010e4071a200041003602000c0a0b200441a0016a41026a2002410f6a2d00003a0000200441e0036a41086a200241206a290200370300200441e0036a41106a200241286a290200370300200441e0036a41186a200241306a280200360200200420022f000d3b01a0012004200241186a2902003703e0032002410c6a2d00002115200241086a2802002107200241106a2802002114200241146a2802002113200241346a280200210a20022802042112200441e0026a41086a200241c0006a2802003602002004200241386a2902003703e002200a415c6a2108417f210603402006410f460d04200641016a2106200841246a22082d00004102460d000b200841246a210b2006210c024002400240024002400240024003400240200c41016a220c410f4d0d002004418c036a200441e8026a280200360200200420063a008103200441013a008003200420042903e00222093702840302402009a7450d0020044180036a41047221060c030b0240200641ff0171410f4b0d00200441023a00c0042008290200210920042903d804210d20042903d004210e20042903c804210f200820042903c004370200200829020821102008200f3702082008290210210f2008200e370210200841186a220b290200210e200b200d3702002004200e370398042004200f37039004200420103703880420042009370380042009a7221641ff01714102460d04200841206a2802002117200441e0016a41026a20042d0083043a0000200441c8036a200429039004370300200441d0036a200429039804370300200420042f0081043b01e00120042004290388043703c003200328020820132007200741244b1b41017420126b6a220c410176210b20032802042108200328020021110240024002400240200c410171450d002008200b490d09200b2008490d01200b20084194a1cc001036000b2008200b4f0d01200b20084184a1cc00104b000b2011200b6a22082d00002118200441003a00c404200441003602c004200441c0046a2011200810c20220044180046a41286a200441c0046a41286a28020036020020044180046a41206a200441c0046a41206a29030037030020044180046a41186a200441c0046a41186a29030037030020044180046a41106a200441c0046a41106a29030037030020044180046a41086a200441c0046a41086a290300370300200420042903c004220d370380044124210302400240200da7220841244b0d0020044180046a210c0c010b2004418c046a210c200821030b0240200c280200220c2003470d004124211902400240200841244b0d00200821030c010b2004418c046a2802002103200821190b024020192003470d00200341016a221a2003490d0b410021190240201a4102490d00417f201a417f6a677621190b201941016a22032019490d0b4124211a02400240200841244b0d0020044180046a410572211b200821190c010b2004418c046a280200211920044188046a280200211b2008211a0b201920034b0d0a02400240024020034125490d00201a2003460d03200841244b0d01200310272208450d112008201b201910e4071a0c020b20084125490d02200441003a00840420044180046a410572201b201910e4071a2004201936028004201b10290c020b201b201a2003102b2208450d0f0b2004418c046a201936020020044188046a2008360200200441013a00840420042003360280040b20042802800421080b2018417071200672210302400240200841244b0d0020044180046a410572210820044180046a21180c010b2004418c046a211820044188046a28020021080b2018200c41016a3602002008200c6a20033a0000200441c8046a2004418d046a290000370300200441d0046a20044195046a290000370300200441d8046a2004419d046a290000370300200441df046a200441a4046a29000037000020042004290085043703c00420042d008404210c2004280280042108410021310c010b200641047421324102210c410121310b20094220882109200441bd026a200441c8046a290300370000200441c5026a200441d0046a290300370000200441cd026a200441d8046a290300370000200441b0026a41246a200441df046a290000370000200420083602b002200420042903c0043700b5022004200c3a00b40202400240200c41ff01714102470d004100210c0c010b0240200841244b0d00200441b0026a410572210c0c010b200441bc026a2802002108200441b8026a280200210c0b2009a721032008200b200c1b2133200c2011200c1b21110240024002400240201641ff01714101470d00200441cf046a200441c8036a290300370000200441d7046a200441d0036a290300370000200420042f01e0013b01c004200420033600c304200420042903c0033700c704200420173a00df042004200441e0016a41026a2d00003a00c20420044189046a20323a0000200420313a0088042004203336028404200420113602800420042001200441c0046a20044180046a10ae062004280204210820042802004101460d03200141c0006a2216280200220c200c417f6a200141386a2203280200220b200141346a22172802006b716b4101470d022001413c6a108b01201728020022172003280200220b4d0d02200b200c20176b2218490d01200128023c220b201628020020186b220c4102746a200b20174102746a201841027410e4071a200141346a200c360200200141386a280200210b0c020b0240200141c0006a2216280200220b200b417f6a200141386a220c2802002208200141346a22172802006b716b4101470d002001413c6a108b0120172802002217200c28020022084d0d0002402008200b20176b2218490d00200128023c2208201628020020186b220b4102746a200820174102746a201841027410e4071a200141346a200b360200200141386a28020021080c010b200128023c2217200b4102746a2017200841027410e4071a200141386a22082008280200200b6a22083602000b200c2016280200417f6a200841016a713602002001413c6a28020020084102746a2003360200200141306a280200220820034d0d0b2001280228200341fc006c6a22082d0010210320082d0008211620082d0004212d20082d0002213820082d0001213920082d000021342008411f6a2d000021172008411e6a2d000021182008411d6a2d000021192008411c6a2d0000211a2008411b6a2d0000211b2008411a6a2d0000211c200841196a2d0000211d200841186a220b2d0000211e200841176a2d0000211f200841166a2d00002120200841156a2d00002121200841146a2d00002122200841136a2d00002123200841126a2d00002124200841116a2d000021252008410f6a2d000021262008410e6a2d000021272008410d6a2d000021282008410c6a2d000021292008410b6a2d0000212a2008410a6a2d0000212b200841096a2d0000212c200841076a2d0000212e200841066a2d0000212f200841056a2d00002130200841036a2d0000213a200b20042903d804370200200820042903d004370210200820042903c804370208200441003a00c004200441003602c404200820042903c004370200200841e0006a210b200841c0006a210c200841206a21080c0f0b200128023c2217200c4102746a2017200b41027410e4071a200141386a220b200b280200200c6a220b3602000b20032016280200417f6a200b41016a713602002001413c6a280200200b4102746a2008360200200141306a280200220b20084d0d0a2001280228200841fc006c6a22082d0010210320082d0008211620082d0004212d20082d0002213820082d0001213920082d000021342008411f6a2d000021172008411e6a2d000021182008411d6a2d000021192008411c6a2d0000211a2008411b6a2d0000211b2008411a6a2d0000211c200841196a2d0000211d200841186a220b2d0000211e200841176a2d0000211f200841166a2d00002120200841156a2d00002121200841146a2d00002122200841136a2d00002123200841126a2d00002124200841116a2d000021252008410f6a2d000021262008410e6a2d000021272008410d6a2d000021282008410c6a2d000021292008410b6a2d0000212a2008410a6a2d0000212b200841096a2d0000212c200841076a2d0000212e200841066a2d0000212f200841056a2d00002130200841036a2d0000213a200b20042903d804370200200820042903d004370210200820042903c804370208200441003a00c004200441003602c404200820042903c004370200200841e0006a210b200841c0006a210c200841206a21080c0d0b2000410136020020002008360204024020042d00b4024102460d0020042802b00241244d0d00200441b8026a28020010290b200a1029200741244d0d0b201410290c0b0b2006411041fc97c8001036000b200b2d00002111200b41246a210b20114102460d000b2004418c036a200441e8026a280200360200200420063a008103200441023a008003200420042903e0023702840320044180036a41047221060b20004104360204200020042f01a0013b0011200041106a20153a00002000410c6a2007360200200041086a2012360200200041186a2013360200200041146a20143602002000411c6a20042903e003370200200041136a200441a2016a2d00003a0000200041246a200441e0036a41086a2903003702002000412c6a200441e0036a41106a290300370200200041346a200441e0036a41186a280200360200200041386a200a36020020004100360200200041c4006a200641086a2802003602002000413c6a20062902003702000c0e0b41c797c800412441fc97c8001057000b200b200841f4a0cc00104b000b41e6a1cc00412041b8a1cc001033000b41a4a1cc00411141b8a1cc001033000b20032008418095c8001036000b2008200b418095c8001036000b1030000b2002280200417e6a4103490d07200210a706200524000f0b200441c0016a41086a223b200b41086a290200370300200441c0016a41106a223c200b41106a290200370300200441c0016a41186a223d200b41186a2802003602002004200c29021022373703702004200c29020822353703682004200c29020022363703602004200b2902003703c0012004200c41186a2902002210370378200841186a29020021092008290210210d2008290208210e2008290200210f02400240203441ff01714101470d00200441003a00c404200441003602c004200441c0046a2011201120336a10c20220044180046a41286a200441c0046a41286a2208280200220b36020020044180046a41206a200441c0046a41206a290300225437030020044180046a41186a200441c0046a41186a220c290300225537030020044180046a41106a200441c0046a41106a2211290300225637030020044180046a41086a200441c0046a41086a2903002257370300200420042903c00422583703800420082057370300200441f0046a2056370300200441f8046a205537030020044180056a205437030020044188056a200b3602002004418d056a20323a00002004418c056a20313a0000200441de046a20173a00002011202541ff017120244108747241ffff0371202341ff017120224108747241107472ad202141ff017120204108747241ffff0371201f41ff0171201e4108747241107472ad42208684370300200441dc046a201941ff01712018410874723b0100200c201d41ff0171201c4108747241ffff0371201b41ff0171201a4108747241107472360200200420583703e0042004203941ff017120384108747241ffff0371203a41ff0171202d4108747241107472ad203041ff0171202f4108747241ffff0371202e41ff017120164108747241107472ad422086843703c0042004202c41ff0171202b4108747241ffff0371202a41ff017120294108747241107472ad202841ff017120274108747241ffff0371202641ff017120034108747241107472ad422086843703c8042004200f3c00df042001200441c0046a10b10420044180026a41086a203b29030037030020044180026a41106a203c29030037030020044180026a41186a203d28020036020020042010370318200420373703102004203537030820042036370300200420042903c00137038002200ea722164180fe0371410876212c200f422088a7222d4180fe03714108762130200da722034180fe03714108762125200e422088a722294180fe037141087621282009a7221e4180fe0371410876211d200d422088a722224180fe037141087621212009422088a7221a4180fe03714108762119200f423888a7212e200f423088a7212f200e423888a72126200e423088a72127200d423888a7211f200d423088a72120200e422086220e423888a7212a200e423088a7212b2009423888a721172009423088a72118200d422086220d423888a72123200d423088a7212420094220862209423888a7211b2009423088a7211c0c010b20044180026a41086a200429036837030020044180026a41106a200429037037030020044180026a41186a20042802783602002004200f37030020042004290360370380022004200e3703082004200d37031020042009370318200921100b0240024002400240202d41ff017120304108747241ffff0371202f41ff0171202e4108747241107472417f6a220841034b0d0020080e0401000002010b419cf7ca00412841b8a1cc001033000b20044180046a41186a2004290300370300200441a0046a2004290308370300200441a8046a200429031037030020044180046a41106a201e41ff0171201d4108747241ffff0371201c41ff0171201b41087472411074722211ad201a41ff017120194108747241ffff0371201841ff017120174108747241107472ad422086843703002004201641ff0171202c4108747241ffff0371202b41ff0171202a4108747241107472220cad202941ff017120284108747241ffff0371202741ff0171202641087472411074722208ad42208684370380042004200341ff017120254108747241ffff0371202441ff017120234108747241107472ad202241ff017120214108747241ffff0371202041ff0171201f4108747241107472220bad4220868437038804200420042903183703a00320042004280280023602a803200441c0046a41086a20153a0000200441c0046a41096a20042f01a0013b0000200441cb046a200441a2016a2d00003a0000200441c0046a41106a2013360200200441cc046a2014360200200420073602c404200420123602c004200441d4046a20042903e003370200200441dc046a200441e0036a41086a290300370200200441c0046a41246a200441e0036a41106a290300370200200441ec046a200441e0036a41186a280200360200200441c0006a41086a410136020020044101360240200420063a005c2004200441dc006a360244200441c0046a200441c0006a10b40602400240200841244b0d0020044180046a41096a210b0c010b201121080b200441c0006a41086a20083602002004200b3602442004200c360240200441c0046a200441c0006a10b4062000428080808010370200200041086a20042903c004370200200041106a200441c0046a41086a290300370200200041186a200441c0046a41106a290300370200200041206a200441c0046a41186a290300370200200041286a200441c0046a41206a290300370200200041306a200441c0046a41286a290300370200200041386a20042903a003370200200041c0006a200441a0036a41086a28020036020020042802840441244d0d012004418c046a28020010290c010b2010a7210c20044180046a41186a2004290300370300200441a0046a2004290308370300200441a8046a200429031037030020044180046a41106a201e41ff0171201d4108747241ffff0371201c41ff0171201b41087472411074722201ad201a41ff017120194108747241ffff0371201841ff017120174108747241107472ad422086843703002004201641ff0171202c4108747241ffff0371202b41ff0171202a41087472411074722211ad202941ff017120284108747241ffff0371202741ff0171202641087472411074722208ad42208684370380042004200341ff017120254108747241ffff0371202441ff017120234108747241107472ad202241ff017120214108747241ffff0371202041ff0171201f4108747241107472220bad42208684370388042004200428021c3602a00320042004290380023702a403200441c0046a41086a20153a0000200441c0046a41096a20042f01a0013b0000200441cb046a200441a2016a2d00003a0000200441c0046a41106a2013360200200441cc046a2014360200200420073602c404200420123602c004200441d4046a20042903e003370200200441dc046a200441e0036a41086a290300370200200441c0046a41246a200441e0036a41106a290300370200200441ec046a200441e0036a41186a280200360200200441c0006a41086a410136020020044101360240200420063a005c2004200441dc006a360244200441c0046a200441c0006a10b40602400240200841244b0d0020044180046a41096a210b0c010b200121080b200441c0006a41086a20083602002004200b36024420042011360240200441c0046a200441c0006a10b40620004104360204200041086a20042903c004370200200041106a200441c0046a41086a290300370200200041186a200441c0046a41106a290300370200200041206a200441c0046a41186a290300370200200041286a200441c0046a41206a290300370200200041306a200441c0046a41286a290300370200200041386a200c3602002000413c6a20042903a003370200200041c4006a200441a0036a41086a2802003602002000410036020020042802840441244d0d002004418c046a28020010290b20042d00b4024102460d0120042802b00241244d0d01200441b8026a2802001029200a10290c050b20044180036a410c6a200441e0026a41086a280200360200200441003a008003200420042903e00222093702840302402009a70d00419897c800412f41b8a1cc001033000b20004101360204200020042f01a0013b0011200041106a20153a00002000410c6a2007360200200041086a2012360200200041186a2013360200200041146a20143602002000411c6a20042903e003370200200041136a200441a2016a2d00003a0000200041246a200441e0036a41086a2903003702002000412c6a200441e0036a41106a290300370200200041346a200441e0036a41186a28020036020020004100360200200041c0006a20044180036a410472220441086a280200360200200041386a20042902003702000b200a10290c030b0240200a0d00419897c800412f41b8a1cc001033000b200441003a00c404200441003602c004200441c0046a4180a6cc004180a6cc0010b00620044180046a41286a200441c0046a41286a280200220636020020044180046a41206a200441c0046a41206a290300220d37030020044180046a41186a200441c0046a41186a290300220e37030020044180046a41106a200441c0046a41106a290300220f37030020044180046a41086a200441c0046a41086a2903002210370300200420042903c004223737038004200041086a410036020020004280808080103702002000410c6a2037370200200041146a20103702002000411c6a200f370200200041246a200e3702002000412c6a200d370200200041346a20063602002000413c6a2009370200200041386a200a3602000b200710290c010b2000428080808030370200200041106a20093702002000410c6a200a360200200041086a20073602000b2002280200417e6a4103490d00200210a706200524000f0b200524000bc90301097f230041106b2202240020002001280200220320002802006a41017110d3070240024002400240024020030d00200141086a2802002104410021030c010b200041046a280200220321050240200341244d0d00200041106a28020021050b200141086a2802002204450d012005417f6a210520012802042d0000210602400240200341244b0d00200041096a21070c010b200041106a28020021032000410c6a28020021070b200320054d0d02200720056a220320032d00002006410f71723a0000410121030b0240200320044f0d00200420036b2105200041096a2108200041106a2109200041046a210a200128020420036a2103034020032d000021060240200028021020002802042201200141244b22071b22042001412420071b470d002002200a410110d207024020022802004101470d00200241086a2802000d0641a4a1cc00411141b8a1cc001033000b200028020421010b02400240200141244b0d0020082101200a21070c010b200028020c2101200921070b2007200441016a360200200120046a20063a0000200341016a21032005417f6a22050d000b0b200241106a24000f0b4100410041eca6cc001036000b2005200341dca6cc001036000b1030000bdd0801087f230041d0026b2204240002400240024002400240024002400240024020022802004101470d00200241086a280200210520022802042102200441b0016a41186a200141186a290000370300200441b0016a41106a200141106a290000370300200441b0016a41086a200141086a290000370300200420012900003703b001200441d0016a200441b0016a20022005200310b20620042802d401210120042802d0012102200441d8006a200441d0016a41086a220541d40010e4071a20024101460d03200441046a200441d8006a41d40010e4071a200420013602d4012005200441046a41d40010e4071a41002102200441003a00d0012003200441d0016a10a90621010c010b2002280204210302400240200241086a28020022024120460d00200441d0016a41086a200141086a290000370300200441d0016a41106a200141106a290000370300200441d0016a41186a200141186a290000370300200420012900003703d0012002417f4c0d050240024020020d0041002101410121060c010b200210272206450d07200221010b0240024020012002490d00200121050c010b200141017422052002200520024b1b22054100480d08024020010d002005102722060d010c0b0b20012005460d00200620012005102b2206450d0a0b20062003200210e4072103413010272201450d09200141043a0000200120042903d001370001200120042f00043b00212001200236002c2001200536002820012003360024200141096a200441d8016a290300370000200141116a200441e0016a290300370000200141196a200441e8016a290300370000200141236a200441066a2d00003a0000410121020c010b200441046a41026a200341026a2d00003a0000200441d0016a41086a2003410f6a290000370300200441e0016a200341176a290000370300200441e8016a2003411f6a2d00003a0000200420032f00003b0104200420032900073703d00120032800032101410021020b200441b0016a41026a2203200441046a41026a22052d00003a0000200441d8006a41086a2206200441d0016a41086a2207290300370300200441d8006a41106a2208200441d0016a41106a2209290300370300200441d8006a41186a220a200441d0016a41186a220b2d00003a0000200420042f01043b01b001200420042903d00137035820020d01200520032d00003a00002007200629030037030020092008290300370300200b200a2d00003a0000200420042f01b0013b0104200420042903583703d001410121020b200020023a000420004100360200200041056a20042f01043b0000200041086a20013602002000410c6a20042903d001370200200041076a200441066a2d00003a0000200041146a200441d0016a41086a2903003702002000411c6a200441e0016a290300370200200041246a200441e8016a2802003602000c050b20004101360200200020013602040c040b20004101360200200020013602040c030b1038000b1039000b1032000b200441d0026a24000f0b1030000b800d01027f230041b0046b22002400024041c004102722010d001030000b200141023a00002001200029008d04370001200141023a0024200120002900ea03370025200141096a2000418d046a41086a290000370000200141116a2000418d046a41106a290000370000200141196a2000418d046a41186a290000370000200141206a2000418d046a411f6a2800003600002001412d6a200041ea036a41086a290000370000200141356a200041ea036a41106a2900003700002001413d6a200041ea036a41186a290000370000200141c4006a200041ea036a411f6a280000360000200141023a0048200141023a006c200120002900c703370049200141d1006a200041c7036a41086a290000370000200141d9006a200041c7036a41106a290000370000200141e1006a200041c7036a41186a290000370000200141e8006a200041c7036a411f6a280000360000200120002900a40337006d200141f5006a200041a4036a41086a290000370000200141fd006a200041a4036a41106a29000037000020014185016a200041a4036a41186a2900003700002001418c016a200041a4036a411f6a280000360000200141023a009001200141023a00b40120012000290081033700910120014199016a20004181036a41086a290000370000200141a1016a20004181036a41106a290000370000200141a9016a20004181036a41186a290000370000200141b0016a20004181036a411f6a280000360000200120002900de023700b501200141bd016a200041de026a41086a290000370000200141c5016a200041de026a41106a290000370000200141cd016a200041de026a41186a290000370000200141d4016a200041de026a411f6a280000360000200141023a00d801200141f8016a200041bb026a411f6a280000360000200141f1016a200041bb026a41186a290000370000200141e9016a200041bb026a41106a290000370000200141e1016a200041bb026a41086a290000370000200120002900bb023700d901200141023a00fc012001419c026a20004198026a411f6a28000036000020014195026a20004198026a41186a2900003700002001418d026a20004198026a41106a29000037000020014185026a20004198026a41086a29000037000020012000290098023700fd01200141023a00a002200141c0026a200041f5016a411f6a280000360000200141b9026a200041f5016a41186a290000370000200141b1026a200041f5016a41106a290000370000200141a9026a200041f5016a41086a290000370000200120002900f5013700a102200141023a00c402200141e4026a200041d2016a411f6a280000360000200141dd026a200041d2016a41186a290000370000200141d5026a200041d2016a41106a290000370000200141cd026a200041d2016a41086a290000370000200120002900d2013700c502200141023a00e80220014188036a200041af016a411f6a28000036000020014181036a200041af016a41186a290000370000200141f9026a200041af016a41106a290000370000200141f1026a200041af016a41086a290000370000200120002900af013700e902200141023a008c03200141ac036a2000418c016a411f6a280000360000200141a5036a2000418c016a41186a2900003700002001419d036a2000418c016a41106a29000037000020014195036a2000418c016a41086a2900003700002001200029008c0137008d03200141023a00b003200141d0036a200041e9006a411f6a280000360000200141c9036a200041e9006a41186a290000370000200141c1036a200041e9006a41106a290000370000200141b9036a200041e9006a41086a290000370000200120002900693700b103200141023a00d403200141f4036a200041c6006a411f6a280000360000200141ed036a200041c6006a41186a290000370000200141e5036a200041c6006a41106a290000370000200141dd036a200041c6006a41086a290000370000200120002900463700d503200141023a00f80320014198046a200041236a411f6a28000036000020014191046a200041236a41186a29000037000020014189046a200041236a41106a29000037000020014181046a200041236a41086a290000370000200120002900233700f903200141023a009c04200141bc046a2000411f6a280000360000200141b5046a200041186a290000370000200141ad046a200041106a290000370000200141a5046a200041086a2900003700002001200029000037009d04200041b0046a240020010b960a02067f057e230041f0006b22032400024002400240024002400240024002400240024002400240200141046a2802002204410174200141086a28020022056b20024d0d0020054101762106200520026a220741017621082007410171450d03200841016a22072006490d05200820044f0d06200128020020066a2108200720066b22014125490d012001417f4c0d07200110272204450d0820042008200110e4071a41012106200121080c020b200420054101762202490d0320012802002101200341003a001420034100360210200341106a200120026a200120046a10b006200341c0006a41286a200341106a41286a2802002201360200200341c0006a41206a200341106a41206a2903002209370300200341c0006a41186a200341106a41186a290300220a370300200341c0006a41106a200341106a41106a290300220b370300200341c0006a41086a200341106a41086a290300220c37030020032003290310220d370340200020054101713602002000200d3702042000410c6a200c370200200041146a200b3702002000411c6a200a370200200041246a20093702002000412c6a20013602000c0a0b200341106a2008200110e4071a2003410c6a41026a200341106a41026a2d00003a0000200341c8006a200341236a290000370300200341d0006a2003412b6a290000370300200341d8006a200341336a2d00003a0000200320032f00103b010c2003200329001b3703402003280013210420032800172108410021060b200341106a41086a220720063a0000200341196a20032f010c3b0000200341106a41106a220620083602002003411c6a2004360200200341246a20032903403702002003411b6a2003410e6a2d00003a00002003412c6a200341c0006a41086a290300370200200341106a41246a200341c0006a41106a2903003702002003413c6a200341c0006a41186a2802003602002003200136021420032005410171360210200341106a200241017110d3070240200341106a41104104200328021441244b1b6a22012802002205450d0020012005417f6a3602000b20002003290310370200200041286a200341106a41286a290300370200200041206a200341106a41206a290300370200200041186a200341106a41186a290300370200200041106a2006290300370200200041086a20072903003702000c080b20082006490d0520042008490d06200128020020066a210402400240200820066b22014125490d002001417f4c0d05200110272202450d0620022004200110e4071a41012104200121060c010b200341106a2004200110e4071a2003410c6a41026a200341106a41026a2d00003a0000200341c8006a200341236a290000370300200341d0006a2003412b6a290000370300200341d8006a200341336a2d00003a0000200320032f00103b010c2003200329001b3703402003280013210220032800172106410021040b2000200136020420002005410171360200200041086a20043a0000200041096a20032f010c3b0000200041106a20063602002000410c6a2002360200200041146a20032903403702002000410b6a2003410e6a2d00003a00002000411c6a200341c0006a41086a290300370200200041246a200341c0006a41106a2903003702002000412c6a200341d8006a2802003602000c070b2002200441c4a0cc00104c000b2006200741d4a0cc00104c000b2007200441d4a0cc00104b000b1038000b1039000b2006200841e4a0cc00104c000b2008200441e4a0cc00104b000b200341f0006a24000bbf06010c7f230041d0006b2202240020002001280200360200200141046a280200220321040240200341244d0d00200141106a28020021040b024002400240200441254f0d0041002105410021040c010b41012105200410272206450d010b2002410c6a22074100360200200241086a2006360200200241106a2002290230370300200241186a200241306a41086a290200370300200241206a200241306a41106a290200370300200241286a200241306a41186a280200360200200220053a000420022004360200200220022f004d3b00052002200241cf006a2d00003a000702400240200341244b0d00200141096a21010c010b200141106a28020021032001410c6a28020021010b02402003450d00200241057221082003417f6a210641002105034020012d00002109024002400240024020052004200441244b220a1b220320044124200a1b470d0002400240200a0d004124210b2004210c0c010b2005210c2004210b0b200b200c470d0002400240200c41016a220d200c490d004100210b0240200d4102490d00417f200d417f6a6776210b0b200b41016a220c200b490d0002400240200a0d004124210d200421052008210b0c010b2002280208210b2004210d0b2005200c4b0d0102400240200c4125490d00200d200c470d010c040b20044125490d04200241003a00042008200b200510e4071a20022005360200200b1029200228020021040c030b02400240200a0d00200c10272204450d0a2004200b200510e4071a0c010b200b200d200c102b2204450d090b2002200536020c20022004360208200241013a00042002200c3602000c040b41a4a1cc00411141b8a1cc001033000b41e6a1cc00412041b8a1cc001033000b200441244b0d010b20022104200821050c010b20022802082105200721040b2004200341016a360200200520036a20093a00002006450d01200141016a21012006417f6a2106200228020c2105200228020021040c000b0b200041046a22042002290300370200200441286a200241286a280200360200200441206a200241206a290300370200200441186a200241186a290300370200200441106a200241106a290300370200200441086a200241086a290300370200200241d0006a24000f0b1030000b130020004103360204200041f098c8003602000b130020004102360204200041989bc8003602000b0f00200028020020012002107941000b900201027f230041106b22022400200028020021002002410036020c02400240024002402001418001490d002001418010490d012002410c6a21032001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c2002410c6a2103410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c2002410c6a2103410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b2000200320011079200241106a240041000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41a8a3c800200241086a10372101200241206a240020010b13002000410036020420004180a6cc003602000b130020004101360204200041f4a6c8003602000bca0603027f017e057f23004180016b2202240041b1dcc900ad4280808080f00084100122032900002104200241306a41086a200341086a290000370300200220043703302003102941f5a7c800ad4280808080a00284100122032900002104200241d0006a41086a200341086a2900003703002002200437035020031029200220013602742002200241f4006aad4280808080c000841002220329000037037820031029200241146a200241f8006a3602002002200241f8006a41086a36020c2002200241f4006a3602102002200241f8006a360208200241c0006a200241086a107502400240024002402002280248220541206a2206417f4c0d00200228024021070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290330370000200341086a200241306a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290350370010200341186a200241d0006a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a02402002280244450d00200710290b200241086a2003200610c306200241d8006a2201200241086a410c6a290200370300200241e0006a2206200241086a41146a290200370300200241e8006a2205200241086a411c6a290200370300200241d0006a41206a200241086a41246a2802003602002002200229020c3703500240024020022802084101460d00200041003602000c010b20004101360200200020022903503702042000410c6a2001290300370200200041146a20062903003702002000411c6a2005290300370200200041246a200241f0006a2802003602000b02402008450d00200310290b20024180016a24000f0b1038000b1039000b1032000b1030000b9f0501057f230041d0006b2205240002400240024002402004417f4c0d000240024020040d0041002106410121070c010b200410272207450d02200421060b0240024020062004490d00200621080c010b200641017422082004200820044b1b22084100480d03024020060d002008102722070d010c050b20062008460d00200720062008102b2207450d040b20072003200410e4072107410021060240200141306a2802002004470d000240200128022822062007470d00410121060c010b20072006200410e7074521060b02402008450d00200710290b0240024020060d00200541186a22082004ad4220862003ad841010220641186a290000370300200541106a2207200641106a290000370300200541086a2209200641086a2900003703002005200629000037030020061029200541206a41186a2008290300370300200541206a41106a2007290300370300200541206a41086a2009290300370300200520052903003703200240024020040d0041002106410121070c010b200410272207450d04200421060b0240024020062004490d00200621080c010b200641017422082004200820044b1b22084100480d05024020060d00200810272207450d070c010b20062008460d00200720062008102b2207450d060b20072003200410e40721062005200436024820052008360244200520063602402001200541206a2004200541c0006a10f906200041186a200541186a290300370000200041106a200541106a290300370000200041086a200541086a290300370000200020052903003700000c010b20002001290034370000200041186a200141cc006a290000370000200041106a200141c4006a290000370000200041086a2001413c6a2900003700000b200541d0006a24000f0b1038000b1039000b1032000b1030000b810d04047f017e027f017e230041a0016b2205240002400240024002400240024002400240024002400240200141d8006a2206200141346a412010e707450d00200541106a41186a200641186a290000370300200541106a41106a200641106a290000370300200541106a41086a200641086a290000370300200520062900003703102001200541106a10bc032206450d01200628020c4101480d010b200441046a2206417f4c0d020240024020060d0041012107410021060c010b200610272207450d040b2005410036021820052007360210200520063602140240200641034b0d00200641017422084104200841044b1b22084100480d050240024020060d002008102722070d010c0c0b20062008460d00200720062008102b2207450d0b0b20052008360214200520073602100b20072002360000200541043602182004200541106a10710240024020052802142208200528021822076b2004490d0020052802102106200821020c010b200720046a22062007490d05200841017422022006200220064b1b22024100480d050240024020080d00024020020d00410121060c020b200210272206450d0c0c010b2005280210210620082002460d00200620082002102b2206450d0b0b20052002360214200520063602100b200620076a2003200410e4071a20052001360210200541206a200141e0006a290200370300200541286a200141e8006a290200370300200541306a200141f0006a29020037030020054188a8c80036021420052001290258370318200541003602582005200720046a36025420052006360250200541f0006a200541106a200541d0006a10860602402002450d00200610290b20052802704101470d010240200528027422012d0000220441034b0d00024020040e0408080008080b200141086a280200450d07200141046a28020010290c070b200141286a280200450d06200141246a28020010290c060b200041003602400c070b20052802742204450d0502400240200541f8006a2903002209422088a741044f0d0041012106410021070c010b20042800002107410021060b02402009a7450d00200410290b20060d0520052007360208200541106a41106a200141d8006a220441086a290200370300200541106a41186a200441106a290200370300200541306a200441186a29020037030020054188a8c8003602142005200136021020052004290200370318200542043702542005200541086a360250200541f0006a200541106a200541d0006a108606024020052802704101470d000240200528027422012d0000220441034b0d00024020040e0406060006060b200141086a280200450d05200141046a28020010290c050b200141286a280200450d04200141246a28020010290c040b0240200528027422060d00200041003602400c070b200541f0006a41086a29030021092005200636020820052009422088a7220736020c41002101200541003a009001024002400240034020072001460d01200541f0006a20016a200620016a22042d00003a00002005200441016a3602082005200141016a22043a0090012004210120044120470d000b200541d0006a41086a2201200541f0006a41086a2202290300370300200541d0006a41106a2208200541f0006a41106a2203290300370300200541d0006a41186a220a200541f0006a41186a220b290300370300200520052903703703502005200720046b36020c200541f0006a200541086a1083022005280290012204450d01200541106a41186a2207200a290300370300200541106a41106a220a2008290300370300200541106a41086a22082001290300370300200541106a41286a22012002290300370300200541106a41306a22022003290300370300200541106a41386a2203200b290300370300200520052903503703102005200529037037033020054194016a280200210b200541f0006a41286a290300210c200041386a2003290300370300200041306a2002290300370300200041286a2001290300370300200041206a2005290330370300200041186a2007290300370300200041106a200a290300370300200041086a200829030037030020002005290310370300200041c8006a200c3702002000200b360244200020043602400c020b2005410036020c200141ff0171450d00200541003a0090010b200041003602400b2009a7450d06200610290c060b1038000b1039000b1032000b20011029200041003602400c020b200110290b200041003602400b200541a0016a24000f0b1030000ba60402097f047e230041f0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022040d00200041003602000c010b200341186a28020021052003280214210641002101200341003a0068024002400240034020052001460d01200341c8006a20016a200420016a2d00003a00002003200141016a22023a00682002210120024120470d000b200341286a41186a2201200341c8006a41186a2207290300370300200341286a41106a2208200341c8006a41106a2209290300370300200341286a41086a220a200341c8006a41086a220b29030037030020032003290348370328200520026b41034d0d01200b200a290300220c37030020092008290300220d37030020072001290300220e37030020032003290328220f370348200420026a28000021012000411c6a200e370200200041146a200d3702002000410c6a200c3702002000200f370204200041246a2001360200410121010c020b200141ff0171450d00200341003a00680b4100210120034100360230200342013703282003410d3602242003200341086a3602202003200341286a36026c200341dc006a41013602002003420137024c200341f4eaca003602482003200341206a360258200341ec006a41a8a3c800200341c8006a10371a20033502304220862003350228841008200328022c450d00200328022810290b200020013602002006450d00200410290b200341f0006a24000b8a0201057f024020002802102201450d00200041146a280200220241046a2103200120026a41016a21042002280200417f73418081828478712105200041186a280200210202400340024002402005450d00200521010c010b0340200320044f0d03200241c0016a210220032802002101200341046a220521032001418081828478712201418081828478460d000b2001418081828478732101200521030b2001417f6a2001712105200220016841037641306c6a220141246a280200450d00200128022010290c000b0b02402000280210220341086a200341056a490d00200341016aad42307e422088a71a0b200028021410290b02402000412c6a280200450d00200028022810290b0b8f3d02267f0c7e23002201210220014180056b41607122032400200041186a22012802002104200041146a220528020022062802002107200141043602002005418cc5c00036020020002802102108200041003602102000411c6a42003702002003200036020c2006200841016a22096a210a200641046a2101024002400240024002402007418081828478712205418081828478460d00200541808182847873210b200421050c010b20042105034002402001200a490d00410021070c030b200541c0026a210520012802002107200141046a220c21012007418081828478712207418081828478460d000b200741808182847873210b200c21010b200341c0046a41186a2005200b6841037641d0006c6a220741186a290200370300200341c0046a41106a220d200741106a290200370300200341c0046a41086a220e200741086a290200370300200320072902003703c0042007280220210f20072d00242110200341c0026a41276a2211200741cc006a280000360000200341c0026a41206a2212200741c5006a290000370300200341c0026a41186a2007413d6a290000370300200341c0026a41106a2213200741356a290000370300200341c0026a41086a22142007412d6a290000370300200320072900253703c002200b417f6a200b71210720104102470d010b2000210f0c010b20034180046a41186a2215200341c0046a41186a221629030037030020034180046a41106a2217200d29030037030020034180046a41086a2218200e290300370300200341d8016a41086a22192014290300370300200341d8016a41106a221a2013290300370300200341d8016a41186a221b200341c0026a41186a221c290300370300200341d8016a41206a221d2012290300370300200341d8016a41276a221e2011280000360000200320032903c00437038004200320032903c0023703d801200341c0026a410572210b2000211f0340200341a0016a41186a220c2015290300370300200341a0016a41106a22202017290300370300200341a0016a41086a22212018290300370300200341106a41086a22222019290300370300200341106a41106a2223201a290300370300200341106a41186a2224201b290300370300200341106a41206a2225201d290300370300200341106a41276a2226201e28000036000020032003290380043703a001200320032903d801370310201b200c290300370300201a202029030037030020192021290300370300200320032903a0013703d801200b2003290310370000200b41086a2022290300370000200b41106a2023290300370000200b41186a2024290300370000200b41206a2025290300370000200b41276a2026280000360000200320103a00c4022003200f3602c002201f41c8006a280200210c201f280244211002400240200f41244b0d00200b211f0c010b20032802cc02210f20032802c802211f0b200320032f01ec023b01c8042003200f3602c4042003201f3602c0042010200341d8016a200341c0046a200c28021c110600024020032802c00241244d0d0020032802c80210290b024002402007450d002001210c0c010b034002402001200a490d0041002107200328020c210f0c040b200541c0026a210520012802002107200141046a220c21012007418081828478712207418081828478460d000b20074180818284787321070b2016200520076841037641d0006c6a220141186a290200370300200d200141106a290200370300200e200141086a290200370300200320012902003703c0042001280220210f20012d002421102011200141cc006a2800003600002012200141c5006a290000370300201c2001413d6a2900003703002013200141356a29000037030020142001412d6a290000370300200320012900253703c0022007417f6a2007712107024020104102470d00200c2101200328020c210f0c020b201520162903003703002017200d2903003703002018200e29030037030020192014290300370300201a2013290300370300201b201c290300370300201d2012290300370300201e2011280000360000200320032903c00437038004200320032903c0023703d801200328020c211f200c21010c000b0b02400340024002402007450d002007210b0c010b03402001200a4f0d03200541c0026a210520012802002107200141046a220c21012007418081828478712207418081828478460d000b200741808182847873210b200c21010b200b417f6a200b7121072005200b6841037641d0006c6a220c28022041244d0d00200c28022810290c000b0b4100210102402008450d00200641ff01200841056a10e6071a2008210120084108490d00200941037641076c21010b20002008360210200041206a41003602002000411c6a2001360200200041186a2004360200200041146a200636020002400240024002400240200f2d00504101460d00200f41d4006a28020021010240200f41c0006a220c28020022072007417f6a200f41386a220a2802002205200f41346a220b2802006b716b4101470d00200f413c6a108b01200b280200220b200a28020022054d0d00024020052007200b6b2210490d00200f28023c2205200c28020020106b22074102746a2005200b4102746a201041027410e4071a200f41346a2007360200200f41386a28020021050c010b200f28023c220b20074102746a200b200541027410e4071a200f41386a2205200528020020076a22053602000b200a200c280200417f6a200541016a71360200200f413c6a28020020054102746a2001360200024002400240024002400240024002400240024002400240200f41306a280200220520014d0d00200f280228200141fc006c6a22012902102127200120032903d00237021020012902082128200120032903c802370208200341003a00c002200341003602c40220012902002129200120032903c002370200200141186a2205290200212a200520032903d802370200200341c0006a41086a2205200141e8006a290200370300200341c0006a41106a2207200141f0006a290200370300200341c0006a41186a220a200141f8006a280200360200200320273703b001200320283703a801200320293703a001200320012902603703402003202a3703b8012001290240212b200141c8006a290200212c200141d0006a290200212d200141d8006a290200212e2001290220212f200141286a2902002130200141306a29020021312003200141386a290200223237039801200320313703900120032030370388012003202f370380012003202e3703782003202d3703702003202c3703682003202b37036002402029a741ff01714101470d00200341d8016a41176a220c20032900b8012229370000200341d8016a41106a220b20032900b1012227370300200341d8016a41086a221020032900a9012228370300200f28024c220120032900a101222a3700002001202fa722083a001f200141086a2028370000200141106a2027370000200141176a20293700002003202a3703d801200341c0026a41d8006a202e370300200341c0026a41d0006a202d370300200341c0026a41c8006a202c37030020034180036a202b370300200341fc026a200328029c01360200200341f4026a200329029401370200200341ec026a200329028c0137020020032003290284013702e402200341a0036a2003290340370300200341c0026a41e8006a2005290300370300200341c0026a41f0006a2007290300370300200341c0026a41f8006a200a280200360200200341c9026a2010290300370000200341d1026a200b290300370000200341c0026a41186a200c290000370000200320032903d8013700c102200341e0026a20083a0000200341013a00c002200f41286a200341c0026a10a9062101200328020c220341003a0050200341d4006a20013602000c0d0b2027a721072028a721052027422088a7210a2028422088a721012003410036028402200341003a00dc01200341003602d80120034188026a41106a200328027836020020034188026a41086a200329037037030020032003290368370388022032422088a721172032a72114024002400240024002402029422088a70e050102030400010b200341e0026a2030370300200341d8026a202f370300200341d0026a202a370300200341cc026a200a360200200341c8026a2007360200200341e8026a2031370300200320053602c002200320013602c40202400240200141244b0d00200341c9026a210a0c010b202aa721010b2005410176210b0240024020054101710d002001200b490d0741002107410021080c010b2001200b4d0d0741012108200a200b6a2d0000410f712107200b41016a210b0b200141017420056b220541ffff03200541ffff03491b210f2001200b6b210c200a200b6a210b02402017410020171b22100d00200f41017641036a22011027220a450d084100210520034100360218200320013602142003200a3602102003200f3602c404200341013b01c004200341c0046a200341106a10f40220080d0b410021010c0e0b200f41017641036a22011027220a450d074100210520034100360218200320013602142003200a3602102003200f3602c40420034181023b01c004200341c0046a200341106a10f40220080d0b410021010c0c0b4101210a410110272207450d06200741003a0000410121010c0e0b200341e0026a2030370300200341d8026a202f370300200341d0026a202a370300200341cc026a200a360200200341c8026a2007360200200341e8026a2031370300200320053602c002200320013602c40202400240200141244b0d00200341c9026a210a0c010b202aa721010b2005410176210702400240200541017122050d0020012007490d08410021054100210c0c010b200120074d0d08200a20076a2d0000410f71210c200741016a21070b200341186a200120076b3602002003200c3a0011200320053a00102003200a20076a360214200320032f0180043b0112200341c0046a200341106a10a506202ba72201200341c0046a10710240024020032802c404220c20032802c80422056b2001490d0020032802c0042107200c210a0c010b200520016a22072005490d13200c410174220a2007200a20074b1b220a4100480d1302400240200c0d000240200a0d00410121070c020b200a10272207450d140c010b20032802c0042107200c200a460d002007200c200a102b2207450d130b2003200a3602c404200320073602c0040b200720056a2014200110e4071a02402017450d00201410290b024020032802c40241244d0d0020032802cc0210290b200520016a21010c0d0b200341e0026a2030370300200341d8026a202f370300200341d0026a202a370300200341cc026a200a360200200341c8026a2007360200200341e8026a2031370300200320053602c002200320013602c40202400240200141244b0d00200341c9026a210a0c010b202aa721010b200320053602e803200320013602e4032003200a3602e00320034180046a200341e0036a10a606200341d8016a200341e0036a410020011091042101200328020c2105200341c0046a41086a202b370300200341c0046a41106a200329038802370300200341d8046a20034188026a41086a290300370300200341e0046a20034188026a41106a280200360200200320323703c004200341106a2005200341c0046a200341d8016a109204200341d8016a2001109304419cf7ca00412841b8a1cc001033000b419cf7ca00412841b8a1cc001033000b20012005418095c8001036000b200b200141b09fcc00104c000b200b200141c09fcc001036000b1039000b2007200141b09fcc00104c000b2007200141c09fcc001036000b410121010c020b410121010b03400240024020010e020001010b02402005200c490d00200341106a21010c040b200b20056a2d00002107200541016a2105410121010c010b0240200328021822012003280214470d00200141016a220a2001490d092001410174220f200a200f200a4b1b220a4100480d090240024020010d000240200a0d004101210f0c020b200a1027220f450d0a0c010b2003280210210f2001200a460d00200f2001200a102b220f450d090b2003200a3602142003200f3602100b200328021020016a20073a00002003200141016a360218410021010c000b0b03400240024020010e020001010b02402005200c490d00200341106a21010c030b200b20056a2d00002107200541016a2105410121010c010b0240200328021822012003280214470d00200141016a220a2001490d082001410174220f200a200f200a4b1b220a4100480d080240024020010d000240200a0d004101210f0c020b200a1027220f0d010c090b2003280210210f2001200a460d00200f2001200a102b220f450d080b2003200a3602142003200f3602100b200328021020016a20073a00002003200141016a360218410021010c000b0b200341d0036a41086a200141086a2802002213360200200320012902003703d0030240201320032802d403470d00201341016a22012013490d06201341017422052001200520014b1b22014100480d060240024020130d00024020010d00410121050c020b200110272205450d070c010b20032802d003210520132001460d00200520132001102b2205450d060b200320013602d403200320053602d0030b20032802d003220620136a41003a0000200320032802d80341016a22013602d8030240200120032802d403470d00200141016a22052001490d06200141017422072005200720054b1b22054100480d060240024020010d00024020050d00410121060c020b200510272206450d070c010b20012005460d00200620012005102b2206450d060b200320053602d403200320063602d0030b200620016a41003a0000200320032802d80341016a22153602d80302402010450d00202b422088a72201200341d0036a10710240024020032802d403220720032802d80322056b2001490d0020032802d00321060c010b200520016a220a2005490d072007410174220c200a200c200a4b1b220a4100480d070240024020070d000240200a0d00410121060c020b200a10272206450d080c010b20032802d00321062007200a460d0020062007200a102b2206450d070b2003200a3602d403200320063602d0030b200620056a2010200110e4071a2003200520016a22153602d8030b0240024002400240201441c0046a22122014470d0041002110410021010c010b200341106a4101722107200341c0046a410172211b200341c9026a211820034180046a41017221054100210b20142101410021104101210f024002400340200341023a00c0042001290200212920032903d804212720032903d004212820032903c804212f200120032903c0043702002001290208212a2001202f3702082001290210212f20012028370210200141186a220a2902002128200a202737020020032028370398042003202f370390042003202a370388042003202937038004200141206a280200210d200341c0046a41176a220a200541176a290000370000200341c0046a41106a2208200541106a290000370300200341c0046a41086a2219200541086a290000370300200320052900003703c00402402029a7220e41ff0171221a4103470d0020104180fe037141087621010c050b200341e0036a41176a220c200a290000370000200341e0036a41106a221f2008290300370300200341e0036a41086a20192903002229370300200320032903c00422273703e00320034180046a41176a2211200c29000037000020034180046a41106a220a201f29030037030020034180046a41086a220c20293703002003202737038004024002400240201a4102470d00200341023a001020034180046a41186a200741186a290000370300200a200741106a290000370300200c200741086a29000037030020032007290000370380044100211a0c010b0240024020032802c402221a41244b0d002018211f0c010b20032802d002211a20032802cc02211f0b200320032802c0023602b8042003201a3602b4042003201f3602b004200341d8016a200341b0046a4101200b109104211a200328020c211f201b200329038004370000201b41086a200c290300370000201b41106a200a290300370000201b41176a20112900003700002003200e3a00c0042003200d3602e004200341106a201f200341c0046a200341d8016a109204200341d8016a201a10930420032d0010221a4103460d0120034180046a41186a221f200741186a290000370300200a200741106a290000370300200c200741086a2900003703002003200729000037038004024002400240201a410371417f6a220d41014b0d004100211a200d0e020103010b4120200341d0036a10710240024020032802d403221920032802d80322086b4120490d0020032802d00321060c010b200841206a221a2008490d1020194101742206201a2006201a4b1b221a4100480d100240024020190d000240201a0d00410121060c020b201a10272206450d110c010b20032802d00321062019201a460d0020062019201a102b2206450d100b2003201a3602d403200320063602d0030b200620086a2219200329038004370000201941186a201f290300370000201941106a200a290300370000201941086a200c290300370000200841206a21150c010b2003280234211a200341c0046a41186a201f2903003703002008200a2903003703002019200c29030037030020032003290380043703c004201a41214f0d04201a200341d0036a10710240024020032802d403220c20032802d803220a6b201a490d0020032802d00321060c010b200a201a6a2208200a490d0f200c41017422192008201920084b1b22084100480d0f02400240200c0d00024020080d00410121060c020b200810272206450d100c010b20032802d0032106200c2008460d002006200c2008102b2206450d0f0b200320083602d403200320063602d0030b2006200a6a200341c0046a201a10e4071a200a201a6a21150b200320153602d803200f211a0b200b41016a210b200f410174210f201a2010722110200141246a22012012460d030c010b0b20104180fe037141087621010c040b201a412041a4e5c300104b000b20104180fe037141087621010b200341033a008004200341d7046a200329009804370000200341d0046a200329009104370300200341c8046a20032900890437030020032003290081043703c0040b200341033a00100b201341026a21052013417d4b0d020240201520054f0d002005201541b4e5c300104b000b200620136a220520013a0001200520103a000020032802d803210120032802d403210a20032802d003210702402017450d00202ba7450d00201710290b2014102920032802c40241244d0d0020032802cc0210290b200328020c220541c8006a280200210c20052802442105200341106a41086a41002802b0a140360200200341002902a8a140370310200341c0026a2005200341106a20072001200c280214110500200328020c220128024c220520032903c002370000200541086a200341c0026a41086a290300370000200541106a200341c0026a41106a290300370000200541186a200341c0026a41186a2903003700002001200128027441016a360274200128024c220541186a2900002129200541106a2900002127200541086a2900002128200141d1006a2005290000370000200141013a0050200141d9006a2028370000200141e1006a2027370000200141e9006a20293700000240200a450d00200710290b20032802d80141244d0d00200341e0016a28020010290b0240200041306a2802002203450d0020002802282201200341fc006c6a2107034002400240200141246a2203200141046a20012d00001b2201280200220541034b0d0002400240024020050e0404000102040b0240200128020841244d0d00200128021010290b200141386a280200450d03200128023410290c030b200128020841244d0d02200128021010290c020b2001280204102920012802082205450d012001410c6a280200450d01200510290c010b0240200128020841244d0d00200128021010290b2001280234102920012802382205450d002001413c6a280200450d00200510290b200341d8006a22012007470d000b0b02402000412c6a2802002201450d00200141fc006c450d00200028022810290b200041c0006a280200210102400240200041386a2802002203200041346a28020022054f0d00200120054f0d014189a7c700411c41b8a1cc001033000b20012003490d020b0240200141ffffffff0371450d002000413c6a28020010290b024020002802102205450d002000280214220341046a2101200520036a41016a21072003280200417f7341808182847871210a200028021821030240034002400240200a450d00200a21050c010b0340200120074f0d03200341c0026a210320012802002105200141046a220a21012005418081828478712205418081828478460d000b2005418081828478732105200a21010b2005417f6a200571210a200320056841037641d0006c6a220528022041244d0d00200528022810290c000b0b02402000280210220141086a200141056a490d00200141016aad42d0007e422088a71a0b200028021410290b200224000f0b2013200541b4e5c300104c000b20032001418ca8c700104b000b1030000b1032000bc00202027f017e230041106b220224002002200028023036020020012002410410720240412010272203450d0020032000290038370000200341186a200041d0006a290000370000200341106a200041c8006a290000370000200341086a200041c0006a290000370000200120034120107220031029024020002d0058220341024b0d00024002400240024020030e03000102000b200241003a00000c020b200241013a00000c010b200241023a00000b20012002410110720b200220002802343602002001200241041072200029030021042002200041086a290300370308200220043703002001200241101072200029031021042002200041186a290300370308200220043703002001200241101072200029032021042002200041286a290300370308200220043703002001200241101072200241106a24000f0b1039000b130020004104360204200041e0a8c8003602000b3400200041e0a7c80036020420004100360200200041146a4102360200200041106a41f0b4c800360200200041086a42093702000bac0402067f027e230041106b220324000240024002400240200141306c4104722204417f4c0d00200410272205450d012003410036020820032004360204200320053602002001200310710240024020010d002003280208210120032802042105200328020021060c010b2000200141306c6a2107200328020021062003280204210520032802082101034002400240200520016b4120490d00200141206a2104200521080c010b200141206a22042001490d05200541017422082004200820044b1b22084100480d05024020050d00024020080d00410121060c020b2008102722060d010c070b20052008460d00200620052008102b2206450d060b200620016a22012000290000370000200141186a200041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200041286a2903002109200041206a290300210a02400240200820046b4110490d00200441106a2101200821050c010b200441106a22012004490d05200841017422052001200520014b1b22054100480d05024020080d00024020050d00410121060c020b200510272206450d070c010b20082005460d00200620082005102b2206450d060b200620046a220420093700082004200a3700002007200041306a2200470d000b2003200536020420032001360208200320063602000b20022902002001ad4220862006ad84100302402005450d00200610290b200341106a24000f0b1038000b1039000b1032000b1030000b130020004101360204200041c4bbc8003602000b3400200041eea1c80036020420004100360200200041146a4105360200200041106a418cbdc800360200200041086a420f3702000b130020004102360204200041a4c2c8003602000b2d01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241e5003600000b13002000410136020420004194c5c8003602000b3400200041f182cc0036020420004100360200200041146a4103360200200041106a41bcc6c800360200200041086a420c3702000b3400200041cdcac80036020420004100360200200041146a4101360200200041106a41e0cac800360200200041086a42123702000b130020004102360204200041e4cbc8003602000bb908030a7f027e017f23004180016b22022400200241106a22034200370300200241086a42003703002002411c6a22044180023b0100200241186a22054180e8922636020020024200370300200241013602680240024002400240411810272206450d002002420137027420022006360270200241f0006a41004101108f01200228027022072002280278220841186c6a2206200329030037030820062002290308370300200620022d001d3a0015200620042d00004100473a001420062005280200360210200841016a21062002280274210902402002280268220341044d0d00200341186c450d00200228020410290b200641186c4104722203417f4c0d01200310272204450d0020024100360208200220033602042002200436020020062002107102402006450d002007200641186c6a210a200228020421042002280208210b200721030340200341086a290300210c2003290300210d024002402004200b6b4110490d00200b41106a210620022802002105200421080c010b200b41106a2206200b490d05200441017422052006200520064b1b22084100480d050240024020040d00024020080d00410121050c020b2008102722050d010c080b2002280200210520042008460d00200520042008102b2205450d070b20022008360204200220053602000b2005200b6a2204200c3700082004200d37000020022006360208200341106a28020021040240200820066b41034b0d00200641046a220b2006490d052008410174220e200b200e200b4b1b220b4100480d050240024020080d000240200b0d00410121050c020b200b10272205450d080c010b2008200b460d0020052008200b102b2205450d070b2002200b360204200220053602000b200520066a20043600002002200641046a2204360208200341146a2d0000210802400240200228020422062004460d00200228020021050c010b200441016a22062004490d05200441017422052006200520064b1b22064100480d050240024020040d0041002104024020060d00410121050c020b200610272205450d080c010b2002280200210520042006460d00200520042006102b2205450d070b20022006360204200220053602000b200520046a20083a00002002200441016a2208360208200341156a2d0000210b0240024020062008460d0020062104200821060c010b200641016a22042006490d05200641017422082004200820044b1b22044100480d050240024020060d0041002106024020040d00410121050c020b200410272205450d080c010b20062004460d00200520062004102b2205450d070b20022004360204200220053602000b200520066a200b3a00002002200641016a220b360208200341186a2203200a470d000b0b20002002290300370200200041086a200241086a28020036020002402009450d00200941186c450d00200710290b20024180016a24000f0b1039000b1038000b1032000b1030000b3501017f02404110102722020d001039000b20024200370008200242c0843d370000200042908080808002370204200020023602000b340020004188a2c80036020420004100360200200041146a4101360200200041106a41d4cec800360200200041086a42183702000ba30301067f230041106b22032400024020014105744104722204417f4c0d000240200410272205450d002003410036020820032004360204200320053602002001200310710240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020002101024002402006200522046b4120490d00200441206a21050c010b024002400240200441206a22052004490d00200641017422002005200020054b1b22004100480d000240024020060d00024020000d00410121070c020b2000102721070c040b20062000470d020b200021060c030b1032000b200720062000102b21070b2000210620070d001030000b200141206a2100200720046a22042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a290000370000200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100302402006450d00200710290b200341106a24000f0b1039000b1038000bc90402017f037e23004190016b22042400024002400240024020002d00000e03000102000b200441206a41186a200341186a290000370300200441206a41106a200341106a290000370300200441206a41086a200341086a29000037030020042003290000370320200041016a2002ad4220862001ad84200441206a101241014621000c020b200441206a41186a200341186a290000370300200441206a41106a200341106a290000370300200441206a41086a200341086a29000037030020042003290000370320200041016a2002ad4220862001ad84200441206a101741014621000c010b2002ad4220862001ad84101022012900002105200141086a2900002106200141106a2900002107200441186a200141186a290000370300200441106a2007370300200441086a2006370300200420053703002001102941012101200441206a200041016a200410d7064100210020042d00200d00200441c8006a41206a200441c1006a2d00003a0000200441c8006a41186a200441396a290000370300200441c8006a41106a200441316a290000370300200441c8006a41086a200441296a29000037030020042004290021370348200441c8006aad4280808080900484101022002900002105200041086a2900002106200041106a2900002107200441f0006a41186a200041186a290000370300200441f0006a41106a2007370300200441f0006a41086a200637030020042005370370200010290240200441f0006a2003460d00200441f0006a2003412010e7074521010b200121000b20044190016a240020000bcf0303017f017e037f230041d0006b22032400024020012002101e2204422088a72201450d002004a722052d0000220241014b0d002001417f6a210602400240024020020e020001000b41002101200341003a0049200541016a21070240034020062001460d01200341286a20016a200720016a2d00003a00002003200141016a22023a00492002210120024121470d000b200341106a200341316a290000370300200341186a200341396a290000370300200341206a200341c1006a2900003703002003200329002937030820032d0028210241002106200341086a21010c020b200141ff0171450d02200341003a00490c020b2006450d0120052d0001220241034f0d01200341086a41186a200341286a41186a290000370300200341086a41106a200341286a41106a290000370300200341086a41086a200341286a41086a2900003703002003200329002837030841012106200341086a21010b200020023a0001200020063a0000200041026a20012900003700002000410a6a200141086a290000370000200041126a200141106a2900003700002000411a6a200141186a29000037000020051029200341d0006a24000f0b41e891cc00412e200341286a419893cc00419892cc00103a000b130020004102360204200041acd1c8003602000bb50301087f230041106b220424002000280204210520002802002106410021072001a7220821090340200741046a22072009200671220a6a21092005200a6a28000041808182847871220b450d000b02402005200b68410376200a6a20067122076a2c000022094100480d0020052005280200418081828478716841037622076a2d000021090b02402009410171220a450d00200028020c0d0020042000200310da062000280204210520002802002106410021070340200741046a2207200820067122096a2108200520096a28000041808182847871220b450d000b2005200b6841037620096a20067122076a2c00004100480d002005280200418081828478716841037621070b2000200028020c200a6b36020c20002802082109200520076a2001a7411976220a3a00002007417c6a20067120056a41046a200a3a00002009200741306c6a220741286a200241286a290200370200200741206a200241206a290200370200200741186a200241186a290200370200200741106a200241106a290200370200200741086a200241086a290200370200200720022902003702002000200028021041016a360210200441106a24000bb01105097f017e057f037e017f230041c0006b22032400024002400240024002400240024002402001280210220441016a22052004490d00200128020022062107024020064108490d00200641016a41037641076c21070b200520074101764d0d032005200741016a2207200520074b1b22050d01418cc5c0002108410021094104210a4100210b0c020b41b4a1c000411c41d0a1c0001033000b024002400240024020054108490d00200541ffffffff01712005470d02200541037441076e21060c010b200541016a21060b417f2006417f6a6776220b41086a2206200b41056a2205490d04200b41016a2207ad42307e220c422088a70d042006417c712206200ca76a22082006490d042008102722080d011030000b41b4a1c000411c41d0a1c0001033000b200b200741037641076c200b4108491b2109200841ff01200510e60720066a210a20012802002106200128021021040b2001280204220541046a210d200620056a41016a210e2005280200417f7341808182847871210f2002280200211020012802082111024003400240200f0d000340200d200e4f0d03201141c0016a2111200d2802002106200d41046a2205210d2006418081828478712206418081828478460d000b200641808182847873210f2005210d0b2003201041086a29030022122010290300220c852213200c4218898520134210868520134225897c221342a0cbbf9599b5a19f0a7c22142011200f6841037641306c6a221529001885201529000020148542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852015290008201342efcdddd088a580a21e7c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852015290010201342bed0fb8bf894dfa4327c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85420042adfed5e4d485fda8d800420010d507200341086a29030020032903007c2012200c7c85220ca72106410021050340200541046a22052006200b7122076a2106200820076a280000418081828478712202450d000b200f417f6a21050240200820026841037620076a200b7122066a2c00004100480d002008280200418081828478716841037621060b2005200f71210f200820066a200ca741197622053a00002006417c6a200b7120086a41046a20053a0000200a200641306c6a220641286a201541286a290200370200200641206a201541206a290200370200200641186a201541186a290200370200200641106a201541106a290200370200200641086a201541086a290200370200200620152902003702000c000b0b200120043602102001200a360208200041003602002001200920046b36020c2001280204210520012008360204200128020021062001200b3602002006450d040240200641086a200641056a490d00200641016aad42307e422088a71a0b200510290c040b200641016a21074100210541002106024003400240024020054101710d00200620074f0d0320062105200641016a21060c010b200641036a220520064922080d022005200749220b450d022007200641046a20081b2007200b1b21060b200128020420056a220520052802002205410776417f73418182840871200541fffefdfb07726a360200410121050c000b0b20012802042106200128020041016a220541044f0d01200641046a2006200510e5071a0c020b41b4a1c000411c41d0a1c0001033000b200620056a20062800003600000b417f2106024002402001280200220541016a22102005490d00200228020021154100210f0340200f221141016a210f024020112001280204220b6a2d0000418001470d0002400340200341106a201541086a29030022122015290300220c852213200c4218898520134210868520134225897c221342a0cbbf9599b5a19f0a7c22142001280208201141306c6a220d29001885200d29000020148542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85200d290008201342efcdddd088a580a21e7c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85200d290010201342bed0fb8bf894dfa4327c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85420042adfed5e4d485fda8d800420010d5072001280200210841002106200341106a41086a29030020032903107c2012200c7c85220ca7220e21050340200641046a2206200520087122076a2105200b20076a280000418081828478712202450d000b0240200b20026841037620076a20087122066a2c00004100480d00200b280200418081828478716841037621060b20062008200e7122056b201120056b732008714104490d01200b20066a22052d000021072005200ca741197622023a00002006417c6a200871200b6a41046a20023a00000240200741ff01460d002001280208200641306c6a2206290200210c2006200d290200370200200641186a220529020021132005200d41186a2207290200370200200641106a220529020021122005200d41106a2208290200370200200641086a220529020021142005200d41086a220b290200370200200b20143702002008201237020020072013370200200d200c370200200641286a2205290200210c2005200d41286a2207290200370200200629022021132006200d290220370220200d20133702202007200c3702002001280204210b0c010b0b2001280204220520116a41ff013a0000200520012802002011417c6a716a41046a41ff013a00002001280208200641306c6a2206200d290200370200200641086a200d41086a290200370200200641106a200d41106a290200370200200641186a200d41186a290200370200200641206a200d41206a290200370200200641286a200d41286a2902003702000c010b200b20116a200ca741197622063a000020082011417c6a71200b6a41046a20063a00000b200f2010470d000b200128020022064108490d010b200641016a41037641076c21060b200041003602002001200620012802106b36020c0b200341c0006a24000bfc0403027f017e057f230041d0006b2202240041d787cc00ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941b5e0c800ad4280808080f00084100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bfc0403027f017e057f230041d0006b2202240041d787cc00ad4280808080900184100122032900002104200241086a41086a200341086a2900003703002002200437030820031029419588cc00ad4280808080d00084100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000bfc0403027f017e057f230041d0006b2202240041d787cc00ad4280808080900184100122032900002104200241086a41086a200341086a2900003703002002200437030820031029418a88cc00ad4280808080b00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031029200220013602342002200241346aad4280808080c000841002220329000037033820031029200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107502400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610272203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008102722030d010c050b20012008460d00200320012008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d00200320082001102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d00200320012008102b2203450d040b200341206a2007200510e4071a2000200636020820002008360204200020033602000240200228022c450d00200710290b200241d0006a24000f0b1038000b1039000b1032000b1030000b931101147f230041106b2204240041002105024002400240200141014b0d0020010e020201020b20012106034020052006410176220720056a2208200020084102746a28020020024b1b2105200620076b220641014b0d000b0b4100210602400240200020054102746a28020022072002470d00410021090c010b200520072002496a2105410121090b4101210a024002400240200141014b0d0020010e020201020b4100210620012107034020062007410176220820066a220b2000200b4102746a28020020034b1b2106200720086b220741014b0d000b0b0240200020064102746a28020022072003470d004100210a0c010b200620072003496a21060b02400240024002400240024020090d00200a450d06200520014f0d0220052106200321020c010b200a0d05200620014f0d020b200020064102746a200236020020014115490d0302402001410176220541ffffffff03712005470d002005410274220c417f4c0d000240200c1027220d450d004100210520044100360208200442043703002000417c6a210e200041746a210f410421094100210320012110034020102102410021104101210b02402002417f6a2211450d00024002400240024002400240200020114102746a2802002002410274221220006a41786a2802002207490d002002417e6a2113200f20126a210841002110410021060340024020132006470d002002210b0c080b200641016a210620072008280200220b4f210a2008417c6a2108200b2107200a0d000b200641016a210b2006417f7320026a21060c010b200f20126a21082011210602400340024020064101470d00410021060c020b2006417f6a210620072008280200220b49210a2008417c6a2108200b2107200a0d000b0b20022006490d02200220014b0d01200220066b220b410176220a450d00200020064102746a2107200e20126a21080340200728020021132007200828020036020020082013360200200741046a21072008417c6a2108200a417f6a220a0d000b0b024020060d00200621100c050b0240200b41094d0d00200621100c050b200220014b0d02200020064102746a2112034020022006417f6a2210490d040240200220106b220b4102490d00200020064102746a22082802002207200020104102746a221328020022144f0d00201320073602000240200b4103490d002011210a201221072013280208221320144f0d00034020072013360200200741046a21082006200a417f6a220a460d01200741086a211320082107201328020022132014490d000b0b200820143602000b2010450d052012417c6a211220102106200b410a4f0d050c000b0b200220014180cac700104b000b200620024180cac700104c000b20022006417f6a2210490d00200220014190cac700104b000b201020024190cac700104c000b024020032004280204470d00200420034101108d01200428020021092004280208220521030b200920034103746a2206200b360204200620103602002004200541016a220536020820052103024020054102490d00024002400240024002400340024002400240024020092005417f6a4103746a2206280200450d00200541037420096a220b41746a2802002208200628020422074d0d0041022103200541024d0d0a20092005417d6a22124103746a2802042206200720086a4d0d0141032103200541034d0d0a200b41646a280200200620086a4d0d01200521030c0a0b20054103490d012006280204210720092005417d6a22124103746a28020421060b20062007490d010b2005417e6a21120b02402005201241016a22144d0d00200520124d0d022009201241037422156a2205280204221620052802006a22062009201441037422176a22052802002211490d03200620014b0d04200020114102746a22082005280204221341027422076a21052006410274210b02400240200620116b220220136b220620134f0d00200d20052006410274220710e407220a20076a2107024020134101480d0020064101480d00200e200b6a21030240034020032005417c6a22062007417c6a220b200b28020020062802004922021b2802003602002007200b20021b210720082006200520021b22054f0d012003417c6a2103200a2007490d000b0b200428020021090b200a21060c010b200d2008200710e407220620076a21070240024020134101480d00200220134a0d010b20082105200621060c010b2000200b6a2103200621060240034020082005280200220b20062802002202200b200249220b1b3602002006200641046a200b1b2106200841046a2108200541046a2005200b1b220520034f0d01200720064b0d000b0b200821050b20052006200720066b417c7110e4071a2004280208220520124d0d05200920156a2206201620136a36020420062011360200200520144d0d06200920176a2206200641086a20052014417f736a41037410e5071a20042005417f6a220536020820052103200541014d0d070c010b0b2014200541a0cac7001036000b2012200541b0cac7001036000b2011200641c0cac700104c000b2006200141c0cac700104b000b2012200541d0cac7001036000b201420051042000b2010450d050c000b0b1039000b1038000b2005200141a4e0c8001036000b2006200141dcdfc8001036000b0240200428020441ffffffff0171450d00200910290b200c450d01200d10290c010b20014102490d002001417f6a2105200020014102746a21084100210b034002400240024020052206417f6a220520014b0d00200120056b22074102490d02200020064102746a22062802002202200020054102746a2203280200220a4f0d022003200236020020074103490d01200b21072008210220032802082203200a4f0d01034020022206417c6a20033602002007417f6a2207450d02200641046a22022802002203200a4f0d020c000b0b2005200141f0c9c700104c000b2006200a3602000b200b41016a210b2008417c6a210820050d000b0b200441106a24000b130020004105360204200041bce0c8003602000ba46708047f017e017f027e077f017e057f097e23004180036b22012400200141e8006a41186a4200370300200141e8006a41106a22024200370300200141e8006a41086a220342003703002001420037036841fce2c800ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004102920032006290300370300200120012903c002370368418be3c800ad4280808080d001841001220429000021052006200441086a290000370300200120053703c00220041029200220012903c0022205370300200141e0026a41086a2003290300370300200141e0026a41106a2005370300200141e0026a41186a2006290300370300200120012903683703e002200141203602ec012001200141e0026a3602e801200141c0026a200141e0026aad2207428080808080048422081007108b020240024020012802c00222030d0041022106200141023602b4020c010b20012802c40221092001200628020022063602f401200120033602f0010240024020064104490d002001200341046a3602f00120012006417c6a22043602f40120044104490d002003280000210a2001200641786a3602f4012001200341086a3602f0012003280004210b200141e8006a200141f0016a10b2032001280268220c450d00200129026c2105410021060240024020012802f401220d0d000c010b2001200d417f6a220e3602f401200120012802f001220f41016a3602f0010240200f2d00004101460d000c010b200e4104490d002001200d417b6a3602f4012001200f41056a3602f001200f2800012104410121060b200120043602b802200120053702ac022001200c3602a8022001200b3602a4022001200a3602a0020c010b200141003602880220014201370380022001410d3602d4022001200141e8016a3602d002200120014180026a3602fc01200141fc006a41013602002001420137026c200141f4eaca003602682001200141d0026a360278200141fc016a41a8a3c800200141e8006a10371a2001350288024220862001350280028410080240200128028402450d0020012802800210290b410221060b200120063602b4022009450d00200310290b200141e8006a41106a2203200141a0026a41106a2209280200360200200141e8006a41086a220a200141a0026a41086a220b290300370300200120012903a0023703680240024002400240024002400240024020064102460d0020014180026a41106a2003280200220336020020014180026a41086a200a29030022103703002001200129036822053703800220092003360200200b2010370300200141b8026a2004360200200120053703a002200120063602b40202402005a722032000470d00410121030240024020064101460d0020012802a4022106200141e0026a200141a0026a41086a10ef05200141f8006a2006360200200141f4006a200141e0026a41086a280200360200200120012903e00237026c41002103200141e8006a21060c010b20012802a4022106200141e0026a200141a0026a41086a10ef05200141fc006a2006360200200141e8006a41086a20012903e002370300200141f8006a200141e0026a41086a2802003602002001200436026c200141e8006a21060b20062003360200200610e10620012802a00221030b024020012802a40220036a2000470d002001200141a8026a220d36026c20014100360268200141b0026a28020041286c4105722206417f4c0d02200610272203450d03200341013a0000200120063602e402200120033602e002200141013602e80220012802a802210620012802b0022203200141e0026a10710240024020030d0020012802e802210320012802e002210b0c010b2006200341286c6a210c20012802e402210920012802e8022103034002400240200920036b4120490d00200341206a210420012802e002210b2009210a0c010b200341206a22042003490d072009410174220a2004200a20044b1b220a4100480d070240024020090d000240200a0d004101210b0c020b200a1027220b0d010c0d0b20012802e002210b2009200a460d00200b2009200a102b220b450d0c0b2001200a3602e4022001200b3602e0020b200b20036a22032006290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a290000370000200120043602e802200641206a290300210502400240200a20046b4108490d00200441086a2103200a21090c010b200441086a22032004490d07200a41017422092003200920034b1b22094100480d0702400240200a0d00024020090d004101210b0c020b20091027220b450d0d0c010b200a2009460d00200b200a2009102b220b450d0c0b200120093602e4022001200b3602e0020b200b20046a2005370000200120033602e802200c200641286a2206470d000b0b20012802e402210641d3d5c800ad4280808080c002842003ad422086200bad84100302402006450d00200b10290b02402001280268450d00200141f0006a2802002206450d00200641286c450d00200128026c10290b200141e8006a41086a2206200d290000370300200141e8006a41106a2204200d41086a2800003602002001410036026c200141073a0068200141e8006a10cb01200141e8006a41186a220a420037030020044200370300200642003703002001420037036841fce2c800ad4280808080f00184100122092900002105200141c0026a41086a2203200941086a290000370300200120053703c0022009102920062003290300370300200120012903c002370368418be3c800ad4280808080d001841001220929000021052003200941086a290000370300200120053703c00220091029200220012903c002370000200241086a2003290300370000200141e0026a41086a2006290300370300200141e0026a41106a2004290300370300200141e0026a41186a200a290300370300200120012903683703e002200810040c010b200141ac026a2802002206450d00200641286c450d0020012802a80210290b200141e8006a41186a22094200370300200141e8006a41106a220a4200370300200141e8006a41086a220342003703002001420037036841fce2c800ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004102920032006290300370300200120012903c0023703684198e3c800ad4280808080d000841001220429000021052006200441086a290000370300200120053703c00220041029200220012903c002370000200241086a2006290300370000200141e0026a41086a2003290300370300200141e0026a41106a200a290300370300200141e0026a41186a2009290300370300200120012903683703e002200141203602c4022001200141e0026a3602c00220014180026a20081007108b022001280280022206450d05200128028402210402400240024020014180026a41086a2802002209450d0020062d0000220a41034b0d0041002103024002400240200a0e0405000102050b2009417f6a4108490d0220062900012105410121030c040b410221030c020b2009417f6a4108490d0020062900012105410321030c020b200141003602a802200142013703a0022001410d3602d4022001200141c0026a3602d0022001200141a0026a3602f001200141fc006a41013602002001420137026c200141f4eaca003602682001200141d0026a360278200141f0016a41a8a3c800200141e8006a10371a20013502a80242208620013502a002841008024020012802a402450d0020012802a00210290b410421030b0b02402004450d00200610290b2003417f6a220641024b0d0520060e03040503040b1038000b1039000b1032000b2005422088a7210602402005a722032000470d00200141043602682001200636026c200141e8006a10e1060b200620036a2000470d01200141003602a002200141e8006a41186a22094200370300200141e8006a41106a220a4200370300200141e8006a41086a220342003703002001420037036841fce2c800ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004102920032006290300370300200120012903c0023703684198e3c800ad4280808080d000841001220429000021052006200441086a290000370300200120053703c00220041029200220012903c002370000200241086a2006290300370000200141e0026a41086a2003290300370300200141e0026a41106a200a290300370300200141e0026a41186a2009290300370300200120012903683703e002200141e8006a200141a0026a10e2062008200135027042208620012802682206ad8410030240200128026c450d00200610290b2001410236026c200141073a0068200141e8006a10cb010c010b2005422088a7210602402005a722032000470d00200141033602682001200636026c200141e8006a10e1060b200620036a2000470d00200141023602a002200141e8006a41186a22094200370300200141e8006a41106a220a4200370300200141e8006a41086a220342003703002001420037036841fce2c800ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004102920032006290300370300200120012903c0023703684198e3c800ad4280808080d000841001220429000021052006200441086a290000370300200120053703c00220041029200220012903c002370000200241086a2006290300370000200141e0026a41086a2003290300370300200141e0026a41106a200a290300370300200141e0026a41186a2009290300370300200120012903683703e002200141e8006a200141a0026a10e2062008200135027042208620012802682206ad8410030240200128026c450d00200610290b2001410136026c200141073a0068200141e8006a10cb010b200141e8006a41186a22044200370300200141e8006a41106a220d4200370300200141e8006a41086a220342003703002001420037036841eea1c800ad4280808080f001842205100122092900002108200141a0026a41086a2206200941086a290000370300200120083703a0022009102920032006290300370300200120012903a00237036841fda3c800ad4280808080e000841001220929000021082006200941086a290000370300200120083703a00220091029200d20012903a0022208370300200141e0026a41086a220a2003290300370300200141e0026a41106a220b2008370300200141e0026a41186a220c2006290300370300200120012903683703e002200141e0006a200141e0026a412010fc012001280264210f0240200128026022024101470d002007428080808080048410040b20044200370300200d4200370300200342003703002001420037036820051001220929000021052006200941086a290000370300200120053703a0022009102920032006290300370300200120012903a00237036841a8c1c800ad4280808080b001841001220929000021052006200941086a290000370300200120053703a00220091029200d20012903a002370000200d41086a2006290300370000200a2003290300370300200b200d290300370300200c2004290300370300200120012903683703e00202400240200141e0026a10b201220641ff01714102460d0020064101710d010b41041027220a450d01200a4100360200200141e8006a41186a22044200370300200141e8006a41106a22094200370300200141e8006a41086a220342003703002001420037036841eea1c800ad4280808080f0018422051001220b2900002108200141a0026a41086a2206200b41086a290000370300200120083703a002200b102920032006290300370300200120012903a00237036841fda1c800ad4280808080b001841001220b29000021082006200b41086a290000370300200120083703a002200b1029200d20012903a002370000200d41086a220b2006290300370000200141e0026a41086a220c2003290300370300200141e0026a41106a22002009290300370300200141e0026a41186a220e2004290300370300200120012903683703e0022001412036026c2001200141e0026a360268200a4101200141e8006a10a304200a102941041027220a450d01200a41003602002004420037030020094200370300200342003703002001420037036820051001221129000021082006201141086a290000370300200120083703a0022011102920032006290300370300200120012903a0023703684183a4c800ad4280808080c001841001221129000021082006201141086a290000370300200120083703a00220111029200d20012903a002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903683703e0022001412036026c2001200141e0026a360268200a4101200141e8006a10a304200a10292004420037030020094200370300200342003703002001420037036820051001220a29000021082006200a41086a290000370300200120083703a002200a102920032006290300370300200120012903a002370368418fa4c800ad4280808080e000841001220a29000021082006200a41086a290000370300200120083703a002200a1029200d20012903a002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903683703e00220014100360268200742808080808004842208200141e8006aad22104280808080c0008410032004420037030020094200370300200342003703002001420037036820051001220a29000021052006200a41086a290000370300200120053703a002200a102920032006290300370300200120012903a00237036841a8c1c800ad4280808080b001841001220a29000021052006200a41086a290000370300200120053703a002200a1029200d20012903a002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903683703e002200141013a0068200820104280808080108410030b200141e8006a41186a4200370300200141e8006a41106a22124200370300200141e8006a41086a220642003703002001420037036841eea1c800ad4280808080f001841001220329000021052006200341086a290000370300200120053703682003102941fda1c800ad4280808080b00184100122032900002105200141a0026a41086a2204200341086a290000370300200120053703a00220031029201220012903a0022205370300200141e0026a41086a2006290300370300200141e0026a41106a2005370300200141e0026a41186a2004290300370300200120012903683703e002200141e8006a200141e0026a108f03024002402001280268220e0d0041002113200141003602c802200142043703c0024104210e410021110c010b2001200129026c22053702c4022001200e3602c0022005422088a721112005a721130b200141e8006a41186a22094200370300200141e8006a41106a220a4200370300200141e8006a41086a220342003703002001420037036841eea1c800ad4280808080f00184100122042900002105200141a0026a41086a2206200441086a290000370300200120053703a0022004102920032006290300370300200120012903a0023703684183a4c800ad4280808080c001841001220429000021052006200441086a290000370300200120053703a00220041029200d20012903a002370000200d41086a2006290300370000200141e0026a41086a2003290300370300200141e0026a41106a200a290300370300200141e0026a41186a2009290300370300200120012903683703e002200141e8006a200141e0026a108f03024002402001280268220a0d0041002114200141003602880220014204370380024104210a4100210c0c010b2001200129026c2205370284022001200a360280022005422088a7210c2005a721140b0240024002400240024020020d002011450d012011410274200e6a417c6a280200210f0b201141002011419c7f6a22062006201141016a4b1b2215490d01200141003602c8022015450d03200e20154102746a2100200e210203402002280200210b02400240024002400240200c41014b0d0041002106200c0e020201020b41002106200c2103034020062003410176220420066a2209200b200a20094102746a280200491b2106200320046b220341014b0d000b0b200b200a200641027422036a2802002204460d022006200b20044b6a21060c010b410021060b2001200636026841cca4c800412e200141e8006a41fca4c800418ca5c800103a000b200c20064d0d03200a20036a2203200341046a2006417f73200c6a41027410e5071a2001200c417f6a220c36028802200241046a22022000470d000c040b0b4195a4c800412641bca4c8001057000b201520111044000b2006200c1042000b410021064100210b0240201120156b2203450d0002402015450d00200e200e20154102746a200341027410e5071a0b200120033602c8022003210b0b024002400240200c41014b0d00200c0e020201020b41002106200c2103034020062003410176220420066a2209200f200a20094102746a280200491b2106200320046b220341014b0d000b0b0240200f200a20064102746a2802002203460d002006200f20034b6a21060b200c20064f0d002006200c1041000b0240200c2014470d0020014180026a20144101109801200128028002210a0b200a20064102746a220341046a2003200c20066b41027410e5071a2003200f3602002001200c41016a2203360288020240200b2013470d00200141c0026a2013410110980120012802c002210e20012802c802210b0b200e200b4102746a200f3602002001200b41016a220b3602c802024002400240024002400240024002402003450d00200341017621062003410171450d01200320064d0d03200a20064102746a28020021000c020b419ca5c80041c30041b8a1cc001033000b200320064d0d0220032006417f6a22044d0d03200a20044102746a280200200a20064102746a2802006a41017621000b20012802c4022102200141e8006a41186a22094200370300200141e8006a41106a220a4200370300200141e8006a41086a220442003703002001420037036841eea1c800ad4280808080f0018422051001220c2900002108200141a0026a41086a2206200c41086a290000370300200120083703a002200c102920042006290300370300200120012903a00237036841fda1c800ad4280808080b001841001220c29000021082006200c41086a290000370300200120083703a002200c1029200d20012903a002370000200d41086a220f2006290300370000200141e0026a41086a22112004290300370300200141e0026a41106a2215200a290300370300200141e0026a41186a22132009290300370300200120012903683703e0022001412036026c2001200141e0026a360268200e200b200141e8006a10a3040240200241ffffffff0371450d00200e10290b200128028402210e200128028002210220094200370300200a4200370300200442003703002001420037036820051001220c29000021052006200c41086a290000370300200120053703a002200c102920042006290300370300200120012903a0023703684183a4c800ad4280808080c001841001220c29000021052006200c41086a290000370300200120053703a002200c1029200d20012903a002370000200f2006290300370000201120042903003703002015200a29030037030020132009290300370300200120012903683703e0022001412036026c2001200141e0026a36026820022003200141e8006a10a3040240200e41ffffffff0371450d00200210290b200141e8006a41186a22094200370300200141e8006a41106a22044200370300200141e8006a41086a220342003703002001420037036841eea1c800ad4280808080f001841001220a2900002105200141a0026a41086a2206200a41086a290000370300200120053703a002200a102920032006290300370300200120012903a002370368418fa4c800ad4280808080e000841001220a29000021052006200a41086a290000370300200120053703a002200a1029200d20012903a002370000200d41086a2006290300370000200141e0026a41086a220a2003290300370300200141e0026a41106a220c2004290300370300200141e0026a41186a22022009290300370300200120012903683703e0022001200036026820074280808080800484200141e8006aad22164280808080c0008410030240200b41e500470d002009420037030020044200370300200342003703002001420037036841b3e6ca00ad4280808080e000841001220b29000021052003200b41086a29000037030020012005370368200b102941c9e6ca00ad4280808080e000841001220b29000021052006200b41086a290000370300200120053703a002200b1029201220012903a002370000201241086a2006290300370000200a2003290300370300200c200429030037030020022009290300370300200120012903683703e002200141d8006a200141e0026a412010fc010b2009420037030020044200370300200342003703002001420037036841eebec500ad4280808080f0008422081001220929000021052006200941086a290000370300200120053703a0022009102920032006290300370300200120012903a00237036841f0f5c100ad428080808090018422101001220929000021052006200941086a290000370300200120053703a00220091029200420012903a0022205370300200a2003290300370300200c200537030020022006290300370300200120012903683703e002200141e8006a200141e0026a10d001024002402001290368427f7c4201560d00200141e0026a21020c010b20042903002117200141e8006a41186a220a4200370300200141e8006a41106a22094200370300200141e8006a41086a220642003703002001420037036841ccbec500ad42808080809001841001220329000021052006200341086a290000370300200120053703682003102941aafac400ad428080808030841001220b2900002105200141a0026a41086a2203200b41086a290000370300200120053703a002200b1029200920012903a0022205370300200141e0026a41086a220c2006290300370300200141e0026a41106a22022005370300200141e0026a41186a22002003290300370300200120012903683703e002200141c8006a200141e0026a10b501200141386a2001290350420020012802481b221842e807802219420042e807420010d507200a420037030020094200370300200642003703002001420037036820081001220b29000021052003200b41086a290000370300200120053703a002200b102920062003290300370300200120012903a00237036820101001220b29000021052003200b41086a290000370300200120053703a002200b1029200420012903a002370000200441086a2003290300370000200c2006290300370300200220092903003703002000200a290300370300200120012903683703e00220012903382105200141386a41086a2903002108410410272206450d06200620173e0000200641044108102b2206450d06200641013a0004200641084110102b2206450d0620062005201820194298787e7c42ff07837c2210427f20082010200554ad7c501b370005200742808080808004842006ad4280808080d00184100320061029200141e0026a21020b200141e8006a41186a22094200370300200141e8006a41106a22044200370300200141e8006a41086a220342003703002001420037036841e4bec500ad4280808080a0018422051001220a2900002108200141a0026a41086a2206200a41086a290000370300200120083703a002200a102920032006290300370300200120012903a002370368418e9fc400ad4280808080e000841001220a29000021082006200a41086a290000370300200120083703a002200a1029200420012903a0022208370300200141e0026a41086a220a2003290300370300200141e0026a41106a220b2008370300200141e0026a41186a220c2006290300370300200120012903683703e0022002ad4280808080800484220810042009420037030020044200370300200342003703002001420037036820051001220229000021052006200241086a290000370300200120053703a0022002102920032006290300370300200120012903a0023703684198b7c400ad4280808080c001841001220229000021052006200241086a290000370300200120053703a00220021029200420012903a0022205370300200a2003290300370300200b2005370300200c2006290300370300200120012903683703e002200810042009420037030020044200370300200342003703002001420037036841cdcac800ad4280808080a002841001220929000021052006200941086a290000370300200120053703a0022009102920032006290300370300200120012903a00237036841b8cbc800ad42808080809002841001220929000021052006200941086a290000370300200120053703a00220091029200420012903a0022205370300200a2003290300370300200b2005370300200c2006290300370300200120012903683703e002200141206a200141e0026a10d102200141206a41106a290300211a2001290328211b20012802202106200141106a10cf02200141e8006a427f2001290310220520012903187c220820082005541b22054280c0a8ca9a3a20054280c0a8ca9a3a541b2218428090cad2c60e2018428090cad2c60e5622091b2208428090cad2c60e200520091b22057d42002008200554ad7d42808090bbbad6adf00d42004280c0a8ca9a3a420010d2020240024020012802684101460d0020042903002205427f570d00200329030021080c010b42ffffffffffffffffff002105427f21080b200141e8006a200820052008200542808090bbbad6adf00d420010d2020240024020012802684101460d00200141f8006a2903002210427f570d00200141f0006a290300211c0c010b42ffffffffffffffffff002110427f211c0b200141e8006a4204420042808090bbbad6adf00d420042a08d06420010d2020240024020012802684101460d00200141f8006a2903002217427f570d00200141f0006a290300211d0c010b42ffffffffffffffffff002117427f211d0b200141e8006a4208420042808090bbbad6adf00d42004280c8afa025420010d2020240024020012802684101460d00200141f8006a2903002219427f570d00200141f0006a290300211e0c010b42ffffffffffffffffff002119427f211e0b200141e8006a201d20172008200542808090bbbad6adf00d420010d202024020012802684101470d00428080808080808080807f42ffffffffffffffffff00200520178542005322031b21084200427f20031b21170c050b200141f8006a2903002208427f550d03428080808080808080807f42ffffffffffffffffff00200520178542005322031b21084200427f20031b21170c040b2006200341e0a5c8001036000b2006200341f0a5c8001036000b200420034180a6c8001036000b200141f0006a29030021170b200141e8006a201e2019201c201042808090bbbad6adf00d420010d2020240024020012802684101470d00428080808080808080807f42ffffffffffffffffff00201020198542005322031b21054200427f20031b211c0c010b0240200141f8006a2903002205427f550d00428080808080808080807f42ffffffffffffffffff00201020198542005322031b21054200427f20031b211c0c010b200141f0006a290300211c0b201a420020061b2110201b420020061b211902400240201842ff8fcad2c60e560d0042ffffffffffffffffff00428080808080808080807f201042ffffffffffffffffff00428080808080808080807f200820057d2017201c54ad7d22184200531b201841012008427f552008501b220641012005427f552005501b47200641012018427f552018501b477122061b22087d20192018423f872017201c7d20061b221754ad7d22054200531b200541012010427f552010501b220641012008427f552008501b47200641012005427f552005501b477122061b2208427f2005423f87201920177d20061b2205428080f0c4c5a9d28f72562008427f552008427f511b22061b21082005428080f0c4c5a9d28f7220061b21050c010b42ffffffffffffffffff00428080808080808080807f201042ffffffffffffffffff00428080808080808080807f200820057c2017201c7c2218201754ad7c22174200531b201741012008427f552008501b220641012005427f552005501b46200641012017427f552017501b477122061b22087c20192017423f87201820061b7c2217201954ad7c22054200531b200541012010427f552010501b220641012008427f552008501b46200641012005427f552005501b477122061b21082005423f87201720061b21050b200141e8006a41186a220a4200370300200141e8006a41106a22094200370300200141e8006a41086a220642003703002001420037036841cdcac800ad4280808080a002841001220b2900002110200141a0026a41086a2203200b41086a290000370300200120103703a002200b102920062003290300370300200120012903a00237036841b8cbc800ad42808080809002841001220b29000021102003200b41086a290000370300200120103703a002200b1029200420012903a002370000200441086a2003290300370000200141e0026a41086a220b2006290300370300200141e0026a41106a220c2009290300370300200141e0026a41186a2202200a290300370300200120012903683703e0022001200837037020012005370368200742808080808004842205201642808080808002841003200a420037030020094200370300200642003703002001420037036841ccbec500ad42808080809001841001220429000021072006200441086a290000370300200120073703682004102941ac84cc00ad42808080809001841001220429000021072003200441086a290000370300200120073703a00220041029200920012903a0022207370300200b2006290300370300200c200737030020022003290300370300200120012903683703e0020240200141e0026a10b201220641ff01714102460d00200510042006410171450d00200141e8006a41186a4200370300200141e8006a41106a22064200370300200141e8006a41086a220442003703002001420037036841c8bec500ad4280808080c00084100122092900002105200141c0026a41086a2203200941086a290000370300200120053703c0022009102920042003290300370300200120012903c00237036841a8c1c800ad4280808080b001841001220929000021052003200941086a290000370300200120053703c00220091029200620012903c0022205370300200141a0026a41086a2004290300370300200141a0026a41106a2005370300200141a0026a41186a2003290300370300200120012903683703a002200141e8006a200141a0026a10ce03024020012d006822034102460d00200141a0026aad22054280808080800484100420014180026a41086a200141f1006a29000037030020014180026a41106a200141f9006a29000037030020014180026a41186a20014181016a29000037030020012001290069370380020240200341037122034103460d0020030e03010001010b200141e0026a41186a20014180026a41186a290300370300200141e0026a41106a20014180026a41106a290300370300200141e0026a41086a20014180026a41086a29030037030020012001290380023703e002200141e8006a41186a220a4200370300200141e8006a41106a220b4200370300200141e8006a41086a220442003703002001420037036841c8bec500ad4280808080c00084100122092900002107200141c0026a41086a2203200941086a290000370300200120073703c0022009102920042003290300370300200120012903c002370368418cf3c200ad4280808080c001841001220929000021072003200941086a290000370300200120073703c00220091029200620012903c002370000200641086a2003290300370000200141a0026a41086a2004290300370300200141a0026a41106a200b290300370300200141a0026a41186a200a290300370300200120012903683703a002200141086a200141a0026a412010fc0141002109200141e8006a200128020c410020012802081b220a10cd03200141a0026a2001280268220b200128027010e3060240024020012802a00222040d00200141003602d802200142013703d00241012104410021030c010b200120012902a40222073702d402200120043602d0022007422088a721032007a721090b0240200128026c450d00200b10290b024002402003418002490d00412010272203450d04200320012903e002370000200341186a200141e0026a41186a290300370000200341106a200141e0026a41106a290300370000200341086a200141e0026a41086a290300370000200141e8006a200a41016a220a10cd0320012802682104200120012802703602a402200120043602a00220034101200141a0026a10a4040240200128026c450d00200410290b20031029200141e8006a41186a220b4200370300200141e8006a41106a220c4200370300200141e8006a41086a220442003703002001420037036841c8bec500ad4280808080c00084100122092900002107200141c0026a41086a2203200941086a290000370300200120073703c0022009102920042003290300370300200120012903c002370368418cf3c200ad4280808080c001841001220929000021072003200941086a290000370300200120073703c00220091029200620012903c002370000200641086a2003290300370000200141a0026a41086a2004290300370300200141a0026a41106a200c290300370300200141a0026a41186a200b290300370300200120012903683703a0022001200a3602682005428080808080048420164280808080c000841003200141d0026a21030c010b200141e8006a41186a220b200141e0026a41186a290300370300200141e8006a41106a220c200141e0026a41106a290300370300200141e8006a41086a2202200141e0026a41086a290300370300200120012903e002370368024020032009470d00200141d0026a20094101109e0120012802d002210420012802d80221030b200420034105746a22092001290368370000200941186a200b290300370000200941106a200c290300370000200941086a20022903003700002001200341016a22093602d802200141e8006a200a10cd0320012802682103200120012802703602a402200120033602a00220042009200141a0026a10a4040240200128026c450d00200310290b200141d0026a21030b200341046a28020041ffffff3f71450d00200328020010290b200141e8006a41186a220a4200370300200141e8006a41106a220b4200370300200141e8006a41086a220442003703002001420037036841c8bec500ad4280808080c00084100122092900002105200141c0026a41086a2203200941086a290000370300200120053703c0022009102920042003290300370300200120012903c00237036841d1e8c200ad42808080808001841001220929000021052003200941086a290000370300200120053703c00220091029200620012903c002370000200641086a2003290300370000200141a0026a41086a2004290300370300200141a0026a41106a200b290300370300200141a0026a41186a200a290300370300200120012903683703a002200141a0026aad4280808080800484100420014180036a24000f0b41c5f7c400412b41b8a1cc001033000b1030000b9111030b7f017e017f230041d0006b2201240020014100360230200142013703280240024002402000280200220241044b0d000240024002400240024020020e050001020304000b410110272202450d062001410136022c20012002360228200241013a000020014101360230200028020421032000410c6a2802002202200141286a10710240024020020d00200128023021020c010b2003200241286c6a21044100200128023022056b2106410021020340200520026a2107024002402006200128022c22086a4120490d00200128022821092008210a0c010b200741206a22092007490d082008410174220a2009200a20094b1b220a4100480d080240024020080d000240200a0d00410121090c020b200a102722090d010c0b0b200128022821092008200a460d0020092008200a102b2209450d0a0b2001200a36022c200120093602280b200920056a20026a220b200320026a2208290000370000200b41186a200841186a290000370000200b41106a200841106a290000370000200b41086a200841086a2900003700002001200741206a220b360230200841206a290300210c0240200a20066a41606a41074b0d00200b41086a220d200b490d08200a410174220b200d200b200d4b1b220b4100480d0802400240200a0d000240200b0d00410121090c020b200b10272209450d0b0c010b200a200b460d002009200a200b102b2209450d0a0b2001200b36022c200120093602280b200920056a20026a41206a200c3700002001200741286a360230200641586a2106200241286a21022004200841286a470d000b200520026a21020b200041106a280200210a02400240200128022c220920026b4104490d00200128022821080c010b200241046a22082002490d06200941017422062008200620084b1b22064100480d060240024020090d00024020060d00410121080c020b200610272208450d090c010b2001280228210820092006460d00200820092006102b2208450d080b2001200636022c200120083602280b200820026a200a3600002001200241046a3602300c040b410110272202450d052001410136022c20012002360228200241023a0000200141013602302000280204210902400240200128022c2208417f6a4104490d00200128022821020c010b200841017422024105200241054b1b220a4100480d052001280228210202402008200a460d0020022008200a102b2202450d070b2001200a36022c200120023602280b200220093600012001410536023020002802082102200041106a2802002208200141286a10710240024020080d002001280230210a0c010b2002200841286c6a210b2001280230210a034002400240200128022c2207200a6b4120490d00200a41206a210820012802282109200721060c010b200a41206a2208200a490d07200741017422092008200920084b1b22064100480d070240024020070d00024020060d00410121090c020b200610272209450d0a0c010b2001280228210920072006460d00200920072006102b2209450d090b2001200636022c200120093602280b2009200a6a220a2002290000370000200a41186a200241186a290000370000200a41106a200241106a290000370000200a41086a200241086a29000037000020012008360230200241206a290300210c0240200620086b41074b0d00200841086a220a2008490d0720064101742207200a2007200a4b1b220a4100480d070240024020060d000240200a0d00410121090c020b200a10272209450d0a0c010b2006200a460d0020092006200a102b2209450d090b2001200a36022c200120093602280b200920086a200c3700002001200841086a220a360230200b200241286a2202470d000b0b200041146a280200210902400240200128022c2208200a6b4104490d00200128022821020c010b200a41046a2202200a490d05200841017422062002200620024b1b22064100480d050240024020080d00024020060d00410121020c020b200610272202450d080c010b2001280228210220082006460d00200220082006102b2202450d070b2001200636022c200120023602280b2002200a6a20093600002001200a41046a3602300c030b410110272202450d042001410136022c20012002360228200241033a000020014101360230200041086a290300210c02400240200128022c2208417f6a4108490d00200128022821020c010b200841017422024109200241094b1b22094100480d0420012802282102024020082009460d00200220082009102b2202450d060b2001200936022c200120023602280b2002200c370001200141093602300c020b410110272202450d032001410136022c20012002360228200241043a0000200141013602302000280204210902400240200128022c2208417f6a4104490d00200128022821020c010b200841017422024105200241054b1b220a4100480d032001280228210202402008200a460d0020022008200a102b2202450d050b2001200a36022c200120023602280b20022009360001200141053602300c010b410110272202450d022001410136022c20012002360228200241053a0000200141013602302000280204210902400240200128022c2208417f6a4104490d00200128022821020c010b200841017422024105200241054b1b220a4100480d022001280228210202402008200a460d0020022008200a102b2202450d040b2001200a36022c200120023602280b20022009360001200141053602300b200141146a200141306a2802003600002001200129032837000c200141346a200141106a290000370000200141c6a4b9da04360029200141023a00282001200129000937002d200141286a10d30302402000280200220241014b0d000240024020020e020001000b200041086a2802002202450d01200241286c450d01200028020410290c010b2000410c6a2802002202450d00200241286c450d00200041086a28020010290b200141d0006a24000f0b1032000b1030000b8c0201037f024002400240024002400240024020012802000e0400010203000b41012102410110272201450d05200141003a0000410121030c040b410110272202450d04200241013a000020012802042103200241014105102b2202450d042002200336000120012802082104410a210320024105410a102b2201450d04200120043600050c020b41012102410110272201450d03200141023a0000410121030c020b410110272202450d02200241033a000020012802042103200241014105102b2202450d022002200336000120012802082104410a210320024105410a102b2201450d02200120043600050b410921020b2000200236020820002003360204200020013602000f0b1030000b8a06010c7f23004190016b220324002003200236021420032001360210200341186a2002ad4220862001ad841007108b020240024002400240200328021822040d00200041003602000c010b200328021c21052003200341206a28020036022c20032004360228200341086a200341286a10c8010240024020032802080d00200328020c2206200328022c22074105762201200120064b1b22014105742202417f4c0d030240024020010d00410121080c010b200210272208450d050b41002109200341003602402003200136023c20032008360238024002402006450d004100210a03402007210b41002101200341003a008801200a41016a210a0340200b2001460d03200341e8006a20016a200328022822022d00003a00002003200241016a3602282003200141016a22023a0088012002210120024120470d000b200341c8006a41186a220c200341e8006a41186a290300370300200341c8006a41106a220d200341e8006a41106a290300370300200341c8006a41086a220e200341e8006a41086a2903003703002003200329036837034802402009200328023c470d00200341386a20094101109e0120032802382108200328024021090b200b20026b2107200820094105746a22012003290348370000200141186a200c290300370000200141106a200d290300370000200141086a200e2903003700002003200941016a2209360240200a2006470d000b2003200b20026b36022c0b2008450d012000200329023c370204200020083602000c020b2003410036022c0240200141ff0171450d00200341003a0088010b200328023c41ffffff3f71450d00200810290b20034100360250200342013703482003410d36023c2003200341106a3602382003200341c8006a360234200341fc006a41013602002003420137026c200341f4eaca003602682003200341386a360278200341346a41a8a3c800200341e8006a10371a200335025042208620033502488410080240200328024c450d00200328024810290b200041003602000b2005450d00200410290b20034190016a24000f0b1038000b1039000ba10701087f230041106b220224002002410036020820024201370300200028020021030240410410272204450d002002410436020420022004360200200420033600002002410436020820002802042103200441044108102b2204450d002002410836020420042003360004200220043602002002410836020820002802082104200041106a280200220320021071024002402003450d00200341057421052002280204210620022802082103034002400240200620036b4120490d00200341206a2107200228020021080c010b200341206a22072003490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009102722080d010c060b2002280200210820062009460d00200820062009102b2208450d050b2002200936020420022008360200200921060b200820036a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200736020820072103200441206a2104200541606a22050d000b0b200028021421042000411c6a2802002203200210710240024020030d0020022802042109200228020821030c010b200341057421054100200228020822036b210820022802042106034002400240200620086a4120490d0020022802002107200621090c010b200341206a22072003490d03200641017422092007200920074b1b22094100480d030240024020060d00024020090d00410121070c020b200910272207450d060c010b2002280200210720062009460d00200720062009102b2207450d050b2002200936020420022007360200200921060b200720036a22072004290000370000200741186a200441186a290000370000200741106a200441106a290000370000200741086a200441086a2900003700002002200341206a2203360208200841606a2108200441206a2104200541606a22050d000b0b2000280220210602400240200920036b4104490d0020022802002104200921070c010b200341046a22042003490d01200941017422072004200720044b1b22074100480d010240024020090d00024020070d00410121040c020b200710272204450d040c010b2002280200210420092007460d00200420092007102b2204450d030b20022007360204200220043602000b200420036a20063600002001290200200341046aad4220862004ad84100302402007450d00200410290b200241106a24000f0b1032000b1030000bd907010f7f230041c0006b22052400200541003602082005420137030020054100360218200542013703102003410020041b21062001410020021b2107200341206a200320041b2108200141206a200120021b2109200120024105746a210a200320044105746a210b4101210c4100210d4101210e4101210f410021100340200e211120102102200821032006210102400340024020010d004100210620070d02200020052903003702002000200529031037020c200041086a200541086a280200360200200041146a200541106a41086a280200360200200541c0006a24000f0b024020070d00200541206a41186a2203200641186a290000370300200541206a41106a2202200641106a290000370300200541206a41086a2207200641086a29000037030020052006290000370320024020102005280214470d00200541106a20104101109e012005280210210e200528021821100b200e20104105746a22012005290320370000200141186a2003290300370000200141106a2002290300370000200141086a20072903003700002005201041016a221036021841002107410020082008200b4622011b2106200e210f2008200841206a20011b21080c030b0240024020012007460d0020012007412010e70722040d010b2003200341206a2003200b4622011b2108410020092009200a4622041b21074100200320011b21062011210e200221102009200941206a20041b21090c030b02402004417f4c0d00200121060c020b200541206a41186a2204200141186a290000370300200541206a41106a2212200141106a290000370300200541206a41086a2213200141086a29000037030020052001290000370320024020022005280214470d00200541106a20024101109e012005280218210220052802102211210f0b200f20024105746a22012005290320370000200141186a2004290300370000200141106a2012290300370000200141086a20132903003700002005200241016a2202360218410020032003200b4622041b21012003200341206a20041b21030c000b0b200541206a41186a2204200741186a290000370300200541206a41106a2212200741106a290000370300200541206a41086a2213200741086a290000370300200520072900003703200240200d2005280204470d002005200d4101109e012005280200210c2005280208210d0b200c200d4105746a22012005290320370000200141186a2004290300370000200141106a2012290300370000200141086a20132903003700002005200d41016a220d360208410020092009200a4622011b21072011210e200221102009200941206a20011b2109200321080c000b0bc96b08067f017e057f037e027f047e047f017e23004180036b220524000240410810272206450d0020062001200241c0016c6a220736020420062001360200024002400240024020000d0020054188026a41186a2208420037030020054188026a41106a2209420037030020054188026a41086a22024200370300200542003703880241fce2c800ad4280808080f001841001220a290000210b200541b8026a41086a220c200a41086a2900003703002005200b3703b802200a10292002200c290300370300200520052903b802370388024190f4c800ad4280808080c001841001220a290000210b200c200a41086a2900003703002005200b3703b802200a1029200920052903b802220b370300200541d8016a41086a220d2002290300370300200541d8016a41106a220e200b370300200541d8016a41186a220f200c29030037030020052005290388023703d801200541c8006a200541d8016a10b5012005290350210b20052802482110200842003703002009420037030020024200370300200542003703880241b1dcc900ad4280808080f000841001220a29000021112002200a41086a2900003703002005201137038802200a1029418886ca00ad4280808080c001841001220a2900002111200c200a41086a290000370300200520113703b802200a1029200920052903b8022211370300200d2002290300370300200e2011370300200f200c29030037030020052005290388023703d801200541c0006a200541d8016a412010fc012005280244210c2005280240210920054188026a200b420020101b10b8042005280288022102200535029002210b2005200c410020091b3602d801200b4220862002ad84200541d8016aad4280808080c0008410030240200528028c02450d00200210290b200610290c010b0240024002402002450d002006200141c0016a3602002005200141226a29000037018a0220052001412a6a29000037019202200541d8026a41086a2202200529039002370300200520012f00203b0188022005200141326a29000037019a0220052001413a6a2800003601a20220052001413e6a2f00003b01a60220052005290388023703d802200529039802210b20052903a0022111200541d8016a41086a220c2002290300370300200520052903d8023703d801200541b8026a41086a200c290300370300200520052903d8013703b802200628020420062802006b41c0016e41286c41286a2202417f4c0d0520021027220e450d04200e20052903b802370300200e4201370320200e2011370318200e200b370310200e41086a200541b8026a41086a220f2903003703004101210c200541013602c0012005200e3602b8012005200241286e22023602bc01200628020022092006280204460d012006200941c0016a3602002005200941226a29000037018a0220052009412a6a29000037019202200541d8026a41086a2208200529039002370300200541003a00a8022005200941216a2d00003a008902200520092d00203a0088022005200941326a29000037019a0220052009413a6a2800003601a20220052009413e6a2f00003b01a602200541203a00a80220052005290388023703d80220052903a002210b2005290398022111200541d8016a41086a22092008290300370300200520052903d8023703d8014102210c41c800210a0340200f20092903002212370300200520052903d80122133703b80220092012370300200520133703d8012005200b3703f001200520113703e8010240200c417f6a2002470d00200541b8016a2002200628020420062802006b41c0016e41016a10a30120052802b801210e0b200e200a6a220d41606a220220052903d8013703002009290300210b200541d8016a41106a2903002111200541d8016a41186a2903002112200d4201370300200241186a2012370300200241106a2011370300200241086a200b3703002005200c3602c0010240200628020022022006280204470d0020052802bc0121020c030b2006200241c0016a3602002005200241226a29000037018a0220052002412a6a290000370192022008200529039002370300200541003a00a8022005200241216a2d00003a008902200520022d00203a0088022005200241326a29000037019a0220052002413a6a2800003601a20220052002413e6a2f00003b01a602200541203a00a80220052005290388023703d80220052903a002210b200529039802211120092008290300370300200520052903d8023703d801200a41286a210a200c41016a210c20052802bc0121020c000b0b200610294108210e4100210c410021020c010b200610290b20054188026a41186a420037030020054188026a41106a2209420037030020054188026a41086a220a4200370300200542003703880241fce2c800ad4280808080f0018410012208290000210b200541b8026a41086a2206200841086a2900003703002005200b3703b80220081029200a2006290300370300200520052903b80237038802418fe5c800ad4280808080f0008410012208290000210b2006200841086a2900003703002005200b3703b80220081029200920052903b802220b370300200541d8016a41086a200a290300370300200541d8016a41106a200b370300200541d8016a41186a200629030037030020052005290388023703d80120054188026a200541d8016a412010f901024002402005280288024101460d002005200c360290022005200236028c022005200e36028802200541d8016a20054188026a41004100200510e706200541d8016aad4280808080800484210b0c010b200541d8016aad4280808080800484220b1004200529028c0221112005200c360290022005200236028c022005200e36028802200541d8016a20054188026a2011a741012011422088a710e7060b20054188026a41186a220a420037030020054188026a41106a220c420037030020054188026a41086a22064200370300200542003703880241fce2c800ad4280808080f001842211100122082900002112200541b8026a41086a2202200841086a290000370300200520123703b8022008102920062002290300370300200520052903b802370388024190f4c800ad4280808080c0018422121001220829000021132002200841086a290000370300200520133703b80220081029200920052903b802370000200941086a22102002290300370000200541d8016a41086a22082006290300370300200541d8016a41106a220d200c290300370300200541d8016a41186a220e200a29030037030020052005290388023703d801200541306a200541d8016a10b5012005280230211420052903382113200a4200370300200c420037030020064200370300200542003703880220111001220f29000021112002200f41086a290000370300200520113703b802200f102920062002290300370300200520052903b8023703880220121001220f29000021112002200f41086a290000370300200520113703b802200f1029200920052903b8023700002010200229030037000020082006290300370300200d200c290300370300200e200a29030037030020052005290388023703d8012005201342017c420120141b221137038802200b20054188026aad42808080808001841003200a4200370300200c420037030020064200370300200542003703880241b1dcc900ad4280808080f0008410012209290000210b2006200941086a2900003703002005200b3703880220091029418886ca00ad4280808080c0018410012209290000210b2002200941086a2900003703002005200b3703b80220091029200c20052903b802220b37030020082006290300370300200d200b370300200e200229030037030020052005290388023703d801200541286a200541d8016a412010fc01200528022c21062005280228210c20054188026a201110b8042005280288022102200535029002210b200520064100200c1b3602d801200b4220862002ad84200541d8016aad4280808080c000841003200528028c02450d00200210290b410810272202450d022002200736020420022001360200410810272206450d0220062003200441c0016c6a221436020420062003360200200541f8006a20024198e5c80010fa0520054188016a200641b0e7c80010fa052005280280012109200528027c21042005280278211020054198016a41086a20054188016a41086a28020036020020052005290388013703980120054188026a41186a220c420037030020054188026a41106a220e420037030020054188026a41086a22064200370300200542003703880241c8bec500ad4280808080c00084220b1001220a2900002111200541d8026a41086a2202200a41086a290000370300200520113703d802200a102920062002290300370300200520052903d8023703880241a4f0c200ad4280808080a0018422111001220a29000021122002200a41086a290000370300200520123703d802200a1029200e20052903d8022212370300200541b8026a41086a220a2006290300370300200541b8026a41106a22082012370300200541b8026a41186a220d200229030037030020052005290388023703b802200541186a200541b8026a10b501024002400240024002402005290320420020052802181b221342017c22122013540d00200c4200370300200e4200370300200642003703002005420037038802200b1001220f29000021132002200f41086a290000370300200520133703d802200f102920062002290300370300200520052903d8023703880220111001220f29000021112002200f41086a290000370300200520113703d802200f1029200e20052903d802370000200e41086a22152002290300370000200a20062903003703002008200e290300370300200d200c29030037030020052005290388023703b8022005201237038802200541b8026aad4280808080800484221120054188026aad221642808080808001841003200c4200370300200e4200370300200642003703002005420037038802200b1001220f290000210b2002200f41086a2900003703002005200b3703d802200f102920062002290300370300200520052903d8023703880241d983cc00ad4280808080b001841001220f290000210b2002200f41086a2900003703002005200b3703d802200f1029200e20052903d80237000020152002290300370000200a20062903003703002008200e290300370300200d200c29030037030020052005290388023703b802200941286c4104722202417f4c0d06200210272206450d0520054100360290022005200236028c022005200636028802200920054188026a10710240024020090d002005280290022102200528028802210a0c010b2010200941286c6a210d200528028c02210c200528029002210220102106034002400240200c20026b4120490d00200528028802210a200c21090c010b200241206a22092002490d07200c410174220a2009200a20094b1b22094100480d0702400240200c0d00024020090d004101210a0c020b20091027220a0d010c0c0b200528028802210a200c2009460d00200a200c2009102b220a450d0b0b2005200936028c022005200a360288020b200a20026a220c2006290000370000200c41186a200641186a290000370000200c41106a200641106a290000370000200c41086a200641086a2900003700002005200241206a220836029002200641206a290300210b02400240200920086b4108490d00200241286a21022009210c0c010b200841086a22022008490d072009410174220c2002200c20024b1b220c4100480d070240024020090d000240200c0d004101210a0c020b200c1027220a450d0c0c010b2009200c460d00200a2009200c102b220a450d0b0b2005200c36028c022005200a360288020b200a20086a200b3700002005200236029002200d200641286a2206470d000b0b200528028c02210620112002ad422086200aad84100302402006450d00200a10290b02402004450d00200441286c450d00201010290b0240201242017c220b2012540d0042002112200541b8026a41186a4200370300200541b8026a41106a220d4200370300200541b8026a41086a22064200370300200542003703b80241c8bec500ad4280808080c000841001220c2900002113200541d8026a41086a2202200c41086a290000370300200520133703d802200c102920062002290300370300200520052903d8023703b80241e4f2c200ad4280808080e001841001220c29000021132002200c41086a290000370300200520133703d802200c1029200d20052903d8022213370300200541d8016a41086a2006290300370300200541d8016a41106a2013370300200541d8016a41186a2002290300370300200520052903b8023703d80120054188026a200541d8016a10c00320054199026a2900002117200541a1026a290000211320052d0088022106200220054191026a29000037030020052005290089023703d8020240024020064101460d00200541d8006a41086a420037030020054200370358420021130c010b200541d8006a41086a2002290300370300200520052903d802370358201721120b200541b8026a41186a220c4200370300200541b8026a41106a22094200370300200541b8026a41086a22064200370300200542003703b80241c8bec500ad4280808080c0008422171001220a2900002118200541d8026a41086a2202200a41086a290000370300200520183703d802200a102920062002290300370300200520052903d8023703b802418cf3c200ad4280808080c0018422181001220a29000021192002200a41086a290000370300200520193703d802200a1029200d20052903d802370000200d41086a22082002290300370000200541d8016a41086a220f2006290300370300200541d8016a41106a22042009290300370300200541d8016a41186a2210200c290300370300200520052903b8023703d801200541106a200541d8016a412010fc01200528021421152005280210211a200c42003703002009420037030020064200370300200542003703b80220171001220a29000021172002200a41086a290000370300200520173703d802200a102920062002290300370300200520052903d8023703b80220181001220a29000021172002200a41086a290000370300200520173703d802200a1029200d20052903d80237000020082002290300370000200f2006290300370300200420092903003703002010200c290300370300200520052903b8023703d8012005410036028802200541d8016aad4280808080800484221720164280808080c000841003200541b8016a41086a200541d8006a41086a290300370300200520052903583703b801417f20154100201a1b220841016a220220022008491b410d744128722210417f4c0d0720101027220f450d06200f20052903b801370000200f200b370020200f2013370018200f2012370010200f41086a200541b8016a41086a29030037000041282104410021064100210202400340024002402002450d00200c2009470d01200a41ffffff3f71450d00200210290b200620084f0d02200541d8026a200610cd03200541b8026a20052802d802220c20052802e002220910e306024020052802b8022202450d002009ad422086200cad8410040b20052902bc02420020021b210b2002410120021b2102024020052802dc02450d00200c10290b200641016a21062002200b422088a74105746a2109200ba7210a2002210c0c010b200541d8016a41186a200c41186a2215290000370300200541d8016a41106a200c41106a221a290000370300200541d8016a41086a200c41086a221b2900003703002005200c2900003703d801201b290000210b201a2900002118200c290000211920054188026a41186a221a201529000037030020054188026a41106a2215201837030020054188026a41086a221b200b3703002005201937038802200541b8026a41186a221c201a290300370300200541b8026a41106a221a2015290300370300200541b8026a41086a221d201b29030037030020052005290388023703b8020240201020046b411f4b0d00200441206a22152004490d082010410174221b2015201b20154b1b22154100480d080240024020100d00024020150d004101210f0c020b20151027220f450d0d0c010b20102015460d00200f20102015102b220f450d0c0b201521100b200c41206a210c200f20046a221520052903b802370000201541186a201c290300370000201541106a201a290300370000201541086a201d290300370000200441206a21040c000b0b200541e8006a41086a2004ad422086200fad841010220241086a290000370300200520022900003703682002290010210b200229001821182002102902402010450d00200f10290b200541b8026a41186a22064200370300200541b8026a41106a22094200370300200541b8026a41086a220c4200370300200542003703b80241c8bec500ad4280808080c0008422191001220a290000211e200541d8026a41086a2202200a41086a2900003703002005201e3703d802200a1029200c2002290300370300200520052903d8023703b80241e4f2c200ad4280808080e001841001220a290000211e2002200a41086a2900003703002005201e3703d802200a1029200d20052903d802370000200d41086a2002290300370000200541d8016a41086a200c290300370300200541d8016a41106a2009290300370300200541d8016a41186a2006290300370300200520052903b8023703d801412010272202450d0620022005290368370000200220183700182002200b370010200241086a200541e8006a41086a29030037000020172002ad4280808080800484100320021029200541a8016a41086a200541d8006a41086a290300220b3703002005200529035822173703a801200541d8016a41086a2208200b370300200520173703d80120054188026a41186a220f420037030020054188026a41106a2204420037030020054188026a41086a220c4200370300200542003703880220191001220a290000210b200541d8026a41086a2202200a41086a2900003703002005200b3703d802200a1029200c2002290300370300200520052903d8023703880241b8f1c200ad4280808080a001841001220a290000210b2002200a41086a2900003703002005200b3703d802200a1029200e20052903d802370000200e41086a220a2002290300370000200541b8026a41086a2210200c290300370300200920042903003703002006200f29030037030020052005290388023703b802412010272206450d06200620052903d8013700002006201337001820062012370010200641086a200829030037000020112006ad428080808080048410032006102920054188026a41186a2209420037030020054188026a41106a22084200370300200c4200370300200542003703880241c8bec500ad4280808080c0008410012206290000210b2002200641086a2900003703002005200b3703d80220061029200c2002290300370300200520052903d8023703880241e4f2c200ad4280808080e0018410012206290000210b2002200641086a2900003703002005200b3703d80220061029200e20052903d802370000200a20022903003700002010200c290300370300200541b8026a41106a2008290300370300200541b8026a41186a200929030037030020052005290388023703b80220054188026a200541b8026a10c00320054199026a290000210b200541a1026a290000211220052d0088022106200220054191026a29000037030020052005290089023703d8020240024020064101460d00200541b8016a41186a4200370300200541b8016a41106a4200370300200541c0016a4200370300200542003703b8010c010b200541b8016a41086a200541d8026a41086a290300370300200520052903d8023703b801200520123703d0012005200b3703c8010b200541d8016a41086a220220054198016a41086a280200360200200541d8016a41246a200541b8016a41186a290300370200200541d8016a411c6a200541b8016a41106a290300370200200541d8016a41146a200541b8016a41086a2903003702002005200529039801220b3703d801200520052903b8013702e401200541b4026a20054180026a28020036020020054188026a41246a200541d8016a41206a29030037020020054188026a411c6a200541d8016a41186a29030037020020054188026a41146a200541d8016a41106a29030037020020054194026a20022903003702002005200b37028c02200541003602880220054188026a10d00320054188026a41186a2209420037030020054188026a41106a220a420037030020054188026a41086a22064200370300200542003703880241c8bec500ad4280808080c000841001220c290000210b200541d8026a41086a2202200c41086a2900003703002005200b3703d802200c102920062002290300370300200520052903d8023703880241a8f2c200ad4280808080f001841001220c290000210b2002200c41086a2900003703002005200b3703d802200c1029200e20052903d802370000200e41086a2002290300370000200541b8026a41086a2006290300370300200541b8026a41106a200a290300370300200541b8026a41186a200929030037030020052005290388023703b802200541203602f4022005200541b8026a3602f002200541e8006a20111007108b02024020052802682202450d00200528026c210c024002400240200541e8006a41086a2802002206450d0020022d00004101470d0020054200370388022006417f6a4108490d002002290001210b2005420037038802200641776a4108490d0020064111460d0020022d001122064103490d010b200541003602e002200542013703d8022005410d36025c2005200541f0026a3602582005200541d8026a3602fc022005419c026a41013602002005420137028c02200541f4eaca00360288022005200541d8006a36029802200541fc026a41a8a3c80020054188026a10371a20053502e00242208620053502d802841008024020052802dc02450d0020052802d80210290b410321060c010b20022900092112200520052800d8023602582005200541d8026a41036a28000036005b200520052802583602e8022005200528005b3600eb020b0240200c450d00200210290b20064103460d0020111004200520052800eb023600db02200520052802e8023602d802200520052800db0236006b200520052802d802360268200541a0026a20063a000020054198026a201237030020054190026a200b370300200541a4026a200528006b360000200520052802683600a102200541023602880220054188026a10d0030b410810272206450d082006200736020420062001360200410810272210450d082010201436020420102003360200200541d8006a41086a2202420037030020054200370358200241b3e6ca00ad4280808080e000841001220c41086a2900003703002005200c290000370358200c102941c9e6ca00ad4280808080e000841001220c290000210b200c2900082111200c102920054188026a41086a2002290300370300200520113703a0022005200b370398022005200529035837038802200541086a20054188026a412010fc012005280208210a200528020c2108200541b8026a41186a220e4200370300200541b8026a41106a220f4200370300200541b8026a41086a22024200370300200542003703b80241c6b7c700ad428080808080018410012209290000210b200541d8026a41086a220c200941086a2900003703002005200b3703d802200910292002200c290300370300200520052903d8023703b80241ceb7c700ad4280808080e0018410012209290000210b200c200941086a2900003703002005200b3703d80220091029200d20052903d802370000200d41086a200c290300370000200541b8016a41086a2002290300370300200541b8016a41106a200f290300370300200541b8016a41186a200e290300370300200520052903b8023703b8012005200841b0096a41b009200a1b36028802200541b8016aad4280808080800484221720164280808080c000841003200628020022022006280204460d022006200241c0016a3602002005200241e2006a29000037018a022005200241ea006a29000037019202200c2005290390023703002005200241e0006a2f00003b0188022005200241f2006a29000037019a022005200241fa006a2800003601a2022005200241fe006a2f00003b01a60220052005290388023703d802200529039802210b20052903a0022111200541d8016a41086a2202200c290300370300200520052903d8023703d801200541e8006a41086a2002290300370300200520052903d801370368200628020420062802006b41c0016e41057441206a220210272204450d0620042005290368370000200420113700182004200b370010200441086a200541e8006a41086a2903003700004101210c200541013602c002200520043602b80220052002410576220f3602bc02200628020022022006280204460d032006200241c0016a3602002005200241e2006a29000037018a022005200241ea006a29000037019202200541d8026a41086a22082005290390023703002005200241e0006a2f00003b0188022005200241f2006a29000037019a022005200241fa006a2800003601a2022005200241fe006a2f00003b01a60220052005290388023703d802200529039802210b20052903a0022111200541d8016a41086a22092008290300370300200520052903d8023703d8014102210c4120210a0340200541b8016a41086a20092903002212370300200520052903d80122133703b80120092012370300200520133703d801200520113703f0012005200b3703e8010240200c417f6a200f470d00200541b8026a200f200628020420062802006b41c0016e41016a109e0120052802b80221040b2004200a6a220220052903d801370000200241186a200541d8016a41186a290300370000200241106a200541d8016a41106a290300370000200241086a20092903003700002005200c3602c0020240200628020022022006280204470d0020052802bc02210f0c050b2006200241c0016a3602002005200241e2006a29000037018a022005200241ea006a2900003701920220082005290390023703002005200241e0006a2f00003b0188022005200241f2006a29000037019a022005200241fa006a2800003601a2022005200241fe006a2f00003b01a60220052005290388023703d802200529039802210b20052903a002211120092008290300370300200520052903d8023703d801200a41206a210a200c41016a210c20052802bc02210f0c000b0b41c489c30041c90041a08ac3001057000b41c489c30041c90041908ac3001057000b200610294100210f410121044100210c0c010b200610290b200541b8026a41186a220a4200370300200541b8026a41106a22084200370300200541b8026a41086a22064200370300200542003703b80241c6b7c700ad428080808080018410012209290000210b200541d8026a41086a2202200941086a2900003703002005200b3703d8022009102920062002290300370300200520052903d8023703b80241dcb7c700ad4280808080c0008410012209290000210b2002200941086a2900003703002005200b3703d80220091029200d20052903d802370000200d41086a2002290300370000200541b8016a41086a2006290300370300200541b8016a41106a2008290300370300200541b8016a41186a200a290300370300200520052903b8023703b801200c41057422084104722202417f4c0d02200210272206450d0120054100360290022005200236028c022005200636028802200c20054188026a107102400240200c0d002005280290022106200528028c022109200528028802210e0c010b410020052802900222066b210a200528028802210e200528028c0221092004210d0340200d210202402009200a6a411f4b0d00200641206a220c2006490d032009410174220d200c200d200c4b1b220c4100480d03024002400240024020090d000240200c0d004101210e0c020b200c1027210e0c030b2009200c470d010b200c21090c020b200e2009200c102b210e0b200c2109200e450d060b200241206a210d200e20066a220c2002290000370000200c41186a200241186a290000370000200c41106a200241106a290000370000200c41086a200241086a290000370000200a41606a210a200641206a2106200841606a22080d000b2005200936028c0220052006360290022005200e360288020b20172006ad422086200ead84100302402009450d00200e10290b0240200f41ffffff3f71450d00200410290b20101029410810272206450d032006200736020420062001360200410810272210450d032010201436020420102003360200024002400240024002402000450d00200628020022022006280204460d012006200241c0016a360200200520024182016a29000037018a0220052002418a016a29000037019202200541d8026a41086a220c200529039002370300200520024180016a2f00003b018802200520024192016a29000037019a0220052002419a016a2800003601a20220052002419e016a2f00003b01a60220052005290388023703d802200529039802210b20052903a0022111200541d8016a41086a2202200c290300370300200520052903d8023703d801200541e8006a41086a220c2002290300370300200520052903d801370368200628020420062802006b41c0016e41057441206a220210272204450d0620042005290368370000200420113700182004200b370010200441086a200c2903003700004101210c200541013602c002200520043602b80220052002410576220f3602bc02200628020022022006280204460d022006200241c0016a360200200520024182016a29000037018a0220052002418a016a29000037019202200541d8026a41086a2208200529039002370300200520024180016a2f00003b018802200520024192016a29000037019a0220052002419a016a2800003601a20220052002419e016a2f00003b01a60220052005290388023703d802200529039802210b20052903a0022111200541d8016a41086a22092008290300370300200520052903d8023703d8014102210c4120210a0340200541b8016a41086a20092903002212370300200520052903d80122133703b80120092012370300200520133703d801200520113703f0012005200b3703e8010240200c417f6a200f470d00200541b8026a200f200628020420062802006b41c0016e41016a109e0120052802b80221040b2004200a6a220220052903d801370000200241186a200541d8016a41186a290300370000200241106a200541d8016a41106a290300370000200241086a20092903003700002005200c3602c0020240200628020022022006280204470d0020052802bc02210f0c040b2006200241c0016a360200200520024182016a29000037018a0220052002418a016a290000370192022008200529039002370300200520024180016a2f00003b018802200520024192016a29000037019a0220052002419a016a2800003601a20220052002419e016a2f00003b01a60220052005290388023703d802200529039802210b20052903a002211120092008290300370300200520052903d8023703d801200a41206a210a200c41016a210c20052802bc02210f0c000b0b20101029200610290c030b200610294100210f410121044100210c0c010b200610290b200541d8006a41086a2202420037030020054200370358200241cd87cc00ad4280808080a001841001220641086a290000370300200520062900003703582006102941d983cc00ad4280808080b0018410012206290000210b200629000821112006102920054188026a41086a2002290300370300200520113703a0022005200b370398022005200529035837038802200c41057422084104722202417f4c0d03200210272206450d02200541003602e001200520023602dc01200520063602d801200c200541d8016a107102400240200c0d0020052802e001210620052802dc01210920052802d801210e0c010b410020052802e00122066b210a20052802d801210e20052802dc0121092004210d0340200d210202402009200a6a411f4b0d00200641206a220c2006490d042009410174220d200c200d200c4b1b220c4100480d04024002400240024020090d000240200c0d004101210e0c020b200c1027210e0c030b2009200c470d010b200c21090c020b200e2009200c102b210e0b200c2109200e450d070b200241206a210d200e20066a220c2002290000370000200c41186a200241186a290000370000200c41106a200241106a290000370000200c41086a200241086a290000370000200a41606a210a200641206a2106200841606a22080d000b200520093602dc01200520063602e0012005200e3602d8010b201642808080808004842006ad422086200ead84100302402009450d00200e10290b0240200f41ffffff3f71450d00200410290b201010290b410810272206450d032006200736020420062001360200410810272201450d032001201436020420012003360200024002400240024002402000450d00200628020022022006280204460d012006200241c0016a3602002005200241a2016a29000037018a022005200241aa016a29000037019202200541d8026a41086a220c2005290390023703002005200241a0016a2f00003b0188022005200241b2016a29000037019a022005200241ba016a2800003601a2022005200241be016a2f00003b01a60220052005290388023703d802200529039802210b20052903a0022111200541d8016a41086a2202200c290300370300200520052903d8023703d801200541e8006a41086a220c2002290300370300200520052903d801370368200628020420062802006b41c0016e41057441206a220210272204450d0620042005290368370000200420113700182004200b370010200441086a200c2903003700004101210c200541013602c002200520043602b80220052002410576220f3602bc02200628020022022006280204460d022006200241c0016a3602002005200241a2016a29000037018a022005200241aa016a29000037019202200541d8026a41086a22082005290390023703002005200241a0016a2f00003b0188022005200241b2016a29000037019a022005200241ba016a2800003601a2022005200241be016a2f00003b01a60220052005290388023703d802200529039802210b20052903a0022111200541d8016a41086a22092008290300370300200520052903d8023703d8014102210c4120210a0340200541b8016a41086a20092903002212370300200520052903d80122133703b80120092012370300200520133703d801200520113703f0012005200b3703e8010240200c417f6a200f470d00200541b8026a200f200628020420062802006b41c0016e41016a109e0120052802b80221040b2004200a6a220220052903d801370000200241186a200541d8016a41186a290300370000200241106a200541d8016a41106a290300370000200241086a20092903003700002005200c3602c0020240200628020022022006280204470d0020052802bc02210f0c040b2006200241c0016a3602002005200241a2016a29000037018a022005200241aa016a2900003701920220082005290390023703002005200241a0016a2f00003b0188022005200241b2016a29000037019a022005200241ba016a2800003601a2022005200241be016a2f00003b01a60220052005290388023703d802200529039802210b20052903a002211120092008290300370300200520052903d8023703d801200a41206a210a200c41016a210c20052802bc02210f0c000b0b20011029200610290c030b20061029410121044100210c4100210f0c010b200610290b200541d8006a41086a22024200370300200542003703582002418ebfc500ad4280808080a002841001220641086a290000370300200520062900003703582006102941dcb7c700ad4280808080c0008410012206290000210b200629000821112006102920054188026a41086a2002290300370300200520113703a0022005200b370398022005200529035837038802200c41057422084104722202417f4c0d03200210272206450d02200541003602e001200520023602dc01200520063602d801200c200541d8016a107102400240200c0d0020052802e001210620052802dc01210920052802d801210e0c010b410020052802e00122066b210a20052802d801210e20052802dc0121092004210d0340200d210202402009200a6a411f4b0d00200641206a220c2006490d042009410174220d200c200d200c4b1b220c4100480d04024002400240024020090d000240200c0d004101210e0c020b200c1027210e0c030b2009200c470d010b200c21090c020b200e2009200c102b210e0b200c2109200e450d070b200241206a210d200e20066a220c2002290000370000200c41186a200241186a290000370000200c41106a200241106a290000370000200c41086a200241086a290000370000200a41606a210a200641206a2106200841606a22080d000b200520093602dc01200520063602e0012005200e3602d8010b201642808080808004842006ad422086200ead84100302402009450d00200e10290b0240200f41ffffff3f71450d00200410290b200110290b20054180036a24000f0b1032000b1039000b1038000b1030000be91305057f017e047f027e037f230041f0006b22052400200541c0006a41186a22064200370300200541c0006a41106a22074200370300200541c0006a41086a220842003703002005420037034041fce2c800ad4280808080f0018410012209290000210a200541e0006a41086a220b200941086a2900003703002005200a370360200910292008200b29030037030020052005290360370340418be3c800ad4280808080d0018410012209290000210a200b200941086a2900003703002005200a3703602009102920072005290360220a370300200541206a41086a22092008290300370300200541206a41106a220c200a370300200541206a41186a220d200b29030037030020052005290340370320200541186a200541206a41204180a6cc004100410010c701024002400240024002400240024020052802184101470d00410d210b419cd5c8002108410221070c010b2006420037030020074200370300200842003703002005420037034041b3e6ca00ad4280808080e0008410012206290000210a2008200641086a2900003703002005200a3703402006102941c9e6ca00ad4280808080e0008410012206290000210a200b200641086a2900003703002005200a3703602006102920072005290360220a37030020092008290300370300200c200a370300200d200b29030037030020052005290340370320200541106a200541206a412010fc012005280214410020052802101b2109024020034101460d00200541206a210e0c030b200541c0006a41186a22064200370300200541c0006a41106a220c4200370300200541c0006a41086a220842003703002005420037034041fce2c800ad4280808080f00184220f1001220d290000210a200541e0006a41086a220b200d41086a2900003703002005200a370360200d10292008200b2903003703002005200529036037034041c8e9c800ad4280808080a0018422101001220d290000210a200b200d41086a2900003703002005200a370360200d102920072005290360370000200741086a220d200b290300370000200541206a41086a220e2008290300370300200541206a41106a2211200c290300370300200541206a41186a2212200629030037030020052005290340370320200541086a200541206a412010fc012005280208450d01200528020c20094d0d014107210b4195d5c8002108410321070b200041831c3b0100200041086a200b360200200041046a2008360200200041026a20073a0000200141046a280200220b450d02200b41286c450d02200128020010290c020b20064200370300200c42003703002008420037030020054200370340200f10012213290000210a200b201341086a2900003703002005200a370360201310292008200b29030037030020052005290360370340201010012213290000210a200b201341086a2900003703002005200a3703602013102920072005290360370000200d200b290300370000200e20082903003703002011200c29030037030020122006290300370300200520052903403703202005200920024101746a360240200541206aad4280808080800484200541c0006aad4280808080c000841003200541206a210e0b200128020821082001280204210c2001280200210d200541c0006a41186a22114200370300200541c0006a41106a22124200370300200541c0006a41086a220142003703002005420037034041fce2c800ad4280808080f0018410012206290000210a200541e0006a41086a220b200641086a2900003703002005200a370360200610292001200b29030037030020052005290360370340418be3c800ad4280808080d0018410012206290000210a200b200641086a2900003703002005200a3703602006102920072005290360370000200741086a200b290300370000200541206a41086a2001290300370300200541206a41106a2012290300370300200541206a41186a201129030037030020052005290340370320200541003602482005420137034041041027220b450d02200541043602442005200b360240200b200936000020054104360248200b41044108102b220b450d0220054108360244200b20023600042005200b360240200541083602482008200541c0006a10712005280248210702402008450d00200d200841286c6a2106200d210b0340024002402005280244220220076b4120490d00200741206a210820052802402101200221090c010b200741206a22082007490d04200241017422012008200120084b1b22094100480d040240024020020d00024020090d00410121010c020b2009102722010d010c070b2005280240210120022009460d00200120022009102b2201450d060b20052009360244200520013602400b200120076a2207200b290000370000200741186a200b41186a290000370000200741106a200b41106a290000370000200741086a200b41086a29000037000020052008360248200b41206a290300210a0240200920086b41074b0d00200841086a22072008490d04200941017422022007200220074b1b22074100480d040240024020090d00024020070d00410121010c020b200710272201450d070c010b20092007460d00200120092007102b2201450d060b20052007360244200520013602400b200120086a200a3700002005200841086a22073602482006200b41286a220b470d000b0b2005280244210b0240024020034101460d0002400240200b2007460d00200528024021080c010b200741016a220b2007490d0420074101742208200b2008200b4b1b220b4100480d040240024020070d00410021070240200b0d00410121080c020b200b10272208450d070c010b200528024021082007200b460d0020082007200b102b2208450d060b2005200b360244200520083602400b200820076a41003a00002005200741016a22073602480c010b02400240200b2007460d00200528024021080c010b200741016a220b2007490d0320074101742208200b2008200b4b1b220b4100480d030240024020070d00410021070240200b0d00410121080c020b200b10272208450d060c010b200528024021082007200b460d0020082007200b102b2208450d050b2005200b360244200520083602400b200820076a41013a00002005200741016a22013602480240200b20016b41034b0d00200141046a22092001490d03200b41017422022009200220094b1b22094100480d0302400240200b0d00024020090d00410121080c020b200910272208450d060c010b200b2009460d002008200b2009102b2208450d050b20052009360244200520083602400b200820016a20043600002005200741056a22073602482005280244210b200528024021080b200ead42808080808004842007ad4220862008ad8410030240200b450d00200810290b0240200c450d00200c41286c450d00200d10290b200041043a00000b200541f0006a24000f0b1032000b1030000b290020004101360204200041086a200128020420012802006b41c0016e2201360200200020013602000bf40101047f230041d0006b21020240200128020022032001280204470d00200041003602000f0b2001200341c0016a3602002002200341c2006a29000037012a2002200341ca006a290000370132200241106a220120022903303703002002200341d2006a29000037013a200241186a220420022903383703002002200341da006a2800003601422002200341de006a2f00003b0146200241206a220520022903403703002002200341c0006a2f00003b01282002200229032837030820002003360200200020022903083700042000410c6a2001290300370000200041146a20042903003700002000411c6a20052903003700000b8406020e7f047e230041b0016b22032400024002402001280200220420012802042205460d002001200441c0016a22063602002003200429004237018a012003200429004a37019201200341e8006a41086a22072003290390013703002003200429005237019a01200341e8006a41106a22082003290398013703002003200428005a3601a201200320042f005e3b01a601200341e8006a41186a220920032903a001370300200320042f00403b0188012003200329038801370368200341c8006a41186a220a2009290300370300200341c8006a41106a220b2008290300370300200341c8006a41086a220c200729030037030020032003290368370348200341286a41186a220d200a290300370300200341286a41106a220e200b290300370300200341286a41086a220f200c29030037030020032003290348370328200541c07e6a211002400340200341086a41186a200d2903002211370300200341086a41106a200e2903002212370300200341086a41086a200f290300221337030020032003290328221437030820034188016a41186a201137030020034188016a41106a201237030020034188016a41086a201337030020032014370388012002450d0120102004460d022001200641c0016a22053602002003200629004237018a012003200629004a3701920120072003290390013703002003200629005237019a0120082003290398013703002003200628005a3601a201200320062f005e3b01a601200920032903a001370300200320062f00403b0188012003200329038801370368200a2009290300370300200b2008290300370300200c200729030037030020032003290368370348200d200a290300370300200e200b290300370300200f200c29030037030020032003290348370328200441c0016a21042002417f6a2102200521060c000b0b2000200436020020002003290388013702042000410c6a20034190016a290300370200200041146a20034198016a2903003702002000411c6a200341a0016a2903003702000c010b200041003602000b200341b0016a24000b130020004101360204200041d4e9c8003602000b3400200041fce2c80036020420004100360200200041146a4106360200200041106a41e0eec800360200200041086a420f3702000b2c01017f02404108102722020d001039000b20004288808080800137020420002002360200200242003700000b2201017f230041106b22022400200241003602002000200210e206200241106a24000bad1206087f017e047f017e057f077e230022042105200441e0016b416071220424000240200341e500490d0041002802d8a74c450d00200441ec006a410136020020044101360264200441b0e3c800360260200420033602482004200441c8006a36026841002802888040210641002802848040210741002802dca74c2108200441c0016a41a806360200200441b8016a42de80808010370300200441b4016a41dde3c800360200200441ac016a4211370200200441a8016a41cce3c800360200200441a0016a420237030020044190016a420337030020044188016a41113602002004419c016a200441e0006a360200200441b4e3c80036028c01200441cce3c80036028401200441013602800120074180a4c000200841024622081b20044180016a20064198a4c00020081b2802101102000b024002400240200141ffffff3f712001470d0020014105742207417f4c0d000240024020070d00410121080c010b200710272208450d020b4100210620044100360288012004200836028001200420074105763602840120044180016a41002001109e01200428028801210902402001450d002001410574210a20042802800120094105746a210b0340200b20066a2207200020066a2208290000370000200741186a200841186a290000370000200741106a200841106a290000370000200741086a200841086a290000370000200a200641206a2206470d000b200141057441606a41057620096a41016a21090b200441186a41086a20093602002004200429038001220c370318200ca7200920044180016a410041202009676b10fa0420044180016a41186a2201420037030020044180016a41106a220d420037030020044180016a41086a220e420037030020044200370380014193d4c800ad4280808080b0028410012206290000210c200e200641086a2900003703002004200c3703800120061029419fdec900ad428080808090018410012206290000210c200441c8006a41086a220f200641086a2900003703002004200c37034820061029200d2004290348220c370300200441e0006a41086a200e290300370300200441e0006a41106a200c370300200441e0006a41186a200f290300370300200420042903800137036020044180016a200441e0006a412010ce012004280280012206410120061b2110200429028401420020061b2211422088a72206450d0220064105742109200441e0006a410c72211220044180016a410c6a210020044180016a411472211320044180016a41087221142010210603402001200641186a290000370300200d200641106a290000370300200e200641086a2900003703002004200629000037038001200441286a20044180016a10f00620044180016a2004280228220b2004280230221510c105200f200041086a290200370300200441c8006a41106a220a200041106a2802003602002004200029020037034820042802a001210702402004280288012208450d00200429038001210c20122004290348370200201241086a200f290300370200201241106a200a2802003602002004200c370360200721160b2004200836026820044100360288012004290378211720042004290398012218370378200429037021192004200429039001221a3703702004290360211b2004200429038001221c3703602004290368210c2004200429038801221d370368201da7210802400240200ca7220a0d00201d210c201a211920182117201621070c010b2004201b370380012004200c37038801200420193703900120042017370398012004200a2019a74105746a3602542004200a3602502004200c422088a736024c2004200a3602482004200441186a360258200441386a200441c8006a10f905201441086a200441386a41086a22162802003602002014200429033837020020042019422088a7220a2017422088a74105746a3602542004200a36025020042017a736024c2004200a3602482004200441186a360258200441386a200441c8006a10f905201341086a201628020036020020132004290338370200200429038801210c200429038001211c2004290398012117200429039001211902402008450d002018a7210a0240201d422088a741ffffff3f71450d00200810290b200a41ffffff3f71450d00201a422088a710290b2004201c3703602004200c3703682004201937037020042017370378200ca721080b2004200c370388012004201937039001200120173703002004201c37038001200420073602a001200ca7210a0240024020080d002015ad422086200bad8410040c010b2004201536024c2004200b36024820044180016a200441c8006a10e4060b0240200a450d002017a721080240200c422088a741ffffff3f71450d00200a10290b200841ffffff3f71450d002019422088a710290b0240200428022c450d00200b10290b200641206a210620072116200941606a22090d000c030b0b1038000b1039000b0240201142ffffff3f83500d00201010290b20044180016a41186a220a420037030020044180016a41106a2208420037030020044180016a41086a2207420037030020044200370380014193d4c800ad4280808080b00284220c10012200290000211c200441c8006a41086a2206200041086a2900003703002004201c3703482000102920072006290300370300200420042903483703800141f0edca00ad4280808080f0008410012200290000211c2006200041086a2900003703002004201c3703482000102920082004290348221c370300200441e0006a41086a220b2007290300370300200441e0006a41106a2201201c370300200441e0006a41186a22092006290300370300200420042903800137036020044120360284012004200441e0006a360280012002200320044180016a10d506200a420037030020084200370300200742003703002004420037038001200c10012200290000210c2006200041086a2900003703002004200c3703482000102920072006290300370300200420042903483703800141f8d7ca00ad4280808080d0008410012200290000210c2006200041086a2900003703002004200c3703482000102920082004290348220c370300200b20072903003703002001200c370300200920062903003703002004200429038001370360200441e0006aad428080808080048410040240200428021c41ffffff3f71450d00200428021810290b200524000b9f0303027f017e027f230041206b220224004193d4c800ad4280808080b00284100122032900002104200241086a200341086a290000370300200220043703002003102941f7edca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000b130020004105360204200041d0f8c8003602000b340020004193d4c80036020420004100360200200041146a4106360200200041106a4190a5c900360200200041086a42133702000b3400200041a6d4c80036020420004100360200200041146a4106360200200041106a4190a5c900360200200041086a42133702000b130020004107360204200041c0a9c9003602000b3400200041d787cc0036020420004100360200200041146a4109360200200041106a4194c0c900360200200041086a42093702000b910101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002404120102722060d001039000b20062002290300370000200042a0808080800437020420002006360200200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000200241206a24000b2d01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241e8073600000bfa0301047f230041206b22042400024002400240024002400240024002402002200141346a2205460d0020022005412010e707450d00200441186a200241186a290000370300200441106a200241106a290000370300200441086a200241086a290000370300200420022900003703002001200410bc0322010d010c060b200141306a2802002202417f4c0d01200128022821060240024020020d0041002101410121070c010b200210272207450d03200221010b0240024020012002490d00200121050c010b200141017422052002200520024b1b22054100480d04024020010d002005102722070d010c060b20012005460d00200720012005102b2207450d050b20072006200210e4072101200041086a200236020020002005360204200020013602000c060b200128020c4101480d0420012802082202417f4c0d00200128020021060240024020020d0041002101410121070c010b200210272207450d02200221010b0240024020012002490d00200121050c010b200141017422052002200520024b1b22054100480d03024020010d00200510272207450d050c010b20012005460d00200720012005102b2207450d040b20072006200210e4072101200041086a200236020020002005360204200020013602000c050b1038000b1039000b1032000b1030000b200041003602000b200441206a24000be80302057f017e230041f0006b22042400200328020021050240024002400240024020032802082206200041306a280200470d00200520002802282207460d0120052007200610e707450d010b200441c0006a41186a2206200141186a290000370300200441c0006a41106a2207200141106a290000370300200441c0006a41086a2208200141086a2900003703002004200129000037034020042000200441c0006a10b00420042802004101470d01200429030821092004200441106a280200220136023c20062004412c6a2902003703002007200441246a29020037030020082004411c6a290200370300200441c0006a412c6a4101360200200441e8006a200341086a2802003602002004200441146a29020037034020042003290200370360200141106a2009200441c0006a2004413c6a10d9060c030b200341046a280200450d020c010b024020042802042201412c6a280200220041004a0d00200141206a2105200441c0006a41086a2206200341086a280200360200200420032902003703400240200141246a280200450d0020012802201029200128022c21000b20052004290340370200200541086a20062802003602002001200041016a36022c0c020b2001200041016a36022c200341046a280200450d010b200510290b200441f0006a24000ba50202047f017e230041f0006b2203240002402001200041346a2204460d0020012004412010e707450d00200341c0006a41186a2204200141186a290000370300200341c0006a41106a2205200141106a290000370300200341c0006a41086a2206200141086a2900003703002003200129000037034020032000200341c0006a10b004024020032802004101470d00200329030821072003200341106a280200220136023c20042003412c6a2902003703002005200341246a29020037030020062003411c6a290200370300200341e8006a4280808080703703002003200341146a29020037034020034201370360200141106a2007200341c0006a2003413c6a10d9060c010b2003280204412c6a22012001280200417f6a3602000b200341f0006a24000b8d0101037f230041206b220324004101210402402001200041346a2205460d0020012005412010e707450d00200341186a200141186a290000370300200341106a200141106a290000370300200341086a200141086a2900003703002003200129000037030002402000200310bc0322010d00410021040c010b200128020c41004a21040b200341206a240020040b130020004106360204200041a8cfc9003602000b1300200041e8d4c900360204200020013602000b1300200041e8d4c900360204200020013602000bfa0301047f230041206b22042400024002400240024002400240024002402002200141346a2205460d0020022005412010e707450d00200441186a200241186a290000370300200441106a200241106a290000370300200441086a200241086a290000370300200420022900003703002001200410bc0322010d010c060b200141306a2802002202417f4c0d01200128022821060240024020020d0041002101410121070c010b200210272207450d03200221010b0240024020012002490d00200121050c010b200141017422052002200520024b1b22054100480d04024020010d002005102722070d010c060b20012005460d00200720012005102b2207450d050b20072006200210e4072101200041086a200236020020002005360204200020013602000c060b200128020c4101480d0420012802082202417f4c0d00200128020021060240024020020d0041002101410121070c010b200210272207450d02200221010b0240024020012002490d00200121050c010b200141017422052002200520024b1b22054100480d03024020010d00200510272207450d050c010b20012005460d00200720012005102b2207450d040b20072006200210e4072101200041086a200236020020002005360204200020013602000c050b1038000b1039000b1032000b1030000b200041003602000b200441206a24000b8d0101037f230041206b220324004101210402402001200041346a2205460d0020012005412010e707450d00200341186a200141186a290000370300200341106a200141106a290000370300200341086a200141086a2900003703002003200129000037030002402000200310bc0322010d00410021040c010b200128020c41004a21040b200341206a240020040b9f0303027f017e027f230041206b220224004193d4c800ad4280808080b00284100122032900002104200241086a200341086a290000370300200220043703002003102941a4a1c900ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000b9f0303027f017e027f230041206b220224004193d4c800ad4280808080b00284100122032900002104200241086a200341086a290000370300200220043703002003102941f7edca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000ba00401037f230041e00b6b22042400200441086a200110850720042004280208220520042802104180a6cc004100410010c701024002400240024002402004280200450d002004280204220620024d0d01200041093a000620004183243b0104200041013602002000410c6a4113360200200041086a41e7d5c8003602000c020b200041023a000620004183243b0104200041013602002000410c6a410f360200200041086a41ced6c8003602000c010b200441b0096a200110850720044188076a20042802b009220220042802b8091086072004280288072101200441bc096a20044188076a41047241a40210e4071a024002402001411c460d00200441e4046a200441bc096a41a40210e4071a024020042802b409450d00200210290b200441c0026a200441e4046a41a40210e4071a20042001360218200441186a410472200441c0026a41a40210e4071a20044188076a200441186a10c3012004290388072003560d01200041086a200441186a41a80210e4071a20004100360200200041b0026a2006360200200428020c450d040c030b024020042802b409450d00200210290b2000410c6a410f360200200041086a41ced6c800360200200041023a000620004183243b0104200041013602000c010b200041083a000620004183243b0104200041013602002000410c6a4113360200200041086a41fad5c800360200200441186a10cc010b200428020c450d010b200510290b200441e00b6a24000b8f0f0b017f017e037f017e017f027e037f027e057f027e067f230041c0036b220524000240024020000d002005413d6a200341086a290000370000200541c5006a200341106a290000370000200541cd006a200341186a290000370000200541033a00342005410a3a003020052003290000370035200541306a10cb0142002106410121070c010b2005413d6a200341086a2200290000370000200541c5006a200341106a2208290000370000200541cd006a200341186a2209290000370000200541023a00342005410a3a003020052003290000370035200541306a10cb01200541306a200410c3012005290330210a2002280204210b200541306a200441a80210e4071a200541e4026a2001360200200541d8026a41086a200b360200200541003a00dc02200541013a00d802200541086a200541306a200541d8026a10c501200541306a41186a2009290000370300200541306a41106a2008290000370300200541306a41086a200029000037030020052003290000370330200541086a41186a2d000021012005290310210c2005290308210d200520052900213703d8022005200541286a2800003600df0202400240200d4201510d00410421000c010b200520052800df0236008703200520052903d8023703800341042100200c4202510d0020052005280087033600b70320052005290380033703b003200121000b200541d8026a41086a2201200541306a41086a290300370300200541d8026a41106a2208200541306a41106a290300370300200541d8026a41186a2209200541306a41186a290300370300200520052903303703d802200520052903b0033703a003200520052800b7033600a703200541043a00342005410a3a00302005413d6a2001290300370000200541c5006a2008290300370000200541cd006a2009290300370000200541d8006a20003a0000200520052903d802370035200541d5006a20052f00b0033b0000200541d7006a200541b2036a2d00003a0000200541d9006a20052903a003370000200541e0006a20052800a703360000200541fc006a20054180036a41186a280200360200200541f4006a20054180036a41106a290200370200200541ec006a20054180036a41086a290200370200200541e4006a200529028003370200200541306a10cb01200541086a41106a290300200a200ca71b2106410021070b200541306a2003108507200535023842208620052802302200ad84100402402005280234450d00200010290b200541306a2003108207200535023842208620052802302200ad84100402402005280234450d00200010290b200541d8026a41186a220e4200370300200541d8026a41106a220f4200370300200541d8026a41086a22104200370300200542003703d8024193d4c800ad4280808080b00284221110012200290000210c2010200041086a2900003703002005200c3703d80220001029419fdec900ad4280808080900184221210012200290000210c200541086a41086a2213200041086a2900003703002005200c37030820001029200f2005290308220c370300200541306a41086a22142010290300370300200541306a41106a2215200c370300200541306a41186a22162013290300370300200520052903d802370330200541d8026a200541306a412010ce0120052802d8022200410120001b2117024020052902dc02420020001b22184220882219a72209450d0041002101201721004100210802400240034002400240024020032000460d0020002003412010e707450d0020010d01410021010c020b200141016a21010c010b200820016b220b20094f0d02200e200020014105746b220b41186a221a290000370300200f200b41106a221b2900003703002010200b41086a221c2900003703002005200b2900003703d802200041086a221d290000210c200041106a221e290000210a200041186a221f290000210d200b2000290000370000201a200d370000201b200a370000201c200c370000201f200e290300370000201e200f290300370000201d2010290300370000200020052903d8023700000b200041206a21002009200841016a2208460d020c000b0b200b20094180bdc7001036000b2001417f6a20094f0d00200920016bad2219422086201842ffffffff0f838421180b20164200370300201542003703002014420037030020054200370330201110012200290000210c2014200041086a2900003703002005200c37033020001029201210012200290000210c2013200041086a2900003703002005200c3703082000102920152005290308220c37030020102014290300370300200f200c370300200e2013290300370300200520052903303703d802201942017c210c0240024020170d00200541d8026aad428080808080048410040c010b200541203602342005200541d8026a36023020172019a7200541306a10cf01201842ffffff3f83500d00201710290b427f200642c0b6fc9a017c220a200a2006541b220a200c42ffffffff0f834290f41d7e7c210c02402007450d00200410cc010b200c200a54210002402002410c6a28020041ffffff3f71450d00200228020810290b427f200c20001b210c0240200241186a28020041ffffff3f71450d00200228021410290b200541c0036a2400200c0b9f0303027f017e027f230041206b220224004193d4c800ad4280808080b00284100122032900002104200241086a200341086a290000370300200220043703002003102941a4a1c900ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000bcd0201027f23004180056b220324002003200236020420032001360200200341086a2002ad4220862001ad841007108b0202400240200328020822010d002000411c3602000c010b200328020c21022003200341106a2802003602ec04200320013602e804200341c0026a200341e8046a10e4030240024020032802c0022204411c470d0020034100360220200342013703182003410d3602f404200320033602f0042003200341186a3602fc04200341d4026a4101360200200342013702c402200341f4eaca003602c0022003200341f0046a3602d002200341fc046a41a8a3c800200341c0026a10371a20033502204220862003350218841008200328021c450d01200328021810290c010b200341186a200341c0026a41047241a40210e4071a200041046a200341186a41a40210e4071a0b200020043602002002450d00200110290b20034180056a24000b9f0303027f017e027f230041206b2202240041a6d4c800ad4280808080b00284100122032900002104200241086a200341086a290000370300200220043703002003102941a4a1c900ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000b13002000410a360204200041e4d5c9003602000b880402097f017e230041d0006b220124000240024002400240200028020c22020d00410021020c010b200041146a28020021030240200041106a2802002200450d00034020022802800321022000417f6a22000d000b0b2003450d004100210403402002450d03410021050240200420022f0106490d00034002400240200228020022000d0041002104410021000c010b200541016a210520022f010421040b2002102920002102200420002f01064f0d000b200021020b200141286a41206a22062002200441226c6a220041286a2f00003b0100200141286a41186a2207200041206a290000370300200141286a41106a2208200041186a290000370300200141286a41086a2209200041106a2900003703002001200041086a290000370328200441016a210402402005450d00200220044102746a4180036a2802002102410021042005417f6a2200450d00034020022802800321022000417f6a22000d000b0b200141206a20062f01003b0100200141186a2007290300370300200141106a2008290300370300200141086a200929030037030020012001290328220a370300200aa741ff01714103460d022003417f6a22030d000b0b200141033a00000b02402002450d0020022802002100200210292000450d00034020002802002102200010292002210020020d000b0b200141d0006a24000f0b41a79dc800412b41e0f6c4001033000bf00f09027f017e057f017e017f017e017f027e0b7f230041d0026b22022400024002400240200128020022032001280204460d00200241f8006aad4280808080900484210420012802082105200241c4016a2106200241c5016a2107200241a0016a410472210803402001200341226a360200024002400240024020032d00000e03010200010b200341096a2209290000210a200341116a220b290000210c200341196a220d290000210e2003290001210f200241f8006a41206a2210200341216a22112d00003a0000200241f8006a41186a2212200e370300200241f8006a41106a2213200c370300200241f8006a41086a2214200a3703002002200f37037820041010221541086a290000210a201541106a290000210c2015290000210e200241d0006a41186a2216201541186a290000370300200241d0006a41106a2217200c370300200241d0006a41086a2218200a3703002002200e37035020151029200241b0026a41186a2016290300220a370300200241b0026a41106a2017290300220c370300200241b0026a41086a2018290300220e37030020022002290350220f3703b0022016200a3703002017200c3703002018200e3703002002200f370350201020112d00003a00002012200d2900003703002013200b2900003703002014200929000037030020022003290001370378410221100c020b200241b0026a41186a200341196a2215290000370300200241b0026a41106a200341116a2216290000370300200241b0026a41086a200341096a2217290000370300200220032900013703b002200241d0006a41186a2015290000370300200241d0006a41106a2016290000370300200241d0006a41086a201729000037030020022003290001370350200241f8006a41186a2015290000370300200241f8006a41106a2016290000370300200241f8006a41086a201729000037030020022003290001370378410021100c010b200241b0026a41186a200341196a2215290000370300200241b0026a41106a200341116a2216290000370300200241b0026a41086a200341096a2217290000370300200220032900013703b002200241d0006a41186a2015290000370300200241d0006a41106a2016290000370300200241d0006a41086a201729000037030020022003290001370350200241f8006a41186a2015290000370300200241f8006a41106a2016290000370300200241f8006a41086a201729000037030020022003290001370378410121100b20024190026a41186a2203200241d0006a41186a221529030037030020024190026a41106a2211200241d0006a41106a221629030037030020024190026a41086a2212200241d0006a41086a2217290300370300200241e8016a41086a2213200241f8006a41086a2218290300370300200241e8016a41106a2214200241f8006a41106a2209290300370300200241e8016a41186a2219200241f8006a41186a220b290300370300200241e8016a41206a221a200241f8006a41206a220d2d00003a00002002200229035037039002200220022903783703e8012008200229039002370200200841086a2012290300370200200841106a2011290300370200200841186a2003290300370200200720022903e801370000200741086a22112013290300370000200741106a22122014290300370000200741186a22132019290300370000200741206a201a2d00003a0000200220053602a001200220103a00c40102400240200128020c22030d00410321030c010b200241003602582002200336025420022001280210360250200241f8006a200241d0006a200610e9044103210320022802784101460d00200d200241a0016a41206a280200360200200b200241a0016a41186a2903003703002009200241a0016a41106a2903003703002018200241a0016a41086a290300370300201720112900003703002016201229000037030020152013290000370300200241d0006a411f6a2007411f6a280000360000200220022903a00137037820022007290000370350201021030b200241286a41086a2018290300370300200241286a41106a2009290300370300200241286a41186a200b290300370300200241286a41206a200d280200360200200241086a2017290300370300200241106a2016290300370300200241186a20152903003703002002411f6a200241d0006a411f6a2800003600002001200128020841016a2205360208200220022903783703282002200229035037030020034103470d02200128020022032001280204470d000b0b200041033a00240c010b200241a0016a41206a2201200241286a41206a280200360200200241a0016a41186a2207200241286a41186a290300370300200241a0016a41106a2208200241286a41106a290300370300200241a0016a41086a2215200241286a41086a290300370300200241f8006a41086a2216200241086a290300370300200241f8006a41106a2217200241106a290300370300200241f8006a41186a2218200241186a290300370300200241f8006a411f6a22092002411f6a280000360000200220022903283703a00120022002290300370378200041206a2001280200360200200041186a2007290300370200200041106a2008290300370200200041086a2015290300370200200020022903a001370200200020033a0024200020022903783700252000412d6a2016290300370000200041356a20172903003700002000413d6a2018290300370000200041c4006a20092800003600000b200241d0026a24000b23002000428080808010370200200041086a200128020420012802006b41226e3602000b920101027f23004190016b22032400200341c8006a2001108a0702400240024020032d006c4103460d00200241016a210403402003200341c8006a41c80010e407220241c8006a200241c80010e4071a2004417f6a2204450d02200241c8006a2001108a0720022d006c4103470d000b0b200041033a00240c010b2000200241c8006a41c80010e4071a0b20034190016a24000b1a000240200028020441ffffff3f71450d00200028020010290b0bf40206037f017e017f017e017f027e230041f0006b2102024020012802082203200128020c470d00200041033a00240f0b2001200341206a360208200241086a41086a2204200341086a2900002205370300200241086a41106a2206200341106a2900002207370300200241086a41186a2208200341186a29000022093703002003290000210a20012001280210220341016a3602102002200a370308200241286a41186a2009370300200241286a41106a2007370300200241286a41086a20053703002002200a370328200241c8006a41186a2009370300200241c8006a41106a2007370300200241c8006a41086a2005370300200020033602002000200a3700252000412d6a2005370000200041356a20073700002000413d6a2009370000200041c5006a200241c8006a41206a2d00003a00002002200a370348200020022903083702042000410c6a2004290300370200200041146a20062903003702002000411c6a2008290300370200200041013a00240b2e0020004101360204200041086a2001410c6a280200200141086a2802006b4105752201360200200020013602000bd50503057f047e0b7f230041c0016b2203240002400240024020012802082204200128020c2205460d002001280210210603402001200441206a2207360208200441186a2900002108200441106a2900002109200441086a290000210a2004290000210b2001200641016a220c360210200341f8006a41086a2204200a370300200341f8006a41106a220d2009370300200341f8006a41186a220e2008370300200341d8006a41106a2009370300200341d8006a41186a2008370300200341d8006a41086a200a370300200341306a41086a220f200a370300200341306a41106a22102009370300200341306a41186a221120083703002003200b3703782003200b3703582003200b370330200341086a41206a2212200341f8006a41206a22132d00003a0000200341086a41186a2214200e290300370300200341086a41106a2215200d290300370300200341086a41086a2216200429030037030020032003290378370308200320032f01563b0106200341a0016a41086a200f290300370300200341a0016a41106a2010290300370300200341a0016a41186a2011290300370300200320032903303703a00120042016290300370300200d2015290300370300200e2014290300370300201320122d00003a000020032003290308370378200320032f01063b01582002450d022002417f6a2102200c21062007210420052007470d000b0b200041033a00240c010b20002006360200200020032903a001370204200041013a0024200020032903783700252000410c6a200341a0016a41086a290300370200200041146a200341a0016a41106a2903003702002000411c6a200341a0016a41186a2903003702002000412d6a200341f8006a41086a290300370000200041356a200341f8006a41106a2903003700002000413d6a200341f8006a41186a290300370000200041c5006a20034198016a2d00003a0000200041c6006a20032f01583b01000b200341c0016a24000ba00605057f017e037f027e027f230041f0006b22022400200241286a200141146a350200422086200135020c841015108b020240024020022802282203450d00200141086a2104200141106a210503400240024020042802002206200229022c2207422088a722084b0d00200128020022092003460d0120092003200610e707450d010b2007a7450d02200310290c020b02402005280200450d00200128020c10290b2001200336020c20052007370200200241086a2003200810fb05024002402002280218220a450d00200241086a41086a29030021072002290308210b2002290320210c200228021c210d024020012d0018450d002001350214422086200135020c8410040b2001280214220820042802002203490d0102400240200820036b22084108490d00200841786a2106200128020c20036a41086a21090c010b41002106024041002802d8a74c0d004180a6cc0021090c010b4100210641002802888040210341002802848040210841002802dca74c210e200241e600360268200242dc80808010370360200241db9fc00036025c20024213370254200241c89fc000360250200242003703484180a6cc00210920024180a6cc0036024420024201370338200241c09fc00036023420024113360230200241c89fc00036022c2002410136022820084180a4c000200e410246220e1b200241286a20034198a4c000200e1b2802101102000b41002103200241003a00480240034020062003460d01200241286a20036a200920036a2d00003a00002002200341016a22083a00482008210320084120470d000b20002002290328370000200041186a200241286a41186a290300370000200041106a200241286a41106a290300370000200041086a200241286a41086a290300370000200041286a20073703002000200b370320200041386a200c3703002000200d3602342000200a3602300c050b0240200341ff0171450d00200241003a00480b200d41ffffff3f71450d00200a10290b200241286a2001350214422086200135020c841015108b02200228022822030d010c020b0b2003200841bcf7c900104c000b200041003602300b200241f0006a24000b130020004102360204200041bcf8c9003602000b3400200041b1dcc90036020420004100360200200041146a4107360200200041106a418481ca00360200200041086a42073702000b2c01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241003600000b130020004108360204200041a48cca003602000b340020004197dec90036020420004100360200200041146a4105360200200041106a41e8b5ca00360200200041086a42083702000b130020004109360204200041b0bfca003602000b3501017f02404108102722020d001039000b20004288808080800137020420002002360200200242f0f2bda1a7ee9cb9f9003700000b3701017f02404110102722020d001039000b2002420037000820024280c8afa025370000200042908080808002370204200020023602000b2b01017f02404101102722020d001039000b200042818080801037020420002002360200200241143a00000b2e01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241c0f0003600000b2e01017f02404104102722020d001039000b20004284808080c0003702042000200236020020024190ce003600000b2e01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241808c153600000b2e01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241d086033600000b130020004107360204200041b8cbca003602000b34002000419ad6ca0036020420004100360200200041146a4102360200200041106a41b0d6ca00360200200041086a42133702000b900a030a7f027e017f230041106b220224002002410036020820024201370300024002400240412010272203450d002003200029004c370000200341186a2204200041e4006a290000370000200341106a2205200041dc006a290000370000200341086a2206200041d4006a290000370000412010272207450d02200241203602042002200736020020072003290000370000200741086a2006290000370000200741106a2005290000370000200741186a200429000037000020024120360208200310292007412041c000102b2203450d022003200029006c370020200341286a200041f4006a290000370000200341306a200041fc006a290000370000200341386a20004184016a29000037000020022003360200200242c080808080083702040240024020002903004201510d00200341c000418001102b2203450d04200341003a004020024180013602042002200336020041c10021070c010b200341c000418001102b2203450d03200341013a00402003200041086a2207290000370041200341e9006a200041306a2903003700002003200041286a290300370061200341c9006a200741086a290000370000200341d1006a200741106a290000370000200341d9006a200741186a2900003700002002200336020020024280818080900c37020441f10021070b200220073602080240024020002802384101460d00200320076a41003a0000200741016a21030c010b200320076a41013a00002002200741016a22033602082000413c6a2802002106024002402002280204220520036b4104490d00200228020021040c010b41000d0320054101742204200341046a2208200420084b1b22084100480d030240024020050d002008102722040d010c060b2002280200210420052008460d00200420052008102b2204450d050b20022008360204200220043602000b200420036a2006360000200741056a21030b2002200336020820002802402109200041c8006a2802002200200210710240024020000d002002280208210020022802042107200228020021050c010b2009200041306c6a210a41002002280208220b6b210620022802042107410021030340200b20036a210802400240200720066a4120490d0020022802002105200721040c010b200841206a22002008490d04200741017422042000200420004b1b22044100480d040240024020070d00024020040d00410121050c020b200410272205450d070c010b2002280200210520072004460d00200520072004102b2205450d060b20022004360204200220053602000b2005200b6a20036a2207200920036a2200290000370000200741186a200041186a290000370000200741106a200041106a290000370000200741086a200041086a2900003700002002200841206a2207360208200041286a290300210c200041206a290300210d02400240200420066a41606a410f4d0d00200421070c010b200741106a220e2007490d0420044101742207200e2007200e4b1b22074100480d040240024020040d00024020070d00410121050c020b200710272205450d070c010b20042007460d00200520042007102b2205450d060b20022007360204200220053602000b2005200b6a20036a220441286a200c370000200441206a200d3700002002200841306a360208200641506a2106200341306a2103200a200041306a470d000b200b20036a21000b20012902002000ad4220862005ad84100302402007450d00200510290b200241106a24000f0b1039000b1032000b1030000b1c00200128021841b09bcc00410f2001411c6a28020028020c1100000b9f0303027f017e027f230041206b220224004197dec900ad4280808080800184100122032900002104200241086a200341086a29000037030020022004370300200310294190bbca00ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310290240412010272203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010272201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003102941c00010272203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011029200241206a24000f0b1039000bb10503027f017e047f230041d0006b220224004197dec900ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941b8baca00ad4280808080c00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000ba11005097f037e027f037e037f230041f0026b220324002003200236020c20032001360208200341106a2002ad4220862001ad841007108b0202400240200328021022040d00200042023703000c010b200328021421052003200341186a28020022063602a401200320043602a00141002107200341003a00e8022004210220062101024002400240024002400240024002400340200721082001450d01200341c8026a20086a20022d00003a000020032001417f6a22013602a4012003200241016a22023602a0012003200841016a22073a00e80220074120470d000b200341a8016a41086a200341c8026a41086a290300370300200341a8016a41106a200341c8026a41106a290300370300200341a8016a41186a200341c8026a41186a290300370300200320032903c8023703a80141002107200341003a00e802200620086b417e6a2108034020012007460d02200341c8026a20076a200220076a22062d00003a00002003200641016a3602a0012003200741016a22063a00e802200320083602a4012008417f6a21082006210720064120470d000b200341c8016a41086a200341c8026a41086a290300370300200341c8016a41106a200341c8026a41106a290300370300200341c8016a41186a200341c8026a41186a290300370300200320032903c8023703c80120012006460d05200220066a22092d00002102200320083602a4012003200941016a22073602a001200241014b0d0520020e020302030b200841ff0171450d04200341003a00e8020c040b200741ff0171450d03200341003a00e8020c030b200941116a210741002102200341003a00e802200120066b416f6a21010240034020082002460d01200341c8026a20026a200920026a41016a2d00003a000020032001410f6a3602a4012003200741716a3602a0012003200241016a22063a00e8022001417f6a2101200741016a21072006210220064120470d000b200341a8026a41186a2202200341c8026a41186a290300370300200341a8026a41106a220a200341c8026a41106a290300370300200341a8026a41086a220b200341c8026a41086a290300370300200320032903c8023703a802200820066b4110490d03200920066a220841096a290000210c200841016a290000210d20034188026a41086a200b29030037030020034188026a41106a200a29030037030020034188026a41186a2002290300370300200320013602a401200320073602a001200320032903a802370388024201210e200121080c020b200241ff0171450d02200341003a00e8020c020b4200210e0b200341e8016a41186a20034188026a41186a290300370300200341e8016a41106a20034188026a41106a290300370300200341e8016a41086a20034188026a41086a29030037030020032003290388023703e8012008450d0020072d0000210120032008417f6a22023602a4012003200741016a3602a001200141014b0d00410021060240024020010e020100010b20024104490d012007280001210920032008417b6a3602a4012003200741056a3602a001410121060b200341c8026a200341a0016a10f40520032802c8020d010b200341003602b002200342013703a8022003410d36028c022003200341086a360288022003200341a8026a3602e801200341dc026a4101360200200342013702cc02200341f4eaca003602c802200320034188026a3602d802200341e8016a41a8a3c800200341c8026a10371a20033502b00242208620033502a802841008024020032802ac02450d0020032802a80210290b4202210e0c010b200341f0006a41086a2202200341c8026a41086a2201280200360200200341d0006a41086a2207200341a8016a41086a290300370300200341d0006a41106a2208200341a8016a41106a290300370300200341d0006a41186a220a200341a8016a41186a290300370300200341306a41086a220b200341c8016a41086a290300370300200341306a41106a220f200341c8016a41106a290300370300200341306a41186a2210200341c8016a41186a290300370300200320032903c802370370200320032903a801370350200320032903c80137033020034180016a41186a200341e8016a41186a290300221137030020034180016a41106a200341e8016a41106a290300221237030020034180016a41086a200341e8016a41086a290300221337030020012013370300200341c8026a41106a22142012370300200341c8026a41186a22152011370300200341206a41086a22162002280200360200200320032903e801221137038001200320113703c80220032003290370370320200341a8026a41186a2202200a290300370300200341a8026a41106a220a2008290300370300200341a8026a41086a22082007290300370300200320032903503703a80220034188026a41186a2207201029030037030020034188026a41106a2210200f29030037030020034188026a41086a220f200b2903003703002003200329033037038802200041306a200c370300200041286a200d3703002000413c6a2009360200200041386a2006360200200041206a2015290300370300200041186a2014290300370300200041106a2001290300370300200020032903c802370308200041c0006a2003290320370300200041c8006a2016280200360200200020032903a80237024c200041d4006a2008290300370200200041dc006a200a290300370200200041e4006a200229030037020020004184016a2007290300370200200041fc006a2010290300370200200041f4006a200f290300370200200020032903880237026c0b2000200e3703002005450d00200410290b200341f0026a24000b8d0303047f017e027f230041d0006b22012400200141206a41186a4200370300200141206a41106a22024200370300200141206a41086a22034200370300200142003703204196ebca00ad42808080808002841001220429000021052003200441086a290000370300200120053703202004102941f0edca00ad4280808080f00084100122042900002105200141c0006a41086a2206200441086a2900003703002001200537034020041029200220012903402205370300200141086a2003290300370300200141106a2005370300200141186a200629030037030020012001290320370300200141206a200110a90720012802202204410820041b2107410021030240024002402001290224420020041b2205422088a7220441014b0d0020040e020201020b03402004410176220220036a220620032007200641306c6a2000412010e7074101481b2103200420026b220441014b0d000b0b2007200341306c6a2000412010e7074521030b02402005a72204450d00200441306c450d00200710290b200141d0006a240020030bb10503027f017e047f230041d0006b220224004197dec900ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003102941b8baca00ad4280808080c00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000b830404047f017e037f027e230041d0006b22012400200141206a41186a4200370300200141206a41106a22024200370300200141206a41086a22034200370300200142003703204196ebca00ad42808080808002841001220429000021052003200441086a290000370300200120053703202004102941f0edca00ad4280808080f00084100122042900002105200141c0006a41086a2206200441086a2900003703002001200537034020041029200220012903402205370300200141086a2003290300370300200141106a2005370300200141186a200629030037030020012001290320370300200141206a200110a90720012802202103200129022421052001410036022820014201370320200141206a41002005420020031b2205422088a7220441306c220641306d109e012005a721072003410820031b21082001280228210202402004450d00200128022020024105746a2103200821040340200441086a2900002105200441106a29000021092004290000210a200341186a200441186a290000370000200341106a2009370000200341086a20053700002003200a370000200241016a2102200341206a2103200441306a2104200641506a22060d000b0b2001200236022802402007450d00200741306c450d00200810290b20002001290320370200200041086a200141206a41086a280200360200200141d0006a24000bbf0201027f230041e0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841007108b0202400240200228021022010d00200041003602000c010b200228021421032002200241106a41086a28020036022420022001360220200241c8006a200241206a10f4050240024020022802480d0020024100360230200242013703282002410d36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241f4eaca003602482002200241386a360258200241c4006a41a8a3c800200241c8006a10371a200235023042208620023502288410080240200228022c450d00200228022810290b200041003602000c010b20002002290348370200200041086a200241c8006a41086a2802003602000b2003450d00200110290b200241e0006a24000b130020004104360204200041f0d9ca003602000b13002000410836020420004188dcca003602000bb10503027f017e047f230041d0006b220224004196ebca00ad4280808080800284100122032900002104200241086a41086a200341086a290000370300200220043703082003102941f7edca00ad4280808080e00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310290240024002400240412010272203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841002220129000037033820011029200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a1075200310292002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110272203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008102722030d010c050b20072008460d00200320072008102b2203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d00200320082007102b2203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d00200320072008102b2203450d040b200341206a2006200510e4071a2000200136020820002008360204200020033602000240200228022c450d00200610290b200241d0006a24000f0b1039000b1038000b1032000b1030000bfc0201037f024020002d0000417f6a2201410b4b0d0002400240024002400240024020010e0c000606060106020304060605000b200041046a2802004102490d05200041106a2802002201450d05200041146a280200450d05200110290f0b200041086a280200450d04200041046a28020010290c040b200041046a2802000d032000410c6a2802002201450d03200141286c450d03200041086a28020010290f0b200041046a2d00004102490d020240200041106a2802002201450d00200141d0006c2102200041086a28020041c4006a21010340024020012802002203450d00200341306c450d002001417c6a28020010290b200141d0006a2101200241b07f6a22020d000b0b2000410c6a2802002201450d02200141d0006c450d02200028020810290f0b200041086a2d00004101470d01200041146a28020041ffffff3f71450d01200041106a28020010290f0b200041046a2d00000d002000410c6a2802002201450d00200141306c450d00200041086a28020010290f0b0b13002000410a360204200041fcf9ca003602000b3400200041b3e6ca0036020420004100360200200041146a410f360200200041106a41a895cb00360200200041086a42063702000b2b01017f02404101102722020d001039000b200042818080801037020420002002360200200241003a00000be00101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002400240412010272206450d0020062002290300370000200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000412010272203450d0120032006290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a29000037000020061029200042a0808080800437020420002003360200200241206a24000f0b1039000b1030000b4201017f0240410810272202450d0020024200370000200241084110102b2202450d0020004290808080800237020420002002360200200242003700080f0b1030000bae0101017f0240410410272202450d0020024100360000200241044108102b2202450d00200241003a0004200241084115102b2202450d00200242003700052002410d6a420037000020024115412a102b2202450d00200242003700152002411d6a42003700002002412a41d400102b2202450d002002420037003520024200370025200042d4808080d008370204200020023602002002413d6a42003700002002412d6a42003700000f0b1030000b1300200041063602042000419cafcb003602000b2f01017f02404104102722020d001039000b20004284808080c000370204200020023602002002418080c0023600000b2f01017f02404108102722020d001039000b20004288808080800137020420002002360200200242c0b2cd3b3700000b3001017f02404108102722020d001039000b2000428880808080013702042000200236020020024280e497d0123700000b4801017f0240410810272202450d00200242c0f0f50b370000200241084110102b2202450d002000429080808080023702042000200236020020024280c2d72f3700080f0b1030000b3101017f02404108102722020d001039000b2000428880808080013702042000200236020020024280c0a8ca9a3a3700000b2d01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241e0123600000b13002000410636020420004194b8cb003602000b340020004196ebca0036020420004100360200200041146a4105360200200041106a41d8e5cb00360200200041086a42103702000b6201027f230041106b220224000240411410272203450d00200342003700082003420037000020024294808080800237020420022003360200410020021071200041086a200228020836020020002002290300370200200241106a24000f0b1039000b130020004106360204200041cceecb003602000b3501017f02404108102722020d001039000b20004288808080800137020420002002360200200242f0d0c9abc6add9b1f4003700000b2c01017f02404104102722020d001039000b20004284808080c00037020420002002360200200241143600000b2c01017f02404104102722020d001039000b20004284808080c000370204200020023602002002410d3600000b3801017f02404110102722020d001039000b2002420037000820024280e8eda1ba01370000200042908080808002370204200020023602000b13002000410536020420004184f3cb003602000bea1508047f017e077f027e037f017e017f037e230041d0016b22022400200241b0016a41186a4200370300200241b0016a41106a22034200370300200241b0016a41086a22044200370300200242003703b0014196ebca00ad42808080808002841001220529000021062004200541086a290000370300200220063703b0012005102941f0edca00ad4280808080f00084100122052900002106200241f0006a41086a2207200541086a290000370300200220063703702005102920032002290370220637030020024190016a41086a200429030037030020024190016a41106a200637030020024190016a41186a2007290300370300200220022903b00137039001200241d0006a20024190016a10a907024002400240200228025022080d00410021092002410036020820024208370300410821080c010b200220022902542206370204200220083602002006a7210941002104024002402006422088a7220a41014b0d00200a0e020201020b200a210503402005410176220720046a220b20042008200b41306c6a2001412010e7074101481b2104200520076b220541014b0d000b0b2008200441306c6a2001412010e7070d0002400240024002402004200a4f0d002008200441306c6a2205200541306a200a2004417f736a41306c10e5071a2002200a417f6a220c360208200241b0016a41186a220b4200370300200241b0016a41106a220d4200370300200241b0016a41086a22044200370300200242003703b0014196ebca00ad4280808080800284220e1001220529000021062004200541086a290000370300200220063703b0012005102941eaf8ca00ad4280808080900184220f100122072900002106200241f0006a41086a2205200741086a290000370300200220063703702007102920032002290370370000200341086a200529030037000020024190016a41086a2203200429030037030020024190016a41106a2210200d29030037030020024190016a41186a2211200b290300370300200220022903b00137039001200241b0016a20024190016a10a90720022802b0012207410820071b21120240024020022902b401420020071b2206422088a722070d00420021130c010b200b20122007417f6a221441306c6a220741186a290300370300200d200741106a2903003703002004200741086a290300370300200220072903003703b0012014ad422086200642ffffffff0f83842106200741286a290300211520072903202116420121130b2011200b2903003703002010200d29030037030020032004290300370300200220022903b00137039001200241f0006a41186a4200370300200241f0006a41106a220342003703002005420037030020024200370370200e10012207290000210e2004200741086a2900003703002002200e3703b0012007102920052004290300370300200220022903b001370370200f10012207290000210e2004200741086a2900003703002002200e3703b00120071029200320022903b001220e370300200241d0006a41086a2005290300370300200241d0006a41106a200e370300200241d0006a41186a2004290300370300200220022903703703500240024020120d00200241d0006aad428080808080048410040c010b200241203602b4012002200241d0006a3602b00120122006422088a7200241b0016a10c9062006a72204450d00200441306c450d00201210290b200241106a41186a20024190016a41186a22042903002206370300200241106a41106a20024190016a41106a2205290300220e370300200241106a41086a20024190016a41086a2207290300220f37030020022002290390012217370310200241306a41186a220b2006370300200241306a41106a220d200e370300200241306a41086a2212200f370300200220173703300240201350450d00200c210a4100210d0c040b2004200b2903003703002005200d29030037030020072012290300370300200220022903303703900141002104024002400240200a417f6a220541014b0d0020050e020201020b200c210503402005410176220720046a220b20042008200b41306c6a20024190016a412010e7074101481b2104200520076b220541014b0d000b0b2008200441306c6a20024190016a412010e7072205450d022005411f7620046a21040b200241d0006a41186a20024190016a41186a2903002206370300200241d0006a41106a20024190016a41106a290300220e370300200241d0006a41086a20024190016a41086a290300220f37030020022002290390012213370350200241f0006a41186a2006370300200241f0006a41106a200e370300200241f0006a41086a200f37030020022013370370200241b0016a41186a2006370300200241b0016a41106a200e370300200241b0016a41086a200f370300200220133703b001200c2004490d020240200c2009470d0020022009410110900120022802042109200228020021080b2008200441306c6a220541306a2005200c20046b41306c10e5071a200541286a201537030020052016370320200541186a200241b0016a41186a290300370300200541106a200241b0016a41106a290300370300200541086a200241b0016a41086a290300370300200520022903b0013703002002200a3602084101210d0c030b2004200a1042000b200241d0006a41186a20024190016a41186a290300370300200241d0006a41106a20024190016a41106a290300370300200241d0006a41086a20024190016a41086a29030037030020022002290390013703504100210d200c210a0c010b2004200c1041000b200241f0006a41186a220b4200370300200241f0006a41106a22124200370300200241f0006a41086a22054200370300200242003703704196ebca00ad4280808080800284100122072900002106200241b0016a41086a2204200741086a290000370300200220063703b0012007102920052004290300370300200220022903b00137037041f0edca00ad4280808080f000841001220729000021062004200741086a290000370300200220063703b00120071029200320022903b001370000200341086a2004290300370000200241d0006a41086a2005290300370300200241d0006a41106a2012290300370300200241d0006a41186a200b29030037030020022002290370370350200241203602b4012002200241d0006a3602b0012008200a200241b0016a10c906200241003602b801200242013703b001200241b0016a4100200a41306c220b41306d109e0120022802b80121070240200a450d0020022802b00120074105746a2104200821050340200541086a2900002106200541106a290000210e2005290000210f200441186a200541186a290000370000200441106a200e370000200441086a20063700002004200f370000200741016a2107200441206a2104200541306a2105200b41506a220b0d000b0b200220073602b80102402009450d00200941306c450d00200810290b20022802b401210520022802b0012104200241b0016a41186a200141186a290000370300200241b0016a41106a200141106a290000370300200241b0016a41086a200141086a290000370300200220012900003703b001200241b0016a41012004200710ef062000200d3a0001200041003a0000200041026a200229019001370100200041086a20024196016a290100370100200541ffffff3f71450d01200410290c010b200041013a00002000410c6a4109360200200041086a41eeebca00360200200041066a410c3a0000200041046a4183283b01002009450d00200941306c450d00200810290b200241d0016a24000b13002000411136020420004190f8cb003602000b8903010a7f230041206b220124000240024002400240200041086a2802002202450d00410020024102746b2103417f210420002802002205210603402003450d01200441016a2104200341046a210320062802002107200641046a21062007450d000b4100200741004741016a41017122066b2004460d002002200620046a2208490d012002200741004741016a4101716b20046b220641ffffffff03712006470d0220064102742209417f4c0d024104210a02402009450d0020091027220a450d040b200141003602182001200a36021020012009410276360214200141106a410020061098012001280210200128021822064102746a200520084102746a4104200741004741016a410171220741027420036a6b10e4071a200141086a22032002200620076b6a20046b360200200120012903103703000240200041046a28020041ffffffff0371450d00200028020010290b20002001290300370200200041086a20032802003602000b200141206a24000f0b2008200241ec8bcc00104c000b1038000b1039000bb90403077f017e097f02400240024002400240200141086a2802002203200241086a2802002204200320044b1b220541016a22064101200641014b1b220741ffffffff03712007470d0020074102742208417f4c0d002008102d2209450d01024020050d004200210a0c040b2004417f6a220b20044b210c2002280200210d2003417f6a220e20034b0d022001280200210f2007417f6a2102200820096a417c6a2110410021064200210a03404100211102402003200e20066b22124d0d00410021112012200e4b0d00200f20124102746a28020021110b410021120240200c0d002004200b20066b22134d0d002013200b4b0d00200d20134102746a28020021120b200720024d0d052010200a2011ad7c2012ad7c220a3e02002010417c6a21102002417f6a2102200a422088210a200641016a22062005490d000c040b0b1038000b1039000b2007417f6a2102200820096a417c6a2111410021104200210a0340410021060240200c0d00410021062004200b20106b22124d0d00410021062012200b4b0d00200d20124102746a28020021060b200720024d0d022011200a2006ad7c220a3e02002011417c6a21112002417f6a2102200a422088210a201041016a22102005490d000b0b024020072005417f736a220220074f0d00200020073602082000200841027636020420002009360200200920024102746a200a3e02000240200141046a28020041ffffffff0371450d00200128020010290b0f0b2002200741dc8bcc001036000b2002200741dc8bcc001036000bb404030e7f017e017f02400240200241086a2802002203200141086a28020022046a22054101200541014b1b220641ffffffff03712006470d0020064102742207417f4c0d0002402007102d2208450d002004450d022001280200210902400240024020030d002006417f6a2105200720086a417c6a210a20092004417f6a22024102746a21030340200420024d0d0302402003280200450d00200620054d0d03200a41003602000b2003417c6a2103200a417c6a210a2005417f6a21052002417f6a2202417f470d000c060b0b200720086a417c6a210b200341027420022802006a417c6a210c4100210d2006210e03402004200d417f736a220220044f0d020240200920024102746a220f2802002210450d0042002111417f2102200b2105200c210a024003402006200e20026a22124d0d012005200a3502002010ad7e20117c20053502007c22113e0200201142208821110240200320026a0d002006200d20036a417f736a220520064f0d05200820054102746a20113e02000c030b2005417c6a2105200a417c6a210a200f280200211020032002417f6a22026a22122003490d000b2012200341cc8bcc001036000b2012200641cc8bcc001036000b200b417c6a210b200e417f6a210e200d41016a220d2004460d050c000b0b2005200641dc8bcc001036000b2002200441cc8bcc001036000b1039000b1038000b2000200636020820002007410276360204200020083602000240200141046a28020041ffffffff0371450d00200128020010290b0bca0302097f017e230041106b2201240002400240024002400240024002402000280200220228020041016a41004c0d002000280204220328020041016a41004c0d012000280208220441086a28020022054101200028020c22062802006b22076a220820054f0d02200720002802142802006b22052000280210220741086a28020022006a220920054f0d03024002402002290308220a42ffffffff0f560d0041002100200a200428020020084102746a3502007e2003290308422086200728020020094102746a35020084580d010b20022802000d052002410036020020022002290308427f7c370308200441086a2802002200200020062802006b22024d0d0620032802000d07200428020020024102746a350200210a200341003602002003200a20032903087c370308410121000b200141106a240020000f0b41cc8ccc004118200141086a41e48ccc0041f48ccc00103a000b41cc8ccc004118200141086a41e48ccc0041f48ccc00103a000b2008200541cc8bcc001036000b2009200041cc8bcc001036000b41c78dcc004110200141086a41d88dcc0041e88dcc00103a000b2002200041cc8bcc001036000b41c78dcc004110200141086a41d88dcc0041e88dcc00103a000ba80301087f200028020822024102742103410021042000280200220521000240024003402003450d012004417f6a21042003417c6a210320002802002106200041046a21002006450d000b410121072004417f73200641004741016a4101716a21080c010b41002107410020046b21080b200128020822094102742103410021042001280200220121000240024003402003450d012004417f6a21042003417c6a210320002802002106200041046a21002006450d000b410021032004417f73200641004741016a4101716a21000c010b410020046b2100410121030b024020070d00410020034101736b0f0b4101210402400240024020030d0020022008490d0120092000490d02417f200220086b2203200920006b22064720032006491b22040d0020062003200320064b1b2107200120004102746a2103200520084102746a2100417f210103400240200141016a22012007490d0041000f0b2003280200210420002802002106200341046a2103200041046a2100417f200620044720062004491b2204450d000b0b20040f0b2008200241fc8bcc00104c000b20002009418c8ccc00104c000b100020002802002000280204200110650bcd04010a7f230041106b220224002002410036020820024204370300200128000c2103410021040240024002400240024002400240024020012802042205200128020022064920012d00084100477222010d004100200520066b2204200420054b1b220741016a220420074f0d00200341086a21084100210441042109410021010340200828020022072005417f736a220a20074f0d02200620054f2107200520062005496b21052003280200200a4102746a280200210a024020012002280204470d0020022001417f41004100417f4100200520066b2209200920054b1b220941016a220b200b2009491b20071b20052006491b220941016a220b200b2009491b109801200228020021090b200920046a200a3602002002200141016a2201360208200441046a21042005200649200772450d000c070b0b2002410020041098012002280208210b20010d042002280200200b4102746a2104200520064d0d012005417f732101200341086a21092005210703402001200928020022086a220a20014f0d0320042003280200200a4102746a280200360200200141016a2101200441046a210420062007417f6a2207490d000b200520066b200b6a210b0c030b200a200741cc8bcc001036000b20052006460d010c020b200a200841cc8bcc001036000b200341086a28020022052006417f736a220620054f0d022004200328020020064102746a280200360200200b41016a210b0b2002200b3602080b20002002290300370200200041086a200241086a280200360200200241106a24000f0b2006200541cc8bcc001036000b1c00200128021841b09bcc00410f2001411c6a28020028020c1100000bb00301047f230041c0006b2202240020002802002103410121000240200128021841c29dc000410c2001411c6a28020028020c1100000d0002400240200328020822000d0020032802002200200328020428020c11070042e4aec285979ba58811520d012002200036020c2002411e36021420022002410c6a36021020012802182104200128021c2105410121002002413c6a41013602002002420237022c200241d09dc0003602282002200241106a36023820042005200241286a10370d020c010b2002200036020c2002410836021420022002410c6a36021020012802182104200128021c2105410121002002413c6a41013602002002420237022c200241d09dc0003602282002200241106a36023820042005200241286a10370d010b200328020c2100200241106a41146a4101360200200241106a410c6a410136020020022000410c6a3602202002200041086a360218200241043602142002200036021020012802182100200128021c2101200241286a41146a41033602002002420337022c200241e09dc0003602282002200241106a36023820002001200241286a103721000b200241c0006a240020000b21002000417f6a41ff01712002ad4220862001ad842004ad4220862003ad8410000b1c00200128021841b09bcc00410f2001411c6a28020028020c1100000bca0201047f230041106b22022400024002400240024020002d002c410171450d0002400240200028020041244b0d00200041056a2103200021040c010b2000410c6a2104200041086a28020021030b20042802002204450d02200420036a417f6a2203450d02200320032d00002001723a00000c010b41242104024002402000280200220541244b0d00200021030c010b2000410c6a2103200521040b0240200328020022032004470d0020022000410110d20720022802004101470d00200241086a2802000d0341a4a1cc00411141b8a1cc001033000b2001410474210102400240200028020041244b0d00200041056a2104200021050c010b2000410c6a2105200041086a28020021040b2005200341016a360200200420036a20013a00000b2000200028022c41016a36022c200241106a24000f0b41e09ccc00413a419c9dcc001057000b1030000bb20301057f41242103024002402001280200220441244b0d00200421050c010b2001410c6a2802002105200421030b4100210602400240024002400240200320056b20024f0d00200520026a22022005490d0241002105024020024102490d00417f2002417f6a677621050b200541016a22032005490d024124210202400240200441244b0d00200141056a2107200421050c010b2001410c6a2802002105200141086a2802002107200421020b200520034b0d030240024020034125490d004100210620022003460d02200441244b0d03200310272202450d0120022007200510e4071a0c060b4100210620044125490d01200141003a0004200141056a2007200510e4071a2001200536020020071029200041003602000f0b2000200336020441012106200041086a41013602000b200020063602000f0b200720022003102b22020d0220002003360204200041086a4101360200200041013602000f0b20002003360204200041086a4100360200200041013602000f0b41e6a1cc00412041b8a1cc001033000b200141013a0004200120033602002001410c6a2005360200200141086a2002360200200041003602000bf109010a7f230041106b220224002000280200210320002001360200024002400240024002400240024002400240024002400240024002400240024002400240200320014b0d00200320014f0d10200041046a2101412421042000280204220541244b0d01200121030c020b200041046a280200220321010240200341244d0d00200041106a28020021010b2001417f6a2206450d0d2001417e6a2107200041096a210841002101034002400240200341244b22040d0020082109200321050c010b20002802102105200028020c21090b200520014d0d03200141016a2105200920016a2d000021090240024020040d002008210a2003210b0c010b2000280210210b200028020c210a0b200b20054d0d04200a20016a41016a2d0000210a0240024020040d00200821040c010b20002802102103200028020c21040b200320014d0d05200420016a200a4104762009410474723a0000200041046a2802002103024020072001460d00200521010c010b0b02400240200341244b0d0020082101200321040c010b20002802102104200028020c21010b200420064d0d05200120066a2d000021010240200341244d0d0020002802102103200028020c21080b200320064d0d060c0e0b200041106a2103200521040b0240200328020022032004470d0020022001410110d20720022802004101470d00200241086a2802000d0641a4a1cc00411141b8a1cc001033000b02400240200128020041244b0d00200041096a21040c010b200041106a21012000410c6a28020021040b2001200341016a360200200420036a41003a0000200041046a280200220321010240200341244d0d00200041106a28020021010b024020014102490d002001417f6a2101200041096a210803402001417f6a210402400240200341244b22050d00200821092003210a0c010b2000280210210a200028020c21090b200a20044d0d08200920016a417f6a2d000021090240024020050d002008210a2003210b0c010b2000280210210b200028020c210a0b200b20014d0d09200a20016a2d0000210a0240024020050d00200821050c010b20002802102103200028020c21050b200320014d0d0a200520016a200a4104762009410474723a0000200141014b2105200041046a28020021032004210120050d000b0b02400240200341244b0d00200041096a2101200321040c010b200041106a28020021042000410c6a28020021010b2004450d0920012d0000210102400240200341244b0d00200041096a21000c010b200041106a28020021032000410c6a28020021000b2003450d0a2000200141f001714104763a00000c0d0b2001200541dca4cc001036000b200141016a200b41eca4cc001036000b2001200341fca4cc001036000b2006200441bca4cc001036000b2006200341cca4cc001036000b1030000b2001417f6a200a4188a2cc001036000b2001200b4198a2cc001036000b2001200341a8a2cc001036000b41004100418ca5cc001036000b41004100419ca5cc001036000b02400240200341244b0d00200041096a2101200321040c010b200041106a28020021042000410c6a28020021010b2004450d0220012d0000210102400240200341244b0d00200041096a21080c010b200041106a28020021032000410c6a28020021080b4100210620030d004100410041cca4cc001036000b200820066a20014104743a00000b200241106a24000f0b4100410041bca4cc001036000b8a0202017f037e230041106b220524002001200210dd0742ffffffff0f832003200410dd0742ffffffff0f8310dc0721062001200210dd074220882003200410dd0742ffffffff0f8310dc0720064220887c220742208810d807210820052003200410dd074220882001200210dd0742ffffffff0f8310dc07200742ffffffff0f837c2207422086200642ffffffff0f83842008200742208810d8077c2001200210dd074220882003200410dd0742208810dc0710d8077c2001200210de072003200410dd0710d80710dc0710db072001200210dd0710d8072003200410de0710dc0710db0710df07200529030021032000200541086a29030037030820002003370300200541106a24000b3c01017f230041106b220524002005200120022003200410d407200529030021012000200541086a29030037030820002001370300200541106a24000b3c01017f230041106b220524002005200120022003200410e307200529030021012000200541086a29030037030820002001370300200541106a24000b040000000b040020000b1500024020014200520d0010d707000b20002001800b1500024020014200520d0010d707000b20002001820b0700200120007c0b0700200120007e0b040020000b040020010b100020002002370308200020013703000b3c01017f230041106b220524002005200120022003200410e107200529030021012000200541086a29030037030820002001370300200541106a24000b3e01017f230041106b2205240020052001200220032004410010e207200529030021012000200541086a29030037030820002001370300200541106a24000bc00704017f027e027f047e230041d0006b2206240002400240024002400240024002400240024002402001200210de07500d002003200410dd0721072003200410de0721082007500d012008500d022003200410de0779a72001200210de0779a76b2209413f4b0d0341ff0020096b210a200941016a21090c080b02402003200410de07500d0020050d040c060b02402005450d002001200210dd072003200410dd0710da07210720054200370308200520073703000b2001200210dd072003200410dd0710d90721010c060b2008500d030240024002402001200210dd07500d002003200410de077b4201510d012003200410de0779a72001200210de0779a76b2209413e4b0d0241ff0020096b210a200941016a21090c090b02402005450d00200642002001200210de072003200410de0710da0710df07200629030021072005200641086a290300370308200520073703000b2001200210de072003200410de0710d90721010c070b02402005450d00200641106a2001200210dd072001200210de072003200410de07427f7c8310df07200629031021072005200641186a290300370308200520073703000b2001200210de072003200410de077a423f838821010c060b2005450d040c020b02402003200410dd077b4201510d0041bf7f2003200410dd0779a72001200210de0779a76b22096b210a200941c1006a21090c060b02402005450d002001200210dd0721072003200410dd07210820054200370308200520072008427f7c833703000b2003200410dd074201510d06200641c0006a200120022003200410dd077aa710eb07200641c8006a2903002102200629034021010c060b2005450d020b2005200137030020052002370308420021010c020b10d707000b420021010b420021020c010b200641206a20012002200a41ff007110ea07200641306a20012002200941ff007110eb07200641206a41086a2903002102200641306a41086a290300210b20062903202101200629033021070240024020090d00420021084200210c0c010b4200210c4200210d0340200b4201862007423f888422082008427f8520047c20074201862002423f88842207427f85220820037c200854ad7c423f8722082004837d20072008200383220e54ad7d210b2007200e7d2107420020024201862001423f8884842102200d200142018684210120084201832208210d2009417f6a22090d000b0b02402005450d00200520073703002005200b3703080b200c20024201862001423f8884842102200820014201868421010b2000200137030020002002370308200641d0006a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a10e207200529031021012000200529031837030820002001370300200541206a24000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f0240024020012000490d002002450d01200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000c020b0b2002450d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000b0b20000b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200041016a2100200141016a21012002417f6a2202450d020c000b0b200420056b21030b20030bac0102017f037e230041206b2204240002400240200341c000710d002003450d012001200210dd0721052001200210de072106200420052003413f71ad2207862001200210dd07410020036b413f71ad8820062007868410df07200441086a2903002102200429030021010c010b200441106a42002001200210dd072003413f71ad8610df07200441186a2903002102200429031021010b2000200137030020002002370308200441206a24000b9e0102017f027e230041106b22042400024002400240200341c000710d002003450d022001200210de0721052001200210dd072003413f71ad2206882005410020036b413f71ad868421052001200210de0720068821010c010b2001200210de072003413f71ad882105420021010b20042005200110df07200441086a2903002102200429030021010b2000200137030020002002370308200441106a24000b3a01017f230041106b22042400200420012002200310e807200429030021012000200441086a29030037030820002001370300200441106a24000b3a01017f230041106b22042400200420012002200310e907200429030021012000200441086a29030037030820002001370300200441106a24000b0bf5a70c0300418080c0000b0c802f88b9001210000012100000419080c0000bc6a70c20001000170000006e020000050000007372632f6c6962616c6c6f632f7261775f7665632e727300c70010004600000068010000130000001f00000004000000040000002000000021000000220000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f72001f000000000000000100000023000000b4001000130000004a020000050000007372632f6c6962616c6c6f632f666d742e72732f72757374632f323435346136386366626236336161376238653039666530353131346435663938623266393734302f7372632f6c6962636f72652f666d742f6d6f642e72730000004b0110001600000061011000160000008e321200010000003801100013000000ca0300000d0000007372632f6c6962616c6c6f632f7665632e7273737761705f72656d6f766520696e6465782028697320292073686f756c64206265203c206c656e202869732000a001100014000000b4011000170000008e321200010000003801100013000000f10300000d000000696e73657274696f6e20696e6465782028697320292073686f756c64206265203c3d206c656e202869732000f40110001200000061011000160000008e321200010000003801100013000000210400000d00000072656d6f76616c20696e64657820286973200000300210001600000046021000230000008e3212000100000038011000130000002d0500000d000000737461727420647261696e20696e6465782028697320292073686f756c64206265203c3d20656e6420647261696e20696e64657820286973200000009402100014000000b4011000170000008e321200010000003801100013000000330500000d000000656e6420647261696e20696e6465782028697320c802100020000000e8021000120000001f000000000000000100000024000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e6465782069732030303031303230333034303530363037303830393130313131323133313431353136313731383139323032313232323332343235323632373238323933303331333233333334333533363337333833393430343134323433343434353436343734383439353035313532353335343535353635373538353936303631363236333634363536363637363836393730373137323733373437353736373737383739383038313832383338343835383638373838383939303931393239333934393539363937393839390000d403100006000000da03100022000000696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e677468200c04100016000000220410000d000000736c69636520696e64657820737461727473206174202062757420656e64732061742000930e100016000000040800002f0000005b2e2e2e5d000000a80410000b0000007d0e100016000000e7041000010000005b0e10000e000000690e1000040000006d0e100010000000e704100001000000a80410000b000000b304100026000000d904100008000000e104100006000000e7041000010000006279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f6620606026051000020000001005100016000000560400002400000010051000160000004c040000110000007372632f6c6962636f72652f666d742f6d6f642e72732e2e3a05100016000000540000001400000030787372632f6c6962636f72652f666d742f6e756d2e727300010305050606030706080809110a1c0b190c140d100e0d0f0410031212130916011705180219031a071c021d011f1620032b032c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f00d11454964658084b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f7475962f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab35280b80e003190801042f043404070301070607110a500f1207550703041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a06213f4c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b32d740c80d61a0c0580ff0580df0cee0d03848d033709815c1480b80880cb2a38030a06380846080c06740b1e035a0459098083181c0a16094c04808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b020e041001110212051311140115021702190d1c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f802f902fa02fb010c273b3e4e4f8f9e9e9f060709363d3e56f3d0d1041418363756577faaaeafbd35e01287898e9e040d0e11122931343a4546494a4e4f64655cb6b71b1c07080a0b141736393aa8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d0aeaf79cc6e6f935e227b0503042d036603012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a8126524e28082a561c1417094e041e0f430e19070a0648082709750b3f412a063b050a0651060105100305808b621e48080a80a65e22450b0a060d1339070a362c041080c03c64530c48090a46451b4808531d398107460a1d03474937030e080a0639070a81361980b7010f320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140050b020e97f80884d62a09a2f7811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a80ae381d0d2c040907020e06809a83d8080d030d03740c59070c140c0438080a062808224e81540c15030305070919070709030d072980cb250a840600b80a1000200000000a0000001c000000b80a1000200000001a000000280000007372632f6c6962636f72652f756e69636f64652f7072696e7461626c652e72730003000083042000910560005d13a0001217a01e0c20e01eef2c202b2a30a02b6fa6602c02a8e02c1efbe02d00fea0359effe035fd016136010aa136240d6137ab0ee1382f182139301c6146f31ea14af06a614e4f6fa14e9dbc214f65d1e14f00da215000e0e15130e16153ece2a154d0e8e15420002e55f001bf55380e100023000000520000003e00000000700007002d0101010201020101480b30151001650702060202010423011e1b5b0b3a09090118040109010301052b03770f0120370101010408040103070a021d013a0101010204080109010a021a010202390104020402020303011e0203010b0239010405010204011402160601013a0101020104080107030a021e013b0101010c0109012801030139030503010407020b021d013a01020102010301050207020b021c02390201010204080109010a021d0148010401020301010801510102070c08620102090b064a021b0101010101370e01050102050b0124090166040106010202021902040310040d01020206010f01000300031d031d021e02400201070801020b09012d03770222017603040209010603db0202013a010107010101010208060a020130113f0430070101050128090c0220040202010338010102030101033a0802029803010d0107040106010302c63a01050001c32100038d016020000669020004010a200250020001030104011902050197021a120d012608190b2e0330010204020227014306020202020c0108012f01330101030202050201012a020801ee010201040100010010101000020001e201950500030102050428030401a50200040002990bb001360f3803310402024503240501083e010c0234090a0402015f03020101020601a0010308150239020101010116010e070305c308020301011701510102060101020101020102eb010204060201021b025508020101026a0101010206010165030204010500090102f5010a0201010401900402020401200a280602040801090602032e0d010200070106010152160207010201027a060301010201070101480203010101000200053b0700013f0451010002000101030405080802071e0494030037043208010e011605010f000701110207010201050007000400076d07006080f000000000380e1000230000004b00000028000000380e10002300000057000000160000007372632f6c6962636f72652f756e69636f64652f756e69636f64655f646174612e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f6620607372632f6c6962636f72652f7374722f6d6f642e7273426f72726f774572726f72426f72726f774d75744572726f7270616e69636b6564206174200000f90e100001000000fa0e1000030000000013130000000000f80e100001000000f80e1000010000003a27272c2020202020000000240f10001a0000008b01000026000000930e100016000000c30700002f0000007372632f6c6962636f72652f7374722f7061747465726e2e72730000500f10001b00000052000000050000007372632f6c6962636f72652f736c6963652f6d656d6368722e72732c200000001f0000000c000000040000002500000026000000270000002c0a00001f000000040000000400000028000000290000002a00000028280a2c0a000000930e100016000000800700002f0000003062000037101000260000006672616d655f737570706f72743a3a686173682f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f737570706f72742f7372632f686173682e7273496e76616c696420726576657273653a2068617368206c656e67746820746f6f2073686f72740000001f00000004000000040000002b0000002c0000002d0000001f00000000000000010000002e0000002f000000300000006d61782d77656967687461637475616c5f7765696768743d00131300000000000000000048617368207461626c65206361706163697479206f766572666c6f77e010100059000000500000001b0000002f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6861736862726f776e2d302e362e332f7372632f7261772f6d6f642e727300000000000000010000000000000082800000000000008a8000000000008000800080000000808b800000000000000100008000000000818000800000008009800000000000808a00000000000000880000000000000009800080000000000a000080000000008b800080000000008b0000000000008089800000000000800380000000000080028000000000008080000000000000800a800000000000000a0000800000008081800080000000808080000000000080010000800000000008800080000000801f00000000000000010000003100000032000000300000001f000000000000000100000031000000320000003000000001a8010001605354524f424576312e302e3200005412100055000000680000000d0000002f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6d65726c696e2d322e302e302f7372632f7374726f62652e727300000054121000550000007c0000001500000054121000550000007d0000000d000000a213100019000000bb13100016000000000000002000000004000000020000000000000002000000000000000300000001000000200000000400000002000000000000000200000000000000030000005412100055000000880000000d000000641310003e0000005412100055000000910000000900000054121000550000005e0000000900000054121000550000005f00000009000000596f75207573656420746865205420666c61672c207768696368207468697320696d706c656d656e746174696f6e20646f65736e277420737570706f7274596f7520747269656420746f20636f6e74696e7565206f702020627574206368616e67656420666c61677320746f20000000000000000100000002000000040000000800000010000000200000004661696c656420746f206465636f646520636f6d70616374207533322061743a00000000941410000e00000000000000a4141000010000000000000000000000ac141000010000000000000000000000b4141000060000000000000000131300000000000000000000000000bc141000010000000000000000000000c4141000070000000000000000131300000000000000000000000000cc14100001000000000000004e6577417574686f7269746965730000471510000d00000023151000240000005061757365640000fc14100027000000526573756d656400d4141000280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e417574686f726974794c6973740000000080151000070000000000000088151000030000000000000000000000a015100003000000000000004f6666656e6365000ea410000400000012a410000e0000000fb9120004000000b8151000550000000d16100053000000601610004700000020546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e6420286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e206c61737420656c656d656e7420696e64696361746573206f6620746865206f6666656e636520776173206170706c69656420287472756529206f7220717565756564202866616c7365292e53746f72656452616e6765000000000000e01610000a00000000000000781e1000010000000000000000000000ec16100002000000000000004e657753657373696f6e0000fc161000550000005117100022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e74696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672edc1710006000000088000000120000002f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e332e302f7372632f636f6465632e72734572726f72496e636f7272656374536c617368696e675370616e73496e636f7272656374486973746f7279446570746843616c6c4e6f74416c6c6f77656450687261676d656e426f677573456c656374696f6e53697a6550687261676d656e426f67757353636f726550687261676d656e426f6775734564676550687261676d656e426f67757353656c66566f746550687261676d656e536c61736865644e6f6d696e6174696f6e50687261676d656e426f6775734e6f6d696e6174696f6e50687261676d656e426f6775734e6f6d696e61746f7250687261676d656e426f677573436f6d7061637450687261676d656e426f67757357696e6e657250687261676d656e426f67757357696e6e6572436f756e74536e617073686f74556e617661696c61626c6550687261676d656e5765616b5375626d697373696f6e50687261676d656e4561726c795375626d697373696f6e416c7265616479436c61696d65644e6f74536f72746564416e64556e69717565496e76616c69644e756d6265724f664e6f6d696e6174696f6e73496e76616c6964457261546f52657761726446756e6465645461726765744e6f556e6c6f636b4368756e6b4e6f4d6f72654368756e6b73496e73756666696369656e7456616c7565496e76616c6964536c617368496e6465784475706c6963617465496e646578456d70747954617267657473416c7265616479506169726564416c7265616479426f6e6465644e6f7453746173684e6f74436f6e74726f6c6c65725761726e696e673a20412073657373696f6e206170706561727320746f2068617665206265656e20736b69707065642e626f6e64626f6e645f6578747261756e626f6e6477697468647261775f756e626f6e64656476616c69646174656e6f6d696e6174656368696c6c7365745f70617965657365745f636f6e74726f6c6c65727365745f76616c696461746f725f636f756e74666f7263655f6e6f5f65726173666f7263655f6e65775f6572617365745f696e76756c6e657261626c6573666f7263655f756e7374616b65666f7263655f6e65775f6572615f616c7761797363616e63656c5f64656665727265645f736c6173687061796f75745f6e6f6d696e61746f727061796f75745f76616c696461746f727061796f75745f7374616b6572737265626f6e647365745f686973746f72795f6465707468726561705f73746173687375626d69745f656c656374696f6e5f736f6c7574696f6e7375626d69745f656c656374696f6e5f736f6c7574696f6e5f756e7369676e6564426f6e6465644c65646765724e6f6d696e61746f7273457261735374616b65727356616c696461746f72536c617368496e4572614e6f6d696e61746f72536c617368496e457261536c617368696e675370616e735370616e536c617368536e617073686f7456616c696461746f7273536e617073686f744e6f6d696e61746f7273457261456c656374696f6e5374617475730000000000081e10000900000000000000141e10000300000000000000000000002c1e10000200000000000000000000003c1e1000060000000000000050da1100020000000000000000000000441e10000100000000000000000000004c1e1000050000000000000050da1100020000000000000000000000541e10000100000000000000000000005c1e10001a00000000000000781e1000010000000000000000000000801e1000020000000000000000000000901e10000f00000000000000a01e1000010000000000000000000000a81e1000010000000000000000000000b01e10000e00000000000000a01e1000010000000000000000000000c01e1000010000000000000000000000e91b1000060000000000000050da1100020000000000000000000000c81e1000040000000000000000000000e81e1000080000000000000050da1100020000000000000000000000f01e1000010000000000000000000000f81e1000090000000000000050da1100020000000000000000000000041f100002000000000000004572615061796f75740000006f221000080000006b721200070000006b72120007000000e8211000560000003e221000310000005265776172640000992110004f000000536c61736800000050211000490000004f6c64536c617368696e675265706f72744469736361726465640000148312000c000000f7201000470000003e211000120000005374616b696e67456c656374696f6e00e82010000f000000a420100044000000536f6c7574696f6e53746f72656400006a2010003a000000aa1f1000230000000013130000000000cd1f1000540000002120100049000000556e626f6e646564851f10002500000057697468647261776e000000141f1000570000006b1f10001a00000020416e206163636f756e74206861732063616c6c6564206077697468647261775f756e626f6e6465646020616e642072656d6f76656420756e626f6e64696e67206368756e6b7320776f727468206042616c616e6365602066726f6d2074686520756e6c6f636b696e672071756575652e20416e206163636f756e742068617320756e626f6e646564207468697320616d6f756e742e20416e206163636f756e742068617320626f6e646564207468697320616d6f756e742e204e4f54453a2054686973206576656e74206973206f6e6c7920656d6974746564207768656e2066756e64732061726520626f6e64656420766961206120646973706174636861626c652e204e6f7461626c792c2069742077696c6c206e6f7420626520656d697474656420666f72207374616b696e672072657761726473207768656e20746865792061726520616464656420746f207374616b652e2041206e657720736f6c7574696f6e20666f7220746865207570636f6d696e6720656c656374696f6e20686173206265656e2073746f7265642e2041206e657720736574206f66207374616b6572732077617320656c656374656420776974682074686520676976656e20636f6d7075746174696f6e206d6574686f642e456c656374696f6e436f6d7075746520416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64206e6f742062652070726f6365737365642e204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e20546865207374616b657220686173206265656e207265776172646564206279207468697320616d6f756e742e20604163636f756e7449646020697320746865207374617368206163636f756e742e2054686520657261207061796f757420686173206265656e207365743b207468652066697273742062616c616e6365206973207468652076616c696461746f722d7061796f75743b20746865207365636f6e64206973207468652072656d61696e6465722066726f6d20746865206d6178696d756d20616d6f756e74206f66207265776172642e457261496e64657845726173526577617264506f696e747300ffff0000ffffffffc72310001c000000e323100004000000e723100002000000e323100004000000e923100002000000972310001d000000b42310001300000074231000220000009623100001000000492310002b00000070616c6c65745f7374616b696e672f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f7374616b696e672f7372632f6c69622e7273f09f92b820457374696d6174696e67206e6578742073657373696f6e206368616e6765206661696c65642ef09f92b8204661696c656420746f2063726561746520736e617073686f74206174202ef09f92b820456c656374696f6e2077696e646f77206973204f70656e28292e20536e617073686f742063726561746564f09f92b820536e617073686f742073697a6520746f6f20626967205b203c3e205d5b5d2e0063241000390000009c241000010000003b241000280000000c2410002f0000004578656375746564206f6666636861696e20776f726b65722074687265616420776974686f7574206572726f72732ef09f92b8204572726f7220696e2070687261676d656e206f6666636861696e20776f726b65723a20736b697070696e67206f6666636861696e20776f726b657220696e206f70656e20656c656374696f6e2077696e646f772064756520746f205b5d000000000000009c1a10000400000000000000c028100003000000000000000000000008291000160000000000000000000000a01a10000a00000000000000b8291000010000000000000000000000d0291000160000000000000000000000aa1a10000600000000000000802a1000010000000000000000000000982a1000200000000000000000000000b01a10001100000000000000982b1000010000000000000000000000b02b10001e0000000000000000000000c11a10000800000000000000a02c1000010000000000000000000000b82c1000110000000000000000000000c91a10000800000000000000402d1000010000000000000000000000582d1000130000000000000000000000d11a1000050000000000000000131300000000000000000000000000f02d1000110000000000000000000000d61a10000900000000000000782e1000010000000000000000000000902e1000100000000000000000000000df1a10000e00000000000000102f1000010000000000000000000000282f1000100000000000000000000000ed1a10001300000000000000a82f1000010000000000000000000000c02f1000080000000000000000000000001b10000d0000000000000000131300000000000000000000000000003010000900000000000000000000000d1b10000d0000000000000000131300000000000000000000000000483010000a00000000000000000000001a1b1000110000000000000098301000010000000000000000000000b03010000900000000000000000000002b1b10000d00000000000000f8301000020000000000000000000000283110000b0000000000000000000000381b1000140000000000000000131300000000000000000000000000803110000800000000000000000000004c1b10001500000000000000c0311000020000000000000000000000f03110000e0000000000000000000000611b1000100000000000000060321000020000000000000000000000903210001e0000000000000000000000711b100010000000000000008033100001000000000000000000000098331000130000000000000000000000811b10000e0000000000000030341000020000000000000000000000603410001700000000000000000000008f1b10000600000000000000802a1000010000000000000000000000183510000f0000000000000000000000951b1000110000000000000090351000020000000000000000000000c0351000150000000000000000000000a61b10000a00000000000000f830100002000000000000000000000068361000100000000000000000000000b01b10001800000000000000e8361000050000000000000000000000603710002f0000000000000000000000c81b10002100000000000000e8361000050000000000000000000000d8381000090000000000000000000000c85a10000a0000000000000087e412002300000000000000bef212000500000000000000c3f212001500000000000000945b10000500000000000000995b100011000000366a1000590000008f6a1000210000000013130000000000b06a10004c0000000013130000000000fc6a1000490000000013130000000000bc69100010000000001313000000000091c212000b000000456b1000350000002deb1100080000007a6b10001a0000000013130000000000946b100054000000e86b100050000000386c1000130000004b6c100017000000deff10000b000000626c10004c000000ae6c10003800000034c312000c00000000000000286a10000e00000000000000c3f21200150000000068100059000000596810000d00000000131300000000006668100054000000ba681000590000001369100013000000001313000000000026691000580000007e6910003e0000000013130000000000bc69100010000000001313000000000091c212000b000000995910003a0000002deb110008000000666710001000000015bb11000d000000cc69100017000000deff10000b000000e369100045000000d76710002900000034c312000c00000000000000bef212000500000000000000c3f21200150000008163100055000000d663100040000000166410004900000000131300000000005f64100052000000b1641000300000000013130000000000e16410004f000000306510004f0000007f6510003f0000000013130000000000005b100055000000dc5b1000430000000013130000000000be651000120000000013130000000000d065100026000000001313000000000091c212000b000000f665100050000000d35910002600000046661000590000009f6610005c000000fb661000540000004f6710001700000066671000100000002b5a10000b0000007667100017000000deff10000b0000008d6710004a000000d767100029000000f0e812000a00000000000000155710001200000000000000c2c41200030000005c5f10004b0000000013130000000000a75f10004d000000f45f1000130000000013130000000000005b100055000000dc5b1000430000000013130000000000076010001300000000131300000000001a6010001b000000001313000000000091c212000b00000035601000550000008a60100051000000db6010003d000000186110005e000000f9591000320000008e481000100000007661100042000000b86110000d000000c56110001d000000e2611000490000002b6210002a000000556210001c0000007162100061000000d26210006c000000d04310001d0000003e6310004300000034c312000c00000000000000495f100005000000000000004e5f10000e000000b45e10003a00000000131300000000000d591000370000000013130000000000005b100055000000dc5b100043000000001313000000000091c212000b000000995910003a000000d359100026000000f959100032000000544b10000c000000ee5e100017000000deff10000b000000055f100024000000295f10002000000034c312000c00000000000000855e100007000000000000008c5e100028000000965c1000440000000013130000000000da5c100054000000d4471000230000000013130000000000005b100055000000dc5b100043000000001313000000000091c212000b0000002e5d10004c0000007a5d100040000000ba5d10003600000028bf11000a000000f05d100021000000115e100021000000deff10000b000000325e100032000000645e10002100000034c312000c000000aa5b10003200000000131300000000000d591000370000000013130000000000005b100055000000dc5b100043000000001313000000000091c212000b000000995910003a0000001f5c100015000000f959100032000000345c1000090000003d5c100017000000deff10000b000000545c100022000000765c10002000000034c312000c00000000000000945b10000500000000000000995b100011000000d25a10002e00000000131300000000000d591000370000000013130000000000005b100055000000001313000000000091c212000b000000995910003a000000d359100026000000f95910003200000028bf11000a000000555b100019000000aec612000d0000006e5b100013000000815b10001300000034c312000c00000000000000c85a10000a0000000000000087e4120023000000e95810002400000000131300000000000d5910003700000000131300000000004459100055000000001313000000000091c212000b000000995910003a000000d359100026000000f9591000320000002b5a10000b000000365a100017000000deff10000b0000004d5a10003d0000008a5a10003e00000034c312000c0000000000000025a912000300000000000000ebea12000c000000965810002500000000131300000000007955100022000000001313000000000091c212000b000000bb58100017000000d25810001700000034c312000c000000515810002c00000000131300000000007955100022000000001313000000000091c212000b00000017581000100000007d58100019000000b35510001200000034c312000c0000009c57100053000000ef5710002800000000131300000000007955100022000000001313000000000091c212000b00000017581000100000002758100019000000405810001100000034c312000c00000000000000915310000a00000000000000adf2120011000000275710003300000000131300000000007955100022000000001313000000000091c212000b0000005a571000070000006157100024000000855710001700000034c312000c00000000000000105710000500000000000000d0cf12000c00000000000000155710001200000000000000c2c4120003000000c55510004300000000131300000000007955100022000000001313000000000091c212000b000000085610003b0000004356100023000000665610002e0000009456100061000000f55610001b00000034c312000c000000385510004100000000131300000000007955100022000000001313000000000091c212000b0000009b55100018000000b35510001200000034c312000c000000000000007841100003000000000000006f22100008000000000000002b5510000d00000000000000aa83120008000000b3531000260000000013130000000000d95310004700000000131300000000002054100041000000001313000000000091c212000b0000006154100015000000765410002e000000a454100035000000d95410001d000000f65410001a000000105510001b00000034c312000c000000000000007841100003000000000000006f2210000800000000000000915310000a000000000000009b53100018000000014d100058000000594d100057000000b04d1000310000000013130000000000bd4f1000290000000013130000000000e64f10003f000000494e100059000000a24e10004c00000025501000560000007b50100049000000c450100022000000e650100042000000285110004800000070511000280000000013130000000000ee4e100057000000454f10000e0000000013130000000000534f100051000000001313000000000091c212000b0000009851100057000000ef51100027000000165210004e00000064521000370000009b52100050000000eb521000520000003d5310005400000034c312000c000000000000007841100003000000000000006f22100008000000014d100058000000594d100057000000b04d1000310000000013130000000000e14d10002900000000131300000000000a4e10003f000000494e100059000000a24e10004c0000000013130000000000ee4e100057000000454f10000e0000000013130000000000534f100051000000001313000000000091c212000b000000a44f100019000000c2e310003100000034c312000c00000000000000f24c10000f00000000000000d0cf12000c000000000000007841100003000000000000006f22100008000000324910004400000000131300000000007649100053000000c94910004a000000134a10004d0000000013130000000000604a100056000000b64a10001e0000000013130000000000d44a100040000000001313000000000091c212000b000000144b100040000000c2e3100031000000544b10000c000000604b100047000000a74b100030000000deff10000b000000d74b1000560000002d4c10004b000000784c100044000000bc4c10003600000034c312000c000000474710003800000000131300000000007f47100055000000d447100023000000001313000000000091c212000b000000f7471000350000002c48100025000000514810003d0000008e481000100000009e48100026000000aec612000d000000c448100040000000044910002e00000034c312000c00000000000000134710001100000000000000244710001100000000000000354710001200000000000000ebea12000c000000ed4310004c000000394410002000000000131300000000002eff10000c00000059441000440000009d44100052000000ef44100051000000404510005100000091451000280000000013130000000000b945100015000000001313000000000091c212000b000000ce45100038000000064610001d000000aec612000d00000023461000280000004b4610001c000000674610004c000000b34610006000000034c312000c0000008b4110004e000000d94110005800000031421000300000000013130000000000614210002400000000131300000000008542100040000000001313000000000091c212000b000000c5421000490000000e43100023000000deff10000b00000031431000360000006743100069000000d04310001d00000034c312000c000000000000003341100007000000000000003a41100013000000000000004d41100007000000000000005441100012000000000000006641100005000000000000006b4110000d000000000000007841100003000000000000006f22100008000000000000007b41100004000000000000007f4110000c000000353a10003800000000131300000000006d3a10000d0000007a3a1000450000000013130000000000bf3a1000210000000013130000000000e03a10002b00000000131300000000000b3b10003d000000483b1000540000009c3b10000c0000000013130000000000a83b10004a0000000013130000000000f23b10002a00000000131300000000001c3c10003200000000131300000000004e3c100053000000a13c100047000000e83c10004c000000343d100054000000883d100058000000e03d1000260000000013130000000000063e10001800000000131300000000001e3e100039000000573e10003e000000953e10002b000000c03e100055000000153f1000570000006c3f1000100000007c3f100043000000bf3f10001b0000000013130000000000da3f10003000000000131300000000000a401000590000006340100059000000bc401000500000000c41100027000000001313000000000091c212000b000000193a10001c00000034c312000c000000203910003000000000131300000000005039100057000000a739100058000000ff3910001a000000001313000000000091c212000b000000193a10001c00000034c312000c00000020556e7369676e65642076657273696f6e206f6620607375626d69745f656c656374696f6e5f736f6c7574696f6e602e204e6f746520746861742074686973206d757374207061737320746865205b6056616c6964617465556e7369676e6564605d20636865636b207768696368206f6e6c7920616c6c6f7773207472616e73616374696f6e732066726f6d20746865206c6f63616c206e6f646520746f20626520696e636c756465642e20496e206f7468657220776f7264732c206f6e6c792074686520626c6f636b20617574686f722063616e20696e636c7564652061207472616e73616374696f6e20696e2074686520626c6f636b2e20536565206063726174653a3a77656967687460206d6f64756c652e205375626d697420612070687261676d656e20726573756c7420746f2074686520636861696e2e2049662074686520736f6c7574696f6e3a20312e2069732076616c69642e20322e206861732061206265747465722073636f7265207468616e206120706f74656e7469616c6c79206578697374696e6720736f6c7574696f6e206f6e20636861696e2e207468656e2c2069742077696c6c206265205f7075745f206f6e20636861696e2e204120736f6c7574696f6e20636f6e7369737473206f662074776f20706965636573206f6620646174613a20312e206077696e6e657273603a206120666c617420766563746f72206f6620616c6c207468652077696e6e657273206f662074686520726f756e642e20322e206061737369676e6d656e7473603a2074686520636f6d706163742076657273696f6e206f6620616e2061737369676e6d656e7420766563746f72207468617420656e636f64657320746865206564676520202020776569676874732e20426f7468206f66207768696368206d617920626520636f6d7075746564207573696e67205b6070687261676d656e605d2c206f7220616e79206f7468657220616c676f726974686d2e204164646974696f6e616c6c792c20746865207375626d6974746572206d7573742070726f766964653a202d20546865206073636f7265602074686174207468657920636c61696d20746865697220736f6c7574696f6e206861732e20426f74682076616c696461746f727320616e64206e6f6d696e61746f72732077696c6c20626520726570726573656e74656420627920696e646963657320696e2074686520736f6c7574696f6e2e2054686520696e64696365732073686f756c6420726573706563742074686520636f72726573706f6e64696e6720747970657320285b6056616c696461746f72496e646578605d20616e64205b604e6f6d696e61746f72496e646578605d292e204d6f72656f7665722c20746865792073686f756c642062652076616c6964207768656e207573656420746f20696e64657820696e746f205b60536e617073686f7456616c696461746f7273605d20616e64205b60536e617073686f744e6f6d696e61746f7273605d2e20416e7920696e76616c696420696e6465782077696c6c2063617573652074686520736f6c7574696f6e20746f2062652072656a65637465642e2054686573652074776f2073746f72616765206974656d73206172652073657420647572696e672074686520656c656374696f6e2077696e646f7720616e64206d6179206265207573656420746f2064657465726d696e652074686520696e64696365732e204120736f6c7574696f6e2069732076616c69642069663a20302e204974206973207375626d6974746564207768656e205b60457261456c656374696f6e537461747573605d20697320604f70656e602e20312e2049747320636c61696d65642073636f726520697320657175616c20746f207468652073636f726520636f6d7075746564206f6e2d636861696e2e20322e2050726573656e74732074686520636f7272656374206e756d626572206f662077696e6e6572732e20332e20416c6c20696e6465786573206d7573742062652076616c7565206163636f7264696e6720746f2074686520736e617073686f7420766563746f72732e20416c6c20656467652076616c756573206d75737420202020616c736f20626520636f727265637420616e642073686f756c64206e6f74206f766572666c6f7720746865206772616e756c6172697479206f662074686520726174696f20747970652028692e652e20323536202020206f722062696c6c696f6e292e20342e20466f72206561636820656467652c20616c6c2074617267657473206172652061637475616c6c79206e6f6d696e617465642062792074686520766f7465722e20352e2048617320636f72726563742073656c662d766f7465732e204120736f6c7574696f6e732073636f726520697320636f6e736973746564206f66203320706172616d65746572733a20312e20606d696e207b20737570706f72742e746f74616c207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265206d6178696d697a65642e20322e206073756d207b20737570706f72742e746f74616c207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265206d696e696d697a65642e20332e206073756d207b20737570706f72742e746f74616c5e32207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265202020206d696e696d697a65642028746f20656e73757265206c6573732076617269616e63652977696e6e6572735665633c56616c696461746f72496e6465783e636f6d70616374436f6d7061637441737369676e6d656e747373636f726550687261676d656e53636f726565726173697a65456c656374696f6e53697a652052656d6f766520616c6c20646174612073747275637475726520636f6e6365726e696e672061207374616b65722f7374617368206f6e6365206974732062616c616e6365206973207a65726f2e205468697320697320657373656e7469616c6c79206571756976616c656e7420746f206077697468647261775f756e626f6e64656460206578636570742069742063616e2062652063616c6c656420627920616e796f6e6520616e6420746865207461726765742060737461736860206d7573742068617665206e6f2066756e6473206c6566742e20546869732063616e2062652063616c6c65642066726f6d20616e79206f726967696e2e202d20607374617368603a20546865207374617368206163636f756e7420746f20726561702e204974732062616c616e6365206d757374206265207a65726f2e20436f6d706c65786974793a204f285329207768657265205320697320746865206e756d626572206f6620736c617368696e67207370616e73206f6e20746865206163636f756e742e2042617365205765696768743a2037352e3934202b20322e333936202a205320c2b573202d2052656164733a205374617368204163636f756e742c20426f6e6465642c20536c617368696e67205370616e732c204c6f636b73202d205772697465733a20426f6e6465642c20536c617368696e67205370616e73202869662053203e2030292c204c65646765722c2050617965652c2056616c696461746f72732c204e6f6d696e61746f72732c205374617368204163636f756e742c204c6f636b73202d2057726974657320456163683a205370616e536c617368202a2053205365742060486973746f72794465707468602076616c75652e20546869732066756e6374696f6e2077696c6c2064656c65746520616e7920686973746f727920696e666f726d6174696f6e207768656e2060486973746f727944657074686020697320726564756365642e202d20606e65775f686973746f72795f6465707468603a20546865206e657720686973746f727920646570746820796f7520776f756c64206c696b6520746f207365742e202d20606572615f6974656d735f64656c65746564603a20546865206e756d626572206f66206974656d7320746861742077696c6c2062652064656c6574656420627920746869732064697370617463682e20202020546869732073686f756c64207265706f727420616c6c207468652073746f72616765206974656d7320746861742077696c6c2062652064656c6574656420627920636c656172696e67206f6c642020202065726120686973746f72792e204e656564656420746f207265706f727420616e2061636375726174652077656967687420666f72207468652064697370617463682e20547275737465642062792020202060526f6f746020746f207265706f727420616e206163637572617465206e756d6265722e204f726967696e206d75737420626520726f6f742e202d20453a204e756d626572206f6620686973746f7279206465707468732072656d6f7665642c20692e652e203130202d3e2037203d2033202d2042617365205765696768743a2032392e3133202a204520c2b57320202020202d2052656164733a2043757272656e74204572612c20486973746f727920446570746820202020202d205772697465733a20486973746f727920446570746820202020202d20436c6561722050726566697820456163683a20457261205374616b6572732c204572615374616b657273436c69707065642c204572617356616c696461746f72507265667320202020202d2057726974657320456163683a204572617356616c696461746f725265776172642c2045726173526577617264506f696e74732c2045726173546f74616c5374616b652c2045726173537461727453657373696f6e496e6465786e65775f686973746f72795f6465707468436f6d706163743c457261496e6465783e5f6572615f6974656d735f64656c65746564205265626f6e64206120706f7274696f6e206f6620746865207374617368207363686564756c656420746f20626520756e6c6f636b65642e20546865206469737061746368206f726967696e206d757374206265207369676e65642062792074686520636f6e74726f6c6c65722c20616e642069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d2054696d6520636f6d706c65786974793a204f284c292c207768657265204c20697320756e6c6f636b696e67206368756e6b73202d20426f756e64656420627920604d41585f554e4c4f434b494e475f4348554e4b53602e202d2053746f72616765206368616e6765733a2043616e277420696e6372656173652073746f726167652c206f6e6c792064656372656173652069742e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a2033342e353120c2b573202a202e303438204c20c2b57320202020202d2052656164733a20457261456c656374696f6e5374617475732c204c65646765722c204c6f636b732c205b4f726967696e204163636f756e745d20202020202d205772697465733a205b4f726967696e204163636f756e745d2c204c6f636b732c204c656467657220506179206f757420616c6c20746865207374616b65727320626568696e6420612073696e676c652076616c696461746f7220666f7220612073696e676c65206572612e202d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e205468656972206e6f6d696e61746f72732c20757020746f20202060543a3a4d61784e6f6d696e61746f72526577617264656450657256616c696461746f72602c2077696c6c20616c736f207265636569766520746865697220726577617264732e202d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e20546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966206974206973206e6f74206f6e65206f6620746865207374616b6572732e20546869732063616e206f6e6c792062652063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d2054696d6520636f6d706c65786974793a206174206d6f7374204f284d61784e6f6d696e61746f72526577617264656450657256616c696461746f72292e202d2d2d2d2d2d2d2d2d2d2d204e20697320746865204e756d626572206f66207061796f75747320666f72207468652076616c696461746f722028696e636c7564696e67207468652076616c696461746f72292042617365205765696768743a20313130202b2035342e32202a204e20c2b57320284d656469616e20536c6f70657329202d20526561643a20457261456c656374696f6e5374617475732c2043757272656e744572612c20486973746f727944657074682c204d6967726174654572612c204572617356616c696461746f725265776172642c202020202020202020457261735374616b657273436c69707065642c2045726173526577617264506f696e74732c204572617356616c696461746f725072656673202838206974656d7329202d205265616420456163683a20426f6e6465642c204c65646765722c2050617965652c204c6f636b732c2053797374656d204163636f756e74202835206974656d7329202d20577269746520456163683a2053797374656d204163636f756e742c204c6f636b732c204c6564676572202833206974656d732976616c696461746f725f7374617368202a2a546869732065787472696e7369632077696c6c2062652072656d6f76656420616674657220604d6967726174696f6e457261202b20486973746f727944657074686020686173207061737365642c20676976696e67206f70706f7274756e69747920666f7220757365727320746f20636c61696d20616c6c2072657761726473206265666f7265206d6f76696e6720746f2053696d706c65205061796f7574732e20416674657220746869732074696d652c20796f752073686f756c642075736520607061796f75745f7374616b6572736020696e73746561642e2a2a204d616b65206f6e652076616c696461746f722773207061796f757420666f72206f6e65206572612e202d206077686f602069732074686520636f6e74726f6c6c6572206163636f756e74206f66207468652076616c696461746f7220746f20706179206f75742e202d206065726160206d6179206e6f74206265206c6f776572207468616e206f6e6520666f6c6c6f77696e6720746865206d6f737420726563656e746c792070616964206572612e204966206974206973206869676865722c2020207468656e20697420696e6469636174657320616e20696e737472756374696f6e20746f20736b697020746865207061796f7574206f6620616c6c2070726576696f757320657261732e205741524e494e473a206f6e636520616e2065726120697320706179656420666f7220612076616c696461746f7220737563682076616c696461746f722063616e277420636c61696d20746865207061796f7574206f662070726576696f7573206572612e205741524e494e473a20496e636f727265637420617267756d656e747320686572652063616e20726573756c7420696e206c6f7373206f66207061796f75742e2042652076657279206361726566756c2e202d2054696d6520636f6d706c65786974793a204f2831292e204d616b65206f6e65206e6f6d696e61746f722773207061796f757420666f72206f6e65206572612e202d206077686f602069732074686520636f6e74726f6c6c6572206163636f756e74206f6620746865206e6f6d696e61746f7220746f20706179206f75742e202d206076616c696461746f72736020697320746865206c697374206f6620616c6c2076616c696461746f72732074686174206077686f6020686164206578706f7375726520746f20647572696e672060657261602c202020616c6f6e67736964652074686520696e646578206f66206077686f6020696e2074686520636c6970706564206578706f73757265206f66207468652076616c696461746f722e202020492e652e206561636820656c656d656e742069732061207475706c65206f66202020602876616c696461746f722c20696e646578206f66206077686f6020696e20636c6970706564206578706f73757265206f662076616c696461746f7229602e202020496620697420697320696e636f6d706c6574652c207468656e206c657373207468616e207468652066756c6c207265776172642077696c6c2062652070616964206f75742e2020204974206d757374206e6f742065786365656420604d41585f4e4f4d494e4154494f4e53602e202d204e756d626572206f662073746f726167652072656164206f6620604f2876616c696461746f727329603b206076616c696461746f7273602069732074686520617267756d656e74206f66207468652063616c6c2c202020616e6420697320626f756e64656420627920604d41585f4e4f4d494e4154494f4e53602e202d20456163682073746f72616765207265616420697320604f284e29602073697a6520616e64206465636f646520636f6d706c65786974793b20604e602069732074686520206d6178696d756d2020206e6f6d696e6174696f6e7320746861742063616e20626520676976656e20746f20612073696e676c652076616c696461746f722e202d20436f6d7075746174696f6e20636f6d706c65786974793a20604f284d41585f4e4f4d494e4154494f4e53202a206c6f674e29603b20604d41585f4e4f4d494e4154494f4e5360206973207468652020206d6178696d756d206e756d626572206f662076616c696461746f72732074686174206d6179206265206e6f6d696e6174656420627920612073696e676c65206e6f6d696e61746f722c206974206973202020626f756e646564206f6e6c792065636f6e6f6d6963616c6c792028616c6c206e6f6d696e61746f72732061726520726571756972656420746f20706c6163652061206d696e696d756d207374616b65292e76616c696461746f72735665633c28543a3a4163636f756e7449642c20753332293e2043616e63656c20656e6163746d656e74206f66206120646566657272656420736c6173682e2043616e2062652063616c6c6564206279206569746865722074686520726f6f74206f726967696e206f72207468652060543a3a536c61736843616e63656c4f726967696e602e20506172616d65746572733a2065726120616e6420696e6469636573206f662074686520736c617368657320666f7220746861742065726120746f206b696c6c2e20436f6d706c65786974793a204f2855202b2053292077697468205520756e6170706c69656420736c6173686573207765696768746564207769746820553d3130303020616e64205320697320746865206e756d626572206f6620736c61736820696e646963657320746f2062652063616e63656c65642e202d20426173653a2035383730202b2033342e3631202a205320c2b573202d20526561643a20556e6170706c69656420536c6173686573202d2057726974653a20556e6170706c69656420536c6173686573736c6173685f696e646963657320466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f662073657373696f6e7320696e646566696e6974656c792e20546865206469737061746368206f726967696e206d75737420626520526f6f742e202d2042617365205765696768743a20322e303520c2b573202d2057726974653a20466f72636545726120466f72636520612063757272656e74207374616b657220746f206265636f6d6520636f6d706c6574656c7920756e7374616b65642c20696d6d6564696174656c792e204f285329207768657265205320697320746865206e756d626572206f6620736c617368696e67207370616e7320746f2062652072656d6f7665642042617365205765696768743a2035332e3037202b20322e333635202a205320c2b5732052656164733a20426f6e6465642c20536c617368696e67205370616e732c204163636f756e742c204c6f636b73205772697465733a20426f6e6465642c20536c617368696e67205370616e73202869662053203e2030292c204c65646765722c2050617965652c2056616c696461746f72732c204e6f6d696e61746f72732c204163636f756e742c204c6f636b732057726974657320456163683a205370616e536c617368202a205373746173686e756d5f736c617368696e675f7370616e7320536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e202d204f285629202d2042617365205765696768743a20322e323038202b202e303036202a205620c2b573202d2057726974653a20496e76756c6e657261626c657320466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c20626520726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e202d204e6f20617267756d656e74732e202d2042617365205765696768743a20312e39353920c2b573202d20577269746520466f72636545726120466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e202d2042617365205765696768743a20312e38353720c2b57320536574732074686520696465616c206e756d626572206f662076616c696461746f72732e2042617365205765696768743a20312e37313720c2b5732057726974653a2056616c696461746f7220436f756e74202852652d297365742074686520636f6e74726f6c6c6572206f6620612073746173682e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e202d2d2d2d2d2d2d2d2d2d2042617365205765696768743a2032352e323220c2b573202d20526561643a20426f6e6465642c204c6564676572204e657720436f6e74726f6c6c65722c204c6564676572204f6c6420436f6e74726f6c6c6572202d2057726974653a20426f6e6465642c204c6564676572204e657720436f6e74726f6c6c65722c204c6564676572204f6c6420436f6e74726f6c6c6572636f6e74726f6c6c6572202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e202d2042617365205765696768743a2031312e333320c2b57320202020202d20526561643a204c656467657220202020202d2057726974653a205061796565706179656552657761726444657374696e6174696f6e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e20416e642c2069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d20436f6e7461696e73206f6e6520726561642e202d2d2d2d2d2d2d2d2042617365205765696768743a2031362e353320c2b573202d20526561643a20457261456c656374696f6e5374617475732c204c6564676572202d2057726974653a2056616c696461746f72732c204e6f6d696e61746f7273204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546869732063616e206f6e6c792062652063616c6c6564207768656e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f662060746172676574736020284e292077686963682069732063617070656420617420436f6d7061637441737369676e6d656e74733a3a4c494d495420284d41585f4e4f4d494e4154494f4e53292e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e2042617365205765696768743a2032322e3334202b202e3336202a204e20c2b573207768657265204e20697320746865206e756d626572206f662074617267657473202d2052656164733a2045726120456c656374696f6e205374617475732c204c65646765722c2043757272656e7420457261202d205772697465733a2056616c696461746f72732c204e6f6d696e61746f7273746172676574735665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e2042617365205765696768743a2031372e313320c2b573202d20526561643a2045726120456c656374696f6e205374617475732c204c6564676572202d2057726974653a204e6f6d696e61746f72732c2056616c696461746f7273707265667356616c696461746f7250726566732052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e20456d697473206057697468647261776e602e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e20436f6d706c6578697479204f285329207768657265205320697320746865206e756d626572206f6620736c617368696e67207370616e7320746f2072656d6f76652042617365205765696768743a205570646174653a2035302e3532202b202e303238202a205320c2b573202d2052656164733a20457261456c656374696f6e5374617475732c204c65646765722c2043757272656e74204572612c204c6f636b732c205b4f726967696e204163636f756e745d202d205772697465733a205b4f726967696e204163636f756e745d2c204c6f636b732c204c6564676572204b696c6c3a2037392e3431202b20322e333636202a205320c2b573202d2052656164733a20457261456c656374696f6e5374617475732c204c65646765722c2043757272656e74204572612c20426f6e6465642c20536c617368696e67205370616e732c205b4f726967696e204163636f756e745d2c204c6f636b73202d205772697465733a20426f6e6465642c20536c617368696e67205370616e73202869662053203e2030292c204c65646765722c2050617965652c2056616c696461746f72732c204e6f6d696e61746f72732c205b4f726967696e204163636f756e745d2c204c6f636b73204e4f54453a2057656967687420616e6e6f746174696f6e20697320746865206b696c6c207363656e6172696f2c20776520726566756e64206f74686572776973652e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e20456d6974732060556e626f6e646564602e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c6564207669612020206077697468647261775f756e626f6e646564602e202d204f6e6520444220656e7472792e2042617365205765696768743a2035302e333420c2b573202d20526561643a2045726120456c656374696f6e205374617475732c204c65646765722c2043757272656e74204572612c204c6f636b732c205b4f726967696e204163636f756e745d202d2057726974653a205b4f726967696e204163636f756e745d2c204c6f636b732c204c65646765722041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c657220616e642069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e20456d6974732060426f6e646564602e2042617365205765696768743a2035342e383820c2b573202d20526561643a2045726120456c656374696f6e205374617475732c20426f6e6465642c204c65646765722c205b4f726967696e204163636f756e745d2c204c6f636b736d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2042617365205765696768743a2036372e383720c2b573202d20526561643a20426f6e6465642c204c65646765722c205b4f726967696e204163636f756e745d2c2043757272656e74204572612c20486973746f72792044657074682c204c6f636b73202d2057726974653a20426f6e6465642c2050617965652c205b4f726967696e204163636f756e745d2c204c6f636b732c204c6564676572000000000000487910000c0000000000000000000000c2c4120003000000000000000000000000000000000000000000000000000000000000000013130054791000000000000000000064791000070000000000000001000000000000009c7910000e0000000000000000000000c2c41200030000000000000000000000000000000000000000000000000000000000000000131300ac7910000000000000000000bc79100001000000000000000100000000000000c4791000150000000000000000000000c2c41200030000000000000000000000000000000000000000000000000000000000000000131300dc7910000000000000000000ec79100001000000000000000100000000000000f47910000d0000000000000000000000adf21200110000000000000000000000000000000000000000000000000000000000000000131300047a10000000000000000000147a100003000000000000000100000000000000e91b1000060000000105000000000000d0cf12000c00000000000000d0cf12000c0000000000000000000000000000000000000000131300dc7f100000000000000000002c7a100001000000000000000000000000000000ef1b1000060000000102000000000000d0cf12000c00000000000000347a1000290000000000000000000000000000000000000000131300dc7f10000000000000000000607a100001000000000000000000000000000000687a1000050000000105000000000000d0cf12000c00000000000000995b1000110000000000000000000000000000000000000000131300707a10000000000000000000807a100001000000000000000100000000000000386e12000a0000000105000000000000d0cf12000c000000000000004e5f10000e00000000000000000000000000000000000000001313003c7c10000000000000000000887a100001000000000000000100000000000000f51b10000a0000000105000000000000d0cf12000c00000000000000907a1000190000000000000000000000000000000000000000131300ac7a10000000000000000000bc7a100001000000000000000000000000000000c47a10000a00000000000000000000006f221000080000000000000000000000000000000000000000000000000000000000000000131300a88010000000000000000000d07a100004000000000000000000000000000000f07a1000090000000000000000000000f97a10000d0000000000000000000000000000000000000000000000000000000000000000131300087b10000000000000000000187b100004000000000000000000000000000000387b10001500000001050000000000006f2210000800000000000000148312000c0000000000000000000000000000000000000000131300a88010000000000000000000507b100001000000000000000000000000000000ff1b10000b00000002050500000000006f2210000800000000000000d0cf12000c00000000000000587b1000240000000000000000131300c07b100000000000000000007c7b100006000000000000000100000000000000ac7b10001200000002050500000000006f2210000800000000000000d0cf12000c00000000000000587b1000240000000000000000131300c07b10000000000000000000d07b10000b000000000000000100000000000000287c10001200000002050500000000006f2210000800000000000000d0cf12000c000000000000004e5f10000e00000000000000001313003c7c100000000000000000004c7c100005000000000000000100000000000000747c10001300000001050000000000006f2210000800000000000000a9f812000c0000000000000000000000000000000000000000131300807e10000000000000000000887c100003000000000000000000000000000000772210001000000001050000000000006f2210000800000000000000a07c10001d0000000000000000000000000000000000000000131300c07c10000000000000000000d07c100002000000000000000100000000000000e07c10000e00000001050000000000006f2210000800000000000000a9f812000c0000000000000000000000000000000000000000131300787d10000000000000000000f07c100002000000000000000100000000000000007d1000080000000000000000000000087d1000070000000000000000000000000000000000000000000000000000000000000000131300107d10000000000000000000207d100001000000000000000100000000000000287d1000130000000000000000000000a1ca12000700000000000000000000000000000000000000000000000000000000000000001313003c7d100000000000000000004c7d100003000000000000000100000000000000647d1000130000000000000000000000a9f812000c0000000000000000000000000000000000000000000000000000000000000000131300787d10000000000000000000887d100002000000000000000100000000000000987d10001000000001050000000000006f2210000800000000000000a87d10002f0000000000000000000000000000000000000000131300d87d10000000000000000000e87d100001000000000000000100000000000000f07d10000a0000000000000000000000fa7d10001d0000000000000000000000000000000000000000000000000000000000000000131300187e10000000000000000000287e1000040000000000000001000000000000000a1c10001300000002050500000000006f2210000800000000000000d0cf12000c00000000000000487e1000170000000000000000131300607e10000000000000000000707e1000020000000000000000000000000000001d1c10001300000002050500000000006f2210000800000000000000d0cf12000c00000000000000a9f812000c0000000000000000131300807e10000000000000000000907e100001000000000000000000000000000000301c10000d0000000105000000000000d0cf12000c00000000000000987e1000170000000000000000000000000000000000000000131300b07e10000000000000000000c07e1000010000000000000000000000000000003d1c1000090000000105000000000000c87e10002300000000000000eb7e1000220000000000000000000000000000000000000000131300107f10000000000000000000207f100002000000000000000100000000000000307f10001600000000000000000000006f221000080000000000000000000000000000000000000000000000000000000000000000131300a88010000000000000000000487f100001000000000000000000000000000000461c1000120000000000000000000000adf21200110000000000000000000000000000000000000000000000000000000000000000131300607f10000000000000000000507f100002000000000000000000000000000000581c1000120000000000000000000000adf21200110000000000000000000000000000000000000000000000000000000000000000131300607f10000000000000000000707f100002000000000000000000000000000000807f10000d00000000000000000000008d7f10002a0000000000000000000000000000000000000000000000000000000000000000131300dc7f10000000000000000000b87f100003000000000000000000000000000000d07f10000b00000000000000000000006b4110000d0000000000000000000000000000000000000000000000000000000000000000131300dc7f10000000000000000000ec7f1000010000000000000000000000000000006a1c1000110000000000000000000000f47f10001e00000000000000000000000000000000000000000000000000000000000000001313001480100000000000000000002480100002000000000000000100000000000000348010001500000000000000000000000fb912000400000000000000000000000000000000000000000000000000000000000000001313004c80100000000000000000005c8010000200000000000000010000000000000010ca11000e00000000000000000000001eca11000800000000000000000000000000000000000000000000000000000000000000001313006c80100000000000000000007c801000040000000000000001000000000000009c8010000a00000000000000000000006f221000080000000000000000000000000000000000000000000000000000000000000000131300a88010000000000000000000b8801000010000000000000000000000486973746f727944657074681f0000000000000001000000330000002b9010002300000000131300000000004e9010004e00000000131300000000009c90100043000000df9010002b0000000a9110004400000056616c696461746f72436f756e7400001f000000000000000100000034000000019010002a0000004d696e696d756d56616c696461746f72436f756e740000001f000000000000000100000035000000b18f100050000000496e76756c6e657261626c65730000001f000000000000000100000036000000dd8e100056000000338f100053000000868f10002b0000009d8e1000400000005374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e0000004c8e10005100000050617965650000001f000000000000000100000037000000138e100039000000c28d1000510000004e6f6d696e6174696f6e733c543a3a4163636f756e7449643e0000001f000000000000000100000038000000698d10005900000043757272656e744572610000d98c1000170000000013130000000000f08c100059000000498d100020000000416374697665457261416374697665457261496e666f00001f0000000000000001000000380000002a8c1000360000000013130000000000608c10002e0000008e8c10004b00000045726173537461727453657373696f6e496e646578000000de8b10004c0000004578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3ec08b10001e000000001313000000000060891000580000000013130000000000b88910002a000000708b100050000000457261735374616b657273436c697070656400001f000000000000000100000039000000e2891000260000000013130000000000088a1000560000005e8a100037000000958a100047000000dc8a10003d0000000013130000000000198b1000570000000013130000000000b88910002a000000708b1000500000004572617356616c696461746f72507265667300001f00000000000000010000003a0000001c89100044000000001313000000000060891000580000000013130000000000b88910002a0000004572617356616c696461746f725265776172640092881000420000000013130000000000d488100048000000457261526577617264506f696e74733c543a3a4163636f756e7449643e0000001f00000000000000010000003b0000001e8810002b000000498810004900000045726173546f74616c5374616b6500009c8710003b000000d787100047000000466f726365457261466f7263696e67001f0000000000000001000000370000008787100015000000536c6173685265776172644672616374696f6e001f000000000000000100000034000000108710003e00000000131300000000004e8710003900000043616e63656c6564536c6173685061796f7574001f00000000000000010000003c0000009086100045000000d58610003b000000556e6170706c696564536c61736865735665633c556e6170706c696564536c6173683c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3e001f0000000000000001000000360000005f86100031000000426f6e646564457261735665633c28457261496e6465782c2053657373696f6e496e646578293e001f000000000000000100000036000000b5851000490000000013130000000000fe85100032000000308610002f0000002850657262696c6c2c2042616c616e63654f663c543e29001f0000000000000001000000380000004885100051000000998510001c0000001f000000000000000100000038000000f084100058000000736c617368696e673a3a536c617368696e675370616e73001f000000000000000100000038000000cd8410002300000028543a3a4163636f756e7449642c20736c617368696e673a3a5370616e496e64657829736c617368696e673a3a5370616e5265636f72643c42616c616e63654f663c543e3e0000001f00000000000000010000003d000000508410004f0000009f8410002e0000004561726c69657374556e6170706c696564536c6173680000118410003f000000b88310005900000072831000460000001f00000000000000010000003800000019831000590000007283100046000000517565756564456c6563746564456c656374696f6e526573756c743c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e005b82100059000000b4821000580000000c8310000d00000051756575656453636f7265001f0000000000000001000000380000002f8210002c000000456c656374696f6e5374617475733c543a3a426c6f636b4e756d6265723e00001f000000000000000100000037000000c281100052000000148210001b000000497343757272656e7453657373696f6e46696e616c0000001f0000000000000001000000380000005981100053000000ac811000160000001f00000000000000010000003e000000fe8010003300000050ca11001f000000001313000000000031811000280000004d69677261746545726100001f000000000000000100000038000000c08010003e0000002054686520657261207768657265207765206d696772617465642066726f6d204c617a79205061796f75747320746f2053696d706c65205061796f7574732054727565206966206e6574776f726b20686173206265656e20757067726164656420746f20746869732076657273696f6e2e20546869732069732073657420746f2076332e302e3020666f72206e6577206e6574776f726b732e2054727565206966207468652063757272656e74202a2a706c616e6e65642a2a2073657373696f6e2069732066696e616c2e204e6f74652074686174207468697320646f6573206e6f742074616b652065726120666f7263696e6720696e746f206163636f756e742e20466c616720746f20636f6e74726f6c2074686520657865637574696f6e206f6620746865206f6666636861696e20656c656374696f6e2e205768656e20604f70656e285f29602c2077652061636365707420736f6c7574696f6e7320746f206265207375626d69747465642e205468652073636f7265206f66207468652063757272656e74205b60517565756564456c6563746564605d2e20546865206e6578742076616c696461746f72207365742e2041742074686520656e64206f6620616e206572612c206966207468697320697320617661696c61626c652028706f74656e7469616c6c792066726f6d2074686520726573756c74206f6620616e206f6666636861696e20776f726b6572292c20697420697320696d6d6564696174656c7920757365642e204f74686572776973652c20746865206f6e2d636861696e20656c656374696f6e2069732065786563757465642e20536e617073686f74206f66206e6f6d696e61746f72732061742074686520626567696e6e696e67206f66207468652063757272656e7420656c656374696f6e2077696e646f772e20546869732073686f756c64206f6e6c79206861766520612076616c7565207768656e205b60457261456c656374696f6e537461747573605d203d3d2060456c656374696f6e5374617475733a3a4f70656e285f29602e20536e617073686f74206f662076616c696461746f72732061742074686520626567696e6e696e67206f66207468652063757272656e7420656c656374696f6e2077696e646f772e20546869732073686f756c64206f6e6c7920546865206561726c696573742065726120666f72207768696368207765206861766520612070656e64696e672c20756e6170706c69656420736c6173682e205265636f72647320696e666f726d6174696f6e2061626f757420746865206d6178696d756d20736c617368206f6620612073746173682077697468696e206120736c617368696e67207370616e2c2061732077656c6c20617320686f77206d7563682072657761726420686173206265656e2070616964206f75742e20536c617368696e67207370616e7320666f72207374617368206163636f756e74732e20416c6c20736c617368696e67206576656e7473206f6e206e6f6d696e61746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682076616c7565206f6620746865206572612e20416c6c20736c617368696e67206576656e7473206f6e2076616c696461746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682070726f706f7274696f6e20616e6420736c6173682076616c7565206f6620746865206572612e2041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e204d75737420636f6e7461696e7320696e666f726d6174696f6e20666f72206572617320666f72207468652072616e67653a20605b6163746976655f657261202d20626f756e64696e675f6475726174696f6e3b206163746976655f6572615d6020416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e2054686520616d6f756e74206f662063757272656e637920676976656e20746f207265706f7274657273206f66206120736c617368206576656e74207768696368207761732063616e63656c65642062792065787472616f7264696e6172792063697263756d7374616e6365732028652e672e20676f7665726e616e6365292e205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e204d6f6465206f662065726120666f7263696e672e2054686520746f74616c20616d6f756e74207374616b656420666f7220746865206c6173742060484953544f52595f44455054486020657261732e20496620746f74616c206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207374616b652069732072657475726e65642e205265776172647320666f7220746865206c6173742060484953544f52595f44455054486020657261732e20496620726577617264206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207265776172642069732072657475726e65642e2054686520746f74616c2076616c696461746f7220657261207061796f757420666f7220746865206c6173742060484953544f52595f44455054486020657261732e2045726173207468617420686176656e27742066696e697368656420796574206f7220686173206265656e2072656d6f76656420646f65736e27742068617665207265776172642e2053696d696c617220746f2060457261735374616b657273602c207468697320686f6c64732074686520707265666572656e636573206f662076616c696461746f72732e2054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e2049732069742072656d6f7665642061667465722060484953544f52595f44455054486020657261732e20436c6970706564204578706f73757265206f662076616c696461746f72206174206572612e20546869732069732073696d696c617220746f205b60457261735374616b657273605d20627574206e756d626572206f66206e6f6d696e61746f7273206578706f736564206973207265647563656420746f207468652060543a3a4d61784e6f6d696e61746f72526577617264656450657256616c696461746f72602062696767657374207374616b6572732e20284e6f74653a20746865206669656c642060746f74616c6020616e6420606f776e60206f6620746865206578706f737572652072656d61696e7320756e6368616e676564292e2054686973206973207573656420746f206c696d69742074686520692f6f20636f737420666f7220746865206e6f6d696e61746f72207061796f75742e2054686973206973206b657965642066697374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e204578706f73757265206f662076616c696461746f72206174206572612e205468652073657373696f6e20696e646578206174207768696368207468652065726120737461727420666f7220746865206c6173742060484953544f52595f44455054486020657261732e20546865206163746976652065726120696e666f726d6174696f6e2c20697420686f6c647320696e64657820616e642073746172742e20546865206163746976652065726120697320746865206572612063757272656e746c792072657761726465642e2056616c696461746f7220736574206f66207468697320657261206d75737420626520657175616c20746f206053657373696f6e496e746572666163653a3a76616c696461746f7273602e205468652063757272656e742065726120696e6465782e205468697320697320746865206c617465737420706c616e6e6564206572612c20646570656e64696e67206f6e20686f77207468652053657373696f6e2070616c6c657420717565756573207468652076616c696461746f72207365742c206974206d6967687420626520616374697665206f72206e6f742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e204e756d626572206f66206572617320746f206b65657020696e20686973746f72792e20496e666f726d6174696f6e206973206b65707420666f72206572617320696e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e204d757374206265206d6f7265207468616e20746865206e756d626572206f6620657261732064656c617965642062792073657373696f6e206f74686572776973652e20492e652e2061637469766520657261206d75737420616c7761797320626520696e20686973746f72792e20492e652e20606163746976655f657261203e2063757272656e745f657261202d20686973746f72795f646570746860206d7573742062652067756172616e746565642e000000000000c09110000e00000000000000148312000c0000000000000000131300d09110000000000000000000e0911000010000000000000000000000e89110000f000000000000006f221000080000000000000000131300f8911000000000000000000008921000010000000000000053657373696f6e7350657245726100001f00000000000000010000003f000000499210001c000000426f6e64696e674475726174696f6e001f0000000000000001000000400000001092100039000000204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e4572726f723a2073746172745f73657373696f6e5f696e646578206d7573742062652073657420666f722063757272656e745f65726100b49210001f000000d392100016000000e992100009000000f09f92b8206e65772076616c696461746f7220736574206f662073697a652020686173206265656e20656c6563746564207669612020666f7220657261200000409410002a000000059410003b00000065786163746c79206f6e65206f6620606d617962655f76616c696461746f726020616e6420606d617962655f6e6f6d696e6174696f6e2e69735f736f6d656020697320747275652e2069735f76616c696461746f722069732066616c73653b206d617962655f6e6f6d696e6174696f6e20697320736f6d653b20716564000000ee2210005b000000a20a000022000000ac93100025000000d19310000b000000dc93100029000000f09f92b820412062657474657220736f6c7574696f6e20287769746820636f6d707574652020616e642073636f7265202920686173206265656e2076616c69646174656420616e642073746f726564206f6e20636861696e2ef09f92b820646574656374656420616e206572726f7220696e20746865207374616b696e67206c6f636b696e6720616e6420736e617073686f742ef09f92b820756e2d636f6d70616374696e6720736f6c7574696f6e206661696c65642064756520746f200000000000005f1a10000d00000000000000d0971000010000000000000000000000571a10000800000000000000d89710000100000000000000000000004a1a10000d00000000000000e09710000100000000000000000000003d1a10000d00000000000000e8971000010000000000000000000000311a10000c00000000000000f0971000010000000000000000000000231a10000e00000000000000f8971000010000000000000000000000121a1000110000000000000000981000010000000000000000000000011a1000110000000000000008981000010000000000000000000000f51910000c0000000000000010981000010000000000000000000000e81910000d0000000000000018981000010000000000000000000000dc1910000c0000000000000020981000010000000000000000000000ca191000120000000000000028981000010000000000000000000000b01910001a00000000000000309810000100000000000000000000009e191000120000000000000038981000010000000000000000000000901910000e0000000000000040981000010000000000000000000000791910001700000000000000489810000100000000000000000000006319100016000000000000005098100001000000000000000000000050191000130000000000000058981000010000000000000000000000381910001800000000000000609810000100000000000000000000002519100013000000000000006898100002000000000000000000000011191000140000000000000078981000020000000000000000000000fb181000160000000000000088981000010000000000000000000000e4181000170000000000000090981000010000000000000000000000cb181000190000000000000098981000020000000000000000000000b61810001500000000000000a8981000010000000000000000000000a51810001100000000000000b0981000010000000000000000000000931810001200000000000000b89810000100000000000000000000007a1810001900000000000000c09810000100000000000000000000006c1810000e00000000000000c8981000010000000000000000000000571810001500000000000000d0981000010000000000000000000000411810001600000000000000d89810000100000000000000399f10001a000000249f1000150000000b9f100019000000ed9e10001e000000d49e100019000000c39e100011000000a19e1000220000006e9e100033000000499e100025000000209e100029000000ed9d100033000000d69d100017000000b79d10001f000000969d100021000000539d1000430000001a9d100039000000da9c100040000000a69c1000340000007a9c10002c000000149c1000580000006c9c10000e000000939b100057000000ea9b10002a0000004e9b100045000000fb9a1000530000008e9a100058000000e69a100015000000459a100049000000f499100051000000ae99100046000000909910001e0000003e991000520000000d99100031000000e09810002d00000020496e636f7272656374206e756d626572206f6620736c617368696e67207370616e732070726f76696465642e20496e636f72726563742070726576696f757320686973746f727920646570746820696e7075742070726f76696465642e205468652063616c6c206973206e6f7420616c6c6f7765642061742074686520676976656e2074696d652064756520746f207265737472696374696f6e73206f6620656c656374696f6e20706572696f642e2054686520656c656374696f6e2073697a6520697320696e76616c69642e2054686520636c61696d65642073636f726520646f6573206e6f74206d61746368207769746820746865206f6e6520636f6d70757465642066726f6d2074686520646174612e20546865207375626d697474656420726573756c742068617320756e6b6e6f776e206564676573207468617420617265206e6f7420616d6f6e67207468652070726573656e7465642077696e6e6572732e20412073656c6620766f7465206d757374206f6e6c79206265206f726967696e617465642066726f6d20612076616c696461746f7220746f204f4e4c59207468656d73656c7665732e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f72732068617320616e2065646765207768696368206973207375626d6974746564206265666f726520746865206c617374206e6f6e2d7a65726f20736c617368206f6620746865207461726765742e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f72732068617320616e206564676520746f20776869636820746865792068617665206e6f7420766f746564206f6e20636861696e2e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f7273206973206e6f7420616e20616374697665206e6f6d696e61746f72206f6e20636861696e2e204572726f72207768696c65206275696c64696e67207468652061737369676e6d656e7420747970652066726f6d2074686520636f6d706163742e20546869732063616e2068617070656e20696620616e20696e64657820697320696e76616c69642c206f72206966207468652077656967687473205f6f766572666c6f775f2e204f6e65206f6620746865207375626d69747465642077696e6e657273206973206e6f7420616e206163746976652063616e646964617465206f6e20636861696e2028696e646578206973206f7574206f662072616e676520696e20736e617073686f74292e20496e636f7272656374206e756d626572206f662077696e6e65727320776572652070726573656e7465642e2054686520736e617073686f742064617461206f66207468652063757272656e742077696e646f77206973206d697373696e672e20546865207375626d697474656420726573756c74206973206e6f7420617320676f6f6420617320746865206f6e652073746f726564206f6e20636861696e2e20546865207375626d697474656420726573756c74206973207265636569766564206f7574206f6620746865206f70656e2077696e646f772e205265776172647320666f72207468697320657261206861766520616c7265616479206265656e20636c61696d656420666f7220746869732076616c696461746f722e204974656d7320617265206e6f7420736f7274656420616e6420756e697175652e20496e76616c6964206e756d626572206f66206e6f6d696e6174696f6e732e20496e76616c69642065726120746f207265776172642e20417474656d7074696e6720746f2074617267657420612073746173682074686174207374696c6c206861732066756e64732e2043616e206e6f74207265626f6e6420776974686f757420756e6c6f636b696e67206368756e6b732e2043616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b732e2043616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e63652e20536c617368207265636f726420696e646578206f7574206f6620626f756e64732e204475706c696361746520696e6465782e20546172676574732063616e6e6f7420626520656d7074792e20436f6e74726f6c6c657220697320616c7265616479207061697265642e20537461736820697320616c726561647920626f6e6465642e204e6f742061207374617368206163636f756e742e204e6f74206120636f6e74726f6c6c6572206163636f756e742e00fe9f100040000000bc9f10004200000096231000010000008b9f10003100000096231000010000005374616b696e674f6666636861696e76616c6964617465556e7369676e65642073756363656564656420666f72206120736f6c7574696f6e206174206572612076616c696461746520756e7369676e65642070726520646973706174636820636865636b73206661696c65642064756520746f206d6f64756c65206572726f72202372656a656374696e6720756e7369676e6564207472616e73616374696f6e2062656361757365206974206973206e6f74206c6f63616c2f696e2d626c6f636b2e7061726974792f7374616b696e672d656c656374696f6e2f6661696c656420746f20777269746520746f206f6666636861696e2064622e666f726b2e726563656e746c792065786563757465642e5265706f72747366696e616c6e756d44656665727265644f6666656e636573004da110001800000065a11000240000007374616b696e6770616c6c65745f7374616b696e673a3a6f6666636861696e5f656c656374696f6e2f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f7374616b696e672f7372632f6f6666636861696e5f656c656374696f6e2e7273707265706172656420736f6c7574696f6e2061667465722020657175616c697a6174696f6e20697465726174696f6e7320776974682073636f7265200000009ca110006200000034000000120000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f7072696d6974697665732f72756e74696d652f7372632f63757276652e72730000000000008ca0100007000000010500000000000060a310000d000000000000006da31000340000000000000000000000000000000000000000131300a4a310000000000000000000b4a31000010000000000000000000000000000009ba01000100000000000000000000000bca31000190000000000000000000000000000000000000000000000000000000000000000131300d8a310000000000000000000e8a3100002000000000000000100000000000000f8a310001600000002050500000000000ea41000040000000000000012a410000e0000000000000020a4100012000000000000000013130034a41000000000000000000044a41000010000000000000001000000000000004ca410001200000001050000000000000ea41000040000000000000059c9120007000000000000000000000000000000000000000013130060a41000000000000000000070a410000600000000000000010000005265706f727449644f663c543e4f6666656e636544657461696c733c543a3a4163636f756e7449642c20543a3a4964656e74696669636174696f6e5475706c653e0000001f00000000000000010000003800000073a61000520000005665633c44656665727265644f6666656e63654f663c543e3e0000001f00000000000000010000003600000009a610005900000062a6100011000000436f6e63757272656e745265706f727473496e6465784b696e644f706171756554696d65536c6f745665633c5265706f727449644f663c543e3e00001f000000000000000100000036000000bfa510004a0000005265706f72747342794b696e64496e64657800001f000000000000000100000036000000a0a41000440000000013130000000000e4a410002f000000001313000000000013a510005200000065a510005a00000020456e756d65726174657320616c6c207265706f727473206f662061206b696e6420616c6f6e672077697468207468652074696d6520746865792068617070656e65642e20416c6c207265706f7274732061726520736f72746564206279207468652074696d65206f66206f6666656e63652e204e6f74652074686174207468652061637475616c2074797065206f662074686973206d617070696e6720697320605665633c75383e602c207468697320697320626563617573652076616c756573206f6620646966666572656e7420747970657320617265206e6f7420737570706f7274656420617420746865206d6f6d656e7420736f2077652061726520646f696e6720746865206d616e75616c2073657269616c697a6174696f6e2e204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e204465666572726564207265706f72747320746861742068617665206265656e2072656a656374656420627920746865206f6666656e63652068616e646c657220616e64206e65656420746f206265207375626d69747465642061742061206c617465722074696d652e20546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e6772616e6470613a65717569766f6361696d2d6f6e6c696e653a6f66666c696e706172613a646f75626c652d766f7465000000b3a7100016000000c9a710001600000080a710002d000000ada7100003000000b0a710000300000000000000200000000000000002000000000000000200000000000000030000000100000020000000080000000200000000000000000000000200000003000000020000002000000000000000020000000000000002000000000000000300000042697450747220726567696f6e2063616e6e6f7420777261702074686520616464726573732073706163653a20202b20203d204269745074722063616e6e6f7420616464726573732020626974733b20746865206d6178696d756d206973204469676573744974656d206e6f7420657175616c5468657265206973206f6e6c79206f6e6520666174616c206572726f723b207165640000001f00000008000000040000004100000098d2110034000000cf020000010000004e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f7221496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473210000dba810000d000000c0a810001b0000001de611000200000098d21100340000002c0300000100000042616420696e70757420646174612070726f766964656420746f20657865637574655f626c6f636bf0a8100010000000696e697469616c697a655f626c6f636b08a910000f0000006170706c795f65787472696e7369630020a9100013000000696e686572656e745f65787472696e73696373003ca910000f000000636865636b5f696e686572656e74730054a910001400000076616c69646174655f7472616e73616374696f6e70a910000f0000006f6666636861696e5f776f726b65720088a91000150000006c6f63616c5f76616c69646174696f6e5f64617461000000a8a910000e00000070617261636861696e5f636f64650000c0a91000090000006765745f6865616473000000d4a91000240000007375626d69745f7265706f72745f65717569766f636174696f6e5f65787472696e73696300aa10001c00000067656e65726174655f6b65795f6f776e6572736869705f70726f6f6624aa10001500000067656e65726174655f73657373696f6e5f6b65797300000044aa1000130000006465636f64655f73657373696f6e5f6b6579730060aa10000d0000006163636f756e745f6e6f6e636500000078aa10000a00000071756572795f696e666f556e63616c6c61626c65556e657870656374656454696d65706f696e7457726f6e6754696d65706f696e744e6f54696d65706f696e744e6f74466f756e6453656e646572496e5369676e61746f726965735369676e61746f726965734f75744f664f72646572546f6f4d616e795369676e61746f72696573546f6f4665775369676e61746f726965734e6f417070726f76616c734e6565646564416c7265616479417070726f7665645a65726f5468726573686f6c64626174636861735f73756261735f6d756c7469617070726f76655f61735f6d756c746963616e63656c5f61735f6d756c7469000000000000a0ac10001000000000000000b0ac1000020000000000000000000000c0ac1000020000000000000000000000d0ac10000e0000000000000000131300000000000000000000000000e0ac1000010000000000000000000000e8ac10000b00000000000000f4ac10000300000000000000000000000cad10000200000000000000000000001cad100010000000000000002cad10000400000000000000000000004cad10000200000000000000000000005cad100010000000000000006cad100005000000000000000000000094ad1000020000000000000000000000a4ad100011000000000000002cad1000040000000000000000000000b8ad100002000000000000000000000082aa10000a00000000000000c8ad1000010000000000000000000000d0ad100001000000000000004261746368496e746572727570746564c2c4120003000000500b13000d000000bcb010005600000012b11000130000004261746368436f6d706c65746564000089b01000330000004e65774d756c7469736967000eb51200090000000eb512000900000058af100008000000fcaf1000520000004eb010003b0000004d756c7469736967417070726f76616c0eb512000900000042af1000160000000eb512000900000058af10000800000060af100056000000b6af1000460000004d756c746973696745786563757465640eb512000900000042af1000160000000eb512000900000058af1000080000007c2e12000e000000a2ae10004b000000edae1000550000004d756c746973696743616e63656c6c65640000000fae10004c0000005bae100047000000c2c4120003000000d8ad10003700000020412063616c6c20776974682061206066616c73656020497343616c6c61626c652066696c7465722077617320617474656d707465642e2041206d756c7469736967206f7065726174696f6e20686173206265656e2063616e63656c6c65642e20466972737420706172616d20697320746865206163636f756e7420746861742069732063616e63656c6c696e672c20746869726420697320746865206d756c7469736967206163636f756e742c20666f757274682069732068617368206f66207468652063616c6c2e2041206d756c7469736967206f7065726174696f6e20686173206265656e2065786563757465642e20466972737420706172616d20697320746865206163636f756e74207468617420697320617070726f76696e672c20746869726420697320746865206d756c7469736967206163636f756e742c20666f757274682069732068617368206f66207468652063616c6c20746f2062652065786563757465642e54696d65706f696e743c426c6f636b4e756d6265723e43616c6c486173682041206d756c7469736967206f7065726174696f6e20686173206265656e20617070726f76656420627920736f6d656f6e652e20466972737420706172616d20697320746865206163636f756e74207468617420697320617070726f76696e672c20746869726420697320746865206d756c7469736967206163636f756e742c20666f757274682069732068617368206f66207468652063616c6c2e2041206e6577206d756c7469736967206f7065726174696f6e2068617320626567756e2e20466972737420706172616d20697320746865206163636f756e74207468617420697320617070726f76696e672c207365636f6e6420697320746865206d756c7469736967206163636f756e742c2074686972642069732068617368206f66207468652063616c6c2e204261746368206f66206469737061746368657320636f6d706c657465642066756c6c792077697468206e6f206572726f722e204261746368206f66206469737061746368657320646964206e6f7420636f6d706c6574652066756c6c792e20496e646578206f66206669727374206661696c696e6720646973706174636820676976656e2c2061732077656c6c20617320746865206572726f722e446561644163636f756e744b656570416c6976654578697374656e7469616c4465706f736974496e73756666696369656e7442616c616e63654c69717569646974795265737472696374696f6e7356657374696e6742616c616e63657365745f62616c616e63657472616e736665725f6b6565705f616c697665546f74616c49737375616e63650000000088b21000070000000000000050da110002000000000000000000000090b2100001000000000000000000000098b21000080000000000000050da1100020000000000000000000000a0b21000020000000000000000000000b0b210000800000000000000b8b21000030000000000000000000000d0b21000010000000000000000000000d8b210000a0000000000000030121100030000000000000000000000e4b21000010000000000000000000000a4711200070000000000000050da1100020000000000000000000000ecb210000100000000000000456e646f77656400f1b310002f000000447573744c6f737482b3100050000000d2b310001f0000005472616e736665720eb51200090000000eb51200090000006b721200070000005cb310002600000042616c616e636553657400002bb3100031000000f4b210003700000020536f6d6520616d6f756e7420776173206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e20412062616c616e6365207761732073657420627920726f6f74202877686f2c20667265652c207265736572766564292e205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c7565292e20416e206163636f756e74207761732072656d6f7665642077686f73652062616c616e636520776173206e6f6e2d7a65726f206275742062656c6f77204578697374656e7469616c4465706f7369742c20726573756c74696e6720696e20616e206f75747269676874206c6f73732e20416e206163636f756e74207761732063726561746564207769746820736f6d6520667265652062616c616e63652e74696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c4c6174656e6573730000000000000024b810000a0000000000000000000000e8c91200030000000000000000000000000000000000000000000000000000000000000000131300a0b81000000000000000000030b8100001000000000000000100000000000000d90113000b000000000000000000000038b8100027000000000000000000000000000000000000000000000000000000000000000013130060b81000000000000000000070b810000100000000000000010000000000000078b810000b0000000000000000000000e8c91200030000000000000000000000000000000000000000000000000000000000000000131300a0b81000000000000000000084b810000200000000000000010000000000000094b810000b0000000000000000000000e8c91200030000000000000000000000000000000000000000000000000000000000000000131300a0b810000000000000000000b0b8100001000000000000000100000000000000b8b810000a0000000000000000000000c2b8100016000000000000000000000000000000000000000000000000000000000000000013130074b910000000000000000000d8b810000a00000000000000010000000000000028b910000f000000000000000000000037b910001400000000000000000000000000000000000000000000000000000000000000001313004cb9100000000000000000005cb910000100000000000000000000000000000064b910000e0000000000000000000000c2b8100016000000000000000000000000000000000000000000000000000000000000000013130074b91000000000000000000084b91000010000000000000001000000000000008cb910000c0000000000000000000000c2c4120003000000000000000000000000000000000000000000000000000000000000000013130054ba1000000000000000000098b9100009000000000000000100000000000000e0b91000110000000105000000000000c2c412000300000000000000f1b910001b00000000000000000000000000000000000000001313000cba100000000000000000001cba100001000000000000000100000000000000a82012000b000000000000000000000024ba10000f000000000000000000000000000000000000000000000000000000000000000013130034ba1000000000000000000044ba10000200000000000000000000000000000051b4100008000000000000000000000090d012000e000000000000000000000000000000000000000000000000000000000000000013130054ba1000000000000000000064ba100005000000000000000100000045706f6368496e64657800001dc01000150000005665633c28417574686f7269747949642c2042616265417574686f72697479576569676874293e001f00000000000000010000003600000002c010001b00000047656e65736973536c6f7400a0bf10003e000000debf10002400000043757272656e74536c6f74001f0000000000000001000000420000008bbf10001500000052616e646f6d6e6573737363686e6f72726b656c3a3a52616e646f6d6e657373c5bd10002e0000000013130000000000f3bd10000b0000000013130000000000febd1000410000003fbe10003e0000007dbe100045000000c2be10004500000007bf10004100000048bf1000430000004e65787445706f6368436f6e6669674e657874436f6e66696744657363726970746f72001f0000000000000001000000380000009fbd1000260000004e65787452616e646f6d6e65737300001f00000000000000010000004300000088bd1000170000005365676d656e74496e64657843bc10001f000000001313000000000062bc10003d0000009fbc100040000000dfbc100025000000001313000000000004bd10003b0000003fbd10004200000081bd100007000000556e646572436f6e737472756374696f6e5665633c7363686e6f72726b656c3a3a52616e646f6d6e6573733e1f000000000000000100000036000000febb1000450000004d6179626552616e646f6d6e657373001f00000000000000010000003800000077bb100040000000b7bb1000470000001f0000000000000001000000340000008cba1000360000000013130000000000c2ba10004500000007bb1000440000004bbb10002c00000020486f77206c617465207468652063757272656e7420626c6f636b20697320636f6d706172656420746f2069747320706172656e742e205468697320656e74727920697320706f70756c617465642061732070617274206f6620626c6f636b20657865637574696f6e20616e6420697320636c65616e6564207570206f6e20626c6f636b2066696e616c697a6174696f6e2e205175657279696e6720746869732073746f7261676520656e747279206f757473696465206f6620626c6f636b20657865637574696f6e20636f6e746578742073686f756c6420616c77617973207969656c64207a65726f2e2054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d6560206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e2054574f582d4e4f54453a20605365676d656e74496e6465786020697320616e20696e6372656173696e6720696e74656765722c20736f2074686973206973206f6b61792e2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e205765206d616b6520612074726164656f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e2057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f2060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e20576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572792065706f63682e204e6578742065706f63682072616e646f6d6e6573732e204e6578742065706f636820636f6e66696775726174696f6e2c206966206368616e6765642e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2043757272656e7420736c6f74206e756d6265722e2054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e2054686973206973203020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e000000000000a4c010000d00000000000000e8c91200030000000000000000131300b4c010000000000000000000c4c01000020000000000000000000000d4c010001100000000000000904a1100090000000000000000131300e8c010000000000000000000f8c01000050000000000000045706f63684475726174696f6e0000001f00000000000000010000004400000050c210004300000093c210003f0000004578706563746564426c6f636b54696d650000001f00000000000000010000004500000020c110004100000061c1100044000000a5c1100041000000e6c110004200000028c210002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e20546865206e756d626572206f66202a2a736c6f74732a2a207468617420616e2065706f63682074616b65732e20576520636f75706c652073657373696f6e7320746f2065706f6368732c20692e652e2077652073746172742061206e65772073657373696f6e206f6e636520746865206e65772065706f636820626567696e732e000060c4100064000000720000001300000060c4100064000000890000001800000060c4100064000000b50000001900000060c4100064000000000100004200000060c410006400000014010000420000004475706c696361746520766f74657220286f72206f7468657220636f727275707420696e707574292e00000060c4100064000000580100001500000060c41000640000005d0100001e0000001f00000000000000010000004600000060c4100064000000600000001a00000060c4100064000000600000002c00000060c4100064000000cd0100002400000060c4100064000000ce0100002400000060c4100064000000f20100002300000060c4100064000000f40100002400000060c4100064000000170200003500000060c4100064000000210200002400000060c4100064000000430200003500000060c4100064000000440200003500000060c4100064000000590200002b00000060c41000640000005a0200002800000060c4100064000000640200002b00000060c410006400000065020000280000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f7072696d6974697665732f70687261676d656e2f7372632f7265647563652e727365706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b2071656400000030c51000580000008b0100001b00000030c510005800000093010000200000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f626162652f7372632f6c69622e72730000000038ab1000050000000000000064c610000100000000000000000000007cc610001400000000000000000000003dab100006000000000000001cc710000200000000000000000000004cc710000a000000000000000000000043ab100008000000000000009cc71000040000000000000000000000fcc710003300000000000000000000004bab1000100000000000000094c91000040000000000000000000000f4c910002700000000000000000000005bab10000f000000000000002ccb10000400000000000000000000008ccb10001b000000000000000000000095db100005000000000000009adb100017000000b4d81000200000000013130000000000d4d810005100000025d9100031000000001313000000000056d910001f000000001313000000000075d910003c000000001313000000000091c212000b000000b1d9100024000000d5d910002e00000003da10003100000034c312000c000000001313000000000034da1000560000008ada10004d000000d7da1000560000002ddb10005400000081db100014000000000000008b46120005000000000000004bd010000300000000000000441912000400000000000000481912001700000013d810003800000000131300000000004bd81000300000000013130000000000948c120034000000001313000000000091c212000b0000007bd810001900000094d810002000000034c312000c000000000000005d4b120009000000000000004bd0100003000000000000004ed010001100000000000000adf21200110000000000000074d410000f0000000000000083d410002100000000000000441912000400000000000000481912001700000092d0100056000000e8d010003f0000000013130000000000a4d4100055000000f9d4100008000000001313000000000027d11000540000007bd1100058000000d3d110000e0000000013130000000000948c1200340000000013130000000000eccc10005600000042cd10005100000093cd10001c000000e1d110005700000038d21000550000008dd210003600000001d5100023000000001313000000000024d51000480000006cd51000470000000013130000000000b3d51000570000000ad610005600000060d6100038000000001313000000000091c212000b00000098d610001500000064ce10003400000098ce100050000000e8ce100052000000add61000490000003acf10003000000011d310003600000047d310003f000000804211000d000000f6d610001c00000086d310004c000000d2d3100024000000f6d310003d00000012d71000200000003ea211000f00000032d710002400000056d71000240000007ad7100025000000aec612000d0000009fd7100030000000cfd710003100000000d810001300000034c312000c000000000000005d4b120009000000000000004bd0100003000000000000004ed010001100000000000000adf21200110000000000000074d410000f0000000000000083d41000210000000000000081d0100009000000000000008ad010000800000092d0100056000000e8d010003f000000001313000000000027d11000540000007bd1100058000000d3d110000e0000000013130000000000948c1200340000000013130000000000eccc10005600000042cd10005100000093cd10001c000000e1d110005700000038d21000550000008dd210003600000026ce1000340000000013130000000000c3d210004e000000001313000000000091c212000b0000005ace10000a00000064ce10003400000098ce100050000000e8ce1000520000003acf10003000000011d310003600000047d310003f000000804211000d00000086d310004c000000d2d3100024000000f6d310003d000000a9cf1000230000003ea211000f00000033d410002000000053d4100021000000aec612000d000000eccf10002f0000001bd010003000000034c312000c000000000000005d4b120009000000000000004bd0100003000000000000004ed010001100000000000000adf2120011000000000000005fd01000090000000000000068d01000190000000000000081d0100009000000000000008ad010000800000064cc100056000000bacc1000320000000013130000000000948c1200340000000013130000000000eccc10005600000042cd10005100000093cd10001c000000afcd10005800000007ce10001f00000026ce100034000000001313000000000091c212000b0000005ace10000a00000064ce10003400000098ce100050000000e8ce1000520000003acf100030000000804211000d0000006acf1000220000008ccf10001d000000a9cf100023000000cccf100020000000aec612000d000000eccf10002f0000001bd010003000000034c312000c0000002043616e63656c2061207072652d6578697374696e672c206f6e2d676f696e67206d756c7469736967207472616e73616374696f6e2e20416e79206465706f7369742072657365727665642070726576696f75736c7920666f722074686973206f7065726174696f6e2077696c6c20626520756e7265736572766564206f6e20737563636573732e202d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e202d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869732064697370617463682e204d6179206e6f7420626520656d7074792e202d206074696d65706f696e74603a205468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e20666f7220746869732064697370617463682e202d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e202d20604f285329602e202d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e202d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f662020207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2e202d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602e202d20492f4f3a2031207265616420604f285329602c206f6e652072656d6f76652e202d2053746f726167653a2072656d6f766573206f6e65206974656d2e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a2033372e36202b20302e303834202a205320202020202d20526561643a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d20202020202d2057726974653a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d7531366f746865725f7369676e61746f7269657374696d65706f696e7454696d65706f696e743c543a3a426c6f636b4e756d6265723e63616c6c5f686173685b75383b2033325d20526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e7420696620617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e205061796d656e743a20604d756c74697369674465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c757320607468726573686f6c64602074696d657320604d756c74697369674465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f722069732063616e63656c6c65642e202d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e204966206974206973206e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2e204e4f54453a2049662074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2077616e7420746f20757365206061735f6d756c74696020696e73746561642e202d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292e202d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e202d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c207769746820612020206465706f7369742074616b656e20666f7220697473206c69666574696d65206f66202020604d756c74697369674465706f73697442617365202b207468726573686f6c64202a204d756c74697369674465706f736974466163746f72602e20202020202d204372656174653a2034342e3731202b20302e303838202a205320202020202d20417070726f76653a2033312e3438202b20302e313136202a20536d617962655f74696d65706f696e744f7074696f6e3c54696d65706f696e743c543a3a426c6f636b4e756d6265723e3e2049662074686572652061726520656e6f7567682c207468656e206469737061746368207468652063616c6c2e2043616c6c73206d75737420656163682066756c66696c207468652060497343616c6c61626c65602066696c7465722e202d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e204e4f54453a20556e6c6573732074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2067656e6572616c6c792077616e7420746f207573652060617070726f76655f61735f6d756c74696020696e73746561642c2073696e6365206974206f6e6c7920726571756972657320612068617368206f66207468652063616c6c2e20526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c7420696620607468726573686f6c64602069732065786163746c79206031602e204f7468657277697365206f6e20737563636573732c20726573756c7420697320604f6b6020616e642074686520726573756c742066726f6d2074686520696e746572696f722063616c6c2c206966206974207761732065786563757465642c206d617920626520666f756e6420696e20746865206465706f736974656420604d756c7469736967457865637574656460206576656e742e202d20604f2853202b205a202b2043616c6c29602e202d204f6e652063616c6c20656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285a296020776865726520605a602069732074782d6c656e2e202d2054686520776569676874206f6620746865206063616c6c602e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d20202020202d204372656174653a2034362e3535202b20302e303839202a205320c2b57320202020202d20417070726f76653a2033342e3033202b202e313132202a205320c2b57320202020202d20436f6d706c6574653a2034302e3336202b202e323235202a205320c2b57320202020202d2052656164733a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d20202020202d205772697465733a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d202d20506c75732043616c6c205765696768742053656e6420612063616c6c207468726f75676820616e20696e64657865642070736575646f6e796d206f66207468652073656e6465722e2043616c6c73206d75737420656163682066756c66696c207468652060497343616c6c61626c65602066696c7465722e202d2042617365207765696768743a20322e38363120c2b573202d20506c75732074686520776569676874206f6620746865206063616c6c602053656e642061206261746368206f662064697370617463682063616c6c732e20546869732077696c6c206578656375746520756e74696c20746865206669727374206f6e65206661696c7320616e64207468656e2073746f702e2043616c6c73206d7573742066756c66696c207468652060497343616c6c61626c65602066696c74657220756e6c65737320746865206f726967696e2069732060526f6f74602e204d61792062652063616c6c65642066726f6d20616e79206f726967696e2e202d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e202d2042617365207765696768743a2031342e3339202b202e393837202a206320c2b573202d20506c7573207468652073756d206f66207468652077656967687473206f6620746865206063616c6c73602e202d20506c7573206f6e65206164646974696f6e616c206576656e742e202872657065617420726561642f77726974652920546869732077696c6c2072657475726e20604f6b6020696e20616c6c2063697263756d7374616e6365732e20546f2064657465726d696e65207468652073756363657373206f66207468652062617463682c20616e206576656e74206973206465706f73697465642e20496620612063616c6c206661696c656420616e64207468652062617463682077617320696e7465727275707465642c207468656e2074686520604261746368496e74657272757074656460206576656e74206973206465706f73697465642c20616c6f6e67207769746820746865206e756d626572206f66207375636365737366756c2063616c6c73206d61646520616e6420746865206572726f72206f6620746865206661696c65642063616c6c2e20496620616c6c2077657265207375636365737366756c2c207468656e2074686520604261746368436f6d706c6574656460206576656e74206973206465706f73697465642e63616c6c735665633c3c542061732054726169743e3a3a43616c6c3e000000000000000cdc1000090000000205020000000000d0cf12000c000000000000008ad01000080000000000000015dc10003400000000000000001313004cdc100000000000000000005cdc10000100000000000000000000004d756c7469736967734d756c74697369673c543a3a426c6f636b4e756d6265722c2042616c616e63654f663c543e2c20543a3a4163636f756e7449643e0000001f00000000000000010000003800000064dc1000250000002054686520736574206f66206f70656e206d756c7469736967206f7065726174696f6e732e00000000000000183c110008000000000000003cdd10000200000000000000000000006cdd10001b000000000000000000000081b110000b0000000000000044de10000300000000000000000000008cde1000120000000000000000000000243c11000e000000000000001cdf100003000000000000000000000064df10000600000000000000000000008cb1100013000000000000003cdd100002000000000000000000000094df10000b00000000000000000000002c261100040000000000000087e412002300000000000000bef2120005000000000000002de210001300000060e4100036000000001313000000000096e4100042000000d8e410004800000020e510004500000065e510002d000000001313000000000092e5100046000000001313000000000091c212000b000000d8e510004c00000024e610003300000057e610005a0000000013130000000000b1e61000130000000013130000000000c4e610005400000018e710004b00000063e710003500000098e7100058000000f0e710005200000042e810003e00000080e8100022000000a2e8100051000000f3e81000370000002ae910004500000034c312000c0000000000000084e41200030000000000000087e4120023000000000000004ce4100008000000000000002de21000130000000000000054e410000c000000000000002de210001300000040e2100025000000001313000000000065e2100048000000ade2100042000000efe210004600000035e3100040000000001313000000000075e310002d000000001313000000000091c212000b000000a2e3100020000000c2e3100031000000b8071100160000003ea211000f000000f3e310001a0000000de410001900000026e410002600000034c312000c0000000000000027e21000060000000000000087e4120023000000000000002c261100040000000000000087e412002300000000000000bef2120005000000000000002de210001300000054e1100054000000a8e110000b00000091c212000b000000b3e110005000000003e210002400000034c312000c000000ecdf10005400000040e0100010000000001313000000000050e010002f00000000131300000000007fe010003100000091c212000b000000b0e010003a000000eae010001800000002e110004700000049e110000b0000002053616d6520617320746865205b607472616e73666572605d2063616c6c2c206275742077697468206120636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e20393925206f66207468652074696d6520796f752077616e74205b607472616e73666572605d20696e73746561642e205b607472616e73666572605d3a207374727563742e4d6f64756c652e68746d6c236d6574686f642e7472616e73666572202d2043686561706572207468616e207472616e736665722062656361757365206163636f756e742063616e6e6f74206265206b696c6c65642e202d2042617365205765696768743a2035312e3420c2b573202d204442205765696768743a2031205265616420616e64203120577269746520746f2064657374202873656e64657220697320696e206f7665726c617920616c72656164792920233c2f7765696768743e2045786163746c7920617320607472616e73666572602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74206d6179206265207370656369666965642e202d2053616d65206173207472616e736665722c20627574206164646974696f6e616c207265616420616e6420777269746520626563617573652074686520736f75726365206163636f756e742069732020206e6f7420617373756d656420746f20626520696e20746865206f7665726c61792e736f75726365436f6d706163743c543a3a42616c616e63653e20536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e63652028606672616d655f73797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e20202020202d204372656174696e673a2032372e353620c2b57320202020202d204b696c6c696e673a2033352e313120c2b573202d204442205765696768743a203120526561642c203120577269746520746f206077686f606e65775f667265656e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c20747269676765722060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e636564602e2020202d20607472616e736665725f6b6565705f616c6976656020776f726b73207468652073616d652077617920617320607472616e73666572602c206275742068617320616e206164646974696f6e616c2020202020636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a2037332e363420c2b5732c20776f7273742063617365207363656e6172696f20286163636f756e7420637265617465642c206163636f756e742072656d6f76656429202d204442205765696768743a2031205265616420616e64203120577269746520746f2064657374696e6174696f6e206163636f756e74202d204f726967696e206163636f756e7420697320616c726561647920696e206d656d6f72792c20736f206e6f204442206f7065726174696f6e7320666f72207468656d2e00000000009fb110000d0000000000000000000000d0ea10000a0000000000000000000000000000000000000000000000000000000000000000131300dcea10000000000000000000ecea10000100000000000000010000000000000039b31200070000000102000000000000d0cf12000c00000000000000f4ea10001700000000000000000000000000000000000000001313000ceb100000000000000000001ceb100006000000000000000100000000000000f8c81100050000000102000000000000d0cf12000c000000000000004ceb10001c000000000000000000000000000000000000000013130068eb1000000000000000000078eb10000200000000000000010000000000000010ca11000e00000000000000000000001eca110008000000000000000000000000000000000000000000000000000000000000000013130088eb1000000000000000000098eb1000030000000000000001000000543a3a42616c616e636500001f00000000000000010000003c00000040ed1000260000004163636f756e74446174613c543a3a42616c616e63653e001f0000000000000001000000470000004fec10001b00000000131300000000006aec100056000000c0ec1000300000000013130000000000f0ec1000500000005665633c42616c616e63654c6f636b3c543a3a42616c616e63653e3e1f000000000000000100000036000000d8eb10002e00000006ec1000490000001f00000000000000010000003700000050ca11001f0000000013130000000000b0eb10002800000020546869732069732073657420746f2076322e302e3020666f72206e6577206e6574776f726b732e20416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e204e4f54453a2053686f756c64206f6e6c79206265206163636573736564207768656e2073657474696e672c206368616e67696e6720616e642066726565696e672061206c6f636b2e205468652062616c616e6365206f6620616e206163636f756e742e204e4f54453a2054484953204d4159204e4556455220424520494e204558495354454e434520414e4420594554204841564520412060746f74616c28292e69735f7a65726f2829602e2049662074686520746f74616c2069732065766572207a65726f2c207468656e2074686520656e747279202a4d5553542a2062652072656d6f7665642e204e4f54453a2054686973206973206f6e6c79207573656420696e20746865206361736520746861742074686973206d6f64756c65206973207573656420746f2073746f72652062616c616e6365732e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e00000000000039b110001200000000000000d0ea10000a0000000000000000131300a0ed10000000000000000000b0ed100001000000000000001f000000000000000100000048000000b8ed10003500000020546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e000000ec0d130064000000700000002e000000ec0d1300640000008f00000034000000ec0d13006400000068000000340000006d6f646c70792f7574696c6973756261000000002bab10000d000000000000009cef10000100000000000000000000001cab10000f00000000000000a4ef10000100000000000000000000000bab10001100000000000000acef1000010000000000000000000000faaa10001100000000000000b4ef1000010000000000000000000000e8aa10001200000000000000bcef1000010000000000000000000000d3aa10001500000000000000c4ef1000010000000000000000000000c0aa10001300000000000000ccef1000010000000000000000000000b8aa10000800000000000000d4ef1000010000000000000000000000003c11000800000000000000dcef1000010000000000000000000000adaa10000b00000000000000e4ef10000100000000000000000000009faa10000e00000000000000ecef10000100000000000000000000008caa10001300000000000000f4ef100001000000000000000000000082aa10000a00000000000000d0ad1000010000000000000085f210001d00000059f210002c00000031f210002800000006f210002b000000daf110002c00000096f110004400000052f11000440000001af1100038000000cef010004c00000086f01000480000003af010004c000000fcef10003e00000020412074696d65706f696e742077617320676976656e2c20796574206e6f206d756c7469736967206f7065726174696f6e20697320756e6465727761792e204120646966666572656e742074696d65706f696e742077617320676976656e20746f20746865206d756c7469736967206f7065726174696f6e207468617420697320756e6465727761792e204e6f2074696d65706f696e742077617320676976656e2c2079657420746865206d756c7469736967206f7065726174696f6e20697320616c726561647920756e6465727761792e204f6e6c7920746865206163636f756e742074686174206f726967696e616c6c79206372656174656420746865206d756c74697369672069732061626c6520746f2063616e63656c2069742e204d756c7469736967206f7065726174696f6e206e6f7420666f756e64207768656e20617474656d7074696e6720746f2063616e63656c2e205468652073656e6465722077617320636f6e7461696e656420696e20746865206f74686572207369676e61746f726965733b2069742073686f756c646e27742062652e20546865207369676e61746f7269657320776572652070726f7669646564206f7574206f66206f726465723b20746865792073686f756c64206265206f7264657265642e2054686572652061726520746f6f206d616e79207369676e61746f7269657320696e20746865206c6973742e2054686572652061726520746f6f20666577207369676e61746f7269657320696e20746865206c6973742e2043616c6c20646f65736e2774206e65656420616e7920286d6f72652920617070726f76616c732e2043616c6c20697320616c726561647920617070726f7665642062792074686973207369676e61746f72792e205468726573686f6c6420697320746f6f206c6f7720287a65726f292e0000ec0d130064000000d300000011000000ec0d130064000000d8000000090000000000000073b110000e00000000000000a4f310000100000000000000000000005eb110001500000000000000acf31000010000000000000000000000834e11000800000000000000b4f310000100000000000000000000004bb110001300000000000000bcf3100001000000000000000000000039b110001200000000000000c4f3100001000000000000000000000030b110000900000000000000ccf31000010000000000000000000000a1d911001700000000000000d4f3100001000000000000000000000025b110000b00000000000000dcf31000010000000000000006f5100027000000d4f4100032000000b7f410001d00000099f410001e0000005ef410003b0000003af410002400000007f4100033000000e4f31000230000002042656e6566696369617279206163636f756e74206d757374207072652d657869737420412076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e74205472616e736665722f7061796d656e7420776f756c64206b696c6c206163636f756e742056616c756520746f6f206c6f7720746f20637265617465206163636f756e742064756520746f206578697374656e7469616c206465706f7369742042616c616e636520746f6f206c6f7720746f2073656e642076616c756520476f7420616e206f766572666c6f7720616674657220616464696e67204163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c2056657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c7565617474657374636c61696d5f6174746573746d696e745f636c61696d496e76616c6964457468657265756d5369676e61747572655369676e65724861734e6f436c61696d53656e6465724861734e6f436c61696d44657374696e6174696f6e56657374696e67506f74556e646572666c6f77496e76616c696453746174656d656e7450726576616c69646174654174746573747300000000000000f0f510000700000000000000f8f5100003000000000000000000000010f610000100000000000000436c61696d6564000eb512000900000033f610000f0000006b7212000700000018f610001b00000020536f6d656f6e6520636c61696d656420736f6d6520444f54732e457468657265756d416464726573737061726100000000000049f510001800000000000000f0f6100001000000000000000000000061f510001000000000000000f8f6100001000000000000000000000071f51000100000000000000000f7100001000000000000000000000081f51000120000000000000008f7100001000000000000000000000093f510000c0000000000000010f710000200000000000000000000009ff51000100000000000000020f71000010000000000000040f810001c00000021f810001f000000fdf7100024000000adf71000500000004df7100059000000a6f710000700000028f71000250000002041206e65656465642073746174656d656e7420776173206e6f7420696e636c756465642e2054686572652773206e6f7420656e6f75676820696e2074686520706f7420746f20706179206f757420736f6d6520756e76657374656420616d6f756e742e2047656e6572616c6c7920696d706c6965732061206c6f676963206572726f722e205468652064657374696e6174696f6e20697320616c72656164792076657374696e6720616e642063616e6e6f742062652074686520746172676574206f662061206675727468657220636c61696d2e204163636f756e742049442073656e64696e6720747820686173206e6f20636c61696d2e20457468657265756d206164647265737320686173206e6f20636c61696d2e20496e76616c696420457468657265756d207369676e61747572652e636c61696d7319457468657265756d205369676e6564204d6573736167653a0a507265636c61696d7300000000000000133c1100050000000000000038f9100002000000000000000000000068f910002600000000000000000000003ff510000a0000000000000098fa1000040000000000000000000000f8fa100017000000000000000000000033f510000c00000000000000b0fb1000030000000000000000000000f8fb10002900000000000000000000002df51000060000000000000040fd100001000000000000000000000058fd10001400000000000000000000002c2611000400000000000000d0cf12000c00000000000000240611001200000000000000360611000e000000870811002300000000131300000000001801110032000000001313000000000090fe100015000000aa0811004200000095011100200000000013130000000000b50111001b000000ec081100260000000013130000000000120911002a00000000131300000000002eff10000c0000008502110037000000bc021100440000000003110028000000001313000000000026e712000900000028031100400000006803110041000000a9031100110000003c091100420000007e09110047000000630411003d000000a004110028000000c804110029000000f10411003b0000002c05110015000000001313000000000094ff100017000000abff10001d000000c509110017000000deff10000b0000005805110057000000af05110057000000dc0911001e000000f0e812000a0000000000000084e41200030000000000000033f610000f00000000000000bef212000500000000000000a9f812000c000000000000002e08110010000000000000003e0811003400000000000000d50011000900000000000000720811001500000044061100220000000013130000000000614111003200000000131300000000002eff10000c000000660611003d000000a306110034000000d706110043000000001313000000000026e712000900000028031100400000001a0711003d00000057071100280000007f07110039000000001313000000000094ff100017000000b807110016000000ce07110017000000deff10000b000000e50711000f000000f4071100180000000c08110022000000f0e812000a000000000000002c2611000400000000000000d0cf12000c00000000000000240611001200000000000000360611000e00000000000000d5001100090000000000000059c9120007000000de0011003a00000000131300000000001801110032000000001313000000000090fe1000150000004a0111004b00000095011100200000000013130000000000b50111001b000000d00111003100000000131300000000000102110053000000540211003100000000131300000000002eff10000c0000008502110037000000bc0211004400000000031100280000003aff10005a000000001313000000000026e712000900000028031100400000006803110041000000a903110011000000ba03110041000000fb031100520000004d04110016000000630411003d000000a004110028000000c804110029000000f10411003b0000002c05110015000000001313000000000094ff100017000000abff10001d0000004105110017000000deff10000b0000005805110057000000af05110057000000060611001e000000f0e812000a00000000000000d5001100090000000000000059c9120007000000f8fd10003e000000001313000000000036fe10005a000000001313000000000090fe100015000000a5fe10004b000000f0fe10003e00000000131300000000002eff10000c0000003aff10005a000000001313000000000026e712000900000094ff100017000000abff10001d000000c8ff100016000000deff10000b000000e9ff1000620000004b00110062000000ad00110028000000f0e812000a0000002041747465737420746f20612073746174656d656e742c206e656564656420746f2066696e616c697a652074686520636c61696d732070726f636573732e205741524e494e473a20496e73656375726520756e6c65737320796f757220636861696e20696e636c75646573206050726576616c69646174654174746573747360206173206120605369676e6564457874656e73696f6e602e20556e7369676e65642056616c69646174696f6e3a20412063616c6c20746f20617474657374206973206465656d65642076616c6964206966207468652073656e6465722068617320612060507265636c61696d60207265676973746572656420616e642070726f76696465732061206073746174656d656e746020776869636820697320657870656374656420666f7220746865206163636f756e742e20506172616d65746572733a202d206073746174656d656e74603a20546865206964656e74697479206f66207468652073746174656d656e74207768696368206973206265696e6720617474657374656420746f20696e20746865207369676e61747572652e20546f74616c20436f6d706c65786974793a204f283129202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2042617365205765696768743a2039332e3320c2b573204442205765696768743a202d20526561643a20507265636c61696d732c205369676e696e672c20436c61696d732c20546f74616c2c20436c61696d732056657374696e672c2056657374696e672056657374696e672c2042616c616e6365204c6f636b2c204163636f756e74202d2057726974653a2056657374696e672056657374696e672c204163636f756e742c2042616c616e6365204c6f636b2c20546f74616c2c20436c61696d2c20436c61696d732056657374696e672c205369676e696e672c20507265636c61696d732056616c69646174652050726556616c6964617465417474657374733a202b382e36333120c2b57373746174656d656e74204d616b65206120636c61696d20746f20636f6c6c65637420796f757220444f5473206279207369676e696e6720612073746174656d656e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e20412063616c6c20746f2060636c61696d5f61747465737460206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d61746368657320746865206578706563746564207369676e6564206d657373616765206f663a203e20457468657265756d205369676e6564204d6573736167653a203e2028636f6e666967757265642070726566697820737472696e67292861646472657373292873746174656d656e742920616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e743b20746865206073746174656d656e7460206d757374206d617463682074686174207768696368206973206578706563746564206163636f7264696e6720746f20796f757220707572636861736520617272616e67656d656e742e202d206064657374603a205468652064657374696e6174696f6e206163636f756e7420746f207061796f75742074686520636c61696d2e202d2060657468657265756d5f7369676e6174757265603a20546865207369676e6174757265206f6620616e20657468657265756d207369676e6564206d657373616765202020206d61746368696e672074686520666f726d6174206465736372696265642061626f76652e2054686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732e202d204f6e6520606574685f7265636f76657260206f7065726174696f6e20776869636820696e766f6c7665732061206b656363616b206861736820616e6420612020206563647361207265636f7665722e202d20466f75722073746f7261676520726561647320746f20636865636b206966206120636c61696d2065786973747320666f722074686520757365722c20746f202020676574207468652063757272656e7420706f742073697a652c20746f207365652069662074686572652065786973747320612076657374696e67207363686564756c652c20746f206765742074686520202072657175697265642073746174656d656e742e202d20557020746f206f6e652073746f7261676520777269746520666f7220616464696e672061206e65772076657374696e67207363686564756c652e202d204f6e6520606465706f7369745f6372656174696e67602043757272656e63792063616c6c2e202d204f6e652073746f7261676520777269746520746f207570646174652074686520746f74616c2e202d2054776f2073746f726167652072656d6f76616c7320666f722076657374696e6720616e6420636c61696d7320696e666f726d6174696f6e2e202d204f6e65206465706f736974206576656e742e2042617365205765696768743a203237302e3220c2b573202d20526561643a205369676e696e672c20436c61696d732c20546f74616c2c20436c61696d732056657374696e672c2056657374696e672056657374696e672c2042616c616e6365204c6f636b2c204163636f756e74202d2057726974653a2056657374696e672056657374696e672c204163636f756e742c2042616c616e6365204c6f636b2c20546f74616c2c20436c61696d2c20436c61696d732056657374696e672c205369676e696e672056616c696461746520556e7369676e65643a202b3139302e3120c2b573657468657265756d5f7369676e617475726545636473615369676e6174757265204d696e742061206e657720636c61696d20746f20636f6c6c65637420444f54732e202d206077686f603a2054686520457468657265756d206164647265737320616c6c6f77656420746f20636f6c6c656374207468697320636c61696d2e202d206076616c7565603a20546865206e756d626572206f6620444f547320746861742077696c6c20626520636c61696d65642e202d206076657374696e675f7363686564756c65603a20416e206f7074696f6e616c2076657374696e67207363686564756c6520666f7220746865736520444f54732e202d204f6e652073746f72616765206d757461746520746f20696e6372656173652074686520746f74616c20636c61696d7320617661696c61626c652e202d204f6e652073746f7261676520777269746520746f206164642061206e657720636c61696d2e202d20557020746f206f6e652073746f7261676520777269746520746f206164642061206e65772076657374696e67207363686564756c652e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2042617365205765696768743a2031302e343620c2b573202d2052656164733a20546f74616c202d205772697465733a20546f74616c2c20436c61696d73202d204d617962652057726974653a2056657374696e672c2053746174656d656e7476657374696e675f7363686564756c654f7074696f6e3c2842616c616e63654f663c543e2c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d626572293e4f7074696f6e3c53746174656d656e744b696e643e204d616b65206120636c61696d20746f20636f6c6c65637420796f757220444f54732e20412063616c6c20746f20636c61696d206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d617463686573203e2028636f6e666967757265642070726566697820737472696e672928616464726573732920616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e742e202d2054687265652073746f7261676520726561647320746f20636865636b206966206120636c61696d2065786973747320666f722074686520757365722c20746f202020676574207468652063757272656e7420706f742073697a652c20746f207365652069662074686572652065786973747320612076657374696e67207363686564756c652e2042617365205765696768743a203236392e3720c2b5732056616c696461746520556e7369676e65643a202b3138382e3720c2b573000000000000c003130006000000010600000000000033f610000f00000000000000a9f812000c0000000000000000000000000000000000000000131300b40b110000000000000000000013130000000000000000000000000000000000c40b1100050000000000000000000000a9f812000c0000000000000000000000000000000000000000000000000000000000000000131300cc0b110000000000000000000013130000000000000000000100000000000000dfd9110007000000010600000000000033f610000f00000000000000dc0b11002c0000000000000000000000000000000000000000131300080c11000000000000000000180c110004000000000000000000000000000000c603130007000000010600000000000033f610000f00000000000000380c11000d0000000000000000000000000000000000000000131300480c11000000000000000000580c1100010000000000000000000000000000007cf81000090000000106000000000000d0cf12000c0000000000000033f610000f0000000000000000000000000000000000000000131300600c11000000000000000000700c11000100000000000000000000001f000000000000000100000038000000546f74616c0000001f00000000000000010000003c0000002842616c616e63654f663c543e2c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d626572291f000000000000000100000038000000f30c11001e000000110d110043000000540d1100390000008d0d11003300000053746174656d656e744b696e640000001f000000000000000100000038000000c30c1100300000001f000000000000000100000038000000780c11004b000000205072652d636c61696d656420457468657265756d206163636f756e74732c20627920746865204163636f756e74204944207468617420746865792061726520636c61696d656420746f2e205468652073746174656d656e74206b696e642074686174206d757374206265207369676e65642c20696620616e792e2056657374696e67207363686564756c6520666f72206120636c61696d2e2046697273742062616c616e63652069732074686520746f74616c20616d6f756e7420746861742073686f756c642062652068656c6420666f722076657374696e672e205365636f6e642062616c616e636520697320686f77206d7563682073686f756c6420626520756e6c6f636b65642070657220626c6f636b2e2054686520626c6f636b206e756d626572206973207768656e207468652076657374696e672073686f756c642073746172742e00000000f80d11000600000000000000fe0d1100050000000000000000131300040e11000000000000000000140e11000100000000000000507265666978265b75385d001f0000000000000001000000490000001c0e11004500000020546865205072656669782074686174206973207573656420696e207369676e656420457468657265756d206d6573736167657320666f722074686973206e6574776f726b656c61626f726174655f6465706c6f795f646174616669785f6465706c6f795f646174617365745f6f6666626f617264696e676269645f72656e65776269646e65775f61756374696f6e41756374696f6e496e50726f67726573734c65617365506572696f64496e506173744e6f74506172614f726967696e506172614e6f744f6e626f617264696e67496e76616c69644f726967696e416c726561647952656769737465726564496e76616c6964436f6465556e7365744465706c6f79446174614e6f6e496e74657273656374696e6752616e67654e6f7443757272656e7441756374696f6e4e6f7441756374696f6e63616e2774207377617020616e20756e6465706c6f7965642070617261636861696e56616c696461746545717569766f636174696f6e5265706f7274417574686f724f6c64556e636c65556e636c65416c7265616479496e636c75646564546f6f48696768556e636c6547656e65736973556e636c65546f6f4d616e79556e636c6573556e636c6573416c7265616479536574496e76616c6964556e636c65506172656e747365745f756e636c65734f6e626f617264696e670000000000401111000e000000000000005011110001000000000000000000000058111100010000000000000000000000601111000e000000000000007011110003000000000000000000000088111100020000000000000000000000981111000d00000000000000a8111100010000000000000000000000b0111100010000000000000000000000b81111000900000000000000c4111100040000000000000000000000e4111100010000000000000000000000ec1111000a00000000000000f8111100040000000000000000000000181211000200000000000000000000002812110008000000000000003012110003000000000000000000000048121100020000000000000000000000581211000a0000000000000050da11000200000000000000000000006412110001000000000000004e65774c65617365506572696f640000d31411000b000000de1411002100000041756374696f6e5374617274656400002e1411000c000000d31411000b000000e31012000b0000003a141100530000008d1411004600000041756374696f6e436c6f7365640000002e1411000c000000ff1311002f000000576f6e4465706c6f79000000eb131100140000008d131100090000002a051300060000006b721200070000009613110055000000576f6e52656e6577616c00002a051300060000008d131100090000006b721200070000006b721200070000000c131100310000003d1311005000000052657365727665640eb51200090000006b721200070000006b72120007000000a412110053000000f712110015000000556e726573657276656400006c121100380000002046756e6473207765726520756e72657365727665642073696e636520626964646572206973206e6f206c6f6e676572206163746976652e2046756e6473207765726520726573657276656420666f7220612077696e6e696e67206269642e2046697273742062616c616e63652069732074686520657874726120616d6f756e742072657365727665642e205365636f6e642069732074686520746f74616c2e20416e206578697374696e672070617261636861696e20776f6e2074686520726967687420746f20636f6e74696e75652e2046697273742062616c616e63652069732074686520657874726120616d6f756e7420726573657665642e205365636f6e642069732074686520746f74616c20616d6f756e742072657365727665642e536c6f7452616e676520536f6d656f6e6520776f6e2074686520726967687420746f206465706c6f7920612070617261636861696e2e2042616c616e636520616d6f756e7420697320646564756374656420666f72206465706f7369742e4e65774269646465723c4163636f756e7449643e20416e2061756374696f6e20656e6465642e20416c6c2066756e6473206265636f6d6520756e72657365727665642e41756374696f6e496e64657820416e2061756374696f6e20737461727465642e2050726f76696465732069747320696e64657820616e642074686520626c6f636b206e756d6265722077686572652069742077696c6c20626567696e20746f20636c6f736520616e6420746865206669727374206c6561736520706572696f64206f662074686520717561647275706c657420746861742069732061756374696f6e65642e4c65617365506572696f642041206e6577206c6561736520706572696f6420697320626567696e6e696e672e00617474656d707420746f20646976696465206279207a65726f00000000000000ab0e1100110000000000000088161100010000000000000000000000bc0e1100110000000000000090161100010000000000000000000000cd0e11000d0000000000000098161100010000000000000000000000da0e11001100000000000000a0161100010000000000000000000000eb0e11000d00000000000000a8161100010000000000000000000000f80e11001100000000000000b0161100010000000000000000000000090f11000b00000000000000b8161100010000000000000000000000140f11000f00000000000000c0161100010000000000000000000000230f11001400000000000000c8161100010000000000000000000000370f11001100000000000000d0161100010000000000000000000000480f11000a00000000000000d8161100010000000000000000000000e12912000c00000000000000e0161100010000000000000000000000ed2912001000000000000000e81611000100000000000000c218110025000000a118110021000000731811002e0000004f18110024000000051811004a000000e417110021000000be1711002600000089171100350000005b1711002e00000044171100170000003417110010000000161711001e000000f01611002600000020476976656e20696e697469616c2068656164206461746120697320746f6f206c617267652e20476976656e20636f64652073697a6520697320746f6f206c617267652e204e6f7420616e2061756374696f6e2e204e6f7420612063757272656e742061756374696f6e2e2054686520626964206d757374206f7665726c617020616c6c20696e74657273656374696e672072616e6765732e204465706c6f796d656e74206461746120686173206e6f74206265656e2073657420666f7220746869732070617261636861696e2e2054686520636f6465206d75737420636f72726573706f6e6420746f2074686520686173682e2050617261636861696e20697320616c726561647920726567697374657265642e20546865206f726967696e20666f7220746869732063616c6c206d75737420626520746865206f726967696e2077686f2072656769737465726564207468652070617261636861696e2e205468652070617261636861696e204944206973206e6f74206f6e626f617264696e672e20546865206f726967696e20666f7220746869732063616c6c206d75737420626520612070617261636861696e2e20546865206c6561736520706572696f6420697320696e2074686520706173742e20546869732061756374696f6e20697320616c726561647920696e2070726f67726573732e4465706f736974734f6666626f617264696e6741756374696f6e496e666f57696e6e696e67556e636c657300001f00000008000000040000004a0000006069203c2034603b20606a203c2069603b20606a202b2031203c2034603b20716564000064b11200340000004c0300001d00000060191100290000006561726c69657220726573697a65206d65616e73206974206d757374206265203e3d20693b207165644f6e626f61726451756575655265736572766564416d6f756e747300000000f70f11000a00000000000000d0191100010000000000000000000000e8191100010000000000000000000000091a11000a00000000000000131a11000e000000f0191100190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e000000000000000c1911000600000000000000000000002c1b11003a0000000000000000000000000000000000000000000000000000000000000000131300681b11000000000000000000781b1100010000000000000001000000000000008e0f1100060000000000000000000000d0cf12000c0000000000000000000000000000000000000000000000000000000000000000131300801b11000000000000000000901b110001000000000000000000000000000000981b11000c00000000000000000000000fb91200040000000000000000000000000000000000000000000000000000000000000000131300a41b11000000000000000000b41b11000100000000000000010000005665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e00001f000000000000000100000036000000041c1100070000001f000000000000000100000038000000eb1b110019000000446964536574556e636c65731f000000000000000100000038000000bc1b11002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c657300ac1c110001000000d51c110028000000ac1c110001000000ad1c11002800000070616c6c65745f6772616e6470613a3a65717569766f636174696f6e2f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f6772616e6470612f7372632f65717569766f636174696f6e2e72735b5d204572726f72207375626d697474696e672065717569766f636174696f6e207265706f72743a205d205375626d6974746564204752414e4450412065717569766f636174696f6e207265706f72742e00000000000000a00e11000b00000000000000081e1100020000000000000000000000381e11000500000000000000000000009d0e11000300000000000000601e1100050000000000000000000000d81e1100100000000000000000000000940e11000900000000000000581f1100040000000000000000000000b81f11000f0000000000000000000000850e11000f000000000000003020110001000000000000000000000048201100050000000000000000000000760e11000f0000000000000070201100050000000000000000000000e8201100070000000000000000000000610e1100150000000000000020211100020000000000000000000000502111000c0000000000000000000000382b11000800000000000000741e12001700000000000000402b1100120000000000000033291100190000002c2a1100160000000013130000000000422a110055000000972a11004a000000e12a11005700000000000000652511000300000000000000682511000e00000000000000072911000d00000000000000142911001500000000000000292911000a000000000000003329110019000000000000004c2911000900000000000000332911001900000000000000552911000600000000000000c3f21200150000005b29110053000000ae2911000b00000000131300000000008426110057000000db261100500000000013130000000000b9291100560000000f2a11001d0000002b271100540000007f2711001b0000009a27110053000000ed271100430000003028110051000000ed271100430000008128110053000000d42811003300000000000000072911000d00000000000000142911001500000000000000292911000a000000000000003329110019000000000000004c2911000900000000000000332911001900000000000000552911000600000000000000c3f212001500000030261100540000000013130000000000ba2511002a00000000131300000000008426110057000000db2611005000000000131300000000002b271100540000007f2711001b0000009a27110053000000ed271100430000003028110051000000ed271100430000008128110053000000d428110033000000000000002c261100040000000000000087e412002300000088251100320000000013130000000000ba2511002a0000000013130000000000e42511004800000000000000652511000300000000000000682511000e00000000000000f223110007000000000000007e5a12000f000000000000007625110009000000000000009ed0120007000000000000007f2511000900000000000000c2c4120003000000000000005b5e120011000000000000006c5e120008000000f92311004b00000000131300000000004424110032000000762411002c000000a224110040000000e224110047000000292511003c00000000000000f223110007000000000000007e5a12000f0000000000000055c9120004000000000000004d5e12000e000000b02111001d0000000013130000000000cd21110053000000202211003100000000131300000000005122110058000000a922110051000000fa221100590000000013130000000000532311001b0000006e2311003f000000ad23110045000000204e6f74652061206e65772070617261636861696e277320636f64652e2054686973206d7573742062652063616c6c656420616674657220606669785f6465706c6f795f646174616020616e642060636f646560206d7573742062652074686520707265696d616765206f66207468652060636f64655f68617368602070617373656420746865726520666f72207468652073616d652060706172615f6964602e2054686973206d61792062652063616c6c6564206265666f7265206f722061667465722074686520626567696e6e696e67206f66207468652070617261636861696e2773206669727374206c6561736520706572696f642e2049662063616c6c6564206265666f7265207468656e207468652070617261636861696e2077696c6c206265636f6d65206163746976652061742074686520666972737420626c6f636b206f6620697473207374617274696e67206c6561736520706572696f642e2049662061667465722c207468656e2069742077696c6c206265636f6d652061637469766520696d6d6564696174656c7920616674657220746869732063616c6c2e202d20605f6f726967696e6020697320697272656c6576616e742e202d2060706172615f696460206973207468652070617261636861696e2049442077686f736520636f64652077696c6c20626520656c61626f72617465642e202d2060636f6465602069732074686520707265696d616765206f662074686520726567697374657265642060636f64655f6861736860206f662060706172615f6964602e706172615f69642053657420746865206465706c6f7920696e666f726d6174696f6e20666f722061207375636365737366756c2062696420746f206465706c6f792061206e65772070617261636861696e2e202d20606f726967696e60206d75737420626520746865207375636365737366756c20626964646572206163636f756e742e202d20607375626020697320746865207375622d626964646572204944206f6620746865206269646465722e202d2060706172615f696460206973207468652070617261636861696e20494420616c6c6f7474656420746f207468652077696e6e696e67206269646465722e202d2060636f64655f6861736860206973207468652068617368206f66207468652070617261636861696e2773205761736d2076616c69646174696f6e2066756e6374696f6e2e202d2060696e697469616c5f686561645f6461746160206973207468652070617261636861696e277320696e697469616c206865616420646174612e737562436f6d706163743c53756249643e636f64655f68617368636f64655f73697a652053657420746865206f66662d626f617264696e6720696e666f726d6174696f6e20666f7220612070617261636861696e2e20546865206f726967696e202a6d7573742a20626520612070617261636861696e206163636f756e742e202d20606465737460206973207468652064657374696e6174696f6e206163636f756e7420746f2072656365697665207468652070617261636861696e2773206465706f7369742e64657374204d616b652061206e6577206269642066726f6d20612070617261636861696e206163636f756e7420666f722072656e6577696e67207468617420287072652d6578697374696e67292070617261636861696e2e204d756c7469706c652073696d756c74616e656f757320626964732066726f6d207468652073616d65206269646465722061726520616c6c6f776564206f6e6c79206173206c6f6e6720617320616c6c206163746976652062696473206f7665726c61702065616368206f746865722028692e652e20617265206d757475616c6c79206578636c7573697665292e20426964732063616e6e6f742062652072656461637465642e202d206061756374696f6e5f696e646578602069732074686520696e646578206f66207468652061756374696f6e20746f20626964206f6e2e2053686f756c64206a757374206265207468652070726573656e742076616c7565206f66206041756374696f6e436f756e746572602e202d206066697273745f736c6f746020697320746865206669727374206c6561736520706572696f6420696e646578206f66207468652072616e676520746f20626964206f6e2e205468697320697320746865206162736f6c757465206c6561736520706572696f6420696e6465782076616c75652c206e6f7420616e2061756374696f6e2d7370656369666963206f66667365742e202d20606c6173745f736c6f746020697320746865206c617374206c6561736520706572696f6420696e646578206f66207468652072616e676520746f20626964206f6e2e205468697320697320746865202d2060616d6f756e74602069732074686520616d6f756e7420746f2062696420746f2062652068656c64206173206465706f73697420666f72207468652070617261636861696e2073686f756c6420746865206269642077696e2e205468697320616d6f756e742069732068656c64207468726f7567686f7574207468652072616e67652e61756374696f6e5f696e646578436f6d706163743c41756374696f6e496e6465783e66697273745f736c6f74436f6d706163743c4c65617365506572696f644f663c543e3e6c6173745f736c6f74616d6f756e74204d616b652061206e6577206269642066726f6d20616e206163636f756e742028696e636c7564696e6720612070617261636861696e206163636f756e742920666f72206465706c6f79696e672061206e65772070617261636861696e2e202d20607375626020697320746865207375622d6269646465722049442c20616c6c6f77696e6720666f72206d756c7469706c6520636f6d706574696e67206269647320746f206265206d6164652062792028616e642066756e64656420627929207468652073616d65206163636f756e742e204372656174652061206e65772061756374696f6e2e20546869732063616e206f6e6c792068617070656e207768656e2074686572652069736e277420616c726561647920616e2061756374696f6e20696e2070726f677265737320616e64206d6179206f6e6c792062652063616c6c65642062792074686520726f6f74206f726967696e2e20416363657074732074686520606475726174696f6e60206f6620746869732061756374696f6e20616e642074686520606c656173655f706572696f645f696e64657860206f662074686520696e697469616c206c6561736520706572696f64206f662074686520666f757220746861742061726520746f2062652061756374696f6e65642e6475726174696f6e6c656173655f706572696f645f696e646578000000000000590113000e00000000000000000000002e1411000c00000000000000000000000000000000000000000000000000000000000000001313006c2e110000000000000000007c2e110001000000000000000100000000000000670113000a00000000000000000000002c6312000b0000000000000000000000000000000000000000000000000000000000000000131300f82f11000000000000000000842e110002000000000000000100000000000000e71811000800000001050000000000002a0513000600000000000000942e1100110000000000000000000000000000000000000000131300a82e11000000000000000000b82e11000d000000000000000100000000000000fa1811000b0000000000000000000000202f1100220000000000000000000000000000000000000000000000000000000000000000131300442f11000000000000000000542f1100050000000000000000000000000000000519110007000000010500000000000090d012000e000000000000007c2f11000e00000000000000000000000000000000000000001313008c2f110000000000000000009c2f110003000000000000000000000000000000951911000f0000000105000000000000b42f11001400000000000000a9f812000c0000000000000000000000000000000000000000131300c82f11000000000000000000d82f110002000000000000000000000000000000891911000c0000000105000000000000e82f110010000000000000002c6312000b0000000000000000000000000000000000000000131300f82f110000000000000000000830110002000000000000000100000000000000011011000a00000001050000000000002a0513000600000000000000183011003c00000000000000000000000000000000000000001313005430110000000000000000006430110004000000000000000000000000000000ef1811000b00000001050000000000002a0513000600000000000000d0cf12000c0000000000000000000000000000000000000000131300843011000000000000000000943011000200000000000000010000001f000000000000000100000034000000db381100360000003e38110053000000913811004a0000005665633c42616c616e63654f663c543e3e0000001f0000000000000001000000360000007335110057000000ca351100140000000013130000000000de3511005900000037361100540000008b3611002c0000000013130000000000b7361100580000000f3711002d00000000131300000000003c371100540000009037110057000000e737110057000000284c65617365506572696f644f663c543e2c20543a3a426c6f636b4e756d6265722900001f00000000000000010000004b000000393411003e00000000131300000000007734110051000000c8341100540000001c3511005700000057696e6e696e67446174613c543e00001f00000000000000010000004c00000047331100570000009e33110054000000f2331100470000004269646465723c543a3a4163636f756e7449643e1f000000000000000100000038000000ed3211004c000000393311000e0000004c65617365506572696f644f663c543e1f0000000000000001000000360000005832110059000000b13211003c000000284c65617365506572696f644f663c543e2c20496e636f6d696e6750617261636861696e3c543a3a4163636f756e7449642c20543a3a486173683e291f00000000000000010000004d0000004b311100530000009e31110049000000e7311100560000003d3211001b0000001f00000000000000010000004e000000a430110059000000fd3011004e000000204f66662d626f617264696e67206163636f756e743b2063757272656e63792068656c64206f6e206465706f73697420666f72207468652070617261636861696e206765747320706c616365642068657265206966207468652070617261636861696e2067657473206f66662d626f61726465643b20692e652e20697473206c6561736520706572696f6420697320757020616e642069742069736e27742072656e657765642e205468652061637475616c206f6e2d626f617264696e6720696e666f726d6174696f6e2e204f6e6c7920657869737473207768656e206f6e65206f662074686520666f6c6c6f77696e6720697320747275653a202d204974206973206265666f726520746865206c6561736520706572696f642074686174207468652070617261636861696e2073686f756c64206265206f6e2d626f61726465642e202d205468652066756c6c206f6e2d626f617264696e6720696e666f726d6174696f6e20686173206e6f7420796574206265656e2070726f766964656420616e64207468652070617261636861696e206973206e6f74207965742064756520746f206265206f66662d626f61726465642e2054686520736574206f662050617261204944732074686174206861766520776f6e20616e64206e65656420746f206265206f6e2d626f617264656420617420616e207570636f6d696e67206c656173652d706572696f642e205468697320697320636c6561726564206f7574206f6e2074686520666972737420626c6f636b206f6620746865206c6561736520706572696f642e20416d6f756e74732063757272656e746c7920726573657276656420696e20746865206163636f756e7473206f662074686520626964646572732063757272656e746c792077696e6e696e6720287375622d2972616e6765732e205468652077696e6e696e67206269647320666f722065616368206f66207468652031302072616e676573206174206561636820626c6f636b20696e207468652066696e616c20456e64696e6720506572696f64206f66207468652063757272656e742061756374696f6e2e20546865206d61702773206b65792069732074686520302d626173656420696e64657820696e746f2074686520456e64696e6720506572696f642e2054686520666972737420626c6f636b206f662074686520656e64696e6720706572696f6420697320303b20746865206c6173742069732060456e64696e67506572696f64202d2031602e20496e666f726d6174696f6e2072656c6174696e6720746f207468652063757272656e742061756374696f6e2c206966207468657265206973206f6e652e20546865206669727374206974656d20696e20746865207475706c6520697320746865206c6561736520706572696f6420696e646578207468617420746865206669727374206f662074686520666f757220636f6e746967756f7573206c6561736520706572696f6473206f6e2061756374696f6e20697320666f722e20546865207365636f6e642069732074686520626c6f636b206e756d626572207768656e207468652061756374696f6e2077696c6c2022626567696e20746f20656e64222c20692e652e2074686520666972737420626c6f636b206f662074686520456e64696e6720506572696f64206f66207468652061756374696f6e2e20566172696f757320616d6f756e7473206f6e206465706f73697420666f7220656163682070617261636861696e2e20416e20656e74727920696e20604d616e616765644964736020696d706c6965732061206e6f6e2d2064656661756c7420656e74727920686572652e205468652061637475616c20616d6f756e74206c6f636b6564206f6e2069747320626568616c6620617420616e792074696d6520697320746865206d6178696d756d206974656d20696e2074686973206c6973742e20546865206669727374206974656d20696e20746865206c6973742069732074686520616d6f756e74206c6f636b656420666f72207468652063757272656e74204c6561736520506572696f642e20466f6c6c6f77696e67206974656d732061726520666f72207468652073756273657175656e74206c6561736520706572696f64732e205468652064656661756c742076616c75652028616e20656d707479206c6973742920696d706c6965732074686174207468652070617261636861696e206e6f206c6f6e6765722065786973747320286f72206e65766572206578697374656429206173206661722061732074686973206d6f64756c6520697320636f6e6365726e65642e20496620612070617261636861696e20646f65736e2774206578697374202a7965742a20627574206973207363686564756c656420746f20657869737420696e20746865206675747572652c207468656e2069742077696c6c206265206c6566742d7061646465642077697468206f6e65206f72206d6f7265207a65726f657320746f2064656e6f74652074686520666163742074686174206e6f7468696e672069732068656c64206f6e206465706f73697420666f7220746865206e6f6e2d6578697374656e7420636861696e2063757272656e746c792c206275742069732068656c6420617420736f6d6520706f696e7420696e20746865206675747572652e204f726465726564206c697374206f6620616c6c2060506172614964602076616c756573207468617420617265206d616e616765642062792074686973206d6f64756c652e205468697320696e636c7564657320636861696e73207468617420617265206e6f7420796574206465706c6f7965642028627574206861766520776f6e20616e2061756374696f6e20696e2074686520667574757265292e20546865206e756d626572206f662061756374696f6e7320746861742068617665206265656e207374617274656420736f206661722e00000000131300000000001de611000200000000000000e50f11001200000000000000e8391100010000000000000000000000d50f11001000000000000000f0391100010000000000000000000000c80f11000d00000000000000f8391100010000000000000000000000bc0f11000c00000000000000003a1100010000000000000000000000b00f11000c00000000000000083a11000100000000000000000000009c0f11001400000000000000103a1100010000000000000000000000940f11000800000000000000183a11000100000000000000d53a110023000000b43a110021000000a33a1100110000008d3a1100160000006d3a1100200000004e3a11001f000000203a11002e0000002054686520756e636c652069736e277420726563656e7420656e6f75676820746f20626520696e636c756465642e2054686520756e636c6520697320616c726561647920696e636c756465642e2054686520756e636c6520697320746f6f206869676820696e20636861696e2e2054686520756e636c652069732067656e657369732e20546f6f206d616e7920756e636c65732e20556e636c657320616c72656164792073657420696e2074686520626c6f636b2e2054686520756e636c6520706172656e74206e6f7420696e2074686520636861696e2e61727261792068617320534c4f545f52414e47455f434f554e54206974656d733b20696e646578206e65766572207265616368657320746861742076616c75653b207165640000001f00000000000000010000004f00000064b1120034000000fd02000036000000703b110055000000480600001b0000002f72757374632f323435346136386366626236336161376238653039666530353131346435663938623266393734302f7372632f6c6962616c6c6f632f636f6c6c656374696f6e732f62747265652f6d61702e727354696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b4e6f745472616e73666572496e5573654e6f744f776e65724e6f7441737369676e6564636c61696d7472616e7366657266726565666f7263655f7472616e736665720000000000008c3c11000d000000000000009c3c1100020000000000000000000000ac3c1100010000000000000000000000b43c11000a00000000000000c03c1100010000000000000000000000c83c11000100000000000000496e64657841737369676e65640000000eb5120009000000003d11000c0000000c3d11001e000000496e64657846726565640000003d11000c000000d03c1100300000002041206163636f756e7420696e64657820686173206265656e2066726565642075702028756e61737369676e6564292e4163636f756e74496e6465782041206163636f756e7420696e646578207761732061737369676e65642e4e6f77736574500000001000000004000000510000004765747320616e64206465636f6465732074696d657374616d7020696e686572656e742064617461783d11005d000000e90000001f0000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f74696d657374616d702f7372632f6c69622e727300000000000000133c11000500000000000000883e1100010000000000000000000000a03e1100100000000000000000000000183c11000800000000000000203f1100020000000000000000000000503f1100100000000000000000000000203c11000400000000000000883e1100010000000000000000000000d03f1100100000000000000000000000243c11000e00000000000000203f1100020000000000000000000000504011001000000000000000000000008b4612000500000000000000cb4411000f000000da44110027000000001313000000000001451100380000000013130000000000948c1200340000000013130000000000394511003d00000000131300000000001542110025000000001313000000000091c212000b00000010f111000a0000003a42110027000000c743110019000000804211000d00000034c312000c0000000000000025a912000300000000000000d0cf12000c000000000000008b4612000500000000000000cb4411000f000000e043110058000000384411002f0000000013130000000000948c1200340000000013130000000000674411004a000000bd4111005800000000131300000000001542110025000000001313000000000091c212000b00000010f111000a0000003a42110027000000b14411001a000000804211000d00000034c312000c0000008d421100260000000013130000000000b34211005800000000131300000000000b43110056000000001313000000000061431100440000000013130000000000a543110022000000001313000000000091c212000b00000010f111000a0000003a42110027000000c743110019000000804211000d00000034c312000c000000d040110056000000264111003b000000001313000000000061411100320000000013130000000000934111002a000000bd4111005800000000131300000000001542110025000000001313000000000091c212000b00000010f111000a0000003a42110027000000614211001f000000804211000d00000034c312000c00000020466f72636520616e20696e64657820746f20616e206163636f756e742e205468697320646f65736e277420726571756972652061206465706f7369742e2049662074686520696e64657820697320616c72656164792068656c642c207468656e20616e79206465706f736974206973207265696d62757273656420746f206974732063757272656e74206f776e65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e202d2060696e646578603a2074686520696e64657820746f206265202872652d2961737369676e65642e202d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e20456d6974732060496e64657841737369676e656460206966207375636365737366756c2e202d204f6e652073746f72616765206d75746174696f6e2028636f64656320604f28312960292e202d20557020746f206f6e652072657365727665206f7065726174696f6e2e202d204f6e65206576656e742e204672656520757020616e20696e646578206f776e6564206279207468652073656e6465722e205061796d656e743a20416e792070726576696f7573206465706f73697420706c6163656420666f722074686520696e64657820697320756e726573657276656420696e207468652073656e646572206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206f776e2074686520696e6465782e202d2060696e646578603a2074686520696e64657820746f2062652066726565642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e20456d6974732060496e646578467265656460206966207375636365737366756c2e202d204f6e652072657365727665206f7065726174696f6e2e2041737369676e20616e20696e64657820616c7265616479206f776e6564206279207468652073656e64657220746f20616e6f74686572206163636f756e742e205468652062616c616e6365207265736572766174696f6e206973206566666563746976656c79207472616e7366657272656420746f20746865206e6577206163636f756e742e202d2060696e646578603a2074686520696e64657820746f2062652072652d61737369676e65642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e202d204f6e65207472616e73666572206f7065726174696f6e2e543a3a4163636f756e74496e6465782041737369676e20616e2070726576696f75736c7920756e61737369676e656420696e6465782e205061796d656e743a20604465706f736974602069732072657365727665642066726f6d207468652073656e646572206163636f756e742e202d2060696e646578603a2074686520696e64657820746f20626520636c61696d65642e2054686973206d757374206e6f7420626520696e207573652e000000000000d0451100080000000102000000000000cb4411000f00000000000000d84511001c0000000000000000000000000000000000000000131300f44511000000000000000000044611000100000000000000000000004163636f756e747328543a3a4163636f756e7449642c2042616c616e63654f663c543e291f0000000000000001000000380000000c4611002200000020546865206c6f6f6b75702066726f6d20696e64657820746f206163636f756e742e0000000000002d3d110003000000000000005c46110001000000000000000000000074461100120000000000000000000000ca4911000300000000000000cd49110012000000044711001600000000131300000000001a4711005600000070471100360000000013130000000000a647110051000000f74711001100000000131300000000000848110036000000001313000000000091c212000b0000003e481100340000007248110068000000da4811002d000000074911002a0000003149110060000000914911003900000034c312000c00000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e202d20604f285429602077686572652060546020636f6d706c6578697479206f6620606f6e5f74696d657374616d705f73657460202d20312073746f72616765207265616420616e6420312073746f72616765206d75746174696f6e2028636f64656320604f28312960292e202862656361757365206f6620604469645570646174653a3a74616b656020696e20606f6e5f66696e616c697a656029202d2031206576656e742068616e646c657220606f6e5f74696d657374616d705f7365746020604f285429602e202d2042656e63686d61726b3a20372e36373820286d696e207371756172657320616e616c79736973292020202d204e4f54453a20546869732062656e63686d61726b2077617320646f6e6520666f7220612072756e74696d65207769746820696e7369676e69666963616e7420606f6e5f74696d657374616d705f736574602068616e646c6572732e20202020204e65772062656e63686d61726b696e67206973206e6565646564207768656e20616464696e67206e65772068616e646c6572732e6e6f77436f6d706163743c543a3a4d6f6d656e743e00000000002a3d1100030000000000000000000000904a11000900000000000000000000000000000000000000000000000000000000000000001313009c4a11000000000000000000ac4a1100010000000000000001000000000000002c0213000900000000000000000000000fb91200040000000000000000000000000000000000000000000000000000000000000000131300b44a11000000000000000000c44a1100010000000000000001000000543a3a4d6f6d656e740000001f000000000000000100000042000000f94a1100240000001f000000000000000100000038000000cc4a11002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e00000000000000584b11000d00000000000000904a1100090000000000000000131300684b11000000000000000000784b110004000000000000004d696e696d756d506572696f640000001f000000000000000100000052000000984b11005a000000f24b11005a0000004c4c110059000000a54c11001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e0000000c4d110049000000920200001a0000000c4d110049000000a3010000270000000100000001000000000000000000000000000000010000000c4d1100490000008e0200001d0000002f72757374632f323435346136386366626236336161376238653039666530353131346435663938623266393734302f7372632f6c6962636f72652f736c6963652f736f72742e72730000000c4d110049000000a1000000300000000c4d110049000000a40000003000000054696d657374616d7020746f6f2066617220696e2066757475726520746f2061636365707454696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b54696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b734d6178566f7465735265616368656457726f6e675570706572426f756e644e6f6e73656e7365496e7374616e744e6f74416c6c6f776564566f74657345786973744e6f7444656c65676174696e67496e73756666696369656e7446756e6473556e646572666c6f774f766572666c6f77416c726561647944656c65676174696e674e6f5065726d697373696f6e4e6f74566f7465724e6f7441637469766557726f6e674f70656e4e6f744f70656e4e6f74457870697265644e6f744c6f636b65644e6f6e6557616974696e67507265696d616765496e76616c69645265666572656e64756d496e76616c6964507265696d6167654d697373696e67496d6d696e656e744e6f74496d6d696e656e744475706c6963617465507265696d6167654e6f7444656c65676174656457726f6e6750726f7879416c726561647950726f7879416c72656164795665746f65644e6f50726f706f73616c496e76616c6964486173684e6f7453696d706c654d616a6f7269747950726f706f73616c426c61636b6c6973746564416c726561647943616e63656c6564426164496e6465784e6f7450726f787956616c75654c6f7744656d6f63726163794465706f7369744f665265666572656e64756d496e666f4f6600000000002c501100080000000000000000000000345011000f0000000000000000000000000000000000000000000000445011000c0000000000000000000000706f6c6b61646f747061726974792d706f6c6b61646f7400df6acb689907609b0300000037e397fc7c91f5e40100000040fe3ad401f8959a04000000d2bc9897eed08f1502000000f78b278be53f454c02000000af2c0297a23e6d3d03000000ed99c5acb25eedf502000000cbca25e39f14238702000000687ad44ad37f03c201000000ab3c0572291feb8b01000000bc9d89904f5b923f0100000037c8bb1350a9a2a8010000006772616e62616265696d6f6e70617261617564690000000040787d010065cd1d00e1f505d85aae1ec0542205b0508f1f38e4750488467020d853e903603c5121d0bf760338323222a8591903402013236039cd02480ef423a82a8f0268f8d42470955c02b8dab525c05a3302d8c4962648bd1102e0b27727a855f601e8a05828e8fedf0180773929c0cacd01586d1a2af8f1be019053fb2a50d8b201d00edc2be0fca80138edbc2c48f2a001e06d9d2d80669a01c80d7e2e500f9501c0575e2f08b6900140323f30e0278d0148202031b0418a0108a3ff3120e8870120bedf32f0fb85013856c03398698401f0fda03478218301b8d87f35d8178201d8c26036183d8101b8223e37508d800188d21c38c8fc7f0168b5f93898877f01a829d139d8297f0120d6ab3ab8db7e0168ae803b389d7e0100ca9a3b68957e0150617920444f547320746f2074686520506f6c6b61646f74206163636f756e743a0000000000000033b312000600000000000000530000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000550000000000000000000000000000005600000000000000000000000000000057000000000000000000000000000000081112001800000000000000580000000000000000000000000000000000000000000000000000000200000000000000000000000000000002000000000000000000000000000000000000005900000000000000000000000000000059000000000000000000000000000000e013120009000000000000005a000000000000000000000000000000000000000000000000000000000000005b0000000000000000000000000000005c0000000000000000000000000000005900000000000000000000000000000059000000000000000000000000000000485f110004000000000000005d0000000000000000000000000000000000000000000000000000000000000059000000000000000000000002000000000000000000000000000000000000005e000000000000000000000000000000590000000000000000000000000000004c5f110009000000000000005f0000000000000000000000000000000000000000000000000000000000000060000000000000000000000002000000000000000000000000000000000000006100000000000000000000000000000059000000000000000000000000000000555f110007000000000000006200000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000006400000000000000000000000000000059000000000000000000000000000000590000000000000000000000000000005c5f110008000000000000006500000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000006700000000000000000000000000000068000000000000000000000000000000690000000000000000000000000000004d25120012000000000000006a0000000000000000000000000000000000000000000000000000000200000000000000000000000000000002000000000000000000000000000000000000006b00000000000000000000000000000059000000000000000000000000000000645f11000a000000000000006c000000000000000000000000000000000000000000000000000000000000006d00000000000000000000000200000000000000000000000000000000000000590000000000000000000000000000006e0000000000000000000000000000006e5f110007000000000000006f0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000710000000000000000000000000000007200000000000000000000000000000073000000000000000000000000000000755f110008000000000000007400000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000007500000000000000000000000000000059000000000000000000000000000000590000000000000000000000000000007d5f11000a00000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000002000000000000000000000000000000000000005900000000000000000000000000000059000000000000000000000000000000316e12000700000000000000760000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000780000000000000000000000000000005900000000000000000000000000000079000000000000000000000000000000ee1012000f000000000000007a000000000000000000000000000000000000000000000000000000000000007b000000000000000000000002000000000000000000000000000000000000007c0000000000000000000000000000007d000000000000000000000000000000875f110007000000000000007e000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000800000000000000000000000000000005900000000000000000000000000000081000000000000000000000000000000c6db110008000000000000008200000000000000000000000000000000000000000000000000000000000000830000000000000000000000000000008400000000000000000000000000000059000000000000000000000000000000850000000000000000000000000000008e5f11001200000002000000000000000000000000000000000000000000000000000000000000000000000059000000000000000000000002000000000000000000000000000000000000005900000000000000000000000000000059000000000000000000000000000000c94f1100090000000000000086000000000000000000000000000000000000000000000000000000000000008700000000000000000000000000000088000000000000000000000000000000890000000000000000000000000000008a000000000000000000000000000000a05f110007000000000000008b000000000000000000000000000000000000000000000000000000000000008c0000000000000000000000000000008d000000000000000000000000000000590000000000000000000000000000008e000000000000000000000000000000a75f110012000000000000008f000000000000000000000000000000000000000000000000000000000000008c0000000000000000000000000000008d000000000000000000000000000000590000000000000000000000000000008e000000000000000000000000000000b95f11001100000000000000900000000000000000000000000000000000000000000000000000000000000091000000000000000000000000000000920000000000000000000000000000009300000000000000000000000000000094000000000000000000000000000000ca5f11001300000000000000950000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000970000000000000000000000000000005900000000000000000000000000000059000000000000000000000000000000176f120008000000000000009800000000000000000000000000000000000000000000000000000000000000990000000000000000000000000000009a0000000000000000000000000000009b0000000000000000000000000000009c000000000000000000000000000000cd0313000a000000000000009d000000000000000000000000000000000000000000000000000000000000009e00000000000000000000000200000000000000000000000000000000000000590000000000000000000000000000009f000000000000000000000000000000710113000c00000000000000a000000000000000000000000000000000000000000000000000000000000000a10000000000000000000000020000000000000000000000000000000000000059000000000000000000000000000000a2000000000000000000000000000000540113000500000000000000a300000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000a500000000000000000000000000000059000000000000000000000000000000a6000000000000000000000000000000d70313000900000000000000a700000000000000000000000000000000000000000000000000000000000000a8000000000000000000000000000000a900000000000000000000000000000059000000000000000000000000000000aa000000000000000000000000000000c00313000600000000000000ab00000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000ad000000000000000000000000000000ae000000000000000000000000000000af000000000000000000000000000000dfd911000700000000000000b000000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000b2000000000000000000000000000000b3000000000000000000000000000000b4000000000000000000000000000000dd5f11000700000000000000b500000000000000000000000000000000000000000000000000000000000000b6000000000000000000000000000000b700000000000000000000000000000059000000000000000000000000000000b800000000000000000000000000000008ed11000400000000000000b900000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000bb00000000000000000000000000000059000000000000000000000000000000bc00000000000000000000004261626554696d657374616d70496e646963657342616c616e636573417574686f72736869705374616b696e674f6666656e636573486973746f726963616c4772616e647061417574686f72697479446973636f76657279436f756e63696c546563686e6963616c436f6d6d6974746565456c656374696f6e7350687261676d656e546563686e6963616c4d656d626572736869705574696c69747900000000c14f11000800000000000000286411000100000000000000000000004e2b12000f0000000000000030641100010000000000000000000000b94f1100080000000000000038641100010000000000000000000000b14f1100080000000000000040641100010000000000000000000000a24f11000f00000000000000486411000100000000000000000000005d2b12001100000000000000506411000100000000000000000000008f4f11001300000000000000586411000100000000000000000000007e4f1100110000000000000060641100010000000000000000000000734f11000b0000000000000068641100010000000000000000000000694f11000a00000000000000706411000100000000000000000000005c4f11000d0000000000000078641100010000000000000000000000504f11000c0000000000000080641100010000000000000000000000464f11000a00000000000000886411000100000000000000000000003a4f11000c0000000000000090641100010000000000000000000000294f11001100000000000000986411000100000000000000000000001e4f11000b00000000000000a06411000100000000000000000000001d2b12000800000000000000a8641100010000000000000000000000164f11000800000000000000b0641100010000000000000000000000074f11000f00000000000000b8641100010000000000000000000000f64e11001100000000000000c0641100010000000000000000000000e74e11000f00000000000000c8641100010000000000000000000000dc4e11000b00000000000000d0641100010000000000000000000000d34e11000900000000000000d8641100010000000000000000000000c94e11000a00000000000000e0641100010000000000000000000000c24e11000700000000000000e8641100010000000000000000000000b94e11000900000000000000f0641100010000000000000000000000b04e11000900000000000000f8641100010000000000000000000000a84e11000800000000000000006511000100000000000000000000009c4e11000c00000000000000086511000100000000000000000000008b4e1100110000000000000010651100010000000000000000000000834e11000800000000000000186511000100000000000000000000007a4e1100090000000000000020651100010000000000000000000000694e11001100000000000000286511000100000000000000000000005c4e11000d0000000000000030651100010000000000000000000000524e11000a0000000000000038651100020000000000000000000000414e1100110000000000000048651100010000000000000000000000394e11000800000000000000506511000100000000000000000000002a4e11000f00000000000000586511000100000000000000000000001b4e11000f00000000000000606511000100000000000000bf6a11000e000000a76a1100180000009b6a11000c0000008d6a11000e000000676a110026000000516a110016000000366a11001b0000000b6a11002b000000fe6911000d000000e969110015000000c269110027000000b269110010000000a66911000c000000986911000e0000008169110017000000746911000d0000006a6911000a00000061691100090000004e691100130000002c691100220000001b691100110000000669110015000000dd68110029000000a16811003c000000626811003f000000146811004e000000d0671100440000009e671100320000006b6711003300000048671100230000001f67110029000000f56611002a000000b5661100400000008c66110029000000fb65110056000000516611003b000000c4651100370000009e6511002600000089651100150000006865110021000000204d6178696d756d206e756d626572206f6620766f74657320726561636865642e20496e76616c696420757070657220626f756e642e2044656c65676174696f6e20746f206f6e6573656c66206d616b6573206e6f2073656e73652e2054686520696e7374616e74207265666572656e64756d206f726967696e2069732063757272656e746c7920646973616c6c6f7765642e20546865206163636f756e742063757272656e746c792068617320766f74657320617474616368656420746f20697420616e6420746865206f7065726174696f6e2063616e6e6f74207375636365656420756e74696c207468657365206172652072656d6f7665642c20656974686572207468726f7567682060756e766f746560206f722060726561705f766f7465602e20546865206163636f756e74206973206e6f742063757272656e746c792064656c65676174696e672e20546f6f206869676820612062616c616e6365207761732070726f7669646564207468617420746865206163636f756e742063616e6e6f74206166666f72642e20416e20756e657870656374656420696e746567657220756e646572666c6f77206f636375727265642e20416e20756e657870656374656420696e7465676572206f766572666c6f77206f636375727265642e20546865206163636f756e7420697320616c72656164792064656c65676174696e672e20546865206163746f7220686173206e6f207065726d697373696f6e20746f20636f6e647563742074686520616374696f6e2e2054686520676976656e206163636f756e7420646964206e6f7420766f7465206f6e20746865207265666572656e64756d2e20412070726f78792d64652d70616972696e672077617320617474656d7074656420746f20616e206163636f756e74207468617420776173206e6f74206163746976652e20412070726f78792d70616972696e672077617320617474656d7074656420746f20616e206163636f756e74207468617420776173206f70656e20746f20616e6f74686572206163636f756e742e20412070726f78792d70616972696e672077617320617474656d7074656420746f20616e206163636f756e74207468617420776173206e6f74206f70656e2e20546865206c6f636b206f6e20746865206163636f756e7420746f20626520756e6c6f636b656420686173206e6f742079657420657870697265642e2054686520746172676574206163636f756e7420646f6573206e6f7420686176652061206c6f636b2e204e6f2070726f706f73616c732077616974696e6720496e76616c696420707265696d61676520566f746520676976656e20666f7220696e76616c6964207265666572656e64756d20507265696d616765206e6f7420666f756e6420496d6d696e656e7420546f6f206561726c79204e6f7420696d6d696e656e7420507265696d61676520616c7265616479206e6f746564204e6f742064656c6567617465642057726f6e672070726f787920416c726561647920612070726f7879204964656e74697479206d6179206e6f74207665746f20612070726f706f73616c207477696365204e6f2065787465726e616c2070726f706f73616c20496e76616c69642068617368204e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974792050726f706f73616c207374696c6c20626c61636b6c69737465642050726f706f73616c20616c7265616479206d6164652043616e6e6f742063616e63656c207468652073616d652070726f706f73616c20747769636520556e6b6e6f776e20696e646578204e6f7420612070726f78792050726f706f73616c20646f6573206e6f742065786973742056616c756520746f6f206c6f7700000000000000906c11000f0000000000000090d012000e0000000000000000131300a06c11000000000000000000b06c1100050000000000000000000000d86c11000c0000000000000090d012000e0000000000000000131300f86c11000000000000000000e46c1100010000000000000000000000ec6c11000c0000000000000090d012000e0000000000000000131300f86c11000000000000000000086d1100010000000000000000000000106d11000e00000000000000a9f812000c0000000000000000131300206d11000000000000000000306d1100010000000000000000000000386d1100150000000000000090d012000e0000000000000000131300506d11000000000000000000606d1100010000000000000000000000686d11000d0000000000000090d012000e0000000000000000131300786d11000000000000000000886d1100010000000000000000000000906d11001300000000000000a9f812000c0000000000000000131300a46d11000000000000000000b46d1100010000000000000000000000bc6d11000800000000000000c2c41200030000000000000000131300c46d11000000000000000000d46d11000100000000000000456e6163746d656e74506572696f64001f0000000000000001000000bd000000996f11005c0000000013130000000000f56f11004c000000417011005a0000009b701100270000004c61756e6368506572696f64606f110039000000566f74696e67506572696f641f0000000000000001000000be000000326f11002e0000004d696e696d756d4465706f73697400001f0000000000000001000000bf000000e56e11004d00000046617374547261636b566f74696e67506572696f640000001f0000000000000001000000c0000000aa6e11003b000000436f6f6c6f6666506572696f640000001f0000000000000001000000c1000000526e110058000000507265696d616765427974654465706f736974001f0000000000000001000000c2000000086e11004a0000004d6178566f7465731f0000000000000001000000c3000000dc6d11002c00000020546865206d6178696d756d206e756d626572206f6620766f74657320666f7220616e206163636f756e742e2054686520616d6f756e74206f662062616c616e63652074686174206d757374206265206465706f7369746564207065722062797465206f6620707265696d6167652073746f7265642e20506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f7220616e20656d657267656e6379207265666572656e64756d2e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e20546865206d696e696d756d20706572696f64206f66206c6f636b696e6720616e642074686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e2049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e73757265207468617420766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e0000000000000c7112000800000000000000b0731100020000000000000000000000c0731100010000000000000000000000c87311000600000000000000d0731100030000000000000000000000e8731100010000000000000000000000f07311000e00000000000000001313000000000000000000000000000074110001000000000000000000000008741100070000000000000010741100020000000000000000000000207411000100000000000000000000002874110006000000000000003074110001000000000000000000000038741100010000000000000000000000407411000900000000000000307411000100000000000000000000004c7411000100000000000000000000005474110009000000000000003074110001000000000000000000000060741100010000000000000000000000542d1200080000000000000068741100020000000000000000000000787411000100000000000000000000008074110009000000000000008c7411000200000000000000000000009c741100010000000000000000000000a47411000b00000000000000b4b41200010000000000000000000000b0741100010000000000000000000000b87411000600000000000000c0741100030000000000000000000000d8741100010000000000000000000000e07411000d00000000000000ec711200030000000000000000000000f0741100010000000000000000000000f87411000c00000000000000ec71120003000000000000000000000004751100010000000000000000000000e74e11000f000000000000000c7511000200000000000000000000001c751100010000000000000000000000074f11000f000000000000000c751100020000000000000000000000247511000100000000000000000000002c7511000e000000000000003c7511000400000000000000000000005c751100010000000000000000000000647511000800000000000000b4b412000100000000000000000000006c7511000100000000000000b8781100090000006b72120007000000cf781100300000005461626c65640000b8781100090000006b72120007000000c17811000e000000817811003700000045787465726e616c5461626c656400005b7811002600000053746172746564007c7611000f0000004e7811000d000000367811001800000050617373656400007c7611000f0000000a7811002c0000004e6f74506173736564000000de7711002c00000043616e63656c6c6564000000bd771100210000007c7611000f0000000fb9120004000000a07711001d00000044656c6567617465640000000eb51200090000000eb51200090000006877110038000000556e64656c656761746564002e7711003a0000005665746f656400000eb51200090000006772120004000000e31012000b0000000877110026000000507265696d6167654e6f746564000000d076110038000000507265696d616765557365648b7611004500000067721200040000007c7611000f0000003976110043000000f675110043000000507265696d616765526561706564000067721200040000000eb51200090000006b721200070000000eb51200090000009f75110057000000556e6c6f636b6564747511002b00000020416e206163636f756e7420686173206265656e20756e6c6f636b6564207375636365737366756c6c792e2041207265676973746572656420707265696d616765207761732072656d6f76656420616e6420746865206465706f73697420636f6c6c6563746564206279207468652072656170657220286c617374206974656d292e20412070726f706f73616c20636f756c64206e6f7420626520657865637574656420626563617573652069747320707265696d61676520776173206d697373696e672e20412070726f706f73616c20636f756c64206e6f7420626520657865637574656420626563617573652069747320707265696d6167652077617320696e76616c69642e5265666572656e64756d496e64657820412070726f706f73616c20707265696d616765207761732072656d6f76656420616e6420757365642028746865206465706f736974207761732072657475726e6564292e20412070726f706f73616c277320707265696d61676520776173206e6f7465642c20616e6420746865206465706f7369742074616b656e2e20416e2065787465726e616c2070726f706f73616c20686173206265656e207665746f65642e20416e206163636f756e74206861732063616e63656c6c656420612070726576696f75732064656c65676174696f6e206f7065726174696f6e2e20416e206163636f756e74206861732064656c65676174656420746865697220766f746520746f20616e6f74686572206163636f756e742e20412070726f706f73616c20686173206265656e20656e61637465642e2041207265666572656e64756d20686173206265656e2063616e63656c6c65642e20412070726f706f73616c20686173206265656e2072656a6563746564206279207265666572656e64756d2e20412070726f706f73616c20686173206265656e20617070726f766564206279207265666572656e64756d2e2041207265666572656e64756d2068617320626567756e2e566f74655468726573686f6c6420416e2065787465726e616c2070726f706f73616c20686173206265656e207461626c65642e2041207075626c69632070726f706f73616c20686173206265656e207461626c656420666f72207265666572656e64756d20766f74652e50726f70496e6465785665633c4163636f756e7449643e2041206d6f74696f6e20686173206265656e2070726f706f7365642062792061207075626c6963206163636f756e742e0000000000802b12000700000000000000547e1100020000000000000000000000847e11001100000000000000000000000c7f11000600000000000000147f1100020000000000000000000000447f11001000000000000000000000009db612000400000000000000c47f1100020000000000000000000000f47f1100120000000000000000000000848011000a00000000000000c47f11000200000000000000000000009080110012000000000000000000000020811100100000000000000030811100010000000000000000000000488111000e0000000000000000000000b88111001000000000000000c8811100010000000000000000000000e08111000e0000000000000000000000508211001900000000000000c88111000100000000000000000000006c8211000f0000000000000000000000e48211001800000000000000c8811100010000000000000000000000fc8211000f0000000000000000000000748311000a0000000000000080831100030000000000000000000000c8831100140000000000000000000000688411000d00000000000000c8811100010000000000000000000000788411000f0000000000000000000000f08411001100000000000000048511000100000000000000000000001c8511000b0000000000000000000000748511000d00000000000000848511000100000000000000000000009c8511000c0000000000000000000000fc8511000e000000000000000c861100010000000000000000000000248611000e0000000000000000000000948611000b0000000000000000131300000000000000000000000000a08611000c00000000000000000000000087110010000000000000000c8611000100000000000000000000001087110010000000000000000000000090871100080000000000000098871100030000000000000000000000e08711001b0000000000000000000000b88811000a0000000000000000131300000000000000000000000000c48811001300000000000000000000005c89110016000000000000000013130000000000000000000000000074891100090000000000000000000000bc8911000d00000000000000cc891100010000000000000000000000e48911000c0000000000000000000000448a11001900000000000000cc891100010000000000000000000000608a1100010000000000000000000000688a11001600000000000000cc891100010000000000000000000000808a11000c0000000000000000000000e08a11002200000000000000cc891100010000000000000000000000048b11000100000000000000000000000c8b11000d000000000000001c8b11000200000000000000000000004c8b1100140000000000000000000000ec8b11000600000000000000f48b11000100000000000000000000000c8c11000e00000000000000000000007c8c11000a00000000000000f48b1100010000000000000000000000888c1100100000000000000000000000088d11000b00000000000000148d11000100000000000000000000002c8d11002000000000000000000000002c8e11001100000000000000408e1100020000000000000000000000708e1100140000000000000000000000108f11000e0000000000000098871100030000000000000000000000208f11001b0000000000000000000000f88f1100100000000000000000131300000000000000000000000000089011000f0000000000000000000000809011001100000000000000148d1100010000000000000000000000949011001100000000000000000000001c9111000e000000000000002c9111000200000000000000000000005c911100010000000000000000000000b89111000d000000000000009ed012000700000000000000bef212000500000000000000c3f21200150000007bbf1100280000000013130000000000a3bf110046000000e9bf11002100000000131300000000000ac011003600000040c0110046000000001313000000000086c0110012000000001313000000000091c212000b000000ba7f12001500000098c011002d000000c5c011003b00000000c111001400000014c111005100000034c312000c0000007365636f6e6400000000000083461200080000000000000056bf1100120000000000000068bf11001300000000000000ebea12000c00000027bd11002e000000001313000000000055bd11004100000096bd1100450000000013130000000000dbbd1100330000000ebe1100510000005fbe11004a000000001313000000000091c212000b000000a9be11004e000000f7be1100180000000fbf11001900000028bf11000a00000032bf11002400000034c312000c000000000000002baf1100090000000000000034af110018000000000000009db6120004000000000000000ebd1100190000007cbb11004d000000c9bb11002f0000000013130000000000769b1100330000000013130000000000f8bb110038000000e3b9110022000000001313000000000091c212000b00000030bc11005200000057ba11002900000082bc11003d000000d7ba11003e000000c4c21200150000003ea211000f000000bfbc110025000000e4bc11002a00000034c312000c00000070726f78795f766f7465000014b911005400000068b911003d0000000013130000000000769b1100330000000013130000000000a5b911003e000000e3b9110022000000001313000000000091c212000b00000005ba11005200000057ba11002900000080ba110057000000d7ba11003e00000015bb11000d0000003ea211000f00000022bb11002b0000004dbb11002f00000034c312000c000000656d657267656e63795f63616e63656c000000002baf110009000000000000007c7611000f000000c4b7110054000000c4b611000c000000001313000000000018b811003f000000001313000000000057b8110035000000001313000000000091c212000b000000dcae1100160000008cb8110030000000bcb8110031000000edb811000e000000fbb811001900000034c312000c00000065787465726e616c5f70726f706f736500000000b89111000d000000000000009ed012000700000078b611004c000000c4b611000c0000000013130000000000d0b611003b0000000013130000000000d1b4110036000000001313000000000091c212000b0000000bb711004b00000056b711002f000000a5b011002800000085b711001c000000a1b711002300000034c312000c00000065787465726e616c5f70726f706f73655f6d616a6f72697479000000b5b51100560000000bb6110018000000001313000000000023b611003c0000000013130000000000d1b4110036000000001313000000000007b51100530000005ab5110027000000001313000000000091c212000b000000ba7f12001500000081b511001b0000005fb611001900000034c312000c00000065787465726e616c5f70726f706f73655f64656661756c7423b411005200000075b4110021000000001313000000000096b411003b0000000013130000000000d1b4110036000000001313000000000007b51100530000005ab5110027000000001313000000000091c212000b000000ba7f12001500000081b511001b0000009cb511001900000034c312000c000000666173745f747261636b000000000000b89111000d000000000000009ed01200070000000000000011b411000d0000000000000090d012000e000000000000001eb41100050000000000000090d012000e0000001ab11100540000006eb1110059000000c7b111003b000000001313000000000002b2110035000000001313000000000037b211003e00000075b2110058000000cdb2110026000000f3b211005500000048b311002f000000001313000000000077b3110011000000001313000000000091c212000b000000ba7f12001500000088b311002e000000b6b3110043000000f9b311001800000034c312000c0000007665746f5f65787465726e616c0000004caf11002f00000000131300000000007baf1100370000000013130000000000b2af11004c0000000013130000000000feaf110010000000001313000000000091c212000b0000000eb011004600000054b0110051000000a5b0110028000000cdb0110029000000f6b011002400000034c312000c00000063616e63656c5f7265666572656e64756d000000000000002baf1100090000000000000034af11001800000091ae110015000000001313000000000066a71100310000000013130000000000a6ae110036000000001313000000000091c212000b000000dcae110016000000f2ae11002000000012af11001900000034c312000c00000063616e63656c5f717565756564000000000000008cae110005000000000000007c7611000f0000005bad110028000000001313000000000066a7110031000000001313000000000083ad110032000000001313000000000091c212000b000000b5ad11004d00000002ae11003200000034ae11003300000067ae11002500000034c312000c00000061637469766174655f70726f787900000000000056ad11000500000000000000d0cf12000c0000009fac1100410000000013130000000000e0ac1100250000000013130000000000769b110033000000001313000000000005ad110038000000001313000000000091c212000b000000ba7f120015000000aaab110014000000beab1100150000003dad11001900000034c312000c000000636c6f73655f70726f787900ebab110026000000001313000000000011ac1100280000000013130000000000769b110033000000001313000000000091c212000b000000ba7f12001500000039ac1100260000005fac11002700000086ac11001900000034c312000c000000646561637469766174655f70726f7879dbaa11004b000000001313000000000026ab110022000000001313000000000048ab1100280000000013130000000000769b110033000000001313000000000070ab11003a000000001313000000000091c212000b000000ba7f120015000000aaab110014000000beab110015000000d3ab11001800000034c312000c00000064656c656761746500000000beaa11000200000000000000d0cf12000c00000000000000c0aa11000a00000000000000caaa11000a00000000000000d4aa11000700000000000000a9f812000c0000009ba911004f0000000013130000000000039611005600000059961100330000000013130000000000eaa9110058000000819711001e0000009f97110057000000f69711002600000000131300000000001c981100520000006e98110056000000c49811005100000015991100550000006a9911003200000000131300000000009c99110013000000001313000000000091c212000b00000067a8110056000000bda811003300000042aa11002b0000006daa11002c00000023a91100290000004ca911002a00000099aa11002500000034c312000c000000756e64656c65676174650000cba711003400000000131300000000007e94110058000000d6941100380000000013130000000000ffa711005200000051a811001600000000131300000000004a95110015000000001313000000000091c212000b00000067a8110056000000bda8110033000000f0a811001900000009a911001a00000023a91100290000004ca911002a00000076a911002500000034c312000c000000636c6561725f7075626c69635f70726f706f73616c73000049a711001d000000001313000000000066a7110031000000001313000000000091c212000b00000010f111000a00000097a711001b000000b2a711001900000034c312000c0000006e6f74655f707265696d6167650000000000000039a71100100000000000000059c912000700000098a6110058000000f0a61100490000000013130000000000769b1100330000000013130000000000eca511003200000000131300000000001ea6110017000000001313000000000091c212000b00000035a611002000000034c312000c0000006e6f74655f707265696d6167655f6f7065726174696f6e616c00000055a61100430000006e6f74655f696d6d696e656e745f707265696d61676500006ea5110051000000bfa511002d0000000013130000000000769b1100330000000013130000000000eca511003200000000131300000000001ea6110017000000001313000000000091c212000b00000035a611002000000034c312000c0000006e6f74655f696d6d696e656e745f707265696d6167655f6f7065726174696f6e616c000022a511004c000000726561705f707265696d61676500000000000000b89111000d000000000000009ed0120007000000000000000aa511001800000000000000ebea12000c00000096a211003d0000000013130000000000769b1100330000000013130000000000d3a211003400000007a311004b00000052a3110040000000001313000000000092a3110054000000e6a31100570000003da411002c000000001313000000000069a4110018000000001313000000000091c212000b00000081a4110034000000b5a4110018000000cda4110019000000e6a411002400000034c312000c000000756e6c6f636b0000000000007bf211000600000000000000d0cf12000c0000003aa11100290000000013130000000000769b110033000000001313000000000063a111002f000000001313000000000091c212000b00000092a1110035000000c7a111003b00000002a211003c0000003ea211000f0000004da211002600000073a211002300000034c312000c0000006f70656e5f70726f787900001ea011001000000000131300000000002ea0110037000000001313000000000065a011001900000000131300000000007ea011003b0000000013130000000000b9a0110042000000001313000000000091c212000b0000002899120013000000d299110025000000fba011002600000021a111001900000034c312000c00000072656d6f76655f766f746500000000008b46120005000000000000007c7611000f000000399a11002000000000131300000000005e9c110004000000629c110023000000859c110020000000a59c110025000000ca9c1100400000000a9d110036000000409d110022000000629d110058000000ba9d1100170000000013130000000000d19d11002b000000fc9d11003c000000389e110038000000709e110030000000a09e110057000000f79e1100570000004e9f11003a0000000013130000000000889f110053000000db9f1100230000000013130000000000049311003e000000001313000000000091c212000b00000042931100500000009293110037000000139c11002b000000fd9311002c000000fe9f11002000000034c312000c00000072656d6f76655f6f746865725f766f7465000000000000007bf211000600000000000000d0cf12000c000000000000008b46120005000000000000007c7611000f000000399a1100200000000013130000000000599a110054000000ad9a11004c000000f99a1100560000004f9b1100270000000013130000000000769b1100330000000013130000000000a99b110054000000fd9b110016000000049311003e000000001313000000000091c212000b00000042931100500000009293110037000000139c11002b000000fd9311002c0000003e9c11002000000034c312000c00000070726f78795f64656c65676174650000b69511004d00000000131300000000000396110056000000599611003300000000131300000000008c96110055000000e19611002c00000000131300000000000d97110058000000659711001c000000819711001e0000009f97110057000000f6971100260000001c981100520000006e98110056000000c49811005100000015991100550000006a9911003200000000131300000000009c99110013000000001313000000000091c212000b000000af99110023000000d299110025000000f79911001d000000149a11002500000034c312000c00000070726f78795f756e64656c65676174654c9411003200000000131300000000007e94110058000000d694110038000000001313000000000058921100540000000e9511003c00000000131300000000004a95110015000000001313000000000091c212000b0000005f951100250000008495110012000000969511002000000034c312000c00000070726f78795f72656d6f76655f766f7465000000c5911100280000000013130000000000ed91110054000000419211001700000000131300000000005892110054000000ac921100580000000013130000000000049311003e000000001313000000000091c212000b00000042931100500000009293110037000000c993110034000000fd9311002c000000299411002300000034c312000c000000656e6163745f70726f706f73616c000000000000b89111000d000000000000009ed0120007000000000000008b46120005000000000000007c7611000f000000649111005400000020456e61637420612070726f706f73616c2066726f6d2061207265666572656e64756d2e20466f72206e6f77207765206a757374206d616b65207468652077656967687420626520746865206d6178696d756d2e70726f706f73616c5f686173682052656d6f766520612070726f7869656420766f746520666f722061207265666572656e64756d2e2045786163746c79206571756976616c656e7420746f206072656d6f76655f766f746560206578636570742074686174206974206f70657261746573206f6e20746865206163636f756e742074686174207468652073656e64657220697320612070726f787920666f722e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d75737420626520612070726f787920666f7220736f6d65206f74686572206163636f756e74207768696368206861732061207265676973746572656420766f746520666f7220746865207265666572656e64756d206f662060696e646578602e202d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e202d20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2e2020205765696768742069732063616c63756c6174656420666f7220746865206d6178696d756d206e756d626572206f6620766f74652e202d2044622072656164733a20605265666572656e64756d496e666f4f66602c2060566f74696e674f66602c206050726f787960202d204462207772697465733a20605265666572656e64756d496e666f4f66602c2060566f74696e674f6660202d2042617365205765696768743a2032362e3335202b202e3336202a205220c2b57320556e64656c65676174652074686520766f74696e6720706f776572206f6620612070726f78696564206163636f756e742e20546f6b656e73206d617920626520756e6c6f636b656420666f6c6c6f77696e67206f6e636520616e20616d6f756e74206f662074696d6520636f6e73697374656e74207769746820746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e2077697468207768696368207468652064656c65676174696f6e20776173206973737565642e2070726f787920666f7220736f6d65206f74686572206163636f756e742077686963682069732063757272656e746c792064656c65676174696e672e20456d6974732060556e64656c656761746564602e2073616d652061732060756e64656c65676174652077697468206164646974696f6e616c3a2044622072656164733a206050726f7879602042617365205765696768743a203339202b20372e393538202a205220c2b5732044656c65676174652074686520766f74696e6720706f77657220287769746820736f6d6520676976656e20636f6e76696374696f6e29206f6620612070726f78696564206163636f756e742e205468652062616c616e63652064656c656761746564206973206c6f636b656420666f72206173206c6f6e6720617320697427732064656c6567617465642c20616e64207468657265616674657220666f72207468652074696d6520617070726f70726961746520666f722074686520636f6e76696374696f6e2773206c6f636b20706572696f642e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e696e67206163636f756e74206d7573742068617665206265656e20736574206173207468652070726f7879206163636f756e7420666f722060746172676574602e202d2060746172676574603a20546865206163636f756e742077686f6c6520766f74696e6720706f776572207368616c6c2062652064656c65676174656420616e642077686f73652062616c616e6365206c6f636b65642e20202054686973206163636f756e74206d757374206569746865723a2020202d2062652064656c65676174696e6720616c72656164793b206f722020202d2068617665206e6f20766f74696e67206163746976697479202869662074686572652069732c207468656e2069742077696c6c206e65656420746f2062652072656d6f7665642f636f6e736f6c69646174656420202020207468726f7567682060726561705f766f746560206f722060756e766f746560292e202d2060746f603a20546865206163636f756e742077686f736520766f74696e6720746865206074617267657460206163636f756e74277320766f74696e6720706f7765722077696c6c20666f6c6c6f772e202d2060636f6e76696374696f6e603a2054686520636f6e76696374696f6e20746861742077696c6c20626520617474616368656420746f207468652064656c65676174656420766f7465732e205768656e207468652020206163636f756e7420697320756e64656c6567617465642c207468652066756e64732077696c6c206265206c6f636b656420666f722074686520636f72726573706f6e64696e6720706572696f642e202d206062616c616e6365603a2054686520616d6f756e74206f6620746865206163636f756e7427732062616c616e636520746f206265207573656420696e2064656c65676174696e672e2054686973206d7573742020206e6f74206265206d6f7265207468616e20746865206163636f756e7427732063757272656e742062616c616e63652e20456d697473206044656c656761746564602e2073616d65206173206064656c65676174652077697468206164646974696f6e616c3a202d2044622072656164733a206050726f7879602c206070726f7879206163636f756e7460202d204462207772697465733a206070726f7879206163636f756e7460202d2042617365205765696768743a2036382e3631202b20382e303339202a205220c2b5732052656d6f7665206120766f746520666f722061207265666572656e64756d2e2049662074686520607461726765746020697320657175616c20746f20746865207369676e65722c207468656e20746869732066756e6374696f6e2069732065786163746c79206571756976616c656e7420746f206072656d6f76655f766f7465602e204966206e6f7420657175616c20746f20746865207369676e65722c207468656e2074686520766f7465206d757374206861766520657870697265642c20656974686572206265636175736520746865207265666572656e64756d207761732063616e63656c6c65642c20626563617573652074686520766f746572206c6f737420746865207265666572656e64756d206f7220626563617573652074686520636f6e76696374696f6e20706572696f64206973206f7665722e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e202d2060746172676574603a20546865206163636f756e74206f662074686520766f746520746f2062652072656d6f7665643b2074686973206163636f756e74206d757374206861766520766f74656420666f722020207265666572656e64756d2060696e646578602e202d2044622072656164733a20605265666572656e64756d496e666f4f66602c2060566f74696e674f6660202d2042617365205765696768743a2031392e3135202b202e333732202a20522049663a202d20746865207265666572656e64756d207761732063616e63656c6c65642c206f72202d20746865207265666572656e64756d206973206f6e676f696e672c206f72202d20746865207265666572656e64756d2068617320656e646564207375636820746861742020202d2074686520766f7465206f6620746865206163636f756e742077617320696e206f70706f736974696f6e20746f2074686520726573756c743b206f722020202d20746865726520776173206e6f20636f6e76696374696f6e20746f20746865206163636f756e74277320766f74653b206f722020202d20746865206163636f756e74206d61646520612073706c697420766f7465202e2e2e7468656e2074686520766f74652069732072656d6f76656420636c65616e6c7920616e64206120666f6c6c6f77696e672063616c6c20746f2060756e6c6f636b60206d617920726573756c7420696e206d6f72652066756e6473206265696e6720617661696c61626c652e2049662c20686f77657665722c20746865207265666572656e64756d2068617320656e64656420616e643a202d2069742066696e697368656420636f72726573706f6e64696e6720746f2074686520766f7465206f6620746865206163636f756e742c20616e64202d20746865206163636f756e74206d6164652061207374616e6461726420766f7465207769746820636f6e76696374696f6e2c20616e64202d20746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e206973206e6f74206f766572202e2e2e7468656e20746865206c6f636b2077696c6c206265206167677265676174656420696e746f20746865206f766572616c6c206163636f756e742773206c6f636b2c207768696368206d617920696e766f6c7665202a6f7665726c6f636b696e672a20287768657265207468652074776f206c6f636b732061726520636f6d62696e656420696e746f20612073696e676c65206c6f636b207468617420697320746865206d6178696d756d206f6620626f74682074686520616d6f756e74206c6f636b656420616e64207468652074696d65206973206974206c6f636b656420666f72292e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e6572206d7573742068617665206120766f7465207265676973746572656420666f72207265666572656e64756d2060696e646578602e202d2042617365205765696768743a2032312e3033202b202e333539202a2052204265636f6d6520612070726f78792e2054686973206d7573742062652063616c6c6564207072696f7220746f2061206c61746572206061637469766174655f70726f7879602e204f726967696e206d7573742062652061205369676e65642e202d2060746172676574603a20546865206163636f756e742077686f736520766f7465732077696c6c206c617465722062652070726f786965642e2060636c6f73655f70726f787960206d7573742062652063616c6c6564206265666f726520746865206163636f756e742063616e2062652064657374726f7965642e202d204462207772697465733a206050726f7879602c206070726f7879206163636f756e7460202d2042617365205765696768743a2031342e383620c2b57320556e6c6f636b20746f6b656e732074686174206861766520616e2065787069726564206c6f636b2e202d2060746172676574603a20546865206163636f756e7420746f2072656d6f766520746865206c6f636b206f6e2e202d20436f6d706c657869747920604f2852296020776974682052206e756d626572206f6620766f7465206f66207461726765742e202d2044622072656164733a2060566f74696e674f66602c206062616c616e636573206c6f636b73602c2060746172676574206163636f756e7460202d204462207772697465733a2060566f74696e674f66602c206062616c616e636573206c6f636b73602c2060746172676574206163636f756e7460202d2042617365205765696768743a20202020202d20556e6c6f636b2052656d6f76653a2034322e3936202b202e303438202a205220202020202d20556e6c6f636b205365743a2033372e3633202b202e333237202a20522052656d6f766520616e20657870697265642070726f706f73616c20707265696d61676520616e6420636f6c6c65637420746865206465706f7369742e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f6620612070726f706f73616c2e202d206070726f706f73616c5f6c656e6774685f75707065725f626f756e64603a20616e20757070657220626f756e64206f6e206c656e677468206f66207468652070726f706f73616c2e20202045787472696e736963206973207765696768746564206163636f7264696e6720746f20746869732076616c75652077697468206e6f20726566756e642e20546869732077696c6c206f6e6c7920776f726b2061667465722060566f74696e67506572696f646020626c6f636b732066726f6d207468652074696d6520746861742074686520707265696d61676520776173206e6f7465642c2069662069742773207468652073616d65206163636f756e7420646f696e672069742e2049662069742773206120646966666572656e74206163636f756e742c207468656e206974276c6c206f6e6c7920776f726b20616e206164646974696f6e616c2060456e6163746d656e74506572696f6460206c617465722e20456d6974732060507265696d616765526561706564602e202d20436f6d706c65786974793a20604f284429602077686572652044206973206c656e677468206f662070726f706f73616c2e202d2044622072656164733a2060507265696d6167657360202d204462207772697465733a2060507265696d6167657360202d2042617365205765696768743a2033392e3331202b202e303033202a206220c2b57370726f706f73616c5f6c656e5f75707065725f626f756e642053616d6520617320606e6f74655f696d6d696e656e745f707265696d6167656020627574206f726967696e20697320604f7065726174696f6e616c507265696d6167654f726967696e602e2052656769737465722074686520707265696d61676520666f7220616e207570636f6d696e672070726f706f73616c2e2054686973207265717569726573207468652070726f706f73616c20746f20626520696e207468652064697370617463682071756575652e204e6f206465706f736974206973206e65656465642e202d2060656e636f6465645f70726f706f73616c603a2054686520707265696d616765206f6620612070726f706f73616c2e20456d6974732060507265696d6167654e6f746564602e2073656520607765696768745f666f723a3a6e6f74655f707265696d616765602053616d6520617320606e6f74655f707265696d6167656020627574206f726967696e20697320604f7065726174696f6e616c507265696d6167654f726967696e602e2052656769737465722074686520707265696d61676520666f7220616e207570636f6d696e672070726f706f73616c2e205468697320646f65736e27742072657175697265207468652070726f706f73616c20746f20626520696e207468652064697370617463682071756575652062757420646f657320726571756972652061206465706f7369742c2072657475726e6564206f6e636520656e61637465642e656e636f6465645f70726f706f73616c20436c6561727320616c6c207075626c69632070726f706f73616c732e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e202d204462207772697465733a20605075626c696350726f707360202d2042617365205765696768743a20322e35303520c2b57320556e64656c65676174652074686520766f74696e6720706f776572206f66207468652073656e64696e67206163636f756e742e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062652063757272656e746c792064656c65676174696e672e202d20436f6d706c65786974793a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722064656c65676174696e6720746f20686173202020766f746564206f6e2e205765696768742069732063686172676564206173206966206d6178696d756d20766f7465732e202d2044622072656164733a20322a60566f74696e674f6660202d204462207772697465733a20322a60566f74696e674f6660202d2044622072656164732070657220766f7465733a20605265666572656e64756d496e666f4f6660202d204462207772697465732070657220766f7465733a20605265666572656e64756d496e666f4f6660202d2042617365205765696768743a2033332e3239202b20382e313034202a205220c2b5732044656c65676174652074686520766f74696e6720706f77657220287769746820736f6d6520676976656e20636f6e76696374696f6e29206f66207468652073656e64696e67206163636f756e742e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e696e67206163636f756e74206d757374206569746865723a202d2044622072656164733a20322a60566f74696e674f66602c206062616c616e636573206c6f636b7360202d204462207772697465733a20322a60566f74696e674f66602c206062616c616e636573206c6f636b7360202d2042617365205765696768743a2036352e3738202b20382e323239202a205220c2b573746f636f6e76696374696f6e436f6e76696374696f6e62616c616e63652044656163746976617465207468652070726f78792c20627574206c65617665206f70656e20746f2074686973206163636f756e742e2043616c6c6564206279207468652073746173682e205468652070726f7879206d75737420616c7265616479206265206163746976652e204e4f54453a205573656420746f2062652063616c6c6564206072656d6f76655f70726f7879602e202d206070726f7879603a20546865206163636f756e7420746861742077696c6c2062652064656163746976617465642061732070726f78792e202d2044622072656164733a206050726f787960202d204462207772697465733a206050726f787960202d2042617365205765696768743a20382e303320c2b57320436c656172207468652070726f78792e2043616c6c6564206279207468652070726f78792e204e4f54453a205573656420746f2062652063616c6c6564206072657369676e5f70726f7879602e202d2044622072656164733a206050726f7879602c206073656e646572206163636f756e7460202d204462207772697465733a206050726f7879602c206073656e646572206163636f756e7460202d2042617365205765696768743a2031352e343120c2b573205370656369667920612070726f7879207468617420697320616c7265616479206f70656e20746f2075732e2043616c6c6564206279207468652073746173682e204e4f54453a205573656420746f2062652063616c6c656420607365745f70726f7879602e202d206070726f7879603a20546865206163636f756e7420746861742077696c6c206265206163746976617465642061732070726f78792e202d2042617365205765696768743a20372e39373220c2b57370726f78792043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e202d20607768696368603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e202d20604f284429602077686572652060446020697320746865206974656d7320696e207468652064697370617463682071756575652e205765696768746564206173206044203d203130602e202d2044622072656164733a20607363686564756c6572206c6f6f6b7570602c207363686564756c6572206167656e646160202d204462207772697465733a20607363686564756c6572206c6f6f6b7570602c207363686564756c6572206167656e646160202d2042617365205765696768743a2033362e3738202b20332e323737202a204420c2b57377686963682052656d6f76652061207265666572656e64756d2e202d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e202d20436f6d706c65786974793a20604f283129602e202d204462207772697465733a20605265666572656e64756d496e666f4f6660202d2042617365205765696768743a2032312e353720c2b5737265665f696e646578436f6d706163743c5265666572656e64756d496e6465783e205665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520605665746f4f726967696e602e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c20746f207665746f20616e6420626c61636b6c6973742e20456d69747320605665746f6564602e202d20436f6d706c65786974793a20604f2856202b206c6f6728562929602077686572652056206973206e756d626572206f6620606578697374696e67207665746f65727360202020506572666f726d7320612062696e61727920736561726368206f6e20606578697374696e675f7665746f657273602077686963682073686f756c64206e6f742062652076657279206c617267652e202d2044622072656164733a20604e65787445787465726e616c602c2060426c61636b6c69737460202d204462207772697465733a20604e65787445787465726e616c602c2060426c61636b6c69737460202d2042617365205765696768743a2032392e3837202b202e313838202a205620c2b573205363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c656420696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e6520627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e20546865206469737061746368206f6620746869732063616c6c206d757374206265206046617374547261636b4f726967696e602e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e202d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e20496e6372656173656420746f2020206046617374547261636b566f74696e67506572696f646020696620746f6f206c6f772e202d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265202020656e61637465642e205468697320646f65736e277420686176652061206d696e696d756d20616d6f756e742e20456d697473206053746172746564602e202d2044622072656164733a20604e65787445787465726e616c602c20605265666572656e64756d436f756e7460202d204462207772697465733a20604e65787445787465726e616c602c20605265666572656e64756d436f756e74602c20605265666572656e64756d496e666f4f6660202d2042617365205765696768743a2033302e3120c2b573766f74696e675f706572696f6464656c6179205363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c44656661756c744f726967696e602e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e20556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061207072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e202d2044622077726974653a20604e65787445787465726e616c60202d2042617365205765696768743a20332e30383720c2b573205363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c4d616a6f726974794f726967696e602e202d2042617365205765696768743a20332e30363520c2b573205363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206045787465726e616c4f726967696e602e202d20436f6d706c657869747920604f2856296020776974682056206e756d626572206f66207665746f65727320696e2074686520626c61636b6c697374206f662070726f706f73616c2e2020204465636f64696e6720766563206f66206c656e67746820562e2043686172676564206173206d6178696d756d202d204462207772697465733a20604e65787445787465726e616c60202d2042617365205765696768743a2031332e38202b202e313036202a205620c2b573205363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d6520546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c6c6174696f6e4f726967696e602e202d607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e202d2044622072656164733a20605265666572656e64756d496e666f4f66602c206043616e63656c6c6174696f6e7360202d204462207772697465733a20605265666572656e64756d496e666f4f66602c206043616e63656c6c6174696f6e7360202d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a2033342e323520c2b57320566f746520696e2061207265666572656e64756d206f6e20626568616c66206f6620612073746173682e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2070726f787920766f746520666f722e202d2060766f7465603a2054686520766f746520636f6e66696775726174696f6e2e202d20436f6d706c65786974793a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d73207468652070726f78792068617320766f746564206f6e2e2020207765696768742069732063686172676564206173206966206d6178696d756d20766f7465732e202d2044622072656164733a20605265666572656e64756d496e666f4f66602c2060566f74696e674f66602c206062616c616e636573206c6f636b73602c206050726f7879602c206070726f7879206163636f756e7460202d204462207772697465733a20605265666572656e64756d496e666f4f66602c2060566f74696e674f66602c206062616c616e636573206c6f636b7360202d2d2d2d2d2d2d2d2d2d2d2d20202020202d2050726f787920566f7465204e65773a2035342e3335202b202e333434202a205220c2b57320202020202d2050726f787920566f7465204578697374696e673a2035342e3335202b202e3335202a205220c2b57320566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f20766f746520666f722e202d20436f6d706c65786974793a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722068617320766f746564206f6e2e202d2044622072656164733a20605265666572656e64756d496e666f4f66602c2060566f74696e674f66602c206062616c616e636573206c6f636b736020202020202d20566f7465204e65773a2034392e3234202b202e333333202a205220c2b57320202020202d20566f7465204578697374696e673a2034392e3934202b202e333433202a205220c2b5734163636f756e74566f74653c42616c616e63654f663c543e3e205369676e616c732061677265656d656e742077697468206120706172746963756c61722070726f706f73616c2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e647320746f20636f76657220746865206465706f7369742c20657175616c20746f20746865206f726967696e616c206465706f7369742e202d206070726f706f73616c603a2054686520696e646578206f66207468652070726f706f73616c20746f207365636f6e642e202d20607365636f6e64735f75707065725f626f756e64603a20616e20757070657220626f756e64206f6e207468652063757272656e74206e756d626572206f66207365636f6e6473206f6e207468697320202070726f706f73616c2e2045787472696e736963206973207765696768746564206163636f7264696e6720746f20746869732076616c75652077697468206e6f20726566756e642e202d20436f6d706c65786974793a20604f28532960207768657265205320697320746865206e756d626572206f66207365636f6e647320612070726f706f73616c20616c7265616479206861732e202d2044622072656164733a20604465706f7369744f6660202d204462207772697465733a20604465706f7369744f6660202d2d2d2d2d2d2d2d2d202d2042617365205765696768743a2032322e3238202b202e323239202a205320c2b573436f6d706163743c50726f70496e6465783e7365636f6e64735f75707065725f626f756e642050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e647320746f20636f76657220746865206465706f7369742e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20707265696d6167652e202d206076616c7565603a2054686520616d6f756e74206f66206465706f73697420286d757374206265206174206c6561737420604d696e696d756d4465706f73697460292e20456d697473206050726f706f736564602e202d2044622072656164733a20605075626c696350726f70436f756e74602c20605075626c696350726f707360202d204462207772697465733a20605075626c696350726f70436f756e74602c20605075626c696350726f7073602c20604465706f7369744f6660202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2042617365205765696768743a2034322e3538202b202e313237202a205020c2b57320776974682060506020746865206e756d626572206f662070726f706f73616c7320605075626c696350726f7073600000000000000090c611000f0000000000000000000000b8781100090000000000000000000000000000000000000000000000000000000000000000131300bcc711000000000000000000a0c6110001000000000000000100000000000000a8c611000b0000000000000000000000b3c61100270000000000000000000000000000000000000000000000000000000000000000131300dcc611000000000000000000ecc6110001000000000000000100000000000000d24f1100090000000105000000000000b87811000900000000000000f4c6110021000000000000000000000000000000000000000013130018c71100000000000000000028c711000300000000000000000000000000000040c711000900000001060000000000009ed01200070000000000000049c711003a000000000000000000000000000000000000000013130028ca1100000000000000000084c711000200000000000000000000000000000094c711000f00000000000000000000007c7611000f0000000000000000000000000000000000000000000000000000000000000000131300bcc711000000000000000000a4c7110001000000000000000100000000000000acc711000d00000000000000000000007c7611000f0000000000000000000000000000000000000000000000000000000000000000131300bcc711000000000000000000ccc7110002000000000000000100000000000000db4f11001000000001050000000000007c7611000f00000000000000dcc7110035000000000000000000000000000000000000000013130014c81100000000000000000024c81100030000000000000000000000000000003cc81100080000000105000000000000d0cf12000c0000000000000044c8110032000000000000000000000000000000000000000013130078c81100000000000000000088c8110004000000000000000100000000000000a8c81100050000000105000000000000d0cf12000c00000000000000adc81100180000000000000000000000000000000000000000131300c8c811000000000000000000d8c8110004000000000000000000000000000000f8c81100050000000105000000000000d0cf12000c0000000000000090d012000e000000000000000000000000000000000000000013130000c91100000000000000000010c911000400000000000000000000000000000030c911001500000000000000000000000fb91200040000000000000000000000000000000000000000000000000000000000000000131300f8c91100000000000000000048c911000200000000000000010000000000000058c911000c000000000000000000000064c9110018000000000000000000000000000000000000000000000000000000000000000013130028ca110000000000000000007cc91100040000000000000000000000000000009cc911000900000001060000000000009ed012000700000000000000a5c91100230000000000000000000000000000000000000000131300c8c911000000000000000000d8c9110002000000000000000000000000000000e8c911000d00000001060000000000009ed0120007000000000000000fb91200040000000000000000000000000000000000000000131300f8c91100000000000000000008ca11000100000000000000010000000000000010ca11000e00000000000000000000001eca110008000000000000000000000000000000000000000000000000000000000000000013130028ca1100000000000000000038ca11000300000000000000000000005075626c696350726f70436f756e740057d111003d0000005075626c696350726f70735665633c2850726f70496e6465782c20543a3a486173682c20543a3a4163636f756e744964293e00001f0000000000000001000000360000000fd1110048000000285665633c543a3a4163636f756e7449643e2c2042616c616e63654f663c543e290000001f00000000000000010000004d000000b8d01100210000000013130000000000d9d0110036000000507265696d61676573507265696d6167655374617475733c543a3a4163636f756e7449642c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265723e0027d01100580000007fd01100390000005265666572656e64756d436f756e7400dbcf11004c0000004c6f77657374556e62616b65640000001f0000000000000001000000340000005bcf110049000000a4cf1100370000005265666572656e64756d496e666f3c543a3a426c6f636b4e756d6265722c20543a3a486173682c2042616c616e63654f663c543e3e0000001f000000000000000100000038000000ecce11002d000000001313000000000019cf110042000000566f74696e674f66566f74696e673c42616c616e63654f663c543e2c20543a3a4163636f756e7449642c20543a3a426c6f636b4e756d6265723e00001f0000000000000001000000c400000004ce1100570000005bce1100570000000013130000000000b2ce11003a00000050726f787950726f787953746174653c543a3a4163636f756e7449643e0000001f00000000000000010000003800000096cd11004c000000e2cd110022000000001313000000000066cd1100300000004c6f636b730000001f000000000000000100000038000000bbcc11005700000012cd110054000000001313000000000066cd1100300000004c6173745461626c656457617345787465726e616c0000005bcc110056000000b1cc11000a0000004e65787445787465726e616c28543a3a486173682c20566f74655468726573686f6c64296dcb110056000000c3cb11005500000018cc11002900000041cc11001a000000426c61636b6c69737428543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e291f00000000000000010000004d000000dfca11005400000033cb11003a00000043616e63656c6c6174696f6e730000001f00000000000000010000003800000095ca11004a00000053746f7261676556657273696f6e52656c656173657300001f00000000000000010000003800000050ca11001f00000000131300000000006fca1100260000002053746f726167652076657273696f6e206f66207468652070616c6c65742e204e6577206e6574776f726b732073746172742077697468206c6173742076657273696f6e2e205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e2041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d6265722028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e20546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e20546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743a202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f72202d20605075626c696350726f70736020697320656d7074792e205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c69632070726f706f73616c2e204163636f756e747320666f7220776869636820746865726520617265206c6f636b7320696e20616374696f6e207768696368206d61792062652072656d6f76656420617420736f6d6520706f696e7420696e20746865206675747572652e205468652076616c75652069732074686520626c6f636b206e756d62657220617420776869636820746865206c6f636b206578706972657320616e64206d61792062652072656d6f7665642e2054574f582d4e4f54453a204f4b20e2809520604163636f756e7449646020697320612073656375726520686173682e2057686f2069732061626c6520746f20766f746520666f722077686f6d2e2056616c7565206973207468652066756e642d686f6c64696e67206163636f756e742c206b65792069732074686520766f74652d7472616e73616374696f6e2d73656e64696e67206163636f756e742e20416c6c20766f74657320666f72206120706172746963756c617220766f7465722e2057652073746f7265207468652062616c616e636520666f7220746865206e756d626572206f6620766f74657320746861742077652068617665207265636f726465642e20546865207365636f6e64206974656d2069732074686520746f74616c20616d6f756e74206f662064656c65676174696f6e732c20746861742077696c6c2062652061646465642e2054574f582d4e4f54453a205341464520617320604163636f756e7449646073206172652063727970746f2068617368657320616e797761792e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e2054574f582d4e4f54453a205341464520617320696e646578657320617265206e6f7420756e64657220616e2061747461636b6572e280997320636f6e74726f6c2e20546865206c6f77657374207265666572656e64756d20696e64657820726570726573656e74696e6720616e20756e62616b6564207265666572656e64756d2e20457175616c20746f20605265666572656e64756d436f756e74602069662074686572652069736e2774206120756e62616b6564207265666572656e64756d2e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e204d6170206f662068617368657320746f207468652070726f706f73616c20707265696d6167652c20616c6f6e6720776974682077686f207265676973746572656420697420616e64207468656972206465706f7369742e2054686520626c6f636b206e756d6265722069732074686520626c6f636b20617420776869636820697420776173206465706f73697465642e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e2054574f582d4e4f54453a20536166652c20617320696e6372656173696e6720696e7465676572206b6579732061726520736166652e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865207365636f6e64206974656d206973207468652070726f706f73616c277320686173682e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e4c4f474943204552524f523a2062616b655f7265666572656e64756d2f7363686564756c655f6e616d6564206661696c65644661696c656420746f206465636f64652060507265696d616765537461747573602076617269616e740010d211005d000000700600002d00000010d211005d00000077060000400000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f64656d6f63726163792f7372632f6c69622e727300000010d211005d000000400600002d000000ccd2110021000000706f6c6b61646f745f72756e74696d652f55736572732f6761762f436f72652f706f6c6b61646f742f72756e74696d652f706f6c6b61646f742f7372632f6c69622e7273556e61626c6520746f20637265617465207369676e6564207061796c6f61643a20496e76616c69642072616e676520666f7220746869732061756374696f6e72616e676520656e6473206265666f726520697420626567696e7372616e676520626567696e7320746f6f206561726c7972616e676520626567696e7320746f6f206c61746572616e676520656e647320746f6f206c617465000000000000000000000000617474656d707420746f20646976696465206279207a65726f617373657274696f6e206661696c65643a206d6964203c3d206c656e0000001f00000008000000040000004a0000001f0000000000000001000000460000001f0000000000000001000000c50000007672662d6e6d2d706b000000f4d3110006000000fad3110010000000496e64657820206f7574206f6620626f756e64733a2000001cd4110055000000420900000e0000002f72757374632f323435346136386366626236336161376238653039666530353131346435663938623266393734302f7372632f6c6962616c6c6f632f636f6c6c656374696f6e732f7665635f64657175652e727371202f206365696c28712f246d617829203c20246d61782e204d6163726f2070726576656e747320616e792074797065206265696e672063726561746564207468617420646f6573206e6f74207361746973667920746869733b2071656400e0d411006a00000065010000270000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f7072696d6974697665732f61726974686d657469632f7372632f7065725f7468696e67732e72730000e0d411006a0000006c01000027000000e0d411006a00000077010000210000004661696c656420746f20636f6e76657274506172656e7420686173682073686f756c642062652076616c69642e5472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642e00000035d6110032000000446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e53746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e5369676e617475726520766572696669636174696f6e206661696c65642e4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e5472616e73616374696f6e43616c6c46696c74657228296e6577686561647350617261636861696e20686561647320636f756c64206e6f74206265206465636f6465642e00a0011300390000008b050000140000004e6f2070617261636861696e20686561647320666f756e6420696e20696e686572656e7420646174612e7265706f72745f646f75626c655f766f74657365745f6865616473546f6f4d616e794865616455706461746573546f6f4d616e795061726143616e6469646174657348656164734f75744f664f72646572556e7265676973746572656450617261496e76616c6964436f6c6c61746f72517565756546756c6c496e76616c69644d6573736167654f726967696e4e6f56616c696461746f7247726f75704e6f74456e6f75676856616c6964697479566f746573566f74657345786365656473417574686f72697469657357726f6e6756616c696461746f72417474657374696e67496e76616c69645369676e6174757265556e746167676564566f746573506172656e744d69736d6174636856616c69646174696f6e436f6465546f6f4c61726765446973616c6c6f776564436f64655570677261646543616e6e6f7450617946656573556e657870656374656452656c6179506172656e7456616c6964617465446f75626c65566f74655265706f727473526571756972655375646f7375646f7375646f5f756e636865636b65645f7765696768747365745f6b65797375646f5f617300000000000010d91100050000000000000018d9110001000000000000000000000020d91100010000000000000000000000b07512000a00000000000000b4b4120001000000000000000000000028d9110001000000000000000000000030d911000a000000000000003cd9110001000000000000000000000020d91100010000000000000053756469640000007c2e12000e00000080d911001800000044d911003c0000005375646f4173446f6e6500000fb912000400000020546865207375646f6572206a757374207377697463686564206964656e746974793b20746865206f6c64206b657920697320737570706c6965642e2041207375646f206a75737420746f6f6b20706c6163652e416d6f756e744c6f774578697374696e6756657374696e675363686564756c654e6f7456657374696e6776657374766573745f6f746865727665737465645f7472616e7366657256657374696e6700000000000040da11000e0000000000000050da110002000000000000000000000060da110002000000000000000000000070da11001000000000000000b4b4120001000000000000000000000080da1100010000000000000056657374696e675570646174656400000eb51200090000006b72120007000000d3da11005600000029db11004600000056657374696e67436f6d706c6574656488da11004b00000020416e206163636f756e742028676976656e2920686173206265636f6d652066756c6c79207665737465642e204e6f20667572746865722076657374696e672063616e2068617070656e2e2054686520616d6f756e742076657374656420686173206265656e20757064617465642e205468697320636f756c6420696e646963617465206d6f72652066756e64732061726520617661696c61626c652e205468652062616c616e636520676976656e2069732074686520616d6f756e74207768696368206973206c65667420756e7665737465642028616e642074687573206c6f636b6564292e50617261636861696e206865616473206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b4475706c696361746564486561727462656174496e76616c69644b6579686561727462656174496d4f6e6c696e6548656172746265617441667465724b6579730000000064dc1100110000000000000078dc110001000000000000000000000080dc110001000000000000000000000088dc110007000000000000000013130000000000000000000000000090dc110001000000000000000000000098dc11000b00000000000000a4dc1100010000000000000000000000acdc1100010000000000000048656172746265617452656365697665640000007cdd11000b0000004cdd110030000000416c6c476f6f640017dd110035000000536f6d654f66666c696e6500ffdc110018000000b4dc11004b0000002041742074686520656e64206f66207468652073657373696f6e2c206174206c65617374206f6e652076616c696461746f722077617320666f756e6420746f206265206f66666c696e652e5665633c4964656e74696669636174696f6e5475706c653e2041742074686520656e64206f66207468652073657373696f6e2c206e6f206f6666656e63652077617320636f6d6d69747465642e2041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f72697479496460417574686f726974794964467574757265436f646555706772616465730000001f000000080000000400000041000000bddb110009000000496e76616c69642f6f75746461746564206b6579206f776e6572736869702070726f6f662e4661696c656420746f207265706f7274206f6666656e6365000000a0011300390000003d0500002f0000006f7264657265645f6e656564735f646973706174636820636f6e7461696e732069643f21a001130039000000bb0300001d00000050617374436f64655072756e696e6750617374436f646550617374436f64654d65746176616c696461746f725f726f6c655f706169727300a001130039000000f20300002f000000a0de110048000000ff01000023000000a0de11004800000000020000230000002f72757374632f323435346136386366626236336161376238653039666530353131346435663938623266393734302f7372632f6c6962636f72652f736c6963652f6d6f642e72730000000001d711001200000000000000fce0110001000000000000000000000013d71100150000000000000004e1110001000000000000000000000028d711000f000000000000000ce1110001000000000000000000000037d71100100000000000000014e1110001000000000000000000000047d711000f000000000000001ce1110001000000000000000000000056d71100090000000000000024e111000100000000000000000000005fd7110014000000000000002ce1110001000000000000000000000073d71100100000000000000034e1110001000000000000000000000083d7110016000000000000003ce1110001000000000000000000000099d71100170000000000000044e11100010000000000000000000000b0d7110017000000000000004ce11100010000000000000000000000c7d71100100000000000000054e11100010000000000000000000000d7d711000d000000000000005ce11100010000000000000000000000e4d711000e0000000000000064e11100010000000000000000000000ed29120010000000000000006ce11100010000000000000000000000f2d71100160000000000000074e1110001000000000000000000000008d8110015000000000000007ce111000100000000000000000000001dd811000d0000000000000084e111000100000000000000000000002ad8110015000000000000008ce11100010000000000000096e411003800000077e411001f0000002de411004a00000001e411002c000000efe3110012000000a8e311004700000089e311001f00000067e31100220000003ee311002900000000e311003e000000c7e2110039000000a6e211002100000072e211003400000049e211002900000030e21100190000000de2110023000000f4e1110019000000c5e111002f00000094e111003100000020556e65787065637465642072656c61792d706172656e7420666f7220612063616e64696461746520726563656970742e205061726120646f6573206e6f74206861766520656e6f7567682062616c616e636520746f2070617920666565732e20446973616c6c6f77656420636f646520757067726164652e204e65772076616c69646174696f6e20636f64652077617320746f6f206c617267652e204865616420646174612077617320746f6f206c617267652e2057726f6e6720706172656e74206865616420666f722070617261636861696e20726563656970742e20457874726120756e7461676765642076616c696469747920766f74657320616c6f6e6720776974682063616e6469646174652e20496e76616c6964207369676e61747572652066726f6d2061747465737465722e20417474657374696e672076616c696461746f72206e6f74206f6e207468697320636861696e27732076616c69646174696f6e20647574792e20546865206e756d626572206f66206174746573746174696f6e73206578636565647320746865206e756d626572206f6620617574686f7269746965732e204e6f7420656e6f7567682076616c696469747920766f74657320666f722063616e6469646174652e204e6f2076616c696461746f722067726f757020666f722070617261636861696e2e20546865206d657373616765206f726967696e20697320696e76616c69642e20546865206d6573736167652071756575652069732066756c6c2e204d657373616765732077696c6c206265206164646564207768656e2074686572652069732073706163652e20496e76616c696420636f6c6c61746f722e2043616e64696461746520697320666f7220616e20756e726567697374657265642070617261636861696e2e2050726f706f736564206865616473206d75737420626520617363656e64696e67206f726465722062792070617261636861696e20494420776974686f7574206475706c69636174652e20546f6f206d616e792070617261636861696e2063616e646964617465732e2050617261636861696e206865616473206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b2e0000a001130039000000f305000035000000417574686f726564426c6f636b73000000e8110045000000c10300002200000000e8110045000000dd0300001500000000e8110045000000eb0300001e00000000e8110045000000f40300001800000000e8110045000000f50300001900000000e8110045000000f80300001a00000000e8110045000000fe0300000d000000f5e51100160000001de6110002000000f5e51100160000000be6110012000000696d6f6e6c696e6570616c6c65745f696d5f6f6e6c696e652f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f696d2d6f6e6c696e652f7372632f6c69622e7273536b697070696e6720686561727462656174206174202e204e6f7420612076616c696461746f722e3a20002fe711001c00000001e711002e000000cfe611001a000000e9e6110018000000b3e611000a000000bde61100120000009be611001800000085e611001600000068e611001d0000004661696c656420746f206665746368206e6574776f726b2073746174654661696c656420746f2061637175697265206c6f636b4661696c656420746f207369676e20686561727462656174417574686f726974792020697320616c7265616479206f6e6c696e6548656172746265617420616c72656164792073656e74206174202e2057616974696e6720666f7220696e636c7573696f6e2e546f6f206561726c7920746f2073656e64206865617274626561742c206e657874206578706563746564206174204661696c656420746f207375626d6974207472616e73616374696f6e0098e511005d00000027020000340000007061726974792f696d2d6f6e6c696e652d6865617274626561742f0098e7110008000000a0e7110020000000c0e711000b000000cbe71100030000005b696e6465783a205d205265706f7274696e6720696d2d6f6e6c696e6520617420626c6f636b3a20202873657373696f6e3a20293a200000001313000000000000131300000000001f0000000400000004000000c60000001f0000000400000004000000c60000002f72757374632f323435346136386366626236336161376238653039666530353131346435663938623266393734302f7372632f6c6962616c6c6f632f736c6963652e72730000000000000063d811000400000000000000f8e8110001000000000000000000000010e911000a000000000000000000000067d81100150000000000000060e9110002000000000000000000000090e911000a00000000000000000000007cd811000700000000000000e0e91100010000000000000000000000f8e9110009000000000000000000000083d81100070000000000000040ea110002000000000000000000000070ea11000b0000000000000000000000441912000400000000000000481912001700000006ec11004e0000000013130000000000948c120034000000001313000000000091c212000b0000002deb11000800000035eb1100190000004eeb11001800000066eb11003200000034c312000c0000000000000044191200040000000000000048191200170000000000000001ed1100070000000000000026d912000600000006ec11004e00000054ec11004c000000a0ec11002d0000000013130000000000948c120034000000001313000000000091c212000b0000002deb110008000000cdec11003400000034c312000c0000000000000025a91200030000000000000087e412002300000098eb11005d0000000013130000000000948c120034000000001313000000000091c212000b0000002deb11000800000035eb110019000000f5eb11001100000034c312000c0000000000000084e41200030000000000000087e4120023000000000000004419120004000000000000004819120017000000c8ea1100540000001ceb1100110000000013130000000000948c120034000000001313000000000091c212000b0000002deb11000800000035eb1100190000004eeb11001800000066eb11003200000034c312000c0000002041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c207769746820605369676e656460206f726967696e2066726f6d206120676976656e206163636f756e742e202d204f2831292e202d204c696d697465642073746f726167652072656164732e202d204f6e6520444220777269746520286576656e74292e202d20576569676874206f662064657269766174697665206063616c6c6020657865637574696f6e202b2031302c3030302e2041757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f206b65792e202d204f6e65204442206368616e67652e2041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e20546869732066756e6374696f6e20646f6573206e6f7420636865636b2074686520776569676874206f66207468652063616c6c2c20616e6420696e737465616420616c6c6f777320746865205375646f207573657220746f20737065636966792074686520776569676874206f66207468652063616c6c2e202d2054686520776569676874206f6620746869732063616c6c20697320646566696e6564206279207468652063616c6c65722e5f7765696768745375646f00000000b7c41200030000000000000000000000d0cf12000c000000000000000000000000000000000000000000000000000000000000000013130064ed1100000000000000000074ed11000100000000000000010000001f00000000000000010000004e0000007ced1100210000002054686520604163636f756e74496460206f6620746865207375646f206b65792e00000000000000c2d9110004000000000000000013130000000000000000000000000024ee1100110000000000000000000000c6d911000a00000000000000acee1100010000000000000000000000c4ee1100130000000000000000000000d0d911000f000000000000005cef11000200000000000000000000008cef11001200000000000000e3f411002f000000001313000000000012f51100580000002ef311001a000000001313000000000048f3110035000000001313000000000091c212000b00000010f111000a0000006af511001e00000088f511003f000000c7f5110040000000f8f311000d00000007f611003b00000042f611003900000078f411006b00000034c312000c000000000000007bf21100060000000000000087e4120023000000aaf211002f0000000013130000000000948c1200340000000013130000000000d9f21100550000002ef311001a000000001313000000000048f3110035000000001313000000000091c212000b00000010f111000a0000001af111001e0000007df311003d000000baf311003e000000f8f311000d00000005f411003a0000003ff411003900000078f411006b00000034c312000c000000000000007bf21100060000000000000087e412002300000000000000c70f1200080000000000000081f21100290000001cf011001a0000000013130000000000948c120034000000001313000000000036f01100450000007bf0110040000000bbf011003d0000000013130000000000f8f0110018000000001313000000000091c212000b00000010f111000a0000001af111001e00000038f111004f00000087f1110050000000d7f11100380000000ff211006c00000034c312000c00000020437265617465206120766573746564207472616e736665722e202d2060746172676574603a20546865206163636f756e7420746861742073686f756c64206265207472616e7366657272656420746865207665737465642066756e64732e202d2060616d6f756e74603a2054686520616d6f756e74206f662066756e647320746f207472616e7366657220616e642077696c6c206265207665737465642e202d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e20456d697473206056657374696e6743726561746564602e202d20604f283129602e202d2044625765696768743a20332052656164732c20332057726974657320202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e742c205b53656e646572204163636f756e745d20202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e742c205b53656e646572204163636f756e745d202d2042656e63686d61726b3a203130302e33202b202e333635202a206c20c2b57320286d696e2073717561726520616e616c7973697329202d205573696e672031303020c2b5732066697865642e20417373756d696e67206c657373207468616e203530206c6f636b73206f6e20616e7920757365722c20656c7365207765206d61792077616e7420666163746f7220696e206e756d626572206f66206c6f636b732e74617267657456657374696e67496e666f3c42616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265723e20556e6c6f636b20616e79207665737465642066756e6473206f662061206074617267657460206163636f756e742e202d2060746172676574603a20546865206163636f756e742077686f7365207665737465642066756e64732073686f756c6420626520756e6c6f636b65642e204d75737420686176652066756e6473207374696c6c206c6f636b656420756e6465722074686973206d6f64756c652e20456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e20202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e7420202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e74202d2042656e63686d61726b3a20202020202d20556e6c6f636b65643a2034342e33202b202e323934202a206c20c2b57320286d696e2073717561726520616e616c797369732920202020202d204c6f636b65643a2034382e3136202b202e313033202a206c20c2b57320286d696e2073717561726520616e616c7973697329202d205573696e6720353020c2b5732066697865642e20417373756d696e67206c657373207468616e203530206c6f636b73206f6e20616e7920757365722c20656c7365207765206d61792077616e7420666163746f7220696e206e756d626572206f66206c6f636b732e20556e6c6f636b20616e79207665737465642066756e6473206f66207468652073656e646572206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e6473207374696c6c202d2044625765696768743a20322052656164732c20322057726974657320202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c205b53656e646572204163636f756e745d20202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c205b53656e646572204163636f756e745d20202020202d20556e6c6f636b65643a2034382e3736202b202e303438202a206c20c2b57320286d696e2073717561726520616e616c797369732920202020202d204c6f636b65643a2034342e3433202b202e323834202a206c20c2b57320286d696e2073717561726520616e616c79736973290000000000dfd91100070000000102000000000000d0cf12000c0000000000000081f21100290000000000000000000000000000000000000000131300d4f611000000000000000000e4f611000100000000000000000000001f000000000000000100000038000000ecf611003600000020496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e0000000000005cf711001100000000000000a9f812000c000000000000000013130070f71100000000000000000080f7110001000000000000004d696e5665737465645472616e736665720000001f0000000000000001000000bf00000088f711004700000020546865206d696e696d756d20616d6f756e7420746f206265207472616e7366657272656420746f206372656174652061206e65772076657374696e67207363686564756c652e0000000000bddb11000900000000000000fcf711000200000000000000000000002cf811000a0000000000000000000000bddb11000900000000000000c7f911001900000000000000e0f911000a00000000000000eaf911002f00000091c212000b0000007cf8110048000000c4f811002d0000000013130000000000f1f811002300000014f911002c00000040f911004f0000008ff9110017000000a6f911002100000034c312000c000000202d20436f6d706c65786974793a20604f284b202b20452960207768657265204b206973206c656e677468206f6620604b6579736020616e642045206973206c656e677468206f66202020604865617274626561742e6e6574776f726b5f73746174652e65787465726e616c5f61646472657373602020202d20604f284b29603a206465636f64696e67206f66206c656e67746820604b602020202d20604f284529603a206465636f64696e672f656e636f64696e67206f66206c656e67746820604560202d20446252656164733a2070616c6c65745f73657373696f6e206056616c696461746f7273602c2070616c6c65745f73657373696f6e206043757272656e74496e646578602c20604b657973602c2020206052656365697665644865617274626561747360202d2044625772697465733a2060526563656976656448656172746265617473604865617274626561743c543a3a426c6f636b4e756d6265723e5f7369676e61747572653c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e617475726500000000000000cedb11000e000000000000000000000090d012000e000000000000000000000000000000000000000000000000000000000000000013130004fc110000000000000000007cfb110006000000000000000100000000000000dcdb1100040000000000000000000000acfb1100130000000000000000000000000000000000000000000000000000000000000000131300840412000000000000000000c0fb110001000000000000000100000000000000c8fb1100120000000205050000000000148312000c00000000000000dafb1100090000000000000059c91200070000000000000000131300e4fb11000000000000000000f4fb110002000000000000000000000000000000e0e411000e0000000205050000000000148312000c00000000000000cc8312000e00000000000000c2c4120003000000000000000013130004fc1100000000000000000014fc11000200000000000000010000002bfd11004c000000001313000000000077fd110044000000bbfd110034000000effd1100400000002ffe11004e0000005665633c543a3a417574686f7269747949643e00f7fc11003400000052656365697665644865617274626561747341757468496e646578001f0000000000000001000000c70000009bfc11003c000000d7fc1100200000001f00000000000000010000003400000024fc11004500000069fc11003200000020466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f662060543a3a56616c696461746f7249646020746f20746865206e756d626572206f6620626c6f636b7320617574686f7265642062792074686520676976656e20617574686f726974792e20466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206041757468496e6465786020746f20606f6666636861696e3a3a4f70617175654e6574776f726b5374617465602e205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e2054686520626c6f636b206e756d6265722061667465722077686963682069742773206f6b20746f2073656e64206865617274626561747320696e2063757272656e742073657373696f6e2e2041742074686520626567696e6e696e67206f6620656163682073657373696f6e20776520736574207468697320746f20612076616c756520746861742073686f756c642066616c6c20726f7567686c7920696e20746865206d6964646c65206f66207468652073657373696f6e206475726174696f6e2e20546865206964656120697320746f206669727374207761697420666f72207468652076616c696461746f727320746f2070726f64756365206120626c6f636b20696e207468652063757272656e742073657373696f6e2c20736f20746861742074686520686561727462656174206c61746572206f6e2077696c6c206e6f74206265206e65636573736172792e00000000000000f8d611000900000000000000d8fe1100010000000000000000000000d8221200010000000000000000000000e6d611001200000000000000f0fe110001000000000000000000000008ff11000400000000000000000000003700120005000000000000003c0012001600000000000000beff11000600000000000000c4ff11007300000028ff110040000000001313000000000068ff110046000000aeff1100100000002050726f7669646520612070726f6f66207468617420736f6d652076616c696461746f722068617320636f6d6d69746564206120646f75626c652d766f74652e205468652077656967687420697320303b20696e206f7264657220746f2061766f696420446f53206120605369676e6564457874656e73696f6e602076616c69646174696f6e20697320696d706c656d656e7465642e7265706f7274446f75626c65566f74655265706f72743c3c543a3a4b65794f776e657250726f6f6653797374656d2061730a20202020202020202020202020202020204b65794f776e657250726f6f6653797374656d3c284b65795479706549642c2056616c696461746f724964293e3e3a3a50726f6f663e68656164735665633c417474657374656443616e6469646174653e000000000000d90113000b0000000000000000000000740412001000000000000000000000000000000000000000000000000000000000000000001313008404120000000000000000009404120001000000000000000100000000000000e40113000400000001050000000000002a05130006000000000000004d5e12000e00000000000000000000000000000000000000001313000405120000000000000000009c041200010000000000000000000000000000004fde11000c00000001050000000000002a0513000600000000000000a4041200200000000000000000000000000000000000000000131300c40412000000000000000000d40412000300000000000000010000000000000047de1100080000000105000000000000ec04120018000000000000004d5e12000e0000000000000000000000000000000000000000131300040512000000000000000000140512000200000000000000000000000000000038de11000f0000000000000000000000240512001d0000000000000000000000000000000000000000000000000000000000000000131300440512000000000000000000540512000100000000000000010000000000000087dd11001200000001050000000000002a051300060000000000000090d012000e00000000000000000000000000000000000000001313005c05120000000000000000000013130000000000000000000000000000000000e80113000a00000001050000000000002a05130006000000000000004d5e12000e00000000000000000000000000000000000000001313006c05120000000000000000000013130000000000000000000100000000000000f20113000500000001050000000000002a05130006000000000000006c5e12000800000000000000000000000000000000000000001313007c05120000000000000000008c05120001000000000000000000000000000000f70113001200000001050000000000002a051300060000000000000094051200120000000000000000000000000000000000000000131300a80512000000000000000000b805120002000000000000000100000000000000090213001600000001050000000000002a0513000600000000000000c80512000a0000000000000000000000000000000000000000131300d40512000000000000000000e4051200030000000000000001000000000000001f0213000d00000000000000000000002c6312000b0000000000000000000000000000000000000000000000000000000000000000131300fc05120000000000000000000c061200010000000000000001000000000000002c0213000900000000000000000000002c6312000b0000000000000000000000000000000000000000000000000000000000000000131300140612000000000000000000240612000400000000000000000000005665633c56616c696461746f7249643e1f0000000000000001000000360000005b0a120025000000260a1200350000005061726150617374436f64654d6574613c543a3a426c6f636b4e756d6265723e1f0000000000000001000000c80000006509120052000000b709120052000000090a12001d000000285061726149642c20543a3a426c6f636b4e756d626572291f000000000000000100000038000000060912004e00000054091200110000005665633c285061726149642c20543a3a426c6f636b4e756d626572293e0000001f000000000000000100000036000000dd081200290000001f0000000000000001000000380000001f0000000000000001000000c90000001f000000000000000100000038000000aa081200330000005665633c5570776172644d6573736167653e00001f00000000000000010000003600000031081200470000007808120032000000287533322c207533322900001f0000000000000001000000ca0000004b071200510000009c07120056000000f20712003f0000001f00000000000000010000003600000007071200440000001f00000000000000010000003800000044061200560000009a061200520000000013130000000000ec0612001b0000002060536f6d6560206966207468652070617261636861696e20686561647320676574207570646174656420696e207468697320626c6f636b2c20616c6f6e672077697468207468652070617261636861696e20494473207468617420646964207570646174652e204f72646572656420696e207468652073616d652077617920617320607265676973747261723a3a416374697665602028692e652e20627920506172614964292e20604e6f6e6560206966206e6f742079657420757064617465642e20546865206f726465726564206c697374206f662050617261496473207468617420686176652061206052656c6179446973706174636851756575656020656e7472792e2053697a65206f6620746865206469737061746368207175657565732e205365706172617465642066726f6d2061637475616c206461746120696e206f7264657220746f2061766f696420636f73746c79206465636f64696e67207768656e20636865636b696e6720726563656970742076616c69646974792e204669727374206974656d20696e207475706c652069732074686520636f756e74206f66206d65737361676573207365636f6e642069662074686520746f74616c206c656e6774682028696e20627974657329206f6620746865206d657373616765207061796c6f6164732e204d6573736167657320726561647920746f2062652064697370617463686564206f6e746f207468652072656c617920636861696e2e204974206973207375626a65637420746f20604d41585f4d4553534147455f434f554e546020616e64206057415445524d41524b5f4d4553534147455f53495a45602e20546865206865616473206f66207468652070617261636861696e7320726567697374657265642061742070726573656e742e205061737420636f6465207072756e696e672c20696e206f72646572206f66207072696f726974792e2041637475616c207061737420636f64652c20696e64696361746564206279207468652070617261636861696e20616e642074686520626c6f636b206e756d62657220617420776869636820697420626563616d65206f757464617465642e205061737420636f6465206f662070617261636861696e732e205468652070617261636861696e73207468656d73656c766573206d6179206e6f74206265207265676973746572656420616e796d6f72652c2062757420776520616c736f206b65657020746865697220636f6465206f6e2d636861696e20666f72207468652073616d6520616d6f756e74206f662074696d65206173206f7574646174656420636f646520746f20617373697374207769746820617661696c6162696c6974792e205468652061637469766520636f6465206f6620612063757272656e746c792d726567697374657265642070617261636861696e2e20416c6c20617574686f72697469657327206b65797320617420746865206d6f6d656e742e7c1313005a000000740100001b0000007c1313005a000000670100000d0000007573657220646f6573206e6f74206861766520616e206578697374696e672076657374696e67207363686564756c653b20712e652e642e001f0000000c0000000400000015000000f80a12005b000000090100000d0000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f76657374696e672f7372632f6c69622e7273000000000058d811000b00000000000000700b12000100000000000000780b1200200000002053656e646572206d75737420626520746865205375646f206163636f756e744272616e63682077697468206e6f2073756276616c7565732e20536f6d657468696e672077656e742077726f6e672e757365645f696e646578206f6e6c7920736574206966206f636375706965643b20716564007c1313005a000000b2040000250000007c1313005a000000de040000250000007c1313005a000000290500001c000000496e73657274696f6e206e657665722064656c657465732e7c1313005a0000006202000025000000617373657274696f6e206661696c65643a20216578697374696e675f6b65792e69735f656d7074792829000000000000b8d911000a00000000000000c40c1200010000000000000000000000a1d911001700000000000000cc0c120001000000000000000000000098d911000900000000000000d40c12000100000000000000750d1200220000001e0d120057000000dc0c12004200000020416d6f756e74206265696e67207472616e7366657272656420697320746f6f206c6f7720746f2063726561746520612076657374696e67207363686564756c652e20416e206578697374696e672076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e7420746861742063616e6e6f7420626520636c6f6262657265642e20546865206163636f756e7420676976656e206973206e6f742076657374696e672e0000000000b3db11000a00000000000000d00d1200010000000000000000000000a0db11001300000000000000d80d12000100000000000000f60d120019000000e00d120016000000204475706c696361746564206865617274626561742e204e6f6e206578697374656e74207075626c6963206b65792e617373657274696f6e206661696c65643a2073656c662e6c656e2829203c204341504143495459617373657274696f6e206661696c65643a20656467652e686569676874203d3d2073656c662e686569676874202d2031617373657274696f6e206661696c65643a2073656c662e686569676874203e2030617373657274696f6e206661696c65643a2073656c662e6c656e2829203e203063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75650000e40e120056000000a5040000520000002f72757374632f323435346136386366626236336161376238653039666530353131346435663938623266393734302f7372632f6c6962616c6c6f632f636f6c6c656374696f6e732f62747265652f6e6f64652e72730000e40e120056000000b60400004c000000617373657274696f6e206661696c65643a20656467652e686569676874203d3d2073656c662e6e6f64652e686569676874202d20316d6f72655f6174746573746174696f6e7356524648617368565246526573756c747672662d696e7672662d6f75744368617267655472616e73616374696f6e5061796d656e747363686564756c6563616e63656c7363686564756c655f6e616d656463616e63656c5f6e616d6564000000000074101200090000000000000080101200020000000000000000000000001313000000000000000000000000009010120008000000000000008010120002000000000000000000000000131300000000000000000000000000981012000a00000000000000a41012000300000000000000000000000013130000000000000000005363686564756c6564000000e31012000b000000c2c412000300000043616e63656c6564446973706174636865640000bc10120018000000d41012000f0000007c2e12000e0000005461736b416464726573733c426c6f636b4e756d6265723e4f7074696f6e3c5665633c75383e3e426c6f636b4e756d62657246696e616c697479547261636b6572526563656e7448696e747352616e646f6d6e657373436f6c6c656374697665466c697052616e646f6d4d6174657269616c66696e616c5f68696e742f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f72616e646f6d6e6573732d636f6c6c6563746976652d666c69702f7372632f6c69622e727300001f0000000400000004000000cb000000cc000000cd0000001f00000004000000040000000a0000001f00000004000000040000000e000000506f7374496e666f3a20546f6f4d616e794174746573746174696f6e735570646174654f72646572656448696e74734d656469616e616c77617973206174206c65617374206f6e6520726563656e742073616d706c653b20716564001013120064000000700000002b000000726563656e7420616e64206f72646572656420636f6e7461696e207468652073616d65206974656d733b2071656400001f00000004000000040000000c00000010131200640000007b0000001b0000007072756e696e672064696374617465642062792077696e646f775f73697a6520776869636820697320616c776179732073617475726174656420617420313b20716564001013120064000000960000001100000010131200640000009000000019000000101312006400000091000000190000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f66696e616c6974792d747261636b65722f7372632f6c69622e727300000000ea11120013000000000000009013120001000000000000009813120035000000204d6f7265206174746573746174696f6e732063616e206265206164646564206f6e6c79206f6e636520696e206120626c6f636b2e000000381112006e00000055000000110000005363686564756c65724c6f6f6b75704167656e6461486973746f726963616c53657373696f6e7300ce0000005800000008000000cf000000d0000000ce0000005800000008000000d1000000d2000000d3000000d4000000d5000000d6000000d70000006661696c656420746f20696e7365727420696e746f2074726965000000000000c70f1200080000000000000010151200040000000000000000000000701512000a0000000000000000000000cf0f12000600000000000000c0151200020000000000000000000000f01512000a0000000000000000000000d50f12000e0000000000000040161200050000000000000000000000b81612000a0000000000000000000000e30f12000c0000000000000008171200010000000000000000000000201712000a0000000000000000000000f0181200040000000000000090d012000e00000000000000f41812000e000000000000000219120028000000000000002a19120008000000000000003219120012000000000000004419120004000000000000004819120017000000bd1912001d000000001313000000000091c212000b0000008f17120028000000da19120024000000aec612000d000000aa19120013000000fe19120014000000121a12004f00000034c312000c00000000000000f0181200040000000000000090d012000e000000000000008b4612000500000000000000c2c41200030000005f19120026000000001313000000000091c212000b0000008f171200280000008519120025000000aec612000d000000aa19120013000000f71712001c000000131812005000000034c312000c00000000000000355f1200020000000000000059c912000700000000000000f0181200040000000000000090d012000e00000000000000f41812000e000000000000000219120028000000000000002a191200080000000000000032191200120000000000000044191200040000000000000048191200170000006318120017000000001313000000000091c212000b0000008f171200280000007a18120023000000aec612000d000000dc1712001b000000f71712001c0000009d1812005300000034c312000c00000000000000355f1200020000000000000059c9120007000000701712001f000000001313000000000091c212000b0000008f17120028000000b717120025000000aec612000d000000dc1712001b000000f71712001c000000131812005000000034c312000c0000002043616e63656c2061206e616d6564207363686564756c6564207461736b2e202d2053203d204e756d626572206f6620616c7265616479207363686564756c65642063616c6c73202d2042617365205765696768743a2032342e3931202b20322e393037202a205320c2b57320202020202d20526561643a204167656e64612c204c6f6f6b757020202020202d2057726974653a204167656e64612c204c6f6f6b7570202d2057696c6c20757365206261736520776569676874206f66203130302077686963682073686f756c6420626520676f6f6420666f7220757020746f203330207363686564756c65642063616c6c73205363686564756c652061206e616d6564207461736b2e202d2042617365205765696768743a2032392e36202b202e313539202a205320c2b573202d2057696c6c20757365206261736520776569676874206f662033352077686963682073686f756c6420626520676f6f6420666f72206d6f7265207468616e203330207363686564756c65642063616c6c737768656e6d617962655f706572696f6469634f7074696f6e3c7363686564756c653a3a506572696f643c543a3a426c6f636b4e756d6265723e3e7072696f726974797363686564756c653a3a5072696f7269747963616c6c426f783c3c542061732054726169743e3a3a43616c6c3e2043616e63656c20616e20616e6f6e796d6f75736c79207363686564756c6564207461736b2e202d2042617365205765696768743a2032322e3135202b20322e383639202a205320c2b57320202020202d20526561643a204167656e646120416e6f6e796d6f75736c79207363686564756c652061207461736b2e202d2042617365205765696768743a2032322e3239202b202e313236202a205320c2b57320202020202d2057726974653a204167656e6461202d2057696c6c20757365206261736520776569676874206f662032352077686963682073686f756c6420626520676f6f6420666f7220757020746f203330207363686564756c65642063616c6c734661696c6564546f43616e63656c0000000000ef13120006000000010500000000000090d012000e00000000000000201b12003a00000000000000000000000000000000000000001313005c1b120000000000000000006c1b120001000000000000000100000000000000e913120006000000010500000000000059c912000700000000000000741b12001b0000000000000000000000000000000000000000131300901b12000000000000000000a01b12000100000000000000000000005665633c4f7074696f6e3c5363686564756c65643c3c542061732054726169743e3a3a43616c6c2c20543a3a426c6f636b4e756d6265723e3e3e00001f000000000000000100000036000000e81b1200530000005461736b416464726573733c543a3a426c6f636b4e756d6265723e001f00000000000000010000004b000000a81b120040000000204c6f6f6b75702066726f6d206964656e7469747920746f2074686520626c6f636b206e756d62657220616e6420696e646578206f6620746865207461736b2e204974656d7320746f2062652065786563757465642c20696e64657865642062792074686520626c6f636b206e756d626572207468617420746865792073686f756c64206265206578656375746564206f6e2e4661696c6564546f5363686564756c654661696c656420746f2067656e657261746520686973746f726963616c20616e6365737472792d696e636c7573696f6e2070726f6f662e000000000004a91d12000e000000b71d12000b000000566563746f72206361706163697479206f766572666c6f77521d1200570000004b00000009000000ffffff1f0a1d120013000000381d12001a0000000a1d1200130000001d1d12001b000000617373657274696f6e206661696c65643a2062697473203c3d20726573756c742e6c656e28294361706163697479206f766572666c6f773a20206f766572666c6f777320616c6c6f636174696f6e2073697a6520206f766572666c6f7773206d6178696d756d206c656e677468202f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6269747665632d302e31372e342f7372632f7665632f6170692e7273566563746f72206c656e67746820206f766572666c6f7773200000000000002e1112000a00000000000000f01d1200010000000000000000000000081e1200020000000000000000000000701e12000400000000000000741e120017000000181e12003d000000551e12001b0000002048696e7420746861742074686520617574686f72206f66207468697320626c6f636b207468696e6b732074686520626573742066696e616c697a656420626c6f636b2069732074686520676976656e206e756d6265722e68696e74436f6d706163743c543a3a426c6f636b4e756d6265723e0000000000fd1012000b0000000000000000000000442012001300000000000000000000000000000000000000000000000000000000000000001313006020120000000000000000005820120001000000000000000100000000000000031212000c00000000000000000000004420120013000000000000000000000000000000000000000000000000000000000000000013130060201200000000000000000070201200010000000000000001000000000000000f12120006000000000000000000000090d012000e00000000000000000000000000000000000000000000000000000000000000001313007820120000000000000000008820120001000000000000000100000000000000fd11120006000000000000000000000090d012000e0000000000000000000000000000000000000000000000000000000000000000131300902012000000000000000000a020120001000000000000000000000000000000a82012000b00000000000000000000000fb91200040000000000000000000000000000000000000000000000000000000000000000131300a42412000000000000000000001313000000000000000000010000005665633c543a3a426c6f636b4e756d6265723e00162112000e0000001f00000000000000010000003600000000211200160000001f000000000000000100000034000000f42012000c0000001f000000000000000100000038000000b320120041000000496e697469616c697a65642046696e616c2068696e7420746f206170706c7920696e2074686520626c6f636b2e20604e6f6e6560206d65616e73202273616d6520617320706172656e74222e20546865206d656469616e2e204f72646572656420726563656e742068696e74732e20526563656e742068696e74732e00000000942112000a0000000000000090d012000e0000000000000000131300a02112000000000000000000b0211200010000000000000000000000b82112000d0000000000000090d012000e0000000000000000131300c82112000000000000000000d8211200010000000000000057696e646f7753697a6500001f0000000000000001000000d800000027221200460000005265706f72744c6174656e63790000001f0000000000000001000000d9000000e021120047000000205468652064656c617920616674657220776869636820706f696e74207468696e6773206265636f6d6520737573706963696f75732e2044656661756c7420697320313030302e20546865206e756d626572206f6620726563656e742073616d706c657320746f206b6565702066726f6d207468697320636861696e2e2044656661756c74206973203130312e50617261426c6f636b4174746573746174696f6e73526563656e7450617261426c6f636b73000000000000810f12001100000000000000c0221200010000000000000000000000d82212000100000000000000000000002523120005000000000000002a23120010000000e0221200450000002050726f766964652063616e64696461746520726563656970747320666f722070617261636861696e732c20696e20617363656e64696e67206f726465722062792069642e5f6d6f72654d6f72654174746573746174696f6e730000000000008222120010000000010500000000000090d012000e000000000000004424120011000000000000000000000000000000000000000013130058241200000000000000000068241200020000000000000000000000000000006d22120015000000020506000000000090d012000e00000000000000677212000400000000000000782412001400000000000000001313008c24120000000000000000009c241200010000000000000000000000000000002c0213000900000000000000000000000fb91200040000000000000000000000000000000000000000000000000000000000000000131300a4241200000000000000000000131300000000000000000001000000496e636c75646564426c6f636b733c543e0000001f000000000000000100000038000000de2412003c0000001a25120033000000426c6f636b4174746573746174696f6e733c543e1f000000000000000100000038000000b42412002a0000001f000000000000000100000038000000204174746573746174696f6e73206f6e206120726563656e742070617261636861696e20626c6f636b2e2041206d617070696e672066726f6d206d6f64756c617220626c6f636b206e756d62657220286e2025204174746573746174696f6e506572696f642920746f2073657373696f6e20696e64657820616e6420746865206c697374206f662063616e646964617465206861736865732e5472616e73616374696f6e5061796d656e740000000000b8251200110000000000000000000000c92512000a0000000000000000000000000000000000000000000000000000000000000000131300d42512000000000000000000001313000000000000000000010000004e6578744665654d756c7469706c6965724d756c7469706c696572001f00000000000000010000003c00000000000000542612001200000000000000a9f812000c000000000000000013130068261200000000000000000078261200010000000000000000000000802612000b000000000000008b261200290000000000000000131300b42612000000000000000000c426120001000000000000005472616e73616374696f6e4279746546656500001f0000000000000001000000da0000000f27120043000000576569676874546f4665655665633c576569676874546f466565436f656666696369656e743c42616c616e63654f663c543e3e3e1f0000000000000001000000db000000cc261200430000002054686520706f6c796e6f6d69616c2074686174206973206170706c69656420696e206f7264657220746f20646572697665206665652066726f6d207765696768742e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e000000000000201112000e00000000000000000000008f5012000c0000000000000000000000000000000000000000000000000000000000000000131300ac2712000000000000000000bc2712000300000000000000010000001f000000000000000100000036000000d4271200580000002c28120058000000842812001100000020536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e672062756666657220776974682060626c6f636b5f6e756d626572202520383160206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e416c72656164795570646174656442616448696e74000000000000952812000e00000000000000e4281200010000000000000000000000a32812000700000000000000ec28120001000000000000001829120032000000f4281200240000002046696e616c697a6564206865696768742061626f766520626c6f636b206e756d6265722046696e616c2068696e74206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b73776170646572656769737465725f7061726174687265616473656c6563745f7061726174687265616472656769737465725f706172617468726561647365745f7468726561645f636f756e74646572656769737465725f7061726172656769737465725f7061726150617261416c7265616479457869737473496e76616c6964436861696e4964496e76616c69645468726561644964436f6465546f6f4c617267654865616444617461546f6f4c617267654c696d697450617261746872656164436f6d6d697473496e7374616e636531436f6c6c656374697665496e7374616e636532436f6c6c656374697665000000442a120023000000605f5f49676e6f7265602063616e206e6576657220626520636f6e73747275637465644475706c69636174654f6666656e63655265706f7274496e76616c69644b65794f776e65727368697050726f6f66546f6f536f6f6e4368616e676550656e64696e67526573756d654661696c656450617573654661696c65647265706f72745f65717569766f636174696f6e3a6772616e6470615f617574686f72697469657357726f6e6750726f706f73616c4c656e67746857726f6e6750726f706f73616c576569676874546f6f4d616e7950726f706f73616c73546f6f4561726c79416c7265616479496e697469616c697a65644475706c6963617465566f746557726f6e67496e64657850726f706f73616c4d697373696e674475706c696361746550726f706f73616c7365745f6d656d626572736578656375746570726f706f7365636c6f7365000000000c7112000800000000000000c02c1200040000000000000000000000e02c1200020000000000000000000000f02c12000500000000000000f82c1200050000000000000000000000202d1200020000000000000000000000302d12000800000000000000bc711200010000000000000000000000382d1200010000000000000000000000402d12000b00000000000000bc7112000100000000000000000000004c2d1200010000000000000000000000542d120008000000000000005c2d12000200000000000000000000006c2d1200010000000000000000000000742d12000e000000000000005c2d1200020000000000000000000000842d12000100000000000000000000008c2d12000600000000000000942d1200030000000000000000000000ac2d120001000000000000000eb51200090000008b7312000d0000006772120004000000e52d12000b000000782f120053000000cb2f120010000000566f7465640000000eb512000900000067721200040000000fb9120004000000e52d12000b000000e52d12000b000000f02e120042000000322f120046000000417070726f766564bf2e120031000000446973617070726f766564008a2e120035000000457865637574656467721200040000007c2e12000e0000003b2e1200410000004d656d62657245786563757465640000f02d12004b000000436c6f73656400006772120004000000e52d12000b000000e52d12000b000000b42d12003100000020412070726f706f73616c2077617320636c6f73656420616674657220697473206475726174696f6e207761732075702e4d656d626572436f756e7420412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e4469737061746368526573756c742041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e2041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20604d656d626572436f756e7460292e00ec2f120038000000ea000000240000002f55736572732f6761762f436f72652f706f6c6b61646f742f72756e74696d652f636f6d6d6f6e2f7372632f7265676973747261722e7273ec2f120038000000e90000002200000000446562746f727300000000b32912001100000000000000c8301200010000000000000000000000c42912000e00000000000000d0301200010000000000000000000000d22912000f00000000000000d8301200010000000000000000000000e12912000c00000000000000e0301200010000000000000000000000ed2912001000000000000000e83012000100000000000000523112001a0000003c3112001600000025311200170000000d31120018000000f03012001d00000020496e76616c69642070617261206865616420646174612073697a652e20496e76616c6964207061726120636f64652073697a652e20496e76616c696420706172617468726561642049442e20496e76616c69642070617261636861696e2049442e2050617261636861696e20616c7265616479206578697374732eec2f120038000000730200002d0000004772616e64706146696e616c69747950656e64696e674368616e67655374617465000000ec2f1200380000000902000011000000640000003b32120049000000843212000a0000008e3212000100000070616c6c65745f636f6c6c6563746976652f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f636f6c6c6563746976652f7372632f6c69622e72734e6577206d656d6265727320636f756e742065786365656473206d6178696d756d20616d6f756e74206f66206d656d626572732065787065637465642e202865787065637465643a202c2061637475616c3a20295374616c6c656400001f0000000800000004000000dc000000dd0000000000000000000000de00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f0000000800000004000000dc000000dd0000000000000000000000de00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e657874466f72636564000000000000c02a120013000000000000000035120002000000000000000000000030351200080000000000000000000000023712001200000000000000143712002a000000000000003e3712000f000000000000004d371200100000007035120043000000b33512003e000000f13512003f000000303612001200000000131300000000004236120041000000833612004a000000cd36120035000000205265706f727420766f7465722065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c20766572696679207468652065717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f6620616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63652077696c6c206265207265706f727465642e2053696e63652074686520776569676874206f66207468652065787472696e73696320697320302c20696e206f7264657220746f2061766f696420446f53206279207375626d697373696f6e206f6620696e76616c69642065717569766f636174696f6e207265706f7274732c2061206d616e6461746f7279207072652d76616c69646174696f6e206f66207468652065787472696e73696320697320696d706c656d656e74656420696e206120605369676e6564457874656e73696f6e602e65717569766f636174696f6e5f70726f6f6645717569766f636174696f6e50726f6f663c543a3a486173682c20543a3a426c6f636b4e756d6265723e6b65795f6f776e65725f70726f6f66543a3a4b65794f776e657250726f6f660000000000000098311200050000000000000000000000703912001b00000000000000000000000000000000000000000000000000000000000000001313008c39120000000000000000009c391200010000000000000001000000000000008b3112000d0000000000000000000000a4391200230000000000000000000000000000000000000000000000000000000000000000131300206412000000000000000000c839120001000000000000000000000000000000c83412000a000000000000000000000090d012000e0000000000000000000000000000000000000000000000000000000000000000131300503a12000000000000000000d0391200010000000000000000000000000000008f321200070000000000000000000000d8391200200000000000000000000000000000000000000000000000000000000000000000131300f83912000000000000000000083a120001000000000000000000000000000000103a12000c00000000000000000000001c3a1200050000000000000000000000000000000000000000000000000000000000000000131300243a12000000000000000000343a120002000000000000000100000000000000443a12000c00000001050000000000001c3a12000500000000000000148312000c0000000000000000000000000000000000000000131300503a12000000000000000000603a120004000000000000000000000053746f72656453746174653c543a3a426c6f636b4e756d6265723e001f0000000000000001000000df0000002a3c12002400000053746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723e00f93b120031000000ca3b12002f00000028543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d626572291f00000000000000010000004b000000a63b12002400000043757272656e74536574496453657449640000001f0000000000000001000000420000001e3b120057000000753b120031000000536574496453657373696f6e1f000000000000000100000038000000803a120056000000d63a12001a0000000013130000000000f03a12002e0000002041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f7220776869636820697473206d656d62657273207765726520726573706f6e7369626c652e2054574f582d4e4f54453a2060536574496460206973206e6f7420756e646572207573657220636f6e74726f6c2e20546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c69746965732920696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e20607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e0000000000006e2b12000b000000000000002c3d1200030000000000000000000000743d1200180000000000000000000000792b12000700000000000000343e1200020000000000000000000000643e12000a0000000000000000000000802b12000700000000000000b43e1200030000000000000000000000fc3e12001b00000000000000000000009db612000400000000000000d43f12000300000000000000000000001c4012000c0000000000000000000000872b120005000000000000007c401200040000000000000000000000dc4012001b0000000000000000000000625012000b00000000000000adf2120011000000000000006d5012000500000000000000725012001400000000000000865012000900000000000000e52d12000b000000974c1200210000000013130000000000b84c1200520000000a4d120039000000434d12004e000000914d12002b0000000013130000000000bc4d1200160000000013130000000000d24d120056000000284e120049000000001313000000000091c212000b0000009a4412000a000000714e120015000000864e120039000000bf4e120039000000f84e12002700000090451200060000001f4f12005d0000007c4f12003c000000b84f1200520000000a5012005800000034c312000c000000000000008346120008000000000000007a4b12001e00000000000000b44612000c00000000000000ebea12000c000000984b12003d0000000013130000000000d54b12002b000000001313000000000091c212000b0000009a4412000a000000004c120061000000614c120036000000bf4712000a00000034c312000c000000000000005d4b12000900000000000000664b120014000000000000008346120008000000000000007a4b12001e00000000000000b44612000c00000000000000ebea12000c000000d04712003f00000000131300000000000f48120022000000001313000000000031481200510000008248120016000000001313000000000091c212000b0000009a4412000a000000984812002c000000c244120039000000fb44120038000000c448120032000000f64812003e00000034491200400000009045120006000000744912002e000000a24912003d000000df4912002b0000000a4a1200430000004d4a12002f0000007c4a120037000000b34a12003a000000ed4a120034000000214b120030000000514b12000c00000034c312000c000000000000008346120008000000000000009ed0120007000000000000008b4612000500000000000000af9912001600000000000000c947120007000000000000000fb9120004000000c04612003d0000000013130000000000fd46120024000000001313000000000091c212000b0000009a4412000a00000021471200430000009045120006000000644712002c000000904712002f000000bf4712000a00000034c312000c000000000000008346120008000000000000009ed0120007000000000000008b4612000500000000000000af9912001600000000000000904612001500000000000000a54612000f00000000000000b44612000c00000000000000ebea12000c000000b4411200540000000013130000000000084212005600000000131300000000005e42120053000000b1421200300000000013130000000000e142120053000000344312004a00000000131300000000007e43120063000000e1431200590000003a44120060000000001313000000000091c212000b0000009a4412000a000000a44412001e000000c244120039000000fb441200380000003345120033000000664512002a00000090451200060000009645120044000000da451200600000003a46120038000000724612001100000034c312000c00000020436c6f7365206120766f746520746861742069732065697468657220617070726f7665642c20646973617070726f766564206f722077686f736520766f74696e6720706572696f642068617320656e6465642e204d61792062652063616c6c656420627920616e79207369676e6564206163636f756e7420696e206f7264657220746f2066696e69736820766f74696e6720616e6420636c6f7365207468652070726f706f73616c2e2049662063616c6c6564206265666f72652074686520656e64206f662074686520766f74696e6720706572696f642069742077696c6c206f6e6c7920636c6f73652074686520766f74652069662069742069732068617320656e6f75676820766f74657320746f20626520617070726f766564206f7220646973617070726f7665642e2049662063616c6c65642061667465722074686520656e64206f662074686520766f74696e6720706572696f642061627374656e74696f6e732061726520636f756e7465642061732072656a656374696f6e7320756e6c6573732074686572652069732061207072696d65206d656d6265722073657420616e6420746865207072696d65206d656d626572206361737420616e20617070726f76616c2e202b206070726f706f73616c5f7765696768745f626f756e64603a20546865206d6178696d756d20616d6f756e74206f662077656967687420636f6e73756d656420627920657865637574696e672074686520636c6f7365642070726f706f73616c2e202b20606c656e6774685f626f756e64603a2054686520757070657220626f756e6420666f7220746865206c656e677468206f66207468652070726f706f73616c20696e2073746f726167652e20436865636b656420766961202020202020202020202020202020202020206073746f726167653a3a726561646020736f206974206973206073697a655f6f663a3a3c7533323e2829203d3d203460206c6172676572207468616e207468652070757265206c656e6774682e20232320576569676874202d20604f2842202b204d202b205031202b20503229602077686572653a2020202d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e646564292020202d20604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564292020202d20605031602069732074686520636f6d706c6578697479206f66206070726f706f73616c6020707265696d6167652e2020202d20605032602069732070726f706f73616c2d636f756e742028636f64652d626f756e64656429202d2044423a20202d20322073746f726167652072656164732028604d656d62657273603a20636f64656320604f284d29602c20605072696d65603a20636f64656320604f283129602920202d2033206d75746174696f6e73202860566f74696e67603a20636f64656320604f284d29602c206050726f706f73616c4f66603a20636f64656320604f284229602c206050726f706f73616c73603a20636f64656320604f28503229602920202d20616e79206d75746174696f6e7320646f6e65207768696c6520657865637574696e67206070726f706f73616c6020286050316029202d20757020746f2033206576656e747370726f706f73616c696e64657870726f706f73616c5f7765696768745f626f756e64436f6d706163743c5765696768743e6c656e6774685f626f756e642041646420616e20617965206f72206e617920766f746520666f72207468652073656e64657220746f2074686520676976656e2070726f706f73616c2e205265717569726573207468652073656e64657220746f2062652061206d656d6265722e202d20604f284d296020776865726520604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564292020202d20312073746f72616765207265616420604d656d62657273602028636f64656320604f284d2960292020202d20312073746f72616765206d75746174696f6e2060566f74696e67602028636f64656320604f284d296029202d2031206576656e74617070726f7665204164642061206e65772070726f706f73616c20746f2065697468657220626520766f746564206f6e206f72206578656375746564206469726563746c792e205265717569726573207468652073656e64657220746f206265206d656d6265722e20607468726573686f6c64602064657465726d696e65732077686574686572206070726f706f73616c60206973206578656375746564206469726563746c792028607468726573686f6c64203c20326029206f722070757420757020666f7220766f74696e672e202d20604f2842202b204d202b2050312960206f7220604f2842202b204d202b20503229602077686572653a2020202d206272616e6368696e6720697320696e666c75656e63656420627920607468726573686f6c64602077686572653a20202020202d20605031602069732070726f706f73616c20657865637574696f6e20636f6d706c65786974792028607468726573686f6c64203c2032602920202020202d20605032602069732070726f706f73616c732d636f756e742028636f64652d626f756e646564292028607468726573686f6c64203e3d203260292020202d20312073746f726167652072656164206069735f6d656d626572602028636f64656320604f284d2960292020202d20312073746f726167652072656164206050726f706f73616c4f663a3a636f6e7461696e735f6b6579602028636f64656320604f28312960292020202d20444220616363657373657320696e666c75656e63656420627920607468726573686f6c64603a20202020202d204549544845522073746f7261676520616363657373657320646f6e65206279206070726f706f73616c602028607468726573686f6c64203c2032602920202020202d204f522070726f706f73616c20696e73657274696f6e2028607468726573686f6c64203c3d20326029202020202020202d20312073746f72616765206d75746174696f6e206050726f706f73616c73602028636f64656320604f285032296029202020202020202d20312073746f72616765206d75746174696f6e206050726f706f73616c436f756e74602028636f64656320604f2831296029202020202020202d20312073746f72616765207772697465206050726f706f73616c4f66602028636f64656320604f2842296029202020202020202d20312073746f726167652077726974652060566f74696e67602028636f64656320604f284d2960292020202d2031206576656e747468726573686f6c64436f6d706163743c4d656d626572436f756e743e426f783c3c542061732054726169743c493e3e3a3a50726f706f73616c3e20446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e204f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e202d20604f284d202b2050296020776865726520604d60206d656d626572732d636f756e742028636f64652d626f756e6465642920616e642060506020636f6d706c6578697479206f66206469737061746368696e67206070726f706f73616c60202d2044423a203120726561642028636f64656320604f284d296029202b20444220616363657373206f66206070726f706f73616c60205365742074686520636f6c6c6563746976652773206d656d626572736869702e202d20606e65775f6d656d62657273603a20546865206e6577206d656d626572206c6973742e204265206e69636520746f2074686520636861696e20616e642070726f7669646520697420736f727465642e202d20607072696d65603a20546865207072696d65206d656d6265722077686f736520766f74652073657473207468652064656661756c742e202d20606f6c645f636f756e74603a2054686520757070657220626f756e6420666f72207468652070726576696f7573206e756d626572206f66206d656d6265727320696e2073746f726167652e202020202020202020202020202020205573656420666f722077656967687420657374696d6174696f6e2e20526571756972657320726f6f74206f726967696e2e204e4f54453a20446f6573206e6f7420656e666f7263652074686520657870656374656420604d41585f4d454d4245525360206c696d6974206f6e2074686520616d6f756e74206f66206d656d626572732c20627574202020202020207468652077656967687420657374696d6174696f6e732072656c79206f6e20697420746f20657374696d61746520646973706174636861626c65207765696768742e202d20604f284d50202b204e29602077686572653a2020202d20604d60206f6c642d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564292020202d20604e60206e65772d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564292020202d206050602070726f706f73616c732d636f756e742028636f64652d626f756e646564292020202d20312073746f72616765206d75746174696f6e2028636f64656320604f284d296020726561642c20604f284e29602077726974652920666f722072656164696e6720616e642077726974696e6720746865206d656d626572732020202d20312073746f7261676520726561642028636f64656320604f285029602920666f722072656164696e67207468652070726f706f73616c732020202d206050602073746f72616765206d75746174696f6e732028636f64656320604f284d29602920666f72207570646174696e672074686520766f74657320666f7220656163682070726f706f73616c2020202d20312073746f726167652077726974652028636f64656320604f283129602920666f722064656c6574696e6720746865206f6c6420607072696d656020616e642073657474696e6720746865206e6577206f6e656e65775f6d656d626572737072696d654f7074696f6e3c543a3a4163636f756e7449643e6f6c645f636f756e745665633c543a3a486173683e006c5212002400000050726f706f73616c4f663c542061732054726169743c493e3e3a3a50726f706f73616c003952120033000000566f7465733c543a3a4163636f756e7449642c20543a3a426c6f636b4e756d6265723e000c5212002d000000fa51120012000000ac5112004e0000001c51120057000000735112003900000020546865206d656d6265722077686f2070726f7669646573207468652064656661756c7420766f746520666f7220616e79206f74686572206d656d62657273207468617420646f206e6f7420766f7465206265666f7265207468652074696d656f75742e204966204e6f6e652c207468656e206e6f206d656d6265722068617320746861742070726976696c6567652e205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e2050726f706f73616c7320736f206661722e20566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e2054686520686173686573206f6620746865206163746976652070726f706f73616c732e000000001f6f12000900000000000000000000008f5012000c0000000000000000000000000000000000000000000000000000000000000000131300a054120000000000000000009c50120001000000000000000100000000000000a45012000a00000001060000000000009ed012000700000000000000ae501200190000000000000000000000000000000000000000131300206412000000000000000000c850120001000000000000000000000000000000f7b612000600000001060000000000009ed012000700000000000000d0501200230000000000000000000000000000000000000000131300206412000000000000000000f450120001000000000000000000000000000000a09c12000d0000000000000000000000c2c41200030000000000000000000000000000000000000000000000000000000000000000131300486312000000000000000000fc50120001000000000000000100000000000000f0b61200070000000000000000000000adf21200110000000000000000000000000000000000000000000000000000000000000000131300b054120000000000000000000451120001000000000000000100000000000000f8ab1200050000000000000000000000d0cf12000c00000000000000000000000000000000000000000000000000000000000000001313002064120000000000000000000c5112000200000000000000000000001f0000000000000001000000360000001f00000000000000010000003600000000000000a62912000d00000000000000f455120004000000000000000000000054561200050000000000000000000000972912000f000000000000007c561200010000000000000000000000945612000100000000000000000000008729120010000000000000009c561200010000000000000000000000b4561200050000000000000000000000742912001300000000000000dc5612000200000000000000000000000c5712000800000000000000000000006329120011000000000000004c571200030000000000000000000000945712000500000000000000000000004e291200150000000000000000131300000000000000000000000000bc5712000700000000000000000000004a2912000400000000000000f45712000100000000000000000000000c581200080000000000000000000000355f120002000000000000007e5a12000f000000000000000860120004000000000000000c601200080000000000000055c9120004000000000000004d5e12000e000000000000005b5e120011000000000000006c5e120008000000375f12003e000000755f1200230000000013130000000000985f12003d000000d55f12003300000000000000355f120002000000000000007e5a12000f000000105f120025000000000000000b5f12000500000000000000c2c4120003000000745e1200500000000013130000000000c45e1200260000000013130000000000ea5e1200210000000000000055c9120004000000000000004d5e12000e000000000000005b5e120011000000000000006c5e120008000000e55c12002900000000131300000000000e5d120053000000615d12004e0000000013130000000000af5d12004c000000fb5d12004a000000455e12000800000000000000c55c120003000000000000007e5a12000f00000000000000c85c12000900000000000000d15c12000a00000000000000db5c12000a000000000000009ed0120007000000c85b1200410000000013130000000000095c120050000000595c120057000000b05c1200150000008d5a1200320000000013130000000000bf5a1200480000000013130000000000075b1200560000005d5b120051000000ae5b12001a00000000000000795a120005000000000000007e5a12000f0000004c58120059000000a558120059000000fe5812005700000000131300000000005559120058000000ad59120050000000fd59120056000000535a120026000000205377617020612070617261636861696e207769746820616e6f746865722070617261636861696e206f7220706172617468726561642e20546865206f726967696e206d7573742062652061206050617261636861696e602e2054686520737761702077696c6c2068617070656e206f6e6c7920696620746865726520697320616c726561647920616e206f70706f7369746520737761702070656e64696e672e204966207468657265206973206e6f742c2074686520737761702077696c6c2062652073746f72656420696e207468652070656e64696e67207377617073206d61702c20726561647920666f722061206c6174657220636f6e6669726d61746f727920737761702e20546865206050617261496460732072656d61696e206d617070656420746f207468652073616d652068656164206461746120616e6420636f646520736f2065787465726e616c20636f64652063616e2072656c79206f6e20605061726149646020746f2062652061206c6f6e672d7465726d206964656e746966696572206f662061206e6f74696f6e616c202270617261636861696e222e20486f77657665722c207468656972207363686564756c696e6720696e666f2028692e652e2077686574686572207468657927726520612070617261746872656164206f722070617261636861696e292c2061756374696f6e20696e666f726d6174696f6e20616e64207468652061756374696f6e206465706f736974206172652073776974636865642e6f74686572436f6d706163743c5061726149643e20446572656769737465722061207061726174687265616420616e6420726574726965766520746865206465706f7369742e204d7573742062652073656e742066726f6d2061206050617261636861696e60206f726967696e2077686963682069732063757272656e746c79206120706172617468726561642e20456e737572652074686174206265666f72652063616c6c696e672074686973207468617420616e792066756e647320796f752077616e7420656d70746965642066726f6d2074686520706172617468726561642773206163636f756e74206973206d6f766564206f75743b20616674657220746869732069742077696c6c20626520696d706f737369626c6520746f207265747269657665207468656d2028776974686f757420676f7665726e616e636520696e74657276656e74696f6e292e20506c61636520612062696420666f722061207061726174687265616420746f2062652070726f6772657373656420696e20746865206e65787420626c6f636b2e20546869732069732061206b696e64206f66207370656369616c207472616e73616374696f6e20746861742073686f756c642062652068656176696c79207072696f726974697a656420696e20746865207472616e73616374696f6e20706f6f6c206163636f7264696e6720746f20746865206076616c7565603b206f6e6c792060546872656164436f756e7460206f66207468656d206d61792062652070726573656e74656420696e20616e792073696e676c6520626c6f636b2e5f69645f636f6c6c61746f72436f6c6c61746f7249645f686561645f686173682052656769737465722061207061726174687265616420666f7220696d6d656469617465207573652e204d7573742062652073656e742066726f6d2061205369676e6564206f726967696e20746861742069732061626c6520746f206861766520506172617468726561644465706f7369742072657365727665642e2060636f64656020616e642060696e697469616c5f686561645f646174616020617265207573656420746f20696e697469616c697a6520746865207061726174687265616427732073746174652e20556e6c696b65206072656769737465725f70617261602c20746869732066756e6374696f6e20646f657320636865636b207468617420746865206d6178696d756d20636f64652073697a6520616e64206865616420646174612073697a6520617265207265737065637465642c206173207061726174687265616420726567697374726174696f6e20697320616e2061746f6d696320616374696f6e2e56616c69646174696f6e436f6465696e697469616c5f686561645f64617461486561644461746120526573657420746865206e756d626572206f6620706172617468726561647320746861742063616e2070617920746f206265207363686564756c656420696e20612073696e676c6520626c6f636b2e202d2060636f756e74603a20546865206e756d626572206f662070617261746872656164732e204d7573742062652063616c6c65642066726f6d20526f6f74206f726967696e2e636f756e74204465726567697374657220612070617261636861696e207769746820676976656e206964696420526567697374657220612070617261636861696e207769746820676976656e20636f64652e204d7573742062652063616c6c656420627920726f6f742e204661696c7320696620676976656e20494420697320616c726561647920757365642e20556e6c696b65207468652060526567697374726172602074726169742066756e6374696f6e206f66207468652073616d65206e616d652c207468697320636865636b732074686520636f646520616e642068656164206461746120616761696e73742073697a65206c696d6974732e696e666f50617261496e666f00000000cd0313000a00000000000000000000002c6312000b00000000000000000000000000000000000000000000000000000000000000001313003863120000000000000000000013130000000000000000000100000000000000e00313000b0000000000000000000000c2c412000300000000000000000000000000000000000000000000000000000000000000001313004863120000000000000000005863120001000000000000000100000000000000eb0313000f0000000000000000000000606312001e00000000000000000000000000000000000000000000000000000000000000001313005064120000000000000000008063120002000000000000000100000000000000fa031300060000000000000000000000906312002e0000000000000000000000000000000000000000000000000000000000000000131300c06312000000000000000000d063120006000000000000000100000000000000000413000a00000000000000000000002a05130006000000000000000000000000000000000000000000000000000000000000000013130000641200000000000000000010641200020000000000000001000000000000000a0413000b00000001050000000000002a05130006000000000000002a0513000600000000000000000000000000000000000000001313002064120000000000000000003064120001000000000000000000000000000000150413000500000001050000000000002a05130006000000000000000c60120008000000000000000000000000000000000000000013130038641200000000000000000048641200010000000000000000000000000000001a0413000a0000000000000000000000606312001e00000000000000000000000000000000000000000000000000000000000000001313005064120000000000000000006064120001000000000000000100000000000000353012000700000001050000000000002a0513000600000000000000d0cf12000c0000000000000000000000000000000000000000131300686412000000000000000000786412000100000000000000010000005665633c5061726149643e001f0000000000000001000000360000001f000000000000000100000034000000786712002d0000005665633c5665633c285061726149642c20436f6c6c61746f724964293e3e0000d8661200540000002c6712004c0000005665633c285061726149642c204f7074696f6e3c28436f6c6c61746f7249642c20526574726961626c65293e293e00001f0000000000000001000000360000008c65120057000000e3651200580000003b6612005600000091661200340000000013130000000000c5661200130000001f0000000000000001000000d9000000286512004f00000077651200150000001f0000000000000001000000380000000f651200190000001f000000000000000100000038000000e56412002a0000001f000000000000000100000036000000ab6412003a0000001f00000000000000010000004e000000806412002b0000002055736572732077686f20686176652070616964206120706172617468726561642773206465706f736974205468652063757272656e7420717565756520666f7220706172617468726561647320746861742073686f756c6420626520726574726965642e204d6170206f6620616c6c20726567697374657265642070617261746872656164732f636861696e732e2050656e64696e672073776170206f7065726174696f6e732e20546865206e65787420756e75736564205061726149642076616c75652e2053746172742074686973206869676820696e206f7264657220746f206b656570206c6f77206e756d6265727320666f722073797374656d2d6c6576656c20636861696e732e2050617261746872656164732f636861696e73207363686564756c656420666f7220657865637574696f6e207468697320626c6f636b2e2049662074686520636f6c6c61746f72204944206973207365742c207468656e206120706172746963756c617220636f6c6c61746f722068617320616c7265616479206265656e2063686f73656e20666f7220746865206e65787420626c6f636b2c20616e64206e6f206f7468657220636f6c6c61746f72206d61792070726f766964652074686520626c6f636b2e20496e2074686973206361736520776520616c6c6f772074686520706f73736962696c697479206f662074686520636f6d62696e6174696f6e206265696e67207265747269656420696e2061206c6174657220626c6f636b2c206578707265737365642062792060526574726961626c65602e204f726465726564206279205061726149642e20416e206172726179206f6620746865207175657565206f6620736574206f662074687265616473207363686564756c656420666f722074686520636f6d696e6720626c6f636b733b206f72646572656420627920617363656e64696e6720706172612049442e2054686572652063616e206265206e6f206475706c696361746573206f66207061726120494420696e2065616368206c697374206974656d2e20546865206e756d626572206f66207468726561647320746f207363686564756c652070657220626c6f636b2e00000000000000b52a12000b0000000000000050681200020000000000000000000000a92a12000c00000000000000606812000200000000000000000000009c2a12000d0000000000000070681200010000000000000000000000952a12000700000000000000786812000100000000000000000000007d2a1200180000000000000080681200010000000000000000000000672a12001600000000000000886812000100000000000000fc691200420000003e6a12002a0000008e69120045000000d369120029000000536912003b0000002369120030000000d66812004d0000009068120046000000204120676976656e2065717569766f636174696f6e207265706f72742069732076616c69642062757420616c72656164792070726576696f75736c79207265706f727465642e2041206b6579206f776e6572736869702070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e2043616e6e6f74207369676e616c20666f72636564206368616e676520736f20736f6f6e206166746572206c6173742e20417474656d707420746f207369676e616c204752414e445041206368616e67652077697468206f6e6520616c72656164792070656e64696e672e20417474656d707420746f207369676e616c204752414e44504120726573756d65207768656e2074686520617574686f72697479207365742069736e2774207061757365642028656974686572206c697665206f7220616c72656164792070656e64696e6720726573756d65292e20417474656d707420746f207369676e616c204752414e445041207061757365207768656e2074686520617574686f72697479207365742069736e2774206c697665202865697468657220706175736564206f7220616c72656164792070656e64696e67207061757365292ece0000005800000008000000d1000000d2000000d3000000d4000000d5000000d6000000d7000000a86a12003c000000843212000a0000008e3212000100000057726f6e6720636f756e74207573656420746f20657374696d617465207365745f6d656d62657273207765696768742e202865787065637465643a2000000000eeb512000900000000000000fc6b12000100000000000000000000005d2b12001100000000000000046c12000100000000000000000000004e2b12000f000000000000000c6c1200010000000000000000000000442b12000a00000000000000146c1200010000000000000000000000372b12000d000000000000001c6c1200010000000000000000000000252b12001200000000000000246c12000100000000000000000000001d2b120008000000000000002c6c12000100000000000000000000000d2b12001000000000000000346c1200010000000000000000000000fa2a120013000000000000003c6c1200010000000000000000000000e72a12001300000000000000446c12000100000000000000b36d120018000000936d1200200000007f6d1200140000006e6d120011000000576d120017000000366d120021000000f66c120040000000b66c120040000000816c1200350000004c6c1200350000002054686520676976656e206c656e67746820626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e2054686520676976656e2077656967687420626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e2054686572652063616e206f6e6c792062652061206d6178696d756d206f6620604d617850726f706f73616c7360206163746976652070726f706f73616c732e2054686520636c6f73652063616c6c206973206d61646520746f6f206561726c792c206265666f72652074686520656e64206f662074686520766f74696e672e204d656d626572732061726520616c726561647920696e697469616c697a656421204475706c696361746520766f74652069676e6f726564204d69736d61746368656420696e6465782050726f706f73616c206d757374206578697374204475706c69636174652070726f706f73616c73206e6f7420616c6c6f776564204163636f756e74206973206e6f742061206d656d6265720000000000617474656d707420746f20646976696465206279207a65726f4e6f4b6579734475706c6963617465644b65794e6f4173736f63696174656456616c696461746f724964496e76616c696450726f6f667365745f6b65797370757267655f6b65797353657373696f6e56616c696461746f72734e6578744b6579734b65794f776e65725072656d61747572655374696c6c4f70656e4e6f7446696e646572556e6b6e6f776e546970416c72656164794b6e6f776e526561736f6e546f6f426967496e76616c696450726f706f73616c496e646578496e73756666696369656e7450726f706f7365727342616c616e636570726f706f73655f7370656e6472656a6563745f70726f706f73616c617070726f76655f70726f706f73616c7265706f72745f617765736f6d65726574726163745f7469707469705f6e6577746970636c6f73655f746970547265617375727950726f706f73616c73000000000c7112000800000000000000147112000100000000000000000000001c7112000100000000000000000000002471120008000000000000002c711200010000000000000000000000347112000100000000000000000000003c7112000700000000000000447112000300000000000000000000005c7112000100000000000000000000006471120008000000000000006c7112000200000000000000000000007c7112000100000000000000000000008471120005000000000000002c7112000100000000000000000000008c7112000100000000000000000000009471120008000000000000002c7112000100000000000000000000009c711200010000000000000000000000a471120007000000000000002c711200010000000000000000000000ac711200010000000000000000000000b47112000600000000000000bc711200010000000000000000000000c4711200010000000000000000000000cc7112000a00000000000000bc711200010000000000000000000000d8711200010000000000000000000000e07112000900000000000000ec711200030000000000000000000000047212000100000000000000000000000c7212000c00000000000000bc71120001000000000000000000000018721200010000000000000050726f706f7365648b7312000d000000f27312000e0000005370656e64696e676b72120007000000b87312003a00000041776172646564008b7312000d0000006b721200070000000eb5120009000000987312002000000052656a65637465648b7312000d0000006b721200070000005e7312002d0000004275726e740000003b73120023000000526f6c6c6f766572ef7212004c0000004465706f73697400cf721200200000004e657754697000006772120004000000a972120026000000546970436c6f73696e6700007272120037000000546970436c6f73656400000067721200040000000eb51200090000006b72120007000000457212002200000054697052657472616374656420721200250000002041207469702073756767657374696f6e20686173206265656e207265747261637465642e2041207469702073756767657374696f6e20686173206265656e20636c6f7365642e4861736842616c616e63652041207469702073756767657374696f6e206861732072656163686564207468726573686f6c6420616e6420697320636c6f73696e672e2041206e6577207469702073756767657374696f6e20686173206265656e206f70656e65642e20536f6d652066756e64732068617665206265656e206465706f73697465642e205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20412070726f706f73616c207761732072656a65637465643b2066756e6473207765726520736c61736865642e50726f706f73616c496e64657820536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e204e65772070726f706f73616c2e416c72656164794d656d6265726164645f6d656d626572737761705f6d656d62657272657365745f6d656d626572736368616e67655f6b65797365745f7072696d65636c6561725f7072696d6500000000000000587512000b0000000000000000131300000000000000000000000000647512000100000000000000000000006c7512000d00000000000000001313000000000000000000000000007c751200010000000000000000000000847512000e0000000000000000131300000000000000000000000000947512000100000000000000000000009c7512000c0000000000000000131300000000000000000000000000a8751200010000000000000000000000b07512000a0000000000000000131300000000000000000000000000bc751200010000000000000000000000c47512000500000000000000cc751200010000000000000000000000d475120001000000000000004d656d62657241646465640001771200390000004d656d62657252656d6f766564000000c67612003b0000004d656d626572735377617070656400008f761200370000004d656d62657273526573657449761200460000004b65794368616e6765640000277612002200000044756d6d79000000f87512002f000000dc7512001c000000205068616e746f6d206d656d6265722c206e6576657220757365642e73705f7374643a3a6d61726b65723a3a5068616e746f6d446174613c284163636f756e7449642c204576656e74293e204f6e65206f6620746865206d656d6265727327206b657973206368616e6765642e20546865206d656d62657273686970207761732072657365743b2073656520746865207472616e73616374696f6e20666f722077686f20746865206e6577207365742069732e2054776f206d656d62657273207765726520737761707065643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732072656d6f7665643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732061646465643b2073656520746865207472616e73616374696f6e20666f722077686f2e0000a001130039000000d003000022000000656e74697265206e65775f7365742077617320676976656e20746f206275696c645f737570706f72745f6d61703b20656e20656e747279206d757374206265206372656174656420666f722065616368206974656d3b20716564000084bc1200660000009803000023000000496e636f6e73697374656e74207374617465202d20636f756c646e277420736574746c6520696d62616c616e636520666f722066756e6473207370656e742062792074726561737572795175657565644b6579732c781200610000009e0100001e0000002c78120061000000fc010000290000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f7072696d6974697665732f70687261676d656e2f7372632f6c69622e72730000002c781200610000007801000033000000b078120048000000bb0100002d0000002f72757374632f323435346136386366626236336161376238653039666530353131346435663938623266393734302f7372632f6c6962636f72652f6f70732f61726974682e7273766563746f72207769746820706f736974697665206c656e6774682077696c6c20686176652061206d61783b207165642c78120061000000c6020000190000006974657261746f72207769746820706f736974697665206c656e6774682077696c6c20686176652061206d696e3b2071656400002c78120061000000ca020000190000002c78120061000000f502000016000000e00000001400000004000000e1000000e20000000000000000000000e30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e40000001800000004000000e5000000e60000000000000000000000e70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cc7b12006d00000078000000450000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f737570706f72742f7372632f73746f726167652f67656e657261746f722f6d61702e7273000000000000001f6e12000800000000000000947c1200020000000000000000000000c47c12000e0000000000000000000000276e12000a0000000000000000131300000000000000000000000000347d12000c000000000000000000000071c5120004000000000000007780120007000000000000007e801200050000000000000059c9120007000000387f12003a000000727f120048000000c77d1200310000000013130000000000f87d120035000000001313000000000091c212000b000000ba7f1200150000005a7e120056000000cf7f12003c0000000b801200290000003480120021000000558012002200000034c312000c000000947d120033000000c77d1200310000000013130000000000f87d120035000000001313000000000091c212000b0000002d7e12002d0000005a7e120056000000b07e12003c000000ec7e120029000000157f12002300000034c312000c0000002052656d6f76657320616e792073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c65722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d20436f6d706c65786974793a20604f2831296020696e206e756d626572206f66206b65792074797065732e20202041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f662060543a3a4b6579733a3a6b65795f6964732829602077686963682069732066697865642e202d20446252656164733a2060543a3a56616c696461746f7249644f66602c20604e6578744b657973602c20606f726967696e206163636f756e7460202d2044625772697465733a20604e6578744b657973602c20606f726967696e206163636f756e7460202d20446257726974657320706572206b65792069643a20604b65794f776e646572602053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b657973602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e202d20436f6d706c65786974793a20604f28312960202d20446252656164733a20606f726967696e206163636f756e74602c2060543a3a56616c696461746f7249644f66602c20604e6578744b65797360202d2044625772697465733a20606f726967696e206163636f756e74602c20604e6578744b65797360202d204462526561647320706572206b65792069643a20604b65794f776e657260202d20446257726974657320706572206b65792069643a20604b65794f776e657260543a3a4b65797370726f6f660000000000386e12000a0000000000000000000000ec821200130000000000000000000000000000000000000000000000000000000000000000131300e0ab120000000000000000000083120001000000000000000100000000000000088312000c0000000000000000000000148312000c0000000000000000000000000000000000000000000000000000000000000000131300b09c120000000000000000002083120001000000000000000100000000000000288312000d00000000000000000000000fb912000400000000000000000000000000000000000000000000000000000000000000001313003883120000000000000000004883120002000000000000000100000000000000027812000a0000000000000000000000588312001e0000000000000000000000000000000000000000000000000000000000000000131300788312000000000000000000888312000200000000000000010000000000000098831200120000000000000000000000aa831200080000000000000000000000000000000000000000000000000000000000000000131300209d12000000000000000000b483120003000000000000000100000000000000426e1200080000000105000000000000cc8312000e0000000000000077801200070000000000000000000000000000000000000000131300dc8312000000000000000000ec831200010000000000000000000000000000004a6e1200080000000105000000000000f48312001400000000000000cc8312000e000000000000000000000000000000000000000013130000ac12000000000000000000088412000100000000000000000000005665633c543a3a56616c696461746f7249643e00028612001f00000043757272656e74496e64657853657373696f6e496e646578e48512001e0000005175657565644368616e6765640000001f0000000000000001000000380000006d8512004e000000bb851200290000005665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e00001f000000000000000100000036000000e68412004f000000358512003800000044697361626c656456616c696461746f72735665633c7533323e000079841200200000000013130000000000998412004d000000543a3a56616c696461746f72496400001f0000000000000001000000380000005284120027000000284b65795479706549642c205665633c75383e29108412004200000020546865206f776e6572206f662061206b65792e20546865206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e20496e6469636573206f662064697361626c65642076616c696461746f72732e205468652073657420697320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e732061206e657720736574206f66206964656e7469746965732e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f727320686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e00000000000000bf6e12000d0000000000000084871200020000000000000000000000b4871200090000000000000000000000cc6e12000f00000000000000fc87120001000000000000000000000014881200070000000000000000000000db6e12001000000000000000fc8712000100000000000000000000004c881200080000000000000000000000eb6e12000e000000000000008c881200020000000000000000000000bc881200130000000000000000000000f96e12000b00000000000000548912000100000000000000000000006c891200130000000000000000000000046f12000700000000000000048a12000300000000000000000000004c8a12001600000000000000000000000b6f12000300000000000000fc8a12000200000000000000000000002c8b12001900000000000000000000000e6f1200090000000000000054891200010000000000000000000000f48b1200110000000000000000000000bef212000500000000000000c3f212001500000000000000da9a12000b0000000000000087e4120023000000c59912004b000000109a12004d0000005d9a120015000000001313000000000091c212000b0000002899120013000000729a12002d0000009f9a12003b00000034c312000c00000000000000a49912000b00000000000000af99120016000000e99812003f000000001313000000000091c212000b00000028991200130000003b991200340000006f9912003500000034c312000c00000018981200570000006f9812002b000000001313000000000091c212000b0000009a98120014000000ae98120024000000d29812001700000034c312000c000000000000008c941200060000000000000059c91200070000000000000084e412000300000000000000d0cf12000c00000087961200570000000013130000000000948c1200340000000013130000000000de961200550000003397120035000000001313000000000043921200580000009b92120017000000b29212003b0000000013130000000000ed9212001e000000001313000000000091c212000b00000068971200330000009b97120025000000c097120031000000f19712002700000034c312000c00000000000000f991120004000000000000009ed012000700000092941200550000000013130000000000e79412003800000000131300000000001f951200540000007395120051000000c49512001400000000131300000000000e8d120059000000678d1200580000000013130000000000d895120024000000001313000000000091c212000b000000ba7f120015000000fc951200370000003396120024000000579612003000000034c312000c000000000000008c941200060000000000000059c91200070000000000000084e412000300000000000000d0cf12000c00000000000000fd9112000900000000000000a9f812000c000000069212003d00000000131300000000002f8f120055000000848f12001d000000001313000000000043921200580000009b92120017000000b29212003b00000007901200540000005b901200360000000013130000000000ed9212001e000000001313000000000091c212000b0000000b9312005500000060931200300000009093120042000000d29312004300000015941200390000004e941200200000006e9412001e00000034c312000c00000000000000f991120004000000000000009ed012000700000000000000fd9112000900000000000000a9f812000c000000028f12002d00000000131300000000002f8f120055000000848f12001d00000000131300000000000e8d120059000000a18f120058000000f98f12000e00000007901200540000005b9012003600000000131300000000009190120059000000ea9012000d000000001313000000000091c212000b000000bf8d120039000000f7901200450000001f8e1200400000005f8e12004100000000131300000000003c911200580000009491120035000000c99112001d000000e69112001300000034c312000c0000007c8c1200180000000013130000000000948c1200340000000013130000000000c88c12004600000000131300000000000e8d120059000000678d120058000000001313000000000091c212000b000000bf8d120039000000f88d1200270000001f8e1200400000005f8e120041000000a08e12002b000000cb8e12003700000034c312000c00000020436c6f736520616e64207061796f75742061207469702e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e2054686520746970206964656e74696669656420627920606861736860206d75737420686176652066696e69736865642069747320636f756e74646f776e20706572696f642e202d206068617368603a20546865206964656e74697479206f6620746865206f70656e2074697020666f722077686963682061207469702076616c7565206973206465636c617265642e205468697320697320666f726d65642020206173207468652068617368206f6620746865207475706c65206f6620746865206f726967696e616c207469702060726561736f6e6020616e64207468652062656e6566696369617279206163636f756e742049442e202d20436f6d706c65786974793a20604f285429602077686572652060546020697320746865206e756d626572206f6620746970706572732e2020206465636f64696e6720605469707065726020766563206f66206c656e677468206054602e202020605460206973206368617267656420617320757070657220626f756e6420676976656e2062792060436f6e7461696e734c656e677468426f756e64602e2020205468652061637475616c20636f737420646570656e6473206f6e2074686520696d706c656d656e746174696f6e206f662060543a3a54697070657273602e202d20446252656164733a206054697073602c206054697070657273602c20607469702066696e64657260202d2044625772697465733a2060526561736f6e73602c206054697073602c206054697070657273602c20607469702066696e64657260204465636c6172652061207469702076616c756520666f7220616e20616c72656164792d6f70656e207469702e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062652061206d656d626572206f662074686520605469707065727360207365742e2020206173207468652068617368206f6620746865207475706c65206f66207468652068617368206f6620746865206f726967696e616c207469702060726561736f6e6020616e64207468652062656e65666963696172792020206163636f756e742049442e202d20607469705f76616c7565603a2054686520616d6f756e74206f66207469702074686174207468652073656e64657220776f756c64206c696b6520746f20676976652e20546865206d656469616e2074697020202076616c7565206f662061637469766520746970706572732077696c6c20626520676976656e20746f20746865206077686f602e20456d6974732060546970436c6f73696e676020696620746865207468726573686f6c64206f66207469707065727320686173206265656e207265616368656420616e642074686520636f756e74646f776e20706572696f642068617320737461727465642e2020206465636f64696e6720605469707065726020766563206f66206c656e677468206054602c20696e736572742074697020616e6420636865636b20636c6f73696e672c20202041637475616c6c792077656967687420636f756c64206265206c6f77657220617320697420646570656e6473206f6e20686f77206d616e7920746970732061726520696e20604f70656e5469706020627574206974202020697320776569676874656420617320696620616c6d6f73742066756c6c20692e65206f66206c656e6774682060542d31602e202d20446252656164733a206054697070657273602c20605469707360202d2044625772697465733a20605469707360686173687469705f76616c7565204769766520612074697020666f7220736f6d657468696e67206e65773b206e6f2066696e6465722773206665652077696c6c2062652074616b656e2e202d2060726561736f6e603a2054686520726561736f6e20666f722c206f7220746865207468696e6720746861742064657365727665732c20746865207469703b2067656e6572616c6c7920746869732077696c6c20626520202061205554462d382d656e636f6465642055524c2e202d206077686f603a20546865206163636f756e742077686963682073686f756c6420626520637265646974656420666f7220746865207469702e20456d69747320604e657754697060206966207375636365737366756c2e202d20436f6d706c65786974793a20604f2852202b2054296020776865726520605260206c656e677468206f662060726561736f6e602c2060546020697320746865206e756d626572206f6620746970706572732e2020202d20604f285429603a206465636f64696e6720605469707065726020766563206f66206c656e677468206054602020202020605460206973206368617267656420617320757070657220626f756e6420676976656e2062792060436f6e7461696e734c656e677468426f756e64602e20202020205468652061637475616c20636f737420646570656e6473206f6e2074686520696d706c656d656e746174696f6e206f662060543a3a54697070657273602e2020202d20604f285229603a2068617368696e6720616e6420656e636f64696e67206f6620726561736f6e206f66206c656e67746820605260202d20446252656164733a206054697070657273602c2060526561736f6e7360202d2044625772697465733a2060526561736f6e73602c20605469707360726561736f6e20526574726163742061207072696f72207469702d7265706f72742066726f6d20607265706f72745f617765736f6d65602c20616e642063616e63656c207468652070726f63657373206f662074697070696e672e204966207375636365737366756c2c20746865206f726967696e616c206465706f7369742077696c6c20626520756e72657365727665642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642074686520746970206964656e74696669656420627920606861736860206d7573742068617665206265656e207265706f7274656420627920746865207369676e696e67206163636f756e74207468726f75676820607265706f72745f617765736f6d65602028616e64206e6f74207468726f75676820607469705f6e657760292e20456d697473206054697052657472616374656460206966207375636365737366756c2e2020202d20446570656e6473206f6e20746865206c656e677468206f662060543a3a48617368602077686963682069732066697865642e202d20446252656164733a206054697073602c20606f726967696e206163636f756e7460202d2044625772697465733a2060526561736f6e73602c206054697073602c20606f726967696e206163636f756e7460205265706f727420736f6d657468696e672060726561736f6e60207468617420646573657276657320612074697020616e6420636c61696d20616e79206576656e7475616c207468652066696e6465722773206665652e205061796d656e743a20605469705265706f72744465706f73697442617365602077696c6c2062652072657365727665642066726f6d20746865206f726967696e206163636f756e742c2061732077656c6c20617320605469705265706f72744465706f736974506572427974656020666f722065616368206279746520696e2060726561736f6e602e202d20436f6d706c65786974793a20604f2852296020776865726520605260206c656e677468206f662060726561736f6e602e2020202d20656e636f64696e6720616e642068617368696e67206f662027726561736f6e27202d20446252656164733a2060526561736f6e73602c206054697073602c206077686f206163636f756e74206461746160202d2044625772697465733a206054697073602c206077686f206163636f756e7420646174616020417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e202d20436f6d706c65786974793a204f2831292e202d20446252656164733a206050726f706f73616c73602c2060417070726f76616c7360202d20446257726974653a2060417070726f76616c73602052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e202d20436f6d706c65786974793a204f283129202d20446252656164733a206050726f706f73616c73602c206072656a65637465642070726f706f736572206163636f756e7460202d2044625772697465733a206050726f706f73616c73602c206072656a65637465642070726f706f736572206163636f756e746070726f706f73616c5f6964436f6d706163743c50726f706f73616c496e6465783e2050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e202d20446252656164733a206050726f706f73616c436f756e74602c20606f726967696e206163636f756e7460202d2044625772697465733a206050726f706f73616c436f756e74602c206050726f706f73616c73602c20606f726967696e206163636f756e746062656e656669636961727900000000000000a09c12000d00000000000000000000008b7312000d0000000000000000000000000000000000000000000000000000000000000000131300b09c12000000000000000000c09c1200010000000000000001000000000000001f6f12000900000001050000000000008b7312000d00000000000000c89c1200240000000000000000000000000000000000000000131300ec9c12000000000000000000fc9c120001000000000000000000000000000000049d12000900000000000000000000000d9d1200120000000000000000000000000000000000000000000000000000000000000000131300209d12000000000000000000309d120001000000000000000100000000000000389d12000400000001050000000000009ed0120007000000000000003c9d12003c000000000000000000000000000000000000000013130000ac12000000000000000000789d120003000000000000000000000000000000909d12000700000001060000000000009ed01200070000000000000059c91200070000000000000000000000000000000000000000131300989d12000000000000000000a89d120002000000000000000000000050726f706f73616c436f756e740000001f000000000000000100000034000000849f12002900000050726f706f73616c3c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e1f000000000000000100000038000000659f12001f000000417070726f76616c735665633c50726f706f73616c496e6465783e001f000000000000000100000036000000279f12003e000000546970734f70656e5469703c543a3a4163636f756e7449642c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265722c20543a3a486173683e629e120056000000b89e12004f000000079f120020000000526561736f6e73001f0000000000000001000000c7000000b89d1200520000000a9e1200580000002053696d706c6520707265696d616765206c6f6f6b75702066726f6d2074686520726561736f6e2773206861736820746f20746865206f726967696e616c20646174612e20416761696e2c2068617320616e20696e73656375726520656e756d657261626c6520686173682073696e636520746865206b65792069732067756172616e7465656420746f2062652074686520726573756c74206f6620612073656375726520686173682e2054697073207468617420617265206e6f742079657420636f6d706c657465642e204b65796564206279207468652068617368206f66206028726561736f6e2c2077686f29602066726f6d207468652076616c75652e2054686973206861732074686520696e73656375726520656e756d657261626c6520686173682066756e6374696f6e2073696e636520746865206b657920697473656c6620697320616c72656164792067756172616e7465656420746f20626520612073656375726520686173682e2050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e00000000000000a8a112000c00000000000000b4a11200070000000000000000131300bca112000000000000000000cca11200020000000000000000000000dca112001300000000000000a9f812000c0000000000000000131300f0a11200000000000000000000a2120001000000000000000000000008a212000b0000000000000090d012000e000000000000000013130014a21200000000000000000024a212000100000000000000000000002ca212000400000000000000b4a1120007000000000000000013130030a21200000000000000000040a2120001000000000000000000000048a212000c0000000000000090d012000e000000000000000013130054a21200000000000000000064a212000100000000000000000000006ca212000d0000000000000079a2120007000000000000000013130080a21200000000000000000090a2120001000000000000000000000098a212001400000000000000a9f812000c0000000000000000131300aca212000000000000000000bca21200010000000000000000000000c4a212001700000000000000a9f812000c0000000000000000131300dca212000000000000000000eca2120001000000000000000000000040f91200080000000000000040f91200080000000000000000131300f4a21200000000000000000004a31200010000000000000050726f706f73616c426f6e645065726d696c6c001f0000000000000001000000e80000001ea512005500000073a512004400000050726f706f73616c426f6e644d696e696d756d001f0000000000000001000000bf000000cca41200520000005370656e64506572696f64001f0000000000000001000000e9000000aaa41200220000004275726e1f0000000000000001000000ea00000066a4120044000000546970436f756e74646f776e1f0000000000000001000000eb00000015a412005100000054697046696e6465727346656550657263656e741f0000000000000001000000ec000000c9a312004c0000005469705265706f72744465706f736974426173651f00000000000000010000004800000094a31200350000005469705265706f72744465706f73697450657242797465001f0000000000000001000000c200000052a31200420000001f0000000000000001000000ed0000000ca3120046000000205468652074726561737572792773206d6f64756c652069642c207573656420666f72206465726976696e672069747320736f7665726569676e206163636f756e742049442e2054686520616d6f756e742068656c64206f6e206465706f7369742070657220627974652077697468696e2074686520746970207265706f727420726561736f6e2e2054686520616d6f756e742068656c64206f6e206465706f73697420666f7220706c6163696e67206120746970207265706f72742e2054686520616d6f756e74206f66207468652066696e616c2074697020776869636820676f657320746f20746865206f726967696e616c207265706f72746572206f6620746865207469702e2054686520706572696f6420666f722077686963682061207469702072656d61696e73206f70656e20616674657220697320686173206163686965766564207468726573686f6c6420746970706572732e2050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e204672616374696f6e206f6620612070726f706f73616c27732076616c756520746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c616365207468652070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f6573206e6f742e00000000000d7412000a00000000000000eca6120001000000000000000000000004a71200030000000000000000000000e3b612000d00000000000000eca612000100000000000000000000001ca71200030000000000000000000000177412000b0000000000000034a7120002000000000000000000000064a71200050000000000000000000000227412000d000000000000008ca71200010000000000000000000000a4a712000400000000000000000000002f7412000a00000000000000c4a71200010000000000000000000000dca71200050000000000000000000000397412000900000000000000eca6120001000000000000000000000004a81200010000000000000000000000427412000b00000000000000001313000000000000000000000000000ca8120001000000000000000000000084e412000300000000000000d0cf12000c000000ceaa12001f0000000013130000000000edaa12002d0000007aaa12002400000000131300000000009eaa1200300000000000000071aa12000600000000000000d0cf12000c0000000000000077aa12000300000000000000d0cf12000c000000cfa91200300000000013130000000000ffa912002e00000000131300000000002daa12004400000000000000c8a912000700000000000000adf212001100000028a91200560000007ea912001b000000001313000000000099a912002f0000000000000025a912000300000000000000d0cf12000c0000006aa81200360000000013130000000000a0a812003d0000000013130000000000dda81200480000003aa812003000000014a81200260000002052656d6f766520746865207072696d65206d656d626572206966206974206578697374732e2053657420746865207072696d65206d656d6265722e204d75737420626520612063757272656e74206d656d6265722e2053776170206f7574207468652073656e64696e67206d656d62657220666f7220736f6d65206f74686572206b657920606e6577602e204d6179206f6e6c792062652063616c6c65642066726f6d20605369676e656460206f726967696e206f6620612063757272656e74206d656d6265722e205072696d65206d656d62657273686970206973207061737365642066726f6d20746865206f726967696e206163636f756e7420746f20606e6577602c20696620657874616e742e6e6577204368616e676520746865206d656d6265727368697020746f2061206e6577207365742c20646973726567617264696e6720746865206578697374696e67206d656d626572736869702e204265206e69636520616e64207061737320606d656d6265727360207072652d736f727465642e204d6179206f6e6c792062652063616c6c65642066726f6d206052657365744f726967696e60206f7220726f6f742e6d656d626572732053776170206f7574206f6e65206d656d626572206072656d6f76656020666f7220616e6f746865722060616464602e204d6179206f6e6c792062652063616c6c65642066726f6d2060537761704f726967696e60206f7220726f6f742e205072696d65206d656d62657273686970206973202a6e6f742a207061737365642066726f6d206072656d6f76656020746f2060616464602c20696620657874616e742e72656d6f76656164642052656d6f76652061206d656d626572206077686f602066726f6d20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d206052656d6f76654f726967696e60206f7220726f6f742e204164642061206d656d626572206077686f6020746f20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d20604164644f726967696e60206f7220726f6f742e496e7374616e6365314d656d6265727368697000000000000000f0b61200070000000000000000000000adf21200110000000000000000000000000000000000000000000000000000000000000000131300e0ab12000000000000000000f0ab120001000000000000000100000000000000f8ab1200050000000000000000000000d0cf12000c000000000000000000000000000000000000000000000000000000000000000013130000ac1200000000000000000010ac12000100000000000000000000001f00000000000000010000003600000041ac1200320000005072696d650000001f00000000000000010000003800000018ac120029000000205468652063757272656e74207072696d65206d656d6265722c206966206f6e65206578697374732e205468652063757272656e74206d656d626572736869702c2073746f72656420617320616e206f726465726564205665632e0094ac12005c000000710200001800000094ac12005c0000009d0200001a0000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f74726561737572792f7372632f6c69622e727300000000136e12000c0000000000000060ad1200010000000000000000000000fc6d1200170000000000000068ad1200010000000000000000000000ef6d12000d0000000000000070ad1200010000000000000000000000e96d1200060000000000000078ad12000100000000000000ecad120019000000c4ad120028000000aaad12001a00000080ad12002a000000204e6f206b65797320617265206173736f63696174656420776974682074686973206163636f756e742e2052656769737465726564206475706c6963617465206b65792e204e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e20496e76616c6964206f776e6572736869702070726f6f662e00000000000000a36e12001c00000000000000e8ae12000100000000000000000000008f6e12001400000000000000f0ae1200010000000000000000000000836e12000c00000000000000f8ae1200010000000000000000000000776e12000c0000000000000000af12000100000000000000000000006d6e12000a0000000000000008af1200010000000000000000000000646e1200090000000000000010af12000100000000000000000000005b6e1200090000000000000018af1200010000000000000000000000526e1200090000000000000020af1200010000000000000081b012001f00000066b012001b00000044b012002200000021b012002300000008b0120019000000c0af12004800000075af12004b00000028af12004d00000020546865207469702063616e6e6f7420626520636c61696d65642f636c6f73656420626563617573652069742773207374696c6c20696e2074686520636f756e74646f776e20706572696f642e20546865207469702063616e6e6f7420626520636c61696d65642f636c6f736564206265636175736520746865726520617265206e6f7420656e6f7567682074697070657273207965742e20546865206163636f756e7420617474656d7074696e6720746f20726574726163742074686520746970206973206e6f74207468652066696e646572206f6620746865207469702e2054686520746970206861736820697320756e6b6e6f776e2e20546865207469702077617320616c726561647920666f756e642f737461727465642e2054686520726561736f6e20676976656e206973206a75737420746f6f206269672e204e6f2070726f706f73616c206174207468617420696e6465782e2050726f706f73657227732062616c616e636520697320746f6f206c6f772ec0b012005e000000ad0000000d000000c0b012005e000000de000000110000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f6d656d626572736869702f7372632f6c69622e72736e6f6e652076616c756573206172652066696c7465726564206f757420696e2070726576696f7573206c6f6769633b2071656400000064b112003400000062030000250000002f55736572732f6761762f436f72652f706f6c6b61646f742f72756e74696d652f636f6d6d6f6e2f7372632f736c6f74732e7273a0b112002a000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a200000d4b11200230000005f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e436865636b457261436865636b576569676874436865636b5370656356657273696f6e436865636b4e6f6e6365436865636b547856657273696f6e436865636b47656e657369734e6f6e5a65726f526566436f756e744e6f6e44656661756c74436f6d706f736974654661696c6564546f4578747261637452756e74696d6556657273696f6e5370656356657273696f6e4e65656473546f496e637265617365496e76616c6964537065634e616d653a65787472696e7369635f696e64657866696c6c5f626c6f636b72656d61726b7365745f686561705f70616765737365745f636f64657365745f636f64655f776974686f75745f636865636b737365745f6368616e6765735f747269655f636f6e6669677365745f73746f726167656b696c6c5f73746f726167656b696c6c5f7072656669787375696369646553797374656d4163636f756e74426c6f636b486173684e756d626572506172656e744861736845787472696e73696373526f6f74446967657374000000000000004cb4120010000000000000005cb4120001000000000000000000000064b412000100000000000000000000006cb412000f000000000000007cb412000200000000000000000000008cb4120001000000000000000000000094b412000b0000000000000000131300000000000000000000000000a0b41200010000000000000000000000a8b412000a00000000000000b4b41200010000000000000000000000bcb41200010000000000000000000000c4b412000d00000000000000b4b41200010000000000000000000000d4b41200010000000000000045787472696e7369635375636365737341b512000c0000004db512002500000045787472696e7369634661696c656400500b13000d00000041b512000c0000002cb5120015000000436f6465557064617465640017b51200150000004e65774163636f756e7400000eb5120009000000f3b412001b0000004b696c6c65644163636f756e74000000dcb412001700000020416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e4163636f756e74496420603a636f6465602077617320757064617465642e20416e2065787472696e736963206661696c65642e4469737061746368496e666f20416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e00007cb512001a0000004552524f523a20436f727275707465642073746174652061742050687261676d656e456c656374696f6e496e76616c69645265706c6163656d656e74496e76616c696452656e6f756e63696e67496e76616c6964566f7465436f756e74496e76616c696443616e646964617465436f756e744e6f744d656d626572496e73756666696369656e7443616e64696461746546756e647352756e6e65725375626d69744d656d6265725375626d69744475706c69636174656443616e6469646174655265706f727453656c664d7573744265566f746572556e61626c65546f506179426f6e644c6f7742616c616e63654d6178696d756d566f7465734578636565646564546f6f4d616e79566f7465734e6f566f746573556e61626c65546f566f7465766f746572656d6f76655f766f7465727265706f72745f646566756e63745f766f7465727375626d69745f63616e64696461637972656e6f756e63655f63616e64696461637972656d6f76655f6d656d6265724d656d62657273566f74696e6700000000000000dcb712000700000000000000e4b71200010000000000000000000000ecb712000400000000000000000000000cb8120009000000000000000013130000000000000000000000000018b8120002000000000000000000000028b812000c00000000000000b4b4120001000000000000000000000034b8120002000000000000000000000044b812000f00000000000000b4b4120001000000000000000000000054b812000100000000000000000000005cb812000d000000000000006cb8120003000000000000000000000084b8120002000000000000004e65775465726d0071bb12001900000017ba1200560000006dba120056000000c3ba1200580000001bbb120056000000456d7074795465726d00000099b912004d000000e6b91200310000004d656d6265724b69636b65643bb91200510000008cb912000d0000004d656d62657252656e6f756e6365640013b9120028000000566f7465725265706f727465640000000eb51200090000000eb51200090000000fb912000400000094b8120058000000ecb8120023000000204120766f7465722028666972737420656c656d656e742920776173207265706f72746564202862797420746865207365636f6e6420656c656d656e742920776974682074686520746865207265706f7274206265696e67207375636365737366756c206f72206e6f742028746869726420656c656d656e74292e626f6f6c2041206d656d626572206861732072656e6f756e6365642074686569722063616e6469646163792e2041206d656d62657220686173206265656e2072656d6f7665642e20546869732073686f756c6420616c7761797320626520666f6c6c6f7765642062792065697468657220604e65775465726d60206f742060456d7074795465726d602e204e6f20286f72206e6f7420656e6f756768292063616e64696461746573206578697374656420666f72207468697320726f756e642e205468697320697320646966666572656e742066726f6d20604e65775465726d285b5d29602e2053656520746865206465736372697074696f6e206f6620604e65775465726d602e2041206e6577207465726d2077697468206e6577206d656d626572732e205468697320696e64696361746573207468617420656e6f7567682063616e64696461746573206578697374656420746f2072756e2074686520656c656374696f6e2c206e6f74207468617420656e6f756768206861766520686173206265656e20656c65637465642e2054686520696e6e65722076616c7565206d757374206265206578616d696e656420666f72207468697320707572706f73652e204120604e65775465726d285b5d296020696e64696361746573207468617420736f6d652063616e6469646174657320676f7420746865697220626f6e6420736c617368656420616e64206e6f6e65207765726520656c65637465642c207768696c73742060456d7074795465726d60206d65616e732074686174206e6f2063616e64696461746573206578697374656420746f20626567696e20776974682e5665633c284163636f756e7449642c2042616c616e6365293e00001f000000000000000100000023000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f646550726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b20716564000000000000000000000000000010bc12003d000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b207165640000000000000000000000000000000000000043616e6469646174657352756e6e65727355700084bc120066000000b0030000190000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f656c656374696f6e732d70687261676d656e2f7372632f6c69622e72734576656e74734576656e74546f706963730000000000b6b212000a00000000000000b4be1200010000000000000000000000ccbe1200010000000000000000000000c0b212000600000000000000d4be1200010000000000000000000000ecbe1200070000000000000000000000c6b212000e0000000000000024bf12000100000000000000000000003cbf1200080000000000000000000000d4b2120008000000000000007cbf120001000000000000000000000094bf12000a0000000000000000000000dcb2120017000000000000007cbf1200010000000000000000000000e4bf1200080000000000000000000000f3b21200170000000000000024c012000100000000000000000000003cc012000a00000000000000000000000ab312000b000000000000008cc01200010000000000000000000000a4c0120008000000000000000000000015b312000c00000000000000e4c01200010000000000000000000000fcc0120008000000000000000000000021b312000b000000000000003cc112000200000000000000000000006cc112000b00000000000000000000002cb31200070000000000000000131300000000000000000000000000c4c112000a00000000000000000000009bca12000600000000000000a1ca12000700000059ca1200420000000000000052ca1200070000000000000059c9120007000000ebc912001b000000001313000000000091c212000b0000009cc212000900000006ca1200380000003eca12001400000034c312000c00000000000000e3c912000500000000000000e8c912000300000060c912003f000000001313000000000091c212000b0000009cc21200090000009fc9120013000000b2c9120019000000cbc912001800000034c312000c0000000000000055c91200040000000000000059c91200070000000dc812001a000000001313000000000091c212000b00000027c812004d00000083c712002200000074c812005e000000a5c712000b000000d2c812005f00000031c912002400000034c312000c00000018c7120047000000001313000000000091c212000b0000005fc712002400000083c7120022000000a5c712000b000000b0c712005d00000034c312000c00000000000000e5c612001300000000000000f8c61200200000000bc6120028000000001313000000000091c212000b0000009cc212000900000033c612002c0000005fc612003600000095c6120019000000aec612000d000000bbc612002a00000034c312000c00000000000000f9c512000500000000000000fec512000d0000007dc512001b000000001313000000000091c212000b00000098c5120025000000bdc512001f000000dcc512001d00000057c512001a00000034c312000c0000000000000071c51200040000000000000075c5120008000000c5c412001e000000001313000000000091c212000b000000e3c412003f00000022c51200190000003bc512001c00000057c512001a00000034c312000c00000000000000b1c412000600000000000000b7c412000300000000000000bac412000800000000000000c2c412000300000040c3120045000000001313000000000085c312004f000000d4c3120050000000001313000000000091c212000b00000024c41200370000005bc412001900000074c412001d00000091c412002000000034c312000c00000014c21200590000006dc2120024000000001313000000000091c212000b0000009cc2120009000000a5c212001f000000c4c2120015000000d9c2120017000000f0c212004400000034c312000c000000204b696c6c207468652073656e64696e67206163636f756e742c20617373756d696e6720746865726520617265206e6f207265666572656e636573206f75747374616e64696e6720616e642074686520636f6d706f73697465206461746120697320657175616c20746f206974732064656661756c742076616c75652e2023203c7765696768743e202d20604f28312960202d20312073746f72616765207265616420616e642064656c6574696f6e2e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2042617365205765696768743a20382e36323620c2b573204e6f2044422052656164206f72205772697465206f7065726174696f6e7320626563617573652063616c6c657220697320616c726561647920696e206f7665726c61792023203c2f7765696768743e204b696c6c20616c6c2073746f72616765206974656d7320776974682061206b657920746861742073746172747320776974682074686520676976656e207072656669782e202a2a4e4f54453a2a2a2057652072656c79206f6e2074686520526f6f74206f726967696e20746f2070726f7669646520757320746865206e756d626572206f66207375626b65797320756e6465722074686520707265666978207765206172652072656d6f76696e6720746f2061636375726174656c792063616c63756c6174652074686520776569676874206f6620746869732066756e6374696f6e2e202d20604f285029602077686572652060506020616d6f756e74206f66206b657973207769746820707265666978206070726566697860202d206050602073746f726167652064656c6574696f6e732e202d2042617365205765696768743a20302e383334202a205020c2b573202d205772697465733a204e756d626572206f66207375626b657973202b20317072656669784b65795f7375626b657973753332204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e202d20604f28494b296020776865726520604960206c656e677468206f6620606b6579736020616e6420604b60206c656e677468206f66206f6e65206b6579202d206049602073746f726167652064656c6574696f6e732e202d2042617365205765696768743a202e333738202a206920c2b573202d205772697465733a204e756d626572206f66206974656d736b6579735665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e202d20604f2849296020776865726520604960206c656e677468206f6620606974656d7360202d206049602073746f72616765207772697465732028604f28312960292e202d2042617365205765696768743a20302e353638202a206920c2b5736974656d735665633c4b657956616c75653e2053657420746865206e6577206368616e676573207472696520636f6e66696775726174696f6e2e202d20312073746f72616765207772697465206f722064656c6574652028636f64656320604f28312960292e202d20312063616c6c20746f20606465706f7369745f6c6f67603a20557365732060617070656e6460204150492c20736f204f283129202d2042617365205765696768743a20372e32313820c2b573202d204442205765696768743a20202020202d205772697465733a204368616e67657320547269652c2053797374656d204469676573746368616e6765735f747269655f636f6e6669674f7074696f6e3c4368616e67657354726965436f6e66696775726174696f6e3e2053657420746865206e65772072756e74696d6520636f646520776974686f757420646f696e6720616e7920636865636b73206f662074686520676976656e2060636f6465602e202d20604f2843296020776865726520604360206c656e677468206f662060636f646560202d20312073746f726167652077726974652028636f64656320604f28432960292e202d2031206576656e742e2054686520776569676874206f6620746869732066756e6374696f6e20697320646570656e64656e74206f6e207468652072756e74696d652e2057652077696c6c207472656174207468697320617320612066756c6c20626c6f636b2e2053657420746865206e65772072756e74696d6520636f64652e202d20604f2843202b2053296020776865726520604360206c656e677468206f662060636f64656020616e642060536020636f6d706c6578697479206f66206063616e5f7365745f636f646560202d20312063616c6c20746f206063616e5f7365745f636f6465603a20604f28532960202863616c6c73206073705f696f3a3a6d6973633a3a72756e74696d655f76657273696f6e6020776869636820697320657870656e73697665292e2054686520776569676874206f6620746869732066756e6374696f6e20697320646570656e64656e74206f6e207468652072756e74696d652c206275742067656e6572616c6c792074686973206973207665727920657870656e736976652e2057652077696c6c207472656174207468697320617320612066756c6c20626c6f636b2e636f64655665633c75383e2053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e202d20312073746f726167652077726974652e202d2042617365205765696768743a20312e34303520c2b573202d203120777269746520746f20484541505f50414745537061676573753634204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e202d2042617365205765696768743a20302e36363520c2b5732c20696e646570656e64656e74206f662072656d61726b206c656e6774682e202d204e6f204442206f7065726174696f6e732e5f72656d61726b204120646973706174636820746861742077696c6c2066696c6c2074686520626c6f636b2077656967687420757020746f2074686520676976656e20726174696f2e5f726174696f50657262696c6c0000000039b31200070000000102000000000000d0cf12000c00000000000000dccf120025000000000000000000000000000000000000000013130004d01200000000000000000014d01200010000000000000001000000000000001cd012000e0000000000000000000000c2c4120003000000000000000000000000000000000000000000000000000000000000000013130078d0120000000000000000002cd012000100000000000000000000000000000034d012000b00000000000000000000003fd0120010000000000000000000000000000000000000000000000000000000000000000013130050d01200000000000000000060d012000100000000000000010000000000000068d01200100000000000000000000000c2c4120003000000000000000000000000000000000000000000000000000000000000000013130078d01200000000000000000088d012000100000000000000000000000000000040b3120009000000010500000000000090d012000e000000000000009ed01200070000000000000000000000000000000000000000131300e8d012000000000000000000a8d0120001000000000000000100000000000000b0d012000d0000000105000000000000c2c41200030000000000000059c91200070000000000000000000000000000000000000000131300c0d012000000000000000000d0d012000100000000000000010000000000000049b3120006000000000000000000000090d012000e0000000000000000000000000000000000000000000000000000000000000000131300e4f412000000000000000000d8d01200010000000000000001000000000000004fb312000a00000000000000000000009ed01200070000000000000000000000000000000000000000000000000000000000000000131300e8d012000000000000000000e0d012000100000000000000010000000000000059b312000e00000000000000000000009ed01200070000000000000000000000000000000000000000000000000000000000000000131300e8d012000000000000000000f8d012000100000000000000010000000000000067b3120006000000000000000000000000d112000b00000000000000000000000000000000000000000000000000000000000000001313000cd1120000000000000000001cd1120001000000000000000100000000000000eabc120006000000000000000000000024d1120023000000000000000000000000000000000000000000000000000000000000000013130048d11200000000000000000058d112000100000000000000010000000000000060d112000a00000000000000000000006ad112000a0000000000000000000000000000000000000000000000000000000000000000131300e4f41200000000000000000074d1120001000000000000000100000000000000f0bc12000b00000001020000000000009ed0120007000000000000007cd11200210000000000000000000000000000000000000000131300a0d112000000000000000000b0d112000a00000000000000010000000000000000d2120012000000000000000000000012d2120016000000000000000000000000000000000000000000000000000000000000000013130028d21200000000000000000038d212000100000000000000000000000000000040d212000e00000000000000000000004ed2120005000000000000000000000000000000000000000000000000000000000000000013130054d21200000000000000000064d21200010000000000000000000000543a3a4163636f756e7449644163636f756e74496e666f3c543a3a496e6465782c20543a3a4163636f756e74446174613e0000001f0000000000000001000000ee0000005fd712003a00000045787472696e736963436f756e74000031d712002e000000426c6f636b57656967687445787472696e73696373576569676874001f0000000000000001000000ef0000000fd7120022000000416c6c45787472696e736963734c656e1f000000000000000100000038000000bfd6120050000000543a3a426c6f636b4e756d626572543a3a4861736800000099d612002600000045787472696e736963446174610000001f0000000000000001000000360000004ad612004f00000008d6120042000000ecd512001c0000001f0000000000000001000000f0000000a7d51200450000004469676573744f663c543e001f0000000000000001000000360000006bd512003c0000005665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e001f00000000000000010000003600000043d51200280000004576656e74436f756e744576656e74496e64657815d512002e0000005665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e0000001f000000000000000100000036000000e3d21200490000002cd3120025000000001313000000000051d3120054000000a5d3120051000000f6d312003900000000131300000000002fd412005300000082d4120053000000d5d41200400000004c61737452756e74696d65557067726164654c61737452756e74696d6555706772616465496e666f1f0000000000000001000000380000008ed2120055000000457865637574696f6e50686173655068617365001f0000000000000001000000380000006cd21200220000002054686520657865637574696f6e207068617365206f662074686520626c6f636b2e2053746f726573207468652060737065635f76657273696f6e6020616e642060737065635f6e616d6560206f66207768656e20746865206c6173742072756e74696d6520757067726164652068617070656e65642e204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2045787472696e7369637320726f6f74206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e205468652063757272656e742077656967687420666f722074686520626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e205468652066756c6c206163636f756e7420696e666f726d6174696f6e20666f72206120706172746963756c6172206163636f756e742049442e00000000000000ecd812000e0000000000000090d012000e0000000000000000131300fcd8120000000000000000000cd9120001000000000000000000000014d91200120000000000000026d912000600000000000000001313002cd9120000000000000000003cd9120001000000000000000000000044d9120008000000000000004cd912000f00000000000000001313005cd9120000000000000000006cd9120001000000000000000000000074d91200140000000000000026d9120006000000000000000013130088d91200000000000000000098d91200010000000000000000000000a0d91200130000000000000026d91200060000000000000000131300b4d912000000000000000000c4d91200010000000000000000000000ccd912001200000000000000c2c41200030000000000000000131300e0d912000000000000000000f0d912000100000000000000426c6f636b48617368436f756e7400001f0000000000000001000000f100000035db1200360000004d6178696d756d426c6f636b5765696768745765696768741f0000000000000001000000f200000016db12001f000000446257656967687452756e74696d654462576569676874001f0000000000000001000000f3000000d4da120042000000426c6f636b457865637574696f6e5765696768741f0000000000000001000000f400000080da12005400000045787472696e73696342617365576569676874001f0000000000000001000000f500000022da12005e0000004d6178696d756d426c6f636b4c656e67746800001f0000000000000001000000f6000000f8d912002a00000020546865206d6178696d756d206c656e677468206f66206120626c6f636b2028696e206279746573292e20546865206261736520776569676874206f6620616e2045787472696e73696320696e2074686520626c6f636b2c20696e646570656e64656e74206f6620746865206f662065787472696e736963206265696e672065786563757465642e20546865206261736520776569676874206f6620657865637574696e67206120626c6f636b2c20696e646570656e64656e74206f6620746865207472616e73616374696f6e7320696e2074686520626c6f636b2e2054686520776569676874206f662072756e74696d65206461746162617365206f7065726174696f6e73207468652072756e74696d652063616e20696e766f6b652e20546865206d6178696d756d20776569676874206f66206120626c6f636b2e20546865206d6178696d756d206e756d626572206f6620626c6f636b7320746f20616c6c6f7720696e206d6f7274616c20657261732e4e6f646520697320636f6e6669677572656420746f20757365207468652073616d6520686173683b2071656400b8db12005a000000200400001c000000b8db12005a00000028040000110000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f6672616d652f73797374656d2f7372632f6c69622e72730000000000009db6120004000000000000001cdd12000200000000000000000000004cdd1200190000000000000000000000a1b612000c000000000000000013130000000000000000000000000014de12000d0000000000000000000000adb6120014000000000000007cde120001000000000000000000000094de12001b0000000000000000000000c1b6120010000000000000006cdf120001000000000000000000000084df1200150000000000000000000000d1b6120012000000000000002ce0120001000000000000000000000044e01200260000000000000000000000e3b612000d0000000000000074e11200020000000000000000000000a4e11200120000000000000000000000a8f212000500000000000000adf212001100000000000000bef212000500000000000000c3f212001500000093ef120057000000eaef120039000000001313000000000023f012005500000078f012000a000000001313000000000082f012001400000096f0120012000000a8f0120056000000fef0120045000000001313000000000043f11200570000009af1120028000000001313000000000091c212000b000000c2f11200170000006eea12000d000000d9f11200360000000ff212001500000024f2120035000000ceea12000e0000006aef12000a00000059f212000800000061f212004700000034c312000c000000e2ee120048000000001313000000000091c212000b0000002aef12001600000040ef12002a0000006eea12000d0000006aef12000a00000074ef120016000000ceea12000e0000006aef12000a0000008aef12000900000074ef12001600000034c312000c00000000000000aaee12000700000000000000b1ee120031000000f7ea1200570000004eeb120057000000a5eb1200170000000013130000000000bceb120022000000deeb12005300000031ec12003c000000001313000000000000131300000000006dec12005a000000c7ec120030000000001313000000000091c212000b000000f7ec12002d00000024ed1200290000004ded1200240000006eea12000d00000071ed12001500000086ed1200140000009aed120013000000aded120036000000ceea12000e000000e3ed12001c000000ffed12003700000036ee12001e00000054ee12005600000034c312000c00000000000000dcea12000f00000000000000ebea12000c0000000ee912001e00000000131300000000002ce912001900000045e912003b00000080e912004b000000cbe912005500000020ea12000d000000001313000000000091c212000b0000002dea12001800000045ea1200290000006eea12000d0000007bea1200140000008fea12000e0000009dea12000b000000a8ea12000d000000b5ea120019000000ceea12000e000000b5ea1200190000008fea12000e00000034c312000c00000000000000fae812000a0000000000000004e912000a000000b9e41200540000000de51200100000001de51200500000006de512003d000000aae512005600000000e612002400000024e612005300000077e6120056000000cde612005900000026e71200090000002fe712001e0000004de712001800000065e712002a0000008fe712000e0000009de712000f000000ace7120026000000d2e712000f0000009de712000f000000ace7120026000000e1e7120019000000fae71200180000008fe712000e00000012e812003400000046e8120023000000d2e712000f00000012e812003400000046e812002300000069e8120019000000fae71200180000008fe712000e00000082e812002b00000046e8120023000000d2e712000f00000082e812002b00000046e81200230000000013130000000000ade8120043000000f0e812000a0000000000000084e41200030000000000000087e412002300000000000000aae412000f000000000000000fb912000400000034e21200570000008be21200200000000013130000000000abe212005600000001e312003d00000000131300000000003ee3120051000000001313000000000091c212000b0000008fe312001a000000a9e312001a000000c3e3120010000000d3e3120014000000e7e31200330000001ae4120011000000e7e31200330000002be412005900000034c312000c0000002052656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c7920616e642074686520626f6e64206f6620746865206f7574676f696e67206d656d62657220697320736c61736865642e20496620612072756e6e65722d757020697320617661696c61626c652c207468656e2074686520626573742072756e6e65722d75702077696c6c2062652072656d6f76656420616e64207265706c6163657320746865206f7574676f696e67206d656d6265722e204f74686572776973652c2061206e65772070687261676d656e20726f756e6420697320737461727465642e204e6f74652074686174207468697320646f6573206e6f7420616666656374207468652064657369676e6174656420626c6f636b206e756d626572206f6620746865206e65787420656c656374696f6e2e20496620776520686176652061207265706c6163656d656e743a20092d2042617365207765696768743a2035302e393320c2b57320092d2053746174652072656164733a2009092d2052756e6e65727355702e6c656e28292009092d204d656d626572732c2052756e6e6572735570202872656d6f76655f616e645f7265706c6163655f6d656d6265722920092d205374617465207772697465733a20456c73652c2073696e63652074686973206973206120726f6f742063616c6c20616e642077696c6c20676f20696e746f2070687261676d656e2c20776520617373756d652066756c6c20626c6f636b20666f72206e6f772e77686f3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263656861735f7265706c6163656d656e742052656e6f756e6365206f6e65277320696e74656e74696f6e20746f20626520612063616e64696461746520666f7220746865206e65787420656c656374696f6e20726f756e642e203320706f74656e7469616c206f7574636f6d65732065786973743a202d20606f726967696e6020697320612063616e64696461746520616e64206e6f7420656c656374656420696e20616e79207365742e20496e207468697320636173652c2074686520626f6e64206973202020756e72657365727665642c2072657475726e656420616e64206f726967696e2069732072656d6f76656420617320612063616e6469646174652e202d20606f726967696e6020697320612063757272656e742072756e6e65722d75702e20496e207468697320636173652c2074686520626f6e6420697320756e72657365727665642c2072657475726e656420616e642020206f726967696e2069732072656d6f76656420617320612072756e6e65722d75702e202d20606f726967696e6020697320612063757272656e74206d656d6265722e20496e207468697320636173652c2074686520626f6e6420697320756e726573657276656420616e64206f726967696e20697320202072656d6f7665642061732061206d656d6265722c20636f6e73657175656e746c79206e6f74206265696e6720612063616e64696461746520666f7220746865206e65787420726f756e6420616e796d6f72652e20202053696d696c617220746f205b6072656d6f76655f766f746572605d2c206966207265706c6163656d656e742072756e6e657273206578697374732c20746865792061726520696d6d6564696174656c7920757365642e203c7765696768743e20496620612063616e6469646174652069732072656e6f756e63696e673a200942617365207765696768743a2031372e323820c2b5732009436f6d706c6578697479206f662063616e6469646174655f636f756e743a20302e32333520c2b573200953746174652072656164733a2009092d2043616e646964617465732009092d205b4163636f756e7442616c616e63652877686f292028756e72657365727665295d20095374617465207772697465733a204966206d656d6265722069732072656e6f756e63696e673a200942617365207765696768743a2034362e323520c2b5732009092d204d656d626572732c2052756e6e6572735570202872656d6f76655f616e645f7265706c6163655f6d656d626572292c2009092d205b4163636f756e74446174612877686f292028756e72657365727665295d2049662072756e6e65722069732072656e6f756e63696e673a2009092d2052756e6e6572735570202872656d6f76655f616e645f7265706c6163655f6d656d626572292c20576569676874206e6f74653a205468652063616c6c20696e746f206368616e67654d656d62657273206e65656420746f206265206163636f756e74656420666f722e203c2f7765696768743e72656e6f756e63696e6752656e6f756e63696e67205375626d6974206f6e6573656c6620666f722063616e6469646163792e20412063616e6469646174652077696c6c206569746865723a2020202d204c6f73652061742074686520656e64206f6620746865207465726d20616e6420666f7266656974207468656972206465706f7369742e2020202d2057696e20616e64206265636f6d652061206d656d6265722e204d656d626572732077696c6c206576656e7475616c6c7920676574207468656972207374617368206261636b2e2020202d204265636f6d6520612072756e6e65722d75702e2052756e6e6572732d75707320617265207265736572766564206d656d6265727320696e2063617365206f6e65206765747320666f72636566756c6c79202020202072656d6f7665642e204261736520776569676874203d2033332e333320c2b57320436f6d706c6578697479206f662063616e6469646174655f636f756e743a20302e33373520c2b5732053746174652072656164733a20092d2043616e646964617465732e6c656e282920092d2043616e6469646174657320092d204d656d6265727320092d2052756e6e657273557020092d205b4163636f756e7442616c616e63652877686f295d205374617465207772697465733a63616e6469646174655f636f756e74436f6d706163743c7533323e205265706f727420607461726765746020666f72206265696e6720616e20646566756e637420766f7465722e20496e2063617365206f6620612076616c6964207265706f72742c20746865207265706f727465722069732072657761726465642062792074686520626f6e6420616d6f756e74206f662060746172676574602e204f74686572776973652c20746865207265706f7274657220697473656c662069732072656d6f76656420616e6420746865697220626f6e6420697320736c61736865642e204120646566756e637420766f74657220697320646566696e656420746f2062653a2020202d206120766f7465722077686f73652063757272656e74207375626d697474656420766f7465732061726520616c6c20696e76616c69642e20692e652e20616c6c206f66207468656d20617265206e6f20202020206c6f6e67657220612063616e646964617465206e6f7220616e20616374697665206d656d626572206f7220612072756e6e65722d75702e20546865206f726967696e206d7573742070726f7669646520746865206e756d626572206f662063757272656e742063616e6469646174657320616e6420766f746573206f6620746865207265706f727465642074617267657420666f722074686520707572706f7365206f66206163637572617465207765696768742063616c63756c6174696f6e2e204e6f204261736520776569676874206261736564206f6e206d696e2073717561726520616e616c797369732e20436f6d706c6578697479206f662063616e6469646174655f636f756e743a20312e37353520c2b57320436f6d706c6578697479206f6620766f74655f636f756e743a2031382e353120c2b5732020092d20566f74696e67287265706f72746572292020092d2043616e6469646174652e6c656e28292020092d20566f74696e6728546172676574292020092d2043616e646964617465732c204d656d626572732c2052756e6e6572735570202869735f646566756e63745f766f7465722920092d204c6f636b287265706f72746572207c7c207461726765742920092d205b4163636f756e7442616c616e6365287265706f72746572295d202b204163636f756e7442616c616e6365287461726765742920092d20566f74696e67287265706f72746572207c7c2074617267657429204e6f74653a207468652064622061636365737320697320776f7273652077697468207265737065637420746f2064622c207768696368206973207768656e20746865207265706f727420697320636f72726563742e646566756e6374446566756e6374566f7465723c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e2052656d6f766520606f726967696e60206173206120766f7465722e20546869732072656d6f76657320746865206c6f636b20616e642072657475726e732074686520626f6e642e2042617365207765696768743a2033362e3820c2b57320416c6c207374617465206163636573732069732066726f6d20646f5f72656d6f76655f766f7465722e20092d20566f74696e6720092d205b4163636f756e74446174612877686f295d20092d204c6f636b7320566f746520666f72206120736574206f662063616e6469646174657320666f7220746865207570636f6d696e6720726f756e64206f6620656c656374696f6e2e20546869732063616e2062652063616c6c656420746f207365742074686520696e697469616c20766f7465732c206f722075706461746520616c7265616479206578697374696e6720766f7465732e2055706f6e20696e697469616c20766f74696e672c206076616c75656020756e697473206f66206077686f6027732062616c616e6365206973206c6f636b656420616e64206120626f6e6420616d6f756e742069732072657365727665642e205468652060766f746573602073686f756c643a2020202d206e6f7420626520656d7074792e2020202d206265206c657373207468616e20746865206e756d626572206f6620706f737369626c652063616e646964617465732e204e6f7465207468617420616c6c2063757272656e74206d656d6265727320616e64202020202072756e6e6572732d75702061726520616c736f206175746f6d61746963616c6c792063616e6469646174657320666f7220746865206e65787420726f756e642e2049742069732074686520726573706f6e736962696c697479206f66207468652063616c6c657220746f206e6f7420706c61636520616c6c206f662074686569722062616c616e636520696e746f20746865206c6f636b20616e64206b65657020736f6d6520666f722066757274686572207472616e73616374696f6e732e2042617365207765696768743a2034372e393320c2b57320092d2043616e646964617465732e6c656e2829202b204d656d626572732e6c656e2829202b2052756e6e65727355702e6c656e282920092d20566f74696e67202869735f766f7465722920092d205b4163636f756e7442616c616e63652877686f292028756e72657365727665202b20746f74616c5f62616c616e6365295d20092d204c6f636b20092d205b4163636f756e7442616c616e63652877686f292028756e72657365727665202d2d206f6e6c79207768656e206372656174696e672061206e657720766f746572295d766f7465735665633c543a3a4163636f756e7449643e76616c7565436f6d706163743c42616c616e63654f663c543e3e00000000f0b6120007000000000000000000000090f41200210000000000000000000000000000000000000000000000000000000000000000131300bcf412000000000000000000b4f41200010000000000000001000000000000006abc120009000000000000000000000090f41200210000000000000000000000000000000000000000000000000000000000000000131300bcf412000000000000000000ccf4120001000000000000000100000000000000d4f412000e0000000000000000000000c2c41200030000000000000000000000000000000000000000000000000000000000000000131300e4f412000000000000000000f4f4120001000000000000000100000000000000f7b61200060000000105000000000000d0cf12000c00000000000000fcf4120021000000000000000000000000000000000000000013130020f51200000000000000000030f512000300000000000000010000000000000060bc12000a0000000000000000000000adf2120011000000000000000000000000000000000000000000000000000000000000000013130048f51200000000000000000058f512000200000000000000010000005665633c28543a3a4163636f756e7449642c2042616c616e63654f663c543e293e0000000ef712003c0000001f000000000000000100000036000000bcf6120052000000456c656374696f6e526f756e647300001f0000000000000001000000340000006cf61200500000002842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e290000001f0000000000000001000000f70000000ef612002e00000000131300000000003cf61200300000001f00000000000000010000003600000068f5120056000000bef5120050000000205468652070726573656e742063616e646964617465206c6973742e20536f72746564206261736564206f6e206163636f756e742d69642e20412063757272656e74206d656d626572206f722072756e6e65722d75702063616e206e6576657220656e746572207468697320766563746f7220616e6420697320616c7761797320696d706c696369746c7920617373756d656420746f20626520612063616e6469646174652e20566f74657320616e64206c6f636b6564207374616b65206f66206120706172746963756c617220766f7465722e2054574f582d4e4f54453a205341464520617320604163636f756e7449646020697320612063727970746f20686173682054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e65642c206578636c7564696e6720746865207570636f6d696e67206f6e652e205468652063757272656e742072756e6e6572735f75702e20536f72746564206261736564206f6e206c6f7720746f2068696768206d657269742028776f72736520746f20626573742072756e6e6572292e205468652063757272656e7420656c6563746564206d656d626572736869702e20536f72746564206261736564206f6e206163636f756e742069642e0000000000009cf812000d00000000000000a9f812000c0000000000000000131300b8f81200000000000000000000131300000000000000000000000000c8f812000a00000000000000a9f812000c0000000000000000131300d4f81200000000000000000000131300000000000000000000000000e4f812000e00000000000000c2c41200030000000000000000131300f4f8120000000000000000000013130000000000000000000000000004f912001000000000000000c2c4120003000000000000000013130014f9120000000000000000000013130000000000000000000000000024f912000c0000000000000090d012000e000000000000000013130030f9120000000000000000000013130000000000000000000000000040f91200080000000000000048f912000e000000000000000013130058f91200000000000000000000131300000000000000000043616e646964616379426f6e6442616c616e63654f663c543e0000001f0000000000000001000000bf000000566f74696e67426f6e6400001f0000000000000001000000f8000000446573697265644d656d6265727300001f0000000000000001000000f90000004465736972656452756e6e65727355701f0000000000000001000000fa0000005465726d4475726174696f6e1f0000000000000001000000c10000004d6f64756c6549644c6f636b4964656e74696669657200001f0000000000000001000000fb0000003a6865617070616765733a636f64653a6368616e6765735f747269650000000097b212000f0000000000000010fa12000200000000000000000000007db212001a0000000000000020fa120002000000000000000000000060b212001d0000000000000030fa12000300000000000000000000004db21200130000000000000048fa12000100000000000000000000003eb212000f0000000000000050fa12000100000000000000cbfb120045000000b6fb12001500000065fb120051000000b6fb120015000000e6fa12003c000000001313000000000022fb120043000000a6fa12004000000058fa12004e0000002054686572652069732061206e6f6e2d7a65726f207265666572656e636520636f756e742070726576656e74696e6720746865206163636f756e742066726f6d206265696e67207075726765642e20537569636964652063616c6c6564207768656e20746865206163636f756e7420686173206e6f6e2d64656661756c7420636f6d706f7369746520646174612e204661696c656420746f2065787472616374207468652072756e74696d652076657273696f6e2066726f6d20746865206e65772072756e74696d652e204569746865722063616c6c696e672060436f72655f76657273696f6e60206f72206465636f64696e67206052756e74696d6556657273696f6e60206661696c65642e205468652073706563696669636174696f6e2076657273696f6e206973206e6f7420616c6c6f77656420746f206465637265617365206265747765656e207468652063757272656e742072756e74696d6520616e6420746865206e65772072756e74696d652e20546865206e616d65206f662073706563696669636174696f6e20646f6573206e6f74206d61746368206265747765656e207468652063757272656e742072756e74696d650000000091b612000c00000000000000ecfd12000100000000000000000000008ab612000700000000000000f4fd12000100000000000000000000007eb612000c00000000000000fcfd12000100000000000000000000006ab61200140000000000000004fe120001000000000000000000000060b612000a000000000000000cfe120001000000000000000000000051b612000f0000000000000014fe120001000000000000000000000046b612000b000000000000001cfe12000100000000000000000000003cb612000a0000000000000024fe120001000000000000000000000029b6120013000000000000002cfe12000100000000000000000000001db612000c0000000000000034fe120001000000000000000000000011b612000c000000000000003cfe1200010000000000000000000000f7b512001a0000000000000044fe1200010000000000000000000000eeb5120009000000000000004cfe1200010000000000000000000000d9b51200150000000000000054fe1200010000000000000000000000c9b5120010000000000000005cfe1200010000000000000000000000b8b51200110000000000000064fe1200010000000000000000000000a6b5120012000000000000006cfe12000100000000000000e100130031000000bb00130026000000990013002200000072001300270000004000130032000000210013001f0000001000130011000000fcff120014000000dbff120021000000b8ff12002300000095ff1200230000006fff12002600000061ff12000e00000028ff120039000000f4fe120034000000b4fe12004000000074fe1200400000002050726564696374696f6e20726567617264696e67207265706c6163656d656e74206166746572206d656d6265722072656d6f76616c2069732077726f6e672e205468652072656e6f756e63696e67206f726967696e2070726573656e74656420612077726f6e67206052656e6f756e63696e676020706172616d657465722e205468652070726f766964656420636f756e74206f66206e756d626572206f6620766f74657320697320696e636f72726563742e205468652070726f766964656420636f756e74206f66206e756d626572206f662063616e6469646174657320697320696e636f72726563742e204e6f742061206d656d6265722e2043616e64696461746520646f6573206e6f74206861766520656e6f7567682066756e64732e2052756e6e65722063616e6e6f742072652d7375626d69742063616e6469646163792e204d656d6265722063616e6e6f742072652d7375626d69742063616e6469646163792e204475706c6963617465642063616e646964617465207375626d697373696f6e2e2043616e6e6f74207265706f72742073656c662e204d757374206265206120766f7465722e20566f7465722063616e206e6f742070617920766f74696e6720626f6e642e2043616e6e6f7420766f74652077697468207374616b65206c657373207468616e206d696e696d756d2062616c616e63652e2043616e6e6f7420766f7465206d6f7265207468616e206d6178696d756d20616c6c6f7765642e2043616e6e6f7420766f7465206d6f7265207468616e2063616e646964617465732e204d75737420766f746520666f72206174206c65617374206f6e652063616e6469646174652e2043616e6e6f7420766f7465207768656e206e6f2063616e64696461746573206f72206d656d626572732065786973742e000002000000010000000100000001000000010000000100000001000000010000000100000002000000030000000400000001000000020000000300000001000000536c6f747341756374696f6e436f756e7465724d616e616765644964734174746573746174696f6e73000000a0011300390000008204000022000000a0011300390000007c040000200000002f55736572732f6761762f436f72652f706f6c6b61646f742f72756e74696d652f636f6d6d6f6e2f7372632f70617261636861696e732e7273417574686f726974696573436f6465467574757265436f6465486561647352656c61794469737061746368517565756552656c61794469737061746368517565756553697a654e656564734469737061746368446964557064617465492068657265627920616772656520746f20746865207465726d73206f66207468652073746174656d656e742077686f7365205348412d323536206d756c74696861736820697320516d58456b4d61686668484a507a5433526a6b58695a56466937375a655665757874416a686f6a47524e59636b7a2e202854686973206d617920626520666f756e64206174207468652055524c3a2068747470733a2f2f73746174656d656e742e706f6c6b61646f742e6e6574776f726b2f736166742e68746d6c29492068657265627920616772656520746f20746865207465726d73206f66207468652073746174656d656e742077686f7365205348412d323536206d756c74696861736820697320516d63315859715436533339574e70325565695255725a6963685557555070474554684445366441623366364e792e202854686973206d617920626520666f756e64206174207468652055524c3a2068747470733a2f2f73746174656d656e742e706f6c6b61646f742e6e6574776f726b2f726567756c61722e68746d6c29436c61696d735369676e696e6750617261636861696e73526567697374726172546872656164436f756e7453656c6563746564546872656164734163746976654e65787446726565496450656e64696e6753776170506172617352657472795175657565000000007c04130014000000000000009004130001000000000000000000000098041300010000000000000000000000a0041300160000000000000090041300010000000000000000000000b8041300010000000000000050617261746872656164526567697374657265642a05130006000000f504130035000000506172617468726561644465726567697374657265640000c004130035000000205468652070617261746872656164206f662074686520737570706c696564204944207761732064652d726567697374657265642e204120706172617468726561642077617320726567697374657265643b20697473206e657720494420697320737570706c6965642e5061726149644005130067000000450000000d0000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f7072696d6974697665732f61726974686d657469632f7372632f62696775696e742e7273000000000000000000617474656d707420746f20646976696465206279207a65726f00000040051300670000006e0000000900000040051300670000007f0000000900000040051300670000009d0000001b0000004005130067000000d50100001c0000004005130067000000d60100001c00000063616e6e6f74206669742061206e756d62657220696e746f207531323800000040051300670000009100000009000000616c7265616479206d757461626c7920626f72726f7765641f00000000000000010000004600000084061300430000001e030000090000002f72757374632f323435346136386366626236336161376238653039666530353131346435663938623266393734302f7372632f6c6962636f72652f63656c6c2e7273616c726561647920626f72726f776564001f0000000000000001000000c500000084061300430000006e0300000900000072656d696e646572206f6620646976206279206320697320616c77617973206c657373207468616e20633b20716564001f00000008000000040000004a000000610713006e000000690000001b000000726573756c742063616e6e6f742066697420696e20753132382f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f7072696d6974697665732f61726974686d657469632f7372632f68656c706572735f3132386269742e727362616265736c6f74436f756c64206e6f74206465636f64652072657175657374656420696e686572656e742074797065214241424520696e686572656e742064617461206e6f7420666f756e6442616265565246496e4f7574436f6e7465787442414245736c6f74206e756d62657263757272656e742065706f6368636861696e2072616e646f6d6e657373006c0813006c000000ce0000000d0000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f7072696d6974697665732f72756e74696d652d696e746572666163652f7372632f696d706c732e72731f000000000000000100000023000000486f737420746f207761736d2076616c7565732061726520656e636f64656420636f72726563746c793b207165640000280913006e00000009010000090000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f7072696d6974697665732f72756e74696d652d696e746572666163652f7372632f706173735f62792e727300001f000000000000000100000023000000001313000000000072756e74696d6552756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e67436f6d70616374496e76616c6964496e646578436f6d706163745374616b654f766572666c6f77436f6d706163745461726765744f766572666c6f770000000000000000000000617474656d707420746f20646976696465206279207a65726f0000004c0a130068000000600000002b0000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f7072696d6974697665732f72756e74696d652f7372632f67656e657269632f6572612e727348617368206e6f7420657175616c2f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f7072696d6974697665732f72756e74696d652f7372632f7472616974732e7273000000c20a1300630000002104000013000000426164206f726967696e43616e206e6f74206c6f6f6b757044697370617463684572726f725472616e616374696f6e206469737061746368206973206d616e6461746f72793b207472616e73616374696f6e73206d6179206e6f742068617665206d616e6461746f727920646973706174636865732e412063616c6c20776173206c6162656c6c6564206173206d616e6461746f72792c2062757420726573756c74656420696e20616e204572726f722e5472616e73616374696f6e20776f756c642065786861757374732074686520626c6f636b206c696d6974735472616e73616374696f6e2068617320616e20616e6369656e7420626972746820626c6f636b5472616e73616374696f6e20686173206120626164207369676e61747572655472616e73616374696f6e206973206f757464617465645472616e73616374696f6e2077696c6c2062652076616c696420696e2074686520667574757265496e6162696c69747920746f2070617920736f6d6520666565732028652e672e206163636f756e742062616c616e636520746f6f206c6f77295472616e73616374696f6e2063616c6c206973206e6f74206578706563746564496e76616c69645472616e73616374696f6e20637573746f6d206572726f72436f756c64206e6f742066696e6420616e20756e7369676e65642076616c696461746f7220666f722074686520756e7369676e6564207472616e73616374696f6e436f756c64206e6f74206c6f6f6b757020696e666f726d6174696f6e20726571756972656420746f2076616c696461746520746865207472616e73616374696f6e556e6b6e6f776e5472616e73616374696f6e20637573746f6d206572726f723c7761736d3a73747269707065643e4475706c69636174655265706f72744f6666656e63654572726f720000ec0d130064000000460000001f0000002f55736572732f6761762f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f666663636538352f7072696d6974697665732f747269652f7372632f6e6f64655f636f6465632e7273ec0d1300640000004f000000140000006c656e20213d20302073696e6365206c656e2025203220213d20303b20696e6e6572206861732061206c61737420656c656d656e743b207165640000ac0e1300610000003c0000001a0000002f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32302e312f7372632f6e6962626c652f6e6962626c657665632e7273000000ac0e1300610000006000000033000000ac0e130061000000600000000d000000ac0e1300610000006b0000000f000000ac0e1300610000006b0000003e000000ac0e130061000000690000000f000000ac0e1300610000009100000039000000ac0e1300610000009100000011000000ac0e1300610000009300000011000000ac0e1300610000009400000040000000ac0e130061000000940000004e000000d00f1300630000009800000017000000d00f13006300000096000000290000002f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32302e312f7372632f6e6962626c652f6e6962626c65736c6963652e727300e01113005b0000004d0000001c000000d00f1300630000004000000012000000d00f1300630000005500000032000000d00f1300630000004f0000002d000000d00f130063000000e10000000f000000d00f130063000000df0000000f000000d00f130063000000e10000003d0000006361706163697479206f766572666c6f7700000010131300490000000a00000009000000617373657274696f6e206661696c65643a20696e646578203c3d206c656e617373657274696f6e206661696c65643a206e65775f636170203e3d206c656e0000e01113005b0000008d0000003c000000e01113005b0000008d00000051000000e01113005b0000008d0000003100000058111300550000004b0000004200000058111300550000004a0000003e0000002f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32302e312f7372632f6e6f64652e727300000058111300550000006b0000002200000058111300550000009a000000320000005811130055000000aa0000003e0000002f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32302e312f7372632f6e6962626c652f6d6f642e727300e01113005b000000870000001d000000e01113005b000000870000000d000000e01113005b0000008600000031000000e01113005b0000008600000042000000e01113005b0000008600000026000000e01113005b0000008e00000018000000e01113005b0000008e0000000d000000c41213002d000000f11213000c000000fd12130003000000617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a20101313004900000010000000090000002f72757374632f323435346136386366626236336161376238653039666530353131346435663938623266393734302f7372632f6c6962636f72652f6d6163726f732f6d6f642e72730000007c1313005a00000042060000090000007c1313005a00000042060000320000002f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32302e312f7372632f7472696564626d75742e72730041d8a7cc000b08000000000000000000898a05046e616d6501808a05ec0700196578745f6c6f6767696e675f6c6f675f76657273696f6e5f31011e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f31021d6578745f68617368696e675f74776f785f36345f76657273696f6e5f3103196578745f73746f726167655f7365745f76657273696f6e5f31041b6578745f73746f726167655f636c6561725f76657273696f6e5f3105206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f3106226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f3107196578745f73746f726167655f6765745f76657273696f6e5f31081d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f3109226578745f6f6666636861696e5f72616e646f6d5f736565645f76657273696f6e5f310a1c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f310b276578745f63727970746f5f73746172745f62617463685f7665726966795f76657273696f6e5f310c286578745f63727970746f5f66696e6973685f62617463685f7665726966795f76657273696f6e5f310d236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f310e286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f310f346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f3110206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f3111206578745f68617368696e675f6b656363616b5f3235365f76657273696f6e5f3112236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f3113226578745f6d6973635f72756e74696d655f76657273696f6e5f76657273696f6e5f31141c6578745f73746f726167655f617070656e645f76657273696f6e5f31151e6578745f73746f726167655f6e6578745f6b65795f76657273696f6e5f31161c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f3117236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f3218286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f31191a6578745f73746f726167655f726f6f745f76657273696f6e5f311a226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f311b2a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f311c256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f311d2c6578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f76657273696f6e5f311e376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f311f256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f3120286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f3121216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f3122246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f3123296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f31241a6578745f73746f726167655f726561645f76657273696f6e5f31251e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f31261c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f31270c5f5f727573745f616c6c6f63280a5f5f72675f616c6c6f63290e5f5f727573745f6465616c6c6f632a0c5f5f72675f6465616c6c6f632b0e5f5f727573745f7265616c6c6f632c0c5f5f72675f7265616c6c6f632d135f5f727573745f616c6c6f635f7a65726f65642e115f5f72675f616c6c6f635f7a65726f65642f09686173685f746573743033616c6c6f633a3a616c6c6f633a3a68616e646c655f616c6c6f635f6572726f723a3a68353163623932333763613366353463663108727573745f6f6f6d3234616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68636633313064393836323166623433303329636f72653a3a70616e69636b696e673a3a70616e69633a3a683030363437306536303862656439353034673c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c26542c636f72653a3a736c6963653a3a497465723c543e3e3e3a3a737065635f657874656e643a3a68663630333566303732643235353538393525616c6c6f633a3a666d743a3a666f726d61743a3a68353162646564663733633836333235353636636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a68393562303464643938363539313862363723636f72653a3a666d743a3a77726974653a3a68303831356161306566383061653962353848616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303135383538626463303964366137323948616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303230616334656139386532646663323a33636f72653a3a6f7074696f6e3a3a6578706563745f6e6f6e655f6661696c65643a3a68363834326330353630396131316161343b3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68623565356635306535393861353161303c3b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a68343835333230373837643133636431643d3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68323565373337646265363866313463313e41616c6c6f633a3a7665633a3a5665633c543e3a3a737761705f72656d6f76653a3a6173736572745f6661696c65643a3a68633031623332663963663337653963313f4e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a6866313530386135356232346364666464402d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a6831323165636465623765613431366466413c616c6c6f633a3a7665633a3a5665633c543e3a3a696e736572743a3a6173736572745f6661696c65643a3a6861393437313162303766353636306563423c616c6c6f633a3a7665633a3a5665633c543e3a3a72656d6f76653a3a6173736572745f6661696c65643a3a68303739623034626265643466336234324341616c6c6f633a3a7665633a3a5665633c543e3a3a647261696e3a3a73746172745f6173736572745f6661696c65643a3a6833323235356664613534653537663838443f616c6c6f633a3a7665633a3a5665633c543e3a3a647261696e3a3a656e645f6173736572745f6661696c65643a3a68356431313731303562383636383764354539636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653a3a63616c6c5f6f6e63653a3a6862393936313139646531313231346565462f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a68366533616365353734346466643033644711727573745f626567696e5f756e77696e6448313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a68303661353130333961616237383235344935636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a68653932373262646363616336306465614a43636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a68643738323237356538303230633037344b34636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68313938373562666436383834646638634c36636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a68316465333637626133373764636538644d2c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a68313636656363363539373163643363634e2e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a68623233363366646233303032316536664f323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6836306537626263363530333664373932504a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683535363930333161386438653835313251323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68376161336631343238396430386261365247636f72653a3a756e69636f64653a3a756e69636f64655f646174613a3a6772617068656d655f657874656e643a3a6c6f6f6b75703a3a68613835323132396535396333363565615332636f72653a3a756e69636f64653a3a7072696e7461626c653a3a636865636b3a3a68393165333839386434396631656236395449636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a683236383537666231363037623539353355453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683065623838643135356633303964303756483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862333335646536383631323063633233572e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a683633646465376666396462376438623458303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686230333265336361626166646339613159323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68343533633561623935663535323564345a323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68306164336266313239633832353336375b533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68363062366563633731616261623535365c2e636f72653a3a736c6963653a3a6d656d6368723a3a6d656d6368723a3a68323361303933653464646237393335315d2f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a68356261336366363138313565373762665e2e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a68663435363732306637616333343265355f3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6838383463623733303536396562326561603b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6865643364376661306531626237333132613a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68666434323965346239656338393933366239636f72653a3a666d743a3a6275696c646572733a3a44656275675475706c653a3a6669656c643a3a68613533333665666163353734656238626337636f72653a3a666d743a3a6275696c646572733a3a44656275675365743a3a656e7472793a3a686637353538653961373662616632373064443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683362303935626162663933396632636265313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862306565323536613538376662373638668001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a68376438313835366161663932613237396747636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a42696e61727920666f722069383e3a3a666d743a3a6830343935376436643034313761623237684a636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a557070657248657820666f72206933323e3a3a666d743a3a6833616234653261306439326130356261693e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68613031393933356237623361336434656a5a637572766532353531395f64616c656b3a3a6261636b656e643a3a73657269616c3a3a7536343a3a6669656c643a3a4669656c64456c656d656e7435313a3a746f5f62797465733a3a68616165363666613661363230343135316b57637572766532353531395f64616c656b3a3a6261636b656e643a3a73657269616c3a3a7536343a3a6669656c643a3a4669656c64456c656d656e7435313a3a706f77326b3a3a68336331316537313265613562386338346c7e637572766532353531395f64616c656b3a3a6669656c643a3a3c696d706c20637572766532353531395f64616c656b3a3a6261636b656e643a3a73657269616c3a3a7536343a3a6669656c643a3a4669656c64456c656d656e7435313e3a3a737172745f726174696f5f693a3a68623934396134613831326165366438666d24737562746c653a3a626c61636b5f626f783a3a68373039366535313535383366663730616e5a637572766532353531395f64616c656b3a3a72697374726574746f3a3a52697374726574746f506f696e743a3a656c6c696761746f725f72697374726574746f5f666c61766f723a3a68346434363937613834366439653935646f49637572766532353531395f64616c656b3a3a7363616c61723a3a5363616c61723a3a66726f6d5f63616e6f6e6963616c5f62797465733a3a683339376564386631343866663435313470693c6672616d655f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683164376535613965633834333230613671776672616d655f73797374656d3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206672616d655f73797374656d3a3a436865636b4e6f6e63653c543e3e3a3a656e636f64655f746f3a3a683037366333643036343238636132323572543c616c6c6f633a3a7665633a3a5665633c75383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4f75747075743e3a3a77726974653a3a683134646330656536363133316264313373693c6672616d655f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683330633838616461386130613930626374483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683862333430623364656464656363353975513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6866373032313266386439656264656232763a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6831623438326238653662666365323234773b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6866373230353261623465333861396463783a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a683832313133333739343830373638623479503c6672616d655f737570706f72743a3a64656275673a3a57726974657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68366232623832663937343735353463337a4d3c6672616d655f737570706f72743a3a64656275673a3a52756e74696d654c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a68636663616565386239613366643935647b493c6672616d655f737570706f72743a3a64656275673a3a52756e74696d654c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a68373564336365333237656131383435617c206b656363616b3a3a66313630303a3a68633262383461656634313639366136637d383c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a68386430646338613436313533343633397e343c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a68353933353866646232646137633663387f363c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a666c7573683a3a68313631306366366334353136666461668001366d65726c696e3a3a7472616e7363726970743a3a5472616e7363726970743a3a6e65773a3a68666363383837626163323430356666398101366d65726c696e3a3a7374726f62653a3a5374726f62653132383a3a626567696e5f6f703a3a68666537346433396134333038343336658201303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683464656338623963613066386161323183013f6d65726c696e3a3a7472616e7363726970743a3a5472616e7363726970743a3a636f6d6d69745f62797465733a3a683731376238316534633737663363663284013d6d65726c696e3a3a7472616e7363726970743a3a5472616e7363726970743a3a617070656e645f7536343a3a68343564373434333964373739616432308501426d65726c696e3a3a7472616e7363726970743a3a5472616e7363726970743a3a6368616c6c656e67655f62797465733a3a6839356634303532623139366662656265860191016d65726c696e3a3a7374726f62653a3a5f4445524956455f44726f705f464f525f416c69676e65644b656363616b53746174653a3a3c696d706c20636f72653a3a6f70733a3a64726f703a3a44726f7020666f72206d65726c696e3a3a7374726f62653a3a416c69676e65644b656363616b53746174653e3a3a64726f703a3a68373664333462333761376438353431668701453c70616c6c65745f7374616b696e673a3a466f7263696e6720617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683566376631643764343734346533333488014470616c6c65745f7374616b696e673a3a736c617368696e673a3a536c617368696e675370616e733a3a656e645f7370616e3a3a686163633034636532306465356531396689013a70616c6c65745f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a68383132646135376466383933616331658a01453c737472206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a68323130366334613461656265353435658b0136616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a646f75626c653a3a68343632626136646564323464653838348c0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68303837363437643835383062613439648d0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68306435326462613632663537623532388e0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68306566303936656635323666656264658f0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831303032383336393230323637653266900137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831353362633434343562363063353266910137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831633239336162336637626363663733920137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832316361383931306662386566396437930137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832336338336537316538623466376661940137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832613130643130393939303936613936950137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832653963653935383137626266386631960137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832656132393938323462396132393761970137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832656665623530376432323637663432980137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6833623733313235663034613732636338990137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68336663353932343830356638353439319a0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68343235306235633863623661333635619b0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68343632643137623131353636346539629c0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68343733393563326335656561636466339d0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68346138613034383331393265623561359e0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68353263643831656466393563396338619f0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6835333639356137613766343639653365a00137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6835373361363461396530373461613535a10137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6836356563643066646532303762313464a20137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6838323432633237313464366463393737a30137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6838663165383139313232366161643963a40137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6839653238363739386661366238646262a50137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6839666261323366633736386437613235a60137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6861313065653937303663656539333435a70137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6861313166346464326364303337363136a80137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6862336436326461643761653537346539a90137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6862623339636332326334306633343166aa0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6863306437613064333638326462313038ab0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6864356538383565346332383162653436ac0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6864653835356332333065646431616437ad0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6865323535386165303038346530383162ae0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6866366430383431383333326338626637af015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839396234666365613664656330396161b001753c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6832653161623666613939326436633663b101386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831383265333238356439623933646563b201386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836653431386535663230353736613362b301386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866623233333463613761663237323939b4013e70616c6c65745f626162653a3a4d6f64756c653c543e3a3a63757272656e745f65706f63685f73746172743a3a6838393264306138373139306565656361b501386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835333265353234646433303336393764b6018b013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61704974657261746f723c4b2c562c4861736865723e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6838396362366331653462333865666232b7018b013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61704974657261746f723c4b2c562c4861736865723e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6864653662376532313132643139313764b80147636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207533323e3a3a666d743a3a6831633835623037353066633565353230b901437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6862636637653733333363323635353436ba01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862373639393133346466316134353662bb013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6831643962643436313038363065646266bc013770616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a6834623366376431656236656463663861bd013b70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a7265776172645f62795f6964733a3a6865636430643231303037343734623461be013f70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a6e6f74655f617574686f72736869703a3a6832633761653761373262326533333361bf013870616c6c65745f626162653a3a4d6f64756c653c543e3a3a646f5f696e697469616c697a653a3a6830643439353531653465333439353662c0015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863303936313362353564336334313931c101386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862373934613934346465316334653135c2012b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6838323165343531376663616630386535c301693c706f6c6b61646f745f72756e74696d653a3a43616c6c206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6838383365623232386231316537613163c4014d3c706f6c6b61646f745f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68386366623631613565366630386233632e31323932c501593c706f6c6b61646f745f72756e74696d653a3a43616c6c2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6834363135353038363761383837336638c6015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6830663635643865376531363535653964c7014373705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a726561643a3a6861623439346133393963636463316230c8016b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6834626232666339316137356230356538c901437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6836613666316638323031636262653631ca01776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a617070656e643a3a6830313032646233363431366236623065cb01416672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6576656e745f696e64657865643a3a6833303661323631613335346362323563cc012b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6838323165343531376663616630386535cd01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838316638656633313665333663633938ce01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834353431333863376631353162396136cf01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6839663063383964386330663235373635d001386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866636363636666613830643837353766d101386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865646666613264373737386166643339d2014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6837366266356662663331313135396635d301723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6835343133343636393631373232623239d401613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6837373834326638653936643436666564d501706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6838313539336630386461313666393432d601706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6863333834646434343738643263316465d701706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6863633435623136613934343263653937d8015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6830306533316236356162653735653365d9015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831663664643762613765346532373464da015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6835616165663138306138313663653862db015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6836623861396566613061336234326139dc015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6838633530346666353239323637323035dd015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864373636306131393331656633623933de015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6866383235386635636565316536323265df01746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6837323439323539366464356362326134e001386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834616361626333393933323636633836e1014e70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a736c61736861626c655f62616c616e63655f6f665f766f74655f7765696768743a3a6835643735616436343765353134643330e201386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863666363646664366534303761323437e301386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861346436356361383366396166663262e4014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6835633436666530333034613938303832e501723c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6830313835653237376265353333373934e6016f3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6833343732316238626636623233313233e7013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6861366461633132643561636263366434e8013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a656e737572655f6e65775f6572613a3a6862626631613966616336613165303531e9013e70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863306363363830366231373033356563ea01723c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637453746f7261676556657273696f6e3c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835663534613335636466636533646637eb01753c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374457261456c656374696f6e5374617475733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861353263326363356530336133343563ec016d3c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563745370616e536c6173683c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863353333373739336338336563386436ed013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6834366336366237656639316263373566ee01723c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637445726173546f74616c5374616b653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866323037613631353236616634636565ef01743c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637445726173526577617264506f696e74733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837643836653133306539616637646630f001763c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563744572617356616c696461746f7250726566733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830383133323530343339626632326230f101763c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374457261735374616b657273436c69707065643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836653938643461643731336332373332f201793c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563744d696e696d756d56616c696461746f72436f756e743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865393737373164363231303232663534f301703c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374486973746f727944657074683c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862653163636661636438613330373330f4014770616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6831656562363935323138646566356261f5019b013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f6e64696e674475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865623833373438613333656439613165f6019a013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53657373696f6e7350657245726144656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866616164313231336431333937363235f7013770616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a73746172745f6572613a3a6861366239326532643164313934613563f801386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835643734663461633663613262353232f901386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862616137393136626238653836333534fa015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832656337326231323639343936633766fb014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6839663036633834393166646633303761fc01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837363430373731323233366238303362fd015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6861303534313264303130346534623734fe01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835383735646333346437636234636636ff013570616c6c65745f7374616b696e673a3a736c617368696e673a3a646f5f736c6173683a3a68653430656366646434306135316461378002446672616d655f737570706f72743a3a7472616974733a3a43757272656e63793a3a7265736f6c76655f6372656174696e673a3a68626133376230396266333439366462378102743c70616c6c65745f62616c616e6365733a3a696d62616c616e6365733a3a4e65676174697665496d62616c616e63653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a54727944726f703e3a3a7472795f64726f703a3a683862663561316463663739393463663882024873705f72756e74696d653a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a68653639353439623332333537353735628302860170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7374616b696e673a3a4578706f737572653c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a683136616562313765633739323234643584026c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683030393434336438396635323932393785028e0170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e3e3a3a656e636f64655f746f3a3a686536353433646465316132303535393486028b0170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e3e3a3a6465636f64653a3a683431626665663434653930633337613187022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a683437343464653461643462323038383688025b70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c41636375726163793e3a3a66726f6d5f61737369676e6d656e743a3a68666434643166333066633633323864658902ba013c70616c6c65745f7374616b696e673a3a53746173684f663c543e2061732073705f72756e74696d653a3a7472616974733a3a436f6e766572743c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a636f6e766572743a3a68303066353063316139613461623966398a02f7013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e2061732073705f7374616b696e673a3a6f6666656e63653a3a4f6e4f6666656e636548616e646c65723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c283c542061732070616c6c65745f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249642c3c542061732070616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a54726169743e3a3a46756c6c4964656e74696669636174696f6e292c7536343e3e3a3a6f6e5f6f6666656e63653a3a68366431306138633931653235386135378b027c3c73705f72756e74696d655f696e746572666163653a3a706173735f62793a3a436f6465633c543e2061732073705f72756e74696d655f696e746572666163653a3a706173735f62793a3a506173734279496d706c3c543e3e3a3a66726f6d5f6666695f76616c75653a3a68306235633164353439653463383931618c02303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68363861666436323766363331396663648d02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68313636653466316238626230643339648e024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68616237336234343032366535363032398f024970616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a6572615f7370616e3a3a683131366564646431666561643566626690023570616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a64697361626c653a3a683931393032383432323262383935333191025e70616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a636f6d706172655f616e645f7570646174655f7370616e5f736c6173683a3a686163363266613066646436393565653692025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683762363332333137366437336137386293025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683936653637396430646534653935616594023570616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6e65775f6572613a3a683365633562396133306638643961663395024370616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a636c6561725f6572615f696e666f726d6174696f6e3a3a68383730663139396539626262316137329602543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68316464343434636237643139386436639702533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a683266363862623936396366343664376398022573705f70687261676d656e3a3a656c6563743a3a68333664343233393634313030306232369902513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68353534373038346532346663343831399a023173705f70687261676d656e3a3a6275696c645f737570706f72745f6d61703a3a68326634626233333266653966663965669b02513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68326162646431356637363632666136369c022d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a68336432626330373030353437343563399d02706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a68646236383536663962663965383562309e02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68303632656230393431376364316262309f02706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6834353333393030626131623632346530a002d3023c70616c6c65745f7374616b696e673a3a4578706f737572654f663c543e2061732073705f72756e74696d653a3a7472616974733a3a436f6e766572743c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c70616c6c65745f7374616b696e673a3a4578706f737572653c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c3c542061732070616c6c65745f7374616b696e673a3a54726169743e3a3a43757272656e6379206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3e3a3a636f6e766572743a3a6866646138306439333236336536376433a102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830363663363938623230643130336536a2026a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a6865313235366166323939656437376436a302493c70616c6c65745f7374616b696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6834323731613037663361663735663233a402623c70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6861653966373434663334613331316433a5025a3c70616c6c65745f7374616b696e673a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6865326335306365663139323763303139a6025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6835383536333563313964613434393330a702336672616d655f73797374656d3a3a4d6f64756c653c543e3a3a696e635f7265663a3a6863663234393833386334396432343366a8025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6835353639333738326633303863383433a902386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838633634323739616133316139633664aa028d013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f6c6f636b3a3a6837306163386633306235326462666335ab023870616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a6839343130656335373832366238383834ac0290013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a72656d6f76655f6c6f636b3a3a6834646366383537386363633733313233ad02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863616232326165343161616262333039ae02746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6838623539386135343363646266626566af025273705f61726974686d657469633a3a7065725f7468696e67733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a6832313536386334613230346262623831b0023970616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a6866303639633931346638386461626539b1024870616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a636865636b5f616e645f7265706c6163655f736f6c7574696f6e3a3a6831363433363634653036353961383633b202336672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465635f7265663a3a6833393031313439346536323831373032b302b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6864343264363837336137306261323337b4024170616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a7072655f64697370617463685f636865636b733a3a6864643834333738306232643136383262b5025b70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c41636375726163793e3a3a696e746f5f61737369676e6d656e743a3a6836326332363362613564653136643238b602403c73705f70687261676d656e3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863326238393965336436393835383664b702386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831346238396262353763623963663739b802633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a666f6c643a3a6834306633663830666636396262373530b902613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6830333637646135386663303566353662ba0247636f72653a3a61727261793a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72205b543b205f5d3e3a3a666d743a3a6862383838386135333136336362303463bb025f3c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6865356566666537626662316430373462bc026f3c73705f72756e74696d653a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6864336661333565666234626235616435bd023e73705f72756e74696d653a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6839343332303963326365376361333436be029d017061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202847302c48302c49302c4a302c4b302c4c302c4d302c4e302c4f302c50302c51302c5230293e3a3a656e636f64655f746f3a3a6832323264663361353335636633346465bf0276706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a6830306164663563393165643064326566c002533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6862336134623464393461396365323434c102960173705f7374616b696e673a3a6f6666656e63653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f7374616b696e673a3a6f6666656e63653a3a4f6666656e636544657461696c733c5265706f727465722c4f6666656e6465723e3e3a3a6465636f64653a3a6864353561316436373733356465373361c202773c736d616c6c7665633a3a536d616c6c5665633c413e20617320636f72653a3a697465723a3a7472616974733a3a636f6c6c6563743a3a457874656e643c3c4120617320736d616c6c7665633a3a41727261793e3a3a4974656d3e3e3a3a657874656e643a3a6838363634383762613936613632313231c3028b013c73705f72756e74696d653a3a67656e657269633a3a636865636b65645f65787472696e7369633a3a436865636b656445787472696e7369633c4163636f756e7449642c43616c6c2c45787472613e2061732073705f72756e74696d653a3a7472616974733a3a4170706c7961626c653e3a3a6170706c793a3a6834366132363831313433303435623037c4024473705f72756e74696d653a3a7472616974733a3a5369676e6564457874656e73696f6e3a3a7072655f64697370617463683a3a6830636565356333633234336137376633c502776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6861343263623865643038633234383138c602406672616d655f73797374656d3a3a436865636b5765696768743c543e3a3a646f5f7072655f64697370617463683a3a6830396537323933633138383236646131c7024570616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a636f6d707574655f6665653a3a6864386235643666623635623864646139c802b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6864623362643132313963633538343365c90283013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4c696d697450617261746872656164436f6d6d6974733c543e2061732073705f72756e74696d653a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a6832656232653435383232613038373863ca0287013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a56616c6964617465446f75626c65566f74655265706f7274733c543e2061732073705f72756e74696d653a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a6837386665326563633738356332653939cb0281013c70616c6c65745f6772616e6470613a3a65717569766f636174696f6e3a3a56616c696461746545717569766f636174696f6e5265706f72743c543e2061732073705f72756e74696d653a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a6861643532383735636465656638336138cc027c3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a50726576616c6964617465417474657374733c543e2061732073705f72756e74696d653a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a6865383566653531313739616532373931cd026b3c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e2061732073705f72756e74696d653a3a7472616974733a3a56616c6964617465556e7369676e65643e3a3a76616c69646174655f756e7369676e65643a3a6833393938616234666137666163313433ce027a3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e2061732073705f72756e74696d653a3a7472616974733a3a56616c6964617465556e7369676e65643e3a3a76616c69646174655f756e7369676e65643a3a6836313762646434313135323566376232cf02766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a6833373636383033373233393364386536d002766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a7075743a3a6832373064336134353438636133656566d102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837326339323933346265663166386338d2024673705f61726974686d657469633a3a68656c706572735f3132386269743a3a6d756c7469706c795f62795f726174696f6e616c3a3a6839613530366236386365323538333036d302463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6834323430646630353166633666326133d402456672616d655f737570706f72743a3a7472616974733a3a4f6e556e62616c616e6365643a3a6f6e5f756e62616c616e6365643a3a6839386133656563616366393138623432d5025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864353136363062393166663965643836d6024f70616c6c65745f7374616b696e673a3a6f6666636861696e5f656c656374696f6e3a3a636f6d707574655f6f6666636861696e5f656c656374696f6e3a3a6832643231613165393837613061366238d70248616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6832343437366439643334396434623939d802633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a666f6c643a3a6834613466643532386334316361656363d902533c73705f61726974686d657469633a3a726174696f6e616c3132383a3a526174696f6e616c31323820617320636f72653a3a636d703a3a4f72643e3a3a636d703a3a6864356130633062383230376236336339da02583c73705f61726974686d657469633a3a726174696f6e616c3132383a3a526174696f6e616c31323820617320636f72653a3a636d703a3a5061727469616c45713e3a3a65713a3a6836646534663366346664323564386465db022d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6834396239396637353537633839353265dc022e73705f70687261676d656e3a3a7265647563653a3a7265647563653a3a6864626334303765633837366134373361dd027a3c73705f61726974686d657469633a3a7065725f7468696e67733a3a5065725531362061732073705f61726974686d657469633a3a7065725f7468696e67733a3a5065725468696e673e3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a6833336134383764633537636462616234de025273705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a7375626d69745f7472616e73616374696f6e3a3a6830393136653934323631656234663438df023f70616c6c65745f6f6666656e6365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6837643233626165633338323165313639e0028c0173705f636f6e73656e7375735f626162653a3a646967657374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f636f6e73656e7375735f626162653a3a646967657374733a3a5072654469676573743e3a3a6465636f64653a3a6832656439353436366339386663353237e102683c73705f636f6e73656e7375735f7672663a3a7363686e6f72726b656c3a3a56524650726f6f66206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6836346330643433313030376563313533e2023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6836623566653766323630306562316536e3028d0170616c6c65745f7363686564756c65723a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f7363686564756c65723a3a5363686564756c65643c43616c6c2c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6830366364386462383131366437306432e402437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6864653032613431373965393765333766e502437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6865613765643438383336643565316330e6023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6830633631383132363430633061393939e7023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6831653433663730353930313239643966e8023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6862653965666432313635636239383638e9025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833313065666330396230376265396634ea02706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6864323536313666666539393033393462eb02437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6866363235383633386431383633336466ec024670616c6c65745f6f6666656e6365733a3a4d6f64756c653c543e3a3a7265706f72745f6f725f73746f72655f6f6666656e63653a3a6863656563383131316530323035623964ed02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831643238666434653238303362656430ee02443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6834323861383434656633653631656537ef02443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837376535613131653432343662346634f0023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6836646162326638353363623364666637f1022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6832356336646634626362663938386434f2024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6835343238303239616363666637343164f3025c3c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6834306632333166323839333930383562f402653c73705f747269653a3a6e6f64655f6865616465723a3a4e6f6465486561646572206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6837376139333365343865313732376231f5020c436f72655f76657273696f6ef6026b3c73705f72756e74696d653a3a72756e74696d655f737472696e673a3a52756e74696d65537472696e67206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6864646438393335383033626364613264f70212436f72655f657865637574655f626c6f636bf802723c73705f72756e74696d653a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6839326361393232313337646639613663f902543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830663533376133383638623334623032fa0284016672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65732c434f6e52756e74696d65557067726164653e3a3a696e697469616c697a655f626c6f636b3a3a6830626133666530343932663239346637fb025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6835663331343565653064623638646366fc025373705f696f3a3a747269653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a626c616b65325f3235365f6f7264657265645f726f6f743a3a6833343835336663616266373861373033fd028c016672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65732c434f6e52756e74696d65557067726164653e3a3a6170706c795f65787472696e7369635f776974685f6c656e3a3a6837303866666435373737613435303930fe02446672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6e6f74655f66696e69736865645f65787472696e736963733a3a6838646464653161373761353934636361ff02713c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e46696e616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a68366536626533636263656561653332648003346672616d655f73797374656d3a3a4d6f64756c653c543e3a3a66696e616c697a653a3a68643761336465366336666438613434328103363c5420617320636f72653a3a636f6e766572743a3a496e746f3c553e3e3a3a696e746f3a3a68663863313365363362313838636239308203303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837316532613637383333306162383335830315436f72655f696e697469616c697a655f626c6f636b8403114d657461646174615f6d657461646174618503870a3c706f6c6b61646f745f72756e74696d653a3a52756e74696d652061732073705f6170693a3a72756e74696d655f6465636c5f666f725f4d657461646174613a3a4d657461646174613c73705f72756e74696d653a3a67656e657269633a3a626c6f636b3a3a426c6f636b3c73705f72756e74696d653a3a67656e657269633a3a6865616465723a3a4865616465723c7533322c73705f72756e74696d653a3a7472616974733a3a426c616b6554776f3235363e2c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c3c3c73705f72756e74696d653a3a4d756c74695369676e61747572652061732073705f72756e74696d653a3a7472616974733a3a5665726966793e3a3a5369676e65722061732073705f72756e74696d653a3a7472616974733a3a4964656e746966794163636f756e743e3a3a4163636f756e7449642c706f6c6b61646f745f72756e74696d653a3a43616c6c2c73705f72756e74696d653a3a4d756c74695369676e61747572652c28706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a5472616e73616374696f6e43616c6c46696c7465723c706f6c6b61646f745f72756e74696d653a3a497343616c6c61626c652c706f6c6b61646f745f72756e74696d653a3a43616c6c3e2c6672616d655f73797374656d3a3a436865636b5370656356657273696f6e3c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b547856657273696f6e3c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b47656e657369733c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b4572613c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b4e6f6e63653c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b5765696768743c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e2c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4368617267655472616e73616374696f6e5061796d656e743c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e2c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4c696d697450617261746872656164436f6d6d6974733c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e2c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a56616c6964617465446f75626c65566f74655265706f7274733c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e2c70616c6c65745f6772616e6470613a3a65717569766f636174696f6e3a3a56616c696461746545717569766f636174696f6e5265706f72743c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e2c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a50726576616c6964617465417474657374733c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e293e3e3e3e3a3a6d657461646174613a3a686635373033353333643437393461353486031c426c6f636b4275696c6465725f6170706c795f65787472696e73696387039c013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68396363386436626233373334353262338803aa0173705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a5472616e73616374696f6e56616c69646974794572726f723e3a3a656e636f64655f746f3a3a686334636364363965363232383266663189031b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b8a035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68396439383661393733623662343132398b03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68636161636662363463303763363566388c0320426c6f636b4275696c6465725f696e686572656e745f65787472696e736963738d036f3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a68333366643061393633633735343534348e03613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68363364623663333932646433353031358f03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68376530613732336632623239656665629003543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686134353834303235646130663538653691031c426c6f636b4275696c6465725f636865636b5f696e686572656e747392034b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6862333839363362613638393164386436930318426c6f636b4275696c6465725f72616e646f6d5f73656564940390013c70616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a52616e646f6d6e6573733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a486173683e3e3a3a72616e646f6d3a3a686561663032663063373030643631326395032b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e96039f013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073705f72756e74696d653a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a683137616534346435366362663932373397035373705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a68306662666463666665386164393232339803436672616d655f73797374656d3a3a436865636b5765696768743c543e3a3a636865636b5f626c6f636b5f6c656e6774683a3a68353366306662663461356331316162349903473c73705f72756e74696d653a3a44697370617463684572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68356532306664323739346631306162639a03323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68343861306539383462313136633032669b03214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b65729c0386016672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65732c434f6e52756e74696d65557067726164653e3a3a657874726163745f7072655f6469676573743a3a68623734383761653538326561613037339d03366672616d655f73797374656d3a3a4d6f64756c653c543e3a3a696e697469616c697a653a3a68316262356261626238613733326637639e03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68343663343739323030333264633234359f035173705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7075626c69635f6b6579733a3a6866613230623938393737623763613563a003633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833386631613537333533653334653031a103583c70616c6c65745f696d5f6f6e6c696e653a3a4f6666636861696e4572723c426c6f636b4e756d6265723e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838323233613963643532336637636335a2031850617261636861696e486f73745f76616c696461746f7273a3031950617261636861696e486f73745f647574795f726f73746572a40358706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a63616c63756c6174655f647574795f726f737465723a3a6836616466653638613034626161663131a5031f50617261636861696e486f73745f6163746976655f70617261636861696e73a603386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864653534663438363265663732633830a7033c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6835363465613433393333383230323438a8032850617261636861696e486f73745f676c6f62616c5f76616c69646174696f6e5f7363686564756c65a9032350617261636861696e486f73745f6c6f63616c5f76616c69646174696f6e5f64617461aa0358706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a6c6f63616c5f76616c69646174696f6e5f646174613a3a6866643730366532623163633438353436ab031c50617261636861696e486f73745f70617261636861696e5f636f6465ac035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831386466666164383262626137316161ad031750617261636861696e486f73745f6765745f6865616473ae03a201706f6c6b61646f745f7072696d6974697665733a3a70617261636861696e3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f7072696d6974697665733a3a70617261636861696e3a3a43616e646964617465436f6d6d69746d656e74733e3a3a656e636f64655f746f3a3a6837633165383837363038653565396136af031d50617261636861696e486f73745f7369676e696e675f636f6e74657874b0033c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6839623364386635393636376634346339b1031e4772616e6470614170695f6772616e6470615f617574686f726974696573b203543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6835303131613762663166303730343735b3032f4772616e6470614170695f7375626d69745f7265706f72745f65717569766f636174696f6e5f65787472696e736963b4038b0173705f66696e616c6974795f6772616e6470613a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f66696e616c6974795f6772616e6470613a3a45717569766f636174696f6e50726f6f663c482c4e3e3e3a3a6465636f64653a3a6837326465373838333262633964346264b5037273705f73657373696f6e3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f73657373696f6e3a3a4d656d6265727368697050726f6f663e3a3a6465636f64653a3a6833323061313831316232386633363763b6034c6672616d655f73797374656d3a3a6f6666636861696e3a3a5369676e65723c542c432c583e3a3a6163636f756e74735f66726f6d5f6b6579733a3a6864376631636436303136303461353364b70368636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6834343135343233363331336233373563b8034a3c73705f636f72653a3a63727970746f3a3a4163636f756e744964333220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839366436396166343461343165393866b903303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835356266646664393631653865633036ba03274772616e6470614170695f67656e65726174655f6b65795f6f776e6572736869705f70726f6f66bb034b70616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a50726f76696e67547269653c543e3a3a67656e65726174655f666f723a3a6861313231303264666438333634646266bc03366861736862726f776e3a3a6d61703a3a486173684d61703c4b2c562c533e3a3a6765743a3a6865653262633435353665333930636435bd0338747269655f64623a3a6c6f6f6b75703a3a4c6f6f6b75703c4c2c513e3a3a6c6f6f6b5f75703a3a6836366431313739353561613063336239be0315426162654170695f636f6e66696775726174696f6ebf03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832336638363233626334303234323365c003386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833656234623238333838346335393735c1031b426162654170695f63757272656e745f65706f63685f7374617274c20321417574686f72697479446973636f766572794170695f617574686f726974696573c3032153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b657973c4034e73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a656432353531395f67656e65726174653a3a6865626533643164666363393838323263c5034e73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f67656e65726174653a3a6863353737343666393336623634666539c6031f53657373696f6e4b6579735f6465636f64655f73657373696f6e5f6b657973c7037a706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f7220706f6c6b61646f745f72756e74696d653a3a53657373696f6e4b6579733e3a3a6465636f64653a3a6834363235653231363663393463653261c8038f0173705f6170706c69636174696f6e5f63727970746f3a3a737232353531393a3a3c696d706c2073705f6170706c69636174696f6e5f63727970746f3a3a7472616974733a3a52756e74696d655075626c696320666f722073705f636f72653a3a737232353531393a3a5075626c69633e3a3a746f5f7261775f7665633a3a6864363462663930386332373362616435c9031d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e6365ca035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837326165636431333737316663343666cb03205472616e73616374696f6e5061796d656e744170695f71756572795f696e666fcc034873705f72756e74696d653a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a6863656133366331663333663932376462cd035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6834656538643664373164383434646639ce03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838383062353631663836626364646661cf03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861303933643964613034326635333035d0033c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6465706f7369745f636f6e73656e7375733a3a6862383638666237613132356339363330d103457363686e6f72726b656c3a3a706f696e74733a3a52697374726574746f426f74683a3a66726f6d5f636f6d707265737365643a3a6864663038366666643863323963336463d203407363686e6f72726b656c3a3a7672663a3a5652464f75747075743a3a6174746163685f696e7075745f686173683a3a6833346366343131353330303362373664d303376672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a6833393934383265623136313363663164d4033b70616c6c65745f626162653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835303662333931383133613664383639d5036b3c70616c6c65745f626162653a3a5f5f4765744279746553747275637452616e646f6d6e6573733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832363039363530643066303062323862d6034470616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6862346363666430316537323437646263d7039a013c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839363964376131383633376232663433d80396013c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837356235653862346234393635303864d90348616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a456e7472793c4b2c563e3a3a6f725f696e736572743a3a6865616133393235343834366336333438da033c73705f70687261676d656e3a3a6e6f64653a3a4e6f64653c413e3a3a7365745f706172656e745f6f663a3a6836663263306664343661613932353337db033373705f70687261676d656e3a3a6e6f64653a3a4e6f64653c413e3a3a726f6f743a3a6832316630373638346537643564303764dc032b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6831346164313732326134383739386163dd033b73705f70687261676d656e3a3a6e6f64653a3a4e6f64653c413e3a3a69735f706172656e745f6f663a3a6862356162343566313132303834643734de03b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6836643838616332626337663665323765df035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863616165343139346135396164343435e00385013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7472616e736665723a3a6862643733393034366333346266653232e1033c70616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830313935353161366335626431326531e2033e70616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832333133313236316661323137313432e3037270616c6c65745f7574696c6974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7574696c6974793a3a43616c6c3c543e3e3a3a6465636f64653a3a6838386461383762613238613266303638e40373706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f7220706f6c6b61646f745f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a6866396362666438303530613064313364e50390013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a657874656e645f6c6f636b3a3a6835623232396564376531363131656161e603386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866383234326433356331666131396161e7033d70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7570646174655f6c6f636b733a3a6836646434616437663665316163323661e8033c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6830386635366661363561353661306239e9039a013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a726570617472696174655f72657365727665643a3a6861396466383336656638316362636563ea03b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6863303163613866346639386663366135eb033f70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6830376234653038313133386636373934ec034170616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6838663230613133616266653561363664ed036e3c70616c6c65745f62616c616e6365733a3a5f5f476574427974655374727563744163636f756e743c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831343431646665313831373361393437ee034a70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6861633461613937363265313938663831ef03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6831356430343035646638313361636565f003437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6835393332353535353339646462623163f103437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6864356662343937613239363739653263f203303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838303536353563653638613630323537f3034a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6835626563633562316235613366393262f403463c70616c6c65745f626162653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6839653030656437363032326439626333f503493c70616c6c65745f7574696c6974793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838353435346663313266376432633238f603643c636f72653a3a697465723a3a61646170746572733a3a436c6f6e65643c493e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a666f6c643a3a6866646663353262353438373138366138f703483c706f6c6b61646f745f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838636662363161356536663038623363f803463c70616c6c65745f7375646f3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6864613835643563383732616634383433f903473c6672616d655f73797374656d3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6839396263323536363336626265663362fa034b3c70616c6c65745f7363686564756c65723a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6833366264353566623132346332663065fb03443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832383737313631363563316638313361fc03493c70616c6c65745f6772616e6470613a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6865313865333466386365616465396136fd034b3c70616c6c65745f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6833316636306132313835613330336461fe034b3c70616c6c65745f64656d6f63726163793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830323538306466323837396332626162ff034e3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68343064613535313332386335313331658004543c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683361333261613938303638323831366381044e3c70616c6c65745f6d656d626572736869703a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686565383966336139376562313731623082044a3c70616c6c65745f74726561737572793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686565306462356365346330653739383483045e3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68393833666536616263356561383366308404593c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a736c6f74733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686637633561393664353363303536376485045d3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686132396361333732393164303733656686045a3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6833303034633761363034323365353937870439747269655f64623a3a6e6f64655f636f6465633a3a4e6f6465436f6465633a3a6465636f64653a3a686231363066383337643232336434383088046b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683963643038636132346436663861346289045a3c70616c6c65745f7574696c6974793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68373765623336626165393161626534318a044670616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a656e737572655f736f727465645f616e645f696e736572743a3a68656164666265343532353765633333398b04437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68343936396565366439393766663238628c04706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a68336334613936363431353538316261388d04386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68376230386165303531636431376239348e04b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a68323335373266363562613662326436388f045f3c70616c6c65745f7574696c6974793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a683038323739336464663265363539343390046d3c73705f747269653a3a6e6f64655f636f6465633a3a4e6f6465436f6465633c483e20617320747269655f64623a3a6e6f64655f636f6465633a3a4e6f6465436f6465633e3a3a6272616e63685f6e6f64655f6e6962626c65643a3a6861326432353235343039363563633561910472747269655f64623a3a6e6962626c653a3a6e6962626c657665633a3a3c696d706c20747269655f64623a3a6e6962626c653a3a4e6962626c655665633e3a3a617070656e645f6f7074696f6e616c5f736c6963655f616e645f6e6962626c653a3a6862303363326536613732633836356235920441747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e3a3a636f6d6d69745f6368696c643a3a683065363938303064653539386432376693045c747269655f64623a3a6e6962626c653a3a6e6962626c657665633a3a3c696d706c20747269655f64623a3a6e6962626c653a3a4e6962626c655665633e3a3a64726f705f6c617374733a3a68366162353562636239623236303661629404623c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a68616431383365396337303839303038669504703c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6861623234333439653835613732333136960440706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a746f5f61736369695f6865783a3a683136346536363238633933626238623597044a706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a6574685f7265636f7665723a3a683663323662303639323864343964373998045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683130653930303363666338326438316199045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68396664393435313265646636623563359a04386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68353037316466366662306437646230309b045573705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a736563703235366b315f65636473615f7265636f7665723a3a68646465343234366534353439396231629c045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68636439373966373232313566613937369d04386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68343465646237653235373165396432659e04543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68303237613330613062376534333266669f047c7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c5230293e3a3a6465636f64653a3a6865323233613133366435366636626537a0047f7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202851302c5230293e3a3a656e636f64655f746f3a3a6830363864666136393638363433306232a104437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830383635656633373563353063323966a204437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830646265383736353563313532376635a304437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6832316363343163613434633239373137a404437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6864366536343961633139666466653330a504a601706f6c6b61646f745f7072696d6974697665733a3a70617261636861696e3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f7072696d6974697665733a3a70617261636861696e3a3a416272696467656443616e646964617465526563656970743e3a3a656e636f64655f746f3a3a6836396262633535343461666231613037a6044d706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6834646436323432333832653366306239a7044f706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6831636463346334356534363837626263a80458706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6832616333643434356165613337383362a904a3013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726566697844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862386164613039613063623332646163aa044a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6861376539633432306335316638386465ab04483c5b543b20385d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6863313061356565323337336263386337ac045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839316133363466366637366231643633ad044c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a70726f636573735f636c61696d3a3a6861353463306466323739623963333735ae045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6861616634366631386636616330636163af0495013c70616c6c65745f76657374696e673a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a56657374696e675363686564756c653c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6164645f76657374696e675f7363686564756c653a3a6834396161366537386261313230393237b004386861736862726f776e3a3a6d61703a3a486173684d61703c4b2c562c533e3a3a656e7472793a3a6861623539613061333233343432346532b104396861736862726f776e3a3a6d61703a3a486173684d61703c4b2c562c533e3a3a696e736572743a3a6862346164396231613065386639323334b2044d636f72653a3a686173683a3a696d706c733a3a3c696d706c20636f72653a3a686173683a3a4861736820666f722028412c42293e3a3a686173683a3a6831343666623930326431313835373263b3043e6861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a726573657276655f7265686173683a3a6839353635356235616437623461633035b4046f3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a736c6f74733a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6863306662343966646537653532373766b504443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837363934346430323738306266373633b60495013c70616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a4b65794f776e657250726f6f6653797374656d3c2873705f636f72653a3a63727970746f3a3a4b65795479706549642c44293e3e3a3a636865636b5f70726f6f663a3a6862643730326464653531636632356466b70482017061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202850302c51302c5230293e3a3a656e636f64655f746f3a3a6835323537653064616334333833646130b8045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6861653032323039363139356564306265b9045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6861373836346361323234313433306463ba04543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6834393136393333316435373335376562bb04753c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6865656661663861666335326164616434bc04386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862643764316663356439636265323665bd045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831633936343838313235613064343961be04a2013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4d6f64756c653c543e20617320706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a5265676973747261723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6e65775f69643a3a6836326662643930346239653736326366bf044a706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a736c6f74733a3a4d6f64756c653c543e3a3a6465706f7369745f68656c643a3a6834366435383537313965346532343731c004386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839643263663239316331356237646463c1045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837313331376333613663663435366335c2045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6835643239383134333430323437613862c3045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862346238363762313062646363306365c4047f7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202851302c5230293e3a3a656e636f64655f746f3a3a6863653161316466313931633565353531c5045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6830346364353938643036666332383935c604386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863343934613836663464346239663736c70468636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6837343161303932633261326531666432c804386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832666366306237393333303265343362c904a9013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4d6f64756c653c543e20617320706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a5265676973747261723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a72656769737465725f706172613a3a6866383833343633303436633637333663ca04386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833326562313137376561323531373266cb045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839633462303761373334636437326263cc04386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832613735336130323236343066343663cd045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6866336135393165616431376161643264ce0451706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a70617261636861696e5f686561643a3a6862306666303632366661303263343838cf044a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6830336262353061376339343762333533d0045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832393734376139383030613539353930d104386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833313966343737666331326139323065d2044470616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a646f5f70687261676d656e3a3a6837373939663236653632653262363332d3043f70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f65787465726e616c3a3a6861616630663964363136633763356462d4043d70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f7075626c69633a3a6830333566333837623063396331653964d5043470616c6c65745f64656d6f63726163793a3a4572726f723c543e3a3a61735f75383a3a6830326662343231363939313366623964d6043570616c6c65745f64656d6f63726163793a3a4572726f723c543e3a3a61735f7374723a3a6836643861343531623238366635393261d704673c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a6835633264653839386137633261633935d8045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833363565353932653436313934333232d904386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831613062363037303230326338616634da044170616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a646f5f656e6163745f70726f706f73616c3a3a6831326463643831393637313936616338db049f0170616c6c65745f64656d6f63726163793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a507265696d6167655374617475733c4163636f756e7449642c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6863666463386331363366313432356666dc044170616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a646f5f7363686564756c655f6e616d65643a3a6863613865666531343762616538316166dd045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6834353265316234663563656230396466de04437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6836303836363633303833643131653365df04753c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6864383731373932313064376163313365e0043f70616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6865303766393763653232666366663264e1044170616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6830653131383034646666303531356337e204437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6862346335316236383930613739653738e3044c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a736c6f74733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6865633531663737306362663838343161e4044e706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a736c6f74733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866396464386330343965663930623134e5047e3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a736c6f74733a3a5f5f476574427974655374727563744f6e626f617264696e673c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838363261623366663064643132343161e6047b3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a736c6f74733a3a5f5f4765744279746553747275637457696e6e696e673c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836646664633034393966393735643233e7047f3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a736c6f74733a3a5f5f4765744279746553747275637441756374696f6e496e666f3c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866653434303235626533396232346632e804ab013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4d6f64756c653c543e20617320706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a5265676973747261723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a646572656769737465725f706172613a3a6866656139373639343864303332343764e90441616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a7365617263683a3a7365617263685f747265653a3a6833626363653631363730393838343535ea04623c70616c6c65745f617574686f72736869703a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6862323235343466346162383935356330eb0448706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a736c6f74733a3a4d6f64756c653c543e3a3a68616e646c655f6269643a3a6862623039326366323231376530396332ec04303c282920617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831356364316262633037326262353161ed042b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6831343231336361373632393939663463ee043c70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6838346232303732643166326235616666ef043e70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863306437373162313862393139613536f0043e70616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832333364653137306435323633303763f1044070616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832643336326265313130613364316437f2044970616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6833366261613464613736386436303134f3049b013c70616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835366532366337616464323537613062f40434636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6864643565323164336663653937306161f5042e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6833366638616236656530373561663037f6043c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6838346565623838333537663131633536f70434636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6862636362663764656337396631636336f8042e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6830613964393261633234663535316131f9043c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6835306665373832353039316163643431fa042d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6836306463353866643939393239643461fb0434636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6861363133643434626338363530373539fc042e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6838616530643636643965663561663231fd043c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6832393430306565303065656433396161fe04fa01616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a48616e646c653c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4e6f64655265663c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4d75742c4b2c562c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4c6561663e2c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a456467653e3a3a696e736572743a3a6836383837333061353038313035316233ff04fe01616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a48616e646c653c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4e6f64655265663c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4d75742c4b2c562c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a496e7465726e616c3e2c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a456467653e3a3a696e736572743a3a683733643264393164653831353135336180055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832663966313262666130373833373937810544706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73797374656d3a3a6839386236663834313937306536643934820547706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7363686564756c65723a3a6862353764666132633965353533343833830545706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696e64696365733a3a6831643133333439356433326135663339840546706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f62616c616e6365733a3a6838333663356561353332653462336231850545706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7374616b696e673a3a6834623139666337303064326639353864860546706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6f6666656e6365733a3a6835353138313764393035626233396265870545706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73657373696f6e3a3a6864393933656332653963346134666437880545706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6772616e6470613a3a6861346338363035313939656337336464890547706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696d5f6f6e6c696e653a3a68633939616134663265303461393664398a054070616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68353563336331643464326233346233378b053e70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68336433643035323962356562306237628c0547706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f64656d6f63726163793a3a68626131366664633266343539336639388d054970616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68383037356330616663663034663833648e05613c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a68303433313833346462333266666238358f0552706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6c6c6563746976655f496e7374616e6365313a3a6837656661336663613037353939656563900550706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f656c656374696f6e735f70687261676d656e3a3a6831643935366433653466396365303761910552706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6d656d626572736869705f496e7374616e6365313a3a6832353838323931303635333735323966920546706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f74726561737572793a3a6862363862653130366433656361313936930543706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f736c6f74733a3a6836333065643035353761313861333464940547706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7265676973747261723a3a6839653636313762316361306161343235950544706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636c61696d733a3a6836663639313862626132383236386137960545706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f76657374696e673a3a6861326364343535653736363432333737970545706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7574696c6974793a3a6830333766656166636464306431306334980542706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7375646f3a3a6836636563346633383161323634333739990596013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178566f74657344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68646437373636343335353331636661319a05a1013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a507265696d616765427974654465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68626262323534656536396161393935659b059b013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a436f6f6c6f6666506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68343831366233363130366561363863369c05a3013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a46617374547261636b566f74696e67506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68346338353239663138303364653539349d059c013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d4465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68356636303831313335376230613438669e059a013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4c61756e6368506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68646164373234636263353036646661649f059d013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456e6163746d656e74506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832326230363462363733393437633639a0056e3c70616c6c65745f64656d6f63726163793a3a5f5f47657442797465537472756374566f74696e674f663c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833663662663439663064353830336137a1053c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6861316261646536366538646132663339a205713c70616c6c65745f64656d6f63726163793a3a5f5f476574427974655374727563745075626c696350726f70733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835626634613032393335366165613435a305386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831376465396633613733613862373865a4054170616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a696e6a6563745f7265666572656e64756d3a3a6837623763643138633361316165343335a5053b70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6261636b696e675f666f723a3a6830363337623662336439383639626166a6053c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6838626662353133643563626535353736a7055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864383731376365643162363436356534a805386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830383063316136613034356230636466a905b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6835343861373230636363613636653364aa056b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837303637363539303438343264636134ab058f0170616c6c65745f64656d6f63726163793a3a766f74653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f64656d6f63726163793a3a766f74653a3a4163636f756e74566f74653c42616c616e63653e3e3a3a6465636f64653a3a6862313031633863396636333566336337ac057a70616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a6839613030323930323433656366326266ad056c70616c6c65745f7375646f3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7375646f3a3a43616c6c3c543e3e3a3a6465636f64653a3a6866373930633536326330366239666432ae056b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7531363e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6839393238326635343030303264306139af05573c70616c6c65745f7375646f3a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6832363234303863393630393361663935b0055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6838323464323361376265393638633138b1053f70616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a646f5f63616e63656c5f6e616d65643a3a6866616134636334623238343331666637b205386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833353962356638613935636535393132b3054a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6832303336343032633965306536336366b405366672616d655f73797374656d3a3a4d6f64756c653c543e3a3a626c6f636b5f686173683a3a6839303736616366343666366363616362b5055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6834396162663434373238316539613538b605386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832323332366430653561376634356261b7055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833303364323437303938633061613761b805706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6865363331316130666466373138333366b9055c3c70616c6c65745f64656d6f63726163793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6836373932353365396664396165653430ba055f3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6861346466343364633663353664623465bb052b616c6c6f633a3a736c6963653a3a6d657267655f736f72743a3a6834666338363733316430636333303433bc054b6672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a7365745f6d656d626572735f736f727465643a3a6834303032643437313464363439373162bd055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833356633616562636236383334663531be055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864623336666561343334313565616661bf05437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6834623036623831346533616166663436c0055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862316161303563373836656263643438c105386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834633333366563383633393331306561c2054c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a76616c69646174655f616e645f6765745f70726f706f73616c3a3a6864616330396130653035326639326334c3054470616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a66696e616c697a655f70726f706f73616c3a3a6864366563333130633633663730356530c405653c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6837313938353139316663393634623732c50599013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6832623335333635356436616432356432c6058d013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f7072696d653a3a6838616136363064663135613863386662c7055b3c70616c6c65745f74726561737572793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6862393032633336653663346431636566c8054c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a7365745f68656164733a3a6830636261396538643139653438306435c905543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6831366464353866626235363137343833ca05437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6837643336623932626134366634316239cb056e3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6831366461373764346237346666613637cc053970616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a7570646174655f6c6f636b3a3a6839666136376133646462636465323039cd055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6835633533616366373832366262623863ce05513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6832343463643132616363396566663965cf053c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6862663763353734356664643437373034d005437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830646661363236353365616637313036d1053870616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f766f74653a3a6830656332623532353065343464613361d2053570616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a70726f78793a3a6832333962353264326437613864366439d305386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864353430346539653537613735316330d4055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837383662316532313837633833353937d505386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865653230373961636334356330616662d605437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6834613462333264356566636635636239d7055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831653039643231626266386461323539d8055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864616263383735663264326461333731d905386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833333538353462343932313563383932da053c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f64656c65676174653a3a6861613433396365636134663138663266db053e70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f756e64656c65676174653a3a6864333631346232333630373930623265dc054370616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6e6f74655f707265696d6167655f696e6e65723a3a6834643063306633393163663130306165dd054c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6e6f74655f696d6d696e656e745f707265696d6167655f696e6e65723a3a6865303064393531613664353262383934de055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833643661393563303239633635333963df055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865626132666638346233666538643465e005386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861363235633161336238303266306636e1053f70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f72656d6f76655f766f74653a3a6865313965316538636532636336306165e2054a70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7265647563655f757073747265616d5f64656c65676174696f6e3a3a6834616131386164393237343961666230e3054a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6839623734386262356165333931326562e4053f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6833633732383364333165376632633765e505713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6863346132356662396634346438393434e6057f7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202851302c5230293e3a3a656e636f64655f746f3a3a6836396631346666626636343737306234e705920170616c6c65745f64656d6f63726163793a3a766f74653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a766f74653a3a4163636f756e74566f74653c42616c616e63653e3e3a3a656e636f64655f746f3a3a6837303931666663383934303737623464e8057d70616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a656e636f64655f746f3a3a6836363561313233643464653938333061e90577706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f72756e74696d653a3a4576656e743e3a3a656e636f64655f746f3a3a6862663135383362316430643261616135ea058e0170616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6c6c6563746976653a3a5261774576656e743c486173682c4163636f756e7449642c493e3e3a3a656e636f64655f746f3a3a6831386365343264353834346464376237eb05763c70616c6c65745f617574686f726974795f646973636f766572793a3a43616c6c3c543e206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6833616539373530373936316232396233ec056f3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6861646337353438313961356661373739ed057c7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c5230293e3a3a6465636f64653a3a6863396332646434303931636565353539ee054a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6865613765333537376232663066376338ef05443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832613231653535383663373363613165f005443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6834343661393039326264323465633566f105443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6865393834323539356163666263626263f205443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838363766643164366463646461373937f305443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6863666665633837623036643465623662f405543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6832383030373863333365303832383662f505543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6833666362343461613939303330346634f605543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6838653266303734656435356537306235f705383c2a636f6e7374205420617320636f72653a3a666d743a3a506f696e7465723e3a3a666d743a3a6834383263333130313336663739386136f805386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865336661393662343665356235333231f905513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6836666166646262356630366535336362fa05513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6839373038386434316265343563393231fb05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866646663656430353661646136616261fc054b6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a72656769737465725f65787472615f7765696768745f756e636865636b65643a3a6832363663393533376264313962643365fd05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866326165386331633063356562323261fe05766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a7075743a3a6832376634383638383330333132363433ff05563c73705f72756e74696d653a3a44697370617463684572726f722061732073705f72756e74696d653a3a7472616974733a3a5072696e7461626c653e3a3a7072696e743a3a686631643738633339346235303264616680069d017061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202847302c48302c49302c4a302c4b302c4c302c4d302c4e302c4f302c50302c51302c5230293e3a3a656e636f64655f746f3a3a68393732323033353233366366646334338106437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68396634366238613031376566623532348206fa013c285475706c65456c656d656e74302c5475706c65456c656d656e74312c5475706c65456c656d656e74322c5475706c65456c656d656e74332c5475706c65456c656d656e74342c5475706c65456c656d656e74352c5475706c65456c656d656e74362c5475706c65456c656d656e74372c5475706c65456c656d656e74382c5475706c65456c656d656e74392c5475706c65456c656d656e7431302c5475706c65456c656d656e743131292061732073705f72756e74696d653a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a6164646974696f6e616c5f7369676e65643a3a68373335346532373461656537626231378306303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68386434366566323039336262643135338406303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68386438633238313861363566313563308506483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6862393062383865643762323866396231860638747269655f64623a3a6c6f6f6b75703a3a4c6f6f6b75703c4c2c513e3a3a6c6f6f6b5f75703a3a683963353134656639353462393631363987062b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a683030356239656462363835656430366688065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a686137613634623838656362623963326289065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68356432346463383761376461316338668a065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68356139393066363434316330663461658b0651706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a6e6f74655f706173745f636f64653a3a68656636373531643232626134326232348c0649706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a6c6f63616c697a65645f7061796c6f61643a3a68303766313130623635313134333065348d065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68396163396666613834346238303437308e06673c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a68383239323161393435303663663539388f065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68386135313930383739653563383962629006386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68613636386139343636306337313465339106743c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a683863616638623362633662643266653292065c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a446f75626c65566f74655265706f72743c50726f6f663e3a3a7665726966795f766f74653a3a683665376664303766626137356665396193063d70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a69735f6f6e6c696e655f6175783a3a686166303538613163373365613064366694064d73705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6e6574776f726b5f73746174653a3a686430616535656661666635383366393495064a73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7369676e3a3a68643862306166353033303261633632319606473c70616c6c65745f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68303633396130616239333063623761399706373c285431302c5431312920617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686231373533643661363437376163316298063970616c6c65745f7375646f3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683530313538346437376537303430366399063b70616c6c65745f7375646f3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68333330356134393932383735396636329a063c70616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68343531376237333037383932663737309b063e70616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68313161343134393839633234663736309c064770616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68376466616663366632333433333634359d063e70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68626564663866323330333038306634399e064070616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68633833383164383764653032396165359f06783c70616c6c65745f696d5f6f6e6c696e653a3a5f5f476574427974655374727563745265636569766564486561727462656174733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862373364336431366137626134613064a00651706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832323431643964386337646363646335a10653706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6830646538633037313230306534383539a2068f013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a5f5f4765744279746553747275637452656c61794469737061746368517565756553697a653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838306333663238666631323830383165a30683013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a5f5f47657442797465537472756374467574757265436f64653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838303066656133633164323361643835a40685013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a5f5f4765744279746553747275637450617374436f64654d6574613c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832306330316639663236363332386464a5063673705f747269653a3a6e6f64655f636f6465633a3a7061727469616c5f656e636f64653a3a6862306138376633326434653931616134a60660747269655f64623a3a6e6962626c653a3a6e6962626c65736c6963653a3a3c696d706c20747269655f64623a3a6e6962626c653a3a4e6962626c65536c6963653e3a3a72696768745f697465723a3a6864336163363763656466366436663763a7062b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6832613265653261336563333738366632a806483c706f6c6b61646f745f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838636662363161356536663038623363a9063c747269655f64623a3a7472696564626d75743a3a4e6f646553746f726167653c483e3a3a616c6c6f633a3a6863393264336664643339373835303130aa065c3c70616c6c65745f7375646f3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6834646631643232643136373830376338ab06543c747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e20617320747269655f64623a3a547269654d75743c4c3e3e3a3a696e736572743a3a6839353465343437353663643665333338ac063e747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e3a3a696e736572745f61743a3a6835656532346634613766633137653962ad063e747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e3a3a72656d6f76655f61743a3a6834623136343234633738343464663237ae063a747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e3a3a63616368653a3a6831303639313235343334343630346537af0645747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e3a3a696e736572745f696e73706563746f723a3a6831393138646565643835363735343431b006773c736d616c6c7665633a3a536d616c6c5665633c413e20617320636f72653a3a697465723a3a7472616974733a3a636f6c6c6563743a3a457874656e643c3c4120617320736d616c6c7665633a3a41727261793e3a3a4974656d3e3e3a3a657874656e643a3a6835616232346365663630346437326465b10645747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e3a3a72656d6f76655f696e73706563746f723a3a6836386361613164633737323061613439b2063c747269655f64623a3a7472696564626d75743a3a4e6f64653c4f3e3a3a66726f6d5f656e636f6465643a3a6832623933366431333336393830366539b30638747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e3a3a6669783a3a6833336236323632396638366632633838b40632747269655f64623a3a7472696564626d75743a3a636f6d62696e655f6b65793a3a6838363163303934363638303234386664b5063e747269655f64623a3a7472696564626d75743a3a4e6f64653c4f3e3a3a696e6c696e655f6f725f686173683a3a6833363638626635356431343937383437b60635747269655f64623a3a7472696564626d75743a3a656d7074795f6368696c6472656e3a3a6865393332626661623964366664353335b70665747269655f64623a3a6e6962626c653a3a6e6962626c65736c6963653a3a3c696d706c20747269655f64623a3a6e6962626c653a3a4e6962626c65536c6963653e3a3a746f5f73746f7265645f72616e67653a3a6833643964326439323432643532303166b8062c636f72653a3a636c6f6e653a3a436c6f6e653a3a636c6f6e653a3a6839333833346565383661663164323466b9065f3c70616c6c65745f76657374696e673a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6866386164626430343132393664346438ba06613c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6830343638626536646464353263643561bb063a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6832643163306365343536393366653936bc063b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6863646266623839343637333333336631bd063a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6832613732343135303339383833623563be06723c70616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6839336535383932346362333233643636bf06763c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a6174746573746174696f6e733a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6838633031353739633232633664353762c006746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6834393431343235666664323964386134c106503c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c543e20617320686173685f64623a3a4861736844423c482c543e3e3a3a696e736572743a3a6837666566323333646638353133316139c2064470616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a50726f76696e67547269653c543e3a3a71756572793a3a6861303932343165646538363130316333c306386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837383335306134303061663866326634c4062b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6833396263336438613465663466633366c5062b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6839336237343237636434353832396533c606aa0170616c6c65745f64656d6f63726163793a3a74797065733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a74797065733a3a5265666572656e64756d5374617475733c426c6f636b4e756d6265722c486173682c42616c616e63653e3e3a3a656e636f64655f746f3a3a6833373663313731336663313934386465c7063e70616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6833613532616230653231616263393966c8064070616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6833656538346635353432613366323262c906437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6833633861386232616337366432323761ca064570616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6831313331363339393731663763626362cb064770616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6839613462353265623466373763633233cc065070616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6830333561316666306532646636366663cd069f013c70616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a57696e646f7753697a6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830633563336330373662646237663938ce0653706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a6174746573746174696f6e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864653266636231623463383461636330cf0655706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a6174746573746174696f6e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862666131643934363330366332303632d0064a70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6834616365663730326537656462373162d1065370616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6861666538386636336663656432323639d206a3013c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a576569676874546f46656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833346338383962393339303662643036d306aa013c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863373664383337326265393832353839d4065170616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6861626665373461306430616462353266d5064a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6833353266653039353262663765373634d606553c73705f72756e74696d653a3a4d756c74695369676e61747572652061732073705f72756e74696d653a3a7472616974733a3a5665726966793e3a3a7665726966793a3a6862623662363265393031333834373631d7066073705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a736563703235366b315f65636473615f7265636f7665725f636f6d707265737365643a3a6865616532313439616230313666396561d806683c70616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6833653866656366336161623733366162d906366861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a696e736572743a3a6865343466656139366238333734383663da063e6861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a726573657276655f7265686173683a3a6861623265366637656336633937643235db065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6861613366353935396437343534363966dc065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6835323731336332633439303737633764dd065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832626130333361316430323738303637de064d706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a737761705f6f7264657265645f6578697374656e63653a3a6836643734336462386139663639316565df06733c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6837616461383932303665336566363636e006713c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e46696e616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a6833663338333036613566303537643361e1063970616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a6832616431336636653261616363633964e2063c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6864383134636361633439666130653739e306386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835623830393163656466383730636632e4064a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6833623361303261636661336532323433e5064d6672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a636f6d707574655f6d656d626572735f646966663a3a6866643237313339616138356166373334e60693013c285475706c65456c656d656e74302c5475706c65456c656d656e74312c5475706c65456c656d656e74322c5475706c65456c656d656e74332c5475706c65456c656d656e7434292061732070616c6c65745f73657373696f6e3a3a53657373696f6e48616e646c65723c4149643e3e3a3a6f6e5f6e65775f73657373696f6e3a3a6866623561316231653630313135383739e7063d70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a7363686564756c655f6368616e67653a3a6865633933326663396166326535336632e806683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a6833356563626230306230653062306565e906633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6834366431353662343164323130653562ea063e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6831393962616639313363346436333034eb063c70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6838343565373366333865633665633138ec063e70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862646130336636323230336139623565ed06703c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637443757272656e7453657449643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830333866643236646236636637623038ee06693c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863613163383738376464323335336131ef0699013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6839626464663232633636396262373131f0065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6861323665323035613337643066636366f1064170616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6839653665346565336434643339643037f2064370616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6863326139396531646336363466633833f3064370616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6865656562353663326130333230666335f40650706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6861313030626536323936366137656463f50652706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865373866336561386236623735343261f6067f3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a5f5f47657442797465537472756374446562746f72733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864383763303935663035663961306438f70682013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a5f5f476574427974655374727563744e6578744672656549643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866623166346562643964393032643863f8064d3c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c543e20617320686173685f64623a3a4861736844423c482c543e3e3a3a6765743a3a6831646236366638316562313964376366f906513c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c543e20617320686173685f64623a3a4861736844423c482c543e3e3a3a656d706c6163653a3a6861636434333537656534343637653339fa06503c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c543e20617320686173685f64623a3a4861736844423c482c543e3e3a3a72656d6f76653a3a6838393963653761393236363938386438fb06523c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c543e20617320686173685f64623a3a4861736844423c482c543e3e3a3a636f6e7461696e733a3a6833666230613063666330616539363638fc065f3c70616c6c65745f6772616e6470613a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6863653739646538323535613863363531fd06563c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c543e20617320686173685f64623a3a41734861736844423c482c543e3e3a3a61735f686173685f64623a3a6831313464366164326236336230353339fe065a3c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c543e20617320686173685f64623a3a41734861736844423c482c543e3e3a3a61735f686173685f64625f6d75743a3a6834356131363337306537316263313365ff06503c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c543e20617320686173685f64623a3a4861736844425265663c482c543e3e3a3a6765743a3a68383162633739363265646432303432308007553c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c543e20617320686173685f64623a3a4861736844425265663c482c543e3e3a3a636f6e7461696e733a3a683239633332303033323134323830323881075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a686563666333386165393331663864313282075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683132393138373466376639613761363783074c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a76616c69646174655f616e645f6765745f70726f706f73616c3a3a683537656537346432326563616138646684074470616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a66696e616c697a655f70726f706f73616c3a3a686333363264626337613663373930373385075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68306664313164633839666235633339668607386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683737336461633037316263393334336187075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68336135623533323333653338336363328807643c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a686138616531646339366662316363346589072b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a68306235636435333938663833313062668a07663c636f72653a3a697465723a3a61646170746572733a3a46696c7465723c492c503e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68386438366636386237663265346331378b076b3c636f72653a3a697465723a3a61646170746572733a3a46696c7465723c492c503e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a68333838303936643236346364356363368c073e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a68366437393362363437303039306564618d072b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a68323739373031313965376330383861638e07633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68386333646161346466353466356139668f07683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a683531663538646363303735383837663490073e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a683736336161613963393266383831393391078b013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61704974657261746f723c4b2c562c4861736865723e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a683137316634396437613739326434366192073c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a686130343138666433306562393463373793073e70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68333333366166343164383938356661619407703c70616c6c65745f73657373696f6e3a3a5f5f4765744279746553747275637443757272656e74496e6465783c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683861633566386365346132663863633895073d70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683662336435323039653234623262356396073f70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a683737633161396461623062306163616697074870616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6861653738316435343366656431346664980795013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6f64756c65496444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68663133353566616231383365623861379907a1013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5469705265706f72744465706f7369744261736544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68306431373966353866306362666436649a079a013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a54697046696e6465727346656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68326636346334303531363666303637669b0799013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a546970436f756e74646f776e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68396136393939383835306232633230399c0791013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4275726e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68623936643366303438663465633463649d0798013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5370656e64506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68333331333935376433353632383732399e0799013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f706f73616c426f6e6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68316562376433393963656162643131339f074170616c6c65745f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6862663133643665663735623335643232a0074370616c6c65745f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6832336164363666366335333961613534a107437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6834353930393437346634326265376666a207683c73705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a5472616e73616374696f6e56616c69646974794572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6836383336396466376466663862363033a3075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862373333623034663638653163356261a4075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839626635303362663530356331366663a507386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836383933323963386134626464323565a6074270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a69735f6d656d6265723a3a6832313662666233646161663764643735a7075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6830623362396335343937326433393065a80793013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a436f6e7461696e733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736f727465645f6d656d626572733a3a6831323437316133616632336232653132a907386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832646638343763656465343664316132aa075f3c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6862636239333630393937393239663438ab07603c70616c6c65745f74726561737572793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6865663636616330613531663137303339ac075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863373965353333373135366334356366ad072b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6866323862623335303662653238633238ae073a6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863346632313634303539373530343732af073c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862343832366138616264636265316332b007703c6672616d655f73797374656d3a3a5f5f47657442797465537472756374457865637574696f6e50686173653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864356134666562353264326333383932b107703c6672616d655f73797374656d3a3a5f5f4765744279746553747275637445787472696e73696373526f6f743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864356132666166316335386664353536b2076d3c6672616d655f73797374656d3a3a5f5f47657442797465537472756374426c6f636b5765696768743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835386362306361336366383236393732b307693c6672616d655f73797374656d3a3a5f5f476574427974655374727563744163636f756e743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838393662316136353130623666363366b407456672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6862363632356361323136626563316234b5079c013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178696d756d426c6f636b4c656e67746844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834316163363330353336633133323166b6079d013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45787472696e7369634261736557656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865623936623535666433393532613433b7079e013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b457865637574696f6e57656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861613461303136336363346236316364b80792013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a446257656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862643633393036646365356365363631b9079c013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178696d756d426c6f636b57656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839366135653131343837363235336239ba0798013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b48617368436f756e7444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839653239663331393565356665643630bb074770616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6838633561633264396237306633316636bc074970616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6833383437613836396238323161316466bd07753c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a5f5f47657442797465537472756374566f74696e673c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832623532633530376563613630366636be075270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6861666437376637326636643236653364bf079f013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6f64756c65496444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864303366343731303933646465623631c007a7013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4465736972656452756e6e657273557044656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838363937353030393234353230396434c107a5013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a446573697265644d656d6265727344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861313065623333346435363530626136c207a1013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67426f6e6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831333635323161343334636464383936c3075d3c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6839643538333035336466386238353834c4075270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a72656d6f76655f616e645f7265706c6163655f6d656d6265723a3a6837373236613764666130303932303662c5076a3c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6864643136303833633038616631306164c6073a73705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6c73747269703a3a6865303938303865373264363961383166c7073773705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6164643a3a6836313938666538396261336439643232c8073773705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6d756c3a3a6836656636386261383236333835353437c9074473705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6469763a3a7b7b636c6f737572657d7d3a3a6838656632386563323332633632623738ca074b3c73705f61726974686d657469633a3a62696775696e743a3a42696755696e7420617320636f72653a3a636d703a3a4f72643e3a3a636d703a3a6838366464333362353533313134643861cb07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6836396438353737646461396136626366cc07513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6832636666306639346236643062326438cd07413c73705f696e686572656e74733a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832366664636266323964343063663063ce07323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6836316638326139656531373939636534cf074273705f696f3a3a6c6f6767696e673a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6c6f673a3a6863393164363339633735306335393734d007573c73705f72756e74696d653a3a72756e74696d655f737472696e673a3a52756e74696d65537472696e6720617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861656364303133623039373237643063d10756747269655f64623a3a6e6962626c653a3a6e6962626c657665633a3a3c696d706c20747269655f64623a3a6e6962626c653a3a4e6962626c655665633e3a3a707573683a3a6866613934323765313666663232313363d20735736d616c6c7665633a3a536d616c6c5665633c413e3a3a7472795f726573657276653a3a6830363538653235346134363363343162d30739747269655f64623a3a6e6962626c653a3a6e6962626c655f6f70733a3a73686966745f6b65793a3a6831633562656466306462663335386131d40738636f6d70696c65725f6275696c74696e733a3a696e743a3a6d756c3a3a5f5f6d756c7469333a3a6839373632626331636361303166383364d507085f5f6d756c746933d607095f5f756d6f64746933d7072b636f6d70696c65725f6275696c74696e733a3a61626f72743a3a6837373662356362633663393964313163d807463c69363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a66726f6d5f756e7369676e65643a3a6862323335333636616636376639373338d907453c75363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a61626f7274696e675f6469763a3a6835333932613666333636333665633930da07453c75363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a61626f7274696e675f72656d3a3a6863616561316238643435356136333439db07453c69363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a7772617070696e675f6164643a3a6835643830383865393331303734336639dc07453c69363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a7772617070696e675f6d756c3a3a6861636634663139336566653333356566dd07423c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a4c61726765496e743e3a3a6c6f773a3a6863353939613333653463386535616133de07433c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a4c61726765496e743e3a3a686967683a3a6866636563313538666435333636616162df07493c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a4c61726765496e743e3a3a66726f6d5f70617274733a3a6864613532623436666163373466343837e007095f5f75646976746933e1073a636f6d70696c65725f6275696c74696e733a3a696e743a3a756469763a3a5f5f756469767469333a3a6831653839613935666364643932303133e2073d636f6d70696c65725f6275696c74696e733a3a696e743a3a756469763a3a5f5f756469766d6f647469343a3a6863326234343164343030373334316166e3073a636f6d70696c65725f6275696c74696e733a3a696e743a3a756469763a3a5f5f756d6f647469333a3a6865396336646230626637383638626331e407066d656d637079e507076d656d6d6f7665e607066d656d736574e7070462636d70e8073b636f6d70696c65725f6275696c74696e733a3a696e743a3a73686966743a3a5f5f6173686c7469333a3a6838656231636163626365343565313733e9073b636f6d70696c65725f6275696c74696e733a3a696e743a3a73686966743a3a5f5f6c7368727469333a3a6861613765666137333665663233346637ea07095f5f6173686c746933eb07095f5f6c73687274693300550970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105727573746325312e34352e302d6e696768746c79202832343534613638636620323032302d30352d303429", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51866e06a692cbd47f2449d23683ea3ce75d020000": "0x6499eec6c70a3e1211a1991248716f999cad2b5911fd652e5700b5382d1d3e2b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d08d33a04630a1200eb6436c93ef19b42b070000": "0x4e8b242422577c9f7a6ed78ebb9408e38e03d7c9096a338ef4081241c29d890700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700846460e32cf55cb7917297457d5f7ef697caf3": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928974f484196d48d68936c07bcc9509d3894fcf7eba": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897da1f36b13c74e5f988f806da14650b790a54b4c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973bbfb20c83b79f8cfe3c3f7296f0390900760745": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5123d9e15b9215b7adaecbda345aff4bb07f060000": "0x70d68c29241a3ef5841c11afdbb956a75e971fef57ce8b82248f027644bf296600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511e88ae973c0c9b9aed1e4e0c65062c23da070000": "0x7631a588d157e5f7eaccb276b39ec6e0fe033574d07139c1354763e122a4d06500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700860b441b1ae0c0641409e5863e1a5f3a28a651": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcc0b999bcedaeacee67b1e36d207f68bd55f1e128cdc90b1a970b1656efc6531": "0xa6a2b356718faf8cce70e78f06712f1ce5917d04", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b0db810871a474bd38da3a58837e35b4df847f": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397734ed6fd608eec64c9fc1d82af4fa6165820bca0": "0x00f0cc775d8600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f8fce84ceddb0e33e9b310adcc5625d8f7b8b77d": "0x008826bcfcd800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ae6869a774b00ba29794c8d4611295bb0d9c2bf2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000d6dbcc9191c9bdaf3904cbc0bd1135f5ccfcb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894f65d1913b854830681e7d0ee71c9756e0fe9f32": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5463e2740bf82a52ebc0b310c575854d592940c": "0x0058823c772100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3eed7d3fb7e8161ca57a6ed51a5175fe0537c71d89202ae75a286d9e78c26d1a": "0x000b6274e5e9464df801fcfd8a9fed607086fbb8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001264aae739aad7299ae9e4154d598c0419f226": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002696d567f76c4b7a60cb00b1d95b0993fdcf95": "0x00a8b5d34bc800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000e0eff1c1ea2d6c76862b36009e1e1017acb88": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397401a887450b7096d8ec6651e15909d0a34e1898e": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc6419b1a4cfb8b590a3eb48bcd5bdc8cdfd8f595ac6e1bac1899e82a1c548200": "0xe5db04802c56a6de7532a9aac9cf39c7a3bc7b71", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b66e4cd327c761fcbcac782909bde1518bcf55cd": "0x0010b8a666b600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e17de34ca530df364f3b818e29a8ec82a3da8e": "0x00c4c3f061ca00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890c69d0cdaf9abd8b01a100387d4c5ccba3b467f4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289625181f151d0300b8a8ed7a5bf2779f939ecad4d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de63503ec5788a8aa4911a43ee47190ae94f2ab44ad62096bffc56a422b38b26e": "0xdb3a83ce2d027400f34819317f357e9e967007c4", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f4899aa039a663975aaf3c069e8aa74152090000": "0x92a195bb2aca1f87595bebe3cfcc5792dfb26a4327b897e13be11c55349f6c4200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897c65ef40b6a9a126951a17eb84fef0ff99d54de2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b82ec69d0521ebd32f7d445188e5b6593ee49046": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c391666d5b864610559e59c046357585192a25": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc94540e69a5c2d5a2e8432e99d9a99d66265343": "0x00c88f18385c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007ca5c1afdce9618c0bb7d86c2e1699fe935581": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5159443b8826f5eb67489423eb1d26ce6962060000": "0x12810d0b133504b5b0f6174b2ef048eb0cfe1b5e45fc7b4e422eed4b2bc1846300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ace3d849dcc2c1b7758b05cea344a7a108fce03": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ae20bb9616cc25af5dfe06997d4e5b8437a7421": "0x0066a69b2a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700812ef6564c068b4612e2c1f289358a115b2ddc": "0x00463efd4e7f0a000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e228a4c62c1abced2b55ca9af8b08b1cf0ae4988": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dca5bc1915da74aba3aadd7ce7b809045d5eb5b73559259755fdcd85a40a5dc6e": "0xdacc0fd259ce0de2829b38a0765970e7ab65346c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009bd3c56ae851e91ac23e8a736a7698de525f1d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fd593bd99ed831bb189c73ad7290501597199ac": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fa204a1b8d4d8da5577c1eacac9b7e5f3e896c70": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928981df87a117417b554a2ade4f7a425fcc4b2d919a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b3900179e0d9e20712ed41f8bb9ff8cb1e3fc88": "0x00a81c90c74c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431c5142225c7e26732a7ea83d3b25c826d8637556": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896afe9576ad00a571d9c04402006414ae45a8a490": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bc5666fb8f709373953716884e8e3e46537957d9": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513ef9590ba923a00623d3df39d3d075087a000000": "0x2eba9a39dbfdd5f3cba964355d45e27319f0271023c0353d97dc6df2401b0e3d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d946f4dec39d47a43ff25d186e00b6f0f5010000": "0xb274417440be5bc8a904a2ecb75d78bd678850e2a01a7b260230848f4231534e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3d8392d560d174203e7c080f13421c5aacf1314": "0x00feb8bf501000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5169e862c3d633b3d32774490b67ed13a03c040000": "0x083cc8444e66f2751a2d725275690c48a2ecef4f5bc519738cec602aa5dfe45100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d364c29bfbc9f06a42b5cf37ffd831e91c843cc25d8b90071546810ecf279e458": "0x24dc293f38625991044c976a3c99c358563f82d1", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e499dde041fdfd3cf0251a08b7ba8582088870": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928956be9656add1b07ddf587a25ca2ee79b5dded4e2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dbda5deda828ffa3c15dc99cad296c5671181fd3": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d2137339627c6cb8de09eeceea4b8160c116a30f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bc3643d1d263c04558f871fe91f8f51acf080000": "0xb65d26557de4647d0b74c1c74f33ee210cb1bab3d38754bb09a664f6d1db760a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d3f4ffe07d9163018c1133d8c260b3d4e4010000": "0xaec55c9f5ae328c609a1fb6a914ea6079f25f33d5ea261fe272460b0f0973d7a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928932b2c49c595f816c6ff3852f983d77249dc9463d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd2cd0bac7ae51daeb1c11493b6dc337fa471e9a1656f8e86b066c6fb22af2822": "0x960cbcac0d20353c14c5a4392af3b80b3f962eef", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397089913f600e20bcca596e00940631f783fcc3fe1": "0x004ed7a1c0bf03000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518d42f3b628436e4e71a27dca47fded37cf040000": "0xb640c8c456f0757ff52f051ffb503c6611e8d7c24c520d9be406c9a73587894500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890082242f0e0c5831adcfdcc04052b72dbeffbad0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a224725ea45e342d5f769ad16c4f7f19df7b1c39": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ab2aaa53121d617f02e48c6e8ac908c4467a5dd": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512ad219d400583e19f68349efc91d9d9426050000": "0x24392caae002c7705b8a8ae61f55a5bae270ddf4b2a61147e43596f62e6dc15c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9e3a57ce212b3db9c683245532d085de60e18bf3d249275c9e7a827939568d1d": "0x6d6fd4653efa8efde0a7bd582adb2d0c8101c930", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fbb059d3b1b26f431937225a41197f03b3070000": "0x44dc7e01917e80374fd8bab942b77bbb6dc857b578b681ce199cc524fd8caf1900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971feed555363e3ec72086c6f347b1b8f67d869333": "0x00ae63c303fe05000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513bd86fd6cc0e794dd225164120277b74a4050000": "0x647a9b6cc579aafd3b0b1a04ae88f2dc5724b89a8fc45042679e87665e17720000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282438919f90098e7976078c2ca828b6af4fdc3ab9052": "0x0070f7e810fb02000000000000000000d4c5d20400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c8495a15d9120bec1b5148745f13667dd7104a82": "0x00ea32381b0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890086c68ec3a352527ee68308deb658fa50da846c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b89b8904b5dc812d1211c1916a09656a35040000": "0xf8553b8def3e39297b80cff66ed8653d62fc8dd3ff4c73144242d4a4c69f0b5c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928934ad8c38970ee9c497009e85f48fcd856322aab9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c520b8c3e99de440a600168725914ebacc16b548": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fe2d3714dc0abc2fed9f148be5ed1f224793f01d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970002945f1fc37863f255e0803b75ff1f5276e23a": "0x0072a9f3d3810e000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896d8188d47b24e6d8061509b7915cc40d31cf4b8c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516c3fa6efb1678f509d5f1d5ca5702655a6040000": "0x0a70464ab2804d852f76709174e8f4c30b46e7c58dd5ad8d189865185873521a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974214a1879b2678aa9ca0abcdc8effd02e40f4419": "0x00c8c736f51b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d9bd91673fffca8936f266f14ebbcf940f684658": "0x0014cfc86b6c08000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d7b88b6d9199cb9cfd50020218517f1b6cd0ec50": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824330caa2e774035687e738e60ed754c1787b206a81": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a75f3a76006ec39432a2bdecc1034b3008090000": "0x90c86ffd4c51b7cb742cc247b992c880bd23d00972912da343d1dee59f118e2700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cbbc5d06be48b9b1d90a8e787b4d42bc4a3b74a8": "0x0098c5448d1600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a35fdcc674e005040637bed34a1278e06f040000": "0x3cba3cb96173c2dfff3f2bb0cf5e3c70784cffadbf02b1b2be4fcdd1f78e437400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799bc4449c9a1e3435912f2c19e75afb1defcbd94": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e7b9a7b203678bd95a2c7c44630e7d56efa2d4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009e51b0d7a06b3a8a22ddc326e1981d417a8b4a": "0x00ceaa99f6be0f000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898f3841e5e0672e7bcd9a2a3a25e24ea7eb0d6c74": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ec037e3865c948398bce3cac6e0a3af1a87969b5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b1e522a1fbfe27af28b0f198775fd9521588000c": "0x001a3581565501000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6b2e23616f4c246e2e0dfaa0485ac98be69725d": "0x007c9f9ebf2b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dca56407a6476d9375e9dd68a55e38feeb2cff715286f9c8597e2272453e8af60": "0x2658a833b04556526cbd6b2caab0a9fada7d8977", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339770bc832c319132b534d1e32eb24a5a58a29f2624": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d1ae1c475ef49e628bfa5e4e09e52fae00d6b66b": "0x006e35f8103500000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512ef3cc2ca8953fc709ddf23b3949199de6070000": "0xe26f1171b9708d791cfb6f144d994a52d30fa3ffeccda0dedebe6b17b054c07100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e7848bedb58a722316a55a845fea16b34cea5e5b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896407c0c25a5ac315d64b8eea2f315983f4096f7b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dccca577630b892c34f36d9681dde7ba25bed23356d467e1415913b7e2515755d": "0xbefc4249d323465b36830ee666c6df935904da3d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bc2c9667bbaa1b51c94f8a6d157a099abbddda": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898beb69c07a54a0feff772c42eed03d8036bcd446": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d4ff781e1de100c601a55c007e2cd85581841dca": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d984e16482c99cfad1436111e321a86d87d0fac203bf64538f888e45d793b5413": "0xcabc87c953dad294fc0ed22c563bac10fa8e3ab5", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc80d34e8174bf6910e23f6dc3b132a0cff6fbcaeaefa2bf588db3c8e11e3f653": "0x00d102007852fb6304637ad44457b9bf42be382b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793f4c3085d088c79aa83a9e60ebaa245e8c3425b": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bf36912f45c463b51d4b90aceea2727d18e0e2ed": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f8b4b80a2830d11d4843b980f06635530e993a18": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6a276c8c59606dbc8515f3bbde2bbf30956ae793689cf5c003d7e595d1ecee64": "0xefabdb22a54dbdc370b31156a16b7a362199affb", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4639d2b10d88d41a4fdf2ce50a922e9a99477aa5500316347f2036dda7cc805b": "0xa974c739d6a0f8bbf598f8da986f6667b347eb78", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51524c1827542b67dce751d8ec1ec83f4d10020000": "0x0a0e65d2793d7b4fd5b46d91a149daed37cbe9dd522a30eec15c3f3e8861a25b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1a73e362728d8de8f7e7961a7a92486d9897c1c": "0x00eef3db9dd901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700197a17c8ec9e02c852be37c127dcc004ea4eca": "0x00b44bd2d67400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973fd29fbaf2b2245931f154595c2b909bea226418": "0x00009573c24800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519c145c16dccf2718cfa8ea304dcd4fd3e9060000": "0x18403959947079acc738119e8cff8a944ac6e3a4956a1a378f1a268b01baf47600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970062bcd4cbb3f4501caa19a2abae06c7dad957e7": "0x00be18543bbc00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f1dbf210d8bd9ba610071d284620c157cdfdf40": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd2f0789cefd1e9c0432e8bfd47c4f1ef06b0a50e1e1884ccd7e1bf263c53af33": "0x4877170e1a23388f4121c72d6b8cee7696ab92d4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970a35612a6a1a9dd3b942ed5113aeb56dcdc4b615": "0x00107cb8e7c300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d16fcf8dd3680ec588538e1b3f27a827da4f3b725ba71e74ef68a636b6f5cc372": "0x00b6a48781fe2ed596deaff18ff09363ad627245", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890073ab4feb184e95b514c03103fa4d0409df140a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977bd77a44bafa948bc94d8fb6dc2d0b9e9583f215": "0x00c68d756eb300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a7455f18d8399830baad97632cda0a9cc2008f66": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512448908877fec51821804c2ab3f9ea29c6050000": "0x12ae1449f1318e75220747ede8feee0561f500f1ca2400c204ffad735c53ec5400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c213678db23cd757e5b476b95358f5b249070000": "0x709326ed34f4e04f9cc1808d1bf6f368c24448f9327c1926ec673fd5093e2c7000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972dbdb05d09c9e0f10446881b9be2e107f91f7e41": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289792b11a085ce9034cf2f6f7e31c53d85e4da2240": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfe578ba506f1c6f5d82d2cc86cef3e6b7447b24c2b9e82891f7f454a55dcc216": "0x006e724fce558be730b5ebf7f1d4da69b8d72daf", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b91355280b218cadf3772a949f0478880594d0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fb1c60db3703abaf29a2d3a01f46c109275e0d": "0x00744903af1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a19ba54235400e8ac4e77957eded1345dbb54277": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a752faa9889de57975049d585fa87377c7bf0894": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972aabaf50bdb0b288e642f0753758ec38ee556567": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e9ad7f04d507c0cad58e5abfd5a55dab4d3b19a": "0x00da99da740a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1472ed23d9d8b62b09fa74698626869e65808583bcc382d8239b7da80024843d": "0x7025fe5275828b45b97d3b950d65666dcdb9fc95", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d72322cff7ccfe90301cecc6957a68c3024c93c6b498f2b3cafa29cb75b85d00c": "0x2a7cb534202768d7daa624051d64ed942ed546bf", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd60888e982105f5cf40568c5ef03aa875becf1e4dd57c42c2623943feb128c26": "0x49e961c06237fdc4bb51c48813a8480e75701478", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894c522a2fe6dd800459133be7817b955fae0beb57": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970026c2822209f9a0f8427fcf5d8f75dc0e471058": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899405ffe8c225312b403cb49a313e7a0da78c1387": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289699fcd9fc201726b30d6f6dd8b3307334f1b89be": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339711814f00f1838263ab8b3acbeb9b90e90bb53e42": "0x00d8adf2724902000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a863cb15ac188d87a440836037e25f645a020000": "0x3c5efe835b5f538e43d755f3b1847af1a33ecb796c24445fec6abad99fb2d04c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899e005e96b230631a08c53a58cbde5e1e13943647": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d624f523610e459d18d7dca623df5000f61e7ff083aabf4358595230f89c5e332": "0x0dc2547858e1caf83aaf4d61db51d3696b2a593a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e25fbe47354d8ed5377773251b41e1caa13f1363": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289223124942a06b92fd5267174d18dee47bebd942d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a712cacb7ee5cc9b956b718f9416ed0993060000": "0x147703aab4af61ad1df86d783df7e3c6d67e5974445e770e9f751733b07f584900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c59be10c6f6d60b03f94c87f4f78ae8afd040000": "0xc62a133f277af4f8d937c5720bc59904ab1d48e59820789cae9e326a0c45e15800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b566eb055743eb2daf5221d7a1da355b1da5433a": "0x002a6809f9ce00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003e042a1c0d20f39cbb5664edb923aaf00b8e30": "0x002a96626fe000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cb3e3c8d8aa4e70f250473414b308e25d9080000": "0x545c47306c568ac5e74d5194126702c63a91639425146deb45671dd6144ef86c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512c917e78db9edd508a9dd83894c993455e080000": "0x52b2685e43a4ff9ae6ff3476f2bdb84356ff427ab671bbcca1de6e486881e15400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006860119dc98195115d8bfd4011eea31214f028": "0x0022afc58d0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db01694db6ea17d4ecf62bf8919c2ed7bf166b237b9dce969168be4c6c600047d": "0xa74d379117fae37e0f17f3ad6634baa201af20ee", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b1a22d149fbe630c3f18a01bd593618e1e2fdd": "0x00aa7f5f551c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339745bca14081244a055409294312fb1731ab3750ac": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339760e04fa14b8faf0d3d7b1844e8535eb156814b3f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973cc9063e7ac5fa8345e1f59bc32a470ccd30ca6d": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d660e0a01a5850b0e4c1c447a8d4f41b9cae63d0": "0x000420885c3341000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d60babb8bab89537c2b2c8d0dfce9ecf940e40": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785ac9e682995ebebde8ff107fbbbfe7c40992e4a": "0x0040763a6b0bde000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e4992bb3d86f6734af7fd1528a658f8484936b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289572613e81421b11b7cf99fb41c3bdcb915a50d31": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006c8616a98ff7b6fd6302ffe44a18348df5b3fc": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517b51f2daf843aa70d89f9688b5832b90d7040000": "0xb8e06dc2e6bb6bd269319ace4cf8f663338f8f285a0564d6a139063c985d231000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51eb210bec36b683e16f8df06253c9efdebb040000": "0xea9c4b014031963e4e1961db0b632181056d80692b9f9f8302b0916394e1402700000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9ef9cc5e5a5d22955f21dfc7b830749badc9974cdb3cebfac4d31333c30865ff66c35c1bf898df5c5dd2924d3280e7201": "0x000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397efaa2f28aed1cf6923c64137ddcedc4a94181fa5": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5138cee411bf913f6b5812146036e22887da060000": "0x9051936ee4376c9062485bf5d47e3755d24f3baf00d120b4162abe72296f584a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d65d5df37328bd4ee8ac0c5e487b0f3675e8ae8272c82d3cbcd699af3d68f61c8": "0x58445ba5cb35d9d4513df77f8ef3ccc8d608045d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970063a5947b2cb42b51fe5e6fa0b75e6105b3a0f2": "0x00da3a60ac3800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289228679ce88ce13bb8483bbefc4d107a1aed02d2b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fe781dc59ce5e521c2ba3415cc78c9145a080000": "0x06ab119355c4230391d5a2983adcf81d91fa5c160c77993512437b35bfa67d4100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928922f6a08b13d46bfac92f45a624dafd3ab4ca5761": "0x00", + "0x1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d": "0x18fa3437b10f6e7af8f31362df3a179b991a8c56313d1bcd6307a4d0c734c1ae310100000000000000d2419bc8835493ac89eb09d5985281f5dff4bc6c7a7ea988fd23af05f301580a0100000000000000ccb6bef60defc30724545d57440394ed1c71ea7ee6d880ed0e79871a05b5e40601000000000000005e67b64cf07d4d258a47df63835121423551712844f5b67de68e36bb9a21e12701000000000000006236877b05370265640c133fec07e64d7ca823db1dc56f2d3584b3d7c0f1615801000000000000006c52d02d95c30aa567fda284acf25025ca7470f0b0c516ddf94475a1807c4d250100000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928975993bdf8a6c4c657f007fe09ec4fb4fcdeb3ba7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fac201d9eb3ac69d0f333067bb0df400ebcbea7c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c95904990fa58ba027b185d876d88d4a079950": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519242af27c7c48756ce7374977002cfc46f050000": "0xf02898c0c4db9a86d5b6c4192c26147cc0d4845d3c93f723a4082701a68c116b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bed113f4cdbf6e0fd3d402f84fe00cdb9ed79c3a": "0x0082357a0a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979704593a5983b6b3e498b644802337974a2d0c3c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af50942a6552333a69f736a00aaf7d5f57e764e1": "0x0066506bfb6400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b0c6e7d0d2756e3c703cb749a78699880892744c": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a403e651ec2cd3b6b385dc639f1a90ea01017f7": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896adab48e2bc7819044ed2a9e4041f918db545aea": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ae09e49b8529bf5e7cdaa468f652c3f09fe62289": "0x00446b11410300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895490d6fb1ddfd925bef575445c4ccf0f20526b83": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bab1d735d0df1c56300c93a4dd1fc16bd9070000": "0xb8bf671a6d683d47aadddebc4586550750407f68178f77a6aedda63fd0cec13100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000f6cdbe9dfc875008e23822266cef6ff78124d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c46fbc59c8742b17c3f67fb39338046c1b3be969": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b7ef6733ceb972d95d74368fe24b511512ae857f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d3388e1ed707443442afa9bb133d9dffacd9b467": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de218d439c40293656ad41f042840106973655483a4e3481535b798cebfc46d52": "0x007b2f1e74f2d7a146dc352b987b44bb49d0d6ab", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700eb3893593421571007c99eecf18314b37d2319": "0x00d8c00f4d0401000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769294b14b71f036b1f394e45b46a370bfa860300": "0x009e4e93b58d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928965e9bd9c64b29a79b286f4b2f8a3cb449c13a91d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894bd120e887cc82285aff8408dc208ed32b132bb3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928919d1e23c329025f05bc9249d021fc59abb483254": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e56da5dcaeafaccb73e526f3afac2f48cd0136ae": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de82b4045016786e298d7f72e2ae948a7d9981df0fe2d3180648fbb4a52b85849": "0xcef45cadd1e590c243490ad0c0fb9bd0a47d07c3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed434693c34b81c2f7979f2f2724a63a0709fbc1": "0x00406cde340405000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f1ad9cf75089d42b8b56407fa8cd4914cf1453": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824369ff7706b367405d95890cba4d905a9f040cd467": "0x00408ab5c74301000000000000000000a4ee0b0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973872d74c3dbddbb0757cdc78070afc7a8266b595": "0x00a87036668100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f74310dfdbde986ba9bde96a472efff97e2234a7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890a35612a6a1a9dd3b942ed5113aeb56dcdc4b615": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824368a85a879380543b48c40d0620e0681300a88553": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893872d74c3dbddbb0757cdc78070afc7a8266b595": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893dbc5ff979d0f30d65c33f684eb4b32cb4cfd3cb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed8bda7a810d594f145079dfb46849d8ae35c716": "0x0016c3676b6700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003ca16bd227028787da3cf107e86b4c78fcb8c3": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da8b44f24437db42008b305e9047895ece47eb7cce3cdeb97bdd2ddf0b4943d5b": "0x60e04fa14b8faf0d3d7b1844e8535eb156814b3f", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df8553b8def3e39297b80cff66ed8653d62fc8dd3ff4c73144242d4a4c69f0b5c": "0xe4d35cb41da50f320fb28123684440d99e450d24", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511dfc028386948d3e6f376cdd5269882419050000": "0xaa98586310c2340a471a30255b03bb4736205056373576e53c5062c1a80f642600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd0a09fefba656f157e715f18083ca46628c3646143daaa0f3f9ac171e306f350": "0x006ef813cd8eab68641cd6fb8d5f3b8126abb5ba", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339795fb1fbd1f13ca58ef95a91fc8171d6f0c53439e": "0x0040f09bbce108000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d501bb225e3c5794bc5c96942847648613c63625ff3593b3901e903ba83c7d957": "0xec12141e117791b66693d6ab5ca3e270f531f76c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a95e38a8dc50337aed200378a46bfd23d33232f5": "0x00c0e1d0612100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bd27d1c8cbd251d089c352d0bd4fbe5722040000": "0xbe2daf84705de34c1930370f53566524b08145b4d192d6cdd5a35cc71930e24000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890051e28f46719ed3e65d93c5c172bfe0ed982b84": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006706b3aced8f9c82f45055521b875be51da06f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b8441ea3b1d64620b1b83a902a7b711c2066447c": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a3cfef97dad26bf0e3f7152edb74b84a278c123b": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002c39a54adc4033eb6cd69c7f67459c0bf90ad9": "0x00de52b6088800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974523dbf40b244fec4c04fb37682ba584aba0711f": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5154c175457b3824026998dd4849feb1c870070000": "0x68410aa34e30d94c8f4b266e5d9db3d14f44242327d9266877454ec70ae0cc4700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f961ef1f20028e8340d5618d3bcb077718e58825": "0x001e10ef470400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397141af52b68e8e1cfe3318d7b91c698b6c0e2d9f5": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d1906f171b3ae82d0c500555143c28d239ca74": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431c00e0743d704094b1d198076a33a33487e2d38c": "0x00406352bfc6010000000000000000001ddcdf0200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5187b3eb6e60044a15c893c2b1b7842ded42090000": "0x1ebd2c29909eb603331b960308a070b839ee78e80fe12ef05e4639a176ab743e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243ff34674c9401c39cf82d06d04f2037411d835db8": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea53c14c3481ba7416851fddf1c192362ac5b8123e4866ff2ead77cd6c2d772a": "0xdd6c0fcf38a991d9c95d2e379f4f234807bcbeba", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ad9acdc0fd7c7e32f899379a3c56ca18a50c41": "0x004a5eddc34200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51473a4f4f9feee536becaf84fd6f94f0792040000": "0xeaeac37aa13c38ed2518b7b4be3e4e7899c5b971091d93a4d33ae18231b1fc1e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5193e9cf20e2f3b9e59596e549631efeea93070000": "0x1eb5c6758a96f303461856a587c3b58bddd005b2b1de6b14b3fded4b5b01960e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b180153b71e80491d9746e90f472a0d8ec040000": "0x68659f683ec88be378fb7729f1e6ab48731265b4c1f915a17cf25624c1109a2900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d00fedab32153c74b69435ee6c8df8c097d47a12e6e513a05079f7cee24c35113": "0x08c58b2dcf43c4505526af8e5e067bc08d3d0175", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1afd8047b4dd08d1d8bc15ffe901a00390a71d7dc601650097828c3fbc6a2202": "0x00ae5328446d335ff5aefe66bbc5be2d827915a3", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d86b8c669e6eb75936e2bdeeaec46be25388fe9104540395aecd2d03a4335e959": "0x15510ab37ed950371ec9ddd5635fb5d1419ba3f9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970002f625594208e49a2a858a109794d50276bf82": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ecad80fa0ba008c28f47b446a99f7c401a24df80": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824309fbc09d7da0c050d4fd80db0649b30378cc4839": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900846460e32cf55cb7917297457d5f7ef697caf3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c1b9adf120f8247211132d86a8b3c9d04dbec26": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cf2e734042a355d05ffb2e3915b16811f45a695e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa65fa461471c7ad4b09bc9b74844df0faf71d0198782b0f26f704b185ac3634": "0xe31e4be4a7c65fbf14ff16ed654bd06b3a1c6750", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897f619e5784802a7c966c46b12cbd2510ceb084de": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289607f233defb94a83543cd250f2113eb5b5d68f7e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda1032f908449065d9512274e07fa2bc8311658a89e10ebb2b93d4d442c3ce29": "0xc47108828a0c47dabe79cb9fc8f87fa9b4dd3447", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890042f115150fc2eb576fc9a626075ce1c785adaa": "0x00", + "0xc2261276cc9d1f8598ea4b6a74b15c2f308ce9615de0775a82f8a94dc3d285a1": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516942fa0a3d7171b7ee7c816e72e6ff57fc070000": "0x901873793cdc00c038c78a1144c8c548482bb2daef46d5cc56e76ba142ecf63200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895fe82ccf847c7f2a0281fac8fd9bcfc7ef245f9a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c69f44ccd469078bb71e7a704c162029e45c0c9d": "0x008032b03281ca000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cfe2d550e5f331a0626b08e9dea48b37c7d33231": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ed1e8aa9e5dd16435e3fa47f87501b777d020000": "0xa2062f4049a118f70b5f523c45f2d637d73a43f73a80949c0c35fc985604393200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928937977eaf6917d93704a3283bfe16d87aa5eb0717": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928915a5e1c36ac791c29453dfb2b7eae643a1b17e73": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b5bfd05d823b7c9f00a9d66319c889d50678f457": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928923b7bf89200663f958f11c7d495f9dfa793b8ef2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397291cb06901bae540721973fb6a98a2f6170b21a0": "0x0020c9e7070400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397470f765ac9ca7fd2d19b7b68b39f3a3da9f648c6": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895f9e3e6c76760ce49fbd87e857fc18ebb7527584": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519e33584c644370201ab6d4d2c7157ce4eb030000": "0x2c4fa0b90e34cd788d2be0354965cfb4bc5207dca0e825b468e7c73a2c223c3000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5a7aab883d2cb1309e3c942074c7a2fc1455152d9adcc2d590b5457eea146e5f": "0xba4795e1db269aa9156234e30888d75ff3aaddfd", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893bca1e6cc37f9b72191cd98b6fbdce4e092f0d3d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a0be7b175484ca4b6ed2490439ceaebd1c83c400": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd4b82f0101e2c306b1cf78e966da56058ad177d1c649111f3dd2ebe90afe3c75": "0xe18eb8520947679c4780bae0abb06e6a219b8df7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900eacd0f6481a7df06b3af2c13b2a185316803eb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ded57d5f73180b6e247ca3f4fce025fb1a82459d86527bbaaef28c2f4a4eeae69": "0x61f4f7d2a593d1040406d2df519699b96f455a50", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a9f94b0f5bed56d03c2a3741eef545edb7c27ddc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ba3494fe956dfdb34a70964c62c613ec1c9d1750": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e666339d61a192d437f96ad1e40f197d547187c8": "0x00203d88792d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977e103f3df1e411be2cb88bd11e9c2e15c4e69394": "0x00a0ed86271400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4479a684448e202bae5f8fcc4f2a898757ab8ea3b891baa6132b37ca3cfee139": "0xf00a83c85b0a5fd088b7ef7cd5b4910ade729d03", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289185476974fb1f9346c90d0831778f958456bcd53": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970055e4b4e56e60aed3224764a6479e704e2cb236": "0x00dc2582a47c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730d6d9ce640c97def75838cde7f753bf7f161403": "0x00ba38eea7830c000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970016b34601309434ee42c643a76b78696e8363ae": "0x00ec670c037900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ff45a27708c55e909009e59f1d53aad9b940e273": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5142a8b76c69d8262a823448c648ec727322080000": "0x0ef2e01a9f54a4567f054356635348f69bb29e7e70592436f60b3dd4a3bd0b1a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df2bf630289bf17443c0eb89d5fdca0868eafa0a": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512f6ea8017692a0d625ae893193e301cc22000000": "0xfcc3adcc46a1d2dde1ccb5a05db9534b7c7fc30404ffc7a5c2e3de947909e94f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cdc5f944f190ab822712994782a65d7723582eff": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513ef7e9ef3e02b5e80ec599420e8c2c8264040000": "0x30599dba50b5f3ba0b36f856a761eb3c0aee61e830d4beb448ef94b6ad92be3900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dec3b9a4f7823e1300b670dc007d3408763760cb7c320453d33619773b01c412a": "0x41a7300cfe3e58c2a2c248b3f55228122961b132", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbccd3abe59dc17a36fae237852338d0fcc0f616a257aa8ee05a964b8b521ea74": "0xb74a9972cc5dbed5eb8714672680d8a1bdecbc3d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f9d96b3520fc91f21d75d65ed8531cfda0628a": "0x000467eeed0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d1329c5042de8e73a19012577ff26372d003d1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975449713c3b74111612c326efdc9a5e9567cbaa89": "0x00769f7b7f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a224725ea45e342d5f769ad16c4f7f19df7b1c39": "0x008053ee7ba80a000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51120c27912af0d6e3aec822e78236bf548b000000": "0x1a6d83de58105258076725b05d526d8af18d027c86f0b702ec1143946f4fa23a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a0957c6c74540218f392c01174ac3e6c911b57": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dc7dcc21d1c488fcf7775d7b081a882502ef47": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970074b0b90a98675309b9db4c27badd1b8ea42b0b": "0x00ce429ebb4103000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738edb955024a69942471180dbaa3416006379f2b": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928910b26700b0a2d3f5ef12fa250aba818ee3b43bf4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51065e7c5d8047290ced6812b637f7b93bc1040000": "0x324ec702cbef49677b575d5f1d84768fa445f2e273530172952030521917985f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891749ad951fb612b42dc105944da86c362a783487": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c5d3a4a84a2d404dc9828428180fd927dcdbc896": "0x00003426f56b1c000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895113c12e12427747e73b87b76bc524124acb69d2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3e78c61b1083bde0307908fcb6231736fc9d51e930469146b4ebb45c68167f4b": "0xd99b6e4871d4235bc2dbcf58c6c1cca46ea8ad1f", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282439a36821b843a170995a145f3503400866bd69fe4": "0x00001c0611c813000000000000000000ed88022000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892e05cd4a04815510ab2d10464db9c1356cec8bd1": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243eb514a98e40a66e5d4f634b9afae1ec41d58c659": "0x0000dc207497010000000000000000009554930200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d542e185fa0607eba80c93da9b7ff93435f0f5fec06a8876ca117c3557a3f516e": "0xb7a9b1c894620751312656b66c7dc2e333cfe677", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc07a393135ceff70346ef1d14953f5f348acbacfaee49076c903c17883f75d7e": "0x82d31226f14b0b79aaa950cfdd01ad248765ad20", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a6a46f3bceaa2b9799712e1d4413ce08cb8a801": "0x00989568830900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5140737986ba076ef494d447bf74cfe13e17090000": "0x4a51e088519499f09d4efa334b901675050a1d5ab6fc66a25eab4dc38a9b097e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890003903739a38fdc8226d75fe036caa51f37ba9f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977df289cbd544ba6bd153b783ee9024e46a1a7527": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f2f3d21866a3167be7b0af44dacb2e496c5b827e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae86355012408b1130842a93db57f27d3edab57e7187589b16d4186dc8eb5d2f": "0xed5b940de6f21fcc6d1168cb78590f9ab6cd2ba6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5cceedf3c21bb629353405e2e438cfab7c94c56": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d76acdf6617c513da01555e0f83863ca8d44226e977f8ee5a243565193cdde012": "0x0026ec71cb407474b48df42a58a80618c4e44e99", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e613d5ff2f7ed0d7ff4c00155b749984ec0ab732": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892c9fff9f2fd3bf895fdedae1c18c3951fa135331": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe7c59f5c785ddb869662aecdccf932b29e10771": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005734cba73fa9aa8aae2e4a11c1ddd631f3d064": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e793755ce4e93d29ae317ed885cfc65d45e98d9e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a378bab57ff303be5842361b3c0b5ff44e222a76": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f9998f8570b0afdf090d930b702e430edf66f8": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b1112458dd8d294c00264a5dfb897e5a85040000": "0x80c506c8a97b330e37357f791c6d498369d086fbbe9e78d67d7e07720d51ea6f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971d2fc4af6283590eee0d236dee41b1c0b257472e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f4d910b1ba48ef5349f3cbfb01908c1f42ed63a": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897cef137621ee58bd6c3a7036924dbc0288f81dc4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51682fa0e0e9a3cce302c81bad161a5a020a020000": "0x823ab8fb16d1f8dee7f90459777ec16efa1a35a6626e965a80f4135c4a6ef33500000000000000000000000000000000", + "0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289efddc6a78911e0d1964ed041a8d81de69cdc8ca4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900edd6cbe72d13a402da3478c6fbc8a0eb461fb8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899303b03dc3aa29a78c0495513920fa310f9e561d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c14f09369aa8e6a7490ce9c54be313e5daafc0c7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512f47ab0a0e2faac53383158350f742b5e5020000": "0x14bb873b383aa7bfc47eca28391ee5482af6bacc5be7ef49f6edfcd7b8be727f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ffb30c28424584c8971adee83f320580ca000000": "0xe4abcfe30c4b4f7ac36c37366241c6091d766a03d28f070deb646707bbbd056200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4a0ec663291c413542dd5919d73f95057ea06907f2937d711fd9f17591c0d25f": "0x9e0ee8a2c14d8c467a9b31129caeae40b021659f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001b2ca922cd635a78fc6e87d33b8e8726e057d8": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339739dc8b68208f3cf7de41f8129623dea433dade6d": "0x00001a93fa350e000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ebe4fd701cce5d001c481f5662d1e941371c49f2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000ee102d3ca744851a94c25c3eea1cfea5bc5a8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289020e6a798d9f7d8eef4696d0f9c555359900ea19": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339729c0e5b31ccbcc929e001a4828a62e09bd307688": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e2f4b428f4fcdc1a238a75b172a73c6fa788a1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d4b1e7287477ce8247daa310641ddef3b9311e": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a95e38a8dc50337aed200378a46bfd23d33232f5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515656b4cbab0151f442f9482cb78d3eae4e080000": "0x1a74b5f0acf6cc5cb0929de58f353dc08ae974bce555de6470a842e5c5a1218c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0ba2bcb31e7789cf711bdb657cc69526bb9a2f7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f465f7ce5a1e26c402177194653c12e7222f127": "0x00a4b18db87601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e31e4be4a7c65fbf14ff16ed654bd06b3a1c6750": "0x0040ee7affbf00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e6594a27734f52d8a01015d8a810c81902070000": "0x3e514819b14bd168c797646db45a4c143390eac318c97c11839ccf819ce24b7f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891c4ba011e13f2f735dee87c7801001ef5e7348d0": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae3fa55a10ce27c1f669636f4c9c9a6e3e665806743ae2ea04129f24e6f7a850": "0x91e943fd3640f82f0b3577e796a9cb31724b7bc0", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bd315db0cbeace9fdfa9b1fca41d0c0918f4827b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51da1dd44112db0e17d2f116694636b9729d010000": "0x2c4bba68b6aacea483b743d0431b1ff5c33cd7522e2c4e3b53c0928211e25b5900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d84c74f819ebdfa0b67b0807eedbd49cc649a38b769d42632458c6a13ea6c5416": "0xa6bddeffe26cd501deca6569ef33870f15aeb637", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e162461bb73493d7340a0fa23908f86005090000": "0xaeaea210589babb9eb1cb9a7787994ee4b65e98906cc9d9288386fa39184a75000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339724a9f3b7757a2f30e5171009f067bb906f9a8e67": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928911814f00f1838263ab8b3acbeb9b90e90bb53e42": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824355e9a88d4c79252e7340f1e7816098b755c942d0": "0x00e08a5e43ea03000000000000000000c4d5550600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd650c3670b5cd26153d23688b773c926ac3188fde5961ee0a6b3d4ebc7cd900f": "0xd5bd0f12144dde4c70b3a80bd8b0817cc1ae6593", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c8b04462d5806811b58295d06cd8510d82050000": "0x1e2b0e0122e7c8598b5e600b94d16d88da6f9b90a520ad2fa21bd3004bf2901a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339713597c1e37b3dbfb347255a2939b6d58f557e1ca": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a3b9f63335f09ab460319dc5b38b9f7029803b": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcce721bcf2f83777132dfe3a79be1bcb76db9b6e0deeebd3cc1adbf1b8a12864": "0xf18ccca441625179b40e774436ba038505fcef83", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397022070e52ad6f0425f72feb16636fffce243529c": "0x00c65a1111d361000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddc3ebef58d5bbd698bd02d914225a4736cf023bc21ebce7cd1a41c03a4324575": "0xbebd4c731ec56e072e94cb0617bb47783ef3741d", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f4925a195ddaa2f6923e6ded18b7b79fe2050000": "0xd0c1c48b97e9bf16e10f7449a111e40dda58ede742fbe3aa9a6dd5662a6bce3400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d1f0e7d6941ac51e65ffcfbe8f84db0ef919f55": "0x001242a3973e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed5b940de6f21fcc6d1168cb78590f9ab6cd2ba6": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289114ee4ee7e6c4bf88c112a1cd1590c82e71ab298": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005a1f98863767d7a9cb58dd848119874ebf099f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516014b085c45f4d08555c77bc422143a3be040000": "0x96d7699bc59f8b6fc9be2be5f6ef506b63c7e10b8d751a73513694b601aced4c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f843d23f9c75d5e2602c6de0574ad94e57e8132": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cfcfb4fa0e64528b2c5c8c42e7d46118ae142d92": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cb33463e1812ee584c557a160780b0331a50b3dc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b6a48781fe2ed596deaff18ff09363ad627245": "0x00301a45ba2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e6d63c094705f1eae1648ab88463fc0ea6050000": "0x60c05022f8868ca43dfac61219a3e3e51bd234b2e76a4e3f2c21793402447e5000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5172b49f438958c47739eed12feaf1c00068040000": "0x18ad345b8bea4ce83dfad12d60239dcd63d92a7d7ff2b8e529569c8fa5fe044200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce6e5f32bd27b3f64a693b593378b389c5103a83": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c95f72c8e52f3df1ebfe156e7ce75c2121c8d1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a8d70c0692ce44b04c5ce0a7e77bcc6a0490766": "0x00a031a95fe300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928957d6f80480c6c1c0c7269c7b5ff282d0e37154b2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de2a3a940afc8f2dda379e32bb95a977514d9bb7fdb4aa27eea3c9a7ee8e8802d": "0x00735384d4b8bc62916ff05a16679d41c9850fb1", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928956d8d3046128996b3356e248e2448c7de420d98b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339728bf51f47e903925c00a03264c7e7a0576785600": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5154758f82d5d1ad2f778cde5223c63e5b12030000": "0x60145312077b3fbd05398e5fd1f349e29b41e6e38029fbc9bae2f1f8a9ae8a2d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928928cd36b7b86b3d6a8d53f0332fc3563489aee858": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d92a195bb2aca1f87595bebe3cfcc5792dfb26a4327b897e13be11c55349f6c42": "0x9a36821b843a170995a145f3503400866bd69fe4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e6f13f5f9c2a098a1b0e02774f73b16f93ed892f": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b0db810871a474bd38da3a58837e35b4df847f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b94ac84a9f1d304a6aa6ee6dbcbfdb3ac81f82": "0x00624c25681301000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000e5a0a7326596d024936e96ec7b662e5de59e7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51677560270335b443c34aeb51a5c8355b9d040000": "0x34e8aa23b46d7b3fe5a4493e01eb4dcdb1bb4bc12ba4cc57e4d53a3c52d5380600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51109314b6e0951def279c176b0427f76bc5060000": "0x7697834d583c3c53aa62fc52856c9be86d55c0768f2bdc9c35295390a93f8e1a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517fef368878716783cde6c5965bdb11f463080000": "0x8e11401fdf86813483585117c55a6a912ab954917e64d3e70efeb25e18901c5e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243cd03d9b87fc7a4669076fb8675021f04e4e8f9da": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4a025dc1068a02a63ca49aed9ffadb1d249a1f5": "0x00e87648170000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c383c50f156431e8f7187e0c04f14b85ad4aff27": "0x005650f3083000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c062628943a930b805849b494719c7d23c77bd5": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977009eb50d01c3aa66f09ed1b9d675c6edbe392b8": "0x00a2ed9f605600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898ca3e84bdb1a6d3e68fd572699737d203ffc66ea": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cf1e7d7b8b56e594e0294c5aef7a81b957350e34": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970028dbe0396e7c888373dc2bf00ec85c292afd84": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003b3575e3870ff8d5dc6114539250b359194aa2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289319112568bec6af88d43c258f36d94319bf1ac23": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007598555819639ca06fb8b20e3ecffe1159cb99": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928985591bfabb18be044fa98d72f7093469c588483c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513dd248ee659776ad3caa0380bf925aa765060000": "0x107210db50634b820ed2323b16a861a2980dc828cd432458a37efcf0efc3390400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005c87548ba2fa697f7d3ee6d63722cb4f25c7c6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700365211e85575a3a4ade9c33c7207fcfe886bb7": "0x00b438b5fcb901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d24d8e5836c187481f76ab9c0a7ab01a912c31": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339770a5643374c28a958b5dcfbb68a36d3fc31e2fb6": "0x0028f637af7c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e8ff247832dc7f7d5163f2623869d3dd3c36b56b": "0x00a030937f8901000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899833f0f9247ee62faea47d6fcc838e262742b95f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896a1e09cd44050639a816fb6374da3baa1228ea4d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5169237cb12bd6cd67888988af9d20662127040000": "0xc65de6003709aa5a6b81354c00fb13e281ac05e852cb4194c69f78566e8ac82800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897738dd4955693f16822925a3cc9fde3f94e13e32": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dc120c0536de04a202721962e9be40432ba642": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9e6e426ce0daef13a18330489126c709e3c54dd535be6e3840513ee1441ddb63": "0x85e2f2767bcc9cb4814bd555413e2e17e1cf8459", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f0bf059f5658c248e0ac04ee4f1dc07bfd739ef0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900091bfd5d263eaf2c04134a4ddd0eea8c70468a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cf356a6efa93781c6cd23d8d8d270fa49c1e549c": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d136726fcaf415dc235995fafe215258aed5c421": "0x007ab0403b2c00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518579ad59200592ae351040c18ada9880ee040000": "0x724e0032275bac5598878e5dee08149d11c44700c9c4626d1f339ff1be715f3000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518fd760bbe17026e541defc264183463a2b030000": "0xfa74a5a45fd63ee5693a96ac0e371fe7559fd8e9895321bc7761e1cbcd73a32200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511c5b41e2c8170e10a44f4346524bcabe2c010000": "0x4cbd028b49652bb2a34aca9063cf88a06495ef9d5d33392598e0e57de504681100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5101f028f40f46aa78954efa1e14f0c6b3a6010000": "0x58e8986a603cab040fb5e976c61b23021a5f5e7a0206da27c08fbaec24fba75500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd4c1562a1e4d60a14486fa3b12d843501862d77075d222ea7ae7e61ac8cf6a11": "0x261c307a058f4a6970c2fd1c3d696fdb968b83a2", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddad463ee00bc9a0e288a87bf7f80ba96ae2bd082d49beeb7467c40eaf153f00d": "0xfdbdeaede3cef361db915f912bcb676475074f21", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700976b44190fbe9870317db584086f6f9d84d610": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ae3e8a291096b596d36cd4f6fcb3edcbaf50e673": "0x000cb2866c2100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900af0c8544bbbe405642a32b0aa5758fe489e37b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890056962a7b6b0ec4c917488d06892ce34075218e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897dfc554e9b71dc76d1836307af3f81c15eb9d0bf": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db3c66b5c51c955020fb220715dc0f73fa4514ca434efb9bd12e9cb1690049889": "0xfcf8700996507fefbcbe7258ff7f5af0abd5821d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a4ceceef89a949afa2ce10c73ed5f0d79dfb3c": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ba381e968d5a797f0d93e5f3705bc2a98d8734": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b4bfe7e67030cd1da33c01c06256038d4713a5": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899bb987d0bfab369b9eca904b842723670584a5fe": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51861a6c763807c7cc9f5c3626ccd6cea90a090000": "0x1ea9fa1c4639443f9cbf06f83e53f11d817b751cc333915cd9d15eb6dd917b1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3cfef97dad26bf0e3f7152edb74b84a278c123b": "0x00009573c24800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ba94085b8a6965a47f4b0c283cc08d76d6060000": "0xa0048e4648a919387cd0843a35a68bd6ea9a1418927eac08a6f7bc11e3f38a4600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431f8a9aa97618c77fad4be22fba26d4ea0507119c": "0x00600b6776ab010000000000000000004eb5b30200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d0036b211691a8f28a2f159a8db9d84fd3eee0": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e784d624d4e60da998bdd79169edb8beff89d27": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c509424fd0794e367683b213a91f3cd83d1180": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289734ed6fd608eec64c9fc1d82af4fa6165820bca0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895eeb604e66c8afebce169152326276d345bc320e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e8a7bad83211e09594da192ac539f37dc2060000": "0xbc309fd2bdd98d456fabda1bf024664ad14d59f052dcee610e47d8db622bf70100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e2409b5ef509e1e584584edc945545f42fcbb3f288f3355e9194206b4ce773f": "0x49fa2629dd5ba6ece667bf6eadf174d2c8195cf4", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df0dace05e939a7d03eb7edb13409ea19b7cb1f0d20469267322acc92c9cdc62b": "0x6846d14e5177c97220466fa343cb3ef0d1e29f07", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397450f4b99969a564bfe2388b52aa949a1c109b588": "0x0008711b0c0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51753c633268f8b3d0362961f5947220b321020000": "0xce23da48a54f65a3dcd3d16bb18a99d44a25cd096954fba3ae2ef973cf706e5800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d46a4232f9aa69c5313bb2909632365ffef0d59eaa0031dbeb68f903b164b0714": "0x0044b3d793d4cbf50f0973e2c8d62ca3bdcbb38d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289855f896fe935353955324fb1609165ec9372d473": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c572d95b14fcff25a83939d95bad68eaad030000": "0x30c76c1fbe70308d47eac55e1bfdbc77cdd577c1cfdba04ee225d5057bcf330700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970129b205bd7da590c22b986f2fcfcb3079ee3d69": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a145addb0a24f0c4697189a02eadb006be244d49": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f651fd29c612a4b39a1a19cc749fa099f82ec9": "0x00c0af01f46809000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339772d8a23c70ec138734d5cde0fd9e3edad5102320": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243b752d54f3436601d8ccb4fa02bf2289192e4ab59": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3a426ce80e46773962e068093597661b7733494a3dc2ecd9873ccb7958a7a153": "0xa738917e17968c22c3ae246a69df2f64fea012ac", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900497c0ea743f6a572459c14dff09468021c84de": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a4ba602a82bb59c3124f5ade6b77e93bb274b3e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0af9641145b68970bf6f3904732bd7740d57be1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ba739859643cd795fdf204bdcc4236fa6ce04ee": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d76729e17ad31469debcb60f3ce3622f79143e442e77b58d6e2195d9ea998680d": "0x6bd98f74f818c4fbfb760afc077c3c8059b11276", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339717822cd9476fdebd92e640bdf9fd63169750f9a5": "0x00e69d55840b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d34e8aa23b46d7b3fe5a4493e01eb4dcdb1bb4bc12ba4cc57e4d53a3c52d53806": "0x116812f3295d2754012b63805ca7f89226115950", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009fe4c8eda6664669ee264c1db5f831d4af2f5f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928938db95df5bffa0bd5e39c27866f7d53e04c2f87c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897abd31d835a1a6ae9d8912936e8b68f7fc89ee0a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db036f284468b4fb6b3d48f86280cb806fc36713edd255d195504d1f32607af26": "0x185a7fc4ace368d233e620b2a45935661292bdf2", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51915725d2421192e91f84c0ce1a78635bd3080000": "0x8829babf92550447e53be69e21369ef808fcb572a5629ce18dce2af6194e951a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282436812d2dbd83e65750a7db91ab8806972ce170be9": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004e0fc93058997aaba684c4b3e9b5549a736fcb": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002bb2aee0241ac3b7a6fb01a6fdb8c5c7cd61c8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51276a63d65b41ec79101ef73e780b7fa1c5080000": "0x8ef70a1d0d8e97d88585fce557a65af431dbf158d2682b5088134e1cbb089b7800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e64078aaf2bb01b7dca49d0257a43652f03813f7": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970045e6f8ae50c7b511c257acc200e3fbbf947d44": "0x00ba12184d7b02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282438d590735c51726c9e24a446143734dd5ed632031": "0x00c06e31d910010000000000000000001184b90100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519d4b9bb11828d6f69d2d1c1021f15aec80040000": "0x40bbe499b94672c1618d355759184eece4fddb4a142d3ee0b79d4de66b92e32100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51923607500b34c83931832797d401d1f4ad000000": "0xe88a80739ece6a8dfbc8a37158c0c1bc0dd0368c672a4ecf3516f0cbd6cf435000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e7b750b2a5a7110f77836074ddfbc7e095070000": "0x9a8ead39ce1b44f37d16e98496441be79018e910d5f58c0fa1518d8fd774955000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007050147f1b0875723fcb4ffce39451ed3fbb4d": "0x0068eb4646f709000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339715a5e1c36ac791c29453dfb2b7eae643a1b17e73": "0x00baad66232700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970584e184eb509fa6417371c8a171206658792da0": "0x00581c527c5c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894755d3d389180081398ce855382d5f03e6547acc": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d38a295559d8977464fd8cdd133f8805f2388e42a6e009219247048a27d9ac06b": "0x30f0056172b5a1432a49c44b0c5bdff96a7fb54a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ff83a6d7418c73bb7fc1cb245d8aca979295316c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a44db7ef03c1c87530fe2aaba58a0b6b01d3c3e1": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c1efc49285eb5deda2ac887d613242475ed15048": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890f2293358c8721bb10cf8fef9fc9704189581ccb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339746db544038c59b826dda8d3cc8b72de90c86e683": "0x00b0ff5367f305000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5e4e1bb00487836ed9891e040019c477ec5fd483ac46cda73b62e151f31f6103": "0x00a2e5004a31e7b931bef05499dc4f3dca1b616b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894d9354ef22423d1d544a01a2fd8b2ac03af0aa0e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ba9d129d178bb0d08689948da60b5517ac35b89b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a3b20eee7cd3801a6408ff4c6f73a75556da2a1d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de679bd5e3d1d3bf6e8a515cca2afc8e5bf5d25aeeda6851134357d1c69070b2b": "0xbc13a9ed082cc1556a92d05a143fcd2346ebe62c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970006bdc62b8bc4ffb50a0e99803b147843117239": "0x00d64e45001d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7a72895374cf1814aa3d5e82a21dcf181782df422e033027fa4ad65629385872": "0x2bba2ac16832d15f8f415f1cb351fe20977ca399", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c5faed48240954efe9b5f666d1b6df1de3fa2ae": "0x00821289f30200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1ea949d53645e094cc44db822ad4c0d779f9c9a3252c5bb85816696b75e04c07": "0x6236f26b6bf5e69bae11e794e9ef25d3895b3b1d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b4fcdf9e6c5fc7ab486cb70177e3676f1df239f4": "0x01", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970028b16bf35427a11760cc5f4db866dd8127be14": "0x0016e332d60200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282436afe9576ad00a571d9c04402006414ae45a8a490": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397925cc6e8424900f85c93957095893f806afab0a8": "0x002a886f964c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcf3808986a5bdfbf72211debc42cdd72af74aa1": "0x00b0ad01f46005000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891add1af6a3949b9613922f9dd9cc3c98d003d5fa": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397668ba98f1cf879d29ff9767dd89dd06c188bdcca": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893be58c29b09669c1b1edd3153b0872e3cbcd8492": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d5bd0f12144dde4c70b3a80bd8b0817cc1ae6593": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e527eaf454a93e9aaf096b404c8450e66cbb9ed": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ccabcd8ff377bae0838b7bd827a83676bce01aec": "0x0010df60427b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289539f0f7f1e8e7aa08d822213305eb6e40c09ee44": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339760f2a161f72ca11980c5b6ebb86a537e63fc2de8": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928937213da6063363ebdae7ba5a3b0dee7e139483f1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397925807e0ad65347794cffac5a8622d573c3cd80a": "0x009a32d2642900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a22438f8c8ba4f08a9a3c857b2687cc1a890ee30": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dccbfb039ee654031cc916533ef1ce64e6b1422f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ae125582205e28cc4786f5e729d9a09608d7b27": "0x00fac8d95c9903000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928955c1214cb709381cc47eb4edbd28d19c67939a7a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5147336a6a2853237545f8e293f51c697882080000": "0x17b7295b2d66adadef5746c793b746bd2443e1da913636625ba95c7ff853bf2200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893e2021221b0bb5e2d1ceda9f024ed9804b055708": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b55be9f54c6606717a0ae67942f3fb297df4e396": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339711bc2c7ea454e083cea1186239abc83733200e78": "0x0040db35ba1601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700320c624958997f6d8ec1d130a436e87a1f0b0e": "0x00bac1e9b31800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928967cdd37fa7b4c8dec31e218467ff93f2d1d44efe": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b53aba6899696c8f9638267c5c32fe003b86c871": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f8a55193512202fe419de12ff41207968ffdce": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e7f5b9a284b1008acec688a28fd7b7080202359c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da2c71c01fae573da0ddcf3a0f10c28e5400093c72eec182b1a141c4dfb4a8a02": "0x58a0056880f6490bf35430b081f49d2edf2b1915", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bef780ac34cf7b53b5624b863d1a84918e6defbc": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004e3b44cad5fb1b7f0e23aecb9564e183a51fc0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d36c27983d26ff572358bdfd21942a2b4cbb3391": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a9184c124058289cde2f114180733a9e5b29724": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282435d5ce50ecdb86b2e04589daed8e6cfcfc238d3d7": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973fa2c79b96c7e30d5fa1f24a81a84e10aa336ae0": "0x00fad415c00000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895dc41b5662cf58ebfe9cef62d58c2c11a9863428": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f780e239ce7dd4a7b7b1413d70e2c01fbe070000": "0x904187b85d65703dbba21e51c74e2d89b492c9b0d44f3ec3b1974824d3eec95c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5196262ec8dd0da5b6d99040f16d4a14f046090000": "0x84e6b806bcba1f9f0255ec9eacff9f4322805b842b6e02e00f469cd5494eca5f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007eb3537067c48639bce08b04e4fb52caf64e9c": "0x0054a6b6228506000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5100ae3b422d71b3c8a313e61997fb1e46f9060000": "0x5a03ae20d63f42ac899a002627267b2b98dcb922812431f7e983a9632d2aac3c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339726a21090f6187a35c5d0578c68e22c78e569b18f": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6a3c186d9e7a9a84043a4a6e62213c376e7dc913be683e2c77c6f61f9e67c045": "0x651547546b24fa036b9c1b1c2dc8b2ae9c07aed9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a3c5437ebea4546ac6e6cfc1d8a76f30a6539f": "0x00defe0f6a5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8ac74f5da1ae7e61f7c7c511e2b888589b801c2": "0x002e275035cd25000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c68b2706d13f729df4eb2ab8edf4f2d59e037803": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da384f18b8a6e83d45afa4731424f1bd08317d10": "0x005880abe94f01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ec8a7741041f5ceeb83ba66b58188a560a040000": "0x7cf0679071a357a43da60fe7685f9d0314b704a6465af69c4ec86a310d2cad4900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970055823c75b1ea66d16f08559adbc70e19227322": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ef237ceb4033d0ea9adf7a316901a384b1040000": "0x76b3fa5836fb5eb23288d20ac261989160ce1c76eded0e23e6e25ab98234152900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928908ee71a2eb80bb3f51e5d5a95862f78aa3703ffb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893137346f506a2d980e1b00a5ff4801ce702448fe": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894185524e7b4ec8f909a435f4ac705f9348105b32": "0x01", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db24b419150b1a22c259fd8321a3058ea83a8118d29eb0bc46e0056e6f9889427": "0x4dce6b147ce7c96b3722bcf6ea4f86c98f0c3419", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000977634918b6483ebdfb23a3e68fa322f1da1b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc2bca81090e89e309ec127817a88dd595f2f3b370c1277ee11f5334cc075122f": "0x1dc59612f191c66e69dc23f3ab00b945593836e9", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dfba60f29b3caff9e6942494862994c277f05d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892271afc06ff1ccad666da20d7e4c5817ce1af599": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897f59fbfe6c2cba95173d69b4b0b00e09c76501fc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ccf6ed5fb4b037e92aa2b61cb1239fc6572d0c6": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fbff56f721e4adf38f8123c4e98abfddcb080000": "0x0e6de68b13b82479fbe988ab9ecb16bad446b67b993cdd9198cd41c7c6259c4900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f24ae4ffa0dea729530f81bda54f5ad0af050000": "0xd4ad39c91010433747d3e6817e73678e317969eb4c33786cdf091affcebe450500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d567082d66dc9c1cd236a3044a92c5b595fbeb6": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea9138be7bd2bf49ac9e7eb09cc9e7727ae44b1b66deb95562f353c71b2ce168": "0x0054ee21332017c772a9dcb68cc6e120b305c9ea", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b357d2fd313c931d28ff7ca74e0e0db992080000": "0x7657cea869409d039e938e7e3c418ee4a0377eed697591775c3210e2f718625300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d396f87af37acca0980aeb814375eb46880d37bc": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700957438646d37820df1a7d2434f4955f4c930ec": "0x00185504205500000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d24bdf1036d7330a4523dd74314816746d3969569fa9604a4d3f8a3de9ce24f28": "0x008dc499df64ff95fd5b048b15d430ca0baabbe1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c699ed7a9354ebbcc89529f88b67802e6f35a337": "0x00b4697f7b3200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51332db308a39ec5c17aeba2b4f6152736b4010000": "0xaa339be97e8b33e2eaa4bd2ae50e48d238882841f2a1caf34da47b021880443400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289759e87db3f90e6dadd412213aa32140a8cf26ba1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897b9be8a12f0bb04e290a6727e57dd34757b776d6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fd4e15b4dd20136a9621576743893a17d4dfff2d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f3e809c51300ca5731ae485be9885098ea8139d0": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243968bbcc804a1003e95b3150c50fcc25873e0d8ba": "0x006001ca9aeb02000000000000000000e7c0b90400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b3b6d0e8643d53b6b22807385fa63146058f56": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970037428972d6c3f5f40200902235c03843a3ed94": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fe2716ed876e1a4243333758d547131a98490a": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707bf572c47678e5141ace6b29c38e0a9995d7134": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7b8441d5110c178c29be709793a41d73ae8b3119a971b18fbd20945ea5d622f0": "0xec3af4ace34c5c019a1bc08de4dd22df31f0895f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a184d0a2f7d54d4552bbdcfc10d287a4c5bea5aa": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f454fa5c8c9dc56209f6f5d4c7df32c735c4946": "0x00cc3bab081700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dfad4e398bcfee3910f788ba02ac6de09156ff44": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ac42f377da5d9a624f94d0e9904e76c144736d": "0x0044db3fc1ac00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900477bcf4c48a8c4814ace55160c0ab89ddc9795": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc08ab19077f91abc5f4163463deebd9054613a93e9d1076b4beaf38684eb4e32": "0x00ba381e968d5a797f0d93e5f3705bc2a98d8734", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700272a64bc6afa24c034902ae6d9253314a0f655": "0x00488c227be903000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c2fdc1f6d5ade6a3d39ab48d545a6a59d971265": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bd546ebfde341c6b20726d206d084de51c316358": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289341ad4e79cb95c9c556e0bf96863d78a182d08f1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005b75905e8b686acbe0365d46ba0ac2a70b3160": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4cf1511151f1ff35e0241aa5ffbf2bb4f13f57e68a2e9ced4274ec08b6af410a": "0x1a0433933f6ea1084a7bf83ccb474b4cd263e7d8", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8e8e3ab65dbcb1a1835299935bad1d984a80fd4d1e3f10f7402dab53aa44b128": "0x705fb243cd2cdda5ffd62c702fbe2d48353e3bdf", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbe84f63b9e30f438711f49b4a2f3e251c541f9a6e43b0e9df4f64e8394ba517e": "0x5c0e0da2990dd5c3933b13cc49264c206e62b474", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5129bb6b788cc740ad8a4076865c06b26727000000": "0x1c2a5f648afea2a94286c17f6c60d16c9ef8511fa4ae88a54ce2748b6c8fa90f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d66b1ebbaeb6b2beee0ef60ab899c6a6ccfc7e3cbf820e5be26f561b44a56832f": "0x004af69a0c1ef595d06cdd6fa458165efeb0fa8c", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d7ffd826ad8f3288a0159a0c6b5492242d070000": "0xd2837598797295d619785777a5b9771ba532dbe841b224caad6ab58110d67a6100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b2cd0402bc1c5e2d064c78538df5837b93d7cc99": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dac9699995e6091a616897cc7344af69d9ee2ab61aa33ffcd2d11cdb895a6f944": "0x5cb05a5971756ce32ceab168695de963f70b051b", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511ccc384eeb1a9cbdaa1ca3ea4b8e4516ae020000": "0x9e743c08f7db2511b7d73fbf70d949c62944ab8fe18ec19690f2ced2c0fc351400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d18a9f519644fbe5f27956fec87cc8c035080000": "0xf49b492b314717533bade41861cb8699c765a0bab8ad7b83635662705c0a11d500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd02c1edcd16c17e8e1a9b6d3bf8c20df4c1427225868599d0e11da1442eb297b": "0x67494fb2a324220f917b9f9d6f6cfe72093d4cae", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897b365d77a01b72223a89517b981d0b97e5e41646": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a43389d6cada465a26af74f61c897d1855ca63": "0x00e61c8dbda200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397141de041d47905ce043140c61970a5a28ca39879": "0x00d098d4af7100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f35d8f45cd7c2bc88e13c929ae5190d7c4060000": "0x56715f37cc9f7b4cf7c97ae4a0f8f4f10d8a22f6a45f0b08a6281bfb175f7f1f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b305edc645bc99c5264c16c8c9227762c59043": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a20a5419f34167dc1b4ed5a22a8888ea6773520a": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ef9d64a965dbebd8671375325a0aad9358218934": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973de2de32606ff2d88b86efcabefc7f0d850b1d07": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8bdc33dd6ee3520995675c15083ad8db68de8bc": "0x00fc717fa12000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbeae5bcad1a8c156291b7ddf46b38b0c61a6aaacebd57b21c75627bfe7f9ab71": "0xd42059f4bba9e1ec1aff76fc2c0afffbb0abe68c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d482c372545dcc163359bb181126befde763314": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bb8b81fa35f3cc0ec9878562c80da8c91a050000": "0x26a9d684d5dcf7d34c82d0e88b811cf5f9faa13c95ee1eef1aabaa1f2f3b956c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda61c824abfb1e5df1140697374346be4443e41fd1e6ec99c22f2cf3381eb82e": "0x7cb45acd0b8a871f396b319e5549bcd36a047533", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516974aa1820a98d8c68dee483a645b846e3070000": "0x208bf08c0dfef7a942588f65ce004eba9932fae7c25fb33720debf8d1e27350200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900599a3e41a80ed4b6dc948a52fb52bba05ef887": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dde55dc13c5df43146dd3a4e8b44da6a27d052dd19443121adc90bbd690b4c334": "0xf41b89ea9a14abeb84183d25896b79071a81f5a9", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5108cf667fd728f66d7fc5b78d2b611cb774010000": "0x808776b923a9800a6a340da7dadecba63033a28c5f30879db9b6f8975caa9a2800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5129d2db55e0a939e65a4afce889d0671790030000": "0x1a14b0528d08f27ab53ff72a5b59dd415232cd840c4cf4d07a237be679cae33400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970be9a01de08f7c18e973f073844aed6d8414a5e6": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339749657dfe91f0572eef4984feb486a34f2a98eebf": "0x00ca91bb010500000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d167d9286a956bc717c29ebd938fc46bc05eeda8f507575a77d01985e35211e20": "0x00106ef113a8cb3c3a233553c4ce69ea14d88524", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5130eab7fa5eec230d8c29e4e58423f9338d080000": "0x9088903c35f715b176cc6dc581484cc306a7d643b0220f1386a31ca925c9a60d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970088a951e10d2f4a7e9cb3a2fefb563fac33eb0e": "0x0028cd22abaa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289350b85f8b7d4924c88b90cdac534ff4931512ab3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cef11607ebc0a7535f23e0b7bc4eba5dd65a75b2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d08a42f9d42527558253666ca03c7ba05ed79b0ee71469cdeb27d99482da09320": "0xd06dd653d12418aca05e155c451e4c4f628ae986", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007c2833e9857bdcfd571270b500c0c397f0ea80": "0x00807c4be53b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc493b051f40fb47625edb508d1a43509ef0e3a6": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001c0a1988b92b2538bb264e649e285bd78beb07": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928936f44cf83a35e43c5ac7d775f24a11e6a874a85f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c5e52c3882edc17def447d245ad8101e0c040000": "0x8a1ec46479fec3c43eea382d637de8f295ccb2c0b6f6fdd4c5d34a687737a60100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289537902c724861132c14848de8f504f196eef562c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c4363a5d67bed3671cecdb593609745882e913": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974dfdcd7e1ac714e61cffb899d09235f4b548f960": "0x009614e5531101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b5eba1c7420ab3513ca76e1358b1a7c9038d1fe1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705fc2dc53c14f07faa71da549035569e14c7c793": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895449713c3b74111612c326efdc9a5e9567cbaa89": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a528e61d81a47cc9ab160555143da7220f9471d2": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e04fba4d693e414f7252ff3381616d711e13b992": "0x00f0cc775d8600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3ac0cc6ebb5ab258f626ddd6ad1c1833140996e9703c6c4a5688f45b421ad710": "0x00de0911e577096ba2d8e3f2d5ec0458b1d24830", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289905aa2247bfd6b8c4850d59b83cb6a43007b2ad8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ea9c3d391651517623fdb56677aed5a825000000": "0x8c6480536395191bbc760632ae89722cba67f49042cd1a5a5e729c3186a4176700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397438ccbd79f20c1e68b828211ec2ba30c0ec9c05a": "0x009cb679bdef03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005423adf241a0a11478d32b7d49930fa4267709": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e2b429c8428f37654b553ea0aaad267f8c67cf82": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da29b24398799903fe36cfe2b193e8d0a90643a3abc81105a5356afe30c7e8377": "0x7d64d09556b4e737f932b39dbbe48fa4f67d862b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928920a77f06ce8ad15268b50577aec5dd0af28c5c84": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d127a30e486492921e58f2564b36ab1ca21ff630672f0e76920edd601f8f2b89a": "0x6be555d4469720a6a980245a1a2139a5e678e415", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971d55410119f0d9f4d3eda0a346a43ff04e15b36f": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a5d4145d389cca2ae8740dc2af3a06acf135e3": "0x00b65c7e590b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b4e721d3968b0c88be2dca14041f75701064b3b6": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700973738d8b9ff38e9af49f5c7b511f41199c106": "0x00e8d992a10400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005e42814cdf3db319923b257a0e0a48e3ee5350": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890093073268cc5bbc3c4a616d9fa90cb49a34d339": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d72d8647fca16d78cae19f6186371a4aa9091dce52f566f05834afa9ab177dd28": "0x449b5b91b10523f024b6d9101afad2f3cfe7c8ea", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee1301ee318ac92f4ae4254263da4325640a97a2": "0x00901ec4bc1600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d5f0ae658e4d4d48cce0355ab6c1eb155b7a82": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc8229bde539592a0e953424f61f362d2e275eec51c6f88facd1b8cbc925f045a": "0x30da5c03ce04c15dfea28b7466b5598e0f48c1e0", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001ad8e92592570e989ca076e2d5e4c1638cd3c5": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca5579297f4dfb9609e7e4c2ebab9ce40a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cd52a72f9655ced5ed66134b11deefa841a28d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978533a89796fe8070604197679c3e250ea2a88a4a": "0x008e804bf80700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289128b1dec802ddf81681e3d6f113bd83dd852311e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004ed6f4db65547b8b8998bec6c133d99d37fe3f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d761a334025503fc32b8d7029bd4f1f90fa08b78f6144e0680b430931c36de76a": "0x07940d682e51fe3f01b2236d18aae7fae021a7e1", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289058457cb480231445486c786db63ead914b9e1d3": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890a2a6f1eaaeced797b514b9da30309ccdf857d70": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892ae125582205e28cc4786f5e729d9a09608d7b27": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701bdb7ada61c82e951b9ed9f0d312dc9af0ba0f2": "0x00d27175e9f502000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dc7778c338e869497f09f0894618334afc21d266": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895cd12fb4761f91f6a2bd4240c73e7d8fc8a3f638": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c99a3b6afc1215dc0b1196ebd9edbf8b045b76": "0x0018ee47a4d000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f9bb7e454f5b3eb2310343f0e99269dc2bb8a1d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c9645cd9c965c5d1ba0d1519f8412c5fdd9283b4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289470959f6872985a33b5f5ccd75bf2f8a407691af": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e737ea62ef4a2b771e3e82be3b8e0898181a8b62": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5143df6ae6411e8d60b5b5a4c5516ba6ff8b080000": "0xb3c66b5c51c955020fb220715dc0f73fa4514ca434efb9bd12e9cb169004988900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243cf7c0865a0dcaaf8bf3c5641e82eb37c690d5024": "0x0080ca3961240000000000000000000069de3a0000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510332b4931909d1f01830bc4361537e4f54090000": "0x1a2f001ed283dc87324378e0fb2c820997b8ad16632be93cc19869440f5f5d4700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f0f772504eca495a1e9bc3b8a1cec2b639c9df": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895b614ba568f71a18428d29dc741ef829140b46e5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b2e52e1a42c3ab5305f1b071ce7d197565e9bbb7": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976f9bb7e454f5b3eb2310343f0e99269dc2bb8a1d": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd1cf598b1a50d24d53c7241fedf2de60f489597": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002954009901528acdcd08e4bc173f271ae4c291": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5247024eb375e8741cd51473702b6f574bf45b8585fce64768177d2659da5f3b": "0xa13d980cb2bedb03cacb7003143e7af78c602030", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd485ebc07a3913f5734c389f7b74a7d81f62ada7262e22d485b1ac2c640ca646": "0xb1b561896f65cd50341459052a69cefb25673451", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970099d229b3b989f3d7ad9778549a540058160fec": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d35ee346bf2df7627509006d92316ed8d0713d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339704f0594c389d0071131f288014a05e91449146bd": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517f824c46b76cc7857e143df7b9afb537b4060000": "0x00e2711e44108938250ef0890c80128c0aac93fe6e146ca54e6905a1895ff06100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792349b865f8b6033f8a36861f62fe4b0202c93d1": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894dda8293a5da4a6021f6b228845713ab246a8607": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd01fdc12481b7c5de7004e8dd54ff70d4bc561d3ee07de32dbee35b7348b813e": "0x65e9bd9c64b29a79b286f4b2f8a3cb449c13a91d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aa70dbd775c74c3182ccf34636c63637b49a8f56": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d824a7af00f98513fc725908955b32f8c745bde6131ee4b71fdae8ea153101218": "0xeb8192767e4a432cf722450cdd0985d904e6b748", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730f92bacb185193876bf6f37a6bb10f01aaeb36e": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d20e0a7b8b478d267fed40ccc4a53315eb9dda9e258c6cd12befa4ce2039b707f": "0x78a451390d870ab409d22dd5afabbbb623166e3f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970042fc4e1015fd757f149ca0ad34f44c33b51893": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513cdb10998eac4559fa1a267eb2738dcbe5080000": "0xf89537d3a6e3eea634392a7db7096c70319cf6c7a8806d6312ec58179e53c60600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51558a258f1e6767ed1f60dbc321d04bd0d7010000": "0x489ce3deac0c0573439241af1f5b6aefaa31bf07c4cc1fe3191f6de83b44952f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7e2928aa326bc909add3e91fc8389d76e6c5fa1d9605edb04d657aab22e5a258": "0x16621a778e3533c0219fa9db54f2d65c1ffd978f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ddf2bd305b334ee4aa8e27481db525338c87da5f": "0x00ee853eab0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976c068858140829f7fddd7907bca518e6b97c7274": "0x00b2db83201e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890710c910d3d8061019f91bb90ccdf607898e135e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6e66021e4bc573a1cd11450b9adde832cafc9e7e83fd3c4901c3e0d0f0789009": "0xd38e00c10beaa10ed77f6e574adcdc31f1647e56", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289537b2feb029a7073da038c2b9bd34c1c6109a0a0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397522aef9c286463840def1e9d7b43f15de76b1b4b": "0x00ae9f17c4be12000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890098029c2d615fe6f6cd9a6b6d35618878dc4cdc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a49b7c571e40e73be0122d9256016ebc704a38c4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8ae76cc2cfc6f643aaebc3391da915c3e722329b4ff10bcbe6fbead4e79fa56c": "0xce2dcc3b6911ac513d32f326bb72bc44c1ca1b84", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970bae10406f82399bab8c8713aa8f5e0c05c98d84": "0x00b688ef6e0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006a2ebbbfbbd4c4d0537c033b1e1ff34202bc61": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc4b2c91d9d4fc939948ca13e03fc91b01b6c9c286ebdeb4c6f9843156166aa19": "0x58a9d04522df5a3c7e1af52192b89d9c952b338d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb2b6f2f316f419c8bbaf441ea94e47a2193f7e2": "0x0000c16ff28623000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea4ca720a5284bec0611c7d63e78cf1d5fa8a64d0c3bfa17354fb2a4cfe45144": "0x129631915a3ca10b9a159a7dc95bde0ba71682d3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c89a2437b7cc02b0bdac206ac317a8a1e7826db": "0x00602225aa3f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892ac00bcb875fae707ed8d800e17985d174ad3027": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fe550bc1088982fa32049171142e42954f3294d4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d8566765f1c00841096a4c097c5da2cf656509": "0x00ecc28c1b9603000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896556deebc10e49b32cad8ed7f3604827f9672e0d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928920c1bf2cb99a7026fea57c28dcc9e85c4ac89c94": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c0dc84869b0efae772635a889ba9986b28c0fb": "0x0058823c772100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c50164ef29cfbff4685873ec8918fa2b5190b2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5abed40690213905ecddaf187a5a16cba5705720196bd942354f1debb47c4470": "0x2c8d6ee56d63c0ccc987b1bbce567834e4e3f312", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a6b2fc358a77318dacd1eabcc8a5b27b7ec14861": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894dde991987acdfc23c0e4e72c70d715794a052c4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897162bf64f3d1e899cdea224458af61a33511ff42": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5191336d14cd48e42c88cd104051270410c3040000": "0x3476a6305429ae9215028af5afdfa49abd1104cadf55e65e20af5173acb2de6000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d103978c14955ceaae31e258d640048cba43ea36a3636d4f6884b7ddf5e30d113": "0x00acc0bd13770679812fae76ceaada758781a5ee", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243cb41214ae65c8ea58500c913d29305ac2092f0d0": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc05210b4c8af29367ca9ecbde4992250204318d053a6cee2a99850ca05cfdb5e": "0x024afac105064abd224256087859ce5fe0dd2f89", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700718f7d6f56e3aef4ae4d4dca50bedaa4bc4f3a": "0x00745a2fa8bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e1d15e2d670c63b9846789c38c28eac68755177": "0x00805cec442900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928943bf5419c4eb65b6f8cd55489338ded388c71b62": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892c8d6ee56d63c0ccc987b1bbce567834e4e3f312": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928974b9ee01ea740c5d61e3868dbfd5abe504269ae6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d98e54d3a278c69a0a65b7bdc5a82294ae9c59fa7ef908a41a3f479ae08742b23": "0x94cbc73d485035a0ab712484144dde3352d6cf60", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bc49098d1f282e8d10fc8ec1f27e119fa45f8498": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d00c68940bd54119e1b84fbf90e9dd10034a2b937f2c2016a155100a598db892b": "0x00590fc72b10e46e5a5eb6adeeb2966b37b61b4c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a7ffad9c186a581b06ffae5f5c1fbfbf190c794": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339772af8296d1272deffe909926d1db18ee418542a8": "0x00a2092f3f3600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397051f77131b0ea6d149608021e06c7206317782cc": "0x0008711b0c0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd3bd59974417b224b5951648e5209ddadc42381": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008d723ecd3298ecf004ea846fc880002822cf59": "0x00983e953b0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700feb32379a84bc54fafefc9e3faa03e626892f8": "0x00bcdd8acecf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4410731522e26803b8e6eb6e5467d77aaa050684b95722bba660882c90a9d015": "0xe0c04181f1437010d0db38d7623be82af40ecd6e", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bdc59bc934360468b13b8a94bad99871df53ae": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300590fc72b10e46e5a5eb6adeeb2966b37b61b4c": "0x00ae3d7161030200000000000000000096f9410300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcce77d786693195b956708015ff218d87a546e5b2c4a2696dc7cdd82b98c9b44": "0x00d57d447ac2a9cde3401bba7abb6f888eb63ed7", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fe023a9198e623f212a7eadfc0565fda1d070000": "0xbe29d91eef0aac3d083dce8b7033d16b98fe94fc303d21e6e268ad311313844a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbe921850b08e283ad8e9fa23d55b6b9a50223d4bbde1f86884783c8619445244": "0xb8f9101b21f47ceaf22f52b0f4373a0d95ae7af9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339713d45bada78daa5cd52162254d158a217dd1faa4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397213de3994517a65ef92c7ad4ec9b824dcccc67f5": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928922128818393800d4123cbb9b81740db04f380977": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890016b34601309434ee42c643a76b78696e8363ae": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c90480cd768c13eb1be84bbc0414883bcbac27": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895c0e0da2990dd5c3933b13cc49264c206e62b474": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d08ca477537ecd3556ea4e694f0d3c9959afdef57149bd303bb85c84a3124a302": "0x000a8a991cb59ddd83b76f334288e57997d25853", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ca3dd8080c9f217c9a1e0820c39e31ade0dfc0b5": "0x001cf28d372200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c163730557af3cc84dffd66affb23d2347154257": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d033fef6d4c75ce2f4878314057c2f959fab4679": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004217146a0642a86afb5e6293021dd02d1f4729": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893de2de32606ff2d88b86efcabefc7f0d850b1d07": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896a8147b63c67b2d13f3d19f6607ae3086f088490": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b26577622b961191d9760e43cfe25ce444b02807": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397487bfea2ffcde43dc7cb20b5cf1f84c7c836e917": "0x00c06e31d91001000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aac3bccfaddf32b9066fed9a76f0694a471e8b71": "0x00865401b47f04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c80503caa4caae2640f0bf835bd5e3418d4ee1": "0x00c0fd5f400100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5172475f0b5a6aca3c0f3e372e09436bdb84060000": "0xd4dac0e43b7012fdaefc31e13762b80c909be0d0508eba2d22d03ad954786f7f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928908c6c136fb974c8ffec3b38e8d053791a048a0b9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928920135f71a2c2d92ad87aab4431862fd7c38c79c4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002cbe540f860818a183be6052ffbb1de22dfbec": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bea1d038be0b029dffb599a396eabbff2584b2a8": "0x007ebb5c423f0b000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5178e311aaabdd03450b0584ce99102e8426040000": "0xbee56ca36a0a5393bf9bfbe5d2079e31d4359d35388df257e23793c7b195b85500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db64c29324eb942fab6b41cc041f0e099f35d5c7fec824bae17717c5fa68cb83e": "0x55c1214cb709381cc47eb4edbd28d19c67939a7a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008bd7c09ec961aac1fffb733e6f7615ba6990b7": "0x00ce0530150000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339723acc3516b86547dc0096ec4a3447af0ea0bfb55": "0x00b2f58f6b0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d982a7fc06922cb361516d5fd621f1801e31943c3e1d957ed63e925dbd5672a35": "0xd97e73afd7e39b59832ce426537ce534bb5a34a9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978370da48be315b1f73fdbf206a9a8678234a16a4": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978506d946cc63d1f1f3a303d68b0da64597cd64f3": "0x001cd01a8f7b43000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970014bcad7b114436044a783d787e18f947fc8bae": "0x001cd75d120e02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f74310dfdbde986ba9bde96a472efff97e2234a7": "0x007ceafac42900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5151eee873794ff81ad8bcb8c28326287de7080000": "0x5efad5aef39eadd6d70721079c222dcfd7a12faddd95169f5df916c45b4e7b3b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900659ec26a98fab3ed365db68d56a31d005cad3f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c3dec2840b7d5077d566658f5224151f97050000": "0x06ba2bdf21a8e40bc4f333eea2868aba048a42f00bee1ea5c1cd8913eeb32a5600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d022a9ca172e5543e2fdfcfb72a6734c6d050000": "0x34d46a7b5d29b3012f3d797ddbdf0e2a5a211d5a2f071a48828897a2f35ca30e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975feea0d35bc1d74650856fdba465a9fd7582b08f": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397efabdb22a54dbdc370b31156a16b7a362199affb": "0x00400f84b5a300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890387fcdba9b695926f21ae1b0701fadc85b28744": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5181ee21bfa4a1c1f0893cdd0f5ada8eeeb8080000": "0xe6634f00d2a02b8c109ccb802bc0351674e21650ec3bb5c96c2515dbe6543a0200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5142469527df36f9aed9f015252db5ea8754050000": "0xb0eea2a1f67da637fd1fa8c1895d15ec763c789567cb02463c6edb494d3af07b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289076f1329e5a326f9b1a7a83b99281e1fa0895585": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928960c5157e1255dae7acf046b38fece4a69ad6289e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc4e71dfddba17863c7ea76d390624122e2369ae4f3a01a910036e7bb70d89e2b": "0x003e042a1c0d20f39cbb5664edb923aaf00b8e30", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed53f7c273f524da37f189e800b9bb66ec9ea26d": "0x00545a7c258502000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ad57cf7ec770f7d356b96e7b5abed7e10fed2c60c21cd43a558ccd33ceed9cd": "0x5b614ba568f71a18428d29dc741ef829140b46e5", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51647a794c7f9a29deca7d75e080f8c65c29000000": "0x5c720889653e8b55b473a6111b9971495a924d131ecc1a60e83d770849953d4a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975cb05a5971756ce32ceab168695de963f70b051b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928902dee0b9caa39f4e16b63822eeb6de8dd68464ad": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008b0c207b6efeccb38af8b6849ffa6b9be0eb61": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289752975f5990c33da38c4cd50f0a41b70b3a6796c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a3db1e1d102c140d89f35c708d37d8565e040000": "0x1251da9bb3f5185428cdc2eb2178278babcc3ffa9bc8bc4b19209d60f5832c6900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cf5351c2d529da04667b48c86d2412d7f6040000": "0x8ada3c6fa6d06703711d5ecd225ce1839bc44ae0e6b9c3ef1ea241db8f66817000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970082242f0e0c5831adcfdcc04052b72dbeffbad0": "0x00c2b658000100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890044208bb3e0d5b0dd69cff4eb36acdeb986c189": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928924586e1a8a6fbb94ca745b6ceeb98017fc8de873": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ae09e49b8529bf5e7cdaa468f652c3f09fe62289": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b5bfd05d823b7c9f00a9d66319c889d50678f457": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892e3fcfa6ce2e239eb735071d9f86e38dd5f8d8f0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b06c6248f718528075ca09e7882eb8acff080000": "0x802bf4620f7a14c125343ee7bb185208670bae709c63228c12acf6ac4d023f2200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bf9ddfe00cd7d62d697c92e084dd61e05d050000": "0x52b0605b1fe9bf82a21c3231b611f23945734683851d49e29cbb51f4acdf041e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d3dcce592e72f9de4f14f72c699145950c7f2889": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511b1934afae7066c22b1305c7c87f045c98040000": "0x28e2740f0d79ca882ba5e2530f61aac644384032af481b1eb41ba48a1c2c1f3f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51db4510c4f58f0bdd1de80a8fd6eea271c7020000": "0xa26d7f204384eec001d21fec7638b13c5fedaabf38d64fb8cb70fd9bc4146e4600000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca487df464e44a534ba6b0cbb32407b587": "0x0000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972553a9aa6cdb203895a904e98f6d2437be0805ce": "0x0094bcba878500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973310cb1ad03f5b8a93d5c673e11782f159a017ad": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f01fb7123fd21b1428098e7684093babeb59b764": "0x0080c6a47e8d03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4487a0a91f3c75bb9631fe6160690d9149ed853": "0x00ba96511c4b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab2a3ec557a9fc596bef9c447637abef78f2bf36": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890a92d58547d1c7a1f0f340e540267f278011ce0f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892f80da45d4b487b5dfabcd2b85478a6730d798c2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a2e0acc596bea390051f5ac435c527bf4c070000": "0xa422bb294c984d6edf3736feb318ff9e316d1a8488e2bde3c9cfdc50a802ee2b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2ea620515ca448e7d546849540f0ffe2bc8dc3b665b7b1350f21f70a35fac055": "0x987901179f790fd04e956173d45fcac9aa74b66c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700aa0554b5802d43ab255cd089a6a7fee211a41a": "0x000ec19d5bbf09000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5181998275b462923c9a3483f4df4a1d9e67050000": "0x542e185fa0607eba80c93da9b7ff93435f0f5fec06a8876ca117c3557a3f516e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c87f254b8701ae8bb2c5eea176838ba02a050000": "0xb067a8a7015b58d16ccdd5dd7ee3e2d6e07f725bec022f6b6604adcb058ec70e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339767e3653e795000b68a3b2f763f628483e21c96bd": "0x00781154c61000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339710b26700b0a2d3f5ef12fa250aba818ee3b43bf4": "0x00caadafad0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397320b5f61e5ce5f386149dd2f1f65019657724650": "0x00e67db2845e01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3c0189ef9aacac36959a78f72da2d5a49535d5b9a31845b820c0da2ff4e26602": "0x1221d505ceba3ea8f70b3324e11ee7eae3740b93", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976eeef85c9161e7486156e8fa517ab0964fc1b969": "0x006c9bea403b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa0fd755c0d0528c9b7633462a4570b75bcabdb9": "0x0076e6a2f50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c9645cd9c965c5d1ba0d1519f8412c5fdd9283b4": "0x00ee5c29a72f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c95904990fa58ba027b185d876d88d4a079950": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928965570b90b7887a0ceb57f7604da311e84663a290": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896bd16c10081589deaeb5cdce5963fabbbd350616": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289720bb1fa61910880dcfb5256a4b2378cd5d8f563": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc838f3c7b8b9223bd1f08b47d800ac5daa9d6b32f2e8faf4f16555c816ac4f22": "0x2ac00bcb875fae707ed8d800e17985d174ad3027", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c8e15c38714d27525ea5dcc9bb1e622f04fd04": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c43afbf4fae6c9545c16a6de3c8abedc2c589271": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5168ff3cade57fc8a0179e6b80456643b781000000": "0x828fd8ddaf7415bed383c5732e236d718bdbcadc1790ada6e27dfa87f9e74a5800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f3a8b900e2bae095cec502f2262339930f090000": "0xe204497afb88b9af744c7d7b0cb10516cf0750aba8ef1989cdd0c511b9c15c6e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339776c1e740aa7f9685923e23e884fb23361f008111": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7a2179c90de5faaa539ef2f2d8a1d0f2ea547db": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bdac7423ca974deb9f4d5db731cbc3f5c64e3f4b": "0x00901f44ae003f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ffdfc5c3130107f310a81996104c889731811d4d": "0x001e39c7e9a600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51555960b388aebf663f7852840a42005553040000": "0x72117b487f33e88cbfb017e9925874f664a0d0cabebafecf2a2677eff0cb847a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a002d19522440cd4af9636097bd510dc780f8f": "0x00ae518f24d701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ab10a4c4d9b566830c833a90c865d859770016": "0x0020034cf68f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515a98b6df68d2532b24cf133d1dee85801c050000": "0xd84d3591efaa337adb83215be213e18204dd71fe9cf356f72281a687c825356a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970086c68ec3a352527ee68308deb658fa50da846c": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700da40c72ba0f9b64145964396c15ccc71cf7766": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890010aacbcfaa53a4b19bd7bad12ea033d1377220": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fef3b3dead1a6926d49aa32b12c22af54d9ff985": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f4f8d0377b14301ea3778fc39552b421b586f7e4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d94b6b94508e6afc5a85d01a5cf4a5bc7db6953981d36ca03d82c851d79648372": "0xa528e61d81a47cc9ab160555143da7220f9471d2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397204ebe348564569032991905d5d1d4ccd35df422": "0x00d44d82b10900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d5faa7afe93789d42c8193c01d67a25478d1f1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a2d3f2f6d4a3fc6b4e5be57fa3d896b3d7e04cd": "0x0080f420e6b500000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b2a794ad36f9c8bf61be70b0d35c4c7829060000": "0x3aef55642426e0153ede83ed786d7d8bc66ced9f461bf5a77348032dddcd853300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fae71531e49260eff5e0e0f970dc70902f040000": "0xe6ba7360b9e07983d3503bd24e0ebd36b6bdf50a613785f994cb4964708c791e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282436df205592f28ab7e1db1ff8e24d66c53e5f22c3f": "0x00407a10f35a00000000000000000000062c930000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243e0e741e91998cee7bdfd13bb0c48ec23fb8c1f60": "0x0080a1a76b4a350000000000000000005bcb3b5600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289608cb60905efc0b59ebad8a9c650a410fead95a0": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d58b05775f004e33d9212457b1f0e246dd665f76142bdf5115f561180acf0bb32": "0x00228be11366ac5fe81770d49480c2a190a9da08", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d4c5ecefdd2a070bd0caffceda6b50ca10d7fd": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900336f4647818e2acaf710ad55c714dfffaf1ecb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e9763a3ac1928e281c7776b41aaa83b558204e0": "0x008c0d35660200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928920965e529c2a05a2630d84b9809be93b76720096": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eaeccfcf272dee48fa3e4e783c6dea0fa1fc38cf": "0x00da5284960300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928971a3d6c54338788dc4da94e34cd9ad2f1d89d7e0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397511912af85b5b6fa435339879dd81d5140e516c9": "0x003a6373de8800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a3dc3119df6bc6cdc397c83ff1d7687738080000": "0x68e72ac76f4f79fa9c7333504a6f19a01cbf28273ea2d34fbface9f8bf817e7000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970097843adb6489371e27819e20fece2d58cdda3d": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f5d7b6314cafa1938306aa393f09f6012ab7288f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d10b5f5141a6e5bb941902a1c358472374c98b36fe1352c5cdcc0083acacbef07": "0x00c0798c0df1e87069417e76b8ca4fa089d051f1", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ffdfc5c3130107f310a81996104c889731811d4d": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19500bfc9f68fb7dd3f27061726180cec7e2d5e28925ae9f906e5ebf1c81adcc7e524751273a73a278f472d863f532": "0xe240d12c7ad07bb0e7785ee6837095ddeebb7aef84d6ed7ea87da197805b343a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009bdf8ded35fd7e2b8f649a808323978569e05a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971bc24e64bd4446b8873a956a4fc1d1af2b798a2d": "0x0048a2f99b4a21000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900dc3020ef4790527aeb51d62567bb48642acac8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fff7e689a4ed9668c9207f55c8d68bab1cb507": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976851cab6bfadfa47246dd71528c4d519aeb85fd4": "0x00008d49fd1a07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339703224123bd06444350b7d75e2b080ba68598ddc9": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f2dbb3e34ed1d44c56caa450a65199ce15165e3": "0x0044135e7e6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d60059d247f883ba83508ba33bc087e517824a5d405fe60542efe01f2d7db5767": "0x0f44232ef2cc7a637513c492322271498bd4b915", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289075c5fec47d39bd6482df2cfe32a6d1f83b722b8": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da24a3d7ea476f7eadf8c65f9ac5aec691aa7af4d0e4a8863795482016401a732": "0x00c5d33619ffdf46315cd16bd053a03d2873bc37", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339702dee0b9caa39f4e16b63822eeb6de8dd68464ad": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ecc05d761209a12fbab5791b193ef3855ac7abd0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289271b8269e278d8a2ab0113de746c1b1136b320cc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d646982089831a323228bf105965a23817d28308": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004ed6f4db65547b8b8998bec6c133d99d37fe3f": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f3f007a415cd23b2275e689b088cc0ff0f0b1b1": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817deaa58dc24089f8bf9d09ce5be1ae57d6f47213a94475761fd34f73e92a3db15a": "0x00036d90bb4e462221fbe06403a023192c0e6c4f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cb33463e1812ee584c557a160780b0331a50b3dc": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1ed7e0cc71b2e17e00fccbb69c8fa70a32da1a96a83e2ee44e30f05678b1da06": "0xb37489e03c48cf54cff37898b07f64402edaf101", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d7841fa410e1caafcc033f67f20c0f60163e3153": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e87a44ddfc5762e9cf415c9c00fcab24f3ada6d3": "0x00704ccdfa7703000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928905c94ef9192ca1b80c427a749771cde2e0f7dc53": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f37e91526b4835c0dbdb35b8f1853adb31060000": "0x62f4e441bde73fd9195635f4706bd275b8f28994a7b24caac04fee952422ad3800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514e32a08bccec5812ad77a105cdb4b90342040000": "0x12c5c9b9dfc7ddbc627c60771de9a84b552bf1bd48e9332ff8abcb7cce87bb1600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339785f8d96b05b4b33b934f358bcffc916ea60ca1e7": "0x0086ef35191300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891e35152239ee9fe923f20df2f38280b32bc98d22": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519ba578f8b9dc9c703000ea47717db77118080000": "0x04518c742860d637765b48a16338b84661cde437e1668aea0867bb9d42724a2c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289280b9eb4839eb05e05e48973e1c969226fcc4392": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898370da48be315b1f73fdbf206a9a8678234a16a4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898e1a6e1d0d940de7accfddc03ae542af6d690c64": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397be7d69b9aec64673f2ccdb97c24bdacafeaaf2a7": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d9bd91673fffca8936f266f14ebbcf940f684658": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5124825437e7a91c00ece51a096237a326dc020000": "0x00ee008cc4cb267e410a49854b34df4dd21ab2bb826cd7dc055fef773711b92500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d9eb97d7b1c97639a6914e0cb56dd8e584910646": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890094803d665f06fae41ff86b05c81413ca8a8a35": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7697834d583c3c53aa62fc52856c9be86d55c0768f2bdc9c35295390a93f8e1a": "0x78f5234552ba1bac0a945d5e5bdfb56d84d4931a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006261f93219f1cf1b3468d807503dce5a5b11f5": "0x00008d49fd1a07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c78724c7d87165b1e7ddece03dcc717b9557c1ff": "0x000c5849192401000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890073e43211dcde9c888a7f57d65e3dc23e967896": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978285a8f9373803328ce82b909ed406e7b88e8206": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf2d514689fad1121753850b85496743cb6ba7df": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d7ee8a9df96c3eb8146b2532d3b25421a451a770": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007ad88b72dc1cf54adf012caf81e3db579bf04e": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ac0ef3f6d0ad997a16438cf7cc685c2aaf032f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e59d5f000bd5e17b3d5f9a87bcf85d1940f2aa8e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928976c1e740aa7f9685923e23e884fb23361f008111": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ef38ee9ba641cba4c3b92a1c594dd6e6708cd3e": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbcbad26ad9af28cfd50dd70c8fa6c7dd3964941a4e124f19851c003ee8be0137": "0xe95a0b7851db5423d0aadc91bf963eab02c6d440", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974f65d1913b854830681e7d0ee71c9756e0fe9f32": "0x0000e941cc6b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de65a278c02c568b67d0bac04b701deeca427066d27f8ac2237972bb86dfc4840": "0x123685f3b3c7550254f187ca3746db61e6a248fd", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000bee5537a6910f6dcee78c1ea1b7967d4efc2e": "0x0044cec0982500000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9e771b378ddd0f68c41961af73e4e93c78dfed5778d5377673ba9ee8573e3d05": "0x8d0d4cfa04b458077b80a2b625bca31d710cb0e9", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900463c8b0c4f1596ada872e327fa84481fed673d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db445e27228291560a790171804710c389df4ef28b65f83848d63db5fc77cd343": "0x5b279c406a13a1772c7c382d1096b04a7e65e753", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977adc26b95c3e4625e1ac01f4eba38273e6c1ce48": "0x00142ea50a1800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b6f20d6fa4c28a6ae5a4372d4798f2f759c25ba7": "0x0068367fe62d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289254c62b0e0862a383dbba455dcf692e71fadcebf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005b6d541644ffd62b7c61884bf8651b1e10e146": "0x00d6dc8cef0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970007e5053a12e40bc320f2be221a71b0bb72300c": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339712f9122d6ca5294f6817ae79a9c4634a07931a85": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705217a5ea7391027b88f54b550bca825d6108af7": "0x00fa3db39f3300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a22438f8c8ba4f08a9a3c857b2687cc1a890ee30": "0x008ace1a761902000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000d21538f4fbbe5aee7b158591e7cfc2456b0c2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339748e9fc7556146598014c9b9a4f258aff8aec463c": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db8ec978a98432565745c836f384440f84ddddd40922aac33d98a1e46f896901b": "0x2f7b34d58d8a6134c268fb8f0174e94ce07874e0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe8f3d02414c57745f1e87be25ee3496a1a573ff": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51571a4c91b0a467fd2ff5cd44e301b0003b050000": "0xfc96e66c4ab58a38b86c7013ed317c808c0e8684a8e921db83280190aabff65500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cb431327705a1ee54417f8cf3146669ea52f3e41": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d06e11fd0d4df6c4765eb346aac47682cb7871da9ecfd235255f6eadb8392b20d": "0xa926f76a86362c456e877e0b3f00c1a43b05c4ce", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970028f8743d32aa2c22d2eb1b415c64d3fb49ebad": "0x00b2f58f6b0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009b32198b47c8b8006c0c3483ba90a7fa18f8f2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c8bb43bfcda8845d576effa7ee5c555e126b0e": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824311e328bd7023e933426940ad12d6e1b5bbd55f1e": "0x00e0d21c5bbb000000000000000000009b2c2f0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a4ba602a82bb59c3124f5ade6b77e93bb274b3e": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d0380d16422278eaf980fcb91502a4cfd23d46": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243005d79be124e0852482eea03f11c3ce1eab68805": "0x00f0caaee75c0600000000000000000090d94b0a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517972ea2c61df6a92867a52b7944a8bd37d060000": "0xd4d2cbec06234804a90868dfa7f89619dcc178d8d361aa9e9eb082309ad6c92000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339743a125a9461625e72cf17558f1c8b3b653347686": "0x00009573c24800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d47e503b630c37057023c04ea57149dc70ae19f186db24f59881c55cb61da522f": "0xaf44c1183aea35445f24b3b82073cc0afd007cf6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ee58852b55610f513c694362070de7122a144b87": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339734ad8c38970ee9c497009e85f48fcd856322aab9": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5c720889653e8b55b473a6111b9971495a924d131ecc1a60e83d770849953d4a": "0xd531b67faf691723fda5e741359efa9bdb52bde5", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a0e65d2793d7b4fd5b46d91a149daed37cbe9dd522a30eec15c3f3e8861a25b": "0xd517ccc6eaa9380931987daf0ea1c53ce4ac4ca8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397968ced1eadf5bbe3ec2f6c6e1911b8f4e43452a7": "0x00a69227cc3b01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d4b1e7287477ce8247daa310641ddef3b9311e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928922a71133e0a9514145b5ea4ce0b874a9afd596fb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708ee71a2eb80bb3f51e5d5a95862f78aa3703ffb": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9289bcdc9cae01e2d396a8b70b27bfe77caf341e969c1175cf908a7ea1906e3a": "0xec27421edc22ae46c23ad1e8b34f8651b3d1d350", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928904f0594c389d0071131f288014a05e91449146bd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397076f1329e5a326f9b1a7a83b99281e1fa0895585": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f6f9eff7c30c41ddfc4cd9f78a5757cf3679ce7b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d07c48e25485b727193d8e1ca5b5a2f3352048f2": "0x008674a4b32c03000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd401d71bf90863a159beb23026bf2c0d14bbd504ae240640a17a16e9c4849d7f": "0xd908f80aba091f8eb3135e7876d51b5b1a7bb188", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397216ad8bd24f5f277b78774e605910e04016b6e78": "0x0080e03779c311000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900de8cecef8b9fa5dcad5ec62ec22d635e8d95bf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896df24f6685a62f791ba337bf3ff67e91f3d4bc3a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700091bfd5d263eaf2c04134a4ddd0eea8c70468a": "0x003497c6042c01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dc3bef2bc640387a9b8ff1938e5a9fbd45040000": "0x16735bbcfb152276f7322d3360d6f4a6ff55b364a953484161e0de19f5599b1300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893a7dd8fc58ff94de5cede695988e78e5f3fb3df2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928993011e03417d775496e3e81c5ba87cd973538dab": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d5bd8a5efaa38c2c9f3ffcc73006b8ff19192e3": "0x00", + "0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3": "0x02", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824346ac13adfb85fb7261d69153e73b006e585509e3": "0x0040158caecc020000000000000000000eb7870400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8ed1e4ffbfc0f87a0ca99d9058e2900c23959e1f410fe31f2648ec3af27006c2": "0xa1d09b38beaef617e933f8c735fee190db1d0263", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000177e159f6b155a0e81f6859e9ca4c6610156d": "0x0056cfcc711400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea2d46da940941153d236e8693624e1f4c75111f1d0dadf824786425c53cc045": "0x0cade02299ddef16f672b3525001d473485289db", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970031aa2156f558895016433e6299dec2a4505d5b": "0x00c029f73d5405000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c908d506ddb0c9a41766b3f54f2ef592c50fbb5": "0x0034a8c5180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977a669ef68da390965ed95cce8f02f6a11a6520ba": "0x00482276b8c703000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900951b683e7eedce3efc6199759ea1ab521fa5b3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928917822cd9476fdebd92e640bdf9fd63169750f9a5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970cade02299ddef16f672b3525001d473485289db": "0x00743ba40b0000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da98a41fff566e802db0fb6a7fec49b6fac5809fd84af6483070acbb92378e3498dbc02fb47f8e97f006bb83f60d7b2b15d": "0x000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b204ab1acdb7b9d2b4cedb03505a281a7f080000": "0x0ea81d109d526eebecfc18c680281235a4bf23fade14e838d120a2943a48efab00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f68ff9a1cb4aeb9018a8671087fcc6155bef517b": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893de899827e1b9413d6889727a4662074ffab3a73": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bb5634d0c12b29996b2086639b804b441878b167": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a0638fc950ad83956179d5584f8115b9f9e0cb4": "0x007cac4553a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002c33c9811e4b478b1d4a2e4c6f60250e792919": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e82fe500c39f4644d479f85e4b3e407a9d6a1e": "0x00461784db1000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51de82bd4b3a5b2be429786d44c4ebacf611040000": "0x92070ebf24c4c84a47db97b62d308834c3f258a9d96aafd6bd11eca52bd6ce4b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f88827e4b5f71ca9f5f34a638e60512752040000": "0xa459850c4accf690b03ee38b0d0b4e312ec1005f58f2f761b01d77c00514ec0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f91786aecd3995bf5fd3a6183973193b51d6b5": "0x00f87ce4f60900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d47297cdcf36eed17305d6a5471c6cd482c7e91c": "0x00be4216aa73bb000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890b4de57c216b2bb92151828a9335856f54bab03f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899e538fc87abe6b95622e5af0d60906350fbe2280": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890048d77cd53479c2e9594d55f058a224041c11ce": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0e741e91998cee7bdfd13bb0c48ec23fb8c1f60": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0d243a2e86fd76e56fd99cde8bb928ce3d140f8": "0x00ba1ae7383a03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006dbb368da30eeda3c789408a6162512e75a788": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e659b900949f70623fda99c695dbd27e9cd9e7fb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ed53f7c273f524da37f189e800b9bb66ec9ea26d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518a96acc0ec56d30ea248b651266f128403080000": "0xc838f3c7b8b9223bd1f08b47d800ac5daa9d6b32f2e8faf4f16555c816ac4f2200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928995e1a959df4af4ac693c2de538b4b0de14592423": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b6d80523162d2d4f2f026e427516057966070000": "0x76817c2ac6b91279539b83574f5d22009a2bb2f37fad4f0ffc8355e69bc59a6c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700746df19d71232f9e5acc79bffda2745b69b97c": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004547158d12daf5a188c111543b87aaa3aafb92": "0x0086985bd4a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975623284ba17d06a852e3c74b6b3ef1509a13b65d": "0x00c6c5932b7300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d42efa2e57a813989da4bac4551e4010ee45003fc3f360f5202a958b2b1a29918": "0x0150dea99371e59d756012651a55cfe5e7a1299e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970059d48fa65e3440a352527e5c11627927751023": "0x0070720eac5800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec77c48e880d46812d3e9c6fc5e4f8858f51d94c": "0x006005ecb58e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6b8e05763ce13e81917c0cab8f724194abf57f2": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d4920fa9841558c97da4dbad60bfea2664f6cb9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d470122b2f8c87b9303d36a4d1a0c089234fa31": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b86a8cbd383f9a45c70ed742eb6edfa2e1aa8e9c": "0x008aa477502200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001adb13591f0a8ac80d152b8902b0a9e66aa599": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c5438aa39d5800ee70449975bb26d31c60792dc9": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e125a2395e88601ad81f6f77d32c9c3640020000": "0x16d28220f8e13c7e464056988a9788066cd6427d5100c773e7adbc4c08f97a5100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c50164ef29cfbff4685873ec8918fa2b5190b2": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009325dfeed3f384e863c57455ac3d3c4809d210": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd6e08fb25db746221175b2d50e9fdf7b227643a": "0x00cc8e03df9905000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfa9066b188cbf62e3b2a063e5ffe4b4f92f8e287b7bf5368fdff1a992bd52857": "0x4ba3b6302e0fd7fe3d21fe1d2ec3ccec915b505f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e2f4b428f4fcdc1a238a75b172a73c6fa788a1": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971508d705f64ce3810d54ed2ff5cc9fccb55a6942": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dac2f0e3d8c2bec6c5f11f6f5e99adb3e9f3b6ae": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e8523b608cd42fc15c1ec89738a62fcb9e5a76": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700daac3d76e6a2e0bda10600e5a6b0e044ea2117": "0x007a4984bfa700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d8f6cbb93e77cd917631c53ef7f1d3c6a9060000": "0x4863d8e858ecdcbe518244f1535ddbca677937bba3e813346bcc5b471f4e516800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892da865b913ce50451351a315d8b37cb87a4f4109": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894a9924ef83a357ec4c978a66ddddfe9cd325b0bd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002dc409f3938a24541ad2dbff32b8635f5af5e9": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a78aeb479d6738f5c0eb11870f1ee63f01070000": "0x3eed7d3fb7e8161ca57a6ed51a5175fe0537c71d89202ae75a286d9e78c26d1a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001e0d294383d5b4136476648acc8d04a6461ae3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f42003e7c19b429ca0f6b9f0f75ae6c08cec5463": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4863d8e858ecdcbe518244f1535ddbca677937bba3e813346bcc5b471f4e5168": "0x8dd535c62fe25e520fb4becc53d19d39f5d798c4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a69c42be4828dcffcba1bc8dd9bd10f5c3caf3": "0x002e50c0ad4000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975e4d95432c7d44feb173a155f31a7c65a1f13668": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b00ae1e677b27eee9955d632ff07a8590210b366": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700508808bce4e1d3d170cc4cedf616e759522144": "0x00e86151d60100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b31f557d9e0b8ebe6f6fa65d6bb6e8d774c794": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c9e9801b90518b2ec3197525805fe1994f020000": "0xfab20f6aac6679222f627da75051b3866b8a547686f676a73a906ef985c48c3800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700adae7292b68d8d92ded17f5c4f606bb90f6f5c": "0x003e8bb26e5b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002844ae6b76746980ce8bc65f409abe021582a9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975cd12fb4761f91f6a2bd4240c73e7d8fc8a3f638": "0x00406352bfc601000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e3bf929b3f1c271e62cc6d1f2882eda0e741f8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973a9b0cdab618a437cfbb3aff8fc8b22ea5188d70": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c1c6383e5fdee5909518f8fb94e23d9757334e": "0x008c0e73b14a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895f05bdfd076980a8884e37d1cf90bda6801cba37": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a34c6bcae6f46ac6470443ccea67d937f6060c7e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bd04211da0c403c48722220799e6253121080000": "0xb67d17f0067c5650930c4d4259ef7b5f7ee951af57f06cf6360b75b7a56e824e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339718be7c263f1de5d3c4e78105638ccc5cef8e7c9d": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397081c8e52338007010ab569afb8f1e098e645d3ec": "0x005880abe94f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768476977382d9cb85d11775b79252ee7d2859738": "0x000cbd89fe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1ed877f9fb8eed0ada11b8f3562e73b807cf65754a073388fd7bae9104b59d0c": "0xfe2ebe8b791bff2fe45927e9fcde8a5f9760e249", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b16993a0b0cebca447009fd302c7d085f4a3f3": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c6f2faaa16c7641c1adff6944452976ca1504976": "0x00d25b92b61f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900961f206d72118bcbb9685c1f642682c11902bd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890dc056cd15bc9857757eabee309f0412cc9c79e5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892392f61669f6e3b81a46d30210761c77b0ed35cd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970ae46dc2234842d01e72c6d688bc2e1c4b18a004": "0x00a05a8c338051000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514416e89eb4020b28249c78a7b1c295ac05030000": "0x04f8e9018e5d7471067ed148c3c91f980b6f713f6d921104bd17b33917a6336600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5640a67cb9a12ac09b8a79ce6c9bb3d8fdcde7d4ffb20797b27341fd6690806e": "0x00d43d052fcc727cb262971ea068d3f94f774935", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de879d14e74c8c5de8dbb00e01fa32b495c0f1fbc66b6b93bc31006f044293955": "0x61436deba951a9f929c5d7f5d9488204c2037aa2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970069c7b8173234a0b275d948db0a415a7b48091c": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a96e78d4900cb5f8c412c1437b15aaf81f6733": "0x001242a3973e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa879bda95576cdcb96a64406d1366b48ef57e33": "0x00d8a5ccb34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893e33c5c1f3a42e74eb61862584b27454a9a44a06": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c326c5ab988880f8fe6c1e17b97cfbea724a39cc": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d169679c4a927396e65263ed42c5bcf3a824cf1dfd03ef3dca2bdc0f3538e487b": "0x198a1bad80c2eac0fb986553955cfb5e30f464c7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895c5f66fc6dd672a91114e67edcde69ac17b2ebc8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a38edc99fbc7935f47a5047a757bd870a7f02640": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289af1ad6a98e5f53c3bb27509177ac3564b55703ff": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e5da2d78dbc9d7a047ac8700a09f4fb50a23d8c3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e96cfaccbc1ed061cad3ed70efd8dd74316a9b": "0x00865401b47f04000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977525af9498280da3fc2f5498c495e89561b8ee79": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d53ff1caf92232a43e8935260dd13dcf03bb4e6473df67213af77085e2948c08a": "0x1c8b8633670b06b418295c37ad8e9390c6f6ad72", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b505830ffd0059f9a3d98c1eebade1b8279a40e3": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243d0d62f0e012fd9cde4c2b255305228fd4a3160de": "0x00706f96a686020000000000000000008564160400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc7d085592f433e4523a2bc030842427b63ce31c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007e917588d7a1392c3604501e00a73565d06845": "0x0076aec8f5abb1000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005417c5ae560be9c83ad34e3f1cfbfde481ba61": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519d73b621f1a1ec7d00ee0f6d2eb055dc58050000": "0xda8564ba0f7e717dd8d61025823ef756b474d6a3f3e8099da01ce16b53d8515400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289247927ac71bdd4d795b6478286a7800064dae9d5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c6f954321a3029db46bacf497159628dba070000": "0xbe2ca6fbdbaa308accc6024e77ead45cf89e5318a8be6c85d52261c341377f2700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512c66dee0f51697b87529bfeb805ce09685070000": "0x4ecddc1c11402f03446a1bd87ca5232df46bd5db7f9a80537464b299d1bd8a0f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e48ce69a2366fe2f8c979b270c94c7cfac040000": "0x7afff4a998fecc10c07df0f46ace2a365517324289dd106c75005d1c5cccfd2100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ddcb32a75577e9a33c2af218bb8209e96f92627f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891f1dbf210d8bd9ba610071d284620c157cdfdf40": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001c23d4e5d6b3b797fe085fb0a3bafb7f758da9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900684c55baee983062a207cca3d8581c7a2c32ef": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892c840d94dcf091b87fd63db7eb0885d9ca4b5f79": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895dd5aa7a9b90b8ca0e608cfa2022281854490dcb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008af2eb1b57b4a591e08cd0dcb93b0b0978053f": "0x007a116602e800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b0fb7ee5554869bfb57d69836b005e00a942d7": "0x008062175ed158000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c14584ac76ee1a0c3d35d336f2448c65f1dbad7": "0x00523940c54600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d70fc94e4372b91e68eae0dbbff7d37a76308ad2c1260b27ca02a1dd4a17f7042": "0xa1c45f47adf9afd4df16500a4c213cf52af55f88", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5c914d49eef7110f4b178ade972bafcdf83f994": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f9c86dd81e7c9af956327767f5e9c5da7a3bdf21": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bf1c98cd754206368af6e2c36e0661454adb11": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397206c99512d5e7bbfb0d430813e23b7b9dc1b41be": "0x004203eec38a05000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd4dac0e43b7012fdaefc31e13762b80c909be0d0508eba2d22d03ad954786f7f": "0x0037b4f93292da122cee7227bbe94ebd9f2fe930", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891b289087ee4dd222cb003d5cf9d14e376502c7c7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928936921aa381ba281dcb6fb6489461c2cabb8c23db": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928966dbb95b55759347745b8580661c049dc211bff2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda91670ea8e3b7b52e7b221279ce9dfe7f97d1c836ba42202f59d245d1589c2d": "0x6d482c372545dcc163359bb181126befde763314", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928977c56ecfc21bf4bc66adae4898224b07a81b4efa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b10d4d83491e7be1f9451065c9dc5909b717a28c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bd22ff2d97e949911807c2f142d609ae40522cea": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb36f3d6b177c8acbd8dc9974cdb3cebfac4d31333c30865ff66c35c1bf898df5c5dd2924d3280e7201": "0x48b623941c2a4d41cf25ef495408690fc853f777192498c0922eab1e9df4f061d2419bc8835493ac89eb09d5985281f5dff4bc6c7a7ea988fd23af05f301580a3ccde029459535c8bda2aa6fc2d97af3880409010bbc05a15f8d42bce8f0176d3c7d33a7ca6e152bcceb20a75bf67dca553cfe1fa0546decfdab25177765ae078acc4f2aa64faa0c97ea1f8702fbdf1843694734eee4d7c65c5605c2f8127148", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d980761b3559eda50fdd683089d53060d8bb900c1a3935ce66f99f6392612b57f": "0xbe7f0d32ca1cfa5d95b4c10c960a088f2080a508", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977a47861cd4c65225b1e00284090503ce41023acf": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890138bd5b9fe5ee16cc0e0b0d63adc94a6ad7b21a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fcd8d9d843b3a5558a914eb74b0ee05e7da49f59": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514a3e7dfa35943bebf09756a6831b24f212080000": "0x7081542596adb05d6140c170ac479edf7cfd5aa35357590acfe5d11a804d944e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51849aa2f468a77c951039ffe1b08247313c030000": "0x0016292937846b8e0f933c667229d8b6765917b86dd19e0f6c32bdb4ab1a2e3400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899a36821b843a170995a145f3503400866bd69fe4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974287603500f11aa83802c4c02e2b5a9130ebe23a": "0x0006ae27a08d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f26719804c82085d861d13a0338d07967af11cfd": "0x0040222ec86a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897c53e4175affb6add29bedc688783c6dd9afc452": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c00bb75cbd8e55346d2fe041c632d5b6cb6f6c4": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e56be81797e2616b7d4c57c892dbecda35045fa1": "0x005a2d81a81d18000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9c159c7347f55c54a3e600e3e9781b9982f05ca871bdeace6b6775dca9eebd11": "0x006a1212d2d3e63753368cbb4116ed4bf3719e64", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ff636bfe534a97fa8adc9366aee821059b032d2": "0x00dcfef6301100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dda9c6a6ad458f966eb78979e4c7bf8557a89f71c221927e0efd1f5c8614e8154": "0xf1d5ca8c8cf354b8d5ee91f6ed61f20059ba4beb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397642a4f994bcbf6fea70c54ec416ed9de02f8e00c": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928980c503db92ae417099a025c49103b80e370ddae1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897eb9c6574928e51488595ce200904de622a212ec": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977a1206a0acb0a887986a5ec7c1899f96a68f6f18": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339719d1e23c329025f05bc9249d021fc59abb483254": "0x00ae6ec28fcd0e000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893d022562f644e3f88a3ce6bfce0afc0539d421e5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896812d2dbd83e65750a7db91ab8806972ce170be9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a9b5d50da09d57e940215c15f075139f7788cd38": "0x0072e669861100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb0d43ba23028b7db38d8d6e2e2fdb56db9c0302": "0x00d2a4642bb700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b2f4451bf599ec52cece0a8cf96d61f350d4ab20": "0x00665faa191700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b725ab758bf6d8834f562726af8535e720060000": "0x0ccf27ab564b31e8835ea23f48894d22b986382bae5889720c66225960dbd80a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786716e7f1b8a4ab2d72262ec5e034ff995b684bc": "0x00f8fb80fdbe00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e48fa43331d29570366a4244398aeb56756467cb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5e4dd79678be50fbf6aebb41dd0a4b6eb2412d28c481d09c0fd2dbb14beed619": "0x00538ad6845f3526e08a2d1bdda4ce56a6191ecf", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb37e5180a48cb71c0e3887050ecff59f58658b3df63a16d03a00f92890f1517f48c2f6ccd215e5450e": "0xdea6f4a727d3b2399275d6ee8817881f10597471dc1d27f144295ad6fb933c7afa3437b10f6e7af8f31362df3a179b991a8c56313d1bcd6307a4d0c734c1ae316a103df5c5131813fa77ba4f8be88b2d2b4a47323d2011c9d987615f067e9e7856f0bb1f6307e043be568014eb4062a9bca4a255f39ed0be9205ee97c93b4b6ee0a3e2de329a70e2763438a1a757bf6dab945dcaededc7455a7fcfae83def07b", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d88fc08d7997cf899274ea31d6e9f6c883483b95ed1d489575fb1523d42912517": "0x55ed1eae79078844675b794dee5902ab7304db79", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4d35cb41da50f320fb28123684440d99e450d24": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ad3e041b7b94a6ada8197b9bc9c554bc747d53c5b2779813597ab0939fe585f": "0x00a5d4145d389cca2ae8740dc2af3a06acf135e3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397040e5e95969b231eb8dbccf2bbe7b339588fde54": "0x0000c16ff28623000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc3a572c4d49eeabd53154a59779f7eb6da912a9": "0x00508df5952701000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289456209ca9fcf4dc8d276a659f6c37003555fd0ac": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515e105a4f48b4168658c5227deeebea5bf9050000": "0xa494377af81b9e491c444929c24ae96e88099a23c0e207aa130d2d1ae589765000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b0807cf08105020d06cbdec06fb549adcccf14e0": "0x00188d22dd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d68e72ac76f4f79fa9c7333504a6f19a01cbf28273ea2d34fbface9f8bf817e70": "0x72d8a23c70ec138734d5cde0fd9e3edad5102320", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928953972a2e0db345848a8fa288b902d1be01393ecb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896c5c5385fb7bebfc1fbe02db4b9c4df76e39941e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896aa251b33219bd6095ffcb9db692ce2abb203e43": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e13540ecee11b212e8b775dc8e71f374aae9b3f8": "0x00a2c3388eab0e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e793755ce4e93d29ae317ed885cfc65d45e98d9e": "0x004af6b3941c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1050436acc3c741a67ef38f329a01baaf317c24ef837ab6245e3c1531719692f": "0x65dd37ee6e2df4710af8229d4aa913ea6264ddb7", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d285f6f5fc6353dcab3853dae25cc92bb18a849fe7493b654338a3527d9d9da68": "0x00961f206d72118bcbb9685c1f642682c11902bd", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ff27838e63649d23e22c115e15e5a22ceb7a680": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289900a94e7b5ef122f71d1cede47deb4cf429cd10a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ab980e9f3b036a21ad11568aa020f6ffb407067": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006a0822d45e7a82220093d1abb1d595e05b1333": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b7a9b1c894620751312656b66c7dc2e333cfe677": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d1a80b1f8a44594e343b3d36806898616c3c123a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd834724ac202075b2125e21c88829469c79745d3615dad5ecfbc96c2b651ad17": "0x31b81404b826658f107997f2a9cf96e6fae6915d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c64f09d3a447e74cd8e8e769983c25c95d697714": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824303fee733b242749112fee4ff2bbf7f612dd607ed": "0x00901ec4bc160000000000000000000001cb240000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289462cc75caee4d0be283eeddbc2cd5698b9880b91": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289949b82dfc04558bc4d3ca033a1b194915a3a3bee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895c7975fa3b0e1ecc47baad4596626aa2c1089524": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928950d919314f2981bda224370b7165fde7bd733040": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708047a8561852b8d75e9ce66751a9e0ef4eb2ad3": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339766c6c69ee2c1b963f63710a599e7fb3508aa3e61": "0x009cc874400e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af44c1183aea35445f24b3b82073cc0afd007cf6": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900197a17c8ec9e02c852be37c127dcc004ea4eca": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1f206f7c890fea0cec8c819d1a9e302849fdc7b1d54e8385895155e1aa4490ea": "0xe96acc7d52abd264535e1a64a03a9fce3e238c77", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d99b6e4871d4235bc2dbcf58c6c1cca46ea8ad1f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899b35dbc596f545739e25e203b41823251acdee17": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3890fe49cc68cb8567fd01fcea08055b25b3cb1d8fd1c37f2896d3819ebffa1b": "0x99ce75400cd94e1277047d0913ba8e6921aa1637", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d583ea20f5dccc9c80dfd745123651bab91e560b74a672f2f2b3dc8f992346c49": "0x6b12c9b8714c27aad069301ad0bc4c0cc416f1e7", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700732c6677028393e3bd88433aa4c221e1d4bda2": "0x00c0ee56871300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df5aa870ca48f1dd80eeb75b80b7d2d797d74ca8": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972afd2c2904bac60f47e0a351c2fd66e12789c7e6": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4791e01db745246a89a9eb394227cabf8ab4e1c": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ab530a569015d1cb75ec21da05e00b943b903b22232d8e2d2c24245b5e3777d": "0xdfe344098825e1ac854d356926e44f303b7d08f2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e28833ecc493aa66477f04c932a4d689598910": "0x00ea85053c1200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792fafb4ba354108be7f0b76f5aa93e59b21288c5": "0x0098550f100200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51585b474dd5eba950a6ea9ed5b67c7f8c4e070000": "0xdaf5e24f1300e8f83b716baf3b1fedd62eab829ecba9592d373871dc1e9b8f6a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979193eaa11ee8101beb2f7c3c88a5df61a5114f98": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c7fb76d905102fbf68a981474bd26e5fa4427790": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f30aa1a2b965b6273414c69bcdbbcea76a52ff": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891098afe502a221d6d6687077daee2b5692faa9e5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510d6389aede1da18020ee7a90881dded296040000": "0xd0aed46706bbb3fd28d13bc698b81ef6aaa0cf78942879954835e3f8475f404400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5128606e12e34d3ea210070284ef80ca395a030000": "0x58771ce0f83cf6651fba0037541ec21a0afab196938a7ef3722769f24a38de5900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fad2f675a57f7709ce2d2f9215a560aa2d060000": "0xd6077b2cf2af58f058dce80e52283bb700ac5d2cf8a979fb6b8e6f4f90a0454400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bf8401e27fbb06066845b15be8c1b06e42b0e6": "0x00daf69b441c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798194b95e37bd6de019d5ac8fc416daed2091408": "0x008027461a740a010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c875b446639ca898f1b3addccd107b9e1e2f09d4": "0x00eca1ad533400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6c4d3830cec539bb01d5209b79ae4fcc5053bc2": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891fa6cdbeec8b0ae15c81a65c5da6d152a0a6c25e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700543f7424da419242560b6036cd8a21dfa01c52": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289994625b177e36e65a06118684707c19a62194586": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa0346f3edefd952f673a0e24ae4658c22a64743": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ab35e5fe5354151bccc15e6d219dcd23c2e868": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d74eef92e8a21aa5cf2507036407d59dd5070000": "0xf058d4c46a6efa9894fa49e07fa14d756b3934a65ce6592cf3ff441dd527db2e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d40145d31d0a4233efc8d72f2917e57d3af5631e01550629ea87570561fbcb952": "0x21fa2fd0d1126a88a7fcfae18f8fe849999a17ed", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae43c3cd9c3e320d03f5cf5ccc4eed0383c6b879bca35e8ccc7174f2147a2a17": "0x524db42cfa6386c5bd43229805ba087cc5d25438", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1924e3e6693420a5461039f1225c5cc765de4f0": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928999dfbf9a028384c05ea011e6279a4c1d18c782be": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824391f2376856197b8bb33ee86f56d4a17da7298859": "0x0000c52ebca2b100000000000000000030fb711f01000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899cb6247bf9e22da514b1b32acae28c560c73d848": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243004272a32a2ca68c679f25fcd14ef02cd7933a5a": "0x0040f09bbce1080000000000000000008f4c5f0e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d566e7d7d28c4566bf9c64bfc61e0bd122dcea4315c30a4db862e96634092446d": "0x04e38005b0c3a9e183c22ddaac3e074c689757de", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe2d3714dc0abc2fed9f148be5ed1f224793f01d": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5107f38a260a8942cac8323fda732df2cd77050000": "0x26f7f8e2427eed26b1844a1a5fe5cfcd9a9fd7038a0e9049552c71f2a244b22c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d52bab50114e81b832ea60de94e7bfb05dc831a309ddb04cbb1be5eaed217151a": "0x0036c76ec47dfc17a96b1a68893bf269e1c2875b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700cc6eb30b179245a98c456964fc577a5e302244": "0x00ae9f17c4be12000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006a8106e821a1b44cb0626f7fea5a951b11a282": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928930c083613ea607aa5c2d723ac9e2c6b0c032288f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a04a8b46187fc60ec1754b78c6489f8918941321": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a1504b9d2fa2a344ae27cf32d1ddef24ef6d46": "0x00aa0f2ad80700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700684acee25e34f5ea3b944a58c5e23f922c14b0": "0x00222837aa7d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970030122b94e0e0c56a5b04feb3ec224244a5b18c": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d422f2aadd599b4974e4cb9a5410f03159e5459fa81e8348f8746a8ad845b8306": "0x23803954be1a85583e00ed01ffc8d232edc87e1c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f44232ef2cc7a637513c492322271498bd4b915": "0x0044698ead0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289df370202f48a6858de8eab90afaa3ebe1c6bc63b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d60bd4d5a4a4b80c613ec911ea4b1a3066f040369ac2655c3dc63e6f9ea97822c": "0xb82ec69d0521ebd32f7d445188e5b6593ee49046", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dd1834278e89be66b9dc56f60516794298000000": "0x023f1505e3e54e2925d67915d720d12db1a32bcc04218ad713d75f5b543cbc5200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51271580cccd57e25ddaa956c1ef8960a2e0040000": "0x09cdcfe42bb7443b5f0d32c6e770f32b18b7ff9838f7015eb6083b5fdeb5cfdb00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bed32016ccb33d7ae3eb165cbf37c7d23e35da90": "0x00da72776c8d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900efcd61a32da40d230aac22bc0ebd026d8a9fcd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f129a8a4ef740ad545508a30068725c058375c4a": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243c89b9819ae522824ade6efe464d30f8e431cf904": "0x0080e03779c3110000000000000000001e99be1c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339708afb83c6ec32222be7277238e78b8b768f47ad7": "0x00203f885c017e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976256921fd93382ce2d468570f6bfb385e5bccf0f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890098a926dfd4c742a18bb91e0dd1196cab95f4b6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c8d2f03af9ee67f36463ef212e09137800e377": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339706d2ab1ed0c25b0629d277afd6fd928d232d41b2": "0x0028dda6111000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928938edb955024a69942471180dbaa3416006379f2b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009d14e5ef0bdaae60db17775e772dcd9e6130c6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce4e902b421071b4825e6c630d14614e6021f42806546f390d8b61c328d55073": "0xa7eac235c1800f3301e452f50a8df7a6f82f6192", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51aa4d3fdad0a740ecb010734cac7c532c30070000": "0x12d777258efa6c17819186568ee99a5bafd6d2ab4f707ebe15d843756ef4c07700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895d0eb611e8056e7061e0acdbc497eca0db4292af": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289745e0ddf824ef48ae3506f915facde8382d4501d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da24280ca3cec95cfa124e17a8f01f1dd287bf14df1937d9ed97c91e39ed5a252": "0x00994d4bbb81f3d3cf352edc8af739c878b78768", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ab2a3ec557a9fc596bef9c447637abef78f2bf36": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975641519cc28def80d631baa28b949f17a6a22ad1": "0x00bc04ffc76607000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc692c0ca48ca508dfe638774741a1f049f03f7799fffcf84c804d7f2a2645108": "0xecad80fa0ba008c28f47b446a99f7c401a24df80", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da033ebb41c70f7fe3525f62f6678ea6b8b986e2808c4e221b51c3cf42beb3df8": "0x470959f6872985a33b5f5ccd75bf2f8a407691af", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289df2bf630289bf17443c0eb89d5fdca0868eafa0a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008481aa634a6d406c0ab9ba67ab019f68ec7d45": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289450f4b99969a564bfe2388b52aa949a1c109b588": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cb1c7fb52c3267564a84e68a2db4daa791000000": "0x4ec51c4a049e6621ca891bc03533a9572b93165aeb4b9f00ee1625cc4ad7472a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d0c352dbc3f03762421093ac7225224cca2f54f9": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243847c5586665b81798aec196a3065cdc577a013dd": "0x00406352bfc6010000000000000000001ddcdf0200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a3cada9b1c35f6fcd1ac2d72afe68e92a8040000": "0xe4af1cfecc881925c64cbb34a528ee9b77805b0b357c8301996bb5d3b21da57e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890961081fdccbd287cc1045744a7c0b0222d70314": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891e1d15e2d670c63b9846789c38c28eac68755177": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c0a78ca841d922a4254e8957d62198a4425ef314": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970077f609a73630a90fdd05e6edb7ab0c99bf71f8": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c39eb735f8dbdf396c2749f298cba2bfd74cde": "0x00a81c90c74c00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fff3f1be70b67ce7363c08cb8966281354070000": "0x1af976180cd02a36b76a442a92af3bf89a15500a334d64271369d1b41639b47600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5ae32d080487ab45708d505c20edf8ff9f49213a0849b378f2e229bf603e7608": "0x286409bf413131c1bdb5c2ff95c5f8d7379c5162", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5197770ba428597b489660c31df381a8f7f3050000": "0xac58e10e4125165d840d53169e111a4e76487f930d7bda577583f6bbf6db513b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db48db47e2db5323dbfc4ad1fd358f731424b27a1d3a323eeb57702bf51589c1e": "0xcd03d9b87fc7a4669076fb8675021f04e4e8f9da", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891dc13ea429ed10d2ad98c5eb66d528e4875bf2c1": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243185d5cd827f66703890387d348a796cc8538d08e": "0x0040c1bda4a901000000000000000000c9c3b00200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892ba8649eceb83037c22cf1727ff5d47b9f666a5b": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243c77c440c06384717ad302a6c5290c9e8716f67c1": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d89384c4107f7d0feadb833e769e7e1396eaa5e4": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19507a177c265e93c51a706172618050e91d8b60377c58f1e8dfb6236dece92917f1b4ee67d2787ab090c5f8d2200f": "0x88ee494d719d68a18aade04903839ea37b6be99552ceceb530674b237afa9166", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243810cff23a588aadac06cd93b443a12fa3a78affc": "0x00008d49fd1a0700000000000000000073707f0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c6dd54d08d5e5db12d90baa03045e877095fa5a": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243729184154b516f6caafdc8ef2826809669a6e082": "0x00406352bfc6010000000000000000001ddcdf0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f9852f33e7b714fdcb0cc70fd2338923c5ee9c45": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518a4b46b256c6b33a8bdbd519b5adc481c7070000": "0x56137106658725f976ea2409e4a015d980c2cfafec7b57d1e4b7fe268cc35b2f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900de78cd0ddc98246466f7fffd6cd96ececf7430": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ece6fd032e4d674561246baffa8f92728955b6": "0x000a1e02571a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dec6b5880e87f3cb86eee445afd7ce299065f11b": "0x00e87648170000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289129631915a3ca10b9a159a7dc95bde0ba71682d3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289efcaae9ff64d2cd95b5249dcffe7faa0a0c0e44d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000f7b173834095ef9a8050828649ac394046818": "0x007c068aa30900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd68a0b50d9c1fa1644238aed53f0bf7b0926a143e1568fb13f1d9142f6c84d76": "0x00f1f605aa47e882d4c33a928fb1620881682ebd", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897a1e82a8554ccc29275f5cd010de3668578bbc9f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eaa0987ad748c033d01d71ddd87e2d5e1fd80e52": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c5b5f898ef9dfd2971c5fc2f145a4c05d762f2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894d1f0e7d6941ac51e65ffcfbe8f84db0ef919f55": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897f365db6236535b6f2cea032578637e82490c80d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ca0e74521dbefb81823ffb4807c78957fea21b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974fe56ab3bae1b0a44433458333c4b05a248f8241": "0x00f2d5e5975e15000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d00ee008cc4cb267e410a49854b34df4dd21ab2bb826cd7dc055fef773711b925": "0xc6b2e23616f4c246e2e0dfaa0485ac98be69725d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339704226cfa81b91131b31a7eebca8ca2d9677bf0de": "0x00920d70945f06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979fcf5f950cd5ff61ca37042f293113dcfec1ea5f": "0x009cebca242900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339749a4754c8d01ba67609c0ebd6569e18679d43abc": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d90592f98c1e649196327edc9212c1dde53cb8c8cb4ccbd7bbe360d0f2e401709": "0xf00098c1c1c81604a82b903cc34f91436e6a72ff", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ed825d6533c5220639bea97f98aeba7e02b0845f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976d8188d47b24e6d8061509b7915cc40d31cf4b8c": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c0ab889aa9583f67dd90116710079d7d2d94f3": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b73c916e56833aa4ef789ac94e78a0a5cae93c70": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea5d1906782ea18165f17d2b7cc97e996d9f08f9f35d7226505fa253892a4311": "0x86e3d8f8c1252600304047adec71785c41671bc2", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891fb5b702b7d3c5efb00630e8014e79bfbbf5ef81": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339705df79a1f08a459cd77ebbf6b3333da75dcb6141": "0x00828a13987702000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289051f77131b0ea6d149608021e06c7206317782cc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970055a15e869bb215e605335181284aee8be30a50": "0x00da602c785f20000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513b3dee7b6bad0e1e1f7d87ca172e08feb9060000": "0x60059d247f883ba83508ba33bc087e517824a5d405fe60542efe01f2d7db576700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d74f57b8c30f491524688bda45df9f49aeaf6b96b4c1a4aed06d777aaee605338": "0xebb3b5365f80f437d4be00fffaedec844b24ce14", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e7f5b9a284b1008acec688a28fd7b7080202359c": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971fc2d658b3346975cc5bd586efd5e7c26db8c98d": "0x00341c01bd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973e0c4d785244c2df4fb88b81b2ca0aa7411a6ec2": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d82e4431bca23b39a02f6131a04c65d0aac0ff3ed9e7d1ca880cee1d65ab82962": "0x6314bea21ac7c7c29127ac20b508ff8d430bdfbc", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707940d682e51fe3f01b2236d18aae7fae021a7e1": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976641a9a247811657a0c435567260eea47c3fc81a": "0x00421e33e0df01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c7dbc61cef6887665a6a2ee94e39c5f7e8030000": "0x3235f7d984058bb410c163fc1d7a90e5475c0917aad77deb241093a50b4f683f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339790947676a04a00d14056a9d1d428e24999f60f2c": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890b8cc90051abd0b9b33bd17121b899bb7a9d796e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928944f4c9eb38dbc24b17fadecb8033c24c70e7d836": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1d483bb4ab67995d0689ddb9104df604cc04178": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890088a951e10d2f4a7e9cb3a2fefb563fac33eb0e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a632b76ee5addaed733c1ecd6a207d8a98060000": "0xfc0d23727263d4adb6de5b630ef74983623192544a7d3c523211c46b2ffbfd7900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890098b09e215f5ffe356a13c6e1fa420209efefb1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd7c282b347e54ed214e842158c7c36c99cac70e": "0x00e03b8bd29400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbe2ca6fbdbaa308accc6024e77ead45cf89e5318a8be6c85d52261c341377f27": "0x458e55f31a66a01be0801221777d1127de93f6d4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899c6f2351c0d351af08be5f54ca624f1a12417531": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51453b6dc8ba5035474f86af7d04ed5e34c6080000": "0x48d307a492109a221d7237b1b3ab2026ab23810b16f8cab2c750aa9181984a7800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d28e3d3c413860766007043602a6d6921c324a873c736d96691a40c9d8ceb8d47": "0x007924aa5e2abb7a230caa625cc0f073f0ca61f4", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcec75028adfd5db7751930c7d9c79a0e660fa55a9cfe45030c0fbb8339021d1c": "0x55b3230118d3952b35b7965b09752dd299a95706", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397269f2df75c2f22db96592cad6ad5ce58bb85472b": "0x00ec226f1d3200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928909d7bc4d2ce5b5369c16b76f6c6297b1c711b832": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d321bad8be173fc114055f9aa77859f1befbf589718d9cc6dc4b801fd0e675c57": "0xd067ee646a21d8904fe24a5d1047cce91b34bdc9", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d76d8103a1098183b5518fd2c4aa0595379a6708d8bfc2ee6414963f307a83a2c": "0x185476974fb1f9346c90d0831778f958456bcd53", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b2e52e1a42c3ab5305f1b071ce7d197565e9bbb7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc65de6003709aa5a6b81354c00fb13e281ac05e852cb4194c69f78566e8ac828": "0x56be9656add1b07ddf587a25ca2ee79b5dded4e2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f36a2d00e9312041d71615ac5260dac69b2c44": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da0c2802ba380d41dcc343cbf730e65bb198929288d6577799e9056014079bc71": "0x6afe9576ad00a571d9c04402006414ae45a8a490", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892ed99752dabb3138a911c2b71c9a80c7fc917614": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e96acc7d52abd264535e1a64a03a9fce3e238c77": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e56da5dcaeafaccb73e526f3afac2f48cd0136ae": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3bbb30d00284df9abc29e5601e34965df641199": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d5ce12a848bb0d982d8a07ae5c462f5e9a7199": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397861bdc02d79dd2598d829fcba91e11f1d26b0aa0": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339781594a7163a447cb1ac16ddb7f831dc1c43f9307": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897c33a725229490756ac021941021ea509853ff7d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b68bbc3e20ee753a024a480dea125bb69262abb4": "0x00fa7c33951000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899c0c36cb561beb841efcfc7212710d0c7b1bb187": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897cca361415fbf12722397c47e063a4952ad65bc0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ae3e8a291096b596d36cd4f6fcb3edcbaf50e673": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700aec6e482d2ec9cedf8f03072ff8bd27850e95c": "0x003eac4f5ab600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ba2b48d35573cd15a89057fc6aa79f58945c36": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970967e2492eb0f8a7bec3979df99088fad360d62f": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512de2af1be289e17743e11cce0667ab71c4050000": "0x2252a1d50d94240bd4e5b32ef5c118d59e864a8add6e2d30fcff53b939f08a1000000000000000000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0ff3ae12770bea2e48d9bde7385e7a25f": "0x0000000002000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a13d980cb2bedb03cacb7003143e7af78c602030": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b593edd7cba746ca27bca29de492b3cdaae2b3fa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bf2c5698312de5417c17d2f7a0e7d8404a1ba62b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289802b450c936ab1849243267995dc9aa45f234a48": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b40d5c17aab371a6ed5ac622ea232b590f2a31b": "0x002c07fd6a5500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339776211ee383d28be255a7a44de4a5e641a7d88e93": "0x00e094fb1eaa02000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513bf4b0a79776148bc186d7f1ea414894c3080000": "0xf2bfe9a0d14bca7ebc7d681f805ab905e882778d398dd991f61dce22d1bea24c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba9d129d178bb0d08689948da60b5517ac35b89b": "0x005806d2931003000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cdbe5c54d75ea03526b2241a1d79329805ac23bf": "0x00749ddfb21500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977a78aa44b5660cc42e0941782a278c510f17cfe7": "0x000870a05e8800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900aaf196cedfe640591c2d0eb4b06cc2c746697f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fae39043b8698caa4f1417659b00737fa19b8ecc": "0x00aabbe1098600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ad1626660dc56812b6798a4960b02662e2e7b70b": "0x00808bd33a30b5000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0e6de68b13b82479fbe988ab9ecb16bad446b67b993cdd9198cd41c7c6259c49": "0xf993f7ba557bde7f6f8c49c7d53d2b0d6dc87361", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ba3494fe956dfdb34a70964c62c613ec1c9d1750": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b7d3dfb87fc35055dcb7d292d3bdc430496380": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900aa4c31db8fcf894fcc3499b2ebcf3e4eeb8842": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900598748134c87ab7e0e4de09dcb4c060fd73591": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928930aeeadd2dad9c66d74ca5c6b52d9d8d3d1b8ed3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d13c361e67f4124aeb0913a21299ccf21c040000": "0xb01917ef7ef9823b455ceb5295211968ff32f415d7feaaafbb6facce258ab11700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c95d852b78d3be6f3df2c1448f023ff3ee4f51": "0x00e0fa29790900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976a8666af2e42ebaae251383d5d96bfe80e41b4e2": "0x006296e5511600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289081754b0a1468f7ee643f1ff9896174ddc6fb4b1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f6fe74155a9b6733a8ac7b3836e38927d7a761b0": "0x00782fcb050a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928950ed8729f9b9cf868b12785094dcd61b4e37fcd9": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5e58b984496c06c4668dc371110f5c0052d826627fea35dbf7dd9254d719665b": "0x0f465f7ce5a1e26c402177194653c12e7222f127", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397211f8d4e57db34f5a7476771ab52ef4e407666e7": "0x00a031a95fe300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890014bcad7b114436044a783d787e18f947fc8bae": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5149f67d3af4fcb13c553835d6179182d5b4070000": "0x6a2484979a9f60423218a17095a44c4db2f17f2db386017faa64bd92724a1e7d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ca0e74521dbefb81823ffb4807c78957fea21b": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b0c94ae3d19f2c585b920842211d2d8430da691f": "0x00148b66da2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510767cc84745b3ae53765b376724b3f071f090000": "0x28a3dba187141f0d7d9af3d921cfc738e52f07aeb3eb5b7814bf0912fe672a2200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db40b9e0fbd4e819b9a56f1e7e7768e7d68f35220f086a80165e38037f391894d": "0xe09656727d41176c0b8987f684450af02eda1466", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ce8a0915d27d4d3295e8b67c593d3423f371ce7d": "0x0098224f9b6720000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282430023772fedf1a43256e6ae4c227b6dc05989f814": "0x0010fc266f380200000000000000000024d3970300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4a991fd5f82d736df9ceee054511249b89f9a4d": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005d79be124e0852482eea03f11c3ce1eab68805": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001e14757da7169f07fe225c2afad22e69eb93cb": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002a66b507752653dd0468eac677ce6063b58701": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243f619a00f641e82037048c9d0cd20f9b64c664fc0": "0x0090dd1e04f1000000000000000000007601860100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5137579c440e2ffab0da172d4e932ae5b030080000": "0x39e54a89f737272fc97f2a35b25e9bb5b0265a2d78749965aee5c0986e4c23ec00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5186cd2bd11f207ea82fe99aedeb87fe81ed050000": "0x5205f3382194a16e9f1e95e9dada0ca5b5f44e5f35cb257c054a5b072ab2515100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397622f1c8146096564ed842e48b498c08fb298b4b8": "0x00ac55c0712600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f365db6236535b6f2cea032578637e82490c80d": "0x00c003a59b5901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792fb25e8d9fa70512c5709c401274d1e6a441f6d": "0x005a64433e8800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007cd4fdb6a94978efcb1997af675dd6e4bbe1d1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898ce6c2909b2bbe2f6a5bb8df2f37568668d22663": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae7976297df7e47f83d7166c1dc7c5170c45574aa384519a0bbd549479bb9139": "0x445fca1e2473f0c47938979ee2cb469aca9d36b6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c17b6f24cf566e25bb33302da671b658577c1373": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d84372f8b7fefa198c90e3ec77d5b062e0467b32": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e403233a64dd902a5cd50e83c5a08b7896875ee8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892de237a350c65bf399bf853a3cc6bffd23b21917": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890007e5053a12e40bc320f2be221a71b0bb72300c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d04518c742860d637765b48a16338b84661cde437e1668aea0867bb9d42724a2c": "0xdffb703dc6c44e62c195bbbcd9c7fdbf45f5a133", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a32ad2c6d4d5ce0b978e4e0e955e02abbb70ca": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a04068a84913bf3db84f450a82588801197e028": "0x004465738fcf01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004337ca7ef0391b38f913689626697307aece2b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700063eccd46e37c80e52b55e9ff2912afd8d99bb": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928961fe11633c0fd8d3c9392b777c0996254e5368cd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892317fedd4b4af7c3b6fd14cd044a2acc92ff15a0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890036ec309c318597ab5e273d535c6cf2b4ecb98e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768f67e0a9c4a93ea99f820c1b4fb86dad5a27883": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b16993a0b0cebca447009fd302c7d085f4a3f3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970011dadd05ec7515e18f0bb50ad1918198ea2b5b": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a79e6221d11f5f98254fb956a38a55076f83d0e": "0x001c0e1d160200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d04c895bdb4bde0c4f6d3cdd1d2d6483e5a8a946": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008fc7cbadffbd0d7fe44f8dfd60a79d721a1c9c": "0x00a65f83e67f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890025c20580d7ce0b8996c9bc91f5935dc031f3ad": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397afab97a2147313fa873dbcfaf175aa1f24c8cbbb": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ba381e968d5a797f0d93e5f3705bc2a98d8734": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd460ce63649068b38c00c88f2b5b451e105f6e217cbe19c6a274819887379e63": "0xba3494fe956dfdb34a70964c62c613ec1c9d1750", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890021381df55f5e10059831b97653c52d42a1e137": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517433f95259db00ac1562af449c06bbb4d4070000": "0x2861549f4eded2d6aa490a7a313e0108aeac7c17bb63ad2b99f815d725311e3300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f57e50a2ea8f652c4166eff8ce217baa204e7f17": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5138b2c90054cd79e4a16921d60df28c9e78070000": "0x4a1d7eb798b449b44466ddc54525343cce18396743aa708d1ec25f870e37cf7100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d22ed1a4911800562bedf94162f45f4b3ed383ff35defc9586c6861105e501945": "0xf82fb4366eb81322a5e8ba8b6281d04c32b3d631", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc85b0daca47936a407193940ba2ab7414970818": "0x005039278c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd766dc1c0441f9b06691d3b19ff1d150b839e7d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c5464af38cf465bee0a30d7ddccd900cc20ab9": "0x002a535b914203000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b3c2a4ce7ce57a74371b7e3dae8f3393229c2aac": "0x01", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195045087148dc2aec4770617261803c7d33a7ca6e152bcceb20a75bf67dca553cfe1fa0546decfdab25177765ae07": "0xdc9974cdb3cebfac4d31333c30865ff66c35c1bf898df5c5dd2924d3280e7201", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515f58dd9bc2f6a98b04433713439ea55a44070000": "0xb445e27228291560a790171804710c389df4ef28b65f83848d63db5fc77cd34300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff83a6d7418c73bb7fc1cb245d8aca979295316c": "0x001a1d06994200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890ae2f976301c5afec7ec28494b91471c1c2f1093": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c88fa499e7561e464292a8a3c76f4f0351101bea": "0x00bc04ffc76607000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f91786aecd3995bf5fd3a6183973193b51d6b5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339756b8729ffcc28c4bb5718c94261543477a4eb4e5": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339783730c5d67dc5740a2ced307a2612e4a337dc46e": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da800e44b2b342ef986a4e96fa2f2b49f57ba47851db3a54e915295d148c8180b": "0x4ccf6ed5fb4b037e92aa2b61cb1239fc6572d0c6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899604602d57c5ad85c36b8bc59394086b5f18e7b4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973b271c43635a5ff2be9b8ce704bdc3ec1cd199a1": "0x0026f61e763a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d908a2a6b07c69278da04e238eb396d240e9818b9e3ad11545bac463a4cb3be1a": "0x2d05ccdd7d7481f71eef6aeb4e0527ad47753272", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890019012e00e460970f1d39925494ec20a2dbd50b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e06a8d603b1151b6e88a82a4ce53e6e8b985b5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c76c643a4c56e4d7f45d3e8a9166340c5e787d3": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e7465a8034887a0004d4ed2c4219c2f5c22cb114": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e88b871f4d3c16b385ddff8370f6730b9b74c38b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d01fe71aa1b2188725a4a1d197f8032c27f75f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d147703aab4af61ad1df86d783df7e3c6d67e5974445e770e9f751733b07f5849": "0x5f3f007a415cd23b2275e689b088cc0ff0f0b1b1", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a8c4badcf003bc07e1096c9c1cda2bab98080000": "0x9a34338cb3f82de1fca9185285d30a075745505390d3a898066eb280cc44ba7300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ca0db0283dbf8d123602a2ec334ab5c3fd9e2540577e0955eaec679cefa4f0a": "0x3799d6c8dfad3c6cac7d4ea9430458503bd9d4e9", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9a58c667ab381990c1070fae2940bff21a5af23ebf4313e745aec82172773315": "0x6df24f6685a62f791ba337bf3ff67e91f3d4bc3a", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ea2376acee36454341f0a626cde932000a591da9b5cb385b5fdafaf077b2425": "0xc49830add09b7b13758537fa4e8db73fa5fd4bb4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339777c2a982679c5d64e845eeb58f59af38459578b6": "0x005ebeb2030a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009fe4c8eda6664669ee264c1db5f831d4af2f5f": "0x001662710c0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000989f1b22b2b2ce40d680a388f9033bc8fa704": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894c9520bc4a39e7ba4108d2794b5ef7727c78d34e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006c8616a98ff7b6fd6302ffe44a18348df5b3fc": "0x00f424648f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db6583b354dfc9f39075200ac364392bed6c5d409ef63f8b8698e7aa14b9b1469": "0x13d8779df2c88e622175dc24f8bd2b53c562e631", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397088e9ad1f2411247868395d0b0a6279d92bf12f3": "0x004a5eddc34200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974bf278ff22a98e2ec520472ee271da5586d4ac12": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c771ceb58b220cb663c2a77b37558cde21c471ee": "0x007ece841f8c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f882d59de84b2bbe5a37dea30d6156abc2624301": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d33aae1defd629dba3d3d9c225b1274788127318": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e10f34493e884232f2847c6da66773e51ec1731b": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f8a9aa97618c77fad4be22fba26d4ea0507119c": "0x00600b6776ab01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d920bbd35a0a98f20c6eac5857ffd316b80963": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea63a7e85bbf2cb582c90d97d8f78170ba7743a5": "0x002c490fd71c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7c3c0e9543220809e9207ece95c504006574f50c42361068e846dc51f7e44c71": "0x00fe2716ed876e1a4243333758d547131a98490a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928906d6ee9ea1c648071973cde4669d95955d496422": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928925b28e2fbab8ce0b5d54ac6968369d6a9f1e2197": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289520ad81a6359835797a4a7b0b0cfd0406a18f64c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289da25fceeab53dd6644261c4723907ee3bf1b8229": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b2bedc981445a47fd58cb9814b8c11699093df": "0x00b808f1f31800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511f91410fd0202db2270b1e13d6b0988cc8050000": "0x1a286c553f1c240de8df6b45d223c3eaa7bba7c29379cc6c634975a48c17503c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b55cb6edcc8c9cca3b659007d1abec171bf75ea4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1e7981c2d131ff111fe1449faef19ae71ab9bffefc3c43f1a1938b287f47b060": "0x00b59ac37bc3e2ae0f9d32b6751e516eccb38732", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2945102218ec28141fd0be4fa57b11ffbb0bf25a6732f2aa68fb70653321b66b": "0x00fa9ed378e8bc649df332605415e5a9f3cea779", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e8fc0738b7450ebf2b496cd15652b1805346be72": "0x00dc023837a403000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928960e04fa14b8faf0d3d7b1844e8535eb156814b3f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cdd4f0d8d858b122c56d54a8a719d7c76e4db0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289af302aa751058797c6ab5249cb83547a6357763a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d9459cc85e78e0336adb349eabf257dbaf9d5a2b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289daec98c63f553f059c024da69f7becc810f8ca0c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b2656fd04da0b96fce05f2adf02e751a14090000": "0xfce03157d8e323968680f92bb8e16e468e35613b5e9645d56b736c1fcbcad72d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722a0105994c3f4ad8c3e78144e47a6eff9976377": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e17fbc2389061940e39af6db317b48ab56d2a33": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f2478f49dc3dc086605e6b5a8dc1d8a8d415c876": "0x000017a775606a010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c9234f3b6117260ff6de428e15b943b387a6d4a7": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289200b6591326cca7daf74d4b6a5789824040d5660": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a74a375a7abfdc2a836a1ad3987caa82aac2e79": "0x004c44f1ae0b00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518fe5fd6356ededc90b893927da844408c7050000": "0x48d8c75ee8b4de67c25eac76659690f8c11b3ff23eaf348b89a2e13e8598ad1400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3c7927e2b4364f8ea6745336ee77f9a77bda0e4dbe2354d3c4b9328817505a7a": "0x5bb96900d055aa4b3de73bd195c49400237fe7f2", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd2610d42a7cc342bdfac6abb2efc488ca51c5685a3cef97ffbf3614a98ecd03b": "0x69ff7706b367405d95890cba4d905a9f040cd467", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a41d48673da40f5343bc1e871eb360ad8b9bdff": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4add2e79c9cb1b479a22a663f7f25e53f63ee7d": "0x00b27651350000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928951cd0cb94cf5bce38ae16c1a0df2af1fafc991e2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007589e0ef0ead23d975d47e48eda004c90b14a6": "0x009c3a04d74c10000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970150dea99371e59d756012651a55cfe5e7a1299e": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974c2d79f8483b8fa0b0026d39db21dd51d90021d9": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f82fb4366eb81322a5e8ba8b6281d04c32b3d631": "0x00a26a5406f200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006ff6c79e263c3d58e9718ca0f08540d46d0db2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928901a7d9fa7d0eb1185c67e54da83c2e75db69e39f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b3bcea099c64a01d1a3d1a6b78198c69a0070000": "0x42804d00b39843601a505a8bc5f29dd23e9ed0256aca3cf207a7c9005c6bd74600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006c1983fccaf096caaee155ce27a6bcafe640bf": "0x00a234c7d60300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d98fa099942b9179688793b146505935d64def65": "0x0026da6a887d25000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e302eb54d1c41647ee0eecea4d5b7dd90dac8ddd": "0x0044135e7e6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cc6eb30b179245a98c456964fc577a5e302244": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d268ecd67d92c521327a5dcd19d0e0ed4191367afc90c726911311d404626fb21": "0x00d920bbd35a0a98f20c6eac5857ffd316b80963", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a0f3bc2c0168cb1ddf914d803e996996ba080000": "0x6e66021e4bc573a1cd11450b9adde832cafc9e7e83fd3c4901c3e0d0f078900900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd68b9347a3c6c5a16919f86d7d7e822f0b7d797361fcfc03338f5c18b6c7cf23": "0x1bbd9ddc49fd2d67462d0b1919151ec9aa45fc4b", + "0x2099d7f109d6e535fb000bba623fd4409f99a2ce711f3a31b2fc05604c93f179": "0x18e0a3e2de329a70e2763438a1a757bf6dab945dcaededc7455a7fcfae83def07b8acc4f2aa64faa0c97ea1f8702fbdf1843694734eee4d7c65c5605c2f812714814f13a09505d4014b468c1d3e394002832d9edc35dbbae1a7a6dc96025d47d5b74b919094e1fca66ed767766aa0a91025b6a8b955bb970912900ad4e413ea9360a7d2ed5da6a62c32ef4477bef2a1ba05c5feea57ebd44516a8257dcf9a3b67b4c0831fc73ca4ae4d46cf82e74ad01549973d132795c579d40eed490cbb01524", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700abe816d32a0ff056a4a9cbf7c9eab2b550a2e4": "0x00c41afa0e9000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004547158d12daf5a188c111543b87aaa3aafb92": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cd0699b4667af672f71ea4e589d9d2c29ca992": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891feed555363e3ec72086c6f347b1b8f67d869333": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928952c7f3fb2a8bdc8f2d9cdc9404b5779108d4ea0c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004e0fc93058997aaba684c4b3e9b5549a736fcb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ed5b940de6f21fcc6d1168cb78590f9ab6cd2ba6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397663e2ead665b23089266bed606d492ddfafa5ff7": "0x00c07ed6adf901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977ff48b76335074baa82f4236dc673b6c56a8a703": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0ab9981f21acbcca729868d221baa118155602912ee0f3cc7014a38d2ac14a71": "0xf65fe2f2d8215e4dfdaf150b031259ece9998f8a", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5155b19dbc37f2b2b113eb82ffda03dfe936070000": "0xb8a3477a6ca9f9545ded0272a812d70c23b1267c8a7d0a077aef540b1d06087a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c0e0da2990dd5c3933b13cc49264c206e62b474": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5128fa8df454e4ccb47c7b699b56b0167dc3060000": "0x0ab9981f21acbcca729868d221baa118155602912ee0f3cc7014a38d2ac14a7100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f32137a894b2f46f186846da0bcfa57941060000": "0xb227d24a97cba787bde41e45897f6cf34822e210d475862df1a62710a661e13e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ccdecb6fb16e73a9311e57c75beef3487b3a0b08": "0x00e4dbdcc51000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1efb42259f19cb4fd06aa4ceada857028a371af88868bd3bd88808ffc5a0747c": "0xb4624dca7c8be0b12e1f883cd5a64da42ee200e7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289225f3e472c48e708915cb4b24a3091f22fda52eb": "0x01", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e83613e4f90a971a43ee9cf36a45e16314050000": "0x7a9749cfb7256e7e48edca7a6911018861ec6e26d9eb2c81bbf037628fefcf0400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798b6371f584b45a302d9f09e8741c4f0e4526bfa": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df67048f1edb9b4c247c24e8b69219024581aa0d3aa509fbf8567199e2acf247a": "0x5a65b40f6e9bd80597482769f6bf1e09d49a5634", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894f26a98109d0e971370b72be7857f44a822a4651": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928986ec1830e985a7f8b3c7cebfa6c86774f9b347b9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b2c52e1aeb3340a166c483297a70f1ec3d0cd160": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b8cea24ecc961f20fd7ea6332915c9ae85521f1b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51da8f51905dd52f35565093792d9ed99097070000": "0xf6bf5945bd3abe20c1cded2b4250a87c47a13726ea2dee57f8a56920ef53d61300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700648e430be595e8293d447699e00f383da18abe": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513abf7d994adca5773bacd203e8dbfa19d6050000": "0xc0e4f5e8f715c5e6acbb2f15742f021693ecd39501613dfdc93a85c1cd77582e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bbeda4a55beb07bcb912a7e5ac6f477703090000": "0x4aadcb14243c81ea0785494a25185106c5dc1ee5a56078ae95603f2f2aaaa15300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289298679f84e404ac8a9c73158ee6fa4973eca9abd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c154d6a5f53e66085ce1d7c26f23aeb6d6b18ac": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397befc4249d323465b36830ee666c6df935904da3d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df4dff459b93832e9bd6e0c32e5866126ecc434a": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700aa7d705eaf0a79ef8f0eb9b8c4b80b885205ea": "0x00fc8d0e800000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d12847802c9c373e96c9f5a0d7ac75a43c080000": "0xfdb612d1816c094e2d7bd3d957b76444c172c761fdf19df2f31d63917926e34e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891739e6e25e3da9107b7f60145dd2c8cbb76fc139": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928930b943dd80ec2729942b65aed370835bff04bfec": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700554019bc1d942aef1cbf7ee6becdab99ca91d7": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e18eb8520947679c4780bae0abb06e6a219b8df7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973d5b125732ab8687d607772cae3a63dc5784ce87": "0x00321a5ef36b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d4c9ffc5680b9492c9fe7201b972190cd51c0d3": "0x00", + "0x3a6772616e6470615f617574686f726974696573": "0x0118dea6f4a727d3b2399275d6ee8817881f10597471dc1d27f144295ad6fb933c7a010000000000000048b623941c2a4d41cf25ef495408690fc853f777192498c0922eab1e9df4f0610100000000000000f72daf2e560e4f0f22fb5cbb04ad1d7fee850aab238fd014c178769e7e3a9b8401000000000000001c151c11cb72334d26d70769e3af7bbff3801a4e2dca2b09b7cce0af8dd813070100000000000000680d278213f908658a49a1025a7f466c197e8fb6fabb5e62220a7bd75f860cab01000000000000008e59368700ea89e2bf8922cc9e4b86d6651d1c689a0d57813f9768dbaadecf710100000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d08d3cd80270b7fcb3d94ca800834890bd03f39d867a9fae9b7335de90e9a576a": "0x14ff1233fa526a1c2a67640f637ffb1bce5df502", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5157ea7f0b431b3b3548859f5cd19e5d3485080000": "0xb6e1b1e9deea63d87810cc9d86bb759d26666a54086a9b650d91d95c59e3a8de00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970038aa4c51581fb226d7a515c038de9796f41fff": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003997d4a7cc30410836ab9003f96afe1f6feb50": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928916eb8921f75fd6761fe5cc90674bd9c69d05d1ea": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000a0f7d5a3ba578fd3438cbccae3d3c722702c9": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893ba7149b3bc64c6f805d02017a0d71e89362de64": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db2751ab0acae482c9785925ea091b999ecb9cf62c8cd2b1a8ad582a90a52b317": "0x034e104e2767228cc99fb3aa5af22db30c428b12", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896e4b9fc84af5b73f2d99d036273766f211d9d6b6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974a522a059291f53b8ffee8b90b72a1223b6dac46": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893a6d927022815090c856377c74b4128f1fb114cb": "0x01", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d380ffa0d99a6519e0ab4d8a08c2d60ff5a8c7762c79e148ae6ee899170010044": "0xffda559dc06f88b229af02fdc41a5a6a48127aa1", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5102a1d41ce52b9e33eabda47327d6536db6070000": "0x761a4086e686fb60b17943b03eca939e82fa2d1e4f9d6a9cbad22578d12be27400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928966f1c634f11355c3dee9015852dff6e65dbbf49c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5154e15702851dda1fa23b1049974a2c9afd060000": "0x2021456d5c848daa658b302a50a0a682e78f24599a6fc4b224621cfb9f00a95300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397beb910ae193dc54411747ac236e67d221ff3f1d7": "0x00bc15a98b8f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d92070ebf24c4c84a47db97b62d308834c3f258a9d96aafd6bd11eca52bd6ce4b": "0x462891ac9ea16c799f864e308c7e73829faafc02", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9fa413d7d329f4217ff3b4713843b6ef8f64c2ad1d769db015187dda34a7ca00": "0x8049419a99016123ed264ca39436a91c35c7fe2a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003c0f01ebe0f29488c629e253dcd4cb9f1cc586": "0x00a65c64378900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700510782b5d5bf4c408ad8a18c4cb7eaaaf592d0": "0x007e15ac953900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51835acde82e1d88b6f34b6d6bd258fecd12050000": "0xe648126c1f38e729968541f3a55390e13ebf3b076c8ea1509e378eec2594286d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51751d32bc127d8e3c50f180d3bb9e42f7c0020000": "0x7e96c1b891441afa759d3b9f5576f58ddff074f49f65059f410a4b4b9bad883700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d48ff48391b63229dc9407669fb7973389cf9a9b6fb3afc5d3b39e3ac8da7f9e9": "0x1476d4c5204269665dac82770a8cfa80cb4ee953", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700de8cecef8b9fa5dcad5ec62ec22d635e8d95bf": "0x00301a45ba2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510607bbf0bf1209ac4aef8d665dd16a9925070000": "0xd401d71bf90863a159beb23026bf2c0d14bbd504ae240640a17a16e9c4849d7f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890007186e9b4a6d02ba04e7b7504173a64814387d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007c0b89085282ce1cdba3bbf12e1228547275d4": "0x000673b4ce1200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970084125bebeaa11df85ac05d8da15c2ad150e814": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce23da48a54f65a3dcd3d16bb18a99d44a25cd096954fba3ae2ef973cf706e58": "0x213de3994517a65ef92c7ad4ec9b824dcccc67f5", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339723f9313f69cc340859fdd8afd5d69f9298fd295d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970086eb4edda94678c1d7894533072af28e6b0faa": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cb55ab5cdb7797b8a44a76c4d923701985df4d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dec0b26473a8566bcb2220ef71791a54381860591c9293f4d51d49f4015025c58": "0x65ad859676e14ccafd371f0e5b5841d1ed014cf5", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928923fc17c723c870ec4bf48e71135a4446986b5d0d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004c54887f268bb0e5ed906f779d6ac081c11660": "0x006e7f7b980800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892702f707de88382ba6cf64a6341d089514341a5b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515f698fe716ed0d54b6e91e8064057ebb34070000": "0xc80d34e8174bf6910e23f6dc3b132a0cff6fbcaeaefa2bf588db3c8e11e3f65300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f36a2d00e9312041d71615ac5260dac69b2c44": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289668dbd6154064e193ab693a4f79bbbd06e107741": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897db1094c1006eb7c057cde290791334ee99e4754": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000c10b4afef8d4c640ae287e75dd71c427cb0e0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b5d47ed8c07fe4d9a143fddf967ca8d66562beb3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e10f34493e884232f2847c6da66773e51ec1731b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899c3668049cc8c0e75c32ec8bad06421c3bd26281": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c8ac080a57b99bdc0f1a66d24064113b8bc5f728": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970073ab4feb184e95b514c03103fa4d0409df140a": "0x00d4238d32a200000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cdf9afacb0a46405d9b985aad3dadbaf3c000000": "0x42a0955465512b8f6e3afa33bad2036803c4786825097a6a7b81f289bd1c520100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397638a66644872aef9572ad260b0b353d4a860b45d": "0x00c029f73d5405000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a48bda48cdcbdd257fa55b7b7985a1ba61d9e1f3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895f3f007a415cd23b2275e689b088cc0ff0f0b1b1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf36912f45c463b51d4b90aceea2727d18e0e2ed": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243ff3592363b611cd701ccfa565dff6d1de23dfb2e": "0x00a031a95fe3000000000000000000000eee6f0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970027be158b9f1dc432577577d225f0520c309696": "0x005e9fc7130400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282433e0c4d785244c2df4fb88b81b2ca0aa7411a6ec2": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928929955c36088322a44d55f597eb63a7f60af639d3": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970044603a9c1b3e99918dc373a07dcdfedf38bdca": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ee03095cfa46cab6e89cdf19dc2cdc64fc76d2": "0x00f6b7082a7e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289af50942a6552333a69f736a00aaf7d5f57e764e1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289810cff23a588aadac06cd93b443a12fa3a78affc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f613cbfe3c3552aa32bd23cc820b811b666007e3": "0x00aae20ead3e00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512cb9d0de12ef65062d8262f04b7adad97d010000": "0x1e713a22e920a812dc7179926fd698289ad66bbba84c982851ddcaaeb26e075800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a42e82c8cb31068b240772ec69685ffc59b7fd11": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f06b9faa0d5b71935682f53b6ec711158a8e9b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f374deac1b5daf9d8f703189f1eec12bd80295a0": "0x00c07c9e760300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005a9309489cc3231adee672e986e79d7dd1acd9": "0x0050a95c091900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b6ec7549a425fb0bfb24c1652c119a3d37050000": "0x8aa7eef9275f5b5230173bf9392682ebaede3cebca4f7acad4e383b8f172723f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003ca16bd227028787da3cf107e86b4c78fcb8c3": "0x00daf338368b00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519cabf0e6f7aa0084163c0c9f32ffa9df51020000": "0xdefd71969bd8c3999920e2e07a671cf76f502b08341a0bef1a4669d3affe205a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e326e81577ca673de641881b5d997528ee246f20": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974fe992e566f8a28248acc4cb401b7ffd7df959b0": "0x00868bdcab1f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339774ebb92f67bd7a62e95e8129177921c2808b1070": "0x00c8a697cf0676020000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397742aa56043ed0dcf2673279f39b7dfe2abaf3610": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974aa9324f187b1005e43892e3fe65bc9c78bb8d8a": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b0b0d02d246dadb22f40133c2fb0fcf738b3337c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e7848bedb58a722316a55a845fea16b34cea5e5b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890069bf728cdbeb783ee8adb4801db3721f94f1ca": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890b86ef72b38f189bbf18a94bc46c044b73ea807a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892fce155ddf214a56eb2e88939f2a48afb4b751c6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d86857505f3b297b65414126f02183450b040000": "0x88d74924b788c1f7ec64a54c63eccaddca748f588f67c26e5595870acecd925900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890013aa2fb5ec916660b38f1d53d4fc9bf8ef8a84": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289663e2ead665b23089266bed606d492ddfafa5ff7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289775d8bb769448c20a545c582088db5bff3751e84": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971c5142225c7e26732a7ea83d3b25c826d8637556": "0x00009573c24800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730c083613ea607aa5c2d723ac9e2c6b0c032288f": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339769c575e3d825fed93c07195a802b6f77de4f5226": "0x0042b095ed0700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e064b904dfb30bdd37886efb20bb328a6b5b4a6c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511b3e756f1b7013ab97b0631e560dda1880070000": "0x1afc89af3de835961ef0c698e6dfb77ab5de39e040d90944febdc47941600f4800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d5faa7afe93789d42c8193c01d67a25478d1f1": "0x006c054ca75702000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d84882d133a24d5f846dbb25597744a99f71327ecc0dd6a9e6ed54fdfd3fd173e": "0x7735e8af95538d6b436e3f63db0233b46f23aa08", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928940f8fc59e380b53808df1bd1c4e0e2674186dfab": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fa6ab66fa1e479c1873ce0c8ea5c1261d778e6": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970098b09e215f5ffe356a13c6e1fa420209efefb1": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289709e8bdba7a7ca0bf99a138cb2a1d3e84b91c753": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928999cf1375f2c178bfc895cd207ebb142621e8b8ef": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d177586539eb325c70e15b369e1f8510bbd3cf44": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d96b238d8b52668f90c36ad34ec02572133c9f234ca8983e33fbacab88345243c": "0x4209c9ea64fb4fa437eb950b3839a43c99d96c06", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ad406dc68cfab9920f00f2c5dfff89650d05929": "0x00ca3777b19c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977c838d644d5b60a023afed7497c311fa78175a6d": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d847ccc12910274a556bd06371c25a54bb922c447c8dae6c8818d86579e494a71": "0x60256530d074465406df460b6f38424ab5df6bed", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bc09b4284743f45d2c07926caaeaffa1bb4b6d46": "0x0000c52ebca2b1000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f3826a238beb074eae1d6c2a42cd3c63e2fc9147": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512b1d74ca63638b94de95a2c5f8b5f9e52e080000": "0xa2bba0c19b621759defe85c49e74d41dc70d6cac1138553207a8c921b6db705b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c8050f5ff8d448a5f3ac9e092f45f5ebb9df9de": "0x00526255c91800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ab416fe30d58afe5d9454c7fce7f830bcc750356": "0x00c87a6ad0cf02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928907d1920e45d63344fd7b9a3de9befd133e61e081": "0x01", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d885a263f335b180210364cc9de22b23cfcd1c90792971a82fca0980952a87219": "0x86821570ee3ec4bfaa2e2ffbbf16ee4f61336dc7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892658a833b04556526cbd6b2caab0a9fada7d8977": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511d9ea318921d67fa137fd2b1fe29855de4030000": "0x7a1878a2deff652de8f84322fbc6f3116e643c65ba2bac59244e64c91382ba4e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890098e8aaf2dc065865e68baad8c60fb2d9787179": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d2eb8b578ae98447fcb32a4f6b68c45058635ab": "0x00dce0e4be3500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003b3575e3870ff8d5dc6114539250b359194aa2": "0x0040f09bbce108000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289335c0552eb130f3dfbe6efcb4d2895aed1e9938b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e63bdf498cc6781799cc23953e32dce295a95a0f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339777603bf4ae686fae678f2b2591a3487dc68599b5": "0x00487ddee25f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928996f0aa4251eb879290d36ae975c57a59f2a5472f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700de0911e577096ba2d8e3f2d5ec0458b1d24830": "0x00d4c710ab4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289822b1f91970e2a6a2b4a72b75c3aa890d9b1fad8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895b53d322d505c0b8f76e745023c7d69845d663b4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339758a9d04522df5a3c7e1af52192b89d9c952b338d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928973361bd483cc76d6d0681065e6ddb25e84ca96df": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397383f42b5de515c564641f65f5da3bd8b4a35b4b4": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e448f88bdd86658308994de3c90a473f04abb4d4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006ef813cd8eab68641cd6fb8d5f3b8126abb5ba": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b7680dba45cb6fd6ae148cc8b30963667d386d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c2fd6608ee68a808f73f06d7b09cc036ea080000": "0xd63e66ba8c5af8b64993b764f71aa50a4b0f112d87f49015031b8378f8ce2d6a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519df9701da88a234e107d455bb8261f94c4080000": "0x6816dca78be4303480a42b848fef6ffc01e4189a5ec4aee433543b0381c3a51e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9e40ca7bd1fd588ca534ee6b96a65ca8a53ec232dda838cc3cd2bd1887904906": "0x11bc2c7ea454e083cea1186239abc83733200e78", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eb0718ce75762eeba4570943d5b2de2afb9085b6": "0x000e760ff72301000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900892b067f072e1f337b367c9a8d9ea968d4419d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517ad99cb9b0f07f70415e6af2b71d66a3ef000000": "0xaed7efec80092410d5bbf134d29e673e1592e2b95bb7fc24f84d5121344c2c2900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970087df4a94ed0637178dff912b20e01ace2dc9d3": "0x009c7912141900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c431b755d5b1ccd238d5b8470b35afa2591474e": "0x00fe2d45b7a603000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977738dd4955693f16822925a3cc9fde3f94e13e32": "0x007829c1894d02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700538ad6845f3526e08a2d1bdda4ce56a6191ecf": "0x00d8b10d918100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5192ddcc9d32b0009dfc1332d9a2684783cc000000": "0xda61c824abfb1e5df1140697374346be4443e41fd1e6ec99c22f2cf3381eb82e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc4e4ff6adcb360ec9eb50d5e04ad47aec66a30055222dc13c6215b5f2db59767": "0xaba13ff6c070ac900ca4e3861ef66045be42b37b", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d09e3d208f737d92bd55e3cc348094b24e60d223f7bbe266a49d7f87e727118dc": "0x048109448c4730ac047abe0097034754cc9f0dc8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339735895e864b6a7b88db055924e01de9e030c42020": "0x004eff6c020700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e260e35f88bb3d71ff842178649c2817dbf50c04": "0x0016c10c435a01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dffb703dc6c44e62c195bbbcd9c7fdbf45f5a133": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d09cdd094e9a51d26bbc6cbb71d3f7c5b8edde629402e3e5370e7f6904512fc4a": "0xde5eea1691af15296ab6474d161ea8a4ab5f86f6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c687a26242033da5caffa1ef62a293c930a3dc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970961081fdccbd287cc1045744a7c0b0222d70314": "0x0042224efe1700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891508d705f64ce3810d54ed2ff5cc9fccb55a6942": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397128bef3c7b002090dd018677f551a865595a19d1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289687f956a18fd757f21ff2c1f0334c589a6bd4d1b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512ee83da91122462c4264a5c79a17968caf010000": "0xc44cba2747fcc1dfdc75f1ad38fbb13fc2ea072cc3855f7db2a52f9e5dd5080e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289123843545fb525c8e134c9a5f15ada6865cc3848": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c09c648b43dacc11c63f053c95beed79c3e7fb31": "0x00be6c373c2000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ad4551742f5718e0af5d88119974c86efc8b83bb": "0x007e84c4358901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973637f645f8bdb74e1cd1b28b5afc64c4a29c1f1b": "0x0040ac6893f800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005ecb236707b6e0e75bbe9fb034528668ad21a3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c4a025dc1068a02a63ca49aed9ffadb1d249a1f5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d313f089755915750761bfbec433d1389a080000": "0xa0dd8643134d45dc348125039356a3d2f9d785235a057a20476de704a088396b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f30a1481febb1a1e6ebde2942c58a284eb060000": "0x2436d28eba2d9eb5a342e5fc9a2de9b2070f4a20ecca3dfdcbc83fdb0d19923600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51867a7fd6cece4c57eb6c2e7ffe3936e831000000": "0xc2fc92e6992a16358fcc7a4d816f46056c0f6d231c33d8cc2def79cde45d226a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5cba75ed8675adb79470d814cf37fa72d13b8df12ea9651a7e65f6bd526bfd48": "0x7b40d5c17aab371a6ed5ac622ea232b590f2a31b", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d76a6b80847d39f2242188ab8488af63177db6cc02d15808fddf18668e2d6bc25": "0x9dedc7bf7fbcfc0d48964cd9977337b944e177e1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a09c71abc6ddcfeb38b68eef7d236d0f4b94c11d": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891f9aa698b3781ea29878036773a0df87f5325d98": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289088cca87b0d829b35efeb6934ff807cd3befc48b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c5ce26469794d196f16f4b83422bdae40f610dd8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006a0822d45e7a82220093d1abb1d595e05b1333": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006b0c951ffdbd1e139bb4734001e5bb38590533": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518f077e8a37488e9e93ea41e00ba310d01e080000": "0x8a2086278ce66471ae2b31bccc818095eda142f95bb13339ce5e8fe7c459961800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d5f1a7ad414f764f51f339126c2bf0e5a2070000": "0xd47637eb6578f4f2017e7dafba599a2829b73980e13e3e5f17b3a2081b9abf0700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339722a71133e0a9514145b5ea4ce0b874a9afd596fb": "0x00c408874aa601000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b4513bc7f383d9f27e8c9d2b16216328927f1669": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974ae4f357871171a3c3e10586ff545acd8e165618": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009715b79dcb53d3fff43ed82c11b2cef7088730": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517c7d10893b30c28cd726fc75f103fb6233080000": "0x8b3219495b480547011e7eb4c773b6b1778077195169a4e5fb16ce6b553b9b0c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f6a9a82ba882ede0fb2e2e8608d01f0250080000": "0x885e9172fadfb8cbdb532c65d07078a2c9c150bc3ded165da437268b1cf3afe100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824346db544038c59b826dda8d3cc8b72de90c86e683": "0x00b0ff5367f3050000000000000000006021a10900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db4f1d6715086ecf1c0f4f46320455faec20ca76cd7dac4151427b212c5021964": "0xe3bbc9586ef4c2baa9cc995fc50dfa7118d35dad", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000f7e4679bd941ca16000210130b66329e28845": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c231dc7e55ec4b6e33ea3ea6d77d88917d879781": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5138013074731c3cfe675e57d793d494743d050000": "0x0a49c0914f127ebf3bf1364ab5a351479d32700fd8b73bc2d6a94cc38176b53900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006e1c09312f5397c46089a6f95fd0424523eab7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339793677d3d013f091f772e54e6e50f26204de7db79": "0x006e525970d400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008211ed672526f479a537039766a8d8daf809f7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a777a85e56f533ee46eb6de0825678efcec56f": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894c2d79f8483b8fa0b0026d39db21dd51d90021d9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890d48af0a9782bce4b43ce6864a1c9e32e5f47c6c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970085ebc8d2dda15b907c3b43e5f6cdb17849b98b": "0x005a9010a19f05000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894d300b561ea06abe10d38ad05319e5d2ea641802": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0f3ca995aadd1438b56bd795335a723114ae98e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d62bac995e1409297460e9ba42a01bba4c01e2740fcaea01950402ee0a51f8022": "0x00dd82457a6fb1ea688d0fa4a2a2151368619403", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519017d1c733ec2aeaa6fd0230614e397e2a000000": "0x48454b0387f763dcf46291236ddfe846ef6466aba368f75aec3bb84b65b39f6600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d682736f965078d3b99638dcdaa574b2f9cdbd60f5a0e0a4c6082496687260d50": "0x456ec4d3265a0e2c8566728f819737a8c4a9872e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9aad9414088708b92ec181c612190b68da9d63cdc7a62f1d0c6ed9f568471224": "0x76211ee383d28be255a7a44de4a5e641a7d88e93", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e20357f4f128753e6fc6de0e6ac51e897d2ba9": "0x00bc082a630800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bc493b051f40fb47625edb508d1a43509ef0e3a6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5137e2e05d860ed55cad9f31ab1e373f1650090000": "0xd657f17319e754644e239fae0cdf743468637219cfd0e3847bb0ab967980523400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282430063d8aa6c33d88963ee4176bdcbd65ece06cc13": "0x0000c16ff286230000000000000000003d327d3900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339789379ecb3d84d69e1b18075d89e864bea36c9b10": "0x00d8d7433fd006000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006bc93719aef20a0258f9371a725b576c046148": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513285e7ce799a85ea0356ac073d6348b9ef040000": "0xaee72821ca00e62304e4f0d858122a65b87c8df4f0eae224ae064b951d39f61000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d48d8c75ee8b4de67c25eac76659690f8c11b3ff23eaf348b89a2e13e8598ad14": "0x22a35cbb6356055d8216a36af746c58bcfb99566", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004bc0521cf3e6289217adc9ab50722a3d2f6849": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005e42814cdf3db319923b257a0e0a48e3ee5350": "0x006af59b273877000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005e5c04f113b7ca7c62a331be999bff4f0ec44d": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928991f2376856197b8bb33ee86f56d4a17da7298859": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339737c5bf8acb3140f17819ecb4dccbf2e66dff9ec6": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e7465a8034887a0004d4ed2c4219c2f5c22cb114": "0x0010a5d4e80000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c4f2ac5ef5a2dcfd221f9ee1bd559802cf060000": "0x62b5214b6ee02f9e2596ba869ce0d3e27d8a5580072163a12f6294f3587bcb0100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da69c4536ec42bf8f3b60198d7b78be15ad9a147ed73f25164474fc61af261a53": "0x0084e0ea2823277102b3701b0b29d974c29e5e3f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005ce603c14ee8349fadd8888ff87d53d93fd43c": "0x00f660a1ac0500000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9008091e2d1fb20e6d6a46c0d66591c9b00b73ea42386c0897dfdd5327c15531": "0x075c5fec47d39bd6482df2cfe32a6d1f83b722b8", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973137346f506a2d980e1b00a5ff4801ce702448fe": "0x00c26f318a5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003997d4a7cc30410836ab9003f96afe1f6feb50": "0x000a8552081600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339728cd36b7b86b3d6a8d53f0332fc3563489aee858": "0x0020034cf68f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397abf9eedde255d9fb1047d2f63970faf7637ce68d": "0x00d616f8da0300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975113c12e12427747e73b87b76bc524124acb69d2": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e2d8cd482efb93b788cff519bcbf5e25dca333be": "0x003ece57dbec23000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa72f6b0d74e9843b68cbba5e8d622d055f7a4e6dd196b421a67f23baf05a841": "0x351a7dffbe4b4eba06a0b583c970c4f83e89835c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a8bdc33dd6ee3520995675c15083ad8db68de8bc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928916b278ad48a9fb2a18f099c210ef742479fce983": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d5e9ea82cabbb9fc6b0485d31b5fd5bf97431d": "0x008c2a02902a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894036ce05f4b3f7254541e9f50f56247cccafc14e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517c2577007a6bbd7c254a2653f03646a0ee060000": "0x90ebf0971459d3c56b434d4a20257625893fd27ad1bd423739d918976adaf86600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8bcdee6b78af63f0ce1c8b97bb7199b8172a10b": "0x009c4d06cc3e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928924a9f3b7757a2f30e5171009f067bb906f9a8e67": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db8362c2fbae2707b54b90ca0e28b7bc4bb25e81159931d9ac85cc75c20a9e161": "0x088cca87b0d829b35efeb6934ff807cd3befc48b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970024f96565d874463a46684d2f276318793049e5": "0x00d86d7f8e2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928940d0a40a05c43ce715932731f2ae3f6b0fbcfbab": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e2ccc768dbf601ace5bfb82591e59297993dc9ef": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339709f8eb817bed2df18ed680c9c310b9ea75c2a488": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339743c8ec1ace6c4b36e88ea5b6388c20ff3f13b19c": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890099fedd81ce071a859bc98a84b7bfdfc52f4242": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eaa0987ad748c033d01d71ddd87e2d5e1fd80e52": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893ffe3083861f58aa0101453a61fd3a1b747d2b75": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aa879bda95576cdcb96a64406d1366b48ef57e33": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518c167783904fbc5bc6801b7fb6cbe29845010000": "0x420c638c444c31f43e678d1f1565f1c40c3d2319de8096fd24ecde1be227ff2400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5153639babc51111bf412889c90be2cd620d040000": "0x8af773cc899e6beafdf0f125cda8cc0b24b253fb2d856db1297c8bd01d76211200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289497acc237dab7e7f944a8b1acdf9f56288bddf13": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc81a4baa6265095f1081b86633e628677325b8f7ce821d1a44492e05b017577f": "0x68a85a879380543b48c40d0620e0681300a88553", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009f4a65c06d5fb189b88f998eb9cd5e88f16708": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a1b28877a75798bed7c923d042a8bee3753aa796": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979e420616cf7f23f48fd442e11cbb1f36e37546f1": "0x00da25696b3a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8284b7cc1e21c463fbe2e309c8cda79827620863b9a26a7445c9daceae91a778": "0x5b53d322d505c0b8f76e745023c7d69845d663b4", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d82e5bbeee29a5fc8ec9513dfe2089ac32387a0d72dd85990a887f9e4ad890855": "0x07b8ae7d128d58f51815d99b751c0dd9b6cf2d44", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700002f21194993a750972574e2d82ce8c95078a6": "0x00d639e9f10000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c8a7cd13c25d7237e4e957074e70bc3985920f21": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d0108a019eee1442d3b864276739f6824a460331": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dec6b5880e87f3cb86eee445afd7ce299065f11b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971020df9da65f804831fa334e16befbac20599a33": "0x0082377cd53497000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bc36c18295814233a70dc57b69d96ea3a2050000": "0x06489613133c162307321143c102143da96dd6309bcc1ba2ff7f1b53f429843300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bdb3924fc91e02130cde47545865b618eeb5e1d4": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19508d6237c8d786801061756469804c0831fc73ca4ae4d46cf82e74ad01549973d132795c579d40eed490cbb01524": "0xe240d12c7ad07bb0e7785ee6837095ddeebb7aef84d6ed7ea87da197805b343a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928985ac9e682995ebebde8ff107fbbbfe7c40992e4a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007924aa5e2abb7a230caa625cc0f073f0ca61f4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fcae7970392f510a985a7eaccd3820b7759d65d9": "0x00fad415c00000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002c5f1d2459a12bd296be7ebc652e9c7d1bf2c0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289970a3182ec4dbe8115a001c5abf6f5383cfd6c6c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518936df98834c9124023f8f439f2a71ffef020000": "0xf8999d6c00d5014ef989664191dd131f18fee4d5b3341637baae3a9925a3ce2500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ae39db49af9e2dec759ad1647fdadefb7184399": "0x005827a658e00f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b73c916e56833aa4ef789ac94e78a0a5cae93c70": "0x00ea6c66a4cf00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51be5cc1288ab067e2d64733e29375c27a2d000000": "0x76acdf6617c513da01555e0f83863ca8d44226e977f8ee5a243565193cdde01200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d0108a019eee1442d3b864276739f6824a460331": "0x00a2a8027b0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289142f4db6d6e603f4c5990723c9376300edc964a5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899e420616cf7f23f48fd442e11cbb1f36e37546f1": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515b3b42c2ab41b914ac211031ab233cba84050000": "0x507b544916be600bd033d37e659e090467d1cdd29bf9dcfab11e1a8eb7b4c67b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f7a7256c303a22b718380a600f75193626090000": "0x74d422ddfaf5c928d04f719fe7f218e9de21d83f5fd0e7cf66fa20a3c2a72d2b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700443dd96337e1a0de0d5b909ca680f00af85f45": "0x00e898be808500000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6cabd36a1a0833f843b41221a584ee3396ac4df33712dd8b96f6a5f0babe4158": "0x008a15ba6eb9104f34001a142a0b57e0008d8e07", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003ef653b996a653d41d4ed315b3209f44bcce9d": "0x007629af4d7601000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900567685d0b24e7a550e84ec66adc6fa91c35208": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f928e604b981ca97463d9bbd06d84ebb5c87ef4": "0x002046fdcb6951010000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6c29577335bfd3cbe0df3daf35919a30761a13580aa72d1d3fe8003e2fc1a443": "0x004d1fe43ac70412e62d8186e8e0cb261d6c602b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339731369166ee8d31fce7b69d3231e42245b117c9bd": "0x00404c948b3203000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cef45cadd1e590c243490ad0c0fb9bd0a47d07c3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898a44f67e79908d52a5d81bf30cd063a481eb528f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ee0a93db77fb6741be11c337e2edfe00233b0c19": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000e229e2cccd3c40cc7d3182ac72fde71122213": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900818158c1ebf72ff7d3a2feb70735d99a5c674b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009f9a431fe97b71e157c50043f770cd5db2558f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900afef101ad493ac1da15395eeb0c84cb8a2a0cf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900daac3d76e6a2e0bda10600e5a6b0e044ea2117": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fcae7970392f510a985a7eaccd3820b7759d65d9": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950a0284e9a010ca7d7696d6f6e803ccde029459535c8bda2aa6fc2d97af3880409010bbc05a15f8d42bce8f0176d": "0xdc9974cdb3cebfac4d31333c30865ff66c35c1bf898df5c5dd2924d3280e7201", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972ee824bf2fad9d0e360bdccd74c2b5d3f634b9c2": "0x00702964a2af00000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcaea07de2b8f010516dca3f7ef52f7ac5a": "0x040000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0af9641145b68970bf6f3904732bd7740d57be1": "0x00d6c280a42800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289106d77aa34d1fedbcdf0cfc17d140745aa5c2626": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289185d5cd827f66703890387d348a796cc8538d08e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289202c3ba79b184884973405abf8b7d3d65cf73f3f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289729184154b516f6caafdc8ef2826809669a6e082": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bb2da6e051604740d95273c51180219056d3e70c": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289386c6c6a0df3ebf66b64cb34c6f8834b9711a2e1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289522325d3c47c84ff0a86fae37bd4f62a703d5b42": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c9f778ebffa282838000bdab016dfa08f75dd445": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928979af82bbb0552f8ad0192f4a7638dfbe8be00908": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397008dd1b21dad14a42715a406f36abc940ebf0287": "0x009e3f8afc9f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899f6bee6899ccd70cf776107ca787cd88dcca0b37": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289edf039c36c3fc977c8830d68d75d989d42ed1827": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d467023bb6cdf712422c34498a5143b0c7f9d3e92e336d5e8c7bfd1da7f119473": "0x1c00e0743d704094b1d198076a33a33487e2d38c", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517a0c5c512b9fa2847953b22cc6ff649867070000": "0x72f7dd3a2e7a78481494856d4ecae073b7fe731495cc78c9b100a2775f59881b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518b8d16cb92be342e132493c0a271a6415d040000": "0xb80268054c501c008024aee44a8d5462f59464ade23dde004291254683496a6600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431ad661fe9878af3b77754710f50981c82549bda8": "0x00009573c24800000000000000000000d1bc750000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da6d16d544f5994d2de0c8064d38f2df418f943595629ee6a2ba8df7a25f23803": "0xcb2b6f2f316f419c8bbaf441ea94e47a2193f7e2", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d96d7699bc59f8b6fc9be2be5f6ef506b63c7e10b8d751a73513694b601aced4c": "0x8e6365a5dad54ec79a5411b6a8100d6b25f155b8", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df8750a008794352b2a7533510bfd2fdc2f2ebb55e343d2dfc4c1bebdd0b89878": "0x5b650393b228dfb785b07f149fb213d691e49b33", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976bf95319e992a3ea48071692bb0553b173fd7d34": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc1162ef65ff4c434e986880d325a2705cc64b37": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004e1ef7504fcd7d982885efd88d190d3179fcc3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eed251dbde2ca8d330a978ccbfe4758294a096c7": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f59fbfe6c2cba95173d69b4b0b00e09c76501fc": "0x007ef91cb75900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977e5684f9a6f43932992d720d52b378fadb376732": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890029dc8d8ef8c287ad395732dbe5d5bf951da820": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008fc7cbadffbd0d7fe44f8dfd60a79d721a1c9c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c699ed7a9354ebbcc89529f88b67802e6f35a337": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d023bd0c9a21b2c69bff060f85fdee8b2a2e2908": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51623245c1c45601313c2fa273b5eed76cc9050000": "0x8a14f3b22fd8bb376d4639aaa8011bd8aa0bc34a5fa83d91e11a07bf83a1613e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8c7856350e309384b519c873fb20d4393fe42085ef1a2f2c260a14eac8045973": "0x001c23d4e5d6b3b797fe085fb0a3bafb7f758da9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978803cd717982cbf4036d0ecd1925f13c09a11a51": "0x00805cec442900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae77fe3329cb18cbb61840793fa16d02319cca0da4ffc3fec7f1a50fbfc1e91f": "0x99fb6c13d95f1b74e77778fc86b98ffb30cfb929", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a738917e17968c22c3ae246a69df2f64fea012ac": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890b7b02c9a7f9b6444ef6e54384a5b5feb6b36be5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970019012e00e460970f1d39925494ec20a2dbd50b": "0x0068d9d7873402000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707d1920e45d63344fd7b9a3de9befd133e61e081": "0x00202e585d3783000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700477bcf4c48a8c4814ace55160c0ab89ddc9795": "0x00888bf5e46100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700169602c4e4f14ba7adabe3c3829b6115e244e4": "0x0090bc88150100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4cfea3e89b8563274d1cdb191bd0d5de97de790821a6d41990f7671db2ae9108": "0x5e0e7a5ca7fd2b638cb8e544d9188dfc38385db3", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd69e158003222f6d68e25d9f39e881c74c2a833a6f048b854f79a03eec996e40": "0xe228a4c62c1abced2b55ca9af8b08b1cf0ae4988", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e825b93af6a21bc084f8f21d59398daeaf2ecd1": "0x00f424648f0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d045e79ff7d87b7fc35c70bec29501fbbc28203": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975dc41b5662cf58ebfe9cef62d58c2c11a9863428": "0x0066fa41c93400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a5fe200655224ca4109e8bc0b29ccbbc1e1269b0": "0x009ea646782400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900cfc49da98153ce90639fa4e327f1516f98cc6e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900467243b6d8312a68f35ca037c0428d52ed8aaf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895bec595767bf447fb61edddc723765f241de1dc4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289719e57b6d5969fdbc9b35bf76153dee9d09e2536": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519c655964ae84dbace8d02d40a7fd744696070000": "0x2251fc8e7977546c82b7bd4bfc3383601436d5ef3cf7a3060859bebc05a9a04600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339717e7adf544b8c6ab81cfd449f4154d14a61b2b29": "0x00706f96a68602000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974aa8f04de40456cfde9e606f9f066f399bfa4aa2": "0x00425a2f59a800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d8cb03d06e50b85644026da3e510f15e39e65efd": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895d930f5838e8f0a2e2db62535d767bdbb5da7ce4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289903e339fcd2bff1d25c91e1bc0d2b46fe71dc1d2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ad1ad5f214271d037176bec3f90fb4448ee56399": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339776436bdf4f3b3b9abfa08f825d2db471a4e33507": "0x000892b8f75a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700388e518f2aac5b12485f3e2dafa9aa8262945e": "0x00204a736c3d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928901c08575d845acf2bdd1df6b449afebe9e8910cf": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de02806109b735d8f9144819353a1db3dec1a4e9d44abfcd6ce67180c02e4ac2a": "0x0023d732d511a5d2cb335d824655f29daa85be26", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d89384c4107f7d0feadb833e769e7e1396eaa5e4": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009580bb9bb318dac9a5b0b3607491c858c45aed": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397456209ca9fcf4dc8d276a659f6c37003555fd0ac": "0x0010a5d4e80000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007ce39c82c2cf3d1d4e5890abdd3bb51567e469": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008235374c2b0a0fadd61c6bbdde2b9983af91f4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397800819914cb399e8eba6cc9f026066fae96e4ff1": "0x005650f3083000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900760e131413c57cf00d098dc27ee53f0fc3a7ff": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289da2bf8e3c90f7250c9db68d9566f40350380149f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928911efc885eda7ddde9c1c77f2946737796ef06e3f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bb73fa15563f569a813a78d9a4f714b9aa020000": "0x74242c09e3519ed1c34ec0a846ccd0509227c4b23e5cfa42b7a84d75a0ba7a5300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a3befe0f30e5fafbe6f9d79d6a3e3a382c060000": "0xf69a73bcfc9996e432faaeca61f336deaab5ce773dc236161ce08bc852df7e0c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002a6b8504b4aa93bf79f1c8bff1fed68c591380": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289393774d01e81a2fa93affad6e3f75a86a569f11e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bc7d1910bc4424aed7eddf5e5a008931625c28": "0x00142a8aecdf01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c49830add09b7b13758537fa4e8db73fa5fd4bb4": "0x00301a45ba2900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518ff8402f59bd3a3cab5b4ebc092939f5b2070000": "0xd60888e982105f5cf40568c5ef03aa875becf1e4dd57c42c2623943feb128c2600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1489a65848401b2fca29f84ca8041af9ec1e8bc08d79469d95554d9c59cbc659": "0x98b6371f584b45a302d9f09e8741c4f0e4526bfa", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975c498cfbae903fcd46bc6eddba138f78b96b7200": "0x00fa4c6f798806000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397456ec4d3265a0e2c8566728f819737a8c4a9872e": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4e3d772a967b139601c365d3804d88396b10b4ed8f7cd6d67d7ea6b46b2d5761": "0x31d04a32f22022ec66afe6c2351db768ed32b873", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e4c826e8a26d72cd784052b0a45f93a451a5e2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928928c42de479e57cc0c90b8a3eceb406dc173ad7cc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928987ccdf773a25a7036e7b95de5ec8fe74bf7121f6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c68bb853570f4d75a02e7f7c1a7bc179e62e830d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519450ccbdc1f3e3857b25ad39e99048788d060000": "0x6cf513881f519aa8ffa7b6631e934e954afba13b14629e9683c20d697fbf5d5a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a3437295823c66aa4e245297ed78ef52fa6c71": "0x00d6dc8cef0c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890087c431927e0a49ac8908026cfb13d3cf96b950": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891cda53cdae34c5c3b2c62e35bdd1db577e56d3a5": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0663c63fc812a1d2d5ec872f1f2244ba474f36cf28dffb9c8197e87ab4f19e50": "0xfc7d085592f433e4523a2bc030842427b63ce31c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fa9ed378e8bc649df332605415e5a9f3cea779": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898ebea2c1deba5a629af27b0c8383113008c8ef43": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d491bd0f908f61798cccff0b8e27838166050000": "0x70472afbf636a8e281850e5a0700ce70b2ce675bb2038e92b134fd7f5d02bf0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3e35d39ed1562e36efd2facd3fc6312c25241e8c665fbe0fef836b92224bb72e": "0x0b792f95c5d535942270423c12a735beace8e36f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004b592365dccc0bcdc29fb82223f2774b93bfea": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928992fafb4ba354108be7f0b76f5aa93e59b21288c5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707ff3463620606e7483f074c44fc25c32383bc79": "0x002484462f7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1c45f47adf9afd4df16500a4c213cf52af55f88": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900da54bae3fa6d6612987a7f29a32ef9999af062": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f51382de43471e6056864cb39123ac877c1902b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f9beb8f41a6431023bcf41a1c396fcb9e4060000": "0x4e3d772a967b139601c365d3804d88396b10b4ed8f7cd6d67d7ea6b46b2d576100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ea3c5be41a73bd49b97f4cdd3eb55335baf03b3": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b4dbea3155a8f7f37183b29d105ce11af7080000": "0x4e2c830f308677db112a4a79bc17a39c91352b6d3ea0e476ed59dff980a0167700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928948f5ae497b444b6acc53150116526f0b239d1170": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397203d2e2bf08a58c132f650f44e6db94b78097032": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928993d79977ef117007a0028218d99dd2caebd70b55": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d28b60a62d04c7d92c4fcba02072a384e2f60ecffd56264aaff66325509ee2277": "0x0087814a753208557c3fad394d80348307326fac", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d46ef2823db8925dfc223d2be94661efd2e77286cc9ed573d94c0391d0622262d": "0x006c8616a98ff7b6fd6302ffe44a18348df5b3fc", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbc1d8ebf568492bdb5735740168af7187006eed87bed5d2082b32b0b3fa9d953": "0x1c062628943a930b805849b494719c7d23c77bd5", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971eb95275df958625d6ee8a7da99eea9fff12127f": "0x001e22598cef03000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5e348817abb98cb962fc0780a47ebd471d9c318395fa80b4529a64cfabb2e32c": "0x9e005e96b230631a08c53a58cbde5e1e13943647", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976df205592f28ab7e1db1ff8e24d66c53e5f22c3f": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bc73c898b502cfba8144fd3a1a33757ab84440ac": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282432c8d6ee56d63c0ccc987b1bbce567834e4e3f312": "0x00901ec4bc160000000000000000000001cb240000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898afe5cd482d702980f9b141ab34150996db32341": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5100ccf8bee84cdd69c2c7f74f02832c23f5080000": "0x6eb49bf513747f0547e07635cfb06fcde75dd66f96ccde6fa072b9fc12603c3c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897a1206a0acb0a887986a5ec7c1899f96a68f6f18": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1c7a132e41c02fa4c8dcb647700633c59d6fc8235b867d9422d1fccf24f77b45": "0x00ab35e5fe5354151bccc15e6d219dcd23c2e868", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513d7ac04550fee8d57d45eecf63665296e0050000": "0x421f3f945c49886c4993af976b9d06e97b4a59f99b151c9af27fd612446bcd6d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e7573ef29328441aba06fcbecae95383cc85a5db": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d70464a147925dde45821d92e07a49082107b862": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fc4045b648c5b9b5c353accd0a61437c4a030000": "0x844d7741df7f47531af93e28a1bd1912a471977cc3cf5666030936380715054c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bf8401e27fbb06066845b15be8c1b06e42b0e6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e187973a417e345f5c4f5dfb690b3d01001e43": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895f2fdfdb7945f770436d1f41c01b47fb76313a39": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519a6b6c99cb0d08662d83ac1764e5809501050000": "0x423185717826a19d375e259a844fad640a1bda720f14e0fa7c74bf936a42007f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f57c911367700dc2b5d847ffb0849293ba5af025": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896285a2a0892b479e0324f4e51b2f1052712a1e73": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009e02b21abefc7ecc1f2b11700b49106d7d552b": "0x0078818246ba00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f5f3148b56f9929c4ca064619f751c0061050000": "0x84583d9d96ad734c94c2a8e35e9545434a0aaf87ef3b14a3aafeeb6f863ccbd400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3cb41637bcd76f2609d767597d6863ccb3cd965d896637769a43039c6347a47c": "0x8f4d910b1ba48ef5349f3cbfb01908c1f42ed63a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a0cf34d8a3dd4d379800bb440c1a3523cad4d9ea": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7455f18d8399830baad97632cda0a9cc2008f66": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d721f7b0f0217f3fe8b192b5a2a7feb22b296e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928951afd27a799424910c5bfbe69646a6f87cc8b73d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397651547546b24fa036b9c1b1c2dc8b2ae9c07aed9": "0x00e6562e0e5e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bed113f4cdbf6e0fd3d402f84fe00cdb9ed79c3a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339788b5c0f4c52ac62c66c1c4d009e6ae0f72f4d042": "0x0036effeca8d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2888de98d79687ad6a7f8c38c9408829b86680eab8e30d62ec36b989f8088c7e": "0xf68ff9a1cb4aeb9018a8671087fcc6155bef517b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890002ec0da4bfd7e9b5cfdcef93f8a02d4b271aba": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339799c72a739535fef15968b080611b4752a564a3f8": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006e6907ba032a02644f7289d5a2e5b6f3e41a49": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19506c292ad94b2c2cee6261626580fa3437b10f6e7af8f31362df3a179b991a8c56313d1bcd6307a4d0c734c1ae31": "0x3887050ecff59f58658b3df63a16d03a00f92890f1517f48c2f6ccd215e5450e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bff9908ed6553a0c3b071b1232bb6b544abdbf": "0x00ee853eab0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ab7edcd19d92170528cd5d8a7d25dc6ffb75c39": "0x00769f7b7f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1eb5c6758a96f303461856a587c3b58bddd005b2b1de6b14b3fded4b5b01960e": "0xafd6e8fdc9e0f3579e0b51f4af2587141b34ae18", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892afd2c2904bac60f47e0a351c2fd66e12789c7e6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892f4400714bf70c32740d1b103553e4147c0ae254": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700aaf196cedfe640591c2d0eb4b06cc2c746697f": "0x001a5524560200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928998e43e922b829f33f3a8c9a81943df15706e7441": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d9103bb6b67a55a7fece2d1af62d457c2178946d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dd421a32ea27a37f92e901256c472f34ce070000": "0xaced6ba10b1cdbb0cb10cf662c37e312414c26f632fb5e89e1ac410238a4406800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f0650200d57ff9098164898d2231b2de220c99": "0x00d42517c30800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e49d3022283a9fa6d64271c2f18813d5250667": "0x000e064d410300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a8c2a3dd76bbaff6c13be1d583b3c95aef9e773d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c766b7772d2ed956c850107bf56ca79299ce6d": "0x00dec475160300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df4f3e8a5bf3a21759f79fdf15f03b1bb099b3ea8284a845d5eac8b476e618804": "0x29bff29d8193e551e089b3aad1e3937882fd9d3d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973bace2a685d8d73c3e60b84bbc34ab782f54100c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339747a22454aab7e24467ac9fd5453db69b3dfe8cdd": "0x004072e62d2d07000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc4f955aa807f2c144801b3ff189da53ae841c7f5d6bd15cb3fd3b5001e94f855": "0x1b22a64ea64c2f4cf1d6ae25c855db5fe1ca0e20", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971114c8fc7287c7b9eaca65be89d82d85288a891a": "0x00901f44ae003f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397893a98ff8d6d8d13cb095ca1ee3f9a70bf9bbaa8": "0x004ce4f43b5701000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ad897f48e2166a71b83e541cdeab9c36232d905": "0x0062ebffa05700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890055996baa3a392a18f78afc52a0fa967e6206e0": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c432730fd9008dcd451546379bfc921b51050000": "0xb8362c2fbae2707b54b90ca0e28b7bc4bb25e81159931d9ac85cc75c20a9e16100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d62544cac590661359cfd64c73c4f33f806d24": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df2bfe9a0d14bca7ebc7d681f805ab905e882778d398dd991f61dce22d1bea24c": "0x3cefad973ebe1f54b6e790c823f90f81e95f4aa8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890f44232ef2cc7a637513c492322271498bd4b915": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892f81a1831e1bb3b21b063f40b5fd29969d9cb2ee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894ff82054932bb21f78c58582390d34e16a479294": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5138071eee89b59e68488f19c2600d80a886070000": "0x9a976f1fe1d9b93e4931a5fc14d9312f64677e32033366f01d9f855edc92ed1200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51686ffa482169b58cb879a4a4e55fdd4a1e090000": "0x46a1fee5a1810662ef7c82a2e91a37a39ab9611105b3a45717ec131bdc4cfe4000000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcac29a0310e1bb45d20cace77ccb62c97d": "0x00e1f505", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5149e13bfe7ec4693058f8fa225936c66b08050000": "0xca51a1ec0e15c10c0bf0e44a957964485d66ddb7009419186136d1cdd60f9a3300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d46ae3dd83d4737906858d8cdaebea882b9bc8581f6716140e1e9cc1516ea0161": "0x0059d48fa65e3440a352527e5c11627927751023", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db01917ef7ef9823b455ceb5295211968ff32f415d7feaaafbb6facce258ab117": "0x7df289cbd544ba6bd153b783ee9024e46a1a7527", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c8e20df2aed2601379f90cca198dba99cbd8ef": "0x00a07bce160400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8889bb12ffc22c93e6190aeac259184d7181bed3f0cc9938d27315f8e61c8c4a": "0xe571ba1d28c1acbc64c8b63b6a4c9664aca816da", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006706b3aced8f9c82f45055521b875be51da06f": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973bca1e6cc37f9b72191cd98b6fbdce4e092f0d3d": "0x00703874580800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510907a059c2701667eebcb93307c14a654b090000": "0x103092c0a2aa3bbbbd71945f255bd5cfb7a97acd4a7f08efdf2ff5cd9c6cc34800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511beedc39f7668334e2012d40b606637ff3080000": "0x0a99dc7c944cb8c2cf094502e581afd9a15b0867783234427828e7e557903e4900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f7e7b1b52725e1f32729d3a2c521a5f76c98df": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005906f955d7a8c58b036a9c36c96398cc40e32d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892684445d42e93876de6d41ed685081b9ae9bdd31": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928940095bd940a96c8b42abc9602a265071d0ef82c6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894d5f062ae922c42aba01b342b17fee7c9ff2d071": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898234c57f49a272ab89ed69f445cf9ce68406a1e1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798d13c1d3fb4621065d79a06a17a0621daa314ee": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897ad682addf837939690da95071b9492b064797b9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289022070e52ad6f0425f72feb16636fffce243529c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899fbaf540fab13261780b0eac3e1beafb4a923bd5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d7841fa410e1caafcc033f67f20c0f60163e3153": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339716b278ad48a9fb2a18f099c210ef742479fce983": "0x008c0d35660200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df677578eb4297cab4fca1239773f757a4d13a01": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002309df96687e44280bb72c3818358faeeb699c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928904226cfa81b91131b31a7eebca8ca2d9677bf0de": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e60cd5cfd2a79cb84942b411750fae1f800b5dde": "0x0066172ede4c06000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928999c72a739535fef15968b080611b4752a564a3f8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cf0489ae7bbf3b7321841f3ce9db682a6b0cf612": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c6a412544ca646cffb8dcee7e8041f1c8c050000": "0x8c23324b0cb29e4fd1a68cb08febe58b50e39d8afdb5f752d6c26c8ba52fc00200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977b1ec653cb5acf9b5e95dc259928fc766d0ac22e": "0x006ce3e337a800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289082d3e0f04664b65127876e9a05e2183451c792a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979bb987d0bfab369b9eca904b842723670584a5fe": "0x00000e8308e409000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002a7fd49620dac7ed03ba8cdd224ec2ddd16a1c": "0x00f8b460847c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397720bb1fa61910880dcfb5256a4b2378cd5d8f563": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339759674388ca17d95cf03ca527665f789ac10bf4f1": "0x000472e3852901000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea9d6a9ff692b9616f90f983f2e2aae2ca3c9186": "0x00f889cfe91900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e723454d7ca777999065bd370faaf671b469149e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890028f8743d32aa2c22d2eb1b415c64d3fb49ebad": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f385662f28eb02ccd3da6d3a370777cf73e68306": "0x00008d49fd1a07000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d064beb03134e27c7ea7635c6dbaa993b3b54819217b3b50838fd21cecfedf725": "0x687f956a18fd757f21ff2c1f0334c589a6bd4d1b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970055996baa3a392a18f78afc52a0fa967e6206e0": "0x0052f09cb80800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bb4576a033caf3ea0eb8a9545b26fef07ee78115": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d013158d85a214417ba437399a5dafce6d040000": "0xccdab8025bb63660540679cce9993fbbfa4a0d0c7ad4704d7d0a04e4be9c6b2600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51905a3b2efee31b5241c157d7ca1fc38661010000": "0xc63e44ad328b36535b7ff697686bfa43c8b009e96b263aab1a37933abfbcb13800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7a1878a2deff652de8f84322fbc6f3116e643c65ba2bac59244e64c91382ba4e": "0x002bd178dc5ec5ae344d367d4a97281f63736d7b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004deef731d0998523980400c6be915b827d4a17": "0x006297f4340500000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899ddac6c981572aa3f4ab7ffa3d64356d94093206": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513a5e670f9ec192f1b4db9f4471061300a0030000": "0x2a85f847dd5d86132513b8e5db91d5a05d15d615c121ebcda24f09e496a7390100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243eaab1f865f5fef8b614c6b2468333205122cd5f7": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d70472afbf636a8e281850e5a0700ce70b2ce675bb2038e92b134fd7f5d02bf0b": "0xe73a25b58bf440d8ad53eb773f412a4e89e22719", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339728020c484d59bc36b2741d5aa1e1d48e6e3ab0e8": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339701772953ed3b69349088ae7824c649d6dcd0cb1e": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890026eb71a83ff1c11b7a516768a7449e27ff565a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db6caa98b3af02040bc59ac2086370f722bb98f22031f65f56fa9a5d2fbf8d849": "0x00b01d06372d7bfdf7ddacb9b11037e024377810", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397001a3929769b8f2f809aad807767b5e2c0a9e27e": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970072d5c92b77a0ca227964a4dfb304acadc78a05": "0x00e4d5530b1e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd8bd9c7e5df52ce11d6370096388ebc0ce1d165fb610382be7f322f78eaef401": "0x80a8bca8a6bfe60479f523c10c459ff6384760c2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700958aa22920b759f069b570b275e2f9034ad0b9": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009f4a65c06d5fb189b88f998eb9cd5e88f16708": "0x00fe0f93981100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339762288f785a33c2318f0244dfe24748a9b444f8e9": "0x0060a23c5e6c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899324439bdee04087564a0c4d01fd94fc5240f88f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899c2746e9042bc252215d3153d0592bc44f28b2f0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a01b1820b48fa4f1866f485e6351659beed55d2a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339723b7bf89200663f958f11c7d495f9dfa793b8ef2": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005dd1c702c3fcbca5f63b3ab931b15e03b3c9ed": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700eefc4631700701e9d546fb7451705dc83b0731": "0x00ba4f31a30800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f80da45d4b487b5dfabcd2b85478a6730d798c2": "0x00a8b75ddc2e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b96841cabbc7dbd69ef0cf8f81dff3c8a5e21570": "0x0018b092324802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002c2d84a889df4bdab0175a1c4487f67adacff9": "0x00fa444440aa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900449ebfbdd1a6e11dc4d7b458d4851efbb06778": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004c54887f268bb0e5ed906f779d6ac081c11660": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002a9013053f71ba888e54a8f4896a5cea18f904": "0x00eca039a32700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979ddac6c981572aa3f4ab7ffa3d64356d94093206": "0x00a6c8b2dd6324000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289669b996dfbf62da2ddf0c9ceeac503b920671639": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ee1fae10668204a6a11d73f1dfba264e212d3286": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007cd4fdb6a94978efcb1997af675dd6e4bbe1d1": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e0ed608adb4488caaa5b7ae3e39f3d7ff7487b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e51231daa306acf16eac34a864564ca36b262a1f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9a5fa029a852ac699897b9bac268e3baaa9c920fc37fae630f62a726b1f25840": "0x008fc7cbadffbd0d7fe44f8dfd60a79d721a1c9c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973fe5d6a2d1caba760006007687adca8661a252f4": "0x001efb11781e02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b7ce6873ee9cd4a462a3e13fc8dd93d9a40ae5ba": "0x0032f4233ff602000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928967494fb2a324220f917b9f9d6f6cfe72093d4cae": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974514bcb1596297d8a9110c03306b47429203aaaa": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973890a960391f2a35e00e7fb86ddd1637b0d5ace9": "0x004e67f401e000000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950e83319b827857d8d696d6f6e805e5ab03e0bc62a8fd3fded0b09ac04c6192796873b38abceffdbd1548f35f61a": "0x5809fd84af6483070acbb92378e3498dbc02fb47f8e97f006bb83f60d7b2b15d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f6fe74155a9b6733a8ac7b3836e38927d7a761b0": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0453de8b68a795494ce1ce969819ede9bf795d7e1b389de4f5b01b6fe1118404": "0x43a6edd95e865b50426330da71638b56f2a75c21", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ee48f23c4b73cbfadebf37cbf7d73fc41469f79b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928965076dd6f1438dea38b5901315208ee437482051": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339724094ad3da60814fa50da15508539effa329a1b8": "0x0088d21c5b0f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4a1d7eb798b449b44466ddc54525343cce18396743aa708d1ec25f870e37cf71": "0x48299f5998fbdc5898ac71e8221014a7124e0788", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a0c59e84c73e9f41ac8dbc44eada4bd908a07f05": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519779622e5d653566d45156fe31ce034067060000": "0x22f738ac3bf4393d7968dfee80d6fac4d0457c0e80b56e4d599b40d7b4a3e34700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5196949239f3bcf14cd5b90a9fae4e8ab91f020000": "0x7c9e58caac08b868c221d0347c32a43e1ca416ee023125bd2f43b590f2c58e3900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289893a98ff8d6d8d13cb095ca1ee3f9a70bf9bbaa8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b0c4f552eee0531a134802d847c8f2fa0ca4e79": "0x0010a125955101000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5057dbc6c810eddf1e13d94305854ab72621bbe9566b117f69e705bdbaa9143d": "0xb20a9355f834dc352aad5ab9bb4edef1d45a37ed", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bd5f99e04c74736c9af2996d0b15c3f8165207": "0x00a02b27a25b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898963d38fea40b7cb37c9bb2c4d3252415f0b6d65": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397111c06a2f9ca5975c5c2803ce2ba4517e5361b56": "0x002484462f7d00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516f629698caa69928b42466c28582a117b9070000": "0x78431453addcdf3e1ae922819e854136abd32cf2937ae9c84329f1eb92a15b7100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ccd8ff59612d4108d9bbe5f16add545efc6fdbe": "0x00a014e3322600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0e3eec80e1f333baf219d42661731c044052704": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513c0990748d50ed1b16b371d96daed0ea14060000": "0xce855e2b5a5260a655291157b6517146f10888ca83cb17609b906a401681a14500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6c6cae8ad5e77ec2b3c9df3df6c139a3e824193b1c9f0ba69cc6e4c01e867a61": "0x331ca0d8ac0d809e8e6031769d5318589a469e0d", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516d8d3acd6eceef751ba2291fb3788d388e060000": "0xba52bca4f4d427db7c58d6e341ea01f2e5374c826a11fa6d4ab5f0a1c6f13f0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970094803d665f06fae41ff86b05c81413ca8a8a35": "0x00a27b4c1d6400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974209c9ea64fb4fa437eb950b3839a43c99d96c06": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d39e54a89f737272fc97f2a35b25e9bb5b0265a2d78749965aee5c0986e4c23ec": "0x27786aebb2cd05b2fecede13382aabc3a838c69d", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5a0669f20ddc7e3feea1e2df54372a8776fc42e4b1997f3f95fac2a962f3367b": "0xa42264114e13a067ac2baca439e9ec5df20c8819", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a0be7b175484ca4b6ed2490439ceaebd1c83c400": "0x0062b3e8e00200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3a24d20be9357d2ea5d385ae82bb06015260533d800c23145dbac4b1cfee7f77": "0x0055a15e869bb215e605335181284aee8be30a50", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc62a133f277af4f8d937c5720bc59904ab1d48e59820789cae9e326a0c45e158": "0x7574855f00481cddf4c103ae36ddf6e042e5d367", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5e6bfb60d6b71fe80ee70912e01de904de80da6da39d1128f210e53db3c71853": "0x43a125a9461625e72cf17558f1c8b3b653347686", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890082f8170db9a32e8cfed10aaaca5cba2c20eee2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894b7530fd33209c28c18e254816adf0e2f065be7e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289611ef0a18a260834d1a063bd279c8f4dfe6f37c0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dd76301e7c4b342f1d805b7205db98f6c1611ad7": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928962288f785a33c2318f0244dfe24748a9b444f8e9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa70dbd775c74c3182ccf34636c63637b49a8f56": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289017a5d5fcc1bf0ff50080df6b62f484e96c5831d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928949fa2629dd5ba6ece667bf6eadf174d2c8195cf4": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d603153efe4c60f146d61b66d5c9f4a9b469291aa260899bd99083d755a28923d": "0x83730c5d67dc5740a2ced307a2612e4a337dc46e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700a1b46319be9163b8ae30dbe506235608a563dc": "0x00cc5d68c87a07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700f57f2f7af6b196ff8cda28f9ea27010464d009": "0x00ae8f7afb2300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515f7c458492c7dd9d734d6600897fc393c1000000": "0x0a4146e5d4eb7d13aa83c9a86ddb78f4b68b6a4f4c4410fbbfae65c2ae7f8f7600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339707ef90799d9df56a442e958d6bcbb274f2f9bd55": "0x00d83b74c6278e000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397539f0f7f1e8e7aa08d822213305eb6e40c09ee44": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ad2f45a879431ad25fd8ecb47119e20b86040b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928947b340a7cd29bfa96a17c1685f61a67f0c7de422": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928978402f084d2219d4844e5446ce4e67fba23b9d1e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898036c27fab2691804b28b9f47239e64c15e249bf": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397addb5210dce9127918db041caee93be7b50ce633": "0x008a74cb221f0d000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d3396c5b7ada618bb851ef905bddd1bbbf4379": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975d67096571f54542c5950d22122a030c308e7ecb": "0x00a0724e180900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b2d0d59cd5f2404e8b84aac4558d85fd81080000": "0xf3a6a9b086181a0005de487ea5fd72fe7066d056d7c7b9d6572e0f609925f3dd00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700fa022c7a8d5712e902569e7dbefc471919a1ad": "0x003036d4980900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e6d7485cbe990acc1ad0ee9e8ccf39c0c93440e": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397da0e34cfc36d47a3e0c08d8fdb0ede1408c7aa3d": "0x0082313f7f2d19010000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cc04cd98da89a9172372aef4b62bedecd01a7f5a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d48e5f2ba6ff67730b0ac46f70411fb5d836c8981bd1a239fe6ef450ec72ae008": "0x00c063dddb0309717f742363085e29ca9b097db6", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979936b02740624946720db39a34ab4f5ce0c11ab9": "0x00a0724e180900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51abdf023635965214039f0930779e5fdfbd040000": "0xdc940c013d2869a42dfbdef9882e33b67ae45dd42494db04d49feef8dc2a680400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512341807f99d624ffb36989b5d85b51306a040000": "0x86dd8c48657e9cb0e83e44d630c8e1cf761e9b92329484c28fe6649a4b7efb5f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970dc2c13dd88f9aae93a65e7e24b07a39e1d94ed0": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d70464a147925dde45821d92e07a49082107b862": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e31e4be4a7c65fbf14ff16ed654bd06b3a1c6750": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c5a0d7d8d403f371985fcb5c4dd9527bf82ee4ab": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824313376a50540351f4d0242e20256e857a80bc86b0": "0x00408ab5c74301000000000000000000a4ee0b0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339766dbb95b55759347745b8580661c049dc211bff2": "0x0012a552ef6000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824341f2f7387969ac7c06fa49a29fc479c22a9ec8e6": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700659ec26a98fab3ed365db68d56a31d005cad3f": "0x00c6ac59614e01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727fad8fa4f7ab0d981f0a5635cce2895f786e59a": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bed32016ccb33d7ae3eb165cbf37c7d23e35da90": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c05217770e1cae59d85c04f333cabfde7c7dbefb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899d979604f1633bd31944245b5f6d183adebcf10a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f2deb52656ec09d473daf4a2a425dd930e050000": "0x70001bb5611ed06bc17a2d36520bc84621baca6e76448ef632aec450edb0c97100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5a03ae20d63f42ac899a002627267b2b98dcb922812431f7e983a9632d2aac3c": "0x0062bcd4cbb3f4501caa19a2abae06c7dad957e7", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d58342df06e837a7ff38096d1169b1f87938fd88bd84c81edcf5900fc525e791b": "0x002408a2f9bbf1fee7a53eb361f8eb2ce47aa6af", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5198d8fa7a7d419b990706565c5911dc78b2080000": "0xe2d126c3dffe301385f3d6da21756147d8f58040a9021e4196a89fffa2800a4800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d34ec6782d6aa76c498734281a7118615544a986f39bcdb18fd3542fe567d044d": "0x67db7a2aa35266295c4e478f2f6f1a1f6663e0c0", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d78c8003d8becb1414e373f12bdafaee23c760cda6aa4f2421bd424472995d707": "0xf220d58015031403687716a43c54f64dc99713b6", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da21f09d50a9e3c76c519e0f59865a8ff370180e83a6058392e5a0e64f8b9a333": "0xa04a8b46187fc60ec1754b78c6489f8918941321", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f38865dac042397b42a80a2cdd54eaf32d439754": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890084e0ea2823277102b3701b0b29d974c29e5e3f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890a8beea0a04b6f97bb39cff19803de453ef4cc02": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289111c06a2f9ca5975c5c2803ce2ba4517e5361b56": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896c4a157e6363fb44cf9a3edaabeec6657914f8a1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898134fae7112d109c4dd3a1f09aac75f2372cdf0b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971241b9a94b7cbd63c50a9fa35b1e370fc583cb00": "0x00ca26e4674802000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700eaa3371c03ec84b98706abf06bfca8b85956bd": "0x00c0a31bf09801000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005789f1339729bd51c51cc221efaaeb571b6dfb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893cd0266a7d638588e79fa9b471fb4c2d6072e4d9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928980872129a96f429312a717e2fab264562b1254d4": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243fa93a39e60a804ed41e1bdfd38badd4197e6a977": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d70fb86ded71ec9629d9edd8f664d277ca1695b56c069cc710c823f6eb7ce0917": "0x005ba629a682cfc064d0f7e35710819889fa357b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339782d31226f14b0b79aaa950cfdd01ad248765ad20": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7a4f4bd2ebfde2b52565fcf21498d1fed82347dbe23c16cc499fa3e194016558": "0x4b78bdc1a48d2186c3a5c3c8c0892ef47155f85d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f67a905cd6e24183abe1bd4718aaba22c520d02": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899e8014d80afe8da0e24e90539b864794c6981a0a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f74ff8fec69a8691f8ff0493dba28b57fe3b11a4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928970bc832c319132b534d1e32eb24a5a58a29f2624": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b8577dadcf48e02e17c649edf5185844dd2df05c": "0x00ba1ae7383a03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890022bcca7fea62918f9412994bde69b9a396e446": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cb4e4ab1d79759d29b58116ef6c0158298a0d12d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519e033ee38dd04dbca2c771088b65f816ce050000": "0x520bb8772cb80655102c3c0395b92b8bbe820dcb8d8ef656bdc2f15cf2701c4900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970f7f54dc0421d8b06c07e3d872730fa111e1aa67": "0x0020034cf68f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510b466ce9b46756db2360a5211200dd0f3a050000": "0xd0a09fefba656f157e715f18083ca46628c3646143daaa0f3f9ac171e306f35000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890075cfddebf8f19740296cad7870516db11db25a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009b60368d141bc267a201d3024cd8c68c5968df": "0x00442e98972f06000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510ff3d81dd18320c1488c8a4a768a1ce5a1040000": "0x525c90c5a8fac52e9992258bc4bf9b8de7f812b172afef45147ddc56ef23731f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5146a76b2bace61b4088fc1a405de25b7fee030000": "0x38a295559d8977464fd8cdd133f8805f2388e42a6e009219247048a27d9ac06b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974af9fe0d55c749c5fa4eac73c660afe9614c926f": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a6dce6de865f10bffa3585eb4422532406050000": "0x1472ed23d9d8b62b09fa74698626869e65808583bcc382d8239b7da80024843d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1e1fa2e8cd46e066c37ba6ab79822b0217bc35122349367473f7fd0851d3b224": "0x0b3967aac9abb324d90ba784b0a4ed41d2a7c257", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928967936306c1490db7c491b0fe56bcf067ede1fd28": "0x01", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1eacff2415e856692ddc43aa3dc4e8f965353af039e2efe4a70d6accb6e76625": "0x00de002b79aade8d38abb85617f6dff10f60917b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397006dcb8ce8e81b15ea955599cbd14b0532da2d0f": "0x0030dc8f48a101000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243003b3575e3870ff8d5dc6114539250b359194aa2": "0x0040f09bbce1080000000000000000008f4c5f0e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700dbddc3563c920884f1efd111c93ff30d3d8465": "0x00aede25018b02000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339786bc373e025f772a169e0c3a1f973f8725979169": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d52528ac5266c38e3558705368e9627a53290f0620a464fd74378bf6fce3f4c5a": "0x1add1af6a3949b9613922f9dd9cc3c98d003d5fa", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289635954403448b9f55655fd5dbcc9675e8a4b8109": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfc6abe24151bd4bd9a8a3c8e578e649d96f27467749cd5198bda48388de2a42e": "0x9c2746e9042bc252215d3153d0592bc44f28b2f0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339775485be7dc5d7e1218052accd222e75d4484df1c": "0x00be174c553800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900510782b5d5bf4c408ad8a18c4cb7eaaaf592d0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897363ce9c3118275a73211c2746432167ea95ebb4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e124cb3fbfa4b20bd4ac9715bba413bce7040000": "0xa2c71c01fae573da0ddcf3a0f10c28e5400093c72eec182b1a141c4dfb4a8a0200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dba1c5969994434143ad0966f1e785de075b8e67": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51432bf4cadba9bba1999f217826c4f55558040000": "0x38258ff5251b93f46034c7e4ad5eccef902a733ac24cd1db66549041273ec23800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e8209f6505dc718027be561be842318187216bc2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a8c2c0007f4f50045241bf96aa1934b0dda2528d": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928930f0056172b5a1432a49c44b0c5bdff96a7fb54a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e629f5ed94561a2e8a2572b46eef3bfb4419162a": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289331ca0d8ac0d809e8e6031769d5318589a469e0d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c43ec0fb4c71b599ab3b5e9e6fbd89553eb615d2": "0x002a911003cb01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5196ff67e4b5330a89cb59d07afd6462cec6010000": "0x388610ae23e60ed846aaed8241eff3c792915b98bed9c1eea8f0a8defd2b976d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002e54f5a746d8af042121ad2129c4240bf460a2": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973dd62544630d94aed21653ed9ec15810cc759a55": "0x000484564a1300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282437a419133257993a9af281933febc870657c764d3": "0x0000b605da79630000000000000000004426f8a000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ffd011cc6737e113dc8ba4b2cc294e656e9d8f00": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928937c5bf8acb3140f17819ecb4dccbf2e66dff9ec6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7631a588d157e5f7eaccb276b39ec6e0fe033574d07139c1354763e122a4d065": "0x206dcd656eb235659735538e8c7e708ba0c3779d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970628dae391a37ccb6ccae7e6b6495c2622d69cda": "0x007a55aa1ceb0f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970004ed6ee7f9141133026274973ed0ee4ce84f65": "0x0058909b1a3e00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5109d914ca781a438ea1d69234460363a59a070000": "0x2e2409b5ef509e1e584584edc945545f42fcbb3f288f3355e9194206b4ce773f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000077e89a2702e5438d2be4f7e8744a5ee2b60a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898d6fbc613b4bedf87e57a6134fb72508099bc089": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397029ecc9d77295d1126c333cb1e1bdf3ceea8d515": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339736f44cf83a35e43c5ac7d775f24a11e6a874a85f": "0x004c2862d02b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a482566e63d032af218a8d65caeeda5dec73e4b4": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d828fd8ddaf7415bed383c5732e236d718bdbcadc1790ada6e27dfa87f9e74a58": "0x29c0e5b31ccbcc929e001a4828a62e09bd307688", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282437735e8af95538d6b436e3f63db0233b46f23aa08": "0x0000b0d140d30f000000000000000000bea09b1900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339752e55f169adf75007081d795987122cf82af8e2d": "0x000aa1d3ec1f01000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51388560f70625e5fd942e32874fb5d94603040000": "0x6ee274ce5c8a1dca1db4d84ac8e9d7164148b088247f6647596573a52684395800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397994625b177e36e65a06118684707c19a62194586": "0x00f4fb4e8b3a00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bcaebcdced422e8079231b446d2b8abd50000000": "0x18d97c8a8030d9450e706a8affb50f35b961b348606433e47c35173f4691d14400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890549c3f578615e95f58e521a726269b6c1985dd5": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da2bba0c19b621759defe85c49e74d41dc70d6cac1138553207a8c921b6db705b": "0x6d508a1452fc1ae7b10b6e858d75e669536fea16", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a1cac24ee6eb326f1640c5c97b8a2e260b4452aa": "0x0038b8458c2e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc2fc92e6992a16358fcc7a4d816f46056c0f6d231c33d8cc2def79cde45d226a": "0x009e02b21abefc7ecc1f2b11700b49106d7d552b", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928912ecdad9268108d4cdb6c21da81e447ab12ad84d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518bfbdeb4a760ee37bd33447838d37d5a94070000": "0x6a3c186d9e7a9a84043a4a6e62213c376e7dc913be683e2c77c6f61f9e67c04500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bdacb2381dea4e23621e4e3f5c8f0ae020cfc688": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700df109c62f7e61eb2531f8751a9202beb4f5436": "0x005e737e69fa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894bcdf08359aeae40aafdd2cc282e7c1fbb2d310a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bebd4c731ec56e072e94cb0617bb47783ef3741d": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928927d8519774c77bab85031463f236c702c7ee8bd7": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282436a37135f77421be9d9e5c15284188e9658207dba": "0x0070139ed73508000000000000000000e124490d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970026eb71a83ff1c11b7a516768a7449e27ff565a": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d660e0a01a5850b0e4c1c447a8d4f41b9cae63d0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c72c867cc89ccb922cda5821ffe7f060d8603d": "0x000aa1d3ec1f01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289801aa940bf8ac12429d35c2cbf0a13b61758bd4e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928958a9d04522df5a3c7e1af52192b89d9c952b338d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976407c0c25a5ac315d64b8eea2f315983f4096f7b": "0x00ec2501941c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fcfee4691f55d3ee2276a75fa57b784d98ffd1": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243546d80fbdadde160e5d4a3482bbdbf310163192c": "0x0040e59c301200000000000000000000346f1d0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d30c76c1fbe70308d47eac55e1bfdbc77cdd577c1cfdba04ee225d5057bcf3307": "0xaa71944087a4242e157bb28a8a1b110274228ea5", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a59c51409b63f4900cc5c90374036d3a98f7673b": "0x00d0c2bb340301000000000000000000aa70a30100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339763a673778cb652db8fe7b320da78842e364c40eb": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890054e99a8a384386279936d42dcbabb4a710ee74": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc63e44ad328b36535b7ff697686bfa43c8b009e96b263aab1a37933abfbcb138": "0x0004ed6ee7f9141133026274973ed0ee4ce84f65", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339798c97b38d63ba67d0770cdcf8115a5c8a470e937": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289928318b2e90c8b1a5255d03ee5eb3a1533e3dbea": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972063700c6e019a814d24f514ec6512711c399826": "0x004e1d826b2608000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b43d777a3640c4b0d674668f57ed75b7fc84ea82": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bb9f0597834168a78ec443f09f75e3d62ee98dd4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e3c4d881755355b58527e1f09a5507808de5f9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a045d6728561c3b5f1978c235e83331e4f9d54": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970c69d0cdaf9abd8b01a100387d4c5ccba3b467f4": "0x00dc597e469902000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900778318977af805d19aecd1aec84802cc0672b2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974bd120e887cc82285aff8408dc208ed32b132bb3": "0x00ba96511c4b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978067113652df86032aa683acd46c0b2abd8c4a36": "0x0080ca39612400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bd4e8aafa7d3e1d9fc46c5ca788d6dcd1ba873": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397275b51c1557dec3d252df5984bd2ce9e1f7429ad": "0x00bcd2c49e0800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289097b2eece415aa2a4a7b1e0c310c81ea3ee1e292": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0e7d980e385eead4e52d1daf803f4f5869799cd12f55a41031f3d9d93b52f882": "0xba10276d69a11c6ca944dcfecd669325b67614eb", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d0e8e4ab292f43b95ab94c1014d22abc9adffd": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a0cc283d935edb5c0df5e29b111534c101fa0280": "0x0000fd137b2a5c010000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970e696320539189bf06f28dc0c7b7ece1880e14e4": "0x008057d73a4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d7200c399634a9dbbf59db9f48685ec22ea4acb7": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d62e11b08e75dca26b32d2cddbbb7c9acccd504aa7dd2ecb41a7e30ff08baca00": "0x50ef20ae1ec6ca0229f4a3195401f1256985bfea", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897eba0c6ce3bc5bba68807e2f390ed997a5f78763": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c44438ca119cb3f91dee8f514f435f2d88c338f": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f95ca3e58c701eff23bcacbfc3c889ec6dc4a8ed": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a3e730a655dc85eb0752491b2b95792e5c080000": "0x3afa3ce88a657a1c8bfb69da7910fbf48b36af6246ab91c868d410338b998a3600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977e22e58855cad471e60b297f1a48c34f44091132": "0x00d6d9e581e101000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518121e7d56c6d2afdf021e0c25ddf8fc305040000": "0x729324ff6798093939a73546e0f3d53a9cd7d4e938d238145c9422ce9f0beb0700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51064fe2eef017486210a9cf90c3dedbad2d050000": "0xe4e822f53c6197f69e968d91b2e0d7ef65d1c4a870cecad43f82195e7841e51a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002537ce06f4d8d67fa5c81c75dda886efb646b2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892553a9aa6cdb203895a904e98f6d2437be0805ce": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a09493ecfecb6c710157bba28443bf28bed792af": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339768616b50e3e0eaed3c1b12fc53162e335e0853c1": "0x00f0ab75a40d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d12e4fa92d67dc73b2ae4a7eab1451467be74b56b03d7892cd31f10ba3991474a": "0x13d5d590be45f86e1c1297073951ad7abfb746e4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ab10a4c4d9b566830c833a90c865d859770016": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2e6ebc8ca688165b98479e557e0f1722d08cc23a910b99d73152f8777f6a3c16": "0xbfe953b6bb77bf8c7851141ca684c5dcfd6cb925", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973dbc5ff979d0f30d65c33f684eb4b32cb4cfd3cb": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d97e73afd7e39b59832ce426537ce534bb5a34a9": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da65b765fa2b4a31d06732e463b6c0ddcbfc615ec83d94ec4570512254b6d0b43": "0xd5c914d49eef7110f4b178ade972bafcdf83f994", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a2e3a0c50956a2c664e9cb7783dc9dcce718daff": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289be1c575e4d30176199bad4b2fcf7217a6df20f16": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289163e5addf68d6e21695adfe1f8fbb33c78d9cd4a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a71f095a32e886f926f17c350b1dba021d00d50b": "0x00aecaf4c90900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c8a8d6adb510e76876d66dd0ce3abae5e37781ae": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339756da5ac544ffd544d8c78afba72665b79dd1b87b": "0x00d22374f95f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cb8483ad49c7987e37dd191dbc834054df080000": "0x680f6ff2de0a6401afa65d55ba9bf6f2cb6043914916950ad51e3eade0f0d67700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df73baa66d4746e8447877fe051d6dffa85811dcd14c6dceeb29e011b1514f23e": "0x0022d7796a2d5977267948e5ffba8b9fe04c3da5", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339791ea6ea479dcc9c599dbf6a410cc7ea3798d3351": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da06c4e59af8d86d8b552887762255c830d79b847a6648210ca6b24d0dbba0e2d": "0x210f50483da86a563e049ccc0e261835a63b98ee", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333977f88b00db27a500fbfa7ebc9c3caa2dea6f59d5b": "0x0002422ba50900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751afd27a799424910c5bfbe69646a6f87cc8b73d": "0x00203d88792d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9841d92c40dfe289a0ad0ba13bc970838226f9d9baf089655588eac023e3b179": "0xe48fa43331d29570366a4244398aeb56756467cb", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc0b8e03e1b852120a5cba39dffcfd8dafd1a882472200210c3a8e6a51bb1c020": "0xe0f3ca995aadd1438b56bd795335a723114ae98e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339726c96b604abf5871c32e63ae7be295008967a47f": "0x003ab9a30d2400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dfc0d23727263d4adb6de5b630ef74983623192544a7d3c523211c46b2ffbfd79": "0xe087bc674e53b1b48ca0d8bd6691eaaea2ff78dc", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900360778f53e71ee3aa3ba78e9b6728ca5917b3b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da44cef17a2676c816212c314fd6b6c46fc1c3d88c888188a0bcd272e25059d3d": "0x00bf2209a10d9ffda04bf453bcb3e367f3eb6756", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c19f28184295a37171703d21b242216a1b10ba3c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979a94771e7e73f9d8d6e880cfb12cab4e9573c45e": "0x0018b092324802000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900eb8e47a06707a3dfb17728f8961009adb88eb8": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4ac3e0cbc1bf2889a7d39e3a2d4f3f1a2ea203367207c98c62a0d7fddaa22510": "0x0051e28f46719ed3e65d93c5c172bfe0ed982b84", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895140e3aa403d274eaa6f6b4af30e2c050c1ec8d4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003cefd9d6241b8d10bd2e4d9047f6174a4ddca6": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7a793f1a32c34ed50dad1a047fd58ba7d6babcc59089bf1c8525ea8c9d813046": "0x00ac0f75d0d139301dd8d666526b02234220b14a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890dc2c13dd88f9aae93a65e7e24b07a39e1d94ed0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894ad2ddf4425a05406b95be23d2d66c1b11844c28": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d98fa099942b9179688793b146505935d64def65": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e97926a75f3f203a4253193af231d3e778080000": "0xed57d5f73180b6e247ca3f4fce025fb1a82459d86527bbaaef28c2f4a4eeae6900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f8edb714fbe38dad3e6a03dc61fb36fc4c37114": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a5b68dd85f2aff5bc60ece004f36879399c242": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d86dd8c48657e9cb0e83e44d630c8e1cf761e9b92329484c28fe6649a4b7efb5f": "0xe0237d930cc0e0748cd9f00e95d88d25de6165b2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a48d6223b001e03cce2b775a968e5199a626434": "0x006c2932302b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892aabaf50bdb0b288e642f0753758ec38ee556567": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b1e522a1fbfe27af28b0f198775fd9521588000c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892b4294fc374566d487008f154cfb6701ae636196": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900472a26baddb79f1149a9589a132e5e0f762253": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890d666d51a8d222c2065f611e6aa7d4c8ff4a4bbd": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5160c9c965b3293e4bef375851e90f5cc9ca050000": "0xea5d1906782ea18165f17d2b7cc97e996d9f08f9f35d7226505fa253892a431100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b61eb7bad145d2c220180375b327c7cbe0ae9a21": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f342cae012d74fc3ecdb75e04e3b957101040000": "0x6cecea2c48271687c926a72814cfccede993dad2b803ec0d546d2bafa586c11d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972f60e0b4d918fa51fe99ec04b7b0f952fcbb7950": "0x007a4b0e500e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895bb506f259835349974c5fbf0bfd5cbd37157dfb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007fd348bf472eaaf68e58f652c082b86813bdca": "0x00e022299d8100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007fe28a2303b0943a759b036d56a73b48bd3164": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f61e40add6b7b887ffe8792aadcb6433d5209a4e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397058457cb480231445486c786db63ead914b9e1d3": "0x00009573c24800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0e5da0878b3aa76231dcc38ba1c8ef7308df8bf3d50496e5d52e8ee76b9b9655": "0xa9409db5aafca9b68f43dcf38bf46d460079cc3e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc4bf2d98b12ab9b121713eafd468e3d1dd1338d": "0x00400f84b5a300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5194a51e4dab4d49c760f9eff8acd580f727070000": "0xde8f4427e9db9a35e0c832a3622287db2dcbb58b2190e6a9a697e867f8d5381800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d5162bef9ca95cab0b5469e0399878923131d36c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df65227f172a1e2e0ccf5238ba986c3ebe035b77f062ef04b43d88614cbc07502": "0x20275e007f9678e47a9f3c52ea85d68c24217a65", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928917e7adf544b8c6ab81cfd449f4154d14a61b2b29": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891bd8808429c6f5c520232fafa9dfe1ea760c5bf8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e8523b608cd42fc15c1ec89738a62fcb9e5a76": "0x00", + "0x2371e21684d2fae99bcb4d579242f74a8a2d09463effcc78a22d75b9cb87dffc": "0x0000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c47108828a0c47dabe79cb9fc8f87fa9b4dd3447": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289db64136231a5004bf3fa556667b26e4eccc15bc5": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397739066ed2d1718fd100cec4d9f347382ec6440dc": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397eaab1f865f5fef8b614c6b2468333205122cd5f7": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd0947083ab9417ea4c8a5e1cf759f3619622753fb60579c45dc65c6cdda10c56": "0x23fc17c723c870ec4bf48e71135a4446986b5d0d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eb8192767e4a432cf722450cdd0985d904e6b748": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896a37135f77421be9d9e5c15284188e9658207dba": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970054d65ed11bf1e5ca7f22799d64d88e7e5c38ee": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970183f3866e19384aa414dadfdb3f18395b36f631": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397967e82bac222eb299da4d0b3c47a4d2c69602fab": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397afd4d2d92a53cd312df6856ea9faf6b8d9f8c3c5": "0x0002aef52d0900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d10ded14d9cffc8776745dbc613da8aa7ab6a22fa02b9d1e929ddb169e8a5445b": "0x3137346f506a2d980e1b00a5ff4801ce702448fe", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cb895cfd442db4a3f550bbe40ea5e4404c080000": "0xda6b7380d10c98da303b571403864215b403dcb77b1d9183649278f9c02c761f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a777a85e56f533ee46eb6de0825678efcec56f": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df1fe9f7ba0feab9e47684d4006ed25ad6c441a1553cef62748545ea575392af5": "0x5d5c3f6832e88fd28cf40a1f25684b7ff99a66a5", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339762431669ffdeeafb1d3b071ceebe443011b8d6ab": "0x00946f32c2d301000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928994ec83fc57394504eb57001350f2b5d4e6f7c5b6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928996f568fd6311f0fcf6c8fb0d017f4b7a85f5dd38": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cc3d336002054a3215fd3cd1f00f08bcc494fbcb": "0x00f8bf551c9d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002f331dd9949283c6f9f9b1833dfcdcba874740": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ad9acdc0fd7c7e32f899379a3c56ca18a50c41": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e6a8d75bc5e3c79b23e45d6ff505015db1b0b753": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900bbb1ea6d7b0b887163d6e32cbdf53e87187cb3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289924c251902924c7dbd4cbf166d42757fb2d146cb": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d78fd3865bb8c8a833369aea5b5014df0d9e860a390391250f367fbe5771a2b49": "0xdd04defd841f7efce21f5c63f123baacc61b796c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976cc5d8a4f16d0dd7122bc1d2759703ee9013c237": "0x0018dc4ea44500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f04a8b3701556ebe9ff89b64058f0875ba4366e3": "0x004c44f1ae0b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002cc28b6e9a1c0757029c8e42378e7ce97021e8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e9ffec62661647c99718d1e2783261291a545747": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891b1a105919ffc05d685f342385d5aa4ff4260383": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f2a9c275221468f59ac010f639c06615bcdc8076": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f947f05d2b295c924a3e6058771180cbb75cd60a": "0x005eb12cde1700000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bce2d382ebe2620439203c9ad7b86d48ed070000": "0xa21f09d50a9e3c76c519e0f59865a8ff370180e83a6058392e5a0e64f8b9a33300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51be1f34fe35eda8b84bd60fb3bc82aef748070000": "0x7e6b597b7c166901e03ec2d436ab4de5185b7ad1a59795b90cc403612e17b27300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974cf7037aeb2962a18b2e08aa140f07cb53e1a957": "0x00ccf483926900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5158d8a7493e162d17c9f71f89cb8cbc38de060000": "0x62bac995e1409297460e9ba42a01bba4c01e2740fcaea01950402ee0a51f802200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2a4252f6d64dad6c3c4b8154a21c2103f6271822a5120cfa4725fbb7f7372c70": "0x1fba1a1a641591737a3ba3e7eb236d2cfafdeb69", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c4ea7d30d01e1d8438dbbea89d44d235a46aca": "0x002695f2b11300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ee43bc46973fb91459bbeea3c7f637c6efef128": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339792ad1b3d75fba67d54663da9fc848a8ade10fa67": "0x00540ec8632600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519d4cc1da6a0332ad3bed7fb48b553d26b9080000": "0x2c75b578ae2bfc003b5fca59f1e26630652005a07144bba9a75ed44a00fed75100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928928046b3cdb72ce8eac1e8953d17727f87dd6ff2f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bee33ac5520a2245cbf8288e768a5cc26927cddf": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d438d034340c787f15207a158d94c62b36dedf8c7314451d196b039ba2e5c6bf5": "0xe7465a8034887a0004d4ed2c4219c2f5c22cb114", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ad379b2518f722776a3b377ad2329afaca060000": "0x9abddb3e03b3abda683c57883445f02d6f6902efd36bae7007e1a71f37368f0d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe550bc1088982fa32049171142e42954f3294d4": "0x008435f8106000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890028a86e047f2fe0834d472d87728dfb50774251": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008e158b389d89e9f98ab781725f34f5d06e7ed0": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5ae1ab6d1fffe69e07bae35aa873beb9f1a4352134629535ddcb0a9bc5313974": "0xe0fb96e2ba70b2c330c297339cb535629f887bf0", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d18ad345b8bea4ce83dfad12d60239dcd63d92a7d7ff2b8e529569c8fa5fe0442": "0x38103bda64188813b4d890ecd742d389589525bf", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000abf987d6d132cd1477b2c9f1fca2ffc0a4375": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005325ce1235df371bf5e8671ba58f7bc2d549c1": "0x00c611f5847e16000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397799217756e33b324e3af7439e0645c0d65b614a5": "0x00ac0b28f31102000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972215457b391a2660337b75568ec05adaec457502": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976b80b7d073b3ed63690c0962d061dbd88cef4f64": "0x00e26fad98e612000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896c583fd0876ecf8c8497bbcb3f8e888f2ee1c214": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897ad41e9d6e1fa47f1f6bcc63bd0327009590a47b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974d300b561ea06abe10d38ad05319e5d2ea641802": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970446eed77a750a57751b3b1f294ed9a72945cd25": "0x00fcec52e30d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d62f4e441bde73fd9195635f4706bd275b8f28994a7b24caac04fee952422ad38": "0x002deff295e375a68734582a3ed0f7786b7e92af", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5159705ade22e03ade30f00a37b1c9f34d9e040000": "0xde880ff77037dce39d035916f70a67006ee696b9cf9b4de4c61360194363037800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700de002b79aade8d38abb85617f6dff10f60917b": "0x00e61c8dbda200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979d6b708f01044bc2d23ac51ed5dbc7563c46a6fd": "0x007e15ac953900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c4d620dd343cd3fe7c350707ad56680b4baae9a3": "0x0080fbbf800200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee2f123f672d5bce14e7f9dbad8cfc34146319bc": "0x00c6c5932b7300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928991e943fd3640f82f0b3577e796a9cb31724b7bc0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a44e6d1cca8226e718ee0b4f4edfa68bd3773705": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cc4b6ec090e357c968d6e38894c9e4cce1030000": "0x9004d2df7c89ba8d7d65f01056ce579d41a7216db3c8e6c28826aec6d6c21b2600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009dcd9ee2679e1a794297acdcdb9b325ed9f2d5": "0x0084449cfc2f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce78603c8966932919873970f15729482bf020697acc7b2fafc031cfc9d9fc1c": "0x2d7b42e27e2382e2d28e06bde9d82413906c6c03", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a99e74d6616ae317cbeef70401baef1383d287a3": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978acb047dc00c1633e89130375c964ba9b1e203b8": "0x00ee853eab0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d4e58becd5f1b09ee3876eb448f6a9b7fd75740b0b1498a73d53ddcc094b6bd79": "0x006dd904124038280e01c52b465f2d802b3c1783", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890014f112fdf769779b38ead59b66f955dad1b147": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928923acc3516b86547dc0096ec4a3447af0ea0bfb55": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d74242c09e3519ed1c34ec0a846ccd0509227c4b23e5cfa42b7a84d75a0ba7a53": "0x3cc9063e7ac5fa8345e1f59bc32a470ccd30ca6d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c923b032f3c9641cfcbc6a909fb66b29faa5449e": "0x00806aacaf3c09000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de4a6bc20742c72fafd45ff5ef53f7073d174aa51bc63126183ba20fedc251867": "0x5641519cc28def80d631baa28b949f17a6a22ad1", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e09f6bbacf54dcddfc5277a0355f2dcfe657c2d0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009325dfeed3f384e863c57455ac3d3c4809d210": "0x00d0e98a070900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928958a0056880f6490bf35430b081f49d2edf2b1915": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900099a01d4d41e7df0f2f08687d2edbf7884d99c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f4791e01db745246a89a9eb394227cabf8ab4e1c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dcc09076d5cbf29fd82ed31be066e2909af4f7af62d3b34007383e60211d4c100": "0xe9faddbdf9c03466a607fc06415ac3f129aa2dc4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900000a9c44f24e314127af63ae55b864a28d7aee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894ed69230ff6fdc2362113979ad08500065c83f31": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970026ec71cb407474b48df42a58a80618c4e44e99": "0x008ee409331900000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f4b93da8b8c241808d6a44786af6d734ee080000": "0x38e9e71e1ed6e521e2fc802a333996a60fa2581b1496e9eee3665ce0994a821300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f84b835800125e729921cb11f3e4becd258d7741": "0x00407a10f35a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824361aa4b596264f9e1eabf688567e8e80080732169": "0x008053ee7ba80a000000000000000000ac283f1100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db2d89b7dbf920e6cd64997f1b3ee49c4de09327342dbbba971a362062817a24e": "0x635954403448b9f55655fd5dbcc9675e8a4b8109", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978e6365a5dad54ec79a5411b6a8100d6b25f155b8": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700539df92b2c2e52a873c02479906672608fe563": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339726dc3a2b04c409af7f03783b000b2cc05020ed7c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f71ffc433df3a137c9c0a5cf08fcc3e4316e4e8e": "0x00769f7b7f5300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891fcec00a57e3900cd43cc6f187ad3deaaa27ff56": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518d9835b2f0aa1bf6fa6001993cfa75dc5b040000": "0xe4a865acc76e7c89557365725832e3ba3ccaabadafdd5f1a668ff74243823c7800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f8b4b80a2830d11d4843b980f06635530e993a18": "0x0060970a641c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d28a3dba187141f0d7d9af3d921cfc738e52f07aeb3eb5b7814bf0912fe672a22": "0x185d5cd827f66703890387d348a796cc8538d08e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b167f576f31f640d6d8d678549db0005619be50b": "0x00181b6acc0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a7f29211d50461588ec3c6857c9ca25474c650c7d2048ef2283a2245ceaa831": "0x23a7e13e72a9844787fab89ca269940f80ae76f1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c2e763a5924cb23fc77515a19ec3cc7e7a122250": "0x00c42f04c43b03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f7a3bb54858fdc941a3be7418e1026dcfdf65d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928940f264c803b913ce7769ab4319b371b95a072103": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c7fb76d905102fbf68a981474bd26e5fa4427790": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c238a08112b845f6da8affa118efb25721090000": "0x2e0efc13ef5ef79db8c5973c8d1956a63e3310b43014dc64187bd50693c9763100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008e7bdaa3171666718763a8b46b28415c256a8d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898e4c6d9d21ed31544cc123f5153d39fe65e9a9e1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900106ef113a8cb3c3a233553c4ce69ea14d88524": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c96ff8e5bccba1f29e17561d2aaf59cb6e38a9": "0x0088515494a600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5197ca506b2b319ada404819036e25b93790060000": "0x0ab234c65bd20f8ecd6ad7aeb23e025b168b7a91847fa048927e2434e3cfa25c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a2e3a0c50956a2c664e9cb7783dc9dcce718daff": "0x007c97c8d60100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51219ac9c0ab255221af97151243e360777b050000": "0xece71fba2046bf700da154b046b97359c83d0e14f81b53e33161e30593571a7a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5177bb609628ab4a59438539f18c4d6d2b56050000": "0x966ee7c8c9dd52e4650c99b77e62531cfec2f7611aa8b5d77ce28206faa3267e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f0f772504eca495a1e9bc3b8a1cec2b639c9df": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8621027cf6c97d46500c2978193be29b4fdc1838cf768057440793a5910dbe20": "0x00518bc639b1ace490d22790ae1ac8dc933160fb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974341633902051568199e6436ef96483c49e72dd7": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891732d95532f10ae18b2317ee75d4ab0981369f37": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a640c639421c815ad2e40be3ed98ff0eb0e446b4": "0x006897abaa5400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895ea3c5be41a73bd49b97f4cdd3eb55335baf03b3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896a6a46f3bceaa2b9799712e1d4413ce08cb8a801": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd00f2a04707472db297d54c9ac7ceaa6c6bdd05d1c12876d7ab3464ebaa20558": "0xb2deac69d3ec9489812479a2994bc068d133706a", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c417ec8432a7cc95fff6a7efee0d97555b07caab": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974504eb623e2c8ae4e61ad147b13cf978aef376ee": "0x0006e8c8f04800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0c5aad719ec7f446020947e59a75f4ebcdeada5f14a43fd3e4e2cc7ae7ba0053": "0x141de041d47905ce043140c61970a5a28ca39879", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e96cfaccbc1ed061cad3ed70efd8dd74316a9b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e4992bb3d86f6734af7fd1528a658f8484936b": "0x00a6ffa0e4e304000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979af1322b1526ea42be721916e6ba232b4f001fd6": "0x00cc6bc2f1bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bffbc05987709ade08d71b36d7e36fcb7a613b": "0x00e49d354e5e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896851cab6bfadfa47246dd71528c4d519aeb85fd4": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892a89681d73055acfac5c4ce4ed108c3ea7a84a59": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9232d67619fc452fad6b32e2bf06d6e1265a28c09cb6e10bc48b971092ec733c": "0x01ba3841bbe358c1b3a9310d84ba98bfac5fb318", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397445fca1e2473f0c47938979ee2cb469aca9d36b6": "0x0082663a29ff6d000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51192683c077b870422fdc89423a0d9b1546060000": "0x90592f98c1e649196327edc9212c1dde53cb8c8cb4ccbd7bbe360d0f2e40170900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d42804d00b39843601a505a8bc5f29dd23e9ed0256aca3cf207a7c9005c6bd746": "0xdec7861534b86faa8f8ae36a561fae5277da4709", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928929bff29d8193e551e089b3aad1e3937882fd9d3d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d707c94e3ad62ed919cf1eebeffe3381161c4daef849a306d698539931a08ce14": "0x656dc09b4dc821695c9de996b762b3362e00a205", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510b7c29cdc876b13796be8ebbe32e10f8b8050000": "0xf45007634380d0945f4056026a04e2f546df29985da61753b225409fb8f4262800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517d0cd5cfc129a18c685de96c8d269dc64a000000": "0xe8c7ad65c15fa3ba64424a61b177382a0c5468135aecca9ca454f5e7ce4d305b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a002d19522440cd4af9636097bd510dc780f8f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f77fd2297cb28b7a104f3f4d47b19a50a1ddd451": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a57844f09543679d27a8f5ce1b6bf81bc14f021": "0x0012a3c85efa00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894af79369d49d03b92400c3b67a65b694044ead5a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d5162bef9ca95cab0b5469e0399878923131d36c": "0x00ca0a717d1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bbfb61f18a0949a5ba261b5a7054c53d5b3c93": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e0e3eec80e1f333baf219d42661731c044052704": "0x00d09172775400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f3e809c51300ca5731ae485be9885098ea8139d0": "0x005ebeb2030a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928999d1efb41a2c5ce8d000599595f598e6ae9a8356": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516c325e3ce706532f3b717bdd1ed6b5f412010000": "0xe02806109b735d8f9144819353a1db3dec1a4e9d44abfcd6ce67180c02e4ac2a00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518d3c2f4ae8dc0dc19f736f40a615f1c026020000": "0x4410731522e26803b8e6eb6e5467d77aaa050684b95722bba660882c90a9d01500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515a5fd6372e4a5314ea7779ad3cc62cf4a4040000": "0xcce721bcf2f83777132dfe3a79be1bcb76db9b6e0deeebd3cc1adbf1b8a1286400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397226c85b4f7e53cee040b6d2f45f4fddef5d97bee": "0x00d0cfdc8cd700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003df8ef68083daaaae470187267dd53bcdb133a": "0x009c3f425b0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974678b10000b032197ae5a403058cd72096198650": "0x000af7ebba6e06010000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893890a960391f2a35e00e7fb86ddd1637b0d5ace9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000028ce0fce9e53bee386adbf4d175062b20fee": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5100abaa29210df0d8c56d796350a2d268cb060000": "0xfc5d04e7ff3965c8285a2c23aa573117deeed886bbe5e3be0974f1cf0a2ff21600000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510ec52599fde54e2277e9e36639158668b7070000": "0x3ac8adb41dbcf04f2d67294fa621940d040400987e05cff6326b1318939db15900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dba58db6c7bfc75aa2b8ec1c9b2624172c81f6d2391180047091dcd0cea5ec45c": "0xbc17ff2de0b6577aae386e5bfe8ab7695282a52f", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513f48a4049e572ea867f9332705d8ad90ad020000": "0xb6e0bb21fa812549e3f75b92d433225455e299a0d106a5d0a1a5867ef5d3a37b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df4015230238cad5d18740a481674824e976409255571cdd91c0ba9a439b7544a": "0x08c6c136fb974c8ffec3b38e8d053791a048a0b9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a34c6bcae6f46ac6470443ccea67d937f6060c7e": "0x0062844325d300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b4c9db39245d9386585a1008f730224cef030000": "0x42efa2e57a813989da4bac4551e4010ee45003fc3f360f5202a958b2b1a2991800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5122f39e59fa4d80f72b5015375df0c56ac4070000": "0xec18887a19369a1c99fafec6d8e52b3f6d0a1af6abdab0d0ca49daa56bfdbb2600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0c53bca5a649c275c951cd479dfbe21e6c4bb9fb9c94dc3fcb6a71410825f632": "0xd8cb03d06e50b85644026da3e510f15e39e65efd", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d54dc905cdef051a3b6bbce57b6e6c5edda54bcde2f34d763dad9e179ce042a32": "0x4daae42c5e89d09da39cb90f81bcb2acbfddf67c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ad2f45a879431ad25fd8ecb47119e20b86040b": "0x001428b7820700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397441dae5199e8c642556707176913c2942b455251": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928952e55f169adf75007081d795987122cf82af8e2d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289be7f0d32ca1cfa5d95b4c10c960a088f2080a508": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee48f23c4b73cbfadebf37cbf7d73fc41469f79b": "0x00d6c0fd102d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d545c47306c568ac5e74d5194126702c63a91639425146deb45671dd6144ef86c": "0xe63bdf498cc6781799cc23953e32dce295a95a0f", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512d6538b75305db26f83b3ae0c4a084ca23090000": "0xc2511b9ebf609e66a3ead4d7eb980e9f0a6ecdfea9846726d14e45d29579207100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df46963643d40844f90c6d1b927d82f67955371cfb3523ab6c272e22a66a92334": "0x0a92d58547d1c7a1f0f340e540267f278011ce0f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289dd41dde058e870f4274deb8cb2417eef04940f61": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514b68e550bd16fa4eb661bad2f583f6ddfa070000": "0xc8ca8ddd21b83ee3a70faadf02745a57659bd0063b8844312300127a8988c10300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ce270cce389cfc09984e1e97337eb7cf1d060000": "0xe2dcfc052f7656cb9e107a9c2d0adc19d2c206bc51e3225ffffca10b83b8c21600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898889ff5b6323e71c28c26d2c34b8bb52654f00a6": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5195b18709044900f8a04d00ee67c895845a040000": "0xc2b8dfe759e221edee35ecb51b15ec454425d1e772d224e2efcecda23f7a3c5e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2852dd1c93302c44657e8bab87b8c86a550e18c4a0dead775708bd6ff909b915": "0xee213d531429838906fcd09e48b7a488bcc501f4", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d510b448492a9fd2771d789bf037ed4e15ddc050000": "0x662d6d64e01bcc5f3a54341ef0bb1cbc022105de37a80558723f50a59ff6895200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b0ed4774f5cb36752a3661f8248958418d4bd1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003c6df13f3c95f12e0f3e2c82e3980d9732558b": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b9be94c7664f2ba9c444d7ab2980bb6d2c050000": "0x502937e1a131cb6646bcb72d521c894d4d3fb35f1da1c44058b7658d8d299d3600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971330b7402f677e3adc774d13164ebbd9066ce181": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e49d3022283a9fa6d64271c2f18813d5250667": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db8e2b3878594576b6226e0050abcfbd96ec61db33f60b5541e3adddb3eff284c": "0xa228f05157969366882c78be7c434dc3d66b5b19", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890097788b27b144f03715621ac2de4aab5b94c158": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d24f8b3dbcb13ea214b670cb611fe7939e20a23db19647485e01206502e64ef7b": "0x0f6550e2abcd33b14be0768e4fa62c66fcbf665f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928945d094b1790602ec766d3a81701f02ad99f3e954": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ed2d649d7c8a8c8c62368e42c5717df2af5e1a33": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282431fd593bd99ed831bb189c73ad7290501597199ac": "0x00407a10f35a00000000000000000000062c930000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3e2a1374cfa7647e2031be60fcafec5add32295e3f65c887654f80a215ff7711": "0xc7f440d4c45c1ce7a295c788d9cbea9ff627cf8a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002b8afafdbf14bd18a1ee36bfd45a35adc783d7": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de827d83f5b7fa514c856ca4157b894148a5a2d7e05265b449422f88213d9ea4f": "0xef398a72ca7e9c352d14aa297c5c59f604c43bdc", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003b872492daab5764157df79e40d853ebbac4cd": "0x0066497f817f07000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a20a5419f34167dc1b4ed5a22a8888ea6773520a": "0x00f077ddc02b0f000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397173ba35fbb37fd281880645a2e7f8e18ba38de0c": "0x0060b7986c8800000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df804000000000000000000000000000000000000000000000000000000000000": "0xd6f5646d9e7fbee7cc907eb8e12dafa5378431e6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004e1d33f9cddab664a732b7eebe2a80d04ae413": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892967ed7db96f71cfff4626dafc29258e337a26f3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928957f0c073f9954b81dd7de5d4b33cbcea46500d8d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289aba74c2bbedd2cc9fbf53faea49cf1080aeca487": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289004996dcf23cdf72b62191ac358142615192c7c2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f6b8e05763ce13e81917c0cab8f724194abf57f2": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3413070fd675fa96164a98442f0cdaf50d6e70c25de43a5268f987f7cbf67426": "0xc24318e1ea1b011a6a84d2f83436c77bd753e840", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970013e7914c4e0368bb75176c58d7b85064ba76af": "0x00f6fb67c47c00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d416cb92370732d87025ddc68f01a6d449080000": "0x7addfa612b215eb31656bda9898be79259e308ab918ec8d61364fc1e872b47af00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890033d8e0c69970ce4aa5402658135a4977e0948e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339740f0e17c0e8d725e985840198edda545fc3a7162": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289152c7b351851c158305f51bcba4cc9570259cd6b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896503fe6dc225865a54dccca75e9410f53a35b137": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de81caeb02e5b76e68d008ebbf4e3b036b570f2d4c44064daa5d1b5efa0e5e052": "0x2317fedd4b4af7c3b6fd14cd044a2acc92ff15a0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700642d51e2ef92650e2c7308b4078864ab0d8603": "0x000c58bce01700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a0d9967935116cdbc4ca46dc114bd175c7eaefb8": "0x006677ef716501000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928948e9fc7556146598014c9b9a4f258aff8aec463c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae43aa58d1bea3f6cfe4741001f77174a074659668bd6a8ad6fffb9c34915a14": "0x008c2651bfc939ffc086fd5b5e598cdc1d662c97", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974cb26d4abc32e99e107f1cfed2b07bbadd425b79": "0x00d0ef2636a902000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900554019bc1d942aef1cbf7ee6becdab99ca91d7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289027ed05be029f65a37ae646f349adafcc9758755": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928943e0c52f9a3920e2f8c01479fdba32a8115ad332": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a1f84545ff677fdb54d955f707055dc70f05452": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fe41c316e87c3c4a6e85c965cd678de24e09bd44": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d20e5782fa85cb47b81c3eeb5186e5d5a8288c92e1cc9001c16bdc6a2c194cd4c": "0x5a6ed25e84058c2810261558ebc593216aa8d1bd", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003edcc4d34cd4a22b85b496aa33defee0ae5717": "0x00920d70945f06000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397560cd6b5772c69efe8c36ec3e1f8af3b95c66b44": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890098b67b82c0be8d4cbdcaf68c96a1bce7bf61fa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c875b446639ca898f1b3addccd107b9e1e2f09d4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289df677578eb4297cab4fca1239773f757a4d13a01": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9446b359ee88fd32037b052b4d815ca777566ecb8cd6860db053a7d4454eb14f": "0x5a6e3ec695183eb5c9808f550fff6a29d2f40de6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a0094af5e7a2d052f67814b9bbc799ad6ece294": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700bc41f12063661d86d9df79c28c9a360782b478": "0x00a8b5d34bc800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899955dc870b36c6ff8c41567f6937f8277b00769c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5110572f8a179d542e6146940ac83095b8e2070000": "0x8ae76cc2cfc6f643aaebc3391da915c3e722329b4ff10bcbe6fbead4e79fa56c00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5134258e533fa096dc90377bbe390a25e744040000": "0x1600e09e1d8a1324934f83d55d5f6f503e2d91bf4270eeaefd462f24e4487e2900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928974ebb92f67bd7a62e95e8129177921c2808b1070": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f95ca3e58c701eff23bcacbfc3c889ec6dc4a8ed": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c5180bb2f2975ce4750af769d7a32dcbd69d39ea": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009bae8840cb3906de25e5f8b9e89ee6cf7eaa43": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002128dc2b569d5765ff40f2656d6d7b91422c58": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ddf8f475ee3b847117ed3df673e85c8b4593bbf3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ca3dd8080c9f217c9a1e0820c39e31ade0dfc0b5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a89a25f5651b44a4e9c99f500a25d503e0070000": "0x2e16ac66b63f96b1d8e9e3b203c613f9f246385e3571bd7730f793f01c66815300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511b8b87b90649256335409373dab8f36983030000": "0x8a0d544a89df376af974b0fb1a1bc47b43d9668d910504573466f70b5d39150700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51af8357dabfc8c7a80891fda8751eb766df070000": "0x66ea46144093bd290acc67ed188e375cb13daf3f329ec5898cd6bf22922a363500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928901bdb7ada61c82e951b9ed9f0d312dc9af0ba0f2": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c6c0f1c8825c7ea730b6fc23bceee8ee5a8389": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891221d505ceba3ea8f70b3324e11ee7eae3740b93": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005ff4500730a6a2a32b6add8c27abf2803b3bf0": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bf1a4bb27ae3ced0991a0c60d49adffaa014779d": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900882015100d9a8165e33467f695de68d115a172": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289984af7d5fc49ec8bfe113d542f3eb2f8e2551dfb": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289005807b3364cb222841a96051227671f15d1f502": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289458e55f31a66a01be0801221777d1127de93f6d4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ccda9de9a7a369174a04ebfc2d18faec1120225a": "0x00864900a51c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970072ffb8069bdd4f791fbf9352a7226c7f46ecd9": "0x00540ec8632600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b72b4ef3d1bc5158136b21f91e44bafdcb8faa60": "0x00d487ed9c0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f0f3afd02178ae1d3e34a7f787b9b8a07b937295": "0x00021044ae9920000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b434e938062f321bee814acd82270acf6844cca9": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890093897717316daa87a594feb918503d7adb5fb1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b305edc645bc99c5264c16c8c9227762c59043": "0x0066a69b2a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289739066ed2d1718fd100cec4d9f347382ec6440dc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397599266e9b5c0983b9f68f13f1834fdac9c2f0ff6": "0x006ee223f3bf00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c5487b072dbf2029b3afdff0a077f531c6060000": "0x6208d7c4e716bc9605f4eeeb26a73f884f9cc17f2bbfec39364ac917c716f14900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289401a887450b7096d8ec6651e15909d0a34e1898e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899a32c58cec6a3db131c52c9dd88d7e006bd18bb5": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5187a6438ac9dec73642b3ff1c1185b91df2060000": "0xdcf77dc7b6033d7330a9d9c3bf666cdfb86362038400f4776da8dfdb03ad8c4900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e8fc0738b7450ebf2b496cd15652b1805346be72": "0x01", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900802eaceef7911f5ef5884174357a13de4b63ac": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4c51165f7f13ce32256492d88388901cf7e615f": "0x0014ee4b971000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fc29a37e321f816145f9645967ab5e2a87d8b0ff": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5177f4c0d755a1eaf6aaf2d8930e1b4f3df3060000": "0xc2bca81090e89e309ec127817a88dd595f2f3b370c1277ee11f5334cc075122f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7eac235c1800f3301e452f50a8df7a6f82f6192": "0x008053ee7ba80a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974036ce05f4b3f7254541e9f50f56247cccafc14e": "0x0060a48df79715000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3e5ae76a3a9b417bf426cc6197998bc4bda848e6f01bef81749a51af89cf4031": "0x68476977382d9cb85d11775b79252ee7d2859738", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397daec98c63f553f059c024da69f7becc810f8ca0c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928923f9313f69cc340859fdd8afd5d69f9298fd295d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c616dcddb10148ef5351b5b0c272486d15b3f629": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f8f3088978f60f5a6c1992b1b3ada0f228cf47ac": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ba1b9304ac4cc7292dc263ed814df01af8060000": "0xce856779cf6c02521d578ea679e1f013b277dc334498cd252aa76f9b6bb5964900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e9bc7845bcdf580a95687ae90c37e0b7f995135f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513ddab6f63d18c9f8ce476e51524a318c4b040000": "0x2434fb99a4b3f7768f861ffef0a7dbed086174caa733acd2cdec25bbbcdfcc5e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974e09168663a2a36b3b066176f82df10fb615f4b2": "0x0010b6c8f94b08000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd401f460e0251ed41d7fb32ca463b5233b620cb9569eef5327def27fbd7c7b57": "0xd8f13d654e51f66ed93335d573ab2da1cdaf832d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fdab49634888d5432dd9f4718887fdc69d27f39a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d515652d2f6bbd21a0695c2b02bcabf61593f090000": "0x2806d2821e7ee92952bd25fde83ed76930fd5d1c7139fb9f3742991ea3c3e35200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894c6dd54d08d5e5db12d90baa03045e877095fa5a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517e5162eadf0a0227dcef05ef4d4d357de9020000": "0x4ad3e041b7b94a6ada8197b9bc9c554bc747d53c5b2779813597ab0939fe585f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a305c9a9b3472c011628c8a7bc59843a88070000": "0x7a793f1a32c34ed50dad1a047fd58ba7d6babcc59089bf1c8525ea8c9d81304600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a4841dd23a0c6e2069f543be8dd5db5442f62cff": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db274417440be5bc8a904a2ecb75d78bd678850e2a01a7b260230848f4231534e": "0x95009f768050dfb14ef9ada842323c6349386972", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0e60dc2e716e841366dd85abf1464d4d8a7e27a1a1bd4b7719f5c26877c52e39": "0xa07166eb5793a0f9d60a9adf056b7e4fdd2eda73", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a4c761977251e08c56f9865ecdbc530df99adee7": "0x00e87648170000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339771b183dc5834b02237e996efed6933c104bc9292": "0x00703874580800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289527a1247054d4dee8fe4720990dd8b9154225487": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f17cb2d4f469ad4776a976ef606c4a871c0677de": "0x006044e269a307000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d500774a5e6eb480dcabecc949e4c2508d7329ea62a1e68aebf76b819da6b864e": "0xcbd1b6c83908c27f324e5cfbb6f62d27ef9e27c4", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fe41c316e87c3c4a6e85c965cd678de24e09bd44": "0x0096837eb52a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893e08fc7cb11366c6e0091fb0fd64e0e5f8190bca": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e9b42caff12b77d5f8b3b291d5d83c4f86060000": "0x7cd6988ebf11799cd1e193aef0c87b6475656d42572eda38d962e05c76260f5800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9641374a4f6f48768d9a6bd815c31807e4765251a974ce0b0c75f2382086fd35": "0xddcb32a75577e9a33c2af218bb8209e96f92627f", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897ba835a2252a188d72be311ab7dcea6a29eba4ad": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51afced508358026f35c5fe8362eb4f94188050000": "0xa686df428ce6fef4c9888ec3b9934c66ab1a0c1b475c22d5ef0fda78a1f9cd4c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2259051e6c53d3a07e28073904ccbebb981a4afa2df4ecc48f2b2a6a89650778": "0x009f33693d1d3fc5b3eedc3d9d457f77059a498a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397643ee88f0cc3872eb8d2092d43c3220e35427653": "0x00a21abb8b1f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7225bf2a5f6b10dea716b22a85f6f1fe23fb44d555f435e7e8e31d13f825c536": "0x007e917588d7a1392c3604501e00a73565d06845", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513260fbafef1102f3350d016fe33476ddb3050000": "0x52eeb0775a35b135b1cc12b0c4234db95f5a684bc6553bd94ce177914830941e00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d460d54a173ad68d1a19c047550b679df7070000": "0x2459105748cd16d4f93c3166c7e4118d762ebccd0cb41c924236a94a3bfbf04200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f23f6f305b8fde67e5adfd6664d64c887f030000": "0x68b96498d1be734042e4cb74d95fed63cd8c08ebc7dafde5564107e1c1a24d5500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51da4273cdb774f1171698e97b7154fa90e9080000": "0x2a7942832aefac80ff43a6842bedcb6f194094474d663ed88c14a940dffc426c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289516760a6e0a4f8e3683260c1b5275ac0b28992f4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899a27e4a44e3633f546f8af7fc0acefc55e58af5a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700beefa91563f6c652924891226981aacdf88834": "0x00eca5b6716f08000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e3f51f35abe48323c6734d1f83342c684225ae": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700c020f030a93bf6e1836931274ecaa1cc958683": "0x00f2eaa9050f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002408a2f9bbf1fee7a53eb361f8eb2ce47aa6af": "0x0062b4f104d248000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da653655826c606e95ea798282f0e700f22d9669ed58fe5279acc79f03f2fb341": "0x5acaf60782e62269ec264824dbbb13f9e85d71cb", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009978d735f1a23bb6922b620c490ac4aba66cfd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928903224123bd06444350b7d75e2b080ba68598ddc9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896d82fda6e5d6dedf42042f3ddfa2b78b152b6402": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c24318e1ea1b011a6a84d2f83436c77bd753e840": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddce017740d3a4d978b15057144384c96e46691410218ac91cec8be4f7d67977a": "0x963260139fd90579c3a8a16292433d4170fc23ca", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa79627160ce8dad4d4619e0c5dc2890254d56b03dd41adbe171d38094b3345e": "0x781088752c0d882ad057dcb31dd0d023efb8d872", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d520aefaa9aa8f2c237f96957bc1858cce594c62126484c3cef56600e11580a77": "0xe56da5dcaeafaccb73e526f3afac2f48cd0136ae", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900345e8d6c2fbe70fe65954937ef335cfc092cb1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700db158028c2d7db707c525956aa3fde0409eca0": "0x00724f344b0a05000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2a8c3c2f2e55ac470078c1021e3f8b77d106f62f7282799e765f75f1723f810b": "0x000977634918b6483ebdfb23a3e68fa322f1da1b", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970352804a070c4d94d441ceb8490ec619899f9e4d": "0x00142a8aecdf01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900484a2fe88db28bad5aeacf9aad06c476542d92": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b32816c1386cf0f7d5df26b4ca5921730c6f0ece": "0x00c0206bc81602000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3ce2e3348670207db72f1be4076a5725bf3f59c41fb13c5f6e585ebe4ce6497f": "0x438ccbd79f20c1e68b828211ec2ba30c0ec9c05a", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d81d2a92dd5f2b6ffe5fec1e40595cfa0dd456ea74935fffab3e5dbcb2b141352": "0x8f7c2327fbd51bb8040c53fc64e3aa6df197c9c0", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec037e3865c948398bce3cac6e0a3af1a87969b5": "0x00008a2cd1b701000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5128cf46e92f592757a8b837809ba340ec51060000": "0x583ea20f5dccc9c80dfd745123651bab91e560b74a672f2f2b3dc8f992346c4900000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518ff048a1a67ed167cbfd961c4bb7ce495f080000": "0x847c474dfcb41662f246b6e223fab3c9d17832da63304dcce5202f7aa686574d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518d2eb150cf5d8b4ebb9133d597c11c2ed5040000": "0x82e5bbeee29a5fc8ec9513dfe2089ac32387a0d72dd85990a887f9e4ad89085500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700250aa807dbedae13eff449a8303ac62fa0dee6": "0x009e7961b21f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978ae1a0bd06aa351227ec269277a43831f0d34da5": "0x00da02e30fe310000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970056962a7b6b0ec4c917488d06892ce34075218e": "0x00aa63c979d100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892a016496ded64b9724a571f0703892fcd5a0ad47": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ee13480f5e260b749022ff1e533a22e14e48c083": "0x004c4cc09aca00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890062bcd4cbb3f4501caa19a2abae06c7dad957e7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890086163e3bd61e85334868c8b1a2d65d3f244f6f": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d0c2ead868626ace5a2389dda1339fd468030000": "0x321bad8be173fc114055f9aa77859f1befbf589718d9cc6dc4b801fd0e675c5700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daed7efec80092410d5bbf134d29e673e1592e2b95bb7fc24f84d5121344c2c29": "0xdfe4c9aa892384176066b2776c0507c17cbf5099", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289383f42b5de515c564641f65f5da3bd8b4a35b4b4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397802b450c936ab1849243267995dc9aa45f234a48": "0x00e094fb1eaa02000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897c90efde43639f566ed43d95d9f909697245acaa": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f156f0e79a516f69163743f87e592677fe3e74f7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894ad406dc68cfab9920f00f2c5dfff89650d05929": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700449ebfbdd1a6e11dc4d7b458d4851efbb06778": "0x00fa5354f60200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397af770e8cbcce62a1a458739a4ae0811c72d33f55": "0x0066497f817f07000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ff573d34af66eb169195a474ac9bd88860060000": "0x0f2f9a1ba9bb89bb9f415a4c237a733a5d8896cd766b4bdb7343ebef0687260d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895dab307d07dba5375eb40ac1f1b285c2d8307b03": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5147767bb710d1a631db7a2b1d32983b4352080000": "0xd6e1166e5621c7bb14591fd4530a0424c3089260083b087b9d77e2cec1bc31de00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3907773de2b12033f7196b9517045a63315b4cd": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008f6eb1f8852e3ec09a2a33ff19e4c7369ea37b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397470959f6872985a33b5f5ccd75bf2f8a407691af": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d518eeb67887ac45edf57c7df3115d9272426060000": "0xaaaf1b0d98b3fe0673c0cfca35d10d99e198d97e8e757b3bfcbb6b7d0fc0b67600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890945c91d5ddc3cdfdf7fdd45ded0746d0f31296e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e8209f6505dc718027be561be842318187216bc2": "0x00500a82d0d400000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003850a6770db5d0bde4dcf7985838a12a1f4045": "0x00188d22dd1400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928992ad1b3d75fba67d54663da9fc848a8ade10fa67": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289be2fde5ea1a064e4b3708f35c269ac5e06c3eb7b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928965e01fd6abad727e8726046f5b55b25ff6bddf92": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dae50b8775cc2cdddd86bc443fe42bfea4e801a316ee579264cc7b4d54bad3307": "0x4dda8293a5da4a6021f6b228845713ab246a8607", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d07c48e25485b727193d8e1ca5b5a2f3352048f2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f581c3646c7eba0b95e6ad486ee48c2be833b660": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397009b32198b47c8b8006c0c3483ba90a7fa18f8f2": "0x00d4dae9256400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0d243a2e86fd76e56fd99cde8bb928ce3d140f8": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513221a387cdf1f10e067ad3fbd7d29967c4020000": "0xd07fcba81f01c46a75c6f430ee4938322ddd3340a460aec133b410962daa304500000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5180ee6d7af42d06c6a13e4655f5822b983d040000": "0x0867efd74f0e185120843b417f4b62e3a937df54007f8b68eef468bf97e2e34200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282430089e3121271cf650d27633bd9693190bd2f69f0": "0x004072e62d2d07000000000000000000a7df9c0b00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5130747856aae8e0afb9d8efdd8aee98c315050000": "0x9e40ca7bd1fd588ca534ee6b96a65ca8a53ec232dda838cc3cd2bd188790490600000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0f2f9a1ba9bb89bb9f415a4c237a733a5d8896cd766b4bdb7343ebef0687260d": "0x06d2ab1ed0c25b0629d277afd6fd928d232d41b2", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978761e0dd63d14cf566acf4b730f3540f164b6b56": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c17d9bb1ec5b9baa20b7d0b4d90aa5643ca1175c": "0x00d420f4be4c01000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dba19adf8ab8528c9f53058b494b6154dde0fadfe2bdeb3a9b9c87761cdcbb441": "0x539f0f7f1e8e7aa08d822213305eb6e40c09ee44", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289009b60368d141bc267a201d3024cd8c68c5968df": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b043ebcca29d4a6c8ba1dfdb75fedad3dac2a5f6": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005b2da8bb885172492b3f57a510e3a90526c637": "0x006aa028eee502000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339752c7f3fb2a8bdc8f2d9cdc9404b5779108d4ea0c": "0x00fe189e4c8505000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e28c5e4c6891afb0df739910c733766305cde69a": "0x00eccc45eb0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890584e184eb509fa6417371c8a171206658792da0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979edc6ba142d75e9662cdbdd2224773be20db4260": "0x00205917580d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397efe2bad68fa91496e13adadf87568b1fc3b454a4": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bccda47579963d17ba3becdad1512e02aa9fb80d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7e1e7b99b256c9faf8acc6fa17a1ad3e6e30cb99ca64df0daaef71735f21b07e": "0x8c723d6c9f5710dd0cc7219a4658f09c3f5d9928", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890013742c72bc005ef342eb367374d089ac6dd481": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928906118f0b0b10db4ea349c972900c67fc44d54516": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282434af79369d49d03b92400c3b67a65b694044ead5a": "0x00203d88792d000000000000000000000396490000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928922e00a49eb33d077e389a17928e7f7bbed4fb938": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928932fc9e119218462c2171fa5bbd554979fb7a3e74": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fdbdeaede3cef361db915f912bcb676475074f21": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928972bd01b74ab575b2bea1ac2f8112a0a15cf09deb": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700049f62287af249ec7e0afef09cd6d6d708bf6f": "0x00b817faac0600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339742a49b7c7a88907053060c8011f11c5d26f2db8f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972a8dc8b6ce13666fe5c2c56d23f9831a7b61a13a": "0x003644e1317705000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e1b93424c6edd8536fa71891923de5766fda9a9a": "0x00bcc1fbefef00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d72f7dd3a2e7a78481494856d4ecae073b7fe731495cc78c9b100a2775f59881b": "0x6f229ac4cc64385aa20b2cf7f75a9eba129b6711", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d514eea4d85c176ea8828cdec479385b3c275040000": "0x0663c63fc812a1d2d5ec872f1f2244ba474f36cf28dffb9c8197e87ab4f19e5000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928908548af3414d04416f96f60cb1c39dc8ea927b4c": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1c2a5f648afea2a94286c17f6c60d16c9ef8511fa4ae88a54ce2748b6c8fa90f": "0x22a5afcec732df9e65eb56c0ca7fab1c3c26e7d3", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d0d62f0e012fd9cde4c2b255305228fd4a3160de": "0x00706f96a68602000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890047753c8946ba8f3ba101ba2afa2832c4a5b6fd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928907bf572c47678e5141ace6b29c38e0a9995d7134": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a32f50f0c7d78bb3a6cb081046bfee5b89060000": "0x445a834ed21583bcae5888eb433323c745fa4a472dd8ef0af700df918158d20100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddee9d01ef9ae9a28b5d1ad92908701b2eef4b6ab8dd733a2bc50fd3f73fb4b63": "0x0025c20580d7ce0b8996c9bc91f5935dc031f3ad", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001c75e0c290be78b48b440123a7b9c9950cb4dc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900248d1380769d8ad43a4663da2712bd1186dc76": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896b84b4c46babd3748c1c73bc408f6999238d00a1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900eb0d1842deec54de9fee30c06369c21e33b99a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc20a5c102573d715a962f123d0991e9c5bf60ca03aea31a1305c72d9d5101671": "0x914c952f5746b19f007124c995ee5b08061139dd", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289410a7076af80d5c66f3eb350f4d455c959e99968": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b1190e1c02cc7db63072609b9da9dae5557f478a": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5820b363e423d6569657bec1820a35823af2aa019c17507f2204ed9f5c107147": "0xc9e65f133b90e4fcf565abb95408708f9845b90c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a13d980cb2bedb03cacb7003143e7af78c602030": "0x00022d34640b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d2c2b9441c516f28c9aa9cbc04f5aa257a18b77083c8ef8092b7e6332eb5ccd51": "0x00320c624958997f6d8ec1d130a436e87a1f0b0e", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd43d6feb9c8b0455a11950079b65ad498771bd454e01b56907a2ac6362d7274b": "0x1eb3162901545cb116b780f3456186b5d1396142", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700928c48cd1e36087af5c06ed90b4a6cc161abde": "0x00381c3a2c0400000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3a32583d65fb0c890d13834bd3f1477b91ad86446828a80c3ba30f6241725a10": "0x341e46b97431121edb45c7397534704946e1090f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f5c78d56cecddfa5e7151650201b5144bdb25fb1": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f88370269b6718332b8005b44de1c1abb1c194b5": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002cdf90e124b3a929d16682b6683f198d65d9b4": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339761ac28a26b98d1639e38034d48d1a3760b96a22d": "0x0008711b0c0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289000028ce0fce9e53bee386adbf4d175062b20fee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b31f557d9e0b8ebe6f6fa65d6bb6e8d774c794": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9a34338cb3f82de1fca9185285d30a075745505390d3a898066eb280cc44ba73": "0x38b89b94dc5dec100a23fae5b5140ffcf81c8b24", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b14c0abd57488f6c66fa299c0b26cddc60da9367": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339760c5157e1255dae7acf046b38fece4a69ad6289e": "0x00da5001030800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c48fd59cfa7e22ad3d505b62a62a9a6050060000": "0x2e0834be7dd8eb02ee1ae17ba5af36b576df80a3b9be07f8837c3739ea69866200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289006d21a300eeab8a54eb2ef797195f60b2517e0c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898e6d7485cbe990acc1ad0ee9e8ccf39c0c93440e": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976e33fe6344ffd1fb1aa35d7823021a99e10aa1fb": "0x00501213dfb68a000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b372cf3e7c70309bd436314663ebd45f3ca4b15c": "0x00caadafad0200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f80791d5ce62ea36ded1fba5e1bf53c15938c9f2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397231e4177e2d79bcffb4dd1d0e9b6cfa31f1acd98": "0x002cb5d95f1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e4d4993cf7be0b894bb458dff9c2653434d407fe": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397007ed64ac2fe49e1bcb932151e72de0ca813ecf8": "0x00a4289f320700000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b9c31d32260bde35e51bff1fcf2237219d99ef91": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e571ba1d28c1acbc64c8b63b6a4c9664aca816da": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894ba3b6302e0fd7fe3d21fe1d2ec3ccec915b505f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289847c5586665b81798aec196a3065cdc577a013dd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ba90e5b6d3376d792ca3927524c27a185fbfb159": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975f9e3e6c76760ce49fbd87e857fc18ebb7527584": "0x0068367fe62d00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5100ae4899cb63e5f444601f805abff66a70080000": "0x260f09bf8836b84b88d389cf793389a6387090d930c1dc555789d94b304d093400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db09131af9d0a9204475313dc71104ba4ab278d9101977e1e9f523a8220e0074f": "0x320a67f5d718c4b541a5ef8194ad4f4638162f6c", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928994c90e0a573db26467e0e812090a9220c20edcd3": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3c803d0e3f20e39f3060761bcffc56363024d98234dc248583149be800647c7e": "0xf409aba35fd318d2f06b820f80cdda3819f7a545", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900beefa91563f6c652924891226981aacdf88834": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ccb2545aaf81d791232b9e111f4acf0a182547f3": "0x004e99ec4e3705000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b434e938062f321bee814acd82270acf6844cca9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333976812d2dbd83e65750a7db91ab8806972ce170be9": "0x00203d88792d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dee095ff182d11b07804c7ae6184e03ea05cdb5e35c0a7d2cbed0e6fdd5ac050a": "0x00aa569e5eeb25e923ea96578d77a73a53bd643e", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a707a440e0a34f11c3c259a20622440cbed1970": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397719819815ba8d64ed7712c3005c8df49b2085368": "0x00d0bba2d55703000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f822a6fa1ddb385ac9b36e3c0a96000822050000": "0xe8eacc9d19f41e050e02e99f34a704b7afcd65c7886bcd79d6c888440e5ba71b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972b91c155fd65aa757542460218f00df1e9a1d822": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7917ca8ca77855eb657fb414a3736204e4e3cca": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5198d6112ef75832eda6c8abfadca79ed6fe050000": "0x5a14fd5630d7c9bbf5f0bf20e8dfb6b8d9cd0be47a64b65c9c4ffea8d25acb2700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282438a77e549ab954b951a118c7106bb46e606e9c445": "0x0080f420e6b5000000000000000000000b58260100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970225bf3928801e04bffc49fa57329c999a3bbc41": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928997883f6fb7483a6cb748a647f23b601fcd69b393": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397705fb243cd2cdda5ffd62c702fbe2d48353e3bdf": "0x00c462cb9a0e00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516ba59061e1ab64b53ba1f9f7a9252d684b060000": "0xa0226b58094e54045005fe23c8a403e110a4eacfc8ccdcf6cb009c81c4f9444700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d246b502d7931ac1df713e968670cd5ac008a1f84e5db9a0df695891a2b9ff13b": "0x77c6f7a1f67e4810c454d57f5972da4761f8079f", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700850453ab4667fbce4688912e43f1ded185f847": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971e768862e1b8abaf3c1c776b032036c7b774de85": "0x001e10b9e23f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970050e26f4860d18a81ec8685bee8e73b18f2614a": "0x001428b7820700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970023772fedf1a43256e6ae4c227b6dc05989f814": "0x0010fc266f3802000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900843587f711b5b15b4b234450e0a3ac1750e4b3": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dac133ebfde441672c055b79ca9a6059850984eead1ae036f48ca1230e7f0556f": "0x3e2021221b0bb5e2d1ceda9f024ed9804b055708", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397000977634918b6483ebdfb23a3e68fa322f1da1b": "0x002656d56b8e22000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971a0094af5e7a2d052f67814b9bbc799ad6ece294": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979b35dbc596f545739e25e203b41823251acdee17": "0x00b8dd585c4b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fb5dfca2e526f23b90d21488082228750c17a3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891a0433933f6ea1084a7bf83ccb474b4cd263e7d8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f5133638ea25da451abbc648fb87b28d0318aef": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289904a974b3f43903b63d2b6c7fd379550baf4742c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e1b93424c6edd8536fa71891923de5766fda9a9a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fa5b8e7942818890da1ab0b8ea9f79c6e912a758": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ea1a59c6785f5c391efee3656f5c7e84dd20e07b": "0x00eccc45eb0100000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900f81756700dca9b2fe8d4269a761206ff26ca95": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928972ff95ddf81bfd2db7a088aaafe39e7f3ad3682d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397aa71944087a4242e157bb28a8a1b110274228ea5": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975a01e248364beedae2dc37ddce5f45dc5b7011c6": "0x0036e9591cef02000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d16d28220f8e13c7e464056988a9788066cd6427d5100c773e7adbc4c08f97a51": "0x7dbb16b85b247430888763302413d6d2abc1ff8c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a6d4b980ebb41243978f92316777792ec14fff50": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289352fc97f4dfc29a453be0898d59984431a6e0714": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700afef101ad493ac1da15395eeb0c84cb8a2a0cf": "0x00ee69afcc2100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51dfab7dc9bda49a0553ba48aa07ecdbf39a010000": "0x760f4fea13251aa55dcf9d3baf44aa467128767f29789fcc3fc1edf69949c77900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824305b30ed53364a95a0ac56b214077a85bd5992772": "0x00001c0611c813000000000000000000ed88022000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890017a7dbf1051e0ea2a57513ff9423919bc8a5e3": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5186fae015c98feff6e4d268982f51f71ac5050000": "0xa6d16d544f5994d2de0c8064d38f2df418f943595629ee6a2ba8df7a25f2380300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896bd98f74f818c4fbfb760afc077c3c8059b11276": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289003f12ba2e37d864732ce8b000270b05fdb2a893": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700e3c4d881755355b58527e1f09a5507808de5f9": "0x0088c596351d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896846d14e5177c97220466fa343cb3ef0d1e29f07": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897a669ef68da390965ed95cce8f02f6a11a6520ba": "0x01", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da95cca149f246208e7bcefeed44145b6ca332fb9b797084eccedfc9b746d1daf": "0x4118b3011a348538694a2655100db72e5010a0c4", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898c01e3c81c99db5918e079c5198282c29b773020": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928991ea6ea479dcc9c599dbf6a410cc7ea3798d3351": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7e88787d9eb21f9643369b4357b4a5e61865cc7caa976ae37b2192fc67218634": "0x8919f90098e7976078c2ca828b6af4fdc3ab9052", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511884a579ede5a880ce55ee21a1e68a048b010000": "0x78c8003d8becb1414e373f12bdafaee23c760cda6aa4f2421bd424472995d70700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5115e2989f2843fbae96dd80fddf4f073516040000": "0x9ed22cfc6877c1961ac2cdbe5536684b0761074b8ea475d0c2f173f5989be90400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e3ea41cc49b5791b4410ecc3d2dc4a303e09f4": "0x00", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300b2272bea66948af04edeecbeb0171521cfb24f": "0x0040763a6b0bde000000000000000000fc794e6701000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897ed6f2cb4f74ed164582fef026304ef2b1d1b637": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d12ae1449f1318e75220747ede8feee0561f500f1ca2400c204ffad735c53ec54": "0x75d27075d8d9aa87e54f05a07a52c5a117436cc7", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928913d45bada78daa5cd52162254d158a217dd1faa4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928992349b865f8b6033f8a36861f62fe4b0202c93d1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975bb506f259835349974c5fbf0bfd5cbd37157dfb": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890025641d2b744f643432cfef4c08b76430fda5e0": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d47297cdcf36eed17305d6a5471c6cd482c7e91c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900a43389d6cada465a26af74f61c897d1855ca63": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dea62962b601de31248d06aa13a52bfbdcb1ad4e534ef4f271bd5b39fe0759637": "0xcf1e7d7b8b56e594e0294c5aef7a81b957350e34", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d8e01e6fca80b292913d75f48f0a2e853f060000": "0xca09f130c47fda19a2512d38b5e7ba1b84e849eca85a93677122fbae4ceb4f1b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7ab28f300e32aa503233448cb8b7ae963933abae546105ea1925172f28efab05": "0x3dd62544630d94aed21653ed9ec15810cc759a55", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397afefeb0eb9875074ca2a2d508eab621fdec459e2": "0x0078e6bb2e4300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fcbe7c027c8cc33f9ff58358629a833279c814": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397393774d01e81a2fa93affad6e3f75a86a569f11e": "0x0080c6a47e8d03000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5144bdf3a496d85bf4b05082b1887e2a2307070000": "0xe805f9ae6f23f4e1bd98a26b1c055d0729755e1fe4c913a713c7094ebb1e362b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d449bc4f0c813a72037bb8747e3c2277c8e2136052071a3dda29af93ca1d66b2e": "0xfba281c66fe1034a2f1cfcde7fc6f6d939df9cd6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928921b967d11709c5f62eccd737625effc14de873ea": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f0571e067930c59f974d3394987bf4392513748e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51badc36e2b573573fc0c0b46103a032be17050000": "0x72c725acce32a689fa5eb670601a139a3dae75fa9e0e77224428896082c5642d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a9d3066f32caa51fd4cec46e3916ef2042060000": "0x36e5192ceacb95e0919a64940e90ca47852b8aa1271e2d4c69383411e72b270200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51543938c9ecba965fcaa21e537c780365e1070000": "0x58783e1e9b02c77a63dbb17861f1fc21cca35045ff11132bcee7afe4ed5db23800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900705b1272d1301af42e4a730161bcc1da26b534": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5097017378c065cfad77e7360fba48624873f44c16669a73913e735237a82a29": "0x46e4cf75e7a515935482c3f1b557efe92893d483", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289177a47426d4c1a6a65276505167c36b663db2575": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5199191ab33190fca8a5ce85235e91f89853000000": "0x08c71e9b40bc639ac1b3e109b15f4a9f701529eb6941b0fbb51ca6856dea4c0800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c6e1586b3fb4ce04143f3b84729234ab9c1e28eb": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bdfedf4cbabcc9cfc93e7e6e7a827434ad050000": "0x7687b89809c7a3c7450a60f94b3f5e23b2e989312f14c3e521506479e4883c1d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928981594a7163a447cb1ac16ddb7f831dc1c43f9307": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a003fc1e731965c0e08ccc93868cddae6895d8e0": "0x00a014e3322600000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d2b35b43c6ecd57e7f154ef5d5dffd0c73f8d4c": "0x007ebb5c423f0b000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ae9a937d4302533dfb4710e49ed7ec6482070000": "0xc4e71dfddba17863c7ea76d390624122e2369ae4f3a01a910036e7bb70d89e2b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d44ba33d654fef43a6736352ccf94a226569f10be0fa323d34c09f13419dec25a": "0xb10d4d83491e7be1f9451065c9dc5909b717a28c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397945df54583eb102061f57d3b4f3e499d7acc49b7": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978f7c2327fbd51bb8040c53fc64e3aa6df197c9c0": "0x0010a5d4e80000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ba0dcf63227d00743abc481beb50a906e6010000": "0x96fa67ee8a1c434d8efd13671fbb12ae29421c4c0e350e2fe93744caea8ad20b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979dedc7bf7fbcfc0d48964cd9977337b944e177e1": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec6ff8b811135779cab408d1449e9ee75703e8c7": "0x00ec851e755400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c5137df3f8f85e7b8d1f5059045ed0639db413": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5cbf38076b2d9b9faef9f96907d266d5effda6e8458ca6f4287615089f05502a": "0x3e386f707569dfdea7210b53bf3e03f6d24ee073", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893ac7850fba178228acbd4c8b601bda2342392e21": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289001ff7e32cfd40f06e0d9f60f60eac6bef113f41": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894aa8f04de40456cfde9e606f9f066f399bfa4aa2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978d4c9ffc5680b9492c9fe7201b972190cd51c0d3": "0x00927581d50000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895fd474f8abdb347ec54b15cbca40b56dd2f2aefc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289007d79331ea38e90d35ce0540f37067f2662585c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896904b80d7b5967daf9a55a469e18c55ea75964e8": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a3f80af332d2b92874c1e0f76af6f23586847357": "0x00b4a3ea662900000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9032a7c54bbe6a7c1c9ab89364242a3d39a725aa880a38110fd92bfceac13b09": "0x6adab48e2bc7819044ed2a9e4041f918db545aea", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511688b90ed29e524caa1cd597aa19684dc1030000": "0x3a2ff980384cc7996c6ae89384ed5f47531ba3ac7f9b2a3f89863a99266a3b1000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970010cb37589862d13ee82641c31b3d3efe93e06e": "0x00289650330900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973c15412599907bcda854ca9f243f32baaf3844a2": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397701ce59b203d5368c7ac68f6f57a5f23552d6458": "0x00e87648170000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bd9d6e7489a7b450937fa7ecbabd71be819bee3d": "0x00ca752c232500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ac9e50fa5a78b072c26e33e6ac2c8e00fb2a22": "0x00aa8e680e0a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928949657dfe91f0572eef4984feb486a34f2a98eebf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289559bd4befa5d868ca380a9928ca2228e3ed26ff1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896256921fd93382ce2d468570f6bfb385e5bccf0f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928964606650c04bde33fab32ad33833dde37b47360b": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da2f43a8179d71374a49f4151bae8d01dd1ca9cc85eaf135a23e8134ae32d4fe7": "0x470f765ac9ca7fd2d19b7b68b39f3a3da9f648c6", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898e10e1d033589ab6ff05a410ec742434858d3f4e": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8c2100c8a8ae062f38b1eaed5b6e754179080d9e37d53b11f4ae7bf94102f451": "0x13983684c4cddfc884ad85d31f5e46f078f13095", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397520ad81a6359835797a4a7b0b0cfd0406a18f64c": "0x00e40b54020000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bcf0c42b60a210ce7d16928b5cfc4421d23ada25": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928938422523da6181fbda6662269bd301a95686a001": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ef398a72ca7e9c352d14aa297c5c59f604c43bdc": "0x007ef91cb75900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e585af0cb7cfcfe9314679e120318a5daa8644": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51445418f19831b32553e6589dce0ea4644c060000": "0x9c0acef99357fd179a671b7724ce635b53b25611ad3742af3878ccc6a0f0046e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c0f428bff6a974aefaafb3d14930fe63699a4bb0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397026581d80b9cf65c119f32a750947c45cdbb0847": "0x008c8b2757e600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289eb0718ce75762eeba4570943d5b2de2afb9085b6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928961ac28a26b98d1639e38034d48d1a3760b96a22d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e688284626ca2d00b578865c0e7d189c6ca978b0": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397012b4170e46b07ad9cc49d4ae4f7b406467cbacb": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f66b1c892c38a01c167535eb17a503ac8e070000": "0x1abaeefafe1ae6d3eb202f130440b7b2d3365279ce56def44f2610e56986ca0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243a974c739d6a0f8bbf598f8da986f6667b347eb78": "0x0070eab4447900000000000000000000b43bc40000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339796cced3c89d0565c7075aad1b2b19c49f449af1c": "0x00da25696b3a00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f73a96a4ff788fdd54acd5c5e2cdef3394040000": "0x9212c23e56838d5813efaec0b256040ba31348213b5d9001c95643164f02486f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f74ff8fec69a8691f8ff0493dba28b57fe3b11a4": "0x005ea223252a00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51d686d1501111e886e060be79b4c4352f34040000": "0xf449728349d850e44f8043b65efd6be7d8db8f4360fad672bfeb2ff6a304877c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3a1c2b4df870c87d3f205b720185a9e54176207b9c52a6803c82de6b34332e0e": "0xf91769506a288aa7edf21f0100444eec2c6f1033", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397cd17aab6f8299d35bc11428093bf1c4ae3b981f3": "0x001e39c7e9a600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e82fe500c39f4644d479f85e4b3e407a9d6a1e": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512c0421799f29ff6ad8f7ba7d95b81d361d050000": "0x66d0e8a978133b248e0d8f228c1040af8f7152f366a2b6543349b2555f21141f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900e17abe40cddfc8a2d2ed13eea958eb0030c0db": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892f60e0b4d918fa51fe99ec04b7b0f952fcbb7950": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5117b6f90d3ebc1391796263eafad63f482f030000": "0xaa44cf61123c6bf9110c8cc4454cc241f0dbfa92af8719ae1c33334f90dc297000000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51abe2883db7414a44b55c1d4979fed69c90040000": "0xe4317517c949be76bb6d6bf45c664e15c948968ecf47fa0b29ef71c331b30c3d00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289318aa87413115388a04d0083e792849e09fe496e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898f6292826b8af10c8b70a178fce20411da8b37b4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a496c36bc39f1dc6d989db28d51c55c102555007": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b167f576f31f640d6d8d678549db0005619be50b": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b61959b37aadff714af150580559858483459b8e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fc27d391ed66cd60f72ce19ccc99abb67a57ee": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bfd720d4cc1aeaca059c466b41ae0a55c652b8a1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d8cb03d06e50b85644026da3e510f15e39e65efd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b422b17a216192f8a25ee6d08342dfeb3e05e6dc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289f5c78d56cecddfa5e7151650201b5144bdb25fb1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397005ba629a682cfc064d0f7e35710819889fa357b": "0x002e6ed21f1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289bf66f78612884363c0f231c11a33ebbd6d26ef82": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d666c474e2f859bb39716a333ad449122df3605cf2d272ab876171d0a61cbdd07": "0xf9852f33e7b714fdcb0cc70fd2338923c5ee9c45", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e697b87de1acad4e636a923460fe2c15b3040000": "0x261f0bbb3c232961255def15a8939e3e0a5f6ec619496d704519ba3e111a601200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d28ca3d92a66a8c35c479af3375d6181a95ae794d798e02e6997b73c3d9307543": "0x002c2d84a889df4bdab0175a1c4487f67adacff9", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817daa84e0c7acc3e5566e5b833d2f8619b98abd0d2a2c159398fbe616c3f16f8bd0": "0x99ddd5e2568b6f88f4ebc3d8025ba4538c8cc8ac", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397150afa640c00b0f2b7add198bb670ddeacd2ba1f": "0x00e070e8b01000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bd3f1a813924a59db054e3ecc3f7baad73060000": "0xbadd8927d3b3276bf4691aaea34e7b5cc8c1afea864578263fd57abc6ded4d4500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339770d394f0974b088f02599badc4b1df6e7fe52d09": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d28206efde24bcb2b8e30e1f36b1fa31bbe821bd61f5bfab0b8c8e7c2a0df7356": "0xc8f9a7246af6650f96401dbbee0c30e5f913cf54", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b6431ad281def976f5cc1d53bf51485433030000": "0xd2595b4dd370884f00e06b9b1e6f8e26e80797cec0660c246a616649f09a490a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397df423fe29ac1331bfcdc8e01f2934a971e4dfb72": "0x005a3db8ca1c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973be088b61fe7972ccefd39298656ef9b147e06b9": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff34674c9401c39cf82d06d04f2037411d835db8": "0x0040e59c301200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002aa61c8653d63ed86aa91053285c5db6be2ef1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397fc6e2bd34595f49ccd77ef257810d6aa9c4941f4": "0x002a07e4311300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900abe816d32a0ff056a4a9cbf7c9eab2b550a2e4": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895705d16cc35d891bf6951c24c374afec5f7e38dc": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895c498cfbae903fcd46bc6eddba138f78b96b7200": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d21d90b501c8f1a883642c9158b61c987753650d": "0x002acfc5745300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d512435420c92437279a5232ef3cceffb7f7e040000": "0x2e4d4b606ea5d17de20136f8e12d3521ffd48fe8acaf5325c7961f002b582d0b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289261c307a058f4a6970c2fd1c3d696fdb968b83a2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ea28924fbdd264700a791f3ce734284a1c080000": "0xf66ad061b8b6ff29e2cf485f542b90e733f2164dd9567d2713eaa54362c4d52100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397574f85614c44755bfd42ee17a3bdebbd67a531bf": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928964465f1b98dbd0158f23e0dc0b1aeb967e1565a5": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898acb047dc00c1633e89130375c964ba9b1e203b8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893c3e4e713e333bbc44b36f89912b5d8dfecb725f": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899d0d5ff120f3d5a0daec7ea328dbe9e682d0efd3": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a62bc08e021695b3cfada083d0481452bf5c0fd4": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e96acc7d52abd264535e1a64a03a9fce3e238c77": "0x00e00d9e260c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b566eb055743eb2daf5221d7a1da355b1da5433a": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a12be70f3ec681399d61fa18022b31b2c5000000": "0xd018840d66c4f9365a2da31759f36a354306e12944d9c207a3668207dfb7e16500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339750d07d27600d0c2d74c22befa45e749c3d3f090d": "0x00e094fb1eaa02000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df1c7807add4fbf549db8d37e8279efac27bd1478a333e4c9bc10c80cdafc9e90": "0x54036dcfa7deae92f0d948088690cfdfea648143", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397128b1dec802ddf81681e3d6f113bd83dd852311e": "0x00a0724e180900000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339727f3ee1c40ec45fda74a1f7c1bf36a66864a2376": "0x00e070e8b01000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e6c6c739e406cf3ccb1c666d24cfd200585faafe": "0x008e805e6cb502000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970090087b636ef3f95b14a4dd93d28fb2b1747fea": "0x00e04fa9956800000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289df524873fc92acd043016194ea11dfa3276f7e70": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972392f61669f6e3b81a46d30210761c77b0ed35cd": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289fea35be9327aca7beffc93d2b0cfea5d291f7d13": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dee0874d09c3b5d554cc991a98bb9e1f7287671660fd542d7796ace33dc7c7502": "0x25d56aca979398aca283611258eaf84de39c0d9d", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891e9ad7f04d507c0cad58e5abfd5a55dab4d3b19a": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b8c167731c26d3dabde6783daee8735ba0408190": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339723c93d5b4d09093d82ec6b4e62505071c3ef00f9": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db08a593d2617176b23f2c2d1e32f7d9bab61aa012c1a5ba68104bfda6504322e": "0x0b7b02c9a7f9b6444ef6e54384a5b5feb6b36be5", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5157ddde16794fdd71380ba804d00194f8f0080000": "0xce4e902b421071b4825e6c630d14614e6021f42806546f390d8b61c328d5507300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51866640194ad325613d8224e5517a53e2c9060000": "0xba35225c3fc78975a20ea5119f4b9e9e458e44c981e67e38f2082b144faecd5900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397c46fbc59c8742b17c3f67fb39338046c1b3be969": "0x00520c259a7d00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b004efb56cdd4fb9bc79132f2fd60902c28142": "0x0064eb1fd70400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289a4c761977251e08c56f9865ecdbc530df99adee7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519485cc4ecd6d298f89297302618fc25096010000": "0x5cec348d901c9a9d931610a858474d3c5092d1297df3fa7dc986faed11c4d05b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d44d131755e0f4f5ae4baaf483ee1dee0f775c91c1451e8a06195b471a5559412": "0xdd9364642d32a48eb2cb1b0b65d18656f4a66180", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339780872129a96f429312a717e2fab264562b1254d4": "0x00bc7c65071400000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5132e347feabaecc5648dec83be9f6386024030000": "0x2c59026a5b96292f0ef483d5604bf90dd067ab2e442adc25767091806dde577500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397bcf0c42b60a210ce7d16928b5cfc4421d23ada25": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899ab791e5fc047dbb25dac95d3a01f162738ffdd2": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289df1e9b2eae31aafa11fcc281d6d0efb49c7e12b2": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51a97a0fd9fd6c732c40439fba699c0a7390080000": "0x0e7d980e385eead4e52d1daf803f4f5869799cd12f55a41031f3d9d93b52f88200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817da4910e5bf0a07ad0b3dd37d04aec0eafdbcc5ce4c96e7bbfb4c332a3d135db79": "0xb752d54f3436601d8ccb4fa02bf2289192e4ab59", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824300b46c2526e227482e2ebb8f4c69e4674d262e75": "0x000022e7a6e89800000000000000000008d06ef700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339730da5c03ce04c15dfea28b7466b5598e0f48c1e0": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289359043a2edeac162a5bcb5594a24724176dd68bf": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e45e521d5179090a446dd312330530177f585091": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397dba1c5969994434143ad0966f1e785de075b8e67": "0x00a854ae840c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002802750d12a39450f2f4a0e19375b8de24074d": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333979c3668049cc8c0e75c32ec8bad06421c3bd26281": "0x004ed7a1c0bf03000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192893bcae7a7bee3a07c59a217cddc891d947965ec00": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0a2eab03e8d24c980a0b7a03c30f0c5537caf9c27907477fe481898217d25c70": "0x00c4ea7d30d01e1d8438dbbea89d44d235a46aca", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1a74b5f0acf6cc5cb0929de58f353dc08ae974bce555de6470a842e5c5a1218c": "0x91ea6ea479dcc9c599dbf6a410cc7ea3798d3351", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928964cea862ccb0395f7b0f2ad5bc63b0f299a56637": "0x00", + "0xf2794c22e353e9a839f12faab03a911b308ce9615de0775a82f8a94dc3d285a1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397355d599405c853d1be6f1ff027967879d69acafb": "0x001e39c7e9a600000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513cda749d107e8dd4351a206703616696d2070000": "0xa203f552cab792a1e664d742c53e060f014328d8d2fa8eefe5edca90c3fa8a4100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339703fcec3a20f276aac1f7967a461301d75180371a": "0x000628f9e97e10000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004c129a0b05b5bda2b7ce56313ffd840c3b47d5": "0x008a28cb900a00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970047522120faa210d0e6722c57a5b1d83c417950": "0x00c662e4d35000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192892576f5ef8309dbb23c39be29d62273b4c917d783": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f760704253f15e9798783e695e6011893b38b549": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890aa3a0ddc82af4c06c0bc4c8acc6a9a9a6280672": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516c8840544bd90ef2cc01dc475d548cf35c040000": "0x246b502d7931ac1df713e968670cd5ac008a1f84e5db9a0df695891a2b9ff13b00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ba9171e89937ac44dfe9a19a1307e54814ce78": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289953bbf3ce4f4e15d76793c6d672f227993c4f3ec": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339751cd0cb94cf5bce38ae16c1a0df2af1fafc991e2": "0x00a6367cdc8300000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51284722d140d9a31b177923162bcfa75020090000": "0xdcd52d8332620b371c24b68a5f8f303792981975e817ac1e0e0d5a1034e1ae1f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700b9f5c58ff70657d2c607eda6c44c1b70e69665": "0x00b4766a6e4200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397152c7b351851c158305f51bcba4cc9570259cd6b": "0x00421e33e0df01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928924941335e79baae9751f508e7e95c1dd475b4e31": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975852b57c0d039fda16a6c948d2689b402526497d": "0x008ac580060600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192899b53723ef104396f1f44a378a84a15067e11e166": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289750410db2d74027243fa5b6abcab763635fa7fa9": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397004cf480789b4cbad22bdfe4c1ae7ccf4a4675c7": "0x00008d49fd1a07000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d0c5ca519856ed9f4245a8613db481fab23c68914960802465e2f2c6f67f40f79": "0x0086c68ec3a352527ee68308deb658fa50da846c", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7c0e9733213d62d53db42c6ab23ba4f20748c41c83f28f7f2ed935a43a32292c": "0xb0c94ae3d19f2c585b920842211d2d8430da691f", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ac090b38263e7fce9c72a0c28fa159bacb040000": "0xfa5640a653470ee0da616be3b471374a4af3bf29545d540b5fa7c63b59c9d06000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8cefa6b7f204e06e8fda587af0917d02df5a35ceb8bed4583c3a5e91352f834c": "0x7c90efde43639f566ed43d95d9f909697245acaa", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339738c1a42ec8564eb3a62966a831a5fa45e42b5455": "0x00624f8f730f00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5187cbbc1a7c8dfc5b8ad46360c40c227aa7000000": "0xd0a28cd71e1b713dafa7168963102e068ee03c9921cc6ecaa91a6f3cfa5b077000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928924a7eaad0d7f13d1999206d8c22f926980a12ca6": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d28e2740f0d79ca882ba5e2530f61aac644384032af481b1eb41ba48a1c2c1f3f": "0x745e0ddf824ef48ae3506f915facde8382d4501d", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978c0a288a91525460275a7b8762d2138207210ee9": "0x0000c16ff28623000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894a74a375a7abfdc2a836a1ad3987caa82aac2e79": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339787b72db3c9257c0647034b53686116d2ffa0f384": "0x00301a45ba2900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895c2ba9a003f6616bbb133e3dbbe827e5f5c45371": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e0dc528b979898218393f18a4568c69476640918": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339757981d9691cc20a7ce7c628f6d7b1ab82fac8607": "0x0094bcba878500000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d78dec21cc26ca8e9a6c12f5f11b0a59f21829e0": "0x00ac9de8d0ec00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c4ea4230999370bef2b2f92144bc03c9511338a7": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511f625ded47a1af12f37184990443c94a45060000": "0xfa407293a2fdaf63407100b29d4c02196810ac847cfbf3d9b472e29abff5872800000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d87282439bb987d0bfab369b9eca904b842723670584a5fe": "0x00000e8308e4090000000000000000007744011000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d40602cf99698212b9115e545fdb1d449d37ed001a3b8c4cc9fb6b890ba92c45b": "0x0aa431c58dac3b6f8cc07877c817165572ac383c", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700818158c1ebf72ff7d3a2feb70735d99a5c674b": "0x001a4b6b869603000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ff551a18250d3764de26d99e1ff0e854771056a3": "0x00525742bab805000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519f338179279b2e54cd06ed99ef51d5ad14040000": "0x98a8cd51a12a19dd5440fde5e43cb50f9d48d95ea5c5ee3618eb0b2945f02f2100000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51cabfa596aa6c29d4f0093819621875dbb3060000": "0xcc614406d9612fa12c9384213e4e4203287d777a602a84c931240fd8c2aa375300000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e9d60c6637468011364a177f0fe4f5e8da080000": "0x90b3bb381576bb2acd03c2e06930913a373b1c3d2ef68b9275d86940812be31200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890048de500664dd14290254bc70fa818079308610": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894e09168663a2a36b3b066176f82df10fb615f4b2": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971f77687df949341a0fd8f69a3b557a26e13efc8f": "0x0054a6b6228506000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc601b3e5d664c8cfd77f6713be93b8b4364e6a1e93217d04888b3c7cc21ee235": "0xd0ee80934b74c7f0f25c7a137a8a16e58e713283", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928999fb6c13d95f1b74e77778fc86b98ffb30cfb929": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890016625480945278b5ff3606667b0571f183efb7": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890446eed77a750a57751b3b1f294ed9a72945cd25": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928965e7c827ef5af55a5080f2589dbbd334e06dae9a": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970077d40b5898cf2fead807b1589e90142b99a3a4": "0x007e2232bb2b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d08e7cdbe4ea147b107456a5a1c4885f3306890522fd89b7394a1ce9ebda1357f": "0xd0c352dbc3f03762421093ac7225224cca2f54f9", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700eb8e5c2880dab44f41e7ebd008ba6031789932": "0x003c728ed34d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289cf356a6efa93781c6cd23d8d8d270fa49c1e549c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5151c5b185a1b28b06d66e0259982686ae89080000": "0x438d034340c787f15207a158d94c62b36dedf8c7314451d196b039ba2e5c6bf500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d1a14b0528d08f27ab53ff72a5b59dd415232cd840c4cf4d07a237be679cae334": "0x006860119dc98195115d8bfd4011eea31214f028", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397266215c7cafe4d42985587d614ecc2a94075cce5": "0x0082357a0a0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d872824345602bfba960277bf917c1b2007d1f03d7bd29e4": "0x00407a10f35a00000000000000000000062c930000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de6634f00d2a02b8c109ccb802bc0351674e21650ec3bb5c96c2515dbe6543a02": "0x354b2ae0cce6f0ed8f332f123d4367bb800ac687", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970051e28f46719ed3e65d93c5c172bfe0ed982b84": "0x001ebc12440b00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333972c400a9c0e85fec5dc0607362a1783e0ec224ef7": "0x0022f2d1e57d01000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339715955df69f2c7dfb120839d6b4c78230b664a362": "0x00bc7a47413600000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900fbcd1a1318617d6df1d267e92dc329c6dda05d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928950d07d27600d0c2d74c22befa45e749c3d3f090d": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d6499eec6c70a3e1211a1991248716f999cad2b5911fd652e5700b5382d1d3e2b": "0x7894774b62144bf5cbbee837c96e833e16e3edce", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700d102007852fb6304637ad44457b9bf42be382b": "0x00e80abae14c10000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289914c952f5746b19f007124c995ee5b08061139dd": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289b8f8068f55fb15342508809c3b2f6606aca7a650": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ecdfb30ff7141766182ca031e20777c0bca09306": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700497c0ea743f6a572459c14dff09468021c84de": "0x00268dca6f7902000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5191fd4ffbdb5000b188deca34c57aabd11b040000": "0xae1595f870cc27a34374a6b819a554e242997efeb760433c6fdb4372c2f2820400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d62b5214b6ee02f9e2596ba869ce0d3e27d8a5580072163a12f6294f3587bcb01": "0xb5d47ed8c07fe4d9a143fddf967ca8d66562beb3", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192894765d5715c351557d5242e3e6af8e1365ed5d08d": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51385e672e49faf784d1eeb47b36fda5db37070000": "0x063ae62f76c019f22db0492b9e2ece04dc8a6c37532cee44cf1e8a43da76053000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dce371857e768db4c8e5e3cb7c5b1aefaea189aa3e9f0e708577666535113517c": "0x00850453ab4667fbce4688912e43f1ded185f847", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51552e94847cedad8a425b0d434c1d2a633f050000": "0x666c474e2f859bb39716a333ad449122df3605cf2d272ab876171d0a61cbdd0700000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700ddaad281bd203effd53340aab51fbcef400e9c": "0x0076585b061100000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51783a73b8f986a0784c1d25a3a00ecc1b81060000": "0xd827433e2e48f71fb28bdfdfeeb6ebef2cc8f1bfcd4062487372fa4a0064ee6e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971ee21068ba0c94e7833940cc4c8058e2dd41096e": "0x00301a45ba2900000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950ed2a206f51a7c5df6772616e801c151c11cb72334d26d70769e3af7bbff3801a4e2dca2b09b7cce0af8dd81307": "0x88ee494d719d68a18aade04903839ea37b6be99552ceceb530674b237afa9166", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51ad7ce7ef2d4f8544d62f6523e74e6b5bec060000": "0x980761b3559eda50fdd683089d53060d8bb900c1a3935ce66f99f6392612b57f00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dba52bca4f4d427db7c58d6e341ea01f2e5374c826a11fa6d4ab5f0a1c6f13f02": "0x422d9bba52a289ca568b6be38a5bda2ed79fb328", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975490d6fb1ddfd925bef575445c4ccf0f20526b83": "0x00e87648170000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397537902c724861132c14848de8f504f196eef562c": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e77bca46a70638e60c9f81bc09d2daad7ebfb379": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c8495a15d9120bec1b5148745f13667dd7104a82": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51636f98f7a17cf965d1bb6a4c103ec5c2d7080000": "0xd62f37fe5de823d66a120bd90a86e7be43c372a5eb9b487d702a8459203bec1000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d6a54b8c2aa14f2a9ab5c4d99c10f8bde48de08e": "0x0028dda6111000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339765570b90b7887a0ceb57f7604da311e84663a290": "0x0082b4b8400200000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289586e945c70b8411172261d48c2d549e52aacf643": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397002b44b7211507e761721b71b7d9dd77b29c67f1": "0x0010fb62e84e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b3868d1aeb675f1fe97eae0da557f9fceff37afa": "0x00d22374f95f00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970620a4b3b1a36178015ae2c7204498ffb160853b": "0x006aedf4123200000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333971dc13ea429ed10d2ad98c5eb66d528e4875bf2c1": "0x00e40b54020000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d517856954c180b3eb0d15cc8e1f29626cc76060000": "0xc08ab19077f91abc5f4163463deebd9054613a93e9d1076b4beaf38684eb4e3200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d3882ccb174b01d544a410c104c75d018db85d9a749e9cc59249cfcf3d4f4d530": "0xc05217770e1cae59d85c04f333cabfde7c7dbefb", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511e00db5f09ff87aaffbf7ce33f6f9fc226070000": "0x268ecd67d92c521327a5dcd19d0e0ed4191367afc90c726911311d404626fb2100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817df6be65cc16c65708bb6a0e4b9958ffe23d1c56ee5683670a69dbbbb70c10d507": "0x553581f31faeec2ffb2119e7ae41a257f5ae0c44", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a50ee9a3d2480093dd4d94442dd6e9ef2044ed39": "0x0000b605da7963000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f4f8d0377b14301ea3778fc39552b421b586f7e4": "0x00f89a5b360300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192891241b9a94b7cbd63c50a9fa35b1e370fc583cb00": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397f8f3088978f60f5a6c1992b1b3ada0f228cf47ac": "0x008ac4fe5b2301000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898b2e32fc97a28e0ebc5482e328a8f8de993650a6": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928997d9c5ee5dd7eeb360eaa1cf37252154ca145e2b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973ba7149b3bc64c6f805d02017a0d71e89362de64": "0x00009573c24800000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51b7acc03ce074748f735cfaf6c4c334b60c080000": "0xda54c31637509fec9b39b34a070c98437c8e78beedd7eacdb46aa99f41ecdb0000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900976b44190fbe9870317db584086f6f9d84d610": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192895a707a440e0a34f11c3c259a20622440cbed1970": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897f4c327d9fb68a5b249d96d7680c8203ef4fe56c": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397482b1c8fcbb12b90573071652cc5d46fc24fa426": "0x00743ba40b0000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5125db438cfe3190f45fff11bf4bef82af14080000": "0x76d8103a1098183b5518fd2c4aa0595379a6708d8bfc2ee6414963f307a83a2c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd006d0f2c483b3ad7df4a76432af79ff2d6d2adb608c1066c7aa1758cc6b0c08": "0xaf1063dc4a5261ecda991dc24ee256e4700be7bb", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970d9905f0c546708f12b180ed038e87fa702e0cad": "0x009cc589734803000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7ed18ee2a4570d6d5da249195b8169757c0104f9398db1be982e656844dbe33d": "0x0a9c3868f96e8a3e5386470d78f78046e09cf77a", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397611ef0a18a260834d1a063bd279c8f4dfe6f37c0": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397b3aeabe65664ab160d8ddef2d0a74f24faf321c7": "0x0080dd62b22102000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339709790fda0cc6a748b715bb2ecd8fcc012d38811a": "0x0080c045b21c00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333974b7530fd33209c28c18e254816adf0e2f065be7e": "0x00acd53cf37000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333975f27b51b5ec208ee9cb25b55d8728243318aa87413115388a04d0083e792849e09fe496e": "0x0030bd6c70430600000000000000000046a4220a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7d341dec7a554c2f7117527a1514f34ead904b6": "0x0048513e650e00000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289002848284eb655a5a99250ffbb09605b8e624261": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900c8d2f03af9ee67f36463ef212e09137800e377": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d513cb01d9cce3fb6e144a034235f01c66e8a000000": "0x7628a5be63c4d3c8dbb96c2904b1a9682e02831a1af836c7efc808020b92fa6300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397924c251902924c7dbd4cbf166d42757fb2d146cb": "0x006ee223f3bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dd0fb8a9ff2c401782c57be9d81d51d4083fb4d77deca12888b29dc737274e832": "0xf613cbfe3c3552aa32bd23cc820b811b666007e3", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5128716b04be1093d3ffa84a217c2e4be6bb060000": "0x48e5f2ba6ff67730b0ac46f70411fb5d836c8981bd1a239fe6ef450ec72ae00800000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519caaa89f83f3e375d77d9b339c1563d8d7050000": "0x7c63cf2a62f9fec0367c3f77d665e2406ca7940cdce57f736cc6ae356b71b61200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192897758d89177a41267dd2390262707faa602f4f2d9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289967e82bac222eb299da4d0b3c47a4d2c69602fab": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51da61288701854493ecd2e07ca345929b99070000": "0xac133ebfde441672c055b79ca9a6059850984eead1ae036f48ca1230e7f0556f00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51f68afb52363799c2c565109210cfdf7eb2040000": "0x8401968bdcdfe4b6d9d9fe8b0b11348ca789ac0135f0ff4299de7dad5c332b4300000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289c61840fbe306c4e984a41128a5a5a492f5491ddc": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700467243b6d8312a68f35ca037c0428d52ed8aaf": "0x00761509960840000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e571ba1d28c1acbc64c8b63b6a4c9664aca816da": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289089913f600e20bcca596e00940631f783fcc3fe1": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a7f5082cece0be9b14e8be6c1747d0fca39ec8d7": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e7321957993cae05c6d5e4282e83d1b09b57caa9": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289e9faddbdf9c03466a607fc06415ac3f129aa2dc4": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d516113b4784bbe247ec0691d70b76ed5c096000000": "0x1492d85a4c248f9eb0c1d5786ba25459f136216d637cf45f69e7ac035a94873c00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397202c3ba79b184884973405abf8b7d3d65cf73f3f": "0x001aa84f47bf00000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397ec50c43867523234d23f0238a29f3e0df59e7b4f": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900010b75619f666c3f172f0d1c7fa86d02adcf9c": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890063a1ad9b3ad315d4a0bb590435d34d4593845e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289320b5f61e5ce5f386149dd2f1f65019657724650": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898c723d6c9f5710dd0cc7219a4658f09c3f5d9928": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8ae2ec50efc3eab6dac128888c6171c2c1a01a03fd01109ec467daa2c3af3b75": "0xfc6b49f7539a0bdb98f78b3089baeb861b9e71c1", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339700845040dab8b551a3b246664a6f9d2c2431c0f2": "0x00c0e1d0612100000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973024413123731ac0ce07c13e9511c0bb76a228d9": "0x006ee223f3bf00000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51128ee2ee636f459614b860212cf9687bf1070000": "0x6a36947e2a739ac119a83602d101a0ea24df365aacfd1a91c166d8734f96491e00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d5a14fd5630d7c9bbf5f0bf20e8dfb6b8d9cd0be47a64b65c9c4ffea8d25acb27": "0xf7d61f6573db5f748e402dee14b0aa70a1a12288", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333978b1f512edfd229d910efed5af91445aaebc8c7a1": "0x009268fea65208000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397a899ca042ea5de91cd2174dfe9e13233e9deafd6": "0x001428b7820700000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397e403233a64dd902a5cd50e83c5a08b7896875ee8": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890a4390841918eb8b1ca88e377ada4da46f8f83e8": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289008ce1ef049738e34a1f1e03764ec209b329a558": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5180c0199c5a46faaa48e11b38c51ba77927060000": "0x9a99db07618548fa203c1816e4fc95741d00d8d0ce0f38eec8633f0ea5a6c51900000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e3339711feb627f21cb0d2e4daeb7f8aeee1fad6574704": "0x00743ba40b0000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ce76a4eb328d7c14d3a425ac145f887d7277e6ff": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289d52edbffac1aea8f0bdcd78ca849abfc51a03d28": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289ed434693c34b81c2f7979f2f2724a63a0709fbc1": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa9119289697eeab43d4558bd0d82e805d319d59578fd12ef": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d511748e36c613e593ed0a5528a8552b89c11060000": "0x4ee051c50b5c51b147d939e25ce61aa7e05af10ced2ed62ce7051509009ddf5400000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397003e3ea8f5c20dfa974948da91960c0812c09ab9": "0x002acfc5745300000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d9efbf480d958cdfcb501e7c573026da710fbc824f4fa05501fa36cfad8dfcd50": "0x5ffcf1f0f84cfc6fd881348ac8e74ec5856beefe", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519ab389998404087e7874af1a002dfc2373070000": "0x7c911f087ecbd131871ac6262c81521e5f32f5e626d30ffb35456a42c0d95c3500000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192898049419a99016123ed264ca39436a91c35c7fe2a": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dbe672adea7c17054748cf224dbd6bf1c769e99f301921ccc034b14b0234e7267": "0x341ad4e79cb95c9c556e0bf96863d78a182d08f1", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51c9fb2f63050fa8c2e727e4d4f43f820138050000": "0x44d131755e0f4f5ae4baaf483ee1dee0f775c91c1451e8a06195b471a555941200000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817de4317517c949be76bb6d6bf45c664e15c948968ecf47fa0b29ef71c331b30c3d": "0xe403233a64dd902a5cd50e83c5a08b7896875ee8", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890024d44f11a321a70888283808c81c454b156546": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928925d56aca979398aca283611258eaf84de39c0d9d": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f3654937b2fb15344117b9b16fe5065d8f0d386": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d5136cfa4ec2770d39006c761b4a1cb69a61c090000": "0x102ecd1c98119bb49b5fdcdde4160e597892cb30aa1aa3a40dafe3717e59a74a00000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970026db7abf8a3fe7b3543a035d11e22b90615ee5": "0x0050a95c091900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192896f4920d9045a58646dada2c7a8b48f513387c86c": "0x00", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51797c51580ad31b9c22b7bda52b6d0042b4080000": "0x3e5f290acd69dfe4ef0ed31024db52c380ea2b18be398c37cd53d1ffe807d77700000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d519ed1a0d6962298a486c3d85733161c5c12060000": "0xa24a3d7ea476f7eadf8c65f9ac5aec691aa7af4d0e4a8863795482016401a73200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e5d255ba83d61f0224659de3c170b2fb0d050000": "0x605a10f7a8372c3ab9d2b945827cbd548781d9c3a054697de99f995aa096ce5200000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e0a391549a38511d69231e67a8ab32d39d060000": "0x22cf9dc37215691aeb166d34895f9651b6b9f0eac9e67795b1d48e8eea19a37100000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333970005ed1b33b541a3029004ccbba7cef3748ae1c7": "0x007a2120ce1100000000000000000000", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817ddc73a045120bad713a3c84fb3ea30d2b28b680eae6737465ab10706b088b0110": "0x004547158d12daf5a188c111543b87aaa3aafb92", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d8401968bdcdfe4b6d9d9fe8b0b11348ca789ac0135f0ff4299de7dad5c332b43": "0x79af82bbb0552f8ad0192f4a7638dfbe8be00908", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333975ca455068327d42db7e66c6c80532452f39ad256": "0x0056b961800900000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900d8566765f1c00841096a4c097c5da2cf656509": "0x00", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817db2dc42595cd47cf78bd4fa4f99b99cd4f20ec4ea682b0715d906b5694e4dc345": "0x656e42bef0b20a74de23d365958a4461f595b755", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e33397d023bd0c9a21b2c69bff060f85fdee8b2a2e2908": "0x0008db62010400000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900b01d06372d7bfdf7ddacb9b11037e024377810": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa911928900ef6623036edb96606b9dff2b5b26e697fbbb9e": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890aa431c58dac3b6f8cc07877c817165572ac383c": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950580521c32d95894070617261809ab54fd64223ac5dd0c547efbf0015944d1bcf8f4ca721716d8922fc940c9a61": "0x82104c22c383925323bf209d771dec6e1388285abe22c22d50de968467e0bb6c", + "0x9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817dc8855e85e66cf69a1652147e4f0f29ff9c32eb0bb2bf5ca462f4f7d022938c69": "0xd1ba30cfd46c08cf699b00c705de01764689c272", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51e1685631e887d23acb4117fe64953bc9b7060000": "0xdeeb4b4fbcbc7e7e1dd19a2371c71951f820801be5e87e8e18e2e2291e4b132d00000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51bb2a19be328e67402a48bfde04baa67e92070000": "0xf8f5d1e351b28ed8669a4b295907d12566df2267d0d244b21a0974a0830e4b1400000000000000000000000000000000", + "0x1a736d37504c2e3fb73dad160c55b2918ee7418a6531173d60d1f6a82d8f4d51fb95039bbaef1da8a64e125600abf60ae2040000": "0xf2f675d0370f2f3fa3e011cd0c381e2c12d17fe56a01ca3045ee38357e15802000000000000000000000000000000000", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890055e4b4e56e60aed3224764a6479e704e2cb236": "0x00", + "0x9c5d795d0297be56027a4b2464e33397c0793c53db77bf57f00ed54aa91192890328d281d559d1e3aad4059a8d5a137e4dbc663b": "0x00", + "0x9c5d795d0297be56027a4b2464e333979c5d795d0297be56027a4b2464e333973f9265fd0b4f92eee642703e72d749c077cffbbb": "0x002acfc5745300000000000000000000" + }, + "childrenDefault": {} + } + }, + "codeSubstitutes": { + "5203203": "0x0061736d010000000184033660037f7f7f017f60027f7f017f60027f7f0060017f0060047f7f7f7f0060057f7f7f7f7f0060037f7f7f0060017f017e60027e7e0060037f7e7e0060027f7e017f60037f7e7f017f6000017f60027f7f017e60037f7f7e017e60000060017e017f60017f017f60017e0060017e017e60047f7e7e7e017f60027f7e017e6000017e60037e7e7f017e60027e7f017f60057f7f7f7f7f017f60047f7f7f7f017f60067f7f7f7f7f7f0060037e7f7f0060047f7f7f7e0060047f7f7e7e0060067f7f7f7e7e7f0060027e7f0060047e7f7f7f0060097f7f7f7f7f7f7f7f7e0060067f7f7f7f7e7e00600a7f7f7f7f7f7f7f7f7f7f0060097f7f7f7f7f7f7f7f7f0060077f7f7e7e7e7f7f0060027f7e0060077f7e7e7e7e7e7e0060047e7e7e7e017f60037e7f7f017f60047f7e7f7f0060047f7e7e7f0060057f7f7f7e7e0060057e7f7e7e7f0060077f7f7e7e7f7e7e0060067f7f7f7f7f7f017f60057f7f7e7e7f0060057f7f7f7e7e017f60057f7e7e7e7e017f60057f7e7e7f7f0060057f7e7e7e7e0002a70e2d03656e76066d656d6f727902001403656e76206578745f6f6666636861696e5f696e6465785f7365745f76657273696f6e5f31000803656e76196578745f6c6f6767696e675f6c6f675f76657273696f6e5f31000903656e76256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f31000a03656e76236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f31000b03656e76286578745f63727970746f5f66696e6973685f62617463685f7665726966795f76657273696f6e5f31000c03656e762c6578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f76657273696f6e5f31000d03656e76376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f31000d03656e76256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f31000a03656e76286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f31000703656e76216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f31000e03656e76236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f32000b03656e76276578745f63727970746f5f73746172745f62617463685f7665726966795f76657273696f6e5f31000f03656e762a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f31001003656e761c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f31000303656e761e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f31001103656e76206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f31001003656e76206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f31001003656e76206578745f68617368696e675f6b656363616b5f3235365f76657273696f6e5f31001003656e761e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f31001003656e761d6578745f68617368696e675f74776f785f36345f76657273696f6e5f31001003656e761c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f31001203656e761c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f31001203656e761d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f31001203656e76226578745f6d6973635f72756e74696d655f76657273696f6e5f76657273696f6e5f31001303656e76236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f31000c03656e76346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f31001403656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f31001503656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f31000903656e76246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f31001603656e76226578745f6f6666636861696e5f72616e646f6d5f736565645f76657273696f6e5f31000c03656e76296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f31001303656e761c6578745f73746f726167655f617070656e645f76657273696f6e5f31000803656e76226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f31001303656e761b6578745f73746f726167655f636c6561725f76657273696f6e5f31001203656e76226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f31001203656e76286578745f73746f726167655f636f6d6d69745f7472616e73616374696f6e5f76657273696f6e5f31000f03656e761c6578745f73746f726167655f6578697374735f76657273696f6e5f31001003656e76196578745f73746f726167655f6765745f76657273696f6e5f31001303656e761e6578745f73746f726167655f6e6578745f6b65795f76657273696f6e5f31001303656e761a6578745f73746f726167655f726561645f76657273696f6e5f31001703656e762a6578745f73746f726167655f726f6c6c6261636b5f7472616e73616374696f6e5f76657273696f6e5f31000f03656e761a6578745f73746f726167655f726f6f745f76657273696f6e5f31001603656e76196578745f73746f726167655f7365745f76657273696f6e5f31000803656e76276578745f73746f726167655f73746172745f7472616e73616374696f6e5f76657273696f6e5f31000f03c408c20811110303000011110f0f0f0f0f060602060005000101020102020201180307191a06000501010111110106061b01010101060101000101000101001c00010102011106060202020206060206060606060204010203060604051d05010101020201060201010206020602030602060606060606060602060d0202020202020202020202020602040202020202020206060302010202060202020202020202020202020202020f02020f02020202020202020202020203030202020202020202020202020202030204020202020102061e061e03020206020303020302020202030206060102021a0202020202020202020001010101010106060306050601040303030401050406020606000203020400030303030602021e0206110602061f1e0302030604020602060406020602060603060302021b020201060602030620020306010206020202060403160605020502020502060206070f021103020202060606020606061b040302020203020202030606020c06060202060206050307020602060202020202030303020202020202022103030202110303030203030202030202020206020303030202060303030203030202020203030202020202020202020303030202020303020302020202030303020603020202060602061f0606030602220206062306020602030402010206110f020202020203020202020202030303020202020303020305060606021e1e021e1e0202060206010602241b11110307070204030303062502020202020202020302030303030402262702280202030302032002020303030202021a0202020302030229020f02020604020606020202020202020202060202020202020202022a2b020601020f02110f0f0202020606060206060606020606060606060202060606022c060206060206060206060202020202020203030202020202020202020302020202020206020206050205050d06020306112d060306060203020102020203060211022e0606021e031e0304020202020101010202020204060302040303030303030303030303030303030303030303030303030101020206110202010202040606060606060202020202020604020202030206022f02030402020f03043003040202032904110c020211010201020301030303020202020206061131010303030903030302321a03030302010101020601030f0f040202020203021103050502020203030202020205270202020203030303030203030302030602030303030d0d030f020c03020d0d0d0d0d0d0d0d060d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d040d0d0d0d0d0d0d0d06060d0d0d0d020202021d0511020204020202021d05110402030303020203020202030203020202040206020204031b01021a040203030202030202020202021b051b0602040c0606030202020233060602040303030303020202020234031202030603030306030206110105270202010311020101022c35353535000000002c0407017001910291020619037f01418080c0000b7f0041ecf5cc000b7f0041ecf5cc000b07980b2a195f5f696e6469726563745f66756e6374696f6e5f7461626c6501000c436f72655f76657273696f6e00c20712436f72655f657865637574655f626c6f636b00c30715436f72655f696e697469616c697a655f626c6f636b00ca07114d657461646174615f6d6574616461746100cb071c426c6f636b4275696c6465725f6170706c795f65787472696e73696300cc071b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b00cd0720426c6f636b4275696c6465725f696e686572656e745f65787472696e7369637300ce071c426c6f636b4275696c6465725f636865636b5f696e686572656e747300cf0718426c6f636b4275696c6465725f72616e646f6d5f7365656400d0072b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e00d107214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b657200d3071850617261636861696e486f73745f76616c696461746f727300d4071e50617261636861696e486f73745f76616c696461746f725f67726f75707300d5072050617261636861696e486f73745f617661696c6162696c6974795f636f72657300d6072750617261636861696e486f73745f7065727369737465645f76616c69646174696f6e5f6461746100d7072650617261636861696e486f73745f636865636b5f76616c69646174696f6e5f6f75747075747300d8072550617261636861696e486f73745f73657373696f6e5f696e6465785f666f725f6368696c6400d9071a50617261636861696e486f73745f73657373696f6e5f696e666f00da071d50617261636861696e486f73745f76616c69646174696f6e5f636f646500db072850617261636861696e486f73745f686973746f726963616c5f76616c69646174696f6e5f636f646500dc072c50617261636861696e486f73745f63616e6469646174655f70656e64696e675f617661696c6162696c69747900dd071e50617261636861696e486f73745f63616e6469646174655f6576656e747300de071a50617261636861696e486f73745f646d715f636f6e74656e747300df072c50617261636861696e486f73745f696e626f756e645f68726d705f6368616e6e656c735f636f6e74656e747300e0071e4772616e6470614170695f6772616e6470615f617574686f72697469657300e107384772616e6470614170695f7375626d69745f7265706f72745f65717569766f636174696f6e5f756e7369676e65645f65787472696e73696300e207274772616e6470614170695f67656e65726174655f6b65795f6f776e6572736869705f70726f6f6600e30715426162654170695f636f6e66696775726174696f6e00e5071b426162654170695f63757272656e745f65706f63685f737461727400e60715426162654170695f63757272656e745f65706f636800e70712426162654170695f6e6578745f65706f636800e80724426162654170695f67656e65726174655f6b65795f6f776e6572736869705f70726f6f6600e90735426162654170695f7375626d69745f7265706f72745f65717569766f636174696f6e5f756e7369676e65645f65787472696e73696300ea0721417574686f72697479446973636f766572794170695f617574686f72697469657300eb072153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b65797300ec071f53657373696f6e4b6579735f6465636f64655f73657373696f6e5f6b65797300ef071d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e636500f007205472616e73616374696f6e5061796d656e744170695f71756572795f696e666f00f107275472616e73616374696f6e5061796d656e744170695f71756572795f6665655f64657461696c7300f2070a5f5f646174615f656e6403010b5f5f686561705f626173650302098f04010041010b900243475950dd0851525a69ee02f902ea05ec05ed058f015f5eb9073f40416a4a6061626364657e870189015b85028c08f603f706f806890288028702dc03f6069c029d029e02b802ae02b602b002b102b502b702b902e10898059405ba03b903b803b703e703dd05c103d905c703cb03ca03aa08cf03f203ce03e503a808cd03e203e103e003df03e803e603a708f303f103fb03fa03f903f803a70796059305b004af04b5045cf904f8048a08f704ff0483058105de05db05dc05da05d8059e05d705d605e405e305e205e105e005930694069206b506b606b706c308c2089e06c408d408d208c108b404b3049f06d304ad04ac04ae04d404b407b307b507da03d903a006db0385078407a1068607d306fe048005b807b707c007d505d405a206df058006f604a306c003bf03a406d303a607a507a506be07b207b107a606bf07a308a208a706a608b60888088708a8068f088b08c903c803a906cc03d503d108d008aa06f503f403ab06f703fe03c503c403ac06c603de0281078007ad0682079c07cb08ae06de03dd03af06e403fc03b503b403b006b603d403ef03ee03b106f003fd0384028302b2068602ad02f406f306b306f50694078b078a07b4068c07f106fa06f90688019a0597059c058d078f07900793078e07a807b607ba07c107e208d8088d088908ba02bb02a508a408ab08a908a9029d0599059b05c908c808c708c608c50890010abcce68c20806002000102d0b0700200010df080b06002000102f0b0700200010de080b0a0020002001200210310b2a01017f0240200210df082203450d002003200020022001200120024b1b10e9081a200010de080b20030b0600200010330b1d01017f0240200010df082201450d0020014100200010eb081a0b20010b05001035000b05001037000b05001034000b1700410141cce2cc00410741d4e2cc00412210d90800000b110041d0f0cc004111418080c0001039000b4701017f230041206b22032400200341146a4100360200200341d4e2cc00360210200342013702042003200136021c200320003602182003200341186a360200200320021044000b950101017f02400240200141004e0d0041012102410021010c010b0240024002400240200228020022030d002001450d022001102c21020c010b0240200228020422020d002001450d022001102c21020c010b200320022001103021020b20020d012000200136020441012101410121020c020b410121020b20002002360204410021020b20002002360200200041086a20013602000bde0201067f230041206b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240200141146a2802000d00200621070c010b02402004450d00410021054101210402402006410f4b0d00200341046a280200450d030b200620066a220720064f0d010c020b4100410041ac80c000103c000b02402007417f4c0d00024020070d0041002105410121040c020b200721052007102c22040d011036000b1038000b20004100360208200020043602002000200536020420022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a290200370300200220012902003703080240200241046a41bc80c000200241086a103d0d00200241206a24000f0b41d480c0004133200241086a418881c000419881c000103e000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c2003418c84c000360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a20021044000bc20501097f230041306b22032400200341246a2001360200200341033a00282003428080808080043703082003200036022020034100360218200341003602100240024002400240024020022802082204450d0020022802002105200228020422062002410c6a2802002207200720064b1b2208450d01200020052802002005280204200128020c1100000d03200541086a2100200228021021092008210a034020032004411c6a2d00003a00282003200441046a290200422089370308200441186a28020021014100210741002102024002400240200441146a2802000e03010002010b2001410374210b410021022009200b6a220b2802044102470d01200b28020028020021010b410121020b2003200136021420032002360210200441106a28020021020240024002402004410c6a2802000e03010002010b20024103742101200920016a22012802044102470d01200128020028020021020b410121070b2003200236021c20032007360218200920042802004103746a2202280200200341086a20022802041101000d04200a417f6a220a450d03200441206a2104200041046a210220002802002101200041086a2100200328022020012002280200200328022428020c110000450d000c040b0b2002280200210520022802042206200241146a2802002204200420064b1b2208450d0020022802102104200020052802002005280204200128020c1100000d02200541086a21002008210203402004280200200341086a200441046a2802001101000d032002417f6a2202450d02200441086a2104200041046a210120002802002107200041086a2100200328022020072001280200200328022428020c110000450d000c030b0b410021080b0240200620084d0d002003280220200520084103746a22042802002004280204200328022428020c1100000d010b410021040c010b410121040b200341306a240020040b7e01017f230041c0006b220524002005200136020c2005200036020820052003360214200520023602102005412c6a41023602002005413c6a41033602002005420237021c20054190e2cc00360218200541043602342005200541306a3602282005200541106a3602382005200541086a360230200541186a20041044000b8d0201047f230041206b22032400024002402000280200220041046a2802002204200041086a28020022056b2002490d00200028020021040c010b0240200520026a22062005490d00200441017422052006200520064b1b22054108200541084b1b21050240024020040d00200341003602100c010b200341106a41086a410136020020032004360214200320002802003602100b20032005200341106a103a200341086a2802002105024020032802004101460d00200020032802042204360200200041046a2005360200200041086a28020021050c020b2005450d001036000b1038000b200420056a2001200210e9081a200041086a2200200028020020026a360200200341206a240041000bbf0501047f230041306b2202240020002802002100024002400240024002400240024002402001418001490d002002410036020c2001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d410321010c040b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c030b024020002802082203200041046a280200460d00200028020021040c020b200341016a22042003490d04200341017422052004200520044b1b22044108200441084b1b21040240024020030d00200241003602200c010b200241206a41086a410136020020022003360224200220002802003602200b200241106a2004200241206a103a200241186a2802002103024020022802104101460d00200020022802142204360200200041046a2003360200200028020821030c020b20030d030c040b20022001413f71418001723a000d2002200141067641c001723a000c410221010c010b200420036a20013a00002000200028020841016a3602080c040b0240200041046a2802002204200041086a28020022036b2001490d00200028020021040c030b200320016a22052003490d01200441017422032005200320054b1b22034108200341084b1b21030240024020040d00200241003602200c010b200241206a41086a410136020020022004360224200220002802003602200b200241106a2003200241206a103a200241106a41086a2802002103024020022802104101460d00200020022802142204360200200041046a2003360200200041086a28020021030c030b2003450d010b1036000b1038000b200420036a2002410c6a200110e9081a200041086a2200200028020020016a3602000b200241306a240041000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41bc80c000200241086a103d2101200241206a240020010b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c2002418c82c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41a482c0001044000b0b002000350200200110480b3401017f230041106b220224002002200136020c200220003602082002419c84c000360204200241d4e2cc0036020020021049000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241fc82c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a419483c0001044000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241d083c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41e883c0001044000b0d0020002802001a037f0c000b0bd20203027f017e037f230041306b22022400412721030240024020004290ce005a0d00200021040c010b412721030340200241096a20036a2205417c6a20004290ce0080220442f0b17f7e20007ca7220641ffff037141e4006e220741017441de84c0006a2f00003b00002005417e6a2007419c7f6c20066a41ffff037141017441de84c0006a2f00003b00002003417c6a2103200042ffc1d72f5621052004210020050d000b0b02402004a7220541e3004c0d00200241096a2003417e6a22036a2004a7220641ffff037141e4006e2205419c7f6c20066a41ffff037141017441de84c0006a2f00003b00000b02400240200541094a0d00200241096a2003417f6a22036a200541306a3a00000c010b200241096a2003417e6a22036a200541017441de84c0006a2f00003b00000b200141d4e2cc004100200241096a20036a412720036b104b2103200241306a240020030b6f01017f230041c0006b220124002001200036020c200141346a410136020020014201370224200141c4e2cc003602202001410536023c2001200141386a36023020012001410c6a360238200141106a200141206a103b410141cce2cc0041072001280210200128021810d90800000b0c0042f3a38eecb2fea7f4570bea0501067f20002802002205410171220620046a21070240024020054104710d00410021010c010b4100210802402002450d00200221092001210a03402008200a2d000041c00171418001476a2108200a41016a210a2009417f6a22090d000b0b200820076a21070b412b418080c40020061b21080240024020002802084101460d004101210a2000200820012002104c0d012000280218200320042000411c6a28020028020c1100000f0b02402000410c6a280200220920074b0d004101210a2000200820012002104c0d012000280218200320042000411c6a28020028020c1100000f0b024002400240024002402005410871450d00200028020421052000413036020420002d002021064101210a200041013a00202000200820012002104c0d054100210a200920076b22092101410120002d0020220820084103461b4103710e0403020102030b4100210a200920076b22092105024002400240410120002d0020220720074103461b4103710e0402010001020b2009410176210a200941016a41017621050c010b410021052009210a0b200a41016a210a0340200a417f6a220a450d0420002802182000280204200028021c280210110100450d000b41010f0b2009410176210a200941016a41017621010c010b410021012009210a0b200a41016a210a02400340200a417f6a220a450d0120002802182000280204200028021c280210110100450d000b41010f0b200028020421094101210a200028021820032004200028021c28020c1100000d01200141016a2108200028021c210120002802182102024003402008417f6a2208450d014101210a200220092001280210110100450d000c030b0b200020063a00202000200536020441000f0b200028020421094101210a2000200820012002104c0d00200028021820032004200028021c28020c1100000d00200541016a2108200028021c210120002802182100034002402008417f6a22080d0041000f0b4101210a200020092001280210110100450d000b0b200a0b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101101000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11000021040b20040b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341a886c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a20021044000b8908010a7f20002802102103024002400240200028020822044101470d0020034101470d020c010b20034101460d002000280218200120022000411c6a28020028020c1100000f0b200120026a2105024002400240200041146a28020022060d0041002107200121080c010b41002107200121080340200520082203460d02200341016a2108024020032c00002209417f4a0d00200941ff017121090240024020082005470d004100210a2005210b0c010b20032d0001413f71210a200341026a2208210b0b200941e001490d0002400240200b2005470d004100210c2005210b0c010b200b2d0000413f71210c200b41016a2208210b0b200941f001490d0002400240200b2005470d004100210b0c010b200b41016a2108200b2d0000413f71210b0b200a410c742009411274418080f0007172200c41067472200b72418080c400460d030b200820036b20076a21072006417f6a22060d000b0b20052008460d00024020082c00002203417f4a0d0002400240200841016a2005470d0041002108200521060c010b200841026a210620082d0001413f7141067421080b200341ff017141e001490d000240024020062005470d0041002106200521090c010b200641016a210920062d0000413f7121060b200341ff017141f001490d00200341ff01712103200620087221080240024020092005470d00410021050c010b20092d0000413f7121050b20084106742003411274418080f0007172200572418080c400460d010b024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20044101460d002000280218200120022000411c6a28020028020c1100000f0b0240024002402002450d004100210820022107200121030340200820032d000041c00171418001476a2108200341016a21032007417f6a22070d000b2008200028020c22054f0d014100210820022107200121030340200820032d000041c00171418001476a2108200341016a21032007417f6a22070d000c030b0b41002108200028020c22050d010b2000280218200120022000411c6a28020028020c1100000f0b41002103200520086b22052107024002400240410020002d0020220820084103461b4103710e0402010001020b20054101762103200541016a41017621070c010b41002107200521030b200341016a210302400240024003402003417f6a2203450d0120002802182000280204200028021c280210110100450d000c020b0b2000280204210841012103200028021820012002200028021c28020c1100000d01200741016a2103200028021c210720002802182100034002402003417f6a22030d0041000f0b200020082007280210110100450d000b0b410121030b20030be00801067f230041f0006b220524002005200336020c20052002360208410121062001210702402001418102490d00410020016b2108418002210903400240200920014f0d0041002106200020096a2c000041bf7f4c0d00200921070c020b2009417f6a21074100210620094101460d01200820096a210a20072109200a4101470d000b0b200520073602142005200036021020054100410520061b36021c200541d4e2cc0041ea86c00020061b3602180240024002400240200220014b22060d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b20052002360220024002402002450d0020022001470d010b200221060c030b200141016a210903400240200220014f0d00200020026a2c00004140480d00200541246a2109200221060c050b2002417f6a210620024101460d03200920024621032006210220030d030c000b0b20052002200320061b360228200541306a41146a4103360200200541c8006a41146a4104360200200541d4006a410436020020054203370234200541f086c0003602302005410136024c2005200541c8006a3602402005200541186a3602582005200541106a3602502005200541286a360248200541306a20041044000b200541e4006a4104360200200541c8006a41146a4104360200200541d4006a4101360200200541306a41146a4104360200200542043702342005418887c0003602302005410136024c2005200541c8006a3602402005200541186a3602602005200541106a36025820052005410c6a3602502005200541086a360248200541306a20041044000b200541246a21090b024020062001460d00410121034100210802400240200020066a22072c000022024100480d002005200241ff0171360224200541286a21010c010b200020016a220121030240200741016a2001460d00200741026a210320072d0001413f7121080b2002411f71210702400240200241ff017141e0014f0d00200820074106747221020c010b410021002001210a024020032001460d00200341016a210a20032d0000413f7121000b200020084106747221030240200241ff017141f0014f0d0020032007410c747221020c010b410021020240200a2001460d00200a2d0000413f7121020b20034106742007411274418080f00071722002722202418080c400460d020b2005200236022441012103200541286a21012002418001490d00410221032002418010490d0041034104200241808004491b21030b200520063602282005200320066a36022c200541306a41146a4105360200200541ec006a4104360200200541e4006a4104360200200541c8006a41146a4106360200200541d4006a410736020020054205370234200541a887c00036023020052001360258200520093602502005410136024c2005200541c8006a3602402005200541186a3602682005200541106a3602602005200541206a360248200541306a20041044000b41e8aac700412b20041039000b1000200120002802002000280204104e0b7c01037f230041206b2202240002402000280200200110550d002001411c6a2802002103200128021821042002411c6a4100360200200241d4e2cc003602182002420137020c2002419088c00036020820042003200241086a103d0d002000280204200110552101200241206a240020010f0b200241206a240041010ba40403037f017e017f410121020240200128021841272001411c6a2802002802101101000d0041f4002103410221040240024002400240024002402000280200220041776a0e1f05010303000303030303030303030303030303030303030303040303030304020b41f2002103410221040c040b41ee002103410221040c030b200041dc00460d010b0240024002400240200010530d0020001054450d01410121040c030b200041017267410276410773ad4280808080d0008421050c010b200041017267410276410773ad4280808080d0008421050b410321040b200021030c010b20002103410221040b03402004210641dc002100410121024101210402400240024002400240024020060e0402010500020b02400240024002402005422088a741ff01710e06050302010006050b200542ffffffff8f608342808080803084210541f50021000c060b200542ffffffff8f608342808080802084210541fb0021000c050b413041d70020032005a72204410274411c7176410f712200410a491b20006a2100024020040d00200542ffffffff8f60834280808080108421050c050b2005427f7c42ffffffff0f832005428080808070838421050c040b200542ffffffff8f6083210541fd0021000c030b41002104200321000c030b20012802184127200128021c2802101101000f0b200542ffffffff8f60834280808080c0008421050b410321040b20012802182000200128021c280210110100450d000b0b20020ba60301047f0240024002404100410f200041a49a04491b2201200141086a2201200141027441b094c0006a280200410b742000410b7422014b1b2202200241046a2202200241027441b094c0006a280200410b7420014b1b2202200241026a2202200241027441b094c0006a280200410b7420014b1b2202200241016a2202200241027441b094c0006a280200410b7420014b1b220241027441b094c0006a280200410b74220320014620032001496a20026a2201411e4b0d0041b105210402402001411e460d00200141027441b494c0006a28020041157621040b4100210202402001417f6a220320014b0d002003411f4f0d03200341027441b094c0006a28020041ffffff007121020b02402004200141027441b094c0006a280200411576220141016a460d00200020026b2102200141b105200141b1054b1b21032004417f6a210441002100034020032001460d032000200141bc95c0006a2d00006a220020024b0d012004200141016a2201470d000b200421010b20014101710f0b2001411f41f09ac000103c000b200341b10541809bc000103c000b2003411f41ac95c000103c000be20601077f024002400240024002400240024002400240200041ffff034b0d0020004180fe0371410876210141ed88c000210241002103200041ff0171210402400340200241026a2105200320022d000122066a21070240024020022d000022022001470d0020072003490d06200741a3024f0d07200341d089c0006a210203402006450d022006417f6a210620022d00002103200241016a210220032004470d000b410021060c050b200220014b0d022007210320052102200541bf89c000470d010c020b2007210320052102200541bf89c000470d000b0b200041ffff0371210441f28bc0002102410121060340200241016a21000240024020022d000022034118744118752207417f4a0d00200041a78ec000460d07200741ff007141087420022d0001722103200241026a21020c010b200021020b200420036b22044100480d0220064101732106200241a78ec000470d000c020b0b0240200041ffff074b0d0020004180fe0371410876210141b88ec000210241002103200041ff0171210402400340200241026a2105200320022d000122066a21070240024020022d000022022001470d0020072003490d09200741b0014f0d0a200341848fc0006a210203402006450d022006417f6a210620022d00002103200241016a210220032004470d000b410021060c050b200220014b0d022007210320052102200541848fc000470d010c020b2007210320052102200541848fc000470d000b0b200041ffff0371210441b390c0002102410121060340200241016a21000240024020022d000022034118744118752207417f4a0d00200041d693c000460d0a200741ff007141087420022d0001722103200241026a21020c010b200021020b200420036b22044100480d0220064101732106200241d693c000470d000c020b0b41002106200041b5d9736a41b5db2b490d00200041e28b746a41e20b490d002000419fa8746a419f18490d00200041dee2746a410e490d00200041feffff0071419ef00a460d00200041a2b2756a4122490d00200041cb91756a410b4f0d070b20064101710f0b2003200741c089c0001057000b200741a20241c089c000104d000b41e8aac700412b41a88ec0001039000b2003200741c089c0001057000b200741af0141c089c000104d000b41e8aac700412b41a88ec0001039000b200041f08338490ba70201037f23004180016b22022400024002400240024020012802002203411071450d00410021030340200220036a41ff006a2000410f712204413072200441d7006a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d02200141ac88c0004102200220036a4180016a410020036b104b21000c010b02402003412071450d00410021030340200220036a41ff006a2000410f712204413072200441376a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d03200141ac88c0004102200220036a4180016a410020036b104b21000c010b2000ad2001104821000b20024180016a240020000f0b2000418001419c88c0001056000b2000418001419c88c0001056000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341b088c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a20021044000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341fc93c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a20021044000bec0201017f230041f0006b220624002006200136020c2006200036020820062003360214200620023602102006410236021c200641f09bc000360218024020042802000d00200641386a41146a4103360200200641c4006a4103360200200641d8006a41146a41033602002006420437025c200641f49bc0003602582006410436023c2006200641386a3602682006200641106a3602482006200641086a3602402006200641186a360238200641d8006a20051044000b200641206a41106a200441106a290200370300200641206a41086a200441086a29020037030020062004290200370320200641d8006a41146a4104360200200641d4006a4108360200200641386a41146a4103360200200641c4006a41033602002006420537025c200641949cc0003602582006410436023c2006200641386a3602682006200641206a3602502006200641106a3602482006200641086a3602402006200641186a360238200641d8006a20051044000b140020002802002001200028020428020c1101000b6401027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a103d2100200241206a240020000b1c00200128021841f39cc000410b2001411c6a28020028020c1100000b1c00200128021841fe9cc000410e2001411c6a28020028020c1100000b5b01017f230041306b220324002003200136020c20032000360208200341246a410136020020034201370214200341c4e2cc003602102003410436022c2003200341286a3602202003200341086a360228200341106a20021044000b6901037f230041206b220224002001411c6a280200210320012802182104200241086a41106a2000280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a103d2101200241206a240020010b15002001200028020022002802002000280204104e0b8a0501077f0240024002402002450d000340024020002802082d0000450d00200028020041c59dc0004104200028020428020c110000450d0041010f0b4100210320022104024002400340200120036a210502400240200441074b0d002004450d03200220036b2106410021070340200520076a2d0000410a460d022006200741016a2207470d000c040b0b024002400240200541036a417c7120056b2207450d0020042007200720044b1b2106410021070340200520076a2d0000410a460d042006200741016a2207470d000b2006200441786a22084b0d020c010b200441786a2108410021060b02400340200520066a220741046a2802002209417f732009418a94a8d0007341fffdfb776a7120072802002207417f732007418a94a8d0007341fffdfb776a7172418081828478710d01200641086a220620084d0d000b0b200620044b0d070b20042006460d02200420066b21092001200620036a6a21054100210702400340200520076a2d0000410a460d012009200741016a2207470d000c040b0b200620076a21070b200720036a220741016a21030240200720024f0d00200120076a2d0000410a470d00410121070c030b200220036b2104200220034f0d000b0b41002107200221030b200028020820073a0000200028020421072000280200210602400240024020022003460d000240200220034d0d00200120036a22052c000041bf7f4a0d020b200120024100200341cc9dc000104f000b200620012002200728020c110000450d0141010f0b0240200620012003200728020c110000450d0041010f0b20052c000041bf7f4c0d040b200120036a2101200220036b22020d000b0b41000f0b20062004418c9ec0001056000b200120022003200241dc9dc000104f000b850201027f230041106b220224002002410036020c02400240024002402001418001490d002001418010490d012002410c6a21032001418080044f0d0220022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d410321010c030b200220013a000c2002410c6a2103410121010c020b20022001413f71418001723a000d2002200141067641c001723a000c2002410c6a2103410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b20002003200110602101200241106a240020010b6001017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41dc9ec000200241086a103d2101200241206a240020010b0d0020002802002001200210600b8c0201027f230041106b22022400200028020021002002410036020c02400240024002402001418001490d002001418010490d012002410c6a21032001418080044f0d0220022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d410321010c030b200220013a000c2002410c6a2103410121010c020b20022001413f71418001723a000d2002200141067641c001723a000c2002410c6a2103410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b20002003200110602101200241106a240020010b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41dc9ec000200241086a103d2101200241206a240020010bd40202047f027e230041c0006b2203240041012104024020002d00080d00200028020421050240200028020022062d0000410471450d00024020050d0041012104200628021841f59ec00041022006411c6a28020028020c1100000d02200028020021060b41012104200341013a0017200341346a41c09ec000360200200320062902183703082003200341176a3602102006290208210720062902102108200320062d00203a00382003200837032820032007370320200320062902003703182003200341086a3602302001200341186a200228020c1101000d01200328023041d89ec0004102200328023428020c11000021040c010b41012104200628021841bc9ec00041f49ec00020051b4102410120051b2006411c6a28020028020c1100000d0020012000280200200228020c11010021040b200020043a00082000200028020441016a360204200341c0006a240020000b840703017f027e027f02402002280200220341134c0d00024002400240200042808084fea6dee111540d002002200341706a2203360200200120036a200042808084fea6dee111802204428080fc81d9a19e6e7e20007c2200428080e983b1de1680a741ff017141e4007041017441de84c0006a2f00003b0000200228020020016a41026a20004280a094a58d1d80a741ffff037141e4007041017441de84c0006a2f00003b0000200228020020016a41046a20004280c8afa02580a741e4007041017441de84c0006a2f00003b0000200228020020016a41066a20004280c2d72f80a741e4007041017441de84c0006a2f00003b0000200228020020016a41086a200042c0843d8042e40082a741017441de84c0006a2f00003b0000200228020020016a410a6a20004290ce008042e40082a741017441de84c0006a2f00003b0000200228020020016a410c6a200042e40080220542e40082a741017441de84c0006a2f00003b00002005429c7f7e20007ca72103410e21060c010b024020004280c2d72f5a0d00200021040c020b2002200341786a2203360200200120036a20004280c2d72f8022044280bea8507e20007ca7220341c0843d6e41ff017141e4007041017441de84c0006a2f00003b0000200228020020016a41026a20034190ce006e41ffff037141e4007041017441de84c0006a2f00003b0000200228020020016a41046a200341e4006e220641e4007041017441de84c0006a2f00003b00002006419c7f6c20036a2103410621060b2001200228020020066a6a200341017441de84c0006a2f00003b00000b024002402004a722064190ce004f0d00200621030c010b20022002280200417c6a2203360200200120036a20064190ce006e220341f0b17f6c20066a220641ffff037141e4006e220741017441de84c0006a2f00003b0000200228020020016a41026a2007419c7f6c20066a41ffff037141017441de84c0006a2f00003b00000b0240200341ffff0371220641e400490d0020022002280200417e6a2207360200200120076a200641e4006e2206419c7f6c20036a41ffff037141017441de84c0006a2f00003b0000200621030b0240200341ffff037141094b0d0020022002280200417f6a2206360200200120066a200341306a3a00000f0b20022002280200417e6a2206360200200120066a200341ffff037141017441de84c0006a2f00003b00000f0b41fb9ec000411c41989fc0001039000bd108020b7f017e4101210302400240200228021841222002411c6a2802002802101101000d000240024020010d00410021040c010b200020016a21052000210641002104200021074100210802400340200641016a210902400240024020062c0000220a4100480d00200a41ff0171210b0c010b0240024020092005470d004100210b200521060c010b20062d0001413f71210b200641026a220921060b200a411f7121030240200a41ff0171220a41e0014f0d00200b200341067472210b0c010b0240024020062005470d004100210c2005210d0c010b20062d0000413f71210c200641016a2209210d0b200c200b41067472210b0240200a41f0014f0d00200b2003410c7472210b0c010b02400240200d2005470d004100210a200921060c010b200d41016a2106200d2d0000413f71210a0b200b4106742003411274418080f0007172200a72220b418080c400470d010c030b200921060b4102210941f400210d02400240024002400240024002400240200b41776a0e1f06010303000303030303030303030303030303030303030303040303030304020b41f200210d0c050b41ee00210d0c040b200b41dc00460d010b0240200b10530d00200b10540d040b200b41017267410276410773ad4280808080d00084210e410321090c010b0b200b210d0b0240024020082004490d0002402004450d0020042001460d00200420014f0d01200020046a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020046a200820046b200228021c28020c110000450d0141010f0b200020012004200841bc9fc000104f000b03402009210a4101210341dc00210441012109024002400240024002400240200a0e0402010500020b0240024002400240200e422088a741ff01710e06050302010006050b200e42ffffffff8f608342808080803084210e4103210941f50021040c070b200e42ffffffff8f608342808080802084210e4103210941fb0021040c060b413041d700200d200ea72209410274411c7176410f712204410a491b20046a2104024020090d00200e42ffffffff8f608342808080801084210e0c050b200e427f7c42ffffffff0f83200e4280808080708384210e0c040b200e42ffffffff8f6083210e4103210941fd0021040c040b41002109200d21040c030b410121090240200b418001490d0041022109200b418010490d0041034104200b41808004491b21090b200920086a21040c040b200e42ffffffff8f60834280808080c00084210e0b410321090b20022802182004200228021c2802101101000d050c000b0b200820076b20066a21082006210720052006470d000b0b2004450d0020042001460d00200420014f0d02200020046a2c000041bf7f4c0d020b410121032002280218200020046a200120046b200228021c28020c1100000d0020022802184122200228021c28021011010021030b20030f0b200020012004200141ac9fc000104f000b870101027f23004180016b2202240020002d00002103410021000340200220006a41ff006a20034101714130723a00002000417f6a2100200341017641ff007122030d000b024020004180016a2203418101490d002003418001419c88c0001056000b200141e79fc0004102200220006a4180016a410020006b104b210020024180016a240020000b1c00200128021841adb3c00041052001411c6a28020028020c1100000bcf0401067e2000420037001720002001290320220242338842137e2001290300220342ffffffffffffff03837c220442137c4233882001290308220542ffffffffffffff038320034233887c22037c4233882001290310220642ffffffffffffff038320054233887c22057c4233882001290318220742ffffffffffffff038320064233887c22067c423388200242ffffffffffffff038320074233887c22077c42338842137e20047c22023c0000200020024228883c0005200020024220883c0004200020024218883c0003200020024210883c0002200020024208883c00012000200242338820037c22044225883c000b20002004421d883c000a200020044215883c000920002004420d883c0008200020044205883c00072000200442338820057c2203422a883c0012200020034222883c001120002003421a883c0010200020034212883c000f20002003420a883c000e200020034202883c000d2000200442ffffffffffffff038322044203862002423088420783843c00062000200342338820067c2202421f883c0017200020024227883c0018200020024217883c001620002002420f883c0015200020024207883c00142000200342ffffffffffffff038322054206862004422d88843c000c2000200242338820077c22034204883c001a20002003420c883c001b200020034214883c001c20002003421c883c001d200020034224883c001e2000200242ffffffffffffff038322024201862005423288843c00132000200342ffffffffffffff03832203422c883c001f200020034204862002422f88843c00190b7101027f230041c0006b2202240020022000106b200241206a2001106b41002101410121000340200241206a20016a2d0000200220016a2d0000732203410020036b72417f7341800171410776106d2000712100200141016a22014120470d000b2000106d2101200241c0006a240020010b1501017f230041106b220120003a000f20012d000f0bd00702017f147e230041f0016b2203240020012903202104200129031821052001290310210620012903082107200129030021080340200341b0016a200842002008420010e80820034180016a20074200200442137e2209420010e808200341c0006a200542137e220a42002006420010e808200341e0016a200a42002005420010e808200341f0006a200842002007420010e808200341306a200642002009420010e808200341e0006a200742002007420010e808200341206a200842002006420010e808200341d0016a200a42002004420010e808200341c0016a200942002004420010e808200341a0016a200842002005420010e808200341106a200742002006420010e8082003200642002006420010e80820034190016a200842002004420010e808200341d0006a200742002005420010e808200329039001220b20032903507c2206420186220c20032903007c220720032903a001220d20032903107c2208420186220e20032903c0017c22042003290320220f20032903d0017c2205420186221020032903607c22092003290370221120032903307c220a420186221220032903e0017c2213200329038001221420032903407c2215420186221620032903b0017c221742338820034180016a41086a290300200341c0006a41086a2903007c2015201454ad7c4201862015423f8884200341b0016a41086a2903007c2017201654ad7c420d86847c2215423388200341f0006a41086a290300200341306a41086a2903007c200a201154ad7c420186200a423f8884200341e0016a41086a2903007c2013201254ad7c2015201354ad7c420d86847c220a423388200341206a41086a290300200341d0016a41086a2903007c2005200f54ad7c4201862005423f8884200341e0006a41086a2903007c2009201054ad7c200a200954ad7c420d86847c2205423388200341a0016a41086a290300200341106a41086a2903007c2008200d54ad7c4201862008423f8884200341c0016a41086a2903007c2004200e54ad7c2005200454ad7c420d86847c220442338820034190016a41086a290300200341d0006a41086a2903007c2006200b54ad7c4201862006423f8884200341086a2903007c2007200c54ad7c2004200754ad7c420d868442137e201742ffffffffffffff03837c220642ffffffffffffff038321082006423388201542ffffffffffffff03837c2107200442ffffffffffffff03832104200542ffffffffffffff03832105200a42ffffffffffffff038321062002417f6a22020d000b2000200437032020002005370318200020063703102000200737030820002008370300200341f0016a24000bbbd40103017f297e037f230041d0c1006b22032400200341a8c1006a20024101106e200341a0386a20022903002204420020032903a8412205420010e808200341b0396a20032903c841220642002002290308220742137e2208420010e808200341f0396a20032903c041220942002002290310220a42137e220b420010e808200341b03a6a20032903b841220c42002002290318220d42137e220e420010e808200341f03a6a20032903b041220f42002002290320221042137e2211420010e808200341f0386a200f42002004420010e808200341b0386a200542002007420010e808200341c0396a20064200200b420010e808200341803a6a20094200200e420010e808200341c03a6a200c42002011420010e80820034180396a200c42002004420010e808200341803b6a200f42002007420010e808200341c0386a20054200200a420010e808200341d0396a20064200200e420010e808200341903a6a200942002011420010e80820034190396a200942002004420010e808200341d03a6a200c42002007420010e808200341903b6a200f4200200a420010e808200341d0386a20054200200d420010e808200341e0396a200642002011420010e808200341a0396a200642002004420010e808200341a03a6a200942002007420010e808200341e03a6a200c4200200a420010e808200341a03b6a200f4200200d420010e808200341e0386a200542002010420010e808200320032903d039221220032903c0387c220520032903903a7c22062003290380397c220920032903803b7c220c20032903c039221320032903b0387c220f20032903803a7c221420032903c03a7c221520032903f0387c221620032903b039221720032903a0387c221820032903f0397c221920032903b03a7c221a20032903f03a7c221b423388200341b0396a41086a290300200341a0386a41086a2903007c2018201754ad7c200341f0396a41086a2903007c2019201854ad7c200341b03a6a41086a2903007c201a201954ad7c200341f03a6a41086a2903007c201b201a54ad7c420d86847c2219423388200341c0396a41086a290300200341b0386a41086a2903007c200f201354ad7c200341803a6a41086a2903007c2014200f54ad7c200341c03a6a41086a2903007c2015201454ad7c200341f0386a41086a2903007c2016201554ad7c2019201654ad7c420d86847c220f42ffffffffffffff038322143703c03b200320032903e039221720032903d0387c22152003290390397c221620032903d03a7c221a20032903903b7c2213200f423388200341d0396a41086a290300200341c0386a41086a2903007c2005201254ad7c200341903a6a41086a2903007c2006200554ad7c20034180396a41086a2903007c2009200654ad7c200341803b6a41086a2903007c200c200954ad7c200f200c54ad7c420d86847c220542ffffffffffffff038322183703c83b200320032903a039221220032903e0387c220620032903a03a7c220920032903e03a7c220c20032903a03b7c220f2005423388200341e0396a41086a290300200341d0386a41086a2903007c2015201754ad7c20034190396a41086a2903007c2016201554ad7c200341d03a6a41086a2903007c201a201654ad7c200341903b6a41086a2903007c2013201a54ad7c2005201354ad7c420d86847c220542ffffffffffffff0383221a3703d03b20032005423388200341a0396a41086a290300200341e0386a41086a2903007c2006201254ad7c200341a03a6a41086a2903007c2009200654ad7c200341e03a6a41086a2903007c200c200954ad7c200341a03b6a41086a2903007c200f200c54ad7c2005200f54ad7c420d868442137e201b42ffffffffffffff03837c220542ffffffffffffff0383220c3703b03b20032005423388201942ffffffffffffff03837c220f3703b83b200341a8c1006a200341b03b6a4101106e20034190356a20032903a841220542002004420010e808200341e0356a20032903c841220642002008420010e808200341b0366a20032903c04122094200200b420010e80820034180376a20032903b84122154200200e420010e808200341d0376a20032903b041221642002011420010e808200341e0376a201642002004420010e808200341a0356a200542002007420010e808200341f0356a20064200200b420010e808200341c0366a20094200200e420010e80820034190376a201542002011420010e808200341a0376a201542002004420010e808200341f0376a201642002007420010e808200341b0356a20054200200a420010e80820034180366a20064200200e420010e808200341d0366a200942002011420010e808200341e0366a200942002004420010e808200341b0376a201542002007420010e80820034180386a20164200200a420010e808200341c0356a20054200200d420010e80820034190366a200642002011420010e808200341a0366a200642002004420010e808200341f0366a200942002007420010e808200341c0376a20154200200a420010e80820034190386a20164200200d420010e808200341d0356a200542002010420010e808200341800d6a200c420020012903002211420010e80820034190346a200f42137e42002001290320220e420010e808200341d0336a200129031822054200201442137e220b420010e80820034190336a200129031022064200201842137e2216420010e808200341c0326a200129030822094200201a42137e2215420010e808200341f00c6a20094200200c420010e80820034180356a200f42002011420010e80820034180346a200e4200200b420010e808200341c0336a200542002016420010e80820034180336a200642002015420010e808200341e00c6a200c42002006420010e808200341b0326a200f42002009420010e808200341f0346a201142002014420010e808200341f0336a200e42002016420010e808200341b0336a200542002015420010e808200341800c6a200c42002005420010e808200341f0326a200f42002006420010e808200341a0326a200942002014420010e808200341e0346a201142002018420010e808200341e0336a20154200200e420010e808200341a00b6a200c4200200e420010e808200341a0336a200f42002005420010e808200341e0326a200642002014420010e80820034190326a200942002018420010e808200341d0346a201a42002011420010e80820034180306a20032903a036221c20032903d0357c220c20032903f0367c220f20032903c0377c22142003290390387c2215200329039036221d20032903c0357c221620032903e0367c220b20032903b0377c22182003290380387c2219200329038036221e20032903b0357c221a20032903d0367c221b20032903a0377c221320032903f0377c220820032903f035221f20032903a0357c221220032903c0367c22172003290390377c222020032903e0377c222120032903e03522222003290390357c222320032903b0367c22242003290380377c222520032903d0377c2226423388200341e0356a41086a29030020034190356a41086a2903007c2023202254ad7c200341b0366a41086a2903007c2024202354ad7c20034180376a41086a2903007c2025202454ad7c200341d0376a41086a2903007c2026202554ad7c420d86847c2223423388200341f0356a41086a290300200341a0356a41086a2903007c2012201f54ad7c200341c0366a41086a2903007c2017201254ad7c20034190376a41086a2903007c2020201754ad7c200341e0376a41086a2903007c2021202054ad7c2023202154ad7c420d86847c221242338820034180366a41086a290300200341b0356a41086a2903007c201a201e54ad7c200341d0366a41086a2903007c201b201a54ad7c200341a0376a41086a2903007c2013201b54ad7c200341f0376a41086a2903007c2008201354ad7c2012200854ad7c420d86847c221a42338820034190366a41086a290300200341c0356a41086a2903007c2016201d54ad7c200341e0366a41086a2903007c200b201654ad7c200341b0376a41086a2903007c2018200b54ad7c20034180386a41086a2903007c2019201854ad7c201a201954ad7c420d86847c2216423388200341a0366a41086a290300200341d0356a41086a2903007c200c201c54ad7c200341f0366a41086a2903007c200f200c54ad7c200341c0376a41086a2903007c2014200f54ad7c20034190386a41086a2903007c2015201454ad7c2016201554ad7c420d868442137e202642ffffffffffffff03837c220f42ffffffffffffff0383220c42002011420010e808200341d0306a200f423388202342ffffffffffffff03837c220f42137e4200200e420010e808200341f0306a201242ffffffffffffff0383221442137e221942002005420010e808200341a0316a201a42ffffffffffffff0383220b42137e221842002006420010e808200341e0316a201642ffffffffffffff0383221642137e221542002009420010e808200341f02f6a200c42002009420010e808200341c0306a200f42002011420010e808200341e0306a20194200200e420010e80820034190316a201842002005420010e808200341d0316a201542002006420010e808200341e02f6a200c42002006420010e808200341b0306a200f42002009420010e808200341c0346a201442002011420010e80820034180316a20184200200e420010e808200341c0316a201542002005420010e808200341d02f6a200c42002005420010e808200341a0306a200f42002006420010e80820034180326a201442002009420010e808200341b0346a200b42002011420010e808200341b0316a20154200200e420010e808200341c02f6a200c4200200e420010e80820034190306a200f42002005420010e808200341d0326a201442002006420010e808200341f0316a200b42002009420010e808200341a0346a201642002011420010e8082003200329038031221220032903c0347c220f20032903c0317c221420032903e02f7c221520032903b0307c2216200329039031221720032903e0307c220c20032903d0317c220b20032903f02f7c221820032903c0307c221920032903a031222020032903f0307c221a20032903e0317c221b2003290380307c221320032903d0307c2208423388200341a0316a41086a290300200341f0306a41086a2903007c201a202054ad7c200341e0316a41086a2903007c201b201a54ad7c20034180306a41086a2903007c2013201b54ad7c200341d0306a41086a2903007c2008201354ad7c420d86847c221a42338820034190316a41086a290300200341e0306a41086a2903007c200c201754ad7c200341d0316a41086a2903007c200b200c54ad7c200341f02f6a41086a2903007c2018200b54ad7c200341c0306a41086a2903007c2019201854ad7c201a201954ad7c420d86847c220b42ffffffffffffff0383220c3703e83b200320032903b03422172003290380327c221820032903b0317c221920032903d02f7c221b20032903a0307c2213200b42338820034180316a41086a290300200341c0346a41086a2903007c200f201254ad7c200341c0316a41086a2903007c2014200f54ad7c200341e02f6a41086a2903007c2015201454ad7c200341b0306a41086a2903007c2016201554ad7c200b201654ad7c420d86847c221442ffffffffffffff0383220f3703f03b200320032903f031222020032903d0327c221520032903a0347c221620032903c02f7c220b2003290390307c22122014423388200341b0346a41086a29030020034180326a41086a2903007c2018201754ad7c200341b0316a41086a2903007c2019201854ad7c200341d02f6a41086a2903007c201b201954ad7c200341a0306a41086a2903007c2013201b54ad7c2014201354ad7c420d86847c221842ffffffffffffff038322143703f83b20032018423388200341f0316a41086a290300200341d0326a41086a2903007c2015202054ad7c200341a0346a41086a2903007c2016201554ad7c200341c02f6a41086a2903007c200b201654ad7c20034190306a41086a2903007c2012200b54ad7c2018201254ad7c420d868442137e200842ffffffffffffff03837c221642ffffffffffffff038322153703d83b20032016423388201a42ffffffffffffff03837c22163703e03b200341803c6a200341d83b6a4101106e200341a8c1006a200341803c6a4101106e200341a83c6a200341a8c1006a4101106e200341b02f6a20032903a83c220b42002015420010e808200341b02c6a2014420020032903b03c221842137e420010e808200341902d6a200f420020032903b83c221942137e2208420010e808200341f02d6a200c420020032903c03c221b42137e2213420010e808200341d02e6a2016420020032903c83c221242137e221a420010e808200341a02f6a20164200200b420010e808200341f02c6a201542002018420010e808200341802d6a201442002008420010e808200341e02d6a200f42002013420010e808200341c02e6a200c4200201a420010e808200341902f6a200c4200200b420010e808200341e02c6a201642002018420010e808200341c02d6a201542002019420010e808200341d02d6a201442002013420010e808200341b02e6a200f4200201a420010e808200341802f6a200f4200200b420010e808200341d02c6a200c42002018420010e808200341b02d6a201642002019420010e808200341902e6a20154200201b420010e808200341a02e6a20144200201a420010e808200341f02e6a20144200200b420010e808200341c02c6a200f42002018420010e808200341a02d6a200c42002019420010e808200341802e6a20164200201b420010e808200341e02e6a201542002012420010e808200341e0296a20032903f02e222720032903e02e7c220b20032903c02c7c221820032903a02d7c221920032903802e7c221a20032903a02e222820032903902e7c221b20032903802f7c221320032903d02c7c220820032903b02d7c221220032903d02d222920032903c02d7c221720032903b02e7c222020032903902f7c222120032903e02c7c222320032903802d222a20032903f02c7c222420032903e02d7c222520032903c02e7c222620032903a02f7c221c20032903b02c222b20032903b02f7c221d20032903902d7c221e20032903f02d7c221f20032903d02e7c2222423388200341b02c6a41086a290300200341b02f6a41086a2903007c201d202b54ad7c200341902d6a41086a2903007c201e201d54ad7c200341f02d6a41086a2903007c201f201e54ad7c200341d02e6a41086a2903007c2022201f54ad7c420d86847c221d423388200341802d6a41086a290300200341f02c6a41086a2903007c2024202a54ad7c200341e02d6a41086a2903007c2025202454ad7c200341c02e6a41086a2903007c2026202554ad7c200341a02f6a41086a2903007c201c202654ad7c201d201c54ad7c420d86847c2224423388200341d02d6a41086a290300200341c02d6a41086a2903007c2017202954ad7c200341b02e6a41086a2903007c2020201754ad7c200341902f6a41086a2903007c2021202054ad7c200341e02c6a41086a2903007c2023202154ad7c2024202354ad7c420d86847c2217423388200341a02e6a41086a290300200341902e6a41086a2903007c201b202854ad7c200341802f6a41086a2903007c2013201b54ad7c200341d02c6a41086a2903007c2008201354ad7c200341b02d6a41086a2903007c2012200854ad7c2017201254ad7c420d86847c221b423388200341f02e6a41086a290300200341e02e6a41086a2903007c200b202754ad7c200341c02c6a41086a2903007c2018200b54ad7c200341a02d6a41086a2903007c2019201854ad7c200341802e6a41086a2903007c201a201954ad7c201b201a54ad7c420d868442137e202242ffffffffffffff03837c221842ffffffffffffff0383220b420020032903803c2213420010e808200341b02a6a2018423388201d42ffffffffffffff03837c221842137e420020032903a03c2208420010e808200341d02a6a202442ffffffffffffff0383221942137e2224420020032903983c2212420010e808200341802b6a201742ffffffffffffff0383221a42137e2223420020032903903c2217420010e808200341c02b6a201b42ffffffffffffff0383221b42137e2221420020032903883c2220420010e808200341d0296a200b42002020420010e808200341a02a6a201842002013420010e808200341c02a6a202442002008420010e808200341f02a6a202342002012420010e808200341b02b6a202142002017420010e808200341c0296a200b42002017420010e808200341902a6a201842002020420010e808200341d02b6a201942002013420010e808200341e02a6a202342002008420010e808200341a02b6a202142002012420010e808200341b0296a200b42002012420010e808200341802a6a201842002017420010e808200341e02b6a201942002020420010e808200341802c6a201a42002013420010e808200341902b6a202142002008420010e808200341a0296a200b42002008420010e808200341f0296a201842002012420010e808200341f02b6a201942002017420010e808200341902c6a201a42002020420010e808200341a02c6a201b42002013420010e808200320032903e02a221e20032903d02b7c221320032903a02b7c220820032903c0297c221220032903902a7c221720032903f02a221f20032903c02a7c222020032903b02b7c222120032903d0297c222320032903a02a7c222420032903802b222220032903d02a7c222520032903c02b7c222620032903e0297c221c20032903b02a7c221d423388200341802b6a41086a290300200341d02a6a41086a2903007c2025202254ad7c200341c02b6a41086a2903007c2026202554ad7c200341e0296a41086a2903007c201c202654ad7c200341b02a6a41086a2903007c201d201c54ad7c420d86847c2225423388200341f02a6a41086a290300200341c02a6a41086a2903007c2020201f54ad7c200341b02b6a41086a2903007c2021202054ad7c200341d0296a41086a2903007c2023202154ad7c200341a02a6a41086a2903007c2024202354ad7c2025202454ad7c420d86847c222042ffffffffffffff03833703e03c200320032903802c221c20032903e02b7c222120032903902b7c222320032903b0297c222420032903802a7c22262020423388200341e02a6a41086a290300200341d02b6a41086a2903007c2013201e54ad7c200341a02b6a41086a2903007c2008201354ad7c200341c0296a41086a2903007c2012200854ad7c200341902a6a41086a2903007c2017201254ad7c2020201754ad7c420d86847c221342ffffffffffffff03833703e83c200320032903902c221e20032903f02b7c220820032903a02c7c221220032903a0297c221720032903f0297c22202013423388200341802c6a41086a290300200341e02b6a41086a2903007c2021201c54ad7c200341902b6a41086a2903007c2023202154ad7c200341b0296a41086a2903007c2024202354ad7c200341802a6a41086a2903007c2026202454ad7c2013202654ad7c420d86847c221342ffffffffffffff03833703f03c20032013423388200341902c6a41086a290300200341f02b6a41086a2903007c2008201e54ad7c200341a02c6a41086a2903007c2012200854ad7c200341a0296a41086a2903007c2017201254ad7c200341f0296a41086a2903007c2020201754ad7c2013202054ad7c420d868442137e201d42ffffffffffffff03837c221342ffffffffffffff03833703d03c20032013423388202542ffffffffffffff03837c3703d83c200341f83c6a200341d03c6a4101106e20034190296a200b420020032903f83c2213420010e80820034190266a201b420020032903803d220842137e420010e808200341f0266a20032903883d221242137e22234200201a420010e808200341d0276a20032903903d222042137e222142002019420010e808200341b0286a2018420020032903983d222442137e2217420010e80820034180296a201842002013420010e808200341d0266a200b42002008420010e808200341e0266a201b42002023420010e808200341c0276a20214200201a420010e808200341a0286a201742002019420010e808200341f0286a201342002019420010e808200341c0266a201842002008420010e808200341a0276a200b42002012420010e808200341b0276a20214200201b420010e80820034190286a20174200201a420010e808200341e0286a20134200201a420010e808200341b0266a200842002019420010e80820034190276a201842002012420010e808200341f0276a200b42002020420010e80820034180286a20174200201b420010e808200341d0286a20134200201b420010e808200341a0266a20084200201a420010e80820034180276a201242002019420010e808200341e0276a201842002020420010e808200341c0286a200b42002024420010e8082003200329039028222520032903b0277c220b20032903f0287c221820032903a0277c221a20032903c0267c221b20032903c027222420032903e0267c221920032903a0287c221320032903d0267c22082003290380297c221220032903f02622262003290390267c221720032903d0277c22202003290390297c222120032903b0287c2223423388200341f0266a41086a29030020034190266a41086a2903007c2017202654ad7c200341d0276a41086a2903007c2020201754ad7c20034190296a41086a2903007c2021202054ad7c200341b0286a41086a2903007c2023202154ad7c420d86847c2220423388200341c0276a41086a290300200341e0266a41086a2903007c2019202454ad7c200341a0286a41086a2903007c2013201954ad7c200341d0266a41086a2903007c2008201354ad7c20034180296a41086a2903007c2012200854ad7c2020201254ad7c420d86847c221342ffffffffffffff038322193703b03d2003200329038028222620032903b0267c220820032903e0287c221220032903f0277c22212003290390277c2224201342338820034190286a41086a290300200341b0276a41086a2903007c200b202554ad7c200341f0286a41086a2903007c2018200b54ad7c200341a0276a41086a2903007c201a201854ad7c200341c0266a41086a2903007c201b201a54ad7c2013201b54ad7c420d86847c220b42ffffffffffffff038322173703b83d2003200329038027222520032903a0267c221820032903d0287c221a20032903c0287c221b20032903e0277c2213200b42338820034180286a41086a290300200341b0266a41086a2903007c2008202654ad7c200341e0286a41086a2903007c2012200854ad7c200341f0276a41086a2903007c2021201254ad7c20034190276a41086a2903007c2024202154ad7c200b202454ad7c420d86847c220b42ffffffffffffff038322213703c03d2003200b42338820034180276a41086a290300200341a0266a41086a2903007c2018202554ad7c200341d0286a41086a2903007c201a201854ad7c200341c0286a41086a2903007c201b201a54ad7c200341e0276a41086a2903007c2013201b54ad7c200b201354ad7c420d868442137e202342ffffffffffffff03837c221842ffffffffffffff0383220b3703a03d20032018423388202042ffffffffffffff03837c22183703a83d200341c83d6a200341a03d6a4105106e200341c0236a200b420020032903c83d221a420010e808200341c0246a201842137e420020032903e83d221b420010e80820034180256a201942137e2224420020032903e03d2213420010e808200341c0256a201742137e2223420020032903d83d2208420010e80820034180266a202142137e2220420020032903d03d2212420010e808200341b0236a200b42002012420010e80820034180246a20184200201a420010e808200341b0246a20244200201b420010e808200341f0246a202342002013420010e808200341b0256a202042002008420010e808200341a0236a200b42002008420010e808200341f0256a201842002012420010e808200341f0236a20194200201a420010e808200341a0246a20234200201b420010e808200341e0246a202042002013420010e80820034190236a200b42002013420010e808200341a0256a201842002008420010e808200341e0256a201942002012420010e808200341e0236a20174200201a420010e80820034190246a20204200201b420010e80820034180236a200b4200201b420010e808200341d0246a201842002013420010e80820034190256a201942002008420010e808200341d0256a201742002012420010e808200341d0236a20214200201a420010e808200320032903a024222420032903f0237c220b20032903e0247c221820032903a0237c221a20032903f0257c221b20032903f024222520032903b0247c221920032903b0257c221320032903b0237c22082003290380247c221220032903c02522262003290380257c22172003290380267c222020032903c0237c222120032903c0247c2223423388200341c0256a41086a29030020034180256a41086a2903007c2017202654ad7c20034180266a41086a2903007c2020201754ad7c200341c0236a41086a2903007c2021202054ad7c200341c0246a41086a2903007c2023202154ad7c420d86847c2217423388200341f0246a41086a290300200341b0246a41086a2903007c2019202554ad7c200341b0256a41086a2903007c2013201954ad7c200341b0236a41086a2903007c2008201354ad7c20034180246a41086a2903007c2012200854ad7c2017201254ad7c420d86847c221342ffffffffffffff038322193703803e200320032903e023222520032903e0257c22082003290390247c22122003290390237c222020032903a0257c22212013423388200341a0246a41086a290300200341f0236a41086a2903007c200b202454ad7c200341e0246a41086a2903007c2018200b54ad7c200341a0236a41086a2903007c201a201854ad7c200341f0256a41086a2903007c201b201a54ad7c2013201b54ad7c420d86847c220b42ffffffffffffff0383221b3703883e200320032903d025221c2003290390257c221820032903d0237c221a2003290380237c221320032903d0247c2224200b423388200341e0236a41086a290300200341e0256a41086a2903007c2008202554ad7c20034190246a41086a2903007c2012200854ad7c20034190236a41086a2903007c2020201254ad7c200341a0256a41086a2903007c2021202054ad7c200b202154ad7c420d86847c220b42ffffffffffffff038322263703903e2003200b423388200341d0256a41086a29030020034190256a41086a2903007c2018201c54ad7c200341d0236a41086a2903007c201a201854ad7c20034180236a41086a2903007c2013201a54ad7c200341d0246a41086a2903007c2024201354ad7c200b202454ad7c420d868442137e202342ffffffffffffff03837c221842ffffffffffffff0383220b3703f03d20032018423388201742ffffffffffffff03837c22183703f83d200341983e6a200341f03d6a410a106e200341b0206a200b420020032903983e2208420010e80820034180216a201842137e2228420020032903b83e2212420010e808200341d0216a201942137e221c420020032903b03e2217420010e808200341a0226a201b42137e2213420020032903a83e2220420010e808200341f0226a202642137e221a420020032903a03e2221420010e808200341e0226a200b42002021420010e808200341a0206a201842002008420010e808200341f0206a201c42002012420010e808200341c0216a201342002017420010e80820034190226a201a42002020420010e80820034180226a200b42002020420010e808200341d0226a201842002021420010e80820034190206a201942002008420010e808200341e0206a201342002012420010e808200341b0216a201a42002017420010e808200341a0216a200b42002017420010e808200341f0216a201842002020420010e808200341c0226a201942002021420010e80820034180206a201b42002008420010e808200341d0206a201a42002012420010e808200341c0206a200b42002012420010e80820034190216a201842002017420010e808200341e0216a201942002020420010e808200341b0226a201b42002021420010e808200341f01f6a202642002008420010e808200320032903e02022292003290390207c220820032903b0217c22122003290380227c222020032903d0227c222120032903c021222720032903f0207c22172003290390227c222320032903e0227c222420032903a0207c222520032903a022222a20032903d0217c221d20032903f0227c221e20032903b0207c221f2003290380217c2222423388200341a0226a41086a290300200341d0216a41086a2903007c201d202a54ad7c200341f0226a41086a2903007c201e201d54ad7c200341b0206a41086a2903007c201f201e54ad7c20034180216a41086a2903007c2022201f54ad7c420d86847c221e423388200341c0216a41086a290300200341f0206a41086a2903007c2017202754ad7c20034190226a41086a2903007c2023201754ad7c200341e0226a41086a2903007c2024202354ad7c200341a0206a41086a2903007c2025202454ad7c201e202554ad7c420d86847c222342ffffffffffffff038322173703d03e2003200329038020222a20032903c0227c222420032903d0207c222520032903a0217c221f20032903f0217c22272023423388200341e0206a41086a29030020034190206a41086a2903007c2008202954ad7c200341b0216a41086a2903007c2012200854ad7c20034180226a41086a2903007c2020201254ad7c200341d0226a41086a2903007c2021202054ad7c2023202154ad7c420d86847c220842ffffffffffffff0383221d3703d83e200320032903b022222920032903e0217c221220032903f01f7c222020032903c0207c22212003290390217c2223200842338820034180206a41086a290300200341c0226a41086a2903007c2024202a54ad7c200341d0206a41086a2903007c2025202454ad7c200341a0216a41086a2903007c201f202554ad7c200341f0216a41086a2903007c2027201f54ad7c2008202754ad7c420d86847c220842ffffffffffffff0383221f3703e03e20032008423388200341b0226a41086a290300200341e0216a41086a2903007c2012202954ad7c200341f01f6a41086a2903007c2020201254ad7c200341c0206a41086a2903007c2021202054ad7c20034190216a41086a2903007c2023202154ad7c2008202354ad7c420d868442137e202242ffffffffffffff03837c221242ffffffffffffff038322083703c03e20032012423388201e42ffffffffffffff03837c22123703c83e200341e83e6a200341c03e6a4114106e200341a01d6a2008420020032903e83e2220420010e808200341f01d6a201242137e420020032903883f2221420010e808200341c01e6a201742137e2227420020032903803f2223420010e808200341901f6a201d42137e2222420020032903f83e2224420010e808200341e01f6a201f42137e221e420020032903f03e2225420010e808200341d01f6a200842002025420010e808200341901d6a201242002020420010e808200341e01d6a202742002021420010e808200341b01e6a202242002023420010e808200341801f6a201e42002024420010e808200341f01e6a200842002024420010e808200341c01f6a201242002025420010e808200341801d6a201742002020420010e808200341d01d6a202242002021420010e808200341a01e6a201e42002023420010e808200341901e6a200842002023420010e808200341e01e6a201242002024420010e808200341b01f6a201742002025420010e808200341f01c6a201d42002020420010e808200341c01d6a201e42002021420010e808200341b01d6a200842002021420010e808200341801e6a201242002023420010e808200341d01e6a201742002024420010e808200341a01f6a201d42002025420010e808200341e01c6a201f42002020420010e808200320032903d01d222720032903801d7c220820032903a01e7c221220032903f01e7c221720032903c01f7c222020032903b01e222920032903e01d7c222120032903801f7c222320032903d01f7c222420032903901d7c222520032903901f222a20032903c01e7c221d20032903e01f7c221e20032903a01d7c221f20032903f01d7c2222423388200341901f6a41086a290300200341c01e6a41086a2903007c201d202a54ad7c200341e01f6a41086a2903007c201e201d54ad7c200341a01d6a41086a2903007c201f201e54ad7c200341f01d6a41086a2903007c2022201f54ad7c420d86847c221d423388200341b01e6a41086a290300200341e01d6a41086a2903007c2021202954ad7c200341801f6a41086a2903007c2023202154ad7c200341d01f6a41086a2903007c2024202354ad7c200341901d6a41086a2903007c2025202454ad7c201d202554ad7c420d86847c222142ffffffffffffff03833703a03f200320032903f01c221f20032903b01f7c222320032903c01d7c222420032903901e7c222520032903e01e7c221e2021423388200341d01d6a41086a290300200341801d6a41086a2903007c2008202754ad7c200341a01e6a41086a2903007c2012200854ad7c200341f01e6a41086a2903007c2017201254ad7c200341c01f6a41086a2903007c2020201754ad7c2021202054ad7c420d86847c220842ffffffffffffff03833703a83f200320032903a01f222720032903d01e7c221220032903e01c7c221720032903b01d7c222020032903801e7c22212008423388200341f01c6a41086a290300200341b01f6a41086a2903007c2023201f54ad7c200341c01d6a41086a2903007c2024202354ad7c200341901e6a41086a2903007c2025202454ad7c200341e01e6a41086a2903007c201e202554ad7c2008201e54ad7c420d86847c220842ffffffffffffff03833703b03f20032008423388200341a01f6a41086a290300200341d01e6a41086a2903007c2012202754ad7c200341e01c6a41086a2903007c2017201254ad7c200341b01d6a41086a2903007c2020201754ad7c200341801e6a41086a2903007c2021202054ad7c2008202154ad7c420d868442137e202242ffffffffffffff03837c220842ffffffffffffff03833703903f20032008423388201d42ffffffffffffff03837c3703983f200341b83f6a200341903f6a410a106e200341901a6a200b420020032903b83f2208420010e808200341e01a6a2028420020032903d83f2212420010e808200341b01b6a20032903d03f22174200201c420010e808200341801c6a20032903c83f222042002013420010e808200341d01c6a20032903c03f22214200201a420010e808200341c01c6a20214200200b420010e808200341801a6a201842002008420010e808200341d01a6a20124200201c420010e808200341a01b6a201742002013420010e808200341f01b6a20204200201a420010e808200341e01b6a20204200200b420010e808200341b01c6a202142002018420010e808200341f0196a200842002019420010e808200341c01a6a201242002013420010e808200341901b6a20174200201a420010e808200341801b6a20174200200b420010e808200341d01b6a202042002018420010e808200341a01c6a202142002019420010e808200341e0196a20084200201b420010e808200341b01a6a20124200201a420010e808200341a01a6a20124200200b420010e808200341f01a6a201742002018420010e808200341c01b6a202042002019420010e808200341901c6a20214200201b420010e808200341d0196a200842002026420010e808200320032903c01a222420032903f0197c220b20032903901b7c221820032903e01b7c221a20032903b01c7c221b20032903801a222520032903d01a7c221920032903a01b7c221320032903f01b7c220820032903c01c7c221220032903b01b222620032903901a7c221720032903e01a7c222020032903801c7c222120032903d01c7c2223423388200341b01b6a41086a290300200341901a6a41086a2903007c2017202654ad7c200341e01a6a41086a2903007c2020201754ad7c200341801c6a41086a2903007c2021202054ad7c200341d01c6a41086a2903007c2023202154ad7c420d86847c2217423388200341801a6a41086a290300200341d01a6a41086a2903007c2019202554ad7c200341a01b6a41086a2903007c2013201954ad7c200341f01b6a41086a2903007c2008201354ad7c200341c01c6a41086a2903007c2012200854ad7c2017201254ad7c420d86847c221342ffffffffffffff038322193703f03f200320032903b01a222520032903e0197c220820032903801b7c221220032903d01b7c222020032903a01c7c22212013423388200341c01a6a41086a290300200341f0196a41086a2903007c200b202454ad7c200341901b6a41086a2903007c2018200b54ad7c200341e01b6a41086a2903007c201a201854ad7c200341b01c6a41086a2903007c201b201a54ad7c2013201b54ad7c420d86847c220b42ffffffffffffff0383221b3703f83f200320032903a01a221c20032903d0197c221820032903f01a7c221a20032903c01b7c221320032903901c7c2224200b423388200341b01a6a41086a290300200341e0196a41086a2903007c2008202554ad7c200341801b6a41086a2903007c2012200854ad7c200341d01b6a41086a2903007c2020201254ad7c200341a01c6a41086a2903007c2021202054ad7c200b202154ad7c420d86847c220b42ffffffffffffff03832226370380402003200b423388200341a01a6a41086a290300200341d0196a41086a2903007c2018201c54ad7c200341f01a6a41086a2903007c201a201854ad7c200341c01b6a41086a2903007c2013201a54ad7c200341901c6a41086a2903007c2024201354ad7c200b202454ad7c420d868442137e202342ffffffffffffff03837c221842ffffffffffffff0383220b3703e03f20032018423388201742ffffffffffffff03837c22183703e83f20034188c0006a200341e03f6a4132106e20034180176a200b42002003290388402208420010e808200341d0176a201842137e2228420020032903a8402212420010e808200341a0186a201942137e221c420020032903a0402217420010e808200341f0186a201b42137e221342002003290398402220420010e808200341c0196a202642137e221a42002003290390402221420010e808200341b0196a200b42002021420010e808200341f0166a201842002008420010e808200341c0176a201c42002012420010e80820034190186a201342002017420010e808200341e0186a201a42002020420010e808200341d0186a200b42002020420010e808200341a0196a201842002021420010e808200341e0166a201942002008420010e808200341b0176a201342002012420010e80820034180186a201a42002017420010e808200341f0176a200b42002017420010e808200341c0186a201842002020420010e80820034190196a202142002019420010e808200341d0166a201b42002008420010e808200341a0176a201a42002012420010e80820034190176a200b42002012420010e808200341e0176a201842002017420010e808200341b0186a201942002020420010e80820034180196a201b42002021420010e808200341c0166a202642002008420010e808200320032903b017222920032903e0167c22082003290380187c221220032903d0187c222020032903a0197c2221200329039018222720032903c0177c221720032903e0187c222320032903b0197c222420032903f0167c222520032903f018222a20032903a0187c221d20032903c0197c221e2003290380177c221f20032903d0177c2222423388200341f0186a41086a290300200341a0186a41086a2903007c201d202a54ad7c200341c0196a41086a2903007c201e201d54ad7c20034180176a41086a2903007c201f201e54ad7c200341d0176a41086a2903007c2022201f54ad7c420d86847c221e42338820034190186a41086a290300200341c0176a41086a2903007c2017202754ad7c200341e0186a41086a2903007c2023201754ad7c200341b0196a41086a2903007c2024202354ad7c200341f0166a41086a2903007c2025202454ad7c201e202554ad7c420d86847c222342ffffffffffffff038322173703c040200320032903d016222a2003290390197c222420032903a0177c222520032903f0177c221f20032903c0187c22272023423388200341b0176a41086a290300200341e0166a41086a2903007c2008202954ad7c20034180186a41086a2903007c2012200854ad7c200341d0186a41086a2903007c2020201254ad7c200341a0196a41086a2903007c2021202054ad7c2023202154ad7c420d86847c220842ffffffffffffff0383221d3703c8402003200329038019222920032903b0187c221220032903c0167c22202003290390177c222120032903e0177c22232008423388200341d0166a41086a29030020034190196a41086a2903007c2024202a54ad7c200341a0176a41086a2903007c2025202454ad7c200341f0176a41086a2903007c201f202554ad7c200341c0186a41086a2903007c2027201f54ad7c2008202754ad7c420d86847c220842ffffffffffffff0383221f3703d0402003200842338820034180196a41086a290300200341b0186a41086a2903007c2012202954ad7c200341c0166a41086a2903007c2020201254ad7c20034190176a41086a2903007c2021202054ad7c200341e0176a41086a2903007c2023202154ad7c2008202354ad7c420d868442137e202242ffffffffffffff03837c221242ffffffffffffff038322083703b04020032012423388201e42ffffffffffffff03837c22123703b840200341d8c0006a200341b0c0006a41e400106e200341f0136a2008420020032903d8402220420010e808200341c0146a201242137e420020032903f8402221420010e80820034190156a201742137e2227420020032903f0402223420010e808200341e0156a201d42137e2222420020032903e8402224420010e808200341b0166a201f42137e221e420020032903e0402225420010e808200341a0166a200842002025420010e808200341e0136a201242002020420010e808200341b0146a202742002021420010e80820034180156a202242002023420010e808200341d0156a201e42002024420010e808200341c0156a200842002024420010e80820034190166a201242002025420010e808200341d0136a201742002020420010e808200341a0146a202242002021420010e808200341f0146a201e42002023420010e808200341e0146a200842002023420010e808200341b0156a201242002024420010e80820034180166a201742002025420010e808200341c0136a201d42002020420010e80820034190146a201e42002021420010e80820034180146a200842002021420010e808200341d0146a201242002023420010e808200341a0156a201742002024420010e808200341f0156a201d42002025420010e808200341b0136a201f42002020420010e808200320032903a014222720032903d0137c220820032903f0147c221220032903c0157c22172003290390167c2220200329038015222920032903b0147c222120032903d0157c222320032903a0167c222420032903e0137c222520032903e015222a2003290390157c221d20032903b0167c221e20032903f0137c221f20032903c0147c2222423388200341e0156a41086a29030020034190156a41086a2903007c201d202a54ad7c200341b0166a41086a2903007c201e201d54ad7c200341f0136a41086a2903007c201f201e54ad7c200341c0146a41086a2903007c2022201f54ad7c420d86847c221d42338820034180156a41086a290300200341b0146a41086a2903007c2021202954ad7c200341d0156a41086a2903007c2023202154ad7c200341a0166a41086a2903007c2024202354ad7c200341e0136a41086a2903007c2025202454ad7c201d202554ad7c420d86847c222142ffffffffffffff038337039041200320032903c013221f2003290380167c22232003290390147c222420032903e0147c222520032903b0157c221e2021423388200341a0146a41086a290300200341d0136a41086a2903007c2008202754ad7c200341f0146a41086a2903007c2012200854ad7c200341c0156a41086a2903007c2017201254ad7c20034190166a41086a2903007c2020201754ad7c2021202054ad7c420d86847c220842ffffffffffffff038337039841200320032903f015222720032903a0157c221220032903b0137c22172003290380147c222020032903d0147c22212008423388200341c0136a41086a29030020034180166a41086a2903007c2023201f54ad7c20034190146a41086a2903007c2024202354ad7c200341e0146a41086a2903007c2025202454ad7c200341b0156a41086a2903007c201e202554ad7c2008201e54ad7c420d86847c220842ffffffffffffff03833703a04120032008423388200341f0156a41086a290300200341a0156a41086a2903007c2012202754ad7c200341b0136a41086a2903007c2017201254ad7c20034180146a41086a2903007c2020201754ad7c200341d0146a41086a2903007c2021202054ad7c2008202154ad7c420d868442137e202242ffffffffffffff03837c220842ffffffffffffff03833703804120032008423388201d42ffffffffffffff03837c37038841200341a8c1006a20034180c1006a4132106e200341a0106a20032903a84122084200200b420010e808200341f0106a20032903c841221242002028420010e808200341c0116a20032903c04122174200201c420010e80820034190126a20032903b841222042002013420010e808200341e0126a20032903b04122214200201a420010e808200341f0126a20214200200b420010e808200341b0106a200842002018420010e80820034180116a20124200201c420010e808200341d0116a201742002013420010e808200341a0126a20204200201a420010e808200341b0126a20204200200b420010e80820034180136a202142002018420010e808200341c0106a200842002019420010e80820034190116a201242002013420010e808200341e0116a20174200201a420010e808200341f0116a20174200200b420010e808200341c0126a202042002018420010e80820034190136a202142002019420010e808200341d0106a20084200201b420010e808200341a0116a20124200201a420010e808200341b0116a20124200200b420010e80820034180126a201742002018420010e808200341d0126a202042002019420010e808200341a0136a20214200201b420010e808200341e0106a200842002026420010e8082003200329039011222420032903c0107c220b20032903e0117c221820032903b0127c22192003290380137c221a200329038011222520032903b0107c221b20032903d0117c221320032903a0127c220820032903f0127c221220032903f010222620032903a0107c221720032903c0117c22202003290390127c222120032903e0127c2223423388200341f0106a41086a290300200341a0106a41086a2903007c2017202654ad7c200341c0116a41086a2903007c2020201754ad7c20034190126a41086a2903007c2021202054ad7c200341e0126a41086a2903007c2023202154ad7c420d86847c221742338820034180116a41086a290300200341b0106a41086a2903007c201b202554ad7c200341d0116a41086a2903007c2013201b54ad7c200341a0126a41086a2903007c2008201354ad7c200341f0126a41086a2903007c2012200854ad7c2017201254ad7c420d86847c221b42ffffffffffffff038337039041200320032903a011222120032903d0107c221320032903f0117c220820032903c0127c22122003290390137c2220201b42338820034190116a41086a290300200341c0106a41086a2903007c200b202454ad7c200341e0116a41086a2903007c2018200b54ad7c200341b0126a41086a2903007c2019201854ad7c20034180136a41086a2903007c201a201954ad7c201b201a54ad7c420d86847c220b42ffffffffffffff038337039841200320032903b011222420032903e0107c22182003290380127c221920032903d0127c221a20032903a0137c221b200b423388200341a0116a41086a290300200341d0106a41086a2903007c2013202154ad7c200341f0116a41086a2903007c2008201354ad7c200341c0126a41086a2903007c2012200854ad7c20034190136a41086a2903007c2020201254ad7c200b202054ad7c420d86847c220b42ffffffffffffff03833703a0412003200b423388200341b0116a41086a290300200341e0106a41086a2903007c2018202454ad7c20034180126a41086a2903007c2019201854ad7c200341d0126a41086a2903007c201a201954ad7c200341a0136a41086a2903007c201b201a54ad7c200b201b54ad7c420d868442137e202342ffffffffffffff03837c220b42ffffffffffffff0383370380412003200b423388201742ffffffffffffff03837c37038841200341a8c1006a20034180c1006a4102106e200341900d6a2015420020032903a841220b420010e80820034190106a2014420020032903b041221842137e420010e808200341c00f6a200f420020032903b841221942137e2208420010e808200341f00e6a200c420020032903c041221b42137e2213420010e808200341a00e6a2016420020032903c841221242137e221a420010e808200341a00d6a20164200200b420010e80820034180106a201542002018420010e808200341b00f6a201442002008420010e808200341e00e6a200f42002013420010e808200341900e6a200c4200201a420010e808200341b00d6a200c4200200b420010e808200341f00f6a201642002018420010e808200341a00f6a201542002019420010e808200341d00e6a201442002013420010e808200341800e6a200f4200201a420010e808200341c00d6a200f4200200b420010e808200341e00f6a200c42002018420010e808200341900f6a201642002019420010e808200341c00e6a20154200201b420010e808200341f00d6a20144200201a420010e808200341d00d6a20144200200b420010e808200341d00f6a200f42002018420010e808200341800f6a200c42002019420010e808200341b00e6a20164200201b420010e808200341e00d6a201542002012420010e808200341f0096a20032903d00f221c20032903800f7c220c20032903d00d7c220f20032903e00d7c221420032903b00e7c221520032903c00d221d20032903e00f7c221620032903f00d7c220b20032903c00e7c221820032903900f7c221920032903800e221e20032903b00d7c221a20032903d00e7c221b20032903a00f7c221320032903f00f7c220820032903e00e221f20032903900e7c221220032903b00f7c22172003290380107c222020032903a00d7c222120032903c00f222220032903f00e7c22232003290390107c222420032903900d7c222520032903a00e7c2226423388200341c00f6a41086a290300200341f00e6a41086a2903007c2023202254ad7c20034190106a41086a2903007c2024202354ad7c200341900d6a41086a2903007c2025202454ad7c200341a00e6a41086a2903007c2026202554ad7c420d86847c2223423388200341e00e6a41086a290300200341900e6a41086a2903007c2012201f54ad7c200341b00f6a41086a2903007c2017201254ad7c20034180106a41086a2903007c2020201754ad7c200341a00d6a41086a2903007c2021202054ad7c2023202154ad7c420d86847c2212423388200341800e6a41086a290300200341b00d6a41086a2903007c201a201e54ad7c200341d00e6a41086a2903007c201b201a54ad7c200341a00f6a41086a2903007c2013201b54ad7c200341f00f6a41086a2903007c2008201354ad7c2012200854ad7c420d86847c221a423388200341c00d6a41086a290300200341e00f6a41086a2903007c2016201d54ad7c200341f00d6a41086a2903007c200b201654ad7c200341c00e6a41086a2903007c2018200b54ad7c200341900f6a41086a2903007c2019201854ad7c201a201954ad7c420d86847c2218423388200341d00f6a41086a290300200341800f6a41086a2903007c200c201c54ad7c200341d00d6a41086a2903007c200f200c54ad7c200341e00d6a41086a2903007c2014200f54ad7c200341b00e6a41086a2903007c2015201454ad7c2018201554ad7c420d868442137e202642ffffffffffffff03837c222742ffffffffffffff0383220c420020032903e032222820032903d0347c220f20032903a00b7c22142003290390327c221520032903a0337c221620032903e033222920032903e0347c220b20032903800c7c221920032903a0327c221b20032903f0327c221320032903f033222a20032903f0347c220820032903b0337c221720032903e00c7c222020032903b0327c222120032903c033222b2003290380347c22242003290380337c222520032903f00c7c22262003290380357c221c200329039033222c20032903d0337c221d20032903800d7c221e20032903c0327c221f2003290390347c222242338820034190336a41086a290300200341d0336a41086a2903007c201d202c54ad7c200341800d6a41086a2903007c201e201d54ad7c200341c0326a41086a2903007c201f201e54ad7c20034190346a41086a2903007c2022201f54ad7c420d86847c221d423388200341c0336a41086a29030020034180346a41086a2903007c2024202b54ad7c20034180336a41086a2903007c2025202454ad7c200341f00c6a41086a2903007c2026202554ad7c20034180356a41086a2903007c201c202654ad7c201d201c54ad7c420d86847c2224423388200341f0336a41086a290300200341f0346a41086a2903007c2008202a54ad7c200341b0336a41086a2903007c2017200854ad7c200341e00c6a41086a2903007c2020201754ad7c200341b0326a41086a2903007c2021202054ad7c2024202154ad7c420d86847c2208423388200341e0336a41086a290300200341e0346a41086a2903007c200b202954ad7c200341800c6a41086a2903007c2019200b54ad7c200341a0326a41086a2903007c201b201954ad7c200341f0326a41086a2903007c2013201b54ad7c2008201354ad7c420d86847c220b423388200341e0326a41086a290300200341d0346a41086a2903007c200f202854ad7c200341a00b6a41086a2903007c2014200f54ad7c20034190326a41086a2903007c2015201454ad7c200341a0336a41086a2903007c2016201554ad7c200b201654ad7c420d868442137e202242ffffffffffffff03837c221742ffffffffffffff0383220f420010e808200341900b6a200b42ffffffffffffff0383221442002027423388202342ffffffffffffff03837c221542137e420010e808200341f00b6a200842ffffffffffffff038322164200201242ffffffffffffff0383221942137e2208420010e808200341d00c6a202442ffffffffffffff0383220b4200201a42ffffffffffffff0383221b42137e2213420010e808200341c00a6a201842ffffffffffffff0383221242137e221a42002017423388201d42ffffffffffffff03837c2218420010e808200341b00a6a200c42002018420010e808200341e0096a20154200200f420010e808200341800b6a201442002008420010e808200341e00b6a201642002013420010e808200341c00c6a200b4200201a420010e808200341b00c6a200b4200200c420010e808200341a00a6a201542002018420010e808200341d0096a20194200200f420010e808200341f00a6a201442002013420010e808200341d00b6a20164200201a420010e808200341c00b6a20164200200c420010e808200341a00c6a200b42002015420010e808200341900a6a201942002018420010e808200341c0096a201b4200200f420010e808200341e00a6a20144200201a420010e808200341d00a6a20144200200c420010e808200341b00b6a201642002015420010e808200341900c6a200b42002019420010e808200341800a6a201b42002018420010e808200341b0096a20124200200f420010e808200320032903f00a221220032903d0097c220c20032903d00b7c220f20032903b00c7c221420032903a00a7c221520032903e00b221720032903800b7c221620032903c00c7c220b20032903b00a7c221820032903e0097c221920032903d00c222020032903f00b7c221a20032903c00a7c221b20032903f0097c221320032903900b7c2208423388200341d00c6a41086a290300200341f00b6a41086a2903007c201a202054ad7c200341c00a6a41086a2903007c201b201a54ad7c200341f0096a41086a2903007c2013201b54ad7c200341900b6a41086a2903007c2008201354ad7c221b420d86847c221a423388200341e00b6a41086a290300200341800b6a41086a2903007c2016201754ad7c200341c00c6a41086a2903007c200b201654ad7c200341b00a6a41086a2903007c2018200b54ad7c200341e0096a41086a2903007c2019201854ad7c201b4233887c201a201954ad7c2213420d86847c221642ffffffffffffff03833703e840200320032903c009221720032903900a7c220b20032903e00a7c221820032903c00b7c221920032903a00c7c221b2016423388200341f00a6a41086a290300200341d0096a41086a2903007c200c201254ad7c200341d00b6a41086a2903007c200f200c54ad7c200341b00c6a41086a2903007c2014200f54ad7c200341a00a6a41086a2903007c2015201454ad7c20134233887c2016201554ad7c2213420d86847c220c42ffffffffffffff03833703f040200320032903800a221220032903900c7c220f20032903b0097c221420032903d00a7c221520032903b00b7c2216200c423388200341c0096a41086a290300200341900a6a41086a2903007c200b201754ad7c200341e00a6a41086a2903007c2018200b54ad7c200341c00b6a41086a2903007c2019201854ad7c200341a00c6a41086a2903007c201b201954ad7c20134233887c200c201b54ad7c220b420d86847c220c42ffffffffffffff03833703f8402003200c423388200341800a6a41086a290300200341900c6a41086a2903007c200f201254ad7c200341b0096a41086a2903007c2014200f54ad7c200341d00a6a41086a2903007c2015201454ad7c200341b00b6a41086a2903007c2016201554ad7c200b4233887c200c201654ad7c420d868442137e200842ffffffffffffff03837c220c42ffffffffffffff03833703d8402003200c423388201a42ffffffffffffff03837c3703e040200341a8c1006a200341d8c0006a4101106e200341a0066a20032903a841220c42002004420010e808200341a0096a20032903b041220f42137e42002010420010e808200341d0086a20032903b841221442137e22184200200d420010e80820034180086a20032903c041221642137e220b4200200a420010e808200341b0076a20032903c841221942137e221542002007420010e808200341b0066a200c42002007420010e80820034190096a200f42002004420010e808200341c0086a201842002010420010e808200341f0076a200b4200200d420010e808200341a0076a20154200200a420010e808200341c0066a200c4200200a420010e80820034180096a200f42002007420010e808200341b0086a201442002004420010e808200341e0076a200b42002010420010e80820034190076a20154200200d420010e808200341d0066a200c4200200d420010e808200341f0086a200f4200200a420010e808200341a0086a201442002007420010e808200341d0076a201642002004420010e80820034180076a201542002010420010e808200341e0066a200c42002010420010e808200341e0086a200f4200200d420010e80820034190086a20144200200a420010e808200341c0076a201642002007420010e808200341f0066a201942002004420010e808200320032903b00822102003290380097c220420032903e0077c22072003290390077c220a20032903c0067c220c20032903c008221a2003290390097c220f20032903f0077c221420032903a0077c221520032903b0067c221620032903d008221b20032903a0097c220b2003290380087c220d20032903a0067c221820032903b0077c2219423388200341d0086a41086a290300200341a0096a41086a2903007c200b201b54ad7c20034180086a41086a2903007c200d200b54ad7c200341a0066a41086a2903007c2018200d54ad7c200341b0076a41086a2903007c2019201854ad7c420d86847c220b423388200341c0086a41086a29030020034190096a41086a2903007c200f201a54ad7c200341f0076a41086a2903007c2014200f54ad7c200341a0076a41086a2903007c2015201454ad7c200341b0066a41086a2903007c2016201554ad7c200b201654ad7c420d86847c220f42ffffffffffffff038337039041200320032903a008221820032903f0087c221420032903d0077c22152003290380077c221620032903d0067c220d200f423388200341b0086a41086a29030020034180096a41086a2903007c2004201054ad7c200341e0076a41086a2903007c2007200454ad7c20034190076a41086a2903007c200a200754ad7c200341c0066a41086a2903007c200c200a54ad7c200f200c54ad7c420d86847c220442ffffffffffffff0383370398412003200329039008221020032903e0087c220720032903c0077c220a20032903f0067c220c20032903e0067c220f2004423388200341a0086a41086a290300200341f0086a41086a2903007c2014201854ad7c200341d0076a41086a2903007c2015201454ad7c20034180076a41086a2903007c2016201554ad7c200341d0066a41086a2903007c200d201654ad7c2004200d54ad7c420d86847c220442ffffffffffffff03833703a0412003200442338820034190086a41086a290300200341e0086a41086a2903007c2007201054ad7c200341c0076a41086a2903007c200a200754ad7c200341f0066a41086a2903007c200c200a54ad7c200341e0066a41086a2903007c200f200c54ad7c2004200f54ad7c420d868442137e201942ffffffffffffff03837c220442ffffffffffffff03833703804120032004423388200b42ffffffffffffff03837c37038841200341b0c0006a20034180c1006a106b20034188c0006a2001106b410021024101212d034020034188c0006a20026a2d0000200341b0c0006a20026a2d000073222e4100202e6b72417f7341800171410776106d202d71212d200241016a22024120470d000b202d106d212f200341a8c1006a41086a42f0ffffffffffff3f200141086a2903007d220442ffffffffffffff038342d0fdffffffffff3f20012903007d22074233887c370300200341a8c1006a41106a42f0ffffffffffff3f200141106a2903007d220a42ffffffffffffff038320044233887c370300200341a8c1006a41186a42f0ffffffffffff3f200141186a2903007d220442ffffffffffffff0383200a4233887c370300200341a8c1006a41206a42f0ffffffffffff3f200141206a2903007d220a42ffffffffffffff038320044233887c3703002003200a42338842137e200742ffffffffffffff03837c3703a841200341b0c0006a20034180c1006a106b20034188c0006a200341a8c1006a106b410021024101212d034020034188c0006a20026a2d0000200341b0c0006a20026a2d000073222e4100202e6b72417f7341800171410776106d202d71212d200241016a22024120470d000b200341a0046a42f0ffffffffffff3f200e7d220742338842137e42d0fdffffffffff3f20117d220e42ffffffffffffff03837c2204420042b0c1bad0f4e48603420010e808200341d0036a42f0ffffffffffff3f20057d220a423388200742ffffffffffffff03837c2207420042a7a7fbf49beaf607420010e808200341f0046a42f0ffffffffffff3f20067d2211423388200a42ffffffffffffff03837c220a420042a0d69f90da80b1cb00420010e808200341c0056a42f0ffffffffffff3f20097d2205423388201142ffffffffffffff03837c2211420042badf96dcb5c3bac700420010e80820034190066a200542ffffffffffffff0383200e4233887c220e420042a7ecfac2b5f7ea19420010e80820034180066a200e420042b0c1bad0f4e48603420010e80820034190046a20044200429db1bce4dfb435420010e808200341c0036a2007420042a0d69f90da80b1cb00420010e808200341e0046a200a420042badf96dcb5c3bac700420010e808200341b0056a2011420042a7ecfac2b5f7ea19420010e808200341a0056a2011420042b0c1bad0f4e48603420010e808200341f0056a200e4200429db1bce4dfb435420010e80820034180046a2004420042e098f4e5e9ebfb03420010e808200341b0036a2007420042badf96dcb5c3bac700420010e808200341d0046a200a420042a7ecfac2b5f7ea19420010e808200341c0046a200a420042b0c1bad0f4e48603420010e80820034190056a20114200429db1bce4dfb435420010e808200341e0056a200e420042e098f4e5e9ebfb03420010e808200341f0036a20044200429e9981b4dab2e103420010e808200341a0036a2007420042a7ecfac2b5f7ea19420010e80820034190036a2007420042b0c1bad0f4e48603420010e808200341b0046a200a4200429db1bce4dfb435420010e80820034180056a2011420042e098f4e5e9ebfb03420010e808200341d0056a200e4200429e9981b4dab2e103420010e808200341e0036a20044200429df893c0a486ae01420010e808200341c0036a41086a290300211820034190046a41086a290300211920032903c00321042003290390042109200341e0046a41086a290300211020032903e004210c200341b0056a41086a290300211a20032903b005210f20034180066a41086a290300211b2003290380062114200341d0036a41086a2903002113200341a0046a41086a290300210820032903d003210720032903a0042115200341f0046a41086a290300211220032903f0042116200341c0056a41086a290300211720032903c005210b20034190066a41086a2903002120200329039006210d20032903b003210a200329038004211120032903d004210e20032903a005210520032903f0052106202d106d2101200320062005200e200a20117c22117c220e7c22057c22062014200f200c200420097c22097c220c7c220f7c2214200d200b2016200720157c22157c22167c220b7c220d423388202020172012201320087c2015200754ad7c7c2016201554ad7c7c200b201654ad7c7c200d200b54ad7c2215420d86847c2207423388201b201a2010201820197c2009200454ad7c7c200c200954ad7c7c200f200c54ad7c7c2014200f54ad7c20154233887c2007201454ad7c2215420d86847c220442ffffffffffffff03833703b841200320032903a003221620032903f0037c220920032903c0047c220c2003290390057c220f20032903e0057c22142004423388200341b0036a41086a29030020034180046a41086a2903007c2011200a54ad7c200341d0046a41086a2903007c200e201154ad7c200341a0056a41086a2903007c2005200e54ad7c200341f0056a41086a2903007c2006200554ad7c20154233887c2004200654ad7c2206420d86847c220442ffffffffffffff03833703c0412003200329039003221520032903e0037c220a20032903b0047c22112003290380057c220e20032903d0057c22052004423388200341a0036a41086a290300200341f0036a41086a2903007c2009201654ad7c200341c0046a41086a2903007c200c200954ad7c20034190056a41086a2903007c200f200c54ad7c200341e0056a41086a2903007c2014200f54ad7c20064233887c2004201454ad7c2206420d86847c220442ffffffffffffff03833703c8412003200442338820034190036a41086a290300200341e0036a41086a2903007c200a201554ad7c200341b0046a41086a2903007c2011200a54ad7c20034180056a41086a2903007c200e201154ad7c200341d0056a41086a2903007c2005200e54ad7c20064233887c2004200554ad7c420d868442137e200d42ffffffffffffff03837c220442ffffffffffffff03833703a84120032004423388200742ffffffffffffff03837c3703b041200341b0c0006a20034180c1006a106b20034188c0006a200341a8c1006a106b410021024101212d034020034188c0006a20026a2d0000200341b0c0006a20026a2d000073222e4100202e6b72417f7341800171410776106d202d71212d200241016a22024120470d000b202d106d210220034180036a20032903d8402204420042b0c1bad0f4e48603420010e808200320032903e040220742137e4200429df893c0a486ae01420010e808200341e0006a20032903e840220a42137e22064200429e9981b4dab2e103420010e808200341c0016a20032903f040220e42137e2205420042e098f4e5e9ebfb03420010e808200341a0026a20032903f840220942137e22114200429db1bce4dfb435420010e808200341f0026a20044200429db1bce4dfb435420010e808200341c0006a2007420042b0c1bad0f4e48603420010e808200341d0006a20064200429df893c0a486ae01420010e808200341b0016a20054200429e9981b4dab2e103420010e80820034190026a2011420042e098f4e5e9ebfb03420010e808200341e0026a2004420042e098f4e5e9ebfb03420010e808200341306a20074200429db1bce4dfb435420010e80820034190016a200a420042b0c1bad0f4e48603420010e808200341a0016a20054200429df893c0a486ae01420010e80820034180026a20114200429e9981b4dab2e103420010e808200341d0026a20044200429e9981b4dab2e103420010e808200341206a2007420042e098f4e5e9ebfb03420010e80820034180016a200a4200429db1bce4dfb435420010e808200341e0016a200e420042b0c1bad0f4e48603420010e808200341f0016a20114200429df893c0a486ae01420010e808200341c0026a20044200429df893c0a486ae01420010e808200341106a20074200429e9981b4dab2e103420010e808200341f0006a200a420042e098f4e5e9ebfb03420010e808200341d0016a200e4200429db1bce4dfb435420010e808200341b0026a2009420042b0c1bad0f4e48603420010e8082003200420042003290370220820032903107c220720032903d0017c220a20032903b0027c221120032903c0027c220e200329038001221220032903207c220520032903e0017c220620032903f0017c220920032903d0027c220c200329039001221720032903307c220f20032903a0017c22142003290380027c221520032903e0027c22162003290350222020032903407c220b20032903b0017c220d2003290390027c221820032903f0027c22192003290360222120032903007c221020032903c0017c221a2003290380037c221b20032903a0027c2213423388200341e0006a41086a290300200341086a2903007c2010202154ad7c200341c0016a41086a2903007c201a201054ad7c20034180036a41086a2903007c201b201a54ad7c200341a0026a41086a2903007c2013201b54ad7c420d86847c2210423388200341d0006a41086a290300200341c0006a41086a2903007c200b202054ad7c200341b0016a41086a2903007c200d200b54ad7c20034190026a41086a2903007c2018200d54ad7c200341f0026a41086a2903007c2019201854ad7c2010201954ad7c420d86847c220b42338820034190016a41086a290300200341306a41086a2903007c200f201754ad7c200341a0016a41086a2903007c2014200f54ad7c20034180026a41086a2903007c2015201454ad7c200341e0026a41086a2903007c2016201554ad7c200b201654ad7c420d86847c220f42338820034180016a41086a290300200341206a41086a2903007c2005201254ad7c200341e0016a41086a2903007c2006200554ad7c200341f0016a41086a2903007c2009200654ad7c200341d0026a41086a2903007c200c200954ad7c200f200c54ad7c420d86847c2205423388200341f0006a41086a290300200341106a41086a2903007c2007200854ad7c200341d0016a41086a2903007c200a200754ad7c200341b0026a41086a2903007c2011200a54ad7c200341c0026a41086a2903007c200e201154ad7c2005200e54ad7c420d868442137e201342ffffffffffffff03837c221142ffffffffffffff03838542002002200172106dad42ff01837d22078385220a3703d84020032011423388201042ffffffffffffff03837c20032903e04022048520078320048522113703e0402003200542ffffffffffffff038320032903f840220485200783200485220e3703f8402003200f42ffffffffffffff038320032903f04022048520078320048522053703f0402003200b42ffffffffffffff038320032903e84022048520078320048522073703e84020034188c0006a200341d8c0006a106b200342f0ffffffffffff3f200e7d220642ffffffffffffff038342f0ffffffffffff3f20057d22094233887c200e85420020032d008840410171106dad42ff01837d220483200e853703f8402003200942ffffffffffffff038342f0ffffffffffff3f20077d220e4233887c2005852004832005853703f0402003200e42ffffffffffffff038342f0ffffffffffff3f20117d220e4233887c2007852004832007853703e8402003200e42ffffffffffffff038342d0fdffffffffff3f200a7d22074233887c2011852004832011853703e0402003200642338842137e200742ffffffffffffff03837c200a85200483200a853703d84020002001202f72106d3a0000200020032903d840370308200041106a20032903e040370300200041186a20032903e840370300200041206a20032903f040370300200041286a20032903f840370300200341d0c1006a24000bd003011a7e200131001221022001310011210320013100102104200131000f2105200131000d2106200131000e2107200131001f2108200131001e2109200131001d210a200131001c210b200131001b210c200131001a210d200131000c210e200131000b210f200131000a21102001310009211120013100072112200131000821132001310019211420013100182115200131001721162001310016211720013100132118200131001421192001310015211a200020013500002001310004422086842001310005422886842001310006221b4230868442ffffffffffffff038337030020002018201942088684201a4210868420174218868420164220868420154228868420144230868442018842ffffffffffffff03833703182000201b201242088684201342108684201142188684201042208684200f42288684200e4230868442038842ffffffffffffff038337030820002015201442088684200d42108684200c42188684200b42208684200a42288684200942308684200842388684420c8842ffffffffffffff03833703202000200e20064208868420074210868420054218868420044220868420034228868420024230868420184238868442068842ffffffffffffff03833703100ba5990104017f237e057f0d7e230041f02b6b22022400200242003703e028200242013703d828200242003703e828200242003703f028200242003703f828200241c82a6a20014101106e200241c8256a20022903c82a2203420042b0c1bad0f4e48603420010e808200241c8286a20022903d02a220442137e4200429df893c0a486ae01420010e808200241f8276a20022903d82a220542137e22064200429e9981b4dab2e103420010e808200241a8276a20022903e02a220742137e2208420042e098f4e5e9ebfb03420010e808200241d8266a20022903e82a220942137e220a4200429db1bce4dfb435420010e808200241d8256a20034200429db1bce4dfb435420010e808200241b8286a2004420042b0c1bad0f4e48603420010e808200241e8276a20064200429df893c0a486ae01420010e80820024198276a20084200429e9981b4dab2e103420010e808200241c8266a200a420042e098f4e5e9ebfb03420010e808200241e8256a2003420042e098f4e5e9ebfb03420010e808200241a8286a20044200429db1bce4dfb435420010e808200241d8276a2005420042b0c1bad0f4e48603420010e80820024188276a20084200429df893c0a486ae01420010e808200241b8266a200a4200429e9981b4dab2e103420010e808200241f8256a20034200429e9981b4dab2e103420010e80820024198286a2004420042e098f4e5e9ebfb03420010e808200241c8276a20054200429db1bce4dfb435420010e808200241f8266a2007420042b0c1bad0f4e48603420010e808200241a8266a200a4200429df893c0a486ae01420010e80820024188266a20034200429df893c0a486ae01420010e80820024188286a20044200429e9981b4dab2e103420010e808200241b8276a2005420042e098f4e5e9ebfb03420010e808200241e8266a20074200429db1bce4dfb435420010e80820024198266a2009420042b0c1bad0f4e48603420010e808200241b81d6a200229038826220b2002290398267c22032002290388287c220420022903b8277c220520022903e8267c220a20022903a826220c20022903f8267c220720022903f8257c22082002290398287c220620022903c8277c2209200229038827220d20022903d8277c220e20022903b8267c220f20022903e8257c221020022903a8287c221120022903e827221220022903b8287c22132002290398277c221420022903c8267c221520022903d8257c221620022903c828221720022903c8257c221820022903f8277c221920022903a8277c221a20022903d8267c221b423388200241c8286a41086a290300200241c8256a41086a2903007c2018201754ad7c200241f8276a41086a2903007c2019201854ad7c200241a8276a41086a2903007c201a201954ad7c200241d8266a41086a2903007c201b201a54ad7c420d86847c2218423388200241e8276a41086a290300200241b8286a41086a2903007c2013201254ad7c20024198276a41086a2903007c2014201354ad7c200241c8266a41086a2903007c2015201454ad7c200241d8256a41086a2903007c2016201554ad7c2018201654ad7c420d86847c221342338820024188276a41086a290300200241d8276a41086a2903007c200e200d54ad7c200241b8266a41086a2903007c200f200e54ad7c200241e8256a41086a2903007c2010200f54ad7c200241a8286a41086a2903007c2011201054ad7c2013201154ad7c420d86847c220e423388200241a8266a41086a290300200241f8266a41086a2903007c2007200c54ad7c200241f8256a41086a2903007c2008200754ad7c20024198286a41086a2903007c2006200854ad7c200241c8276a41086a2903007c2009200654ad7c200e200954ad7c420d86847c220742338820024188266a41086a29030020024198266a41086a2903007c2003200b54ad7c20024188286a41086a2903007c2004200354ad7c200241b8276a41086a2903007c2005200454ad7c200241e8266a41086a2903007c200a200554ad7c2007200a54ad7c420d868442137e201b42ffffffffffffff03837c220442ffffffffffffff0383220320022903d8287c2208420042f682ffa299b88202420010e808200241d81c6a200742ffffffffffffff0383220720022903f8287c2206420042ddf396f0fbf7b9c300420010e808200241e81c6a200e42ffffffffffffff0383220a20022903f0287c2209420042ccf7d9e9fbcee010420010e80820024188236a201342ffffffffffffff0383220520022903e8287c220e4200428df582a3b0868004420010e808200241e8216a2004423388201842ffffffffffffff03837c220420022903e0287c220f4200429aebd0c282f1c201420010e808200241f8216a200f420042f682ffa299b88202420010e808200241c81d6a2008420042cff887b5bcb5c603420010e808200241c81c6a2006420042ccf7d9e9fbcee010420010e808200241f81c6a20094200428df582a3b0868004420010e80820024198236a200e4200429aebd0c282f1c201420010e808200241a8236a200e420042f682ffa299b88202420010e80820024188226a200f420042cff887b5bcb5c603420010e808200241d81d6a2008420042848dc885f9eff000420010e808200241b81c6a20064200428df582a3b0868004420010e808200241881d6a20094200429aebd0c282f1c201420010e808200241981d6a2009420042f682ffa299b88202420010e808200241b8236a200e420042cff887b5bcb5c603420010e80820024198226a200f420042848dc885f9eff000420010e808200241e81d6a2008420042dfddd7d2ccf91a420010e808200241a81c6a20064200429aebd0c282f1c201420010e808200241981c6a2006420042f682ffa299b88202420010e808200241a81d6a2009420042cff887b5bcb5c603420010e808200241c8236a200e420042848dc885f9eff000420010e808200241a8226a200f420042dfddd7d2ccf91a420010e808200241f81d6a2008420042bed6acd4f2a00a420010e808200220022903b81c221920022903d81d7c220820022903881d7c220620022903a8237c22092002290388227c220e20022903c81c221a20022903c81d7c220f20022903f81c7c22102002290398237c221120022903f8217c221320022903d81c221b20022903b81d7c221420022903e81c7c22152002290388237c221620022903e8217c2218423388200241d81c6a41086a290300200241b81d6a41086a2903007c2014201b54ad7c200241e81c6a41086a2903007c2015201454ad7c20024188236a41086a2903007c2016201554ad7c200241e8216a41086a2903007c2018201654ad7c420d86847c2214423388200241c81c6a41086a290300200241c81d6a41086a2903007c200f201a54ad7c200241f81c6a41086a2903007c2010200f54ad7c20024198236a41086a2903007c2011201054ad7c200241f8216a41086a2903007c2013201154ad7c2014201354ad7c420d86847c220f42ffffffffffffff038337039029200220022903a81c221620022903e81d7c221020022903981d7c221120022903b8237c22132002290398227c2215200f423388200241b81c6a41086a290300200241d81d6a41086a2903007c2008201954ad7c200241881d6a41086a2903007c2006200854ad7c200241a8236a41086a2903007c2009200654ad7c20024188226a41086a2903007c200e200954ad7c200f200e54ad7c420d86847c220842ffffffffffffff038337039829200220022903981c221920022903f81d7c220620022903a81d7c220920022903c8237c220e20022903a8227c220f2008423388200241a81c6a41086a290300200241e81d6a41086a2903007c2010201654ad7c200241981d6a41086a2903007c2011201054ad7c200241b8236a41086a2903007c2013201154ad7c20024198226a41086a2903007c2015201354ad7c2008201554ad7c420d86847c220842ffffffffffffff03833703a02920022008423388200241981c6a41086a290300200241f81d6a41086a2903007c2006201954ad7c200241a81d6a41086a2903007c2009200654ad7c200241c8236a41086a2903007c200e200954ad7c200241a8226a41086a2903007c200f200e54ad7c2008200f54ad7c420d868442137e201842ffffffffffffff03837c220842ffffffffffffff03833703802920022008423388201442ffffffffffffff03837c37038829200241d8216a2003420042a3f1e59aa1b9d301420010e808200241f8226a200442137e221c420042ffed8af7ec86c802420010e808200241e8236a200542137e2210420042bbf9809de6b8ce03420010e80820024198246a200a42137e2211420042a9808780a6f4f902420010e808200241d8246a200742137e2208420042bdddd5d88385ea00420010e808200241c8216a2003420042bdddd5d88385ea00420010e808200241e8226a2004420042a3f1e59aa1b9d301420010e808200241d8236a2010420042ffed8af7ec86c802420010e80820024188246a2011420042bbf9809de6b8ce03420010e808200241c8246a2008420042a9808780a6f4f902420010e808200241b8216a2003420042a9808780a6f4f902420010e808200241d8226a2004420042bdddd5d88385ea00420010e808200241e8246a2005420042a3f1e59aa1b9d301420010e808200241f8236a2011420042ffed8af7ec86c802420010e808200241b8246a2008420042bbf9809de6b8ce03420010e808200241a8216a2003420042bbf9809de6b8ce03420010e808200241c8226a2004420042a9808780a6f4f902420010e808200241f8246a2005420042bdddd5d88385ea00420010e80820024198256a200a420042a3f1e59aa1b9d301420010e808200241a8246a2008420042ffed8af7ec86c802420010e808200241d8206a2003420042ffed8af7ec86c802420010e808200241b8226a2004420042bbf9809de6b8ce03420010e80820024188256a2005420042a9808780a6f4f902420010e808200241a8256a200a420042bdddd5d88385ea00420010e808200241b8256a2007420042a3f1e59aa1b9d301420010e808200241881e6a200342a3f1e59aa1b9d3017c2206420042efffffffffffffc30020022903d820221d20022903b8257c220920022903b8227c220e2002290388257c220f20022903a8257c221320022903a824221e2002290398257c221420022903a8217c221520022903c8227c221620022903f8247c221820022903f823221f20022903e8247c221920022903b8247c221a20022903b8217c221b20022903d8227c220b20022903d823222020022903e8227c220c2002290388247c220d20022903c8247c221220022903c8217c221720022903f822222120022903d8217c222220022903e8237c22232002290398247c222420022903d8247c2225423388200241f8226a41086a290300200241d8216a41086a2903007c2022202154ad7c200241e8236a41086a2903007c2023202254ad7c20024198246a41086a2903007c2024202354ad7c200241d8246a41086a2903007c2025202454ad7c420d86847c2222423388200241d8236a41086a290300200241e8226a41086a2903007c200c202054ad7c20024188246a41086a2903007c200d200c54ad7c200241c8246a41086a2903007c2012200d54ad7c200241c8216a41086a2903007c2017201254ad7c2022201754ad7c420d86847c220c423388200241f8236a41086a290300200241e8246a41086a2903007c2019201f54ad7c200241b8246a41086a2903007c201a201954ad7c200241b8216a41086a2903007c201b201a54ad7c200241d8226a41086a2903007c200b201b54ad7c200c200b54ad7c420d86847c2219423388200241a8246a41086a29030020024198256a41086a2903007c2014201e54ad7c200241a8216a41086a2903007c2015201454ad7c200241c8226a41086a2903007c2016201554ad7c200241f8246a41086a2903007c2018201654ad7c2019201854ad7c420d86847c221442ffffffffffffff03837d221542338842137e42bcfdffffffffffc3002014423388200241d8206a41086a290300200241b8256a41086a2903007c2009201d54ad7c200241b8226a41086a2903007c200e200954ad7c20024188256a41086a2903007c200f200e54ad7c200241a8256a41086a2903007c2013200f54ad7c2014201354ad7c420d868442137e202542ffffffffffffff03837c221342ffffffffffffff03837d221642ffffffffffffff03837c2209420010e808200241881f6a201542ffffffffffffff038342efffffffffffffc300201942ffffffffffffff03837d220f4233887c220e4200201c4287f0dc94c6dfde0f7c420010e80820024198216a200f42ffffffffffffff038342efffffffffffffc300200c42ffffffffffffff03837d22144233887c220f42002010428b868581d2a18c387c2215420010e808200241c8206a201442ffffffffffffff038342efffffffffffffc3002013423388202242ffffffffffffff03837c7d22134233887c22104200201142e18392a796b7d2c4007c2214420010e80820024188206a201342ffffffffffffff038320164233887c22114200200842eda9ced69582d9307c2208420010e808200241981e6a201142002006420010e808200241c81f6a20094200200442bdddd5d88385ea007c2213420010e808200241f81e6a200e42002015420010e80820024188216a200f42002014420010e808200241b8206a201042002008420010e808200241a81e6a201042002006420010e808200241f81f6a201142002013420010e808200241b81f6a20094200200542a9808780a6f4f9027c2215420010e808200241e81e6a200e42002014420010e808200241f8206a200f42002008420010e808200241b81e6a200f42002006420010e808200241a8206a201042002013420010e808200241e81f6a201142002015420010e808200241a81f6a20094200200a42bbf9809de6b8ce037c2214420010e808200241d81e6a200e42002008420010e808200241c81e6a200e42002006420010e808200241e8206a200f42002013420010e80820024198206a201042002015420010e808200241d81f6a201142002014420010e808200241981f6a20094200200742ffed8af7ec86c8027c420010e808200220022903e81e221920022903b81f7c220820022903f8207c220620022903a81e7c220920022903f81f7c220e20022903f81e221a20022903c81f7c220f2002290388217c221020022903b8207c221120022903981e7c221320022903881f221b20022903881e7c22142002290398217c221520022903c8207c22162002290388207c2218423388200241881f6a41086a290300200241881e6a41086a2903007c2014201b54ad7c20024198216a41086a2903007c2015201454ad7c200241c8206a41086a2903007c2016201554ad7c20024188206a41086a2903007c2018201654ad7c420d86847c2214423388200241f81e6a41086a290300200241c81f6a41086a2903007c200f201a54ad7c20024188216a41086a2903007c2010200f54ad7c200241b8206a41086a2903007c2011201054ad7c200241981e6a41086a2903007c2013201154ad7c2014201354ad7c420d86847c220f42ffffffffffffff03833703e029200220022903d81e221620022903a81f7c221020022903b81e7c221120022903a8207c221320022903e81f7c2215200f423388200241e81e6a41086a290300200241b81f6a41086a2903007c2008201954ad7c200241f8206a41086a2903007c2006200854ad7c200241a81e6a41086a2903007c2009200654ad7c200241f81f6a41086a2903007c200e200954ad7c200f200e54ad7c420d86847c220842ffffffffffffff03833703e829200220022903c81e221920022903981f7c220620022903e8207c22092002290398207c220e20022903d81f7c220f2008423388200241d81e6a41086a290300200241a81f6a41086a2903007c2010201654ad7c200241b81e6a41086a2903007c2011201054ad7c200241a8206a41086a2903007c2013201154ad7c200241e81f6a41086a2903007c2015201354ad7c2008201554ad7c420d86847c220842ffffffffffffff03833703f02920022008423388200241c81e6a41086a290300200241981f6a41086a2903007c2006201954ad7c200241e8206a41086a2903007c2009200654ad7c20024198206a41086a2903007c200e200954ad7c200241d81f6a41086a2903007c200f200e54ad7c2008200f54ad7c420d868442137e201842ffffffffffffff03837c220842ffffffffffffff03833703d02920022008423388201442ffffffffffffff03837c3703d829200241c82a6a20024180296a200241d0296a106f20022d00c82a2126200241a02a6a41206a2227200241f02a6a2903002208370300200241a02a6a41186a2228200241c82a6a41206a2903002206370300200241a02a6a41106a2229200241c82a6a41186a2903002209370300200241a02a6a41086a222a200241c82a6a41106a290300220e370300200220022903d02a220f3703a02a20024188196a200129030022104200200f420010e808200241881c6a200842002001290308221142137e420010e808200241b81b6a200642002001290310221342137e2218420010e808200241e81a6a200942002001290318221542137e2216420010e808200241981a6a200e42002001290320221942137e2214420010e80820024198196a200e42002010420010e808200241f81b6a200f42002011420010e808200241a81b6a200842002018420010e808200241d81a6a200642002016420010e808200241881a6a200942002014420010e808200241a8196a200942002010420010e808200241e81b6a200e42002011420010e808200241981b6a200f42002013420010e808200241c81a6a200842002016420010e808200241f8196a200642002014420010e808200241b8196a200642002010420010e808200241d81b6a200942002011420010e808200241881b6a200e42002013420010e808200241b81a6a200f42002015420010e808200241e8196a200842002014420010e808200241c8196a200842002010420010e808200241c81b6a200642002011420010e808200241f81a6a200942002013420010e808200241a81a6a200e42002015420010e808200241d8196a200f42002019420010e808200220022903c819222220022903d8197c220820022903c81b7c220620022903f81a7c220920022903a81a7c220e20022903e819222320022903b81a7c220f20022903b8197c221020022903d81b7c221120022903881b7c221320022903c81a222420022903981b7c221420022903f8197c221520022903a8197c221620022903e81b7c221820022903a81b222520022903f81b7c221920022903d81a7c221a20022903881a7c221b2002290398197c220b20022903881c221c2002290388197c220c20022903b81b7c220d20022903e81a7c221220022903981a7c2217423388200241881c6a41086a29030020024188196a41086a2903007c200c201c54ad7c200241b81b6a41086a2903007c200d200c54ad7c200241e81a6a41086a2903007c2012200d54ad7c200241981a6a41086a2903007c2017201254ad7c420d86847c220c423388200241a81b6a41086a290300200241f81b6a41086a2903007c2019202554ad7c200241d81a6a41086a2903007c201a201954ad7c200241881a6a41086a2903007c201b201a54ad7c20024198196a41086a2903007c200b201b54ad7c200c200b54ad7c420d86847c2219423388200241c81a6a41086a290300200241981b6a41086a2903007c2014202454ad7c200241f8196a41086a2903007c2015201454ad7c200241a8196a41086a2903007c2016201554ad7c200241e81b6a41086a2903007c2018201654ad7c2019201854ad7c420d86847c2214423388200241e8196a41086a290300200241b81a6a41086a2903007c200f202354ad7c200241b8196a41086a2903007c2010200f54ad7c200241d81b6a41086a2903007c2011201054ad7c200241881b6a41086a2903007c2013201154ad7c2014201354ad7c420d86847c220f423388200241c8196a41086a290300200241d8196a41086a2903007c2008202254ad7c200241c81b6a41086a2903007c2006200854ad7c200241f81a6a41086a2903007c2009200654ad7c200241a81a6a41086a2903007c200e200954ad7c200f200e54ad7c420d868442137e201742ffffffffffffff03837c220842ffffffffffffff03833703f82a20022008423388200c42ffffffffffffff03837c22063703802b2002200f42ffffffffffffff038322093703982b2002201442ffffffffffffff0383220e3703902b2002201942ffffffffffffff0383220f3703882b200241c82a6a200241f82a6a106b20022d00c82a410171106d417f73410171106d21012002200642f0ffffffffffff3f20067d221142ffffffffffffff038342d0fdffffffffff3f20022903f82a22107d22134233887c8542002001ad42ff01837d22088320068522063703802b2002200942f0ffffffffffff3f20097d221442ffffffffffffff038342f0ffffffffffff3f200e7d22154233887c8520088320098522093703982b2002200f42f0ffffffffffff3f200f7d221642ffffffffffffff038320114233887c85200883200f85220f3703882b200220102010201442338842137e201342ffffffffffffff03837c852008838522103703f82a2002200e201542ffffffffffffff038320164233887c85200883200e85220e3703902b2026417f734101712201106d2126202a202a290300221120068542002026ad42ff01837d220883201185370300202920292903002206200f85200883200685370300202820282903002206200e85200883200685370300202720272903002206200985200883200685370300200220022903a02a22062010852008832006853703a02a2001106d2101200241c80f6a200720022903f8287d42f0ffffffffffff3f7c221142338842137e200320022903d8287d42d0fdffffffffff3f7c220942ffffffffffffff03837c22084200200342ecffffffffffff038542002001ad42ff01837d22038342ecffffffffffff03852206420010e808200241880d6a200742ffffffffffffff038520038342ffffffffffffff038522074200200420022903e0287d42f0ffffffffffff3f7c220f42ffffffffffffff038320094233887c220942137e420010e808200241d80d6a200a42ffffffffffffff038520038342ffffffffffffff0385220e4200200520022903e8287d42f0ffffffffffff3f7c221042ffffffffffffff0383200f4233887c220f42137e2213420010e808200241a80e6a200542ffffffffffffff038520038342ffffffffffffff038522054200200a20022903f0287d42f0ffffffffffff3f7c221442ffffffffffffff038320104233887c220a42137e2210420010e808200241f80e6a200442ffffffffffffff038520038342ffffffffffffff038522034200201142ffffffffffffff038320144233887c221142137e2204420010e808200241e80e6a200342002008420010e808200241b80f6a200642002009420010e808200241f80c6a200742002013420010e808200241c80d6a200e42002010420010e808200241980e6a200542002004420010e808200241880e6a200542002008420010e808200241d80e6a200342002009420010e808200241a80f6a20064200200f420010e808200241e80c6a200742002010420010e808200241b80d6a200e42002004420010e808200241a80d6a200e42002008420010e808200241f80d6a200542002009420010e808200241c80e6a20034200200f420010e808200241980f6a20064200200a420010e808200241880c6a200742002004420010e808200241a80b6a200742002008420010e808200241980d6a200e42002009420010e808200241e80d6a20054200200f420010e808200241b80e6a20034200200a420010e808200241880f6a200642002011420010e808200241f8096a20022903a80b220b20022903880f7c220320022903980d7c220420022903e80d7c220520022903b80e7c220a20022903880c220c20022903980f7c220720022903a80d7c220820022903f80d7c220620022903c80e7c220920022903e80c220d20022903a80f7c220e20022903b80d7c220f20022903880e7c221020022903d80e7c221120022903f80c221220022903b80f7c221320022903c80d7c221420022903980e7c221520022903e80e7c221620022903880d221720022903c80f7c221820022903d80d7c221920022903a80e7c221a20022903f80e7c221b423388200241880d6a41086a290300200241c80f6a41086a2903007c2018201754ad7c200241d80d6a41086a2903007c2019201854ad7c200241a80e6a41086a2903007c201a201954ad7c200241f80e6a41086a2903007c201b201a54ad7c420d86847c2218423388200241f80c6a41086a290300200241b80f6a41086a2903007c2013201254ad7c200241c80d6a41086a2903007c2014201354ad7c200241980e6a41086a2903007c2015201454ad7c200241e80e6a41086a2903007c2016201554ad7c2018201654ad7c420d86847c2213423388200241e80c6a41086a290300200241a80f6a41086a2903007c200e200d54ad7c200241b80d6a41086a2903007c200f200e54ad7c200241880e6a41086a2903007c2010200f54ad7c200241d80e6a41086a2903007c2011201054ad7c2013201154ad7c420d86847c220e423388200241880c6a41086a290300200241980f6a41086a2903007c2007200c54ad7c200241a80d6a41086a2903007c2008200754ad7c200241f80d6a41086a2903007c2006200854ad7c200241c80e6a41086a2903007c2009200654ad7c200e200954ad7c420d86847c2207423388200241a80b6a41086a290300200241880f6a41086a2903007c2003200b54ad7c200241980d6a41086a2903007c2004200354ad7c200241e80d6a41086a2903007c2005200454ad7c200241b80e6a41086a2903007c200a200554ad7c2007200a54ad7c420d868442137e201b42ffffffffffffff03837c220842ffffffffffffff03832203420042a09ab5a7a4d5d602420010e808200241980b6a200742ffffffffffffff03832204420042efabafe6f7c88835420010e808200241f80b6a200e42ffffffffffffff03832205420042f8fb9b94e0ed8617420010e808200241d80c6a201342ffffffffffffff0383220a4200428b83d98ea38bdb0a420010e808200241c80a6a2008423388201842ffffffffffffff03837c2207420042e6c09290d28a8b35420010e808200241b80a6a2007420042a09ab5a7a4d5d602420010e808200241e8096a2003420042b5cccc99bcc0e502420010e808200241880b6a2004420042f8fb9b94e0ed8617420010e808200241e80b6a20054200428b83d98ea38bdb0a420010e808200241c80c6a200a420042e6c09290d28a8b35420010e808200241b80c6a200a420042a09ab5a7a4d5d602420010e808200241a80a6a2007420042b5cccc99bcc0e502420010e808200241d8096a2003420042a8f2a9fabaa79b01420010e808200241f80a6a20044200428b83d98ea38bdb0a420010e808200241d80b6a2005420042e6c09290d28a8b35420010e808200241c80b6a2005420042a09ab5a7a4d5d602420010e808200241a80c6a200a420042b5cccc99bcc0e502420010e808200241980a6a2007420042a8f2a9fabaa79b01420010e808200241c8096a2003420042a9afa6f3e694c800420010e808200241e80a6a2004420042e6c09290d28a8b35420010e808200241d80a6a2004420042a09ab5a7a4d5d602420010e808200241b80b6a2005420042b5cccc99bcc0e502420010e808200241980c6a200a420042a8f2a9fabaa79b01420010e808200241880a6a2007420042a9afa6f3e694c800420010e808200241b8096a2003420042c2cdbdbdb3d1e502420010e80820022903f029210f20022903e829210e20022903e029210520022903d829210320022903d0292104200241a02b6a200241a02a6a4101106e200241c82b6a41106a220120292903002207370300200241c82b6a41086a202a290300220a200a7c220a3703002001200720077c2207370300200241c82b6a41186a2028290300220820087c2208370300200241c82b6a41206a2027290300220620067c2206370300200220022903a02a220920097c22093703c82b200241c8176a200442002009420010e808200241b8176a20064200200342137e420010e808200241c8166a20084200200542137e2213420010e80820024188186a20074200200e42137e2211420010e808200241b8166a200a4200200f42137e2210420010e808200241c8186a200a42002004420010e808200241d8176a200942002003420010e808200241a8176a200642002013420010e808200241d8166a200842002011420010e808200241a8166a200742002010420010e80820024198186a200742002004420010e808200241d8186a200a42002003420010e808200241e8176a200942002005420010e80820024198176a200642002011420010e80820024198166a200842002010420010e808200241e8166a200842002004420010e808200241a8186a200742002003420010e808200241e8186a200a42002005420010e808200241f8176a20094200200e420010e808200241e8146a200642002010420010e80820024188176a200642002004420010e808200241f8166a200842002003420010e808200241b8186a200742002005420010e808200241f8186a200a4200200e420010e808200241b8136a20094200200f420010e808200241e8066a20022903d80a222220022903b8097c220a20022903b80b7c220720022903980c7c220820022903880a7c220620022903e80a222320022903c8097c220920022903c80b7c221020022903a80c7c221120022903980a7c221320022903f80a222420022903d8097c221420022903d80b7c221520022903b80c7c221620022903a80a7c221820022903880b222520022903e8097c221920022903e80b7c221a20022903c80c7c221b20022903b80a7c220b20022903980b221c20022903f8097c220c20022903f80b7c220d20022903d80c7c221220022903c80a7c2217423388200241980b6a41086a290300200241f8096a41086a2903007c200c201c54ad7c200241f80b6a41086a2903007c200d200c54ad7c200241d80c6a41086a2903007c2012200d54ad7c200241c80a6a41086a2903007c2017201254ad7c420d86847c220c423388200241880b6a41086a290300200241e8096a41086a2903007c2019202554ad7c200241e80b6a41086a2903007c201a201954ad7c200241c80c6a41086a2903007c201b201a54ad7c200241b80a6a41086a2903007c200b201b54ad7c200c200b54ad7c420d86847c2219423388200241f80a6a41086a290300200241d8096a41086a2903007c2014202454ad7c200241d80b6a41086a2903007c2015201454ad7c200241b80c6a41086a2903007c2016201554ad7c200241a80a6a41086a2903007c2018201654ad7c2019201854ad7c420d86847c2214423388200241e80a6a41086a290300200241c8096a41086a2903007c2009202354ad7c200241c80b6a41086a2903007c2010200954ad7c200241a80c6a41086a2903007c2011201054ad7c200241980a6a41086a2903007c2013201154ad7c2014201354ad7c420d86847c220942ffffffffffffff0383200f7d42f0ffffffffffff3f7c220f42338842137e2009423388200241d80a6a41086a290300200241b8096a41086a2903007c200a202254ad7c200241b80b6a41086a2903007c2007200a54ad7c200241980c6a41086a2903007c2008200754ad7c200241880a6a41086a2903007c2006200854ad7c2009200654ad7c420d868442137e201742ffffffffffffff03837c220742ffffffffffffff038320047d42d0fdffffffffff3f7c220842ffffffffffffff03837c22044200429bdceccb84d4fd03420010e808200241b8076a200f42ffffffffffffff0383201442ffffffffffffff0383200e7d42f0ffffffffffff3f7c22064233887c220a420042969988cadca7b00e420010e808200241a8096a200642ffffffffffffff0383201942ffffffffffffff038320057d42f0ffffffffffff3f7c22064233887c2205420042a88c8b81f5cabeca00420010e808200241d8086a200642ffffffffffffff03832007423388200c42ffffffffffffff03837c20037d42f0ffffffffffff3f7c22074233887c2203420042c8ee859b8cd29829420010e80820024188086a200742ffffffffffffff038320084233887c2207420042dcd78e98b19df320420010e808200241f8076a20074200429bdceccb84d4fd03420010e808200241d8066a2004420042d2dfded4f0ede000420010e808200241a8076a200a420042a88c8b81f5cabeca00420010e80820024198096a2005420042c8ee859b8cd29829420010e808200241c8086a2003420042dcd78e98b19df320420010e808200241b8086a20034200429bdceccb84d4fd03420010e808200241e8076a2007420042d2dfded4f0ede000420010e808200241c8066a2004420042b8ecf9b5ffe8f503420010e80820024198076a200a420042c8ee859b8cd29829420010e80820024188096a2005420042dcd78e98b19df320420010e808200241f8086a20054200429bdceccb84d4fd03420010e808200241a8086a2003420042d2dfded4f0ede000420010e808200241d8076a2007420042b8ecf9b5ffe8f503420010e80820024198056a200442004298c9f9f3f9c09502420010e80820024188076a200a420042dcd78e98b19df320420010e808200241f8066a200a4200429bdceccb84d4fd03420010e808200241e8086a2005420042d2dfded4f0ede000420010e80820024198086a2003420042b8ecf9b5ffe8f503420010e808200241c8076a200742004298c9f9f3f9c09502420010e808200241e8036a2004420042b4f0cadfb1d2dd01420010e80820022903b82b212320022903b02b212420022903a82b212520022903c02b211c20022903a02b211d200242003703d02a200242013703c82a200242003703d82a200242003703e02a200242003703e82a200220022903a02b42017c22033703c82a200220022903a82b22043703d02a200220022903b02b22103703d82a200220022903b82b22153703e02a200241e8106a20034200200229038817221720022903b8137c220520022903f8167c220a20022903b8187c220720022903f8187c220820022903e814222220022903f8177c220620022903e8167c220920022903a8187c220e20022903e8187c220f200229039817221e20022903e8177c22112002290398167c22132002290398187c221420022903d8187c221620022903a817221f20022903d8177c221820022903d8167c221920022903a8167c221a20022903c8187c221b20022903b817222020022903c8177c220b20022903c8167c220c2002290388187c220d20022903b8167c2212423388200241b8176a41086a290300200241c8176a41086a2903007c200b202054ad7c200241c8166a41086a2903007c200c200b54ad7c20024188186a41086a2903007c200d200c54ad7c200241b8166a41086a2903007c2012200d54ad7c420d86847c220b423388200241a8176a41086a290300200241d8176a41086a2903007c2018201f54ad7c200241d8166a41086a2903007c2019201854ad7c200241a8166a41086a2903007c201a201954ad7c200241c8186a41086a2903007c201b201a54ad7c200b201b54ad7c420d86847c221942338820024198176a41086a290300200241e8176a41086a2903007c2011201e54ad7c20024198166a41086a2903007c2013201154ad7c20024198186a41086a2903007c2014201354ad7c200241d8186a41086a2903007c2016201454ad7c2019201654ad7c420d86847c2211423388200241e8146a41086a290300200241f8176a41086a2903007c2006202254ad7c200241e8166a41086a2903007c2009200654ad7c200241a8186a41086a2903007c200e200954ad7c200241e8186a41086a2903007c200f200e54ad7c2011200f54ad7c420d86847c220642338820024188176a41086a290300200241b8136a41086a2903007c2005201754ad7c200241f8166a41086a2903007c200a200554ad7c200241b8186a41086a2903007c2007200a54ad7c200241f8186a41086a2903007c2008200754ad7c2006200854ad7c420d868442137e201242ffffffffffffff03837c220942ffffffffffffff03832205420010e808200241a8136a200642ffffffffffffff0383220a4200200442137e222b420010e808200241d8146a201142ffffffffffffff038322074200201042137e2218420010e80820024188166a201942ffffffffffffff038322084200201542137e2216420010e80820024188126a2009423388200b42ffffffffffffff03837c2206420020022903c02b221a42137e2211420010e808200241f8116a200642002003420010e808200241d8106a200542002004420010e80820024198136a200a42002018420010e808200241c8146a200742002016420010e808200241f8156a200842002011420010e808200241e8156a200842002003420010e808200241e8116a200642002004420010e808200241c8106a200542002010420010e80820024188136a200a42002016420010e808200241b8146a200742002011420010e808200241a8146a200742002003420010e808200241d8156a200842002004420010e808200241d8116a200642002010420010e808200241b8106a200542002015420010e808200241f8126a200a42002011420010e808200241e8126a200a42002003420010e80820024198146a200742002004420010e808200241c8156a200842002010420010e808200241c8116a200642002015420010e808200241a8106a20054200201a420010e8082000200229038813222c20022903c8107c221b20022903b8147c220b20022903e8157c220c20022903e8117c220d200229039813222220022903d8107c220920022903c8147c220e20022903f8157c220f20022903f8117c221320022903a813221e20022903e8107c221420022903d8147c22192002290388167c22122002290388127c2217423388200241a8136a41086a290300200241e8106a41086a2903007c2014201e54ad7c200241d8146a41086a2903007c2019201454ad7c20024188166a41086a2903007c2012201954ad7c20024188126a41086a2903007c2017201254ad7c420d86847c221242338820024198136a41086a290300200241d8106a41086a2903007c2009202254ad7c200241c8146a41086a2903007c200e200954ad7c200241f8156a41086a2903007c200f200e54ad7c200241f8116a41086a2903007c2013200f54ad7c2012201354ad7c420d86847c222242ffffffffffffff038337031020024198106a42f0ffffffffffff3f201c7d221442338842137e42d1fdffffffffff3f201d7d220e42ffffffffffffff03837c220942002005420010e808200241d8126a200a420042f0ffffffffffff3f20257d220f42ffffffffffffff0383200e4233887c220e42137e420010e80820024188146a2007420042f0ffffffffffff3f20247d221342ffffffffffffff0383200f4233887c220f42137e2224420010e808200241b8156a2008420042f0ffffffffffff3f20237d221942ffffffffffffff038320134233887c221342137e2223420010e808200241b8116a20064200201442ffffffffffffff038320194233887c221442137e2219420010e808200241a8116a200642002009420010e80820024188106a20054200200e420010e808200241c8126a200a42002024420010e808200241f8136a200742002023420010e808200241a8156a200842002019420010e80820024198156a200842002009420010e80820024198116a20064200200e420010e808200241f80f6a20054200200f420010e808200241b8126a200a42002023420010e808200241e8136a200742002019420010e808200241d8136a200742002009420010e80820024188156a20084200200e420010e80820024188116a20064200200f420010e808200241e80f6a200542002013420010e808200241a8126a200a42002019420010e80820004190016a20022903a812222d20022903e80f7c221920022903d8137c22232002290388157c22242002290388117c222520022903b812222e20022903f80f7c221c20022903e8137c221d2002290398157c221e2002290398117c221f20022903c812222f2002290388107c222020022903f8137c222120022903a8157c223020022903a8117c223120022903d81222322002290398107c22332002290388147c223420022903b8157c223520022903b8117c2236423388200241d8126a41086a29030020024198106a41086a2903007c2033203254ad7c20024188146a41086a2903007c2034203354ad7c200241b8156a41086a2903007c2035203454ad7c200241b8116a41086a2903007c2036203554ad7c420d86847c2233423388200241c8126a41086a29030020024188106a41086a2903007c2020202f54ad7c200241f8136a41086a2903007c2021202054ad7c200241a8156a41086a2903007c2030202154ad7c200241a8116a41086a2903007c2031203054ad7c2033203154ad7c420d86847c2220423388200241b8126a41086a290300200241f80f6a41086a2903007c201c202e54ad7c200241e8136a41086a2903007c201d201c54ad7c20024198156a41086a2903007c201e201d54ad7c20024198116a41086a2903007c201f201e54ad7c2020201f54ad7c420d86847c221c42ffffffffffffff0383370300200020022903f812223020022903b8107c221d20022903a8147c221e20022903d8157c221f20022903d8117c2221202242338820024188136a41086a290300200241c8106a41086a2903007c201b202c54ad7c200241b8146a41086a2903007c200b201b54ad7c200241e8156a41086a2903007c200c200b54ad7c200241e8116a41086a2903007c200d200c54ad7c2022200d54ad7c420d86847c221b42ffffffffffffff038337031820024198126a200a42002009420010e808200241c8136a20074200200e420010e808200241f8146a20084200200f420010e808200241f8106a200642002013420010e808200241d80f6a200542002014420010e80820004198016a200229039812222c20022903d80f7c220b20022903c8137c220c20022903f8147c220d20022903f8107c2222201c423388200241a8126a41086a290300200241e80f6a41086a2903007c2019202d54ad7c200241d8136a41086a2903007c2023201954ad7c20024188156a41086a2903007c2024202354ad7c20024188116a41086a2903007c2025202454ad7c201c202554ad7c420d86847c222342ffffffffffffff0383370300200020022903e812221920022903a8107c22052002290398147c220a20022903c8157c220720022903c8117c2208201b423388200241f8126a41086a290300200241b8106a41086a2903007c201d203054ad7c200241a8146a41086a2903007c201e201d54ad7c200241d8156a41086a2903007c201f201e54ad7c200241d8116a41086a2903007c2021201f54ad7c201b202154ad7c420d86847c220642ffffffffffffff038337032020002006423388200241e8126a41086a290300200241a8106a41086a2903007c2005201954ad7c20024198146a41086a2903007c200a200554ad7c200241c8156a41086a2903007c2007200a54ad7c200241c8116a41086a2903007c2008200754ad7c2006200854ad7c420d868442137e201742ffffffffffffff03837c220542ffffffffffffff038337030020002005423388201242ffffffffffffff03837c370308200241d8016a20022903f806222d20022903e8037c220520022903e8087c220a2002290398087c220720022903c8077c2208200229038807222e2002290398057c220620022903f8087c221920022903a8087c221b20022903d8077c2212200229039807222f20022903c8067c22172002290388097c222420022903b8087c222520022903e8077c221c20022903a807223220022903d8067c221d2002290398097c221e20022903c8087c221f20022903f8077c222120022903b807223720022903e8067c223020022903a8097c223120022903d8087c22342002290388087c2235423388200241b8076a41086a290300200241e8066a41086a2903007c2030203754ad7c200241a8096a41086a2903007c2031203054ad7c200241d8086a41086a2903007c2034203154ad7c20024188086a41086a2903007c2035203454ad7c420d86847c2230423388200241a8076a41086a290300200241d8066a41086a2903007c201d203254ad7c20024198096a41086a2903007c201e201d54ad7c200241c8086a41086a2903007c201f201e54ad7c200241f8076a41086a2903007c2021201f54ad7c2030202154ad7c420d86847c221d42338820024198076a41086a290300200241c8066a41086a2903007c2017202f54ad7c20024188096a41086a2903007c2024201754ad7c200241b8086a41086a2903007c2025202454ad7c200241e8076a41086a2903007c201c202554ad7c201d201c54ad7c420d86847c221742338820024188076a41086a29030020024198056a41086a2903007c2006202e54ad7c200241f8086a41086a2903007c2019200654ad7c200241a8086a41086a2903007c201b201954ad7c200241d8076a41086a2903007c2012201b54ad7c2017201254ad7c420d86847c2206423388200241f8066a41086a290300200241e8036a41086a2903007c2005202d54ad7c200241e8086a41086a2903007c200a200554ad7c20024198086a41086a2903007c2007200a54ad7c200241c8076a41086a2903007c2008200754ad7c2006200854ad7c420d868442137e203542ffffffffffffff03837c220a42ffffffffffffff0383220542002009420010e808200241f8026a20144200200a423388203042ffffffffffffff03837c220a42137e420010e808200241b8056a20134200201d42ffffffffffffff0383220742137e2212420010e80820024198046a200f4200201742ffffffffffffff0383220842137e221b420010e808200241386a200e4200200642ffffffffffffff0383220642137e2219420010e808200241c8016a200e42002005420010e808200241e8026a20094200200a420010e808200241a8056a201442002012420010e80820024188046a20134200201b420010e808200241286a200f42002019420010e808200241b8016a200f42002005420010e808200241d8026a200e4200200a420010e808200241c8056a200942002007420010e808200241f8036a20144200201b420010e808200241186a201342002019420010e808200241a8016a201342002005420010e808200241c8026a200f4200200a420010e808200241d8056a200e42002007420010e808200241a8046a200942002008420010e808200241086a201442002019420010e80820024198016a201442002005420010e808200241b8026a20134200200a420010e808200241e8056a200f42002007420010e808200241b8046a200e42002008420010e80820024188036a200942002006420010e80820024188016a200342002005420010e80820024198036a20064200202b420010e808200241c8046a200842002018420010e808200241f8056a200742002016420010e808200241a8026a200a42002011420010e80820024198026a200a42002003420010e808200241f8006a200542002004420010e808200241a8036a200642002018420010e808200241d8046a200842002016420010e80820024188066a200742002011420010e80820024198066a200742002003420010e80820024188026a200a42002004420010e808200241e8006a200542002010420010e808200241b8036a200642002016420010e808200241e8046a200842002011420010e808200241f8046a200842002003420010e808200241a8066a200742002004420010e808200241f8016a200a42002010420010e808200241d8006a200542002015420010e808200241c8036a200642002011420010e808200241d8036a200642002003420010e80820024188056a200842002004420010e808200241b8066a200742002010420010e808200241e8016a200a42002015420010e808200241c8006a20054200201a420010e80820004188016a202042ffffffffffffff03833703002000202342338820024198126a41086a290300200241d80f6a41086a2903007c200b202c54ad7c200241c8136a41086a2903007c200c200b54ad7c200241f8146a41086a2903007c200d200c54ad7c200241f8106a41086a2903007c2022200d54ad7c2023202254ad7c420d868442137e203642ffffffffffffff03837c220342ffffffffffffff038337037820004180016a2003423388203342ffffffffffffff03837c370300200041e0006a20022903b803221b20022903687c220320022903e8047c22042002290398067c22052002290388027c220a20022903a803221320022903787c220720022903d8047c22082002290388067c22062002290398027c220920022903980322142002290388017c220e20022903c8047c220f20022903f8057c221020022903a8027c221142338820024198036a41086a29030020024188016a41086a2903007c200e201454ad7c200241c8046a41086a2903007c200f200e54ad7c200241f8056a41086a2903007c2010200f54ad7c200241a8026a41086a2903007c2011201054ad7c420d86847c220e423388200241a8036a41086a290300200241f8006a41086a2903007c2007201354ad7c200241d8046a41086a2903007c2008200754ad7c20024188066a41086a2903007c2006200854ad7c20024198026a41086a2903007c2009200654ad7c200e200954ad7c420d86847c220742ffffffffffffff0383370300200041386a20022903f803220b20022903c8057c220820022903187c220620022903b8017c220920022903d8027c220f20022903a805220c20022903e8027c22102002290388047c221320022903287c221420022903c8017c221520022903f802220d20022903d8017c221620022903b8057c22182002290398047c221920022903387c221a423388200241f8026a41086a290300200241d8016a41086a2903007c2016200d54ad7c200241b8056a41086a2903007c2018201654ad7c20024198046a41086a2903007c2019201854ad7c200241386a41086a2903007c201a201954ad7c420d86847c2216423388200241a8056a41086a290300200241e8026a41086a2903007c2010200c54ad7c20024188046a41086a2903007c2013201054ad7c200241286a41086a2903007c2014201354ad7c200241c8016a41086a2903007c2015201454ad7c2016201554ad7c420d86847c221042ffffffffffffff0383370300200041e8006a20022903c803221920022903587c221320022903f8047c221420022903a8067c221520022903f8017c22182007423388200241b8036a41086a290300200241e8006a41086a2903007c2003201b54ad7c200241e8046a41086a2903007c2004200354ad7c20024198066a41086a2903007c2005200454ad7c20024188026a41086a2903007c200a200554ad7c2007200a54ad7c420d86847c220342ffffffffffffff0383370300200041c0006a2002290308221b20022903a8047c220420022903a8017c220520022903c8027c220a20022903d8057c22072010423388200241f8036a41086a290300200241c8056a41086a2903007c2008200b54ad7c200241186a41086a2903007c2006200854ad7c200241b8016a41086a2903007c2009200654ad7c200241d8026a41086a2903007c200f200954ad7c2010200f54ad7c420d86847c220842ffffffffffffff0383370300200041f0006a20022903d803220b20022903487c22062002290388057c220920022903b8067c220f20022903e8017c22102003423388200241c8036a41086a290300200241d8006a41086a2903007c2013201954ad7c200241f8046a41086a2903007c2014201354ad7c200241a8066a41086a2903007c2015201454ad7c200241f8016a41086a2903007c2018201554ad7c2003201854ad7c420d86847c220342ffffffffffffff0383370300200041c8006a20022903980122192002290388037c221320022903b8027c221420022903e8057c221520022903b8047c22182008423388200241086a41086a290300200241a8046a41086a2903007c2004201b54ad7c200241a8016a41086a2903007c2005200454ad7c200241c8026a41086a2903007c200a200554ad7c200241d8056a41086a2903007c2007200a54ad7c2008200754ad7c420d86847c220442ffffffffffffff038337030020002003423388200241d8036a41086a290300200241c8006a41086a2903007c2006200b54ad7c20024188056a41086a2903007c2009200654ad7c200241b8066a41086a2903007c200f200954ad7c200241e8016a41086a2903007c2010200f54ad7c2003201054ad7c420d868442137e201142ffffffffffffff03837c220342ffffffffffffff0383370350200041d8006a2003423388200e42ffffffffffffff03837c3703002000200442338820024198016a41086a29030020024188036a41086a2903007c2013201954ad7c200241b8026a41086a2903007c2014201354ad7c200241e8056a41086a2903007c2015201454ad7c200241b8046a41086a2903007c2018201554ad7c2004201854ad7c420d868442137e201a42ffffffffffffff03837c220342ffffffffffffff0383370328200041306a2003423388201642ffffffffffffff03837c370300200241f02b6a24000bd32004047f017e027f1c7e23004190066b220224000240024020012c001f417f4a0d00200041003a00000c010b20024180056a41186a2203200141186a29000037030020024180056a41106a2204200141106a29000037030020024180056a41086a2205200141086a29000037030020022001290000220637038005200220022d009f0541ff00713a009f05200241c0056a41186a22074200370300200241c0056a41106a22084200370300200241c0056a41086a220142003703002002200231008205421086200231008105420886200642ff0183848422063703c005200220023100830542188620068422063703c005200220023100840542208620068422063703c005200220023100850542288620068422063703c005200220023100860542308620068422063703c00520022002310087054238862006843703c005200120012903002005310000842206370300200120023100890542088620068422063703002001200231008a0542108620068422063703002001200231008b0542188620068422063703002001200231008c0542208620068422063703002001200231008d0542288620068422063703002001200231008e0542308620068422063703002001200231008f0542388620068437030020082008290300200431000084220637030020082002310091054208862006842206370300200820023100920542108620068422063703002008200231009305421886200684220637030020082002310094054220862006842206370300200820023100950542288620068422063703002008200231009605423086200684220637030020082002310097054238862006842209370300200720072903002003310000842206370300200720023100990542088620068422063703002007200231009a0542108620068422063703002007200231009b0542188620068422063703002007200231009c0542208620068422063703002007200231009d0542288620068422063703002007200231009e0542308620068422063703002007200231009f05423886200684220a37030020024180036a20022903c005220b42ffffffffffffff07832206420042edcd87b9d697d207420010e808200241c0026a2006420042dac89fe3dad6ee01420010e80820024180026a2001290300220c420c864280e0ffffffffff0783200b42348884220b420042edcd87b9d697d207420010e808200241b0026a20064200429bcad7d9feffff07420010e808200241c0016a200b420042dac89fe3dad6ee01420010e808200241d0036a200942188642808080f8ffffff0783200c42288884220c420042edcd87b9d697d207420010e808200241a0026a2006420042ffffffffffffff07420010e80820024180016a200b4200429bcad7d9feffff07420010e808200241c0036a200c420042dac89fe3dad6ee01420010e808200241a0046a200a422486428080808080feff07832009421c88842209420042edcd87b9d697d207420010e80820024190026a2006420042ffffffffffff03420010e808200241c0006a200b420042ffffffffffffff07420010e808200241b0036a200c4200429bcad7d9feffff07420010e80820024190046a2009420042dac89fe3dad6ee01420010e808200241f0046a200a4210882206420042edcd87b9d697d207420010e8082002200b420042ffffffffffff03420010e808200241a0036a200c420042ffffffffffffff07420010e80820024180046a20094200429bcad7d9feffff07420010e808200241e0046a2006420042dac89fe3dad6ee01420010e80820024190036a200c420042ffffffffffff03420010e808200241f0036a2009420042ffffffffffffff07420010e808200241d0046a20064200429bcad7d9feffff07420010e808200241e0036a2009420042ffffffffffff03420010e808200241c0046a2006420042ffffffffffffff07420010e808200241b0046a2006420042ffffffffffff03420010e808200241f0026a200229038003220b429bfcd192b1b4c7027e42ffffffffffffff07832206420042eda7d7e7a5e39801420010e808200241e0026a200642004281cbb5cef7c5fa06420010e808200241f0016a200229038002220d20022903c0027c220c200b20022903f00222097c220b423488200241f0026a41086a29030020024180036a41086a2903007c200b200954ad7c220e420c86847c220920022903e0027c220a429bfcd192b1b4c7027e42ffffffffffffff0783220b420042eda7d7e7a5e39801420010e808200241d0026a2006420042f9bdd300420010e808200241e0016a200b42004281cbb5cef7c5fa06420010e808200241b0016a20022903c001220f20022903b0027c221020022903d0037c221120022903d0027c221220022903e0017c221320022903f0012214200a7c2215423488200241f0016a41086a29030020024180026a41086a290300200241c0026a41086a2903007c200c200d54ad7c200e4234887c2009200c54ad7c200241e0026a41086a2903007c200a200954ad7c7c2015201454ad7c2216420c86847c2209429bfcd192b1b4c7027e42ffffffffffffff0783220c420042eda7d7e7a5e39801420010e808200241d0016a200b420042f9bdd300420010e808200241a0016a200c42004281cbb5cef7c5fa06420010e808200241f0006a200229038001221720022903a0027c220a20022903c0037c220d20022903a0047c220e20022903d0017c221420022903a0017c221520022903b001221820097c2219423488200241b0016a41086a290300200241c0016a41086a290300200241b0026a41086a2903007c2010200f54ad7c200241d0036a41086a2903007c2011201054ad7c200241d0026a41086a2903007c2012201154ad7c200241e0016a41086a2903007c2013201254ad7c20164234887c2009201354ad7c7c2019201854ad7c221a420c86847c2210429bfcd192b1b4c7027e42ffffffffffffff07832209420042eda7d7e7a5e39801420010e80820024190016a200c420042f9bdd300420010e808200241e0006a200942004281cbb5cef7c5fa06420010e808200241306a2002290340221b2002290390027c221120022903b0037c22122002290390047c221320022903f0047c220f2006422c867c22162002290390017c221820022903607c22192002290370221c20107c221d423488200241f0006a41086a29030020024180016a41086a290300200241a0026a41086a2903007c200a201754ad7c200241c0036a41086a2903007c200d200a54ad7c200241a0046a41086a2903007c200e200d54ad7c200241d0016a41086a2903007c2014200e54ad7c200241a0016a41086a2903007c2015201454ad7c201a4234887c2010201554ad7c7c201d201c54ad7c221e420c86847c2210429bfcd192b1b4c7027e42ffffffffffffff0783220a420042eda7d7e7a5e39801420010e808200241d0006a2009420042f9bdd300420010e808200241206a200a42004281cbb5cef7c5fa06420010e808200241106a200a420042f9bdd300420010e808200120022903f003221f2002290390037c220d20022903d0047c220e200c422c867c221420022903107c221520022903a003222020022903007c22172002290380047c221a20022903e0047c221c200b422c867c221d20022903507c222120022903207c22222002290330222320107c2224423488200241306a41086a290300200241c0006a41086a29030020024190026a41086a2903007c2011201b54ad7c200241b0036a41086a2903007c2012201154ad7c20024190046a41086a2903007c2013201254ad7c200241f0046a41086a2903007c200f201354ad7c20064214887c2016200f54ad7c20024190016a41086a2903007c2018201654ad7c200241e0006a41086a2903007c2019201854ad7c201e4234887c2010201954ad7c7c2024202354ad7c2210420c86847c2206423488200241a0036a41086a290300200241086a2903007c2017202054ad7c20024180046a41086a2903007c201a201754ad7c200241e0046a41086a2903007c201c201a54ad7c200b4214887c201d201c54ad7c200241d0006a41086a2903007c2021201d54ad7c200241206a41086a2903007c2022202154ad7c20104234887c2006202254ad7c2212420c86847c220b42ffffffffffffff0783200642ffffffffffffff07834293d8a898da9ce77e7c2206423f877c42ffb4cab188ba85797c221342ffffffffffffff0783200642ffffffffffffff0783200a422c86220f20022903b0047c220620022903c004221620022903e0037c22102009422c867c2211200b423488200241f0036a41086a29030020024190036a41086a2903007c200d201f54ad7c200241d0046a41086a2903007c200e200d54ad7c200c4214887c2014200e54ad7c200241106a41086a2903007c2015201454ad7c20124234887c200b201554ad7c220c420c86847c220b423488200241c0046a41086a290300200241e0036a41086a2903007c2010201654ad7c20094214887c2011201054ad7c200c4234887c200b201154ad7c2209420c86847c220c423488200a421488200241b0046a41086a2903007c2006200f54ad7c20094234887c200c200654ad7c420c8684200c42ffffffffffffff0783200b42ffffffffffffff07832013423f877c4287c2ac7f7c220c423f877c2209423f877c428080808080807c7c2210423f87220a42eda7d7e7a5e39801837c22064234887c200a4281cbb5cef7c5fa06837c220b42ffffffffffffff078322113703002008200c42ffffffffffffff0783200b4234887c200a42f9bdd300837c220c42ffffffffffffff078322123703002007200942ffffffffffffff0783200c4234887c220942ffffffffffffff07832213370300200241e0056a201042ffffffffffffff078320094234887c200a4280808080808004837c220a42ffffffffffffff07833703002002200642ffffffffffffff078322103703c0052002200a4228883c00bf052002200a4220883c00be052002200a4218883c00bd052002200a4210883c00bc052002200a4208883c00bb052002200a3c00ba0520022009422c883c00b905200220094224883c00b80520022009421c883c00b705200220094214883c00b60520022009420c883c00b505200220094204883c00b405200220134204862012423088843c00b3052002200c4228883c00b2052002200c4220883c00b1052002200c4218883c00b0052002200c4210883c00af052002200c4208883c00ae052002200c3c00ad052002200b422c883c00ac052002200b4224883c00ab052002200b421c883c00aa052002200b4214883c00a9052002200b420c883c00a8052002200b4204883c00a705200220114204862010423088843c00a605200220064228883c00a505200220064220883c00a405200220064218883c00a305200220064210883c00a205200220064208883c00a105200220063c00a0052006a72108200241a0056a4101722103410021014101210702400340200820024180056a20016a2d0000732208410020086b72417f7341800171410776106d20077121072001411f460d01200320016a2d00002108200141016a21010c000b0b4100210102402007106d41ff01714101470d002000200229038005370001200041196a20024198056a290300370000200041116a20024190056a290300370000200041096a20024188056a290300370000410121010b200020013a00000b20024190066a24000bc60101017f230041106b2202240002400240024002400240024002400240200041ff01710e0700010203040506070b200241003a000f20012002410f6a410110740c060b200241013a000f20012002410f6a410110740c050b200241023a000f20012002410f6a410110740c040b200241033a000f20012002410f6a410110740c030b200241043a000f20012002410f6a410110740c020b200241053a000f20012002410f6a410110740c010b200241063a000f20012002410f6a410110740b200241106a24000b880201047f230041206b2203240002400240200041046a2802002204200041086a28020022056b2002490d00200028020021040c010b0240200520026a22062005490d00200441017422052006200520064b1b22054108200541084b1b21050240024020040d00200341003602100c010b200341106a41086a410136020020032004360214200320002802003602100b200320054101200341106a107d200341086a2802002105024020032802004101460d00200020032802042204360200200041046a2005360200200041086a28020021050c020b2005450d001036000b1038000b200420056a2001200210e9081a200041086a2200200028020020026a360200200341206a24000bfa0201057f230041106b2203240002402001450d002000200141386c6a210403402000220528020421012005280208220620021076200220012006107420052802102101200528021422062002107620022001200610740240024020052802184101470d00200528021c2101200528022422062002107620022001200610740c010b2003200528021c200528022028020c11020020032802002101200328020822062002107620022001200610742003280204450d002001102e0b200541386a2100200528022c21010240024020052802284101470d00200528023422052002107620054103742205450d01200120056a2107034020012802002105200141046a2802002206200210762002200520061074200141086a22012007470d000c020b0b200528023022052002107620054103742205450d00200120056a2107034020012802002105200141046a2802002206200210762002200520061074200141086a22012007470d000b0b20002004470d000b0b200341106a24000bab0101017f230041106b220224000240024002400240200041c000490d00200041808001490d012000418080808004490d02200241033a00032001200241036a41011074200220003602042001200241046a410410740c030b200220004102743a00032001200241036a410110740c020b200220004102744101723b010a20012002410a6a410210740c010b2002200041027441027236020c20012002410c6a410410740b200241106a24000bec0101047f02402001450d0020002001411c6c6a21030340200022042802042101200428020822052002107620022001200510742004411c6a21002004280210210102400240200428020c4101470d00200428021822042002107620044103742204450d01200120046a2106034020012802002104200141046a2802002205200210762002200420051074200141086a22012006470d000c020b0b200428021422042002107620044103742204450d00200120046a2106034020012802002104200141046a2802002205200210762002200420051074200141086a22012006470d000b0b20002003470d000b0b0be40301057f02402001450d0020002001412c6c6a21030340200022042802042101200428020822052002107620022001200510742004280210210102400240200428020c4101470d0020042802182205200210762005450d01200541186c2105200141146a21010340200141706a2802002106200141746a28020022072002107620022006200710742001417c6a280200210620012802002207200210762002200620071074200141186a2101200541686a22050d000c020b0b200441146a2802002205200210762005450d00200541186c2105200141146a21010340200141706a2802002106200141746a28020022072002107620022006200710742001417c6a280200210620012802002207200210762002200620071074200141186a2101200541686a22050d000b0b2004412c6a21002004280220210102400240200428021c4101470d00200428022822052002107620054103742205450d01200120056a2107034020012802002105200141046a2802002206200210762002200520061074200141086a22012007470d000c020b0b200428022422052002107620054103742205450d00200120056a2107034020012802002105200141046a2802002206200210762002200520061074200141086a22012007470d000b0b20002003470d000b0b0bb00701057f230041c0006b2203240002402001450d002000200141f0006c6a21040340200028020421012000280208220520021076200220012005107402400240200028020c22014102470d00200341003a00202002200341206a410110740c010b200341013a00202002200341206a41011074024020014101470d002000280214210120002802182205200210762002200120051074200028022021010240200028021c4101470d002000280228220520021076200120052002107a0c020b200041246a280200220520021076200120052002107a0c010b200341206a20002802101103002003280224210120032802282205200210762002200120051074200328023021060240200328022c4101460d002003280234220120021076200620012002107a0c010b2003280238220120021076200620012002107a024020032802382201450d00200141d8006c21074100210503400240200620056a220141346a280200450d002001413c6a280200450d00200141386a280200102e0b0240200141c4006a280200450d00200141cc006a28020041ffffffff0171450d00200141c8006a280200102e0b2007200541d8006a2205470d000b0b20032802342201450d00200141d8006c450d002006102e0b02400240200028022c22014102470d00200341003a00202002200341206a410110740c010b200341013a00202002200341206a41011074024020014101470d0020002802302101200028023822052002107620012005200210780c010b200341186a200028023011030020032802182101200328021c22052002107620012005200210780b02400240200028023c22014102470d00200341003a00202002200341206a410110740c010b200341013a00202002200341206a41011074024020014101470d00200028024021012000280248220520021076200120052002107b0c010b200341106a2000280240110300200328021021012003280214220520021076200120052002107b0b02400240200028024c4101470d0020002802502101200028025822052002107620012005200210750c010b200341086a200028025011030020032802082101200328020c22052002107620012005200210750b200041f0006a210102400240200028025c4101470d0020002802602105200028026822062002107620052006200210770c010b2003200028026011030020032802002105200328020422062002107620052006200210770b200320002d006c3a00202002200341206a410110742001210020012004470d000b0b200341c0006a24000bc10501057f230041106b2203240002402001450d002000200141d8006c6a21040340200022052802042101200528020822062002107620022001200610740240024020052d00544101460d00200341003a000f20022003410f6a410110740c010b200341013a000f20022003410f6a410110740b024002400240024020052d000c0e03000102030b200341003a000f20022003410f6a4101107420052802142101200528021822062002107620022001200610740c020b200341013a000f20022003410f6a410110742005410d6a2d0000200210732005280214210120052802182206200210762002200120061074200528022021012005280224220620021076200220012006107420032005410e6a2d00003a000f20022003410f6a410110740c010b200341023a000f20022003410f6a410110742005410d6a2d00002002107320052802142101200528021822062002107620022001200610742005280220210120052802242206200210762002200120061074200528022c2101200528023022062002107620022001200610742005410e6a2d0000200210730b0240024020052802344101470d0020052802382101200528024022062002107620022001200610740c010b20032005280238200528023c28020c11020020032802002101200328020822062002107620022001200610742003280204450d002001102e0b200541d8006a2100200528024821010240024020052802444101470d00200528025022052002107620054103742205450d01200120056a2107034020012802002105200141046a2802002206200210762002200520061074200141086a22012007470d000c020b0b200528024c22052002107620054103742205450d00200120056a2107034020012802002105200141046a2802002206200210762002200520061074200141086a22012007470d000b0b20002004470d000b0b200341106a24000b950301057f02402001450d0020002001412c6c6a21030340200022042802042101200428020822052002107620022001200510742004280210210102400240200428020c4101470d00200428021822052002107620054103742205450d01200120056a2106034020012802002105200141046a2802002207200210762002200520071074200141086a22012006470d000c020b0b200428021422052002107620054103742205450d00200120056a2106034020012802002105200141046a2802002207200210762002200520071074200141086a22012006470d000b0b2004412c6a21002004280220210102400240200428021c4101470d00200428022822052002107620054103742205450d01200120056a2106034020012802002105200141046a2802002207200210762002200520071074200141086a22012006470d000c020b0b200428022422052002107620054103742205450d00200120056a2106034020012802002105200141046a2802002207200210762002200520071074200141086a22012006470d000b0b20002003470d000b0b0be207010c7f230041206b220224002001410c6a2802002103200128020821042001280204210502400240024002400240024002400240024002400240200128020022060d002004450d01200320046b21070c020b200520066b2101024020040d00200121070c020b2001200320046b6a220720014f0d012000420137020041002107200041086a22084100360200200520066b2109410121010c040b2000420137020041002107200041086a22084100360200410121010c010b2007417f4c0d070240024020070d00410121010c010b2007102c2201450d050b20002001360200200041086a22084100360200200041046a200736020020060d010b200320046b410020041b21090c020b200520066b21092004450d010b02402009200320046b6a220a2009490d00200a21090c010b0240024020052006460d00200641016a210b0c010b2004450d0420032004460d044100210b20042106200441016a21040b200041046a210c4100210d034020042109200b210a20062d0000210602400240024002400240200d2007470d0002400240200a0d00200320096b410020091b21040c010b2005200a6b21042009450d00417f2004200320096b6a220b200b2004491b21040b200720076b417f200441016a220b200b2004491b22044f0d00200720046a22042007490d0a2007410174220b2004200b20044b1b22044108200441084b1b21040240024020070d00200241003602100c010b2002410136021820022007360214200220013602100b200220044101200241106a107d2002280208210720022802004101460d01200020022802042201360200200c20073602000b2001200d6a20063a00002008200d41016a220d360200200a0d01200a210b0c020b2007450d080c050b200a2005470d014100210b0b2009450d0520092003460d05200941016a2104200921060c010b200a41016a210b20092104200a21060c000b0b200720094f0d012007410174220a2009200a20094b1b22094108200941084b1b21090240024020070d00200241003602100c010b200241106a41086a410136020020022007360214200220013602100b200220094101200241106a107d200241086a2802002109024020022802004101460d00200020022802042201360200200041046a20093602000c020b2009450d030b1036000b4100210902402006450d0020052006460d00200520066b21090340200120062d00003a0000200141016a21012005200641016a2206470d000b0b02402004450d0020032004460d00200920046b21060340200120042d00003a0000200141016a21012003200441016a2204470d000b200320066a21090b200820093602000b200241206a24000f0b1038000bbd0101017f0240024002400240024002402002450d0020014100480d01024002400240200328020022040d002001450d010c050b200328020422030d0120010d040b200221030c050b20042003200110302203450d030c040b2000200136020420004101360200200041086a41003602000f0b20004101360200200041086a41003602000f0b2001102c22030d010b2000200136020441012103200221010c010b20002003360204410021030b20002003360200200041086a20013602000b1c002001280218419eeacc00410f2001411c6a28020028020c1100000b9f0904017f017e017f087e230041b0046b22022400200141bc016a350200210320012802b8012104200241c0016a200141b80110e9081a024002400240200241e8016a2903004201510d0020022903c80121050c010b200241f0016a290300220620022903c8012205560d010b200521060b200220063703c801024002400240200241a0026a2903004201510d0020022903c80121050c010b200241a8026a290300220620022903c8012205560d010b200521060b200220063703c801024002400240200241d8026a2903004201510d0020022903c80121050c010b200241e0026a290300220620022903c8012205560d010b200521060b200220063703c80102402004450d002006428094ebdc038020037e2006428094ebdc038220037e2206428094ebdc038042ffffffff0f2006428080808080c0b2cd3b541b2006428094ebdc03824280cab5ee0156ad7c42ffffffff0f837c21060240200241d8016a2903004201510d00200241e0016a42004200200241f0016a290300220320067d220520052003561b220320022903d0017d220520052003561b3703002002200241e8016a2903003703d8010b024020024190026a2903004201510d0020024198026a42004200200241a8026a290300220320067d220520052003561b220320024188026a2903007d220520052003561b3703002002200241a0026a290300370390020b200241c8026a2903004201510d00200241d0026a42004200200241e0026a290300220320067d220620062003561b2206200241c0026a2903007d220320032006561b3703002002200241d8026a2903003703c8020b200241f8026a200241c0016a41b80110e9081a02400240200229038003220620022903f8022203200241f8036a29030022077c580d002006420020024198046a290300220520024190046a2903005022011b540d00427e200241a8046a290300427f7c200241a0046a290300501b2007540d0020024188046a29030022085020024180046a2903002209420052710d00420020082009501b4200427f200520011b220520077d220820082005561b560d0020062003200241c0036a29030022097c580d0020064200200241e0036a2903002208200241f8026a41e0006a2903005022011b540d00427e200241f0036a290300427f7c200241e8036a290300501b2009540d00200241d0036a290300220a50200241c8036a290300220b420052710d004200200a200b501b4200427f200820011b220820097d220a200a2008561b560d0020062003200229038803220a7c580d0020064200200241a8036a290300220b200241a0036a2903005022011b540d00427e200241b8036a290300427f7c200241b0036a290300501b200a540d0020024198036a29030022065020024190036a290300220c420052710d0042002006200c501b4200427f200b20011b2206200a7d220b200b2006561b560d002006502006200a5620062003567172450d00200850200820095620082003567172450d002005502005200756200520035671720d010b200241013a000241d3a0c00041e000200241026a41ec9fc00041b4a1c000103e000b2000200241086a200241f8026a41b80110e90841b80110e9081a200241b0046a24000ba90803197e017f147e20002903c0012101200029039801210220002903702103200029034821042000290320210520002903b8012106200029039001210720002903682108200029034021092000290318210a20002903b001210b200029038801210c2000290360210d2000290338210e2000290310210f20002903a8012110200029038001211120002903582112200029033021132000290308211420002903a00121152000290378211620002903502117200029032821182000290300211941c07e211a0340200b200c200d200e200f85858585221b4201892015201620172018201985858585221c85221d201385211e20012006200720082009200a85858585221f201c42018985221c85212020012002200320042005858585852221420189201b85221b2009854237892222201f4201892010201120122013201485858585220985221f200f85423e892223427f8583201d201085420289222485210120222021200942018985220f20168542298922212003201c854227892225427f8583852110201b2006854238892226201f200c85420f892227427f8583201d201285420a89222885210c2028200f2018854224892229427f85832005201c85421b89222a852116200f2015854212892215201f200e85420689222b201d201485420189222c427f85838521032002201c85420889222d201b200885421989222e427f8583202b8521122004201c85421489221c201b200a85421c89220a427f8583201f200b85423d89220e852104200a200e427f8583201d201185422d89221d852109200f2017854203892214200e201d427f858385210e201d2014427f8583201c852113200a2014201c427f8583852118201b200785421589221d200f201985221c2020420e89221b427f858385210a201b201d427f8583201f200d85422b89221f85210f201d201f427f8583201e422c89221d852114201a4198a3c0006a290300201c201f201d427f85838585211920262029202a427f858385221f2102201d201c427f8583201b85221d2105202120232024427f858385221c2106202a2026427f8583202785221b2107202c2015427f8583202d852226210820242021427f85832025852224210b202e2015202d427f8583852221210d202920272028427f8583852227211120252022427f858320238522222115202e202b427f8583202c8522232117201a41086a221a0d000b200020223703a00120002016370378200020233703502000201837032820002019370300200020103703a8012000202737038001200020123703582000201337033020002014370308200020243703b0012000200c37038801200020213703602000200e3703382000200f3703102000201c3703b8012000201b3703900120002026370368200020093703402000200a370318200020013703c0012000201f3703980120002003370370200020043703482000201d3703200be61801037f230041f0016b22032400200341106a41126a410041b60110eb081a2003411e6a41002800b6a340360100200341002f00aca3403b0114200341002800a8a340360210200341002900aea340370116200341106a1080012000200341106a41c80110e908220041003a00ca01200041003b01c801200041124100108201024020002d00c801220441c7014b0d00200020046a220420042d000041cd00733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200441c8014f0d010b200020046a220420042d000041e500733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200441c7014b0d010b200020046a220420042d000041f200733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200441c7014b0d010b200020046a220420042d000041ec00733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200441c7014b0d010b200020046a220420042d000041e900733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200441c7014b0d010b200020046a220420042d000041ee00733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200441c7014b0d010b200020046a220420042d00004120733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200441c7014b0d010b200020046a220420042d000041f600733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200441c7014b0d010b200020046a220420042d00004131733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200441c7014b0d010b200020046a220420042d0000412e733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220441a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200441c7014b0d010b200020046a220420042d00004130733a0000200020002d00c80141016a22043a00c8010240200441ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000108001200041003b01c8010b2003200236020c200041124100108201024020002d00c801220441c8014f0d00200020046a220420042d000041e400733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220541a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200541c8014f0d010b2000200441ff01716a220420042d000041ef00733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220541a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200541c7014b0d010b2000200441ff01716a220420042d000041ed00733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220541a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200541c7014b0d010b2000200441ff01716a220420042d0000412d733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220541a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200541c7014b0d010b2000200441ff01716a220420042d000041f300733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220541a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200541c7014b0d010b2000200441ff01716a220420042d000041e500733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220541a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200541c7014b0d010b200041ca016a21052000200441ff01716a220420042d000041f000733a0000200020002d00c80141016a22043a00c8010240200441ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010b200341123a00df01024020052d00004112460d00200341e0016a410c6a4109360200200341246a4102360200200341106a410c6a4102360200200341186a41aca4c000360200200341023602142003419ca4c000360210200341093602e401200320053602e001200341206a200341e0016a3602002003200341df016a3602e8012005200341df016a200341106a41eca4c000108301000b0240200441ff0171220541c7014b0d00200020056a220420042d000020032d000c733a0000200020002d00c80141016a22043a00c80102400240200441ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200441ff017141c8014f0d010b2000200441ff01716a220420042d000020032d000d733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220541a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200541c7014b0d010b2000200441ff01716a220420042d000020032d000e733a0000200020002d00c80141016a22043a00c80102400240200441ff0171220541a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010c010b200541c7014b0d010b2000200441ff01716a220420042d000020032d000f733a0000200020002d00c80141016a22043a00c8010240200441ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000108001200041003b01c8010b200041024100108201024002402002450d0020002d00c80121040340200441ff0171220441c7014b0d02200020046a220420042d000020012d0000733a0000200020002d00c80141016a22043a00c8010240200441ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002104200041003b01c8010b200141016a21012002417f6a22020d000b0b200341f0016a24000f0b200441c80141bca3c000103c000b200441ff017141c80141bca3c000103c000b200441ff017141c80141bca3c000103c000b200441c80141bca3c000103c000bd30501027f230041306b22032400200320013a000702400240024002402002450d0020002d00ca01200141ff0171460d01200341086a410c6a41093602002003412c6a4102360200200341186a410c6a4102360200200341206a41aca4c0003602002003410236021c2003419ca4c0003602182003410936020c2003200041ca016a2200360208200341286a200341086a3602002003200341076a3602102000200341076a200341186a41eca4c000108301000b2003200141087122023a00080240024020020d00200020013a00ca0120002d00c9012104200020002d00c801220241016a3a00c901200320013a0019200320043a00180240200241c7014b0d00200020026a220120012d000020032d0018733a0000200020002d00c80141016a22023a00c8010240200241ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002102200041003b01c8010c030b200141c801490d020b200241ff017141c80141bca3c000103c000b2003412c6a4100360200200341286a41d4e2cc003602002003420137021c200341fca4c000360218200341086a41aad3c800200341186a4184a5c000108301000b2000200241ff01716a220120012d000020032d0019733a0000200020002d00c80141016a22013a00c8010240200141ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002101200041003b01c8010b20032d0007412471450d00200141ff01712201450d00200141c7014b0d01200020016a220120012d000020002d00c901733a000020002d00c80141016a41ff0171220141c8014f0d02200020016a220120012d00004104733a0000200020002d00a701418001733a00a7012000108001200041003b01c8010b200341306a24000f0b200141c8014194a5c000103c000b200141c80141a4a5c000103c000b6601017f230041206b220424002004200136020420042000360200200441086a41106a200241106a290200370300200441086a41086a200241086a2902003703002004200229020037030820044198a3c000200441046a4198a3c000200441086a20031058000b960801027f230041306b2205240020052004360200200041124100108201024002400240024002402002450d0020002d00c80121060340200641ff0171220641c7014b0d02200020066a220620062d000020012d0000733a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002106200041003b01c8010b200141016a21012002417f6a22020d000b0b200541123a000720002d00ca014112470d0120002d00c801220641c7014b0d03200020066a220620062d000020052d0000733a0000200020002d00c80141016a22063a00c8010240200641ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002106200041003b01c8010c030b200141c801490d020c030b200641c80141bca3c000103c000b200541206a410c6a41093602002005411c6a4102360200200541086a410c6a4102360200200541106a41aca4c0003602002005410236020c2005419ca4c000360208200541093602242005200041ca016a2200360220200541186a200541206a3602002005200541076a3602282000200541076a200541086a41eca4c000108301000b2000200641ff01716a220620062d000020052d0001733a0000200020002d00c80141016a22063a00c80102400240200641ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002106200041003b01c8010c010b200141c7014b0d010b2000200641ff01716a220620062d000020052d0002733a0000200020002d00c80141016a22063a00c80102400240200641ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002106200041003b01c8010c010b200141c7014b0d010b2000200641ff01716a220620062d000020052d0003733a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000108001200041003b01c8010b200041024100108201024002402004450d0020002d00c80121060340200641ff0171220641c7014b0d02200020066a220620062d000020032d0000733a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002106200041003b01c8010b200341016a21032004417f6a22040d000b0b200541306a24000f0b200641c80141bca3c000103c000b200641ff017141c80141bca3c000103c000be00e01027f230041c0006b220424002004200337030820044108360210200041124100108201024002400240024002402002450d0020002d00c80121050340200541ff0171220541c7014b0d02200020056a220520052d000020012d0000733a0000200020002d00c80141016a22053a00c8010240200541ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002105200041003b01c8010b200141016a21012002417f6a22020d000b0b200441123a001720002d00ca014112470d0120002d00c801220541c7014b0d03200020056a220520052d000020042d0010733a0000200020002d00c80141016a22053a00c8010240200541ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002105200041003b01c8010c030b200141c801490d020c030b200541c80141bca3c000103c000b200441306a410c6a41093602002004412c6a4102360200200441186a410c6a4102360200200441206a41aca4c0003602002004410236021c2004419ca4c000360218200441093602342004200041ca016a2200360230200441286a200441306a3602002004200441176a3602382000200441176a200441186a41eca4c000108301000b2000200541ff01716a220520052d000020042d0011733a0000200020002d00c80141016a22053a00c80102400240200541ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002105200041003b01c8010c010b200141c7014b0d010b2000200541ff01716a220520052d000020042d0012733a0000200020002d00c80141016a22053a00c80102400240200541ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002105200041003b01c8010c010b200141c7014b0d010b2000200541ff01716a220520052d000020042d0013733a0000200020002d00c80141016a22053a00c8010240200541ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000108001200041003b01c8010b200041024100108201024020002d00c801220541c8014f0d00200020056a220520052d000020042d0008733a0000200020002d00c80141016a22053a00c80102400240200541ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002105200041003b01c8010c010b200141c8014f0d010b2000200541ff01716a220520052d000020042d0009733a0000200020002d00c80141016a22053a00c80102400240200541ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002105200041003b01c8010c010b200141c7014b0d010b2000200541ff01716a220520052d000020042d000a733a0000200020002d00c80141016a22053a00c80102400240200541ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002105200041003b01c8010c010b200141c7014b0d010b2000200541ff01716a220520052d000020042d000b733a0000200020002d00c80141016a22053a00c80102400240200541ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002105200041003b01c8010c010b200141c7014b0d010b2000200541ff01716a220520052d000020042d000c733a0000200020002d00c80141016a22053a00c80102400240200541ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002105200041003b01c8010c010b200141c7014b0d010b2000200541ff01716a220520052d000020042d000d733a0000200020002d00c80141016a22053a00c80102400240200541ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002105200041003b01c8010c010b200141c7014b0d010b2000200541ff01716a220520052d000020042d000e733a0000200020002d00c80141016a22053a00c80102400240200541ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002105200041003b01c8010c010b200141c7014b0d010b2000200541ff01716a220520052d000020042d000f733a0000200020002d00c80141016a22053a00c8010240200541ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000108001200041003b01c8010b200441c0006a24000f0b200541ff017141c80141bca3c000103c000b200541ff017141c80141bca3c000103c000bb80801027f230041306b2205240020052004360200200041124100108201024002400240024002402002450d0020002d00c80121060340200641ff0171220641c7014b0d02200020066a220620062d000020012d0000733a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002106200041003b01c8010b200141016a21012002417f6a22020d000b0b200541123a000720002d00ca014112470d0120002d00c801220641c7014b0d03200020066a220620062d000020052d0000733a0000200020002d00c80141016a22063a00c8010240200641ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002106200041003b01c8010c030b200141c801490d020c030b200641c80141bca3c000103c000b200541206a410c6a41093602002005411c6a4102360200200541086a410c6a4102360200200541106a41aca4c0003602002005410236020c2005419ca4c000360208200541093602242005200041ca016a2200360220200541186a200541206a3602002005200541076a3602282000200541076a200541086a41eca4c000108301000b2000200641ff01716a220620062d000020052d0001733a0000200020002d00c80141016a22063a00c80102400240200641ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002106200041003b01c8010c010b200141c7014b0d010b2000200641ff01716a220620062d000020052d0002733a0000200020002d00c80141016a22063a00c80102400240200641ff0171220141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002106200041003b01c8010c010b200141c7014b0d010b2000200641ff01716a220620062d000020052d0003733a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a7012000108001200041003b01c8010b20004107410010820102402004450d0020002d00c8012106024002400340200641ff0171220641c7014b0d012003200020066a2d00003a000020002d00c801220641c7014b0d02200020066a41003a0000200020002d00c80141016a22063a00c8010240200641ff017141a601470d00200020002d00a60120002d00c901733a00a601200020002d00a701418401733a00a701200010800141002106200041003b01c8010b200341016a21032004417f6a22040d000c030b0b200641c80141a4a6c000103c000b200641c80141b4a6c000103c000b200541306a24000f0b200641ff017141c80141bca3c000103c000bc60201037f23004180016b2202240020002802002100024002400240024020012802002203411071450d0020002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d02200141ac88c0004102200220006a4180016a410020006b104b21000c010b20002d0000210402402003412071450d00410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d03200141ac88c0004102200220006a4180016a410020006b104b21000c010b2004ad42ff01832001104821000b20024180016a240020000f0b2004418001419c88c0001056000b2004418001419c88c0001056000b820401027f230041106b220224000240024002400240024002400240024002402000280200417b6a2203410220034108491b0e080102030405060700010b200128021841e4a6c000410c2001411c6a28020028020c11000021010c070b200128021841f0a6c00041102001411c6a28020028020c11000021010c060b20012802184180a7c00041132001411c6a28020028020c11000021010c050b200220012802184193a7c000410c2001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41a0a7c00010661a20022d0008210120022802042203450d04200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d0041012101200028021841f79ec00041012000411c6a28020028020c1100000d010b2002280200220128021841f89ec00041012001411c6a28020028020c11000021010b200220013a00080c040b200128021841b0a7c000410b2001411c6a28020028020c11000021010c030b200128021841bba7c000410c2001411c6a28020028020c11000021010c020b200128021841c7a7c000410d2001411c6a28020028020c11000021010c010b200128021841d4a7c000410c2001411c6a28020028020c11000021010b200241106a2400200141ff01714100470b1c002001280218419eeacc00410f2001411c6a28020028020c1100000bd10201057f230041106b22022400024002400240024002400240024002400240024020012d00000e06010203040500010b20024181ca003b01082002200141216a3602042002200141016a3602000c050b410110322201450d062000428180808010370204200020013602000c050b2001410c6a22032802002204412020044120491b220541016a2204102c2206450d0520062004200410eb082106200328020022032005490d06200641016a200141046a280200200510e9081a2000200436020820002004360204200020063602000c040b20024181c4003b01082002200141216a3602042002200141016a3602000c020b20024181c6003b01082002200141216a3602042002200141016a3602000c010b20024181c8003b01082002200141216a3602042002200141016a3602000b20002002108b010b200241106a24000f0b1036000b2005200341b8aac000104d000bef06010c7f230041206b22022400200141096a2d0000210320012802042104200128020021050240024002400240024002400240024002400240024020012d000822064102470d0002402005450d00200420056b21070c020b2000420137020041002107200041086a22084100360200410121010c030b20064101462101024020050d00200121070c020b2001200420056b6a220720014f0d002000420137020041002107200041086a2208410036020041012101200641014621090c040b2007417f4c0d080b0240024020070d00410121010c010b2007102c2201450d050b20002001360200200041086a22084100360200200041046a200736020020064102470d010b200420056b410020051b21090c020b200641014621092005450d010b02402009200420056b6a220a2009490d00200a21090c010b200041046a210b410021090340024002400240200641ff01714102470d002003210a0c010b4100210a2006410171450d00410021060c010b2005450d0520052004460d0520052d0000210341022106200541016a21050b0240024020092007470d00200720076b417f200420056b410020051b220c41016a220d200d200c491b220c4f0d002007200c6a220c2007490d072007410174220d200c200d200c4b1b220c4108200c41084b1b210c0240024020070d00200241003602100c010b2002410136021820022007360214200220013602100b2002200c4101200241106a107d2002280208210720022802004101460d01200020022802042201360200200b20073602000b200120096a20033a00002008200941016a2209360200200a21030c010b0b2007450d040c010b200720094f0d012007410174220a2009200a20094b1b22094108200941084b1b21090240024020070d00200241003602100c010b200241106a41086a410136020020022007360214200220013602100b200220094101200241106a107d200241086a2802002107024020022802004101460d00200020022802042201360200200041046a20073602000c020b2007450d030b1036000b410021070240024020060e03010001000b200120033a000041012107200141016a21010b02402005450d0020042005460d00200720056b21070340200120052d00003a0000200141016a21012004200541016a2205470d000b200420076a21070b200820073602000b200241206a24000f0b1038000bc10201067f230041206b2202240041002103024002400240200141016a2204200028020422054d0d000240200041146a22062802002201200041106a280200470d00200141016a22032001490d03200141017422072003200720034b1b22034104200341044b1b220341ffffffff03712003464102742107200341027421030240024020010d00200241003602100c010b200241186a4104360200200220014102743602142002200028020c3602100b200220032007200241106a107d200241086a280200210320022802004101460d022000200228020436020c200041106a20034102763602000b200028020c220341046a2003200141027410ea081a2003200420056b36020020002004360204410121032006200141016a3602002000200028020041016a3602000b200241206a240020030f0b2003450d001036000b1038000bc60101097f200141146a28020022034102742104200128020c210520012802002106417f210720012802042208210902400340024020040d00410021040c020b200741016a21072004417c6a21042005280200210a200920024b210b200541046a21052009200a6b2109200b0d000b200620036b2205210402402003200b20076a2209490d00200141146a20093602002006200b6b20076b21040b20002005360204200041086a2004360200410121040b20002004360200200120082002200820024b1b3602040b810201057f0240024020012802042202450d002001280200210303402002418c016a210420022f018a012105410021010240034020052001460d01418fafc0002004410810ec082206450d04200141016a2101200441086a21042006417f4a0d000b2001417f6a21050b2003450d012003417f6a2103200220054102746a41e4016a28020021020c000b0b200041003602042000410c6a4128360200200041086a4197afc000360200200041013602000f0b024020022001410c6c6a2201410c6a2802004108490d00200041086a200141046a280200290000370300200041003602000f0b20004201370300200041086a41bfafc000ad42808080809005843702000b1c00200128021841a2b3c000410b2001411c6a28020028020c1100000b1c00200128021841adb3c00041052001411c6a28020028020c1100000b800201047f230041206b2202240002400240200041046a280200200041086a2802002203460d00200028020021040c010b0240200341016a22042003490d00200341017422052004200520044b1b22044108200441084b1b21040240024020030d00200241003602100c010b200241106a41086a410136020020022003360214200220002802003602100b200220044101200241106a107d200241086a2802002103024020022802004101460d00200020022802042204360200200041046a2003360200200041086a28020021030c020b2003450d001036000b1038000b200420036a20013a0000200041086a2200200028020041016a360200200241206a24000bc004010b7f23004180016b2203240002400240024002400240200220012802044105762204200420024b1b22054105742204417f4c0d000240024020050d00410121060c010b2004102c2206450d030b024020020d00410021020c040b200341c8006a41017221044100210741002108410021090340200341c8006a2001109301200341286a41086a220a200441086a290000370300200341286a41106a220b200441106a290000370300200341286a41186a220c200441186a2900003703002003200429000037032820032d00484101460d02200341086a41186a220d200c290300370300200341086a41106a220c200b290300370300200341086a41086a220b200a290300370300200320032903283703080240024020092005470d002007200941016a220a2007200a4b1b220a4104200a41044b1b220a41ffffff3f71200a462105200a410574210a0240024020090d00200341003602480c010b200341013602502003200836024c200320063602480b200341f0006a200a2005200341c8006a107d2003280278210a20032802704101460d0120032802742106200a41057621050b200620086a220a2003290308370000200a41186a200d290300370000200a41106a200c290300370000200a41086a200b290300370000200741026a2107200841206a21082002200941016a2209460d050c010b0b200a0d020b1038000b20004100360200200541ffffff3f71450d022006102e0c020b1036000b2000200536020420002006360200200041086a20023602000b20034180016a24000bfd0202047f047e230041b0016b2202240041002103200241003a00682001280204417f6a210402400240024003402004417f460d01200241c8006a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00682004417f6a21042005210320054120470d000b200241f0006a41086a2204200241c8006a41086a290300370300200241f0006a41106a2201200241c8006a41106a290300370300200241f0006a41186a2203200241c8006a41186a29030037030020022002290348370370200541ff0171411f4d0d01200241286a41186a20032903002206370300200241086a41086a20042903002207370300200241086a41106a20012903002208370300200241086a41186a2006370300200220022903702209370308200041196a2006370000200041116a2008370000200041096a200737000020002009370001410021040c020b200341ff0171450d00200241003a00680b410121040b200020043a0000200241b0016a24000bcc0403027f017e077f230041a0076b2203240002400240024002400240024002402002200128020028020441b0026e2204200420024b1bad42b0027e2205422088a70d002005a72204417f4c0d000240024020040d00410821060c010b2004102c2206450d040b2001200128020441016a2207360204200441b0026e210802400240200720012802084b0d0020020d01410021020c070b200041003602000c030b200341e0046a41047221094100210a41002104410021070340200341e0046a200110950120032802e004210b200341b4026a200941ac0210e9081a200b411c460d02200341086a200341b4026a41ac0210e9081a0240024020072008470d00200a200741016a2208200a20084b1b22084104200841044b1bad42b0027e2205422088a74541037421082005a7210c0240024020070d00200341003602e0040c010b200341083602e804200320043602e404200320063602e0040b20034190076a200c2008200341e0046a107d20032802980721082003280290074101460d012003280294072106200841b0026e21080b200620046a220c200b360200200c41046a200341086a41ac0210e9081a200a41026a210a200441b0026a21042002200741016a2207460d060c010b0b20080d030b1038000b200041003602002007450d002006210703402007109601200741b0026a2107200441d07d6a22040d000b0b2008450d03200841b0026c450d032006102e0c030b1036000b200128020421070b2000200836020420002006360200200041086a200236020020012007417f6a3602040b200341a0076a24000b93e9030d057f017e037f027e027f077e0f7f027e017f027e017f017e0e7f230041c01a6b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020020060e250102030405060708090a290b0c0d0e0f101112132929292914151629172e2d2929292c2b2a290b2000411c3602000c560b200128020022032802042204450d54200328020022052d0000210620032004417f6a3602042003200541016a36020002400240024002400240024002400240024002400240024020060e0a00010203040506070809600b2001280200220128020422034104490d5f20012802002205280000210420012003417c6a3602042001200541046a3602002004418194ebdc034f0d5f410121010c0a0b2002200110ad0120022802000d5e20012802002205280204220620022802042203490d5e2003417f4c0d560240024020030d00410121040c010b200310322204450d5c2001280200220528020421060b20062003490d5d20042005280200200310e9082101200528020422062003490d302005200620036b3602042005200528020020036a3602002001450d5e2003ad220742208620078421074102410b20011b21010c080b2001280200220128020422034108490d5d2001280200220429000021072001200341786a3602042001200441086a360200410321010c080b200241086a200110ad0120022802080d5c200128020022052802042206200228020c2203490d5c2003417f4c0d540240024020030d00410121040c010b200310322204450d5a2001280200220528020421060b20062003490d5b20042005280200200310e9082101200528020422062003490d262005200620036b3602042005200528020020036a3602002001450d5c2003ad220742208620078421074104410b20011b21010c060b200241106a200110ad0120022802100d5b20012802002205280204220620022802142203490d5b2003417f4c0d530240024020030d00410121040c010b200310322204450d592001280200220528020421060b20062003490d5a20042005280200200310e9082101200528020422062003490d242005200620036b3602042005200528020020036a3602002001450d5b2003ad220742208620078421074105410b20011b21010c050b200241c0156a200110fd0520022802c01522044102460d5a20022902c4152107410621010c040b200241286a200110ad0120022802280d59200228022c2206200128020028020441186e2203200320064b1bad42187e2207422088a70d512007a72203417f4c0d510240024020030d00410421040c010b2003102c2204450d570b2001200128020441016a2205360204200341186ead2107200520012802084b0d57024002402006450d000340200241206a200110ad0120022802200d5a20012802002205280204220820022802242203490d5a2003417f4c0d540240024020030d00410121090c010b200310322209450d5a2001280200220528020421080b0240024020082003490d0020092005280200200310e90821082005280204220a2003490d2f2005200a20036b3602042005200528020020036a3602002008450d5c200241186a200110ad012003ad220b422086200b84220ca7210d024020022802180d0020012802002205280204220a200228021c2203490d002003417f4c0d570240024020030d004101210e0c010b20031032220e450d5d20012802002205280204210a0b02400240200a2003490d00200e2005280200200310e908210a2005280204220e20034f0d012003200e41b8b2c0001056000b200e102e0c010b2005200e20036b3602042005200528020020036a360200200a0d020b200d450d5c0b2009102e0c5b0b02402007422088220ba722052007a7470d00200541016a22092005490d552005410174220e20092009200e491b22094104200941044b1bad42187e220b422088a7454102742109200ba7210e0240024020050d00200241003602c0150c010b200241043602c815200220043602c0152002200541186c3602c4150b200241e0076a200e2009200241c0156a107d20022802e807210920022802e0074101460d0320022802e40721042007422088220ba72105200941186ead21070b2004200541186c6a2205200d36020420052008360200200541146a2003ad220f422086200f84220f422088a73602002005410c6a200f422086200aad84370200200541086a200c422088a7360200200b422086200742ffffffff0f83844280808080107c21072006417f6a22060d000b200128020421050b20012005417f6a3602042004450d5a4107410b20041b21010c040b2009450d510c560b200241c0156a200110e80120022802c0152204450d5820022902c4152107410821010c020b200241306a200110ad0120022802300d5720012802002205280204220620022802342203490d572003417f4c0d4f0240024020030d00410121040c010b200310322204450d552001280200220528020421060b20062003490d5620042005280200200310e9082106200528020422082003490d1f2005200820036b3602042005200528020020036a3602002006450d572003ad2207422086200784210702402001280200220128020422054104490d0020012802002206280000210320012005417c6a3602042001200641046a360200410921010c030b2007a70d560c570b200241386a200110ad0120022802380d56200128020022052802042206200228023c2203490d562003417f4c0d4e0240024020030d00410121040c010b200310322204450d542001280200220528020421060b20062003490d5520042005280200200310e9082101200528020422062003490d1d2005200620036b3602042005200528020020036a3602002001450d562003ad22074220862007842107410a410b20011b21010b0b20004100360200200041186a2003360200200041106a20073702002000410c6a2004360200200041086a2001360200200041206a200241f0176a41900210e9081a0c550b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020002400240024002400240024002400240024020060e06000102030405090b2001280200220428020422054104490d0820042802002206280000210320042005417c6a3602042004200641046a360200200241f0176a200110fd0520022802f01722044102460d08200128020022062802042209450d08200241f8176a280200210820022802f417210a2006280200220d2d0000210520062009417f6a3602042006200d41016a3602002001200128020441016a2206360204200620012802084b0d08200241f0176a200110950120022802f0172109200241c0156a200241f0176a41047241ac0210e9081a2009411c460d08200241f0176a200241c0156a41ac0210e9081a41b002102c2206450d5920062009360200200641046a200241f0176a41ac0210e9081a20012001280204417f6a36020441012101420021070c050b2001280200220428020422054104490d0720042802002206280000210320042005417c6a3602042004200641046a3602002001280200220128020422054104490d0720012802002206280000210420012005417c6a3602042001200641046a3602004102210141002106420021070c040b200241c0006a200110ad0120022802400d0620012802002205280204220620022802442204490d062004417f4c0d520240024020040d00410121030c010b200410322203450d582001280200220528020421060b20062004490d0520032005280200200410e9082106200528020422082004490d2a2005200820046b3602042005200528020020046a3602002006450d062004ad2207422086200784220ba721042001280200220528020422064104490d042005280200220a280000210820052006417c6a3602042005200a41046a360200200241f0176a200110fd0520022802f01722064102460d042001280200220a2802042209450d0420022902f4172107200a280200220d2d00002105200a2009417f6a360204200a200d41016a3602002001200128020441016a220a360204200a20012802084b0d04200241f0176a200110950120022802f017210d200241c0156a200241f0176a41047241ac0210e9081a200d411c460d04200241f0176a200241c0156a41ac0210e9081a41b002102c2209450d57200b422088a7210a2009200d360200200941046a200241f0176a41ac0210e9081a20012001280204417f6a360204410321010c030b200241c8006a200110ad0120022802480d05200128020022052802042206200228024c2204490d052004417f4c0d510240024020040d00410121030c010b200410322203450d572001280200220528020421060b20062004490d0420032005280200200410e9082101200528020422062004490d1f2005200620046b3602042005200528020020046a3602002001450d052004ad22074220862007842207422088a7210a2007a721044104210141002106410021080c020b2001280200220428020422054104490d0420042802002206280000210320042005417c6a3602042004200641046a360200200241f0176a200110fd0520022802f01722044102460d04200128020022062802042208450d0420022902f41721072006280200220a2d0000210520062008417f6a3602042006200a41016a3602002001200128020441016a2206360204200620012802084b0d04200241f0176a200110950120022802f0172108200241c0156a200241f0176a41047241ac0210e9081a2008411c460d04200241f0176a200241c0156a41ac0210e9081a41b002102c2206450d5520062008360200200641046a200241f0176a41ac0210e9081a20012001280204417f6a3602042007422088a721082007a7210a41052101420021070c010b200241d0006a200110ad0120022802500d0320012802002205280204220620022802542204490d032004417f4c0d4f0240024020040d00410121030c010b200410322203450d552001280200220528020421060b20062004490d0220032005280200200410e9082106200528020422082004490d1c2005200820046b3602042005200528020020046a3602002006450d032004ad2207422086200784220ba721042001280200220528020422064104490d012005280200220a280000210820052006417c6a3602042005200a41046a360200200241f0176a200110fd0520022802f01722064102460d012001280200220a2802042209450d0120022902f4172107200a280200220d2d00002105200a2009417f6a360204200a200d41016a3602002001200128020441016a220a360204200a20012802084b0d01200241f0176a200110950120022802f017210d200241c0156a200241f0176a41047241ac0210e9081a200d411c460d01200241f0176a200241c0156a41ac0210e9081a41b002102c2209450d54200b422088a7210a2009200d360200200941046a200241f0176a41ac0210e9081a20012001280204417f6a360204410621010b200020053a0005200020013a000420004101360200200041246a20093602002000411c6a2007370200200041186a2006360200200041146a2008360200200041106a200a3602002000410c6a2004360200200041086a2003360200200041286a200241e0076a41880210e9081a0c570b2004450d010b2003102e0b2000411c3602000c540b200128020022032802042204450d4e200328020022052d0000210620032004417f6a3602042003200541016a3602000240024002400240024020060e03000103530b200241f0176a2001109802200241fc176a2802002204450d5220024184186a280200210320024180186a280200210520022802f817210920022903f0172107200241e0076a20024188186a41e40010e9081a200241f4186a2802002108200241f0176a4180016a2802002106200241ec186a280200210a200241c0156a200241f8186a41800110e9081a200241f0176a200110f601024020022802f417450d00200241fc176a290200210c20022902f417210b20022802f0172101200241a80e6a200241e0076a41e40010e9081a200241d8116a200241c0156a41800110e9081a4101210d0c040b02402003450d00200341246c21032004210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012003415c6a22030d000b0b02402005450d00200541246c450d002004102e0b02402008450d00200841246c2103200a210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012003415c6a22030d000b0b2006450d52200641246c0d010c520b200241f0176a2001109802200241fc176a2802002204450d5120024184186a280200210320024180186a280200210520022802f817210920022903f0172107200241e0076a20024188186a41e40010e9081a200241f4186a2802002108200241f0176a4180016a2802002106200241ec186a280200210a200241c0156a200241f8186a41800110e9081a200241f0176a200110f601024020022802f417450d00200241fc176a290200210c20022902f417210b20022802f0172101200241a80e6a200241e0076a41e40010e9081a200241d8116a200241c0156a41800110e9081a4102210d0c030b02402003450d00200341246c21032004210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012003415c6a22030d000b0b02402005450d00200541246c450d002004102e0b02402008450d00200841246c2103200a210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012003415c6a22030d000b0b2006450d51200641246c450d510b200a102e0c500b200128020022032802042204450d4f200328020022052d0000210620032004417f6a3602042003200541016a36020020064101470d4f2001280200220328020422044108490d4f20032802002205290000210b2003200441786a3602042003200541086a3602002001280200220328020422044108490d4f20032802002205290000210c2003200441786a3602042003200541086a360200200128020022012802042203450d4f200128020022042d0000210520012003417f6a3602042001200441016a3602004200210702400240024020050e03020001520b420121070c010b420221070b200241a80e6a200241d8146a41e40010e9081a200241d8116a200241e0076a41800110e9081a4103210d0b200241d00a6a200241a80e6a41e40010e9081a20024198106a200241d8116a41800110e9081a200041186a200c370200200041106a200b370200200041346a2003360200200041306a20053602002000412c6a2004360200200041286a2009360200200041206a20073702002000410c6a2001360200200041086a200d36020020004102360200200041386a200241d00a6a41e40010e9081a200041a4016a2008360200200041a0016a20063602002000419c016a200a360200200041a8016a20024198106a41800110e9081a0c530b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020020060d00200241d8006a200110da042002290358a70d002002290360210720004103360200200041086a2007370300200041106a200241f0176a41a00210e9081a0c530b2000411c3602000c520b200128020022032802042204450d49200328020022052d0000210620032004417f6a3602042003200541016a3602000240024002400240024020060e0500010203044e0b2001280200220128020422044104490d4d20012802002205280000210320012004417c6a3602042001200541046a36020042002107410121084200210b0c4f0b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2203200241c0156a410f6a290000370000200241e0076a41086a2204200241c0156a41086a290300370300200241d8116a410f6a22052003290000370000200241d8116a41086a2203200429030037030020024198106a41086a2204200329030037030020024198106a410f6a22032005290000370000200220022903c01537039810200241df156a310000210b20022900d7152107200241f8136a410f6a22052003290000370000200241f8136a41086a200429030037030020022002290398103703f8132001280200220128020422084104490d4d2005280000210a200228008b14210920022900ff13210c20022800fb13210320022f00f913210420022d00f81321052001280200220d280000210620012008417c6a3602042001200d41046a36020020022007421888a73b00eb1420022007421088a73a00ea1420022007a73b01e81420022009ad422086200aad843703e01420022007422888200b42188684a722013600ed142001411076210a2002200c3703d814200c421888a7210d200c420888a72109200241d8146a410f6a290000210b20022900df142107200ca7210e410221080c4f0b200441ff0171450d4c200241003a00e0150c4c0b2001280200220128020422044104490d4b20012802002205280000210320012004417c6a3602042001200541046a36020042002107410321080c4c0b41002104200241003a00e0150240024002400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2203200241c0156a410f6a290000370000200241e0076a41086a2204200241c0156a41086a290300370300200241d8116a410f6a22052003290000370000200241d8116a41086a2203200429030037030020024198106a41086a2204200329030037030020024198106a410f6a22032005290000370000200220022903c01537039810200241df156a310000210b20022900d7152107200241f8136a410f6a22052003290000370000200241f8136a41086a200429030037030020022002290398103703f81320012802002208280204220a4104490d4d2005280000210d200228008b14210e20022900ff13210c20022800fb13210320022f00f913210420022d00f81321052008280200220928000021062008200a417c6a3602042008200941046a360200200128020022012802042208450d4d2001280200220a2d0000210920012008417f6a3602042001200a41016a3602004100210120090e0202014d0b200441ff0171450d4c200241003a00e0150c4c0b410121010b2002200e3602f4092002200d3602f009200220073703f8092007423888200b42ff018342088684a7210a2002200c3703e809200c421888a7210d200c420888a72109200241f7096a290000210b20022900ef092107200ca7210e410421080c4c0b2001280200220128020422044104490d4920012802002205280000210320012004417c6a3602042001200541046a36020042002107410521080c4a0b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a360200024002400240024002400240024020060e0400010203070b200241c0156a200110eb0120022d00c0154105460d06200241c0156a41106a290300210b200241c8156a2903002107200241e0156a2802002103200241d8156a290300210c20022802c415210520022802c0152104200241e8006a200110820202402002290368a70d00200241e8006a41106a29030021102005ad4220862004ad8421112002290370220f422088a72105200fa72104410121010c040b200441ff01714102470d062007a7450d062005102e0c060b200241c0156a200110eb0120022d00c0154105460d05200241c0156a41106a290300210b200241e0156a2802002103200241d8156a290300210c200241c8156a290300210720022802c415210520022802c015210420024198016a2001108202200229039801a70d0420024198016a41106a290300211020022903a001210f20024180016a2001108202200229038001a70d0420024180016a41106a290300211220022903880121132005ad4220862004ad842111200f422088a72105200fa72104410221010c020b200241c0156a200110eb0120022d00c0154105460d04200241c0156a41106a290300210b200241e0156a22042802002103200241d8156a290300210c200241c0156a41086a2205290300210720022802c415210820022802c0152106200241c0156a200110eb01024020022d00c0154105460d00200241d8116a41086a200241c0156a41146a290200370300200241d8116a41106a200241dc156a2802003602002002200241c0156a410c6a2902003703d8112005280200210a2004350200210f20022802c415210520022802c0152104200241b0016a2001108202024020022903b001a70d00200241b0016a41106a290300211420022903b8012115200241e0076a41146a200241d8116a41106a280200360200200241e0076a410c6a200241e0116a290300370200200220022903d8113702e4072002200a3602e0072008ad4220862006ad842111200241e0076a41106a290300211220022903e007211020022903e8072113410321010c030b200441ff01714102470d00200a450d002005102e0b200641ff01714102470d042007a7450d042008102e0c040b200241c0156a200110eb0120022d00c0154105460d03200241c0156a41106a290300210b200241c8156a2903002107200241e0156a2802002103200241d8156a290300210c20022802c415210520022802c0152104200241c8016a200110820220022903c801a70d01200241c8016a41106a29030021102005ad4220862004ad84211120022903d001220f422088a72105200fa721044200210f4104210142002113420021120b20004105360200200041e0006a2014370200200041d8006a2015370200200041c8006a2012370200200041c0006a2013370200200041386a20103702002000411c6a200b370200200041146a2007370200200041d0006a200f3702002000412c6a2003360200200041246a200c3702002000410c6a2011370200200041086a2001360200200041306a2005ad4220862004ad84370200200041e8006a200241f0176a41c80110e9081a0c530b200441ff01714102470d012007a7450d012005102e0c010b200441ff01714102470d002007a7450d002005102e0b2000411c3602000c500b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020020060d00200241e0016a200110ad0120022802e0010d0020022802e4012205200128020028020441f0006e2203200320054b1bad42f0007e2207422088a70d472007a72203417f4c0d470240024020030d00410421060c010b2003102c2206450d4d0b2001200128020441016a2204360204200341f0006ead21070240200420012802084b0d00024002402005450d00200241c0156a41086a21090340200241c0156a200110990220022802c415210420022802c0152108200241e0076a200941e80010e9081a2004450d03200241d8116a200241e0076a41e80010e9081a02402007422088220ba722032007a7470d00200341016a220a2003490d4c2003410174220d200a200a200d491b220a4104200a41044b1bad42f0007e220b422088a745410274210a200ba7210d0240024020030d00200241003602c0150c010b200241043602c815200220063602c0152002200341f0006c3602c4150b20024198106a200d200a200241c0156a107d20022802a010210a2002280298104101460d03200228029c1021062007422088220ba72103200a41f0006ead21070b2006200341f0006c6a2203200436020420032008360200200341086a200241d8116a41e80010e9081a200b422086200742ffffffff0f83844280808080107c21072005417f6a22050d000b200128020421040b20012004417f6a3602042006450d022000200636020420004106360200200041086a2007370200200041106a200241f0176a41a00210e9081a0c520b200a0d4d0c480b02402007422088a72201450d002006200141f0006c6a2105200621010340024020012204410c6a2802002203450d0020042802042101200341246c210303400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012003415c6a22030d000b0b200441f0006a21010240200441086a2802002203450d00200341246c450d002004280204102e0b20012005470d000b0b2007a72201450d00200141f0006c450d002006102e0b2000411c3602000c4f0b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a360200410021164100210e410721090240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020060e170001020304055c060708090a0b0c0d0e0f101112131415170b200241c0156a200110eb0120022d00c0154105460d16200241d8116a41086a200241d4156a290200370300200241d8116a41106a200241dc156a2902003703002002200241cc156a2902003703d811200241c0156a41086a280200210820022802c415210a20022802c0152105200241e8016a2001108202024002400240024020022903e801a70d00200128020022032802042204450d00200241e8016a41106a290300210c20022903f001210b200328020022062d0000210e20032004417f6a360204410121092003200641016a36020041002104024002400240200e0e050600010204030b410121040c050b410221040c030b41002104200241003a00e01502400340200128020022032802042206450d01200241c0156a20046a2003280200220d2d00003a000020032006417f6a3602042003200d41016a3602002002200441016a22033a00e0152003210420034120470d000b200241a80e6a410f6a2201200241c0156a410f6a290000370000200241a80e6a41086a2203200241c0156a41086a290300370300200241d8146a410f6a22042001290000370000200241d8146a41086a22012003290300370300200241d00a6a41086a22032001290300370300200241d00a6a410f6a22012004290000370000200220022903c0153703d00a200241c0156a411f6a310000210720022900d715210f200241f8136a410f6a22042001290000370000200241f8136a41086a2003290300370300200220022903d00a3703f8132004290000211020022800fb13210120022900ff13211120022d00f8132103200220022f00f9133b00e107200220033a00e007200241e0076a411f6a20073c0000200241e0076a410f6a20103700002002200f3700f707200220113700e707200220013600e3074103210420022f01e007210d0c040b200441ff0171450d00200241003a00e0150b200541ff01714102470d192008450d19200a102e0c190b410421040b0b20024198106a41106a200241d8116a41106a29030037030020024198106a41086a200241d8116a41086a290300221137030020022901e607220f422088200241ee076a2901002210422086842107200fa7220e41807e7121162010422088210f20022d00ff07211720022800fb07211820022f00f907211920022d00f807211a20022f01f607211b20022801e207210320022903d811211020022802ac10211c20022f01aa10211d20022d00a910211e20022800a510211f20022f00a310212020022d00a21021212011a721220c5b0b20024180026a2001108202200229038002a70d15200229038802220b42208820024190026a290300220c422086842107200c422088210f200ba7220e41807e712116410221090c580b20024198026a2001108202200229039802a70d1420022903a002220b422088200241a8026a290300220c422086842107200c422088210f200ba7220e41807e712116410321090c570b410421092001280200220128020422044104490d1320012802002205280000210320012004417c6a3602042001200541046a360200420021070c550b200241b0026a200110ad0120022802b0020d1220022802b40221032002418094ebdc033602c415200220033602c015200128020022012802042204450d12200241c0156a2003418094ebdc034b4102746a2802002103200128020022052d0000210620012004417f6a3602042001200541016a360200410521094100210e024020060e025800130b4101210e0c550b200241c0156a200110ea0120022802c0152203450d1120022802c415220e41807e712116200241c8156a35020021074200210f410621090c540b200128020022032802042204450d0f200328020022052d0000210620032004417f6a3602042003200541016a36020002400240024002400240024020060e050001020304050b200241003a00d8140c590b200241013a00d8140c580b200241023a00d8140c570b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241d8116a410f6a2201200241c0156a410f6a290000370000200241d8116a41086a2203200241c0156a41086a29030037030020024198106a410f6a2204200129000037000020024198106a41086a22012003290300370300200241a80e6a41086a22032001290300370300200241a80e6a410f6a22012004290000370000200220022903c0153703a80e200241df156a310000211020022900d715210b200241f8136a410f6a22042001290000370000200241f8136a41086a2003290300370300200220022903a80e3703f8132004290000210c20022900ff13210720022d00f813210120022f00f9132103200220022800fb133602dc14200220033b01da14200220013a00d914200241033a00d8140c570b0240200441ff0171450d00200241003a00e0150b200241053a00d8140c120b200241043a00d8140c550b200241053a00d8140c100b200241c0156a200110eb0120022d00c0154105460d0f20022902c415220c422088200241cc156a290200220f422086842107200241d4156a290200220b422888200241dc156a31000042188684a72118200ca7220e41807e712116200f422088210f200b421888a72119200b421088a7211a200241e0156a2802002105200241de156a2f01002123200241dd156a2d0000211720022802c0152103200ba7211b410921090c520b200241b8026a200110ad0120022802b8020d0e20022802bc02210342002107410a21090c500b200241c0026a200110ad0120022802c0020d0d20022802c402210342002107410b21090c4f0b200128020022012802042203450d0c200128020022052d0000210420012003417f6a3602042001200541016a360200200441e5004f0d0c42002107410c21094100210e4200210f0c510b410d21094100210e0c4e0b410e21094100210e0c4d0b200241c0156a200110e40120022802c0152203450d0920022802c415220e41807e712116200241c8156a35020021074200210f410f21090c4c0b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2203200241c0156a410f6a290000370000200241e0076a41086a2204200241c0156a41086a290300370300200241d8116a410f6a22052003290000370000200241d8116a41086a2203200429030037030020024198106a41086a2204200329030037030020024198106a410f6a22032005290000370000200220022903c01537039810200241df156a310000210720022900d715210b200241f8136a410f6a22052003290000370000200241f8136a41086a200429030037030020022002290398103703f81320022800fb13210320022f00f913210d20022d00f8132104200241d8146a41086a22062005290000370300200220022900ff133703d814200241f0146a20073c00002002200b3703e8142001280200220128020422084104490d092001280200220a280000210520012008417c6a3602042001200a41046a36020020022903d814220b4220882006290300220c422086842107200c422088210f200ba7220e41807e71211620022800ed14211820022f00eb14211920022d00ea14211a20022f01e814211b411021090c4e0b200441ff0171450d08200241003a00e0150c080b411121094100210e0c4a0b2001280200220428020422054104490d0620042802002206280000210320042005417c6a3602042004200641046a360200200241c8026a200110ad0120022802c8020d0620022802cc02220441ffffffff03712004470d06200441027422052001280200220628020422084b0d062005417f4c0d4c0240024020050d004104210e0c010b20051032220e450d522001280200220628020421080b02400240200820044102742201490d00200e2006280200200110e90821082006280204220a20014f0d012001200a41b8b2c0001056000b2005450d07200e102e0c070b2006200a20016b3602042006200628020020016a3602002008450d062004ad4220862005410276ad842107200841807e7121164200210f411221090c490b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2203200241c0156a410f6a290000370000200241e0076a41086a2204200241c0156a41086a290300370300200241d8116a410f6a22052003290000370000200241d8116a41086a2203200429030037030020024198106a41086a2204200329030037030020024198106a410f6a22032005290000370000200220022903c01537039810200241df156a310000210b20022900d7152107200241f8136a410f6a22052003290000370000200241f8136a41086a200429030037030020022002290398103703f8132001280200220128020422084104490d062007422888200b42188684a721182005350000210c200228008b14210620022900ff13210b20022800fb13210320022f00f913210d20022d00f81321042007421888a721192007421088a7211a2007a7211b2001280200220a280000210520012008417c6a3602042001200a41046a3602002006411076ad423086200641087641ff0171ad42288684200c2006ad4220864280808080f01f8384842207422088210f200b4220882007422086842107200ba7220e41807e712116411321090c4b0b200441ff0171450d05200241003a00e0150c050b200241d0026a200110820220022903d002a70d0420022903d802220b422088200241e0026a290300220c422086842107200c422088210f200ba7220e41807e712116411421090c470b200241f0026a200110ad0120022802f0020d0320022802f4022103200241e8026a200110ad0120022802e8020d0320022802ec02220e41807e712116411521090c460b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2203200241c0156a410f6a290000370000200241e0076a41086a2204200241c0156a41086a290300370300200241d8116a410f6a22052003290000370000200241d8116a41086a2203200429030037030020024198106a41086a2204200329030037030020024198106a410f6a22032005290000370000200220022903c01537039810200241df156a310000210c20022900d715210b200241f8136a410f6a22052003290000370000200241f8136a41086a200429030037030020022002290398103703f8132001280200220128020422064104490d0320052800002108200228008b14210a20022900ff13210f20022800fb13210320022f00f913210d20022d00f813210420012802002209280000210520012006417c6a3602042001200941046a3602002002200a3602f409200220083602f009200f42208820022903f0092210422086842107200b422888200c42188684a72118200fa7220e41807e7121162010422088210f200b421888a72119200b421088a7211a200ba7211b411621090c480b200441ff0171450d02200241003a00e0150c020b200241c0156a200110ea0120022802c0152203450d0120022902c415220b4220882107200ba7220e41807e7121164200210f411721090c440b200241053a00d8140b2000411c3602000c4e0b0240200128020022012802042203450d0020012003417f6a3602042001200128020041016a3602000b2000411c3602000c4d0b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a3602004100212402400240024020060e020001030b41002104200241003a00e015024002400240024002400240024002400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241d8146a410f6a2203200241c0156a410f6a290000370000200241d8146a41086a2204200241c0156a41086a290300370300200241e8096a410f6a22052003290000370000200241e8096a41086a22032004290300370300200241c80d6a41086a22042003290300370300200241c80d6a410f6a22032005290000370000200220022903c0153703c80d200241df156a310000210c20022900d715210b200241f8136a410f6a22052003290000370000200241f8136a41086a2004290300370300200220022903c80d3703f8132005290000210720022800fb13210920022f00f913210a20022d00f813210820022900ff13211241002104200241003a00e015200b422888200c42188684a721212012428080808070832125200b421888a72122200b421088a7210e200ba7210d0340200128020022032802042205450d02200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e8096a410f6a2203200241c0156a410f6a290000370000200241e8096a41086a2204200241c0156a41086a290300370300200241c80d6a410f6a22052003290000370000200241c80d6a41086a22032004290300370300200241a00d6a41086a22042003290300370300200241a00d6a410f6a22032005290000370000200220022903c0153703a00d200241df156a310000210b20022900d715210c200241f8136a410f6a22052003290000370000200241f8136a41086a2004290300370300200220022903a00d3703f8132005290000210f20022800fb13211e20022f00f913211f20022d00f813212020022900ff132110200241f0146a200b3c00002002200c3703e8142002200f3703e014200220103703d81441002104200241003a00e0150340200128020022032802042205450d03200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e8096a410f6a2203200241c0156a410f6a290000370000200241e8096a41086a2204200241c0156a41086a290300370300200241c80d6a410f6a22052003290000370000200241c80d6a41086a22032004290300370300200241a00d6a41086a22042003290300370300200241a00d6a410f6a22032005290000370000200220022903c0153703a00d200241df156a310000211020022900d715210f200241f8136a410f6a22052003290000370000200241f8136a41086a2004290300370300200220022903a00d3703f8132005290000210c20022900ff13210b20022800fb13211720022f00f913211c20022d00f813211d41002104200241003a00e015200f422888201042188684a72118200f421888a72119200f421088a7211b200fa721230340200128020022032802042205450d04200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e8096a410f6a2203200241c0156a410f6a290000370000200241e8096a41086a2204200241c0156a41086a290300370300200241c80d6a410f6a22052003290000370000200241c80d6a41086a22032004290300370300200241a00d6a41086a22042003290300370300200241a00d6a410f6a22032005290000370000200220022903c0153703a00d200241df156a310000211120022900d7152110200241f8136a410f6a22052003290000370000200241f8136a41086a2004290300370300200220022903a00d3703f8132005350000212620022900ff13210f20022800fb13210520022f00f913210420022d00f8132103200228008b1421064100211a200241003a00e015200641087621272006ad42208621282006411076ad21290340200128020022062802042216450d05200241c0156a201a6a2006280200222a2d00003a000020062016417f6a3602042006202a41016a3602002002201a41016a22063a00e0152006211a20064120470d000b200241c80d6a410f6a2206200241c0156a410f6a290000370000200241c80d6a41086a221a200241c0156a41086a290300370300200241a00d6a410f6a22162006290000370000200241a00d6a41086a2206201a290300370300200241e80c6a41086a221a2006290300370300200241e80c6a410f6a22062016290000370000200220022903c0153703e80c200241df156a310000211520022900d7152114200241f8136a410f6a22162006290000370000200241f8136a41086a201a290300370300200220022903e80c3703f8132016290000211320022800fb13212a20022f00f913211620022d00f813211a20022900ff13212b200241800a6a20153c0000200220143703f809200220133703f0092002202b3703e8094100212c200241003a00e015034020012802002206280204222d450d06200241c0156a202c6a2006280200222e2d00003a00002006202d417f6a3602042006202e41016a3602002002202c41016a22063a00e0152006212c20064120470d000b200241c80d6a410f6a2206200241c0156a410f6a290000370000200241c80d6a41086a222c200241c0156a41086a290300370300200241a00d6a410f6a222d2006290000370000200241a00d6a41086a2206202c290300370300200241e80c6a41086a222c2006290300370300200241e80c6a410f6a2206202d290000370000200220022903c0153703e80c200241df156a310000211320022900d7152114200241f8136a410f6a222d2006290000370000200241f8136a41086a202c290300370300200220022903e80c3703f813202d280000212f200228008b14213020022900ff13211520022800fb13212e20022f00f913212d20022d00f813212c200241e0076a41186a2206200241d8146a41186a2d00003a0000200241e0076a41106a2224200241d8146a41106a290300370300200241e0076a41086a2231200241d8146a41086a290300370300200220022903d8143703e007200241d8116a41186a2232200241e8096a41186a2d00003a0000200241d8116a41106a2233200241e8096a41106a290300370300200241d8116a41086a2234200241e8096a41086a290300370300200220022903e8093703d81120024198106a41186a20062d00003a000020024198106a41106a202429030037030020024198106a41086a2031290300370300200220022903e00737039810200241a80e6a41186a20322d00003a0000200241a80e6a41106a2033290300370300200241a80e6a41086a2034290300370300200220022903d8113703a80e200241f8026a200110ad0120022802f8020d0a20012802002231280204223220022802fc022206490d0a2006417f4c0d4e20060d06410121240c070b200441ff0171450d09200241003a00e0150c090b200441ff0171450d08200241003a00e0150c080b200441ff0171450d07200241003a00e0150c070b200441ff0171450d06200241003a00e0150c060b201a41ff0171450d05200241003a00e0150c050b202c41ff0171450d04200241003a00e0150c040b200610322224450d4c2001280200223128020421320b20322006490d0120242031280200200610e9082101203128020422322006490d1d2031203220066b3602042031203128020020066a3602002001450d022029423086202741ff0171ad4228868420284280808080f01f832026848421262025201242ffffffff0f838421252006ad22124220862012842112200241d00a6a41186a20024198106a41186a2d00003a0000200241d00a6a41106a20024198106a41106a290300370300200241d00a6a41086a20024198106a41086a29030037030020024198136a41086a200241a80e6a41086a29030037030020024198136a41106a200241a80e6a41106a29030037030020024198136a41186a200241a80e6a41186a2d00003a000020022002290398103703d00a200220022903a80e370398130b200241e80f6a41186a2201200241d00a6a41186a2d00003a0000200241e80f6a41106a2206200241d00a6a41106a290300370300200241e80f6a41086a2227200241d00a6a41086a290300370300200241f80d6a41086a223120024198136a41086a290300370300200241f80d6a41106a223220024198136a41106a290300370300200241f80d6a41186a223320024198136a41186a2d00003a0000200220022903d00a3703e80f20022002290398133703f80d2000411f6a2007370000200041176a2025370000200041336a201e360000200041316a201f3b0000200041306a20203a00002000412c6a20213602002000412a6a20223b01002000200e3a0029200041276a200d3b0000200041136a2009360000200041116a200a3b0000200041106a20083a0000200041086a20123702002000202436020420004109360200200020022903e80f3700372000413f6a2027290300370000200041c7006a2006290300370000200041cf006a20012d00003a00002000418f016a20113c000020004187016a2010370000200041ff006a2026370000200041f7006a200f370000200041df006a200c370000200041d7006a200b37000020004193016a202a36000020004191016a20163b000020004190016a201a3a0000200041f3006a2005360000200041f1006a20043b0000200041f0006a20033a0000200041ec006a2018360200200041ea006a20193b01002000201b3a0069200041e7006a20233b0000200041d3006a2017360000200041d1006a201c3b0000200041d0006a201d3a0000200041b3016a202e360000200041b7016a2015370000200041bf016a202f360000200041c3016a2030360000200041cf016a20133c0000200041c7016a2014370000200041b1016a202d3b0000200041b0016a202c3a0000200041af016a20332d00003a0000200041a7016a20322903003700002000419f016a2031290300370000200020022903f80d37009701200041d0016a200241f0176a41e00010e9081a0c4e0b2024102e0b2000411c3602000c4c0b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a360200024002400240024020060e03000102040b200241f0176a200110cb0620022903f81722074202510d0320022802fc17210320022802f417210420022802f0172105200241e0076a20024180186a41e40010e9081a200241e8186a280200210620022802ec18210820022802e418210a200241c0156a200241f0176a4180016a41800110e9081a200241f0176a200110f60120022802f417450d032007a72101200241fc176a290200210b20022802f017210920022902f417210c200241d00a6a200241e0076a41e40010e9081a200241d8116a200241c0156a41800110e9081a200c422088200b422086842107200b422088210b200ca7210d4101210e0c020b200241f0176a200110cb0620022903f81722074202510d0220022802fc17210320022802f417210420022802f0172105200241a80e6a20024180186a41e40010e9081a200241e8186a280200210620022802ec18210820022802e418210a200241c0156a200241f0176a4180016a41800110e9081a200241f0176a200110f60120022802f417450d022007a72101200241fc176a290200210b20022802f017210920022902f417210c200241d8146a200241a80e6a41e40010e9081a200241e0076a200241c0156a41800110e9081a200241d00a6a200241d8146a41e40010e9081a200241d8116a200241e0076a41800110e9081a200c422088200b422086842107200b422088210b200ca7210d4102210e0c010b2001280200220328020422044104490d0120032802002205280000210920032004417c6a3602042003200541046a3602002001280200220128020422034104490d0120012802002204280000210d20012003417c6a3602042001200441046a360200200241d00a6a200241c0156a41e40010e9081a200241d8116a200241f0176a41800110e9081a4103210e0b200241e8096a200241d00a6a41e40010e9081a20024198106a200241d8116a41800110e9081a2000411c6a200b3e0200200041146a20073702002000412c6a2003360200200041286a2001360200200041246a2004360200200041206a2005360200200041106a200d3602002000410c6a2009360200200041086a200e3602002000410a360200200041306a200241e8096a41e40010e9081a2000419c016a200836020020004198016a200636020020004194016a200a360200200041a0016a20024198106a41800110e9081a200041a8026a20024198136a41086a290300370300200041a0026a2002290398133703000c4c0b2000411c3602000c4b0b200128020022032802042204450d3b200328020022052d0000210620032004417f6a3602042003200541016a36020020060d3b2001280200220328020422044104490d3b20032802002205280000210620032004417c6a3602042003200541046a36020020024190036a200110ad012002280290030d3b2001280200220428020422052002280294032203490d3b2003417f4c0d410240024020030d00410121080c010b200310322208450d472001280200220428020421050b0240024020052003490d0020082004280200200310e90821052004280204220820034f0d012003200841b8b2c0001056000b2008102e0c3c0b2004200820036b3602042004200428020020036a3602002005450d3b2003ad2207422086200784210b20024188036a200110ad012002280288030d3a200228028c0322082001280200280204410c6e2203200320084b1bad420c7e2207422088a70d412007a72203417f4c0d410240024020030d004104210a0c010b2003102c220a450d470b2001200128020441016a22043602042003410c6ead2107200420012802084b0d3902402008450d00034020024180036a200110ad012002280280030d3b2001280200220428020422092002280284032203490d3b2003417f4c0d430240024020030d004101210d0c010b20031032220d450d492001280200220428020421090b20092003490d3a200d2004280200200310e90821092004280204220d2003490d192004200d20036b3602042004200428020020036a3602002009450d3b02402007422088220ca722042007a7470d00200441016a220d2004490d442004410174220e200d200d200e491b220d4104200d41044b1bad420c7e220c422088a745410274210d200ca7210e0240024020040d00200241003602e0070c010b200241043602e8072002200a3602e00720022004410c6c3602e4070b200241d8116a200e200d200241e0076a107d20022802e011210d20022802d8114101460d3f20022802dc11210a2007422088220ca72104200d410c6ead21070b200a2004410c6c6a22042003ad220f422086200f8437020420042009360200200c422086200742ffffffff0f83844280808080107c21072008417f6a22080d000b200128020421040b20012004417f6a360204200a450d3a2002200a3602c815200128020022032802042104200220073702cc152002200b3703c015200ba7210d20044104490d3720032802002208280000210e20032004417c6a3602042003200841046a3602002001280200220328020422044104490d3720032802002208280000212020032004417c6a3602042003200841046a3602002001280200220328020422044104490d3720032802002208280000211e20032004417c6a3602042003200841046a360200200241cc156a290200210720022902c415210b4100210a200241003a008016200b422088a7211f2007422088a72121200ba7211d2007a7212241c000210402400240034002400240200128020022032802042208450d002003280200220a2d0000210920032008417f6a3602042003200a41016a36020020022d008016220341c000490d01200220093a00e00741bcf5cc00412b200241e0076a41e0c0cb0041e4decc00103e000b200a41ff0171450d02200241003a0080160c020b200241c0156a20036a20093a00002002200341016a220a3a0080162004417f6a22040d000b2003413e4b0d010b0240200d450d002005102e0b02402021450d002021410c6c2103201f210103400240200141046a280200450d002001280200102e0b2001410c6a2101200341746a22030d000b0b2022450d3c2022410c6c450d3c201f102e0c3c0b2005450d3b200241f8156a290300210720022903f015210b20022802ec15210120022f01ea15210320022800e515210420022f00e315210820022d00e215210a20022f01e015210920022903d815210c20022802d415211c20022802d015211720022802cc15212320022f01ca15211b20022d00c915211920022800c515211820022f00c315211a20022d00c215211620022f01c015212a200020022d00e9153a00552000200a3a004e200020193a0035200020163a002e200020063602042000410b360200200041e4006a2007370200200041dc006a200b370200200041d8006a2001360200200041d6006a20033b0100200041d1006a2004360000200041cf006a20083b0000200041cc006a20093b0100200041c4006a200c370200200041c0006a201c3602002000413c6a2017360200200041386a2023360200200041366a201b3b0100200041316a20183600002000412f6a201a3b00002000412c6a202a3b0100200041286a201e360200200041246a2020360200200041206a200e3602002000411c6a2021360200200041186a2022360200200041146a201f360200200041106a201d3602002000410c6a200d360200200041086a2005360200200041ec006a200241f0176a41c40110e9081a0c4a0b0240200128020022012802042203450d0020012003417f6a3602042001200128020041016a3602000b2000411c3602000c490b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a3602004200210f42002107410d21080240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020060e19000102030405060708090a0b18170c0d0e0f101112131415161a0b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b20022802dc15210d20022f01da15210920022d00d915210e20022f00d715210a20022900cf15210720022800cb15212220022800c715212120022800c315210320022f00c115210420022d00c015210520024198036a2001108202200229039803a70d1a200241a8036a290300210c20022903a003210b2007422088210f410121080c180b200441ff0171450d19200241003a00e0150c190b200241b8036a200110ad0120022802b8030d1820022802bc032103200241b0036a200110ad0120022802b0030d1820022802b403212141022108420021070c160b200241c0036a200110ad0120022802c0030d17200128020022042802042205450d1720022802c4032103200428020022062d0000210820042005417f6a3602042004200641016a36020002400240024020080e0200011a0b200128020022042802042205450d19200428020022082d0000210620042005417f6a3602042004200841016a360200410021040240024002400240024002400240200641ff00710e0706000102030405200b4180800421040c050b4180800821040c040b4180800c21040c030b4180801021040c020b4180801421040c010b4180801821040b2001280200220128020422054110490d192001280200220841086a290000210b200829000021072001200841106a3602002001200541706a360204200242003703d015200220073703c0152002200b3703c8152006410174418002712101410021050c010b2001280200220428020422054110490d182004280200220641086a290000210b200629000021072004200641106a3602002004200541706a3602042001280200220128020422044110490d182001280200220541086a290000210c2005290000210f2001200541106a360200200241d8156a200c3703002001200441706a360204200220073703c0152002200b3703c8152002200f3703d0154100210141012105410021040b2007422088210f20044180801c71200172200572212120022903d815210b20022802d415211f20022f01d215211e20022d00d115212020022800cd15210d20022f00cb15210920022d00ca15210e20022f01c815210a4200210c410321080c150b410421082001280200220128020422044104490d1620012802002205280000210320012004417c6a3602042001200541046a360200420021070c140b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b20022900cf152207422088210f20022802dc15210d20022f01da15210920022d00d915210e20022f00d715210a20022800cb15212220022800c715212120022800c315210320022f00c115210420022d00c0152105410521080c140b200441ff0171450d15200241003a00e0150c150b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b20022900cf152207422088210f20022802dc15210d20022f01da15210920022d00d915210e20022f00d715210a20022800cb15212220022800c715212120022800c315210320022f00c115210420022d00c0152105410621080c130b200441ff0171450d14200241003a00e0150c140b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b20022900cf152207422088210f20022802dc15210d20022f01da15210920022d00d915210e20022f00d715210a20022800cb15212220022800c715212120022800c315210320022f00c115210420022d00c0152105410721080c120b200441ff0171450d13200241003a00e0150c130b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b2001280200220628020422084104490d1320022802dc15210d20022f01da15210920022d00d915210e20022f00d715210a20022900cf15210720022800cb15212220022800c715212120022800c315210320022f00c115210420022d00c015210520062802002220280000211f20062008417c6a3602042006202041046a3602002001280200220128020422064104490d1320012802002208350000210b20012006417c6a3602042001200841046a3602002007422088210f4200210c410821080c110b200441ff0171450d12200241003a00e0150c120b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b20022900cf152207422088210f20022802dc15210d20022f01da15210920022d00d915210e20022f00d715210a20022800cb15212220022800c715212120022800c315210320022f00c115210420022d00c0152105410921080c100b200441ff0171450d11200241003a00e0150c110b200241c8036a200110ad0120022802c8030d1020022802cc032103410a2108420021070c0e0b2001280200220128020422044104490d0f20012802002205280000210320012004417c6a3602042001200541046a360200410b2108420021070c0d0b41002104200241003a00e015024002400240024002400240024002400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2203200241c0156a410f6a290000370000200241e0076a41086a2204200241c0156a41086a290300370300200241d8116a410f6a22052003290000370000200241d8116a41086a2203200429030037030020024198106a41086a2204200329030037030020024198106a410f6a22032005290000370000200220022903c01537039810200241df156a310000210720022900d715210b200241f8136a410f6a22052003290000370000200241f8136a41086a200429030037030020022002290398103703f813200128020022062802042208450d16200235008b14210f2005350000210c200228008314212220022800ff13212120022800fb13210320022f00f913210420022d00f81321052006280200220a2d0000210920062008417f6a3602042006200a41016a3602004100212020090e0707060102030405160b200441ff0171450d15200241003a00e0150c150b410221200c050b410321200c040b410421200c030b410521200c020b410621200c010b410121200b2001280200220128020422064110490d0e200b422888200742188684a7210d200f422086200c842107200b421888a72109200b421088a7210e200ba7210a2001280200220841086a290000210c2008290000210b2001200841106a3602002001200641706a360204410c21080c0c0b200241d0036a200110ad0120022802d0030d0d20012802002205280204220620022802d4032204490d0d2004417f4c0d4d0240024020040d00410121030c010b200410322203450d532001280200220528020421060b20062004490d0c20032005280200200410e9082101200528020422062004490d222005200620046b3602042005200528020020046a3602002001450d0d2004ad22074220862007842207422088a721222007a72121410f2108420021070c0b0b200241d8036a200110ad0120022802d8030d0c20012802002205280204220620022802dc032204490d0c2004417f4c0d4c0240024020040d00410121030c010b200410322203450d522001280200220528020421060b20062004490d0b20032005280200200410e9082101200528020422062004490d182005200620046b3602042005200528020020046a3602002001450d0c2004ad22074220862007842207422088a721222007a7212141102108420021070c0a0b200241e0036a200110ad0120022802e0030d0b20012802002205280204220620022802e4032204490d0b2004417f4c0d4b0240024020040d00410121030c010b200410322203450d512001280200220528020421060b20062004490d0a20032005280200200410e9082101200528020422062004490d162005200620046b3602042005200528020020046a3602002001450d0b2004ad22074220862007842207422088a721222007a7212141112108420021070c090b200241e8036a200110ad0120022802e8030d0a20012802002205280204220620022802ec032204490d0a2004417f4c0d4a0240024020040d00410121030c010b200410322203450d502001280200220528020421060b20062004490d0920032005280200200410e9082101200528020422062004490d142005200620046b3602042005200528020020046a3602002001450d0a2004ad22074220862007842207422088a721222007a7212141122108420021070c080b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241cf156a290000210720022802dc15210d20022f01da15210920022d00d915210e20022f00d715210a20022800c315210320022f00c115210420022d00c015210520022900c715210b200241f0036a200110ad0120022802f0030d0a200b422088a72122200ba7212120022802f403211f2007422088210f411321080c080b200441ff0171450d09200241003a00e0150c090b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2201200241c0156a410f6a290000370000200241e0076a41086a2203200241c0156a41086a290300370300200241d8116a410f6a22042001290000370000200241d8116a41086a2201200329030037030020024198106a41086a2203200129030037030020024198106a410f6a22012004290000370000200220022903c01537039810200241df156a310000210720022900d715210b200241f8136a410f6a22042001290000370000200241f8136a41086a200329030037030020022002290398103703f813200b422888200742188684a7210d200235008b14220f4220862004350000842107200b421888a72109200b421088a7210e20022900ff13220c422088a7212220022800fb13210320022f00f913210420022d00f8132105200ba7210a200ca72121411421080c070b200441ff0171450d08200241003a00e0150c080b2001280200220128020422044104490d0720012802002205280000210320012004417c6a3602042001200541046a36020041152108420021070c050b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2203200241c0156a410f6a290000370000200241e0076a41086a2204200241c0156a41086a290300370300200241d8116a410f6a22052003290000370000200241d8116a41086a2203200429030037030020024198106a41086a2204200329030037030020024198106a410f6a22032005290000370000200220022903c01537039810200241df156a310000210b20022900d7152107200241f8136a410f6a22052003290000370000200241f8136a41086a200429030037030020022002290398103703f8132001280200220128020422064104490d072007422888200b42188684a7210d2005350000210c200235008b14210f20022900ff13210b20022800fb13210320022f00f913210420022d00f81321052007421888a721092007421088a7210e2007a7210a20012802002208280000211f20012006417c6a3602042001200841046a360200200c200f422086842107200b422088a72122200ba72121411621080c050b200441ff0171450d06200241003a00e0150c060b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241d8116a41086a2206200241cf156a29000037030041172108200241d8116a41106a220a200241c0156a41176a290000370300200241d8116a41186a2209200241df156a2d00003a0000200220022900c71522073703e007200220073703d81120022d00c015210520022f00c115210420022800c3152103200241e8096a41186a220d20092d00003a0000200241e8096a41106a200a290300370300200241e8096a41086a220a2006290300370300200220022903d8113703e8092001280200220128020422064104490d0620012802002209280000211f20012006417c6a3602042001200941046a36020020022903f809220b422888200d31000042188684a7210d200a2903002207422088210f200b421888a72109200b421088a7210e20022903e809220c422088a72122200ba7210a200ca721210c040b200441ff0171450d05200241003a00e0150c050b41002104200241003a00e0150240024002400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200128020022062802042208450d0720022900d715210b200241df156a310000210f200241cf156a290000210720022900c715210c20022800c315210320022f00c115210420022d00c01521052006280200220a2d0000210920062008417f6a3602042006200a41016a3602004100211f20090e020201070b200441ff0171450d06200241003a00e0150c060b2001280200220128020422084104490d052001280200220a280000210620012008417c6a3602042001200a41046a3602004101211f0b200b422888200f42188684a7210d2007422088210f200b421888a72109200b421088a7210e200ba7210a200c422088a721222006ad210b200ca721214200210c411821080c020b200241f8036a200110ad0120022802f8030d0320022802fc03210341192108420021070c010b410e2108420021070b2000201e3b012a200020203a0029200020093b00232000200e3a0022200020043b000a200020053a00092000410d360200200041386a200c370200200041306a200b3702002000412c6a201f360200200041256a200d360000200041206a200a3b0100200041146a2022360200200041106a20213602002000410c6a2003360200200041086a20083a0000200041186a200f422086200742ffffffff0f8384370200200041c0006a200241f0176a41f00110e9081a0c4a0b2003102e0b2000411c3602000c480b200241e0076a200110cc06024020022d00e0074107460d00200241d8116a41306a200241e0076a41306a2903002207370300200241d8116a41286a200241e0076a41286a290300220b370300200241d8116a41206a200241e0076a41206a290300220c370300200241d8116a41186a200241e0076a41186a290300220f370300200241c0156a410c6a200241e0076a41086a290300370200200241c0156a41146a200241e0076a41106a290300370200200241c0156a411c6a200f370200200241c0156a41246a200c370200200241c0156a412c6a200b370200200241c0156a41346a2007370200200220022903e0073702c4152000410e360200200020022902c0153702042000410c6a200241c0156a41086a290200370200200041146a200241c0156a41106a2902003702002000411c6a200241c0156a41186a290200370200200041246a200241c0156a41206a2902003702002000412c6a200241c0156a41286a290200370200200041346a200241c0156a41306a2902003702002000413c6a200241f8156a280200360200200041c0006a200241f0176a41f00110e9081a0c480b2000411c3602000c470b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020002400240024002400240024002400240024020060e06000102030405090b200241c0156a200110e40120022802c0152208450d0820022802c415210a200128020022032802042204450d05200241c8156a2802002109200328020022052d0000210620032004417f6a3602042003200541016a360200024002400240024020060e020201000b200241023a00d8140c090b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241d8116a410f6a2203200241c0156a410f6a290000370000200241d8116a41086a2204200241c0156a41086a29030037030020024198106a410f6a2205200329000037000020024198106a41086a22032004290300370300200241a80e6a41086a22042003290300370300200241a80e6a410f6a22032005290000370000200220022903c0153703a80e200241df156a310000210f20022900d7152110200241f8136a410f6a22052003290000370000200241f8136a41086a2004290300370300200220022903a80e3703f8132005290000210b20022900ff13210c20022d00f813210320022f00f9132104200220022800fb1322053602dc14200220043b01da14200220033a00d914200241013a00d814200541187621040c020b0240200441ff0171450d00200241003a00e0150b200241023a00d8140c080b200241003a00d81420022d00df1421040b2001280200220128020422054104490d0620022d00da14210620022f01d814210e20022800db1421032002200c3700e107200241e9076a200b3700002001280200220d350000210720012005417c6a3602042001200d41046a360200200220103700f107200220043a00e007200c423888200b42088684a7210d200e20064110747222044180feff07714108762105200fa741ff01712101200c421888a7210e200b421888a72122200241f8076a310000210b20022802e007210620022903f007210c410121210c3b0b200110cc042203450d0720024180046a200110ad012002280280040d0620022802840421064200210c41022121410021224200210b42002107410021090c3a0b20024190046a200110ad012002280290040d062002280294042103200110cc042206450d0620024188046a200110ad0102402002280288040d00200228028c04210e4200210c41032121410021224200210b42002107410021090c390b2006108b022006102e0c060b41002104200241003a00e0150240024002400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241cf156a290000210720022900c715210f20022802dc15210620022f01da15210a20022d00d915210920022f00d715210d20022800c315210320022f00c115210520022d00c015210420024198046a200110ad012002280298040d0820012802002201280204220e450d08200228029c042108200128020022222d000021212001200e417f6a3602042001202241016a3602004100210120210e020201080b200441ff0171450d07200241003a00e0150c070b410121010b200220063600ed142002200a3b00eb14200220093a00ea142002200d3b01e814200f422088a7210e2007422088a72122200241f0146a310000210b20022903e814210c200fa721062007a7210d410421210c380b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241d8116a41086a2206200241cf156a290000370300200241d8116a41106a2208200241d7156a290000370300200241d8116a41186a220a200241df156a2d00003a0000200220022900c71522073703e007200220073703d81120022d00c015210420022f00c115210520022800c3152103200241e8096a41186a200a2d00003a0000200241e8096a41106a2008290300370300200241e8096a41086a2006290300370300200220022903d8113703e809200241b8046a200110ad0120022802b8040d0520022802bc042108200241a8046a200110da0420022903a804a70d0520022903b0042107200241a0046a200110ad0120022802a0040d0520022802a404210a20022903e809220f422088a7210e200241f0096a2903002210422088a72122200241800a6a310000210b20022903f809210c200fa721062010a7210d410521210c370b200441ff0171450d04200241003a00e0150c040b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b20022900c7152207422088a7210e200241df156a310000210b20022900d715210c20022800d315212220022800cf15210d20022800c315210320022f00c115210520022d00c01521042007a721064106212141002109420021070c360b200441ff0171450d03200241003a00e0150c030b200241023a00d8140b200a41ffffff3f71450d012008102e0c010b2003108b022003102e0b2000411c3602000c460b200128020022032802042204450d2f200328020022052d0000210620032004417f6a3602042003200541016a3602004102210e02400240024002400240024020060e06003401020304350b200241c0156a200110e40120022802c0152203450d3420022902c415210b200241c0046a2001108202024020022903c004a70d0020022903c8042207423888200241d0046a290300220c42088684a7210d200b422088a72104200c423888a7210a200c421888a72109200ba721054101210e0c330b200b42ffffff3f83500d342003102e0c340b200241d8046a200110ad0120022802d8040d3320022802dc04210320023502801420024184146a33010020024186146a31000042108684422086842107200228008b142109200228008714210d20022802fc1321044103210e4200210b0c310b200128020022032802042204450d32200328020022052d0000210620032004417f6a3602042003200541016a3602004104210e4100210a410021094100210d41002103024020060e03320300330b200241e0046a200110ad0120022802e0040d3220022802e4042105410221030c2f0b200241c0156a200110eb0120022d00c0154105460d31200241e0076a41086a200241d4156a290200370300200241f0076a200241dc156a2902003703002002200241cc156a2902003703e007200241c0156a41086a280200210420022802c415210520022802c01521030240200128020022012802042206450d00200128020022082d0000210a20012006417f6a3602042001200841016a3602004100210802400240200a0e020100020b410121080b20022903e0072207423888200241e8076a290300220b42088684a7210d200b423888a7210a200b421888a72109200241f0076a290300210b4105210e0c310b200341ff01714102470d312004450d312005102e0c310b2001280200220428020422054104490d3020042802002206280000210320042005417c6a3602042004200641046a3602002001280200220128020422044104490d3020012802002206280000210520012004417c6a3602042001200641046a3602004106210e0c2d0b4100210a410021094100210d410121030c2d0b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a3602004107210302400240024002400240024020060e0700010203040531060b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2201200241c0156a410f6a290000370000200241e0076a41086a2203200241c0156a41086a290300370300200241d8116a410f6a22042001290000370000200241d8116a41086a2201200329030037030020024198106a41086a2203200129030037030020024198106a410f6a22012004290000370000200220022903c01537039810200241df156a310000210720022900d715210b200241f8136a410f6a22042001290000370000200241f8136a41086a200329030037030020022002290398103703f813200b422888200742188684a7211b200b421888a72120200b421088a721192004280000210e200228008b14210d20022900ff13210720022800fb13210820022f00f913210a20022d00f8132109200ba72122410121030c310b200441ff0171450d05200241003a00e0150c050b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2201200241c0156a410f6a290000370000200241e0076a41086a2203200241c0156a41086a290300370300200241d8116a410f6a22042001290000370000200241d8116a41086a2201200329030037030020024198106a41086a2203200129030037030020024198106a410f6a22012004290000370000200220022903c01537039810200241df156a310000210720022900d715210b200241f8136a410f6a22042001290000370000200241f8136a41086a200329030037030020022002290398103703f81320022800fb13210820022f00f913210a20022d00f8132109200241d8146a41086a22012004290000370300200220022900ff133703d814200241f0146a20073c00002002200b3703e814200b422888200742188684a7211b200b421888a72120200b421088a721192001290300220c422088a7210d20022903d8142107200ba72122200ca7210e410221030c300b200441ff0171450d04200241003a00e0150c040b41002104200241003a00e015024002400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2203200241c0156a410f6a290000370000200241e0076a41086a2204200241c0156a41086a290300370300200241d8116a410f6a22052003290000370000200241d8116a41086a2203200429030037030020024198106a41086a2204200329030037030020024198106a410f6a22032005290000370000200220022903c01537039810200241df156a310000210720022900d715210b200241f8136a410f6a22052003290000370000200241f8136a41086a200429030037030020022002290398103703f81320022800fb13210820022f00f913210a20022d00f8132109200241e8096a41086a2005290000370300200220022900ff133703e809200241800a6a20073c00002002200b3703f80941002104200241003a00e0150340200128020022032802042205450d02200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2201200241c0156a410f6a290000370000200241e0076a41086a2203200241c0156a41086a290300370300200241d8116a410f6a22042001290000370000200241d8116a41086a2201200329030037030020024198106a41086a2203200129030037030020024198106a410f6a22012004290000370000200220022903c01537039810200241df156a310000210720022900d715210f200241f8136a410f6a22042001290000370000200241f8136a41086a200329030037030020022002290398103703f813200f422888200742188684a7211e2004290000210c20022900ff13210b20022800fb13211c20022f00f913211720022d00f813212320022903f8092210422888200241800a6a31000042188684a7211b200f421888a7211f200f421088a7211d2010421888a721202010421088a72119200241e8096a41086a2903002211422088a7210d20022903e8092107200fa721212010a721222011a7210e410321030c300b200441ff0171450d04200241003a00e0150c040b200441ff0171450d03200241003a00e0150c030b200241d8116a200110e40120022802d8112208450d0220022902dc112107200241cc156a290200210c20022902c415210b20022f01e807212220022d00ea07211920022f00eb07212020022d009c10212320022f009d10211720022f01d415212120022d00d615211d20022f00d715211f20022800d915211e20022d00dd15210520022f01de152104410421034100210d4100210e0c2d0b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2201200241c0156a410f6a290000370000200241e0076a41086a2203200241c0156a41086a290300370300200241d8116a410f6a22042001290000370000200241d8116a41086a2201200329030037030020024198106a41086a2203200129030037030020024198106a410f6a22012004290000370000200220022903c01537039810200241df156a310000210720022900d715210b200241f8136a410f6a22042001290000370000200241f8136a41086a200329030037030020022002290398103703f813200b422888200742188684a7211b200b421888a72120200b421088a721192004280000210e200228008b14210d20022900ff13210720022800fb13210820022f00f913210a20022d00f8132109200ba72122410521030c2d0b200441ff0171450d01200241003a00e0150c010b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2201200241c0156a410f6a290000370000200241e0076a41086a2203200241c0156a41086a290300370300200241d8116a410f6a22042001290000370000200241d8116a41086a2201200329030037030020024198106a41086a2203200129030037030020024198106a410f6a22012004290000370000200220022903c01537039810200241df156a310000210720022900d715210b200241f8136a410f6a22042001290000370000200241f8136a41086a200329030037030020022002290398103703f813200b422888200742188684a7211b200b421888a72120200b421088a721192004280000210e200228008b14210d20022900ff13210720022800fb13210820022f00f913210a20022d00f8132109200ba72122410621030c2c0b200441ff0171450d00200241003a00e0150b2000411c3602000c440b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a3602000240024002400240024020060e03000102050b200241e8046a200110820220022903e804a70d04200241f8046a290300210720022903f004210b200241c0156a200110eb0120022d00c0154105460d0420022903c0152211422088a72101200241d0156a290300210c200241c8156a290300210f200241e0156a2802002103200241d8156a29030021102011a72104410121050c030b20024180056a200110ad0120022802800522010d034104410220011b210520022802840521040c010b20024188056a200110ad0120022802880522010d024104410320011b2105200228028c0521040b0b20004112360200200041386a2007370200200041306a200b3702002000411c6a200c370200200041146a200f3702002000412c6a2003360200200041246a2010370200200041106a20013602002000410c6a2004360200200041086a2005360200200041c0006a200241f0176a41f00110e9081a0c440b2000411c3602000c430b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020002400240024002400240024002400240024020060e050001020304090b41002104200241003a00e015024002400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241df156a310000210b20022900c715210c20022800c315210d20022f00c115210920022d00c015210a20023500cf15210f20022800d315210e20022900d715210741002104200241003a0081162007422888200b42188684a72122200f200ead42208684210b2007421888a721212007421088a721202007a7211f0340200128020022032802042205450d02200328020022062d0000210820032005417f6a3602042003200641016a360200200241c0156a20046a20083a00002002200441016a22033a00811620032104200341c100470d000b2002200c3703d814200220223600ed14200220213b00eb14200220203a00ea142002201f3b01e8142002200b3703e014200e4110762101200e4108762120200241ef156a290000211020022900e715210f20022f00ff15211f20022800fb15211e20022800f715211d20022800e315210320022f00e115210420022d00e015210520022802dc15210620022f01da15210820022d00d915210e20022f00d715212220022900cf15210720022800cb15211c20022800c715212120023502c01520023301c41520023100c6154210868442208684420886200241f0146a31000084211120022903e8142115410121230c060b200441ff0171450d09200241003a00e0150c090b200441ff0171450d08200241003a0081160c080b41002104200241003a00d4150240024002400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00d4152003210420034114470d000b200220022802d0153602f007200220022903c8153702e807200220022802c4153602e407200220022802c015220a3602e0072001280200220328020422044110490d0a2003280200220541086a2900002111200529000021152003200541106a3602002003200441706a360204200128020022032802042204450d0a200328020022052d0000210920032004417f6a3602042003200541016a3602004100212120090e0202010a0b200441ff0171450d09200241003a00d4150c090b2001280200220328020422044110490d082003280200220541086a290000210b200529000021072003200541106a3602002003200441706a3602042001280200220328020422044110490d082003280200220541086a290000210f2005290000210c2003200541106a3602002003200441706a36020420012802002203280204220441034d0d0820032802002205280000210620032004417c6a3602042003200541046a3602002002200c3703d0152002200b3703c815200220063602e01520022802d415210320022f01d215210420022d00d115210520022f00cb15210820022800cd15210620022d00ca15210e20022f01c815212220022903e0152110410121210b20012802002209280204220d450d07200928020022202d0000211f2009200d417f6a3602042009202041016a360200410221234102212002400240201f0e020100090b200128020022012802042209450d082001280200220d2d0000211f20012009417f6a3602042001200d41016a360200410021200240201f0e020100090b410121200b200a410876210920023500ef07200241f3076a31000042208684210b20022900e707210c20022800e307210d4100211c0c030b41002104200241003a00e01502400240024002400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241800a6a200241df156a3100003c0000200220022900d7153703f809200220022900cf153703f009200220022900c7153703e80920022800c315210d20022f00c115210920022d00c015210a41002104200241003a0081160340200128020022032802042205450d02200328020022062d0000210820032005417f6a3602042003200641016a360200200241c0156a20046a20083a00002002200441016a22033a00811620032104200341c100470d000b200241ef156a290000211020022900e715210f20022f00ff15211f20022800fb15211e20022800f715211d20022800e315210320022f00e115210420022d00e015210520022802dc15210620022f01da15210820022d00d915210e20022f00d715212220022900cf15210720022800cb15211c20022800c715212120023502c015210b20023301c415210c20023100c615211120024190056a200110ad012002280290050d0a20012802002223280204221b2002280294052220490d0a2020417f4c0d4420200d02410121170c030b200441ff0171450d09200241003a00e0150c090b200441ff0171450d08200241003a0081160c080b202010322217450d4620012802002223280204211b0b201b2020490d0420172023280200202010e90821012023280204221b2020490d142023201b20206b3602042023202328020020206a3602002001450d06200b200c20114210868442208684420886200241800a6a3100008421112020ad220b422086200b842214422088a72118200241f0096a290300220b423088a72101200b422888a7212020022903f809211520022903e809210c2014a72119410321230c020b20024198056a200110ad012002280298050d05200128020022042802042205200228029c052203490d052003417f4c0d3f0240024020030d004101210d0c010b20031032220d450d452001280200220428020421050b20052003490d04200d2004280200200310e9082101200428020422052003490d122004200520036b3602042004200428020020036a3602002001450d052003ad2207422086200784210c410421230c010b41002104200241003a00d41502400240024002400240024002400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00d4152003210420034114470d000b20022802d015210d20022903c815210720022802c015210a20022802c415210841002104200241003a00d4152008411876210e200a411876211f200a41087621090340200128020022032802042205450d02200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00d4152003210420034114470d000b200128020022032802042204450d0220022802c415212220022802c015212020022802d015212120022903c815210b200328020022052d0000210620032004417f6a3602042003200541016a36020020060e020405030b200441ff0171450d0a200241003a00d4150c0a0b200441ff0171450d09200241003a00d4150c090b200241023a00e8090c080b200241023a00e8090c070b200241003a00e8090c010b41002104200241003a00e0150340200128020022032802042205450d03200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241d8116a410f6a2201200241c0156a410f6a290000370000200241d8116a41086a2203200241c0156a41086a290300370300200241a80e6a410f6a22042001290000370000200241a80e6a41086a22012003290300370300200241d8146a41086a22032001290300370300200241d8146a410f6a22012004290000370000200220022903c0153703d814200241df156a310000210f20022900d7152114200241f8136a410f6a22042001290000370000200241f8136a41086a2003290300370300200220022903d8143703f8132004290000211020022900ff13210c20022d00f813210120022f00f9132103200220022800fb133602ec09200220033b01ea09200220013a00e909200241013a00e8090b202041087621012002200c3700e107200241e9076a2010370000200241dc0a6a2021410874ad200b423888843e0200200220022d00ef093a00e0072002200b4208862022411876ad843702d40a200220224108742020411876723602d00a2014423888200f42ff018342088684210f202141187620022f01e80920022d00ea0941107472410874722121200dad42088620074238888442ffffffffff1f83210b200c423888201042088684a721222007420886200ead84210c2008410874201f72210d2014421888a721032014420888a721042010422088a721062010421088a721082010420888a7210e20022800eb09211c200241d00a6a41086a2903002111200228029810211d200228029c10211e20022f01a010211f20022f01a210211b20022802a410211720022802a810211920022802ac10211820022903e007210720022903d00a21152014a7210542002110410521230b200020053a00492000200e3a0042200020013b011e200020203a001d200020093b000a2000200a3a0009200041133602002000411c6a200b4220883c0000200041186a200b3e0000200041d8006a2010370200200041d0006a200f370200200041286a2011370200200041206a2015370200200041f4006a2018360200200041f0006a2019360200200041ec006a2017360200200041ea006a201b3b0100200041e8006a201f3b0100200041e4006a201e360200200041e0006a201d360200200041cc006a2003360200200041ca006a20043b0100200041c5006a2006360000200041c3006a20083b0000200041c0006a20223b0100200041386a2007370200200041346a201c360200200041306a2021360200200041106a200c3700002000410c6a200d360000200041086a20233a0000200041f8006a200241f0176a41b80110e9081a0c460b0240200441ff0171450d00200241003a00e0150b200241023a00e8090c020b2017102e0c010b200d102e0b2000411c3602000c420b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602044101210a2003200541016a360200024002400240024002400240024020060e0403000102070b200241c0156a200110eb0120022d00c0154105460d0620022903c015220b422088a72103200241d0156a290300210f200241c8156a2903002107200241e0156a2802002105200241d8156a290300210c200ba721044102210a0c020b200241c0156a200110eb0120022d00c01522044105460d05200241d8116a41086a200241d4156a290200370300200241d8116a41106a200241dc156a2802003602002002200241cc156a2902003703d811200241c0156a41086a280200210a20022802c415210302402001280200220628020422084110490d0020022d00c315210d20022f00c115210e200241e0156a28020021052006280200220941086a290000210b200929000021102006200941106a3602002006200841706a3602042001280200220628020422084110490d002006280200220941086a2900002111200929000021152006200941106a3602002006200841706a3602042001280200220128020422064104490d0020012802002209280000210820012006417c6a3602042001200941046a360200200241ec076a200241d8116a41086a290300370200200241f4076a200241d8116a41106a2802003602002002200a3602e007200220022903d8113702e407200e200d411074724108742004722104200241e0076a41086a290300210f20022903e007210720022903f007210c420021124103210a420021250c020b20044102470d05200a0d040c050b200241c0156a200110eb0120022d00c0154105460d04200241c0156a41106a2208290300210f200241e0156a220a2802002105200241d8156a2209290300210c200241c8156a2206290300210720022802c415210320022802c0152104200241c0156a200110eb0120022d00c0154105460d022006290300210b20022802c415210e20022802c015210d2001280200220628020422224110490d0120082903002115200a2802002108200929030021112006280200220a41086a2900002114200a29000021102006200a41106a3602002006202241706a36020420012802002206280204220a4110490d012006280200220941086a2900002113200929000021282006200941106a3602002006200a41706a3602044104210a2001280200220128020422064104490d0120012802002209280000212220012006417c6a3602042001200941046a360200200220223602d0152014422086201042208884212520104220862112200ead422086200dad842110200220283703c01520022802c415210d20022903d01521262028a721090b20004114360200200041f8006a2026370200200041f0006a2013370200200041dc006a20253e0200200041d4006a2012370200200041c0006a2015370200200041386a200b3702002000411c6a200f370200200041146a2007370200200041ec006a200d360200200041e8006a2009360200200041e0006a2014370200200041d0006a2008360200200041c8006a2011370200200041306a20103702002000412c6a2005360200200041246a200c370200200041086a200a3602002000410c6a2003ad4220862004ad8437020020004180016a200241f0176a41b00110e9081a0c450b200d41ff01714102470d00200ba7450d00200e102e0b200441ff01714102470d012007a7450d010b2003102e0b2000411c3602000c410b200241c0156a200110cd06024020022f01c0154104460d00200241e0076a41086a200241c0156a41086a2903002207370300200220022903c015220b3703e007200041153602002000200b3702042000410c6a2007370200200041146a200241f0176a419c0210e9081a0c410b2000411c3602000c400b200128020022032802042204450d24200328020022052d0000210620032004417f6a3602042003200541016a3602004104210a0240024020060e0f00012425232221201f1e1d1c1b1a19260b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241900d6a41086a200241e8096a41086a2800003602002002418c0d6a41026a20024198136a41026a2d00003a0000200241c80d6a41106a200241e0076a41106a290000370300200241c80d6a41086a200241e0076a41086a290000370300200220022900e8093703900d200220022f0098133b018c0d200220022900e0073703c80d200241df156a310000210c20022900d715210b20022900c715210720022800c315210820022f00c115212a20022d00c015212c20023500cf15210f20023500d3152110200241880d6a41026a200241e80f6a41026a2d00003a0000200220022f00e80f3b01880d200241a00d6a41106a200241d8116a41106a290000370300200241a00d6a41086a200241d8116a41086a290000370300200220022900d8113703a00d200241840d6a41026a200241f80d6a41026a2d00003a0000200220022f00f80d3b01840d200241e80c6a41106a20024198106a41106a290000370300200241e80c6a41086a20024198106a41086a29000037030020022002290098103703e80c200241e40c6a41026a200241f8136a41026a2d00003a0000200220022f00f8133b01e40c200241c80c6a41106a200241a80e6a41106a290000370300200241c80c6a41086a200241a80e6a41086a290000370300200220022900a80e3703c80c200241d8146a41206a200241f0176a41206a280000360200200241d8146a41186a200241f0176a41186a290000370300200241d8146a41106a200241f0176a41106a290000370300200241d8146a41086a200241f0176a41086a290000370300200220022900f0173703d814201042208622104280808080806083200f20104280808080f01f838484210f4101210a0c250b200441ff0171450d25200241003a00e0150c250b200241a0056a200110ad0120022802a0050d2420022802a4052205200128020028020441c8006e2203200320054b1bad42c8007e2207422088a70d362007a72203417f4c0d360240024020030d00410421080c010b2003102c2208450d3c0b2001200128020441016a2204360204200341c8006ead210702400240024002400240024002400240024002400240200420012802084b0d00024002402005450d00200241c0156a410c6a211f200241c0156a410172211c0340200241c0156a200110ed0302400240024020022d00c01522044106460d00200241f8136a41026a220a201c41026a2d00003a0000200241e8096a41086a2209201f41086a290200370300200241e8096a41106a220d201f41106a2902003703002002201c2f00003b01f8132002201f2902003703e80920022802c415210620022802c8152103200241f0176a200110ed0320022d00f0174106470d0120044101470d002003450d002006102e0b410621040c010b200241b4146a41026a200a2d00003a000020024198136a41086a200929030037030020024198136a41106a200d290300370300200241e0076a41086a200241f0176a41086a290300370300200241e0076a41106a200241f0176a41106a290300370300200241e0076a41186a200241f0176a41186a290300370300200241e0076a41206a200241f0176a41206a280200360200200220022f01f8133b01b414200220022903e80937039813200220022903f0173703e0072003211e2006211d0b200241b0146a41026a2203200241b4146a41026a2d00003a0000200241e80f6a41086a220620024198136a41086a290300370300200241e80f6a41106a220a20024198136a41106a290300370300200241d8116a41086a2209200241e0076a41086a290300370300200241d8116a41106a220d200241e0076a41106a290300370300200241d8116a41186a220e200241e0076a41186a290300370300200241d8116a41206a2222200241e0076a41206a280200360200200220022f01b4143b01b01420022002290398133703e80f200220022903e0073703d81120044106460d03200241ac146a41026a222120032d00003a0000200241f80d6a41086a22202006290300370300200241f80d6a41106a2206200a29030037030020024198106a41086a220a200929030037030020024198106a41106a2209200d29030037030020024198106a41186a220d200e29030037030020024198106a41206a220e2022280200360200200220022f01b0143b01ac14200220022903e80f3703f80d200220022903d8113703981002402007422088220ba722032007a7470d00200341016a22222003490d4520034101742217202220222017491b22224104202241044b1bad42c8007e220b422088a7454102742122200ba721170240024020030d00200241003602f0170c010b200241043602f817200220083602f0172002200341c8006c3602f4170b200241c0156a20172022200241f0176a107d20022802c815212220022802c0154101460d0320022802c41521082007422088220ba72103202241c8006ead21070b2008200341c8006c6a220320043a0000200341086a201e360000200341046a201d360000200341036a20212d00003a0000200320022f01ac143b00012003410c6a20022903f80d370000200341146a20202903003700002003411c6a2006290300370000200341346a20092903003700002003412c6a200a2903003700002003413c6a200d290300370000200341246a200229039810370000200341c4006a200e280200360000200b422086200742ffffffff0f83844280808080107c21072005417f6a22050d000b200128020421040b20012004417f6a3602042008450d30200241f0176a200110ed0320022d00f0174106460d0a20024180186a310000210c20024190186a220a350200210f20024188186a2209290300211420024184186a220d280200210320024182186a2f0100210420024181186a2d00002105200241f0176a41086a220e290300210b20022802f417212a20022802f0172106200241f0176a200110ed0320022d00f0174106460d09200241e8096a41086a200a280200360200200220092903003703e809200d280200210d200241fc176a220a2902002110200e280200212d20022802f417212e20022802f017212c200241f0176a200110ed0320022d00f01722094106460d08200241f8136a41026a20022d00f3173a000020024198106a41086a20024184186a222029020037030020024198106a41106a2002418c186a221f290200370300200220022f00f1173b01f8132002200a29020037039810200241f0176a41086a220a280200210e20022802f4172122200241f0176a200110ed0320022d00f01722214106460d07200241f80d6a41026a20022d00f3173a0000200241d8116a41086a2020290200370300200241d8116a41106a201f290200370300200220022f00f1173b01f80d2002200241fc176a221d2902003703d811200a280200212020022802f417211f200241f0176a200110ed0320022d00f017221e4106460d06200241ea0f6a20022d00f3173a0000200241e0076a41086a20024184186a290200370300200241f0076a2002418c186a290200370300200220022f00f1173b01e80f2002201d2902003703e007200241f0176a41086a280200211d20022802f417211c2001280200220a2802042217450d05200a28020022232d00002118200a2017417f6a360204200a202341016a3602004100212f420021114100212320180e020302050b20220d460c410b02402007422088a72201450d002008200141c8006c6a2103200821010340024020012d00004101470d00200141086a280200450d00200141046a280200102e0b0240200141246a2d00004101470d002001412c6a280200450d00200141286a280200102e0b200141c8006a22012003470d000b0b2007a72201450d2e200141c8006c450d2e2008102e0c2e0b41002117200241003a00841803402001280200220a2802042223450d02200241f0176a20176a200a280200221b2d00003a0000200a2023417f6a360204200a201b41016a3602002002201741016a220a3a008418200a2117200a4114470d000b20022802f417220a41087420022802f0172217411876722119200a41187621302017410876211b200228028018212f20022903f8172111410121230b200241f0176a200110ed0320022d00f01722184106460d014102210a20024198136a41026a222420022d00f3173a0000200241c0156a41086a222720024184186a290200370300200241c0156a41106a22312002418c186a290200370300200220022f00f1173b0198132002200241fc176a2902003703c015200241f0176a41086a2232280200211a20022802f4172116200241f0176a200110ed0320022d00f0174106470d0720184101470d01201a450d012016102e0c010b201741ff0171450d00200241003a0084180b201e4101470d00201d450d00201c102e0b20214101470d002020450d00201f102e0b20094101470d00200e450d002022102e0b202c41ff01714101470d00202d450d00202e102e0b200641ff01714101470d00200ba7450d00202a102e0b02402007422088a72201450d002008200141c8006c6a2103200821010340024020012d00004101470d00200141086a280200450d00200141046a280200102e0b0240200141246a2d00004101470d002001412c6a280200450d00200141286a280200102e0b200141c8006a22012003470d000b0b2007a72201450d25200141c8006c450d252008102e0c250b200241a80e6a41206a2201200241f0176a41206a280200360200200241a80e6a41186a2233200241f0176a41186a290300370300200241a80e6a41106a2234200241f0176a41106a290300370300200241a80e6a41086a22352032290300370300200241900d6a41086a200241e8096a41086a2802003602002002418c0d6a41026a200241f8136a41026a2d00003a0000200220022903f0173703a80e200220022903e8093703900d200220022f01f8133b018c0d200241c80d6a41106a20024198106a41106a290300370300200241c80d6a41086a20024198106a41086a29030037030020022002290398103703c80d200241880d6a41026a200241f80d6a41026a2d00003a0000200220022f01f80d3b01880d200241a00d6a41106a200241d8116a41106a290300370300200241a00d6a41086a200241d8116a41086a290300370300200220022903d8113703a00d200241840d6a41026a200241e80f6a41026a2d00003a0000200220022f01e80f3b01840d200241e80c6a41106a200241e0076a41106a290300370300200241e80c6a41086a200241e0076a41086a290300370300200220022903e0073703e80c200241e40c6a41026a20242d00003a0000200220022f0198133b01e40c200241c80c6a41106a2031290300370300200241c80c6a41086a2027290300370300200220022903c0153703c80c200241d8146a41206a2001280200360200200241d8146a41186a2033290300370300200241d8146a41106a2034290300370300200241d8146a41086a2035290300370300200220022903a80e3703d81420114208862030ad42ff0183842113202fad42088620114238888442ffffffffff1f832112202dad422086202ead842111202cad422086200f842115202aad4220862006ad84210f0c230b2004200641b8b2c0001056000b2004200641b8b2c0001056000b2004200641b8b2c0001056000b2004200841b8b2c0001056000b2004200641b8b2c0001056000b2003200641b8b2c0001056000b2003200841b8b2c0001056000b2003200641b8b2c0001056000b2003200641b8b2c0001056000b2003200541b8b2c0001056000b2020201b41b8b2c0001056000b2004200641b8b2c0001056000b2003200d41b8b2c0001056000b2006203241b8b2c0001056000b2004200841b8b2c0001056000b2003200a41b8b2c0001056000b2003200641b8b2c0001056000b2000411c3602000c2d0b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020020060d00200241d8116a200110950620022802d811450d0020024198106a200241d8116a41c00110e9081a200241003a00881202402001280200220328020422044110490d002003280200220541086a29000021072005290000210b2003200541106a3602002003200441706a360204200241013a0088122002200b3703d811200220073703e0110240200128020022032802042204410f4d0d002003280200220541086a29000021072005290000210b2003200541106a3602002003200441706a360204200241d8116a41186a22042007370300200241023a0088122002200b3703e8112001280200220328020422054110490d002003280200220641086a29000021072006290000210b2003200641106a360200200241d8116a41286a20073703002003200541706a360204200241033a0088122002200b3703f811200241d00a6a41086a200241d8116a41086a290300220c370300200241d00a6a41106a200241d8116a41106a290300220f370300200241d00a6a41186a20042903002210370300200241d00a6a41206a200b370300200241d00a6a41286a2007370300200220022903d81122113703d00a200241e8096a41286a22032007370300200241e8096a41206a2204200b370300200241e8096a41186a22052010370300200241e8096a41106a2206200f370300200241e8096a41086a2208200c370300200220113703e80920024198136a41286a220a200329030037030020024198136a41206a2209200429030037030020024198136a41186a200529030037030020024198136a41106a200629030037030020024198136a41086a22042008290300370300200220022903e809370398132001280200220328020422054104490d0120032802002206280000210820032005417c6a3602042003200641046a3602002002280298102103200241a80e6a20024198106a41047241bc0110e9081a200241e80f6a41286a200a290300370300200241e80f6a41206a2009290300370300200241e80f6a41186a220520024198136a41186a290300370300200241e80f6a41106a220620024198136a41106a290300370300200241e80f6a41086a200429030037030020022002290398133703e80f2003450d02200241f0176a41286a200241e80f6a41286a290300370300200241f0176a41206a200241e80f6a41206a290300370300200241f0176a41186a2005290300370300200241f0176a41106a2006290300370300200241f0176a41086a200241e80f6a41086a290300370300200220022903e80f3703f017200220033602a018200241a4186a200241a80e6a41bc0110e9082104200220083602e019200241d8076a200110ad010240024020022802d8070d0020022802dc072105200241d0076a200110ad0120022802d007450d010b200241a0186a109b060c030b20022802d4072101200241f80d6a41286a2206200241f0176a41286a290300370300200241f80d6a41206a2208200241f0176a41206a290300370300200241f80d6a41186a220a200241f0176a41186a290300370300200241f80d6a41106a2209200241f0176a41106a290300370300200241f80d6a41086a220d200241f0176a41086a290300370300200220022903f0173703f80d200241c0156a200441c40110e9081a200241c80d6a41086a2204200d290300370300200241c80d6a41106a220d2009290300370300200241c80d6a41186a2209200a290300370300200241c80d6a41206a220a2008290300370300200241c80d6a41286a22082006290300370300200220022903f80d3703c80d200241e0076a200241c0156a41c40110e9081a200241d8146a412c6a2008290300370200200241d8146a41246a200a290300370200200241d8146a411c6a2009290300370200200241d8146a41146a200d290300370200200241d8146a410c6a2004290300370200200220022903c80d3702dc142000411b360200200020022902d8143702042000410c6a200241d8146a41086a290200370200200041146a200241d8146a41106a2902003702002000411c6a200241d8146a41186a290200370200200041246a200241d8146a41206a2902003702002000412c6a200241d8146a41286a290200370200200041346a20024188156a280200360200200041386a20033602002000413c6a200241e0076a41c40110e9081a20004184026a200136020020004180026a200536020020004188026a20022903a00d37030020004190026a200241a00d6a41086a29030037030020004198026a200241a00d6a41106a290300370300200041a0026a200241a00d6a41186a290300370300200041a8026a200241a00d6a41206a2903003703000c2f0b200241003a0088120b20024198106a109b060b2000411c3602000c2c0b0240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020002400240024002400240024002400240024002400240024020060e060001020304050c0b20024190076a200110ad012002280290070d0b2001280200220528020422062002280294072204490d0b2004417f4c0d2e0240024020040d00410121030c010b200410322203450d342001280200220528020421060b20062004490d0a20032005280200200410e9082106200528020422082004490d082005200820046b3602042005200528020020046a3602002006450d0b41002105200241003a00e0152004ad22074220862007842207422088a7210d2007a7210902400340200128020022042802042206450d01200241c0156a20056a200428020022082d00003a000020042006417f6a3602042004200841016a3602002002200541016a22043a00e0152004210520044120470d000b200241e0076a410f6a2201200241c0156a410f6a290000370000200241e0076a41086a2204200241c0156a41086a290300370300200241d8116a410f6a22052001290000370000200241d8116a41086a22012004290300370300200241d8146a41086a22042001290300370300200241d8146a410f6a22012005290000370000200220022903c0153703d814200241df156a310000210c20022900d715210b200241f8136a410f6a22052001290000370000200241f8136a41086a2004290300370300200220022903d8143703f81320052800002108200228008b14210a20022900ff13210720022800fb13210420022f00f913210520022d00f8132106200242003703a0102002200d36029c102002200936029810200b422888200c42188684a72109200b421888a7210d200b421088a7210e200ba72122410121210c070b0240200541ff0171450d00200241003a00e0150b2009450d0b0c0a0b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b20024198106a41086a200241e0076a41086a29000037030020024198106a41106a200241e0076a41106a290000370300200220022900e00737039810200241cf156a290000220b422088a7210a20022900c715210720022802dc15210920022f01da15210d20022d00d915210e20022f00d715212220022800c315210420022f00c115210520022d00c0152106200ba72108410221210c050b200441ff0171450d0a200241003a00e0150c0a0b200241b0076a200110ad0120022802b0070d0920012802002205280204220620022802b4072204490d092004417f4c0d2c0240024020040d00410121030c010b200410322203450d322001280200220528020421060b20062004490d0820032005280200200410e9082106200528020422082004490d072005200820046b3602042005200528020020046a3602002006450d092004ad2207422086200784210b41002105200241003a00e015024002400340200128020022042802042206450d01200241c0156a20056a200428020022082d00003a000020042006417f6a3602042004200841016a3602002002200541016a22043a00e0152004210520044120470d000b200241e0076a410f6a2204200241c0156a410f6a290000370000200241e0076a41086a2205200241c0156a41086a290300370300200241d8116a410f6a22062004290000370000200241d8116a41086a22042005290300370300200241d00a6a41086a22052004290300370300200241d00a6a410f6a22042006290000370000200220022903c0153703d00a200241df156a310000210f20022900d715210c200241f8136a410f6a22062004290000370000200241f8136a41086a2005290300370300200220022903d00a3703f81320062800002108200228008b14210a20022900ff13210720022800fb13210420022f00f913210520022d00f813210620024198076a2001108202200229039807a70d01200c422888200f42188684a72109200c421888a7210d200c421088a7210e200ca7212220022903a007210c20024198106a41106a20024198076a41106a2903003703002002200b370398102002200c3703a010410321210c060b200541ff0171450d00200241003a00e0150b200ba70d080c090b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241d8116a41086a2203200241cf156a290000370300200241d8116a41106a2208200241d7156a290000370300200241d8116a41186a220a200241df156a2d00003a0000200220022900c71522073703e007200220073703d81120022d00c015210620022f00c115210520022800c3152104200241e8096a41186a2209200a2d00003a0000200241e8096a41106a2008290300370300200241e8096a41086a22082003290300370300200220022903d8113703e809200241b8076a200110820220022903b807a70d09200241b8076a41106a2903002107200220022903c00737039810200220073703a01020022903f809220b422888200931000042188684a72109200b421888a7210d200b421088a7210e2008290300220c422088a7210a20022903e8092107200ba72122200ca72108410421210c030b200441ff0171450d08200241003a00e0150c080b41002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b20024198106a41086a200241e0076a41086a29000037030020024198106a41106a200241e0076a41106a290000370300200220022900e0073703981020022900d715220b422888200241df156a31000042188684a72109200b421888a7210d200b421088a7210e20022800d315210a20022800cf15210820022900c715210720022800c315210420022f00c115210520022d00c0152106200ba72122410521210c020b200441ff0171450d07200241003a00e0150c070b41002104200241003a00e0150340200128020022032802042205450d03200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b20024198106a41086a200241e0076a41086a29000037030020024198106a41106a200241e0076a41106a290000370300200220022900e0073703981020022900d715220b422888200241df156a31000042188684a72109200b421888a7210d200b421088a7210e200241cf156a290000220c422088a7210a20022900c715210720022800c315210420022f00c115210520022d00c0152106200ba72122200ca72108410621210b0b200241a80e6a41106a220120024198106a41106a290300370300200241a80e6a41086a20024198106a41086a290300220b3703002002200229039810220c3703a80e200041186a200aad4220862008ad84370000200041106a20073700002000412c6a2003360000200020093600252000200d3b00232000200e3a0022200041206a20223b00002000410c6a2004360000200020053b000a200020063a0009200041086a20213a00002000411a360200200041306a200c370200200041386a200b370200200041c0006a2001290300370200200041c8006a200241f0176a41e80110e9081a0c300b200441ff0171450d03200241003a00e0150c030b2004200841b8b2c0001056000b2004200841b8b2c0001056000b2003102e0b2000411c3602000c2b0b02400240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a360200024002400240024002400240024002400240024002400240024020060e090001020304050608070d0b20024198066a2001108202200229039806a70d0c200241a8066a290300210b20022903a006210720024190066a200110ad012002280290060d0c2001280200220528020422062002280294062204490d0c2004417f4c0d2f0240024020040d00410121030c010b200410322203450d352001280200220528020421060b20062004490d0b20032005280200200410e9082101200528020422062004490d0d2005200620046b3602042005200528020020046a3602002001450d0c2004ad220c422086200c84220c422088210f200ca72104410121010c090b200241b0066a200110ad0120022802b00622010d0b410a410220011b21014200210f20022802b40621030c070b200241d0066a200110ad0120022802d0060d0a20022802d4062103200241c0156a200110eb0120022d00c0154105460d0a200241c0156a41106a290300210b200241c8156a2903002107200241e0156a2802002105200241d8156a290300210c20022802c415210620022802c0152104200241b8066a2001108202024020022903b806a70d00200241b8066a41106a290300211120022903c00621102006ad210f410321010c090b200441ff01714102470d0a2007a7450d0a2006102e0c0a0b200241d8066a200110ad0120022802d80622010d09410a410420011b21014200210f20022802dc0621030c050b200241e0066a200110ad0120022802e00622010d08410a410520011b21014200210f20022802e40621030c040b200241e8066a200110ad0120022802e8060d0720022802ec062103200241c0156a200110eb0120022d00c0154105460d0720022903c0152210422088210f200241d0156a290300210b200241c8156a2903002107200241e0156a2802002105200241d8156a290300210c2010a721044200211041062101420021110c050b200241f0066a200110ad0120022802f00622010d06410a410720011b21014200210f20022802f40621030c020b20024188076a200110ad012002280288070d05200228028c07210320024180076a200110ad012002280280070d052001280200220628020422082002280284072205490d052005417f4c0d280240024020050d00410121040c010b200510322204450d2e2001280200220628020421080b0240024020082005490d0020042006280200200510e90821012006280204220820054f0d012005200841b8b2c0001056000b2004102e0c060b2006200820056b3602042006200628020020056a3602002001450d052005ad2207422086200784220f42208821074200210b410921010c020b200241f8066a200110ad0120022802f80622010d04410a410820011b21014200210f20022802fc0621030b0b0b20004119360200200041c0006a2011370200200041386a2010370200200041206a200b370200200041186a2007370200200041306a2005360200200041286a200c3702002000410c6a2003360200200041086a2001360200200041106a200f4220862004ad84370200200041c8006a200241f0176a41e80110e9081a0c2d0b2003102e0b2000411c3602000c2b0b2004200641b8b2c0001056000b024002400240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a3602000240024002400240024002400240024020060e0400010203080b200241d8116a200110e40120022802d8112203450d0720022902dc11210b0240200110cc042204450d0020022902d815220c42808080807083210f20022902d0152207428080808070832110200241ec076a310000211120022902e407211520022802cc15210e20022802c8152109200228009b10210820022f009910210a2007a7210d410121010c0a0b200b42ffffff3f8350450d060c070b2001280200220328020422044102490d06200328020022062f0000210520032004417e6a3602042003200641026a360200200241c0156a200110e40120022802c0152203450d0620022902c415210b200241c0156a200110fd0520022802c01522044102460d04200241c8156a280200210a20022802c415210620024188066a200110ad012002280288060d0420012802002209280204220d200228028c062208490d042008417f4c0d290240024020080d004101210e0c010b20081032220e450d2f20012802002209280204210d0b200d2008490d03200e2009280200200810e908210d200928020422222008490d072009202220086b3602042009200928020020086a360200200d450d042008ad2207422086200784210c200128020022082802042209450d02200828020022222d0000212120082009417f6a3602042008202241016a360200410021220240024020210e020100040b410121220b2001280200220128020422094108490d02200c422088a721082001280200220e29000021072001200941786a3602042001200e41086a360200200c422086200dad84220f4220882111200f422086200aad842115200c421088a7210a200c420888a72121410221014100210d4200210c4200210f420021100c080b2001280200220328020422044102490d05200328020022052f0000210a20032004417e6a3602042003200541026a360200200241c0156a200110e40120022802c0152208450d0520022902c4152107200241c0156a200110fd05024020022802c0154102460d00200241c8156a280200210d20022903c015211041002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b2001280200220128020422094108490d01200241df156a310000211120022900d715211520022900c715210b20022800c315210320022f00c115210520022d00c0152122200241cf156a290000220c422088a72106200ca721042001280200220e290000210c2001200941786a3602042001200e41086a360200200c42808080807083210f2010422088a7210e2010a7210941032101420021100c090b200441ff0171450d00200241003a00e0150b200742ffffff3f83500d052008102e0c050b2001280200220328020422044102490d04200328020022052f0000210a20032004417e6a3602042003200541026a360200200241c0156a200110e40120022802c0152208450d0420022902c415210702402001280200220328020422044104490d0020032802002205280000210920032004417c6a3602042003200541046a3602002001280200220328020422044104490d0020032802002205280000210e20032004417c6a3602042003200541046a36020041002104200241003a00e01502400340200128020022032802042205450d01200241c0156a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00e0152003210420034120470d000b200241e0076a410f6a2201200241c0156a410f6a290000370000200241e0076a41086a2203200241c0156a41086a290300370300200241d8116a410f6a22042001290000370000200241d8116a41086a2201200329030037030020024198106a41086a2203200129030037030020024198106a410f6a22012004290000370000200220022903c01537039810200241df156a310000211120022900d7152115200241f8136a410f6a22042001290000370000200241f8136a41086a200329030037030020022002290398103703f81320042800002104200228008b14210620022900ff13210b20022800fb13210320022f00f913210520022d00f8132122410421014100210d4200210c4200210f420021100c080b200441ff0171450d00200241003a00e0150b200742ffffff3f83500d042008102e0c040b200ca7450d010b200e102e0b200b42ffffff3f83500d010b2003102e0b2000411c3602000c2b0b2008202241b8b2c0001056000b200020213a0029200020223a000920004118360200200041286a20113c0000200041206a20153702002000413c6a200e360200200041386a2009360200200041306a20073702002000412c6a20083602002000412a6a200a3b01002000411c6a2006360200200041186a2004360200200041106a200b3702002000410c6a20033602002000410a6a20053b0100200041086a20013a0000200041c8006a200f200c42ffffffff0f8384370200200041c0006a2010200dad84370200200041d0006a200241f0176a41e00110e9081a0c290b200241c0156a200110bc03024020022d00c015410b460d00200241e0076a200241c0156a41c80010e9081a20004117360200200041046a200241e0076a41c80010e9081a200041cc006a200241f0176a41e40110e9081a0c290b2000411c3602000c280b410f210a0c0b0b200241f0176a200110eb0120022d00f0174105460d0b200241900d6a41086a200241e8096a41086a2802003602002002418c0d6a41026a20024198136a41026a2d00003a0000200241c80d6a41086a200241e0076a41086a290200370300200241c80d6a41106a200241e0076a41106a290200370300200220022902e8093703900d200220022f0098133b018c0d200220022902e0073703c80d2002418c186a310000210c20024184186a290200210b200241fc176a290200210f200241f0176a41206a28020021032002418e186a2f010021042002418d186a2d0000210520022902f417210720022802f0172108200241880d6a41026a200241e80f6a41026a2d00003a0000200220022f00e80f3b01880d200241a00d6a41106a200241d8116a41106a290200370300200241a00d6a41086a200241d8116a41086a290200370300200220022902d8113703a00d200241840d6a41026a200241f80d6a41026a2d00003a0000200220022f00f80d3b01840d200241e80c6a41106a20024198106a41106a290200370300200241e80c6a41086a20024198106a41086a29020037030020022002290298103703e80c200241e40c6a41026a200241f8136a41026a2d00003a0000200220022f00f8133b01e40c200241c80c6a41106a200241a80e6a41106a290200370300200241c80c6a41086a200241a80e6a41086a290200370300200220022902a80e3703c80c200241d8146a41206a200241c0156a41206a280200360200200241d8146a41186a200241c0156a41186a290200370300200241d8146a41106a200241c0156a41106a290200370300200241d8146a41086a200241c0156a41086a290200370300200220022902c0153703d814410e210a0c0a0b200241f0176a200110eb0120022d00f0174105460d0a2002418c186a310000210c20024184186a290200210b200241f0176a41206a220928020021032002418e186a2f010021042002418d186a2d00002105200241fc176a290200210f200241f0176a41086a220e280200210620022802f417210a20022802f0172108200241f0176a200110ed03024020022d00f0174106460d00200241900d6a41086a200241e8096a41086a2802003602002002418c0d6a41026a20024198136a41026a2d00003a0000200241c80d6a41086a200241e0076a41086a290200370300200241c80d6a41106a200241e0076a41106a290200370300200220022902e8093703900d200220022f0098133b018c0d200220022902e0073703c80d200241f0176a41186a2903002110200241f0176a41106a29030021112009280200210d200e290300211520022903f0172114200241880d6a41026a200241e80f6a41026a2d00003a0000200220022f00e80f3b01880d200241a00d6a41106a200241d8116a41106a290200370300200241a00d6a41086a200241d8116a41086a290200370300200220022902d8113703a00d200241840d6a41026a200241f80d6a41026a2d00003a0000200220022f00f80d3b01840d200241e80c6a41106a20024198106a41106a290200370300200241e80c6a41086a20024198106a41086a29020037030020022002290298103703e80c200241e40c6a41026a200241f8136a41026a2d00003a0000200220022f00f8133b01e40c200241c80c6a41106a200241a80e6a41106a290200370300200241c80c6a41086a200241a80e6a41086a290200370300200220022902a80e3703c80c200241d8146a41206a200241c0156a41206a280200360200200241d8146a41186a200241c0156a41186a290200370300200241d8146a41106a200241c0156a41106a290200370300200241d8146a41086a200241c0156a41086a290200370300200220022902c0153703d8142006ad422086200aad842107410d210a0c0a0b200841ff01714102470d0a2006450d0a200a102e0c0a0b200241f0176a200110eb0120022d00f0174105460d092002418c186a310000210c20024184186a290200210b200241f0176a41206a220d28020021032002418e186a2f010021042002418d186a2d00002105410c210a200241f0176a410c6a290200210f200241f0176a41086a220e280200210620022802f417210920022802f0172108200241f0176a200110ed03024020022d00f0174106460d00200241900d6a41086a200241e8096a41086a2802003602002002418c0d6a41026a20024198136a41026a2d00003a0000200241c80d6a41086a200241e0076a41086a290200370300200241c80d6a41106a200241e0076a41106a290200370300200220022902e8093703900d200220022f0098133b018c0d200220022902e0073703c80d200241f0176a41186a2903002110200241f0176a41106a2903002111200d280200210d200e290300211520022903f0172114200241880d6a41026a200241e80f6a41026a2d00003a0000200220022f00e80f3b01880d200241a00d6a41106a200241d8116a41106a290200370300200241a00d6a41086a200241d8116a41086a290200370300200220022902d8113703a00d200241840d6a41026a200241f80d6a41026a2d00003a0000200220022f00f80d3b01840d200241e80c6a41106a20024198106a41106a290200370300200241e80c6a41086a20024198106a41086a29020037030020022002290298103703e80c200241e40c6a41026a200241f8136a41026a2d00003a0000200220022f00f8133b01e40c200241c80c6a41106a200241a80e6a41106a290200370300200241c80c6a41086a200241a80e6a41086a290200370300200220022902a80e3703c80c200241d8146a41206a200241c0156a41206a280200360200200241d8146a41186a200241c0156a41186a290200370300200241d8146a41106a200241c0156a41106a290200370300200241d8146a41086a200241c0156a41086a290200370300200220022902c0153703d8142006ad4220862009ad8421070c090b200841ff01714102470d092006450d092009102e0c090b200241f0176a200110eb0120022d00f0174105460d08200241900d6a41086a200241e8096a41086a2802003602002002418c0d6a41026a20024198136a41026a2d00003a0000200241c80d6a41086a200241e0076a41086a290200370300200241c80d6a41106a200241e0076a41106a290200370300200220022902e8093703900d200220022f0098133b018c0d200220022902e0073703c80d2002418c186a310000210c20024184186a290200210b200241fc176a290200210f200241f0176a41206a28020021032002418e186a2f010021042002418d186a2d0000210520022902f417210720022802f0172108200241880d6a41026a200241e80f6a41026a2d00003a0000200220022f00e80f3b01880d200241a00d6a41106a200241d8116a41106a290200370300200241a00d6a41086a200241d8116a41086a290200370300200220022902d8113703a00d200241840d6a41026a200241f80d6a41026a2d00003a0000200220022f00f80d3b01840d200241e80c6a41106a20024198106a41106a290200370300200241e80c6a41086a20024198106a41086a29020037030020022002290298103703e80c200241e40c6a41026a200241f8136a41026a2d00003a0000200220022f00f8133b01e40c200241c80c6a41106a200241a80e6a41106a290200370300200241c80c6a41086a200241a80e6a41086a290200370300200220022902a80e3703c80c200241d8146a41206a200241c0156a41206a280200360200200241d8146a41186a200241c0156a41186a290200370300200241d8146a41106a200241c0156a41106a290200370300200241d8146a41086a200241c0156a41086a290200370300200220022902c0153703d814410b210a0c070b20024180066a200110ad012002280280060d072002280284062108200241f0176a200110eb0120022d00f0174105460d07200241f8176a280200210920022802f417210d20022802f017210a0240024020012802002206280204220e450d0020024188186a310000210c20024180186a290300210b20024190186a35020021142002418c186a28020021032002418a186a2f0100210420024189186a2d00002105200241fc176a3502002107200628020022222d000021212006200e417f6a3602042006202241016a3602004200211502400240024002400240024020210e0707000102030405060b2001280200220128020422064110490d052001280200220e41086a2900002110200e29000021112001200e41106a3602002001200641706a360204420121150c060b420221150c050b420321150c040b420421150c030b420521150c020b420621150c010b200a41ff01714102470d082009450d08200d102e0c080b200241900d6a41086a200241e8096a41086a2802003602002002418c0d6a41026a20024198136a41026a2d00003a0000200241c80d6a41086a200241e0076a41086a290200370300200241c80d6a41106a200241e0076a41106a290200370300200241880d6a41026a200241e80f6a41026a2d00003a0000200220022902e8093703900d200220022f0098133b018c0d200220022902e0073703c80d200220022f00e80f3b01880d200241a00d6a41106a200241d8116a41106a290200370300200241a00d6a41086a200241d8116a41086a290200370300200241840d6a41026a200241f80d6a41026a2d00003a0000200241e80c6a41086a20024198106a41086a290200370300200241e80c6a41106a20024198106a41106a290200370300200241e40c6a41026a200241f8136a41026a2d00003a0000200220022902d8113703a00d200220022f00f80d3b01840d20022002290298103703e80c200220022f00f8133b01e40c200241c80c6a41106a200241a80e6a41106a290200370300200241c80c6a41086a200241a80e6a41086a290200370300200241d8146a41206a200241c0156a41206a280200360200200241d8146a41186a200241c0156a41186a290200370300200241d8146a41106a200241c0156a41106a290200370300200241d8146a41086a200241c0156a41086a290200370300200220022902a80e3703c80c200220022902c0153703d81420074220862009ad84210f200dad422086200aad842107410a210a0c060b200241f8056a200110ad0120022802f8050d062001280200220128020422034108490d0620022802fc0521082001280200220429000021072001200341786a3602042001200441086a360200200742ff01560d06200241900d6a41086a200241a80e6a41086a2802003602002002418c0d6a41026a200241e8096a41026a2d00003a0000200241c80d6a41086a200241c0156a41086a290200370300200241c80d6a41106a200241c0156a41106a290200370300200241880d6a41026a20024198136a41026a2d00003a0000200220022902a80e3703900d200220022f00e8093b018c0d200220022902c0153703c80d200220022f0098133b01880d200241a00d6a41106a200241e0076a41106a290200370300200241a00d6a41086a200241e0076a41086a290200370300200241840d6a41026a200241e80f6a41026a2d00003a0000200241e80c6a41086a200241d8116a41086a290200370300200241e80c6a41106a200241d8116a41106a290200370300200241e40c6a41026a200241f80d6a41026a2d00003a0000200220022902e0073703a00d200220022f00e80f3b01840d200220022902d8113703e80c200220022f00f80d3b01e40c200241c80c6a41106a20024198106a41106a290200370300200241c80c6a41086a20024198106a41086a290200370300200241d8146a41206a200241f0176a41206a280200360200200241d8146a41186a200241f0176a41186a290200370300200241d8146a41106a200241f0176a41106a290200370300200241d8146a41086a200241f0176a41086a29020037030020022002290298103703c80c200220022902f0173703d814200742ff018321074109210a0c050b200241f0056a200110ad0120022802f0050d0520022802f405210341002105200241003a00e01502400340200128020022042802042206450d01200241c0156a20056a200428020022082d00003a000020042006417f6a3602042004200841016a3602002002200541016a22043a00e0152004210520044120470d000b200241e8096a41186a200241df156a310000220c3c00004108210a200241900d6a41086a20024198136a41086a2802003602002002418c0d6a41026a200241e80f6a41026a2d00003a0000200220022900cf15220f3703f009200220022900c71522073703e809200220022900d715220b3703f80920022002290298133703900d200220022f00e80f3b018c0d20022800c315210820022f00c115212a20022d00c015212c200241c80d6a41106a200241e0076a41106a290200370300200241c80d6a41086a200241e0076a41086a290200370300200220022902e0073703c80d200241880d6a41026a200241f80d6a41026a2d00003a0000200220022f00f80d3b01880d200241a00d6a41106a200241d8116a41106a290200370300200241a00d6a41086a200241d8116a41086a290200370300200220022902d8113703a00d200241840d6a41026a200241f8136a41026a2d00003a0000200220022f00f8133b01840d200241e80c6a41106a20024198106a41106a290200370300200241e80c6a41086a20024198106a41086a29020037030020022002290298103703e80c200241e40c6a41026a200241b4146a41026a2d00003a0000200220022f00b4143b01e40c200241c80c6a41106a200241a80e6a41106a290200370300200241c80c6a41086a200241a80e6a41086a290200370300200220022902a80e3703c80c200241d8146a41206a200241f0176a41206a280200360200200241d8146a41186a200241f0176a41186a290200370300200241d8146a41106a200241f0176a41106a290200370300200241d8146a41086a200241f0176a41086a290200370300200220022902f0173703d8140c050b200541ff0171450d05200241003a00e0150c050b200241e8056a200110ad0120022802e8050d0420022802ec052108200241d0056a200110820220022903d005a70d04200241d0056a41106a290300210f20022903d8052107200241900d6a41086a200241a80e6a41086a2802003602002002418c0d6a41026a200241e8096a41026a2d00003a0000200241c80d6a41086a200241c0156a41086a290200370300200241c80d6a41106a200241c0156a41106a290200370300200241880d6a41026a20024198136a41026a2d00003a0000200220022902a80e3703900d200220022f00e8093b018c0d200220022902c0153703c80d200220022f0098133b01880d200241a00d6a41106a200241e0076a41106a290200370300200241a00d6a41086a200241e0076a41086a290200370300200241840d6a41026a200241e80f6a41026a2d00003a0000200241e80c6a41086a200241d8116a41086a290200370300200241e80c6a41106a200241d8116a41106a290200370300200241e40c6a41026a200241f80d6a41026a2d00003a0000200220022902e0073703a00d200220022f00e80f3b01840d200220022902d8113703e80c200220022f00f80d3b01e40c200241c80c6a41106a20024198106a41106a290200370300200241c80c6a41086a20024198106a41086a290200370300200241d8146a41206a200241f0176a41206a280200360200200241d8146a41186a200241f0176a41186a290200370300200241d8146a41106a200241f0176a41106a290200370300200241d8146a41086a200241f0176a41086a29020037030020022002290298103703c80c200220022902f0173703d8144107210a0c030b2001280200220128020422034104490d0320012802002204280000210820012003417c6a3602042001200441046a360200200241900d6a41086a200241a80e6a41086a2802003602002002418c0d6a41026a200241e8096a41026a2d00003a0000200241c80d6a41086a200241c0156a41086a290200370300200241c80d6a41106a200241c0156a41106a290200370300200220022902a80e3703900d200220022f00e8093b018c0d200220022902c0153703c80d200241880d6a41026a20024198136a41026a2d00003a0000200220022f0098133b01880d200241a00d6a41106a200241e0076a41106a290200370300200241a00d6a41086a200241e0076a41086a290200370300200220022902e0073703a00d200241840d6a41026a200241e80f6a41026a2d00003a0000200220022f00e80f3b01840d200241e80c6a41106a200241d8116a41106a290200370300200241e80c6a41086a200241d8116a41086a290200370300200220022902d8113703e80c200241e40c6a41026a200241f80d6a41026a2d00003a0000200220022f00f80d3b01e40c200241c80c6a41106a20024198106a41106a290200370300200241c80c6a41086a20024198106a41086a29020037030020022002290298103703c80c200241d8146a41206a200241f0176a41206a280200360200200241d8146a41186a200241f0176a41186a290200370300200241d8146a41106a200241f0176a41106a290200370300200241d8146a41086a200241f0176a41086a290200370300200220022902f0173703d8144106210a4200210f0c020b200241c8056a200110ad0120022802c8050d0220022802cc052108200241b0056a200110820220022903b005a70d02200241b0056a41106a290300210f20022903b8052107200241900d6a41086a200241a80e6a41086a2802003602002002418c0d6a41026a200241e8096a41026a2d00003a0000200241c80d6a41086a200241c0156a41086a290200370300200241c80d6a41106a200241c0156a41106a290200370300200241880d6a41026a20024198136a41026a2d00003a0000200220022902a80e3703900d200220022f00e8093b018c0d200220022902c0153703c80d200220022f0098133b01880d200241a00d6a41106a200241e0076a41106a290200370300200241a00d6a41086a200241e0076a41086a290200370300200241840d6a41026a200241e80f6a41026a2d00003a0000200241e80c6a41086a200241d8116a41086a290200370300200241e80c6a41106a200241d8116a41106a290200370300200241e40c6a41026a200241f80d6a41026a2d00003a0000200220022902e0073703a00d200220022f00e80f3b01840d200220022902d8113703e80c200220022f00f80d3b01e40c200241c80c6a41106a20024198106a41106a290200370300200241c80c6a41086a20024198106a41086a290200370300200241d8146a41206a200241f0176a41206a280200360200200241d8146a41186a200241f0176a41186a290200370300200241d8146a41106a200241f0176a41106a290200370300200241d8146a41086a200241f0176a41086a29020037030020022002290298103703c80c200220022902f0173703d8144105210a0c010b200241a8056a200110ad0120022802a8050d0120022802ac052222200128020028020441c4006e2203200320224b1bad42c4007e2207422088a70d132007a72203417f4c0d130240024020030d00410421080c010b2003102c2208450d190b2001200128020441016a2204360204200341c4006ead21070240200420012802084b0d00024002402022450d00200241f8136a410f6a211a20024180186a212c4100210a0340200241003a009018200a41016a210a410021040240024002400340200128020022032802042205450d01200241f0176a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0090182003210420034120470d000b200241f0176a411f6a310000210b200229008718210c20022d00f017210320022f00f117210520022800f317210620022900f717210f20022800ff172116200228008318212a200241f0176a200110ed0320022d00f01722044106470d01410621040c020b0240200441ff0171450d00200241003a0090180b410621040c010b202c290300211520022903f817211120022f019218211f20022d009118211e200228008d18211d20022f008b18211c20022d008a18211720022f018818212320022802f417211b20022f01f217211920022d00f1172118202a212120162120200f2110200621092005210d2003210e200c2114200b21130b2002202136008b142002202036008714200220103700ff13200220093600fb132002200d3b00f9132002200e3a00f81320044106460d03201a290000210c20022900ff13210f02402007422088220ba722032007a7470d00200341016a22052003490d1820034101742206200520052006491b22054104200541044b1bad42c4007e220b422088a7454102742105200ba721060240024020030d00200241003602f0170c010b200241043602f817200220083602f0172002200341c4006c3602f4170b200241e8096a20062005200241f0176a107d20022802f009210520022802e8094101460d0320022802ec0921082007422088220ba72103200541c4006ead21070b2008200341c4006c6a22032011370028200320143700172003200f3700072003201f3b00422003201e3a00412003201d36003d2003201c3b003b200320173a003a200320233b00382003201b360024200320193b0022200320183a0021200320043a0020200320093600032003200d3b00012003200e3a0000200341306a20153700002003411f6a20133c00002003410f6a200c370000200b422086200742ffffffff0f83844280808080107c2107200a2022470d000b200128020421040b20012004417f6a3602042008450d03200241900d6a41086a20024198136a41086a2802003602002002418c0d6a41026a200241e80f6a41026a2d00003a0000200241c80d6a41086a200241e0076a41086a290200370300200241c80d6a41106a200241e0076a41106a290200370300200241880d6a41026a200241f80d6a41026a2d00003a000020022002290298133703900d200220022f00e80f3b018c0d200220022902e0073703c80d200220022f00f80d3b01880d200241a00d6a41106a200241d8116a41106a290200370300200241a00d6a41086a200241d8116a41086a290200370300200241840d6a41026a200241b4146a41026a2d00003a0000200241e80c6a41086a20024198106a41086a290200370300200241e80c6a41106a20024198106a41106a290200370300200241e40c6a41026a200241b0146a41026a2d00003a0000200220022902d8113703a00d200220022f00b4143b01840d20022002290298103703e80c200220022f00b0143b01e40c200241c80c6a41106a200241a80e6a41106a290200370300200241c80c6a41086a200241a80e6a41086a290200370300200241d8146a41206a200241c0156a41206a280200360200200241d8146a41186a200241c0156a41186a290200370300200241d8146a41106a200241c0156a41106a290200370300200241d8146a41086a200241c0156a41086a290200370300200220022902a80e3703c80c200220022902c0153703d8144103210a0c020b20050d190c140b02402007422088a72201450d00200141c4006c2103200841286a210103400240200141786a2d00004101470d002001280200450d002001417c6a280200102e0b200141c4006a2101200341bc7f6a22030d000b0b2007a72201450d01200141c4006c450d012008102e0c010b200241b80c6a41086a2201200241900d6a41086a280200360200200241b40c6a41026a22062002418c0d6a41026a2d00003a0000200241980c6a41086a222d200241c80d6a41086a290300370300200241980c6a41106a222e200241c80d6a41106a290300370300200241940c6a41026a222f200241880d6a41026a2d00003a0000200220022903900d3703b80c200220022f018c0d3b01b40c200220022903c80d3703980c200220022f01880d3b01940c200241f80b6a41106a2230200241a00d6a41106a290300370300200241f80b6a41086a2224200241a00d6a41086a290300370300200241f40b6a41026a2227200241840d6a41026a2d00003a0000200241d80b6a41086a2231200241e80c6a41086a290300370300200241d80b6a41106a2232200241e80c6a41106a290300370300200241d40b6a41026a2233200241e40c6a41026a2d00003a0000200220022903a00d3703f80b200220022f01840d3b01f40b200220022903e80c3703d80b200220022f01e40c3b01d40b200241b80b6a41106a2234200241c80c6a41106a290300370300200241b80b6a41086a2235200241c80c6a41086a290300370300200241d00a6a41206a2236200241d8146a41206a280200360200200241d00a6a41186a2237200241d8146a41186a290300370300200241d00a6a41106a2238200241d8146a41106a290300370300200241d00a6a41086a2239200241d8146a41086a290300370300200220022903c80c3703b80b200220022903d8143703d00a200041c8006a2010370200200041c0006a2011370200200041286a200c3c0000200041206a200b370200200041186a200f370200200041106a2007370200200041d0006a200d360200200041386a2015370200200041306a20143702002000412c6a2003360200200020043b002a200020053a00292000410c6a20083602002000202a3b000a2000202c3a0009200041086a200a3a000020004116360200200041e0006a20093a0000200041d4006a20022903b80c370200200041dc006a2001280200360200200041e4006a2022360200200041e8006a200e360200200020022f01b40c3b0061200041e3006a20062d00003a0000200041ec006a20022903980c370200200041f4006a202d290300370200200041fc006a202e29030037020020004184016a20213a000020004187016a202f2d00003a0000200020022f01940c3b0085012000418c016a202036020020004188016a201f360200200041a0016a203029030037020020004198016a202429030037020020004190016a20022903f80b370200200041a8016a201e3a0000200041ab016a20272d00003a0000200020022f01f40b3b00a901200041b0016a201d360200200041ac016a201c360200200041c4016a2032290300370200200041bc016a2031290300370200200041b4016a20022903d80b370200200041cc016a20183a0000200041cf016a20332d00003a0000200020022f01d40b3b00cd01200041d4016a201a360200200041d0016a2016360200200041e8016a2034290300370200200041e0016a2035290300370200200041d8016a20022903b80b37020020004190026a203628020036020020004188026a203729030037020020004180026a2038290300370200200041f8016a2039290300370200200041f0016a20022903d00a370200200041a4026a20123700002000419c026a201337000020004198026a20193600002000201b3b009602200020173a00950220004194026a20233a00000c1b0b2000411c3602000c1a0b200020043b0046200020053a00452000201e3600412000201f3b003f2000201d3a003e200020173b0026200020233a00252000201b360021200020203b001f200020193a001e2000200a3b0006200020093a0005200020033a000420004111360200200041346a200c3700002000412c6a200b3700002000410c6a20073700002000413c6a20213b0000200041286a201c3600002000411c6a20223b0000200041086a2008360000200041146a200dad422086200ead84370000200041c8006a200241f0176a41e80110e9081a0c190b4100210a410021094100210d0b0b200020083a000920004110360200200041286a200b370200200041146a2004360200200041106a20053602002000410c6a2003360200200041086a200e3a0000200041186a200dad220b423886200742ffffffffffffffff008384370200200041206a200aad4238862009ad42188684200b42088884370200200041306a200241f0176a41800210e9081a0c160b2000411c3602000c150b0b200020013a0029200020053b000a200020043a00092000410f360200200041286a200b3c0000200041206a200c370200200041386a2007370200200041346a2009360200200041306a200a3602002000412c6a2008360200200041146a200e360200200041106a20063602002000410c6a2003360200200041086a20213a0000200041186a2022ad422086200dad84370200200041c0006a200241f0176a41f00110e9081a0c130b2007422088a721010240200d450d002005102e0b2007a7210402402001450d002001410c6c2103200a210103400240200141046a280200450d002001280200102e0b2001410c6a2101200341746a22030d000b0b2004450d032004410c6c450d03200a102e0c030b200d102e0b02402007422088a72201450d002001410c6c2103200a210103400240200141046a280200450d002001280200102e0b2001410c6a2101200341746a22030d000b0b2007a72201450d002001410c6c450d00200a102e0b200ba7450d002005102e0b2000411c3602000c0e0b200d0d090c040b4100210e4200210f0b0c010b200241e9076a200c370000200220073700e107200220022d00df143a00e0074108210920022903e007220c422088200241e0076a41086a290300220f42208684210720022f01d81420022d00da14411074722204410876210d200f422088210f200ca7220e41807e7121162002200b3700f107200b422088a72118200b421088a72119200b420888a7211a201042ff0183a7211720022800db14210320022f01f007211b0b2000201e3a0049200020213a0042200020233b002a200020173a0029200020193b00232000201a3a00222000200d3b010a200020043a000920004107360200200041d8006a200c370200200041d0006a200b370200200041cc006a201c360200200041ca006a201d3b0100200041c5006a201f360000200041c3006a20203b0000200041c0006a20223b0100200041386a2010370200200041346a2008360200200041306a200a3602002000412c6a2005360200200041256a2018360000200041206a201b3b01002000410c6a2003360200200041086a20093a0000200041186a200f422086200742208884370200200041106a20074220862016200e41ff017172ad84370200200041e0006a200241f0176a41d00110e9081a0c090b1038000b2000411c3602000c070b410021064200210b410021010b200041003b0126200020013a00252000200a3b0023200020093b000d200020043b0006200020053a0005200020083a0004200041043602002000411b6a200b370000200041136a2007370000200041286a20063602002000410f6a200d3600002000410c6a200e3a0000200041086a20033602002000412c6a200241f0176a41840210e9081a0c050b2000411c3602000c040b1036000b02402007422088a72201450d00200141186c21032004210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141186a2101200341686a22030d000b0b2007a72201450d01200141186c450d010b2004102e0b2000411c3602000b200241c01a6a24000baa2d01047f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002802000e1b00010218180304051806070818090a0b0c0d0e0f10111213141516170b0240024002400240024002400240200041086a2802000e0a1e1e001e01021e030405060b200041106a280200450d1d2000410c6a280200102e0f0b200041106a280200450d1c2000410c6a280200102e0f0b200041106a280200450d1b2000410c6a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141186c210103400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200141686a22010d000b0b200041106a2802002202450d1a200241186c450d1a200028020c102e0f0b0240200041146a2802002201450d002000410c6a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041106a2802002202450d192002410c6c450d19200028020c102e0f0b200041106a280200450d182000410c6a280200102e0f0b200041106a280200450d172000410c6a280200102e0f0b0240024002400240024020002d00040e061b001b010203040b200041186a22022802001096012002280200102e0f0b02402000410c6a280200450d00200041086a280200102e0b200041246a22022802001096012002280200102e0f0b2000410c6a280200450d18200041086a280200102e0f0b200041186a22022802001096012002280200102e0f0b02402000410c6a280200450d00200041086a280200102e0b200041246a22022802001096012002280200102e0f0b02400240200041086a280200417f6a0e020001170b0240200041346a2802002201450d002000412c6a2802002102200141246c210103400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b0240200041306a2802002202450d00200241246c450d00200028022c102e0b0240200041a4016a2802002201450d002000419c016a2802002102200141246c210103400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b0240200041a0016a2802002202450d00200241246c450d00200028029c01102e0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d162002410c6c450d162000280210102e0f0b0240200041346a2802002201450d002000412c6a2802002102200141246c210103400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b0240200041306a2802002202450d00200241246c450d00200028022c102e0b0240200041a4016a2802002201450d002000419c016a2802002102200141246c210103400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b0240200041a0016a2802002202450d00200241246c450d00200028029c01102e0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d152002410c6c450d152000280210102e0f0b0240024002400240200041086a2802000e0418000102030b2000410c6a2d00004102470d17200041146a280200450d17200041106a280200102e0f0b2000410c6a2d00004102470d16200041146a280200450d16200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004102470d15200041386a280200450d15200041346a280200102e0f0b2000410c6a2d00004102470d14200041146a280200450d14200041106a280200102e0f0b02402000410c6a2802002201450d0020002802042202200141f0006c6a21030340024020022204410c6a2802002201450d0020042802042102200141246c210103400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200441f0006a21020240200441086a2802002201450d00200141246c450d002004280204102e0b20022003470d000b0b200041086a2802002202450d13200241f0006c450d132000280204102e0f0b024002400240024002400240200041086a2d00000e171800181818180118180218181818180318180418181818050b2000412c6a2d00004102470d17200041346a280200450d17200041306a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141246c21010340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200041106a2802002202450d16200241246c450d16200028020c102e0f0b2000410c6a2d00004102470d15200041146a280200450d15200041106a280200102e0f0b200041106a28020041ffffff3f71450d142000410c6a280200102e0f0b200041146a28020041ffffffff0371450d13200041106a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141246c21010340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200041106a2802002202450d12200241246c450d12200028020c102e0f0b20002802042202450d11200041086a280200450d112002102e0f0b02400240200041086a280200417f6a0e020001120b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d112002410c6c450d112000280210102e0f0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d102002410c6c450d102000280210102e0f0b02402000410c6a280200450d00200041086a280200102e0b02402000411c6a2802002201450d00200041146a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041186a2802002202450d0f2002410c6c450d0f2000280214102e0f0b0240024002400240200041086a2d000041716a0e0400010203120b200041106a280200450d112000410c6a280200102e0f0b200041106a280200450d102000410c6a280200102e0f0b200041106a280200450d0f2000410c6a280200102e0f0b200041106a280200450d0e2000410c6a280200102e0f0b024002400240200041086a2d0000417f6a0e03000102100b200041306a28020041ffffff3f71450d0f2000412c6a280200102e0f0b2000410c6a22022802001096012002280200102e0f0b200041106a22022802001096012002280200102e0f0b024002400240200041086a2d0000417f6a0e030001020f0b200041306a28020041ffffff3f71450d0e2000412c6a280200102e0f0b2000410c6a22022802001096012002280200102e0f0b200041106a22022802001096012002280200102e0f0b02400240200041086a2d0000417f6a0e05000d0d0d010d0b200041106a28020041ffffff3f71450d0c2000410c6a280200102e0f0b2000410c6a2d00004102470d0b200041146a280200450d0b200041106a280200102e0f0b20002d00044104470d0a2000410c6a28020041ffffff3f71450d0a200041086a280200102e0f0b200041086a2802004101470d092000410c6a2d00004102470d09200041146a280200450d09200041106a280200102e0f0b02400240200041086a2d0000417d6a0e0200010a0b200041f0006a280200450d09200041ec006a280200102e0f0b200041106a280200450d082000410c6a280200102e0f0b024002400240200041086a2802000e040a0a0001020b2000410c6a2d00004102470d09200041146a280200450d09200041106a280200102e0f0b2000410c6a2d00004102470d08200041146a280200450d08200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004102470d07200041386a280200450d07200041346a280200102e0f0b02400240024020002f01040e03090001020b0240200041106a2802002201450d00200041086a2802002102200141b0026c210103402002109601200241b0026a2102200141d07d6a22010d000b0b2000410c6a2802002202450d08200241b0026c450d082000280208102e0f0b200041086a22022802001096012002280200102e0f0b0240200041106a2802002201450d00200041086a2802002102200141b0026c210103402002109601200241b0026a2102200141d07d6a22010d000b0b2000410c6a2802002202450d06200241b0026c450d062000280208102e0f0b0240024002400240024002400240200041086a2d0000417e6a0e0d00010c0c0c0c0c0c02030405060c0b0240200041146a2802002201450d002000410c6a2802002202200141c8006c6a21010340024020022d00004101470d00200241086a280200450d00200241046a280200102e0b0240200241246a2d00004101470d002002412c6a280200450d00200241286a280200102e0b200241c8006a22022001470d000b0b0240200041106a2802002202450d00200241c8006c450d00200028020c102e0b0240200041186a2d00004101470d00200041206a280200450d002000411c6a280200102e0b02402000413c6a2d00004101470d00200041c4006a280200450d00200041c0006a280200102e0b0240200041e0006a2d00004101470d00200041e8006a280200450d00200041e4006a280200102e0b024020004184016a2d00004101470d002000418c016a280200450d0020004188016a280200102e0b0240200041a8016a2d00004101470d00200041b0016a280200450d00200041ac016a280200102e0b0240200041cc016a2d00004101470d00200041d4016a280200450d00200041d0016a280200102e0b200041f0016a2d00004101470d0b200041f8016a280200450d0b200041f4016a280200102e0f0b0240200041146a2802002202450d00200241c4006c21012000410c6a28020041286a210203400240200241786a2d00004101470d002002280200450d002002417c6a280200102e0b200241c4006a2102200141bc7f6a22010d000b0b200041106a2802002202450d0a200241c4006c450d0a200028020c102e0f0b200041106a2d00004102470d09200041186a280200450d09200041146a280200102e0f0b2000410c6a2d00004102470d08200041146a280200450d08200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004101470d07200041386a280200450d07200041346a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004101470d06200041386a280200450d06200041346a280200102e0f0b2000410c6a2d00004102470d05200041146a280200450d05200041106a280200102e0f0b20002d00042202417e6a4108490d040240024020020e020600010b200041286a22022802001096012002280200102e0f0b200041c8006a22022802001096012002280200102e0f0b0240024002400240200041086a2d00000e0407000102030b0240200041106a28020041ffffff3f71450d002000410c6a280200102e0b200041186a22022802001096012002280200102e0f0b0240200041106a28020041ffffff3f71450d002000410c6a280200102e0b200041286a280200450d05200041246a280200102e0f0b200041306a28020041ffffff3f71450d042000412c6a280200102e0f0b200041306a28020041ffffff3f71450d032000412c6a280200102e0f0b0240024002400240200041086a2802000e09060006010606020606030b200041106a280200450d052000410c6a280200102e0f0b200041106a2d00004102470d04200041186a280200450d04200041146a280200102e0f0b200041106a2d00004102470d03200041186a280200450d03200041146a280200102e0f0b200041146a280200450d02200041106a280200102e0f0b02400240200041086a2d0000417f6a0e03000301030b200041306a280200450d022000412c6a280200102e0c020b200041306a280200450d012000412c6a280200102e0f0b02402000413c6a28020041ffffffff0171450d00200041386a280200102e0b0240200041c8006a2802002202450d002002410c6c450d00200041c4006a280200102e0b0240200041d4006a28020041ffffffff0071450d00200041d0006a280200102e0b0240200041e0006a2802002202450d00200241146c450d00200041dc006a280200102e0b0240200041ec006a2802002202450d00200241186c450d00200041e8006a280200102e0b0240200041f8006a2802002202450d002002411c6c450d00200041f4006a280200102e0b024020004184016a28020041ffffff3f71450d0020004180016a280200102e0b024020004190016a2802002202450d00200241246c450d002000418c016a280200102e0b02402000419c016a2802002202450d00200241286c450d0020004198016a280200102e0b0240200041a8016a2802002202450d002002412c6c450d00200041a4016a280200102e0b0240200041b4016a2802002202450d00200241306c450d00200041b0016a280200102e0b0240200041c0016a2802002202450d00200241346c450d00200041bc016a280200102e0b0240200041cc016a2802002202450d00200241386c450d00200041c8016a280200102e0b0240200041d8016a2802002202450d002002413c6c450d00200041d4016a280200102e0b0240200041e4016a28020041ffffff1f71450d00200041e0016a280200102e0b200041f0016a2802002202450d00200241c4006c450d00200041ec016a280200102e0f0b0b900403027f017e077f230041a0076b22032400024002400240024002402002200128020441b0026e2204200420024b1bad42b0027e2205422088a70d002005a72204417f4c0d000240024020040d00410821060c010b2004102c2206450d030b200441b0026e2107024020020d00410021020c040b200341e0046a410472210841002109410021044100210a0340200341e0046a200110980120032802e004210b200341b4026a200841ac0210e9081a200b411c460d02200341086a200341b4026a41ac0210e9081a02400240200a2007470d002009200a41016a220c2009200c4b1b220c4104200c41044b1bad42b0027e2205422088a745410374210c2005a7210702400240200a0d00200341003602e0040c010b200341083602e804200320043602e404200320063602e0040b20034190076a2007200c200341e0046a107d200328029807210c2003280290074101460d012003280294072106200c41b0026e21070b200620046a220c200b360200200c41046a200341086a41ac0210e9081a200941026a2109200441b0026a21042002200a41016a220a460d050c010b0b200c0d020b1038000b200041003602000240200a450d002006210a0340200a109601200a41b0026a210a200441d07d6a22040d000b0b2007450d02200741b0026c450d022006102e0c020b1036000b2000200736020420002006360200200041086a20023602000b200341a0076a24000bfcb1030b067f017e027f027e037f017e027f067e0f7f037e117f230041c01b6b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200141046a2104200128020022052d0000210620012003417f6a22073602042001200541016a36020020060e250102030405060708090a2b0b0c0d0e0f101112132b2b2b2b1415162b17302f2b2b2b2e2d2c2b0b2000411c3602000c630b2007450d6120052d0001210620012003417e6a22073602042001200541026a36020002400240024002400240024002400240024002400240024020060e0a000102030405060708096d0b20074104490d6c2005280002210620012003417a6a3602042001200541066a3602002006418194ebdc034f0d6c410121010c0a0b2002200110ab0120022802000d6b2004280200220320022802042205490d6b2005417f4c0d670240024020050d00410121060c010b200510322206450d6a200428020021030b20032005490d6a20062001280200200510e9082103200128020422072005490d302001200720056b3602042001200128020020056a3602002003450d6b2005ad220842208620088421084102410b20031b21010c080b20074108490d6a200529000221082001200341766a36020420012005410a6a360200410321010c080b200241086a200110ab0120022802080d6920042802002203200228020c2205490d692005417f4c0d650240024020050d00410121060c010b200510322206450d68200428020021030b20032005490d6820062001280200200510e9082103200128020422072005490d262001200720056b3602042001200128020020056a3602002003450d692005ad220842208620088421084104410b20031b21010c060b200241106a200110ab0120022802100d682004280200220320022802142205490d682005417f4c0d640240024020050d00410121060c010b200510322206450d67200428020021030b20032005490d6720062001280200200510e9082103200128020422072005490d242001200720056b3602042001200128020020056a3602002003450d682005ad220842208620088421084105410b20031b21010c050b20024180166a200110fe0520022802801622064102460d672002290284162108410621010c040b200241286a200110ab0120022802280d66200228022c2207200428020041186e2205200520074b1bad42187e2208422088a70d622008a72205417f4c0d620240024020050d00410421060c010b2005102c2206450d650b200541186ead2108024002402007450d000340200241206a200110ab010240024020022802200d002004280200220320022802242205490d002005417f4c0d670240024020050d00410121090c010b200510322209450d6a200428020021030b024020032005490d0020092001280200200510e908210a200128020422032005490d302001200320056b3602042001200128020020056a360200200a450d01200241186a200110ab012005ad220b422086200b84220ca7210d024020022802180d0020042802002203200228021c2205490d002005417f4c0d690240024020050d004101210e0c010b20051032220e450d6c200428020021030b0240024020032005490d00200e2001280200200510e908210e2001280204220320054f0d012005200341b8b2c0001056000b200e102e0c010b2001200320056b3602042001200128020020056a360200200e0d030b200d450d010b2009102e0b02402008422088a72201450d00200141186c21052006210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141186a2101200541686a22050d000b0b2008a72201450d6a200141186c450d6a0c690b02402008422088220ba722032008a7470d00200341016a22092003490d662003410174220f20092009200f491b22094104200941044b1bad42187e220b422088a7454102742109200ba7210f0240024020030d0020024100360280160c010b200241043602881620022006360280162002200341186c360284160b20024198086a200f200920024180166a107d20022802a00821092002280298084101460d03200228029c0821062008422088220ba72103200941186ead21080b2006200341186c6a2203200d3602042003200a360200200341146a2005ad22104220862010842210422088a73602002003410c6a2010422086200ead84370200200341086a200c422088a7360200200b422086200842ffffffff0f83844280808080107c21082007417f6a22070d000b0b2006450d674107410b20061b21010c040b2009450d620c640b20024180166a200110e3012002280280162206450d652002290284162108410821010c020b200241306a200110ab0120022802300d642004280200220320022802342205490d642005417f4c0d600240024020050d00410121060c010b200510322206450d63200428020021030b20032005490d6320062001280200200510e9082103200128020422072005490d1f2001200720056b3602042001200128020020056a3602002003450d642005ad220842208620088421080240200428020022034104490d0020012802002207280000210520012003417c6a3602042001200741046a360200410921010c030b2008a70d630c640b200241386a200110ab0120022802380d6320042802002203200228023c2205490d632005417f4c0d5f0240024020050d00410121060c010b200510322206450d62200428020021030b20032005490d6220062001280200200510e9082103200128020422072005490d1d2001200720056b3602042001200128020020056a3602002003450d632005ad22084220862008842108410a410b20031b21010b0b20004100360200200041186a2005360200200041106a20083702002000410c6a2006360200200041086a2001360200200041206a200241b0186a41900210e9081a0c620b02402007450d0020052d0001210620012003417e6a22073602042001200541026a36020002400240024002400240024002400240024020060e06000102030405090b20074104490d082005280002210620012003417a6a22073602042001200541066a3602002007450d0820052d0006210a2001200341796a22043602042001200541076a220e3602004100210702400240200a0e0201000a0b20044104490d09200535000721082001200341756a220736020420012005410b6a36020020074104490d09200535000b210b2001200341716a220436020420012005410f6a220e3602002008200b422086842108410121070b41000d082004450d08200e2d0000210320012004417f6a3602042001200e41016a360200200241b0186a200110980120022802b018210120024180166a200241b0186a41047241ac0210e9081a2001411c460d08200241b0186a20024180166a41ac0210e9081a41b002102c2205450d6720052001360200200541046a200241b0186a41ac0210e9081a2008422088a721042008a7210a4101210e420021080c050b20074104490d072005280002210620012003417a6a22073602042001200541066a36020020074104490d07200528000621072001200341766a36020420012005410a6a3602004102210e41002105420021080c040b200241c0006a200110ab0120022802400d062004280200220320022802442205490d062005417f4c0d630240024020050d00410121060c010b200510322206450d66200428020021030b20032005490d0520062001280200200510e9082103200128020422072005490d2a2001200720056b3602042001200128020020056a3602002003450d062005ad2208422086200884220ba72107200428020022034104490d0420012802002205280000210420012003417c6a220e3602042001200541046a220a360200200e450d04200a2d0000210920012003417b6a220e3602042001200a41016a220d360200410021050240024020090e020100060b200e4104490d05200a35000121082001200341776a22053602042001200a41056a36020020054104490d05200a350005210c2001200341736a220e3602042001200a41096a220d3602002008200c422086842108410121050b41000d04200e450d04200d2d000021032001200e417f6a3602042001200d41016a360200200241b0186a200110980120022802b018210e20024180166a200241b0186a41047241ac0210e9081a200e411c460d04200241b0186a20024180166a41ac0210e9081a41b002102c2201450d65200b422088a7210a2001200e360200200141046a200241b0186a41ac0210e9081a4103210e0c030b200241c8006a200110ab0120022802480d0520042802002203200228024c2205490d052005417f4c0d620240024020050d00410121060c010b200510322206450d65200428020021030b20032005490d0420062001280200200510e9082103200128020422072005490d1f2001200720056b3602042001200128020020056a3602002003450d052005ad22084220862008842208422088a7210a2008a721074104210e41002105410021040c020b20074104490d042005280002210620012003417a6a22073602042001200541066a3602002007450d0420052d0006210a2001200341796a22043602042001200541076a220e3602004100210702400240200a0e020100060b20044104490d05200535000721082001200341756a220736020420012005410b6a36020020074104490d05200535000b210b2001200341716a220436020420012005410f6a220e3602002008200b422086842108410121070b41000d042004450d04200e2d0000210320012004417f6a3602042001200e41016a360200200241b0186a200110980120022802b018210120024180166a200241b0186a41047241ac0210e9081a2001411c460d04200241b0186a20024180166a41ac0210e9081a41b002102c2205450d6320052001360200200541046a200241b0186a41ac0210e9081a2008422088a721042008a7210a4105210e420021080c010b200241d0006a200110ab0120022802500d032004280200220320022802542205490d032005417f4c0d600240024020050d00410121060c010b200510322206450d63200428020021030b20032005490d0220062001280200200510e9082103200128020422072005490d1c2001200720056b3602042001200128020020056a3602002003450d032005ad2208422086200884220ba72107200428020022034104490d0120012802002205280000210420012003417c6a220e3602042001200541046a220a360200200e450d01200a2d0000210920012003417b6a220e3602042001200a41016a220d360200410021050240024020090e020100030b200e4104490d02200a35000121082001200341776a22053602042001200a41056a36020020054104490d02200a350005210c2001200341736a220e3602042001200a41096a220d3602002008200c422086842108410121050b41000d01200e450d01200d2d000021032001200e417f6a3602042001200d41016a360200200241b0186a200110980120022802b018210e20024180166a200241b0186a41047241ac0210e9081a200e411c460d01200241b0186a20024180166a41ac0210e9081a41b002102c2201450d62200b422088a7210a2001200e360200200141046a200241b0186a41ac0210e9081a4106210e0b200020033a00052000200e3a000420004101360200200041246a20013602002000411c6a2008370200200041186a2005360200200041146a2004360200200041106a200a3602002000410c6a2007360200200041086a2006360200200041286a20024198086a41880210e9081a0c640b2007450d010b2006102e0b2000411c3602000c610b2007450d5c20052d0001210620012003417e6a3602042001200541026a3602000240024002400240024020060e03000103610b200241b0186a2001109a02200241bc186a2802002203450d60200241c4186a2802002105200241c0186a280200210620022802b818210e20022903b018210820024198086a200241c8186a41e40010e9081a200241b4196a2802002104200241b0186a4180016a2802002107200241ac196a280200210a20024180166a200241b8196a41800110e9081a200241b0186a200110f701024020022802b418450d00200241bc186a290200210b20022902b418210c20022802b0182109200241980f6a20024198086a41e40010e9081a20024198126a20024180166a41800110e9081a410121010c040b02402005450d00200541246c21052003210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012005415c6a22050d000b0b02402006450d00200641246c450d002003102e0b02402004450d00200441246c2105200a210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012005415c6a22050d000b0b2007450d60200741246c0d010c600b200241b0186a2001109a02200241bc186a2802002203450d5f200241c4186a2802002105200241c0186a280200210620022802b818210e20022903b018210820024198086a200241c8186a41e40010e9081a200241b4196a2802002104200241b0186a4180016a2802002107200241ac196a280200210a20024180166a200241b8196a41800110e9081a200241b0186a200110f701024020022802b418450d00200241bc186a290200210b20022902b418210c20022802b0182109200241980f6a20024198086a41e40010e9081a20024198126a20024180166a41800110e9081a410221010c030b02402005450d00200541246c21052003210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012005415c6a22050d000b0b02402006450d00200641246c450d002003102e0b02402004450d00200441246c2105200a210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012005415c6a22050d000b0b2007450d5f200741246c450d5f0b200a102e0c5e0b200241b0186a20011095024103210120022d00c0184103460d5d200241b8186a290300210b20022903b018210c20022903c0182108200241980f6a20024198156a41e40010e9081a20024198126a20024198086a41800110e9081a0b200241880b6a200241980f6a41e40010e9081a200241d8106a20024198126a41800110e9081a200041186a200b370200200041106a200c370200200041346a2005360200200041306a20063602002000412c6a2003360200200041286a200e360200200041206a20083702002000410c6a2009360200200041086a200136020020004102360200200041386a200241880b6a41e40010e9081a200041a4016a2004360200200041a0016a20073602002000419c016a200a360200200041a8016a200241d8106a41800110e9081a0c600b02402007450d0020052d0001210620012003417e6a3602042001200541026a36020020060d00200241d8006a200110d9042002290358a70d002002290360210820004103360200200041086a2008370300200041106a200241b0186a41a00210e9081a0c600b2000411c3602000c5f0b02402007450d0020052d0001210620012003417e6a22073602042001200541026a36020002400240024002400240024020060e050001020304060b20074104490d052005280002210620012003417a6a3602042001200541066a36020042002108410121044100210a4200210b4100210e0c040b20024180166a200110930120022d0080164101460d04200428020022044104490d0420024180166a41106a290300210820024188166a290300210c2002419d166a280000210a2002419b166a2f0000210e2002419a166a2d0000210920024198166a2f0100210d200228028416210620022f018216210520022d00811621032001280200220f280000210720012004417c6a3602042001200f41046a3602002002200e3b00eb10200220093a00ea102002200d3b01e8102002200c3703d810200220083703e0102002200a3600ed1020022900df102210422888200241e7106a290000220b421886842108200a4110762109200b422888210b200c421888a72111200c420888a7210f2010420888a7210a200ca721122010a7210e410221040c030b20074104490d032005280002210620012003417a6a3602042001200541066a36020042002108410321044100210a4200210b4100210e4100210d41002107410021010c020b20024180166a200110930120022d0080164101460d02200428020022044104490d0220024190166a290300211020024188166a290300210c2002419d166a28000021092002419b166a2f0000210d2002419a166a2d0000210f20024198166a2f01002111200228028416210620022f018216210520022d00811621032001280200220a280000210720012004417c6a220e3602042001200a41046a220a360200200e450d02200a2d0000210e20012004417b6a3602042001200a41016a3602004100210102400240200e0e020100040b410121010b2002200d3b00ab0f2002200f3a00aa0f200220113b01a80f200220103703a00f200c423888201042088684a7210e200220093600ad0f20094110762109200241ac0f6a330100200241ae0f6a31000042108684210b200c421888a72111200c420888a7210f20022902a40f2108200ca721122010a7210a410421040c010b20074104490d012005280002210620012003417a6a3602042001200541066a36020020022900df10220c422888200241e7106a290000220b421886842108200b422888210b200c420888a7210a20022f00d910210f20022800db10211120022f00ef10210920022d00f110210120022f01f210210d20022802f4102107200ca7210e410521040b2000200d3b0126200020013a0025200020093b00232000200f3b000d200020053b0006200020033a0005200020043a000420004104360200200041286a20073602002000410f6a20113600002000410c6a20123a0000200041086a20063602002000411b6a200b422886200842188884370000200041136a2008422886200aad42088684200ead42ff0183843700002000412c6a200241b0186a41840210e9081a0c5f0b2000411c3602000c5e0b02402007450d0020052d0001210620012003417e6a3602042001200541026a360200024002400240024002400240024020060e0400010203070b20024180166a200110e60120022d0080164105460d0620024180166a41106a290300210b20024188166a2903002108200241a0166a280200210520024198166a290300210c20022802841621062002280280162103200241e8006a200110db0402402002290368a70d00200241e8006a41106a29030021132006ad4220862003ad84211420022903702210422088a721062010a72103410121010c040b200341ff01714102470d062008a7450d062006102e0c060b20024180166a200110e60120022d0080164105460d0520024180166a41106a290300210b200241a0166a280200210520024198166a290300210c20024188166a29030021082002280284162106200228028016210320024198016a200110db04200229039801a70d0420024198016a41106a290300211320022903a001211020024180016a200110db04200229038001a70d0420024180016a41106a290300211520022903880121162006ad4220862003ad8421142010422088a721062010a72103410221010c020b20024180166a200110e60120022d0080164105460d0420024180166a41106a290300210b200241a0166a2203280200210520024198166a290300210c20024180166a41086a220629030021082002280284162104200228028016210720024180166a200110e601024020022d0080164105460d0020024198126a41086a20024180166a41146a29020037030020024198126a41106a2002419c166a280200360200200220024180166a410c6a290200370398122006280200210a2003350200211020022802841621062002280280162103200241b0016a200110db04024020022903b001a70d00200241b0016a41106a290300211720022903b801211820024198086a41146a20024198126a41106a28020036020020024198086a410c6a200241a0126a290300370200200220022903981237029c082002200a360298082004ad4220862007ad84211420024198086a41106a2903002115200229039808211320022903a0082116410321010c030b200341ff01714102470d00200a450d002006102e0b200741ff01714102470d042008a7450d042004102e0c040b20024180166a200110e60120022d0080164105460d0320024180166a41106a290300210b20024188166a2903002108200241a0166a280200210520024198166a290300210c20022802841621062002280280162103200241c8016a200110db0420022903c801a70d01200241c8016a41106a29030021132006ad4220862003ad84211420022903d0012210422088a721062010a72103420021104104210142002116420021150b20004105360200200041e0006a2017370200200041d8006a2018370200200041c8006a2015370200200041c0006a2016370200200041386a20133702002000411c6a200b370200200041146a2008370200200041d0006a20103702002000412c6a2005360200200041246a200c3702002000410c6a2014370200200041086a2001360200200041306a2006ad4220862003ad84370200200041e8006a200241b0186a41c80110e9081a0c600b200341ff01714102470d012008a7450d012006102e0c010b200341ff01714102470d002008a7450d002006102e0b2000411c3602000c5d0b02402007450d0020052d0001210620012003417e6a3602042001200541026a36020020060d00200241e0016a200110ab0120022802e0010d0020022802e4012206200428020041f0006e2205200520064b1bad42f0007e2208422088a70d582008a72205417f4c0d580240024020050d00410421070c010b2005102c2207450d5b0b200541f0006ead21080240024002402006450d0020024180166a41086a210e034020024180166a2001109b022002280284162103200228028016210420024198086a200e41e80010e9081a2003450d0320024198126a20024198086a41e80010e9081a02402008422088220ba722052008a7470d00200541016a220a2005490d5d20054101742209200a200a2009491b220a4104200a41044b1bad42f0007e220b422088a745410274210a200ba721090240024020050d0020024100360280160c010b200241043602881620022007360280162002200541f0006c360284160b200241d8106a2009200a20024180166a107d20022802e010210a20022802d8104101460d0320022802dc1021072008422088220ba72105200a41f0006ead21080b2007200541f0006c6a2205200336020420052004360200200541086a20024198126a41e80010e9081a200b422086200842ffffffff0f83844280808080107c21082006417f6a22060d000b0b2007450d022000200736020420004106360200200041086a2008370200200041106a200241b0186a41a00210e9081a0c5f0b200a0d5b0c590b02402008422088a72201450d002007200141f0006c6a2106200721010340024020012203410c6a2802002205450d0020032802042101200541246c210503400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012005415c6a22050d000b0b200341f0006a21010240200341086a2802002205450d00200541246c450d002003280204102e0b20012006470d000b0b2008a72201450d00200141f0006c450d002007102e0b2000411c3602000c5c0b02402007450d0020052d0001210620012003417e6a22193602042001200541026a3602004100211a410021124107210d0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020060e170001020304056d060708090a0b0c0d0e0f101112131415170b20024180166a200110e60120022d0080164105460d1620024198086a41086a20024194166a29020037030020024198086a41106a2002419c166a29020037030020022002418c166a2902003703980820024180166a41086a28020021092002280284162111200228028016210e200241e8016a200110db0420022903e801a70d1520042802002205450d15200241e8016a41106a290300210c20022903f001210b200128020022032d0000210620012005417f6a3602044101210d2001200341016a3602004100210a02400240024002400240024020060e0505000102031b0b4101210a0c030b4102210a0c020b20024180166a200110930120022d0080164101460d18200241d8106a41106a20024191166a290000370300200241f0106a20024199166a2900002210370300200241e0106a20024189166a290000370300200220022900811622143703d81020022f00eb10200241ed106a2d0000411074722103200241e6106a310000210820022801da10210720022901de10211320022800e710210520022f01ee10211b20022f00f110211c20022800f310211d20022d00f710211e2014a7210f2010a7211f4103210a0c020b4104210a0b0b20024198126a41106a20024198086a41106a29030037030020024198126a41086a20024198086a41086a29030022143703002003ad4228862005ad42088684200842ff01838422084220882110201342208820084220868421082013a7221241807e71211a200229039808211320022d00a212212020022f00a312212120022800a512212220022d00a912212320022f01aa12212420022802ac1221252014a721260c6c0b20024180026a200110db04200229038002a70d15200229038802220b42208820024190026a290300220c422086842108200c4220882110200ba7221241807e71211a4102210d0c6a0b20024198026a200110db04200229039802a70d1420022903a002220b422088200241a8026a290300220c422086842108200c4220882110200ba7221241807e71211a4103210d0c690b4104210d20194104490d132005280002210720012003417a6a3602042001200541066a360200420021080c670b200241b0026a200110ab0120022802b0020d1220022802b40221052002418094ebdc0336028416200220053602801620042802002203450d1220024180166a2005418094ebdc034b4102746a2802002107200128020022052d0000210620012003417f6a3602042001200541016a3602004105210d41002112024020060e026900130b410121120c670b20024180166a200110e5012002280280162207450d11200228028416221241807e71211a20024188166a3502002108420021104106210d0c660b2019450d1020052d0002210620012003417d6a3602042001200541036a3602004100210a02400240024002400240024020060e050500010203160b4101210a0c030b4102210a0c020b20024180166a200110930120022d0080164101460d13200241d8106a41106a20024191166a290000370300200241d8106a41086a20024189166a290000370300200241f0106a220120024199166a29000037030020024198086a41086a200241e6106a29010037030020024198086a41106a200241ee106a2f01003b0100200220022900811622083703d810200220022901de103703980820022801da1021072001290300210b2008a7210f4103210a0c020b4104210a0b0b4108210d200229039808220c42208820024198086a41086a2903002210422086842108200ca7221241807e71211a20104220882110200b423888a7211e200b421888a7211d200b420888a7211c200241a8086a2f0100211b200ba7211f0c660b20024180166a200110e60120022d0080164105460d0f200229028416220b4220882002418c166a290200220c422086842108200ba7221241807e71211a200c4220882110200241a0166a280200210e2002419e166a2f010021272002419d166a2d0000211e20024199166a280000211d20024197166a2f0000211c20024196166a2d0000211f20024194166a2f0100211b20022802801621074109210d0c640b200241b8026a200110ab0120022802b8020d0e20022802bc02210742002108410a210d0c620b200241c0026a200110ab0120022802c0020d0d20022802c402210742002108410b210d0c610b2019450d0c20052d0002210a20012003417d6a3602042001200541036a360200200a41e5004f0d0c42002108410c210d41002112420021100c620b410d210d410021120c600b410e210d410021120c5f0b200241c8026a200110ab01024020022802c802450d0020024100360280160c0a0b20024180166a200120022802cc021092012002280280162207450d09200228028416221241807e71211a20024188166a350200210842002110410f210d0c5e0b20024180166a200110930120022d0080164101460d084110210d200241d8106a41086a220520024180166a41106a290300370300200241d8106a41106a20024180166a41186a290300370300200241d8106a41186a200241a0166a2d00003a0000200220024180166a41086a2903003703d810200428020022034104490d08200228028416210720022f018216210f20022d008116210a20012802002206280000210e20012003417c6a3602042001200641046a36020020022903d810220b4220882005290300220c422086842108200ba7221241807e71211a200c422088211020022f01e810211b20022d00ea10211f20022f00eb10211c20022800ed10211d0c5e0b4111210d410021120c5c0b20194104490d062005280002210720012003417a6a3602042001200541066a36020020024180166a200110e7012002280280162212450d06201241807e71211a2002290284162108420021104112210d0c5b0b20024180166a200110930120022d0080164101460d05200428020022054104490d05200241a0166a310000211020024198166a290300210b20024190166a290300210c20024188166a2903002113200228028416210720022f018216210f20022d008116210a20012802002203280000210e20012005417c6a3602042001200341046a3602002013422088200c422086842108200b422888201042188684a7211d200c42208821102013a7221241807e71211a200b421888a7211c200b421088a7211f200ba7211b4113210d0c5b0b200241d0026a200110db0420022903d002a70d0420022903d802220b422088200241e0026a290300220c422086842108200c4220882110200ba7221241807e71211a4114210d0c590b200241f0026a200110ab0120022802f0020d0320022802f4022107200241e8026a200110ab0120022802e8020d0320022802ec02221241807e71211a4115210d0c580b20024180166a200110930120022d0080164101460d02200428020022054104490d0220024190166a290300210b20024188166a290300210c2002419d166a280000211d2002419b166a2f0000211c2002419a166a2d0000211f20024198166a2f0100211b200228028416210720022f018216210f20022d008116210a20012802002203280000210e20012005417c6a3602042001200341046a360200200c422088200b422086842108200b4220882110200ca7221241807e71211a4116210d0c580b20024180166a200110e5012002280280162207450d01200229028416220b4220882108200ba7221241807e71211a420021104117210d0c560b200e41ff01714102470d002009450d002011102e0b2000411c3602000c5b0b02402007450d0020012003417e6a3602042001200541026a3602000b2000411c3602000c5a0b02402007450d0020052d0001210620012003417e6a3602042001200541026a3602004100210502400240024020060e020001030b200241b0186a200110990320022d00b0184101460d0220024180166a200241b0186a41017241c00110e9081a200241f8026a200110ab0120022802f8020d022004280200220620022802fc022203490d022003417f4c0d570240024020030d00410121050c010b200310322205450d5a200428020021060b20062003490d0120052001280200200310e9082106200128020422072003490d1d2001200720036b3602042001200128020020036a3602002006450d022003ad2208422086200884210820024198086a20024180166a41c00110e9081a0b20024198126a20024198086a41c00110e9081a200041086a20083702002000200536020420004109360200200041106a20024198126a41c00110e9081a200041d0016a200241d8106a41e00010e9081a0c5b0b2005102e0b2000411c3602000c590b02402007450d0020052d0001210620012003417e6a22073602042001200541026a360200024002400240024020060e03000102040b200241b0186a200110c80620022903b81822084202510d0320022802bc18210520022802b418210320022802b018210620024198086a200241c0186a41e40010e9081a200241a8196a280200210720022802ac19210420022802a419210a20024180166a200241b0186a4180016a41800110e9081a200241b0186a200110f70120022802b418450d032008a72101200241bc186a290200210b20022802b018210e20022902b418210c200241880b6a20024198086a41e40010e9081a20024198126a20024180166a41800110e9081a200c422088200b422086842108200b422088210b200ca721094101210d0c020b200241b0186a200110c80620022903b81822084202510d0220022802bc18210520022802b418210320022802b0182106200241980f6a200241c0186a41e40010e9081a200241a8196a280200210720022802ac19210420022802a419210a20024180166a200241b0186a4180016a41800110e9081a200241b0186a200110f70120022802b418450d022008a72101200241bc186a290200210b20022802b018210e20022902b418210c20024198156a200241980f6a41e40010e9081a20024198086a20024180166a41800110e9081a200241880b6a20024198156a41e40010e9081a20024198126a20024198086a41800110e9081a200c422088200b422086842108200b422088210b200ca721094102210d0c010b20074104490d012005280002210e20012003417a6a22063602042001200541066a36020020064104490d01200528000621092001200341766a36020420012005410a6a360200200241880b6a20024180166a41e40010e9081a20024198126a200241b0186a41800110e9081a4103210d0b200241a00a6a200241880b6a41e40010e9081a200241d8106a20024198126a41800110e9081a2000411c6a200b3e0200200041146a20083702002000412c6a2005360200200041286a2001360200200041246a2003360200200041206a2006360200200041106a20093602002000410c6a200e360200200041086a200d3602002000410a360200200041306a200241a00a6a41e40010e9081a2000419c016a200436020020004198016a200736020020004194016a200a360200200041a0016a200241d8106a41800110e9081a200041a8026a200241e80e6a41086a290300370300200041a0026a20022903e80e3703000c590b2000411c3602000c580b2007450d4e20052d0001210620012003417e6a22073602042001200541026a36020020060d4e20074104490d4e2005280002210620012003417a6a3602042001200541066a36020020024190036a200110ab012002280290030d4e200428020022032002280294032205490d4e2005417f4c0d520240024020050d00410121070c010b200510322207450d55200428020021030b0240024020032005490d0020072001280200200510e908210e2001280204220320054f0d012005200341b8b2c0001056000b2007102e0c4f0b2001200320056b3602042001200128020020056a360200200e450d4e2005ad2208422086200884211020024188036a200110ab010240024002402002280288030d00200228028c03220a2004280200410c6e22052005200a4b1bad420c7e2208422088a70d552008a72205417f4c0d550240024020050d00410421090c010b2005102c2209450d580b2005410c6ead21080240024002400240200a450d00034020024180036a200110ab012002280280030d04200428020022032002280284032205490d042005417f4c0d5a0240024020050d00410121070c010b200510322207450d5d200428020021030b20032005490d0320072001280200200510e9082107200128020422032005490d1f2001200320056b3602042001200128020020056a3602002007450d0402402008422088220ba722032008a7470d00200341016a220d2003490d5b2003410174220f200d200d200f491b220d4104200d41044b1bad420c7e220b422088a745410274210d200ba7210f0240024020030d0020024100360298080c010b200241043602a008200220093602980820022003410c6c36029c080b20024198126a200f200d20024198086a107d20022802a012210d2002280298124101460d03200228029c1221092008422088220ba72103200d410c6ead21080b20092003410c6c6a22032005ad220c422086200c8437020420032007360200200b422086200842ffffffff0f83844280808080107c2108200a417f6a220a0d000b0b2009450d032002200936028816200428020021052002200837028c1620022010370380162010a7210320054104490d0420012802002207280000210a20012005417c6a22043602042001200741046a36020020044104490d042007280004210d2001200541786a22043602042001200741086a36020020044104490d04200728000821092001200541746a36020420012007410c6a36020020024180166a410c6a2902002108200229028416210b20024180166a200110a701200b422088a721042008422088a721012008a7210720022d0080164101470d0502402003450d00200e102e0b02402001450d002001410c6c21052004210103400240200141046a280200450d002001280200102e0b2001410c6a2101200541746a22050d000b0b2007450d542007410c6c450d542004102e0c540b200d0d590c570b2007102e0b02402008422088a72201450d002001410c6c21052009210103400240200141046a280200450d002001280200102e0b2001410c6a2101200541746a22050d000b0b2008a72201450d002001410c6c450d002009102e0b2010a7450d50200e102e0c500b2008422088a7210102402003450d00200e102e0b2008a7210302402001450d002001410c6c21052009210103400240200141046a280200450d002001280200102e0b2001410c6a2101200541746a22050d000b0b2003450d4f2003410c6c450d4f2009102e0c4f0b200e450d4e200241b9166a290000210820024180166a41316a290000210c200241ad166a2800002105200241ab166a2f0000210f200241a6166a280100211120024180166a41246a2f01002112200241a3166a2d0000211b200241a1166a2f0000211c20024199166a290000211020024195166a280000211d20024191166a280000211f2002418d166a280000211e20024180166a410b6a2f000021272002418a166a2d00002126200228018616212020022f018416212120022d008316212220022f00811621232000200241aa166a2d00003a00552000201b3a004e200020263a0035200020223a002e200020063602042000410b360200200041e4006a2008370200200041dc006a200c370200200041d8006a2005360200200041d6006a200f3b0100200041d1006a2011360000200041cf006a20123b0000200041cc006a201c3b0100200041c4006a2010370200200041c0006a201d3602002000413c6a201f360200200041386a201e360200200041366a20273b0100200041316a20203600002000412f6a20213b00002000412c6a20233b0100200041286a2009360200200041246a200d360200200041206a200a3602002000411c6a2001360200200041186a2007360200200041146a2004360200200041106a200ba73602002000410c6a2003360200200041086a200e360200200041ec006a200241b0186a41c40110e9081a0c570b02402007450d0020012003417e6a3602042001200541026a3602000b2000411c3602000c560b2007450d4a20052d0001210720012003417e6a22063602042001200541026a360200410d211b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020070e19000102030405060708090a0b640c0d0e0f1011121314151617630b41002107200241003a00a0162003417d6a21030240034020062007460d0120024180166a20076a200520076a220441026a2d00003a0000200120033602042001200441036a3602002002200741016a22043a00a0162003417f6a21032004210720044120470d000b200441ff01714120490d63200228029c16211120022f019a16210f20022d009916211220022f009716210a200229008f162108200228008b16211c200228008716211d200228008316210e20022f008116210920022d008016210d20024198036a200110db0420022802980322010d63411a410120011b211b200241a8036a290300210c20022903a003210b0c640b200741ff0171450d62200241003a00a0160c620b200241b8036a200110ab0120022802b8030d6120022802bc03210e200241b0036a200110ab0120022802b0030d6120022802b403211d4102211b0c620b200241c0036a200110ab0120022802c0030d6020022802c403210e20024180166a200110b10420022d0080164102460d60200241a0166a290300210b2002419c166a280200211e2002419a166a2f0100212720024199166a2d0000211f20024195166a280000211120024193166a2f0000210f20024192166a2d0000211220024190166a2f0100210a20024188166a2903002108200228028416211c200228028016211d4200210c4103211b0c610b4104211b20064104490d5f2005280002210e20012003417a6a3602042001200541066a3602000c600b41002107200241003a00a0162003417d6a21030240034020062007460d0120024180166a20076a200520076a220441026a2d00003a0000200120033602042001200441036a3602002002200741016a22043a00a0162003417f6a21032004210720044120470d000b200441ff01714120490d5f200228029c16211120022f019a16210f20022d009916211220022f009716210a200229008f162108200228008b16211c200228008716211d200228008316210e20022f008116210920022d008016210d4105211b0c600b200741ff0171450d5e200241003a00a0160c5e0b41002107200241003a00a0162003417d6a21030240034020062007460d0120024180166a20076a200520076a220441026a2d00003a0000200120033602042001200441036a3602002002200741016a22043a00a0162003417f6a21032004210720044120470d000b200441ff01714120490d5e200228029c16211120022f019a16210f20022d009916211220022f009716210a200229008f162108200228008b16211c200228008716211d200228008316210e20022f008116210920022d008016210d4106211b0c5f0b200741ff0171450d5d200241003a00a0160c5d0b41002107200241003a00a0162003417d6a21030240034020062007460d0120024180166a20076a200520076a220441026a2d00003a0000200120033602042001200441036a3602002002200741016a22043a00a0162003417f6a21032004210720044120470d000b200441ff01714120490d5d200228029c16211120022f019a16210f20022d009916211220022f009716210a200229008f162108200228008b16211c200228008716211d200228008316210e20022f008116210920022d008016210d4107211b0c5e0b200741ff0171450d5c200241003a00a0160c5c0b41002107200241003a00a0162006411f2006411f491b20056a41036a211b417d210a0240034020062007460d0120024180166a20076a200520076a220441026a2d00003a000020012003200a6a3602042001200441036a3602002002200741016a22043a00a016200a417f6a210a2004210720044120470d000b200441ff01714120490d5c200320046b2203417e6a4104490d5c200228029c16211120022f019a16210f20022d009916211220022f009716210a200229008f162108200228008b16211c200228008716211d200228008316210e20022f008116210920022d008016210d201b280000211e20012003417a6a22063602042001200520046a220541066a220736020020064104490d5c2007350000210b2001200341766a36020420012005410a6a3602004200210c4108211b0c5d0b200741ff0171450d5b200241003a00a0160c5b0b41002107200241003a00a0162003417d6a21030240034020062007460d0120024180166a20076a200520076a220441026a2d00003a0000200120033602042001200441036a3602002002200741016a22043a00a0162003417f6a21032004210720044120470d000b200441ff01714120490d5b200228029c16211120022f019a16210f20022d009916211220022f009716210a200229008f162108200228008b16211c200228008716211d200228008316210e20022f008116210920022d008016210d4109211b0c5c0b200741ff0171450d5a200241003a00a0160c5a0b200241c8036a200110ab0120022802c8030d5920022802cc03210e410a211b0c5a0b20064104490d582005280002210e20012003417a6a3602042001200541066a360200410b211b0c590b20024180166a200110930120022d0080164101460d5720042802002203450d572002419d166a28000021112002419b166a2f0000210f2002419a166a2d0000211220024198166a2f0100210a20024190166a29030021082002418c166a280200211c20024188166a280200211d200228028416210e20022f018216210920022d008116210d200128020022052d0000210620012003417f6a22073602042001200541016a3602004100211f024002400240024002400240024020060e07060500010203045e0b4102211f0c050b4103211f0c040b4104211f0c030b4105211f0c020b4106211f0c010b4101211f0b20074110490d57200541096a290000210c2005290001210b20012003416f6a3602042001200541116a360200410c211b0c580b410e211b0c570b200241d0036a200110ab0120022802d0030d552004280200220320022802d4032205490d552005417f4c0d5b0240024020050d004101210e0c010b20051032220e450d5e200428020021030b20032005490d0a200e2001280200200510e9082103200128020422062005490d1f2001200620056b3602042001200128020020056a3602002003450d552005ad22084220862008842208422088a7211c2008a7211d410f211b0c560b200241d8036a200110ab0120022802d8030d542004280200220320022802dc032205490d542005417f4c0d5a0240024020050d004101210e0c010b20051032220e450d5d200428020021030b20032005490d09200e2001280200200510e9082103200128020422062005490d152001200620056b3602042001200128020020056a3602002003450d542005ad22084220862008842208422088a7211c2008a7211d4110211b0c550b200241e0036a200110ab0120022802e0030d532004280200220320022802e4032205490d532005417f4c0d590240024020050d004101210e0c010b20051032220e450d5c200428020021030b20032005490d08200e2001280200200510e9082103200128020422062005490d132001200620056b3602042001200128020020056a3602002003450d532005ad22084220862008842208422088a7211c2008a7211d4111211b0c540b200241e8036a200110ab0120022802e8030d522004280200220320022802ec032205490d522005417f4c0d580240024020050d004101210e0c010b20051032220e450d5b200428020021030b20032005490d07200e2001280200200510e9082103200128020422062005490d112001200620056b3602042001200128020020056a3602002003450d522005ad22084220862008842208422088a7211c2008a7211d4112211b0c530b41002107200241003a00a0162003417d6a21030240034020062007460d0120024180166a20076a200520076a220441026a2d00003a0000200120033602042001200441036a3602002002200741016a22043a00a0162003417f6a21032004210720044120470d000b200441ff01714120490d52200229008716210b2002418f166a2900002108200228029c16211120022f019a16210f20022d009916211220022f009716210a200228008316210e20022f008116210920022d008016210d200241f0036a200110ab0120022802f00322010d52200b422088a7211c200ba7211d411a411320011b211b20022802f403211e0c530b200741ff0171450d51200241003a00a0160c510b20024180166a200110930120022d0080164101460d5020024188166a290300220b422088a7211c20024190166a29030021082002419d166a28000021112002419b166a2f0000210f2002419a166a2d0000211220024198166a2f0100210a200228028416210e20022f018216210920022d008116210d200ba7211d4114211b0c510b20064104490d4f2005280002210e20012003417a6a3602042001200541066a3602004115211b0c500b20024180166a200110930120022d0080164101460d4e200428020022054104490d4e20024190166a290300210820024188166a290300210b2002419d166a28000021112002419b166a2f0000210f2002419a166a2d0000211220024198166a2f0100210a200228028416210e20022f018216210920022d008116210d20012802002203280000211e20012005417c6a3602042001200341046a360200200b422088a7211c200ba7211d4116211b0c4f0b41002107200241003a00a0162006411f2006411f491b20056a41036a210f417d21040240034020062007460d0120024180166a20076a200520076a220a41026a2d00003a00002001200320046a3602042001200a41036a3602002002200741016a220a3a00a0162004417f6a2104200a2107200a4120460d4e0c000b0b200741ff0171450d4d200241003a00a0160c4d0b41002107200241003a00a016417d21040240034020062007460d0120024180166a20076a200520076a220a41026a2d00003a00002001200320046a3602042001200a41036a3602002002200741016a220a3a00a0162004417f6a2104200a2107200a4120460d4c0c000b0b200741ff0171450d4c200241003a00a0160c4c0b200241f8036a200110ab0120022802f8030d4b20022802fc03210e4119211b0c4c0b200e102e0c4a0b20024198086a200110c906024020022d0098084107460d0020024198126a41306a20024198086a41306a290300220837030020024198126a41286a20024198086a41286a290300220b37030020024198126a41206a20024198086a41206a290300220c37030020024198126a41186a20024198086a41186a290300221037030020024180166a410c6a20024198086a41086a29030037020020024180166a41146a20024198086a41106a29030037020020024180166a411c6a201037020020024180166a41246a200c37020020024180166a412c6a200b37020020024180166a41346a20083702002002200229039808370284162000410e36020020002002290280163702042000410c6a20024180166a41086a290200370200200041146a20024180166a41106a2902003702002000411c6a20024180166a41186a290200370200200041246a20024180166a41206a2902003702002000412c6a20024180166a41286a290200370200200041346a20024180166a41306a2902003702002000413c6a200241b8166a280200360200200041c0006a200241b0186a41f00110e9081a0c550b2000411c3602000c540b2007450d4520052d0001210620012003417e6a22073602042001200541026a36020002400240024002400240024002400240024020060e060001020304054e0b20024180046a200110ab010240200228028004450d0020024100360280160c4e0b20024180166a20012002280284041092012002280280162206450d4d200228028416210e20042802002205450d0520024188166a2802002109200128020022072d0000210a20012005417f6a22033602042001200741016a3602000240024002400240200a0e020201000b200241023a0098120c090b20024180166a2001109301024020022d0080164101470d00200241023a0098120c090b200241d8106a41186a20024199166a290000370300200241e8106a20024191166a290000370300200241e0106a20024189166a290000370300200220022900811622083703d810200241e7106a290000210b20022900df10210c20022f00ef10210720022d00f110210520022f01f210210320022802f410210a20022f00d910210d200220022800db10220f36029c122002200d3b019a12200220083c009912200241013a0098122002200a36009d08200220033b009b08200220053a009a08200220073b019808200f411876210a200428020021030c010b200241003a00981220022d009f12210a0b20034104490d0620022d009a12210d20022f019812210f2002290099082110200228009b1221052002200c3700990f200241a10f6a200b37000020012802002204350000210820012003417c6a3602042001200441046a3602002002200a3a00980f200220073a00a90f200c423888200b42088684a72104200f200d4110747222074180feff0771410876210a2010423888a721012010421888a7210d2010420888a7210f200c421888a72111200b421888a7211c20022802980f210320022f01a80f21122010a7211b4101211d0c4c0b200110cb042205450d4c20024188046a200110ab012002280288040d06200228028c0421034102211d420021084100211c410021090c4b0b20024198046a200110ab012002280298040d4b200228029c042105200110cb042203450d4b20024190046a200110ab0102402002280290040d0020022802940421114103211d420021084100211c410021090c490b2003108b022003102e0c4b0b41002106200241003a00a0162003417d6a21030240034020072006460d0120024180166a20066a200520066a220a41026a2d00003a0000200120033602042001200a41036a3602002002200641016a220a3a00a0162003417f6a2103200a2106200a4120460d4a0c000b0b200641ff0171450d4a200241003a00a0160c4a0b41002106200241003a00a0162003417d6a21030240034020072006460d0120024180166a20066a200520066a220441026a2d00003a0000200120033602042001200441036a3602002002200641016a22043a00a0162003417f6a21032004210620044120470d000b200441ff01714120490d4a200229009716210b2002419f166a31000021132002418f166a290000210c2002290087162110200228008316210520022f008116210a20022d0080162107200241c0046a200110ab0120022802c0040d4a20022802c4042106200241b0046a200110d90420022903b004a70d4a20022903b8042108200241a8046a200110ab0120022802a8040d4a200b422888201342188684a7210d200b421888a7210f200b421088a7211b200ba7211220022802ac04210e200c422088a7211c2010422088a72111200ca721042010a721034105211d0c470b200641ff0171450d49200241003a00a0160c490b41002106200241003a00a0162003417d6a21030240034020072006460d0120024180166a20066a200520066a220441026a2d00003a0000200120033602042001200441036a3602002002200641016a22043a00a0162003417f6a21032004210620044120460d460c000b0b200641ff0171450d48200241003a00a0160c480b200241023a0098120b200e41ffffff3f71450d462006102e0c460b2005108b022005102e0c450b2007450d3f20052d0001210620012003417e6a22113602044102210d2001200541026a3602000240024002400240024020060e06004301020304440b200241e0046a200110ab01024020022802e004450d0020024100360280160c440b20024180166a200120022802e4041092012002280280162207450d43200229028416210b200241c8046a200110db04024020022903c804a70d0020022903d0042208423888200241d8046a290300220c42088684a7210f200c421888210c200b422088a7210a200ba7210e4101210d0c430b200b42ffffff3f83500d432007102e0c430b200241e8046a200110ab0120022802e8040d4220022802ec04210720023500eb10200241ef106a31000042208684210c20023502e010200241e4106a330100200241e6106a3100004210868442208684210820022903f010210b20022800e710210f20022802dc10210a4103210d0c410b2011450d4120052d0002210620012003417d6a3602042001200541036a3602004104210d4100210f4200210c410021070240024020060e03420001430b410121070c410b200241f0046a200110ab0120022802f0040d4120022802f404210e410221070c400b20024180166a200110e60120022d0080164105460d4020024198086a41086a20024194166a290200370300200241a8086a2002419c166a29020037030020022002418c166a2902003703980820024180166a41086a280200210a200228028416210e2002280280162107024020042802002205450d00200128020022032d0000210620012005417f6a3602042001200341016a360200410021090240024020060e020100020b410121090b2002290398082208423888200241a0086a290300220b42088684a7210f200b421888210c200241a8086a290300210b4105210d0c400b200741ff01714102470d40200a450d40200e102e0c400b20114104490d3f2005280002210720012003417a6a22063602044106210d2001200541066a36020020064104490d3f2005280006210e2001200341766a36020420012005410a6a3602004100210f4200210c0c3e0b2007450d3c20052d0001210620012003417e6a3602042001200541026a3602004107210502400240024002400240024020060e0700010203040541420b20024180166a20011093014101210520022d0080164101460d4120024190166a290300220b422088a7210920024188166a29030021082002419d166a28000021262002419b166a2f000021122002419a166a2d0000212020024198166a2f0100210f200228028416210320022f018216210720022d0081162104200ba7210d0c400b20024180166a200110930120022d0080164101460d40200241d8106a41186a200241a0166a2d00003a0000200241d8106a41106a20024180166a41186a290300220b37030020024180166a41106a290300220c422088a7210920024188166a2903002108200228028416210320022f018216210720022d008116210420022800ed10212620022f00eb10211220022d00ea102120200ba7210f200ca7210d410221050c3f0b20024180166a200110930120022d0080164101460d3f200241980f6a41086a220520024180166a41106a2206290300370300200241980f6a41106a20024180166a41186a220a290300370300200241980f6a41186a220e200241a0166a2d00003a0000200220024180166a41086a220d2903003703980f200228028416210320022f018216210720022d008116210420024180166a200110930120022d0080164101460d3f20022903a80f2210422888200e31000042188684a721262010421888a721122010421088a7212020052903002213422088a721092006290300210c200d290300210b2002419d166a280000211c2002419b166a2f0000211b2002419a166a2d0000211d200a2f01002111200228028416211f20022f018216211e20022d008116212720022903980f21082010a7210f2013a7210d410321050c3e0b200241f8046a200110ab01024020022802f804450d0020024100360298080c3f0b20024198086a200120022802fc041092012002280298082203450d3e200229029c0821082002418c166a290200210c200229028416210b20022d009c12212720022f009d12211e20022f019416211120022d009616211d20022f009716211b200228009916211c20022d009d16210e20022f019e16210a41042105410021094100210d0c3d0b20024180166a200110930120022d0080164101460d3d20024190166a290300220b422088a7210920024188166a29030021082002419d166a28000021262002419b166a2f000021122002419a166a2d0000212020024198166a2f0100210f200228028416210320022f018216210720022d0081162104200ba7210d410521050c3c0b20024180166a200110930120022d0080164101460d3c200241f0106a20024199166a290000370300200241e8106a20024191166a290000370300200241e0106a20024189166a2900003703002002200229008116220b3703d81020022f00d910210720022800db10210320022900df10210820022800e710210d20022800eb10210920022f00ef10210f20022d00f110212020022f01f210211220022802f4102126200ba72104410621050c3b0b02402007450d0020052d0001210620012003417e6a3602042001200541026a3602000240024002400240024020060e03000102050b20024180056a200110db04200229038005a70d0420024190056a2903002108200229038805210b20024180166a200110e60120022d0080164105460d042002290380162214422088a7210120024190166a290300210c20024188166a2903002110200241a0166a280200210520024198166a29030021132014a72103410121060c030b20024198056a200110ab0120022802980522010d034104410220011b2106200228029c0521030c010b200241a0056a200110ab0120022802a00522010d024104410320011b210620022802a40521030b0b20004112360200200041386a2008370200200041306a200b3702002000411c6a200c370200200041146a20103702002000412c6a2005360200200041246a2013370200200041106a20013602002000410c6a2003360200200041086a2006360200200041c0006a200241b0186a41f00110e9081a0c510b2000411c3602000c500b2007450d3820052d0001210620012003417e6a22073602042001200541026a360200024002400240024002400240024020060e0500010203043f0b20024180166a200110930120022d0080164101460d3e20024190166a2204290300210820024188166a2212290300210b2002419d166a220928000021072002419b166a220d2f0000210a2002419a166a220f2d0000210e20024180166a41186a22112f0100211b200228028416210520022f018216210620022d008116210320024180166a200110a80120022d0080164101460d3e2002200b3703d810200220073600ed102002200a3b00eb102002200e3a00ea102002201b3b01e810200220083703e010200241b0166a2903002113200241a8166a2903002110200241c0166a2f0100211b200241bc166a280200211c200241b8166a280200211d200241a4166a2802002107200241a2166a2f0100210a200241a1166a2d0000210e20092800002109200d2f0000210d200f2d0000210f20112f010021112004290300210c2002418c166a280200211f201228020021122002350081162002330085162002310087164210868442208684420886200241d8106a41186a3100008421142008423088a721012008422888a7210420022903e8102118410121270c3c0b200241003a0094162007450d3d20052d0002210620012003417d6a22073602042001200541036a360200200241013a009416200220063a00801620070d1a0c3c0b20024180166a200110930120022d0080164101460d3c200241980f6a41086a20024180166a41106a2212290300370300200241980f6a41106a20024180166a41186a2211290300370300200241980f6a41186a200241a0166a2d00003a0000200220024180166a41086a221e2903003703980f200228028416210520022f018216210620022d008116210320024180166a200110a80120022d0080164101460d3c200241b0166a2903002113200241a8166a2903002110200241c0166a2f0100211b200241bc166a280200211c200241b8166a280200211d200241a4166a2802002107200241a2166a2f0100210a200241a1166a2d0000210e2002419d166a28000021092002419b166a2f0000210d2002419a166a2d0000210f20112f010021112012290300210c2002418c166a280200211f201e28020021122002350081162108200233008516210b2002310087162114200241a8056a200110ab0120022802a8050d3c2004280200222620022802ac052227490d3c2027417f4c0d4e0240024020270d004101211e0c010b20271032221e450d51200428020021260b20262027490d02201e2001280200202710e9082104200128020422262027490d112001202620276b3602042001200128020020276a3602002004450d3c2008200b20144210868442208684420886200241b00f6a3100008421142027ad22084220862008842217422088a72121200241a00f6a2903002208423088a721012008422888a7210420022903a80f211820022903980f210b2017a72120410321270c3a0b200241b0056a200110ab0120022802b0050d3b2004280200220620022802b4052203490d3b2003417f4c0d4d0240024020030d00410121050c010b200310322205450d50200428020021060b20062003490d0220052001280200200310e9082106200128020422072003490d0f2001200720036b3602042001200128020020036a3602002006450d3b2003ad2208422086200884210b410421270c390b200241003a0094162007450d3a20052d0002210620012003417d6a22073602042001200541036a360200200241013a009416200220063a00801620070d160c360b201e102e0c390b2005102e0c380b02402007450d0020052d0001210620012003417e6a3602042001200541026a3602004101210e024002400240024002400240024020060e0403000102070b20024180166a200110e60120022d0080164105460d06200229038016220b422088a7210520024190166a290300211020024188166a2903002108200241a0166a280200210720024198166a290300210c200ba721034102210e0c020b20024180166a200110e60120022d00801622034105460d0520024198126a41086a20024194166a29020037030020024198126a41106a2002419c166a28020036020020022002418c166a2902003703981220024180166a41086a280200210e20022802841621050240200428020022044110490d0020022d008316210920022f008116210d200241a0166a28020021072001280200220641086a290000210b200629000021132001200641106a3602002001200441706a220a360204200a4110490d00200641186a2900002114200629001021182001200441606a220a3602042001200641206a360200200a4104490d002006280020210a20012004415c6a3602042001200641246a360200200241ac086a200241a8126a280200360200200241a4086a20024198126a41086a2903003702002002200e36029808200220022903981237029c08200d200941107472410874200372210320024198086a41086a2903002110200229039808210820022903a808210c420021154103210e420021280c020b20034102470d05200e0d040c050b20024180166a200110e60120022d0080164105460d0420024180166a41106a220a2903002110200241a0166a220e280200210720024198166a2209290300210c20024188166a220629030021082002280284162105200228028016210320024180166a200110e60120022d0080164105460d022006290300210b200228028416210f200228028016210d200428020022044110490d01200a2903002118200e280200210a200929030021142001280200220641086a2900002117200629000021132001200641106a3602002001200441706a220e360204200e4110490d01200641186a2900002116200629001021292001200441606a22093602042001200641206a3602004104210e20094104490d012006280020210920012004415c6a3602042001200641246a36020020022009360290162017422086201342208884212820134220862115200fad422086200dad8421132002202937038016200228028416210d200229039016212a2029a721090b20004114360200200041f8006a202a370200200041f0006a2016370200200041dc006a20283e0200200041d4006a2015370200200041c0006a2018370200200041386a200b3702002000411c6a2010370200200041146a2008370200200041ec006a200d360200200041e8006a2009360200200041e0006a2017370200200041d0006a200a360200200041c8006a2014370200200041306a20133702002000412c6a2007360200200041246a200c370200200041086a200e3602002000410c6a2005ad4220862003ad8437020020004180016a200241b0186a41b00110e9081a0c520b200d41ff01714102470d00200ba7450d00200f102e0b200341ff01714102470d012008a7450d010b2005102e0b2000411c3602000c4e0b20024180166a200110ca06024020022f0180164104460d0020024198086a41086a20024180166a41086a29030022083703002002200229038016220b37039808200041153602002000200b3702042000410c6a2008370200200041146a200241b0186a419c0210e9081a0c4e0b2000411c3602000c4d0b2007450d2f20052d0001210720012003417e6a222b3602042001200541026a3602004104210e0240024020070e0f000126282524232221201f1e1d1c1b310b20024180166a20011093014101210e20022d0080164101460d30200241800e6a41086a200241a00a6a41086a280000360200200241fc0d6a41026a200241e80e6a41026a2d00003a0000200220022900a00a3703800e200220022f00e80e3b01fc0d20024180166a41106a290300210b20024180166a41086a29030021082002419d166a280000210f2002419b166a2f000021122002419a166a2d0000211b20024180166a41186a2f01002111200228028416210620022f018216212c20022d008116212d200241e00d6a41106a20024198086a41106a290000370300200241e00d6a41086a20024198086a41086a29000037030020022002290098083703e00d200241dc0d6a41026a200241b80e6a41026a2d00003a0000200220022f00b80e3b01dc0d200241c00d6a41106a20024198126a41106a290000370300200241c00d6a41086a20024198126a41086a29000037030020022002290098123703c00d200241bc0d6a41026a200241900e6a41026a2d00003a0000200220022f00900e3b01bc0d200241a00d6a41106a200241d8106a41106a290000370300200241a00d6a41086a200241d8106a41086a290000370300200220022900d8103703a00d2002419c0d6a41026a200241a0146a41026a2d00003a0000200220022f00a0143b019c0d200241800d6a41106a200241980f6a41106a290000370300200241800d6a41086a200241980f6a41086a290000370300200220022900980f3703800d20024198156a41206a200241b0186a41206a28000036020020024198156a41186a200241b0186a41186a29000037030020024198156a41106a200241b0186a41106a29000037030020024198156a41086a200241b0186a41086a290000370300200220022900b018370398150c270b200241b8056a200110ab0120022802b8050d2f20022802bc052207200428020041c8006e2205200520074b1bad42c8007e2208422088a70d472008a72205417f4c0d470240024020050d00410421060c010b2005102c2206450d4a0b200541c8006ead210802400240024002402007450d0020024180166a410c6a211c20024180166a410172211e034020024180166a200110ec0302400240024020022d00801622034106460d00200241a0146a41026a220e201e41026a2d00003a0000200241a00a6a41086a2209201c41086a290200370300200241a00a6a41106a220d201c41106a2902003703002002201e2f00003b01a0142002201c2902003703a00a200228028416210a2002280288162105200241b0186a200110ec0320022d00b0184106470d0120034101470d002005450d00200a102e0b410621030c010b200241b4146a41026a200e2d00003a0000200241e80e6a41086a2009290300370300200241e80e6a41106a200d29030037030020024198086a41086a200241b0186a41086a29030037030020024198086a41106a200241b0186a41106a29030037030020024198086a41186a200241b0186a41186a29030037030020024198086a41206a200241b0186a41206a280200360200200220022f01a0143b01b414200220022903a00a3703e80e200220022903b01837039808200a211d2005211f0b200241b0146a41026a2205200241b4146a41026a2d00003a0000200241b80e6a41086a220a200241e80e6a41086a290300370300200241b80e6a41106a220e200241e80e6a41106a29030037030020024198126a41086a220920024198086a41086a29030037030020024198126a41106a220d20024198086a41106a29030037030020024198126a41186a220f20024198086a41186a29030037030020024198126a41206a221120024198086a41206a280200360200200220022f01b4143b01b014200220022903e80e3703b80e20022002290398083703981220034106460d03200241ac146a41026a221220052d00003a0000200241900e6a41086a221b200a290300370300200241900e6a41106a220a200e290300370300200241d8106a41086a220e2009290300370300200241d8106a41106a2209200d290300370300200241d8106a41186a220d200f290300370300200241d8106a41206a220f2011280200360200200220022f01b0143b01ac14200220022903b80e3703900e20022002290398123703d81002402008422088220ba722052008a7470d00200541016a22112005490d4d20054101742227201120112027491b22114104201141044b1bad42c8007e220b422088a7454102742111200ba721270240024020050d00200241003602b0180c010b200241043602b818200220063602b0182002200541c8006c3602b4180b20024180166a20272011200241b0186a107d20022802881621112002280280164101460d0320022802841621062008422088220ba72105201141c8006ead21080b2006200541c8006c6a220520033a0000200541086a201f360000200541046a201d360000200541036a20122d00003a0000200520022f01ac143b00012005410c6a20022903900e370000200541146a201b2903003700002005411c6a200a290300370000200541346a20092903003700002005412c6a200e2903003700002005413c6a200d290300370000200541246a20022903d810370000200541c4006a200f280200360000200b422086200842ffffffff0f83844280808080107c21082007417f6a22070d000b0b2006450d32200241b0186a200110ec0320022d00b0184106460d30200241ec0e6a200241bc186a22032d00003a00002002200241b0186a41086a22072802003602e80e200241bd186a280000210f200241c1186a2d0000210d200241c2186a2f01002109200241c4186a220e280200210a200241c8186a22112903002114200241d0186a2212350200210b20022802b418212c20022802b0182105200241b0186a200110ec0320022d00b0184106460d2f200241a00a6a41086a2012280200360200200220112903003703a00a200e280200211d2003290200210c2007280200210720022802b418212d20022802b0182103200241b0186a200110ec0320022d00b018221c4106460d2e200241b4146a41026a20022d00b3183a0000200241d8106a41086a200241c4186a220e290200370300200241d8106a41106a200241cc186a2211290200370300200220022f00b1183b01b4142002200241bc186a22122902003703d810200241b0186a41086a221b280200211f20022802b418211e200241b0186a200110ec0320022d00b01822274106460d2d200241a0146a41026a20022d00b3183a000020024198126a41086a200e29020037030020024198126a41106a2011290200370300200220022f00b1183b01a0142002201229020037039812201b280200212620022802b4182120200241b0186a200110ec0320022d00b01822214106460d2c200241920e6a20022d00b3183a000020024198086a41086a200241c4186a290200370300200241a8086a200241cc186a290200370300200220022f00b1183b01900e2002200241bc186a29020037039808200241b0186a41086a280200212220022802b41821232004280200220e450d2b200128020022042d000021112001200e417f6a22123602042001200441016a3602004100212b420021104100211920110e0228022b0b20110d4b0c490b02402008422088a72201450d002006200141c8006c6a2105200621010340024020012d00004101470d00200141086a280200450d00200141046a280200102e0b0240200141246a2d00004101470d002001412c6a280200450d00200141286a280200102e0b200141c8006a22012005470d000b0b2008a72201450d30200141c8006c450d300c2f0b200241003a00c4182012450d2820042d000121112001200e417e6a22123602042001200441026a360200200241013a00c418200220113a00b0182012450d2720042d000221112001200e417d6a22123602042001200441036a360200200241023a00c418200220113a00b1182012450d2720042d000321112001200e417c6a22123602042001200441046a360200200241033a00c418200220113a00b2182012450d2720042d000421112001200e417b6a22123602042001200441056a360200200241043a00c418200220113a00b3182012450d2720042d000521112001200e417a6a22123602042001200441066a360200200241053a00c418200220113a00b4182012450d2720042d000621112001200e41796a22123602042001200441076a360200200241063a00c418200220113a00b5182012450d2720042d000721112001200e41786a22123602042001200441086a360200200241073a00c418200220113a00b6182012450d2720042d000821112001200e41776a22123602042001200441096a360200200241083a00c418200220113a00b7182012450d2720042d000921112001200e41766a221236020420012004410a6a360200200241093a00c418200220113a00b8182012450d2720042d000a21112001200e41756a221236020420012004410b6a3602002002410a3a00c418200220113a00b9182012450d2720042d000b21112001200e41746a221236020420012004410c6a3602002002410b3a00c418200220113a00ba182012450d2720042d000c21112001200e41736a221236020420012004410d6a3602002002410c3a00c418200220113a00bb182012450d2720042d000d21112001200e41726a221236020420012004410e6a3602002002410d3a00c418200220113a00bc182012450d2720042d000e21112001200e41716a221236020420012004410f6a3602002002410e3a00c418200220113a00bd182012450d2720042d000f21112001200e41706a22123602042001200441106a3602002002410f3a00c418200220113a00be182012450d2720042d001021112001200e416f6a22123602042001200441116a360200200241103a00c418200220113a00bf182012450d2720042d001121112001200e416e6a22123602042001200441126a360200200241113a00c418200220113a00c0182012450d2720042d001221112001200e416d6a22123602042001200441136a360200200241123a00c418200220113a00c1182012450d2720042d001321112001200e416c6a22123602042001200441146a360200200241133a00c418200220113a00c2182012450d2720042d001421112001200e416b6a3602042001200441156a360200200220113a00c31820022802b418220441087420022802b018221a4118767221242004411876212e201a410876212520022903b818211020022802c018212b410121190c250b2005200641b8b2c0001056000b2005200641b8b2c0001056000b2005200641b8b2c0001056000b2005200741b8b2c0001056000b2005200741b8b2c0001056000b2005200741b8b2c0001056000b2005200741b8b2c0001056000b2005200741b8b2c0001056000b2005200741b8b2c0001056000b2003200741b8b2c0001056000b2027202641b8b2c0001056000b2005200641b8b2c0001056000b2005200341b8b2c0001056000b2003200741b8b2c0001056000b2005200741b8b2c0001056000b2005200341b8b2c0001056000b2005200741b8b2c0001056000b20052d0003210620012003417c6a22073602042001200541046a360200200241023a009416200220063a0081162007450d1f20052d0004210620012003417b6a22073602042001200541056a360200200241033a009416200220063a0082162007450d1f20052d0005210620012003417a6a22073602042001200541066a360200200241043a009416200220063a0083162007450d1f20052d000621062001200341796a22073602042001200541076a360200200241053a009416200220063a0084162007450d1f20052d000721062001200341786a22073602042001200541086a360200200241063a009416200220063a0085162007450d1f20052d000821062001200341776a22073602042001200541096a360200200241073a009416200220063a0086162007450d1f20052d000921062001200341766a220736020420012005410a6a360200200241083a009416200220063a0087162007450d1f20052d000a21062001200341756a220736020420012005410b6a360200200241093a009416200220063a0088162007450d1f20052d000b21062001200341746a220736020420012005410c6a3602002002410a3a009416200220063a0089162007450d1f20052d000c21062001200341736a220736020420012005410d6a3602002002410b3a009416200220063a008a162007450d1f20052d000d21062001200341726a220736020420012005410e6a3602002002410c3a009416200220063a008b162007450d1f20052d000e21062001200341716a220736020420012005410f6a3602002002410d3a009416200220063a008c162007450d1f20052d000f21062001200341706a22073602042001200541106a3602002002410e3a009416200220063a008d162007450d1f20052d0010210620012003416f6a22073602042001200541116a3602002002410f3a009416200220063a008e162007450d1f20052d0011210620012003416e6a22073602042001200541126a360200200241103a009416200220063a008f162007450d1f20052d0012210620012003416d6a22073602042001200541136a360200200241113a009416200220063a0090162007450d1f20052d0013210620012003416c6a22073602042001200541146a360200200241123a009416200220063a0091162007450d1f20052d0014210620012003416b6a22073602042001200541156a360200200241133a009416200220063a00921620070d1e0c1f0b20052d0003210620012003417c6a22073602042001200541046a360200200241023a009416200220063a0081162007450d2120052d0004210620012003417b6a22073602042001200541056a360200200241033a009416200220063a0082162007450d2120052d0005210620012003417a6a22073602042001200541066a360200200241043a009416200220063a0083162007450d2120052d000621062001200341796a22073602042001200541076a360200200241053a009416200220063a0084162007450d2120052d000721062001200341786a22073602042001200541086a360200200241063a009416200220063a0085162007450d2120052d000821062001200341776a22073602042001200541096a360200200241073a009416200220063a0086162007450d2120052d000921062001200341766a220736020420012005410a6a360200200241083a009416200220063a0087162007450d2120052d000a21062001200341756a220736020420012005410b6a360200200241093a009416200220063a0088162007450d2120052d000b21062001200341746a220736020420012005410c6a3602002002410a3a009416200220063a0089162007450d2120052d000c21062001200341736a220736020420012005410d6a3602002002410b3a009416200220063a008a162007450d2120052d000d21062001200341726a220736020420012005410e6a3602002002410c3a009416200220063a008b162007450d2120052d000e21062001200341716a220736020420012005410f6a3602002002410d3a009416200220063a008c162007450d2120052d000f21062001200341706a22073602042001200541106a3602002002410e3a009416200220063a008d162007450d2120052d0010210620012003416f6a22073602042001200541116a3602002002410f3a009416200220063a008e162007450d2120052d0011210620012003416e6a22073602042001200541126a360200200241103a009416200220063a008f162007450d2120052d0012210620012003416d6a22073602042001200541136a360200200241113a009416200220063a0090162007450d2120052d0013210620012003416c6a22073602042001200541146a360200200241123a009416200220063a0091162007450d2120052d0014210620012003416b6a22073602042001200541156a360200200241133a009416200220063a00921620070d1f0c210b2000411c3602000c380b024002402007450d0020052d0001210620012003417e6a3602042001200541026a36020020060d0020024198126a2001109606200228029812450d00200241d8106a20024198126a41c00110e9081a20024198126a200110a401024002402002290398124201510d00200241880b6a41286a2205200241c8126a290300370300200241880b6a41206a220320024198126a41286a290300370300200241880b6a41186a220620024198126a41206a290300370300200241880b6a41106a220720024198126a41186a290300370300200241880b6a41086a220a20024198126a41106a290300370300200220022903a0123703880b2004280200220441044f0d010b200241d8106a109b060c010b2001280200220e280000210920012004417c6a3602042001200e41046a36020020022802d8102104200241980f6a200241d8106a41047241bc0110e9081a200241a00a6a41286a2005290300370300200241a00a6a41206a2003290300370300200241a00a6a41186a2006290300370300200241a00a6a41106a2007290300370300200241a00a6a41086a200a290300370300200220022903880b3703a00a2004450d00200241b0186a41286a200241a00a6a41286a290300370300200241b0186a41206a200241a00a6a41206a290300370300200241b0186a41186a200241a00a6a41186a290300370300200241b0186a41106a200241a00a6a41106a290300370300200241b0186a41086a200241a00a6a41086a290300370300200220022903a00a3703b018200220043602e018200241e4186a200241980f6a41bc0110e9082105200220093602a01a20024190086a200110ab0102402002280290080d00200228029408210320024188086a200110ab01200228028808450d020b200241e0186a109b060b2000411c3602000c380b200228028c082101200241e80e6a41286a2206200241b0186a41286a290300370300200241e80e6a41206a2207200241b0186a41206a290300370300200241e80e6a41186a220a200241b0186a41186a290300370300200241e80e6a41106a220e200241b0186a41106a290300370300200241e80e6a41086a2209200241b0186a41086a290300370300200220022903b0183703e80e20024180166a200541c40110e9081a200241b80e6a41086a22052009290300370300200241b80e6a41106a2209200e290300370300200241b80e6a41186a220e200a290300370300200241b80e6a41206a220a2007290300370300200241b80e6a41286a22072006290300370300200220022903e80e3703b80e20024198086a20024180166a41c40110e9081a20024198156a412c6a200729030037020020024198156a41246a200a29030037020020024198156a411c6a200e29030037020020024198156a41146a200929030037020020024198156a410c6a2005290300370200200220022903b80e37029c152000411b36020020002002290298153702042000410c6a20024198156a41086a290200370200200041146a20024198156a41106a2902003702002000411c6a20024198156a41186a290200370200200041246a20024198156a41206a2902003702002000412c6a20024198156a41286a290200370200200041346a200241c8156a280200360200200041386a20043602002000413c6a20024198086a41c40110e9081a20004184026a200136020020004180026a200336020020004188026a20022903900e37030020004190026a200241900e6a41086a29030037030020004198026a200241900e6a41106a290300370300200041a0026a200241900e6a41186a290300370300200041a8026a200241900e6a41206a2903003703000c370b02402007450d0020052d0001210620012003417e6a22073602042001200541026a3602000240024002400240024002400240024002400240024002400240024020060e060001020304050e0b200241c8076a200110ab0120022802c8070d0d2004280200220620022802cc072203490d0d2003417f4c0d3f0240024020030d00410121050c010b200310322205450d42200428020021060b20062003490d0620052001280200200310e9082106200128020422072003490d072001200720036b3602042001200128020020036a3602002006450d0d20024180166a2001109301410121012003ad22084220862008842208a72103024020022d0080164101460d00200242003703a0152002200336029815200220084220883e029c1520024190166a290300220b422088a7210d20024188166a29030021082002419d166a28000021042002419b166a2f0000210a2002419a166a2d0000210e20024198166a2f01002109200228028416210320022f018216210620022d0081162107200ba7210f0c0d0b20030d060c0d0b41002106200241003a00a0162003417d6a21030240034020072006460d0120024180166a20066a200520066a220441026a2d00003a0000200120033602042001200441036a3602002002200641016a22043a00a0162003417f6a21032004210620044120470d000b200441ff01714120490d0d20022900871621082002418f166a290000210b200228029c16210420022f019a16210a20022d009916210e20022f0097162109200228008316210320022f008116210620022d008016210720024198156a41106a20024198086a41106a29000037030020024198156a41086a20024198086a41086a290000370300200220022900980837039815200842808080807083200842ffffffff0f83842108200b422088a7210d200ba7210f410221010c0b0b200641ff0171450d0c200241003a00a0160c0c0b200241e8076a200110ab0120022802e8070d0b2004280200220620022802ec072203490d0b2003417f4c0d3d0240024020030d00410121050c010b200310322205450d40200428020021060b20062003490d0420052001280200200310e9082106200128020422072003490d062001200720036b3602042001200128020020036a3602002006450d0b2003ad2208422086200884210b20024180166a200110930120022d0080164101460d0320024180166a41106a290300210c20024188166a29030021082002419d166a28000021042002419b166a2f0000210a2002419a166a2d0000210e20024198166a2f01002109200228028416210320022f018216210620022d0081162107200241d0076a200110db0420022903d007a70d0320022903d807211020024198156a41106a200241d0076a41106a2903003703002002200b37039815200220103703a015200c422088a7210d200ca7210f410321010c0a0b41002106200241003a00a0162003417d6a21030240034020072006460d0120024180166a20066a200520066a220441026a2d00003a0000200120033602042001200441036a3602002002200641016a22043a00a0162003417f6a21032004210620044120460d090c000b0b200641ff0171450d0a200241003a00a0160c0a0b41002106200241003a00a0162003417d6a21030240034020072006460d0120024180166a20066a200520066a220441026a2d00003a0000200120033602042001200441036a3602002002200641016a22043a00a0162003417f6a21032004210620044120470d000b200441ff01714120490d0a20022900871621082002418f166a290000210b200228029c16210420022f019a16210a20022d009916210e20022f0097162109200228008316210320022f008116210620022d008016210720024198156a41106a20024198086a41106a29000037030020024198156a41086a20024198086a41086a290000370300200220022900980837039815200842808080807083200842ffffffff0f83842108200b422088a7210d200ba7210f410521010c080b200641ff0171450d09200241003a00a0160c090b41002106200241003a00a0162003417d6a21030240034020072006460d0120024180166a20066a200520066a220441026a2d00003a0000200120033602042001200441036a3602002002200641016a22043a00a0162003417f6a21032004210620044120460d060c000b0b200641ff0171450d08200241003a00a0160c080b200ba7450d070b2005102e0c060b2003200741b8b2c0001056000b2003200741b8b2c0001056000b20024198086a41086a220120024180166a41086a29030037030020024198086a41106a220520024180166a41106a29030037030020024198086a41186a220320024180166a41186a290300370300200220022903801637039808200441ff0171411f4d0d0320024198126a41186a20032903002208370300200241d8106a41086a2001290300370300200241d8106a41106a2005290300370300200241d8106a41186a200837030020022002290398083703d81020022d00d810210720022f00d910210620022800db10210320022f00ef10210920022d00f110210e20022f01f210210a20022802f410210420022800eb10210d20022800e710210f20022900df10210820024198156a41106a200241980f6a41106a29000037030020024198156a41086a200241980f6a41086a290000370300200220022900980f37039815410621010c010b20024198086a41086a22052002418f166a29000037030020024198086a41106a220a20024197166a29000037030020024198086a41186a220e20024180166a411f6a2d00003a0000200220022900871637039808200441ff0171411f4d0d0220022d008016210720022f00811621062002280083162103200241980f6a41086a2005290300370300200241980f6a41106a200a290300370300200241980f6a41186a200e2d00003a000020022002290398083703980f200241f0076a200110db0420022903f007a70d02200241f0076a41106a2903002108200220022903f80737039815200220083703a01520022903a80f220b422888200241b00f6a31000042188684a72104200b421888a7210a200b421088a7210e200241a00f6a290300220c422088a7210d20022903980f2108200ba72109200ca7210f410421010b0b200241880b6a41106a221120024198156a41106a290300370300200241880b6a41086a20024198156a41086a290300220b3703002002200229039815220c3703880b200041186a200dad422086200fad84370000200041106a20083700002000412c6a2005360000200020043600252000200a3b00232000200e3a0022200041206a20093b00002000410c6a2003360000200020063b000a200020073a0009200041086a20013a00002000411a360200200041306a200c370200200041386a200b370200200041c0006a2011290300370200200041c8006a200241b0186a41e80110e9081a0c370b2000411c3602000c360b024002402007450d0020052d0001210620012003417e6a3602042001200541026a360200024002400240024002400240024002400240024002400240024020060e090001020304050608070d0b200241d0066a200110db0420022903d006a70d0c200241e0066a290300210b20022903d8062108200241c8066a200110ab0120022802c8060d0c2004280200220620022802cc062203490d0c2003417f4c0d3e0240024020030d00410121050c010b200310322205450d41200428020021060b20062003490d0b20052001280200200310e9082106200128020422072003490d0d2001200720036b3602042001200128020020036a3602002006450d0c2003ad220c422086200c84220c4220882114200ca72103410121010c090b200241e8066a200110ab0120022802e80622010d0b410a410220011b21014200211420022802ec0621050c070b20024188076a200110ab012002280288070d0a200228028c07210520024180166a200110e60120022d0080164105460d0a20024180166a41106a290300210b20024188166a2903002108200241a0166a280200210620024198166a290300210c20022802841621072002280280162103200241f0066a200110db04024020022903f006a70d00200241f0066a41106a290300211320022903f80621102007ad2114410321010c090b200341ff01714102470d0a2008a7450d0a2007102e0c0a0b20024190076a200110ab0120022802900722010d09410a410420011b21014200211420022802940721050c050b20024198076a200110ab0120022802980722010d08410a410520011b210142002114200228029c0721050c040b200241a0076a200110ab0120022802a0070d0720022802a407210520024180166a200110e60120022d0080164105460d072002290380162210422088211420024190166a290300210b20024188166a2903002108200241a0166a280200210620024198166a290300210c2010a721034200211041062101420021130c050b200241a8076a200110ab0120022802a80722010d06410a410720011b21014200211420022802ac0721050c020b200241c0076a200110ab0120022802c0070d0520022802c4072105200241b8076a200110ab0120022802b8070d052004280200220720022802bc072206490d052006417f4c0d370240024020060d00410121030c010b200610322203450d3a200428020021070b0240024020072006490d0020032001280200200610e90821072001280204220420064f0d012006200441b8b2c0001056000b2003102e0c060b2001200420066b3602042001200128020020066a3602002007450d052006ad2208422086200884221442208821084200210b410921010c020b200241b0076a200110ab0120022802b00722010d04410a410820011b21014200211420022802b40721050b0b0b20004119360200200041c0006a2013370200200041386a2010370200200041206a200b370200200041186a2008370200200041306a2006360200200041286a200c3702002000410c6a2005360200200041086a2001360200200041106a20144220862003ad84370200200041c8006a200241b0186a41e80110e9081a0c380b2005102e0b2000411c3602000c360b2003200741b8b2c0001056000b0240024002402007450d0020052d0001210620012003417e6a22073602042001200541026a3602000240024002400240024002400240024020060e0400010203080b200241a0066a200110ab01024020022802a006450d0020024100360298080c080b20024198086a200120022802a4061092012002280298082205450d07200229029c08210b0240200110cb042203450d0020022902981622104280808080708321132002290290162208428080808070832114200228028c16210f2002280288162109200228009b12210e20022f009912210a2008a7210d410121010c0a0b200b42ffffff3f8350450d060c070b20074102490d0620052f0002210620012003417c6a3602042001200541046a360200200241b0066a200110ab01024020022802b006450d0020024100360280160c070b20024180166a200120022802b4061092012002280280162205450d06200229028416210b20024180166a200110fe0520022802801622034102460d04200229028416210c200241a8066a200110ab0120022802a8060d042004280200220e20022802ac06220a490d04200a417f4c0d3802400240200a0d00410121070c010b200a10322207450d3b2004280200210e0b200e200a490d0320072001280200200a10e90821092001280204220e200a490d072001200e200a6b36020420012001280200200a6a3602002009450d04200aad220842208620088421102004280200220a450d022001280200220d2d0000210e2001200a417f6a220f3602042001200d41016a3602004100210402400240200e0e020100040b410121040b200f4108490d022010422088a7210e200d29000121082001200a41776a3602042001200d41096a360200200941107621112010421088a7210a2010420888a7211b20104220862009ad84421888a72112410221014100210d4200211042002113420021140c080b20074102490d0520052f0002210a20012003417c6a3602042001200541046a360200200241b8066a200110ab01024020022802b806450d0020024100360280160c060b20024180166a200120022802bc06109201200228028016220e450d05200229028416210820024180166a200110fe0502402002280280164102460d0020024188166a280200210d200229038016211441002105200241003a00a01620042802002107417f21030240034020072005460d0120024180166a20056a200128020022062d00003a00002001200720036a3602042001200641016a3602002002200541016a22063a00a0162003417f6a21032006210520064120470d000b200641ff01714120490d01200720066b22074108490d01200229008716210b2002418f166a2900002118200228029c16210320022f019a16210920022d009916210f20022f0097162111200228008316210520022f008116210620022d00801621042001280200221229000021102001200741786a3602042001201241086a360200200220093b00ab0f2002200f3a00aa0f200220113b01a80f2010428080808070832113200b422088a7ad422086200ba7ad84210b200220033600ad0f20034110762112200341087621112014422088a7210f200220183703a00f20022902a40f210c20022f01ac0f21072014a721092018a7210341032101420021140c090b200541ff0171450d00200241003a00a0160b200842ffffff3f83500d05200e102e0c050b20074102490d0420052f0002210a20012003417c6a3602042001200541046a360200200241c0066a200110ab01024020022802c006450d0020024100360280160c050b20024180166a200120022802c406109201200228028016220e450d0420022902841621080240200428020022034104490d0020012802002207280000210920012003417c6a22053602042001200741046a36020020054104490d002007280004210f2001200341786a22043602042001200741086a36020041002105200241003a00a016200341776a21030240034020042005460d0120024180166a20056a200720056a220641086a2d00003a0000200120033602042001200641096a3602002002200541016a22063a00a0162003417f6a21032006210520064120470d000b20024198086a41086a220120024180166a41086a29030037030020024198086a41106a220520024180166a41106a29030037030020024198086a41186a220320024180166a41186a290300370300200220022903801637039808200641ff0171411f4d0d0120024198126a41186a2003290300220b370300200241d8106a41086a2001290300370300200241d8106a41106a2005290300370300200241d8106a41186a200b37030020022002290398083703d81020022d00d810210420022f00d910210620022800db10210520022f00f310210720022d00f510211120022f01f610211220022900eb10210c20022800e710210320022900df10210b410421014100210d4200211042002113420021140c080b200541ff0171450d00200241003a00a0160b200842ffffff3f83500d04200e102e0c040b2010a7450d010b2007102e0b200b42ffffff3f83500d010b2005102e0b2000411c3602000c360b200a200e41b8b2c0001056000b2000201b3a0029200020113a0026200020043a0009200041183602002000413c6a200f360200200041386a2009360200200041306a20083702002000412c6a200e3602002000412a6a200a3b0100200041276a20123b0000200041246a20073b01002000411c6a200c370200200041186a2003360200200041106a200b3702002000410c6a20053602002000410a6a20063b0100200041086a20013a0000200041c8006a2013201042ffffffff0f8384370200200041c0006a2014200dad84370200200041d0006a200241b0186a41e00110e9081a0c340b20024180166a200110bd03024020022d008016410b460d0020024198086a20024180166a41c80010e9081a20004117360200200041046a20024198086a41c80010e9081a200041cc006a200241b0186a41e40110e9081a0c340b2000411c3602000c330b410f210e0c0c0b200241b0186a200110e60120022d00b0184105460d14200241800e6a41086a200241a00a6a41086a280200360200200241fc0d6a41026a200241e80e6a41026a2d00003a0000200220022902a00a3703800e200220022f00e80e3b01fc0d200241bc186a290200210b200241b0186a41206a280200210a200241ce186a2f01002109200241cd186a2d0000210d200241c9186a280000210f200241c7186a2f00002112200241c6186a2d0000211b200241c4186a2f0100211120022902b418210820022802b0182106200241e00d6a41106a20024198086a41106a290200370300200241e00d6a41086a20024198086a41086a29020037030020022002290298083703e00d200241dc0d6a41026a200241b80e6a41026a2d00003a0000200220022f00b80e3b01dc0d200241c00d6a41106a20024198126a41106a290200370300200241c00d6a41086a20024198126a41086a29020037030020022002290298123703c00d200241bc0d6a41026a200241900e6a41026a2d00003a0000200220022f00900e3b01bc0d200241a00d6a41106a200241d8106a41106a290200370300200241a00d6a41086a200241d8106a41086a290200370300200220022902d8103703a00d2002419c0d6a41026a200241a0146a41026a2d00003a0000200220022f00a0143b019c0d200241800d6a41106a200241980f6a41106a290200370300200241800d6a41086a200241980f6a41086a290200370300200220022902980f3703800d20024198156a41206a20024180166a41206a28020036020020024198156a41186a20024180166a41186a29020037030020024198156a41106a20024180166a41106a29020037030020024198156a41086a20024180166a41086a290200370300200220022902801637039815410e210e0c0b0b200241b0186a200110e60120022d00b0184105460d13200241b0186a41206a2207280200210a200241ce186a2f01002109200241cd186a2d0000210d200241c9186a280000210f200241c7186a2f00002112200241c6186a2d0000211b200241c4186a2f01002111200241bc186a290200210b200241b0186a41086a2204280200210520022802b418210320022802b0182106200241b0186a200110ec03024020022d00b0184106460d00200241800e6a41086a200241a00a6a41086a280200360200200241fc0d6a41026a200241e80e6a41026a2d00003a0000200241e00d6a41086a20024198086a41086a290200370300200241e00d6a41106a20024198086a41106a290200370300200220022902a00a3703800e200220022f00e80e3b01fc0d20022002290298083703e00d200241b0186a41186a290300210c200241b0186a41106a29030021102007280200211d2004290300211320022903b0182114200241dc0d6a41026a200241b80e6a41026a2d00003a0000200220022f00b80e3b01dc0d200241c00d6a41106a20024198126a41106a290200370300200241c00d6a41086a20024198126a41086a29020037030020022002290298123703c00d200241bc0d6a41026a200241900e6a41026a2d00003a0000200220022f00900e3b01bc0d200241a00d6a41106a200241d8106a41106a290200370300200241a00d6a41086a200241d8106a41086a290200370300200220022902d8103703a00d2002419c0d6a41026a200241a0146a41026a2d00003a0000200220022f00a0143b019c0d200241800d6a41106a200241980f6a41106a290200370300200241800d6a41086a200241980f6a41086a290200370300200220022902980f3703800d20024198156a41206a20024180166a41206a28020036020020024198156a41186a20024180166a41186a29020037030020024198156a41106a20024180166a41106a29020037030020024198156a41086a20024180166a41086a2902003703002002200229028016370398152005ad4220862003ad842108410d210e0c0b0b200641ff01714102470d132005450d132003102e0c130b200241b0186a200110e60120022d00b0184105460d12200241b0186a41206a2207280200210a200241ce186a2f01002109200241cd186a2d0000210d200241c9186a280000210f200241c7186a2f00002112200241c6186a2d0000211b200241c4186a2f01002111410c210e200241b0186a410c6a290200210b200241b0186a41086a2204280200210520022802b418210320022802b0182106200241b0186a200110ec03024020022d00b0184106460d00200241800e6a41086a200241a00a6a41086a280200360200200241fc0d6a41026a200241e80e6a41026a2d00003a0000200241e00d6a41086a20024198086a41086a290200370300200241e00d6a41106a20024198086a41106a290200370300200220022902a00a3703800e200220022f00e80e3b01fc0d20022002290298083703e00d200241b0186a41186a290300210c200241b0186a41106a29030021102007280200211d2004290300211320022903b0182114200241dc0d6a41026a200241b80e6a41026a2d00003a0000200220022f00b80e3b01dc0d200241c00d6a41106a20024198126a41106a290200370300200241c00d6a41086a20024198126a41086a29020037030020022002290298123703c00d200241bc0d6a41026a200241900e6a41026a2d00003a0000200220022f00900e3b01bc0d200241a00d6a41106a200241d8106a41106a290200370300200241a00d6a41086a200241d8106a41086a290200370300200220022902d8103703a00d2002419c0d6a41026a200241a0146a41026a2d00003a0000200220022f00a0143b019c0d200241800d6a41106a200241980f6a41106a290200370300200241800d6a41086a200241980f6a41086a290200370300200220022902980f3703800d20024198156a41206a20024180166a41206a28020036020020024198156a41186a20024180166a41186a29020037030020024198156a41106a20024180166a41106a29020037030020024198156a41086a20024180166a41086a2902003703002002200229028016370398152005ad4220862003ad8421080c0a0b200641ff01714102470d122005450d122003102e0c120b200241b0186a200110e60120022d00b0184105460d11200241800e6a41086a200241a00a6a41086a280200360200200241fc0d6a41026a200241e80e6a41026a2d00003a0000200220022902a00a3703800e200220022f00e80e3b01fc0d200241bc186a290200210b200241b0186a41206a280200210a200241ce186a2f01002109200241cd186a2d0000210d200241c9186a280000210f200241c7186a2f00002112200241c6186a2d0000211b200241c4186a2f0100211120022902b418210820022802b0182106200241e00d6a41106a20024198086a41106a290200370300200241e00d6a41086a20024198086a41086a29020037030020022002290298083703e00d200241dc0d6a41026a200241b80e6a41026a2d00003a0000200220022f00b80e3b01dc0d200241c00d6a41106a20024198126a41106a290200370300200241c00d6a41086a20024198126a41086a29020037030020022002290298123703c00d200241bc0d6a41026a200241900e6a41026a2d00003a0000200220022f00900e3b01bc0d200241a00d6a41106a200241d8106a41106a290200370300200241a00d6a41086a200241d8106a41086a290200370300200220022902d8103703a00d2002419c0d6a41026a200241a0146a41026a2d00003a0000200220022f00a0143b019c0d200241800d6a41106a200241980f6a41106a290200370300200241800d6a41086a200241980f6a41086a290200370300200220022902980f3703800d20024198156a41206a20024180166a41206a28020036020020024198156a41186a20024180166a41186a29020037030020024198156a41106a20024180166a41106a29020037030020024198156a41086a20024180166a41086a290200370300200220022902801637039815410b210e0c080b20024198066a200110ab012002280298060d10200228029c062106200241b0186a200110e60120022d00b0184105460d10200241b8186a280200210320022802b418210720022802b01821050240024020042802002204450d00200241d0186a3502002114200241cc186a280200210a200241ca186a2f01002109200241c9186a2d0000210d200241c5186a280000210f200241c3186a2f00002112200241c2186a2d0000211b200241c0186a2f01002111200241bc186a35020021082001280200220e2d0000211c20012004417f6a221d3602042001200e41016a36020042002113024002400240024002400240201c0e0707000102030405060b201d4110490d05200e41096a290000210c200e290001211020012004416f6a3602042001200e41116a360200420121130c060b420221130c050b420321130c040b420421130c030b420521130c020b420621130c010b200541ff01714102470d112003450d112007102e0c110b200241800e6a41086a200241a00a6a41086a280200360200200241fc0d6a41026a200241e80e6a41026a2d00003a0000200241e00d6a41086a20024198086a41086a290200370300200241e00d6a41106a20024198086a41106a290200370300200241dc0d6a41026a200241b80e6a41026a2d00003a0000200220022902a00a3703800e200220022f00e80e3b01fc0d20022002290298083703e00d200220022f00b80e3b01dc0d200241c00d6a41106a20024198126a41106a290200370300200241c00d6a41086a20024198126a41086a290200370300200241bc0d6a41026a200241900e6a41026a2d00003a0000200241a00d6a41086a200241d8106a41086a290200370300200241a00d6a41106a200241d8106a41106a2902003703002002419c0d6a41026a200241a0146a41026a2d00003a000020022002290298123703c00d200220022f00900e3b01bc0d200220022902d8103703a00d200220022f00a0143b019c0d200241800d6a41106a200241980f6a41106a290200370300200241800d6a41086a200241980f6a41086a29020037030020024198156a41206a20024180166a41206a28020036020020024198156a41186a20024180166a41186a29020037030020024198156a41106a20024180166a41106a29020037030020024198156a41086a20024180166a41086a290200370300200220022902980f3703800d20022002290280163703981520084220862003ad84210b2007ad4220862005ad842108410a210e0c070b20024190066a200110ab012002280290060d0f200428020022054108490d0f20022802940621062001280200220329000021082001200541786a3602042001200341086a360200200842ff01560d0f200241800e6a41086a200241980f6a41086a280200360200200241fc0d6a41026a200241a00a6a41026a2d00003a0000200241e00d6a41086a20024180166a41086a290200370300200241e00d6a41106a20024180166a41106a290200370300200241dc0d6a41026a200241e80e6a41026a2d00003a0000200220022902980f3703800e200220022f00a00a3b01fc0d20022002290280163703e00d200220022f00e80e3b01dc0d200241c00d6a41106a20024198086a41106a290200370300200241c00d6a41086a20024198086a41086a290200370300200241bc0d6a41026a200241b80e6a41026a2d00003a0000200241a00d6a41086a20024198126a41086a290200370300200241a00d6a41106a20024198126a41106a2902003703002002419c0d6a41026a200241900e6a41026a2d00003a000020022002290298083703c00d200220022f00b80e3b01bc0d20022002290298123703a00d200220022f00900e3b019c0d200241800d6a41106a200241d8106a41106a290200370300200241800d6a41086a200241d8106a41086a29020037030020024198156a41206a200241b0186a41206a28020036020020024198156a41186a200241b0186a41186a29020037030020024198156a41106a200241b0186a41106a29020037030020024198156a41086a200241b0186a41086a290200370300200220022902d8103703800d200220022902b01837039815200842ff018321084109210e0c060b20024188066a200110ab012002280288060d0e200228028c06210a20024180166a200110930120022d0080164101460d0e4108210e200241800e6a41086a200241a00a6a41086a280200360200200241fc0d6a41026a200241e80e6a41026a2d00003a0000200241e00d6a41086a20024198086a41086a290200370300200241e00d6a41106a20024198086a41106a290200370300200220022902a00a3703800e200220022f00e80e3b01fc0d20022002290298083703e00d20024180166a41106a290300210b20024180166a41086a290300210820024180166a41186a290300210c20024180166a41206a3100002110200228028416210620022f018216212c20022d008116212d200241dc0d6a41026a200241b80e6a41026a2d00003a0000200220022f00b80e3b01dc0d200241c00d6a41106a20024198126a41106a290200370300200241c00d6a41086a20024198126a41086a29020037030020022002290298123703c00d200241bc0d6a41026a200241900e6a41026a2d00003a0000200220022f00900e3b01bc0d200241a00d6a41106a200241d8106a41106a290200370300200241a00d6a41086a200241d8106a41086a290200370300200220022902d8103703a00d2002419c0d6a41026a200241a0146a41026a2d00003a0000200220022f00a0143b019c0d200241800d6a41106a200241980f6a41106a290200370300200241800d6a41086a200241980f6a41086a290200370300200220022902980f3703800d20024198156a41206a200241b0186a41206a28020036020020024198156a41186a200241b0186a41186a29020037030020024198156a41106a200241b0186a41106a29020037030020024198156a41086a200241b0186a41086a290200370300200220022902b01837039815200c422888201042188684a7210f200c421888a72112200c421088a7211b200ca721110c050b20024180066a200110ab012002280280060d0d2002280284062106200241e8056a200110db0420022903e805a70d0d200241e8056a41106a290300210b20022903f0052108200241800e6a41086a200241980f6a41086a280200360200200241fc0d6a41026a200241a00a6a41026a2d00003a0000200241e00d6a41086a20024180166a41086a290200370300200241e00d6a41106a20024180166a41106a290200370300200241dc0d6a41026a200241e80e6a41026a2d00003a0000200220022902980f3703800e200220022f00a00a3b01fc0d20022002290280163703e00d200220022f00e80e3b01dc0d200241c00d6a41106a20024198086a41106a290200370300200241c00d6a41086a20024198086a41086a290200370300200241bc0d6a41026a200241b80e6a41026a2d00003a0000200241a00d6a41086a20024198126a41086a290200370300200241a00d6a41106a20024198126a41106a2902003703002002419c0d6a41026a200241900e6a41026a2d00003a000020022002290298083703c00d200220022f00b80e3b01bc0d20022002290298123703a00d200220022f00900e3b019c0d200241800d6a41106a200241d8106a41106a290200370300200241800d6a41086a200241d8106a41086a29020037030020024198156a41206a200241b0186a41206a28020036020020024198156a41186a200241b0186a41186a29020037030020024198156a41106a200241b0186a41106a29020037030020024198156a41086a200241b0186a41086a290200370300200220022902d8103703800d200220022902b018370398154107210e0c040b202b4104490d0c2005280002210620012003417a6a3602044106210e2001200541066a360200200241800e6a41086a200241980f6a41086a280200360200200241fc0d6a41026a200241a00a6a41026a2d00003a0000200241e00d6a41086a20024180166a41086a290200370300200241e00d6a41106a20024180166a41106a290200370300200241dc0d6a41026a200241e80e6a41026a2d00003a0000200220022902980f3703800e200220022f00a00a3b01fc0d20022002290280163703e00d200220022f00e80e3b01dc0d200241c00d6a41106a20024198086a41106a290200370300200241c00d6a41086a20024198086a41086a290200370300200241bc0d6a41026a200241b80e6a41026a2d00003a0000200241a00d6a41086a20024198126a41086a290200370300200241a00d6a41106a20024198126a41106a2902003703002002419c0d6a41026a200241900e6a41026a2d00003a000020022002290298083703c00d200220022f00b80e3b01bc0d20022002290298123703a00d200220022f00900e3b019c0d200241800d6a41106a200241d8106a41106a290200370300200241800d6a41086a200241d8106a41086a29020037030020024198156a41206a200241b0186a41206a28020036020020024198156a41186a200241b0186a41186a29020037030020024198156a41106a200241b0186a41106a29020037030020024198156a41086a200241b0186a41086a290200370300200220022902d8103703800d200220022902b018370398154200210b0c030b200241e0056a200110ab0120022802e0050d0b20022802e4052106200241c8056a200110db0420022903c805a70d0b200241c8056a41106a290300210b20022903d0052108200241800e6a41086a200241980f6a41086a280200360200200241fc0d6a41026a200241a00a6a41026a2d00003a0000200241e00d6a41086a20024180166a41086a290200370300200241e00d6a41106a20024180166a41106a290200370300200241dc0d6a41026a200241e80e6a41026a2d00003a0000200220022902980f3703800e200220022f00a00a3b01fc0d20022002290280163703e00d200220022f00e80e3b01dc0d200241c00d6a41106a20024198086a41106a290200370300200241c00d6a41086a20024198086a41086a290200370300200241bc0d6a41026a200241b80e6a41026a2d00003a0000200241a00d6a41086a20024198126a41086a290200370300200241a00d6a41106a20024198126a41106a2902003703002002419c0d6a41026a200241900e6a41026a2d00003a000020022002290298083703c00d200220022f00b80e3b01bc0d20022002290298123703a00d200220022f00900e3b019c0d200241800d6a41106a200241d8106a41106a290200370300200241800d6a41086a200241d8106a41086a29020037030020024198156a41206a200241b0186a41206a28020036020020024198156a41186a200241b0186a41186a29020037030020024198156a41106a200241b0186a41106a29020037030020024198156a41086a200241b0186a41086a290200370300200220022902d8103703800d200220022902b018370398154105210e0c020b200241c0056a200110ab0120022802c0050d0a20022802c405220a200428020041c4006e22052005200a4b1bad42c4007e2208422088a70d222008a72205417f4c0d220240024020050d00410421060c010b2005102c2206450d250b200541c4006ead2108024002400240200a450d004100210e0340200241003a00d018200e41016a210e2004280200417f6a2105410021030240024003402005417f460d01200241b0186a20036a200128020022072d00003a0000200120053602042001200741016a3602002002200341016a22073a00d0182005417f6a21052007210320074120470d000b20024198086a41086a2205200241b0186a41086a29030037030020024198086a41106a2203200241b0186a41106a220d29030037030020024198086a41186a2209200241b0186a41186a290300370300200220022903b01837039808200741ff0171411f4b0d010c050b200341ff0171450d04200241003a00d0180c040b200241d8106a41086a2005290300370300200241d8106a41106a2003290300370300200241d8106a41186a200929030037030020022002290398083703d810200241b0186a200110ec0320022d00b01822034106460d03200d290300210c20022903b818211020022f01d218210720022d00d118210920022800cd18210d20022f00cb18210f20022d00ca18211120022f01c818211220022802b418211b20022f01b218211c20022d00b118211d20022800db10211f20022f00d910211e20022d00d810212720022f00ef10210520022d00f110212620022f01f210212020022802f410212120022900df10210b200220022900e7103703a00f2002200b3703980f200220213600ad0f200220203b00ab0f200220263a00aa0f200220053b01a80f02402008422088220ba722052008a7470d00200541016a22262005490d2720054101742220202620262020491b22264104202641044b1bad42c4007e220b422088a7454102742126200ba721200240024020050d00200241003602b0180c010b200241043602b818200220063602b0182002200541c4006c3602b4180b20024198086a20202026200241b0186a107d20022802a00821262002280298084101460d03200228029c0821062008422088220ba72105202641c4006ead21080b2006200541c4006c6a2205201f3600032005201e3b0001200520273a0000200241980f6a41186a2d0000211f200241980f6a41106a2903002113200241980f6a41086a290300211420022903980f2118200541306a200c37000020052010370028200520183700072005410f6a2014370000200541176a20133700002005411f6a201f3a0000200520073b0042200520093a00412005200d36003d2005200f3b003b200520113a003a200520123b00382005201b3600242005201c3b00222005201d3a0021200520033a0020200b422086200842ffffffff0f83844280808080107c2108200e200a470d000b0b2006450d0c200241800e6a41086a200241a0146a41086a280200360200200241fc0d6a41026a200241b4146a41026a2d00003a0000200241e00d6a41086a200241a00a6a41086a290200370300200241e00d6a41106a200241a00a6a41106a290200370300200241dc0d6a41026a200241b0146a41026a2d00003a0000200220022902a0143703800e200220022f00b4143b01fc0d200220022902a00a3703e00d200220022f00b0143b01dc0d200241c00d6a41106a200241e80e6a41106a290200370300200241c00d6a41086a200241e80e6a41086a290200370300200241bc0d6a41026a200241ac146a41026a2d00003a0000200241a00d6a41086a200241b80e6a41086a290200370300200241a00d6a41106a200241b80e6a41106a2902003703002002419c0d6a41026a2002419d146a41026a2d00003a0000200220022902e80e3703c00d200220022f00ac143b01bc0d200220022902b80e3703a00d200220022f009d143b019c0d200241800d6a41106a200241900e6a41106a290200370300200241800d6a41086a200241900e6a41086a29020037030020024198156a41206a20024180166a41206a28020036020020024198156a41186a20024180166a41186a29020037030020024198156a41106a20024180166a41106a29020037030020024198156a41086a20024180166a41086a290200370300200220022902900e3703800d2002200229028016370398154103210e0c030b20260d250c230b02402008422088a72201450d00200141c4006c2105200641286a210103400240200141786a2d00004101470d002001280200450d002001417c6a280200102e0b200141c4006a2101200541bc7f6a22050d000b0b2008a72201450d0a200141c4006c0d090c0a0b200241b0186a200110ec0320022d00b018222f4106460d024102210e200241b80e6a41026a220420022d00b3183a000020024180166a41086a2230200241c4186a29020037030020024180166a41106a2231200241cc186a290200370300200220022f00b1183b01b80e2002200241bc186a29020037038016200241b0186a41086a2211280200213220022802b4182133200241b0186a200110ec03024020022d00b0184106470d00202f4101470d032032450d032033102e0c030b200241980f6a41206a2201200241b0186a41206a280200360200200241980f6a41186a2234200241b0186a41186a290300370300200241980f6a41106a2235200241b0186a41106a290300370300200241980f6a41086a22362011290300370300200241800e6a41086a200241a00a6a41086a280200360200200220022903b0183703980f200220022903a00a3703800e20022f01e80e211120022d00ea0e211b20022f00eb0e2112200241fc0d6a41026a200241b4146a41026a2d00003a0000200220022f01b4143b01fc0d200241e00d6a41106a200241d8106a41106a290300370300200241e00d6a41086a200241d8106a41086a290300370300200220022903d8103703e00d200241dc0d6a41026a200241a0146a41026a2d00003a0000200220022f01a0143b01dc0d200241c00d6a41106a20024198126a41106a290300370300200241c00d6a41086a20024198126a41086a29030037030020022002290398123703c00d200241bc0d6a41026a200241900e6a41026a2d00003a0000200220022f01900e3b01bc0d200241a00d6a41106a20024198086a41106a290300370300200241a00d6a41086a20024198086a41086a29030037030020022002290398083703a00d2002419c0d6a41026a20042d00003a0000200220022f01b80e3b019c0d200241800d6a41106a2031290300370300200241800d6a41086a203029030037030020022002290380163703800d20024198156a41206a200128020036020020024198156a41186a203429030037030020024198156a41106a203529030037030020024198156a41086a2036290300370300200220022903980f370398152010420886202ead42ff0183842118202bad42088620104238888442ffffffffff1f8321172007ad422086202dad8421102003ad422086200b842113202cad4220862005ad84210b0b200241f00c6a41086a2201200241800e6a41086a280200360200200241ec0c6a41026a2205200241fc0d6a41026a2d00003a0000200241d00c6a41086a2203200241e00d6a41086a290300370300200241d00c6a41106a2207200241e00d6a41106a290300370300200241cc0c6a41026a2204200241dc0d6a41026a2d00003a0000200220022903800e3703f00c200220022f01fc0d3b01ec0c200220022903e00d3703d00c200220022f01dc0d3b01cc0c200241b00c6a41106a222b200241c00d6a41106a290300370300200241b00c6a41086a222e200241c00d6a41086a290300370300200241ac0c6a41026a2230200241bc0d6a41026a2d00003a0000200241900c6a41086a2231200241a00d6a41086a290300370300200241900c6a41106a2234200241a00d6a41106a2903003703002002418c0c6a41026a22352002419c0d6a41026a2d00003a0000200220022903c00d3703b00c200220022f01bc0d3b01ac0c200220022903a00d3703900c200220022f019c0d3b018c0c200241f00b6a41106a2236200241800d6a41106a290300370300200241f00b6a41086a2237200241800d6a41086a290300370300200241880b6a41206a223820024198156a41206a280200360200200241880b6a41186a223920024198156a41186a290300370300200241880b6a41106a223a20024198156a41106a290300370300200241880b6a41086a223b20024198156a41086a290300370300200220022903800d3703f00b20022002290398153703880b200041c8006a200c370200200041c0006a2010370200200041186a200b370200200041106a2008370200200041d0006a201d360200200041386a2013370200200041306a20143702002000412c6a200a360200200020093b002a2000200d3a0029200041256a200f360000200020123b00232000201b3a0022200041206a20113b01002000410c6a20063602002000202c3b000a2000202d3a0009200041086a200e3a000020004116360200200041e0006a201c3a0000200041d4006a20022903f00c370200200041dc006a2001280200360200200041e4006a201e360200200041e8006a201f360200200020022f01ec0c3b0061200041e3006a20052d00003a0000200041ec006a20022903d00c370200200041f4006a2003290300370200200041fc006a200729030037020020004184016a20273a000020004187016a20042d00003a0000200020022f01cc0c3b0085012000418c016a202636020020004188016a2020360200200041a0016a202b29030037020020004198016a202e29030037020020004190016a20022903b00c370200200041a8016a20213a0000200041ab016a20302d00003a0000200020022f01ac0c3b00a901200041b0016a2022360200200041ac016a2023360200200041c4016a2034290300370200200041bc016a2031290300370200200041b4016a20022903900c370200200041cc016a202f3a0000200041cf016a20352d00003a0000200020022f018c0c3b00cd01200041d4016a2032360200200041d0016a2033360200200041e8016a2036290300370200200041e0016a2037290300370200200041d8016a20022903f00b37020020004190026a203828020036020020004188026a203929030037020020004180026a203a290300370200200041f8016a203b290300370200200041f0016a20022903880b370200200041a4026a20173700002000419c026a201837000020004198026a2024360000200020253b0096022000201a3a00950220004194026a20193a00000c250b200241003a00c4180b20214101470d002022450d002023102e0b20274101470d002026450d002020102e0b201c4101470d00201f450d00201e102e0b200341ff01714101470d002007450d00202d102e0b200541ff01714101470d0020022802e80e450d00202c102e0b02402008422088a72201450d002006200141c8006c6a2105200621010340024020012d00004101470d00200141086a280200450d00200141046a280200102e0b0240200141246a2d00004101470d002001412c6a280200450d00200141286a280200102e0b200141c8006a22012005470d000b0b2008a72201450d01200141c8006c450d010b2006102e0b2000411c3602000c1c0b20052d0015210720012003416a6a22063602042001200541166a2205360200200220073a009316200229038816210b200228029016210e2002280280162103200228028416210a200241003a0094162006450d0420052d0000210720012006417f6a2204360204200241013a0094162001200541016a360200200220073a00801602402004450d0020052d0001210720012006417e6a2204360204200241023a0094162001200541026a360200200220073a0081162004450d0020052d0002210720012006417d6a2204360204200241033a0094162001200541036a360200200220073a0082162004450d0020052d0003210720012006417c6a2204360204200241043a0094162001200541046a360200200220073a0083162004450d0020052d0004210720012006417b6a2204360204200241053a0094162001200541056a360200200220073a0084162004450d0020052d0005210720012006417a6a2204360204200241063a0094162001200541066a360200200220073a0085162004450d0020052d000621072001200641796a2204360204200241073a0094162001200541076a360200200220073a0086162004450d0020052d000721072001200641786a2204360204200241083a0094162001200541086a360200200220073a0087162004450d0020052d000821072001200641776a2204360204200241093a0094162001200541096a360200200220073a0088162004450d0020052d000921072001200641766a22043602042002410a3a00941620012005410a6a360200200220073a0089162004450d0020052d000a21072001200641756a22043602042002410b3a00941620012005410b6a360200200220073a008a162004450d0020052d000b21072001200641746a22043602042002410c3a00941620012005410c6a360200200220073a008b162004450d0020052d000c21072001200641736a22043602042002410d3a00941620012005410d6a360200200220073a008c162004450d0020052d000d21072001200641726a22043602042002410e3a00941620012005410e6a360200200220073a008d162004450d0020052d000e21072001200641716a22043602042002410f3a00941620012005410f6a360200200220073a008e162004450d0020052d000f21072001200641706a2204360204200241103a0094162001200541106a360200200220073a008f162004450d0020052d0010210720012006416f6a2204360204200241113a0094162001200541116a360200200220073a0090162004450d0020052d0011210720012006416e6a2204360204200241123a0094162001200541126a360200200220073a0091162004450d0020052d0012210720012006416d6a2204360204200241133a0094162001200541136a360200200220073a0092162004450d0020052d0013210720012006416c6a22063602042001200541146a2205360200200220073a009316024020060d00200241023a00880b0c060b200228028416210720022802801621042002290388162108200228029016210920052d0000210d20012006417f6a3602042001200541016a3602000240024002400240200d0e020102000b200241023a00880b0c080b200241003a00880b0c010b20024180166a2001109301024020022d0080164101470d00200241023a00880b0c070b200241f0106a20024199166a290000370300200241e8106a20024191166a290000370300200241e0106a20024189166a290000370300200220022900811622133703d810200241e7106a290000210c20022900df10211020022f00ef10210120022d00f110210520022f01f210210620022802f410210d20022f00d910210f200220022800db1036028c0b2002200f3b018a0b200220133c00890b200241013a00880b2002200d36009d15200220063b009b15200220053a009a15200220013b019815200228029812211d0b2003410876210620044108762101200241a4086a2009410874ad2008423888843e0200200220022d008f0b3a00980f200220084208862007411876ad8437029c082002200741087420044118767236029808200941187620022f01880b20022d008a0b41107472410874722112200ead420886200b4238888442ffffffffff1f832108200220103700990f2010423888200c42088684a7211120022900991522134230882110200b420886200a411876ad84210b200a41087420034118767221052013421088a72107200c422088a72109200c421088a7210d200c420888a7210f200228008b0b211f20022d009815210e20024198086a41086a2903002114200228029c12211c20022f01a012211b20022f01a212212620022802a412211e20022802a812212020022802ac12212120022903980f210c20022903980821182013a7210a42002113410521270c030b200241003a0094160c040b200241003a0094160c030b20052d0015210720012003416a6a22063602042001200541166a2205360200200220073a00931620022002290388163702a008200220022802841636029c08200220022802801622033602980820022002280290163602a80820064110490d02200541086a2900002114200529000021182001200641706a22073602042001200541106a3602002007450d0220052d0010210420012006416f6a221b3602042001200541116a221c360200410021120240024020040e020100040b201b4110490d03200541196a29000021082005290011210c20012006415f6a22073602042001200541216a36020020074110490d03200541296a29000021102005290021210b20012006414f6a22073602042001200541316a360200200741034d0d032005280031210720012006414b6a221b3602042001200541356a221c3602002002200b370390162002200837038816200220073602a016200228029416210720022f019216210a20022d009116210e20022f008b16210d200228008d16210920022d008a16210f20022f018816211120022903a0162113410121120b41000d02201b450d02201c2d000021052001201b417f6a22063602042001201c41016a36020041022127410221040240024020050e020100040b2006450d03201c2d000121052001201b417e6a3602042001201c41026a36020041002104024020050e020100040b410121040b2003410876210620023500a708200241ab086a310000422086842108200229009f08210b200228009b0821054100211f0b2000200e3a00492000200f3a0042200020013b011e200020043a001d200020063b000a200020033a0009200041133602002000411c6a20084220883c0000200041186a20083e0000200041d8006a2013370200200041d0006a2010370200200041286a2014370200200041206a2018370200200041f4006a2021360200200041f0006a2020360200200041ec006a201e360200200041ea006a20263b0100200041e8006a201b3b0100200041e4006a201c360200200041e0006a201d360200200041cc006a2007360200200041ca006a200a3b0100200041c5006a2009360000200041c3006a200d3b0000200041c0006a20113b0100200041386a200c370200200041346a201f360200200041306a2012360200200041106a200b3700002000410c6a2005360000200041086a20273a0000200041f8006a200241b0186a41b80110e9081a0c180b200241003a0094160b2000411c3602000c160b2000200a3b00462000200e3a00452000201c3600412000201b3b003f2000201d3a003e2000201e3b0026200020273a002520002026360021200020123b001f200020203a001e200020073b0006200020043a0005200020053a000420004111360200200041346a200c3700002000412c6a200b3700002000410c6a20083700002000413c6a20113b0000200041286a201f3600002000411c6a200f3b0000200041086a2003360000200041146a2009ad422086200dad84370000200041c8006a200241b0186a41e80110e9081a0c150b2000411c3602000c140b200020093a000920004110360200200041286a200b370200200041146a200a360200200041106a200e3602002000410c6a2007360200200041086a200d3a0000200041206a200c421886200fad220b42088884370200200041186a200b423886200842ffffffffffffffff008384370200200041306a200241b0186a41800210e9081a0c130b2000411c3602000c120b20024198086a41086a22012002418f166a29000037030020024198086a41106a220320024197166a29000037030020024198086a41186a220620024180166a411f6a2d00003a0000200220022900871637039808200441ff0171411f4d0d0320022d008016210720022f008116210a200228008316210520024198126a41186a20062d000022063a0000200241980f6a41086a20012903002208370300200241980f6a41106a22012003290300370300200241980f6a41186a20063a00002002200229039808220b3703980f20012f01002112200228029c0f211120022d00aa0f211b20022f00ab0f210f20022800ad0f210d20022802a40f211c200ba721032008a721044106211d41002109420021080b0c010b20024198086a41086a22032002418f166a29000037030020024198086a41106a220620024197166a29000037030020024198086a41186a220e20024180166a411f6a2d00003a0000200220022900871637039808200a41ff0171411f4d0d0120022d008016210720022f008116210a2002280083162105200241d8106a41086a2003290300370300200241d8106a41106a2006290300370300200241d8106a41186a200e2d00003a000020022002290398083703d810200241a0046a200110ab0120022802a0040d0120042802002203450d0120022802a4042106200128020022042d0000210e20012003417f6a3602042001200441016a3602004100210102400240200e0e020100030b410121010b20022903d8102208422088a72111200241e0106a290300220b422088a7211c20022800ed10210d20022f00eb10210f20022d00ea10211b20022f01e81021122008a72103200ba721044104211d0b200020013a00292000200f3b00232000201b3a00222000200a3b000a200020073a00092000410f360200200041386a2008370200200041346a2009360200200041306a200e3602002000412c6a2006360200200041256a200d360000200041206a20123b0100200041146a2011360200200041106a20033602002000410c6a2005360200200041086a201d3a0000200041186a201cad4220862004ad84370200200041c0006a200241b0186a41f00110e9081a0c0e0b2000411c3602000c0d0b20024198086a41086a220620024180166a41086a29030037030020024198086a41106a220720024180166a41106a29030037030020024198086a41186a220e20024180166a41186a290300370300200220022903801637039808200a41ff0171411f4d0d01200241d8106a41086a2006290300370300200241d8106a41106a2007290300370300200241d8106a41186a200e29030037030020022002290398083703d8102003417e6a200a460d012005200a6a220541026a2d000021062001200320046a22043602042001200541036a3602004100211e0240024020060e020100030b20044104490d02200541036a280000210720012003200a6b41796a3602042001200541076a3602004101211e0b20022900df10220c422088a7211c200241e7106a290000210820022802f410211120022f01f210210f20022d00f110211220022f00ef10210a20022800db10210e20022f00d910210920022d00d810210d2007ad210b200ca7211d4200210c4118211b0c020b20024198086a41086a22062002418f166a29000037030020024198086a41106a220720024197166a29000037030020024198086a41186a220420024180166a411f6a2d00003a0000200220022900871637039808200a41ff0171411f4d0d0020022d008016210d20022f0081162109200228008316210e200241980f6a41086a2006290300370300200241980f6a41106a2007290300370300200241980f6a41186a20042d00003a000020022002290398083703980f2003200a6b2203417e6a4104490d00200f280000211e20012003417a6a36020420012005200a6a41066a36020020022903a80f220b422888200241b00f6a31000042188684a72111200b421888a7210f200b421088a7211220022903980f220c422088a7211c200241a00f6a2903002108200ba7210a200ca7211d4200210b4117211b4200210c0c010b2000411c3602000c0a0b200020273b012a2000201f3a00292000200f3b0023200020123a0022200020093b000a2000200d3a00092000410d360200200041386a200c370200200041306a200b3702002000412c6a201e360200200041256a2011360000200041206a200a3b0100200041186a2008370200200041146a201c360200200041106a201d3602002000410c6a200e360200200041086a201b3a0000200041c0006a200241b0186a41f00110e9081a0c090b2000411c3602000c080b41002112420021100b0b200020233a0049200020203a0042200020273b002a2000201e3a00292000201c3b00232000201f3a00222000200f3b010a2000200a3a000920004107360200200041d8006a200c370200200041d0006a200b370200200041cc006a2025360200200041ca006a20243b0100200041c5006a2022360000200041c3006a20213b0000200041c0006a20263b0100200041386a2013370200200041346a2009360200200041306a20113602002000412c6a200e360200200041256a201d360000200041206a201b3b01002000410c6a2007360200200041086a200d3a0000200041186a2010422086200842208884370200200041106a2008422086201a201241ff017172ad84370200200041e0006a200241b0186a41d00110e9081a0c050b1038000b2000411c3602000c030b1036000b2006102e0b2000411c3602000b200241c01b6a24000b940704027f017e097f037e23004190026b22032400024002400240024002402002200128020441286e2204200420024b1bad42287e2205422088a70d002005a72204417f4c0d000240024020040d00410821060c010b2004102c2206450d020b200441286e2107024020020d00410021020c040b410021080340200341003a00c8012008220941016a21082001280204210a417f210b41002104024002400340200a2004460d01200341a8016a20046a2001280200220c2d00003a00002001200a200b6a3602042001200c41016a3602002003200441016a220c3a00c801200b417f6a210b200c2104200c4120470d000b200341d0016a41086a2204200341a8016a41086a290300370300200341d0016a41106a220b200341a8016a41106a290300370300200341d0016a41186a220d200341a8016a41186a290300370300200320032903a8013703d001200c41ff0171411f4b0d010c050b200441ff0171450d04200341003a00c8010c040b200341e8006a41086a220e2004290300370300200341e8006a41106a2204200b290300370300200341e8006a41186a220b200d290300370300200320032903d001370368200a200c6b220c4108490d032001280200220a29000021052001200c41786a3602042001200a41086a360200200341286a41086a200e290300220f370300200341286a41106a20042903002210370300200341286a41186a200b2903002211370300200341086a41186a220b2011370300200341086a41106a220c2010370300200341086a41086a220a200f37030020032003290368220f3703282003200f3703080240024020092007470d0020094101742204200941016a2207200420074b1b22044104200441044b1bad42287e220f422088a7454103742104200fa721070240024020090d00200341003602a8010c010b200341083602b001200320063602a8012003200941286c3602ac010b200341d0016a20072004200341a8016a107d20032802d801210420032802d0014101460d0120032802d4012106200441286e21070b2006200941286c6a22042003290308370300200a290300210f200c2903002110200b290300211120042005370320200441186a2011370300200441106a2010370300200441086a200f37030020082002460d050c010b0b20040d010b1038000b1036000b200041003602002007450d01200741286c450d012006102e0c010b2000200736020420002006360200200041086a20023602000b20034190026a24000baf0102017f017e230041106b2203240002402001450d002001410674210103400240024020002903004201510d00200341003a000020022003410110740c010b200341013a000020022003410110742002200041206a41201074200041086a29030021042003200041106a2903003703082003200437030020022003411010742003200041186a29030037030020022003410810740b200041c0006a2100200141406a22010d000b0b200341106a24000b9e0101027f230041106b22032400024002402001450d002000200141c4006c6a210403402003200028020036020020022003410410744120102c2201450d0220034220370204200320013602002003200041046a2200412010742002200328020022012003280208107402402003280204450d002001102e0b2002200041206a41201074200041c0006a22002004470d000b0b200341106a24000f0b1036000b740002402001450d002000200141e0016c6a2101034020022000412010742002200041206a412010742002200041c0006a412010742002200041e0006a41201074200220004180016a412010742002200041a0016a412010742002200041c0016a41201074200041e0016a22002001470d000b0b0bb40203027f017e027f230041106b2203240002402001450d002000200141d8006c6a210403402002200041386a41201074200029030021052003200041086a2903003703082003200537030020022003411010742000280220210120002802282206200210760240200641306c2206450d00200120066a210603402002200141201074200141206a29030021052003200141286a290300370308200320053703002002200341101074200141306a22012006470d000b0b200041d8006a2107200028022c2101200041346a28020022062002107602402006450d002006410574210603402002200141201074200141206a2101200641606a22060d000b0b200029031021052003200041186a2903003703082003200537030020022003411010742007210020072004470d000b0b200341106a24000ba40102017f017e230041106b2203240002402001450d002001410574210103402002200041106a41081074200029030021042003200041086a29030037030820032004370300200220034110107402400240024002400240200041186a2d00000e03000102040b200341003a00000c020b200341013a00000c010b200341023a00000b20022003410110740b200041206a2100200141606a22010d000b0b200341106a24000bff0101027f230041106b2203240002400240200141c4006c2201450d0003400240024020002d00004101460d00200341003a000020022003410110742003200041046a28020036020020022003410410740c010b200341013a000020022003410110744120102c2204450d0320034220370204200320043602002003200041016a412010742002200328020022042003280208107402402003280204450d002004102e0b0240200041216a2d00004101460d00200341003a000020022003410110740c010b200341013a000020022003410110742002200041226a412010740b200041c4006a2100200141bc7f6a22010d000b0b200341106a24000f0b1036000b930201057f230041106b2203240002402001450d0020002001411c6c6a2104034020002802002105200028020822012002107602402001450d002005200141e0006c6a210603402005200210a101200528025021012005280258220720021076200541e0006a210502402007450d002007410574210703402002200141201074200141206a2101200741606a22070d000b0b20052006470d000b0b2000411c6a2105200028020c2101200028021422072002107602402007450d00200741027421070340200320012802003602082002200341086a41041074200141046a21012007417c6a22070d000b0b2003200028021836020c20022003410c6a410410742005210020052004470d000b0b200341106a24000b9c0101027f230041106b2202240020012000412010742002200041206a360204200241046a200110af012002200041306a360208200241086a200110af01200041c0006a2802002103200041c8006a28020022002001107602402000450d00200041306c210003402001200341106a412010742002200336020c2002410c6a200110af01200341306a2103200041506a22000d000b0b200241106a24000bc50101037f230041306b2203240002400240200241046a2204417f4c0d000240024020040d00410121050c010b2004102c2205450d020b200341003602102003200436020c200320053602082002200341086a1076200341086a2001200210742003200328020822022003280210220410a3013703182003412c6a200220046a360200200320023602282003200341206a3602242003200341186a3602202000200341206a107c0240200328020c450d002002102e0b200341306a24000f0b1038000b1036000b1d01017e2001ad4220862000ad841013220029000021022000102e20020bea0304037f027e017f047e230041a0016b22022400200241003a00380240024002400240200128020422034110490d002001280200220441086a2900002105200429000021062001200441106a3602002001200341706a2204360204200241013a00382002200637030820022005370310200441104f0d01200042013703000c020b200042013703000c020b2001280200220441086a2900002105200429000021062001200441106a360200200241086a41186a220720053703002001200341606a2204360204200241023a003820022006370318024020044110490d002001280200220441086a2900002105200429000021062001200441106a360200200241086a41286a20053703002001200341506a360204200241033a003820022006370328200241c0006a41086a200241086a41086a2903002208370300200241c0006a41106a200241086a41106a2903002209370300200241c0006a41186a2007290300220a370300200241c0006a41206a2006370300200241c0006a41286a200537030020022002290308220b370340200041306a2005370300200041286a2006370300200041206a200a370300200041186a2009370300200041106a20083703002000200b370308200042003703000c020b200042013703000b200241003a00380b200241a0016a24000bac0401057f230041106b220241003a000802400240024020012802042203450d00200128020022042d0000210520012003417f6a2206360204200241013a00082001200441016a360200200220053a000020060d01200041013a00000c020b200041013a00000f0b200128020022042d0000210520012003417e6a22063602042001200441016a360200200241023a0008200220053a00010240024002400240024002402006450d00200128020022042d0000210520012003417d6a22063602042001200441016a360200200241033a0008200220053a00022006450d01200128020022042d0000210520012003417c6a22063602042001200441016a360200200241043a0008200220053a00032006450d02200128020022042d0000210520012003417b6a22063602042001200441016a360200200241053a0008200220053a00042006450d03200128020022042d0000210520012003417a6a22063602042001200441016a360200200241063a0008200220053a00052006450d04200128020022042d000021052001200341796a22063602042001200441016a360200200241073a0008200220053a00062006450d05200041003a0000200128020022042d000021052001200341786a3602042001200441016a360200200220053a0007200020022903003700010f0b200041013a00000c050b200041013a00000c040b200041013a00000c030b200041013a00000c020b200041013a00000c010b200041013a00000b200241003a00080bbf0202077f047e230041f0006b22022400200241003a002841002103024002400340200241003a003020012802002204280204220520054100472206490d01200341016a2107200241306a20042802002208200610e9081a2004200520066b3602042004200820066a360200024020050d00200241003a00300b200241086a20036a20022d00303a0000200220073a00282007210320074120470d000b200241306a41086a200241086a41086a2903002209370300200241306a41106a200241086a41106a290300220a370300200241306a41186a200241086a41186a290300220b37030020022002290308220c370330200041196a200b370000200041116a200a370000200041096a20093700002000200c370001200041003a00000c010b200041013a0000200341ff0171450d00200241003a00280b200241f0006a24000bd60301087f230041d0016b2202240041002103200241003a00482001280204417f6a210402400240024003402004417f460d01200241086a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00482004417f6a210420052103200541c000470d000b200241d0006a41086a2204200241086a41086a290300370300200241d0006a41106a2201200241086a41106a290300370300200241d0006a41186a2203200241086a41186a290300370300200241d0006a41206a2206200241086a41206a290300370300200241d0006a41286a2207200241086a41286a290300370300200241d0006a41306a2208200241086a41306a290300370300200241d0006a41386a2209200241086a41386a29030037030020022002290308370350200541ff017141c000490d0120002002290350370001200041003a0000200041396a2009290300370000200041316a2008290300370000200041296a2007290300370000200041216a2006290300370000200041196a2003290300370000200041116a2001290300370000200041096a20042903003700000c020b200041013a0000200341ff0171450d01200241003a00480c010b200041013a00000b200241d0016a24000bef0101047f230041d0016b2202240041002103200241003a00492001280204417f6a210402400240024003402004417f460d01200241086a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00492004417f6a210420052103200541c100470d000b2002418f016a200241086a41c10010e9081a200241ce006a2002418f016a41c10010e9081a200541ff017141c100490d01200041016a200241ce006a41c10010e9081a200041003a00000c020b200041013a0000200341ff0171450d01200241003a00490c010b200041013a00000b200241d0016a24000be20201077f230041206b2202240002400240200041046a2802002203200041086a28020022046b2001410c6a280200200128020822056b22064103752207490d00200028020021030c010b0240200420076a22082004490d00200341017422042008200420084b1b22044104200441044b1b220441ffffffff01712004464102742108200441037421040240024020030d00200241003602100c010b200241186a410436020020022003410374360214200220002802003602100b200220042008200241106a107d200241086a2802002104024020022802004101460d00200020022802042203360200200041046a2004410376360200200041086a28020021040c020b2004450d001036000b1038000b200320044103746a2005200610e9081a20012001410c6a280200360208200041086a2200200028020020076a3602000240200141046a28020041ffffffff0171450d002001280200102e0b200241206a24000bf90302057f017e230041106b22022400200242003c000c200242003e02080240024020012802042203450d00200128020022042d0000210520012003417f6a2206360204200241013a000c2001200441016a360200200220053a000802402006450d00200128020022042d0000210520012003417e6a22063602042001200441016a360200200241023a000c200220053a00092006450d00200128020022042d0000210520012003417d6a22063602042001200441016a360200200241033a000c200220053a000a2006450d00200128020022042d0000210520012003417c6a3602042001200441016a360200200241043a000c200220053a000b200231000ca741034d0d01200228020821042002200110ab01024002400240024020022802000d002001280204220520022802042203490d002003417f4c0d020240024020030d00410121060c010b200310322206450d04200128020421050b0240024020052003490d0020062001280200200310e90821052001280204220620034f0d012003200641b8b2c0001056000b2006102e0c010b2001200620036b3602042001200128020020036a36020020050d010b200041003602040c050b20002003ad220742208620078437020820002005360204200020043602000c040b1038000b1036000b200241003a000c0b200041003602040b200241106a24000bcf0201067f0240024020012802042202450d00200128020022032d0000210420012002417f6a2205360204410121062001200341016a3602000240200441037122074103460d0002400240024020070e03000102000b20044102762107410021060c040b41012106024020050d000c040b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d03200141fcff03714102762107410021060c030b20054103490d01200341036a2d0000210620032f0001210720012002417c6a3602042001200341046a3602002007200641107472410874200472220141808004492106200141027621070c020b0240200441034d0d000c020b20054104490d012003280001210720012002417b6a3602042001200341056a36020020074180808080044921060c010b410121060b20002007360204200020063602000ba00402067f017e230041106b22022400200242003c000c200242003e020802400240200128020022032802042204450d00200328020022052d0000210620032004417f6a360204200241013a000c2003200541016a360200200220063a00080240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a360200200241023a000c200220063a0009200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a360200200241033a000c200220063a000a200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a360200200241043a000c200220063a000b200231000ca741034d0d01200228020821042002200110ad01024002400240024020022802000d0020012802002205280204220620022802042203490d002003417f4c0d020240024020030d00410121070c010b200310322207450d042001280200220528020421060b0240024020062003490d0020072005280200200310e90821012005280204220620034f0d012003200641b8b2c0001056000b2007102e0c010b2005200620036b3602042005200528020020036a36020020010d010b200041003602040c050b20002003ad220842208620088437020820002001360204200020043602000c040b1038000b1036000b200241003a000c0b200041003602040b200241106a24000bfb0201057f02400240200128020022022802042203450d00200228020022042d0000210520022003417f6a360204410121032002200441016a3602000240200541037122024103460d0002400240024020020e03000102000b20054102762102410021030c040b200128020022022802042203450d02200228020022012d0000210420022003417f6a360204410121032002200141016a3602002004410874200572220141ffff0371418002490d03200141fcff03714102762102410021030c030b2001280200220228020422034103490d012002280200220141026a2d0000210420012f000021062002200141036a36020020022003417d6a3602042006200441107472410874200572220241808004492103200241027621020c020b0240200541034d0d000c020b2001280200220128020422054104490d0120012802002203280000210220012005417c6a3602042001200341046a36020020024180808080044921030c010b410121030b20002002360204200020033602000bad0201047f230041106b22022400024002402001280208220341146a2204417f4c0d000240024020040d00410121050c010b2004102c2205450d020b20024100360208200220043602042002200536020020022001410c6a411010742001280200210420032002107620022004200310742002200128021c2204412010742002200441206a36020c2002410c6a200210af012002200441306a36020c2002410c6a200210af01200441c0006a2802002101200441c8006a28020022042002107602402004450d00200441306c210403402002200141106a412010742002200136020c200141306a21012002410c6a200210af01200441506a22040d000b0b200020022802002201200228020810b00102402002280204450d002001102e0b200241106a24000f0b1038000b1036000bad0303017f027e027f230041306b2202240002400240024002400240024020002802002200290300220342c000544100200041086a29030022045022051b0d0020034280800154410020051b0d01200342808080800454410020051b0d02411020047920037942c0007c20044200521ba741037622056b41044f0d0341c087c500413641c489c5001039000b20022003a74102743a00182001200241186a410110740c030b20022003a74102744101723b01182001200241186a410210740c020b20022003a74102744102723602182001200241186a410410740c010b2002413320054102746b3a00182001200241186a41011074200029030021032002200041086a290300220437031020022003370308200541706a21000340200220033c00182001200241186a410110742003420888200442388684210320044208882104200041016a22052000492106200521002006450d000b2002200337030820022004370310200320048450450d010b200241306a24000f0b2002412c6a4100360200200241286a41d4e2cc003602002002420137021c2002418888c500360218200241086a200241186a10de04000b4c0020002002ad4220862001ad8410102201290000370000200041186a200141186a290000370000200041106a200141106a290000370000200041086a200141086a2900003700002001102e0b920101047f230041106b22022400024002402000280208220341d8006c4104722204417f4c0d00200028020021002004102c2205450d01200241003602082002200436020420022005360200200320021076200020032002109d012001280200200128020420022802002201200228020810b20102402002280204450d002001102e0b200241106a24000f0b1038000b1036000b18002001ad4220862000ad842003ad4220862002ad84102a0bc00101047f230041106b2202240002400240200128020822034105744104722204417f4c0d00200128020021012004102c2205450d0120004100360208200020043602042000200536020020032000107602402003450d002003410574210303404120102c2204450d03200242203702042002200436020020022001412010742000200228020022042002280208107402402002280204450d002004102e0b200141206a2101200341606a22030d000b0b200241106a24000f0b1038000b1036000bd90102047f017e230041106b2202240002400240200128020822034106744104722204417f4c0d00200128020021012004102c2205450d0120004100360208200020043602042000200536020020032000107602402003450d002003410674210303402000200141206a41201074200129030021062002200141086a290300370308200220063703002000200241101074200141106a29030021062002200141186a290300370308200220063703002000200241101074200141c0006a2101200341406a22030d000b0b200241106a24000f0b1038000b1036000bae0101047f230041106b2202240002400240200128020822034103744104722204417f4c0d00200128020021012004102c2205450d0120004100360208200020043602042000200536020020032000107602402003450d00200120034103746a21030340200220012802003602082000200241086a410410742002200141046a28020036020c20002002410c6a41041074200141086a22012003470d000b0b200241106a24000f0b1038000b1036000ba50101047f230041106b2202240020002802002103200028020822002001107602402000450d002003200041386c6a210403402001200341086a41201074200220032903003703082001200241086a41081074200328022821002003280230220520011076200341386a210302402005450d002005410574210503402001200041201074200041206a2100200541606a22050d000b0b20032004470d000b0b200241106a24000b990101037f230041106b2202240020002802002103200028020822002001107602402000450d002003200041c8006c6a2104034020022003108a012001200228020022002002280208107402402002280204450d002000102e0b2002200341246a2203108a012001200228020022002002280208107402402002280204450d002000102e0b200341246a22032004470d000b0b200241106a24000b8d0101037f230041106b22022400200028020021032000280208220020011076024002402000450d002000410574210003404120102c2204450d02200242203702042002200436020020022003412010742001200228020022042002280208107402402002280204450d002004102e0b200341206a2103200041606a22000d000b0b200241106a24000f0b1036000bde0103037f017e017f230041106b22022400200028020021032000280208220020011076024020004106742200450d00200320006a210403402001200341201074200329032021052002200341286a290300370308200220053703002001200241101074200328023021002003280238220620011076200341c0006a21030240200641306c2206450d00200020066a210603402001200041201074200041206a29030021052002200041286a290300370308200220053703002001200241101074200041306a22002006470d000b0b20032004470d000b0b200241106a24000bdc0201047f230041206b2203240002400240200041086a28020022042001490d00024002402004200041046a280200470d00200441016a22052004490d03200441017422062005200620054b1b22054104200541044b1b220541ffffff3f712005464103742106200541057421050240024020040d00200341003602100c010b200341106a41086a410836020020032004410574360214200320002802003602100b200320052006200341106a107d200341086a280200210520032802004101460d0120002003280204360200200041046a20054105763602000b200028020020014105746a220541206a2005200420016b41057410ea081a200541186a200241186a290300370300200541106a200241106a290300370300200541086a200241086a29030037030020052002290300370300200041086a200441016a360200200341206a24000f0b2005450d011036000b200120041045000b1038000bf70301087f200041086a22032802002104410021052003410036020002402004450d004100210541002106024003400240024020050d0020012802002207210803402000280200200641306c6a210903402008450d0320082009412010ec0841004a0d0302400240200228020022082002280204470d00410021080c010b2002200841206a3602000b2001200836020020072009412010ec08210a20082107200a4100480d000b200821072004200641016a22064b0d000b410021050c040b03402000280200200641306c6a210920012802002207210803402008450d0220082009412010ec0841004a0d0202400240200228020022082002280204470d00410021080c010b2002200841206a3602000b2001200836020020072009412010ec08210a20082107200a4100480d000b2000280200200620056b41306c6a22082009290300370300200841286a200941286a290300370300200841206a200941206a290300370300200841186a200941186a290300370300200841106a200941106a290300370300200841086a200941086a2903003703002004200641016a22064d0d030c000b0b200541016a21052004200641016a22064b0d000b0b024020050d00410021050c010b20002802002208200620056b41306c6a2008200641306c6a200420066b41306c10ea081a0b2003200420056b3602000be10101047f230041206b22012400024002400240200041046a28020020002802082202470d00200241016a22032002490d02200241017422042003200420034b1b22034104200341044b1b220341ffffffff01712003464102742104200341037421030240024020020d00200141003602100c010b200141186a410436020020012002410374360214200120002802003602100b200120032004200141106a107d200141086a280200210220012802004101460d0120002001280204360200200041046a20024103763602000b200141206a24000f0b2002450d001036000b1038000baf0c01107f230041a0036b2202240002400240024020012802082203200128020c460d0020012802102104200241b4026a2105200241e0026a41206a2106200241c8016a4104722107200241d0006a4104722108200241106a41386a2109200241106a41306a210a200241106a41286a210b03402001200341206a36020820082003290000370000200841086a200341086a290000370000200841106a200341106a290000370000200841186a200341186a29000037000020022004360250024002402004200810be01450d002001200128021041016a22043602100c010b200241c8016a41206a200241d0006a41206a280200360200200241c8016a41186a200241d0006a41186a290300370300200241c8016a41106a200241d0006a41106a290300370300200241c8016a41086a200241d0006a41086a290300370300200220022903503703c801200241f0016a41186a2203200741186a220c290000370300200241f0016a41106a220d200741106a220e290000370300200241f0016a41086a220f200741086a2210290000370300200220072900003703f001200241e0026a41186a2204200c290000370300200241e0026a41106a220c200e290000370300200241e0026a41086a220e2010290000370300200220072900003703e00220024190026a200241e0026a10bf01200241c0026a41186a22102003290300370300200241c0026a41106a2211200d290300370300200241c0026a41086a220d200f290300370300200220022903f0013703c0020240024020022802b00222030d00410021030c010b2006200229039002370300200641186a20024190026a41186a290300370300200641106a20024190026a41106a290300370300200641086a20024190026a41086a29030037030020042010290300370300200c2011290300370300200e200d290300370300200241f8006a41086a200541086a280200360200200220022903c0023703e0022002200529020037037820024188016a41386a200241e0026a41386a29030037030020024188016a41306a200241e0026a41306a29030037030020024188016a41286a200241e0026a41286a29030037030020024188016a41206a200629030037030020024188016a41186a200429030037030020024188016a41106a200c29030037030020024188016a41086a200e290300370300200220022903e002370388010b0240024020030d0020094200370300200a4200370300200b4200370300200241106a41206a4200370300200241106a41186a4200370300200241106a41106a4200370300200241106a41086a4200370300200241086a410036020020024200370310200242003703000c010b200920024188016a41386a290300370300200a20024188016a41306a290300370300200b20024188016a41286a290300370300200241106a41206a20024188016a41206a290300370300200241106a41186a20024188016a41186a290300370300200241106a41106a20024188016a41106a290300370300200241106a41086a20024188016a41086a290300370300200241086a200241f8006a41086a2802003602002002200229038801370310200220022903783703000b2001200128021041016a220436021020030d030b20012802082203200128020c470d000b0b200041003602400c010b200241e0026a41386a2201200241106a41386a290300370300200241e0026a41306a2208200241106a41306a290300370300200241e0026a41286a2204200241106a41286a290300370300200241e0026a41206a2207200241106a41206a290300370300200241e0026a41186a2206200241106a41186a290300370300200241e0026a41106a220c200241106a41106a290300370300200241e0026a41086a220e200241106a41086a29030037030020024188016a41086a220d200241086a280200360200200220022903103703e0022002200229030037038801200041386a2001290300370300200041306a2008290300370300200041286a2004290300370300200041206a2007290300370300200041186a2006290300370300200041106a200c290300370300200041086a200e290300370300200020022903e002370300200020033602402000200229038801370244200041cc006a200d2802003602000b200241a0036a24000bc10501037f23004190016b22022400200241e0006a22034200370300200241d8006a22044200370300200241c8006a41086a420037030020024200370348200241c8006a41a081ca004107108102200241e8006a41e4d1c100410c1081022003200241e8006a41086a29000037030020042002290068370300200241106a200241c8006a4120108e02200241c8006a2002280214410020022802101b2204200010c206200228024822002002280250108f0221030240200228024c450d002000102e0b4101210002400240024020030d00200241186a41bed8c8004108108102200241e8006a41edd8c800410e108102200220043602382002200241386a410410a301370378200241d4006a2203200241386a41046a3602002002200241f8006a41086a36024c2002200241386a3602502002200241f8006a360248200241286a200241c8006a107c4120102c2200450d012002422037027c20022000360278200241f8006a200141201074200220022802782200200228028001220410a301370388012003200020046a36020020022000360250200220024188016a41086a36024c200220024188016a360248200241386a200241c8006a107c0240200228027c450d002000102e0b20022802302203200228024022046a41206a2200417f4c0d020240024020000d00410121010c010b2000102c2201450d020b200241003602502002200036024c20022001360248200241c8006a200241186a41101074200241c8006a200241e8006a41101074200241c8006a2002280228220020031074200241c8006a20022802382203200410740240200228023c450d002003102e0b0240200228022c450d002000102e0b200241086a200228024822042002280250108e02200228020c2100200228020821030240200228024c450d002004102e0b200341004720004100477121000b20024190016a240020000f0b1036000b1038000bbf0302077f017e230041a0016b22022400200241086a1094030240024020022903084202520d00200041003602200c010b200241f0006a200241086a41106a280200200110a103200241c0006a20022802702203200228027810a20320024180016a41186a2204200241c0006a41186a29030037030020024180016a41106a2205200241c0006a41106a2903003703004108210120024180016a41086a2206200241c0006a41086a2903003703002002200229034037038001200241ec006a280200210702400240200228026022080d0042002109200241206a41186a4200370300200241206a41106a4200370300200241206a41086a4200370300200242003703200c010b200241206a41086a2006290300370300200241206a41106a2005290300370300200241206a41186a2004290300370300200220022903800137032020022902642109200821010b02402002280274450d002003102e0b2000200229032037030020002009370224200020013602202000412c6a2007360200200041186a200241206a41186a290300370300200041106a200241206a41106a290300370300200041086a200241206a41086a2903003703000b200241a0016a24000bb60303057f017e037f230041e0006b2202240002400240200128020c2203200128020822046b2205410675220641ffffff3f712006470d0020054101752205417f4c0d00200129020021070240024020050d00410121010c010b2005102c2201450d020b20002001360200200041086a220841003602002000200541057636020420004100200610c10120082802002105024020042003460d00200028020020054105746a2100200241206a41206a21010340200241206a41386a200441386a290300370300200241206a41306a200441306a290300370300200241206a41286a200441286a2903003703002001200441206a290300370300200241086a2206200141086a290000370300200241106a2209200141106a290000370300200241186a220a200141186a29000037030020022001290000370300200041186a200a290300370000200041106a2009290300370000200041086a200629030037000020002002290300370000200541016a2105200041206a21002003200441c0006a2204470d000b0b20082005360200024020074280808080f0ffffff0383500d002007a7102e0b200241e0006a24000f0b1038000b1036000bdd0101027f230041206b22032400024002400240200041046a280200220420016b20024f0d00200120026a22022001490d02200441017422012002200120024b1b22014104200141044b1b220141ffffff3f712001462102200141057421010240024020040d00200341003602100c010b200341186a410136020020032004410574360214200320002802003602100b200320012002200341106a107d200341086a280200210120032802004101460d0120002003280204360200200041046a20014105763602000b200341206a24000f0b2001450d001036000b1038000bad0204047f017e017f037e02400240200128020c2202200128020822036b41306d220441ffffff3f712004470d0020044105742205417f4c0d00200129020021060240024020050d00410121010c010b2005102c2201450d020b20002001360200200041086a220741003602002000200541057636020420004100200410c1012006422088a7210420072802002101024020032002460d00200028020020014105746a21000340200341086a2900002108200341106a29000021092003290000210a200041186a200341186a290000370000200041106a2009370000200041086a20083700002000200a370000200141016a2101200041206a21002002200341306a2203470d000b0b2007200136020002402004450d00200441306c450d002006a7102e0b0f0b1038000b1036000b820203017f017e067f0240024020012802082202ad420c7e2203422088a70d002003a72204417f4c0d00200128020021054104210102402004450d002004102c2201450d020b2000410036020820002001360200200041046a2004410c6e220636020002402004410c490d00200241ffffffff0371210703402007450d01200541086a2802002204417f4c0d02200528020021080240024020040d00410121090c010b2004102c2209450d040b20092008200410e9082108200141086a2004360200200141046a2004360200200120083602002005410c6a21052001410c6a21012007417f6a21072006417f6a22060d000b0b200020023602080f0b1038000b1036000bd10503027f017e0a7f230041206b220224000240024020012802082203ad42247e2204422088a70d002004a72205417f4c0d00200128020021064104210702402005450d002005102c2207450d020b410021082000410036020820002007360200200041046a200541246e2209360200024020054124490d002002411e6a210a034020052008460d014101210b02400240024002400240200620086a22012d00000e050104020300010b200a200141036a2d00003a00004104210b200241086a41046a200141146a2d00003a00002002200141016a2f00003b011c2002200141106a2800003602082001410c6a280000210c200141086a280000210d200141046a280000210e0c030b200a200141036a2d00003a0000200241086a41086a200141186a290000370300200241086a41106a200141206a2d00003a00002002200141016a2f00003b011c2002200141106a2900003703082001410c6a280000210c200141086a280000210d200141046a280000210e4100210b0c020b2001410c6a280200220d417f4c0d04200141046a280200210102400240200d0d004101210e0c010b200d102c220e450d060b200e2001200d10e9081a4102210b200d210c0c010b4103210b200a200141036a2d00003a0000200241086a41086a200141186a290000370300200241086a41106a200141206a2d00003a00002002200141016a2f00003b011c2002200141106a2900003703082001410c6a280000210c200141086a280000210d200141046a280000210e0b200720086a2201200b3a0000200141016a20022f011c3b0000200141036a200a2d00003a00002001410c6a200c360200200141086a200d360200200141046a200e360200200141106a2002290308370200200141186a200241086a41086a290300370200200141206a200241086a41106a280200360200200841246a21082009417f6a22090d000b0b20002003360208200241206a24000f0b1038000b1036000bdb0205027f017e037f017e037f230041206b220224000240024020012802082203ad42307e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410821010c010b2005102c2201450d020b2000410036020820002001360200200041046a200541306e2207360200024020054130490d00200341ffffffff0071210503402005450d01200641086a290300210420062903002108200241186a2209200641286a290300370300200241106a220a200641206a290300370300200241086a220b200641186a2903003703002002200641106a2903003703002001200437030820012008370300200141106a2002290300370300200141186a200b290300370300200141206a200a290300370300200141286a2009290300370300200641306a2106200141306a21012005417f6a21052007417f6a22070d000b0b20002003360208200241206a24000f0b1038000b1036000bbf0304027f017e067f077e230041306b220224000240024020012802082203ad42d0007e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410821010c010b2005102c2201450d020b2000410036020820002001360200200041046a200541d0006e22073602000240200541d000490d0003402005450d01200241106a41086a2208200641086a290300370300200241106a41106a2209200641106a290300370300200241106a41186a220a200641186a29030037030020022006290300370310200641286a2903002104200641306a290300210b200641386a290300210c2006290320210d2002200641c0006a10c501200a290300210e2009290300210f2008290300211020022903102111200141386a200c370300200141306a200b370300200141286a2004370300200141206a200d370300200141086a201037030020012011370300200141106a200f370300200141186a200e370300200141c0006a2002290300370300200141c8006a200241086a280200360200200141d0006a2101200541b07f6a2105200641d0006a21062007417f6a22070d000b0b20002003360208200241306a24000f0b1038000b1036000bdd0603027f017e0d7f230041106b220224000240024020012802082203ad42247e2204422088a70d002004a72205417f4c0d00200128020021064104210702402005450d002005102c2207450d020b410021082000410036020820002007360200200041046a200541246e2209360200024020054124490d00034020052008460d010240024002400240024002400240200620086a22012d00000e06010203040500010b2001410c6a280200220a417f4c0d08200141046a280200210102400240200a0d004101210b0c010b200a102c220b450d0a0b200b2001200a10e908410876210c4105210d200a210e0c050b2002200141146a2900003703002002200141196a290000370005200141016a2f0000200141036a2d000041107472210f200141046a280000220b410876210c200141106a28000021102001410c6a280000210a200141086a280000210e4100210d0c040b200141106a2802002210417f4c0d06200141036a2d0000210f200141016a2f0000210a200141086a2802002111200141046a2d0000210b4101210d4101210e02402010450d002010102c220e450d080b200a200f41107472210f200e2011201010e9081a2010210a0c030b200141106a2802002210417f4c0d05200141036a2d0000210f200141016a2f0000210a200141086a280200210d200141046a2d0000210b0240024020100d004101210e0c010b2010102c220e450d070b200a200f41107472210f200e200d201010e9081a4102210d2010210a0c020b200141106a2802002210417f4c0d04200141036a2d0000210f200141016a2f0000210a200141086a280200210d200141046a2d0000210b0240024020100d004101210e0c010b2010102c220e450d060b200a200f41107472210f200e200d201010e9081a4103210d2010210a0c010b4104210d200141046a280200210b2001410c6a280200210a200141086a280200210e4100210c0b200720086a2201200d3a0000200141036a200f4110763a0000200141016a200f3b0000200141106a20103602002001410c6a200a360200200141086a200e360200200141046a200c410874200b41ff017172360200200141146a20022903003702002001411c6a200241086a290300370200200841246a21082009417f6a22090d000b0b20002003360208200241106a24000f0b1038000b1036000be20102047f037e024002402001280208220241ffffff3f712002470d0020024105742203417f4c0d00200128020021040240024020030d00410121010c010b2003102c2201450d020b2000410036020820002001360200200041046a2003410576220536020002402003450d0003402005450d01200441086a2900002106200441106a290000210720042900002108200141186a200441186a290000370000200141106a2007370000200141086a200637000020012008370000200141206a2101200441206a21042005417f6a22050d000b0b200020023602080f0b1038000b1036000bf4380f027f017e167f017e017f027e0d7f027e047f017e057f047e0b7f027e037f230041c0056b220224000240024020012802082203ad42b0027e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410821070c010b2005102c2207450d020b410021082000410036020820002007360200200041046a200541b0026e22093602000240200541b002490d00200241a8036a210a20024190056a210b200241d0036a210c200241a4036a210d200241f8036a210e200241d8036a210f200241b8036a211020024198036a2111200241d4036a2112200241a0036a2113034020052008460d0102400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200620086a22012802000e1c0102030405060708090a0b0c0d0e0f101112131415161718191a1b00010b20024190036a200141386a10ca0120024180036a41086a2214200141246a2d00003a000020022001411c6a29020037038003200141256a2d000021152002200141266a2f01003b01be01200141186a2802002116200141146a2802002117200141106a2802002118200141086a2903002104200141286a28020021192001412c6a280200211a200141306a290300211b200141f8016a280200211c200229039003211d200229039803211e200241d0016a201341b00110e9081a20014184026a280200211f20014180026a2802002120200241c0016a41086a20142d00003a000020022002290380033703c001200241086a200241d0016a41b00110e9081a411b21140c1b0b20024190036a200141086a10cb01200220022802a4033602c00120022802a0032116200228029c03211720022802980321182002290390032104410021140c1a0b20024190036a200141046a10cc01200241c0016a41086a200a41086a2d00003a00002002200a2902003703c001200220022f01b2033b01be0120022802a403211620022802a0032117200228029c0321182002290294032104200228029003212120022d00b1032115410121140c190b20024190036a200141086a10cd01200241c0016a41086a200d41086a2d00003a00002002200d2902003703c001200220022f01ae033b01be01200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a20022903c803211e200241086a200c41b00110e9081a200241d0016a41086a200b41086a290200370300200241d0016a41106a200b41106a290200370300200241d0016a41186a200b41186a2902003703002002200b2902003703d001200228028c05211f20022802880521202002280284052122200228028005211c410221140c180b200141086a2903002104410321140c170b4104211402400240024002400240024002400240200141046a2d0000417f6a0e050102030405000b41e2a0cc00412841e89bc4001039000b200141086a2802002101410121140c040b20024190036a41086a200141246a2d00003a000020022001411c6a29000037039003200141056a2f0000200141076a2d0000411074722123200141186a2800002116200141146a2800002117200141106a2800002124200141286a2802002119200141086a2900002204a721012004422088a7212541022114202621150c040b200141086a2802002101410321140c020b20024190036a41086a200141246a2d00003a000020022001411c6a29000037039003200141056a2f0000200141076a2d0000411074722123200141256a2d00004100472115200141186a2800002116200141146a2800002117200141106a2800002124200141286a2802002119200141086a2900002204a721012004422088a721250c020b200141086a2802002101410521140b202721192026211520282117202921160b200241c0016a41086a20024190036a41086a2d00003a000020022002290390033703c001200220022f01d0013b01be01202341087420147221212025ad4220862001ad8421044104211420192127201521262017212820162129202421180c160b20024190036a200141086a10ce01200241c0016a41086a200d41086a2d00003a0000200241086a41086a200c41086a290200370300200241086a41106a200c41106a290200370300200241086a41186a200c41186a2902003703002002200d2902003703c001200220022f01ae033b01be012002200c290200370308200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a20022903c803211e410521140c150b20024190036a200141046a10cf0120022902940321042002280290032121410621140c140b20024190036a200141086a10d001200241c0016a41086a200d41086a2d00003a0000200241086a41086a200c41086a290200370300200241086a41106a200c41106a2902003703002002200d2902003703c001200220022f01ae033b01be012002200c290200370308200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a20022903c803211e410721140c130b10d101000b02400240200141046a22142802000d0041002121202a2117202b21160c010b200241086a41086a200141246a2d00003a0000201141186a200141e8006a290200370200201141106a200141e0006a290200370200201141086a200141d8006a2902003702002011200141d0006a29020037020020022001411c6a2900003703082002200141266a2f01003b01c0012002200141c8006a29020037039003200141386a290200212c200141306a290200212d200141186a2802002116200141146a2802002117200141106a280200212e200141256a2d0000212f200141286a28020021302001412c6a2802002131200141c0006a2902002132201041186a20014188016a290200370200201041106a20014180016a290200370200201041086a200141f8006a2902003702002010200141f0006a290200370200200f20014190016a290200370200200f41086a20014198016a290200370200200f41106a200141a0016a290200370200200f41186a200141a8016a290200370200200e200141b0016a290200370200200e41086a200141b8016a290200370200200e41106a200141c0016a290200370200200e41186a200141c8016a2902003702002001410c6a2802002233417f4c0d15201428020021010240024020330d00410121210c010b2033102c2221450d170b20212001203310e9081a20024180036a41086a200241086a41086a2d00003a00002002200229030837038003200220022f01c0013b01ce01200241d0016a20024190036a41880110e9081a2017212a2016212b0b200241c0016a41086a20024180036a41086a2d00003a000020022002290380033703c001200220022f01ce013b01be01200241086a200241d0016a41880110e9081a2033ad4220862033ad842104410921142032211e202d211b202c211d2031211a20302119202f2115202e21180c110b20024190036a200141086a10d201200241c0016a41086a200d41086a2d00003a00002002200d2902003703c001200220022f01ae033b01be01200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a20022903c803211e200241086a200c41b00110e9081a200241d0016a41086a200b41086a290200370300200241d0016a41106a200b41106a2902003703002002200b2902003703d001200228028c05211f20022802880521202002280284052122200228028005211c410a21140c100b20024190036a200141046a10d301200241c0016a41086a200a41086a2d00003a0000200241086a41086a201241086a290200370300200241086a41106a201241106a290200370300200241086a41186a201241186a290200370300200241086a41206a201241206a2802003602002002200a2902003703c001200220022f01b2033b01be0120022012290200370308200241c4036a290200211d20022902bc03211b20022802a403211620022802a0032117200228029c0321182002290294032104200228029003212120022d00b103211520022802b403211920022802b803211a20022902cc03211e410b21140c0f0b10d401000b20024190036a200141086a10d501200241c0016a41086a200d41086a2d00003a00002002200d2902003703c001200220022f01ae033b01be01200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a410d21140c0d0b20024190036a200141086a10d601200241c0016a41086a200d41086a2d00003a00002002200d2902003703c001200220022f01ae033b01be01200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a410e21140c0c0b20024190036a200141086a10d601200241c0016a41086a200d41086a2d00003a00002002200d2902003703c001200220022f01ae033b01be01200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a410f21140c0b0b20024190036a200141086a10d701200241c0016a41086a200d41086a2d00003a00002002200d2902003703c001200220022f01ae033b01be0120022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a411021140c0a0b4107211702400240024002400240024002400240200141046a2d0000417f6a0e0701020304050607000b41e2a0cc00412841a4c3cb001039000b20024190036a41086a200141246a2d00003a000020022001411c6a29000037039003200141056a2f0000200141076a2d0000411074722134200141186a2800002135200141146a2800002136200141106a2800002137200141086a2900002138410121170c050b20024190036a41086a200141246a2d00003a000020022001411c6a29000037039003200141056a2f0000200141076a2d0000411074722134200141186a2800002135200141146a2800002136200141106a2800002137200141086a2900002138410221170c040b20024190036a41086a200141246a2d00003a000020022001411c6a290000370390032002200141266a2f00003b01d001200141056a2f0000200141076a2d000041107472213420394280808080806083200141c0006a350000200141c4006a31000042208684842139200141386a290000213a200141306a290000213b2001412c6a280000213c200141286a280000213d200141256a2d0000213e200141186a2800002135200141146a2800002136200141106a2800002137200141086a2900002138410321170c030b20024190036a200141086a10c80120022802980321372002290390032138410421170c020b20024190036a41086a200141246a2d00003a000020022001411c6a2900003703900341052117200141056a2f0000200141076a2d0000411074722134200141186a2800002135200141146a2800002136200141106a2800002137200141086a29000021380c010b20024190036a41086a200141246a2d00003a000020022001411c6a29000037039003200141056a2f0000200141076a2d0000411074722134200141186a2800002135200141146a2800002136200141106a2800002137200141086a2900002138410621170b200241c0016a41086a20024190036a41086a2d00003a000020022002290390033703c001200220022f01d0013b01be0120344108742017722121411121142039211e203b211b203a211d203c211a203d2119203e2115203621172035211620372118203821040c090b024002400240024002400240200141086a280200417f6a0e03010203000b41e2a0cc0041284184ccc2001039000b200141386a290300211d200141306a290300211b41012117024002400240024002402001410c6a2d00000e050104020300010b4104211720024190036a41046a200141206a2d00003a000020022001411c6a280000360290032001410d6a2f00002001410f6a2d000041107472213f200141186a2800002140200141146a2800002141200141106a28000021420c030b20024198036a200141246a2d00003a000020022001411c6a290000370390032002200141266a2f00003b01082001410d6a2f00002001410f6a2d000041107472213f2001412c6a2d00002143200141286a2800002144200141256a2d00002145200141186a2800002140200141146a2800002141200141106a2800002142410021170c020b200141186a2802002241417f4c0d11200141106a28020021010240024020410d00410121420c010b2041102c2242450d130b20422001204110e9081a41022117204121400c010b20024198036a200141246a2d00003a000020022001411c6a290000370390032002200141266a2f00003b01082001410d6a2f00002001410f6a2d000041107472213f2001412c6a2d00002143200141286a2800002144200141256a2d00002145200141186a2800002140200141146a2800002141200141106a2800002142410321170b200241d0016a41086a20024190036a41086a2d00003a000020022002290390033703d001200220022f01083b018003204341ff0171211a42012104203f21010c030b2001410c6a28020022174108762101420221040c010b2001410c6a28020022174108762101420321040b2046211a2047211b2048211d0b200241c0016a41086a200241d0016a41086a2d00003a0000200220022903d0013703c001200220022f0180033b01be012001410874201741ff017172ad422086200484210441122114201a2146201b2147201d214820442119204521152041211720402116204221180c080b20024190036a200141086a10d801200241c0016a41086a200d41086a2d00003a0000200241086a41086a200c41086a290200370300200241086a41106a200c41106a290200370300200241086a41186a200c41186a290200370300200241086a41206a200c41206a290200370300200241086a41286a200c41286a2902003703002002200d2902003703c001200220022f01ae033b01be012002200c290200370308200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a20022903c803211e411321140c070b20024190036a200141086a10d901200241c0016a41086a200d41086a2d00003a0000200241086a41086a200c41086a290200370300200241086a41106a200c41106a290200370300200241086a41186a200c41186a290200370300200241086a41206a200c41206a290200370300200241086a41286a200c41286a290200370300200241086a41306a200c41306a2902003703002002200d2902003703c001200220022f01ae033b01be012002200c29020037030820024190036a41306a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a20022903c803211e411421140c060b0240024002400240200141046a2f0100417f6a0e03010200010b20024190036a200141086a10c9012002280298032149200228029403214a2002280290032114410321010c020b20024190036a200141086a10c9012002280298032149200228029403214a2002280290032114410121010c010b200141066a2f0100214b41b002102c2214450d0a20024190036a200141086a28020010da01201420024190036a41b00210e9081a410221010b204b4110742001722121204aad4220862014ad84210441152114204921180c050b20024190036a200141086a10db01200241c0016a41086a200d41086a2d00003a00002002200d2902003703c001200220022f01ae033b01be01200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a20022903c803211e200241086a200c41b00110e9081a200241d0016a41086a200b41086a290200370300200241d0016a41106a200b41106a290200370300200241d0016a41186a200b41186a290200370300200241d0016a41206a200b41206a2902003703002002200b2902003703d001200228028c05211f20022802880521202002280284052122200228028005211c411621140c040b20024190036a200141046a10dc01200241c0016a41086a200a41086a2d00003a00002002200a2902003703c001200220022f01b2033b01be01200220022802d403360208200241c4036a290200211d20022902bc03211b20022802a403211620022802a0032117200228029c0321182002290294032104200228029003212120022d00b103211520022802b403211920022802b803211a20022902cc03211e411721140c030b20024190036a200141086a10dd01200241c0016a41086a200d41086a2d00003a00002002200d2902003703c001200220022f01ae033b01be01200220022903d003370308200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a20022903c803211e411821140c020b20024190036a200141086a10de01200241c0016a41086a200d41086a2d00003a00002002200d2902003703c001200220022f01ae033b01be01200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a20022903c803211e411921140c010b20024190036a200141086a10df01200241c0016a41086a200d41086a2d00003a00002002200d2902003703c001200220022f01ae033b01be01200241c0036a290300211d20022903b803211b20022802a0032116200228029c0321172002280298032118200229039003210420022d00ad03211520022802b003211920022802b403211a20022903c803211e411a21140b200720086a22012014360200200141186a2016360200200141146a2017360200200141106a2018360200200141086a2004370300200141046a2021360200200241c0016a41086a2d0000211420022903c0012104200141256a20153a0000200141386a201d370200200141306a201b3702002001411c6a2004370200200141246a20143a0000200141c0006a201e3702002001412c6a201a360200200141286a2019360200200141266a20022f01be013b0100200141c8006a200241086a41b00110e9081a20014184026a201f36020020014180026a2020360200200141fc016a2022360200200141f8016a201c36020020014188026a20022903d00137020020014190026a200241d0016a41086a29030037020020014198026a200241d0016a41106a290300370200200141a0026a200241d0016a41186a290300370200200141a8026a200241f0016a290300370200200841b0026a21082009417f6a22090d000b0b20002003360208200241c0056a24000f0b1038000b1036000bce0d03057f017e287f024002402001280208220241ffffffff01712002470d0020024103742203417f4c0d00200128020021040240024020030d00410421050c010b2003102c2205450d020b200020053602002000200341037636020420052004200241037410e9081a20002002360208200141146a2802002206ad420c7e2207422088a70d002007a72204417f4c0d00200128020c21034104210202402004450d002004102c2202450d020b20022003200410e9082108200141206a280200220241ffffffff00712002470d0020024104742209417f4c0d00200128021821054104210302402009450d002009102c2203450d020b20032005200241047410e908210a2001412c6a280200220bad42147e2207422088a70d002007a7220c417f4c0d002001280224210302400240200c0d00410421050c010b200c102c2205450d020b20052003200c10e908210d200141386a280200220ead42187e2207422088a70d002007a7220f417f4c0d002001280230210302400240200f0d00410421050c010b200f102c2205450d020b20052003200f10e9082110200141c4006a2802002211ad421c7e2207422088a70d002007a72212417f4c0d00200128023c21030240024020120d00410421050c010b2012102c2205450d020b20052003201210e9082113200141d0006a280200220341ffffff3f712003470d0020034105742214417f4c0d00200128024821050240024020140d00410421150c010b2014102c2215450d020b20152005200341057410e9082116200141dc006a2802002217ad42247e2207422088a70d002007a72215417f4c0d00200128025421050240024020150d00410421180c010b2015102c2218450d020b20182005201510e9082119200141e8006a280200221aad42287e2207422088a70d002007a72218417f4c0d00200128026021050240024020180d004104211b0c010b2018102c221b450d020b201b2005201810e908211c200141f4006a280200221dad422c7e2207422088a70d002007a7221b417f4c0d00200128026c210502400240201b0d004104211e0c010b201b102c221e450d020b201e2005201b10e908211f20014180016a2802002220ad42307e2207422088a70d002007a7221e417f4c0d002001280278210502400240201e0d00410421210c010b201e102c2221450d020b20212005201e10e90821222001418c016a2802002223ad42347e2207422088a70d002007a72221417f4c0d0020012802840121050240024020210d00410421240c010b2021102c2224450d020b20242005202110e908212520014198016a2802002226ad42387e2207422088a70d002007a72224417f4c0d0020012802900121050240024020240d00410421270c010b2024102c2227450d020b20272005202410e9082128200141a4016a2802002229ad423c7e2207422088a70d002007a72227417f4c0d00200128029c0121050240024020270d004104212a0c010b2027102c222a450d020b202a2005202710e908212b200141b0016a280200220541ffffff1f712005470d002005410674222c417f4c0d0020012802a801212a02400240202c0d004104212d0c010b202c102c222d450d020b202d202a200541067410e908212d200141bc016a280200222ead42c4007e2207422088a70d002007a7222a417f4c0d0020012802b401212f410421010240202a450d00202a102c2201450d020b2001202f202a10e9082101200041bc016a202e360200200041b8016a202a41c4006e360200200020013602b401200041b0016a2005360200200041ac016a202c4106763602002000202d3602a801200041a4016a2029360200200041a0016a2027413c6e3602002000202b36029c0120004198016a202636020020004194016a202441386e36020020002028360290012000418c016a202336020020004188016a202141346e360200200020253602840120004180016a2020360200200041fc006a201e41306e36020020002022360278200041f4006a201d360200200041f0006a201b412c6e3602002000201f36026c200041e8006a201a360200200041e4006a201841286e3602002000201c360260200041dc006a2017360200200041d8006a201541246e36020020002019360254200041d0006a2003360200200041cc006a201441057636020020002016360248200041c4006a2011360200200041c0006a2012411c6e3602002000201336023c200041386a200e360200200041346a200f41186e360200200020103602302000412c6a200b360200200041286a200c41146e3602002000200d360224200041206a20023602002000411c6a20094104763602002000200a360218200041146a2006360200200041106a2004410c6e3602002000200836020c0f0b1038000b1036000b9d0803047f017e087f230041106b2202240002400240024002400240024002400240024002400240024002402001280200417f6a0e0a01020304050607080900010b2001410c6a2802002203417f4c0d0a200128020421010240024020030d00410121040c010b2003102c2204450d0c0b20042001200310e90821012000410c6a2003360200200041086a2003360200200020013602042000410a3602000c090b20004101360200200020012802043602040c080b2001410c6a2802002203417f4c0d08200128020421010240024020030d00410121040c010b2003102c2204450d0a0b20042001200310e90821012000410c6a2003360200200041086a200336020020002001360204200041023602000c070b20004103360200200041086a200141086a2903003703000c060b2001410c6a2802002203417f4c0d06200128020421010240024020030d00410121040c010b2003102c2204450d080b20042001200310e90821012000410c6a2003360200200041086a200336020020002001360204200041043602000c050b2001410c6a2802002203417f4c0d05200128020421010240024020030d00410121040c010b2003102c2204450d070b20042001200310e90821012000410c6a2003360200200041086a200336020020002001360204200041053602000c040b20004106360200200020012902043702042000410c6a2001410c6a2802003602000c030b2001410c6a2802002205ad42187e2206422088a70d032006a72203417f4c0d030240024020030d00200341186e2107410421080c010b200128020421092003102c2208450d05200341186e210720034118490d00200541ffffffff0171210a4100210b2007210c0340200a450d012009200b6a220141086a2802002203417f4c0d05200128020021040240024020030d004101210d0c010b2003102c220d450d070b200d2004200310e908210d200141146a2802002204417f4c0d052001410c6a28020021010240024020040d004101210e0c010b2004102c220e450d070b200e2001200410e908210e2008200b6a2201200d360200200141146a2004360200200141106a20043602002001410c6a200e360200200141086a2003360200200141046a2003360200200a417f6a210a200b41186a210b200c417f6a220c0d000b0b20002008360204200041073602002000410c6a2005360200200041086a20073602000c020b2002200141046a10c301200041083602002000410c6a200241086a280200360200200020022903003702040c010b2001410c6a2802002203417f4c0d01200128020421040240024020030d004101210b0c010b2003102c220b450d030b200b2004200310e90821042000410c6a2003360200200041086a20033602002000200436020420004109360200200041106a20012802103602000b200241106a24000f0b1038000b1036000bca0701097f230041b0026b22022400024002400240024002400240024002400240024020012d0000417f6a0e06010203040506000b41e2a0cc00412841ecb0c4001039000b200141106a28020021032001410c6a2802002104200141086a2802002105200141046a280200210620012d0001210741b002102c2208450d062002200141146a28020010a8042008200241b00210e9082101200041106a20033602002000410c6a2004360200200041086a2005360200200041046a2006360200200041146a2001360200200020073a0001200041013a00000c050b200041023a0000200041046a200141046a2902003702000c040b2001410c6a2802002203417f4c0d05200141046a28020021040240024020030d00410121050c010b2003102c2205450d050b20052004200310e90821042001411c6a2802002105200141186a280200210620012d00012107200128021421082001280210210941b002102c220a450d042002200128022010a804200a200241b00210e90821012000411c6a2005360200200041186a2006360200200041146a2008360200200041106a20093602002000410c6a2003360200200041086a2003360200200041046a2004360200200041206a2001360200200020073a0001200041033a00000c030b2001410c6a2802002203417f4c0d04200141046a28020021010240024020030d00410121040c010b2003102c2204450d040b20042001200310e90821012000410c6a2003360200200041086a2003360200200041046a2001360200200041043a00000c020b200141106a28020021032001410c6a2802002104200141086a2802002105200141046a280200210620012d0001210741b002102c2208450d022002200141146a28020010a8042008200241b00210e9082101200041106a20033602002000410c6a2004360200200041086a2005360200200041046a2006360200200041146a2001360200200020073a0001200041053a00000c010b2001410c6a2802002203417f4c0d02200141046a28020021040240024020030d00410121050c010b2003102c2205450d020b20052004200310e90821042001411c6a2802002105200141186a280200210620012d00012107200128021421082001280210210941b002102c220a450d012002200128022010a804200a200241b00210e90821012000411c6a2005360200200041186a2006360200200041146a2008360200200041106a20093602002000410c6a2003360200200041086a2003360200200041046a2004360200200041206a2001360200200020073a0001200041063a00000b200241b0026a24000f0b1036000b1038000b9b1b03047f017e167f230041e0036b2202240002400240024002402001280200417f6a0e03010200010b20004103360200200041186a200141186a2d00003a0000200041106a200141106a290300370300200041086a200141086a2903003703000c020b20024180026a41186a220320014198026a29000037030020024180026a41106a220420014190026a29000037030020024180026a41086a220520014188026a290000370300200220014180026a29000037038002200141186a2903002106200241e0026a41086a2207200141386a290200370300200241e0026a41106a2208200141c0006a290200370300200241e0026a41186a2209200141c8006a290200370300200241c0026a41086a220a200141d8006a290200370300200241c0026a41106a220b200141e0006a290200370300200241c0026a41186a220c200141e8006a290200370300200241a0026a41086a220d200141f8006a290200370300200241a0026a41106a220e20014180016a290200370300200241a0026a41186a220f20014188016a2902003703002002200141306a2902003703e0022002200141d0006a2902003703c0022002200141f0006a2902003703a002200141206a2802002110200241f0016a200141246a10c701200241c0036a41086a2211200141a8016a290200370300200241c0036a41106a2212200141b0016a290200370300200241c0036a41186a2213200141b8016a290200370300200241a0036a41086a2214200141c8016a290200370300200241a0036a41106a2215200141d0016a290200370300200241a0036a41186a2216200141d8016a29020037030020024180036a41086a2217200141e8016a29020037030020024180036a41106a2218200141f0016a29020037030020024180036a41186a2219200141f8016a2902003703002002200141a0016a2902003703c0032002200141c0016a2902003703a0032002200141e0016a2902003703800320014190016a280200211a20024180016a20014194016a10c701200241186a221b2003290300370300200241106a22032004290300370300200241086a22042005290300370300200241d0016a41086a22052007290300370300200241d0016a41106a22072008290300370300200241d0016a41186a22082009290300370300200241b0016a41086a2209200a290300370300200241b0016a41106a220a200b290300370300200241b0016a41186a220b200c2903003703002002200229038002370300200220022903e0023703d001200220022903c0023703b00120024190016a41186a220c200f29030037030020024190016a41106a220f200e29030037030020024190016a41086a220e200d290300370300200241e0006a41186a220d2013290300370300200241e0006a41106a22132012290300370300200241e0006a41086a22122011290300370300200241c0006a41186a221c2016290300370300200241c0006a41106a22162015290300370300200241c0006a41086a22152014290300370300200220022903a00237039001200220022903c003370360200220022903a003370340200241206a41186a22142019290300370300200241206a41106a22192018290300370300200241206a41086a22182017290300370300200220022903800337032020012802042117200241c0036a200141086a10c301200041206a2010360200200041186a2006370300200041246a20022903f0013702002000412c6a200241f0016a41086a280200360200200041306a20022903d001370300200041386a2005290300370300200041c0006a2007290300370300200041c8006a2008290300370300200041d0006a20022903b001370300200041d8006a2009290300370300200041e0006a200a290300370300200041e8006a200b290300370300200141146a280200210120004190016a201a36020020004188016a200c29030037030020004180016a200f290300370300200041f8006a200e290300370300200041f0006a2002290390013703002000419c016a20024180016a41086a28020036020020004194016a200229038001370200200041a0016a2002290360370300200041a8016a2012290300370300200041b0016a2013290300370300200041b8016a200d290300370300200041d8016a201c290300370300200041d0016a2016290300370300200041c8016a2015290300370300200041c0016a2002290340370300200041f8016a2014290300370300200041f0016a2019290300370300200041e8016a2018290300370300200041e0016a200229032037030020004198026a201b29030037030020004190026a200329030037030020004188026a200429030037030020004180026a200229030037030020002017360204200041106a2011280200360200200041086a20022903c003370200200041146a2001360200200041013602000c010b20024180026a41186a220320014198026a29000037030020024180026a41106a220420014190026a29000037030020024180026a41086a220520014188026a290000370300200220014180026a29000037038002200141186a2903002106200241e0026a41086a2207200141386a290200370300200241e0026a41106a2208200141c0006a290200370300200241e0026a41186a2209200141c8006a290200370300200241c0026a41086a220a200141d8006a290200370300200241c0026a41106a220b200141e0006a290200370300200241c0026a41186a220c200141e8006a290200370300200241a0026a41086a220d200141f8006a290200370300200241a0026a41106a220e20014180016a290200370300200241a0026a41186a220f20014188016a2902003703002002200141306a2902003703e0022002200141d0006a2902003703c0022002200141f0006a2902003703a002200141206a2802002110200241f0016a200141246a10c701200241c0036a41086a2211200141a8016a290200370300200241c0036a41106a2212200141b0016a290200370300200241c0036a41186a2213200141b8016a290200370300200241a0036a41086a2214200141c8016a290200370300200241a0036a41106a2215200141d0016a290200370300200241a0036a41186a2216200141d8016a29020037030020024180036a41086a2217200141e8016a29020037030020024180036a41106a2218200141f0016a29020037030020024180036a41186a2219200141f8016a2902003703002002200141a0016a2902003703c0032002200141c0016a2902003703a0032002200141e0016a2902003703800320014190016a280200211a20024180016a20014194016a10c701200241186a221b2003290300370300200241106a22032004290300370300200241086a22042005290300370300200241d0016a41086a22052007290300370300200241d0016a41106a22072008290300370300200241d0016a41186a22082009290300370300200241b0016a41086a2209200a290300370300200241b0016a41106a220a200b290300370300200241b0016a41186a220b200c2903003703002002200229038002370300200220022903e0023703d001200220022903c0023703b00120024190016a41186a220c200f29030037030020024190016a41106a220f200e29030037030020024190016a41086a220e200d290300370300200241e0006a41186a220d2013290300370300200241e0006a41106a22132012290300370300200241e0006a41086a22122011290300370300200241c0006a41186a221c2016290300370300200241c0006a41106a22162015290300370300200241c0006a41086a22152014290300370300200220022903a00237039001200220022903c003370360200220022903a003370340200241206a41186a22142019290300370300200241206a41106a22192018290300370300200241206a41086a22182017290300370300200220022903800337032020012802042117200241c0036a200141086a10c301200041206a2010360200200041186a2006370300200041246a20022903f0013702002000412c6a200241f0016a41086a280200360200200041306a20022903d001370300200041386a2005290300370300200041c0006a2007290300370300200041c8006a2008290300370300200041d0006a20022903b001370300200041d8006a2009290300370300200041e0006a200a290300370300200041e8006a200b290300370300200141146a280200210120004190016a201a36020020004188016a200c29030037030020004180016a200f290300370300200041f8006a200e290300370300200041f0006a2002290390013703002000419c016a20024180016a41086a28020036020020004194016a200229038001370200200041a0016a2002290360370300200041a8016a2012290300370300200041b0016a2013290300370300200041b8016a200d290300370300200041d8016a201c290300370300200041d0016a2016290300370300200041c8016a2015290300370300200041c0016a2002290340370300200041f8016a2014290300370300200041f0016a2019290300370300200041e8016a2018290300370300200041e0016a200229032037030020004198026a201b29030037030020004190026a200329030037030020004188026a200429030037030020004180026a200229030037030020002017360204200041106a2011280200360200200041086a20022903c003370200200041146a2001360200200041023602000b200241e0036a24000bc61803067f037e047f230041c0006b2202240002400240024002400240024002402001280200417f6a0e0401020300010b200141046a2103410121040240024002400240024020012d00040e050104020300010b2002410a6a200341036a2d00003a0000200241286a41046a200141186a2d00003a0000200220032f00013b01082002200141146a280000360228200141106a28020021052001410c6a2802002106200141086a2802002107410421040c030b2002410a6a200341036a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a0000200220032f00013b01082002200141146a290000370328200141106a28020021052001410c6a2802002106200141086a2802002107410021040c020b200141106a2802002205417f4c0d06200141086a28020021040240024020050d00410121070c010b2005102c2207450d080b20072004200510e9081a41022104200521060c010b410321042002410a6a200341036a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a0000200220032f00013b01082002200141146a290000370328200141106a28020021052001410c6a2802002106200141086a28020021070b200020043a0004200020022f01083b0005200020022f00243b0025200041106a20053600002000410c6a2006360000200041086a2007360000200041146a2002290328370000200041076a200241086a41026a2d00003a00002000411c6a200241286a41086a290300370000200041246a200241286a41106a2d00003a0000200041276a200241246a41026a2d00003a000020012903282108200041306a200141306a290300370300200041286a2008370300200041043602000c030b200141046a2103410121060240024002400240024020012d00040e050104020300010b2002410a6a200341036a2d00003a0000200241286a41046a200141186a2d00003a0000200220032f00013b01082002200141146a280000360228200141106a28020021042001410c6a2802002105200141086a2802002107410421060c030b2002410a6a200341036a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a0000200220032f00013b01082002200141146a290000370328200141106a28020021042001410c6a2802002105200141086a2802002107410021060c020b200141106a2802002205417f4c0d05200141086a28020021040240024020050d00410121070c010b2005102c2207450d070b20072004200510e9081a41022106200521040c010b410321062002410a6a200341036a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a0000200220032f00013b01082002200141146a290000370328200141106a28020021042001410c6a2802002105200141086a28020021070b200020063a0004200020022f01083b0005200020022f00243b0025200041106a20043600002000410c6a2005360000200041086a2007360000200041146a2002290328370000200041076a200241086a41026a2d00003a00002000411c6a200241286a41086a290300370000200041246a200241286a41106a2d00003a0000200041276a200241246a41026a2d00003a000020012903282108200041306a200141306a290300370300200041286a2008370300200041013602000c020b200141046a2103410121040240024002400240024020012d00040e050104020300010b2002410a6a200341036a2d00003a0000200241286a41046a200141186a2d00003a0000200220032f00013b01082002200141146a280000360228200141106a28020021062001410c6a2802002105200141086a2802002107410421040c030b2002410a6a200341036a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a0000200220032f00013b01082002200141146a290000370328200141106a28020021062001410c6a2802002105200141086a2802002107410021040c020b200141106a2802002205417f4c0d04200141086a28020021040240024020050d00410121070c010b2005102c2207450d060b20072004200510e9081a41022104200521060c010b410321042002410a6a200341036a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a0000200220032f00013b01082002200141146a290000370328200141106a28020021062001410c6a2802002105200141086a28020021070b200020043a0004200020022f01083b0005200020022f00243b0025200041106a20063600002000410c6a2005360000200041086a2007360000200041146a2002290328370000200041076a200241086a41026a2d00003a00002000411c6a200241286a41086a290300370000200041246a200241286a41106a2d00003a0000200041276a200241246a41026a2d00003a0000200141306a2903002108200129032821092001290338210a200041c0006a200141c0006a290300370300200041386a200a370300200041306a2008370300200041286a2009370300200041023602000c010b200141046a2107410121034101210b0240024002400240024020012d00040e050104020300010b200241206a200741036a2d00003a0000200241086a41046a200141186a2d00003a0000200220072f00013b011e2002200141146a280000360208200141106a280200210c2001410c6a2802002105200141086a28020021044104210b0c030b200241206a200741036a2d00003a0000200241086a41086a2001411c6a290000370300200241086a41106a200141246a2d00003a0000200220072f00013b011e2002200141146a290000370308200141106a280200210c2001410c6a2802002105200141086a28020021044100210b0c020b200141106a2802002205417f4c0d03200141086a28020021070240024020050d00410121040c010b2005102c2204450d050b20042007200510e9081a4102210b2005210c0c010b4103210b200241206a200741036a2d00003a0000200241086a41086a2001411c6a290000370300200241086a41106a200141246a2d00003a0000200220072f00013b011e2002200141146a290000370308200141106a280200210c2001410c6a2802002105200141086a28020021040b02400240024002400240200141286a220d2d00000e050104020300010b200241266a200d41036a2d00003a000041042103200241286a41046a2001413c6a2d00003a00002002200d2f00013b01242002200141386a280000360228200141346a2802002107200141306a280200210e2001412c6a28020021060c030b200241266a200d41036a2d00003a0000200241306a200141c0006a290000370300200241386a200141c8006a2d00003a00002002200d2f00013b01242002200141386a290000370328200141346a2802002107200141306a280200210e2001412c6a2802002106410021030c020b200141346a2802002207417f4c0d032001412c6a28020021030240024020070d00410121060c010b2007102c2206450d050b20062003200710e9081a410221032007210e0c010b41032103200241266a200d41036a2d00003a0000200241306a200141c0006a290000370300200241386a200141c8006a2d00003a00002002200d2f00013b01242002200141386a290000370328200141346a2802002107200141306a280200210e2001412c6a28020021060b2000200b3a0004200020022f011e3b0005200020022f00053b0025200041106a200c3600002000410c6a2005360000200041086a2004360000200041146a2002290308370000200041076a2002411e6a41026a2d00003a00002000411c6a200241086a41086a290300370000200041246a200241086a41106a2d00003a0000200041276a200241056a41026a2d00003a0000200141d8006a290300210820012903502109200041286a20033a00002000412c6a2006360000200041306a200e360000200041346a2007360000200020022f01243b00292000412b6a200241246a41026a2d00003a0000200041386a2002290328370000200041c0006a200241286a41086a290300370000200041c8006a200241286a41106a2d00003a0000200020022f00213b0049200041cb006a200241216a41026a2d00003a0000200041d8006a2008370300200041d0006a2009370300200041033602000b200241c0006a24000f0b1038000b1036000b8d0503027f017e0f7f230041f0006b220224000240024020012802082203ad42f0007e2204422088a70d002004a72205417f4c0d00200128020021064104210702402005450d002005102c2207450d020b410021012000410036020820002007360200200041046a200541f0006e22083602000240200541f000490d00200341ffffffff0071210903402009450d01200241c0006a41086a220a200620016a220541186a290000370300200241c0006a41106a220b200541206a290000370300200241c0006a41186a220c200541286a290000370300200241206a41086a220d200541386a290000370300200241206a41106a220e200541c0006a290000370300200241206a41186a220f200541c8006a290000370300200241086a2210200541d8006a290000370300200241106a2211200541e0006a290000370300200241186a2212200541e8006a2900003703002002200541106a2900003703402002200541306a2900003703202002200541d0006a29000037030020052802002113200241e0006a200541046a10c701200720016a22052013360200200541046a20022903603702002005410c6a200241e0006a41086a280200360200200541106a2002290340370200200541186a200a290300370200200541206a200b290300370200200541286a200c290300370200200541306a2002290320370200200541386a200d290300370200200541c0006a200e290300370200200541c8006a200f290300370200200541e8006a2012290300370200200541e0006a2011290300370200200541d8006a2010290300370200200541d0006a20022903003702002009417f6a2109200141f0006a21012008417f6a22080d000b0b20002003360208200241f0006a24000f0b1038000b1036000bd41403057f027e017f230041d0006b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a0e170102030405060708090a0b0c0d0e0f1011121314151617000b41e2a0cc00412841f4ebc6001039000b4101210302400240024002400240200141246a2d00000e050104020300010b200241ce006a200141276a2d00003a000041042103200241106a41046a200141386a2d00003a00002002200141256a2f00003b014c2002200141346a280000360210200141306a28000021042001412c6a2800002105200141286a28000021060c030b200241ce006a200141276a2d00003a0000200241186a2001413c6a290000370300200241206a200141c4006a2d00003a00002002200141256a2f00003b014c2002200141346a290000370310200141306a28000021042001412c6a2800002105200141286a2800002106410021030c020b200141306a2802002205417f4c0d19200141286a28020021030240024020050d00410121060c010b2005102c2206450d1b0b20062003200510e9081a41022103200521040c010b200241ce006a200141276a2d00003a0000200241186a2001413c6a290000370300200241206a200141c4006a2d00003a00002002200141256a2f00003b014c2002200141346a290000370310200141306a28000021042001412c6a2800002105200141286a2800002106410321030b200141d0006a290300210720012903482108410421090240024002400240024020012d00010e050001020304000b410021090c030b410121090c020b410221090c010b200241c0006a2001411a6a290000370300200241386a200141126a290000370300200241306a2001410a6a2900003703002002200141026a290000370328410321090b200041246a20033a0000200041256a20022f014c3b0000200041306a20043600002000412c6a2005360000200041286a2006360000200041346a2002290310370000200041c5006a20022f000d3b0000200041276a200241cc006a41026a2d00003a00002000413c6a200241106a41086a290300370000200041c4006a200241106a41106a2d00003a0000200041c7006a2002410d6a41026a2d00003a0000200041d0006a2007370300200041c8006a2008370300200020093a0001200041013a0000200041026a20022903283700002000410a6a200241286a41086a290300370000200041126a200241286a41106a2903003700002000411a6a200241c0006a2903003700000c160b200041023a0000200041106a200141106a290300370300200041086a200141086a2903003703000c150b200041033a0000200041106a200141106a290300370300200041086a200141086a2903003703000c140b200041043a0000200041046a200141046a2802003602000c130b200041053a0000200041046a200141046a280200360200200041086a200141086a2d00004100473a00000c120b200241286a200141046a10c401200041063a00002000410c6a200241306a280200360200200041046a20022903283702000c110b200041073a00000c100b410421050240024002400240024020012d00010e050001020304000b410021050c030b410121050c020b410221050c010b200241c0006a2001411a6a290000370300200241386a200141126a290000370300200241306a2001410a6a2900003703002002200141026a290000370328410321050b200020053a0001200041083a0000200041026a20022903283700002000410a6a200241286a41086a290300370000200041126a200241386a2903003700002000411a6a200241c0006a2903003700000c0f0b4101210302400240024002400240200141046a2d00000e050104020300010b200241126a200141076a2d00003a0000200241286a41046a200141186a2d00003a00002002200141056a2f00003b01102002200141146a280000360228200141106a28000021042001410c6a2800002105200141086a2800002106410421030c030b200241126a200141076a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a00002002200141056a2f00003b01102002200141146a290000370328200141106a28000021042001410c6a2800002105200141086a2800002106410021030c020b200141106a2802002205417f4c0d11200141086a28020021010240024020050d00410121060c010b2005102c2206450d130b20062001200510e9081a41022103200521040c010b200241126a200141076a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a00002002200141056a2f00003b01102002200141146a290000370328200141106a28000021042001410c6a2800002105200141086a2800002106410321030b200041046a20033a0000200041056a20022f01103b0000200041106a20043600002000410c6a2005360000200041086a2006360000200041146a2002290328370000200041256a20022f004c3b0000200041076a200241106a41026a2d00003a00002000411c6a200241286a41086a290300370000200041246a200241286a41106a2d00003a0000200041276a200241cc006a41026a2d00003a0000200041093a00000c0e0b2000410a3a0000200041046a200141046a2802003602000c0d0b2000410b3a0000200041046a200141046a2802003602000c0c0b2000410c3a0000200020012d00013a00010c0b0b2000410d3a00000c0a0b2000410e3a00000c090b200241286a200141046a10c8012000410f3a00002000410c6a200241306a280200360200200041046a20022903283702000c080b200041103a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c070b200041113a00000c060b200141106a280200220541ffffffff03712005470d0620054102742206417f4c0d06200141086a2802002103200141046a28020021044104210102402006450d002006102c2201450d080b20012003200541027410e9082101200041106a20053602002000410c6a2006410276360200200041086a2001360200200041046a2004360200200041123a00000c050b200041133a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c040b200041143a0000200041106a200141106a290300370300200041086a200141086a2903003703000c030b200041153a0000200041046a200141046a2902003702000c020b200041163a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c010b200241286a200141046a10c401200041173a00002000410c6a200241306a280200360200200041046a20022903283702000b200241d0006a24000f0b1038000b1036000b110041e2a0cc00412841889cc5001039000bc91a05017f017e0a7f027e117f230041c0036b22022400024002400240024002402001280200417f6a0e03010203000b41e2a0cc00412841c499c9001039000b200141186a2903002103200241a0036a41086a22042001413c6a290200370300200241a0036a41106a2205200141c4006a290200370300200241a0036a41186a2206200141cc006a290200370300200241e0026a41086a2207200141dc006a290200370300200241e0026a41106a2208200141e4006a290200370300200241e0026a41186a2209200141ec006a290200370300200241e0026a41206a220a200141f4006a290200370300200241e0026a41286a220b200141fc006a290200370300200241e0026a41306a220c20014184016a290200370300200241e0026a41386a220d2001418c016a2902003703002002200141346a2902003703a0032002200141d4006a2902003703e002200141206a290300210e200141286a290300210f200141306a2802002110200241c0026a41186a2211200141b0016a290200370300200241c0026a41106a2212200141a8016a290200370300200241c0026a41086a2213200141a0016a29020037030020024180026a41386a2214200141f0016a29020037030020024180026a41306a2215200141e8016a29020037030020024180026a41286a2216200141e0016a29020037030020024180026a41206a2217200141d8016a29020037030020024180026a41186a2218200141d0016a29020037030020024180026a41106a2219200141c8016a29020037030020024180026a41086a221a200141c0016a290200370300200220014198016a2902003703c0022002200141b8016a2902003703800220014194016a280200211b200241e0016a41186a221c20014190026a290300370300200241e0016a41106a221d20014188026a290300370300200241e0016a41086a221e20014180026a2903003703002002200141f8016a2903003703e001200241c0016a41186a221f2006290300370300200241c0016a41106a22062005290300370300200241c0016a41086a22052004290300370300200220022903a0033703c00120024180016a41386a2204200d29030037030020024180016a41306a220d200c29030037030020024180016a41286a220c200b29030037030020024180016a41206a220b200a29030037030020024180016a41186a220a200929030037030020024180016a41106a2209200829030037030020024180016a41086a22082007290300370300200220022903e00237038001200241e0006a41186a22202011290300370300200241e0006a41106a22112012290300370300200241e0006a41086a22122013290300370300200220022903c002370360200241206a41386a22132014290300370300200241206a41306a22142015290300370300200241206a41286a22152016290300370300200241206a41206a22162017290300370300200241206a41186a22172018290300370300200241206a41106a22182019290300370300200241206a41086a2219201a2903003703002002200229038002370320200241186a221a201c290300370300200241106a221c201d290300370300200241086a221d201e290300370300200220022903e0013703002001280204211e200241e0026a200141086a10c301200041306a2010360200200041286a200f370300200041206a200e370300200041186a2003370300200041346a20022903c0013702002000413c6a2005290300370200200041c4006a2006290300370200200041cc006a201f290300370200200041d4006a200229038001370200200041dc006a2008290300370200200041e4006a2009290300370200200041ec006a200a290300370200200041f4006a200b290300370200200041fc006a200c29030037020020004184016a200d2903003702002000418c016a2004290300370200200141146a280200210120004194016a201b360200200041b0016a2020290300370200200041a8016a2011290300370200200041a0016a201229030037020020004198016a2002290360370200200041f0016a2013290300370200200041e8016a2014290300370200200041e0016a2015290300370200200041d8016a2016290300370200200041d0016a2017290300370200200041c8016a2018290300370200200041c0016a2019290300370200200041b8016a200229032037020020004190026a201a29030037030020004188026a201c29030037030020004180026a201d290300370300200041f8016a20022903003703002000201e360204200041106a2007280200360200200041086a20022903e002370200200041146a2001360200200041013602000c020b200141186a2903002103200241a0036a41086a22042001413c6a290200370300200241a0036a41106a2205200141c4006a290200370300200241a0036a41186a2206200141cc006a290200370300200241e0026a41086a2207200141dc006a290200370300200241e0026a41106a2208200141e4006a290200370300200241e0026a41186a2209200141ec006a290200370300200241e0026a41206a220a200141f4006a290200370300200241e0026a41286a220b200141fc006a290200370300200241e0026a41306a220c20014184016a290200370300200241e0026a41386a220d2001418c016a2902003703002002200141346a2902003703a0032002200141d4006a2902003703e002200141206a290300210e200141286a290300210f200141306a2802002110200241c0026a41186a2211200141b0016a290200370300200241c0026a41106a2212200141a8016a290200370300200241c0026a41086a2213200141a0016a29020037030020024180026a41386a2214200141f0016a29020037030020024180026a41306a2215200141e8016a29020037030020024180026a41286a2216200141e0016a29020037030020024180026a41206a2217200141d8016a29020037030020024180026a41186a2218200141d0016a29020037030020024180026a41106a2219200141c8016a29020037030020024180026a41086a221a200141c0016a290200370300200220014198016a2902003703c0022002200141b8016a2902003703800220014194016a280200211b200241e0016a41186a221c20014190026a290300370300200241e0016a41106a221d20014188026a290300370300200241e0016a41086a221e20014180026a2903003703002002200141f8016a2903003703e001200241c0016a41186a221f2006290300370300200241c0016a41106a22062005290300370300200241c0016a41086a22052004290300370300200220022903a0033703c00120024180016a41386a2204200d29030037030020024180016a41306a220d200c29030037030020024180016a41286a220c200b29030037030020024180016a41206a220b200a29030037030020024180016a41186a220a200929030037030020024180016a41106a2209200829030037030020024180016a41086a22082007290300370300200220022903e00237038001200241e0006a41186a22202011290300370300200241e0006a41106a22112012290300370300200241e0006a41086a22122013290300370300200220022903c002370360200241206a41386a22132014290300370300200241206a41306a22142015290300370300200241206a41286a22152016290300370300200241206a41206a22162017290300370300200241206a41186a22172018290300370300200241206a41106a22182019290300370300200241206a41086a2219201a2903003703002002200229038002370320200241186a221a201c290300370300200241106a221c201d290300370300200241086a221d201e290300370300200220022903e0013703002001280204211e200241e0026a200141086a10c301200041306a2010360200200041286a200f370300200041206a200e370300200041186a2003370300200041346a20022903c0013702002000413c6a2005290300370200200041c4006a2006290300370200200041cc006a201f290300370200200041d4006a200229038001370200200041dc006a2008290300370200200041e4006a2009290300370200200041ec006a200a290300370200200041f4006a200b290300370200200041fc006a200c29030037020020004184016a200d2903003702002000418c016a2004290300370200200141146a280200210120004194016a201b360200200041b0016a2020290300370200200041a8016a2011290300370200200041a0016a201229030037020020004198016a2002290360370200200041f0016a2013290300370200200041e8016a2014290300370200200041e0016a2015290300370200200041d8016a2016290300370200200041d0016a2017290300370200200041c8016a2018290300370200200041c0016a2019290300370200200041b8016a200229032037020020004190026a201a29030037030020004188026a201c29030037030020004180026a201d290300370300200041f8016a20022903003703002000201e360204200041106a2007280200360200200041086a20022903e002370200200041146a2001360200200041023602000c010b20004103360200200020012902043702040b200241c0036a24000b910403067f017e077f024002402001410c6a2802002202417f4c0d0020012802042103200128020021040240024020020d00410121050c010b2002102c2205450d020b20052003200210e9082106200141186a2802002207ad420c7e2208422088a70d002008a72203417f4c0d000240024020030d002003410c6e21094104210a0c010b2001280210210b2003102c220a450d022003410c6e21092003410c490d00200741ffffffff0371210c200a21052009210d0340200c450d01200b41086a2802002203417f4c0d02200b280200210e0240024020030d004101210f0c010b2003102c220f450d040b200f200e200310e908210e200541086a2003360200200541046a20033602002005200e360200200b410c6a210b2005410c6a2105200c417f6a210c200d417f6a220d0d000b0b2000200636020420002004360200200020012802243602242000200129021c37021c200041186a2007360200200041146a2009360200200041106a200a3602002000410c6a2002360200200041086a200236020020002001290228370228200041306a200141306a290200370200200041386a200141386a290200370200200041c0006a200141c0006a290200370200200041c8006a200141c8006a290200370200200041d0006a200141d0006a290200370200200041d8006a200141d8006a290200370200200041e0006a200141e0006a2902003702000f0b1038000b1036000b110041e2a0cc00412841f4afc4001039000b8a0f03037f027e027f230041106b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a0e190102030405060708090a0b0c0d0e0f10111213141516171819000b41e2a0cc00412841c0accb001039000b200041013a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c180b200041023a0000200041046a200141046a2902003702000c170b200141046a28020021034101210402400240200141086a2d00004101470d00200141286a2903002105200141206a29030021060c010b200141096a2d000041017121072001410a6a2d00002108410021040b200041033a0000200041286a2005370300200041206a2006370300200041106a20012903103703002000410a6a20083a0000200041096a20073a0000200041086a20043a0000200041046a20033602002000410b6a200228000b360000200041186a200141186a2903003703002000410f6a2002410b6a41046a2d00003a00000c160b200041043a0000200041046a200141046a2802003602000c150b200041053a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c140b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c130b200041073a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c120b200041083a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2902003702000c110b200041093a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c100b2000410a3a0000200041046a200141046a2802003602000c0f0b2000410b3a0000200041046a200141046a2802003602000c0e0b2000410c3a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000c0d0b2000410d3a00000c0c0b2000410e3a00000c0b0b2001410c6a2802002204417f4c0d0b200141046a28020021010240024020040d00410121030c010b2004102c2203450d0d0b20032001200410e90821012000410c6a2004360200200041086a2004360200200041046a20013602002000410f3a00000c0a0b2001410c6a2802002204417f4c0d0a200141046a28020021010240024020040d00410121030c010b2004102c2203450d0c0b20032001200410e90821012000410c6a2004360200200041086a2004360200200041046a2001360200200041103a00000c090b2001410c6a2802002204417f4c0d09200141046a28020021010240024020040d00410121030c010b2004102c2203450d0b0b20032001200410e90821012000410c6a2004360200200041086a2004360200200041046a2001360200200041113a00000c080b2001410c6a2802002204417f4c0d08200141046a28020021010240024020040d00410121030c010b2004102c2203450d0a0b20032001200410e90821012000410c6a2004360200200041086a2004360200200041046a2001360200200041123a00000c070b200041133a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c060b200041143a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c050b200041153a0000200041046a200141046a2802003602000c040b200041163a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c030b200041173a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c020b200041183a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041286a200141286a280200360200200041246a200141246a2802004101463602000c010b200041193a0000200041046a200141046a2802003602000b200241106a24000f0b1038000b1036000bd90501037f230041c0026b2202240002400240024002400240024002400240024020012d0000417f6a0e06010203040506000b41e2a0cc00412841b8afc9001039000b2002200141246a10c80141002103024020012d00014101470d00200241286a2001411a6a290000370300200241206a200141126a290000370300200241186a2001410a6a2900003703002002200141026a290000370310410121030b200020033a0001200041013a0000200041246a2002290300370200200041026a2002290310370000200041306a20012802303602002000412c6a200241086a2802003602002000410a6a200241106a41086a290300370000200041126a200241206a2903003700002000411a6a200241286a2903003700000c050b41b002102c2203450d05200241106a200141046a280200108e08200041046a2003200241106a41b00210e908360200200041023a0000200041086a200141086a2802003602000c040b200141046a280200210341b002102c2204450d04200241106a200141086a280200108e08200041086a2004200241106a41b00210e908360200200041046a2003360200200041033a00002000410c6a2001410c6a2802003602000c030b200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00004100473a00000c020b200041053a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041306a200141306a290300370300200041246a200141246a2902003702000c010b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000b200241c0026a24000f0b1036000b960701057f230041206b22022400024002400240024002400240024002400240024020012d0000417f6a0e06010203040506000b41e2a0cc0041284188f3c0001039000b200241086a200141046a10c801200041013a0000200041186a200141186a290300370300200041106a200141106a290300370300200041046a20022903083702002000410c6a200241106a2802003602000c050b200041023a00000c040b200041033a0000200041046a200141046a2802003602000c030b200141086a280200210341002104024002400240200141046a2802000e03020100020b410221040c010b410121040b200041043a0000200041086a2003360200200041046a20043602000c020b4101210502400240024002400240200141046a2d00000e050104020300010b2002411e6a200141076a2d00003a0000200241086a41046a200141186a2d00003a00002002200141056a2f00003b011c2002200141146a280000360208200141106a28000021062001410c6a2800002104200141086a2800002103410421050c030b2002411e6a200141076a2d00003a0000200241086a41086a2001411c6a290000370300200241086a41106a200141246a2d00003a00002002200141056a2f00003b011c2002200141146a290000370308200141106a28000021062001410c6a2800002104200141086a2800002103410021050c020b200141106a2802002204417f4c0d04200141086a28020021050240024020040d00410121030c010b2004102c2203450d060b20032005200410e9081a41022105200421060c010b2002411e6a200141076a2d00003a0000200241086a41086a2001411c6a290000370300200241086a41106a200141246a2d00003a00002002200141056a2f00003b011c2002200141146a290000370308200141106a28000021062001410c6a2800002104200141086a2800002103410321050b200041046a20053a0000200041056a20022f011c3b0000200041106a20063600002000410c6a2004360000200041086a2003360000200041146a2002290308370000200041256a20022f00053b0000200041076a2002411c6a41026a2d00003a00002000411c6a200241086a41086a290300370000200041246a200241086a41106a2d00003a0000200041276a200241056a41026a2d00003a000020012d00012101200041053a0000200020014100473a00010c010b200041063a0000200041046a200141046a2902003702000b200241206a24000f0b1038000b1036000bee0903037f037e037f23004180016b2202240002400240024002400240024002400240024020012d0000417f6a0e050102030405000b41e2a0cc00412841e0f3c0001039000b20002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a41c10010e9081a200041013a00000c040b200241106a2203200141116a280000360200200241086a2204200141096a29000037030020022001290001370300200141206a2903002105200141186a2903002106420021070240200141286a2903004201520d00200241206a41206a200141d0006a290300370300200241206a41186a200141c8006a290300370300200241206a41106a200141c0006a290300370300200241206a41086a200141386a2903003703002002200141306a290300370320420121070b20002002290300370001200041206a2005370300200041186a2006370300200041286a2007370300200041306a2002290320370300200041096a2004290300370000200041116a2003280200360000200041386a200241206a41086a290300370300200041c0006a200241206a41106a290300370300200041c8006a200241206a41186a290300370300200041d0006a200241206a41206a29030037030020012d00152101200041023a0000200041156a4102200141004720014102461b3a00000c030b200241186a200141196a290000370300200241106a200141116a290000370300200241086a200141096a29000037030020022001290001370300200241206a200141216a41c10010e9081a200141ec006a2802002203417f4c0d03200141e4006a28020021010240024020030d00410121040c010b2003102c2204450d050b20042001200310e9082101200041196a200241186a290300370000200041116a200241106a290300370000200041096a200241086a29030037000020002002290300370001200041216a200241206a41c10010e9081a200041ec006a2003360200200041e8006a2003360200200041e4006a2001360200200041033a00000c020b2001410c6a2802002203417f4c0d02200141046a28020021010240024020030d00410121040c010b2003102c2204450d040b20042001200310e90821012000410c6a2003360200200041086a2003360200200041046a2001360200200041043a00000c010b200241e8006a41106a2204200141116a280000360200200241e8006a41086a2208200141096a29000037030020022001290001370368200241106a2209200141256a280000360200200241086a220a2001411d6a2900003703002002200141156a290000370300410021030240200141296a2d00004101470d00200241386a200141c2006a290000370300200241206a41106a2001413a6a290000370300200241206a41086a200141326a29000037030020022001412a6a290000370320410121030b20002002290368370001200041156a2002290300370000200041296a20033a00002000412a6a2002290320370000200041116a2004280200360000200041096a20082903003700002000411d6a200a290300370000200041256a2009280200360000200041326a200241206a41086a2903003700002000413a6a200241206a41106a290300370000200041c2006a200241386a290300370000200041053a00000b20024180016a24000f0b1038000b1036000ba014020a7f047e230041c0006b2202240002400240024002400240024002402001280200417f6a0e0401020300010b200141046a210341012104410121050240024002400240024020012d00040e050104020300010b200241246a200341036a2d00003a0000200241106a41046a200141186a2d00003a0000200220032f00013b01222002200141146a280000360210200141106a28020021062001410c6a2802002107200141086a2802002108410421050c030b200241246a200341036a2d00003a0000200241106a41086a2001411c6a290000370300200241106a41106a200141246a2d00003a0000200220032f00013b01222002200141146a290000370310200141106a28020021062001410c6a2802002107200141086a2802002108410021050c020b200141106a2802002206417f4c0d06200141086a28020021030240024020060d00410121080c010b2006102c2208450d080b20082003200610e9081a41022105200621070c010b41032105200241246a200341036a2d00003a0000200241106a41086a2001411c6a290000370300200241106a41106a200141246a2d00003a0000200220032f00013b01222002200141146a290000370310200141106a28020021062001410c6a2802002107200141086a28020021080b02400240024002400240200141286a22092d00000e050104020300010b2002413e6a200941036a2d00003a000041042104200241286a41046a2001413c6a2d00003a0000200220092f00013b013c2002200141386a280000360228200141346a2802002103200141306a280200210a2001412c6a280200210b0c030b2002413e6a200941036a2d00003a0000200241306a200141c0006a290000370300200241386a200141c8006a2d00003a0000200220092f00013b013c2002200141386a290000370328200141346a2802002103200141306a280200210a2001412c6a280200210b410021040c020b200141346a2802002203417f4c0d062001412c6a28020021040240024020030d004101210b0c010b2003102c220b450d080b200b2004200310e9081a410221042003210a0c010b410321042002413e6a200941036a2d00003a0000200241306a200141c0006a290000370300200241386a200141c8006a2d00003a0000200220092f00013b013c2002200141386a290000370328200141346a2802002103200141306a280200210a2001412c6a280200210b0b200020053a0004200020022f01223b0005200041106a20063600002000410c6a2007360000200041086a2008360000200041146a2002290310370000200041076a200241226a41026a2d00003a00002000411c6a200241106a41086a290300370000200041246a200241106a41106a2d00003a0000200141f0006a2802002106200141d8006a290300210c200141e0006a290300210d200141e8006a290300210e2001290350210f200041286a20043a00002000412c6a200b360000200041306a200a360000200041346a2003360000200041276a2002410d6a41026a2d00003a0000200020022f000d3b0025200020022f013c3b00292000412b6a2002413c6a41026a2d00003a0000200041386a2002290328370000200041c0006a200241286a41086a290300370000200041c8006a200241286a41106a2d00003a0000200041e8006a200e370300200041e0006a200d370300200041d8006a200c370300200041d0006a200f370300200041f0006a200636020020004104360200200041cb006a200241256a41026a2d00003a0000200020022f00253b00490c030b200041013602000c020b200141046a2104410121080240024002400240024020012d00040e050104020300010b200241126a200441036a2d00003a0000200241286a41046a200141186a2d00003a0000200220042f00013b01102002200141146a280000360228200141106a280200210b2001410c6a2802002106200141086a2802002103410421080c030b200241126a200441036a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a0000200220042f00013b01102002200141146a290000370328200141106a280200210b2001410c6a2802002106200141086a2802002103410021080c020b200141106a2802002206417f4c0d04200141086a28020021010240024020060d00410121030c010b2006102c2203450d060b20032001200610e9081a410221082006210b0c010b41032108200241126a200441036a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a0000200220042f00013b01102002200141146a290000370328200141106a280200210b2001410c6a2802002106200141086a28020021030b200020083a0004200020022f01103b0005200020022f003c3b0025200041106a200b3600002000410c6a2006360000200041086a2003360000200041146a2002290328370000200041076a200241106a41026a2d00003a00002000411c6a200241286a41086a290300370000200041246a200241286a41106a2d00003a0000200041276a2002413c6a41026a2d00003a0000200041023602000c010b200141046a2104410121080240024002400240024020012d00040e050104020300010b200241126a200441036a2d00003a0000200241286a41046a200141186a2d00003a0000200220042f00013b01102002200141146a280000360228200141106a280200210b2001410c6a2802002106200141086a2802002103410421080c030b200241126a200441036a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a0000200220042f00013b01102002200141146a290000370328200141106a280200210b2001410c6a2802002106200141086a2802002103410021080c020b200141106a2802002206417f4c0d03200141086a28020021080240024020060d00410121030c010b2006102c2203450d050b20032008200610e9081a410221082006210b0c010b41032108200241126a200441036a2d00003a0000200241286a41086a2001411c6a290000370300200241286a41106a200141246a2d00003a0000200220042f00013b01102002200141146a290000370328200141106a280200210b2001410c6a2802002106200141086a28020021030b200020083a0004200020022f01103b0005200041106a200b3600002000410c6a2006360000200041086a2003360000200041146a2002290328370000200041076a200241106a41026a2d00003a00002000411c6a200241286a41086a290300370000200041246a200241286a41106a2d00003a0000200141306a290300210c200141c0006a290300210d200141386a290300210e2001290328210f200041c8006a200141c8006a280200360200200041386a200e370300200041c0006a200d370300200041286a200f370300200041306a200c37030020004103360200200041276a2002413c6a41026a2d00003a0000200020022f003c3b00250b200241c0006a24000f0b1038000b1036000be22505027f017e027f017e037f230041b0046b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c0102030405060708090a0b0c0d0e0f101112131415161718191a1b00010b200241086a200141386a10ca01200241f8016a41286a200141306a290300370300200241f8016a41206a200141286a290300370300200241f8016a41186a200141206a290300370300200241f8016a41106a200141186a290300370300200241f8016a41086a200141106a2903003703002002200141086a2903003703f801200141f8016a2802002103200241f8016a41306a200241086a41c00110e9081a20014180026a2903002104200241086a200241f8016a41f00110e9081a200041086a200241086a41f00110e9081a20004180026a2004370300200041f8016a20033602002000411b3602000c1b0b200241f8016a200141086a10cb0120004100360200200041186a200241f8016a41106a290300370300200041106a200241f8016a41086a290300370300200041086a20022903f8013703000c1a0b200241f8016a200141046a10cc0120004101360200200041246a20024198026a2802003602002000411c6a20024190026a290300370200200041146a20024188026a2903003702002000410c6a20024180026a290300370200200020022903f8013702040c190b200241f8016a200141086a10cd01200041086a200241f8016a41a00210e9081a200041023602000c180b20004103360200200041086a200141086a2903003703000c170b41042103200141046a210502400240024002400240024002400240024020012d0004417f6a0e050102030405000b41e2a0cc00412841e89bc4001039000b200141086a2802002105410121030c040b41022103200241086a41026a200541036a2d00003a0000200241f8016a41086a200141146a29020037030020024188026a2001411c6a29020037030020024190026a200141246a2d00003a0000200220052f00013b010820022001410c6a2902003703f801200141086a2802002105200141286a28020021010c040b200141086a2802002105410321030c020b2002410a6a200541036a2d00003a0000200241f8016a41086a200141146a29020037030020024188026a2001411c6a29020037030020024190026a200141246a2d00003a0000200220052f00013b010820022001410c6a2902003703f80120012d00254100472106200141086a2802002105200141286a28020021010c030b200141086a2802002105410521030b0b0b200020033a0004200020022f01083b0005200020063a0025200020022f01ac043b0126200041086a20053602002000410c6a20022903f801370200200041286a2001360200200041076a2002410a6a2d00003a0000200041146a200241f8016a41086a2903003702002000411c6a20024188026a290300370200200041246a20024190026a2d00003a0000200041043602000c160b200241f8016a200141086a10ce01200041086a200241f8016a41e00010e9081a200041053602000c150b200241f8016a200141046a10cf01200041063602002000410c6a20024180026a280200360200200020022903f8013702040c140b200241f8016a200141086a10d001200041086a200241f8016a41d80010e9081a200041073602000c130b10d101000b02400240200128020422050d00410021030c010b200241f8016a41186a200141286a290000370300200241f8016a41106a200141206a29000037030020024180026a200141186a290000370300200241f8016a41286a200141386a290000370300200241f8016a41306a200141c0006a290000370300200241f8016a41386a200141c8006a290000370300200241f8016a41c8006a200141d8006a290000370300200241f8016a41d0006a200141e0006a290000370300200241f8016a41d8006a200141e8006a2900003703002002200141106a2900003703f8012002200141306a290000370398022002200141d0006a2900003703b802200241f8016a41f8006a20014188016a290000370300200241f8016a41f0006a20014180016a290000370300200241f8016a41e8006a200141f8006a290000370300200241f8016a4198016a200141a8016a290000370300200241f8016a4190016a200141a0016a290000370300200241f8016a4188016a20014198016a290000370300200241f8016a41b8016a200141c8016a290000370300200241f8016a41b0016a200141c0016a290000370300200241f8016a41a8016a200141b8016a2900003703002002200141f0006a2900003703d802200220014190016a2900003703f8022002200141b0016a290000370398032001410c6a2802002201417f4c0d130240024020010d00410121030c010b2001102c2203450d150b20032005200110e9081a200241086a200241f8016a41c00110e9081a0b200020033602042000410c6a2001360200200041086a2001360200200041106a200241086a41c00110e9081a200041093602000c110b200241f8016a200141086a10d201200041086a200241f8016a41980210e9081a2000410a3602000c100b200241f8016a200141046a10d301200041046a200241f8016a41e80010e9081a2000410b3602000c0f0b10d401000b200241f8016a200141086a10d5012000410d360200200041386a200241f8016a41306a290300370300200041306a200241f8016a41286a290300370300200041286a200241f8016a41206a290300370300200041206a200241f8016a41186a290300370300200041186a200241f8016a41106a290300370300200041106a200241f8016a41086a290300370300200041086a20022903f8013703000c0d0b200241f8016a200141086a10d6012000410e360200200041386a200241f8016a41306a290300370300200041306a200241f8016a41286a290300370300200041286a200241f8016a41206a290300370300200041206a200241f8016a41186a290300370300200041186a200241f8016a41106a290300370300200041106a200241f8016a41086a290300370300200041086a20022903f8013703000c0c0b200241f8016a200141086a10d6012000410f360200200041386a200241f8016a41306a290300370300200041306a200241f8016a41286a290300370300200041286a200241f8016a41206a290300370300200041206a200241f8016a41186a290300370300200041186a200241f8016a41106a290300370300200041106a200241f8016a41086a290300370300200041086a20022903f8013703000c0b0b200241f8016a200141086a10d70120004110360200200041286a200241f8016a41206a290300370300200041206a200241f8016a41186a290300370300200041186a200241f8016a41106a290300370300200041106a200241f8016a41086a290300370300200041086a20022903f8013703000c0a0b200141046a2103410721050240024002400240024002400240024020012d0004417f6a0e0701020304050607000b41e2a0cc00412841a4c3cb001039000b20024190026a200341196a29000037030020024188026a200341116a29000037030020024180026a200341096a290000370300200220032900013703f801410121050c050b20024190026a200341196a29000037030020024188026a200341116a29000037030020024180026a200341096a290000370300200220032900013703f801410221050c040b200241f8016a41186a200341196a290000370300200241f8016a41106a200341116a290000370300200241f8016a41086a200341096a290000370300200241086a41086a200341296a290000370300200241086a41106a200341316a290000370300200241086a41186a200341396a290000370300200220032900013703f8012002200341216a290000370308410321050c030b200241086a200141086a10c80120024183026a200241086a41086a280200360000200220022903083700fb01410421050c020b20024190026a200341196a29000037030020024188026a200341116a29000037030020024180026a200341096a290000370300200220032900013703f801410521050c010b20024190026a200341196a29000037030020024188026a200341116a29000037030020024180026a200341096a290000370300200220032900013703f801410621050b200020053a0004200020022903f80137000520002002290308370025200020022f00ac043b00452000410d6a200241f8016a41086a290300370000200041156a200241f8016a41106a2903003700002000411d6a200241f8016a41186a2903003700002000412d6a200241086a41086a290300370000200041356a200241086a41106a2903003700002000413d6a200241086a41186a290300370000200041c7006a200241ae046a2d00003a0000200041113602000c090b024002400240024002400240200141086a280200417f6a0e03010203000b41e2a0cc0041284184ccc2001039000b200141386a2903002104200141306a29030021074101210841012109024002400240024002402001410c6a2d00000e050104020300010b41042109200241f8016a41046a200141206a2d00003a000020022001411c6a2800003602f80120012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a28020021050c030b20024180026a200141246a290000370300200241f8016a41106a2001412c6a2d00003a000020022001411c6a2900003703f80120012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a2802002105410021090c020b200141186a2802002203417f4c0d0f200141106a28020021010240024020030d00410121050c010b2003102c2205450d110b20052001200310e9081a410221092003210a0c010b20024180026a200141246a290000370300200241f8016a41106a2001412c6a2d00003a000020022001411c6a2900003703f80120012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a2802002105410321090b200241086a41106a200241f8016a41106a2d00003a0000200241086a41086a200241f8016a41086a290300370300200241046a41026a200241ac046a41026a2d00003a0000200220022903f801370308200220022f00ac043b01040c030b2001410c6a28020022094108762106410221080c010b2001410c6a28020022094108762106410321080b0b200020022f01043b002d20004112360200200041386a2004370300200041306a2007370300200041186a200a360200200041146a2003360200200041106a2005360200200041086a20083602002000411c6a20022903083702002000410c6a2006410874200941ff017172360200200041246a200241086a41086a2903003702002000412c6a200241086a41106a2d00003a00002000412f6a200241066a2d00003a00000c080b200241f8016a200141086a10d801200041086a200241f8016a41f00010e9081a200041133602000c070b200241f8016a200141086a10d901200041086a200241f8016a41f80010e9081a200041143602000c060b024002400240024020012f0104417f6a0e03010200010b200241f8016a200141086a10c90120022902fc01210420022802f8012103410321010c020b200241f8016a200141086a10c90120022902fc01210420022802f8012103410121010c010b20012f0106210541b002102c2203450d08200241f8016a200141086a28020010da012003200241f8016a41b00210e9081a410221010b200020013b0104200041153602002000410c6a2004370200200041086a2003360200200041066a20053b01000c050b200241f8016a200141086a10db01200041086a200241f8016a41a80210e9081a200041163602000c040b200241f8016a200141046a10dc01200041046a200241f8016a41c80010e9081a200041173602000c030b200241f8016a200141086a10dd01200041086a200241f8016a41c80010e9081a200041183602000c020b200241f8016a200141086a10de0120004119360200200041c0006a200241f8016a41386a290300370300200041386a200241f8016a41306a290300370300200041306a200241f8016a41286a290300370300200041286a200241f8016a41206a290300370300200041206a200241f8016a41186a290300370300200041186a200241f8016a41106a290300370300200041106a200241f8016a41086a290300370300200041086a20022903f8013703000c010b200241f8016a200141086a10df012000411a360200200041c0006a200241f8016a41386a290300370300200041386a200241f8016a41306a290300370300200041306a200241f8016a41286a290300370300200041286a200241f8016a41206a290300370300200041206a200241f8016a41186a290300370300200041186a200241f8016a41106a290300370300200041106a200241f8016a41086a290300370300200041086a20022903f8013703000b200241b0046a24000f0b1038000b1036000b8b6f04027f017e3c7f027e230041c0036b22022400024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a0e0f0102030405060708090a0b0c0d0e0f000b41e2a0cc00412841f89bc4001039000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c0e0b2001410c6a2802002203ad42c8007e2204422088a70d0e2004a72205417f4c0d0e0240024020050d00200541c8006e2106410421070c010b200141046a28020021082005102c2207450d10200541c8006e2106200541c800490d00200341ffffffff017121094100210a2006210b03402009450d014100210c4100210d0240024002400240024002402008200a6a22052d00000e06050102030400050b200241f0026a41026a200541036a2d00003a000020024188036a41086a200541186a29000037030020024188036a41106a200541206a2d00003a00002002200541016a2f00003b01f0022002200541106a290000370388032005410c6a280000210e200541086a280000210f200541046a28000021104105210d0c040b2005410c6a280200220e417f4c0d14200541046a280200210f4101210d410121100240200e450d00200e102c2210450d160b2010200f200e10e9081a200e210f0c030b4102210d200241f0026a41026a200541036a2d00003a000020024188036a41086a200541186a29000037030020024188036a41106a200541206a2d00003a00002002200541016a2f00003b01f0022002200541106a290000370388032005410c6a280000210e200541086a280000210f200541046a28000021100c020b4103210d200241f0026a41026a200541036a2d00003a000020024188036a41086a200541186a29000037030020024188036a41106a200541206a2d00003a00002002200541016a2f00003b01f0022002200541106a290000370388032005410c6a280000210e200541086a280000210f200541046a28000021100c010b200241f0026a41026a200541036a2d00003a000020024188036a41086a200541186a29000037030020024188036a41106a200541206a2d00003a00002002200541016a2f00003b01f0022002200541106a290000370388032005410c6a280000210e200541086a280000210f4104210d200541046a28000021100b024002400240024002400240200541246a2d00000e06050102030400050b200241d8026a41026a200541276a2d00003a0000200241a0036a41086a2005413c6a290000370300200241a0036a41106a200541c4006a2d00003a00002002200541256a2f00003b01d8022002200541346a2900003703a003200541306a28000021112005412c6a2800002112200541286a28000021134105210c0c040b200541306a2802002212417f4c0d14200541286a28020021054101210c4101211302402012450d002012102c2213450d160b20132005201210e9081a201221110c030b4102210c200241d8026a41026a200541276a2d00003a0000200241a0036a41086a2005413c6a290000370300200241a0036a41106a200541c4006a2d00003a00002002200541256a2f00003b01d8022002200541346a2900003703a003200541306a28000021112005412c6a2800002112200541286a28000021130c020b200241d8026a41026a200541276a2d00003a0000200241a0036a41086a2005413c6a290000370300200241a0036a41106a200541c4006a2d00003a00002002200541256a2f00003b01d8022002200541346a2900003703a003200541306a28000021112005412c6a2800002112200541286a28000021134103210c0c010b200241d8026a41026a200541276a2d00003a0000200241a0036a41086a2005413c6a290000370300200241a0036a41106a200541c4006a2d00003a00002002200541256a2f00003b01d8022002200541346a2900003703a003200541306a28000021112005412c6a2800002112200541286a28000021134104210c0b2007200a6a2205200d3a0000200541016a20022f01f0023b0000200541036a200241f0026a41026a2d00003a00002005410c6a200e360200200541086a200f360200200541046a2010360200200541106a200229038803370200200541186a20024188036a41086a290300370200200541206a20024188036a41106a280200360200200541246a200c3a0000200541256a20022f01d8023b0000200541276a200241d8026a41026a2d00003a0000200541306a20113602002005412c6a2012360200200541286a2013360200200541346a20022903a0033702002005413c6a200241a0036a41086a290300370200200541c4006a200241a0036a41106a2802003602002009417f6a2109200a41c8006a210a200b417f6a220b0d000b0b4100211441002115024002400240024002400240200141106a2d00000e06050102030400050b200241f4016a200141136a2d00003a0000200241e8016a200141286a290000370300200241e0016a41106a200141306a2d00003a00002002200141116a2f00003b01f2012002200141206a2900003703e0012001411c6a2800002105200141186a2800002116200141146a2800002110410521150c040b2001411c6a2802002205417f4c0d12200141146a280200210a410121154101211002402005450d002005102c2210450d140b2010200a200510e9081a200521160c030b41022115200241f2016a41026a200141136a2d00003a0000200241e8016a200141286a290000370300200241e0016a41106a200141306a2d00003a00002002200141116a2f00003b01f2012002200141206a2900003703e0012001411c6a2800002105200141186a2800002116200141146a28000021100c020b200241f4016a200141136a2d00003a0000200241e8016a200141286a290000370300200241e0016a41106a200141306a2d00003a00002002200141116a2f00003b01f2012002200141206a2900003703e0012001411c6a2800002105200141186a2800002116200141146a2800002110410321150c010b200241f4016a200141136a2d00003a0000200241e8016a200141286a290000370300200241e0016a41106a200141306a2d00003a00002002200141116a2f00003b01f2012002200141206a2900003703e0012001411c6a2800002105200141186a2800002116200141146a2800002110410421150b024002400240024002400240200141346a2d00000e06050102030400050b2002418c026a200141376a2d00003a000020024180026a200141cc006a29000037030020024188026a200141d4006a2d00003a00002002200141356a2f00003b018a022002200141c4006a2900003703f801200141c0006a280000210a2001413c6a2800002117200141386a2800002113410521140c040b200141c0006a280200220a417f4c0d12200141386a280200210941012114410121130240200a450d00200a102c2213450d140b20132009200a10e9081a200a21170c030b410221142002418a026a41026a200141376a2d00003a000020024180026a200141cc006a29000037030020024188026a200141d4006a2d00003a00002002200141356a2f00003b018a022002200141c4006a2900003703f801200141c0006a280000210a2001413c6a2800002117200141386a28000021130c020b2002418c026a200141376a2d00003a000020024180026a200141cc006a29000037030020024188026a200141d4006a2d00003a00002002200141356a2f00003b018a022002200141c4006a2900003703f801200141c0006a280000210a2001413c6a2800002117200141386a2800002113410321140c010b2002418c026a200141376a2d00003a000020024180026a200141cc006a29000037030020024188026a200141d4006a2d00003a00002002200141356a2f00003b018a022002200141c4006a2900003703f801200141c0006a280000210a2001413c6a2800002117200141386a2800002113410421140b4100211841002119024002400240024002400240200141d8006a2d00000e06050102030400050b200241a4026a200141db006a2d00003a000020024198026a200141f0006a290000370300200241a0026a200141f8006a2d00003a00002002200141d9006a2f00003b01a2022002200141e8006a29000037039002200141e4006a2800002109200141e0006a280000211a200141dc006a280000210b410521190c040b200141e4006a2802002209417f4c0d12200141dc006a280200210c410121194101210b02402009450d002009102c220b450d140b200b200c200910e9081a2009211a0c030b41022119200241a2026a41026a200141db006a2d00003a000020024198026a200141f0006a290000370300200241a0026a200141f8006a2d00003a00002002200141d9006a2f00003b01a2022002200141e8006a29000037039002200141e4006a2800002109200141e0006a280000211a200141dc006a280000210b0c020b200241a4026a200141db006a2d00003a000020024198026a200141f0006a290000370300200241a0026a200141f8006a2d00003a00002002200141d9006a2f00003b01a2022002200141e8006a29000037039002200141e4006a2800002109200141e0006a280000211a200141dc006a280000210b410321190c010b200241a4026a200141db006a2d00003a000020024198026a200141f0006a290000370300200241a0026a200141f8006a2d00003a00002002200141d9006a2f00003b01a2022002200141e8006a29000037039002200141e4006a2800002109200141e0006a280000211a200141dc006a280000210b410421190b024002400240024002400240200141fc006a2d00000e06050102030400050b200241bc026a200141ff006a2d00003a0000200241b0026a20014194016a290000370300200241b8026a2001419c016a2d00003a00002002200141fd006a2f00003b01ba0220022001418c016a2900003703a80220014188016a280000211b20014184016a280000210c20014180016a2800002111410521180c040b20014188016a280200220c417f4c0d1220014180016a280200210d41012118410121110240200c450d00200c102c2211450d140b2011200d200c10e9081a200c211b0c030b41022118200241ba026a41026a200141ff006a2d00003a0000200241b0026a20014194016a290000370300200241b8026a2001419c016a2d00003a00002002200141fd006a2f00003b01ba0220022001418c016a2900003703a80220014188016a280000211b20014184016a280000210c20014180016a28000021110c020b200241bc026a200141ff006a2d00003a0000200241b0026a20014194016a290000370300200241b8026a2001419c016a2d00003a00002002200141fd006a2f00003b01ba0220022001418c016a2900003703a80220014188016a280000211b20014184016a280000210c20014180016a2800002111410321180c010b200241bc026a200141ff006a2d00003a0000200241b0026a20014194016a290000370300200241b8026a2001419c016a2d00003a00002002200141fd006a2f00003b01ba0220022001418c016a2900003703a80220014188016a280000211b20014184016a280000210c20014180016a2800002111410421180b4100211c4100211d024002400240024002400240200141a0016a2d00000e06050102030400050b200241d4026a200141a3016a2d00003a0000200241c8026a200141b8016a290000370300200241d0026a200141c0016a2d00003a00002002200141a1016a2f00003b01d2022002200141b0016a2900003703c002200141ac016a280000211e200141a8016a280000210d200141a4016a280000210f4105211d0c040b200141ac016a280200220d417f4c0d12200141a4016a280200210e4101211d4101210f0240200d450d00200d102c220f450d140b200f200e200d10e9081a200d211e0c030b4102211d200241d2026a41026a200141a3016a2d00003a0000200241c8026a200141b8016a290000370300200241d0026a200141c0016a2d00003a00002002200141a1016a2f00003b01d2022002200141b0016a2900003703c002200141ac016a280000211e200141a8016a280000210d200141a4016a280000210f0c020b200241d4026a200141a3016a2d00003a0000200241c8026a200141b8016a290000370300200241d0026a200141c0016a2d00003a00002002200141a1016a2f00003b01d2022002200141b0016a2900003703c002200141ac016a280000211e200141a8016a280000210d200141a4016a280000210f4103211d0c010b200241d4026a200141a3016a2d00003a0000200241c8026a200141b8016a290000370300200241d0026a200141c0016a2d00003a00002002200141a1016a2f00003b01d2022002200141b0016a2900003703c002200141ac016a280000211e200141a8016a280000210d200141a4016a280000210f4104211d0b02402001418c026a2d00004101470d00200241b0036a2001419d026a280000360200200241a8036a20014195026a29000037030020022001418d026a2900003703a0034101211c0b4100211f41002120024002400240024002400240200141c4016a2d00000e06050102030400050b200241ec026a200141c7016a2d00003a0000200241e0026a200141dc016a290000370300200241e8026a200141e4016a2d00003a00002002200141c5016a2f00003b01ea022002200141d4016a2900003703d802200141d0016a2800002121200141cc016a280000210e200141c8016a2800002108410521200c040b200141d0016a280200220e417f4c0d12200141c8016a280200211241012120410121080240200e450d00200e102c2208450d140b20082012200e10e9081a200e21210c030b41022120200241ea026a41026a200141c7016a2d00003a0000200241e0026a200141dc016a290000370300200241e8026a200141e4016a2d00003a00002002200141c5016a2f00003b01ea022002200141d4016a2900003703d802200141d0016a2800002121200141cc016a280000210e200141c8016a28000021080c020b200241ec026a200141c7016a2d00003a0000200241e0026a200141dc016a290000370300200241e8026a200141e4016a2d00003a00002002200141c5016a2f00003b01ea022002200141d4016a2900003703d802200141d0016a2800002121200141cc016a280000210e200141c8016a2800002108410321200c010b200241ec026a200141c7016a2d00003a0000200241e0026a200141dc016a290000370300200241e8026a200141e4016a2d00003a00002002200141c5016a2f00003b01ea022002200141d4016a2900003703d802200141d0016a2800002121200141cc016a280000210e200141c8016a2800002108410421200b024002400240024002400240200141e8016a2d00000e06050102030400050b20024186036a200141eb016a2d00003a0000200241f8026a20014180026a29000037030020024180036a20014188026a2d00003a00002002200141e9016a2f00003b0184032002200141f8016a2900003703f002200141f4016a2800002122200141f0016a2800002112200141ec016a28000021234105211f0c040b200141f4016a2802002212417f4c0d12200141ec016a28020021014101211f4101212302402012450d002012102c2223450d140b20232001201210e9081a201221220c030b4102211f20024184036a41026a200141eb016a2d00003a0000200241f8026a20014180026a29000037030020024180036a20014188026a2d00003a00002002200141e9016a2f00003b0184032002200141f8016a2900003703f002200141f4016a2800002122200141f0016a2800002112200141ec016a28000021230c020b20024186036a200141eb016a2d00003a0000200241f8026a20014180026a29000037030020024180036a20014188026a2d00003a00002002200141e9016a2f00003b0184032002200141f8016a2900003703f002200141f4016a2800002122200141f0016a2800002112200141ec016a28000021234103211f0c010b20024186036a200141eb016a2d00003a0000200241f8026a20014180026a29000037030020024180036a20014188026a2d00003a00002002200141e9016a2f00003b0184032002200141f8016a2900003703f002200141f4016a2800002122200141f0016a2800002112200141ec016a28000021234104211f0b200241da016a41026a2201200241f2016a41026a2d00003a0000200241c8016a41086a2224200241e0016a41086a290300370300200241c8016a41106a2225200241e0016a41106a2d00003a0000200241c4016a41026a2226200241dd016a41026a2d00003a0000200241c0016a41026a22272002418a026a41026a2d00003a0000200220022f01f2013b01da01200220022903e0013703c801200220022f00dd013b01c401200220022f018a023b01c001200241a8016a41106a2228200241f8016a41106a2d00003a0000200241a8016a41086a2229200241f8016a41086a290300370300200241a4016a41026a222a200241f5016a41026a2d00003a0000200241a0016a41026a222b200241a2026a41026a2d00003a000020024188016a41086a222c20024190026a41086a29030037030020024188016a41106a222d20024190026a41106a2d00003a0000200220022903f8013703a801200220022f00f5013b01a401200220022f01a2023b01a00120022002290390023703880120024184016a41026a222e2002418d026a41026a2d00003a000020024180016a41026a222f200241ba026a41026a2d00003a0000200241e8006a41106a2230200241a8026a41106a2d00003a0000200241e8006a41086a2231200241a8026a41086a290300370300200241e4006a41026a2232200241a5026a41026a2d00003a0000200220022f008d023b018401200220022f01ba023b018001200220022903a802370368200220022f00a5023b0164200241e0006a41026a2233200241d2026a41026a2d00003a0000200220022f01d2023b0160200241c8006a41106a2234200241c0026a41106a2d00003a0000200241c8006a41086a2235200241c0026a41086a290300370300200220022903c002370348200241c4006a41026a2236200241bd026a41026a2d00003a0000200220022f00bd023b014420024188036a41106a2237200241a0036a41106a28020036020020024188036a41086a2238200241a0036a41086a290300370300200220022903a00337038803200241c0006a41026a2239200241ea026a41026a2d00003a0000200220022f01ea023b0140200241286a41106a223a200241d8026a41106a2d00003a0000200241286a41086a223b200241d8026a41086a290300370300200220022903d802370328200241246a41026a223c200241d5026a41026a2d00003a0000200220022f00d5023b0124200241206a41026a223d20024184036a41026a2d00003a0000200220022f0184033b0120200241086a41106a223e200241f0026a41106a2d00003a0000200241086a41086a223f200241f0026a41086a290300370300200220022903f002370308200241046a41026a2240200241ed026a41026a2d00003a0000200220022f00ed023b0104200041106a20153a00002000410c6a2003360200200041086a2006360200200041046a20073602002000411c6a2005360000200041186a2016360000200041146a2010360000200041116a20022f01da013b0000200041136a20012d00003a0000200041206a20022903c801370000200041286a2024290300370000200041306a20252d00003a0000200041316a20022f01c4013b0000200041336a20262d00003a0000200041346a20143a0000200041376a20272d00003a0000200041356a20022f01c0013b0000200041c0006a200a3600002000413c6a2017360000200041386a2013360000200041d4006a20282d00003a0000200041cc006a2029290300370000200041c4006a20022903a801370000200041d7006a202a2d00003a0000200041d5006a20022f01a4013b0000200041d8006a20193a0000200041db006a202b2d00003a0000200041d9006a20022f01a0013b0000200041e4006a2009360000200041e0006a201a360000200041dc006a200b360000200041f8006a202d2d00003a0000200041f0006a202c290300370000200041e8006a200229038801370000200041fb006a202e2d00003a0000200041f9006a20022f0184013b0000200041fc006a20183a0000200041ff006a202f2d00003a0000200041fd006a20022f0180013b000020004188016a201b36000020004184016a200c36000020004180016a20113600002000419c016a20302d00003a000020004194016a20312903003700002000418c016a20022903683700002000419f016a20322d00003a00002000419d016a20022f01643b0000200041a0016a201d3a0000200041a3016a20332d00003a0000200041a1016a20022f01603b0000200041ac016a201e360000200041a8016a200d360000200041a4016a200f360000200041c0016a20342d00003a0000200041b8016a2035290300370000200041b0016a2002290348370000200041c3016a20362d00003a0000200041c1016a20022f01443b0000200041c4016a20203a0000200041c7016a20392d00003a0000200041c5016a20022f01403b0000200041d0016a2021360000200041cc016a200e360000200041c8016a2008360000200041e4016a203a2d00003a0000200041dc016a203b290300370000200041d4016a2002290328370000200041e7016a203c2d00003a0000200041e5016a20022f01243b0000200041e8016a201f3a0000200041eb016a203d2d00003a0000200041e9016a20022f01203b0000200041f4016a2022360000200041f0016a2012360000200041ec016a202336000020004188026a203e2d00003a000020004180026a203f290300370000200041f8016a20022903083700002000418b026a20402d00003a000020004189026a20022f01043b00002000418c026a201c3a00002000419d026a203728020036000020004195026a20382903003700002000418d026a200229038803370000200041a3026a200241a0036a41026a2d00003a0000200041a1026a20022f00a0033b0000200041023a00000c0d0b2001410c6a2802002214ad42c4007e2204422088a70d0d2004a72211417f4c0d0d0240024020110d00201141c4006e2123410421070c010b200141046a28020021082011102c2207450d0f201141c4006e2123201141c400490d004100210a200241f2026a210f200821052023210e03402011200a460d01200241a0036a41086a2212200541086a290200370300200241a0036a41106a2210200541106a290200370300200241a0036a41186a2213200541186a290200370300200220052902003703a0034100210902400240024002400240024020052d00200e06050102030400050b200f2008200a6a220141236a2d00003a000020024188036a41086a200141386a29000037030020024188036a41106a200141c0006a2d00003a00002002200141216a2f00003b01f0022002200141306a290000370388032001412c6a280000210b200141286a280000210c200141246a280000210d410521090c040b2008200a6a2201412c6a280200220c417f4c0d13200141246a2802002101410121094101210d0240200c450d00200c102c220d450d150b200d2001200c10e9081a200c210b0c030b41022109200241f0026a41026a2008200a6a220141236a2d00003a000020024188036a41086a200141386a29000037030020024188036a41106a200141c0006a2d00003a00002002200141216a2f00003b01f0022002200141306a290000370388032001412c6a280000210b200141286a280000210c200141246a280000210d0c020b200f2008200a6a220141236a2d00003a000020024188036a41086a200141386a29000037030020024188036a41106a200141c0006a2d00003a00002002200141216a2f00003b01f0022002200141306a290000370388032001412c6a280000210b200141286a280000210c200141246a280000210d410321090c010b200f2008200a6a220141236a2d00003a000020024188036a41086a200141386a29000037030020024188036a41106a200141c0006a2d00003a00002002200141216a2f00003b01f0022002200141306a290000370388032001412c6a280000210b200141286a280000210c200141246a280000210d410421090b200541c4006a21052007200a6a220120022903a003370200200141186a2013290300370200200141106a2010290300370200200141086a2012290300370200200141206a20093a0000200141216a20022f01f0023b0000200141236a200f2d00003a00002001412c6a200b360200200141286a200c360200200141246a200d360200200141306a200229038803370200200141386a20024188036a41086a290300370200200141c0006a20024188036a41106a280200360200200a41c4006a210a200e417f6a220e0d000b0b200041033a00002000410c6a2014360200200041086a2023360200200041046a20073602000c0c0b200041043a00000c0b0b200041053a0000200041106a200141106a290300370300200041086a200141086a290300370300200041046a200141046a2802003602000c0a0b200041063a0000200041046a200141046a2802003602000c090b200041073a0000200041106a200141106a290300370300200041086a200141086a290300370300200041046a200141046a2802003602000c080b200041083a000020002001290001370001200041246a200141246a280200360200200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c070b200041093a0000200041086a200141086a290300370300200041046a200141046a2802003602000c060b200141046a280200210d4101210902400240024002400240200141086a2d00000e050104020300010b2002418a036a2001410b6a2d00003a0000200241a0036a41046a2001411c6a2d00003a00002002200141096a2f00003b0188032002200141186a2800003602a003200141146a280000210c200141106a28000021052001410c6a280000210a410421090c030b2002418a036a2001410b6a2d00003a0000200241a0036a41086a200141206a290000370300200241a0036a41106a200141286a2d00003a00002002200141096a2f00003b0188032002200141186a2900003703a003200141146a280000210c200141106a28000021052001410c6a280000210a410021090c020b200141146a2802002205417f4c0d082001410c6a28020021090240024020050d004101210a0c010b2005102c220a450d0a0b200a2009200510e9081a410221092005210c0c010b2002418a036a2001410b6a2d00003a0000200241a0036a41086a200141206a290000370300200241a0036a41106a200141286a2d00003a00002002200141096a2f00003b0188032002200141186a2900003703a003200141146a280000210c200141106a28000021052001410c6a280000210a410321090b200141c0006a2903002141200141386a290300214242062104024002400240024002400240024020012802300e0700010203040506000b420021040c050b420121040c040b420221040c030b420321040c020b420421040c010b420521040b200041086a20093a0000200041046a200d360200200041096a20022f0188033b0000200041146a200c360000200041106a20053600002000410c6a200a360000200041186a20022903a003370000200041296a20022f00f0023b00002000410b6a20024188036a41026a2d00003a0000200041206a200241a0036a41086a290300370000200041286a200241a0036a41106a2d00003a00002000412b6a200241f0026a41026a2d00003a0000200041c0006a2041370300200041386a2042370300200041306a20043703002000410a3a00000c050b4101210902400240024002400240200141046a2d00000e050104020300010b2002418a036a200141076a2d00003a0000200241a0036a41046a200141186a2d00003a00002002200141056a2f00003b0188032002200141146a2800003602a003200141106a280000210c2001410c6a2800002105200141086a280000210a410421090c030b2002418a036a200141076a2d00003a0000200241a0036a41086a2001411c6a290000370300200241a0036a41106a200141246a2d00003a00002002200141056a2f00003b0188032002200141146a2900003703a003200141106a280000210c2001410c6a2800002105200141086a280000210a410021090c020b200141106a2802002205417f4c0d07200141086a28020021010240024020050d004101210a0c010b2005102c220a450d090b200a2001200510e9081a410221092005210c0c010b2002418a036a200141076a2d00003a0000200241a0036a41086a2001411c6a290000370300200241a0036a41106a200141246a2d00003a00002002200141056a2f00003b0188032002200141146a2900003703a003200141106a280000210c2001410c6a2800002105200141086a280000210a410321090b200041046a20093a0000200041056a20022f0188033b0000200041106a200c3600002000410c6a2005360000200041086a200a360000200041146a20022903a003370000200041256a20022f00f0023b0000200041076a20024188036a41026a2d00003a00002000411c6a200241a0036a41086a290300370000200041246a200241a0036a41106a2d00003a0000200041276a200241f0026a41026a2d00003a00002000410b3a00000c040b4101211202400240024002400240200141046a2d00000e050104020300010b200241c2026a200141076a2d00003a000020024188036a41046a200141186a2d00003a00002002200141056a2f00003b01c0022002200141146a28000036028803200141106a28000021102001410c6a2800002105200141086a280000210c410421120c030b200241c2026a200141076a2d00003a000020024188036a41086a2001411c6a29000037030020024188036a41106a200141246a2d00003a00002002200141056a2f00003b01c0022002200141146a29000037038803200141106a28000021102001410c6a2800002105200141086a280000210c410021120c020b200141106a2802002205417f4c0d06200141086a280200210a0240024020050d004101210c0c010b2005102c220c450d080b200c200a200510e9081a41022112200521100c010b200241c2026a200141076a2d00003a000020024188036a41086a2001411c6a29000037030020024188036a41106a200141246a2d00003a00002002200141056a2f00003b01c0022002200141146a29000037038803200141106a28000021102001410c6a2800002105200141086a280000210c410321120b4100210d02400240024002400240024020012d00280e06050102030400050b200241f2026a2001412b6a2d00003a0000200241a8036a200141c0006a290000370300200241b0036a200141c8006a2d00003a00002002200141296a2f00003b01f0022002200141386a2900003703a003200141346a280000210e200141306a280000210a2001412c6a28000021094105210d0c040b200141346a280200220a417f4c0d082001412c6a28020021014101210d410121090240200a450d00200a102c2209450d0a0b20092001200a10e9081a200a210e0c030b4102210d200241f0026a41026a2001412b6a2d00003a0000200241a8036a200141c0006a290000370300200241b0036a200141c8006a2d00003a00002002200141296a2f00003b01f0022002200141386a2900003703a003200141346a280000210e200141306a280000210a2001412c6a28000021090c020b200241f2026a2001412b6a2d00003a0000200241a8036a200141c0006a290000370300200241b0036a200141c8006a2d00003a00002002200141296a2f00003b01f0022002200141386a2900003703a003200141346a280000210e200141306a280000210a2001412c6a28000021094103210d0c010b200241f2026a2001412b6a2d00003a0000200241a8036a200141c0006a290000370300200241b0036a200141c8006a2d00003a00002002200141296a2f00003b01f0022002200141386a2900003703a003200141346a280000210e200141306a280000210a2001412c6a28000021094104210d0b200041046a20123a0000200041056a20022f01c0023b0000200041106a20103600002000410c6a2005360000200041086a200c360000200041146a200229038803370000200041256a20022f00a8023b0000200041076a200241c0026a41026a2d00003a00002000411c6a20024188036a41086a290300370000200041246a20024188036a41106a2d00003a0000200041276a200241a8026a41026a2d00003a0000200041286a200d3a00002000412c6a2009360000200041306a200a360000200041346a200e360000200041296a20022f01f0023b00002000412b6a200241f0026a41026a2d00003a0000200041386a20022903a003370000200041c0006a200241a0036a41086a290300370000200041c8006a200241a0036a41106a2d00003a0000200041c9006a20022f00d8023b0000200041cb006a200241d8026a41026a2d00003a00002000410c3a00000c030b4101211202400240024002400240200141046a2d00000e050104020300010b200241c2026a200141076a2d00003a000020024188036a41046a200141186a2d00003a00002002200141056a2f00003b01c0022002200141146a28000036028803200141106a28000021102001410c6a2800002105200141086a280000210c410421120c030b200241c2026a200141076a2d00003a000020024188036a41086a2001411c6a29000037030020024188036a41106a200141246a2d00003a00002002200141056a2f00003b01c0022002200141146a29000037038803200141106a28000021102001410c6a2800002105200141086a280000210c410021120c020b200141106a2802002205417f4c0d05200141086a280200210a0240024020050d004101210c0c010b2005102c220c450d070b200c200a200510e9081a41022112200521100c010b200241c2026a200141076a2d00003a000020024188036a41086a2001411c6a29000037030020024188036a41106a200141246a2d00003a00002002200141056a2f00003b01c0022002200141146a29000037038803200141106a28000021102001410c6a2800002105200141086a280000210c410321120b4100210d02400240024002400240024020012d00280e06050102030400050b200241f2026a2001412b6a2d00003a0000200241a8036a200141c0006a290000370300200241b0036a200141c8006a2d00003a00002002200141296a2f00003b01f0022002200141386a2900003703a003200141346a280000210e200141306a280000210a2001412c6a28000021094105210d0c040b200141346a280200220a417f4c0d072001412c6a28020021014101210d410121090240200a450d00200a102c2209450d090b20092001200a10e9081a200a210e0c030b4102210d200241f0026a41026a2001412b6a2d00003a0000200241a8036a200141c0006a290000370300200241b0036a200141c8006a2d00003a00002002200141296a2f00003b01f0022002200141386a2900003703a003200141346a280000210e200141306a280000210a2001412c6a28000021090c020b200241f2026a2001412b6a2d00003a0000200241a8036a200141c0006a290000370300200241b0036a200141c8006a2d00003a00002002200141296a2f00003b01f0022002200141386a2900003703a003200141346a280000210e200141306a280000210a2001412c6a28000021094103210d0c010b200241f2026a2001412b6a2d00003a0000200241a8036a200141c0006a290000370300200241b0036a200141c8006a2d00003a00002002200141296a2f00003b01f0022002200141386a2900003703a003200141346a280000210e200141306a280000210a2001412c6a28000021094104210d0b200041046a20123a0000200041056a20022f01c0023b0000200041106a20103600002000410c6a2005360000200041086a200c360000200041146a200229038803370000200041256a20022f00a8023b0000200041076a200241c0026a41026a2d00003a00002000411c6a20024188036a41086a290300370000200041246a20024188036a41106a2d00003a0000200041276a200241a8026a41026a2d00003a0000200041286a200d3a00002000412c6a2009360000200041306a200a360000200041346a200e360000200041296a20022f01f0023b00002000412b6a200241f0026a41026a2d00003a0000200041386a20022903a003370000200041c0006a200241a0036a41086a290300370000200041c8006a200241a0036a41106a2d00003a0000200041c9006a20022f00d8023b0000200041cb006a200241d8026a41026a2d00003a00002000410d3a00000c020b4101210902400240024002400240200141046a2d00000e050104020300010b2002418a036a200141076a2d00003a0000200241a0036a41046a200141186a2d00003a00002002200141056a2f00003b0188032002200141146a2800003602a003200141106a28000021052001410c6a280000210c200141086a280000210a410421090c030b2002418a036a200141076a2d00003a0000200241a0036a41086a2001411c6a290000370300200241a0036a41106a200141246a2d00003a00002002200141056a2f00003b0188032002200141146a2900003703a003200141106a28000021052001410c6a280000210c200141086a280000210a410021090c020b200141106a2802002205417f4c0d04200141086a28020021010240024020050d004101210a0c010b2005102c220a450d060b200a2001200510e9081a410221092005210c0c010b2002418a036a200141076a2d00003a0000200241a0036a41086a2001411c6a290000370300200241a0036a41106a200141246a2d00003a00002002200141056a2f00003b0188032002200141146a2900003703a003200141106a28000021052001410c6a280000210c200141086a280000210a410321090b200041046a20093a0000200041056a20022f0188033b0000200041106a20053600002000410c6a200c360000200041086a200a360000200041146a20022903a003370000200041256a20022f00f0023b0000200041076a20024188036a41026a2d00003a00002000411c6a200241a0036a41086a290300370000200041246a200241a0036a41106a2d00003a0000200041276a200241f0026a41026a2d00003a00002000410e3a00000c010b2000410f3a00000b200241c0036a24000f0b1038000b1036000bd90a01097f230041f0026b2202240002400240024002400240024002400240024002400240024020012d0000417f6a0e0a01020304050607080900010b200241186a2203200141196a290000370300200241106a2204200141116a290000370300200241086a2205200141096a29000037030020022001290001370300200241206a41186a2206200141396a290000370300200241206a41106a2207200141316a290000370300200241206a41086a2208200141296a2900003703002002200141216a290000370320200141c1006a2d0000210941b002102c220a450d0a200241c0006a200141c4006a28020010bb03200a200241c0006a41b00210e9082101200041196a2003290300370000200041116a2004290300370000200041096a200529030037000020002002290300370001200041216a2002290320370000200041296a2008290300370000200041316a2007290300370000200041396a2006290300370000200041c4006a2001360200200041c1006a20093a00002000410a3a00000c090b200241386a2203200141196a290000370300200241306a2204200141116a290000370300200241286a2205200141096a29000037030020022001290001370320200141216a2d0000210641b002102c2207450d09200241c0006a200141246a28020010bb032007200241c0006a41b00210e9082101200041196a2003290300370000200041116a2004290300370000200041096a200529030037000020002002290320370001200041246a2001360200200041216a20063a0000200041013a00000c080b200041023a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00003a00000c070b200041033a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00003a00000c060b200041043a00000c050b200041053a0000200020012d00013a0001200041046a200141046a280200360200200041026a200141026a2f01003b01000c040b200041063a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a290200370200200041226a200141226a2f01003b0100200041216a200141216a2d00003a00000c030b200041073a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000c020b200041083a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000c010b200041093a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000b200241f0026a24000f0b1036000bf14107037f017e057f017e027f027e067f230041b0056b220224000240024002400240024002400240024002400240024020012d0000417f6a0e0401020304000b41e2a0cc00412841889cc4001039000b200241086a200141046a10c80141b002102c2203450d03411021040240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141106a28020022012802000e1c0102030405060708090a0b0c0d0e0f101112131415161718191a1b00010b20024180036a200141386a10ca01200141086a2903002105200241d0016a41086a200141246a2d00003a000020022001411c6a2902003703d001200220012f01263b01ce01200141186a2802002106200141146a2802002107200141106a2802002108200141286a28020021092001412c6a280200210a200141306a290300210b200141f8016a280200210c20012d0025210d200229038003210e200229038803210f200241186a20024180036a41106a41b00110e9081a2005a721102005422088a7211120014184026a280200211220014180026a2802002101411b21040c1c0b20024180036a200141086a10cb01200220024194036a2802003602d001200229038003220f422088a7211120024190036a28020021062002418c036a280200210720024180036a41086a2802002108200fa72110410021040c1c0b20024180036a200141046a10cc01200241d8016a200241a0036a2d00003a0000200220024198036a2903003703d0012002200241a2036a2f01003b01ce0120022f00810320022d008303411074722113200229028403220f422088a7211120024194036a280200210620024180036a41106a28020021072002418c036a2802002108200241a1036a2d0000210d20022d0080032114200fa72110410121040c230b20024180036a200141086a10cd01200241d0016a41086a2002419c036a2d00003a0000200220024194036a2902003703d001200220022f019e033b01ce01200241b0036a290300210e200241a8036a290300210b20024180036a41106a28020021062002418c036a280200210720024180036a41086a2802002108200241a0036a2802002109200241a4036a280200210a200241b8036a290300210f20022d009d03210d2002290380032105200241186a200241c0036a41b00110e9081a200241e0016a41086a20024188056a290300370300200241e0016a41106a20024190056a290300370300200241f8016a20024198056a290300370300200220024180056a2903003703e0012005422088a72111200241fc046a2802002112200241f8046a2802002101200241f4046a2802002115200241f0046a280200210c2005a72110410221040c190b200141086a290300220fa72110200f422088a72111410321040c190b02400240024002400240024002400240024020012d0004417f6a0e050102030405000b41e2a0cc00412841e89bc4001039000b200141086a2802002110410121140c040b20024180036a41086a200141246a2d00003a000020022001411c6a2902003703800320012f0005200141076a2d0000411074722113200141186a2802002106200141146a2802002107200141106a28020021082001410c6a2802002111200141086a2802002110200141286a2802002109410221140c040b200141086a2802002110410321140c020b20024180036a41086a200141246a2d00003a000020022001411c6a2902003703800320012d0025410047210d20012f0005200141076a2d0000411074722113200141186a2802002106200141146a2802002107200141106a28020021082001410c6a2802002111200141086a2802002110200141286a2802002109410421140c030b200141086a2802002110410521140b0b0b200241d0016a41086a20024180036a41086a2d00003a000020022002290380033703d001410421040c200b20024180036a200141086a10ce01200241d0016a41086a2002419c036a2d00003a0000200241186a41086a200241c8036a290300370300200241186a41106a200241d0036a290300370300200241306a200241d8036a290300370300200220024194036a2902003703d001200220022f019e033b01ce012002200241c0036a2903003703182002290380032205422088a72111200241b0036a290300210e200241a8036a290300210b20024180036a41106a28020021062002418c036a280200210720024180036a41086a2802002108200241a0036a2802002109200241a4036a280200210a200241b8036a290300210f20022d009d03210d2005a72110410521040c150b20024180036a200141046a10cf0120022f00810320022d008303411074722113200229028403220f422088a7211120022d0080032114200fa72110410621040c1e0b20024180036a200141086a10d001200241d0016a41086a2002419c036a2d00003a0000200241186a41086a200241c8036a290300370300200241186a41106a200241d0036a290300370300200220024194036a2902003703d00120022002419e036a2f01003b01ce012002200241c0036a2903003703182002290380032205422088a72111200241b0036a290300210e200241a8036a290300210b20024180036a41106a28020021062002418c036a280200210720024180036a41086a28020021082002419d036a2d0000210d200241a0036a2802002109200241a4036a280200210a200241b8036a290300210f2005a72110410721040c130b10d101000b02400240200128020422130d0041002114410021110c010b200241206a200141246a2d00003a000020022001411c6a290000370318200220012f01263b01d0012002200141c8006a29020037038003200141386a290200210e200141306a290200210b200141186a2802002106200141146a2802002107200141106a2802002108200141286a28020021092001412c6a280200210a200141c0006a290200210f20012d0025210d200241a0036a200141e8006a29020037030020024180036a41186a200141e0006a29020037030020024180036a41106a200141d8006a29020037030020024180036a41306a200141f8006a29020037030020024180036a41386a20014180016a29020037030020024180036a41c0006a20014188016a29020037030020024180036a41d0006a20014198016a29020037030020024180036a41d8006a200141a0016a29020037030020024180036a41e0006a200141a8016a2902003703002002200141d0006a290200370388032002200141f0006a2902003703a803200220014190016a2902003703c80320024180036a4180016a200141c8016a29020037030020024180036a41f8006a200141c0016a29020037030020024180036a41f0006a200141b8016a2902003703002002200141b0016a2902003703e8032001410c6a2802002211417f4c0d190240024020110d00410121140c010b2011102c2214450d190b20142013201110e9081a200241f0026a41086a200241186a41086a2d00003a0000200220022903183703f002200220022f01d0013b01ee02200241e0016a20024180036a41880110e9081a0b200241d0016a41086a200241f0026a41086a2d00003a0000200220022903f0023703d001200220022f01ee023b01ce01200241186a200241e0016a41880110e9081a2014410876211341092104201121100c1b0b20024180036a200141086a10d201200241d0016a41086a2002419c036a2d00003a0000200220024194036a2902003703d001200220022f019e033b01ce01200241b0036a290300210e200241a8036a290300210b20024180036a41106a28020021062002418c036a280200210720024180036a41086a2802002108200241a0036a2802002109200241a4036a280200210a200241b8036a290300210f20022d009d03210d2002290380032105200241186a200241c0036a41b00110e9081a200241e0016a41086a20024188056a290300370300200241e0016a41106a20024190056a290300370300200220024180056a2903003703e0012005422088a72111200241fc046a2802002112200241f8046a2802002101200241f4046a2802002115200241f0046a280200210c2005a72110410a21040c110b20024180036a200141046a10d301200241d0016a41086a20024180036a41206a2d00003a0000200241186a41086a200241cc036a290200370300200241186a41106a200241d4036a290200370300200241186a41186a200241dc036a290200370300200241186a41206a200241e4036a280200360200200220024180036a41186a2903003703d001200220022f01a2033b01ce012002200241c4036a29020037031820022f00810320022d0083034110747221132002290284032205422088a72111200241b4036a290200210e200241ac036a290200210b20024194036a280200210620024180036a41106a28020021072002418c036a2802002108200241bc036a290200210f20022d008003211420022d00a103210d20022802a403210920022802a803210a2005a72110410b21040c190b10d401000b20024180036a200141086a10d501200241d0016a41086a2002419c036a2d00003a0000200220024194036a2902003703d00120022002419e036a2f01003b01ce01200229038003220f422088a72111200241b0036a290300210e200241a8036a290300210b20024190036a28020021062002418c036a280200210720024180036a41086a28020021082002419d036a2d0000210d200241a0036a2802002109200241a4036a280200210a200fa72110410d21040c0e0b20024180036a200141086a10d601200241d0016a41086a2002419c036a2d00003a0000200220024194036a2902003703d00120022002419e036a2f01003b01ce01200229038003220f422088a72111200241b0036a290300210e200241a8036a290300210b20024190036a28020021062002418c036a280200210720024180036a41086a28020021082002419d036a2d0000210d200241a0036a2802002109200241a4036a280200210a200fa72110410e21040c0d0b20024180036a200141086a10d601200241d0016a41086a2002419c036a2d00003a0000200220024194036a2902003703d00120022002419e036a2f01003b01ce01200229038003220f422088a72111200241b0036a290300210e200241a8036a290300210b20024190036a28020021062002418c036a280200210720024180036a41086a28020021082002419d036a2d0000210d200241a0036a2802002109200241a4036a280200210a200fa72110410f21040c0c0b20024180036a200141086a10d701200241d0016a41086a2002419c036a2d00003a0000200220024194036a2902003703d00120022002419e036a2f01003b01ce01200229038003220f422088a7211120024180036a41106a28020021062002418c036a280200210720024180036a41086a28020021082002419d036a2d0000210d200241a0036a2802002109200241a4036a280200210a200fa721100c0c0b4107211402400240024002400240024002400240024020012d0004417f6a0e0701020304050608000b41e2a0cc00412841a4c3cb001039000b20024180036a41086a200141246a2d00003a000020022001411c6a2900003703800320012f0005200141076a2d0000411074722113200141186a2800002106200141146a2800002107200141106a2800002108200141086a2900002105410121140c050b20024180036a41086a200141246a2d00003a000020022001411c6a2900003703800320012f0005200141076a2d0000411074722113200141186a2800002106200141146a2800002107200141106a2800002108200141086a2900002105410221140c040b20024180036a41086a200141246a2d00003a0000200220012f00263b011820022001411c6a29000037038003200141c0006a350000200141c4006a31000042208684210f20012f0005200141076a2d0000411074722113200141386a290000210e200141306a290000210b2001412c6a280000210a200141286a2800002109200141186a2800002106200141146a2800002107200141106a2800002108200141086a290000210520012d0025210d410321140c040b20024180036a200141086a10c80120022802880321082002290380032105410421140c030b20024180036a41086a200141246a2d00003a000020022001411c6a2900003703800320012f0005200141076a2d0000411074722113200141186a2800002106200141146a2800002107200141106a2800002108200141086a2900002105410521140c010b20024180036a41086a200141246a2d00003a000020022001411c6a2900003703800320012f0005200141076a2d0000411074722113200141186a2800002106200141146a2800002107200141106a2800002108200141086a2900002105410621140b0b200241d0016a41086a20024180036a41086a2d00003a000020022002290380033703d001200220022f01183b01ce012005422088a721112005a72110411121040c130b024002400240024002400240200141086a280200417f6a0e03010203000b41e2a0cc0041284184ccc2001039000b200141386a290300210e200141306a290300210b4101211041012113024002400240024002402001410c6a2d00000e050104020300010b4104211320024180036a41046a200141206a2d00003a000020022001411c6a2802003602800320012f000d2001410f6a2d0000411074722104200141186a2802002106200141146a2802002107200141106a28020021080c030b20024188036a200141246a2d00003a0000200220012f01263b01e00120022001411c6a2902003703800320012f000d2001410f6a2d00004110747221042001412c6a2d00002114200141286a2802002109200141186a2802002106200141146a2802002107200141106a280200210820012d0025210d410021130c020b200141186a2802002207417f4c0d15200141106a28020021010240024020070d00410121080c010b2007102c2208450d150b20082001200710e9081a41022113200721060c010b20024188036a200141246a2d00003a0000200220012f01263b01e00120022001411c6a2902003703800320012f000d2001410f6a2d00004110747221042001412c6a2d00002114200141286a2802002109200141186a2802002106200141146a2802002107200141106a280200210820012d0025210d410321130b200241186a41086a20024180036a41086a2d00003a00002002200229038003370318200220022f01e0013b01f002201441ff0171210a0c030b2001410c6a28020022134108762104410221100c010b2001410c6a28020022134108762104410321100b0b200241d0016a41086a200241186a41086a2d00003a0000200220022903183703d001200220022f01f0023b01ce012004410874201341ff0171722111411221040c090b20024180036a200141086a10d801200241d0016a41086a2002419c036a2d00003a0000200241186a41086a200241c8036a290300370300200241186a41106a200241d0036a290300370300200241306a200241d8036a290300370300200241186a41206a200241e0036a290300370300200241186a41286a200241e8036a290300370300200220024194036a2902003703d00120022002419e036a2f01003b01ce012002200241c0036a2903003703182002290380032205422088a72111200241b0036a290300210e20024180036a41286a290300210b20024180036a41106a28020021062002418c036a280200210720024180036a41086a28020021082002419d036a2d0000210d20024180036a41206a2802002109200241a4036a280200210a200241b8036a290300210f2005a72110411321040c070b20024180036a200141086a10d901200241d0016a41086a2002419c036a2d00003a0000200241186a41086a200241c8036a290300370300200241186a41106a200241d0036a290300370300200241306a200241d8036a290300370300200241186a41206a200241e0036a290300370300200241186a41286a200241e8036a290300370300200241186a41306a200241f0036a290300370300200220024194036a2902003703d001200220022f019e033b01ce012002200241c0036a2903003703182002290380032205422088a7211120024180036a41306a290300210e20024180036a41286a290300210b20024180036a41106a28020021062002418c036a280200210720024180036a41086a280200210820024180036a41206a2802002109200241a4036a280200210a200241b8036a290300210f20022d009d03210d2005a72110411421040c100b02400240024020012f0104417f6a0e03010200010b20024180036a200141086a10c901410321140c0f0b20024180036a200141086a10c901410121140c0e0b20012f0106211341b002102c2210450d0b20024180036a200141086a28020010da01201020024180036a41b00210e9081a200220133b011a41022114200241023b01180c0e0b20024180036a200141086a10db01200241d0016a41086a2002419c036a2d00003a0000200220024194036a2902003703d00120022002419e036a2f01003b01ce01200241b0036a290300210e200241a8036a290300210b20024180036a41106a28020021062002418c036a280200210720024180036a41086a28020021082002419d036a2d0000210d20024180036a41206a2802002109200241a4036a280200210a200241b8036a290300210f2002290380032105200241186a200241c0036a41b00110e9081a200241e0016a41086a20024188056a290300370300200241e0016a41106a20024190056a290300370300200241f8016a20024198056a290300370300200241e0016a41206a200241a0056a290300370300200220024180056a2903003703e0012005422088a72111200241fc046a2802002112200241f8046a2802002101200241f4046a2802002115200241f0046a280200210c2005a72110411621040c050b20024180036a200141046a10dc01200241d8016a200241a0036a2d00003a0000200220024198036a2903003703d0012002200241a2036a2f01003b01ce01200241b4036a290200210e200241ac036a290200210b20024194036a280200210620024180036a41106a28020021072002418c036a2802002108200241a1036a2d0000210d200241a4036a2802002109200241a8036a280200210a200241bc036a290200210f20022d0080032114200229028403210520022f008103210120022d00830321132002200241c4036a280200360218200120134110747221132005422088a721112005a72110411721040c0d0b20024180036a200141086a10dd01200241d0016a41086a2002419c036a2d00003a0000200220024194036a2902003703d00120022002419e036a2f01003b01ce012002200241c0036a2903003703182002290380032205422088a72111200241b0036a290300210e200241a8036a290300210b20024180036a41106a28020021062002418c036a280200210720024180036a41086a28020021082002419d036a2d0000210d200241a0036a2802002109200241a4036a280200210a200241b8036a290300210f2005a72110411821040c020b20024180036a200141086a10de01200241d0016a41086a2002419c036a2d00003a0000200220024194036a2902003703d001200220022f019e033b01ce012002290380032205422088a72111200241b0036a290300210e200241a8036a290300210b20024180036a41106a28020021062002418c036a280200210720024180036a41086a2802002108200241a0036a2802002109200241a4036a280200210a200241b8036a290300210f20022d009d03210d2005a72110411921040c010b20024180036a200141086a10df01200241d0016a41086a2002419c036a2d00003a0000200220024194036a2902003703d00120022002419e036a2f01003b01ce012002290380032205422088a72111200241b0036a290300210e200241a8036a290300210b20024180036a41106a28020021062002418c036a280200210720024180036a41086a28020021082002419d036a2d0000210d200241a0036a2802002109200241a4036a280200210a200241b8036a290300210f2005a72110411a21040b0b0b0c070b200141026a2f0100211320024180036a200141046a10c801200141246a2802002203417f4c0d032001411c6a2802002104200141186a2802002114200141146a2802002111200141106a28020021070240024020030d00410121080c010b2003102c2208450d030b20082004200310e9082104200041026a20133b0100200041246a2003360200200041206a20033602002000411c6a2004360200200041186a2014360200200041146a2011360200200041106a2007360200200041023a0000200041046a2002290380033702002000410c6a20024188036a280200360200200041286a2001290328370300200020012d00014100473a00010c070b200141226a2f0100210320024180036a200141246a10c801200041226a20033b0100200041246a2002290380033702002000412c6a20024188036a280200360200200041386a200141386a280200360200200041306a200141306a29020037030020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200141c0006a290300210f200041033a0000200041c0006a200f3703000c060b200141226a2f0100210320024180036a200141246a10c801200041226a20033b0100200041043a0000200041246a2002290380033702002000412c6a20024188036a280200360200200041306a200141306a29020037030020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c050b1036000b1038000b200220143b01182002280288032108200228028403211120022802800321100b20022f001920022d001b411074722113411521040b200320133b0005200320143a000420032004360200200341076a20134110763a000020032011ad4220862010ad843703082003200b3703302003200636021820032007360214200320083602102003200d3a00252003200f3703402003200a36022c20032009360228200320022f01ce013b0126200341386a200e370300200320022903d00137021c200341246a200241d0016a41086a2d00003a0000200341c8006a200241186a41b00110e9081a20032012360284022003200136028002200320153602fc012003200c3602f801200320022903e0013703880220034190026a200241e0016a41086a29030037030020034198026a200241e0016a41106a290300370300200341a0026a200241f8016a290300370300200341a8026a20024180026a2903003703002000410c6a200241086a41086a280200360200200041046a2002290308370200200041106a2003360200200041013a00000b200241b0056a24000b850d03027f027e057f230041206b2202240002400240024002400240024002400240024002400240024002402001280200417f6a0e09010203040506070809000b41e2a0cc00412841e0ecc0001039000b2001410c6a2802002203417f4c0d09200141186a2903002104200141106a2903002105200128020421064101210102402003450d002003102c2201450d0b0b20012006200310e9082101200041186a2004370300200041106a20053703002000410c6a2003360200200041086a200336020020002001360204200041013602000c080b20004102360200200020012802043602040c070b200128020421074101210802400240024002400240200141086a22092d00000e050104020300010b2002411e6a200941036a2d00003a000041042108200241086a41046a2001411c6a2d00003a0000200220092f00013b011c2002200141186a280000360208200141146a280200210a200141106a28020021032001410c6a28020021060c030b2002411e6a200941036a2d00003a0000200241086a41086a200141206a290000370300200241086a41106a200141286a2d00003a0000200220092f00013b011c2002200141186a290000370308200141146a280200210a200141106a28020021032001410c6a2802002106410021080c020b200141146a2802002203417f4c0d092001410c6a28020021080240024020030d00410121060c010b2003102c2206450d0b0b20062008200310e9081a410221082003210a0c010b410321082002411e6a200941036a2d00003a0000200241086a41086a200141206a290000370300200241086a41106a200141286a2d00003a0000200220092f00013b011c2002200141186a290000370308200141146a280200210a200141106a28020021032001410c6a28020021060b20002007360204200020022f011c3b0009200020022f00053b0029200041086a20083a0000200041146a200a360000200041106a20033600002000410c6a2006360000200041186a20022903083700002000410b6a2002411c6a41026a2d00003a0000200041206a200241086a41086a290300370000200041286a200241086a41106a2d00003a00002000412b6a200241056a41026a2d00003a000020012903302104200041386a200141386a290300370300200041306a2004370300200041033602000c060b20004104360200200020012802043602040c050b20004105360200200020012802043602040c040b200128020421074101210802400240024002400240200141086a22092d00000e050104020300010b2002411e6a200941036a2d00003a000041042108200241086a41046a2001411c6a2d00003a0000200220092f00013b011c2002200141186a280000360208200141146a280200210a200141106a28020021032001410c6a28020021060c030b2002411e6a200941036a2d00003a0000200241086a41086a200141206a290000370300200241086a41106a200141286a2d00003a0000200220092f00013b011c2002200141186a290000370308200141146a280200210a200141106a28020021032001410c6a2802002106410021080c020b200141146a2802002203417f4c0d062001410c6a28020021010240024020030d00410121060c010b2003102c2206450d080b20062001200310e9081a410221082003210a0c010b410321082002411e6a200941036a2d00003a0000200241086a41086a200141206a290000370300200241086a41106a200141286a2d00003a0000200220092f00013b011c2002200141186a290000370308200141146a280200210a200141106a28020021032001410c6a28020021060b20002007360204200020022f011c3b0009200020022f00053b0029200041086a20083a0000200041146a200a360000200041106a20033600002000410c6a2006360000200041186a20022903083700002000410b6a2002411c6a41026a2d00003a0000200041206a200241086a41086a290300370000200041286a200241086a41106a2d00003a00002000412b6a200241056a41026a2d00003a0000200041063602000c030b20004107360200200020012802043602040c020b20004108360200200020012802043602040c010b200141106a2802002203417f4c0d01200141086a2802002106200128020421010240024020030d00410121080c010b2003102c2208450d030b20082006200310e9082106200041106a20033602002000410c6a2003360200200041086a200636020020002001360204200041093602000b200241206a24000f0b1038000b1036000bc00501037f02400240024002400240024002400240024020012d0000417f6a0e06010203040506000b41e2a0cc00412841d4cec8001039000b2001412c6a2802002202417f4c0d05200141246a28020021034101210402402002450d002002102c2204450d070b20042003200210e90821042000412c6a2002360200200041286a2002360200200041246a2004360200200041013a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000f0b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2001412c6a2802002202417f4c0d03200141246a28020021040240024020020d00410121030c010b2002102c2203450d050b20032004200210e90821042000412c6a2002360200200041286a2002360200200041246a2004360200200041033a0000200041386a200141386a290300370300200041306a200129033037030020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000f0b200041043a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000f0b200041053a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b1038000b1036000bff0104017f017e037f037e0240024020012802082202ad42287e2203422088a70d002003a72204417f4c0d00200128020021050240024020040d00410821010c010b2004102c2201450d020b2000410036020820002001360200200041046a200441286e2206360200024020044128490d0003402004450d01200541086a2903002103200541106a29030021072005290320210820052903002109200141186a200541186a290300370300200141106a2007370300200141086a200337030020012009370300200141206a2008370300200141286a2101200441586a2104200541286a21052006417f6a22060d000b0b200020023602080f0b1038000b1036000ba80101017f024020002802082201450d0020002802002100200141246c210103400240024002400240024020002d00000e050400010204030b2000410c6a280200450d03200041086a280200102e0c030b2000410c6a280200450d02200041086a280200102e0c020b2000410c6a280200450d01200041086a280200102e0c010b200041086a280200450d00200041046a280200102e0b200041246a21002001415c6a22010d000b0b0bcd0101017f0240024002400240024020002802000e0404000102030b0240200041086a2802004125490d00200041106a280200102e0b200041386a280200450d03200041346a280200102e0f0b200041086a2802004125490d02200041106a280200102e0f0b2000280204102e200041086a2802002201450d012000410c6a280200450d012001102e0c010b0240200041086a2802004125490d00200041106a280200102e0b200041346a280200102e200041386a2802002201450d002000413c6a280200450d002001102e0f0b0bff0403037f017e077f230041306b22022400200241086a200110ab01024002402002280208450d00200041003602000c010b024002400240024002400240200228020c22032001280204410c6e2204200420034b1bad420c7e2205422088a70d002005a72204417f4c0d000240024020040d00410421060c010b2004102c2206450d040b2004410c6e2107024020030d00410021030c060b41002108410021094100210a03402002200110ab0120022802000d032001280204220b20022802042204490d032004417f4c0d010240024020040d004101210c0c010b20041032220c450d052001280204210b0b200b2004490d02200c2001280200200410e908210b2001280204220c2004490d052001200c20046b3602042001200128020020046a36020002400240200a2007470d002008200a41016a220c2008200c4b1b220c4104200c41044b1bad420c7e2205422088a745410274210c2005a7210702400240200a0d00200241003602200c010b2002410436022820022009360224200220063602200b200241106a2007200c200241206a107d2002280218210c20022802104101460d0120022802142106200c410c6e21070b200620096a220c200b360200200c41046a2004ad2205422086200584370200200841026a21082009410c6a21092003200a41016a220a460d070c010b0b200c0d030b1038000b200c102e0b200041003602000240200a450d002006210403400240200441046a280200450d002004280200102e0b2004410c6a2104200941746a22090d000b0b2007450d032007410c6c450d032006102e0c030b1036000b2004200c41b8b2c0001056000b2000200736020420002006360200200041086a20033602000b200241306a24000bd206030a7f017e017f230041f0016b220224002002200110ad01024002402002280200450d00200041003602000c010b024002400240024002402002280204220320012802002802044105762204200420034b1b22054105742204417f4c0d004101210602402005450d002004102c2206450d020b2001200128020441016a220436020402400240200420012802084b0d0020030d01410021030c060b200041003602000c030b410021070340200241003a00a8012007220841016a21074100210902400240024002400240034020012802002204280204220a450d0120024188016a20096a2004280200220b2d00003a00002004200a417f6a3602042004200b41016a3602002002200941016a22043a00a8012004210920044120470d000b200241e8006a41186a20024188016a41186a290300220c370300200241c8006a41086a220420024188016a41086a290300370300200241c8006a41106a220920024188016a41106a290300370300200241c8006a41186a220a200c3703002002200229038801370348200241286a41186a220b200a290300370300200241286a41106a220a2009290300370300200241286a41086a2209200429030037030020022002290348370328200241086a41186a220d200b290300370300200241086a41106a220b200a290300370300200241086a41086a220a20092903003703002002200229032837030820082005470d0320084101742204200841016a2209200420094b1b22044104200441044b1b220441ffffff3f7120044621092004410574210420080d0120024100360288010c020b0240200941ff0171450d00200241003a00a8010b200041003602000c070b200241013602900120022006360288012002200841057436028c010b200241e8006a2004200920024188016a107d2002280270210420022802684101460d01200228026c2106200441057621050b200620084105746a22042002290308370000200441186a200d290300370000200441106a200b290300370000200441086a200a29030037000020072003460d050c010b0b20040d010b1038000b1036000b200541ffffff3f71450d022006102e0c020b200128020421040b2000200536020420002006360200200041086a200336020020012004417f6a3602040b200241f0016a24000bfc0503037f017e0b7f23004190016b220224002002200110ab01024002402002280200450d00200041003602000c010b024002400240024020022802042203200128020441246e2204200420034b1bad42247e2205422088a70d002005a72204417f4c0d000240024020040d00410421060c010b2004102c2206450d030b200441246e2107024020030d00410021030c040b200241d8006a4101722108410021094100210a4100210b0340200241d8006a200110e601200241306a41086a2204200841086a290000370300200241306a41106a220c200841106a290000370300200241306a41186a220d200841186a290000370300200241306a411f6a220e2008411f6a2800003600002002200829000037033020022d0058220f4105460d02200241086a411f6a2210200e280000360000200241086a41186a220e200d290300370300200241086a41106a220d200c290300370300200241086a41086a220c20042903003703002002200229033037030802400240200b2007470d002009200b41016a2204200920044b1b22044104200441044b1bad42247e2205422088a74541027421042005a7210702400240200b0d00200241003602580c010b200241043602602002200a36025c200220063602580b20024180016a20072004200241d8006a107d20022802880121042002280280014101460d012002280284012106200441246e21070b2006200a6a2204200f3a0000200441016a2002290308370000200441096a200c290300370000200441116a200d290300370000200441196a200e290300370000200441206a2010280000360000200941026a2109200a41246a210a2003200b41016a220b460d050c010b0b20040d020b1038000b200041003602000240200b450d00200621040340024020042d00004102470d00200441086a280200450d00200441046a280200102e0b200441246a2104200a415c6a220a0d000b0b2007450d02200741246c450d022006102e0c020b1036000b2000200736020420002006360200200041086a20033602000b20024190016a24000b801103057f047e017f230041f0016b22022400024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a36020020050e050102030405060b200041053a00000c0e0b200241d8006a2001109301024020022d00584101460d0020024198016a200241d8006a41196a290000220737030020024190016a200241d8006a41116a290000220837030020024188016a200241d8006a41096a290000220937030020022002290059220a37038001200041003a00002000200a370001200041096a2009370000200041116a2008370000200041196a2007370000200041216a20022f00383b0000200041236a2002413a6a2d00003a00000c0e0b200041053a00000c0d0b200041013a00000c0c0b200241086a200110ab01024020022802080d0020012802042203200228020c2205490d002005417f4c0d050240024020050d004101210b0c010b20051032220b450d07200128020421030b024020032005490d00200b2001280200200510e90821032001280204220b2005490d082001200b20056b3602042001200128020020056a3602002003450d01200041023a0000200020022f0080013b0001200041086a2005ad2207422086200784370000200041046a2003360000200041106a2002290258370200200041036a20024180016a41026a2d00003a0000200041186a200241d8006a41086a290200370200200041206a200241d8006a41106a2802003602000c0d0b200b102e0b200041053a00000c0b0b41002105200241003a00782003417e6a21030240034020062005460d01200241d8006a20056a200420056a220b41016a2d00003a0000200120033602042001200b41026a3602002002200541016a220b3a00782003417f6a2103200b2105200b4120460d0a0c000b0b200541ff0171450d09200241003a00780c090b200241003a006c2006450d0620042d0001210520012003417e6a220b3602042001200441026a360200200241013a006c200220053a0058200b0d010c050b200041053a00000c080b20042d0002210520012003417d6a220b3602042001200441036a360200200241023a006c200220053a0059200b450d0320042d0003210520012003417c6a220b3602042001200441046a360200200241033a006c200220053a005a200b450d0320042d0004210520012003417b6a220b3602042001200441056a360200200241043a006c200220053a005b200b450d0320042d0005210520012003417a6a220b3602042001200441066a360200200241053a006c200220053a005c200b450d0320042d000621052001200341796a220b3602042001200441076a360200200241063a006c200220053a005d200b450d0320042d000721052001200341786a220b3602042001200441086a360200200241073a006c200220053a005e200b450d0320042d000821052001200341776a220b3602042001200441096a360200200241083a006c200220053a005f200b450d0320042d000921052001200341766a220b36020420012004410a6a360200200241093a006c200220053a0060200b450d0320042d000a21052001200341756a220b36020420012004410b6a3602002002410a3a006c200220053a0061200b450d0320042d000b21052001200341746a220b36020420012004410c6a3602002002410b3a006c200220053a0062200b450d0320042d000c21052001200341736a220b36020420012004410d6a3602002002410c3a006c200220053a0063200b450d0320042d000d21052001200341726a220b36020420012004410e6a3602002002410d3a006c200220053a0064200b450d0320042d000e21052001200341716a220b36020420012004410f6a3602002002410e3a006c200220053a0065200b450d0320042d000f21052001200341706a220b3602042001200441106a3602002002410f3a006c200220053a0066200b450d0320042d0010210520012003416f6a220b3602042001200441116a360200200241103a006c200220053a0067200b450d0320042d0011210520012003416e6a220b3602042001200441126a360200200241113a006c200220053a0068200b450d0320042d0012210520012003416d6a220b3602042001200441136a360200200241123a006c200220053a0069200b450d0320042d0013210520012003416c6a220b3602042001200441146a360200200241133a006c200220053a006a200b450d0320042d0014210520012003416b6a3602042001200441156a36020020024180016a41086a2201200241d8006a41086a290300370300200220053a006b20024180016a41106a2205200241d8006a41106a280200360200200241143a006c2002200229035837038001200241386a41106a22032005280200360200200241386a41086a220520012903003703002002200229038001370338200041043a000020002002290338370001200041096a2005290300370000200041116a2003280200360000200041156a20022900183700002000411c6a2002411f6a2900003700000c070b1038000b1036000b2005200b41b8b2c0001056000b200241003a006c0b200041053a00000c020b20024180016a41086a2205200241d8006a41086a29030037030020024180016a41106a2201200241d8006a41106a29030037030020024180016a41186a2203200241d8006a41186a2903003703002002200229035837038001200b41ff0171411f4d0d00200241186a41086a20052903002207370300200241186a41106a20012903002208370300200241186a41186a200329030022093703002002200229038001220a370318200041033a00002000200a370001200041096a2007370000200041116a2008370000200041196a2009370000200041216a20022f00153b0000200041236a200241176a2d00003a00000c010b200041053a00000b200241f0016a24000b8a0201067f230041106b22022400200241086a200110ab01024002400240024002402002280208450d00200041003602000c010b0240200228020c220341ffffffff03712003470d0020034102742204200128020422054b0d002004417f4c0d020240024020040d00410421060c010b200410322206450d04200128020421050b0240200520034102742207490d0020062001280200200710e9082105200128020422062007490d0520002003ad4220862004410276ad84370204200020053602002001200620076b3602042001200128020020076a3602000c020b2004450d002006102e0b200041003602000b200241106a24000f0b1038000b1036000b2007200641b8b2c0001056000bc50503037f017e087f230041306b22022400200241086a200110ad01024002402002280208450d00200041003602000c010b02400240024002400240024002400240200228020c22032001280200280204410c6e2204200420034b1bad420c7e2205422088a70d002005a72204417f4c0d000240024020040d00410421060c010b2004102c2206450d050b2001200128020441016a22073602042004410c6e210802400240200720012802084b0d0020030d01410021030c090b200041003602000c040b41002109410021074100210a03402002200110ad0120022802000d032001280200220b280204220c20022802042204490d032004417f4c0d010240024020040d004101210d0c010b20041032220d450d062001280200220b280204210c0b200c2004490d02200d200b280200200410e908210c200b280204220d2004490d06200b200d20046b360204200b200b28020020046a36020002400240200a2008470d002009200a41016a220b2009200b4b1b220b4104200b41044b1bad420c7e2205422088a745410274210b2005a7210802400240200a0d00200241003602200c010b2002410436022820022007360224200220063602200b200241106a2008200b200241206a107d2002280218210b20022802104101460d0120022802142106200b410c6e21080b200620076a220b200c360200200b41046a2004ad2205422086200584370200200941026a21092007410c6a21072003200a41016a220a460d080c010b0b200b0d040b1038000b200d102e0b20004100360200200a450d002006210403400240200441046a280200450d002004280200102e0b2004410c6a2104200741746a22070d000b0b2008450d042008410c6c450d042006102e0c040b1036000b2004200d41b8b2c0001056000b200128020421070b2000200836020420002006360200200041086a200336020020012007417f6a3602040b200241306a24000bd60704037f017e0a7f057e23004190026b220224002002200110ab01024002402002280200450d00200041003602000c010b024002400240024020022802042203200128020441306e2204200420034b1bad42307e2205422088a70d002005a72204417f4c0d000240024020040d00410821060c010b2004102c2206450d020b200441306e2107024020030d00410021030c040b410021080340200241003a00c8012008220941016a21082001280204210a417f210b41002104024002400340200a2004460d01200241a8016a20046a2001280200220c2d00003a00002001200a200b6a3602042001200c41016a3602002002200441016a220c3a00c801200b417f6a210b200c2104200c4120470d000b200241d0016a41086a2204200241a8016a41086a290300370300200241d0016a41106a220b200241a8016a41106a290300370300200241d0016a41186a220d200241a8016a41186a290300370300200220022903a8013703d001200c41ff0171411f4b0d010c050b200441ff0171450d04200241003a00c8010c040b200241e8006a41086a220e2004290300370300200241e8006a41106a220f200b290300370300200241e8006a41186a220b200d290300370300200220022903d001370368200a200c6b220c4110490d032001280200220441086a2900002105200429000021102001200441106a3602002001200c41706a360204200241286a41086a2204200e290300370300200241286a41106a220c200f290300370300200241286a41186a220a200b29030037030020022002290368370328200241086a41186a220b200a290300370300200241086a41106a220a200c290300370300200241086a41086a220c2004290300370300200220022903283703080240024020092007470d0020094101742204200941016a2207200420074b1b22044104200441044b1bad42307e2211422088a74541037421042011a721070240024020090d00200241003602a8010c010b200241083602b001200220063602a8012002200941306c3602ac010b200241d0016a20072004200241a8016a107d20022802d801210420022802d0014101460d0120022802d4012106200441306e21070b200c2903002111200a2903002112200b2903002113200229030821142006200941306c6a2204201037032020042014370300200441286a2005370300200441186a2013370300200441106a2012370300200441086a201137030020082003460d050c010b0b20040d010b1038000b1036000b200041003602002007450d01200741306c450d012006102e0c010b2000200736020420002006360200200041086a20033602000b20024190026a24000bb80603037f017e0b7f23004190016b220224002002200110ad01024002402002280200450d00200041003602000c010b02400240024002400240024020022802042203200128020028020441246e2204200420034b1bad42247e2205422088a70d002005a72204417f4c0d000240024020040d00410421060c010b2004102c2206450d040b2001200128020441016a2207360204200441246e210802400240200720012802084b0d0020030d01410021030c070b200041003602000c030b200241d8006a4101722107410021094100210a4100210b0340200241d8006a200110eb01200241306a41086a2204200741086a290000370300200241306a41106a220c200741106a290000370300200241306a41186a220d200741186a290000370300200241306a411f6a220e2007411f6a2800003600002002200729000037033020022d0058220f4105460d02200241086a411f6a2210200e280000360000200241086a41186a220e200d290300370300200241086a41106a220d200c290300370300200241086a41086a220c20042903003703002002200229033037030802400240200b2008470d002009200b41016a2204200920044b1b22044104200441044b1bad42247e2205422088a74541027421042005a7210802400240200b0d00200241003602580c010b200241043602602002200a36025c200220063602580b20024180016a20082004200241d8006a107d20022802880121042002280280014101460d012002280284012106200441246e21080b2006200a6a2204200f3a0000200441016a2002290308370000200441096a200c290300370000200441116a200d290300370000200441196a200e290300370000200441206a2010280000360000200941026a2109200a41246a210a2003200b41016a220b460d060c010b0b20040d030b1038000b20004100360200200b450d00200621040340024020042d00004102470d00200441086a280200450d00200441046a280200102e0b200441246a2104200a415c6a220a0d000b0b2008450d03200841246c450d032006102e0c030b1036000b200128020421070b2000200836020420002006360200200041086a200336020020012007417f6a3602040b20024190016a24000baf0a02057f027e230041b0026b2202240002400240024002400240024002400240024002400240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020020060e050102030405060b200041053a00000c060b41002104200241003a00b80102400340200128020022032802042205450d0120024198016a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00b8012003210420034120470d000b200241386a41186a20024198016a41186a2903002207370300200241086a41086a220120024198016a41086a290300370300200241086a41106a220320024198016a41106a290300370300200241086a41186a220420073703002002200229039801370308200041003a000020002002290308370001200041096a2001290300370000200041116a2003290300370000200041196a2004290300370000200041216a20022f00293b0000200041236a2002412b6a2d00003a00000c060b0240200441ff0171450d00200241003a00b8010b200041053a00000c050b200041013a00000c040b2002200110ad01024020022802000d0020012802002204280204220520022802042203490d002003417f4c0d050240024020030d00410121060c010b200310322206450d072001280200220428020421050b024020052003490d0020062004280200200310e9082101200428020422052003490d082004200520036b3602042004200428020020036a3602002001450d01200041023a0000200020022f00383b0001200041086a2003ad2207422086200784370000200041046a2001360000200041106a200229029801370200200041036a200241386a41026a2d00003a0000200041186a20024198016a41086a290200370200200041206a20024198016a41106a2802003602000c050b2006102e0b200041053a00000c030b41002104200241003a00b80102400340200128020022032802042205450d0120024198016a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00b8012003210420034120470d000b200241386a41186a20024198016a41186a2903002207370300200241086a41086a220120024198016a41086a290300370300200241086a41106a220320024198016a41106a290300370300200241086a41186a220420073703002002200229039801370308200041033a000020002002290308370001200041096a2001290300370000200041116a2003290300370000200041196a2004290300370000200041216a20022f00293b0000200041236a2002412b6a2d00003a00000c030b0240200441ff0171450d00200241003a00b8010b200041053a00000c020b41002104200241003a00ac0102400340200128020022032802042205450d0120024198016a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00ac012003210420034114470d000b200241086a41086a20024198016a41086a2903002207370300200241086a41106a20024198016a41106a280200220136020020022002290398012208370308200041043a000020002008370001200041096a2007370000200041116a2001360000200041156a20022900293700002000411c6a200241306a2900003700000c020b0240200441ff0171450d00200241003a00ac010b200041053a00000c010b200041053a00000b200241b0026a24000f0b1038000b1036000b2003200541b8b2c0001056000bde0505037f017e057f017e017f230041e00a6b220224002002200110ad01024002402002280200450d00200041003602000c010b02400240024002400240024020022802042203200128020028020441c8036e2204200420034b1bad42c8037e2205422088a70d002005a72204417f4c0d000240024020040d00410821060c010b2004102c2206450d040b2001200128020441016a2207360204200441c8036e210802400240200720012802084b0d0020030d01410021030c070b200041003602000c030b20024188076a41f0006a21094100210a4100210441002107034020024188076a200110ed01200241a0066a20024188076a41e80010e9081a20022903f0072105200241c8036a200941d80210e9081a20054203510d02200241e0026a200241a0066a41e80010e9081a200241086a200241c8036a41d80210e9081a0240024020072008470d00200a200741016a2208200a20084b1b22084104200841044b1bad42c8037e220b422088a7454103742108200ba7210c0240024020070d0020024100360288070c010b20024108360290072002200436028c0720022006360288070b200241d00a6a200c200820024188076a107d20022802d80a210820022802d00a4101460d0120022802d40a2106200841c8036e21080b200620046a200241e0026a41e80010e908220c41e8006a2005370300200c41f0006a200241086a41d80210e9081a200a41026a210a200441c8036a21042003200741016a2207460d060c010b0b20080d030b1038000b200041003602002007450d002006210a03400240200a220741e8006a2903004202510d0020072d00004102470d00200741086a280200450d00200741046a280200102e0b200741c8036a210a20074198016a109601200441b87c6a22040d000b0b2008450d03200841c8036c450d032006102e0c030b1036000b200128020421070b2000200836020420002006360200200041086a200336020020012007417f6a3602040b200241e00a6a24000bdf1504057f017e077f067e230041c00a6b22022400200241286a200110ad0102400240024002400240024002400240024020022802280d00200228022c210320012001280204220441016a2205360204200520012802084b0d0002402003450d0041002105410020036b2103034020054101460d0520032005417f6a2205470d000b0b20012004360204200128020022052802042203450d01200528020022062d0000210420052003417f6a3602042005200641016a360200200441ff00714104460d02200042033703680c080b200042033703680c070b200042033703680c060b02402004411874411875417f4c0d00420221070c040b20024180076a200110eb01024020022d00800722044105460d00200241fc066a41026a20022d0083073a0000200241e0066a41086a20024194076a290200370300200241f0066a2002419c076a290200370300200220022f0081073b01fc0620022002418c076a2902003703e00620024180076a41086a2802002105200228028407210602400240024002400240200128020022032802042208450d00200328020022092d0000210a20032008417f6a3602042003200941016a36020002400240024002400240200a0e03000102050b41002108200241003a00e80402400340200128020022032802042209450d01200241a8046a20086a2003280200220a2d00003a000020032009417f6a3602042003200a41016a3602002002200841016a22033a00e80420032108200341c000470d000b200241f8016a41086a2203200241a8046a41086a290300370300200241f8016a41106a2208200241a8046a41106a290300370300200241f8016a41186a2209200241a8046a41186a290300370300200241f8016a41206a220a200241a8046a41206a290300370300200241f8016a41286a220b200241a8046a41286a290300370300200241f8016a41306a220c200241a8046a41306a290300370300200241f8016a41386a220d200241a8046a41386a290300370300200220022903a8043703f801200241f8096a41386a220e200d290300370300200241f8096a41306a200c2903002207370300200241f8096a41286a200b290300220f370300200241f8096a41206a200a2903002210370300200241f8096a41186a20092903002211370300200241f8096a41106a20082903002212370300200241f8096a41086a20032903002213370300200220022903f80122143703f809200241e8076a41306a2007370300200241e8076a41286a200f370300200241e8076a41206a2010370300200241e8076a41186a2011370300200241e8076a41106a2012370300200241e8076a41086a2013370300200241e8076a41386a200e290300370300200220143703e807410021080c030b200841ff0171450d04200241003a00e8040c040b41002108200241003a00e80402400340200128020022032802042209450d01200241a8046a20086a2003280200220a2d00003a000020032009417f6a3602042003200a41016a3602002002200841016a22033a00e80420032108200341c000470d000b200241f8016a41086a2203200241a8046a41086a290300370300200241f8016a41106a2208200241a8046a41106a290300370300200241f8016a41186a2209200241a8046a41186a290300370300200241f8016a41206a220a200241a8046a41206a290300370300200241f8016a41286a220b200241a8046a41286a290300370300200241f8016a41306a220c200241a8046a41306a290300370300200241f8016a41386a220d200241a8046a41386a290300370300200220022903a8043703f801200241f8096a41386a220e200d290300370300200241f8096a41306a200c2903002207370300200241f8096a41286a200b290300220f370300200241f8096a41206a200a2903002210370300200241f8096a41186a20092903002211370300200241f8096a41106a20082903002212370300200241f8096a41086a20032903002213370300200220022903f80122143703f809200241e8076a41306a2007370300200241e8076a41286a200f370300200241e8076a41206a2010370300200241e8076a41186a2011370300200241e8076a41106a2012370300200241e8076a41086a2013370300200241e8076a41386a200e290300370300200220143703e807410121080c020b200841ff0171450d03200241003a00e8040c030b41002108200241003a00e9040340200128020022032802042209450d02200241a8046a20086a2003280200220a2d00003a000020032009417f6a3602042003200a41016a3602002002200841016a22033a00e90420032108200341c100470d000b200241f8016a200241a8046a41c10010e9081a200241f8096a200241f8016a41c10010e9081a200241b6096a200241f8096a41c10010e9081a200241e8076a200241b6096a41c10010e9081a410221080b200241a7076a200241e8076a41c10010e9081a200128020022032802042209450d042003280200220a310000211020032009417f6a3602042003200a41016a360200201050450d02420021070c030b200841ff0171450d00200241003a00e9040b20044102470d0420050d030c040b200128020022032802042209450d012003280200220a310000211120032009417f6a3602042003200a41016a36020042022010420f8386220f4204540d01420121072011420886201084420488200f420c882210420120104201561b7e2210200f5a0d010b200241206a200110ad0120022802200d0020022802242109200241086a20011082022002290308a7450d040b20044102470d012005450d010b2006102e0b420221070c020b1038000b200241086a41106a290300211220022903102111200241f8096a41026a200241fc066a41026a2d00003a0000200241f8016a41086a200241e0066a41086a290300370300200241f8016a41106a200241e0066a41106a290300370300200220022f01fc063b01f809200220022903e0063703f801200241a8046a200241a7076a41c10010e9081a200220022f01de063b01b6090b200241f4016a41026a2203200241f8096a41026a2d00003a0000200241d8016a41086a220a200241f8016a41086a290300370300200241d8016a41106a220b200241f8016a41106a290300370300200220022f01f8093b01f401200220022903f8013703d80120024197016a200241a8046a41c10010e9081a200220022f01b6093b01940120074202510d0120024190016a41026a20032d00003a0000200241f8006a41086a200a290300370300200241f8006a41106a200b290300370300200220022f01f4013b019001200220022903d801370378200241376a20024197016a41c10010e9081a200220022f0194013b01340b200241a8046a200110950120022802a8042103200241f8016a200241a8046a41047241ac0210e9081a02402003411c460d00200020043a0000200020022f0190013b000120002005360208200020063602042000200229037837020c200020083a0024200041036a20024192016a2d00003a0000200041146a20024180016a2903003702002000411c6a20024188016a290300370200200041256a200241376a41c10010e9081a20004188016a201237030020004180016a201137030020004190016a2009360200200041f8006a20103703002000200f37037020002007370368200020022f01343b016620004198016a20033602002000419c016a200241f8016a41ac0210e9081a0c020b2000420337036820074202510d01200441ff01714102470d012005450d012006102e0c010b200042033703680b200241c00a6a24000beb0201067f230041206b2202240002400240200041046a2802002203200041086a28020022046b20012802042205200128020022066b2207490d00200028020021030c010b0240200420076a22062004490d00200341017422042006200420064b1b22044108200441084b1b21040240024020030d00200241003602100c010b200241106a41086a410136020020022003360214200220002802003602100b200220044101200241106a107d200241086a2802002104024020022802004101460d00200020022802042203360200200041046a2004360200200041086a280200210420012802002106200128020421050c020b2004450d001036000b1038000b024020062005460d002001200641016a36020020062d0000210602400340200320046a20063a0000200128020022062001280204460d01200441016a21042001200641016a36020020062d000021060c000b0b200441016a21040b200041086a2004360200200241206a24000bde0a04077f017e037f017e230041d0006b22022400200241086a200110ad01024002402002280208450d00200041013602000c010b200228020c21032001200128020441016a2204360204024002400240024002400240200420012802084b0d00200241003a00172002420037021c024020030d00200241286a41086a200241186a41086a28020036020020022002290318370328200241286a21040c050b4100210502400240024002400340200241003a0030200128020022042802042206450d07200428020022072d0000210820042006417f6a3602042004200741016a360200200241013a0030200220083a0028200128020022042802042206450d06200428020022072d0000210820042006417f6a3602042004200741016a360200200241023a0030200220083a0029200128020022042802042206450d06200428020022072d0000210820042006417f6a3602042004200741016a360200200241033a0030200220083a002a200128020022042802042206450d06200428020022072d0000210820042006417f6a3602042004200741016a360200200241043a0030200220083a002b200128020022042802042206450d06200428020022072d0000210820042006417f6a3602042004200741016a360200200241053a0030200220083a002c200128020022042802042206450d06200428020022072d0000210820042006417f6a3602042004200741016a360200200241063a0030200220083a002d200128020022042802042206450d06200428020022072d0000210820042006417f6a3602042004200741016a360200200241073a0030200220083a002e200128020022042802042206450d06200428020022072d0000210820042006417f6a3602042004200741016a360200200220083a002f200229032821092002200110ad0120022802000d0720012802002206280204220720022802042204490d072004417f4c0d020240024020040d00410121080c010b200410322208450d042001280200220628020421070b20072004490d0120082006280200200410e908210a200628020422072004490d042006200720046b3602042006200628020020046a360200200a450d072002200937032802400240200228021c220b450d002002280218210c0c010b41e401102c220b450d044100210c200b4100360200200b41003b018a012002200b36021c200241003602180b200541016a21052004ad220d422086200d84210d024002400340200b418c016a2106200b2f018a012108410021040240034020082004460d01200241286a2006410810ec082207450d03200441016a2104200641086a21062007417f4a0d000b2004417f6a21080b0240200c450d00200c417f6a210c200b20084102746a41e4016a280200210b0c010b0b20022009370338200220083602302002200b36022c200241003602282002200241186a3602342002200d3702442002200a360240200241286a200241c0006a10f0010c010b200b2004410c6c6a220441086a220628020021072006200d370200200441046a220628020021042006200a3602002004450d002007450d002004102e0b20052003470d000b20022d00172104200241286a41086a200241186a41086a2802003602002002200229031837032820040d07200241286a21040c080b2008102e0c050b1038000b1036000b2004200741b8b2c0001056000b200041013602000c050b200241003a00300b200241013a0017200241286a41086a200241186a41086a280200360200200220022903183703280b200241286a10f101410121040c010b200020042902003702042000410c6a200441086a280200360200410021040b2000200436020020012001280204417f6a3602040b200241d0006a24000b931505017f017e097f017e067f230041e0006b2202240020002902102103200028020821042000280200210520002802042106200241206a41086a2207200141086a2802003602002002200129020037032002400240024020062f018a012201410a4b0d00200241c0006a41086a2007280200360200200220022903203703402006418c016a2107200141016a21080240200441016a220920014b220a0d00200720094103746a200720044103746a20082004417f736a41037410ea081a0b200720044103746a2003370000200241d0006a41086a2205200241c0006a41086a28020036020020022002290340370350200641046a21070240200a0d0020072009410c6c6a20072004410c6c6a200120046b410c6c10ea081a0b20072004410c6c6a22042002290350370200200441086a2005280200360200200620083b018a010c010b410521014100210a02400240200441054f0d0041042101200421070c010b41052107024002402004417b6a0e020201000b200441796a21074101210a410621010c010b410021074101210a0b0240024002400240024002400240024002400240024041e401102c2204450d00200441003b018a0120044100360200200420062f018a01220b2001417f736a22083b018a012006418c016a220c20014103746a290000210d200241d0006a41086a200641046a220e2001410c6c6a220941086a280200360200200220092902003703502008410c4f0d01200b200141016a22096b2008470d022004418c016a200c20094103746a200841037410e9081a200441046a200e2009410c6c6a2008410c6c10e9081a200620013b018a01200241306a41086a200241d0006a41086a220b28020036020020022002290350370330200241c0006a41086a220c200241206a41086a2802003602002002200229032037034020042006200a1b2201418c016a210820012f018a01220941016a210a0240200741016a220e20094b220f0d002008200e4103746a200820074103746a200a2007417f736a41037410ea081a0b200820074103746a2003370000200b200c28020036020020022002290340370350200141046a21080240200f0d002008200e410c6c6a20082007410c6c6a200920076b410c6c10ea081a0b20082007410c6c6a22072002290350370200200741086a200241d0006a41086a220b2802003602002001200a3b018a01200241106a41086a200241306a41086a220f2802002201360200200220022903302203370310200241086a22102001360200200220033703000240024002402006280200220a0d00410021050c010b200d21032004211141002101034020062f0188012108200f20102802003602002002200229030037033020052001470d06200a2f018a01220e410b490d024100210941042106024020084105490d0020082106024002402008417b6a0e020201000b200841796a210841012109410621060c010b4100210841012109410521060b419402102c2204450d03200441003b018a01200441003602002004200a2f018a01220c2006417f736a22013b018a01200a418c016a221220064103746a290000210d200b200a41046a22132006410c6c6a220741086a280200360200200220072902003703502001410c4f0d07200c200641016a22076b2001470d082004418c016a201220074103746a200141037410e9081a200441046a20132007410c6c6a2001410c6c10e9081a200a20063b018a01200241c0006a41086a220c200b2802003602002002200229035037034020042f018a01220141016a21122001410c4f0d09200e20066b22062012470d0a200541016a2105200441e4016a200a20074102746a41e4016a200641027410e9081a4100210602400340200420064102746a41e4016a280200220720063b018801200720043602002006200620014922076a220620014b0d0120070d000b0b200241206a41086a2212200c28020036020020022002290340370320200c200f280200360200200220022903303703402004200a20091b2207418c016a210e20072f018a01220141016a21090240200841016a220620014b22130d00200e20064103746a200e20084103746a2008417f7320096a41037410ea081a0b200e20084103746a2003370000200b200c28020036020020022002290340370350200741046a210c024020130d00200c2006410c6c6a200c2008410c6c6a200120086b410c6c10ea081a0b200c2008410c6c6a220c2002290350370200200c41086a200b280200360200200741e4016a210c0240200841026a220e200141026a22014f0d00200c200e4102746a200c20064102746a2006417f7320016a41027410ea081a0b200c20064102746a2011360200200720093b018a010240200620014f0d00200720084102746a41e8016a2106034020062802002201200841016a22083b01880120012007360200200641046a210620092008470d000b0b2010201228020036020020022002290320370300200a2106200a2802002207210a200d2103200421112005210120070d000b0b200f20102802002206360200200220022903002203370330200241c0006a41086a200636020020022003370340200028020c22012802042207450d0920012802002108419402102c2206450d01200620073602e401200641003b018a0120064100360200200741003b01880120072006360200200120063602042001200841016a360200200241d0006a41086a200241c0006a41086a2802003602002002200229034037035020082005470d0a20062f018a012207410b4f0d0b2006200741016a22083b018a01200620074103746a418c016a200d37000020062007410c6c6a2207410c6a200241d8006a280200360200200741046a2002290350370200200620084102746a41e4016a2004360200200420083b018801200420063602002001200128020841016a3602080c0d0b200241c0006a41086a2205200241306a41086a28020036020020022002290330370340200841016a2106200a418c016a2107200a2f018a01220441016a21090240200420084d22010d00200720064103746a200720084103746a2008417f7320096a41037410ea081a0b200720084103746a2003370000200241d0006a41086a200528020036020020022002290340370350200a41046a2107024020010d0020072006410c6c6a20072008410c6c6a200420086b410c6c10ea081a0b20072008410c6c6a22072002290350370200200741086a200241d0006a41086a280200360200200a41e4016a2107200441026a2105024020010d00200841027420076a41086a200720064102746a2006417f7320056a41027410ea081a0b200720064102746a2011360200200a20093b018a01200620054f0d0b200441016a2107200a2006417f6a22064102746a41e8016a2104034020042802002201200641016a22063b0188012001200a360200200441046a210420072006470d000c0c0b0b1036000b2008410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b41ac9cc700413541e49cc7001039000b2001410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b2012410c41f49cc700104d000b41f49bc7004128419c9cc7001039000b41e8aac700412b4194abc7001039000b41e899c700413041989ac7001039000b41a89ac700412041c89ac7001039000b200028020c2206200628020841016a3602080b200241e0006a24000bc80203047f017e017f200028020421012000410036020402402001450d00024020002802002202450d002002417f6a2102034020012802e40121012002450d012002417f6a21020c000b0b024020002802082203450d004100210003402003417f6a210341012102024002400340200020012f018a01490d010240200128020022040d002001102e410021010c030b20012f01880121002001102e2002417f6a2102200421010c000b0b200041016a210420012000410c6c6a220041086a2902002105200041046a2802002106024020024101470d00200421000c010b200120044102746a41e4016a280200210102402002450d000340200241016a220020024f210420012802e40121012000210220040d000b0b410021000b2006450d0202402005a7450d002006102e0b20030d000b0b0340200128020021022001102e2002210120020d000b0b0bc30301067f230041206b22022400200041086a28020022032001107602400240200028020422040d004100210441002100410021030c010b2000280200210520042100034020042f013221062005450d012005417f6a2105200420064102746a4194036a280200210420002802940321000c000b0b200241146a2006360200200241106a20043602002002200336021820024200370308200220003602042002200536020002402003450d00034020022003417f6a3602182002410020001b220628020021050240024020062802082203200628020422042f01324f0d00200421000c010b03400240200428020022000d00410021000c020b200541016a210520042f0130210320002104200320002f01324f0d000b0b200341016a21070240024020050d00200021040c010b200020074102746a4194036a280200210402402005417f6a2205450d00034020042802940321042005417f6a22050d000b0b410021070b2006200436020420064100360200200620073602082001200020034105746a41346a412010742002200020034102746a41046a28020036021c20012002411c6a4104107420022802182203450d01200228020421000c000b0b200241206a24000ba3990204067f1a7e157f407e230041d0ce006b22042400200441d0c6006a200341d00110e9081a200441d0c6006a41abd8c8004109200241a0016a412010840120044180c5006a200441d0c6006a41d00110e9081a200441a0c8006a41386a22024200370300200441a0c8006a41306a22034200370300200441a0c8006a41286a22054200370300200441a0c8006a41206a22064200370300200441a0c8006a41186a22074200370300200441a0c8006a41106a22084200370300200441a0c8006a41086a22094200370300200442003703a04820044180c5006a41b0b7c0004107200441a0c8006a41c0001086012008310000210a2009310000210b2007310000210c20043100b248210d20043100b148210e20043100af48210f20043100ad48211020043100ae48211120043100bf48211220043100be48211320043100bd48211420043100bc48211520043100bb48211620043100ba48211720043100ac48211820043100ab48211920043100aa48211a20043100a948211b20043100a748211c20043100b948211d20043100b748211e20043100b648211f20043100b348212020043100b448212120043100b5482122200420043502a04820043100a4484220868420043100a5484228868420043100a64822234230868442ffffffffffffff03833703e04820042020202142088684202242108684201f42188684201e42208684200c42288684201d4230868442018842ffffffffffffff03833703f84820042023201c42088684200b42108684201b42188684201a4220868420194228868420184230868442038842ffffffffffffff03833703e8482004200c201d42088684201742108684201642188684201542208684201442288684201342308684201242388684420c8842ffffffffffffff03833703804920042018201042088684201142108684200f42188684200a42208684200e42288684200d4230868420204238868442068842ffffffffffffff03833703f04820044188c9006a200441e0c8006a1071200441a8ca006a41186a20022903002220370300200441a8ca006a41106a2003290300220a370300200441a8ca006a41086a2005290300220b37030020042006290300220d3703a84a20043100ba4a210e20043100b94a210f20043100b74a211020043100b54a211120043100b64a211220043100c74a211320043100c64a211420043100c54a211520043100c44a211620043100c34a211720043100c24a211920043100b44a210c20043100b34a211a20043100b24a211b20043100b14a211c20043100af4a211e20043100c14a211820043100bf4a211f20043100be4a212120043100bb4a211d20043100bc4a212220043100bd4a21232004200d42ffffffff0f8320043100ac4a4220868420043100ad4a4228868420043100ae4a220d4230868442ffffffffffffff03833703c84a2004201d202242088684202342108684202142188684201f42208684202042ff018322204228868420184230868442018842ffffffffffffff03833703e04a2004200d201e42088684200b42ff018342108684201c42188684201b42208684201a42288684200c4230868442038842ffffffffffffff03833703d04a20042018420886202084201942108684201742188684201642208684201542288684201442308684201342388684420c8842ffffffffffffff03833703e84a2004200c201142088684201242108684201042188684200a42ff018342208684200f42288684200e42308684201d4238868442068842ffffffffffffff03833703d84a200441f0ca006a200441c8ca006a1071200441d0c6006a41106a2203200441f0ca006a41386a290300220b370300200441d0c6006a41086a2224200441f0ca006a41306a290300220d20042903f84a220e7c3703002003200b20042903804b220f7c370300200441d0c6006a41186a2208200441f0ca006a41c0006a290300221020042903884b22117c370300200441d0c6006a41206a2209200441f0ca006a41c8006a290300221220042903904b22137c370300200420042903984b221420042903f04a22157c3703d046200441a8ce006a41206a2202200441f0ca006a41f0006a290300370300200441a8ce006a41186a2205200441f0ca006a41e8006a290300370300200441a8ce006a41106a2206200441f0ca006a41e0006a290300370300200441a8ce006a41086a2207200441f0ca006a41d8006a290300370300200420042903c04b3703a84e200441d0c1006a20042903e84b220c420042d9e2cbb5c2f2a603420010e808200441a0c2006a200441f0ca006a4198016a29030022184200428ee0b9a98cbfbd1f420010e808200441f0c2006a200441f0ca006a4190016a290300221d420042968c8a82a4c39824420010e808200441c0c3006a200441f0ca006a4188016a2903002220420042d587a4ceaceea43d420010e80820044190c4006a200441f0ca006a4180016a290300220a420042edd39cadab84b215420010e808200441a0c4006a200a420042d9e2cbb5c2f2a603420010e808200441e0c1006a200c420042fabaabb1878ad401420010e808200441b0c2006a2018420042968c8a82a4c39824420010e80820044180c3006a201d420042d587a4ceaceea43d420010e808200441d0c3006a2020420042edd39cadab84b215420010e808200441e0c3006a2020420042d9e2cbb5c2f2a603420010e808200441b0c4006a200a420042fabaabb1878ad401420010e808200441f0c1006a200c420042d2808e80cce8f301420010e808200441c0c2006a2018420042d587a4ceaceea43d420010e80820044190c3006a201d420042edd39cadab84b215420010e808200441a0c3006a201d420042d9e2cbb5c2f2a603420010e808200441f0c3006a2020420042fabaabb1878ad401420010e808200441c0c4006a200a420042d2808e80cce8f301420010e80820044180c2006a200c420042f7f281baccf19c03420010e808200441d0c2006a2018420042edd39cadab84b215420010e808200441e0c2006a2018420042d9e2cbb5c2f2a603420010e808200441b0c3006a201d420042fabaabb1878ad401420010e80820044180c4006a2020420042d2808e80cce8f301420010e808200441d0c4006a200a420042f7f281baccf19c03420010e80820044190c2006a200c420042ffdb95eed98d9001420010e808200441d0c6006a41c8006a2225201220137d42f0ffffffffffff3f7c220c42ffffffffffffff0383201020117d42f0ffffffffffff3f7c22184233887c370300200441d0c6006a41c0006a2226201842ffffffffffffff0383200b200f7d42f0ffffffffffff3f7c22184233887c370300200441d0c6006a41386a2227201842ffffffffffffff0383200d200e7d42f0ffffffffffff3f7c22184233887c370300200441d0c6006a41306a2228201842ffffffffffffff0383201420157d42d0fdffffffffff3f7c22184233887c3703002004200c42338842137e201842ffffffffffffff03837c3703f846200441d0c6006a41f0006a22292002290300370300200441d0c6006a41e8006a222a2005290300370300200441d0c6006a41e0006a222b2006290300370300200441d0c6006a41d8006a222c2007290300370300200420042903a84e3703a047200441d0c6006a4188016a222d20042903c042221320042903f0417c220c2004290390437c221820042903e0437c221d20042903b0447c222020042903b042221420042903e0417c220a2004290380437c220b20042903d0437c220d20042903a0447c220e20042903a042221520042903d0417c220f20042903f0427c221020042903c0437c22112004290390447c2212423388200441a0c2006a41086a290300200441d0c1006a41086a2903007c200f201554ad7c200441f0c2006a41086a2903007c2010200f54ad7c200441c0c3006a41086a2903007c2011201054ad7c20044190c4006a41086a2903007c2012201154ad7c420d86847c220f423388200441b0c2006a41086a290300200441e0c1006a41086a2903007c200a201454ad7c20044180c3006a41086a2903007c200b200a54ad7c200441d0c3006a41086a2903007c200d200b54ad7c200441a0c4006a41086a2903007c200e200d54ad7c200f200e54ad7c420d86847c220a42ffffffffffffff0383370300200441d0c6006a4190016a222e20042903d04222112004290380427c220b20042903a0437c220d20042903f0437c220e20042903c0447c2210200a423388200441c0c2006a41086a290300200441f0c1006a41086a2903007c200c201354ad7c20044190c3006a41086a2903007c2018200c54ad7c200441e0c3006a41086a2903007c201d201854ad7c200441b0c4006a41086a2903007c2020201d54ad7c200a202054ad7c420d86847c220c42ffffffffffffff0383370300200441d0c6006a4198016a222f20042903e04222132004290390427c221820042903b0437c221d2004290380447c222020042903d0447c220a200c423388200441d0c2006a41086a29030020044180c2006a41086a2903007c200b201154ad7c200441a0c3006a41086a2903007c200d200b54ad7c200441f0c3006a41086a2903007c200e200d54ad7c200441c0c4006a41086a2903007c2010200e54ad7c200c201054ad7c420d86847c220c42ffffffffffffff0383370300200441d0c6006a4180016a2230200c423388200441e0c2006a41086a29030020044190c2006a41086a2903007c2018201354ad7c200441b0c3006a41086a2903007c201d201854ad7c20044180c4006a41086a2903007c2020201d54ad7c200441d0c4006a41086a2903007c200a202054ad7c200c200a54ad7c420d868442137e201242ffffffffffffff03837c220c423388200f42ffffffffffffff03837c3703002004200c42ffffffffffffff03833703c84720044190cc006a41206a223120044188c9006a41c8006a223229030037030020044190cc006a41186a223320044188c9006a41c0006a2234290300222037030020044190cc006a41106a223520044188c9006a41386a2236290300221d37030020044190cc006a41086a223720044188c9006a41306a22382903002218370300200420042903b049220c3703904c2004200c2004290388497c220c3703904c203720182004290390497c22183703002035201d2004290398497c221d3703002033202020042903a0497c22203703002031203129030020042903a8497c220a370300200441c03e6a20042903d046220b4200200c420010e808200441c0c1006a200a42002024290300220d42137e420010e808200441f0c0006a202042002003290300220e42137e2212420010e808200441a0c0006a201d42002008290300221042137e2211420010e808200441d03f6a201842002009290300221342137e220f420010e808200441d03e6a20184200200b420010e808200441b0c1006a200c4200200d420010e808200441e0c0006a200a42002012420010e80820044190c0006a202042002011420010e808200441c03f6a201d4200200f420010e808200441e03e6a201d4200200b420010e808200441a0c1006a20184200200d420010e808200441d0c0006a200c4200200e420010e80820044180c0006a200a42002011420010e808200441b03f6a20204200200f420010e808200441f03e6a20204200200b420010e80820044190c1006a201d4200200d420010e808200441c0c0006a20184200200e420010e808200441f03f6a200c42002010420010e808200441a03f6a200a4200200f420010e808200441803f6a200a4200200b420010e80820044180c1006a20204200200d420010e808200441b0c0006a201d4200200e420010e808200441e03f6a201842002010420010e808200441903f6a200c42002013420010e8082038290300210b2036290300210a2034290300211d200429039049210d200429039849210e20042903a0492120200441f03b6a20042903f846220c4200203229030020042903a8497d42f0ffffffffffff3f7c220f42338842137e20042903b0492004290388497d42d0fdffffffffff3f7c221242ffffffffffffff03837c2218420010e808200441f03d6a200f42ffffffffffffff0383201d20207d42f0ffffffffffff3f7c220f4233887c221d42002028290300222042137e420010e808200441b03d6a200f42ffffffffffffff0383200a200e7d42f0ffffffffffff3f7c220f4233887c220a42002027290300220e42137e2213420010e808200441f03c6a200f42ffffffffffffff0383200b200d7d42f0ffffffffffff3f7c220d4233887c220b42002026290300221042137e2211420010e808200441b03c6a200d42ffffffffffffff038320124233887c220d42002025290300221242137e220f420010e808200441e03b6a200d4200200c420010e808200441b03e6a201842002020420010e808200441a03d6a201d42002013420010e808200441e03c6a200a42002011420010e808200441a03c6a200b4200200f420010e808200441d03b6a200b4200200c420010e808200441a03e6a200d42002020420010e808200441e03d6a20184200200e420010e808200441d03c6a201d42002011420010e808200441903c6a200a4200200f420010e808200441c03b6a200a4200200c420010e808200441903e6a200b42002020420010e808200441d03d6a200d4200200e420010e808200441903d6a201842002010420010e808200441803c6a201d4200200f420010e808200441b03b6a201d4200200c420010e808200441803e6a200a42002020420010e808200441c03d6a200b4200200e420010e808200441803d6a200d42002010420010e808200441c03c6a201842002012420010e808200420042903d03c221320042903e03d7c220c20042903903c7c221820042903d03b7c221d20042903a03e7c222020042903a03d221420042903b03e7c220a20042903e03c7c220b20042903a03c7c220d20042903e03b7c220e20042903f03d221520042903f03b7c220f20042903b03d7c221020042903f03c7c221120042903b03c7c2212423388200441f03d6a41086a290300200441f03b6a41086a2903007c200f201554ad7c200441b03d6a41086a2903007c2010200f54ad7c200441f03c6a41086a2903007c2011201054ad7c200441b03c6a41086a2903007c2012201154ad7c420d86847c220f423388200441a03d6a41086a290300200441b03e6a41086a2903007c200a201454ad7c200441e03c6a41086a2903007c200b200a54ad7c200441a03c6a41086a2903007c200d200b54ad7c200441e03b6a41086a2903007c200e200d54ad7c200f200e54ad7c420d86847c220a42ffffffffffffff03833703c84c200420042903803c221120042903903d7c220b20042903c03b7c220d20042903903e7c220e20042903d03d7c2210200a423388200441d03c6a41086a290300200441e03d6a41086a2903007c200c201354ad7c200441903c6a41086a2903007c2018200c54ad7c200441d03b6a41086a2903007c201d201854ad7c200441a03e6a41086a2903007c2020201d54ad7c200a202054ad7c420d86847c220c42ffffffffffffff03833703d04c200420042903b03b221320042903c03c7c221820042903803e7c221d20042903c03d7c222020042903803d7c220a200c423388200441803c6a41086a290300200441903d6a41086a2903007c200b201154ad7c200441c03b6a41086a2903007c200d200b54ad7c200441903e6a41086a2903007c200e200d54ad7c200441d03d6a41086a2903007c2010200e54ad7c200c201054ad7c420d86847c220c42ffffffffffffff03833703d84c2004200c423388200441b03b6a41086a290300200441c03c6a41086a2903007c2018201354ad7c200441803e6a41086a2903007c201d201854ad7c200441c03d6a41086a2903007c2020201d54ad7c200441803d6a41086a2903007c200a202054ad7c200c200a54ad7c420d868442137e201242ffffffffffffff03837c220c42ffffffffffffff03833703b84c2004200c423388200f42ffffffffffffff03837c3703c04c200441e03a6a20042903c847220c420020042903804a2218420010e808200441d03a6a20044188c9006a4198016a290300221d42002030290300222042137e420010e808200441803a6a20044188c9006a4190016a290300220a4200202d290300220e42137e2212420010e808200441b0396a20044188c9006a4188016a290300220b4200202e290300221042137e2211420010e808200441e0386a20044188c9006a4180016a290300220d4200202f290300221342137e220f420010e808200441d0386a200d4200200c420010e808200441a03b6a201842002020420010e808200441c03a6a201d42002012420010e808200441f0396a200a42002011420010e808200441a0396a200b4200200f420010e80820044190396a200b4200200c420010e808200441c0386a200d42002020420010e808200441903b6a20184200200e420010e808200441b03a6a201d42002011420010e808200441e0396a200a4200200f420010e808200441d0396a200a4200200c420010e80820044180396a200b42002020420010e808200441b0386a200d4200200e420010e808200441803b6a201842002010420010e808200441a03a6a201d4200200f420010e808200441903a6a201d4200200c420010e808200441c0396a200a42002020420010e808200441f0386a200b4200200e420010e808200441a0386a200d42002010420010e808200441f03a6a201842002013420010e808200420042903903a221c20042903f03a7c220c20042903c0397c221820042903f0387c221d20042903a0387c222020042903a03a221e20042903803b7c220a20042903d0397c220b2004290380397c220d20042903b0387c220e20042903b03a221f20042903903b7c220f20042903e0397c22102004290390397c221120042903c0387c221220042903c03a222120042903a03b7c221320042903f0397c221420042903a0397c221520042903d0387c221620042903d03a222220042903e03a7c221720042903803a7c221920042903b0397c221a20042903e0387c221b423388200441d03a6a41086a290300200441e03a6a41086a2903007c2017202254ad7c200441803a6a41086a2903007c2019201754ad7c200441b0396a41086a2903007c201a201954ad7c200441e0386a41086a2903007c201b201a54ad7c420d86847c2217423388200441c03a6a41086a290300200441a03b6a41086a2903007c2013202154ad7c200441f0396a41086a2903007c2014201354ad7c200441a0396a41086a2903007c2015201454ad7c200441d0386a41086a2903007c2016201554ad7c2017201654ad7c420d86847c2213423388200441b03a6a41086a290300200441903b6a41086a2903007c200f201f54ad7c200441e0396a41086a2903007c2010200f54ad7c20044190396a41086a2903007c2011201054ad7c200441c0386a41086a2903007c2012201154ad7c2013201254ad7c420d86847c220f423388200441a03a6a41086a290300200441803b6a41086a2903007c200a201e54ad7c200441d0396a41086a2903007c200b200a54ad7c20044180396a41086a2903007c200d200b54ad7c200441b0386a41086a2903007c200e200d54ad7c200f200e54ad7c420d86847c220a42ffffffffffffff03833703804d2004200f42ffffffffffffff03833703f84c2004201342ffffffffffffff03833703f04c2004200a423388200441903a6a41086a290300200441f03a6a41086a2903007c200c201c54ad7c200441c0396a41086a2903007c2018200c54ad7c200441f0386a41086a2903007c201d201854ad7c200441a0386a41086a2903007c2020201d54ad7c200a202054ad7c420d868442137e201b42ffffffffffffff03837c220c423388201742ffffffffffffff03837c3703e84c2004200c42ffffffffffffff03833703e04c20044190356a20042903a047220c420020042903d8492218420010e808200441a0366a20044188c9006a41f0006a290300221d4200202c290300222042137e420010e808200441e0366a20044188c9006a41e8006a290300220a4200202b290300220e42137e2212420010e808200441a0376a20044188c9006a41e0006a290300220b4200202a290300221042137e2211420010e808200441e0376a20044188c9006a41d8006a290300220d42002029290300221342137e220f420010e808200441e0356a200d4200200c420010e808200441a0356a201842002020420010e808200441b0366a201d42002012420010e808200441f0366a200a42002011420010e808200441b0376a200b4200200f420010e808200441f0356a200b4200200c420010e808200441f0376a200d42002020420010e808200441b0356a20184200200e420010e808200441c0366a201d42002011420010e80820044180376a200a4200200f420010e80820044180366a200a4200200c420010e808200441c0376a200b42002020420010e80820044180386a200d4200200e420010e808200441c0356a201842002010420010e808200441d0366a201d4200200f420010e80820044190366a201d4200200c420010e80820044190376a200a42002020420010e808200441d0376a200b4200200e420010e80820044190386a200d42002010420010e808200441d0356a201842002013420010e8082004200429039036221c20042903d0357c220c2004290390377c221820042903d0377c221d2004290390387c222020042903d036221e20042903c0357c220a2004290380367c220b20042903c0377c220d2004290380387c220e20042903c036221f20042903b0357c220f2004290380377c221020042903f0357c221120042903f0377c221220042903b036222120042903a0357c221320042903f0367c221420042903b0377c221520042903e0357c221620042903a03622222004290390357c221720042903e0367c221920042903a0377c221a20042903e0377c221b423388200441a0366a41086a29030020044190356a41086a2903007c2017202254ad7c200441e0366a41086a2903007c2019201754ad7c200441a0376a41086a2903007c201a201954ad7c200441e0376a41086a2903007c201b201a54ad7c420d86847c2217423388200441b0366a41086a290300200441a0356a41086a2903007c2013202154ad7c200441f0366a41086a2903007c2014201354ad7c200441b0376a41086a2903007c2015201454ad7c200441e0356a41086a2903007c2016201554ad7c2017201654ad7c420d86847c2213423388200441c0366a41086a290300200441b0356a41086a2903007c200f201f54ad7c20044180376a41086a2903007c2010200f54ad7c200441f0356a41086a2903007c2011201054ad7c200441f0376a41086a2903007c2012201154ad7c2013201254ad7c420d86847c220f423388200441d0366a41086a290300200441c0356a41086a2903007c200a201e54ad7c20044180366a41086a2903007c200b200a54ad7c200441c0376a41086a2903007c200d200b54ad7c20044180386a41086a2903007c200e200d54ad7c200f200e54ad7c420d86847c220a42338820044190366a41086a290300200441d0356a41086a2903007c200c201c54ad7c20044190376a41086a2903007c2018200c54ad7c200441d0376a41086a2903007c201d201854ad7c20044190386a41086a2903007c2020201d54ad7c200a202054ad7c420d868442137e201b42ffffffffffffff03837c221842ffffffffffffff0383220c3703884d20042018423388201742ffffffffffffff03837c22183703904d2004200a42ffffffffffffff0383221d3703a84d2004200f42ffffffffffffff038322203703a04d2004201342ffffffffffffff0383220a3703984d200441b0cd006a41086a2231201820187c370300200441b0cd006a41106a2224200a200a7c370300200441b0cd006a41186a2225202020207c370300200441b0cd006a41206a2226201d201d7c3703002004200c200c7c3703b04d20042903c04c211c20042903c84c211e20042903d04c211f20042903d84c212120042903b84c2122200420042903803f222320042903903f7c220c2004290380417c221820042903b0407c221d20042903e03f7c222020042903a03f223920042903f03f7c220a20042903f03e7c220b2004290390417c220d20042903c0407c220e200429038040223a20042903d0407c220f20042903b03f7c221020042903e03e7c221120042903a0417c221220042903e040223b20042903b0417c22132004290390407c221420042903c03f7c221520042903d03e7c221620042903c041223c20042903c03e7c221720042903f0407c221920042903a0407c221a20042903d03f7c221b423388200441c0c1006a41086a290300200441c03e6a41086a2903007c2017203c54ad7c200441f0c0006a41086a2903007c2019201754ad7c200441a0c0006a41086a2903007c201a201954ad7c200441d03f6a41086a2903007c201b201a54ad7c420d86847c2217423388200441e0c0006a41086a290300200441b0c1006a41086a2903007c2013203b54ad7c20044190c0006a41086a2903007c2014201354ad7c200441c03f6a41086a2903007c2015201454ad7c200441d03e6a41086a2903007c2016201554ad7c2017201654ad7c420d86847c221342338820044180c0006a41086a290300200441d0c0006a41086a2903007c200f203a54ad7c200441b03f6a41086a2903007c2010200f54ad7c200441e03e6a41086a2903007c2011201054ad7c200441a0c1006a41086a2903007c2012201154ad7c2013201254ad7c420d86847c220f423388200441a03f6a41086a290300200441f03f6a41086a2903007c200a203954ad7c200441f03e6a41086a2903007c200b200a54ad7c20044190c1006a41086a2903007c200d200b54ad7c200441c0c0006a41086a2903007c200e200d54ad7c200f200e54ad7c420d86847c220a423388200441803f6a41086a290300200441903f6a41086a2903007c200c202354ad7c20044180c1006a41086a2903007c2018200c54ad7c200441b0c0006a41086a2903007c201d201854ad7c200441e03f6a41086a2903007c2020201d54ad7c200a202054ad7c420d868442137e201b42ffffffffffffff03837c220c423388201742ffffffffffffff03837c220e3703884e2004200c42ffffffffffffff0383220b3703804e2004200a42ffffffffffffff0383220a3703a04e2004200f42ffffffffffffff0383220d3703984e2004201342ffffffffffffff0383220f3703904e2004200b20042903b84c7c3703804e2004200e20042903c04c7c3703884e2004200f20042903c84c7c3703904e2004200d20042903d04c7c3703984e2004200a20042903d84c7c3703a04e2002202629030037030020052025290300222037030020062024290300221d370300200720312903002218370300200420042903b04d220c3703a84e2004200c20042903e04c7c220c3703a84e2007201820042903e84c7c22183703002006201d20042903f04c7c221d3703002005202020042903f84c7c22123703002002200229030020042903804d7c2215370300200441f0276a202629030020042903804d7d42f0ffffffffffff3f7c221042338842137e20042903b04d20042903e04c7d42d0fdffffffffff3f7c221142ffffffffffffff03837c22204200200a20217d42f0ffffffffffff3f7c221342338842137e200b20227d42d0fdffffffffff3f7c221442ffffffffffffff03837c220a420010e80820044180356a201342ffffffffffffff0383200d201f7d42f0ffffffffffff3f7c220d4233887c220b4200203129030020042903e84c7d42f0ffffffffffff3f7c221642ffffffffffffff038320114233887c221342137e2223420010e80820044180346a200d42ffffffffffffff0383200f201e7d42f0ffffffffffff3f7c220f4233887c220d4200202429030020042903f04c7d42f0ffffffffffff3f7c221142ffffffffffffff038320164233887c221942137e221e420010e80820044180336a200f42ffffffffffffff0383200e201c7d42f0ffffffffffff3f7c220f4233887c220e4200202529030020042903f84c7d42f0ffffffffffff3f7c221642ffffffffffffff038320114233887c221c42137e221b420010e808200441d0266a200f42ffffffffffffff038320144233887c220f4200201042ffffffffffffff038320164233887c222142137e2216420010e808200441c0266a200f42002020420010e808200441e0276a200a42002013420010e808200441f0336a200b4200201e420010e808200441f0326a200d4200201b420010e80820044180326a200e42002016420010e80820044180316a200e42002020420010e808200441b0266a200f42002013420010e808200441d0276a200a42002019420010e808200441e0326a200b4200201b420010e808200441f0316a200d42002016420010e808200441f0306a200d42002020420010e808200441e0346a200e42002013420010e80820044180256a200f42002019420010e808200441c0276a200a4200201c420010e808200441e0316a200b42002016420010e808200441e0306a200b42002020420010e808200441d0346a200d42002013420010e808200441c0336a200e42002019420010e808200441d0236a200f4200201c420010e808200441b0276a200a42002021420010e808200441902b6a200c420020042903804e2210420010e808200441802d6a20042903a04e221a4200201842137e420010e808200441802e6a20042903984e22174200201d42137e2239420010e808200441802f6a20042903904e22144200201242137e2222420010e80820044180306a20042903884e22114200201542137e221f420010e808200441f02f6a20114200200c420010e808200441a02b6a201042002018420010e808200441f02c6a201a42002039420010e808200441f02d6a201742002022420010e808200441f02e6a20144200201f420010e808200441e02e6a20144200200c420010e808200441e02f6a201142002018420010e808200441b02b6a20104200201d420010e808200441e02c6a201a42002022420010e808200441e02d6a20174200201f420010e808200441d02d6a20174200200c420010e808200441d02e6a201442002018420010e808200441d02f6a20114200201d420010e808200441c02b6a201042002012420010e808200441d02c6a201a4200201f420010e808200441c02c6a201a4200200c420010e808200441c02d6a201742002018420010e808200441c02e6a20144200201d420010e808200441c02f6a201142002012420010e808200441d02b6a201042002015420010e808200441d0306a20204200200c420010e808200441f0346a201542002023420010e808200441e0336a20124200201e420010e808200441d0326a201d4200201b420010e808200441d0316a201842002016420010e808200441c0306a201842002020420010e808200441c0346a200c42002013420010e808200441d0336a20154200201e420010e808200441c0326a20124200201b420010e808200441c0316a201d42002016420010e808200441b0306a201d42002020420010e808200441b0346a201842002013420010e808200441b0336a200c42002019420010e808200441b0326a20154200201b420010e808200441b0316a201242002016420010e808200441a0306a201242002020420010e808200441a0346a201d42002013420010e808200441a0336a201842002019420010e808200441a0326a200c4200201c420010e808200441a0316a201542002016420010e80820044190306a201542002020420010e80820044190346a201242002013420010e80820044190336a201d42002019420010e80820044190326a20184200201c420010e80820044190316a200c42002021420010e808200441a0276a20104200200a420010e808200441902f6a200b4200201142137e420010e808200441a02e6a200d4200201442137e221d420010e808200441b02d6a200e4200201742137e2218420010e80820044190106a200f4200201a42137e220c420010e80820044180106a200f42002010420010e80820044190276a200a42002011420010e808200441902e6a200b4200201d420010e808200441a02d6a200d42002018420010e808200441b02c6a200e4200200c420010e808200441e02b6a200e42002010420010e808200441f00f6a200f42002011420010e80820044180276a200a42002014420010e808200441902d6a200b42002018420010e808200441a02c6a200d4200200c420010e808200441f02b6a200d42002010420010e808200441b02f6a200e42002011420010e808200441900f6a200f42002014420010e808200441f0266a200a42002017420010e808200441902c6a200b4200200c420010e808200441802c6a200b42002010420010e808200441a02f6a200d42002011420010e808200441b02e6a200e42002014420010e808200441b00e6a200f42002017420010e808200441e0266a200a4200201a420010e808200420042903e02c221320042903b02b7c220c20042903e02d7c221820042903e02e7c221d20042903e02f7c222020042903f02c221420042903a02b7c220a20042903f02d7c220b20042903f02e7c220d20042903f02f7c220e20042903802d221520042903902b7c220f20042903802e7c221020042903802f7c22112004290380307c2212423388200441802d6a41086a290300200441902b6a41086a2903007c200f201554ad7c200441802e6a41086a2903007c2010200f54ad7c200441802f6a41086a2903007c2011201054ad7c20044180306a41086a2903007c2012201154ad7c420d86847c220f423388200441f02c6a41086a290300200441a02b6a41086a2903007c200a201454ad7c200441f02d6a41086a2903007c200b200a54ad7c200441f02e6a41086a2903007c200d200b54ad7c200441f02f6a41086a2903007c200e200d54ad7c200f200e54ad7c420d86847c220a42ffffffffffffff038322173703c04d200420042903d02c221120042903c02b7c220b20042903d02d7c220d20042903d02e7c220e20042903d02f7c2210200a423388200441e02c6a41086a290300200441b02b6a41086a2903007c200c201354ad7c200441e02d6a41086a2903007c2018200c54ad7c200441e02e6a41086a2903007c201d201854ad7c200441e02f6a41086a2903007c2020201d54ad7c200a202054ad7c420d86847c220c42ffffffffffffff038322213703c84d200420042903c02c221320042903d02b7c221820042903c02d7c221d20042903c02e7c222020042903c02f7c220a200c423388200441d02c6a41086a290300200441c02b6a41086a2903007c200b201154ad7c200441d02d6a41086a2903007c200d200b54ad7c200441d02e6a41086a2903007c200e200d54ad7c200441d02f6a41086a2903007c2010200e54ad7c200c201054ad7c420d86847c220c42ffffffffffffff038322233703d04d2004200c423388200441c02c6a41086a290300200441d02b6a41086a2903007c2018201354ad7c200441c02d6a41086a2903007c201d201854ad7c200441c02e6a41086a2903007c2020201d54ad7c200441c02f6a41086a2903007c200a202054ad7c200c200a54ad7c420d868442137e201242ffffffffffffff03837c220c42ffffffffffffff038322143703b04d2004200c423388200f42ffffffffffffff03837c22153703b84d20044180286a20042903903022222004290390317c220c2004290390347c22182004290390337c221d2004290390327c222020042903a031223920042903a0327c220a20042903a0307c220b20042903a0347c220d20042903a0337c220e20042903b032223a20042903b0337c220f20042903b0317c221020042903b0307c221120042903b0347c221220042903d033223b20042903c0347c221320042903c0327c221620042903c0317c221920042903c0307c221a20042903f034223c20042903d0307c221b20042903e0337c221c20042903d0327c221e20042903d0317c221f423388200441f0346a41086a290300200441d0306a41086a2903007c201b203c54ad7c200441e0336a41086a2903007c201c201b54ad7c200441d0326a41086a2903007c201e201c54ad7c200441d0316a41086a2903007c201f201e54ad7c420d86847c221b423388200441d0336a41086a290300200441c0346a41086a2903007c2013203b54ad7c200441c0326a41086a2903007c2016201354ad7c200441c0316a41086a2903007c2019201654ad7c200441c0306a41086a2903007c201a201954ad7c201b201a54ad7c420d86847c2213423388200441b0326a41086a290300200441b0336a41086a2903007c200f203a54ad7c200441b0316a41086a2903007c2010200f54ad7c200441b0306a41086a2903007c2011201054ad7c200441b0346a41086a2903007c2012201154ad7c2013201254ad7c420d86847c220f423388200441a0316a41086a290300200441a0326a41086a2903007c200a203954ad7c200441a0306a41086a2903007c200b200a54ad7c200441a0346a41086a2903007c200d200b54ad7c200441a0336a41086a2903007c200e200d54ad7c200f200e54ad7c420d86847c220a42ffffffffffffff0383223d42f0ffffffffffff3f7c223e20237d221242338842137e200a42338820044190306a41086a29030020044190316a41086a2903007c200c202254ad7c20044190346a41086a2903007c2018200c54ad7c20044190336a41086a2903007c201d201854ad7c20044190326a41086a2903007c2020201d54ad7c200a202054ad7c420d868442137e201f42ffffffffffffff03837c222042ffffffffffffff0383223f42d0fdffffffffff3f7c224020147d220a42ffffffffffffff03837c220c4200203f20147c2218420010e808200441c0296a203d20237c221d42002020423388201b42ffffffffffffff03837c224142f0ffffffffffff3f7c224220157d220b42ffffffffffffff0383200a4233887c222042137e420010e808200441a02a6a200f42ffffffffffffff0383224320217c220a4200201342ffffffffffffff0383224442f0ffffffffffff3f7c224520177d220d42ffffffffffffff0383200b4233887c220e42137e2213420010e808200441b02a6a204420177c220b4200204342f0ffffffffffff3f7c224620217d220f42ffffffffffffff0383200d4233887c221042137e2211420010e808200441d0296a204120157c220d4200201242ffffffffffffff0383200f4233887c221242137e220f420010e80820044180296a200d4200200c420010e80820044190286a201842002020420010e808200441902a6a201d42002013420010e808200441e02a6a200a42002011420010e808200441c02a6a200b4200200f420010e808200441f0286a200b4200200c420010e808200441b0296a200d42002020420010e808200441a0286a20184200200e420010e808200441d02a6a201d42002011420010e808200441f02a6a200a4200200f420010e808200441e0286a200a4200200c420010e808200441a0296a200b42002020420010e808200441e0296a200d4200200e420010e808200441b0286a201842002010420010e808200441802b6a201d4200200f420010e808200441d0286a201d4200200c420010e80820044190296a200a42002020420010e808200441802a6a200b4200200e420010e808200441f0296a200d42002010420010e808200441c0286a201842002012420010e80820044180216a2014420020042903e030222220042903b0277c220c20042903d0347c221820042903c0337c221d20042903d0237c222020042903e031223920042903c0277c220a20042903f0307c220b20042903e0347c220d2004290380257c220e20042903e032223a20042903d0277c220f20042903f0317c22102004290380317c221120042903b0267c221220042903f033223b20042903e0277c221320042903f0327c22162004290380327c221920042903c0267c221a200429038035223c20042903f0277c221b2004290380347c221c2004290380337c221e20042903d0267c221f42338820044180356a41086a290300200441f0276a41086a2903007c201b203c54ad7c20044180346a41086a2903007c201c201b54ad7c20044180336a41086a2903007c201e201c54ad7c200441d0266a41086a2903007c201f201e54ad7c420d86847c221b423388200441f0336a41086a290300200441e0276a41086a2903007c2013203b54ad7c200441f0326a41086a2903007c2016201354ad7c20044180326a41086a2903007c2019201654ad7c200441c0266a41086a2903007c201a201954ad7c201b201a54ad7c420d86847c2213423388200441e0326a41086a290300200441d0276a41086a2903007c200f203a54ad7c200441f0316a41086a2903007c2010200f54ad7c20044180316a41086a2903007c2011201054ad7c200441b0266a41086a2903007c2012201154ad7c2013201254ad7c420d86847c220f423388200441e0316a41086a290300200441c0276a41086a2903007c200a203954ad7c200441f0306a41086a2903007c200b200a54ad7c200441e0346a41086a2903007c200d200b54ad7c20044180256a41086a2903007c200e200d54ad7c200f200e54ad7c420d86847c220a423388200441e0306a41086a290300200441b0276a41086a2903007c200c202254ad7c200441d0346a41086a2903007c2018200c54ad7c200441c0336a41086a2903007c201d201854ad7c200441d0236a41086a2903007c2020201d54ad7c200a202054ad7c420d868442137e201f42ffffffffffffff03837c220c42ffffffffffffff03832218420010e808200441b0226a200a42ffffffffffffff0383221d4200201542137e420010e808200441e0236a200f42ffffffffffffff038322204200201742137e220e420010e80820044190256a201342ffffffffffffff0383220a4200202142137e220d420010e808200441a0226a200c423388201b42ffffffffffffff03837c220b4200202342137e220c420010e80820044190226a200b42002014420010e808200441f0206a201842002015420010e808200441c0226a201d4200200e420010e808200441f0236a20204200200d420010e808200441a0256a200a4200200c420010e808200441b0256a200a42002014420010e80820044180226a200b42002015420010e808200441e0206a201842002017420010e808200441d0226a201d4200200d420010e80820044180246a20204200200c420010e80820044190246a202042002014420010e808200441c0256a200a42002015420010e808200441f0216a200b42002017420010e808200441d0206a201842002021420010e808200441e0226a201d4200200c420010e808200441f0226a201d42002014420010e808200441a0246a202042002015420010e808200441d0256a200a42002017420010e808200441e0216a200b42002021420010e808200441c0206a201842002023420010e808200420042903d022221c20042903e0207c220c2004290380247c220d20042903b0257c220e2004290380227c220f20042903c022221e20042903f0207c221020042903f0237c221120042903a0257c22122004290390227c221320042903b022221f2004290380217c221620042903e0237c22192004290390257c221a20042903a0227c221b423388200441b0226a41086a29030020044180216a41086a2903007c2016201f54ad7c200441e0236a41086a2903007c2019201654ad7c20044190256a41086a2903007c201a201954ad7c200441a0226a41086a2903007c201b201a54ad7c420d86847c2216423388200441c0226a41086a290300200441f0206a41086a2903007c2010201e54ad7c200441f0236a41086a2903007c2011201054ad7c200441a0256a41086a2903007c2012201154ad7c20044190226a41086a2903007c2013201254ad7c2016201354ad7c420d86847c221042ffffffffffffff03833703904e200420042903e022221a20042903d0207c22112004290390247c221220042903c0257c221320042903f0217c22192010423388200441d0226a41086a290300200441e0206a41086a2903007c200c201c54ad7c20044180246a41086a2903007c200d200c54ad7c200441b0256a41086a2903007c200e200d54ad7c20044180226a41086a2903007c200f200e54ad7c2010200f54ad7c420d86847c220c42ffffffffffffff03833703984e200420042903f022221c20042903c0207c220d20042903a0247c220e20042903d0257c220f20042903e0217c2210200c423388200441e0226a41086a290300200441d0206a41086a2903007c2011201a54ad7c20044190246a41086a2903007c2012201154ad7c200441c0256a41086a2903007c2013201254ad7c200441f0216a41086a2903007c2019201354ad7c200c201954ad7c420d86847c220c42ffffffffffffff03833703a04e2004200c423388200441f0226a41086a290300200441c0206a41086a2903007c200d201c54ad7c200441a0246a41086a2903007c200e200d54ad7c200441d0256a41086a2903007c200f200e54ad7c200441e0216a41086a2903007c2010200f54ad7c200c201054ad7c420d868442137e201b42ffffffffffffff03837c220c42ffffffffffffff03833703804e2004200c423388201642ffffffffffffff03837c3703884e20044190286a41086a2903002147200441902a6a41086a2903002148200429039028213b20042903902a210c200441e02a6a41086a290300214920042903e02a213c200441c02a6a41086a290300214a20042903c02a214b20044180296a41086a290300214c200429038029214d20044180286a41086a290300214e200441c0296a41086a290300214f200429038028215020042903c029210d200441a02a6a41086a290300215120042903a02a2152200441b02a6a41086a290300215320042903b02a2154200441d0296a41086a290300215520042903d029215620042903d02a210f20042903a028211f20042903f02a212220042903f028213920042903b029213a200441d02a6a41086a2903002157200441a0286a41086a2903002158200441f02a6a41086a2903002159200441f0286a41086a290300215a200441b0296a41086a290300215b20042903802b211020042903b028211a20042903e028211b20042903a029211c20042903e029211e200441802b6a41086a290300215c200441b0286a41086a290300215d200441e0286a41086a290300215e200441a0296a41086a290300215f200441e0296a41086a290300216020042903c028211220042903d0282111200429039029211320042903802a211620042903f0292119200441c0286a41086a2903002161200441d0286a41086a290300216220044190296a41086a2903002163200441802a6a41086a2903002164200441f0296a41086a290300216520044188c9006a20044180ce006a4101106e200441e01c6a200429038849220e4200201920162013201120127c22127c22137c22167c2219201e201c201b2010201a7c221a7c221b7c221c7c221e203a20392022200f201f7c221f7c22227c22397c223a204d204b203c200c203b7c223b7c223c7c224b7c224d205620542052200d20507c22507c22527c22547c2256423388205520532051204f204e7c2050200d54ad7c7c2052205054ad7c7c2054205254ad7c7c2056205454ad7c420d86847c220d423388204c204a2049204820477c203b200c54ad7c7c203c203b54ad7c7c204b203c54ad7c7c204d204b54ad7c200d204d54ad7c420d86847c223b423388205b205a2059205720587c201f200f54ad7c7c2022201f54ad7c7c2039202254ad7c7c203a203954ad7c203b203a54ad7c420d86847c221f4233882060205f205e205c205d7c201a201054ad7c7c201b201a54ad7c7c201c201b54ad7c7c201e201c54ad7c201f201e54ad7c420d86847c220f423388206520642063206220617c2012201154ad7c7c2013201254ad7c7c2016201354ad7c7c2019201654ad7c200f201954ad7c420d868442137e205642ffffffffffffff03837c221142ffffffffffffff0383220c420010e808200441e01f6a200f42ffffffffffffff038322194200200429039049220f42137e420010e808200441901f6a201f42ffffffffffffff038322164200200429039849221042137e221b420010e808200441c01e6a203b42ffffffffffffff03832213420020042903a049221242137e221a420010e808200441f01d6a2011423388200d42ffffffffffffff03837c220d420020042903a849221c42137e2211420010e808200441f01c6a200d4200200e420010e808200441d01f6a200c4200200f420010e808200441801f6a20194200201b420010e808200441b01e6a20164200201a420010e808200441e01d6a201342002011420010e808200441801d6a20134200200e420010e808200441c01f6a200d4200200f420010e808200441f01e6a200c42002010420010e808200441a01e6a20194200201a420010e808200441d01d6a201642002011420010e808200441901d6a20164200200e420010e808200441b01f6a20134200200f420010e808200441e01e6a200d42002010420010e808200441901e6a200c42002012420010e808200441c01d6a201942002011420010e808200441a01d6a20194200200e420010e808200441a01f6a20164200200f420010e808200441d01e6a201342002010420010e808200441801e6a200d42002012420010e808200441b01d6a200c4200201c420010e808200420042903a01e223a20042903f01e7c220e20042903d01d7c220f20042903801d7c221020042903c01f7c221120042903801f223b20042903d01f7c221220042903b01e7c221a20042903e01d7c221b20042903f01c7c221c20042903e01f223c20042903e01c7c221e20042903901f7c221f20042903c01e7c222220042903f01d7c2239423388200441e01f6a41086a290300200441e01c6a41086a2903007c201e203c54ad7c200441901f6a41086a2903007c201f201e54ad7c200441c01e6a41086a2903007c2022201f54ad7c200441f01d6a41086a2903007c2039202254ad7c420d86847c221e423388200441801f6a41086a290300200441d01f6a41086a2903007c2012203b54ad7c200441b01e6a41086a2903007c201a201254ad7c200441e01d6a41086a2903007c201b201a54ad7c200441f01c6a41086a2903007c201c201b54ad7c201e201c54ad7c420d86847c221242ffffffffffffff03833703b84e200420042903c01d222220042903901e7c221a20042903901d7c221b20042903b01f7c221c20042903e01e7c221f2012423388200441a01e6a41086a290300200441f01e6a41086a2903007c200e203a54ad7c200441d01d6a41086a2903007c200f200e54ad7c200441801d6a41086a2903007c2010200f54ad7c200441c01f6a41086a2903007c2011201054ad7c2012201154ad7c420d86847c220e42ffffffffffffff03833703c04e200420042903a01d223a20042903b01d7c220f20042903a01f7c221020042903d01e7c221120042903801e7c2212200e423388200441c01d6a41086a290300200441901e6a41086a2903007c201a202254ad7c200441901d6a41086a2903007c201b201a54ad7c200441b01f6a41086a2903007c201c201b54ad7c200441e01e6a41086a2903007c201f201c54ad7c200e201f54ad7c420d86847c220e42ffffffffffffff03833703c84e2004200e423388200441a01d6a41086a290300200441b01d6a41086a2903007c200f203a54ad7c200441a01f6a41086a2903007c2010200f54ad7c200441d01e6a41086a2903007c2011201054ad7c200441801e6a41086a2903007c2012201154ad7c200e201254ad7c420d868442137e203942ffffffffffffff03837c220e42ffffffffffffff03833703a84e2004200e423388201e42ffffffffffffff03837c3703b04e200441f0ca006a41106a4200370300200441f0ca006a41186a4200370300200441f0ca006a41206a4200370300200442003703f84a200442013703f04a200441d0c6006a200441f0ca006a200441a8ce006a106f200441c0146a200c420020042903d846220e420010e808200441e0156a200441d0c6006a41286a290300220f4200200d42137e420010e80820044180176a200929030022104200201342137e221c420010e808200441a0186a200829030022114200201642137e221b420010e808200441c0196a200329030022124200201942137e221a420010e808200441b0196a20124200200c420010e808200441b0146a200e4200200d420010e808200441d0156a200f4200201c420010e808200441f0166a20104200201b420010e80820044190186a20114200201a420010e80820044180186a20114200200c420010e808200441a0196a20124200200d420010e808200441a0146a200e42002013420010e808200441c0156a200f4200201b420010e808200441e0166a20104200201a420010e808200441d0166a20104200200c420010e808200441f0176a20114200200d420010e80820044190196a201242002013420010e808200441c0136a200e42002016420010e808200441b0156a200f4200201a420010e808200441a0156a200f4200200c420010e808200441c0166a20104200200d420010e808200441e0176a201142002013420010e80820044180196a201242002016420010e808200441e0126a200e42002019420010e80820044180126a20042903804e220c4200200e420010e80820044190156a200f420020042903884e220d42137e420010e808200441b0166a2010420020042903904e221342137e221b420010e808200441d0176a2011420020042903984e221942137e221a420010e808200441f0186a2012420020042903a04e221c42137e2216420010e808200441e0186a20124200200c420010e808200441f0116a200e4200200d420010e80820044180156a200f4200201b420010e808200441a0166a20104200201a420010e808200441c0176a201142002016420010e808200441b0176a20114200200c420010e808200441d0186a20124200200d420010e808200441e0116a200e42002013420010e808200441f0146a200f4200201a420010e80820044190166a201042002016420010e80820044180166a20104200200c420010e808200441a0176a20114200200d420010e808200441c0186a201242002013420010e808200441d0116a200e42002019420010e808200441e0146a200f42002016420010e808200441d0146a200f4200200c420010e808200441f0156a20104200200d420010e80820044190176a201142002013420010e808200441b0186a201242002019420010e808200441c0116a200e4200201c420010e808200441c00d6a20042903802c224b20042903e0267c220c20042903a02f7c220d20042903b02e7c220e20042903b00e7c220f20042903902c224d20042903f0267c221020042903f02b7c221120042903b02f7c221220042903900f7c221320042903902d22502004290380277c221620042903a02c7c221920042903e02b7c221a20042903f00f7c221b20042903902e22522004290390277c221c20042903a02d7c221e20042903b02c7c221f2004290380107c222220042903902f225420042903a0277c223920042903a02e7c223a20042903b02d7c223b2004290390107c223c423388200441902f6a41086a290300200441a0276a41086a2903007c2039205454ad7c200441a02e6a41086a2903007c203a203954ad7c200441b02d6a41086a2903007c203b203a54ad7c20044190106a41086a2903007c203c203b54ad7c420d86847c2239423388200441902e6a41086a29030020044190276a41086a2903007c201c205254ad7c200441a02d6a41086a2903007c201e201c54ad7c200441b02c6a41086a2903007c201f201e54ad7c20044180106a41086a2903007c2022201f54ad7c2039202254ad7c420d86847c221e423388200441902d6a41086a29030020044180276a41086a2903007c2016205054ad7c200441a02c6a41086a2903007c2019201654ad7c200441e02b6a41086a2903007c201a201954ad7c200441f00f6a41086a2903007c201b201a54ad7c201e201b54ad7c420d86847c2216423388200441902c6a41086a290300200441f0266a41086a2903007c2010204d54ad7c200441f02b6a41086a2903007c2011201054ad7c200441b02f6a41086a2903007c2012201154ad7c200441900f6a41086a2903007c2013201254ad7c2016201354ad7c420d86847c2210423388200441802c6a41086a290300200441e0266a41086a2903007c200c204b54ad7c200441a02f6a41086a2903007c200d200c54ad7c200441b02e6a41086a2903007c200e200d54ad7c200441b00e6a41086a2903007c200f200e54ad7c2010200f54ad7c420d868442137e203c42ffffffffffffff03837c225642ffffffffffffff0383220d420020042903d014224720042903c0117c220c20042903f0157c220e2004290390177c220f20042903b0187c221120042903e014224820042903d0117c22122004290380167c221320042903a0177c221920042903c0187c221a20042903f014224920042903e0117c221b2004290390167c221c20042903b0177c221f20042903d0187c2222200429038015224a20042903f0117c223a20042903a0167c223b20042903c0177c223c20042903e0187c224b200429039015224c2004290380127c224d20042903b0167c225020042903d0177c225220042903f0187c225442338820044190156a41086a29030020044180126a41086a2903007c204d204c54ad7c200441b0166a41086a2903007c2050204d54ad7c200441d0176a41086a2903007c2052205054ad7c200441f0186a41086a2903007c2054205254ad7c420d86847c224d42338820044180156a41086a290300200441f0116a41086a2903007c203a204a54ad7c200441a0166a41086a2903007c203b203a54ad7c200441c0176a41086a2903007c203c203b54ad7c200441e0186a41086a2903007c204b203c54ad7c204d204b54ad7c420d86847c223a423388200441f0146a41086a290300200441e0116a41086a2903007c201b204954ad7c20044190166a41086a2903007c201c201b54ad7c200441b0176a41086a2903007c201f201c54ad7c200441d0186a41086a2903007c2022201f54ad7c203a202254ad7c420d86847c221c423388200441e0146a41086a290300200441d0116a41086a2903007c2012204854ad7c20044180166a41086a2903007c2013201254ad7c200441a0176a41086a2903007c2019201354ad7c200441c0186a41086a2903007c201a201954ad7c201c201a54ad7c420d86847c2212423388200441d0146a41086a290300200441c0116a41086a2903007c200c204754ad7c200441f0156a41086a2903007c200e200c54ad7c20044190176a41086a2903007c200f200e54ad7c200441b0186a41086a2903007c2011200f54ad7c2012201154ad7c420d868442137e205442ffffffffffffff03837c220c42ffffffffffffff0383221a420010e808200441900e6a201242ffffffffffffff0383221b42002056423388203942ffffffffffffff03837c220e42137e420010e808200441b00f6a201c42ffffffffffffff0383221c4200201e42ffffffffffffff0383221342137e2211420010e808200441e00e6a203a42ffffffffffffff0383221e4200201642ffffffffffffff0383221642137e220f420010e808200441f00c6a200c423388204d42ffffffffffffff03837c221f4200201042ffffffffffffff0383221942137e220c420010e808200441b00d6a201f4200200d420010e808200441800e6a201a4200200e420010e808200441a00f6a201b42002011420010e808200441d00e6a201c4200200f420010e808200441e00c6a201e4200200c420010e808200441a00d6a201e4200200d420010e808200441f00d6a201f4200200e420010e808200441c00f6a201a42002013420010e808200441c00e6a201b4200200f420010e808200441d00c6a201c4200200c420010e808200441900d6a201c4200200d420010e808200441e00d6a201e4200200e420010e808200441d00f6a201f42002013420010e808200441f00e6a201a42002016420010e808200441f00b6a201b4200200c420010e808200441800d6a201b4200200d420010e808200441d00d6a201c4200200e420010e808200441e00f6a201e42002013420010e808200441800f6a201f42002016420010e808200441a00e6a201a42002019420010e808200441b00a6a20042903800d224c20042903a00e7c220c20042903d00d7c220f20042903e00f7c221020042903800f7c221120042903f00b224e20042903f00e7c221220042903900d7c222220042903e00d7c223920042903d00f7c223a20042903c00e224f20042903c00f7c223b20042903d00c7c223c20042903a00d7c224b20042903f00d7c224d20042903a00f225120042903800e7c225020042903d00e7c225220042903e00c7c225420042903b00d7c225620042903900e225320042903c00d7c224720042903b00f7c224820042903e00e7c224920042903f00c7c224a423388200441900e6a41086a290300200441c00d6a41086a2903007c2047205354ad7c200441b00f6a41086a2903007c2048204754ad7c200441e00e6a41086a2903007c2049204854ad7c200441f00c6a41086a2903007c204a204954ad7c420d86847c2247423388200441a00f6a41086a290300200441800e6a41086a2903007c2050205154ad7c200441d00e6a41086a2903007c2052205054ad7c200441e00c6a41086a2903007c2054205254ad7c200441b00d6a41086a2903007c2056205454ad7c2047205654ad7c420d86847c2250423388200441c00e6a41086a290300200441c00f6a41086a2903007c203b204f54ad7c200441d00c6a41086a2903007c203c203b54ad7c200441a00d6a41086a2903007c204b203c54ad7c200441f00d6a41086a2903007c204d204b54ad7c2050204d54ad7c420d86847c223b423388200441f00b6a41086a290300200441f00e6a41086a2903007c2012204e54ad7c200441900d6a41086a2903007c2022201254ad7c200441e00d6a41086a2903007c2039202254ad7c200441d00f6a41086a2903007c203a203954ad7c203b203a54ad7c420d86847c223c423388200441800d6a41086a290300200441a00e6a41086a2903007c200c204c54ad7c200441d00d6a41086a2903007c200f200c54ad7c200441e00f6a41086a2903007c2010200f54ad7c200441800f6a41086a2903007c2011201054ad7c203c201154ad7c420d868442137e204a42ffffffffffffff03837c225542ffffffffffffff03832222420020042903a015225720042903e0127c220c20042903c0167c220f20042903e0177c22102004290380197c221120042903b015225820042903c0137c221220042903d0167c223920042903f0177c223a2004290390197c224b20042903c015225920042903a0147c224d20042903e0167c22522004290380187c225420042903a0197c225620042903d015225a20042903b0147c224820042903f0167c22492004290390187c224a20042903b0197c224c20042903e015225b20042903c0147c224e2004290380177c224f20042903a0187c225120042903c0197c2253423388200441e0156a41086a290300200441c0146a41086a2903007c204e205b54ad7c20044180176a41086a2903007c204f204e54ad7c200441a0186a41086a2903007c2051204f54ad7c200441c0196a41086a2903007c2053205154ad7c420d86847c224e423388200441d0156a41086a290300200441b0146a41086a2903007c2048205a54ad7c200441f0166a41086a2903007c2049204854ad7c20044190186a41086a2903007c204a204954ad7c200441b0196a41086a2903007c204c204a54ad7c204e204c54ad7c420d86847c2248423388200441c0156a41086a290300200441a0146a41086a2903007c204d205954ad7c200441e0166a41086a2903007c2052204d54ad7c20044180186a41086a2903007c2054205254ad7c200441a0196a41086a2903007c2056205454ad7c2048205654ad7c420d86847c224d423388200441b0156a41086a290300200441c0136a41086a2903007c2012205854ad7c200441d0166a41086a2903007c2039201254ad7c200441f0176a41086a2903007c203a203954ad7c20044190196a41086a2903007c204b203a54ad7c204d204b54ad7c420d86847c2212423388200441a0156a41086a290300200441e0126a41086a2903007c200c205754ad7c200441c0166a41086a2903007c200f200c54ad7c200441e0176a41086a2903007c2010200f54ad7c20044180196a41086a2903007c2011201054ad7c2012201154ad7c420d868442137e205342ffffffffffffff03837c225242ffffffffffffff0383220c420010e808200441800b6a201242ffffffffffffff0383220f42002055423388204742ffffffffffffff03837c223942137e420010e808200441900c6a204d42ffffffffffffff038322104200205042ffffffffffffff0383223a42137e2250420010e808200441b00b6a204842ffffffffffffff038322114200203b42ffffffffffffff0383224b42137e224d420010e808200441e0096a2052423388204e42ffffffffffffff03837c22124200203c42ffffffffffffff0383223c42137e223b420010e808200441a00a6a201242002022420010e808200441f00a6a200c42002039420010e808200441800c6a200f42002050420010e808200441a00b6a20104200204d420010e808200441d0096a20114200203b420010e808200441900a6a201142002022420010e808200441e00a6a201242002039420010e808200441a00c6a200c4200203a420010e808200441900b6a200f4200204d420010e808200441c0096a20104200203b420010e808200441800a6a201042002022420010e808200441d00a6a201142002039420010e808200441b00c6a20124200203a420010e808200441c00b6a200c4200204b420010e808200441e0086a200f4200203b420010e808200441f0096a200f42002022420010e808200441c00a6a201042002039420010e808200441c00c6a20114200203a420010e808200441d00b6a20124200204b420010e808200441e00b6a200c4200203c420010e808200441b0206a2018420042b0c1bad0f4e48603420010e80820044180236a201d420042a7a7fbf49beaf607420010e808200441b0246a2020420042a0d69f90da80b1cb00420010e808200441e0256a200a420042badf96dcb5c3bac700420010e808200441d0216a200b420042a7ecfac2b5f7ea19420010e808200441c0216a200b420042b0c1bad0f4e48603420010e808200441a0206a20184200429db1bce4dfb435420010e80820044190236a201d420042a0d69f90da80b1cb00420010e808200441c0246a2020420042badf96dcb5c3bac700420010e808200441f0256a200a420042a7ecfac2b5f7ea19420010e80820044180266a200a420042b0c1bad0f4e48603420010e808200441b0216a200b4200429db1bce4dfb435420010e80820044190206a2018420042e098f4e5e9ebfb03420010e808200441a0236a201d420042badf96dcb5c3bac700420010e808200441d0246a2020420042a7ecfac2b5f7ea19420010e808200441e0246a2020420042b0c1bad0f4e48603420010e80820044190266a200a4200429db1bce4dfb435420010e808200441a0216a200b420042e098f4e5e9ebfb03420010e80820044180206a20184200429e9981b4dab2e103420010e808200441b0236a201d420042a7ecfac2b5f7ea19420010e808200441c0236a201d420042b0c1bad0f4e48603420010e808200441f0246a20204200429db1bce4dfb435420010e808200441a0266a200a420042e098f4e5e9ebfb03420010e80820044190216a200b4200429e9981b4dab2e103420010e808200441f01f6a20184200429df893c0a486ae01420010e808200441901a6a20042903b04d2222420042b0c1bad0f4e48603420010e808200441e01a6a20042903d04d2239420042a7a7fbf49beaf607420010e808200441b01b6a20042903c84d223a420042a0d69f90da80b1cb00420010e808200441801c6a20042903c04d223b420042badf96dcb5c3bac700420010e808200441d01c6a20042903b84d223c420042a7ecfac2b5f7ea19420010e808200441c01c6a203c420042b0c1bad0f4e48603420010e808200441801a6a20224200429db1bce4dfb435420010e808200441d01a6a2039420042a0d69f90da80b1cb00420010e808200441a01b6a203a420042badf96dcb5c3bac700420010e808200441f01b6a203b420042a7ecfac2b5f7ea19420010e808200441e01b6a203b420042b0c1bad0f4e48603420010e808200441b01c6a203c4200429db1bce4dfb435420010e808200441f0196a2022420042e098f4e5e9ebfb03420010e808200441c01a6a2039420042badf96dcb5c3bac700420010e808200441901b6a203a420042a7ecfac2b5f7ea19420010e808200441801b6a203a420042b0c1bad0f4e48603420010e808200441d01b6a203b4200429db1bce4dfb435420010e808200441a01c6a203c420042e098f4e5e9ebfb03420010e808200441e0196a20224200429e9981b4dab2e103420010e808200441b01a6a2039420042a7ecfac2b5f7ea19420010e808200441a01a6a2039420042b0c1bad0f4e48603420010e808200441f01a6a203a4200429db1bce4dfb435420010e808200441c01b6a203b420042e098f4e5e9ebfb03420010e808200441901c6a203c4200429e9981b4dab2e103420010e808200441d0196a20224200429df893c0a486ae01420010e808200441e0106a200c420042ea81f582a8b53f420010e808200441d0126a200f420042bbda9284b7cbdd1b420010e808200441b0136a201042004288f5a7f5b28623420010e80820044190146a2011420042edd5d7bc83fb803c420010e808200441b0116a2012420042edc19ab7ab9cc0c700420010e808200441a0116a2012420042ea81f582a8b53f420010e808200441d0106a200c420042b9a6dff282e9ba01420010e808200441c0126a200f42004288f5a7f5b28623420010e808200441a0136a2010420042edd5d7bc83fb803c420010e80820044180146a2011420042edc19ab7ab9cc0c700420010e808200441f0136a2011420042ea81f582a8b53f420010e80820044190116a2012420042b9a6dff282e9ba01420010e808200441c0106a200c420042d8f8d29390ec01420010e808200441b0126a200f420042edd5d7bc83fb803c420010e80820044190136a2010420042edc19ab7ab9cc0c700420010e80820044180136a2010420042ea81f582a8b53f420010e808200441e0136a2011420042b9a6dff282e9ba01420010e80820044180116a2012420042d8f8d29390ec01420010e808200441b0106a200c420042ff91f789b6a19403420010e808200441a0126a200f420042edc19ab7ab9cc0c700420010e80820044190126a200f420042ea81f582a8b53f420010e808200441f0126a2010420042b9a6dff282e9ba01420010e808200441d0136a2011420042d8f8d29390ec01420010e808200441f0106a2012420042ff91f789b6a19403420010e808200441a0106a200c420042fff5f38289d9e103420010e808200441a0076a20042903f009224c20042903e00b7c220c20042903c00a7c220f20042903c00c7c221020042903d00b7c221120042903e008224e20042903c00b7c221220042903800a7c222220042903d00a7c223920042903b00c7c223a20042903900b224f20042903a00c7c223b20042903c0097c223c20042903900a7c224b20042903e00a7c224d20042903800c225120042903f00a7c225020042903a00b7c225220042903d0097c225420042903a00a7c225620042903800b225320042903b00a7c224720042903900c7c224820042903b00b7c224920042903e0097c224a423388200441800b6a41086a290300200441b00a6a41086a2903007c2047205354ad7c200441900c6a41086a2903007c2048204754ad7c200441b00b6a41086a2903007c2049204854ad7c200441e0096a41086a2903007c204a204954ad7c420d86847c2247423388200441800c6a41086a290300200441f00a6a41086a2903007c2050205154ad7c200441a00b6a41086a2903007c2052205054ad7c200441d0096a41086a2903007c2054205254ad7c200441a00a6a41086a2903007c2056205454ad7c2047205654ad7c420d86847c2250423388200441900b6a41086a290300200441a00c6a41086a2903007c203b204f54ad7c200441c0096a41086a2903007c203c203b54ad7c200441900a6a41086a2903007c204b203c54ad7c200441e00a6a41086a2903007c204d204b54ad7c2050204d54ad7c420d86847c223b423388200441e0086a41086a290300200441c00b6a41086a2903007c2012204e54ad7c200441800a6a41086a2903007c2022201254ad7c200441d00a6a41086a2903007c2039202254ad7c200441b00c6a41086a2903007c203a203954ad7c203b203a54ad7c420d86847c223a423388200441f0096a41086a290300200441e00b6a41086a2903007c200c204c54ad7c200441c00a6a41086a2903007c200f200c54ad7c200441c00c6a41086a2903007c2010200f54ad7c200441d00b6a41086a2903007c2011201054ad7c203a201154ad7c420d868442137e204a42ffffffffffffff03837c220c42ffffffffffffff0383220f4200200d420010e808200441f0076a20194200200c423388204742ffffffffffffff03837c221042137e225e420010e80820044180096a20164200205042ffffffffffffff0383221242137e2250420010e808200441a0086a20134200203b42ffffffffffffff0383223942137e2222420010e808200441d0066a200e4200203a42ffffffffffffff0383225242137e2211420010e80820044190076a200e4200200f420010e808200441e0076a200d42002010420010e808200441f0086a201942002050420010e80820044190086a201642002022420010e808200441c0066a201342002011420010e80820044180076a20134200200f420010e808200441d0076a200e42002010420010e80820044190096a200d42002012420010e80820044180086a201942002022420010e808200441b0066a201642002011420010e808200441f0066a20164200200f420010e808200441c0076a201342002010420010e808200441a0096a200e42002012420010e808200441b0086a200d42002039420010e808200441a0066a201942002011420010e808200441e0066a20194200200f420010e808200441b0076a201642002010420010e808200441b0096a201342002012420010e808200441c0086a200e42002039420010e808200441d0086a200d42002052420010e8082004200429038008224c2004290390097c220c20042903b0067c223a2004290380077c223b20042903d0077c223c20042903f008224e20042903e0077c224b2004290390087c224d20042903c0067c22542004290390077c225620042903f007224f20042903a0077c22472004290380097c224820042903a0087c224920042903d0067c224a423388200441f0076a41086a290300200441a0076a41086a2903007c2047204f54ad7c20044180096a41086a2903007c2048204754ad7c200441a0086a41086a2903007c2049204854ad7c200441d0066a41086a2903007c204a204954ad7c420d86847c2247423388200441f0086a41086a290300200441e0076a41086a2903007c204b204e54ad7c20044190086a41086a2903007c204d204b54ad7c200441c0066a41086a2903007c2054204d54ad7c20044190076a41086a2903007c2056205454ad7c2047205654ad7c420d86847c224b42ffffffffffffff03833703e046200420042903a006224920042903b0087c224d20042903f0067c225420042903c0077c225620042903a0097c2248204b42338820044180086a41086a29030020044190096a41086a2903007c200c204c54ad7c200441b0066a41086a2903007c203a200c54ad7c20044180076a41086a2903007c203b203a54ad7c200441d0076a41086a2903007c203c203b54ad7c204b203c54ad7c420d86847c220c42ffffffffffffff03833703e846200420042903e006224c20042903d0087c223a20042903b0077c223b20042903b0097c223c20042903c0087c224b200c423388200441a0066a41086a290300200441b0086a41086a2903007c204d204954ad7c200441f0066a41086a2903007c2054204d54ad7c200441c0076a41086a2903007c2056205454ad7c200441a0096a41086a2903007c2048205654ad7c200c204854ad7c420d86847c220c42ffffffffffffff03833703f0462004200c423388200441e0066a41086a290300200441d0086a41086a2903007c203a204c54ad7c200441b0076a41086a2903007c203b203a54ad7c200441b0096a41086a2903007c203c203b54ad7c200441c0086a41086a2903007c204b203c54ad7c200c204b54ad7c420d868442137e204a42ffffffffffffff03837c220c42ffffffffffffff03833703d0462004200c423388204742ffffffffffffff03837c3703d84620044190236a41086a290300215f200441a0206a41086a2903002160200429039023210c20042903a0202155200441c0246a41086a290300216120042903c0242157200441f0256a41086a290300216220042903f0252158200441c0216a41086a290300216320042903c021215920044180236a41086a2903002164200441b0206a41086a2903002165200429038023213a20042903b020215a200441b0246a41086a290300216620042903b024215b200441e0256a41086a290300216720042903e025215c200441d0216a41086a290300216820042903d021215d20042903a023213b200429039020214e20042903d024214f200429038026215120042903b0212153200441a0236a41086a290300216920044190206a41086a290300216a200441d0246a41086a290300216b20044180266a41086a290300216c200441b0216a41086a290300216d20042903b023213c200429038020214820042903e0242149200429039026214a20042903a021214c200441b0236a41086a290300216e20044180206a41086a290300216f200441e0246a41086a290300217020044190266a41086a2903002171200441a0216a41086a290300217220042903c023214b20042903f01f214d20042903f024215420042903a02621562004290390212147200441c0236a41086a2903002173200441f01f6a41086a2903002174200441f0246a41086a2903002175200441a0266a41086a290300217620044190216a41086a2903002177200441a8ca006a200441d0c6006a106b20042d00a84a410171106d2102200420042903b04d2278204720562054204b204d7c224d7c22547c22567c2247204c204a2049203c20487c22487c22497c224a7c224c20532051204f203b204e7c224e7c224f7c22517c2253205920582057200c20557c22557c22577c22587c2259205d205c205b203a205a7c225a7c225b7c225c7c225d423388206820672066206420657c205a203a54ad7c7c205b205a54ad7c7c205c205b54ad7c7c205d205c54ad7c420d86847c223a423388206320622061205f20607c2055200c54ad7c7c2057205554ad7c7c2058205754ad7c7c2059205854ad7c203a205954ad7c420d86847c2255423388206d206c206b2069206a7c204e203b54ad7c7c204f204e54ad7c7c2051204f54ad7c7c2053205154ad7c2055205354ad7c420d86847c223b423388207220712070206e206f7c2048203c54ad7c7c2049204854ad7c7c204a204954ad7c7c204c204a54ad7c203b204c54ad7c420d86847c223c423388207720762075207320747c204d204b54ad7c7c2054204d54ad7c7c2056205454ad7c7c2047205654ad7c203c204754ad7c420d868442137e205d42ffffffffffffff03837c224b42ffffffffffffff03838542002002ad42ff01837d220c832078853703b04d200420042903b84d224d204b423388203a42ffffffffffffff03837c85200c83204d853703b84d200420042903c04d223a205542ffffffffffffff038385200c83203a853703c04d200420042903c84d223a203b42ffffffffffffff038385200c83203a853703c84d200420042903d04d223a203c42ffffffffffffff038385200c83203a853703d04d20044190066a200f4200201820042903a01a225a20042903d0197c223a20042903f01a7c223b20042903c01b7c223c20042903901c7c224b20042903b01a225b20042903e0197c224d20042903801b7c225420042903d01b7c225620042903a01c7c224720042903c01a225c20042903f0197c224820042903901b7c224920042903e01b7c224a20042903b01c7c224c20042903d01a225d20042903801a7c224e20042903a01b7c224f20042903f01b7c225120042903c01c7c225320042903e01a225f20042903901a7c225520042903b01b7c225720042903801c7c225820042903d01c7c2259423388200441e01a6a41086a290300200441901a6a41086a2903007c2055205f54ad7c200441b01b6a41086a2903007c2057205554ad7c200441801c6a41086a2903007c2058205754ad7c200441d01c6a41086a2903007c2059205854ad7c420d86847c2255423388200441d01a6a41086a290300200441801a6a41086a2903007c204e205d54ad7c200441a01b6a41086a2903007c204f204e54ad7c200441f01b6a41086a2903007c2051204f54ad7c200441c01c6a41086a2903007c2053205154ad7c2055205354ad7c420d86847c224e423388200441c01a6a41086a290300200441f0196a41086a2903007c2048205c54ad7c200441901b6a41086a2903007c2049204854ad7c200441e01b6a41086a2903007c204a204954ad7c200441b01c6a41086a2903007c204c204a54ad7c204e204c54ad7c420d86847c2248423388200441b01a6a41086a290300200441e0196a41086a2903007c204d205b54ad7c200441801b6a41086a2903007c2054204d54ad7c200441d01b6a41086a2903007c2056205454ad7c200441a01c6a41086a2903007c2047205654ad7c2048204754ad7c420d86847c224d423388200441a01a6a41086a290300200441d0196a41086a2903007c203a205a54ad7c200441f01a6a41086a2903007c203b203a54ad7c200441c01b6a41086a2903007c203c203b54ad7c200441901c6a41086a2903007c204b203c54ad7c204d204b54ad7c420d868442137e205942ffffffffffffff03837c225442ffffffffffffff038385200c83201885223a420010e808200441d0036a201d204d42ffffffffffffff038385200c83201d85223b4200205e420010e808200441a0046a2020204842ffffffffffffff038385200c83202085223c42002050420010e808200441f0046a200a204e42ffffffffffffff038385200c83200a85224b42002022420010e808200441c0056a200b2054423388205542ffffffffffffff03837c85200c83200b85224d42002011420010e808200441b0056a204d4200200f420010e80820044180066a203a42002010420010e808200441c0036a203b42002050420010e80820044190046a203c42002022420010e808200441e0046a204b42002011420010e808200441d0046a204b4200200f420010e808200441a0056a204d42002010420010e808200441f0056a203a42002012420010e808200441b0036a203b42002022420010e80820044180046a203c42002011420010e808200441f0036a203c4200200f420010e808200441c0046a204b42002010420010e80820044190056a204d42002012420010e808200441e0056a203a42002039420010e808200441a0036a203b42002011420010e80820044190036a203b4200200f420010e808200441e0036a203c42002010420010e808200441b0046a204b42002012420010e80820044180056a204d42002039420010e808200441d0056a203a42002052420010e808200420042903b003225220042903f0057c220f2004290380047c221020042903d0047c221120042903a0057c221220042903c00322542004290380067c22222004290390047c223920042903e0047c223a20042903b0057c223b20042903d00322562004290390067c223c20042903a0047c224b20042903f0047c224d20042903c0057c2250423388200441d0036a41086a29030020044190066a41086a2903007c203c205654ad7c200441a0046a41086a2903007c204b203c54ad7c200441f0046a41086a2903007c204d204b54ad7c200441c0056a41086a2903007c2050204d54ad7c420d86847c223c423388200441c0036a41086a29030020044180066a41086a2903007c2022205454ad7c20044190046a41086a2903007c2039202254ad7c200441e0046a41086a2903007c203a203954ad7c200441b0056a41086a2903007c203b203a54ad7c203c203b54ad7c420d86847c222242ffffffffffffff03833703e046200420042903a003224d20042903e0057c223920042903f0037c223a20042903c0047c223b2004290390057c224b2022423388200441b0036a41086a290300200441f0056a41086a2903007c200f205254ad7c20044180046a41086a2903007c2010200f54ad7c200441d0046a41086a2903007c2011201054ad7c200441a0056a41086a2903007c2012201154ad7c2022201254ad7c420d86847c220f42ffffffffffffff03833703e8462004200429039003225220042903d0057c221020042903e0037c221120042903b0047c22122004290380057c2222200f423388200441a0036a41086a290300200441e0056a41086a2903007c2039204d54ad7c200441f0036a41086a2903007c203a203954ad7c200441c0046a41086a2903007c203b203a54ad7c20044190056a41086a2903007c204b203b54ad7c200f204b54ad7c420d86847c220f42ffffffffffffff03833703f0462004200f42338820044190036a41086a290300200441d0056a41086a2903007c2010205254ad7c200441e0036a41086a2903007c2011201054ad7c200441b0046a41086a2903007c2012201154ad7c20044180056a41086a2903007c2022201254ad7c200f202254ad7c420d868442137e205042ffffffffffffff03837c220f42ffffffffffffff03833703d0462004200f423388203c42ffffffffffffff03837c3703d846200441c0126a41086a290300215a200441d0106a41086a290300215b20042903c012211120042903d010214e200441a0136a41086a290300215c20042903a013214f20044180146a41086a290300215d2004290380142151200441a0116a41086a290300215e20042903a0112153200441d0126a41086a290300215f200441e0106a41086a290300216020042903d012211220042903e0102155200441b0136a41086a290300216120042903b013215720044190146a41086a29030021622004290390142158200441b0116a41086a290300216320042903b011215920042903b012212220042903c0102148200429039013214920042903f013214a200429039011214c200441b0126a41086a2903002164200441c0106a41086a290300216520044190136a41086a2903002166200441f0136a41086a290300216720044190116a41086a290300216820042903a012213920042903b0102152200429038013215420042903e01321562004290380112147200441a0126a41086a2903002169200441b0106a41086a290300216a20044180136a41086a290300216b200441e0136a41086a290300216c20044180116a41086a290300216d200429039012213a20042903a010214b20042903f012214d20042903d013215020042903f010216e20044190126a41086a290300216f200441a0106a41086a2903002170200441f0126a41086a2903002171200441d0136a41086a2903002172200441f0106a41086a2903002173200441a8ca006a200441d0c6006a106b20042d00a84a410171106d2102200420042903b04d221042f0ffffffffffff3f20042903d04d223b7d223c42338842137e42d0fdffffffffff3f20107d227442ffffffffffffff03837c8542002002ad42ff01837d220f8320108522103703b04d2004203b203b203c42ffffffffffffff038342f0ffffffffffff3f20042903c84d223c7d22754233887c85200f8385223b3703d04d20044180036a203e203b7d223e42338842137e204020107d224042ffffffffffffff03837c22104200201a206e2050204d203a204b7c223b7c224b7c224d7c2250204720562054203920527c22527c22547c22567c2247204c204a2049202220487c22487c22497c224a7c224c20532051204f2011204e7c224e7c224f7c22517c2253205920582057201220557c22557c22577c22587c2259423388206320622061205f20607c2055201254ad7c7c2057205554ad7c7c2058205754ad7c7c2059205854ad7c420d86847c2255423388205e205d205c205a205b7c204e201154ad7c7c204f204e54ad7c7c2051204f54ad7c7c2053205154ad7c2055205354ad7c420d86847c224e423388206820672066206420657c2048202254ad7c7c2049204854ad7c7c204a204954ad7c7c204c204a54ad7c204e204c54ad7c420d86847c2222423388206d206c206b2069206a7c2052203954ad7c7c2054205254ad7c7c2056205454ad7c7c2047205654ad7c2022204754ad7c420d86847c2212423388207320722071206f20707c203b203a54ad7c7c204b203b54ad7c7c204d204b54ad7c7c2050204d54ad7c2012205054ad7c420d868442137e205942ffffffffffffff03837c223a42ffffffffffffff038385200c83201a852211420010e808200420042903b84d221a42f0ffffffffffff3f201a7d223942ffffffffffffff038320744233887c85200f83201a85221a3703b84d200441c0006a201b201242ffffffffffffff038385200c83201b85221242002042201a7d223b42ffffffffffffff038320404233887c221a42137e420010e808200420042903c04d221b42f0ffffffffffff3f201b7d224b42ffffffffffffff038320394233887c85200f83201b8522393703c04d20044190016a201c202242ffffffffffffff038385200c83201c85221b4200204520397d222242ffffffffffffff0383203b4233887c221c42137e223b420010e8082004203c203c207542ffffffffffffff0383204b4233887c85200f838522393703c84d200441e0016a201e204e42ffffffffffffff038385200c83201e85220f4200204620397d221e42ffffffffffffff038320224233887c222242137e2239420010e808200441b0026a201f203a423388205542ffffffffffffff03837c85200c83201f85220c4200203e42ffffffffffffff0383201e4233887c221f42137e221e420010e808200441a0026a200c42002010420010e808200441f0026a20114200201a420010e808200441306a20124200203b420010e80820044180016a201b42002039420010e808200441d0016a200f4200201e420010e808200441c0016a200f42002010420010e80820044190026a200c4200201a420010e808200441e0026a20114200201c420010e808200441206a201242002039420010e808200441f0006a201b4200201e420010e808200441e0006a201b42002010420010e808200441b0016a200f4200201a420010e80820044180026a200c4200201c420010e808200441d0026a201142002022420010e808200441106a20124200201e420010e8082004201242002010420010e808200441d0006a201b4200201a420010e808200441a0016a200f4200201c420010e808200441f0016a200c42002022420010e808200441c0026a20114200201f420010e80820042004290300225620042903c0027c220c20042903507c220f20042903a0017c221020042903f0017c22112004290310224720042903d0027c221220042903607c221a20042903b0017c221b2004290380027c221c2004290320224820042903e0027c221e20042903707c221f20042903c0017c22222004290390027c22392004290330224920042903f0027c223a2004290380017c223b20042903d0017c223c20042903a0027c224b2004290340224a2004290380037c224d2004290390017c225020042903e0017c225220042903b0027c2254423388200441c0006a41086a29030020044180036a41086a2903007c204d204a54ad7c20044190016a41086a2903007c2050204d54ad7c200441e0016a41086a2903007c2052205054ad7c200441b0026a41086a2903007c2054205254ad7c420d86847c224d423388200441306a41086a290300200441f0026a41086a2903007c203a204954ad7c20044180016a41086a2903007c203b203a54ad7c200441d0016a41086a2903007c203c203b54ad7c200441a0026a41086a2903007c204b203c54ad7c204d204b54ad7c420d86847c223a423388200441206a41086a290300200441e0026a41086a2903007c201e204854ad7c200441f0006a41086a2903007c201f201e54ad7c200441c0016a41086a2903007c2022201f54ad7c20044190026a41086a2903007c2039202254ad7c203a203954ad7c420d86847c221e423388200441106a41086a290300200441d0026a41086a2903007c2012204754ad7c200441e0006a41086a2903007c201a201254ad7c200441b0016a41086a2903007c201b201a54ad7c20044180026a41086a2903007c201c201b54ad7c201e201c54ad7c420d86847c2212423388200441086a290300200441c0026a41086a2903007c200c205654ad7c200441d0006a41086a2903007c200f200c54ad7c200441a0016a41086a2903007c2010200f54ad7c200441f0016a41086a2903007c2011201054ad7c2012201154ad7c420d868442137e205442ffffffffffffff03837c220c42ffffffffffffff0383220f3703d0462004200c423388204d42ffffffffffffff03837c22103703d8462004201242ffffffffffffff038322113703f0462004201e42ffffffffffffff038322123703e8462004203a42ffffffffffffff0383221a3703e046200441a8ca006a200441d0c6006a106b2004201142f0ffffffffffff3f20117d221b42ffffffffffffff038342f0ffffffffffff3f20127d221c4233887c85420020042d00a84a410171106dad42ff01837d220c832011853703f04620042012201c42ffffffffffffff038342f0ffffffffffff3f201a7d22114233887c85200c832012853703e8462004201a201142ffffffffffffff038342f0ffffffffffff3f20107d22114233887c85200c83201a853703e04620042010201142ffffffffffffff038342d0fdffffffffff3f200f7d22114233887c85200c832010853703d8462004200f201b42338842137e201142ffffffffffffff03837c85200c83200f853703d046200441e0c4006a200441d0c6006a106b41002102034020044180c5006a20026a41003a0000200241016a220241c801470d000b20044188c9006a41186a2203200141186a29000037030020044188c9006a41106a2205200141106a29000037030020044188c9006a41086a2206200141086a2900003703002004200129000037038849200441d0c6006a20044188c9006a10f401200441d0c6006a41086a290300210c200441d0c6006a41106a290300210f200441d0c6006a41186a2903002110200441d0c6006a41206a290300211a200441f8c6006a290300211b20044180c7006a290300211120044188c7006a290300211220044190c7006a290300211c20044198c7006a290300211e200441a0c7006a290300211f20042802d446210120042802d046210220044180c5006a200441a8c7006a41f00010e9081a0240024020024101460d00200441f0ca006a20044180c5006a41f00010e9081a2004200f200c4233887c22224233882022200f54ad420d8684223a20107c223942ffffffffffffff03833703b048200420394233882039203a54ad420d8684223a201a7c223942ffffffffffffff03833703b848200420394233882039203a54ad420d8684223a201b7c223942ffffffffffffff03833703c048200420394233882039203a54ad420d868442137e200c42ffffffffffffff03837c223942ffffffffffffff03833703a04820042039423388202242ffffffffffffff03837c3703a84820044188c9006a41206a4200370300200342003703002005420037030020064200370300200442003703884920044180c5006a41206a420037030020044180c5006a41186a420037030020044180c5006a41106a420037030020044180c5006a41086a420037030020044200370380452004201220114233887c22224233882022201254ad420d8684223a201c7c22394233882039203a54ad420d8684223b201e7c223a423388203a203b54ad420d8684223c201f7c223b42ffffffffffffff03833703f0462004203a42ffffffffffffff03833703e8462004203942ffffffffffffff03833703e0462004203b423388203b203c54ad420d868442137e201142ffffffffffffff03837c2239423388202242ffffffffffffff03837c3703d8462004203942ffffffffffffff03833703d0460240200441a0c8006a20044188c9006a106c20044180c5006a200441d0c6006a106c72106d41ff01714101470d0020004101360200200041013a00040c020b200041a0016a201937030020004198016a201637030020004190016a201337030020004188016a200e37030020004180016a200d370300200041f8006a203d370300200041f0006a2043370300200041e8006a2044370300200041e0006a2041370300200041d8006a203f370300200041d0006a2023370300200041c8006a2021370300200041c0006a2017370300200041386a2015370300200041306a2014370300200041286a201d370300200041206a2020370300200041186a200a370300200041106a200b370300200041086a201837030020004190026a201f37030020004188026a201e37030020004180026a201c370300200041f8016a2012370300200041f0016a2011370300200041e8016a201b370300200041e0016a201a370300200041d8016a2010370300200041d0016a200f370300200041c8016a200c370300200041c0016a200441e0c4006a41186a290300370300200041b8016a200441e0c4006a41106a290300370300200041b0016a200441e0c4006a41086a290300370300200041a8016a20042903e04437030020004198026a200441f0ca006a41f00010e9081a200041003602000c010b2000200136020420004101360200200041186a20103e0200200041106a200f370200200041086a200c3702000b200441d0ce006a24000bbd6603047f237e067f230041d01f6b22022400200241801c6a20011070200241a81c6a200241801c6a106b41002103410121040340200120036a2d0000200241a81c6a20036a2d0000732205410020056b72417f7341800171410776106d2004712104200341016a22034120470d000b2004106d2103200241881f6a200241801c6a106b20022d00881f410171106d210402400240024002400240200341ff0171450d00200441ff01714101470d010b200241b81e6a21030c010b200241c81c6a200241801c6a4101106e200242f0ffffffffffff3f20022903e81c7d220642ffffffffffffff038342f0ffffffffffff3f20022903e01c7d22074233887c3703901d2002200742ffffffffffffff038342f0ffffffffffff3f20022903d81c22077d22084233887c3703881d2002200842ffffffffffffff038342f0ffffffffffff3f20022903d01c22087d22094233887c3703801d2002200942ffffffffffffff038342d1fdffffffffff3f20022903c81c22097d220a4233887c3703f81c2002200642338842137e200a42ffffffffffffff03837c3703f01c200242003703b01d200242003703b81d2002200942017c3703981d200220083703a01d200220073703a81d200220022903e01c3703b01d200220022903b81d20022903e81c7c3703b81d200241c01d6a200241981d6a4101106e200241b81e6a200241f01c6a4101106e200241f8156a20022903b81e2206420042ca8e9ae5dec6ac02420010e808200241f8186a20022903c01e220742137e4200428092f58893f9b701420010e808200241a8186a20022903c81e220842137e220b420042c486ffe299c731420010e808200241d8176a20022903d01e220a42137e220c420042d6fff8ffd98b8601420010e80820024188176a20022903d81e220d42137e2209420042c2a2aaa7fcfa9503420010e80820024188166a2006420042c2a2aaa7fcfa9503420010e808200241e8186a2007420042ca8e9ae5dec6ac02420010e80820024198186a200b4200428092f58893f9b701420010e808200241c8176a200c420042c486ffe299c731420010e808200241f8166a2009420042d6fff8ffd98b8601420010e80820024198166a2006420042d6fff8ffd98b8601420010e808200241d8186a2007420042c2a2aaa7fcfa9503420010e80820024188186a2008420042ca8e9ae5dec6ac02420010e808200241b8176a200c4200428092f58893f9b701420010e808200241e8166a2009420042c486ffe299c731420010e808200241a8166a2006420042c486ffe299c731420010e808200241c8186a2007420042d6fff8ffd98b8601420010e808200241f8176a2008420042c2a2aaa7fcfa9503420010e808200241a8176a200a420042ca8e9ae5dec6ac02420010e808200241d8166a20094200428092f58893f9b701420010e808200241b8166a20064200428092f58893f9b701420010e808200241b8186a2007420042c486ffe299c731420010e808200241e8176a2008420042d6fff8ffd98b8601420010e80820024198176a200a420042c2a2aaa7fcfa9503420010e808200241c8166a200d420042ca8e9ae5dec6ac02420010e808200241f8136a20022903c01d2208420020022903b816220e20022903c8167c220620022903b8187c220720022903e8177c22092002290398177c220a20022903d816220f20022903a8177c220c20022903a8167c220b20022903c8187c220d20022903f8177c221020022903b81722112002290388187c221220022903e8167c22132002290398167c221420022903d8187c2215200229039818221620022903e8187c221720022903c8177c221820022903f8167c22192002290388167c221a20022903f818221b20022903f8157c221c20022903a8187c221d20022903d8177c221e2002290388177c221f423388200241f8186a41086a290300200241f8156a41086a2903007c201c201b54ad7c200241a8186a41086a2903007c201d201c54ad7c200241d8176a41086a2903007c201e201d54ad7c20024188176a41086a2903007c201f201e54ad7c420d86847c221c42338820024198186a41086a290300200241e8186a41086a2903007c2017201654ad7c200241c8176a41086a2903007c2018201754ad7c200241f8166a41086a2903007c2019201854ad7c20024188166a41086a2903007c201a201954ad7c201c201a54ad7c420d86847c2218423388200241b8176a41086a29030020024188186a41086a2903007c2012201154ad7c200241e8166a41086a2903007c2013201254ad7c20024198166a41086a2903007c2014201354ad7c200241d8186a41086a2903007c2015201454ad7c2018201554ad7c420d86847c2212423388200241d8166a41086a290300200241a8176a41086a2903007c200c200f54ad7c200241a8166a41086a2903007c200b200c54ad7c200241c8186a41086a2903007c200d200b54ad7c200241f8176a41086a2903007c2010200d54ad7c2012201054ad7c420d86847c220c42ffffffffffffff038320022903e01d220d7d42f0ffffffffffff3f7c220b42338842137e200c423388200241b8166a41086a290300200241c8166a41086a2903007c2006200e54ad7c200241b8186a41086a2903007c2007200654ad7c200241e8176a41086a2903007c2009200754ad7c20024198176a41086a2903007c200a200954ad7c200c200a54ad7c420d868442137e201f42feffffffffffff03837c220742ffffffffffffff038320087d42d0fdffffffffff3f7c221342ffffffffffffff03837c2206420010e808200241e8156a200b42ffffffffffffff0383201242ffffffffffffff038320022903d81d220c7d42f0ffffffffffff3f7c220a4233887c2217420020022903c81d220942137e420010e80820024198156a200a42ffffffffffffff0383201842ffffffffffffff038320022903d01d220a7d42f0ffffffffffff3f7c220b4233887c22144200200a42137e2215420010e808200241c8146a200b42ffffffffffffff03832007423388201c42ffffffffffffff03837c20097d42f0ffffffffffff3f7c22074233887c22124200200c42137e2210420010e808200241a8136a200742ffffffffffffff038320134233887c22074200200d42137e220b420010e80820024198136a200742002008420010e808200241e8136a200642002009420010e808200241d8156a201742002015420010e80820024188156a201442002010420010e808200241b8146a20124200200b420010e808200241a8146a201242002008420010e80820024188136a200742002009420010e808200241d8136a20064200200a420010e808200241c8156a201742002010420010e808200241f8146a20144200200b420010e808200241e8146a201442002008420010e80820024198146a201242002009420010e808200241f8126a20074200200a420010e808200241c8136a20064200200c420010e808200241b8156a20174200200b420010e808200241a8156a201742002008420010e808200241d8146a201442002009420010e80820024188146a20124200200a420010e808200241e8126a20074200200c420010e808200241b8136a20064200200d420010e808200220022903c815221c20022903d8137c220820022903f8147c220920022903a8147c220a2002290388137c220c20022903d815221d20022903e8137c220b2002290388157c220d20022903b8147c22102002290398137c221320022903e815221e20022903f8137c22152002290398157c221820022903c8147c221920022903a8137c221a423388200241e8156a41086a290300200241f8136a41086a2903007c2015201e54ad7c20024198156a41086a2903007c2018201554ad7c200241c8146a41086a2903007c2019201854ad7c200241a8136a41086a2903007c201a201954ad7c420d86847c2215423388200241d8156a41086a290300200241e8136a41086a2903007c200b201d54ad7c20024188156a41086a2903007c200d200b54ad7c200241b8146a41086a2903007c2010200d54ad7c20024198136a41086a2903007c2013201054ad7c2015201354ad7c420d86847c220b42ffffffffffffff03833703a01e200220022903b815221920022903c8137c220d20022903e8147c22102002290398147c221320022903f8127c2218200b423388200241c8156a41086a290300200241d8136a41086a2903007c2008201c54ad7c200241f8146a41086a2903007c2009200854ad7c200241a8146a41086a2903007c200a200954ad7c20024188136a41086a2903007c200c200a54ad7c200b200c54ad7c420d86847c220842ffffffffffffff03833703a81e200220022903a815221c20022903b8137c220920022903d8147c220a2002290388147c220c20022903e8127c220b2008423388200241b8156a41086a290300200241c8136a41086a2903007c200d201954ad7c200241e8146a41086a2903007c2010200d54ad7c20024198146a41086a2903007c2013201054ad7c200241f8126a41086a2903007c2018201354ad7c2008201854ad7c420d86847c220842ffffffffffffff03833703b01e20022008423388200241a8156a41086a290300200241b8136a41086a2903007c2009201c54ad7c200241d8146a41086a2903007c200a200954ad7c20024188146a41086a2903007c200c200a54ad7c200241e8126a41086a2903007c200b200c54ad7c2008200b54ad7c420d868442137e201a42ffffffffffffff03837c220842ffffffffffffff03833703901e20022008423388201542ffffffffffffff03837c3703981e200241a81f6a41106a4200370300200241a81f6a41186a4200370300200241a81f6a41206a4200370300200242003703b01f200242013703a81f200241b81e6a200241a81f6a200241901e6a106f20024198126a20022903981d220d420020022903c01e2208420010e808200241d80f6a200241e01e6a2903002209420020022903a01d221042137e420010e808200241b8106a200241b81e6a41206a2203290300220a420020022903a81d221342137e221a420010e80820024198116a200241b81e6a41186a2204290300220c420020022903b01d221842137e2219420010e808200241f8116a200241b81e6a41106a2205290300220b420020022903b81d221c42137e2215420010e808200241d8126a200b4200200d420010e80820024198106a200842002010420010e808200241a8106a20094200201a420010e80820024188116a200a42002019420010e808200241e8116a200c42002015420010e808200241c8126a200c4200200d420010e80820024188106a200b42002010420010e808200241e8106a200842002013420010e808200241f8106a200942002019420010e808200241d8116a200a42002015420010e808200241b8126a200a4200200d420010e808200241f80f6a200c42002010420010e808200241d8106a200b42002013420010e808200241b8116a200842002018420010e808200241c8116a200942002015420010e808200241a8126a20094200200d420010e808200241e80f6a200a42002010420010e808200241c8106a200c42002013420010e808200241a8116a200b42002018420010e80820024188126a20084200201c420010e808200241980d6a2006420020022903a81222202002290388127c220d20022903e80f7c221020022903c8107c221320022903a8117c221520022903c811222120022903b8117c221820022903b8127c221920022903f80f7c221a20022903d8107c221c20022903f810222220022903e8107c221d20022903d8117c221e20022903c8127c221f2002290388107c220e20022903a81022232002290398107c220f2002290388117c221120022903e8117c221620022903d8127c221b20022903d80f22242002290398127c222520022903b8107c22262002290398117c222720022903f8117c2228423388200241d80f6a41086a29030020024198126a41086a2903007c2025202454ad7c200241b8106a41086a2903007c2026202554ad7c20024198116a41086a2903007c2027202654ad7c200241f8116a41086a2903007c2028202754ad7c420d86847c2225423388200241a8106a41086a29030020024198106a41086a2903007c200f202354ad7c20024188116a41086a2903007c2011200f54ad7c200241e8116a41086a2903007c2016201154ad7c200241d8126a41086a2903007c201b201654ad7c2025201b54ad7c420d86847c220f423388200241f8106a41086a290300200241e8106a41086a2903007c201d202254ad7c200241d8116a41086a2903007c201e201d54ad7c200241c8126a41086a2903007c201f201e54ad7c20024188106a41086a2903007c200e201f54ad7c200f200e54ad7c420d86847c221d423388200241c8116a41086a290300200241b8116a41086a2903007c2018202154ad7c200241b8126a41086a2903007c2019201854ad7c200241f80f6a41086a2903007c201a201954ad7c200241d8106a41086a2903007c201c201a54ad7c201d201c54ad7c420d86847c2218423388200241a8126a41086a29030020024188126a41086a2903007c200d202054ad7c200241e80f6a41086a2903007c2010200d54ad7c200241c8106a41086a2903007c2013201054ad7c200241a8116a41086a2903007c2015201354ad7c2018201554ad7c420d868442137e202842ffffffffffffff03837c221042ffffffffffffff0383220d420010e808200241b8096a201842ffffffffffffff038322184200200742137e420010e808200241c80e6a201d42ffffffffffffff038322154200201242137e221c420010e808200241f80d6a200f42ffffffffffffff038322134200201442137e221a420010e808200241e80d6a2010423388202542ffffffffffffff03837c22104200201742137e2219420010e808200241d80d6a201042002006420010e808200241880d6a200d42002007420010e808200241980f6a20184200201c420010e808200241d80e6a20154200201a420010e808200241880e6a201342002019420010e808200241980e6a201342002006420010e808200241c80d6a201042002007420010e808200241f80c6a200d42002012420010e808200241a80f6a20184200201a420010e808200241e80e6a201542002019420010e808200241f80e6a201542002006420010e808200241a80e6a201342002007420010e808200241b80d6a201042002012420010e808200241e80c6a200d42002014420010e808200241b80f6a201842002019420010e808200241c80f6a201842002006420010e808200241880f6a201542002007420010e808200241b80e6a201342002012420010e808200241a80d6a201042002014420010e808200241d80c6a200d42002017420010e808200241e8066a20022903c80f222020022903d80c7c220620022903880f7c220720022903b80e7c221220022903a80d7c221420022903b80f222120022903e80c7c221720022903f80e7c221920022903a80e7c221a20022903b80d7c221c20022903a80f222220022903f80c7c221d20022903e80e7c221e20022903980e7c221f20022903c80d7c220e20022903980f222320022903880d7c220f20022903d80e7c221120022903880e7c221620022903d80d7c221b20022903b809222420022903980d7c222520022903c80e7c222620022903f80d7c222720022903e80d7c2228423388200241b8096a41086a290300200241980d6a41086a2903007c2025202454ad7c200241c80e6a41086a2903007c2026202554ad7c200241f80d6a41086a2903007c2027202654ad7c200241e80d6a41086a2903007c2028202754ad7c420d86847c2225423388200241980f6a41086a290300200241880d6a41086a2903007c200f202354ad7c200241d80e6a41086a2903007c2011200f54ad7c200241880e6a41086a2903007c2016201154ad7c200241d80d6a41086a2903007c201b201654ad7c2025201b54ad7c420d86847c220f423388200241a80f6a41086a290300200241f80c6a41086a2903007c201d202254ad7c200241e80e6a41086a2903007c201e201d54ad7c200241980e6a41086a2903007c201f201e54ad7c200241c80d6a41086a2903007c200e201f54ad7c200f200e54ad7c420d86847c221d423388200241b80f6a41086a290300200241e80c6a41086a2903007c2017202154ad7c200241f80e6a41086a2903007c2019201754ad7c200241a80e6a41086a2903007c201a201954ad7c200241b80d6a41086a2903007c201c201a54ad7c201d201c54ad7c420d86847c2217423388200241c80f6a41086a290300200241d80c6a41086a2903007c2006202054ad7c200241880f6a41086a2903007c2007200654ad7c200241b80e6a41086a2903007c2012200754ad7c200241a80d6a41086a2903007c2014201254ad7c2017201454ad7c420d868442137e202842ffffffffffffff03837c220742ffffffffffffff0383220642002008420010e808200241b8076a200942002007423388202542ffffffffffffff03837c220742137e420010e808200241d8076a200a4200200f42ffffffffffffff0383221242137e221c420010e80820024188086a200c4200201d42ffffffffffffff0383221942137e221a420010e808200241c8086a200b4200201742ffffffffffffff0383221742137e2214420010e808200241d8066a200b42002006420010e808200241a8076a200842002007420010e808200241c8076a20094200201c420010e808200241f8076a200a4200201a420010e808200241b8086a200c42002014420010e808200241c8066a200c42002006420010e80820024198076a200b42002007420010e808200241d8086a200842002012420010e808200241e8076a20094200201a420010e808200241a8086a200a42002014420010e808200241e8056a200a42002006420010e80820024188076a200c42002007420010e808200241e8086a200b42002012420010e80820024188096a200842002019420010e80820024198086a200942002014420010e80820024188056a200942002006420010e808200241f8066a200a42002007420010e808200241f8086a200c42002012420010e80820024198096a200b42002019420010e808200241a8096a200842002017420010e80820022d00b81e21292003200241801c6a41206a222a2903003703002004200241801c6a41186a222b2903003703002005200241801c6a41106a222c2903002208370300200241b81e6a41086a222d200241801c6a41086a222e2903002207370300200220022903801c22063703b81e2002200620022903801c7c22063703b81e202d2007202e2903007c220737030020052008202c2903007c220837030020042004290300202b2903007c220937030020032003290300202a2903007c220a370300200241880c6a200d42002006420010e808200241880a6a200a4200201042137e420010e808200241980a6a20094200201342137e2212420010e808200241e80a6a20084200201542137e220b420010e808200241b80b6a20074200201842137e220c420010e808200241c80b6a20074200200d420010e808200241980c6a200642002010420010e808200241f8096a200a42002012420010e808200241a80a6a20094200200b420010e808200241f80a6a20084200200c420010e808200241880b6a20084200200d420010e808200241d80b6a200742002010420010e808200241a80c6a200642002013420010e808200241e8096a200a4200200b420010e808200241b80a6a20094200200c420010e808200241c80a6a20094200200d420010e808200241980b6a200842002010420010e808200241e80b6a200742002013420010e808200241b80c6a200642002015420010e808200241d8096a200a4200200c420010e808200241c8096a200a4200200d420010e808200241d80a6a200942002010420010e808200241a80b6a200842002013420010e808200241f80b6a200742002015420010e808200241c80c6a200642002018420010e808200220022903c809221f20022903c80c7c220620022903d80a7c220720022903a80b7c220820022903f80b7c220920022903d809220e20022903b80c7c220a20022903c80a7c220c20022903980b7c220b20022903e80b7c220d20022903e809220f20022903a80c7c221020022903b80a7c221220022903880b7c221320022903d80b7c221420022903f809221120022903980c7c221520022903a80a7c221720022903f80a7c221820022903c80b7c221920022903880a221620022903880c7c221a20022903980a7c221c20022903e80a7c221d20022903b80b7c221e423388200241880a6a41086a290300200241880c6a41086a2903007c201a201654ad7c200241980a6a41086a2903007c201c201a54ad7c200241e80a6a41086a2903007c201d201c54ad7c200241b80b6a41086a2903007c201e201d54ad7c420d86847c221a423388200241f8096a41086a290300200241980c6a41086a2903007c2015201154ad7c200241a80a6a41086a2903007c2017201554ad7c200241f80a6a41086a2903007c2018201754ad7c200241c80b6a41086a2903007c2019201854ad7c201a201954ad7c420d86847c2215423388200241e8096a41086a290300200241a80c6a41086a2903007c2010200f54ad7c200241b80a6a41086a2903007c2012201054ad7c200241880b6a41086a2903007c2013201254ad7c200241d80b6a41086a2903007c2014201354ad7c2015201454ad7c420d86847c2210423388200241d8096a41086a290300200241b80c6a41086a2903007c200a200e54ad7c200241c80a6a41086a2903007c200c200a54ad7c200241980b6a41086a2903007c200b200c54ad7c200241e80b6a41086a2903007c200d200b54ad7c2010200d54ad7c420d86847c220a423388200241c8096a41086a290300200241c80c6a41086a2903007c2006201f54ad7c200241d80a6a41086a2903007c2007200654ad7c200241a80b6a41086a2903007c2008200754ad7c200241f80b6a41086a2903007c2009200854ad7c200a200954ad7c420d868442137e201e42ffffffffffffff03837c220642ffffffffffffff03833703e81d20022006423388201a42ffffffffffffff03837c3703f01d2002200a42ffffffffffffff038322063703881e2002201042ffffffffffffff038322073703801e2002201542ffffffffffffff0383220c3703f81d200241881f6a200241e81d6a106b2002200642f0ffffffffffff3f20067d220942ffffffffffffff038342f0ffffffffffff3f20077d22084233887c85420020022d00881f410171106dad42ff01837d220a8320068522063703881e20022007200842ffffffffffffff038342f0ffffffffffff3f200c7d220b4233887c85200a8320078522073703801e200220022903e81d2208200942338842137e42d0fdffffffffff3f20087d220d42ffffffffffffff03837c85200a8320088522083703e81d200220022903f01d220942f0ffffffffffff3f20097d221042ffffffffffffff0383200d4233887c85200a8320098522093703f01d2002200c200b42ffffffffffffff038320104233887c85200a83200c85220a3703f81d20024198046a200229038805221b20022903a8097c220c20022903f8067c220b20022903f8087c220d2002290398097c221020022903980822252002290388097c221220022903e8057c22132002290388077c221420022903e8087c221520022903e807222620022903d8087c221720022903a8087c221820022903c8067c22192002290398077c221a20022903c807222720022903a8077c221c20022903f8077c221d20022903b8087c221e20022903d8067c221f20022903b807222820022903e8067c220e20022903d8077c220f2002290388087c221120022903c8087c2216423388200241b8076a41086a290300200241e8066a41086a2903007c200e202854ad7c200241d8076a41086a2903007c200f200e54ad7c20024188086a41086a2903007c2011200f54ad7c200241c8086a41086a2903007c2016201154ad7c420d86847c220e423388200241c8076a41086a290300200241a8076a41086a2903007c201c202754ad7c200241f8076a41086a2903007c201d201c54ad7c200241b8086a41086a2903007c201e201d54ad7c200241d8066a41086a2903007c201f201e54ad7c200e201f54ad7c420d86847c221c423388200241e8076a41086a290300200241d8086a41086a2903007c2017202654ad7c200241a8086a41086a2903007c2018201754ad7c200241c8066a41086a2903007c2019201854ad7c20024198076a41086a2903007c201a201954ad7c201c201a54ad7c420d86847c221742338820024198086a41086a29030020024188096a41086a2903007c2012202554ad7c200241e8056a41086a2903007c2013201254ad7c20024188076a41086a2903007c2014201354ad7c200241e8086a41086a2903007c2015201454ad7c2017201554ad7c420d86847c221842338820024188056a41086a290300200241a8096a41086a2903007c200c201b54ad7c200241f8066a41086a2903007c200b200c54ad7c200241f8086a41086a2903007c200d200b54ad7c20024198096a41086a2903007c2010200d54ad7c2018201054ad7c420d868442137e201642ffffffffffffff03837c221042ffffffffffffff0383220c420020022903f01c220b420010e808200241e8046a20022903901d220d42002010423388200e42ffffffffffffff03837c221042137e420010e80820024188066a20022903881d22124200201c42ffffffffffffff0383221542137e221c420010e808200241b8056a20022903801d22134200201742ffffffffffffff0383221942137e221a420010e808200241c8036a20022903f81c22144200201842ffffffffffffff0383221842137e2217420010e80820024188046a20144200200c420010e808200241d8046a200b42002010420010e808200241f8056a200d4200201c420010e808200241a8056a20124200201a420010e808200241b8036a201342002017420010e808200241f8036a20134200200c420010e808200241c8046a201442002010420010e80820024198066a200b42002015420010e80820024198056a200d4200201a420010e808200241a8036a201242002017420010e808200241e8036a20124200200c420010e808200241b8046a201342002010420010e808200241a8066a201442002015420010e808200241c8056a200b42002019420010e808200241c8026a200d42002017420010e808200241d8036a200d4200200c420010e808200241a8046a201242002010420010e808200241b8066a201342002015420010e808200241d8056a201442002019420010e808200241f8046a200b42002018420010e8082002200229039805221c2002290398067c220c20022903a8037c220b20022903f8037c221020022903c8047c221220022903f805221d20022903d8047c220d20022903a8057c221320022903b8037c22142002290388047c221520022903e804221e2002290398047c22172002290388067c221820022903b8057c221920022903c8037c221a423388200241e8046a41086a29030020024198046a41086a2903007c2017201e54ad7c20024188066a41086a2903007c2018201754ad7c200241b8056a41086a2903007c2019201854ad7c200241c8036a41086a2903007c201a201954ad7c420d86847c2217423388200241f8056a41086a290300200241d8046a41086a2903007c200d201d54ad7c200241a8056a41086a2903007c2013200d54ad7c200241b8036a41086a2903007c2014201354ad7c20024188046a41086a2903007c2015201454ad7c2017201554ad7c420d86847c221342ffffffffffffff0383220d3703a01e200220022903c802221d20022903c8057c221420022903e8037c221520022903b8047c221820022903a8067c2219201342338820024198056a41086a29030020024198066a41086a2903007c200c201c54ad7c200241a8036a41086a2903007c200b200c54ad7c200241f8036a41086a2903007c2010200b54ad7c200241c8046a41086a2903007c2012201054ad7c2013201254ad7c420d86847c220c42ffffffffffffff038322103703a81e200220022903d803221e20022903f8047c220b20022903a8047c221220022903b8067c221320022903d8057c221c200c423388200241c8026a41086a290300200241c8056a41086a2903007c2014201d54ad7c200241e8036a41086a2903007c2015201454ad7c200241b8046a41086a2903007c2018201554ad7c200241a8066a41086a2903007c2019201854ad7c200c201954ad7c420d86847c220c42ffffffffffffff038322143703b01e2002200c423388200241d8036a41086a290300200241f8046a41086a2903007c200b201e54ad7c200241a8046a41086a2903007c2012200b54ad7c200241b8066a41086a2903007c2013201254ad7c200241d8056a41086a2903007c201c201354ad7c200c201c54ad7c420d868442137e201a42ffffffffffffff03837c220b42ffffffffffffff0383220c3703901e2002200b423388201742ffffffffffffff03837c220b3703981e20024188016a200c42002008420010e808200241d8016a20064200200b42137e420010e808200241e8026a20074200200d42137e2215420010e80820024188026a200a4200201042137e2213420010e808200241386a20094200201442137e2212420010e808200241f8006a20094200200c420010e808200241c8016a20084200200b420010e808200241d8026a200642002015420010e808200241f8016a200742002013420010e808200241286a200a42002012420010e808200241e8006a200a4200200c420010e808200241b8016a20094200200b420010e808200241f8026a20084200200d420010e808200241e8016a200642002013420010e808200241186a200742002012420010e808200241d8006a20074200200c420010e808200241a8016a200a4200200b420010e80820024188036a20094200200d420010e80820024198026a200842002010420010e808200241086a200642002012420010e808200241c8006a20064200200c420010e80820024198016a20074200200b420010e80820024198036a200a4200200d420010e808200241a8026a200942002010420010e808200241b8026a200842002014420010e808200220022903e801221520022903f8027c220620022903187c220720022903687c220820022903b8017c220920022903d802221720022903c8017c220a20022903f8017c220c20022903287c220b20022903787c220d20022903d80122182002290388017c221020022903e8027c22122002290388027c221320022903387c2214423388200241d8016a41086a29030020024188016a41086a2903007c2010201854ad7c200241e8026a41086a2903007c2012201054ad7c20024188026a41086a2903007c2013201254ad7c200241386a41086a2903007c2014201354ad7c420d86847c2210423388200241d8026a41086a290300200241c8016a41086a2903007c200a201754ad7c200241f8016a41086a2903007c200c200a54ad7c200241286a41086a2903007c200b200c54ad7c200241f8006a41086a2903007c200d200b54ad7c2010200d54ad7c420d86847c220a42ffffffffffffff03833703b81f2002200229030822132002290398027c220c20022903587c220b20022903a8017c220d2002290388037c2212200a423388200241e8016a41086a290300200241f8026a41086a2903007c2006201554ad7c200241186a41086a2903007c2007200654ad7c200241e8006a41086a2903007c2008200754ad7c200241b8016a41086a2903007c2009200854ad7c200a200954ad7c420d86847c220642ffffffffffffff03833703c01f20022002290348221520022903b8027c22072002290398017c22082002290398037c220920022903a8027c220a2006423388200241086a41086a29030020024198026a41086a2903007c200c201354ad7c200241d8006a41086a2903007c200b200c54ad7c200241a8016a41086a2903007c200d200b54ad7c20024188036a41086a2903007c2012200d54ad7c2006201254ad7c420d86847c220642ffffffffffffff03833703c81f20022006423388200241c8006a41086a290300200241b8026a41086a2903007c2007201554ad7c20024198016a41086a2903007c2008200754ad7c20024198036a41086a2903007c2009200854ad7c200241a8026a41086a2903007c200a200954ad7c2006200a54ad7c420d868442137e201442ffffffffffffff03837c220642ffffffffffffff03833703a81f20022006423388201042ffffffffffffff03837c3703b01f4200210602402029450d00200241881f6a200241a81f6a106b4200210620022d00881f410171106d41ff01714101460d00200241d01e6a4200370300200241c81e6a4200370300200241c01e6a4200370300200242003703b81e200241881f6a200241901e6a106b200241b81e6a4101722129410021054100210341012104024003402005200241881f6a20036a2d0000732205410020056b72417f7341800171410776106d20047121042003411f460d01202920036a2d00002105200341016a21030c000b0b420021062004106d41ff01714101460d00200241b81e6a41206a200241e81d6a41206a290300370300200241b81e6a41186a200241e81d6a41186a290300370300200241b81e6a41106a200241e81d6a41106a290300370300200241b81e6a41086a200241e81d6a41086a290300370300200241e81e6a200241901e6a41086a290300370300200241f01e6a200241901e6a41106a290300370300200241f81e6a200241901e6a41186a290300370300200241801f6a200241901e6a41206a290300370300200220022903e81d3703b81e200220022903901e3703e01e200241881b6a41206a200241a81f6a41206a290300370300200241881b6a41186a200241a81f6a41186a290300370300200241881b6a41106a200241a81f6a41106a290300370300200241881b6a41086a200241a81f6a41086a290300370300200220022903a81f3703881b200241b01b6a200241b81e6a41d00010e9081a420121060b200241b81e6a210320064200520d010b200241b01a6a410f6a2003410f6a290000370000200241b01a6a41086a200341086a290000370300200220032900003703b01a200241b5196a200241b01a6a41d30010e9081a41012103200041013a0004200020022900b5193700052000410d6a200241b5196a41086a290000370000200041146a200241b5196a410f6a2900003700000c010b200241b01a6a41036a200241b01b6a41d00010e9081a200241881a6a41206a2203200241881b6a41206a290300370300200241881a6a41186a2204200241881b6a41186a290300370300200241881a6a41106a2205200241881b6a41106a290300370300200241881a6a41086a2229200241881b6a41086a290300370300200220022903881b3703881a200241b5196a200241b01a6a41d30010e9081a20024188196a41206a222a200329030037030020024188196a41186a2203200429030037030020024188196a41106a2204200529030037030020024188196a41086a22052029290300370300200220022903881a37038819200041086a200241b5196a41036a41d00010e9081a200041e0006a4200370300200041d8006a4201370300200041e8006a4200370300200041f0006a4200370300200041f8006a420037030020004180016a20022903881937000020004188016a200529030037000020004190016a200429030037000020004198016a2003290300370000200041a0016a202a290300370000200041a8016a2001290000370000200041b0016a200141086a290000370000200041b8016a200141106a290000370000200041c0016a200141186a290000370000410021030b20002003360200200241d01f6a24000bd60101027f230041106b2202240002400240024002400240024020002d00000e050001020304050b200241003a000f20012002410f6a410110742001200041016a412010740c040b200241013a000f20012002410f6a410110740c030b200241023a000f20012002410f6a41011074200041046a28020021032000410c6a28020022002001107620012003200010740c020b200241033a000f20012002410f6a410110742001200041016a412010740c010b200241043a000f20012002410f6a410110742001200041016a411410740b200241106a24000bb40201067f230041106b22022400024002402001280200220328020422044104490d0020032802002205280000210620032004417c6a3602042003200541046a3602002002200110e8010240024020022802002203450d00200241086a2802002105200228020421042001280200220128020422074104490d012000200436020820002003360204200020063602002000410c6a200536020020012802002203280000210420012007417c6a3602042001200341046a360200200041106a20043602000c030b200041003602040c020b2000410036020402402005450d002005410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b2004450d012004410c6c450d012003102e0c010b200041003602040b200241106a24000baa0201067f230041106b2202240002400240200128020422034104490d0020012802002204280000210520012003417c6a3602042001200441046a3602002002200110e3010240024020022802002203450d00200241086a280200210620022802042104200128020422074104490d012000200436020820002003360204200020053602002000410c6a200636020020012802002203280000210420012007417c6a3602042001200341046a360200200041106a20043602000c030b200041003602040c020b2000410036020402402006450d002006410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b2004450d012004410c6c450d012003102e0c010b200041003602040b200241106a24000bd007020e7f047e230041b0046b22022400200128020c2103200128020821042001280204210520012802002106200241286a200010f901200241e0016a200228022822002002280230220710fa01200241f0036a41086a2208200241e0016a41086a290300370300200241f0036a41106a2209200241e0016a41106a290300370300200241f0036a41186a220a200241e0016a41186a290300370300200241f0036a41206a220b200241e0016a41206a290300370300200241f0036a41286a220c200241e0016a41286a290300370300200241f0036a41306a220d200241e0016a41306a290300370300200241f0036a41386a220e200241e0016a41386a290300370300200220022903e0013703f00320022d00a002210120024188036a200241e0016a41c1006a41e70010e9081a02402001410646220f0d00200241386a41386a200e290300370300200241386a41306a200d290300370300200241386a41286a200c290300370300200241386a41206a200b290300370300200241386a41186a200a290300370300200241386a41106a2009290300370300200241386a41086a2008290300370300200220022903f003370338200241386a41c1006a20024188036a41e70010e9081a0b200220013a0078410021010240200f0d0002402006280200220f290300221020022903382211542206200f41086a2903002212200241386a41086a220829030022135420122013511b0d00200f201020117d370300200f201220137d2006ad7d370308200241023a0078200241186a200241c0016a2002290368200241f0006a29030010fb012005280200210f20042802002106200242f0f2bda1a7ee9cb9f9003703f00320022006360290032002410236028c03200241e2b8c00036028803200241e0016a200241f0036a20024188036a10fc01200241086a200241e0016a2002290338200829030010fd01200f427f200f290300221220022903087c221320132012542206200f41086a22082903002212200241086a41086a2903007c2006ad7c221320125420132012511b22061b3703002008427f201320061b370300200241ec016a2004280200360200200241e0016a41086a41023a0000200241153a00e001200241e0016a10fe010c010b41012101200328020041013a00000b200241e0016a200241386a41a80110e9081a0240024020022d00a0024106470d002000200710ff010c010b20024100360290032002420137038803200241e0016a20024188036a10800220002007200228028803220f20022802900310b201200228028c03450d00200f102e0b0240200228022c450d002000102e0b200241b0046a240020010b870201037f230041d0006b22022400200241086a41bad7c7004108108102200241186a419dfec6004108108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000bd41205047f067e017f027e0a7f230041a0026b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822010d00200041063a00400c010b200328020c21042003200341086a41086a28020036026c20032001360268200341186a200341e8006a109301024002400240024020032d00184101460d0020034190016a200341316a290000370300200341f8006a41106a200341296a290000370300200341f8006a41086a200341216a29000037030020032003290019370378200328026c22024110490d0020032003280268220541106a3602682003200241706a220636026c20064110490d00200541086a2900002107200529000021082003200541206a3602682003200241606a220636026c20064110490d00200541186a29000021092005290010210a2003200541306a3602682003200241506a220636026c20064110490d00200541286a290000210b2005290020210c2003200241406a220d36026c2003200541c0006a2206360268200d450d00200541386a290000210e2005290030210f2003200241bf7f6a36026c2003200641016a36026841002102024002400240024020062d00000e06060500010203040b410221020c050b200341186a200341e8006a10930120032d00184101460d02200341b8016a41186a200341316a290000370300200341b8016a41106a200341296a290000370300200341b8016a41086a200341216a290000370300200341b4016a41026a200341d8016a41026a2d00003a000020034198016a41086a200341f8016a41086a29000037030020034198016a41106a200341f8016a41106a29000037030020034198016a41186a200341f8016a41186a280000360200200320032900193703b801200320032f00d8013b01b401200320032900f80137039801410321020c040b200341186a200341e8006a10930120032d00184101460d01200341f8016a41186a2205200341316a290000370300200341f8016a41106a2206200341296a290000370300200341f8016a41086a220d200341216a290000370300200320032900193703f80141042102200328026c22104104490d01200341b8016a41086a200d290300370300200341b8016a41106a2006290300370300200341b8016a41186a2005290300370300200341b4016a41026a2003419c026a41026a2d00003a0000200320032903f8013703b80120032802682205280000210d20032010417c6a36026c2003200541046a360268200320032f009c023b01b40120034198016a41186a200341d8016a41186a28020036020020034198016a41106a200341d8016a41106a29020037030020034198016a41086a200341d8016a41086a290200370300200320032902d801370398010c030b200341186a200341e8006a10930120032d00184101460d00200341f8016a41186a200341316a290000370300200341f8016a41106a200341296a290000370300200341f8016a41086a200341216a290000370300200320032900193703f801200341186a200341e8006a10930120032d00184101460d002003419c026a41026a220220032d001b3a0000200341d8016a41086a200341186a41106a290300370300200341d8016a41106a200341186a41186a290300370300200341d8016a41186a200341386a2d00003a0000200320032f00193b019c022003200341186a41086a2903003703d801200328026c22064104490d00200328021c210d200341b8016a41086a200341f8016a41086a290300370300200341b8016a41106a200341f8016a41106a290300370300200341b8016a41186a200341f8016a41186a290300370300200341b4016a41026a20022d00003a000020034198016a41186a200341d8016a41186a2d00003a000020034198016a41106a200341d8016a41106a29030037030020034198016a41086a200341d8016a41086a290300370300200320032903f8013703b801200320032f019c023b01b401200320032903d8013703980120032802682202280000210520032006417c6a36026c2003200241046a360268200341b3016a200341f5016a41026a2d00003a0000200320032f00f5013b00b101410521020c020b20034100360220200342013703182003410a3602fc01200320033602f8012003200341186a3602b801200341d4006a410136020020034201370244200341909dc5003602402003200341f8016a360250200341b8016a419cebc000200341c0006a103d1a2003280218200328022010ef020240200328021c450d002003280218102e0b410621020c020b410121020b200341c0006a41186a2206200341b8016a41186a290300370300200341c0006a41106a2210200341b8016a41106a290300370300200341c0006a41086a2211200341b8016a41086a290300370300200341f4006a41026a2212200341b4016a41026a2d00003a0000200341d8016a41086a221320034198016a41086a290300370300200341d8016a41106a221420034198016a41106a290300370300200341d8016a41186a221520034198016a41186a280200360200200320032903b801370340200320032f01b4013b017420032003290398013703d801200341f8016a41086a2216200341f8006a41086a290300370300200341f8016a41106a2217200341f8006a41106a290300370300200341f8016a41186a2218200341f8006a41186a290300370300200341e2006a20122d00003a0000200320032903783703f801200320032f01743b0160200041386a200e3703002000200f370330200041286a200b3703002000200c370320200041186a20093703002000200a3703102000200737030820002008370300200341186a411f6a2212200341c0006a411f6a280000360000200341186a41186a22192006290300370300200341186a41106a22062010290300370300200341186a41086a2210201129030037030020032003290340370318200041e4006a200d360000200041e0006a2012280000360000200041d9006a2019290300370000200041d1006a2006290300370000200041c9006a201029030037000020002003290318370041200041e8006a20032903d801370000200041f0006a2013290300370000200041f8006a201429030037000020004180016a201528020036000020004184016a2005360000200041a0016a201829030037000020004198016a201729030037000020004190016a201629030037000020004188016a20032903f8013700000b200020023a00402004450d002001102e0b200341a0026a24000bf21104027f097e047f087e230041d0026b2204240002400240200220038450450d0042002102420021030c010b200441f0006a200110c802200441d0016a20042802702205200428027810c902200441f0016a2903002106200441e8016a2903002107200441e0016a290300210820042903d801210920042903d001210a02402004280274450d002005102e0b200a4201520d002009200784200820068484500d00200441f0006a200110c802200441d0016a20042802702205200428027810c902200441d0016a41386a290300210b200441d0016a41306a2903002107200441d0016a41286a2903002108200441d0016a41206a290300210c200441d0016a41186a290300210d200441d0016a41106a290300210a20044190026a290300210e20042903d801210620042903d0012109200441206a41086a200441a0026a290300370300200420044198026a2903003703200240024020094201510d004200210e200441306a41386a4200370300200441306a41306a4200370300200441306a41286a4200370300200441306a41206a4200370300200441306a41186a4200370300200441306a41106a4200370300200441306a41086a4200370300200442003703304200210842002107420021064200210a0c010b200441306a41286a2007370300200441306a41306a200b37030020042008370350200420063703302004200e3703682004200d3703402004200a3703382004200c3703480b02402004280274450d002005102e0b024002402006200a844200520d0020082004290340842007200441c8006a29030084844200520d002004290360200441e8006a2903008450450d004200210d410021050c010b200441c0006a2903002106200441e0006a290300210c200441d8006a2903002108200441d0006a290300210b20042903382107200429033021094201210d2004290348210a410121050b0240200d420152220f450d004200210b420021084200210c4200210e420021064200210a42002109420021070b200441f8016a2210200837030020044180026a2211200c370300200441e8016a200a2003200a2006200256200a200356200a2003511b22121b22087d20062002200620121b220a54ad7d220d3703002004200b3703f00120042006200a7d22133703e0012004427f200720087c2009200a7c220b2009542212ad7c22062012200620075420062007511b22121b22063703d8012004427f200b20121b22073703d001200fad210b02400240427f200720137c22092009200754220f2006200d7c200fad7c220920065420092006511b220f1b220c42ffc7afa02556427f2009200f1b22094200522009501b0d0020072013842006200d8484220d50210f42002113200d420052ad210d0c010b2011290300211420102903002115200441f0016a2903002116200441e0016a290300211720042903e801211820042903d801211920042903d001211a420121134200210d4101210f0b200441a8016a200837030020044198016a200937030020044190016a2212200c37030020044180016a20063703002004200a3703a001200420073703782004200d370388012004200b37037002400240024020052013420152720d00200420013602d0012001200441d0016a10bd060c010b0240200541017322052013420151720d00200420013602d0012001200441d0016a10be0641ff017122054103460d01024020050e03030200030b200f0d03200420123602d001200441d0016a10cc020c030b20134201522005710d010b200441b0016a200110c802200441d0016a20042802b001220520042802b801220f10c90220042903d001210a200441206a41086a2212200441a0026a290300370300200420044198026a29030037032002400240200a4201510d00200441c0016a41086a4200370300200442003703c0010c010b200441c0016a41086a2012290300370300200420042903203703c0010b024020134201510d004200211a420021194200211642002115420021144200210e42002117420021180b20044180026a2015370300200441d0016a41286a2016370300200441f0016a2018370300200441e8016a2017370300200441d0016a41106a201937030020044190026a200e37030020044198026a20042903c001370300200441d0016a41386a2014370300200441a0026a200441c0016a41086a2903003703002004201a3703d801200442013703d0012005200f200441d0016a41086a10c805024020042802b401450d002005102e0b200441f0006a41106a2903002106200441f0006a41286a2903002109200441f0006a41386a290300210820042903782107200429039001210c20042903a001210a2004290370210b200429038801210d0b0240200b4201520d0020044188026a200637030020044180026a2007370300200441d0016a41086a41003a0000200441d9016a2001290000370000200441e1016a200141086a290000370000200441e9016a200141106a290000370000200441f1016a200141186a290000370000200441033a00d001200441d0016a10fe010b02400240200d50450d00420021060c010b200441d0016a41186a200141186a290000370300200441d0016a41106a200141106a290000370300200441d0016a41086a200141086a290000370300200420012900003703d001420121060b200441186a200441d0016a41186a22052903002207370300200441106a200441d0016a41106a220f290300220b370300200441086a200441d0016a41086a2212290300220d370300200420042903d001220e37030020044180026a22102009370300200441f8016a2211200c370300200f200d3703002005200b370300200441f0016a2007370300200420063703d0012004200e3703d801200441d0016a10d204024020042903d001500d0020042011360270200441f0006a10cc020b20044188026a20083703002010200a370300201241063a0000200441d9016a2001290000370000200441e1016a200141086a290000370000200441e9016a200141106a290000370000200441f1016a200141186a290000370000200441033a00d001200320087d2002200a54ad7d21032002200a7d2102200441d0016a10fe010b2000200237030020002003370308200441d0026a24000b930301037f230041e0006b22032400200341c0006a200241086a2802003602002003200229020037033820032001360230200341edde91e30636023402400240200341306a410c6a2802002204410c6a2202417f4c0d000240024020020d00410121050c010b2002102c2205450d020b200341003602502003200236024c20032005360248200341c8006a200341306a41047241041074200341c8006a200141081074200328023821022004200341c8006a1076200341c8006a2002200410742003200341c0006a280200360208200341c8006a200341086a41041074200328024821022003200328025036025c20032002360258200341086a200341d8006a10d0040240200328024c450d002002102e0b0240024020032d00084101470d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002003290009370000200041186a200341216a290000370000200041106a200341196a290000370000200041086a200341116a2900003700000b200341e0006a24000f0b1038000b1036000b9c1005027f0c7e017f047e017f230041d0026b22042400024002402002200384500d00200441e0006a200110c802200441d0016a20042802602205200428026810c902200441d0016a41386a2903002106200441d0016a41306a2903002107200441d0016a41286a2903002108200441d0016a41206a2903002109200441d0016a41186a290300210a200441d0016a41106a290300210b20044190026a290300210c20042903d801210d20042903d001210e200441a0016a41086a200441a0026a290300370300200420044198026a2903003703a00102400240200e4201510d004200210c200441206a41386a4200370300200441206a41306a4200370300200441206a41286a4200370300200441206a41206a4200370300200441206a41186a4200370300200441206a41106a4200370300200441206a41086a420037030020044200370320420021094200210842002107420021064200210d4200210b4200210a4200210f420021104200210e420021110c010b200441206a41206a2008370300200441206a41286a2007370300200441206a41106a200a370300200441206a41306a2006370300200420093703382004200d3703202004200c3703582004200b3703282008210f20072110200d210e200b21110b02402004280264450d002005102e0b02400240200e2011844200520d00200f2004290330842010200441386a29030084844200520d002004290350200441d8006a2903008450450d004200210e410021120c010b4201210e410121120b0240200e4201510d004200210a4200210c420021094200210842002107420021064200210d4200210b0b0240200e4201510d0020024280c8afa0255441002003501b0d010b200441f0016a2008370300200441f8016a200737030020044180026a2006370300200420093703e8012004200a3703e0012004200b200b20037c200d20027c220f200d542205ad7c221120052011200b542011200b511b22051b22113703d8012004200d200f20051b220d3703d0014200210f4200200320051b21034200200220051b210b42012110200e420152ad211302400240427f200d200a7c22022002200d542205201120097c2005ad7c220220115420022011511b22051b221442ffc7afa02556427f200220051b22024200522002501b0d00200d200a84201120098484220a50210542002110200a420052ad210f0c010b200441e0016a290300211520042903d801211620042903d001210a410121050b20044198016a200337030020044188016a200237030020044180016a22172014370300200441f0006a20113703002004200b370390012004200d3703682004200f3703782004201337036002400240024002400240024020122010420152720d00200420013602d0012001200441d0016a10bd060c010b0240201241017322122010420151720d00200420013602d0012001200441d0016a10be0641ff017122124103460d01024020120e03030200030b20044190016a2101024020050d00200420173602d001200441d0016a10cc020b200420013602d001200441d0016a10ce020c060b20104201522012710d020b200441b0016a200110c802200441d0016a20042802b001221220042802b801221710c90220042903d001210b200441a0016a41086a2205200441a0026a290300370300200420044198026a2903003703a00102400240200b4201510d00200441c0016a41086a4200370300200442003703c0010c010b200441c0016a41086a2005290300370300200420042903a0013703c0010b20044198026a20042903c001370300200441a0026a200441c0016a41086a290300370300200442013703d001200441d0016a41386a20064200201042015122051b37030020044180026a2007420020051b370300200441d0016a41286a2008420020051b370300200441f0016a2009420020051b370300200441e8016a2015420020051b370300200441d0016a41106a2016420020051b37030020044190026a200c420020051b3703002004200a420020051b3703d80120122017200441d0016a41086a10c805024020042802b401450d002012102e0b20042903602209428080808070832107200441e0006a41106a2903002111200441e0006a41286a2903002102200441e0006a41386a29030021032004290368210d2004290380012114200429039001210b2004290378210f0c030b200e420152ad21090c010b200e420152ad21090b420021070b02402007200942ffffffff0f83844201520d0020044188026a201137030020044180026a200d370300200441d0016a41086a41003a0000200441d9016a2001290000370000200441e1016a200141086a290000370000200441e9016a200141106a290000370000200441f1016a200141186a290000370000200441033a00d001200441d0016a10fe010b02400240200f50450d004200210d0c010b200441d0016a41186a200141186a290000370300200441d0016a41106a200141106a290000370300200441d0016a41086a200141086a290000370300200420012900003703d0014201210d0b200441186a200441d0016a41186a22012903002209370300200441106a200441d0016a41106a22052903002207370300200441086a200441d0016a41086a2903002208370300200420042903d001220a37030020044180026a2002370300200441f8016a221220143703002005200837030020012007370300200441f0016a20093703002004200d3703d0012004200a3703d801200441d0016a10d20420042903d001500d0120042012360260200441e0006a10cc020c010b4200210b420021030b2000200b37030020002003370308200441d0026a24000bfe0a010c7f23004180026b22012400200141c0016a22024200370300200141b8016a22034200370300200141a8016a41086a22044200370300200142003703a801200141c8016a41d9fcc60041061081022004200141c8016a41086a2205290000370300200120012900c8013703a801200141c8016a4180f4cb00410610810220022005290000370300200320012900c801370300200141086a200141a8016a4120108e02024002402001280208450d00200128020c450d00200141c0016a22064200370300200141b8016a22074200370300200141a8016a41086a22024200370300200142003703a801200141c8016a41d9fcc60041061081022002200141c8016a41086a2204290000370300200120012900c8013703a801200141c8016a41e8f7cb00410e108102200341086a22082004290000370000200320012900c801370000200141203602dc012001200141a8016a3602d801200141f0016a200141a8016a412010ed020240024020012802f00122090d00410321050c010b200141f0016a41086a280200210a20012802f401210b200141003a00c801024002400240200a450d00410121050240024020092d00000e03000401020b200a417f6a4104490d012009280001210c410021050c030b410221050c010b200141003602d001200142013703c8012001410a3602e4012001200141d8016a3602e0012001200141c8016a3602ec01200141246a410136020020014201370214200141909dc5003602102001200141e0016a360220200141ec016a419cebc000200141106a103d1a20012802c80120012802d00110ef02024020012802cc01450d0020012802c801102e0b410321050b0b200b450d002009102e0b200141106a200041800110e9081a200141a0016a410036020020014194016a200c360200200142013703980120014102200520054103461b220536029001200642003703002007420037030020024200370300200142003703a801200141c8016a41d9fcc600410610810220022004290000370300200120012900c8013703a801200141c8016a41a4f5cb00410a10810220082004290000370000200320012900c8013700002001200141a8016a4120108e020240024002402001280204410020012802001b220241016a22002002490d0020014198016a210c200141c0016a22064200370300200141b8016a22074200370300200141a8016a41086a22044200370300200142003703a801200141c8016a41d9fcc60041061081022004200141c8016a41086a2202290000370300200120012900c8013703a801200141c8016a41a4f5cb00410a108102200341086a22082002290000370000200320012900c801370000200120003602c801200141a8016a4120200141c8016a410410b201200642003703002007420037030020044200370300200142003703a801200141c8016a41d9fcc600410610810220042002290000370300200120012900c8013703a801200141c8016a41e0f4cb00410610810220082002290000370000200320012900c801370000200141003602f801200142013703f0010240024020050e03030001040b200141013a00c801200141f0016a200141c8016a410110740c030b200141023a00c801200141f0016a200141c8016a410110740c020b200141106a10c008200128029c0141ffffff3f71450d03200128029801102e0c030b200141003a00c801200141f0016a200141c8016a4101107420012001280294013602c801200141f0016a200141c8016a410410740b200141106a200141f0016a109c06200c200141f0016a10b8012002200141f0016a41086a280200360200200120012903f0013703c801200141a8016a4120200141c8016a10c702200141106a10c008200128029c0141ffffff3f71450d01200128029801102e0c010b200010c0080b20014180026a24000b0e002001ad4220862000ad8410210b910302017f017e230041106b22022400200120004188016a41201074200029030021032002200041086a290300370308200220033703002001200241101074200029031021032002200041186a290300370308200220033703002001200241101074200029032021032002200041286a290300370308200220033703002001200241101074200029033021032002200041386a290300370308200220033703002001200241101074024002400240024002400240024020002d00400e06000102030405060b200241003a000020012002410110740c050b200241013a000020012002410110740c040b200241023a000020012002410110740c030b200241033a000020012002410110742001200041c1006a412010740c020b200241043a000020012002410110742001200041c1006a412010742002200041e4006a28020036020020012002410410740c010b200241053a000020012002410110742001200041c1006a412010742001200041e1006a41201074200220004184016a28020036020020012002410410740b200241106a24000b2c0020002002ad4220862001ad8410122201290000370000200041086a200141086a2900003700002001102e0ba10606057f017e027f017e027f017e230041206b2202240002400240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020002400240200641037122034103460d00024002400240024020030e03000102000b2006410276ad21070c020b200128020022012802042203450d04200128020022042d0000210520012003417f6a360204410121032001200441016a3602002005410874200672220141ffff0371418002490d03200141fcff0371410276ad21070c010b410121032001280200220128020422044103490d022001280200220541026a2d0000210820052f000021092001200541036a36020020012004417d6a3602042009200841107472410874200672220141808004490d022001410276ad21070b4200210a410021030c030b02400240024002402006410276220b0e0d00030303010303030303030302030b2001280200220328020422014104490d0420032802002206350000210720032001417c6a3602042003200641046a36020020074280808080045421034200210a0c050b2001280200220328020422014108490d032003280200220629000021072003200141786a3602042003200641086a3602002007428080808080808080015421034200210a0c040b2001280200220328020422014110490d022003280200220641086a290000210a200629000021072003200641106a3602002003200141706a360204200a428080808080808080015421030c030b200641334b0d01200b41046a21094100210441012103200241186a210c420021074200210a0340200128020022062802042205450d0120062802002208310000210d20062005417f6a3602042006200841016a360200200241106a200d4200200441037441f8007110ed08200c290300200a84210a20022903102007842107200441016a22062104200641ff01712009490d000b2002427f427f41e800200b4103746b41f8007110e4082007200229030058200a200241086a290300220d58200a200d511b21030c020b0c010b410121030b20002007370308200041106a200a37030020002003ad370300200241206a24000b130020004109360204200041a8b9c0003602000b3400200041bad7c70036020420004100360200200041146a4104360200200041106a41b8d6c000360200200041086a42083702000b4201027f230041106b2202240002404104102c22030d001036000b20004204370204200020033602002002410036020c20002002410c6a41041074200241106a24000b130020004107360204200041a4dcc0003602000b4401027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241a0c21e36020c20002002410c6a41041074200241106a24000b4501027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241808dcf0036020c20002002410c6a41041074200241106a24000b4401027f230041106b2202240002404104102c22030d001036000b200042043702042000200336020020024180840736020c20002002410c6a41041074200241106a24000be92007017f027e027f017e067f027e027f230041f0126b2202240042022103024002400240024002400240200129036822044202520d00200241106a20014198016a41b00210e9081a0c010b2002418e036a200141246a41c20010e9081a200241d0036a41086a220520014188016a290300370300200241d0036a41106a220620014190016a290300370300200220014180016a2903003703d003200141f8006a290300210320012903702107200128020821082001280204210920012d0000210a200241d00d6a41026a220b200141036a2d00003a000020024188046a41086a220c200141146a29020037030020024188046a41106a2001411c6a290200370300200220012f00013b01d00d2002200129020c37038804024002400240200a0e03020100010b2008450d002009102e0b200241f8116a41026a200241c8126a41026a2d00003a000020024188086a41086a200241980b6a41086a29030037030020024188086a410d6a200241980b6a410d6a290000370000200220022f01c8123b01f811200220022903980b37038808200041036a41003a0000200041013b0001200041013a000020014198016a108b020c030b200241980b6a410d6a220a20024188046a410d6a290000370000200241980b6a41086a220d200c290300370300200241f8116a41026a220c200b2d00003a000020024188086a41086a220b200d29030037030020024188086a410d6a220d200a290000370000200220022f01d00d3b01f8112002200229038804370388082002200c2d00003a00ea03200220022f01f8113b01e803200220083600ef03200220093600eb03200241e8036a41186a200d290000370000200241e8036a41136a200b29030037000020022002290388083700f303200241d00d6a20014198016a41b00210e9081a20024180106a41106a200629030037030020024180106a41086a2005290300370300200220022903d003370380104100210a200241d8116a4100108c02200241c8126a20022802d811220820022802e011108d0220022d00c8122101200241f8116a41186a2209200241e1126a290000370300200241f8116a41106a200241d9126a290000370300200241f8116a41086a200241d1126a290000370300200220022900c9123703f8110240024020014101460d00200241bd126a4200370000200241b8126a4200370300200241b0126a4200370300200242003703a8120c010b200241b0126a20024183126a290000370300200241a8126a41106a200241f8116a41136a290000370300200241bd126a2009290000370000200220022900fb113703a81220022f01f81120022d00fa1141107472210a0b024020022802dc11450d002008102e0b20024198116a41086a200241a8126a41086a29030037030020024198116a41106a200241a8126a41106a29030037030020024198116a41156a200241a8126a41156a290000370000200220022903a8123703981120024190126a22014200370300200241f8116a41106a22084200370300200241f8116a41086a22094200370300200242003703f811200241c8126a41d9fcc60041061081022009200241c8126a41086a2205290000370300200220022900c8123703f811200241c8126a4180f4cb00410610810220012005290000370300200820022900c812370300200241086a200241f8116a4120108e0241002101024020044201520d0020074200510d04200228020c410020022802081b2108417f210142002008ad220e20037d220f200f200e561b220e20037c200e2007827d220e42ffffffff0f560d00200ea721010b200241c8126a2001108c0220022802c812220920022802d012108f022108024020022802cc12450d002009102e0b2008450d0120024198126a2001108c02200241c8126a200228029812220820022802a012108d0220022d00c812210120024190126a2209200241e1126a290000370300200241f8116a41106a200241d9126a290000370300200241f8116a41086a200241d1126a290000370300200220022900c9123703f8110240024020014101460d00200241bd126a4200370000200241a8126a41106a4200370300200241a8126a41086a4200370300200242003703a812410021010c010b200241a8126a41086a20024183126a290000370300200241a8126a41106a2002418b126a290000370300200241bd126a2009290000370000200220022900fb113703a81220022f01f81120022d00fa114110747221010b0240200228029c12450d002008102e0b200241d8116a41156a2208200241a8126a41156a290000370000200241d8116a41106a2209200241a8126a41106a290300370300200241b8116a41106a22052009290300370300200241b8116a41156a22092008290000370000200241b8116a41086a200241a8126a41086a290300220e370300200241d8106a41086a2208200e370300200241d8106a41106a22062005290300370300200241d8106a41156a22052009290000370000200220022903a812220e3703b8112002200e3703d810200241f8106a41156a220920024198116a41156a290000370000200241f8106a41106a220b20024198116a41106a290300370300200241f8106a41086a220c20024198116a41086a29030037030020022002290398113703f810200241b8106a41156a220d2009290000370000200241b8106a41106a2209200b290300370300200241b8106a41086a220b200c290300370300200220022903f8103703b81020024198106a41156a220c200529000037000020024198106a41106a2205200629030037030020024198106a41086a22062008290300370300200220022903d81037039810200241e00a6a41156a2208200d290000370000200241e00a6a41106a220d2009290300370300200241e00a6a41086a2209200b290300370300200220022903b8103703e00a200241c00a6a41156a220b200c290000370000200241c00a6a41106a220c2005290300370300200241c00a6a41086a2205200629030037030020022002290398103703c00a200241800b6a41106a220620024180106a41106a290300370300200241800b6a41086a221020024180106a41086a29030037030020022002290380103703800b200241980b6a41046a200241d00d6a41b00210e9081a20024188086a200241980b6a41b40210e9081a200241f0076a41106a22112006290300370300200241f0076a41086a22062010290300370300200241d0076a41086a22102009290300370300200241d0076a41106a2209200d290300370300200241d0076a41156a220d2008290000370000200241b0076a41086a22082005290300370300200241b0076a41106a2205200c290300370300200241b0076a41156a220c200b290000370000200220022903800b3703f007200220022903e00a3703d007200220022903c00a3703b00720024188046a20024188086a41046a41b00210e9081a200241f2066a200a4110763a0000200241f0066a200a3b0100200241c8066a2003370300200241c0066a2007370300200241d0066a220a20022903f007370300200241d8066a2006290300370300200241e0066a22062011290300370300200241f3066a20022903d007370000200241fb066a201029030037000020024183076a200929030037000020024188076a200d290000370000200220043703b8062002429e808080f0003703e80620024192076a20014110763a000020024190076a20013b010020024193076a20022903b0073700002002419b076a2008290300370000200241a3076a2005290300370000200241a8076a200c2900003700004108102c2201450d042002420837028c08200220013602880820024188046a20024188086a1090020240024020022903b8064201520d00200220022903c80620022903c0062203420c882204420120044201561b80a741047420037aa7417f6a22014101200141014b1b2201410f2001410f491b723b01980b20024188086a200241980b6a410210740c010b200241003a00980b20024188086a200241980b6a410110740b200620024188086a1091022002200a3602980b200241980b6a20024188086a10af01200220022802e8063602980b20024188086a200241980b6a41041074200220022802ec063602980b20024188086a200241980b6a410410744120102c2201450d042002422037029c0b200220013602980b200241980b6a200241f0066a4120107420024188086a20022802980b220120022802a00b10740240200228029c0b450d002001102e0b4120102c2201450d042002422037029c0b200220013602980b200241980b6a20024190076a4120107420024188086a20022802980b220120022802a00b10740240200228029c0b450d002001102e0b200228028808210102400240200228029008220a418102490d00200241f8116a2001200a10b0012002418e036a200241f8116a4120200241e8036a10920221010c010b2002418e036a2001200a200241e8036a10920221010b0240200228028c08450d00200228028808102e0b024020010d0020004180083b0001200041013a0000200041036a41003a000020024188046a108b020c030b200241e8026a41086a200241e8036a41086a290300370300200241e8026a41106a200241e8036a41106a290300370300200241e8026a41186a200241e8036a41186a290300370300200241c0026a41086a200241c8066a290300370300200241c0026a41106a200241d0066a290300370300200241c0026a41186a200241d8066a290300370300200241e0026a200241e0066a290300370300200220022903e8033703e8022002200241c0066a2903003703c00220022903b8062103200241106a20024188046a41b00210e9081a0b200041086a20022903e802370300200041286a2003370300200041306a20022903c002370300200041206a200241e8026a41186a290300370300200041186a200241e8026a41106a290300370300200041106a200241e8026a41086a290300370300200041386a200241c0026a41086a290300370300200041c0006a200241c0026a41106a290300370300200041c8006a200241c0026a41186a290300370300200041d0006a200241c0026a41206a290300370300200041d8006a200241106a41b00210e9081a200041003a00000c010b200241b8116a41156a200241d8116a41156a290000370000200241b8106a41086a200241f8106a41086a290000370300200241b8106a41106a200241f8106a41106a290000370300200241b8106a41156a200241f8106a41156a29000037000020024198106a41156a200241d8106a41156a290000370000200220022900f8103703b810200241d00d6a108b0220024188086a200241980b6a41b40210e9081a200241f0076a41106a200241800b6a41106a290300370300200241f0076a41086a200241800b6a41086a290300370300200241d0076a41086a200241e00a6a41086a290000370300200241d0076a41106a200241e00a6a41106a290000370300200241d0076a41156a200241e00a6a41156a290000370000200241b0076a41086a200241c00a6a41086a290000370300200241b0076a41106a200241c00a6a41106a290000370300200241b0076a41156a200241c00a6a41156a290000370000200220022903800b3703f007200220022900e00a3703d007200220022900c00a3703b007200041036a41003a0000200041800a3b0001200041013a00000b200241f0126a24000f0b41d0e7cc00411941ece7cc001039000b1036000ba62801047f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002802000e1b00010218180304051806070818090a0b0c0d0e0f10111213141516170b0240024002400240024002400240200041086a2802000e0a1e1e001e01021e030405060b200041106a280200450d1d2000410c6a280200102e0f0b200041106a280200450d1c2000410c6a280200102e0f0b200041106a280200450d1b2000410c6a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141186c210103400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200141686a22010d000b0b200041106a2802002202450d1a200241186c450d1a200028020c102e0f0b0240200041146a2802002201450d002000410c6a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041106a2802002202450d192002410c6c450d19200028020c102e0f0b200041106a280200450d182000410c6a280200102e0f0b200041106a280200450d172000410c6a280200102e0f0b0240024002400240024020002d00040e061b001b010203040b200041186a2202280200108b022002280200102e0f0b02402000410c6a280200450d00200041086a280200102e0b200041246a2202280200108b022002280200102e0f0b2000410c6a280200450d18200041086a280200102e0f0b200041186a2202280200108b022002280200102e0f0b02402000410c6a280200450d00200041086a280200102e0b200041246a2202280200108b022002280200102e0f0b02400240200041086a280200417f6a0e020001170b2000412c6a220110e1010240200041306a2802002202450d00200241246c450d002001280200102e0b2000419c016a220110e1010240200041a0016a2802002202450d00200241246c450d002001280200102e0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d162002410c6c450d162000280210102e0f0b2000412c6a220110e1010240200041306a2802002202450d00200241246c450d002001280200102e0b2000419c016a220110e1010240200041a0016a2802002202450d00200241246c450d002001280200102e0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d152002410c6c450d152000280210102e0f0b0240024002400240200041086a2802000e0418000102030b2000410c6a2d00004102470d17200041146a280200450d17200041106a280200102e0f0b2000410c6a2d00004102470d16200041146a280200450d16200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004102470d15200041386a280200450d15200041346a280200102e0f0b2000410c6a2d00004102470d14200041146a280200450d14200041106a280200102e0f0b02402000410c6a2802002201450d0020002802042202200141f0006c6a21030340024020022204410c6a2802002201450d0020042802042102200141246c210103400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200441f0006a21020240200441086a2802002201450d00200141246c450d002004280204102e0b20022003470d000b0b200041086a2802002202450d13200241f0006c450d132000280204102e0f0b024002400240024002400240200041086a2d00000e171800181818180118180218181818180318180418181818050b2000412c6a2d00004102470d17200041346a280200450d17200041306a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141246c21010340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200041106a2802002202450d16200241246c450d16200028020c102e0f0b2000410c6a2d00004102470d15200041146a280200450d15200041106a280200102e0f0b200041106a28020041ffffff3f71450d142000410c6a280200102e0f0b200041146a28020041ffffffff0371450d13200041106a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141246c21010340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200041106a2802002202450d12200241246c450d12200028020c102e0f0b20002802042202450d11200041086a280200450d112002102e0f0b02400240200041086a280200417f6a0e020001120b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d112002410c6c450d112000280210102e0f0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d102002410c6c450d102000280210102e0f0b02402000410c6a280200450d00200041086a280200102e0b02402000411c6a2802002201450d00200041146a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041186a2802002202450d0f2002410c6c450d0f2000280214102e0f0b0240024002400240200041086a2d000041716a0e0400010203120b200041106a280200450d112000410c6a280200102e0f0b200041106a280200450d102000410c6a280200102e0f0b200041106a280200450d0f2000410c6a280200102e0f0b200041106a280200450d0e2000410c6a280200102e0f0b024002400240200041086a2d0000417f6a0e03000102100b200041306a28020041ffffff3f71450d0f2000412c6a280200102e0f0b2000410c6a2202280200108b022002280200102e0f0b200041106a2202280200108b022002280200102e0f0b024002400240200041086a2d0000417f6a0e030001020f0b200041306a28020041ffffff3f71450d0e2000412c6a280200102e0f0b2000410c6a2202280200108b022002280200102e0f0b200041106a2202280200108b022002280200102e0f0b02400240200041086a2d0000417f6a0e05000d0d0d010d0b200041106a28020041ffffff3f71450d0c2000410c6a280200102e0f0b2000410c6a2d00004102470d0b200041146a280200450d0b200041106a280200102e0f0b20002d00044104470d0a2000410c6a28020041ffffff3f71450d0a200041086a280200102e0f0b200041086a2802004101470d092000410c6a2d00004102470d09200041146a280200450d09200041106a280200102e0f0b02400240200041086a2d0000417d6a0e0200010a0b200041f0006a280200450d09200041ec006a280200102e0f0b200041106a280200450d082000410c6a280200102e0f0b024002400240200041086a2802000e040a0a0001020b2000410c6a2d00004102470d09200041146a280200450d09200041106a280200102e0f0b2000410c6a2d00004102470d08200041146a280200450d08200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004102470d07200041386a280200450d07200041346a280200102e0f0b02400240024020002f01040e03090001020b0240200041106a2802002201450d00200041086a2802002102200141b0026c210103402002109601200241b0026a2102200141d07d6a22010d000b0b2000410c6a2802002202450d08200241b0026c450d082000280208102e0f0b200041086a2202280200108b022002280200102e0f0b0240200041106a2802002201450d00200041086a2802002102200141b0026c210103402002109601200241b0026a2102200141d07d6a22010d000b0b2000410c6a2802002202450d06200241b0026c450d062000280208102e0f0b0240024002400240024002400240200041086a2d0000417e6a0e0d00010c0c0c0c0c0c02030405060c0b0240200041146a2802002201450d002000410c6a2802002202200141c8006c6a21010340024020022d00004101470d00200241086a280200450d00200241046a280200102e0b0240200241246a2d00004101470d002002412c6a280200450d00200241286a280200102e0b200241c8006a22022001470d000b0b0240200041106a2802002202450d00200241c8006c450d00200028020c102e0b0240200041186a2d00004101470d00200041206a280200450d002000411c6a280200102e0b02402000413c6a2d00004101470d00200041c4006a280200450d00200041c0006a280200102e0b0240200041e0006a2d00004101470d00200041e8006a280200450d00200041e4006a280200102e0b024020004184016a2d00004101470d002000418c016a280200450d0020004188016a280200102e0b0240200041a8016a2d00004101470d00200041b0016a280200450d00200041ac016a280200102e0b0240200041cc016a2d00004101470d00200041d4016a280200450d00200041d0016a280200102e0b200041f0016a2d00004101470d0b200041f8016a280200450d0b200041f4016a280200102e0f0b0240200041146a2802002202450d00200241c4006c21012000410c6a28020041286a210203400240200241786a2d00004101470d002002280200450d002002417c6a280200102e0b200241c4006a2102200141bc7f6a22010d000b0b200041106a2802002202450d0a200241c4006c450d0a200028020c102e0f0b200041106a2d00004102470d09200041186a280200450d09200041146a280200102e0f0b2000410c6a2d00004102470d08200041146a280200450d08200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004101470d07200041386a280200450d07200041346a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004101470d06200041386a280200450d06200041346a280200102e0f0b2000410c6a2d00004102470d05200041146a280200450d05200041106a280200102e0f0b20002d00042202417e6a4108490d040240024020020e020600010b200041286a2202280200108b022002280200102e0f0b200041c8006a2202280200108b022002280200102e0f0b0240024002400240200041086a2d00000e0407000102030b0240200041106a28020041ffffff3f71450d002000410c6a280200102e0b200041186a2202280200108b022002280200102e0f0b0240200041106a28020041ffffff3f71450d002000410c6a280200102e0b200041286a280200450d05200041246a280200102e0f0b200041306a28020041ffffff3f71450d042000412c6a280200102e0f0b200041306a28020041ffffff3f71450d032000412c6a280200102e0f0b0240024002400240200041086a2802000e09060006010606020606030b200041106a280200450d052000410c6a280200102e0f0b200041106a2d00004102470d04200041186a280200450d04200041146a280200102e0f0b200041106a2d00004102470d03200041186a280200450d03200041146a280200102e0f0b200041146a280200450d02200041106a280200102e0f0b02400240200041086a2d0000417f6a0e03000301030b200041306a280200450d022000412c6a280200102e0c020b200041306a280200450d012000412c6a280200102e0f0b02402000413c6a28020041ffffffff0171450d00200041386a280200102e0b0240200041c8006a2802002202450d002002410c6c450d00200041c4006a280200102e0b0240200041d4006a28020041ffffffff0071450d00200041d0006a280200102e0b0240200041e0006a2802002202450d00200241146c450d00200041dc006a280200102e0b0240200041ec006a2802002202450d00200241186c450d00200041e8006a280200102e0b0240200041f8006a2802002202450d002002411c6c450d00200041f4006a280200102e0b024020004184016a28020041ffffff3f71450d0020004180016a280200102e0b024020004190016a2802002202450d00200241246c450d002000418c016a280200102e0b02402000419c016a2802002202450d00200241286c450d0020004198016a280200102e0b0240200041a8016a2802002202450d002002412c6c450d00200041a4016a280200102e0b0240200041b4016a2802002202450d00200241306c450d00200041b0016a280200102e0b0240200041c0016a2802002202450d00200241346c450d00200041bc016a280200102e0b0240200041cc016a2802002202450d00200241386c450d00200041c8016a280200102e0b0240200041d8016a2802002202450d002002413c6c450d00200041d4016a280200102e0b0240200041e4016a28020041ffffff1f71450d00200041e0016a280200102e0b200041f0016a2802002202450d00200241c4006c450d00200041ec016a280200102e0f0b0b850201037f230041d0006b22022400200241086a41d9fcc6004106108102200241186a41a0f3cb004109108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000b9d0902047f017e230041b0016b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200041003a00000c010b200341186a280200210220032802142104200341003a0060024002402002450d00200320012d00003a0040200341013a0060024020024101460d00200320012d00013a0041200341023a006020024102460d00200320012d00023a0042200341033a006020024103460d00200320012d00033a0043200341043a006020024104460d00200320012d00043a0044200341053a006020024105460d00200320012d00053a0045200341063a006020024106460d00200320012d00063a0046200341073a006020024107460d00200320012d00073a0047200341083a006020024108460d00200320012d00083a0048200341093a006020024109460d00200320012d00093a00492003410a3a00602002410a460d00200320012d000a3a004a2003410b3a00602002410b460d00200320012d000b3a004b2003410c3a00602002410c460d00200320012d000c3a004c2003410d3a00602002410d460d00200320012d000d3a004d2003410e3a00602002410e460d00200320012d000e3a004e2003410f3a00602002410f460d00200320012d000f3a004f200341103a006020024110460d00200320012d00103a0050200341113a006020024111460d00200320012d00113a0051200341123a006020024112460d00200320012d00123a0052200341133a006020024113460d00200320012d00133a0053200341143a006020024114460d00200320012d00143a0054200341153a006020024115460d00200320012d00153a0055200341163a006020024116460d00200320012d00163a0056200341173a006020024117460d00200320012d00173a0057200341183a006020024118460d00200320012d00183a0058200341193a006020024119460d00200320012d00193a00592003411a3a00602002411a460d00200320012d001a3a005a2003411b3a00602002411b460d00200320012d001b3a005b2003411c3a00602002411c460d00200320012d001c3a005c2003411d3a00602002411d460d00200320012d001d3a005d2003411e3a00602002411e460d00200320012d001e3a005e2003411f3a00602002411f460d00200341206a41106a2202200341c0006a41106a290300370300200341206a41086a2205200341c0006a41086a290300370300200320012d001f3a005f200341206a41186a2206200341c0006a41186a290300370300200341203a006020032003290340220737036820032007370320200041196a2006290300370000200041116a2002290300370000200041096a200529030037000020002003290320370001410121020c020b200341003a00600b20034100360270200342013703682003410a3602242003200341086a3602202003200341e8006a3602ac01200341d4006a410136020020034201370244200341909dc5003602402003200341206a360250200341ac016a419cebc000200341c0006a103d1a2003280268200328027010ef020240200328026c450d002003280268102e0b410021020b200020023a00002004450d002001102e0b200341b0016a24000b840201037f230041d0006b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822040d00410021010c010b200328020c210502400240200341106a2802004104490d0020042800002102410121010c010b4100210120034100360220200342013703182003410a36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341909dc5003602382003200341286a360248200341346a419cebc000200341386a103d1a2003280218200328022010ef020240200328021c450d002003280218102e0b0b2005450d002004102e0b2000200236020420002001360200200341d0006a24000b11002001ad4220862000ad8410244101460bf97002067f017e230041106b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002802000e1c000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c0b200241003a000020012002410110740240024002400240024002400240024002400240200041086a280200417f6a0e0a00010203040506070809250b200241003a0000200120024101107420022000410c6a28020036020020012002410410740c240b200241013a000020012002410110742000410c6a2802002103200041146a28020022002001107620012003200010740c230b200241023a000020012002410110742002200041106a29030037030020012002410810740c220b200241033a000020012002410110742000410c6a2802002103200041146a28020022002001107620012003200010740c210b200241043a000020012002410110742000410c6a2802002103200041146a28020022002001107620012003200010740c200b200241053a0000200120024101107402402000410c6a2802004101460d00200241003a000020012002410110740c200b200241013a000020012002410110742002200041106a28020036020020012002410410742002200041146a28020036020020012002410410740c1f0b200241063a000020012002410110742000410c6a2802002103200041146a2802002200200110762000450d1e2003200041186c6a2104034020032802002100200341086a28020022052001107620012000200510742003410c6a2802002100200341146a2802002205200110762001200020051074200341186a22032004470d000c1f0b0b200241073a000020012002410110742000410c6a2802002103200041146a2802002200200110762000450d1d20032000410c6c6a2104034020032802002100200341086a28020022052001107620012000200510742003410c6a22032004470d000c1e0b0b200241083a000020012002410110742000410c6a2802002103200041146a28020022052001107620012003200510742002200041186a28020036020020012002410410740c1c0b200241093a000020012002410110742000410c6a2802002103200041146a28020022002001107620012003200010740c1b0b200241013a0000200120024101107402400240024002400240024020002d0004417f6a0e06000102030405200b200241003a000020012002410110742002200041086a2802003602002001200241041074024002402000410c6a2802004101460d00200241003a000020012002410110740c010b200241013a000020012002410110742002200041106a28020036020020012002410410742002200041146a28020036020020012002410410740b200220002d00053a00002001200241011074200028021820011090020c1f0b200241013a000020012002410110742002200041086a280200360200200120024104107420022000410c6a28020036020020012002410410740c1e0b200241023a00002001200241011074200041086a2802002103200041106a28020022052001107620012003200510742002200041146a280200360200200120024104107402400240200041186a2802004101460d00200241003a000020012002410110740c010b200241013a0000200120024101107420022000411c6a28020036020020012002410410742002200041206a28020036020020012002410410740b200220002d00053a00002001200241011074200028022420011090020c1d0b200241033a00002001200241011074200041086a2802002103200041106a28020022002001107620012003200010740c1c0b200241043a000020012002410110742002200041086a2802003602002001200241041074024002402000410c6a2802004101460d00200241003a000020012002410110740c010b200241013a000020012002410110742002200041106a28020036020020012002410410742002200041146a28020036020020012002410410740b200220002d00053a00002001200241011074200028021820011090020c1b0b200241053a00002001200241011074200041086a2802002103200041106a28020022052001107620012003200510742002200041146a280200360200200120024104107402400240200041186a2802004101460d00200241003a000020012002410110740c010b200241013a0000200120024101107420022000411c6a28020036020020012002410410742002200041206a28020036020020012002410410740b200220002d00053a00002001200241011074200028022420011090020c1a0b200241023a00002001200241011074024002400240200041086a280200417f6a0e030001021c0b200241003a00002001200241011074200120004188026a412010742002200041206a2903003703002001200241081074200041286a2001108f0620004198016a2001108f0620022000410c6a2802003602002001200241041074200041106a2802002103200041186a28020022052001107602402005450d0020032005410c6c6a2106034020032802002105200341086a28020022042001107620012005200410742003410c6a22032006470d000b0b20022000411c6a28020036020020012002410410740c1b0b200241013a00002001200241011074200120004188026a412010742002200041206a2903003703002001200241081074200041286a2001108f0620004198016a2001108f0620022000410c6a2802003602002001200241041074200041106a2802002103200041186a28020022052001107602402005450d0020032005410c6c6a2106034020032802002105200341086a28020022042001107620012005200410742003410c6a22032006470d000b0b20022000411c6a28020036020020012002410410740c1a0b200241023a00002001200241011074200041106a20011096020c190b200241033a00002001200241011074200241003a00002001200241011074200041086a200110dc040c180b200241043a00002001200241011074200041046a21030240024002400240024020002d0004417f6a0e0500010203041c0b200241003a000020012002410110742002200041086a28020036020020012002410410740c1b0b200241013a000020012002410110742001200341016a412010742002200041286a28020036020020012002410410740c1a0b200241023a000020012002410110742002200041086a28020036020020012002410410740c190b200241033a000020012002410110742001200341016a412010742002200041286a2802003602002001200241041074200220002d00253a000020012002410110740c180b200241043a000020012002410110742002200041086a28020036020020012002410410740c170b200241053a000020012002410110740240024002400240200041086a280200417f6a0e04000102031a0b200241003a000020012002410110742000410c6a200110f5012002200041306a3602002002200110af010c190b200241013a000020012002410110742000410c6a200110f5012002200041306a3602002002200110af012002200041c0006a3602002002200110af010c180b200241023a000020012002410110742000410c6a200110f501200041306a200110f5012002200041d8006a3602002002200110af010c170b200241033a000020012002410110742000410c6a200110f5012002200041306a3602002002200110af010c160b200241063a00002001200241011074200241003a00002001200241011074200028020421032000410c6a2802002200200110762000450d15200041f0006c2100034020032001108f06200341f0006a2103200041907f6a22000d000c160b0b200241073a0000200120024101107402400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041086a22032d0000417f6a0e17000102030405060708090a0b0c0d0e0f101112131415162b0b200241003a000020012002410110742000412c6a200110f5012002200041d0006a3602002002200110af010240024002400240024020002d00090e0500010203042f0b200241003a000020012002410110740c2e0b200241013a000020012002410110740c2d0b200241023a000020012002410110740c2c0b200241033a000020012002410110742001200341026a412010740c2b0b200241043a000020012002410110740c2a0b200241013a000020012002410110742002200041106a3602002002200110af010c290b200241023a000020012002410110742002200041106a3602002002200110af010c280b200241033a0000200120024101107420022000410c6a28020036020020012002410410740c270b200241043a000020012002410110742000410c6a20011091022002200041106a2d00003a000020012002410110740c260b200241053a000020012002410110742000410c6a2802002103200041146a280200220020011076200041246c2200450d2503402003200110f501200341246a21032000415c6a22000d000c260b0b200241063a000020012002410110740c240b200241073a000020012002410110740240024002400240024020032d00010e050001020304280b200241003a000020012002410110740c270b200241013a000020012002410110740c260b200241023a000020012002410110740c250b200241033a000020012002410110742001200341026a412010740c240b200241043a000020012002410110740c230b200241083a000020012002410110742000410c6a200110f5010c220b200241093a000020012002410110742000410c6a20011091020c210b2002410a3a000020012002410110742000410c6a20011091020c200b2002410b3a00002001200241011074200220032d00013a000020012002410110740c1f0b2002410c3a000020012002410110740c1e0b2002410d3a000020012002410110740c1d0b2002410e3a000020012002410110742000410c6a2802002103200041146a2802002200200110762000450d1c2000410574210003402001200341201074200341206a2103200041606a22000d000c1d0b0b2002410f3a000020012002410110742001200341016a4120107420022000412c6a28020036020020012002410410740c1b0b200241103a000020012002410110740c1a0b200241113a0000200120024101107420022000410c6a2802003602002001200241041074200041106a2802002103200041186a28020022002001107620012003200041027410740c190b200241123a000020012002410110742001200341016a4120107420022000412c6a28020036020020012002410410740c180b200241133a000020012002410110742002200041106a3602002002200110af010c170b200241143a000020012002410110742000410c6a2001109102200041106a20011091020c160b200241153a000020012002410110742001200341016a4120107420022000412c6a28020036020020012002410410740c150b200241163a000020012002410110742000410c6a2802002103200041146a280200220020011076200041246c2200450d1403402003200110f501200341246a21032000415c6a22000d000c150b0b200241083a00002001200241011074200110b6040c130b200241093a0000200120024101107402402000280204450d00200241003a000020012002410110742001200041106a412010742001200041306a412010742001200041d0006a412010742001200041f0006a41201074200120004190016a412010742001200041b0016a41201074200028020421032000410c6a28020022002001107620012003200010740c130b200241013a000020012002410110740c120b2002410b3a00002001200241011074024002400240200041086a280200417f6a0e03000102140b200241003a00002001200241011074200041206a200110900620022000410c6a2802003602002001200241041074200041106a2802002103200041186a28020022052001107602402005450d0020032005410c6c6a2106034020032802002105200341086a28020022042001107620012005200410742003410c6a22032006470d000b0b20022000411c6a28020036020020012002410410740c130b200241013a00002001200241011074200041206a200110900620022000410c6a2802003602002001200241041074200041106a2802002103200041186a28020022052001107602402005450d0020032005410c6c6a2106034020032802002105200341086a28020022042001107620012005200410742003410c6a22032006470d000b0b20022000411c6a28020036020020012002410410740c120b200241023a0000200120024101107420022000410c6a28020036020020012002410410742002200041106a28020036020020012002410410740c110b2002410c3a00002001200241011074200241003a00002001200241011074200220002802043602002001200241041074200041086a2802002103200041106a2802002205200110762001200320051074200041146a28020021032000411c6a2802002205200110762000412c6a210702402005450d0020032005410c6c6a2106034020032802002105200341086a28020022042001107620012005200410742003410c6a22032006470d000b0b2002200041206a28020036020020012002410410742002200041246a28020036020020012002410410742002200041286a28020036020020012002410410742001200741c00010740c100b2002410d3a00002001200241011074200110b6040c0f0b2002410e3a000020012002410110740240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041086a22032d0000417f6a0e19000102030405060708090a0b0c0d0e0f101112131415161718270b200241003a000020012002410110744120102c2205450d27200041306a210020024220370204200220053602002002200341016a412010742001200228020022032002280208107402402002280204450d002003102e0b200220003602002002200110af010c260b200241013a000020012002410110742000410c6a2001109102200041106a20011091020c250b200241023a000020012002410110742000410c6a2001109102200041106a200110b2040c240b200241033a0000200120024101107420022000410c6a28020036020020012002410410740c230b200241043a000020012002410110744120102c2200450d2320024220370204200220003602002002200341016a41201074200120022802002200200228020810742002280204450d222000102e0c220b200241053a000020012002410110744120102c2200450d2220024220370204200220003602002002200341016a41201074200120022802002200200228020810742002280204450d212000102e0c210b200241063a000020012002410110744120102c2200450d2120024220370204200220003602002002200341016a41201074200120022802002200200228020810742002280204450d202000102e0c200b200241073a000020012002410110744120102c2205450d2020024220370204200220053602002002200341016a412010742001200228020022032002280208107402402002280204450d002003102e0b2002200028022c36020020012002410410742002200028023036020020012002410410740c1f0b200241083a000020012002410110744120102c2200450d1f20024220370204200220003602002002200341016a41201074200120022802002200200228020810742002280204450d1e2000102e0c1e0b200241093a000020012002410110742000410c6a20011091020c1d0b2002410a3a0000200120024101107420022000410c6a28020036020020012002410410740c1c0b2002410b3a000020012002410110742001200341016a4120107420002d002920011073200041306a29030021082002200041386a2903003703082002200837030020012002411010740c1b0b2002410c3a000020012002410110740c1a0b2002410d3a000020012002410110740c190b2002410e3a000020012002410110742000410c6a2802002103200041146a28020022002001107620012003200010740c180b2002410f3a000020012002410110742000410c6a2802002103200041146a28020022002001107620012003200010740c170b200241103a000020012002410110742000410c6a2802002103200041146a28020022002001107620012003200010740c160b200241113a000020012002410110742000410c6a2802002103200041146a28020022002001107620012003200010740c150b200241123a000020012002410110744120102c2205450d152000412c6a210020024220370204200220053602002002200341016a412010742001200228020022032002280208107402402002280204450d002003102e0b200020011091020c140b200241133a000020012002410110742001200341016a412010740c130b200241143a0000200120024101107420022000410c6a28020036020020012002410410740c120b200241153a000020012002410110742001200341016a4120107420022000412c6a28020036020020012002410410740c110b200241163a000020012002410110744120102c2205450d1120024220370204200220053602002002200341016a412010742001200228020022032002280208107402402002280204450d002003102e0b2002200028022c36020020012002410410740c100b200241173a000020012002410110744120102c2205450d1020024220370204200220053602002002200341016a412010742001200228020022032002280208107402402002280204450d002003102e0b0240200028022c4101460d00200241003a000020012002410110740c100b200241013a000020012002410110742002200041306a28020036020020012002410410740c0f0b200241183a000020012002410110742000410c6a20011091020c0e0b2002410f3a00002001200241011074024002400240024002400240200041086a22042d0000417f6a0e06000102030405130b200241003a000020012002410110742000412c6a2802002103200041346a28020022052001107602402005450d002005410574210503402001200341201074200341206a2103200541606a22050d000b0b0240024020042d00014101460d00200241003a000020012002410110740c010b200241013a000020012002410110742001200441026a412010740b2002200028023836020020012002410410740c120b200241013a000020012002410110742000410c6a2802002001109002200041106a20011091020c110b200241023a000020012002410110742000410c6a2001109102200041106a2802002001109002200041146a20011091020c100b200241033a000020012002410110744120102c2203450d102000412c6a210020024220370204200220033602002002200441016a412010742001200228020022032002280208107402402002280204450d002003102e0b20002001109102200220042d00213a000020012002410110740c0f0b200241043a000020012002410110744120102c2203450d0f200041306a2105200041386a21062000412c6a210020024220370204200220033602002002200441016a412010742001200228020022032002280208107402402002280204450d002003102e0b200020011091022006200110dc04200520011091020c0e0b200241053a000020012002410110744120102c2200450d0e20024220370204200220003602002002200441016a41201074200120022802002200200228020810742002280204450d0d2000102e0c0d0b200241103a00002001200241011074024002400240024002400240200041086a22042d0000417f6a0e06000102030405120b200241003a000020012002410110742000412c6a2802002103200041346a28020022052001107602402005450d002005410574210503402001200341201074200341206a2103200541606a22050d000b0b0240024020042d00014101460d00200241003a000020012002410110740c010b200241013a000020012002410110742001200441026a412010740b2002200028023836020020012002410410740c110b200241013a000020012002410110742000410c6a2802002001109002200041106a20011091020c100b200241023a000020012002410110742000410c6a2001109102200041106a2802002001109002200041146a20011091020c0f0b200241033a000020012002410110744120102c2203450d0f2000412c6a210020024220370204200220033602002002200441016a412010742001200228020022032002280208107402402002280204450d002003102e0b20002001109102200220042d00213a000020012002410110740c0e0b200241043a000020012002410110744120102c2203450d0e200041306a2105200041386a21062000412c6a210020024220370204200220033602002002200441016a412010742001200228020022032002280208107402402002280204450d002003102e0b200020011091022006200110dc04200520011091020c0d0b200241053a000020012002410110744120102c2200450d0d20024220370204200220003602002002200441016a41201074200120022802002200200228020810742002280204450d0c2000102e0c0c0b200241113a00002001200241011074024002400240024002400240200041086a2d0000417f6a0e06000102030405110b200241003a000020012002410110742000410c6a2802002103200041146a280200220520011076200041186a210402402005450d002005410574210003402001200341201074200341206a2103200041606a22000d000b0b200220043602002002200110af010c100b200241013a000020012002410110740c0f0b200241023a000020012002410110742000410c6a20011091020c0e0b200241033a000020012002410110740240024002402000410c6a2802000e03000102100b200241003a000020012002410110740c0f0b200241013a000020012002410110740c0e0b200241023a00002001200241011074200041106a20011091020c0d0b200241043a000020012002410110742000410c6a200110f501200220002d00093a000020012002410110740c0c0b200241053a0000200120024101107420022000410c6a28020036020020012002410410742002200041106a28020036020020012002410410740c0b0b200241123a00002001200241011074200041046a2103024002400240024002400240024020002d0004417f6a0e0700010203040506110b200241003a000020012002410110742001200341016a412010740c100b200241013a000020012002410110742001200341016a412010740c0f0b200241023a000020012002410110742001200341016a412010742001200341216a412010740c0e0b200241033a00002001200241011074200041086a2802002103200041106a2802002200200110762000450d0d2000410574210003402001200341201074200341206a2103200041606a22000d000c0e0b0b200241043a000020012002410110742001200341016a412010740c0c0b200241053a000020012002410110742001200341016a412010740c0b0b200241063a000020012002410110740c0a0b200241133a00002001200241011074024002400240200041086a280200417f6a0e030001020c0b200241003a000020012002410110742002200041306a3602002002200110af012000410c6a200110f5010c0b0b200241013a000020012002410110742000410c6a20011091020c0a0b200241023a000020012002410110742000410c6a20011091020c090b200241183a0000200120024101107402400240024002400240200041086a22032d0000417f6a0e0500010203040d0b200241003a000020012002410110742001200341016a412010742001200341216a41c10010740c0c0b200241013a000020012002410110742001200341016a41141074200041206a29030021082002200041286a29030037030820022008370300200120024110107402400240200041306a2903004201510d00200241003a000020012002410110740c010b200241013a00002001200241011074200041386a29030021082002200041c0006a290300370308200220083703002001200241101074200041c8006a29030021082002200041d0006a2903003703082002200837030020012002411010742002200041d8006a28020036020020012002410410740b024020032d001522004102470d00200241003a000020012002410110740c0c0b200241013a00002001200241011074024020004101460d00200241003a000020012002410110740c0c0b200241013a000020012002410110740c0b0b200241023a000020012002410110742001200341016a412010742001200341216a41c1001074200041ec006a2802002103200041f4006a28020022002001107620012003200010740c0a0b200241033a000020012002410110742000410c6a2802002103200041146a28020022002001107620012003200010740c090b200241043a000020012002410110742001200341016a411410742001200341156a411410740240200341296a2d00004101460d00200241003a000020012002410110740c090b200241013a0000200120024101107420012003412a6a412010740c080b200241193a000020012002410110740240024002400240200041086a280200417f6a0e04000102030b0b200241003a000020012002410110740c0a0b200241013a000020012002410110742000410c6a200110f5010c090b200241023a000020012002410110742000410c6a200110f501200041306a29030021082002200041386a290300370308200220083703002001200241101074200041c0006a29030021082002200041c8006a2903003703082002200837030020012002411010742002200041d0006a28020036020020012002410410740c080b200241033a000020012002410110742000410c6a200110f501200041306a200110f501200041d8006a29030021082002200041e0006a290300370308200220083703002001200241101074200041e8006a29030021082002200041f0006a2903003703082002200837030020012002411010742002200041f8006a28020036020020012002410410740c070b2002411a3a0000200120024101107402400240024020002f0104417f6a0e03000102090b200241003a00002001200241011074200041086a2802002103200041106a280200220020011076200041b0026c2200450d08034020032001109002200341b0026a2103200041d07d6a22000d000c090b0b200241013a00002001200241011074200220002f01063b01002001200241021074200041086a28020020011090020c070b200241023a00002001200241011074200041086a2802002103200041106a280200220020011076200041b0026c2200450d06034020032001109002200341b0026a2103200041d07d6a22000d000c070b0b2002411c3a00002001200241011074024002400240024002400240024002400240024002400240024002400240200041086a22032d0000417f6a0e0f000102030405060708090a0b0c0d0e140b200241003a000020012002410110742001200341016a412010740c130b200241013a000020012002410110742000410c6a200110b7012002200041186a108a012001200228020022032002280208107402402002280204450d002003102e0b20022000413c6a108a012001200228020022032002280208107402402002280204450d002003102e0b2002200041e0006a108a012001200228020022032002280208107402402002280204450d002003102e0b200220004184016a108a012001200228020022032002280208107402402002280204450d002003102e0b2002200041a8016a108a012001200228020022032002280208107402402002280204450d002003102e0b0240024020004194026a22032d00004101460d00200241003a000020012002410110740c010b200241013a000020012002410110742001200341016a411410740b2002200041cc016a108a012001200228020022032002280208107402402002280204450d002003102e0b2002200041f0016a108a01200120022802002200200228020810742002280204450d122000102e0c120b200241023a000020012002410110742000410c6a2802002103200041146a280200220020011076200041c4006c2200450d11200320006a2105034020012003412010742002200341206a2200108a012001200228020022032002280208107402402002280204450d002003102e0b200041246a22032005470d000c120b0b200241033a000020012002410110740c100b200241043a000020012002410110742000410c6a20011091022002200041106a3602002002200110af010c0f0b200241053a0000200120024101107420022000410c6a28020036020020012002410410740c0e0b200241063a000020012002410110742000410c6a20011091022002200041106a3602002002200110af010c0d0b200241073a000020012002410110742000412c6a20011091022001200341016a412010740c0c0b200241083a000020012002410110742000410c6a20011091022002200041106a29030037030020012002410810740c0b0b200241093a000020012002410110742000410c6a2001109102200041106a200110f501200041386a200110ea030c0a0b2002410a3a000020012002410110742000410c6a200110f5010c090b2002410b3a000020012002410110742000410c6a200110f5012002200041306a108a01200120022802002200200228020810742002280204450d082000102e0c080b2002410c3a000020012002410110742000410c6a200110f5012002200041306a108a01200120022802002200200228020810742002280204450d072000102e0c070b2002410d3a000020012002410110742000410c6a200110f5010c060b2002410e3a000020012002410110740c050b2002411d3a00002001200241011074200041046a2103024002400240024002400240024002400240024020002d0004417f6a0e0a000102030405060708090e0b200241003a000020012002410110742001200341016a412010740240024020002d00254107470d00200241003a000020012002410110740c010b200241013a00002001200241011074024002400240024002400240024020032d00210e0700010203070405070b200241003a00000c050b200241013a00000c040b200241023a00000c030b200241033a00000c020b200241053a00000c010b200241063a00000b20012002410110740b200028022820011090020c0d0b200241013a000020012002410110742001200341016a41201074024002400240024002400240024020002d00250e0700010203060405060b200241003a000020012002410110740c050b200241013a000020012002410110740c040b200241023a000020012002410110740c030b200241033a000020012002410110740c020b200241053a000020012002410110740c010b200241063a000020012002410110740b2002200028022836020020012002410410740c0c0b200241023a000020012002410110742001200341016a41201074024002400240024002400240024020002d00250e0700010203060405060b200241003a000020012002410110740c050b200241013a000020012002410110740c040b200241023a000020012002410110740c030b200241033a000020012002410110740c020b200241053a000020012002410110740c010b200241063a000020012002410110740b2002200028022836020020012002410410740c0b0b200241033a000020012002410110740c0a0b200241043a00002001200241011074024002400240024002400240024020002d00050e0700010203060405060b200241003a000020012002410110740c050b200241013a000020012002410110740c040b200241023a000020012002410110740c030b200241033a000020012002410110740c020b200241053a000020012002410110740c010b200241063a000020012002410110740b200220002802083602002001200241041074200220002f01063b010020012002410210740c090b200241053a000020012002410110742001200341016a412010742000412c6a2105200041286a2104024002400240024002400240024020002d00250e0700010203060405060b200241003a000020012002410110740c050b200241013a000020012002410110740c040b200241023a000020012002410110740c030b200241033a000020012002410110740c020b200241053a000020012002410110740c010b200241063a000020012002410110740b200220032f01223b0100200120024102107420042001109102200520011091020c080b200241063a000020012002410110742001200341016a412010744120102c2200450d0820024220370204200220003602002002200341216a41201074200120022802002200200228020810742002280204450d072000102e0c070b200241073a000020012002410110742001200341016a412010744120102c2200450d0720024220370204200220003602002002200341216a41201074200120022802002200200228020810742002280204450d062000102e0c060b200241083a000020012002410110742001200341016a412010744120102c2200450d0620024220370204200220003602002002200341216a41201074200120022802002200200228020810742002280204450d052000102e0c050b200241093a000020012002410110742001200341016a412010742001200341216a412010740240024020002d00454107470d00200241003a000020012002410110740c010b200241013a00002001200241011074024002400240024002400240024020032d00410e0700010203070405070b200241003a00000c050b200241013a00000c040b200241023a00000c030b200241033a00000c020b200241053a00000c010b200241063a00000b20012002410110740b200028024820011090020c040b2002411e3a000020012002410110740240024002400240200041086a22042d0000417f6a0e0400010203070b200241003a000020012002410110742000410c6a2802002103200041146a28020022052001107602402005450d002005410574210503402001200341201074200341206a2103200541606a22050d000b0b200028021820011090020c060b200241013a00002001200241011074200220002f010a3b010020012002410210742000410c6a2802002103200041146a28020022052001107602402005450d002005410574210503402001200341201074200341206a2103200541606a22050d000b0b0240024020002802184101460d00200241003a000020012002410110740c010b200241013a0000200120024101107420022000411c6a28020036020020012002410410742002200041206a28020036020020012002410410740b200028022421032000412c6a2802002205200110762001200320051074200220002d00093a000020012002410110742002200029033037030020012002410810740c050b200241023a00002001200241011074200220002f012a3b010020012002410210742000412c6a2802002103200041346a28020022052001107602402005450d002005410574210503402001200341201074200341206a2103200541606a22050d000b0b200441016a21030240024020002802384101460d00200241003a000020012002410110740c010b200241013a0000200120024101107420022000413c6a28020036020020012002410410742002200041c0006a28020036020020012002410410740b20012003412010742002200029034837030020012002410810740c040b200241033a00002001200241011074200220002f012a3b010020012002410210742000412c6a2802002103200041346a280200220520011076200441016a210402402005450d002005410574210503402001200341201074200341206a2103200541606a22050d000b0b20022000280238360200200120024104107420022000413c6a280200360200200120024104107420012004412010740c030b200241223a00002001200241011074024002400240024002400240024002400240200041086a280200417f6a0e090001020304050607080b0b200241003a000020012002410110742002200041186a3602002002200110af012000410c6a2802002103200041146a28020022002001107620012003200010740c0a0b200241013a000020012002410110742000410c6a20011091020c090b200241023a000020012002410110742000410c6a2001109102200041106a200110f5012002200041386a3602002002200110af010c080b200241033a000020012002410110742000410c6a20011091020c070b200241043a000020012002410110742000410c6a20011091020c060b200241053a000020012002410110742000410c6a2001109102200041106a200110f5010c050b200241063a000020012002410110742000410c6a20011091020c040b200241073a000020012002410110742000410c6a20011091020c030b200241083a000020012002410110742000410c6a2001109102200041106a2802002103200041186a28020022002001107620012003200010740c020b200241233a00002001200241011074024002400240024002400240200041086a22032d0000417f6a0e06000102030405070b200241003a000020012002410110742000412c6a2802002105200041346a28020022002001107620012005200010742001200341016a412010740c060b200241013a000020012002410110744120102c2200450d0620024220370204200220003602002002200341016a41201074200120022802002200200228020810742002280204450d052000102e0c050b200241023a000020012002410110742000412c6a2802002105200041346a28020022042001107620012005200410742001200341016a412010742002200041386a3602002002200110af010c040b200241033a000020012002410110744120102c2205450d04200041306a210020024220370204200220053602002002200341016a412010742001200228020022032002280208107402402002280204450d002003102e0b200220003602002002200110af010c030b200241043a000020012002410110744120102c2200450d0320024220370204200220003602002002200341016a41201074200120022802002200200228020810742002280204450d022000102e0c020b200241053a000020012002410110744120102c2200450d0220024220370204200220003602002002200341016a41201074200120022802002200200228020810742002280204450d012000102e0c010b200241243a00002001200241011074200241003a000020012002410110742002200041386a1091062001200228020022042002280208107420004180026a2103200041086a210502402002280204450d002004102e0b20012005413010742002200041f8016a28020036020020012002410410742003200110910220004184026a20011091020b200241106a24000f0b1036000bb30101027f230041106b2202240002400240024002402000280200220341c000490d00200341808001490d012003418080808004490d02200241033a00032001200241036a41011074200220002802003602042001200241046a410410740c030b200220034102743a00032001200241036a410110740c020b200220034102744101723b010a20012002410a6a410210740c010b2002200341027441027236020c20012002410c6a410410740b200241106a24000bf70201017f23004190016b22042400024002400240024020002d00000e03000102000b200441206a41186a200341186a290000370300200441206a41106a200341106a290000370300200441206a41086a200341086a29000037030020042003290000370320200041016a20012002200441206a10890721000c020b200441206a41186a200341186a290000370300200441206a41106a200341106a290000370300200441206a41086a200341086a29000037030020042003290000370320200041016a20012002200441206a10fa0421000c010b20042001200210b001200441206a200041016a200410d3084100210020042d00200d00200441c8006a41206a200441206a41216a2d00003a0000200441e0006a200441396a290000370300200441d8006a200441316a290000370300200441d0006a200441296a29000037030020042004290021370348200441f0006a200441c8006a412110b001200441f0006a2003412010ec084521000b20044190016a240020000bc81303067f017e067f230041d0036b2202240002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002005417f6a0e03010203040b200042033703000c040b024020064104490d002004280001210720012003417b6a22053602042001200441056a36020020054108490d00200429000521082001200341736a220936020420012004410d6a36020041002105200241003a0028200341726a21030240034020092005460d01200241086a20056a200420056a2206410d6a2d00003a00002001200336020420012006410e6a3602002002200541016a22063a00282003417f6a21032006210520064120470d000b20024190036a41086a2204200241086a41086a29030037030020024190036a41106a2203200241086a41106a29030037030020024190036a41186a2209200241086a41186a2903003703002002200229030837039003410121050240200641ff01714120490d00200241f0026a41186a2009290300370300200241f0026a41106a2003290300370300200241f0026a41086a200429030037030020022002290390033703f002410021050b200241b0026a41086a200241f0026a41086a290300370300200241b0026a41106a200241f0026a41106a290300370300200241b0026a41186a200241f0026a41186a290300370300200220022903f0023703b00220050d01200241f0016a41086a2205200241b0026a41086a290300370300200241f0016a41106a2204200241b0026a41106a290300370300200241f0016a41186a2203200241b0026a41186a290300370300200220022903b0023703f001200241086a200110940220022d00084101460d01200241a8016a2201200241c1006a290000370300200241a0016a2206200241396a29000037030020024198016a2209200241316a29000037030020024190016a220a200241296a290000370300200241f0006a41186a220b200241216a290000370300200241f0006a41106a220c200241196a290000370300200241f0006a41086a220d200241116a290000370300200241d0016a41086a220e2005290300370300200241d0016a41106a22052004290300370300200241d0016a41186a2204200329030037030020022002290009370370200220022903f0013703d001200241b0016a41186a22032004290300370300200241b0016a41106a22042005290300370300200241b0016a41086a2205200e290300370300200220022903d0013703b001200041106a20073602002000200837030820004200370300200020022903b0013702142000411c6a2005290300370200200041246a20042903003702002000412c6a2003290300370200200020022903703702342000413c6a200d290300370200200041c4006a200c290300370200200041cc006a200b290300370200200041d4006a200a290300370200200041dc006a2009290300370200200041e4006a2006290300370200200041ec006a20012903003702000c050b0240200541ff0171450d00200241003a00280b200241b0026a41086a200241f0026a41086a290300370300200241b0026a41106a200241f0026a41106a290300370300200241b0026a41186a200241f0026a41186a290300370300200220022903f0023703b0020b200042033703000c030b024020064104490d002004280001210620012003417b6a22053602042001200441056a36020020054108490d0020004201370300200429000521082001200341736a36020420012004410d6a360200200041106a200636020020002008370308200041146a200241086a41e40010e9081a0c030b200042033703000c020b024020064104490d002004280001210720012003417b6a22053602042001200441056a36020020054108490d00200429000521082001200341736a220936020420012004410d6a36020041002105200241003a0028200341726a21030240034020092005460d01200241086a20056a200420056a2206410d6a2d00003a00002001200336020420012006410e6a3602002002200541016a22063a00282003417f6a21032006210520064120470d000b20024190036a41086a2204200241086a41086a29030037030020024190036a41106a2203200241086a41106a29030037030020024190036a41186a2209200241086a41186a2903003703002002200229030837039003410121050240200641ff01714120490d00200241f0026a41186a2009290300370300200241f0026a41106a2003290300370300200241f0026a41086a200429030037030020022002290390033703f002410021050b200241b0026a41086a200241f0026a41086a290300370300200241b0026a41106a200241f0026a41106a290300370300200241b0026a41186a200241f0026a41186a290300370300200220022903f0023703b00220050d01200241f0016a41086a2205200241b0026a41086a290300370300200241f0016a41106a2204200241b0026a41106a290300370300200241f0016a41186a2203200241b0026a41186a290300370300200220022903b0023703f001200241086a200110940220022d00084101460d01200241a8016a2201200241c1006a290000370300200241a0016a2206200241396a29000037030020024198016a2209200241316a29000037030020024190016a220a200241296a290000370300200241f0006a41186a220b200241216a290000370300200241f0006a41106a220c200241196a290000370300200241f0006a41086a220d200241116a290000370300200241d0016a41086a220e2005290300370300200241d0016a41106a22052004290300370300200241d0016a41186a2204200329030037030020022002290009370370200220022903f0013703d001200241b0016a41186a22032004290300370300200241b0016a41106a22042005290300370300200241b0016a41086a2205200e290300370300200220022903d0013703b001200041106a20073602002000200837030820004202370300200020022903b0013702142000411c6a2005290300370200200041246a20042903003702002000412c6a2003290300370200200020022903703702342000413c6a200d290300370200200041c4006a200c290300370200200041cc006a200b290300370200200041d4006a200a290300370200200041dc006a2009290300370200200041e4006a2006290300370200200041ec006a20012903003702000c030b0240200541ff0171450d00200241003a00280b200241b0026a41086a200241f0026a41086a290300370300200241b0026a41106a200241f0026a41106a290300370300200241b0026a41186a200241f0026a41186a290300370300200220022903f0023703b0020b200042033703000c010b200042033703000b200241d0036a24000bd411010b7f230041b0036b2202240020024180016a200110a701200241c0006a41086a220120024189016a290000370300200241c0006a41106a220320024191016a290000370300200241c0006a41186a220420024199016a290000370300200241c0006a41206a2205200241a1016a290000370300200241c0006a41286a2206200241a9016a290000370300200241c0006a41306a2207200241b1016a290000370300200241c0006a41386a2208200241b9016a290000370300200220022900810137034002400240024020022d0080014101460d00200241386a22092008290300370300200241306a22082007290300370300200241286a22072006290300370300200241206a22062005290300370300200241186a22052004290300370300200241106a220a2003290300370300200241086a220b20012903003703002002200229034037030020024198026a41186a200929030037030020024198026a41106a200829030037030020024198026a41086a20072903003703002002200629030037039802200420052903003703002003200a2903003703002001200b2903003703002002200229030037034020024180016a200241c0006a10720240024020022d0080014101460d0020024190036a410f6a200241c0006a410f6a29000037000020024190036a41086a200241c0006a41086a290000370300200220022900403703900341012101410221050c010b200241ae036a20022d0083013a000020024198036a2002418d016a2900003703002002419f036a20024194016a2900003700002002418c036a200241a0016a2d00003a0000200220022f0081013b01ac0320022002290085013703900320022002419c016a280200360288034100210120022d00840121050b20024184036a41026a2206200241ac036a41026a2d00003a0000200241e8026a41086a220320024190036a41086a290300370300200241e8026a410f6a220420024190036a410f6a290000370000200241e0026a41046a220720024188036a41046a2d00003a0000200220022f01ac033b01840320022002290390033703e80220022002280288033602e002024020010d00200241dc026a41026a20062d00003a0000200241c0026a41086a2003290300370300200241c0026a410f6a2004290000370000200241b8026a41046a20072d00003a0000200220022f0184033b01dc02200220022903e8023703c002200220022802e0023602b802200241c0006a41186a20024198026a41186a290300370300200241c0006a41106a20024198026a41106a290300370300200241c0006a41086a20024198026a41086a290300370300200220022903980237034020024180016a200241c0006a1072410121010240024020022d0080014101460d0020024190036a410f6a200241c0006a410f6a29000037000020024190036a41086a200241c0006a41086a2900003703002002200229004037039003410221030c010b200241ae036a20022d0083013a000020024198036a2002418d016a2900003703002002419f036a20024194016a2900003700002002418c036a200241a0016a2d00003a0000200220022f0081013b01ac0320022002290085013703900320022002419c016a280200360288034100210120022d00840121030b20024184036a41026a2207200241ac036a41026a22082d00003a0000200241e8026a41086a220420024190036a41086a2209290300370300200241e8026a410f6a220620024190036a410f6a220a290000370000200241e0026a41046a220b20024188036a41046a220c2d00003a0000200220022f01ac033b01840320022002290390033703e80220022002280288033602e00202402001450d0020024180016a410f6a200629000037000020024180016a41086a2004290300370300200220022903e8023703800141012101200321050c030b20024194026a41026a20072d00003a000020092004290300370300200a2006290000370000200c200b2d00003a00002008200241dc026a41026a2d00003a0000200220022f0184033b019402200220022903e80237039003200220022802e00236028803200220022f01dc023b01ac0320024180016a410f6a2201200241c0026a410f6a29000037000020024180016a41086a2204200241c0026a41086a290300370300200220022903c00237038001200241e8026a41046a200241b8026a41046a2d00003a0000200220022802b8023602e802200241c0006a410f6a2001290000370000200241c0006a41086a20042903003703002002200229038001370340410021010c020b20024180016a410f6a200429000037000020024180016a41086a2003290300370300200220022903e80237038001410121010c010b200041013a00000c010b20024190026a41026a2204200241ac036a41026a2d00003a0000200241f8016a41086a2206200241c0006a41086a290300370300200241f8016a410f6a2207200241c0006a410f6a290000370000200241f0016a41046a2208200241e8026a41046a2d00003a0000200241ec016a41026a220920024194026a41026a2d00003a0000200220022f01ac033b019002200220022903403703f801200220022802e8023602f001200220022f0194023b01ec01200241d0016a410f6a220a20024190036a410f6a290000370000200241d0016a41086a220b20024190036a41086a290300370300200241c8016a41046a220c20024188036a41046a2d00003a000020022002290390033703d00120022002280288033602c801024020010d00200020022f0190023b0001200041046a20053a0000200041056a20022903f8013700002000411c6a20022802f001360000200041216a20022f01ec013b0000200041036a20042d00003a00002000410d6a2006290300370000200041146a2007290000370000200041206a20082d00003a0000200041236a20092d00003a0000200041246a20033a0000200041003a0000200041256a20022903d0013700002000412d6a200b290300370000200041346a200a2900003700002000413c6a20022802c801360000200041c0006a200c2d00003a00000c010b200041013a00000b200241b0036a24000ba40202057f027e230041106b21020240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a36020020054101470d01024002400240024020064108490d00200429000121072001200341776a22053602042001200441096a36020020054108490d002004290009210820012003416f6a22033602042001200441116a22043602002003450d0320042d0000210520012003417f6a3602042001200441016a36020041002101024020050e03030200040b410221010c020b200041033a00100f0b410121010b200020013a0010200020083703082000200737030020002002280009360011200041146a2002410c6a2800003600000f0b200041033a00100f0b200041033a00100f0b200041033a00100ba10101017f230041106b22022400200241013a00082001200241086a41011074200220002903003703082001200241086a41081074200220002903083703082001200241086a41081074024002400240024020002d00100e03000102030b200241003a00082001200241086a410110740c020b200241013a00082001200241086a410110740c010b200241023a00082001200241086a410110740b200241106a24000b9f0101057f230041106b2202240020004100360208200042013702002002200128020036020c20002002410c6a41041074200128020421032001410c6a28020022042000107602402004450d0020032004410c6c6a2105034020032802002104200341086a28020022062000107620002004200610742003410c6a22032005470d000b0b200220012802103602082000200241086a41041074200241106a24000bd20603057f017e027f230041a0046b2202240041002103200241003a009003024002400240024002400340200128020022042802042205450d01200241f0026a20036a200428020022062d00003a000020042005417f6a3602042004200641016a3602002002200341016a22043a0090032004210320044120470d000b20024190026a41186a200241f0026a41186a2903002207370300200241f0016a41086a200241f0026a41086a290300370300200241f0016a41106a200241f0026a41106a290300370300200241f0016a41186a2007370300200220022903f0023703f0012001280200220428020422034108490d012004280200220529000021072004200341786a3602042004200541086a360200200241f0026a200110990220022802f4022205450d02200241fc026a280200210420022802f802210620022802f002210320024190026a200241f0026a41106a41e00010e9081a200241f0026a200110990220022802f402450d03200241206a200241f0026a41f00010e9081a200241086a2201200241f0016a41086a290300370300200241106a2208200241f0016a41106a290300370300200241186a2209200241f0016a41186a290300370300200220022903f00137030020024190016a20024190026a41e00010e9081a200041146a2004360200200020063602102000200536020c2000200336020820002007370300200041186a20024190016a41e00010e9081a200041f8006a200241206a41f00010e9081a20004180026a2009290300370300200041f8016a2008290300370300200041f0016a2001290300370300200041e8016a20022903003703000c040b0240200341ff0171450d00200241003a0090030b2000410036020c0c030b2000410036020c0c020b2000410036020c0c010b2000410036020c02402004450d00200441246c21032005210403400240024002400240024020042d00000e050400010204030b2004410c6a280200450d03200441086a280200102e0c030b2004410c6a280200450d02200441086a280200102e0c020b2004410c6a280200450d01200441086a280200102e0c010b200441086a280200450d00200441046a280200102e0b200441246a21042003415c6a22030d000b0b2006450d00200641246c450d002005102e0b200241a0046a24000b881d05057f017e087f027e057f230041d0056b2202240041002103200241003a00a805024002400240024002400240024002400340200128020022042802042205450d0120024188056a20036a200428020022062d00003a000020042005417f6a3602042004200641016a3602002002200341016a22043a00a8052004210320044120470d000b200241e0036a41186a20024188056a41186a2903002207370300200241c0026a41086a220420024188056a41086a290300370300200241c0026a41106a220320024188056a41106a290300370300200241c0026a41186a2205200737030020022002290388053703c002200241a0016a41186a22062005290300370300200241a0016a41106a22052003290300370300200241a0016a41086a22032004290300370300200220022903c0023703a00120024180016a41186a200629030037030020024180016a41106a200529030037030020024180016a41086a2003290300370300200220022903a00137038001200241186a200110ad0120022802180d02200228021c210841002103200241003a00a8050340200128020022042802042205450d0220024188056a20036a200428020022062d00003a000020042005417f6a3602042004200641016a3602002002200341016a22043a00a8052004210320044120470d000b200241e0036a41186a20024188056a41186a2903002207370300200241c0026a41086a220420024188056a41086a290300370300200241c0026a41106a220320024188056a41106a290300370300200241c0026a41186a2205200737030020022002290388053703c002200241e0016a41186a22062005290300370300200241e0016a41106a22052003290300370300200241e0016a41086a22032004290300370300200220022903c0023703e001200241c0016a41186a2006290300370300200241c0016a41106a2005290300370300200241c0016a41086a2003290300370300200220022903e0013703c00141002103200241003a00a8050340200128020022042802042205450d0420024188056a20036a200428020022062d00003a000020042005417f6a3602042004200641016a3602002002200341016a22043a00a8052004210320044120470d000b200241e0036a41186a20024188056a41186a2903002207370300200241c0026a41086a220420024188056a41086a290300370300200241c0026a41106a220320024188056a41106a290300370300200241c0026a41186a2205200737030020022002290388053703c002200241a0026a41186a22062005290300370300200241a0026a41106a22052003290300370300200241a0026a41086a22032004290300370300200220022903c0023703a00220024180026a41186a200629030037030020024180026a41106a200529030037030020024180026a41086a2003290300370300200220022903a00237038002200241106a200110ad0120022802100d0520022802142209200128020028020441246e2204200420094b1bad42247e2207422088a7450d040c070b0240200341ff0171450d00200241003a00a8050b200241a0016a41086a200241c0026a41086a290300370300200241a0016a41106a200241c0026a41106a290300370300200241a0016a41186a200241c0026a41186a290300370300200220022903c0023703a001200041003602040c050b0240200341ff0171450d00200241003a00a8050b200241e0016a41086a200241c0026a41086a290300370300200241e0016a41106a200241c0026a41106a290300370300200241e0016a41186a200241c0026a41186a290300370300200220022903c0023703e001200041003602040c040b200041003602040c030b0240200341ff0171450d00200241003a00a8050b200241a0026a41086a200241c0026a41086a290300370300200241a0026a41106a200241c0026a41106a290300370300200241a0026a41186a200241c0026a41186a290300370300200220022903c0023703a002200041003602040c020b2007a72204417f4c0d02024002400240024020040d004104210a0c010b2004102c220a450d010b2001200128020441016a2203360204200441246ead2107200320012802084b0d01024002402009450d00200241ed036a210b2002419b056a220c41056a210d4100210e0340200128020022042802042203450d04200428020022052d0000210620042003417f6a3602042004200541016a360200024002400240024002400240024002400240024020060e08000e010e030402050e0b200241086a200110ad0120022802080d0d200128020022032802042206200228020c2204490d0d2004417f4c0d100240024020040d00410121050c010b200410322205450d0d2001280200220328020421060b20062004490d0620052003280200200410e90821062003280204220f20044f0d052004200f41b8b2c0001056000b41002103200241003a00a80502400340200128020022042802042205450d0120024188056a20036a200428020022062d00003a000020042005417f6a3602042004200641016a3602002002200341016a22043a00a8052004210320044120470d000b2002200d2900003700c5052002200c2900003703c005200220022900c5053700b505200220022903c0053703b005200220022903b0053703f804200220022900b5053700fd04200228008f05210620022f018805210420022d008a052103200228008b0521052002290093052110200220022900fd043700ed04200220022903f8043703e804200220022900ed043700dd04200220022903e8043703d804200220022900dd043700e503200220022903d8043703e003200b20022f00d5043b0000200b41026a200241d5046a41026a2d00003a0000201042808080807083211120054108762112200420034110747221032010a7210f410021130c080b200341ff0171450d0c200241003a00a8050c0c0b20024188056a200110ac01200228028c052206450d0b20022f01880520022d008a0541107472210320022d008b05210520022903900522104280808080708321112010a7210f410121130c060b20024188056a200110ac01200228028c052206450d0a20022f01880520022d008a0541107472210320022d008b05210520022903900522104280808080708321112010a7210f410221130c050b20024188056a200110ac01200228028c052206450d0920022f01880520022d008a0541107472210320022d008b05210520022903900522104280808080708321112010a7210f410321130c040b200128020022042802042203450d08200428020022052d0000210620042003417f6a3602042004200541016a36020020060d08200241c0056a200110fd0520022802c00522054102460d08200241e0036a41086a20024188056a41086a29020037030020022002290288053703e00320022802c805210f20022802c40521064104211342002111410021120c020b2003200f20046b3602042003200328020020046a3602002006450d07200241e0036a41086a20024188056a41086a29020037030020022002290288053703e003200641087621122004ad22104220862010842210422088a7210f2010a7210641052113420021110c010b2005102e0c060b0b200241c0026a41086a200241e0036a41086a2903002210370300200241c0046a41086a22142010370300200220022903e00322103703c002200220103703c004024020074220882210a722042007a7470d00200441016a22152004490d0820044101742216201520152016491b22154104201541044b1bad42247e2210422088a74541027421152010a721160240024020040d0020024100360288050c010b20024104360290052002200a360288052002200441246c36028c050b200241e0036a2016201520024188056a107d20022802e803211520022802e0034101460d0320022802e403210a20074220882210a72104201541246ead21070b200a200441246c6a22042011200fad8437000c2004200636000820042012410874200541ff017172360004200420033b0001200420133a0000200441036a20034110763a0000200420022903c0043700142004411c6a20142903003700002010422086200742ffffffff0f83844280808080107c2107200e41016a220e2009470d000b200128020421030b20012003417f6a360204200a450d03200241e0006a41186a220420024180016a41186a290300370300200241e0006a41106a220320024180016a41106a290300370300200241e0006a41086a220520024180016a41086a290300370300200241c0006a41086a2206200241c0016a41086a290300370300200241c0006a41106a2201200241c0016a41106a290300370300200241c0006a41186a2209200241c0016a41186a290300370300200241206a41086a220e20024180026a41086a290300370300200241206a41106a220f20024180026a41106a290300370300200241206a41186a221320024180026a41186a2903003703002002200229038001370360200220022903c0013703402002200229038002370320200020073702082000200a36020420002008360200200041106a2002290360370200200041186a2005290300370200200041206a2003290300370200200041286a2004290300370200200041306a2002290340370200200041386a2006290300370200200041c0006a2001290300370200200041c8006a2009290300370200200041e8006a2013290300370200200041e0006a200f290300370200200041d8006a200e290300370200200041d0006a20022903203702000c040b2015450d040b1036000b02402007422088a72204450d00200441246c2103200a210403400240024002400240024020042d00000e050400010204030b2004410c6a280200450d03200441086a280200102e0c030b2004410c6a280200450d02200441086a280200102e0c020b2004410c6a280200450d01200441086a280200102e0c010b200441086a280200450d00200441046a280200102e0b200441246a21042003415c6a22030d000b0b2007a72204450d00200441246c450d00200a102e0b200041003602040b200241d0056a24000f0b1038000b9e0703067f017e017f230041a0046b2202240041002103200241003a00900320012802042104417f21050240024002400240034020042003460d01200241f0026a20036a200128020022062d00003a00002001200420056a3602042001200641016a3602002002200341016a22063a0090032005417f6a21052006210320064120470d000b20024190026a41086a2203200241f0026a41086a29030037030020024190026a41106a2205200241f0026a41106a29030037030020024190026a41186a2207200241f0026a41186a290300370300200220022903f00237039002200641ff0171411f4b0d010c020b200341ff0171450d01200241003a0090030c010b200241f0016a41086a2003290300370300200241f0016a41106a2005290300370300200241f0016a41186a200729030037030020022002290390023703f001024002400240200420066b22034108490d002001280200220529000021082001200341786a3602042001200541086a360200200241f0026a2001109b0220022802f4022205450d01200241fc026a280200210320022802f802210620022802f002210420024190026a200241f0026a41106a41e00010e9081a200241f0026a2001109b0220022802f402450d02200241206a200241f0026a41f00010e9081a200241086a2201200241f0016a41086a290300370300200241106a2207200241f0016a41106a290300370300200241186a2209200241f0016a41186a290300370300200220022903f00137030020024190016a20024190026a41e00010e9081a200041146a2003360200200020063602102000200536020c2000200436020820002008370300200041186a20024190016a41e00010e9081a200041f8006a200241206a41f00010e9081a20004180026a2009290300370300200041f8016a2007290300370300200041f0016a2001290300370300200041e8016a20022903003703000c040b2000410036020c0c030b2000410036020c0c020b2000410036020c02402003450d00200341246c21012005210303400240024002400240024020032d00000e050400010204030b2003410c6a280200450d03200341086a280200102e0c030b2003410c6a280200450d02200341086a280200102e0c020b2003410c6a280200450d01200341086a280200102e0c010b200341086a280200450d00200341046a280200102e0b200341246a21032001415c6a22010d000b0b2006450d01200641246c450d012005102e0c010b2000410036020c0b200241a0046a24000bd80e03057f037e067f23004190046b2202240041002103200241003a00c8032001280204417f6a210402400240024002400240024002400240024003402004417f460d01200241a8036a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8032004417f6a21042005210320054120470d000b200241d0036a41086a2204200241a8036a41086a290300370300200241d0036a41106a2203200241a8036a41106a290300370300200241d0036a41186a2206200241a8036a41186a290300370300200220022903a8033703d003200541ff0171411f4d0d0120024188016a41086a2004290300220737030020024188016a41106a2003290300220837030020024188016a41186a20062903002209370300200241e8006a41186a2009370300200241e8006a41106a2008370300200241e8006a41086a2007370300200220022903d00322073703a8022002200737038801200220073703682002200110ab0120022802000d042002280204210641002103200241003a00c8032001280204417f6a210403402004417f460d03200241a8036a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8032004417f6a21042005210320054120470d000b200241d0036a41086a2203200241a8036a41086a290300370300200241d0036a41106a220a200241a8036a41106a290300370300200241d0036a41186a220b200241a8036a41186a290300370300200220022903a8033703d003200541ff0171411f4d0d03200241c8016a41086a20032903002207370300200241c8016a41106a200a2903002208370300200241c8016a41186a200b2903002209370300200241a8016a41186a2009370300200241a8016a41106a2008370300200241a8016a41086a2007370300200220022903d00322073703a802200220073703c801200220073703a80141002103200241003a00c80303402004417f460d06200241a8036a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8032004417f6a21042005210320054120470d000b200241d0036a41086a2204200241a8036a41086a290300370300200241d0036a41106a2203200241a8036a41106a290300370300200241d0036a41186a220a200241a8036a41186a290300370300200220022903a8033703d003200541ff0171411f4d0d0620024188026a41086a2004290300220737030020024188026a41106a2003290300220837030020024188026a41186a200a2903002209370300200241e8016a41186a2009370300200241e8016a41106a2008370300200241e8016a41086a2007370300200220022903d00322073703a8022002200737038802200220073703e801200241a8036a200110b50520022802a8032204450d0720022902ac032107200241c8006a41186a2201200241e8006a41186a290300370300200241c8006a41106a2203200241e8006a41106a290300370300200241c8006a41086a2205200241e8006a41086a290300370300200241286a41086a220a200241a8016a41086a290300370300200241286a41106a220b200241a8016a41106a290300370300200241286a41186a220c200241a8016a41186a290300370300200241086a41086a220d200241e8016a41086a290300370300200241086a41106a220e200241e8016a41106a290300370300200241086a41186a220f200241e8016a41186a29030037030020022002290368370348200220022903a801370328200220022903e801370308200020073702082000200436020420002006360200200041106a2002290348370200200041186a2005290300370200200041206a2003290300370200200041286a2001290300370200200041306a2002290328370200200041386a200a290300370200200041c0006a200b290300370200200041c8006a200c290300370200200041e8006a200f290300370200200041e0006a200e290300370200200041d8006a200d290300370200200041d0006a20022903083702000c080b200341ff0171450d00200241003a00c8030b20024188016a41086a200241a8026a41086a29030037030020024188016a41106a200241a8026a41106a29030037030020024188016a41186a200241a8026a41186a290300370300200220022903a80237038801200041003602040c060b200341ff0171450d00200241003a00c8030b200241c8016a41086a200241a8026a41086a290300370300200241c8016a41106a200241a8026a41106a290300370300200241c8016a41186a200241a8026a41186a290300370300200220022903a8023703c801200041003602040c040b200041003602040c030b200341ff0171450d00200241003a00c8030b20024188026a41086a200241a8026a41086a29030037030020024188026a41106a200241a8026a41106a29030037030020024188026a41186a200241a8026a41186a290300370300200220022903a80237038802200041003602040c010b200041003602040b20024190046a24000b0f00200028020020012002107441000b8a0201027f230041106b22022400200028020021002002410036020c02400240024002402001418001490d002001418010490d012002410c6a21032001418080044f0d0220022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d410321010c030b200220013a000c2002410c6a2103410121010c020b20022001413f71418001723a000d2002200141067641c001723a000c2002410c6a2103410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b2000200320011074200241106a240041000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a419cebc000200241086a103d2101200241206a240020010bdf0101087f0240200028020422020d0041000f0b2000280200210320012d002041ff01712104037f200241346a210020022f01322105410021060240024003400240200520062207470d00200521070c030b02400240024020012000412010ec082206450d00410121082006417f4c0d050c010b2004200041206a2d00002206460d01417f200420064720042006491b21080b200741016a2106200041216a210041012109200841016a0e03030201030b0b410121090b20090f0b024020030d0041000f0b2003417f6a2103200220074102746a41a0036a28020021020c000b0b980101057f0240200028020422020d0041000f0b200028020021030340200241346a210420022f013221054100210002400240034020052000460d0120012004412010ec082206450d02200041016a2100200441206a21042006417f4a0d000b2000417f6a21050b024020030d0041000f0b2003417f6a2103200220054102746a4194036a28020021020c010b0b200220004102746a41046a0b9a0101057f0240200028020422020d0041000f0b20002802002103034020024190026a210420022f018e0221054100210002400240034020052000460d0120012004412010ec082206450d02200041016a2100200441206a21042006417f4a0d000b2000417f6a21050b024020030d0041000f0b2003417f6a2103200220054102746a41f0046a28020021020c010b0b2002200041186c6a41046a0b960101057f0240200028020422020d0041000f0b200028020021030340200241e0006a210420022f015e21054100210002400240034020052000460d0120012004412010ec082206450d02200041016a2100200441206a21042006417f4a0d000b2000417f6a21050b024020030d0041000f0b2003417f6a2103200220054102746a41c0036a28020021020c010b0b200220004103746a0ba90301087f02400240024020012802042203450d00200128020021040c010b41a003102c2203450d0141002104200341003b01322003410036020020012003360204200141003602000b20022d002041ff017121050340200341346a210620032f0132210741002108024003400240200720082209470d00200721090c020b02400240024020022006412010ec082208450d004101210a2008417f4c0d040c010b2005200641206a2d00002208460d01417f200520084720052008491b210a0b200941016a2108200641216a2106200a41016a0e03020001020b0b20002004360204200041106a20013602002000410c6a2009360200200041086a2003360200200041013602000f0b02402004450d002004417f6a2104200320094102746a41a0036a28020021030c010b0b20004100360204200041106a20013602002000410c6a2009360200200041086a2003360200200041146a20022900003700002000411c6a200241086a290000370000200041246a200241106a2900003700002000412c6a200241186a290000370000200041346a200241206a2d00003a0000200041003602000f0b1036000bc01c03067f037e187f230041e0016b22032400200341206a41186a200141186a290000370300200341206a41106a200141106a290000370300200341206a41086a200141086a2900003703002003200129000037032002400240024002400240024002400240024002400240024002400240024020002802042204450d00200028020021050c010b419403102c2204450d0141002105200441003b01322004410036020020002004360204200041003602000b02400340200441346a210620042f01322107410021010240034020072001460d01200341206a2006412010ec082208450d03200141016a2101200641206a21062008417f4a0d000b2001417f6a21070b02402005450d002005417f6a2105200420074102746a4194036a28020021040c010b0b200341086a2003412c6a2902002209370300200341106a200341346a290200220a370300200341186a2003413c6a280200220136020020032003290224220b3703002003280220210c200341a0016a41186a22062001360200200341a0016a41106a2208200a370300200341a0016a41086a220520093703002003200b3703a001024020042f01322201410a4b0d00200341206a41186a2006280200360200200341206a41106a2008290300370300200341206a41086a2005290300370300200320032903a001370320200441346a2106200141016a21080240200741016a220520014b220d0d00200620054105746a200620074105746a20082007417f736a41057410ea081a0b200620074105746a2201200c360000200120032903203700042001410c6a200341286a290300370000200141146a200341306a2903003700002001411c6a200341386a280200360000200441046a21010240200d0d00200120054102746a200120074102746a20082007417f736a41027410ea081a0b200120074102746a2002360200200420083b01320c0d0b410521014100210e02400240200741054f0d0041042101200721080c010b41052108024002402007417b6a0e020201000b200741796a21084101210e410621010c010b410021084101210e0b419403102c2206450d01200641003b013220064100360200200620042f0132220d2001417f736a22073b0132200441346a220f20014105746a22052800002110200341386a2005411c6a280000360200200341306a200541146a290000370300200341286a2005410c6a290000370300200320052900043703202007410c4f0d02200d200141016a22056b2007470d03200441046a220d20014102746a2802002111200641346a200f20054105746a200741057410e9081a200641046a200d20054102746a200741027410e9081a200420013b0132200341c0016a41086a200341206a41086a2205290300370300200341c0016a41106a200341206a41106a220d290300370300200341c0016a41186a200341206a41186a220f280200360200200320032903203703c00120062004200e1b22072f01322101200f200341a0016a41186a280200360200200d200341a0016a41106a2903003703002005200341a0016a41086a290300370300200320032903a001370320200741346a210e200141016a21120240200841016a221320014b22140d00200e20134105746a200e20084105746a20122008417f736a41057410ea081a0b200e20084105746a2201200c360000200120032903203700042001410c6a2005290300370000200141146a200d2903003700002001411c6a200f280200360000200741046a2101024020140d00200120134102746a200120084102746a20122008417f736a41027410ea081a0b200120084102746a2002360200200720123b013220034180016a41086a2215200341c0016a41086a2216290300220937030020034180016a41106a2217200341c0016a41106a2218290300220a37030020034180016a41186a2219200341c0016a41186a221a2802002201360200200320032903c001220b37038001200341e0006a41186a22122001360200200341e0006a41106a2213200a370300200341e0006a41086a221420093703002003200b370360024002400240200428020022020d004100211b0c010b4100211b2011211c2006211d2010211e034020042f01302104200341a0016a41186a221f2012280200360200200341a0016a41106a22202013290300370300200341a0016a41086a22212014290300370300200320032903603703a0014101450d0720022f0132220e410b490d024100210541042101024020044105490d0020042101024002402004417b6a0e020201000b200441796a210441012105410621010c010b4100210441012105410521010b41c403102c2206450d04200641003b013220064100360200200620022f013222112001417f736a22083b0132200241346a222220014105746a22072800002110200341206a41186a220c2007411c6a280000360200200341206a41106a220d200741146a290000370300200341206a41086a220f2007410c6a290000370300200320072900043703202008410c4f0d082011200141016a22076b2008470d09200241046a222320014102746a2802002111200641346a202220074105746a200841057410e9081a200641046a2023200741027422076a200841027410e9081a200220013b01322016200f2903003703002018200d290300370300201a200c280200360200200320032903203703c00120062f0132220841016a21222008410c4f0d0a200e20016b22012022470d0b201b41016a211b20064194036a200220076a4194036a200141027410e9081a4100210102400340200620014102746a4194036a280200220720013b0130200720063602002001200120084922076a220120084b0d0120070d000b0b2019201a2802003602002017201829030037030020152016290300370300200320032903c001370380012006200220051b22072f0132210e200c201f280200360200200d2020290300370300200f2021290300370300200320032903a001370320200741346a2108200e41016a21050240200441016a2201200e4b221f0d00200820014105746a200820044105746a2004417f7320056a41057410ea081a0b200820044105746a2208201e360000200820032903203700042008410c6a200f290300370000200841146a200d2903003700002008411c6a200c280200360000200741046a21080240201f0d00200820014102746a200820044102746a2004417f7320056a41027410ea081a0b20082004410274220d6a201c36020020074194036a21080240200441026a220f200e41026a220c4f0d002008200f4102746a200820014102746a2001417f73200c6a41027410ea081a0b200820014102746a201d360200200720053b013202402001200c4f0d002007200d6a4198036a2101034020012802002208200441016a22043b013020082007360200200141046a210120052004470d000b0b2014201529030037030020132017290300370300201220192802003602002003200329038001370360200221042002280200220121022011211c2006211d2010211e20010d000b0b200341c0006a41186a20122802002201360200200341c0006a41106a20132903002209370300200341c0006a41086a2014290300220a37030020032003290360220b370340201a2001360200201820093703002016200a3703002003200b3703c00120002802042208450d0a2000280200210741c403102c2201450d022001200836029403200141003b013220014100360200200841003b013020082001360200200020013602042000200741016a360200200341206a41186a200341c0016a41186a280200360200200341206a41106a200341c0016a41106a290300370300200341206a41086a200341c0016a41086a290300370300200320032903c0013703202007201b470d0b20012f01322207410b4f0d0c200120074105746a220841346a2010360000200841386a2003290320370000200841c0006a200341286a290300370000200841c8006a200341306a290300370000200841d0006a200341386a2802003600002001200741016a22083b0132200120084102746a4194036a2006360200200120074102746a41046a2011360200200620083b0130200620013602002000200028020841016a3602080c0e0b20022f01322108200341206a41186a220c200341a0016a41186a280200360200200341206a41106a220d200341a0016a41106a290300370300200341206a41086a220f200341a0016a41086a290300370300200320032903a001370320200441016a2101200241346a2106200841016a21070240200420084f22050d00200620014105746a200620044105746a2004417f7320076a41057410ea081a0b200620044105746a2206201e360000200620032903203700042006410c6a200f290300370000200641146a200d2903003700002006411c6a200c280200360000200241046a2106024020050d00200620014102746a200620044102746a2004417f7320076a41027410ea081a0b20062004410274220c6a201c36020020024194036a2106200841026a2104024020050d00200c20066a41086a200620014102746a2001417f7320046a41027410ea081a0b200620014102746a201d360200200220073b0132200120044f0d0c200841016a210720022001417f6a22014102746a4198036a2106034020062802002208200141016a22013b013020082002360200200641046a210620072001470d000c0d0b0b200420014102746a41046a20023602000c0c0b1036000b2007410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b41ac9cc700413541e49cc7001039000b2008410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b2022410c41f49cc700104d000b41f49bc7004128419c9cc7001039000b41e8aac700412b4194abc7001039000b41e899c700413041989ac7001039000b41a89ac700412041c89ac7001039000b2000200028020841016a3602080b200341e0016a24000beb0201067f230041206b220124000240024002402000410c6a28020022022002417f6a200041046a28020020002802006b716b4101470d00200221030240024002402002450d00200220026a22032002490d04200141106a41086a4104360200200120024102743602142001200028020836021020012003410274200341ffffffff0371200346410274200141106a107d200141086a280200210320012802004101460d01200020012802043602082000410c6a200341027622033602000b20032002410174470d0420002802002204200041046a28020022054d0d022005200220046b22064f0d01200041086a280200220320024102746a2003200541027410e9081a200041046a2200200028020020026a3602000c020b2003450d021036000b200041086a2802002202200320066b22034102746a200220044102746a200641027410e9081a200020033602000b200141206a24000f0b1038000b41c4ebc000412b41f0ebc0001039000bd20302037f017e23004180126b2203240020034280808080802037020c2003200236021c200320013602182003200341186a360208200341b80e6a200341086a10ed010240024020032903a00f4203510d00200341f00a6a200341b80e6a41c80310e9081a02402003280208220228020422044104490d0020022802002205280000210120022004417c6a3602042002200541046a360200200341880a6a200341f00a6a41e80010e9081a20032903d80b2106200341b0076a200341e00b6a41d80210e9081a0c020b024020032903d80b4202510d0020032d00f00a41ff01714102470d0020032802f80a450d0020032802f40a102e0b200341880c6a108b020b420321060b200341c8066a200341880a6a41e80010e9081a200341f0036a200341b0076a41d80210e9081a0240024020064203510d00200341206a200341c8066a41e80010e9081a200320063703880120034190016a200341f0036a41d80210e9081a200320013602e803024020032802082802040d002000200341206a41d00310e9081a0c020b20004203370368024020064202510d0020032d002041ff01714102470d002003280228450d002003280224102e0b200341b8016a108b020c010b200042033703680b20034180126a24000bef1a03037f037e197f230041f0036b2205240020012802042106200128020021072001280208220141086a2900002108200141106a29000021092001290000210a200541186a220b200141186a290000370300200541106a220c2009370300200541086a220d20083703002005200a3703002003410174210e2005410772210f200541c8016a41186a2110200541c8016a410c6a2111200541c8016a41206a211241002113410021144100211502400240024002400240024002400240024002400240024002400240024002400340201541017621010240024020154101710d00200120034b0d03200541003a00d001200520013602cc01200520023602c8010c010b200120034b0d03200120034f0d04200541013a00d001200520023602c801200520013602cc012005200220016a2d000041f001713a00d1010b200541d0036a20072005200541c8016a200628020c110400024020052802d00322160d00200541c8016a41086a2213200541086a290300370300200541c8016a41106a2203200541106a290300370300200541c8016a41186a2217200541186a290300370300200520052903003703c8014130102c2201450d10200120052903c80137000120012005290020370021200120144100473a0000200141096a2013290300370000200141116a2003290300370000200141196a2017290300370000200141286a200541276a29000037000020004101360200200020013602040c0f0b20052802d803210120052802d4032118024002400240200428020c20144b0d002001417f4c0d130240024020010d00410121170c010b2001102c2217450d130b20172016200110e90821192010200b290300370300200541c8016a41106a221a200c290300370300200541c8016a41086a221b200d290300370300200520052903003703c801024020042802082217200441046a221c280200470d00201741016a221d2017490d142017410174221e201d201e201d4b1b221d4104201d41044b1bad42307e2208422088a745410274211d2008a7211e0240024020170d00200541003602200c010b200541043602282005201741306c360224200520042802003602200b200541d0036a201e201d200541206a107d20052802d803211720052802d0034101460d02200420052802d403360200201c201741306e360200200428020821170b2004280200201741306c6a2217201936020420172014360200201720052903c8013702102017410c6a2001360200201741086a2001360200201741186a201b290300370200201741206a201a290300370200201741286a20102903003702002004200428020841016a3602080b200541c8016a2016200110a80220052d00c8014101460d0e201441016a21140c010b20170d100c110b034020052802e401211f20052802e001212020052802dc01212120052802d801211920052802d401211720052802d001211a20052802cc012101200541206a201241a80110e9081a200528029403211b200528029003211c024002400240024020010e05100f000102100b410021010240201741017420196b2222200e20136b221b201b20224b1b2223450d000340201320016a221b410176221c20034f0d0a201920016a221d410176221e20174f0d0b2002201c6a2d0000221c410f71201c41f00171410476201b4101711b201a201e6a2d0000221b410f71201b410476201d4101711b470d012023200141016a2201470d000b202321010b024020012022470d00202221010c030b200042003702000c110b2005201f3602dc01200520203602d801200520213602d401200520193602d001200520173602cc012005201a3602c8012010200541206a41a80110e9081a02400240200e2013460d002013410176220120034f0d0b200541c8016a200220016a2d00002201410f71200141047620134101711b410c6c6a220128020022214102470d01200042003702000c120b410021010240201c450d00201b417f4c0d1502400240201b0d00410121010c010b201b102c2201450d150b2001201c201b10e9081a0b20002001360204200041003602002000410c6a201b360200200041086a201b3602000c110b20012802042120200141086a280200211f41012122410121010c010b20052802a0032123200528029c03212220052802980321012005201f3602d001200520203602cc01200520213602c8012011200541206a41a80110e9081a20052001360284032005201b360280032005201c3602fc02410021010240201741017420196b221f200e20136b22212021201f4b1b2220450d000340201320016a221b410176221c20034f0d0b201920016a221d410176221e20174f0d0c2002201c6a2d0000221c410f71201c41f00171410476201b4101711b201a201e6a2d0000221b410f71201b410476201d4101711b470d012020200141016a2201470d000b202021010b02402001201f460d00200042003702000c100b024002402021201f460d002013201f6a2201410176221720034f0d0d200541c8016a200220176a2d00002217410f71201741047620014101711b410c6c6a221728020022214102470d01200042003702000c110b4100210102402022450d002023417f4c0d140240024020230d00410121010c010b2023102c2201450d140b20012022202310e9081a0b20002001360204200041003602002000410c6a2023360200200041086a20233602000c100b201f41016a2122201f41016a210120172802042120201741086a280200211f0b200120156a2115201320226a211302402021450d00200541c8016a2020201f10a80220052d00c8014101460d0e0c010b0b02400240201f4120460d002010200b290300370300200541c8016a41106a2201200c290300370300200541c8016a41086a2217200d290300370300200520052903003703c801201f417f4c0d1202400240201f0d00410121190c010b201f102c2219450d120b20192020201f10e9082119200541d0036a41186a221a2010290300370300200541d0036a41106a221b2001290300370300200541d0036a41086a221c2017290300370300200520052903c8013703d0034130102c2201450d11200141043a0000200120052903d003370001200120052f00c8013b00212001201f36002c2001201f36002820012019360024200141096a201c290300370000200141116a201b290300370000200141196a201a290300370000200141236a200541c8016a41026a2d00003a0000410121170c010b41002117200541c8016a41026a41003a0000200541003b01c80120202f00002119200541cc036a41026a202041026a2d00003a00002020411f6a2d0000211a202041176a29000021082020280003210120202900072109200541d0036a41086a221b2020410f6a290000370300200541d0036a41106a221c2008370300200541d0036a41186a221d201a3a0000200520193b01cc03200520093703d0032010201d2d00003a0000200541c8016a41106a201c290300370300200541c8016a41086a201b290300370300200520052903d0033703c8010b200541c8036a41026a2219200541cc036a41026a2d00003a0000200541a8036a41086a221a200541c8016a41086a290300370300200541a8036a41106a221b200541c8016a41106a290300370300200541a8036a41186a221c2010280200360200200520052f01cc033b01c803200520052903c8013703a803024020170d00200f20052903a803370000200f41086a201a290300370000200f41106a201b290300370000200f41186a201c2d00003a0000200520052f01c8033b010020052001360003200520192d00003a00022018450d012016102e0c010b0b20004101360200200020013602040c0c0b2001200341a0f0cc00104d000b2001200341b0f0cc00104d000b2001200341c0f0cc00103c000b201c200341e0efcc00103c000b201e201741e0efcc00103c000b2001200341e0efcc00103c000b201c200341e0efcc00103c000b201e201741e0efcc00103c000b2017200341e0efcc00103c000b41002104024002400240201741017420196b200e20136b2215470d004100210441002101024002402015450d00410021010340201920016a221b410176221c20174f0d04201320016a221d410176221e20034f0d05201a201c6a2d0000221c410f71201c41f00171410476201b4101711b2002201e6a2d0000221b410f71201b410476201d4101711b470d012015200141016a2201470d000c020b0b20012015470d010b2020417f4c0d080240024020200d00410121040c010b2020102c2204450d080b20042021202010e9081a2020ad220842208620088421080b2000200436020420004100360200200041086a20083702000c040b201c201741e0efcc00103c000b201e200341e0efcc00103c000b200042003702000c010b20052d00c9012113200541d0036a41086a2203200541086a290300370300200541d0036a41106a2217200541106a290300370300200541d0036a41186a2219200541186a290300370300200520052903003703d0034130102c2201450d02200141033a0000200120052903d003370001200120133a0021200120052901a803370122200141096a2003290300370000200141116a2017290300370000200141196a2019290300370000200141286a200541ae036a29010037010020004101360200200020013602040b2018450d002016102e0b200541f0036a24000f0b1036000b1038000b9e1203027f027e127f230041b0096b2203240041002104200341003602a806200320023602a406200320013602a006420321050240024020020d0042002106410021070c010b41012107200341013602a80642002106024020012d000022080d00420021050c010b0240024002400240024002400240024002400240200841c00171220941c001460d0002402009418001460d00200941c000470d0b2008413f712208413f470d05410221074141210803402007417f6a20024f0d03200320073602a8060240200120076a417f6a2d0000220941ff01460d00200920086b21080c0c0b200841817e6a2108200741016a2207418302470d000b41ffff03210841820221070c0a0b2008413f712208413f470d05410221074141210803402007417f6a20024f0d03200320073602a8060240200120076a417f6a2d0000220941ff01460d00200920086b21080c0a0b200841817e6a2108200741016a2207418302470d000b41ffff03210841820221070c080b2008413f712208413f470d05410221074141210803402007417f6a20024f0d03200320073602a8060240200120076a417f6a2d0000220941ff01460d00200920086b21080c080b200841817e6a2108200741016a2207418302470d000b41ffff03210841820221070c060b2007417f6a21070c080b2007417f6a21070c070b2007417f6a21070c060b410121070c040b410121070c020b410121070b2008ad422086428002842106420121050c020b2008ad4220862106420121050c010b2008ad4220862106420221050b2006422088a721094101210a41012108024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402005200684a741ff01710e040500010a050b2009410171220b450d03200720024f0d0141002108200120076a2d00004110490d030c090b2009410171220b450d010240200720024f0d0041002108200120076a2d00004110490d020c090b2007200241f4cec800103c000b200720024184cfc800103c0c030b2007200941016a4101766a220c20024b0d052003200c3602a806200341106a200341a0066a10d70420032802100d0520032802a806220d20032802146a220e20032802a4064b0d052003200e3602a806200341e0046a200341f0076a41c00110e9081a410121040c010b2007200941016a4101766a220c20024b0d042003200c3602a806200c41026a220820024b0d04200320083602a806200c417e4f0d062001200c6a2f00002104410021094100210d0240200642800283500d00200341086a200341a0066a10d70420032802080d054101210820032802a806220e200328020c6a220f20032802a4064b0d062003200f3602a8064101210d0b200341023602a40920034102360298092003410236028c092003410236028009200341023602f408200341023602e808200341023602dc08200341023602d008200341023602c408200341023602b808200341023602ac08200341023602a00820034102360294082003410236028808200341023602fc07200341023602f007200341f0076a2108200441ffff037121100340024020102009410f7176410171450d002003200341a0066a10d70420032802000d0620032802a8062211200328020422126a220420032802a4064b0d06200320043602a806200841086a2004360200200841046a2011360200200820124120473602000b2008410c6a2108200941016a22094110470d000b200341e0046a200341f0076a41c00110e9081a410421040b200341a0036a200341e0046a41c00110e9081a200341c0016a41186a200f360200200341c0016a41146a200e360200200341c0016a41106a200d360200200341c0016a410c6a200b360200200341c0016a41086a200c360200200320073602c401200320043602c001200341c0016a411c6a200341a0036a41c00110e9081a4100210a4100211320040e050e010000020e0b000b200c2007490d04200c20024b0d05200e200d490d06200e20024b0d07200c20076b2109200120076a21082001200d6a2114200e200d6b2115410121130c0c0b200341023602a40920034102360298092003410236028c092003410236028009200341023602f408200341023602e808200341023602dc08200341023602d008200341023602c408200341023602b808200341023602ac08200341023602a00820034102360294082003410236028808200341023602fc07200341023602f007410021080340410221040240200341c0016a20086a2209411c6a22102802004102460d00200941246a2802002111200941206a28020021090240024020102802004101470d0020112009490d0b41012104201120024d0d012011200241d4f2cc00104d000b20112009490d0b41002104201120024b0d0c0b201120096b2111200120096a21120b200341f0076a20086a22092004360200200941086a2011360200200941046a20123602002008410c6a220841c001460d0b0c000b0b410121080b200341a0036a200341e0046a41c00110e9081a200020083a00010c0a0b200c200841e4cec8001057000b2007200c41c4f3cc001057000b200c200241c4f3cc00104d000b200d200e41d4f3cc001057000b200e200241d4f3cc00104d000b2009201141d4f2cc001057000b2009201141e4f2cc001057000b2011200241e4f2cc00104d000b02400240200d4101460d00410021120c010b200f200e490d03200f20024b0d04200f200e6b21112001200e6a21120b200c2007490d04200c20024b0d05200341f8076a280200211620032802f407211520032802f0072114200341186a200341fc076a41a80110e9081a200c20076b2109200120076a2108200341ac096a2802002110200341a8096a280200211720032802a4092118410421130b2000411c6a2016360200200041186a2015360200200041146a2014360200200041106a200b3602002000410c6a2009360200200041086a2008360200200041046a2013360200200041206a200341186a41a80110e9081a200041d8016a2011360200200041d4016a2012360200200041d0016a2010360200200041cc016a2017360200200041c8016a20183602000b2000200a3a0000200341b0096a24000f0b200e200f41e4f3cc001057000b200f200241e4f3cc00104d000b2007200c41c4f3cc001057000b200c200241c4f3cc00104d000b7e01027f230041306b22022400200241146a410436020020024188e2cc003602102002410436020c20024180e2cc003602082001411c6a2802002103200128021821012002412c6a41023602002002420237021c20024190e2cc003602182002200241086a36022820012003200241186a103d2101200241306a240020010bc81703037f037e197f230041f0036b2204240020012802042105200128020021062001280208220141086a2900002107200141106a290000210820012900002109200441186a220a200141186a290000370300200441106a220b2008370300200441086a220c2007370300200420093703002003410174210d2004410772210e200441c8016a41186a210f200441c8016a410c6a2110200441c8016a41206a211141002112410021134100211402400240024002400240024002400240024002400240024002400240024002400340201441017621010240024020144101710d00200120034b0d03200441003a00d001200420013602cc01200420023602c8010c010b200120034b0d03200120034f0d04200441013a00d001200420023602c801200420013602cc012004200220016a2d000041f001713a00d1010b200441d0036a20062004200441c8016a200528020c11040002400240024020042802d00322150d00200441c8016a41086a2212200441086a290300370300200441c8016a41106a2203200441106a290300370300200441c8016a41186a2216200441186a290300370300200420042903003703c8014130102c22010d010c130b20042802d4032117200441c8016a201520042802d80310a80220042d00c8014101460d0f201341016a21130c010b200120042903c80137000120012004290020370021200120134100473a0000200141096a2012290300370000200141116a2003290300370000200141196a2016290300370000200141286a200441276a29000037000020004101360200200020013602040c100b034020042802e401211820042802e001211920042802dc01211a20042802d801211b20042802d401211620042802d001211c20042802cc012101200441206a201141a80110e9081a200428029403211d200428029003211e024002400240024020010e05110f000102110b4100210102402016410174201b6b221f200d20126b221d201d201f4b1b2220450d000340201220016a221d410176221e20034f0d0a201b20016a2221410176222220164f0d0b2002201e6a2d0000221e410f71201e41f00171410476201d4101711b201c20226a2d0000221d410f71201d41047620214101711b470d012020200141016a2201470d000b202021010b02402001201f470d00201f21010c030b200042003702000c120b200420183602dc01200420193602d8012004201a3602d4012004201b3602d001200420163602cc012004201c3602c801200f200441206a41a80110e9081a02400240200d2012460d002012410176220120034f0d0b200441c8016a200220016a2d00002201410f71200141047620124101711b410c6c6a2201280200221a4102470d01200042003702000c130b410021010240201e450d00201d417f4c0d1002400240201d0d00410121010c010b201d102c2201450d160b2001201e201d10e9081a0b20002001360204200041003602002000410c6a201d360200200041086a201d3602000c120b20012802042119200141086a28020021184101211f410121010c010b20042802a0032120200428029c03211f2004280298032101200420183602d001200420193602cc012004201a3602c8012010200441206a41a80110e9081a20042001360284032004201d360280032004201e3602fc024100210102402016410174201b6b2218200d20126b221a201a20184b1b2219450d000340201220016a221d410176221e20034f0d0b201b20016a2221410176222220164f0d0c2002201e6a2d0000221e410f71201e41f00171410476201d4101711b201c20226a2d0000221d410f71201d41047620214101711b470d012019200141016a2201470d000b201921010b024020012018460d00200042003702000c110b02400240201a2018460d00201220186a2201410176221620034f0d0d200441c8016a200220166a2d00002216410f71201641047620014101711b410c6c6a2216280200221a4102470d01200042003702000c120b410021010240201f450d002020417f4c0d0f0240024020200d00410121010c010b2020102c2201450d150b2001201f202010e9081a0b20002001360204200041003602002000410c6a2020360200200041086a20203602000c110b201841016a211f201841016a210120162802042119201641086a28020021180b200120146a21142012201f6a21120240201a450d00200441c8016a2019201810a80220042d00c8014101460d0f0c010b0b0240024020184120460d00200f200a290300370300200441c8016a41106a2201200b290300370300200441c8016a41086a2216200c290300370300200420042903003703c8012018417f4c0d0d0240024020180d004101211b0c010b2018102c221b450d130b201b2019201810e908211b200441d0036a41186a221c200f290300370300200441d0036a41106a221d2001290300370300200441d0036a41086a221e2016290300370300200420042903c8013703d0034130102c2201450d12200141043a0000200120042903d003370001200120042f00c8013b00212001201836002c200120183600282001201b360024200141096a201e290300370000200141116a201d290300370000200141196a201c290300370000200141236a200441c8016a41026a2d00003a0000410121160c010b41002116200441c8016a41026a41003a0000200441003b01c80120192f0000211b200441cc036a41026a201941026a2d00003a00002019411f6a2d0000211c201941176a29000021072019280003210120192900072108200441d0036a41086a221d2019410f6a290000370300200441d0036a41106a221e2007370300200441d0036a41186a2221201c3a00002004201b3b01cc03200420083703d003200f20212d00003a0000200441c8016a41106a201e290300370300200441c8016a41086a201d290300370300200420042903d0033703c8010b200441c8036a41026a221b200441cc036a41026a2d00003a0000200441a8036a41086a221c200441c8016a41086a290300370300200441a8036a41106a221d200441c8016a41106a290300370300200441a8036a41186a221e200f280200360200200420042f01cc033b01c803200420042903c8013703a803024020160d00200e20042903a803370000200e41086a201c290300370000200e41106a201d290300370000200e41186a201e2d00003a0000200420042f01c8033b0100200420013600032004201b2d00003a00022017450d012015102e0c010b0b20004101360200200020013602040c0d0b2001200341a0f0cc00104d000b2001200341b0f0cc00104d000b2001200341c0f0cc00103c000b201e200341e0efcc00103c000b2022201641e0efcc00103c000b2001200341e0efcc00103c000b201e200341e0efcc00103c000b2022201641e0efcc00103c000b2016200341e0efcc00103c000b410021180240024002402016410174201b6b200d20126b2214470d004100211841002101024002402014450d00410021010340201b20016a221d410176221e20164f0d04201220016a2221410176222220034f0d05201c201e6a2d0000221e410f71201e41f00171410476201d4101711b200220226a2d0000221d410f71201d41047620214101711b470d012014200141016a2201470d000c020b0b20012014470d010b2019417f4c0d030240024020190d00410121180c010b2019102c2218450d090b2018201a201910e9081a2019ad220742208620078421070b2000201836020420004100360200200041086a20073702000c050b201e201641e0efcc00103c000b2022200341e0efcc00103c000b1038000b200042003702000c010b20042d00c9012112200441d0036a41086a2203200441086a290300370300200441d0036a41106a2216200441106a290300370300200441d0036a41186a221b200441186a290300370300200420042903003703d0034130102c2201450d02200141033a0000200120042903d003370001200120123a0021200120042901a803370122200141096a2003290300370000200141116a2016290300370000200141196a201b290300370000200141286a200441ae036a29010037010020004101360200200020013602040b2017450d002015102e0b200441f0036a24000f0b1036000b9f0402027f037e230041f0006b2201240002404101102c22020d001036000b200241003a0000410041003502e8f54c200141d0006aad7c42adfed5e4d485fda8d8007e42218922033e02e8f54c200141c0006a41e8f5cc00ad220442a4bb99fed1a0bbb02385420042adfed5e4d485fda8d800420010e808200141206a200342a4bb99fed1a0bbb02385420042adfed5e4d485fda8d800420010e808200141306a200442c5ecb3fec9ecf7c2c30085420042adfed5e4d485fda8d800420010e808200141106a200342c5ecb3fec9ecf7c2c30085420042adfed5e4d485fda8d800420010e80820012003200485420042adfed5e4d485fda8d800420010e808200141d0006a41aad3c800410110b001200041286a4200370300200041246a41d0a1c00036020020004100360220200041346a428180808010370200200020023602302000200129005037003c200041c4006a200141d0006a41086a290000370000200041cc006a200141e0006a290000370000200041d4006a200141e8006a29000037000020002003200141c0006a41086a2903002001290340857c200141086a29030020012903008542cf829ebbefefde82147c2205893703002000200141106a41086a29030020012903108520047c20054230888937031820002003200141306a41086a2903002001290330857c2005422088893703102000200141206a41086a29030020012903208520047c200542108889370308200141f0006a24000bfd0101057f2000410c6a280200200028020822016b220241e0006d210302402002450d002001200341e0006c6a2104034002402001220541386a2802002201450d00200141d8006c2102200528023041306a21010340200128020022032003280200417f6a3602000240200128020022032802000d00200341046a22032003280200417f6a3602002001280200220341046a2802000d002003102e0b200141d8006a2101200241a87f6a22020d000b0b200541e0006a21010240200541346a2802002202450d00200241d8006c450d002005280230102e0b20012004470d000b0b024020002802042201450d00200141e0006c450d002000280200102e0b0b130020004109360204200041f0ecc0003602000bb10201027f230041206b220424000240024002400240024020022001413c6a412010ec080d00200141386a2802002202417f4c0d01200128023021050240024020020d00410121010c010b2002102c2201450d030b200020023602042000200136020020012005200210e9081a200041086a20023602000c040b200441186a200241186a290000370300200441106a200241106a290000370300200441086a200241086a290000370300200420022900003703002001200410af022202450d02200228020c4101480d0220022802082201417f4c0d00200228020021050240024020010d00410121020c010b2001102c2202450d020b200020013602042000200236020020022005200110e9081a200041086a20013602000c030b1038000b1036000b200041003602000b200441206a24000be10303017f047e087f230041306b22022400200241206a20002903182000290308852203200141186a2900008542002000290310220420002903002205852206200129001085420010e808200241106a2003200141086a2900008542002006200129000085420010e8082002200442002004200241106a41086a2903002002290310857c2004200241206a41086a2903002002290320857c200542adfed5e4d485fda8d8007e42a0cbbf9599b5a19f0a7c85421789854217892203420010e808200041246a280200220720002802202208200241086a290300200229030085200389a722097122006a280000220a200941197641818284086c220b732209417f73200941fffdfb776a71418081828478712109200041046a200871210c4104210d024003400240024020090d00200d21090340200c21000240200a200a4101747141808182847871450d004100210e0c050b2008200020096a41046a71210c200941046a220d2109200b200720006a280000220a73220e417f73200e41fffdfb776a7141808182847871220e450d000c020b0b2009210e20070d004100210e0c020b200e417f6a200e71210920012007410020082000200e684103766a716b41306c6a41506a220e412010ec080d000b0b200241306a2400200e41206a4100200e1b0bb60301057f230041e0006b22052400024002402004417f4c0d000240024020040d00410121060c010b2004102c2206450d020b20062003200410e9082107410021060240200141386a2802002004470d0020072001280230200410ec084521060b02402004450d002007102e0b024002402006450d002000200129003c370000200041186a200141d4006a290000370000200041106a200141cc006a290000370000200041086a200141c4006a2900003700000c010b20052003200410b001200541206a41186a200541186a2207290000370300200541206a41106a200541106a2208290000370300200541206a41086a200541086a220929000037030020052005290000370320200541c0006a41086a200241086a280200360200200520022902003703400240024020040d00410121060c010b2004102c2206450d030b200520043602542005200636025020062003200410e9081a200520043602582001200541206a200541c0006a200541d0006a10b102200041186a2007290000370000200041106a2008290000370000200041086a2009290000370000200020052900003700000b200541e0006a24000f0b1038000b1036000be50301047f23004180016b220424000240024020032802082205200041386a280200470d00200328020022062000280230200510ec080d00200341046a280200450d012006102e0c010b200441c0006a41186a2205200141186a290000370300200441c0006a41106a2206200141106a290000370300200441c0006a41086a2207200141086a2900003703002004200129000037034020042000200441c0006a10b202024020042903004201520d00200441c0006a41286a200441306a290300370300200441c0006a41206a200441286a2903003703002005200441206a2903003703002006200441186a2903003703002007200441106a29030037030020042004290308370340200441f0006a41086a200341086a2802003602002004410136027c20042003290200370370200441c0006a200441f0006a10b3020c010b0240200441106a2802002205417c6a2201280200220041004a0d00200541706a2106200441c0006a41086a2207200341086a280200360200200420032902003703400240200541746a280200450d002006280200102e200128020021000b20062004290340370200200641086a20072802003602002001200041016a3602000c010b2001200041016a360200200341046a280200450d002003280200102e0b20044180016a24000b880503017f047e097f230041306b22032400200341206a20012903182001290308852204200241186a2900008542002001290310220520012903002206852207200229001085420010e808200341106a2004200241086a2900008542002007200229000085420010e8082003200542002005200341106a41086a2903002003290310857c2005200341206a41086a2903002003290320857c200642adfed5e4d485fda8d8007e42a0cbbf9599b5a19f0a7c85421789854217892204420010e808200141246a280200220820012802202209200341086a2903002003290300852004892205a7220a71220b6a280000220c200a41197641818284086c220d73220a417f73200a41fffdfb776a7141808182847871210e200b41046a200971210f410421100240024003400240200e0d002010210a0340200f210b200c200c41017471418081828478710d032009200b200a6a41046a71210f200a41046a2210210a200d2008200b6a280000220c73220e417f73200e41fffdfb776a7141808182847871220e450d000b0b2008450d01200e68210a200e417f6a200e71210e200841002009200b200a4103766a716b41306c6a220a41506a2002412010ec080d000b2000200537030820004200370300200041186a41013a0000200041146a2001360200200041106a200a360200200041196a2002290000370000200041216a200241086a290000370000200041296a200241106a290000370000200041316a200241186a2900003700000c010b2000200537030820004201370300200041106a2001360200200041146a20022900003700002000411c6a200241086a290000370000200041246a200241106a2900003700002000412c6a200241186a2900003700000b200341306a24000bca0503027f077e067f23004180016b2202240020022000280208220336020c20002903002104200241106a41186a200041246a2902002205370300200241106a41106a2000411c6a2902002206370300200241106a41086a200041146a2902002207370300200241106a41286a200141086a29020022083703002002200029020c220937031020022001290200220a370330200241c0006a41286a2008370300200241c0006a41206a200a370300200241c0006a41186a2005370300200241c0006a41106a2006370300200241c0006a41086a200737030020022009370340200341206a210b2003280220220c2004a7220d712101200341246a280200210e4104210003402001220f20006a200c712101200041046a2100200e200f6a280000418081828478712210450d000b0240200e201068410376200f6a200c7122006a2c000022014100480d00200e200e280200418081828478716841037622006a2d000021010b200341286a280200210f024020014101712210450d00200f0d00200241f0006a200b2002410c6a10b4022003280220220c200d712101200341246a280200210e4104210003402001220f20006a200c712101200041046a2100200e200f6a28000041808182847871220b450d000b0240200e200b68410376200f6a200c7122006a2c00004100480d00200e280200418081828478716841037621000b2003280228210f0b2003200f20106b360228200e20006a200d41197622013a0000200c2000417c6a71200e6a41046a20013a0000200e410020006b41306c6a41506a220041286a200241c0006a41286a290300370200200041206a200241c0006a41206a290300370200200041186a200241c0006a41186a290300370200200041106a200241c0006a41106a290300370200200041086a200241c0006a41086a290300370200200020022903403702002003412c6a2200200028020041016a36020020024180016a24000be91007077f017e077f017e027f027e017f23004180016b220324000240024002400240200128020c220441016a22052004490d000240200520012802002206200641016a220741037641076c20064108491b22064101764b0d004100210641002105024003400240024020064101710d00200520074f0d0320052106200541016a21050c010b200541036a220620054922080d0220062007492209450d022007200541046a20081b200720091b21050b200141046a28020020066a220620062802002206410776417f73418182840871200641fffefdfb07726a360200410121060c000b0b200141046a2802002105200128020041016a22064104490d02200520066a20052800003600000c030b024002400240024002402005200641016a2206200520064b1b22050d0041d0a1c000210841002109410021050c010b02400240200541074b0d004104410820054104491b21050c010b200541ffffffff01712005470d04417f2005410374220541076e417f6a677641016a41012005410d4b1b21050b2005ad42307e220a422088a70d02200aa72206200541046a22096a22082006490d022008102c2208450d01200820066a220841ff01200910eb081a2005417f6a2209200541037641076c20094108491b21050b200841506a210b200520046b210c200141046a280200220d41046a210e200d20076a210f200d280200417f7341808182847871211020022802002111034002400240024020100d000340200e200f4f0d02200d41c07e6a210d200e2802002105200e41046a2206210e2005418081828478712205418081828478460d000b2005418081828478732207417f6a20077121102006210e0c020b200d450d00201021072010417f6a20107121100c010b2001200436020c2001200c360208200041003602002001280200210520012009360200200141046a22062802002107200620083602002005450d082007200541016aad42307ea76b102e0c080b41002105200341106a20112903182011290308852212200d41002007684103766b41306c6a41506a221341186a22142900008542002011290310220a20112903002215852216201329001085420010e808200341206a2012201341086a22172900008542002016201329000085420010e8082003200a4200200a200341206a41086a2903002003290320857c200a200341106a41086a2903002003290310857c201542adfed5e4d485fda8d8007e42a0cbbf9599b5a19f0a7c85421789854217892212420010e808200341086a290300200329030085201289220aa721060340200541046a2205200620097122076a2106200820076a280000418081828478712202450d000b0240200820026841037620076a20097122056a2c00004100480d002008280200418081828478716841037621050b200820056a200aa741197622063a00002005417c6a20097120086a41046a20063a0000200b410020056b41306c6a220541286a201341286a290200370200200541206a201341206a290200370200200541186a2014290200370200200541106a201341106a290200370200200541086a2017290200370200200520132902003702000c000b0b1036000b41accdcc00411c41c8cdcc001039000b41accdcc00411c41c8cdcc001039000b41accdcc00411c41c8cdcc001039000b200541046a2005200610ea081a0b41002105024020012802002204417f460d002002280200210d200141046a2110410021050340024020102802002208200522146a2d0000418001470d00410020146b21170340200341c0006a200d290318200d2903088522122008201741306c6a41506a220e41186a2213290000854200200d290310220a200d2903002215852216200e29001085420010e808200341d0006a2012200e41086a220f2900008542002016200e29000085420010e808200341306a200a4200200a200341d0006a41086a2903002003290350857c200a200341c0006a41086a2903002003290340857c201542adfed5e4d485fda8d8007e42a0cbbf9599b5a19f0a7c85421789854217892212420010e8082001280200210941002105200341306a41086a290300200329033085201289220aa7221121060340200541046a2205200620097122076a2106200820076a280000418081828478712202450d000b0240200820026841037620076a20097122056a2c00004100480d002008280200418081828478716841037621050b02402005200920117122066b201420066b7320097141034b0d00200820146a200aa741197622053a000020092014417c6a7120086a41046a20053a00000c020b200820056a22062d000021072006200aa741197622023a00002005417c6a20097120086a41046a20023a00000240200741ff01470d002010280200220620146a41ff013a0000200620012802002014417c6a716a41046a41ff013a00002010280200410020056b41306c6a41506a2205200e290200370200200541086a200f290200370200200541106a200e41106a290200370200200541186a2013290200370200200541206a200e41206a290200370200200541286a200e41286a2902003702000c020b2010280200410020056b41306c6a41506a2205290200210a2005200e290200370200200541186a2206290200211220062013290200370200200541106a220629020021152006200e41106a2207290200370200200541086a220629020021162006200f290200370200200f20163702002007201537020020132012370200200e200a370200200541286a2206290200210a2006200e41286a2207290200370200200529022021122005200e290220370220200e20123702202007200a370200201028020021080c000b0b201441016a210520142004470d000b20012802002205200541016a41037641076c20054108491b21050b2000410036020020012005200128020c6b3602080b20034180016a24000ba20201047f23004180016b22032400024020012000413c6a412010ec08450d00200341c0006a41186a2204200141186a290000370300200341c0006a41106a2205200141106a290000370300200341c0006a41086a2206200141086a2900003703002003200129000037034020032000200341c0006a10b202024020032903004201520d00200341c0006a41286a200341306a290300370300200341c0006a41206a200341286a2903003703002004200341206a2903003703002005200341186a2903003703002006200341106a29030037030020032003290308370340200342808080807037037820034201370370200341c0006a200341f0006a10b3020c010b200341106a280200417c6a22012001280200417f6a3602000b20034180016a24000b880101017f230041206b220324000240024020012000413c6a412010ec080d00410121010c010b200341186a200141186a290000370300200341106a200141106a290000370300200341086a200141086a2900003703002003200129000037030002402000200310af0222010d00410021010c010b200128020c41004a21010b200341206a240020010b1300200041e0f2c000360204200020013602000b9a0201067f024020002802202201450d0002402000412c6a280200450d00200041246a280200220241046a2103200120026a41016a21042002280200417f73418081828478712101024003400240024020010d000340200320044f0d04200241c07e6a210220032802002101200341046a220521032001418081828478712201418081828478460d000b2001418081828478732201417f6a2001712106200521030c010b2002450d022001417f6a20017121060b2001682105200621012002410020054103766b41306c6a220541746a280200450d00200541706a280200102e200621010c000b0b200028022021010b200041246a280200200141016aad42307ea76b102e0b0240200041346a280200450d002000280230102e0b0b1300200041e0f2c000360204200020013602000bb10201027f230041206b220424000240024002400240024020022001413c6a412010ec080d00200141386a2802002202417f4c0d01200128023021050240024020020d00410121010c010b2002102c2201450d030b200020023602042000200136020020012005200210e9081a200041086a20023602000c040b200441186a200241186a290000370300200441106a200241106a290000370300200441086a200241086a290000370300200420022900003703002001200410af022202450d02200228020c4101480d0220022802082201417f4c0d00200228020021050240024020010d00410121020c010b2001102c2202450d020b200020013602042000200236020020022005200110e9081a200041086a20013602000c030b1038000b1036000b200041003602000b200441206a24000b880101017f230041206b220324000240024020012000413c6a412010ec080d00410121010c010b200341186a200141186a290000370300200341106a200141106a290000370300200341086a200141086a2900003703002003200129000037030002402000200310af0222010d00410021010c010b200128020c41004a21010b200341206a240020010b8b0201047f200028020421012000410036020402402001450d00024020002802002202450d002002417f6a2102034020012802940321012002450d012002417f6a21020c000b0b024020002802082203450d004100210003402003417f6a210341012102024002400340200020012f0132490d010240200128020022040d002001102e410021010c030b20012f013021002001102e2002417f6a2102200421010c000b0b200041016a210020024101460d00200120004102746a4194036a280200210102402002450d000340200241016a220020024f210420012802940321012000210220040d000b0b410021000b20030d000b0b0340200128020021022001102e2002210120020d000b0b0b8a0201047f200028020421012000410036020402402001450d00024020002802002202450d002002417f6a21020340200128026021012002450d012002417f6a21020c000b0b024020002802082203450d004100210003402003417f6a210341012102024002400340200020012f015e490d01024020012802002204450d0020012f015c21002001102e2002417f6a2102200421010c010b0b2001102e410021010c010b200041016a210020024101460d00200120004102746a41e0006a280200210102402002450d000340200241016a220020024f2104200128026021012000210220040d000b0b410021000b20030d000b0b0340200128020021022001102e2002210120020d000b0b0b8b0201047f200028020421012000410036020402402001450d00024020002802002202450d002002417f6a2102034020012802c00321012002450d012002417f6a21020c000b0b024020002802082203450d004100210003402003417f6a210341012102024002400340200020012f015e490d010240200128025822040d002001102e410021010c030b20012f015c21002001102e2002417f6a2102200421010c000b0b200041016a210020024101460d00200120004102746a41c0036a280200210102402002450d000340200241016a220020024f210420012802c00321012000210220040d000b0b410021000b20030d000b0b0340200128025821022001102e2002210120020d000b0b0be90101047f200028020421012000410036020402402001450d00024020002802182202450d0020002802082103200028020021000340410120006b21002002417f6a2102024002400340200320012f0106490d010240200128020022040d002001102e410021010c030b20012f010421032001102e2000417f6a2100200421010c000b0b200341016a210320004101460d00200120034102746a41206a280200210102402000450d004100210303402001280220210120002003417f6a2203470d000b0b410021030b4100210020020d000b0b0340200128020021002001102e2000210120000d000b0b0bc78c0106027f027e077f027e197f037e230022032104200341e0076b41607122032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e0a00010203040506070809000b2003418c056a4101360200200342013702fc042003419cc3cb003602f804200341043602e40620034194c3cb003602e0062003200341e0066a36028805200341f8046a41e0ecc0001044000b200141186a2903002105200141106a29030021062001410c6a2802002107200141086a280200210820012802042101200341f8046a41286a200241286a280200360200200341f8046a41206a200241206a290200370300200341f8046a41186a200241186a290200370300200341f8046a41106a200241106a290200370300200341f8046a41086a200241086a290200370300200320022902003703f804200341e0066a200341f8046a10c10241022102200341d0066a41026a220920032d00e3063a0000200341a0036a41086a220a200341f4066a290200370300200341a0036a410d6a220b200341f9066a290000370000200320032f00e1063b01d0062003200341e0066a410c6a2902003703a00302400240024020032d00e0064101460d00200341e0066a41086a280200210220032802e406210c200341f4026a41026a20092d000022093a0000200341c0046a41086a220d200a290300370300200341c0046a410d6a220a200b290000370000200320032f01d006220b3b01f402200320032903a0033703c004200320093a00a2062003200b3b01a006200320023600a7062003200c3600a306200341b3066a200d290300370000200341a0066a41186a200a290000370000200320032903c0043700ab06024002400240200741818001490d00200341a0046a410310c2020c010b0240200642ffcfdbc3f4025620054200522005501b0d00200341a0046a410610c2020c010b200341a0046a41186a220b4200370300200341b0046a22024200370300200341a0046a41086a22094200370300200342003703a004200341e0066a41bad7c70041081081022009200341e0066a41086a220a290000370300200320032900e0063703a004200341e0066a4198d9c000410b108102200b200a290000370300200220032900e006370300200341106a200341a0046a4120108e0220032007ad42004280c2d72f420010e8082003280214210c2003280210210d200341f8046a200341a0066a2003290300220e4280c8afa0257c220f200341086a290300200f200e54ad7c220e10c302024020032d00f8044106470d00200b42003703002002420037030020094200370300200342003703a004200341e0066a41bad7c70041081081022009200a290000370300200320032900e0063703a004200341e0066a4198d9c000410b108102200241086a200a290000370000200220032900e0063700002003200c4100200d1b220241016a3602f804200341a0046a4120200341f8046a410410b20120034182066a20032d00a2063a000020034183066a20032900a306370000200341f8046a41186a4200370300200341f8046a41206a4200370300200341a0056a42003703002003418b066a200341ab066a220929000037000020034193066a200941086a29000037000020034198066a2009410d6a2900003700002003200537038005200320063703f804200320032f01a0063b0180062003420037038805200341b0056a200e3703002003200f3703a805200341003a00b805200341a0046a200210f90120032802a804210a20032802a0042109200341003602e806200342013703e006200341f8046a200341e0066a1080022009200a20032802e006220b20032802e80610b201024020032802e406450d00200b102e0b024020032802a404450d002009102e0b200320073602a804200320083602a404200320013602a004200341e0066a200210c40220032802e006220720032802e806200341a0046a10c502024020032802e406450d002007102e0b02402008450d002001102e0b200341ec066a2002360200200341e8066a41003a0000200341153a00e006200341e0066a10fe0141062102200341063a00a0040c020b200341a0046a410110c2020b02402008450d002001102e0b20032902a404210520032d00a00421020b200341f8026a41026a220120032d00a3043a0000200320032f00a1043b01f802200241ff01714106460d02200341e0036a41026a20012d00003a0000200320032f01f8023b01e0030c010b02402008450d002001102e0b0b20034190036a41026a200341e0036a41026a2d000022013a0000200320032f01e00322083b019003200041206a20023a0000200041186a41003a000020004200370308200020083b0021200041236a20013a00002000200537002420004201370300200424000f0b200041186a41003a00002000420037030820002003280080043600192000411c6a20034183046a28000036000020004200370300200424000f0b20012802042101200341f8046a41286a200241286a280200360200200341f8046a41206a200241206a290200370300200341f8046a41186a200241186a290200370300200341f8046a41106a200241106a290200370300200341f8046a41086a200241086a290200370300200320022902003703f8044102210202400240200341f8046a10c60241ff01714102460d00200341c0046a200110f901200341f8046a20032802c004220820032802c804220710fa01024002400240024020032d00b80541064622020d0002404100200341f8046a20021b22022d0040450d0020034180046a410410c2020c020b200241013a0040200241c1006a200341e0066a41c70010e9081a200341b8046a22094200370300200341b0046a220a4200370300200341a0046a41086a220b4200370300200342003703a004200341e0066a41bad7c7004108108102200b200341e0066a41086a2202290000370300200320032900e0063703a004200341e0066a41c0dac000410f10810220092002290000370300200a20032900e0063703004104102c2209450d0d200342043702a406200320093602a006200320013602e006200341a0066a200341e0066a41041074200220032802a806360200200320032903a0063703e006200341a0046a4120200341e0066a10c702200341063a0080040c020b20034180046a410210c2020b4100210120032d00800422024106470d010b410621020240024020032d00b8054106470d002008200710ff010c010b200341003602e806200342013703e006200341f8046a200341e0066a1080022008200720032802e006220220032802e80610b201024020032802e406450d002002102e0b410621020b410121010b024020032802c404450d002008102e0b200341f8026a41026a220820032d0083043a0000200320032f0081043b01f80220010d012003290284042105200341c0036a41026a20082d00003a0000200320032f01f8023b01c00320024106460d010b200341a0036a41026a200341c0036a41026a2d000022013a0000200320032f01c00322083b01a003200041206a20023a0000200041186a41003a000020004200370308200020083b0021200041236a20013a00002000200537002420004201370300200424000f0b20004200370308200020032800e003360019200041186a41003a00002000411c6a200341e3036a28000036000020004200370300200424000f0b200141386a2903002105200141306a29030021062001280204211020034190036a41026a22072001410b6a2d00003a0000200341e0066a41086a22092001411c6a290200370300200341e0066a41106a220a200141246a290200370300200320012f00093b0190032003200141146a2902003703e006200141086a2d000021082001410c6a280200210d200141106a2802002101200341f8046a41286a200241286a280200360200200341f8046a41206a200241206a290200370300200341f8046a41186a200241186a290200370300200341f8046a41106a220b200241106a290200370300200341f8046a41086a220c200241086a290200370300200320022902003703f8040240024002400240200341f8046a10c60241ff01714102460d00200341c0046a41026a20072d00003a0000200c2009290300370300200b200a290300370300200320032f0190033b01c004200320032903e0063703f8040240024020080e03030100010b2001450d00200d102e0b200341c0036a41086a200341a0066a41086a290300370300200320032f01a0043b01fc02410121020c020b20084102470d1f2001450d1f200d102e410221020c200b200341a0066a410d6a2202200341f8046a410d6a290000370000200341a0066a41086a2208200341f8046a41086a290300370300200341fc026a41026a2207200341c0046a41026a2d00003a0000200341c0036a41086a22092008290300370300200341c0036a410d6a22082002290000370000200320032f01c0043b01fc02200320032903f8043703c003200341d0066a41026a220220072d00003a0000200320032f01fc023b01d006200341a0036a410d6a22072008290000370000200341a0036a41086a220a2009290300370300200320032903c0033703a003200341c0046a201010f901200341f8046a20032802c004220820032802c804220910fa01200341b3046a200a290300370000200341b8046a2007290000370000200320022d00003a00a204200320032f01d0063b01a004200320013600a7042003200d3600a304200320032903a0033700ab04024002400240024020032d00b80541064622020d0002404100200341f8046a20021b22022d00404103490d0020034180046a410410c2020c020b02402002290300200656200241086a290300220f200556200f2005511b0d0020034180046a410710c2020c020b200241033a0040200241c1006a20032903a004370000200341a0046a41186a290300210f200241186a2005370300200341b0046a290300210520022006370310200241c9006a200341a0046a41086a290300370000200241d1006a2005370000200241d9006a200f370000200341063a0080040c020b20034180046a410210c2020b4100210120032d00800422024106470d010b410621020240024020032d00b8054106470d002008200910ff010c010b200341003602a806200342013703a006200341f8046a200341a0066a1080022008200920032802a006220220032802a80610b201024020032802a406450d002002102e0b410621020b410121010b024020032802c404450d002008102e0b200341f8026a41026a220820032d0083043a0000200320032f0081043b01f80220010d01200329028404210520034180036a41026a20082d00003a0000200320032f01f8023b0180030b20024106470d1e0b20004200370308200020032800e003360019200041186a41003a00002000411c6a200341e3036a28000036000020004200370300200424000f0b20012802042111200241276a2d00002112200241256a2f00002113200241246a2d00002114200241226a2f01002115200241206a2f0100210b2002411c6a280200210c200241186a280200210d200241146a2802002110200241106a28020021162002410c6a2802002109200241086a280200210a200241066a2f00002117200241056a2d00002118200241046a2d0000210841022107200241026a2f010021192002280228210120022d0001211a0240024002400240024020022d0000221b0e03000102000b4100211c4102211d2008210702400240201a0e03000105000b4100211d200821074100211c0c040b4101211d200821070c030b4102210702400240024020080e03000102000b410021070c010b410121070b200341a0066a41026a200341f8046a41026a2d00003a0000200320032f00f8043b01a0064101211c0c010b02400240024020080e03000102000b410021070c010b410121070b4102211c200341a0066a41026a200341f8046a41026a2d00003a0000200320032f00f8043b01a0060b0b200128020041016a221e41014d0d06201320124110747221022003419c056a221220143a00002003419a056a221320153b010020034198056a221f200b3b010020034194056a2220200c36020020034190056a2221200d360200200341f8046a41146a22222010360200200341f8046a41106a22232016360200200341f8046a410c6a22242009360200200341f8046a41086a2225200a3602002001201e3602002003419d056a221e20032f01a0063b00002003419f056a2226200341a0066a41026a2d00003a0000200320173b01fe04200320183a00fd04200320073a00fc04200320193b01fa042003201d3a00f9042003201c3a00f804200320013602a005200341e0066a200341f8046a10c102024020032d00e0064101470d00202620024110763a0000201e20023b0000201220143a0000201320153b0100201f200b3b01002020200c3602002021200d3602002022201036020020232016360200202420093602002025200a360200200320013602a005200320173b01fe04200320183a00fd04200320083a00fc04200320193b01fa042003201a3a00f9042003201b3a00f804024002400240201b0e020001020b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b2003200b3b01be062003200c3601ba062003200d3601b606200320103601b206200320163601ae06200320093601aa062003200a3601a606200320173b01a406200320183a00a306200320083a00a206200320193b01a0060240201a450d004110102c2202450d09200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d0920014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220836020020080d022002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22082008280200417f6a220836020020080d022002102e0c020b4101210b410021084100210a0c1d0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b024020080d004101210b200a41017420094d0d00410021084100210a0c1d0b4110102c2202450d07200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d0720014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220836020020080d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22082008280200417f6a220836020020080d002002102e0b20012001280200417f6a22023602004100210b4101210820020d1a2001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d1a2001102e4100210a0c1b0b200341d0066a41026a220720032d00e3063a0000200341a0036a41086a2227200341e0066a41146a290200370300200341a0036a410d6a2228200341f9066a290000370000200320032f00e1063b01d0062003200341e0066a410c6a2902003703a003200341e0066a41086a280200211d20032802e406211c202620024110763a0000201e20023b0000201220143a0000201320153b0100201f200b3b01002020200c3602002021200d3602002022201036020020232016360200202420093602002025200a360200200320013602a005200320173b01fe04200320183a00fd04200320083a00fc04200320193b01fa042003201a3a00f9042003201b3a00f804200341f4026a41026a20072d00003a0000200341c0046a41086a2027290300370300200341c0046a410d6a202829000037000020012001280200417f6a2202360200200320032f01d0063b01f402200320032903a0033703c0044101210a41002108024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b20032802a005220141046a22022002280200417f6a220236020020020d002001102e0b4100210b0c1a0b20012802042101200341f8046a41286a200241286a280200360200200341f8046a41206a200241206a290200370300200341f8046a41186a200241186a290200370300200341f8046a41106a200241106a290200370300200341f8046a41086a200241086a290200370300200320022902003703f804200341e0066a200341f8046a10c102200341a0046a41086a2202200341e9066a290000370300200341a0046a41106a2208200341f1066a290000370300200341a0046a41186a2207200341f9066a290000370300200320032900e1063703a00420032d00e0064101460d07200341c0046a41186a2007290300370300200341c0046a41106a2008290300370300200341c0046a41086a2002290300370300200320032903a0043703c004200341a0046a200110f901200341f8046a20032802a004220820032802a804220710fa0120032d00b80541064622020d0602404100200341f8046a20021b22022d00404103460d00200341a0066a410410c2020c140b0240200341c0046a200241c1006a2201412010ec08450d00200341a0066a410510c2020c140b200341e8016a20022903102205200241186a290300220642c0843d420010e608200341d8016a2005200642c0843d420010e708200341c8016a20032903d801200341d8016a41086a29030042a0c21e420010e808200341e0066a200120032903c801220620032903e8012205420188a7200542a0c21e7e42c0843d8242a0c21e566aad7c2205200341c8016a41086a2903002005200654ad7c220610c302200341fa026a220920032d00e3063a0000200320032f00e1063b01f802024020032d00e006220a4106470d0020022005370320200241286a2006370300200341a0066a41186a22094200370300200341a0066a41106a220a4200370300200341a0066a41086a220b4200370300200342003703a006200341d0066a41d9fcc6004106108102200b200341d0066a41086a220c290000370300200320032900d0063703a006200341d0066a4180f4cb0041061081022009200c290000370300200a20032900d006370300200341c0016a200341a0066a4120108e0220032802c001210920032802c401210a200241043a0040200141086a2900002105200141106a29000021062001290000210f200241d9006a200141186a290000370000200241d1006a2006370000200241c9006a2005370000200241c1006a200f370000200241e4006a200a41808dcf006a41808dcf0020091b360200200341063a00a0060c150b20032902e40621052003200a3a00a006200320032f01f8023b00a106200320053702a406200320092d00003a00a3060c130b20012802042117200341ec026a41026a22072001410b6a2d00003a000020034180046a41086a22092001411c6a29020037030020034180046a41106a220a200141246a290200370300200320012f00093b01ec022003200141146a29020037038004200141086a2d000021082001410c6a280200210b200141106a2802002101200341f8046a41286a200241286a280200360200200341f8046a41206a200241206a290200370300200341f8046a41186a200241186a290200370300200341f8046a41106a220c200241106a290200370300200341f8046a41086a220d200241086a290200370300200320022902003703f804200341e0066a200341f8046a10c102200341f4026a41026a220220032d00e3063a0000200341c0046a41086a2210200341e0066a41146a290200370300200341c0046a410d6a2216200341f9066a290000370000200320032f00e1063b01f4022003200341e0066a410c6a2902003703c00402400240024020032d00e0064101460d00200341e0066a41086a280200211820032802e406211920034180036a41026a20022d00003a0000200341e0036a41086a2010290300370300200341e0036a410d6a2016290000370000200320032f01f4023b018003200320032903c0043703e003200341a0066a41026a20072d00003a0000200320032f01ec023b01a006200d2009290300370300200c200a29030037030020032003290380043703f8040240024020080e03030100010b2001450d00200b102e0b200341a0036a41086a200341e0066a41086a290300370300200320032f01a0043b01d006410121020c020b20084102470d122001450d12200b102e410221020c130b200341e0066a410d6a2202200341f8046a410d6a290000370000200341e0066a41086a2208200341f8046a41086a290300370300200341d0066a41026a2207200341a0066a41026a2d00003a0000200341a0036a41086a22092008290300370300200341a0036a410d6a22082002290000370000200320032f01a0063b01d006200320032903f8043703a003200320072d00003a00c204200320032f01d0063b01c004200320013600c7042003200b3600c304200341d8046a2008290000370000200341d3046a2009290300370000200320032903a0033700cb04200341a0036a201710f901200341f8046a20032802a003220820032802a803220710fa01200341e0066a410b6a2018360000200341ef066a20032903e003370000200341f7066a200341e0036a41086a290300370000200341fc066a200341e0036a410d6a290000370000200320032f0180033b01e406200320034180036a41026a2d00003a00e606200320193600e70620032d00b80521022003200341c0046a3602e0060240024002400240200241064622020d0002404100200341f8046a20021b22022d00404104460d00200341a0066a410410c2020c020b0240200341e0066a4104722209200241c1006a220a412010ec08450d00200341a0066a410510c2020c020b200341fe026a220d20032d00c2043a0000200341a0046a41086a2210200941086a290200370300200341a0046a41106a2216200941106a290200370300200341a0046a41186a2218200941186a290200370300200341c0036a41086a2219200341c0046a410b6a220c41086a290000370300200341c0036a410d6a2214200c410d6a290000370000200320032f01c0043b01fc02200320092902003703a0042003200c2900003703c003200341a0066a41186a22094200370300200341a0066a41106a220c4200370300200341a0066a41086a22154200370300200342003703a006200341d0066a41d9fcc60041061081022015200341d0066a41086a221a290000370300200320032900d0063703a006200341d0066a4180f4cb0041061081022009201a290000370300200c20032900d006370300200341f8016a200341a0066a4120108e0220032802f801210920032802fc01210c200241053a0040200a41186a2018290300370000200a41106a2016290300370000200a41086a2010290300370000200a20032903a004370000200241e1006a20032f01fc023b0000200241e3006a200d2d00003a0000200241e8006a2001360000200241e4006a200b36000020024184016a200c418084076a4180840720091b360200200241ec006a20032903c003370000200241f4006a2019290300370000200241f9006a2014290000370000200341063a00a0060c020b200341a0066a410210c2020b4100210120032d00a00622024106470d010b410621020240024020032d00b8054106470d002008200710ff010c010b200341003602e806200342013703e006200341f8046a200341e0066a1080022008200720032802e006220220032802e80610b201024020032802e406450d002002102e0b410621020b410121010b024020032802a403450d002008102e0b200341f8026a41026a220820032d00a3063a0000200320032f00a1063b01f80202402001450d00200341f8046a41086a41033a000020034181056a20032903c004370000200341a4056a201736020020034189056a200341c0046a41086a29030037000020034191056a200341d0046a29030037000020034199056a200341d8046a290300370000200341153a00f804200341f8046a10fe010c110b20032902a4062105200341e8026a41026a20082d00003a0000200320032f01f8023b01e8020b20024106460d0f0c110b20012802042108200341f8046a41286a2207200241286a280200360200200341f8046a41206a200241206a290200370300200341f8046a41186a2209200241186a290200370300200341f8046a41106a200241106a290200370300200341f8046a41086a200241086a290200370300200320022902003703f804200341e0066a200341f8046a10c102410121014102210220032d00e0064101460d0d20034190036a200810f901200341f8046a200328029003220a200328029803220b10fa01200341d0056a22022903002105200220032903f806370300200341c8056a22022903002106200220032903f006370300200341c0056a2202290300210f200220032903e806370300200320053703b806200320063703b0062003200f3703a806200320032903b80522053703a0062003200341f0056a2903003703d8042003200341e8056a2903003703d0042003200341e0056a2903003703c8042003200341d8056a290300220e3703c004200341063a00e006200320032903e00622063703b805200341f8056a290300210f024002402005a7220241ff01714106470d000c010b2009290300210520072903002129200329038805212a200329039805212b200341e0066a41176a20032900b806370000200341e0066a41106a20032900b106370300200341e0066a41086a20032900a906370300200341a0046a41086a20032900c904370300200341a0046a41106a20032900d104370300200341a0046a41176a20032900d804370000200320032900a1063703e006200320032900c1043703a004200ea72118200fa72119410021010b2006a7210720034180046a41086a2209200341e0066a41086a29030037030020034180046a41106a220c200341e0066a41106a29030037030020034180046a41176a220d200341e0066a41176a290000370000200341e0036a41086a2210200341a0046a41086a290300370300200341e0036a41106a2216200341a0046a41106a290300370300200341e0036a41176a2217200341a0046a41176a290000370000200320032903e00637038004200320032903a0043703e00320010d06200341c0036a41176a200d290000370000200341c0036a41106a200c290300370300200341c0036a41086a2009290300370300200341a0036a41086a2010290300370300200341a0036a41106a2016290300370300200341a0036a41176a201729000037000020032003290380043703c003200320032903e0033703a0030240200241ff01714105460d0020034180036a410410c2020c0d0b200341a0046a41176a200341c0036a41176a290000370000200341a0046a41106a200341c0036a41106a290300370300200341a0046a41086a200341c0036a41086a290300370300200320032903c0033703a004200320183a00bf04200341c0046a41176a200341a0036a41176a290000370000200341c0046a41106a200341a0036a41106a290300370300200341c0046a41086a200341a0036a41086a290300370300200320032903a0033703c004200320193a00df04200341b8066a22024200370300200341a0066a41106a22014200370300200341a0066a41086a22094200370300200342003703a006200341d0066a41d9fcc60041061081022009200341d0066a41086a220c290000370300200320032900d0063703a006200341d0066a4180f4cb0041061081022002200c290000370300200120032900d00637030020034190026a200341a0066a4120108e02024020032802940241002003280290021b200f422088a74f0d0020034180036a410910c2020c0d0b200342f0f2bda1a7ee9cb9f90037038004200320083602e806200341023602e406200341e2b8c0003602e006200341a0066a20034180046a200341e0066a10fc0120034180046a200341a0066a10c802200341e0066a200328028004220120032802880410c902200341e0066a41106a290300420020032903e00642015122021b210620032903e806420020021b210f0240200328028404450d002001102e0b20034180026a200341a0046a202b202910fb01200341e0036a200341a0066a200341a0046a200f202a202a200f56200520065620052006511b22021b220e2006200520021b2205410110ca0220034180046a200341a0066a200341c0046a4200200f200e7d222a202a200f56200620057d200f200e54ad7d220520065620052006511b22021b22064200200520021b2205410110ca0241062107200341063a00b805200341e0066a200810c40220032802e006220220032802e80610ff01024020032802e406450d002002102e0b20034198076a200537030020034190076a2006370300200341e0066a41086a41043a0000200341e9066a20032903c0043700002003418c076a2008360200200341f1066a200341c0046a41086a290300370000200341f9066a200341d0046a29030037000020034181076a200341d8046a290300370000200341153a00e006200341e0066a10fe01200341063a0080030c0c0b200128020421072002410e6a2f0100210a2002410d6a2d0000210b2002410c6a2d0000210c2002410a6a2f0100210d200241096a2d00002110200241086a2d00002116200241046a2d0000210920022802282101024020022d000022080d002002411a6a2901002105200241196a2d00002108200241186a2d00002117200241166a2f01002118200241156a2d00002119200241146a2d00002114200241126a2f01002115200241116a2d0000211a200241106a2d0000211b200241066a2f0100211d200241056a2d0000211c200241026a2f0100211220022d0001210220012001280200417f6a2213360200024020130d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22132013280200417f6a221336020020130d002001102e0b200320053703b806200320083a00b706200320173a00b606200320183b01b406200320193a00b306200320143a00b206200320153b01b0062003201a3a00af062003201b3a00ae062003200a3b01ac062003200b3a00ab062003200c3a00aa062003200d3b01a806200320103a00a706200320163a00a6062003201d3b01a4062003201c3a00a306200320093a00a206200320123b01a0060240200241ff01710d00410321080c010b4110102c2202450d02200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d0220014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a22173602004100210820170d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22172017280200417f6a221736020020170d002002102e0b0240024002402008417f6a0e03000102010b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200941ff01710d00200d411074201041087472201672410174200a411074200b41087472200c724b0d020b4110102c2202450d03200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d0320014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220836020020080d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22082008280200417f6a220836020020080d002002102e0b20012001280200417f6a22083602004102210220080d0b2001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22082008280200417f6a220836020020080d0b2001102e0c0b0b200341a0046a200710f901200341f8046a20032802a004220120032802a804220810fa01024002400240024002400240024020032d00b80541064622020d004100200341f8046a20021b22022d00400e06020305050401020b200341e0066a410210c202200320032900e106370380042003200341e8066a2800003600870420032d00e006210220032802a404450d102001102e0c100b200341e0066a410810c202200320032900e106370380042003200341e0066a41086a2800003600870420032d00e006210220032802a404450d0f2001102e0c0f0b200341e0066a200710c40220032802e006220920032802e80610ff01024020032802e406450d002009102e0b200341a8026a20024188016a2002290330222a200241386a290300222b10cb0220032903a80221052003200341a8026a41086a29030022063703e806200320053703e0060240024020052006844200520d002003200341e0066a3602a006200341a0066a10cc020c010b200342f0f2bda1a7ee9cb9f9003703a006200341e0066a200341a0066a10cd0220034198026a200341e0066a2005200610fd01200341b0066a20034198026a41086a290300220e20067d200329039802220f200554ad7d2006200e7d2005200f54ad7d200f200556200e200656200e2006511b22021b3703002003200f20057d2005200f7d20021b3703a80620032002ad3703a006200341a0066a41086a21090240024020020d00200320093602c004200341c0046a10cc020c010b200320093602c004200341c0046a10ce020b200341f8066a2006370300200341f0066a2005370300200341e8066a41063a00002003410e3a00e006200341e0066a10fe010b200341063a00b805200341f8066a202b370300200341f0066a202a370300200341ec066a2007360200200341e8066a41013a0000200341153a00e006200341e0066a10fe0142f0f98fc30121050c030b200341e0066a410410c202200320032900e106370380042003200341e8066a2800003600870420032d00e006210220032802a404450d0d2001102e0c0d0b200341c8026a200241c1006a2002290320200241286a29030010fb010b200342f0f2bda1a7ee9cb9f9003703c004200320073602e806200341023602e406200341e2b8c0003602e006200341a0066a200341c0046a200341e0066a10fc01200341e0066a200710c40220032802e006220220032802e80610ff01024020032802e406450d002002102e0b200341c0046a200341a0066a10c802200341e0066a20032802c004220920032802c80410c902200341f0066a290300420020032903e00642015122021b210520032903e806420020021b2106024020032802c404450d002009102e0b200342f0f2bda1a7ee9cb9f9003703c004200341e0066a200341c0046a10cd02200341c0046a200341a0066a200341e0066a20062005410110ca02200341063a00b805200341ec066a2007360200200341e8066a41053a0000200341153a00e006200341e0066a10fe01428887a88c0221050b0240024020032d00b8054106470d002001200810ff010c010b200341003602e806200342013703e006200341f8046a200341e0066a1080022001200820032802e006220220032802e80610b20120032802e406450d002002102e0b024020032802a404450d002001102e0b200320032800c0033602a0032003200341c3036a2800003600a303200041186a41003a0000200041106a200537030020004201370308200020032802a0033600192000411c6a20032800a30336000020004200370300200424000f0b200128020421072001410c6a2802002108200141086a2802002101200341f8046a41286a200241286a280200360200200341f8046a41206a200241206a290200370300200341f8046a41186a200241186a290200370300200341f8046a41106a200241106a290200370300200341f8046a41086a200241086a290200370300200320022902003703f804200341e0066a200341f8046a10c102200341a0046a41086a2202200341e9066a290000370300200341a0046a41106a2209200341f1066a290000370300200341a0046a41186a220a200341f9066a290000370300200320032900e1063703a00420032d00e0064101460d05200341c0046a41186a200a290300370300200341c0046a41106a2009290300370300200341c0046a41086a2002290300370300200320032903a0043703c004200341a0046a200710f901200341f8046a20032802a004220a20032802a804220b10fa01024002400240024020032d00b80541064622020d0002404100200341f8046a20021b22022d00404104460d00200341a0066a410410c2020c020b0240200241c1006a200341c0046a412010ec08450d00200341a0066a410510c2020c020b200341b8066a22094200370300200341b0066a220c4200370300200341a0066a41086a220d4200370300200342003703a006200341d0066a41d9fcc6004106108102200d200341d0066a41086a2210290000370300200320032900d0063703a006200341d0066a4180f4cb00410610810220092010290000370300200c20032900d006370300200341d8026a200341a0066a4120108e02200220032802dc0241808dcf006a41808dcf0020032802d8021b22092002280264220c2009200c4b1b360264200341063a00a0060c020b200341a0066a410210c2020b4100210920032d00a00622024106470d010b410621020240024020032d00b8054106470d00200a200b10ff010c010b200341003602e806200342013703e006200341f8046a200341e0066a108002200a200b20032802e006220220032802e80610b201024020032802e406450d002002102e0b410621020b410121090b024020032802a404450d00200a102e0b200341f8026a41026a220a20032d00a3063a0000200320032f00a1063b01f80202402009450d0020034184056a200736020020034180056a41063a0000200341153a00f804200341f8046a10fe012008450d082001102e0c080b20032902a406210520034180046a41026a200a2d00003a0000200320032f01f8023b0180040c060b1036000b00000b200341a0066a410210c2020c0c0b410221020c0e0b20034180036a410210c2020c050b410221020b02402008450d002001102e0b20024106460d00200341f8046a41026a20034180046a41026a2d000022013a0000200320032f01800422083b01f804200041206a20023a0000200041186a41003a000020004200370308200020083b0021200041236a20013a000020002005370024420121050c010b4200210520004200370308200020032800f804360019200041186a41003a00002000411c6a200341fb046a2800003600000b20002005370300200424000f0b200320032800c0033602a00320032003290380043703e00320032003280087043600e7032003200341c3036a2800003600a303200041186a41003a000020004200370308200020032802a0033600192000411c6a20032800a303360000200041206a20023a0000200020032903e003370021200041286a20032800e70336000020004201370300200424000f0b024020032d00800322024106470d0002400240200741ff01714106470d00200a200b10ff010c010b200341003602e806200342013703e006200341f8046a200341e0066a108002200a200b20032802e006220220032802e80610b20120032802e406450d002002102e0b0240200328029403450d00200a102e0b200041186a41003a000020004200370308200020032800ec023600192000411c6a200341ef026a28000036000020004200370300200424000f0b0240200328029403450d00200a102e0b200341fe026a20032d0083033a0000200320032f00810322013b01f802200320013b01fc0220032902840321050b200341f4026a41026a200341fc026a41026a2d000022013a0000200320032f01fc0222083b01f402200041206a20023a0000200041186a41003a000020004200370308200020083b0021200041236a20013a00002000200537002420004201370300200424000f0b200042003703082000200328009003360019200041186a41003a00002000411c6a20034193036a28000036000020004200370300200424000f0b410221020b200341e4026a41026a200341e8026a41026a2d000022013a0000200320032f01e80222083b01e402200041206a20023a0000200041186a41003a000020004200370308200020083b0021200041236a20013a00002000200537002420004201370300200424000f0b4100210120032d00a00622024106470d010b410621020240024020032d00b8054106470d002008200710ff010c010b200341003602e806200342013703e006200341f8046a200341e0066a1080022008200720032802e006220220032802e80610b201024020032802e406450d002002102e0b410621020b410121010b024020032802a404450d002008102e0b200341e0036a41026a220820032d00a3063a0000200320032f00a1063b01e00320010d0120032902a4062105200341c0036a41026a20082d00003a0000200320032f01e0033b01c00320024106460d010b200341a0036a41026a200341c0036a41026a2d000022013a0000200320032f01c00322083b01a003200041206a20023a0000200041186a41003a000020004200370308200020083b0021200041236a20013a00002000200537002420004201370300200424000f0b200042003703082000200328008004360019200041186a41003a00002000411c6a20034183046a28000036000020004200370300200424000f0b4100210a0b4102210220034180036a41026a2201200341f4026a41026a2d00003a0000200341e0036a41086a2207200341c0046a41086a290300370300200341e0036a410d6a2209200341c0046a410d6a290000370000200320032f01f4023b018003200320032903c0043703e003024002400240024002400240024020080d00200341ec026a41026a220220012d00003a000020034180046a41086a2201200729030037030020034180046a410d6a22072009290000370000200320032f0180033b01ec02200320032903e00337038004200341e0036a201110f901200341f8046a20032802e003220820032802e803220910fa01200341fc026a41026a20022d00003a0000200341c0036a41086a2001290300370300200341c0036a410d6a2007290000370000200320032f01ec023b01fc0220032003290380043703c0030240024020032d00b80541064622020d00024002400240024002404100200341f8046a20021b22022d00400e06000000010203000b200341a0066a410410c2020c050b200341b3046a200341c0036a41086a290300370000200341a0046a41186a2201200341cd036a290000370000200320032f01fc023b01a0042003201d3600a7042003201c3600a304200320032903c0033700ab042003200341fe026a2d00003a00a204200a450d07200341e0066a41186a2001290300370300200341e0066a41106a200341a0046a41106a290300370300200341e0066a41086a200341a0046a41086a290300370300200320032903a0043703e006200341e0066a200241c1006a412010ec08450d070c020b200241c1006a2101024002400240200a450d00200341d3046a200341c0036a41086a290300370000200341c0046a41186a200341cd036a290000370000200320032f01fc023b01c0042003201d3600c7042003201c3600c304200320032903c0033700cb042003200341fe026a2d00003a00c204200341c0046a2001412010ec08450d01200341a0066a41186a22074200370300200341b0066a220a4200370300200341a0066a41086a220b4200370300200342003703a006200341d0066a41d9fcc6004106108102200b200341d0066a41086a220c290000370300200320032900d0063703a006200341d0066a4180f4cb0041061081022007200c290000370300200a20032900d006370300200341d8006a200341a0066a4120108e0202402003280258450d002002280264200328025c490d030b200341a0066a410910c2020c060b200341f0006a20012002290320200241286a29030010cb02200329037021052003200341f0006a41086a29030022063703e806200320053703e0060240024020052006844200520d002003200341e0066a3602a006200341a0066a10cc020c010b200342f0f2bda1a7ee9cb9f9003703a006200341e0066a200341a0066a10cd02200341e0006a200341e0066a2005200610fd01200341b0066a200341e0006a41086a290300220e20067d2003290360220f200554ad7d2006200e7d2005200f54ad7d200f200556200e200656200e2006511b22011b3703002003200f20057d2005200f7d20011b3703a80620032001ad3703a006200341a0066a41086a21070240024020010d00200320073602c004200341c0046a10cc020c010b200320073602c004200341c0046a10ce020b200341f8066a2006370300200341f0066a2005370300200341e8066a41063a00002003410e3a00e006200341e0066a10fe010b20024200370320200241286a42003703000c080b200341186a20012002290320200241286a29030010fb010c070b200341386a20012002290320200241286a29030010cb02200329033821052003200341386a41086a29030022063703e806200320053703e0060240024020052006844200520d002003200341e0066a3602a006200341a0066a10cc020c010b200342f0f2bda1a7ee9cb9f9003703a006200341e0066a200341a0066a10cd02200341286a200341e0066a2005200610fd01200341b0066a200341286a41086a290300220e20067d2003290328220f200554ad7d2006200e7d2005200f54ad7d200f200556200e200656200e2006511b22011b3703002003200f20057d2005200f7d20011b3703a80620032001ad3703a006200341a0066a41086a21070240024020010d00200320073602a004200341a0046a10cc020c010b200320073602a004200341a0046a10ce020b200341f8066a2006370300200341f0066a2005370300200341e8066a41063a00002003410e3a00e006200341e0066a10fe010b20024200370320200241286a42003703000c060b200b0d040b41022102200341023a00a006410021010c060b200341a0066a410210c2020b4100210120032d00a00622024106470d040c030b0c040b200341a0016a200241c1006a2002290320200241286a29030010cb0220032903a00121052003200341a0016a41086a29030022063703e806200320053703e0060240024020052006844200520d002003200341e0066a3602a006200341a0066a10cc020c010b200342f0f2bda1a7ee9cb9f9003703a006200341e0066a200341a0066a10cd0220034190016a200341e0066a2005200610fd01200341b0066a20034190016a41086a290300220e20067d200329039001220f200554ad7d2006200e7d2005200f54ad7d200f200556200e200656200e2006511b22011b3703002003200f20057d2005200f7d20011b3703a80620032001ad3703a006200341a0066a41086a21070240024020010d00200320073602c004200341c0046a10cc020c010b200320073602c004200341c0046a10ce020b200341f8066a2006370300200341f0066a2005370300200341e8066a41063a00002003410e3a00e006200341e0066a10fe010b20024200370320200241286a42003703000b200241023a0040200241c1006a200341e0066a41c70010e9081a200341063a00a0060b410621020240024020032d00b8054106470d002008200910ff010c010b200341003602e806200342013703e006200341f8046a200341e0066a1080022008200920032802e006220220032802e80610b201024020032802e406450d002002102e0b410621020b410121010b024020032802e403450d002008102e0b200341f8026a41026a220820032d00a3063a0000200320032f00a1063b01f80220010d0120032902a4062105200341e8026a41026a20082d00003a0000200320032f01f8023b01e80220024106460d010b200341e4026a41026a200341e8026a41026a2d000022013a0000200320032f01e80222083b01e402200041206a20023a0000200041186a41003a000020004200370308200020083b0021200041236a20013a00002000200537002420004201370300200424000f0b200042003703082000200328009003360019200041186a41003a00002000411c6a20034193036a28000036000020004200370300200424000f0b410221020b200341ec026a41026a20034180036a41026a2d000022013a0000200320032f01800322083b01ec02200041206a20023a0000200041186a41003a000020004200370308200020083b0021200041236a20013a00002000200537002420004201370300200424000bbe06030d7f017e037f230041306b220224002002200141026a2f01003b012e2002200141066a2f01003b012c20022001410a6a2f01003b012a200141046a2d00002103200141056a2d00002104200141086a2d00002105200141096a2d000021062001410c6a2d000021072001410d6a2d0000210820012d0001210920012d0000210a20022001410e6a2f01003b0128200141116a2d0000210b200141106a2d0000210c2002200141126a2f01003b0126200141156a2d0000210d200141146a2d0000210e2002200141166a2f01003b01242001411a6a290100210f200141196a2d00002110200141186a2d000021112001280228210120022f012e211202400240200a0d0020012001280200417f6a220a360200200220123b0122200220022f012c3b0120200220022f012a3b011e200220022f01283b011c200220022f01263b011a200220022f01243b01182002200f3703080240200a0d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a220a200a280200417f6a220a360200200a0d002001102e0b0240200941ff01714101460d00200041013a00000c020b200020022f01223b0001200041046a20043a0000200041036a20033a0000200041086a20063a0000200041076a20053a0000200041056a20022f01203b00002000410c6a20083a00002000410b6a20073a0000200041096a20022f011e3b0000200041106a200b3a00002000410f6a200c3a00002000410d6a20022f011c3b0000200041146a200d3a0000200041136a200e3a0000200041116a20022f011a3b0000200041186a20103a0000200041176a20113a0000200041003a0000200041156a20022f01183b0000200041196a20022903083700000c010b200220123b0120200220022f012c3b011e200220022f012a3b011c200220022f01283b011a200220022f01263b01182002200f37020c200220103a000b200220113a000a200220022f01243b0108200041013a000020012001280200417f6a220036020020000d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22002000280200417f6a220036020020000d002001102e0b200241306a24000bc60201047f230041c0006b2202240041aab4c700210341092104410821050240024002400240024002400240024002400240200141ff01710e0a00010203040506070809000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a41b0a5cc001044000b41d0ffc3002103411c2104410021050c070b41caeac2002103410c2104410121050c060b419eb4c7002103410c2104410221050c050b4195b9c000210341102104410321050c040b4187b9c0002103410e2104410421050c030b41fbb8c0002103410c2104410521050c020b41f1b8c0002103410a2104410621050c010b41e4b8c0002103410d2104410721050b20004183c4003b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000bce1204027f0c7e037f037e230041e0026b220424002004200337031020042002370308200420013602040240024020022003844200520d00200041063a00000c010b2004200136023c20044180016a200110c802200441e0016a200428028001220520042802880110c902200441e0016a41386a2903002106200441e0016a41306a2903002107200441e0016a41286a2903002108200441e0016a41206a2903002109200441e0016a41186a290300210a200441e0016a41106a290300210b200441a0026a290300210c20042903e801210d20042903e001210e200441b0016a41086a200441b0026a2903003703002004200441a8026a2903003703b00102400240200e4201510d004200210c200441c0006a41386a4200370300200441c0006a41306a4200370300200441c0006a41286a4200370300200441c0006a41206a4200370300200441c0006a41186a4200370300200441c0006a41106a4200370300200441c0006a41086a420037030020044200370340420021094200210842002107420021064200210d4200210b4200210a4200210f420021104200210e420021110c010b200441c0006a41206a2008370300200441c0006a41286a2007370300200441c0006a41106a200a370300200441c0006a41306a2006370300200420093703582004200d3703402004200c3703782004200b3703482008210f20072110200d210e200b21110b0240200428028401450d002005102e0b02400240200e2011844200520d00200f2004290350842010200441d8006a29030084844200520d002004290370200441f8006a2903008450450d004200210e410021050c010b4201210e410121050b0240200e4201510d004200210842002107420021064200210c4200210a420021094200210d4200210b0b0240024002400240024002400240200d20027d2211200d56200b20037d200d200254ad7d220d200b56200d200b511b0d000240200a20027c220f200a542212200920037c2012ad7c220b200954200b2009511b450d00200441d0016a41086a4108360200200441a984ca003602d401200441023a00d201200441830a3b01d0010c020b200441d0016a20012002200341042011200d10d70620042d00d0014106470d0120044188026a22132007370300200441f8016a200b37030020044190026a2214200637030020042008370380022004200f3703f001200420113703e0012004200d3703e8014200210a42012107200e420152ad210802400240427f2011200f7c220920092011542212200d200b7c2012ad7c2209200d542009200d511b22121b220642ffc7afa02556427f200920121b22094200522009501b0d002011200f84200d200b8484220b50211242002107200b420052ad210a0c010b201429030021152013290300211620044180026a2903002117200441f0016a290300210f20042903f801211020042903e801210e20042903e001210b410121120b200441a8016a2009370300200441a0016a2213200637030020044190016a200d37030020042011370388012004200a37039801200420083703800120052007420152720d02200420013602e0012001200441e0016a10bd060c040b200441d8016a4113360200200441c8a3c7003602d401200441033a00d201200441830a3b01d0010b20042902d401210b20042802d00121050c010b0240200541017322052007420151720d00200420013602e0012001200441e0016a10be0641ff017122054103460d02024020050e03040300040b41042105024020120d00200420133602e001200441e0016a10cc020b0c010b2007420152200571450d010c020b200541ff01714106460d02200020053a0000200041036a20054118763a0000200020054108763b0001200041046a200b3702000c030b200441c0016a200110c802200441e0016a20042802c001221220042802c801221310c90220042903e0012102200441b0016a41086a2205200441b0026a2903003703002004200441a8026a2903003703b0010240024020024201510d00200441d0016a41086a4200370300200442003703d0010c010b200441d0016a41086a2005290300370300200420042903b0013703d0010b200441a8026a20042903d001370300200441b0026a200441d0016a41086a290300370300200442013703e00120044198026a20154200200742015122051b37030020044190026a2016420020051b370300200441e0016a41286a2017420020051b37030020044180026a2010420020051b370300200441f8016a200f420020051b370300200441e0016a41106a200e420020051b370300200441a0026a200c420020051b3703002004200b420020051b3703e80120122013200441e0016a41086a10c805024020042802c401450d002012102e0b20044180016a41106a290300210d20044180016a41286a2903002109200429038801211120042903a00121062004290380012108200429039801210a0b024020084201520d0020044198026a200d37030020044190026a2011370300200441e0016a41086a41003a0000200441e9016a2001290000370000200441f1016a200141086a290000370000200441f9016a200141106a29000037000020044181026a200141186a290000370000200441033a00e001200441e0016a10fe010b02400240200a50450d00420021020c010b200441e0016a41086a200428023c220141086a290000370300200441e0016a41106a200141106a290000370300200441e0016a41186a200141186a290000370300200420012900003703e001420121020b200441186a41186a200441e0016a41186a22012903002203370300200441186a41106a200441e0016a41106a2205290300220b370300200441186a41086a200441e0016a41086a290300220d370300200420042903e001220a37031820044190026a200937030020044188026a221220063703002005200d3703002001200b37030020044180026a2003370300200420023703e0012004200a3703e801200441e0016a10d204024020042903e001500d0020042012360240200441c0006a10cc020b200441086a41086a290300210320042903082102200428020421010b20044198026a200337030020044190026a2002370300200441e0016a41086a41053a0000200441e9016a2001290000370000200441f1016a200141086a290000370000200441f9016a200141106a29000037000020044181026a200141186a290000370000200441033a00e001200441e0016a10fe01200041063a00000b200441e0026a24000b870201037f230041d0006b22022400200241086a41bad7c7004108108102200241186a4194dac0004112108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000b970101047f230041106b22032400024002402002280208220441046a2205417f4c0d00200228020021020240024020050d00410121060c010b2005102c2206450d020b20034100360208200320053602042003200636020020042003107620032002200410742000200120032802002205200328020810b20102402003280204450d002005102e0b200341106a24000f0b1038000b1036000b9d0601087f20002802282101024002400240024020002d000022020d0020002d0001210020012001280200417f6a2203360200024020030d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22032003280200417f6a220336020020030d002001102e0b0240200041ff01710d0041000f0b4110102c2200450d03200041f8f7c60036020c2000410136020820004281808080103702004110102c2201450d0320014190f8c60036020c20014101360208200142818080801037020020002000280200417f6a220336020020030d012000280208200028020c2802001103000240200028020c280204450d002000280208102e0b200041046a22032003280200417f6a220336020020030d012000102e0c010b410021030240024002402002417f6a0e03000104010b2000410e6a2f010021022000410d6a2d000021042000410c6a2d000021052000410a6a2f01002106200041096a2d00002107200041086a2d00002108200041046a2d0000210020012001280200417f6a2203360200024020030d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22032003280200417f6a220336020020030d002001102e0b200041ff01710d0141012103200641107420074108747220087241056c200241107420044108747220057241036c490d010c030b4101210320024103460d020c010b4110102c2200450d02200041f8f7c60036020c2000410136020820004281808080103702004110102c2201450d0220014190f8c60036020c20014101360208200142818080801037020020002000280200417f6a220336020020030d002000280208200028020c2802001103000240200028020c280204450d002000280208102e0b200041046a22032003280200417f6a220336020020030d002000102e0b20012001280200417f6a22003602004102210320000d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22002000280200417f6a220036020020000d002001102e0b20030f0b1036000b31002001ad4220862000ad84200235020842208620022802002200ad84101f0240200241046a280200450d002000102e0b0bac0201037f230041e0006b22022400200241d9fcc6004106108102200241106a41dcf1cb004107108102024002404120102c2203450d002002422037023420022003360230200241306a200141201074200241c0006a200228023022012002280238220310d803200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c0006a360250200241206a200241d0006a107c02402002280234450d002001102e0b2002280228220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b20004100360208200020013602042000200436020020002002411010742000200241106a411010742000200228022022012003107402402002280224450d002001102e0b200241e0006a24000f0b1036000b1038000b8c0402067f027e230041d0006b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822010d00200042003703000c010b200328020c2102024002400240200341106a28020022044104490d002004417c7122054104460d0020054108460d002005410c460d00200441707122044110460d00200128000021052001280004210620012800082107200128000c2108200141186a29000021092001290010210a0240200441506a0e110102020202020202020202020202020201000b20044120470d010b20034100360220200342013703182003410a36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341909dc5003602382003200341286a360248200341346a419cebc000200341386a103d1a2003280218200328022010ef020240200328021c450d002003280218102e0b420021090c010b2000200a370308200041386a2001290040370300200041286a2001290030370300200041186a2001290020370300200041106a2009370300200041d4006a2008360200200041d0006a2007360200200041cc006a2006360200200041c8006a2005360200200041c0006a200141c8006a290000370300200041306a200141386a290000370300200041206a200141286a290000370300420121090b200020093703002002450d002001102e0b200341d0006a24000bb63507017f0a7e017f067e047f047e037f230041d0066b2206240020062001360204200620053a001f20062003370308200620043703100240024002402003200484500d0020012002412010ec080d010b200041063a00000c010b200620023602e401200641a8026a200210c802200641d0056a20062802a802220120062802b00210c9020240024020062903d0054201510d0042002107200641e8016a41386a4200370300200641e8016a41306a4200370300200641e8016a41286a420037030020064188026a4200370300200641e8016a41186a4200370300200641e8016a41106a4200370300200641f0016a4200370300200642003703e80142002108420021094200210a4200210b42002104420021034200210c4200210d4200210e4200210f420021100c010b200641d0056a41386a290300210b200641d0056a41306a290300210a200641d0056a41206a2903002108200641d0056a41186a290300210c200641d0056a41106a290300210320064190066a290300210720062903d805210420064188026a200641d0056a41286a2903002209370300200641e8016a41286a200a370300200641e8016a41106a200c370300200641e8016a41306a200b3703002006200837038002200620043703e801200620073703a002200620033703f0012009210d200a210e2004210f200321100b024020062802ac02450d002001102e0b02400240200f2010844200520d00200d20062903f80184200e20064180026a29030084844200520d00200629039802200641a0026a2903008450450d0042002110410021110c010b42012110410121110b0240024020104201510d00200641e8036a4200370300200641e0036a4200370300200641d8036a4200370300200641d0036a4200370300200641c8036a4200370300200641c0036a4200370300200641b8036a4200370300200642003703b0030c010b200641d0036a2009370300200641d8036a200a370300200641e0036a200b370300200641c0036a200c370300200620083703c803200620073703e803200620043703b003200620033703b8030b2006200628020422013602f403200641e8046a200110c802200641d0056a20062802e804220520062802f00410c9020240024020062903d0054201510d004200210d200641f8036a41386a4200370300200641f8036a41306a4200370300200641f8036a41286a4200370300200641f8036a41206a4200370300200641f8036a41186a4200370300200641f8036a41106a420037030020064180046a4200370300200642003703f80342002112420021134200210c4200211442002104420021034200210f42002115420021164200210e420021170c010b200641d0056a41386a2903002114200641d0056a41306a290300210c200641d0056a41206a2903002112200641d0056a41186a290300210f200641d0056a41106a290300210320064190066a290300210d20062903d8052104200641f8036a41206a200641d0056a41286a2903002213370300200641f8036a41286a200c370300200641f8036a41106a200f370300200641f8036a41306a20143703002006201237039004200620043703f8032006200d3703b004200620033703800420132115200c21162004210e200321170b024020062802ec04450d002005102e0b02400240200e2017844200520d00201520062903880484201620064190046a29030084844200520d0020062903a804200641b0046a2903008450450d004200210e410021050c010b4201210e410121050b02400240200e4201510d004200210d20064198056a420037030020064190056a420037030020064188056a420037030020064180056a4200370300200641f8046a4200370300200641f0046a4200370300200642003703e80442002104420021030c010b20064188056a201337030020064190056a200c37030020064198056a2014370300200641f8046a200f3703002006201237038005200620043703e804200620033703f0040b024002400240024020042006290308220f7d220c2004562003200641086a41086a29030022177d2004200f54ad7d220420035620042003511b450d0041838a0c21054280808080b002210341c8a3c7002118410121190c010b2006200c3703e804200620043703f004024020062903b0032203200f7c22132003542218200641b0036a41086a290300221220177c2018ad7c220320125420032012511b450d0041838a08210542808080808001210341a984ca002118410121190c010b200620133703b003200641c8036a2903002112200620033703b8030240427f201320062903c0037c221420142013542218200320127c2018ad7c221220035420122003511b22181b4280c8afa025544100427f201220181b501b450d0041838a1021054280808080a002210341e4a3c7002118410121190c010b200641d0056a2006280204200f20174102200c200410d706024020062d00d0054106460d0041838a0421054280808080d002210341a0a3c7002118410121190c010b0240024020062d001f4101470d00200641a0056a200628020410c802200641d0056a20062802a005221920062802a80510c902200628029c06211820062903d0052103024020062802a405450d002019102e0b20034201520d012018450d010b427f200c20062903f8047c22032003200c542218200420064180056a2903007c2018ad7c220320045420032004511b22181b4280c8afa025544100427f200320181b501b450d0041838a1421054280808080900121034180a4c7002118410121190c010b200641a0056a41206a200641e8046a41306a2903002203370300200641a0056a41186a200641e8046a41286a2903002212370300200641a0056a41106a200641e8046a41206a2903002213370300200641a8056a200641e8046a41186a290300220f370300200620062903f80422173703a0052006200d3703c805200641d0056a41186a200f370300200641d0056a41206a22192013370300200641d0056a41286a221a2012370300200641d0056a41306a221b2003370300200620173703e0052006200c3703d005200620043703d80542012103200e420152ad211402400240427f200c20177c22122012200c5422182004200f7c2018ad7c221320045420132004511b22181b22124280c8afa025544100427f201320181b2213501b450d00200c2017842004200f8484220f50211842002103200f420052ad21170c010b201b290300211c201a290300211d2019290300211e200641d0056a41106a290300211620062903e805211f20062903d805211520062903d005210f42002117410121180b200641e0046a2013370300200641d8046a221a2012370300200641c8046a20043703002006200c3703c004200620173703d004200620143703b8040240024002400240024020052003420152720d00200620013602d0052001200641d0056a10bd060c010b0240200541017322052003420151720d00200620013602d0052001200641d0056a10be0641ff017122054103460d01024020050e03030200030b42002103410121194104210502402018450d000c060b2006201a3602d005200641d0056a10cc020c050b20034201522005710d020b200641e8046a200110c802200641d0056a20062802e804221920062802f004221a10c90220064198066a221b2802002120200641a0066a22212903002104200628029c06212220062903d005210c200642013703d00520064188066a201c4200200342015122051b37030020064180066a201d420020051b370300200641d0056a41286a201e420020051b370300200641f0056a201f420020051b370300200641e8056a2016420020051b370300200641d0056a41106a2015420020051b370300202120044200200c42015122181b3703002006419c066a2022410020181b360200201b2020410020181b36020020064190066a200d420020051b3703002006200f420020051b3703d8052019201a200641d8056a10c805024020062802ec04450d002019102e0b200641b8046a41106a2903002104200641b8046a41286a290300211320062903c004210c20062903d804211220062903b804210f20062903d00421170c040b20062903b80422044280808080708321032004a72118200641e0046a2903002113200641c8046a290300210420062903d804211220062903c004210c4100211920062903d00421170c010b200e420152211842002103410021190b0b20032018ad84210f2019450d00410121010c010b0240200f4201520d0020064188066a200437030020064180066a200c370300200641d0056a41086a41003a0000200641d9056a2001290000370000200641e1056a200141086a290000370000200641e9056a200141106a290000370000200641f1056a200141186a290000370000200641033a00d005200641d0056a10fe010b02400240201750450d004200210f0c010b200641d0056a41086a20062802f403220141086a290000370300200641d0056a41106a200141106a290000370300200641d0056a41186a200141186a290000370300200620012900003703d0054201210f0b200641f8036a41186a200641d0056a41186a2903002204370300200641f8036a41106a200641d0056a41106a2903002203370300200641f8036a41086a200641d0056a41086a290300220c370300200641e8046a41086a200c370300200641e8046a41106a2003370300200641e8046a41186a2004370300200620062903d00522043703f803200620043703e804410021010b200641f8036a41086a2218200641b0036a41186a290300370300200641f8036a41106a2219200641b0036a41206a290300370300200641f8036a41186a221a200641b0036a41286a290300370300200641f8036a41206a221b200641b0036a41306a290300370300200620062903c0033703f803200641b0036a41086a290300210420062903b0032103024002402001450d004200210e41012101200f210c0c010b200641e8036a2903002107200641d0056a41186a2018290300220a370300200641d0056a41206a2019290300370300200641d0056a41286a201a290300370300200641d0056a41306a201b290300370300200620062903f80322083703e005200620033703d005200620043703d8054200210d4201210e2010420152210102400240427f200320087c220c200c20035422182004200a7c2018ad7c220c200454200c2004511b22181b221742ffc7afa02556427f200c20181b22104200522010501b0d004200210e20032008842004200a8484420052ad210d0c010b20064180066a290300210b200641f8056a290300210a200641f0056a2903002109200641e0056a290300211620062903e805210820062903d805211520062903d00521140b2001ad210c200641a0056a41086a200641e8046a41086a290300370300200641a0056a41106a200641e8046a41106a290300370300200641a0056a41186a200641e8046a41186a290300370300200620062903e8043703a005410021010b20064190036a41086a200641a0056a41086a29030037030020064190036a41106a200641a0056a41106a29030037030020064190036a41186a200641a0056a41186a290300370300200620062903a0053703900302400240024002400240024020010d00200641d0026a2010370300200641c8026a22052017370300200641a8026a41106a200437030020064188036a201337030020064180036a22192012370300200641e0026a2201200629039003370300200641e8026a20064198036a290300370300200641f0026a20064190036a41106a290300370300200641f8026a200641a8036a290300370300200620033703b0022006200f3703d8022006200d3703c0022006200c3703a802024002402011200e420152720d00200620023602d0052002200641d0056a10bd060c010b024020114101732218200e420151720d00200620023602d0052002200641d0056a10be0641ff017122184103460d010240024020180e03010300010b0240200d500d00200620053602d005200641d0056a10cc020b200641d8026a10d204410121184104210520062903d802500d05200620193602d005200641d0056a10cc020c050b200641b0036a41286a200141286a290300370300200641b0036a41206a200141206a290300370300200641b0036a41186a200141186a290300370300200641b0036a41106a200141106a290300370300200641b0036a41086a200141086a290300370300200620012903003703b003410021180c040b200e4201522018710d020b200641f8036a200210c802200641d0056a20062802f8032219200628028004221110c90220064198066a221a280200211b200641a0066a22202903002104200628029c06212120062903d0052103200642013703d00520064188066a200b4200200e42015122051b37030020064180066a200a420020051b370300200641d0056a41286a2009420020051b370300200641d0056a41206a2008420020051b370300200641d0056a41186a2016420020051b370300200641d0056a41106a2015420020051b370300202020044200200342015122181b3703002006419c066a2021410020181b360200201a201b410020181b36020020064190066a2007420020051b37030020062014420020051b3703d80520192011200641d0056a41086a10c805024020062802fc03450d002019102e0b200641b0036a41086a2205200141086a290300370300200641b0036a41106a2218200141106a290300370300200641b0036a41186a2219200141186a290300370300200641b0036a41206a2211200141206a290300370300200641b0036a41286a221a200141286a290300370300200620012903003703b003200641a8026a41106a2903002104200641a8026a41286a290300211020062903b002210320062903c802211720062903a802210a20062903c002210d20062903d802210c200641f8036a41286a201a290300370300200641f8036a41206a2011290300370300200641f8036a41186a2019290300370300200641f8036a41106a2018290300370300200641f8036a41086a2005290300370300200620062903b0033703f803200641f8036a21010c030b410121180c010b200641b0036a41286a200141286a290300370300200641b0036a41206a200141206a290300370300200641b0036a41186a200141186a290300370300200641b0036a41106a200141106a290300370300200641b0036a41086a200141086a290300370300200620012903003703b003410021180b200641f8036a41286a200641b0036a41286a290300370300200641f8036a41206a200641b0036a41206a290300370300200641f8036a41186a200641b0036a41186a290300370300200641f8036a41106a200641b0036a41106a290300370300200641f8036a41086a200641b0036a41086a290300370300200620062903b0033703f803200641f8036a210120180d01200c210a200f210c0b200641a8026a41286a200141286a290300370300200641a8026a41206a200141206a290300370300200641a8026a41186a200141186a290300370300200641a8026a41106a200141106a290300370300200641a8026a41086a200141086a290300370300200620012903003703a8020240200a4201520d0020062802e401210120064188066a200437030020064180066a2003370300200641d0056a41086a41003a0000200641d9056a2001290000370000200641e1056a200141086a290000370000200641e9056a200141106a290000370000200641f1056a200141186a290000370000200641033a00d005200641d0056a10fe010b02400240200d50450d00420021040c010b200641e8016a41086a20062802e401220141086a290000370300200641e8016a41106a200141106a290000370300200641e8016a41186a200141186a290000370300200620012900003703e801420121040b200641e8046a41186a200641e8016a41186a290300370300200641e8046a41106a200641e8016a41106a290300370300200641e8046a41086a200641e8016a41086a290300370300200641d0056a41086a200641a8026a41086a290300370300200641d0056a41106a200641a8026a41106a290300370300200641d0056a41186a200641a8026a41186a290300370300200641d0056a41206a200641a8026a41206a290300370300200641d0056a41286a200641a8026a41286a290300370300200620062903e8013703e804200620062903a8023703d005410021010c010b410121010b200641b0016a41086a2218200641d0056a41086a290300370300200641b0016a41106a2219200641d0056a41106a290300370300200641b0016a41186a2211200641d0056a41186a290300370300200641b0016a41206a221a200641d0056a41206a290300370300200641b0016a41286a221b200641d0056a41286a29030037030020064190016a41086a2220200641e8046a41086a29030037030020064190016a41106a2221200641e8046a41106a29030037030020064190016a41186a2222200641e8046a41186a290300370300200620062903d0053703b001200620062903e80437039001024020010d00200641e0006a200629039001370300200641206a41106a2018290300370300200641206a41186a2019290300370300200641206a41206a2011290300370300200641206a41286a201a290300370300200641d0006a201b290300370300200641e8006a2020290300370300200641f0006a2021290300370300200641f8006a20222903003703002006200c370320200620062903b0013703282006200437035820064188016a201037030020064180016a22012017370300200641206a10d20402402006290320500d002006200641c8006a3602d005200641d0056a10cc020b200641d8006a10d20402402006290358500d00200620013602d005200641d0056a10cc020b200641086a41086a290300210420062903082103200641206a41186a2006280204220141186a290000220c370300200641206a41106a200141106a290000220a370300200641206a41086a200141086a290000220f370300200620012900002207370320200641a8066a2004370300200641a0066a2003370300200641d0056a41086a41023a0000200641d9056a2007370000200641e1056a200f370000200641e9056a200a370000200641f1056a200c370000200641f9056a200229000037000020064181066a200241086a29000037000020064189066a200241106a29000037000020064191066a200241186a290000370000200641033a00d005200641d0056a10fe01200041063a00000c010b20002005360200200041046a200c3702000b200641d0066a24000beb130a017f047e017f047e0b7f017e027f017e017f0c7e230041f0026b2204240002400240200220038450450d00420021054200210642002107420021080c010b20044180016a200110c802200441f0016a200428028001220920042802880110c90220044190026a290300210a20044188026a290300210b20044180026a290300210620042903f801210c20042903f001210d0240200428028401450d002009102e0b420021050240200d4201520d00200c200b842006200a8484500d00200441f0016a41c8006a210e200441f0016a41086a210f20044180016a41306a211020044180016a41206a211141002109200441f0016a41386a2112200441f0016a41106a2113200441c0006a41286a2114200441c0006a41186a211502400240024003402004200136022c20044180016a200110c802200441f0016a200428028001221620042802880110c90220122903002107200441f0016a41306a2217290300210b200441f0016a41206a221829030021082013290300210d2004290398022105200429038802211920042903f801210a20042903b002210c20042903f0012106200441306a41086a200e41086a2903003703002004200e2903003703300240024020064201510d004200210c200441c0006a41386a4200370300200441c0006a41306a420037030020144200370300200441c0006a41206a420037030020154200370300200441c0006a41106a4200370300200441c0006a41086a420037030020044200370340420021054200210b4200210a4200210d0c010b2014200b370300200441c0006a41306a2007370300200420053703602004200a3703402004200c370378200420193703502004200d370348200420083703580b0240200428028401450d002016102e0b02400240200a200d844200520d002005200429035084200429037084200b201529030084200441c0006a41386a290300848450450d0042002119410021160c010b200441c0006a41106a290300210a200441c0006a41306a290300210820142903002106200441c0006a41206a29030021072004290348210d2004290340210b4201211920042903582105410121160b02402019420152221a450d004200210742002106420021084200210c4200210a420021054200210b4200210d0b200441f0016a41286a221b2006370300201720083703002004200b3703f0012004200d3703f801200441f0016a41186a200542002005200d7c200a200b7c2206200a54ad7c220820064280c8afa02554ad7d221920064280b8d0df5a7c221c2006562019200856200642ffc7afa025561b221d1b220620034200201c201d1b2208200254200620035420062003511b221d1b200320091b22062005200a20082002201d1b200220091b220856200520065620052006511b221d1b22067d200a2008200a201d1b220554ad7d221937030020042007370390022004200a20057d221c37038002200320067d2002200554ad7d2108200220057d2107201aad211e02400240427f200b201c7c220a200a200b54221a200d20197c201aad7c220a200d54200a200d511b221a1b221f42ffc7afa02556427f200a201a1b220a420052200a501b0d002020200a200b201c84200d20198484220c5022171b21202021201f20171b21214200210a200c420052ad21190c010b20172903002122201b29030021232018290300212420132903002125200429038802212620042903f801212720042903f00121284201210a4200211941012117200c21290b20044180016a41c8006a200837030020044180016a41386a200637030020044180016a41286a202037030020044180016a41106a200d370300200420073703c001200420053703b001200420213703a0012004200b3703880120042019370398012004201e3703800102402016200a420152720d00200420013602f0012001200441f0016a10bd060c030b20164101732216200a420151720d01200420013602f00102402001200441f0016a10be0641ff017122164102460d0020160d03200441c8016a2903002108200441b8016a2903002106200441a8016a290300212020044190016a290300210d20042903c001210720042903b001210520042903a0012121200429038801210b2004290398012119200429038001211e0c040b024020170d00200420113602f001200441f0016a10cc020b200420103602f001200441f0016a10cc02200941016a22094102470d000b420021050c030b200a4201522016710d010b200441d0016a200110c802200441f0016a20042802d001220920042802d801221610c90220042903f001210d200441306a41086a2217200e41086a2903003703002004200e29030037033002400240200d4201510d00200441e0016a41086a4200370300200442003703e0010c010b200441e0016a41086a2017290300370300200420042903303703e0010b0240200a4201510d0042002128420021274200212442002123420021224200212942002125420021260b200e20042903e001370300200441a0026a202337030020044190026a2026370300200441f0016a41106a2027370300200441f0016a41386a2022370300200e41086a200441e0016a41086a29030037030020042024370398022004202537038802200420283703f801200420293703b002200442013703f00120092016200f10c805024020042802d401450d002009102e0b20044180016a41106a290300210d200441a8016a290300212020044180016a41386a2903002106200441c8016a2903002108200429038801210b20042903a001212120042903b001210520042903c0012107200429038001211e20042903980121190b0240201e4201520d00200441a8026a200d370300200441a0026a200b370300200441f0016a41086a41003a0000200441f9016a200129000037000020044181026a200141086a29000037000020044189026a200141106a29000037000020044191026a200141186a290000370000200441033a00f001200441f0016a10fe010b02400240201950450d00420021030c010b200441f0016a41086a200428022c220141086a290000370300200441f0016a41106a200141106a290000370300200441f0016a41186a200141186a290000370300200420012900003703f001420121030b200441086a41186a200441f0016a41186a2201290300220d370300200441086a41106a200441f0016a41106a2209290300220a370300200441086a41086a200441f0016a41086a290300220b370300200420042903f0012202370308200441a0026a202037030020044198026a221620213703002009200b3703002001200a37030020044190026a200d370300200420033703f001200420023703f801200441f0016a10d20420042903f001500d01200420163602800120044180016a10cc020c010b4200210620022107200321080b2000200737031020002005370300200041186a200837030020002006370308200441f0026a24000b9b0304057f027e017f027e230041d0006b22012400200141386a22024200370300200141206a41106a22034200370300200141206a41086a2204420037030020014200370320200141c0006a41f8fcc60041081081022004200141c0006a41086a220529000037030020012001290040370320200141c0006a41a8aac800410d1081022002200529000037030020032001290040370300200141086a200141206a412010f802200141086a41106a290300210620012903102107200128020821082000280200220041086a29030021092000290300210a20024200370300200342003703002004420037030020014200370320200141c0006a41f8fcc60041081081022004200529000037030020012001290040370320200141c0006a41a8aac800410d1081022002200529000037030020032001290040370300200142002006420020081b220620097d2007420020081b2207200a54ad7d22092007200a7d220a200756200920065620092006511b22021b37034820014200200a20021b370340200141206a4120200141c0006a411010b201200141d0006a24000b8f0201027f230041d0006b22022400200241d4e2cc0036023020022001360228200241edde91e30636022c02404104102c2203450d002002420437023c20022003360238200241386a200241286a41047241041074200241386a200141081074200228023821012002200228024036024c200220013602482002200241c8006a10d0040240200228023c450d002001102e0b0240024020022d00004101470d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002002290001370000200041186a200241196a290000370000200041106a200241116a290000370000200041086a200241096a2900003700000b200241d0006a24000f0b1036000b9a0304057f027e017f027e230041d0006b22012400200141386a22024200370300200141206a41106a22034200370300200141206a41086a2204420037030020014200370320200141c0006a41f8fcc60041081081022004200141c0006a41086a220529000037030020012001290040370320200141c0006a41a8aac800410d1081022002200529000037030020032001290040370300200141086a200141206a412010f802200141086a41106a290300210620012903102107200128020821082000280200220041086a29030021092000290300210a20024200370300200342003703002004420037030020014200370320200141c0006a41f8fcc60041081081022004200529000037030020012001290040370320200141c0006a41a8aac800410d10810220022005290000370300200320012900403703002001427f20092006420020081b22067c200a2007420020081b22077c22092007542202ad7c22072002200720065420072006511b22021b3703482001427f200920021b370340200141206a4120200141c0006a411010b201200141d0006a24000bd88f01040a7f047e047f037e230022032104200341c0086b416071220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0b00010203040506070d1817000b20034194056a410136020020034201370284052003419cc3cb0036028005200341043602e403200341a4a7c7003602e0032003200341e0036a3602900520034180056a4198f3c0001044000b200141246a2802002105200141216a2d00002106200341b8076a41186a200141196a290000370300200341b8076a41106a200141116a290000370300200341b8076a41086a200141096a290000370300200320012900013703b80720034180056a41286a2201200241286a28020036020020034180056a41206a2207200241206a29020037030020034180056a41186a2208200241186a29020037030020034180056a41106a2209200241106a29020037030020034180056a41086a220a200241086a2902003703002003200229020037038005200341e0036a20034180056a10c102200341c0036a41086a2202200341e0036a41096a290000370300200341c0036a41106a220b200341e0036a41116a290000370300200341c0036a41186a220c200341e0036a41196a290000370300200320032900e1033703c00320032d00e0034101460d14200341a0026a41186a200c290300370300200341a0026a41106a200b290300370300200341a0026a41086a2002290300370300200320032903c0033703a00220034180056a200341b8076a200341a0026a200610d002200341e0036a41086a2008290300370300200341e0036a41106a2007290300370300200341e0036a41186a2001280200360200200320092903003703e003200a290300210d20032802840521012003280280054101460d2f200341e0046a41186a2202200341e0036a41186a280200360200200341e0046a41106a2206200341e0036a41106a290300370300200341e0046a41086a2207200341e0036a41086a290300370300200320032903e0033703e00402402001450d0020034180056a410710d102200329028405210d20032802800521010c300b200341ec036a20032903e004370200200341f4036a2007290300370200200341e0036a411c6a200629030037020020034184046a20022802003602002003200d3702e403200341003602e003200341d8076a41186a200341b8076a41186a290300370300200341d8076a41106a200341b8076a41106a290300370300200341d8076a41086a200341b8076a41086a290300370300200320032903b8073703d80720034180056a200541b00210e9081a200341e0036a200341d8076a20034180056a10d2022005102e200320032800c0043602a0042003200341c3046a2800003600a304200041186a41003a000020004200370308200020032802a0043600192000411c6a20032800a30436000020004200370300200424000f0b200141246a2802002109200141216a2d0000210a200341a0036a41186a2205200141196a290000370300200341a0036a41106a2206200141116a290000370300200341a0036a41086a2207200141096a290000370300200320012900013703a003200341e0036a41286a200241286a280200360200200341e0036a41206a200241206a290200370300200341e0036a41186a200241186a290200370300200341e0036a41106a200241106a290200370300200341e0036a41086a200241086a290200370300200320022902003703e003200341d8076a200341e0036a10c102200341c0036a41086a2201200341d8076a41096a290000370300200341c0036a41106a2202200341d8076a41116a290000370300200341c0036a41186a2208200341d8076a41196a290000370300200320032900d9073703c00320032d00d8074101460d11200341a0046a41186a2008290300370300200341a0046a41106a2002290300370300200341a0046a41086a2001290300370300200320032903c0033703a004200341c0046a41186a2005290300370300200341c0046a41106a2006290300370300200341c0046a41086a2007290300370300200320032903a0033703c0040240200341a0046a200341c0046a412010ec080d00200341d8076a410810d102200341ef036a200341d8076a41086a280200220136000020034198056a41003a0000200341a8056a2001360000200320032903d8073700e703200341a1056a200341e0036a41086a29000037000020034200370388052003420137038005200320032900e00337009905410121020c2c0b200341e0046a41186a2206200341c0046a41186a290300370300200341e0046a41106a2207200341c0046a41106a290300370300200341e0046a41086a2208200341c0046a41086a290300370300200320032903c0043703e004200341b0086a200341a0046a10d302200341e0036a20032802b00820032802b80810d402200341ec036a280200210b0240024020032802e00322050d004200210e4100210141042105410021024200210d0c010b200341e0036a41186a290300210d200341e0036a41106a290300210e200341e0036a41086a280200210220032802e40321010b200341b8076a41186a2006290300370300200341b8076a41106a2007290300370300200341b8076a41086a2008290300370300200320032903e0043703b807024020024120490d00200341e0036a410110d10220032f00e10320032d00e3034110747221020c290b200341f4076a200341b8076a41186a290300370200200341ec076a200341b8076a41106a290300370200200341e4076a200341b8076a41086a290300370200200320032903b8073702dc072003200a3a00fc07200320093602d807200341306a20052002200341d8076a10d5022003280230450d0b20032802342107200341e0036a41206a200341d8076a41206a290300370300200341e0036a41186a200341d8076a41186a290300370300200341e0036a41106a200341d8076a41106a290300370300200341e0036a41086a200341d8076a41086a290300370300200320032903d8073703e00320022007490d12024002400240024020022001470d00200141016a22062001490d09200141017422082006200820064b1b22064104200641044b1bad42287e220f422088a7454102742106200fa721080240024020010d00200341003602c0030c010b200341c8036a4104360200200320053602c0032003200141286c3602c4030b20034180036a20082006200341c0036a107d20034188036a28020021012003280280034101460d012003280284032105200141286e21010b2005200741286c6a220641286a2006200220076b41286c10ea081a200641206a200341e0036a41206a290300370200200641186a200341e0036a41186a290300370200200641106a200341e0036a41106a290300370200200641086a200341e0036a41086a290300370200200620032903e003370200200341206a200241016a2202ad42004280cdad9d01420010e80820032903202210428088caade9057c220f200e56200341206a41086a290300200f201054ad7c2210200d562010200d5122061b450d01200341e0036a200341a0046a200f200e7d2010200d7d200f200e54ad7d10c30220032d00e00322064106460d0220032f00e10320032d00e30341107472210220032902e403210d0c2c0b2001450d070c290b200e200f58200d20105820061b0d00200341106a200341a0046a200e200f7d200d20107d200e200f54ad7d10fb010b200341f8036a20103703002003200f3703f0032003200b3602ec03200320023602e803200320013602e403200320053602e00320032802b808210220032802b00821060240024020050d002006200210ff010c010b20062002200341e0036a10d6022005450d002001450d00200141286c450d002005102e0b20034198056a41003a00002003419c056a200341a3086a28000036000020034200370380052003420037038805200320032800a008360099050c2a0b200141246a2802002109200141216a2d0000210a200341c0046a41186a2205200141196a290000370300200341c0046a41106a2206200141116a290000370300200341c0046a41086a2207200141096a290000370300200320012900013703c004200341e0036a41286a200241286a280200360200200341e0036a41206a200241206a290200370300200341e0036a41186a200241186a290200370300200341e0036a41106a200241106a290200370300200341e0036a41086a200241086a290200370300200320022902003703e003200341a0026a200341e0036a10c102200341c0036a41086a2201200341a0026a41096a290000370300200341c0036a41106a2202200341a0026a41116a290000370300200341c0036a41186a2208200341a0026a41196a290000370300200320032900a1023703c003024020032d00a0024101470d0020034180056a41206a41023a000020034180056a41186a41003a00002003420037038805200342013703800520034180056a41086a21010c250b200341e0046a41186a2008290300370300200341e0046a41106a2002290300370300200341e0046a41086a2001290300370300200320032903c0033703e004200341a0036a200341e0046a10d302200341a0026a20032802a00320032802a80310d402200341b8076a41186a2005290300370300200341b8076a41106a2006290300370300200341b8076a41086a2007290300370300200320032903c0043703b807200341a0026a41186a2201290300210e200120032903f803370300200341003602e00320032903b0022110200320032903f0033703b00220032903a802210f200320032903e8033703a80220032903a002210d200320032903e0033703a002200da72201450d0f200341fc036a200341b8076a41186a290300370200200341f4036a200341c8076a290300370200200341ec036a200341b8076a41086a290300370200200320032903b8073702e4032003200a3a008404200320093602e003200341d8006a2001200fa72205200341e0036a10d502200d422088a721020240024020032802580d00200328025c220620054f0d102001200641286c6a2207200741286a20052006417f736a41286c10ea081a02402005417f6a22050d004200210f4200210d0c220b200341c8006a2005ad42004280cdad9d01420010e8082003290348220d428088caade9057c220f201056200341d0006a290300200f200d54ad7c220d200e56200d200e511b450d21200341a0046a200341e0046a200f20107d200d200e7d200f201054ad7d10c30220032d00a00422064106460d2220032d00a304210520032f00a104210720032902a404210d200341a0056a20063a000020034198056a41003a00002003200720054110747222053b00a105200341a3056a20054110763a00002003200d3702a405200342003703880520034201370380050c010b200341c0036a410210d102200341af046a200341c0036a41086a280200220536000020034180056a41186a41003a0000200341a8056a2005360000200320032903c0033700a704200341a1056a200341a0046a41086a29000037000020034200370388052003420137038005200320032900a004370099050b2002450d23200241286c450d232001102e0c230b20034180056a41286a200241286a28020036020020034180056a41206a200241206a29020037030020034180056a41186a200241186a29020037030020034180056a41106a200241106a29020037030020034180056a41086a200241086a2902003703002003200229020037038005200341e0036a20034180056a10c102200341c0036a41086a2201200341e9036a290000370300200341c0036a41106a2202200341f1036a290000370300200341c0036a41186a2205200341f9036a290000370300200320032900e1033703c003024020032d00e0034101470d00200320032800e0043602c004200320032900a0023703b8072003200341e3046a2800003600c3042003200341a7026a2800003600bf07200041186a41003a000020004200370308200020032802c0043600192000411c6a20032800c304360000200041206a41023a0000200020032903b807370021200041286a20032800bf0736000020004201370300200424000f0b200341d8076a41186a2005290300370300200341d8076a41106a2002290300370300200341d8076a41086a2001290300370300200320032903c0033703d807200341e0036a200341d8076a10d30220034180056a20032802e003220220032802e803220110d4020240024020032802800522050d004200210d41042105410021014200210e0c010b2002200110ff0120034198056a290300210e20034190056a290300210d20032802840521010b024020032802e403450d002002102e0b02402001450d00200141286c450d002005102e0b200341e0006a200341d8076a200d200e10fb01200320032800e0043602c0042003200341e3046a2800003600c304200041186a41003a000020004200370308200020032802c0043600192000411c6a20032800c30436000020004200370300200424000f0b41022105200141026a2f01002106200141046a2802002109200320012d00013a00b00820034180056a41286a200241286a28020036020020034180056a41206a200241206a29020037030020034180056a41186a200241186a29020037030020034180056a41106a200241106a29020037030020034180056a41086a2201200241086a2902003703002003200229020037038005200341e0036a20034180056a10c102200341d8076a41086a2202200341e9036a290000370300200341d8076a41106a2207200341f1036a290000370300200341d8076a41186a2208200341f9036a290000370300200320032900e1033703d807024020032d00e0034101460d00200341a0026a41186a2008290300370300200341a0026a41106a2007290300370300200341a0026a41086a2002290300370300200320032903d8073703a002200341b8076a41186a22024200370300200341b8076a41106a22054200370300200341b8076a41086a22074200370300200342003703b80720034180056a41d9fcc60041061081022007200129000037030020032003290080053703b80720034180056a4180f4cb004106108102200220012900003703002005200329008005370300200341f8006a200341b8076a4120108e02200328027c210120032802782102200341f0006a41fcc6cb004110108e022003280274210520032802702107200320063b01940520032005410020071b36028c0520032001410020021b36028805200341a8f3c000360280052003200341b0086a360290052003200341a0026a36028405200341c0036a20034180056a10d702200341203602dc072003200341c0036a3602d80720034180056a200341d8076a1093010240024020032d0080054101470d00200341f8036a4200370300200341f0036a4200370300200341e8036a4200370300200342003703e0030c010b200341f8036a20034199056a290000370300200341f0036a20034191056a290000370300200341e8036a20034189056a29000037030020032003290081053703e0030b20034180056a200341e0036a10d3022003280280052202200328028805108f0221010240200328028405450d002002102e0b02402001450d0020034180056a410510d10220032003290081053703e004200320034188056a2800003600e70420032d00800521050c010b20034180056a200341a0026a4280d5f7caea05420010c302200320032900810537039004200320034180056a41086a28000036009704024020032d00800522054106470d00200341a0046a41086a200341a0026a41086a290300370300200341a0046a41106a2202200341a0026a41106a290300370300200341a0046a41186a2205200341a0026a41186a290300370300200320032903a0023703a00420032d00b00821074128102c2201450d2620012009360200200120032903a004370204200120073a0024200120032f01c0033b00252001410c6a200341a8046a290300370200200141146a20022903003702002001411c6a2005290300370200200141276a200341c2036a2d00003a0000200341b8076a200341e0036a10d30220032802c007210520032802b8072102413c102c2207450d262003423c3702dc07200320073602d80720014101200341d8076a10d802200342003703880520034280d5f7caea0537038005200341d8076a20034180056a411010742002200520032802d807220720032802e00710b201024020032802dc07450d002007102e0b024020032802bc07450d002002102e0b2001102e20032d00b00821012003418d056a200341e0036a41086a29030037000020034195056a200341e0036a41106a2903003700002003419d056a200341e0036a41186a290300370000200341a5056a20032903a002370000200341ad056a200341a0026a41086a290300370000200341b5056a200341a0026a41106a290300370000200341bd056a200341a0026a41186a290300370000200341c6056a20063b0100200341c5056a20013a0000200341013a008405200341133a008005200320032903e0033700850520034180056a10fe01200320032800a003360280032003200341a3036a28000036008303200041186a41003a00002000420037030820002003280280033600192000411c6a20032800830336000020004200370300200424000f0b20032003280097043600e70420032003290390043703e0040b200320032800a00336028003200320032903e0043703c004200320032800e7043600c7042003200341a3036a28000036008303200041186a41003a00002000420037030820002003280280033600192000411c6a200328008303360000200041206a20053a0000200020032903c004370021200041286a20032800c70436000020004201370300200424000f0b200141286a2802002106200141246a2802002107200141226a2f01002108200141216a2d00002105200341a0026a41186a200141196a290000370300200341a0026a41106a200141116a290000370300200341a0026a41086a200141096a290000370300200320012900013703a002200320053a00b00820034180056a41286a200241286a28020036020020034180056a41206a200241206a29020037030020034180056a41186a200241186a29020037030020034180056a41106a200241106a29020037030020034180056a41086a200241086a2902003703002003200229020037038005200341e0036a20034180056a10c102200341a0046a41086a2201200341e0036a41096a290000370300200341a0046a41106a2202200341e0036a41116a290000370300200341a0046a41186a2205200341e0036a41196a290000370300200320032900e1033703a0040240024020032d00e0034101460d00200341d8076a41186a2005290300370300200341d8076a41106a2002290300370300200341d8076a41086a2001290300370300200320032903a0043703d807200320083b0194052003200636028c052003200736028805200341a8f3c000360280052003200341b0086a360290052003200341a0026a36028405200341c0036a20034180056a10d702200341203602bc072003200341c0036a3602b80720034180056a200341b8076a1093010240024020032d0080054101470d00200341f8036a4200370300200341f0036a4200370300200341e8036a4200370300200342003703e0030c010b200341f8036a20034199056a290000370300200341f0036a20034191056a290000370300200341e8036a20034189056a29000037030020032003290081053703e0030b0240200341e0036a200341d8076a412010ec08450d0020034180056a410610d10220032003290081053703e004200320034188056a2800003600e70420032d00800521010c020b200341b8076a200341d8076a10d30220034180056a20032802b807220220032802c007220110d4020240024020032802800522050d004200210d41002101410421054200210e0c010b2002200110ff0120034198056a290300210e20034190056a290300210d20032802840521010b024020032802bc07450d002002102e0b02402001450d00200141286c450d002005102e0b20034180016a200341a0026a200d200e10fb01200320032800a003360280032003200341a3036a28000036008303200041186a41003a00002000420037030820002003280280033600192000411c6a20032800830336000020004200370300200424000f0b410221010b200320032800a00336028003200320032903e0043703c004200320032800e7043600c7042003200341a3036a28000036008303200041186a41003a00002000420037030820002003280280033600192000411c6a200328008303360000200041206a20013a0000200020032903c004370021200041286a20032800c70436000020004201370300200424000f0b20034180036a41186a200141196a29000037030020034180036a41106a200141116a29000037030020034180036a41086a200141096a2900003703002003200129000137038003200341a0036a41186a200141396a290000370300200341a0036a41106a200141316a290000370300200341a0036a41086a200141296a2900003703002003200141216a2900003703a00320034180056a41286a200241286a28020036020020034180056a41206a200241206a29020037030020034180056a41186a200241186a29020037030020034180056a41106a200241106a29020037030020034180056a41086a2201200241086a2902003703002003200229020037038005200341e0036a20034180056a10c102200341d8076a41086a2202200341e0036a41096a290000370300200341d8076a41106a2205200341e0036a41116a290000370300200341d8076a41186a2206200341e0036a41196a290000370300200320032900e1033703d80720032d00e0034101460d09200341c0046a41186a2006290300370300200341c0046a41106a2005290300370300200341c0046a41086a2002290300370300200320032903d8073703c004200341e0036a20034180036a10d30220034180056a20032802e003220620032802e80310d4022001280200410020032802800522011b21022003280284052105024020032802e403450d002006102e0b2001410420011b21112005410020011b2112024002402002450d002011200241286c6a210c20034180056a410472210b20034180056a41256a2106200341d8076a41026a2105201121010340200341e0036a41206a2207200141206a280200360200200341e0036a41186a2208200141186a290200370300200341e0036a41106a2209200141106a290200370300200341e0036a41086a220a200141086a290200370300200320012902003703e003200141246a2d000021022005200141276a2d00003a00002003200141256a2f00003b01d80720024107460d01200620032f01d8073b000020034180056a41206a200728020036020020034180056a41186a200829030037030020034180056a41106a200929030037030020034180056a41086a200a290300370300200641026a20052d00003a0000200320032903e00337038005200320023a00a405200b200341c0046a412010ec08450d02200141286a2201200c470d000b0b20034180056a410310d10220032003290081053703e802200320034188056a2800003600ef0220032d00800521012012450d1b201241286c450d1b2011102e0c1b0b02402012450d00201241286c450d002011102e0b200341c0036a41086a220520034180036a41086a290300370300200341c0036a41106a220620034180036a41106a290300370300200341c0036a41186a220920034180036a41186a290300370300200341a0046a41086a220a200341a0036a41086a290300370300200341a0046a41106a220b200341a0036a41106a290300370300200341a0046a41186a220c200341a0036a41186a29030037030020032003290380033703c003200320032903a0033703a0044200210d200341b8076a41186a22014200370300200341b8076a41106a22074200370300200341b8076a41086a22084200370300200342003703b80720034180056a41d9fcc6004106108102200820034180056a41086a220229000037030020032003290080053703b80720034180056a4180f4cb004106108102200120022900003703002007200329008005370300200341b0016a200341b8076a4120108e0220032802b401211220032802b0012111200820052903003703002007200629030037030020012009290300370300200341e0046a41086a2209200a290300370300200341e0046a41106a220a200b290300370300200341e0046a41186a220b200c290300370300200320032903c0033703b807200320032903a0043703e00420034180086a200341c0046a10d90220034180056a20032802800820032802880810da022003418c056a280200210c0240024020032802800522060d004104210641002102410021054200210e0c010b20034180056a41186a290300210e20034180056a41106a290300210d2002280200210520032802840521020b200341d8076a41086a2008290300370300200341d8076a41106a2007290300370300200341d8076a41186a2001290300370300200341a0026a41086a2009290300370300200341a0026a41106a200a290300370300200341a0026a41186a200b290300370300200320032903b8073703d807200320032903e0043703a0022005411f4b0d0320034180056a41086a2207200341d8076a41086a29030037030020034180056a41106a2208200341d8076a41106a29030037030020034180056a41186a2209200341d8076a41186a290300370300200341e0036a41086a220a200341a0026a41086a290300370300200341e0036a41106a220b200341a0026a41106a290300370300200341e0036a41186a2213200341a0026a41186a290300370300200320032903d80737038005200320032903a0023703e00320052002470d02200241016a22012002490d00200241017422142001201420014b1b22014104200141044b1bad42c4007e220f422088a7454102742101200fa721140240024020020d00200341003602b0080c010b200341b8086a4104360200200320063602b0082003200241c4006c3602b4080b200341a0086a20142001200341b0086a107d200341a8086a280200210120032802a0084101470d0120010d220b1038000b20032802a4082106200141c4006e21020b2006200541c4006c6a22012012410020111b36020020012003290380053702042001410c6a2007290300370200200141146a20082903003702002001411c6a2009290300370200200120032903e0033702242001412c6a200a290300370200200141346a200b2903003702002001413c6a2013290300370200200341a0016a200541016a2205ad420042809adbba02420010e8080240024020032903a0012210428088caade9057c220f200d58200341a0016a41086a290300200f201054ad7c2210200e582010200e5122011b0d0020034180056a200341c0046a200f200d7d2010200e7d200f200d54ad7d10c30220032d00800522014106460d0120032d008305210520032f008105210720032003290284053702940820032007200541107472410874200172360290080c170b200d200f58200e20105820011b0d0020034190016a200341c0046a200d200f7d200e20107d200d200f54ad7d10fb010b41062101200341063a0090080c010b20034190086a410110d102200d210f200e211020032d00900822014106470d140b20034198056a20103703002003200f370390052003200c36028c05200320053602880520032002360284052003200636028005200328028808210520032802800821070240024020060d002007200510ff010c010b2007200520034180056a10db022006450d002002450d00200241c4006c450d002006102e0b20032003290091083703e003200320034198086a2800003600e7030c140b200341b8076a41186a200141196a290000370300200341b8076a41106a200141116a290000370300200341b8076a41086a200141096a290000370300200320012900013703b807200341a0026a41186a200141396a290000370300200341a0026a41106a200141316a290000370300200341a0026a41086a200141296a2900003703002003200141216a2900003703a00220034180056a41286a200241286a28020036020020034180056a41206a200241206a29020037030020034180056a41186a200241186a29020037030020034180056a41106a200241106a29020037030020034180056a41086a200241086a2902003703002003200229020037038005200341e0036a20034180056a10c102200341c0036a41086a2201200341e0036a41096a290000370300200341c0036a41106a2202200341e0036a41116a290000370300200341c0036a41186a2205200341e0036a41196a290000370300200320032900e1033703c00320032d00e0034101460d01200341d8076a41186a2005290300370300200341d8076a41106a2002290300370300200341d8076a41086a2001290300370300200320032903c0033703d807200341e0046a200341d8076a10d902200341e0036a20032802e00420032802e80410da02200341e0036a41186a2201290300210e200120032903980537030041002108200341003602800520032903f003211020032003290390053703f00320032903e803210f20032003290388053703e80320032903e003210d20032003290380053703e003200da72207450d02200d422088210d0240200fa72206450d00200741246a210a41002109410021084100210202400340024002402008450d002007200241c4006c6a21012007200220096a41c4006c6a210503400240200141046a200341b8076a412010ec080d00200141246a200341a0026a412010ec08450d030b2005200141c40010e90841c4006a2105200141c4006a2101200241016a22022006490d000c040b0b200a200241c4006c6a210103400240200141606a200341b8076a412010ec080d002001200341a0026a412010ec08450d020b200141c4006a2101200241016a22022006490d000b410021080c030b2009417f6a2109200841016a2108200241016a22022006490d000b0b024020080d00410021080c010b2007200220086b41c4006c6a2007200241c4006c6a200620026b41c4006c10ea081a0b200da7210202400240200620086b22012006490d0020034180056a410210d1020c010b200d200f422086842115024020010d004200210f4200210d0c0e0b200341c8016a2001ad2216420042809adbba02420010e80820032903c801220d428088caade9057c220f201058200341d0016a290300200f200d54ad7c220d200e58200d200e511b0d0d20034180056a200341d8076a200f20107d200d200e7d200f201054ad7d10c302024020032d00800522014106470d002016422086201542ffffffff0f8384210e0c0f0b20032d008305210520032f008105210620032003290284053702840520032006200541107472410874200172360280050b2002450d0b200241c4006c450d0b2007102e0c0b0b200341e0036a410510d10220032f00e10320032d00e3034110747221020c1c0b410221010c0f0b20034180056a410210d1020c080b410221010c100b200620051046000b200341a0046a410210d102200341ef036a200341a0046a41086a280200220136000020034198056a41003a0000200341a8056a2001360000200320032903a0043700e703200341a1056a200341e0036a41086a29000037000020034200370388052003420137038005200320032900e003370099050c130b20034180056a41206a41023a000020034180056a41186a41003a00002003420037038805200342013703800520034180056a41086a21010c1a0b200720021045000b410221010c1a0b200141c4006a2802002107200141c1006a2d00002105200341c0046a41186a200141196a290000370300200341c0046a41106a200141116a290000370300200341c0046a41086a200141096a290000370300200320012900013703c004200341e0046a41186a200141396a290000370300200341e0046a41106a200141316a290000370300200341e0046a41086a200141296a2900003703002003200141216a2900003703e00420034180056a41286a2201200241286a28020036020020034180056a41206a2206200241206a29020037030020034180056a41186a2208200241186a29020037030020034180056a41106a2209200241106a29020037030020034180056a41086a220a200241086a2902003703002003200229020037038005200341e0036a20034180056a10c10202400240024020032d00e0034101470d00410221090c010b20034180056a200341e0046a200341c0046a200510d002200341e0036a41086a2008290300370300200341e0036a41106a2006290300370300200341e0036a41186a2001280200360200200320092903003703e00320032f00850520032d008705411074722108200a290300210d20032d00840521092003280280054101460d00200341a0046a41186a200341e0036a41186a2201280200360200200341a0046a41106a200341e0036a41106a290300370300200341a0046a41086a200341e0036a41086a290300370300200320032903e0033703a00420034100360288052003420137038005200720034180056a109002200341b8076a20032802800520032802880510b001200341a0026a41186a200341b8076a41186a2202290200370300200341a0026a41106a200341b8076a41106a2205290200370300200341a0026a41086a200341b8076a41086a2206290200370300200320032902b8073703a0020240200328028405450d00200328028005102e0b200242003703002005420037030020064200370300200342003703b80720034180056a41d9fcc6004106108102200620034180056a41086a220a29000037030020032003290080053703b80720034180056a4180f4cb0041061081022002200a290000370300200520032900800537030020034198026a200341b8076a4120108e02200328029c0221022003280298022105200341d8076a200341c0046a10d902200341e0036a20032802d80720032802e00710da022001290300210f200120032903980537030020032903f003211520032003290390053703f00320032903e803211020032003290388053703e803200341003602800520032903e003210e20032003290380053703e0030240024002400240024002400240200ea7220a450d00200e422088210e024002402010a722060d004100210c0c010b2002410020051b210b20084108742009722111410021134100210c410021020240034002400240200c450d00200a200241c4006c6a2101200a200220136a41c4006c6a210503400240200141046a200341e0046a412010ec080d00200141246a200341a0026a412010ec080d004100200b20012802006b22122012200b4b1b20114f0d030b2005200141c40010e90841c4006a2105200141c4006a2101200241016a22022006490d000c040b0b200a200241c4006c6a210103400240200141046a200341e0046a412010ec080d00200141246a200341a0026a412010ec080d004100200b20012802006b22052005200b4b1b20114f0d020b200141c4006a2101200241016a22022006490d000b4100210c0c030b2013417f6a2113200c41016a210c200241016a22022006490d000b0b0240200c0d004100210c0c010b200a2002200c6b41c4006c6a200a200241c4006c6a200620026b41c4006c10ea081a0b200ea72102024002402006200c6b22012006490d0020034180056a410210d1020c010b200e2010422086842116024020010d00420021104200210e0c040b20034188026a2001ad2217420042809adbba02420010e808200329038802220e428088caade9057c221020155820034190026a2903002010200e54ad7c220e200f58200e200f511b0d0320034180056a200341c0046a201020157d200e200f7d2010201554ad7d10c302024020032d00800522014106470d002017422086201642ffffffff0f8384210f0c050b20032d008305210520032f008105210620032003290284053702840520032006200541107472410874200172360280050b2002450d01200241c4006c450d01200a102e0c010b20034180056a410210d1020b20032d0080052202410646210120032802e003210a20024106460d02200a450d040c030b02402015201058200f200e58200f200e511b0d00200341f8016a200341c0046a201520107d200f200e7d2015201054ad7d10fb010b2001ad422086201642ffffffff0f8384210f20010d0002402002450d00200241c4006c450d00200a102e0b4100210a0b024020032802e0032201450d0020032802e4032202450d00200241c4006c450d002001102e0b200341f8036a200e370300200341f0036a20103703002003200f3702e4032003200a3602e003200341063a008005410121010b20032802e007210220032802d80721050240200a0d002005200210ff010c020b20052002200341e0036a10db020b20032802e4032202450d00200241c4006c450d00200a102e0b024020032802dc07450d0020032802d807102e0b02402001450d00200341ec036a20032903a004370200200341f4036a200341a0046a41086a290300370200200341e0036a411c6a200341a0046a41106a29030037020020034184046a200341a0046a41186a2802003602002003200d3702e403200320084108742009723602e003200341d8076a41186a200341e0046a41186a290300370300200341d8076a41106a200341e0046a41106a290300370300200341d8076a41086a200341e0046a41086a290300370300200320032903e0043703d80720034180056a200741b00210e9081a200341e0036a200341d8076a20034180056a10d2022007102e200320032800c003360280052003200341c3036a28000036008305200041186a41003a00004200210d2000420037030820002003280280053600192000411c6a2003280083053600000c020b20034180056a410710d10220032f00810520032d008305411074722108200329028405210d20032d00800521090b2007108b022007102e200320032800c003360280052003200341c3036a28000036008305200041236a20084110763a0000200020083b0021200041186a41003a00002000420037030820002003280280053600192000411c6a2003280083053600002000200d370024200041206a20093a00004201210d0b2000200d370300200424000f0b200341b8076a41186a200141196a290000370300200341b8076a41106a200141116a290000370300200341b8076a41086a200141096a290000370300200320012900013703b807200341a0026a41186a200141396a290000370300200341a0026a41106a200141316a290000370300200341a0026a41086a200141296a2900003703002003200141216a2900003703a00220034180056a41286a200241286a28020036020020034180056a41206a200241206a29020037030020034180056a41186a200241186a29020037030020034180056a41106a200241106a29020037030020034180056a41086a200241086a2902003703002003200229020037038005200341e0036a20034180056a10c102200341c0036a41086a2201200341e0036a41096a290000370300200341c0036a41106a2202200341e0036a41116a290000370300200341c0036a41186a2205200341e0036a41196a290000370300200320032900e1033703c00302400240024002400240024002400240024020032d00e0034101460d00200341d8076a41186a2005290300370300200341d8076a41106a2002290300370300200341d8076a41086a2001290300370300200320032903c0033703d807200341e0046a200341b8076a10d902200341e0036a20032802e00420032802e80410da02200341e0036a41186a2201290300210e200120032903980537030041002108200341003602800520032903f003211020032003290390053703f00320032903e803210f20032003290388053703e80320032903e003210d20032003290380053703e003200da72207450d01200d422088210d0240200fa72206450d00200741246a210a41002109410021084100210202400340024002402008450d002007200241c4006c6a21012007200220096a41c4006c6a210503400240200141046a200341d8076a412010ec080d00200141246a200341a0026a412010ec08450d030b2005200141c40010e90841c4006a2105200141c4006a2101200241016a22022006490d000c040b0b200a200241c4006c6a210103400240200141606a200341d8076a412010ec080d002001200341a0026a412010ec08450d020b200141c4006a2101200241016a22022006490d000b410021080c030b2009417f6a2109200841016a2108200241016a22022006490d000b0b024020080d00410021080c010b2007200220086b41c4006c6a2007200241c4006c6a200620026b41c4006c10ea081a0b200da7210202400240200620086b22012006490d0020034180056a410210d1020c010b200d200f422086842115024020010d004200210f4200210d0c050b200341e8016a2001ad2216420042809adbba02420010e80820032903e801220d428088caade9057c220f201058200341f0016a290300200f200d54ad7c220d200e58200d200e511b0d0420034180056a200341b8076a200f20107d200d200e7d200f201054ad7d10c302024020032d00800522014106470d002016422086201542ffffffff0f8384210e0c060b20032d008305210520032f008105210620032003290284053702840520032006200541107472410874200172360280050b2002450d02200241c4006c450d022007102e0c020b410221010c070b20034180056a410210d1020b20032d0080052201410646210220032802e003210720014106460d022007450d040c030b02402010200f58200e200d58200e200d511b0d00200341d8016a200341b8076a2010200f7d200e200d7d2010200f54ad7d10fb010b2001ad422086201542ffffffff0f8384210e20010d0002402002450d00200241c4006c450d002007102e0b410021070b024020032802e0032201450d0020032802e4032202450d00200241c4006c450d002001102e0b200341f8036a200d370300200341f0036a200f3703002003200e3702e403200320073602e00341062101200341063a008005410121020b20032802e804210520032802e0042106024020070d002006200510ff010c020b20062005200341e0036a10db020b20032802e4032205450d00200541c4006c450d002007102e0b024020032802e404450d0020032802e004102e0b200320032900810537039004200320034188056a2800003600970402402002450d00200320032800a003360280032003200341a3036a28000036008303200041186a41003a00002000420037030820002003280280033600192000411c6a20032800830336000020004200370300200424000f0b20032003280097043600c70420032003290390043703c0040b200320032800a00336028003200320032903c0043703a004200320032800c7043600a7042003200341a3036a28000036008303200041186a41003a00002000420037030820002003280280033600192000411c6a200328008303360000200041206a20013a0000200020032903a004370021200041286a20032800a70436000020004201370300200424000f0b20032d0080052201410646210220032802e003210720014106460d022007450d040c030b02402010200f58200e200d58200e200d511b0d00200341b8016a200341d8076a2010200f7d200e200d7d2010200f54ad7d10fb010b2001ad422086201542ffffffff0f8384210e20010d0002402002450d00200241c4006c450d002007102e0b410021070b024020032802e0032201450d0020032802e4032202450d00200241c4006c450d002001102e0b200341f8036a200d370300200341f0036a200f3703002003200e3702e403200320073602e00341062101200341063a008005410121020b20032802e804210520032802e0042106024020070d002006200510ff010c020b20062005200341e0036a10db020b20032802e4032205450d00200541c4006c450d002007102e0b024020032802e404450d0020032802e004102e0b200320032900810537039004200320034188056a2800003600970402402002450d00200320032800a003360280032003200341a3036a28000036008303200041186a41003a00002000420037030820002003280280033600192000411c6a20032800830336000020004200370300200424000f0b20032003280097043600c70420032003290390043703c0040b200320032800a00336028003200320032903c0043703a004200320032800c7043600a7042003200341a3036a28000036008303200041186a41003a00002000420037030820002003280280033600192000411c6a200328008303360000200041206a20013a0000200020032903a004370021200041286a20032800a70436000020004201370300200424000f0b20032003290091083703e003200320034198086a2800003600e7032002450d00200241c4006c450d002006102e0b0240200328028408450d00200328028008102e0b200320032903e00337039004200320032800e70336009704024020014106470d00200341a5056a20032903c0043700002003418d056a20034180036a41086a29030037000020034195056a20034180036a41106a2903003700002003419d056a20034180036a41186a290300370000200341ad056a200341c0046a41086a290300370000200341b5056a200341c0046a41106a290300370000200341bd056a200341c0046a41186a290300370000200341023a008405200341133a008005200320032903800337008505200341dd056a200341a0036a41186a290300370000200341d5056a200341a0036a41106a290300370000200341cd056a200341a0036a41086a290300370000200341c5056a20032903a00337000020034180056a10fe01200320032800f9023602e0022003200341fc026a2800003600e302200041186a41003a000020004200370308200020032802e0023600192000411c6a20032800e30236000020004200370300200424000f0b20032003280097043600ef0220032003290390043703e8020b200320032800f9023602e002200320032903e8023703d002200320032800ef023600d7022003200341fc026a2800003600e302200041186a41003a000020004200370308200020032802e0023600192000411c6a20032800e302360000200041206a20013a0000200020032903d002370021200041286a20032800d70236000020004201370300200424000f0b02402010200f56200e200d56200e200d511b450d00200341386a200341e0046a2010200f7d200e200d7d2010200f54ad7d10fb010b2005450d010b024020032802a0022206450d0020032802a4022207450d00200741286c450d002006102e0b200341a0026a41186a200d370300200341b0026a200f37030020034180056a41186a41003a0000200320053602a802200320023602a402200320013602a002200342003703800520034200370388050c010b20034198056a41003a00002003420037038005200342003703880502402002450d00200241286c450d002001102e0b20032802a00221010b20032802a803210220032802a0032105024020010d002005200210ff010c010b20052002200341a0026a10d6020b024020032802a002450d0020032802a4022201450d00200141286c450d0020032802a002102e0b024020032802a403450d0020032802a003102e0b20034180056a41086a21012003290380054201520d010b200341d8076a41206a200141206a290300220d370300200341d8076a41186a200141186a290300220e370300200341d8076a41106a200141106a290300220f370300200341d8076a41086a200141086a29030022103703002003200129030022153703d807200041286a200d370300200041206a200e370300200041186a200f370300200041106a20103703002000201537030820004201370300200424000f0b200341d8076a41106a200141106a290300220d370300200341d8076a41086a200141086a290300220e37030020032001290300220f3703d807200041186a200d370300200041106a200e3703002000200f37030820004200370300200424000f0b1036000b20032902e403210d20032d00e00321060b20034198056a41003a0000200341a0056a20063a0000200320023b00a105200341a3056a20024110763a00002003419c056a200341a3086a28000036000020034200370388052003420137038005200320032800a008360099052003200d3702a4052001450d00200141286c450d002005102e0b024020032802b408450d0020032802b008102e0b20032903800542015121020b20034180056a41086a21012002450d010b200341a0026a41206a200141206a290300220d370300200341a0026a41186a200141186a290300220e370300200341a0026a41106a200141106a290300220f370300200341a0026a41086a200141086a29030022103703002003200129030022153703a002200041286a200d370300200041206a200e370300200041186a200f370300200041106a20103703002000201537030820004201370300200424000f0b200341a0026a41106a200141106a290300220d370300200341a0026a41086a200141086a290300220e37030020032001290300220f3703a002200041186a200d370300200041106a200e3703002000200f37030820004200370300200424000f0b2005108b022005102e200320032800c0043602a0042003200341c3046a2800003600a304200041186a41003a000020004200370308200020032802a0043600192000411c6a20032800a304360000200041246a200d370200200041206a200136020020004201370300200424000b8a0e020e7f037e230041e0016b2204240020044190016a200110d302200441b8016a200428029001220520042802980110d402200441c0016a280200410020042802b80122061b210120042802bc0121070240200428029401450d002005102e0b2006410420061b21080240024002402001450d002008200141286c6a2109200441b8016a410472210a200441b8016a41256a2105024002400240200341ff0171220b4107460d00200441e4006a41026a210c200821010340200441e8006a41206a220d200141206a280200360200200441e8006a41186a220e200141186a290200370300200441e8006a41106a220f200141106a290200370300200441e8006a41086a2210200141086a29020037030020042001290200370368200141246a2d00002111200c200141276a2d00003a00002004200141256a2f00003b016420114107460d04200441b8016a41206a200d280200360200200441b8016a41186a200e290300370300200441b8016a41106a200f290300370300200441b8016a41086a2010290300370300200520042f01643b0000200541026a200c2d00003a0000200420042903683703b801200420113a00dc010240200a2002412010ec080d002011200b460d030b200141286a22012009470d000c040b0b200441e4006a41026a2111200821010340200441e8006a41206a220c200141206a280200360200200441e8006a41186a220d200141186a290200370300200441e8006a41106a220e200141106a290200370300200441e8006a41086a220f200141086a29020037030020042001290200370368200141246a2d000021032011200141276a2d00003a00002004200141256a2f00003b016420034107460d03200441b8016a41206a200c280200360200200441b8016a41186a200d290300370300200441b8016a41106a200e290300370300200441b8016a41086a200f290300370300200520042f01643b0000200541026a20112d00003a0000200420042903683703b801200420033a00dc010240200a2002412010ec08450d0020044190016a41206a41002802d8f34036020020044190016a41186a41002902d0f34037030020044190016a41106a41002902c8f340370300200141286a22012009470d010c040b0b20044190016a41206a200441b8016a41206a28020036020020044190016a41186a200441b8016a41186a29030037030020044190016a41106a200441b8016a41106a29030037030020044190016a41086a200441b8016a41086a2903003703002004418c016a41026a200541026a2d00003a0000200420042903b80137039001200420052f00003b018c010c010b20044190016a41206a200441b8016a41206a28020036020020044190016a41186a200441b8016a41186a29030037030020044190016a41106a200441b8016a41106a29030037030020044190016a41086a200441b8016a41086a2903003703002004418c016a41026a200541026a2d00003a0000200420042903b80137039001200420052f00003b018c010b200441c0006a41206a220120044190016a41206a2205280200360200200441c0006a41186a221120044190016a41186a2202290300370300200441c0006a41106a220a20044190016a41106a220c290300370300200441c0006a41086a220920044190016a41086a220d2903003703002004413c6a41026a220e2004418c016a41026a2d00003a00002004200429039001370340200420042f018c013b013c200341ff01714107470d010b41012105410721030c010b200520012802002201360200200220112903002212370300200c200a2903002213370300200d20092903002214370300200441e8006a41026a200e2d00003a0000200441c2016a2014370100200441ca016a2013370100200441d2016a2012370100200441da016a200136010020042004290340221237039001200420042f013c3b0168200420123701ba01410021050b2007410020061b2101200441106a41086a200441b8016a41086a2211290100370300200441106a41106a200441b8016a41106a290100370300200441106a41186a200441b8016a41186a290100370300200441106a411e6a200441b8016a411e6a2901003701002004410c6a41026a2202200441e8006a41026a2d00003a0000200420042901b801370310200420042f01683b010c0240024020050d0020002004290112370104200020042f010c3b0029200041286a20033a0000200041246a200441326a2801003601002000411c6a2004412a6a290100370100200041146a200441226a2901003701002000410c6a2004411a6a2901003701002000412b6a20022d00003a000002402001450d00200141286c450d002008102e0b410021010c010b200441b8016a410310d1022000410c6a2011280200360200200020042903b80137020402402001450d00200141286c450d002008102e0b410121010b20002001360200200441e0016a24000ba80201047f230041c0006b22022400410b210341f6fac000210441072105024002400240024002400240024002400240200141ff01710e09000102030405060708000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a41bc8ccc001044000b4107210341effac0002104410021050c060b41082103418be7c4002104410121050c050b4108210341e7fac0002104410221050c040b41dcfac0002104410321050c030b4109210341d3fac0002104410421050c020b410c210341c284ca002104410521050c010b41c8fac0002104410621050b200041833a3b0100200041086a2003360200200041046a2004360200200041026a20053a0000200241c0006a24000bd20a02057f017e23004190066b22032400200341186a200141186a290000370300200341106a200141106a290000370300200341086a200141086a29000037030020032001290000370300024002404110102c2204450d00200441f8f7c60036020c2004410136020820044281808080103702004110102c2201450d0020014190f8c60036020c20014101360208200142818080801037020020042004280200417f6a2205360200024020050d002004280208200428020c2802001103000240200428020c280204450d002004280208102e0b200441046a22052005280200417f6a220536020020050d002004102e0b200341d8006a41206a2204200041206a290200370300200341d8006a41186a2205200041186a290200370300200341d8006a41106a2206200041106a290200370300200341d8006a41086a2207200041086a29020037030020032000290200370358200128020041016a220041014d0d0120012000360200200341b0036a41206a2004290300370300200341b0036a41186a2005290300370300200341b0036a41106a2006290300370300200341b0036a41086a2007290300370300200320032903583703b003412c102c2200450d0020002001360200200020032903b0033702042000410c6a200341b8036a290300370200200041146a200341b0036a41106a2903003702002000411c6a200341c8036a290300370200200041246a200341d0036a2903003702004110102c2204450d00200441c0fec60036020c20042000360208200442818080801037020020012001280200417f6a2200360200024020000d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22002000280200417f6a220036020020000d002001102e0b200341d8006a200241b00210e9081a20034188036a411e6a22012003411e6a29010037010020034188036a41186a2200200341186a29030037030020034188036a41106a2202200341106a29030037030020034188036a41086a2205200341086a2903003703002003200329030037038803024002402004280208200341d8006a200428020c28020c1101000d0041022100200341c8006a41023a0000200341286a41186a41003a000020042004280200417f6a2201360200420021082003420037033020034201370328024020010d002004280208200428020c2802001103000240200428020c280204450d002004280208102e0b200441046a22012001280200417f6a220136020020010d002004102e0b200341d8006a10dc02410121010c010b200341b0036a200341d8006a41b00210e9081a200341ea056a2005290300370100200341f2056a2002290300370100200341fa056a2000290300370100200341e0056a41206a200129010037010020034180023b01e00520032003290388033701e2052003200436028806200341286a200341b0036a200341e0056a10dd0220032903284201512101200341286a41206a2d00002100200329033021080b2003200341d0006a2800003600b703200320032900493703b0030240024020010d00410621010c010b200320032800b70336005f200320032903b0033703584106210120084202510d002003200328005f3600b703200320032903583703b003200021010b200320032903b0033703e005200320032800b7033600e705200341b8036a20013a0000200341b9036a20032903e005370000200341c0036a20032800e705360000200341003a00b403200341133a00b003200320032f0088033b00b50320032003418a036a2d00003a00b703200341c4036a200341d8006a41d40010e9081a200341b0036a10fe0120034190066a24000f0b1036000b00000bb10201037f230041e0006b22022400200241086a4190fec6004105108102200241186a41a8dbc8004107108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000ba30b04047f017e0c7f037e230041d0016b220324002003200236021420032001360210200341186a2001200210ed0202400240200328021822040d00200041003602000c010b200328021c21052003200341206a28020036022c20032004360228200341086a200341286a10ab0102400240024020032802080d00024002400240200328020c2206200328022c41286e2201200120064b1bad42287e2207422088a70d002007a72201417f4c0d0002400240024020010d00410421080c010b2001102c2208450d010b200141286e2102024020060d00410021060c030b200341a8016a41017221094100210a4100210b0340200341a8016a200341286a1093010240024020032d00a8014101460d0020034188016a41186a220c200941186a29000037030020034188016a41106a220d200941106a29000037030020034188016a41086a220e200941086a2900003703002003200929000037038801200328022c2201450d002003280228220f2d0000211020032001417f6a221136022c2003200f41016a3602284100211202400240024002400240024020100e0705040001060203060b410221120c040b410321120c030b410521120c020b410621120c010b410121120b20114104490d00200341a8016a41086a200e290300370300200341a8016a41106a200d290300370300200341a8016a41186a200c29030037030020034182016a41026a20034185016a41026a2d00003a000020032003290388013703a801200f280001211320032001417b6a36022c2003200f41056a360228200320032f0085013b0182010c010b410721120b200341e0006a41186a2201200341a8016a41186a290300370300200341e0006a41106a220f200341a8016a41106a290300370300200341e0006a41086a220c200341a8016a41086a290300370300200341dc006a41026a220d20034182016a41026a2d00003a0000200320032903a801370360200320032f0182013b015c024020124107460d00200341386a41186a220e2001290300370300200341386a41106a2210200f290300370300200341386a41086a220f200c290300370300200341346a41026a220c200d2d00003a000020032003290360370338200320032f015c3b01340240200b2002470d00200241016a22012002490d042002410174220d2001200d20014b1b22014104200141044b1bad42287e2207422088a74541027421012007a7210d0240024020020d00200341003602a8010c010b200341043602b001200320083602a8012003200241286c3602ac010b20034188016a200d2001200341a8016a107d200328029001210102402003280288014101470d0020010d040c050b200328028c012108200141286e21020b2008200a6a22012013360200200e290300210720102903002114200f290300211520032903382116200141246a20123a0000200141046a20163702002001410c6a2015370200200141146a20143702002001411c6a2007370200200141256a20032f01343b0000200141276a200c2d00003a0000200a41286a210a2006200b41016a220b460d040c010b0b2002450d04200241286c450d040c030b1036000b1038000b2008450d01200328022c2201410f4b0d022002450d01200241286c450d010b2008102e0b200341003602900120034201370388012003410a3602642003200341106a360260200320034188016a360238200341bc016a4101360200200342013702ac01200341909dc5003602a8012003200341e0006a3602b801200341386a419cebc000200341a8016a103d1a20032802880120032802900110ef020240200328028c01450d00200328028801102e0b200041003602000c010b2000200236020420002008360200200041106a20032802282202290000370300200041086a2006360200200041186a200241086a2900003703002003200141706a36022c2003200241106a3602280b2005450d002004102e0b200341d0016a24000bd70201097f410121044100210502400240024020020e020201000b200341046a21062003280200210720032d002441ff017121084100210503400240024020012002410176220920056a220a41286c6a220b41046a2006412010ec08220c450d00417f4101200c4100481b210c0c010b4100417f200b2d0024220c200847200c2008491b200c2008461b220c0d00417f200b280200220c200747200c2007491b210c0b2005200a200c4101461b2105200220096b220241014b0d000b0b024002402001200541286c6a220c41046a200341046a412010ec082202450d00417f410120024100481b21020c010b02404100417f200c2d0024220220032d002422094720022009491b20022009461b22020d0041ff012102200c280200220c20032802002209490d01200c20094721020b20020d00410021040c010b2005200241ff017141ff01466a21050b20002005360204200020043602000baa0102037f017e230041206b2203240002400240200228020841286c41146a2204417f4c0d002004102c2205450d0120034100360208200320043602042003200536020020022802002002280208200310d802200229031021062003200241186a290300370318200320063703102003200341106a411010742000200120032802002202200328020810b20102402003280204450d002002102e0b200341206a24000f0b1038000b1036000bc40201027f230041106b220224000240411a102c2203450d002002421a37020420022003360200200220012802004110107420022001280204412010742002200128020836020c20022002410c6a410410742002200128020c36020c20022002410c6a41041074024002400240024002400240024020012802102d00000e0700010203060405060b200241003a000c20022002410c6a410110740c050b200241013a000c20022002410c6a410110740c040b200241023a000c20022002410c6a410110740c030b200241033a000c20022002410c6a410110740c020b200241053a000c20022002410c6a410110740c010b200241063a000c20022002410c6a410110740b200220012f01143b010c20022002410c6a41021074200020022802002201200228020810b00102402002280204450d002001102e0b200241106a24000f0b1036000bf90101017f230041106b2203240020012002107602402001450d00200141286c210103402002200041046a412010740240024002400240024002400240200041246a2d00000e0700010203060405060b200341003a000b20022003410b6a410110740c050b200341013a000c20022003410c6a410110740c040b200341023a000d20022003410d6a410110740c030b200341033a000e20022003410e6a410110740c020b200341053a000f20022003410f6a410110740c010b200341063a00032002200341036a410110740b200320002802003602042002200341046a41041074200041286a2100200141586a22010d000b0b200341106a24000bb10201037f230041e0006b22022400200241086a4190fec6004105108102200241186a41afdbc800410d108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000bb10d03047f017e0d7f23004190036b220324002003200236020c20032001360208200341106a2001200210ed020240024002400240200328021022040d00200041003602000c010b200328021421052003200341186a280200360224200320043602202003200341206a10ab0102400240024020032802000d0020032802042206200328022441c4006e2201200120064b1bad42c4007e2207422088a70d052007a72201417f4c0d050240024020010d00410421080c010b2001102c2208450d050b200141c4006e210902400240024020060d00410021060c010b200341a8026a410172210a4100210b0340200341a8026a200341206a10930102400240024020032d00a8024101460d00200b41016a210c200341e8016a41186a220d200a41186a290000370300200341e8016a41106a220e200a41106a290000370300200341e8016a41086a220f200a41086a2900003703002003200a2900003703e80141002101200341003a00c802417f2102200328022421100240034020102001460d01200341a8026a20016a200328022022112d00003a00002003201020026a3602242003201141016a3602202003200141016a22123a00c8022002417f6a21022012210120124120470d000b200341f0026a41186a2201200341a8026a41186a290300370300200341f0026a41106a2202200341a8026a41106a290300370300200341f0026a41086a2213200341a8026a41086a290300370300200320032903a8023703f002201241ff01714120490d0120034188026a41086a2214201329030037030020034188026a41106a2213200229030037030020034188026a41186a22022001290300370300200320032903f00237038802201020126b22014104490d01200341c8016a41086a2212200f290300370300200341c8016a41106a2210200e290300370300200341c8016a41186a220e200d290300370300200341a8016a41086a220d2014290300370300200341a8016a41106a220f2013290300370300200341a8016a41186a22132002290300370300200320032903e8013703c80120032003290388023703a801201128000121022003201141056a36022020032001417c6a36022420034188016a41086a2201201229030037030020034188016a41106a2212201029030037030020034188016a41186a2210200e290300370300200341e8006a41086a2211200d290300370300200341e8006a41106a220d200f290300370300200341e8006a41186a220e2013290300370300200320032903c80137038801200320032903a801370368200341c8006a41186a220f2010290300370300200341c8006a41106a22102012290300370300200341c8006a41086a22122001290300370300200341286a41186a2213200e290300370300200341286a41106a220e200d290300370300200341286a41086a220d2011290300370300200320032903880137034820032003290368370328200b2009470d03200941016a220120094f0d020c0c0b200141ff0171450d00200341003a00c8020b2009450d05200941c4006c0d040c050b200941017422112001201120014b1b22014104200141044b1bad42c4007e2207422088a74541027421012007a721110240024020090d00200341003602a8020c010b200341043602b002200320083602a8022003200941c4006c3602ac020b200341f0026a20112001200341a8026a107d20032802f8022101024020032802f0024101470d002001450d0a0c090b20032802f4022108200141c4006e21090b2008200b41c4006c6a22012002360200200120032903483702042001410c6a2012290300370200200141146a20102903003702002001411c6a200f290300370200200120032903283702242001412c6a200d290300370200200141346a200e2903003702002001413c6a2013290300370200200c210b200c2006470d000b0b2008450d0120032802242201410f4b0d022009450d01200941c4006c450d010b2008102e0b200341003602f802200342013703f0022003410a3602d4022003200341086a3602d0022003200341f0026a36028802200341bc026a4101360200200342013702ac02200341909dc5003602a8022003200341d0026a3602b80220034188026a419cebc000200341a8026a103d1a20032802f00220032802f80210ef02024020032802f402450d0020032802f002102e0b200041003602000c010b2000200936020420002008360200200041106a20032802202202290000370300200041086a2006360200200041186a200241086a2900003703002003200141706a3602242003200241106a3602200b2005450d002004102e0b20034190036a24000f0b1036000b1038000bc10102047f017e230041206b22032400024002402002280208220441c4006c41146a2205417f4c0d000240024020050d00410121060c010b2005102c2206450d02200228020821040b200341003602082003200536020420032006360200200228020020042003109505200229031021072003200241186a290300370318200320073703102003200341106a411010742000200120032802002202200328020810b20102402003280204450d002002102e0b200341206a24000f0b1038000b1036000b802401047f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002802000e1b00010218180304051806070818090a0b0c0d0e0f10111213141516170b0240024002400240024002400240200041086a2802000e0a1e1e001e01021e030405060b200041106a280200450d1d2000410c6a280200102e0f0b200041106a280200450d1c2000410c6a280200102e0f0b200041106a280200450d1b2000410c6a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141186c210103400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200141686a22010d000b0b200041106a2802002202450d1a200241186c450d1a200028020c102e0f0b0240200041146a2802002201450d002000410c6a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041106a2802002202450d192002410c6c450d19200028020c102e0f0b200041106a280200450d182000410c6a280200102e0f0b200041106a280200450d172000410c6a280200102e0f0b0240024002400240024020002d00040e061b001b010203040b200041186a220228020010dc022002280200102e0f0b02402000410c6a280200450d00200041086a280200102e0b200041246a220228020010dc022002280200102e0f0b2000410c6a280200450d18200041086a280200102e0f0b200041186a220228020010dc022002280200102e0f0b02402000410c6a280200450d00200041086a280200102e0b200041246a220228020010dc022002280200102e0f0b02400240200041086a280200417f6a0e020001170b2000412c6a220110e1010240200041306a2802002202450d00200241246c450d002001280200102e0b2000419c016a220110e1010240200041a0016a2802002202450d00200241246c450d002001280200102e0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d162002410c6c450d162000280210102e0f0b2000412c6a220110e1010240200041306a2802002202450d00200241246c450d002001280200102e0b2000419c016a220110e1010240200041a0016a2802002202450d00200241246c450d002001280200102e0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d152002410c6c450d152000280210102e0f0b0240024002400240200041086a2802000e0418000102030b2000410c6a2d00004102470d17200041146a280200450d17200041106a280200102e0f0b2000410c6a2d00004102470d16200041146a280200450d16200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004102470d15200041386a280200450d15200041346a280200102e0f0b2000410c6a2d00004102470d14200041146a280200450d14200041106a280200102e0f0b02402000410c6a2802002201450d0020002802042202200141f0006c6a21030340024020022204410c6a2802002201450d0020042802042102200141246c210103400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200441f0006a21020240200441086a2802002201450d00200141246c450d002004280204102e0b20022003470d000b0b200041086a2802002202450d13200241f0006c450d132000280204102e0f0b024002400240024002400240200041086a2d00000e171800181818180118180218181818180318180418181818050b2000412c6a2d00004102470d17200041346a280200450d17200041306a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141246c21010340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200041106a2802002202450d16200241246c450d16200028020c102e0f0b2000410c6a2d00004102470d15200041146a280200450d15200041106a280200102e0f0b200041106a28020041ffffff3f71450d142000410c6a280200102e0f0b200041146a28020041ffffffff0371450d13200041106a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141246c21010340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200041106a2802002202450d12200241246c450d12200028020c102e0f0b20002802042202450d11200041086a280200450d112002102e0f0b02400240200041086a280200417f6a0e020001120b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d112002410c6c450d112000280210102e0f0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d102002410c6c450d102000280210102e0f0b02402000410c6a280200450d00200041086a280200102e0b02402000411c6a2802002201450d00200041146a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041186a2802002202450d0f2002410c6c450d0f2000280214102e0f0b0240024002400240200041086a2d000041716a0e0400010203120b200041106a280200450d112000410c6a280200102e0f0b200041106a280200450d102000410c6a280200102e0f0b200041106a280200450d0f2000410c6a280200102e0f0b200041106a280200450d0e2000410c6a280200102e0f0b024002400240200041086a2d0000417f6a0e03000102100b200041306a28020041ffffff3f71450d0f2000412c6a280200102e0f0b2000410c6a220228020010dc022002280200102e0f0b200041106a220228020010dc022002280200102e0f0b024002400240200041086a2d0000417f6a0e030001020f0b200041306a28020041ffffff3f71450d0e2000412c6a280200102e0f0b2000410c6a220228020010dc022002280200102e0f0b200041106a220228020010dc022002280200102e0f0b02400240200041086a2d0000417f6a0e05000d0d0d010d0b200041106a28020041ffffff3f71450d0c2000410c6a280200102e0f0b2000410c6a2d00004102470d0b200041146a280200450d0b200041106a280200102e0f0b20002d00044104470d0a2000410c6a28020041ffffff3f71450d0a200041086a280200102e0f0b200041086a2802004101470d092000410c6a2d00004102470d09200041146a280200450d09200041106a280200102e0f0b02400240200041086a2d0000417d6a0e0200010a0b200041f0006a280200450d09200041ec006a280200102e0f0b200041106a280200450d082000410c6a280200102e0f0b024002400240200041086a2802000e040a0a0001020b2000410c6a2d00004102470d09200041146a280200450d09200041106a280200102e0f0b2000410c6a2d00004102470d08200041146a280200450d08200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004102470d07200041386a280200450d07200041346a280200102e0f0b02400240024020002f01040e03090001020b0240200041106a2802002201450d00200041086a2802002102200141b0026c210103402002109601200241b0026a2102200141d07d6a22010d000b0b2000410c6a2802002202450d08200241b0026c450d082000280208102e0f0b200041086a220228020010dc022002280200102e0f0b0240200041106a2802002201450d00200041086a2802002102200141b0026c210103402002109601200241b0026a2102200141d07d6a22010d000b0b2000410c6a2802002202450d06200241b0026c450d062000280208102e0f0b0240024002400240024002400240200041086a2d0000417e6a0e0d00010c0c0c0c0c0c02030405060c0b0240200041146a2802002201450d002000410c6a2802002202200141c8006c6a21010340024020022d00004101470d00200241086a280200450d00200241046a280200102e0b0240200241246a2d00004101470d002002412c6a280200450d00200241286a280200102e0b200241c8006a22022001470d000b0b0240200041106a2802002202450d00200241c8006c450d00200028020c102e0b0240200041186a2d00004101470d00200041206a280200450d002000411c6a280200102e0b02402000413c6a2d00004101470d00200041c4006a280200450d00200041c0006a280200102e0b0240200041e0006a2d00004101470d00200041e8006a280200450d00200041e4006a280200102e0b024020004184016a2d00004101470d002000418c016a280200450d0020004188016a280200102e0b0240200041a8016a2d00004101470d00200041b0016a280200450d00200041ac016a280200102e0b0240200041cc016a2d00004101470d00200041d4016a280200450d00200041d0016a280200102e0b200041f0016a2d00004101470d0b200041f8016a280200450d0b200041f4016a280200102e0f0b0240200041146a2802002202450d00200241c4006c21012000410c6a28020041286a210203400240200241786a2d00004101470d002002280200450d002002417c6a280200102e0b200241c4006a2102200141bc7f6a22010d000b0b200041106a2802002202450d0a200241c4006c450d0a200028020c102e0f0b200041106a2d00004102470d09200041186a280200450d09200041146a280200102e0f0b2000410c6a2d00004102470d08200041146a280200450d08200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004101470d07200041386a280200450d07200041346a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004101470d06200041386a280200450d06200041346a280200102e0f0b2000410c6a2d00004102470d05200041146a280200450d05200041106a280200102e0f0b20002d00042202417e6a4108490d040240024020020e020600010b200041286a220228020010dc022002280200102e0f0b200041c8006a220228020010dc022002280200102e0f0b0240024002400240200041086a2d00000e0407000102030b0240200041106a28020041ffffff3f71450d002000410c6a280200102e0b200041186a220228020010dc022002280200102e0f0b0240200041106a28020041ffffff3f71450d002000410c6a280200102e0b200041286a280200450d05200041246a280200102e0f0b200041306a28020041ffffff3f71450d042000412c6a280200102e0f0b200041306a28020041ffffff3f71450d032000412c6a280200102e0f0b0240024002400240200041086a2802000e09060006010606020606030b200041106a280200450d052000410c6a280200102e0f0b200041106a2d00004102470d04200041186a280200450d04200041146a280200102e0f0b200041106a2d00004102470d03200041186a280200450d03200041146a280200102e0f0b200041146a280200450d02200041106a280200102e0f0b02400240200041086a2d0000417f6a0e03000301030b200041306a280200450d022000412c6a280200102e0c020b200041306a280200450d012000412c6a280200102e0f0b200041386a109b060f0b0be5890505077f077e147f0b7e037f230041f0176b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c0203040506070809010a0b0c010d0e0f10363534333231302f2e2d00020b20014184026a280200210420014180026a280200210520022d0001210620022d000021072002280228210220034190136a200141086a41f80110e9081a20022002280200417f6a2201360200024002400240024020070d00024020010d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b200641ff01714102470d01200341e9003602d408200341fee7c7003602d008200341e0106a20034190136a10b80620032d00e0104106470d2f200341c0066a22014200370300200341a8066a41106a22024200370300200341a8066a41086a22074200370300200342003703a806200341e8056a41a5fec600411a1081022007200341e8056a41086a290300370300200320032903e8053703a806200341a8046a41ccc5c80041101081022001200341a8046a41086a290300370300200220032903a804370300200341203602b40a2003200341a8066a3602b00a200341b00e6a200341a8066a412010ed0220032802b00e22070d02410021060c030b20010d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b200341c0136a109b06200320032800f0063602e8062003200341f3066a2800003600eb06200041186a41003a000020004200370308200020032802e8063600192000411c6a20032800eb06360000200041206a41023a0000200042013703000c640b20032802b40e21082003200341b00e6a41086a2802003602840c200320073602800c200341a0046a200341800c6a10ab0102400240024020032802a0040d0020032802a404210120034198046a200341800c6a10ab01200328029804450d010b41002106200341003602e810200342013703e0102003410a3602ac042003200341b00a6a3602a8042003200341e0106a3602e805200341d4156a4101360200200342013702c415200341909dc5003602c0152003200341a8046a3602d015200341e8056a419cebc000200341c0156a103d1a20032802e01020032802e81010ef02024020032802e410450d0020032802e010102e0b0c010b200328029c042109410121060b2008450d002007102e0b2006450d2a20012005470d2920092004470d28200341c0156a20034190136a41f80110e9081a200341e0106a200341c0156a10b90620032802e0104101460d12200341b00e6a41386a2201200341a0116a290300370300200341b00e6a41306a200341e0106a41386a290300220a370300200341b00e6a41286a200341e0106a41306a290300220b370300200341b00e6a41206a200341e0106a41286a290300220c370300200341b00e6a41186a200341e0106a41206a290300220d370300200341b00e6a41106a200341e0106a41186a290300220e370300200341b00e6a41086a200341e0106a41106a290300220f3703002003200341e0106a41086a29030022103703b00e200341c0156a41306a2207200a370300200341c0156a41286a200b370300200341c0156a41206a200c370300200341c0156a41186a200d370300200341c0156a41106a200e370300200341c0156a41086a200f370300200341c0156a41386a2001290300370300200320103703c015200341a8066a41186a4200370300200341a8066a41106a4200370300200341a8066a41086a22014200370300200342003703a806200341e8056a41a5fec600411a1081022001200341e8056a41086a290300370300200320032903e8053703a806200341a8046a4184c4c800410e108102200241086a200341a8046a41086a290300370300200220032903a804370300200341003602e810200342013703e0102007200341e0106a10b901200341e0106a200341c0156a41301074024002400240024020032d00fc150e03000102030b200341003a00a804200341e0106a200341a8046a410110740c020b200341013a00a804200341e0106a200341a8046a410110740c010b200341023a00a804200341e0106a200341a8046a410110740b200341a8066a412020032802e010220220032802e81010b201024020032802e410450d002002102e0b20032802f01521060240200341f8156a2802002202450d0020024106742101200641346a21020340024020022802002207450d00200741306c450d002002417c6a280200102e0b200241c0006a2102200141406a22010d000b0b0240200341f4156a28020041ffffff1f71450d002006102e0b20034180043b01c415200341173a00c015200341c0156a10fe01200320032800f0063602e8062003200341f3066a2800003600eb06200041186a41003a000020004200370308200020032802e8063600192000411c6a20032800eb06360000200042003703000c620b000b2001410c6a2802002108200141106a290300210a200141086a280200210120034190136a41286a2207200241286a28020036020020034190136a41206a2206200241206a29020037030020034190136a41186a2204200241186a29020037030020034190136a41106a2205200241106a29020037030020034190136a41086a2209200241086a2902003703002003200229020037039013200aa72111200a422088a7211202400240024002400240024002400240024002402001417f6a0e0a00010203040506070809000b200341c0156a41286a2007280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c0150240200341c0156a10a705450d00200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200041206a41023a0000200042013703000c6a0b200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200042003703000c690b200341c0156a41286a2007280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c015200341e0106a200341c0156a10c102024020032d00e0104101470d0002402011450d002008102e0b200320032800b00e3602800c2003200341b30e6a2800003600830c200041186a41003a000020004200370308200020032802800c3600192000411c6a20032800830c360000200041206a41023a0000200042013703000c690b02402011450d002008102e0b200320032800b00e3602800c2003200341b30e6a2800003600830c200041186a41003a000020004200370308200020032802800c3600192000411c6a20032800830c360000200042003703000c680b200341c0156a41286a2007280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c0150240200341c0156a10a705450d00200320032800b00e3602800c2003200341b30e6a2800003600830c200041186a41003a000020004200370308200020032802800c3600192000411c6a20032800830c360000200041206a41023a0000200042013703000c680b4108102c2202450d64200342083702c415200320023602c0152003200a3703e010200341c0156a200341e0106a4108107441dcc1cb00410a20032802c015220220032802c81510b201024020032802c415450d002002102e0b200320032800b00e3602800c2003200341b30e6a2800003600830c200041186a41003a000020004200370308200020032802800c3600192000411c6a20032800830c360000200042003703000c670b200341c0156a41286a2007280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c0150240200341c0156a10a705450d00410221060c660b200341b00e6a2008201210ba0620032802b00e2202450d6420032802b40e21012003200341b80e6a2802003602840c200320023602800c200341106a200341800c6a10ab010240024020032802100d0020032802840c220720032802142206490d002006417f4c0d510240024020060d00410121040c010b200610322204450d6620032802840c21070b024020072006490d00200420032802800c200610e908210920032802840c22072006490d182003200720066b3602840c200320032802800c20066a3602800c200341086a200341800c6a10ab01024020032802080d0020032802840c2207200328020c2205490d002005417f4c0d530240024020050d00410121130c010b200510322213450d6820032802840c21070b024020072005490d00201320032802800c200510e908211420032802840c22072005490d192003200720056b22073602840c200320032802800c20056a22153602800c024020074104490d002003201541046a3602800c20032007417c6a22163602840c20164104490d00201528000421172003201541086a3602800c2003200741786a22163602840c20164104490d002003200741746a3602840c20032015410c6a3602800c2003200341800c6a10ab0120032802000d002003280204221520032802840c410c6e2207200720154b1bad420c7e220a422088a70d55200aa72207417f4c0d550240024020070d00410421160c010b2007102c2216450d6a0b2007410c6ead210a02400240024002402015450d000340200341c0156a200341800c6a10a50120032d00c0154101460d0320032802840c22074104490d0320032900c115210b20032802800c2218280000211920032007417c6a3602840c2003201841046a3602800c0240200a422088a72207200aa7470d00200741016a22182007490d5b2007410174221a20182018201a491b22184104201841044b1bad420c7e220c422088a7454102742118200ca7211a0240024020070d00200341003602c0150c010b200341043602c815200320163602c01520032007410c6c3602c4150b200341e0106a201a2018200341c0156a107d20032802e810211820032802e0104101460d0320032802e4102116200a428080808070832018410c6ead84210a0b20162007410c6c6a220720193602082007200b370200200a4280808080107c210a2015417f6a22150d000b0b2016450d03200aa7211520032802840c41034b0d082015450d032015410c6c0d020c030b2018450d570c6b0b200aa72207450d012007410c6c450d010b2016102e0b2005450d010b2013102e0b2006450d010b2004102e0b2001450d652002102e0c650b02402001450d002002102e0b02400240024020064108470d000240200929000042f0deb1db968cd9b7f400510d00410021074180c2cb002101410f21020c020b02402017411f4f0d004101210741e6c1cb002101411a21020c020b2009102e02402005450d002014102e0b02402015450d002015410c6c450d002016102e0b41acc2cb0041052008201210b201200341c8156a41023a0000200341003a00c015200341c0156a10fe0102402011450d002008102e0b200320032800b00a3602d0082003200341b30a6a2800003600d308200041186a41003a000020004200370308200020032802d0083600192000411c6a20032800d308360000200042003703000c690b410021074180c2cb002101410f21022006450d010b2009102e0b02402005450d002014102e0b410321062015450d652015410c6c450d652016102e0c650b200341c0156a41286a2007280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c0150240200341c0156a10a705450d0002402011450d002008102e0b200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200041206a41023a0000200042013703000c660b41acc2cb0041052008201210b201200341c8156a41023a0000200341003a00c015200341c0156a10fe0102402011450d002008102e0b200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200042003703000c650b200341c0156a41286a2007280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c015200341c0156a10a7050d290240024020084101460d0041b1c2cb00410d10ff010c010b200341003602c815200342013703c015200320113602800c200341c0156a200341800c6a41041074200320123602800c200341c0156a200341800c6a4104107441b1c2cb00410d20032802c015220220032802c81510b20120032802c415450d002002102e0b200341cc156a2012360200200341c8156a2011360200200320083602c415200341043a00c015200341c0156a10a504200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200042003703000c640b200341c0156a41286a2007280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c0150240200341c0156a10a7050d0002402012450d002008201241186c6a21012008210203402002280200200241086a2802002002410c6a280200200241146a28020010b201200241186a22022001470d000b2012450d00201241186c21012008210203400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200141686a22010d000b0b02402011450d00201141186c450d002008102e0b200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200042003703000c640b02402012450d00201241186c21012008210203400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200141686a22010d000b0b02402011450d00201141186c450d002008102e0b200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200041206a41023a0000200042013703000c630b200341c0156a41286a2007280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c0150240200341c0156a10a7050d0002402012450d0020082012410c6c6a21012008210203402002280200200241086a28020010ff012002410c6a22022001470d000b2012450d002012410c6c21012008210203400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b02402011450d002011410c6c450d002008102e0b200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200042003703000c630b02402012450d002012410c6c21012008210203400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b02402011450d002011410c6c450d002008102e0b200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200041206a41023a0000200042013703000c620b200341c0156a41286a2007280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c0150240200341c0156a10a705450d0002402011450d002008102e0b200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200041206a41023a0000200042013703000c620b2008201210890302402011450d002008102e0b200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200042003703000c610b200341c0156a41286a2007280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c015200341e0106a200341c0156a10c102200341c8066a41086a200341e0106a41096a290000370300200341c8066a41106a200341e0106a41116a290000370300200341c8066a41186a200341e0106a41196a290000370300200320032900e1103703c806024020032d00e0104101470d0002402011450d002008102e0b200320032800ab043600f30b200320032802a8043602f00b200041186a41003a000020004200370308200020032802f00b3600192000411c6a20032800f30b360000200041206a41023a0000200042013703000c610b200341900a6a41186a2202200341c8066a41186a290300370300200341900a6a41106a2201200341c8066a41106a290300370300200341900a6a41086a2207200341c8066a41086a290300370300200320032903c8063703900a200341a8066a2008201210b001200341e0106a41186a2206200341a8066a41186a290300370300200341e0106a41106a2204200341a8066a41106a290300370300200341e0106a41086a2205200341a8066a41086a290300370300200320032903a8063703e010200341c0156a41086a41053a0000200341c0156a41096a20032903900a370000200341c0156a41116a2007290300370000200341c0156a41196a2001290300370000200341e1156a2002290300370000200341e9156a20032903e010370000200341f1156a2005290300370000200341f9156a200429030037000020034181166a2006290300370000200341003a00c015200341c0156a10fe0102402011450d002008102e0b200320032800ab043600f30b200320032802a8043602f00b200041186a41003a000020004200370308200020032802f00b3600192000411c6a20032800f30b360000200042003703000c600b20034190136a41206a200141246a28020036020020034190136a41186a2001411c6a29020037030020034190136a41106a200141146a29020037030020034190136a41086a2001410c6a2902003703002003200129020437039013200341c0156a41286a200241286a280200360200200341c0156a41206a200241206a290200370300200341c0156a41186a200241186a290200370300200341c0156a41106a200241106a290200370300200341c0156a41086a200241086a290200370300200320022902003703c015200020034190136a200341c0156a10d5040c5f0b200141346a2802002115200141306a28020021122001412c6a2802002118200141286a2802002117200141206a290200210a2001411c6a280200211a200141186a2802002106200141146a2802002107200141106a28020021162001410c6a280200211b200141086a2802002104200341800c6a200141386a41e40010e9081a200141a4016a2802002114200141a0016a28020021132001419c016a2802002119200341e0106a200141a8016a41800110e9081a200341d0086a41286a2201200241286a280200360200200341d0086a41206a2205200241206a290200370300200341d0086a41186a2209200241186a290200370300200341d0086a41106a2208200241106a290200370300200341d0086a41086a2211200241086a290200370300200320022902003703d008024002400240024020040e0400010203000b200341c0156a41146a4101360200200342013702c4152003419cc3cb003602c015200341043602ac04200341a4a7c7003602a8042003200341a8046a3602d015200341c0156a4190afc4001044000b200341b00e6a200341800c6a41e40010e9081a20034190136a200341e0106a41800110e9081a200341c0156a41286a2001280200360200200341c0156a41206a2005290300370300200341c0156a41186a2009290300370300200341c0156a41106a2008290300370300200341c0156a41086a2011290300370300200320032903d0083703c015200341f0066a200341c0156a10c102200341a8066a41086a200341f9066a2202290000370300200341a8066a41106a20034181076a2201290000370300200341a8066a41186a20034189076a2204290000370300200320032900f1063703a80602400240024020032d00f0064101470d00200341d00a6a41023a0000200341c80a6a41003a0000200342003703b80a200342013703b00a02402006450d002006410c6c21012016210203400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b02402007450d002007410c6c450d002016102e0b02402015450d00201541246c21012018210203400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b02402012450d00201241246c450d002018102e0b02402014450d00201441246c21012019210203400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b02402013450d00201341246c450d002019102e0b200341b80a6a210241002106410221040c010b200341c8066a41186a200341a8066a41186a290300220b370300200341c8066a41106a200341a8066a41106a290300220c370300200341c8066a41086a200341a8066a41086a290300220d370300200320032903a806220e3703c8062004200b3700002001200c3700002002200d3700002003200e3700f106200341013a00f006200341d4156a2015360200200341c0156a41106a2012360200200341c0156a410c6a2018360200200320173602c8152003200a3703c015200341c0156a41186a200341b00e6a41e40010e9081a200341c4166a2014360200200341c0156a4180016a2013360200200341bc166a2019360200200341c8166a20034190136a41800110e9081a200341a8046a410c6a2006360200200341a8046a41086a20073602002003201a3602b804200320163602ac042003201b3602a804200341b00a6a200341f0066a200341c0156a200341a8046a10990420032903b00a4201520d01200341b00a6a41086a2102200341d00a6a2d0000210420032d00c80a21060b200320022800113602b0082003200241146a2800003600b30820022f0019210120022d001b2107200229001c210a2002280224210220032903b80a210b20032903c00a210c200041186a20063a0000200041106a200c3703002000200b370308200020032802b0083600192000411c6a20032800b3083600002000412c6a20023602002000200a370024200020073a0023200020013b0021200041206a20043a0000200042013703000c610b200320032800c90a3602b0082003200341b00a6a411c6a2800003600b30820032903b80a210a20032903c00a210b200041186a20032d00c80a3a0000200041106a200b3703002000200a370308200020032802b0083600192000411c6a20032800b308360000200042003703000c600b200341b00e6a200341800c6a41e40010e9081a20034190136a200341e0106a41800110e9081a200341c0156a41286a2001280200360200200341c0156a41206a2005290300370300200341c0156a41186a2009290300370300200341c0156a41106a2008290300370300200341c0156a41086a2011290300370300200320032903d0083703c015024002400240200341c0156a10bb06450d00200341d00a6a41023a0000200341c80a6a41003a0000200342003703b80a200342013703b00a02402006450d002006410c6c21012016210203400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b02402007450d002007410c6c450d002016102e0b02402015450d00201541246c21012018210203400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b02402012450d00201241246c450d002018102e0b02402014450d00201441246c21012019210203400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b02402013450d00201341246c450d002019102e0b200341b80a6a210241002106410221040c010b200341c0156a10e20420034189076a200341c0156a41186a220229030037000020034181076a200341c0156a41106a2201290300370000200341f9066a200341c0156a41086a290300370000200341013a00f006200320032903c0153700f106200341d4156a201536020020012012360200200341c0156a410c6a2018360200200320173602c8152003200a3703c0152002200341b00e6a41e40010e9081a200341c4166a2014360200200341c0156a4180016a2013360200200341bc166a2019360200200341c8166a20034190136a41800110e9081a200341a8046a410c6a2006360200200341a8046a41086a20073602002003201a3602b804200320163602ac042003201b3602a804200341b00a6a200341f0066a200341c0156a200341a8046a10990420032903b00a4201520d01200341b00a6a41086a2102200341d00a6a2d0000210420032d00c80a21060b200320022800113602e8052003200241146a2800003600eb0520022f0019210120022d001b2107200229001c210a2002280224210220032903b80a210b20032903c00a210c200041186a20063a0000200041106a200c3703002000200b370308200020032802e8053600192000411c6a20032800eb053600002000412c6a20023602002000200a370024200020073a0023200020013b0021200041206a20043a0000200042013703000c600b200320032800c90a3602e8052003200341b00a6a411c6a2800003600eb0520032903b80a210a20032903c00a210b200041186a20032d00c80a3a0000200041106a200b3703002000200a370308200020032802e8053600192000411c6a20032800eb05360000200042003703000c5f0b200341c0156a41286a2001280200360200200341c0156a41206a2005290300370300200341c0156a41186a2009290300370300200341c0156a41106a2008290300370300200341c0156a41086a2011290300370300200320032903d0083703c0150240200341c0156a10a705450d00200320032800f3063600eb06200320032802f0063602e806200041186a41003a000020004200370308200020032802e8063600192000411c6a20032800eb06360000200041206a41023a0000200042013703000c5f0b2003200a3703d0152003201a3602cc15200320063602c815200320073602c415200320163602c015200341c0156a10ed04200320032802f0063602e806200320032800f3063600eb06200041186a41003a000020004200370308200020032802e8063600192000411c6a20032800eb06360000200042003703000c5e0b200141086a290300210a200341c0156a41286a200241286a280200360200200341c0156a41206a200241206a290200370300200341c0156a41186a200241186a290200370300200341c0156a41106a200241106a290200370300200341c0156a41086a200241086a290200370300200320022902003703c01502400240200341c0156a10bb060d00200341a8066a41186a22024200370300200341a8066a41106a22014200370300200341a8066a41086a22074200370300200342003703a806200341e8056a41e8fcc60041091081022007200341e8056a41086a290300370300200320032903e8053703a806200341a8046a41d48ec90041091081022002200341a8046a41086a290300370300200120032903a804370300200341a8066a4120108f020d23200341c0066a22074200370300200341b8066a22064200370300200341a8066a41086a22024200370300200342003703a806200341e8056a41e8fcc60041091081022002200341e8056a41086a2204290300370300200320032903e8053703a806200341a8046a41b08ec9004103108102200141086a2205200341a8046a41086a2209290300370300200120032903a804370300200341286a200341a8066a1085032003280228450d012003290330220b500d01200b42b8177c200a580d0141f4d6c80041ce0041c4d7c8001039000b200320032800f3063600eb06200320032802f0063602e806200041186a41003a000020004200370308200020032802e8063600192000411c6a20032800eb06360000200041206a41023a0000200042013703000c5e0b200742003703002006420037030020024200370300200342003703a806200341e8056a41e8fcc600410910810220022004290300370300200320032903e8053703a806200341a8046a41b08ec900410310810220052009290300370300200120032903a8043703002003200a3703c015200341a8066a4120200341c0156a410810b201200742003703002006420037030020024200370300200342003703a806200341e8056a41e8fcc600410910810220022004290300370300200320032903e8053703a806200341a8046a41d48ec900410910810220052009290300370300200120032903a804370300200341013a00a804200341a8066a4120200341a8046a410110b201200742003703002006420037030020024200370300200342003703a806200341e8056a41a8f8c600410410810220022004290300370300200320032903e8053703a806200341a8046a41c98bc500410b10810220052009290300370300200120032903a804370300200341186a200341a8066a1085032003290320420020032802181b200a42f02e80520d20200320032800f3063600eb06200320032802f0063602e806200041186a41003a000020004200370308200020032802e8063600192000411c6a20032800eb06360000200042003703000c5d0b200341f0066a41086a22082001411d6a290000370300200320012900153703f0062001410d6a290000210b200141286a2802002111200141056a290000210a20012d0004210720012d0025211220034190136a41286a2201200241286a28020036020020034190136a41206a2206200241206a29020037030020034190136a41186a2204200241186a29020037030020034190136a41106a2205200241106a29020037030020034190136a41086a2209200241086a2902003703002003200229020037039013200a421888a7210202400240024002400240024020070e06000102030405000b200341d4156a4101360200200342013702c4152003419cc3cb003602c015200341043602ac0420034194c3cb003602a8042003200341a8046a3602d015200341c0156a41e89bc4001044000b200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c015200341e0106a200341c0156a10c102200341900a6a41086a200341e9106a290000370300200341900a6a41106a200341f1106a290000370300200341900a6a41186a200341f9106a290000370300200320032900e1103703900a02400240024020032d00e0104101460d00200341b00e6a41186a200341900a6a41186a290300370300200341b00e6a41106a200341900a6a41106a290300370300200341b00e6a41086a200341900a6a41086a290300370300200320032903900a3703b00e200341800c6a200210ff03200341c0156a20032802800c220420032802880c220610b205200341a8066a41086a2205200341c0156a41186a290300370300200341a8066a41106a2209200341e0156a290300370300200341a8066a41186a2208200341e8156a290300370300200320032903d0153703a806200320032800f1153602a8042003200341f4156a2800003600ab04200341c0156a41086a290300210a20032903c015210b024020032d00f015220741024622010d00200341c8066a41186a2008290300370300200341c8066a41106a2009290300370300200341c8066a41086a2005290300370300200320032903a8063703c806200320032802a8043602f00b200320032800ab043600f30b0b0240024020010d00200341e0106a410310bc060c010b200341c8066a41186a200341b00e6a41186a290300370300200341c8066a41106a200341b00e6a41106a290300370300200341c8066a41086a200341b00e6a41086a290300370300200320032903b00e3703c8064200210a4280d0dbc3f402210b200341e0106a200341b00e6a4280d0dbc3f402420010c302410021070b20032d00e01022014106470d01200341f4156a20032800f30b360000200341c0156a41186a200341c8066a41086a290300370300200341e0156a200341c8066a41106a290300370300200341e8156a2201200341c8066a41186a2903003703002003200b3703c015200320032903c8063703d015200320073a00f015200320032802f00b3600f1152003200a3703c81520042006200341c0156a10c605024020032802840c450d002004102e0b20012002360200200341cd156a200341b00e6a41086a290300370000200341d5156a200341b00e6a41106a290300370000200341dd156a200341b00e6a41186a290300370000200341003a00c415200341023a00c015200320032903b00e3700c515200341c0156a10fe01200041186a41003a000020004200370308200020032800e8053600192000411c6a200341eb056a280000360000200042003703000c630b410221010c010b20032902e410210a20032d00e310210620032d00e210210720032d00e110210220032802840c450d002004102e0b2000200a370024200020063a0023200020073a0022200020023a002120004200370308200041206a20013a0000200041186a41003a0000200042013703000c600b200341800c6a41186a20082903003703002003200b3703880c2003200a3703800c200320032903f0063703900c200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c015200341e0106a200341c0156a10c102200341a8066a41086a200341e9106a290000370300200341a8066a41106a200341f1106a290000370300200341a8066a41186a200341f9106a290000370300200320032900e1103703a80620032d00e0104101460d21200341b00e6a41186a200341a8066a41186a290300370300200341b00e6a41106a200341a8066a41106a290300370300200341b00e6a41086a200341a8066a41086a290300370300200320032903a8063703b00e0240200341b00e6a200341800c6a412010ec08450d00200341900a6a201110ff03200341c0156a20032802900a220120032802980a220710b205200341b00a6a41086a200341e8156a290300370300200320032903e0153703b00a200320032800f1153602a8042003200341f4156a2800003600ab04200341c0156a41186a290300210a20032903d015210b20032903c815210c20032903c015210d024020032d00f015220641024622020d00200341d0086a41086a200341b00a6a41086a290300370300200320032903b00a3703d008200320032802a8043602f00b200320032800ab043600f30b0b200341a8046a41086a2204200341d0086a41086a290300370300200320032903d0083703a80420020d21200341e8056a41086a2004290300220e370300200320032903a804220f3703e805200341d8156a200e3703002003200a3703c8152003200b3703c0152003200f3703d01502402006410171450d00200341e0106a410510bc060c580b0240200341c0156a200341b00e6a412010ec08450d00200341e0106a410210bc060c580b200341e0106a200341b00e6a200341800c6a200d200c4101108904200341e0106a41086a290300210e024020032802e0104101460d00200341f0106a290300210a200341d0086a41086a200341980c6a290300370300200320032903900c3703d008200341063a00e0104200200c200a7d200d200e54ad7d220a200d200e7d220b200d56200a200c56200a200c511b22021b210c4200200b20021b210d20032903880c210a20032903800c210b41002102410021060c590b20032802e41021022003200e3702e410200320023602e0100c570b200341b0086a410410bc0620032d00b0084106460d590c5b0b200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c015200341e0106a200341c0156a10c102200341a8066a41086a200341e9106a290000370300200341a8066a41106a200341f1106a290000370300200341a8066a41186a200341f9106a290000370300200320032900e1103703a80620032d00e0104101460d1c200341b00e6a41186a200341a8066a41186a290300370300200341b00e6a41106a200341a8066a41106a290300370300200341b00e6a41086a200341a8066a41086a290300370300200320032903a8063703b00e200341800c6a200210ff03200341c0156a20032802800c220520032802880c220710b205200341b00a6a41086a2206200341e8156a290300370300200320032903e0153703b00a200341c0156a41186a290300210a20032903d015210b20032903c815210c20032903c015210d024020032d00f015220441024622010d00200341d0086a41086a2006290300370300200320032903b00a3703d0080b200341a8046a41086a200341d0086a41086a290300370300200320032903d0083703a80420010d1e200341e8056a41086a200341a8046a41086a290300220e370300200320032903a804220f3703e805200341d8156a200e3703002003200a3703c8152003200b3703c0152003200f3703d01502402004410171450d00200341e0106a410510bc060c510b200341c0156a200341b00e6a412010ec08450d1d200341e0106a410210bc060c500b200341d0086a41086a2008290300370300200320032903f0063703d008200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c015200341c0156a10a7050d1a200341e0106a201110ff03200341c0156a20032802e010220220032802e810220110b205200341e8056a41086a2206200341e8156a290300370300200320032903e0153703e805200320032800f1153602a8042003200341f4156a2800003600ab04200341d8156a290300210c20032903d015210d20032903c815210e20032903c015210f024020032d00f01541024622070d00200341b00a6a41086a2006290300370300200320032903e8053703b00a200320032802a8043602f00b200320032800ab043600f30b0b200341a8046a41086a200341b00a6a41086a290300370300200320032903b00a3703a804024020070d00200341d8156a200341b0046a290300370300200320032903a8043703d0152003200d3703c0152003200c3703c815200341c8006a200341c0156a200f200e10fb010b200341c0156a41186a200b370300200341e0156a20032903d008370300200341f4156a20032800f30b360000200341e8156a2207200341d8086a22062903003703002003200a3703d015200342003703c815200342003703c015200320123a00f015200320032802f00b3600f11520022001200341c0156a10c605024020032802e410450d002002102e0b200341cd156a200b370000200341d5156a20032903d00837000020072011360200200341dd156a20062903003700002003200a3700c515200341003a00c415200341023a00c015200341c0156a10fe01200041186a41003a000020004200370308200020032800e8063600192000411c6a200341eb066a280000360000200042003703000c5d0b200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a200929030037030020032003290390133703c015200341e0106a200341c0156a10c102200341a8066a41086a200341e9106a290000370300200341a8066a41106a200341f1106a290000370300200341a8066a41186a200341f9106a290000370300200320032900e1103703a80620032d00e0104101460d16200341b00e6a41186a200341a8066a41186a290300370300200341b00e6a41106a200341a8066a41106a290300370300200341b00e6a41086a200341a8066a41086a290300370300200320032903a8063703b00e200341900a6a200210ff03200341c0156a20032802900a220520032802980a220710b205200341b00a6a41086a2206200341e8156a290300370300200320032903e0153703b00a200320032800f1153602a8042003200341f4156a2800003600ab04200341c0156a41186a290300210a20032903d015210b20032903c815210c20032903c015210d024020032d00f015220441024622010d00200341d0086a41086a2006290300370300200320032903b00a3703d008200320032802a8043602f00b200320032800ab043600f30b0b200341a8046a41086a200341d0086a41086a290300370300200320032903d0083703a80420010d18200341e8056a41086a200341a8046a41086a290300220e370300200320032903a804220f3703e805200341f8106a200e3703002003200a3703e8102003200b3703e0102003200f3703f01002402004410171450d00200341800c6a410510bc060c4a0b200341e0106a200341b00e6a412010ec08450d17200341800c6a410210bc060c490b20034194066a41026a22062001410f6a2d00003a0000200341d0086a41086a2204200141206a290200370300200341d0086a41106a2205200141286a290200370300200320012f000d3b0194062003200141186a2902003703d008200141c8006a290300210e200141c0006a290300210d2002411a6a290100210c200241196a2d00002113200241186a2d00002115200241166a2f01002114200241156a2d00002116200241146a2d00002118200241126a2f01002119200241116a2d0000211a200241106a2d000021172002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f01002124200141146a2802002108200141106a28020021112001410c6a2d00002109200141386a290300210b200141306a290300210a2002280228210720022d0001211220022d0000210202400240024002400240200141086a2802000e050001020304000b200341c0156a41146a4101360200200342013702c4152003419cc3cb003602c015200341043602ac04200341a4a7c7003602a8042003200341a8046a3602d015200341c0156a4194a7c7001044000b200341b0086a41026a20062d00003a0000200341b00e6a41086a2004290300370300200341b00e6a41106a2005290300370300200320032f0194063b01b008200320032903d0083703b00e20072007280200417f6a22013602000240024002400240024002400240200241ff01710d00024020010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b41012102201241ff01714101470d012003201f3a00cf06200320203a00ce06200320213b01cc06200320223a00cb06200320233a00ca06200320243b01c8062003201a3a00d706200320173a00d6062003201b3b01d4062003201c3a00d3062003201d3a00d2062003201e3b01d006200320133a00df06200320153a00de06200320143b01dc06200320163a00db06200320183a00da06200320193b01d8062003200c3703e006200341900a6a41186a2201200c370300200341900a6a41106a220720032903d806370300200341900a6a41086a220620032903d006370300200320032903c8063703900a20034190136a41186a200129030037030020034190136a41106a200729030037030020034190136a41086a2006290300370300200320032903900a37039013200341a8046a41026a2201200341b0086a41026a2d00003a0000200320032f01b0083b01a804200341e0106a41086a2207200341b00e6a41086a290300370300200341e0106a41106a200341b00e6a41106a290300370300200320032903b00e3703e01002400240024020090e03000201020b200341e8056a41026a20012d00003a0000200341800c6a41086a2007290300370300200341800c6a410d6a200341e0106a410d6a290000370000200320032f01a8043b01e805200320032903e0103703800c410021020c010b2008450d002011102e0b200341bb066a200341800c6a41086a290300370000200341a8066a41186a2003418d0c6a290000370000200320032f01e8053b01a806200320083600af06200320113600ab06200320032903800c3700b3062003200341e8056a41026a2d00003a00aa0620020d03200341c0156a41186a200341a8066a41186a290300370300200341c0156a41106a200341a8066a41106a290300370300200341c0156a41086a200341a8066a41086a290300370300200320032903a8063703c015200341e0106a20034190136a200341c0156a200a200b410110ca0220032d00e01022024106460d0620032902e410210a20032d00e310210120032d00e210210720032d00e11021060c050b024020010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b200341900a6a41186a200341c8066a41186a290300370300200341900a6a41106a200341c8066a41106a290300370300200341900a6a41086a200341c8066a41086a290300370300200320032903c8063703900a0c010b200341900a6a41186a200341c8066a41186a290300370300200341900a6a41106a200341c8066a41106a290300370300200341900a6a41086a200341c8066a41086a290300370300200320032903c8063703900a0b4102210220094102470d012008450d012011102e0c010b410121020b0b200320032800b00a3602f0062003200341b30a6a2800003600f306200041186a41003a000020004200370308200020032802f0063600192000411c6a20032800f306360000200041246a200a370200200020013a0023200020073a0022200020063a0021200041206a20023a0000200042013703000c5f0b200320032800b00a3602f0062003200341b30a6a2800003600f306200041186a41003a000020004200370308200020032802f0063600192000411c6a20032800f306360000200042003703000c5e0b200341e8066a41026a20062d00003a0000200341b00a6a41086a2004290300370300200341b00a6a41106a200529030037030020072007280200417f6a2201360200200320032f0194063b01e806200320032903d0083703b00a02400240024002400240200241ff01710d00024020010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b201241ff01710d01200341e0106a41026a2201200341e8066a41026a2d00003a0000200341c0156a41086a2207200341b00a6a41086a290300370300200341c0156a41106a200341b00a6a41106a290300370300200320032f01e8063b01e010200320032903b00a3703c0154101210220090e03020403040b20010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b4102210220094102470d4c2008450d4c2011102e0c4c0b200341b00e6a41026a20012d00003a000020034190136a41086a200729030037030020034190136a410d6a200341c0156a410d6a290000370000200320032f01e0103b01b00e200320032903c01537039013410021020c010b2008450d002011102e0b200341bb066a20034190136a41086a290300370000200341a8066a41186a22012003419d136a290000370000200320032f01b00e3b01a806200320083600af06200320113600ab0620032003290390133700b3062003200341b00e6a41026a2d00003a00aa0620020d16200341800c6a41186a2001290300370300200341800c6a41106a200341a8066a41106a290300370300200341800c6a41086a200341a8066a41086a290300370300200320032903a8063703800c20034190136a200341800c6a10c802200341c0156a200328029013220720032802981310c902200341c0156a41386a2903002125200341c0156a41306a2903002126200341c0156a41286a2903002127200341c0156a41206a2903002128200341c0156a41186a2903002129200341c0156a41106a290300210f20034180166a290300212a20032903c815211020032903c015210c200341a8046a41086a20034190166a290300370300200320034188166a2903003703a804200e200b7c200d200a7c222b200d54ad7c212c02400240200c4201510d00200341e0106a41386a4200370300200341e0106a41306a4200370300200341e0106a41286a4200370300200341e0106a41206a4200370300200341f8106a4200370300200341e0106a41106a4200370300200341e0106a41086a4200370300200342003703e0104200212a42002128420021274200212642002125420021104200210f420021294200212d4200212e4200210c4200212f0c010b200341e0106a41206a2027370300200341e0106a41286a2026370300200341e0106a41106a2029370300200341e0106a41306a2025370300200320283703f810200320103703e0102003202a370398112003200f3703e8102027212d2026212e2010210c200f212f0b202c502102202b4280c8afa0255421010240200328029413450d002007102e0b2001410020021b210202400240200c202f844200520d00202d20032903f01084202e200341f8106a29030084844200520d0020032903901120034198116a2903008450450d004200212b410021010c010b4201212b410121010b4200200b20021b210b4200200a20021b210a0240202b4201510d004200212742002126420021254200212a4200212942002128420021104200210f0b4200200e20021b210c4200200d20021b210d02400240200a201058200b200f58200b200f5122021b0d002003200a20107d3703c0152003200b200f7d200a201054ad7d3703c8152003200341c0156a3602f006200341f0066a10ce020c010b200a20105a200b200f5a20021b0d0020032010200a7d3703c0152003200f200b7d2010200a54ad7d3703c8152003200341c0156a3602f006200341f0066a10cc020b02400240200d202958200c202858200c20285122021b0d002003200d20297d3703c0152003200c20287d200d202954ad7d3703c8152003200341c0156a3602f006200341f0066a10ce020c010b200d20295a200c20285a20021b0d0020032029200d7d3703c01520032028200c7d2029200d54ad7d3703c8152003200341c0156a3602f006200341f0066a10cc020b200341e8156a22072026370300200341f0156a22062025370300200320273703e0152003200c3703d8152003200d3703d0152003200a3703c0152003200b3703c8154200210f42012110202b420152ad212802400240427f200a200d7c220e200e200a542202200b200c7c2002ad7c220e200b54200e200b511b22021b222942ffc7afa02556427f200e20021b220e420052200e501b0d00200a200d84200b200c8484220f50210242002110200f420052ad210f0c010b2006290300212d2007290300212f200341e0156a290300212c200341d0156a290300212520032903d815212b20032903c815212720032903c0152126410121020b200341d8136a200c370300200341d0136a200d370300200341c8136a200b370300200341b8136a200e370300200341b0136a22072029370300200341a0136a200b3703002003200a3703c0132003200a370398132003200f3703a8132003202837039013024020012010420152720d002003200341800c6a3602c015200341800c6a200341c0156a10bd060c480b02400240200141017322012010420151720d002003200341800c6a3602c015200341800c6a200341c0156a10be0641ff017122014103460d49024020010e03024a00020b024020020d00200320073602c015200341c0156a10cc020b410421020c4b0b2010420152200171450d480b200a2126200b21100c480b200141e0006a290300210c200141d8006a290300210f200141d0006a2903002110200ba72113200aa72101200a422088a72115200341f0066a41026a20062d00003a0000200341e0106a41086a2004290300370300200341e0106a41106a200529030037030020072007280200417f6a2206360200200320032f0194063b01f006200320032903d0083703e0100240024002400240024002400240200241ff01710d00024020060d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b201241ff01710d01200341800c6a41026a2207200341f0066a41026a2d00003a0000200341c0156a41086a2206200341e0106a41086a290300370300200341c0156a41106a200341e0106a41106a290300370300200320032f01f0063b01800c200320032903e0103703c0154101210220090e03020403040b20060d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b410221020240200141ff01714102470d002013450d002015102e0b20094102470d032008450d032011102e0c030b200341b00a6a41026a20072d00003a0000200341b00e6a41086a2006290300370300200341b00e6a410d6a200341c0156a410d6a290000370000200320032f01800c3b01b00a200320032903c0153703b00e410021020c010b2008450d002011102e0b200341db066a200341b00e6a41086a290300370000200341c8066a41186a2207200341bd0e6a290000370000200320032f01b00a3b01c806200320083600cf06200320113600cb06200320032903b00e3700d3062003200341b00a6a41026a2d00003a00ca060240024020020d00200b422088a7210420034190136a41186a200729030037030020034190136a41106a200341c8066a41106a29030037030020034190136a41086a200341c8066a41086a290300370300200320032903c806370390132001410876210241012106024002400240200141ff01710e03000201020b2010a72107410021060c010b02402013450d002015102e0b0b200341bf066a200e3700002003200d3700b706200320073a00c706200320043600b306200320133600af06200320153600ab06200320023b01a806200320024110763a00aa0620060d01200341c0156a41186a200341a8066a41186a290300370300200341c0156a41106a200341a8066a41106a290300370300200341c0156a41086a200341a8066a41086a290300370300200320032903a8063703c015200341b00e6a20034190136a200341c0156a200f200c410110ca02024020032d00b00e22024106460d0020032902b40e210a20032d00b30e210120032d00b20e210720032d00b10e21060c040b200320032802e8053602b008200320032800eb053600b308200041186a41003a000020004200370308200020032802b0083600192000411c6a20032800b308360000200042003703000c600b41012102200141ff01714102470d012013450d012015102e0c010b410121020b0b200320032802e8053602b008200320032800eb053600b308200041186a41003a000020004200370308200020032802b0083600192000411c6a20032800b308360000200041246a200a370200200020013a0023200020073a0022200020063a0021200041206a20023a0000200042013703000c5c0b200341e8056a41026a20062d00003a0000200341b00e6a41086a2004290300370300200341b00e6a41106a2005290300370300200320032f0194063b01e805200320032903d0083703b00e20072007280200417f6a22013602000240024002400240024002400240200241ff01710d00024020010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b41012102201241ff01714101470d012003201f3a00cf06200320203a00ce06200320213b01cc06200320223a00cb06200320233a00ca06200320243b01c8062003201a3a00d706200320173a00d6062003201b3b01d4062003201c3a00d3062003201d3a00d2062003201e3b01d006200320133a00df06200320153a00de06200320143b01dc06200320163a00db06200320183a00da06200320193b01d8062003200c3703e006200341900a6a41186a2201200c370300200341900a6a41106a220720032903d806370300200341900a6a41086a220620032903d006370300200320032903c8063703900a20034190136a41186a200129030037030020034190136a41106a200729030037030020034190136a41086a2006290300370300200320032903900a37039013200341b00a6a41026a2201200341e8056a41026a2d00003a0000200320032f01e8053b01b00a200341e0106a41086a2207200341b00e6a41086a290300370300200341e0106a41106a200341b00e6a41106a290300370300200320032903b00e3703e01002400240024020090e03000201020b200341a8046a41026a20012d00003a0000200341800c6a41086a2007290300370300200341800c6a410d6a200341e0106a410d6a290000370000200320032f01b00a3b01a804200320032903e0103703800c410021020c010b2008450d002011102e0b200341bb066a200341800c6a41086a290300370000200341a8066a41186a2003418d0c6a290000370000200320032f01a8043b01a806200320083600af06200320113600ab06200320032903800c3700b3062003200341a8046a41026a2d00003a00aa0620020d03200341c0156a41186a200341a8066a41186a290300370300200341c0156a41106a200341a8066a41106a290300370300200341c0156a41086a200341a8066a41086a290300370300200320032903a8063703c015200341e0106a20034190136a200341c0156a200a200b410010ca0220032d00e01022024106460d0620032902e410210a20032d00e310210120032d00e210210720032d00e11021060c050b024020010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b200341900a6a41186a200341c8066a41186a290300370300200341900a6a41106a200341c8066a41106a290300370300200341900a6a41086a200341c8066a41086a290300370300200320032903c8063703900a0c010b200341900a6a41186a200341c8066a41186a290300370300200341900a6a41106a200341c8066a41106a290300370300200341900a6a41086a200341c8066a41086a290300370300200320032903c8063703900a0b4102210220094102470d012008450d012011102e0c010b410121020b0b200320032802f0063602e806200320032800f3063600eb06200041186a41003a000020004200370308200020032802e8063600192000411c6a20032800eb063600002000200a370024200020013a0023200020073a0022200020063a0021200041206a20023a0000200042013703000c5c0b200320032802f0063602e806200320032800f3063600eb06200041186a41003a000020004200370308200020032802e8063600192000411c6a20032800eb06360000200042003703000c5b0b2001410c6a2802002105200141086a280200211120012802042104200341c0156a41286a200241286a280200360200200341c0156a41206a200241206a290200370300200341c0156a41186a200241186a290200370300200341c0156a41106a200241106a290200370300200341c0156a41086a200241086a290200370300200320022902003703c0150240024002400240200341c0156a10bb060d0002402005410a4d0d00200341f00b6a410310bf060c030b200341900a6a41186a22014200370300200341900a6a41106a22174200370300200341900a6a41086a22024200370300200342003703900a200341d0086a4190dac800410a1081022002200341d0086a41086a2206290300370300200320032903d0083703900a200341b00a6a41d097c900410c1081022001200341b00a6a41086a2209290300370300201720032903b00a3703000240200341900a6a108603220741ff01714102460d002007410171450d00200341f00b6a410210bf060c020b200142003703002017420037030020024200370300200342003703900a200341d0086a4190dac800410a10810220022006290300370300200320032903d0083703900a200341b00a6a41d097c900410c108102201741086a2009290300370200201720032903b00a370200200341013a00a804200341900a6a4120200341a8046a410110b201200341c8066a41186a22024200370300200341c8066a41106a221b4200370300200341c8066a41086a22014200370300200342003703c806200341e8056a41d9fcc60041061081022001200341e8056a41086a290300370300200320032903e8053703c806200341a8046a4180f4cb0041061081022002200341a8046a41086a290300370300201b20032903a80437030020034180016a200341c8066a4120108e0220032802800121012003280284012107200341b0086a10e10402400240024020032802b808220220032802b4082219470d00200241016a22062002490d4a200241017422092006200920064b1b22064104200641044b1bad42c4007e220a422088a7454102742106200aa721090240024020020d00200341003602c0150c010b200341c8156a4104360200200320032802b0083602c0152003200241c4006c3602c4150b20034190136a20092006200341c0156a107d20034198136a28020021062003280290134101460d0120032003280294133602b0082003200641c4006e22193602b4080b20032802b008221c200241c4006c6a22062007410020011b360204200641003a00002003200241016a22153602b8082004200541f0006c22026a212420050d01200421070c460b20060d5c0c480b200441f4006a2106200241907f6a2109200341e0106a4101722114200341c0156a41106a2130200341c0156a41086a2131200341c8066a41186a21162003419f0c6a21322004210703402007280204211a20072802002112200341c0156a200741086a41e80010e9081a200741f0006a2107201a450d4520034190136a200341c0156a41e80010e9081a2003201a3602c415200320123602c015203120034190136a41e80010e9081a20164200370300200341c8066a41106a22184200370300200341c8066a41086a22134200370300200342003703c806200341e8056a41d9fcc60041061081022013200341e8056a41086a290300370300200320032903e8053703c806200341a8046a4180f4cb004106108102201b41086a200341a8046a41086a290300370300201b20032903a804370300200341f8006a200341c8066a4120108e0220032802782102200328027c2101200341800c6a200341c0156a109a04024020120d00200341e0106a410410bf0620033500e11020033300e51020033100e7104210868442208684210a200341e8106a28020021020c450b024020122001410020021b22024d0d00200341e0106a410510bf0620033500e11020033300e51020033100e7104210868442208684210a200341e8106a28020021020c450b200341b00a6a2012417f6a108c02200341e0106a20032802b00a220820032802b80a108d0220032d00e01021012016201441186a221d2900003703002018201441106a221e2900003703002013201441086a221f290000370300200320142900003703c8060240024020014101460d00200341b00e6a41186a4200370300200341b00e6a41106a4200370300200341b00e6a41086a4200370300200342003703b00e0c010b200341b00e6a41186a2016290300370300200341b00e6a41106a2018290300370300200341b00e6a41086a2013290300370300200320032903c8063703b00e0b024020032802b40a450d002008102e0b0240200341b00e6a2030412010ec08450d00200341e0106a410110bf0620033500e11020033300e51020033100e7104210868442208684210a200341e8106a28020021020c450b0240201220024f0d00200341e0106a410710bf0620033500e11020033300e51020033100e7104210868442208684210a200341e8106a28020021020c450b024002402015450d00201541c4006c2101201c21020340024020022d00004101470d0041012108200241016a200341800c6a412010ec08450d030b200241c4006a2102200141bc7f6a22010d000b0b410021080b200341b00a6a2012108c02200341e0106a20032802b00a220120032802b80a108d0220032d00e01021022016201d2900003703002018201e2900003703002013201f290000370300200320142900003703c8060240024020024101460d00200341b00e6a41186a4200370300200341b00e6a41106a4200370300200341b00e6a41086a4200370300200342003703b00e0c010b200341b00e6a41186a2016290300370300200341b00e6a41106a2018290300370300200341b00e6a41086a2013290300370300200320032903c8063703b00e0b024020032802b40a450d002001102e0b02402008417f73200341b00e6a200341800c6a412010ec08410047710d00200341e0106a410610bf0620033500e11020033300e51020033100e7104210868442208684210a200341e8106a28020021020c450b2032310000210a20032900930c210b200328008f0c2101200328008b0c210820032800870c211220032800830c211a20032f00810c211d200335009b0c210c200341800c6a200341c0156a109a04200341b00e6a41186a221e4200370300200341b00e6a41106a221f4200370300200341b00e6a41086a22204200370300200342003703b00e200341a8066a41186a22214200370300200341a8066a41106a22224200370300200341a8066a41086a22234200370300200342003703a80641c800102c2202450d5c200341c8066a10e2042002410236022020024101360244200241186a2016290300370200200241106a2018290300370200200241086a2013290300370200200220032903c806370200200220032903a8063702242002412c6a2023290300370200200241346a20222903003702002002413c6a2021290300370200200320023602e01020034282808080203702e410200341e0106a10e304200341e0106a41186a201e290300370300200341e0106a41106a201f290300370300200341e0106a41086a2020290300370300200320032903b00e3703e010200341e0106a10e404200341f0066a41186a2213200341800c6a41186a290300370300200341f0066a41106a2218200341800c6a41106a290300370300200341f0066a41086a221e200341800c6a41086a290300370300200320032903800c3703f006024020152019470d0020192019470d00201941016a22022019490d492019410174221f2002201f20024b1b22024104200241044b1bad42c4007e220d422088a7454102742102200da7211f0240024020190d00200341003602e0100c010b200341043602e8102003201c3602e0102003201941c4006c3602e4100b200341b00e6a201f2002200341e0106a107d20032802b80e210220032802b00e4101460d44200320032802b40e221c3602b0082003200241c4006e22193602b4080b201c201541c4006c6a220241013a0000201e290300210d2018290300210e2013290300210f20032903f0062110200241c1006a200c200a42208684220a4220883c00002002200a3e003d2002200b370035200220013600312002200836002d200220123600292002201a3600252002201d3b0023200241003a002120022010370001200241196a200f370000200241116a200e370000200241096a200d370000200320032802b80841016a22153602b80820032802c4152108024020032802cc152202450d00200241246c21012008210203400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b024020032802c8152202450d00200241246c450d002008102e0b200941907f6a2109200641f0006a210620072024470d000c460b0b200341023a00f00b0b2005450d010b2004200541f0006c6a2106200421020340024020022207410c6a2802002201450d0020072802042102200141246c210103400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200741f0006a21020240200741086a2802002201450d00200141246c450d002007280204102e0b20022006470d000b0b2011450d42201141f0006c450d422004102e0c420b200341c0156a200141086a41d80010e9081a20034190136a41286a200241286a28020036020020034190136a41206a200241206a29020037030020034190136a41186a200241186a29020037030020034190136a41106a200241106a29020037030020034190136a41086a200241086a29020037030020032002290200370390132000200341c0156a20034190136a1081060c590b200141086a280200211520012802042112200341a8046a200141106a41c00110e9081a200341e8056a41286a2201200241286a280200360200200341e8056a41206a2207200241206a290200370300200341e8056a41186a2206200241186a290200370300200341e8056a41106a2204200241106a290200370300200341e8056a41086a2205200241086a290200370300200320022902003703e80502402012450d00200341f0066a200341a8046a41c00110e9081a200341c0156a41286a2001280200360200200341c0156a41206a2007290300370300200341c0156a41186a2006290300370300200341c0156a41106a2004290300370300200341c0156a41086a2005290300370300200320032903e8053703c01520034190136a200341c0156a10c102200341900a6a41086a20034199136a290000370300200341900a6a41106a200341a1136a290000370300200341900a6a41186a200341a9136a29000037030020032003290091133703900a024020032d0090134101460d00200341b0086a41186a2202200341900a6a41186a2206290300370300200341b0086a41106a2201200341900a6a41106a290300370300200341b0086a41086a2207200341900a6a41086a290300370300200320032903900a3703b008200341d0086a200341f0066a41c00110e9081a20034190136a41186a200229030037030020034190136a41106a200129030037030020034190136a41086a2007290300370300200320032903b00837039013200341c0156a20034190136a10f005024020032d00c0154101470d00200341f7106a2202200341d9156a290000370000200341e0106a41106a2201200341d2156a290100370300200341990a6a200341ca156a290100370000200341a10a6a200129030037000020062002290000370000200320032d00c1153a00900a200320032901c2153700910a200341b0086a1083060d13200341b00e6a200341d0086a41c00110e9081a200341c8066a200341900a6a10a603200341c0156a20032802c806220120032802d00610a70320032d00c0152102200341e0106a200341c0156a41017241c00110e9081a0240024020024101460d00200341003a0090130c010b200341013a00901320034190136a410172200341e0106a41c00110e9081a0b024020032802cc06450d002001102e0b20034190136a4101722114200341c0156a4101722102416821060340200341c0016a200341b00e6a200641b0fac6006a280000220110d10320032802c0012107200320032802c40122043602e810200320073602e410200320013602e010200341f00b6a200341e0106a10c203200341c0156a20032802f00b220520032802f80b10f402200341a8066a41086a2209200241086a290000370300200341a8066a41106a2208200241106a290000370300200341a8066a41186a2211200241186a290000370300200320022900003703a8060240024020032d00c0154101470d00200341c8066a41186a22132011290300370300200341c8066a41106a22112008290300370300200341c8066a41086a22082009290300370300200320032903a8063703c806024020032802f40b450d002005102e0b200341c0156a41186a2013290300370300200341c0156a41106a2011290300370300200341c0156a41086a2008290300370300200320032903c8063703c015200341c0156a200341900a6a412010ec08450d01200341c0156a410310c006200341800c6a410a6a200341c8156a2202280200360000200320032903c0153700820c200341b00a6a200341800c6a41c00110e9081a2002200341b00a6a410a6a280000360200200320032900b20a3703c0150c3f0b20032802f40b450d002005102e0b0240024020032d0090134101470d00200341b8016a2014200110d10320032802b8012205450d000240200420032802bc012209470d0020072005200410ec08450d020b200320093602c815200320053602c415200320013602c015200341e0106a200341c0156a10c20320032802e010220520032802e81010ff0120032802e410450d002005102e0b200320043602c815200320073602c415200320013602c015200341e0106a200341c0156a10c20320032802e010210120032802e81021074120102c2204450d5a200342203702c415200320043602c015200341c0156a200341900a6a412010742001200720032802c015220420032802c81510b201024020032802c415450d002004102e0b20032802e410450d002001102e0b200641046a22060d000b200341e0106a200341900a6a10a60320032802e810210120032802e0102102200341003602c815200342013703c015200341c0156a200341b00e6a41201074200341c0156a200341b00e6a41206a41201074200341c0156a200341f00e6a41201074200341c0156a200341900f6a41201074200341c0156a200341b00f6a41201074200341c0156a200341d00f6a412010742002200120032802c015220720032802c81510b201024020032802c415450d002007102e0b024020032802e410450d002002102e0b024020032d009013450d00200341b0086a108a060b41062102200341063a00c0150c3d0b200341c0156a410210c0060c3b0b410221020c3c0b200341c0156a41286a2001280200360200200341c0156a41206a2007290300370300200341c0156a41186a2006290300370300200341c0156a41106a2004290300370300200341c0156a41086a2005290300370300200320032903e8053703c01520034190136a200341c0156a10c102200341a8066a41086a20034199136a290000370300200341a8066a41106a200341a1136a290000370300200341a8066a41186a200341a9136a29000037030020032003290091133703a80620032d0090134101460d0f200341b00a6a41186a200341a8066a41186a290300220a370300200341b00a6a41106a200341a8066a41106a290300220b370300200341b00a6a41086a200341a8066a41086a290300220c370300200320032903a806220d3703b00a20034190136a41186a200a37030020034190136a41106a200b37030020034190136a41086a200c3703002003200d37039013200341c0156a20034190136a10f0050240024020032d00c0154101470d00200341f7106a2202200341d9156a290000370000200341e0106a41106a2201200341d2156a290100370300200341890c6a200341ca156a290100370000200341910c6a2001290300370000200341800c6a41186a2002290000370000200320032d00c1153a00800c200320032901c2153700810c200341d0086a200341800c6a10a603200341c0156a20032802d008220220032802d808220710a703024020032d00c0152201450d002002200710ff010b20032d00c1152107200341e0106a200341c0156a41027241bf0110e9081a024020014101470d00200341b00e6a200341e0106a41bf0110e9081a024020032802d408450d002002102e0b200320073a00901320034190136a410172200341b00e6a41bf0110e9081a200341b0016a20034190136a41e7e485f30610d103200320032903b0013702c415200341e7e485f3063602c015200341e0106a200341c0156a10c20320032802e010220220032802e81010ff01024020032802e410450d002002102e0b200341a8016a20034190136a41e2c289ab0610d103200320032903a8013702c415200341e2c289ab063602c015200341e0106a200341c0156a10c20320032802e010220220032802e81010ff01024020032802e410450d002002102e0b200341a0016a20034190136a41e9dabdf30610d103200320032903a0013702c415200341e9dabdf3063602c015200341e0106a200341c0156a10c20320032802e010220220032802e81010ff01024020032802e410450d002002102e0b20034198016a20034190136a41f0c2c98b0610d10320032003290398013702c415200341f0c2c98b063602c015200341e0106a200341c0156a10c20320032802e010220220032802e81010ff01024020032802e410450d002002102e0b20034190016a20034190136a41e1e69df30610d10320032003290390013702c415200341e1e69df3063602c015200341e0106a200341c0156a10c20320032802e010220220032802e81010ff01024020032802e410450d002002102e0b20034188016a20034190136a41e1ea91cb0610d10320032003290388013702c415200341e1ea91cb063602c015200341e0106a200341c0156a10c20320032802e010220220032802e81010ff01024020032802e410450d002002102e0b200341b00a6a108a060c3b0b024020032802d408450d002002102e0b200341f0066a410410c0060c010b200341f0066a410210c0060b20032d00f00622024106460d3820032d00f106210120032d00f206210720032d00f306210620032902f406210a0c370b2001411c6a2802002115200141186a2802002111200141146a2802002108200141106a28020021122001410c6a2802002113200141086a2802002107200341e0106a200141206a41800210e9081a200341800c6a41286a2201200241286a280200360200200341800c6a41206a2206200241206a290200370300200341800c6a41186a2204200241186a290200370300200341800c6a41106a2205200241106a290200370300200341800c6a41086a2209200241086a290200370300200320022902003703800c024002400240024020070e0400010203000b200341c0156a41146a4101360200200342013702c4152003419cc3cb003602c015200341043602ac0420034194c3cb003602a8042003200341a8046a3602d015200341c0156a41c499c9001044000b20034190136a200341e0106a41800210e9081a200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a2009290300370300200320032903800c3703c015200341b00a6a200341c0156a10c102200341a8066a41086a200341b90a6a2202290000370300200341a8066a41106a200341c10a6a2201290000370300200341a8066a41186a200341c90a6a2207290000370300200320032900b10a3703a80602400240024020032d00b00a4101470d00200341d00e6a41023a0000200341c80e6a41003a0000200342003703b80e200342013703b00e02402011450d002011410c6c21012012210203400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b02402008450d002008410c6c450d002012102e0b200341b80e6a210241002106410221040c010b200341c8066a41186a200341a8066a41186a290300220a370300200341c8066a41106a200341a8066a41106a290300220b370300200341c8066a41086a200341a8066a41086a290300220c370300200320032903a806220d3703c8062007200a3700002001200b3700002002200c3700002003200d3700b10a200341013a00b00a200341c0156a20034190136a41800210e9081a200341dc086a2011360200200341d0086a41086a2008360200200320153602e008200320123602d408200320133602d008200341b00e6a200341b00a6a200341c0156a200341d0086a10c10620032903b00e4201520d01200341b00e6a41086a2102200341d00e6a2d0000210420032d00c80e21060b200320022800113602e8062003200241146a2800003600eb0620022f0019210120022d001b2107200229001c210a2002280024210220032903b80e210b20032903c00e210c200041186a20063a0000200041106a200c3703002000200b370308200020032802e8063600192000411c6a20032800eb063600002000412c6a2002360200200041246a200a370200200020073a0023200020013b0021200041206a20043a0000200042013703000c5a0b200320032800c90e3602e8062003200341b00e6a411c6a2800003600eb0620032903b80e210a20032903c00e210b200041186a20032d00c80e3a0000200041106a200b3703002000200a370308200020032802e8063600192000411c6a20032800eb06360000200042003703000c590b20034190136a200341e0106a41800210e9081a200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a2009290300370300200320032903800c3703c015024002400240200341c0156a10bb06450d00200341d00e6a41023a0000200341c80e6a41003a0000200342003703b80e200342013703b00e02402011450d002011410c6c21012012210203400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b02402008450d002008410c6c450d002012102e0b200341b80e6a210241002106410221040c010b200341c0156a10e204200341c90a6a200341c0156a41186a290300370000200341c10a6a200341c0156a41106a290300370000200341b90a6a200341c0156a41086a290300370000200341013a00b00a200320032903c0153700b10a200341c0156a20034190136a41800210e9081a200341dc086a2011360200200341d0086a41086a2008360200200320153602e008200320123602d408200320133602d008200341b00e6a200341b00a6a200341c0156a200341d0086a10c10620032903b00e4201520d01200341b00e6a41086a2102200341d00e6a2d0000210420032d00c80e21060b200320022800113602f0062003200241146a2800003600f30620022f0019210120022d001b2107200229001c210a2002280024210220032903b80e210b20032903c00e210c200041186a20063a0000200041106a200c3703002000200b370308200020032802f0063600192000411c6a20032800f3063600002000412c6a2002360200200041246a200a370200200020073a0023200020013b0021200041206a20043a0000200042013703000c590b200320032800c90e3602f0062003200341b00e6a411c6a2800003600f30620032903b80e210a20032903c00e210b200041186a20032d00c80e3a0000200041106a200b3703002000200a370308200020032802f0063600192000411c6a20032800f306360000200042003703000c580b200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a2009290300370300200320032903800c3703c0150240200341c0156a10a705450d002000420037002420004200370308200041206a41023a0000200041186a41003a0000200042013703000c580b200341a8066a41186a22024200370300200341b8066a22014200370300200341a8066a41086a22074200370300200342003703a806200341e8056a41a0dac800410f1081022007200341e8056a41086a290300370300200320032903e8053703a806200341a8046a41a0eec80041071081022002200341a8046a41086a290300370300200120032903a804370300200341a8066a41202013201210e504200041186a41003a000020004200370308200020032800e8063600192000411c6a200341eb066a280000360000200042003703000c570b200141246a28020021052001411c6a2802002104200141186a2802002109200141146a2802002108200141106a28020021062001410c6a2802002111200141086a2802002112200341c0156a41286a200241286a280200360200200341c0156a41206a200241206a290200370300200341c0156a41186a200241186a290200370300200341c0156a41106a200241106a290200370300200341c0156a41086a200241086a290200370300200320022902003703c015024002400240200341c0156a10bb06450d004200210a410221064200210b0c010b200341a8066a41186a22024200370300200341a8066a41106a22014200370300200341a8066a41086a22074200370300200342003703a806200341e8056a41a081ca0041071081022007200341e8056a41086a290300370300200320032903e8053703a806200341a8046a41e4d1c100410c1081022002200341a8046a41086a290300370300200120032903a804370300200341c8016a200341a8066a4120108e02200341c0156a20032802cc01410020032802c8011b2215200510c20620032802c015220220032802c815108f022107024020032802c415450d002002102e0b200341b00e6a1087032007417f7320032802b00e221320054105746a410020032802b80e20054b1b2202410047710d01024020032802b40e41ffffff3f71450d002013102e0b4280808080b0024280808080a00120071b210b41b4f3c800ad41aaf3c800ad20071b210a410321060b02402011450d002012102e0b02402004450d002004410c6c21012008210203400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b02402009450d002009410c6c450d002008102e0b200020073a00222000410c3a0021200042003703082000200b200a84370024200041206a20063a0000200041186a41003a0000200042013703000c570b200241086a290000210a200241106a290000210b2002290000210c200341c8066a41186a200241186a290000220d370300200341c8066a41106a200b370300200341c8066a41086a200a3703002003200c3703c806200341cd156a200a370000200341d5156a200b370000200341dd156a200d370000200341003a00c415200341083a00c0152003200c3700c515200341c0156a10fe01200341003602e810200342013703e0102006200341e0106a1076200341e0106a2012200610742004200341e0106a107602402004450d0020082004410c6c6a210620082102034020022802002101200241086a2802002207200341e0106a1076200341e0106a2001200710742002410c6a22022006470d000b0b20034190136a2015200510c20620032802e810220141046a2202417f4c0d3f20032802e0102107200328029813210520032802901321060240024020020d00410121150c010b2002102c2215450d540b200341003602c815200320023602c415200320153602c0152001200341c0156a1076200341c0156a2007200110742006200520032802c015220220032802c81510b201024020032802c415450d002002102e0b0240200328029413450d002006102e0b024020032802e410450d002007102e0b024020032802b40e41ffffff3f71450d002013102e0b02402011450d002012102e0b02402004450d002004410c6c21012008210203400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b02402009450d002009410c6c450d002008102e0b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c560b200341c0156a41306a200141386a290300370300200341c0156a41286a200141306a290300370300200341c0156a41206a200141286a290300370300200341c0156a41186a200141206a290300370300200341c0156a41106a200141186a290300370300200341c0156a41086a200141106a2903003703002003200141086a2903003703c01520034190136a41286a200241286a28020036020020034190136a41206a200241206a29020037030020034190136a41186a200241186a29020037030020034190136a41106a200241106a29020037030020034190136a41086a200241086a29020037030020032002290200370390132000200341c0156a20034190136a10c3060c550b200341c0156a41306a200141386a290300370300200341c0156a41286a200141306a290300370300200341c0156a41206a200141286a290300370300200341c0156a41186a200141206a290300370300200341c0156a41106a200141186a290300370300200341c0156a41086a200141106a2903003703002003200141086a2903003703c01520034190136a41286a200241286a28020036020020034190136a41206a200241206a29020037030020034190136a41186a200241186a29020037030020034190136a41106a200241106a29020037030020034190136a41086a200241086a29020037030020032002290200370390132000200341c0156a20034190136a10c4060c540b200341c0156a41306a200141386a290300370300200341c0156a41286a200141306a290300370300200341c0156a41206a200141286a290300370300200341c0156a41186a200141206a290300370300200341c0156a41106a200141186a290300370300200341c0156a41086a200141106a2903003703002003200141086a2903003703c01520034190136a41286a200241286a28020036020020034190136a41206a200241206a29020037030020034190136a41186a200241186a29020037030020034190136a41106a200241106a29020037030020034190136a41086a200241086a29020037030020032002290200370390132000200341c0156a20034190136a10c5060c530b200141206a290300210c200141186a290300210a200141286a290300210b200141146a2802002112200141106a28020021112001410c6a2802002108200141086a2d0000210720012d00092113200341e0106a41286a2201200241286a280200360200200341e0106a41206a2206200241206a290200370300200341e0106a41186a2204200241186a290200370300200341e0106a41106a2205200241106a290200370300200341e0106a41086a2209200241086a290200370300200320022902003703e0100240024002400240024002400240024020070e0700010203040506000b200341c0156a41146a4101360200200342013702c4152003419cc3cb003602c015200341043602ac0420034194c3cb003602a8042003200341a8046a3602d015200341c0156a4188f3c0001044000b200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a2009290300370300200320032903e0103703c01520034190136a200341c0156a10c1020240024020032d0090134101460d0020034190136a41086a280200210220034190136a410c6a280200210120034190136a41106a280200210720034190136a41146a290200210b20032d009113210620032f019213210420032802941321052003200341ac136a35020020034190136a41206a31000042208684220d3e00cb0e200341cf0e6a200d4220883c00002003200b3700c30e200320073600bf0e200320013600bb0e200320023600b70e200320053600b30e200320043b00b10e200320063a00b00e0240201241104d0d00200341d0086a410410f3020c020b024020120d00200341d0086a410210f3020c020b200341980c6a22014200370300200341800c6a41106a22024200370300200341800c6a41086a22074200370300200342003703800c200341b00a6a418ef9c00041101081022007200341b00a6a41086a290000370300200320032900b00a3703800c200341c0156a419ef9c000410a1081022001200341c0156a41086a290000370300200220032900c01537030041002101200341b40a6a41003a0000200341003602b00a20034198026a200341800c6a4120200341b00a6a4105410010ca040240200328029802450d002003200328029c022201410520014105491b3602c4152003200341b00a6a3602c01520034190026a200341c0156a10ab010240200328029002450d00410021010c010b20032802940221010b200341980c6a4200370300200341800c6a41106a4200370300200341800c6a41086a22074200370300200342003703800c200341b00a6a418ef9c00041101081022007200341b00a6a41086a290000370300200320032900b00a3703800c200341c0156a41c7c3cb004107108102200241086a200341c0156a41086a290000370000200220032900c01537000041002107200341b40a6a41003a0000200341003602b00a20034188026a200341800c6a4120200341b00a6a4105410010ca040240200328028802450d002003200328028c022207410520074105491b3602c4152003200341b00a6a3602c01520034180026a200341c0156a10ab010240200328028002450d00410021070c010b20032802840221070b200341980c6a4200370300200341800c6a41106a4200370300200341800c6a41086a22064200370300200342003703800c200341b00a6a418ef9c00041101081022006200341b00a6a41086a290000370300200320032900b00a3703800c200341c0156a41a8f9c0004109108102200241086a200341c0156a41086a290000370000200220032900c01537000041002102200341b40a6a41003a0000200341003602b00a200341f8016a200341800c6a4120200341b00a6a4105410010ca04024020032802f801450d00200320032802fc012202410520024105491b3602c4152003200341b00a6a3602c015200341f0016a200341c0156a10ab01024020032802f001450d00410021020c010b20032802f40121020b02402002417f200120076a220720072001491b2201720d00200341d0086a410110f3020c020b02402012417f200120026a220220022001491b4d0d00200341d0086a410310f3020c020b0240200a4280c8afa02556200c420052200c501b0d00200341d0086a410510f3020c020b200341e0016a2012ad42004280a0cb9801420010e80820034190136a200341b00e6a10e702200341c0156a200328029013220120032802981310e902200341d8156a290300210b20032802e015210220032903d015210f20032903e001220e4280e0cdb8eb057c220d200e54ad2110200341e8016a290300212820032902e41521290240200328029413450d002001102e0b200b420020021b210e200f420020021b210f202820107c210b02402002450d00202942ffffff3f83500d002002410120021b102e0b024002400240417f200d200f85200b200e8584420052200d200f542202200b200e54200b200e511b1b41016a0e03010200010b200341c0156a200341b00e6a200d200f7d200b200e7d2002ad7d10c30220032d00c0154106460d01200341d0086a410610f3020c030b200341d0016a200341b00e6a200f200d7d200e200b7d200f200d54ad7d10fb010b20034190136a200341b00e6a10c802200341c0156a200328029013220720032802981310c902200341e0156a290300420020032903c01542015122021b2110200341d8156a2201290300420020021b2128200341d0156a290300420020021b210e20032903c815420020021b210f0240200328029413450d002007102e0b42f0d0c9abc6add9b1f400200341b00e6a427f200f20287c22282028200f542202200e20107c2002ad7c220f200e54200f200e511b22021b220e200a200e200a54427f200f20021b220e200c54200e200c511b22021b220a200e200c20021b220c411f1085062001200b370300200341e8156a2012360200200341e4156a20113602002003200d3703d0152003200c3703c8152003200a3703c015200320083602e01520034190136a200341b00e6a10e7022003280290132202200328029813200341c0156a10b9050240200328029413450d002002102e0b0240201141ffffff3f71450d002008102e0b200341063a00d0080c380b200341023a00d0080b0240201141ffffff3f71450d002008102e0b20032d00d00822024106460d3620032f00d108210120032d00d3082107200020032902d408370024200020073a0023200020013b0021200041206a20023a0000200041186a41003a000020004200370308200042013703000c580b200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a2009290300370300200320032903e0103703c01520034190136a200341c0156a10c102200341800c6a41086a20034199136a290000370300200341800c6a41106a200341a1136a290000370300200341800c6a41186a200341a9136a29000037030020032003290091133703800c20032d0090134101460d0d200341b00e6a41186a200341800c6a41186a290300370300200341b00e6a41106a200341800c6a41106a290300370300200341b00e6a41086a200341800c6a41086a290300370300200320032903800c3703b00e200341c0156a200341b00e6a10e70220032802c015220120032802c815108f022102024020032802c415450d002001102e0b02402002450d00200341b00e6a10e802200341063a00b00a0c350b200341b00a6a410710f30220032d00b00a4106460d340c330b200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a2009290300370300200320032903e0103703c01520034190136a200341c0156a10c10220032d0090134101460d0b20034190136a41086a280200210220034190136a410c6a280200210120034190136a41106a280200210720034190136a41146a290200210a20032d009113210620032f019213210420032802941321052003200341ac136a35020020034190136a41206a31000042208684220b3e00cb0e200341cf0e6a200b4220883c00002003200a3700c30e200320073600bf0e200320013600bb0e200320023600b70e200320053600b30e200320043b00b10e200320063a00b00e200341980c6a22024200370300200341800c6a41106a22054200370300200341800c6a41086a22014200370300200342003703800c200341b00a6a418ef9c00041101081022001200341b00a6a41086a290000370300200320032900b00a3703800c200341c0156a419ef9c000410a1081022002200341c0156a41086a290000370300200520032900c015370300200341b40a6a41003a0000200341003602b00a200341b0026a200341800c6a4120200341b00a6a4105410010ca04024020032802b002450d00200320032802b4022202410520024105491b3602c4152003200341b00a6a3602c015200341a8026a200341c0156a10ab0120032802a8020d0020032802ac0220084d0d00200341f0066a410e10f3020c300b200341a0026a200341b00e6a10eb0220032802a002450d0a20032802a4022109200341c0066a22024200370300200341a8066a41106a22014200370300200341a8066a41086a22074200370300200342003703a806200341e8056a418ef9c00041101081022007200341e8056a41086a290300370300200320032903e8053703a806200341a8046a41c7c3cb0041071081022002200341a8046a41086a290300370300200120032903a804370300200341c0156a200341a8066a10f10220032802c0152201410820011b21044100210202400240024020032902c415420020011b220a422088a722010e020201000b4100210203402001410176220620026a210720072002200420074106746a41206a200341b00e6a412010ec084101481b2102200120066b220141014b0d000b0b200420024106746a41206a200341b00e6a412010ec084521020b0240200a42ffffff1f83500d002004102e0b02402002450d00200341f0066a410a10f3020c300b200341a80a6a22024200370300200341900a6a41106a22014200370300200341900a6a41086a22074200370300200342003703900a200341b00a6a418ef9c00041101081022007200341b00a6a41086a290000370300200320032900b00a3703900a200341d0086a41a8f9c00041091081022002200341d0086a41086a290000370300200120032900d008370300200341c0156a200341900a6a10f10220032802c0152202410820021b210602400240024020032902c415420020021b220a422088a72201450d00200641206a2102200141067441406a41067641016a210741002101034002402002200341b00e6a412010ec080d000240200a42ffffff1f83500d002006102e0b200341f0066a410b10f3020c340b200241c0006a21022007200141016a2201470d000b200a42ffffff1f8350450d010c020b200a42ffffff1f83500d010b2006102e0b200341c0156a200341b00e6a4280a094a58d1d420010c302024020032d00c0154106470d00200341cf0e6a310000210a20033500cb0e210b20032900c30e210c20032800bf0e210720032800bb0e210620032800b70e210420032800b30e210820032f00b10e211120032d00b00e2112200341d0086a10ec0220032802d80822012009490d0a0240200120032802d408470d00200141016a22022001490d41200141017422132002201320024b1b22024104200241044b1bad42307e220d422088a7454103742102200da721130240024020010d00200341003602c0150c010b200341c0156a41086a4108360200200320032802d0083602c0152003200141306c3602c4150b20034190136a20132002200341c0156a107d20034198136a28020021022003280290134101460d0520032003280294133602d0082003200241306e3602d4080b20032802d008200941306c6a220241306a2002200120096b41306c10ea081a2002411f6a200b200a42208684220a4220883c00002002200a3e001b200241286a420037030020024280a094a58d1d3703202002200c3700132002200736000f2002200636000b2002200436000720022008360003200220113b0001200220123a00002003200141016a22023602d80820034190136a41086a2002360200200320032903d008220a3703901302400240200aa722020d00200341980c6a4200370300200341800c6a41106a4200370300200341800c6a41086a22024200370300200342003703800c200341b00a6a418ef9c00041101081022002200341b00a6a41086a290000370300200320032900b00a3703800c200341c0156a419ef9c000410a108102200541086a200341c0156a41086a290000370000200520032900c015370000200341800c6a412010ff010c010b200341980c6a4200370300200341800c6a41106a4200370300200341800c6a41086a22014200370300200342003703800c200341b00a6a418ef9c00041101081022001200341b00a6a41086a290000370300200320032900b00a3703800c200341c0156a419ef9c000410a108102200541086a200341c0156a41086a290000370000200520032900c015370000200341800c6a20034190136a10bd052003280294132201450d00200141306c450d002002102e0b200341063a00f0060c320b200341f0066a410c10f3020c2f0b200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a2009290300370300200320032903e0103703c01520034190136a200341c0156a10c102200341f0066a41086a20034199136a290000370300200341f0066a41106a200341a1136a290000370300200341f0066a41186a200341a9136a29000037030020032003290091133703f0060240024002400240024002400240024020032d0090134101460d00200341b00e6a41186a200341f0066a41186a290300370300200341b00e6a41106a200341f0066a41106a290300370300200341b00e6a41086a200341f0066a41086a290300370300200320032903f0063703b00e20080e03020301020b41022102200341023a00a8040c060b200320113602f006200341b00e6a411f6a310000210a20032d00b00e210220032f00b10e210120032900b30e210b20032900bb0e210c20032900c30e210d20033500cb0e210e200341d0086a10ec02200341b3136a200a3c000020034190136a411f6a200e3e0000200341a7136a200d3700002003419f136a200c3700002003200b37009713200320013b009513200320023a00941320032802d80821092003200341f0066a36029013410e2108200920114b0d0220034190136a4104722104410021024110210820032802d00821050240024020090e020401000b410021022009210103402001410176220620026a2107200720022005200741306c6a2004412010ec084101481b2102200120066b220141014b0d000b0b2005200241306c6a2004412010ec080d02200920024d0d0d2005200241306c6a2201290320210a200141286a290300210b2001200141306a20092002417f736a41306c10ea081a20032009417f6a3602d808200341c8026a2004200a200b10fb01200341c0156a41086a220241043a0000200341c9156a2004290000370000200341d1156a200441086a290000370000200341d9156a200441106a290000370000200341e1156a200441186a2900003700002003410c3a00c015200341c0156a10fe0120034190136a41086a20032802d808360200200320032903d008220a370390130240200aa722010d00200341800c6a41186a22014200370300200341800c6a41106a22074200370300200341800c6a41086a22064200370300200342003703800c200341b00a6a418ef9c00041101081022006200341b00a6a41086a290000370300200320032900b00a3703800c200341c0156a419ef9c000410a10810220012002290000370300200720032900c015370300200341800c6a412010ff010c330b200341800c6a41186a22074200370300200341800c6a41106a22064200370300200341800c6a41086a22044200370300200342003703800c200341b00a6a418ef9c00041101081022004200341b00a6a41086a290000370300200320032900b00a3703800c200341c0156a419ef9c000410a10810220072002290000370300200620032900c015370300200341800c6a20034190136a10bd052003280294132202450d32200241306c450d322001102e0c320b200341c0156a200341b00e6a410010f00220032d00c0154101460d02200341c0156a41086a41043a0000200341c9156a20032903b00e370000200341d1156a200341b00e6a41086a290300370000200341d9156a200341c00e6a290300370000200341e1156a200341c80e6a2903003700002003410c3a00c015200341c0156a10fe010c310b200341b00e6a411f6a310000210a20032d00b00e210120032f00b10e210720032900b30e210b20032900bb0e210c20032900c30e210d20033500cb0e210e200341900a6a41186a22024200370300200341900a6a41106a22064200370300200341900a6a41086a22044200370300200342003703900a200341b00a6a418ef9c00041101081022004200341b00a6a41086a290000370300200320032900b00a3703900a200341d0086a41a8f9c00041091081022002200341d0086a41086a290000370300200620032900d008370300200341c0156a200341900a6a10f10220032802c015210220032902c415210f20034190136a411f6a200a3c00002003200e3e00ab132003200d3700a3132003200c37009b132003200b37009313200320073b009113200320013a0090132002410820021b210402400240200f420020021b220a422088a72205450d00200441206a2107200541067441406a41067641016a210641002102410021010340200720026a20034190136a412010ec08450d02200241c0006a21022006200141016a2201470d000b0b0240200a42ffffff1f83500d002004102e0b200341a8046a411010f3020c030b200420026a220241186a290300210b200241106a290300210c2002200241c0006a2001417f7320056a41067410ea081a200341b8026a20034190136a200c200b10fb01200341c0156a41086a220241043a0000200341c0156a41096a200329039013370000200341d1156a20034190136a41086a290300370000200341d9156a20034190136a41106a290300370000200341e1156a20034190136a41186a2903003700002003410c3a00c015200341c0156a10fe0120032004360290132003200a4280808080707c220a37029413200341800c6a41186a22014200370300200341800c6a41106a22074200370300200341800c6a41086a22064200370300200342003703800c200341b00a6a418ef9c00041101081022006200341b00a6a41086a290000370300200320032900b00a3703800c200341c0156a41a8f9c000410910810220012002290000370300200720032900c015370300200341800c6a20034190136a10f202200a42ffffff1f83500d302004102e0c300b024020032802d4082202450d00200241306c450d0020032802d008102e0b200341a8046a200810f3020c010b200341a8046a411010f3020b20032d00a80422024106460d2e0b20032f00a904210120032d00ab042107200020032902ac04370024200020073a0023200020013b0021200041206a20023a0000200041186a41003a000020004200370308200042013703000c550b200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a2009290300370300200320032903e0103703c01502400240200341c0156a10a7050d004200210e410121010240200841ff01710e03022d002d0b2012450d2b2011102e0c2b0b410221014200210e200841ff01714102470d2a2012450d2a2011102e0c2a0b2003200b3e00ab13200341af136a200b4220883c000020032012360097132003201136009313200320084110763b009113200320084108763a0090132003200a3e009b132003200c3700a3132003200a4220883e009f13200341980c6a22024200370300200341800c6a41106a22014200370300200341800c6a41086a22074200370300200342003703800c200341b00a6a418ef9c00041101081022007200341b00a6a41086a290000370300200320032900b00a3703800c200341c0156a41a8f9c00041091081022002200341c0156a41086a290000370300200120032900c015370300200341b40a6a41003a0000200341003602b00a200341e0026a200341800c6a4120200341b00a6a4105410010ca040240024020032802e002450d00200320032802e4022202410520024105491b3602c4152003200341b00a6a3602c015200341d8026a200341c0156a10ab01201341ff017141004720032802d8024520032802dc0241004771730d010c2a0b201341ff0171450d290b200341c0156a411110f30220033500c11520033300c51520033100c7154210868442208684210d200341c8156a280200210220032d00c01521014201210e0c2a0b200341c0156a41286a2001280200360200200341c0156a41206a2006290300370300200341c0156a41186a2004290300370300200341c0156a41106a2005290300370300200341c0156a41086a2009290300370300200320032903e0103703c015200341c0156a10a7050d04200341b00a6a418ef9c0004110108102200341c0156a41fbafc90041061081024120102c2202450d502003422037029413200320023602901320034190136a200341b00a6a4110107420034190136a200341c0156a411010742003280298132202417f4c0d3c20032802901321010240024020020d00410121070c010b2002102c2207450d510b20072001200210e9082101200341f0066a41086a20034190136a41086a22162802002207360200200341a8046a41026a2206200341c0156a41026a2d00003a00002003200329039013220a3703f006200320032f00c0153b01a804200341940c6a2007360200200320023602880c200320023602840c200320013602800c2003200a37028c0c200341003a009c0c2003410b3602980c2003419f0c6a20062d00003a0000200320032f01a8043b009d0c200341c0156a200341800c6a10fa020240200341c0156a41c0006a2802002213450d00200341900a6a41106a2108200341c8066a41106a2109034020034190136a41386a200341c0156a41386a29030037030020034190136a41306a200341c0156a41306a29030037030020034190136a41286a200341c0156a41286a29030037030020034190136a41206a200341c0156a41206a29030037030020034190136a41186a2218200341c0156a41186a29030037030020034190136a41106a2219200341c0156a41106a2903003703002016200341c0156a41086a290300370300200320032903c0153703901320132003280288164105746a211520032802841621142013210202400240024003400240024002400240200222062015460d00200341c8066a41186a420037030020094200370300200341c8066a41086a22024200370300200342003703c806200341d0086a418ef9c00041101081022002200341d0086a41086a2211290300370300200320032903d0083703c806200341b00a6a41c7c3cb004107108102200941086a200341b00a6a41086a2212290300370300200920032903b00a370300200341b00e6a200341c8066a10f10220032802b00e2201410820011b21054100210202400240024020032902b40e420020011b220a422088a722010e020201000b4100210203402001410176220420026a210720072002200520074106746a41206a2006412010ec084101481b2102200120046b220141014b0d000b0b200520024106746a41206a2006412010ec084521020b0240200a42ffffff1f83500d002005102e0b20020d05200341900a6a41186a420037030020084200370300200341900a6a41086a22024200370300200342003703900a200341b00a6a418ef9c000411010810220022012290000370300200320032900b00a3703900a200341d0086a41a8f9c0004109108102200841086a2011290000370000200820032900d008370000200341b00e6a200341900a6a10f10220032802b00e2202410820021b210420032902b40e420020021b220a422088a72201450d01200441206a2102200141067441406a41067641016a2107410021010340024020022006412010ec080d00200a42ffffff1f83500d072004102e0c070b200241c0006a21022007200141016a2201470d000b200a42ffffff1f8350450d020c030b200341b00e6a41186a2018290300370300200341b00e6a41106a2019290300370300200341b00e6a41086a201629030037030020032003290390133703b00e200341b00e6a10e802201441ffffff3f71450d060c050b200a42ffffff1f83500d010b2004102e0b200641206a2102200341e8026a200610eb0220032802e8020d000b0b201441ffffff3f71450d010b2013102e0b200341c0156a200341800c6a10fa0220032802801622130d000b0b024020032802840c450d0020032802800c102e0b0240200341900c6a280200450d00200328028c0c102e0b200041186a41003a000020004200370308200020032800e8063600192000411c6a200341eb066a280000360000200042003703000c530b20020d4f0c3b0b2005200741b8b2c0001056000b2006200741b8b2c0001056000b20032802d008210220032802d4082101200341c8156a200341ec106a280200360200200320032902e4103703c01520022001200341c0156a41a8e9c70041b8e9c700103e000b2000420037002420004200370308200041206a41023a0000200041186a41003a0000200042013703000c4e0b200220091046000b200920011045000b200341f0066a410910f3020c240b41022102200341023a00f0060c240b200341023a00b00a0c250b410221020c270b200341c0156a410510c0060c280b410121020c320b410221010c350b200341d8006a200341b00e6a200d200c10cb02200341c0156a41186a200341d8006a41186a290300370300200320032903683703d0152003200341d8006a41086a2903003703c815200320032903583703c0152003200341c0156a3602800c200341800c6a10cc02200341d0086a41086a200341f0106a220141086a290300370300200341063a00800c200320012903003703d0084200210d41002101410121064200210c0c320b200341800c6a410110bc060c300b2000420037002420004200370308200041206a41023a0000200041186a41003a0000200042013703000c420b410221010c360b200341386a200341b00e6a200d200c10fb01200341063a00e0100c330b200341e0106a410110bc060c310b200341e0106a410110bc060c350b200341023a00b0080c390b4184b4c400412741acb4c4001039000b41b3d6c800413041e4d6c8001039000b200320032800e0103602b00e2003200341e3106a2800003600b30e200041186a41003a000020004200370308200020032802b00e3600192000411c6a20032800b30e360000200041206a41023a0000200042013703000c3a0b200341d4156a4101360200200342013702c415200341c4e2cc003602c015200341043602e4102003200341e0106a3602d0152003200341d0086a3602e010200341c0156a4198e9c7001044000b200341d4156a4101360200200342013702c415200341c4e2cc003602c015200341043602e4102003200341e0106a3602d0152003200341d0086a3602e010200341c0156a4188e9c7001044000b41fee7c70041e90041f8e8c700105d000b200341c0156a41086a200341e0106a41086a280200360200200320032903e0103703c01541fee7c70041e900200341c0156a41f4a7c70041e8e8c700103e000b200341c0156a41386a200141c0006a290300370300200341c0156a41306a200141386a290300370300200341c0156a41286a200141306a290300370300200341c0156a41206a200141286a290300370300200341c0156a41186a200141206a290300370300200341c0156a41106a200141186a290300370300200341c0156a41086a200141106a2903003703002003200141086a2903003703c01520034190136a41286a200241286a28020036020020034190136a41206a200241206a29020037030020034190136a41186a200241186a29020037030020034190136a41106a200241106a29020037030020034190136a41086a200241086a29020037030020032002290200370390132000200341c0156a20034190136a10c6060c350b200341c0156a41386a200141c0006a290300370300200341c0156a41306a200141386a290300370300200341c0156a41286a200141306a290300370300200341c0156a41206a200141286a290300370300200341c0156a41186a200141206a290300370300200341c0156a41106a200141186a290300370300200341c0156a41086a200141106a2903003703002003200141086a2903003703c01520034190136a41286a200241286a28020036020020034190136a41206a200241206a29020037030020034190136a41186a200241186a29020037030020034190136a41106a200241106a29020037030020034190136a41086a200241086a29020037030020032002290200370390132000200341c0156a20034190136a10c0020c340b200141c8006a290300210f200141c0006a29030021102001413c6a2802002117200141386a280200211a200141306a290300210d2001412c6a28020021182001412a6a2f010021152001411c6a290200210e200141186a2802002107200141146a2802002113200141106a28020021112001410c6a28020021122001410a6a2f01002114200141086a2d00002106200141246a350200210a200141286a310000210b20012d0029211920012d00092116200341800c6a41286a2201200241286a280200360200200341800c6a41206a2204200241206a290200370300200341800c6a41186a2205200241186a290200370300200341800c6a41106a2209200241106a290200370300200341800c6a41086a2208200241086a290200370300200320022902003703800c200a200b42208684210c0240024002400240024020060e050001020304000b200341c0156a41146a4101360200200342013702c4152003419cc3cb003602c015200341043602ac0420034194c3cb003602a8042003200341a8046a3602d015200341c0156a41889cc4001044000b200341c0156a41286a2001280200360200200341c0156a41206a2004290300370300200341c0156a41186a2005290300370300200341c0156a41106a2009290300370300200341c0156a41086a2008290300370300200320032903800c3703c01520034190136a200341c0156a10c102200341c8066a41086a20034199136a290000370300200341c8066a41106a200341a1136a290000370300200341c8066a41186a200341a9136a29000037030020032003290091133703c806024002400240024002400240024020032d0090134101460d00200341900a6a41186a200341c8066a41186a290300370300200341900a6a41106a200341c8066a41106a290300370300200341900a6a41086a200341c8066a41086a290300370300200320032903c8063703900a02400240024020130d00200341c0156a4104108e04200341c0156a41086a28020021020c010b201341e400490d01200341c0156a4105108e04200341c8156a28020021020b20032903c015210a2007108c042007102e0c020b200320133602e810200320113602e410200320123602e010200341c0156a41186a200341900a6a41186a290300370300200341c0156a41106a200341900a6a41106a290300370300200341c0156a41086a2201200341900a6a41086a290300370300200320032903900a3703c01520034190136a200341e0106a200341c0156a108d042003419c136a2802002102200329029413210a02402003280290134101460d00200120023602002003200aa722043602c415200341b1c5cb003602c015200341013b01cc15200341a8066a200341c0156a10900420034120360294132003200341a8066a36029013200341c0156a20034190136a1093010240024020032d00c0154101470d00200341e8086a4200370300200341e0086a4200370300200341d8086a4200370300200342003703d0080c010b200341e8086a200341d9156a290000370300200341e0086a200341d1156a290000370300200341d8086a200341c9156a290000370300200320032900c1153703d0080b200341003602c815200342013703c0152007200341c0156a10900220032802c8152105024020032802c415450d0020032802c015102e0b20034190136a200741b00210e9081a200341b00a6a41186a200341d0086a41186a290300370300200341b00a6a41106a200341d0086a41106a290300370300200341b00a6a41086a200341d0086a41086a290300370300200320032903d0083703b00a4110102c2201450d3b200141f8f7c60036020c2001410136020820014281808080103702004110102c2202450d3b20024190f8c60036020c20024101360208200242818080801037020020012001280200417f6a2206360200024020060d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22062006280200417f6a220636020020060d002001102e0b02400240200228020820034190136a200228020c28020c1101000d0020034180116a41023a0000200341f8106a41003a000020022002280200417f6a22013602004200210b200342003703e810200342013703e010024020010d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b20034190136a10dc02410121060c010b200341c0156a20034190136a41b00210e9081a200341ba0e6a200341b80a6a290300370100200341c20e6a200341c00a6a290300370100200341ca0e6a200341c80a6a290300370100200341d00e6a200341ce0a6a29010037010020034180023b01b00e200320032903b00a3701b20e200320023602d80e200341e0106a200341c0156a200341b00e6a10dd0220032903e010420151210620032903e810210b0b20034188116a280200210220034180116a290300210e200341f0106a290300210c200328028c112101024020060d00410021064200210d200ba70d044200210b0c060b410121060240200b4201510d00200341f8106a290300210d0c060b427f2005ad42e8077e42b0b182067c220b200c7c220c200c200b541b210c4200210d0c040b2007108c042007102e4200210b4200210d0c050b2007108c042007102e4202210a0b4200210b0240201141ffffff3f710d004200210d0c040b2012102e4200210d0c030b427f2005ad42e8077e42b0b182067c220b200c7c220c200c200b541b210c0b4201210b0b0240200a4280808080f0ffffff0783500d002004102e0b2007102e2006450d01200e210a0b2000200b3703082000412c6a2001360200200041286a2002360200200041206a200a370300200041186a200d370300200041106a200c370300200042013703000c370b2000200b370308200041186a200d370300200041106a200c370300200042003703000c360b200ba72102200aa7210620034190136a41286a200128020036020020034190136a41206a200429030037030020034190136a41186a200529030037030020034190136a41106a200929030037030020034190136a41086a2008290300370300200320032903800c37039013200341e0106a20034190136a10c102200341a8066a41086a200341e9106a290000370300200341a8066a41106a200341f1106a290000370300200341a8066a41186a200341f9106a290000370300200320032900e1103703a80602400240024020032d00e0104101470d0041022101200341e0156a41023a000041002107200341d8156a41003a00004200210a200342003703c815200342013703c01502402015411074201941087472200272450d002006102e0b201141ffffff3f71450d012012102e0c010b200341c8066a41186a200341a8066a41186a290300220a370300200341c8066a41106a200341a8066a41106a290300220b370300200341c8066a41086a200341a8066a41086a290300220c370300200320032903a806220f3703c806200341e0106a41186a200a370300200341e0106a41106a200b370300200341e0106a41086a200c3703002003200f3703e010200320133602b80e200320113602b40e200320123602b00e2003419c136a201836020020034190136a41086a20154110742019410874722002723602002003200636029413200320163a009113200341003a009013200341c0156a200341e0106a2014200341b00e6a2007200ea7200e422088a720034190136a200d108f0420032903c815210a20032903c0154201520d01200341e0156a2d00002101200341c0156a41186a2d000021070b200320032800d9153602e8062003200341c0156a411c6a2800003600eb06200341c0156a41106a290300210b20032f00e115210220032d00e315210620032902e415210c20032802ec152104200041186a20073a0000200041106a200b3703002000200a370308200020032802e8063600192000411c6a20032800eb063600002000412c6a2004360200200041246a200c370200200020063a0023200020023b0021200041206a20013a0000200042013703000c360b200320032800d9153602e8062003200341c0156a411c6a2800003600eb06200341c0156a41106a290300210b200041186a200341c0156a41186a2d00003a0000200041106a200b3703002000200a370308200020032802e8063600192000411c6a20032800eb06360000200042003703000c350b20034190136a41286a200128020036020020034190136a41206a200429030037030020034190136a41186a200529030037030020034190136a41106a200929030037030020034190136a41086a2008290300370300200320032903800c37039013200341e0106a20034190136a10c102200341a8066a41086a200341e9106a290000370300200341a8066a41106a200341f1106a290000370300200341a8066a41186a200341f9106a290000370300200320032900e1103703a80602400240024020032d00e0104101470d0041022102200341e0156a41023a000041002101200341d8156a41003a00004200210a200342003703c815200342013703c015200d42ffffff3f83500d012018102e0c010b200341c8066a41186a200341a8066a41186a290300220a370300200341c8066a41106a200341a8066a41106a290300220b370300200341c8066a41086a200341a8066a41086a2903002228370300200320032903a80622293703c806200341e0106a41186a200a370300200341e0106a41106a200b370300200341e0106a41086a2028370300200320293703e0102003200d3702b40e200320183602b00e20034190136a41206a200c4220883c000020034190136a411c6a200c3e0200200341a4136a200e37020020034190136a41106a20073602002003419c136a201336020020034190136a41086a20113602002003201236029413200320143b019213200320163a009113200341013a009013200341c0156a200341e0106a2015200341b00e6a201a20172010a720034190136a200f108f0420032903c815210a20032903c0154201520d01200341c0156a41206a2d00002102200341c0156a41186a2d000021010b200320032800d9153602f0062003200341c0156a411c6a2800003600f306200341c0156a41106a290300210b20032f00e115210720032d00e315210620032902e415210c20032802ec152104200041186a20013a0000200041106a200b3703002000200a370308200020032802f0063600192000411c6a20032800f3063600002000412c6a2004360200200041246a200c370200200020063a0023200020073b0021200041206a20023a0000200042013703000c350b200320032800d9153602f0062003200341c0156a411c6a2800003600f306200341c0156a41106a290300210b200041186a200341c0156a41186a2d00003a0000200041106a200b3703002000200a370308200020032802f0063600192000411c6a20032800f306360000200042003703000c340b2003200c3e008b072003418f076a200c4220883c00002003200e37008307200320073600ff06200320133600fb06200320113600f706200320123600f306200320143b00f106200320163a00f006200341c0156a41286a2001280200360200200341c0156a41206a2004290300370300200341c0156a41186a2005290300370300200341c0156a41106a2009290300370300200341c0156a41086a2008290300370300200320032903800c3703c01520034190136a200341c0156a10c102200341c8066a41086a20034199136a290000370300200341c8066a41106a200341a1136a290000370300200341c8066a41186a200341a9136a29000037030020032003290091133703c8060240024002400240024020032d0090134101460d00200341d0086a41186a200341c8066a41186a290300370300200341d0086a41106a200341c8066a41106a290300370300200341d0086a41086a200341c8066a41086a290300370300200320032903c8063703d0080240201541024f0d00200341f00b6a4101108e040c020b0240200d42ffffffff0f560d00200341f00b6a4104108e040c020b0240200d422088a741e400490d00200341f00b6a4105108e040c020b2003200d3702e410200320183602e010200341c0156a41186a200341d0086a41186a290300370300200341c0156a41106a200341d0086a41106a290300370300200341c0156a41086a2201200341d0086a41086a290300370300200320032903d0083703c01520034190136a200341e0106a200341c0156a108d042003419c136a2802002102200329029413210a024002402003280290134101460d0020012002360200200320153b01cc152003200aa722013602c415200341b1c5cb003602c015200341a8066a200341c0156a10900420034120360294132003200341a8066a36029013200341c0156a20034190136a109301200a422088210a0240024020032d00c0154101470d00200341c80a6a4200370300200341c00a6a4200370300200341b80a6a4200370300200342003703b00a0c010b200341c80a6a200341d9156a290000370300200341c00a6a200341d1156a290000370300200341b80a6a200341c9156a290000370300200320032900c1153703b00a0b200aa72102200341a8066a41186a200341f0066a41186a290000370300200341a8066a41106a200341f0066a41106a290000370300200341a8066a41086a200341f0066a41086a290000370300200320032900f0063703a806200341c8066a200341b00a6a200341a8066a109104200341c0156a20032802c806220720032802d006109204200341900a6a41086a2206200341c0156a41086a290300370300200341900a6a41106a2204200341c0156a41106a290300370300200341e0106a41086a2205200341e4156a290200370300200341e0106a41106a2209200341ec156a290200370300200341e0106a41186a2208200341f4156a290200370300200341e0106a41206a2211200341fc156a290200370300200341e0106a41286a221220034184166a280200360200200320032903c0153703900a200320032902dc153703e010024020032802d8152213450d00200341b0086a41106a2004290300370300200341b0086a41086a2006290300370300200341b00e6a41086a2005290300370300200341b00e6a41106a2009290300370300200341b00e6a41186a2008290300370300200341b00e6a41206a2011290300370300200341b00e6a41286a2012280200360200200320032903900a3703b008200320032903e0103703b00e024020032802cc06450d002007102e0b200341a8046a41166a200341b0086a41106a290300220a370100200341a8046a410e6a200341b0086a41086a290300370100200341e8056a41166a2207200a370100200341e8056a41106a200341a8046a41106a290100370300200320032903b0083701ae04200341e8056a41086a200341a8046a41086a290100370300200320032901a8043703e80520034190136a41106a2206200729010037030020034190136a41086a200341e8056a410e6a290100370300200320032901ee0537039013200320133602a813200341d4136a200341d80e6a280200360200200341cc136a200341d00e6a290300370200200341c4136a200341c80e6a290300370200200341bc136a200341b00e6a41106a290300370200200341b4136a200341b00e6a41086a290300370200200341ac136a20032903b00e37020002402006280200201a470d00200341a4136a2802002017460d030b200341f00b6a410b108e040c050b024020032802cc06450d002007102e0b200341f00b6a4108108e040c050b200341f00b6a41086a20023602002003200a3703f00b0c050b0240200341b4136a2207200341d0086a412010ec08450d00200341f00b6a4109108e040c030b20034188046a200720032903901320034190136a41086a29030010fb01200341e8056a4195fec6004108108102200341a8046a41f4f3c30041091081024120102c2207450d35200342203702e410200320073602e010200341e0106a200341b00a6a41201074200320032802e010220720032802e810220610a3013703b00e200341cc156a200720066a360200200320073602c8152003200341b00e6a41086a3602c4152003200341b00e6a3602c015200341b0086a200341c0156a107c024020032802e410450d002007102e0b4120102c2207450d35200342203702b40e200320073602b00e200341b00e6a200341f0066a41201074200341e0106a20032802b00e220720032802b80e220610d803200341cc156a200720066a360200200320073602c8152003200341f0106a3602c4152003200341e0106a3602c015200341900a6a200341c0156a107c024020032802b40e450d002007102e0b20032802b808220620032802980a22046a41206a2207417f4c0d210240024020070d00410121050c010b2007102c2205450d360b200341003602c815200320073602c415200320053602c015200341c0156a200341e8056a41101074200341c0156a200341a8046a41101074200341c0156a20032802b008220720061074200341c0156a20032802900a220620041074024020032802940a450d002006102e0b024020032802b408450d002007102e0b20032802c015220720032802c81510ff01024020032802c415450d002007102e0b200341f0066a109804200341cd156a200341d0086a41086a290300370000200341d5156a200341d0086a41106a290300370000200341dd156a200341d0086a41186a290300370000200341e5156a20032903b00a370000200341ed156a200341b00a6a41086a290300370000200341f5156a200341b00a6a41106a290300370000200341fd156a200341b00a6a41186a290300370000200341033a00c415200341143a00c015200320032903d0083700c515200341a8166a201a360200200341ac166a20173602002003419d166a200341f0066a41186a29000037000020034195166a200341f0066a41106a2900003700002003418d166a200341f0066a41086a29000037000020034185166a20032900f006370000200341c0156a10fe01200341063a00f00b024020032802ac1341ffffff3f71450d0020032802a813102e0b200241ffffff3f71450d042001102e0c040b200341023a00f00b0b200d42ffffff3f83500d022018102e0c020b20032802ac1341ffffff3f71450d0020032802a813102e0b200241ffffff3f71450d002001102e0b024020032d00f00b22024106460d0020032f00f10b210120032d00f30b2107200020032902f40b370024200020073a0023200020013b0021200041206a20023a0000200041186a41003a000020004200370308200042013703000c340b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c330b200341c0156a200141046a41c80010e9081a20034190136a41286a200241286a28020036020020034190136a41206a200241206a29020037030020034190136a41186a200241186a29020037030020034190136a41106a200241106a29020037030020034190136a41086a200241086a29020037030020032002290200370390132000200341c0156a20034190136a10cf020c320b200341c0156a200141086a41a80210e9081a20034190136a41286a200241286a28020036020020034190136a41206a200241206a29020037030020034190136a41186a200241186a29020037030020034190136a41106a200241106a29020037030020034190136a41086a200241086a29020037030020032002290200370390132000200341c0156a20034190136a1080040c310b200141106a28020021232001410c6a2802002131200141086a280200211d200141066a2f0100210420012f01042107200241246a2d0000211c200241226a2f010021092002411a6a290100210b200241196a2d00002108200241186a2d00002111200241166a2f01002112200241156a2d00002113200241146a2d00002115200241106a28020021142002410c6a2802002116200241086a2802002118200241066a2f01002119200241056a2d0000211a200241046a2d00002101200241026a2f0100211720022d0001212220022d00002105200341f00b6a41026a2206200241276a2d00003a00002003200241256a2f00003b01f00b2002280228210202400240024002400240024002400240024002400240024002402007417f6a0e03000102000b024002400240024002400240024020050e03000102000b4100210441022107200121060240024020220e03000107000b4100210720012106410021040c060b41012107200121060c050b4101210441022106024020010e03020005020b41012106410121040c040b410221044102210620010e03000103000b410021060c010b410121060b0b200228020041016a221b41014d0d0b200341e4156a201c360200200341e2156a20093b0100200341da156a200b370100200341d9156a20083a0000200341d8156a20113a0000200341d6156a20123b0100200341d5156a20133a0000200341d4156a20153a0000200341d0156a2014360200200341cc156a2016360200200341c8156a20183602002002201b360200200320023602e815200320193b01c6152003201a3a00c515200320063a00c415200320173b01c215200320073a00c115200320043a00c015201d202341b0026c6a2107200341c0156a10a7052106024020230d004200210a201d21010c050b200341e0106a410472212120060d024200210a41002106201c2130201c2120201c2132201d210403402004280200211b20034190136a200441046a221e41ac0210e9081a200341c0156a201e41ac0210e9081a0240201b411c470d00200441b0026a21010c080b200341e0106a200341c0156a41ac0210e9081a200341b00e6a200341e0106a41ac0210e9081a200341800c6a200341b00e6a41ac0210e9081a2003201b3602e0102021200341800c6a41ac0210e9081a200341d0086a200341e0106a109704200341c0156a200341e0106a41b00210e9081a0240024002400240024020050e03000102000b4100211f4102211b2001211e0240024020220e03000105000b4100211b2001211e4100211f0c040b4101211b2001211e0c030b4101211f4102211e203221200240024020010e03000104000b4100211e203221200c020b4101211e203241807e71201c72222021324101211f0c020b4102211f203021204102211e02400240024020010e03000104000b4100211e0c010b203041807e71201c7221304101211e0b203021200b0b200228020041016a222441014d0d0c20022024360200200320023602b813200320203602b413200320093b01b2132003200b3701aa13200320083a00a913200320113a00a813200320123b01a613200320133a00a513200320153a00a413200320143602a0132003201636029c132003201836029813200320193b0196132003201a3a0095132003201e3a009413200320173b0192132003201b3a0091132003201f3a009013200341b00e6a200341c0156a20034190136a10dd020240024020032903b80e4201510d0020032903d008210c0c010b20032903d008220c20032903c00e220d200d200c561b210c0b427f200a200c7c220c200c200a541b210a024020032903b00e4201510d00200641016a2106200441b0026a22042007470d010c050b0b200441b0026a21010c080b200341f0066a41026a20062d00003a0000200320032f01f00b3b01f006024002400240024002400240024020050e03000102000b41002106410221070240024020220e03000107000b41002107410021060c060b410121070c050b410121062001210541022101024020050e03020005020b41012101410121060c040b41022106200121054102210120050e03000103000b410021010c010b410121010b0b200228020041016a220541014d0d0a200341e4156a201c360200200341e2156a20093b0100200341da156a200b370100200341c0156a41196a20083a0000200341c0156a41186a20113a0000200341d6156a20123b0100200341d5156a20133a0000200341d4156a220920153a0000200341c0156a41106a2014360200200341cc156a22082016360200200341c0156a41086a201836020020022005360200200320023602e815200320193b01c6152003201a3a00c515200320013a00c415200320173b01c215200320073a00c115200320063a00c01520034190136a200341c0156a10c102200341c8066a41086a220120034199136a290000370300200341c8066a41106a2207200341a1136a290000370300200341c8066a41186a220620034190136a41196a29000037030020032003290091133703c8060240024002400240024020032d0090134101460d00200341900a6a41186a2006290300220a370300200341900a6a41106a2007290300220b370300200341900a6a41086a2001290300220c370300200320032903c806220d3703900a2008200c3702002009200b370200200341dc156a200a370200200341b1c5cb003602c0152003200d3702c415200320043b01e4154112102c2201450d3d2003421237029413200320013602901320034190136a41b1c5cb004110107420034190136a200341c0156a41047241201074200320043b01e01020034190136a200341e0106a41021074200341a8066a200328029013220120032802981310b0010240200328029413450d002001102e0b20034120360294132003200341a8066a36029013200341c0156a20034190136a1093010240024020032d00c0154101470d00410021044200210a41002105410021094100210841002111410021124100211341002115410021144100211641002118410021190c010b200341d9156a290000210a200341d8156a2d00002104200341d7156a2d00002105200341d5156a2f00002109200341d4156a2d00002108200341d3156a2d00002111200341cf156a2800002112200341cb156a280000211320032800c715211520032f00c515211420032d00c415211620032d00c315211820032f00c11521190b4110102c2201450d3d200141f8f7c60036020c2001410136020820014281808080103702004110102c2207450d3d20074190f8c60036020c20074101360208200742818080801037020020012001280200417f6a2206360200024020060d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22062006280200417f6a220636020020060d002001102e0b200341f0066a41026a2201200341c0156a41026a2d00003a000020072007280200417f6a2206360200200320032f00c0153b01f006024020060d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22062006280200417f6a220636020020060d002007102e0b200341800c6a201d10970420034190136a201d41b00210e9081a200341b00a6a41026a20012d00003a0000200320032f01f0063b01b00a02400240200228020820034190136a200228020c28020c1101000d0020034180116a41023a0000200341f8106a41003a000020022002280200417f6a2201360200200342003703e810200342013703e010024020010d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b20034190136a10dc0220032903800c210a0c010b200341c0156a20034190136a41b00210e9081a200341ca0e6a200a370100200341c90e6a20043a0000200341c80e6a20053a0000200341c60e6a20093b0100200341c50e6a20083a0000200341c40e6a20113a0000200341b00e6a41106a2012360200200341bc0e6a2013360200200341b80e6a2015360200200341d50e6a20032f01b00a3b0000200341d70e6a200341b20a6a2d00003a0000200320143b01b60e200320163a00b50e200320183a00b40e200320193b01b20e20034180023b01b00e200320023602d80e200341e0106a200341c0156a200341b00e6a10dd02024020032903e8104201510d0020032903800c210a0c010b20032903800c220a200341e0106a41106a290300220b200b200a561b210a0b200320032800f9103602a8042003200341fc106a2800003600ab04200a42d0ceae3d7c220b200a54210620034188116a280200210220032903e0104201520d0120034180116a290300210c200320032800ab043600d308200320032802a8043602d008200320032802d0083602b008200320032800d3083600b308200c420888210a200328028c112101200ca72107410121040c020b20022002280200417f6a2201360200024020010d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b201d108b02201d102e4200210c410221070c020b200320032800ab043600d308200320032802a8043602d008410021040b427f200b20061b210b201d102e4201210c2004450d010b200320032800b3083600eb05200320032802b0083602e805200041276a200a4230883c0000200041256a200a4220883d00002000200a3e0021200041186a41003a0000200041106a200b3703002000200c370308200020032802e8053600192000411c6a20032800eb053600002000412c6a2001360200200041286a2002360000200041206a20073a0000200042013703000c3c0b200320032800b3083600eb05200320032802b0083602e805200041186a41003a0000200041106a200b37030020004201370308200020032802e8053600192000411c6a20032800eb05360000200042003703000c3b0b20034190136a41246a201c3a000020034190136a41226a20093b010020034190136a411a6a200b37010020034190136a41196a20083a000020034190136a41186a20113a000020034190136a41166a20123b010020034190136a41156a20133a000020034190136a41146a20153a000020034190136a41106a201436020020034190136a410c6a201636020020034190136a41086a2018360200200320193b0196132003201a3a009513200320013a009413200320173b019213200320223a009113200320053a00901320034190136a41256a20032f01f00b3b000020034190136a41276a20062d00003a0000200320023602b813200341e0106a410c6a2023360200200341e0106a41086a20313602002003201d3602e410200320034190136a3602e010200341c0156a200341e0106a10a40520032802b81322022002280200417f6a360200024020032802b81322022802000d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b20032802b81341046a22022002280200417f6a36020020032802b813220241046a2802000d002002102e0b200341d9156a2102200341c0156a41186a2d00002101200341c0156a41106a290300210a20032903c815210b024020032903c0154201520d00200320022800003602f0062003200241036a2800003600f306200341c0156a41206a280200210220032902e415210c20032802ec152107200041186a20013a0000200041106a200a3703002000200b370308200020032802f0063600192000411c6a20032800f3063600002000200736002c2000200c370024200041206a2002360000200042013703000c3b0b200320022800003602f0062003200241036a2800003600f306200041186a20013a0000200041106a200a3703002000200b370308200020032802f0063600192000411c6a20032800f306360000200042003703000c3a0b201c213041002106201c2124201c2132201d21044200210a03402004280200211b20034190136a200441046a221e41ac0210e9081a200341c0156a201e41ac0210e9081a201b411c460d03200341e0106a200341c0156a41ac0210e9081a200341b00e6a200341e0106a41ac0210e9081a200341800c6a200341b00e6a41ac0210e9081a2003201b3602e0102021200341800c6a41ac0210e9081a200341d0086a200341e0106a10970420034190136a200341e0106a41b00210e9081a0240024002400240024020050e03000102000b410021204102211b2001211e0240024020220e03000105000b4100211b2001211e410021200c040b4101211b2001211e0c030b410121204102211e203221240240024020010e03000104000b4100211e203221240c020b4101211e203241807e71201c7222242132410121200c020b41022120203021244102211e02400240024020010e03000104000b4100211e0c010b203041807e71201c7221304101211e0b203021240b0b200228020041016a221f41014d0d092002201f36020002400240200228020820034190136a200228020c28020c1101000d0020022002280200417f6a221b360200200341023a00d00e200341003a00c80e200342003703b80e200342013703b00e0240201b0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a221b201b280200417f6a221b360200201b0d002002102e0b20034190136a10dc0220032903d008210c0c010b200341c0156a20034190136a41b00210e9081a200320023602d80a200320243602d40a200320093b01d20a2003200b3701ca0a200320083a00c90a200320113a00c80a200320123b01c60a200320133a00c50a200320153a00c40a200320143602c00a200320163602bc0a200320183602b80a200320193b01b60a2003201a3a00b50a2003201e3a00b40a200320173b01b20a2003201b3a00b10a200320203a00b00a200341b00e6a200341c0156a200341b00a6a10dd02024020032903b80e4201510d0020032903d008210c0c010b20032903d008220c20032903c00e220d200d200c561b210c0b427f200a200c7c220c200c200a541b210a20032903b00e4201510d05200641016a2106200441b0026a22042007470d000b0b200721010b200341c0156a20034190136a41ac0210e9081a0c010b200441b0026a21010b024020072001460d0003402001108b022007200141b0026a2201470d000b0b02402031450d00203141b0026c450d00201d102e0b200341c8156a41063a0000200341113a00c015200341c0156a10fe0120022002280200417f6a22013602002023ad4288b0fa007e200a7c42c8b8fa067c210a20010d032002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a22013602002001450d020c030b200441b0026a21010b20034190136a41206a200341d80e6a290300220b37030020034190136a41186a200341b00e6a41206a290300220c37030020034190136a41106a200341b00e6a41186a29030037030020034190136a41086a200341b00e6a41106a290300370300200320032903b80e37039013200341c0156a41086a200c370300200341c0156a41106a200b3e0200200341113a00c015200320063602c415200641016aad4288b0fa007e210b200341c0156a10fe01024020072001460d0003402001108b022007200141b0026a2201470d000b0b200b200a7c210a02402031450d00203141b0026c450d00201d102e0b200a42c8b8fa067c210a20022002280200417f6a220136020020010d012002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d010b2002102e0b200320032800eb063600eb05200320032802e8063602e805200041186a41003a0000200041106a200a37030020004201370308200020032802e8053600192000411c6a20032800eb05360000200042003703000c310b00000b200341e8056a41026a22062001410f6a2d00003a0000200341800c6a41086a2204200141206a290200370300200341800c6a41106a2205200141286a290200370300200320012f000d3b01e8052003200141186a2902003703800c200141c8006a290300210d200141c0006a290300210e2002411a6a290100210c200241196a2d00002113200241186a2d00002115200241166a2f01002114200241156a2d00002116200241146a2d00002118200241126a2f01002119200241116a2d0000211a200241106a2d000021172002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f01002124200141d0006a2802002131200141146a2802002108200141106a28020021112001410c6a2d00002109200141386a290300210b200141306a290300210a2002280228210720022d0001211220022d0000210202400240024002400240200141086a2802000e050001020304000b200341c0156a41146a4101360200200342013702c4152003419cc3cb003602c015200341043602e410200341a4a7c7003602e0102003200341e0106a3602d015200341c0156a41aca7c7001044000b20072007280200417f6a220136020002400240024002400240200241ff01710d00024020010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b201241ff01714101460d02200341c8066a41186a200341a8066a41186a290300370300200341c8066a41106a200341a8066a41106a290300370300200341c8066a41086a200341a8066a41086a290300370300200320032903a8063703c8060c010b024020010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b200341c8066a41186a200341a8066a41186a290300370300200341c8066a41106a200341a8066a41106a290300370300200341c8066a41086a200341a8066a41086a290300370300200320032903a8063703c8060b200341023a0090130c010b2003201f3a00af06200320203a00ae06200320213b01ac06200320223a00ab06200320233a00aa06200320243b01a8062003201a3a00b706200320173a00b6062003201b3b01b4062003201c3a00b3062003201d3a00b2062003201e3b01b006200320133a00bf06200320153a00be06200320143b01bc06200320163a00bb06200320183a00ba06200320193b01b8062003200c3703c006200341c8066a41186a2202200c370300200341c8066a41106a220120032903b806370300200341c8066a41086a220720032903b006370300200320032903a8063703c806200341900a6a41186a22062002290300370300200341900a6a41106a22022001290300370300200341900a6a41086a22012007290300370300200320032903c8063703900a200341c0156a41186a2006290300370300200341c0156a41106a2002290300370300200341c0156a41086a2001290300370300200320032903900a3703c01520034190136a200341c0156a10b30320032d0090134106460d010b20032802901321022000200329029413370024200041206a2002360000200041186a41003a000020004200370308200042013703000c330b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c320b200341a8046a41026a20062d00003a0000200341e0106a41086a2004290300370300200341e0106a41106a200529030037030020072007280200417f6a2201360200200320032f01e8053b01a804200320032903800c3703e0100240024002400240024002400240200241ff01710d00024020010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b41012102201241ff01714101470d01200341d0086a41026a2201200341a8046a41026a2d00003a000020034190136a41086a2207200341e0106a41086a29030037030020034190136a41106a200341e0106a41106a290300370300200320032f01a8043b01d008200320032903e0103703901320090e03020403040b20010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b41022102200341023a00b00a20094102470d0302402008450d002011102e0b410221020c030b200341f0066a41026a20012d00003a0000200341b00e6a41086a2007290300370300200341b00e6a410d6a20034190136a410d6a290000370000200320032f01d0083b01f00620032003290390133703b00e410021020c010b2008450d002011102e0b200341bb066a200341b00e6a41086a290300370000200341a8066a41186a2201200341bd0e6a290000370000200320032f01f0063b01a806200320083600af06200320113600ab06200320032903b00e3700b3062003200341f0066a41026a2d00003a00aa0602402002450d0041012102200341013a00b00a0c010b200341c0156a41186a2001290300370300200341c0156a41106a200341a8066a41106a290300370300200341c0156a41086a200341a8066a41086a290300370300200320032903a8063703c015200341b00a6a200341c0156a10b30320032d00b00a22024106460d010b20032f00b10a210120032d00b30a2107200020032902b40a370024200020073a0023200020013b0021200041206a20023a0000200041186a41003a000020004200370308200042013703000c320b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c310b200341a8046a41026a20062d00003a0000200341b00e6a41086a2004290300370300200341b00e6a41106a2005290300370300200320032f01e8053b01a804200320032903800c3703b00e20072007280200417f6a220136020002400240024002400240024002400240200241ff01710d00024020010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b201241ff01714101470d022003201f3a00cf06200320203a00ce06200320213b01cc06200320223a00cb06200320233a00ca06200320243b01c8062003201a3a00d706200320173a00d6062003201b3b01d4062003201c3a00d3062003201d3a00d2062003201e3b01d006200320133a00df06200320153a00de06200320143b01dc06200320163a00db06200320183a00da06200320193b01d8062003200c3703e006200341900a6a41186a2202200c370300200341900a6a41106a220120032903d806370300200341900a6a41086a220720032903d006370300200320032903c8063703900a200341e0106a41186a2002290300370300200341e0106a41106a2001290300370300200341e0106a41086a2007290300370300200320032903900a3703e010200a4280a094a58d1d544100200b501b450d01410321020c040b024020010d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b200341900a6a41186a200341c8066a41186a290300370300200341900a6a41106a200341c8066a41106a290300370300200341900a6a41086a200341c8066a41086a290300370300200320032903c8063703900a0c020b200341d0086a41026a2201200341a8046a41026a2d00003a0000200341c0156a41086a200341b00e6a41086a290300370300200341c0156a41106a200341b00e6a41106a290300370300200320032f01a8043b01d008200320032903b00e3703c0154101210202400240024020090e03000201020b200341f0066a41026a20012d00003a0000200341b00a6a41086a200341c0156a41086a290300370300200341b00a6a410d6a200341c0156a410d6a290000370000200320032f01d0083b01f006200320032903c0153703b00a410021020c010b2008450d002011102e0b200341bb066a200341b00a6a41086a290300370000200341a8066a41186a2201200341bd0a6a290000370000200320032f01f0063b01a806200320083600af06200320113600ab06200320032903b00a3700b3062003200341f0066a41026a2d00003a00aa060240024020020d0020034190136a41186a200129030037030020034190136a41106a200341a8066a41106a29030037030020034190136a41086a200341a8066a41086a290300370300200320032903a80637039013200341c0156a20034190136a10b10320032802c015220120032802c815108f022102024020032802c415450d002001102e0b2002450d014194a4c700ad210a4280808080f002210b4101210741192106410321020c050b4200210a410121024200210b0c050b200341c0156a200341e0106a20034190136a200a200b410110ca02024020032d00c01522024106470d00200341c0156a20034190136a10b10320032802c015220120032802c815108f022102024020032802c415450d002001102e0b2002450d06200341c8156a411736020020034194a4c7003602c415200341013a00c21520034183323b01c01541bca7c7004137200341c0156a41f4a7c7004184a8c700103e000b20032d00c315210120032d00c215210720032d00c115210620032902c415220a42808080807083210b0c040b200341900a6a41186a200341c8066a41186a290300370300200341900a6a41106a200341c8066a41106a290300370300200341900a6a41086a200341c8066a41086a290300370300200320032903c8063703900a0b410221020b4102210741ceeac700ad210a42808080809001210b4119210620094102470d002008450d002011102e41ceeac700ad210a0b0b200020013a0023200020073a0022200020063a0021200041206a20023a0000200041186a41003a0000200042003703082000200b42808080807083200a42ffffffff0f8384370024200042013703000c310b200341c0156a41186a2202200d3703002003200e3703d0152003200a3703c015200320313602e0152003200b3703c81520034190136a200341c0156a10b203200220034190136a41186a290300370300200341c0156a41106a20034190136a41106a290300370300200341c0156a41086a20034190136a41086a29030037030020032003290390133703c015200341b00a6a200341c0156a10b303200041186a41003a000020004200370308200020032800e8063600192000411c6a200341eb066a280000360000200042003703000c300b200141f0006a2903002110200141e8006a2903002128200141e0006a290300210c200141d8006a290300210f200141f8006a2802002114200ba72113200aa72101200a422088a72115200341a8046a41026a20062d00003a0000200341b00e6a41086a2004290300370300200341b00e6a41106a200529030037030020072007280200417f6a2206360200200320032f01e8053b01a804200320032903800c3703b00e0240024002400240024002400240200241ff01710d00024020060d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b41022102201241ff01710d0141032102200f4280a094a58d1d544100200c501b0d01200b422088a721062001410876210241012107200141ff01710e03020403040b4102210220060d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22062006280200417f6a220636020020060d002007102e0b200141ff01714102470d032013450d032015102e0c030b410021070c010b02402013450d002015102e0b0b200341df066a200d3700002003200e3700d706200320313a00e706200320063600d306200320133600cf06200320153600cb06200320023b01c806200320024110763a00ca06024020070d00200341e0106a41186a200341c8066a41186a290300370300200341e0106a41106a200341c8066a41106a290300370300200341e0106a41086a200341c8066a41086a290300370300200320032903c8063703e010200341d0086a41026a2201200341a8046a41026a2d00003a0000200320032f01a8043b01d008200341c0156a41086a2207200341b00e6a41086a290300370300200341c0156a41106a200341b00e6a41106a290300370300200320032903b00e3703c0154101210202400240024020090e03000201020b200341f0066a41026a20012d00003a0000200341b00a6a41086a2007290300370300200341b00a6a410d6a200341c0156a410d6a290000370000200320032f01d0083b01f006200320032903c0153703b00a410021020c010b2008450d002011102e0b200341bb066a200341b00a6a41086a290300370000200341a8066a41186a200341bd0a6a290000370000200320032f01f0063b01a806200320083600af06200320113600ab06200320032903b00a3700b3062003200341f0066a41026a2d00003a00aa060240024020020d0020034190136a41186a200341a8066a41186a29030037030020034190136a41106a200341a8066a41106a29030037030020034190136a41086a200341a8066a41086a290300370300200320032903a80637039013200341c0156a200341e0106a10b10320032802c015220120032802c815108f022102024020032802c415450d002001102e0b2002450d014194a4c700ad210a4280808080f002210b4101210141192107410321020c040b4200210a410121024200210b0c030b200341c0156a20034190136a200341e0106a200f200c410110ca020240024020032d00c01522024106470d00200341c0156a200341e0106a10b10320032802c015220120032802c815108f022102024020032802c415450d002001102e0b2002450d01200341c8156a411736020020034194a4c7003602c415200341013a00c21520034183323b01c01541bca7c7004137200341c0156a41f4a7c7004194a8c700103e000b20032d00c315210620032d00c215210120032d00c115210720032902c415220a42808080807083210b0c030b200341c0156a41186a22022010370300200320283703d0152003200f3703c015200320143602e0152003200c3703c815200341e0106a200341c0156a10b2032002200341e0106a41186a290300370300200341c0156a41106a200341e0106a41106a290300370300200341c0156a41086a200341e0106a41086a290300370300200320032903e0103703c015200341b00a6a200341c0156a10b303200041186a41003a000020004200370308200020032800e8063600192000411c6a200341eb066a280000360000200042003703000c320b410121020b4102210141ceeac700ad210a42808080809001210b41192107024020094102470d002008450d002011102e41ceeac700ad210a0b0b200020063a0023200020013a0022200020073a0021200041206a20023a0000200041186a41003a0000200042003703082000200b42808080807083200a42ffffffff0f8384370024200042013703000c2f0b200341a4066a41026a22192001410b6a2d00003a00002003419c066a41046a221a2001411c6a2d00003a0000200320012f00093b01a4062003200141186a28000036029c06200141286a290300210a200141206a290300210c200141086a2d000021042001410c6a2800002111200141106a2800002105200141146a2800002118200141306a290300210b200141386a290300210d200141c0006a290300210e200141c8006a2d0000211b20012d001d211720012f011e211e200341f00b6a41086a221f200141da006a2f00003b0100200341900a6a41086a2221200141e8006a2802003602002003200141cc006a280000360097062003200128004936029406200320012900523703f00b2003200141e0006a2903003703900a200141d0006a2d0000211c200141dc006a2802002120200141ec006a2802002122200141f0006a2802002123200141f4006a280200212420012d0051211d2003200241166a2901003703b00a20032002411c6a2901003701b60a200241246a2802002112200241156a2d00002113200241146a2d00002115200241106a28020021072002410c6a2802002108200241086a2802002109200241046a2802002106200241026a2f010021142002280228210120022d0001211620022d0000210202400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020040e06000102030405000b200341c0156a41146a4101360200200342013702c4152003419cc3cb003602c015200341043602ac0420034194c3cb003602a8042003200341a8046a3602d015200341c0156a41e0f3c0001044000b200341ff106a200a3c0000200341f3106a201a2d00003a00002003200c3700f710200320192d00003a00e210200320032f01a4063b01e010200320183600eb10200320053600e710200320113600e3102003200328029c063600ef102003201e3b00f510200320173a00f4102003200a4238883c00c6152003200a4228883d01c4152003200a4208883e02c0152003201b3a00df152003200e3700d7152003200d3700cf152003200b3700c715200341e3156a2003280097063600002003201d3a00e8152003201c3a00e71520032003280294063602e015200341f1156a201f2f01003b0000200320203600f315200320032903f00b3700e915200341ff156a20212f01003b0000200320032903900a3700f71520034190136a41156a20133a000020034190136a41146a20153a000020034190136a41106a200736020020034190136a410c6a200836020020034190136a41086a200936020020034190136a41246a20123602002003200636029413200320143b019213200320163a009113200320023a00901320034190136a41166a20032903b00a37010020034190136a411c6a20032901b60a370100200320013602b81320034190136a10bb060d04200341f0066a200341e0106a10e00220034190136a200341c0156a20032802f006220220032802f80641d4e2cc00410010e10220032d0090134101470d0520032003280095133600b30820032003280192133602b008200320032800b3083600eb05200320032802b0083602e805200320032d0091133a00800c200320032802e8053600810c200320032800eb053600840c20034199136a2d00002101200341a1136a28000021072003419a136a350100210a2003419e136a330100210b2003418f0c6a200341a0136a3100003c00002003418d0c6a200b3d00002003200a3e00890c200320073602900c200320013a00880c20034190136a200341800c6a10ab03200328029013220720032802981310e40241ff017121010240200328029413450d002007102e0b024020014102460d00200341a8046a410510b0030c140b200341b00e6a41106a200341800c6a41106a280200360200200341b00e6a41086a200341800c6a41086a290300370300200320032903800c3703b00e20034190136a41186a200341e0106a41186a29030037030020034190136a41106a200341e0106a41106a29030037030020034190136a41086a200341e0106a41086a290300370300200320032903e01037039013200341d0086a200341b00e6a20034190136a10ac03024020032d00d00822014106470d00024020032802f406450d002002102e0b200341063a00a8040c160b20032d00d108210720032d00d208210620032d00d3082104200320032902d4083702ac04200320043a00ab04200320063a00aa04200320073a00a904200320013a00a8040c130b200341800c6a41026a20192d00003a0000200341b00e6a41046a201a2d00003a0000200320032f01a4063b01800c2003200328029c063602b00e20032003280294063602c80620032003280097063600cb06200341b0086a41086a201f2f01003b0100200320032903f00b3703b008200341c0156a41156a20133a0000200341c0156a41146a20153a0000200341c0156a41106a2007360200200341c0156a410c6a2008360200200341c0156a41086a2009360200200341c0156a41246a2012360200200320063602c415200320143b01c215200320163a00c115200320023a00c015200341c0156a41166a20032903b00a370100200341c0156a411c6a20032901b60a370100200320013602e815200341c0156a10a7050d05200341c0066a22024200370300200341a8066a41106a22014200370300200341a8066a41086a22074200370300200342003703a806200341e8056a41b6d1cc0041061081022007200341e8056a41086a2204290300370300200320032903e8053703a806200341a8046a41e9f9c00041051081022002200341a8046a41086a2209290300370300200120032903a804370300200341d8036a200341a8066a412010f802200341d8036a41106a290300210f20032903e003211020032802d8032106200242003703002001420037030020074200370300200342003703a806200341e8056a41b6d1cc00410610810220072004290300370300200320032903e8053703a806200341a8046a41e9f9c000410510810220022009290300370300200120032903a80437030020032010420020061b2210200c7c22283703c0152003200f420020061b200a7c2028201054ad7c3703c815200341a8066a4120200341c0156a411010b201200341d3156a200341b40e6a2d00003a00002003200341820c6a2d00003a00c215200320032f01800c3b01c015200320183600cb15200320053600c715200320113600c315200320032802b00e3600cf15200341e8056a41b6d1cc004106108102200341a8046a41b6d1cc0041061081024114102c2202450d402003421437029413200320023602901320034190136a200341c0156a411410742003280298132202417f4c0d2c20032802901321010240024020020d00410121070c010b2002102c2207450d410b20072001200210e90821070240200328029413450d002001102e0b200241206a2201417f4c0d2c2001102c2206450d4020034100360298132003200136029413200320063602901320034190136a200341e8056a4110107420034190136a200341a8046a4110107420034190136a20072002107402402002450d002007102e0b200328029013210220032802981321012003200a3703c8152003200c3703c01520022001200341c0156a411010b2010240200328029413450d002002102e0b0240200b4201520d00200341c0156a41146a20032800cb06360000200341e2156a200341b8086a2f01003b01002003201b3a00d0152003200e3703c8152003200d3703c015200320032802c8063600d1152003201d3a00d9152003201c3a00d815200320032903b0083701da15200320203602e4152003200341820c6a2d00003a009213200320032f01800c3b0190132003201836009b1320032005360097132003201136009313200341a3136a200341b40e6a2d00003a0000200320032802b00e36009f13200341e8056a41b6d1cc004106108102200341a8046a41bcdbc80041071081024114102c2202450d41200342143702e410200320023602e010200341e0106a20034190136a4114107420032802e8102202417f4c0d2d20032802e01021010240024020020d00410121070c010b2002102c2207450d420b20072001200210e9082107024020032802e410450d002001102e0b200241206a2201417f4c0d2d2001102c2206450d41200341003602e810200320013602e410200320063602e010200341e0106a200341e8056a41101074200341e0106a200341a8046a41101074200341e0106a20072002107402402002450d002007102e0b20032802e010220220032802e810200341c0156a10ba0520032802e410450d002002102e0b0240201741ff017122024102460d00200341d3156a200341b40e6a2d00003a0000200320032f01800c3b01c015200320183600cb15200320053600c715200320113600c315200320032802b00e3600cf152003200341800c6a41026a2d00003a00c21520034190136a200341c0156a10e30220032802901321012003280298132107200341003602c815200342013703c0150240024020024101460d00200341003a00a804200341c0156a200341a8046a410110740c010b200341013a00a804200341c0156a200341a8046a410110740b2001200720032802c015220220032802c81510b201024020032802c415450d002002102e0b200328029413450d002001102e0b200041186a41003a000020004200370308200020032800e8063600192000411c6a200341eb066a280000360000200042003703000c430b200341ff106a200a3c0000200341f3106a201a2d00003a00002003200c3700f710200320192d00003a00e210200320032f01a4063b01e010200320183600eb10200320053600e710200320113600e3102003200328029c063600ef102003201e3b00f510200320173a00f4102003200a4238883c00c6152003200a4228883d01c4152003200a4208883e02c0152003201b3a00df152003200e3700d7152003200d3700cf152003200b3700c715200341e3156a2003280097063600002003201d3a00e8152003201c3a00e71520032003280294063602e015200341f1156a201f2f01003b0000200320203600f315200320032903f00b3700e915200341ff156a20212f01003b0000200320032903900a3700f71520034190136a41156a20133a000020034190136a41146a20153a000020034190136a41106a200736020020034190136a410c6a200836020020034190136a41086a200936020020034190136a41246a20123602002003200636029413200320143b019213200320163a009113200320023a00901320034190136a41166a20032903b00a37010020034190136a411c6a20032901b60a370100200320013602b81320034190136a10bb060d05200341d0086a200341e0106a10e00220034190136a200341c0156a20032802d008220220032802d8082022202410e10220032d0090134101470d0620032003280095133600b30820032003280192133602b008200320032800b3083600eb05200320032802b0083602e805200320032802e8053602a804200320032800eb053600ab0420034199136a2d00002107200341a1136a28000021062003419a136a350100210a2003419e136a330100210b20032d00911321042003419f136a200341a0136a310000220c3c00002003419d136a200b3d0000200320043a0090132003200a3e009913200320063602a013200320073a009813200320032802a80436009113200320032800ab0436009413200341b00e6a20034190136a10e30220032802b00e220520032802b80e10e40241ff01712101024020032802b40e450d002005102e0b024020014102460d00024041c40141c70120011b2024470d0041abcecc0041efcfcc0020011b2022202410ec08450d010b200341f0066a410510b0030c0f0b2003200a200b200c4210868442208684220a3e00b90e200341bf0e6a200a4230883c0000200341bd0e6a200a4220883d0000200320043a00b00e200320032802a8043600b10e200320032800ab043600b40e200320063602c00e200320073a00b80e20034190136a41186a200341e0106a41186a29030037030020034190136a41106a200341e0106a41106a29030037030020034190136a41086a200341e0106a41086a290300370300200320032903e01037039013200341800c6a200341b00e6a20034190136a10ac03024020032d00800c22014106470d00024020032802d408450d002002102e0b200341063a00f0062023450d112022102e0c110b20032d00810c210720032d00820c210620032d00830c2104200320032902840c3702f406200320043a00f306200320063a00f206200320073a00f106200320013a00f0060c0e0b200341c0156a41156a20133a0000200341c0156a41146a20153a0000200341c0156a41106a2007360200200341c0156a410c6a2008360200200341c0156a41086a2009360200200341c0156a41166a20032903b00a370100200341c0156a411c6a20032901b60a370100200341c0156a41246a2012360200200320063602c415200320143b01c215200320163a00c115200320023a00c015200320013602e81520034190136a200341c0156a10c102200341a8066a41086a20034190136a41096a290000370300200341a8066a41106a20034190136a41116a290000370300200341a8066a41186a200341a9136a29000037030020032003290091133703a80620032d0090134101460d06200341e0106a41186a200341a8066a41186a290300370300200341e0106a41106a200341a8066a41106a290300370300200341e0106a41086a200341a8066a41086a290300370300200320032903a8063703e01020034190136a200341e0106a108103200341c0156a2003280290132202200328029813108203200320032801c2153602b008200320032800c5153600b3080240024020032d00c0154101470d00200341ca156a350100200341ce156a330100200341c0156a41106a3100004210868442208684210a200341c0156a41116a2800002101200341c0156a41096a2d0000210720032d00c1152106200320032800b3083600eb05200320032802b0083602e8050240200328029413450d002002102e0b200320032800eb053600ab04200320032802e8053602a804200320032802a8043602d008200320032800ab043600d3082003200a3e00c915200341cf156a200a4230883c0000200341cd156a200a4220883d0000200320063a00c015200320032802d0083600c115200320032800d3083600c415200320013602d015200320073a00c81520034190136a200341c0156a10e302200328029013220420032802981310e40241ff017121020240200328029413450d002004102e0b20024102460d01024041c40141c70120021b2018470d0041abcecc0041efcfcc0020021b2011201810ec08450d020b200341800c6a410510b0030c0d0b0240200328029413450d002002102e0b200341800c6a410310b0030c0c0b2003200a3e0099132003419f136a200a4230883c00002003419d136a200a4220883d0000200320063a009013200320032802d00836009113200320032800d30836009413200320013602a013200320073a009813200341c0156a41186a200341e0106a41186a290300370300200341c0156a41106a200341e0106a41106a290300370300200341c0156a41086a200341e0106a41086a290300370300200320032903e0103703c015200341b00e6a20034190136a200341c0156a10ac03024020032d00b00e22024106470d00200341c0156a200341e0106a10810320032802c015220220032802c81510ff01024020032802c415450d002002102e0b200341063a00800c2005450d0d2011102e0c0d0b20032d00b10e210120032d00b20e210720032d00b30e2106200320032902b40e3702840c200320063a00830c200320073a00820c200320013a00810c200320023a00800c0c0b0b200341930c6a201a2d00003a0000200320192d00003a00820c200320032f01a4063b01800c2003201836008b0c200320053600870c200320113600830c2003200328029c0636008f0c200341b00e6a410b6a200a3700002003200c3700b30e2003201e3b00b10e200320173a00b00e2003200b3c00c30e2003200b4230883d01cc062003200b4210883e02c8062003201b3a00de062003200e3701d6062003200d3701ce06200341e2066a2003280097063600002003201d3a00e7062003201c3a00e60620032003280294063600df06200320032901b60a3701c615200320032903b00a3703c0150240200241ff017122044101470d0020012001280200417f6a220236020020032f01cc15210420032902c415210a20032d00c315210520032d00c215211120032f01c0152118024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200641ff01710d072009410274200841036c490d070c090b20044103460d0820032801ca15210520032f01c815211120032903c015210c0c070b200341023a00a8040c0f0b200341a8046a410110b0030c0d0b20004200370024200041206a41023a0000200041186a41003a000020004200370308200042013703000c3d0b200341023a00f0060c090b200341f0066a410110b0030c070b200341023a00800c0c040b200320043b01cc15200320053a00c315200320113a00c215200320183b01c0152003200a3702c41520032801ca15210520032903c015210c4110102c2204450d36200441f8f7c60036020c410121022004410136020820044281808080103702004110102c2201450d36200a422088a7211120014190f8c60036020c20014101360208200142818080801037020020042004280200417f6a221836020020180d002004280208200428020c2802001103000240200428020c280204450d002004280208102e0b200441046a22182018280200417f6a221836020020180d002004102e0b200341e4156a2012360200200341c0156a41206a2005360200200341de156a20113b0100200341d6156a200c370100200341d5156a20133a0000200341d4156a20153a0000200341d2156a20074110763b0100200341d1156a20074108763a0000200341c0156a41106a20073a0000200341cc156a2008360200200341c0156a41086a2009360200200320013602e815200320063602c415200320143b01c215200320163a00c115200320023a00c015200341c0156a10a7050d010b200341c0156a200341800c6a10e202200341f0036a20032802c015220220032802c815220110f80220034180046a290300210c20032903f803210d024020032903f003220a4201520d002002200110ff010b200aa72101024020032802c415450d002002102e0b02402001450d0020034190136a200341b00e6a10e202200328029813210120032802901321022003200c3703c8152003200d3703c01520022001200341c0156a411010b201200328029413450d002002102e0b20034190136a200341800c6a10ad03200341c0156a2003280290132202200328029813220710ae03024020032903c01542015222010d002002200710ff010b200320032800d9153602f0062003200341dc156a2800003600f3060240024020010d00200341e0156a2d00002101200341d8156a2d00002107200341d0156a290300210a20032802ec15210620032902e415210c20032d00e315210420032d00e215210520032d00e115210920032903c815210d200320032800f3063600eb06200320032802f0063602e8060240200328029413450d002002102e0b200341d4156a20032800eb06360000200320073a00d0152003200a3703c8152003200d3703c015200320032802e8063600d115200320063602e4152003200c3702dc15200320043a00db15200320053a00da15200320093a00d915200320013a00d81520034190136a200341b00e6a10ad032003280290132202200328029813200341c0156a10ba05200328029413450d012002102e0c010b200328029413450d002002102e0b200341c0156a200341800c6a10ab03024020032802c015220120032802c815220710e40241ff017122024102460d002001200710ff010b024020032802c415450d002001102e0b024020024102460d0020034190136a200341b00e6a10ab0320032802981321072003280290132101200341003602c815200342013703c0150240024020024101460d00200341003a00a804200341c0156a200341a8046a410110740c010b200341013a00a804200341c0156a200341a8046a410110740b2001200720032802c015220220032802c81510b201024020032802c415450d002002102e0b200328029413450d002001102e0b200341a8066a41186a2202200341c8066a41186a290300370300200341a8066a41106a2201200341c8066a41106a290300370300200341a8066a41086a2207200341c8066a41086a290300370300200320032903c8063703a8060240200b4280fe0383428002520d00200341c0156a41186a2002290300370300200341c0156a41106a2001290300370300200341c0156a41086a2007290300370300200320032903a8063703c015200341f0066a200341c0156a10810320034190136a20032802f006220220032802f80622011082030240024020032d0090134101460d00200341003a00e0100c010b200341e0106a41136a20034190136a41136a2f00003b0000200341e0106a410b6a20034190136a410b6a290000370000200341e0106a41096a20034190136a41096a2f00003b000020032003290091133700e110200341013a00e010200341e0106a4101722207200341800c6a411410ec080d00200720032903b00e370000200741086a200341b00e6a41086a290300370000200741106a200341b00e6a41106a280200360000200341013a00e0100b20034190136a410d6a200341e0106a410d6a29000037000020034190136a41086a200341e0106a41086a290300370300200320032903e010220a3703901302400240200aa741ff01714101460d002002200110ff010c010b4114102c2207450d36200342143702d408200320073602d008200341d0086a20034190136a410172411410742002200120032802d008220720032802d80810b20120032802d408450d002007102e0b20032802f406450d002002102e0b200320032802e8053602b008200320032800eb053600b308200041186a41013a000020004200370308200020032802b0083600192000411c6a20032800b308360000200042003703000c370b200320032802e8053602b008200320032800eb053600b308200041186a41003a000020004200370308200020032802b0083600192000411c6a20032800b308360000200041206a41023a0000200042013703000c360b02402005450d002011102e0b20032d00800c22024106460d0020032f00810c210120032d00830c2107200020032902840c370024200020073a0023200020013b0021200041206a20023a0000200041186a41003a000020004200370308200042013703000c350b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c340b20032802d408450d002002102e0b02402023450d002022102e0b20032d00f00622024106460d0020032f00f106210120032d00f3062107200020032902f406370024200020073a0023200020013b0021200041206a20023a0000200041186a41003a000020004200370308200042013703000c320b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c310b024020032802f406450d002002102e0b20032d00a8044106460d010b20032802a8042102200020032902ac04370024200041206a2002360000200041186a41003a000020004200370308200042013703000c2f0b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c2e0b200341d0086a41086a2222200141206a290300370300200341d0086a41106a2223200141286a2903003703002003200141186a2903003703d008200241246a2801002120200241226a2f010021212002411a6a290100210a200241196a2d00002115200241186a2d00002114200241166a2f01002116200241156a2d00002118200241146a2d00002119200241126a2f0100211a200241116a2d00002117200241106a2d0000211b2002410e6a2f010021052002410d6a2d000021092002410c6a2d000021082002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f0100211c200241056a2d0000211d200241046a2d0000210441022124200241026a2f0100211e2001410c6a28020021062002280228210720022d0001211f20022d000021020240024002400240200141086a2802000e0400010203000b200341c0156a41146a4101360200200342013702c4152003419cc3cb003602c015200341043602e41020034194c3cb003602e0102003200341e0106a3602d015200341c0156a4184ccc2001044000b200141386a290300210b200141306a290300210c200141146a2802002124200141106a2802002101200341b00e6a41106a2023290300370300200341b00e6a41086a2022290300370300200320032903d0083703b00e200341c0156a41246a2020360200200341c0156a41226a20213b0100200341c0156a411a6a200a370100200341c0156a41196a20153a0000200341c0156a41186a20143a0000200341c0156a41166a20163b0100200341c0156a41156a20183a0000200341c0156a41146a20193a0000200341c0156a41126a201a3b0100200341c0156a41116a20173a0000200341c0156a41106a201b3a0000200341c0156a410e6a20053b0100200341c0156a410d6a20093a0000200341c0156a410c6a20083a0000200341c0156a410a6a20113b0100200341c0156a41096a20123a0000200341c0156a41086a20133a0000200320073602e8152003201c3b01c6152003201d3a00c515200320043a00c4152003201e3b01c2152003201f3a00c115200320023a00c01520034190136a200341c0156a10c10241012102024002400240024020032d0090134101460d0020034190136a41086a280200210720034190136a410c6a280200210420034190136a41106a280200210520034190136a41146a290200210a20032d009113210920032f019213210820032802941321112003200341ac136a35020020034190136a41206a31000042208684220d3e00fb10200341ff106a200d4220883c00002003200a3700f310200320053600ef10200320043600eb10200320073600e710200320113600e310200320083b00e110200320093a00e010200341c0156a41106a200341b00e6a41106a290300370300200341c0156a41086a2204200341b00e6a41086a290300370300200320032903b00e3703c01520064108762107024002400240200641ff01710e03000201020b20034190136a410d6a200341c0156a410d6a29000037000020034190136a41086a2004290300370300200320032903c01537039013410021020c010b2024450d002001102e0b200341a30a6a20034190136a41086a290300370000200341900a6a41186a22062003419d136a290000370000200320243600970a200320013600930a200320032903901337009b0a200320073b01900a200320074110763a00920a20020d02200341f0066a41186a2006290300370300200341f0066a41106a2206200341900a6a41106a290300370300200341f0066a41086a2204200341900a6a41086a290300370300200320032903900a3703f00620034198036a200c200b42c0843d420010e60820034188036a200c200b42c0843d420010e708200341f8026a20032903880320034188036a41086a29030042d08603420010e808200341c0156a200341e0106a20032903f802220d200329039803220a421480a7200a42d086037e42c0843d8242a0c21e566aad7c220a4280a094a58d1d200a4280a094a58d1d56200341f8026a41086a290300200a200d54ad7c220a420052200a501b22021b220d200a420020021b220a10c30220032d00c0154106460d014280808080c003210a410321020c030b410221020240200641ff01714102460d004200210a0c030b4200210a410221022024450d022001102e0c020b200341c8066a41186a22024200370300200341c8066a41106a22014200370300200341c8066a41086a22074200370300200342003703c806200341e8056a41bad7c70041081081022007200341e8056a41086a2205290300370300200320032903e8053703c806200341a8046a41e4afc900410d1081022002200341a8046a41086a2209290300370300200120032903a804370300200341f0026a200341c8066a4120108e0220032802f402210820032802f0022111200242003703002001420037030020074200370300200342003703c806200341e8056a41bad7c700410810810220072005290300370300200320032903e8053703c806200341a8046a41e4afc900410d10810220022009290300370300200120032903a80437030020032008410020111b220241016a3602c015200341c8066a4120200341c0156a410410b201200341c0156a41186a200a370300200341f8156a200341e0106a41186a290300370300200341f0156a200341e0106a41106a290300370300200341e8156a200341e0106a41086a29030037030020034188166a200429030037030020034190166a200629030037030020034198166a200341f0066a41186a2903003703002003200b3703c8152003200c3703c0152003200d3703d015200320032903e0103703e015200320032903f00637038016200341b00a6a200210d60320032802b80a210720032802b00a2101200341003602880c200342013703800c200341800c6a200341c0156a41206a412010742003200b370398132003200c37039013200341800c6a20034190136a41101074200341800c6a20034180166a412010742003200a370398132003200d37039013200341800c6a20034190136a411010742001200720032802800c220620032802880c10b201024020032802840c450d002006102e0b024020032802b40a450d002001102e0b200341cc156a2002360200200341c8156a41003a00002003410e3a00c015200341c0156a10fe01200041186a41003a000020004200370308200020032800e8063600192000411c6a200341eb066a280000360000200042003703000c310b4200210a410121020b200041133b002120004200370308200041206a20023a0000200041186a41003a00002000200a4280808080f0038341d0ffc300ad84370024200042013703000c2f0b0240200241ff01710d0020072007280200417f6a2202360200024020020d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b2003200a3703c006200320153a00bf06200320143a00be06200320163b01bc06200320183a00bb06200320193a00ba062003201a3b01b806200320173a00b7062003201b3a00b606200320053b01b406200320093a00b306200320083a00b206200320113b01b006200320123a00af06200320133a00ae062003201c3b01ac062003201d3a00ab06200320043a00aa062003201e3b01a8060240201f41ff01710d00410321020c010b4110102c2201450d2c200141f8f7c60036020c2001410136020820014281808080103702004110102c2207450d2c20074190f8c60036020c20074101360208200742818080801037020020012001280200417f6a22153602004100210220150d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22152015280200417f6a221536020020150d002001102e0b0240024002400240200241ff0171417f6a0e03000102010b20072007280200417f6a2202360200024020020d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b0240200441ff01710d00201141107420124108747220137241017420054110742009410874722008724b0d020b4110102c2202450d2e200241f8f7c60036020c2002410136020820024281808080103702004110102c2207450d2e20074190f8c60036020c20074101360208200742818080801037020020022002280200417f6a220136020020010d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b20072007280200417f6a22013602004200210a4102210202402001450d004200210b0c020b2007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22012001280200417f6a220136020002402001450d004200210b0c020b2007102e4200210b0c010b200341e8056a41bad7c7004108108102200341a8046a41dbafc9004109108102200320063602b0082003200341b0086a410410a3013703900a200341cc156a200341b0086a41046a3602002003200341900a6a41086a3602c4152003200341b0086a3602c8152003200341900a6a3602c015200341b00e6a200341c0156a107c20032802b80e220741206a2202417f4c0d180240024020020d00410121010c010b2002102c2201450d2d0b200341003602f806200320023602f406200320013602f006200341f0066a200341e8056a41101074200341f0066a200341a8046a41101074200341f0066a20032802b00e220220071074024020032802b40e450d002002102e0b200341c0156a20032802f006220220032802f806220110b805024020032903c0154201520d002002200110ff01200341b00e6a200341c0156a41086a41e00010e9081a200341800c6a200341b00e6a41e00010e9081a024020032802f406450d002002102e0b20034190136a41066a200341800c6a41e00010e9081a200341e0106a20034190136a41e60010e9081a200341b00a6a200341e0106a41066a41e00010e9081a200341b8036a200341d00a6a20032903c00a220e200341c80a6a290300220f10cb0220032903b803210a2003200341b8036a41086a290300220b3703c8152003200a3703c01502400240200a200b844200520d002003200341c0156a3602901320034190136a10cc020c010b200342f0f2bda1a7ee9cb9f90037039013200341c0156a20034190136a10cd02200341a8036a200341c0156a200a200b10fd01200341a0136a200341a8036a41086a290300220d200b7d20032903a803220c200a54ad7d200b200d7d200a200c54ad7d200c200a56200d200b56200d200b511b22021b3703002003200c200a7d200a200c7d20021b3703981320032002ad3703901320034190136a41086a21010240024020020d00200320013602e010200341e0106a10cc020c010b200320013602e010200341e0106a10ce020b200341d8156a200b370300200341d0156a200a370300200341c8156a41063a00002003410e3a00c015200341c0156a10fe010b200341c0156a41186a200f370300200341d0156a200e370300200341cc156a2006360200200341c8156a41033a00002003410e3a00c015200341c0156a10fe01200041186a41003a000020004200370308200020032800e8063600192000411c6a200341e8066a41036a280000360000200042003703000c300b200341b00e6a200341c8156a41e00010e9081a024020032802f406450d002002102e0b41caeac200ad210a4280808080c001210b410321020b20004193023b0021200042003703082000200b200a84370024200041206a20023a0000200041186a41003a0000200042013703000c2e0b200341c0156a41246a2020360200200341c0156a41226a20213b0100200341c0156a411a6a200a370100200341c0156a41196a20153a0000200341c0156a41186a20143a0000200341c0156a41166a20163b0100200341c0156a41156a20183a0000200341c0156a41146a20193a0000200341c0156a41126a201a3b0100200341c0156a41116a20173a0000200341c0156a41106a201b3a0000200341c0156a410e6a20053b0100200341c0156a410d6a20093a0000200341c0156a410c6a20083a0000200341c0156a410a6a20113b0100200341c0156a41096a20123a0000200341c0156a41086a20133a0000200320073602e8152003201c3b01c6152003201d3a00c515200320043a00c4152003201e3b01c2152003201f3a00c115200320023a00c0154200210a4200210b02400240200341c0156a10c60241ff01714102460d00200341c0156a200610d60320032802c015220120032802c815108f022102024020032802c415450d002001102e0b20020d0141caeac200ad210a4280808080c001210b410321240b20004193023b0021200042003703082000200b200a84370024200041206a20243a0000200041186a41003a0000200042013703000c2e0b200341c8066a41186a22024200370300200341d8066a22014200370300200341c8066a41086a22074200370300200342003703c806200341e8056a41bad7c70041081081022007200341e8056a41086a290300370300200320032903e8053703c806200341a8046a4194ccc20041091081022002200341a8046a41086a290300370300200120032903a8043703004104102c2202450d2a20034204370294132003200236029013200320063602c01520034190136a200341c0156a41041074200341c0156a41086a20032802981336020020032003290390133703c015200341c8066a4120200341c0156a10c702200041186a41003a000020004200370308200020032800e8063600192000411c6a200341eb066a280000360000200042003703000c2d0b200341c0156a200141046a41c40010e9081a20034190136a41286a200241286a28020036020020034190136a41206a200241206a29020037030020034190136a41186a200241186a29020037030020034190136a41106a200241106a29020037030020034190136a41086a200241086a29020037030020032002290200370390132000200341c0156a20034190136a10c7060c2c0b200341c0156a20034190136a410110f002200341c9156a2102024020032d00c0154101470d0020033500c5152002330000200341cb156a3100004210868442208684210d200341c0156a410c6a280200210220032d00c41521014200210e0c020b20032d00c1152101200341c0156a41086a41033a00002002200329039013370000200341d1156a20034190136a41086a290300370000200341d9156a200341a0136a290300370000200341e1156a20034190136a41186a2903003700002003410c3a00c015200341c0156a10fe010240200141ff01710d0010f7021a0b200320032802a8043602b008200320032800ab043600b308200041186a41003a000020004200370308200020032802b0083600192000411c6a20032800b308360000200042003703000c2b0b0b200320032800ab043600b308200320032802a8043602b008200041276a200d4230883c0000200041256a200d4220883d00002000200d3e0021200041186a41003a0000200041106a42d8e4970f3703002000200e370308200020032802b0083600192000411c6a20032800b308360000200041286a2002360000200041206a20013a0000200042013703000c290b200341063a00a8040b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c270b20032d00f00622024106460d010b20032f00f106210120032d00f3062107200020032902f406370024200020073a0023200020013b0021200041206a20023a0000200041186a41003a000020004200370308200042013703000c250b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c240b20032802b00a2102200020032902b40a370024200041206a2002360000200041186a41003a000020004200370308200042013703000c230b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c220b20004200370308200020032800e805360019200041186a41003a00002000411c6a200341eb056a280000360000200042003703000c210b2000200a370024200020063a0023200020073a0022200020013a002120004200370308200041206a20023a0000200041186a41003a0000200042013703000c200b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c1f0b20032d00c01521020b0240200241ff01714106460d0020032d00c115210120032d00c215210720032d00c315210620032902c415210a0c010b02402015450d002012102e0b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c1d0b02402015450d002012102e0b2000200a370024200020063a0023200020073a0022200020013a002120004200370308200041206a20023a0000200041186a41003a0000200042013703000c1c0b20020d180c040b20032d00e0102101200341f00b6a41086a2002360200200320013a00f00b2003200a3e00f10b2003200a4230883c00f70b2003200a4220883d00f50b024020032802cc152202450d00200241246c2101201a210203400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b024020032802c8152202450d00200241246c450d00201a102e0b024020242007460d000340200610e1010240200641046a2802002202450d00200241246c450d002006280200102e0b200641f0006a2106200941907f6a22090d000b0b02402011450d00201141f0006c450d002004102e0b20032802b4082202450d02200241c4006c450d0220032802b008102e0c020b20242007460d002004200541f0006c6a210603402007220241046a220110e101200241f0006a21070240200241086a2802002202450d00200241246c450d002001280200102e0b20062007470d000b0b02402011450d00201141f0006c450d002004102e0b200341a80a6a4200370300200341a00a6a4200370300200341900a6a41086a22024200370300200342003703900a200341d0086a4190dac800410a1081022002200341d0086a41086a290300370300200320032903d0083703900a200341b00a6a41d5dac8004106108102201741086a200341b00a6a41086a290300370200201720032903b00a370200201541c4006c41046a2202417f4c0d0120032802b00821010240024020020d00410121070c010b2002102c2207450d160b200341003602c815200320023602c415200320073602c0152015200341c0156a107620012015200341c0156a109f01200341900a6a412020032802c015220220032802c81510b201024020032802c415450d002002102e0b200341063a00f00b20032802b4082202450d00200241c4006c450d002001102e0b024020032d00f00b22024106460d0020032f00f10b210120032d00f30b2107200020032902f40b370024200020073a0023200020013b0021200041206a20023a0000200041186a41003a000020004200370308200042013703000c180b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c170b1038000b200341e8056a200341800c6a10c802200341c0156a20032802e805220120032802f005220710c90220032903c015210a200341a8046a41086a220220034190166a290300370300200320034188166a2903003703a80402400240200a4201510d00200341f0066a41086a4200370300200342003703f0060c010b200341f0066a41086a2002290300370300200320032903a8043703f0060b200341c0156a41c8006a20032903f00637030020034190166a200341f0066a41086a290300370300200342013703c015200341c0156a41386a202d4200201042015122021b370300200341f0156a202f420020021b370300200341c0156a41286a202c420020021b370300200341e0156a202b420020021b370300200341d8156a2025420020021b370300200341c0156a41106a2027420020021b37030020034180166a202a420020021b37030020032026420020021b3703c81520012007200341c0156a41086a10c805024020032802ec05450d002001102e0b20034190136a41106a290300211020034190136a41286a290300210e20034190136a41386a290300210b20034190136a41c8006a290300210c200329039813212620032903b013212920032903c013210a20032903d013210d200329039013212820032903a813210f0b024020284201520d00200341f8156a2010370300200341f0156a2026370300200341c0156a41086a41003a0000200341c9156a20032903800c370000200341d1156a200341800c6a41086a290300370000200341d9156a200341900c6a290300370000200341e1156a200341980c6a290300370000200341033a00c015200341c0156a10fe010b02400240200f50450d004200210f0c010b200341c0156a41186a200341800c6a41186a290300370300200341c0156a41106a200341800c6a41106a290300370300200341c0156a41086a200341800c6a41086a290300370300200320032903800c3703c0154201210f0b200341b00e6a41186a200341c0156a41186a22022903002210370300200341b00e6a41106a200341c0156a41106a22012903002228370300200341b00e6a41086a200341c0156a41086a22072903002226370300200320032903c01522273703b00e200341f0156a2206200e370300200341e8156a220420293703002001202637030020022028370300200341e0156a20103703002003200f3703c015200320273703c815200341c0156a10d204024020032903c015500d00200320043602901320034190136a10cc020b20034188166a200c37030020034180166a200d370300200341f8156a200b3703002006200a370300200741033a0000200341c9156a20032903800c370000200341d1156a200341800c6a41086a290300370000200341d9156a200341800c6a41106a290300370000200341e1156a200341800c6a41186a290300370000200341033a00c015200341c0156a10fe01200320032802c8063602f00b200320032800cb063600f30b200041186a41003a000020004200370308200020032802f00b3600192000411c6a20032800f30b360000200042003703000c140b200341900a6a41086a2201200341b0086a41086a2f01003b0100200320032802c8063602f00b200320032800cb063600f30b200320032903b0083703900a200041186a41003a000020004200370308200020032802f00b3600192000411c6a20032800f30b360000200041206a20023a0000200020032903900a3700222000412a6a20012f01003b0000200042013703000c130b20032d00800c22014106470d0141012101410221060b200341e0156a20032903d008370300200341f4156a20032800f30b360000200341e8156a200341d8086a290300370300200341d8156a200a3703002003200d3703c015200320063a00f015200320032802f00b3600f1152003200c3703c8152003200b3703d015024002402001450d002005200710ff010c010b20052007200341c0156a10c6050b410621010b20032902840c210a20032d00830c210720032d00820c210620032d00810c2104024020032802940a450d002005102e0b20014106460d010b2000200a370024200020073a0023200020063a0022200020043a002120004200370308200041206a20013a0000200041186a41003a0000200042013703000c0f0b200341e8156a2002360200200341cd156a200341b80e6a290300370000200341d5156a200341c00e6a290300370000200341dd156a200341b00e6a41186a290300370000200341023a00c415200341023a00c015200320032903b00e3700c515200341c0156a10fe01200041186a41003a000020004200370308200020032800e8063600192000411c6a200341eb066a280000360000200042003703000c0e0b20032d00e01022014106470d010b2005200710ff01410621010b20032902e410210a20032d00e310210720032d00e210210620032d00e1102104024020032802840c450d002005102e0b20014106460d010b2000200a370024200020073a0023200020063a0022200020043a002120004200370308200041206a20013a0000200041186a41003a0000200042013703000c0a0b200341c8156a2002360200200341013a00c415200341023a00c015200341c0156a10fe01200041186a41003a000020004200370308200020032800e8063600192000411c6a200341eb066a280000360000200042003703000c090b20032d00e01022024106470d0141012106410221020b200341e0156a20032903d008370300200341f4156a20032800f30b360000200341e8156a200341d8086a290300370300200341d8156a200a3703002003200d3703c015200320023a00f015200320032802f00b3600f1152003200c3703c8152003200b3703d015024002402006450d002001200710ff010c010b20012007200341c0156a10c6050b410621020b20032902e410210a20032d00e310210720032d00e210210620032d00e1102104024020032802940a450d002001102e0b20024106470d01200341cd156a20032903880c370000200341e8156a2011360200200341d5156a200341900c6a290300370000200341dd156a200341980c6a290300370000200341003a00c415200341023a00c015200320032903800c3700c515200341c0156a10fe01200341063a00b0080b20004200370308200020032800e806360019200041186a41003a00002000411c6a200341eb066a280000360000200042003703000c050b2003200a3702b408200320073a00b308200320063a00b208200320043a00b108200320023a00b0080b20032802b0082102200020032902b408370024200041206a2002360000200041186a41003a000020004200370308200042013703000c030b1036000b4103210641022107418fc2cb002101411d21020b02402011450d002008102e0b200320032800b00a3602d0082003200341b30a6a2800003600d308200041186a41003a000020004200370308200020032802d0083600192000411c6a20032800d308360000200041286a2002360200200041246a2001360200200020073a0022200041003a0021200041206a20063a0000200042013703000b200341f0176a24000b13002000410636020420004198f4c0003602000bf70802077f027e230041f0006b2202240002400240024002400240024020012d0000417f6a0e03010002000b200041003b0001200041013a0000200041036a41003a00000c030b200241386a200141016a10e00241002103200241d0006a200141216a20022802382204200228024041d4e2cc00410010e102200241286a200241db006a290000370300200241306a200241e3006a2f00003b01002002200229005337032020022d0052210520022d0051210620022d005021010240200228023c450d002004102e0b0c010b200241386a200141016a10e002200241d0006a200141216a200228023822072002280240200141e4006a2204280200200141ec006a220128020010e102200241286a200241db006a290000370300200241306a200241e3006a2f00003b010020022002290053370320200128020021082004280200210320022d0052210520022d0051210620022d00502101200228023c450d002007102e0b200241086a41106a200241206a41106a2f010022043b0100200241086a41086a200241206a41086a290300220937030020022002290320220a370308200241d0006a41106a220720043b0100200241d0006a41086a220420093703002002200a3703500240200141ff01714101470d002002412a6a2004290300370100200241326a20072f01003b0100200220053a0021200220063a002020022002290350370122200241d0006a200241206a10e202200228025022042002280258108f02210102402002280254450d002004102e0b024020010d00200041800e3b0001200041013a0000200041036a41013a00000c020b200241d0006a41106a200241206a41106a280200360200200241d0006a41086a200241206a41086a29030037030020022002290320370350200241386a200241d0006a10e30220022802382204200228024010e40241ff017121010240200228023c450d002004102e0b0240024020014102460d0002402003450d0041c40141c70120011b2008470d0041abcecc0041efcfcc0020011b2003200810ec08450d020b200041800e3b0001200041013a0000200041036a41033a00000c030b2003450d00200041800e3b0001200041013a0000200041036a41033a00000c020b410c102c2201450d02200241d0006a41106a200241206a41086a290300370300200241d0006a41186a200241206a41106a28020036020020024106360254200241eef8c00036025020022002290320370358410a102c2204450d022002420a37023c200220043602384106200241386a1076200241386a41eef8c00041061074200241386a200241d0006a41086a41141074200141086a200228024036020020012002290338370200200041306a41013a0000200041286a428180808010370200200041246a2001360200200041206a4100360200200041186a4204370300200041106a427f370300200041086a42e400370300200041316a2002280038360000200041346a2002413b6a280000360000200041003a00000c010b200041800e3b0001200041013a0000200041036a41003a00000b200241f0006a24000f0b1036000be80401097f230041306b22022400024002404120102c2203450d002002422037020420022003360200200220014120107441012104200228020822034101742201417f4c0d012002280200210502402001450d002001102c2204450d010b2000410036020820002004360200200041046a2206200136020002402003450d002003417f6a2107410021030240034020052d00002108024002400240024020032001470d00200141016a22092001490d082001410174220a2009200a20094b1b22094108200941084b1b21090240024020010d00200241003602200c010b2002410136022820022001360224200220043602200b200241106a20094101200241206a10d1042002280218210120022802104101460d01200020022802142204360200200620013602000b2000200341016a2209360208200420036a413041d700200841a001491b20084104766a3a000020092001470d0220062802002001470d02200141016a220420014f0d010c070b2001450d060c050b2001410174220a2004200a20044b1b22044108200441084b1b21040240024020010d00200241003602200c010b2002410136022820022001360224200220002802003602200b200241106a20044101200241206a10d1042002280218210120022802104101460d02200020022802142204360200200620013602000b2000200941016a2209360208200420036a41016a413041d7002008410f712201410a491b20016a3a00002007450d02200541016a21052007417f6a210720062802002101200921030c000b0b2001450d020c010b02402002280204450d002002280200102e0b200241306a24000f0b1036000b1038000bb40a02077f027e230041a0026b22062400024002400240024002400240200520036a41216a22070d0041012108410021094100210a0c010b4100210b4100210c4100210a410121080240024003402007410a7021090240200c200a470d00200c41016a220a200c490d05200b200a200b200a4b1b220a4108200a41084b1b210a02400240200c0d00200641003602d8010c010b200641013602e0012006200c3602dc01200620083602d8010b20064198016a200a4101200641d8016a107d20062802a001210a2006280298014101460d02200628029c0121080b2008200c6a20094130723a00002007410a490d02200c41016a210c200b41026a210b2007410a6e21070c000b0b200a450d020c050b200c41016a21090b411a102c220c450d032006411a36025c2006200c360258200c41002900f4f840370000200c41086a41002900fcf840370000200c41106a4100290084f940370000200c41186a41002f008cf9403b00002006411a360260024002402009450d002009411a6a22072009490d022006429a808080103702dc012006200c3602d80120064198016a20074134200741344b1b4101200641d8016a107d200641a0016a28020021072006280298014101460d01200628029c01210c2006200736025c2006200c3602580b20090d02411a210c0c030b20070d030b1038000b2008417f6a210b200c411a6a210c200921070340200c200b20076a2d00003a0000200c41016a210c2007417f6a22070d000b2009411a6a210c0b2006200c3602600240200a450d002008102e0b200641d8006a41b8fcc60041211074200641d8006a200220031074200641d8006a20042005107420062006280258220c200628026010e5020240200628025c450d00200c102e0b4100210c200641206a41106a4100360200200641206a41086a420037030020064200370320200641d8016a2001200610e602024020062d00d8014101460d00200641d0016a20064191026a290000370300200641c8016a20064189026a290000370300200641c0016a20064181026a290000370300200641b8016a200641f9016a290000370300200641b0016a200641f1016a29000037030020064198016a41106a200641e9016a29000037030020064198016a41086a200641e1016a290000370300200620062900d901370398014101210c0b200641d8016a41386a220720064198016a41386a290300370300200641d8016a41306a220b20064198016a41306a290300370300200641d8016a41286a220920064198016a41286a290300370300200641d8016a41206a220820064198016a41206a290300370300200641d8016a41186a220a20064198016a41186a290300370300200641d8016a41106a20064198016a41106a290300370300200641d8016a41086a20064198016a41086a29030037030020062006290398013703d80102400240200c450d00200641d8006a41386a2007290300370300200641d8006a41306a200b290300370300200641d8006a41286a2009290300370300200641d8006a41206a2008290300370300200641d8006a41186a200a290300370300200641d8006a41106a200641d8016a41106a290300370300200641d8006a41086a200641d8016a41086a290300370300200620062903d801370358200641386a200641d8006a41c00010e502200641206a41106a200641d4006a280000220c360200200641206a41086a200641cc006a290000220d37030020062006290044220e370320200041116a200c360000200041096a200d3700002000200e3700014101210c0c010b4100210c0b2000200c3a0000200641a0026a24000f0b1036000bf50101047f230041306b22022400200241b6d1cc004106108102200241106a41b6d1cc004106108102024002404114102c2203450d002002421437022420022003360220200241206a20014114107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bf50101047f230041306b22022400200241b6d1cc004106108102200241106a41bcd1cc004107108102024002404114102c2203450d002002421437022420022003360220200241206a20014114107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000b800201027f230041d0006b220224002002200136020420022000360200200241086a2000200110ed0202400240200228020822010d00410221000c010b200228020c210302400240200241106a280200450d0041002100024020012d00000e020200010b410121000c010b20024100360220200242013703182002410a36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241909dc5003602382002200241286a360248200241346a419cebc000200241386a103d1a2002280218200228022010ef020240200228021c450d002002280218102e0b410221000b2003450d002001102e0b200241d0006a240020000b4c0020002002ad4220862001ad8410112201290000370000200041186a200141186a290000370000200041106a200141106a290000370000200041086a200141086a2900003700002001102e0ba80503017f017e027f23004190016b22032400024002402001200210052204422088a722020d00410121010c010b2004a721010b200320023602442003200136024002402002450d0020012d0000210520032002417f6a22063602442003200141016a36024002400240024020050e020001030b200341c8006a200341c0006a10a70120032d00484101460d02200341086a200341d2006a290100370300200341106a200341da006a290100370300200341186a200341e2006a290100370300200341206a200341ea006a290100370300200341286a200341f2006a290100370300200341306a200341fa006a290100370300200341376a20034181016a2900003700002003200329014a37030020032d00492102410021050c010b2006450d0120012d0001210520032002417e6a3602442003200141026a3602404100210202400240024020050e03020100040b410221020c010b410121020b200341376a200341c8006a41376a290000370000200341306a200341c8006a41306a290000370300200341286a200341c8006a41286a290000370300200341206a200341c8006a41206a290000370300200341186a200341c8006a41186a290000370300200341106a200341c8006a41106a290000370300200341086a200341c8006a41086a29000037030020032003290048370300410121050b200020023a0001200020053a0000200041026a20032903003700002000410a6a200341086a290300370000200041126a200341106a2903003700002000411a6a200341186a290300370000200041226a200341206a2903003700002000412a6a200341286a290300370000200041326a200341306a290300370000200041396a200341376a2900003700002001102e20034190016a24000f0b41cae0cc00412e200341c8006a41f8e0cc004188e1cc00103e000bb10201037f230041e0006b22022400200241086a418ef9c0004110108102200241186a41fbafc9004106108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000bb40102047f027e230041d0006b22012400200141106a200010e702200141206a200128021022022001280218220310e90202400240200128024022040d00420021054101210441002103420021060c010b2002200310ff01200128024441ffffff3f712103200141386a2903002106200129033021050b02402001280214450d002002102e0b02402003450d002004102e0b42f0d0c9abc6add9b1f400200010ea02200120002005200610fb01200141d0006a24000bf00304027f017e037f037e230041e0006b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200041003602200c010b200328021421022003200341186a280200360224200320013602202003200341206a10ab0102400240024002402003280200450d00200341003602480c010b200341c8006a200341206a200328020410920120032802482204450d00200329024c210502400240200328022422064110490d0020032003280220220741106a3602202003200641706a2208360224200841104f0d010b200542ffffff3f83500d012004102e0c010b200741086a29000021092007290000210a2003200641606a3602242003200741206a36022020040d010b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341909dc5003602482003200341386a360258200341c4006a419cebc000200341c8006a103d1a2003280228200328023010ef020240200328022c450d002003280228102e0b200041003602200c010b200741186a290000210b200020072900103703102000200a3703002000200537022420002004360220200041186a200b370300200020093703080b2002450d002001102e0b200341e0006a24000b9503010a7f230041206b2202240020022000370308200241106a200110d4062002280218210341002104200241003602180240024020030d0041002105200228021021060c010b2002280210220641106a2107410021054100210802400340024002402005450d00200620084105746a21092006200820046a4105746a210a0340200941106a220b2900002002290308510d02200a2009290300370300200a41186a200941186a290300370300200a41106a200b290300370300200a41086a200941086a290300370300200a41206a210a200941206a21092003200841016a22084b0d000c040b0b200720084105746a2109034020092900002002290308510d01200941206a21092003200841016a22084b0d000b410021050c030b2004417f6a2104200541016a21052003200841016a22084b0d000b0b024020050d00410021050c010b2006200820056b4105746a200620084105746a200320086b41057410ea081a0b2002200320056b220936021820012006200910d5060240200228021441ffffff3f71450d002006102e0b200241206a24000bca0101077f230041106b22022400200210ec0241012103200228020021044100210541002106024002400240200228020822070e020201000b4100210503402007410176220820056a2106200620052004200641306c6a2001412010ec084101481b2105200720086b220741014b0d000b0b02402004200541306c6a2001412010ec0822070d0020052106410021030c010b20052007411f766a21060b024020022802042205450d00200541306c450d002004102e0b2000200636020420002003360200200241106a24000bb40302047f017e23004180016b22012400200141206a22024200370300200141086a41106a22034200370300200141086a41086a420037030020014200370308200141086a418ef9c0004110108102200141e8006a419ef9c000410a1081022002200141e8006a41086a290000370300200320012900683703002001412036022c2001200141086a360228200141306a200141086a412010ed0202400240200128023022030d00410021020c010b200128023421042001200141306a41086a28020036024420012003360240200141e8006a200141c0006a10e90102400240200128026822020d004100210220014100360250200142013703482001410a36025c2001200141286a3602582001200141c8006a360264200141fc006a41013602002001420137026c200141909dc5003602682001200141d8006a360278200141e4006a419cebc000200141e8006a103d1a2001280248200128025010ef020240200128024c450d002001280248102e0b0c010b200129026c21050b2004450d002003102e0b0240024020020d0020004100360208200042083702000c010b20002005370204200020023602000b20014180016a24000b130020002002ad4220862001ad84102510da080bde0401047f230041c0006b220224002000280204210320002802002104200128021841a89fc00041012001411c6a28020028020c11000021000240024020030d00200021050c010b2002200436020441012105024020000d00024020012d0000410471450d0041012105200128021841f99ec0004101200128021c28020c1100000d012001280200210041012105200241013a001720022000360218200241c09ec00036023420022001290218370308200220012d00203a00382002200128020436021c20022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a1087010d01200228023041d89ec0004102200228023428020c11000021050c010b200241046a200110870121050b20034101460d00200441016a21002003417f6a2103034020022000360204200541ff0171210441012105024020040d00024020012802002205410471450d00200241013a001720022005360218200241c09ec00036023420022001290218370308200220012d00203a00382002200128020436021c20022001290210370328200220012902083703202002200241176a3602102002200241086a3602300240200241046a200241186a1087010d00200228023041d89ec0004102200228023428020c11000021050c020b410121050c010b41012105200128021841bc9ec0004102200128021c28020c1100000d00200241046a200110870121050b200041016a21002003417f6a22030d000b0b41012100024020050d00200128021841fa9ec0004101200128021c28020c11000021000b200241c0006a240020000b0e002001ad4220862000ad8410160be52005067f017e027f067e057f230041f0026b22032400200341b8016a22044200370300200341a0016a41106a22054200370300200341a0016a41086a22064200370300200342003703a001200341e0006a418ef9c00041101081022006200341e0006a41086a2207290000370300200320032900603703a001200341e0006a41c7c3cb0041071081022004200729000037030020052003290060370300200341e0016a200341a0016a10f10220032802e0012206410820061b2108410021040240024002400240024002400240024002400240024002400240024002400240024020032902e401420020061b2209422088a7220a0e020201000b41002104200a210603402006410176220b20046a210720072004200820074106746a41206a2001412010ec084101481b21042006200b6b220641014b0d000b0b200820044106746a41206a2001412010ec080d002004200a4f0d01200820044106746a2206290310210c200641186a290300210d2006200641c0006a2004417f73200a6a41067410ea081a024002402002450d00200341106a2001200c200d10cb022003290310210e2003200341106a41086a290300220f3703e8012003200e3703e00102400240200e200f844200520d002003200341e0016a3602a001200341a0016a10cc020c010b200342f0f2bda1a7ee9cb9f9003703a001200341e0016a200341a0016a10cd022003200341e0016a200e200f10fd01200341b0016a200341086a2903002210200f7d20032903002211200e54ad7d200f20107d200e201154ad7d2011200e562010200f562010200f511b22041b37030020032011200e7d200e20117d20041b3703a80120032004ad3703a001200341a0016a41086a21060240024020040d0020032006360260200341e0006a10cc020c010b20032006360260200341e0006a10ce020b200341f8016a200f370300200341f0016a200e370300200341e8016a41063a00002003410e3a00e001200341e0016a10fe010b20034198026a200d37030020034190026a200c370300200341e0016a41086a41063a0000200341e9016a2001290000370000200341f1016a200141086a290000370000200341f9016a200141106a29000037000020034181026a200141186a2900003700002003410c3a00e001200341e0016a10fe010c010b200341306a2001200c200d10fb010b200341a0016a41186a220a4200370300200341a0016a41106a22024200370300200341a0016a41086a220b4200370300200342003703a001200341e0006a418ef9c0004110108102200b200341e0006a41086a2206290000370300200320032900603703a001200341e0006a41a8f9c0004109108102200541086a200629000037000020052003290060370000200341e0016a200341a0016a10f10220032802e0012204410820041b21070240024020032902e401420020041b220e422088a722040d00410021120c010b200341e0016a41386a20072004417f6a22134106746a220441386a290300370300200341e0016a41306a200441306a290300370300200341e0016a41286a200441286a290300370300200341e0016a41206a200441206a290300370300200341e0016a41186a200441186a290300370300200341e0016a41106a200441106a290300370300200341e0016a41086a200441086a290300370300200320042903003703e001200e42ffffffff0f832013ad42208684210e410121120b200341a0016a41386a2213200341e0016a41386a290300370300200341a0016a41306a2214200341e0016a41306a290300370300200341a0016a41286a2215200341e0016a41286a290300370300200341a0016a41206a2216200341e0016a41206a290300370300200a200341e0016a41186a22042903003703002002200341e0016a41106a220a290300370300200b200341e0016a41086a2202290300370300200320032903e0013703a001200320073602402003200e37024420044200370300200a420037030020024200370300200342003703e001200341e0006a418ef9c000411010810220022006290000370300200320032900603703e001200341e0006a41a8f9c000410910810220042006290000370300200a2003290060370300200341e0016a200341c0006a10f2020240200e42ffffff1f83500d002007102e0b20094280808080707c210e200341e0006a41086a2204200341a0016a41086a290300370300200341e0006a41106a2206200341a0016a41106a290300370300200341e0006a41186a2207200341a0016a41186a290300370300200341e0006a41206a2016290300370300200341e0006a41286a2015290300370300200341e0006a41306a2014290300370300200341e0006a41386a2013290300370300200320032903a001370360410021132012450d05200341e0016a41386a2212200341e0006a41386a290300370300200341e0016a41306a2214200341e0006a41306a290300370300200341e0016a41286a2215200341e0006a41286a290300370300200341e0016a41206a2202200341e0006a41206a290300370300200341e0016a41186a2007290300370300200341e0016a41106a2006290300370300200341e0016a41086a2004290300370300200320032903603703e001410021040240200e4220882210a722130e020403000b410021042013210603402006410176220b20046a210720072004200820074106746a41206a2002412010ec084101481b21042006200b6b220641014b0d000c030b0b0240200942ffffff1f83500d002008102e0b200341e0016a410d10f302200041013a00002000410c6a200341e8016a280200360200200041046a20032903e0013702000c0b0b2004200a1046000b200820044106746a41206a2002412010ec082206450d0120042006411f766a21040b200341a0016a41086a2015290300370300200341b0016a2014290300370300200341a0016a41186a201229030037030020032003290380023703a001200420134b0d09200341e0016a41186a290300210f200341e0016a41086a290300210c20032903f001210d20032903e001211102402013200ea7470d00201341016a22062013490d0620134101742207200620062007491b22064104200641044b1b220641ffffff1f712006464103742107200641067421060240024020130d00200341003602400c010b200341c0006a41086a410836020020032008360240200320104206863e02440b200341e0026a20062007200341c0006a107d200341e8026a280200210620032802e0024101460d0320032802e40221082006410676ad210e0b200820044106746a220641c0006a2006201320046b41067410ea081a200641186a200f3703002006200d3703102006200c37030820062011370300200620032903a001370320200641286a200341a8016a290300370300200641306a200341b0016a290300370300200641386a200341a0016a41186a290300370300200e42ffffffff0f8320094280808080708384210e0b410121130b2003200e3702a401200320083602a00120080d01200341f8016a4200370300200341e0016a41106a4200370300200341e0016a41086a22044200370300200342003703e001200341e0006a418ef9c00041101081022004200341e0006a41086a2206290000370300200320032900603703e001200341e0006a41c7c3cb004107108102200a41086a2006290000370000200a2003290060370000200341e0016a412010ff010c020b2006450d020c070b200341f8016a4200370300200341e0016a41106a4200370300200341e0016a41086a22044200370300200342003703e001200341e0006a418ef9c00041101081022004200341e0006a41086a2206290000370300200320032900603703e001200341e0006a41c7c3cb004107108102200a41086a2006290000370000200a2003290060370000200341e0016a200341a0016a10f2022008450d00200e42ffffff1f83500d002008102e0b200341b8016a4200370300200341a0016a41106a4200370300200341a0016a41086a22044200370300200342003703a001200341e0006a418ef9c00041101081022004200341e0006a41086a2206290000370300200320032900603703a001200341e0006a41c7c3cb004107108102200541086a200629000037000020052003290060370000200341e0016a200341a0016a10f10220032902e401420020032802e001220b1b2209422088a72207410674410675220441ffffff3f712004470d0020044105742206417f4c0d000240024020060d00410121020c010b2006102c2202450d060b024002402006410576221220044f0d00200641047622082004200820044b1b22044104200441044b1b220441ffffff3f712004462108200441057421040240024020060d00200341003602e0010c010b200341e8016a4101360200200320063602e401200320023602e0010b200341a0016a20042008200341e0016a107d200341a8016a280200210420032802a0014101460d0120032802a4012102200441057621120b200b4108200b1b211420070d02410021080c030b20040d050b1038000b2007410674210b200741067441406a4106762115200341e0016a41206a210720022104201421060340200341e0016a41386a200641386a290300370300200341e0016a41306a200641306a290300370300200341e0016a41286a200641286a2903003703002007200641206a290300370300200341a0016a41086a2208200741086a290000370300200341a0016a41106a2205200741106a290000370300200341a0016a41186a220a200741186a290000370300200320072900003703a001200441186a200a290300370000200441106a2005290300370000200441086a2008290300370000200420032903a001370000200441206a2104200641c0006a2106200b41406a220b0d000b201541016a21080b0240200942ffffff1f83500d002014102e0b200341c0006a41186a200141186a290000370300200341c0006a41106a200141106a290000370300200341c0006a41086a200141086a29000037030020032001290000370340200341a0016a41186a22044200370300200341a0016a41106a22064200370300200341a0016a41086a22074200370300200342003703a001200341e0006a41c8afc90041131081022007200341e0006a41086a220b290000370300200320032900603703a001200341e0006a41dbc3cb0041051081022004200b29000037030020062003290060370300200341e0016a200341a0016a412010f40220032d00e00121052004200341f9016a2900003703002006200341f1016a2900003703002007200341e9016a290000370300200320032900e1013703a0010240024020054101470d00200341e0006a41186a22052004290300370300200341e0006a41106a220a2006290300370300200b2007290300370300200320032903a001370360200341c0006a41012002200810f502200420052903003703002006200a2903003703002007200b290300370300200320032903603703a001200341a0016a2001412010ec08450d01200341f9016a200341b8016a290300370000200341f1016a200341b0016a290300370000200341e9016a200341a8016a290300370000200320032903a0013700e101200341013a00e001200341e0016a10f6020c010b200341c0006a41012002200810f5020b200041003a0000200020133a00012012450d002002102e0b200341f0026a24000f0b200420131045000b1036000b9c0804067f017e057f057e230041d0016b220224002002412036020c20022001360208200241106a2001412010ed02024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10ab010240024020022802000d00024002402002280204220520022802244106762201200120054b1b22014106742206417f4c0d000240024020010d00410821070c010b2006102c2207450d060b2001ad2108024002402005450d00200241a8016a41017221090340200241a8016a200241206a10930120022d00a8014101460d0420024188016a41186a220a200941186a29000037030020024188016a41106a220b200941106a29000037030020024188016a41086a220c200941086a2900003703002002200929000037038801200228022422064110490d0420022002280220220141106a3602202002200641706a220d360224200d4110490d04200141086a290000210e2001290000210f200241c8006a41086a200c2903002210370300200241c8006a41106a200b2903002211370300200241c8006a41186a200a2903002212370300200241286a41086a220a2010370300200241286a41106a220b2011370300200241286a41186a220c20123703002002200641606a3602242002200141206a3602202002200229038801221037034820022010370328200141186a290000211020012900102111024020084220882212a722062008a7470d00200641016a22012006490d042006410174220d20012001200d491b22014104200141044b1b220141ffffff1f71200146410374210d200141067421010240024020060d00200241003602a8010c010b200241083602b001200220073602a801200220124206863e02ac010b20024188016a2001200d200241a8016a107d20022802900121012002280288014101460d03200228028c0121072001410676ad21080b200720064106746a220120113703102001200e3703082001200f370300200141186a201037030020012002290328370320200141286a200a290300370300200141306a200b290300370300200141386a200c290300370300200842ffffffff0f83200641016aad4220868421082005417f6a22050d000b0b2007450d0320002008370204200020073602000c040b20010d050b1038000b200842ffffff1f83500d002007102e0b200241003602900120024201370388012002410a36026c2002200241086a360268200220024188016a360248200241bc016a4101360200200242013702ac01200241909dc5003602a8012002200241e8006a3602b801200241c8006a419cebc000200241a8016a103d1a20022802880120022802900110ef020240200228028c01450d00200228028801102e0b200041003602000b2004450d002003102e0b200241d0016a24000f0b1036000b810202047f017e230041206b2202240002400240200128020822034106744104722204417f4c0d00200128020021012004102c2205450d0120024100360208200220043602042002200536020020032002107602402003450d002003410674210303402002200141206a41201074200129030021062002200141086a290300370318200220063703102002200241106a41101074200141106a29030021062002200141186a290300370318200220063703102002200241106a41101074200141c0006a2101200341406a22030d000b0b2000412020022802002201200228020810b20102402002280204450d002001102e0b200241206a24000f0b1038000b1036000be90301047f230041c0006b220224004182fcc10021034112210441102105024002400240024002400240024002400240024002400240024002400240024002400240200141ff01710e12000102030405060708090a0b0c0d0e0f1011000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a4184c2cc001044000b41f6fbc1002103410c2104410021050c0f0b41effbc100210341072104410121050c0e0b41e3fbc1002103410c2104410221050c0d0b41cffbc100210341142104410321050c0c0b41c5fbc1002103410a2104410421050c0b0b41b6fbc1002103410f2104410521050c0a0b41abfbc1002103410b2104410621050c090b41a1fbc1002103410a2104410721050c080b418efbc100210341132104410821050c070b4182fbc1002103410c2104410921050c060b41f4fac1002103410e2104410a21050c050b41dafac1002103411a2104410b21050c040b41e0c3cb00210341092104410c21050c030b41c8fac1002103410d21050c020b41b8fac100210341102104410e21050c010b41a7fac100210341112104410f21050b20004183223b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000b970302027f047e23004180016b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200041003a00000c010b200328021421042003200341106a41086a28020036026c20032001360268200341c0006a200341e8006a109301410121020240024020032d00404101470d004100210220034100360228200342013703202003410a3602742003200341086a3602702003200341206a36027c200341d4006a410136020020034201370244200341909dc5003602402003200341f0006a360250200341fc006a419cebc000200341c0006a103d1a2003280220200328022810ef022003280224450d012003280220102e0c010b200341386a200341c0006a41196a2900002205370300200341306a200341c0006a41116a2900002206370300200341206a41086a200341c0006a41096a2900002207370300200320032900412208370320200041196a2005370000200041116a2006370000200041096a2007370000200020083700010b200020023a00002004450d002001102e0b20034180016a24000bc210050b7f017e087f087e0b7f230022042105200441c0016b4160712206240002400240200141ffffff3f712001470d0020014105742207417f4c0d0041012108024002402007450d002007102c2208450d0120074105762109200821042007210a0340200a450d0120042000290000370000200441086a200041086a290000370000200441106a200041106a290000370000200441186a200041186a290000370000200441206a2104200a41606a210a200041206a21002009417f6a22090d000b0b2008200110fc02200641e0006a41186a220b4200370300200641e0006a41106a220c4200370300200641e0006a41086a220d42003703002006420037036020064180016a41c8afc9004113108102200d20064180016a41086a2200290000370300200620062900800137036020064180016a41dbafc9004109108102200b2000290000370300200c20062900800137030020064180016a200641e0006a4120108d032006280280012204410120041b210e200629028401420020041b220f422088a72204450d02200e20044105746a2110200641206a410c72211120064180016a410c6a2112200e2113034020064180016a41186a2214201341186a29000037030020064180016a41106a201341106a2900003703002000201341086a2900003703002006201329000037038001200641106a20064180016a10f50720064180016a200628021022152006280218221610b305200d201241086a290200370300200c201241106a2802003602002006201229020037036020062802a00121170240200628028801220a450d00200629038001211820112006290360370200201141086a200d290300370200201141106a200c28020036020020062018370320201721040b2006200a360228200641003602880120062903382119200620062903980122183703382006290330211a2006200629039001221b3703302006290320211c2006200629038001221d3703202006290328211e2006200629038801221f37032802400240201ea722200d00200421170c010b2006201c3703402006201e3703482006201a370350201e422088a721212006201937035802400240201aa722040d00201a422088a721222019422088a721042019a72123202021240c010b202020044105746a212220202125202021240340200b202541186a2900002218370300200c202541106a290000221b370300200d202541086a290000221d37030020002025290000221e370000200041086a2226201d370000200041106a2227201b370000200041186a222820183700002006201e37036020062024360284012006202036028001202541206a212541002104024002400240024020010e020201000b410021042001210a0340200a410176222920046a210920092004200820094105746a2000412010ec084101481b2104200a20296b220a41014b0d000b0b200820044105746a2000412010ec08450d010b20242000290000370000202441186a2028290000370000202441106a2027290000370000202441086a2026290000370000202441206a21240b20252022470d000b200628025c210420062802582123200628025421220b201fa7212a2006202136024c200620203602482006202420206b4105753602500240024020040d00202221240c010b202220044105746a212020222125202221240340200b202541186a2900002218370300200c202541106a290000221b370300200d202541086a290000221d37030020002025290000221e370000200041086a2226201d370000200041106a2227201b370000200041186a222820183700002006201e37036020062024360284012006202236028001202541206a212541002104024002400240024020010e020201000b410021042001210a0340200a410176222920046a210920092004200820094105746a2000412010ec084101481b2104200a20296b220a41014b0d000b0b200820044105746a2000412010ec08450d010b20242000290000370000202441186a2028290000370000202441106a2027290000370000202441086a2026290000370000202441206a21240b20252020470d000b0b20062023360258200620223602542006202420226b41057536025c2006290348211f2006290340211d2006290350211b200629035821180240202a450d000240200628022c41ffffff3f71450d002006280228102e0b200628023841ffffff3f71450d002006280234102e0b2006201d3703202006201f3703282006201b370330200620183703380b2006201f370388012006201b37039001201420183703002006201d37038001200620173602a00102400240201fa722040d002015201610ff010c010b2018a7210a2015201620064180016a10c0050240201f422088a741ffffff3f71450d002004102e0b200a41ffffff3f71450d00201b422088a7102e0b201341206a211302402006280214450d002015102e0b2017210420132010470d000c030b0b1036000b1038000b0240200f42ffffff3f83500d00200e102e0b20064198016a2200420037030020064190016a2204420037030020064180016a41086a220a42003703002006420037038001200641e0006a41c8afc9004113108102200a200641e0006a41086a22092900003703002006200629006037038001200641e0006a41c7c3cb004107108102200020092900003703002004200629006037030020064180016a2002200310c5052000420037030020044200370300200a42003703002006420037038001200641e0006a41c8afc9004113108102200a20092900003703002006200629006037038001200641e0006a41dbc3cb004105108102200020092900003703002004200629006037030020064180016a412010ff0102402007450d002008102e0b200524000bdc0301057f230041f0006b2201240020002d00002102200141186a2203200041196a290000370300200141106a2204200041116a290000370300200141086a2205200041096a2900003703002001200029000137030002400240024020020d00200141c0006a41186a22004200370300200141c0006a41106a22024200370300200141c0006a41086a420037030020014200370340200141c0006a41c8afc9004113108102200141206a41dbc3cb0041051081022000200141206a41086a29000037030020022001290020370300200141c0006a412010ff010c010b200141206a41186a2003290300370300200141206a41106a2004290300370300200141206a41086a200529030037030020012001290300370320200141c0006a41186a22004200370300200141c0006a41106a22024200370300200141c0006a41086a420037030020014200370340200141c0006a41c8afc9004113108102200141e0006a41dbc3cb0041051081022000200141e0006a41086a290000370300200220012900603703004120102c2200450d012001422037026420012000360260200141e0006a200141206a41201074200141c0006a412020012802602200200128026810b2012001280264450d002000102e0b200141f0006a24000f0b1036000be4750d067f017e047f017e0b7f057e027f027e027f027e027f017e177f230041f0036b22002400200041d0016a10ec02200041c0026a41186a22014200370300200041c0026a41106a22024200370300200041c0026a41086a22034200370300200042003703c002200041f0026a418ef9c00041101081022003200041f0026a41086a2204290000370300200020002900f0023703c002200041f0026a41c7c3cb00410710810220012004290000370300200220002900f002370300200041f0026a200041c0026a10f10220002802f002210520002902f4022106200142003703002002420037030020034200370300200042003703c002200041f0026a418ef9c000411010810220032004290000370300200020002900f0023703c002200041f0026a41a8f9c000410910810220012004290000370300200220002900f002370300200041f0026a200041c0026a10f1022005410820051b210720002802f0022208410820081b21092006420020051b2206a7210a20002902f402420020081b220ba7210c0240024002400240024002402006422088a7220d410674220e4106752208200b422088a7220f41067422104106756a22052008490d002005ad42307e2206422088a70d042006a72208417f4c0d04024020080d00410821110c020b2008102c22110d010c050b2007200e6a2112200920106a2113200a41ffffff1f7121144100210a4100210f4100210d41002115410821112007210e200921080340024002400240024020070d00200721050c010b2012200e470d01410021052014450d002007102e0b024020132008460d00200829031021062002200841306a2903003703002003200841286a290300370300200841186a290300210b2001200841386a290300370300200020082903203703c002200841c0006a2108200521070c020b200c41ffffff1f710d040c050b200e29031021062002200e41306a2903003703002003200e41286a290300370300200e41186a290300210b2001200e41386a2903003703002000200e2903203703c002200e41c0006a210e0b200041f0026a41186a22102001290300370300200041f0026a41106a2216200229030037030020042003290300370300200020002903c0023703f00202400240200d2015470d00024002402007450d00417f2012200e6b4106752205201320086b4106756a221520152005491b21050c010b201320086b41067521050b200d417f200541016a221520152005491b6a2205200d490d06200f2005200f20054b1b22054104200541044b1bad42307e2217422088a74541037421052017a7211502400240200d0d00200041003602a0020c010b200041083602a8022000200a3602a402200020113602a0020b20004180026a20152005200041a0026a107d20002802880221052000280280024101460d012000280284022111200541306e21150b2011200a6a220520002903f002370300200429030021172016290300211820102903002119200541286a200b370300200541206a2006370300200541186a2019370300200541106a2018370300200541086a2017370300200a41306a210a200f41026a210f200d41016a210d0c010b0b20050d040c030b0240024002400240200841306e221520054f0d00201541017422082005200820054b1b22054104200541044b1bad42307e2206422088a74541037421052006a721080240024020150d00200041003602f0020c010b200041f0026a41086a4108360200200020113602f0022000201541306c3602f4020b200041c0026a20082005200041f0026a107d200041c8026a280200210520002802c0024101460d0120002802c4022111200541306e21150b200d0d014100210d201121050c020b20050d050c040b200741206a2108200d410674220d41406a4106762101201121050340200841086a2903002106200841106a290300210b200841186a2903002117200841706a220e41086a290300211820082903002119200541206a200e290300370300200541286a2018370300200541186a2017370300200541106a200b370300200541086a200637030020052019370300200541306a2105200841c0006a2108200d41406a220d0d000b200141016a210d0b0240200a41ffffff1f71450d002007102e0b0240200f450d00200f410674210e200941206a21080340200841086a2903002106200841106a290300210b200841186a2903002117200841706a220a41086a290300211820082903002119200541206a200a290300370300200541286a2018370300200541186a2017370300200541106a200b370300200541086a200637030020052019370300200541306a2105200841c0006a2108200d41016a210d200e41406a220e0d000b0b200c41ffffff1f71450d010b2009102e0b0240024020002802d401220820002802d80122056b200d490d0020002802d00121080c010b2005200d6a220e2005490d0120084101742205200e2005200e4b1b22054104200541044b1bad42307e2206422088a74541037421052006a7210e0240024020080d00200041003602f0020c010b200041f0026a41086a4108360200200020002802d0013602f0022000200841306c3602f4020b200041c0026a200e2005200041f0026a107d200041c8026a2802002105024020002802c0024101460d00200020002802c40222083602d0012000200541306e3602d40120002802d80121050c010b20050d020c010b2008200541306c6a2011200d41306c10e9081a200020002802d801200d6a22083602d80102402015450d00201541306c450d002011102e20002802d80121080b02400240024020080d00200041f8026a41013a00002000410c3a00f002200041f0026a10fe01024020002802d4012205450d00200541306c450d0020002802d001102e0b42c0b2cd3b21060c010b200841ffffff3f712008470d022008410574220d417f4c0d0220002802d0012105200d102c2204450d030240024002400240200d410576221020084f0d00200041f0026a41086a4101360200200020043602f0022000200d3602f402200041c0026a200d410476220d2008200d20084b1b220d4104200d41044b1b220d410574200d41ffffff3f71200d46200041f0026a107d200041c0026a41086a280200210d20002802c0024101460d0120002802c4022104200d41057621100b20052005200841306c6a470d01410021160c020b200d0d050c040b200841306c220d41506a41306e210e20042108034020082005290000370000200841186a200541186a290000370000200841106a200541106a290000370000200841086a200541086a290000370000200841206a2108200541306a2105200d41506a220d0d000b200e41016a21160b200041d8026a4200370300200041c0026a41106a4200370300200041c0026a41086a22054200370300200042003703c002200041f0026a41f8fcc60041081081022005200041f0026a41086a2208290000370300200020002900f0023703c002200041f0026a41a8aac800410d108102200241086a2008290000370000200220002900f002370000200041b8016a200041c0026a412010f802200041b8016a41106a290300211a20002903c001211b20002802b8012103200041f0016a418ef9c0004110108102200041c0026a41fbafc90041061081024120102c2205450d03200042203702f402200020053602f002200041f0026a200041f0016a41101074200041f0026a200041c0026a4110107420002802f8022205417f4c0d0220002802f002210d0240024020050d00410121080c010b2005102c2208450d040b2008200d200510e9082108200041e0016a41086a200041f0026a41086a220a280200220d360200200041dc016a41026a220e200041c0026a41026a2d00003a0000200020002903f00222063703e001200020002f00c0023b01dc0120004194026a200d3602002000200536028802200020053602840220002008360280022000200637028c02200041003a009c022000410b360298022000419f026a200e2d00003a0000200020002f01dc013b009d02200041f0026a20004180026a10fa02024002400240024002400240024002400240024020002802b00322050d000240200028028402450d00200028028002102e0b4108211c4100211d024020004190026a280200450d00200028028c02102e0b4100210c0c010b200041c0026a41186a2208200041f0026a41186a290300370300200041c0026a41106a220d200041f0026a41106a290300370300200041c0026a41086a200a290300370300200020002903f0023703c002200041f0026a41286a2903002106200029039003210b20002902b403211741c000102c221c450d0c201c200b370300201c20002903c002370310201c2017370234201c2005360230201c2006370308201c41186a200041c0026a41086a2202290300370300201c41206a200d290300370300201c41286a2008290300370300200041a0026a41186a20004180026a41186a290300370300200041a0026a41106a20004180026a41106a290300370300200041a0026a41086a20004180026a41086a29030037030020002000290380023703a002200041f0026a200041a0026a10fa020240024020002802b00322070d004101210c4101211d0c010b41f400210d20004198036a21014101210c4101211d0340200041c0026a41186a200041f0026a41186a220e2903002206370300200041c0026a41106a200041f0026a41106a220a290300220b3703002002200041f0026a41086a220f2903002217370300200020002903f00222183703c00220012903002119200029039003211e20002902b403211f200e2006370300200a200b370300200f2017370300200020183703f0020240201d200c470d00200c41016a2205200c490d0e200c41017422082005200820054b1b22054104200541044b1b220541ffffff1f7120054641037421082005410674210502400240200c0d00200041003602f0010c010b200041083602f8012000201c3602f0012000200c4106743602f4010b200041e0026a20052008200041f0016a107d20002802e802210520002802e0024101460d0420002802e402211c2005410676210c0b201c200d6a2205414c6a220820193703082008201e3703002005415c6a220820002903f002370300200841086a200f290300370300200841106a200a290300370300200841186a200e2903003703002005201f3702002005417c6a2007360200200d41c0006a210d201d41016a211d200041f0026a200041a0026a10fa0220002802b00322070d000b0b024020002802a402450d0020002802a002102e0b200041b0026a280200450d0020002802ac02102e0b201d41ffffff1f7141386c2220417f4c0d0a0240024020200d00410821210c010b2020102c2221450d0c0b201a420020031b2122201b420020031b212302400240201c201d41067422246a201c470d0041002125420021260c010b200041a8016a20232022427f420010e708200041a8016a41086a2903002206420020002903a801220b42015620064200522006501b22051b211e200b420120051b211f201c201d4106746a2101200041f0026a41306a2103200041f0026a41106a210d4100210e4100212520212105201c21080340200d41186a220f200841286a290300370300200d41106a2207200841206a290300370300200d41086a2202200841186a290300370300200d200841106a2903003703002000200841086a2903003703f802200020082903003703f0022003200841306a10c80120004198016a20002903f00220002903f802201f201e10e70820002903a003210620002802a803210a2005200029039801427f20004198016a41086a290300501b3703002002290300210b20072903002117200f2903002118200d2903002119200541306a200a360200200541206a2018370300200541186a2017370300200541106a200b370300200541086a2019370300200541286a2006370300417f200e200a6a220a200a200e491b210e200541386a2105202541016a21252001200841c0006a2208470d000b200ead42a895b1037e21260b20003502d801211a200020163602a802200020103602a402200020043602a0022025ad221b42387e2206422088a70d0a2006a7220e417f4c0d0a02400240200e0d00410821050c010b200e102c2205450d0c0b200041003602c802200020053602c0022000200e41386e22073602c4020240200e4138490d00200041f0026a41286a210f200041f0026a41086a210d202121082007210a0340200e450d01200a450d04200d2008290308370300200d41186a200841206a290300370300200d41106a200841186a290300370300200d41086a200841106a290300370300200020082903003703f002200f200841286a10c801200541306a200041f0026a41306a290300370300200541286a200f290300370300200541206a200041f0026a41206a290300370300200541186a200041f0026a41186a290300370300200541106a200041f0026a41106a290300370300200541086a200d290300370300200520002903f002370300200541386a2105200e41486a210e200841386a2108200a417f6a220a0d000b0b200020253602c80242002106200042003703f00220004180026a4121200041a0026a200041c0026a200041f0026a10fb022000280280024101460d032000418c026a28020021014108210220004180026a41086a280200212720004180026a41186a280200212820004194026a280200212920004180026a41106a280200212a200028028402212b200041f0026a41186a22054200370300200041f0026a41106a222c4200370300200041f0026a41086a22084200370300200042003703f002200041f0016a418ef9c00041101081022008200041f0016a41086a290000370300200020002900f0013703f002200041c0026a41c7c3cb0041071081022005200041c0026a41086a290000370300202c20002900c002370300200041c0026a200041f0026a10f102024020002802c0022205450d00200041f0026a412010ff0120002902c4022106200521020b2006422088a7220d410674410675220541ffffff3f712005470d0a20054105742208417f4c0d0a0240024020080d004101212d0c010b2008102c222d450d0c0b02400240024002402008410576222e20054f0d002008410476220e2005200e20054b1b22054104200541044b1b220541ffffff3f71200546210e200541057421050240024020080d00200041003602f0020c010b200041f8026a4101360200200020083602f4022000202d3602f0020b200041c0026a2005200e200041f0026a107d200041c8026a280200210520002802c0024101460d0120002802c402212d2005410576212e0b200d0d014100212f0c020b20050d0d0c0c0b200d410674210e200d41067441406a4106762103200041f0026a41206a210d202d2105200221080340200041f0026a41386a200841386a290300370300200041f0026a41306a200841306a290300370300200041f0026a41286a200841286a290300370300200d200841206a290300370300200041c0026a41086a220a200d41086a290300370300200041c0026a41106a220f200d41106a290300370300200041c0026a41186a2207200d41186a2903003703002000200d2903003703c002200541186a2007290300370000200541106a200f290300370000200541086a200a290300370000200520002903c002370000200541206a2105200841c0006a2108200e41406a220e0d000b200341016a212f0b0240200642ffffff1f83500d002002102e0b4200210620004188036a4200370300200041f0026a41106a420037030041082102200041f0026a41086a22054200370300200042003703f002200041f0016a418ef9c00041101081022005200041f0016a41086a290000370300200020002900f0013703f002200041c0026a41a8f9c0004109108102202c41086a200041c0026a41086a290000370000202c20002900c002370000200041c0026a200041f0026a10f102024020002802c0022205450d00200041f0026a412010ff0120002902c4022106200521020b2006422088a7220d410674410675220541ffffff3f712005470d0a20054105742208417f4c0d0a0240024020080d00410121300c010b2008102c2230450d0c0b02400240024002402008410576223120054f0d002008410476220e2005200e20054b1b22054104200541044b1b220541ffffff3f71200546210e200541057421050240024020080d00200041003602f0020c010b200041f8026a4101360200200020083602f402200020303602f0020b200041c0026a2005200e200041f0026a107d200041c8026a280200210520002802c0024101460d0120002802c4022130200541057621310b200d0d01410021050c020b20050d0d0c0c0b200d410674210e200d41067441406a4106762103200041f0026a41206a210d20302105200221080340200041f0026a41386a200841386a290300370300200041f0026a41306a200841306a290300370300200041f0026a41286a200841286a290300370300200d200841206a290300370300200041c0026a41086a220a200d41086a290300370300200041c0026a41106a220f200d41106a290300370300200041c0026a41186a2207200d41186a2903003703002000200d2903003703c002200541186a2007290300370000200541106a200f290300370000200541086a200a290300370000200520002903c002370000200541206a2105200841c0006a2108200e41406a220e0d000b200341016a21050b0240200642ffffff1f83500d002002102e0b2030200510fc020240024020010d00202b21080c010b20004188016a20232022427f420010e70820004188016a41086a29030022064200200029038801220b42015620064200522006501b22051b2117200b420120051b2118200141306c210d202b2105202b21080340200541286a2903002106200541206a290300210b200041c0026a41186a220e200541186a290300370300200041c0026a41106a220a200541106a290300370300200041c0026a41086a220f200541086a290300370300200020052903003703c0020240200b2006844200510d00200041d8006a200642002018420010e808200041e8006a20174200200b420010e808200041f8006a200b42002018420010e808200041f0026a41186a200e290300220b370300200041f0026a41106a200a2903002219370300200041f0026a41086a200f290300221e370300200020002903c002221f3703f002200841186a200b370300200841106a2019370300200841086a201e3703002008201f370300200841286a427f200041f8006a41086a290300220b200029035820002903687c7c221920064200522017420052712000290360420052722000290370420052722019200b5472220e1b3703002008427f2000290378200e1b370320200841306a21080b200541306a2105200d41506a220d0d000b0b024002402008202b6b41306d2232410d2032410d491b223341306c22050d00410821340c010b2005102c2234450d0c0b203220336b2135024020330d00410021360c070b203341306c220d41506a41306e210e20342105202b21080340200841086a2903002106200841106a290300210b200841186a2903002117200841206a290300211820082903002119200541286a200841286a290300370300200541206a2018370300200541186a2017370300200541106a200b370300200541086a200637030020052019370300200541306a2105200841306a2108200d41506a220d0d000b200e41016a213602402035450d002033450d00202b202b203341306c6a203541306c10ea081a0b0240203641144b0d00203641014d0d07200e417f6a2105200e41306c20346a41506a21084102210d034020362005490d032008200d10fd02200841506a2108200d41016a210d2005417f6a2205417f470d000c080b0b2036410176ad42307e2206422088a70d0a2006a72237417f4c0d0a2037102c2238450d0b203441506a2139203441f07e6a213a410421104100213b410021032036213c0340203c213d4100213c4101210d0240203d417f6a220e450d000240024002400240024002402034200e41306c6a203d41306c220f20346a41a07f6a412010ec084100480d00203d417e6a210e203a200f6a21054100213c4100210803400240200e2008470d00203d210d0c080b200841016a2108200541306a2005412010ec08210d200541506a2105200d417f4a0d000b200841016a210d2008417f73203d6a210e0c010b203a200f6a2105024003400240200e4101470d004100210e0c020b200e417f6a210e200541306a2005412010ec082108200541506a210520084100480d000b0b203d200e490d01203d20364b0d02203d200e6b220d410176220a450d002039200f6a21052034200e41306c6a21080340200041c0026a41186a220f200841186a2207290300370300200041c0026a41106a2202200841106a2201290300370300200041c0026a41086a2204200841086a2216290300370300200020082903003703c002200841206a22112903002106200541286a2215290300210b200541086a22132903002117200541106a22122903002118200541186a221429030021192005290300211e2011200541206a22092903003703002007201937030020012018370300201620173703002008201e370300200841286a220729030021172007200b370300201220022903003703002014200f29030037030020132004290300370300200520002903c0023703002015201737030020092006370300200541506a2105200841306a2108200a417f6a220a0d000b0b0240200e0d00200e213c0c050b0240200d41094d0d00200e213c0c050b203d20364b0d02203d200e6b210d200e417f6a21052039200e41306c6a21080340203d2005490d0b2008200d41016a220d10fd022005417f6a220e20054f0d04200841506a2108200e2105200d410a490d000c040b0b200e203d41e4d1cc001057000b203d203641e4d1cc00104d000b203d200e417f6a2205490d07203d203641f4d1cc00104d000b200e41016a213c0b02402003203b470d00203b41016a2205203b490d0c203b41017422082005200820054b1b22054104200541044b1b220541ffffffff017120054641027421082005410374210502400240203b0d00200041003602f0020c010b200041043602f802200020103602f0022000203b4103743602f4020b200041c0026a20052008200041f0026a107d20002802c8022105024020002802c0024101470d0020050d0e0c0d0b20002802c40221102005410376213b0b201020034103746a2205200d3602042005203c360200200341016a22132103024020134102490d0002400240024003400240024002400240201020132203417f6a22134103746a2205280200450d00200341037420106a220a41746a280200220e200528020422084d0d00200341024d0d0820102003417d6a22054103746a280204220d2008200e6a4d0d01200341034d0d08200a41646a280200200d200e6a4b0d080c010b20034103490d012005280204210820102003417d6a22054103746a280204210d0b200d2008490d010b2003417e6a21050b02402003200541016a22124d0d00200320054d0d02201020054103746a2216280204221420162802006a2205201020124103746a22112802002215490d03200520364b0d04201641046a21092034201541306c6a22012011280204220441306c22086a210e200541306c210d02400240200520156b220f20046b22052004490d0020382001200810e908220220086a210a0240024020044101480d00200f20044a0d010b200121052002210d0c020b2034200d6a21072002210d2001210503402005200e200d200e200d412010ec08410048220f1b2208290300370300200541286a200841286a290300370300200541206a200841206a290300370300200541186a200841186a290300370300200541106a200841106a290300370300200541086a200841086a290300370300200d200d41306a200f1b210d200541306a2105200e41306a200e200f1b220e20074f0d02200a200d4b0d000c020b0b2038200e200541306c220810e908220220086a210a0240024020044101480d00200541014e0d010b200e21052002210d0c010b2039200d6a2108200e21050340200541506a210e200a41506a210f2008200e200f200f200e412010ec0841004822071b220d290300370300200841286a200d41286a290300370300200841206a200d41206a290300370300200841186a200d41186a290300370300200841106a200d41106a290300370300200841086a200d41086a290300370300200a200f20071b210a02402001200e200520071b2205490d002002210d0c020b200841506a21082002210d2002200a490d000b0b2005200d200a200d6b220820084130706b10e9081a2009201420046a360200201620153602002011201141086a20032012417f736a41037410ea081a41012103201341014d0d050c010b0b201220034184d2cc00103c000b200520034194d2cc00103c000b2015200541a4d2cc001057000b2005203641a4d2cc00104d000b203c450d060c000b0b20050d0a0c090b2005203641c4d1cc001056000b200720074188decc00103c000b200028028402210d0240201d450d00201d4106742108201c41346a210503400240200528020041ffffff3f71450d002005417c6a280200102e0b200541c0006a2105200841406a22080d000b0b0240200c41ffffff1f71450d00201c102e0b200d4105460d03200041f8026a41023a00002000410c3a00f002200041f0026a10fe010c030b2005203d41f4d1cc001057000b0240203b41ffffffff0171450d002010102e0b2037413070210520374130490d0020372005460d002038102e0b02402035410176220d450d00203541306c202b6a41506a2105202b21080340200041f0026a41286a220e200841286a220a290300370300200041f0026a41206a220f200841206a2207290300370300200041f0026a41186a2202200841186a2201290300370300200041f0026a41106a2203200841106a2204290300370300200041f0026a41086a2210200841086a2216290300370300200020082903003703f002200541086a22112903002106200541106a2215290300210b200541186a22132903002117200541206a22122903002118200541286a2214290300211920082005290300370300200a201937030020072018370300200120173703002004200b370300201620063703002014200e2903003703002012200f290300370300201320022903003703002015200329030037030020112010290300370300200520002903f002370300200541506a2105200841306a2108200d417f6a220d0d000b0b203541ffffff3f712035470d0320354105742205417f4c0d030240024020050d00410121030c010b2005102c2203450d050b0240024002402005410576221420354f0d00200541047622082035200820354b1b22084104200841044b1b220841ffffff3f71200846210d200841057421080240024020050d00200041003602f0020c010b200041f8026a4101360200200020053602f402200020033602f0020b200041c0026a2008200d200041f0026a107d200041c8026a2802002105024020002802c0024101460d0020002802c40221032005410576211420354521380c020b20050d070c060b203545213820350d00410021150c010b203241306c203341306c6b210d203541306c41506a41306e210e20032105202b2108034020052008290000370000200541186a200841186a290000370000200541106a200841106a290000370000200541086a200841086a290000370000200541206a2105200841306a2108200d41506a220d0d000b200e41016a21150b2003201510fc022036ad42187e2206422088a70d032006a72205417f4c0d030240024020050d004108210f0c010b2005102c220f450d050b0240024002400240200541186e221320364f0d00201341017422082036200820364b1b22084104200841044b1bad42187e2206422088a74541037421082006a7210d02400240200541174b0d00200041003602f0020c010b200041f0026a41086a41083602002000200f3602f0022000201341186c3602f4020b200041c0026a200d2008200041f0026a107d200041c8026a280200210520002802c0024101460d0120002802c402210f200541186e21130b20342034203641306c6a2211462212450d01410021020c020b20050d060c050b2034203641306c22056a210d200541506a41306e210e200f210520342108034020052008360200200541106a4200370300200541086a4200370300200541186a2105200d200841306a2208470d000b200e41016a21020b201c201d4106746a2116024002400240201d0d00201c21040c010b201c21050340200541c0006a210420052802302210450d010240200541346a290200221e422088a74105742208450d00200541086a290300211820052903002119201020086a2101410021072010210a024003404100210502400240024020020e020201000b410021052002210803402008410176220e20056a210d200d2005200f200d41186c6a280200200a412010ec084101481b21052008200e6b220841014b0d000b0b200f200541186c6a2208280200200a412010ec080d00200220054d0d02200041386a20184200411020076bad2206420010e808200041c8006a201942002006420010e8082008427f20082903082206427f20002903482000290340420052200041c8006a41086a290300220b20002903387c2217200b547222051b7c220b200b200654220d200841106a220e2903002206427f201720051b7c200dad7c220b200654200b2006511b22051b370308200e427f200b20051b3703000b200741016a21072001200a41206a220a470d000c020b0b2005200241b4f9c000103c000b0240201e42ffffff3f83500d002010102e0b2004210520042016470d000c020b0b20162004460d000340200441c0006a21050240200441346a28020041ffffff3f71450d00200441306a280200102e0b2005210420162005470d000b0b0240200c41ffffff1f71450d00201c102e0b0240024002402002450d00200f280200220d450d00024020024101460d00200f200241186c6a210a200f41186a2105200f41106a2903002106200f290308210b03402005280200220e450d012006200541106a2903002217200b200541086a290300221856200620175620062017511b22081b2106200b201820081b210b200d200e20081b210d200541186a2205200a470d000b0b02402013450d00201341186c450d00200f102e0b200d0d014100210e0c020b4100210e2013450d01201341186c450d01200f102e0c010b200041a0026a41186a200d41186a290000370300200041a0026a41106a200d41106a290000370300200041a0026a41086a200d41086a2900003703002000200d2900003703a0024101210e0b203641ffffff3f712036470d0320364105742205417f4c0d030240024020050d00410121070c010b2005102c2207450d050b02400240024002402005410576220920364f0d00200541047622082036200820364b1b22084104200841044b1b220841ffffff3f71200846210d200841057421080240024020050d00200041003602f0020c010b200041f8026a4101360200200020053602f402200020073602f0020b200041c0026a2008200d200041f0026a107d200041c8026a280200210520002802c0024101460d0120002802c4022107200541057621090b2012450d01410021010c020b20050d060c050b2034203641306c22056a210d200541506a41306e210a2007210520342108034020052008290000370000200541186a200841186a290000370000200541106a200841106a290000370000200541086a200841086a290000370000200541206a2105200d200841306a2208470d000b200a41016a21010b200041f0026a20072001202d202f10fe02200041f0026a41106a280200210c20002802f402211d20002802f002211c20002802fc02223d20004184036a2802002007200110f502200041f9026a2202200041a0026a41086a29030037000020004181036a200041a0026a41106a29030037000020004189036a200041a0026a41186a2903003700002000200e3a00f002200020002903a0023700f102200041f0026a10f602024020002802d80141306c2205450d0020002802d001220e20056a2104200041c0026a41086a2116200041a8036a21100340200e41306a210f0240024002400240024020010e020300010b410021050c010b410021052001210803402008410176220a20056a210d200d20052007200d4105746a200e412010ec084101481b21052008200a6b220841014b0d000b0b200720054105746a200e412010ec08450d010b024002400240024020150e020300010b410021050c010b410021052015210803402008410176220a20056a210d200d20052003200d4105746a200e412010ec084101481b21052008200a6b220841014b0d000b0b200320054105746a200e412010ec08450d010b200041186a200e200e290320200e41286a220829030010cb02200029031821062000200041186a41086a290300220b3703f802200020063703f002024002402006200b844200520d002000200041f0026a3602c002200041c0026a10cc020c010b200042f0f2bda1a7ee9cb9f9003703c002200041f0026a200041c0026a10cd02200041086a200041f0026a2006200b10fd01200041c0026a41106a200041086a41086a2903002218200b7d20002903082217200654ad7d200b20187d2006201754ad7d20172006562018200b562018200b511b22051b3703002000201720067d200620177d20051b3703c80220002005ad3703c0020240024020050d00200020163602f001200041f0016a10cc020c010b200020163602f001200041f0016a10ce020b200041f0026a41186a200b3703002000200637038003200041063a00f8022000410e3a00f002200041f0026a10fe010b200e2903202106200e41186a290000210b200e41106a2900002117200e29000021182010200829030037030020022018370000200241086a200e41086a290000370000200241106a2017370000200241186a200b370000200041053a00f8022000410c3a00f002200020063703a003200041f0026a10fe010b200f210e200f2004470d000b0b201120346b41306e220541ffffff1f712005470d0320054106742208417f4c0d030240024020080d00410821100c010b2008102c2210450d050b4100210d200041003602e802200020103602e0022000200841067622163602e4020240201620054f0d002008410576220e2005200e20054b1b22054104200541044b1b220541ffffff1f71200546410374210e200541067421050240024020080d00200041003602f0020c010b200041f0026a41086a4108360200200020083602f402200020103602f0020b200041c0026a2005200e200041f0026a107d200041c8026a280200210520002802c0024101460d03200020002802c40222103602e0022000200541067622163602e4020b024020120d0020002802d80141306c2101203641306c41506a41306e211520002802d00121042010210f2034210203402002220e41306a2102200121052004210802400340024020050d00420021064200210b0c020b200541506a21052008200e412010ec08210d200841306a220a2108200d0d000b200a41706a22052903002106200541086a290300210b0b200041c0026a41186a2205200e41186a290300370300200041c0026a41106a2208200e41106a290300370300200041c0026a41086a220d200e41086a290300370300200e41286a2903002117200e2903202118200e2903002119200f2006370310200f41186a200b370300200020193703c002200f2018370300200f2017370308200f41386a2005290300370300200f41306a2008290300370300200f20002903c002370320200f41286a200d290300370300200f41c0006a210f20022011470d000b201541016a210d0b2000200d3602e80220004188036a4200370300200041f0026a41106a4200370300200041f0026a41086a22054200370300200042003703f002200041f0016a418ef9c00041101081022005200041f0016a41086a290000370300200020002900f0013703f002200041c0026a41c7c3cb004107108102202c41086a200041c0026a41086a290000370000202c20002900c002370000200041f0026a200041e0026a10ff0202402016450d002010102e0b203541ffffff1f712035470d0320354106742205417f4c0d030240024020050d00410821150c010b2005102c2215450d050b41002108200041003602e802200020153602e0022000200541067622133602e402024002400240201320354f0d00200541057622082035200820354b1b22084104200841044b1b220841ffffff1f71200846410374210d200841067421080240024020050d00200041003602f0020c010b200041f0026a41086a4108360200200020053602f402200020153602f0020b200041c0026a2008200d200041f0026a107d200041c8026a2802002105024020002802c0024101460d00200020002802c40222153602e0022000200541067622133602e4020c020b20050d070c060b20380d010b202b203541306c6a211020002802d80141306c2116203541306c41506a41306e211220002802d00121112015210a202b210f0340200f41286a2903002106200f290320210b200041f0026a41186a2202200f41186a290000370300200041f0026a41106a2201200f41106a290000370300200041f0026a41086a2204200f41086a2900003703002000200f2900003703f002200f41306a210f201621052011210802400340024020050d0042002117420021180c020b200541506a21052008200041f0026a412010ec08210d200841306a220e2108200d0d000b200e41706a22052903002117200541086a29030021180b200041c0026a41186a22052002290300370300200041c0026a41106a22082001290300370300200041c0026a41086a220d2004290300370300200020002903f0023703c002200a2006370308200a200b370300200a2017370310200a41186a2018370300200a20002903c002370320200a41286a200d290300370300200a41306a2008290300370300200a41386a2005290300370300200a41c0006a210a200f2010470d000b201241016a21080b200020083602e80202402027450d00202741306c450d00202b102e0b20004188036a220d4200370300200041f0026a41106a22084200370300200041f0026a41086a22054200370300200042003703f002200041f0016a418ef9c00041101081022005200041f0016a41086a220e290000370300200020002900f0013703f002200041c0026a41a8f9c0004109108102202c41086a220a200041c0026a41086a220f290000370000202c20002900c002370000200041f0026a200041e0026a10ff0202402013450d002015102e0b200d42003703002008420037030020054200370300200042003703f002200041f0016a418ef9c00041101081022005200e290000370300200020002900f0013703f002200041c0026a419ef9c000410a108102200a200f290000370000202c20002900c002370000200041f0026a412010ff0120004184036a203636020020082033360200200541003a00002000410c3a00f002200041f0026a410c6a2034360200200041f0026a10fe01200d42003703002008420037030020054200370300200042003703f002200041f0016a418ef9c00041101081022005200e290000370300200020002900f0013703f002200041c0026a41e0a3c200410e108102200a200f290000370000202c20002900c0023700002000200041f0026a4120108e022000280200210220002802042101200d42003703002008420037030020054200370300200042003703f002200041f0016a418ef9c00041101081022005200e290000370300200020002900f0013703f002200041c0026a41e0a3c200410e108102200a200f290000370000202c20002900c0023700002000200141016a410120021b3602c002200041f0026a4120200041c0026a410410b2010240200c41ffffff3f71450d00203d102e0b0240201d41ffffff3f71450d00201c102e0b02402009450d002007102e0b02402014450d002003102e0b02402031450d002030102e0b0240202e450d00202d102e0b02402028450d002028412c6c2108202a210503400240200541046a280200220d450d00200d41246c450d002005280200102e0b2005412c6a2105200841546a22080d000b0b2029450d002029412c6c450d00202a102e0b201b42f094c0337e201a42c0a8ee3f7e7c20267c2106201a4280e1eb177e210b02402025450d00202541386c21082021412c6a210503400240200528020041ffffff3f71450d002005417c6a280200102e0b200541386a2105200841486a22080d000b0b2006200b7c2106201b42c0f0f50b7e210b02402024450d002020450d002021102e0b2006200b7c2106201a4280c2d72f7e210b024020002802d4012205450d00200541306c450d0020002802d001102e0b2006200b7c21060b200041f0036a240020060f0b20050d010b1038000b1036000b9d0202017f037e230041d0006b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822010d00420021040c010b200328020c210202400240200341086a41086a2802004110490d00200141086a290000210520012900002106420121040c010b20034100360220200342013703182003410a36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341909dc5003602382003200341286a360248200341346a419cebc000200341386a103d1a2003280218200328022010ef020240200328021c450d002003280218102e0b420021040b2002450d002001102e0b2000200637030820002004370300200041106a2005370300200341d0006a24000bbf0402017f057e23004180016b220524002005200436020c20052003360208200541d4e2cc00200141086a20024108491b36021020054100200241786a2201200120024b1b360214200541d8006a200541106a109301200541386a41086a2202200541e1006a290000370300200541386a41106a2201200541e9006a290000370300200541386a41186a2203200541f1006a290000370300200520052900593703380240024002400240024020052d00584101460d00200541186a41186a2003290300370300200541186a41106a2001290300370300200541186a41086a2002290300370300200520052903383703182005200541086a10ab0102402005280200450d00200541003602580c030b200541d8006a200541086a200528020410920120052802582202450d02200529025c21060240200528020c22014110490d0020052005280208220341106a3602082005200141706a220436020c200441104f0d020b200642ffffff3f83500d022002102e0c020b200041003602400c030b200341086a2900002107200329000021082005200141606a36020c2005200341206a36020820020d010b200041003602400c010b200341186a29000021092003290010210a20002005290318370000200041186a200541186a41186a290300370000200041106a200541186a41106a290300370000200041086a200541186a41086a290300370000200041386a20093703002000200a370330200041286a20073703002000200837032020002006370244200020023602400b20054180016a24000be60203057f017e037f230041d0006b220224002002200128020c200141146a280200108b050240024020022802002203450d00200141086a2104200141106a210502400340024002402004280200220620022902042207422088a722084b0d0020012802002003200610ec08450d010b2007a7450d032003102e0c030b02402005280200450d00200128020c102e0b2001200336020c2005200737020020022003200810ed020240024020022802002203450d002002280208210920022802042108024020012d001c450d00200128020c200128021410ff010b2001280214220a20042802002206490d032002200128020c20066a200a20066b20032009200128021811050020022802400d012008450d002003102e0b2002200128020c2001280214108b05200228020022030d010c030b0b2000200241d00010e9081a2008450d022003102e0c020b2006200a41e89ec5001056000b200041003602400b200241d0006a24000bea6609037f017e017f017e187f037e097f027e067f230041c0036b22052400200541b0026a41086a2206200241086a280200360200200520022902003703b00220054180026a41086a2202200341086a2802003602002005200329020037038002200541e0026a200541b0026a20054180026a10b904200541086a41086a200541e0026a41086a22032802002207360200200520052903e0022208370308200541186a41086a200541f4026a2802002209360200200520052902ec02220a37031820062007360200200520083703b002200220093602002005200a37038002200541e0026a2001200541b0026a20054180026a10e206200541c8006a41086a2206200541f8026a2802003602002005200541f0026a2903003703482003280200210b200541e0026a410c6a280200210220052802e402210c024002400240024002400240024002400240024020052802e0024101460d00200541286a41086a200628020036020020052005290348370328024020042903004201520d00200541286a2004280208200441106a290300200441186a29030010c0040b200c20024102746a210702400240024020010d00200c2103200c210d0c010b200c2103200c210d2002450d0020024102742104200c2103200c210d03402003220241046a210320022802002202450d012002280208220641016a41004c0d022002200636020802400240200241f4006a2d00000d0020022002280200417f6a220636020020060d01200241046a22062006280200417f6a220636020020060d012002102e0c010b200d2002360200200d41046a210d2001417f6a2201450d020b2004417c6a22040d000b200721030b0240200720036b2202450d00200241027541027421020340200328020022012001280200417f6a3602000240200328020022012802000d00200141046a22012001280200417f6a3602002003280200220141046a2802000d002001102e0b200341046a21032002417c6a22020d000b0b02400240200d200c6b220e410275220f41144b0d00200f41014d0d0641022103200c200f417e6a22024102746a21010340200f2002490d022001200310e306200341016a21032001417c6a21012002417f6a2202417f470d000c070b0b200f410176220341ffffffff03712003470d0b20034102742210417f4c0d0b2010102c2211450d0a200c417c6a2112200c41746a2113410421144100211541002116200f2117034020172109410021174101210202402009417f6a2204450d00024002400240024002400240024002400240024002400240200c20044102746a2802002203280208220241016a41004c0d0020032002360208200c2009417e6a22074102746a2802002202280208220141016a41004c0d01200328025021032002200136020820032002280250490d04201320094102746a210341002117410021010340024020072001470d00200921020c0e0b200341046a2802002202280208220441016a41004c0d032002200436020820032802002204280208220641016a41004c0d0420022802502102200420063602082003417c6a2103200141016a2101200220042802504f0d000b200141016a21022001417f7320096a21040c050b41bcd9cc00411820054180026a41c4f8c90041d4f8c900103e000b41bcd9cc00411820054180026a41c4f8c90041d4f8c900103e000b41bcd9cc00411820054180026a41c4f8c90041d4f8c900103e000b41bcd9cc00411820054180026a41c4f8c90041d4f8c900103e000b2013200941027422076a210302400340024020044101470d00410021040c020b200341046a2802002202280208220141016a41004c0d032002200136020820032802002201280208220641016a41004c0d0420022802502102200120063602082004417f6a21042003417c6a210320022001280250490d000b0b20092004490d032009200f4b0d04200920046b22024101762206450d00200c20044102746a2103201220076a21010340200328020021072003200128020036020020012007360200200341046a21032001417c6a21012006417f6a22060d000b0b024020040d00200421170c070b0240200241094d0d00200421170c070b2009200f4b0d04200920046b21022004417f6a2103201220044102746a2101034020092003490d0c2001200241016a220210e3062003417f6a220420034f0d062001417c6a2101200421032002410a490d000c060b0b41bcd9cc00411820054180026a41c4f8c90041d4f8c900103e000b41bcd9cc00411820054180026a41c4f8c90041d4f8c900103e000b2004200941e4d1cc001057000b2009200f41e4d1cc00104d000b20092004417f6a2203490d062009200f41f4d1cc00104d000b200441016a21170b0240024002400240024020162015460d00201621030c010b201541016a22032015490d10201541017422012003200120034b1b22034104200341044b1b220341ffffffff01712003464102742101200341037421030240024020150d00200541003602e0020c010b200541043602e802200520143602e002200520154103743602e4020b20054180026a20032001200541e0026a107d20052802880221012005280280024101460d01200528028402211420152103200141037621150b201420034103746a2203200236020420032017360200201641016a22182116201841024f0d010c020b20010d0d0c0e0b024002400240024002400240024003400240024002400240201420182216417f6a22184103746a2203280200450d00201641037420146a220641746a2802002204200328020422024d0d00201641024d0d0c20142016417d6a22034103746a2802042201200220046a4d0d01201641034d0d0c200641646a280200200120046a4b0d0c0c010b20164103490d012003280204210220142016417d6a22034103746a28020421010b20012002490d010b2016417e6a21030b02402016200341016a22194d0d00201620034d0d02201420034103746a221a280204221b201a2802006a2203201420194103746a221c280200221d490d032003200f4b0d04200c201d4102746a221e201c280204221f41027422026a210120034102742106024002402003201d6b2207201f6b2203201f490d002011201e200210e908220320026a210402400240201f4101480d002007201f4a0d010b201e2102200321030c020b200c20066a212020032103201e2102034020012802002206280208220741016a41004c0d082006200736020820032802002207280208220941016a41004c0d092006280250210620072009360208200220012003200620072802504922061b2802003602002003200341046a20061b2103200241046a2102200141046a200120061b220120204f0d02200420034b0d000c020b0b201120012003410274220210e908222020026a210402400240201f4101480d00200341014e0d010b20012102202021030c010b201220066a21092001210203402004417c6a22032802002201280208220641016a41004c0d09200120063602082002417c6a22062802002207280208222141016a41004c0d0a2001280250210120072021360208200920062003200120072802504922011b2802003602002004200320011b21040240201e2006200220011b2202490d00202021030c020b2009417c6a21092020210320202004490d000b0b20022003200420036b417c7110e9081a201a41046a201b201f6a360200201a201d360200201c201c41086a20162019417f736a41037410ea081a41012116201841014d0d090c010b0b201920164184d2cc00103c000b200320164194d2cc00103c000b201d200341a4d2cc001057000b2003200f41a4d2cc00104d000b41bcd9cc00411820054180026a41c4f8c90041d4f8c900103e000b41bcd9cc00411820054180026a41c4f8c90041d4f8c900103e000b41bcd9cc00411820054180026a41c4f8c90041d4f8c900103e000b41bcd9cc00411820054180026a41c4f8c90041d4f8c900103e000b2017450d050c000b0b2002200f41c4d1cc001056000b41bcd9cc00411820054180026a4190b7c00041a0b7c000103e000b2000200c360204200041013602002000410c6a2002360200200041086a200b3602000c030b2003200941f4d1cc001057000b0240201541ffffffff0171450d002014102e0b2010450d002011102e0b20052802302102200528022c21012005200528022822033602402005200136023c2005200336023820052003200241e0006c6a221a36024441042122024002402002450d00200541b0026a410472211c200541e0026a41346a21020240034020054180026a41286a2204200341286a29030037030020054180026a41206a2206200341206a29030037030020054180026a41186a2207200341186a29030037030020054180026a41106a2209200341106a29030037030020054180026a41086a2220200341086a2903003703002005200329030037038002200341306a2802002101200541c8006a41086a22212003413c6a290200370300200541c8006a41106a221e200341c4006a290200370300200541c8006a41186a2216200341cc006a290200370300200541c8006a41206a221f200341d4006a290200370300200541c8006a41286a2214200341dc006a2802003602002005200341346a290200370348024020010d00200341e0006a211a0c020b200541e0026a41286a2004290300370300200541e0026a41206a2006290300370300200541e0026a41186a2007290300370300200541e0026a41106a2009290300370300200541e0026a41086a202029030037030020022005290348370200200241086a2021290300370200200241106a201e290300370200200241186a2016290300370200200241206a201f290300370200200241286a201428020036020020052005290380023703e0022005200136029003200541b0026a200541e0026a10bd07024020052802b00222010d00200341e0006a2203201a470d010c020b0b200541f8006a41106a201c41106a2902002208370300200541d8016a41086a201c41086a290200220a370300200541d8016a41106a2008370300200541d8016a41186a201c41186a2902002223370300200541d8016a41206a201c41206a29020022243703002005200341e0006a3602402005201c29020022253703d801200541b0016a41206a22032024370300200541b0016a41186a22022023370300200541b0016a41106a22042008370300200541b0016a41086a2206200a370300200520253703b001412c102c2222450d0720222001360200202220052903b0013702042022410c6a2006290300370200202241146a20042903003702002022411c6a2002290300370200202241246a2003290300370200200541a0016a41086a200541386a41086a2903002208370300200520052903383703a001024002402008a7220120052802ac01221a470d0041012126410121270c010b200541e0026a41346a2102200541b0026a410472211c41012126410121270240034020054180026a41286a22042001220341286a29030037030020054180026a41206a2206200341206a29030037030020054180026a41186a2207200341186a29030037030020054180026a41106a2209200341106a29030037030020054180026a41086a2220200341086a2903003703002005200329030037038002200341306a2802002101200541c8006a41086a22212003413c6a290200370300200541c8006a41106a221e200341c4006a290200370300200541c8006a41186a2216200341cc006a290200370300200541c8006a41206a221f200341d4006a290200370300200541c8006a41286a2214200341dc006a2802003602002005200341346a2902003703482001450d01200541e0026a41286a2004290300370300200541e0026a41206a22042006290300370300200541e0026a41186a22062007290300370300200541e0026a41106a22072009290300370300200541e0026a41086a2209202029030037030020022005290348370200200241086a2021290300370200200241106a201e290300370200200241186a2016290300370200200241206a201f290300370200200241286a201428020036020020052005290380023703e0022005200136029003200541b0026a200541e0026a10bd07024020052802b00222010d00200341e0006a2201201a470d010c020b200541f8006a41106a201c41106a2902002208370300200541d8016a41086a201c41086a290200220a370300200541d8016a41106a2008370300200541d8016a41186a201c41186a2902002223370300200541d8016a41206a201c41206a29020022243703002005200341e0006a3602a8012005201c29020022253703d801200541b0016a41206a22032024370300200541b0016a41186a22202023370300200541b0016a41106a22212008370300200541b0016a41086a221e200a370300200520253703b0012004200329030037030020062020290300370300200720212903003703002009201e290300370300200520052903b0013703e0020240024020272026470d00202641016a22032026490d0d202641017422202003202020034b1b22034104200341044b1bad422c7e2208422088a74541027421032008a721200240024020260d0020054100360280020c010b2005410436028802200520223602800220052026412c6c360284020b200541b0026a2020200320054180026a107d20052802b802210320052802b0024101460d0120052802b40221222003412c6e21260b20222027412c6c6a220320013602002003410c6a2009290300370200200320052903e002370204200341146a20072903003702002003411c6a2006290300370200200341246a2004290300370200202741016a212720052802a801220120052802ac01221a470d010c030b0b2003450d0a0c090b2005200341e0006a3602a8010b200541a0016a10ac020c020b2005201a3602400b200541386a10ac0241002127410021260b200541053602b00220222027412c6c6a2128202221290240034020292028460d012029280208220341ffffffff03712003470d072029280200210402400240200341027422020d004104212a0c010b2002102c222a450d070b02400240024002402002410276222b20034f0d00200241017622012003200120034b1b22014104200141044b1b220141ffffffff03712001464102742106200141027421010240024020020d00200541003602e0020c010b200541043602e802200520023602e4022005202a3602e0020b20054180026a20012006200541e0026a107d20052802880221022005280280024101460d01200528028402212a2002410276212b0b20042004200341246c22016a470d01410021030c020b2002450d090c080b200441206a21032001415c6a41246e2104202a2102034020022003280200360200200341246a2103200241046a21022001415c6a22010d000b200441016a21030b4101450d0720034103742202417f4c0d070240024020020d004108212c0c010b2002102c222c450d070b0240024002402002410376222d20034f0d00200241027622012003200120034b1b22014104200141044b1b41037421010240024020020d00200541003602e0020c010b200541083602e802200520023602e4022005202c3602e0020b20054180026a20014108200541e0026a107d200528028802210202402005280280024101460d00200528028402212c2002410376212d0c020b2002450d0a0c090b20030d00410021130c010b20034102742201417c6a4102762104202c2103202a2102034020032002350200370300200341086a2103200241046a21022001417c6a22010d000b200441016a21130b2029412c6a212e202c201341037422046a21064200210820042103202c210202400240024002400340024020030d00024020130d004100212041082107410021130c050b0240428094ebdc0320082008428094ebdc035422031b2008428094ebdc0320031b7d222f4200520d00201341ffffffff01712013470d0e20134103742203417f4c0d0e2003102c2207450d0d2007202c200310e9081a200341037621200c050b202f2013ad2230822124202f20308021252006202c6b2203410376220241ffffffff00712002470d0d20034101742203417f4c0d0d0240024020030d004108211f0c010b2003102c221f450d0d0b02400240024002402003410476223120024f0d00200341037622012002200120024b1b22024104200241044b1b220241ffffffff00712002464103742101200241047421020240024020030d00200541003602e0020c010b200541083602e802200520033602e4022005201f3602e0020b20054180026a20022001200541e0026a107d20052802880221032005280280024101460d01200528028402211f200341047621310b201341037441786a2232410376211541002102201f2103202c21010340200341086a200129030037030020032002360200200341106a2103200241016a2102200141086a2101200441786a22040d000b201541016a210f02402032419f014b22330d002032450d07200f410474201f6a41706a210741002104201521010340200f20012203417f6a2201490d040240200f20016b22204102490d00201f20034104746a220341086a2206290300201f20014104746a220241086a2209290300220a5a0d00200228020021212002200329030037030020092006290300370300024020204103490d002004417f6a210941002102200721030340200341186a2206290300200a5a0d0120092002460d06200341086a20062903003703002003200341106a22062903003703002006210320042002417f6a2202470d000b200621030b2003200a370308200320213602000b200741706a21072004417f6a210420010d000c080b0b200f410176220341ffffffff00712003470d1020034104742234417f4c0d102034102c2212450d0f201f41706a2135201f41586a213641002110410421144100211e200f211803400240024020182207417f6a22030d0041012106410021180c010b0240024002400240024002400240201f20034104746a41086a29030020074104742209201f6a41686a290300220a540d002007417e6a2104203620096a210241002118410021030340024020042003470d00200721060c090b200341016a2103200a200229030022235a2101200241706a21022023210a20010d000b200341016a21062003417f7320076a21030c010b203620096a210202400340024020034101470d00410021030c020b2003417f6a2103200a20022903002223542101200241706a21022023210a20010d000b0b20072003490d012007200f4b0d02200720036b22064101762204450d00201f20034104746a2102203520096a21010340200541e0026a41086a2209200241086a2220290300370300200520022903003703e002200141086a2221290300210a200220012903003703002020200a37030020212009290300370300200120052903e002370300200241106a2102200141706a21012004417f6a22040d000b0b024020030d00200321180c060b0240200641094d0d00200321180c060b2007200f4b0d03200320076b2101201f20034104746a2109034020072003417f6a2218490d050240200720186b22064102490d00201f20034104746a220341086a2204290300201f20184104746a220241086a2220290300220a5a0d00200228020021212002200329030037030020202004290300370300024020064103490d0041012102200921030340200341186a2204290300200a5a0d01200120026a4101460d06200341086a20042903003703002003200341106a2204290300370300200421032001200241016a22026a0d000b200421030b2003200a370308200320213602000b2018450d06200941706a21092001417f6a2101201821032006410a4f0d060c000b0b2003200741e4d1cc001057000b2007200f41e4d1cc00104d000b2002200641d4d1cc00103c000b20072003417f6a2218490d002007200f41f4d1cc00104d000b2018200741f4d1cc001057000b02400240024002400240201e2010460d00201e21030c010b201041016a22032010490d15201041017422022003200220034b1b22034104200341044b1b220341ffffffff01712003464102742102200341037421030240024020100d00200541003602e0020c010b200541043602e802200520143602e002200520104103743602e4020b20054180026a20032002200541e0026a107d20052802880221022005280280024101460d01200528028402211420102103200241037621100b201420034103746a2203200636020420032018360200201e41016a2219211e201941024f0d010c020b2002450d130c120b0240024002400340024002400240024020142019221e417f6a22194103746a2203280200450d00201e41037420146a220641746a2802002204200328020422024d0d00201e41024d0d082014201e417d6a22034103746a2802042201200220046a4d0d01201e41034d0d08200641646a280200200120046a4b0d080c010b201e4103490d01200328020421022014201e417d6a22034103746a28020421010b20012002490d010b201e417e6a21030b0240201e200341016a221b4d0d00201e20034d0d02201420034103746a221a2802042211201a2802006a22032014201b4103746a221c280200221d490d032003200f4b0d04201a41046a2117201f201d4104746a2221201c280204221641047422026a210420034104742106024002402003201d6b220720166b22032016490d0020122021200210e908222020026a21010240024020164101480d00200720164a0d010b20212103202021020c020b201f20066a210920202102202121030340200320042002200441086a290300200241086a2903005422061b2207290300370300200341086a200741086a2903003703002002200241106a20061b2102200341106a2103200441106a200420061b220420094f0d02200120024b0d000c020b0b201220042003410474220210e908220720026a21010240024020164101480d00200341014e0d010b20042103200721020c010b203520066a21062004210303402006200341706a2204200141706a2209200141786a290300200341786a2903005422021b2220290300370300200641086a202041086a2903003703002001200920021b2101024020212004200320021b2203490d00200721020c020b200641706a21062007210220072001490d000b0b20032002200120026b41707110e9081a2017201120166a360200201a201d360200201c201c41086a201e201b417f736a41037410ea081a4101211e201941014d0d050c010b0b201b201e4184d2cc00103c000b2003201e4194d2cc00103c000b201d200341a4d2cc001057000b2003200f41a4d2cc00104d000b2018450d060c000b0b2003450d0f0c0e0b410120026b202041d4d1cc00103c000b2001200f41c4d1cc001056000b200341786a2103200820022903007c220a2008542101200241086a2102200a21082001450d000b0240202d450d00202c102e0b411e212041b4d2cc0021030c030b0240201041ffffffff0171450d002014102e0b2034450d002012102e0b0240024002400240024002400240024002400240200842ff93ebdc03560d00428094ebdc032030802123410021030240202f2030540d004100210320132102034020152003490d09201f20034104746a2201290308220a20257c2208200a540d08200141086a2008370300024020082023540d00200341016a20137021030b2002417f6a22020d000b0b2024500d01034020152003490d06201f20034104746a2202290308220a42017c2208200a540d05200241086a2008370300024020082023540d00200341016a20137021030b2024427f7c222450450d000c020b0b201f29030821232013417f6a220121030240202f2030540d00034020152003490d04201f20034104746a220242002002290308220820257d220a200a20085622021b200a20021b220a370308200320012003417f6a2204200420034b1b200a2023561b21032024202520087d420020021b7c21242013417f6a22130d000b0b2024500d00034020152003490d0202400240201f20034104746a22022903082208427f7c220a2008580d0020012003417f6a2202200220034b1b21030c010b200241086a200a370300200320012003417f6a2202200220034b1b200a2023561b21032024427f7c21240b20244200520d000b0b02400240024020330d002032450d0a200f410474201f6a41706a2107410021040340200f20152203417f6a2215490d030240200f20156b22204102490d00201f20034104746a2203280200201f20154104746a220228020022064f0d0020022903082108200241086a200341086a29030037030020022003290300370300024020204103490d002004417f6a210941002101200721030340200341106a220228020020064f0d0120092001460d05200341086a200341186a290300370300200320022903003703002002210320042001417f6a2201470d000b200221030b20032008370308200320063602000b200741706a21072004417f6a210420150d000c0b0b0b200f410176220341ffffffff00712003470d1320034104742235417f4c0d132035102c2215450d12201f41706a2113201f41506a211041002112410421144100211e200f211803400240024020182209417f6a22030d0041012107410021180c010b0240024002400240024002400240201f20034104746a28020020094104742220201f6a41606a2802002202490d002009417e6a2107201020206a210141002118410021030340024020072003470d00200921070c090b200341016a21032002200128020022044f2106200141706a21012004210220060d000b200341016a21072003417f7320096a21030c010b201020206a210102400340024020034101470d00410021030c020b2003417f6a2103200220012802002204492106200141706a21012004210220060d000b0b20092003490d012009200f4b0d02200920036b22074101762204450d00201f20034104746a2102201320206a21010340200541e0026a41086a2206200241086a2220290300370300200520022903003703e002200141086a22212903002108200220012903003703002020200837030020212006290300370300200120052903e002370300200241106a2102200141706a21012004417f6a22040d000b0b024020030d00200321180c060b0240200741094d0d00200321180c060b2009200f4b0d03200320096b2104201f20034104746a2120034020092003417f6a2218490d050240200920186b22074102490d00201f20034104746a2203280200201f20184104746a220228020022064f0d0020022903082108200241086a200341086a29030037030020022003290300370300024020074103490d0041012102202021030340200341106a220128020020064f0d01200420026a4101460d06200341086a200341186a29030037030020032001290300370300200121032004200241016a22026a0d000b200121030b20032008370308200320063602000b2018450d06202041706a21202004417f6a2104201821032007410a4f0d060c000b0b2003200941e4d1cc001057000b2009200f41e4d1cc00104d000b2002200741d4d1cc00103c000b20092003417f6a2218490d002009200f41f4d1cc00104d000b2018200941f4d1cc001057000b02400240024002400240201e2012460d00201e21030c010b201241016a22032012490d18201241017422022003200220034b1b22034104200341044b1b220341ffffffff01712003464102742102200341037421030240024020120d00200541003602e0020c010b200541043602e802200520143602e002200520124103743602e4020b20054180026a20032002200541e0026a107d20052802880221022005280280024101460d01200528028402211420122103200241037621120b201420034103746a2203200736020420032018360200201e41016a2219211e201941024f0d010c020b2002450d160c150b0240024002400340024002400240024020142019221e417f6a22194103746a2203280200450d00201e41037420146a220641746a2802002204200328020422024d0d00201e41024d0d082014201e417d6a22034103746a2802042201200220046a4d0d01201e41034d0d08200641646a280200200120046a4b0d080c010b201e4103490d01200328020421022014201e417d6a22034103746a28020421010b20012002490d010b201e417e6a21030b0240201e200341016a221b4d0d00201e20034d0d02201420034103746a221a2802042211201a2802006a22032014201b4103746a221c280200221d490d032003200f4b0d04201a41046a2117201f201d4104746a2221201c280204221641047422026a210120034104742106024002402003201d6b220720166b22032016490d0020152021200210e908220320026a21040240024020164101480d00200720164a0d010b20212102200321030c020b201f20066a210920032103202121020340200220012003200128020020032802004922061b2207290300370300200241086a200741086a2903003703002003200341106a20061b2103200241106a2102200141106a200120061b220120094f0d02200420034b0d000c020b0b201520012003410474220210e908220920026a21040240024020164101480d00200341014e0d010b20012102200921030c010b201320066a21062001210203402006200241706a2203200441706a2201200128020020032802004922071b2220290300370300200641086a202041086a2903003703002004200120071b2104024020212003200220071b2202490d00200921030c020b200641706a21062009210320092004490d000b0b20022003200420036b41707110e9081a2017201120166a360200201a201d360200201c201c41086a201e201b417f736a41037410ea081a4101211e201941014d0d050c010b0b201b201e4184d2cc00103c000b2003201e4194d2cc00103c000b201d200341a4d2cc001057000b2003200f41a4d2cc00104d000b2018450d090c000b0b410120016b202041d4d1cc00103c000b2015200f41c4d1cc001056000b2003200f419cd4cc00103c000b2003200f418cd4cc00103c000b41b4d3cc00412641fcd3cc00105d000b2003200f41ecd3cc00103c000b41b4d3cc00412641dcd3cc00105d000b2003200f41a4d3cc00103c000b0240201241ffffffff0171450d002014102e0b2035450d002015102e0b200f4104742201410475220341ffffffff01712003470d0920034103742202417f4c0d090240024020020d00410821070c010b2002102c2207450d090b02402002410376222020034f0d00200241027622042003200420034b1b22034104200341044b1b220341ffffffff01712003464103742104200341037421030240024020020d00200541003602e0020c010b200541083602e802200520023602e402200520073602e0020b20054180026a20032004200541e0026a107d20052802880221032005280280024101460d082005280284022107200341037621200b201f41086a2103200141706a410476210420072102034020022003290300370300200341106a2103200241086a2102200141706a22010d000b200441016a21132031450d00201f102e0b20134103742201410375220341ffffffff03712003470d0820034102742202417f4c0d080240024020020d00410421090c010b2002102c2209450d080b02400240024002402002410276222120034f0d00200241017622042003200420034b1b22034104200341044b1b220341ffffffff03712003464102742104200341027421030240024020020d00200541003602e0020c010b200541043602e802200520023602e402200520093602e0020b20054180026a20032004200541e0026a107d20052802880221032005280280024101460d012005280284022109200341027621210b200720016a22062007470d01410021010c020b2003450d0a0c090b4100210120092103200721020340200320022903002208a7417f2008428080808010541b2204418094ebdc032004418094ebdc03491b360200200141016a2101200341046a21032006200241086a2202470d000b0b02402020450d002007102e0b0240202d450d00202c102e0b02402001410274410275220320292802082202200220034b1b2201450d00202928020041206a210320092102034020032002280200360200200241046a2102200341246a21032001417f6a22010d000b0b410021032021450d002009102e0b0240202b450d00202a102e0b202e21292003450d000b200541033602b00220052020ad4220862003ad843702b4020b024020052802b00222034105470d00200e4102752203ad42307e2208422088a70d062008a72202417f4c0d060240024020020d004108211f0c010b2002102c221f450d060b0240024002400240200241306e221420034f0d00201441017422012003200120034b1b22014104200141044b1bad42307e2208422088a74541037421012008a72104024002402002412f4b0d00200541003602e0020c010b200541e0026a41086a41083602002005201f3602e0022005201441306c3602e4020b20054180026a20042001200541e0026a107d20054188026a28020021022005280280024101460d01200528028402211f200241306e21140b200c200d470d014100211a200c21020c020b2002450d080c070b200e417c6a41027641016a211a200541e0026a41086a2107200541e0026a41106a2109200541e0026a41186a212041002106201f2101200c2102024003402002220341046a21020240200328020022030d002006211a0c020b2003280208220441016a222141004c0d05200320213602082007200341dc006a2900003703002009200341e4006a2900003703002020200341ec006a2900003703002005200341d4006a2900003703e002200441026a41004c0d062003200436020820054180026a41086a2204200729030037030020054180026a41106a2221200929030037030020054180026a41186a221e2020290300370300200520052903e00237038002200341c8006a29030021082003290340210a20032003280200417f6a2216360200024020160d00200341046a22162016280200417f6a221636020020160d002003102e0b20012005290380023703002004290300212320212903002124201e2903002125200141286a2008370300200141206a200a370300200141186a2025370300200141106a2024370300200141086a2023370300200141306a2101200641016a2106200d2002470d000b200d21020b200d20026b220e41027521030b0240200e450d00200341027421030340200228020022012001280200417f6a3602000240200228020022012802000d00200141046a22012001280200417f6a3602002002280200220141046a2802000d002001102e0b200241046a21022003417c6a22030d000b0b0240200b41ffffffff0371450d00200c102e0b2000201f36020420004100360200200041186a2027360200200041146a2026360200200041106a20223602002000410c6a201a360200200041086a20143602000c010b200041086a20052902b402370200200020033602042000410136020002402027450d002027412c6c21022022210303400240200341046a2802002201450d00200141246c450d002003280200102e0b2003412c6a2103200241546a22020d000b0b02402026450d002026412c6c450d002022102e0b0240200e450d00200c210203402002220328020022022002280200417f6a360200200341046a21020240200328020022012802000d00200141046a22012001280200417f6a3602002003280200220341046a2802000d002003102e0b200d2002470d000b0b200b41ffffffff0371450d00200c102e0b200541c0036a24000f0b41bcd9cc00411820054180026a41f09cc50041c09dc500103e000b41bcd9cc00411820054180026a41f09cc50041d09dc500103e000b2003450d010b1036000b1038000bad0f07167f017e017f017e017f017e027f230041306b220224000240024002400240024002400240200141144b0d00200141014d0d0620002001417e6a22034105746a2104410221050340200320014b0d022004200510fa07200541016a2105200441606a21042003417f6a2203417f470d000c070b0b2001410176220341ffffff3f712003470d0220034105742206417f4c0d022006102c2207450d01200041606a2108200041a07f6a21094104210a4100210b4100210c2001210d0340200d210e4100210d410121050240200e417f6a220f450d000240024002400240024002402000200f4105746a200e410574221020006a41406a412010ec084100480d00200e417e6a210f200920106a21034100210d4100210403400240200f2004470d00200e21050c080b200441016a2104200341206a2003412010ec082105200341606a21032005417f4a0d000b200441016a21052004417f73200e6a210f0c010b200920106a2103024003400240200f4101470d004100210f0c020b200f417f6a210f200341206a2003412010ec082104200341606a210320044100480d000b0b200e200f490d01200e20014b0d02200e200f6b22054101762211450d00200820106a21032000200f4105746a21040340200241186a2210200441186a2212290000370300200241106a2213200441106a2214290000370300200241086a2215200441086a221629000037030020022004290000370300200341086a22172900002118200341106a2219290000211a200341186a221b290000211c200420032900003700002012201c3700002014201a37000020162018370000201b2010290300370000201920132903003700002017201529030037000020032002290300370000200341606a2103200441206a21042011417f6a22110d000b0b0240200f0d00200f210d0c050b0240200541094d0d00200f210d0c050b200e20014b0d02200e200f6b2105200f417f6a21032008200f4105746a21040340200e2003490d0a2004200541016a220510fa072003417f6a220f20034f0d04200441606a2104200f21032005410a490d000c040b0b200f200e41e4d1cc001057000b200e200141e4d1cc00104d000b200e200f417f6a2203490d06200e200141f4d1cc00104d000b200f41016a210d0b02400240024002400240200c200b460d00200c21030c010b200b41016a2203200b490d07200b41017422042003200420034b1b22034104200341044b1b220341ffffffff017120034641027421042003410374210302400240200b0d00200241003602000c010b200241043602082002200a3602002002200b4103743602040b200241206a200320042002107d2002280228210420022802204101460d012002280224210a200b21032004410376210b0b200a20034103746a220320053602042003200d360200200c41016a221b210c201b41024f0d010c020b20040d040c050b02400240024003400240024002400240200a201b220c417f6a221b4103746a2203280200450d00200c410374200a6a221141746a280200220f200328020422044d0d00200c41024d0d08200a200c417d6a22034103746a28020422052004200f6a4d0d01200c41034d0d08201141646a2802002005200f6a4b0d080c010b200c4103490d0120032802042104200a200c417d6a22034103746a28020421050b20052004490d010b200c417e6a21030b0240200c200341016a220e4d0d00200c20034d0d02200a20034103746a2216280204221d20162802006a2203200a200e4103746a22172802002219490d03200320014b0d04201641046a211e200020194105746a22142017280204221541057422046a210f2003410574210502400240200320196b221020156b22032015490d0020072014200410e908221320046a21110240024020154101480d00201020154a0d010b20142103201321040c020b200020056a2112201321042014210303402003200f2004200f2004412010ec0841004822101b2205290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a2900003700002004200441206a20101b2104200341206a2103200f41206a200f20101b220f20124f0d02201120044b0d000c020b0b2007200f2003410574220410e908221320046a21110240024020154101480d00200341014e0d010b200f2103201321040c010b200820056a2105200f21030340200341606a2104201141606a210f20052004200f200f2004412010ec0841004822121b2210290000370000200541186a201041186a290000370000200541106a201041106a290000370000200541086a201041086a2900003700002011200f20121b2111024020142004200320121b2203490d00201321040c020b200541606a21052013210420132011490d000b0b20032004201120046b41607110e9081a201e201d20156a360200201620193602002017201741086a200c200e417f736a41037410ea081a4101210c201b41014d0d050c010b0b200e200c4184d2cc00103c000b2003200c4194d2cc00103c000b2019200341a4d2cc001057000b2003200141a4d2cc00104d000b200d450d050c000b0b2003200141c4d1cc001056000b1036000b1038000b2003200e41f4d1cc001057000b0240200b41ffffffff0171450d00200a102e0b2006450d002007102e0b200241306a24000b840403027f017e097f230041306b220224000240024020014102490d00200041306a22032000412010ec08417f4a0d002000290300210420002003290300370300200241286a2205200041286a2206290300370300200241206a200041206a2207290300370300200241186a2208200041186a2209290300370300200241106a220a200041106a220b290300370300200241086a220c200041086a220d290300370300200d200341086a290300370300200b200341106a2903003703002009200341186a2903003703002007200341206a2903003703002006200341286a2903003703002002200437030041012107024020014103490d00410020016b2109200041e0006a210341012107034020032002412010ec08417f4a0d0120012007460d03200341506a22062003290300370300200641286a200341286a290300370300200641206a200341206a290300370300200641186a200341186a290300370300200641106a200341106a290300370300200641086a200341086a290300370300200341306a21032009200741016a22076a417f470d000b0b2000200741306c6a22032002290300370300200341286a2005290300370300200341206a200241206a290300370300200341186a2008290300370300200341106a200a290300370300200341086a200c2903003703000b200241306a24000f0b2001200141d4d1cc00103c000bd809010c7f230041c0006b220524002003410020041b21062001410020021b2107200341206a200320041b2108200141206a200120021b2109200120024105746a210a200320044105746a210b410021034100210c4101210d410021014100210e4101210f0240024003400240024020060d0020070d012000200d36020c200020013602082000200e3602042000200f360200200041146a2003360200200041106a200c360200200541c0006a24000f0b02402007450d00024020062007412010ec0822020d00410020092009200a4622021b2107410020082008200b4622041b21062009200941206a20021b21092008200841206a20041b21080c030b2002417f4a0d01200541186a2202200641186a290000370300200541106a2204200641106a290000370300200541086a2210200641086a29000037030020052006290000370300024002402003200c470d00200341016a22062003490d062003410174220c2006200c20064b1b22064104200641044b1b220641ffffff3f71200646210c200641057421060240024020030d00200541003602300c010b200541013602382005200d360230200520034105743602340b200541206a2006200c200541306a107d2005280228210620052802204101460d012005280224210d2006410576210c0b200d20034105746a22062005290300370000200641186a2002290300370000200641106a2004290300370000200641086a2010290300370000410020082008200b4622021b2106200341016a21032008200841206a20021b21080c030b20060d030c040b200541186a2202200641186a290000370300200541106a2204200641106a290000370300200541086a2210200641086a29000037030020052006290000370300024002402003200c470d00200341016a22072003490d05200341017422062007200620074b1b22074104200741044b1b220741ffffff3f712007462106200741057421070240024020030d00200541003602300c010b200541013602382005200d360230200520034105743602340b200541206a20072006200541306a107d2005280228210720052802204101460d012005280224210d2007410576210c0b200d20034105746a22072005290300370000200741186a2002290300370000200741106a2004290300370000200741086a201029030037000041002107410020082008200b4622021b2106200341016a21032008200841206a20021b21080c020b20070d020c030b200541186a2202200741186a290000370300200541106a2204200741106a290000370300200541086a2210200741086a29000037030020052007290000370300024002402001200e470d00200141016a22072001490d042001410174220e2007200e20074b1b22074104200741044b1b220741ffffff3f71200746210e200741057421070240024020010d00200541003602300c010b200541013602382005200f360230200520014105743602340b200541206a2007200e200541306a107d2005280228210720052802204101460d012005280224210f2007410576210e0b200f20014105746a22072005290300370000200741186a2002290300370000200741106a2004290300370000200741086a2010290300370000410020092009200a4622021b2107200141016a21012009200941206a20021b21090c010b0b2007450d010b1036000b1038000b810202047f017e230041206b2202240002400240200128020822034106744104722204417f4c0d00200128020021012004102c2205450d0120024100360208200220043602042002200536020020032002107602402003450d002003410674210303402002200141206a41201074200129030021062002200141086a290300370318200220063703102002200241106a41101074200141106a29030021062002200141186a290300370318200220063703102002200241106a41101074200141c0006a2101200341406a22030d000b0b2000412020022802002201200228020810b20102402002280204450d002001102e0b200241206a24000f0b1038000b1036000bc30402057f027e230041f0006b2203240002400240024020022802004113470d00200241086a2d00004104470d00200341c8006a2001108103200341306a200328024822042003280250108203200341d8006a41086a2003413b6a290000370300200341d8006a41106a2205200341c3006a2f00003b0100200320032900333703584101210120032d0032210620032d003121070240024020032d00304101460d00410021010c010b200341186a41106a20052f01003b0100200341186a41086a200341d8006a41086a290300370300200320032903583703180b0240200328024c450d002004102e0b2001450d01200341106a200341186a41106a2f010022013b0100200341086a200341186a41086a29030022083703002003200329031822093703002003413a6a2008370100200341c2006a20013b0100200320063a0031200320073a003020032009370132200341d8006a200341306a10e30220032802582204200328026010e40241ff017121010240200328025c450d002004102e0b20014102460d000240200241146a280200220441c40141c70120011b470d00200228020c41abcecc0041efcfcc0020011b200410ec08450d010b200041800e3b0001200041013a0000200041036a41033a00000c020b200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a42003703000c010b200041800e3b0001200041013a0000200041036a41013a00000b200341f0006a24000bf50101047f230041306b22022400200241b6d1cc004106108102200241106a41d6f9c0004109108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bc20602027f027e23004180016b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822010d00200041003a00000c010b200341106a2802002102200328020c2104200341003a007c024002402002450d00200320012d00003a0068200341013a007c024020024101460d00200320012d00013a0069200341023a007c20024102460d00200320012d00023a006a200341033a007c20024103460d00200320012d00033a006b200341043a007c20024104460d00200320012d00043a006c200341053a007c20024105460d00200320012d00053a006d200341063a007c20024106460d00200320012d00063a006e200341073a007c20024107460d00200320012d00073a006f200341083a007c20024108460d00200320012d00083a0070200341093a007c20024109460d00200320012d00093a00712003410a3a007c2002410a460d00200320012d000a3a00722003410b3a007c2002410b460d00200320012d000b3a00732003410c3a007c2002410c460d00200320012d000c3a00742003410d3a007c2002410d460d00200320012d000d3a00752003410e3a007c2002410e460d00200320012d000e3a00762003410f3a007c2002410f460d00200320012d000f3a0077200341103a007c20024110460d00200320012d00103a0078200341113a007c20024111460d00200320012d00113a0079200341123a007c20024112460d00200320012d00123a007a200341133a007c20024113460d00200341186a41086a200341e8006a41086a2903002205370300200320012d00133a007b200341186a41106a200341e8006a41106a2802002202360200200341143a007c200320032903682206370318200041116a2002360000200041096a200537000020002006370001410121020c020b200341003a007c0b20034100360220200342013703182003410a360234200320033602302003200341186a360264200341fc006a41013602002003420137026c200341909dc5003602682003200341306a360278200341e4006a419cebc000200341e8006a103d1a2003280218200328022010ef020240200328021c450d002003280218102e0b410021020b200020023a00002004450d002001102e0b20034180016a24000bd7c40108017f017e057f017e057f017e217f077e230041e00e6b2201240010840342002102024002400240024020004101460d00200141b0046a41186a22034200370300200141b0046a41106a22044200370300200141b0046a41086a22054200370300200142003703b004200141b8076a41a8f8c60041041081022005200141b8076a41086a2206290000370300200120012900b8073703b00420014198096a41c98bc500410b108102200320014198096a41086a22072900003703002004200129009809370300200141a0046a200141b0046a10850320012903a804210820012802a0042109200141d0046a41186a220a4200370300200141d0046a41106a220b4200370300200141d0046a41086a220c4200370300200142003703d004200141800d6a41a8f8c6004104108102200c200141800d6a41086a220d290000370300200120012900800d3703d004200141800d6a41fa8bc500410a108102200a200d290000370300200b20012900800d37030020014190046a200141d0046a10850320014180046a20012903980442002001280290041b420042e012420010e8080240024002400240024020012903880450450d002001290380042102200342003703002004420037030020054200370300200142003703b004200141b8076a41a8f8c600410410810220052006290000370300200120012900b8073703b00420014198096a41e38bc500410b108102200441086a20072900003700002004200129009809370000200141f0036a200141b0046a108503200220012903f803420020012802f0031b7c220e2002540d014200210242002008420020091b2208200e7d220e200e2008561b42e012540d05200141b0046a41186a22034200370300200141b0046a41106a220f420037030041082107200141b0046a41086a22064200370300200142003703b004200141800d6a41a081ca0041071081022006200141800d6a41086a2205290000370300200120012900800d3703b004200141800d6a41e4d1c100410c10810220032005290000370300200f20012900800d370300200141e8036a200141b0046a4120108e0220012802ec03211020012802e803211120034200370300200f420037030020064200370300200142003703b004200141800d6a41a081ca00410710810220062005290000370300200120012900800d3703b004200141800d6a4188d2c100410d10810220032005290000370300200f20012900800d370300200141b0046a1086032112200141c00c6a41186a22034200370300200141c00c6a41106a220c4200370300200141c00c6a41086a22064200370300200142003703c00c200141800d6a41a081ca00410710810220062005290000370300200120012900800d3703c00c200141800d6a41e4d1c100410c10810220032005290000370300200c20012900800d370300200141e0036a200141c00c6a4120108e0220012802e403210d20012802e0032113200141f0046a10870320034200370300200c420037030020064200370300200142003703c00c200141800d6a41a081ca00410710810220062005290000370300200120012900800d3703c00c200141800d6a41f09dc500410a10810220032005290000370300200c20012900800d370300200141800d6a200141c00c6a10880320012902840d2102200120012802800d2205410120051b22033602e005200120033602d80520012002420020051b22023e02dc05200120032002422088a74105746a3602e405200141003602e805200141800d6a200141d8056a10bd0102400240200141c00d6a280200450d0041d000102c2207450d0a2007200141800d6a41d00010e9081a200141b8076a41106a200141d8056a41106a280200360200200141b8076a41086a200141d8056a41086a290300370300200120012903d8053703b80720014198096a200141b8076a10bd01024002400240200141d8096a2802000d0041012105410121030c010b41d000210641012105410121030340200141800d6a20014198096a41d00010e9081a024020032005470d00200541016a22092005490d0d2005410174220a2009200a20094b1b22094104200941044b1bad42d0007e2202422088a74541037421092002a7210a0240024020050d00200141003602f80a0c010b200141083602800b200120073602f80a2001200541d0006c3602fc0a0b200141e00c6a200a2009200141f80a6a107d20012802e80c210520012802e00c4101460d0320012802e40c2107200541d0006e21050b200720066a200141800d6a41d00010e9081a200641d0006a2106200341016a210320014198096a200141b8076a10bd0120012802d8090d000b0b024020012802bc0741ffffff3f71450d0020012802b807102e0b2001200336028805200120053602840520012007360280050c020b2005450d090c0a0b20014100360288052001420837038005024020012802dc0541ffffff3f71450d0020012802d805102e0b41002105410021030b200141d80c6a4200370300200141d00c6a4200370300200141c00c6a41086a22064200370300200142003703c00c200141800d6a41a081ca0041071081022006200141800d6a41086a2209290000370300200120012900800d3703c00c200141800d6a41e4d1c100410c108102200c41086a2009290000370000200c20012900800d370000200141d8036a200141c00c6a4120108e0220012802dc03210620012802d8032109200141b8076a41bed8c800410810810220014198096a41a4fcc800411210810220012006410020091b3602e00c2001200141e00c6a410410a3013703f80a200141800d6a410c6a200141e00c6a41046a3602002001200141f80a6a41086a3602840d2001200141e00c6a3602880d2001200141f80a6a3602800d200141d8056a200141800d6a107c20012802e005220941206a2206417f4c0d070240024020060d004101210a0c010b2006102c220a450d090b200141003602880d200120063602840d2001200a3602800d200141800d6a200141b8076a41101074200141800d6a20014198096a41101074200141800d6a20012802d805220620091074024020012802dc05450d002006102e0b20012802800d220620012802880d108903024020012802840d450d002006102e0b200141d80c6a4200370300200141d00c6a4200370300200141c00c6a41086a22064200370300200142003703c00c200141800d6a41a081ca0041071081022006200141800d6a41086a2209290000370300200120012900800d3703c00c200141800d6a41e4d1c100410c108102200c41086a2009290000370000200c20012900800d370000200141d0036a200141c00c6a4120108e0220012802d403210620012802d0032109200141b8076a41bed8c800410810810220014198096a41edd8c800410e10810220012006410020091b3602e00c2001200141e00c6a410410a3013703f80a200141800d6a410c6a200141e00c6a41046a3602002001200141f80a6a41086a3602840d2001200141e00c6a3602880d2001200141f80a6a3602800d200141d8056a200141800d6a107c20012802e005220941206a2206417f4c0d070240024020060d004101210a0c010b2006102c220a450d090b200141003602880d200120063602840d2001200a3602800d200141800d6a200141b8076a41101074200141800d6a20014198096a41101074200141800d6a20012802d805220620091074024020012802dc05450d002006102e0b20012802800d220620012802880d108903024020012802840d450d002006102e0b024020030d00200141013a00840d200141083a00800d200141800d6a10fe012005450d05200541d0006c450d052007102e0c050b200141800d6a20014180056a10c601200141a3096a200141800d6a41086a280200360000200120012903800d37009b092001418c0d6a2001419f096a290000370000200141023a00840d200141083a00800d20012001290098093700850d200141800d6a10fe0120012802f8042114200141a0056a20014180056a41086a28020036020020012014360294052001200d410020131b220a36029005200120012903800537039805200141b8056a20014190056a41086a10c601200141003602d005200142013703c80520012802b805211520012802bc05211620012802c00521134104102c2205450d08200142043702d404200120053602d0042001200a3602800d200141d0046a200141800d6a41041074200141800d6a41f996c500108a0320014198096a20012802800d220320012802880d108b03200129029c09420020012802980922051b21022005410120051b2117024020012802840d450d002003102e0b200120024220883e02b404200120173602b004200141c8036a200141b0046a10ab01024020012802c803450d00410021184104210c4100210d0c040b20012802cc03220c20012802b40441246e22052005200c4b1bad42247e2208422088a70d072008a72205417f4c0d070240024020050d00410421190c010b2005102c2219450d090b200541246e211a0240200c0d004100210c0c030b4100210d034002400240024020012802b40422034104490d00200d41016a211820012802b0042207280000211b20012003417c6a22093602b4042001200741046a3602b00441002105200141003a00a00d2003417b6a210302400340200141003a00a80520092005460d01200141800d6a20056a200720056a220641046a2d00003a00002001200641056a3602b0042001200541016a22063a00a00d200120033602b4042003417f6a21032006210520064120470d000b20014198096a41186a2205200141800d6a41186a29030037030020014198096a41106a2203200141800d6a41106a29030037030020014198096a41086a2207200141800d6a41086a290300370300200120012903800d37039809200641ff01714120490d01200141d8056a41086a20072903002208370300200141f80a6a41186a22062005290300370300200141f80a6a41106a22052003290300370300200141f80a6a41086a22032008370300200120012903980922083703d805200120083703f80a200141e00c6a41186a22072006290300370300200141e00c6a41106a22062005290300370300200141e00c6a41086a22092003290300370300200120012903f80a3703e00c200d201a470d03201a41016a2205201a4f0d020c0c0b200541ff0171450d00200141003a00a00d0b410021184104210c0240201a450d00201a41246c450d002019102e0b4100210d0c060b201a41017422032005200320054b1b22054104200541044b1bad42247e2208422088a74541027421052008a7210302400240201a0d00200141003602800d0c010b200141043602880d200120193602800d2001201a41246c3602840d0b20014198096a20032005200141800d6a107d20012802a009210502402001280298094101470d0020050d0b0c0a0b200128029c092119200541246e211a0b2019200d41246c6a2205201b360200200520012903e00c3702042005410c6a2009290300370200200541146a20062903003702002005411c6a20072903003702002018210d2018200c460d030c000b0b41e8b2c40041fa0041e4b3c400105d000b41e8b2c40041fa0041f4b3c400105d000b200c410020191b210d201a410020191b21182019410420191b210c0b200141800d6a41f996c500200141d0046a108c0320014198096a20012802800d220320012802880d108d032001280298092105200129029c092108024020012802840d450d002003102e0b2008420020051b210820012802d804211c20012802d404211d20012802d004211e02402002a7450d002017102e0b2005410120051b211f2008a72119024002400240024002402013450d002008422088a7211a2015201341d0006c6a2117200141800d6a41d0006a2120200141800d6a410c6a211b200141b8076a41c4006a21212015210941002122024002400340200141d8056a41386a22232009220541386a290300370300200141d8056a41306a2224200541306a290300370300200141d8056a41286a2225200541286a290300370300200141d8056a41206a2226200541206a290300370300200141d8056a41186a2206200541186a290300370300200141d8056a41106a2207200541106a290300370300200141d8056a41086a2213200541086a290300370300200141b8076a41086a2203200541cc006a280200360200200120052903003703d8052001200541c4006a2902003703b807200541d0006a2109200541c0006a2802002205450d04200141f80a6a41386a22272023290300370300200141f80a6a41306a22232024290300370300200141f80a6a41286a22242025290300370300200141f80a6a41206a22252026290300370300200141f80a6a41186a22262006290300370300200141f80a6a41106a22282007290300370300200141f80a6a41086a22292013290300370300200141a8056a41086a222a2003280200360200200120012903d8053703f80a200120012903b8073703a805200141b8076a41386a2027290300370300200141b8076a41306a2023290300370300200141b8076a41286a2024290300370300200141b8076a41206a2025290300370300200141b8076a41186a2026290300370300200141b8076a41106a202829030037030020032029290300370300200120012903f80a3703b807200120053602f807202120012903a805370200202141086a202a2802003602004104102c2205450d0c200142043702840d200120053602800d2001200a36029809200141800d6a20014198096a41041074201b41086a41002900819745370000201b41002900f996453700002001200141b8076a36029c0d200141d8056a200141800d6a10ae01024020012802840d450d0020012802800d102e0b200141800d6a200141d8056a108e0320012802800d220320012802880d108f022105024020012802840d450d002003102e0b024002400240024020050d0020014198096a200141b8076a41d00010e9081a200141e00c6a200141c8056a10c801200141800d6a20014198096a41d00010e9081a202041086a200141e00c6a41086a280200360200202020012903e00c37020020014198096a200141d8056a108e03200128029809220520012802a009200141800d6a108f030240200128029c09450d002005102e0b024020012802c40d2205450d00200541306c450d0020012802c00d102e0b024020012802d40d41ffffff3f71450d0020012802d00d102e0b200141b0046a41186a22232006290300370300200141b0046a41106a22242007290300370300200141b0046a41086a22252013290300370300200120012903d8053703b004410021050240200d0e020302000b41002105200d2103034020052003410176220620056a2207200c200741246c6a280200200a4b1b2105200320066b220341014b0d000c020b0b20012802fc072205450d02200541306c450d0220012802f807102e0c020b200c200541246c6a2802002203200a460d0020052003200a496a21050b200141800d6a41186a22062023290300370300200141800d6a41106a22072024290300370300200141800d6a41086a22132025290300370300200120012903b0043703800d200d2005490d020240200d2018470d00201841016a22032018490d0d201841017422262003202620034b1b22034104200341044b1bad42247e2202422088a74541027421032002a721260240024020180d0020014100360298090c010b200141043602a0092001200c360298092001201841246c36029c090b200141e00c6a2026200320014198096a107d20012802e80c210320012802e00c4101460d0420012802e40c210c200341246e21180b200c200541246c6a220341246a2003200d20056b41246c10ea081a2003200a3602002003411c6a2006290300370200200341146a20072903003702002003410c6a2013290300370200200320012903800d370204200141d0046a41186a22032023290300370300200141d0046a41106a22062024290300370300200141d0046a41086a22072025290300370300200120012903b0043703d0040240201a2019470d00201941016a22052019490d0d201941017422132005201320054b1b22054104200541044b1b220541ffffff3f712005462113200541057421050240024020190d00200141003602800d0c010b200141013602880d2001201f3602800d200120194105743602840d0b20014198096a20052013200141800d6a107d20012802a009210502402001280298094101470d0020050d0f0c0e0b200128029c09211f200541057621190b200d41016a210d201f201a4105746a220520012903d004370000200541186a2003290300370000200541106a2006290300370000200541086a200729030037000041012122201a41016a211a0b20092017470d000b201721090c030b2005200d1045000b20030d090c080b2016450d01201641d0006c450d012015102e0c010b024020172009460d0003402009220541d0006a21090240200541c4006a2802002203450d00200341306c450d00200541c0006a280200102e0b20172009470d000b0b02402016450d00201641d0006c450d002015102e0b2022410171450d00024002400240201a450d00201a4105742107200141c40d6a2105201f21030340200141d0046a2003108e03200141800d6a20012802d004220920012802d80410900320014198096a41086a2213200141800d6a41086a29030037030020014198096a41106a2217200141800d6a41106a29030037030020014198096a41186a221b200141800d6a41186a29030037030020014198096a41206a2221200141800d6a41206a29030037030020014198096a41286a2223200141800d6a41286a29030037030020014198096a41306a2224200141800d6a41306a29030037030020014198096a41386a2225200141800d6a41386a290300370300200141e00c6a41086a2226200541086a290200370300200141e00c6a41106a2227200541106a290200370300200141e00c6a41186a2228200541186a280200360200200120012903800d37039809200120052902003703e00c024020012802c00d2206450d00200141b8076a41386a2025290300370300200141b8076a41306a2024290300370300200141b8076a41286a2023290300370300200141b8076a41206a2021290300370300200141b8076a41186a201b290300370300200141b8076a41106a2017290300370300200141b8076a41086a2013290300370300200141d8056a41086a2026290300370300200141d8056a41106a2027290300370300200141d8056a41186a202828020036020020012001290398093703b807200120012903e00c3703d8050b024020012802d404450d002009102e0b20060d02200341206a2103200741606a22070d000b0b42002102410821090c010b200141f80a6a41386a2205200141b8076a41386a290300370300200141f80a6a41306a2213200141b8076a41306a290300370300200141f80a6a41286a2217200141b8076a41286a290300370300200141f80a6a41206a221b200141b8076a41206a290300370300200141f80a6a41186a2221200141b8076a41186a290300370300200141f80a6a41106a2223200141b8076a41106a290300370300200141f80a6a41086a2224200141b8076a41086a290300370300200141c00c6a41086a2225200141d8056a41086a290300370300200141c00c6a41106a2226200141d8056a41106a290300370300200141c00c6a41186a2227200141d8056a41186a280200360200200120012903b8073703f80a200120012903d8053703c00c41e000102c2209450d08200920012903f80a37030020092006360240200920012903c00c370244200941386a2005290300370300200941306a2013290300370300200941286a2017290300370300200941206a201b290300370300200941186a2021290300370300200941106a2023290300370300200941086a2024290300370300200941cc006a2025290300370200200941d4006a2026290300370200200941dc006a2027280200360200024020074120470d0042818080801021020c010b200341206a2113201f201a4105746a222241606a2115200141800d6a41c4006a210542818080801021020340201321030340200141d0046a2003108e03200141800d6a20012802d004220720012802d80410900320014198096a41086a2213200141800d6a41086a222929030037030020014198096a41106a2217200141800d6a41106a222a29030037030020014198096a41186a221b200141800d6a41186a222029030037030020014198096a41206a2221200141800d6a41206a29030037030020014198096a41286a2223200141800d6a41286a29030037030020014198096a41306a2224200141800d6a41306a29030037030020014198096a41386a2225200141800d6a41386a290300370300200141e00c6a41086a2226200541086a290200370300200141e00c6a41106a2227200541106a290200370300200141e00c6a41186a2228200541186a280200360200200120012903800d37039809200120052902003703e00c024020012802c00d2206450d00200141b8076a41386a2025290300370300200141b8076a41306a2024290300370300200141b8076a41286a2023290300370300200141b8076a41206a2021290300370300200141b8076a41186a201b290300370300200141b8076a41106a2017290300370300200141b8076a41086a2013290300370300200141f80a6a41086a2026290300370300200141f80a6a41106a2027290300370300200141f80a6a41186a202828020036020020012001290398093703b807200120012903e00c3703f80a0b024020012802d404450d002007102e0b024020060d002022200341206a2203470d010c030b0b200141d8056a41386a2207200141b8076a41386a2217290300370300200141d8056a41306a2213200141b8076a41306a221b290300370300200141d8056a41286a2227200141b8076a41286a2221290300370300200141d8056a41206a2228200141b8076a41206a2223290300370300200141d8056a41186a2216200141b8076a41186a2224290300370300200141d8056a41106a222b200141b8076a41106a2225290300370300200141d8056a41086a222c200141b8076a41086a2226290300370300200141c00c6a41086a222d200141f80a6a41086a290300370300200141c00c6a41106a222e200141f80a6a41106a290300370300200141c00c6a41186a222f200141f80a6a41186a280200360200200120012903b8073703d805200120012903f80a3703c00c2026202c2903003703002025202b290300370300202420162903003703002023202829030037030020212027290300370300201b201329030037030020172007290300370300200120012903d8053703b8072029202d290300370300202a202e2903003703002020202f280200360200200120012903c00c3703800d024002402002422088a722072002a7460d00200221080c010b200741016a22132007490d0920074101742227201320132027491b22134104201341044b1bad42e0007e2208422088a74541037421132008a721270240024020070d0020014100360298090c010b200141083602a00920012009360298092001200741e0006c36029c090b200141f80a6a2027201320014198096a107d20012802800b211320012802f80a4101460d0420012802fc0a2109201341e0006ead21080b200341206a21132009200741e0006c6a220720012903b807370300200741106a2025290300370300200741086a2026290300370300201b290300210e20172903002130202129030021312023290300213220242903002133200741c0006a2006360200200741186a2033370300200741206a2032370300200741286a2031370300200741386a2030370300200741306a200e370300200741c4006a20012903800d370200200741cc006a2029290300370200200741d4006a202a290300370200200741dc006a2020280200360200200842ffffffff0f8320024280808080107c4280808080708384210220152003470d000b0b200141a00d6a200d3602002001419c0d6a2018360200200141940d6a201a360200200141900d6a20193602002001200c3602980d2001201f36028c0d2001201c3602880d2001201d3602840d2001201e3602800d200d41246c41046a2205417f4c0d060240024020050d00410121030c010b2005102c2203450d080b200141003602c007200120053602bc07200120033602b807200d200141b8076a10760240200d450d00200c200d41246c6a2106200c210503402001200528020036029809200141b8076a20014198096a410410744120102c2203450d092001422037029c09200120033602980920014198096a200541046a220541201074200141b8076a200128029809220320012802a00910740240200128029c09450d002003102e0b200541206a22052006470d000b0b20014198096a41f996c500108a03200128029809220520012802a009200141b8076a10c5020240200128029c09450d002005102e0b024020012802bc07450d0020012802b807102e0b20014198096a41f996c500200141800d6a108c03200128029809220520012802a0092001418c0d6a1091030240200128029c09450d002005102e0b0240201d450d00201e102e0b0240201941ffffff3f71450d00201f102e0b2018450d02201841246c450d02200c102e0c020b0240201d450d00201e102e0b0240201941ffffff3f71450d00201f102e0b4100210902402018450d00201841246c450d00200c102e0b0c010b20130d050c040b024020012802cc0541ffffff3f71450d0020012802c805102e0b024020090d0020012802980521070240200141a0056a2802002205450d00200541d0006c2103200741c4006a21050340024020052802002206450d00200641306c450d002005417c6a280200102e0b200541d0006a2105200341b07f6a22030d000b0b024020014190056a410c6a2802002205450d00200541d0006c450d002007102e0b41bceacc00410c10ef0241adeacc00410f10ef020c010b4100210602400240024002402014410a6e417f732002422088a722076a220320074b0d0020144101201441014b1b2205418094ebdc036e2005418094ebdc03704100476a22064101200641014b1b220620054b0d012005200341036c220320052003491b20066ead428094ebdc037e200520066ead8042ffffffff0f834280bbb0217e428094ebdc0380a721060b200741ffffffff03712007470d0620074102742205417f4c0d060240024020050d004104210c0c010b2005102c220c450d080b02402005410276220d20074f0d00200541017622032007200320074b1b22034104200341044b1b220341ffffffff0371200346410274210d200341027421030240024020050d00200141003602800d0c010b200141880d6a4104360200200120053602840d2001200c3602800d0b20014198096a2003200d200141800d6a107d200141a0096a280200210502402001280298094101460d00200128029c09210c2005410276210d0c030b20050d080c070b20070d01410021050c020b41d0d8c800411941bcd7cc001039000b20072103200c2105034020052006360200200541046a21052003417f6a22030d000b200721050b200141b8036a20092007200c20052001280290051092034104102c2205450d04200142043702bc07200120053602b8072001200a3602800d200141b8076a200141800d6a41041074200141cc076a41002900819745370200200141002900f996453702c407200141b3096a200141b8076a41186a280200360000200141ab096a200141b8076a41106a290300370000200141a3096a20012903c007370000200120012903b80737009b09200141890d6a200141a0096a290000370000200141910d6a20014198096a41106a290000370000200141800d6a41186a200141af096a290000370000200141a00d6a41013a0000200141053a00800d20012001290098093700810d200141800d6a10fe010240200d450d00200c102e0b02402007450d00200741e0006c2103200941d4006a210503400240200541706a2802002206450d00200641306c450d002005416c6a280200102e0b0240200528020041ffffff3f71450d002005417c6a280200102e0b200541e0006a2105200341a07f6a22030d000b0b02402002a72205450d00200541e0006c450d002009102e0b20012802980521070240200141a0056a2802002205450d00200541d0006c2103200741c4006a21050340024020052802002206450d00200641306c450d002005417c6a280200102e0b200541d0006a2105200341b07f6a22030d000b0b2001419c056a2802002205450d00200541d0006c450d002007102e0b024020012802f40441ffffff3f71450d0020012802f004102e0b200141b0046a41186a22184200370300200141b0046a41106a221a4200370300200141b0046a41086a22174200370300200142003703b004200141800d6a41a081ca0041071081022017200141800d6a41086a2205290000370300200120012900800d3703b004200141800d6a41f09dc500410a108102200441086a2005290000370000200420012900800d370000200141800d6a200141b0046a10880320012802800d2205410120051b212920012902840d420020051b2202a7211f0240024002402002422088a72205450d002029200541057422076a2119200141b8076a41206a212a2001419c0b6a2103202921050340200141c00c6a41186a2206200541186a2209290000370300200141c00c6a41106a220a200541106a220c290000370300200141c00c6a41086a220d200541086a2213290000370300200120052900003703c00c20132900002102200c29000021082005290000210e200141d0046a41186a220c2009290000370300200141d0046a41106a22092008370300200141d0046a41086a221320023703002001200e3703d004200141b8076a41186a2006290300370300200141b8076a41106a200a290300370300200141b8076a41086a200d290300370300200120012903c00c3703b807200141f80a6a200141b8076a10bf01200141e00c6a41086a200141f80a6a41086a290300370300200141e00c6a41106a200141f80a6a41106a290300370300200141e00c6a41186a200141f80a6a41186a29030037030020014190056a41086a200341086a280200360200200120012903f80a3703e00c200120032902003703900520012802980b21062018200c290300370300201a200929030037030020172013290300370300200120012903d0043703b00402402006450d00202a20012903e00c370300202a41086a200141e00c6a41086a290300370300202a41106a200141e00c6a41106a290300370300202a41186a200141e00c6a41186a290300370300200141b8076a41186a200141b0046a41186a2903002202370300200141b8076a41106a200141b0046a41106a2903002208370300200141b8076a41086a200141b0046a41086a290300220e370300200141800d6a41086a2203200e370300200141800d6a41106a22092008370300200141800d6a41186a220a2002370300200141800d6a41206a220c200141b8076a41206a290300370300200141800d6a41286a220d200141b8076a41286a290300370300200141800d6a41306a2213200141b8076a41306a290300370300200141800d6a41386a2217200141b8076a41386a290300370300200120012903b00422023703b807200120023703800d200141c8056a41086a221820014190056a41086a28020036020020014198096a41386a221a201729030037030020014198096a41306a2217201329030037030020014198096a41286a2213200d29030037030020014198096a41206a220d200c29030037030020014198096a41186a220c200a29030037030020014198096a41106a220a200929030037030020014198096a41086a2209200329030037030020012001290390053703c805200120012903800d37039809200141b8056a41086a22032018280200360200200120012903c8053703b805200141d8056a41386a2218201a290300370300200141d8056a41306a221a2017290300370300200141d8056a41286a221b2013290300370300200141d8056a41206a2213200d290300370300200141d8056a41186a220d200c290300370300200141d8056a41106a220c200a290300370300200141d8056a41086a220a200929030037030020012001290398093703d805200141a8056a41086a22092003280200360200200120012903b8053703a80541d000102c2217450d08201720012903d80537030020172006360240201720012903a805370244201741386a2018290300370300201741306a201a290300370300201741286a201b290300370300201741206a2013290300370300201741186a200d290300370300201741106a200c290300370300201741086a200a290300370300201741cc006a2009280200360200024020074120470d0041012128410121270c040b200541206a210a201941606a2120200141fc056a210341012128410121270340200a21050340200141c00c6a41186a2206200541186a2207290000370300200141c00c6a41106a2209200541106a220a290000370300200141c00c6a41086a220c200541086a220d290000370300200120052900003703c00c200141d0046a41186a22132007290000370300200141d0046a41106a2207200a290000370300200141d0046a41086a220a200d290000370300200120052900003703d004200141b8076a41186a221a2006290300370300200141b8076a41106a221b2009290300370300200141b8076a41086a2209200c290300370300200120012903c00c3703b807200141d8056a200141b8076a10bf01200141e00c6a41086a2221200141d8056a41086a220c290300370300200141e00c6a41106a2223200141d8056a41106a220d290300370300200141e00c6a41186a2224200141d8056a41186a221829030037030020014190056a41086a2225200341086a280200360200200120012903d8053703e00c200120032902003703900520012802f8052106200141b0046a41186a22262013290300370300200141b0046a41106a22132007290300370300200141b0046a41086a2207200a290300370300200120012903d0043703b00402402006450d00202a20012903e00c370300202a41086a2021290300370300202a41106a2023290300370300202a41186a2024290300370300201a20262903002202370300201b2013290300220837030020092007290300220e370300200141800d6a41086a2207200e370300200141800d6a41106a220a2008370300200141800d6a41186a22132002370300200141800d6a41206a221a200141b8076a41206a290300370300200141800d6a41286a221b200141b8076a41286a290300370300200141800d6a41306a2221200141b8076a41306a290300370300200141800d6a41386a2223200141b8076a41386a290300370300200120012903b00422023703b807200120023703800d200141c8056a41086a2224202528020036020020014198096a41386a2225202329030037030020014198096a41306a2223202129030037030020014198096a41286a2221201b29030037030020014198096a41206a221b201a29030037030020014198096a41186a221a201329030037030020014198096a41106a2213200a29030037030020014198096a41086a220a200729030037030020012001290390053703c805200120012903800d37039809200141b8056a41086a22072024280200360200200120012903c8053703b805200141f80a6a41386a22242025290300370300200141f80a6a41306a22252023290300370300200141f80a6a41286a22232021290300370300200141f80a6a41206a2221201b290300370300200141f80a6a41186a221b201a290300370300200141f80a6a41106a221a2013290300370300200141f80a6a41086a2213200a29030037030020012001290398093703f80a200141a8056a41086a220a2007280200360200200120012903b8053703a805200c2013290300370300200d201a2903003703002018201b290300370300200141d8056a41206a22132021290300370300200141d8056a41286a221a2023290300370300200141d8056a41306a221b2025290300370300200141d8056a41386a22212024290300370300200120012903f80a3703d8052009200a280200360200200120012903a8053703b8070240024020272028470d00202841016a22072028490d0c2028410174220a2007200a20074b1b22074104200741044b1bad42d0007e2202422088a74541037421072002a7210a0240024020280d00200141003602800d0c010b200141083602880d200120173602800d2001202841d0006c3602840d0b20014198096a200a2007200141800d6a107d20012802a00921072001280298094101460d01200128029c092117200741d0006e21280b200541206a210a2017202741d0006c6a220720012903d805370300200d2903002102201829030021082013290300210e201a2903002130201b290300213120212903002132200c290300213320072006360240200741086a2033370300200741386a2032370300200741306a2031370300200741286a2030370300200741206a200e370300200741186a2008370300200741106a2002370300200720012903b807370244200741cc006a2009280200360200202741016a212720202005470d030c070b20070d0b0c0a0b2019200541206a2205470d000c050b0b0b200541206a2105200741606a22070d000b0b0240201f41ffffff3f71450d002029102e0b410821174100212741042105410021280c010b0240201f41ffffff3f71450d002029102e0b202741d0006c4104722205417f4c0d030b2005102c2203450d032010410020111b2107200141003602880d200120053602840d200120033602800d2027200141800d6a10760240202741d0006c2205450d00201720056a21032017210503402005200141800d6a10a1012003200541d0006a2205470d000b0b20012802880d210320012802800d210620012007360298094117102c2205450d032005412f3a0012200541e1d8013b0010200542e8d2cda3f7cddcb4e300370008200542f3cacd9b97ed9bb7df00370000200520012802980936001320054117200620031093032005102e024020012802840d450d0020012802800d102e0b02402027450d00202741d0006c2103201741c4006a21050340024020052802002206450d00200641306c450d002005417c6a280200102e0b200541d0006a2105200341b07f6a22030d000b0b02402028450d00202841d0006c450d002017102e0b200141b8076a109403024020012903b80722024202510d0020012903c0072108200141800d6a200141c8076a280200220641016a109503200141b0036a20012802800d220320012802880d108e0220012802b403210920012802b0032105024020012802840d450d002003102e0b20054101470d002009200741016a470d0020024201520d00200141e8046a22094200370300200141d0046a41106a220a4200370300200141d0046a41086a22054200370300200142003703d004200141800d6a41e8fcc60041091081022005200141800d6a41086a2203290000370300200120012900800d3703d004200141800d6a41b08ec9004103108102200b41086a220c2003290000370000200b20012900800d370000200141a0036a200141d0046a108503200141f8026a20012903a803420020012802a0031b220242e80780420042e807420010e808200141800d6a200610960320014188036a20012802800d221320012802880d10f80220012903f802220e200242e807827c2202427f200141f8026a41086a2903002002200e54ad7c501b20087d213020014188036a41106a2903004200200128028803220d1b21082001290390034200200d1b2131024020012802840d450d002013102e0b20094200370300200a420037030020054200370300200142003703d004200141800d6a41f8fcc600410810810220052003290000370300200120012900800d3703d004200141800d6a41a8aac800410d108102200c2003290000370000200b20012900800d370000200141e0026a200141d0046a412010f802200141d0026a20012903e802420020012802e00222051b220e200141e0026a41106a290300420020051b2202428094ebdc03420010e608200141c0026a200e2002428094ebdc03420010e708200220082031200e56200820025620082002511b22051b2108200e203120051b21332030428086ebc7f5002030428086ebc7f500541b420588428094ebdc037e4298ac9fd603802134200141c0026a41086a29030021314100210341b0fac600210520012903c002213220012903d0022130024002400340200141b0026a2032203120053502002202420010e808203320012903b002220e203020027e2202428094ebdc0380a7417f2002428080808080c0b2cd3b541b2002428094ebdc03824280cab5ee01566aad7c2202542008200141b0026a41086a2903002002200e54ad7c22025420082002511b0d01200541086a2105200341016a22034121470d000b200141a0026a203220314298f1840d420010e808200141a8026a29030020012903a002220820304298f1840d7e2202428094ebdc0380a72002428094ebdc03824280cab5ee01566aad7c2202200854ad7c21080c010b02402003417f6a220920034d0d00200141b0016a2032203142c0f0f50b420010e808200141b8016a29030020012903b00122082030422880a7203042c0f0f50b7e428094ebdc03824280cab5ee01566aad7c2202200854ad7c21080c010b02400240200941204b0d0020014190026a203220312009410374220a41b0fac6006a2802002209ad2202420010e808200141f0016a2033200129039002220e203020027e2202428094ebdc0380a7417f2002428080808080c0b2cd3b541b220341016a20032002428094ebdc03824280cab5ee01561bad7c22022033200256200820014190026a41086a2903002002200e54ad7c220e562008200e511b22031b22352002203320031b22027d22332008200e20031b200e200820031b7d2035200254ad7d220e41002005280200220c20096b22092009200c4b1b22094101200941014b1bad2202420010e708200141c0016a200141f0016a41086a2903004200200541046a2802002209200a41b4fac6006a2802002205200920054b220a1b20052009200a1b6bad2208420010e808200141d0016a20012903f00142002008420010e808200141e0016a2033200e2002420010e60820014180026a203220312005ad2233420010e808427f427f200141d0016a41086a290300220e20012903c0017c223520012903c8014200522035200e5472220a1b2235427f20012903d001200a1b220e20012903e00120087e2002807c2202200e54220aad7c2208200a20082035542002200e5a1b220a1b2135427f2002200a1b210e20014180026a41086a2903002001290380022236203020337e2202428094ebdc0380a7417f2002428080808080c0b2cd3b541b2002428094ebdc03824280cab5ee01566aad7c2208203654ad7c21022003200920054d460d01427f200220357c2008200e7c220e2008542205ad7c22082005200820025420082002511b22051b2108427f200e20051b21020c020b2009412141f889c500103c000b4200200220357d2008200e54ad7d22332008200e7d220e200856203320025620332002511b22051b21084200200e20051b21020b200141a0016a20022008428094ebdc03420010e60820014190016a20022008428094ebdc03420010e70820014180016a20012903900120014190016a41086a2903002034420010e808200141f0006a203220314280c2d72f420010e808200141e0006a200129037022082030420a80a720304280c2d72f7e428094ebdc03824280cab5ee01566aad7c2202200141f0006a41086a2903002002200854ad7c2208428094ebdc03420010e608200141d0006a20022008428094ebdc03420010e708200141c0006a2001290350200141d0006a41086a2903002034420010e8082001418c0d6a2006360200200141800d6a41086a41003a0000200141800d6a41106a2001290380012208203420012903a0017e2202428094ebdc0380a72002428094ebdc03824280cab5ee01566aad7c2202370300200141980d6a20014180016a41086a2903002002200854ad7c2208370300200141a80d6a4200200141c0006a41086a29030020012903402230203420012903607e220e428094ebdc0380a7200e428094ebdc03824280cab5ee01566aad7c220e203054ad7c223020087d200e200254ad7d2231200e20027d2232200e56203120305620312030511b22051b2231370300200141a00d6a4200203220051b2232370300200141043a00800d200141800d6a10fe0120014198096a200610970320012802a00921032001280298092105200120083703880d200120023703800d20052003200141800d6a411010b2010240200128029c09450d002005102e0b200120313703880d200120323703800d024002400240200e200256203020085620302008511b0d00200142003703880d200142003703800d0c010b200141800d6a10980320012903800d21022001200141800d6a41086a29030022083703880d200120023703800d20022008844200520d010b2001200141800d6a3602980920014198096a10cc020c010b200142f0f2bda1a7ee9cb9f90037039809200141800d6a20014198096a10cd02200141306a200141800d6a2002200810fd01200141a8096a200141306a41086a290300223020087d2001290330220e200254ad7d200820307d2002200e54ad7d200e200256203020085620302008511b22051b3703002001200e20027d2002200e7d20051b3703a00920012005ad3703980920014198096a41086a21030240024020050d00200120033602d805200141d8056a10cc020c010b200120033602d805200141d8056a10ce020b200141980d6a2008370300200141900d6a2002370300200141880d6a41063a00002001410e3a00800d200141800d6a10fe010b200141c8046a4200370300200141c0046a4200370300200141b0046a41086a22054200370300200142003703b004200141800d6a41a081ca0041071081022005200141800d6a41086a2203290000370300200120012900800d3703b004200141800d6a41dff9c000410a108102200f41086a2003290000370000200f20012900800d370000200141203602bc052001200141b0046a3602b80520014190056a200141b0046a412010ed0202400240200128029005220a0d00410021090c010b200128029405210c200120014190056a41086a2802003602cc052001200a3602c805200141286a200141c8056a10ab010240024020012802280d00200128022c220d20012802cc0541e0016e22052005200d4b1bad42e0017e2202422088a70d052002a72205417f4c0d050240024020050d00410121090c010b2005102c2209450d070b200541e0016ead210202400240200d450d00200141800d6a41206a2117200141f80a6a4101722118410021130340200141003a00980b20012802cc05417f6a2105201341016a211341002103024002400240024002400340200141003a00a8052005417f460d01200141f80a6a20036a20012802c80522062d00003a00002001200641016a3602c8052001200341016a22063a00980b200120053602cc052005417f6a21052006210320064120470d000b200141e00c6a41186a2205200141f80a6a41186a290300370300200141e00c6a41106a2203200141f80a6a41106a290300370300200141e00c6a41086a221a200141f80a6a41086a290300370300200120012903f80a3703e00c200641ff01714120490d01200141d0046a41086a2206201a290300370300200141d0046a41106a221a2003290300370300200141d0046a41186a22032005290300370300200120012903e00c3703d004200141f80a6a200141c8056a10990320012d00f80a4101460d01200141800d6a41186a2003290300370300200141800d6a41106a201a290300370300200141800d6a41086a2006290300370300200120012903d0043703800d2017201841c00110e9081a20014198096a200141800d6a41e00110e9081a200141b8076a20014198096a41e00110e9081a200141d8056a200141b8076a41e00110e9081a2002422088a722052002a7470d04200541016a22032005490d0d20054101742206200320032006491b22034104200341044b1bad42e0017e2202a721032002422088a745210620050d02200141003602800d0c030b200341ff0171450d00200141003a00980b0b2002a721052005450d06200541e0016c450d062009102e0c060b200141013602880d200120093602800d2001200541e0016c3602840d0b20014198096a20032006200141800d6a107d20012802a00921032001280298094101460d03200128029c092109200341e0016ead21020b2009200541e0016c6a200141d8056a41e00110e9081a200242ffffffff0f83200541016aad4220868421022013200d470d000b0b2009450d010c020b20030d060c050b41002109200141003602a00920014201370398092001410a3602bc072001200141b8056a3602b807200120014198096a3602d805200141940d6a4101360200200142013702840d200141909dc5003602800d2001200141b8076a3602900d200141d8056a419cebc000200141800d6a103d1a20012802980920012802a00910ef02200128029c09450d00200128029809102e0b200c450d00200a102e0b2002420020091b2208422088a7222141ffffff3f712021470d0241012123024020214105742205450d002005102c2223450d040b2009410120091b2124410021032001410036029805200120233602900520012005410576222736029405024002400240202720214f0d00200541047622032021200320214b1b22034104200341044b1b220341ffffff3f712003462106200341057421030240024020050d00200141003602800d0c010b200141880d6a4101360200200120053602840d200120233602800d0b20014198096a20032006200141800d6a107d200141a0096a280200210502402001280298094101460d002001200128029c09222336029005200120054105762227360294050c020b20050d060c050b2021450d010b202141e0016c220641a07e6a41e0016e21092023210520242103034020052003290000370000200541186a200341186a290000370000200541106a200341106a290000370000200541086a200341086a290000370000200541206a2105200341e0016a2103200641a07e6a22060d000b200941016a21030b2001200336029805200141c8046a22064200370300200141c0046a22094200370300200141b0046a41086a22054200370300200142003703b004200141800d6a41a081ca0041071081022005200141800d6a41086a2203290000370300200120012900800d3703b004200141800d6a41f09dc500410a108102200f41086a220a2003290000370000200f20012900800d370000200141b0046a20014190056a109a0302402012201241ff0171410247712220450d00200642003703002009420037030020054200370300200142003703b004200141800d6a41a081ca00410710810220052003290000370300200120012900800d3703b004200141800d6a41f8d2c1004112108102200a2003290000370000200f20012900800d370000200141800d6a200141b0046a109b0320012802800d220c450d00200141b0046a412010ff0120012902840d42ffffffff0383500d00200c102e0b200642003703002009420037030020054200370300200142003703b004200141800d6a41a081ca00410710810220052003290000370300200120012900800d3703b004200141800d6a41e4d1c100410c108102200a2003290000370000200f20012900800d3700002001200741016a22283602800d200141b0046a4120200141800d6a410410b201200141800d6a1094030240024020012903800d4202510d00200141900d6a28020041016a21050c010b410021050b200141800d6a2005109503200141206a20012802800d220620012802880d108e022001280224210320012802202105024020012802840d450d002006102e0b024020054101470d00024020032028460d00200320284f0d0141c3ebc600413010ef020b2028109c030b200141c8046a4200370300200141c0046a4200370300200141b0046a41086a22054200370300200142003703b004200141b8076a41a081ca0041071081022005200141b8076a41086a290000370300200120012900b8073703b00420014198096a41bfadc000410b108102200441086a20014198096a41086a2900003700002004200129009809370000200141800d6a200141b0046a4120109d03200741026a211b0240024020012802800d4101470d0020013502840d21020c010b201bad220242208620028421020b2001200242ffffffff0f83200741036aad422086843702840d200141013602800d200141b0046a41186a4200370300200141b0046a41106a4200370300200141b0046a41086a22054200370300200142003703b004200141b8076a41a081ca0041071081022005200141b8076a41086a290000370300200120012900b8073703b00420014198096a41bfadc000410b108102200441086a20014198096a41086a2900003700002004200129009809370000200141b0046a4120200141800d6a410472109e03200141d0046a41186a22064200370300200141d0046a41106a22074200370300200141d0046a41086a22054200370300200142003703d004200141800d6a4192fdc60041071081022005200141800d6a41086a2203290000370300200120012900800d3703d004200141800d6a4198b7c6004115108102200b41086a22092003290000370000200b20012900800d3700002001201b3602800d200141d0046a4120200141800d6a410410b201200642003703002007420037030020054200370300200142003703d004200141800d6a4192fdc600410710810220052003290000370300200120012900800d3703d004200141800d6a4194adc600410a10810220092003290000370000200b20012900800d370000200141186a200141d0046a4120108e020240024020012802184101460d00200141c00c6a201b109f030c010b200141800d6a200128021c109503200141106a20012802800d220620012802880d108e022001280214210320012802102105024020012802840d450d002006102e0b024020050d00418debc600413610ef02410021030b024002400240024010a00341ff01710e0401000302030b200141e8046a4200370300200141e0046a4200370300200141d0046a41086a22054200370300200142003703d004200141800d6a4192fdc60041071081022005200141800d6a41086a2203290000370300200120012900800d3703d004200141800d6a41b8b2c6004108108102200b41086a2003290000370000200b20012900800d370000200141d0046a412010ff010c010b4100201b20036b22052005201b4b1b4106490d010b200141c00c6a201b109f030c010b200141003602c00c0b024002400240024002400240024020012802c00c2226450d00200141e8046a4200370300200141e0046a4200370300200141d0046a41086a22054200370300200142003703d004200141800d6a4192fdc60041071081022005200141800d6a41086a2203290000370300200120012900800d3703d004200141800d6a4194adc600410a108102200b41086a2003290000370000200b20012900800d370000200141086a200141d0046a4120108e02200141c00c6a41086a2802002205ad42d0007e2202422088a70d092002a72203417f4c0d0920012802082106200128020c210720012802c40c21290240024020030d00410821250c010b2003102c2225450d0b0b024002400240200341d0006e222a20054f0d00202a41017422092005200920054b1b22094104200941044b1bad42d0007e2202422088a74541037421092002a7210a02400240200341cf004b0d00200141003602800d0c010b200141800d6a41086a4108360200200120253602800d2001202a41d0006c3602840d0b20014198096a200a2009200141800d6a107d200141a0096a280200210302402001280298094101460d00200128029c092125200341d0006e212a0c020b20030d0d0c0c0b20050d00410021090c010b2007410020061b21192005410574220941606a410576211f200141b8076a41206a210620252105202621030340200141d8056a41186a220a200341186a290000370300200141d8056a41106a220c200341106a290000370300200141d8056a41086a220d200341086a290000370300200120032900003703d805200141f80a6a2019200141d8056a10a103200141800d6a20012802f80a220420012802800b10a203200141e00c6a41186a2217200141800d6a41186a290300370300200141e00c6a41106a2218200141800d6a41106a290300370300200141e00c6a41086a221a200141800d6a41086a290300370300200120012903800d3703e00c20012802ac0d21130240024020012802a00d22070d004200210220014198096a41186a420037030020014198096a41106a42003703004108210720014198096a41086a420037030020014200370398090c010b20014198096a41086a201a29030037030020014198096a41106a201829030037030020014198096a41186a2017290300370300200120012903e00c3703980920012902a40d21020b024020012802fc0a450d002004102e0b200341206a21032006200129039809370300200141b8076a41086a2204200d290300370300200141b8076a41106a220d200c290300370300200141b8076a41186a220c200a290300370300200641186a20014198096a41186a290300370300200641106a20014198096a41106a290300370300200641086a20014198096a41086a290300370300200120012903d8053703b807200541386a200141b8076a41386a290300370300200541306a200141b8076a41306a290300370300200541286a200141b8076a41286a290300370300200541206a2006290300370300200541186a200c290300370300200541106a200d290300370300200541086a2004290300370300200520012903b807370300200541cc006a2013360200200541c4006a2002370200200541c0006a2007360200200541d0006a2105200941606a22090d000b201f41016a21090b0240202941ffffff3f71450d002026102e0b2025450d00200941ffffff3f712009470d0920094105742205417f4c0d090240024020050d00410121290c010b2005102c2229450d0b0b02400240024002402005410576221f20094f0d00200541047622032009200320094b1b22034104200341044b1b220341ffffff3f712003462106200341057421030240024020050d00200141003602800d0c010b200141880d6a4101360200200120053602840d200120293602800d0b20014198096a20032006200141800d6a107d200141a0096a28020021052001280298094101460d01200128029c0921292005410576211f0b20252025200941d0006c6a470d01410021060c020b20050d0c0c0b0b2025200941d0006c6a2107410021062029210520252103034020052003290000370000200541186a200341186a290000370000200541106a200341106a290000370000200541086a200341086a290000370000200641016a2106200541206a21052007200341d0006a2203470d000b0b200120093602a0092001202a36029c092001202536029809200141800d6a20014198096a10a30320012802800d4101470d0120012802880d210520012802840d21034188accb00413710ef022003200510ef020c020b200141b8076a4100201b417f6a22052005201b4b1b10a403200141800d6a20012802b807220520012802c00710a503200141f80a6a41086a2203200141800d6a41106a290300370300200141f80a6a41106a2206200141800d6a41186a290300370300200141f80a6a41186a2207200141a00d6a2903003703002001200141800d6a41086a2903003703f80a20012802800d4101470d0220012802840d210920014198096a41186a200729030037030020014198096a41106a200629030037030020014198096a41086a2003290300370300200120012903f80a37039809024020012802bc07450d002005102e0b2001418c0d6a200141a0096a290300370200200141940d6a200141a8096a2903003702002001419c0d6a200141b0096a290300370200200120093602800d20012001290398093702840d200141f80a6a201b10a40320012802800b210320012802f80a21054104102c2206450d09200142043702dc05200120063602d8054120102c2206450d09200142203702bc07200120063602b807200141b8076a200141800d6a41201074200141d8056a20012802b807220620012802c0071074024020012802bc07450d002006102e0b200120012802a00d3602b807200141d8056a200141b8076a410410742005200320012802d805220620012802e00510b201024020012802dc05450d002006102e0b20012802fc0a450d032005102e0c030b20014198096a200141800d6a41086a41800110e9081a200141d0076a200141900a6a290300370300200141c8076a200141880a6a290300370300200141b8076a41086a200141800a6a290300370300200120012903f8093703b807200120093602d807200141e00c6a201b10a40320012802e80c210320012802e00c21054104102c2207450d08200142043702fc0a200120073602f80a4120102c2207450d08200142203702dc05200120073602d805200141d8056a200141b8076a41201074200141f80a6a20012802d805220720012802e0051074024020012802dc05450d002007102e0b200120093602d805200141f80a6a200141d8056a410410742005200320012802f80a220720012802800b10b201024020012802fc0a450d002007102e0b024020012802e40c450d002005102e0b20014198096a10b8020b20294521222029450d022006ad422086201fad8421024101212a2029210b0c030b20012802bc07450d002005102e0b41002129410121220b200141e8046a4200370300200141e0046a4200370300200141d0046a41086a22054200370300200142003703d004200141800d6a41a081ca0041071081022005200141800d6a41086a2203290000370300200120012900800d3703d004200141800d6a41f09dc500410a108102200b41086a2003290000370000200b20012900800d370000200141800d6a200141d0046a10880320012902840d420020012802800d22051b21022005410120051b210b4100212a0b2002422088a722064105744105752203ad42e0017e220e422088a70d02200ea72205417f4c0d020240024020050d00410121250c010b2005102c2225450d040b0240024002400240200541e0016e222620034f0d00202641017422072003200720034b1b22034104200341044b1bad42e0017e220ea72103200e422088a745210702400240200541df014b0d00200141003602800d0c010b200141880d6a4101360200200120253602800d2001202641e0016c3602840d0b20014198096a20032007200141800d6a107d200141a0096a28020021052001280298094101460d01200128029c092125200541e0016e21260b20060d0141002118202a21040c020b20050d050c040b2024202141e0016c6a211b2006410574220741606a4105762114200141800d6a41206a2118200141f80a6a41a0016a2115200141f80a6a4180016a2111200141f80a6a41e0006a2110200141f80a6a41c0006a2112200141f80a6a41206a211920014198096a410172211a202a21042024210620252109200b2105034020062103200141e00c6a41186a220a200541186a290000370300200141e00c6a41106a220c200541106a290000370300200141e00c6a41086a220d200541086a290000370300200120052900003703e00c200141c00c6a200141e00c6a10a60320014198096a20012802c00c221720012802c80c10a70320012d0098092113200141b8076a201a41c00110e9081a41002106024020134101470d00200141d8056a200141b8076a41c00110e9081a410121060b024020012802c40c450d002017102e0b0240024020060d00200141f80a6a41186a4200370300200141f80a6a41106a4200370300200141f80a6a41086a4200370300200142003703f80a2019410041a00110eb081a0c010b200141f80a6a200141d8056a41c00110e9081a0b02400240200441ff0171450d00200321060c010b4100210402402003201b470d00200321060c010b200341e0016a21060240200341206a200141f80a6a412010ec080d00200341c0006a2019412010ec080d00200341e0006a2012412010ec080d0020034180016a2010412010ec080d00200341a0016a2011412010ec080d00200341c0016a2015412010ec08450d010b410121040b200541206a2105200141800d6a41186a200a290300370300200141800d6a41106a200c290300370300200141800d6a41086a200d290300370300200120012903e00c3703800d2018200141f80a6a41c00110e9081a2009200141800d6a41e00110e90841e0016a2109200741606a22070d000b201441016a21180b0240200242ffffff3f83500d00200b102e0b2018ad42e0017e2202422088a70d022002a72219417f4c0d020240024020190d00410121174100211b0c010b2019102c2217450d04201941e0016e211b201941e001490d002025201841e0016c6a211a200141c00e6a2103200141a00e6a2106200141800e6a2107200141e00d6a2109200141c00d6a210a200141a00d6a210c4100210d20252105201b21130340201a2005460d012013450d03200141800d6a41186a200541186a290000370300200141800d6a41106a200541106a290000370300200141800d6a41086a200541086a29000037030020052900002102200c2005290020370000200c41086a200541286a290000370000200c41106a200541306a290000370000200c41186a200541386a290000370000200a41186a200541d8006a290000370000200a41106a200541d0006a290000370000200a41086a200541c8006a290000370000200a2005290040370000200120023703800d200941186a200541f8006a290000370000200941106a200541f0006a290000370000200941086a200541e8006a29000037000020092005290060370000200741186a20054198016a290000370000200741106a20054190016a290000370000200741086a20054188016a2900003700002007200529008001370000200620052900a001370000200641086a200541a8016a290000370000200641106a200541b0016a290000370000200641186a200541b8016a290000370000200320052900c001370000200341086a200541c8016a290000370000200341186a200541d8016a290000370000200341106a200541d0016a2900003700002017200d6a200141800d6a41e00110e9081a200d41e0016a210d200541e0016a21052013417f6a22130d000b0b200141c8046a4200370300200141c0046a4200370300200141b0046a41086a22054200370300200142003703b004200141800d6a41a081ca0041071081022005200141800d6a41086a2203290000370300200120012900800d3703b004200141800d6a41dff9c000410a108102200f41086a2003290000370000200f20012900800d370000201841e0016c4104722205417f4c0d022005102c2203450d03200141003602880d200120053602840d200120033602800d2018200141800d6a107620172018200141800d6a109c01200141b0046a412020012802800d220520012802880d10b201024020012802840d450d002005102e0b0240201941e001490d00201b41e0016c450d002017102e0b200141c8046a4200370300200141c0046a4200370300200141b0046a41086a22054200370300200142003703b004200141800d6a41a081ca0041071081022005200141800d6a41086a2203290000370300200120012900800d3703b004200141800d6a4188d2c100410d108102200f41086a2003290000370000200f20012900800d370000200120043a00a805200141b0046a4120200141a8056a410110b201200120283602840d200141063a00800d200141800d6a10fe012020202420212025201810a80302402026450d00202641e0016c450d002025102e0b0240202a2022720d00201f41ffffff3f71450d002029102e0b02402027450d002023102e0b02402008a72205450d00200541e0016c450d002024102e0b200141800d6a10a90320012903880d21020b200010aa032108200141e00e6a2400427f200220087c220820082002541b0f0b201b201b4188decc00103c000b1038000b1036000bdd2107067f017e037f017e017f067e017f230041900e6b22002400200041a0036a2201420037030020004198036a2202420037030020004188036a41086a220342003703002000420037038803200041b00c6a41a8f8c60041041081022003200041b00c6a41086a2204290000370300200020002900b00c37038803200041b00c6a41978cc500410b10810220012004290000370300200220002900b00c370300200041a8096a20004188036a10a004024020002d00a8094102470d002001420037030020024200370300200342003703002000420037038803200041b00c6a41d9fcc600410610810220032004290000370300200020002900b00c37038803200041b00c6a41b4f4cb004106108102200241086a2004290000370000200220002900b00c370000200041a8096a20004188036a10a10420002802a8092203410420031b21050240024020002902ac09420020031b2206422088a7220741246c2203450d00200520036a2104200041a8096a41086a2108200521030340024020032d00004101470d00200341016a2800002101200341086a28020021092000200341106a2802003602cc07200020093602c8070240200141c28289aa04470d00200041a8096a200041c8076a10930220002903a809220a4203510d0020004188036a200841f00010e9081a200041c00c6a20004188036a41f00010e9081a200041306a200041c00c6a41f00010e9081a0c040b200041c00c6a41e8b1c40041f00010e9081a0b2004200341246a2203470d000b0b4203210a0b02402007450d00200741246c21042005210303400240024002400240024020032d00000e050400010204030b2003410c6a280200450d03200341086a280200102e0c030b2003410c6a280200450d02200341086a280200102e0c020b2003410c6a280200450d01200341086a280200102e0c010b200341086a280200450d00200341046a280200102e0b200341246a21032004415c6a22040d000b0b02402006a72203450d00200341246c450d002005102e0b200041a0016a200041306a41f00010e9081a41002109410021010240200a4203510d002000200a3703900220004190026a41086a200041a0016a41f00010e908210b200041a0036a2201420037030020004198036a2205420037030020004188036a41086a220342003703002000420037038803200041b00c6a41a8f8c60041041081022003200041b00c6a41086a2204290000370300200020002900b00c37038803200041b00c6a41e38bc500410b108102200241086a22072004290000370000200220002900b00c370000200041206a20004188036a1085032000290398022106024002402000280220450d0020002903284200520d010b2001420037030020054200370300200342003703002000420037038803200041b00c6a41a8f8c600410410810220032004290000370300200020002900b00c37038803200041b00c6a41e38bc500410b10810220072004290000370000200220002900b00c370000200020063703a80920004188036a4120200041a8096a410810b2012001420037030020054200370300200342003703002000420037038803200041b00c6a41a8f8c600410410810220032004290000370300200020002900b00c37038803200041b00c6a41a58bc500410b10810220072004290000370000200220002900b00c370000200041a8096a20004188036a10a20420002802a809210720002902ac09210c2001420037030020054200370300200342003703002000420037038803200041b00c6a41a8f8c600410410810220032004290000370300200020002900b00c37038803200041b00c6a41c28cc500410a10810220012004290000370300200520002900b00c370300200041a8096a20004188036a10a30420002d00a80921042001200041c1096a2900003703002005200041b9096a2900003703002003200041b1096a290000370300200020002900a90937038803200c420020071b210d200c42808080807083420020071b210c2007410820071b21030240024020044101460d00200041d80c6a4200370300200041d00c6a4200370300200041c80c6a4200370300200042003703c00c0c010b200041c00c6a41186a20004188036a41186a290300370300200041c00c6a41106a20004188036a41106a290300370300200041c00c6a41086a20004188036a41086a29030037030020002000290388033703c00c0b200041c8076a41086a200041c00c6a41086a290300220e370300200041c8076a41106a200041c00c6a41106a290300220f370300200041c8076a41186a200041c00c6a41186a2903002210370300200020002903c00c22113703c807200041a8096a41086a200c200d42ffffffff0f8384370300200041a8096a41106a2011370300200041a8096a41186a200e370300200041c8096a200f370300200041a8096a41286a2010370300200020033602ac09200041003602a80920004188036a200041a8096a10a404200041cb0c6a20004188036a41086a28020036000020002000290388033700c30c20004194036a200041c70c6a290000370000200041c28289aa0436008903200041023a008803200020002900c00c37008d0320004188036a10a504200da72204450d00200441286c450d002003102e0b200041a0036a2205420037030020004188036a41106a2207420037030020004188036a41086a220342003703002000420037038803200041b00c6a41a8f8c60041041081022003200041b00c6a41086a2204290000370300200020002900b00c37038803200041b00c6a41c98bc500410b108102200241086a22082004290000370000200220002900b00c370000200041106a20004188036a108503200028021021012000290318210c2005420037030020074200370300200342003703002000420037038803200041b00c6a41a8f8c600410410810220032004290000370300200020002900b00c37038803200041b00c6a41a28cc500410810810220082004290000370000200220002900b00c370000200042002006200c42017c420120011b7d220c200c2006561b3e02a80920004188036a4120200041a8096a410410b2012005420037030020074200370300200342003703002000420037038803200041b00c6a41a8f8c600410410810220032004290000370300200020002900b00c37038803200041b00c6a41c98bc500410b10810220082004290000370000200220002900b00c370000200020063703a80920004188036a4120200041a8096a410810b20141002101200a4201510d0020004190026a41106a28020021012005420037030020074200370300200342003703002000420037038803200041b00c6a41a8f8c600410410810220032004290000370300200020002900b00c37038803200041b00c6a41a58bc500410b10810220082004290000370000200220002900b00c370000200041a8096a20004188036a10a20420002802a8092203410820031b210402400240200120002902ac09420020031b220c422088a74f0d00200041c8076a41186a2004200141286c6a220341186a290000370300200041c8076a41106a200341106a290000370300200041c8076a41086a200341086a290000370300200020032900003703c807200041a8096a200041c8076a10f40120002802a809210320004188036a200041a8096a41047241c40110e9081a20034101460d00200b410c6a210720004188066a200041c00c6a41046a20004188036a41046a41c00110e90841c00110e9081a200041c8076a20004188066a41c00110e9081a20004188036a41186a2203420037030020004188036a41106a2201420037030020004188036a41086a220542003703002000420037038803200041b00c6a41a8f8c60041041081022005200041b00c6a41086a2208290000370300200020002900b00c37038803200041b00c6a41c28cc500410a10810220032008290000370300200120002900b00c370300200041a8096a20004188036a10a30420002d00a80921082003200041c1096a2900003703002001200041b9096a2900003703002005200041b1096a290000370300200020002900a909370388030240024020084101460d00200041a0096a420037030020004198096a420037030020004190096a420037030020004200370388090c010b20004188096a41186a20004188036a41186a29030037030020004188096a41106a20004188036a41106a29030037030020004188096a41086a20004188036a41086a2903003703002000200029038803370388090b20004188036a41186a420037030020004188036a41106a420037030020004188036a41086a220342003703002000420037038803200041b00c6a41a8f8c60041041081022003200041b00c6a41086a2201290000370300200020002900b00c37038803200041b00c6a41fa8bc500410a108102200241086a2001290000370000200220002900b00c370000200020004188036a1085032000290308210d20002802002103200041c00c6a41dcddcc004104108101200041c00c6a41e0ddcc00410b2006108501200041c00c6a41ebddcc00410d200d420020031b108501200041c00c6a41f8ddcc00411020004188096a412010840120004188036a200041c00c6a41d00110e9081a200041a8096a2007200041c8076a20004188036a10f30120002802a8094101460d0020004188036a200041a8096a41086a41800310e9081a200041a8096a20004188036a41800310e9081a200041c00c6a41b7b7c0004109108101200041c00c6a41d4e2cc00410041c9ddcc004113108401200041c00c6a41c0b7c0004106200041c80a6a4120108401200041c00c6a41c6b7c0004107200041880c6a412010840120004188096a41186a420037030020004188096a41106a420037030020004188096a41086a42003703002000420037038809200041c00c6a41d4e2cc00410020004188096a4120108601410021030340200041c00c6a20036a41003a0000200341016a220341c801470d000b200041c8076a41086a20004188096a41086a290300370300200041c8076a41106a20004188096a41106a290300370300200041c8076a41186a20004188096a41186a29030037030020002000290388093703c807410121010c010b410021010b200ca72203450d00200341286c450d002004102e0b0240200a4200520d00200041c00c6a41186a200041c8076a41186a290300370300200041c00c6a41106a200041c8076a41106a290300370300200041c00c6a41086a200041c8076a41086a290300370300200020002903c8073703c00c200121090b200041b1096a2205200041c00c6a41086a290300370000200041b9096a2207200041c00c6a41106a290300370000200041c1096a2208200041c00c6a41186a290300370000200020093a00a809200020002903c00c3700a90920004188036a41186a2209420037030020004188036a41106a220b420037030020004188036a41086a220342003703002000420037038803200041b00c6a41a8f8c60041041081022003200041b00c6a41086a2204290000370300200020002900b00c37038803200041b00c6a41978cc500410b108102200241086a22122004290000370000200220002900b00c37000020004188036a200041a8096a10a6042005200041c8076a41086a2903003700002007200041c8076a41106a2903003700002008200041c8076a41186a290300370000200020013a00a809200020002903c8073700a90920094200370300200b4200370300200342003703002000420037038803200041b00c6a41a8f8c600410410810220032004290000370300200020002900b00c37038803200041b00c6a41848cc500411310810220122004290000370000200220002900b00c37000020004188036a200041a8096a10a6040b200041900e6a24000b8d0204017f017e017f017e230041d0006b220224002002412036020420022001360200200241086a2001412010ed0202400240200228020822010d00420021030c010b200228020c210402400240200241086a41086a2802004108490d0020012900002105420121030c010b20024100360220200242013703182002410a36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241909dc5003602382002200241286a360248200241346a419cebc000200241386a103d1a2002280218200228022010ef020240200228021c450d002002280218102e0b420021030b2004450d002001102e0b2000200537030820002003370300200241d0006a24000b800201037f230041d0006b220124002001412036020420012000360200200141086a2000412010ed0202400240200128020822020d00410221000c010b200128020c210302400240200141106a280200450d0041002100024020022d00000e020200010b410121000c010b20014100360220200142013703182001410a36022c200120013602282001200141186a360234200141cc006a41013602002001420137023c200141909dc5003602382001200141286a360248200141346a419cebc000200141386a103d1a2001280218200128022010ef020240200128021c450d002001280218102e0b410221000b2003450d002002102e0b200141d0006a240020000ba70905077f017e037f037e027f23004190026b22012400200141206a22024200370300200141186a22034200370300200141086a41086a420037030020014200370308200141086a41bed8c8004108108102200141a8016a41e9d8c80041041081022002200141a8016a41086a290000370300200320012900a8013703002001412036022c2001200141086a360228200141306a200141086a412010ed020240024002400240024002400240200128023022040d00410021050c010b200128023421062001200141306a41086a280200360244200120043602402001200141c0006a10ab010240024020012802000d002001280204220720012802444105762202200220074b1b22024105742203417f4c0d070240024020020d00410121050c010b2003102c2205450d050b2002ad210802402007450d00410021090340200141003a00c8012001280244417f6a2102200941016a210941002103024002400240024003402002417f460d01200141a8016a20036a2001280240220a2d00003a00002001200a41016a3602402001200341016a220a3a00c801200120023602442002417f6a2102200a2103200a4120470d000b200141f0016a41186a2202200141a8016a41186a290300370300200141f0016a41106a2203200141a8016a41106a290300370300200141f0016a41086a220b200141a8016a41086a290300370300200120012903a8013703f001200a41ff01714120490d01200141e8006a41086a200b290300220c370300200141e8006a41106a2003290300220d370300200141e8006a41186a2002290300220e370300200141c8006a41186a220a200e370300200141c8006a41106a220b200d370300200141c8006a41086a220f200c370300200120012903f001220c370388012001200c3703682001200c3703482008422088220ca722022008a7470d03200241016a220320024f0d020c0d0b200341ff0171450d00200141003a00c8010b0240200842ffffff3f83500d002005102e0b0c040b20024101742210200320032010491b22034104200341044b1b220341ffffff3f712003462110200341057421030240024020020d00200141003602a8010c010b200141013602b001200120053602a8012001200c4205863e02ac010b200141f0016a20032010200141a8016a107d20012802f801210320012802f0014101460d0620012802f40121052003410576ad21080b200520024105746a22032001290348370000200341186a200a290300370000200341106a200b290300370000200341086a200f290300370000200842ffffffff0f83200241016aad42208684210820092007470d000b0b20050d010b41002105200141003602f801200142013703f0012001410a3602d4012001200141286a3602d0012001200141f0016a36028801200141bc016a4101360200200142013702ac01200141909dc5003602a8012001200141d0016a3602b80120014188016a419cebc000200141a8016a103d1a20012802f00120012802f80110ef0220012802f401450d0020012802f001102e0b2006450d002004102e0b20050d0220004100360208200042013702000c030b2003450d030b1036000b20002008370204200020053602000b20014190026a24000f0b1038000bd60201027f230041e0006b220224002002412036020c20022001360208200241106a2001412010ed0202400240200228021022010d00200041003602000c010b200228021421032002200241186a280200360224200220013602202002200241206a10ab0102400240024002402002280200450d00200241003602480c010b200241c8006a200241206a200228020410920120022802480d010b20024100360230200242013703282002410a36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241909dc5003602482002200241386a360258200241c4006a419cebc000200241c8006a103d1a2002280228200228023010ef020240200228022c450d002002280228102e0b200041003602000c010b20002002290348370200200041086a200241c8006a41086a2802003602000b2003450d002001102e0b200241e0006a24000b0e002001ad4220862000ad8410220bb40201037f230041e0006b22022400200241086a4199fdc6004108108102200241186a418092c5004112108102024002404110102c2203450d002002421037023c20022003360238200241386a2001411010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241c8006a41086a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000bba0302047f017e230041e0006b220324002003200236020c20032001360208200341106a2001200210ed0202400240024002400240200328021022010d00200041003602000c010b200328021421022003200341186a280200360224200320013602202003200341206a10ab010240024020032802000d002003280224220420032802042205490d002005417f4c0d030240024020050d00410121060c010b200510322206450d05200328022421040b024020042005490d0020062003280220200510e9082104200328022422062005490d0620002005ad2207422086200784370204200020043602002003200620056b3602242003200328022020056a3602200c020b2006102e0b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341909dc5003602482003200341386a360258200341c4006a419cebc000200341c8006a103d1a2003280228200328023010ef020240200328022c450d002003280228102e0b200041003602000b2002450d002001102e0b200341e0006a24000f0b1038000b1036000b2005200641b8b2c0001056000beb0201037f230041e0006b22032400200341086a4199fdc6004108108102200341186a41ac91c5004116108102024002404110102c2204450d002003421037023c20032004360238200341386a2001411010742003200328023822012003280240220410a301370348200341dc006a200120046a360200200320013602582003200341c8006a41086a3602542003200341c8006a360250200341286a200341d0006a107c0240200328023c450d002001102e0b200341d0006a2002280200200228020810a20120032802302202200328025822046a41206a2201417f4c0d010240024020010d00410121050c010b2001102c2205450d010b2000410036020820002001360204200020053602002000200341086a411010742000200341186a41101074200020032802282201200210742000200328025022022004107402402003280254450d002002102e0b0240200328022c450d002001102e0b200341e0006a24000f0b1036000b1038000bb10805057f017e037f037e027f230041f0016b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022040d00200041003602000c010b200328021421052003200341186a280200360224200320043602202003200341206a10ab010240024020032802000d00024002402003280204220620032802244105762201200120064b1b22014105742202417f4c0d000240024020010d00410121070c010b2002102c2207450d020b2001ad2108024002402006450d00410021090340200341003a00a8012003280224417f6a2101200941016a2109410021020240024002400240024003402001417f460d0120034188016a20026a2003280220220a2d00003a00002003200a41016a3602202003200241016a220a3a00a801200320013602242001417f6a2101200a2102200a4120470d000b200341d0016a41186a220120034188016a41186a290300370300200341d0016a41106a220220034188016a41106a290300370300200341d0016a41086a220b20034188016a41086a29030037030020032003290388013703d001200a41ff01714120490d01200341c8006a41086a200b290300220c370300200341c8006a41106a2002290300220d370300200341c8006a41186a2001290300220e370300200341286a41186a220a200e370300200341286a41106a220b200d370300200341286a41086a220f200c370300200320032903d001220c3703682003200c3703482003200c3703282008422088220ca722012008a7470d04200141016a22022001490d0820014101742210200220022010491b22024104200241044b1b220241ffffff3f7120024621102002410574210220010d0220034100360288010c030b200241ff0171450d00200341003a00a8010b200341c8006a41186a200341e8006a41186a290300370300200842ffffff3f83500d082007102e0c080b200341013602900120032007360288012003200c4205863e028c010b200341d0016a2002201020034188016a107d20032802d801210220032802d0014101460d0320032802d40121072002410576ad21080b200720014105746a22022003290328370000200241186a200a290300370000200241106a200b290300370000200241086a200f290300370000200842ffffffff0f83200141016aad42208684210820092006470d000b0b2007450d0320002008370204200020073602000c040b20020d010b1038000b1036000b200341003602d801200342013703d0012003410a3602b4012003200341086a3602b0012003200341d0016a3602682003419c016a41013602002003420137028c01200341909dc500360288012003200341b0016a36029801200341e8006a419cebc00020034188016a103d1a20032802d00120032802d80110ef02024020032802d401450d0020032802d001102e0b200041003602000b2005450d002004102e0b200341f0016a24000bb40201037f230041e0006b22022400200241086a4199fdc6004108108102200241186a419090c5004107108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241c8006a41086a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000b8b0101027f230041106b2203240020034100360208200342013703002002200310a10120022802502104200241d8006a28020022022003107602402002450d002002410574210203402003200441201074200441206a2104200241606a22020d000b0b2000200120032802002204200328020810b20102402003280204450d002004102e0b200341106a24000ba60201017f230041a0016b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822010d00200041003602400c010b200328020c21022003200341106a28020036027c20032001360278200341186a200341f8006a10e0040240024020032802580d00200341003602880120034201370380012003410a360294012003200336029001200320034180016a36029c012003412c6a41013602002003420137021c200341909dc500360218200320034190016a3602282003419c016a419cebc000200341186a103d1a20032802800120032802880110ef020240200328028401450d00200328028001102e0b200041003602400c010b2000200341186a41e00010e9081a0b2002450d002001102e0b200341a0016a24000be50101047f230041206b2203240002400240200228020822044105744104722205417f4c0d00200228020021022005102c2206450d0120034100360208200320053602042003200636020020042003107602402004450d002004410574210403404120102c2205450d032003422037021420032005360210200341106a2002412010742003200328021022052003280218107402402003280214450d002005102e0b200241206a2102200441606a22040d000b0b2000200120032802002202200328020810b20102402003280204450d002002102e0b200341206a24000f0b1038000b1036000bf63608077f017e097f017e067f067e077f027e230041c0036b22062400200641d8026a22074200370300200641d0026a22084200370300200641c0026a41086a22094200370300200642003703c002200641b0026a4192fdc60041071081022009200641b0026a41086a290000370300200620062900b0023703c00220064180036a41e0b2c6004113108102200720064180036a41086a22092900003703002008200629008003370300200641203602a4022006200641c0026a3602a00220064180036a200641c0026a412010ed020240024020062802800322070d004100210a0c010b200628028403210b0240024020092802004104490d004101210a2007280000220c418194ebdc03490d010b4100210a200641003602e801200642013703e0012006410a3602b4022006200641a0026a3602b0022006200641e0016a36029002200641ac036a41013602002006420137029c03200641909dc500360298032006200641b0026a3602a80320064190026a419cebc00020064198036a103d1a20062802e00120062802e80110ef0220062802e401450d0020062802e001102e0b200b450d002007102e0b200641c0026a1094030240024020062903c0024202520d0042c0f0f50b210d0c010b200641c0026a200641d0026a280200220e109503200641d8016a20062802c002220920062802c802108e0220062802dc01210b20062802d8012107024020062802c402450d002009102e0b02400240024020070d00418debc600413610ef024100200e41646a22072007200e4b1b210f428084afdf00210d200e21100c010b4100200e41646a22072007200e4b1b210f428084afdf00210d0240200b20054b0d00200e21100c010b200641c0026a10f10520062802c002221120062802c80241037422076a210903402007450d02200741786a21072009417c6a210b200941786a2109200b28020020054b0d000b201120076a2802002110024020062802c40241ffffffff0171450d002011102e0b42c0f4a4eb00210d0b200c4100200a1b2112200641c0026a41186a22134200370300200641c0026a41106a22144200370300200641c0026a41086a220c4200370300200642003703c002200641b0026a4192fdc6004107108102200c200641b0026a41086a2215290000370300200620062900b0023703c00220064180036a41e8b6c6004116108102200841086a220720064180036a41086a22162900003700002008200629008003370000200641d0016a200641c0026a4120108e0220062802d401210920062802d001210b2013420037030020144200370300200c4200370300200642003703c002200641b0026a4192fdc6004107108102200c2015290000370300200620062900b0023703c00220064180036a41e8b6c600411610810220072016290000370000200820062900800337000020062009200e200b4101461b36029803200641c0026a412020064198036a410410b2012013420037030020144200370300200c4200370300200642003703c002200641b0026a4192fdc6004107108102200c2015290000370300200620062900b0023703c00220064180036a418cabc600410d10810220072016290000370000200820062900800337000020064198036a200641c0026a108803200629029c03420020062802980322071b2217422088a7410574211820042002200220044b1b21192007410120071b211a20064198036a41106a210220064180026a41046a211b20064190026a41086a211c4100210802400240034020082019200820194b1b21040340024020082004470d00201742ffffff3f83500d06201a102e0c060b200841016a211d2001200841e0006c6a210520182107201a2109024003402007450d01200741606a210720092005412010ec08210b200941206a2109200b0d000b201d21080c010b0b200320084102746a2802002107200642003703880220064200370380022006420037039802200642003703900220064190016a2005290330221e200541386a290300221f428094ebdc03420010e608200641a0016a201e201f428094ebdc03420010e70820064180016a20062903a001200641a0016a41086a2903002007ad221f420010e808200641b0016a2005290320221e200541286a2903002220428094ebdc03420010e608200641c0016a201e2020428094ebdc03420010e708200641f0006a20062903c001200641c0016a41086a290300201f420010e808200629039001201f7e2220428094ebdc038021212020428094ebdc038221220240024002402006290370420020062903b001201f7e221e428094ebdc0380a7417f201e428080808080c0b2cd3b541b201e428094ebdc03824280cab5ee01566a2209ad7d85200641f0006a41086a29030042002009410047ad7d85844200520d00200642003703a802200642003703a002200642003703b802200642003703b00220064198036a200510ce050240024020062802a4030d00200642003703900320064280808080c000370388032006200f360284032006410036028003200520064180036a10d0050c010b20064180036a41106a2002290300370300201620064198036a41086a2903003703002006200629039803370380030b200c200629038003370200200c41086a2016290300370200200c41106a20064180036a41106a290300370200200641003a00ec02200620053602c4022006200f3602c002200620123602e8022006200641b0026a3602e4022006200641a0026a3602e00220064198036a200641c0026a201010f205024020062802a0034102460d0020062802980320062802c802470d002006200c200e108c0120062d00ec024100477222073a00ec0220064198036a2005108605200628029803220920062802a00310ff010240200628029c03450d002009102e0b20064198036a200510d105200628029803220920062802a00310ff010240200628029c03450d002009102e0b0240200510f30541ff017122094102460d002009410171450d00024010a00341ff0171417f6a0e03010001000b20064198036a41186a42003703002002420037030020064198036a41086a22094200370300200642003703980320064180036a4192fdc60041071081022009201629000037030020062006290080033703980320064180036a41b8b2c6004108108102200241086a2016290000370000200220062900800337000020064100360288032006420137038003200641013a00f00220064180036a200641f0026a4101107420064198036a4120200628028003220920062802880310b201200628028403450d002009102e0b2007450d00200641f0026a200c20062802c002108d01024020062802f0024101470d0020062802f402220720062802f80222054f0d0020062802c4022109034020064198036a41186a200941186a2900003703002002200941106a29000037030020064198036a41086a200941086a2900003703002006200929000037039803200620073602b80320064180036a20064198036a10cd05200628028003220b20062802880310ff01200741016a21070240200628028403450d00200b102e0b20052007470d000b0b20062802c402200c10d0050b20062802d80241ffffffff0371450d0120062802d402102e0c010b200629038001211e20064180016a41086a2903002123200641b0026a2010200510cc0520062802b0022109200620062802b802220b3602f402200620093602f00220064180036a2009200b10ed0202400240200628028003220b0d0041002104200a21240c010b20062802840321080240024020062802880322114104490d00200b2800002224418094ebdc034b0d00202421042011417c6a410f4b0d010b200641003602a00320064201370398032006410a3602a4022006200641f0026a3602a002200620064198036a3602bc03200641013602d402200642013702c402200641909dc5003602c0022006200641a0026a3602d002200641bc036a419cebc000200641c0026a103d1a20062802980320062802a00310ef020240200628029c03450d00200628029803102e0b41002104200a21240b2008450d00200b102e0b024020062802b402450d002009102e0b0240200720044d0d0020064180036a2010200510cc05200628028803210b20062802800321094110102c2208450d052006421037029c032006200836029803200620073602c00220064198036a200641c0026a4104107420062023201e2021a7417f2020428080808080c0b2cd3b541b20224280cab5ee01566aad7c2220201e54ad7c221e3703c802200620203703c00220064198036a200641c0026a411010742009200b200628029803220720062802a00310b2010240200628029c03450d002007102e0b0240200628028403450d002009102e0b20064198036a200510ce050240024020062802a4030d00200642003703900320064280808080c000370388032006200f360284032006410036028003200520064180036a10d0050c010b20064180036a41106a2002290300370300201620064198036a41086a2903003703002006200629039803370380030b200c200629038003370200200c41086a22252016290300370200200c41106a222620064180036a41106a2227290300370200200641003a00ec02200620053602c4022006200f3602c002200620123602e802200620064190026a3602e402200620064180026a3602e002200641e8006a200641c0026a20102020201e10f40502400240024020062802684101470d00200628026c20062802c802460d010b20062d00ec0221070c010b2006200c200e108c0120062d00ec024100477222073a00ec0220064198036a2005108605200628029803220920062802a00310ff010240200628029c03450d002009102e0b20064198036a200510d105200628029803220920062802a00310ff010240200628029c03450d002009102e0b200510f30541ff017122094102460d002009410171450d00024010a00341ff0171417f6a0e03010001000b20064198036a41186a42003703002002420037030020064198036a41086a22094200370300200642003703980320064180036a4192fdc60041071081022009201629000037030020062006290080033703980320064180036a41b8b2c6004108108102200241086a2016290000370000200220062900800337000020064100360288032006420137038003200641013a00b00220064180036a200641b0026a4101107420064198036a4120200628028003220920062802880310b201200628028403450d002009102e0b0240200741ff0171450d00200641b0026a200c20062802c002108d01024020062802b0024101470d0020062802b402220720062802b80222084f0d0020062802c4022109034020064198036a41186a200941186a2900003703002002200941106a29000037030020064198036a41086a200941086a2900003703002006200929000037039803200620073602b80320064180036a20064198036a10cd05200628028003220b20062802880310ff01200741016a21070240200628028403450d00200b102e0b20082007470d000b0b20062802c402200c10d0050b024020062802d80241ffffffff0371450d0020062802d402102e0b42002120200642003703a802200642003703a0024100211102400240200541c8006a220928020022070d004108212841002129420021210c010b200641003602c00220064198036a20074104200741044b1bad42307e221ea7201e422088a745410374200641c0026a107d20062802a003210702402006280298034101470d002007450d060c070b200628029c032128200741306e21290240200928020022070d0042002120420021210c010b200541c0006a280200220a200741306c6a212a2004ad2123410021110340200642003703b802200642003703b002200641c0006a200a290300221e200a41086a2903002220428094ebdc03420010e608200641306a201e2020428094ebdc03420010e708200641206a2006290330221e200641306a41086a29030022202023420010e808200641106a201e2020201f420010e808200641c0026a2010200a41106a220b10cb05200641d0006a20062802c002220920062802c80210f8024200200641106a41086a2903002006290310222020062903402221201f7e221e428094ebdc0380a7417f201e428080808080c0b2cd3b541b201e428094ebdc03824280cab5ee01566aad7c221e202054ad7c2220200641206a41086a29030020062903202222202120237e2221428094ebdc0380a7417f2021428080808080c0b2cd3b541b2021428094ebdc03824280cab5ee01566aad7c2221202254ad7c7d201e202154ad7d2222201e20217d2221201e56202220205620222020511b22071b21204200202120071b211e200641d0006a41106a29030021212006290358212220062802502107024020062802c402450d002009102e0b20064198036a2010200b10cb0520062802a0032108200628029803210920062022420020071b2222201e7c221e3703c00220062021420020071b20207c201e202254ad7c22203703c80220092008200641c0026a411010b2010240200628029c03450d002009102e0b20064198036a200b10ce050240024020062802a4030d00200642003703900320064280808080c000370388032006200f360284032006410036028003200b20064180036a10d0050c010b20272002290300370300201620064198036a41086a2903003703002006200629039803370380030b200c2006290380033702002025201629030037020020262027290300370200200641003a00ec022006200b3602c4022006200f3602c002200620123602e8022006200641b0026a3602e4022006200641a0026a3602e002200641086a200641c0026a2010201e202010f4050240024020062802084101470d00200628020c20062802c802470d002006200c200e108c0120062d00ec024100477222073a00ec020c010b20062d00ec0221070b0240200741ff0171450d00200641f0026a200c20062802c002108d01024020062802f0024101470d0020062802f402220720062802f80222044f0d0020062802c4022109034020064198036a41186a200941186a2900003703002002200941106a29000037030020064198036a41086a200941086a2900003703002006200929000037039803200620073602b80320064180036a20064198036a10cd05200628028003220820062802880310ff01200741016a21070240200628028403450d002008102e0b20042007470d000b0b20062802c402200c10d0050b024020062802d80241ffffffff0371450d0020062802d402102e0b200b41086a290000211e200b29000021202013200b41186a2900003703002014200b41106a290000370300200c201e370300200620203703c0022015290300211e20062903b0022120024020112029470d00202941016a22072029490d07202941017422092007200920074b1b22074104200741044b1bad42307e2221422088a74541037421072021a721090240024020290d0020064100360298030c010b200641083602a00320062028360298032006202941306c36029c030b20064180036a2009200720064198036a107d200628028803210702402006280280034101470d0020070d090c080b2006280284032128200741306e21290b200c2903002121201429030021222013290300212b20062903c002212c2028201141306c6a220720203703202007202c370300200741286a201e370300200741186a202b370300200741106a2022370300200741086a2021370300201141016a2111200a41306a220a202a470d000b200641a0026a41086a290300212120062903a00221200b200641e0016a41086a2207200541086a290300370300200641e0016a41106a2209200541106a290300370300200641e0016a41186a220b200541186a290300370300200620052903003703e00120280d020b2024210a0b200d42808c8d9e027c210d201d21080c010b20064180026a41086a2903002122200629038002211f201c2903002123200629039002212b200641c0026a200541d0006a10c80120062802c802210820062802c402210420062802c002210a20064198036a41186a2227200b2903003703002002200929030037030020064198036a41086a220b2007290300370300200620062903e00137039803200641b0026a4192fdc600410710810220064180036a41d0b3c60041101081022006200e36028002200620064180026a410410a301370390022006201b3602cc022006201c3602c402200620064180026a3602c802200620064190026a3602c002200641a0026a200641c0026a107c20062802a802220941206a2207417f4c0d010240024020070d00410121050c010b2007102c2205450d030b20064100360298022006200736029402200620053602900220064190026a200641b0026a4110107420064190026a20064180036a4110107420064190026a20062802a002220720091074024020062802a402450d002007102e0b200641c0026a20062802900220062802980210f5050240024020062802c00222050d00410021094200211e41082105410021070c010b20062902c402221e422088a72109201ea721070b2013202729030037030020142002290300370300200c200b29030037030020062006290398033703c0020240024020092007470d00201ea7201e422088a72209470d00200941016a22072009490d032009410174220b20072007200b491b22074104200741044b1bad42d8007e221e422088a7454103742107201ea7210b0240024020090d0020064100360280030c010b200641083602880320062005360280032006200941d8006c360284030b200641b0026a200b200720064180036a107d20062802b802210720062802b0024101460d0120062802b4022105200741d8006ead211e0b2011ad42c097e8b2017e200d7c212c2005200941d8006c220b6a2207201f20207c2220370310200720233703082007202b3703002007200a36022c20072028360220200741186a202220217c2020201f54ad7c370300200741346a2008360200200741306a2004360200200741286a2011360200200741246a2029360200200720062903c002370338200741c0006a200c290300370300200741c8006a2014290300370300200741d0006a20132903003703002006201e42ffffffff0f83200941016a2209ad422086843702c402200620053602c002200628029802210720062802900221080240024020050d002008200710ff010c010b201ea7210420062007360284032006200836028003200641c0026a20064180036a10b10102402009450d00200541306a2107200b41d8006a210903400240200741746a280200220b450d00200b41306c450d00200741706a280200102e0b0240200728020041ffffff3f71450d002007417c6a280200102e0b200741d8006a2107200941a87f6a22090d000b0b2004450d00200441d8006c450d002005102e0b202c42c097e8b2017c211e0240200628029402450d002008102e0b201e42c0b2cd3b7c210d201d21082024210a0c010b0b20070d010b1038000b1036000b024020062802c40241ffffffff0171450d002011102e0b42c0d1e123210d0b2000200d37030820004200370300200641c0036a24000b18002001ad4220862000ad842003ad4220862002ad8410000bbe0304037f017e027f017e230041f0006b22012400200141186a22024200370300200141106a22034200370300200141086a42003703002001420037030020014192fdc6004107108102200141d8006a41d0adc60041091081022002200141d8006a41086a290000370300200320012900583703002001412036022420012001360220200141286a2001412010ed0202400240200128022822020d00420221040c010b200128022c210502400240200141286a41086a28020022064104490d002002280000210320064104460d0042002104024020022d00040e020200010b2006417b6a4108490d0020022900052107420121040c010b20014100360240200142013703382001410a36024c2001200141206a3602482001200141386a360254200141ec006a41013602002001420137025c200141909dc5003602582001200141c8006a360268200141d4006a419cebc000200141d8006a103d1a2001280238200128024010ef020240200128023c450d002001280238102e0b420221040b2005450d002002102e0b0240024020044202520d00200042023703000c010b2000200737030820002004370300200041106a20033602000b200141f0006a24000b850201037f230041d0006b22022400200241086a4192fdc6004107108102200241186a4198aec6004115108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000b850201037f230041d0006b22022400200241086a4192fdc6004107108102200241186a4188b2c600410e108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000b850201037f230041d0006b22022400200241086a4192fdc6004107108102200241186a418cb1c6004113108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000ba00304067f027e017f027e230041d0006b22012400200141386a22024200370300200141206a41106a22034200370300200141206a41086a2204420037030020014200370320200141c0006a41f8fcc60041081081022004200141c0006a41086a220529000037030020012001290040370320200141c0006a41a8aac800410d1081022002200529000037030020032001290040370300200141086a200141206a412010f802024020012903104200200128020822061b220720002903007c22082007542209200141086a41106a290300420020061b220a200041086a2903007c2009ad7c220b200a54200b200a511b4101470d00427f210820002007427f853703002000200a427f85370308427f210b0b20024200370300200342003703002004420037030020014200370320200141c0006a41f8fcc60041081081022004200529000037030020012001290040370320200141c0006a41a8aac800410d108102200341086a2005290000370000200320012900403700002001200b37034820012008370340200141206a4120200141c0006a411010b201200141d0006a24000bcc1202067f017e230041f0056b2202240041002103200241003a00a8052001280204417f6a2104024002400240024002400240024002400240024002400240024003402004417f460d0120024188056a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a8052004417f6a21042005210320054120470d000b200241b0056a41086a220320024188056a41086a290300370300200241b0056a41106a220620024188056a41106a290300370300200241b0056a41186a220720024188056a41186a29030037030020022002290388053703b005200541ff0171411f4d0d0120024188036a41086a20032903002208370300200241c8016a41186a2007290300370300200241c8016a41106a2006290300370300200241c8016a41086a2008370300200220022903b005220837038803200220083703c80141002103200241003a00a80503402004417f460d0320024188056a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a8052004417f6a21042005210320054120470d000b200241b0056a41086a220320024188056a41086a290300370300200241b0056a41106a220620024188056a41106a290300370300200241b0056a41186a220720024188056a41186a29030037030020022002290388053703b005200541ff0171411f4d0d0320024188036a41086a20032903002208370300200241e8016a41186a2007290300370300200241e8016a41106a2006290300370300200241e8016a41086a2008370300200220022903b005220837038803200220083703e80141002103200241003a00a80503402004417f460d0520024188056a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a8052004417f6a21042005210320054120470d000b200241b0056a41086a220320024188056a41086a290300370300200241b0056a41106a220620024188056a41106a290300370300200241b0056a41186a220720024188056a41186a29030037030020022002290388053703b005200541ff0171411f4d0d0520024188036a41086a2003290300220837030020024188026a41186a200729030037030020024188026a41106a200629030037030020024188026a41086a2008370300200220022903b005220837038803200220083703880241002103200241003a00a80503402004417f460d0720024188056a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a8052004417f6a21042005210320054120470d000b200241b0056a41086a220320024188056a41086a290300370300200241b0056a41106a220620024188056a41106a290300370300200241b0056a41186a220720024188056a41186a29030037030020022002290388053703b005200541ff0171411f4d0d0720024188036a41086a20032903002208370300200241a8026a41186a2007290300370300200241a8026a41106a2006290300370300200241a8026a41086a2008370300200220022903b005220837038803200220083703a80241002103200241003a00a80503402004417f460d0920024188056a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a8052004417f6a21042005210320054120470d000b200241b0056a41086a220320024188056a41086a290300370300200241b0056a41106a220620024188056a41106a290300370300200241b0056a41186a220720024188056a41186a29030037030020022002290388053703b005200541ff0171411f4d0d0920024188036a41086a20032903002208370300200241c8026a41186a2007290300370300200241c8026a41106a2006290300370300200241c8026a41086a2008370300200220022903b005220837038803200220083703c80241002103200241003a00a80503402004417f460d0b20024188056a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a8052004417f6a21042005210320054120470d000b200241b0056a41086a220420024188056a41086a290300370300200241b0056a41106a220120024188056a41106a290300370300200241b0056a41186a220320024188056a41186a29030037030020022002290388053703b005200541ff0171411f4d0d0b20024188036a41086a20042903002208370300200241e8026a41186a22042003290300370300200241e8026a41106a22032001290300370300200241e8026a41086a22012008370300200220022903b005220837038803200220083703e802200241086a41186a200241c8016a41186a290300370300200241086a41106a200241c8016a41106a290300370300200241086a41086a200241c8016a41086a290300370300200220022903c801370308200241c0006a200241e8016a41186a290300370300200241386a200241e8016a41106a290300370300200241306a200241e8016a41086a290300370300200220022903e801370328200241e0006a20024188026a41186a290300370300200241d8006a20024188026a41106a290300370300200241d0006a20024188026a41086a290300370300200220022903880237034820024180016a200241a8026a41186a290300370300200241f8006a200241a8026a41106a290300370300200241f0006a200241a8026a41086a290300370300200220022903a802370368200241a0016a200241c8026a41186a29030037030020024198016a200241c8026a41106a29030037030020024190016a200241c8026a41086a290300370300200220022903c80237038801200241c0016a2004290300370300200241b8016a2003290300370300200241b0016a2001290300370300200220022903e8023703a801200041016a200241086a41c00110e9081a200041003a00000c0c0b200341ff0171450d00200241003a00a8050b200041013a00000c0a0b200341ff0171450d00200241003a00a8050b200041013a00000c080b200341ff0171450d00200241003a00a8050b200041013a00000c060b200341ff0171450d00200241003a00a8050b200041013a00000c040b200341ff0171450d00200241003a00a8050b200041013a00000c020b200341ff0171450d00200241003a00a8050b200041013a00000b200241f0056a24000bac0101047f230041106b2202240002400240200128020822034105744104722204417f4c0d00200128020021012004102c2205450d0120024100360208200220043602042002200536020020032002107602402003450d002003410574210303402002200141201074200141206a2101200341606a22030d000b0b2000412020022802002201200228020810b20102402002280204450d002001102e0b200241106a24000f0b1038000b1036000bb30201027f230041e0006b220224002002412036020c20022001360208200241106a2001412010ed0202400240200228021022010d00200041003602000c010b200228021421032002200241106a41086a28020036022420022001360220200241c8006a200241206a10e7010240024020022802480d0020024100360230200242013703282002410a36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241909dc5003602482002200241386a360258200241c4006a419cebc000200241c8006a103d1a2002280228200228023010ef020240200228022c450d002002280228102e0b200041003602000c010b20002002290348370200200041086a200241c8006a41086a2802003602000b2003450d002001102e0b200241e0006a24000b961c03017f017e167f23004180026b22012400200141206a109403200129032021022001420037032020014100200128023041016a20024202511b2203360230200141b0016a22044200370300200141a8016a2205420037030020014198016a41086a220642003703002001420037039801200141f8006a4192fdc60041071081022006200141f8006a41086a22072900003703002001200129007837039801200141f8006a41d0adc6004109108102200420072900003703002005200129007837030020014100360280012001420137037820012003360258200141f8006a200141d8006a41041074200141003a0058200141f8006a200141d8006a4101107420014198016a41202001280278220420012802800110b2010240200128027c450d002004102e0b200141106a10f10502400240024002400240024002402001280218220420012802142208470d00200441016a22062004490d04200441017422072006200720064b1b22064104200641044b1b220641ffffffff01712006464102742107200641037421060240024020040d0020014100360298010c010b200141a0016a410436020020012001280210360298012001200441037436029c010b200141206a2006200720014198016a107d200141286a280200210620012802204101460d01200120012802243602102001200641037622083602140b2001280210220920044103746a22062000360204200620033602002001200441016a220a3602182003411d490d024100210b200a450d01200341646a2100200441ffffffff017141016a21064100210b2009210402400340200428020020004f0d01200441086a21042006200b41016a220b470d000b2006210b0b200a200b4f0d01200b200a41b4b3c000104d000b2006450d020c040b200141003602180240200b4103742207450d00200141f4016a41046a210c200141f8016a41086a210d20092100034020002802002106200141f8006a4192fdc6004107108102200141206a41fd9fc5004113108102200120063602f4012001200141f4016a410410a3013703f8012001200c3602a4012001200d36029c012001200141f4016a3602a0012001200141f8016a36029801200141d8006a20014198016a107c2001280260220e41206a2204417f4c0d030240024020040d004101210f0c010b2004102c220f450d060b200141003602a0012001200436029c012001200f3602980120014198016a200141f8006a4110107420014198016a200141206a4110107420014198016a20012802582204200e10740240200128025c450d002004102e0b200128029801220420012802a0011089030240200128029c01450d002004102e0b200141f8006a4192fdc6004107108102200141206a4190a0c5004113108102200120063602f4012001200141f4016a410410a3013703f8012001200c3602a4012001200d36029c012001200141f4016a3602a0012001200141f8016a36029801200141d8006a20014198016a107c2001280260220641206a2204417f4c0d030240024020040d004101210e0c010b2004102c220e450d060b200141003602a0012001200436029c012001200e3602980120014198016a200141f8006a4110107420014198016a200141206a4110107420014198016a20012802582204200610740240200128025c450d002004102e0b200128029801220420012802a0011089030240200128029c01450d002004102e0b200041086a2100200741786a22070d000b0b0240200a200b6b220a0d004100210a0c010b0240200b450d0020092009200b4103746a200a41037410ea081a0b2001200a3602182009280204210c200141b0016a22044200370300200141a8016a2207420037030020014198016a41086a220042003703002001420037039801200141f8006a41a081ca0041071081022000200141f8006a41086a2900003703002001200129007837039801200141206a41bfadc000410b1081022004200141206a41086a29000037030020072001290020370300200141206a20014198016a4120109d032001290224210241002104024020012802204101470d0002402002422088a7220d200c200c200d4b1b22062002a722044f0d00410121040c010b0240200620044d0d00034020014198016a200410a403200128029801220020012802a00110ff01200441016a21040240200128029c01450d002000102e0b20062004470d000b0b200c200d4921042002428080808070832006ad8421020b2001200237025c20012004360258024020040d00200141b0016a4200370300200141a8016a420037030020014198016a41086a220442003703002001420037039801200141f8006a41a081ca0041071081022004200141f8006a41086a2900003703002001200129007837039801200141206a41bfadc000410b108102200741086a200141206a41086a2900003700002007200129002037000020014198016a412010ff010c010b200141b0016a4200370300200141a8016a420037030020014198016a41086a220442003703002001420037039801200141f8006a41a081ca0041071081022004200141f8006a41086a2900003703002001200129007837039801200141206a41bfadc000410b108102200741086a200141206a41086a2900003700002007200129002037000020014198016a4120200141d8006a410472109e030b200141b0016a4200370300200141a8016a420037030020014198016a41086a220442003703002001420037039801200141f8006a4192fdc60041071081022004200141f8006a41086a22002900003703002001200129007837039801200141f8006a41a8b4c600410a108102200541086a200029000037000020052001290078370000200a4103744104722204417f4c0d002004102c2200450d02200141003602282001200436022420012000360220200a200141206a10760240200a450d002009200a4103746a210020092104034020012004280200360278200141206a200141f8006a410410742001200441046a280200360278200141206a200141f8006a41041074200441086a22042000470d000b0b20014198016a412020012802202204200128022810b20102402001280224450d002004102e0b0240200841ffffffff0171450d002009102e0b200141b0016a4200370300200141a8016a420037030020014198016a41086a220442003703002001420037039801200141f8006a4192fdc60041071081022004200141f8006a41086a22002900003703002001200129007837039801200141f8006a41e8b6c6004116108102200541086a200029000037000020052001290078370000200141086a20014198016a4120108e02200128020c2110024020012802084101460d00410021040c020b024020104100200341656a2204200420034b1b22114f0d0020014198016a41246a210020014198016a41286a210f201021120340200141206a201210f90520014198016a200128022022042001280228220610f5050240024020012802980122130d0042002102410821130c010b2004200610ff01200129029c0121020b02402001280224450d002004102e0b20132002422088a7220441d8006c6a21070240024020040d00201321040c010b201321040340200141f8006a41186a220b200441186a290300370300200141f8006a41106a220a200441106a290300370300200141f8006a41086a2203200441086a29030037030020012004290300370378200441206a280200210620014198016a41086a220c2004412c6a29020037030020014198016a41106a220d200441346a29020037030020014198016a41186a220e2004413c6a29020037030020014198016a41206a2209200441c4006a290200370300200f200441cc006a29020037030020014198016a41306a2208200441d4006a2802003602002001200441246a29020037039801024020060d00200441d8006a21040c020b200141d8006a41186a2214200b290300370300200141d8006a41106a220b200a290300370300200141d8006a41086a220a2003290300370300200141206a41086a2203200c290300370300200141206a41106a2215200d290300370300200141206a41186a2216200e290300370300200141206a41206a22172009290300370300200141206a41286a2209200f290300370300200141206a41306a22182008280200360200200120012903783703582001200129039801370320200e2014290300370300200d200b290300370300200c200a29030037030020002001290320370200200041086a2003290300370200200041106a2015290300370200200041186a2016290300370200200041206a2017290300370200200041286a2009290300370200200041306a20182802003602002001200129035837039801200120063602b80120014198016a10fa05200441d8006a22042007470d000b200721040b2002a7210c024020072004460d0003400240200441246a2802002206450d00200641306c450d00200441206a280200102e0b200441d8006a21060240200441306a28020041ffffff3f71450d002004412c6a280200102e0b2006210420072006470d000b0b201241016a21120240200c450d00200c41d8006c450d002013102e0b20122011470d000b0b20102011201020114b1b2110410121040c010b1038000b2001200436022020012010360224200141b0016a4200370300200141a8016a420037030020014198016a41086a220042003703002001420037039801200141f8006a4192fdc60041071081022000200141f8006a41086a22062900003703002001200129007837039801200141f8006a41e8b6c6004116108102200541086a2006290000370000200520012900783700000240024020040d0020014198016a412010ff010c010b2001201036027820014198016a4120200141f8006a410410b2010b20014180026a24000f0b1036000b8f0201027f230041d0006b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822010d00200041003602000c010b200328020c2102024002400240200341106a28020022044104490d002004417c714104470d010b4100210420034100360220200342013703182003410a36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341909dc5003602382003200341286a360248200341346a419cebc000200341386a103d1a2003280218200328022010ef02200328021c450d012003280218102e0c010b20002001290000370204410121040b200020043602002002450d002001102e0b200341d0006a24000b7e01027f230041106b2203240002404108102c2204450d0020034208370204200320043602002003200228020036020c20032003410c6a410410742003200228020436020c20032003410c6a410410742000200120032802002202200328020810b20102402003280204450d002002102e0b200341106a24000f0b1036000bd67b070a7f027e127f027e0c7f097e057f230041f0056b2202240020024180046a22034200370300200241f8036a22044200370300200241e8036a41086a22054200370300200242003703e803200241d8016a4192fdc60041071081022005200241d8016a41086a2206290000370300200220022900d8013703e80320024198026a4194adc600410a108102200320024198026a41086a22072900003703002004200229009802370300200241c0016a200241e8036a4120108e0220022802c001210820022802c4012109200342003703002004420037030020054200370300200242003703e803200241d8016a4192fdc600410710810220052006290000370300200220022900d8013703e80320024198026a4194adc600410a108102200320072900003703002004200229009802370300410121052002200941016a410020081b220a36029802200241e8036a412020024198026a410410b201200241d8016a4192fdc600410710810220024198026a4198aec60041151081022002200a3602d0052002200241d0056a410410a3013703f802200241f4036a200241d0056a41046a3602002002200241f8026a41086a3602ec032002200241d0056a3602f0032002200241f8026a3602e803200241a8036a200241e8036a107c024020022802b003220641206a2203417f4c0d00024002402003450d002003102c2205450d010b200241003602f003200220033602ec03200220053602e803200241e8036a200241d8016a41101074200241e8036a20024198026a41101074200241e8036a20022802a803220320061074024020022802ac03450d002003102e0b20022802e803210320022802f003210520022001360298022003200520024198026a410410b201024020022802ec03450d002003102e0b200241e8036a41186a4200370300200241e8036a41106a4200370300200241e8036a41086a22034200370300200242003703e803200241d8016a4192fdc60041071081022003200241d8016a41086a290000370300200220022900d8013703e80320024198026a41e0a9c600410c108102200441086a20024198026a41086a2900003700002004200229009802370000200241b8016a200241e8036a4120108e020240200a20022802bc0141016a41d50020022802b8011b6b2205200a4b0d00200510f6050b200241f8026a41186a22054200370300200241f8026a41106a220b4200370300200241f8026a41086a22014200370300200242003703f802200241e8036a41a5fec600411a10810220012003290000370300200220022900e8033703f802200241e8036a4184c4c800410e10810220052003290000370300200b20022900e803370300200241e8036a200241f8026a10ab05024020022d00a40422034103460d00200241f8026a412010ff010b024002400240024002400240024020034103460d0020022802a0042105200229039804210c429896c78220210d0c010b200241e8036a4100200310e9054101210320022802e8034101460d01200241e8036a41106a2205280200210e200241f4036a2201280200210f200241e8036a41086a22032802002110200241e8036a4100200310ef0520022802e8034101460d02200528020021112001280200211220032802002113200241a0056a41186a22144200370300200241a0056a41106a22054200370300200241a0056a41086a22014200370300200242003703a005200241e8036a4192fdc600410710810220012003290000370300200220022900e8033703a005200241e8036a41b4aac600410e10810220142003290000370300200520022900e803370300200241b0016a200241a0056a4120108e0220022802b401211520022802b0012116200242003702dc030240200e450d002010200e41386c6a2117200241f8026a41086a2118200241a0056a41086a2119200241e8036a41086a211a410021072010210903402009290300210c2009290208210d201a200941106a290200370300200241e8036a41106a221b200941186a290200370300200241e8036a41186a221c200941206a2902003703002002200d3703e803024002402007450d0020022802d803211d0c010b41c003102c2207450d094100211d200741003b015e20074100360258200220073602dc03200241003602d8030b200941386a21090240024002400240024002400240024002400240024002400340200741e0006a211e20072f015e221f410574210841002101417f21054100210302400340024020082003470d00201f21050c020b200241e8036a200720036a41e0006a412010ec082206450d03200541016a2105200141086a2101200341206a21032006417f4a0d000b0b0240201d450d00201d417f6a211d200720054102746a41c0036a28020021070c010b0b200241c0056a41086a201a41086a290200220d3703002002201a29020022203703c00520022802ec03210820022802e803211d200229038004212120024198026a41086a2222200d37030020022020370398020240201f410a4b0d00200241d0056a41086a2206202229030037030020022002290398023703d005200541016a211b201f41016a210102402005201f4f221f0d00201e201b4105746a201e20054105746a20012005417f736a41057410ea081a0b201e20054105746a220320083600042003201d360000200320022903d005370008200341106a2006290300370000200320213700180240201f0d002007201b4103746a200720054103746a20012005417f736a41037410ea081a0b200720054103746a200c370300200720013b015e0c0b0b410021234104210302400240200541054f0d00200521010c010b4105210341052101024002402005417b6a0e020201000b200541796a210141012123410621030c010b41002101410121230b41c003102c221f450d14201f41003b015e201f4100360258201f20072f015e22242003417f736a22053b015e201e20034105746a2206280004212520062800002126200241d0056a41086a2227200641106a290000370300200220062900083703d0052005410c4f0d012024200341016a22286b2005470d02200720034103746a290300210d20062900182120201f41e0006a201e20284105746a200541057410e9081a201f200720284103746a200541037410e9082129200720033b015e201a2027290300370300200220022903d0053703e8032029200720231b22032f015e21052027202229030037030020022002290398023703d005200341e0006a2106200541016a211e0240200141016a222820054b22230d00200620284105746a200620014105746a201e2001417f736a41057410ea081a0b200620014105746a220520083600042005201d360000200520022903d005370008200541106a202729030037000020052021370018024020230d00200320284103746a200320014103746a201e2001417f736a41037410ea081a0b200320014103746a200c3703002003201e3b015e200241d8016a41086a2224201a290300220c370300200220022903e80322213703d801200241a8036a41086a2223200c370300200220213703a8030240024002402007280258221d0d00410021280c010b4100212820202121200d210c202921292025212a2026212b034020072f015c210720222023290300370300200220022903a80337039802201d2f015e221e410b490d024100210841042103024020074105490d0020072103024002402007417b6a0e020201000b200741796a210741012108410621030c010b4100210741012108410521030b41f003102c221f450d17201f41003b015e201f4100360258201f201d2f015e222c2003417f736a22053b015e201d41e0006a222d20034105746a22012800042125200128000021262027200141106a290000370300200220012900083703d0052005410c4f0d06202c200341016a22066b2005470d0720012900182120201d20034103746a290300210d201f41e0006a202d20064105746a200541057410e9081a201f201d20064103746a200541037410e9082105201d20033b015e201a2027290300370300200220022903d0053703e80320052f015e220141016a212c2001410c4f0d08201e20036b2203202c470d09202841016a2128200541c0036a201d20064102746a41c0036a200341027410e9081a4100210302400340200520034102746a41c0036a280200220620033b015c200620053602582003200320014922066a220320014b0d0120060d000b0b2024201a290300370300200220022903e8033703d8012005201d20081b22062f015e21012019200229039802370000201941086a20222903003700002002202a3602a4052002202b3602a005200220213703b805200641e0006a211e200141016a210802400240200741016a220320014b0d00201e20034105746a201e20074105746a221e2007417f7320086a222a41057410ea081a201e41186a2014290300370000201e41106a200241a0056a41106a290300370000201e41086a2019290300370000201e20022903a005370000200620034103746a200620074103746a202a41037410ea081a0c010b201e20074105746a221e20022903a005370000201e41186a2014290300370000201e41106a200241a0056a41106a290300370000201e41086a20192903003700000b200620074103746a200c370300200641c0036a211e0240200741026a222a200141026a22014f0d00201e202a4102746a201e20034102746a2003417f7320016a41027410ea081a0b201e20034102746a2029360200200620083b015e0240200320014f0d00200620074102746a41c4036a2103034020032802002201200741016a22073b015c20012006360258200341046a210320082007470d000b0b20232024290300370300200220022903d8013703a803201d210720202121201d2802582203211d200d210c200521292025212a2026212b20030d000b0b200241d8026a41086a2023290300220c370300200220022903a80322213703d80220182021370300201841086a200c370300200220253602fc02200220263602f802200220203703900320022802dc032205450d0820022802d803210141f003102c2203450d15200320053602c003200341003b015e20034100360258200541003b015c20052003360258200220033602dc032002200141016a3602d803201c200241f8026a41186a290300370300201b200241f8026a41106a290300370300201a2018290300370300200220022903f8023703e80320012028470d0920032f015e2205410b4f0d0a2003200541016a22063b015e200320054105746a220141e0006a20022903e803370000200141e8006a201a290300370000200141f0006a201b290300370000200141f8006a201c290300370000200320054103746a200d370300200341c0036a20064102746a201f360200201f20063b015c201f2003360258200220022802e00341016a3602e003200d1a20071a20281a201f1a20201a0c0c0b2019200229039802370000201941086a20222903003700002002202a3602a4052002202b3602a005200220213703b805201d41e0006a2103201e41016a210502402007201e4f0d00200320074105746a220141206a20012007417f7320056a41057410ea081a0b200320074105746a220320022903a005370000200341186a2014290300370000200341106a200241a0056a41106a290300370000200341086a2019290300370000200741016a2103201d20074103746a2101024002402007201e490d002001200c370300201d41c0036a2101201e41026a21060c010b201d20034103746a20012007417f7320056a41037410ea081a2001200c3703002007410274201d41c0036a22016a41086a200120034102746a2003417f73201e41026a22066a41027410ea081a0b2001200341027422076a2029360200201d20053b015e200320064f0d0a2007201d6a41c0036a210503402005280200220120033b015c2001201d360258200541046a21052006200341016a2203470d000c0b0b0b200720016a200c3703000c0a0b2005410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b2005410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b202c410c41f49cc700104d000b41f49bc7004128419c9cc7001039000b41e8aac700412b4194abc7001039000b41e899c700413041989ac7001039000b41a89ac700412041c89ac7001039000b200220022802e00341016a3602e0030b20092017460d0120022802dc0321070c000b0b200220113602b003200220123602ac03200220133602a8032002200e3602e0012002200f3602dc01200220103602d801200242003703e80320024198026a2015410020161b200241a8036a200241d8016a200241e8036a10fb020240024002402002280298024101470d00200229029c02220c422088a72101200241a4026a2802002107200ca721060c010b20024198026a41106a2222280200220f20024198026a41146a290200222e422088a72203412c6c6a212c20024198026a41086a2227290300212f200228029c0221120240024020030d00200f211d200f21090c010b200241e8036a410c6a211f200241e8036a410472211e20024198026a41186a212820024198026a41206a2125200f211d03402027201d2209410c6a2902003703002022200941146a222629020037030020282009411c6a22232902003703002025200941246a222429020037030020022009290204370398022009412c6a211d2009280200221b450d01201e200229039802370200201e41086a2027290300370200201e41106a2022290300370200201e41186a2028290300370200201e41206a20252903003702002002201b3602e80302400240200241d8036a201f10a20222030d00420021210c010b200329030021210b200241d0056a41086a2229201f41086a290200370300200241d0056a41106a222a201f41106a290200370300200241d0056a41186a222b201f41186a2902003703002002201f2902003703d00520022802ec0321190240024020022802f0032203450d00200341246c221c2101201b21030340200341206a2802002105200341086a290200210c200341106a290200210d20032902002120200241a0056a41186a2206200341186a290200370300200241a0056a41106a2207200d370300200241a0056a41086a2208200c370300200220203703a00502402005450d00200241d8016a41086a222d2008290300370300200241d8016a41106a22142007290300370300200241d8016a41186a220e2006290300370300200220022903a005220c3703f8022002200c3703d8012021428094ebdc0380210d2021428094ebdc038221204130102c221a450d0e200241a0016a200d42002005ad220c420010e808201a20022903d801370300201a41186a200e290300370300201a41106a2014290300370300201a41086a202d290300370300201a20022903a00122212020200c7e220c428094ebdc0380a7417f200c428080808080c0b2cd3b541b200c428094ebdc03824280cab5ee01566aad7c220c370320201a41286a200241a0016a41086a290300200c202154ad7c37030002400240024020014124470d00410121174101211c0c010b200341246a2110201b201c6a2201415c6a2111410121174101211c034020102103024002400340200341206a28020021052006200341186a2902003703002007200341106a2902003703002008200341086a290200370300200220032902003703a00502402005450d0020024190016a200d42002005ad220c420010e808200241f8026a41086a20082903002221370300200241f8026a41106a20072903002230370300200241f8026a41186a20062903002231370300200220022903a00522323703f802200e203137030020142030370300202d2021370300200220323703d8012020200c7e220c428094ebdc03802130200c428094ebdc03822131200229039001212120024190016a41086a2903002132201c2017470d03201741016a220520174f0d020c160b2001200341246a2203470d000c040b0b201741017422102005201020054b1b22054104200541044b1bad42307e2233422088a74541037421052033a721100240024020170d00200241003602a8030c010b200241083602b0032002201a3602a8032002201741306c3602ac030b200241a0056a20102005200241a8036a107d20022802a805210520022802a0054101460d0320022802a405211a200541306e21170b200341246a2110202d290300213320142903002134200e290300213520022903d8012136201a201c41306c6a220520212030a7417f200c428080808080c0b2cd3b541b20314280cab5ee01566aad7c220c37032020052036370300200541286a2032200c202154ad7c370300200541186a2035370300200541106a2034370300200541086a2033370300201c41016a211c20112003470d000b0b2019450d04201941246c450d04201b102e0c040b2005450d0f0c0e0b200341246a21032001415c6a22010d000b0b410021174108211a02402019450d00201941246c450d00201b102e0b4100211c0b200241d8016a41186a2203202b290300370300200241d8016a41106a2205202a290300370300200241d8016a41086a22012029290300370300200220022903d0053703d801200920173602042009201c3602082009201a360200200920022903d80137020c202620012903003702002023200529030037020020242003290300370200201d202c470d000b201d2109202c211d0b202f422088210c202c201d6b2203412c6d210502402003450d002005412c6c210303400240201d41046a2802002205450d00200541246c450d00201d280200102e0b201d412c6a211d200341546a22030d000b0b200ca72107202ea72108202fa7211d200f2009200f6b221f412c6d2209412c6c6a2106200f2103034020032006460d0202400240200241d8036a2003410c6a220310a20222050d004200210c0c010b2005290300210c0b20024188016a200341746a200c420010bf04200341206a21032002280288012201450d000b200228028c0121070240201f450d002009412c6c2105200f210303400240200341046a2802002206450d00200641306c450d002003280200102e0b2003412c6a2103200541546a22050d000b0b02402008450d002008412c6c450d00200f102e0b41032106201d450d00201d41306c450d002012102e0b200241d8036a10be022007ad2120410021030c050b200220123602f0032002201d3602ec03200220123602e80320022012200741306c6a3602f403200241d8016a200241e8036a10c201200241e8036a20022802d801220320022802e001200f200910b704410121060240024020022802e8034101470d00200241f4036a350200212020022902ec03210c0c010b20022802ec0321052002200241f0036a29030037029c022002200536029802200241e8036a10a90320022903f003210d200229039802210c20022903a0022120410021060b024020022802dc0141ffffff3f71450d002003102e0b0240201f450d002009412c6c2105200f210303400240200341046a2802002201450d00200141306c450d002003280200102e0b2003412c6a2103200541546a22050d000b0b02402008450d002008412c6c450d00200f102e0b200241d8036a10be0202402006450d00200c422088a72101200ca72106410021030c050b2020a72105410021030b200220033a00ed03200241013a00ec03200241173a00e803200241e8036a10fe0120024190036a420037030020024188036a4200370300200241f8026a41086a22034200370300200242003703f802200241e8036a41a5fec600411a1081022003200241e8036a41086a2201290000370300200220022900e8033703f802200241e8036a4180c3c8004105108102200b41086a2001290000370000200b20022900e80337000020024180016a200241f8026a4120108e0220022005ad3703d0012002200c3703c801200ca72126410021080c040b200241f0036a280200210120022802ec0321060c010b2003280200210120022802ec0321060240200e450d00200e41386c21052010412c6a210303400240200328020041ffffff3f71450d002003417c6a280200102e0b200341386a2103200541486a22050d000b0b41012103200f450d00200f41386c450d002010102e0b0b200241f4036a20203e020020022001ad4220862006ad843702ec03200220033602e803200241e8036a41086a2203290300210d20022903e803210c20024181063b01ec03200241173a00e803200241e8036a10fe0120024190036a420037030020024188036a4200370300200241f8026a41086a22054200370300200242003703f802200241e8036a41a5fec600411a10810220052003290000370300200220022900e8033703f802200241e8036a4180c3c8004105108102200b41086a2003290000370000200b20022900e803370000200241f8006a200241f8026a4120108e022002200d3703d0012002200c4220883e02cc012002200ca722263602c801410121080b20024190036a22014200370300200241f8026a41106a22064200370300200241f8026a41086a22034200370300200242003703f802200241e8036a41a5fec600411a1081022003200241e8036a41086a2205290000370300200220022900e8033703f802200241e8036a4180c3c8004105108102200b41086a22072005290000370000200b20022900e803370000200241f0006a200241f8026a4120108e02200228027021092002280274211d200142003703002006420037030020034200370300200242003703f802200241e8036a41a5fec600411a10810220032005290000370300200220022900e8033703f802200241e8036a4180c3c800410510810220072005290000370000200b20022900e8033700002002201d41016a410220091b3602e803200241f8026a4120200241e8036a410410b2014102200310ec04200142003703002006420037030020034200370300200242003703f802200241e8036a41a5fec600411a10810220032005290000370300200220022900e8033703f802200241e8036a41c8c4c800410810810220072005290000370000200b20022900e803370000200241f8026a412010ff01200142003703002006420037030020034200370300200242003703f802200241e8036a41a5fec600411a10810220032005290000370300200220022900e8033703f802200241e8036a41ccc5c800411010810220072005290000370000200b20022900e803370000200241f8026a412010ff01200142003703002006420037030020034200370300200242003703f802200241e8036a41a5fec600411a10810220032005290000370300200220022900e8033703f802200241e8036a4194c5c800410e10810220072005290000370000200b20022900e803370000200241f8026a412010ff010240024020080d002026450d0020022902cc012136200d410210f104200241b8056a22034200370300200241a0056a41106a22054200370300200241a0056a41086a22014200370300200242003703a005200241e8036a41f8fcc60041081081022001200241e8036a41086a2206290000370300200220022900e8033703a005200241e8036a41a8aac800410d10810220032006290000370300200520022900e803370300200241d8006a200241a0056a412010f8022036422088a7220641067422014106752203ad42d0007e220c422088a70d03200ca72205417f4c0d03200241d8006a41106a290300210c2002290360210d200228025821070240024020050d00410821180c010b2005102c2218450d030b0240024002400240200541d0006e223720034f0d00203741017422082003200820034b1b22084104200841044b1bad42d0007e2220422088a74541037421082020a7210902400240200541cf004b0d00200241003602e8030c010b200241e8036a41086a4108360200200220183602e8032002203741d0006c3602ec030b20024198026a20092008200241e8036a107d200241a0026a28020021052002280298024101460d01200228029c022118200541d0006e21370b20060d01410021172026211a0c020b2005450d050c040b202620016a2125200241c8006a200d200c427f420010e708200241c8006a41086a290300420020071b220c42002002290348420020071b220d420156200c420052200c501b22031b2130200d420120031b2131200641067441406a41067641016a2123200241e8036a41206a211b2018211e410021172026211a0240034020024198026a41286a2201201a220341286a29030037030020024198026a41206a2206200341206a29030037030020024198026a41186a2207200341186a29030037030020024198026a41106a2208200341106a29030037030020024198026a41086a2209200341086a2903003703002002200329030037039802200341c0006a211a200341306a2802002219450d01200341386a2802002105200341346a280200211c200241e8036a41286a2001290300370300201b2006290300370300200241e8036a41186a2007290300220c370300200241e8036a41106a2008290300220d370300200241e8036a41086a20092903002220370300200220022903980222213703e803200241a8036a41186a2222200c370300200241a8036a41106a2227200d370300200241a8036a41086a22282020370300200220213703a803200241d0056a41086a201b41086a2903003703002002201b2903003703d0052005ad42307e220c422088a70d06200ca72203417f4c0d060240024020030d004108211f0c010b2003102c221f450d060b200341306e21060240024020050d004200210d410021014200210c42002134420021330c010b200541306c21074200210d410021014200210c4200213442002133201921030340200341206a2903002120200341286a2903002121200241f8026a41186a200341186a2205290300370300200241f8026a41106a200341106a2208290300370300200241f8026a41086a200341086a2209290300370300200220032903003703f802200241186a202142002031420010e808200241286a203042002020420010e808200241386a202042002031420010e808200241d8016a41186a221d2005290000370300200241d8016a41106a220b2008290000370300200241d8016a41086a22082009290000370300200220032900003703d801427f200241386a41086a2903002220200229031820022903287c7c2232202142005220304200527120022903204200527220022903304200527220322020547222051b2120427f200229033820051b212102400240200241d8016a200241a8036a412010ec080d00427f203320207c203420217c22352034542205ad7c22322005203220335420322033511b22051b2133427f203520051b21340c010b200241a0056a41186a2209201d290300370300200241a0056a41106a221d200b290300370300200241a0056a41086a220b2008290300370300200220022903d8013703a005024020012006470d00200641016a22052006490d0a200641017422082005200820054b1b22054104200541044b1bad42307e2232422088a74541037421052032a721080240024020060d00200241003602d8020c010b200241083602e0022002201f3602d8022002200641306c3602dc020b200241c0056a20082005200241d8026a107d20022802c8052105024020022802c0054101470d002005450d0b0c0a0b20022802c405211f200541306e21060b201f200141306c6a2205202037030820052021370300200520022903a005370310200541186a200b290300370300200541206a201d290300370300200541286a2009290300370300200141016a21010b200341306a2103427f200c20207c200d20217c2220200d542205ad7c220d2005200d200c54200d200c511b22051b210c427f202020051b210d200741506a22070d000b0b0240201c450d00201c41306c450d002019102e0b200241d8016a41186a20222903002220370300200241d8016a41106a20272903002221370300200241d8016a41086a20282903002232370300200220022903a80322353703d801201e41386a2033370300201e41306a2034370300201e41286a200c370300201e200d370320201e41186a2020370300201e41106a2021370300201e41086a2032370300201e2035370300201e41c8006a2001360200201e41c4006a2006360200201e41c0006a201f360200201741016a2117201e41d0006a211e201a2025470d000b2025211a202321170b2025201a6b220141067521030b02402001450d0020034106742105201a41346a21030340024020032802002201450d00200141306c450d002003417c6a280200102e0b200341c0006a2103200541406a22050d000b0b0240203642ffffff1f83500d002026102e0b201741d0006c221d41d0006e213802400240201d0d00410121390c010b2038410574102c2239450d030b4100212b024020182018201d6a2209460d004100212b20392103201821050340200241a0056a41086a2201200541086a290300370300200241a0056a41106a2206200541106a290300370300200241a0056a41186a2207200541186a290300370300200220052903003703a005200241e8036a200541c0006a220510c501024020022802ec032208450d00200841306c450d0020022802e803102e0b200320022903a005370000200341186a2007290300370000200341106a2006290300370000200341086a2001290300370000202b41016a212b200341206a2103200541106a22052009470d000b0b4200213320024180046a4200370300200241e8036a41106a4200370300200241e8036a41086a22034200370300200242003703e803200241d8016a4192fdc60041071081022003200241d8016a41086a290000370300200220022900d8013703e80320024198026a41dcaac6004115108102200441086a20024198026a41086a2900003700002004200229009802370000200241106a200241e8036a4120108e02024002400240202b2002280214410020022802101b22034101200341014b1b490d002018201741d0006c6a210e024020170d002018212c420021320c020b200241a8036a41106a213a200241f8026a41106a213b2002419c036a210f200241e8036a41206a211442002133420021322018212c0340200241d8016a41386a2205202c220341386a290300370300200241d8016a41306a2201200341306a290300370300200241d8016a41286a2206200341286a290300370300200241d8016a41206a2207200341206a290300370300200241d8016a41186a2208200341186a290300370300200241d8016a41106a2209200341106a290300370300200241d8016a41086a221d200341086a2903003703002003290300210c200241c8016a41086a220b200341cc006a2802003602002002200c3703d8012002200341c4006a2902003703c801200341d0006a212c200341c0006a2802002203450d0220024198026a41386a200529030037030020024198026a41306a200129030037030020024198026a41286a200629030037030020024198026a41206a200729030037030020024198026a41186a221f200829030037030020024198026a41106a221e200929030037030020024198026a41086a221a201d290300370300200220022903d80137039802200241e8036a41386a2005290300370300200241e8036a41306a2001290300370300200241e8036a41286a200629030037030020142007290300370300200241e8036a41186a2008290300370300200241e8036a41106a2009290300370300200241e8036a41086a201d290300370300200220022903d8013703e803200241d8026a41186a201f290300370300200241d8026a41106a201e290300370300200241d8026a41086a201a29030037030020022002290398023703d802200241f8026a41186a2206201441186a290300370300200241f8026a41106a2207201441106a290300370300200241f8026a41086a2208201441086a290300223437030020022003360298032002201429030022353703f802200f20022903c801370200200f41086a200b280200360200200241d0056a200a200241d8026a10a10320022802d805210920022802d0052101200241003602b003200242013703a8032002200241f8026a3602a005200241a0056a200241a8036a10af012002203b3602a005200241a0056a200241a8036a10af01200228029803210320022802a0032205200241a8036a107602402005450d00200541306c21050340200241a8036a200341106a41201074200220033602a005200341306a2103200241a0056a200241a8036a10af01200541506a22050d000b0b2001200920022802a803220320022802b00310b201024020022802ac03450d002003102e0b024020022802d405450d002001102e0b200241d0056a41186a22112006290300370300200241d0056a41106a22122007290300370300200241d0056a41086a22132008290300370300200220022903f8023703d00520022802a4032115200228029c0321162002280298032127024020022802a0032226418102490d002026410176ad42307e220c422088a70d08200ca72210417f4c0d082010102c2223450d07202741506a2129202741f07e6a212d410021244104211a4100211f202621190340024002402019221d417f6a22010d0041012109410021190c010b02400240024002400240024002402027200141306c6a2203290300201d41306c222a20276a41a07f6a2205290300220d56200341086a2903002220200541086a290300220c562020200c511b0d00201d417e6a2108202d202a6a210341002119410021050340024020082005470d00201d21090c090b200d20032903002221582101200c200341086a2903002220512106200c2020582107200341506a2103200541016a21052021210d2020210c2001200720061b0d000b200541016a21092005417f73201d6a21010c010b202d202a6a210302400340024020014101470d00410021010c020b200d20032903002221562105200c200341086a2903002220512106200c2020562107200341506a21032001417f6a21012021210d2020210c2005200720061b0d000b0b201d2001490d01201d20264b0d02201d20016b22094101762206450d002029202a6a21032027200141306c6a21050340200241a8036a41186a2207200541186a2208290300370300200241a8036a41106a220b200541106a221e290300370300200241a8036a41086a221b200541086a221c290300370300200220052903003703a803200541206a2217290300210c200341286a2219290300210d200341086a22042903002120200341106a22222903002121200341186a22282903002130200329030021312017200341206a222529030037030020082030370300201e2021370300201c202037030020052031370300200541286a220829030021202008200d3703002022200b290300370300202820072903003703002004201b290300370300200320022903a803370300201920203703002025200c370300200341506a2103200541306a21052006417f6a22060d000b0b024020010d00200121190c060b0240200941094d0d00200121190c060b201d20264b0d03201d20016b21062027200141306c6a210b2029202a6a21220340201d2001417f6a2219490d050240201d20196b22094102490d002027200141306c6a22032903002027201941306c6a2208290300222058200341086a2205290300220d200841086a2201290300220c58200d200c511b0d00200241a0056a41186a221b200841286a2207290300370300200241a0056a41106a221c200841206a221e290300370300200241a0056a41086a2217200841186a2204290300370300200220082903103703a0052008200329030037030020012005290300370300200841106a200341106a2903003703002004200341186a290300370300201e200341206a2903003703002007200341286a29030037030041012105024020094103490d002006417f6a211e41002105200b210302400340200341306a2201290300202058200341386a2207290300220d200c58200d200c511b0d0120062005460d07200341286a200341d8006a290300370300200341206a200341d0006a290300370300200341186a200341c8006a290300370300200341106a200341c0006a290300370300200341086a20072903003703002003200129030037030020012103201e200541016a2205470d000b200541016a2105202221030c010b200541016a21050b200320203703002003200c3703082008200541306c6a220341286a201b290300370300200341206a201c290300370300200341186a2017290300370300200320022903a0053703100b2019450d06200641016a2106200b41506a210b201921012009410a4f0d060c000b0b2001201d41e4d1cc001057000b201d202641e4d1cc00104d000b200541016a200941d4d1cc00103c000b201d2001417f6a2219490d00201d202641f4d1cc00104d000b2019201d41f4d1cc001057000b0240201f2024470d00202441016a22032024490d0a202441017422052003200520034b1b22034104200341044b1b220341ffffffff01712003464102742105200341037421030240024020240d00200241003602a8030c010b200241043602b0032002201a3602a803200220244103743602ac030b200241a0056a20032005200241a8036a107d20022802a8052103024020022802a0054101470d002003450d0b0c0a0b20022802a405211a200341037621240b201a201f4103746a2203200936020420032019360200201f41016a2204211f024020044102490d0002400240024003400240024002400240201a2004221f417f6a22044103746a2203280200450d00201f410374201a6a220741746a2802002206200328020422054d0d00201f41024d0d08201a201f417d6a22034103746a2802042201200520066a4d0d01201f41034d0d08200741646a280200200120066a4b0d080c010b201f4103490d0120032802042105201a201f417d6a22034103746a28020421010b20012005490d010b201f417e6a21030b0240201f200341016a22224d0d00201f20034d0d02201a20034103746a221b2802042228201b2802006a2203201a20224103746a221c2802002217490d03200320264b0d04201b41046a21252027201741306c6a220b201c280204221e41306c22056a2106200341306c210102400240200320176b2208201e6b2203201e490d002023200b200510e908221d20056a210702400240201e4101480d002008201e4a0d010b200b2103201d21050c020b202720016a2109201d2105200b210303402003200620052006290300200529030056200641086a290300220c200541086a290300220d56200c200d511b22081b2201290300370300200341086a200141086a290300370300200341106a200141106a290300370300200341186a200141186a290300370300200341206a200141206a290300370300200341286a200141286a2903003703002005200541306a20081b2105200341306a2103200641306a200620081b220620094f0d02200720054b0d000c020b0b20232006200341306c220510e908221d20056a210702400240201e4101480d00200341014e0d010b20062103201d21050c010b202920016a21012006210303402001200341506a2206200741506a22082008290300200629030056200841086a290300220c200641086a290300220d56200c200d511b22091b2205290300370300200141086a200541086a290300370300200141106a200541106a290300370300200141186a200541186a290300370300200141206a200541206a290300370300200141286a200541286a2903003703002007200820091b21070240200b2006200320091b2203490d00201d21050c020b200141506a2101201d2105201d2007490d000b0b20032005200720056b220120014130706b10e9081a20252028201e6a360200201b2017360200201c201c41086a201f2022417f736a41037410ea081a4101211f200441014d0d050c010b0b2022201f4184d2cc00103c000b2003201f4194d2cc00103c000b2017200341a4d2cc001057000b2003202641a4d2cc00104d000b20190d000b0240202441ffffffff0171450d00201a102e0b20104130702103024020104130490d0020102003460d002023102e0b20264180022026418002491b21260b203220347c210c203320357c220d2033542206ad2120200241a8036a41186a2011290300370300200241a8036a41106a2012290300370300200241a8036a41086a2013290300370300200220022903d0053703a803200220153602d403200220263602d003200220163602cc03200220273602c803200241c0056a200a200241d8026a10f70520022802c805210720022802c0052101200241003602a805200242013703a0052002200241a8036a3602d803200241d8036a200241a0056a10af012002203a3602d803200241d8036a200241a0056a10af0120022802c803210320022802d0032205200241a0056a107602402005450d00200541306c21050340200241a0056a200341106a41201074200220033602d803200341306a2103200241d8036a200241a0056a10af01200541506a22050d000b0b200c20207c210c2001200720022802a005220320022802a80510b201024020022802a405450d002003102e0b200c2032512103200c2032542105024020022802c405450d002001102e0b2006200520031b2103024020022802cc032205450d00200541306c450d0020022802c803102e0b427f200c20031b2132427f200d20031b2133202c200e470d000c030b0b0240201d450d002039102e0b02402017450d00201741d0006c2105201841c4006a21030340024020032802002201450d00200141306c450d002003417c6a280200102e0b200341d0006a2103200541b07f6a22050d000b0b2037450d02203741d0006c450d022018102e0c020b200e202c460d000340202c220341d0006a212c0240200341c4006a2802002205450d00200541306c450d00200341c0006a280200102e0b200e202c470d000b0b02402037450d00203741d0006c450d002018102e0b20024198026a200a10960320022802a00221052002280298022103200220323703f003200220333703e80320032005200241e8036a411010b2010240200228029c02450d002003102e0b0240202b450d00202b4105742106203921030340200241e8036a2003108605200241086a20022802e803220720022802f0031087054100200228020820022d000c22054102461b210120054101712105024020022802ec03450d002007102e0b200220053a00dc01200220013602d80120024198026a200a200310f80520022802a00221072002280298022101200241003602f003200242013703e803200241d8016a200241e8036a109102200220053a00a803200241e8036a200241a8036a410110742001200720022802e803220520022802f00310b201024020022802ec03450d002005102e0b0240200228029c02450d002001102e0b200341206a2103200641606a22060d000b0b200241f0036a41043a0000200241043a00e803200241e8036a10fe012039450d002000202bad4220862038ad84370204200020393602000c010b200041003602000b200241f0056a24000f0b1036000b1038000b810301047f230041f0006b22002400200041186a22014200370300200041106a22024200370300200041086a42003703002000420037030020004192fdc6004107108102200041d8006a41b8b2c60041081081022001200041d8006a41086a290000370300200220002900583703002000412036022420002000360220200041286a2000412010ed0241042101024020002802282202450d00200028022c210302400240200041286a41086a280200450d004100210102400240024020022d00000e0404000102030b410121010c030b410221010c020b410321010c010b20004100360240200042013703382000410a36024c2000200041206a3602482000200041386a360254200041ec006a41013602002000420137025c200041909dc5003602582000200041c8006a360268200041d4006a419cebc000200041d8006a103d1a2000280238200028024010ef020240200028023c450d002000280238102e0b410421010b2003450d002002102e0b200041f0006a24004100200120014104461b0bae0301037f230041f0006b22032400200341086a4192fdc6004107108102200341186a41b29dc500410b108102200320013602382003200341386a410410a301370348200341ec006a2201200341386a41046a3602002003200341c8006a41086a3602642003200341386a3602682003200341c8006a360260200341286a200341e0006a107c024002404120102c2204450d002003422037024c20032004360248200341c8006a2002412010742003200328024822022003280250220410a3013703582001200220046a360200200320023602682003200341d8006a41086a3602642003200341d8006a360260200341386a200341e0006a107c0240200328024c450d002002102e0b20032802302201200328024022046a41206a2202417f4c0d010240024020020d00410121050c010b2002102c2205450d010b2000410036020820002002360204200020053602002000200341086a411010742000200341186a4110107420002003280228220220011074200020032802382201200410740240200328023c450d002001102e0b0240200328022c450d002002102e0b200341f0006a24000f0b1036000b1038000bfb0201017f230041f0006b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822010d00200041003602200c010b200328020c21022003200341086a41086a28020036024c20032001360248200341186a200341c8006a1085050240024020032802380d0020034100360258200342013703502003410a360264200320033602602003200341d0006a36026c2003412c6a41013602002003420137021c200341909dc5003602182003200341e0006a360228200341ec006a419cebc000200341186a103d1a2003280250200328025810ef0202402003280254450d002003280250102e0b200041003602200c010b20002003290318370300200041286a200341186a41286a290300370300200041206a200341186a41206a290300370300200041186a200341186a41186a290300370300200041106a200341186a41106a290300370300200041086a200341186a41086a2903003703000b2002450d002001102e0b200341f0006a24000b921c030a7f037e137f230041800a6b22022400200241d8006a10ab02200241b8016a41186a22034200370300200241b8016a41106a22044200370300200241b8016a41086a22054200370300200242003703b801200241e0066a41aad3c800410110b0012003200241e0066a41186a22062900003703002004200241e0066a41106a22072900003703002005200241e0066a41086a2208290000370300200220022900e0063703b801200241e0066a41aad3c800410110b001200241b8086a41186a22092006290000370300200241b8086a41106a220a2007290000370300200241b8086a41086a220b2008290000370300200220022900e0063703b80802400240024002404120102c2203450d002008200b2903003703002007200a29030037030020062009290300370300410041003502e8f54c200241a0056aad7c42adfed5e4d485fda8d8007e422189220c3e02e8f54c200241c8006a41e8f5cc00ad220d42a4bb99fed1a0bbb02385420042adfed5e4d485fda8d800420010e808200241286a200c42a4bb99fed1a0bbb02385420042adfed5e4d485fda8d800420010e808200241386a200d42c5ecb3fec9ecf7c2c30085420042adfed5e4d485fda8d800420010e808200241186a200c42c5ecb3fec9ecf7c2c30085420042adfed5e4d485fda8d800420010e808200241086a200c200d85420042adfed5e4d485fda8d800420010e8082002418c026a420037020020024194026a4200370200200220022903b8083703e0062002410436028802200241d8016a41d0006a41d081ca00360200200241d8016a41c8006a4108360200200241d8016a41c4006a20033602002002200241b8016a3602ac022002200241d8006a3602a402200241013a00b002200241c9026a2006290300370000200241c1026a2007290300370000200241b9026a2008290300370000200241b1026a20022903e006370000200241d3026a200241a2056a2d00003a0000200241d1026a20022f00a0053b0000200241d8016a41286a4200370300200241d8016a41246a41d0a1c000360200200241003602d402200241003602f8012002200241186a41086a290300200229031885200d7c200241086a41086a29030020022903088542cf829ebbefefde82147c220e423088893703f0012002200c200241386a41086a2903002002290338857c200e422088893703e8012002200241286a41086a290300200229032885200d7c200e421088893703e0012002200c200241c8006a41086a2903002002290348857c200e893703d8012001280200220f2001280208221041d0006c6a2111200241e0066a41306a2112200241e0066a41206a2113200241b8086a41246a2104200241f8026a41046a2105200241e0066a41046a2103200241e0066a410172211420012802042115200f2116410021170340201621012017211802400240034002400240024020112001470d00200241e0066a41386a200241a0056a41386a290300370300200241e0066a41306a200241a0056a41306a290300370300200241e0066a41286a200241a0056a41286a290300370300200241e0066a41206a200241a0056a41206a290300370300200241e0066a41186a200241a0056a41186a290300370300200241e0066a41106a200241a0056a41106a290300370300200241e0066a41086a200241a0056a41086a290300370300200220022903a0053703e006201121010c010b200241a0056a41386a200141386a2219290300370300200241a0056a41306a200141306a221a290300370300200241a0056a41286a200141286a221b290300370300200241a0056a41206a200141206a221c290300370300200241a0056a41186a200141186a2216290300370300200241a0056a41106a200141106a2217290300370300200241a0056a41086a200141086a221d290300370300200220012903003703a005200141c0006a280200211e200141c4006a280200211f200141c8006a290200210c200241e0066a41386a222020192903003703002012201a290300370300200241e0066a41286a2219201b2903003703002013201c29030037030020062016290300370300200720172903003703002008201d290300370300200220012903003703e006201e0d01200141d0006a21010b024020112001460d0003402001220341d0006a21010240200341c4006a2802002204450d00200441306c450d00200341c0006a280200102e0b20112001470d000b0b02402015450d00201541d0006c450d00200f102e0b200241d8016a109b08200241e0066a200241d8006a41e00010e9081a200241d8076a200241d0016a290300370300200241d0076a200241c8016a290300370300200241c8076a200241b8016a41086a290300370300200220022903b8013703c007200041086a200241e0066a41800110e9081a200041003602000c080b200241e0036a41386a221a2020290300370300200241e0036a41306a221b2012290300370300200241e0036a41286a221c2019290300370300200241e0036a41206a22192013290300370300200241e0036a41186a22162006290300370300200241e0036a41106a22172007290300370300200241e0036a41086a221d2008290300370300200220022903e0063703e003200341386a201a290300370200200341306a201b290300370200200341286a201c290300370200200341206a2019290300370200200341186a2016290300370200200341106a2017290300370200200341086a201d290300370200200320022903e003370200200241b8086a200241e0066a41c40010e9081a200241f8026a41086a200b290200370300200241f8026a41106a200a290200370300200241f8026a41186a2009290200370300200241f8026a41206a200241b8086a41206a280200360200200241d8026a41086a2219200441086a290200370300200241d8026a41106a221a200441106a290200370300200241d8026a41186a221b200441186a290200370300200220022902b8083703f802200220042902003703d802200241a0036a41186a221c200541186a290000370300200241a0036a41106a2216200541106a290000370300200241a0036a41086a2217200541086a290000370300200220052900003703a003200241c0036a41186a221d201b290300370300200241c0036a41106a2220201a290300370300200241c0036a41086a22212019290300370300200220022903d8023703c003200241a8086a200241a0036a10a603200241e0066a20022802a808221b20022802b00810a70320022d00e006211a200241b8086a201441c00110e9081a410021190240201a4101470d00200241a0056a200241b8086a41c00110e9081a410121190b024020022802ac08450d00201b102e0b024002402019450d00200241e0036a200241a0056a41c00110e9081a2006201c2903003703002007201629030037030020082017290300370300201320022903c003370300201341086a2021290300370300201341106a2020290300370300201341186a201d290300370300200220022903a0033703e0062002200c3703a8072002201f3602a4072002201e3602a007201841016a2117200141d0006a21164100211903402002200241e0036a20194198fac6006a221a28000010d1032002280204221e41046a221f417f4c0d022002280200211b02400240201f0d004101211c0c010b201f102c221c450d080b200241003602a8052002201f3602a4052002201c3602a005200241a0056a201a41041074201e200241a0056a1076200241a0056a201b201e107420022802a805211e20022802a005211f200220183602a808200241b8086a200241d8016a201f201e200241a8086a4104109c08024020022802a405450d00201f102e0b20022802bc08211f024020022802b8084101470d0002400240201f2d00000e0407070007010b201f41086a280200450d06201f41046a280200102e0c060b201f41286a280200450d05201f41246a280200102e0c050b0240201f450d0020022802c008450d00201f102e0b201941046a22194118460d050c000b0b0240201f450d00201f41306c450d00201e102e0b200141d0006a2101201841016a21180c010b0b1038000b201f102e200041086a411a360200200041f881ca00360204200041013602000c040b200220183602fc09200241003602a805200242013703a005200241a0056a200241e0066a41201074200220133602a808200241a8086a200241a0056a10af01200220123602a808200241a8086a200241a0056a10af0120022802a007211f20022802a8072218200241a0056a107602402018450d00201841306c21180340200241a0056a201f41106a412010742002201f3602a808201f41306a211f200241a8086a200241a0056a10af01201841506a22180d000b0b200241b8086a200241d8016a200241fc096a410420022802a005221f20022802a805109c08024020022802a405450d00201f102e0b024020022802b8084101470d000240024020022802bc0822032d00000e0405050005010b200341086a280200450d04200341046a280200102e0c040b200341286a280200450d03200341246a280200102e0c030b024020022802bc082201450d0020022802c008450d002001102e0b20022802a4072201450d00200141306c450d0020022802a007102e0c000b0b1036000b2003102e200041086a411a360200200041f881ca00360204200041013602000b201141b07f6a2103024020022802a4072204450d00200441306c450d0020022802a007102e0b024020032001460d00201041d0006c200f6a41b07f6a21040340024020014194016a2802002203450d00200341306c450d0020014190016a280200102e0b2004200141d0006a2201470d000b0b02402015450d00201541d0006c450d00200f102e0b200241d8016a109b08200241d8006a10b8020b200241800a6a24000b850201037f230041d0006b22022400200241086a41a081ca004107108102200241186a41a781ca004112108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000bdf0902087f047e230041b0016b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200041003602000c010b200341186a280200210220032802142104200341003a0060024002402002450d00200320012d00003a0040200341013a0060024020024101460d00200320012d00013a0041200341023a006020024102460d00200320012d00023a0042200341033a006020024103460d00200320012d00033a0043200341043a006020024104460d00200320012d00043a0044200341053a006020024105460d00200320012d00053a0045200341063a006020024106460d00200320012d00063a0046200341073a006020024107460d00200320012d00073a0047200341083a006020024108460d00200320012d00083a0048200341093a006020024109460d00200320012d00093a00492003410a3a00602002410a460d00200320012d000a3a004a2003410b3a00602002410b460d00200320012d000b3a004b2003410c3a00602002410c460d00200320012d000c3a004c2003410d3a00602002410d460d00200320012d000d3a004d2003410e3a00602002410e460d00200320012d000e3a004e2003410f3a00602002410f460d00200320012d000f3a004f200341103a006020024110460d00200320012d00103a0050200341113a006020024111460d00200320012d00113a0051200341123a006020024112460d00200320012d00123a0052200341133a006020024113460d00200320012d00133a0053200341143a006020024114460d00200320012d00143a0054200341153a006020024115460d00200320012d00153a0055200341163a006020024116460d00200320012d00163a0056200341173a006020024117460d00200320012d00173a0057200341183a006020024118460d00200320012d00183a0058200341193a006020024119460d00200320012d00193a00592003411a3a00602002411a460d00200320012d001a3a005a2003411b3a00602002411b460d00200320012d001b3a005b2003411c3a00602002411c460d00200320012d001c3a005c2003411d3a00602002411d460d00200320012d001d3a005d2003411e3a00602002411e460d00200320012d001e3a005e2003411f3a00602002411f460d00200341206a41106a2205200341c0006a41106a2206290300370300200341206a41086a2207200341c0006a41086a2208290300370300200320012d001f3a005f200341206a41186a2209200341c0006a41186a220a290300370300200341203a006020032003290340220b3703682003200b3703202002417c714120460d0120082007290300220b37030020062005290300220c370300200a2009290300220d37030020032003290320220e370340200128002021022000411c6a200d370200200041146a200c3702002000410c6a200b3702002000200e370204200041246a2002360200410121020c020b200341003a00600b4100210220034100360270200342013703682003410a3602242003200341086a3602202003200341e8006a3602ac01200341d4006a410136020020034201370244200341909dc5003602402003200341206a360250200341ac016a419cebc000200341c0006a103d1a2003280268200328027010ef02200328026c450d002003280268102e0b200020023602002004450d002001102e0b200341b0016a24000bb40201037f230041e0006b22022400200241086a41a081ca004107108102200241186a41b4d3c1004108108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241c8006a41086a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000bcb0201027f230041c0036b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200041003a00000c010b200328021421042003200341186a2802003602ac03200320013602a803200341e0016a200341a8036a109903410121020240024020032d00e0014101470d004100210220034100360228200342013703202003410a3602b4032003200341086a3602b0032003200341206a3602bc03200341f4016a4101360200200342013702e401200341909dc5003602e0012003200341b0036a3602f001200341bc036a419cebc000200341e0016a103d1a2003280220200328022810ef022003280224450d012003280220102e0c010b200341206a200341e0016a41017241c00110e9081a200041016a200341206a41c00110e9081a0b200020023a00002004450d002001102e0b200341c0036a24000b986905087f017e097f027e017f230041d0026b2205240002404108102c2206450d0020062001200241e0016c6a2207360204200620013602004108102c2208450d0020082003200441e0016c6a22093602042008200336020002400240024002400240024002402000450d00200541c0016a210a0c010b200541d8016a220b4200370300200541d0016a22044200370300200541c0016a41086a22024200370300200542003703c001200541a8026a41a0dac800410f1081022002200541a8026a41086a220c290000370300200520052900a8023703c001200541a8026a41a0eec8004107108102200b200c290000370300200420052900a802370300200541c0016a210a200541c0016a4120108f02450d010b200541a8026a200610a9070240024020052802a802450d00200541c0016a41106a200541a8026a41106a290300370300200541c0016a41086a200541a8026a41086a290300370300200541c0016a41186a200541a8026a41186a290300370300200541c0016a41206a200541a8026a41206a280200360200200541a0016a41086a200541cc016a290200370300200541a0016a41106a200541d4016a290200370300200541a0016a41186a200541dc016a290200370300200520052903a8023703c001200520052902c4013703a001200541c0016a200610aa07417f20052802c001220441016a220220022004491bad42287e220d422088a70d06200da72204417f4c0d062004102c220e450d07200e20052903a001370300200e4201370320200e41186a200541a0016a41186a220f290300370300200e41106a200541a0016a41106a2210290300370300200e41086a200541a0016a41086a2211290300370300200541a8026a200610a907200441286e2112024020052802a8020d00410121022006102e0c020b200541c0016a410472210b4128210c410221134101210202400340200541c0016a41206a200541a8026a41206a280200360200200541c0016a41186a2214200541a8026a41186a290300370300200541c0016a41106a2215200541a8026a41106a290300370300200541c0016a41086a2216200541a8026a41086a290300370300200520052903a8023703c0012011200b41086a2902003703002010200b41106a290200370300200f200b41186a2902003703002005200b2902003703a0012014200f2903003703002015201029030037030020162011290300370300200520052903a0013703c001024020022012470d00200541a8026a200610aa072002417f20052802a802220441016a221220122004491b6a22042002490d0920132004201320044b1b22044104200441044b1bad42287e220d422088a7454103742104200da721120240024020020d00200541003602a8020c010b200541083602b0022005200c3602ac022005200e3602a8020b20054180016a20122004200541a8026a107d20052802880121042005280280014101460d02200528028401210e200441286e21120b200e200c6a220420052903c001370300200441186a2014290300370300200441106a2015290300370300200441086a2016290300370300200441206a4201370300200541a8026a200610a907200c41286a210c201341026a2113200241016a210220052802a8020d000b2006102e0c020b2004450d060c070b2006102e4108210e41002102410021120b200541d8016a220b4200370300200541d0016a22044200370300200541c0016a41086a4200370300200542003703c001200541a8026a41a0dac800410f108102200a41086a200541a8026a41086a220c290000370000200a20052900a802370000200541a8026a41a0eec8004107108102200b200c290000370300200420052900a802370300200541a8026a200a4120109d0320052802a8024101460d01200520023602c801200520123602c4012005200e3602c001200541a0016a200541c0016a41004100200510ab070c020b200b42003703002004420037030020024200370300200542003703c001200541a8026a41a0dac800410f1081022002200c290000370300200520052900a8023703c001200541a8026a41e0eec800410c108102200441086a200c290000370000200420052900a802370000200541d0006a200541c0016a1085032005290358210d20052802502113200b42003703002004420037030020024200370300200542003703c001200541a8026a41a081ca0041071081022002200c290000370300200520052900a8023703c001200541e0006a41e4d1c100410c108102200b200541e0006a41086a29000037030020042005290060370300200541c8006a200541c0016a4120108e02200528024c21022005280248210b200541c0016a200d420020131b10ac0720052802c801210c20052802c0012104200520024100200b1b3602a8022004200c200541a8026a410410b201024020052802c401450d002004102e0b2008102e2006102e0c020b200a412010ff0120052902ac02210d200520023602c801200520123602c4012005200e3602c001200541a0016a200541c0016a200da74101200d422088a710ab070b20052d00a0012114200541d8016a220b4200370300200541d0016a220c4200370300200541c0016a41086a22134200370300200542003703c001200541a8026a41a0dac800410f108102200a41086a2215200541a8026a41086a2202290000370000200a20052900a802370000200541a8026a41e0eec800410c108102200441086a22162002290000370000200420052900a802370000200541386a200a1085032005290340420020052802381b210d024020144106470d00200b4200370300200c420037030020134200370300200542003703c001200541a8026a41a0dac800410f10810220152002290000370000200a20052900a802370000200541a8026a41e0eec800410c10810220162002290000370000200420052900a8023700002005200d42017c220d3703a802200a4120200541a8026a410810b2010b200b4200370300200c420037030020134200370300200542003703c001200541a8026a41a081ca00410710810220132002290000370300200520052900a8023703c001200541e0006a41e4d1c100410c108102200b200541e0006a41086a290000370300200c2005290060370300200541306a200541c0016a4120108e02200528023421022005280230210b200541c0016a200d10ac0720052802c801210c20052802c0012104200520024100200b1b3602a8022004200c200541a8026a410410b201024020052802c401450d002004102e0b2008102e0b4108102c2211450d0120112007360204201120013602004108102c2208450d012008200936020420082003360200200541a8026a201110ad070240024020052802a802450d00200541c0016a41106a200541a8026a41106a290300370300200541c0016a41086a200541a8026a41086a290300370300200541c0016a41186a200541a8026a41186a290300370300200541c0016a41206a200541a8026a41206a280200360200200541a0016a41086a200541cc016a290200370300200541a0016a41106a200541d4016a290200370300200541a0016a41186a200541dc016a290200370300200520052903a8023703c001200520052902c4013703a001200541c0016a201110aa07417f20052802c001220441016a220220022004491bad42287e220d422088a70d02200da72204417f4c0d022004102c2210450d03201020052903a00137030020104201370320201041186a200541a0016a41186a220e290300370300201041106a200541a0016a41106a2206290300370300201041086a200541a0016a41086a220f290300370300200541a8026a201110ad07200441286e2102024020052802a8020d004101210c2011102e0c020b200541c0016a410472210441c80021134101210c02400340200541c0016a41206a200541a8026a41206a280200360200200541c0016a41186a2214200541a8026a41186a290300370300200541c0016a41106a2215200541a8026a41106a290300370300200541c0016a41086a2216200541a8026a41086a290300370300200520052903a8023703c001200f200441086a2902003703002006200441106a290200370300200e200441186a290200370300200520042902003703a0012014200e290300370300201520062903003703002016200f290300370300200520052903a0013703c0010240200c2002470d00200541a8026a201110aa072002417f20052802a802220b41016a22122012200b491b6a220b2002490d0520024101742212200b2012200b4b1b220b4104200b41044b1bad42287e220d422088a745410374210b200da721120240024020020d00200541003602a8020c010b200541083602b002200520103602a8022005200241286c3602ac020b20054180016a2012200b200541a8026a107d20052802880121022005280280014101460d022005280284012110200241286e21020b201020136a221241606a220b20052903c0013703002016290300210d201529030021172014290300211820124201370300200b41186a2018370300200b41106a2017370300200b41086a200d370300200541a8026a201110ad07201341286a2113200c41016a210c20052802a8020d000b2011102e0c020b20020d030c020b2011102e410821104100210c410021020b200541a8026a200810ad070240024020052802a802450d00200541c0016a41106a200541a8026a41106a290300370300200541c0016a41086a200541a8026a41086a290300370300200541c0016a41186a200541a8026a41186a290300370300200541c0016a41206a200541a8026a41206a280200360200200541a0016a41086a200541cc016a290200370300200541a0016a41106a200541d4016a290200370300200541a0016a41186a200541dc016a290200370300200520052903a8023703c001200520052902c4013703a001200541c0016a200810aa07417f20052802c001220441016a220b200b2004491bad42287e220d422088a70d02200da72204417f4c0d022004102c220f450d03200f20052903a001370300200f4201370320200f41186a200541a0016a41186a2211290300370300200f41106a200541a0016a41106a2212290300370300200f41086a200541a0016a41086a220a290300370300200541a8026a200810ad07200441286e2114024020052802a8020d00410121152008102e0c020b200541c0016a410472210441c80021134101211502400340200541c0016a41206a200541a8026a41206a280200360200200541c0016a41186a2216200541a8026a41186a290300370300200541c0016a41106a220e200541a8026a41106a290300370300200541c0016a41086a2206200541a8026a41086a290300370300200520052903a8023703c001200a200441086a2902003703002012200441106a2902003703002011200441186a290200370300200520042902003703a00120162011290300370300200e20122903003703002006200a290300370300200520052903a0013703c001024020152014470d00200541a8026a200810aa072014417f20052802a802220b41016a22192019200b491b6a220b2014490d0520144101742219200b2019200b4b1b220b4104200b41044b1bad42287e220d422088a745410374210b200da721190240024020140d00200541003602a8020c010b200541083602b0022005200f3602a8022005201441286c3602ac020b20054180016a2019200b200541a8026a107d200528028801210b2005280280014101460d02200528028401210f200b41286e21140b200f20136a221941606a220b20052903c0013703002006290300210d200e29030021172016290300211820194201370300200b41186a2018370300200b41106a2017370300200b41086a200d370300200541a8026a200810ad07201341286a2113201541016a211520052802a8020d000b2008102e0c020b200b0d030c020b2008102e410021144108210f410021150b200541f8006a22134200370300200541f0006a220e4200370300200541e0006a41086a2204420037030020054200370360200541a8026a41a8f8c60041041081022004200541a8026a41086a220b290000370300200520052900a802370360200541a8026a41fa8bc500410a1081022013200b290000370300200e20052900a802370300200541206a200541e0006a10850302402005290328420020052802201b221742017c220d2017540d0020134200370300200e42003703002004420037030020054200370360200541a8026a41a8f8c60041041081022004200b290000370300200520052900a802370360200541a8026a41fa8bc500410a108102200e41086a2216200b290000370000200e20052900a8023700002005200d3703c001200541e0006a4120200541c0016a410810b20120134200370300200e42003703002004420037030020054200370360200541a8026a41a8f8c60041041081022004200b290000370300200520052900a802370360200541a8026a41a58bc500410b1081022016200b290000370000200e20052900a802370000200c41286c4104722204417f4c0d012004102c220b450d02200541003602c801200520043602c4012005200b3602c001200c200541c0016a10760240200c41286c2204450d00201020046a210b201021040340200541c0016a2004412010742005200441206a2903003703a802200541c0016a200541a8026a41081074200441286a2204200b470d000b0b200541e0006a412020052802c001220420052802c80110b201024020052802c401450d002004102e0b02402002450d00200241286c450d002010102e0b0240200d42017c2217200d540d00200541a0016a41186a22044200370300200541a0016a41106a22064200370300200541a0016a41086a22024200370300200542003703a001200541a8026a41a8f8c60041041081022002200541a8026a41086a220b290000370300200520052900a8023703a001200541a8026a41978bc500410e1081022004200b290000370300200620052900a802370300200541c0016a200541a0016a10a30420052d00c0012104200541e0006a41186a2202200541d9016a290000370300200541e0006a41106a220b200541d1016a290000370300200541e0006a41086a220c200541c9016a290000370300200520052900c1013703600240024020044101460d0020054180016a41186a420037030020054180016a41106a420037030020054180016a41086a420037030020054200370380010c010b20054180016a41186a200229030037030020054180016a41106a200b29030037030020054180016a41086a200c29030037030020052005290360370380010b200541e0006a41186a220b4200370300200541e0006a41106a220c4200370300200541e0006a41086a2202420037030020054200370360200541a8026a41a8f8c60041041081022002200541a8026a41086a2204290000370300200520052900a802370360200541a8026a41ee8bc500410c108102200e41086a22132004290000370000200e20052900a802370000200541186a200541e0006a4120108e02200528021c211620052802182110200b4200370300200c42003703002002420037030020054200370360200541a8026a41a8f8c600410410810220022004290000370300200520052900a802370360200541a8026a41ee8bc500410c10810220132004290000370000200e20052900a802370000200541003602c001200541e0006a4120200541c0016a410410b201200541a8026a41186a20054180016a41186a290300370300200541a8026a41106a20054180016a41106a290300370300200420054180016a41086a29030037030020052005290380013703a802417f2016410020101b221041016a220420042010491b410d744128722204417f4c0d022004102c220b450d0341002102200541003602f801200520043602f4012005200b3602f001200541f0016a200541a8026a41201074200520173703c001200541f0016a200541c0016a4108107441002104034020022010200220104b1b21160240034002402004450d00200b200c470d02201341ffffff3f71450d002004102e0b024020162002460d0020054188026a200210db06200541e0006a200528028802220b200528029002220c10b60502400240200528026022040d004200210d410121040c010b200b200c10ff012005290264210d0b0240200528028c02450d00200b102e0b200241016a21022004200d422088a74105746a210c200da721132004210b0c010b0b200541c0016a20052802f001220420052802f80110b001024020052802f401450d002004102e0b200541f8006a4200370300200541f0006a4200370300200541e0006a41086a2204420037030020054200370360200541a8026a41a8f8c60041041081022004200541a8026a41086a2202290000370300200520052900a802370360200541a8026a41978bc500410e108102200e41086a2002290000370000200e20052900a8023700004120102c2204450d05200542203702ac02200520043602a802200541a8026a200541c0016a41201074200541e0006a412020052802a802220420052802b00210b201024020052802ac02450d002004102e0b200541a0016a41186a20054180016a41186a290300370300200541a0016a41106a20054180016a41106a290300370300200541a0016a41086a20054180016a41086a29030037030020052005290380013703a001200541e0006a41186a4200370300200541e0006a41106a4200370300200541e0006a41086a2204420037030020054200370360200541a8026a41a8f8c60041041081022004200541a8026a41086a2202290000370300200520052900a802370360200541a8026a41c28cc500410a108102200e41086a2002290000370000200e20052900a8023700004120102c2204450d05200542203702c401200520043602c001200541c0016a200541a0016a41201074200541e0006a412020052802c001220420052802c80110b201024020052802c401450d002004102e0b200541f8006a4200370300200541f0006a4200370300200541e0006a41086a2204420037030020054200370360200541a8026a41a8f8c60041041081022004200541a8026a41086a2202290000370300200520052900a802370360200541a8026a41ba8bc500410f108102200e41086a2002290000370000200e20052900a802370000201541286c4104722204417f4c0d042004102c2202450d05200541003602c801200520043602c401200520023602c0012015200541c0016a10760240201541286c2204450d00200f20046a2102200f21040340200541c0016a2004412010742005200441206a2903003703a802200541c0016a200541a8026a41081074200441286a22042002470d000b0b200541e0006a412020052802c001220420052802c80110b201024020052802c401450d002004102e0b200541a0016a41186a220c4200370300200541a0016a41106a22134200370300200541a0016a41086a22044200370300200542003703a001200541a8026a41a8f8c60041041081022004200541a8026a41086a2202290000370300200520052900a8023703a001200541e0006a41b08bc500410a108102200641086a2216200541e0006a41086a220b29000037000020062005290060370000200541c0016a200541a0016a4120109d03200541c0016a41086a2212280200210a20052802c0012108200541e0006a41186a22104200370300200541e0006a41106a22114200370300200b420037030020054200370360200541a8026a41d9fcc6004106108102200b2002290000370300200520052900a802370360200541a8026a4180f4cb004106108102200e41086a2002290000370000200e20052900a802370000200541106a200541e0006a4120108e0220122005280214410020052802101b360200200541013602c0012005200a410020084101461b3602c401200c42003703002013420037030020044200370300200542003703a001200541a8026a41a8f8c600410410810220042002290000370300200520052900a8023703a001200541e0006a41b08bc500410a1081022016200b29000037000020062005290060370000200541a0016a4120200541c0016a410472109e03200c42003703002013420037030020044200370300200542003703a001200541a8026a41a8f8c600410410810220042002290000370300200520052900a8023703a001200541a8026a41978bc500410e10810220162002290000370000200620052900a802370000200541c0016a200541a0016a10a30420052d00c00121022010200541d9016a2900003703002011200541d1016a290000370300200b200541c9016a290000370300200520052900c1013703600240024020024101460d00200c42003703002013420037030020044200370300200542003703a0010c010b200c2010290300370300201320112903003703002004200b290300370300200520052903603703a0010b200541c0016a410c6a2015360200200541c0016a41086a2014360200200541c0016a41106a20052903a001370300200541c0016a41186a200541a0016a41086a290300370300200541e0016a200541a0016a41106a290300370300200541c0016a41286a200541a0016a41186a2903003703002005200f3602c401200541003602c001200541a8026a200541c0016a10a404200541eb006a200541a8026a41086a2204280200360000200520052903a802370063200541a8026a410c6a200541e7006a290000370000200541c28289aa043600a902200541023a00a802200520052900603700ad02200541a8026a10a50402402014450d00201441286c450d00200f102e0b200541e0006a41186a4200370300200541e0006a41106a4200370300200541e0006a41086a2202420037030020054200370360200541a8026a41a8f8c600410410810220022004290000370300200520052900a802370360200541a8026a41d48bc500410f108102200e41086a2004290000370000200e20052900a802370000200541c0016a200541e0006a10b005024020052d00d00122044103460d0020052903c001210d20052903c8012117200541f8006a4200370300200541f0006a4200370300200541e0006a41086a2202420037030020054200370360200541a8026a41a8f8c60041041081022002200541a8026a41086a220b290000370300200520052900a802370360200541a8026a418c8bc500410b108102200e41086a200b290000370000200e20052900a802370000200541e0006a200d2017200410c2050b200541e0006a41186a4200370300200541f0006a4200370300200541e0006a41086a2204420037030020054200370360200541a8026a41a8f8c60041041081022004200541a8026a41086a2202290000370300200520052900a802370360200541a8026a41aa8cc5004118108102200e41086a2002290000370000200e20052900a80237000020054120360284022005200541e0006a3602800220054188026a200541e0006a412010ed020240024020052802880222020d00410321040c010b200528028c02210b200520054188026a41086a28020036029c022005200236029802200541c0016a20054198026a1095020240024020052d00d00122044103470d00200541003602b002200542013703a8022005410a3602f401200520054180026a3602f0012005200541a8026a3602a402200541d4016a4101360200200542013702c401200541909dc5003602c0012005200541f0016a3602d001200541a4026a419cebc000200541c0016a103d1a20052802a80220052802b00210ef02024020052802ac02450d0020052802a802102e0b0c010b200520052800d1013602a8022005200541d4016a2800003600ab0220052903c801210d20052903c00121170b0240200b450d002002102e0b024020044103470d00410321040c010b200541e0006a412010ff010b200520052800ab0236008b02200520052802a80236028802024020044103460d00200541e0006a41186a4200370300200541e0006a41106a4200370300200541e0006a41086a220b420037030020054200370360200541a8026a41a8f8c6004104108102200b200541a8026a41086a2202290000370300200520052900a802370360200541a8026a41d48bc500410f108102200e41086a2002290000370000200e20052900a802370000200541e0006a2017200d200410c205200541c0016a41186a20043a0000200541c0016a41106a200d370300200541c0016a41086a2017370300200541dc016a200528008b0236000020052005280288023600d901200541023602c001200541a8026a200541c0016a10a404200541e0006a41036a220441086a2002280200360000200420052903a802370000200541b4026a200541e7006a290000370000200541c28289aa043600a902200541023a00a802200520052900603700ad02200541a8026a10a5040b4108102c2206450d0520062007360204200620013602004108102c2212450d052012200936020420122003360200200541c0016a41186a22044200370300200541c0016a41106a22114200370300200541c0016a41086a22024200370300200542003703c001200541a8026a41d9fcc60041061081022002200541a8026a41086a220b290000370300200520052900a8023703c001200541e0006a4180f4cb0041061081022004200541e0006a41086a221429000037030020112005290060370300200541086a200541c0016a4120108e022005280208210c200528020c2113200442003703002011420037030020024200370300200542003703c001200541a8026a41bed8c80041081081022002200b290000370300200520052900a8023703c001200541a8026a41dbdac800410e1081022004200b290000370300201120052900a8023703002005201341b0096a41b009200c1b3602a802200541c0016a4120200541a8026a410410b201200541a8026a200610ae070240024020052802a802450d002011200541a8026a41106a2903003703002002200b2903003703002004200541a8026a41186a290300370300200541c0016a41206a200541a8026a41206a2802003602002014200541cc016a290200370300200541e0006a41106a200541d4016a290200370300200541e0006a41186a200541dc016a290200370300200520052903a8023703c001200520052902c401370360200541c0016a200610aa07417f20052802c001220441016a220220022004491b220441ffffff3f712004470d0620044105742204417f4c0d062004102c220e450d07200541e0006a41086a290300210d200541e0006a41106a290300211720052903602118200e41186a200541e0006a41186a290300370000200e41106a2017370000200e41086a200d370000200e2018370000200541a8026a200610ae072004410576210b024020052802a8020d004101210c2006102e0c020b200541c0016a4104722104412021134101210c02400340200541c0016a41206a200541a8026a41206a280200360200200541c0016a41186a2214200541a8026a41186a290300370300200541c0016a41106a2215200541a8026a41106a290300370300200541c0016a41086a2216200541a8026a41086a290300370300200520052903a8023703c001200541a0016a41086a2202200441086a290000370300200541a0016a41106a220f200441106a290000370300200541a0016a41186a2210200441186a290000370300200520042900003703a001201420102903003703002015200f29030037030020162002290300370300200520052903a0013703c0010240200c200b470d00200541a8026a200610aa07200b417f20052802a802220241016a220f200f2002491b6a2202200b490d09200b410174220f2002200f20024b1b22024104200241044b1b220241ffffff3f71200246210f2002410574210202400240200b0d00200541003602a8020c010b200541013602b0022005200e3602a8022005200b4105743602ac020b20054180016a2002200f200541a8026a107d20052802880121022005280280014101460d02200528028401210e2002410576210b0b200e20136a220220052903c001370000200241186a2014290300370000200241106a2015290300370000200241086a2016290300370000200541a8026a200610ae07201341206a2113200c41016a210c20052802a8020d000b2006102e0c020b20020d070c060b2006102e4101210e4100210c4100210b0b200541d8016a4200370300200541d0016a4200370300200541c0016a41086a22044200370300200542003703c001200541a8026a41bed8c80041081081022004200541a8026a41086a2202290000370300200520052900a8023703c001200541a8026a41e9d8c8004104108102201141086a2002290000370000201120052900a802370000200c4105744104722204417f4c0d042004102c2202450d05200541003602b002200520043602ac02200520023602a802200c200541a8026a10760240200c450d00200c4105742102200e21040340200541a8026a200441201074200441206a2104200241606a22020d000b0b200541c0016a412020052802a802220420052802b00210b201024020052802ac02450d002004102e0b0240200b41ffffff3f71450d00200e102e0b2012102e4108102c2204450d0520042007360204200420013602004108102c2202450d0520022009360204200220033602002002102e2004102e4108102c2204450d0520042007360204200420013602004108102c2202450d0520022009360204200220033602002002102e2004102e4108102c220e450d05200e2007360204200e20013602004108102c2206450d052006200936020420062003360200024002402000450d00200541a8026a200e10af070240024020052802a802450d00200541c0016a41106a200541a8026a41106a290300370300200541c0016a41086a200541a8026a41086a290300370300200541c0016a41186a200541a8026a41186a290300370300200541c0016a41206a200541a8026a41206a280200360200200541e0006a41086a200541cc016a290200370300200541e0006a41106a200541d4016a290200370300200541e0006a41186a200541dc016a290200370300200520052903a8023703c001200520052902c401370360200541c0016a200e10aa07417f20052802c001220441016a220220022004491b220441ffffff3f712004470d0820044105742204417f4c0d082004102c220f450d09200541e0006a41086a290300210d200541e0006a41106a290300211720052903602118200f41186a200541e0006a41186a290300370000200f41106a2017370000200f41086a200d370000200f2018370000200541a8026a200e10af072004410576211202400240024020052802a8020d00410121040c010b200541c0016a41047221024120210c41022113410121040340200541c0016a41206a200541a8026a41206a280200360200200541c0016a41186a2214200541a8026a41186a290300370300200541c0016a41106a2215200541a8026a41106a290300370300200541c0016a41086a2216200541a8026a41086a290300370300200520052903a8023703c001200541a0016a41086a220b200241086a290000370300200541a0016a41106a2210200241106a290000370300200541a0016a41186a2211200241186a290000370300200520022900003703a00120142011290300370300201520102903003703002016200b290300370300200520052903a0013703c001024020042012470d00200541a8026a200e10aa072004417f20052802a802220b41016a22102010200b491b6a220b2004490d0c2013200b2013200b4b1b220b4104200b41044b1b220b41ffffff3f71200b462110200b410574210b0240024020040d00200541003602a8020c010b200541013602b0022005200c3602ac022005200f3602a8020b20054180016a200b2010200541a8026a107d200528028801210b2005280280014101460d03200528028401210f200b41057621120b200f200c6a220b20052903c001370000200b41186a2014290300370000200b41106a2015290300370000200b41086a2016290300370000200541a8026a200e10af07200c41206a210c201341026a2113200441016a210420052802a8020d000b0b200e102e200520043602c801200520123602c4012005200f3602c0010c020b200b0d090c080b41002112200541003602c801200542013703c001200e102e4101210f0b200541c0026a22044200370300200541b8026a220a4200370300200541a8026a41086a4200370300200542003703a802200541a8026a41b2fdc6004112108102200541e0006a41e9d8c80041041081022004200541e0006a41086a290000370300200a2005290060370300200541a8026a200541c0016a10c1050240201241ffffff3f71450d00200f102e0b200541a8026a200610af070240024020052802a802450d00200541c0016a41106a200541a8026a41106a290300370300200541c0016a41086a200541a8026a41086a290300370300200541c0016a41186a200541a8026a41186a290300370300200541c0016a41206a200541a8026a41206a280200360200200541e0006a41086a200541cc016a290200370300200541e0006a41106a200541d4016a290200370300200541e0006a41186a200541dc016a290200370300200520052903a8023703c001200520052902c401370360200541c0016a200610aa07417f20052802c001220441016a220220022004491b220441ffffff3f712004470d0820044105742204417f4c0d082004102c220e450d09200541e0006a41086a290300210d200541e0006a41106a290300211720052903602118200e41186a200541e0006a41186a290300370000200e41106a2017370000200e41086a200d370000200e2018370000200541a8026a200610af072004410576211102400240024020052802a8020d00410121040c010b200541c0016a41047221024120210c41022113410121040340200541c0016a41206a200541a8026a41206a280200360200200541c0016a41186a2214200541a8026a41186a290300370300200541c0016a41106a2215200541a8026a41106a290300370300200541c0016a41086a2216200541a8026a41086a290300370300200520052903a8023703c001200541a0016a41086a220b200241086a290000370300200541a0016a41106a220f200241106a290000370300200541a0016a41186a2210200241186a290000370300200520022900003703a001201420102903003703002015200f2903003703002016200b290300370300200520052903a0013703c001024020042011470d00200541a8026a200610aa072004417f20052802a802220b41016a220f200f200b491b6a220b2004490d0c2013200b2013200b4b1b220b4104200b41044b1b220b41ffffff3f71200b46210f200b410574210b0240024020040d00200541003602a8020c010b200541013602b0022005200c3602ac022005200e3602a8020b20054180016a200b200f200541a8026a107d200528028801210b2005280280014101460d03200528028401210e200b41057621110b200e200c6a220b20052903c001370000200b41186a2014290300370000200b41106a2015290300370000200b41086a2016290300370000200541a8026a200610af07200c41206a210c201341026a2113200441016a210420052802a8020d000b0b2006102e200520043602c801200520113602c4012005200e3602c0010c020b200b0d090c080b41002111200541003602c801200542013703c0012006102e4101210e0b200541c0026a4200370300200541b8026a4200370300200541a8026a41086a4200370300200542003703a802200541a8026a41b2fdc6004112108102200541e0006a41b4d3c1004108108102200a41086a200541e0006a41086a290000370000200a2005290060370000200541a8026a200541c0016a10c105201141ffffff3f71450d01200e102e0c010b2006102e200e102e0b200541d0026a24000f0b200541a0016a41186a200b41186a2216290000370300200541a0016a41106a200b41106a2211290000370300200541a0016a41086a200b41086a22122900003703002005200b2900003703a0012012290000210d20112900002117200b2900002118200541c0016a41186a22112016290000370300200541c0016a41106a22162017370300200541c0016a41086a2212200d370300200520183703c001200541e0006a41186a2011290300370300200541e0006a41106a2016290300370300200541e0006a41086a2012290300370300200520052903c001370360200541f0016a200541e0006a41201074200b41206a210b0c000b0b41bcb4c40041c9004198b5c400105d000b41bcb4c40041c9004188b5c400105d000b1038000b1036000b930501047f230041a0036b22012400200141106a4200370300200141186a4200370300200141206a4200370300200141286a4200370300200120012903c801370308200142c0b2cd3b37039803200142c0b2cd3b37039003200142c0b2cd3b370388034100210241012103034020014188036a2104024002400240200241ff01710e03010002010b20014190036a21040c010b20014198036a21040b200442c0b2cd3b370300024020034103460d00200341e99fc0006a2104200341016a210320042d000022024103470d010b0b20014188026a420037030020014180026a4201370300200141f8016a22034200370300200141f0016a22044201370300200141c8016a41186a4200370300200141c8016a41f8006a4200370300200141c8016a41f0006a4201370300200141c8016a41e8006a4200370300200141c8016a41e0006a420137030020014198026a420037030020014190026a200129039003370300200141d0026a4200370300200141c8026a200129038803370300200142003703d00120014280e497d0123703c80120012001290398033703d801200141f8026a200141286a290300370300200141f0026a200141086a41186a290300370300200141e8026a200141186a290300370300200141e0026a200141106a290300370300200141d8026a20012903083703002004420137030020034280b0def7d32b3703002001410036028003200141086a200141c8016a41c00110e9081a200141086a41f8006a428090cad2c60e370300200141086a41f0006a4201370300200141086a41e8006a4280c0a8ca9a3a370300200141086a41e0006a4201370300200141c8016a200141086a41b80110e9081a2001428180808080d0a5cc00370380032000200141c8016a107f200141a0036a24000bc88d0109017f027e047f047e057f017e117f037e287f230041d01a6b22012400200141d0176a10df0420012903d81721024200210320014190046a22044200370300200141f8036a41106a22054200370300200141f8036a41086a22064200370300200142003703f803200141d0176a4199fdc60041081081022006200141d0176a41086a2207290000370300200120012900d0173703f803200141d0176a41fc8ac500411010810220042007290000370300200520012900d017370300200141203602dc142001200141f8036a3602d814200141f0066a200141f8036a412010ed022002428094ebdc038242808c8d9e027e2208428094ebdc038021092008428094ebdc0382210a2002428094ebdc0380210b4100210c024002400240024020012802f006220d0d004100210e0c010b20012802f406210f2001200141f0066a41086a280200360294152001200d36029015200141c0006a20014190156a10ab010240024002402001280240450d000c010b20012802442210200128029415411c6e2204200420104b1bad421c7e2202422088a70d042002a72204417f4c0d040240024020040d004104210e0c010b2004102c220e450d040b2004411c6ead21110240024002400240024020100d000c010b200141d0176a41c4006a2106410021120340200141386a20014190156a10ab0120012802380d04200128023c221320012802941541e0006e2204200420134b1bad42e0007e2202422088a70d092002a72204417f4c0d090240024020040d00410821140c010b2004102c2214450d090b200441e0006e21150240024020130d00410021130c010b41002116410021054100210702400340200141d0176a20014190156a10e004200141c8006a41386a2204200141d0176a41386a290300370300200141c8006a41306a2217200141d0176a41306a290300370300200141c8006a41286a2218200141d0176a41286a290300370300200141c8006a41206a2219200141d0176a41206a290300370300200141c8006a41186a221a200141d0176a41186a290300370300200141c8006a41106a221b200141d0176a41106a290300370300200141c8006a41086a221c200141d0176a41086a290300370300200141a00f6a41086a221d200641086a290200370300200141a00f6a41106a221e200641106a290200370300200141a00f6a41186a221f200641186a280200360200200120012903d017370348200120062902003703a00f2001280290182220450d0120014198126a41386a2221200429030037030020014198126a41306a2222201729030037030020014198126a41286a2217201829030037030020014198126a41206a2218201929030037030020014198126a41186a2219201a29030037030020014198126a41106a221a201b29030037030020014198126a41086a221b201c290300370300200141e00c6a41086a221c201d290300370300200141e00c6a41106a221d201e290300370300200141e00c6a41186a221e201f2802003602002001200129034837039812200120012903a00f3703e00c024020072015470d002016200741016a2204201620044b1b22044104200441044b1bad42e0007e2202422088a74541037421042002a7211f0240024020070d00200141003602d0170c010b200141083602d817200120053602d417200120143602d0170b200141e8096a201f2004200141d0176a107d20012802f0092104024020012802e8094101470d0020040d0d0c0e0b20012802ec092114200441e0006e21150b201420056a2204200129039812370300200441106a201a290300370300200441086a201b2903003703002022290300210220212903002108201729030021232018290300212420192903002125200441c0006a2020360200200441186a2025370300200441206a2024370300200441286a2023370300200441386a2008370300200441306a2002370300200441c4006a20012903e00c370200200441cc006a201c290300370200200441d4006a201d290300370200200441dc006a201e280200360200201641026a2116200541e0006a21052013200741016a2207460d020c000b0b02402007450d00201441d4006a210403400240200441706a2802002206450d00200641306c450d002004416c6a280200102e0b0240200428020041ffffff3f71450d002004417c6a280200102e0b200441e0006a2104200541a07f6a22050d000b0b2015450d05201541e0006c450d050c040b2014450d04200141306a20014190156a10ab010240024020012802300d00200128023422262001280294154102762204200420264b1b22274102742204417f4c0d0b0240024020270d00410421280c010b2004102c2228450d0b0b0240024020260d00410021260c010b4100210541002107410021040240034020012802941522174104490d012001280290152218280000211620012017417c6a360294152001201841046a360290152016418094ebdc034b0d01024020042027470d002007200441016a2217200720174b1b22174104201741044b1b221741ffffffff03712017464102742118201741027421170240024020040d00200141003602d0170c010b200141043602d817200120053602d417200120283602d0170b200141c8006a20172018200141d0176a107d20012802502117024020012802484101470d002017450d100c0f0b200128024c2128201741027621270b202820056a2016360200200541046a2105200741026a21072026200441016a2204460d020c000b0b202741ffffffff0371450d012028102e0c010b2028450d00200128029415220441034b0d010240202741ffffffff0371450d002028102e0b02402013450d002014201341e0006c6a21062014210403400240200441c4006a2802002205450d00200541306c450d00200441c0006a280200102e0b200441e0006a21050240200441d4006a28020041ffffff3f71450d00200441d0006a280200102e0b2005210420062005470d000b0b2015450d06201541e0006c0d050c060b02402013450d002014201341e0006c6a21062014210403400240200441c4006a2802002205450d00200541306c450d00200441c0006a280200102e0b200441e0006a21050240200441d4006a28020041ffffff3f71450d00200441d0006a280200102e0b2005210420062005470d000b0b2015450d05201541e0006c0d040c050b2001280290152205280000212920012004417c6a360294152001200541046a3602901502402011422088a722042011a7470d00200441016a22052004490d0a20044101742207200520052007491b22054104200541044b1bad421c7e2202422088a74541027421052002a721070240024020040d00200141003602d0170c010b200141043602d8172001200e3602d01720012004411c6c3602d4170b200141c8006a20072005200141d0176a107d2001280250210520012802484101460d03200128024c210e2011428080808070832005411c6ead8421110b200e2004411c6c6a2204201536020420042014360200200441186a2029360200200441146a2026360200200441106a20273602002004410c6a2028360200200441086a201336020020114280808080107c21112026212a2027212b2028212c2013212d2015212e201241016a22122010470d000b0b200e0d040c030b2005450d060c050b2014102e0b02402011422088a72204450d00200e2004411c6c6a2116200e21070340024020072802082204450d00200441e0006c2105200728020041d4006a210403400240200441706a2802002206450d00200641306c450d002004416c6a280200102e0b0240200428020041ffffff3f71450d002004417c6a280200102e0b200441e0006a2104200541a07f6a22050d000b0b0240200741046a2802002204450d00200441e0006c450d002007280200102e0b2007411c6a21040240200741106a28020041ffffffff0371450d00200728020c102e0b2004210720042016470d000b0b02402011a72204450d002004411c6c450d00200e102e0b202e2115202d2113202c2128202b2127202a21260b4100210e20014100360250200142013703482001410a36029c122001200141d8146a360298122001200141c8006a3602a00f200141e4176a4101360200200142013702d417200141909dc5003602d017200120014198126a3602e017200141a00f6a419cebc000200141d0176a103d1a2001280248200128025010ef02200128024c450d002001280248102e0b200f450d00200d102e0b200e4104200e1b2114024020114200200e1b2208422088a72207450d00200b42808c8d9e027e2009200a4280cab5ee0156ad7c7c210242002103410021164100210c0240034002400240200c450d0020142104200c210603400240200320025a0d00200141206a200420166a220e2802002014200c411c6c6a2204280208200428020c200441146a2802002004280218109203200129032821230c030b2004200420166a2205290200370200200441186a200541186a280200360200200441106a200541106a290200370200200441086a200541086a2902003702002004411c6a2104200641016a22062007490d000c040b0b200c210403400240200320025a0d00200141106a2014200c411c6c6a220e280200200e280208200e28020c200e41146a280200200e280218109203200129031821230c020b200441016a22042007490d000b4100210c0c030b02402014200c411c6c6a22172802082204450d00200441e0006c2105200e28020041d4006a210403400240200441706a2802002206450d00200641306c450d002004416c6a280200102e0b0240200428020041ffffff3f71450d002004417c6a280200102e0b200441e0006a2104200541a07f6a22050d000b0b0240200e41046a2802002204450d00200441e0006c450d00200e280200102e0b200c41016a210c0240201741106a28020041ffffffff0371450d00201728020c102e0b200320237c21032016411c6a2116200c2106200c2007490d000b0b0240200c0d004100210c0c010b20142006200c6b411c6c6a20142006411c6c6a200720066b411c6c10ea081a0b200141e8176a22044200370300200141d0176a41106a22054200370300200141d0176a41086a22064200370300200142003703d017200141c8006a4199fdc60041081081022006200141c8006a41086a2216290000370300200120012900483703d017200141c8006a41fc8ac500411010810220042016290000370300200520012900483703002007200c6b2204411c6c41046a2205417f4c0d010240024020050d00410121060c010b2005102c2206450d010b200141003602502001200536024c200120063602482004200141c8006a107620142004200141c8006a10a001200141d0176a412020012802482205200128025010b2010240200128024c450d002005102e0b02402004450d0020142004411c6c6a2116201421070340024020072802082204450d00200441e0006c2105200728020041d4006a210403400240200441706a2802002206450d00200641306c450d002004416c6a280200102e0b0240200428020041ffffff3f71450d002004417c6a280200102e0b200441e0006a2104200541a07f6a22050d000b0b0240200741046a2802002204450d00200441e0006c450d002007280200102e0b2007411c6a21040240200741106a28020041ffffffff0371450d00200728020c102e0b2004210720042016470d000b0b02402008a72204450d002004411c6c450d002014102e0b20014198126a10e1044100210520012802981221164100210602400240024002400240024020012802a012220c450d00200c41c4006c2107200c410274417c6a41027641016a2114410021062016210402400340024020042d00004101460d00200441046a28020020004f0d020b200441c4006a2104200641016a2106200741bc7f6a22070d000b201421060b200c2006490d010b200141003602a012200c20066b210e2016200641c4006c220c6a210402400340200c2005460d01201620056a2107200541c4006a2214210520072d00004102470d000b201620146a21040b2016200641c4006c6a21070240034020072004460d0120042d00002105200441c4006a210420054102470d000b0b02400240200e0d004100210e0c010b02402006450d0020162016200641c4006c6a200e41c4006c10ea081a0b2001200e3602a0120b200128029c122106200141e8176a22054200370300200141e0176a22044200370300200141d0176a41086a22074200370300200142003703d017200141c8006a4190dac800410a1081022007200141c8006a41086a220c290000370300200120012900483703d017200141c8006a41d5dac80041061081022005200c29000037030020042001290048370300200e41c4006c41046a2205417f4c0d060240024020050d00410121070c010b2005102c2207450d060b200141003602502001200536024c20012007360248200e200141c8006a10762016200e200141c8006a109f01200141d0176a412020012802482205200128025010b2010240200128024c450d002005102e0b02402006450d00200641c4006c450d002016102e0b42002102200141d0176a41186a22074200370300200141d0176a41106a221642003703004108212a200141d0176a41086a22064200370300200142003703d017200141c8006a4190dac800410a1081022006200141c8006a41086a2205290000370300200120012900483703d017200141c8006a41d097c900410c108102200441086a200529000037000020042001290048370000200141003a0048200141d0176a4120200141c8006a410110b201200141c8006a10e204200141f8036a41186a220c200141c8006a41186a2214290300370300200141f8036a41106a220e200141c8006a41106a2217290300370300200141f8036a41086a22182005290300370300200120012903483703f8034124102c2204450d05200420012903f80337010020044114360220200441186a200c290300370100200441106a200e290300370100200441086a201829030037010020014281808080103702d417200120043602d017200141d0176a10e304200720142903003703002016201729030037030020062005290300370300200120012903483703d017200141d0176a10e404108403200141d0176a10df0420012903d8172108200141c8006a200010a704200141d0176a200128024822042001280250220510c5042008428094ebdc0382428090bcfd027e2223428094ebdc038021242023428094ebdc038221232008428094ebdc03802108024020012802d0172206450d002004200510ff0120012902d41721022006212a0b0240200128024c450d002004102e0b202a2002422088a7220441f8026c22056a21062002a7212b024020040d00202a21040c030b200541887d6a2119200141d0176a41046a2110200141c8006a41046a2121200141a00f6a41046a210d41002107200141c0036a41306a2116200141c0036a41286a210c200141c0036a41206a2114200141c0036a41186a210e200141c0036a41106a2117200141c0036a41086a2118202a210402400340200141f8036a200441bc0210e9081a200441bc026a28020021052016200441f0026a290300370300200c200441e8026a2903003703002014200441e0026a290300370300200e200441d8026a2903003703002017200441d0026a2903003703002018200441c8026a2903003703002001200441c0026a2903003703c00320054103460d03200d200141f8036a41bc0210e9082122200141c8006a200141a00f6a41c00210e9081a20014190156a202141bc0210e9081a200141d8146a41306a221b2016290300370300200141d8146a41286a221c200c290300370300200141d8146a41206a221d2014290300370300200141d8146a41186a221e200e290300370300200141d8146a41106a221f2017290300370300200141d8146a41086a22202018290300370300200120012903c0033703d814024002402005410247221a0d00200141e00c6a4194b4c00041c00210e9081a4100211b200141a80c6a41306a4100290388b740370300200141a80c6a41286a4100290380b740370300200141a80c6a41206a41002903f8b640370300200141a80c6a41186a41002903f0b640370300200141a80c6a41106a41002903e8b640370300200141a80c6a41086a41002903e0b640370300200141002903d8b6403703a80c0c010b201020014190156a41bc0210e9081a20014198126a200141d0176a41c00210e9081a200141e0116a41306a220f201b290300370300200141e0116a41286a221b201c290300370300200141e0116a41206a221c201d290300370300200141e0116a41186a221d201e290300370300200141e0116a41106a221e201f290300370300200141e0116a41086a221f2020290300370300200120012903d8143703e011200141e00c6a20014198126a41c00210e9081a200141a80c6a41306a200f290300370300200141a80c6a41286a201b290300370300200141a80c6a41206a201c290300370300200141a80c6a41186a201d290300370300200141a80c6a41106a201e290300370300200141a80c6a41086a201f290300370300200120012903e0113703a80c2007211b0b201a0d01200741016a2107201941887d6a2119200441f8026a22042006470d000b200621040c030b200141f0066a200141e00c6a41c00210e9081a200141b8066a41306a2216200141a80c6a41306a290300370300200141b8066a41286a220c200141a80c6a41286a290300370300200141b8066a41206a2214200141a80c6a41206a290300370300200141b8066a41186a220e200141a80c6a41186a290300370300200141b8066a41106a2217200141a80c6a41106a290300370300200141b8066a41086a2218200141a80c6a41086a290300370300200120012903a80c3703b806200141e8096a200141f0066a41c00210e9081a200141b0096a41306a221a2016290300370300200141b0096a41286a2216200c290300370300200141b0096a41206a220c2014290300370300200141b0096a41186a2214200e290300370300200141b0096a41106a220e2017290300370300200141b0096a41086a22172018290300370300200120012903b8063703b009418003102c2220450d052020201b360200202041046a200141e8096a41c00210e9081a202020053602c402202020012903b0093703c802202041d0026a2017290300370300202041d8026a200e290300370300202041e0026a2014290300370300202041e8026a200c290300370300202041f0026a2016290300370300202041f8026a201a29030037030020062105024002402019450d00200441f8026a2104200741016a2107200141a00f6a41046a210d200141a80c6a41306a2116200141a80c6a41286a210c200141a80c6a41206a2114200141a80c6a41186a210e200141a80c6a41106a2117200141a80c6a41086a211802400340200141f0066a200441bc0210e9081a200441bc026a28020021052016200441f0026a290300370300200c200441e8026a2903003703002014200441e0026a290300370300200e200441d8026a2903003703002017200441d0026a2903003703002018200441c8026a2903003703002001200441c0026a2903003703a80c20054103460d01200d200141f0066a41bc0210e9081a200141c8006a200141a00f6a41c00210e9081a20014190156a202141bc0210e9081a200141d8146a41306a221a2016290300370300200141d8146a41286a221b200c290300370300200141d8146a41206a221c2014290300370300200141d8146a41186a221d200e290300370300200141d8146a41106a221e2017290300370300200141d8146a41086a221f2018290300370300200120012903a80c3703d81402400240200541024722190d00200141e00c6a4194b4c00041c00210e9081a4100211a200141e0116a41306a4100290388b740370300200141e0116a41286a4100290380b740370300200141e0116a41206a41002903f8b640370300200141e0116a41186a41002903f0b640370300200141e0116a41106a41002903e8b640370300200141e0116a41086a41002903e0b640370300200141002903d8b6403703e0110c010b201020014190156a41bc0210e9081a20014198126a200141d0176a41c00210e9081a200141f8036a41306a220f201a290300370300200141f8036a41286a221a201b290300370300200141f8036a41206a221b201c290300370300200141f8036a41186a221c201d290300370300200141f8036a41106a221d201e290300370300200141f8036a41086a221e201f290300370300200120012903d8143703f803200141e00c6a20014198126a41c00210e9081a200141e0116a41306a200f290300370300200141e0116a41286a201a290300370300200141e0116a41206a201b290300370300200141e0116a41186a201c290300370300200141e0116a41106a201d290300370300200141e0116a41086a201e290300370300200120012903f8033703e0112007211a0b20190d03200741016a2107200441f8026a22042006470d000b200621050c010b200441f8026a21050b4101212f4101210d0c040b200141e8096a200141e00c6a41c00210e9081a200141b0096a41306a222c200141e0116a41306a221b290300370300200141b0096a41286a222d200141e0116a41286a221c290300370300200141b0096a41206a222e200141e0116a41206a221d290300370300200141b0096a41186a2212200141e0116a41186a221e290300370300200141b0096a41106a2230200141e0116a41106a221f290300370300200141b0096a41086a2231200141e0116a41086a220f290300370300200120012903e0113703b009200441f8026a2104200741016a21074101212f4101210d0340200141d0176a200141e8096a41c00210e9081a200141c8006a41306a220c202c290300370300200141c8006a41286a2214202d290300370300200141c8006a41206a220e202e290300370300200141c8006a41186a22172012290300370300200141c8006a41106a22182030290300370300200141c8006a41086a22192031290300370300200120012903b009370348024002400240200d202f470d00202f41016a2216202f490d0a202f41017422322016203220164b1b22164104201641044b1bad4280037e2202422088a74541037421162002a7213202400240202f0d0020014100360298120c010b200141083602a01220012020360298122001202f4180036c36029c120b200141a00f6a2032201620014198126a107d20012802a80f211620012802a00f4101460d0120012802a40f212020164180036e212f0b2020200d4180036c6a2216201a360200201641046a200141d0176a41c00210e9081a201641c4026a2005360200201641c8026a2001290348370300201641d0026a2019290300370300201641d8026a2018290300370300201641e0026a2017290300370300201641e8026a200e290300370300201641f0026a2014290300370300201641f8026a200c290300370300200d41016a210d20042006470d01200621050c060b2016450d080c070b024002400340200141f8036a200441bc0210e9081a200441bc026a2802002105200141c0036a41306a2216200441f0026a290300370300200141c0036a41286a220c200441e8026a290300370300200141c0036a41206a2214200441e0026a290300370300200141c0036a41186a220e200441d8026a290300370300200141c0036a41106a2217200441d0026a290300370300200141c0036a41086a2218200441c8026a2903003703002001200441c0026a2903003703c00320054103460d012022200141f8036a41bc0210e9081a200141c8006a200141a00f6a41c00210e9081a20014190156a202141bc0210e9081a200141d8146a41306a22192016290300370300200141d8146a41286a221a200c290300370300200141d8146a41206a220c2014290300370300200141d8146a41186a2214200e290300370300200141d8146a41106a220e2017290300370300200141d8146a41086a22172018290300370300200120012903c0033703d81402400240200541024722160d00200141e00c6a4194b4c00041c00210e9081a4100211a200141a80c6a41306a4100290388b740370300200141a80c6a41286a4100290380b740370300200141a80c6a41206a41002903f8b640370300200141a80c6a41186a41002903f0b640370300200141a80c6a41106a41002903e8b640370300200141a80c6a41086a41002903e0b640370300200141002903d8b6403703a80c0c010b201020014190156a41bc0210e9081a20014198126a200141d0176a41c00210e9081a201b2019290300370300201c201a290300370300201d200c290300370300201e2014290300370300201f200e290300370300200f2017290300370300200120012903d8143703e011200141e00c6a20014198126a41c00210e9081a200141a80c6a41306a201b290300370300200141a80c6a41286a201c290300370300200141a80c6a41206a201d290300370300200141a80c6a41186a201e290300370300200141a80c6a41106a201f290300370300200141a80c6a41086a200f290300370300200120012903e0113703a80c2007211a0b20160d02200741016a2107200441f8026a22042006470d000b200621050c060b200441f8026a21050c050b200141f0066a200141e00c6a41c00210e9081a200141b8066a41306a2216200141a80c6a41306a290300370300200141b8066a41286a220c200141a80c6a41286a290300370300200141b8066a41206a2214200141a80c6a41206a290300370300200141b8066a41186a220e200141a80c6a41186a290300370300200141b8066a41106a2217200141a80c6a41106a290300370300200141b8066a41086a2218200141a80c6a41086a290300370300200120012903a80c3703b806200141e8096a200141f0066a41c00210e9081a202c2016290300370300202d200c290300370300202e20142903003703002012200e2903003703002030201729030037030020312018290300370300200120012903b8063703b009200441f8026a2104200741016a21070c000b0b2006200c41b4b3c000104d000b200441f8026a21040b024020062004460d000340200441f8026a21050240200441bc026a2802004102460d000240200441b0026a2802002207450d00200441b4026a280200450d002007102e0b2004108b020b2005210420062005470d000b0b4100212f410821200240202b450d00202b41f8026c450d00202a102e0b4100210d0c010b024020062005460d000340200541f8026a21040240200541bc026a2802004102460d000240200541b0026a2802002207450d00200541b4026a280200450d002007102e0b2005108b020b2004210520062004470d000b0b0240202b450d00202b41f8026c450d00202a102e0b0240024002400240200d41144b0d00200d41014d0d042020200d417f6a22064180036c6a2114410021070340200d20062204417f6a2206490d030240200d20066b22174102490d00202020044180036c6a220441f8026a2d0000202020064180036c6a220541f8026a2d0000220c4f0d00200141d0176a200541f80210e9081a2001200541fc026a28000036004b2001200541f9026a2800003602482005200441800310e9081a024020174103490d002007417f6a210e41002105201421040340200441f8056a2d0000200c4f0d01200e2005460d05200420044180036a221641800310e9081a2016210420072005417f6a2205470d000b201621040b2004200141d0176a41f80210e908220441f8026a200c3a0000200441f9026a2001280248360000200441fc026a200128004b3600000b201441807d6a21142007417f6a210720060d000c050b0b200d410176ad4280037e2202422088a70d052002a7222c417f4c0d05202c102c220f450d04202041807d6a212a202041f8796a212b410421194100211041002117200d211d0340201d21144100211d4101210c02402014417f6a2204450d000240024002400240024002400240202020044180036c6a41f8026a2d000020144180036c220e20206a41f87c6a2d00002205490d002014417e6a2116202b200e6a21064100211d410021040340024020162004470d002014210c0c090b200441016a2104200541ff0171210720062d00002105200641807d6a2106200720054f0d000b200441016a210c2004417f7320146a21040c010b202b200e6a210602400340024020044101470d00410021040c020b2004417f6a2104200541ff0171210720062d00002105200641807d6a210620072005490d000b0b20142004490d012014200d4b0d02201420046b220c4101762207450d00202020044180036c6a2105202a200e6a21060340200141d0176a200541800310e9081a2005200641800310ea084180036a21052006200141d0176a41800310e90841807d6a21062007417f6a22070d000b0b024020040d002004211d0c060b0240200c41094d0d002004211d0c060b2014200d4b0d03200420146b2106202020044180036c6a210e034020142004417f6a221d490d0502402014201d6b220c4102490d00202020044180036c6a220441f8026a2d00002020201d4180036c6a220541f8026a2d000022164f0d00200141d0176a200541f80210e9081a2001200541fc026a28000036004b2001200541f9026a2800003602482005200441800310e9081a0240200c4103490d0041012105200e21040340200441f8056a2d000020164f0d01200620056a4101460d06200420044180036a220741800310e9081a200721042006200541016a22056a0d000b200721040b2004200141d0176a41f80210e908220441f8026a20163a0000200441f9026a2001280248360000200441fc026a200128004b3600000b201d450d06200e41807d6a210e2006417f6a2106201d2104200c410a4f0d060c000b0b2004201441e4d1cc001057000b2014200d41e4d1cc00104d000b2005200c41d4d1cc00103c000b20142004417f6a221d490d002014200d41f4d1cc00104d000b201d201441f4d1cc001057000b024020172010470d00201041016a22042010490d07201041017422052004200520044b1b22044104200441044b1b220441ffffffff01712004464102742105200441037421040240024020100d00200141003602d0170c010b200141043602d817200120193602d017200120104103743602d4170b200141c8006a20042005200141d0176a107d20012802502104024020012802484101470d002004450d080c070b200128024c2119200441037621100b201920174103746a2204200c3602042004201d360200201741016a221e21170240201e4102490d00024002400240034002400240024002402019201e2217417f6a221e4103746a2204280200450d00201741037420196a221641746a2802002207200428020422054d0d00201741024d0d0820192017417d6a22044103746a2802042206200520076a4d0d01201741034d0d08201641646a280200200620076a4b0d080c010b20174103490d012004280204210520192017417d6a22044103746a28020421060b20062005490d010b2017417e6a21040b02402017200441016a221f4d0d00201720044d0d02201920044103746a221a2802042221201a2802006a22042019201f4103746a221b280200221c490d032004200d4b0d04201a41046a21222020201c4180036c6a220e201b28020422184180036c22056a210720044180036c210c024002402004201c6b221620186b22042018490d00200f200e200510e908220420056a21060240024020184101480d00201620184a0d010b200e2105200421040c020b2020200c6a211420042104200e2105034020072004200741f8026a2d0000200441f8026a2d00004922161b210c200420044180036a20161b21042005200c41800310e9084180036a210520074180036a200720161b220720144f0d02200620044b0d000c020b0b200f200720044180036c220510e908221620056a21060240024020184101480d00200441014e0d010b20072105201621040c010b202a200c6a210c200721050340200c200541807d6a2207200641807d6a2214200641786a2d0000200541786a2d00004922041b41800310e908210c2006201420041b21060240200e2007200520041b2205490d00201621040c020b200c41807d6a210c2016210420162006490d000b0b20052004200620046b22062006418003706b10e9081a2022202120186a360200201a201c360200201b201b41086a2017201f417f736a41037410ea081a41012117201e41014d0d050c010b0b201f20174184d2cc00103c000b200420174194d2cc00103c000b201c200441a4d2cc001057000b2004200d41a4d2cc00104d000b201d450d030c000b0b410120056b201741d4d1cc00103c000b2006200d41c4d1cc001056000b0240201041ffffffff0171450d002019102e0b202c418003702104202c418003490d00202c2004460d00200f102e0b2020200d4180036c6a210c02400240200d0d0042002123202021050c010b2008428090bcfd027e202420234280cab5ee0156ad7c7c2124200141c8006a41b0026a2133200141d0176a41c0026a2105200141c8006a41c0026a2106200041016a2134200141ed176a2135200141f8036a4105722136200141c8006a41ca026a2137200141c8006a41cd026a2138200141a00f6a410572212d200141f8036a4103722139200141d0176a41ca026a213a200141d0176a41cd026a213b200141c8006a41046a213c42c0f4a4eb00210220014190156a41306a211c20014190156a41286a211d20014190156a41206a211e20014190156a41186a211f20014190156a41106a212120014190156a41086a2122200141890a6a223d41076a213e410021174200212320202104024003402004280200213f20014198126a200441046a41c00210e9081a200441c4026a2802002107201c200441f8026a290300370300201d200441f0026a290300370300201e200441e8026a290300370300201f200441e0026a2903003703002021200441d8026a2903003703002022200441d0026a2903003703002001200441c8026a29030037039015024020074102470d0020044180036a21050c030b200141c8006a20014198126a41c00210e9081a200141d0176a203c41bc0210e9081a2005200129039015370300200541086a220d2022290300370300200541106a220f2021290300370300200541186a2210201f290300370300200541206a222a201e290300370300200541286a222b201d290300370300200541306a222c201c2903003703002001200736028c1a200141a00f6a200141d0176a10970420012903a00f2108024002400240024020012d00981a0e03000102000b4102210e02400240024020012d00991a0e03000102000b4100210e0c010b200141f8036a41186a203a41186a290000370300200141f8036a41106a203a41106a290000370300200141f8036a41086a203a41086a2900003703002001203a29000022253703f8032025a721404101210e0b200141a00f6a41026a203941026a2d00003a0000200120392f00003b01a00f201b4180807c7120012f01960472211b20012d00fa03211820012801fe032119200128018204211a200128018604212e200128018a042112200128018e042130200128019204213141002132410121160c020b41022118024002400240024020012d009c1a0e03000103000b410021180c010b200141f8036a41026a203b41026a2d00003a00002001203b2f00003b01f803204141807e7120012d00bc1a7221414101211820012802b81a214220012802b41a214320012802b01a214420012802ac1a214520012802a81a21460b20012802a41a211a20012802a01a21190b200141a00f6a41026a200141f8036a41026a2d00003a0000200120012f01f8033b01a00f41012132410021162046212e204521122044213020432131204121472042211b0c010b4102213241022118024002400240024020012d009c1a0e03000103000b410021180c010b200141f8036a41026a203b41026a2d00003a00002001203b2f00003b01f803202941807e7120012d00bc1a7221294101211820012802b81a212620012802b41a212720012802b01a212820012802ac1a211320012802a81a21150b20012802a41a211a20012802a01a21190b200141a00f6a41026a200141f8036a41026a2d00003a0000200120012f01f8033b01a00f410021162015212e201321122028213020272131202921472026211b0b4110102c2207450d03200741f8f7c60036020c200741013602082007428180808010370200200141e8096a41026a2248200141a00f6a41026a2d00003a0000200120012f01a00f3b01e809024002402016200e41ff01714571450d00200721160c010b4110102c2216450d0420164190f8c60036020c20164101360208201642818080801037020020072007280200417f6a224936020020490d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22492049280200417f6a224936020020490d002007102e0b200141f8036a41026a224920482d000022073a0000200120012f01e80922483b01f803202d20483b0000202d41026a20073a0000200120183a00a40f200120403b01a20f2001200e3a00a10f200120323a00a00f200120163602c80f200120473602c40f2001201b3602c00f200120313602bc0f200120303602b80f200120123602b40f2001202e3602b00f2001201a3602ac0f200120193602a80f200141e8096a200141a00f6a10c10220012d00e8092116200128028c1a210720012802801a2118200141e00c6a200141d0176a41bc0210e9081a200141f0066a41306a2219202c290300370300200141f0066a41286a221a202b290300370300200141f0066a41206a222e202a290300370300200141f0066a41186a22122010290300370300200141f0066a41106a2230200f290300370300200141f0066a41086a2231200d290300370300200120052903003703f00620074102460d01427f427f427f200220087c220820082002541b2202427f200242c0b2cd3b7c220820082002541b20161b22024280c2d72f7c220820082002541b200220181b220242c0b2cd3b7c220820082002541b200220074101461b2102200141c8006a200141e00c6a41bc0210e9081a200641306a22162019290300370300200620012903f006370300200641086a22182031290300370300200641106a22192030290300370300200641186a22302012290300370300200641206a2212202e290300370300200641286a222e201a290300370300200120073602840302400240024020012d00b80341c000490d002017450d0020022024560d010b200141a00f6a200141c8006a10a804024002400240024020012d0090030e03000102000b4102214a02400240024020012d0091030e03000102000b4100214a0c010b200141f8036a41186a203741186a290000370300200141f8036a41106a203741106a290000370300200141f8036a41086a203741086a2900003703002001203729000022083703f8032008a7214b4101214a0b200141d0176a41026a203941026a2d00003a0000200120392f00003b01d017204c4180807c7120012f01960472214c20012d00fa03211820012801fe032119200128018204211a200128018604210f200128018a042110200128018e04212a200128019204212b4100212c410121160c020b41022118024002400240024020012d0094030e03000103000b410021180c010b2049203841026a2d00003a0000200120382f00003b01f803204141807e7120012d00b4037221414101211820012802b003214220012802ac03214320012802a803214420012802a403214520012802a00321460b200128029c03211a20012802980321190b200141d0176a41026a20492d00003a0000200120012f01f8033b01d0174101212c410021162046210f204521102044212a2043212b2041214d2042214c0c010b4102212c41022118024002400240024020012d0094030e03000103000b410021180c010b2049203841026a2d00003a0000200120382f00003b01f803202941807e7120012d00b4037221294101211820012802b003212620012802ac03212720012802a803212820012802a403211320012802a00321150b200128029c03211a20012802980321190b200141d0176a41026a200141f8036a41026a2d00003a0000200120012f01f8033b01d017410021162015210f201321102028212a2027212b2029214d2026214c0b200141d8146a41026a222e200141d0176a41026a2d00003a0000200120012f01d0173b01d8144110102c2207450d05200741f8f7c60036020c200741013602082007428180808010370200200741086a210d024002402016204a41ff01714571450d00200d2112200721160c010b4110102c2216450d0620164190f8c60036020c20164101360208201642818080801037020020072007280200417f6a2230360200201641086a211220300d002007280208200728020c2802001103000240200728020c280204450d00200d280200102e0b200741046a220d200d280200417f6a220d360200200d0d002007102e0b024002402016280208200141a00f6a201628020c28020c1101000d0020162016280200417f6a2207360200200141023a00880a200141003a00800a200142003703f009200142013703e809024020070d002012280200201628020c2802001103000240201628020c280204450d002016280208102e0b201641046a22072007280200417f6a220736020020070d002016102e0b200141a00f6a10dc020c010b200141d0176a200141a00f6a41b00210e9081a203620012f01d8143b0000203641026a202e2d00003a0000200120183a00fc032001204b3b01fa032001204a3a00f9032001202c3a00f803200120163602a0042001204d36029c042001204c360298042001202b360294042001202a360290042001201036028c042001200f360288042001201a360284042001201936028004200141e8096a200141d0176a200141f8036a10dd020b0240024020012802f80222160d00410021070c010b2001280280032214417f4c0d070240024020140d00410121070c010b2014102c2207450d070b20072016201410e9081a0b024002402001280284034101460d004101211820012802f802450d01200141d0176a203310a90420012802d017221620012802d81710ff0120012802d417450d012016102e0c010b200128028803211602400240200128028c0322184102490d00200141013602840320012018417f6a36028c030c010b20014100360284030b201620006a2116024020012802f802450d00200141d0176a201610a70420012802d817211920012802d0172118200141f8036a41046a41003a0000200141003602f803200141086a20182019200141f8036a4105410010ca04024002402001280208450d002001200128020c2219410520194105491b3602a40f2001200141f8036a3602a00f2001200141a00f6a10ab0120012802042119200128020045211a0c010b4100211a0b024020012802d417450d002018102e0b200141d0176a203310a90420012802d017221820012802d817201620194100201a1b10e50420012802d417450d002018102e0b200141d0176a200141c8006a41f80210e9081a2016200141d0176a10aa04410021180b2001203d2900003703d0172001203e2800003600d7170240024020012903e8094201510d00410621160c010b20012d00880a211920012903f0092108200120012800d7173600a70f200120012903d0173703a00f4106211620084202510d00200120012800a70f3600d717200120012903a00f3703d017201921160b200120012903d0173703f803200120012800d7173600ff03203520012903f803370000203541076a20012800ff03360000200120163a00ec17200120143602e817200120143602e417200120073602e0172001203f3602dc17200120003602d817200141023602d417200141013a00d017200141d0176a10fe0102402018450d00024020012802f8022207450d0020012802fc02450d002007102e0b200141c8006a108b020b200221230c010b200141a00f6a200141c8006a41bc0210e9081a200141e8096a41306a221a2016290300370300200141e8096a41286a2216202e290300370300200141e8096a41206a222e2012290300370300200141e8096a41186a22122030290300370300200141e8096a41106a22302019290300370300200141e8096a41086a22192018290300370300200120062903003703e80920074103460d00200141d0176a200141a00f6a41bc0210e9081a200520012903e809370300200d2019290300370300200f203029030037030020102012290300370300202a202e290300370300202b2016290300370300202c201a2903003703002001200736028c1a2034200141d0176a10aa040b2017417f6a211720044180036a2204200c470d000b200c21050c010b20044180036a21050b0240200c2005460d000340200522044180036a21050240200441b8026a2802002206450d00200441bc026a280200450d002006102e0b200441086a108b02200c2005470d000b0b0240202f450d00202f4180036c450d002020102e0b200141c8006a41186a22044200370300200141c8006a41106a22054200370300200141c8006a41086a2206420037030020014200370348200141d0176a41d9fcc60041061081022006200141d0176a41086a2207290000370300200120012900d017370348200141d0176a41a0f4cb00410a10810220042007290000370300200520012900d017370300200141d0176a200141c8006a4120108d0220012d00d0172107200141f8036a41186a2216200141e9176a290000370300200141f8036a41106a220c200141e1176a290000370300200141f8036a41086a2214200141d9176a290000370300200120012900d1173703f8030240024020074101460d00200442003703002005420037030020064200370300200142003703480c010b200420162903003703002005200c29030037030020062014290300370300200120012903f8033703480b200141d0176a41186a22054200370300200141d0176a41106a22074200370300200141d0176a41086a22064200370300200142003703d01720014198126a41f4c2cc004118108102200620014198126a41086a220429000037030020012001290098123703d01720014198126a41e4c3cc00410e108102200520042900003703002007200129009812370300200141a00f6a200141d0176a4120108d03024002400240024002400240024020012802a00f22040d002005200141c8006a41186a2903003703002007200141c8006a41106a2903003703002006200141c8006a41086a290300370300200120012903483703d0174100210641012104200141d0176a21160c010b20012802a40f2106200141a00f6a41086a280200220541d0004b0d03200141d0176a41186a200141c8006a41186a290300370300200141d0176a41106a200141c8006a41106a290300370300200141d0176a41086a200141c8006a41086a290300370300200120012903483703d017024020052006472214450d00200141d0176a21162006210c0c020b200141d0176a21162006210c20140d010b200641016a22052006490d062006410174220c2005200c20054b1b22054104200541044b1b220541ffffff3f71200546210c200541057421050240024020060d0020014100360298120c010b200141a0126a410136020020012004360298122001200641057436029c120b200141a00f6a2005200c20014198126a107d200141a80f6a280200210520012802a00f4101460d0120012802a40f21042005410576210c200621050b200420054105746a22062016290000370000200641186a201641186a290000370000200641106a201641106a290000370000200641086a201641086a290000370000200541016a21050c020b2005450d040c030b200141d0176a41186a220c200141c8006a41186a290300370300200141d0176a41106a2214200141c8006a41106a290300370300200141d0176a41086a220e200141c8006a41086a290300370300200120012903483703d01720052000417f6a41d1007022164d0d01200420164105746a221620012903d017370000201641186a200c290300370000201641106a2014290300370000201641086a200e2903003700002006210c0b200141a00f6a41086a20053602002001200c3602a40f200120043602a00f0240024020040d00200141d0176a41186a4200370300200141e0176a4200370300200141d0176a41086a22044200370300200142003703d01720014198126a41f4c2cc004118108102200420014198126a41086a220529000037030020012001290098123703d01720014198126a41e4c3cc00410e108102200741086a20052900003700002007200129009812370000200141d0176a412010ff010c010b200141d0176a41186a4200370300200141e0176a4200370300200141d0176a41086a22054200370300200142003703d01720014198126a41f4c2cc004118108102200520014198126a41086a220629000037030020012001290098123703d01720014198126a41e4c3cc00410e108102200741086a20062900003700002007200129009812370000200141d0176a200141a00f6a10e6042004450d00200c41ffffff3f71450d002004102e0b200141d01a6a2400427f2003427f20234290f796027c220220022023541b7c220220022003541b0f0b2016200541b4cccc00103c000b1036000b1038000bf50101047f230041306b22022400200241b6d1cc004106108102200241106a41bcd1cc004107108102024002404114102c2203450d002002421437022420022003360220200241206a20014114107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bdf0b04027f027e037f077e230041a0026b22032400200341e0006a200110e202200341c8006a20032802602204200328026810f802200341d8006a2903002105200329035021062003280248210702402003280264450d002004102e0b0240024002402007450d00200341f8006a22044200370300200341e0006a41106a22074200370300200341e0006a41086a2208420037030020034200370360200341e0016a41b6d1cc0041061081022008200341e0016a41086a2209290000370300200320032900e001370360200341e0016a41e9f9c000410510810220042009290000370300200720032900e001370300200341306a200341e0006a412010f80220032903384200200328023022081b220a20067d220b200a56200341306a41106a290300420020081b220c20057d200a200654ad7d220a200c56200a200c511b0d01200341e0016a200110ad03200341e0006a20032802e001220820032802e80110ae03200341e0006a41206a290300210d2004290300210e2007290300210f20034188016a2802002104200329036821102003290360210c024020032802e401450d002008102e0b02400240200c4201520d00200341e0016a200210af03024020032903e0014201520d00200341f8006a22014200370300200341f0006a22074200370300200341e0006a41086a420037030020034200370360200341e0006a41d9fcc600410610810220034190026a4180f4cb004106108102200120034190026a41086a2900003703002007200329009002370300200341086a200341e0006a4120108e0220034190026a200210c802200341e0006a200328029002220120032802980210c9020240200328029402450d002001102e0b2000410610b0030c050b200341106a20022006200510fd012003200341186a290300370368200320032903103703602003200341e0006a3602e001200341e0016a10ce022010200f84500d01200341e0006a200210b103200328026022092003280268108f02210802402003280264450d002009102e0b024020080d00200341e0006a41186a2208200d3703002003200e3703702003201037036020032004360280012003200f3703682002200341e0006a10b2032008200241186a290000370300200341e0006a41106a200241106a290000370300200341e0006a41086a200241086a29000037030020032002290000370360200341e0016a200341e0006a10b3030c020b200341e8006a411736020020034194a4c700360264200341013a006220034183323b016041eef9c0004137200341e0006a41a8fac00041b8fac000103e000b200341206a20022006200510fd012003200341286a290300370368200320032903203703602003200341e0006a3602e001200341e0016a10ce020b200341f8006a4200370300200341e0006a41106a4200370300200341e0006a41086a2204420037030020034200370360200341e0016a41b6d1cc0041061081022004200341e0016a41086a2208290000370300200320032900e001370360200341e0016a41e9f9c0004105108102200741086a2008290000370000200720032900e0013700002003200a3703e8012003200b3703e001200341e0006a4120200341e0016a411010b201200341e0006a200110e20220032802602207200328026810ff0102402003280264450d002007102e0b200341e0006a200110ad0320032802602207200328026810ff0102402003280264450d002007102e0b200341e0006a200110ab0320032802602207200328026810ff0102402003280264450d002007102e0b200341e0006a41106a2005370300200341e0006a41086a2006370300200341e0006a41186a200229000037030020034180016a200241086a29000037030020034188016a200241106a29000037030020034190016a200241186a29000037030020034198016a2001290000370300200341a0016a200141086a290000370300200341a8016a200141106a2800003602002003410f3a0060200341e0006a10fe01200041063a00000c020b2000410210b0030c010b2000410410b0030b200341a0026a24000bf50101047f230041306b22022400200241b6d1cc004106108102200241106a41bcdbc8004107108102024002404114102c2203450d002002421437022420022003360220200241206a20014114107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bd80202027f017e230041d0006b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822010d00200042003703000c010b200328020c2102024002400240200341106a28020022044110490d0020044170714110460d002004417c714120470d010b20034100360220200342013703182003410a36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341909dc5003602382003200341286a360248200341346a419cebc000200341386a103d1a2003280218200328022010ef020240200328021c450d002003280218102e0b420021050c010b200041186a200129001037030020002001290000370308200041286a2001280020360200200041206a200141186a290000370300200041106a200141086a290000370300420121050b200020053703002002450d002001102e0b200341d0006a24000b940304027f017e027f047e230041e0006b220224002002200110b1032002280200210120022002280208220336021420022001360210200241186a2001200310ed0202400240200228021822030d00420021040c010b200228021c2105024002400240200241206a28020022064110490d0020064170714110460d002006417c714120470d010b20024100360230200242013703282002410a36023c2002200241106a3602382002200241286a360244200241dc006a41013602002002420137024c200241909dc5003602482002200241386a360258200241c4006a419cebc000200241c8006a103d1a2002280228200228023010ef020240200228022c450d002002280228102e0b420021040c010b200341186a2900002107200341086a2900002108200329001021092003290000210a20032800202106420121040b2005450d002003102e0b200041206a2007370300200041186a2009370300200041106a20083703002000200a370308200041286a20063602002000200437030002402002280204450d002001102e0b200241e0006a24000b860201047f230041c0006b2202240041c4f6c000210341132104410521050240024002400240024002400240200141ff01710e0700010203040506000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a41d0c1cc001044000b41c0f5c000210341182104410021050c040b41e0f5c000210341102104410121050c030b41f8f5c000210341102104410221050c020b4190f6c0002103410c2104410321050c010b41acf6c000210341102104410421050b20004183303b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000bac0201037f230041e0006b22022400200241bcdbc8004107108102200241106a41bcdbc8004107108102024002404120102c2203450d002002422037023420022003360230200241306a200141201074200241c0006a200228023022012002280238220310d803200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c0006a360250200241206a200241d0006a107c02402002280234450d002001102e0b2002280228220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b20004100360208200020013602042000200436020020002002411010742000200241106a411010742000200228022022012003107402402002280224450d002001102e0b200241e0006a24000f0b1036000b1038000be40104017f027e017f027e230041306b22022400200141186a2903002103200141086a29030021042001280220210520012903102106200129030021072002200010b103200228020821002002280200210120024100360218200242013703102002200437032820022007370320200241106a200241206a411010742002200337032820022006370320200241106a200241206a4110107420022005360220200241106a200241206a410410742001200020022802102205200228021810b20102402002280214450d002005102e0b02402002280204450d002001102e0b200241306a24000bc00807027f017e017f027e017f027e067f230041c0016b22022400200241c0006a200110af03024002400240024020022903404201520d00200241d0006a22032903002104200241d8006a22052903002106200241c0006a41206a2903002107200241e8006a2802002108200229034821092005420037030020034200370300200241c0006a41086a420037030020024200370340200241c0006a41d9fcc6004106108102200241306a4180f4cb0041061081022005200241306a41086a29000037030020032002290030370300200241286a200241c0006a4120108e02200241086a200742004100200228022c410020022802281b220320086b2205200520034b1bad220a420010e808200241186a200a42002006420010e80802402002290310420052200241186a41086a290300220720022903087c2206200754720d0020092002290318220756200420065620042006511b0d020b200242f6cacda397cddbb320370330200241c0006a200110d4062002280248210b2002410036024802400240200b0d004100210c2002280240210d0c010b2002280240220d41106a210e4100210f4100210c410021080240034002400240200c450d00200d20084105746a2103200d2008200f6a4105746a21050340200341106a22102900002002290330510d0220052003290300370300200541186a200341186a290300370300200541106a2010290300370300200541086a200341086a290300370300200541206a2105200341206a2103200b200841016a22084b0d000c040b0b200e20084105746a2103034020032900002002290330510d01200341206a2103200b200841016a22084b0d000b4100210c0c030b200f417f6a210f200c41016a210c200b200841016a22084b0d000b0b0240200c0d004100210c0c010b200d2008200c6b4105746a200d20084105746a200b20086b41057410ea081a0b2002200b200c6b22033602482001200d200310d5060240200228024441ffffff3f71450d00200d102e0b200241c0006a200110b10320022802402203200228024810ff0102402002280244450d002003102e0b200241c0006a41086a41013a0000200241c9006a2001290000370000200241d1006a200141086a290000370000200241e1006a200141186a290000370000200241103a0040200241d9006a200141106a290000370000200241c0006a10fe010c020b2000410110d6060c020b42f6cacda397cddbb32020014200200920077d220a200a200956200420067d2009200754ad7d220620045620062004511b22031b22044200200620031b22064106108506200241f8006a2006370300200241f0006a2004370300200241c0006a41086a41003a0000200241c9006a2001290000370000200241d1006a200141086a290000370000200241e1006a200141186a290000370000200241103a0040200241d9006a200141106a290000370000200241c0006a10fe010b200041063a00000b200241c0016a24000b13002000410a360204200041c4ffc0003602000b340020004190fec60036020420004100360200200041146a4102360200200041106a4188b2c100360200200041086a42053702000b130020004106360204200041d8b6c1003602000b4201027f230041106b2202240002404104102c22030d001036000b20004204370204200020033602002002412036020c20002002410c6a41041074200241106a24000b4201027f230041106b2202240002404102102c22030d001036000b2000420237020420002003360200200241203b010e20002002410e6a41021074200241106a24000b4a01027f230041106b2202240002404110102c22030d001036000b20004210370204200020033602002002420037030820024280cdad9d013703002000200241101074200241106a24000b4b01027f230041106b2202240002404110102c22030d001036000b2000421037020420002003360200200242003703082002428088caade9053703002000200241101074200241106a24000be22505027f017e027f017e037f230041b0046b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c0102030405060708090a0b0c0d0e0f101112131415161718191a1b00010b200241086a200141386a10ca0120024180026a41286a200141306a29030037030020024180026a41206a200141286a29030037030020024180026a41186a200141206a29030037030020024180026a41106a200141186a29030037030020024180026a41086a200141106a2903003703002002200141086a29030037038002200141f8016a280200210320024180026a41306a200241086a41c00110e9081a20014180026a2903002104200241086a20024180026a41f00110e9081a200041086a200241086a41f00110e9081a20004180026a2004370300200041f8016a20033602002000411b3602000c1b0b20024180026a200141086a10cb0120004100360200200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c1a0b20024180026a200141046a10cc0120004101360200200041246a200241a0026a2802003602002000411c6a20024198026a290300370200200041146a20024190026a2903003702002000410c6a20024188026a29030037020020002002290380023702040c190b20024180026a200141086a10cd01200041086a20024180026a41a00210e9081a200041023602000c180b20004103360200200041086a200141086a2903003703000c170b41042103200141046a210502400240024002400240024002400240024020012d0004417f6a0e050102030405000b41e2a0cc00412841e89bc4001039000b200141086a2802002105410121030c040b41022103200241086a41026a200541036a2d00003a000020024180026a41086a200141146a29020037030020024190026a2001411c6a29020037030020024198026a200141246a2d00003a0000200220052f00013b010820022001410c6a29020037038002200141086a2802002105200141286a28020021010c040b200141086a2802002105410321030c020b2002410a6a200541036a2d00003a000020024180026a41086a200141146a29020037030020024190026a2001411c6a29020037030020024198026a200141246a2d00003a0000200220052f00013b010820022001410c6a2902003703800220012d00254100472106200141086a2802002105200141286a28020021010c030b200141086a2802002105410521030b0b0b200020033a0004200020022f01083b0005200020063a0025200020022f01fc013b0126200041086a20053602002000410c6a200229038002370200200041286a2001360200200041076a2002410a6a2d00003a0000200041146a20024180026a41086a2903003702002000411c6a20024190026a290300370200200041246a20024198026a2d00003a0000200041043602000c160b20024180026a200141086a10ce01200041086a20024180026a41e00010e9081a200041053602000c150b20024180026a200141046a10cf01200041063602002000410c6a20024188026a28020036020020002002290380023702040c140b20024180026a200141086a10d001200041086a20024180026a41d80010e9081a200041073602000c130b10d101000b02400240200128020422050d00410021030c010b20024180026a41186a200141286a29000037030020024180026a41106a200141206a29000037030020024188026a200141186a29000037030020024180026a41286a200141386a29000037030020024180026a41306a200141c0006a29000037030020024180026a41386a200141c8006a29000037030020024180026a41c8006a200141d8006a29000037030020024180026a41d0006a200141e0006a29000037030020024180026a41d8006a200141e8006a2900003703002002200141106a290000370380022002200141306a2900003703a0022002200141d0006a2900003703c00220024180026a41f8006a20014188016a29000037030020024180026a41f0006a20014180016a29000037030020024180026a41e8006a200141f8006a29000037030020024180026a4198016a200141a8016a29000037030020024180026a4190016a200141a0016a29000037030020024180026a4188016a20014198016a29000037030020024180026a41b8016a200141c8016a29000037030020024180026a41b0016a200141c0016a29000037030020024180026a41a8016a200141b8016a2900003703002002200141f0006a2900003703e002200220014190016a290000370380032002200141b0016a2900003703a0032001410c6a2802002201417f4c0d130240024020010d00410121030c010b2001102c2203450d150b20032005200110e9081a200241086a20024180026a41c00110e9081a0b200020033602042000410c6a2001360200200041086a2001360200200041106a200241086a41c00110e9081a200041093602000c110b20024180026a200141086a10d201200041086a20024180026a41980210e9081a2000410a3602000c100b20024180026a200141046a10d301200041046a20024180026a41e80010e9081a2000410b3602000c0f0b10d401000b20024180026a200141086a10d5012000410d360200200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0d0b20024180026a200141086a10d6012000410e360200200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0c0b20024180026a200141086a10d6012000410f360200200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0b0b20024180026a200141086a10d70120004110360200200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0a0b200141046a2103410721050240024002400240024002400240024020012d0004417f6a0e0701020304050607000b41e2a0cc00412841a4c3cb001039000b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410121050c050b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410221050c040b20024180026a41186a200341196a29000037030020024180026a41106a200341116a29000037030020024180026a41086a200341096a290000370300200241086a41086a200341296a290000370300200241086a41106a200341316a290000370300200241086a41186a200341396a29000037030020022003290001370380022002200341216a290000370308410321050c030b200241086a200141086a10c8012002418b026a200241086a41086a2802003600002002200229030837008302410421050c020b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410521050c010b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410621050b200020053a0004200020022903800237000520002002290308370025200020022f00fc013b00452000410d6a20024180026a41086a290300370000200041156a20024180026a41106a2903003700002000411d6a20024180026a41186a2903003700002000412d6a200241086a41086a290300370000200041356a200241086a41106a2903003700002000413d6a200241086a41186a290300370000200041c7006a200241fe016a2d00003a0000200041113602000c090b024002400240024002400240200141086a280200417f6a0e03010203000b41e2a0cc0041284184ccc2001039000b200141386a2903002104200141306a29030021074101210841012109024002400240024002402001410c6a2d00000e050104020300010b4104210920024180026a41046a200141206a2d00003a000020022001411c6a2800003602800220012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a28020021050c030b20024188026a200141246a29000037030020024180026a41106a2001412c6a2d00003a000020022001411c6a2900003703800220012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a2802002105410021090c020b200141186a2802002203417f4c0d0f200141106a28020021010240024020030d00410121050c010b2003102c2205450d110b20052001200310e9081a410221092003210a0c010b20024188026a200141246a29000037030020024180026a41106a2001412c6a2d00003a000020022001411c6a2900003703800220012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a2802002105410321090b200241086a41106a20024180026a41106a2d00003a0000200241086a41086a20024180026a41086a290300370300200241046a41026a200241fc016a41026a2d00003a00002002200229038002370308200220022f00fc013b01040c030b2001410c6a28020022094108762106410221080c010b2001410c6a28020022094108762106410321080b0b200020022f01043b002d20004112360200200041386a2004370300200041306a2007370300200041186a200a360200200041146a2003360200200041106a2005360200200041086a20083602002000411c6a20022903083702002000410c6a2006410874200941ff017172360200200041246a200241086a41086a2903003702002000412c6a200241086a41106a2d00003a00002000412f6a200241066a2d00003a00000c080b20024180026a200141086a10d801200041086a20024180026a41f00010e9081a200041133602000c070b20024180026a200141086a10d901200041086a20024180026a41f80010e9081a200041143602000c060b024002400240024020012f0104417f6a0e03010200010b20024180026a200141086a10c90120022902840221042002280280022103410321010c020b20024180026a200141086a10c90120022902840221042002280280022103410121010c010b20012f0106210541b002102c2203450d0820024180026a200141086a28020010da01200320024180026a41b00210e9081a410221010b200020013b0104200041153602002000410c6a2004370200200041086a2003360200200041066a20053b01000c050b20024180026a200141086a10db01200041086a20024180026a41a80210e9081a200041163602000c040b20024180026a200141046a10dc01200041046a20024180026a41c80010e9081a200041173602000c030b20024180026a200141086a10dd01200041086a20024180026a41c80010e9081a200041183602000c020b20024180026a200141086a10de0120004119360200200041c0006a20024180026a41386a290300370300200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c010b20024180026a200141086a10df012000411a360200200041c0006a20024180026a41386a290300370300200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000b200241b0046a24000f0b1038000b1036000bec3703057f047e047f230041900c6b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020020060e0a0102030405060708090a0b0b2000410b3a00000c130b41002104200241003a0080040240024002400340200128020022032802042205450d01200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a290300220737030020024190016a41086a2203200241e0036a41086a29030037030020024190016a41106a2204200241e0036a41106a29030037030020024190016a41186a22052007370300200220022903e00337039001200241f0006a41186a2005290300370300200241f0006a41106a2004290300370300200241f0006a41086a20032903003703002002200229039001370370200128020022032802042204450d12200328020022052d0000210620032004417f6a3602042003200541016a3602004107210320060e020201120b0240200441ff0171450d00200241003a0080040b2000410b3a00000c140b200128020022032802042204450d10200328020022052d0000210620032004417f6a3602042003200541016a360200410021030240024002400240024020060e0705040001150203150b410221030c040b410321030c030b410521030c020b410621030c010b410121030b2001200128020441016a22043602040240200420012802084b0d00200241e0036a200110950120022802e0032104200241b0016a200241e0036a41047241ac0210e9081a2004411c460d00200241e0036a200241b0016a41ac0210e9081a41b002102c2205450d1220052004360200200541046a200241e0036a41ac0210e9081a200241d0006a41186a200241f0006a41186a2903002207370300200241d0006a41106a200241f0006a41106a2903002208370300200241d0006a41086a200241f0006a41086a290300220937030020012001280204417f6a36020420022002290370220a370350200041013a00002000200a370001200041096a2009370000200041116a2008370000200041196a2007370000200041246a2005360200200041216a20033a0000200041286a2002290230370200200041306a200241306a41086a290200370200200041386a200241306a41106a290200370200200041c0006a200241306a41186a2902003702000c130b2000410b3a00000c120b41002104200241003a0080040240024002400240024002400240024002400340200128020022032802042205450d01200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a290300220737030020024190016a41086a2203200241e0036a41086a29030037030020024190016a41106a2204200241e0036a41106a29030037030020024190016a41186a22052007370300200220022903e00337039001200241f0006a41186a2005290300370300200241f0006a41106a2004290300370300200241f0006a41086a20032903003703002002200229039001370370200128020022032802042204450d07200328020022052d0000210620032004417f6a3602042003200541016a3602004100210320060e0706050102070304070b0240200441ff0171450d00200241003a0080040b2000410b3a00000c190b410221030c040b410321030c030b410521030c020b410621030c010b410121030b2001280200220128020422044104490d0120012802002205280000210620012004417c6a3602042001200541046a360200200241d0006a41086a200241f0006a41086a2903002207370300200241d0006a41106a200241f0006a41106a2903002208370300200241d0006a41186a200241f0006a41186a290300220937030020022002290370220a370350200041023a00002000200a370001200041096a2007370000200041116a2008370000200041196a2009370000200041246a2006360200200041216a20033a0000200041286a2002290230370200200041306a200241306a41086a290200370200200041386a200241306a41106a290200370200200041c0006a200241306a41186a2902003702000c130b2000410b3a00000c120b2000410b3a00000c110b41002104200241003a0080040240024002400240024002400240024002400340200128020022032802042205450d01200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a290300220737030020024190016a41086a2203200241e0036a41086a29030037030020024190016a41106a2204200241e0036a41106a29030037030020024190016a41186a22052007370300200220022903e00337039001200241f0006a41186a2005290300370300200241f0006a41106a2004290300370300200241f0006a41086a20032903003703002002200229039001370370200128020022032802042204450d07200328020022052d0000210620032004417f6a3602042003200541016a3602004100210320060e0706050102070304070b0240200441ff0171450d00200241003a0080040b2000410b3a00000c180b410221030c040b410321030c030b410521030c020b410621030c010b410121030b2001280200220128020422044104490d0120012802002205280000210620012004417c6a3602042001200541046a360200200241d0006a41086a200241f0006a41086a2903002207370300200241d0006a41106a200241f0006a41106a2903002208370300200241d0006a41186a200241f0006a41186a290300220937030020022002290370220a370350200041033a00002000200a370001200041096a2007370000200041116a2008370000200041196a2009370000200041246a2006360200200041216a20033a0000200041286a2002290230370200200041306a200241306a41086a290200370200200041386a200241306a41106a290200370200200041c0006a200241306a41186a2902003702000c120b2000410b3a00000c110b2000410b3a00000c100b200041043a00000c0f0b200128020022032802042204450d0c200328020022052d0000210620032004417f6a3602042003200541016a3602004100210402400240024002400240024020060e0705000102120304120b410121040c040b410221040c030b410321040c020b410521040c010b410621040b024002402001280200220328020422054104490d0020032802002206280000210b20032005417c6a3602042003200641046a3602002001280200220128020422034102490d01200128020022052f0000210620012003417e6a3602042001200541026a360200200041046a200b360200200041026a20063b0100200020043a0001200041053a0000200041086a20022902e003370200200041106a200241e0036a41086a290200370200200041186a200241e0036a41106a290200370200200041206a200241e0036a41186a290200370200200041286a200241e0036a41206a290200370200200041306a200241e0036a41286a290200370200200041386a200241e0036a41306a290200370200200041c0006a200241e0036a41386a2902003702000c100b2000410b3a00000c0f0b2000410b3a00000c0e0b41002104200241003a008004024002400240024002400240024002400240024002400340200128020022032802042205450d01200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a290300220737030020024190016a41086a2203200241e0036a41086a29030037030020024190016a41106a2204200241e0036a41106a29030037030020024190016a41186a22052007370300200220022903e00337039001200241f0006a41186a2005290300370300200241f0006a41106a2004290300370300200241f0006a41086a20032903003703002002200229039001370370200128020022032802042204450d07200328020022052d0000210620032004417f6a3602042003200541016a3602004100210420060e0706050102070304070b0240200441ff0171450d00200241003a0080040b2000410b3a00000c170b410221040c040b410321040c030b410521040c020b410621040c010b410121040b2001280200220328020422054102490d01200328020022062f0000210b20032005417e6a3602042003200641026a360200200241086a200110ad0120022802080d02200228020c21032002200110ad0120022802000d0320022802042101200241d0006a41186a200241f0006a41186a2903002207370300200241d0006a41106a200241f0006a41106a2903002208370300200241d0006a41086a200241f0006a41086a290300220937030020022002290370220a370350200041063a00002000200a370001200041096a2009370000200041116a2008370000200041196a2007370000200041286a2001360200200041246a2003360200200041226a200b3b0100200041216a20043a00002000412c6a2002290230370200200041346a200241306a41086a2902003702002000413c6a200241306a41106a290200370200200041c4006a200241306a41186a2802003602000c110b2000410b3a00000c100b2000410b3a00000c0f0b2000410b3a00000c0e0b2000410b3a00000c0d0b41002104200241003a008004024002400340200128020022032802042205450d01200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a290300220737030020024190016a41086a2203200241e0036a41086a29030037030020024190016a41106a2204200241e0036a41106a29030037030020024190016a41186a22052007370300200220022903e00337039001200241f0006a41186a2005290300370300200241f0006a41106a2004290300370300200241f0006a41086a2003290300370300200220022903900137037041002104200241003a0080040340200128020022032802042205450d02200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a2903002207370300200241306a41086a2201200241e0036a41086a290300370300200241306a41106a2203200241e0036a41106a290300370300200241306a41186a22042007370300200220022903e003370330200241d0006a41186a2205200241f0006a41186a290300370300200241d0006a41106a2206200241f0006a41106a290300370300200241d0006a41086a220b200241f0006a41086a29030037030020022002290370370350200041073a000020002002290350370001200041096a200b290300370000200041116a2006290300370000200041196a2005290300370000200041216a2002290330370000200041296a2001290300370000200041316a2003290300370000200041396a2004290300370000200041c1006a2002280010360000200041c4006a200241136a2800003600000c0e0b0240200441ff0171450d00200241003a0080040b2000410b3a00000c0d0b0240200441ff0171450d00200241003a0080040b2000410b3a00000c0c0b41002104200241003a008004024002400340200128020022032802042205450d01200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a290300220737030020024190016a41086a2203200241e0036a41086a29030037030020024190016a41106a2204200241e0036a41106a29030037030020024190016a41186a22052007370300200220022903e00337039001200241f0006a41186a2005290300370300200241f0006a41106a2004290300370300200241f0006a41086a2003290300370300200220022903900137037041002104200241003a0080040340200128020022032802042205450d02200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a2903002207370300200241306a41086a2201200241e0036a41086a290300370300200241306a41106a2203200241e0036a41106a290300370300200241306a41186a22042007370300200220022903e003370330200241d0006a41186a2205200241f0006a41186a290300370300200241d0006a41106a2206200241f0006a41106a290300370300200241d0006a41086a220b200241f0006a41086a29030037030020022002290370370350200041083a000020002002290350370001200041096a200b290300370000200041116a2006290300370000200041196a2005290300370000200041216a2002290330370000200041296a2001290300370000200041316a2003290300370000200041396a2004290300370000200041c1006a2002280010360000200041c4006a200241136a2800003600000c0d0b0240200441ff0171450d00200241003a0080040b2000410b3a00000c0c0b0240200441ff0171450d00200241003a0080040b2000410b3a00000c0b0b41002104200241003a008004024002400340200128020022032802042205450d01200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a290300220737030020024190016a41086a2203200241e0036a41086a29030037030020024190016a41106a2204200241e0036a41106a29030037030020024190016a41186a22052007370300200220022903e00337039001200241f0006a41186a2005290300370300200241f0006a41106a2004290300370300200241f0006a41086a2003290300370300200220022903900137037041002104200241003a0080040340200128020022032802042205450d02200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a2903002207370300200241306a41086a2201200241e0036a41086a290300370300200241306a41106a2203200241e0036a41106a290300370300200241306a41186a22042007370300200220022903e003370330200241d0006a41186a2205200241f0006a41186a290300370300200241d0006a41106a2206200241f0006a41106a290300370300200241d0006a41086a220b200241f0006a41086a29030037030020022002290370370350200041093a000020002002290350370001200041096a200b290300370000200041116a2006290300370000200041196a2005290300370000200041216a2002290330370000200041296a2001290300370000200041316a2003290300370000200041396a2004290300370000200041c1006a2002280010360000200041c4006a200241136a2800003600000c0c0b0240200441ff0171450d00200241003a0080040b2000410b3a00000c0b0b0240200441ff0171450d00200241003a0080040b2000410b3a00000c0a0b41002104200241003a00800402400340200128020022032802042205450d01200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a290300220737030020024190016a41086a2203200241e0036a41086a29030037030020024190016a41106a2204200241e0036a41106a29030037030020024190016a41186a22052007370300200220022903e00337039001200241d0006a41186a2005290300370300200241d0006a41106a2004290300370300200241d0006a41086a2003290300370300200220022903900137035041002104200241003a0080040340200128020022032802042205450d03200241e0036a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a0080042003210420034120470d000b200241b0016a41186a200241e0036a41186a290300220737030020024190016a41086a2203200241e0036a41086a29030037030020024190016a41106a2204200241e0036a41106a29030037030020024190016a41186a22052007370300200220022903e00337039001200241f0006a41186a2005290300370300200241f0006a41106a2004290300370300200241f0006a41086a20032903003703002002200229039001370370200128020022032802042204450d05200328020022052d0000210620032004417f6a3602042003200541016a3602004107210320060e020403050b0240200441ff0171450d00200241003a0080040b2000410b3a00000c090b2000410b3a00000c080b0240200441ff0171450d00200241003a0080040b2000410b3a00000c070b200128020022032802042204450d01200328020022052d0000210620032004417f6a3602042003200541016a360200410021030240024002400240024020060e0705040001060203060b410221030c040b410321030c030b410521030c020b410621030c010b410121030b2001200128020441016a2204360204200420012802084b0d01200241e0036a200110950120022802e0032104200241b0016a200241e0036a41047241ac0210e9081a2004411c460d01200241e0036a200241b0016a41ac0210e9081a41b002102c2205450d0420052004360200200541046a200241e0036a41ac0210e9081a200241306a41086a2204200241d0006a41086a290300370300200241306a41106a2206200241d0006a41106a290300370300200241306a41186a220b200241d0006a41186a290300370300200241106a41086a220c200241f0006a41086a290300370300200241106a41106a220d200241f0006a41106a290300370300200241106a41186a220e200241f0006a41186a29030037030020012001280204417f6a36020420022002290350370330200220022903703703102000410a3a000020002002290330370001200041096a2004290300370000200041116a2006290300370000200041196a200b290300370000200041216a2002290310370000200041296a200c290300370000200041316a200d290300370000200041396a200e290300370000200041c4006a2005360200200041c1006a20033a00000c050b2000410b3a00000c040b2000410b3a00000c030b2000410b3a00000c020b2000410b3a00000c010b1036000b200241900c6a24000bad2a03067f047e027f230041e0066b22022400024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a36020020050e0a0102030405060708090b0a0b2000410b3a00000c100b200241d0036a200110930120022d00d0034101460d0a20024198016a200241e9036a29000037030020024190016a200241e1036a29000037030020024188016a200241d9036a290000370300200220022900d10337038001024020012802042203450d00200128020022042d0000210520012003417f6a22073602042001200441016a360200410721060240024020050e020100020b2007450d0120042d0001210520012003417e6a3602042001200441026a360200410021060240024002400240024020050e0705040001060203060b410221060c040b410321060c030b410521060c020b410621060c010b410121060b200241d0036a200110980120022802d0032101200241a0016a200241d0036a41047241ac0210e9081a024002402001411c460d00200241d0036a200241a0016a41ac0210e9081a41b002102c22030d010c130b2000410b3a00000c110b20032001360200200341046a200241d0036a41ac0210e9081a200241e0006a41186a20024180016a41186a2903002208370300200241e0006a41106a20024180016a41106a2903002209370300200241e0006a41086a20024180016a41086a290300220a3703002002200229038001220b370360200041013a00002000200b370001200041096a200a370000200041116a2009370000200041196a2008370000200041246a2003360200200041216a20063a0000200041286a2002290240370200200041306a200241c0006a41086a290200370200200041386a200241c0006a41106a290200370200200041c0006a200241c0006a41186a2902003702000c100b2000410b3a00000c0f0b200241d0036a200110930102400240024020022d00d0034101460d00200241b8016a200241e9036a290000370300200241b0016a200241e1036a290000370300200241a8016a200241d9036a290000370300200220022900d1033703a00120012802042203450d0d200128020022042d0000210620012003417f6a22073602042001200441016a36020041002105024002400240024020060e0706050001110203110b410221050c050b410321050c040b410521050c030b410621050c020b2000410b3a00000c100b410121050b024020074104490d002004280001210620012003417b6a3602042001200441056a36020020024180016a41086a200241a0016a41086a290300220837030020024180016a41106a200241a0016a41106a290300220937030020024180016a41186a200241a0016a41186a290300220a370300200220022903a001220b37038001200041023a00002000200b370001200041096a2008370000200041116a2009370000200041196a200a370000200041246a2006360200200041216a20053a0000200041286a2002290260370200200041306a200241e0006a41086a290200370200200041386a200241e0006a41106a290200370200200041c0006a200241e0006a41186a2902003702000c0f0b2000410b3a00000c0e0b200241d0036a200110930102400240024020022d00d0034101460d00200241b8016a200241e9036a290000370300200241b0016a200241e1036a290000370300200241a8016a200241d9036a290000370300200220022900d1033703a00120012802042203450d0d200128020022042d0000210620012003417f6a22073602042001200441016a36020041002105024002400240024020060e0706050001110203110b410221050c050b410321050c040b410521050c030b410621050c020b2000410b3a00000c0f0b410121050b024020074104490d002004280001210620012003417b6a3602042001200441056a36020020024180016a41086a200241a0016a41086a290300220837030020024180016a41106a200241a0016a41106a290300220937030020024180016a41186a200241a0016a41186a290300220a370300200220022903a001220b37038001200041033a00002000200b370001200041096a2008370000200041116a2009370000200041196a200a370000200041246a2006360200200041216a20053a0000200041286a2002290260370200200041306a200241e0006a41086a290200370200200041386a200241e0006a41106a290200370200200041c0006a200241e0006a41186a2902003702000c0e0b2000410b3a00000c0d0b200041043a00000c0c0b0240024002402006450d0020042d0001210620012003417e6a22073602042001200441026a3602004100210502400240024002400240024020060e0705000102060304060b410121050c040b410221050c030b410321050c020b410521050c010b410621050b20074104490d012004280002210720012003417a6a22063602042001200441066a36020020064102490d0220042f000621062001200341786a3602042001200441086a360200200041046a2007360200200041026a20063b0100200020053a0001200041053a0000200041086a20022902d003370200200041106a200241d0036a41086a290200370200200041186a200241d0036a41106a290200370200200041206a200241d0036a41186a290200370200200041286a200241d0036a41206a290200370200200041306a200241d0036a41286a290200370200200041386a200241d0036a41306a290200370200200041c0006a200241d0036a41386a2902003702000c0e0b2000410b3a00000c0d0b2000410b3a00000c0c0b2000410b3a00000c0b0b200241d0036a2001109301024002400240024002400240024020022d00d0034101460d00200241b8016a200241e9036a290000370300200241b0016a200241e1036a290000370300200241a8016a200241d9036a290000370300200220022900d1033703a00120012802042203450d03200128020022042d0000210520012003417f6a22063602042001200441016a36020041002107024002400240024020050e0706050001070203070b410221070c050b410321070c040b410521070c030b410621070c020b2000410b3a00000c100b410121070b20064102490d0120042f0001210520012003417d6a3602042001200441036a360200200241106a200110ab0120022802100d0220022802142103200241086a200110ab0120022802080d03200228020c210120024180016a41186a200241a0016a41186a290300220837030020024180016a41106a200241a0016a41106a290300220937030020024180016a41086a200241a0016a41086a290300220a370300200220022903a001220b37038001200041063a00002000200b370001200041096a200a370000200041116a2009370000200041196a2008370000200041286a2001360200200041246a2003360200200041226a20053b0100200041216a20073a00002000412c6a2002290260370200200041346a200241e0006a41086a2902003702002000413c6a200241e0006a41106a290200370200200041c4006a200241e0006a41186a2802003602000c0e0b2000410b3a00000c0d0b2000410b3a00000c0c0b2000410b3a00000c0b0b2000410b3a00000c0a0b200241d0036a2001109301024020022d00d0034101460d00200241f8006a200241e9036a290000370300200241f0006a200241e1036a290000370300200241e8006a200241d9036a290000370300200220022900d10337036041002104200241003a00f0032001280204417f6a21030240024003402003417f460d01200241d0036a20046a200128020022052d00003a0000200120033602042001200541016a3602002002200441016a22053a00f0032003417f6a21032005210420054120470d000b200241a0016a41086a2201200241d0036a41086a290300370300200241a0016a41106a2203200241d0036a41106a290300370300200241a0016a41186a2204200241d0036a41186a290300370300200220022903d0033703a001200541ff0171411f4d0d01200241206a41086a22052001290300370300200241206a41106a22012003290300370300200241206a41186a22032004290300370300200241c0006a41086a2204200241e0006a41086a290300370300200241c0006a41106a2206200241e0006a41106a290300370300200241c0006a41186a2207200241e0006a41186a290300370300200220022903a00137032020022002290360370340200041073a000020002002290340370001200041096a2004290300370000200041116a2006290300370000200041196a2007290300370000200041216a2002290320370000200041296a2005290300370000200041316a2001290300370000200041396a2003290300370000200041c1006a2002280019360000200041c4006a2002411c6a2800003600000c0c0b200441ff0171450d00200241003a00f0030b2000410b3a00000c0a0b2000410b3a00000c090b200241d0036a2001109301024020022d00d0034101460d00200241f8006a200241e9036a290000370300200241f0006a200241e1036a290000370300200241e8006a200241d9036a290000370300200220022900d10337036041002104200241003a00f0032001280204417f6a21030240024003402003417f460d01200241d0036a20046a200128020022052d00003a0000200120033602042001200541016a3602002002200441016a22053a00f0032003417f6a21032005210420054120470d000b200241a0016a41086a2201200241d0036a41086a290300370300200241a0016a41106a2203200241d0036a41106a290300370300200241a0016a41186a2204200241d0036a41186a290300370300200220022903d0033703a001200541ff0171411f4d0d01200241206a41086a22052001290300370300200241206a41106a22012003290300370300200241206a41186a22032004290300370300200241c0006a41086a2204200241e0006a41086a290300370300200241c0006a41106a2206200241e0006a41106a290300370300200241c0006a41186a2207200241e0006a41186a290300370300200220022903a00137032020022002290360370340200041083a000020002002290340370001200041096a2004290300370000200041116a2006290300370000200041196a2007290300370000200041216a2002290320370000200041296a2005290300370000200041316a2001290300370000200041396a2003290300370000200041c1006a2002280019360000200041c4006a2002411c6a2800003600000c0b0b200441ff0171450d00200241003a00f0030b2000410b3a00000c090b2000410b3a00000c080b200241d0036a2001109301024020022d00d0034101460d00200241f8006a200241e9036a290000370300200241f0006a200241e1036a290000370300200241e8006a200241d9036a290000370300200220022900d10337036041002104200241003a00f0032001280204417f6a21030240024003402003417f460d01200241d0036a20046a200128020022052d00003a0000200120033602042001200541016a3602002002200441016a22053a00f0032003417f6a21032005210420054120470d000b200241a0016a41086a2201200241d0036a41086a290300370300200241a0016a41106a2203200241d0036a41106a290300370300200241a0016a41186a2204200241d0036a41186a290300370300200220022903d0033703a001200541ff0171411f4d0d01200241206a41086a22052001290300370300200241206a41106a22012003290300370300200241206a41186a22032004290300370300200241c0006a41086a2204200241e0006a41086a290300370300200241c0006a41106a2206200241e0006a41106a290300370300200241c0006a41186a2207200241e0006a41186a290300370300200220022903a00137032020022002290360370340200041093a000020002002290340370001200041096a2004290300370000200041116a2006290300370000200041196a2007290300370000200041216a2002290320370000200041296a2005290300370000200041316a2001290300370000200041396a2003290300370000200041c1006a2002280019360000200041c4006a2002411c6a2800003600000c0a0b200441ff0171450d00200241003a00f0030b2000410b3a00000c080b2000410b3a00000c070b2000410b3a00000c060b200241d0036a200110930120022d00d0034101460d03200241e0006a41186a200241e9036a2203290000370300200241e0006a41106a200241e1036a2204290000370300200241e0006a41086a200241d9036a2205290000370300200220022900d103370360200241d0036a2001109301024002400240024020022d00d0034101460d0020024180016a41186a200329000037030020024180016a41106a200429000037030020024180016a41086a2005290000370300200220022900d1033703800120012802042203450d03200128020022042d0000210520012003417f6a22073602042001200441016a36020041072106024020050e020300040b2007450d0320042d0001210520012003417e6a3602042001200441026a36020041002106024002400240024020050e0706050001070203070b410221060c050b410321060c040b410521060c030b410621060c020b2000410b3a00000c080b410121060b200241d0036a200110980120022802d0032101200241a0016a200241d0036a41047241ac0210e9081a2001411c460d05200241d0036a200241a0016a41ac0210e9081a41b002102c2203450d0720032001360200200341046a200241d0036a41ac0210e9081a200241c0006a41086a2201200241e0006a41086a290300370300200241c0006a41106a2204200241e0006a41106a290300370300200241c0006a41186a2205200241e0006a41186a290300370300200241206a41086a220720024180016a41086a290300370300200241206a41106a220c20024180016a41106a290300370300200241206a41186a220d20024180016a41186a2903003703002002200229036037034020022002290380013703202000410a3a000020002002290340370001200041096a2001290300370000200041116a2004290300370000200041196a2005290300370000200041216a2002290320370000200041296a2007290300370000200041316a200c290300370000200041396a200d290300370000200041c4006a2003360200200041c1006a20063a00000c060b2000410b3a00000c050b2000410b3a00000c040b2000410b3a00000c030b2000410b3a00000c020b2000410b3a00000c010b2000410b3a00000b200241e0066a24000f0b1036000baf0101017f230041106b22042400200420003703082003200441086a410810740240024002400240200141ff01710e03000102030b200441003a00072003200441076a410110740c020b200441013a00072003200441076a410110740c010b200441023a00072003200441076a410110740b02400240200241ff01714101460d00200441003a00072003200441076a410110740c010b200441013a00072003200441076a410110740b200441106a24000b13002000410236020420004188c4c1003602000b3400200041a081ca0036020420004100360200200041146a4107360200200041106a41d0ccc100360200200041086a42073702000b2f01017f02404104102c22020d001036000b2000420437020420002002360200410020001076410141002000109c010bf70201047f230041e0006b22022400200241086a41a081ca004107108102200241186a41e4d3c100410810810202400240200141086a280200220341046a2204417f4c0d000240024020040d00410121050c010b2004102c2205450d020b200241003602402002200436023c20022005360238200241386a200141041074200128020421012003200241386a1076200241386a2001200310742002200228023822012002280240220410a301370348200241dc006a200120046a360200200220013602582002200241d0006a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220441206a2201417f4c0d000240024020010d00410121030c010b2001102c2203450d020b2000410036020820002001360204200020033602002000200241086a411010742000200241186a41101074200020022802282201200410740240200228022c450d002001102e0b200241e0006a24000f0b1038000b1036000b960203047f017e027f230041306b22012400200141186a22024200370300200141106a22034200370300200141086a4200370300200142003703002001418ef9c0004110108102200141206a41c7c3cb0041071081022002200141206a41086a29000037030020032001290020370300200141206a200110f10220012802202203410820031b2104410021020240024002402001290224420020031b2205422088a722030e020201000b4100210203402003410176220620026a210720072002200420074106746a41206a2000412010ec084101481b2102200320066b220341014b0d000b0b200420024106746a41206a2000412010ec084521020b0240200542ffffff1f83500d002004102e0b200141306a240020020b130020004105360204200041acd8c1003602000b3400200041b6d1cc0036020420004100360200200041146a4105360200200041106a41b8f0c100360200200041086a42063702000b130020004101360204200041f4f7c1003602000b3101017f02404125102c22020d001036000b2000422537020420002002360200412120001076200041b8fcc600412110740b13002000410636020420004194fcc1003602000b34002000418ef9c00036020420004100360200200041146a4105360200200041106a41c09ec200360200200041086a42103702000b5401017f230041106b2202240020004100360208200042013702004100200010762002420037030820024200370300200020024110107420024200370308200242003703002000200241101074200241106a24000b2901017f230041106b2202240020024100360208200242083703002000200210b401200241106a24000b130020004107360204200041a0a9c2003602000b4b01027f230041106b22022400200242f0d0c9abc6add9b1f40037030802404108102c22030d001036000b20004208370204200020033602002000200241086a41081074200241106a24000b4201027f230041106b2202240002404104102c22030d001036000b20004204370204200020033602002002410d36020c20002002410c6a41041074200241106a24000b4b01027f230041106b2202240002404110102c22030d001036000b20004210370204200020033602002002420037030820024280e0cdb8eb053703002000200241101074200241106a24000ba30302057f017e230041b0016b220224002002200141206a41e7e485f30610d103200228020421032002280200210441002105200241003a0068024002400240034020032005460d01200241c8006a20056a200420056a2d00003a00002002200541016a22063a00682006210520064120470d000b200241f0006a41086a2205200241c8006a41086a290300370300200241f0006a41106a2203200241c8006a41106a290300370300200241f0006a41186a2204200241c8006a41186a29030037030020022002290348370370200641ff0171411f4d0d01200241286a41186a20042903002207370300200241086a41086a2005290300370300200241086a41106a2003290300370300200241086a41186a2007370300200220022903703703080c020b200541ff0171450d00200241003a00680b200241106a4200370300200241186a4200370300200241206a4200370300200242003703080b20002001360200200020022903083700042000410c6a200241106a290300370000200041146a200241186a2903003700002000411c6a200241206a290300370000200241b0016a24000bc00101027f4100210341d4e2cc0021040240024002400240024002400240200241e6e485f3064a0d00200241f0c2c98b06460d03200241e2c289ab06460d01200241e1ea91cb06470d06200141a0016a21040c050b200241e9dabdf306460d01200241e1e69df306460d03200241e7e485f306470d0541202103200121040c050b41202103200141206a21040c040b200141c0006a21040c020b200141e0006a21040c010b20014180016a21040b412021030b20002003360204200020043602000ba30302057f017e230041b0016b220224002002200141206a41e9dabdf30610d103200228020421032002280200210441002105200241003a0068024002400240034020032005460d01200241c8006a20056a200420056a2d00003a00002002200541016a22063a00682006210520064120470d000b200241f0006a41086a2205200241c8006a41086a290300370300200241f0006a41106a2203200241c8006a41106a290300370300200241f0006a41186a2204200241c8006a41186a29030037030020022002290348370370200641ff0171411f4d0d01200241286a41186a20042903002207370300200241086a41086a2005290300370300200241086a41106a2003290300370300200241086a41186a2007370300200220022903703703080c020b200541ff0171450d00200241003a00680b200241106a4200370300200241186a4200370300200241206a4200370300200242003703080b20002001360200200020022903083700042000410c6a200241106a290300370000200041146a200241186a2903003700002000411c6a200241206a290300370000200241b0016a24000b130020004105360204200041c8b9c2003602000b130020004108360204200041c8bcc2003602000b13002000411136020420004180c2c2003602000b870201037f230041d0006b22022400200241086a41bad7c7004108108102200241186a41dbafc9004109108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000bac0201037f230041e0006b2202240020024188fec6004108108102200241106a41e7ccc2004107108102024002404120102c2203450d002002422037023420022003360230200241306a200141201074200241c0006a200228023022012002280238220310d803200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c0006a360250200241206a200241d0006a107c02402002280234450d002001102e0b2002280228220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b20004100360208200020013602042000200436020020002002411010742000200241106a411010742000200228022022012003107402402002280224450d002001102e0b200241e0006a24000f0b1036000b1038000b2c0020002002ad4220862001ad84100f2201290000370000200041086a200141086a2900003700002001102e0b1300200041053602042000419ccdc2003602000b3400200041f1fcc60036020420004100360200200041146a4101360200200041106a41b4e4c200360200200041086a42073702000b130020004101360204200041f4e5c2003602000b4b01027f230041106b2202240002404110102c22030d001036000b20004210370204200020033602002002420037030820024280d0dbc3f4023703002000200241101074200241106a24000b13002000410f360204200041c4ebc2003602000b340020004188fec60036020420004100360200200041146a4104360200200041106a41f0aac300360200200041086a42083702000b2f01017f02404104102c22020d001036000b2000420437020420002002360200410020001076410841002000109a010b4c01027f230041106b2202240002404114102c22030d001036000b200042143702042000200336020020024200370308200242003703002000200241101074410020001076200241106a24000b7001027f230041d0006b22022400200241063a002802404101102c2203450d002000420137020420002003360200200241003a004f2000200241cf006a41011074024020022d00284101470d00200241306a280200450d002002412c6a280200102e0b200241d0006a24000f0b1036000b840101027f230041d0026b22022400200241ac026a41023a000002404101102c2203450d002000420137020420002003360200200241003a00cf022000200241cf026a41011074024020022d00ac024102460d0002402002411c6a28020041ffffff3f71450d002002280218102e0b200241246a10e3030b200241d0026a24000f0b1036000b930301027f024020002802082201450d0020002802002202200141c8006c6a21010340024020022d00004101470d00200241086a280200450d00200241046a280200102e0b0240200241246a2d00004101470d002002412c6a280200450d00200241286a280200102e0b200241c8006a22022001470d000b0b0240200041046a2802002202450d00200241c8006c450d002000280200102e0b024020002d000c4101470d00200041146a280200450d00200041106a280200102e0b024020002d00304101470d00200041386a280200450d00200041346a280200102e0b024020002d00544101470d00200041dc006a280200450d00200041d8006a280200102e0b024020002d00784101470d0020004180016a280200450d00200041fc006a280200102e0b024020002d009c014101470d00200041a4016a280200450d00200041a0016a280200102e0b024020002d00c0014101470d00200041c8016a280200450d00200041c4016a280200102e0b024020002d00e4014101470d00200041ec016a280200450d00200041e8016a280200102e0b0b130020004106360204200041d0b4c3003602000b4201027f230041106b2202240002404104102c22030d001036000b20004204370204200020033602002002411436020c20002002410c6a41041074200241106a24000b4b01027f230041106b2202240002404110102c22030d001036000b20004210370204200020033602002002420037030820024280f19384eb053703002000200241101074200241106a24000b4a01027f230041106b2202240002404110102c22030d001036000b200042103702042000200336020020024200370308200242809adbba023703002000200241101074200241106a24000b4b01027f230041106b2202240002404110102c22030d001036000b20004210370204200020033602002002420037030820024280fad5d5f2053703002000200241101074200241106a24000bfc0302037f017e230041106b2202240020002802102103200041186a280200220420011076024020044105742204450d00200320046a21040340200220032802003602002001200241041074200341086a200110ea03200341206a22032004470d000b0b200029030021052002200041086a2903003703082002200537030020012002411010742000411c6a200110b7012002200041286a108a012001200228020022032002280208107402402002280204450d002003102e0b2002200041cc006a108a012001200228020022032002280208107402402002280204450d002003102e0b2002200041f0006a108a012001200228020022032002280208107402402002280204450d002003102e0b200220004194016a108a012001200228020022032002280208107402402002280204450d002003102e0b2002200041b8016a108a012001200228020022032002280208107402402002280204450d002003102e0b02400240200041a4026a2d00004101460d00200241003a000020012002410110740c010b200241013a000020012002410110742001200041a5026a411410740b2002200041dc016a108a012001200228020022032002280208107402402002280204450d002003102e0b200220004180026a108a012001200228020022032002280208107402402002280204450d002003102e0b200241106a24000bd50102017f017e230041106b220224000240024002400240024002400240024020002802000e0700010203040506070b200241003a000020012002410110740c060b200241013a00002001200241011074200029030821032002200041106a2903003703082002200337030020012002411010740c050b200241023a000020012002410110740c040b200241033a000020012002410110740c030b200241043a000020012002410110740c020b200241053a000020012002410110740c010b200241063a000020012002410110740b200241106a24000baa0b010a7f230041e0006b22022400200241003a00380240024002400240024002400240024002400240024020012802002203280204220420044100472205490d00200241386a20032802002206200510e9081a2003200420056b3602042003200620056a360200024020040d0041002107200241056a2103200241086a21042002411c6a21050c0a0b41002107200241056a2103200241086a21042002411c6a210520022d003822080e260901010101010101010101010101010101010101010101010101010101010101010102030405010b200041063a00000c090b02402008417f6a220641ff01714121490d00200041063a00000c090b0240024020060d00410121090c010b200610322209450d060b20092001280200220128020020012802042208200620082006491b220a10e908210b20012802042207200a490d0620012007200a6b36020420012001280200200a6a360200410121070240200820064f0d00200b200a6a22014100200b20066a20016b10eb081a0b2006210a0c070b200241386a200110a60141022107200241346a41026a220120022d003b3a0000200241206a41086a2208200241d0006a290300370300200241206a41106a220b200241d8006a2d00003a0000200220022f00393b01342002200241386a41106a29030037032020022d00384101460d03200241386a41086a2802002106200241c4006a280200210a200228023c21092002411c6a41026a20012d00003a0000200241086a41086a2008290300370300200241086a41106a200b2d00003a0000200220022f01343b011c200220022903203703080c060b200241386a200110a601200241346a41026a220120022d003b3a0000200241206a41086a2207200241d0006a290300370300200241206a41106a2208200241d8006a2d00003a0000200220022f00393b01342002200241386a41106a290300370320024020022d00384101460d00200241386a41086a2802002106200241c4006a280200210a200228023c21092002411c6a41026a20012d00003a0000200241086a41086a2007290300370300200241086a41106a20082d00003a0000200220022f01343b011c20022002290320370308410321070c060b200041063a00000c060b200241386a200110a601200241346a41026a220120022d003b3a0000200241206a41086a2207200241d0006a290300370300200241206a41106a2208200241d8006a2d00003a0000200220022f00393b01342002200241386a41106a290300370320024020022d00384101460d00200241386a41086a2802002106200241c4006a280200210a200228023c21092002411c6a41026a20012d00003a0000200241086a41086a2007290300370300200241086a41106a20082d00003a0000200220022f01343b011c20022002290320370308410421070c050b200041063a00000c050b200241386a200110a601200241346a41026a220120022d003b3a0000200241206a41086a2207200241d0006a290300370300200241206a41106a2208200241d8006a2d00003a0000200220022f00393b01342002200241386a41106a290300370320024020022d00384101460d00200241386a41086a2802002106200241c4006a280200210a200228023c21092002411c6a41026a20012d00003a0000200241086a41086a2007290300370300200241086a41106a20082d00003a0000200220022f01343b011c20022002290320370308410521070c040b200041063a00000c040b200041063a00000c030b1036000b200a200741b8b2c0001056000b200020073a0000200020052f00003b00012000410c6a200a360000200041086a2006360000200041046a2009360000200041106a2004290000370000200041216a20032f00003b0000200041036a200541026a2d00003a0000200041186a200441086a290000370000200041206a200441106a2d00003a0000200041236a200341026a2d00003a00000b200241e0006a24000bbe1503097f027e027f23004190016b2202240002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602004100210720050e260601010101010101010101010101010101010101010101010101010101010101010102030405010b200041063a00000c0a0b02402005417f6a41ff01714121490d00200041063a00000c0a0b024002402005417f6a22080d00410121090c010b200810322209450d07200128020421060b20062008490d0520092001280200200810e9081a200128020422042008490d072001200420086b3602042001200128020020086a360200410121072008210a0c040b41002108200241003a00582003417f6a21092003417e6a210302400240034020092008460d01200241386a20086a200420086a220541016a2d00003a0000200120033602042001200541026a3602002002200841016a22053a00582003417f6a21032005210820054120470d000b200241f4006a41026a220420022d003a22013a00002002418c016a41026a220320013a0000200241f8006a41086a2207200241cf006a290000220b370300200241f8006a41106a2206200241d7006a2d000022013a0000200220022f013822083b0174200220083b018c0120022002290047220c370378200228003b2109200228003f210a20022800432108200241e0006a41106a220d20013a0000200241e0006a41086a220e200b3703002002200c37036041012101200541ff01714120490d01200320042d00003a00002007200e2903003703002006200d2d00003a0000200220022f01743b018c0120022002290360370378410021010c010b0240200841ff0171450d00200241003a00580b410121010b41022107200241346a41026a22042002418c016a41026a2d00003a0000200241206a41086a2203200241f8006a41086a290300370300200241206a41106a2205200241f8006a41106a2d00003a0000200220022f018c013b013420022002290378370320024020010d002002411c6a41026a20042d00003a0000200241086a41086a2003290300370300200241086a41106a20052d00003a0000200220022f01343b011c200220022903203703080c040b200041063a00000c080b41002108200241003a00582003417f6a21092003417e6a210302400240034020092008460d01200241386a20086a200420086a220541016a2d00003a0000200120033602042001200541026a3602002002200841016a22053a00582003417f6a21032005210820054120470d000b200241f4006a41026a220420022d003a22013a00002002418c016a41026a220320013a0000200241f8006a41086a2207200241cf006a290000220b370300200241f8006a41106a2206200241d7006a2d000022013a0000200220022f013822083b0174200220083b018c0120022002290047220c370378200228003b2109200228003f210a20022800432108200241e0006a41106a220d20013a0000200241e0006a41086a220e200b3703002002200c37036041012101200541ff01714120490d01200320042d00003a00002007200e2903003703002006200d2d00003a0000200220022f01743b018c0120022002290360370378410021010c010b0240200841ff0171450d00200241003a00580b410121010b200241346a41026a22042002418c016a41026a2d00003a0000200241206a41086a2203200241f8006a41086a290300370300200241206a41106a2205200241f8006a41106a2d00003a0000200220022f018c013b013420022002290378370320024020010d002002411c6a41026a20042d00003a0000200241086a41086a2003290300370300200241086a41106a20052d00003a0000200220022f01343b011c20022002290320370308410321070c030b200041063a00000c070b41002108200241003a00582003417f6a21092003417e6a210302400240034020092008460d01200241386a20086a200420086a220541016a2d00003a0000200120033602042001200541026a3602002002200841016a22053a00582003417f6a21032005210820054120470d000b200241f4006a41026a220420022d003a22013a00002002418c016a41026a220320013a0000200241f8006a41086a2207200241cf006a290000220b370300200241f8006a41106a2206200241d7006a2d000022013a0000200220022f013822083b0174200220083b018c0120022002290047220c370378200228003b2109200228003f210a20022800432108200241e0006a41106a220d20013a0000200241e0006a41086a220e200b3703002002200c37036041012101200541ff01714120490d01200320042d00003a00002007200e2903003703002006200d2d00003a0000200220022f01743b018c0120022002290360370378410021010c010b0240200841ff0171450d00200241003a00580b410121010b200241346a41026a22042002418c016a41026a2d00003a0000200241206a41086a2203200241f8006a41086a290300370300200241206a41106a2205200241f8006a41106a2d00003a0000200220022f018c013b013420022002290378370320024020010d002002411c6a41026a20042d00003a0000200241086a41086a2003290300370300200241086a41106a20052d00003a0000200220022f01343b011c20022002290320370308410421070c020b200041063a00000c060b41002108200241003a00582003417f6a21092003417e6a210302400240034020092008460d01200241386a20086a200420086a220541016a2d00003a0000200120033602042001200541026a3602002002200841016a22053a00582003417f6a21032005210820054120470d000b200241f4006a41026a220420022d003a22013a00002002418c016a41026a220320013a0000200241f8006a41086a2207200241cf006a290000220b370300200241f8006a41106a2206200241d7006a2d000022013a0000200220022f013822083b0174200220083b018c0120022002290047220c370378200228003b2109200228003f210a20022800432108200241e0006a41106a220d20013a0000200241e0006a41086a220e200b3703002002200c37036041012101200541ff01714120490d01200320042d00003a00002007200e2903003703002006200d2d00003a0000200220022f01743b018c0120022002290360370378410021010c010b0240200841ff0171450d00200241003a00580b410121010b200241346a41026a22042002418c016a41026a2d00003a0000200241206a41086a2203200241f8006a41086a290300370300200241206a41106a2205200241f8006a41106a2d00003a0000200220022f018c013b01342002200229037837032020010d042002411c6a41026a20042d00003a0000200241086a41086a2003290300370300200241086a41106a20052d00003a0000200220022f01343b011c20022002290320370308410521070b200020073a0000200020022f011c3b00012000410c6a2008360000200041086a200a360000200041046a2009360000200041106a2002290308370000200041216a20022f00053b0000200041036a2002411c6a41026a2d00003a0000200041186a200241086a41086a290300370000200041206a200241086a41106a2d00003a0000200041236a200241056a41026a2d00003a00000c040b200041063a00002009102e0c030b1036000b2008200441b8b2c0001056000b200041063a00000b20024190016a24000bd61405067f017e027f017e017f23004190016b22022400024002400240024002400240024002400240024002400240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a3602004100210720060e260601010101010101010101010101010101010101010101010101010101010101010102030405010b200041063a00000c0a0b02402006417f6a41ff01714121490d00200041063a00000c0a0b024002402006417f6a22030d00410121040c010b200310322204450d070b200128020022012802042003490d0520042001280200200310e9081a200128020422052003490d072001200520036b3602042001200128020020036a36020041012107200321050c040b41002104200241003a0058024002400340200128020022032802042205450d01200241386a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00582003210420034120470d000b200241f4006a41026a220120022d003a22033a00002002418c016a41026a220620033a0000200241f8006a41086a2207200241cf006a2900002208370300200241f8006a41106a2209200241d7006a2d0000220a3a0000200220022f013822033b0174200220033b018c0120022002290047220b370378200228003b2104200228003f210520022800432103200241e0006a41106a220c200a3a0000200241e0006a41086a220a20083703002002200b370360200620012d00003a0000200220022f01743b018c012009200c2d00003a00002007200a29030037030020022002290360370378410021010c010b0240200441ff0171450d00200241003a00580b410121010b41022107200241346a41026a22062002418c016a41026a2d00003a0000200241206a41086a2209200241f8006a41086a290300370300200241206a41106a220a200241f8006a41106a2d00003a0000200220022f018c013b013420022002290378370320024020010d002002411c6a41026a20062d00003a0000200241086a41086a2009290300370300200241086a41106a200a2d00003a0000200220022f01343b011c200220022903203703080c040b200041063a00000c080b41002104200241003a0058024002400340200128020022032802042205450d01200241386a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00582003210420034120470d000b200241f4006a41026a220120022d003a22033a00002002418c016a41026a220620033a0000200241f8006a41086a2207200241cf006a2900002208370300200241f8006a41106a2209200241d7006a2d0000220a3a0000200220022f013822033b0174200220033b018c0120022002290047220b370378200228003b2104200228003f210520022800432103200241e0006a41106a220c200a3a0000200241e0006a41086a220a20083703002002200b370360200620012d00003a0000200220022f01743b018c012009200c2d00003a00002007200a29030037030020022002290360370378410021010c010b0240200441ff0171450d00200241003a00580b410121010b200241346a41026a22062002418c016a41026a2d00003a0000200241206a41086a2207200241f8006a41086a290300370300200241206a41106a2209200241f8006a41106a2d00003a0000200220022f018c013b013420022002290378370320024020010d002002411c6a41026a20062d00003a0000200241086a41086a2007290300370300200241086a41106a20092d00003a0000200220022f01343b011c20022002290320370308410321070c030b200041063a00000c070b41002104200241003a0058024002400340200128020022032802042205450d01200241386a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00582003210420034120470d000b200241f4006a41026a220120022d003a22033a00002002418c016a41026a220620033a0000200241f8006a41086a2207200241cf006a2900002208370300200241f8006a41106a2209200241d7006a2d0000220a3a0000200220022f013822033b0174200220033b018c0120022002290047220b370378200228003b2104200228003f210520022800432103200241e0006a41106a220c200a3a0000200241e0006a41086a220a20083703002002200b370360200620012d00003a0000200220022f01743b018c012009200c2d00003a00002007200a29030037030020022002290360370378410021010c010b0240200441ff0171450d00200241003a00580b410121010b200241346a41026a22062002418c016a41026a2d00003a0000200241206a41086a2207200241f8006a41086a290300370300200241206a41106a2209200241f8006a41106a2d00003a0000200220022f018c013b013420022002290378370320024020010d002002411c6a41026a20062d00003a0000200241086a41086a2007290300370300200241086a41106a20092d00003a0000200220022f01343b011c20022002290320370308410421070c020b200041063a00000c060b41002104200241003a0058024002400340200128020022032802042205450d01200241386a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00582003210420034120470d000b200241f4006a41026a220120022d003a22033a00002002418c016a41026a220620033a0000200241f8006a41086a2207200241cf006a2900002208370300200241f8006a41106a2209200241d7006a2d0000220a3a0000200220022f013822033b0174200220033b018c0120022002290047220b370378200228003b2104200228003f210520022800432103200241e0006a41106a220c200a3a0000200241e0006a41086a220a20083703002002200b370360200620012d00003a0000200220022f01743b018c012009200c2d00003a00002007200a29030037030020022002290360370378410021010c010b0240200441ff0171450d00200241003a00580b410121010b200241346a41026a22062002418c016a41026a2d00003a0000200241206a41086a2207200241f8006a41086a290300370300200241206a41106a2209200241f8006a41106a2d00003a0000200220022f018c013b01342002200229037837032020010d042002411c6a41026a20062d00003a0000200241086a41086a2007290300370300200241086a41106a20092d00003a0000200220022f01343b011c20022002290320370308410521070b200020073a0000200020022f011c3b00012000410c6a2003360000200041086a2005360000200041046a2004360000200041106a2002290308370000200041216a20022f00053b0000200041036a2002411c6a41026a2d00003a0000200041186a200241086a41086a290300370000200041206a200241086a41106a2d00003a0000200041236a200241056a41026a2d00003a00000c040b200041063a00002004102e0c030b1036000b2003200541b8b2c0001056000b200041063a00000b20024190016a24000b13002000410436020420004180ccc3003602000b340020004195fec60036020420004100360200200041146a4102360200200041106a41c4f2c300360200200041086a42083702000b130020004103360204200041b4f5c3003602000b4301027f230041106b2202240002404102102c22030d001036000b2000420237020420002003360200200241e4003b010e20002002410e6a41021074200241106a24000b4a01027f230041106b2202240002404110102c22030d001036000b20004210370204200020033602002002420037030820024280a0cb98013703002000200241101074200241106a24000b4b01027f230041106b2202240002404110102c22030d001036000b200042103702042000200336020020024200370308200242809886abec053703002000200241101074200241106a24000b130020004103360204200041ecffc3003602000b3400200041bad7c70036020420004100360200200041146a4103360200200041106a41c489c400360200200041086a42083702000b2e01017f02404104102c22020d001036000b200042043702042000200236020041002000107620004104410010740b130020004105360204200041d88dc4003602000b4b01027f230041106b22022400200242f0f2bda1a7ee9cb9f90037030802404108102c22030d001036000b20004208370204200020033602002000200241086a41081074200241106a24000b4401027f230041106b2202240002404104102c22030d001036000b200042043702042000200336020020024190ce0036020c20002002410c6a41041074200241106a24000b4401027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241808c1536020c20002002410c6a41041074200241106a24000b4401027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241d0860336020c20002002410c6a41041074200241106a24000b130020004110360204200041989cc4003602000b13002000410e360204200041e4a3c4003602000b130020004102360204200041e4adc4003602000bff0101037f230041d0006b22022400200241f1fcc6004107108102200241106a418ce5c20041081081022002200136022c200241306a2002412c6a410410d803200241cc006a2002412c6a41046a3602002002200241c0006a36024420022002412c6a3602482002200241306a360240200241206a200241c0006a107c024002402002280228220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b20004100360208200020013602042000200436020020002002411010742000200241106a411010742000200228022022012003107402402002280224450d002001102e0b200241d0006a24000f0b1038000b1036000be4810203097f097e187f230041e0116b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e100001020f0e0d0c0b0a09080706050403000b200341940f6a4101360200200342013702840f2003419cc3cb003602800f200341043602c40c20034194c3cb003602c00c2003200341c00c6a3602900f200341800f6a41f89bc4001044000b41022104200341f0046a41026a200141036a2d00003a0000200341c00c6a41086a2205200141146a290000370300200341c00c6a410d6a2206200141196a290000370000200320012f00013b01f00420032001410c6a2900003703c00c200141086a2800002107200141046a280000210820022802282101024002400240024020022d00000e0400010203020b20022d0001210220012001280200417f6a2209360200024020090d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22092009280200417f6a220936020020090d002001102e0b200241ff0171450d024110102c2202450d1a200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1a20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220536020020050d012002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22052005280200417f6a220536020020050d012002102e0c010b200241046a2d00002109200241086a280200210a2002410c6a280200210b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200941ff01710d00200a410174200b4b0d020b4110102c2202450d19200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1920014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220536020020050d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22052005280200417f6a220536020020050d002002102e0b20012001280200417f6a220236020020020d192001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d192001102e0c1a0b20034190056a108104200341e8016a41086a2005290300370300200341e8016a410d6a2006290000370000200320032f01f0043b0184022003200341f2046a2d00003a008602200320032903c00c3703e8010240200328029805220241134b0d00200341800f6a41086a2204200341e8016a41086a290300370300200341800f6a410d6a2205200341e8016a410d6a290000370000200320032f0184023b01a00c200320032d0086023a00a20c200320032903e8013703800f02400240024002402002200328029405470d00200241016a22012002490d13200241017422062001200620014b1b22014104200141044b1b220141ffffff1f712001464103742106200141067421010240024020020d00200341003602f0090c010b200341f0096a41086a410836020020032003280290053602f009200320024106743602f4090b200341c0076a20012006200341f0096a107d200341c8076a280200210120032802c0074101460d01200320032802c4073602900520032001410676360294050b20032802900520024106746a2201420037030820014201370300200141106a4200370300200141186a4200370300200141206a20032f01a00c3b0100200141226a20032d00a20c3a0000200141276a2007360000200141236a20083600002001412b6a20032903800f370000200141336a2004290300370000200141386a20052900003700002003200241016a220136029805200341f0096a41086a20013602002003200329039005220c3703f009200ca722040d0120034188026a41186a2204420037030020034188026a41106a2205420037030020034188026a41086a220642003703002003420037038802200341800f6a4188fec60041081081022006200341800f6a41086a2207290000370300200320032900800f37038802200341800f6a41b0afc300410a10810220042007290000370300200520032900800f37030020034188026a412010ff010c020b2001450d110c1a0b20034188026a41186a2205420037030020034188026a41106a2206420037030020034188026a41086a220742003703002003420037038802200341800f6a4188fec60041081081022007200341800f6a41086a2208290000370300200320032900800f37038802200341800f6a41b0afc300410a10810220052008290000370300200620032900800f37030020034188026a200341f0096a10820420032802f40941ffffff1f71450d002004102e0b2003418c0f6a2002360200200341880f6a41063a0000200341123a00800f200341800f6a10fe01200320032800c8023602c0112003200341cb026a2800003600c311200041186a41003a0000200041106a2001ad42b0ae157e42c896efc5007c37030020004201370308200020032802c0113600192000411c6a20032800c311360000200042003703000c1b0b200341800f6a410d108304200341880f6a280200210120032802840f210220032802800f210420032802940541ffffff1f71450d19200328029005102e0c190b200341f0096a200141046a41a00210e9081a200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a200241106a290200370300200341800f6a41086a200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c10220034188026a41086a2201200341c90c6a29000037030020034188026a41106a2202200341d10c6a29000037030020034188026a41186a2204200341d90c6a290000370300200320032900c10c3703880220032d00c00c4101460d11200341c0076a41186a2004290300370300200341c0076a41106a2002290300370300200341c0076a41086a200129030037030020032003290388023703c007024020032802f809220141e4004d0d00200341800f6a410c10830420032f00810f20032d00830f41107472210120032902840f210c20032d00800f21020c130b200341106a2001ad220d420042809adbba02420010e808200341c0116a200341c0076a108404200341800f6a20032802c011220120032802c81110850420034190056a200341800f6a41a40210e9081a200341f0046a41086a2202200341ad116a290000370300200341f0046a41106a2204200341b5116a290000370300200341f0046a41176a2205200341bc116a280000360000200320032900a5113703f004200341106a41086a290300210e2003290310210f20032d00a41122064102460d13200341c8026a20034190056a41a40210e9081a200341a8026a41176a2005280000360000200341a8026a41106a2004290300370300200341a8026a41086a2002290300370300200320032903f0043703a802024020032802c411450d002001102e0b200341800f6a200341c8026a41a40210e9081a200341800f6a41a4026a20063a0000200341a5116a20032903a802370000200341ad116a200341a8026a41086a290300370000200341b5116a200341a8026a41106a290300370000200341bc116a200341bf026a280000360000200341800f6a41186a22012802002106410021072001410036020002402006450d0020032802900f220841086a210a41002109410021074100210402400340024002402007450d00200820044105746a21012008200420096a4105746a210203400240200141086a2205280200417f6a0e06000303030300030b20022001290300370300200241186a200141186a290300370300200241106a200141106a290300370300200241086a2005290300370300200241206a2102200141206a21012006200441016a22044b0d000c040b0b200a20044105746a2101034002402001280200417f6a0e06000202020200020b200141206a21012006200441016a22044b0d000b410021070c030b2009417f6a2109200741016a21072006200441016a22044b0d000b0b024020070d00410021070c010b2008200420076b4105746a200820044105746a200620046b41057410ea081a0b2003200620076b3602980f2003419c0f6a220110e3032001200341f0096a41a00210e9081a200341c00c6a200341800f6a41c00210e9081a200341c00c6a41086a290300211020032903c00c21110c140b200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a200241106a290200370300200341800f6a41086a200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c102200341c0076a41086a2201200341c90c6a290000370300200341c0076a41106a2202200341d10c6a290000370300200341c0076a41186a2204200341d90c6a290000370300200320032900c10c3703c00702400240024002400240024020032d00c00c4101460d0020034190056a41186a200429030037030020034190056a41106a200229030037030020034190056a41086a2001290300370300200320032903c00737039005200341c0076a20034190056a10d703200341800f6a20032802c007220120032802c8072204108604024020032d00a00f220541064622020d002001200410ff010b20034188026a41086a200341800f6a41086a29030037030020034188026a41106a200341800f6a41106a29030037030020034188026a41186a2204200341800f6a41186a290300370300200341bc076a41026a2206200341a30f6a2d00003a0000200341a00c6a41086a2207200341b40f6a290200370300200341a00c6a41106a2208200341bc0f6a290200370300200320032903800f37038802200320032f00a10f3b01bc072003200341ac0f6a2902003703a00c024020020d00200341a80f6a2802002109200341a40f6a280200210a200341b8016a41086a20034188026a41136a290000370300200341b8016a410d6a22022004290000370000200341b8076a41026a20062d00003a0000200341f0046a41106a2008290300370300200341f0046a41086a2007290300370300200320032d008a023a00ea01200320032f0188023b01e80120032003290093023703b801200320032f01bc073b01b807200320032903a00c3703f004200328008b022104200328008f022106024020032802c407450d002001102e0b200341c00c6a410d6a22012002290000370000200341c00c6a41086a2202200341b8016a41086a290300370300200341b4016a220720032d00ea013a0000200341f0096a41086a22082002290300370300200341f0096a410d6a22022001290000370000200320032f01e8013b01d201200320032903b8013703f009200320032801d0013602b001200320063600c707200320043600c307200320072d00003a00c207200320032f01b2013b01c007200341c0076a41136a2008290300370000200341c0076a41186a2002290000370000200320032903f0093700cb0741012108024020054101470d002009450d00200a102e0b200341e8016a41086a200341a3056a290000370300200341f5016a220120034190056a41186a290000370000200320032f0190053b018402200320032d0092053a0086022003200329009b053703e80120032800930521022003280097052104200341c8026a200341c0076a108704200341800f6a20032802c80220032802d0021088044100210720032802900f22050d024200210e410021064200210c4200210f0c030b024020032802c407450d002001102e0b200341c0116a410f10830420032d00c0114106460d0320032902c411210c0c040b200341023a00c0110c030b20032902940f220c42ffffffff0f83210e200c422088a72106200341880f6a290300210f2003419c0f6a280200210a20032903800f210c200521080b200341cb0c6a2004360000200341cf0c6a20032903e801370000200341d70c6a200341e8016a41086a290300370000200341dc0c6a2001290000370000200320032f0184023b01c40c200320032d0086023a00c60c200320023600c70c2003200341c0076a3602c00c200341c00c6a410472210502402006450d0041002109410021074100210402400340024002402007450d00200820044105746a21012008200420096a4105746a2102034020012005412010ec08450d0220022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a290000370000200241206a2102200141206a21012006200441016a22044b0d000c040b0b200820044105746a2101034020012005412010ec08450d01200141206a21012006200441016a22044b0d000b410021070c030b2009417f6a2109200741016a21072006200441016a22044b0d000b0b024020070d00410021070c010b2008200420076b4105746a200820044105746a200620046b41057410ea081a0b200341800f6a20032802c00c2005200c4280f19384eb05200c4280f19384eb05544100200f501b22011b2210200f420020011b2211410010890420032802c00c2101200341f0096a41186a200541186a290000220d370300200341f0096a41106a200541106a2900002212370300200341f0096a41086a200541086a29000022133703002003200529000022143703f009200341d80f6a2011370300200341d00f6a2010370300200341800f6a41086a41093a0000200341800f6a41096a2014370000200341910f6a2013370000200341990f6a2012370000200341a10f6a200d370000200341a90f6a2001290000370000200341b10f6a200141086a290000370000200341b90f6a200141106a290000370000200341c10f6a200141186a290000370000200341123a00800f200341800f6a10fe01200341940f6a200620076bad422086200e843702002003200f20117d200c201054ad7d3703880f2003200c20107d3703800f2003200a36029c0f200320083602900f20032802c802220120032802d002200341800f6a108a040240200e42ffffff3f83500d002008102e0b024020032802cc02450d002001102e0b200341063a00c0110b4200210c20004200370308200020032800800f360019200041186a41003a00002000411c6a200341830f6a2800003600000c010b20032802c01121012000200c370024200041206a2001360000200041186a41003a0000200042003703084201210c0b2000200c3703000c180b200341e4016a41026a200141076a2d00003a0000200341a8026a41086a200141186a290200370300200341a8026a41106a200141206a2902003703002003200141056a2f00003b01e4012003200141106a2902003703a802200141046a2d00002104200141086a28020021052001410c6a2802002101200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a200241106a290200370300200341800f6a41086a200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c102200341c0076a41086a2202200341c90c6a290000370300200341c0076a41106a2206200341d10c6a290000370300200341c0076a41186a2207200341d90c6a290000370300200320032900c10c3703c007024002400240024020032d00c00c4101460d00200341c0116a41186a2007290300370300200341c0116a41106a2006290300370300200341c0116a41086a2002290300370300200320032903c0073703c011200341800f6a200341c0116a10840420032802800f220620032802880f108f022102024020032802840f450d002006102e0b024020020d00200341d8016a41061083040c020b200341f0096a41026a2206200341e4016a41026a2d00003a0000200341800f6a41086a2202200341a8026a41086a290300370300200341800f6a41106a2207200341a8026a41106a290300370300200320032f01e4013b01f009200320032903a8023703800f02400240024020040e03020100010b2001450d002005102e0b200320032903c00c3703b801200341013a00d8010c030b200341c00c6a410d6a2204200341800f6a410d6a290000370000200341c00c6a41086a22082002290300370300200341b8016a41086a22092008290300370300200341b8016a410d6a22082004290000370000200320032f01f0093b01e801200320032903800f3703b801200320062d00003a00ea01200320032d00ea013a00ca02200320032f01e8013b01c802200320013600cf02200320053600cb02200341c8026a41186a2008290000370000200341c8026a41136a2009290300370000200320032903b8013700d302200341c0076a200341c8026a10d703200341800f6a20032802c007220120032802c80710860420034188026a41086a200229030037030020034188026a41106a200729030037030020034188026a41186a2202200341800f6a41186a290300370300200341bc076a41026a200341a30f6a2d00003a0000200341a00c6a41086a200341b40f6a290200370300200341a00c6a41106a200341bc0f6a290200370300200320032903800f37038802200320032f00a10f3b01bc072003200341ac0f6a2902003703a00c0240024020032d00a00f22044106460d00200341a80f6a2802002109200341a40f6a280200210a200341e8016a41086a220520034188026a41136a290000370300200341e8016a410d6a2002290000370000200341b8076a41026a200341bc076a41026a2d00003a0000200341f0046a41106a200341a00c6a41106a290300370300200341f0046a41086a200341a00c6a41086a290300370300200320032d008a023a008602200320032f0188023b01840220032003290093023703e801200320032f01bc073b01b807200320032903a00c3703f004200328008b022102200328008f022106024020032802c407450d002001102e0b200341c00c6a410d6a2201200341e8016a410d6a290000370000200341c00c6a41086a22072005290300370300200341b4016a220520032d0086023a0000200341f0096a41086a22082007290300370300200341f0096a410d6a22072001290000370000200320032f0184023b01d201200320032903e8013703f009200320032801d0013602b00120032006360097052003200236009305200320052d00003a009205200320032f01b2013b019005200341a3056a2008290300370000200341a8056a2007290000370000200320032903f00937009b05024020044101470d002009450d00200a102e0b20034190056a200341c0116a412010ec08450d01200341d8016a41101083040c040b024020032802c407450d002001102e0b200341d8016a410f1083040c030b200341800f6a200341c8026a10d70320032802800f220120032802880f10ff01024020032802840f450d002001102e0b200341c0076a41186a200341c8026a41186a290300220c370300200341c0076a41106a200341c8026a41106a2903002210370300200341c0076a41086a200341c8026a41086a290300220f370300200341c0076a41286a200341c0116a41086a2903002211370300200341c0076a41306a200341c0116a41106a290300220e370300200341c0076a41386a200341c0116a41186a290300220d370300200320032903c80222123703c007200320032903c01122133703e007200341f0096a41386a2201200d370300200341f0096a41306a2202200e370300200341f0096a41286a22042011370300200341f0096a41206a22082013370300200341f0096a41186a220a200c370300200341f0096a41106a220b2010370300200341f0096a41086a2215200f370300200320123703f009200341a00c6a20034190056a108704200341800f6a20032802a00c220920032802a80c2216108804410021060240024020032802900f22070d004200211141012107410021054200210c420021100c010b20032902940f220c42ffffffff0f832111200c422088a72105200341800f6a41086a29030021102003419c0f6a280200211720032903800f210c0b200341c00c6a41386a2001290300370300200341c00c6a41306a2002290300370300200341c00c6a41286a2004290300370300200341c00c6a41206a2008290300370300200341c00c6a41186a200a290300370300200341c00c6a41106a200b290300370300200341c00c6a41086a2015290300370300200320032903f0093703c00c02402005450d0041002108410021064100210402400340024002402006450d00200720044105746a21012007200420086a4105746a210203402001200341c00c6a412010ec08450d0220022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a290000370000200241206a2102200141206a21012005200441016a22044b0d000c040b0b200720044105746a210103402001200341c00c6a412010ec08450d01200141206a21012005200441016a22044b0d000b410021060c030b2008417f6a2108200641016a21062005200441016a22044b0d000b0b024020060d00410021060c010b2007200420066b4105746a200720044105746a200520046b41057410ea081a0b20034190016a200341e00c6a200c4280f19384eb05200c4280f19384eb055441002010501b22011b220f2010420020011b220e10fb01200341d80f6a200e370300200341d00f6a200f370300200341800f6a41086a41083a0000200341890f6a20032903c00c370000200341910f6a200341c00c6a41086a290300370000200341990f6a200341d00c6a290300370000200341a10f6a200341d80c6a290300370000200341a90f6a20032903e00c370000200341b10f6a200341e80c6a290300370000200341b90f6a200341f00c6a290300370000200341c10f6a200341f80c6a290300370000200341123a00800f200341800f6a10fe01200341940f6a200520066bad42208620118437020020032010200e7d200c200f54ad7d3703880f2003200c200f7d3703800f2003201736029c0f200320073602900f20092016200341800f6a108a040240201142ffffff3f83500d002007102e0b024020032802a40c450d002009102e0b200341063a00d8010c030b200341023a00d8010b20044102470d002001450d002005102e0b20032d00d8014106460d0020032802d8012101200020032902dc01370024200041206a2001360000200041186a41003a000020004200370308200042013703000c180b20004200370308200020032800a001360019200041186a41003a00002000411c6a200341a3016a280000360000200042003703000c170b200341a0016a41026a2209200141076a2d00003a0000200341c8026a41086a220a200141186a290200370300200341c8026a41106a220b200141206a2902003703002003200141056a2f00003b01a0012003200141106a2902003703c802200141046a2d00002104200141086a28020021072001410c6a2802002106200341d8016a41026a2001412b6a2d00003a000020034190056a41086a2001413c6a29020037030020034190056a41106a200141c4006a2902003703002003200141296a2f00003b01d8012003200141346a29020037039005200141286a2d000021052001412c6a2802002108200141306a2802002101200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a2215200241106a290200370300200341800f6a41086a2216200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c102200341c0076a41086a2202200341c90c6a290000370300200341c0076a41106a2217200341d10c6a290000370300200341c0076a41186a2218200341d90c6a290000370300200320032900c10c3703c0070240024002400240024020032d00c00c4101460d00200341f0096a41186a2018290300370300200341f0096a41106a2017290300370300200341f0096a41086a2002290300370300200320032903c0073703f009200341a00c6a41026a20092d00003a0000200320032f01a0013b01a00c2016200a2903003703002015200b290300370300200320032903c8023703800f0240024020040e03030100010b2006450d002007102e0b200320032903c0073703b801200341013a00c0110c020b200341023a00c0110240200541ff01714101470d002001450d002008102e0b20044102470d022006450d022007102e0c020b200341c0076a410d6a2202200341800f6a410d6a290000370000200341c0076a41086a2204200341800f6a41086a290300370300200341b8016a41086a22092004290300370300200341b8016a410d6a22042002290000370000200320032f01a00c3b01e801200320032903800f3703b8012003200341a20c6a2d00003a00ea01200320032d00ea013a00c20c200320032f01e8013b01c00c200320063600c70c200320073600c30c200341d80c6a2004290000370000200341d30c6a2009290300370000200320032903b8013700cb0c200341800f6a200341f0096a10840420032802800f220420032802880f108f022102024020032802840f450d002004102e0b024020020d00200341c0116a41061083040c010b200341c0076a200341c00c6a10d703200341800f6a20032802c007220420032802c80710860420034188026a41086a200341800f6a41086a29030037030020034188026a41106a200341800f6a41106a29030037030020034188026a41186a2206200341800f6a41186a290300370300200341bc076a41026a2207200341a30f6a2d00003a0000200341a00c6a41086a2209200341b40f6a290200370300200341a00c6a41106a220a200341bc0f6a290200370300200320032903800f37038802200320032f00a10f3b01bc072003200341ac0f6a2902003703a00c0240024020032d00a00f22024106460d00200341a80f6a280200210b200341a40f6a2802002115200341e8016a41086a20034188026a41136a290000370300200341f5016a22162006290000370000200341b8076a41026a20072d00003a0000200341f0046a41106a200a290300370300200341f0046a41086a2009290300370300200320032d008a023a008602200320032f0188023b01840220032003290093023703e801200320032f01bc073b01b807200320032903a00c3703f004200328008b022106200328008f022107024020032802c407450d002004102e0b200341a10f6a20032f01b8073b0000200341800f6a41136a200341e8016a41086a290300370000200341980f6a2016290000370000200341a30f6a200341ba076a2d00003a0000200320032d0086023a00820f200320032f0184023b01800f200320073600870f200320063600830f200320032903e80137008b0f200320023a00a00f200341a80f6a200b360200200341a40f6a2015360200200341ac0f6a20032903f004370200200341b40f6a200341f0046a41086a290300370200200341bc0f6a20034180056a290300370200200341800f6a200341f0096a412010ec082104024020024101470d00200b450d002015102e0b20040d01200341a10f6a20032f01d8013b0000200341a80f6a2001360200200341a40f6a2008360200200341ac0f6a200329039005370200200341800f6a41186a200341f0096a41186a290300370300200341800f6a41106a200341f0096a41106a290300370300200341800f6a41086a200341f0096a41086a290300370300200341a30f6a200341da016a2d00003a0000200341b40f6a20034190056a41086a290300370200200341bc0f6a20034190056a41106a290300370200200320032903f0093703800f200320053a00a00f200341c0076a200341c00c6a10d70320032802c007220120032802c807200341800f6a108b04024020032802c407450d002001102e0b024020032d00a00f4101470d0020032802a80f450d0020032802a40f102e0b200341063a00c0110c040b20032802c407450d002004102e0b200341c0116a41101083040b200541ff01714101470d002001450d002008102e0b20032d00c0114106460d0020032802c0112101200020032902c411370024200041206a2001360000200041186a41003a000020004200370308200042013703000c170b20004200370308200020032800a802360019200041186a41003a00002000411c6a200341ab026a280000360000200042003703000c160b200341b0016a41026a2209200141076a2d00003a0000200341c0116a41086a220a200141186a290200370300200341c0116a41106a220b200141206a2902003703002003200141056a2f00003b01b0012003200141106a2902003703c011200141046a2d00002105200141086a28020021072001410c6a2802002106200341d0016a41026a2001412b6a2d00003a0000200341c8026a41086a2001413c6a290200370300200341c8026a41106a200141c4006a2902003703002003200141296a2f00003b01d0012003200141346a2902003703c802200141286a2d000021042001412c6a2802002108200141306a2802002101200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a2215200241106a290200370300200341800f6a41086a2216200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c102200341c0076a41086a2202200341c90c6a290000370300200341c0076a41106a2217200341d10c6a290000370300200341c0076a41186a2218200341d90c6a290000370300200320032900c10c3703c007024002400240024020032d00c00c4101460d0020034190056a41186a201829030037030020034190056a41106a201729030037030020034190056a41086a2002290300370300200320032903c00737039005200341c0076a41026a20092d00003a0000200320032f01b0013b01c0072016200a2903003703002015200b290300370300200320032903c0113703800f0240024020050e03030100010b2006450d002007102e0b200320032903c00c3703b801200341013a00d8010c020b200341023a00d8010240200441ff01714101470d002001450d002008102e0b20054102470d022006450d022007102e0c020b200341c00c6a410d6a2202200341800f6a410d6a290000370000200341c00c6a41086a2205200341800f6a41086a290300370300200341b8016a41086a22092005290300370300200341b8016a410d6a22052002290000370000200320032f01c0073b01e801200320032903800f3703b8012003200341c2076a2d00003a00ea01200320032d00ea013a00f209200320032f01e8013b01f009200320063600f709200320073600f309200341880a6a2005290000370000200341830a6a2009290300370000200320032903b8013700fb09200341800f6a20034190056a10840420032802800f220520032802880f108f022102024020032802840f450d002005102e0b024020020d00200341d8016a41061083040c010b200341800f6a200341f0096a10d70320032802800f220520032802880f108f022102024020032802840f450d002005102e0b02402002450d00200341d8016a410e1083040c010b200341b8016a41026a220b200341d0016a41026a2d00003a0000200341e8016a41086a2215200341fb096a220241086a290000370300200341e8016a410d6a22162002410d6a290000370000200320032f01d0013b01b801200320032f01f0093b018402200320032d00f2093a008602200320022900003703e801200341c0076a41086a2217200341c8026a41086a290300370300200341c0076a41106a2218200341c8026a41106a290300370300200320032903c8023703c007200341a8026a20034190056a108704200341800f6a20032802a802220a20032802b00222191088040240024020032802900f22020d004200210c410021094101210241002105420021100c010b20032902940f220c422088a72105200ca72109200341800f6a41086a29030021102003419c0f6a280200211a20032903800f210c0b200341cc0c6a2001360200200341c00c6a41086a2008360200200341c00c6a41106a20032903c007370300200341d80c6a2017290300370300200341e00c6a2018290300370300200341ea0c6a20032d0086023a0000200320043a00c40c200320032f01b8013b00c50c2003200b2d00003a00c70c200320032f0184023b01e80c200320034190056a3602c00c200341ef0c6a2006360000200341eb0c6a2007360000200341f30c6a20032903e801370000200341fb0c6a2015290300370000200341800d6a201629000037000002400240024002400240200541e400490d00200341f0046a41011083040c010b200341800f6a20034190056a4280f19384eb05420010c302024020032d00800f22064106470d00200341800f6a41186a20034190056a41186a290300370300200341800f6a41106a20034190056a41106a290300370300200341800f6a41086a20034190056a41086a290300370300200341800f6a41286a200341c00c6a410472220141086a290200370300200341b00f6a200141106a290200370300200341b80f6a200141186a290200370300200341c00f6a200141206a28020036020020032003290390053703800f200320012902003703a00f200341a00c6a200341c00c6a41286a10d70320032802a00c220120032802a80c200341800f6a108b04024020032802a40c450d002001102e0b200341e80c6a2101024020032d00a00f4101470d00200341a80f6a280200450d00200341a40f6a280200102e0b20034188026a41186a2206200141186a220729020037030020034188026a41106a2208200141106a220b29020037030020034188026a41086a2215200141086a22162902003703002003200129020037038802024020052009470d00200941016a22042009490d11200941017422172004201720044b1b22044104200441044b1b220441ffffff3f712004462117200441057421040240024020090d00200341003602800f0c010b200341880f6a4101360200200320023602800f200320094105743602840f0b200341a00c6a20042017200341800f6a107d200341a80c6a2802002104024020032802a00c4101470d0020040d1b0c120b20032802a40c2102200441057621090b200220054105746a2204200329038802370000200441186a2006290300370000200441106a2008290300370000200441086a201529030037000020032802c00c2104200341d80f6a4200370300200341d00f6a4280f19384eb05370300200341800f6a41086a41073a0000200341890f6a2001290000370000200341910f6a2016290000370000200341990f6a200b290000370000200341a10f6a2007290000370000200341a90f6a2004290000370000200341b10f6a200441086a290000370000200341b90f6a200441106a290000370000200341c10f6a200441186a290000370000200341123a00800f200341800f6a10fe01200341063a00f004427f2010200c4280f19384eb057c220f200c542201ad7c221120012011201054200f200c5a1b22011b2110427f200f20011b210c200541016a21050c020b20032d00830f210720032f00810f210b200320032902840f3702f404200320063a00f0042003200b20074110747222063b00f104200320064110763a00f3040b0240200441ff01714101470d002001450d002008102e0b20032d00f0044106470d010b200341940f6a2005ad4220862009ad843702002003200c3703800f2003201a36029c0f200320023602900f200320103703880f0240024020020d00200a201910ff010c010b200a2019200341800f6a108a042002450d00200941ffffff3f71450d002002102e0b200341d8016a41086a200341f0046a41086a280200360200200320032903f0043703d8010c010b200341d8016a41086a200341f0046a41086a280200360200200320032903f0043703d801200941ffffff3f71450d002002102e0b20032802ac02450d01200a102e0c010b200441ff01714101470d002001450d002008102e0b024020032d00d8014106460d0020032802d8012101200020032902dc01370024200041206a2001360000200041186a41003a000020004200370308200042013703000c160b20004200370308200020032800a001360019200041186a41003a00002000411c6a200341a3016a280000360000200042003703000c150b200341b0016a41026a2207200141076a2d00003a0000200341a00c6a41086a2208200141186a290200370300200341a00c6a41106a2209200141206a2902003703002003200141056a2f00003b01b0012003200141106a2902003703a00c2001410c6a2802002104200141086a2802002106200141046a2d0000210520022802282101024002400240024002400240024020022d00000e0400010203020b20022d0001210220012001280200417f6a220a3602000240200a0d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a220a200a280200417f6a220a360200200a0d002001102e0b200241ff0171450d024110102c2202450d17200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1720014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220736020020070d012002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22072007280200417f6a220736020020070d012002102e0c010b200241046a2d0000210a200241086a280200210b2002410c6a280200211520012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200a41ff01710d00200b41017420154b0d020b4110102c2202450d16200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1620014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220736020020070d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22072007280200417f6a220736020020070d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b4102210120054102470d012004450d012006102e0c010b200341f0096a41026a20072d00003a0000200341800f6a41086a2008290300370300200341800f6a41106a2009290300370300200320032f01b0013b01f009200320032903a00c3703800f4101210102400240024020050e03000201020b200341c0076a41026a200341f0096a41026a2d00003a0000200341c00c6a41086a200341800f6a41086a290300370300200341c00c6a410d6a200341800f6a410d6a290000370000200320032f01f0093b01c007200320032903800f3703c00c410021010c010b2004450d002006102e0b2003419b026a200341c00c6a41086a29030037000020034188026a41186a2202200341cd0c6a290000370000200320032f01c0073b0188022003200436008f022003200636008b02200320032903c00c370093022003200341c2076a2d00003a008a02024020010d00200341c0116a41186a2002290300370300200341c0116a41106a20034188026a41106a290300370300200341c0116a41086a20034188026a41086a29030037030020032003290388023703c011200341c00c6a200341c0116a108704200341800f6a20032802c00c220220032802c80c22041088040240024020032802900f22010d00410121050c010b2002200410ff01200121050b20032903800f211020032902940f210c200341880f6a2903002111024020032802c40c450d002002102e0b200341b8016a200341c0116a108404200341800f6a20032802b801220220032802c0012206108504024020032d00a411220741024622040d002002200610ff010b200c420020011b210f20034190056a200341800f6a41a40210e9081a200341f0046a41176a2206200341bc116a280000360000200341f0046a41106a2208200341b5116a290000370300200341f0046a41086a2209200341ad116a290000370300200320032900a5113703f004024020040d00200341c8026a20034190056a41a40210e9081a200341a8026a41176a2006280000360000200341a8026a41106a2008290300370300200341a8026a41086a2009290300370300200320032903f0043703a802024020032802bc01450d002002102e0b2010420020011b210e2011420020011b210d200341f0096a41066a200341c8026a41a40210e9081a200341c0076a200341f0096a41aa0210e9081a20034188026a41176a2201200341a8026a41176a28000036000020034188026a41106a2202200341a8026a41106a29030037030020034188026a41086a2204200341a8026a41086a290300370300200320032903a80237038802200341c00c6a200341c0076a41066a41a40210e9081a200341c00c6a41a4026a20073a0000200341e50e6a200329038802370000200341ed0e6a2004290300370000200341f50e6a2002290300370000200341fc0e6a2001280000360000200341c00c6a41086a290300211220032903c00c211120032802d00c210602400240200341d80c6a280200220741057422020d004200210c420021100c010b200641106a21014200210c420021100340200141086a2903004200200141786a29030042015122041b20107c2001290300420020041b2210200c7c220c201054ad7c2110200141206a2101200241606a22020d000b0b2012200d7c2011200e7c220e201154ad7c20107c200e200c7c220d200e54ad7c210e0240200f4220882212a72201450d0020014105742102200521010340200341800f6a200110d70320032802800f220420032802880f10ff01024020032802840f450d002004102e0b200141206a2101200241606a22020d000b0b200341f0006a200341c0116a200d200e10cb022003290370210c2003200341f0006a41086a29030022103703880f2003200c3703800f200c2010844200520d032003200341800f6a3602f009200341f0096a10cc020c040b024020032802bc01450d002002102e0b200341800f6a4103108304200320032900810f3703e8012003200341880f6a2800003600ef0120032d00800f2101200f42ffffff3f83500d012005102e0c010b410121010b200320032800a0013602d001200320032903e8013703d801200320032800ef013600df012003200341a3016a2800003600d301200041186a41003a000020004200370308200020032802d0013600192000411c6a20032800d301360000200041206a20013a0000200020032903d801370021200041286a20032800df01360000200042013703000c160b200342f0f2bda1a7ee9cb9f9003703f009200341800f6a200341f0096a10cd02200341e0006a200341800f6a200c201010fd01200341800a6a200341e0006a41086a290300221320107d20032903602211200c54ad7d201020137d200c201154ad7d2011200c56201320105620132010511b22011b37030020032011200c7d200c20117d20011b3703f80920032001ad3703f009200341f0096a41086a21020240024020010d00200320023602c007200341c0076a10cc020c010b200320023602c007200341c0076a10ce020b200341980f6a2010370300200341900f6a200c370300200341880f6a41063a00002003410e3a00800f200341800f6a10fe010b200341b80f6a200e370300200341b00f6a200d370300200341800f6a41086a41023a0000200341890f6a20032903c011370000200341910f6a200341c0116a41086a290300370000200341990f6a200341d0116a290300370000200341a10f6a200341d8116a290300370000200341123a00800f200341800f6a10fe012007ad42e0d4037e201242f0fb8d017e7c200341e40c6a35020042e8077e7c20124280c2d72f7e7c210c200341dc0c6a21010240200341d40c6a28020041ffffff3f71450d002006102e0b200c4288babcd6017c210c200110e3030240200f42ffffff3f83500d002005102e0b200320032800a0013602d0012003200341a3016a2800003600d301200041186a41003a0000200041106a200c37030020004201370308200020032802d0013600192000411c6a20032800d301360000200042003703000c140b200141c0006a2903002110200141386a290300210f200141306a290300210c200141046a280200211741022104200341bc076a41026a22072001410b6a2d00003a0000200341b8016a41086a22082001411c6a290200370300200341b8016a41106a2209200141246a2902003703002003200141096a2f00003b01bc072003200141146a2902003703b801200141086a2d000021052001410c6a2802002106200141106a2802002101200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a220a200241106a290200370300200341800f6a41086a220b200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c102200341e8016a41086a2215200341c00c6a41146a290200370300200341f5016a2216200341d90c6a290000370000200320032f00c10c3b018402200320032d00c30c3a0086022003200341c00c6a410c6a2902003703e80141012102024002400240024002400240024002400240024020032d00c00c4101460d00200341c00c6a41086a280200210420032802c40c2118200341a00c6a41136a2015290300370000200341a00c6a41186a2016290000370000200320032d0086023a00a20c200320032f0184023b01a00c200320043600a70c200320183600a30c200320032903e8013700ab0c200341f0096a41026a20072d00003a0000200320032f01bc073b01f009200b2008290300370300200a2009290300370300200320032903b8013703800f02400240024020050e03000201020b200341c0076a41026a200341f0096a41026a2d00003a0000200341c00c6a41086a200341800f6a41086a290300370300200341c00c6a410d6a200341800f6a410d6a290000370000200320032f01f0093b01c007200320032903800f3703c00c410021020c010b2001450d002006102e0b20034188026a41136a200341c00c6a41086a29030037000020034188026a41186a2204200341cd0c6a290000370000200320032f01c0073b0188022003200136008f022003200636008b02200320032903c00c370093022003200341c2076a2d00003a008a0220020d02200341c0116a41186a2004290300370300200341c0116a41106a20034188026a41106a290300370300200341c0116a41086a20034188026a41086a29030037030020032003290388023703c011200c4201520d01200341800f6a4109108304200320032900810f3703d8012003200341880f6a2800003600df0120032d00800f21040c030b20054102470d022001450d022006102e0c020b200341c00c6a10810420032802c00c210102400240024020032802c80c20174d0d00200120174106746a22022903004201520d00200241206a200341a00c6a412010ec080d00024020032802c40c41ffffff1f71450d002001102e0b200341e8016a200341c0116a108404200341800f6a20032802e801220120032802f00110850420034190056a200341800f6a41a40210e9081a200341f0046a41086a2202200341ad116a290000370300200341f0046a41106a2204200341b5116a290000370300200341f0046a41176a2205200341bc116a280000360000200320032900a5113703f004024020032d00a41122064102460d00200341c8026a20034190056a41a40210e9081a200341a8026a41176a2005280000360000200341a8026a41106a2004290300370300200341a8026a41086a2002290300370300200320032903f0043703a802024020032802ec01450d002001102e0b200341f0096a41066a200341c8026a41a40210e9081a200341c0076a200341f0096a41aa0210e9081a20034188026a41176a2201200341a8026a41176a28000036000020034188026a41106a2202200341a8026a41106a29030037030020034188026a41086a2204200341a8026a41086a290300370300200320032903a80237038802200341c00c6a200341c0076a41066a41a40210e9081a200341c00c6a41a4026a20063a0000200341e50e6a200329038802370000200341ed0e6a2004290300370000200341f50e6a2002290300370000200341fc0e6a20012800003600004100210120032802d00c2106200341c00c6a41186a28020022070e020803020b024020032802ec01450d002001102e0b200341800f6a410b108304200320032900810f3703d8012003200341880f6a2800003600df0120032d00800f21040c040b200341800f6a410a108304200320032900810f3703d8012003200341880f6a2800003600df0120032d00800f210420032802c40c41ffffff1f71450d032001102e0c030b4100210120072102034020012002410176220420016a2205200620054105746a28020020174b1b2101200220046b220241014b0d000c040b0b4100210120062102200628020022042017470d030c060b410121040b200320032800d0013602b001200320032903d8013703a001200320032800df013600a7012003200341d3016a2800003600b301200041186a41003a000020004200370308200020032802b0013600192000411c6a20032800b301360000200041206a20043a0000200020032903a001370021200041286a20032800a701360000200042013703000c190b200620014105746a220228020022042017460d020b200120042017496a21010b200341800f6a41186a2010370300200341800f6a41106a200f3703002003200c3703880f200320173602800f200341c00c6a41106a2001200341800f6a10ba0120032802d80c21070c020b200720014b0d00200120074180afc400103c000b200620014105746a220141086a2104024020012903084201520d00200341800f6a200341c0116a200341a00c6a200141106a290300200141186a29030041001089040b2004200c37030020022017360200200141186a2010370300200141106a200f3703000b200341e40c6a350200210c200341800f6a200341c00c6a41c00210e9081a200341c0076a200341c0116a10840420032802c807210220032802c0072101200341003602f809200342013703f009200341800f6a200341f0096a10e9032001200220032802f009220420032802f80910b201024020032802f409450d002004102e0b024020032802c407450d002001102e0b0240200341940f6a28020041ffffff3f71450d0020032802900f102e0b200341800f6a411c6a10e303200341800f6a41086a41053a0000200341890f6a20032903c011370000200341910f6a200341c0116a41086a290300370000200341990f6a200341c0116a41106a290300370000200341a10f6a200341c0116a41186a290300370000200341ac0f6a2017360200200341123a00800f200341800f6a10fe01200320032800d0013602b0012003200341d3016a2800003600b301200041186a41003a0000200041106a2007ad42c08b117e200c42e8fcd6007e7c42a8d793d9007c37030020004201370308200020032802b0013600192000411c6a20032800b301360000200042003703000c130b200141086a290300210c200141046a2802002104200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a200241106a290200370300200341800f6a41086a200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c102200341e8016a41086a2201200341d40c6a290200370300200341f5016a2202200341d90c6a290000370000200320032f00c10c3b018402200320032d00c30c3a0086022003200341cc0c6a2902003703e8010240024020032d00c00c4101460d00200341c00c6a41086a280200210520032802c40c2106200341830a6a2001290300370000200341f0096a41186a2002290000370000200320032d0086023a00f209200320032f0184023b01f009200320053600f709200320063600f309200320032903e8013700fb09200341c0076a1081040240024020032802c807220120044d0d0020032802c007220520044106746a22022903004201520d00200241206a200341f0096a412010ec080d00200520044106746a200c370318410021020c010b200341800f6a410a108304024020032d00800f22024106470d00410021020c010b20032902840f210c20032f00810f20032d00830f411074724108742002722101410121020b200341c00c6a41086a200341c0076a41086a280200360200200320032903c00722103703c00c024002402010a722040d00200341a0026a2204420037030020034198026a2205420037030020034188026a41086a220642003703002003420037038802200341800f6a4188fec60041081081022006200341800f6a41086a2207290000370300200320032900800f37038802200341800f6a41b0afc300410a10810220042007290000370300200520032900800f37030020034188026a412010ff010c010b200341a0026a2205420037030020034198026a2206420037030020034188026a41086a220742003703002003420037038802200341800f6a4188fec60041081081022007200341800f6a41086a2208290000370300200320032900800f37038802200341800f6a41b0afc300410a10810220052008290000370300200620032900800f37030020034188026a200341c00c6a10820420032802c40c41ffffff1f71450d002004102e0b20020d0120032003280090053602c802200320034193056a2800003600cb02200041186a41003a0000200041106a2001ad42f0f5127e4290ddb83f7c37030020004201370308200020032802c8023600192000411c6a20032800cb02360000200042003703000c140b410221010b20032003280090053602c802200320034193056a2800003600cb02200041186a41003a000020004200370308200020032802c8023600192000411c6a20032800cb02360000200041246a200c370200200041206a2001360200200042013703000c120b200141246a280200210541022104200341a00c6a41026a2206200141036a2d00003a0000200341c0076a41086a2207200141146a290000370300200341c0076a410d6a2208200141196a290000370000200320012f00013b01a00c20032001410c6a2900003703c007200141046a2800002109200141086a280000210a200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a200241106a290200370300200341800f6a41086a200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c102200341b8016a41086a2201200341c00c6a41146a290200370300200341b8016a410d6a2202200341c00c6a41196a290000370000200320032f00c10c3b01e801200320032d00c30c3a00ea012003200341c00c6a410c6a2902003703b8010240024020032d00c00c4101460d00200341c00c6a41086a280200210420032802c40c210b200341830a6a2001290300370000200341f0096a41186a2002290000370000200320032d00ea013a00f209200320032f01e8013b01f009200320043600f7092003200b3600f309200320032903b8013700fb0920034190056a108104200341e8016a41086a2007290300370300200341e8016a410d6a2008290000370000200320032f01a00c3b018402200320062d00003a008602200320032903c0073703e80102400240200328029805220420054d0d0020032802900520054106746a22012903004201520d002003419b026a200341e8016a41086a29030037000020034188026a41186a2202200341f5016a290000370000200320032d0086023a008a02200320032f0184023b0188022003200a36008f022003200936008b02200320032903e80137009302200141206a2201200341f0096a412010ec080d002001200329038802370200200141186a2002290300370200200141106a20034188026a41106a290300370200200141086a20034188026a41086a290300370200410021010c010b200341800f6a410a108304024020032d00800f22014106470d00410021010c010b20032902840f210c20032f00810f20032d00830f411074724108742001722104410121010b200341c00c6a41086a20034190056a41086a280200360200200320032903900522103703c00c024002402010a722020d00200341a0026a2202420037030020034198026a2205420037030020034188026a41086a220642003703002003420037038802200341800f6a4188fec60041081081022006200341800f6a41086a2207290000370300200320032900800f37038802200341800f6a41b0afc300410a10810220022007290000370300200520032900800f37030020034188026a412010ff010c010b200341a0026a2205420037030020034198026a2206420037030020034188026a41086a220742003703002003420037038802200341800f6a4188fec60041081081022007200341800f6a41086a2208290000370300200320032900800f37038802200341800f6a41b0afc300410a10810220052008290000370300200620032900800f37030020034188026a200341c00c6a10820420032802c40c41ffffff1f71450d002002102e0b20010d01200320032800c8023602c0112003200341cb026a2800003600c311200041186a41003a0000200041106a2004ad42f89c137e42a8adef3f7c37030020004201370308200020032802c0113600192000411c6a20032800c311360000200042003703000c130b0b200320032800c8023602c0112003200341cb026a2800003600c311200041186a41003a000020004200370308200020032802c0113600192000411c6a20032800c311360000200041246a200c370200200041206a2004360200200042013703000c110b200141106a290300210c200141086a2903002110200141046a2802002104200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a200241106a290200370300200341800f6a41086a200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c102200341e8016a41086a2201200341d40c6a290200370300200341f5016a2202200341d90c6a290000370000200320032f00c10c3b018402200320032d00c30c3a0086022003200341cc0c6a2902003703e8010240024020032d00c00c4101460d00200341c00c6a41086a280200210520032802c40c2106200341830a6a2001290300370000200341f0096a41186a2002290000370000200320032d0086023a00f209200320032f0184023b01f009200320053600f709200320063600f309200320032903e8013700fb09200341c0076a1081040240024020032802c807220120044d0d0020032802c00720044106746a22022903004201520d00200241206a200341f0096a412010ec080d00200241086a220220103703002002200c370308410021020c010b200341800f6a410a108304024020032d00800f22024106470d00410021020c010b20032902840f210c20032f00810f20032d00830f411074724108742002722101410121020b200341c00c6a41086a200341c0076a41086a280200360200200320032903c00722103703c00c024002402010a722040d00200341a0026a2204420037030020034198026a2205420037030020034188026a41086a220642003703002003420037038802200341800f6a4188fec60041081081022006200341800f6a41086a2207290000370300200320032900800f37038802200341800f6a41b0afc300410a10810220042007290000370300200520032900800f37030020034188026a412010ff010c010b200341a0026a2205420037030020034198026a2206420037030020034188026a41086a220742003703002003420037038802200341800f6a4188fec60041081081022007200341800f6a41086a2208290000370300200320032900800f37038802200341800f6a41b0afc300410a10810220052008290000370300200620032900800f37030020034188026a200341c00c6a10820420032802c40c41ffffff1f71450d002004102e0b20020d0120032003280090053602c802200320034193056a2800003600cb02200041186a41003a0000200041106a2001ad42a0e6127e42e0efb73f7c37030020004201370308200020032802c8023600192000411c6a20032800cb02360000200042003703000c120b410221010b20032003280090053602c802200320034193056a2800003600cb02200041186a41003a000020004200370308200020032802c8023600192000411c6a20032800cb02360000200041246a200c370200200041206a2001360200200042013703000c100b200141046a2802002106200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a200241106a290200370300200341800f6a41086a200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c10220034188026a41086a2201200341c90c6a29000037030020034188026a41106a2202200341d10c6a29000037030020034188026a41186a2204200341d90c6a290000370300200320032900c10c3703880202400240024002400240024002400240024020032d00c00c4101460d00200341c0116a41186a2004290300370300200341c0116a41106a2002290300370300200341c0116a41086a200129030037030020032003290388023703c011200341a00c6a200341c0116a108404200341800f6a20032802a00c220120032802a80c10850420034190056a200341800f6a41a40210e9081a200341f0046a41086a200341ad116a290000370300200341f0046a41106a200341b5116a290000370300200341f0046a41176a2202200341bc116a280000360000200320032900a5113703f004024020032d00a41122044102460d00200341c8026a20034190056a41a40210e9081a200341a8026a41176a2002280000360000200341a8026a41106a2202200341f0046a41106a290300370300200341a8026a41086a2205200341f0046a41086a290300370300200320032903f0043703a802024020032802a40c450d002001102e0b200341f0096a41066a200341c8026a41a40210e9081a200341c0076a200341f0096a41aa0210e9081a20034188026a41176a2201200341a8026a41176a28000036000020034188026a41106a2207200229030037030020034188026a41086a22022005290300370300200320032903a80237038802200341c00c6a200341c0076a41066a41a40210e9081a200341c00c6a41a4026a20043a0000200341e50e6a200329038802370000200341ed0e6a2002290300370000200341f50e6a2007290300370000200341fc0e6a200128000036000020032802d00c2107200341d80c6a28020022080e020403020b024020032802a40c450d002001102e0b200341800f6a4106108304200320032900810f3703b8012003200341880f6a2800003600bf0120032d00800f21010c070b410221010c060b4100210120082102034020012002410176220420016a2205200720054105746a28020020064b1b2101200220046b220241014b0d000b200720014105746a2802002006470d01200820014d0d020c030b4100210120072802002006460d020b200341800f6a4102108304200320032900810f3703b8012003200341880f6a2800003600bf010c020b200120081046000b200720014105746a220241186a2903002110200241106a290300210f2002290308210c2002200241206a20082001417f736a41057410ea081a20032008417f6a22013602d80c200c4201510d02200341800f6a4108108304200320032900810f3703b8012003200341800f6a41086a2800003600bf010b20032d00800f21010240200341d40c6a28020041ffffff3f71450d002007102e0b200341dc0c6a10e3030b200320032800d8013602a001200320032903b8013703e801200320032800bf013600ef012003200341db016a2800003600a301200041186a41003a000020004200370308200020032802a0013600192000411c6a20032800a301360000200041206a20013a0000200020032903e801370021200041286a20032800ef01360000200042013703000c100b200341d0006a200341c0116a200f201010fb01200341e40c6a350200210c200341800f6a200341c00c6a41c00210e9081a200341c0076a200341c0116a10840420032802c807210420032802c0072102200341003602f809200342013703f009200341800f6a200341f0096a10e9032002200420032802f009220520032802f80910b201024020032802f409450d002005102e0b024020032802c407450d002002102e0b0240200341940f6a28020041ffffff3f71450d0020032802900f102e0b200341800f6a411c6a10e303200341800f6a41086a41043a0000200341890f6a20032903c011370000200341910f6a200341c0116a41086a290300370000200341990f6a200341c0116a41106a290300370000200341a10f6a200341c0116a41186a290300370000200341ac0f6a2006360200200341123a00800f200341800f6a10fe01200320032800d8013602a0012003200341db016a2800003600a301200041186a41003a0000200041106a2001ad4288800d7e200c42c0b6d6007e7c42e8dfb4d4007c37030020004201370308200020032802a0013600192000411c6a20032800a301360000200042003703000c0f0b200141106a290300210c200141086a2903002110200141046a2802002101200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a200241106a290200370300200341800f6a41086a200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c10220034188026a41086a2202200341c90c6a29000037030020034188026a41106a2204200341d10c6a29000037030020034188026a41186a2205200341d90c6a290000370300200320032900c10c37038802024002400240024002400240024002400240024002400240024020032d00c00c4101460d00200341c0116a41186a2005290300370300200341c0116a41106a2004290300370300200341c0116a41086a200229030037030020032003290388023703c011200341b8016a10810420032802b801210420032802c00120014d0d01200420014106746a22022903004201520d0102402002290308201056200241106a2903002210200c562010200c511b450d00200341800f6a410510830420032f00810f20032d00830f4110747221010c0b0b200341a00c6a200341c0116a108404200341800f6a20032802a00c220520032802a80c10850420034190056a200341800f6a41a40210e9081a200341f0046a41086a200341ad116a290000370300200341f0046a41106a200341b5116a290000370300200341f0046a41176a2206200341bc116a280000360000200320032900a5113703f00402400240024020032d00a41122074102460d00200241086a2109200341c8026a20034190056a41a40210e9081a200341a8026a41176a2006280000360000200341a8026a41106a2202200341f0046a41106a290300370300200341a8026a41086a2206200341f0046a41086a290300370300200320032903f0043703a802024020032802a40c450d002005102e0b200341f0096a41066a200341c8026a41a40210e9081a200341c0076a200341f0096a41aa0210e9081a20034188026a41176a2205200341a8026a41176a28000036000020034188026a41106a2208200229030037030020034188026a41086a22022006290300370300200320032903a80237038802200341c00c6a200341c0076a41066a41a40210e9081a200341c00c6a41a4026a20073a0000200341e50e6a200329038802370000200341ed0e6a2002290300370000200341f50e6a2008290300370000200341fc0e6a2005280000360000200941086a290300210c200929030021104100210220032802d00c2108200341c00c6a41186a280200220a0e020702010b024020032802a40c450d002005102e0b200341800f6a410610830420032f00810f20032d00830f4110747221010c0c0b41002102200a2105034020022005410176220620026a2207200820074105746a28020020014b1b2102200520066b220541014b0d000c040b0b4100210220082106200828020022052001470d030c060b410221020c0b0b200341800f6a410410830420032f00810f20032d00830f4110747221010c080b200820024105746a220628020022052001460d020b200220052001496a21020b200341800f6a41186a200c370300200341900f6a2010370300200342013703880f200320013602800f200341c00c6a41106a2002200341800f6a10ba010c020b200a20024b0d002002200a41f0aec400103c000b02400240200820024105746a2202280208417f6a0e06000101010100010b200341800f6a410710830420032f00810f20032d00830f41107472210120032902840f210c20032d00800f21020c020b200241086a420137030020062001360200200241186a200c370300200241106a20103703000b200341800f6a200341c0116a2009290300200941086a29030010c30220032d00800f22024106460d0120032f00810f20032d00830f41107472210120032902840f210c0b0240200341d40c6a28020041ffffff3f71450d0020032802d00c102e0b200341dc0c6a10e3030c020b200341e40c6a350200210c20033502d80c2110200341800f6a200341c00c6a41c00210e9081a200341c0076a200341c0116a10840420032802c807210520032802c0072102200341003602f809200342013703f009200341800f6a200341f0096a10e9032002200520032802f009220620032802f80910b201024020032802f409450d002006102e0b024020032802c407450d002002102e0b0240200341940f6a28020041ffffff3f71450d0020032802900f102e0b200341800f6a411c6a10e303200341800f6a41086a41033a0000200341890f6a20032903c011370000200341910f6a200341c0116a41086a290300370000200341990f6a200341c0116a41106a290300370000200341a10f6a200341c0116a41186a290300370000200341ac0f6a2001360200200341123a00800f201042e0a4137e200c4290c3d7007e7c42c8a3e7e2007c210c200341800f6a10fe01024020032802bc0141ffffff1f71450d002004102e0b200320032800e8013602d8012003200341e8016a41036a2800003600db01200041186a41003a0000200041106a200c37030020004201370308200020032802d8013600192000411c6a20032800db01360000200042003703000c110b20032902840f210c20032d00800f21020b20032802bc0141ffffff1f71450d002004102e0b200320032800e8013602d8012003200341eb016a2800003600db01200041236a20014110763a0000200020013b0021200041186a41003a000020004200370308200020032802d8013600192000411c6a20032800db013600002000200c370024200041206a20023a0000200042013703000c0e0b200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a200241106a290200370300200341800f6a41086a200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c10220034188026a41086a2201200341c90c6a29000037030020034188026a41106a2202200341d10c6a29000037030020034188026a41186a2204200341d90c6a290000370300200320032900c10c37038802410121050240024020032d00c00c4101460d00200341c0116a41186a2004290300370300200341c0116a41106a2002290300370300200341c0116a41086a200129030037030020032003290388023703c011200341c00c6a200341c0116a108704200341800f6a20032802c00c220220032802c80c2204108804024020032802900f2201450d002002200410ff01200121050b20032903800f211020032902940f210c200341880f6a2903002111024020032802c40c450d002002102e0b200341a00c6a200341c0116a108404200341800f6a20032802a00c220220032802a80c2206108504024020032d00a411220741024622040d002002200610ff010b200c420020011b210f20034190056a200341800f6a41a40210e9081a200341f0046a41176a2206200341bc116a280000360000200341f0046a41106a2208200341b5116a290000370300200341f0046a41086a2209200341ad116a290000370300200320032900a5113703f004024020040d00200341c8026a20034190056a41a40210e9081a200341a8026a41176a2006280000360000200341a8026a41106a2008290300370300200341a8026a41086a2009290300370300200320032903f0043703a802024020032802a40c450d002002102e0b2010420020011b210e2011420020011b210d200341f0096a41066a200341c8026a41a40210e9081a200341c0076a200341f0096a41aa0210e9081a20034188026a41176a2201200341a8026a41176a28000036000020034188026a41106a2202200341a8026a41106a29030037030020034188026a41086a2204200341a8026a41086a290300370300200320032903a80237038802200341c00c6a200341c0076a41066a41a40210e9081a200341c00c6a41a4026a20073a0000200341e50e6a200329038802370000200341ed0e6a2004290300370000200341f50e6a2002290300370000200341fc0e6a2001280000360000200341c00c6a41086a290300211220032903c00c211120032802d00c210602400240200341d80c6a280200220741057422020d004200210c420021100c010b200641106a21014200210c420021100340200141086a2903004200200141786a29030042015122041b20107c2001290300420020041b2210200c7c220c201054ad7c2110200141206a2101200241606a22020d000b0b2012200d7c2011200e7c220e201154ad7c20107c200e200c7c220c200e54ad7c21100240200f4220882211a72201450d0020014105742102200521010340200341800f6a200110d70320032802800f220420032802880f10ff01024020032802840f450d002004102e0b200141206a2101200241606a22020d000b0b200341c0006a200341c0116a200c201010fb01200341b80f6a2010370300200341b00f6a200c370300200341800f6a41086a41013a0000200341890f6a20032903c011370000200341910f6a200341c0116a41086a290300370000200341990f6a200341d0116a290300370000200341a10f6a200341d8116a290300370000200341123a00800f200341800f6a10fe012007ad42a084097e201142b0ba8e017e7c200341e40c6a35020042d8ac2d7e7c20114280c2d72f7e7c210c200341dc0c6a21010240200341d40c6a28020041ffffff3f71450d002006102e0b200c42d0faca90017c210c200110e3030240200f42ffffff3f83500d002005102e0b200320032800d8013602a0012003200341db016a2800003600a301200041186a41003a0000200041106a200c37030020004201370308200020032802a0013600192000411c6a20032800a301360000200042003703000c100b024020032802a40c450d002002102e0b200341800f6a4103108304200320032900810f3703b8012003200341880f6a2800003600bf0120032d00800f2101200f42ffffff3f83500d012005102e0c010b410221010b200320032800d8013602a001200320032903b8013703e801200320032800bf013600ef012003200341db016a2800003600a301200041186a41003a000020004200370308200020032802a0013600192000411c6a20032800a301360000200041206a20013a0000200020032903e801370021200041286a20032800ef01360000200042013703000c0d0b2001410c6a2802002107200141086a2802002108200141046a280200211b200341800f6a41286a200241286a280200360200200341800f6a41206a200241206a290200370300200341800f6a41186a200241186a290200370300200341800f6a41106a200241106a290200370300200341800f6a41086a200241086a290200370300200320022902003703800f200341c00c6a200341800f6a10c102200341b8016a41086a2201200341d40c6a290200370300200341c5016a2202200341d90c6a290000370000200320032f00c10c3b01e801200320032d00c30c3a00ea012003200341c00c6a410c6a2902003703b801024020032d00c00c4101460d00200341c00c6a41086a280200210420032802c40c2105200341d3076a2001290300370000200341c0076a41186a2002290000370000200320032d00ea013a00c207200320032f01e8013b01c007200320043600c707200320053600c307200320032903b8013700cb07200341800f6a200341c0076a10840420032802800f220220032802880f108f022101024020032802840f450d002002102e0b024020010d00200341800f6a410210830420032f00810f20032d00830f4110747221040c040b0240200741e500490d00200341800f6a410110830420032f00810f20032d00830f4110747221040c040b200341c00c6a200341c0076a108704200341800f6a20032802c00c220120032802c80c108804200341800f6a41086a290300210f20032802900f211c20032903800f211020032902940f210c024020032802c40c450d002001102e0b200c4200201c1b210d201c4101201c1b211d200341306a2007ad42004280f19384eb05420010e808200341306a41086a29030021112003290330210e0240200741c4006c2205450d00200341ac0f6a2101200341a10f6a2104200341800f6a410b6a210a20034188026a410b6a210b201b21020340200341c00c6a200210d703200341800f6a20032802c00c220920032802c80c10860420034188026a41086a200341800f6a41086a29030037030020034188026a41106a200341800f6a41106a29030037030020034188026a41186a200341800f6a41186a290300370300200341bc076a41026a2215200441026a22162d00003a0000200341a00c6a41086a2217200141086a2218290000370300200341a00c6a41106a2219200141106a221a290000370300200320032903800f37038802200320042f00003b01bc07200320012900003703a00c0240024020032d00a00f22064106460d0020032802a80f211e20032802a40f211f200341e8016a41086a2220200b41086a290000370300200341e8016a410d6a2221200b410d6a290000370000200341b8076a41026a222220152d00003a0000200341f0046a41106a22152019290300370300200341f0046a41086a22192017290300370300200320032d008a023a008602200320032f0188023b018402200320032f01bc073b01b807200320032903a00c3703f0042003200b2900003703e801200328008b022117200328008f022123024020032802c40c450d002009102e0b200a20032903e801370000200420032f01b8073b0000200a41086a2020290300370000200a410d6a2021290000370000201620222d00003a0000200320032d0086023a00820f200320032f0184023b01800f200320233600870f200320173600830f200320063a00a00f200120032903f00437000020182019290300370000201a20152903003700002003201e3602a80f2003201f3602a40f200341800f6a200341c0076a412010ec082109024020064101470d00201e450d00201f102e0b2009450d01200341800f6a410e10830420032f00810f20032d00830f41107472210420032902840f210c20032d00800f21050c060b20032802c40c450d002009102e0b200241c4006a2102200541bc7f6a22050d000b0b0240024020104200201c1b2210200e5a200f4200201c1b220c20115a200c20115122011b0d00200341800f6a200341c0076a200e20107d2011200c7d200e201054ad7d10c30220032d00800f22054106460d0120032f00810f20032d00830f41107472210420032902840f210c0c040b2010200e58200c20115820011b0d00200341206a200341c0076a2010200e7d200c20117d2010200e54ad7d10fb010b0240200d4220882212a72201450d0020014105742102201d21010340200341800f6a200110d70320032802800f220420032802880f10ff01024020032802840f450d002004102e0b200141206a2101200241606a22020d000b0b200741c4006c220441c4006d220141ffffff3f712001470d0120014105742202417f4c0d010240024020020d00410121240c010b2002102c2224450d0b0b02400240024002402002410576222520014f0d00200241047622052001200520014b1b22054104200541044b1b220541ffffff3f712005462106200541057421050240024020020d00200341003602800f0c010b200341880f6a4101360200200320023602840f200320243602800f0b200341c00c6a20052006200341800f6a107d200341c80c6a280200210220032802c00c4101460d0120032802c40c2124200241057621250b201b20046a2226201b470d0141002106201b21050c020b20020d0c0c030b2007410274417c6a41027641016a2127200341800f6a41216a210441002106200341c00c6a411f6a2107201b21012024210202400340200141186a290200210c200141176a2d00002109200141166a2d0000210a200141146a2f0100210b200141136a2d00002115200141126a2d00002116200141106a2f010021172001410f6a2d000021182001410e6a2d000021192001410c6a2f0100211a2001410b6a2d0000211e2001410a6a2d0000211f200141086a2f01002120200141076a2d00002121200141066a2d00002122200141046a2f01002123200141036a2d0000211c200141026a2d00002128200141206a2d0000210520012f010021292007200141c0006a280000360000200341c00c6a41186a222a200141396a290000370300200341c00c6a41106a222b200141316a290000370300200341c00c6a41086a222c200141296a2900003703002003200141216a2900003703c00c024020054106470d00200141c4006a21050c020b2003200c3703880a200320093a00870a2003200a3a00860a2003200b3b01840a200320153a00830a200320163a00820a200320173b01800a200320183a00ff09200320193a00fe092003201a3b01fc092003201e3a00fb092003201f3a00fa09200320203b01f809200320213a00f709200320223a00f609200320233b01f4092003201c3a00f309200320283a00f209200320293b01f009200341800f6a41186a200341c0076a41186a290300370300200341800f6a41106a200341c0076a41106a290300370300200341800f6a41086a200341c0076a41086a290300370300200420032903c00c370000200441086a202c290300370000200441106a202b290300370000200441186a202a2903003700002004411f6a2007280000360000200320032903c0073703800f200320053a00a00f20034190056a200341f0096a10d7032003280290052205200328029805200341800f6a108b040240200328029405450d002005102e0b024020032d00a00f4101470d0020032802a80f450d0020032802a40f102e0b200341f0096a41086a290300210c200341f0096a41106a290300211020032903f009210f200241186a200341f0096a41186a290300370000200241106a2010370000200241086a200c3700002002200f370000200641016a2106200241206a2102200141c4006a22012026470d000b20262105202721060b202620056b220441c4006d21010b02402004450d00200141c4006c2102200541286a210103400240200141786a2d00004101470d002001280200450d002001417c6a280200102e0b200141c4006a2101200241bc7f6a22020d000b0b02402008450d00200841c4006c450d00201b102e0b0240024020060d00200341800f6a200341c0076a10870420032802800f220120032802880f10ff01024020032802840f450d002001102e0b201242e0aa8e017e20124280c2d72f7e7c4290cf9fb8017c210c2025450d012024102e0c010b200341f0096a200341c0076a10870420064105744114722201417f4c0d0220032802f809210520032802f00921042001102c2202450d0b200341003602c80c200320013602c40c200320023602c00c200320113703880f2003200e3703800f200341c00c6a200341800f6a411010742006200341c00c6a107620064105742102202421010340200341c00c6a200141201074200141206a2101200241606a22020d000b2004200520032802c00c220120032802c80c10b201024020032802c40c450d002001102e0b024020032802f409450d002004102e0b02402025450d002024102e0b201242e0aa8e017e20124280c2d72f7e7c2006ad220c42b8fea8037e200c42c0f0f50b7e7c200c4280c2d72f7e7c7c4290cf9fb8017c210c0b0240200d42ffffff3f83500d00201d102e0b200320032800c8023602c0112003200341cb026a2800003600c311200041186a41003a0000200041106a200c37030020004201370308200020032802c0113600192000411c6a20032800c311360000200042003703000c0d0b410221050c030b1038000b200d42ffffff3f83500d01201d102e0c010b20032902840f210c20032d00800f21050b02402007450d00200741c4006c2102201b41286a210103400240200141786a2d00004101470d002001280200450d002001417c6a280200102e0b200141c4006a2101200241bc7f6a22020d000b0b02402008450d00200841c4006c450d00201b102e0b200320032800c8023602c0112003200341cb026a2800003600c311200041236a20044110763a0000200020043b0021200041186a41003a000020004200370308200020032802c0113600192000411c6a20032800c3113600002000200c370024200041206a20053a0000200042013703000c080b410221020b200341f0096a10e3030c020b024020032802c411450d002001102e0b200341d80c6a410036020042002111200342003703c80c200342003703c00c200342083703d00c200341dc0c6a200341f0096a41a00210e9081a420021100b2003200f4280fad5d5f2057c220c3703c00c2003200e200c200f54ad7c220f3703c80c0240200c201158200f201058200f20105122011b0d00200341800f6a200341c0076a200c20117d200f20107d200c201154ad7d10c30220032d00800f22024106460d0020032d00830f411074210120032f00810f210420032902840f210c0240200341d40c6a28020041ffffff3f71450d0020032802d00c102e0b20042001722101200341dc0c6a10e3030c010b02402011200c582010200f5820011b0d002003200341c0076a2011200c7d2010200f7d2011200c54ad7d10fb010b200341d80c6a350200210c200341800f6a200341c00c6a41c00210e9081a200341c8026a200341c0076a10840420032802d002210220032802c802210120034100360298052003420137039005200341800f6a20034190056a10e90320012002200328029005220420032802980510b2010240200328029405450d002004102e0b024020032802cc02450d002001102e0b0240200341940f6a28020041ffffff3f71450d0020032802900f102e0b200341800f6a411c6a10e303200341800f6a41086a41003a0000200341890f6a20032903c007370000200341910f6a200341c0076a41086a290300370000200341990f6a200341c0076a41106a290300370000200341a10f6a200341c0076a41186a290300370000200341123a00800f200341800f6a10fe01200320032800a00c3602b8012003200341a30c6a2800003600bb01200041186a41003a0000200041106a200c4288f70f7e200d4280aec4007e7c4280e7a9d6007c37030020004201370308200020032802b8013600192000411c6a20032800bb01360000200042003703000c040b200320032800a00c3602b8012003200341a30c6a2800003600bb01200041236a20014110763a0000200020013b0021200041186a41003a000020004200370308200020032802b8013600192000411c6a20032800bb013600002000200c370024200041206a20023a0000200042013703000c030b1036000b0b200320032800c8023602c0112003200341cb026a2800003600c311200041186a41003a000020004200370308200020032802c0113600192000411c6a20032800c311360000200041286a2001360200200041246a2002360200200041206a2004360200200042013703000b200341e0116a24000bca0a06067f017e037f017e047f067e230041f0016b22012400200141206a22024200370300200141186a22034200370300200141086a41086a420037030020014200370308200141086a4188fec6004108108102200141c8016a41b0afc300410a1081022002200141c8016a41086a290000370300200320012900c8013703002001412036022c2001200141086a360228200141306a200141086a412010ed02024002400240200128023022040d00410021030c010b200128023421052001200141306a41086a280200360244200120043602402001200141c0006a10ab010240024020012802000d00024002402001280204220620012802444106762202200220064b1b22024106742203417f4c0d000240024020020d00410821030c010b2003102c2203450d060b2002ad2107024002402006450d00200141c8016a4101722108034020012802442202450d04200128024022092d0000210a20012002417f6a3602442001200941016a3602404200210b02400240200a0e020100060b200141c8016a200141c0006a10930120012d00c8014101460d05200141a8016a41186a220c200841186a290000370300200141a8016a41106a220d200841106a290000370300200141a8016a41086a220e200841086a290000370300200120082900003703a801200128024422024110490d0520012001280240220941106a220a3602402001200241706a220f360244200f4108490d05200941086a2900002110200929000021112001200241686a3602442001200a41086a360240200a290000220b4280025a0d0520014188016a41186a200c29030037030020014188016a41106a200d29030037030020014188016a41086a200e290300370300200120012903a80137038801200b42ff018321124201210b0b200141e8006a41186a20014188016a41186a2903002213370300200141e8006a41106a20014188016a41106a2903002214370300200141e8006a41086a20014188016a41086a2903002215370300200141c8006a41086a22092015370300200141c8006a41106a220a2014370300200141c8006a41186a220f20133703002001200129038801221337036820012013370348024020074220882213a722022007a7470d00200241016a220c2002490d042002410174220d200c200c200d491b220c4104200c41044b1b220c41ffffff1f71200c46410374210d200c410674210c0240024020020d00200141003602c8010c010b200141083602d001200120033602c801200120134206863e02cc010b200141a8016a200c200d200141c8016a107d20012802b001210c20012802a8014101460d0320012802ac012103200742808080807083200c410676ad8421070b200320024106746a220220113703082002200b370300200241106a2010370300200241186a2012370300200241206a2001290348370300200241286a2009290300370300200241306a200a290300370300200241386a200f29030037030020074280808080107c21072006417f6a22060d000b0b2003450d030c040b200c0d050b1038000b0240200742ffffff1f83500d002003102e0b0b41002103200141003602b001200142013703a8012001410a36028c012001200141286a360288012001200141a8016a360268200141dc016a4101360200200142013702cc01200141909dc5003602c801200120014188016a3602d801200141e8006a419cebc000200141c8016a103d1a20012802a80120012802b00110ef0220012802ac01450d0020012802a801102e0b2005450d002004102e0b0240024020030d0020004100360208200042083702000c010b20002007370204200020033602000b200141f0016a24000f0b1036000b8b0101047f230041106b2202240002400240200128020822034106744104722204417f4c0d00200128020021012004102c2205450d01200241003602082002200436020420022005360200200320021076200120032002109a012000412020022802002201200228020810b20102402002280204450d002001102e0b200241106a24000f0b1038000b1036000bd80301047f230041c0006b2202240041bbebc2002103410f21044108210502400240024002400240024002400240024002400240024002400240024002400240200141ff01710e11000102030405060708090a0b0c0d0e0f10000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a4198a6cc001044000b41a9ebc200210341122105410021040c0e0b418be7c400210341012104410821050c0d0b41a1ebc200210341022104410821050c0c0b4197ebc2002103410a2105410321040c0b0b418debc2002103410a2105410421040c0a0b4183ebc2002103410a2105410521040c090b41f4eac2002103410f2105410621040c080b41e6eac2002103410e2105410721040c070b41d6eac200210341102105410821040c060b41caeac2002103410c2105410921040c050b41bdeac2002103410d2105410a21040c040b41b0eac2002103410d2105410b21040c030b419feac200210341112105410c21040c020b41faa0c5002103410e2105410d21040c010b4199eac200210341062105410e21040b20004183383b0100200041086a2005360200200041046a2003360200200041026a20043a0000200241c0006a24000bb40201037f230041e0006b22022400200241086a4188fec6004108108102200241186a41d0adc300410a108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241c8006a41086a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000baa37050e7f027e017f027e247f230041f0086b220324002003200236021c20032001360218200341206a2001200210ed0202400240200328022022040d00200041023a00a4020c010b200328022421052003200341206a41086a2802003602bc02200320043602b8022003200341b8026a3602e805200341106a200341e8056a10d8040240024020032802100d004108210602400240200328021422074180012007418001491b2208450d002008410574102c2206450d010b024002400240024002400240024020070d00410021070c010b20034198086a41106a210920034198086a41046a210a20034198086a41086a210b4100210c4100210d4100210e0340200341003602980820034198086a20032802b802220f20032802bc022201410420014104491b220210e9081a2003200120026b22013602bc022003200f20026a220f3602b802024020034198086a20026a2210200a460d0020104100410420026b10eb081a0b2003350298082111200341003a0098070240200120014100472202490d0020034198076a200f200210e9081a2003200120026b22103602bc022003200f20026a22023602b80202400240024020010d00420021120c010b4200211202400240024002400240024020032d0098070e0707000102030405080b20034198086a2010411020104110491b22016a41004100411020016b22132001410f4b1b10eb08210f20034198086a2002200110e9081a2003201020016b3602bc022003200220016a3602b8020240200f2009460d00200f4100201310eb081a0b200b29030021142003290398082115420121120c060b420221120c040b420321120c030b420421120c020b420521120c010b420621120b0b0240200e2008470d00200d200e41016a2201200d20014b1b22014104200141044b1b220141ffffff3f7120014641037421022001410574210102400240200e0d0020034100360298080c010b200341083602a0082003200c36029c0820032006360298080b200341f0076a2001200220034198086a107d20032802f8072101024020032802f0074101470d002001450d050c0a0b20032802f4072106200141057621080b2006200c6a22012011370300200141186a2014370300200141106a2015370300200141086a2012370300200c41206a210c200d41026a210d2007200e41016a220e460d020c010b0b410221010240200841ffffff3f710d000c090b2006102e0c080b2006450d06200341a0086a220e4200370300200342003703980820034198086a20032802b802220c20032802bc022202411020024110491b220110e9081a2003200220016b3602bc022003200c20016a3602b802024020014110460d0020034198086a20016a4100411020016b10eb081a0b200e29030021152003290398082112200341086a200341e8056a10d80420032802080d0302400240200328020c220c4138200c4138491b22020d004104210e0c010b200241c8006c102c220e450d060b0240200c0d004100210c0c020b200341f0076a410c6a2116200341f0076a4101722117410021104100210d0340200341f0076a200341e8056a10eb0302400240024020032d00f007220f4106460d00200341c8056a41026a2209201741026a2d00003a0000200341d8076a41086a220b201641086a290200370300200341d8076a41106a2213201641106a290200370300200320172f00003b01c805200320162902003703d80720032802f407210a20032802f807210120034198086a200341e8056a10eb0320032d0098084106470d01200f4101470d002001450d00200a102e0b4106210f0c010b200341a8056a41026a20092d00003a0000200341c0076a41086a200b290300370300200341c0076a41106a201329030037030020034198076a41086a20034198086a41086a29030037030020034198076a41106a20034198086a41106a29030037030020034198076a41186a20034198086a41186a29030037030020034198076a41206a20034198086a41206a280200360200200320032f01c8053b01a805200320032903d8073703c007200320032903980837039807200a2118200121190b20034188056a41026a2201200341a8056a41026a2d00003a000020034180076a41086a220a200341c0076a41086a29030037030020034180076a41106a2209200341c0076a41106a290300370300200341d8066a41086a220b20034198076a41086a290300370300200341d8066a41106a221320034198076a41106a290300370300200341d8066a41186a221a20034198076a41186a290300370300200341d8066a41206a221b20034198076a41206a280200360200200320032f01a8053b018805200320032903c0073703800720032003290398073703d8060240200f4106460d00200341e8046a41026a221c20012d00003a0000200341c0066a41086a221d200a290300370300200341c0066a41106a220a200929030037030020034198066a41086a2209200b29030037030020034198066a41106a220b201329030037030020034198066a41186a2213201a29030037030020034198066a41206a221a201b280200360200200320032f0188053b01e80420032003290380073703c006200320032903d806370398060240200d2002470d00200241016a22012002490d032002410174221b2001201b20014b1b22014104200141044b1bad42c8007e2214422088a74541027421012014a7211b0240024020020d0020034100360298080c010b200341043602a0082003200e360298082003200241c8006c36029c080b200341f0076a201b200120034198086a107d20032802f8072101024020032802f0074101470d0020010d090c040b20032802f407210e200141c8006e21020b200e20106a2201200f3a0000200141086a2019360000200141046a2018360000200141036a201c2d00003a0000200141016a20032f01e8043b00002001410c6a20032903c006370000200141146a201d2903003700002001411c6a200a290300370000200141346a200b2903003700002001412c6a20092903003700002001413c6a2013290300370000200141246a200329039806370000200141c4006a201a280200360000201041c8006a2110200c200d41016a220d460d030c010b0b0240200d450d00200e20106a210c200e21010340024020012d00004101470d00200141086a280200450d00200141046a280200102e0b0240200141246a2d00004101470d002001412c6a280200450d00200141286a280200102e0b200c200141c8006a2201470d000b0b2002450d03200241c8006c0d020c030b1038000b200e450d0120034198086a200341e8056a10eb03024020032d00980822104106460d00200341ec056a41026a20032d009b083a000020034180076a41086a200341ac086a220129020037030020034180076a41106a200341b4086a220f290200370300200320032f0099083b01ec052003200341a4086a220d2902003703800720034198086a41086a2213280200210a200328029c08210920034198086a200341e8056a10eb03024020032d009808220b4106460d00200341f0056a41026a20032d009b083a0000200341c0076a41086a2001290200370300200341c0076a41106a200f290200370300200320032f0099083b01f0052003200d2902003703c00720132802002113200328029c08211a20034198086a200341e8056a10eb03024020032d009808221b4106460d00200341f4056a41026a20032d009b083a0000200341d8076a41086a200341ac086a2201290200370300200341d8076a41106a200341b4086a220f290200370300200320032f0099083b01f4052003200341a4086a220d2902003703d80720034198086a41086a2218280200211c200328029c08211d20034198086a200341e8056a10eb03024020032d00980822164106460d00200341f8056a41026a20032d009b083a000020034198066a41086a200129020037030020034198066a41106a200f290200370300200320032f0099083b01f8052003200d2902003703980620182802002118200328029c08211920034198086a200341e8056a10eb03024020032d00980822174106460d00200341fe056a20032d009b083a0000200341d8066a41086a200341ac086a290200370300200341e8066a200341b4086a290200370300200320032f0099083b01fc052003200341a4086a2902003703d80620034198086a41086a280200211e200328029c08211f200341003a009808024020032802e805222028020422012001410047220d490d0020034198086a20202802002221200d10e9081a20202001200d6b220f36020420202021200d6a22213602000240024020010d00410021010c010b41002101024020032d0098080e020100020b200341003a00ac084100212202400340200341003a009807200f200f4100472201490d01202241016a210d20034198076a2021200110e9081a2020200f20016b22233602042020202120016a22213602000240200f0d00200341003a0098070b20034198086a20226a20032d0098073a00002003200d3a00ac082023210f200d2122200d4114470d000b200341f0076a41086a20034198086a41086a290300370300200341f0076a41106a20034198086a41106a28020036020020032003290398083703f007410121010c010b202241ff0171450d01200341003a00ac080c010b20034180066a41106a200341f0076a41106a28020036020020034180066a41086a200341f0076a41086a290300370300200320032903f0073703800620034198086a200341e8056a10eb0320032d00980822204106460d0020034194066a41026a220f20032d009b083a000020034198076a41086a200341ac086a29020037030020034198076a41106a200341b4086a290200370300200320032f0099083b0194062003200341a4086a2902003703980720034198086a41086a2802002121200328029c08212220034198086a200341e8056a10eb0320032d0098084106470d0820204101470d002021450d002022102e0b20174101470d00201e450d00201f102e0b20164101470d002018450d002019102e0b201b4101470d00201c450d00201d102e0b200b4101470d002013450d00201a102e0b20104101470d00200a450d002009102e0b0240200c450d00200e200c41c8006c6a210c200e21010340024020012d00004101470d00200141086a280200450d00200141046a280200102e0b0240200141246a2d00004101470d002001412c6a280200450d00200141286a280200102e0b200141c8006a2201200c470d000b0b2002450d01200241c8006c450d010b200e102e0b200841ffffff3f71450d022006102e410221010c030b200341f0076a41206a20034198086a41206a280200360200200341f0076a41186a20034198086a41186a290300370300200341f0076a41106a20034198086a41106a220d290300370300200341f0076a41086a20034198086a41086a2223290300370300200341e4056a41026a200341ec056a41026a2d00003a0000200341c0066a41086a20034180076a41086a290300370300200341c0066a41106a20034180076a41106a29030037030020032003290398083703f007200320032f01ec053b01e40520032003290380073703c006200341e0056a41026a200341f0056a41026a2d00003a0000200320032f01f0053b01e005200341c8056a41106a200341c0076a41106a290300370300200341c8056a41086a200341c0076a41086a290300370300200320032903c0073703c805200341c4056a41026a200341f4056a41026a2d00003a0000200320032f01f4053b01c405200341a8056a41106a200341d8076a41106a290300370300200341a8056a41086a200341d8076a41086a290300370300200320032903d8073703a805200341a4056a41026a200341f8056a41026a2d00003a0000200320032f01f8053b01a40520034188056a41106a20034198066a41106a29030037030020034188056a41086a20034198066a41086a29030037030020032003290398063703880520034184056a41026a200341fc056a41026a2d00003a0000200320032f01fc053b018405200341e8046a41106a200341d8066a41106a290300370300200341e8046a41086a200341d8066a41086a290300370300200320032903d8063703e804200d20034180066a41106a280200360200202320034180066a41086a290300370300200320032903800637039808200341e4046a41026a200f2d00003a0000200320032f0194063b01e404200341c8046a41106a20034198076a41106a290300370300200341c8046a41086a20034198076a41086a29030037030020032003290398073703c8040c020b1036000b410221010b200341c4046a41026a200341e4056a41026a2d00003a0000200341a8046a41086a200341c0066a41086a290300370300200341a8046a41106a2223200341c0066a41106a290300370300200341a4046a41026a200341e0056a41026a2d00003a000020034188046a41086a200341c8056a41086a29030037030020034188046a41106a2224200341c8056a41106a290300370300200320032f01e4053b01c404200320032903c0063703a804200320032f01e0053b01a404200320032903c8053703880420034184046a41026a200341c4056a41026a2d00003a0000200341e8036a41086a200341a8056a41086a290300370300200341e8036a41106a2225200341a8056a41106a290300370300200341e4036a41026a200341a4056a41026a2d00003a0000200341c8036a41086a20034188056a41086a290300370300200341c8036a41106a222620034188056a41106a290300370300200320032f01c4053b018404200320032903a8053703e803200320032f01a4053b01e40320032003290388053703c803200341c4036a41026a20034184056a41026a2d00003a0000200341a8036a41106a2227200341e8046a41106a290300370300200341a8036a41086a200341e8046a41086a290300370300200341a4036a41026a200341e4046a41026a2d00003a000020034188036a41106a2228200341c8046a41106a29030037030020034188036a41086a200341c8046a41086a290300370300200320032f0184053b01c403200320032903e8043703a803200320032f01e4043b01a403200320032903c80437038803200341e0026a41206a2229200341f0076a41206a280200360200200341e0026a41186a222a200341f0076a41186a290300370300200341e0026a41106a222b200341f0076a41106a290300370300200341e0026a41086a200341f0076a41086a290300370300200320032903f0073703e002200341c0026a41176a20034198086a41176a220f280000360000200341c0026a41106a20034198086a41106a220d290300370300200341c0026a41086a20034198086a41086a29030037030020032003290398083703c0020240024020014102470d00200341003602f807200342013703f0072003410a36029c072003200341186a360298072003200341f0076a3602d806200341ac086a41013602002003420137029c08200341909dc50036029808200320034198076a3602a808200341d8066a419cebc00020034198086a103d1a20032802f00720032802f80710ef0220032802f407450d0120032802f007102e0c010b200341b4026a41026a222c200341c4046a41026a2d00003a000020034198026a41086a222d200341a8046a41086a29030037030020034198026a41106a222e202329030037030020034194026a41026a2223200341a4046a41026a2d00003a0000200341f8016a41086a222f20034188046a41086a290300370300200341f8016a41106a22302024290300370300200320032f01c4043b01b402200320032903a80437039802200320032f01a4043b01940220032003290388043703f801200341f4016a41026a222420034184046a41026a2d00003a0000200341d8016a41086a2231200341e8036a41086a290300370300200341d8016a41106a22322025290300370300200341d4016a41026a2225200341e4036a41026a2d00003a0000200341b8016a41086a2233200341c8036a41086a290300370300200341b8016a41106a22342026290300370300200320032f0184043b01f401200320032903e8033703d801200320032f01e4033b01d401200320032903c8033703b801200341b4016a41026a2226200341c4036a41026a2d00003a000020034198016a41106a2235202729030037030020034198016a41086a2227200341a8036a41086a29030037030020034194016a41026a2236200341a4036a41026a2d00003a0000200341f8006a41106a22372028290300370300200341f8006a41086a222820034188036a41086a290300370300200320032f01c4033b01b401200320032903a80337039801200320032f01a4033b0194012003200329038803370378200341d0006a41206a22382029280200360200200341d0006a41186a2229202a290300370300200341d0006a41106a222a202b290300370300200341d0006a41086a222b200341e0026a41086a290300370300200320032903e002370350200341306a410f6a200341c0026a410f6a290000370000200341306a41086a2239200341c0026a41086a290300370300200320032903c0023703302000201537030820002012370300200020103a00282000200c360224200020023602202000200e36021c2000200736021820002008360214200020063602102000200a3602302000200936022c200020032f01b4023b00292000412b6a202c2d00003a000020002003290398023702342000413c6a202d290300370200200041c4006a202e2903003702002000200b3a004c200041cf006a20232d00003a0000200020032f0194023b004d200020133602542000201a360250200041e8006a2030290300370200200041e0006a202f290300370200200020032903f8013702582000201b3a0070200041f3006a20242d00003a0000200020032f01f4013b00712000201c3602782000201d3602742000418c016a203229030037020020004184016a2031290300370200200020032903d80137027c200020163a00940120004197016a20252d00003a0000200020032f01d4013b0095012000201836029c012000201936029801200041b0016a2034290300370200200041a8016a2033290300370200200020032903b8013702a001200020173a00b801200041bb016a20262d00003a0000200020032f01b4013b00b9012000201e3602c0012000201f3602bc01200041d4016a2035290300370200200041cc016a202729030037020020002003290398013702c401200020203a00dc01200041df016a20362d00003a0000200020032f0194013b00dd01200020213602e401200020223602e001200041f8016a2037290300370200200041f0016a2028290300370200200020032903783702e801200041a0026a203828020036020020004198026a202929030037020020004190026a202a29030037020020004188026a202b2903003702002000200329035037028002200f200341306a41176a280000360000200d200341306a41106a29030037030020034198086a41086a220220392903003703002003200329033037039808200041bc026a200f280000360000200041b5026a200d290300370000200041ad026a200229030037000020002003290398083700a5020b200020013a00a4022005450d002004102e0b200341f0086a24000bbd07010a7f23004180026b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022040d00200041063a00200c010b200328021421052003200341186a280200220636029401200320043602900141002101200341003a00d801024002400240034020062001460d01200341b8016a20016a200420016a22022d00003a00002003200241016a360290012003200141016a22023a00d8012002210120024120470d000b2003200620026b36029401200341206a41186a2201200341b8016a41186a290300370300200341206a41106a2206200341b8016a41106a290300370300200341206a41086a2207200341b8016a41086a290300370300200320032903b801370320200241ff01714120490d0120034198016a41086a200729030037030020034198016a41106a200629030037030020034198016a41186a20012903003703002003200329032037039801200341b8016a20034190016a10ec0320032d00b80122014106460d01200341f0006a41186a220220034198016a41186a290300370300200341f0006a41106a220620034198016a41106a290300370300200341f0006a41086a220720034198016a41086a290300370300200341c8006a41086a2208200341c1016a290000370300200341c8006a41106a2209200341c9016a290000370300200341c8006a41186a220a200341d1016a290000370300200341c8006a411f6a220b200341d8016a2800003600002003200329039801370370200320032900b901370348200341206a411f6a220c200b280000360000200341206a41186a220b200a290300370300200341206a41106a220a2009290300370300200341206a41086a22092008290300370300200041186a2002290300370200200041106a2006290300370200200041086a20072903003702002000200329037037020020032003290348370320200041c0006a200c280000360000200041396a200b290300370000200041316a200a290300370000200041296a2009290300370000200020032903203700210c020b2003410036029401200141ff0171450d00200341003a00d8010b20034100360250200342013703482003410a3602242003200341086a3602202003200341c8006a3602e001200341cc016a4101360200200342013702bc01200341909dc5003602b8012003200341206a3602c801200341e0016a419cebc000200341b8016a103d1a2003280248200328025010ef020240200328024c450d002003280248102e0b410621010b200020013a00202005450d002004102e0b20034180026a24000bb40201037f230041e0006b22022400200241086a4188fec6004108108102200241186a41d0aec3004106108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241c8006a41086a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000b8e0302027f037e230041e0006b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200041003602100c010b200328021421042003200341106a41086a2802002202360224200320013602200240024020024110490d002003200241706a3602242003200141106a360220200141086a2900002105200129000021062003200341206a10ab0102402003280200450d00200341003602480c010b200341c8006a200341206a200328020410920120032802482202450d00200329024c2107200020053703082000200637030020002007370214200020023602100c010b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341909dc5003602482003200341386a360258200341c4006a419cebc000200341c8006a103d1a2003280228200328023010ef020240200328022c450d002003280228102e0b200041003602100b2004450d002001102e0b200341e0006a24000ba43809017f0a7e027f077e017f017e037f037e047f230041f0056b22062400200620043703202006200337031820062001360214200620053a002f0240024020032004844200520d0020004100360200200041106a4200370300200041086a42003703000c010b024002400240024002400240024002400240024020012002412010ec080d002005450d01200641d0016a200110c802200641f0046a20062802d001220220062802d80110c90220064190056a290300420020062903f00442015122011b210720064188056a290300420020011b2108024020062802d401450d002002102e0b20004100360200200041106a4200200420077d2003200854ad7d2207200320087d2208200356200720045620072004511b22011b370300200041086a4200200820011b3703000c0a0b2006200236028c01200641d0016a200210c802200641f0046a20062802d001220520062802d80110c902200641f0046a41386a2903002109200641f0046a41306a2903002107200641f0046a41286a290300210a200641f0046a41206a290300210b200641f0046a41186a290300210c200641f0046a41106a2903002103200641b0056a290300210d20062903f804210420062903f0042108200641c8036a41086a200641c0056a2903003703002006200641b8056a2903003703c8030240024020084201510d004200210d20064190016a41386a420037030020064190016a41306a420037030020064190016a41286a4200370300200641b0016a420037030020064190016a41186a420037030020064190016a41106a420037030020064190016a41086a420037030020064200370390014200210b4200210a420021074200210942002104420021034200210c4200210e4200210f42002108420021100c010b200641b0016a200a37030020064190016a41286a200737030020064190016a41106a200c37030020064190016a41306a20093703002006200b3703a80120062004370390012006200d3703c8012006200337039801200a210e2007210f20042108200321100b024020062802d401450d002005102e0b0240024020082010844200520d00200e20062903a00184200f200641a8016a29030084844200520d0020062903c001200641c8016a2903008450450d0042002108410021110c010b42012108410121110b0240024020084201510d0042002104200641c0036a4200370300200641b8036a4200370300200641b0036a4200370300200641a8036a4200370300200641a0036a420037030020064198036a420037030020064190036a42003703002006420037038803420021030c010b200641a8036a200a370300200641b0036a2007370300200641b8036a200937030020064198036a200c3703002006200b3703a0032006200d3703c003200620043703880320062003370390030b024020084201510d00200641a0046a41206a200641b8036a290300370300200641a0046a41186a200641b0036a290300370300200641b0046a20064188036a41206a290300370300200641a8046a20064188036a41186a29030037030020062006290398033703a00441838a1c211241b4a4c7002101410b21050c070b200620013602dc03200641a0046a200110c802200641f0046a20062802a004220520062802a80410c902200641f0046a41386a2903002113200641f0046a41306a290300210f200641f0046a41286a2903002114200641f0046a41206a2903002104200641f0046a41186a290300210c200641f0046a41106a2903002103200641b0056a290300211520062903f804211020062903f004210e200641c8036a41086a200641c0056a2903003703002006200641b8056a2903003703c80302400240200e4201510d0042002115200641e0036a41386a4200370300200641e0036a41306a4200370300200641e0036a41286a4200370300200641e0036a41206a4200370300200641e0036a41186a4200370300200641e0036a41106a4200370300200641e0036a41086a4200370300200642003703e00342002104420021144200210f4200211342002110420021034200210c42002116420021174200210e420021180c010b200641e0036a41206a2014370300200641e0036a41286a200f370300200641e0036a41106a200c370300200641e0036a41306a2013370300200620043703f803200620103703e0032006201537039804200620033703e80320142116200f21172010210e200321180b024020062802a404450d002005102e0b02400240200e2018844200520d00201620062903f003842017200641f8036a29030084844200520d0020062903900420064198046a2903008450450d0042002117410021120c010b42012117410121120b024020174201510d00420021044200210c42002115420021144200210f4200211342002110420021030b200641186a41086a290300220e2004200c20062903182218562004200e562004200e511b22051b21162018200c20051b210e02400240024020062d002f4101470d002006290398032218200e7c22192018542205200641a0036a221a290300221820167c2005ad7c221b201854201b2018511b450d010c060b2006290388032218200e7c2219201854220520064188036a41086a290300221820167c2005ad7c221b201854201b2018511b0d0520062019370388032006201b370390030c010b201a201b37030020062019370398030b20064198056a221c200f370300200641a0056a221d201337030020064188056a200420167d200c200e54ad7d220f37030020062014370390052006200c200e7d221437038005200620103703f004200620033703f80442002104200e422088a72105200ea7211a02400240427f201020147c220c200c201054221e2003200f7c201ead7c220c200354200c2003511b221e1b221842ffc7afa02556427f200c201e1b22134200522013501b0d0020102014842003200f8484220450211e4200210c2004420052ad21040c010b201d290300211f201c290300212020064190056a290300212120064180056a290300211b200629038805211920062903f804211420062903f004210e4201210c4101211e0b200641c8046a2013370300200641c0046a221c2018370300200641b0046a2003370300200620103703a804200620163703d804200620053602d4042006201a3602d004200620043703b80420062017420152ad220f3703a0040240024002402012200c420152720d00200620013602f0042001200641f0046a10bd060c010b024020124101732205200c420151720d00200620013602f0042001200641f0046a10be0641ff017122054103460d01024020050e03030200030b41002105410421120240201e0d002006201c3602f004200641f0046a10cc020b410021010c070b200c4201522005710d030b200641e0046a200110c802200641f0046a20062802e004221220062802e804221a10c90220062903f0042103200641c8036a41086a2205200641c0056a2903003703002006200641b8056a2903003703c8030240024020034201510d00200641e8026a41086a4200370300200642003703e8020c010b200641e8026a41086a2005290300370300200620062903c8033703e8020b200641b8056a20062903e802370300200641c0056a200641e8026a41086a290300370300200642013703f004200641f0046a41386a201f4200200c42015122051b370300200641a0056a2020420020051b370300200641f0046a41286a2021420020051b37030020064190056a2019420020051b37030020064188056a201b420020051b370300200641f0046a41106a2014420020051b370300200641b0056a2015420020051b3703002006200e420020051b3703f8042012201a200641f0046a41086a10c805024020062802e404450d002012102e0b200641a0046a41106a2903002103200641a0046a41286a2903002113200641a0046a41386a290300210c20062903a804211020062903c004211820062903d004210e20062903a004210f20062903b80421040c030b200641c8046a2903002113200641b0046a2903002103200641d8046a290300210c20062903c004211820062903a804211020062903d004210e20062903b804210420062903a004210f0c020b200620012003200410fb0120062903002103200041106a200641086a290300370300200041086a2003370300200041003602000c080b200641d8046a290300210c20062903d004210e0b0240200f4201520d00200641a8056a2003370300200641a0056a2010370300200641f0046a41086a41003a0000200641f9046a200129000037000020064181056a200141086a29000037000020064189056a200141106a29000037000020064191056a200141186a290000370000200641033a00f004200641f0046a10fe010b02400240200450450d00420021150c010b200641f0046a41086a20062802dc03220141086a290000370300200641f0046a41106a200141106a290000370300200641f0046a41186a200141186a290000370300200620012900003703f004420121150b200641e0036a41186a200641f0046a41186a290300370300200641e0036a41106a200641f0046a41106a290300370300200641e0036a41086a200641f0046a41086a290300370300200620062903f0043703e0034100211a0c020b41808008210141800a2105410321120b20014180800c71200541800e7172201272211241a984ca00ad4280808080800184210e4101211a4200210c0b20064188036a41086a2903002103200641c0036a29030021212006290388032104200641a0046a41206a221e20064188036a41306a290300370300200641a0046a41186a221c20064188036a41286a290300370300200641b0046a221d20064188036a41206a290300370300200641a0046a41086a222220064188036a41186a29030037030020062006290398033703a004200e422088a72105200ea72101201a450d010b2005ad4220862001ad8421084200210f410121010c010b200641f0046a41186a20222903002207370300200641f0046a41206a201d290300370300200641f0046a41286a201c290300370300200641f0046a41306a201e290300370300200620062903a004220a37038005200620043703f004200620033703f804420021104201210f2008420152211a02400240427f2004200a7c22082008200454221e200320077c201ead7c220820035420082003511b221e1b221442ffc7afa02556427f2008201e1b220e420052200e501b0d004200210f2004200a84200320078484420052ad21100c010b200641a0056a290300210920064198056a290300210720064190056a290300210a20064180056a2903002119200629038805210b20062903f804211b20062903f00421170b201aad2108200641e8026a41086a200641e0036a41086a290300370300200641e8026a41106a200641e0036a41106a290300370300200641e8026a41186a200641e0036a41186a290300370300200620062903e0033703e8022005ad4220862001ad842116410021012021210d0b200641c8026a41086a2205200641e8026a41086a290300370300200641c8026a41106a221a200641e8026a41106a290300370300200641c8026a41186a221e200641e8026a41186a290300370300200620062903e8023703c8020240024002400240024020010d0020064188026a200c370300200641f8016a200e370300200641f0016a22012014370300200641d0016a41106a2003370300200641c0026a2013370300200641b8026a221c201837030020064190026a201537030020064198026a20062903c802370300200641a0026a2005290300370300200641a8026a201a290300370300200641b0026a201e2903003703002006201637038002200620043703d801200620103703e801200620083703d001024002402011200f420152720d00200620023602f0042002200641f0046a10bd060c010b024020114101732205200f420151720d00200620023602f0042002200641f0046a10be0641ff017122054103460d010240024020050e03010300010b02402010500d00200620013602f004200641f0046a10cc020b20064190026a220510d20441012101410421122005290300500d052006201c3602f004200641f0046a10cc020c050b20064190046a200641c0026a29030037030020064188046a200641b8026a29030037030020064180046a200641b0026a290300370300200641f8036a200641a8026a290300370300200641f0036a200641a0026a290300370300200641e8036a20064198026a290300370300200620064190026a2903003703e003410021010c040b200f4201522005710d020b20064188036a200210c802200641f0046a2006280288032205200628029003221210c90220062903f0042103200641c8036a41086a2201200641c0056a2903003703002006200641b8056a2903003703c8030240024020034201510d00200641a0046a41086a4200370300200642003703a0040c010b200641a0046a41086a2001290300370300200620062903c8033703a0040b200641f0046a41c8006a20062903a004370300200641f0046a41d0006a200641a0046a41086a2211290300370300200642013703f004200641f0046a41386a20094200200f42015122011b370300200641f0046a41306a2007420020011b370300200641f0046a41286a200a420020011b370300200641f0046a41206a200b420020011b370300200641f0046a41186a2019420020011b370300200641f0046a41106a201b420020011b370300200641f0046a41c0006a200d420020011b37030020062017420020011b3703f80420052012200641f0046a41086a10c8050240200628028c03450d002005102e0b200641e0036a41086a2201200641d0016a41c8006a290300370300200641e0036a41106a2205200641d0016a41d0006a290300370300200641e0036a41186a2212200641a8026a290300370300200641e0036a41206a221a200641b0026a290300370300200641e0036a41286a221e200641b8026a290300370300200641e0036a41306a221c200641c0026a2903003703002006200641d0016a41c0006a2903003703e003200641d0016a41106a2903002103200641d0016a41286a290300210e200641d0016a41386a290300210c20062903d801210420062903f0012114200629038002210820062903d001210720062903e8012110200641a0046a41306a201c290300370300200641a0046a41286a201e290300370300200641a0046a41206a201a290300370300200641a0046a41186a2012290300370300200641a0046a41106a200529030037030020112001290300370300200620062903e0033703a004200641a0046a21010c030b410121010c010b20064190046a200641c0026a29030037030020064188046a200641b8026a29030037030020064180046a200641b0026a290300370300200641f8036a200641a8026a290300370300200641f0036a200641a0026a290300370300200641e8036a20064198026a290300370300200620064190026a2903003703e003410021010b200641a0046a41306a200641e0036a41306a290300370300200641a0046a41286a200641e0036a41286a290300370300200641a0046a41206a200641e0036a41206a290300370300200641a0046a41186a200641e0036a41186a290300370300200641a0046a41106a200641e0036a41106a290300370300200641a0046a41086a200641e0036a41086a290300370300200620062903e0033703a00402402001450d00410121010c020b200641a0046a210120082107201621080b200641d0016a41306a200141306a290300370300200641d0016a41286a200141286a290300370300200641d0016a41206a200141206a290300370300200641d0016a41186a200141186a290300370300200641d0016a41106a200141106a290300370300200641d0016a41086a200141086a290300370300200620012903003703d001024020074201520d00200628028c012101200641a8056a2003370300200641f0046a41306a2004370300200641f0046a41086a41003a0000200641f9046a200129000037000020064181056a200141086a29000037000020064189056a200141106a29000037000020064191056a200141186a290000370000200641033a00f004200641f0046a10fe010b02400240201050450d00420021030c010b20064188036a41086a200628028c01220141086a29000037030020064188036a41106a200141106a29000037030020064188036a41186a200141186a2900003703002006200129000037038803420121030b20064190016a41186a20064188036a41186a29030037030020064190016a41106a20064188036a41106a29030037030020064190016a41086a20064188036a41086a290300370300200641f0046a41086a200641d0016a41086a290300370300200641f0046a41106a200641d0016a41106a290300370300200641f0046a41186a200641d0016a41186a290300370300200641f0046a41206a200641d0016a41206a290300370300200641f0046a41286a200641d0016a41286a290300370300200641f0046a41306a200641d0016a41306a290300370300200620062903880337039001200620062903d0013703f004410021010b200641d0006a41086a2205200641f0046a41086a2211290300370300200641d0006a41106a221a200641f0046a41106a290300370300200641d0006a41186a221e200641f0046a41186a290300370300200641d0006a41206a221c200641f0046a41206a290300370300200641d0006a41286a221d200641f0046a41286a290300370300200641d0006a41306a2222200641f0046a41306a290300370300200641306a41086a222320064190016a41086a290300370300200641306a41106a222420064190016a41106a290300370300200641306a41186a222520064190016a41186a290300370300200620062903f0043703502006200629039001370330024020010d00200641a0046a41306a2022290300370300200641a0046a41286a201d290300370300200641a0046a41206a201c290300370300200641a0046a41186a201e290300370300200641a0046a41106a201a290300370300200641a0046a41086a2005290300370300200620062903503703a004200641d0016a41306a200e370300200641d0016a41286a22122014370300200641d0016a41106a2023290300370300200641d0016a41186a2024290300370300200641d0016a41206a2025290300370300200620033703d001200620062903303703d80120062d002f2105200641e0036a41186a2006280214220141186a2900002203370300200641e0036a41106a200141106a2900002204370300200641e0036a41086a200141086a290000220737030020062001290000220a3703e003200641c8056a200c370300200641c0056a2008370300201141073a0000200641f9046a200a37000020064181056a200737000020064189056a200437000020064191056a2003370000200641b9056a20053a000020064199056a2002290000370000200641a1056a200241086a290000370000200641a9056a200241106a290000370000200641b1056a200241186a290000370000200641033a00f004200641f0046a10fe01200041086a2006290318220320087d37030020004100360200200041106a200641186a41086a290300200c7d2003200854ad7d370300200641d0016a10d204024020062903d001500d00200620123602f004200641f0046a10cc020b200641a0046a10d20420062903a004500d012006200641c8046a3602f004200641f0046a10cc020c010b2000201236020420004101360200200041086a20083702000b200641f0056a24000bda0102037f017e230041206b2203240002400240200241186a2802004105744114722204417f4c0d002004102c2205450d01200341003602082003200436020420032005360200200229030021062003200241086a290300370318200320063703102003200341106a4110107420022802102104200228021822022003107602402002450d002002410574210203402003200441201074200441206a2104200241606a22020d000b0b2000200120032802002204200328020810b20102402003280204450d002004102e0b200341206a24000f0b1038000b1036000b7801017f230041206b2203240020034100360208200342013703002003200241201074200341106a200241206a108a012003200328021022022003280218107402402003280214450d002002102e0b2000200120032802002202200328020810b20102402003280204450d002002102e0b200341206a24000b832501047f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002802000e1b00010218180304051806070818090a0b0c0d0e0f10111213141516170b0240024002400240024002400240200041086a2802000e0a1e1e001e01021e030405060b200041106a280200450d1d2000410c6a280200102e0f0b200041106a280200450d1c2000410c6a280200102e0f0b200041106a280200450d1b2000410c6a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141186c210103400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200141686a22010d000b0b200041106a2802002202450d1a200241186c450d1a200028020c102e0f0b0240200041146a2802002201450d002000410c6a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041106a2802002202450d192002410c6c450d19200028020c102e0f0b200041106a280200450d182000410c6a280200102e0f0b200041106a280200450d172000410c6a280200102e0f0b0240024002400240024020002d00040e061b001b010203040b200041186a2202280200108c042002280200102e0f0b02402000410c6a280200450d00200041086a280200102e0b200041246a2202280200108c042002280200102e0f0b2000410c6a280200450d18200041086a280200102e0f0b200041186a2202280200108c042002280200102e0f0b02402000410c6a280200450d00200041086a280200102e0b200041246a2202280200108c042002280200102e0f0b02400240200041086a280200417f6a0e020001170b2000412c6a220110e1010240200041306a2802002202450d00200241246c450d002001280200102e0b2000419c016a220110e1010240200041a0016a2802002202450d00200241246c450d002001280200102e0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d162002410c6c450d162000280210102e0f0b2000412c6a220110e1010240200041306a2802002202450d00200241246c450d002001280200102e0b2000419c016a220110e1010240200041a0016a2802002202450d00200241246c450d002001280200102e0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d152002410c6c450d152000280210102e0f0b0240024002400240200041086a2802000e0418000102030b2000410c6a2d00004102470d17200041146a280200450d17200041106a280200102e0f0b2000410c6a2d00004102470d16200041146a280200450d16200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004102470d15200041386a280200450d15200041346a280200102e0f0b2000410c6a2d00004102470d14200041146a280200450d14200041106a280200102e0f0b02402000410c6a2802002201450d0020002802042202200141f0006c6a21030340024020022204410c6a2802002201450d0020042802042102200141246c210103400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200441f0006a21020240200441086a2802002201450d00200141246c450d002004280204102e0b20022003470d000b0b200041086a2802002202450d13200241f0006c450d132000280204102e0f0b024002400240024002400240200041086a2d00000e171800181818180118180218181818180318180418181818050b2000412c6a2d00004102470d17200041346a280200450d17200041306a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141246c21010340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200041106a2802002202450d16200241246c450d16200028020c102e0f0b2000410c6a2d00004102470d15200041146a280200450d15200041106a280200102e0f0b200041106a28020041ffffff3f71450d142000410c6a280200102e0f0b200041146a28020041ffffffff0371450d13200041106a280200102e0f0b0240200041146a2802002201450d002000410c6a2802002102200141246c21010340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b200041106a2802002202450d12200241246c450d12200028020c102e0f0b20002802042202450d11200041086a280200450d112002102e0f0b02400240200041086a280200417f6a0e020001120b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d112002410c6c450d112000280210102e0f0b0240200041186a2802002201450d00200041106a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041146a2802002202450d102002410c6c450d102000280210102e0f0b02402000410c6a280200450d00200041086a280200102e0b02402000411c6a2802002201450d00200041146a28020021022001410c6c210103400240200241046a280200450d002002280200102e0b2002410c6a2102200141746a22010d000b0b200041186a2802002202450d0f2002410c6c450d0f2000280214102e0f0b0240024002400240200041086a2d000041716a0e0400010203120b200041106a280200450d112000410c6a280200102e0f0b200041106a280200450d102000410c6a280200102e0f0b200041106a280200450d0f2000410c6a280200102e0f0b200041106a280200450d0e2000410c6a280200102e0f0b024002400240200041086a2d0000417f6a0e03000102100b200041306a28020041ffffff3f71450d0f2000412c6a280200102e0f0b2000410c6a2202280200108c042002280200102e0f0b200041106a2202280200108c042002280200102e0f0b024002400240200041086a2d0000417f6a0e030001020f0b200041306a28020041ffffff3f71450d0e2000412c6a280200102e0f0b2000410c6a2202280200108c042002280200102e0f0b200041106a2202280200108c042002280200102e0f0b02400240200041086a2d0000417f6a0e05000d0d0d010d0b200041106a28020041ffffff3f71450d0c2000410c6a280200102e0f0b2000410c6a2d00004102470d0b200041146a280200450d0b200041106a280200102e0f0b20002d00044104470d0a2000410c6a28020041ffffff3f71450d0a200041086a280200102e0f0b200041086a2802004101470d092000410c6a2d00004102470d09200041146a280200450d09200041106a280200102e0f0b02400240200041086a2d0000417d6a0e0200010a0b200041f0006a280200450d09200041ec006a280200102e0f0b200041106a280200450d082000410c6a280200102e0f0b024002400240200041086a2802000e040a0a0001020b2000410c6a2d00004102470d09200041146a280200450d09200041106a280200102e0f0b2000410c6a2d00004102470d08200041146a280200450d08200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004102470d07200041386a280200450d07200041346a280200102e0f0b02400240024020002f01040e03090001020b0240200041106a2802002201450d00200041086a2802002102200141b0026c210103402002109601200241b0026a2102200141d07d6a22010d000b0b2000410c6a2802002202450d08200241b0026c450d082000280208102e0f0b200041086a2202280200108c042002280200102e0f0b0240200041106a2802002201450d00200041086a2802002102200141b0026c210103402002109601200241b0026a2102200141d07d6a22010d000b0b2000410c6a2802002202450d06200241b0026c450d062000280208102e0f0b0240024002400240024002400240200041086a2d0000417e6a0e0d00010c0c0c0c0c0c02030405060c0b2000410c6a10e3030f0b0240200041146a2802002202450d00200241c4006c21012000410c6a28020041286a210203400240200241786a2d00004101470d002002280200450d002002417c6a280200102e0b200241c4006a2102200141bc7f6a22010d000b0b200041106a2802002202450d0a200241c4006c450d0a200028020c102e0f0b200041106a2d00004102470d09200041186a280200450d09200041146a280200102e0f0b2000410c6a2d00004102470d08200041146a280200450d08200041106a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004101470d07200041386a280200450d07200041346a280200102e0f0b02402000410c6a2d00004102470d00200041146a280200450d00200041106a280200102e0b200041306a2d00004101470d06200041386a280200450d06200041346a280200102e0f0b2000410c6a2d00004102470d05200041146a280200450d05200041106a280200102e0f0b20002d00042202417e6a4108490d040240024020020e020600010b200041286a2202280200108c042002280200102e0f0b200041c8006a2202280200108c042002280200102e0f0b0240024002400240200041086a2d00000e0407000102030b0240200041106a28020041ffffff3f71450d002000410c6a280200102e0b200041186a2202280200108c042002280200102e0f0b0240200041106a28020041ffffff3f71450d002000410c6a280200102e0b200041286a280200450d05200041246a280200102e0f0b200041306a28020041ffffff3f71450d042000412c6a280200102e0f0b200041306a28020041ffffff3f71450d032000412c6a280200102e0f0b0240024002400240200041086a2802000e09060006010606020606030b200041106a280200450d052000410c6a280200102e0f0b200041106a2d00004102470d04200041186a280200450d04200041146a280200102e0f0b200041106a2d00004102470d03200041186a280200450d03200041146a280200102e0f0b200041146a280200450d02200041106a280200102e0f0b02400240200041086a2d0000417f6a0e03000301030b200041306a280200450d022000412c6a280200102e0c020b200041306a280200450d012000412c6a280200102e0f0b02402000413c6a28020041ffffffff0171450d00200041386a280200102e0b0240200041c8006a2802002202450d002002410c6c450d00200041c4006a280200102e0b0240200041d4006a28020041ffffffff0071450d00200041d0006a280200102e0b0240200041e0006a2802002202450d00200241146c450d00200041dc006a280200102e0b0240200041ec006a2802002202450d00200241186c450d00200041e8006a280200102e0b0240200041f8006a2802002202450d002002411c6c450d00200041f4006a280200102e0b024020004184016a28020041ffffff3f71450d0020004180016a280200102e0b024020004190016a2802002202450d00200241246c450d002000418c016a280200102e0b02402000419c016a2802002202450d00200241286c450d0020004198016a280200102e0b0240200041a8016a2802002202450d002002412c6c450d00200041a4016a280200102e0b0240200041b4016a2802002202450d00200241306c450d00200041b0016a280200102e0b0240200041c0016a2802002202450d00200241346c450d00200041bc016a280200102e0b0240200041cc016a2802002202450d00200241386c450d00200041c8016a280200102e0b0240200041d8016a2802002202450d002002413c6c450d00200041d4016a280200102e0b0240200041e4016a28020041ffffff1f71450d00200041e0016a280200102e0b200041f0016a2802002202450d00200241c4006c450d00200041ec016a280200102e0f0b0b830501077f230041c0006b220324002001280204210420012802002105024002400240200128020822060d00410021070c010b200641057421084100210941002107200521010240034002402009450d0020092001412010ec084100480d0020034106108e04200041013602002000410c6a200341086a280200360200200020032903003702040c020b024020012002412010ec08220941004a0d00024020090d0020034107108e04200041013602002000410c6a200341086a280200360200200020032903003702040c030b200741016a21070b20012109200141206a2101200841606a2208450d020c000b0b200441ffffff3f71450d012005102e0c010b200341186a200241186a290000370300200341106a200241106a290000370300200341086a200241086a290000370300200320022900003703000240024020062007490d000240024020062004470d00200441016a22012004490d03200441017422092001200920014b1b22014104200141044b1b220141ffffff3f712001462109200141057421010240024020040d00200341003602300c010b200341386a410136020020032005360230200320044105743602340b200341206a20012009200341306a107d200341286a280200210120032802204101460d0120032802242105200141057621040b200520074105746a220141206a2001200620076b41057410ea081a200141186a200341186a290300370000200141106a200341106a290300370000200141086a200341086a290300370000200120032903003700002000410c6a200641016a360200200041086a200436020020002005360204200041003602000c030b2001450d011036000b200720061045000b1038000b200341c0006a24000bae0301047f230041c0006b2202240041f0cbc3002103410d2104410d2105024002400240024002400240024002400240024002400240024002400240200141ff01710e0f000102030405060708090a0b0c0d0e000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a4180a7cc001044000b41e0cbc300210341102105410021040c0c0b41d1cbc3002103410f2105410121040c0b0b41c0cbc300210341112105410221040c0a0b41afcbc300210341112105410321040c090b419dcbc300210341122105410421040c080b4188cbc300210341152105410521040c070b41f5cac300210341132105410621040c060b418be7c400210341082105410721040c050b41feccc200210341082104410821050c040b41eacac3002103410b2105410921040c030b41dccac3002103410e2105410a21040c020b41c9cac300210341132105410b21040c010b41bacac3002103410f2105410c21040b200041833c3b0100200041086a2005360200200041046a2003360200200041026a20043a0000200241c0006a24000b9d3e07077f017e027f037e017f027e067f230041b00d6b220924004101210a02400240200241ffff037141014b0d00200941d00a6a4101108e042009418f026a200941d00a6a41086a2802002202360000200920092903d00a37008702200041186a41003a0000200042003703082000200929008002370019200041216a20094180026a41086a290000370000200041286a200236000020004201370300410121020c010b02400240200341086a280200220b0d00200941d00a6a4104108e042009418f026a200941d00a6a41086a280200220a360000200920092903d00a37008702200041186a41003a0000200042003703082000200929008002370019200041216a20094180026a41086a290000370000200041286a200a360000200042013703000c010b0240200b41e400490d00200941d00a6a4105108e042009418f026a200941d00a6a41086a280200220a360000200920092903d00a37008702200041186a41003a0000200042003703082000200929008002370019200041216a20094180026a41086a290000370000200041286a200a360000200042013703000c010b20094198076a41086a200341086a280200360200200920032902003703980720094180026a41186a200141186a29000037030020094180026a41106a200141106a29000037030020094180026a41086a220c200141086a2900003703002009200129000037038002200941d00a6a20094198076a20094180026a108d044101210a200941d00a6a41086a280200210d200941dc0a6a280200210e20092802d40a210f024002400240024002400240024002400240024002400240024002400240024020092802d00a4101460d00200c200e360200200920023b018c022009200f36028402200941b1c5cb003602800220094198076a20094180026a109004200941203602d40a200920094198076a3602d00a20094180026a200941d00a6a1093010240024020092d0080024101470d00200941d0006a4200370300200941c8006a4200370300200941c0006a4200370300200942003703380c010b200941d0006a20094199026a290000370300200941c8006a20094191026a290000370300200941c0006a20094189026a29000037030020092009290081023703380b4101210a0240024020072d00004101470d0020094198026a200741196a29000037030020094190026a200741116a29000037030020094188026a200741096a29000037030020092007290001370380024200211041002111410021120c010b20072d0001210e20094180026a200741046a2802002211200741086a29020022134220882210a710b0014100210a200e41004721120b200941d8006a41186a20094180026a41186a2903002214370300200941d8006a41106a20094180026a41106a220e2903002215370300200941d8006a41086a20094180026a41086a221629030022173703002009200929038002221837035820094198076a41186a201437030020094198076a41106a220c201537030020094198076a41086a221920173703002009201837039807200941b8046a200941386a20094198076a10910420094180026a20092802b804221a20092802c00410920420192016290300370300200c200e290300370300200941d00a6a41086a2216200941a8026a290300370300200941d00a6a41106a221b200941b0026a290300370300200941d00a6a41186a221c200941b8026a290300370300200941d00a6a41206a221d200941c0026a290300370300200920092903800237039807200920094180026a41206a2903003703d00a200928029c02211e0240200928029802220e450d00200941a0016a41106a200c290300370300200941a0016a41086a2019290300370300200941f8006a41086a2016290300370300200941f8006a41106a201b290300370300200941f8006a41186a201c290300370300200941f8006a41206a201d29030037030020092009290398073703a001200920092903d00a3703780b024020092802bc04450d00201a102e0b02400240200e0d004101210520044101470d01200941d00a6a410c108e042009418f026a200941d00a6a41086a2802002202360000200920092903d00a37008702200041186a41003a0000200042003703082000200929008002370019200041216a20094180026a41086a290000370000200041286a2002360000200042013703000c100b200941d4016a201e360200200941b8016a41206a2009290378370300200941b8016a41106a200941a0016a41106a290300370300200941b8016a41086a200941a0016a41086a290300370300200941b8016a41286a200941f8006a41086a290300370300200941e8016a200941f8006a41106a290300370300200941f0016a200941f8006a41186a290300370300200941f8016a200941f8006a41206a290300370300200920092903a0013703b8012009200e3602d0010240024020044101470d00024020092802c8012005470d00200941cc016a2802002006460d020b200941d00a6a410b108e042009418f026a200941d00a6a41086a2802002202360000200920092903d00a3700870241002105200041186a41003a0000200042003703082000200929008002370019200041216a20094180026a41086a290000370000200041286a20023600002000420137030020092802d40141ffffff3f71450d1120092802d001102e0c110b200941d00a6a410a108e042009418f026a200941d00a6a41086a2802002202360000200920092903d00a3700870241002105200041186a41003a0000200042003703082000200929008002370019200041216a20094180026a41086a290000370000200041286a20023600002000420137030020092802d40141ffffff3f71450d1020092802d001102e0c100b4101211b410021044100210c024020092802d801221a0e020605000b41002104201a210c0340200c410176221620046a211920192004200e20194105746a2001412010ec084101481b2104200c20166b220c41014b0d000c050b0b200941186a2002ad42ffff038342004280a0cb9801420010e808200941186a41086a2903002009290318221442809886abec057c2208201454ad7c21140240024002400240024002402011450d002013a7210220120d012002450d002011102e0b20094180026a20012008201410c30220092009290081023703d00a200920094180026a41086a2800003600d70a20092d00800222024106470d044100211d0c010b20094180026a41186a200141186a29000037030020094180026a41106a200141106a29000037030020094180026a41086a200141086a2900003703002009200129000037038002200920134220883e02d80a200920023602d40a200920113602d00a20094198076a20094180026a200941d8006a200941d00a6a2008201410930420092009290099073703b804200920094198076a41086a2800003600bf0420092d00980722024106470d014101211d0b200941b8046a41186a220a200941d8006a41186a290300370300200941b8046a41106a2202200941d8006a41106a290300370300200941b8046a41086a2204200941d8006a41086a290300370300200920092903583703b80420094180026a41186a2207420037030020094180026a41106a2205420037030020094180026a41086a4200370300200942003703800220094180026a41d9fcc6004106108102200941d00a6a4180f4cb0041061081022007200941d00a6a41086a2203290000370300200520092900d00a370300200941106a20094180026a4120108e022009280214210520092802102106200941086a41fcc6cb004110108e02200928020c210c20092802082119200941d00a6a41186a2211200141186a2216290000370300200941d00a6a41106a221a200141106a221b2900003703002003200141086a221c290000370300200920012900003703d00a4120102c2207450d0820072001290000370000200741186a2016290000370000200741106a201b290000370000200741086a201c29000037000020094180026a41146a200c410020191b360200200941ac026a2003290300370200200941b4026a201a290300370200200941bc026a20112903003702002009200837038002200920092903d00a3702a402200920143703880220092005410020061b360290022009419c026a428180808010370200200920073602980220094198076a41186a200a29030037030020094198076a41106a200229030037030020094198076a41086a2004290300370300200920092903b80437039807200941d00a6a200941386a20094198076a10910420092802d00a220320092802d80a20094180026a109404024020092802d40a450d002003102e0b2007102e200941a5026a2009290338370000200941ad026a200941386a41086a290300370000200941b5026a200941386a41106a290300370000200941bd026a200941386a41186a2903003700002009418d026a200141086a29000037000020094195026a200141106a2900003700002009419d026a200141186a290000370000200941003a008402200941143a0080022009200129000037008502200941dd026a200941d8006a41186a290300370000200941d5026a200941d8006a41106a290300370000200941cd026a200941d8006a41086a290300370000200941c5026a200929035837000020094180026a10fe01200bad2108201d0d01200842a08a077e201042e8077e7c42e0ff9fe1007c21080c050b20004200370308200020092903b80437002120004201370300200041206a20023a0000200041186a41003a0000200041286a20092800bf043600000c030b200842d8a1077e201042b8177e7c428093e49f017c21080c030b20004200370308200020092903d00a37002120004201370300200041206a20023a0000200041186a41003a0000200041286a20092800d70a3600000c010b2000200d3600242000420037030820004201370300200041286a200e360000200041206a200f36000041002102200041186a41003a00000c100b410121050c0d0b200042013703082000420037030041002107200041186a41003a0000200041106a20083703000c0a0b0240200e20044105746a2001412010ec08220c0d002004210c4100211b0c010b2004200c411f766a210c0b02400240024002400240201a41ffff0371200241ffff0371220249201b712204201a6a41ffff03712002490d000240024020110d0020094198076a200941d8006a109504200941d00a6a200928029807220220092802a007109604024020092802d00a2219450d0020092902d40a21140240200928029c07450d002002102e0b20092014422088a722163602bc04200920193602b804200941d00a6a200941b8046a109801024020092802d00a2202411c460d0020094198076a200941d00a6a41047241ac0210e9081a20094180026a41047220094198076a41ac0210e9081a200920163602b0040b20092002360280022014a7450d022019102e20092802800221020c020b0240200928029c07450d002002102e0b2009411c360280020c040b20092013422088a722193602bc04200920113602b804200941d00a6a200941b8046a109801024020092802d00a2202411c460d0020094198076a200941d00a6a41047241ac0210e9081a20094180026a41047220094198076a41ac0210e9081a200920193602b0040b20092002360280020b2002411c460d01200941b8046a20094180026a41b00210e9081a20093502b0042114200941d00a6a200941b8046a109704024020092903d00a2008580d0020094198076a410d108e04200941df0a6a20094198076a41086a280200220236000020092009290398073700d70a41002105200041186a41003a000020004200370308200020092900d00a370019200041216a200941d00a6a41086a290000370000200041286a200236000020004201370300200941b8046a108c0420092802d40141ffffff3f71450d0f20092802d001102e0c0f0b20094198076a41186a200941d8006a41186a29030037030020094198076a41106a200941d8006a41106a29030037030020094198076a41086a200941d8006a41086a2903003703002009200929035837039807200941d00a6a200941386a20094198076a10910420092802d00a220720092802d80a10ff01024020092802d40a450d002007102e0b200941d8006a109804200941286a200941dc016a20092903b801200941b8016a41086a29030010fb0120094198076a200941b8046a41b00210e9081a200941c8096a41186a200941386a41186a290300370300200941c8096a41106a200941386a41106a290300370300200941c8096a41086a200941386a41086a290300370300200920092903383703c8094110102c2203450d05200341f8f7c60036020c2003410136020820034281808080103702004110102c2207450d0520074190f8c60036020c20074101360208200742818080801037020020032003280200417f6a220a3602000240200a0d002003280208200328020c2802001103000240200328020c280204450d002003280208102e0b200341046a220a200a280200417f6a220a360200200a0d002003102e0b02400240200728020820094198076a200728020c28020c1101000d004102210320094188076a41023a000020094180076a41003a000020072007280200417f6a220a36020042002108200942003703f006200942013703e8060240200a0d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a220a200a280200417f6a220a360200200a0d002007102e0b20094198076a10dc02410121070c010b200941d00a6a20094198076a41b00210e9081a2009418a0d6a200941d0096a290300370100200941920d6a200941d8096a2903003701002009419a0d6a200941e0096a290300370100200941800d6a41206a200941e6096a29010037010020094180023b01800d200920092903c8093701820d200920073602a80d200941e8066a200941d00a6a200941800d6a10dd0220092903e8064201512107200941e8066a41206a2d0000210320092903f00621080b200941800d6a41186a200141186a290000370300200941800d6a41106a200141106a290000370300200941800d6a41086a200141086a290000370300200920012900003703800d20094198076a41186a200941386a41186a29030037030020094198076a41106a200941386a41106a29030037030020094198076a41086a200941386a41086a2903003703002009200929033837039807200941d00a6a41186a200941d8006a41186a290300370300200941d00a6a41106a200941d8006a41106a290300370300200941d00a6a41086a200941d8006a41086a290300370300200920092903583703d00a200920094190076a2800003600cf0920092009290089073703c8090240024020070d00410621070c010b200920092800cf093600c70a200920092903c8093703c00a4106210720084202510d00200920092800c70a3600b70a200920092903c00a3703b00a200321070b200941c8096a41086a2203200941800d6a41086a290300370300200941c8096a41106a220a200941800d6a41106a290300370300200941c8096a41186a2202200941800d6a41186a290300370300200941900a6a41086a220120094198076a41086a290300370300200941900a6a41106a220420094198076a41106a290300370300200941900a6a41186a220c20094198076a41186a290300370300200941f0096a41186a2219200941d00a6a41186a290300370300200941f0096a41106a2216200941d00a6a41106a290300370300200941f0096a41086a221a200941d00a6a41086a290300370300200920092903800d3703c80920092009290398073703900a200920092903d00a3703f009200920092800b70a3600c70a200920092903b00a3703c00a200941dd0a6a2003290300370000200941e50a6a200a290300370000200941ed0a6a2002290300370000200941143a00d00a200920092903c8093700d50a200941023a00d40a200941f50a6a20092903900a370000200941fd0a6a2001290300370000200941850b6a20042903003700002009418d0b6a200c290300370000200941ad0b6a2019290300370000200941a50b6a20162903003700002009419d0b6a201a290300370000200941950b6a20092903f009370000200941b70b6a20094198076a41026a2d00003a0000200941b50b6a20092f0098073b0000200941c00b6a20073a0000200941bc0b6a2006360200200941b80b6a2005360200200941c80b6a20092800c70a360000200941c10b6a20092903c00a370000200941d00a6a10fe010240024020092802f0060d00420021080c010b427f200bad42d886107e20144288277e7c42c0c995d6017c2208200941e8066a41106a2903007c221420142008541b2114420121080b20002008370308200020092800d00a36001920004200370300200041186a41003a0000200041106a20143703002000411c6a200941d30a6a280000360000024020092802d40141ffffff3f71450d0020092802d001102e0b410121072011450d0d2013a7450d0d2011102e0c0d0b2009411c360280020b2011450d00024020120d002013a7450d012011102e0c010b200941d00a6a41186a200141186a290000370300200941d00a6a41106a200141106a290000370300200941d00a6a41086a200141086a290000370300200920012900003703d00a2009201337029c072009201136029807200941b8046a200941d00a6a200941d8006a20094198076a42004200109304200920092900b9043703e8062009200941b8046a41086a2800003600ef06024020092d00b80422024106460d0020004200370308200020092903e80637002120004201370300200041206a20023a0000200041186a41003a0000200041286a20092800ef063600000c020b410121024101210720040d020c040b4100210220040d0120094198076a4102108e04200941df0a6a20094198076a41086a280200220236000020092009290398073700d70a200041186a41003a000020004200370308200020092900d00a370019200041216a200941d00a6a41086a290000370000200041286a2002360000200042013703000b0240200928028002411c460d0020094180026a108c040b024020092802d40141ffffff3f71450d0020092802d001102e0b410021050c0b0b200941d00a6a41186a200141186a290000370300200941d00a6a41106a200141106a290000370300200941d00a6a41086a200141086a290000370300200920012900003703d00a20092802d8012207200c490d0302400240200720092802d401470d00200741016a22032007490d062007410174220a2003200a20034b1b22034104200341044b1b220341ffffff3f71200346210a200341057421030240024020070d0020094100360298070c010b200941a0076a4101360200200920092802d001360298072009200741057436029c070b200941b8046a2003200a20094198076a107d200941c0046a280200210320092802b8044101460d01200920092802bc043602d001200920034105763602d4010b20092802d001200c4105746a220341206a20032007200c6b41057410ea081a200341186a200941d00a6a41186a290300370000200341106a200941d00a6a41106a290300370000200341086a200941d00a6a41086a290300370000200320092903d00a3700002009200741016a3602d801200941d00a6a200941b8016a41c80010e9081a20094198076a41186a200941d8006a41186a29030037030020094198076a41106a200941d8006a41106a29030037030020094198076a41086a200941d8006a41086a2903003703002009200929035837039807200941b8046a200941386a20094198076a10910420092802b804220720092802c004200941d00a6a109404024020092802bc04450d002007102e0b0240200941ec0a6a28020041ffffff3f71450d0020092802e80a102e0b200941f50a6a2009290338370000200941dd0a6a200141086a290000370000200941e50a6a200141106a290000370000200941ed0a6a200141186a290000370000200941fd0a6a200941386a41086a290300370000200941850b6a200941386a41106a2903003700002009418d0b6a200941386a41186a290300370000200941013a00d40a200941143a00d00a200920012900003700d50a200941b80b6a2005360200200941bc0b6a2006360200200941ad0b6a200941d8006a41186a290300370000200941a50b6a200941d8006a41106a2903003700002009419d0b6a200941d8006a41086a290300370000200941950b6a2009290358370000200941d00a6a10fe014100210720020d02200bad42c0a6087e201042e8077e7c42b090bbca007c2108410021070c030b2003450d040b1036000b200bad42f093097e201042b8177e7c42d086c192017c21080b2000420137030820004200370300200041186a41003a0000200041106a2008370300200928028002411c470d0220070d030c040b200c20071045000b1038000b20094180026a108c042007450d010b20092802d40141ffffff3f71450d0020092802d001102e0b410121070b0240200d41ffffff3f71450d00200f102e0b02402007200e45720d00201e41ffffff3f71450d00200e102e0b200941b00d6a24000f0b2011450d002013a7450d002011102e0b0240200d41ffffff3f71450d00200f102e0b02400240200e450d0020054101730d00201e41ffffff3f710d010b410021020c020b200e102e410021020c010b4101210a410121020b024020072d00000d00200a450d00200741086a280200450d00200741046a280200102e0b02402002450d00200341046a28020041ffffff3f71450d002003280200102e0b200941b00d6a24000bcd0101047f230041106b2202240002400240200141086a28020022034105744116722204417f4c0d002004102c2205450d0120024100360208200220043602042002200536020020022001280200411010742001280204210420032002107602402003450d002003410574210303402002200441201074200441206a2104200341606a22030d000b0b200220012f010c3b010e20022002410e6a41021074200020022802002204200228020810b00102402002280204450d002004102e0b200241106a24000f0b1038000b1036000bd40301037f230041f0006b2203240020034195fec6004108108102200341106a41f4f3c3004109108102024002404120102c2204450d002003422037025420032004360250200341d0006a2001412010742003200328025022012003280258220410a301370340200341ec006a200120046a360200200320013602682003200341c0006a41086a3602642003200341c0006a360260200341206a200341e0006a107c02402003280254450d002001102e0b4120102c2201450d002003422037024420032001360240200341c0006a200241201074200341d0006a200328024022012003280248220210d803200341ec006a200120026a360200200320013602682003200341e0006a3602642003200341d0006a360260200341306a200341e0006a107c02402003280244450d002001102e0b20032802282202200328023822046a41206a2201417f4c0d010240024020010d00410121050c010b2001102c2205450d010b20004100360208200020013602042000200536020020002003411010742000200341106a41101074200020032802202201200210742000200328023022022004107402402003280234450d002002102e0b02402003280224450d002001102e0b200341f0006a24000f0b1036000b1038000bc00502057f077e23004190016b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200041003602180c010b200328021421042003200341186a2802002202360244200320013602400240024020024104490d00200128000021052003200141046a36024020032002417c6a220636024420064104490d002003200141086a360240200128000421072003200241786a220636024420064110490d002003200241686a3602442003200141186a360240200141106a290000210820012900082109200341e8006a200341c0006a10930120032d00684101460d00200341c8006a41186a20034181016a290000370300200341d8006a200341f9006a290000370300200341d0006a200341f1006a290000370300200320032900693703482003200341c0006a10ab0102402003280200450d00200341003602680c010b200341e8006a200341c0006a200328020410920120032802682202450d00200341206a41086a200341c8006a41086a290300220a370300200341206a41106a200341c8006a41106a290300220b370300200341206a41186a200341c8006a41186a290300220c37030020032003290348220d370320200329026c210e20002008370308200020093703002000200e37021c200020023602182000200736021420002005360210200041246a200d3702002000412c6a200a370200200041346a200b3702002000413c6a200c3702000c010b20034100360250200342013703482003410a3602242003200341086a3602202003200341c8006a36028c01200341fc006a41013602002003420137026c200341909dc5003602682003200341206a3602782003418c016a419cebc000200341e8006a103d1a2003280248200328025010ef020240200328024c450d002003280248102e0b200041003602180b2004450d002001102e0b20034190016a24000bc70603037f027e017f23004180016b22062400200641106a2002109504200628021022072006280218108f02210802402006280214450d002007102e0b024002400240024002402008450d002000410e108e040c010b2006200341086a2208280200411f6a410576ad42004280a0cb9801420010e808200641106a2001200420062903007c220942809886abec057c220a2005200641086a2903007c2009200454ad7c200a200954ad7c220410c302200620062900113703702006200641106a41086a2207280000360077024020062d0010220b4106470d00200641c8006a200437030020072008280200360200200641246a200141086a2900003702002006412c6a200141106a290000370200200641346a200141186a2900003702002006200a370340200620032902003703102006200129000037021c200641d0006a4195fec6004108108102200641f0006a41ccf4c30041051081024120102c2203450d032006422037026420062003360260200641e0006a20024120107420062802682203417f4c0d04200628026021010240024020030d00410121020c010b2003102c2202450d040b20022001200310e908210202402006280264450d002001102e0b200341206a2201417f4c0d042001102c2208450d03200641003602682006200136026420062008360260200641e0006a200641d0006a41101074200641e0006a200641f0006a41101074200641e0006a20022003107402402003450d002002102e0b2006280218220141146a2203417f4c0d0420062802602102200628026821080240024020030d00410121070c010b2003102c2207450d040b200641003602582006200336025420062007360250200628021021032001200641d0006a1076200641d0006a200320011074200641d0006a2006411c6a41201074200620043703782006200a370370200641d0006a200641f0006a411010742002200820062802502201200628025810b20102402006280254450d002001102e0b02402006280264450d002002102e0b02402006280214450d002003102e0b200041063a00000c020b2000200b3a000020002006290370370001200041086a20062800773600000b200341046a280200450d002003280200102e0b20064180016a24000f0b1036000b1038000be50103017f017e017f230041206b220324002003410036020820034201370300200320022802103602102003200341106a410410742003200241146a2802003602102003200341106a41041074200229030021042003200241086a290300370318200320043703102003200341106a411010742003200241246a4120107420022802182105200241206a28020022022003107602402002450d002002410574210203402003200541201074200541206a2105200241606a22020d000b0b2000200120032802002205200328020810b20102402003280204450d002005102e0b200341206a24000bf50101047f230041306b2202240020024195fec6004108108102200241106a41ccf4c3004105108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bee0502087f057e23004190016b220324002003200236020c20032001360208200341106a2001200210ed0202400240024002400240200328021022010d00200041003602000c010b200328021421022003200341186a280200360244200320013602402003200341c0006a10ab0102400240024020032802000d002003280244220420032802042205490d002005417f4c0d040240024020050d00410121060c010b200510322206450d06200328024421040b024020042005490d0020062003280240200510e9082107200328024422042005490d072003200420056b3602442003200328024020056a360240200341e8006a200341c0006a109301024020032d00684101470d0020050d010c020b200341c8006a41186a220420034181016a290000370300200341c8006a41106a2208200341f9006a290000370300200341c8006a41086a2209200341f1006a290000370300200320032900693703482003280244220a410f4b0d022005450d010b2006102e0b20034100360250200342013703482003410a3602242003200341086a3602202003200341c8006a36028c01200341fc006a41013602002003420137026c200341909dc5003602682003200341206a3602782003418c016a419cebc000200341e8006a103d1a2003280248200328025010ef020240200328024c450d002003280248102e0b200041003602000c010b200341206a41086a2009290300220b370300200341206a41106a2008290300220c370300200341206a41186a2206200429030037030020032003290348220d3703202003200a41706a36024420032003280240220441106a360240200441086a290000210e2004290000210f200041086a20053602002000200536020420002007360200200041386a200e370300200041306a200f3703002000410c6a200d370200200041146a200b3702002000411c6a200c370200200041246a20062903003702000b2002450d002001102e0b20034190016a24000f0b1038000b1036000b2005200441b8b2c0001056000bd34804017f027e107f037e230041d0016b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c0102030405060708090a0b0c0d0e0f101112131415161718191a1b00010b20014184026a350200210320014180026a3502002104200141f4016a2802002105200141e8016a2802002106200141dc016a2802002107200141d0016a2802002108200141c4016a2802002109200141b8016a280200210a200141ac016a280200210b200141a0016a280200210c20014194016a280200210d20014188016a280200210e200141fc006a280200210f200141f0006a2802002110200141e4006a2802002111200141d8006a2802002112200141cc006a2802002113200141c0006a2802002114200241086a200141386a109706200342889b047e200442f0aefa017e7c417f2005417f2006417f2007417f2008417f2009417f200a417f200b417f200c417f200d417f200e417f200f417f2010417f2011417f2012417f201420136a220120012014491b22016a221420142001491b22016a221420142001491b22016a221420142001491b22016a221420142001491b22016a221420142001491b22016a221420142001491b22016a221420142001491b22016a221420142001491b22016a221420142001491b22016a221420142001491b22016a221420142001491b22016a221420142001491b22016a221420142001491b22016a221420142001491bad42e8aede067e7c200235021042a0ede0017e7c4280e59af7007c21030240200228020c41808080807872418080808078460d002002280208102e0b200041003b0108200020033703000c1b0b02400240024002400240024002400240024002400240200141086a2802000e0b000102030405060708090a000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194cccc003602c0012002200241c0016a360218200241086a41ecc5cc001044000b2001410c6a3502002103200241086a10a90320022903102104200041003b0108200020032004428094ebdc03807e20032004428094ebdc03827e2203428094ebdc038042ffffffff0f2003428080808080c0b2cd3b541b2003428094ebdc03824280cab5ee0156ad7c42ffffffff0f837c3703000c230b200041003b0108200042b0f7d0003703000c220b200041013b0108200042a8afc8303703000c210b200241086a10a90320022903102103200041013b0108200020033703000c200b200241086a10a90320022903102103200041013b0108200020033703000c1f0b200041013b0108200042e8f084f0003703000c1e0b200041013b01082000200141146a3502004290a7fa2f7e3703000c1d0b200041013b01082000200141146a3502004280f4f02f7e3703000c1c0b200041013b01082000417f200141186a280200220141016a221420142001491bad42f8f88b307e3703000c1b0b200041003b01082000200141146a35020042e8077e3703000c1a0b024002400240024002400240024020012d00040e0700010203040506000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41ecb0c4001044000b200041003b0108200042d8c4c7c8003703000c1e0b200041003b010820004290cf93bc013703000c1d0b200041003b0108200042f8a8ee87013703000c1c0b200041003b010820004288b68eca013703000c1b0b200041003b0108200042d8c4c7c8003703000c1a0b200041003b0108200042f8a8ee87013703000c190b0240024002400240200141086a2802000e0400010203000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194cccc003602c0012002200241c0016a360218200241086a4190afc4001044000b200041003b010820002001411c6a280200220141e400200141e4004b1bad4298d70a7e4280a9f3bbb0027c3703000c1a0b200041003b010820002001411c6a280200220141e400200141e4004b1bad4298d70a7e4280a9f3bbb0027c3703000c190b200041003b010820004280c2d72f3703000c180b200041023b0108200042a0bebbd8003703000c170b02400240024002400240024020012d00040e06000102030405000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41e89bc4001044000b200041003b0108200042a887a2cf003703000c1a0b200041003b0108200042c8f8978f013703000c190b200041003b0108200042e8e398cf003703000c180b200041003b010820004280c6928b013703000c170b200041003b0108200042b8a8b4ce003703000c160b02400240024002400240200141086a2802000e050001020304000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194cccc003602c0012002200241c0016a360218200241086a4194a7c7001044000b200041003b0108200042e8dae8df003703000c180b200041003b0108200042f085f7cc003703000c170b200041003b0108200042988ef29a013703000c160b200041003b0108200042d0e0dad6003703000c150b200041023b0108200042003703000c140b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141086a2d00000e18000102030405060708090a0b0c0d0e0f1011121314151617000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41f4ebc6001044000b200041003b0108200042f0a8939e023703000c290b200041003b0108200042c8c6ce9e013703000c280b200041003b0108200042b8f4cad7013703000c270b200041003b010820002001410c6a350200220342f8ef9e017e20034280c2d72f7e7c4290fb86ed037c3703000c260b200041003b010820004280e5a9f2003703000c250b200041003b01082000200141146a350200220342f094d6027e200342c0f0f50b7e7c4280d0d98e017c3703000c240b200041003b010820004298e7fcf1003703000c230b200041003b0108200042f0dba8c1003703000c220b200041003b010820004280f7b6bf013703000c210b200041003b0108200042c8b6d0303703000c200b200041003b0108200042c8b6d0303703000c1f0b200041003b0108200042c8b6d0303703000c1e0b200041003b0108200042808fe5303703000c1d0b200041003b0108200042d0a1e4303703000c1c0b200041003b01082000200141146a35020042b891027e428086e8307c3703000c1b0b200041003b010820002001412c6a350200220342c0db9d017e20034280c2d72f7e7c42c0abb4c9037c3703000c1a0b200041003b0108200042a0bde0303703000c190b200041003b01082000200141186a35020042a8edc0107e42d8c8e8c0167c3703000c180b200041003b0108200042c88dfff4d5033703000c170b200041003b0108200042f8b3dac4013703000c160b200041003b01082000200141106a35020022034298bfe50e7e20034280cee4cd027e7c4280e9c9d6017c3703000c150b200041003b010820002001412c6a350200220342b08a9e017e20034280c2d72f7e7c428091a2cb037c3703000c140b200041003b01082000200141146a350200220342b0b2cf087e200342c0f0f50b7e7c20034280c2d72f7e7c42b0fbf2107c3703000c130b108405000b200041003b0108200042b08ee2d00342b0a1bafa0220012802041b3703000c110b0240024002400240200141086a2802000e0400010203000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41c499c9001044000b200041003b010820002001411c6a280200220141e400200141e4004b1bad4298d70a7e42c0c6cbccb0027c3703000c120b200041003b010820002001411c6a280200220141e400200141e4004b1bad4298d70a7e42c0c6cbccb0027c3703000c110b200041003b0108200042c0cf8e313703000c100b200041003b01082000200141286a35020042d0e50d7e2001411c6a35020042e092197e7c42c0b7828b017c3703000c0f0b109f04000b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141086a2d00000e1a000102030405060708090a0b0c0d0e0f10111213141516171819000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41c0accb001044000b200041003b0108200042a8cad6cf013703000c250b200041003b01082000200141106a35020042a0f80c7e42f89f9fcf007c3703000c240b200041003b010820004288dbaed7013703000c230b200041013b0108200042d0ed9c85013703000c220b200041003b010820004280ac9cd3003703000c210b200041003b010820004288dc82313703000c200b200041003b010820004280b582313703000c1f0b200041003b0108200042b0d0b5b4013703000c1e0b200041003b0108200042d89afd8e013703000c1d0b200041003b01082000429080ef373703000c1c0b200041013b0108200042f899c995013703000c1b0b200041003b01082000429887abd1333703000c1a0b200041003b010820004290fbc2c9323703000c190b200041003b0108200042d09be6303703000c180b200041003b01082000200141146a35020042a01f7e42f0ae87d1007c3703000c170b200041013b01082000200141146a35020042a01f7e42f0ae87d1007c3703000c160b200041003b01082000200141146a35020042b8177e4298d7a9c9007c3703000c150b200041013b01082000200141146a35020042b8177e4298d7a9c9007c3703000c140b200041003b010820002001412c6a35020042b8177e42c0cae5da007c3703000c130b200041003b0108200042b880d9d1013703000c120b200041003b01082000428881b08d013703000c110b200041003b010820004298c3b48d013703000c100b200241086a10a90320022903102103200041003b0108200020033703000c0f0b200041013b0108200042c88892a5033703000c0e0b200041003b010820004290848df0013703000c0d0b0240024002400240024002400240200141086a2d00000e0700010203040506000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41b8afc9001044000b200041013b01082000200141346a35020042b882077e200141386a35020042c0b5e5097e7c42a0c0b291397c3703000c110b200141106a3502002103200241086a2001410c6a28020010970420022903082104200041013b01082000427f2004200342a01f7e42d8878f1c7c22037c220420042003541b3703000c100b200141146a2802002114024002402001410c6a28020041014b0d00200241086a200141106a280200109704427f2014ad42a01f7e42f8f3e32f7c220320022903087c220420042003541b21030c010b2014ad4288277e4280d997a0027c21030b200041013b0108200020033703000c0f0b200041013b0108200042a0949fe6003703000c0e0b200041013b01082000427f200141306a35020042b8177e42e090bd8a027c2203200141386a2903007c220420042003541b3703000c0d0b200041003b010820004290d591bc013703000c0c0b0240024002400240024002400240200141086a2d00000e0700010203040506000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41b8afc9001044000b200041013b01082000200141346a35020042b882077e200141386a35020042c0b5e5097e7c42a0c0b291397c3703000c100b200141106a3502002103200241086a2001410c6a28020010970420022903082104200041013b01082000427f2004200342a01f7e42d8878f1c7c22037c220420042003541b3703000c0f0b200141146a2802002114024002402001410c6a28020041014b0d00200241086a200141106a280200109704427f2014ad42a01f7e42f8f3e32f7c220320022903087c220420042003541b21030c010b2014ad4288277e4280d997a0027c21030b200041013b0108200020033703000c0e0b200041013b0108200042a0949fe6003703000c0d0b200041013b01082000427f200141306a35020042b8177e42e090bd8a027c2203200141386a2903007c220420042003541b3703000c0c0b200041003b010820004290d591bc013703000c0b0b0240024002400240024002400240200141086a2d00000e0700010203040506000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a4188f3c0001044000b200041003b01082000200141146a35020022034288f1117e42d0ef9dbc017c2204200342c8ac137e42c0da8abc017c221520042015561b2204200342c082147e4290faffaf017c220320042003561b3703000c0f0b200041003b0108200042f8a1f095013703000c0e0b200041003b010820002001410c6a35020042e08f1a7e42f0e2efee007c3703000c0d0b4288e3e7d40021030240024002402001410c6a2802000e03010200010b200141106a35020042e0b30e7e42c089ecd1007c21030c010b42f0f7f0920221030b200041003b0108200020033703000c0c0b42e0fca3da022103024020012d00090d00200241086a10a903200229031021030b200041003b0108200020033703000c0b0b200041003b010820002001410c6a350200220342a0838b377e200342c0d1e1237e7c20034280c6868f017e7c4280c2d72f7c3703000c0a0b0240024002400240024002400240024020012d00040e080001020304050607000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41a4c3cb001044000b200041003b010820004280e1eb173703000c0f0b200041003b010820004280e1eb173703000c0e0b200041003b010820004280e1eb173703000c0d0b200041003b010820004280e1eb173703000c0c0b200041003b010820004280e1eb173703000c0b0b200041003b010820004280e1eb173703000c0a0b200041003b010820004280e1eb173703000c090b0240024002400240200141086a2802000e0400010203000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a4184ccc2001044000b200041003b0108200042c88b98ff003703000c0a0b200041013b0108200042f8b59f92013703000c090b200041013b0108200042c0b4c6cb003703000c080b024002400240024002400240200141086a2d00000e06000102030405000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41e0f3c0001044000b200041003b0108200042e8b0efff043703000c0b0b200041003b0108200042b8e5dbd3013703000c0a0b200041003b0108200042b895a182053703000c090b20004180023b0108200042a8a0c4a7043703000c080b200041003b0108200042e0ecad90033703000c070b02400240024002400240200141086a2802000e050001020304000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194cccc003602c0012002200241c0016a360218200241086a41aca7c7001044000b200041003b0108200042f0ee8291013703000c090b200041003b0108200042a8aac0cc013703000c080b200041003b010820004288b0b6e7013703000c070b200041003b010820004280c2eca2023703000c060b024002400240024002400240024020012f01040e0400010203000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194cccc003602c0012002200241c0016a360218200241086a41fcc5cc001044000b200141106a280200220741ffffffff00712007470d0b41082106200141086a2802002114024020074104742201450d002001102c2206450d030b02400240024002402001410476220820074f0d00200141037622052007200520074b1b22054104200541044b1b220541ffffffff00712005464103742108200541047421050240024020010d00200241003602080c010b200241086a41086a41083602002002200136020c200220063602080b200241c0016a20052008200241086a107d200241c8016a280200210120022802c0014101460d0120022802c4012106200141047621080b20142014200741b0026c6a470d0142002103200621050c020b20010d040c0d0b200741b0026c2105200741047441706a4104762109200621010340200241086a2014109704200141086a200241086a41086a29030037030020012002290308370300200141106a2101201441b0026a2114200541d07d6a22050d000b2006200941016a41047422146a2105420021034100210141000d000340427f2003200620016a2903007c220420042003541b21032014200141106a2201470d000b0b427f2007ad4288b0fa007e20037c42c8b8fa067c220420042003541b21032005200622146b210141012107024003402001450d01200141706a2101201441086a2105201441106a211420052d00004101460d000b410021070b02402008450d002006102e0b200041003a0009200020073a0008200020033703000c0a0b200241086a200141086a2802001097042002290308210320022d00102101200041003a0009200020013a00082000427f200342d0ceae3d7c220420042003541b3703000c090b200141106a280200220741ffffffff00712007470d0941082106200141086a2802002114024020074104742201450d002001102c2206450d010b024002402001410476220820074f0d00200141037622052007200520074b1b22054104200541044b1b220541ffffffff00712005464103742108200541047421050240024020010d00200241003602080c010b200241086a41086a41083602002002200136020c200220063602080b200241c0016a20052008200241086a107d200241c8016a280200210120022802c0014101460d0120022802c4012106200141047621080b20142014200741b0026c6a470d0242002103200621050c030b2001450d090b1036000b200741b0026c2105200741047441706a4104762109200621010340200241086a2014109704200141086a200241086a41086a29030037030020012002290308370300200141106a2101201441b0026a2114200541d07d6a22050d000b2006200941016a41047422146a2105420021034100210141000d000340427f2003200620016a2903007c220420042003541b21032014200141106a2201470d000b0b427f2007ad42e88dfb007e20037c42e0b8a1077c220420042003541b21032005200622146b210141012107024003402001450d01200141706a2101201441086a2105201441106a211420052d00004101460d000b410021070b02402008450d002006102e0b200041003a0009200020073a0008200020033703000c050b0240024002400240024002400240024002400240024002400240024002400240200141086a2d00000e10000102030405060708090a0b0c0d0e0f000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41f89bc4001044000b200041003b010820004288b69ac9003703000c120b200041003b0108200042a0ac9c8e013703000c110b200041003b01082000200141146a350200220342b8fea8037e200342c0f0f50b7e7c20034280c2d72f7e7c4290cae8c7277c3703000c100b200041003b0108200042f0d98bc5273703000c0f0b200041003b010820004288bb99aa013703000c0e0b200041003b010820004288abfb99013703000c0d0b200041003b0108200042e0ecafc2003703000c0c0b200041003b010820004288f0efc2003703000c0b0b200041003b0108200042d092b3c2003703000c0a0b200041003b0108200042c8fee29f013703000c090b200041003b0108200042e891b0e6273703000c080b200041003b0108200042e099e6a8013703000c070b200041003b0108200042889e8ad1003703000c060b200041003b010820004288ee8ea8013703000c050b200041003b0108200042e8dcfb90013703000c040b0240024002400240024002400240024002400240024020012d00040e0b000102030405060708090a000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194cccc003602c0012002200241c0016a360218200241086a4198f3c0001044000b200241086a200141286a2802001097042002290308210320022d00102101200041003a0009200020013a00082000427f200342f0f6e0d5007c220420042003541b3703000c0c0b200041003b0108200042f097e5d0003703000c0b0b200041003b0108200042a0fe91d1003703000c0a0b200041003b010820004298b0a4cf003703000c090b200041003b0108200042e0cedfdf003703000c080b200041003b0108200042b0b19ed0003703000c070b200041003b0108200042c0ff90a8013703000c060b200041003b0108200042a0a68f93013703000c050b200041003b0108200042c8e69193013703000c040b200241086a200141c8006a2802001097042002290308210320022d00102101200041003a0009200020013a00082000427f200342b0c1a4e5017c220420042003541b3703000c030b02400240024002400240200141086a2d00000e050001020304000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41889cc4001044000b200241086a200141186a2802002201109704200241003602c801200242013703c0012001200241c0016a10900220023502c8012103024020022802c401450d0020022802c001102e0b2002290308210420022d00102101200041003a0009200020013a00082000427f427f2004200342e8077e42b0b182067c22037c220420042003541b220342c0b2cd3b7c220420042003541b3703000c050b200041003b01082000427f200141146a350200220342a08a077e2001412c6a350200220442e8077e22157c42e0ff9fe1007c2216200342d8a1077e200442b8177e7c428093e49f017c221720162017561b2216200342c0a6087e20157c42b090bbca007c221520162015561b2215200342d886107e20044288277e7c42c0c995d6017c220320152003561b2203200141306a2903007c220420042003541b3703000c040b200041003b01082000427f200141346a350200220342a08a077e42f8c287e1007c2204200342f096087e42b8f9a5ca007c221520042015561b220420034298c5107e4288b6fef8017c220320042003561b2203200141c8006a2903007c220420042003541b3703000c030b200041003b01082000200141346a35020042f8c0077e42b8dfe7a6017c3703000c020b0240024002400240024002400240024002400240200141086a2802000e0a00010203040506070809000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41e0ecc0001044000b200041003b01082000200141146a35020042e8077e42a0a080ec017c3703000c090b200041003b0108200042c0bcd7fc003703000c080b200041003b0108200042c8e4e73f3703000c070b200041003b0108200042b08ddb93013703000c060b200041003b010820004298c6bf89013703000c050b200041003b0108200042d8cac8c7003703000c040b200041003b0108200042b897cedd023703000c030b200041003b01082000428887a88c023703000c020b200041003b0108200042c89596c7003703000c010b0240024002400240024002400240200141086a2d00000e0700010203040506000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602c40120024194c3cb003602c0012002200241c0016a360218200241086a41d4cec8001044000b200041003b01082000200141346a35020042d00f7e42a096ca8f017c3703000c050b200041003b0108200042a0cfe181013703000c040b200041003b01082000200141346a35020042d00f7e42a0899387017c3703000c030b200041003b0108200042c0c1f7d5003703000c020b200041003b010820004288fbb8de013703000c010b200041003b010820004280e4c4f7003703000b200241d0016a24000f0b1038000baa0303067f027e017f230041b0016b22012400200141386a2000109504200141c8006a2001280238220220012802402203109604024020012802482200450d002002200310ff010b20014188016a41086a2203200141c8006a41106a29030037030020014188016a41106a2204200141c8006a41186a29030037030020014188016a41186a2205200141c8006a41206a29030037030020014188016a41206a2206200141f0006a2802003602002001200141c8006a41086a290300370388010240024020000d00200128023c450d012002102e0c010b20014180016a2903002107200141f8006a2903002108200128024c2109200141106a41206a2006280200360200200141106a41186a2005290300370300200141106a41106a2004290300370300200141106a41086a200329030037030020012001290388013703100240200128023c450d002002102e0b200141e0006a2001412c6a290200370300200141d8006a200141246a290200370300200141d0006a2001411c6a290200370300200120012902143703482001200141c8006a2008200710fb012009450d002000102e0b200141b0016a24000bc64b0a017f017e047f017e017f037e087f017e147f027e230041d0076b22042400200441c0006a20024180026a290000370300200441386a200241f8016a290000370300200441286a41086a200241f0016a290000370300200420022900e80137032820022903002105200441e8016a200241880210e9081a200420044180056a3602f403200420044180056a3602f003200441d0056a200441e8016a41086a2206109a04200441f8036a200441e0026a2207109a0402400240024002400240200441d0056a200441f8036a412010ec08450d00200441fc016a2802002208450d00200441f4016a2802002102200841246c21080340024020022d00004101470d00200241016a28000041c28289aa04470d002004200241106a2802003602d4052004200241086a2802003602d005200441f8036a200441d0056a10930220042903f8034203510d00200441ec026a2802002208450d022004280288042109200429038004210a200441e4026a2802002102200841246c2108024002400240024002400340024020022d00004101470d00200241016a28000041c28289aa04470d002004200241106a2802003602d4052004200241086a2802003602d005200441f8036a200441d0056a10930220042903f8034203510d0020042903e801200a520d09200a200429038004520d092009200428028804470d09200441f8036a200641f00010e9081a2004200441d0036a22023602e804200441f8036a2002109b04450d0a200441f8036a200741f00010e9081a200420023602e804200441f8036a2002109b04450d0b2003280210210b20032802002107200441e8016a41186a22024200370300200441e8016a41106a22084200370300200441e8016a41086a22064200370300200442003703e801200441f8036a41a8f8c60041041081022006200441f8036a41086a2209290000370300200420042900f8033703e801200441f8036a41e38bc500410b10810220022009290000370300200820042900f803370300200441186a200441e8016a10850302402007420020052004290320420020042802181b7d220a200a2005561b220a42e01280a7417f200a428080808080ac02541b460d00200441e8016a4102109c0420004201370300200041286a200441e8016a41206a290300370300200041206a2002290300370300200041186a2008290300370300200041106a2006290300370300200020042903e8013703080c0d0b2004418c056a200441286a41086a29030037020020044194056a200441286a41106a2903003702002004419c056a200441286a41186a290300370200200441e2c289ab0636028005200420042903283702840520044198016a41106a200341106a28020036020020044198016a41086a200341086a2902003703002004200329020037039801200441d0056a20044180056a20044198016a109d04200428029006450d02200441e8016a41066a200441d0056a41d00010e9081a200441f8036a200441e8016a41d60010e9081a200441c8006a200441f8036a41066a41d00010e9081a20044198016a200441c8006a41d00010e9081a4101210841002103024020012d00004101470d00200441e8016a41186a2202200141196a290000370300200441e8016a41106a2203200141116a290000370300200441e8016a41086a2206200141096a290000370300200420012900013703e8014120102c2208450d06200820042903e801370000200841186a2002290300370000200841106a2003290300370000200841086a2006290300370000410121030b200420053703f803200441f8036a41086a20044198016a41d00010e90821022004200b3602d404200420073602d00441d000102c2206450d05200441e8016a41086a2207200241086a290300370300200441e8016a41106a2201200241106a290300370300200441e8016a41186a2209200241186a290300370300200420022903003703e801200441f8036a41286a290300210a200441a8046a290300210c200441f8036a41386a290300210d200441b8046a290300210e200441d0056a200441f8036a41c8006a10c501200641386a200e3703002006200d370330200641286a200c3703002006200a370320200641186a2009290300370300200641106a2001290300370300200641086a2007290300370300200620042903e801370300200620042903d005370340200641c8006a200441d0056a41086a280200360200200420033602f804200420033602f404200420083602f0044108102c2202450d05200442083702e406200420023602e006200420053703e8014108210f200441e0066a200441e8016a41081074200441e8016a419997c500108a03200441d0056a20042802e801220820042802f001108b0320042902d405420020042802d00522021b210a2002410120021b2109024020042802ec01450d002008102e0b2004200a4220883e02c407200420093602c007200441106a200441c0076a10ab01410021104100211120042802100d042004280214221220042802c40741286e2202200220124b1bad42287e220c422088a70d06200ca72202417f4c0d060240024020020d00410821130c010b2002102c2213450d060b200241286e2114024020120d00410021120c040b41002115034002400240024020042802c40722084108490d00201541016a211620042802c0072207290000210c2004200841786a22013602c4072004200741086a3602c00741002102200441003a008802200841776a21080240034020012002460d01200441e8016a20026a200720026a220341086a2d00003a00002004200341096a3602c0072004200241016a22033a008802200420083602c4072008417f6a21082003210220034120470d000b200441d0056a41186a2202200441e8016a41186a290300370300200441d0056a41106a2208200441e8016a41106a290300370300200441d0056a41086a2207200441e8016a41086a290300370300200420042903e8013703d005200341ff01714120490d01200441c0066a41086a2007290300220d370300200441c0066a41106a2008290300220e370300200441c0066a41186a20022903002217370300200441a0066a41186a22082017370300200441a0066a41106a2203200e370300200441a0066a41086a2207200d370300200420042903d005220d370380072004200d3703c0062004200d3703a00620152014470d03201441016a220220144f0d020c0b0b200241ff0171450d00200441003a0088020b410021104108210f02402014450d00201441286c450d002013102e0b410021110c070b201441017422012002200120024b1b22024104200241044b1bad42287e220d422088a7454103742102200da721010240024020140d00200441003602e8010c010b200441083602f001200420133602e8012004201441286c3602ec010b200441d0056a20012002200441e8016a107d20042802d8052102024020042802d0054101470d002002450d090c080b20042802d4052113200241286e21140b2013201541286c6a2202200c370300200220042903a006370308200241106a2007290300370300200241186a2003290300370300200241206a20082903003703002016211520162012460d040c000b0b200241246a21022008415c6a22080d000c080b0b200441e8016a4102109c0420004201370300200041286a200441e8016a41206a290300370300200041206a200441e8016a41186a290300370300200041186a200441e8016a41106a290300370300200041106a200441f0016a290300370300200020042903e8013703080c0a0b2012410020131b21112014410020131b21102013410820131b210f0b200441e8016a419997c500200441e0066a108c03200441d0056a20042802e801220820042802f001108d0320042902d405420020042802d00522021b210c024020042802ec01450d002008102e0b200c422088210d20042802e806211820042802e406211920042802e006211a0240200aa7450d002009102e0b2002410120021b211b200da7211c200ca7211d200441e8016a41086a2202200641086a290300370300200441e8016a41106a2208200641106a290300370300200441e8016a41186a2203200641186a290300370300200441e8016a41206a2207200641206a290300370300200441e8016a41286a2201200641286a290300370300200441e8016a41306a2209200641306a290300370300200441e8016a41386a2214200641386a290300370300200441d0056a41086a2212200641cc006a280200360200200420062903003703e801200420062902443703d00502400240200628024022130d00410021070c010b20044180076a41386a2215201429030037030020044180076a41306a2214200929030037030020044180076a41286a2209200129030037030020044180076a41206a2201200729030037030020044180076a41186a2207200329030037030020044180076a41106a2203200829030037030020044180076a41086a22082002290300370300200441c0076a41086a22022012280200360200200420042903e80137038007200420042903d0053703c00720044180056a41386a201529030037030020044180056a41306a201429030037030020044180056a41286a200929030037030020044180056a41206a200129030037030020044180056a41186a200729030037030020044180056a41106a200329030037030020044180056a41086a2008290300370300200420042903800737038005200420133602c005200441c4056a220820042903c007370200200841086a20022802003602004108102c2202450d01200442083702ec01200420023602e801200420053703d005200441e8016a200441d0056a41081074200441f4016a220241086a41002900a19745370000200241002900999745370000200420044180056a36028402200441c0066a200441e8016a10ae01024020042802ec01450d0020042802e801102e0b200441e8016a200441c0066a108e0320042802e801220820042802f001108f022102024020042802ec01450d002008102e0b02400240024020020d00200441d0056a20044180056a41d00010e9081a200441a0066a200441f0046a10c801200441e8016a200441d0056a41d00010e9081a200441e8016a41d0006a220241086a200441a0066a41086a280200360200200220042903a006370200200441d0056a200441c0066a108e0320042802d005220220042802d805200441e8016a108f03024020042802d405450d002002102e0b024020042802ac022202450d00200241306c450d0020042802a802102e0b024020042802bc0241ffffff3f71450d0020042802b802102e0b200441d0056a41186a2201200441c0066a41186a290300370300200441d0056a41106a2209200441c0066a41106a290300370300200441d0056a41086a2214200441c0066a41086a290300370300200420042903c0063703d00541002102024020110e020302000b4100210220112108034020022008410176220320026a2207200f200741286c6a2903002005561b2102200820036b220841014b0d000c020b0b4100210720042802c4052202450d02200241306c450d0220042802c005102e0c020b200f200241286c6a290300220a2005510d002002200a2005546a21020b200441e8016a41186a2001290300370300200441e8016a41106a2009290300370300200441e8016a41086a2014290300370300200420042903d0053703e8010240024020112002490d00024020112010470d00201041016a22082010490d05201041017422032008200320084b1b22084104200841044b1bad42287e220a422088a7454103742108200aa721030240024020100d00200441003602a0060c010b200441083602a8062004200f3602a0062004201041286c3602a4060b200441e0066a20032008200441a0066a107d20042802e806210820042802e0064101460d0220042802e406210f200841286e21100b200f200241286c6a220841286a2008201120026b41286c10ea081a20082005370300200841206a200441e8016a41186a2203290300370300200841186a200441e8016a41106a2201290300370300200841106a200441e8016a41086a2209290300370300200820042903e8013703082003200441d0056a41186a2903003703002001200441d0056a41106a2903003703002009200441d0056a41086a290300370300200420042903d0053703e8010240201c201d470d00201d41016a2202201d490d05201d41017422082002200820024b1b22024104200241044b1b220241ffffff3f7120024621082002410574210202400240201d0d00200441003602a0060c010b200441013602a8062004201b3602a0062004201d4105743602a4060b200441e0066a20022008200441a0066a107d20042802e8062102024020042802e0064101470d002002450d060c050b20042802e406211b2002410576211d0b41012107201141016a2111201b201c4105746a220220042903e801370000200241186a2003290300370000200241106a2001290300370000200241086a2009290300370000201c41016a211c0c020b200220111045000b2008450d020c010b200641d0006a220220026b220841d0006d210302402008450d00200341d0006c2108200241c4006a21020340024020022802002203450d00200341306c450d002002417c6a280200102e0b200241d0006a2102200841b07f6a22080d000b0b2006102e0240024002402007450d00024002400240201c450d00201c4105742106200441ac026a2102201b21080340200441c0076a2008108e03200441e8016a20042802c007220720042802c807109003200441d0056a41086a2201200441e8016a41086a290300370300200441d0056a41106a2209200441e8016a41106a290300370300200441d0056a41186a2214200441e8016a41186a290300370300200441d0056a41206a2212200441e8016a41206a290300370300200441d0056a41286a2213200441e8016a41286a290300370300200441d0056a41306a2215200441e8016a41306a290300370300200441d0056a41386a2216200441e8016a41386a290300370300200441c0066a41086a221e200241086a290200370300200441c0066a41106a221f200241106a290200370300200441c0066a41186a2220200241186a280200360200200420042903e8013703d005200420022902003703c006024020042802a8022203450d0020044180056a41386a201629030037030020044180056a41306a201529030037030020044180056a41286a201329030037030020044180056a41206a201229030037030020044180056a41186a201429030037030020044180056a41106a200929030037030020044180056a41086a2001290300370300200441a0066a41086a201e290300370300200441a0066a41106a201f290300370300200441a0066a41186a2020280200360200200420042903d00537038005200420042903c0063703a0060b024020042802c407450d002007102e0b20030d02200841206a2108200641606a22060d000b0b4200210a410821070c010b20044180076a41386a220220044180056a41386a29030037030020044180076a41306a220120044180056a41306a29030037030020044180076a41286a220920044180056a41286a29030037030020044180076a41206a221420044180056a41206a29030037030020044180076a41186a221220044180056a41186a29030037030020044180076a41106a221320044180056a41106a29030037030020044180076a41086a221520044180056a41086a290300370300200441e0066a41086a2216200441a0066a41086a290300370300200441e0066a41106a221e200441a0066a41106a290300370300200441e0066a41186a221f200441a0066a41186a280200360200200420042903800537038007200420042903a0063703e00641e000102c2207450d04200720042903800737030020072003360240200720042903e006370244200741386a2002290300370300200741306a2001290300370300200741286a2009290300370300200741206a2014290300370300200741186a2012290300370300200741106a2013290300370300200741086a2015290300370300200741cc006a2016290300370200200741d4006a201e290300370200200741dc006a201f280200360200024020064120470d00428180808010210a0c010b200841206a2112201b201c4105746a222141606a2122200441e8016a41c4006a2102428180808010210a0340201221080340200441c0076a2008108e03200441e8016a20042802c007221420042802c807109003200441d0056a41086a2206200441e8016a41086a2223290300370300200441d0056a41106a2201200441e8016a41106a2224290300370300200441d0056a41186a2209200441e8016a41186a2225290300370300200441d0056a41206a2212200441e8016a41206a2226290300370300200441d0056a41286a2213200441e8016a41286a2227290300370300200441d0056a41306a2215200441e8016a41306a2228290300370300200441d0056a41386a2216200441e8016a41386a2229290300370300200441c0066a41086a221e200241086a290200370300200441c0066a41106a221f200241106a290200370300200441c0066a41186a2220200241186a280200360200200420042903e8013703d005200420022902003703c006024020042802a8022203450d0020044180056a41386a201629030037030020044180056a41306a201529030037030020044180056a41286a201329030037030020044180056a41206a201229030037030020044180056a41186a200929030037030020044180056a41106a200129030037030020044180056a41086a2006290300370300200441a0066a41086a201e290300370300200441a0066a41106a201f290300370300200441a0066a41186a2020280200360200200420042903d00537038005200420042903c0063703a0060b024020042802c407450d002014102e0b024020030d002021200841206a2208470d010c030b0b20044180076a41386a221420044180056a41386a29030037030020044180076a41306a221220044180056a41306a29030037030020044180076a41286a221320044180056a41286a29030037030020044180076a41206a221520044180056a41206a29030037030020044180076a41186a221620044180056a41186a29030037030020044180076a41106a221e20044180056a41106a29030037030020044180076a41086a221f20044180056a41086a290300370300200441e0066a41086a2220200441a0066a41086a290300370300200441e0066a41106a222a200441a0066a41106a290300370300200441e0066a41186a222b200441a0066a41186a280200360200200420042903800537038007200420042903a0063703e0062023201f2903003703002024201e290300370300202520162903003703002026201529030037030020272013290300370300202820122903003703002029201429030037030020042004290380073703e801200620202903003703002001202a2903003703002009202b280200360200200420042903e0063703d00502400240200a422088a72214200aa7460d00200a210c0c010b201441016a22122014490d0720144101742213201220122013491b22124104201241044b1bad42e0007e220c422088a7454103742112200ca721130240024020140d0020044100360280050c010b200441083602880520042007360280052004201441e0006c360284050b200441c0066a2013201220044180056a107d20042802c806211220042802c0064101460d0420042802c4062107201241e0006ead210c0b200841206a21122007201441e0006c6a221420042903e801370300201441106a2024290300370300201441086a20232903003703002028290300210d2029290300210e202729030021172026290300212c2025290300212d201441c0006a2003360200201441186a202d370300201441206a202c370300201441286a2017370300201441386a200e370300201441306a200d370300201441c4006a20042903d005370200201441cc006a2006290300370200201441d4006a2001290300370200201441dc006a2009280200360200200c42ffffffff0f83200a4280808080107c4280808080708384210a20222008470d000b0b20044188026a201136020020044184026a2010360200200441fc016a201c360200200441f8016a201d3602002004200f360280022004201b3602f401200420183602f001200420193602ec012004201a3602e801201141286c4104722202417f4c0d042002102c2208450d03200441003602880520042002360284052004200836028005201120044180056a107602402011450d00200f201141286c6a2103200f21020340200420022903003703d00520044180056a200441d0056a410810744120102c2208450d05200442203702d405200420083602d005200441d0056a200241086a22024120107420044180056a20042802d005220820042802d8051074024020042802d405450d002008102e0b200241206a22022003470d000b0b200441d0056a419997c500108a0320042802d005220220042802d80520044180056a10c502024020042802d405450d002002102e0b0240200428028405450d00200428028005102e0b200441d0056a419997c500200441e8016a108c0320042802d005220220042802d805200441f4016a109103024020042802d405450d002002102e0b02402019450d00201a102e0b0240201d41ffffff3f71450d00201b102e0b2010450d02201041286c450d02200f102e0c020b02402019450d00201a102e0b0240201d41ffffff3f71450d00201b102e0b4100210702402010450d00201041286c450d00200f102e0b0c010b2012450d020c010b024020042802f40441ffffff3f71450d0020042802f004102e0b024020070d000240200441c4046a2802002202450d00200241306c450d0020042802c004102e0b200441e8016a4103109c0420004201370300200041286a200441e8016a41206a290300370300200041206a200441e8016a41186a290300370300200041186a200441e8016a41106a290300370300200041106a200441f0016a290300370300200020042903e8013703080c090b024002400240200b4101200b41014b1b2202418094ebdc036e2002418094ebdc03704100476a22084101200841014b1b220820024b0d002002200a422088a7220641036c220320022003491b20086ead428094ebdc037e200220086ead80a7109e042103200641ffffffff03712006470d0420064102742202417f4c0d040240024020020d00410421010c010b2002102c2201450d040b02402002410276220920064f0d00200241017622082006200820064b1b22084104200841044b1b220841ffffffff03712008464102742109200841027421080240024020020d00200441003602e8010c010b200441f0016a4104360200200420023602ec01200420013602e8010b200441d0056a20082009200441e8016a107d200441d8056a2802002102024020042802d0054101460d0020042802d4052101200241027621090c030b2002450d050c040b20060d01410021020c020b41d0d8c800411941bcd7cc001039000b2006210820012102034020022003360200200241046a21022008417f6a22080d000b200621020b2004200720062001200220042802d0041092034108102c2202450d0020044208370284052004200236028005200420053703e80120044180056a200441e8016a4108107420044194056a41002900a1974537020020044100290099974537028c05200441eb056a20044180056a41186a280200360000200441e3056a20044180056a41106a290300370000200441db056a20042903880537000020042004290380053700d305200441f1016a200441d0056a41086a290000370000200441f9016a200441d0056a41106a290000370000200441e8016a41186a200441e7056a29000037000020044188026a41013a0000200441053a00e801200420042900d0053700e901200441e8016a10fe0102402009450d002001102e0b02402006450d00200641e0006c2108200741d4006a210203400240200241706a2802002203450d00200341306c450d002002416c6a280200102e0b0240200228020041ffffff3f71450d002002417c6a280200102e0b200241e0006a2102200841a07f6a22080d000b0b0240200aa72202450d00200241e0006c450d002007102e0b0240200441c4046a2802002202450d00200241306c450d0020042802c004102e0b2000420037030820004200370300200041186a41013a0000200441d0076a24000f0b1036000b1038000b200241246a21022008415c6a22080d000b0b0240200441fc016a2802002208450d00200441e8016a410c6a2802002102200841246c210803400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b200441f8016a2802002202450d00200241246c450d0020042802f401102e0b0240200441ec026a2802002208450d00200441e4026a2802002102200841246c210803400240024002400240024020022d00000e050400010204030b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b200441e8026a2802002202450d00200241246c450d0020042802e402102e0b200441e8016a4101109c0420004201370300200041286a200441e8016a41206a290300370300200041206a200441e8016a41186a290300370300200041186a200441e8016a41106a290300370300200041106a200441f0016a290300370300200020042903e8013703080b2003280204210002402003410c6a2802002202450d002002410c6c21082000210203400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b200341086a2802002202450d002002410c6c450d002000102e0b200441d0076a24000bfb0201037f230041206b22022400200241003602082002420137030002404120102c2203450d002002422037021420022003360210200241106a200141106a412010742002200228021022032002280218107402402002280214450d002003102e0b200120021091024120102c2203450d002002422037021420022003360210200241106a200141306a412010742002200228021022032002280218107402402002280214450d002003102e0b4120102c2203450d002002422037021420022003360210200241106a200141d0006a412010742002200228021022032002280218107402402002280214450d002003102e0b200128020421032001410c6a2802002201200210760240200141246c2201450d000340200241106a200310ef042002200228021022042002280218107402402002280214450d002004102e0b200341246a21032001415c6a22010d000b0b200020022802002203200228020810b00102402002280204450d002003102e0b200241206a24000f0b1036000bc90a03047f037e057f230041c0026b220224000240024002402000410c6a28020022030d00200241f8016a411f6a200241d0016a411f6a280000360000200241f8016a41186a200241d0016a41186a290300370300200241f8016a41106a200241d0016a41106a290300370300200241f8016a41086a200241d0016a41086a290300370300200220022903d0013703f8010c010b20002003417f6a220336020c200241d0016a411f6a22042000280204200341246c6a220341206a280000360000200241d0016a41186a2205200341196a290000370300200241d0016a41086a200341096a2900002206370300200241d0016a41106a200341116a29000022073703002002200329000122083703d00120032d00002103200241f8016a411f6a22092004280000360000200241f8016a41186a22042005290300370300200241f8016a41106a22052007370300200241f8016a41086a220a2006370300200220083703f80120034106460d00200241a8016a411f6a220b2009280000360000200241a8016a41186a22092004290300370300200241a8016a41106a20052903002206370300200241a8016a41086a200a290300220737030020024180016a41096a200737000020024180016a41116a200637000020024180016a41196a200929030037000020024180016a41206a200b280000360000200220022903f80122063703a8012002200637008101200220033a00800102400240024020034103470d0020024180016a41017228000041c28289aa04470d01200220024180016a41106a2802003602d401200220024180016a41086a2802003602d001200241f8016a200241d0016a10a701410121030240024020022d00f8014101470d00410021030c010b200241f8006a200241b1026a290000370300200241f0006a200241a9026a290000370300200241e8006a200241a1026a290000370300200241e0006a20024199026a290000370300200241d8006a20024191026a290000370300200241c0006a41106a20024189026a290000370300200241c0006a41086a20024181026a290000370300200220022900f9013703400b200241f8016a41386a2204200241c0006a41386a290300370300200241f8016a41306a2205200241c0006a41306a290300370300200241f8016a41286a2209200241c0006a41286a290300370300200241f8016a41206a220a200241c0006a41206a290300370300200241f8016a41186a220b200241c0006a41186a290300370300200241f8016a41106a220c200241c0006a41106a290300370300200241f8016a41086a220d200241c0006a41086a290300370300200220022903403703f8012003450d01200241386a2004290300370300200241306a2005290300370300200241286a2009290300370300200241206a200a290300370300200241186a200b290300370300200241106a200c290300370300200241086a200d290300370300200220022903f80137030002402002418c016a280200450d0020024188016a280200102e0b200241f8016a2000109a042002200241f8016a4120200110fa04450d03200041046a220410e10141012103200041086a2802002200450d04200041246c450d042004280200102e0c040b0240024020030e050400010304030b2002418c016a280200450d0320024188016a280200102e0c030b2002418c016a280200450d0220024188016a280200102e0c020b2002418c016a280200450d0120024188016a280200102e0c010b20024188016a280200450d00200228028401102e0b200041046a220410e10141002103200041086a2802002200450d00200041246c450d002004280200102e0b200241c0026a240020030bd50101047f230041c0006b220224004116210341baddc8002104410221050240024002400240200141ff01710e0400010203000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602242002418883ca003602202002200241206a360218200241086a4190b7c4001044000b4118210341dfdcc8002104410021050c010b4118210341f7dcc8002104410121050b20004183043b0118200041003a001020004200370300200041206a20033602002000411c6a20043602002000411a6a20053a0000200241c0006a24000baa1404077f047e017f057e230041e0036b2203240020012800002104200341106a41186a2001411c6a290000370300200341106a41106a200141146a290000370300200341106a41086a2001410c6a2900003703002003200129000437031020022802002105200341b0036a41186a22064200370300200341b0036a41106a22014200370300200341b0036a41086a22074200370300200342003703b003200341d0006a41a081ca0041071081022007200341d0006a41086a2208290000370300200320032900503703b003200341d0006a41e4d1c100410c1081022006200829000037030020012003290050370300200341086a200341b0036a4120108e0241002109024002402005200328020c410020032802081b470d0020084120360200200320043602502003200341106a360254200341d0026a200341d0006a10c203200341d0006a20032802d002220520032802d80210f4022007200341d9006a2900003703002001200341e1006a2900003703002006200341e9006a290000370300200320032900513703b003024020032d00504101470d00200341306a41186a200341b0036a41186a290300370300200341306a41106a200341b0036a41106a290300370300200341306a41086a200341b0036a41086a290300370300200320032903b003370330410121090b024020032802d402450d002005102e0b2002410c6a2802002106200241086a280200210520022802042107024020090d002000410036024002402006450d002006410c6c21002007210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b2005450d022005410c6c450d022007102e0c020b20022802102104200341d0016a41186a2202200341306a41186a290300220a370300200341d0016a41106a2208200341306a41106a290300220b370300200341d0016a41086a2209200341306a41086a290300220c37030020032003290330220d3703d001200341d0006a41186a200a370300200341d0006a41106a200b370300200341d0006a41086a200c3703002003200d370350200341d0026a200341d0006a10bf01200341f0016a41186a220e2002290300370300200341f0016a41106a22022008290300370300200341f0016a41086a2009290300370300200320032903d0013703f001024020032802f00222080d002000410036024002402006450d002006410c6c21002007210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b2005450d022005410c6c450d022007102e0c020b20034190026a41186a200e29030037030020034190026a41106a200229030037030020034190026a41086a200341f0016a41086a290300370300200320032903f00137039002200341b0026a41186a200341d0026a41186a290300370300200341b0026a41106a200341d0026a41106a290300370300200341b0026a41086a200341d0026a41086a290300370300200320032903d0023703b002200341f8026a290300210a20032802f4022102200341b0036a41186a4200370300200341b0036a41106a4200370300200341b0036a41086a22094200370300200342003703b003200341d0006a41a081ca0041071081022009200341d0006a41086a220e290000370300200320032900503703b003200341d0006a41f09dc500410a108102200141086a200e29000037000020012003290050370000200341d0036a200341b0036a1088030240024020032802d00322090d00410021010c010b20032902d403220b422088a72101200b42ffffff3f83500d002009102e0b0240024020042001460d002000410036024002402002450d00200241306c450d002008102e0b02402006450d002006410c6c21002007210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b2005450d032005410c6c0d010c030b2000200329039002220b370300200041206a20032903b002220c370300200341d0006a41186a20034190026a41186a290300220d370300200341d0006a41106a20034190026a41106a290300220f370300200341d0006a41086a20034190026a41086a2903002210370300200341d0006a41286a200341b0026a41086a2903002211370300200341d0006a41306a200341b0026a41106a2903002212370300200341d0006a41386a200341b0026a41186a2903002213370300200041086a2010370300200041106a200f370300200041186a200d370300200041286a2011370300200041306a2012370300200041386a20133703002003200b3703502003200c370370200041c8006a200a370300200020023602442000200836024002402006450d002006410c6c21002007210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b2005450d022005410c6c450d020b2007102e0c010b200341d0006a2005109908200341d0026a41086a200341d0006a410c6a290200370300200341d0026a41106a200341d0006a41146a290200370300200341d0026a41186a200341d0006a411c6a290200370300200320032902543703d0020240024020032802504101470d00200341b0036a41086a2205200341d0026a41086a290300220a370300200341b0036a41106a2206200341d0026a41106a290300220b370300200341b0036a41186a2207200341d0026a41186a290300220c370300200320032903d002220d3703b003200341f4006a2802002101200341b0026a41186a2208200c370300200341b0026a41106a2209200b370300200341b0026a41086a220e200a3703002003200d3703b002024020012002280210460d00200041003602400c020b20072008290300370300200620092903003703002005200e290300370300200320032903b0023703b0032002410c6a280200210720022802042108200341d0026a10ab0202402007450d0020082007410c6c6a210541002802cca140210641002902c4a140210a20082101034020034190026a41086a20063602002003200a37039002200341d0006a200341d0026a20034190026a2001280200200141086a28020010b0022001410c6a22012005470d000b0b200341d0006a200341d0026a41e00010e9081a200341c8016a200341c8036a290300370300200341c0016a200341c0036a290300370300200341b8016a200341b0036a41086a290300370300200320032903b0033703b0012000200341d0006a2004200341106a109a08200341d0006a10b80202402007450d002007410c6c21002008210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b200241086a2802002201450d022001410c6c450d022008102e0c020b200041003602400b2002280204210502402002410c6a2802002201450d002001410c6c21002005210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b200241086a2802002201450d002001410c6c450d002005102e0b200341e0036a24000b2e01017e2000ad220120017e220142808090bbbad6adf00d200142808090bbbad6adf00d541b428094ebdc0380a70b4d01017f230041206b22002400200041146a4101360200200042013702042000419cc3cb003602002000410436021c20004194c3cb003602182000200041186a360210200041f4afc4001044000bfa0a02047f047e230041b0016b220224002002412036020c20022001360208200241106a2001412010ed0202400240200228021022010d00200041023a00000c010b2002280214210302400240200241186a2802002204450d004100210502400240024020012d00000e020100030b200241003a006020044101460d0220012d00012105200241013a0060200220053a004020044102460d0120012d00022105200241023a0060200220053a004120044103460d0120012d00032105200241033a0060200220053a004220044104460d0120012d00042105200241043a0060200220053a004320044105460d0120012d00052105200241053a0060200220053a004420044106460d0120012d00062105200241063a0060200220053a004520044107460d0120012d00072105200241073a0060200220053a004620044108460d0120012d00082105200241083a0060200220053a004720044109460d0120012d00092105200241093a0060200220053a00482004410a460d0120012d000a21052002410a3a0060200220053a00492004410b460d0120012d000b21052002410b3a0060200220053a004a2004410c460d0120012d000c21052002410c3a0060200220053a004b2004410d460d0120012d000d21052002410d3a0060200220053a004c2004410e460d0120012d000e21052002410e3a0060200220053a004d2004410f460d0120012d000f21052002410f3a0060200220053a004e20044110460d0120012d00102105200241103a0060200220053a004f20044111460d0120012d00112105200241113a0060200220053a005020044112460d0120012d00122105200241123a0060200220053a005120044113460d0120012d00132105200241133a0060200220053a005220044114460d0120012d00142105200241143a0060200220053a005320044115460d0120012d00152105200241153a0060200220053a005420044116460d0120012d00162105200241163a0060200220053a005520044117460d0120012d00172105200241173a0060200220053a005620044118460d0120012d00182105200241183a0060200220053a005720044119460d0120012d00192105200241193a0060200220053a00582004411a460d0120012d001a21052002411a3a0060200220053a00592004411b460d0120012d001b21052002411b3a0060200220053a005a2004411c460d0120012d001c21052002411c3a0060200220053a005b2004411d460d0120012d001d21052002411d3a0060200220053a005c2004411e460d0120012d001e21052002411e3a0060200220053a005d2004411f460d0120012d001f21052002411f3a0060200220053a005e20044120460d01200241206a41106a200241c0006a41106a290300370300200241206a41086a200241c0006a41086a290300370300200220012d00203a005f200241206a41186a200241c0006a41186a290300370300200241203a006020022002290340220637036820022006370320410121050b200241c0006a41186a200241206a41186a2903002206370300200241c0006a41106a200241206a41106a2903002207370300200241c0006a41086a200241206a41086a2903002208370300200220022903202209370340200020053a000020002009370001200041096a2008370000200041116a2007370000200041196a20063700000c020b200241003a00600b20024100360270200242013703682002410a3602242002200241086a3602202002200241e8006a3602ac01200241d4006a410136020020024201370244200241909dc5003602402002200241206a360250200241ac016a419cebc000200241c0006a103d1a2002280268200228027010ef020240200228026c450d002002280268102e0b200041023a00000b2003450d002001102e0b200241b0016a24000bb30201027f230041e0006b220224002002412036020c20022001360208200241106a2001412010ed0202400240200228021022010d00200041003602000c010b200228021421032002200241106a41086a28020036022420022001360220200241c8006a200241206a10b5050240024020022802480d0020024100360230200242013703282002410a36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241909dc5003602482002200241386a360258200241c4006a419cebc000200241c8006a103d1a2002280228200228023010ef020240200228022c450d002002280228102e0b200041003602000c010b20002002290348370200200041086a200241c8006a41086a2802003602000b2003450d002001102e0b200241e0006a24000ba50904047f017e087f047e23004190026b220224002002412036020c20022001360208200241106a2001412010ed0202400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10ab010240024020022802000d000240024020022802042205200228022441286e2201200120054b1bad42287e2206422088a70d002006a72201417f4c0d000240024020010d00410821070c010b2001102c2207450d020b200141286ead2106024002402005450d00410021080340200241003a00c801200841016a210820022802242109417f210a4100210102400240024002400240034020092001460d01200241a8016a20016a2002280220220b2d00003a000020022009200a6a3602242002200b41016a3602202002200141016a220c3a00c801200a417f6a210a200c2101200c4120470d000b200241f0016a41186a2201200241a8016a41186a290300370300200241f0016a41106a220a200241a8016a41106a290300370300200241f0016a41086a220d200241a8016a41086a290300370300200220022903a8013703f001200c41ff01714120490d0120024188016a41086a220e200d29030037030020024188016a41106a220d200a29030037030020024188016a41186a220a2001290300370300200220022903f001370388012009200c6b22014108490d01200241c8006a41086a200e290300220f370300200241c8006a41106a200d2903002210370300200241c8006a41186a200a2903002211370300200241286a41086a220c200f370300200241286a41106a22092010370300200241286a41186a220d2011370300200b290001210f2002200b41096a3602202002200141786a36022420022002290388012210370348200220103703282006422088a722012006a7470d04200141016a220a2001490d082001410174220b200a200a200b491b220a4104200a41044b1bad42287e2206422088a745410374210a2006a7210b20010d02200241003602a8010c030b200141ff0171450d00200241003a00c8010b2006a72201450d08200141286c450d082007102e0c080b200241083602b001200220073602a8012002200141286c3602ac010b200241f0016a200b200a200241a8016a107d20022802f801210a20022802f0014101460d0320022802f4012107200a41286ead21060b2007200141286c6a220a2002290328370300200c290300211020092903002111200d2903002112200a200f370320200a41186a2012370300200a41106a2011370300200a41086a2010370300200642ffffffff0f83200141016aad42208684210620082005470d000b0b2007450d0320002006370204200020073602000c040b200a0d010b1038000b1036000b200241003602f801200242013703f0012002410a3602d4012002200241086a3602d0012002200241f0016a36028801200241bc016a4101360200200242013702ac01200241909dc5003602a8012002200241d0016a3602b80120024188016a419cebc000200241a8016a103d1a20022802f00120022802f80110ef02024020022802f401450d0020022802f001102e0b200041003602000b2004450d002003102e0b20024190026a24000b9d0902057f017e230041b0016b220224002002412036020c20022001360208200241106a2001412010ed0202400240200228021022010d00200041003a00000c010b200241186a280200210320022802142104200241003a0060024002402003450d00200220012d00003a0040200241013a0060024020034101460d00200220012d00013a0041200241023a006020034102460d00200220012d00023a0042200241033a006020034103460d00200220012d00033a0043200241043a006020034104460d00200220012d00043a0044200241053a006020034105460d00200220012d00053a0045200241063a006020034106460d00200220012d00063a0046200241073a006020034107460d00200220012d00073a0047200241083a006020034108460d00200220012d00083a0048200241093a006020034109460d00200220012d00093a00492002410a3a00602003410a460d00200220012d000a3a004a2002410b3a00602003410b460d00200220012d000b3a004b2002410c3a00602003410c460d00200220012d000c3a004c2002410d3a00602003410d460d00200220012d000d3a004d2002410e3a00602003410e460d00200220012d000e3a004e2002410f3a00602003410f460d00200220012d000f3a004f200241103a006020034110460d00200220012d00103a0050200241113a006020034111460d00200220012d00113a0051200241123a006020034112460d00200220012d00123a0052200241133a006020034113460d00200220012d00133a0053200241143a006020034114460d00200220012d00143a0054200241153a006020034115460d00200220012d00153a0055200241163a006020034116460d00200220012d00163a0056200241173a006020034117460d00200220012d00173a0057200241183a006020034118460d00200220012d00183a0058200241193a006020034119460d00200220012d00193a00592002411a3a00602003411a460d00200220012d001a3a005a2002411b3a00602003411b460d00200220012d001b3a005b2002411c3a00602003411c460d00200220012d001c3a005c2002411d3a00602003411d460d00200220012d001d3a005d2002411e3a00602003411e460d00200220012d001e3a005e2002411f3a00602003411f460d00200241206a41106a2203200241c0006a41106a290300370300200241206a41086a2205200241c0006a41086a290300370300200220012d001f3a005f200241206a41186a2206200241c0006a41186a290300370300200241203a006020022002290340220737036820022007370320200041196a2006290300370000200041116a2003290300370000200041096a200529030037000020002002290320370001410121030c020b200241003a00600b20024100360270200242013703682002410a3602242002200241086a3602202002200241e8006a3602ac01200241d4006a410136020020024201370244200241909dc5003602402002200241206a360250200241ac016a419cebc000200241c0006a103d1a2002280268200228027010ef020240200228026c450d002002280268102e0b410021030b200020033a00002004450d002001102e0b200241b0016a24000bf50101037f230041206b220224002000410036020820004201370200024002400240024020012802000e03000102030b200241013a000f20002002410f6a41011074200128020421032001410c6a2802002204200010760240200441286c2204450d00200320046a2104034020002003412010742002200341206a2903003703102000200241106a41081074200341286a22032004470d000b0b2000200141106a412010740c020b200241023a000f20002002410f6a410110742002200128020436021c20002002411c6a410410740c010b200241033a000f20002002410f6a41011074200141086a20001096020b200241206a24000b850301047f230041f0006b22012400200141086a41206a200041206a280200360200200141086a41186a200041186a290200370300200141086a41106a200041106a290200370300200141086a41086a2202200041086a29020037030020012000290200370308200141306a41186a22004200370300200141306a41106a22034200370300200141306a41086a420037030020014200370330200141306a41d9fcc6004106108102200141e0006a41b4f4cb0041061081022000200141e0006a41086a220429000037030020032001290060370300200141d0006a200141086a10ef042004200141d0006a41086a28020036020020012001290350370360200141306a4120200141e0006a10c7020240024002400240024020012d00080e050400010204030b200141146a280200450d03200141106a280200102e0c030b200141146a280200450d02200141106a280200102e0c020b200141146a280200450d01200141106a280200102e0c010b2002280200450d00200128020c102e0b200141f0006a24000ba50101047f230041106b2202240002404121410120012d000041014622031b2204102c2205450d002002410036020820022004360204200220053602000240024020030d00200241003a000f20022002410f6a410110740c010b200241013a000f20022002410f6a410110742002200141016a412010740b2000412020022802002201200228020810b20102402002280204450d002001102e0b200241106a24000f0b1036000b850201037f230041d0006b22022400200241086a41dffcc6004109108102200241186a41d3b1c4004106108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000be22505027f017e027f017e037f230041b0046b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c0102030405060708090a0b0c0d0e0f101112131415161718191a1b00010b200241086a200141386a10ca0120024180026a41286a200141306a29030037030020024180026a41206a200141286a29030037030020024180026a41186a200141206a29030037030020024180026a41106a200141186a29030037030020024180026a41086a200141106a2903003703002002200141086a29030037038002200141f8016a280200210320024180026a41306a200241086a41c00110e9081a20014180026a2903002104200241086a20024180026a41f00110e9081a200041086a200241086a41f00110e9081a20004180026a2004370300200041f8016a20033602002000411b3602000c1b0b20024180026a200141086a10cb0120004100360200200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c1a0b20024180026a200141046a10cc0120004101360200200041246a200241a0026a2802003602002000411c6a20024198026a290300370200200041146a20024190026a2903003702002000410c6a20024188026a29030037020020002002290380023702040c190b20024180026a200141086a10cd01200041086a20024180026a41a00210e9081a200041023602000c180b20004103360200200041086a200141086a2903003703000c170b41042103200141046a210502400240024002400240024002400240024020012d0004417f6a0e050102030405000b41e2a0cc00412841e89bc4001039000b200141086a2802002105410121030c040b41022103200241086a41026a200541036a2d00003a000020024180026a41086a200141146a29020037030020024190026a2001411c6a29020037030020024198026a200141246a2d00003a0000200220052f00013b010820022001410c6a29020037038002200141086a2802002105200141286a28020021010c040b200141086a2802002105410321030c020b2002410a6a200541036a2d00003a000020024180026a41086a200141146a29020037030020024190026a2001411c6a29020037030020024198026a200141246a2d00003a0000200220052f00013b010820022001410c6a2902003703800220012d00254100472106200141086a2802002105200141286a28020021010c030b200141086a2802002105410521030b0b0b200020033a0004200020022f01083b0005200020063a0025200020022f01fc013b0126200041086a20053602002000410c6a200229038002370200200041286a2001360200200041076a2002410a6a2d00003a0000200041146a20024180026a41086a2903003702002000411c6a20024190026a290300370200200041246a20024198026a2d00003a0000200041043602000c160b20024180026a200141086a10ce01200041086a20024180026a41e00010e9081a200041053602000c150b20024180026a200141046a10cf01200041063602002000410c6a20024188026a28020036020020002002290380023702040c140b20024180026a200141086a10d001200041086a20024180026a41d80010e9081a200041073602000c130b10d101000b02400240200128020422050d00410021030c010b20024180026a41186a200141286a29000037030020024180026a41106a200141206a29000037030020024188026a200141186a29000037030020024180026a41286a200141386a29000037030020024180026a41306a200141c0006a29000037030020024180026a41386a200141c8006a29000037030020024180026a41c8006a200141d8006a29000037030020024180026a41d0006a200141e0006a29000037030020024180026a41d8006a200141e8006a2900003703002002200141106a290000370380022002200141306a2900003703a0022002200141d0006a2900003703c00220024180026a41f8006a20014188016a29000037030020024180026a41f0006a20014180016a29000037030020024180026a41e8006a200141f8006a29000037030020024180026a4198016a200141a8016a29000037030020024180026a4190016a200141a0016a29000037030020024180026a4188016a20014198016a29000037030020024180026a41b8016a200141c8016a29000037030020024180026a41b0016a200141c0016a29000037030020024180026a41a8016a200141b8016a2900003703002002200141f0006a2900003703e002200220014190016a290000370380032002200141b0016a2900003703a0032001410c6a2802002201417f4c0d130240024020010d00410121030c010b2001102c2203450d150b20032005200110e9081a200241086a20024180026a41c00110e9081a0b200020033602042000410c6a2001360200200041086a2001360200200041106a200241086a41c00110e9081a200041093602000c110b20024180026a200141086a10d201200041086a20024180026a41980210e9081a2000410a3602000c100b20024180026a200141046a10d301200041046a20024180026a41e80010e9081a2000410b3602000c0f0b10d401000b20024180026a200141086a10d5012000410d360200200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0d0b20024180026a200141086a10d6012000410e360200200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0c0b20024180026a200141086a10d6012000410f360200200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0b0b20024180026a200141086a10d70120004110360200200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0a0b200141046a2103410721050240024002400240024002400240024020012d0004417f6a0e0701020304050607000b41e2a0cc00412841a4c3cb001039000b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410121050c050b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410221050c040b20024180026a41186a200341196a29000037030020024180026a41106a200341116a29000037030020024180026a41086a200341096a290000370300200241086a41086a200341296a290000370300200241086a41106a200341316a290000370300200241086a41186a200341396a29000037030020022003290001370380022002200341216a290000370308410321050c030b200241086a200141086a10c8012002418b026a200241086a41086a2802003600002002200229030837008302410421050c020b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410521050c010b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410621050b200020053a0004200020022903800237000520002002290308370025200020022f00fc013b00452000410d6a20024180026a41086a290300370000200041156a20024180026a41106a2903003700002000411d6a20024180026a41186a2903003700002000412d6a200241086a41086a290300370000200041356a200241086a41106a2903003700002000413d6a200241086a41186a290300370000200041c7006a200241fe016a2d00003a0000200041113602000c090b024002400240024002400240200141086a280200417f6a0e03010203000b41e2a0cc0041284184ccc2001039000b200141386a2903002104200141306a29030021074101210841012109024002400240024002402001410c6a2d00000e050104020300010b4104210920024180026a41046a200141206a2d00003a000020022001411c6a2800003602800220012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a28020021050c030b20024188026a200141246a29000037030020024180026a41106a2001412c6a2d00003a000020022001411c6a2900003703800220012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a2802002105410021090c020b200141186a2802002203417f4c0d0f200141106a28020021010240024020030d00410121050c010b2003102c2205450d110b20052001200310e9081a410221092003210a0c010b20024188026a200141246a29000037030020024180026a41106a2001412c6a2d00003a000020022001411c6a2900003703800220012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a2802002105410321090b200241086a41106a20024180026a41106a2d00003a0000200241086a41086a20024180026a41086a290300370300200241046a41026a200241fc016a41026a2d00003a00002002200229038002370308200220022f00fc013b01040c030b2001410c6a28020022094108762106410221080c010b2001410c6a28020022094108762106410321080b0b200020022f01043b002d20004112360200200041386a2004370300200041306a2007370300200041186a200a360200200041146a2003360200200041106a2005360200200041086a20083602002000411c6a20022903083702002000410c6a2006410874200941ff017172360200200041246a200241086a41086a2903003702002000412c6a200241086a41106a2d00003a00002000412f6a200241066a2d00003a00000c080b20024180026a200141086a10d801200041086a20024180026a41f00010e9081a200041133602000c070b20024180026a200141086a10d901200041086a20024180026a41f80010e9081a200041143602000c060b024002400240024020012f0104417f6a0e03010200010b20024180026a200141086a10c90120022902840221042002280280022103410321010c020b20024180026a200141086a10c90120022902840221042002280280022103410121010c010b20012f0106210541b002102c2203450d0820024180026a200141086a28020010da01200320024180026a41b00210e9081a410221010b200020013b0104200041153602002000410c6a2004370200200041086a2003360200200041066a20053b01000c050b20024180026a200141086a10db01200041086a20024180026a41a80210e9081a200041163602000c040b20024180026a200141046a10dc01200041046a20024180026a41c80010e9081a200041173602000c030b20024180026a200141086a10dd01200041086a20024180026a41c80010e9081a200041183602000c020b20024180026a200141086a10de0120004119360200200041c0006a20024180026a41386a290300370300200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c010b20024180026a200141086a10df012000411a360200200041c0006a20024180026a41386a290300370300200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000b200241b0046a24000f0b1038000b1036000bbc0101037f230041306b22022400200241dffcc6004109108102200241106a41e5b0c4004106108102200241206a2001280200200128020810a201024002402002280228220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b20004100360208200020013602042000200436020020002002411010742000200241106a411010742000200228022022012003107402402002280224450d002001102e0b200241306a24000f0b1038000b1036000bfa0101037f230041306b220224002002200010a704200228020821032002280200210002404101102c2204450d0020024201370214200220043602100240024020012802bc024102470d00200241003a0020200241106a200241206a410110740c010b200241013a0020200241106a200241206a410110742001200241106a10ab040b200241206a41086a200241106a41086a2802003602002002200229031037032020002003200241206a10c70202402002280204450d002000102e0b024020012802bc024102460d00024020012802b0022200450d00200141b4026a280200450d002000102e0b2001108b020b200241306a24000f0b1036000bb20501037f230041106b220224000240024020002802b00222030d00200241003a000c20012002410c6a410110742002410c6a21030c010b200241013a000c20012002410c6a41011074200041b8026a28020022042001107620012003200410742002410c6a21030b200220002d00f0023a000c2001200341011074200020011090020240024020002802bc024101460d00200241003a000c20012003410110740c010b200241013a000c20012003410110742002200041c0026a28020036020c20012002410c6a410410742002200041c4026a28020036020c20012002410c6a410410740b0240024002400240024020002d00c8020e0400010203000b200241003a000c2001200341011074024002400240200041c9026a2d00000e03000102060b200241003a000c20012003410110740c050b200241013a000c20012003410110742001200041ca026a412010740c040b200241023a000c20012003410110740c030b2002410f3a000c2001200341011074024002400240200041cc026a2d00000e03000102050b200241003a000c20012003410110742002200041d0026a28020036020c20012002410c6a410410742002200041d4026a28020036020c20012002410c6a410410740c040b200241013a000c20012003410110742001200041cd026a412010740c030b200241023a000c20012003410110740c020b200241103a000c2001200341011074024002400240200041cc026a2d00000e03000102040b200241003a000c20012003410110742002200041d0026a28020036020c20012002410c6a410410742002200041d4026a28020036020c20012002410c6a410410740c030b200241013a000c20012003410110742001200041cd026a412010740c020b200241023a000c20012003410110740c010b200241033a000c2001200341011074200110b6040b200241106a24000b130020004103360204200041a0b7c4003602000b3400200041a8f8c60036020420004100360200200041146a4110360200200041106a41a8bec400360200200041086a42043702000b130020004102360204200041f4e0c4003602000b4301027f230041106b2202240002404108102c22030d001036000b2000420837020420002003360200200242f02e3703082000200241086a41081074200241106a24000b4301027f230041106b2202240002404108102c22030d001036000b2000420837020420002003360200200242e0123703082000200241086a41081074200241106a24000ba10402067f027e230041206b2102024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a36020020050e020102030b200041023a00000f0b2006450d0420042d0001210520012003417e6a22073602042001200441026a360200410021060240024002400240024002400240200541ff00710e07060001020304050b0b410121060c050b410221060c040b410321060c030b410421060c020b410521060c010b410621060b024020074110490d00200041003a0000200041086a2004290002370300200041026a20063a0000200020054107763a0001200041036a200228001b360000200041186a2002290308370300200041106a2004410a6a29000037030020012003416e6a3602042001200441126a360200200041076a2002411f6a2d00003a0000200041206a200241086a41086a2903003703000f0b200041023a00000f0b20064110490d01200441096a29000021082004290001210920012003416f6a22053602042001200441116a36020020054110490d02200041013a000020002002280008360001200041186a2004290011370300200041106a2008370300200041086a2009370300200041206a200441196a29000037030020012003415f6a3602042001200441216a360200200041046a2002410b6a2800003600000f0b200041023a00000f0b200041023a00000f0b200041023a00000f0b200041023a00000ba20202037f017e230041106b220224000240024020002d00004101460d00200241003a0000200120024101107420002d00012103410621040240024002400240024002400240200041026a2d00000e0700010203040506000b410021040c050b410121040c040b410221040c030b410321040c020b410421040c010b410521040b20022004200341ff0171410047410774723a00002001200241011074200029030821052002200041106a2903003703082002200537030020012002411010740c010b200241013a00002001200241011074200029030821052002200041106a290300370308200220053703002001200241101074200041186a29030021052002200041206a2903003703082002200537030020012002411010740b200241106a24000b130020004106360204200041b8e7c4003602000b3400200041dffcc60036020420004100360200200041146a4103360200200041106a41f0f7c400360200200041086a42093702000b3401017f230041106b220224002000410036020820004201370200200241003a000f20002002410f6a41011074200241106a24000b4601027f230041106b220124002001410036020820014201370300200110b6042000200128020022022001280208107402402001280204450d002002102e0b200141106a24000bef43050e7f037e1c7f047e0a7f230041f0026b220524000240024002400240024002400240024002400240024002400240024002400240024020020d0041002106410021070c010b200120024105746a2108200541b0026a41186a2109200541386a41186a210a200541b0026a41086a210b410021064100210703402009200141186a290000370300200541b0026a41106a220c200141106a290000370300200b200141086a290000370300200520012900003703b002024020070d0041c805102c2207450d0e4100210d200741003b01e602200741003602e0020b200141206a21012007210e200d210f024002400340200e41e8026a2110200e2f01e6022111410021020240034020112002460d01200541b0026a2010412010ec082212450d03200241016a2102201041206a21102012417f4a0d000b2002417f6a21110b0240200f450d00200f417f6a210f200e20114102746a41c8056a280200210e0c010b0b200541206a41086a200b41086a2902002213370300200541206a41106a200b41106a29020022143703002005200b290200221537032020052802b402210f20052802b0022116200541c0016a41106a22172014370300200541c0016a41086a22182013370300200520153703c00102400240200e2f01e6022202410a4b0d0020054198026a41106a2219201729030037030020054198026a41086a221a2018290300370300200520052903c00137039802200e41e8026a2110200241016a21120240201141016a221b20024b221c0d002010201b4105746a201020114105746a20122011417f736a41057410ea081a0b20102011410574220c6a2202200f360004200220163600002002200529039802370008200241106a201a290300370000200241186a20192903003700000240201c0d00200e201b4105746a200e200c6a20122011417f736a41057410ea081a0b200e200c6a22024200370308200242003703002002410036021820024208370310200e20123b01e6020c010b4100211a4104210202400240201141054f0d00201121120c010b4105210241052112024002402011417b6a0e020201000b201141796a21124101211a410621020c010b410021124101211a0b41c805102c2219450d10201941003b01e602201941003602e0022019200e2f01e602221b2002417f736a22113b01e602200e41e8026a221c2002410574221d6a2210280004211e2010280000211f20054198026a41106a2220201041186a29000037030020054198026a41086a2221201041106a2900003703002005201029000837039802200a200e201d6a221041186a290300370300200541386a41106a2222201041106a290300370300200541386a41086a2223201041086a290300370300200520102903003703382011410c4f0d0e201b200241016a22106b2011470d0d201941e8026a201c201041057422106a2011410574221110e9081a2019200e20106a201110e908211d20092005290338370300200941086a22242023290300370300200941106a22252022290300370300200941186a2226200a290300370300200e20023b01e602200c20202903002213370300200541e0016a41086a22272021290300370300200541e0016a41106a22282013370300200541e0016a41186a22292009290300370300200541e0016a41206a222a200541b0026a41206a222b290300370300200541e0016a41286a222c200541b0026a41286a222d290300370300200541e0016a41306a222e200541b0026a41306a222f29030037030020052005290398023703e001201d200e201a1b22022f01e60221102020201729030037030020212018290300370300200520052903c00137039802200241e8026a2111201041016a211a0240201241016a221c20104b22300d002011201c4105746a201120124105746a201a2012417f736a41057410ea081a0b20112012410574221b6a2210200f360004201020163600002010200529039802370008201041106a2021290300370000201041186a2020290300370000024020300d002002201c4105746a2002201b6a201a2012417f736a41057410ea081a0b2002201b6a22104200370308201042003703004100213120104100360218201042083703102002201a3b01e602200541f0006a41086a221a20272903002213370300200541f0006a41106a221b20282903002214370300200541f0006a41186a221c20292903002215370300200541f0006a41206a202a2903002232370300200541f0006a41286a202c2903002233370300200541f0006a41306a202e2903002234370300200520052903e0012235370370200541386a41306a22362034370300200541386a41286a22372033370300200541386a41206a22382032370300200a201537030020222014370300202320133703002005203537033802400240200e2802e0022216450d0041002131201d2139201e213a201f213b0340200e2f01e402210e200541a8016a41106a22302022290300370300200541a8016a41086a223c2023290300370300200520052903383703a801200541c0016a41186a221d200a41186a2903003703002017200a41106a2903003703002018200a41086a2903003703002005200a2903003703c0014101450d0f20162f01e602223d410b490d024100210f410421020240200e4105490d00200e210202400240200e417b6a0e020201000b200e41796a210e4101210f410621020c010b4100210e4101210f410521020b41f805102c2219450d13201941003b01e602201941003602e002201920162f01e602223e2002417f736a22123b01e602201641e8026a223f200241057422116a2210280004211e2010280000211f2020201041186a2900003703002021201041106a2900003703002005201029000837039802201c201620116a221041186a290300370300201b201041106a290300370300201a201041086a290300370300200520102903003703702012410c4f0d0e203e200241016a22116b2012470d0d201941e8026a203f201141057422106a2012410574221210e9081a2019201620106a201210e9082110201620023b01e602200b2021290300370300200c2020290300370300200920052903703703002024201a2903003703002025201b2903003703002026201c29030037030020052005290398023703b00220102f01e602221241016a213e2012410c4f0d0c203d20026b2202203e470d0b203141016a2131201041c8056a201620114102746a41c8056a200241027410e9081a4100210202400340201020024102746a41c8056a280200221120023b01e402201120103602e0022002200220124922116a220220124b0d0120110d000b0b202e202f290300370300202c202d290300370300202a202b290300370300202920092903003703002028200c2903003703002027200b290300370300200520052903b0023703e001201c201d290300370300201b2017290300370300201a2018290300370300200520052903c00137037020102016200f1b22112f01e602211d200c2030290300370300200b203c290300370300200520052903a8013703b002201141e8026a2112201d41016a210f0240200e41016a2202201d4b223c0d00201220024105746a2012200e4105746a200e417f73200f6a41057410ea081a0b2012200e41057422306a2212203a3600042012203b360000201241186a200c290300370000201241106a200b290300370000201220052903b0023700082009201c290300370300200c201b290300370300200b201a290300370300200520052903703703b0020240203c0d00201120024105746a201120306a200e417f73200f6a41057410ea081a0b201120306a221220052903b002370300201241186a2009290300370300201241106a200c290300370300201241086a200b290300370300201141c8056a21120240200e41026a2230201d41026a221d4f0d00201220304102746a201220024102746a2002417f73201d6a41027410ea081a0b201220024102746a20393602002011200f3b01e60202402002201d4f0d002011200e4102746a41cc056a2102034020022802002212200e41016a220e3b01e402201220113602e002200241046a2102200f200e470d000b0b2023202729030037030020222028290300370300200a20292903003703002038202a2903003703002037202c2903003703002036202e290300370300200520052903e0013703382016210e20162802e0022202211620102139201e213a201f213b20020d000b0b202e20362903002213370300202c20372903002214370300202a203829030022153703002029200a29030022323703002028202229030022333703002027202329030022343703002005200529033822353703e001202f2013370300202d2014370300202b201537030020092032370300200c2033370300200b2034370300200520353703b0022007450d0841f805102c2202450d11200220073602c805200241003b01e602200241003602e002200741003b01e402200720023602e0022022200c2903003703002023200b290300370300200520052903b002370338201c2026290300370300201b2025290300370300201a202429030037030020052009290300370370200d2031470d0720022f01e6022210410b4f0d06200d41016a210d2002201041016a22123b01e602200220104105746a22102005290370370300201041ec026a201e360000201041e8026a201f360000201041f0026a2005290338370000201041f8026a202329030037000020104180036a2022290300370000201041086a201a290300370300201041106a201b290300370300201041186a201c290300370300200220124102746a41c8056a2019360200201920123b01e402201920023602e002200221070c010b201c201d290300370300201b2017290300370300201a2018290300370300200520052903c00137037020162f01e6022112200c2030290300370300200b203c290300370300200520052903a8013703b002200e41016a2102201641e8026a2110201241016a21110240200e20124f220f0d00201020024105746a2010200e4105746a200e417f7320116a41057410ea081a0b2010200e41057422196a2210203a3600042010203b360000201041186a200c290300370000201041106a200b290300370000201020052903b0023700082009201c290300370300200c201b290300370300200b201a290300370300200520052903703703b0020240200f0d00201620024105746a201620196a200e417f7320116a41057410ea081a0b201620196a221020052903b002370300201041186a2009290300370300201041106a200c290300370300201041086a200b290300370300201641c8056a2110201241026a21120240200f0d00200e41027420106a41086a201020024102746a2002417f7320126a41027410ea081a0b201020024102746a2039360200201620113b01e602200220124f0d0020162002417f6a22024102746a41cc056a2110034020102802002212200241016a22023b01e402201220163602e002201041046a211020112002470d000b0b2005410036028001200641016a21060c010b200541003602c802200542083703c002200542003703b802200542003703b002200e20024105746a220229031021132002420837031020022903082114200242003703082002290300211520024200370300200241186a22022903002132200220052903c802370300200541f0006a41186a2032370300200520133703800120052014370378200520153703702013a72202450d002005280284012210450d00201041306c450d002002102e0b20012008470d000b0b02402004450d0020032004412c6c6a211903400240200328020841306c2202450d002003280200220e20026a21092003410c6a2116024003402007450d01200e41306a210b20072101200d210f02400340200141e8026a211020012f01e60221114100210202400240034020112002460d01200e2010412010ec082212450d02200241016a2102201041206a21102012417f4a0d000b2002417f6a21110b200f450d02200f417f6a210f200120114102746a41c8056a28020021010c010b0b200120024105746a2202427f20022903002213200e2903207c221420142013542210200241086a22122903002213200e41286a22112903007c2010ad7c221420135420142013511b22101b3703002012427f201420101b37030020162900002113200541b0026a41086a2201201641086a290000370300200541b0026a41106a220f201641106a290000370300200541b0026a41186a220c201641186a290000370300200520133703b00220112903002113200e2903202114200241186a2110200241106a2111024020022802182212200241146a280200470d0020112012410110b804201028020021120b2011280200201241306c6a220220052903b00237030020022014370320200241186a200c290300370300200241106a200f290300370300200241086a2001290300370300200241286a20133703002010201028020041016a360200200b210e200b2009460d030c010b0b0240200d450d00034020072802c8052107200d417f6a220d0d000b0b02402006450d0041002110200541c0026a2101200541b8026a210f03402006417f6a210641012102024002400340201020072f01e602490d01024020072802e00222120d002007102e410021070c030b20072f01e40221102007102e2002417f6a2102201221070c000b0b2001200720104105746a22124180036a290000370300200f201241f8026a2900003703002005201241f0026a2900003703b002201041016a2110201228021421112012280210210e20024101460d00200720104102746a41c8056a280200210702402002450d000340200241016a221020024f211220072802c80521072010210220120d000b0b410021100b200e450d0202402011450d00201141306c450d00200e102e0b20060d000b0b034020072802e00221022007102e2002210720020d000b0b20004104360204410121020c110b2003412c6a22032019470d000b0b024020070d0041002102410021060c0b0b200721020340200d450d0b200d417f6a210d200720072f01e6024102746a41c8056a280200210720022802c80521020c000b0b41a89ac700412041c89ac7001039000b41e899c700413041989ac7001039000b41e8aac700412b4194abc7001039000b41f49bc7004128419c9cc7001039000b203e410c41f49cc700104d000b41f49bc7004128419c9cc7001039000b2012410b41e49bc700104d000b41ac9cc700413541e49cc7001039000b41f49bc7004128419c9cc7001039000b2011410b41e49bc700104d000b0240024002400240024002402006450d002002450d032006417f6a210741002110024002400340201020022f01e602490d01024020022802e00222120d002002102e410021020c030b20022f01e40221102002102e200d41016a210d201221020c000b0b200541f0006a41186a2201200220104105746a22114180036a290000370300200541f0006a41106a220f201141f8026a290000370300200541f0006a41086a2216201141f0026a2900003703002005201141e8026a2900003703702011280210210e200541c0016a41086a220b2011411c6a280200360200200520112902143703c001201041016a2112201141086a2903002114201129030021130240200d450d00200220124102746a41c8056a28020021020240200d4101460d0041012110034020022802c8052102200d201041016a2210470d000b0b410021120b200541bc026a2016290300370200200541c4026a200f290300370200200541b0026a411c6a200129030037020020054198026a41086a200b280200360200200520052903703702b402200541e0016a41086a200541b0026a41086a290200370300200541e0016a41106a200541b0026a41106a290200370300200541e0016a41186a200541b0026a41186a290200370300200541e0016a41206a200541b0026a41206a280200360200200520052903c00137039802200520052902b0023703e0010b200541b0026a41106a200541e0016a41106a290300370300200541b0026a41086a200541e0016a41086a290300370300200541b0026a41186a200541e0016a41186a290300370300200541b0026a41206a200541e0016a41206a280200360200200541a8016a41086a20054198026a41086a280200360200200541386a41086a200541bc026a290200370300200541386a41106a200541c4026a290200370300200541386a41186a200541cc026a290200370300200520052903e0013703b00220052005290398023703a801200520052902b402370338200e450d01417f200741016a221020102007491b221041ffffff1f712010470d0420104106742210417f4c0d042010102c220f450d06200f2013370320200f2005290338370300200f200e360230200f20052903a801370234200f41286a2014370300200f41186a200541386a41186a290300370300200f41106a200541386a41106a290300370300200f41086a200541386a41086a290300370300200f413c6a200541a8016a41086a2802003602002010410676210d024020070d004101210e0c080b2007417f6a210741012111024002400340201220022f01e602490d01024020022802e00222100d002002102e410021020c030b20022f01e40221122002102e2011417f6a2111201021020c000b0b200541f0006a41186a2201200220124105746a220e4180036a290000370300200541f0006a41106a2216200e41f8026a290000370300200541f0006a41086a220c200e41f0026a2900003703002005200e41e8026a290000370370200e280210210b200541386a41086a2209200e411c6a2802003602002005200e290214370338201241016a2110200e41086a2903002134200e2903002133024020114101460d00200220104102746a41c8056a280200210202402011450d000340201141016a221020114f211220022802c80521022010211120120d000b0b410021100b200541bc026a200c290300370200200541c4026a2016290300370200200541b0026a411c6a200129030037020020054198026a41086a2009280200360200200520052903703702b402200541e0016a41086a200541b0026a41086a290200370300200541e0016a41106a200541b0026a41106a290200370300200541e0016a41186a200541b0026a41186a290200370300200541e0016a41206a200541b0026a41206a2802003602002005200529033837039802200520052902b0023703e0010b200541b0026a41106a220c200541e0016a41106a2208290300370300200541b0026a41086a2209200541e0016a41086a2206290300370300200541b0026a41186a2219200541e0016a41186a2222290300370300200541b0026a41206a2220200541e0016a41206a2223280200360200200541206a41086a220a20054198026a41086a2230280200360200200541c0016a41086a221a200541bc026a290200370300200541c0016a41106a221b200541c4026a290200370300200541c0016a41186a221c200541b0026a411c6a290200370300200520052903e0013703b0022005200529039802370320200520052902b4023703c00102400240200b0d004101210e0c010b200541f0006a41046a2101200541b0026a41046a211d4101210e03402009201a290300370300200c201b2903003703002019201c290300370300200541386a41086a2216200a280200360200200520052903c0013703b00220052005290320370338024002400240200d200e470d00200d200e6b417f200741016a221220122007491b22124f0d00200e20126a2212200e490d09200d41017422112012201120124b1b22124104201241044b1b221241ffffff1f7120124641037421112012410674211202400240200d0d00200541003602e0010c010b200541083602e8012005200f3602e0012005200d4106743602e4010b200541f0006a20122011200541e0016a107d2005280278211220052802704101460d012005280274210f2012410676210d0b200c2903002113201929030021142009290300211520052903b0022132200f200e4106746a2212200b36023020122032370300201241086a201537030020122033370320201241286a2034370300201241186a2014370300201241106a2013370300201220052903383702342012413c6a2016280200360200200e41016a210e2007450d0b2007417f6a2107410121120c010b2012450d070c090b024002400340201020022f01e602490d01024020022802e0022211450d0020022f01e40221102002102e2012417f6a2112201121020c010b0b2002102e410021020c010b200541386a41186a2217200220104105746a22114180036a290000370300200541386a41106a2218201141f8026a2900003703002016201141f0026a2900003703002005201141e8026a2900003703382011280210210b20302011411c6a2802003602002005201129021437039802201041016a2110201141086a290300213420112903002133024020124101460d00200220104102746a41c8056a280200210202402012450d000340201241016a221020124f211120022802c80521022010211220110d000b0b410021100b201d2005290338370000201d41086a2016290300370000201d41106a2018290300370000201d41186a2017290300370000200541a8016a41086a2030280200360200200620092902003703002008200c290200370300202220192902003703002023202028020036020020052005290398023703a801200520052902b0023703e0010b200541f0006a41206a2023280200360200200541f0006a41186a2022290300370300200541f0006a41106a2008290300370300200541f0006a41086a2006290300370300200a200541a8016a41086a280200360200200520052903e001370370200520052903a801370320201a200141086a290200370300201b200141106a290200370300201c200141186a290200370300200520012902003703c001200b0d000b0b2007450d0703402007417f6a210741012112024002400340201020022f01e602490d01024020022802e00222110d002002102e410021020c030b20022f01e40221102002102e2012417f6a2112201121020c000b0b201041016a2111200220104105746a2210280214210120102802102116024020124101470d00201121100c010b200220114102746a41c8056a280200210202402012450d0041002110034020022802c805210220122010417f6a2210470d000b0b410021100b2016450d0902402001450d00200141306c450d002016102e0b2007450d080c000b0b20020d010c040b2007450d00200541c0026a210f200541b8026a210d03402007417f6a210741012110024002400340201220022f01e602490d01024020022802e0022211450d0020022f01e40221122002102e2010417f6a2110201121020c010b0b2002102e410021020c010b200f200220124105746a22114180036a290000370300200d201141f8026a2900003703002005201141f0026a2900003703b002201241016a21122011280214210e2011280210210120104101460d00200220124102746a41c8056a280200210202402010450d000340201041016a221220104f211120022802c80521022012211020110d000b0b410021120b2001450d040240200e450d00200e41306c450d002001102e0b20070d000b0b034020022802e00221102002102e2010210220100d000c030b0b41e8aac700412b41f8b7c0001039000b1038000b4108210f4100210e4100210d0c020b1036000b034020022802e00221102002102e2010210220100d000b0b2000200f3602042000410c6a200e360200200041086a200d360200410021020b20002002360200200541f0026a24000be30102027f017e230041206b22032400024002400240200041046a280200220420016b20024f0d00200120026a22022001490d02200441017422012002200120024b1b22014104200141044b1bad42307e2205422088a74541037421012005a721020240024020040d00200341003602100c010b200341106a41086a41083602002003200441306c360214200320002802003602100b200320022001200341106a107d200341086a280200210120032802004101460d0120002003280204360200200041046a200141306e3602000b200341206a24000f0b2001450d001036000b1038000be71e080a7f017e017f017e017f027e0e7f017e230041d0046b220324002003420037020c02400240024002400240024002402001280208220441ffffffff03712004470d0020044102742205417f4c0d0020012802042106200128020021070240024020050d00410421010c010b2005102c2201450d070b41002108200341003602202003200136021820032005410276220936021c024002400240200920044f0d00200541017622092004200920044b1b22094104200941044b1b220941ffffffff0371200946410274210a200941027421090240024020050d00200341003602e8030c010b200341f0036a4104360200200320053602ec03200320013602e8030b20034180036a2009200a200341e8036a107d20034188036a280200210502402003280280034101460d00200320032802840322013602182003200541027636021c200328022021080c020b2005450d030c090b2004450d010b2004410574210b200120084102746a210a200341e8036a41046a210c20034180036a41c4006a210141002109200721050340200341c8016a41186a200541186a2204290000220d370300200341c8016a41106a200541106a220e290000220f370300200341c8016a41086a200541086a221029000022113703002003200529000022123703c801200341a8026a41186a22132004290000370300200341a8026a41106a2204200e290000370300200341a8026a41086a220e2010290000370300200320052900003703a802200341e8036a41186a200d370300200341e8036a41106a200f370300200341e8036a41086a2011370300200320123703e803200341086a200341e8036a200910a402200141186a2013290300370200200141106a2004290300370200200141086a200e290300370200200120032903a80237020020034180036a410041c40010eb081a200c20034180036a41e40010e9081a41f800102c2204450d08200541206a21052004410036020820044281808080103703002004410c6a200341e8036a41e80010e9081a200441003a0074200420032f00f8013b0075200441f7006a200341f8016a41026a2d00003a0000200a2004360200200941016a2109200a41046a210a200b41606a220b0d000b200820096a21080b200320083602200240200641ffffff3f71450d002007102e0b2002280208210420022802042107200228020021022003413c6a200341186a360200200320023602302003200736022c2003200236022820032002200441386c220a6a22143602342003200341086a360238200221012004450d04200341e8036a41346a2106200341286a41106a210820034180036a412c6a2109200221010340200341d8026a41086a220b2001220441086a290300370300200341d8026a41106a220e200441106a290300370300200341d8026a41186a2210200441186a290300370300200341d8026a41206a2213200441206a290300370300200320042903003703d8022003200441386a2201360230200441286a2802002105200341c0006a41086a220c200441346a28020036020020032004412c6a2902003703402005450d0420034180036a41206a201329030037030020034180036a41186a201029030037030020034180036a41106a200e29030037030020034180036a41086a200b29030037030020092003290340370200200941086a200c280200360200200320032903d80237038003200320053602a803200341e8036a200820034180036a10ba04024020032802980422050d00200a41486a220a0d010c050b0b200341a8026a41286a2204200341e8036a41286a290300370300200341a8026a41206a2201200341e8036a41206a290300370300200341a8026a41186a2209200341e8036a41186a290300370300200341a8026a41106a220a200341e8036a41106a290300370300200341a8026a41086a220b200341e8036a41086a290300370300200341d0006a41086a220e200641086a290200370300200341d0006a41106a2210200641106a290200370300200341d0006a41186a2213200641186a290200370300200341d0006a41206a220c200641206a290200370300200341d0006a41286a2208200641286a280200360200200320032903e8033703a80220032006290200370350200341f8016a41086a2202200e290300370300200341f8016a41106a220e2010290300370300200341f8016a41186a22102013290300370300200341f8016a41206a2213200c290300370300200341f8016a41286a220c2008280200360200200341c8016a41086a2208200b290300370300200341c8016a41106a220b200a290300370300200341c8016a41186a220a2009290300370300200341c8016a41206a22072001290300370300200341c8016a41286a22012004290300370300200320032903503703f801200320032903a8023703c80120034198016a41286a2204200c28020036020020034198016a41206a220c201329030037030020034198016a41186a2213201029030037030020034198016a41106a2210200e29030037030020034198016a41086a220e2002290300370300200320032903f8013703980141e000102c2209450d06200920032903c801370300200920053602302009200329039801370234200941286a2001290300370300200941206a2007290300370300200941186a200a290300370300200941106a200b290300370300200941086a20082903003703002009413c6a200e290300370200200941c4006a2010290300370200200941cc006a2013290300370200200941d4006a200c290300370200200941dc006a200428020036020020034180016a41086a200341286a41086a290300220d37030020034180016a41106a2202200341286a41106a29030037030020032003290328370380010240200da72201200328028c012208470d0041012107410121060c030b20034180036a412c6a210a200341e8036a41346a211541012107410121060340200341d8026a41186a220b2001220441186a290300370300200341d8026a41206a220e200441206a2903003703002003200441386a220136028801200341d8026a41086a2210200441086a290300370300200341d8026a41106a2213200441106a290300370300200320042903003703d802200441286a2802002105200341c0006a41086a220c200441346a28020036020020032004412c6a2902003703402005450d0220034180036a41206a2214200e29030037030020034180036a41186a220e200b29030037030020034180036a41106a220b201329030037030020034180036a41086a22132010290300370300200a2003290340370200200a41086a200c280200360200200320032903d80237038003200320053602a803200341e8036a200220034180036a10ba04024020032802980422050d0020082001470d010c030b200341a8026a41286a2204200341e8036a41286a2201290300370300200341a8026a41206a2216200341e8036a41206a2210290300370300200341a8026a41186a2217200341e8036a41186a220c290300370300200341a8026a41106a2218200341e8036a41106a2208290300370300200341a8026a41086a2219200341e8036a41086a221a290300370300200341d0006a41086a221b201541086a290200370300200341d0006a41106a221c201541106a290200370300200341d0006a41186a221d201541186a290200370300200341d0006a41206a221e201541206a290200370300200341d0006a41286a221f201541286a280200360200200320032903e8033703a80220032015290200370350200341f8016a41086a2220201b290300370300200341f8016a41106a221b201c290300370300200341f8016a41186a221c201d290300370300200341f8016a41206a221d201e290300370300200341f8016a41286a221e201f280200360200200341c8016a41086a221f2019290300370300200341c8016a41106a22192018290300370300200341c8016a41186a22182017290300370300200341c8016a41206a22172016290300370300200341c8016a41286a22162004290300370300200320032903503703f801200320032903a8023703c80120034198016a41286a2204201e28020036020020034198016a41206a221e201d29030037030020034198016a41186a221d201c29030037030020034198016a41106a221c201b29030037030020034198016a41086a221b2020290300370300200320032903f80137039801201a201f29030037030020082019290300370300200c20182903003703002010201729030037030020012016290300370300200320032903c8013703e8032013201b290300370300200b201c290300370300200e201d2903003703002014201e29030037030020034180036a41286a221620042802003602002003200329039801370380030240024020062007470d00200741016a22042007490d03200741017422172004201720044b1b22044104200441044b1bad42e0007e220d422088a7454103742104200da721170240024020070d00200341003602a8020c010b200341083602b002200320093602a8022003200741e0006c3602ac020b200341f8016a20172004200341a8026a107d200328028002210420032802f8014101460d0120032802fc012109200441e0006e21070b2009200641e0006c6a220420032903e8033703002001290300210d201a290300210f20082903002111200c29030021122010290300212120042005360230200441206a2021370300200441186a2012370300200441106a2011370300200441086a200f370300200441286a200d370300200441346a2003290380033702002004413c6a2013290300370200200441c4006a200b290300370200200441cc006a200e290300370200200441d4006a2014290300370200200441dc006a2016280200360200200641016a21062003280288012201200328028c012208470d010c040b0b20040d060b1038000b200441386a21010b200820016b220441386d210502402004450d00200541386c21052001412c6a210403400240200428020041ffffff3f71450d002004417c6a280200102e0b200441386a2104200541486a22050d000b0b2003280284012204450d02200441386c450d02200328028001102e0c020b200441386a21010b201420016b220441386d210502402004450d00200541386c21052001412c6a210403400240200428020041ffffff3f71450d002004417c6a280200102e0b200441386a2104200541486a22050d000b0b410821094100210602402007450d00200741386c450d002002102e0b410021070b200020032903183702002000200936020c200041146a2006360200200041106a2007360200200041086a200341186a41086a280200360200200341086a10bc02200341d0046a24000f0b1036000ba10b05047f027e0b7f037e017f230041f0016b220324002002412c6a2802002104200241306a28020021052002280228210620022903002107200341186a200241206a290000370300200341106a200241186a290000370300200341086a200241106a2900003703002003200229000837030002400240024002400240024002402005ad42d8007e2208422088a70d002008a72202417f4c0d000240024020020d00410821090c010b2002102c2209450d020b200241d8006e210a024020050d004100210b0c070b200620054105746a210c20034188016a41046a210d4100210b2006210e0340200341206a41086a220f200e41086a290000370300200341206a41106a2210200e41106a290000370300200341206a41186a2211200e41186a2900003703002003200e290000370320200b41d8006c2102200e41206a210e2009210502400240024003402002450d01200241a87f6a2102200541346a2112200541d8006a21052012200341206a412010ec080d000c020b0b2001280200200341206a10a0022202450d00200128020422052802082213200228020022124d0d05200528020020124102746a28020022122802080d062012417f3602082012427f2012290330220820077c221420142008542205201241386a221329030022152005ad7c2216201554201420085a1b22051b3703302013427f201620051b370300200341e0006a41186a22132011290300370300200341e0006a41106a22112010290300370300200341e0006a41086a2210200f2903003703002003200329032037036020012802042205280208220f200228020022024d0d07200528020020024102746a280200220f28020041016a220241014d0d08200f2002360200200d410041e40010eb081a41f800102c2205450d042005410036020820054281808080103703002005410c6a20034188016a41e80010e9081a200541003a0074200520032f0085013b0075200541f7006a20034185016a41026a2d00003a0000200341c0006a41086a22172010290300370300200341c0006a41106a22102011290300370300200341c0006a41186a22112013290300370300200320032903603703400240200b200a470d00200b41016a2202200b490d04200b41017422132002201320024b1b22024104200241044b1bad42d8007e2208422088a74541037421022008a7211302400240200b0d0020034100360288010c010b200341083602900120032009360288012003200b41d8006c36028c010b200341e0006a2013200220034188016a107d2003280268210220032802604101460d0220032802642109200241d8006e210a0b2009200b41d8006c6a220242003703002002200f360230200241186a4200370300200241106a4200370300200241086a4200370300200241206a4200370300200241286a4200370300200220032903403702342002413c6a2017290300370200200241c4006a2010290300370200200241cc006a201129030037020020052005280200417f6a2202360200024020020d00200541046a22022002280200417f6a220236020020020d002005102e0b200b41016a210b2012201228020841016a3602080b200e200c460d080c010b0b20020d010b1038000b1036000b20122013418884c500103c000b4194dacc00411020034188016a41e4ffc400419884c500103e000b2002200f41a884c500103c000b00000b0240200441ffffff3f71450d002006102e0b02400240200b0d0020004100360230200a450d01200a41d8006c450d012009102e0c010b200042013703202000420037031020004200370308200020073703002000200a36023420002009360230200041286a4200370300200041186a4200370300200041386a200b3602002000413c6a2003290300370000200041c4006a200341086a290300370000200041cc006a200341106a290300370000200041d4006a200341186a2903003700000b200341f0016a24000bf60805077f027e047f037e027f230041306b2202240002400240024002400240024002400240200141386a2802002203450d002001280230220441d8006a21052004200341d8006c22066a21070340200541586a2802002203280208220441016a41004c0d04200541486a22082903002109200841086a290300210a20032004360208200341f4006a2d00004101460d02200541d8006a2105200641a87f6a22060d000b0b4100210620024100360220200242083703184108210b0c010b024002404110102c220b450d00200b2009370300200b200a3703084101210641012108034020052007460d02200541306a2802002203280208220441016a41004c0d05200541286a2903002109200541206a290300210a20032004360208200541d8006a22042105200341f4006a2d00004101470d000240024020082006470d00200641016a22052006490d08200641017422032005200320054b1b22054104200541044b1b220541ffffffff00712005464103742103200541047421050240024020060d00200241003602080c010b200241083602102002200b3602082002200641047436020c0b200241186a20052003200241086a107d2002280220210520022802184101460d01200228021c210b200541047621060b200b20084104746a220520093703082005200a370300200841016a2108200421050c010b0b2005450d050b1036000b200220083602202002200636021c2002200b3602180b200241086a200241186a2001290300200141086a29030010bc040240024020022802084101470d00200241086a41086a2802002105200228020c21030c010b20012802302204200128023841d8006c6a2108200228020c220c200241146a2802004104746a210d200241086a41086a280200210e200c210702400340200820042205460d01200541306a2802002203280208220441016a41004c0d0620032004360208200541d8006a2104200341f4006a2d0000450d002007200d460d01200541d8006a220441586a28020022052802080d07200741086a29030021092007290300210a2005417f360208200542002005290340220f200441486a220129030022107d22112011200f56200541c8006a22032903002211200141086a22122903007d200f201054ad7d220f201156200f2011511b22131b37034020034200200f20131b370300201220093703002001200a3703002005200528020841016a3602082005427f200a2005290340220f7c220a200a200f54220120092003290300220a7c2001ad7c2209200a542009200a511b22011b3703402003427f200920011b370300200741106a21070c000b0b410021030240200e41ffffffff0071450d00200c102e0b0b0240200641ffffffff0071450d00200b102e0b2000200536020420002003360200200241306a24000f0b41bcd9cc004118200241286a41c4ffc40041e883c500103e000b41bcd9cc004118200241286a41c4ffc40041e883c500103e000b1038000b41bcd9cc004118200241286a41c4ffc40041d4ffc400103e000b4194dacc004110200241286a41e4ffc40041f4ffc400103e000bdb3609057f027e017f027e037f067e0e7f017e077f230041e0006b22042400200128020022052001280208220641047422076a210842002109410021014200210a02400240024002400340024020072001470d0020060d02200042808080808001370200200041086a42003702000c030b200a200520016a220b41086a2903007c2009200b2903007c220c200954220bad7c220d200a51210e200d200a54210f200141106a2101200c2109200d210a200b200f200e1b4101470d000b200041b4d2cc0036020420004101360200200041086a411e3602000c010b0240200220092009200254200a200354200a200351220b1b22101b220d2009200220101b220c7d22112003200a20101b200a200320101b7d200d200c54ad7d2212844200520d00200641ffffffff00712006470d0320064104742201417f4c0d032001102c220b450d02200b2005200641047410e90821052000410c6a2006360200200041086a200141047636020020002005360204200041003602000c010b200441286a201120122006ad2213420010e708200441186a201120122013420010e608201342187e220d422088a70d02200da72201417f4c0d02200441186a41086a2903002114200441286a41086a29030021152004290318210c200429032821162001102c2217450d0102400240024002400240024002400240024002400240024002400240024002400240024002400240200141186e221820064f0d00200441386a41086a41083602002004201841186c36023c20042017360238200441d0006a201841017422012006200120064b1b22014104200141044b1bad42187e220da7200d422088a745410374200441386a107d200441d0006a41086a280200210120042802504101460d0120042802542117200141186e21180b20052008460d042006410474210b410021192017210103402005290300210a200141106a200541086a290300370300200141086a200a37030020012019360200200141186a2101201941016a2119200541106a2105200b41706a220b0d000b201941144b0d01201941014d0d0620172019417f6a220b41186c6a21084100210e03402019200b2201417f6a220b490d0402402019200b6b221a4102490d002017200141186c6a220141086a220f2903002017200b41186c6a220541086a2207290300220d5a200141106a221b2903002209200541106a221c290300220a5a2009200a511b0d002005280200211d200520012903003703002007200f290300370300201c201b2903003703000240201a4103490d00200e417f6a211b41002105200821010340200141206a220f290300200d5a200141286a22072903002209200a5a2009200a511b0d01201b2005460d06200141106a2007290300370300200141086a200f2903003703002001200141186a220f290300370300200f2101200e2005417f6a2205470d000b200f21010b2001200d3703082001201d360200200141106a200a3703000b200841686a2108200e417f6a210e200b0d000c070b0b20010d130c140b2019410176ad42187e220a422088a70d13200aa7221e417f4c0d13201e102c221f450d12201741686a2120201741406a212141042122410021234100211c20192124034020242108410021244101210702402008417f6a220e450d0002400240024002400240024002402017200e41186c6a220141086a290300200841186c221b20176a41586a2205290300220954200141106a290300220d200541086a290300220a54200d200a511b0d002008417e6a21072021201b6a210141002124410021050340024020072005470d00200821070c090b2009200129030022255a210b200a200141086a290300220d51210e200a200d5a210f200141686a2101200541016a210520252109200d210a200b200f200e1b0d000b200541016a21072005417f7320086a210e0c010b2021201b6a2101024003400240200e4101470d004100210e0c020b200920012903002225542105200a200141086a290300220d51210b200a200d54210f200141686a2101200e417f6a210e20252109200d210a2005200f200b1b0d000b0b2008200e490d01200820194b0d022008200e6b2207410176220b450d002017200e41186c6a21012020201b6a21050340200441386a41106a220f200141106a221b290300370300200441386a41086a221a200141086a221d29030037030020042001290300370338200541106a2226290300210a200541086a2227290300210920012005290300370300201d2009370300201b200a3703002026200f2903003703002027201a29030037030020052004290338370300200141186a2101200541686a2105200b417f6a220b0d000b0b0240200e0d00200e21240c060b0240200741094d0d00200e21240c060b200820194b0d03200e20086b210b2017200e41186c6a211b03402008200e417f6a2224490d050240200820246b22074102490d002017200e41186c6a220141086a220e2903002017202441186c6a220541086a220f290300220d5a200141106a221a2903002209200541106a221d290300220a5a2009200a511b0d002005280200212620052001290300370300200f200e290300370300201d201a290300370300024020074103490d0041012105201b21010340200141206a220e290300200d5a200141286a220f2903002209200a5a2009200a511b0d01200b20056a4101460d06200141106a200f290300370300200141086a200e2903003703002001200141186a220e290300370300200e2101200b200541016a22056a0d000b200e21010b2001200d37030820012026360200200141106a200a3703000b2024450d06201b41686a211b200b417f6a210b2024210e2007410a4f0d060c000b0b200e200841e4d1cc001057000b2008201941e4d1cc00104d000b2005200741d4d1cc00103c000b2008200e417f6a2224490d002008201941f4d1cc00104d000b2024200841f4d1cc001057000b02400240024002400240201c2023460d00201c21010c010b202341016a22012023490d18202341017422052001200520014b1b22014104200141044b1b220141ffffffff01712001464102742105200141037421010240024020230d00200441003602380c010b20044104360240200420223602382004202341037436023c0b200441d0006a20012005200441386a107d2004280258210520042802504101460d012004280254212220232101200541037621230b202220014103746a2201200736020420012024360200201c41016a2228211c202841024f0d010c020b2005450d160c150b0240024002400340024002400240024020222028221c417f6a22284103746a2201280200450d00201c41037420226a220f41746a280200220e200128020422054d0d00201c41024d0d082022201c417d6a22014103746a280204220b2005200e6a4d0d01201c41034d0d08200f41646a280200200b200e6a4b0d080c010b201c4103490d01200128020421052022201c417d6a22014103746a280204210b0b200b2005490d010b201c417e6a21010b0240201c200141016a22294d0d00201c20014d0d02202220014103746a2226280204222a20262802006a2201202220294103746a2227280200222b490d03200120194b0d04202641046a212c2017202b41186c6a221a2027280204221d41186c22056a210b200141186c210f024002402001202b6b2207201d6b2201201d490d00201f201a200510e908221b20056a210e02400240201d4101480d002007201d4a0d010b201a2101201b21050c020b2017200f6a2108201b2105201a210103402001200b2005200b41086a290300200541086a29030054200b41106a290300220a200541106a290300220954200a2009511b220f1b2207290300370300200141086a200741086a290300370300200141106a200741106a2903003703002005200541186a200f1b2105200141186a2101200b41186a200b200f1b220b20084f0d02200e20054b0d000c020b0b201f200b200141186c220510e908220720056a210e02400240201d4101480d00200141014e0d010b200b2101200721050c010b2020200f6a210f200b21010340200f200141686a2208200e41686a221b200e41706a2205290300200141706a220b29030054200541086a290300220a200b41086a290300220954200a2009511b22051b220b290300370300200f41086a200b41086a290300370300200f41106a200b41106a290300370300200e201b20051b210e0240201a2008200120051b2201490d00200721050c020b200f41686a210f200721052007200e490d000b0b20012005200e20056b220b200b4118706b10e9081a202c202a201d6a3602002026202b3602002027202741086a201c2029417f736a41037410ea081a4101211c202841014d0d050c010b0b2029201c4184d2cc00103c000b2001201c4194d2cc00103c000b202b200141a4d2cc001057000b2001201941a4d2cc00104d000b2024450d040c000b0b410120056b201a41d4d1cc00103c000b200b201941c4d1cc001056000b0240200920025a200a20035a200b1b0d004101210f410021190c030b41d2d2cc00413f4194d3cc00105d000b0240202341ffffffff0171450d002022102e0b201e4118702101201e4118490d00201e2001460d00201f102e0b2019411549210f20100d002006417f6a210b201741106a290300212520172903082102201120135441002012501b450d01200c2109200b21010c020b200441086a200220032013420010e70841002101200441086a41086a290300210d200429030821030240201120135441002012501b0d00410021012006210b0340201920014d0d0a2017200141186c6a2205290308220a20167c2209200a54220e200541106a290300222520157c200ead7c220a202554200a2025511b4101460d09200541086a220520093703002005200a37030802402009200354200a200d54200a200d511b0d00200141016a20067021010b200b417f6a220b0d000b0b200c201484500d020340201920014d0d072017200141186c6a2205290308222542017c220a202554220b200541106a2903002216200bad7c2209201654200a20255a1b4101460d06200541086a2205200a370300200520093703080240200a2003542009200d542009200d511b0d00200141016a20067021010b200c427f7c220a200c542105200a210c200a20142005ad7c427f7c22148450450d000c030b0b200b21010340201920014d0d042017200141186c6a220542002005290308220a20167d22032003200a56200541106a220e290300220920157d200a201654ad7d220d200956200d2009511b22051b200320051b2203370308200e4200200d20051b200d20051b220d3703002001200b2001417f6a220e200e20014b1b2003200256200d202556200d2025511b1b21012014201520097d2016200a54ad7d420020051b7c200c2016200a7d420020051b7c2209200c54ad7c21142009210c2006417f6a22060d000b0b2009201484500d002009210c0340201920014d0d02024002402017200141186c6a2205290308220a427f7c2216200a56200541106a2903002203200a50ad7d220d200356200a4200521b4101470d00200b2001417f6a2205200520014b1b21010c010b200541086a220520163703002005200d3703082001200b2001417f6a2205200520014b1b2016200256200d202556200d2025511b1b210120142009427f7c220c200954ad7c427f7c2114200c21090b200c2014844200520d000b0b024002400240200f450d00201941014d0d0a20172019417f6a220e41186c6a21084100210f03402019200e2201417f6a220e490d0302402019200e6b221a4102490d002017200141186c6a22012802002017200e41186c6a220528020022074f0d00200520012903003703002005290308210a200541086a200141086a290300370300200541106a220529030021092005200141106a2903003703000240201a4103490d00200f417f6a211b41002105200821010340200141186a220b28020020074f0d01201b2005460d05200141106a200141286a290300370300200141086a200141206a2903003703002001200b290300370300200b2101200f2005417f6a2205470d000b200b21010b2001200a37030820012007360200200141106a20093703000b200841686a2108200f417f6a210f200e0d000c0b0b0b2019410176ad42187e220a422088a70d0c200aa72210417f4c0d0c2010102c221f450d0b201741686a2123201741b87f6a212041042122410021064100211c20192124034020242108410021244101210702402008417f6a220b450d0002400240024002400240024002402017200b41186c6a280200200841186c221b20176a41506a2802002201490d002008417e6a21072020201b6a210b41002124410021050340024020072005470d00200821070c090b200541016a21052001200b280200220e4f210f200b41686a210b200e2101200f0d000b200541016a21072005417f7320086a210b0c010b2020201b6a2105024003400240200b4101470d004100210b0c020b200b417f6a210b20012005280200220e49210f200541686a2105200e2101200f0d000b0b2008200b490d01200820194b0d022008200b6b2207410176220e450d002017200b41186c6a21012023201b6a21050340200441386a41106a220f200141106a221b290300370300200441386a41086a221a200141086a221d29030037030020042001290300370338200541106a2226290300210a200541086a2227290300210920012005290300370300201d2009370300201b200a3703002026200f2903003703002027201a29030037030020052004290338370300200141186a2101200541686a2105200e417f6a220e0d000b0b0240200b0d00200b21240c060b0240200741094d0d00200b21240c060b200820194b0d03200b20086b210e2017200b41186c6a211b03402008200b417f6a2224490d050240200820246b22074102490d002017200b41186c6a22012802002017202441186c6a2205280200220f4f0d00200520012903003703002005290308210a200541086a200141086a290300370300200541106a220529030021092005200141106a290300370300024020074103490d0041012105201b21010340200141186a220b280200200f4f0d01200e20056a4101460d06200141106a200141286a290300370300200141086a200141206a2903003703002001200b290300370300200b2101200e200541016a22056a0d000b200b21010b2001200a3703082001200f360200200141106a20093703000b2024450d06201b41686a211b200e417f6a210e2024210b2007410a4f0d060c000b0b200b200841e4d1cc001057000b2008201941e4d1cc00104d000b2005200741d4d1cc00103c000b2008200b417f6a2224490d002008201941f4d1cc00104d000b2024200841f4d1cc001057000b02400240024002400240201c2006460d00201c21010c010b200641016a22012006490d11200641017422052001200520014b1b22014104200141044b1b220141ffffffff01712001464102742105200141037421010240024020060d00200441003602380c010b20044104360240200420223602382004200641037436023c0b200441d0006a20012005200441386a107d2004280258210520042802504101460d012004280254212220062101200541037621060b202220014103746a2201200736020420012024360200201c41016a2228211c202841024f0d010c020b2005450d0f0c0e0b0240024002400340024002400240024020222028221c417f6a22284103746a2201280200450d00201c41037420226a220f41746a280200220e200128020422054d0d00201c41024d0d082022201c417d6a22014103746a280204220b2005200e6a4d0d01201c41034d0d08200f41646a280200200b200e6a4b0d080c010b201c4103490d01200128020421052022201c417d6a22014103746a280204210b0b200b2005490d010b201c417e6a21010b0240201c200141016a22294d0d00201c20014d0d02202220014103746a2226280204222a20262802006a2201202220294103746a2227280200222b490d03200120194b0d04202641046a212c2017202b41186c6a221a2027280204221d41186c22056a210b200141186c210f024002402001202b6b2207201d6b2201201d490d00201f201a200510e908221b20056a210e02400240201d4101480d002007201d4a0d010b201a2101201b21050c020b2017200f6a2108201b2105201a210103402001200b2005200b280200200528020049220f1b2207290300370300200141106a200741106a290300370300200141086a200741086a2903003703002005200541186a200f1b2105200141186a2101200b41186a200b200f1b220b20084f0d02200e20054b0d000c020b0b201f200b200141186c220510e908221b20056a210e02400240201d4101480d00200141014e0d010b200b2101201b21050c010b2023200f6a210f200b21010340200f200141686a2205200e41686a220b200b28020020052802004922071b2208290300370300200f41106a200841106a290300370300200f41086a200841086a290300370300200e200b20071b210e0240201a2005200120071b2201490d00201b21050c020b200f41686a210f201b2105201b200e490d000b0b20012005200e20056b220b200b4118706b10e9081a202c202a201d6a3602002026202b3602002027202741086a201c2029417f736a41037410ea081a4101211c202841014d0d050c010b0b2029201c4184d2cc00103c000b2001201c4194d2cc00103c000b202b200141a4d2cc001057000b2001201941a4d2cc00104d000b2024450d090c000b0b410120056b201a41d4d1cc00103c000b200e201941c4d1cc001056000b20012019419cd4cc00103c000b20012019418cd4cc00103c000b41b4d3cc00412641fcd3cc00105d000b2001201941ecd3cc00103c000b41b4d3cc00412641dcd3cc00105d000b2001201941a4d3cc00103c000b0240200641ffffffff0171450d002022102e0b2010411870210120104118490d0020102001460d00201f102e0b201941186c41186d220141ffffffff00712001470d0220014104742205417f4c0d020240024020050d004108210e0c010b2005102c220e450d020b02400240024002402005410476220f20014f0d002005410376220b2001200b20014b1b22014104200141044b1b220141ffffffff0071200146410374210b200141047421010240024020050d00200441003602380c010b200441386a41086a41083602002004200536023c2004200e3602380b200441d0006a2001200b200441386a107d200441d8006a280200210120042802504101460d012004280254210e2001410476210f0b20190d01410021010c020b2001450d040c030b201741086a2101201941186c220b41686a41186e2107200e210503402001290300210a2005200141086a2903003703082005200a370300200141186a2101200541106a2105200b41686a220b0d000b200741016a21010b02402018450d00201841186c450d002017102e0b2000200e360204200041003602002000410c6a2001360200200041086a200f3602000b200441e0006a24000f0b1036000b1038000bb50b020d7f047e23004190026b220424002004200337036820042002370360200128020021052001280204210602400240024002400240024020012802082207450d002005200741226c22086a2109200441d0006a2002200342ffff03420010e608200441c0006a2002200342ffff03420010e708200441c0006a41086a2903002102200429034021032004280250210a200521070340200741206a2f0100210b200441f0016a41186a200741186a290000370300200441f0016a41106a200741106a290000370300200441f0016a41086a200741086a290000370300200420072900003703f001200b0d02200741226a21072008415e6a22080d000b0b20004100360208200042083702002006450d01200641226c450d012005102e0c010b200441306a20032002200bad420010e80820044190016a41086a200441f0016a41086a2903002202370300200441f0006a41186a220c200441f0016a41186a290300370300200441f0006a41106a220d200441f0016a41106a290300370300200441f0006a41086a220e2002370300200420042903f00122023703900120042002370370200a200b6c220b41ffff036e210a200b41ffff0370210f20042903302102200441306a41086a29030021034130102c2210450d0220102002200a417f200b4180807c491b200f41ffff014b6aad42ffff03837c221137032020102004290370370300201041286a20032011200254ad7c370300201041186a200c290300370300201041106a200d290300370300201041086a200e2903003703002004200936027c2004200741226a220736027820042006360274200420053602702004200441e0006a360280010240024020084122470d004101210d4101210c0c010b4101210d4101210c03402004200741226a220b360278200741206a2f01002108200441f0016a41186a2205200741186a290000370300200441f0016a41106a2206200741106a290000370300200441f0016a41086a220a200741086a290000370300200420072900003703f001024020080d00200b21072009200b470d010c020b200441206a20042802800122072903002202200741086a290300220342ffff03420010e608200441106a2002200342ffff03420010e70820042004290310200441106a41086a2903002008ad420010e80820044190016a41086a2207200a29030037030020044190016a41106a220b200629030037030020044190016a41186a22092005290300370300200420042903f00122023703b0012004200237039001200520092903003703002006200b290300370300200a200729030037030020042004290390013703f001200428022020086c220b41ffff036e2108200b41ffff0370210920042903002102200441086a29030021030240200c200d470d00200d41016a2207200d490d06200d410174220e2007200e20074b1b22074104200741044b1bad42307e2211422088a74541037421072011a7210e02400240200d0d00200441003602d0010c010b200441083602d801200420103602d0012004200d41306c3602d4010b200441b0016a200e2007200441d0016a107d20042802b801210720042802b0014101460d0420042802b4012110200741306e210d0b2010200c41306c6a220720042903f0013703002006290300211120052903002112200a2903002113200720022008417f200b4180807c491b200941ffff014b6aad42ffff03837c2214370320200741086a2013370300200741286a20032014200254ad7c370300200741186a2012370300200741106a2011370300200c41016a210c20042802782207200428027c2209470d000b0b024020042802742207450d00200741226c450d002004280270102e0b2000200c3602082000200d360204200020103602000b2000200129020c37020c200041246a200141246a2902003702002000411c6a2001411c6a290200370200200041146a200141146a29020037020020044190026a24000f0b2007450d010b1036000b1038000b9e3203187f017e0f7f230041206b2202240002402001280208220320036a22042003490d002001280200210502400240024020040d00410221060c010b2004102c2206450d010b02400240024002402004410176220720034f0d0020042003200420034b1b22084104200841044b1b220820086a220920084f41017421080240024020040d00200241003602100c010b200241186a410236020020022004360214200220063602100b200220092008200241106a107d200241086a280200210420022802004101460d0120022802042106200441017621070b20052005200341226c6a470d01410021040c020b20040d020c030b200541206a2104200341226c2205415e6a41226e2108200621030340200320042f01003b0100200441226a2104200341026a21032005415e6a22050d000b200841016a21040b4101450d0120044102742203417f4c0d010240024020030d004104210a0c010b2003102c220a450d010b0240024002402003410276220b20044f0d00200341017622052004200520044b1b22054104200541044b1b41027421050240024020030d00200241003602100c010b200241186a4104360200200220033602142002200a3602100b200220054104200241106a107d200241086a2802002103024020022802004101460d002002280204210a2003410276210b0c020b2003450d040c030b20040d004100210c0c010b20044101742205417e6a4101762108200a2104200621030340200420032f0100360200200441046a2104200341026a21032005417e6a22050d000b200841016a210c0b200a200c41027422046a21094100210d200a2103024002400240024002400340024020040d000240200c0d004100210e4104210f4100210c0c050b024041ffff03200d200d41ffff034922041b200d41ffff0320041b6b22100d00200c41ffffffff0371200c470d09200c4102742204417f4c0d092004102c220f450d08200f200a200c41027410e9081a2004410276210e0c050b2010200c7021112010200c6e21122009200a6b2204410276220341ffffffff01712003470d0820044101742204417f4c0d080240024020040d00410421130c010b2004102c2213450d080b02400240024002402004410376221420034f0d00200441027622052003200520034b1b22034104200341044b1b220341ffffffff01712003464102742105200341037421030240024020040d00200241003602100c010b200241186a410436020020022004360214200220133602100b200220032005200241106a107d200241086a280200210420022802004101460d0120022802042113200441037621140b200c4102742208417c6a221541027621164100210320132104200a21050340200441046a200528020036020020042003360200200441086a2104200341016a2103200541046a21052008417c6a22080d000b201641016a21170240201541cf004b0d002015450d07201320164103746a2118201741037420136a41786a210e41002108201621050340201720052204417f6a2205490d040240201720056b22194102490d00201320044103746a220441046a280200201320054103746a220341046a2802004f0d002003290200211a20032004290200370200024020194103490d00201a422088a7210f2008417f6a211b41002103200e210403402004410c6a280200200f4f0d01201b2003460d062004200441086a22092902003702002009210420082003417f6a2203470d000b201821040b2004201a3702000b2008417f6a2108200e41786a210e20050d000c080b0b2017410176220441ffffffff01712004470d0b2004410374221c417f4c0d0b201c102c221d450d0a201341786a211e2013416c6a211f4104212041002121410021192017212203402022210f41002122410121090240200f417f6a2204450d000240024002400240024002400240201320044103746a41046a280200200f410374221820136a41746a2802002203490d00200f417e6a210e201f20186a2105410021224100210403400240200e2004470d00200f21090c090b200441016a21042003200528020022084f2109200541786a21052008210320090d000b200441016a21092004417f73200f6a21040c010b201f20186a210502400340024020044101470d00410021040c020b2004417f6a2104200320052802002208492109200541786a21052008210320090d000b0b200f2004490d01200f20174b0d02200f20046b22094101762208450d00201320044103746a2103201e20186a210503402003290200211a200320052902003702002005201a370200200341086a2103200541786a21052008417f6a22080d000b0b024020040d00200421220c060b0240200941094d0d00200421220c060b200f20174b0d03200f20046b2105201320044103746a211b201e20186a21230340200f2004417f6a2222490d050240200f20226b22094102490d00201320044103746a220441046a280200201320224103746a220341046a2802004f0d002003290200211a20032004290200370200024020094103490d00201a422088a7210e2005417f6a211841002103201b210403402004410c6a280200200e4f0d0120052003460d062004200441086a2208290200370200200821042018200341016a2203470d000b202321040b2004201a3702000b2022450d06200541016a2105201b41786a211b202221042009410a4f0d060c000b0b2004200f41e4d1cc001057000b200f201741e4d1cc00104d000b200341016a200941d4d1cc00103c000b200f2004417f6a2222490d00200f201741f4d1cc00104d000b2022200f41f4d1cc001057000b0240024002400240024020192021460d00201921040c010b202141016a22042021490d10202141017422032004200320044b1b22044104200441044b1b220441ffffffff01712004464102742103200441037421040240024020210d00200241003602100c010b2002410436021820022020360210200220214103743602140b200220042003200241106a107d2002280208210320022802004101460d012002280204212020212104200341037621210b202020044103746a2204200936020420042022360200201941016a22242119202441024f0d010c020b2003450d0e0c0d0b02400240024003400240024002400240202020242219417f6a22244103746a2204280200450d00201941037420206a220941746a2802002208200428020422034d0d00201941024d0d0820202019417d6a22044103746a2802042205200320086a4d0d01201941034d0d08200941646a280200200520086a4b0d080c010b20194103490d012004280204210320202019417d6a22044103746a28020421050b20052003490d010b2019417e6a21040b02402019200441016a22254d0d00201920044d0d02202020044103746a2223280204222620232802006a2204202020254103746a22272802002228490d03200420174b0d04202341046a2129201320284103746a221b2027280204221841037422036a21082004410374210902400240200420286b220f20186b22042018490d00201d201b200310e908220420036a21050240024020184101480d00200f20184a0d010b201b2103200421040c020b201320096a210f20042104201b21030340200320082004200841046a280200200441046a2802004922091b2902003702002004200441086a20091b2104200341086a2103200841086a200820091b2208200f4f0d02200520044b0d000c020b0b201d20082004410374220310e908220f20036a21050240024020184101480d00200441014e0d010b20082103200f21040c010b201e20096a21092008210303402009200341786a2208200541786a220e2005417c6a2802002003417c6a2802004922041b2902003702002005200e20041b21050240201b2008200320041b2203490d00200f21040c020b200941786a2109200f2104200f2005490d000b0b20032004200520046b41787110e9081a2029202620186a360200202320283602002027202741086a20192025417f736a41037410ea081a41012119202441014d0d050c010b0b202520194184d2cc00103c000b200420194194d2cc00103c000b2028200441a4d2cc001057000b2004201741a4d2cc00104d000b2022450d060c000b0b2004450d0a0c090b410120036b201941d4d1cc00103c000b2005201741c4d1cc001056000b2004417c6a2104200d20032802006a2205200d492108200341046a21032005210d2008450d000b0240200b450d00200a102e0b411e210e41b4d2cc0021040c030b0240202141ffffffff0171450d002020102e0b201c450d00201d102e0b0240024002400240024002400240024002400240200d41feff034b0d0041ffff03200c6e2109410021040240200c20104b0d0041002104200c2105034020162004490d09201320044103746a2208280204220f20126a2203200f490d08200841046a2003360200024020032009490d00200441016a200c7021040b2005417f6a22050d000b0b2011450d01034020162004490d06201320044103746a2205280204220841016a22032008490d05200541046a2003360200024020032009490d00200441016a200c7021040b2011417f6a22110d000c020b0b200c417f6a21092013280204210e02400240200c20104d0d00200921040c010b20092104034020162004490d04201320044103746a220341002003280204220320126b2205200520034b22081b200520081b2205360204200420092004417f6a220f200f20044b1b2005200e4b1b21042011201220036b410020081b6a2111200c417f6a220c0d000b0b2011450d00034020162004490d0202400240201320044103746a22082802042203417f6a220520034d0d0020092004417f6a2203200320044b1b21040c010b200841046a2005360200200420092004417f6a2203200320044b1b2005200e4b1b21042011417f6a21110b20110d000b0b024002400240201541cf004b0d002015450d0a201320164103746a2119201741037420136a41786a210f410021080340201720162204417f6a2216490d030240201720166b221b4102490d00201320044103746a2204280200201320164103746a22032802004f0d002003290200211a200320042902003702000240201b4103490d00201aa721092008417f6a210e41002103200f21040340200441086a220528020020094f0d01200e2003460d05200420052902003702002005210420082003417f6a2203470d000b201921040b2004201a3702000b2008417f6a2108200f41786a210f20160d000c0b0b0b2017410176220441ffffffff01712004470d0e2004410374220c417f4c0d0e200c102c2229450d0d201341786a211d201341686a21114104212041002116410021192017212203402022210f41002122410121090240200f417f6a2204450d000240024002400240024002400240201320044103746a280200200f410374221820136a41706a2802002203490d00200f417e6a210e201120186a2105410021224100210403400240200e2004470d00200f21090c090b200441016a21042003200528020022084f2109200541786a21052008210320090d000b200441016a21092004417f73200f6a21040c010b201120186a210502400340024020044101470d00410021040c020b2004417f6a2104200320052802002208492109200541786a21052008210320090d000b0b200f2004490d01200f20174b0d02200f20046b22094101762208450d00201320044103746a2103201d20186a210503402003290200211a200320052902003702002005201a370200200341086a2103200541786a21052008417f6a22080d000b0b024020040d00200421220c060b0240200941094d0d00200421220c060b200f20174b0d03200f20046b2108201320044103746a211b201d20186a21230340200f2004417f6a2222490d050240200f20226b22094102490d00201320044103746a2204280200201320224103746a22032802004f0d002003290200211a20032004290200370200024020094103490d00201aa7210e2008417f6a211841002103201b21040340200441086a2205280200200e4f0d0120082003460d0620042005290200370200200521042018200341016a2203470d000b202321040b2004201a3702000b2022450d06200841016a2108201b41786a211b202221042009410a4f0d060c000b0b2004200f41e4d1cc001057000b200f201741e4d1cc00104d000b200341016a200941d4d1cc00103c000b200f2004417f6a2222490d00200f201741f4d1cc00104d000b2022200f41f4d1cc001057000b0240024002400240024020192016460d00201921040c010b201641016a22042016490d13201641017422032004200320044b1b22044104200441044b1b220441ffffffff01712004464102742103200441037421040240024020160d00200241003602100c010b2002410436021820022020360210200220164103743602140b200220042003200241106a107d2002280208210320022802004101460d012002280204212020162104200341037621160b202020044103746a2204200936020420042022360200201941016a22242119202441024f0d010c020b2003450d110c100b02400240024003400240024002400240202020242219417f6a22244103746a2204280200450d00201941037420206a220941746a2802002208200428020422034d0d00201941024d0d0820202019417d6a22044103746a2802042205200320086a4d0d01201941034d0d08200941646a280200200520086a4b0d080c010b20194103490d012004280204210320202019417d6a22044103746a28020421050b20052003490d010b2019417e6a21040b02402019200441016a220d4d0d00201920044d0d02202020044103746a2223280204222520232802006a22042020200d4103746a22272802002228490d03200420174b0d04202341046a2126201320284103746a221b2027280204221841037422036a21052004410374210902400240200420286b220f20186b22042018490d002029201b200310e908220420036a21080240024020184101480d00200f20184a0d010b201b2103200421040c020b201320096a210f20042104201b21030340200320052004200528020020042802004922091b2902003702002004200441086a20091b2104200341086a2103200541086a200520091b2205200f4f0d02200820044b0d000c020b0b202920052004410374220310e908220e20036a21080240024020184101480d00200441014e0d010b20052103200e21040c010b201d20096a210f200521030340200f200341786a2204200841786a2205200528020020042802004922091b2902003702002008200520091b21080240201b2004200320091b2203490d00200e21040c020b200f41786a210f200e2104200e2008490d000b0b20032004200820046b41787110e9081a2026202520186a360200202320283602002027202741086a2019200d417f736a41037410ea081a41012119202441014d0d050c010b0b200d20194184d2cc00103c000b200420194194d2cc00103c000b2028200441a4d2cc001057000b2004201741a4d2cc00104d000b2022450d090c000b0b410120036b201b41d4d1cc00103c000b2016201741c4d1cc001056000b20042017419cd4cc00103c000b20042017418cd4cc00103c000b41b4d3cc00412641fcd3cc00105d000b2004201741ecd3cc00103c000b41b4d3cc00412641dcd3cc00105d000b2004201741a4d3cc00103c000b0240201641ffffffff0171450d002020102e0b200c450d002029102e0b2017410374410375220441ffffffff03712004470d0420044102742203417f4c0d040240024020030d004104210f0c010b2003102c220f450d040b02402003410276220e20044f0d00200341017622052004200520044b1b22044104200441044b1b220441ffffffff03712004464102742105200441027421040240024020030d00200241003602100c010b200241186a4104360200200220033602142002200f3602100b200220042005200241106a107d200241086a280200210420022802004101460d032002280204210f2004410276210e0b2017410374220541786a4103762108200f2104201321030340200420033502043e0200200441046a2104200341086a2103200541786a22050d000b200841016a210c2014450d002013102e0b200c4102742205410275220320036a22042003490d032004417f4c0d030240024020040d004102211b0c010b2004102c221b450d030b02400240024002402004410176221920034f0d0020042003200420034b1b22034104200341044b1b220320036a220820034f41017421030240024020040d00200241003602100c010b200241186a4102360200200220043602142002201b3602100b200220082003200241106a107d200241086a280200210420022802004101460d012002280204211b200441017621190b200f20056a2209200f470d01410021050c020b2004450d050c040b41002105201b2104200f21030340200420032802002208417f200841808004491b3b0100200541016a2105200441026a21042009200341046a2203470d000b0b0240200e450d00200f102e0b0240200b450d00200a102e0b02402005410174410175220420012802082203200320044b1b2205450d00200128020041206a2104201b21030340200420032f01003b0100200341026a2103200441226a21042005417f6a22050d000b0b410021042019450d00201b102e0b02402007450d002006102e0b2000200e36020420002004360200200241206a24000f0b2004450d010b1036000b1038000be80402087f017e230041306b2204240002400240024002402001280208220541ffffffff00712005470d0020054104742206417f4c0d00200128020021070240024020060d00410821080c010b2006102c2208450d040b41002109200441003602182004200836021020042006410476220a36021402400240200a20054f0d002006410376220a2005200a20054b1b220a4104200a41044b1b220a41ffffffff0071200a46410374210b200a410474210a0240024020060d00200441003602000c010b200441086a410836020020042006360204200420083602000b200441206a200a200b2004107d200441286a280200210620042802204101460d0120042004280224220836021020042006410476220a3602140b024020072007200541306c6a460d00200741206a2106200541306c220741506a41306e21092008210503402006290300210c2005200641086a2903003703082005200c370300200641306a2106200541106a2105200741506a22070d000b200941016a21090b200420093602182004200441106a2002200310bc0420042802004101470d02200441086a2802002106200428020421050c030b20060d030b1038000b200441086a280200210b2004280204210902402004410c6a280200220620012802082205200520064b1b2207450d00200128020041206a21062009210503402005290300210c2006200541086a2903003703082006200c370300200541106a2105200641306a21062007417f6a22070d000b0b410021050240200b41ffffffff0071450d002009102e0b0b0240200a450d002008102e0b2000200636020420002005360200200441306a24000f0b1036000bee2e0a057f027e077f027e037f027e057f027e127f057e23004180016b2204240002402001450d0041002105034020002802082206450d0120002802002207200641e0006c6a2108420021094200210a0340024002402007280238220b450d00200b41d8006c210c2007280230220d210602400240024002400240024002400240024002400340200641306a280200220e280208220f41016a41004c0d01200641d8006a2110200e200f3602080240200e41f4006a2d00000d0020102106200c41a87f6a220c450d0c0c010b0b4104102c2211450d09201120063602000240200c41d800470d0042002112420021132011102e0c0c0b200d200b41d8006c6a220f41a87f6a210b4101211441012115024002400240024003402010210602400340200641306a280200220e280208220c41016a41004c0d08200e200c3602080240200e41f4006a2d00000d00200f200641d8006a2206470d010c020b0b024020152014470d00201441016a220e2014490d0f2014410174220c200e200c200e4b1b220e4104200e41044b1b220e41ffffffff0371200e46410274210c200e410274210e0240024020140d00200441003602680c010b20044104360270200420113602682004201441027436026c0b200441d8006a200e200c200441e8006a107d2004280260210e20042802584101460d03200428025c2111200e41027621140b200641d8006a2110201120154102746a2006360200201541016a2115200b2006470d010b0b420021124200211320154102490d0320112015410274220b6a2116200b0d0142002117420021180c020b200e450d0b0c0c0b4200211742002118201121060340427f20182006280200220e41286a2903007c2017200e41206a2903007c2213201754220ead7c2217200e201720185420172018511b220e1b2118427f2013200e1b21172016200641046a2206470d000b0b201541ffffffff00712015470d0920154104742206417f4c0d090240024020060d00410821190c010b2006102c2219450d0b0b0240024002402006410476221a20154f0d002006410376220e2015200e20154b1b220e4104200e41044b1b220e41ffffffff0071200e46410374210c200e410474210e0240024020060d00200441003602680c010b200441083602702004200636026c200420193602680b200441d8006a200e200c200441e8006a107d2004280260210620042802584101460d01200428025c21192006410476211a0b4108211b2011201646221c450d014100211d0c090b20060d0b0c0a0b41002110201921062011210c0340200c28020041306a280200220e280208220f41016a41004c0d04200e200f360208200e29034021132006200e41c8006a29030037030820062013370300201041016a2110200641106a21062016200c41046a220c470d000b4100211d201c0d07201121060240034002402006280200220e290320200e41286a29030084500d00200e280230220e280208220c41016a41004a0d0241bcd9cc004118200441f8006a41c4ffc40041f883c500103e000b200641046a2106200b417c6a220b450d090c000b0b200e200c360208200e41c8006a2903002113200e290340211e4110102c221b450d0a200641046a2106201b201e370300201b20133703084101211d4100210f4101210b0240034020162006460d012006280200210e200641046a220c2106200e290320200e41286a29030084500d00200e2802302206280208220e41016a41004c0d062006200e360208200641c8006a29030021132006290340211e02400240200b201d470d00201d41016a2206201d490d0d201d410174220e2006200e20064b1b22064104200641044b1b220641ffffffff0071200646410374210e2006410474210602400240201d0d00200441003602680c010b200441083602702004201b3602682004201d41047436026c0b200441d8006a2006200e200441e8006a107d2004280260210620042802584101460d01200428025c211b2006410476211d0b201b200b4104746a220620133703082006201e370300200f41106a210f200b41016a210b200c21060c010b0b20060d0b0c0a0b200b450d07200b410474450d0502400240200b4101470d00201b210e0c010b201b41106a2106201b210e0340200e2006200e290300200629030056200e41086a2903002213200641086a290300221e562013201e511b1b210e200641106a2106200f41706a220f0d000b0b2010410474220c450d060240024020104101470d002019210c0c010b201941106a2106200c41706a21102019210c03402006200c200c290300200629030056200c41086a2903002213200641086a290300221e562013201e511b1b210c200641106a2106201041706a22100d000b0b427f4200200e2903002213200c29030022127d221e201e201356200e41086a290300221e200c41086a2903007d2013201254ad7d2213201e562013201e511b22061b221f42002007290300221e20177d22122012201e56200741086a290300221220187d201e201754ad7d221820125620182012511b220e1b7c22172017201f54220c4200201320061b221742002018200e1b7c200cad7c221820175420182017511b22061b2212200254427f201820061b221320035420132003511b450d080240201d41ffffffff0071450d00201b102e0b201a450d002019102e0b201441ffffffff0371450d0b2011102e0c0b0b41bcd9cc004118200441f8006a41c4ffc40041d883c500103e000b41bcd9cc004118200441f8006a41c4ffc40041d883c500103e000b41bcd9cc004118200441f8006a41f09cc50041809dc500103e000b41bcd9cc004118200441f8006a41c4ffc40041f883c500103e000b41e580c5004130419881c500105d000b41a881c500413241dc81c500105d000b200741086a2903002113200729030021120b024002400240024002400240201c0d002011210e0340200e28020028023022062802080d022006417f3602082006420020062903402218200e280200220c290320221e7d22172017201856200641c8006a22102903002217200c41286a2903007d2018201e54ad7d221820175620182017511b220c1b370340201042002018200c1b370300200e280200220c4200370320200c41286a42003703002006200628020841016a3602082016200e41046a220e470d000b0b0240201541144b0d00201541014d0d052015417e6a21064102210e201120154102746a41786a210c034020152006490d03200c200e10c104200c417c6a210c200e41016a210e2006417f6a2206417f470d000c060b0b2015410176220641ffffffff03712006470d0520064102742220417f4c0d052020102c2221450d062011417c6a2122201141746a2123410021244104212541002126201521270340024002402027220b417f6a22270d004101210c410021270c010b024002400240024002400240024002400240024002400240201120274102746a28020041306a2802002206280208220e41016a41004c0d002006200e3602082011200b417e6a220d4102746a28020041306a280200220e280208220c41016a41004c0d01200641c8006a290300211820062903402117200e200c3602082017200e290340542018200e41c8006a29030022175420182017511b0d042023200b4102746a2106410021274100211003400240200d2010470d00200b210c0c0e0b200641046a28020041306a280200220e280208220c41016a41004c0d03200e200c360208200628020041306a280200220c280208220f41016a41004c0d04200e41c8006a2903002118200e2903402117200c200f3602082006417c6a2106201041016a21102017200c2903405a2018200c41c8006a29030022175a20182017511b0d000b201041016a210c2010417f73200b6a21270c050b41bcd9cc004118200441f8006a41c4f8c90041ccf9c900103e000b41bcd9cc004118200441f8006a41c4f8c90041ccf9c900103e000b41bcd9cc004118200441f8006a41c4f8c90041ccf9c900103e000b41bcd9cc004118200441f8006a41c4f8c90041ccf9c900103e000b2023200b410274220f6a210602400340024020274101470d00410021270c020b200641046a28020041306a280200220e280208220c41016a41004c0d03200e200c360208200628020041306a280200220c280208221041016a41004c0d04200e41c8006a2903002118200e2903402117200c20103602082006417c6a21062027417f6a21272017200c290340542018200c41c8006a29030022175420182017511b0d000b0b200b2027490d03200b20154b0d04200b20276b220c4101762210450d00201120274102746a21062022200f6a210e03402006280200210f2006200e280200360200200e200f360200200641046a2106200e417c6a210e2010417f6a22100d000b0b2027450d06200c41094b0d06200b20154b0d04200b20276b210c2027417f6a2106202220274102746a210e0340200b2006490d0b200e200c41016a220c10c1042006417f6a221020064f0d06200e417c6a210e20102106200c410a490d000c060b0b41bcd9cc004118200441f8006a41c4f8c90041ccf9c900103e000b41bcd9cc004118200441f8006a41c4f8c90041ccf9c900103e000b2027200b41e4d1cc001057000b200b201541e4d1cc00104d000b200b2027417f6a2206490d05200b201541f4d1cc00104d000b201041016a21270b0240024002400240024020262024460d00202621060c010b202441016a22062024490d0a2024410174220e2006200e20064b1b22064104200641044b1b220641ffffffff0171200646410274210e200641037421060240024020240d00200441003602680c010b20044104360270200420253602682004202441037436026c0b200441d8006a2006200e200441e8006a107d2004280260210e20042802584101460d01200428025c212520242106200e41037621240b202520064103746a2206200c36020420062027360200202641016a22282126202841024f0d010c020b200e0d090c080b024002400240024002400240024003400240024002400240202520282226417f6a22284103746a2206280200450d00202641037420256a220f41746a28020022102006280204220e4d0d00202641024d0d0c20252026417d6a22064103746a280204220c200e20106a4d0d01202641034d0d0c200f41646a280200200c20106a4b0d0c0c010b20264103490d012006280204210e20252026417d6a22064103746a280204210c0b200c200e490d010b2026417e6a21060b02402026200641016a22294d0d00202620064d0d02202520064103746a222a280204222b202a2802006a2206202520294103746a222c280200222d490d03200620154b0d042011202d4102746a222e202c280204222f410274220e6a210c2006410274210f024002402006202d6b220b202f6b2206202f490d002021202e200e10e9082206200e6a211002400240202f4101480d00200b202f4a0d010b202e210e200621060c020b2011200f6a213020062106202e210e0340200c28020041306a280200220f280208220b41016a41004c0d08200f200b360208200628020041306a280200220b280208220d41016a41004c0d09200f41c8006a2903002118200f2903402117200b200d360208200e200c20062017200b290340542018200b41c8006a29030022175420182017511b220f1b2802003602002006200641046a200f1b2106200e41046a210e200c41046a200c200f1b220c20304f0d02201020064b0d000c020b0b2021200c2006410274220e10e9082230200e6a211002400240202f4101480d00200641014e0d010b200c210e203021060c010b2022200f6a210f200c210e03402010417c6a220b28020041306a2802002206280208220c41016a41004c0d092006200c360208200e417c6a220d28020041306a280200220c280208223141016a41004c0d0a200641c8006a290300211820062903402117200c2031360208200f200d200b2017200c290340542018200c41c8006a29030022175420182017511b22061b2802003602002010200b20061b21100240202e200d200e20061b220e490d00203021060c020b200f417c6a210f2030210620302010490d000b0b200e2006201020066b417c7110e9081a202a41046a202b202f6a360200202a202d360200202c202c41086a20262029417f736a41037410ea081a41012126202841014d0d090c010b0b202920264184d2cc00103c000b200620264194d2cc00103c000b202d200641a4d2cc001057000b2006201541a4d2cc00104d000b41bcd9cc004118200441f8006a41c4f8c90041ccf9c900103e000b41bcd9cc004118200441f8006a41c4f8c90041ccf9c900103e000b41bcd9cc004118200441f8006a41c4f8c90041ccf9c900103e000b41bcd9cc004118200441f8006a41c4f8c90041ccf9c900103e000b2027450d040c000b0b4194dacc004110200441f8006a41e4ffc40041ec81c500103e000b2006201541c4d1cc001056000b2006200b41f4d1cc001057000b0240202441ffffffff0171450d002025102e0b2020450d002021102e0b2015417f6a210f02400240024002400240024002400240201c450d0042002118420021170c010b420021184100210e420021172011210c0340200c2802002802302206280208221041016a41004c0d0220062010360208200441386a200641c8006a29030022324200200ead2233420010e808200441c8006a2006290340223442002033420010e80802404200427f20042903482004290340420052200441c8006a41086a290300221e20042903387c221f201e547222061b221e20187d22352035201e56427f201f20061b221f20177d201e201854ad7d221e201f56201e201f511b22061b2007290300584200201e20061b221e200741086a290300221f58201e201f511b0d0042002033427f7c221e201e203356200e45200e1b1ba7210f0c020b200e41016a210e427f201720327c201820347c221e2018542206ad7c22182006201820175420182017511b22061b2117427f201e20061b21182016200c41046a220c470d000b0b2015200f4d0d012011200f4102746a2802002802302206280208220e41016a41004c0d022006200e360208200441186a200641c8006a29030022354200200f41016a220fad2233420010e808200441286a2006290340223242002033420010e8084200427f200741086a290300221e20177c2007290300221720187c221f2017542206ad7c221820062018201e542018201e511b22061b2218427f200441286a41086a290300221720042903187c221e2004290320420052201e20175472220e1b7d427f201f20061b2217427f2004290328200e1b221f54ad7d221e2017201f7d221f201756201e201856201e2018511b22061b21344200201f20061b21362015410274210c201121100340200c450d0620102802002206450d062006280230220e280208220b41016a41004c0d04200e200b360208200441086a203620342033420010e70820064200427f2004290308221820327c22172017201854220b200441086a41086a290300221820357c200bad7c221720185420172018511b220b1b2218200e290340221e7d221f201f201856427f2017200b1b2217200e41c8006a2903007d2018201e54ad7d221820175620182017511b220e1b2217370320200641286a42002018200e1b221e370300200628023022062802080d05201041046a2110200641003602082006427f2006290340221820177c22172017201854220e200641c8006a220b2903002218201e7c200ead7c221720185420172018511b220e1b370340200b427f2017200e1b370300200c417c6a210c200f417f6a220f0d000c060b0b41bcd9cc004118200441f8006a41c4ffc40041fc81c500103e000b418c82c500418a01419883c500105d000b41bcd9cc004118200441f8006a41c4ffc40041a883c500103e000b41bcd9cc004118200441f8006a41c4ffc40041b883c500103e000b4194dacc004110200441f8006a41e4ffc40041c883c500103e000b0240201441ffffffff0371450d002011102e0b2004200710bb040240201d41ffffffff0071450d00201b102e0b201a450d032019102e0c030b1038000b1036000b42002112420021130b2013200a20122009562013200a562013200a511b22061b210a2012200920061b2109200741e0006a22072008470d000b200541016a220520014f0d012009200258200a200358200a2003511b450d000b0b20044180016a24000bf00303047f027e037f230041106b2202240002400240024002400240024020014102490d00200028020441306a2802002203280208220441016a41004c0d0220032004360208200028020041306a2802002204280208220541016a41004c0d03200341c8006a29030021062003290340210720042005360208200720042903405a2006200441c8006a29030022075a20062007511b0d00200028020021082000200028020436020002400240200141034f0d00200041046a21040c010b200041046a21052001417f6a21090340200541046a220428020041306a2802002200280208220341016a41004c0d0620002003360208200841306a2802002203280208220a41016a41004c0d07200041c8006a2903002106200029034021072003200a3602080240200720032903405a2006200341c8006a29030022075a20062007511b450d00200521040c020b2009450d0320052004280200360200200421052009417f6a22094101470d000b0b200420083602000b200241106a24000f0b2001200141d4d1cc00103c000b41bcd9cc004118200241086a41c4f8c90041ccf9c900103e000b41bcd9cc004118200241086a41c4f8c90041ccf9c900103e000b41bcd9cc004118200241086a41c4f8c90041ccf9c900103e000b41bcd9cc004118200241086a41c4f8c90041ccf9c900103e000bf70302037f017e230041106b2202240020004100360208200042013702000240024020012d00004101460d00200241003a00002000200241011074200141046a28020021032001410c6a2802002204200010760240200441306c2204450d00200320046a21040340200220032802003602002000200241041074200341086a200010b204200341306a22032004470d000b0b200129031021052002200141186a290300370308200220053703002000200241101074200141206a29030021052002200141286a2903003703082002200537030020002002411010742002200141c0006a2802003602002000200241041074200129033021052002200141386a2903003703082002200537030020002002411010740c010b200241013a00002000200241011074200141286a29030021052002200141306a2903003703082002200537030020002002411010742000200141016a41201074200141216a2d000020001073200141386a29030021052002200141c0006a290300370308200220053703002000200241101074200141c8006a29030021052002200141d0006a2903003703082002200537030020002002411010742002200141e8006a2802003602002000200241041074200141d8006a29030021052002200141e0006a2903003703082002200537030020002002411010740b200241106a24000bb20b04057f017e037f017e230041c0046b2203240020034180026a41086a200241086a2802003602002003200229020037038002200341086a20034180026a10c404200341186a20032802082003280210109d03200341286a41206a2204200141206a290200370300200341286a41186a2205200141186a290200370300200341286a41106a2206200141106a290200370300200341286a41086a2207200141086a290200370300200328021821022003410036021820032001290200370328024002400240024020024101470d00200329021c2108200341e0006a41206a22022004290300370300200341e0006a41186a22092005290300370300200341e0006a41106a22052006290300370300200341e0006a41086a220a20072903003703002003200329032837036020034188016a2008a7220b10a70420034180026a2003280288012206200328029001220410c504200329028402210c2003280280022101200341a0016a41206a2002290300370300200341a0016a41186a2009290300370300200341a0016a41106a2005290300370300200341a0016a41086a200a290300370300200320032903603703a0012001410820011b2105024002400240200c420020011b220c422088a722022008422088a722074d0d0020034180026a41206a200341a0016a41206a29030037030020034180026a41186a200341a0016a41186a29030037030020034180026a41106a200341a0016a41106a29030037030020034180026a41086a200341a0016a41086a290300370300200320032903a00122083703800220032005200741f8026c6a22013602a80202402008a741ff01714103460d0020012802bc024102460d0020034180026a2005200741f8026c6a41c8026a10c6040d020b200141bc026a2104024020012802bc024102460d0002402005200741f8026c6a22062802b0022209450d00200641b4026a280200450d002009102e0b2001108b020b200120034180026a41bc0210e9081a200441023602002005200741f8026c6a220141f0026a200341f8016a290300370300200141e8026a200341f0016a290300370300200141e0026a200341e8016a290300370300200141d8026a200341e0016a290300370300200141d0026a200341d8016a290300370300200141c8026a200341d0016a290300370300200120032903c8013703c002200328028801210620032802900121040b20032005360280022003200c370284022006200420034180026a10c704200ca7210902402002450d00200241f8026c21022005210103400240200141bc026a2802004102460d000240200141b0026a2802002204450d00200141b4026a280200450d002004102e0b20011096010b200141f8026a2101200241887d6a22020d000b0b02402009450d00200941f8026c450d002005102e0b20032003290095013703c80120032003419c016a2800003600cf0141062101410121020c010b20032003290095013703c80120032003419c016a2800003600cf01200241f8026c21022005210103400240200141bc026a2802004102460d000240200141b0026a2802002204450d00200141b4026a280200450d002004102e0b20011096010b200141f8026a2101200241887d6a22020d000b4102210141002102200ca72204450d00200441f8026c450d002005102e0b0240200328028c01450d002006102e0b200320032903c801370350200320032800cf01360057024020020d00200020013a000020002003290350370001200041086a20032800573600000c020b2003418c026a200736020020034188026a200b3602002003410136028402200341013a00800220034180026a10fe01200041063a00000c020b2000410210c80420002d000021010b200141ff01714106470d010b2003280210210120032802082102024020032802184101460d002002200110ff010c010b20022001200341186a410472109e030b0240200328020c450d002003280208102e0b200341c0046a24000bd00101057f230041306b22022400200241dffcc6004109108102200241106a41e5b0c4004106108102200241206a20012802002203200128020810a201024002402002280228220441206a2205417f4c0d000240024020050d00410121060c010b2005102c2206450d020b20004100360208200020053602042000200636020020002002411010742000200241106a411010742000200228022022052004107402402002280224450d002005102e0b0240200141046a280200450d002003102e0b200241306a24000f0b1038000b1036000bb91f09047f017e0c7f027e047f037e167f017e087f230041a00e6b220324002003200236021c20032001360218200341206a2001200210ed020240024002400240200328022022040d00200041003602000c010b200328022421052003200341286a28020036023420032004360230200341106a200341306a10ab010240024020032802100d000240024020032802142206200328023441f8026e2201200120064b1bad42f8027e2207422088a70d002007a72201417f4c0d000240024020010d00410821080c010b2001102c2208450d060b200141f8026ead2107024002402006450d00200341870b6a2109200341c80d6a41126a210a200341f50d6a210b200341e00d6a410372210c200341e00d6a41126a210d200341900e6a41086a210e200341f80a6a410472220f41076a211003400240024020032802342201450d00200328023022112d0000211220032001417f6a22133602342003201141016a360230410321020240024020120e020001030b410221020c020b024002400240024002402013450d0020112d0001210220032001417e6a22013602342003201141026a22123602304100211102400240024020020e020100030b200341086a200341306a10ab0120032802080d0220032802342201200328020c2202490d022002417f4c0d0c0240024020020d00410121110c010b200210322211450d12200328023421010b20012002490d0120112003280230200210e9081a200328023422012002490d122002ad221442208620148421152003200120026b22013602342003200328023020026a22123602300b2015a7211302402001450d0020122d0000211620032001417f6a3602342003201241016a360230200341f80a6a200341306a10980120032802f80a411c460d00200341c8086a200341f80a6a41b00210e9081a024020032802342201450d00200328023022122d0000211720032001417f6a22183602342003201241016a2219360230410021020240024020170e020100020b20184104490d01201235000121142003201241056a36023020032001417b6a220236023420024104490d012012350005211a2003200141776a22183602342003201241096a2219360230201a422086201484211b410121020b2018450d0020192d0000210120032018417f6a22123602342003201941016a360230024002400240024020010e110004040304040404040404040404040102040b2012450d0320192d0001210120032018417e6a3602342003201941026a3602304100211741002118024020010e03090008040b200341f80a6a200341306a10930120032d00f80a4101460d03200341f80d6a41086a200941086a2900002214370300200341f80d6a41106a200941106a2f000022013b01002003200f290000221a3703900e20032009290000221c3703f80d200320102800003600970e20032d00fb0a211d20032f00f90a211e20032d00920e211f20032800930e212020032800970e2121200341e00d6a41106a20013b0100200341e00d6a41086a20143703002003201c3703e00d201aa72122410121180c080b2012450d0220192d0001210120032018417e6a2217360234410221122003201941026a36023002400240024020010e03000102050b20174104490d04201928000221172003201941066a36023020032018417a6a220136023420014104490d04200341e00d6a41086a200341f80a6a41086a290200370300200341e00d6a41106a200341f80a6a41106a290200370300200320032902f80a3703e00d201928000621232003201841766a36023420032019410a6a36023041002112201721240c010b200341f80a6a200341306a10930120032d00f80a4101460d03200341f80d6a41086a2201200941086a290000370300200341f80d6a41106a2212200941106a2f00003b01002003200f29000022143703900e200320092900003703f80d200320102800003600970e20032d00fb0a212520032f00f90a212620032802940e21232003200e41026a2d00003a00e20d2003200e2f01003b01e00d200c20032903f80d370000200c41086a2001290300370000200c41106a20122f01003b0000200b20032f009d0e3b0000200b41026a2003419d0e6a41026a2d00003a00002014a72124410121120b200341c80d6a41106a200341e00d6a41106a2903002214370300200341c80d6a41086a200341e00d6a41086a290300221a370300200341b00d6a41086a201a370300200341b00d6a41106a20143d0100200320032903e00d22143703c80d200341a80d6a41046a200a41046a2f01003b0100200320143703b00d2003200a2801003602a80d410121170c080b2012450d0120192d0001210120032018417e6a2227360234410221172003201941026a3602304102211202400240024020010e03000102040b20274104490d03201928000221272003201941066a36023020032018417a6a220136023420014104490d03200341e00d6a41086a200341f80a6a41086a290200370300200341e00d6a41106a200341f80a6a41106a290200370300200320032902f80a3703e00d201928000621232003201841766a36023420032019410a6a36023041002112202721240c010b200341f80a6a200341306a10930120032d00f80a4101460d02200341f80d6a41086a2201200941086a290000370300200341f80d6a41106a2212200941106a2f00003b01002003200f29000022143703900e200320092900003703f80d200320102800003600970e20032d00fb0a212520032f00f90a212620032802940e21232003200e41026a2d00003a00e20d2003200e2f01003b01e00d200c20032903f80d370000200c41086a2001290300370000200c41106a20122f01003b0000200b20032f009d0e3b0000200b41026a2003419d0e6a41026a2d00003a00002014a72124410121120b200341b00d6a41106a200341e00d6a41106a2f01003b0100200341b00d6a41086a200341e00d6a41086a290300370300200341a80d6a41046a200d41046a2f01003b0100200320032903e00d3703b00d2003200d2801003602a80d0c070b2012450d0020032018417e6a3602342003201941026a3602300b200341c8086a108b020b2011450d012013450d010b2011102e0b41022102410121010c030b410221180b200341b00d6a41106a200341e00d6a41106a2f01003b0100200341b00d6a41086a200341e00d6a41086a290300370300200341a80d6a41046a200341c80d6a41046a2f01003b0100200320032903e00d3703b00d200320032801c80d3602a80d20222126201d21122020212420212123201f21250b2015422088a72128200341e00d6a41106a200341b00d6a41106a2f01003b0100200341e00d6a41086a200341b00d6a41086a290300370300200341f80d6a41046a200341a80d6a41046a2f01003b0100200320032903b00d3703e00d200320032802a80d3602f80d200341f80a6a200341c8086a41b00210e9081a200320032800c1083602c80d2003200341c1086a41036a2800003600cb0d41002101201821292017212a201b211c2012212b2013212c2011212d2016212e0b20034190066a200341f80a6a41b00210e9081a200341f8056a41106a2211200341e00d6a41106a2f01003b0100200341f8056a41086a2212200341e00d6a41086a290300370300200341f0056a41046a2213200341f80d6a41046a2f01003b0100200320032903e00d3703f805200320032802f80d3602f005200320032802c80d3602e805200320032800cb0d3600eb0520010d00200341f80a6a20034190066a41b00210e9081a200341c8086a41106a20112f01003b0100200341c8086a41086a2012290300370300200341c80d6a41046a20132f01003b0100200320032903f8053703c808200320032802f0053602c80d200320032802e8053602e00d200320032800eb053600e30d201e212f2026213020292131202a2132201c2133202b2134202421352023213620282137202c2138202d2139202e213a2025213b0c010b410321020b200341b8036a200341f80a6a41b00210e9081a200341a0036a41106a2201200341c8086a41106a2f01003b0100200341a0036a41086a2211200341c8086a41086a29030037030020034198036a41046a2212200341c80d6a41046a2f01003b0100200320032903c8083703a003200320032802c80d36029803200320032802e00d36029003200320032800e30d3600930320024103460d04200341e0006a200341b8036a41b00210e9081a200341c8006a41106a221320012f01003b0100200341c8006a41086a22162011290300370300200341c0006a41046a221120122f01003b0100200320032903a00337034820032003280298033602402003200328029003360238200320032800930336003b02402007422088a722012007a7470d00200141016a22122001490d0420014101742218201220122018491b22124104201241044b1bad42f8027e2214422088a74541037421122014a721180240024020010d00200341003602f80a0c010b200341083602800b200320083602f80a2003200141f8026c3602fc0a0b200341c8086a20182012200341f80a6a107d20032802d008211220032802c8084101460d0320032802cc082108200742808080807083201241f8026ead8421070b2008200141f8026c6a200341e0006a41b00210e908220141d4026a2036360000200141d0026a2035360000200141cf026a203b3a0000200141cd026a20303b0000200141cc026a20343a0000200141ca026a202f3b0000200141c9026a20313a0000200141c8026a20323a0000200120333703c002200120023602bc02200120373602b802200120383602b402200120393602b00220132f010021022016290300211420112f010021112003290348211a20032802402112200141f0026a203a3a0000200141ea026a2012360000200141ee026a20113b0000200141d8026a201a370000200141e0026a2014370000200141e8026a20023b0000200141f1026a2003280238360000200141f4026a200328003b36000020074280808080107c21072006417f6a22060d000b0b2008450d0320002007370204200020083602000c040b20120d050b1038000b02402007422088a72201450d00200141f8026c21022008210103400240200141bc026a2802004102460d000240200141b0026a2802002206450d00200141b4026a280200450d002006102e0b20011096010b200141f8026a2101200241887d6a22020d000b0b2007a72201450d00200141f8026c450d002008102e0b200341003602d008200342013703c8082003410a360294062003200341186a360290062003200341c8086a3602b8032003418c0b6a4101360200200342013702fc0a200341909dc5003602f80a200320034190066a3602880b200341b8036a419cebc000200341f80a6a103d1a20032802c80820032802d00810ef02024020032802cc08450d0020032802c808102e0b200041003602000b2005450d002004102e0b200341a00e6a24000f0b1036000b2002200141b8b2c0001056000ba50201027f41012102024020002d0000220320012d0000470d0002400240024020030e03000102000b4101210220002d0001220320012d0001470d024100210220034101470d02200041026a200141026a412010ec084100470f0b200041046a2d00002203200141046a2d0000470d01410021020240024020030e03010003010b200041056a200141056a412010ec084100470f0b41012102200041086a280200200141086a280200470d012000410c6a2802002001410c6a280200470f0b200041046a2d00002203200141046a2d0000470d00410021020240024020030e03010002010b200041056a200141056a412010ec084100470f0b41012102200041086a280200200141086a280200470d002000410c6a2802002001410c6a2802004721020b20020be80101047f230041106b22032400024002402002280208220441f8026c4104722205417f4c0d00200228020021022005102c2206450d012003410036020820032005360204200320063602002004200310760240200441f8026c2204450d00034002400240200241bc026a2802004102470d00200341003a000f20032003410f6a410110740c010b200341013a000f20032003410f6a410110742002200310ab040b200241f8026a2102200441887d6a22040d000b0b200020012003280200200328020810b20102402003280204450d002003280200102e0b200341106a24000f0b1038000b1036000bdc0101047f230041c0006b2202240041a3e7c4002103411221044103210502400240024002400240200141ff01710e050001020304000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602242002418883ca003602202002200241206a360218200241086a41e4e6c4001044000b4193e7c400210341102104410021050c020b418be7c400210341082104410121050c010b41f4e6c400210341172104410221050b20004183023b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000bb80701057f230041b0036b220a2400200a41206a200110a904200a280220220b200a280228108f02210c0240200a280224450d00200b102e0b02400240024002400240200c0d00200a41386a220c4200370300200a41306a220b4200370300200a41206a41086a4200370300200a4200370320200a41206a41d9fcc6004106108102200a4198036a4180f4cb004106108102200c200a4198036a41086a290000370300200b200a29009803370300200a41186a200a41206a4120108e024100210d0240417f417f200a28021c4100200a2802181b220c20036a220b200b200c491b220b41016a220e200e200b491b200320021b2203200c4d0d00024020044101470d002005410047200641014b71210d2006417f6a21020b2001280208220c417f4c0d042001280200210b02400240200c0d00410121040c010b200c102c2204450d060b2004200b200c10e9082104200a41206a200941b00210e9081a200a41e4026a2002360200200a41e0026a2005360200200a41d8026a200c360200200a41d4026a200c360200200a41f0026a200841086a290200370300200a41f8026a200841106a290200370300200a4180036a200841186a290200370300200a4188036a200841206a290200370300200a200d3602dc02200a20043602d002200a20073a009003200a20082902003703e8022003200a41206a10aa04200a41206a200310a704200a280228210c200a280220210841002109200a41ac036a41003a0000200a41003602a803200a41106a2008200c200a41a8036a4105410010ca0402400240200a280210450d00200a200a2802142209410520094105491b36029c03200a200a41a8036a36029803200a41086a200a4198036a10ab01200a28020c417f6a210c200a2802084521090c010b0b0240200a280224450d002008102e0b200a200c410020091b220836029c03200a200336029803200a41206a200110a904200a2802202209200a280228200a4198036a109e030240200a280224450d002009102e0b200a412c6a2008360200200a41206a41086a2003360200200a4100360224200a41013a0020200a41206a10fe01200041086a20083602002000200336020420004100360200200141046a280200450d03200b102e0c030b20004281808080b0a08001370200200041086a41f4e6c400ad4280808080f002843702000c010b200041003a000620004183023b0104200041013602002000410c6a4110360200200041086a4193e7c4003602000b2009108b02200141046a280200450d002001280200102e0b200a41b0036a24000f0b1038000b1036000b940102017f017e230041106b2206240002402002ad4220862001ad842004ad4220862003ad84200510272207422088a72203450d0041002105024002402007a722022d00000e020100020b2003417f6a4104490d0120022800012101410121050b2002102e2000200136020420002005360200200641106a24000f0b41cae0cc00412e200641086a41f8e0cc004188e1cc00103e000b8f0101027f230041e0046b22012400200141b0026a200010980120012802b0022102200141046a200141b0026a41047241ac0210e9081a0240024002402002411c460d00200141b0026a200141046a41ac0210e9081a41b002102c2200450d0220002002360200200041046a200141b0026a41ac0210e9081a0c010b410021000b200141e0046a240020000f0b1036000bb00101037f230041e0046b220124002000200028020441016a22023602044100210302400240200220002802084b0d00200141b0026a200010950120012802b0022102200141046a200141b0026a41047241ac0210e9081a2002411c460d00200141b0026a200141046a41ac0210e9081a41b002102c2203450d0120032002360200200341046a200141b0026a41ac0210e9081a20002000280204417f6a3602040b200141e0046a240020030f0b1036000b5a01017f024020002802002201450d0020012001280200417f6a360200200028020022012802000d002001410c6a10cd04200028020041046a22012001280200417f6a3602002000280200220041046a2802000d002000102e0b0b950102027f027e230041106b2201240002404101102c2202450d00200142013702042001200236020002400240200028020022020d00200141003a000f20012001410f6a410110740c010b200141013a000f20012001410f6a41011074200041086a28020022002001107620012002200010740b2001350208210320013502002104200141106a240020042003422086840f0b1036000b810302037f027e230041206b22012400200141003602102001420137030820012000290300370318200141086a200141186a4108107420012000290308370318200141086a200141186a4108107420012000290310370318200141086a200141186a4108107420002802302102200041386a2802002203200141086a10760240200341286c2203450d00200220036a21030340200141086a2002412010742001200241206a290300370318200141086a200141186a41081074200241286a22022003470d000b0b200141086a2000413c6a4120107420012000290318370318200141086a200141186a410810742001200041206a290300370318200141086a200141186a410810740240024002400240200041286a2d00000e03000102030b200141003a0018200141086a200141186a410110740c020b200141013a0018200141086a200141186a410110740c010b200141023a0018200141086a200141186a410110740b2001350210210420013502082105200141206a240020052004422086840bce0202057f017e230041b0016b22022400200241003a006820012802002103200128020421044100210502400340200241003a0028200241286a20032004410047220610e9081a024020040d00200241003a00280b20042006490d01200241c8006a20056a20022d00283a00002001200420066b22043602042001200320066a22033602002002200541016a22063a00682006210520064120470d000b200241286a41186a200241c8006a41186a2903002207370300200241086a41086a2204200241c8006a41086a290300370300200241086a41106a2206200241c8006a41106a290300370300200241086a41186a2203200737030020022002290348370308200041196a2003290300370000200041116a2006290300370000200041096a200429030037000020002002290308370001200041003a0000200241b0016a24000f0b2006200441cce9cc001056000bbb010002400240024002402002450d0020014100480d01024002400240200328020022020d0020010d01410121020c020b0240200328020422030d0020010d01410121020c020b200220032001103022020d010c040b2001102c2202450d030b20002002360204410021020c030b2000200136020420004101360200200041086a41003602000f0b20004101360200200041086a41003602000f0b2000200136020441012101410121020b20002002360200200041086a20013602000b8c0202017f067e23004190016b220124002000290300210220004200370300024020024201520d00200041286a2903002102200041186a29030021032000290310210420002903082105200041206a2903002106200141c8006a200041306a2903002207370300200141106a41306a2002370300200141296a2003370000200141216a2004370000200141196a2005370000200141316a2006370000200141186a41013a0000200141033a0010200141106a10fe012001200737031820012002370310024020022007844200520d002001200141106a36020c2001410c6a10cc020c010b20012007370318200120023703102001200141106a36020c2001410c6a10cc020b20014190016a24000b130020004104360204200041b884c5003602000b130020004103360204200041ec86c5003602000ba56d031a7f2d7e037f230022032104200341a0056b41607122032400024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0700010203040506000b200341ac016a41013602002003420137029c012003419cc3cb0036029801200341043602a40420034194c3cb003602a0042003200341a0046a3602a80120034198016a41ecb0c4001044000b200141146a2802002105200141046a280200210620012d0001210741022108200341206a41026a200241246a2d00003a00002003200241226a2f01003b0120200141106a28020021092001410c6a280200210a200141086a280200210b200241206a2f0100210c2002411c6a280200210d200241186a280200210e200241146a280200210f200241106a28020021102002410c6a2802002111200241086a2802002112200241066a2f00002113200241056a2d00002114200241046a2d00002115200241026a2f010021162002280228210120022d0001211702400240024002400240024020022d000022180e03000102000b20174521194101211a201521080c040b410221080240024020150e03000104000b410021080c030b20034180016a41026a200341206a41026a2d00003a0000200320032f01203b0180010c010b0240024020150e03000103000b410021080c020b20034180016a41026a200341206a41026a2d00003a0000200320032f01203b0180010b410121080b4100211a0b2001280200221b41016a221c41014d0d052001201c36020020012102024002400240201a450d002001201b36020020194101710d014110102c221c450d09201c41f8f7c60036020c201c4101360208201c4281808080103702004110102c2202450d0920024190f8c60036020c200241013602082002428180808010370200201c201c280200417f6a2208360200024020080d00201c280208201c28020c2802001103000240201c28020c280204450d00201c280208102e0b201c41046a22082008280200417f6a220836020020080d00201c102e0b2002280200211c0b2002201c417f6a221c3602000240201c0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a221c201c280200417f6a221c360200201c0d002002102e0b2005108b022005102e20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b410221020c010b41022102200341386a41026a200341206a41026a2d00003a0000200320032f01203b0138024002400240024020180e03000102000b4102210202400240024020170e03000102000b410021020c010b41012102201521080b200341c0046a200c3b0100200341bc046a200d360200200341b8046a200e360200200341b4046a200f360200200341b0046a2010360200200341ac046a2011360200200341a8046a2012360200200320133b01a604200320143a00a504200320083a00a404200320163b01a204200320023a00a104200341003a00a0040c020b4102210202400240024020150e03000102000b410021020c010b20034180016a41026a200341386a41026a2d00003a0000200320032f01383b018001410121020b200341c0046a200c3b0100200341bc046a200d360200200341b8046a200e360200200341b4046a200f360200200341b0046a2010360200200341ac046a2011360200200341a8046a2012360200200341c2046a200328018001360100200341c6046a20034184016a2f01003b0100200320133b01a604200320143a00a504200320023a00a404200341013a00a0040c010b02400240024020150e03000102000b410021020c010b20034180016a41026a200341386a41026a2d00003a0000200320032f01383b018001410121020b200341c0046a200c3b0100200341bc046a200d360200200341b8046a200e360200200341b4046a200f360200200341b0046a2010360200200341ac046a2011360200200341a8046a2012360200200341c2046a200328018001360100200341c6046a20034184016a2f01003b0100200320133b01a604200320143a00a504200320023a00a404200341023a00a0040b20034198016a200541b00210e9081a20034180016a41002006200b200a20092007200341a0046a20034198016a10d604200341f0006a41026a221c20032d0087013a0000200320032f0085013b017002402003280280014101460d0020012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b2005102e0c120b20034188016a290300211d20032d0084012102200341086a41026a201c2d00003a0000200320032f01703b010820012001280200417f6a221c3602000240201c0d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a221c201c280200417f6a221c360200201c0d002001102e0b2005102e200241ff01714106460d110b20034198046a41026a200341086a41026a2d000022013a0000200320032f010822053b019804200041206a20023a0000200041186a41003a000020004200370308200020053b0021200041236a20013a00002000201d37002420004201370300200424000f0b200141086a280200211b200141046a280200210c4102211c200341106a41026a200241246a2d00003a00002003200241226a2f01003b0110200241206a2f0100210e2002411c6a280200210f200241186a2802002110200241146a2802002111200241106a28020021122002410c6a2802002113200241086a2802002114200241066a2f00002106200241056a2d00002107200241046a2d00002108200241026a2f010021092002280228210520022d0001211702400240024002400240024020022d0000220d0e03000102000b201745211a410121152008211c0c040b4102211c0240024020080e03000104000b4100211c0c030b20034180016a41026a200341106a41026a2d00003a0000200320032f01103b0180010c010b0240024020080e03000103000b4100211c0c020b20034180016a41026a200341106a41026a2d00003a0000200320032f01103b0180010b4101211c0b410021150b2005280200221941016a220141014d0d042005200136020020052102024002402015450d0020052019360200201a4101710d014110102c2203450d07200341f8f7c60036020c2003410136020820034281808080103702004110102c2202450d0720024190f8c60036020c20024101360208200242818080801037020020032003280200417f6a2201360200024020010d002003280208200328020c2802001103000240200328020c280204450d002003280208102e0b200341046a22012001280200417f6a220136020020010d002003102e0b200228020021010b20022001417f6a2203360200024020030d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22032003280200417f6a220336020020030d002002102e0b20052005280200417f6a22033602004102210820030d0e2005280208200528020c2802001103000240200528020c280204450d002005280208102e0b200541046a22032003280200417f6a220336020020030d0e2005102e0c0f0b41022102200341146a41026a200341106a41026a2d00003a0000200320032f01103b011402400240024002400240200d0e03000102000b4100210a4102210d0240024020170e03000105000b4100210d4100210a0c040b4101210d2008211c0c030b4102211c02400240024020080e03000102000b4100211c0c010b20034180016a41026a200341146a41026a2d00003a0000200320032f01143b0180014101211c0b200341186a41046a20034180016a41046a2f01003b010020032003280180013602184101210a0c010b02400240024020080e03000102000b410021020c010b20034180016a41026a200341146a41026a2d00003a0000200320032f01143b018001410121020b200341186a41046a20034180016a41046a2f01003b010020032003280180013602184102210a2002211c0b0b200341e8006a41046a2201200341186a41046a2f01003b010020032003280218360268200341f0006a200c10a70420034198016a2003280270221a2003280278221910c504200329029c01211d2003280298012102200341dc036a4102360200200341003602980120034198046a41046a220820012f01003b010020032003280268360298042002410820021b21150240024002400240201b201d420020021b221d422088a72201490d0020034180016a41086a20034188046a29030037030020034180016a41106a20034190046a290300370300200320034180046a29030037038001200341f8036a290300211e200341f0036a290300211f200341e8036a2903002120200341e0036a2903002121200341d8036a2903002122200341d0036a2903002123200341c8036a2903002124200341c0036a2903002125200341b8036a2903002126200341b0036a2903002127200341a8036a2903002128200341a0036a290300212920034198036a290300212a20034190036a290300212b20034188036a290300212c20034180036a290300212d200341f8026a290300212e200341f0026a290300212f200341e8026a2903002130200341e0026a2903002131200341d8026a2903002132200341d0026a2903002133200341c8026a2903002134200341c0026a2903002135200341b8026a2903002136200341b0026a2903002137200341a8026a2903002138200341a0026a290300213920034198026a290300213a20034190026a290300213b20034188026a290300213c20034180026a290300213d200341f8016a290300213e200341f0016a290300213f200341e8016a2903002140200341e0016a2903002141200341d8016a2903002142200341d0016a2903002143200341c8016a2903002144200341c0016a2903002145200341b8016a2903002146200341b0016a290300214720034198016a41106a290300214820032903a0012149200328029c0121080c010b200341c2046a200328029804360100200341c0046a200e3b0100200341bc046a200f360200200341a0046a41186a2010360200200341b4046a2011360200200341a0046a41106a2012360200200341ac046a2013360200200341a0046a41086a2014360200200341c6046a20082f01003b0100200320063b01a604200320073a00a5042003201c3a00a404200320093b01a2042003200d3a00a1042003200a3a00a00420032015201b41f8026c6a22023602c804024020022802bc024102460d00200341a0046a200241c8026a10c6040d020b41022108200341023602bc0420022903a0022125200241186a290300214620022903102147200229030821482002290300214920032903b004211e20032903a804212320032903b804211f200220032903a0043703a002200241b8026a221c2903002122201c201f370300200241a8026a221c2903002124201c2023370300200241b0026a221c2903002123201c201e370300200229038002212920022903e001212d20022903c001213120022903a001213520022903800121392002290360213d200229034021412002290320214520022903c002212120024198026a290300212620024190026a290300212720024188026a2903002128200241f8016a290300212a200241f0016a290300212b200241e8016a290300212c200241d8016a290300212e200241d0016a290300212f200241c8016a2903002130200241b8016a2903002132200241b0016a2903002133200241a8016a290300213420024198016a290300213620024190016a290300213720024188016a2903002138200241f8006a290300213a200241f0006a290300213b200241e8006a290300213c200241d8006a290300213e200241d0006a290300213f200241c8006a2903002140200241386a2903002142200241306a2903002143200241286a2903002144200241d8026a290300211e200241d0026a290300211f200241c8026a290300212020034188016a200241e8026a29030037030020034180016a41106a200241f0026a2903003703002003200241e0026a290300370380012003280298010d0020032802dc034102460d0020034198016a41086a21020240200341d0036a280200221c450d00200341d4036a280200450d00201c102e0b2002108b020b20032015360298012003201d37029c01201a201920034198016a10c704201da7211902402001450d00200141f8026c21012015210203400240200241bc026a2802004102460d000240200241b0026a280200221c450d00200241b4026a280200450d00201c102e0b20021096010b200241f8026a2102200141887d6a22010d000b0b02402019450d00201941f8026c450d002015102e0b200341d0006a41086a20034180016a41086a290300370300200341d0006a41106a20034180016a41106a2903003703002003200329038001370350410021020c010b200341d0006a41086a20034180016a41086a290300370300200341d0006a41106a20034180016a41106a2903003703002003200329038001370350200141f8026c21012015210203400240200241bc026a2802004102460d000240200241b0026a280200221c450d00200241b4026a280200450d00201c102e0b20021096010b200241f8026a2102200141887d6a22010d000b41012102410221080240201da72201450d00200141f8026c450d002015102e0b0b02402003280274450d00201a102e0b200341386a41086a2201200341d0006a41086a290300370300200341386a41106a221c200341d0006a41106a290300370300200320032903503703380240024020020d00200341206a41106a201c290300370300200341206a41086a2001290300370300200320032903383703200240202242808080807083428080808020854200520d0041082103418be7c400210241012115410321084101211c0c020b200341e0036a2020370300200341d8036a2021370300200341c0036a2024370300200341b8036a2025370300200341a0036a202837030020034198036a202937030020034180036a202c370300200341f8026a202d370300200341e0026a2030370300200341d8026a2031370300200341c0026a2034370300200341b8026a2035370300200341a0026a203837030020034198026a203937030020034180026a203c370300200341f8016a203d370300200341e0016a2040370300200341d8016a2041370300200341c0016a2044370300200341b8016a2045370300200341f8036a2003290320370300200341e8036a201f370300200341c8036a2023370300200341a8036a202737030020034188036a202b370300200341e8026a202f370300200341c8026a2033370300200341a8026a203737030020034188026a203b370300200341e8016a203f370300200341c8016a204337030020034180046a200341206a41086a29030037030020034188046a200341306a290300370300200341f0036a201e370300200341d0036a22022022370300200341b0036a202637030020034190036a202a370300200341f0026a202e370300200341d0026a2032370300200341b0026a203637030020034190026a203a370300200341f0016a203e370300200341d0016a2042370300200341b0016a20463703002003204937039801200320483703a001200320473703a8010240202342ffffffff0f83500d00200341a0046a41086a2002280200360200200320032903c8033703a00420034180016a200341a0046a10c404200328028001220220032802880110ff01200328028401450d002002102e0b200341ac046a201b360200200341a0046a41086a200c360200200341013602a404200341013a00a004200341a0046a10fe0120034198016a108b020c0e0b200841ff01714106460d0d200841187621012008411076211c200841087621152049422088a721032049a721020b20052005280200417f6a221a360200201a0d0e2005280208200528020c2802001103000240200528020c280204450d002005280208102e0b200541046a221a201a280200417f6a221a360200201a0d0e2005102e0c0e0b200141206a2802002105200141106a280200210920012d0001210a41022108200341086a41026a200241246a2d00003a00002003200241226a2f01003b01082001411c6a280200210b200141186a2802002118200141146a28020021162001410c6a280200214a200141086a280200211a200141046a280200211b200241206a2f0100210e2002411c6a280200210f200241186a2802002110200241146a2802002111200241106a28020021122002410c6a2802002113200241086a2802002114200241066a2f00002106200241056a2d00002107200241046a2d00002115200241026a2f0100214b2002280228210120022d0001210d02400240024002400240024020022d0000224c0e03000102000b200d45211741012119201521080c040b410221080240024020150e03000104000b410021080c030b20034180016a41026a200341086a41026a2d00003a0000200320032f01083b0180010c010b0240024020150e03000103000b410021080c020b20034180016a41026a200341086a41026a2d00003a0000200320032f01083b0180010b410121080b410021190b2001280200220c41016a221c41014d0d032001201c360200200121020240024002402019450d002001200c36020020174101710d014110102c221c450d07201c41f8f7c60036020c201c4101360208201c4281808080103702004110102c2202450d0720024190f8c60036020c200241013602082002428180808010370200201c201c280200417f6a2208360200024020080d00201c280208201c28020c2802001103000240201c28020c280204450d00201c280208102e0b201c41046a22082008280200417f6a220836020020080d00201c102e0b2002280200211c0b2002201c417f6a221c3602000240201c0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a221c201c280200417f6a221c360200201c0d002002102e0b2005108b022005102e0240201a450d00201b102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b410221020c010b41022102200341206a41026a200341086a41026a2d00003a0000200320032f01083b01202003204a3602582003201a3602542003201b3602500240024002400240204c0e03000102000b41022102024002400240200d0e03000102000b410021020c010b41012102201521080b200341c0046a200e3b0100200341bc046a200f360200200341b8046a2010360200200341b4046a2011360200200341b0046a2012360200200341ac046a2013360200200341a8046a2014360200200320063b01a604200320073a00a504200320083a00a4042003204b3b01a204200320023a00a104200341003a00a0040c020b4102210202400240024020150e03000102000b410021020c010b20034180016a41026a200341206a41026a2d00003a0000200320032f01203b018001410121020b200341c0046a200e3b0100200341bc046a200f360200200341b8046a2010360200200341b4046a2011360200200341b0046a2012360200200341ac046a2013360200200341a8046a2014360200200341c2046a200328018001360100200341c6046a20034184016a2f01003b0100200320063b01a604200320073a00a504200320023a00a404200341013a00a0040c010b02400240024020150e03000102000b410021020c010b20034180016a41026a200341206a41026a2d00003a0000200320032f01203b018001410121020b200341c0046a200e3b0100200341bc046a200f360200200341b8046a2010360200200341b4046a2011360200200341b0046a2012360200200341ac046a2013360200200341a8046a2014360200200341c2046a200328018001360100200341c6046a20034184016a2f01003b0100200320063b01a604200320073a00a504200320023a00a404200341023a00a0040b20034198016a200541b00210e9081a20034180016a200341d0006a4100200920162018200b200a200341a0046a20034198016a10c904200341f0006a41026a221c20032d0087013a0000200320032f0085013b017002402003280280014101460d0020012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b2005102e0c0c0b20034188016a290300211d20032d008401210220034198046a41026a201c2d00003a0000200320032f01703b01980420012001280200417f6a221c3602000240201c0d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a221c201c280200417f6a221c360200201c0d002001102e0b2005102e200241ff01714106460d0b0b200341e8006a41026a20034198046a41026a2d000022013a0000200320032f01980422053b0168200041206a20023a0000200041186a41003a000020004200370308200020053b0021200041236a20013a00002000201d37002420004201370300200424000f0b4102211c200341206a41026a200241246a2d00003a00002003200241226a2f01003b01202001410c6a2802002107200141086a2802002115200141046a2802002119200241206a2f0100210d2002411c6a280200210e200241186a280200210f200241146a2802002110200241106a28020021112002410c6a2802002112200241086a2802002113200241066a2f00002114200241056a2d00002106200241046a2d00002108200241026a2f0100210a2002280228210120022d0001210c02400240024002400240024020022d000022090e03000102000b200c45211b4101211a2008211c0c040b4102211c0240024020080e03000104000b4100211c0c030b20034180016a41026a200341206a41026a2d00003a0000200320032f01203b0180010c010b0240024020080e03000103000b4100211c0c020b20034180016a41026a200341206a41026a2d00003a0000200320032f01203b0180010b4101211c0b4100211a0b2001280200221741016a220541014d0d02200120053602002001210202400240201a450d0020012017360200201b4101710d014110102c2203450d05200341f8f7c60036020c2003410136020820034281808080103702004110102c2202450d0520024190f8c60036020c20024101360208200242818080801037020020032003280200417f6a2205360200024020050d002003280208200328020c2802001103000240200328020c280204450d002003280208102e0b200341046a22052005280200417f6a220536020020050d002003102e0b200228020021050b20022005417f6a2203360200024020030d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22032003280200417f6a220336020020030d002002102e0b02402015450d002019102e0b20012001280200417f6a22033602004102210220030d082001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22032003280200417f6a220336020020030d082001102e0c090b41022102200341386a41026a200341206a41026a2d00003a0000200320032f01203b0138024002400240024020090e03000102000b41022102024002400240200c0e03000102000b410021020c010b410121022008211c0b200341b8016a200d3b0100200341b4016a200e360200200341b0016a200f360200200341ac016a2010360200200341a8016a2011360200200341a4016a2012360200200341a0016a2013360200200320143b019e01200320063a009d012003201c3a009c012003200a3b019a01200320023a009901200341003a0098010c020b4102210202400240024020080e03000102000b410021020c010b20034180016a41026a200341386a41026a2d00003a0000200320032f01383b018001410121020b200341b8016a200d3b0100200341b4016a200e360200200341b0016a200f360200200341ac016a2010360200200341a8016a2011360200200341a4016a2012360200200341a0016a2013360200200341ba016a200328018001360100200341be016a20034184016a2f01003b0100200320143b019e01200320063a009d01200320023a009c01200341013a0098010c010b02400240024020080e03000102000b410021020c010b20034180016a41026a200341386a41026a2d00003a0000200320032f01383b018001410121020b200341b8016a200d3b0100200341b4016a200e360200200341b0016a200f360200200341ac016a2010360200200341a8016a2011360200200341a4016a2012360200200341a0016a2013360200200341ba016a200328018001360100200341be016a20034184016a2f01003b0100200320143b019e01200320063a009d01200320023a009c01200341023a0098010b200320073602a804200320153602a404200320193602a00420034180016a20034198016a200341a0046a10c30420034188016a280200210520032d008101211a20032d008201211520032d0083012108200328028401211c20032d008001210220012001280200417f6a2219360200024020024106470d00024020190d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200041186a41003a000020004200370308200020032800503600192000411c6a200341d3006a28000036000020004200370300200424000f0b20190d082001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22032003280200417f6a220336020020030d082001102e0c080b200141146a2802002105200141046a280200210620012d0001210741022108200341206a41026a200241246a2d00003a00002003200241226a2f01003b0120200141106a28020021092001410c6a280200210a200141086a280200210b200241206a2f0100210c2002411c6a280200210d200241186a280200210e200241146a280200210f200241106a28020021102002410c6a2802002111200241086a2802002112200241066a2f00002113200241056a2d00002114200241046a2d00002115200241026a2f010021162002280228210120022d0001211702400240024002400240024020022d000022180e03000102000b20174521194101211a201521080c040b410221080240024020150e03000104000b410021080c030b20034180016a41026a200341206a41026a2d00003a0000200320032f01203b0180010c010b0240024020150e03000103000b410021080c020b20034180016a41026a200341206a41026a2d00003a0000200320032f01203b0180010b410121080b4100211a0b2001280200221b41016a221c41014d0d012001201c36020020012102024002400240201a450d002001201b36020020194101710d014110102c221c450d05201c41f8f7c60036020c201c4101360208201c4281808080103702004110102c2202450d0520024190f8c60036020c200241013602082002428180808010370200201c201c280200417f6a2208360200024020080d00201c280208201c28020c2802001103000240201c28020c280204450d00201c280208102e0b201c41046a22082008280200417f6a220836020020080d00201c102e0b2002280200211c0b2002201c417f6a221c3602000240201c0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a221c201c280200417f6a221c360200201c0d002002102e0b2005108b022005102e20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b410221020c010b41022102200341386a41026a200341206a41026a2d00003a0000200320032f01203b0138024002400240024020180e03000102000b4102210202400240024020170e03000102000b410021020c010b41012102201521080b200341c0046a200c3b0100200341bc046a200d360200200341b8046a200e360200200341b4046a200f360200200341b0046a2010360200200341ac046a2011360200200341a8046a2012360200200320133b01a604200320143a00a504200320083a00a404200320163b01a204200320023a00a104200341003a00a0040c020b4102210202400240024020150e03000102000b410021020c010b20034180016a41026a200341386a41026a2d00003a0000200320032f01383b018001410121020b200341c0046a200c3b0100200341bc046a200d360200200341b8046a200e360200200341b4046a200f360200200341b0046a2010360200200341ac046a2011360200200341a8046a2012360200200341c2046a200328018001360100200341c6046a20034184016a2f01003b0100200320133b01a604200320143a00a504200320023a00a404200341013a00a0040c010b02400240024020150e03000102000b410021020c010b20034180016a41026a200341386a41026a2d00003a0000200320032f01383b018001410121020b200341c0046a200c3b0100200341bc046a200d360200200341b8046a200e360200200341b4046a200f360200200341b0046a2010360200200341ac046a2011360200200341a8046a2012360200200341c2046a200328018001360100200341c6046a20034184016a2f01003b0100200320133b01a604200320143a00a504200320023a00a404200341023a00a0040b20034198016a200541b00210e9081a20034180016a41012006200b200a20092007200341a0046a20034198016a10d604200341f0006a41026a221c20032d0087013a0000200320032f0085013b017002402003280280014101460d0020012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b2005102e0c070b20034188016a290300211d20032d0084012102200341086a41026a201c2d00003a0000200320032f01703b010820012001280200417f6a221c3602000240201c0d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a221c201c280200417f6a221c360200201c0d002001102e0b2005102e200241ff01714106460d060b20034198046a41026a200341086a41026a2d000022013a0000200320032f010822053b019804200041206a20023a0000200041186a41003a000020004200370308200020053b0021200041236a20013a00002000201d37002420004201370300200424000f0b200141206a2802002105200141106a280200210920012d0001210a41022108200341206a41026a200241246a2d00003a00002003200241226a2f01003b01202001411c6a280200210b200141186a2802002118200141146a28020021162001410c6a280200214a200141086a280200211a200141046a280200211b200241206a2f0100210e2002411c6a280200210f200241186a2802002110200241146a2802002111200241106a28020021122002410c6a2802002113200241086a2802002114200241066a2f00002106200241056a2d00002107200241046a2d00002115200241026a2f0100214b2002280228210120022d0001210d02400240024002400240024020022d0000224c0e03000102000b200d45211741012119201521080c040b410221080240024020150e03000104000b410021080c030b20034180016a41026a200341206a41026a2d00003a0000200320032f01203b0180010c010b0240024020150e03000103000b410021080c020b20034180016a41026a200341206a41026a2d00003a0000200320032f01203b0180010b410121080b410021190b2001280200220c41016a221c41014d0d002001201c360200200121020240024002402019450d002001200c36020020174101710d014110102c221c450d04201c41f8f7c60036020c201c4101360208201c4281808080103702004110102c2202450d0420024190f8c60036020c200241013602082002428180808010370200201c201c280200417f6a2208360200024020080d00201c280208201c28020c2802001103000240201c28020c280204450d00201c280208102e0b201c41046a22082008280200417f6a220836020020080d00201c102e0b2002280200211c0b2002201c417f6a221c3602000240201c0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a221c201c280200417f6a221c360200201c0d002002102e0b2005108b022005102e0240201a450d00201b102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b410221020c010b41022102200341386a41026a200341206a41026a2d00003a0000200320032f01203b01382003204a3602582003201a3602542003201b3602500240024002400240204c0e03000102000b41022102024002400240200d0e03000102000b410021020c010b41012102201521080b200341c0046a200e3b0100200341bc046a200f360200200341b8046a2010360200200341b4046a2011360200200341b0046a2012360200200341ac046a2013360200200341a8046a2014360200200320063b01a604200320073a00a504200320083a00a4042003204b3b01a204200320023a00a104200341003a00a0040c020b4102210202400240024020150e03000102000b410021020c010b20034180016a41026a200341386a41026a2d00003a0000200320032f01383b018001410121020b200341c0046a200e3b0100200341bc046a200f360200200341b8046a2010360200200341b4046a2011360200200341b0046a2012360200200341ac046a2013360200200341a8046a2014360200200341c2046a200328018001360100200341c6046a20034184016a2f01003b0100200320063b01a604200320073a00a504200320023a00a404200341013a00a0040c010b02400240024020150e03000102000b410021020c010b20034180016a41026a200341386a41026a2d00003a0000200320032f01383b018001410121020b200341c0046a200e3b0100200341bc046a200f360200200341b8046a2010360200200341b4046a2011360200200341b0046a2012360200200341ac046a2013360200200341a8046a2014360200200341c2046a200328018001360100200341c6046a20034184016a2f01003b0100200320063b01a604200320073a00a504200320023a00a404200341023a00a0040b20034198016a200541b00210e9081a20034180016a200341d0006a4101200920162018200b200a200341a0046a20034198016a10c904200341f0006a41026a221c20032d0087013a0000200320032f0085013b017002402003280280014101460d0020012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b2005102e0c040b20034188016a290300211d20032d0084012102200341086a41026a201c2d00003a0000200320032f01703b010820012001280200417f6a221c3602000240201c0d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a221c201c280200417f6a221c360200201c0d002001102e0b2005102e200241ff01714106460d030b20034198016a41026a200341086a41026a2d000022013a0000200320032f010822053b019801200041206a20023a0000200041186a41003a000020004200370308200020053b0021200041236a20013a00002000201d3700244201211d0c030b00000b1036000b4200211d200042003703082000200328009801360019200041186a41003a00002000411c6a2003419b016a2800003600000b2000201d370300200424000f0b2000420037030820002003280050360019200041186a41003a00002000411c6a200341d3006a28000036000020004200370300200424000f0b0b2000201c360024200020083a0023200020153a00222000201a3a002120004200370308200041286a2005360000200041206a20023a0000200041186a41003a000020004201370300200424000f0b2000420037030820002003280038360019200041186a41003a00002000411c6a2003413b6a28000036000020004200370300200424000f0b20052005280200417f6a2202360200024020020d002005280208200528020c2802001103000240200528020c280204450d002005280208102e0b200541046a22022002280200417f6a220236020020020d002005102e0b200041186a41003a000020004200370308200020032800083600192000411c6a2003410b6a28000036000020004200370300200424000f0b0b20002002360024200020013a00232000201c3a0022200020153a002120004200370308200041286a2003360000200041206a20083a0000200041186a41003a000020004201370300200424000f0b2000420037030820002003280050360019200041186a41003a00002000411c6a200341d3006a28000036000020004200370300200424000b9f0501057f230041b0036b22092400200941386a220a4200370300200941306a220b4200370300200941206a41086a420037030020094200370320200941206a41d9fcc600410610810220094198036a4180f4cb004106108102200a20094198036a41086a290000370300200b200929009803370300200941186a200941206a4120108e024100210c02400240417f417f200928021c410020092802181b220a20026a220b200b200a491b220b41016a220d200d200b491b200220011b2202200a4d0d00024020034101470d002004410047200541014b71210c2005417f6a210a0b200941206a200841b00210e9081a200941e4026a200a36020020094190036a20063a0000200941e8026a2007290200370300200941f0026a200741086a290200370300200941f8026a200741106a29020037030020094180036a200741186a29020037030020094188036a200741206a290200370300200920043602e0022009200c3602dc0241002107200941003602d0022002200941206a10aa04200941206a200210a704200928022821082009280220210a200941ac036a41003a0000200941003602a803200941106a200a2008200941a8036a4105410010ca04024002402009280210450d00200920092802142207410520074105491b36029c032009200941a8036a36029803200941086a20094198036a10ab01200928020c417f6a210820092802084521070c010b0b02402009280224450d00200a102e0b2009412c6a2008410020071b2207360200200941206a41086a200236020020094100360224200941013a0020200941206a10fe01200041086a200736020020002002360204200041003602000c010b20004281808080b0a08001370200200041086a41f4e6c400ad4280808080f002843702002008108b020b200941b0036a24000b880301077f410121020240024002400240024002402001280208220341016a2204200128020422054d0d000c010b200320054f0d012001280200220620036a2d00002107200120043602080240200741037122084103460d0002400240024020080e03000102000b20074102762108410021020c030b0240200341026a220320054d0d000c030b200120033602082004417f460d04200620046a2d0000410874200772220141ffff0371418002490d02200141fcff03714102762108410021020c020b200341046a220320054b0d01200120033602082004417d4f0d04200620046a22012f0000200141026a2d000041107472410874200772220141808004492102200141027621080c010b0240200741034d0d000c010b200341056a220320054b0d00200120033602082004417c4f0d04200620046a28000022084180808080044921020b20002008360204200020023602000f0b200320054188eccc00103c000b417f20034198ebcc001057000b200420034198ebcc001057000b200420034198ebcc001057000bdf0401057f230041106b22022400200241003a0005024002400240024002400240024020012802002203280204220420044100472205490d00200241056a20032802002206200510e9081a2003200420056b3602042003200620056a360200024020040d00410021040c060b024020022d0005220441037122034103460d000240024020030e03080001080b200241003b0106200220043a00064101210420012802002201280204220320034100472205490d04200241066a41017220012802002204200510e90821062001200320056b3602042001200420056a360200024020030d00200620056a41003a00000b20022f0106220441ff014d0d0220044102762103410021040c080b20024100360208200220043a0008200241086a4101722001280200220428020020042802042203410320034103491b220310e9082101200428020422052003490d042004200520036b3602042004200428020020036a360200024020034103732204450d00200120036a4100200410eb081a0b2002280208220341808004492104200341027621030c070b200441034d0d010b410121040c050b2002410036020c2002410c6a2001280200220328020020032802042204410420044104491b220410e9081a200328020422052004490d022003200520046b3602042003200328020020046a360200024020044104460d002002410c6a20046a4100410420046b10eb081a0b200228020c22034180808080044921040c040b0c030b2003200541b8b2c0001056000b2004200541b8b2c0001056000b20044102762103410021040b2000200336020420002004360200200241106a24000bb40404057f017e027f017e0240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a360200024002400240200441037122064103460d000240024020060e03030001030b41012106024020050d000c060b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d05200141fcff0371410276ad21070c030b410121060240200541034f0d000c050b200341036a2d0000210520032f0001210820012002417c6a3602042001200341046a3602002008200541107472410874200472220141808004490d042001410276ad21070c020b024002400240200441027622090e050002020201020b20054104490d042003350001210720012002417b6a3602042001200341056a36020020074280808080045421060c050b20054108490d03200329000121072001200241776a3602042001200341096a3602002007428080808080808080015421060c040b200441134b0d02200941046a21082002417e6a2102200341026a2103410021044200210741012106034002402002417f470d000c050b2003417f6a310000210a20012002360204200120033602002002417f6a2102200341016a2103200a2004410374413871ad862007842107200441016a22052104200541ff01712008490d000b2007427f412820094103746b413871ad885821060c030b2004410276ad21070b410021060c010b410121060b2000200737030820002006ad3703000be70404047f017e037f017e02400240200128020022022802042203450d00200228020022042d0000210520022003417f6a3602042002200441016a3602000240200541037122024103460d0002400240024020020e03000102000b2005410276ad2106410021020c040b200128020022012802042202450d02200128020022032d0000210420012002417f6a360204410121022001200341016a3602002004410874200572220141ffff0371418002490d03200141fcff0371410276ad2106410021020c030b41012102024020012802002201280204220341034f0d000c030b2001280200220441026a2d0000210720042f000021082001200441036a36020020012003417d6a3602042008200741107472410874200572220141808004490d022001410276ad2106410021020c020b024002400240200541027622090e050002020201020b2001280200220228020422014104490d0220022802002205350000210620022001417c6a3602042002200541046a36020020064280808080045421020c030b2001280200220228020422014108490d012002280200220529000021062002200141786a3602042002200541086a3602002006428080808080808080015421020c020b200541134b0d00200941046a2108410021034200210641012102034002402001280200220528020422040d000c030b20052802002207310000210a20052004417f6a3602042005200741016a360200200a2003410374413871ad862006842106200341016a22052103200541ff01712008490d000b2006427f412820094103746b413871ad885821020c010b410121020b2000200637030820002002ad3703000be10506067f017e027f017e017f017e230041206b220224000240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200024002400240200541037122074103460d0002400240024020070e03000102000b2005410276ad21080c040b410121072006450d0220042d0001210620012003417e6a3602042001200441026a3602002006410874200572220141ffff0371418002490d02200141fcff0371410276ad21080c030b4101210720064103490d01200441036a2d0000210620042f0001210920012003417c6a3602042001200441046a3602002009200641107472410874200572220141808004490d012001410276ad21080c020b02400240024002402005410276220a0e0d00030303010303030303030302030b20064104490d052004350001210820012003417b6a3602042001200441056a36020020084280808080045421074200210b0c060b20064108490d04200429000121082001200341776a3602042001200441096a3602002008428080808080808080015421074200210b0c050b20064110490d03200441096a290000210b2004290001210820012003416f6a3602042001200441116a360200200b428080808080808080015421070c040b200541334b0d02200a41046a21092003417e6a2103200441026a21044100210541012107200241186a210c420021084200210b03402003417f460d012004417f6a310000210d2001200336020420012004360200200241106a200d4200200541037441f8007110ed082003417f6a2103200441016a2104200c290300200b84210b20022903102008842108200541016a22062105200641ff01712009490d000b2002427f427f41e800200a4103746b41f8007110e4082008200229030058200b200241086a290300220d58200b200d511b21070c030b0c020b4200210b410021070c010b410121070b20002008370308200041106a200b37030020002007ad370300200241206a24000bd60203017f017e027f230041206b220224000240024002400240024002402000290300220342c000540d00200342808001540d012003428080808004540d024108200379a741037622046b41044f0d0341c087c500413641f887c5001039000b20022003a74102743a00082001200241086a410110740c030b20022003a74102744101723b01082001200241086a410210740c020b20022003a74102744102723602082001200241086a410410740c010b2002411320044102746b3a00082001200241086a41011074200220002903002203370300200441786a21000340200220033c00082001200241086a4101107420034208882103200041016a22042000492105200421002005450d000b20022003370300200350450d010b200241206a24000f0b2002411c6a4100360200200241186a41d4e2cc003602002002420137020c2002418888c5003602082002200241086a10dd04000b6c01017f230041206b220224002002419088c50036020420022000360200200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241c4cec800200241046a41c4cec800200241086a419888c5001058000b6c01017f230041206b22022400200241d889c50036020420022000360200200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241b4cec800200241046a41b4cec800200241086a41e889c5001058000b930501047f230041a0036b22012400200141106a4200370300200141186a4200370300200141206a4200370300200141286a4200370300200120012903c801370308200142c0b2cd3b37039803200142c0b2cd3b37039003200142c0b2cd3b370388034100210241012103034020014188036a2104024002400240200241ff01710e03010002010b20014190036a21040c010b20014198036a21040b200442c0b2cd3b370300024020034103460d00200341e99fc0006a2104200341016a210320042d000022024103470d010b0b20014188026a420037030020014180026a4201370300200141f8016a22034200370300200141f0016a22044201370300200141c8016a41186a4200370300200141c8016a41f8006a4200370300200141c8016a41f0006a4201370300200141c8016a41e8006a4200370300200141c8016a41e0006a420137030020014198026a420037030020014190026a200129039003370300200141d0026a4200370300200141c8026a200129038803370300200142003703d00120014280e497d0123703c80120012001290398033703d801200141f8026a200141286a290300370300200141f0026a200141086a41186a290300370300200141e8026a200141186a290300370300200141e0026a200141106a290300370300200141d8026a20012903083703002004420137030020034280b0def7d32b3703002001410036028003200141086a200141c8016a41c00110e9081a200141086a41f8006a428090cad2c60e370300200141086a41f0006a4201370300200141086a41e8006a4280c0a8ca9a3a370300200141086a41e0006a4201370300200141c8016a200141086a41b80110e9081a2001428180808080d0a5cc00370380032000200141c8016a107f200141a0036a24000b800903097f017e027f23004190036b2202240041002103200241003a00a0022001280204417f6a2104024002400240024003402004417f460d0120024180026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a0022004417f6a21042005210320054120470d000b200241d0026a41086a220420024180026a41086a290300370300200241d0026a41106a220320024180026a41106a290300370300200241d0026a41186a220620024180026a41186a29030037030020022002290380023703d002200541ff0171411f4b0d010c020b200341ff0171450d01200241003a00a0020c010b200241e0016a41086a2004290300370300200241e0016a41106a2003290300370300200241e0016a41186a2006290300370300200220022903d0023703e00120024180026a200110850520022802a0022204450d00200241a0016a41186a2203200241e0016a41186a290300370300200241a0016a41106a2205200241e0016a41106a290300370300200241a0016a41086a2206200241e0016a41086a290300370300200241a0016a41286a220720024180026a41086a290300370300200241a0016a41306a220820024180026a41106a290300370300200241a0016a41386a220920024180026a41186a290300370300200220022903e0013703a00120022002290380023703c001200241a4026a280200210a20024180026a41286a290300210b200241e0006a41086a220c2006290300370300200241e0006a41106a22062005290300370300200241e0006a41186a22052003290300370300200241e0006a41206a220320022903c001370300200241e0006a41286a220d2007290300370300200241e0006a41306a22072008290300370300200241e0006a41386a22082009290300370300200220022903a0013703602004450d00200241206a41386a2008290300370300200241206a41306a2007290300370300200241206a41286a200d290300370300200241206a41206a2003290300370300200241206a41186a2005290300370300200241206a41106a2006290300370300200241206a41086a200c29030037030020022002290360370320200241086a200110ab010240024002402002280208450d00200241003602a0010c010b200241a0016a2001200228020c10920120022802a0010d010b20004100360240200a450d02200a41306c450d022004102e0c020b200241106a41086a2201200241a0016a41086a280200360200200220022903a001370310200041386a200241206a41386a290300370300200041306a200241206a41306a290300370300200041286a200241206a41286a290300370300200041206a200241206a41206a290300370300200041186a200241206a41186a290300370300200041106a200241206a41106a290300370300200041086a200241206a41086a29030037030020002002290320370300200041c8006a200b3703002000200a36024420002004360240200041d0006a2002290310370300200041d8006a20012802003602000c010b200041003602400b20024190036a24000bc01509077f017e097f017e017f017e027f017e047f230041c0036b22012400200141286a22024200370300200141206a22034200370300200141106a41086a420037030020014200370310200141106a4190dac800410a10810220014198036a41d5dac8004106108102200220014198036a41086a2900003703002003200129009803370300200141203602342001200141106a360230200141386a200141106a412010ed02024002400240200128023822040d00410021050c010b200128023c21062001200141386a41086a28020036024c20012004360248200141086a200141c8006a10ab010240024020012802080d0002400240200128020c2207200128024c41c4006e2202200220074b1bad42c4007e2208422088a70d002008a72202417f4c0d000240024020020d00410421050c010b2002102c2205450d060b200241c4006ead2108024002402007450d0020014198036a410172210920014198036a410772210a4100210b03400240024002400240200128024c2203450d002001280248220c2d0000210220012003417f6a220d36024c2001200c41016a3602480240024020020e020001020b200d4104490d012001418c026a41026a200141f0026a41026a2d00003a0000200141f0016a41086a200141b0026a41086a290200370300200141f0016a41106a200141b0026a41106a290200370300200141f0016a41186a200141b0026a41186a2d00003a0000200141d0016a41086a20014198036a41086a290100370300200141d0016a41106a20014198036a41106a290100370300200141d0016a41186a20014198036a41186a290100370300200120012f00f0023b018c02200120012902b0023703f00120012001290198033703d001200c280001210e20012003417b6a36024c2001200c41056a36024841002102410021030c040b41002102200141003a00b8032003417e6a210302400340200d2002460d0120014198036a20026a200c20026a220f41016a2d00003a00002001200f41026a3602482001200241016a220f3a00b8032001200336024c2003417f6a2103200f2102200f4120460d030c000b0b200241ff0171450d02200141003a00b8030c020b200141cc016a41026a2001418c026a41026a2d00003a0000200141b0016a41086a200141f0016a41086a290300370300200141b0016a41106a200141f0016a41106a290300370300200141b0016a41186a200141f0016a41186a2d00003a000020014190016a41086a200141d0016a41086a29030037030020014190016a41106a200141d0016a41106a29030037030020014190016a41186a200141d0016a41186a290300370300200120012f018c023b01cc01200120012903f0013703b001200120012903d001370390010c070b20014190036a41026a221020012d009a0322023a000020014194036a41026a20023a0000200141b0026a41086a2211200a41086a2900002212370300200141b0026a41106a2213200a41106a2900002214370300200141b0026a41186a2215200a41186a2d000022023a0000200120012f01980322163b019003200120163b0194032001200a29000022173703b002200128009b032118200141f0026a41186a221620023a0000200141f0026a41106a22022014370300200141f0026a41086a22192012370300200120173703f002200f41ff0171411f4d0d00200141ec026a41026a20102d000022103a0000200141d0026a41086a20192903002212370300200141d0026a41106a20022903002214370300200141d0026a41186a20162d000022023a0000200141ac026a41026a221920103a0000200120012f01900322163b01ec02200120012903f00222173703d002200120163b01ac0220014190026a41186a221620023a000020014190026a41106a2210201437030020014190026a41086a221a20123703002001201737039002200d200f460d00200c200f6a220241016a2d0000210f2001200336024c2001200241026a360248410021024100210c02400240200f0e020100020b20014198036a200141c8006a10930120012d0098034101460d012015200941186a2900003703002013200941106a2900003703002011200941086a290000370300200120092900003703b0024101210c0b200141d0016a41186a2015290300370300200141d0016a41106a2013290300370300200141d0016a41086a20112903003703002001418c026a41026a20192d00003a0000200141f0016a41086a201a290300370300200141f0016a41106a2010290300370300200141f0016a41186a20162d00003a0000200120012903b0023703d001200120012f01ac023b018c0220012001290390023703f00141012103200c211b2018210e0c010b41022103410121020b200141cc016a41026a220f2001418c026a41026a2d00003a0000200141b0016a41086a220c200141f0016a41086a290300370300200141b0016a41106a220d200141f0016a41106a290300370300200141b0016a41186a2216200141f0016a41186a2d00003a000020014190016a41086a2210200141d0016a41086a29030037030020014190016a41106a2219200141d0016a41106a29030037030020014190016a41186a2211200141d0016a41186a290300370300200120012f018c023b01cc01200120012903f0013703b001200120012903d0013703900120020d042001418c016a41026a2213200f2d00003a0000200141f0006a41086a220f200c290300370300200141f0006a41106a220c200d290300370300200141f0006a41186a220d20162d00003a0000200141d0006a41086a22162010290300370300200141d0006a41106a22102019290300370300200141d0006a41186a22192011290300370300200120012f01cc013b018c01200120012903b001370370200120012903900137035002402008422088a722022008a7470d00200241016a22112002490d0420024101742215201120112015491b22114104201141044b1bad42c4007e2212422088a74541027421112012a721150240024020020d0020014100360298030c010b200141043602a00320012005360298032001200241c4006c36029c030b200141b0026a2015201120014198036a107d20012802b802211120012802b0024101460d0320012802b4022105200842808080807083201141c4006ead8421080b2005200241c4006c6a220220033a00002002200e360004200241036a20132d00003a0000200220012f018c013b0001200d2d00002103200c2903002112200f2903002114200129037021172002201b3a002120022017370008200241106a2014370000200241186a2012370000200241206a20033a00002002413a6a2019290300370000200241326a20102903003700002002412a6a20162903003700002002200129035037002220084280808080107c2108200b41016a220b2007470d000b0b2005450d030c040b20110d050b1038000b2008a721022002450d00200241c4006c450d002005102e0b41002105200141003602b802200142013703b0022001410a3602d4012001200141306a3602d0012001200141b0026a36029001200141ac036a41013602002001420137029c03200141909dc500360298032001200141d0016a3602a80320014190016a419cebc00020014198036a103d1a20012802b00220012802b80210ef0220012802b402450d0020012802b002102e0b2006450d002004102e0b0240024020050d0020004100360208200042043702000c010b20002008370204200020053602000b200141c0036a24000f0b1036000bdc0b04067f017e037f017e230041d0016b22012400200141386a41186a22024200370300200141386a41106a22034200370300200141386a41086a2204420037030020014200370338200141286a4190dac800410a1081022004200141286a41086a220529000037030020012001290028370338200141286a419adac80041061081022002200529000037030020032001290028370300200141d8006a200141386a412010f40220012d005821052002200141f1006a2900003703002003200141e9006a2900003703002004200141e1006a290000370300200120012900593703380240024020054101470d0020002001290338370000200041186a2002290300370000200041106a2003290300370000200041086a20042903003700000c010b200141d8006a41186a22024200370300200141d8006a41106a22064200370300200141d8006a41086a2203420037030020014200370358200141386a41d9fcc60041061081022003200429000037030020012001290038370358200141386a41b4f4cb0041061081022002200429000037030020062001290038370300200141386a200141d8006a10a10420012802382204410420041b210302400240200129023c420020041b2207422088a7220541246c2204450d00200320046a2202415c6a2108200321040340024020042d00004101460d002002200441246a2204470d010c020b200441016a2800002109200441086a280200210a2001200441106a28020036023c2001200a36023802400240200941c28289aa04470d00200141d8006a200141386a10930220012903584203510d03200141d8006a41106a22042802002102200141d8006a41186a420037030020044200370300200141d8006a41086a2204420037030020014200370358200141386a41a081ca0041071081022004200141386a41086a220929000037030020012001290038370358200141386a41f09dc500410a108102200641086a200929000037000020062001290038370000200141386a200141d8006a1088034101210620012802382204410120041b210902402002200129023c420020041b220b422088a74f0d00200141086a41186a200920024105746a220441186a290000370300200141086a41106a200441106a290000370300200141086a41086a200441086a29000037030020012004290000370308410021060b0240200b42ffffff3f83500d002009102e0b20060d03200141d8006a41186a200141086a41186a290300370300200141d8006a41106a200141086a41106a290300370300200141d8006a41086a200141086a41086a29030037030020012001290308370358200141386a41186a22044200370300200141386a41106a22024200370300200141386a41086a2206420037030020014200370338200141286a4190dac800410a1081022006200141286a41086a220929000037030020012001290028370338200141286a419adac800410610810220042009290000370300200220012900283703004120102c2204450d012001422037022c20012004360228200141286a200141d8006a41201074200141386a412020012802282204200128023010b2010240200128022c450d002004102e0b20002001290358370000200041186a200141d8006a41186a290300370000200041106a200141d8006a41106a290300370000200041086a200141d8006a41086a2903003700000c040b20082004462109200441246a21042009450d010c020b0b1036000b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000b02402005450d00200541246c21022003210403400240024002400240024020042d00000e050400010204030b2004410c6a280200450d03200441086a280200102e0c030b2004410c6a280200450d02200441086a280200102e0c020b2004410c6a280200450d01200441086a280200102e0c010b200441086a280200450d00200441046a280200102e0b200441246a21042002415c6a22020d000b0b2007a72204450d00200441246c450d002003102e0b200141d0016a24000ba70702117f047e23004190016b22012400200110940302400240024020012903004202510d00200028020821022000280204210320002802002104200141186a200141106a28020010a105200141d8006a2001280218200128022010a205200141386a41086a2200200141e4006a2902003703002001200129025c3703380240024020012802584101460d00200141286a41086a4200370300200141003602280c010b200141286a41086a2000290300370300200120012903383703280b02402002450d002004200241246c6a2105200141d8006a41106a2106200141286a410472210720042108034020082802202109200141d8006a41186a220a200841186a2900003703002006200841106a290000370300200141d8006a41086a220b200841086a29000037030020012008290000370358024002402001280230220c450d00200128022c210d0c010b419403102c220c450d054100210d200c4100360200200c41003b01322001200c3602302001410036022c0b200841246a2108024002400340200c2f0132220e410574210f41002100417c2110417f2102024003400240200f2000470d00200e21020c020b200141d8006a200c20006a41346a412010ec082211450d03200241016a21022010417c6a2110200041206a21002011417f4a0d000b0b0240200d450d00200d417f6a210d200c20024102746a4194036a280200210c0c010b0b200141386a41186a200a2903002212370300200141386a41106a20062903002213370300200141386a41086a200b290300221437030020012001290358221537033820062015370200200641086a2014370200200641106a2013370200200641186a201237020020012007360264200120023602602001200c36025c20014100360258200141d8006a410010a30521000c010b200c20106b21000b2000200028020020096a3602002001200128022820096a36022820082005470d000b0b02402003450d00200341246c450d002004102e0b200141e4006a200141286a41086a29030037020020012001290328221237025c2001410136025820012802182100200128022021022001410036024020014201370338200120123e028c01200141386a2001418c016a41041074200141d8006a41086a2210200141386a10f2012000200220012802382211200128024010b2010240200128023c450d002011102e0b201010bc02200128021c450d012000102e0c010b200041046a2802002202450d00200241246c450d002000280200102e0b20014190016a24000f0b1036000be70501067f230041a0016b22012400200141d8006a41186a22024200370300200141d8006a41106a22034200370300200141d8006a41086a2204420037030020014200370358200141d8006a41a081ca00410710810220014190016a41e4d1c100410c108102200220014190016a41086a2900003703002003200129009001370300200141106a200141d8006a4120108e0220012802142105200128021021062002200041186a2900003703002003200041106a2900003703002004200041086a29000037030020012000290000370358200141186a41bed8c8004108108102200141286a41edd8c800410e10810220012005410020061b3602482001200141c8006a410410a30137037820014190016a410c6a2202200141c8006a41046a3602002001200141f8006a41086a360294012001200141c8006a360298012001200141f8006a36029001200141386a20014190016a107c024002404120102c2200450d002001422037027c20012000360278200141f8006a200141d8006a41201074200120012802782200200128028001220310a301370388012002200020036a3602002001200036029801200120014188016a41086a36029401200120014188016a36029001200141c8006a20014190016a107c0240200128027c450d002000102e0b20012802402202200128025022036a41206a2200417f4c0d010240024020000d00410121040c010b2000102c2204450d010b20014100360298012001200036029401200120043602900120014190016a200141186a4110107420014190016a200141286a4110107420014190016a200128023822002002107420014190016a20012802482202200310740240200128024c450d002002102e0b0240200128023c450d002000102e0b200141086a20012802900122002001280298012202108e022001200128020c41016a410120012802081b36025820002002200141d8006a410410b2010240200128029401450d002000102e0b200141a0016a24000f0b1036000b1038000b7801027f230041106b2204240002404108102c2205450d0020044208370204200420053602002004200236020c20042004410c6a410410742004200336020c20042004410c6a410410742000200120042802002202200428020810b20102402004280204450d002002102e0b200441106a24000f0b1036000be50101047f230041206b2202240002400240200128020822034105744104722204417f4c0d00200128020021012004102c2205450d0120024100360208200220043602042002200536020020032002107602402003450d002003410574210303404120102c2204450d032002422037021420022004360210200241106a2001412010742002200228021022042002280218107402402002280214450d002004102e0b200141206a2101200341606a22030d000b0b2000412020022802002201200228020810b20102402002280204450d002001102e0b200241206a24000f0b1038000b1036000bb80404017f017e017f047e230041c0036b2207240042002108024020050d00200741186a2001ad420042c0843d420010e80820074188026a10a903200741c0006a2007290390022208200220082002541b10e804200741c0006a41086a290300210820072903402102200741a0026a2201420037030020074188026a41106a2205420037030020074188026a41086a22094200370300200742003703880220074188026a4180fdc6004112108102200741d0006a41dc98c50041111081022001200741d0006a41086a29000037030020052007290050370300200741286a20074188026a10e90420074188026a200729033042808090bbbad6adf00d200728022822011b200741286a41106a290300420020011b2002200842808090bbbad6adf00d420010ea04200741186a41086a29030021022007290318210a024002402007280288024101470d00427f210b427f210c0c010b2005290300210c2009290300210b0b200741d0006a10a9030240024002400240200641ff01710e03010200010b200741d0016a21050c020b200741e0006a21050c010b20074198016a21050b2005290300210820074188026a10a903200741086a200729039002220d2008200d2008541b10e804200741106a29030021082007290308210d200041306a200c370300200041286a200b370300200041206a2002370300200041186a200a370300200041106a20083703002000200d370308420121080b2000200337033820002008370300200041c0006a2004370300200741c0036a24000bdd0706017f017e047f037e037f067e230041c0026b22022400420021034280c2d72f42004280f985d40442001082052104200241e0016a22054200370300200241d0016a41086a4200370300200241ec016a22064180023b0100200241e8016a22072004360200200242003703d00141012104200241013602b802024002404100450d0042012108420021090c010b0240024002404101450d004200210a0c010b200241c8016a210b4101210c420021080340200241b0016a200842002001420010e808200241c0016a200142002001420010e808200820022903b801220184200184420052200b290300220120022903b001220a200a7c7c220a200154720d0220022903c0012101200c410271210d200c4101762204210c200a2108200d450d000b0b0240200441024f0d0020012108200a21090c020b200241a0016a41086a210d20012108200a2109034020024190016a200a42002001420010e808200241a0016a200142002001420010e808200a200229039801220184200184420052200d2903002201200229039001220a200a7c7c220a200154720d0120022903a001210102402004410271450d00200241e0006a200942002001420010e808200241f0006a200a42002008420010e80820024180016a200842002001420010e8082009420052200a4200527120022903684200527220022903784200527220024180016a41086a2903002208200229036020022903707c7c2209200854720d0220022903800121080b200441034b210c20044101762104200a210a200c0d000c020b0b427f2108427f21090b200241d0006a20082009428094ebdc03420010e608200241306a2005290300220a42002008420010e808200241206a2009420020022903d8012201420010e808200241c0006a200142002008420010e8080240024020062d0000450d00420021010c010b2002290338210e2002290328210f2002290320211020022903302111200241c0006a41086a2903002101200728020021042002290350210320022903402112200241106a20082009428094ebdc03420010e70820022002290310200241106a41086a2903002004ad2208420010e808427f200241086a29030020022903002213200320087e2208428094ebdc0380a7417f2008428080808080c0b2cd3b541b2008428094ebdc03824280cab5ee01566aad7c2208201354ad7c2203427f2001201120107c7c2210200a420052200942005271200e42005272200f4200527220102001547222041b7c2008427f201220041b7c220a2008542204ad7c22012004200120035420012003511b22041b2101427f200a20041b21030b2000200337030020002001370308200241c0026a24000ba10204017f017e017f027e230041d0006b220224002002412036020420022001360200200241086a2001412010ed0202400240200228020822010d00420021030c010b200228020c210402400240200241086a41086a2802004110490d00200141086a290000210520012900002106420121030c010b20024100360220200242013703182002410a36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241909dc5003602382002200241286a360248200241346a419cebc000200241386a103d1a2002280218200228022010ef020240200228021c450d002002280218102e0b420021030b2004450d002001102e0b2000200637030820002003370300200041106a2005370300200241d0006a24000bcd3607017f017e017f027e017f017e1b7f230041e0026b220724000240024002402001200284500d0020032004844200520d010b20004100360200200041106a4200370300200041086a42003703000c010b42012108200741f0006a200320012003200156200420025620042002511b22091b220a2004200220091b220b20054201200542015620064200522006501b220c1b220d20064200200c1b220510e6082002200420091b21022001200320091b21040240024002402007290370200741f0006a41086a29030084500d00200741e0006a20042002200d200510e6082007290360200741e0006a41086a29030084500d01200d21080c020b200741c0006a200a200b200d200510e708200741c0006a41086a290300210b420021052007290340210a0c010b200741d0006a20042002200d200510e708200741d8006a29030021024200210542012108200729035021040b200741106a200b42002004420010e808200741206a20024200200a420010e808200741306a200a42002004420010e8080240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200b420052200242005271200729031842005272200729032842005272200741306a41086a2903002201200729031020072903207c7c2203200154724101470d004110102c2209450d192009200a3e020c2009200a4220883e02082009200b3e02042009200b4220883e020020074284808080c00037028401200720093602800120074180016a10bb074110102c2209450d19200920043e020c200920044220883e0208200920023e0204200920024220883e020020074284808080c00037029401200720093602900120074190016a10bb074110102c2209450d1920092008a7220e36020c200920084220883e0208200920053e0204200920054220883e020020074284808080c0003702a401200720093602a001200741a0016a10bb07200741f0016a41086a20074190016a41086a28020036020020072007290390013703f00120074180026a41086a20074180016a41086a280200360200200720072903800137038002200741b0016a20074180026a200741f0016a10bc07024020072802f40141ffffffff0371450d0020072802f001102e0b200741b0016a10bb0720072802b801210920072802b401210f20072802b001211020072802a80122110e020501020b2007200729033020032008200510e70820004100360200200041106a200741086a290300370300200041086a20072903003703000c1b0b20094101200941014b1b221141ffffffff03712011470d162011410274220c417f4c0d1602400240200c0d00410421120c010b200c10322212450d180b200720113602d802200720123602d0022007200c4102763602d4022009450d182012201141027420094102746b6a210c410020096b2109200e4101200e41014b1bad2102420021042010210e03402011201120096a22124d0d02200c2004422086200e3502008422042002803e02002009417f460d19200e41046a210e200c41046a210c200941016a2109200420028221040c000b0b20072802a00122132802000d010c020b2012201141ecd8cc00103c000b2009450d032010280200450d00200920114d0d00200720113602bc01200920116b221441016a22154101201541014b1b221641ffffffff03712016470d1320164102742217417f4c0d1320170d01410421180c020b410021180240200f41ffffffff03710d000c070b2010102e0c060b201710322218450d120b20114101201141014b1b221941ffffffff03712019470d102019410274221a417f4c0d10201a1032221b450d11410121124102210c024002400240201328020067221c0e020201000b4102210c201c210e410121120340200c4101200e4101711b20126c2112200e41034b211d200c200c6c210c200e410176210e201d0d000b0b200c20126c21120b200720093602f8012007200f3602f401200720103602f0014104102c2209450d11200920123602002007428180808010370284022007200936028002200741c0016a200741f0016a20074180026a10bc072009102e201141ffffffff03712011470d1020114102742209417f4c0d104104210c02402009450d002009102c220c450d120b2007200c3602f001200720094102763602f401200c2013201141027410e9081a200720113602f8014104102c2209450d11200920123602002007428180808010370284022007200936028002200741d0016a200741f0016a20074180026a10bc072009102e201520072802bc016a220920072802c801220c4d0d032009200c6b220941ffffffff03712009470d1020094102742211417f4c0d100240024020110d004104210c0c010b2011102c220c450d120b02402011410276220e20094f0d002011410176220e2009200e20094b1b220e4104200e41044b1b220e41ffffffff0371200e464102742112200e410274210e0240024020110d0020074100360280020c010b20074188026a410436020020072011360284022007200c360280020b200741f0016a200e201220074180026a107d200741f8016a280200210e024020072802f0014101460d0020072802f401210c200e410276210e0c030b200e450d110c120b20090d01410021090c020b4100410041fcd8cc00103c000b200c4100200941027410eb081a0b20072802c001211002400240200e20096b20072802c8012211490d00200920116a21120c010b200920116a22122009490d0e200e410174220f2012200f20124b1b220f4104200f41044b1b220f41ffffffff0371200f46410274211d200f410274210f02400240200e0d0020074100360280020c010b20074188026a41043602002007200c360280022007200e410274360284020b200741f0016a200f201d20074180026a107d200741f8016a280200210e024020072802f0014101460d0020072802f401210c200e410276210e0c010b200e0d0f0c0e0b200c20094102746a2010201141027410e9081a024020072802c40141ffffffff0371450d0020072802c001102e0b200720123602c8012007200e3602c4012007200c3602c0010b2017410276211e201a410276211f200741d0016a10bb0703402007201422203602dc01024020072802c801220920072802bc01220c20206a220e417f736a22112009490d002011200941ccd7cc00103c000b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020092009200e6b220e4d0d0020072802d80122092009200c6b220c4d0d0120072802d001200c4102746a35020022024200510d02202020204100476b211420072802c001220920114102746a35020021042009200e4102746a3502002101200741003602e0012007200120044220868422042002803703e801200720042002823703f801200741003602f0012007200741dc016a360294022007200741c0016a360290022007200741bc016a36028c022007200741d0016a360288022007200741f0016a360284022007200741e0016a3602800220074180026a10d7081a034020072802f001220941016a41004c0d04200720093602f001024020072903f80142ffffffff0f560d0020074180026a10d7080d010b0b20072903e80121024100210c02400240024020072802bc01221220072802dc01220e6a22092012490d00201241016a220c20124f0d00410421102007410436029802410021130c010b200c41ffffffff0371200c470d2b200c4102742211417f4c0d2b0240024020110d00410421100c010b2011102c2210450d2d0b2007201036029802201141027621134100210c2009200e490d0b201241016a220c20124f0d010b41002111410021124100210c034020072802c801220f2009417f736a221d200f4f0d06200e20094f210f2009200e2009496b210920072802c001201d4102746a280200211d02400240200c2013470d00200c417f41004100417f2009200e6b221341016a221720172013491b200f1b2009200e491b221341016a221720172013491b6a2213200c490d2d20122013201220134b1b22134104201341044b1b221341ffffffff037120134641027421172013410274211302400240200c0d00200741003602d0020c010b200741043602d802200720113602d402200720103602d0020b200741c0026a20132017200741d0026a107d20072802c802211320072802c0024101460d01200720072802c402221036029802201341027621130b201020116a201d360200201141046a2111201241026a2112200c41016a210c2009200e49200f72450d010c0c0b0b20130d2b0c2a0b02402013200c4f0d002011410176220f200c200f200c4b1b220c4104200c41044b1b220c41ffffffff0371200c46410274210f200c410274210c0240024020110d00200741003602d0020c010b200741043602d802200720113602d402200720103602d0020b200741c0026a200c200f200741d0026a107d20072802c802210c20072802c0024101460d07200720072802c402221036029802200c41027621130b200e20094f0d072009417f73210c0340200c20072802c801220f6a2211200c4f0d06201020072802c00120114102746a280200360200200c41016a210c201041046a2110200e2009417f6a2209490d000b2012210c0c080b200e200941ccd7cc00103c000b200c200941ccd7cc00103c000b4190d9cc00411941acd9cc001039000b41bcd9cc004118200741d0026a41d4d9cc0041e4d9cc00103e000b201d200f41ccd7cc00103c000b2011200f41ccd7cc00103c000b200c0d230c220b4100210c20120d010b20072802c8012209200e417f736a220e20094f0d01201020072802c001200e4102746a280200360200200c41016a210c0b20072802d801220e41ffffffff0371200e470d1f200e4102742209417f4c0d1f20072802d00121120240024020090d00410421110c010b2009102c2211450d210b200720113602c002200720094102763602c40220112012200910e9081a2007200e3602c8024108102c2209450d2020092002a72221360204200920024220883e020020074282808080203702d402200720093602d002200741a0026a200741c0026a200741d0026a10bc072009102e200c20072802a8022222200c20224b1b220f4101200f41014b1b221041ffffffff03712010470d1f20104102742223417f4c0d1f20072802980221240240024020230d00410421250c010b202310322225450d210b02400240200f0d004100211d0c010b2010417f6a210e2022417f6a222620224b2117200c417f6a2227200c4b2115202520236a417c6a2111410021124200210420072802a0022128034041002109024020150d0041002109200c202720126b221d4d0d0041002109201d20274b0d002024201d4102746a28020021090b2009ad210241002109024020170d002022202620126b221d4d0d00201d20264b0d002028201d4102746a28020021090b0240024020022009ad22067d22032002560d00200320047d22012003560d00420021044100211d0c010b20024280808080108420047d20067d2101420121044101211d0b2010200e4d0d03201120013e02002011417c6a2111200e417f6a210e200f201241016a2212470d000b0b0240201341ffffffff0371450d002024102e0b20072802bc01220e20072802dc01220c6a2213200e490d06200c20134f0d04200c417f732109034020102010200c6a20096a22114d0d03200920072802c80122126a220c20094f0d0420072802c001200c4102746a202520114102746a2802003602002009417f6a210920072802dc01210c200e417f6a220e0d000c060b0b200e200941ccd7cc00103c000b200e201041ecd8cc00103c000b200f4101200f41014b1b200c6a20096a201041ccd7cc00103c000b200c201241ecd8cc00103c000b200e0d010b200c2013417f7322096a220c20106a220e200c4f0d0120072802c801220c20096a2209200c4f0d0220072802c00120094102746a2025200e4102746a28020036020020072802dc01210c0b2016200c417f736a220920164f0d02201820094102746a2021360200201d450d0a201620072802dc01417f736a220920164f0d03201820094102746a22092009280200417f6a3602004100210c02400240024020072802bc01221220072802dc01220e6a22092012490d00201241016a220c20124f0d0041042110200741043602bc02410021130c010b200c41ffffffff0371200c470d1a200c410274220c417f4c0d1a02400240200c0d00410421100c010b200c102c2210450d1c0b200720103602bc02200c410276211302402009200e4f0d004100210c0c0c0b201241016a221120124f0d010b41002111410021124100210c034020072802c801220f2009417f736a221d200f4f0d06200e20094f210f2009200e2009496b210920072802c001201d4102746a280200211d02400240200c2013470d00200c417f41004100417f2009200e6b221341016a221720172013491b200f1b2009200e491b221341016a221720172013491b6a2213200c490d1c20122013201220134b1b22134104201341044b1b221341ffffffff037120134641027421172013410274211302400240200c0d00200741003602d0020c010b200741043602d802200720113602d402200720103602d0020b200741c0026a20132017200741d0026a107d20072802c802211320072802c0024101460d01200720072802c40222103602bc02201341027621130b201020116a201d360200201141046a2111201241026a2112200c41016a210c2009200e49200f72450d010c0c0b0b20130d1a0c190b0240201320114f0d00200c410176220f2011200f20114b1b22114104201141044b1b221141ffffffff0371201146410274210f2011410274211102400240200c0d00200741003602d0020c010b200741043602d8022007200c3602d402200720103602d0020b200741c0026a2011200f200741d0026a107d20072802c802210c20072802c0024101460d07200720072802c40222103602bc02200c41027621130b200e20094f0d072009417f73210c0340200c20072802c801220f6a2211200c4f0d06201020072802c00120114102746a280200360200200c41016a210c201041046a2110200e2009417f6a2209490d000b2012210c0c080b200e201041ccd7cc00103c000b2009200c41ecd8cc00103c000b2009201641ecd8cc00103c000b2009201641ccd7cc00103c000b201d200f41ccd7cc00103c000b2011200f41ccd7cc00103c000b200c0d120c110b4100210c20120d010b20072802c8012209200e417f736a220e20094f0d04201020072802c001200e4102746a280200360200200c41016a210c20072802bc0221100b2007200c3602b802200720133602b402200720103602b00220072802d801220c41ffffffff0371200c470d0e200c4102742209417f4c0d0e20072802d00121110240024020090d004104210e0c010b2009102c220e450d100b2007200e3602d002200720094102763602d402200e2011200910e9081a2007200c3602d802200741c0026a200741d0026a200741b0026a10d608024020072802bc01220920072802dc01220f6a220c2009490d0002400240200f200c4f0d00200c417f73210920072802c002211d20072802c802210e200f21110340200e200e20116a20096a22114d0d08200920072802c80122176a221220094f0d0920072802c00120124102746a201d20114102746a280200360200200941016a210920072802dc012111200f200c417f6a220c490d000c020b0b20090d0120072802c802210e200f21110b200e2011200f417f7322096a6a220c200e4f0d0720072802c801220e20096a2209200e4f0d0820072802c00120094102746a20072802c002200c4102746a2802003602000b024020072802c40241ffffffff0371450d0020072802c002102e0b201341ffffffff0371450d002010102e0b02402023450d002025102e0b024020072802a40241ffffffff0371450d0020072802a002102e0b20200d000b02400240201c450d00024020072802bc0122094101460d00410020096b2110201c411f71210f4100201c6b411f71211d2019410274201b6a417c6a210c417f21090340200920072802c80122116a220e20094f0d0c2011200e417f6a22124d0d0d2019201920096a22114d0d0e200c20072802c001221120124102746a280200201d742011200e4102746a280200200f7672360200200c417c6a210c20102009417f6a2209470d000b20072802bc0121090b20072802c801220c200c20096b220e4d0d082019201920096b22094d0d09201b20094102746a20072802c001200e4102746a280200201c411f717636020041012109201b210e0c010b4100210920072802c801211920072802c401211f20072802c001210e201a450d00201b102e0b024020072802d40141ffffffff0371450d0020072802d001102e0b2009450d0020072802c40141ffffffff0371450d0020072802c001102e0b4104102c2209450d0c200941003602004104102c220c450d0c200c41003602000240024020180d00410121194101211f410121164101211e0c010b2009102e200c102e200e210c201821090b200720163602e8012007201e3602e401200720093602e001200720193602f8012007201f3602f4012007200c3602f00120074180026a200741f0016a10d5082007280280024101460d0a024020074180026a41086a29030020084201882005423f86845820074180026a41106a2903002202200542018822045820022004511b0d00200741f0016a41086a200741e0016a41086a280200360200200720072903e0013703f0014110102c2209450d0d20094280808080103702082009420037020020074284808080c00037028402200720093602800220074180026a10bb07200741e0016a200741f0016a20074180026a10d60820072802840241ffffffff0371450d00200728028002102e0b200741d0026a41086a200741e0016a41086a280200360200200720072903e0013703d0020c0e0b200e200941ccd7cc00103c000b2011200e41ccd7cc00103c000b2012201741ecd8cc00103c000b200c200e41ccd7cc00103c000b2009200e41ecd8cc00103c000b200e200c41ccd7cc00103c000b2009201941ecd8cc00103c000b200e201141ccd7cc00103c000b200e417f6a201141ccd7cc00103c000b2011201941ecd8cc00103c000b20072007290284023703f00141f8dbcc00412f200741f0016a41a8dccc0041b8dccc00103e000b1038000b1036000b200f41ffffffff0371450d002010102e0b200741d0026a10bb07200741f0016a41086a200741d0026a41086a280200360200200720072903d0023703f00120074180026a200741f0016a10d50841012109024002402007280280024101470d00200041c8dccc00360204200041086a41193602000c010b200041106a20074180026a41106a290300370300200041086a20074180026a41086a290300370300410021090b2000200936020020072802a40141ffffffff0371450d0020072802a001102e0b200741e0026a24000ba40201037f230041c0006b22022400200241206a22034200370300200241186a22044200370300200241086a41086a420037030020024200370308200241086a41d9fcc6004106108102200241286a41e8f7cb00410e1081022003200241286a41086a290000370300200420022900283703004100210320024100360230200242013703280240024002400240024020000e03000102040b200241003a003c200241286a2002413c6a410110742002200136023c200241286a2002413c6a410410740c020b200241013a003c200241286a2002413c6a410110740c010b200241023a003c200241286a2002413c6a410110740b200228022c21030b200241086a412020022802282200200228023010b20102402003450d002000102e0b200241c0006a24000bc30201037f230041c0006b22022400200241206a22034200370300200241186a22044200370300200241086a41086a420037030020024200370308200241086a41a5fec600411a108102200241286a41c8c3c800410c1081022003200241286a41086a29000037030020042002290028370300200241003602302002420137032802400240024002402000417e6a22034102200341ff01714102491b41ff01710e03000102030b200241003a003c200241286a2002413c6a410110740c020b200241013a003c200241286a2002413c6a410110740c010b200241023a003c200241286a2002413c6a41011074200220003a003c200241286a2002413c6a410110742002200136023c200241286a2002413c6a410410740b200241086a412020022802282200200228023010b2010240200228022c450d002000102e0b200241c0006a24000bdf0203027f027e017f230041c0006b2201240020002d001021022000290308210320002903002104200141086a41186a22004200370300200141186a22054200370300200141086a41086a420037030020014200370308200141086a41a8f8c6004104108102200141286a41aa8cc50041181081022000200141286a41086a290000370300200520012900283703002001410036023020014201370328200141013a0038200141286a200141386a4101107420012004370338200141286a200141386a4108107420012003370338200141286a200141386a41081074024002400240024020020e03000102030b200141003a0038200141286a200141386a410110740c020b200141013a0038200141286a200141386a410110740c010b200141023a0038200141286a200141386a410110740b200141086a412020012802282200200128023010b2010240200128022c450d002000102e0b200141c0006a24000bc10201047f230041c0006b22012400200141186a22024200370300200141106a22034200370300200141086a420037030020014200370300200141d9fcc6004106108102200141206a41b4f4cb0041061081022002200141206a41086a29000037030020032001290020370300024002402000280208220341246c41046a2202417f4c0d00200028020021000240024020020d00410121040c010b2002102c2204450d020b2001410036023820012002360234200120043602302003200141306a10760240200341246c2202450d000340200141206a200010ef04200141306a200128022022032001280228107402402001280224450d002003102e0b200041246a21002002415c6a22020d000b0b2001412020012802302200200128023810b20102402001280234450d002000102e0b200141c0006a24000f0b1038000b1036000bbe0401027f230041106b220224000240024002400240024002400240024020012d00000e06010402030500010b2000410036020820004201370200200241003a00002000200241011074200141046a28020021032001410c6a28020022012000107620002003200110740c050b2000410036020820004201370200200241023a000020002002410110744120102c2203450d0520024220370204200220033602002002200141016a41201074200020022802002201200228020810742002280204450d042001102e0c040b2000410036020820004201370200200241043a000020002002410110742000200141016a41041074200141086a2802002103200141106a28020022012000107620002003200110740c030b2000410036020820004201370200200241053a000020002002410110742000200141016a41041074200141086a2802002103200141106a28020022012000107620002003200110740c020b2000410036020820004201370200200241063a000020002002410110742000200141016a41041074200141086a2802002103200141106a28020022012000107620002003200110740c010b2000410036020820004201370200200241073a00002000200241011074200241003a000020002002410110740240200141046a2802004101460d00200241003a000020002002410110740c010b200241013a000020002002410110742002200141086a280200360200200020024104107420022001410c6a28020036020020002002410410740b200241106a24000f0b1036000bbd0101037f230041306b22012400200141186a22024200370300200141106a22034200370300200141086a420037030020014200370300200141d9fcc6004106108102200141206a41a0f4cb00410a1081022002200141206a41086a2900003703002003200129002037030002404120102c2202450d002001422037022420012002360220200141206a2000412010742001412020012802202200200128022810b20102402001280224450d002000102e0b200141306a24000f0b1036000bd50302087f017e230041f0006b22022400200241c0006a41186a22034200370300200241c0006a41106a22044200370300200241c0006a41086a2205420037030020024200370340200241e0006a41d9fcc60041061081022005200241e0006a41086a220629000037030020022002290060370340200241e0006a41d4f2cb00410b1081022003200629000037030020042002290060370300200241206a200241c0006a10f204200220022903284200200229032042015122071b3703182002200241206a41106a2208290300420020071b3703102002200241206a41186a2209290300420020071b370308200241086a2107024002400240200141ff01710e03010002010b200241106a21070c010b200241186a21070b2007427f2007290300220a20007c22002000200a541b3703002009200229030837030020082002290310370300200220022903183703282002420137032020034200370300200442003703002005420037030020024200370340200241e0006a41d9fcc60041061081022005200629000037030020022002290060370340200241e0006a41d4f2cb00410b108102200441086a200629000037000020042002290060370000200241c0006a200241206a41086a10f304200241f0006a24000bbb0202037f017e230041d0006b220224002002412036020420022001360200200241086a2001412010ed0202400240200228020822010d00200042003703000c010b200228020c2103024002400240200241086a41086a28020022044108490d00200441787141786a0e09000101010101010100010b20024100360220200242013703182002410a36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241909dc5003602382002200241286a360248200241346a419cebc000200241386a103d1a2002280218200228022010ef020240200228021c450d002002280218102e0b420021050c010b200041186a2001290010370300200041106a200129000837030020002001290000370308420121050b200020053703002003450d002001102e0b200241d0006a24000b8c0101017f230041206b22022400200241003602102002420137030820022001290300370318200241086a200241186a4108107420022001290308370318200241086a200241186a4108107420022001290310370318200241086a200241186a410810742000412020022802082201200228021010b2010240200228020c450d002001102e0b200241206a24000bb80301067f230041f0006b22012400200141186a22024200370300200141106a22034200370300200141086a420037030020014200370300200141a5fec600411a108102200141d8006a41c8c3c800410c1081022002200141d8006a41086a290000370300200320012900583703002001412036022420012001360220200141286a2001412010ed0202400240200128022822040d00410421020c010b200128022c2105024002400240200141286a41086a2802002206450d00410221020240024020042d00000e03040001020b410321020c020b20064101460d00410021020240024020042d00010e020100020b410121020b2006417e6a4104490d00200428000221030c020b20014100360240200142013703382001410a36024c2001200141206a3602482001200141386a360254200141ec006a41013602002001420137025c200141909dc5003602582001200141c8006a360268200141d4006a419cebc000200141d8006a103d1a2001280238200128024010ef020240200128023c450d002001280238102e0b410421020b0b2005450d002004102e0b2000200336020420004102200220024104461b3a0000200141f0006a24000bc50d04077f017e097f037e230041c0026b22012400200141306a22024200370300200141286a22034200370300200141186a41086a420037030020014200370318200141186a41a5fec600411a108102200141d8016a41c8c4c80041081081022002200141d8016a41086a290000370300200320012900d8013703002001412036023c2001200141186a360238200141c0006a200141186a412010ed0202400240200128024022040d00410021050c010b200128024421062001200141c0006a41086a28020036025420012004360250200141106a200141d0006a10ab010240024020012802100d000240024020012802142207200128025441386e2202200220074b1bad42387e2208422088a70d002008a72202417f4c0d0002400240024020020d00410821050c010b2002102c2205450d010b200241386e21090240024020070d00410021070c010b4100210a4100210b0340200141003a00f801200b220c41016a210b2001280254210d417f210341002102024002400340200d2002460d01200141d8016a20026a2001280250220e2d00003a00002001200d20036a3602542001200e41016a3602502001200241016a220f3a00f8012003417f6a2103200f2102200f4120470d000b200141a0026a41186a2202200141d8016a41186a290300370300200141a0026a41106a2203200141d8016a41106a290300370300200141a0026a41086a2210200141d8016a41086a290300370300200120012903d8013703a002200f41ff01714120490d06200141b8016a41086a22112010290300370300200141b8016a41106a22102003290300370300200141b8016a41186a22032002290300370300200120012903a0023703b801200d200f6b22024108490d06200e29000121122001200e41096a3602502001200241786a360254200141086a200141d0006a10ab012001280208450d01200141003602d8010c060b200241ff0171450d05200141003a00f8010c050b200141d8016a200141d0006a200128020c10920120012802d801220f450d0420014198016a41186a2003290300220837030020014198016a41106a20102903002213370300200141f8006a41086a20112903002214370300200141f8006a41106a2013370300200141f8006a41186a2008370300200141d8006a41186a22032008370300200141d8006a41106a220d2013370300200141d8006a41086a220e2014370300200120012903b80122083703782001200837035820012902dc0121080240200c2009470d00200941016a22022009490d04200941017422102002201020024b1b22024104200241044b1bad42387e2213422088a74541037421022013a721100240024020090d00200141003602d8010c010b200141083602e001200120053602d8012001200941386c3602dc010b200141a0026a20102002200141d8016a107d20012802a8022102024020012802a0024101470d0020020d040c050b20012802a4022105200241386e21090b2005200c41386c6a2202201237030020022001290358370308200241106a200e290300370300200241186a200d290300370300200241206a20032903003703002002412c6a20083702002002200f360228200a41386a210a200b2007470d000b0b2005450d032001200141d0006a10ab010240024002402001280200450d00200141003602d8010c010b200141d8016a200141d0006a200128020410920120012802d8010d010b02402007450d002005200741386c6a210f200521020340200241386a210302402002412c6a28020041ffffff3f71450d00200241286a280200102e0b20032102200f2003470d000b0b024020090d00410021090c050b200941386c450d042005102e0c040b200141a0026a41086a200141d8016a41086a280200360200200120012903d8013703a0020c040b1036000b1038000b200141f8006a41186a20014198016a41186a2903003703000240200c450d002005412c6a210203400240200228020041ffffff3f71450d002002417c6a280200102e0b200241386a2102200a41486a220a0d000b0b2009450d00200941386c21022002450d002005102e0b41002105200141003602a802200142013703a0022001410a360284022001200141386a360280022001200141a0026a3602b801200141ec016a4101360200200142013702dc01200141909dc5003602d801200120014180026a3602e801200141b8016a419cebc000200141d8016a103d1a20012802a00220012802a80210ef0220012802a402450d0020012802a002102e0b2006450d002004102e0b200041086a200736020020002009360204200020053602002000410c6a20012903a002370200200041146a200141a0026a41086a280200360200200141c0026a24000b340020004199fdc60036020420004100360200200041146a4104360200200041106a41b08dc500360200200041086a42083702000b2e01017f02404104102c22020d001036000b200042043702042000200236020041002000107620004101410010740b2f01017f02404104102c22020d001036000b200042043702042000200236020041002000107641044100200010a0010b950101027f230041f0006b22022400200241c8006a410036020002404101102c2203450d002000420137020420002003360200200241003a006f2000200241ef006a41011074024020022802482200450d000240200241cc006a2802002203450d00200341306c450d002000102e0b200241dc006a28020041ffffff3f71450d002002280258102e0b200241f0006a24000f0b1036000b150020002002ad4220862001ad842003100a4101460bb60201067f024002402001280200220228020422030d00410121030c010b200228020022042d0000210520022003417f6a360204410121032002200441016a3602000240200541037122024103470d000c010b024002400240024020020e03000102000b200541027621020c020b02402001280200220228020422010d000c030b200228020022032d0000210420022001417f6a3602042002200341016a360200200441087420057241ffff03712202418002492103200241027621020c020b024020012802002202280204220141034f0d000c020b2002280200220441026a2d0000210620042f000021072002200441036a36020020022001417d6a360204200720064110747241087420057222014180807c6a41ffff0b4b0d01200141027621020b410021030b200020023b0102200020033b01000b950201067f02400240200128020422020d00410121030c010b200128020022042d0000210520012002417f6a2206360204410121032001200441016a3602000240200541037122074103470d000c010b024002400240024020070e03000102000b200541027621010c020b024020060d000c030b20042d0001210320012002417e6a3602042001200441026a360200200341087420057241ffff03712201418002492103200141027621010c020b0240200641034f0d000c020b200441036a2d0000210720042f0001210620012002417c6a3602042001200441046a360200200620074110747241087420057222024180807c6a41ffff0b4b0d01200241027621010b410021030b200020013b0102200020033b01000be10101027f230041106b2202240002400240024020002f0100220341c000490d00200341808001490d012002200341027441027236020020012002410410740c020b200220034102743a00052001200241056a410110740c010b200220034102744101723b01062001200241066a410210740b02400240024020002f0102220041c000490d00200041808001490d01200220004102744102723602082001200241086a410410740c020b200220004102743a00052001200241056a410110740c010b200220004102744101723b010e20012002410e6a410210740b200241106a24000b340020004180fdc60036020420004100360200200041146a4102360200200041106a41ac97c500360200200041086a42123702000b4e01027f230041106b2202240002404110102c22030d001036000b200042103702042000200336020020024200370308200242808090bbbad6adf00d3703002000200241101074200241106a24000b1300200041023602042000419899c5003602000bc60202057f017e230041f0006b220224004280c2d72f42004280f985d40442001082052103200241106a22044200370300200241086a42003703002002411c6a22054180023b0100200241186a22062003360200200242003703002002410136026802404118102c2203450d0020032002290308370300200320022d001d3a00152003200429030037030820032006280200360210200320052d00004100473a00140240200228026822044105490d00200441186c450d002002280204102e0b411c102c2204450d002000421c37020420002004360200410120001076200329030021072002200341086a290300370308200220073703002000200241101074200220032802103602002000200241041074200220032d00143a00002000200241011074200220032d00153a000020002002410110742003102e200241f0006a24000f0b1036000bb10302027f037e230041d0006b22042400200441386a20024201200242015620034200522003501b22051b22022003420020051b2203428094ebdc03420010e708200441286a20022003428094ebdc03420010e608200441186a20022003200429033822062004290328200441286a41086a29030084420052ad7c220742012007420156200441386a41086a2903002007200654ad7c22074200522007501b22051b22062007420020051b220810e70802400240024020042903182207428080808010544100200441186a41086a290300501b450d00200441086a200220002002200054200320015420032001511b22051b2003200120051b2006200810e70820042903082203428080808010544100200441086a41086a290300501b450d012007a70d0241d0d8c800411941bcd7cc001039000b2004411136024c2004419cd5cc0036024841add5cc0041de00200441c8006a41bcdcc80041bcd7cc00103e000b2004411136024c2004419cd5cc0036024841add5cc0041de00200441c8006a41bcdcc80041bcd7cc00103e000b200441d0006a2400200342ffffffff0f83428094ebdc037e200742ffffffff0f8380a70b4801027f230041106b2202240002404110102c22030d001036000b200042103702042000200336020020024200370308200242c0843d3703002000200241101074200241106a24000b4d01017f230041206b22002400200041146a4101360200200042013702042000419cc3cb003602002000410436021c20004194c3cb003602182000200041186a360210200041889cc5001044000b840707017f047e027f017e047f057e037f23004180026b22022400200241c0006a200110db040240024002402002290340a70d00200241c0006a41106a290300210320022903482104200241286a200110db0402402002290328a70d00200241286a41106a290300210520022903302106200241206a200110ab01024020022802200d000240024020022802242207200128020441306e2208200820074b1bad42307e2209422088a70d002009a72208417f4c0d000240024020080d004108210a0c010b2008102c220a450d060b200841306ead2109024002402007450d00200241d8016a410172210b0340200241d8016a200110930120022d00d8014101460d04200241b8016a41186a2208200b41186a290000370300200241b8016a41106a220c200b41106a290000370300200241b8016a41086a220d200b41086a2900003703002002200b2900003703b801200241086a200110db042002290308a70d04200241086a41106a290300210e2002290310210f200241f8006a41086a200d2903002210370300200241f8006a41106a200c2903002211370300200241f8006a41186a20082903002212370300200241d8006a41086a220d2010370300200241d8006a41106a22132011370300200241d8006a41186a22142012370300200220022903b80122103703782002201037035802402009422088a7220c2009a7470d00200c41016a2208200c490d04200c4101742215200820082015491b22084104200841044b1bad42307e2209422088a74541037421082009a7211502400240200c0d00200241003602d8010c010b200241083602e0012002200a3602d8012002200c41306c3602dc010b200241b8016a20152008200241d8016a107d20022802c001210820022802b8014101460d0320022802bc01210a200841306ead21090b200a200c41306c6a2208200e3703082008200f37030020082002290358370310200841186a200d290300370300200841206a2013290300370300200841286a2014290300370300200942ffffffff0f83200c41016aad4220868421092007417f6a22070d000b0b200a450d0320002004370300200020093702242000200a3602202000200637031020002003370308200041186a20053703000c070b20080d050b1038000b2009a72201450d00200141306c450d00200a102e0b200041003602200c030b200041003602200c020b200041003602200c010b1036000b20024180026a24000bb10201037f230041e0006b22022400200241086a4192fdc6004107108102200241186a41f09dc500410a108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000b830301057f230041e0006b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022040d00410221010c010b200328021421052003200341186a280200360224200320043602202003200341206a10ab010240024020032802000d00200328020421012003418094ebdc0336024c2003200136024820032802242206450d00200341c8006a2001418094ebdc034b4102746a2802002102200328022022012d0000210720032006417f6a3602242003200141016a36022041002101024020070e020200010b410121010c010b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341909dc5003602482003200341386a360258200341c4006a419cebc000200341c8006a103d1a2003280228200328023010ef020240200328022c450d002003280228102e0b410221010b2005450d002004102e0b200020013a000420002002360200200341e0006a24000b801301267f23004190046b220424000240024002402001280200220520012802044f0d00200441f7026a2106200441a4016a2107200441ac036a2108200441f0026a4101722109200441d1036a220a41036a210b03402001200541016a360200200441e0016a2005108905200441f0026a20042802e001220c20042802e801108a05200441d8036a41086a220d200941086a290000370300200441d8036a41106a220e200941106a290000370300200441d8036a41186a220f200941186a290000370300200441d8036a41206a2210200941206a290000370300200441d8036a41286a2211200941286a290000370300200441d8036a412f6a22122009412f6a29000037000020044188026a41086a2213200841086a29000037030020044188026a41106a2214200841106a29000037030020044188026a41186a2215200841186a29000037030020044188026a41206a2216200841206a280000360200200420092900003703d803200420082900003703880220042802a803211720042d00f00221182004200a2800003602782004200b28000036007b41022119024020184102460d0020042d00d003211a200441a0016a412f6a2012290000370000200441a0016a41286a2011290300370300200441a0016a41206a2010290300370300200441a0016a41186a200f290300370300200441a0016a41106a200e290300370300200441a0016a41086a200d290300370300200441c8026a41086a2013290300370300200441c8026a41106a2014290300370300200441c8026a41186a2015290300370300200441c8026a41206a2016280200360200200420042903d8033703a00120042004290388023703c8022004200428007b3600c302200420042802783602c002201821192017211b0b024020042802e401450d00200c102e0b200d200441a0016a41086a221c290300370300200e200441a0016a41106a221d290300370300200f200441a0016a41186a221e2903003703002010200441a0016a41206a221f2903003703002011200441a0016a41286a22202903003703002012200441a0016a412f6a290000370000200441f8006a41086a2221200441c8026a41086a2218290300370300200441f8006a41106a2222200441c8026a41106a220c290300370300200441f8006a41186a2223200441c8026a41186a2217290300370300200441f8006a41206a2224200441c8026a41206a2225280200360200200420042903a0013703d803200420042903c802370378200420042800c302360073200420042802c002360270200441f0026a41086a2226200d290300370300200441f0026a41106a2227200e290300370300200441f0026a41186a220e200f290300370300200441f0026a41206a220f2010290300370300200441f0026a41286a22102011290300370300200441f0026a412f6a2012290000370000200420042903d8033703f00220182021290300370300200c20222903003703002017202329030037030020252024280200360200200420042903783703c802200420042800733600c302200420042802703602c00202400240024020194102460d002019410171450d010b4103210d0c010b20072006290000370000200741286a200641286a290000370000200741206a200641206a290000370000200741186a200641186a290000370000200741106a200641106a290000370000200741086a200641086a290000370000200441e0016a41086a22112018290300370300200441e0016a41106a2212200c290300370300200441e0016a41186a22192017290300370300200441e0016a41206a22182025280200360200200420042903c8023703e0012013201c2902003703002014201d2902003703002015201e2902003703002016201f29020037030020044188026a41286a220c202029020037030020044188026a41306a2217200441a0016a41306a280200360200200420042800c3023600db01200420042802c0023602d801200420042902a001370388024103210d201a41ff01714103460d002026201329030037030020272014290300370300200e2015290300370300200f20162903003703002010200c290300370300200441f0026a41306a220d2017280200360200201c2011290300370300201d2012290300370300201e2019290300370300201f201828020036020020042004290388023703f002200420042903e0013703a001200420042800db013600cb02200420042802d8013602c8020240201b2003280200280200470d00200441386a41306a200d280200360200200441386a41286a2010290300370300200441386a41206a200f290300370300200441386a41186a200e290300370300200441386a41106a2027290300370300200441386a41086a2026290300370300200441106a41086a201c290300370300200441106a41106a201d290300370300200441106a41186a201e290300370300200441106a41206a201f280200360200200420042903f002370338200420042903a001370310200420042800cb0236000b200420042802c80236020820052128201b2129201a210d0c010b41002128200441386a41306a41002802b49e45360200200441386a41286a41002902ac9e45370300200441386a41206a41002902a49e45370300200441386a41186a410029029c9e45370300200441386a41106a41002902949e45370300200441386a41086a410029028c9e45370300200441106a41086a41002902c49e45370300200441106a41106a41002902cc9e45370300200441106a41186a41002902d49e45370300200441106a41206a41002802dc9e45360200200441002902849e45370338200441002902bc9e45370310200441002800e49e4536000b200441002800e19e453602084103210d410021290b200d41ff01714103470d02200128020022052001280204490d000b0b200041033a00600c010b2000202836020020002004290338370204200020293602382000200429031037023c2000410c6a200441386a41086a290300370200200041146a200441386a41106a2903003702002000411c6a200441386a41186a290300370200200041246a200441386a41206a2903003702002000412c6a200441e0006a290300370200200041346a200441e8006a280200360200200041c4006a200441106a41086a290300370200200041cc006a200441106a41106a290300370200200041d4006a200441106a41186a290300370200200041dc006a200441106a41206a2802003602002004200428000b360003200420042802083602002000200d3a006020002004280200360061200041e4006a20042800033600000b20044190046a24000b850201037f230041d0006b22022400200241086a41de80ca004109108102200241186a41e780ca004110108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000bfc0f05057f017e027f057e037f230041d0016b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822010d00200041023a00000c010b200328020c210202400240200341106a2802002204450d002004417f6a21050240024002400240024020012d00000e020001050b20054104490d0420012800012106200341003a00880120044105460d0420012d00052105200341013a008801200320053a006820044106470d010c030b2005450d03410021050240024020012d00010e020100050b410121050b2004417e6a4104490d03200341206a41086a200341e8006a41086a290300370300200341206a41106a200341e8006a41106a290300370300200341206a41186a200341e8006a41186a290300370300200320032903683703202003200328009001360218200320034193016a28000036001b20012800022107410121040c010b20012d00062105200341023a008801200320053a006920044107460d0120012d00072105200341033a008801200320053a006a20044108460d0120012d00082105200341043a008801200320053a006b20044109460d0120012d00092105200341053a008801200320053a006c2004410a460d0120012d000a2105200341063a008801200320053a006d2004410b460d0120012d000b2105200341073a008801200320053a006e2004410c460d0120012d000c2105200341083a008801200320053a006f2004410d460d0120012d000d2105200341093a008801200320053a00702004410e460d0120012d000e21052003410a3a008801200320053a00712004410f460d0120012d000f21052003410b3a008801200320053a007220044110460d0120012d001021052003410c3a008801200320053a007320044111460d0120012d001121052003410d3a008801200320053a007420044112460d0120012d001221052003410e3a008801200320053a007520044113460d0120012d001321052003410f3a008801200320053a007620044114460d0120012d00142105200341103a008801200320053a007720044115460d0120012d00152105200341113a008801200320053a007820044116460d0120012d00162105200341123a008801200320053a007920044117460d0120012d00172105200341133a008801200320053a007a20044118460d0120012d00182105200341143a008801200320053a007b20044119460d0120012d00192105200341153a008801200320053a007c2004411a460d0120012d001a2105200341163a008801200320053a007d2004411b460d0120012d001b2105200341173a008801200320053a007e2004411c460d0120012d001c2105200341183a008801200320053a007f2004411d460d0120012d001d2105200341193a008801200320053a0080012004411e460d0120012d001e21052003411a3a008801200320053a0081012004411f460d0120012d001f21052003411b3a008801200320053a00820120044120460d0120012d002021052003411c3a008801200320053a00830120044121460d012003411d3a008801200320012d00213a00840120044122460d012003411e3a008801200320012d00223a00850120044123460d012003411f3a008801200320012d00233a00860120044124460d01200341c8006a41106a200341e8006a41106a290300370300200341c8006a41086a200341e8006a41086a290300370300200320012d00243a008701200341c8006a41186a200341e8006a41186a290300370300200341203a008801200320032903682208370390012003200837034820044125460d024100210902400240024020012d00250e03020100050b410221090c010b410121090b2004415a6a4104490d02200441566a4110490d02200441466a4110490d02200441b67f6a410f4d0d022001280026210a200341206a41086a200341c8006a41086a290300370300200341206a41106a200341c8006a41106a290300370300200341206a41186a200341c8006a41186a29030037030020032003290348370320200320032800413602182003200341c4006a28000036001b200141d2006a2900002108200141c2006a290000210b200141326a290000210c200129004a210d200129003a210e200129002a210f410021040b200341e8006a41186a2210200341206a41186a290300370300200341e8006a41106a2211200341206a41106a290300370300200341e8006a41086a2212200341206a41086a2903003703002003200329032037036820032003280218360290012003200328001b36009301200041306a2008370000200041286a200d370000200041206a200b370000200041186a200e370000200041106a200c370000200041086a200f3700002000413c6a200a360000200041386a2006360000200041046a2007360000200020053a0001200041e0006a20093a0000200041c0006a2003290368370000200041c8006a2012290300370000200041d0006a2011290300370000200041d8006a2010290300370000200041e1006a200328029001360000200041e4006a2003280093013600000c020b200341003a0088010b200341003602980120034201370390012003410a36024c20032003360248200320034190016a360220200341fc006a41013602002003420137026c200341909dc5003602682003200341c8006a360278200341206a419cebc000200341e8006a103d1a20032802900120032802980110ef020240200328029401450d00200328029001102e0b410221040b200020043a00002002450d002001102e0b200341d0016a24000b130020002002ad4220862001ad84102610da080bbe0303057f017e037f230041306b22022400200241086a200128020c200141146a280200108b050240024020022802082203450d00200141086a2104200141106a2105024003400240024020042802002206200229020c2207422088a722084b0d0020012802002003200610ec08450d010b2007a7450d032003102e0c030b02402005280200450d00200128020c102e0b2001200336020c20052007370200200241086a2003200810ed020240024020022802082203450d0020022802102109200228020c2108024020012d001c450d00200128020c200128021410ff010b2001280214220a20042802002206490d03200241086a200128020c20066a200a20066b20032009200128021811050020022d002c4102470d012008450d002003102e0b200241086a200128020c2001280214108b05200228020822030d010c030b0b20002002290308370200200041206a200241086a41206a290300370200200041186a200241086a41186a290300370200200041106a200241086a41106a290300370200200041086a200241086a41086a2903003702002008450d022003102e0c020b2006200a41e89ec5001056000b200041023a00240b200241306a24000be30303057f017e037f230041c0006b22022400200241086a200128020c200141146a280200108b050240024020022802082203450d00200141086a2104200141106a2105024003400240024020042802002206200229020c2207422088a722084b0d0020012802002003200610ec08450d010b2007a7450d032003102e0c030b02402005280200450d00200128020c102e0b2001200336020c20052007370200200241086a2003200810ed020240024020022802082203450d0020022802102109200228020c2108024020012d001c450d00200128020c200128021410ff010b2001280214220a20042802002206490d03200241086a200128020c20066a200a20066b20032009200128021811050020022802340d012008450d002003102e0b200241086a200128020c2001280214108b05200228020822030d010c030b0b20002002290308370200200041306a200241086a41306a290300370200200041286a200241086a41286a290300370200200041206a200241086a41206a290300370200200041186a200241086a41186a290300370200200041106a200241086a41106a290300370200200041086a200241086a41086a2903003702002008450d022003102e0c020b2006200a41e89ec5001056000b2000410036022c0b200241c0006a24000bbe0301017f230041106b220224000240024020002d00004101460d00200241003a000f20012002410f6a41011074024002400240024002400240024002400240024020002d00010e0a000102030405060708090b0b200241003a000f20012002410f6a410110740c0a0b200241013a000f20012002410f6a410110740c090b200241023a000f20012002410f6a410110740c080b200241033a000f20012002410f6a410110740c070b200241043a000f20012002410f6a410110740c060b200241053a000f20012002410f6a410110740c050b200241063a000f20012002410f6a410110740c040b200241073a000f20012002410f6a410110742002200041026a2d00003a000f20012002410f6a410110740c030b200241083a000f20012002410f6a410110740c020b200241093a000f20012002410f6a410110740c010b200241013a000f20012002410f6a4101107402400240024020002d00010e03000102030b200241003a000f20012002410f6a410110740c020b200241013a000f20012002410f6a410110740c010b200241023a000f20012002410f6a410110742002200041026a2d00003a000f20012002410f6a410110740b200241106a24000b9c0101037f230041206b2202240020024100360208200242013703002001280200210302404120102c2204450d002002422037021420022004360210200241106a2003412010742002200228021022032002280218107402402002280214450d002003102e0b2002200128020441201074200020022802002201200228020810b00102402002280204450d002001102e0b200241206a24000f0b1036000baa0a01067f230041c0006b22022400024041ca03102c2203450d0020002003360200200041046a220442ca03370200200341003b000041022105200041086a4102360200024002400240200128020022032903684202520d00410221010240024020042802004102470d00200242828080801037021420022000280200360210200241306a41084101200241106a107d200241306a41086a280200210120022802304101460d0120002002280234360200200041046a2001360200200041086a28020021010b200028020020016a41043a0000200041086a2201200128020041016a3602000c020b2001450d020c030b02400240024002400240024020042802004102470d00200242828080801037021420022000280200360210200241306a41084101200241106a107d200241306a41086a280200210120022802304101460d0120002002280234360200200041046a2001360200200041086a28020021050b200341e8006a2101200028020020056a4184013a0000200041086a2204200428020041016a3602002003200010f50120032d00240e03010203040b20010d060c050b200241003a00102000200241106a410110742000200341256a41c00010740c020b200241013a00102000200241106a410110742000200341256a41c00010740c010b200241023a00102000200241106a410110742000200341256a41c10010740b200120001091050b20034198016a2000109002200041086a220128020021034104102c2204450d01200242043702042002200436020041012003417e6a220320034101461b410020031b2002107602402001280200220141014d0d00200241286a2002280200220320022802086a220436020020022000360220200041086a4100360200200241023602102002411c6a2000280200220541026a22063602002002200336022420022001417e6a220136021420022006360218200241246a21060240024020010d002000200610ee010c010b41002101034020032004460d012002200341016a360224200520016a20032d00003a00002000200028020841016a360208024020014101460d00200141016a210120022802242103200228022821040c010b0b0240200228022820022802246b2203450d00200241106a200310920520022802202200280208220320022802102201460d00200120036b2104200028020020036a21030340200228022422012002280228460d022002200141016a360224200320012d00003a00002000200028020841016a360208200341016a21032004417f6a22040d000b0b200228022820022802246b2203417f4c0d020240024020030d00410121010c010b2003102c2201450d040b200241003602382002200336023420022001360230200241306a200610ee012002280234210620022802302107024020022802382203450d00200241106a200310920520022802202204280208220120022802102200460d00200020016b2105200428020020016a21012007210003402003450d01200120002d00003a00002004200428020841016a3602082003417f6a2103200041016a2100200141016a21012005417f6a22050d000b0b2006450d002007102e0b02402002280218200228021c2203460d00200220033602180b024020022802142203450d000240200228021022042002280220220541086a22002802002201460d002005280200220520016a200520046a200310ea081a200228021421030b2000200320016a3602000b02402002280204450d002002280200102e0b200241c0006a24000f0b4102200141b4b3c000104d000b1038000b1036000baa0103017f027e017f230041106b220224000240024020002903004201520d002002200041106a290300200041086a2903002203420c882204420120044201561b80a741047420037aa7417f6a22054101200541014b1b2205410f2005410f491b723b01082001200241086a410210740c010b200241003a000b20012002410b6a410110740b200041286a20011091022002200041186a36020c2002410c6a200110af01200241106a24000b950201067f230041206b22022400024002402000280210220341046a280200220420002802042205200028020022066a22076b2001490d00200328020021040c010b0240200720016a22062007490d00200441017422052006200520064b1b22064108200641084b1b21060240024020040d00200241003602100c010b200241106a41086a410136020020022004360214200220032802003602100b200220064101200241106a107d200241086a2802002106024020022802004101460d00200320022802042204360200200341046a200636020020002802042105200028020021060c020b2006450d001036000b1038000b2004200620016a22016a200420066a200510ea081a20002001360200200241206a24000b5401027f230041106b2202240002404108102c22030d001036000b2000420837020420002003360200200241003602082000200241086a410410742002410036020c20002002410c6a41041074200241106a24000b4f01027f230041106b2202240002404114102c22030d001036000b200042143702042000200336020041044100200010950520024200370308200242003703002000200241101074200241106a24000ba40101027f230041106b22032400200120021076024002402001450d00200141c4006c210103402002200041046a412010744120102c2204450d0220034220370204200320043602002003200041246a412010742002200328020022042003280208107402402003280204450d002004102e0b200320002802003602002002200341041074200041c4006a2100200141bc7f6a22010d000b0b200341106a24000f0b1036000b5d01027f230041206b22022400200241186a4200370300200241106a4200370300200241086a42003703002002420037030002404120102c22030d001036000b20004220370204200020033602002000200241201074200241206a24000b2f01017f02404104102c22020d001036000b2000420437020420002002360200410020001076410841002000109e010b4f01027f230041106b2202240002404114102c22030d001036000b200042143702042000200336020041044100200010d80220024200370308200242003703002000200241101074200241106a24000b5801017f230041106b220224002000410036020820004201370200200242003703082000200241086a41081074200242003703082000200241086a41081074200242003703082000200241086a41081074200241106a24000b7a01017f230041106b22022400200041003602082000420137020020024200370308200242003703002000200241101074200242003703082002420037030020002002411010742002420037030820024200370300200020024110107420024200370308200242003703002000200241101074200241106a24000b8f0101027f230041306b220224002000410036020820004201370200200241186a4200370300200241106a4200370300200241086a42003703002002420037030002404120102c2203450d002002422037022420022003360220200241206a2002412010742000200228022022032002280228107402402002280224450d002003102e0b200241306a24000f0b1036000b4201027f230041106b2202240002404104102c22030d001036000b20004204370204200020033602002002410136020c20002002410c6a41041074200241106a24000bb60101017f230041106b22022400200041003602082000420137020020024100360200200020024104107420024100360200200020024104107420024100360200200020024104107420024100360200200020024104107420024200370308200242003703002000200241101074200242003703082002420037030020002002411010742002420037030820024200370300200020024110107420024200370308200242003703002000200241101074200241106a24000b2901017f230041106b2202240020024100360208200242043703002000200210b501200241106a24000ba40b02087f067e230041b0036b2203240020034190036a41186a2204420037030020034190036a41106a2205420037030020034190036a41086a22064200370300200342003703900341062107200341d8016a41d9fcc60041061081022006200341d8016a41086a2208290000370300200320032900d80137039003200341d8016a4188f3cb00411010810220042008290000370300200520032900d801370300200341086a20034190036a4120108e02410021090240417f200328020c410020032802081b220a20026a22022002200a491b220a418080c002418080f001200141ff017122021b4b0d00200341106a10a9032004420037030020054200370300200642003703002003420037039003200341d8016a41d9fcc600410610810220062008290000370300200320032900d80137039003200341d8016a41d4f2cb00410b108102200541086a2008290000370000200520032900d801370000200341d8016a20034190036a10f204200341d8016a41186a290300210b200341d8016a41106a290300210c20032903e001210d20032903d801210e200341d8016a200341106a41b80110e9081a2003200d4200200e42015122061b370390032003200c420020061b3703d0012003200b420020061b3703c801024002400240024020020e03010200010b427f2000200341d8026a22062903007c220b200b2000541b210b0c020b427f200020032903e8017c220b200b2000541b210b200341e8016a21060c010b427f2000200341a0026a22062903007c220b200b2000541b210b0b02400240024002402006290318220c4201510d0020062903284201510d00200341c8016a2108024002400240200141ff01710e03010002010b200341d0016a21080c010b20034190036a21080b2008427f2008290300220d200b7c220b200b200d541b3703000c010b200341c8016a2108024002400240200141ff01710e03010002010b200341d0016a21080c010b20034190036a21080b2008290300220d200b7c220b200d540d012008200b3703000b200341c8016a2108024002400240200141ff01710e03000102000b20034190036a21080c010b200341d0016a21080b2008290300210e0240200c4201520d00200e200641206a290300560d010b0240427f427f200329039003220b20032903d001220c7c220d200d200b541b220f20032903c801220d7c22102010200f541b20032903e001580d0020062903284201520d00200e200641306a290300560d010b41002106410021070c010b41062107410121060b20060d00200341d8016a10a9030240024002400240200141ff01710e03010200010b200341d8026a21010c020b200341e8016a21010c010b200341a0026a21010b024020012903084201520d0041062107200141106a2903002000540d010b200341a8036a2208420037030020034190036a41106a2207420037030020034190036a41086a220142003703002003420037039003200341d8016a41d9fcc60041061081022001200341d8016a41086a2206290000370300200320032900d80137039003200341d8016a4188f3cb004110108102200541086a22042006290000370000200520032900d8013700002003200a3602d80120034190036a4120200341d8016a410410b2012008420037030020074200370300200142003703002003420037039003200341d8016a41d9fcc600410610810220012006290000370300200320032900d80137039003200341d8016a41d4f2cb00410b10810220042006290000370000200520032900d801370000200341003602e001200342013703d8012003200b370310200341d8016a200341106a410810742003200c370310200341d8016a200341106a410810742003200d370310200341d8016a200341106a4108107420034190036a412020032802d801220520032802e00110b201024020032802dc01450d002005102e0b410221090b200341b0036a240020074108742009720bee0302037f017e230041d0016b22042400200441206a22054200370300200441086a41106a22064200370300200441086a41086a420037030020044200370308200441086a41d9fcc6004106108102200441c0016a4188f3cb0041101081022005200441c0016a41086a290000370300200620042900c0013703002004200441086a4120108e0202400240417f2004280204410020042802001b220520036a220320032005491b418080c002418080f001200241ff017122031b4b0d00200441086a10a903024002400240024020030e03010200010b20044188016a21030c020b200441186a21030c010b200441d0006a21030b0240024020032903084201520d00200341106a2903002001540d010b42002107024002400240200241ff01710e03000102000b200121070c010b427f200142ffffffffffffffffbf7f7c220720072001541b21070b200041003a0000200041306a41013a0000200041286a4200370200200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a2007370300200041316a2004280008360000200041346a2004410b6a2800003600000c020b200041800c3b0001200041013a0000200041036a41003a00000c010b200041800c3b0001200041013a0000200041036a41003a00000b200441d0016a24000b850201037f230041d0006b22022400200241086a4192fdc6004107108102200241186a41ed9fc5004110108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000b8c0a03107f047e037f23004180026b220324002003200236021420032001360210200341186a2001200210ed0202400240200328021822040d00200041003602000c010b200328021c21052003200341206a280200220136022c200320043602280240024020014104490d002004280000210620032001417c6a36022c2003200441046a360228200341086a200341286a10ab0120032802080d00200328020c210720034200370244024002402007450d00200341d0016a41106a2108410021090340200341003a00f001200941016a2109200328022c210a417f21024100210102400240024002400340200a2001460d01200341d0016a20016a2003280228220b2d00003a00002003200a20026a36022c2003200b41016a3602282003200141016a220c3a00f0012002417f6a2102200c2101200c4120470d000b200341b0016a41186a220d200341d0016a41186a220e290300370300200341b0016a41106a220f2008290300370300200341b0016a41086a2210200341d0016a41086a2211290300370300200320032903d0013703b001200c41ff01714120490d01200341f0006a41086a22012010290300370300200341f0006a41106a2202200f290300370300200341f0006a41186a2212200d290300370300200320032903b001370370200a200c6b220c4104490d01200341d0006a41086a20012903002213370300200341d0006a41106a20022903002214370300200341d0006a41186a20122903002215370300200320032903702216370350200b28000121172003200b41056a3602282003200c417c6a36022c200e20153703002008201437030020112013370300200320163703d0012003280244220b450d02200328024021180c030b200141ff0171450d00200341003a00f0010b200341d0016a41086a200341c0006a41086a280200360200200320032903403703d001200341d0016a10bc020c050b419403102c220b450d0341002118200b4100360200200b41003b01322003200b360244200341003602400b024002400340200b2f013222194105742112410021014104210c417f210202400340024020122001470d00201921020c020b200341d0016a200b20016a41346a412010ec08220a450d03200241016a2102200c41046a210c200141206a2101200a417f4a0d000b0b02402018450d002018417f6a2118200b20024102746a4194036a280200210b0c010b0b200d200e2903002213370300200f20082903002214370300201020112903002215370300200320032903d00122163703b00120082016370200200841086a2015370200200841106a2014370200200841186a2013370200200320023602d8012003200b3602d401200341003602d0012003200341c0006a3602dc01200341d0016a201710a3051a0c010b200b200c6a20173602000b20092007470d000b0b200341b0016a41086a200341c0006a41086a28020022013602002003200329034022133703b0012000200636020420004101360200200041086a2013370200200041106a20013602000c020b1036000b200341003602b801200342013703b0012003410a360294012003200341106a360290012003200341b0016a360270200341e4016a4101360200200342013702d401200341909dc5003602d001200320034190016a3602e001200341f0006a419cebc000200341d0016a103d1a20032802b00120032802b80110ef02024020032802b401450d0020032802b001102e0b200041003602000b2005450d002004102e0b20034180026a24000bc51a07147f017e027f017e027f017e087f230041a0016b2202240020002802102103200028020821042000280200210520002802042106200241c0006a41186a22072000412c6a280000360200200241c0006a41106a2208200041246a290000370300200241c0006a41086a22092000411c6a2900003703002002200041146a29000037034002400240024020062f0132220a410a4b0d0020024180016a41186a200728020036020020024180016a41106a200829030037030020024180016a41086a20092903003703002002200229034037038001200641346a2107200a41016a21080240200441016a2209200a4b22050d00200720094105746a200720044105746a20082004417f736a41057410ea081a0b200720044105746a220a2003360000200a200229038001370004200a410c6a20024188016a290300370000200a41146a20024190016a290300370000200a411c6a20024198016a280200360000200641046a210a024020050d00200a20094102746a200a20044102746a20082004417f736a41027410ea081a0b200a20044102746a220b2001360200200620083b01320c010b4105210a4100210c02400240200441054f0d004104210a200421070c010b41052107024002402004417b6a0e020201000b200441796a21074101210c4106210a0c010b410021074101210c0b02400240024002400240024002400240024002400240419403102c2204450d00200441003b013220044100360200200420062f0132220d200a417f736a22083b013220024188016a200641346a220e200a4105746a2209410c6a29000037030020024190016a200941146a29000037030020024198016a2009411c6a28000036020020022009290004370380012008410c4f0d01200d200a41016a220f6b2008470d02200641046a220d200a4102746a280200211020092800002111200441346a200e200f4105746a200841057410e9081a200441046a200d200f4102746a200841027410e9081a2006200a3b0132200241e0006a41086a20024180016a41086a2209290300370300200241e0006a41106a20024180016a41106a220f290300370300200241e0006a41186a20024180016a41186a220d280200360200200220022903800137036020042006200c1b22082f0132210a200d200241c0006a41186a280200360200200f200241c0006a41106a2903003703002009200241c0006a41086a2903003703002002200229034037038001200841346a210c200a41016a210e0240200741016a2212200a4b22130d00200c20124105746a200c20074105746a200e2007417f736a41057410ea081a0b200c20074105746a220a2003360000200a200229038001370004200a410c6a2009290300370000200a41146a200f290300370000200a411c6a200d280200360000200841046a210a024020130d00200a20124102746a200a20074102746a200e2007417f736a41027410ea081a0b200a20074102746a220b2001360200200241206a41086a2214200241e0006a41086a22152903002216370300200241206a41106a2217200241e0006a41106a22182903002219370300200241206a41186a221a200241e0006a41186a221b280200220a3602002008200e3b013220022002290360221c370320200241186a220e200a360200200241106a22122019370300200241086a221320163703002002201c370300024002400240200628020022010d00410021050c010b2010211d4100210a2004211e2011211f034020062f01302108200241c0006a41186a2220200e280200360200200241c0006a41106a22212012290300370300200241c0006a41086a22222013290300370300200220022903003703402005200a470d0620012f0132220c410b490d024100210941042106024020084105490d0020082106024002402008417b6a0e020201000b200841796a210841012109410621060c010b4100210841012109410521060b41c403102c2204450d03200441003b013220044100360200200420012f013222102006417f736a220a3b0132200141346a222320064105746a2207280000211120024180016a41186a22032007411c6a28000036020020024180016a41106a220f200741146a29000037030020024180016a41086a220d2007410c6a2900003703002002200729000437038001200a410c4f0d072010200641016a22076b200a470d08200141046a222420064102746a2802002110200441346a202320074105746a200a41057410e9081a200441046a2024200741027422076a200a41027410e9081a200120063b01322015200d2903003703002018200f290300370300201b2003280200360200200220022903800137036020042f0132220a41016a2123200a410c4f0d09200c20066b22062023470d0a200541016a210520044194036a200120076a4194036a200641027410e9081a4100210602400340200420064102746a4194036a280200220720063b01302007200436020020062006200a4922076a2206200a4b0d0120070d000b0b201a201b2802003602002017201829030037030020142015290300370300200220022903603703202004200120091b22072f0132210c20032020280200360200200f2021290300370300200d20222903003703002002200229034037038001200741346a210a200c41016a21090240200841016a2206200c4b22200d00200a20064105746a200a20084105746a2008417f7320096a41057410ea081a0b200a20084105746a220a201f360000200a200229038001370004200a410c6a200d290300370000200a41146a200f290300370000200a411c6a2003280200360000200741046a210a024020200d00200a20064102746a200a20084102746a2008417f7320096a41027410ea081a0b200a2008410274220f6a201d36020020074194036a210a0240200841026a220d200c41026a22034f0d00200a200d4102746a200a20064102746a2006417f7320036a41027410ea081a0b200a20064102746a201e360200200720093b01320240200620034f0d002007200f6a4198036a210603402006280200220a200841016a22083b0130200a2007360200200641046a210620092008470d000b0b2013201429030037030020122017290300370300200e201a28020036020020022002290320370300200121062001280200220721012010211d2005210a2004211e2011211f20070d000b0b200241c0006a41186a200e2802002206360200200241c0006a41106a20122903002216370300200241c0006a41086a2013290300221937030020022002290300221c370340201b200636020020182016370300201520193703002002201c370360200028020c220a2802042207450d09200a280200210841c403102c2206450d012006200736029403200641003b013220064100360200200741003b013020072006360200200a2006360204200a200841016a36020020024180016a41186a200241e0006a41186a28020036020020024180016a41106a200241e0006a41106a29030037030020024180016a41086a200241e0006a41086a290300370300200220022903603703800120082005470d0a20062f01322208410b4f0d0b200620084105746a220741346a2011360000200741386a200229038001370000200741c0006a20024188016a290300370000200741c8006a20024190016a290300370000200741d0006a20024198016a2802003600002006200841016a22073b0132200620074102746a4194036a2004360200200620084102746a41046a2010360200200420073b013020042006360200200a200a28020841016a3602080c0d0b20012f0132210a20024180016a41186a2205200241c0006a41186a28020036020020024180016a41106a2203200241c0006a41106a29030037030020024180016a41086a220f200241c0006a41086a2903003703002002200229034037038001200841016a2106200141346a2104200a41016a210902402008200a4f22070d00200420064105746a200420084105746a2008417f7320096a41057410ea081a0b200420084105746a2204201f36000020042002290380013700042004410c6a200f290300370000200441146a20032903003700002004411c6a2005280200360000200141046a2104024020070d00200420064102746a200420084102746a2008417f7320096a41027410ea081a0b2004200841027422056a201d36020020014194036a2104200a41026a2108024020070d00200520046a41086a200420064102746a2006417f7320086a41027410ea081a0b200420064102746a201e360200200120093b0132200620084f0d0b200a41016a210720012006417f6a22064102746a4198036a210403402004280200220a200641016a22063b0130200a2001360200200441046a210420072006470d000c0c0b0b1036000b2008410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b41ac9cc700413541e49cc7001039000b200a410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b2023410c41f49cc700104d000b41f49bc7004128419c9cc7001039000b41e8aac700412b4194abc7001039000b41e899c700413041989ac7001039000b41a89ac700412041c89ac7001039000b200028020c2206200628020841016a3602080b200241a0016a2400200b0bf60d04067f017e057f027e230041800d6b2202240010a505200141086a28020021032001410c6a280200210420012802042105200241a00a6a2001280200220610a6052005200441b0026c6a2107200241a00a6a10a7052101024002400240024002400240024020040d0042002108200521010c010b20024180056a41047221090240024020010d00200241e9026a210a420021084100210b20052101024003402001280200210c200241c0076a200141046a220d41ac0210e9081a200241a00a6a200d41ac0210e9081a200c411c460d0120024180056a200241a00a6a41ac0210e9081a200241d0026a20024180056a41ac0210e9081a200241246a200241d0026a41ac0210e9081a2002200c360280052009200241246a41ac0210e9081a200241b0076a20024180056a109704200241a00a6a20024180056a41b00210e9081a200241c0076a200610a605200241d0026a200241a00a6a200241c0076a10dd020240024020022903d8024201510d0020022903b007210e0c010b20022903b007220e20022903e002220f200f200e561b210e0b200241a00a6a41086a200a41086a290000370300200241a00a6a410f6a200a410f6a2900003700002002200a2900003703a00a427f2008200e7c220e200e2008541b2108024020022903d0024201510d00200b41016a210b200141b0026a22012007470d010c040b0b200141b0026a21010c050b200141b0026a21010c060b200241e9026a210c4100210b200521014200210803402001280200210a200241c0076a200141046a220d41ac0210e9081a200241a00a6a200d41ac0210e9081a200a411c460d0520024180056a200241a00a6a41ac0210e9081a200241d0026a20024180056a41ac0210e9081a200241246a200241d0026a41ac0210e9081a2002200a360280052009200241246a41ac0210e9081a200241b0076a20024180056a109704200241c0076a20024180056a41b00210e9081a200241f0096a200610a6050240024020022802980a220a280208200241c0076a200a28020c28020c1101000d00200a200a280200417f6a220d360200200241023a00f002200241003a00e802200242003703d802200242013703d0020240200d0d00200a280208200a28020c2802001103000240200a28020c280204450d00200a280208102e0b200a41046a220d200d280200417f6a220d360200200d0d00200a102e0b200241c0076a10dc0220022903b007210e0c010b200241a00a6a200241c0076a41b00210e9081a200241d00c6a41286a200241f0096a41286a280200360200200241d00c6a41206a200241f0096a41206a290300370300200241d00c6a41186a200241f0096a41186a290300370300200241d00c6a41106a200241f0096a41106a290300370300200241d00c6a41086a200241f0096a41086a290300370300200220022903f0093703d00c200241d0026a200241a00a6a200241d00c6a10dd02024020022903d8024201510d0020022903b007210e0c010b20022903b007220e20022903e002220f200f200e561b210e0b200241a00a6a41086a200c41086a290000370300200241a00a6a410f6a200c410f6a2900003700002002200c2900003703a00a427f2008200e7c220e200e2008541b210820022903d0024201510d03200b41016a210b200141b0026a22012007470d000b0b200721010b200241a00a6a200241c0076a41ac0210e9081a0c030b200141b0026a21010b200241086a410f6a200241a00a6a410f6a290000370000200241086a41086a200241a00a6a41086a290300370300200220022903a00a370308200b41016aad42e88dfb007e20087c2108024020072001460d0003402001108b022007200141b0026a2201470d000b0b200842e0b8a1077c210802402003450d00200341b0026c450d002005102e0b200241c0076a410f6a2201200241086a410f6a290000370000200241c0076a41086a2207200241086a41086a290300370300200220022903083703c00710a805200041186a41003a0000200041106a20083703002000420137030820004201370300200020022903c007370019200041216a2007290300370000200041286a20012900003700000c020b200141b0026a21010b024020072001460d0003402001108b022007200141b0026a2201470d000b0b02402003450d00200341b0026c450d002005102e0b200241a00a6a41086a41063a0000200241113a00a00a200241a00a6a10fe01200241c0076a41086a2201200241086a41086a290300370300200241c0076a410f6a2207200241086a410f6a290000370000200220022903083703c00710a905200041186a41003a0000200041106a2004ad42e88dfb007e20087c42e0b8a1077c3703002000420137030820004200370300200020022903c007370019200041216a2001290300370000200041286a20072900003700000b200241800d6a24000b0400102b0ba10701087f230041c0006b21020240024002400240024020012d00000e03000102000b4102210302400240024020012d00010e03000102000b410021030c010b2002413c6a41026a200141076a2d00003a0000200241206a41086a200141186a290000370300200241206a41106a200141206a2f00003b01002002200141056a2f00003b013c2002200141106a2900003703202001410c6a2800002104200141086a2800002105200141046a2d00002106200141026a2f00002107410121030b2002411c6a41026a2002413c6a41026a2d00003a0000200241086a200241206a41086a290300370300200241106a200241206a41106a2f01003b0100200220022f013c3b011c20022002290320370300410021080c030b41022106024002400240200141046a2d00000e03000102000b2001410c6a2802002104200141086a2802002105410021060c010b2002413e6a200141076a2d00003a0000200241206a41086a200141186a2900003703002002412d6a2001411d6a2900003700002002200141056a2f00003b013c2002200141106a2900003703202001410c6a2800002104200141086a2800002105410121060b2002411c6a41026a2002413c6a41026a2d00003a0000200241086a200241206a41086a290300370300200241106a200241206a41106a290300370300200220022f013c3b011c20022002290320370300410121080c010b4102210841022106024002400240200141046a2d00000e03000102000b2001410c6a2802002104200141086a2802002105410021060c010b2002413e6a200141076a2d00003a0000200241206a41086a200141186a2900003703002002412d6a2001411d6a2900003700002002200141056a2f00003b013c2002200141106a2900003703202001410c6a2800002104200141086a2800002105410121060b2002411c6a41026a2002413c6a41026a2d00003a0000200241086a200241206a41086a290300370300200241106a200241206a41106a290300370300200220022f013c3b011c200220022903203703000b0b02402001280228220128020041016a220941014b0d0000000b200020033a0001200020083a000020002001360228200041046a20063a0000200041026a20073b010020012009360200200041056a20022f011c3b00002000410c6a2004360200200041086a2005360200200041106a2002290300370200200041076a2002411c6a41026a2d00003a0000200041186a200241086a290300370200200041206a200241106a2903003702000bcc0101037f200028022822012001280200417f6a220236020020002d0001210302400240024020002d00000d004100210020020d022001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a22023602002002450d010c020b4101210020020d012001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d010b2001102e0b200341ff01714100472000720b040010280b040010230bce0902037f017e230041b0016b220224002002412036020c20022001360208200241106a2001412010ed0202400240200228021022010d00200041033a00200c010b200241186a280200210320022802142104200241003a0060024002402003450d00200220012d00003a0040200241013a0060024020034101460d00200220012d00013a0041200241023a006020034102460d00200220012d00023a0042200241033a006020034103460d00200220012d00033a0043200241043a006020034104460d00200220012d00043a0044200241053a006020034105460d00200220012d00053a0045200241063a006020034106460d00200220012d00063a0046200241073a006020034107460d00200220012d00073a0047200241083a006020034108460d00200220012d00083a0048200241093a006020034109460d00200220012d00093a00492002410a3a00602003410a460d00200220012d000a3a004a2002410b3a00602003410b460d00200220012d000b3a004b2002410c3a00602003410c460d00200220012d000c3a004c2002410d3a00602003410d460d00200220012d000d3a004d2002410e3a00602003410e460d00200220012d000e3a004e2002410f3a00602003410f460d00200220012d000f3a004f200241103a006020034110460d00200220012d00103a0050200241113a006020034111460d00200220012d00113a0051200241123a006020034112460d00200220012d00123a0052200241133a006020034113460d00200220012d00133a0053200241143a006020034114460d00200220012d00143a0054200241153a006020034115460d00200220012d00153a0055200241163a006020034116460d00200220012d00163a0056200241173a006020034117460d00200220012d00173a0057200241183a006020034118460d00200220012d00183a0058200241193a006020034119460d00200220012d00193a00592002411a3a00602003411a460d00200220012d001a3a005a2002411b3a00602003411b460d00200220012d001b3a005b2002411c3a00602003411c460d00200220012d001c3a005c2002411d3a00602003411d460d00200220012d001d3a005d2002411e3a00602003411e460d00200220012d001e3a005e2002411f3a00602003411f460d00200241206a41106a200241c0006a41106a290300370300200241206a41086a200241c0006a41086a290300370300200220012d001f3a005f200241206a41186a200241c0006a41186a290300370300200241203a00602002200229034022053703682002200537032020034120460d014100210302400240024020012d00200e03020001040b410121030c010b410221030b20002002290320370000200041186a200241206a41186a290300370000200041106a200241206a41106a290300370000200041086a200241206a41086a2903003700000c020b200241003a00600b20024100360270200242013703682002410a3602242002200241086a3602202002200241e8006a3602ac01200241d4006a410136020020024201370244200241909dc5003602402002200241206a360250200241ac016a419cebc000200241c0006a103d1a2002280268200228027010ef020240200228026c450d002002280268102e0b410321030b200020033a00202004450d002001102e0b200241b0016a24000be30d020f7f077e230041c0026b220224002002412036021420022001360210200241186a2001412010ed020240024002400240200228021822030d00200041033a003c0c010b200228021c21042002200241206a28020036022c20022003360228200241086a200241286a10ab01024002400240024020022802080d00200228020c2205200228022c4106762201200120054b1b22064106742201417f4c0d060240024020060d00410821070c010b2001102c2207450d060b02400240024020050d00410021050c010b41002108410021090340200241003a0088012009220a41016a2109200228022c210b417f210c41002101024002400240024002400340200b2001460d01200241e8006a20016a2002280228220d2d00003a00002002200b200c6a36022c2002200d41016a3602282002200141016a220e3a008801200c417f6a210c200e2101200e4120470d000b200241386a41186a2201200241e8006a41186a290300370300200241386a41106a220c200241e8006a41106a290300370300200241386a41086a220f200241e8006a41086a29030037030020022002290368370338200e41ff01714120490d0120024180026a41086a2210200f29030037030020024180026a41106a220f200c29030037030020024180026a41186a220c20012903003703002002200229033837038002200b200e6b22014110490d012002200d41116a3602282002200141706a36022c200d41096a2900002111200d2900012112200241e8006a200241286a10e9012002280268220e450d01200241c0016a41086a20102903002213370300200241c0016a41106a200f2903002214370300200241c0016a41186a200c2903002215370300200241a0016a41086a22012013370300200241a0016a41106a220c2014370300200241a0016a41186a220b2015370300200220022903800222133703c001200220133703a001200229026c2113200a2006470d04200641016a220d2006490d0e2006410174220f200d200f200d4b1b220d4104200d41044b1b220d41ffffff1f71200d46410374210f200d410674210d20060d02200241003602680c030b200141ff0171450d00200241003a0088010b0240200a450d00200741346a2101034002402001280200220c450d00200c41306c450d002001417c6a280200102e0b200141c0006a2101200841406a22080d000b0b200641ffffff1f710d050c060b20024108360270200220073602682002200641067436026c0b200241386a200d200f200241e8006a107d2002280240210d024020022802384101470d00200d0d0a0c0b0b200228023c2107200d41067621060b20012903002114200c2903002115200b290300211620022903a00121172007200a4106746a2201201237032020012017370300200120133702342001200e360230200141286a2011370300200141186a2016370300200141106a2015370300200141086a2014370300200841c0006a210820092005470d000b0b2007450d01200241e8006a200241286a10a401024020022903684201510d00200241386a41286a20024198016a290300370300200241386a41206a200241e8006a41286a290300370300200241386a41186a200241e8006a41206a290300370300200241386a41106a200241e8006a41186a290300370300200241c0006a200241e8006a41106a29030037030020022002290370370338200228022c2201450d002002280228220c2d0000210e20022001417f6a36022c2002200c41016a360228410021010240200e0e03050400010b410221010c040b02402005450d00200720054106746a210b2007210103402001220c41c0006a21010240200c41346a280200220e450d00200e41306c450d00200c41306a280200102e0b200b2001470d000b0b200641ffffff1f71450d010b2007102e0b20024100360240200242013703382002410a3602a4022002200241106a3602a0022002200241386a36028002200241fc006a41013602002002420137026c200241909dc5003602682002200241a0026a36027820024180026a419cebc000200241e8006a103d1a2002280238200228024010ef020240200228023c450d002002280238102e0b410321010c020b410121010b20002002290338370300200041286a200241386a41286a290300370300200041206a200241386a41206a290300370300200041186a200241386a41186a290300370300200041106a200241386a41106a290300370300200041086a200241386a41086a290300370300200241e8006a41026a220c200241356a41026a2d00003a0000200220022f00353b0168200020053602382000200636023420002007360230200020022f01683b003d2000413f6a200c2d00003a00000b200020013a003c2004450d002003102e0b200241c0026a24000f0b1036000b1038000b990805067f017e037f037e027f230041f0016b220224002002412036020c20022001360208200241106a2001412010ed0202400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10ab010240024020022802000d00024002402002280204220520022802244105762201200120054b1b22014105742206417f4c0d000240024020010d00410121070c010b2006102c2207450d020b2001ad2108024002402005450d00410021090340200241003a00a8012002280224417f6a2101200941016a2109410021060240024002400240024003402001417f460d0120024188016a20066a2002280220220a2d00003a00002002200a41016a3602202002200641016a220a3a00a801200220013602242001417f6a2101200a2106200a4120470d000b200241d0016a41186a220120024188016a41186a290300370300200241d0016a41106a220620024188016a41106a290300370300200241d0016a41086a220b20024188016a41086a29030037030020022002290388013703d001200a41ff01714120490d01200241c8006a41086a200b290300220c370300200241c8006a41106a2006290300220d370300200241c8006a41186a2001290300220e370300200241286a41186a220a200e370300200241286a41106a220b200d370300200241286a41086a220f200c370300200220022903d001220c3703682002200c3703482002200c3703282008422088220ca722012008a7470d04200141016a22062001490d0820014101742210200620062010491b22064104200641044b1b220641ffffff3f7120064621102006410574210620010d0220024100360288010c030b200641ff0171450d00200241003a00a8010b200842ffffff3f83500d082007102e0c080b200241013602900120022007360288012002200c4205863e028c010b200241d0016a2006201020024188016a107d20022802d801210620022802d0014101460d0320022802d40121072006410576ad21080b200720014105746a22062002290328370000200641186a200a290300370000200641106a200b290300370000200641086a200f290300370000200842ffffffff0f83200141016aad42208684210820092005470d000b0b2007450d0320002008370204200020073602000c040b20060d010b1038000b1036000b200241003602d801200242013703d0012002410a3602b4012002200241086a3602b0012002200241d0016a3602682002419c016a41013602002002420137028c01200241909dc500360288012002200241b0016a36029801200241e8006a419cebc00020024188016a103d1a20022802d00120022802d80110ef02024020022802d401450d0020022802d001102e0b200041003602000b2004450d002003102e0b200241f0016a24000bf30a06087f027e027f027e017f017e230041a0016b220324002003200236021420032001360210200341186a2001200210ed0202400240024002400240200328021822010d00200041023a00000c010b200328021c21042003200341206a280200220236024c20032001360248024002402002450d0020012d0000210520032002417f6a220636024c2003200141016a3602480240024002400240024020050e020001050b20064104490d04200341c4006a41026a200341d8006a41026a2d00003a0000200341286a41086a200341f8006a41086a290300370300200341286a41106a200341f8006a41106a290300370300200341286a41186a200341f8006a41186a280200360200200320032f00583b0144200320032903783703282001280001210720032002417b6a36024c2003200141056a360248410021020c010b200341086a200341c8006a10ab0120032802080d03200328024c2202200328020c2205490d032005417f4c0d060240024020050d00410121060c010b200510322206450d08200328024c21020b20022005490d0220062003280248200510e9081a200328024c22022005490d082003200220056b36024c2003200328024820056a360248200341f8006a200341c8006a10930120032d00784101460d012003419e016a20032d007b3a0000200341d8006a41086a200341f8006a41106a290300370300200341d8006a41106a200341f8006a41186a290300370300200341d8006a41186a20034198016a2d00003a0000200320032f00793b019c012003200341f8006a41086a290300370358200328024c22024110490d01200328027c210720032003280248220841106a22093602482003200241706a220a36024c200a4104490d01200841086a290000210b2008290000210c20032002416c6a220836024c2003200941046a3602482008450d012009280000210d20032002416b6a220e36024c2003200941056a3602484100210a0240024020092d00040e020100030b200e4104490d022003200241676a36024c2003200941096a360248200928000521084101210a0b200341c4006a41026a2003419c016a41026a2d00003a0000200341286a41086a200341d8006a41086a290300370300200341286a41106a200341d8006a41106a290300370300200341286a41186a200341d8006a41186a2d00003a0000200341c3006a200341d5006a41026a2d00003a0000200320032f019c013b014420032003290358370328200320032f00553b0041410121020b200341d8006a41026a200341c4006a41026a2d000022093a0000200341f8006a41086a200341286a41086a290300220f370300200341f8006a41106a200341286a41106a2903002210370300200341f8006a41186a200341286a41186a280200220e360200200320032f014422113b0158200320032903282212370378200041036a20093a0000200020113b0001200041046a2007360000200041c8006a200b370000200041c0006a200c370000200041086a2012370000200041106a200f370000200041186a2010370000200041206a200e360000200041386a2008360000200041346a200a360000200041306a200d3600002000412c6a2005360000200041286a2005360000200041246a20063600000c030b2005450d010b2006102e0b20034100360230200342013703282003410a36025c2003200341106a3602582003200341286a36029c012003418c016a41013602002003420137027c200341909dc5003602782003200341d8006a360288012003419c016a419cebc000200341f8006a103d1a2003280228200328023010ef020240200328022c450d002003280228102e0b410221020b200020023a00002004450d002001102e0b200341a0016a24000f0b1038000b1036000b2005200241b8b2c0001056000bbf0302057f017e230041e0006b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200041003602000c010b200328021421022003200341186a280200360224200320013602202003200341206a10ab0102400240024002402003280200450d00200341003602480c010b200341c8006a200341206a200328020410920120032802482204450d00200328024c210520032802242206410f4b0d01200541ffffff3f71450d002004102e0b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341909dc5003602482003200341386a360258200341c4006a419cebc000200341c8006a103d1a2003280228200328023010ef020240200328022c450d002003280228102e0b200041003602000c010b2003200641706a36022420032003280220220641106a360220200341c8006a41086a280200210720062900002108200041186a200641086a290000370300200041106a2008370300200041086a200736020020002005360204200020043602000b2002450d002001102e0b200341e0006a24000bc20201027f23004190056b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822010d002000411c3602000c010b200328020c21022003200341106a2802003602fc04200320013602f804200341c8026a200341f8046a1098010240024020032802c8022204411c470d0020034100360220200342013703182003410a3602840520032003360280052003200341186a36028c05200341dc026a4101360200200342013702cc02200341909dc5003602c802200320034180056a3602d8022003418c056a419cebc000200341c8026a103d1a2003280218200328022010ef02200328021c450d012003280218102e0c010b200341186a200341c8026a41047241ac0210e9081a200041046a200341186a41ac0210e9081a0b200020043602002002450d002001102e0b20034190056a24000bf90202037f027e230041d0006b220224002002412036020420022001360200200241086a2001412010ed0202400240200228020822010d00200041033a00100c010b200228020c21030240024002400240200241086a41086a28020022044108490d0020044178714108460d0020044110460d00200129000021052001290008210641002104024020012d00100e03030200010b410221040c020b20024100360220200242013703182002410a36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241909dc5003602382002200241286a360248200241346a419cebc000200241386a103d1a2002280218200228022010ef020240200228021c450d002002280218102e0b410321040c020b410121040b2002200228003836021820022002413b6a28000036001b200020063703082000200537030020002002280218360011200041146a200228001b3600000b200020043a00102003450d002001102e0b200241d0006a24000b901308057f017e057f027e017f017e037f047e23004180026b220324002003200236020c20032001360208200341106a2001200210ed020240024002400240200328021022020d00200041023a00000c010b200328021421042003200341186a280200220536025420032002360250024002402005450d0020022d0000210120032005417f6a22063602542003200241016a3602500240024002400240024020010e020001050b2003200341d0006a10ab0120032802000d0420032802042207200328025441306e2201200120074b1bad42307e2208422088a70d082008a72201417f4c0d080240024020010d00410821090c010b2001102c2209450d080b200141306e210a0240024020070d00410021070c010b200341d8016a41017221064100210b41002105034002400240200328025422014104490d002003280250220c350000210820032001417c6a3602542003200c41046a360250200341d8016a200341d0006a10b10420032d00d801220c4102470d010b20034188016a411f6a200341b0016a411f6a29000037000020034188016a41186a200341b0016a41186a290300370300200a450d07200a41306c0d060c070b200341b0016a411f6a22012006411f6a290000370000200341b0016a41186a220d200641186a29000037030020034188016a41086a200641086a290000220e37030020034188016a41106a200641106a290000220f37030020034188016a41186a2210200d29030037030020034188016a411f6a220d200129000037000020032006290000221137038801200341e0006a411f6a2212200d290000370000200341e0006a41186a220d2010290300370300200341e0006a41106a2210200f370300200341e0006a41086a2213200e3703002003201137036002402005200a470d00200a41016a2201200a490d0b200a41017422142001201420014b1b22014104200141044b1bad42307e220e422088a7454103742101200ea7211402400240200a0d00200341003602d8010c010b200341083602e001200320093602d8012003200a41306c3602dc010b200341b0016a20142001200341d8016a107d20032802b8012101024020032802b0014101470d0020010d0b0c0c0b20032802b4012109200141306e210a0b2009200b6a22012008370300200141086a200c3a0000200141096a2003290360370000200141116a2013290300370000200141196a2010290300370000200141216a200d290300370000200141286a2012290000370000200b41306a210b2007200541016a2205470d000b0b2009450d04200328025422014110490d0220032003280250220641106a3602502003200141706a220b360254200b4110490d02200641086a290000210f200629000021112003200641206a220b3602502003200141606a220536025420054104490d02200641186a29000021082006290010210e2003200b41046a36025020032001415c6a220636025420064110490d02200b2800002106200341386a200b410c6a290000370300200341cc006a41026a200341dc006a41026a2d00003a00002003200e370320200320032f005c3b014c200320063602402003200b2900043703302003200837032820032001414c6a3602542003200b41146a360250410021010c010b20064110490d0320032005416f6a220a3602542003200241116a360250200241096a29000021082002290001210e41002101200341003a00f801416e2106024002400240024002400240024002400340200a2001460d01200341d8016a20016a200220016a220b41116a2d00003a00002003200520066a3602542003200b41126a3602502003200141016a220b3a00f8012006417f6a2106200b2101200b4120470d000b20034188016a41026a220120032d00da013a0000200320032f01d8013b018801200b41ff01714120490d0b200341ef016a290000210f20032900e701211120032d00f701210c20032800e301210720032800df01210a20032800db012109200341dc006a41026a20012d00003a0000200320032f0188013b015c2005416f6a200b460d0b2002200b6a220141116a2d0000210d2003200520066a22063602542003200141126a36025041002110200d0e07070102030405060b0b200141ff0171450d0a200341003a00f8010c0a0b410121100c050b410221100c040b410321100c030b410421100c020b410521100c010b410621100b20064110490d032003200141226a220d36025020032005200b6b220b415e6a220636025420064110490d032001411a6a2900002115200141126a29000021162003200141326a22053602502003200b414e6a220636025420064104490d032001412a6a2900002117200d2900002118200528000021062003200141366a220d3602502003200b414a6a220536025420054110490d03200341cc006a41026a200341dc006a41026a2d00003a0000200341c0006a2015370300200341206a41106a2008370300200320032f015c3b014c2003200b41ba7f6a3602542003200141c6006a360250200320163703382003200e370328200320103a00212003200c3a0020200320032801b0013601222003200341b4016a2f01003b01262001413e6a290000210e200d2900002108410121010b200341b0016a41026a200341cc006a41026a2d0000220b3a0000200341d8016a41086a2205200341206a41086a290300370300200341d8016a41106a220c200341206a41106a290300370300200341d8016a41186a220d200341206a41186a290300370300200341d8016a41206a2210200341206a41206a290300370300200320032f014c22123b01b001200320032903203703d801200041186a200f370000200041106a2011370000200041036a200b3a0000200020123b00012000410c6a2007360000200041086a200a360000200041046a2009360000200041e8006a2006360000200041e0006a200e370000200041d8006a2008370000200041d0006a2017370000200041c8006a2018370000200041206a20032903d801370000200041286a2005290300370000200041306a200c290300370000200041386a200d290300370000200041c0006a20102903003700000c030b200a450d01200a41306c450d010b2009102e0b20034100360228200342013703202003410a3602b4012003200341086a3602b0012003200341206a36028801200341ec016a4101360200200342013702dc01200341909dc5003602d8012003200341b0016a3602e80120034188016a419cebc000200341d8016a103d1a2003280220200328022810ef0202402003280224450d002003280220102e0b410221010b200020013a00002004450d002002102e0b20034180026a24000f0b1036000b1038000b8a0b02027f067e230041d0016b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200041023a00300c010b200341186a280200210220032802142104200341003a008801024002402002450d00200320012d00003a0068200341013a008801024020024101460d00200320012d00013a0069200341023a00880120024102460d00200320012d00023a006a200341033a00880120024103460d00200320012d00033a006b200341043a00880120024104460d00200320012d00043a006c200341053a00880120024105460d00200320012d00053a006d200341063a00880120024106460d00200320012d00063a006e200341073a00880120024107460d00200320012d00073a006f200341083a00880120024108460d00200320012d00083a0070200341093a00880120024109460d00200320012d00093a00712003410a3a0088012002410a460d00200320012d000a3a00722003410b3a0088012002410b460d00200320012d000b3a00732003410c3a0088012002410c460d00200320012d000c3a00742003410d3a0088012002410d460d00200320012d000d3a00752003410e3a0088012002410e460d00200320012d000e3a00762003410f3a0088012002410f460d00200320012d000f3a0077200341103a00880120024110460d00200320012d00103a0078200341113a00880120024111460d00200320012d00113a0079200341123a00880120024112460d00200320012d00123a007a200341133a00880120024113460d00200320012d00133a007b200341143a00880120024114460d00200320012d00143a007c200341153a00880120024115460d00200320012d00153a007d200341163a00880120024116460d00200320012d00163a007e200341173a00880120024117460d00200320012d00173a007f200341183a00880120024118460d00200320012d00183a008001200341193a00880120024119460d00200320012d00193a0081012003411a3a0088012002411a460d00200320012d001a3a0082012003411b3a0088012002411b460d00200320012d001b3a0083012003411c3a0088012002411c460d00200320012d001c3a0084012003411d3a0088012002411d460d00200320012d001d3a0085012003411e3a0088012002411e460d00200320012d001e3a0086012003411f3a0088012002411f460d00200341c8006a41106a200341e8006a41106a290300370300200341c8006a41086a200341e8006a41086a290300370300200320012d001f3a008701200341c8006a41186a200341e8006a41186a290300370300200341203a0088012003200329036822053703900120032005370348200241606a22024110490d0120024110460d01200141286a290000210520012900202106410021020240024020012d00300e020100030b410121020b200341206a41186a200341c8006a41186a2903002207370300200341206a41106a200341c8006a41106a2903002208370300200341206a41086a200341c8006a41086a290300220937030020032003290348220a370320200320032800413602682003200341c4006a28000036006b20002005370308200020063703002000200a370310200041186a2009370300200041206a2008370300200041286a2007370300200041346a200328006b360000200020032802683600310c020b200341003a0088010b200341003602980120034201370390012003410a36024c2003200341086a360248200320034190016a360220200341fc006a41013602002003420137026c200341909dc5003602682003200341c8006a360278200341206a419cebc000200341e8006a103d1a20032802900120032802980110ef020240200328029401450d00200328029001102e0b410221020b200020023a00302004450d002001102e0b200341d0016a24000bf80403047f017e067f230041f0006b220324002003200236021c20032001360218200341206a2001200210ed0202400240200328022022010d00200041003602080c010b200328022421042003200341286a2802002202360234200320013602300240024020024104490d00200128000021052003200141046a36023020032002417c6a220636023420064104490d00200128000421062003200241786a3602342003200141086a360230200341106a200341306a10ab0102402003280210450d00200341003602580c010b200341d8006a200341306a200328021410920120032802582202450d00200329025c2107200341086a200341306a10ab01024002402003280208450d00200341003602580c010b200341d8006a200341306a200328020c10920120032802582208450d00200328025c210902402003280234220a4104490d00200341e0006a280200210b2003280230220c280000210d2003200a417c6a3602342003200c41046a3602302002450d022000200737020c200020023602082000200636020420002005360200200041206a200d3602002000411c6a200b360200200041186a2009360200200041146a20083602000c030b200941ffffff3f71450d002008102e0b200742ffffff3f83500d002002102e0b20034100360240200342013703382003410a36024c2003200341186a3602482003200341386a360254200341ec006a41013602002003420137025c200341909dc5003602582003200341c8006a360268200341d4006a419cebc000200341d8006a103d1a2003280238200328024010ef020240200328023c450d002003280238102e0b200041003602080b2004450d002001102e0b200341f0006a24000ba40c03057f027e0c7f230041f0016b220324002003200236020420032001360200200341086a2001200210ed0202400240200328020822040d00200041023602100c010b200328020c21052003200341106a280200220636025c2003200436025841002101200341003a00a8012006417f6a21020240024002400240024002400240034020062001460d0120034188016a20016a200420016a22072d00003a00002003200741016a3602582003200141016a22073a00a8012003200236025c2002417f6a21022007210120074120470d000b200341d0016a41186a220120034188016a41186a290300370300200341d0016a41106a220220034188016a41106a290300370300200341d0016a41086a220620034188016a41086a29030037030020032003290388013703d001200741ff01714120490d03200341e8006a41086a2006290300370300200341e8006a41106a2002290300370300200341e8006a41186a2001290300370300200320032903d00137036820034188016a200341d8006a10930120032d0088014101460d03200341b0016a41186a200341a1016a2201290000370300200341b0016a41106a20034199016a2202290000370300200341b0016a41086a20034191016a220729000037030020032003290089013703b00120034188016a200341d8006a10930120032d0088014101460d03200341d0016a41186a2001290000370300200341d0016a41106a2002290000370300200341d0016a41086a200729000037030020032003290089013703d001200328025c22024110490d032003200241706a220636025c20032003280258220141106a22073602582006450d03200141086a29000021082001290000210920032002416f6a220636025c2003200741016a3602584100210120072d00000e020201030b200141ff0171450d02200341003a00a8010c020b20064104490d0120032002416b6a36025c2003200741056a3602582007280001210a410121010b20034188016a200341d8006a10e9012003280288012207450d00200328028c0121020240200328025c2206450d0020034190016a280200210b2003280258220c2d0000210d20032006417f6a36025c2003200c41016a36025841002106200d0e020302000b2002450d00200241306c450d002007102e0b200341003602d801200342013703d0012003410a3602b401200320033602b0012003200341d0016a3602682003419c016a41013602002003420137028c01200341909dc500360288012003200341b0016a36029801200341e8006a419cebc00020034188016a103d1a20032802d00120032802d80110ef02024020032802d401450d0020032802d001102e0b410221010c020b410121060b20034188016a41186a220c200341e8006a41186a29030037030020034188016a41106a220d200341e8006a41106a29030037030020034188016a41086a220e200341e8006a41086a290300370300200341386a41086a220f200341b0016a41086a290300370300200341386a41106a2210200341b0016a41106a290300370300200341386a41186a2211200341b0016a41186a290300370300200341186a41086a2212200341d0016a41086a290300370300200341186a41106a2213200341d0016a41106a290300370300200341186a41186a2214200341d0016a41186a2903003703002003200329036837038801200320032903b001370338200320032903d001370318200341146a41026a2215200341e5006a41026a2d00003a0000200320032f00653b01142000200837030820002009370300200041206a200b3602002000411c6a2002360200200041186a20073602002000200a360214200041246a2003290388013702002000412c6a200e290300370200200041346a200d2903003702002000413c6a200c290300370200200041c4006a2003290338370200200041cc006a200f290300370200200041d4006a2010290300370200200041dc006a2011290300370200200041fc006a2014290300370200200041f4006a2013290300370200200041ec006a2012290300370200200041e4006a200329031837020020004184016a20063a000020004187016a20152d00003a0000200020032f01143b0085010b200020013602102005450d002004102e0b200341f0016a24000bfc0d05037f017e097f027e057f230041c0016b22022400200241086a200110ab0102400240024020022802080d00200228020c2203200128020441246e2204200420034b1bad42247e2205422088a70d022005a72204417f4c0d0202400240024020040d00410421060c010b2004102c2206450d010b200441246ead2105024002402003450d002002413d6a21072002418b016a220841056a21094100210a03400240024002402001280204220b450d002001280200220c2d000021042001200b417f6a220d3602042001200c41016a3602000240024002400240024002400240024002400240024020040e08000b010b030402050b0b2002200110ab0120022802000d0a2001280204220b20022802042204490d0a2004417f4c0d130240024020040d004101210e0c010b20041032220e450d112001280204210b0b200b2004490d06200e2001280200200410e908210b2001280204220c20044f0d052004200c41b8b2c0001056000b41002104200241003a009801200b417e6a210b02400340200d2004460d01200241f8006a20046a200c20046a220e41016a2d00003a00002001200b3602042001200e41026a3602002002200441016a220e3a009801200b417f6a210b200e2104200e4120460d090c000b0b200441ff0171450d09200241003a0098010c090b200241f8006a200110aa01200228027c220c450d0820022f017820022d007a41107472210b20022d007b210e200229038001220f428080808070832110200fa7210d410121110c070b200241f8006a200110aa01200228027c220c450d0720022f017820022d007a41107472210b20022d007b210e200229038001220f428080808070832110200fa7210d410221110c060b200241f8006a200110aa01200228027c220c450d0620022f017820022d007a41107472210b20022d007b210e200229038001220f428080808070832110200fa7210d410321110c050b200d450d05200c2d000121042001200b417e6a3602042001200c41026a36020020040d05200241b0016a200110fe0520022802b001220e4102460d05200241306a41086a200241f8006a41086a2902003703002002200229027837033020022802b801210d20022802b401210c4104211142002110410021120c020b2001200c20046b3602042001200128020020046a360200200b450d04200241306a41086a200241f8006a41086a29020037030020022002290278370330200b41087621122004ad220f422086200f84220f422088a7210d200fa7210c41052111420021100c010b200e102e0c030b0c010b200220082900003703b001200220092900003700b501200220022903b0013703a001200220022900b5013700a501200e41ff0171411f4d0d0120022f017820022d007a41107472210b200228007b210e200228007f210c200229008301210f200220022900a50137006d200220022903a0013703682002200229006d37005d20022002290368370358200220022903583703482002200229005d37004d2002200229004d37003520022002290348370330200720022f00453b0000200741026a200241c5006a41026a2d00003a0000200f428080808070832110200e4108762112200fa7210d410021110b200241206a41086a200241306a41086a290300220f370300200241106a41086a2213200f37030020022002290330220f3703202002200f3703102005422088220fa722042005a7470d02200441016a221420044f0d010c090b02402005422088a72201450d00200141246c21042006210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012004415c6a22040d000b0b2005a72201450d06200141246c450d062006102e0c060b20044101742215201420142015491b22144104201441044b1bad42247e220f422088a7454102742114200fa721150240024020040d00200241003602780c010b2002410436028001200220063602782002200441246c36027c0b200241306a20152014200241f8006a107d2002280238211420022802304101460d03200228023421062005422088220fa72104201441246ead21050b2006200441246c6a22042010200dad8437000c2004200c36000820042012410874200e41ff0171723600042004200b3b0001200420113a0000200441036a200b4110763a0000200420022903103700142004411c6a2013290300370000200f422086200542ffffffff0f83844280808080107c2105200a41016a220a2003470d000b0b2006450d0220002005370204200020063602000c030b2014450d030b1036000b200041003602000b200241c0016a24000f0b1038000bd00905057f017e047f017e017f230041f0016b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022040d00200041003602000c010b200328021421052003200341186a280200360224200320043602202003200341206a10ab010240024020032802000d00024002402003280204220620032802244105762201200120064b1b22014105742202417f4c0d000240024020010d00410121070c010b2002102c2207450d020b2001ad2108024002402006450d00410021090340200341003a00a8012003280224417f6a2101200941016a2109410021020240024002400240024003402001417f460d0120034188016a20026a2003280220220a2d00003a00002003200a41016a3602202003200241016a220a3a00a801200320013602242001417f6a2101200a2102200a4120470d000b200341b0016a41086a220220034188016a41086a290300370300200341b0016a41106a220b20034188016a41106a290300370300200341b0016a41186a220c20034188016a41186a29030037030020032003290388013703b001410121010240200a41ff01714120490d00200341e8006a41186a200c290300370300200341e8006a41106a200b290300370300200341e8006a41086a2002290300370300200320032903b001370368410021010b200341c8006a41086a2202200341e8006a41086a290300370300200341c8006a41106a220a200341e8006a41106a290300370300200341c8006a41186a220b200341e8006a41186a2903003703002003200329036837034820010d01200341286a41186a220c200b290300370300200341286a41106a220b200a290300370300200341286a41086a220a2002290300370300200320032903483703282008422088220da722012008a7470d04200141016a22022001490d082001410174220e20022002200e491b22024104200241044b1b220241ffffff3f71200246210e2002410574210220010d0220034100360288010c030b0240200241ff0171450d00200341003a00a8010b200341c8006a41086a200341e8006a41086a290300370300200341c8006a41106a200341e8006a41106a290300370300200341c8006a41186a200341e8006a41186a290300370300200320032903683703480b200842ffffff3f83500d082007102e0c080b200341013602900120032007360288012003200d4205863e028c010b200341b0016a2002200e20034188016a107d20032802b801210220032802b0014101460d0320032802b40121072002410576ad21080b200720014105746a22022003290328370000200241186a200c290300370000200241106a200b290300370000200241086a200a290300370000200842ffffffff0f83200141016aad42208684210820092006470d000b0b2007450d0320002008370204200020073602000c040b20020d010b1038000b1036000b200341003602b801200342013703b0012003410a36026c2003200341086a3602682003200341b0016a3602482003419c016a41013602002003420137028c01200341909dc500360288012003200341e8006a36029801200341c8006a419cebc00020034188016a103d1a20032802b00120032802b80110ef02024020032802b401450d0020032802b001102e0b200041003602000b2005450d002004102e0b200341f0016a24000bf40201037f230041e0006b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200041003602040c010b200328021421042003200341186a2802002202360224200320013602200240024020024104490d002001280000210520032002417c6a3602242003200141046a3602202003200341206a10ab0102402003280200450d00200341003602480c010b200341c8006a200341206a200328020410920120032802482202450d002000200329024c37020820002002360204200020053602000c010b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341909dc5003602482003200341386a360258200341c4006a419cebc000200341c8006a103d1a2003280228200328023010ef020240200328022c450d002003280228102e0b200041003602040b2004450d002001102e0b200341e0006a24000bf90604027f027e077f017e230041b0016b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200042003703000c010b200328021421022003200341106a41086a2802003602442003200136024020034188016a200341c0006a10930102400240024020032d0088014101460d00200341e0006a200341a1016a290000370300200341c8006a41106a20034199016a290000370300200341c8006a41086a20034191016a2900003703002003200329008901370348200328024422044110490d002003200441706a36024420032003280240220441106a360240200441086a29000021052004290000210620034188016a200341c0006a10930120032d0088014101460d00200341e8006a41186a2204200341a1016a290000370300200341e8006a41106a220720034199016a290000370300200341e8006a41086a20034191016a29000037030020032003290089013703682003280244220841104f0d010b20034100360270200342013703682003410a36024c2003200341086a3602482003200341e8006a3602202003419c016a41013602002003420137028c01200341909dc500360288012003200341c8006a36029801200341206a419cebc00020034188016a103d1a2003280268200328027010ef020240200328026c450d002003280268102e0b420021050c010b20034188016a41086a2209200341c8006a41086a29030037030020034188016a41106a220a200341c8006a41106a29030037030020034188016a41186a220b200341c8006a41186a290300370300200341206a41086a220c200341e8006a41086a290300370300200341206a41106a220d2007290300370300200341206a41186a220720042903003703002003200329034837038801200320032903683703202003200841706a36024420032003280240220441106a3602402004290000210e200041206a200441086a290000370300200041186a200e370300200041106a200537030020002006370308200041286a200329038801370300200041306a2009290300370300200041386a200a290300370300200041c0006a200b290300370300200041c8006a2003290320370300200041d0006a200c290300370300200041d8006a200d290300370300200041e0006a2007290300370300420121050b200020053703002002450d002001102e0b200341b0016a24000bd10102037f017e230041206b22032400200341003602082003420137030020022802202104200241286a28020022052003107602402005450d002005410574210503402003200441201074200441206a2104200541606a22050d000b0b200229030021062003200241086a290300370318200320063703102003200341106a41101074200229031021062003200241186a290300370318200320063703102003200341106a411010742000200120032802002204200328020810b20102402003280204450d002004102e0b200341206a24000bb70102027f017e230041206b2203240002404124102c2204450d002003422437020420032004360200200229030021052003200241086a290300370318200320053703102003200341106a41101074200229031021052003200241186a290300370318200320053703102003200341106a41101074200320022802203602102003200341106a410410742000200120032802002202200328020810b20102402003280204450d002002102e0b200341206a24000f0b1036000b9e0303027f017e017f230041206b22032400200341003602082003420137030002404120102c2204450d002003422037021420032004360210200341106a200241246a412010742003200328021022042003280218107402402003280214450d002004102e0b2003200241c4006a412010742003200241e4006a41201074200229030021052003200241086a290300370318200320053703102003200341106a411010740240024020022802104101460d00200341003a00102003200341106a410110740c010b200341013a00102003200341106a410110742003200241146a2802003602102003200341106a410410740b20022802182104200241206a2802002206200310760240200641306c2206450d00200420066a210603402003200441201074200441206a29030021052003200441286a290300370318200320053703102003200341106a41101074200441306a22042006470d000b0b200320022d0084013a00102003200341106a410110742000200120032802002204200328020810b20102402003280204450d002004102e0b200341206a24000f0b1036000b9b0302027f017e230041106b2202240002400240024020002d00004101460d00200241003a000020012002410110742002200041386a28020036020020012002410410744120102c2203450d0220024220370204200220033602002002200041c0006a412010742001200228020022032002280208107402402002280204450d002003102e0b0240024002400240200041e0006a2d00000e03000102030b200241003a000020012002410110740c020b200241013a000020012002410110740c010b200241023a000020012002410110740b20022000413c6a2802003602002001200241041074200029030821042002200041106a290300370308200220043703002001200241101074200041186a29030021042002200041206a290300370308200220043703002001200241101074200041286a29030021042002200041306a2903003703082002200437030020012002411010740c010b200241013a00002001200241011074200220002d00013a000020012002410110742002200041046a28020036020020012002410410740b200241106a24000f0b1036000bd80102047f017e230041206b22022400024002402001280208220341306c4104722204417f4c0d00200128020021012004102c2205450d012002410036020820022004360204200220053602002003200210760240200341306c2203450d00200120036a210303402002200141201074200141206a29030021062002200141286a290300370318200220063703102002200241106a41101074200141306a22012003470d000b0b2000412020022802002201200228020810b20102402002280204450d002001102e0b200241206a24000f0b1038000b1036000b810201037f230041106b2203240020034100360208200342013703002003200228020036020c20032003410c6a410410742003200228020436020c20032003410c6a4104107420022802082104200241106a28020022052003107602402005450d002005410574210503402003200441201074200441206a2104200541606a22050d000b0b200228021421042002411c6a28020022052003107602402005450d002005410574210503402003200441201074200441206a2104200541606a22050d000b0b2003200228022036020c20032003410c6a410410742000200120032802002204200328020810b20102402003280204450d002004102e0b200341106a24000bc90101047f230041106b22032400024002402002410c6a28020022044105742205410472417b4c0d0020054108722205102c2206450d012003410036020820032005360204200320063602002003200228020036020c20032003410c6a410410742002280204210220042003107602402004450d002004410574210403402003200241201074200241206a2102200441606a22040d000b0b2000200120032802002202200328020810b20102402003280204450d002002102e0b200341106a24000f0b1038000b1036000b810201037f230041106b2203240020034100360208200342013703002003200228020036020c20032003410c6a410410742003200228020436020c20032003410c6a4104107420022802082104200241106a28020022052003107602402005450d002005410574210503402003200441201074200441206a2104200541606a22050d000b0b200228021421042002411c6a28020022052003107602402005450d002005410574210503402003200441201074200441206a2104200541606a22050d000b0b2003200228022036020c20032003410c6a410410742000200120032802002204200328020810b20102402003280204450d002004102e0b200341106a24000bac0101047f230041106b2202240002400240200128020822034105744104722204417f4c0d00200128020021012004102c2205450d0120024100360208200220043602042002200536020020032002107602402003450d002003410574210303402002200141201074200141206a2101200341606a22030d000b0b2000412020022802002201200228020810b20102402002280204450d002001102e0b200241106a24000f0b1038000b1036000bc90101017f230041206b22042400200441003602102004420137030820042001370318200441086a200441186a4108107420042002370318200441086a200441186a410810740240024002400240200341ff01710e03000102030b200441003a0018200441086a200441186a410110740c020b200441013a0018200441086a200441186a410110740c010b200441023a0018200441086a200441186a410110740b2000412020042802082203200428021010b2010240200428020c450d002003102e0b200441206a24000b970101047f230041106b22032400024002402002280208220441046a2205417f4c0d00200228020021020240024020050d00410121060c010b2005102c2206450d020b20034100360208200320053602042003200636020020042003107620032002200410742000200120032802002205200328020810b20102402003280204450d002005102e0b200341106a24000f0b1038000b1036000b9c0101047f230041106b22022400024002402001280208220341c4006c41046a2204417f4c0d00200128020021010240024020040d00410121050c010b2004102c2205450d020b200241003602082002200436020420022005360200200320021076200120032002109b012000412020022802002204200228020810b20102402002280204450d002004102e0b200241106a24000f0b1038000b1036000ba00101037f230041106b220324000240024020024105744104722204417f4c0d002004102c2205450d0120034100360208200320043602042003200536020020022003107602402002450d002002410574210203402003200141201074200141206a2101200241606a22020d000b0b2000412020032802002201200328020810b20102402003280204450d002001102e0b200341106a24000f0b1038000b1036000b9c0102027f017e230041206b2203240002404111102c2204450d0020034211370204200320043602002003200241106a41201074200229030021052003200241086a290300370318200320053703102003200341106a41101074200320022d00303a00102003200341106a410110742000200120032802002202200328020810b20102402003280204450d002002102e0b200341206a24000f0b1036000b9c0101057f230041106b220224000240024020012802082203410274220441046a2205417f4c0d00200128020021010240024020050d00410121060c010b2005102c2206450d020b20024100360208200220053602042002200636020020032002107620022001200410742000412020022802002205200228020810b20102402002280204450d002005102e0b200241106a24000f0b1038000b1036000bb20202017f017e230041206b220324002003410036020820034201370300200320022802403602102003200341106a41041074200320022802443602102003200341106a41041074200320022802483602102003200341106a410410742003200228024c3602102003200341106a41041074200229030021042003200241086a290300370318200320043703102003200341106a41101074200229031021042003200241186a290300370318200320043703102003200341106a41101074200229032021042003200241286a290300370318200320043703102003200341106a41101074200229033021042003200241386a290300370318200320043703102003200341106a411010742000200120032802002202200328020810b20102402003280204450d002002102e0b200341206a24000bb20202017f017e230041206b220324002003410036020820034201370300200320022802403602102003200341106a41041074200320022802443602102003200341106a41041074200320022802483602102003200341106a410410742003200228024c3602102003200341106a41041074200229030021042003200241086a290300370318200320043703102003200341106a41101074200229031021042003200241186a290300370318200320043703102003200341106a41101074200229032021042003200241286a290300370318200320043703102003200341106a41101074200229033021042003200241386a290300370318200320043703102003200341106a411010742000200120032802002202200328020810b20102402003280204450d002002102e0b200341206a24000bdd0101027f230041206b22022400200241003602082002420137030002404120102c2203450d002002422037021420022003360210200241106a2001412010742002200228021022032002280218107402402002280214450d002003102e0b024002400240024020012d00200e03000102030b200241003a00102002200241106a410110740c020b200241013a00102002200241106a410110740c010b200241023a00102002200241106a410110740b2000412020022802002201200228020810b20102402002280204450d002001102e0b200241206a24000f0b1036000bae0301037f230041f0006b22032400200341086a4192fdc6004107108102200341186a4190a0c5004113108102200320013602382003200341386a410410a301370348200341ec006a2201200341386a41046a3602002003200341c8006a41086a3602642003200341386a3602682003200341c8006a360260200341286a200341e0006a107c024002404120102c2204450d002003422037024c20032004360248200341c8006a2002412010742003200328024822022003280250220410a3013703582001200220046a360200200320023602682003200341d8006a41086a3602642003200341d8006a360260200341386a200341e0006a107c0240200328024c450d002002102e0b20032802302201200328024022046a41206a2202417f4c0d010240024020020d00410121050c010b2002102c2205450d010b2000410036020820002002360204200020053602002000200341086a411010742000200341186a4110107420002003280228220220011074200020032802382201200410740240200328023c450d002001102e0b0240200328022c450d002002102e0b200341f0006a24000f0b1036000b1038000bae0301037f230041f0006b22032400200341086a4192fdc6004107108102200341186a41fd9fc5004113108102200320013602382003200341386a410410a301370348200341ec006a2201200341386a41046a3602002003200341c8006a41086a3602642003200341386a3602682003200341c8006a360260200341286a200341e0006a107c024002404120102c2204450d002003422037024c20032004360248200341c8006a2002412010742003200328024822022003280250220410a3013703582001200220046a360200200320023602682003200341d8006a41086a3602642003200341d8006a360260200341386a200341e0006a107c0240200328024c450d002002102e0b20032802302201200328024022046a41206a2202417f4c0d010240024020020d00410121050c010b2002102c2205450d010b2000410036020820002002360204200020053602002000200341086a411010742000200341186a4110107420002003280228220220011074200020032802382201200410740240200328023c450d002001102e0b0240200328022c450d002002102e0b200341f0006a24000f0b1036000b1038000bca0201037f230041e0006b22022400200241086a4192fdc6004107108102200241186a41a3a0c5004109108102024002404104102c2203450d002002420437023c20022003360238200241386a20014120107420022001280220360250200241386a200241d0006a410410742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000bdd0302077f017e230041f0006b22022400200241086a200110cf052002280208210120022002280210220336021c20022001360218200241206a2001200310ed0202400240200228022022030d00410021040c010b200228022421052002200241286a2802002204360234200220033602300240024020044104490d00200328000021062002200341046a36023020022004417c6a220736023420074104490d002002200341086a360230200328000421072002200441786a220836023420084104490d002002200441746a36023420022003410c6a36023020032800082108200241d8006a200241306a10e70120022802582204450d00200229025c21090c010b4100210420024100360240200242013703382002410a36024c2002200241186a3602482002200241386a360254200241ec006a41013602002002420137025c200241909dc5003602582002200241c8006a360268200241d4006a419cebc000200241d8006a103d1a2002280238200228024010ef020240200228023c450d002002280238102e0b0b02402005450d002003102e0b024020040d00410021040c010b200020093702102000200836020820002007360204200020063602000b2000200436020c0240200228020c450d002001102e0b200241f0006a24000bb10201037f230041e0006b22022400200241086a4192fdc6004107108102200241186a41aca0c500410d108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000bd60101037f230041206b220224002002200010cf05200228020821032002280200210020024100360218200242013703102002200128020036021c200241106a2002411c6a410410742002200128020436021c200241106a2002411c6a410410742002200128020836021c200241106a2002411c6a41041074200128020c2104200141146a2802002201200241106a1076200241106a2004200141027410742000200320022802102201200228021810b20102402002280214450d002001102e0b02402002280204450d002000102e0b200241206a24000bb10201037f230041e0006b22022400200241086a4192fdc6004107108102200241186a41dfa2c500410a108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000ba30201047f230041206b220224002002200010d30520022802082103200228020021042002410036021820024201370310200241106a200141386a412010742002200136021c2002411c6a200241106a10af012002200141106a36021c2002411c6a200241106a10af0120012802202100200141286a2802002205200241106a10760240200541186c2205450d00200020056a210503402002200036021c2002411c6a200241106a10af01200041106a200241106a109102200041186a22002005470d000b0b200128022c2100200141346a2802002205200241106a1076200241106a2000200541027410742004200320022802102200200228021810b20102402002280214450d002000102e0b02402002280204450d002004102e0b200241206a24000bac0201037f230041e0006b2202240020024192fdc6004107108102200241106a41e9a2c5004106108102024002404120102c2203450d002002422037023420022003360230200241306a200141201074200241c0006a200228023022012002280238220310d803200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c0006a360250200241206a200241d0006a107c02402002280234450d002001102e0b2002280228220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b20004100360208200020013602042000200436020020002002411010742000200241106a411010742000200228022022012003107402402002280224450d002001102e0b200241e0006a24000f0b1036000b1038000b130020004117360204200041f0a2c5003602000b340020004192fdc60036020420004100360200200041146a411e360200200041106a419095c600360200200041086a42073702000b3401017f230041106b220224002000410036020820004201370200200241053a000f20002002410f6a41011074200241106a24000b4e01017f230041106b2202240020004100360208200042013702002002420037030820024200370300200020024110107420024200370308200242003703002000200241101074200241106a24000b2f01017f02404104102c22020d001036000b2000420437020420002002360200410020001076410841002000109d010b4601027f230041106b2202240002404110102c22030d001036000b200042103702042000200336020020024200370308200242003703002000200241101074200241106a24000b5901027f230041206b220224002000410036020820004201370200200241106a4200370300200241003602082002410036021c20002002411c6a41041074200241086a4104722203200010f201200310bc02200241206a24000b4901017f230041106b220224002000410036020820004201370200200241003a00042002410036020020022000109102200241003a000f20002002410f6a41011074200241106a24000bf20101037f230041c0006b220224002000410036020820004201370200200241206a4200370300200241086a41106a22034200370300200241106a4200370300200241306a2204410036020020024200370308200242083703282002200241086a36023c2002413c6a200010af012002200336023c2002413c6a200010af0120022802282103200428020022042000107602402004450d00200441306c210403402000200341106a412010742002200336023c2002413c6a200010af01200341306a2103200441506a22040d000b0b0240200228022c2203450d00200341306c450d002002280228102e0b200241c0006a24000b2601017f02404104102c22020d001036000b20004204370204200020023602004100200010760b4301027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241d40036020c20002002410c6a41041074200241106a24000b130020004105360204200041c4d5c6003602000b4201027f230041106b2202240002404104102c22030d001036000b20004204370204200020033602002002411036020c20002002410c6a41041074200241106a24000b4301027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241800236020c20002002410c6a41041074200241106a24000b4201027f230041106b2202240002404104102c22030d001036000b20004204370204200020033602002002411b36020c20002002410c6a41041074200241106a24000b4201027f230041106b2202240002404104102c22030d001036000b20004204370204200020033602002002411c36020c20002002410c6a41041074200241106a24000b4201027f230041106b2202240002404104102c22030d001036000b20004204370204200020033602002002410636020c20002002410c6a41041074200241106a24000bb10201037f230041e0006b22022400200241086a4192fdc6004107108102200241186a41c4abc6004106108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000bd30908017f047e027f017e027f027e047f017e230041e0016b220324002003200236025c20032001360258200341e0006a2001200210ed02024002400240200328026022010d00200041003602200c010b200328026421022003200341e0006a41086a280200360284012003200136028001200341a8016a20034180016a10930102400240024020032d00a8014101460d00200341a0016a200341c1016a29000037030020034188016a41106a200341b9016a29000037030020034188016a41086a200341b1016a290000370300200320032900a90137038801200341c0006a20034180016a10db042003290340a70d00200341c0006a41106a290300210420032903482105200341286a20034180016a10db042003290328a70d00200341286a41106a290300210620032903302107200341206a20034180016a10ab0120032802200d000240024002402003280224220820032802840141186e2209200920084b1bad42187e220a422088a70d00200aa72209417f4c0d000240024020090d004108210b0c010b2009102c220b450d080b200941186ead210a024002402008450d00200341186a210c0340200341086a20034180016a10db042003290308a70d04200c290300210d2003290310210e200320034180016a10ab0120032802000d042003280204210f0240200a422088a72210200aa72209470d00200941016a22112009490d04200941017422122011201220114b1b22114104201141044b1bad42187e2213422088a74541037421112013a721120240024020090d00200341003602a8010c010b200341083602b0012003200b3602a8012003200941186c3602ac010b200341d0016a20122011200341a8016a107d20032802d801210920032802d0014101460d0320032802d401210b200a42808080807083200941186ead84210a0b200b201041186c6a2209200d3703082009200e3703002009200f360210200a4280808080107c210a2008417f6a22080d000b0b200b450d04200341d0016a20034180016a10e70120032802d0010d05200aa72209450d04200941186c0d030c040b20090d070b1038000b200aa72209450d01200941186c450d010b200b102e0b200341003602900120034201370388012003410a3602d4012003200341d8006a3602d001200320034188016a360270200341bc016a4101360200200342013702ac01200341909dc5003602a8012003200341d0016a3602b801200341f0006a419cebc000200341a8016a103d1a20032802880120032802900110ef020240200328028c01450d00200328028801102e0b200041003602200c010b200341f0006a41086a2209200341d0016a41086a280200360200200341a8016a41086a220820034188016a41086a290300370300200341a8016a41106a220f20034188016a41106a290300370300200341a8016a41186a221020034188016a41186a290300370300200320032903d00137037020032003290388013703a801200041186a20063703002000200737031020002004370308200020053703002000200a3702242000200b3602202000412c6a2003290370370200200041346a2009280200360200200041386a20032903a801370300200041c0006a2008290300370300200041c8006a200f290300370300200041d0006a20102903003703000b2002450d002001102e0b200341e0016a24000f0b1036000ba20201037f230041106b220224002001280208210302404101102c2204450d0020004201370204200020043602000240024020030d00200241003a00032000200241036a410110740c010b200241013a00032000200241036a41011074200220012802003602042000200241046a41041074200220012802043602082000200241086a41041074200128021022042000107602402004450d002004410574210403402000200341201074200341206a2103200441606a22040d000b0b200141146a28020021032001411c6a28020022042000107602402004450d002004410574210403402000200341201074200341206a2103200441606a22040d000b0b2002200141206a28020036020c20002002410c6a410410740b200241106a24000f0b1036000bbd0401047f230041106b2202240020002802042103024002400240024020002802004101470d002000410c6a280200220041046a2204417f4c0d020240024002400240024020040d002002410036020820022004360204200241013602000c010b2004102c2205450d07200241003602082002200436020420022005360200200041c000490d01200041808001490d022000418080808004490d030b200241033a000c20022002410c6a410110742002200036020c20022002410c6a4104107420022003200010740c040b200220004102743a000c20022002410c6a4101107420022003200010740c030b200220004102744101723b010c20022002410c6a4102107420022003200010740c020b2002200041027441027236020c20022002410c6a4104107420022003200010740c010b200041086a280200220041046a2204417f4c0d0102400240024002400240024020040d002002410036020820022004360204200241013602000c010b2004102c2205450d07200241003602082002200436020420022005360200200041c000490d01200041808001490d022000418080808004490d030b200241031091012002200036020c20022002410c6a410410740c030b200220004102741091010c020b200220004102744101723b010c20022002410c6a410210740c010b2002200041027441027236020c20022002410c6a410410740b20022003200010740b200120022802002002280208107402402002280204450d002002280200102e0b200241106a24000f0b1038000b1036000b884c09047f017e037f027e077f017e037f017e2a7f23004190056b22032400200341d8006a4192fdc600410710810220034190016a41dfa2c500410a10810202404120102c2204450d00200342203702c404200320043602c004200341c0046a200341d8006a41101074200341c0046a20034190016a4110107402400240024020032802c8042204417f4c0d0020032802c00421050240024020040d00410121060c010b2004102c2206450d040b20062005200410e9082105200341e8036a41086a200341c0046a41086a2802002206360200200320032903c00422073703e803200341ec006a2006360200200341f7006a200341c0046a41026a2d00003a0000200320043602602003200436025c200320053602582003200737026441002108200341003a00742003410c360270200320032f00c0043b007520034190016a200341d8006a10eb050240200341c0016a2d00004102460d00410021080340024020032802b40141ffffff3f71450d0020032802b001102e0b200841016a210820034190016a200341d8006a10eb0520032d00c0014102470d000b0b0240200328025c450d002003280258102e0b0240200341e8006a280200450d002003280264102e0b200341d8006a4192fdc600410710810220034190016a41f09dc500410a1081024120102c2204450d03200342203702c404200320043602c004200341c0046a200341d8006a41101074200341c0046a20034190016a4110107420032802c8042204417f4c0d0020032802c00421050240024020040d00410121060c010b2004102c2206450d040b20062005200410e9082105200341e8036a41086a200341c0046a41086a2802002206360200200320032903c00422073703e803200341ec006a2006360200200341f7006a200341c0046a41026a2d00003a0000200320043602602003200436025c200320053602582003200737026441002109200341003a00742003410d360270200320032f00c0043b007520034190016a200341d8006a108c050240200341b4016a2d00004102460d00410021090340200941016a210920034190016a200341d8006a108c0520032d00b4014102470d000b0b0240200328025c450d002003280258102e0b0240200341e8006a280200450d002003280264102e0b02402001450d00417f200820096a220420042008491b20024d0d00200041e0eac60036020420004101360200200041086a41163602000c030b200341d8006a4192fdc600410710810220034190016a41aca0c500410d1081024120102c2204450d03200342203702c404200320043602c004200341c0046a200341d8006a41101074200341c0046a20034190016a4110107420032802c8042204417f4c0d0020032802c00421010240024020040d00410121050c010b2004102c2205450d040b20052001200410e9082101200341e8036a41086a200341c0046a41086a2802002205360200200320032903c00422073703e803200341ec006a2005360200200341f7006a200341c2046a2d00003a0000200320043602602003200436025c20032001360258200320073702644100210a200341003a00742003410e360270200320032f00c0043b007520034190016a200341d8006a108d05024020032802bc012204450d004100210a0340024020032802c00141ffffffff0371450d002004102e0b200a41016a210a20034190016a200341d8006a108d0520032802bc0122040d000b0b0240200328025c450d002003280258102e0b0240200341d8006a41106a280200450d002003280264102e0b200341d8046a22044200370300200341c0046a41106a22014200370300200341c0046a41086a22054200370300200342003703c00420034190016a41f8fcc6004108108102200520034190016a41086a220629000037030020032003290090013703c00420034190016a41a8aac800410d1081022004200629000037030020012003290090013703002003200341c0046a412010f802200341106a29030021072003290308210b2003290300210c4110102c220d450d03200d200b4200200ca722041b370300200d2007420020041b370308200341d8006a4192fdc600410710810220034190016a41f09dc500410a1081024120102c2204450d03200342203702c404200320043602c004200341c0046a200341d8006a41101074200341c0046a20034190016a4110107420032802c8042204417f4c0d0020032802c00421010240024020040d00410121050c010b2004102c2205450d040b20052001200410e90821014108210e200341c8016a41086a200341c0046a41086a2802002205360200200341386a41026a220620034190016a41026a2d00003a0000200320032903c00422073703c801200320032f0090013b0138200341ac036a2005360200200320043602a0032003200436029c032003200136029803200320073702a4034100210f200341003a00b4032003410d3602b003200341b7036a20062d00003a0000200320032f01383b00b50320034190016a20034198036a108c05410021100240200341b4016a2d00004102460d0041002111410021124100210f410021104108210e0340200341d8006a41206a20034190016a41206a290300370300200341d8006a41186a220420034190016a41186a22052903002207370300200341d8006a41106a220120034190016a41106a2206290300220b370300200341d8006a41086a221320034190016a41086a2202290300220c37030020032003290390012214370358200341e8036a41186a22152007370300200341e8036a41106a2216200b370300200341e8036a41086a2217200c370300200320143703e8032005200429030037030020062001290300370300200220132903003703002003200329035837039001200d200341e8036a10ee0521074120102c2201450d05200120032903e803370000200141186a2015290300370000200141106a2016290300370000200141086a2017290300370000200341c0046a41086a2002290300220b370300200341c0046a41106a2006290300220c370300200341c0046a41186a20052903002214370300200320032903900122183703c004200520143703002006200c3703002002200b37030020032018370390010240200f2010470d00200f41016a2204200f490d0320122004201220044b1b22044104200441044b1bad42387e220b422088a7454103742104200ba7211302400240200f0d00200341003602e0020c010b200341083602e802200320113602e4022003200e3602e0020b200341a8026a20132004200341e0026a107d20032802b0022104024020032802a8024101470d002004450d040c070b20032802ac02210e200441386e21100b200e20116a22042007370300200441086a200329039001370300200441106a2002290300370300200441186a2006290300370300200441206a20052903003703002004412c6a428180808010370200200441286a2001360200201141386a2111201241026a2112200f41016a210f20034190016a20034198036a108c0520032d00b4014102470d000b0b0240200328029c03450d00200328029803102e0b0240200341a8036a280200450d0020032802a403102e0b200341d8006a4192fdc600410710810220034190016a41aca0c500410d1081024120102c2204450d03200342203702c404200320043602c004200341c0046a200341d8006a41101074200341c0046a20034190016a4110107420032802c8042204417f4c0d0020032802c00421010240024020040d00410121050c010b2004102c2205450d040b20052001200410e9082101200341286a41086a200341c0046a41086a22172802002205360200200320032903c00422073703282003420037021c200341386a41146a2005360200200341d7006a200341256a41026a2d00003a0000200320043602402003200436023c2003200136023820032007370244200341003a00542003410e360250200320032f00253b0055200341d8006a200341386a108d0502402003280284012219450d00200341a8026a411c6a211a200341c0046a410472211b200341c0046a411c6a211c200341e0026a411c6a211d200341c8016a41206a211641002112034020034190016a41306a200341d8006a41306a220429030037030020034190016a41286a200341d8006a41286a220129030037030020034190016a41206a200341d8006a41206a290300220737030020034190016a41186a2205200341d8006a41186a290300220b37030020034190016a41106a2206200341d8006a41106a290300220c37030020034190016a41086a2202200341d8006a41086a290300221437030020032003290358221837039001200341c8016a41286a200128020036020020162007370300200341c8016a41186a200b370300200341c8016a41106a200c370300200341c8016a41086a2014370300200320183703c8012004280200211e200328028c01211f200341f8016a41086a2220201641086a280200360200200320162903003703f801200341c0046a41186a22212005290300370300200341c0046a41106a222220062903003703002017200229030037030020032003290390013703c004024002402012450d00200328021821130c010b41f004102c2212450d0641002113201241003b018e02201241003602002003201236021c200341003602180b0240024002400240024002400240024002400240024002400340201241186a210120124190026a211120122f018e022215410574210241002104417f210502400340024020022004470d00201521050c020b200341c0046a201120046a412010ec082206450d03200541016a2105200141186a2101200441206a21042006417f4a0d000b0b02402013450d002013417f6a2113201220054102746a41f0046a28020021120c010b0b20034188026a41086a201b41086a2223290200220737030020034188026a41106a201b41106a2224290200220b37030020034188026a41186a201b41186a222528020022043602002003201b290200220c3703880220032802c0042113200341e0026a41186a22262004360200200341e0026a41106a2227200b370300200341e0026a41086a222820073703002003200c3703e002200341d0036a41086a22292020280200360200200320032903f8013703d00302402015410a4b0d00200341e8036a41086a22062029280200360200200320032903d0033703e803200341a0046a41186a22022026280200360200200341a0046a41106a22222027290300370300200341a0046a41086a22202028290300370300200320032903e0023703a004200541016a2121201541016a21010240200520154f22270d00201120214105746a201120054105746a20012005417f736a41057410ea081a0b201120054105746a22042013360000200441146a20222903003700002004410c6a2020290300370000200420032903a0043700042004411c6a200228020036000020172006280200360200200320032903e8033703c004201241046a2104024020270d002004202141186c6a2004200541186c6a201520056b41186c10ea081a0b2004200541186c6a220420032903c004370200201728020021052004201f3602142004201e3602102004201936020c200441086a2005360200201220013b018e020c0b0b4100212a4104210402400240200541054f0d00200521060c010b4105210441052106024002402005417b6a0e020201000b200541796a21064101212a410621040c010b410021064101212a0b41f004102c2201450d11200141003b018e0220014100360200200120122f018e02222b2004417f736a22053b018e02201120044105746a2202280000212c200341a0046a41186a222d2002411c6a280000360200200341a0046a41106a2215200241146a290000370300200341a0046a41086a22202002410c6a290000370300200320022900043703a004200341f8046a41106a222e201241046a222f200441186c6a220241106a290200370300200341f8046a41086a2230200241086a290200370300200320022902003703f8042005410c4f0d01202b200441016a22026b2005470d0220014190026a201120024105746a200541057410e9081a200141046a202f200241186c6a200541186c10e9081a201c20032903f8043702002021202d280200360200201c41086a22312030290300370200201c41106a2232202e290300370200201220043b018e02202220152903002207370300200341e8036a41086a222b2020290300370300200341e8036a41106a222f2007370300200341e8036a41186a22332021290300370300200341e8036a41206a2234200341c0046a41206a2235290300370300200341e8036a41286a2236200341c0046a41286a2237290300370300200341e8036a41306a2238200341c0046a41306a2239280200360200200320032903a0043703e80320302029280200360200200320032903d0033703f80420012012202a1b22052f018e022102202d20262802003602002015202729030037030020202028290300370300200320032903e0023703a00420054190026a2104200241016a21110240200641016a222a20024b223a0d002004202a4105746a200420064105746a20112006417f736a41057410ea081a0b200420064105746a22042013360000200441146a20152903003700002004410c6a2020290300370000200420032903a0043700042004411c6a202d28020036000020172030280200360200200320032903f8043703c004200541046a21040240203a0d002004202a41186c6a2004200641186c6a200220066b41186c10ea081a0b2004200641186c6a220420032903c004370200201728020021062004201f3602142004201e3602102004201936020c200441086a2006360200200520113b018e0220034198036a41306a2204203828020036020020034198036a41286a2205203629030037030020034198036a41206a2206203429030037030020034198036a41186a221f203329030037030020034198036a41106a2219202f29030037030020034198036a41086a221e202b290300370300200320032903e80337039803200341e0026a41306a223b2004280200360200200341e0026a41286a223c2005290300370300200341e0026a41206a223d20062903003703002026201f290300370300202720192903003703002028201e29030037030020032003290398033703e002024002400240201228020022130d004100212a0c010b4100212a2001213a202c213e034020122f018c022102201f202628020036020020192027290300370300201e2028290300370300200320032903e00237039803200341d0036a41106a223f201d41106a2902003703002029201d41086a2902003703002003201d2902003703d00320132f018e022212410b490d024100211141042104024020024105490d0020022104024002402002417b6a0e020201000b200241796a210241012111410621040c010b4100210241012111410521040b41a005102c2201450d14200141003b018e0220014100360200200120132f018e0222402004417f736a22053b018e0220134190026a224120044105746a2206280000212c202d2006411c6a2800003602002015200641146a29000037030020202006410c6a290000370300200320062900043703a004202e201341046a2242200441186c6a220641106a2902003703002030200641086a290200370300200320062902003703f8042005410c4f0d062040200441016a22066b2005470d0720014190026a204120064105746a200541057410e9081a200141046a2042200641186c6a200541186c10e9081a201320043b018e0220172020290300370300202220152903003703002021202d280200360200201c20032903f804370200203120302903003702002032202e290300370200200320032903a0043703c00420012f018e02220541016a21402005410c4f0d08201220046b22042040470d09202a41016a212a200141f0046a201320064102746a41f0046a200441027410e9081a4100210402400340200120044102746a41f0046a280200220620043b018c02200620013602002004200420054922066a220420054b0d0120060d000b0b20382039280200360200203620372903003703002034203529030037030020332021290300370300202f2022290300370300202b2017290300370300200320032903c0043703e8032015203f29030037030020202029290300370300200320032903d0033703a0042001201320111b22062f018e0221052003203e3602c004201b2003290398033700002023201e290300370000202420192903003700002025201f28020036000020064190026a2112200541016a21110240200241016a220420054b223e0d00201220044105746a201220024105746a2002417f7320116a41057410ea081a0b201220024105746a221220032903c004370000201241186a2021290300370000201241106a2022290300370000201241086a20172903003700002022201529030037030020172020290300370300200320032903a0043703c004200641046a21120240203e0d002012200441186c6a2012200241186c6a200520026b41186c10ea081a0b2012200241186c6a221220032903c004370200201241106a2022290300370200201241086a2017290300370200200641f0046a21120240200241026a223e200541026a22054f0d002012203e4102746a201220044102746a2004417f7320056a41027410ea081a0b201220044102746a203a360200200620113b018e020240200420054f0d00200620024102746a41f4046a2104034020042802002205200241016a22023b018c0220052006360200200441046a210420112002470d000b0b2028202b2903003703002027202f29030037030020262033290300370300203d2034290300370300203c2036290300370300203b2038280200360200200320032903e8033703e002201321122013280200220421132001213a202c213e20040d000b0b200341a8026a41306a203b280200360200200341a8026a41286a203c290300370300200341a8026a41206a203d290300370300200341a8026a41186a20262903002207370300200341a8026a41106a2027290300220b370300200341a8026a41086a2028290300220c370300200320032903e00222143703a802202b200c370300202f200b370300203320073e02002028201a41086a2902003703002027201a41106a290200370300200320143703e8032003201a2902003703e002200328021c2205450d082003280218210641a005102c2204450d12200420053602f004200441003b018e0220044100360200200541003b018c02200520043602002003200436021c2003200641016a360218202120332802003602002022202f2903003703002017202b290300370300200320032903e8033703c00420192027290300370300201e2028290300370300200320032903e002370398032006202a470d0920042f018e022206410b4f0d0a2004200641016a22023b018e02200420064105746a22054190026a202c36000020054194026a20032903c0043700002005419c026a2017290300370000200541a4026a2022290300370000200541ac026a20212802003600002004200641186c6a220541046a2003290398033702002005410c6a201e290300370200200541146a2019290300370200200441f0046a20024102746a2001360200200120023b018c02200120043602002003200328022041016a360220202a1a20011a0c0c0b2015203f29030037030020202029290300370300200320032903d0033703a004201b2003290398033700002023201e290300370000202420192903003700002025201f2802003600002003203e3602c00420134190026a2104201241016a21060240201220024d22010d00200420024105746a220541206a20052002417f7320066a41057410ea081a0b200420024105746a220420032903c004370000200441186a2021290300370000200441106a2022290300370000200441086a20172903003700002022201529030037030020172020290300370300200320032903a0043703c004200241016a2104201341046a2105024020010d002005200441186c6a2005200241186c6a201220026b41186c10ea081a0b2005200241186c6a220520032903c004370200200541106a2022290300370200200541086a2017290300370200201341f0046a2105201241026a2111024020010d00200241027420056a41086a200520044102746a2004417f7320116a41027410ea081a0b200520044102746a203a360200201320063b018e02200420114f0d0a20132004417f6a22044102746a41f4046a2101034020012802002205200441016a22043b018c0220052013360200200141046a210120062004470d000c0b0b0b2001416c6a220520032903f801370200200141786a2206280200210420202802002102200620193602002001417c6a220628020021112006201e3602002001201f360200200541086a20023602002004450d0a201141ffffffff0371450d0a2004102e0c0a0b2005410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b2005410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b2040410c41f49cc700104d000b41f49bc7004128419c9cc7001039000b41e8aac700412b4194abc7001039000b41e899c700413041989ac7001039000b41a89ac700412041c89ac7001039000b2003200328022041016a3602200b200341d8006a200341386a108d052003280284012219450d01200328021c21120c000b0b0240200328023c450d002003280238102e0b0240200341c8006a280200450d002003280244102e0b200341d8006a4192fdc600410710810220034190016a41dfa2c500410a1081024120102c2204450d03200342203702c404200320043602c004200341c0046a200341d8006a41101074200341c0046a20034190016a4110107420032802c8042204417f4c0d0020032802c00421010240024020040d00410121050c010b2004102c2205450d040b20052001200410e9082101200341a8026a41086a200341c0046a41086a22212802002205360200200341c8016a41026a220620034190016a41026a2d00003a0000200320032903c00422073703a802200320032f0090013b01c801200341fc036a2005360200200320043602f003200320043602ec03200320013602e803200320073702f403200341003a0084042003410c3602800420034187046a20062d00003a0000200320032f01c8013b00850420034190016a200341e8036a10eb0520034190016a41306a2d00004102460d010340202120034190016a41086a22152903002207370300200341c0046a41106a20034190016a41106a2216290300220b370300200341c0046a41186a20034190016a41186a2217290300220c370300200320032903900122143703c00420032802bc01211120032802b001211320032802b401211920032802b8012106200341d8006a41186a221e200c370300200341d8006a41106a221f200b370300200341d8006a41086a22202007370300200320143703580240024020060d00410021120c010b41002122410021124100210502400340024002402012450d00201320054105746a21042013200520226a4105746a210103400240200341186a200410a1022202450d00200228020820114b0d030b20012004290000370000200141186a200441186a290000370000200141106a200441106a290000370000200141086a200441086a290000370000200441206a2104200141206a21012006200541016a22054b0d000c040b0b201320054105746a210403400240200341186a200410a1022201450d00200128020820114b0d020b200441206a21042006200541016a22054b0d000b410021120c030b2022417f6a2122201241016a21122006200541016a22054b0d000b0b024020120d00410021120c010b2013200520126b4105746a201320054105746a200620056b41057410ea081a0b200d200341d8006a10ee0521072017201e2903003703002016201f2903003703002015202029030037030020032003290358370390010240200f2010470d00200f41016a2204200f490d02200f41017422012004200120044b1b22044104200441044b1bad42387e220b422088a7454103742104200ba7210102400240200f0d0020034100360298030c010b200341083602a0032003200e360298032003200f41386c36029c030b200341e0026a2001200420034198036a107d20032802e8022104024020032802e0024101470d0020040d060c030b20032802e402210e200441386e21100b200e200f41386c6a220420073703002004200329039001370308200441106a2015290300370300200441186a2016290300370300200441206a2017290300370300200441306a200620126b3602002004412c6a201936020020042013360228200f41016a210f20034190016a200341e8036a10eb0520032d00c0014102470d000c020b0b1038000b2009ad220742f8cdaf0d7e2008ad220b42c8acef0b7e7c200aad220c42d8e5f90a7e7c200b42c0d1e1237e7c200742c0d1e1237e7c42c0d1e1237c220b200c42c0f0f50b7e7c2107024020032802ec03450d0020032802e803102e0b2007200b5421040240200341f8036a280200450d0020032802f403102e0b427f200720041b210b200328021c21042003410036021c02402004450d00024020032802182201450d002001417f6a2101034020042802f00421042001450d012001417f6a21010c000b0b024020032802202202450d0041002105200341c8046a211203402002417f6a210241012101024002400340200520042f018e02490d010240200428020022060d002004102e410021040c030b20042f018c0221052004102e2001417f6a2101200621040c000b0b200341c0046a41186a200420054105746a220641a8026a290000370300200341c0046a41106a200641a0026a290000370300201220064198026a290000370300200320064190026a2900003703c004200541016a21062004200541186c6a220541146a2902002107200541106a2802002111024020014101470d00200621050c010b200420064102746a41f0046a280200210402402001450d000340200141016a220520014f210620042802f00421042005210120060d000b0b410021050b2011450d020240200742ffffffff0383500d002011102e0b20020d000b0b0340200428020021012004102e2001210420010d000b0b200d102e200041186a200b370300200041106a200f3602002000410c6a2010360200200041086a200e360200200041003602000b20034190056a24000f0b1036000b980501047f23004190016b220524002005200436021420052003360210200541d4e2cc00200141086a20024108491b36021820054100200241786a2201200120024b1b36021c200541e0006a200541186a109301200541c0006a41086a2202200541e9006a290000370300200541c0006a41106a2201200541f1006a290000370300200541c0006a41186a2203200541f9006a29000037030020052005290061370340024002400240024020052d00604101460d00200541206a41186a2003290300370300200541206a41106a2001290300370300200541206a41086a200229030037030020052005290340370320200541086a200541106a10ab01024002402005280208450d00200541003602600c010b200541e0006a200541106a200528020c10920120052802602202450d00200528026421010240200528021422034104490d00200541e8006a280200210620052802102204280000210720052003417c6a22083602142005200441046a22043602102008450d0020042d0000210820052003417b6a3602142005200441016a3602104100210320080e020403000b200141ffffff3f71450d002002102e0b20054186016a41026a2005418a016a41026a2d00003a0000200520052f018a013b018601200041023a00300c030b200041023a00300c020b410121030b20054186016a41026a22042005418d016a41026a2d00003a0000200520052f008d013b018601200041186a200541206a41186a290300370000200041106a200541206a41106a290300370000200041086a200541206a41086a29030037000020002005290320370000200020033a00302000200736022c200020063602282000200136022420002002360220200020052f0186013b0031200041336a20042d00003a00000b20054190016a24000be60303057f017e037f230041c0006b22022400200241086a200128020c200141146a280200108b050240024020022802082203450d00200141086a2104200141106a2105024003400240024020042802002206200229020c2207422088a722084b0d0020012802002003200610ec08450d010b2007a7450d032003102e0c030b02402005280200450d00200128020c102e0b2001200336020c20052007370200200241086a2003200810ed020240024020022802082203450d0020022802102109200228020c2108024020012d001c450d00200128020c200128021410ff010b2001280214220a20042802002206490d03200241086a200128020c20066a200a20066b20032009200128021811050020022d00384102470d012008450d002003102e0b200241086a200128020c2001280214108b05200228020822030d010c030b0b20002002290308370200200041306a200241086a41306a280200360200200041286a200241086a41286a290300370200200041206a200241086a41206a290300370200200041186a200241086a41186a290300370200200041106a200241086a41106a290300370200200041086a200241086a41086a2903003702002008450d022003102e0c020b2006200a41e89ec5001056000b200041023a00300b200241c0006a24000bf80301017f23004190016b220524002005200436021420052003360210200541d4e2cc00200141086a20024108491b36021820054100200241786a2201200120024b1b36021c200541e8006a200541186a109301200541c8006a41086a2202200541f1006a290000370300200541c8006a41106a2201200541f9006a290000370300200541c8006a41186a220320054181016a290000370300200520052900693703480240024002400240024020052d00684101460d00200541286a41186a2003290300370300200541286a41106a2001290300370300200541286a41086a200229030037030020052005290348370328200541086a200541106a10ab0120052802080d03200528020c21022005418094ebdc0336026c2005200236026820052802142201450d03200541e8006a2002418094ebdc034b4102746a2802002104200528021022022d0000210320052001417f6a3602142005200241016a3602104100210220030e020201030b200041023a00240c030b410121020b20002005290328370000200041186a200541286a41186a290300370000200041106a200541286a41106a290300370000200041086a200541286a41086a290300370000200020023a002420002004360220200020052f00253b0025200041276a200541276a2d00003a00000c010b200041023a00240b20054190016a24000bf70302027f017e23004180016b220524002005200436020c20052003360208200541d4e2cc00200141086a20024108491b36021020054100200241786a2201200120024b1b360214200541d8006a200541106a109301200541386a41086a2202200541e1006a290000370300200541386a41106a2201200541e9006a290000370300200541386a41186a2206200541f1006a290000370300200520052900593703380240024020052d00584101460d00200541186a41186a2006290300370300200541186a41106a2001290300370300200541186a41086a200229030037030020052005290338370318024020044104490d002005200341046a36020820052004417c6a220236020c20024104490d00200328000021012005200341086a3602082005200441786a220236020c20024104490d00200328000421022005200441746a36020c20052003410c6a36020820032800082104200541d8006a200541086a10e70120052802582203450d00200529025c210720002005290318370000200041186a200541186a41186a290300370000200041106a200541186a41106a290300370000200041086a200541186a41086a290300370000200020073702302000200336022c2000200436022820002002360224200020013602200c020b2000410036022c0c010b2000410036022c0b20054180016a24000ba10706017f027e027f017e027f017e230041a0026b22022400200041086a29030021032000290300210420024190026a200110e505200241e8006a200228029002220020022802980210f402200241c8006a41086a2201200241f1006a290000370300200241c8006a41106a2205200241f9006a290000370300200241c8006a41186a220620024181016a2900003703002002200229006937034802400240024002400240024020022d00684101470d00200241286a41186a2006290300370300200241286a41106a2005290300370300200241286a41086a2001290300370300200220022903483703280240200228029402450d002000102e0b200241e8006a41186a200241286a41186a290300370300200241e8006a41106a200241286a41106a290300370300200241e8006a41086a200241286a41086a29030037030020022002290328370368200241d0016a4192fdc6004107108102200241e0016a41e9a2c50041061081024120102c2200450d042002422037028402200220003602800220024180026a200241e8006a4120107420024190026a2002280280022200200228028802220110d803200241d4006a200020016a36020020022000360250200220024190026a41106a36024c200220024190026a360248200241f0016a200241c8006a107c0240200228028402450d002000102e0b20022802f801220141206a2200417f4c0d050240024020000d00410121050c010b2000102c2205450d050b200241003602c801200220003602c401200220053602c001200241c0016a200241d0016a41101074200241c0016a200241e0016a41101074200241c0016a20022802f001220020011074024020022802f401450d002000102e0b200241e8006a20022802c001220520022802c80110e60520022802c40121002002280288012206450d0120024180016a290300210720024198016a280200210820024194016a28020021092002290378210a200228028c01210102402000450d002005102e0b02402001450d00200141186c450d002006102e0b200841ffffffff0371450d032009102e0c030b200228029402450d012000102e0c010b2000450d002005102e0b4200210a420021070b200241186a20042003427f420010e708200241086a200a20072002290318220342012003420156200241186a41086a29030022034200522003501b22001b2003420020001b10e708200241086a41086a290300210320022903082104200241a0026a24002004427f2003501b0f0b1036000b1038000bc00c07047f017e047f017e017f027e017f230041c0016b22032400200341d8006a4192fdc6004107108102200341f8006a41f09dc500410a108102024002400240024002404120102c2204450d002003422037023c20032004360238200341386a200341d8006a41101074200341386a200341f8006a4110107420032802402204417f4c0d04200328023821050240024020040d00410121060c010b2004102c2206450d010b20062005200410e9082105200341186a41086a200341386a41086a2802002206360200200320032903382207370318200341ec006a2006360200200341f7006a200341386a41026a2d00003a0000200320043602602003200436025c200320053602582003200737026441002104200341003a00742003410d360270200320032f00383b0075200341f8006a200341d8006a108c0502402003419c016a2d00004102460d00410021040340200441016a2104200341f8006a200341d8006a108c0520032d009c014102470d000b0b0240200328025c450d002003280258102e0b0240200341e8006a280200450d002003280264102e0b02402001450d00200420024d0d00200041f6eac600360204200041086a4117360200410121040c040b200341d8006a4192fdc6004107108102200341f8006a41f09dc500410a1081024120102c2201450d002003422037023c20032001360238200341386a200341d8006a41101074200341386a200341f8006a4110107420032802402201417f4c0d04200328023821050240024020010d00410121060c010b2001102c2206450d010b20062005200110e9082105200341086a41086a200341386a41086a2802002206360200200341046a41026a2202200341f8006a41026a2d00003a0000200320032903382207370308200320032f00783b01042003412c6a2006360200200320013602202003200136021c2003200536021820032007370224200341003a00342003410d360230200341376a20022d00003a0000200320032f01043b0035200341f8006a200341186a108c0520032d009c014102460d01200341d8006a41186a2201200341f8006a41186a290300370300200341d8006a41106a2205200341f8006a41106a290300370300200341d8006a41086a200341f8006a41086a290300370300200320032903783703584120102c2208450d0020082003290358370000200841186a2001290300370000200841106a2005290300370000200841086a200341d8006a41086a2209290300370000200341386a41186a200341186a41186a290300370300200341386a41106a200341186a41106a290300370300200341386a41086a200341186a41086a29030037030020032003290318370338200341f8006a200341386a108c0502400240024020032d009c014102470d0041012101410121060c010b4120210241012101410121060340200341d8006a41186a200341f8006a41186a220a2903002207370300200341d8006a41106a200341f8006a41106a220b290300220c3703002009200341f8006a41086a220d290300220e37030020032003290378220f370358200a2007370300200b200c370300200d200e3703002003200f370378024020062001470d00200141016a22052001490d08200141017422102005201020054b1b22054104200541044b1b220541ffffff3f712005462110200541057421050240024020010d00200341003602b0010c010b200341013602b801200320083602b001200320014105743602b4010b200341a0016a20052010200341b0016a107d20032802a801210120032802a0014101460d0320032802a4012108200141057621010b200820026a22052003290378370000200541186a200a290300370000200541106a200b290300370000200541086a200d290300370000200241206a2102200641016a2106200341f8006a200341386a108c0520032d009c014102470d000b0b0240200328023c450d002003280238102e0b200341c8006a280200450d032003280244102e0c030b2001450d040b1036000b0240200328021c450d002003280218102e0b41002101410121080240200341286a280200450d002003280224102e0b410021060b200041186a2004ad42c0f0f50b7e370300200041106a20063602002000410c6a2001360200200041086a2008360200410021040b20002004360200200341c0016a24000f0b1038000bdb0401097f230041c0016b2202240020024188016a200110d305200241306a200228028801220320022802900110e60520024198016a41086a2204200241ec006a29020037030020024198016a41106a2205200241f4006a29020037030020024198016a41186a2206200241fc006a29020037030020024198016a41206a220720024184016a2802003602002002200241e4006a290200370398010240024020022802502208450d00200241e0006a2802002109200241dc006a280200210a20022802542101200241086a41206a2007280200360200200241086a41186a2006290300370300200241086a41106a2005290300370300200241086a41086a200429030037030020022002290398013703080240200228028c01450d002003102e0b200241306a41106a200241086a41106a290300370300200241306a41086a200241086a41086a290300370300200241306a41186a200241086a41186a290300370300200241306a41206a200241086a41206a28020036020020024198016a41086a2002413c6a29020037030020024198016a41106a200241c4006a29020037030020024198016a41186a200241cc006a29020037030020022002290308370330200220022902343703980102402001450d00200141186c450d002008102e0b0240200941ffffffff0371450d00200a102e0b2000200229039801370001200041196a200241b0016a290300370000200041116a200241a8016a290300370000200041096a200241a0016a290300370000410121010c010b0240200228028c01450d002003102e0b410021010b200020013a0000200241c0016a24000bd60605067f017e037f017e017f23004180016b22012400200141286a22024200370300200141206a22034200370300200141106a41086a420037030020014200370310200141106a4192fdc6004107108102200141e8006a41a8b4c600410a1081022002200141e8006a41086a29000037030020032001290068370300200141203602342001200141106a360230200141386a200141106a412010ed02024002400240200128023822040d00410021030c010b200128023c21052001200141386a41086a28020036024c20012004360248200141086a200141c8006a10ab010240024020012802080d0002400240200128020c2206200128024c4103762202200220064b1b22024103742203417f4c0d000240024020020d00410421030c010b2003102c2203450d060b2002ad2107024002402006450d000340200128024c22084104490d042001280248220228000021092001200241046a36024820012008417c6a220a36024c200a4104490d042002280004210a2001200841786a36024c2001200241086a36024802402007422088220ba722022007a7470d00200241016a22082002490d042002410174220c20082008200c491b22084104200841044b1b220841ffffffff0171200846410274210c200841037421080240024020020d00200141003602680c010b20014104360270200120033602682001200b4203863e026c0b200141d8006a2008200c200141e8006a107d2001280260210820012802584101460d03200128025c21032007428080808070832008410376ad8421070b200320024103746a2202200a3602042002200936020020074280808080107c21072006417f6a22060d000b0b2003450d030c040b20080d050b1038000b0240200742ffffffff0183500d002003102e0b0b4100210320014100360260200142013703582001410a3602542001200141306a3602502001200141d8006a360264200141fc006a41013602002001420137026c200141909dc5003602682001200141d0006a360278200141e4006a419cebc000200141e8006a103d1a2001280258200128026010ef02200128025c450d002001280258102e0b2005450d002004102e0b0240024020030d0020004100360208200042043702000c010b20002007370204200020033602000b20014180016a24000f0b1036000bc40101057f2001280208210302402001410c6a280200220420024b0d002000410036020820002004ad4220862003ad843702000f0b02402001411c6a28020022050d00200041023602080f0b200141146a2802002101200541027421052003417f6a21030240034002402004200128020022066b220720024b0d00200420024b0d020b200141046a21012003417f6a2103200721042005417c6a22050d000b200041023602080f0b2000200636020c20002007ad4220862003ad84370200200041013602080bd80c08017f017e047f017e067f027e027f027e23004180016b2201240042002102200141306a22034200370300200141286a22044200370300200141186a41086a420037030020014200370318200141186a41a081ca004107108102200141d8006a41f09dc500410a1081022003200141d8006a41086a29000037030020042001290058370300200141d8006a200141186a10880320012802582203410120031b210541022106024002400240200129025c420020031b2207422088a72203450d00200341057441606a41057641016a210841002104200521030240034020032000412010ec08450d01200242017c2102200341206a21032008200441016a2204470d000c020b0b200141306a22094200370300200141286a220a4200370300200141186a41086a220b420037030020014200370318200141d8006a41a081ca004107108102200b200141d8006a41086a220c29000037030020012001290058370318200141d8006a41f8d2c10041121081022009200c290000370300200a2001290058370300200141d8006a200141186a109b0320012802582208410420081b210d4100210641002103410021000240024002400240024002400240200129025c420020081b220e422088220fa722100e020201000b4100210320102100034020032000410176220820036a22112004200d20114102746a280200491b2103200020086b220041014b0d000b0b41012100200d20034102746a28020022082004460d012003200420084b6a21000b20094200370300200a4200370300200b420037030020014200370318200141d8006a41a081ca004107108102200b200c29000037030020012001290058370318200141d8006a41f09dc500410a108102200a41086a200c290000370000200a2001290058370000200141c8006a41046a41003a000020014100360248200141106a200141186a4120200141c8006a4105410010ca040240024002402001280210450d00200120012802142203410520034105491b36025c2001200141c8006a360258200141086a200141d8006a10ab012001280208450d010b410021030c010b200128020c21030b2003418094ebdc0370ad4280fd87d1007e2212428094ebdc038221132012428094ebdc038021122003418094ebdc036e2108200020104b0d0502402010200ea7470d00201041016a22032010490d0720104101742211200320032011491b22034104200341044b1b220341ffffffff03712003464102742111200341027421030240024020100d00200141003602180c010b200141206a41043602002001200d3602182001200f4202863e021c0b200141d8006a20032011200141186a107d200141e0006a280200210320012802584101460d02200128025c210d2003410276ad210e0b200d20004102746a220341046a2003201020006b41027410ea081a20032004360200200e42ffffffff0f83201041016a2203ad42208684210e200320084180fd87d1006c2012a720134280cab5ee01566a6a4b2106410021000b2001200e37024c2001200d360248200d0d01200141306a4200370300200141286a4200370300200141186a41086a2203420037030020014200370318200141d8006a41a081ca0041071081022003200141d8006a41086a220829000037030020012001290058370318200141d8006a41f8d2c1004112108102200a41086a2008290000370000200a2001290058370000200141186a412010ff010c020b2003450d041036000b200141306a4200370300200141286a4200370300200141186a41086a2203420037030020014200370318200141d8006a41a081ca0041071081022003200141d8006a41086a220829000037030020012001290058370318200141d8006a41f8d2c1004112108102200a41086a2008290000370000200a2001290058370000200141186a200141c8006a10c705200d450d00200e42ffffffff0383500d00200d102e0b20000d00200141186a41086a200237030020014102360218200141186a108c06200141013602182001200436021c200141d8006a200141186a10a404200141d3006a200141d8006a41086a2802003600002001200129035837004b200141e4006a200141cf006a290000370000200141c28289aa04360059200141023a00582001200129004837005d200141d8006a10a5040b0240200742ffffff3f83500d002005102e0b20014180016a240020060f0b200020101045000b1038000bd90c04047f017e027f067e230041d0026b22052400200541c8016a2001200210f2050240024002400240024020052802d0014102460d0020052802c8012106200541c8016a41086a2001280204220741086a290000370300200541c8016a41106a200741106a290000370300200541c8016a41186a200741186a290000370300200520063602e801200520072900003703c801200541f0016a200541c8016a10cd0520052802f0012108200520052802f8012207360284022005200836028002200541b0026a2008200710ed020240024020052802b00222070d00420021090c010b20052802b402210a024002400240200541b0026a41086a280200220b4110490d00200b4170714110470d010b200541003602c802200542013703c0022005410a36028c02200520054180026a360288022005200541c0026a36029402200541ac026a41013602002005420137029c02200541909dc50036029802200520054188026a3602a80220054194026a419cebc00020054198026a103d1a20052802c00220052802c80210ef02024020052802c402450d0020052802c002102e0b420021090c010b200741186a290000210c200741086a290000210d2007290010210e2007290000210f420121090b200a450d002007102e0b200d4200200942005222071b210d200f420020071b210f024020052802f401450d002008102e0b200c420020071b210c200e420020071b210e0240200f200354200d200454200d2004511b0d00200f200385200d2004858450450d04200541b8016a20032004428094ebdc03420010e608200541a8016a20032004428094ebdc03420010e70820054198016a20052903a801200541a8016a41086a2903002001350228220d420010e80820054188016a4200200529039801220f200d20052903b8017e220d428094ebdc0380a7417f200d428080808080c0b2cd3b541b200d428094ebdc03824280cab5ee01566aad7c220d200e7d22092009200d5620054198016a41086a290300200d200f54ad7c220f200c7d200d200e54ad7d220d200f56200d200f511b22021b220f4200200d20021b220d428094ebdc03420010e608200541f8006a200f200d428094ebdc03420010e708200541e8006a2005290378200541f8006a41086a2903004280cab5ee01420010e8082005290368220f200529038801220d420188a7200d4280cab5ee017e428094ebdc03824280cab5ee01566aad7c220d200541e8006a41086a290300200d200f54ad7c220f84500d040c020b200541d8006a20032004428094ebdc03420010e608200541c8006a20032004428094ebdc03420010e708200541386a2005290348200541c8006a41086a29030020013502282209420010e808200541286a420020052903382210200920052903587e2209428094ebdc0380a7417f2009428080808080c0b2cd3b541b2009428094ebdc03824280cab5ee01566aad7c2209200e7d22112011200956200541386a41086a2903002009201054ad7c2210200c7d2009200e54ad7d220920105620092010511b22071b22104200200920071b2209428094ebdc03420010e608200541186a20102009428094ebdc03420010e708200541086a2005290318200541186a41086a2903004280cab5ee01420010e808200128022422072003200f7d220920072903007c2210370300200741086a22072004200d7d2003200f54ad7d20072903007c2010200954ad7c370300200141106a2207200728020022072002200720024b1b3602002005290308220f2005290328220d420188a7200d4280cab5ee017e428094ebdc03824280cab5ee01566aad7c220d200541086a41086a290300200d200f54ad7c220f8450450d01200e210d0c020b410021010c030b2001280220220220022903002209200d7c2210370300200241086a22022002290300200f7c2010200954ad7c370300200c200f7c200e200d7c220d200e54ad7c210c0b200141013a002c200541b0026a200541c8016a10cd0520052802b802210220052802b0022101200541003602c802200542013703c002200520043703a0022005200337039802200541c0026a20054198026a411010742005200c3703a0022005200d37039802200541c0026a20054198026a411010742001200220052802c002220720052802c80210b201024020052802c402450d002007102e0b20052802b402450d002001102e0b410121010b2000200636020420002001360200200541d0026a24000b9c0b09047f017e047f027e017f017e037f037e027f230041e0016b220324002003200236021c20032001360218200341206a2001200210ed0202400240200328022022040d00200041003602000c010b200328022421052003200341286a28020036023420032004360230200341106a200341306a10ab010240024020032802100d000240024002400240024020032802142206200328023441d8006e2201200120064b1bad42d8007e2207422088a70d002007a72201417f4c0d000240024020010d00410821080c010b2001102c2208450d020b200141d8006ead2107024002402006450d00200341b8016a41017221020340200341b8016a200341306a10930120032d00b8014101460d0720034198016a41186a2209200241186a29000037030020034198016a41106a220a200241106a29000037030020034198016a41086a220b200241086a2900003703002003200229000037039801200328023422014110490d072003200141706a36023420032003280230220141106a360230200141086a290000210c2001290000210d200341b8016a200341306a10e90120032802b801220e450d0720032902bc01210f200341086a200341306a10ab0102402003280208450d00200341003602b8010c070b200341b8016a200341306a200328020c10920120032802b8012210450d0620032802bc012111200328023422014110490d0520032802c0012112200341d8006a41086a200b2903002213370300200341d8006a41106a200a2903002214370300200341d8006a41186a20092903002215370300200341386a41186a22092015370300200341386a41106a220a2014370300200341386a41086a220b20133703002003200141706a36023420032003280230220141106a3602302003200329039801221337035820032013370338200141086a29000021132001290000211402402007422088a722012007a7470d00200141016a22162001490d0420014101742217201620162017491b22164104201641044b1bad42d8007e2215422088a74541037421162015a721170240024020010d00200341003602b8010c010b200341083602c001200320083602b8012003200141d8006c3602bc010b20034198016a20172016200341b8016a107d20032802a00121162003280298014101460d03200328029c012108200742808080807083201641d8006ead8421070b2008200141d8006c6a220120143703102001200c3703082001200d3703002001200e360220200141186a2013370300200141346a2012360200200141306a20113602002001412c6a2010360200200141246a200f370200200141386a2003290338370200200141c0006a200b290300370200200141c8006a200a290300370200200141d0006a200929030037020020074280808080107c21072006417f6a22060d000b0b2008450d0620002007370204200020083602000c070b20160d010b1038000b1036000b201141ffffff3f71450d002010102e0b200fa72201450d00200141306c450d00200e102e0b200341d8006a41086a200341f8006a41086a29030037030002402007422088a72201450d00200141d8006c2102200841306a210103400240200141746a2802002206450d00200641306c450d00200141706a280200102e0b0240200128020041ffffff3f71450d002001417c6a280200102e0b200141d8006a2101200241a87f6a22020d000b0b2007a72201450d00200141d8006c450d002008102e0b200341003602a00120034201370398012003410a36027c2003200341186a360278200320034198016a360258200341cc016a4101360200200342013702bc01200341909dc5003602b8012003200341f8006a3602c801200341d8006a419cebc000200341b8016a103d1a20032802980120032802a00110ef020240200328029c01450d00200328029801102e0b200041003602000b2005450d002004102e0b200341e0016a24000bb10b01047f230041d0006b22012400200141086a4192fdc6004107108102200141186a41b29dc500410b108102200120003602342001200141346a410410a301370338200141cc006a200141346a41046a3602002001200141c0006a3602442001200141346a3602482001200141386a360240200141286a200141c0006a107c024002402001280230220241206a2203417f4c0d000240024020030d00410121040c010b2003102c2204450d020b200141003602482001200336024420012004360240200141c0006a200141086a41101074200141c0006a200141186a41101074200141c0006a20012802282203200210740240200128022c450d002003102e0b20012802402203200128024810890302402001280244450d002003102e0b200141086a4192fdc6004107108102200141186a41c4afc6004112108102200120003602342001200141346a410410a301370338200141cc006a200141346a41046a3602002001200141c0006a3602442001200141346a3602482001200141386a360240200141286a200141c0006a107c2001280230220241206a2203417f4c0d000240024020030d00410121040c010b2003102c2204450d020b200141003602482001200336024420012004360240200141c0006a200141086a41101074200141c0006a200141186a41101074200141c0006a20012802282203200210740240200128022c450d002003102e0b20012802402203200128024810890302402001280244450d002003102e0b200141086a4192fdc6004107108102200141186a41c0b0c6004112108102200120003602342001200141346a410410a301370338200141cc006a200141346a41046a3602002001200141c0006a3602442001200141346a3602482001200141386a360240200141286a200141c0006a107c2001280230220241206a2203417f4c0d000240024020030d00410121040c010b2003102c2204450d020b200141003602482001200336024420012004360240200141c0006a200141086a41101074200141c0006a200141186a41101074200141c0006a20012802282203200210740240200128022c450d002003102e0b20012802402203200128024810890302402001280244450d002003102e0b200141086a4192fdc6004107108102200141186a418cb1c6004113108102200120003602342001200141346a410410a301370338200141cc006a200141346a41046a3602002001200141c0006a3602442001200141346a3602482001200141386a360240200141286a200141c0006a107c2001280230220241206a2203417f4c0d000240024020030d00410121040c010b2003102c2204450d020b200141003602482001200336024420012004360240200141c0006a200141086a41101074200141c0006a200141186a41101074200141c0006a20012802282203200210740240200128022c450d002003102e0b20012802402203200128024810ff0102402001280244450d002003102e0b200141c0006a200010a10520012802402203200128024810ff0102402001280244450d002003102e0b200141086a4192fdc6004107108102200141186a4188b2c600410e108102200120003602342001200141346a410410a301370338200141cc006a200141346a41046a3602002001200141c0006a3602442001200141346a3602482001200141386a360240200141286a200141c0006a107c2001280230220241206a2203417f4c0d000240024020030d00410121040c010b2003102c2204450d020b200141003602482001200336024420012004360240200141c0006a200141086a41101074200141c0006a200141186a41101074200141c0006a20012802282203200210740240200128022c450d002003102e0b20012802402203200128024810ff0102402001280244450d002003102e0b200141c0006a200010950320012802402200200128024810ff0102402001280244450d002000102e0b200141d0006a24000f0b1038000b1036000bae0301037f230041f0006b22032400200341086a4192fdc6004107108102200341186a41c4afc6004112108102200320013602382003200341386a410410a301370348200341ec006a2201200341386a41046a3602002003200341c8006a41086a3602642003200341386a3602682003200341c8006a360260200341286a200341e0006a107c024002404120102c2204450d002003422037024c20032004360248200341c8006a2002412010742003200328024822022003280250220410a3013703582001200220046a360200200320023602682003200341d8006a41086a3602642003200341d8006a360260200341386a200341e0006a107c0240200328024c450d002002102e0b20032802302201200328024022046a41206a2202417f4c0d010240024020020d00410121050c010b2002102c2205450d010b2000410036020820002002360204200020053602002000200341086a411010742000200341186a4110107420002003280228220220011074200020032802382201200410740240200328023c450d002001102e0b0240200328022c450d002002102e0b200341f0006a24000f0b1036000b1038000bae0301037f230041f0006b22032400200341086a4192fdc6004107108102200341186a41c0b0c6004112108102200320013602382003200341386a410410a301370348200341ec006a2201200341386a41046a3602002003200341c8006a41086a3602642003200341386a3602682003200341c8006a360260200341286a200341e0006a107c024002404120102c2204450d002003422037024c20032004360248200341c8006a2002412010742003200328024822022003280250220410a3013703582001200220046a360200200320023602682003200341d8006a41086a3602642003200341d8006a360260200341386a200341e0006a107c0240200328024c450d002002102e0b20032802302201200328024022046a41206a2202417f4c0d010240024020020d00410121050c010b2002102c2205450d010b2000410036020820002002360204200020053602002000200341086a411010742000200341186a4110107420002003280228220220011074200020032802382201200410740240200328023c450d002001102e0b0240200328022c450d002002102e0b200341f0006a24000f0b1036000b1038000b850201037f230041d0006b22022400200241086a4192fdc6004107108102200241186a41d0b3c6004110108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000ba20a08037f047e017f027e017f027e017f047e23004180026b2201240020014200370348200142003703402001200041186a29030037035820012000290310370350200041386a2000290300200041086a290300200141d0006a200141c0006a10ca080240200041286a28020041306c2202450d002000280220210303402003200341206a290300200341286a290300200141d0006a200141c0006a10ca08200341306a2103200241506a22020d000b0b200141c0006a41086a29030021042001290340210502400240024020012903502206200141d0006a41086a290300220784500d00200041346a28020022030d010b2001200537036020012004370368024020052004844200520d002001200141e0006a3602e001200141e0016a10cc020c020b200142f0f2bda1a7ee9cb9f9003703e001200141e0006a200141e0016a10cd022001200141e0006a2005200410fd01200141f0016a200141086a290300220620047d20012903002207200554ad7d200420067d2005200754ad7d2007200556200620045620062004511b22031b3703002001200720057d200520077d20031b3703e80120012003ad3703e001200141e0016a41086a21020240024020030d00200120023602fc01200141fc016a10cc020c010b200120023602fc01200141fc016a10ce020b200141f8006a2004370300200141f0006a2005370300200141e8006a41063a00002001410e3a0060200141e0006a10fe010c010b200028022c2102200141306a200520062005200654200420075420042007511b22081b22092004200720081b220a2003ad420010e70820034105742108200141e0006a41086a210b200141306a41086a290300210c2001290330210d200141f0006a210e2009210f200a21100340200141206a2002200d200f200f200d562010200c562010200c511b22031b2207200c201020031b220610fd01200e200141206a41086a290300221120067d20012903202212200754ad7d200620117d2007201254ad7d2012200756201120065620112006511b22031b3703002001201220077d200720127d20031b37036820012003ad370360201020067d2106200f200754ad21100240024020030d002001200b3602e001200141e0016a10cc020c010b2001200b3602e001200141e0016a10ce020b200620107d2110200f20077d210f200241206a2102200841606a22080d000b2001427f2004200a7d2005200954ad7d221220107c200520097d2211200f7c220c2011542203ad7c22072003200720125420072012511b22031b22063703682001427f200c20031b220737036002402011200f842012201084844200520d002001200141e0006a3602e001200141e0016a10cc020c010b200142f0f2bda1a7ee9cb9f9003703e001200141e0006a200141e0016a10cd02200141106a200141e0006a2007200610fd01200141f0016a200141106a41086a290300221020067d2001290310220f200754ad7d200620107d2007200f54ad7d200f200756201020065620102006511b22031b3703002001200f20077d2007200f7d20031b3703e80120012003ad3703e001200141e0016a41086a21020240024020030d00200120023602fc01200141fc016a10cc020c010b200120023602fc01200141fc016a10ce020b200141f8006a2006370300200141f0006a2007370300200141e8006a41063a00002001410e3a0060200141e0006a10fe010b0240200041246a2802002203450d00200341306c450d002000280220102e0b0240200041306a28020041ffffff3f71450d00200028022c102e0b20014180026a24000b8f0201027f20014180feff07714108762102024002402001410171450d00411f210341aae7cc00210102400240200241ff01710e03000103000b41c100210341e9e6cc0021010c020b41c100210341a8e6cc0021010c010b411f21034189e6cc002101024002400240024002400240024002400240200241ff01710e0a00060102030405090708000b4120210341e9e5cc0021010c080b412721034189e5cc0021010c070b4117210341f2e4cc0021010c060b41d3e4cc0021010c050b4126210341ade4cc0021010c040b412a21034183e4cc0021010c030b4139210341b0e5cc0021010c020b413b210341c8e3cc0021010c010b41d200210341f6e2cc0021010b20002003360204200020013602000b4201027f41032102024020014105490d004100210302400240024020002d00040e03020001030b410121030c010b410221030b2003410320014105461b21020b20020be30101047f0240024002400240200128020022022802042203450d00200228020022042d0000210520022003417f6a3602042002200441016a36020020050e020203010b200041023602000f0b200041023602000f0b200041003602000f0b02402001280200220228020422034104490d0020022802002204280000210520022003417c6a3602042002200441046a3602002001280200220228020422014104490d00200020053602042000410136020020022802002203280000210420022001417c6a3602042002200341046a360200200041086a20043602000f0b200041023602000bc40101047f024002400240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a36020020040e020203010b200041023602000f0b200041023602000f0b200041003602000f0b024020054104490d002003280001210520012002417b6a22043602042001200341056a36020020044104490d002000200536020420004101360200200328000521042001200241776a3602042001200341096a360200200041086a20043602000f0b200041023602000bc60401047f230041106b22022400024002400240024020002d00000e03010200010b200041046a280200220041ffff03200041ffff03491b220341c0006a41ff0020032000413e2003413e491b2204461b2100200320046b2103410121040340024002400240200441ff01714102470d00200021050c010b410021052004410171450d00410021040c010b2003450d0402400240200341ff014b0d002003417f6a2100410021030c010b200341817e6a210341ff0121000b410221040b200220003a000f20012002410f6a41011074200521000c000b0b200241003a000f20012002410f6a410110740c010b200041046a2802002203413e200341ffff03200341ffff03491b2203413e491b2104024020002d0001450d00200341406a417f20032004461b2100200320046b2103410121040340024002400240200441ff01714102470d00200021050c010b410021052004410171450d00410021040c010b2003450d0302400240200341ff014b0d002003417f6a2100410021030c010b200341817e6a210341ff0121000b410221040b200220003a000f20012002410f6a41011074200521000c000b0b200341807f7341bf7f20032004461b2100200320046b2103410121040340024002400240200441ff01714102470d00200021050c010b410021052004410171450d00410021040c010b2003450d0202400240200341ff014b0d002003417f6a2100410021030c010b200341817e6a210341ff0121000b410221040b200220003a000f20012002410f6a41011074200521000c000b0b200241106a24000b13002000411436020420004184ecc6003602000bd5b1020a017f027e057f027e027f057e107f017e047f027e230041e0066b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e18000102030405060708090a0b0c0d0e0f10111213201f1e1d000b200341f4056a4101360200200342013702e4052003419cc3cb003602e005200341043602840520034194c3cb0036028005200320034180056a3602f005200341e0056a41f4ebc6001044000b200141d0006a2903002104200141c8006a2903002105200341d8026a41026a200141276a2d00003a0000200341b0036a41086a200141386a290200370300200341b0036a41106a200141c0006a2902003703002003200141256a2f00003b01d8022003200141306a2902003703b003200141246a2d00002106200141286a28020021072001412c6a2802002108200341b8046a41206a200141216a2d00003a0000200341b8046a41186a200141196a290000370300200341b8046a41106a200141116a290000370300200341b8046a41086a200141096a290000370300200320012900013703b804200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a200241086a290200370300200320022902003703e00520034180056a200341e0056a10c10220034180046a41086a220220034180056a41096a29000037030020034180046a41106a220120034180056a41116a29000037030020034180046a41186a220920034180056a41196a29000037030020032003290081053703800402400240024020032d0080054101460d00200341d8036a41186a2009290300370300200341d8036a41106a2001290300370300200341d8036a41086a200229030037030020032003290380043703d803200341e0056a200341d8036a10e50520032802e005220120032802e805108f022102024020032802e405450d002001102e0b02402002450d00200341a8046a41031082060c020b20034180046a41026a2202200341d8026a41026a2d00003a0000200341e0056a41086a2201200341b0036a41086a290300370300200341e0056a41106a200341b0036a41106a290300370300200320032f01d8023b018004200320032903b0033703e0050240024002400240024020064107710e03000201020b200341f0026a410d6a2206200341e0056a410d6a290000370000200341f0026a41086a22092001290300370300200341d8056a41026a220120022d00003a000020034190036a41086a2202200929030037030020034190036a410d6a22092006290000370000200320032f0180043b01d805200320032903e00537039003200320012d00003a008205200320032f01d8053b0180052003200836008705200320073600830520034198056a200929000037000020034193056a2002290300370000200320032903900337008b05200341e0056a20034180056a10d30520032802e005220120032802e805108f022102024020032802e405450d002001102e0b2002450d03200341a8046a41041082060c060b02402008450d002007102e0b200341d8056a41026a2003418c036a41026a2d00003a000020034190036a41086a200341f0026a41086a29030037030020034190036a410d6a200341f0026a410d6a290000370000200320032f018c033b01d805200320032903f002370390030c010b200341d8056a41026a2003418c036a41026a2d00003a000020034190036a41086a200341f0026a41086a29030037030020034190036a410d6a200341f0026a410d6a290000370000200320032f018c033b01d805200320032903f002370390030b200341013a00a8040c030b0240200542ffc7afa0255620044200522004501b0d00200341a8046a41081082060c030b0240200341d8036a1083060d0020034180046a200341d8036a10e505200328028804210120032802800421024120102c2206450d41200342203702e405200320063602e005200341e0056a20034180056a412010742002200120032802e005220620032802e80510b201024020032802e405450d002006102e0b0240200328028404450d002002102e0b200341e0056a41206a200341b8046a41206a2d00003a0000200341e0056a41186a200341b8046a41186a290300370300200341e0056a41106a200341b8046a41106a290300370300200341e0056a41086a200341b8046a41086a290300370300200320032903b8043703e005200341e0046a200341d8036a10840620032802e804210120032802e00421022003410036028804200342013703800402400240024002400240024020032d00e0050e050001020304050b200341003a00900320034180046a20034190036a410110740c040b200341013a00900320034180046a20034190036a410110740c030b200341023a00900320034180046a20034190036a410110740c020b200341033a00900320034180046a20034190036a4101107420034180046a200341e0056a410172412010740c010b200341043a00900320034180046a20034190036a410110740b20022001200328028004220620032802880410b2010240200328028404450d002006102e0b024020032802e404450d002002102e0b20034180046a41186a2202420037030020034180046a41106a2201420037030020034180046a41086a220642003703002003420037038004200341f0026a4192fdc60041071081022006200341f0026a41086a2207290300370300200320032903f0023703800420034190036a4194adc600410a108102200220034190036a41086a22082903003703002001200329039003370300200341106a20034180046a4120108e02200328021421092003280210210a2002420037030020014200370300200642003703002003420037038004200341f0026a4192fdc600410710810220062007290300370300200320032903f0023703800420034190036a41e0a9c600410c108102200220082903003703002001200329039003370300200341086a20034180046a4120108e02200328020c21022003280208210120034180046a200341d8036a10c802200341e0056a200328028004220720032802880410c902410020094100200a1b2206200241d40020011b6b2202200220064b1b2102200341e0056a41106a290300420020032903e00542015122011b210b20032903e805420020011b210c0240200328028404450d002007102e0b200341e0056a41086a41053a0000200341e9056a20032903d803370000200341f1056a200341d8036a41086a290300370000200341f9056a200341d8036a41106a29030037000020034181066a200341d8036a41186a220129030037000020034198066a200b2004200c200554200b200454200b2004511b22071b220437030020034190066a200c200520071b2205370300200341043a00e005200341e0056a10fe012008200341eb036a2900003703002003419d036a2001290000370000200320032f01d8033b01d805200320032d00da033a00da05200320032900e303370390034100200620026b2209200920064b1b220141ffffffff03712001470d3b20014102742208417f4c0d3b20032800df03210d20032800db03210e0240024020080d00410421070c010b2008102c2207450d420b024002402008410276220a20014f0d002008410176220a2001200a20014b1b22014104200141044b1b220141ffffffff0371200146410274210a200141027421010240024020080d00200341003602e0050c010b200341e8056a4104360200200320083602e405200320073602e0050b20034180046a2001200a200341e0056a107d20034188046a28020021012003280280044101460d0120032802840421072001410276210a0b410021010240200620024d0d0020072101034020012002360200200141046a21012006200241016a2202470d000b200921010b200341e0056a41186a20043703002003419a066a20032d00da053a00002003419f066a200d3600002003419b066a200e360000200341a3066a20032903900337000020034194066a200136020020034190066a200a36020020034188066a4100360200200341ab066a20034198036a290300370000200341b0066a2003419d036a290000370000200320053703f005200320053703e005200320032f01d8053b0198062003200736028c062003420837038006200320043703e80542f3e885db96cddbb32020034198066a20052004411f10850620034180056a200341e0056a10d205024020034184066a2802002202450d00200241186c450d00200328028006102e0b024020032802900641ffffffff0371450d00200328028c06102e0b200341063a00a8040c430b2001450d3b0c410b200341a8046a41121082060c020b200341023a00a8040b200641ff01714102470d002008450d002007102e0b20032d00a8044106460d3e20032802a8042102200020032902ac04370024200041206a2002360000200041186a41003a000020004200370308200042013703000c3f0b200141106a2903002104200141086a2903002105200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a200241086a290200370300200320022902003703e00520034180056a200341e0056a10c10220034180046a41086a220220034189056a29000037030020034180046a41106a220120034191056a29000037030020034180046a41186a220620034180056a41196a29000037030020032003290081053703800420032d0080054101460d19200341e0046a41186a2006290300370300200341e0046a41106a2001290300370300200341e0046a41086a200229030037030020032003290380043703e004200341d8036a200341e0046a10e505200341e0056a20032802d803220220032802e00310f40220034180056a41086a200341ea056a29010037030020034180056a41106a200341f2056a29010037030020034180056a41176a2201200341e0056a41196a290000370000200320032901e2053703800502400240024020032d00e0054101470d0020032d00e105210620034190036a41176a200129000037000020034190036a41106a220120034180056a41106a29030037030020034190036a41086a220820034180056a41086a290300370300200320032903800537039003024020032802dc03450d002002102e0b20034180046a41176a220720034190036a41176a29000037000020034180046a41106a22022001290300370300200341c1046a2008290300370000200341c9046a2002290300370000200341b8046a41186a2007290000370000200320063a00b80420032003290390033700b90420034190036a200341b8046a10d305200341e0056a200328029003220120032802980310e60520034180046a41086a2003419c066a2902003703002002200341a4066a29020037030020034180046a41186a2202200341ac066a29020037030020034180046a41206a2206200341b4066a280200360200200320034194066a2902003703800402402003280280062208450d00200341e0056a41186a290300210f200341e0056a41086a290300210c20034190066a28020021072003418c066a280200210920034188066a280200210a20032903f005211020032903e005210b200328028406210d200341d8036a41206a2006280200360200200341d8036a41186a2002290300370300200341d8036a41106a220220034180046a41106a290300370300200341d8036a41086a220620034180046a41086a29030037030020032003290380043703d8030240200328029403450d002001102e0b200341b0036a41086a22012006290300370300200341b0036a41106a22062002290300370300200341b0036a41186a2202200341d8036a41186a290300370300200341b0036a41206a220e200341d8036a41206a28020036020020034180056a41186a200f370300200341b0056a2007360200200341a8056a200a360200200341a4056a200d360200200320032903d8033703b00320032010370390052003200b37038005200320093602ac05200320083602a0052003200c37038805200341d4056a200e280200360200200341cc056a2002290300370200200341c4056a2006290300370200200341bc056a2001290300370200200341b4056a20032903b00337020020034180046a200341e0046a10c802200341e0056a200328028004220120032802880410c902200341e0056a41106a290300420020032903e00542015122021b210f20032903e805420020021b21100240200328028404450d002001102e20034188056a290300210c200329038005210b0b2010200b7d2211201056200f200c7d2010200b54ad7d2210200f562010200f511b0d0320034180056a41186a2202290300211220032003290390052213200520112011200556201020045620102004511b22011b22057c220f37039005200220122004201020011b22107c200f201354ad7c220437030020032005200b7c220b3703800520032010200c7c200b200554ad7c220c37038805200f42ffc7afa0255620044200522004501b0d02200341f0026a4108108206024020032802a4052202450d00200241186c450d0020032802a005102e0b20032802b00541ffffffff0371450d3e20032802ac05102e0c3e0b0240200328029403450d002001102e0b200341f0026a41011082060c3d0b024020032802dc03450d002002102e0b200341f0026a41021082060c3c0b200341e0056a41386a201037030020034190066a2005370300200341e0056a41086a41053a0000200341e9056a20032903e004370000200341f1056a200341e0046a41086a290300370000200341f9056a200341f0046a29030037000020034181066a200341e0046a41186a290300370000200341043a00e005200341e0056a10fe0142f3e885db96cddbb32020034180056a41386a200b200c411f108506200341b8046a20034180056a10d2050b024020032802a4052202450d00200241186c450d0020032802a005102e0b024020032802b00541ffffffff0371450d0020032802ac05102e0b200341063a00f0020c3b0b200141106a2903002104200141086a2903002105200341e0056a41286a2206200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a2208200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a2207200241086a290200370300200320022902003703e00520034180056a200341e0056a10c10220034190036a41086a220220034194056a2902003703002003419d036a220120034199056a290000370000200320032f0081053b01d805200320032d0083053a00da0520032003418c056a290200370390030240024020032d0080054101460d0020034180056a41086a2802002109200328028405210a200341cb046a2002290300370000200341b8046a41186a2001290000370000200320032d00da053a00ba04200320032f01d8053b01b804200320093600bf042003200a3600bb0420032003290390033700c304200341e0046a200341b8046a10d305200341e0056a20032802e004220920032802e80410e60520034180046a41086a2003419c066a29020037030020034180046a41106a200341a4066a29020037030020034180046a41186a200341ac066a29020037030020034180046a41206a200341b4066a280200360200200320034194066a2902003703800402402003280280062201450d002008290300210b2007290300210f20034190066a28020021082003418c066a28020021072006280200210620032903f005210c20032903e00521102003280284062102200341d8036a41206a220a20034180046a41206a280200360200200341d8036a41186a220d20034180046a41186a290300370300200341d8036a41106a220e20034180046a41106a290300370300200341d8036a41086a221420034180046a41086a29030037030020032003290380043703d803024020032802e404450d002009102e0b200341b0036a41086a22092014290300370300200341b0036a41106a2214200e290300370300200341b0036a41186a220e200d290300370300200341b0036a41206a220d200a28020036020020034180056a41186a200b370300200341b0056a2008360200200341a8056a2006360200200341a4056a2002360200200320032903d8033703b0032003200c370390052003201037038005200320073602ac05200320013602a0052003200f37038805200341d4056a200d280200360200200341cc056a200e290300370200200341c4056a2014290300370200200341bc056a2009290300370200200341b4056a20032903b0033702002006411f4d0d02200341a8046a4109108206024020032802a4052202450d00200241186c450d0020032802a005102e0b20032802b00541ffffffff0371450d3920032802ac05102e0c390b024020032802e404450d002009102e0b200341a8046a41011082060c380b200341023a00a8040c380b02400240200c2005200c200554200b200454200b2004511b22061b2205200b200420061b220484500d0020034180056a41186a4200200b20047d200c200554ad7d220f200c20057d22104280c8afa025544100200f501b22061b37030020034200201020061b3703900520034180046a41186a2202420037030020034190046a2208420037030020034180046a41086a220742003703002003420037038004200341f0026a4192fdc60041071081022007200341f0026a41086a290300370300200320032903f0023703800420034190036a4194adc600410a108102200220034190036a41086a2903003703002008200329039003370300200341186a20034180046a4120108e02200328021c210820032802182107024020032802a805220220032802a405470d00200241016a22092002490d382002410174220a2009200a20094b1b22094104200941044b1bad42187e220f422088a7454103742109200fa7210a0240024020020d00200341003602e0050c010b200341e0056a41086a4108360200200320013602e0052003200241186c3602e4050b20034180046a200a2009200341e0056a107d20034188046a28020021022003280280044101460d02200320032802840422013602a0052003200241186e3602a40520032802a80521020b2001200241186c6a2202200b200420061b22043703082002200c200520061b220537030020022008411c6a411c20071b360210200320032802a80541016a3602a80542f3e885db96cddbb32020034180056a41386a20032903800520034180056a41086a290300411f108506200341b8046a20034180056a10d205200341e0056a41386a200437030020034190066a2005370300200341e0056a41086a41063a0000200341e9056a20032903b805370000200341f1056a200341c0056a290300370000200341f9056a200341c8056a29030037000020034181066a200341d0056a290300370000200341043a00e005200341e0056a10fe0120032802a40521020b02402002450d00200241186c450d0020032802a005102e0b024020032802b00541ffffffff0371450d0020032802ac05102e0b200341063a00a8040c390b20020d3b0c350b200141046a280200210e200341e0056a41286a2207200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a220a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a220d200241086a290200370300200320022902003703e00520034180056a200341e0056a10c102410221022003418c036a41026a220120032d0083053a0000200341f0026a41086a220620034194056a290200370300200341fd026a220820034199056a290000370000200320032f0081053b018c0320032003418c056a2902003703f002024002400240024020032d0080054101460d0020034180056a41086a28020021022003280284052109200341f3046a2006290300370000200341e0046a41186a2008290000370000200320032f018c033b01e004200320023600e704200320093600e304200320032903f0023700eb04200320012d00003a00e204200341b8046a200341e0046a10d305200341e0056a20032802b804221420032802c00410e60520034180046a41086a2003419c066a29020037030020034180046a41106a200341a4066a29020037030020034180046a41186a200341ac066a29020037030020034180046a41206a200341b4066a280200360200200320034194066a2902003703800402402003280280062209450d00200a2903002104200d290300210f20034190066a280200210d2003418c066a28020021152007280200210220032903f005210520032903e0052110200328028406210a200341d8036a41206a220720034180046a41206a280200360200200341d8036a41186a221620034180046a41186a2201290300370300200341d8036a41106a221720034180046a41106a2206290300370300200341d8036a41086a221820034180046a41086a220829030037030020032003290380043703d803024020032802bc04450d002014102e0b200341b0036a41086a22142018290300370300200341b0036a41106a22182017290300370300200341b0036a41186a22172016290300370300200341b0036a41206a2216200728020036020020034180056a41186a2004370300200341b0056a200d360200200341a8056a2002360200200341a4056a200a360200200320032903d8033703b00320032005370390052003201037038005200320153602ac05200320093602a0052003200f37038805200341d4056a2016280200360200200341cc056a2017290300370200200341c4056a2018290300370200200341bc056a2014290300370200200341b4056a220720032903b003370200200341b8046a41186a200341d0056a220d290300370300200341b8046a41106a200341c8056a290300370300200341b8046a41086a200341c0056a290300370300200320032903b8053703b8042001420037030020064200370300200842003703002003420037038004200341f0026a4192fdc60041071081022008200341f0026a41086a290300370300200320032903f0023703800420034190036a4194adc600410a108102200120034190036a41086a2903003703002006200329039003370300200341206a20034180046a4120108e0220032802204101460d0220102105200f210b0c030b024020032802bc04450d002014102e0b200341e0056a4101108206200341da026a20032d00e3053a0000200320032f00e1053b01d80220032d00e005210220032902e40521040c030b0c020b20032802242108200341e0056a41086a2216200728020036020020034190036a41086a2217200341cb056a29000037030020034190036a410d6a2218200d290000370000200320032902ac053703e0052003200341c3056a220d290000370390032003200341b8056a22142f01003b01d8052003201441026a22192d00003a00da05200341ac056a211520034180056a41186a221a2903002111200341bf056a280000211b200341bb056a280000211c20032903900521120240024020020d0020102105200f210b200921010c010b2009200241186c6a210720102105200f210b20092102200921010340200241086a290300210c20022903002104024002402008200241106a28020022064f0d0020012004370300200120063602102001200c370308200141186a21010c010b4200200b200c7d2005200454ad7d220c200520047d2204200556200c200b56200c200b511b22061b210b4200200420061b21050b200241186a22022007470d000b0b201520032903e005370200201420032f01d8053b0100200d200329039003370000201a2011370300201920032d00da053a0000201541086a2016280200360200200d41086a2017290300370000200d410d6a2018290000370000200320123703900520032005370380052003200a3602a4052003201b3600bf052003201c3600bb052003200b37038805200320093602a0052003200120096b41186d22023602a8050b0240024020020d002003290390054280c8afa02554410020034198056a290300501b0d010b42f3e885db96cddbb320200341b8056a2005200b411f108506200ead42f8d2017e4288ca87d8017c2105200341e0046a20034180056a10d2054201210b0c350b200341e0056a200341b8046a200e108606200341b0036a41026a220120032d00e3053a0000200320032f00e1053b01b003024020032d00e00522024106470d0042f3e885db96cddbb320200341b8046a10ea024200210b0c350b20032902e4052104200341d8026a41026a20012d00003a0000200320032f01b0033b01d802024020032802a4052201450d00200141186c450d0020032802a005102e0b20032802b00541ffffffff0371450d0020032802ac05102e0b200341d4026a41026a2201200341d8026a41026a2d00003a0000200320032800a8043602e002200320032f01d8023b01d4022003200341ab046a2800003600e302200041186a41003a000020004200370308200020032802e0023600192000411c6a20032800e302360000200041206a20023a000020002004370024200020032f01d4023b0021200041236a20012d00003a0000200042013703000c3c0b200141086a2d00002108200141046a2802002107200341e0056a41286a2209200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a220a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a220d200241086a290200370300200320022902003703e00520034180056a200341e0056a10c10220034180046a41086a220220034189056a29000037030020034180046a41106a220120034191056a29000037030020034180046a41186a220620034199056a29000037030020032003290081053703800420032d0080054101460d15200341b8046a41186a2006290300370300200341b8046a41106a2001290300370300200341b8046a41086a200229030037030020032003290380043703b804200341e0046a200341b8046a10d305200341e0056a20032802e004220e20032802e80410e60520022003419c066a2902003703002001200341a4066a2902003703002006200341ac066a29020037030020034180046a41206a200341b4066a280200360200200320034194066a2902003703800402402003280280062201450d00200a2903002104200d290300210520034190066a28020021062003418c066a280200210a2009280200210920032903f005210b20032903e005210c2003280284062102200341d8036a41206a220d20034180046a41206a280200360200200341d8036a41186a221420034180046a41186a290300370300200341d8036a41106a221520034180046a41106a290300370300200341d8036a41086a221620034180046a41086a29030037030020032003290380043703d803024020032802e404450d00200e102e0b200341b0036a41086a220e2016290300370300200341b0036a41106a22162015290300370300200341b0036a41186a22152014290300370300200341b0036a41206a2214200d28020036020020034180056a41186a2004370300200341b0056a2006360200200341a8056a2009360200200341a4056a2002360200200320032903d8033703b0032003200b370390052003200c370380052003200a3602ac05200320013602a0052003200537038805200341d4056a2014280200360200200341cc056a2015290300370200200341c4056a2016290300370200200341bc056a200e290300370200200341b4056a20032903b003370200200341e0056a200341b8056a220910d10520032802e005220d20032802e80510ff01024020032802e405450d00200d102e0b200320083a00dc03200320073602d80320034180046a200910860520032802880421092003280280042107200341003602e805200342013703e005200341d8036a200341e0056a109102200320083a00b003200341e0056a200341b0036a410110742007200920032802e005220820032802e80510b201024020032802e405450d002008102e0b0240200328028404450d002007102e0b02402002450d00200241186c450d002001102e0b0240200641ffffffff0371450d00200a102e0b200341063a0090030c320b024020032802e404450d00200e102e0b20034190036a410110820620032d0090034106460d3120032902940321040c300b2001410c6a2802002106200141086a2802002108200141046a2802002107200341e0056a41286a2209200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a220a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a220d200241086a290200370300200320022902003703e00520034180056a200341e0056a10c10220034190036a41086a220220034194056a2902003703002003419d036a220120034199056a290000370000200320032f0081053b01d805200320032d0083053a00da05200320034180056a410c6a290200370390030240024002400240024020032d0080054101460d0020034180056a41086a280200210e2003280284052114200341f3046a2002290300370000200341e0046a41186a2001290000370000200320032d00da053a00e204200320032f01d8053b01e0042003200e3600e704200320143600e30420032003290390033700eb04200341b8046a200341e0046a10d305200341e0056a20032802b804220e20032802c00410e60520034180046a41086a2003419c066a29020037030020034180046a41106a200341a4066a29020037030020034180046a41186a200341ac066a29020037030020034180046a41206a200341b4066a280200360200200320034194066a29020037038004024002402003280280062201450d00200a2903002104200d290300210520034190066a280200210a2003418c066a280200210d2009280200210920032903f005210b20032903e005210c2003280284062102200341d8036a41206a221420034180046a41206a280200360200200341d8036a41186a221520034180046a41186a290300370300200341d8036a41106a221620034180046a41106a290300370300200341d8036a41086a221720034180046a41086a29030037030020032003290380043703d803024020032802bc04450d00200e102e0b200341b0036a41086a220e2017290300370300200341b0036a41106a22172016290300370300200341b0036a41186a22162015290300370300200341b0036a41206a2215201428020036020020034180056a41186a2004370300200341b0056a200a360200200341a8056a2009360200200341a4056a2002360200200320032903d8033703b0032003200b370390052003200c370380052003200d3602ac05200320013602a0052003200537038805200341d4056a2015280200360200200341cc056a2016290300370200200341c4056a2017290300370200200341bc056a200e290300370200200341b4056a20032903b00337020020060d01200341e0026a410510820602402002450d00200241186c450d002001102e0b200a41ffffffff0371450d05200d102e0c050b024020032802bc04450d00200e102e0b200341e0026a41011082060c020b024020064111490d00200341e0026a411310820602402002450d00200241186c450d002001102e0b200a41ffffffff0371450d03200d102e0c030b20034180046a200341b8056a221510d105200341e0056a2003280280042202200328028804108706200341f0026a41086a2201200341e0056a41086a290300370300200320032903e0053703f0020240024020032d00f0054102460d00200341b8046a41086a2001290300370300200320032903f0023703b8040240200328028404450d002002102e0b200341a8046a41086a200341b8046a41086a280200360200200320032903b8043703a8040c010b0240200328028404450d002002102e0b200341003602b004200342013703a8040b200341063a00f00220032007200641246c6a3602e403200320073602e003200320083602dc03200320073602d8032003200341f0026a3602ec032003200341a8046a3602e803200341e0056a200341d8036a1088060240024020032d00e0054101470d004120102c2209450d3f200920032900e105370000200941186a200341f9056a290000370000200941106a200341f1056a290000370000200941086a200341e9056a29000037000020034180046a41106a200341d8036a41106a29030037030020034180046a41086a200341d8036a41086a290300370300200320032903d80337038004200341e0056a20034180046a10880602400240024020032d00e0050d0041012101410121080c010b200341e0056a41017221024120210741012101410121080340200341b8046a41186a220a200241186a290000370300200341b8046a41106a220d200241106a290000370300200341b8046a41086a220e200241086a290000370300200320022900003703b804024020082001470d00200141016a22062001490d3d200141017422142006201420064b1b22064104200641044b1b220641ffffff3f712006462114200641057421060240024020010d00200341003602b0030c010b200341013602b803200320093602b003200320014105743602b4030b20034190036a20062014200341b0036a107d20032802980321012003280290034101460d032003280294032109200141057621010b200920076a220620032903b804370000200641186a200a290300370000200641106a200d290300370000200641086a200e290300370000200741206a2107200841016a2108200341e0056a20034180046a10880620032d00e0050d000b0b200328028c0420032802880422026b220641246d210702402006450d00200741246c21060340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022006415c6a22060d000b0b2003280284042202450d02200241246c450d02200328028004102e0c020b20010d3f0c390b20032802e40320032802e00322026b220141246d210602402001450d00200641246c21010340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b4100210141012109024020032802dc032202450d00200241246c450d0020032802d803102e0b410021080b200341f0026a41086a2102024020032d00f00222064106460d0020032f00f10220032d00f3024110747221082002280200210220032802f40221070240200141ffffff3f71450d002009102e0b200341e8026a2002360200200320073602e402200320063a00e002200320083b00e102200320084110763a00e302024020032802ac0441ffffff3f71450d0020032802a804102e0b024020032802a4052202450d00200241186c450d0020032802a005102e0b20032802b00541ffffffff0371450d0520032802ac05102e0c050b20034198046a2206420037030020034180046a41106a2207420037030020034180046a41086a220a4200370300200342003703800420034190036a4192fdc6004107108102200a20034190036a41086a290300370300200320032903900337038004200341f0026a4194adc600410a10810220062002290300370300200720032903f002370300200341286a20034180046a4120108e02200328022c210220032802282106200341e0056a201510860520032802e005220720032802e80510ff01024020032802e405450d002007102e0b2002410020061b210a200341b8046a201510d10520032802c004210d20032802b8042107200341003602e805200342013703e0052008200341e0056a107602402008450d0020084105742106200921020340200341e0056a200241201074200241206a2102200641606a22060d000b0b2003200a36028004200341e0056a20034180046a41041074200341003a00b003200341e0056a200341b0036a410110742007200d20032802e005220220032802e80510b201024020032802e405450d002002102e0b024020032802bc04450d002007102e0b0240200141ffffff3f71450d002009102e0b024020032802ac0441ffffff3f71450d0020032802a804102e0b024020032802a4052202450d00200241186c450d0020032802a005102e0b024020032802b00541ffffffff0371450d0020032802ac05102e0b200341063a00e0020c330b200341023a00e0020b2006450d010b200641246c2101200721020340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b2008450d00200841246c450d002007102e0b20032d00e0024106460d2e20032802e0022102200020032902e402370024200041206a2002360000200041186a41003a000020004200370308200042013703000c3a0b200341e0056a41286a2208200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a2207200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a2209200241086a290200370300200320022902003703e00520034180056a200341e0056a10c10220034180046a41086a220220034189056a29000037030020034180046a41106a220120034191056a29000037030020034180046a41186a220620034199056a29000037030020032003290081053703800420032d0080054101460d12200341b8046a41186a2006290300370300200341b8046a41106a2001290300370300200341b8046a41086a200229030037030020032003290380043703b804200341e0046a200341b8046a10d305200341e0056a20032802e004220a20032802e80410e60520022003419c066a2902003703002001200341a4066a2902003703002006200341ac066a29020037030020034180046a41206a200341b4066a280200360200200320034194066a2902003703800402402003280280062201450d00200729030021042009290300210520034190066a28020021062003418c066a28020021072008280200210820032903f005210b20032903e005210c2003280284062102200341d8036a41206a220920034180046a41206a280200360200200341d8036a41186a220d20034180046a41186a290300370300200341d8036a41106a220e20034180046a41106a290300370300200341d8036a41086a221420034180046a41086a29030037030020032003290380043703d803024020032802e404450d00200a102e0b200341b0036a41086a220a2014290300370300200341b0036a41106a2214200e290300370300200341b0036a41186a220e200d290300370300200341b0036a41206a220d200928020036020020034180056a41186a2004370300200341b0056a2006360200200341a8056a2008360200200341a4056a2002360200200320032903d8033703b0032003200b370390052003200c37038005200320073602ac05200320013602a0052003200537038805200341d4056a200d280200360200200341cc056a200e290300370200200341c4056a2014290300370200200341bc056a200a290300370200200341b4056a20032903b003370200200341e0056a200341b8056a220810860520032802e005220920032802e80510ff01024020032802e405450d002009102e0b200341e0056a200810d10520032802e005220820032802e80510ff01024020032802e405450d002008102e0b02402002450d00200241186c450d002001102e0b0240200641ffffffff0371450d002007102e0b200341063a0090030c2d0b024020032802e404450d00200a102e0b20034190036a410110820620032d0090034106460d2c20032902940321040c2b0b200341b8046a41206a200141216a2d00003a0000200341b8046a41186a200141196a290000370300200341b8046a41106a200141116a290000370300200341b8046a41086a200141096a290000370300200320012900013703b804200341e0056a41286a2208200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a2207200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a2209200241086a290200370300200320022902003703e00520034180056a200341e0056a10c10220034180046a41086a220220034180056a41096a29000037030020034180046a41106a220120034180056a41116a29000037030020034180046a41186a220620034180056a41196a29000037030020032003290081053703800420032d0080054101460d10200341e0046a41186a2006290300370300200341e0046a41106a2001290300370300200341e0046a41086a200229030037030020032003290380043703e00420034190036a200341e0046a10d305200341e0056a200328029003220a20032802980310e60520022003419c066a2902003703002001200341a4066a2902003703002006200341ac066a29020037030020034180046a41206a200341b4066a280200360200200320034194066a2902003703800402402003280280062201450d00200729030021042009290300210520034190066a28020021062003418c066a28020021072008280200210820032903f005210b20032903e005210c2003280284062102200341d8036a41206a220920034180046a41206a280200360200200341d8036a41186a220d20034180046a41186a290300370300200341d8036a41106a220e20034180046a41106a290300370300200341d8036a41086a221420034180046a41086a29030037030020032003290380043703d8030240200328029403450d00200a102e0b200341b0036a41086a220a2014290300370300200341b0036a41106a2214200e290300370300200341b0036a41186a220e200d290300370300200341b0036a41206a220d200928020036020020034180056a41186a2004370300200341b0056a2006360200200341a8056a2008360200200341a4056a2002360200200320032903d8033703b0032003200b370390052003200c37038005200320073602ac05200320013602a0052003200537038805200341d4056a200d280200360200200341cc056a200e290300370200200341c4056a2014290300370200200341bc056a200a290300370200200341b4056a20032903b003370200200341e0056a41206a200341b8046a41206a2d00003a0000200341e0056a41186a200341b8046a41186a290300370300200341e0056a41106a200341b8046a41106a290300370300200341e0056a41086a200341b8046a41086a290300370300200320032903b8043703e005200341d8036a200341b8056a10840620032802e003210920032802d80321082003410036028804200342013703800402400240024002400240024020032d00e0050e050001020304050b200341003a00b00320034180046a200341b0036a410110740c040b200341013a00b00320034180046a200341b0036a410110740c030b200341023a00b00320034180046a200341b0036a410110740c020b200341033a00b00320034180046a200341b0036a4101107420034180046a200341e0056a410172412010740c010b200341043a00b00320034180046a200341b0036a410110740b20082009200328028004220a20032802880410b2010240200328028404450d00200a102e0b024020032802dc03450d002008102e0b02402002450d00200241186c450d002001102e0b0240200641ffffffff0371450d002007102e0b200341063a00f0020c2a0b0240200328029403450d00200a102e0b200341f0026a410110820620032d00f0024106460d2920032902f40221040c280b200341d8026a41026a200141076a2d00003a0000200341e0046a41086a200141186a290200370300200341e0046a41106a200141206a2902003703002003200141056a2f00003b01d8022003200141106a2902003703e004200141046a2d00002106200141086a28020021082001410c6a2802002101200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a200241086a290200370300200320022902003703e00520034180056a200341e0056a10c1022003418c036a41026a220220032d0083053a0000200341f0026a41086a220720034194056a290200370300200341fd026a220920034180056a41196a290000370000200320032f0081053b018c03200320034180056a410c6a2902003703f00202400240024020032d0080054101460d0020034180056a41086a220a280200210d200328028405210e200341c3036a2007290300370000200341b0036a41186a2009290000370000200320032f018c033b01b0032003200d3600b7032003200e3600b303200320032903f0023700bb03200320022d00003a00b203200341b8046a200341b0036a10e505200341e0056a20032802b804220220032802c00410f402200a200341ea056a29010037030020034180056a41106a200341f2056a29010037030020034180056a41176a2207200341e0056a41196a290000370000200320032901e20537038005024002400240024020032d00e0054101470d0020032d00e105210920034190036a41176a200729000037000020034190036a41106a220720034180056a41106a29030037030020034190036a41086a220a20034180056a41086a290300370300200320032903800537039003024020032802bc04450d002002102e0b20034180046a41176a220220034190036a41176a29000037000020034180046a41106a220d2007290300370300200341e1036a200a290300370000200341e9036a200d290300370000200341d8036a41186a2002290000370000200320093a00d80320032003290390033700d90320034180056a41026a2202200341d8026a41026a2d00003a0000200320032f01d8023b018005200341e0056a41086a200341e0046a41086a290300370300200341e0056a41106a200341e0046a41106a290300370300200320032903e0043703e0050240024020064107710e03000301030b20034180046a41186a2206200341e0056a410d6a29000037000020034180046a41136a2207200341e0056a41086a29030037000020034190036a41086a2209200729000037030020034190036a410d6a22072006290000370000200320032f01800522063b0180042003200136008704200320022d000022023a008204200320063b01d805200320032903e00537039003200320023a00da05200320032d00da053a00ba04200320032f01d8053b01b804200320013600bf04200320083600bb04200341b8046a41186a2007290000370000200341b8046a41136a200929030037000020032003290390033700c304200341e0056a200341b8046a10d30520032802e005220120032802e805108f022102024020032802e405450d002001102e0b2002450d04200341a8046a41041082060c070b02402001450d002008102e0b20034198036a20034193046a2900003703002003419d036a20034198046a290000370000200320032f0180043b01d805200320032d0082043a00da052003200329008b04370390030c020b024020032802bc04450d002002102e0b200341a8046a41021082060c040b20034198036a20034193046a2900003703002003419d036a20034180046a41186a290000370000200320032f0180043b01d805200320032d0082043a00da052003200329008b04370390030b200341013a00a8040c030b200341b8046a200341d8036a412010ec08450d2820034180056a200341b0036a10e505200328028805210120032802800521024120102c2206450d38200342203702e405200320063602e005200341e0056a200341b8046a412010742002200120032802e005220620032802e80510b201024020032802e405450d002006102e0b0240200328028405450d002002102e0b20034190036a200341d8036a10d305200341e0056a2003280290032201200328029803220610e60502402003280280062202450d002001200610ff010b20034180046a41086a22062003419c066a29020037030020034180046a41106a2208200341a4066a29020037030020034180046a41186a2207200341ac066a29020037030020034180046a41206a2209200341b4066a280200360200200320034194066a2902003703800402402002450d00200341e0056a41186a2903002104200341e0056a41086a290300210520034190066a280200210a2003418c066a280200210d20034188066a280200210e20032903f005210b20032903e005210c200328028406211420034180056a41206a200928020036020020034180056a41186a200729030037030020034180056a41106a200829030037030020034180056a41086a20062903003703002003200329038004370380050240200328029403450d002001102e0b200341e0056a41186a200437030020034190066a200a36020020034188066a2201200e36020020034184066a201436020020034194066a2003290380053702002003419c066a20034188056a290300370200200341a4066a20034180056a41106a290300370200200341ac066a20034180056a41186a290300370200200341b4066a20034180056a41206a2802003602002003200b3703f005200320053703e8052003200c3703e0052003200d36028c06200320023602800620034190036a200341b8046a10d305200328029803210820032802900321062003410036028804200342013703800420034180046a20034198066a412010742003200341e0056a3602f002200341f0026a20034180046a10af012003200341e0056a41106a3602f002200341f0026a20034180046a10af0120032802800621022001280200220120034180046a10760240200141186c2201450d00200220016a21010340200320023602f002200341f0026a20034180046a10af01200241106a20034180046a109102200241186a22022001470d000b0b200328028c062102200328029406220120034180046a107620034180046a20022001410274107420062008200328028004220220032802880410b2010240200328028404450d002002102e0b0240200328029403450d002006102e0b02402003280284062202450d00200241186c450d00200328028006102e0b20032802900641ffffffff0371450d29200328028c06102e0c290b200328029403450d282001102e0c280b200341023a00a8040b200641ff01714102470d002001450d002008102e0b20032d00a8044106460d2620032802a8042102200020032902ac04370024200041206a2002360000200041186a41003a000020004200370308200042013703000c370b200141046a2802002101200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a200241086a290200370300200320022902003703e0050240200341e0056a10a705450d00200341d8036a41026a200341b8046a41026a2d000022023a0000200320032f00b80422013b01d803200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a0000200042013703000c370b20034180046a41186a2202420037030020034180046a41106a2206420037030020034180046a41086a220842003703002003420037038004200341f0026a4192fdc60041071081022008200341f0026a41086a290200370300200320032902f0023703800420034190036a41b4aac600410e108102200220034190036a41086a2903003703002006200329039003370300200320013602e00520034180046a4120200341e0056a410410b201200041186a41003a00002000420037030820002003280080053600192000411c6a20034183056a280000360000200042003703000c360b200141046a2802002108200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a200241086a290200370300200320022902003703e0050240200341e0056a10a705450d00200341d8036a41026a200341b8046a41026a2d000022023a0000200320032f00b80422013b01d803200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a0000200042013703000c360b20034180046a41186a2202420037030020034180046a41106a2201420037030020034180046a41086a220642003703002003420037038004200341f0026a4192fdc60041071081022006200341f0026a41086a2207290200370300200320032902f0023703800420034190036a41b4aac600410e108102200220034190036a41086a22092903003703002001200329039003370300200341306a20034180046a4120108e022003280234210a2003280230210d2002420037030020014200370300200642003703002003420037038004200341f0026a4192fdc600410710810220062007290200370300200320032902f0023703800420034190036a41b4aac600410e1081022002200929030037030020012003290390033703002003200a4100200d1b20086a3602e00520034180046a4120200341e0056a410410b201200041186a41003a00002000420037030820002003280080053600192000411c6a20034183056a280000360000200042003703000c350b20012d00012101200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a200241086a290200370300200320022902003703e0050240200341e0056a10a7050d0020034180046a41186a2202420037030020034180046a41106a2206420037030020034180046a41086a220842003703002003420037038004200341f0026a4192fdc60041071081022008200341f0026a41086a2207290200370300200320032902f0023703800420034190036a41b4aac600410e108102200220034190036a41086a22092903003703002006200329039003370300200341386a20034180046a4120108e02200328023c210a2003280238210d2002420037030020064200370300200842003703002003420037038004200341f0026a4192fdc600410710810220082007290200370300200320032902f0023703800420034190036a41b4aac600410e1081022002200929030037030020062003290390033703002003200a4100200d1b220241e4006e20016c200241e4007020016c220141e4006e41ff0120014180c801491b200141e4007041324b6a41ff01716a20026a3602e00520034180046a4120200341e0056a410410b201200041186a41003a00002000420037030820002003280080053600192000411c6a20034183056a280000360000200042003703000c350b200341d8036a41026a200341b8046a41026a2d000022023a0000200320032f00b80422013b01d803200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a0000200042013703000c340b200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a2201200241086a290200370300200320022902003703e005200341e0056a10a7050d0a200341b8046a41186a22024200370300200341b8046a41106a22064200370300200341b8046a41086a22084200370300200342003703b804200341e0056a4192fdc600410710810220082001290000370300200320032900e0053703b804200341e0056a41b8b2c600410810810220022001290000370300200620032900e005370300200341003602e805200342013703e005200341023a00b003200341e0056a200341b0036a41011074200341b8046a412020032802e005220220032802e80510b201024020032802e405450d002002102e0b200041186a41003a00002000420037030820002003280080053600192000411c6a20034183056a280000360000200042003703000c330b200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a2201200241086a290200370300200320022902003703e005200341e0056a10a7050d08200341b8046a41186a22024200370300200341b8046a41106a22064200370300200341b8046a41086a22084200370300200342003703b804200341e0056a4192fdc600410710810220082001290000370300200320032900e0053703b804200341e0056a41b8b2c600410810810220022001290000370300200620032900e005370300200341003602e805200342013703e005200341013a00b003200341e0056a200341b0036a41011074200341b8046a412020032802e005220220032802e80510b201024020032802e405450d002002102e0b200041186a41003a00002000420037030820002003280080053600192000411c6a20034183056a280000360000200042003703000c320b2001410c6a2802002106200141086a2802002108200141046a2802002107200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a200241086a290200370300200320022902003703e0050240200341e0056a10a7050d0020034180046a41186a2202420037030020034180046a41106a2201420037030020034180046a41086a220942003703002003420037038004200341f0026a4192fdc60041071081022009200341f0026a41086a290200370300200320032902f0023703800420034190036a418cabc600410d108102200220034190036a41086a290300370300200120032903900337030020064105744104722202417f4c0d2a2002102c2201450d30200341003602e805200320023602e405200320013602e0052006200341e0056a107602402006450d0020064105742101200721020340200341e0056a200241201074200241206a2102200141606a22010d000b0b20034180046a412020032802e005220220032802e80510b201024020032802e405450d002002102e0b0240200841ffffff3f71450d002007102e0b200042003703082000200328008005360019200041186a41003a00002000411c6a20034183056a280000360000200042003703000c320b0240200841ffffff3f71450d002007102e0b200341d8036a41026a200341b8046a41026a2d000022023a0000200320032f00b80422013b01d803200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a0000200042013703000c310b200141246a280200210620034180056a41186a200141196a29000037030020034180056a41106a200141116a29000037030020034180056a41086a200141096a2900003703002003200129000137038005200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a200241086a290200370300200320022902003703e005200341e0056a10a7050d05200341e0056a20034180056a2006108606200341b0036a41026a220120032d00e3053a0000200320032f00e1053b01b003024020032d00e00522024106460d0020032902e405210420034180046a41026a20012d00003a0000200320032f01b0033b0180040c1e0b42f3e885db96cddbb32020034180056a10ea02200041186a41003a000020004200370308200020032800b8043600192000411c6a200341bb046a280000360000200042003703000c300b200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a2201200241086a290200370300200320022902003703e005200341e0056a10a7050d03200341b8046a41186a22024200370300200341b8046a41106a22064200370300200341b8046a41086a22084200370300200342003703b804200341e0056a4192fdc600410710810220082001290000370300200320032900e0053703b804200341e0056a41b8b2c600410810810220022001290000370300200620032900e005370300200341003602e805200342013703e005200341033a00b003200341e0056a200341b0036a41011074200341b8046a412020032802e005220220032802e80510b201024020032802e405450d002002102e0b200041186a41003a00002000420037030820002003280080053600192000411c6a20034180056a41036a280000360000200042003703000c2f0b200141046a280200211b2002410e6a2f010021092002410d6a2d0000210a2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d00002114200241086a2d00002115200241046a2d00002108200141106a28020021072001410c6a280200211a200141086a280200211920022802282101024020022d000022060d002002411a6a2901002104200241196a2d00002106200241186a2d00002116200241166a2f01002117200241156a2d00002118200241146a2d0000211c200241126a2f0100211d200241116a2d0000211e200241106a2d0000211f200241066a2f01002120200241056a2d00002121200241026a2f0100212220022d0001210220012001280200417f6a2223360200024020230d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22232023280200417f6a222336020020230d002001102e0b200320043701d004200320063a00cf04200320163a00ce04200320173b01cc04200320183a00cb042003201c3a00ca042003201d3b01c8042003201e3a00c7042003201f3a00c604200320093b01c4042003200a3a00c3042003200d3a00c2042003200e3b01c004200320143a00bf04200320153a00be04200320203b01bc04200320213a00bb04200320083a00ba04200320223b01b8040240200241ff01710d00410321060c010b4110102c2202450d2d200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d2d20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a22163602004100210620160d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22162016280200417f6a221636020020160d002002102e0b024002402006417f6a0e03001a011a0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200841ff01710d18200e4110742014410874722015724102742009411074200a41087472200d7241036c490d180b024020070d0020034180046a41051082060c1a0b200741016a210120192102024003402001417f6a22014102490d01200241046a210620022802002108200241046a210220082006280200490d000b20034180046a410e1082060c1a0b200341e0056a201b10f90520034180056a20032802e005220220032802e80510f5050240024020032802800522180d004100211c200341003602c004200342083703b80441082118410021170c010b200320032902840522043702bc04200320183602b8042004422088a721172004a7211c0b024020032802e405450d002002102e0b02402007410274220d20196a417c6a2802002017490d0020034180046a410710820602402017450d00201741d8006c2101201841306a210203400240200241746a2802002206450d00200641306c450d00200241706a280200102e0b0240200228020041ffffff3f71450d002002417c6a280200102e0b200241d8006a2102200141a87f6a22010d000b0b201c450d1a201c41d8006c450d1a2018102e0c1a0b201741d8006c210641002101417f2108201921070340201720016a220920012007280200220e6a22024d0d022018200241d8006c6a220228022c211520022802202116200241306a2802002114200241246a280200210a2002200241d8006a20092008200e6b6a41d8006c10ea081a20032009417f6a3602c0040240200a450d00200a41306c450d002016102e0b0240201441ffffff3f71450d002015102e0b200741046a2107200841016a21082001417f6a2101200641a87f6a2106200d417c6a220d450d170c000b0b200141246a2802002106200341e0046a41186a2208200141196a290000370300200341e0046a41106a2207200141116a290000370300200341e0046a41086a2209200141096a290000370300200320012900013703e004200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a200241086a290200370300200320022902003703e00520034180056a200341e0056a10c10220032d0080054101460d0e200341b0036a41186a2008290300370300200341b0036a41106a2007290300370300200341b0036a41086a2009290300370300200320032903e0043703b00320034180046a41186a2201420037030020034180046a41106a2202420037030020034180046a41086a220842003703002003420037038004200341f0026a4192fdc60041071081022008200341f0026a41086a290200370300200320032902f0023703800420034190036a4194adc600410a108102200120034190036a41086a2903003703002002200329039003370300200341b8026a20034180046a4120108e0220032802b802450d0d024020032802bc02220120064f0d00200341e0026a410c1082060c130b20034198046a420037030020034180046a41106a420037030020034180046a41086a220842003703002003420037038004200341f0026a4192fdc60041071081022008200341f0026a41086a290200370300200320032902f0023703800420034190036a41e0a9c600410c108102200241086a20034190036a41086a2903003700002002200329039003370000200341b0026a20034180046a4120108e02024020064100200120032802b40241d40020032802b0021b6b2202200220014b1b22074f0d00200341e0026a410c1082060c130b200341e0056a200610970320034198026a20032802e005220120032802e80510f80220034198026a41106a290300210420032903a00221052003280298022102024020032802e405450d002001102e0b02402002450d00200341d8036a200341b0036a10e505200341e0056a20032802d803220120032802e00310f40220034180046a41086a200341e0056a41096a29000037030020034180046a41106a200341e0056a41116a29000037030020034198046a2208200341f9056a290000370300200320032900e10537038004410121020240024020032d00e0054101460d00410021020c010b20034180056a41086a20034180046a41096a29000037030020034180056a41106a20034180046a41116a29000037030020034197056a200829000037000020032003290081043703800520032d00800421080b024020032802dc03450d002001102e0b2002450d1120034190036a41176a220220034180056a41176a29000037000020034190036a41106a220120034180056a41106a290300370300200341c1046a20034180056a41086a290300370000200341c9046a2001290300370000200341b8046a41186a2002290000370000200320083a00b80420032003290380053700b90420034190036a200341b8046a10d305200341e0056a200328029003220e20032802980310e60520034180046a41086a22022003419c066a29020037030020034180046a41106a2201200341a4066a29020037030020034180046a41186a2209200341ac066a29020037030020034180046a41206a220a200341b4066a280200360200200320034194066a29020037038004200328028006220d450d12200341e0056a41186a290300210b200341e0056a41086a290300210c20034190066a28020021142003418c066a280200210820034188066a280200211520032903f005210f20032903e00521102003280284062116200341d8036a41206a200a280200360200200341d8036a41186a2009290300370300200341d8036a41106a2001290300370300200341d8036a41086a200229030037030020032003290380043703d8030240200328029403450d00200e102e0b20034180056a41186a200b370300200341b0056a2014360200200341a8056a2015360200200341a4056a2016360200200341b4056a220220032903d803370200200341bc056a200341e0036a290300370200200341c4056a200341e8036a290300370200200341cc056a200341d8036a41186a290300370200200341d4056a200341f8036a2802003602002003200f370390052003201037038005200320083602ac052003200d3602a0052003200c370388052002280200210d4100210920024100360200410021140240200d450d004100210e410021144100210102400340024002402014450d002001410274210203402007200820026a280200220a4b0d022008200e6a20026a200a3602000240200d200141016a220a4d0d00200241046a210220032802ac052108200a21010c010b0b200141016a21010c030b200820014102746a21020340200720022802004b0d01200241046a2102200d200141016a22014b0d000b410021140c030b200e417c6a210e201441016a2114200d200141016a22014b0d000b0b024020140d00410021140c010b20032802ac052202200120146b4102746a200220014102746a200d20016b41027410ea081a0b2003200d20146b220a3602b40520032802ac0521070240024002400240024002400240200a0e020201000b41002109200a2102034020092002410176220120096a22082006200720084102746a280200491b2109200220016b220241014b0d000b0b02402006200720094102746a2802002202470d00200341e0026a410f1082060c020b200a2009200620024b6a2209490d030b0240024002400240200a20032802b005470d00200a41016a2202200a490d2e200a41017422012002200120024b1b22024104200241044b1b220241ffffffff037120024641027421012002410274210202400240200a0d00200341003602e0050c010b200341e8056a4104360200200320073602e0052003200a4102743602e4050b20034180046a20022001200341e0056a107d20034188046a28020021022003280280044101460d01200320032802840422073602ac05200320024102763602b0050b200720094102746a220241046a2002200a20096b41027410ea081a200220063602002003200a41016a3602b40520034180046a2006200341b8056a220a10f705200341e0056a200328028004220220032802880410a20320032802800622150d01420021104100211a410821154100211641002117420021114200210c4200210f0c020b20020d320c2c0b20032f00850620034187066a2d0000411074724108742117200341e0056a41086a290300210f200341f8056a290300211120034188066a280200211a20032903e005210c20032903f005211020032d00840621160b0240200328028404450d002002102e0b200341b8046a20034180056a10d205200341f0026a4192fdc600410710810220034190036a41ed9fc5004110108102200320063602d8052003200341d8056a410410a3013703d803200341ec056a200341d8056a41046a3602002003200341e0036a3602e4052003200341d8056a3602e8052003200341d8036a3602e00520034180046a200341e0056a107c200328028804220141206a2202417f4c0d2a0240024020020d00410121080c010b2002102c2208450d310b200341003602e003200320023602dc03200320083602d803200341d8036a200341f0026a41101074200341d8036a20034190036a41101074200341d8036a2003280280042202200110740240200328028404450d002002102e0b200341e0056a20032802d803220220032802e00310a20520034180046a41086a2201200341ec056a290200370300200320032902e405370380040240024020032802e0054101460d00200341a8046a41086a420037030041002119200341003602a8040c010b200341a8046a41086a20012903003703002003200329038004220b3703a804200ba721190b024020032802dc03450d002002102e0b200341a8046a41047221180240200341b0046a280200220d450d0020032802ac04210e0340200d41046a2107200d41346a2101200d2f013222144105742102417f2108024002400340024020020d00201421080c020b200a2001412010ec082209450d02200841016a2108200741046a2107200241606a2102200141206a21012009417f4a0d000b0b200e450d02200e417f6a210e200d20084102746a4194036a280200210d0c010b0b200728020022010d020b200341063a00e002201810bc0220172016722202450d00200241306c450d002015102e0b024020032802a4052202450d00200241186c450d0020032802a005102e0b20032802b00541ffffffff0371450d1620032802ac05102e0c160b20194101201941014b1b2202418094ebdc036e2002418094ebdc03704100476a22084101200841014b1b220820024b0d0120034180026a20052004428094ebdc03420010e608200341f0016a20052004428094ebdc03420010e708200341e0016a20032903f001200341f0016a41086a2903002002200120022001491b20086ead428094ebdc037e200220086ead8042ffffffff0f832204420010e808200341e0056a2006200341b0036a10f80520034190026a20032802e005220120032802e805108705200341e0016a41086a29030020032903e001220520042003290380027e2204428094ebdc0380a72004428094ebdc03824280cab5ee01566aad7c2204200554ad7c2105410020032802900220032d0094024102461b2102024020032802e405450d002001102e0b200341b8016a20042005428094ebdc03420010e608200341a8016a20042005428094ebdc03420010e70820034198016a20032903a801200341a8016a41086a2903002002ad220b420010e80820034188016a2004200329039801221220032903b801200b7e220b428094ebdc0380a7417f200b428080808080c0b2cd3b541b200b428094ebdc03824280cab5ee01566aad7c220b7d2213200520034198016a41086a290300200b201254ad7c22247d2004200b54ad7d2204428094ebdc03420010e608200341f8006a20132004428094ebdc03420010e70820102011200c200f1082052102200341e8006a20032903782210200341f8006a41086a29030022112002ad2204420010e808200341c8016a200a20032903682205200329038801221220047e2204428094ebdc0380a7417f2004428080808080c0b2cd3b541b2004428094ebdc03824280cab5ee01566aad7c2204200b7c220b200341e8006a41086a2903002004200554ad7c20247c200b200454ad7c10890620034180046a41106a200341c8016a41106a2903002205370300200320032903d001220b37038804200320032903c80122043703800402402004a74101470d002003200b3703d803200320053703e003200341bb056a290000210420034198066a200537030020034190066a200b370300200341e8056a41013a0000200341e9056a20032f01b8053b0000200341eb056a200341ba056a2d00003a0000200341ec056a2004370200200341f4056a200341c3056a290000370200200341fc056a200341cb056a29000037020020034181066a200341d0056a290000370000200341043a00e005200341e0056a10fe012003200341d8036a3602e005200341e0056a10ce020c130b20044201520d12200320034180046a41086a3602e005200341e0056a10ce020c120b2009200a1045000b41d0d8c800411941bcd7cc001039000b200341e0026a410c1082060c120b200220091046000b200341d8036a41026a20034180046a41026a2d000022023a0000200320032f00800422013b01d803200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a0000200042013703000c2b0b410221020c170b200341d8036a41026a20034180046a41026a2d000022023a0000200320032f00800422013b01d803200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a0000200042013703000c290b200341d8036a41026a20034180046a41026a2d000022023a0000200320032f00800422013b01d803200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a0000200042013703000c280b200341023a00f0020c170b200341023a0090030c180b200341023a0090030c1a0b200341023a00f0020c200b2001410c6a2802002106200141086a2802002107200141046a2802002108200341e0056a41286a220a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a220d200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a220e200241086a290200370300200320022902003703e00520034180056a200341e0056a10c10220034180046a41086a220220034189056a29000037030020034180046a41106a220120034191056a29000037030020034180046a41186a220920034199056a290000370300200320032900810537038004024002400240024002400240024020032d0080054101460d00200341e0046a41186a2009290300370300200341e0046a41106a2001290300370300200341e0046a41086a200229030037030020032003290380043703e004200341b8046a200341e0046a10d305200341e0056a20032802b804221420032802c00410e60520022003419c066a2902003703002001200341a4066a2902003703002009200341ac066a29020037030020034180046a41206a200341b4066a280200360200200320034194066a2902003703800402402003280280062202450d00200d2903002104200e290300210520034190066a28020021012003418c066a2802002109200a280200210a20032903f005210b20032903e005210c200328028406210d200341d8036a41206a220e20034180046a41206a280200360200200341d8036a41186a221520034180046a41186a290300370300200341d8036a41106a221620034180046a41106a290300370300200341d8036a41086a221720034180046a41086a29030037030020032003290380043703d803024020032802bc04450d002014102e0b200341b0036a41086a22142017290300370300200341b0036a41106a22172016290300370300200341b0036a41186a22162015290300370300200341b0036a41206a2215200e28020036020020034180056a41186a2004370300200341b0056a2001360200200341a8056a200a36020020034180056a41246a200d360200200320032903d8033703b0032003200b370390052003200c37038005200320093602ac05200320023602a0052003200537038805200341d4056a2015280200360200200341cc056a2016290300370200200341c4056a2017290300370200200341bc056a2014290300370200200341b4056a20032903b0033702002008200641246c22026a2109024020020d00200821020c050b200341e0026a41026a2201200841036a2d00003a000020034190036a41086a220a200841146a29000037030020034190036a41106a220d2008411c6a290000370300200320082f00013b01e0022003200829000c37039003200841246a210220082d0000220e4105460d042008280008211420082800042115200341a8046a41026a20012d00003a0000200341b0036a41086a200a290300370300200341b0036a41106a200d290300370300200320032f01e0023b01a80420032003290390033703b0030240024002400240200e4107710e03000201020b200341b8046a41026a200341a8046a41026a2d00003a0000200341cb046a200341b8036a290300370000200341d0046a200341bd036a290000370000200320032f01a8043b01b804200320143600bf04200320153600bb04200320032903b0033700c304410121014100210a0c020b2014450d002015102e0b410021014101210a0b20034180046a41086a220d200341b8046a41086a29010037030020034180046a41106a220e200341b8046a41106a29010037030020034180046a41186a2214200341b8046a41186a290100370300200320032901b804370380042001450d05200341d8036a41186a2014290300370300200341d8036a41106a200e290300370300200341d8036a41086a200d29030037030020032003290380043703d8034120102c221c450d29201c20032903d803370000201c41186a200341d8036a41186a290300370000201c41106a200341d8036a41106a290300370000201c41086a200341d8036a41086a290300370000200921010240024020092002460d00200341e0026a41026a2201200241036a2d00003a000020034190036a41086a200841386a29000037030020034190036a41106a200841c0006a290000370300200320022f00013b01e0022003200829003037039003200841c8006a2102024020082d0024220d4105460d00200828002c210e20082800282114200341a8046a41026a20012d00003a0000200341b0036a41086a220120034190036a41086a290300370300200341b0036a41106a20034190036a41106a290300370300200320032f01e0023b01a80420032003290390033703b0030240024002400240200d4107710e03000201020b200341b8046a41026a200341a8046a41026a2d00003a0000200341cb046a2001290300370000200341d0046a200341bd036a290000370000200320032f01a8043b01b8042003200e3600bf04200320143600bb04200320032903b0033700c304410121010c020b200e450d002014102e0b410021014101210a0b20034180046a41086a2216200341b8046a41086a222529010037030020034180046a41106a2217200341b8046a41106a222629010037030020034180046a41186a2218200341b8046a41186a2227290100370300200320032901b8043703800420010d020b200221010b4101211f4101210d0c040b200341d8036a41186a22192018290300370300200341d8036a41106a221a2017290300370300200341d8036a41086a221b201629030037030020032003290380043703d803200841ec006a2101200641246c41b87f6a2114200341c3046a2128412021154102210d4101211f0340200341e0056a41186a221d2019290300370300200341e0056a41106a221e201a290300370300200341e0056a41086a2220201b290300370300200320032903d8033703e005024002400240200d417f6a201f470d00201f41016a220e201f490d27201f4101742221200e2021200e4b1b220e4104200e41044b1b220e41ffffff3f71200e462121200e410574210e02400240201f0d00200341003602b8040c010b200341013602c0042003201c3602b8042003201f4105743602bc040b20034180046a200e2021200341b8046a107d200328028804210e2003280280044101460d01200328028404211c200e410576211f0b201c20156a220e20032903e005370000200e41186a201d290300370000200e41106a201e290300370000200e41086a202029030037000020140d01200921010c060b200e0d2b0c250b200241086a2800002122200241046a2800002123200241036a2d0000210e20022f0001211d20034190036a41086a221e200241146a29000037030020034190036a41106a22202002411c6a290000370300200341e0026a41026a2221200e3a00002003201d3b01e00220032002410c6a2900003703900320022d0000220e4105460d04200341a8046a41026a221d20212d00003a0000200341b0036a41086a2221201e290300370300200341b0036a41106a2020290300370300200320032f01e0023b01a80420032003290390033703b0030240024002400240200e4107710e03000201020b202820032903b003370000200341b8046a41026a201d2d00003a0000202841086a20212903003700002028410d6a200341b0036a410d6a290000370000200320032f01a8043b01b804200320223600bf04200320233600bb044101210e0c020b2022450d002023102e0b4100210e4101210a0b201620252901003703002017202629010037030020182027290100370300200320032901b80437038004200e450d04200241246a210220192018290300370300201a2017290300370300201b201629030037030020032003290380043703d803201541206a2115200d41016a210d2014415c6a2114200141246a21010c000b0b024020032802bc04450d002014102e0b200341f0026a41011082060c010b200341023a00f0020b02402006450d00200641246c2101200821020340024020022d00004102470d00200241086a280200450d00200241046a280200102e0b200241246a21022001415c6a22010d000b0b2007450d04200741246c450d042008102e0c040b024020092001460d002008200641246c6a210603402001220241246a2101024020022d00004102470d00200241086a280200450d00200241046a280200102e0b20062001470d000b0b2007450d02200741246c450d022008102e0c020b4100210a0b024020092002460d002008200641246c6a210603402002220141246a2102024020012d00004102470d00200141086a280200450d00200141046a280200102e0b20062002470d000b0b4100211f4101211c02402007450d00200741246c450d002008102e0b4100210d0b024002400240200a41ff0171450d00201f41ffffff3f71450d01201c102e0c010b201c0d010b200341013a00f002024020032802a4052202450d00200241186c450d0020032802a005102e0b20032802b00541ffffffff0371450d0120032802ac05102e0c010b0240200d450d00201c200d4105746a211920034189066a211d200341e9056a211e200341b8056a2107201c21060340200641086a2900002104200641106a29000021052006290000210b200341b8046a41186a2216200641186a290000370300200341b8046a41106a22172005370300200341b8046a41086a221820043703002003200b3703b80420034180046a200341b8046a10d105200341e0056a200328028004220e200328028804221410870620034190036a41086a200341e0056a41086a290300370300200320032903e00537039003024002400240024020032d00f00522154102460d00200328029c03211a200328029403211b20032802900321080240200328029803220d0d004100210d0c030b200d41057441606a41057641016a210a41002102410021010340200820026a22092007412010ec08450d02200241206a2102200a200141016a2201470d000c030b0b200e201410ff010c020b2008200d417f6a220d4105746a22022900002104200229000821052002290010210b200941186a200241186a2900003700002009200b3700102009200537000820092004370000201e20032903b804370000201e41106a2017290300370000201e41186a2016290300370000201d2007290000370000201d41106a200741106a290000370000201d41186a200741186a290000370000200341083a00e805201e41086a2018290300370000201d41086a200741086a290000370000200341043a00e005200341e0056a10fe010b200341003602e805200342013703e005200d200341e0056a10760240200d450d00200d4105742101200821020340200341e0056a200241201074200241206a2102200141606a22010d000b0b2003201a3602d803200341e0056a200341d8036a41041074200320153a00b003200341e0056a200341b0036a41011074200e201420032802e005220220032802e80510b201024020032802e405450d002002102e0b201b41ffffff3f71450d002008102e0b200641206a21060240200328028404450d00200e102e0b20062019470d000b0b0240201f41ffffff3f71450d00201c102e0b200341063a00f002024020032802a4052202450d00200241186c450d0020032802a005102e0b20032802b00541ffffffff0371450d0020032802ac05102e0b0240024020032d00f0024106460d0020032802f0022102200020032902f402370024200041206a2002360000200041186a41003a000020004200370308420121040c010b4200210420004200370308200020032800e005360019200041186a41003a00002000411c6a200341e3056a2800003600000b200020043703000c230b200141246a28020021082002280228210220034180056a41186a200141196a29000037030020034180056a41106a200141116a29000037030020034188056a200141096a2900003703002003200129000137038005200341b8046a20034180056a10c802200341e0056a20032802b804220620032802c00410c902200341e0056a41106a290300420020032903e00542015122011b210420032903e805420020011b210520034180066a290300420020011b210b200341e0056a41186a290300420020011b210c024020032802bc04450d002006102e0b024002400240427f2005200c7c220c200c20055422012004200b7c2001ad7c220520045420052004511b22011b4280c8afa02585427f200520011b84500d0020034180046a410b1082060c010b200341e0056a20034180056a2008108606200341b2036a220120032d00e3053a0000200320032f00e1053b01b003024020032d00e00522064106470d0042f3e885db96cddbb32020034180056a10ea0220022002280200417f6a2201360200200341063a00800420010d022002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d022002102e0c020b20032902e4052104200320063a008004200320032f01b0033b0081042003200437028404200320012d00003a0083040b20022002280200417f6a2201360200024020010d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b20032d0080044106460d0020032802800421022000200329028404370024200041206a2002360000200041186a41003a000020004200370308200042013703000c230b20004200370308200020032800d803360019200041186a41003a00002000411c6a200341db036a280000360000200042003703000c220b200141046a2802002108200341e0056a41286a200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a200241086a290200370300200320022902003703e0050240200341e0056a10a7050d0020034180046a41186a2202420037030020034180046a41106a2206420037030020034180046a41086a220142003703002003420037038004200341f0026a4192fdc60041071081022001200341f0026a41086a290200370300200320032902f0023703800420034190036a4194adc600410a108102200220034190036a41086a2903003703002006200329039003370300200341c8026a20034180046a4120108e02024020032802c8024101470d0020032802cc02210120034198046a2209420037030020034190046a220a420037030020034180046a41086a220742003703002003420037038004200341f0026a4192fdc60041071081022007200341f0026a41086a220d290200370300200320032902f0023703800420034190036a41e0a9c600410c108102200641086a220e20034190036a41086a22142903003700002006200329039003370000200341c0026a20034180046a4120108e0202404100200120032802c40241d40020032802c0021b6b2202200220014b1b22024100200120086b2215201520014b1b22014f0d000340200210f6052001200241016a2202470d000b0b20094200370300200a4200370300200742003703002003420037038004200341f0026a4192fdc60041071081022007200d290200370300200320032902f0023703800420034190036a41e0a9c600410c108102200e20142903003700002006200329039003370000200320083602e00520034180046a4120200341e0056a410410b2010b200042003703082000200328008005360019200041186a41003a00002000411c6a20034183056a280000360000200042003703000c220b200341d8036a41026a200341b8046a41026a2d000022023a0000200320032f00b80422013b01d803200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a0000200042013703000c210b200141106a290300210b200141086a2903002110200341e0056a41286a2208200241286a280200360200200341e0056a41206a200241206a290200370300200341e0056a41186a2207200241186a290200370300200341e0056a41106a200241106a290200370300200341e0056a41086a2209200241086a290200370300200320022902003703e00520034180056a200341e0056a10c10220034180046a41086a220220034189056a29000037030020034180046a41106a220120034191056a29000037030020034180046a41186a220620034199056a290000370300200320032900810537038004024002400240024020032d0080054101460d00200341e0046a41186a2006290300370300200341e0046a41106a2001290300370300200341e0046a41086a200229030037030020032003290380043703e00420034180056a200341e0046a10d305200341e0056a200328028005220d20032802880510e60520022003419c066a2902003703002001200341a4066a2902003703002006200341ac066a29020037030020034180046a41206a200341b4066a280200360200200320034194066a290200370380040240200328028006220a450d00200729030021112009290300212920034190066a28020021072003418c066a28020021142008280200210120032903f005210c20032903e005212a2003280284062108200341d8036a41206a220220034180046a41206a280200360200200341d8036a41186a220620034180046a41186a290300370300200341d8036a41106a220920034180046a41106a290300370300200341d8036a41086a220e20034180046a41086a29030037030020032003290380043703d8030240200328028405450d00200d102e0b200341b0036a41106a20092903002204370300200341b8046a41086a200e290300370300200341b8046a41106a2004370300200341b8046a41186a2006290300370300200341b8046a41206a2002280200360200200320032903d8033703b80420010d02200341e0056a410a108206200320032900e105370390032003200341e8056a2800003600970320032d00e005210202402008450d00200841186c450d00200a102e0b200741ffffffff0371450d032014102e0c030b0240200328028405450d00200d102e0b200341e0056a4101108206200320032900e105370390032003200341e8056a2800003600970320032d00e00521020c020b410221020c010b20034180056a41206a200341b8046a41206a28020036020020034180056a41186a200341b8046a41186a29030037030020034180056a41106a200341b8046a41106a29030037030020034180056a41086a200341b8046a41086a290300370300200320032903b80437038005200141186c200a6a41686a2102420021124200211302400340024020010d0041002101200c210f0c020b02402002290300220f20127c2204201058200241086a290300222420137c2004200f54ad7c2205200b582005200b5122061b0d002002200f201020127d22047d37030020022024200b20137d2010201254ad7d22057d200f200454ad7d370308201120057c200c20047c220f200c54ad7c21110c020b2001417f6a2101201120247c200c200f7c220f200c54ad7c2111200241686a2102200f210c200421122005211320042010542005200b5420061b0d000b0b20034190066a200736020020034188066a200136020020034184066a200836020020034194066a2003290380053702002003200f3703f005200341e0056a41186a20113703002003419c066a20034180056a41086a2202290300370200200341a4066a20034190056a290300370200200341ac066a20034180056a41186a290300370200200341b4066a200341a0056a2802003602002003202a3703e0052003201436028c062003200a36028006200320293703e805200f42ffc7afa0255620114200522011501b0d0120034180056a4108108206200320032900810537039003200320022800003600970320032d008005210202402003280284062201450d00200141186c450d00200328028006102e0b20032802900641ffffffff0371450d00200328028c06102e0b200320032800a8043602e00220032003290390033703f00220032003280097033600f7022003200341ab046a2800003600e302200041186a41003a000020004200370308200020032802e0023600192000411c6a20032800e302360000200041206a20023a0000200020032903f002370021200041286a20032800f702360000200042013703000c210b42f3e885db96cddbb32020034198066a202a2029411f108506200341e0046a200341e0056a10d20520033502880642d086037e210402402003280284062202450d00200241186c450d00200328028006102e0b20044280f3e893017c2104024020032802900641ffffffff0371450d00200328028c06102e0b200320032800a8043602e0022003200341ab046a2800003600e302200041186a41003a0000200041106a200437030020004201370308200020032802e0023600192000411c6a20032800e302360000200042003703000c200b200341e0026a410c1082060c040b200341023a00e0020c040b0240201a450d002015201a41306c6a2109200341e0056a41146a2106200341e9056a210a20034180046a41086a210e20034198066a210d201521020340200341c0006a201020112002290300200241086a290300200c200f108205ad2204420010e808200341d0006a200241106a220120032903402205201220047e2204428094ebdc0380a7417f2004428080808080c0b2cd3b541b2004428094ebdc03824280cab5ee01566aad7c2204200341c0006a41086a2903002004200554ad7c10890620034180046a41106a200341d0006a41106a290300220537030020032003290358220b3703880420032003290350220437038004024002402004a74101470d002003200b3703d803200320053703e00320012f000021082003418c036a41026a200241126a2d000022073a0000200320083b01d805200320073a00da05200320083b018c03200241136a2900002104200a20083b0000200a41026a20073a0000200341013a00e805200341043a00e005200320043702ec052002412b6a28000021082002412f6a2d00002107200241236a290000210420062002411b6a290000370000200641086a2004370000200d2005370300200641146a20073a0000200641106a20083600002003200b37039006200341e0056a10fe012003200341d8036a3602e005200341e0056a10ce020c010b20044201520d002003200e3602e005200341e0056a10ce020b200141206a22022009470d000b0b200341063a00e002201810bc02024020172016722202450d00200241306c450d002015102e0b024020032802a4052202450d00200241186c450d0020032802a005102e0b20032802b00541ffffffff0371450d0220032802ac05102e0c020b200341e0026a41021082060c010b0240200328029403450d00200e102e0b200341e0026a41011082060b20032d00e0024106460d0120032902e40221040b20032802e002210220002004370024200041206a2002360000200041186a41003a000020004200370308200042013703000c190b20004200370308200020032800d802360019200041186a41003a00002000411c6a200341db026a280000360000200042003703000c180b0240201a41ffffffff0371450d002019102e0b201720016a2101200341e0056a201b10f90520032802e0052102200320032802e805360284052003200236028005200341b8046a20034180056a10b101024020032802e405450d002002102e0b02402001450d00201841306a210203400240200241746a2802002201450d00200141306c450d00200241706a280200102e0b0240200228020041ffffff3f71450d002002417c6a280200102e0b200241d8006a2102200641a87f6a22060d000b0b0240201c450d00201c41d8006c450d002018102e0b200341063a0080040c030b4110102c2202450d14200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1420014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220636020020060d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22062006280200417f6a220636020020060d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200341023a0080040b0240201a41ffffffff0371450d002019102e0b20032d0080044106460d0020032802800421022000200329028404370024200041206a2002360000200041186a41003a000020004200370308200042013703000c140b20004200370308200020032800d803360019200041186a41003a00002000411c6a200341db036a280000360000200042003703000c130b200341d8036a41026a20034180046a41026a2d000022013a0000200320032f01800422063b01d803200041206a20023a0000200041186a41003a000020004200370308200020063b0021200041236a20013a000020002004370024200042013703000c120b200341063a00a8040b20004200370308200020032800e002360019200041186a41003a00002000411c6a200341e3026a280000360000200042003703000c100b20032802f002210220002004370024200041206a2002360000200041186a41003a000020004200370308200042013703000c0f0b20004200370308200020032800a804360019200041186a41003a00002000411c6a200341ab046a280000360000200042003703000c0e0b200328029003210220002004370024200041206a2002360000200041186a41003a000020004200370308200042013703000c0d0b20004200370308200020032800f002360019200041186a41003a00002000411c6a200341f3026a280000360000200042003703000c0c0b20004200370308200020032800d802360019200041186a41003a00002000411c6a200341db026a280000360000200042003703000c0b0b200328029003210220002004370024200041206a2002360000200041186a41003a000020004200370308200042013703000c0a0b20004200370308200020032800f002360019200041186a41003a00002000411c6a200341f3026a280000360000200042003703000c090b02402010200329038005220c58200f20034180056a41086a290300220458200f2004511b0d0020034190066a2010200c7d370300200341e0056a41086a41073a0000200341e9056a20032903b804370000200341f1056a200341b8046a41086a290300370000200341f9056a200341c8046a29030037000020034181066a200341d0046a29030037000020034198066a200f20047d2010200c54ad7d370300200341043a00e005200341e0056a10fe010b024020032802a4052202450d00200241186c450d0020032802a005102e0b024020032802b00541ffffffff0371450d0020032802ac05102e0b200320032800a8043602e0022003200341ab046a2800003600e302200041186a41003a0000200041106a20053703002000200b370308200020032802e0023600192000411c6a20032800e302360000200042003703000c080b1038000b20032d00a8044106460d0120032902ac0421040b20032802a804210220002004370024200041206a2002360000200041186a41003a000020004200370308200042013703000c050b20004200370308200020032800e002360019200041186a41003a00002000411c6a200341e3026a280000360000200042003703000c040b20032d00f0024106460d0020032802f0022102200020032902f402370024200041206a2002360000200041186a41003a000020004200370308200042013703000c030b20004200370308200020032800a804360019200041186a41003a00002000411c6a200341ab046a280000360000200042003703000c020b1036000b20004200370308200020032800e002360019200041186a41003a00002000411c6a200341e3026a280000360000200042003703000b200341e0066a24000bac0401047f230041c0006b2202240041d6a2c50021034109210441132105024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141ff01710e15000102030405060708090a0b0c0d0e0f1011121314000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a41ec8fcc001044000b41c9a2c5002103410d2104410021050c120b41c1a2c500210341082104410121050c110b41b4a2c5002103410d2104410221050c100b41a7a2c5002103410d2104410321050c0f0b419ba2c5002103410c2104410421050c0e0b418da2c5002103410e2104410521050c0d0b41fca1c500210341112104410621050c0c0b41eba1c500210341112104410721050c0b0b41dfa1c5002103410c2104410821050c0a0b41d2a1c5002103410d2104410921050c090b41c6a1c5002103410c2104410a21050c080b41b4a1c500210341122104410b21050c070b419aa1c5002103411a2104410c21050c060b4188a1c500210341122104410d21050c050b41faa0c5002103410e2105410e21040c040b41e5a0c500210341152104410f21050c030b41cfa0c500210341162104411021050c020b41c7a0c500210341082104411121050c010b41b9a0c5002103410e2104411221050b200041830e3b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000b9c0203057f017e017f23004180026b22012400200141086a200010c802200141e0006a200128020822022001280210220310c902200141b4016a2802002104200141b0016a2802002100200141ac016a280200210520012903602106200141b8016a200141e8006a41c40010e9081a0240024020064201510d00200141186a410041c40010eb081a410121000c010b200141186a200141b8016a41c40010e9081a024020000d00410121000c010b200141e8006a200141186a41c40010e9082107200141b4016a2004360200200141b0016a2000360200200141ac016a417f200541016a220020002005491b3602002001420137036020022003200710c805410021000b0240200128020c450d002002102e0b20014180026a240020000bb10201037f230041e0006b22022400200241086a4192fdc6004107108102200241186a41a8acc6004105108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000bee06020a7f017e230022052106200541a0016b41607122052400200520003703180240024002402002200384500d00200520023703202005200037033020052003370328200541004102410120044101711b200441ff01714101461b3a003820054180016a200110d40620052802840121072005280280012208210902402005280288012204450d00200820044105746a210a200541e0006a41196a210b20082104200821090340200541c8006a41106a220c200441106a290300370300200541c8006a41086a220d200441086a29030037030020052004290300370348200441186a2d0000210e2005200441196a28000036024020052004411c6a280000360043200e4103460d01200b2005280240360000200b41036a2005280043360000200541e0006a41106a200c2903002202370300200520052903483703602005200e3a00782005200d2903003703680240024020022005290318520d00200541033a0098012005290330210320052005290390013703302005290328210020052005290388013703282005290320210f20052005290380013703202005290338210220052005290398013703382002a7210e0c010b200541e0006a41186a2903002202a7210e20052903702103200529036821002005290360210f0b0240200e41ff01714103460d002009200f3703002009200037030820092003370310200941186a2002370300200941206a21090b200441206a2204200a470d000b0b200920086b41057521040240024020052d00384103470d00200721050c010b2005290338210220052903302103200529032821002005290320210f0240024020042007460d0020072105200421070c010b200741016a22042007490d04200741017422092004200920044b1b22044104200441044b1b220441ffffff3f712004464103742109200441057421040240024020070d0020054100360280010c010b20054180016a41086a4108360200200520083602800120052007410574360284010b200541e0006a2004200920054180016a107d200541e8006a280200210420052802604101460d0320052802642108200441057621050b200820074105746a22042003370310200420003703082004200f370300200441186a2002370300200741016a21040b20012008200410d506200541ffffff3f71450d002008102e0b200624000f0b2004450d001036000b1038000bd20801087f230041c0016b22032400200341e8006a200110e50520034198016a20032802682204200328027010f402200341f8006a41086a2205200341a2016a290100370300200341f8006a41106a2206200341aa016a290100370300200341f8006a41176a2207200341b1016a2900003700002003200329019a01370378024002400240024020032d0098014101470d0020032d0099012108200341c8006a41176a2007290000370000200341c8006a41106a2006290300370300200341c8006a41086a2005290300370300200320032903783703480240200328026c450d002004102e0b200341286a41176a2204200341c8006a41176a290000370000200341286a41106a2205200341c8006a41106a290300370300200341116a200341d0006a290300370000200341196a2005290300370000200341206a2004290000370000200320083a00082003200329034837000920034198016a200110ce050240024020032802a4012209450d0020032802a801210a024002400240200341ac016a28020022044102742205417c6a41027641026a410120041b20024d0d00200341c8006a4111108206200a41ffffffff03710d010c020b200328029801210220034198016a200110cf05200328029801220420032802a00110ff010240200328029c01450d002004102e0b200920056a2108410021042009210620022107024003402004417e712105410221040240024020054102460d00200221050c010b2006450d0220082006460d02200641046a2106410321042007417f6a220721050b20034198016a41186a200141186a29000037030020034198016a41106a200141106a29000037030020034198016a41086a200141086a290000370300200320053602b8012003200129000037039801200341f8006a20034198016a10cd052003280278220520032802800110ff01200328027c450d002005102e0c000b0b200341063a0048200a41ffffffff0371450d030b2009102e0b200320032900493703282003200341c8006a41086a28000036002f20032d004822044106470d030c040b200341063a00480b200320032900493703282003200341d0006a28000036002f0c020b0240200328026c450d002004102e0b200041021082060c020b200020043a000020002003290328370001200041086a200328002f3600000c010b20034198016a200110e505200328029801220420032802a00110ff010240200328029c01450d002004102e0b20034198016a200341086a10d305200328029801220420032802a00110ff010240200328029c01450d002004102e0b20034198016a2001108406200328029801220420032802a00110ff010240200328029c01450d002004102e0b20034198016a2001108605200328029801220420032802a00110ff010240200328029c01450d002004102e0b20034198016a200110d105200328029801220420032802a00110ff010240200328029c01450d002004102e0b2001108a06200041063a00000b200341c0016a24000b970401087f230041e0006b220324002003200236020c20032001360208200341106a2001200210ed0202400240200328021022010d00200041023a00100c010b200328021421042003200341186a280200360224200320013602202003200341206a10ab01024002400240024002402003280200450d00200341003602480c010b200341c8006a200341206a200328020410920120032802482205450d00200328024c21060240200328022422024104490d00200341d0006a280200210720032802202208280000210920032002417c6a220a3602242003200841046a2208360220200a450d0020082d0000210a20032002417b6a3602242003200841016a36022041002102200a0e020302000b200641ffffff3f71450d002005102e0b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341909dc5003602482003200341386a360258200341c4006a419cebc000200341c8006a103d1a2003280228200328023010ef020240200328022c450d002003280228102e0b410221020c020b410121020b200341c8006a41026a200341286a41026a2d000022083a0000200320032f0028220a3b01482000200936020c2000200736020820002006360204200020053602002000200a3b0011200041136a20083a00000b200020023a00102004450d002001102e0b200341e0006a24000bbd0a020a7f017e230041c0016b2202240002400240024020012802082203200128020c460d00200128021421042001200341246a3602082002413c6a41026a2205200341036a2d00003a0000200241286a41086a2206200341186a290000370300200241286a41106a2207200341206a2d00003a0000200220032f00013b013c2002200341106a29000037032820032d000022084105470d010b410021030c010b2003410c6a2800002109200341086a280000210a200341046a280000210b20024188016a41026a20052d00003a0000200241a0016a41086a2006290300370300200241a0016a41106a20072d00003a0000200220022f013c3b018801200220022903283703a001024002400240024020084107710e03020100010b200a450d00200b102e0b4101210b410121030c010b20024184016a41026a20024188016a41026a2d000022033a0000200241f0006a41086a200241a0016a41086a290300220c370300200241f0006a41106a200241a0016a41106a2d000022053a0000200241ec006a41026a20033a0000200241d8006a41086a200c370300200241d8006a41106a20053a0000200220022f01880122033b018401200220022903a001220c370370200220033b016c2002200c370358410021030b2001280210210120024184016a41026a2205200241ec006a41026a2d00003a0000200241f0006a41086a2206200241d8006a41086a290300370300200241f0006a41106a2207200241d8006a41106a2d00003a0000200220022f016c3b0184012002200229035837037002400240024002402003450d00200b2103200a2101200921050c010b200241b7016a2006290300370000200241bf016a20072d00003a0000200220022f0184013b01a001200220093600ab012002200a3600a7012002200b3600a301200220022903703700af01200220052d00003a00a2012001280208410574210320012802002101200241af016a2106024003402003450d01200341606a21032001200241a0016a412010ec082105200141206a210120050d000c030b0b20024188016a200241a0016a108605200241086a200228028801220120022802900110870520022d000c41017121030240200228028c01450d002001102e0b2003450d0120024188016a411410820620024190016a2802002105200228028c01210120022802880121030b200420053602082004200136020420042003360200410021060c010b2002419c016a41026a20022d00a20122033a000020024188016a41086a200641086a290000220c37030020024188016a41106a200641106a2d000022013a0000200241d4006a41026a20033a0000200241c0006a41086a200c370300200241c0006a41106a20013a0000200220022f01a00122033b019c0120022006290000220c37038801200220033b01542002200c370340410121060b200241246a41026a200241d4006a41026a2d000022033a0000200241106a41086a2201200241c0006a41086a290300370300200241106a41106a2205200241c0006a41106a2d00003a0000200220022f015422043b01242002200229034037031020024188016a41026a220720033a0000200220043b018801200241a0016a41106a220420052d00003a0000200241a0016a41086a22052001290300370300200220022903103703a001410021032006450d00200020022f0188013b00012000410c6a2009360000200041086a200a360000200041046a200b360000200041106a20022903a001370000200041036a20072d00003a0000200041186a2005290300370000200041206a20042d00003a0000410121030b200020033a0000200241c0016a24000bfb1904057f037e077f057e230041d0036b22042400200441c0006a2001108406200428024021052004200428024822063602bc01200420053602b801200441f8006a2005200610ed0241052106024020042802782207450d00200428027c2108200420044180016a28020022063602fc01200420073602f80102400240024002402006450d0020042006417f6a3602fc012004200741016a3602f8014100210602400240024020072d00000e050504000102030b410221060c040b200441f8026a200441f8016a10930120042d00f8024101460d01200441b0026a20044191036a290000370300200441a8026a20044189036a290000370300200441a0026a20044181036a290000370300200420042900f90237039802410321060c030b410421060c020b200441003602a00220044201370398022004410a3602dc022004200441b8016a3602d802200420044198026a3602202004418c036a4101360200200442013702fc02200441909dc5003602f8022004200441d8026a36028803200441206a419cebc000200441f8026a103d1a20042802980220042802a00210ef020240200428029c02450d00200428029802102e0b410521060c020b410121060b200441d8016a41186a20044198026a41186a2903002209370300200441d8016a41106a20044198026a41106a290300220a370300200441d8016a41086a20044198026a41086a290300220b370300200441f8026a41086a200b370300200441f8026a41106a200a370300200441f8026a41186a2009370300200420042903980222093703d801200420093703f8020b2008450d002007102e0b200441d8016a41186a2208200441f8026a41186a290300370300200441d8016a41106a220c200441f8026a41106a290300370300200441d8016a41086a220d200441f8026a41086a290300370300200420042903f8023703d80141002107024020064105460d00200441206a41186a2008290300370300200441206a41106a200c290300370300200441206a41086a200d290300370300200420042903d801370320200621070b02402004280244450d002005102e0b4200210b024002400240024002400240024020070e050201000306020b200441f8006a200110e505200441f8026a2004280278220520042802800110f402200441d8016a41086a220620044181036a290000370300200441d8016a41106a220720044189036a290000370300200441d8016a41186a220120044191036a290000370300200420042900f9023703d801024020042d00f8024101470d0020044198026a41186a200129030037030020044198026a41106a200729030037030020044198026a41086a2006290300370300200420042903d801370398020240200428027c450d002005102e0b200441f8026a41186a20044198026a41186a290300370300200441f8026a41106a20044198026a41106a290300370300200441f8026a41086a20044198026a41086a29030037030020042004290398023703f8022004200441f8026a2002200310fd01200441086a290300210a200429030021090c040b0240200428027c450d002005102e0b0c050b200441f8026a200120022003108b0620043502f802420185210b20044188036a290300210a20044180036a29030021090c040b20044198026a200110e505200441f8026a200428029802220520042802a00210f402200441d8016a41086a220620044181036a290000370300200441d8016a41106a220720044189036a290000370300200441d8016a41186a220820044191036a290000370300200420042900f9023703d80102400240024020042d00f8024101470d00200441b8016a41186a2008290300370300200441b8016a41106a2007290300370300200441b8016a41086a2006290300370300200420042903d8013703b8010240200428029c02450d002005102e0b200441f8016a41186a200441b8016a41186a290300370300200441f8016a41106a200441b8016a41106a290300370300200441f8016a41086a200441b8016a41086a290300370300200420042903b8013703f801200441d8016a200441f8016a10d305200441f8026a20042802d801220620042802e00110e605200441f8006a41086a2207200441f8026a41086a290300370300200441f8006a41106a2208200441f8026a41106a290300370300200441f8006a41186a220c200441f8026a41186a29030037030020044198026a41086a220d200441a4036a29020037030020044198026a41106a220e200441ac036a29020037030020044198026a41186a220f200441b4036a29020037030020044198026a41206a2210200441bc036a29020037030020044198026a41286a2211200441c4036a29020037030020044198026a41306a2212200441cc036a280200360200200420042903f8023703782004200429029c03370398022004280298032205450d01200441d8026a41186a200c290300370300200441d8026a41106a2008290300370300200441d8026a41086a2007290300370300200441c0006a41086a200d290300370300200441c0006a41106a200e290300370300200441c0006a41186a200f290300370300200441c0006a41206a2010290300370300200441c0006a41286a2011290300370300200441c0006a41306a2012280200360200200420042903783703d8022004200429039802370340024020042802dc01450d002006102e0b200441d8016a41186a200441f8016a41186a2903002209370300200441d8016a41106a200441f8016a41106a290300220a370300200441d8016a41086a200441f8016a41086a290300220b370300200420042903f80122133703d801200441f8026a41186a2009370300200441f8026a41106a200a370300200441f8026a41086a200b370300200441f8026a41286a200441d8026a41086a2903002214370300200441f8026a41306a200441d8026a41106a2903002215370300200441f8026a41386a200441d8026a41186a2903002216370300200420133703f802200420042903d802221737039803200441f8006a41386a2016370300200441f8006a41306a2015370300200441f8006a41286a201437030020044198016a2017370300200441f8006a41186a2009370300200441f8006a41106a200a370300200441f8006a41086a200b370300200420133703780c020b200428029c02450d042005102e0c040b024020042802dc01450d002006102e0b200441d8016a41186a200441f8016a41186a290300370300200441d8016a41106a200441f8016a41106a290300370300200441d8016a41086a200441f8016a41086a290300370300200420042903f8013703d8010b2005450d0220044198026a41386a2207200441f8006a41386a29030037030020044198026a41306a2208200441f8006a41306a29030037030020044198026a41286a220c200441f8006a41286a29030037030020044198026a41206a220d200441f8006a41206a29030037030020044198026a41186a200441f8006a41186a220629030037030020044198026a41106a200441f8006a41106a220e29030037030020044198026a41086a200441f8006a41086a220f2903003703002004200429037837039802200441d8026a41186a2006290300370300200441d8026a41106a200e290300370300200441d8026a41086a200f290300370300200420042903783703d802200441f8026a41186a22062007290300370300200441f8026a41106a22072008290300370300200441f8026a41086a2208200c29030037030020042005360298032004200d2903003703f8022004419c036a22052004290340370200200441a4036a200441c0006a41086a290300370200200441ac036a200441c0006a41106a290300370200200441b4036a200441c0006a41186a290300370200200441bc036a200441c0006a41206a290300370200200441c4036a200441c0006a41286a290300370200200441cc036a200441c0006a41306a2802003602002006290300210920072007290300220a20027c220b3703002006200920037c200b200a54ad7c3703002008200829030020037c20042903f802220920027c220b200954ad7c22133703002004200b3703f802200441f8016a200120022003108b06200441f8016a41106a290300210a200441f8016a41086a290300210920043502f801210242f3e885db96cddbb320200441f8026a41386a200b2013411f108506200441d8026a200441f8026a10d205024020052802002205450d00200541186c450d00200428029803102e0b0240200441f8026a41306a28020041ffffffff0371450d0020042802a403102e0b2002420185210b0c030b200441f8026a41186a200441206a41186a290300370300200441f8026a41106a200441206a41106a290300370300200441f8026a41086a200441206a41086a290300370300200420042903203703f802200441106a200441f8026a2002200310fd01200441106a41086a290300210a200429031021090b4201210b0c010b4200210b0b200020093703082000200b370300200041106a200a370300200441d0036a24000bff0105027f017e017f017e017f23004180026b22012400200141086a200010c802200141e0006a200128020822002001280210220210c902200141b0016a2903002103200141ac016a280200210420012903602105200141b8016a200141e8006a41c40010e9081a02400240024020054201510d00200141186a410041c40010eb081a420021030c010b200141186a200141b8016a41c40010e9081a2004450d002004417f6a21040c010b410021040b200141e8006a200141186a41c40010e9082106200141b0016a2003370300200141ac016a20043602002001420137036020002002200610c8050240200128020c450d002000102e0b20014180026a24000bc21005027f0c7e037f017e017f230041b0026b220424000240024020022003844200520d0020004100360200200041106a4200370300200041086a42003703000c010b200441c0006a200110c802200441b0016a20042802402205200428024810c902200441b0016a41386a2903002106200441b0016a41306a2903002107200441b0016a41286a2903002108200441b0016a41206a2903002109200441b0016a41186a290300210a200441b0016a41106a290300210b200441f0016a290300210c20042903b801210d20042903b001210e20044180016a41086a20044180026a2903003703002004200441f8016a2903003703800102400240200e4201510d004200210c200441386a4200370300200441306a4200370300200441286a4200370300200441206a4200370300200441186a4200370300200441106a4200370300200441086a420037030020044200370300420021094200210842002107420021064200210d4200210b4200210a4200210f420021104200210e420021110c010b200441206a2008370300200441286a2007370300200441106a200a370300200441306a2006370300200420093703182004200d3703002004200c3703382004200b3703082008210f20072110200d210e200b21110b02402004280244450d002005102e0b02400240200e2011844200520d00200f2004290310842010200441186a29030084844200520d002004290330200441386a2903008450450d004200210e410021050c010b4201210e410121050b024002400240200e4201510d004280808080b001210241b4a4c70021054180801c21010c010b0240200d20027c220e200d542212200b20037c2012ad7c220d200b54200d200b511b450d0042808080808001210241a984ca0021054180800821010c010b200441d0016a2008370300200441d8016a2007370300200441e0016a2006370300200420093703c8012004200e3703b0012004200d3703b8012004200a3703c0014200210b2002422088a721122002a7211302400240427f200e200a7c22022002200e542214200d20097c2014ad7c2202200d542002200d511b22141b221142ffc7afa02556427f200220141b22024200522002501b0d00200e200a84200d20098484220b5021144200210a200b420052ad210b0c010b200441c0016a290300211520042903b801211020042903b001210f4201210a410121140b200441e8006a2002370300200441e0006a22162011370300200441d0006a200d3703002004200e3703482004200337037820042012360274200420133602702004200b3703582004420037034002400240024002402005200a420152720d00200420013602b0012001200441b0016a10bd060c010b024020054101732205200a420151720d00200420013602b0012001200441b0016a10be0641ff017122054103460d010240024020050e03010300010b200441f0006a2101024020140d00200420163602b001200441b0016a10cc020b200420013602b001200441b0016a10ce024104210541002101410021120c060b200441f8006a29030021092004290370210a0c030b200a4201522005710d010b20044190016a200110c802200441b0016a2004280290012212200428029801221310c90220042903b001210220044180016a41086a220520044180026a2903003703002004200441f8016a290300370380010240024020024201510d00200441a0016a41086a4200370300200442003703a0010c010b200441a0016a41086a200529030037030020042004290380013703a0010b200441f8016a20042903a00137030020044180026a200441a0016a41086a290300370300200442013703b001200441b0016a41386a20064200200a42015122051b370300200441e0016a2007420020051b370300200441b0016a41286a2008420020051b370300200441d0016a2009420020051b370300200441c8016a2015420020051b370300200441b0016a41106a2010420020051b370300200441f0016a200c420020051b3703002004200f420020051b3703b80120122013200441b0016a41086a10c8050240200428029401450d002012102e0b200441c0006a41286a2903002102200441c0006a41386a2903002109200429036021112004290370210a2004290358210b20042903404201520d0120042903482103200441e8016a200441c0006a41106a290300370300200441e0016a2003370300200441b0016a41086a41003a0000200441b9016a2001290000370000200441c1016a200141086a290000370000200441c9016a200141106a290000370000200441d1016a200141186a290000370000200441033a00b001200441b0016a10fe010c010b200441f8006a29030021092004290370210a0b02400240200b50450d004200210b0c010b200441b0016a41186a200141186a290000370300200441b0016a41106a200141106a290000370300200441b0016a41086a200141086a290000370300200420012900003703b0014201210b0b200441c0006a41186a200441b0016a41186a22012903002203370300200441c0006a41106a200441b0016a41106a2205290300220d370300200441c0006a41086a200441b0016a41086a2903002207370300200420042903b0012208370340200441e0016a2002370300200441d8016a22122011370300200520073703002001200d370300200441d0016a20033703002004200b3703b001200420083703b801200441b0016a10d204024020042903b001500d0020042012360200200410cc020b20004100360200200041106a2009370300200041086a200a3703000c020b20022005ad8421024103210541800a21120b200041086a200237020020004101360200200020014180801c71201241800e71722005723602040b200441b0026a24000bb50501047f230041c0006b220124002001410036022020014201370318024002400240024002400240200028020022020e050001020304050b200141013a0008200141186a200141086a41011074200028020421032000410c6a2802002204200141186a10760240200441286c2204450d00200320046a21040340200141186a2003412010742001200341206a290300370308200141186a200141086a41081074200341286a22032004470d000b0b2001200041106a280200360208200141186a200141086a410410740c040b200141023a0008200141186a200141086a4101107420012000280204360208200141186a200141086a41041074200041086a2802002103200041106a2802002204200141186a10760240200441286c2204450d00200320046a21040340200141186a2003412010742001200341206a290300370308200141186a200141086a41081074200341286a22032004470d000b0b2001200041146a280200360208200141186a200141086a410410740c030b200141033a0008200141186a200141086a410110742001200041086a290300370308200141186a200141086a410810740c020b200141043a0008200141186a200141086a4101107420012000280204360208200141186a200141086a410410740c010b200141053a0008200141186a200141086a4101107420012000280204360208200141186a200141086a410410740b200141136a200141186a41086a2802003600002001200129031837000b200141186a410c6a2001410f6a290000370000200141c6a4b9da04360019200141023a00182001200129000837001d200141186a10a50402400240024020020e020001020b200041086a2802002203450d01200341286c450d012000280204102e0c010b2000410c6a2802002203450d00200341286c450d00200041086a280200102e0b200141c0006a24000b9dc602140c7f017e017f017e057f017e087f017e017f017e087f017e017f027e017f017e017f017e017f017e230041c0026b220424002004200336020420012802042105200128020021060240024002400240024002400240200128020822030d004104210741002108410021090c010b2003410374210a20044198026a41026a210b200441e0006a41106a210c4100210d411b210e4100210841002109410421072006210f02400240024003404100210302402002280208200f2902002210a722114d0d00200b2002280200201141386c6a2203410a6a2d00003a0000200441e0006a41086a2003411f6a290000370300200c200341276a2d00003a0000200420032f00083b0198022004200341176a2900003703602003410f6a29000021122003410b6a2800002113410121030b41022114200441bc016a41026a20044198026a41026a2d00003a0000200441d8016a41086a2215200441e0006a41086a2216290300370300200441d8016a41106a2217200c2d00003a0000200420042f0198023b01bc01200420042903603703d8014101211102402003450d00200441206a41026a200441bc016a41026a2d00003a0000200441f0016a41086a2015290300370300200441f0016a41106a20172d00003a0000200420042f01bc013b0120200420042903d8013703f0014100211120122118201321140b200441dc006a41026a2203200441206a41026a22192d00003a0000200441c0016a41086a221a200441f0016a41086a221b290300370300200441c0016a41106a221c200441f0016a41106a221d2d00003a0000200420042f01203b015c200420042903f0013703c00120110d02200441d8006a41026a221e20032d00003a0000200441a0016a41086a221f201a290300370300200441a0016a41106a2220201c2d00003a0000200420042f015c3b0158200420042903c0013703a0014122102c2203450d094100211102402004280204221a2802082010422088a741ffff0371221c4d0d002019201a280200201c4105746a221141026a2d00003a00002016201141176a290000370300200c2011411f6a2d00003a0000200420112f00003b01202004201129000f3703602011290007212120112800032122410121110b4102211a200441bc016a41026a200441206a41026a2d00003a0000201520162903003703002017200c2d00003a0000200420042f01203b01bc01200420042903603703d8014101211602402011450d00200441086a41026a200441bc016a41026a2d00003a0000201b2015290300370300201d20172d00003a0000200420042f01bc013b0108200420042903d8013703f00141002116202121232022211a0b200441b8016a41026a2211200441086a41026a2d00003a000020044198026a41086a2215201b29030037030020044198026a41106a2217201d2d00003a0000200420042f01083b01b801200420042903f0013703980220160d01200320042f01b8013b0000200320233700072003201a360003200320042903980237000f200341ffff033b0120200341026a20112d00003a0000200341176a20152903003700002003411f6a20172d00003a0000200420042f01583b01542004201e2d00003a0056200441386a41106a221520202d00003a0000200441386a41086a2217201f290300370300200420042903a0013703380240024020082009470d00200d200841016a2211200d20114b1b22114104201141044b1bad422c7e2210422088a74541027421112010a7210902400240200e411b470d00200441003602600c010b20044104360268200420073602602004200e41656a3602640b200441f0016a20092011200441e0006a107d20042802f801211120042802f0014101460d0120042802f40121072011412c6e21090b200f41086a210f2007200e6a221141656a2003360200201141696a428180808010370200201141786a201837000020042d0056210320042f01542116201141746a2014360000201141716a221420163b0100201441026a20033a000020112004290338370000201141086a2017290300370000201141106a20152d00003a0000200d41026a210d200e412c6a210e200841016a2108200a41786a220a450d050c010b0b2011450d070c080b2000201a36020420004101360200200041086a20233702002003102e0c010b2000201436020420004101360200200041086a20183702000b4101210c0240200541ffffffff0171450d002006102e0b41012102410121164101211b4101211d4101211a4101210f410121154101211c4101210a410121174101210d410121144101210e4101211e0c010b0240200541ffffffff0171450d002006102e0b200141106a2802002124200128020c21250240200141146a2802002203450d002003410c6c21262008410174211b2008412c6c411b6a211420044198026a41026a2127200441e0006a41106a210e41002116024002400240024003400240202520166a220341066a2f0100221d41ffff03470d00200042013702000c050b200341086a2f0100210a200341046a2f0100210d4100211502402002280208200328020022034d0d0020272002280200200341386c6a2203410a6a2d00003a0000200441e0006a41086a2003411f6a290000370300200e200341276a2d00003a0000200420032f00083b0198022004200341176a2900003703602003410f6a29000021122003410b6a2800002128410121150b4102211a200441bc016a41026a20044198026a41026a2d00003a0000200441d8016a41086a2211200441e0006a41086a220f290300370300200441d8016a41106a220c200e2d00003a0000200420042f0198023b01bc01200420042903603703d8014101210302402015450d00200441c0016a41026a200441bc016a41026a2d00003a0000200441f0016a41086a2011290300370300200441f0016a41106a200c2d00003a0000200420042f01bc013b01c001200420042903d8013703f00141002103201221102028211a0b200441cc006a41026a221c200441c0016a41026a2d00003a0000200441386a41086a221e200441f0016a41086a2215290300370300200441386a41106a221f200441f0016a41106a22172d00003a0000200420042f01c0013b014c200420042903f00137033820030d02200441346a41026a2222201c2d00003a0000200441206a41086a220b201e290300370300200441206a41106a2206201f2d00003a0000200420042f014c3b01342004200429033837032041c400102c2203450d0a4100211c02402004280204221f2802082220200d4d0d002027201f280200200d4105746a220d41026a2d00003a0000200f200d41176a290000370300200e200d411f6a2d00003a00002004200d2f00003b0198022004200d29000f370360200d2900072121200d28000321294101211c0b4102211e200441bc016a41026a20044198026a41026a2d00003a00002011200f290300370300200c200e2d00003a0000200420042f0198023b01bc01200420042903603703d8014101210d0240201c450d00200441b8016a41026a200441bc016a41026a2d00003a0000201520112903003703002017200c2d00003a0000200420042f01bc013b01b801200420042903d8013703f0014100210d202121182029211e0b200441d4006a41026a221c200441b8016a41026a222a2d00003a0000200441c0016a41086a22192015290300370300200441c0016a41106a221320172d00003a0000200420042f01b8013b0154200420042903f0013703c001200d0d03200441d0006a41026a2205201c2d00003a0000200441a0016a41086a222b2019290300370300200441a0016a41106a221920132d00003a0000200420042f01543b0150200420042903c0013703a0014100210d02402020200a4d0d00202a201f280200200a4105746a220d41026a2d00003a0000200f200d41176a290000370300200e200d411f6a2d00003a00002004200d2f00003b01b8012004200d29000f370360200d290007212c200d280003212d4101210d0b4102211c200441bc016a41026a200441b8016a41026a2d00003a00002011200f290300370300200c200e2d00003a0000200420042f01b8013b01bc01200420042903603703d8014101210f0240200d450d00200441dc006a41026a200441bc016a41026a2d00003a0000201520112903003703002017200c2d00003a0000200420042f01bc013b015c200420042903d8013703f0014100210f202c2123202d211c0b200441d8006a41026a2211200441dc006a41026a2d00003a000020044198026a41086a220c201529030037030020044198026a41106a221520172d00003a0000200420042f015c3b0158200420042903f00137039802200f0d01200320042f01503b0100200320183700072003201e360003200320042903a00137000f2003201d3b0120200320042f01583b0022200341026a20052d00003a0000200341176a202b2903003700002003411f6a20192d00003a0000200341246a20112d00003a0000200320233700292003201c3600252003201d417f733b01422003200429039802370031200341396a200c290300370000200341c1006a20152d00003a0000200441086a41086a220c200b290300370300200441086a41106a220f20062d00003a0000200420042f01343b011c200420222d00003a001e200420042903203703080240024020082009470d00201b200841016a2211201b20114b1b22114104201141044b1bad422c7e222e422088a7454102742111202ea721150240024020080d00200441003602600c010b20044104360268200420073602602004201441656a3602640b200441f0016a20152011200441e0006a107d20042802f801211120042802f0014101460d0120042802f40121072011412c6e21090b200720146a221141656a2003360200201141696a428280808020370200201141786a201037000020042d001e210320042f011c2115201141746a201a360000201141716a221720153b0100201741026a20033a000020112004290308370000201141086a200c290300370000201141106a200f2d00003a0000201b41026a211b2014412c6a2114200841016a210820262016410c6a2216470d010c060b0b20110d090c080b2000201c36020420004101360200200041086a20233702002003102e0c020b2000201a36020420004101360200200041086a20103702000c010b2000201e36020420004101360200200041086a20183702002003102e0b4100211e4101210c02402024450d002024410c6c450d002025102e0b41012102410121164101211b4101211d4101211a4101210f410121154101211c4101210a410121174101210d410121144101210e0c010b02402024450d002024410c6c450d002025102e0b200128021821282001411c6a28020021270240200141206a2802002203450d00202820034104746a2125200441e0006a4102722116200441206a41086a21052028211e02400240024002400340201e2f010c211f201e28020021202004201e290204370320200441003b015c20044105360238200420053602dc012004200441386a3602e8012004200441046a3602e4012004200441dc006a3602e0012004200441206a3602d801200441e0006a200441d8016a108e060240024020042f01604101470d004122102c220f450d0c200f2016290100370100200f41206a201641206a221b2f01003b0100200f41186a201641186a221d290100370100200f41106a201641106a221a290100370100200f41086a201641086a221c29010037010020044198026a41106a200441d8016a41106a28020036020020044198026a41086a200441d8016a41086a290300370300200420042903d80137039802200441e0006a20044198026a108e06410121114101210e20042f01604101470d01410121114122210c4101210e02400340200441f0016a41206a2215201b2f01003b0100200441f0016a41186a2217201d290100370300200441f0016a41106a220d201a290100370300200441f0016a41086a2214201c290100370300200420162901003703f0010240200e2011470d00201141016a22032011490d0e2011410174220a2003200a20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7210a0240024020110d00200441003602c0010c010b200441023602c8012004200f3602c0012004201141226c3602c4010b200441a0016a200a2003200441c0016a107d20042802a801210320042802a0014101460d0220042802a401210f200341226e21110b200f200c6a220320042903f001370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441e0006a20044198026a108e0620042f01604101460d000c030b0b20030d0c0c0b0b410021114102210f4100210e0b0240200428023822034105460d00200429023c211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441a0016a41026a200c280200201f4105746a220341026a2d00003a0000200441e0006a41086a200341176a290000370300200441e0006a41106a2003411f6a2d00003a0000200420032f00003b01a0012004200329000f370360200329000721122003280003212b410121030b4102211a200441bc016a41026a200441a0016a41026a2d00003a0000200441d8016a41086a221b200441e0006a41086a221c290300370300200441d8016a41106a221d200441e0006a41106a220a2d00003a0000200420042f01a0013b01bc01200420042903603703d8014101210d02402003450d00200441386a41026a200441bc016a41026a2d00003a0000200441f0016a41086a201b290300370300200441f0016a41106a201d2d00003a0000200420042f01bc013b0138200420042903d8013703f0014100210d20122118202b211a0b200441086a41026a220c200441386a41026a221f2d00003a000020044198026a41086a2215200441f0016a41086a221929030037030020044198026a41106a2217200441f0016a41106a22132d00003a0000200420042f01383b0108200420042903f0013703980202400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441c0016a41086a220d2015290300370300200441c0016a41106a221420172d00003a0000200420042f01083b01b80120042004290398023703c001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d10201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602600c010b200441023602682004200f3602602004201141226c3602640b200441f0016a20062003200441e0006a107d20042802f801210320042802f0014101460d0120042802f401210f200341226e21060b200f201141226c6a22032018370007200b2d0000211120042f01b801210b2003201a3600032003200b3b0100200341026a20113a0000200320042903c00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441a0016a41026a2002280200202041386c6a2203410a6a2d00003a0000201c2003411f6a290000370300200a200341276a2d00003a0000200420032f00083b01a0012004200341176a2900003703602003410f6a29000021212003410b6a280000212a410121030b4102211a200441bc016a41026a200441a0016a41026a2d00003a0000201b201c290300370300201d200a2d00003a0000200420042f01a0013b01bc01200420042903603703d8014101211102402003450d00201f200441bc016a41026a2d00003a00002019201b2903003703002013201d2d00003a0000200420042f01bc013b0138200420042903d8013703f0014100211120212123202a211a0b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01383b0108200420042903f0013703980220110d07200d2015290300370300201420172d00003a0000200420042f01083b01b80120042004290398023703c0012004200c2d00003a00ba0120082009470d0420084101742203200841016a2211200320114b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7211120080d02200441003602600c030b20030d0f0c0e0b2000201a36020420004101360200200041086a20183702000c070b200441043602682004200736026020042008412c6c3602640b200441f0016a20112003200441e0006a107d20042802f801210320042802f0014101460d0120042802f40121072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a2023370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a201a3600002003411b6a20042903c001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201e41106a221e2025470d010c060b0b20030d090c080b2000201a36020420004101360200200041086a2023370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b4100210e4101210c0240202741ffffffff0071450d002028102e0b41012102410121164101211b4101211d4101211a4101210f410121154101211c4101210a410121174101210d410121144100211e0c010b0240202741ffffffff0071450d002028102e0b20012802242127200141286a2802002129024002402001412c6a2802002203450d002027200341146c6a2128200441e0006a4102722116200441206a410c6a2105200441206a41086a212b2027211e02400240024002400340201e2f0110211f201e2802002120201e2901042110202b201e410c6a28010036020020042010370320200441003b015c20044105360238200420053602dc012004200441386a3602e8012004200441046a3602e4012004200441dc006a3602e0012004200441206a3602d801200441e0006a200441d8016a108e060240024020042f01604101470d004122102c220f450d0d200f2016290100370100200f41206a201641206a221b2f01003b0100200f41186a201641186a221d290100370100200f41106a201641106a221a290100370100200f41086a201641086a221c29010037010020044198026a41106a200441d8016a41106a28020036020020044198026a41086a200441d8016a41086a290300370300200420042903d80137039802200441e0006a20044198026a108e06410121114101210e20042f01604101470d01410121114122210c4101210e02400340200441f0016a41206a2215201b2f01003b0100200441f0016a41186a2217201d290100370300200441f0016a41106a220d201a290100370300200441f0016a41086a2214201c290100370300200420162901003703f0010240200e2011470d00201141016a22032011490d0f2011410174220a2003200a20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7210a0240024020110d00200441003602c0010c010b200441023602c8012004200f3602c0012004201141226c3602c4010b200441a0016a200a2003200441c0016a107d20042802a801210320042802a0014101460d0220042802a401210f200341226e21110b200f200c6a220320042903f001370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441e0006a20044198026a108e0620042f01604101460d000c030b0b20030d0d0c0c0b410021114102210f4100210e0b0240200428023822034105460d00200429023c211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441a0016a41026a200c280200201f4105746a220341026a2d00003a0000200441e0006a41086a200341176a290000370300200441e0006a41106a2003411f6a2d00003a0000200420032f00003b01a0012004200329000f370360200329000721122003280003212a410121030b4102211a200441bc016a41026a200441a0016a41026a2d00003a0000200441d8016a41086a221b200441e0006a41086a221c290300370300200441d8016a41106a221d200441e0006a41106a220a2d00003a0000200420042f01a0013b01bc01200420042903603703d8014101210d02402003450d00200441386a41026a200441bc016a41026a2d00003a0000200441f0016a41086a201b290300370300200441f0016a41106a201d2d00003a0000200420042f01bc013b0138200420042903d8013703f0014100210d20122118202a211a0b200441086a41026a220c200441386a41026a221f2d00003a000020044198026a41086a2215200441f0016a41086a221929030037030020044198026a41106a2217200441f0016a41106a22132d00003a0000200420042f01383b0108200420042903f0013703980202400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441c0016a41086a220d2015290300370300200441c0016a41106a221420172d00003a0000200420042f01083b01b80120042004290398023703c001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d11201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602600c010b200441023602682004200f3602602004201141226c3602640b200441f0016a20062003200441e0006a107d20042802f801210320042802f0014101460d0120042802f401210f200341226e21060b200f201141226c6a22032018370007200b2d0000211120042f01b801210b2003201a3600032003200b3b0100200341026a20113a0000200320042903c00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441a0016a41026a2002280200202041386c6a2203410a6a2d00003a0000201c2003411f6a290000370300200a200341276a2d00003a0000200420032f00083b01a0012004200341176a2900003703602003410f6a29000021212003410b6a2800002125410121030b41022111200441bc016a41026a200441a0016a41026a2d00003a0000201b201c290300370300201d200a2d00003a0000200420042f01a0013b01bc01200420042903603703d8014101211a02402003450d00201f200441bc016a41026a2d00003a00002019201b2903003703002013201d2d00003a0000200420042f01bc013b0138200420042903d8013703f0014100211a20212123202521110b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01383b0108200420042903f00137039802201a0d07200d2015290300370300201420172d00003a0000200420042f01083b01b80120042004290398023703c0012004200c2d00003a00ba0120082009470d0420084101742203200841016a220c2003200c4b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7210c20080d02200441003602600c030b20030d100c0f0b2000201a36020420004101360200200041086a20183702000c070b200441043602682004200736026020042008412c6c3602640b200441f0016a200c2003200441e0006a107d20042802f801210320042802f0014101460d0120042802f40121072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a2023370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a20113600002003411b6a20042903c001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201e41146a221e2028470d010c060b0b20030d0a0c090b2000201136020420004101360200200041086a2023370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b410021144101210c02402029450d00202941146c450d002027102e0b41012102410121164101211b4101211d4101211a4101210f410121154101211c4101210a410121174101210d0c010b02402029450d00202941146c450d002027102e0b20012802302127200141346a280200212902400240200141386a2802002203450d002027200341186c6a2128200441e0006a4102722116200441a0016a41106a2105200441a0016a41086a212b2027211e02400240024002400340201e2f0114211f201e2802002120201e2901042110202b201e410c6a290100370300200420103703a001200441003b015c20044105360220200420053602dc012004200441206a3602e8012004200441046a3602e4012004200441dc006a3602e0012004200441a0016a3602d801200441e0006a200441d8016a108e060240024020042f01604101470d004122102c220f450d0e200f2016290100370100200f41206a201641206a221b2f01003b0100200f41186a201641186a221d290100370100200f41106a201641106a221a290100370100200f41086a201641086a221c29010037010020044198026a41106a200441d8016a41106a28020036020020044198026a41086a200441d8016a41086a290300370300200420042903d80137039802200441e0006a20044198026a108e06410121114101210e20042f01604101470d01410121114122210c4101210e02400340200441f0016a41206a2215201b2f01003b0100200441f0016a41186a2217201d290100370300200441f0016a41106a220d201a290100370300200441f0016a41086a2214201c290100370300200420162901003703f0010240200e2011470d00201141016a22032011490d102011410174220a2003200a20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7210a0240024020110d00200441003602c0010c010b200441023602c8012004200f3602c0012004201141226c3602c4010b200441386a200a2003200441c0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a220320042903f001370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441e0006a20044198026a108e0620042f01604101460d000c030b0b20030d0e0c0d0b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441e0006a41086a200341176a290000370300200441e0006a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f370360200329000721122003280003212a410121030b4102211a200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221b200441e0006a41086a221c290300370300200441d8016a41106a221d200441e0006a41106a220a2d00003a0000200420042f01383b01bc01200420042903603703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a0000200441f0016a41086a201b290300370300200441f0016a41106a201d2d00003a0000200420042f01bc013b0120200420042903d8013703f0014100210d20122118202a211a0b200441086a41026a220c200441206a41026a221f2d00003a000020044198026a41086a2215200441f0016a41086a221929030037030020044198026a41106a2217200441f0016a41106a22132d00003a0000200420042f01203b0108200420042903f0013703980202400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441c0016a41086a220d2015290300370300200441c0016a41106a221420172d00003a0000200420042f01083b01b80120042004290398023703c001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d12201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602600c010b200441023602682004200f3602602004201141226c3602640b200441f0016a20062003200441e0006a107d20042802f801210320042802f0014101460d0120042802f401210f200341226e21060b200f201141226c6a22032018370007200b2d0000211120042f01b801210b2003201a3600032003200b3b0100200341026a20113a0000200320042903c00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000201c2003411f6a290000370300200a200341276a2d00003a0000200420032f00083b01382004200341176a2900003703602003410f6a29000021212003410b6a2800002125410121030b41022111200441bc016a41026a200441386a41026a2d00003a0000201b201c290300370300201d200a2d00003a0000200420042f01383b01bc01200420042903603703d8014101211a02402003450d00201f200441bc016a41026a2d00003a00002019201b2903003703002013201d2d00003a0000200420042f01bc013b0120200420042903d8013703f0014100211a20212123202521110b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b0108200420042903f00137039802201a0d07200d2015290300370300201420172d00003a0000200420042f01083b01b80120042004290398023703c0012004200c2d00003a00ba0120082009470d0420084101742203200841016a220c2003200c4b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7210c20080d02200441003602600c030b20030d110c100b2000201a36020420004101360200200041086a20183702000c070b200441043602682004200736026020042008412c6c3602640b200441f0016a200c2003200441e0006a107d20042802f801210320042802f0014101460d0120042802f40121072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a2023370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a20113600002003411b6a20042903c001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201e41186a221e2028470d010c060b0b20030d0b0c0a0b2000201136020420004101360200200041086a2023370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b4100210d4101210c02402029450d00202941186c450d002027102e0b41012102410121164101211b4101211d4101211a4101210f410121154101211c4101210a410121170c010b02402029450d00202941186c450d002027102e0b200128023c2129200141c0006a280200212d02400240200141c4006a2802002203450d0020292003411c6c6a2127200441e0006a4102722116200441c0016a41146a2105200441c0016a41106a212b200441c0016a41086a212a2029211e02400240024002400340201e2f0118211f201e2802002120201e410c6a2901002110201e2901042118202b201e41146a280100360200202a2010370300200420183703c001200441003b015c20044105360220200420053602dc012004200441206a3602e8012004200441046a3602e4012004200441dc006a3602e0012004200441c0016a3602d801200441e0006a200441d8016a108e060240024020042f01604101470d004122102c220f450d0f200f2016290100370100200f41206a201641206a221b2f01003b0100200f41186a201641186a221d290100370100200f41106a201641106a221a290100370100200f41086a201641086a221c29010037010020044198026a41106a200441d8016a41106a28020036020020044198026a41086a200441d8016a41086a290300370300200420042903d80137039802200441e0006a20044198026a108e06410121114101210e20042f01604101470d01410121114122210c4101210e02400340200441f0016a41206a2215201b2f01003b0100200441f0016a41186a2217201d290100370300200441f0016a41106a220d201a290100370300200441f0016a41086a2214201c290100370300200420162901003703f0010240200e2011470d00201141016a22032011490d112011410174220a2003200a20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7210a0240024020110d00200441003602a0010c010b200441023602a8012004200f3602a0012004201141226c3602a4010b200441386a200a2003200441a0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a220320042903f001370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441e0006a20044198026a108e0620042f01604101460d000c030b0b20030d0f0c0e0b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441e0006a41086a200341176a290000370300200441e0006a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f3703602003290007212120032800032125410121030b4102211a200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221b200441e0006a41086a221c290300370300200441d8016a41106a221d200441e0006a41106a220a2d00003a0000200420042f01383b01bc01200420042903603703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a0000200441f0016a41086a201b290300370300200441f0016a41106a201d2d00003a0000200420042f01bc013b0120200420042903d8013703f0014100210d202121232025211a0b200441086a41026a220c200441206a41026a221f2d00003a000020044198026a41086a2215200441f0016a41086a221929030037030020044198026a41106a2217200441f0016a41106a22132d00003a0000200420042f01203b0108200420042903f0013703980202400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441a0016a41086a220d2015290300370300200441a0016a41106a221420172d00003a0000200420042f01083b01b80120042004290398023703a001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d13201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602600c010b200441023602682004200f3602602004201141226c3602640b200441f0016a20062003200441e0006a107d20042802f801210320042802f0014101460d0120042802f401210f200341226e21060b200f201141226c6a22032023370007200b2d0000211120042f01b801210b2003201a3600032003200b3b0100200341026a20113a0000200320042903a00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000201c2003411f6a290000370300200a200341276a2d00003a0000200420032f00083b01382004200341176a2900003703602003410f6a290000212c2003410b6a2800002128410121030b41022111200441bc016a41026a200441386a41026a2d00003a0000201b201c290300370300201d200a2d00003a0000200420042f01383b01bc01200420042903603703d8014101211a02402003450d00201f200441bc016a41026a2d00003a00002019201b2903003703002013201d2d00003a0000200420042f01bc013b0120200420042903d8013703f0014100211a202c2112202821110b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b0108200420042903f00137039802201a0d07200d2015290300370300201420172d00003a0000200420042f01083b01b80120042004290398023703a0012004200c2d00003a00ba0120082009470d04200841016a22032008490d122008410174220c2003200c20034b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7210c20080d02200441003602600c030b20030d120c110b2000201a36020420004101360200200041086a20233702000c070b200441043602682004200736026020042008412c6c3602640b200441f0016a200c2003200441e0006a107d20042802f801210320042802f0014101460d0120042802f40121072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a2012370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a20113600002003411b6a20042903a001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201e411c6a221e2027470d010c060b0b20030d0c0c0b0b2000201136020420004101360200200041086a2012370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b410021174101210c0240202d450d00202d411c6c450d002029102e0b41012102410121164101211b4101211d4101211a4101210f410121154101211c4101210a0c010b0240202d450d00202d411c6c450d002029102e0b20012802482129200141cc006a280200212d02400240200141d0006a2802002203450d00202920034105746a2127200441e0006a410272211620044198026a41186a210520044198026a41106a212b20044198026a41086a212a2029211e02400240024002400340201e2f011c211f201e2802002120201e410c6a2901002110201e2901042118202b201e41146a290100370300202a20103703002004201837039802200441003b015c20044105360220200420053602c4012004200441206a3602d0012004200441046a3602cc012004200441dc006a3602c801200420044198026a3602c001200441e0006a200441c0016a108e060240024020042f01604101470d004122102c220f450d10200f2016290100370100200f41206a201641206a221b2f01003b0100200f41186a201641186a221d290100370100200f41106a201641106a221a290100370100200f41086a201641086a221c290100370100200441d8016a41106a200441c0016a41106a280200360200200441d8016a41086a200441c0016a41086a290300370300200420042903c0013703d801200441e0006a200441d8016a108e06410121114101210e20042f01604101470d01410121114122210c4101210e02400340200441f0016a41206a2215201b2f01003b0100200441f0016a41186a2217201d290100370300200441f0016a41106a220d201a290100370300200441f0016a41086a2214201c290100370300200420162901003703f0010240200e2011470d00201141016a22032011490d122011410174220a2003200a20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7210a0240024020110d00200441003602a0010c010b200441023602a8012004200f3602a0012004201141226c3602a4010b200441386a200a2003200441a0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a220320042903f001370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441e0006a200441d8016a108e0620042f01604101460d000c030b0b20030d100c0f0b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441e0006a41086a200341176a290000370300200441e0006a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f3703602003290007212120032800032125410121030b4102211a200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221b200441e0006a41086a221c290300370300200441d8016a41106a221d200441e0006a41106a220a2d00003a0000200420042f01383b01bc01200420042903603703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a0000200441f0016a41086a201b290300370300200441f0016a41106a201d2d00003a0000200420042f01bc013b0120200420042903d8013703f0014100210d202121232025211a0b200441086a41026a220c200441206a41026a221f2d00003a0000200441c0016a41086a2215200441f0016a41086a2219290300370300200441c0016a41106a2217200441f0016a41106a22132d00003a0000200420042f01203b0108200420042903f0013703c00102400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441a0016a41086a220d2015290300370300200441a0016a41106a221420172d00003a0000200420042f01083b01b801200420042903c0013703a001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d14201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602600c010b200441023602682004200f3602602004201141226c3602640b200441f0016a20062003200441e0006a107d20042802f801210320042802f0014101460d0120042802f401210f200341226e21060b200f201141226c6a22032023370007200b2d0000211120042f01b801210b2003201a3600032003200b3b0100200341026a20113a0000200320042903a00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000201c2003411f6a290000370300200a200341276a2d00003a0000200420032f00083b01382004200341176a2900003703602003410f6a290000212c2003410b6a2800002128410121030b41022111200441bc016a41026a200441386a41026a2d00003a0000201b201c290300370300201d200a2d00003a0000200420042f01383b01bc01200420042903603703d8014101211a02402003450d00201f200441bc016a41026a2d00003a00002019201b2903003703002013201d2d00003a0000200420042f01bc013b0120200420042903d8013703f0014100211a20282111202c21120b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b0108200420042903f0013703c001201a0d07200d2015290300370300201420172d00003a0000200420042f01083b01b801200420042903c0013703a0012004200c2d00003a00ba0120082009470d04200841016a22032008490d132008410174220c2003200c20034b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7210c20080d02200441003602600c030b20030d130c120b2000201a36020420004101360200200041086a20233702000c070b200441043602682004200736026020042008412c6c3602640b200441f0016a200c2003200441e0006a107d20042802f801210320042802f0014101460d0120042802f40121072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a2012370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a20113600002003411b6a20042903a001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201e41206a221e2027470d010c060b0b20030d0d0c0c0b2000201136020420004101360200200041086a2012370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b4100210a4101210c0240202d41ffffff3f71450d002029102e0b41012102410121164101211b4101211d4101211a4101210f410121154101211c0c010b0240202d41ffffff3f71450d002029102e0b2001280254212d200141d8006a280200212602400240200141dc006a2802002203450d00202d200341246c6a2129200441e0006a410272211620044198026a411c6a210520044198026a41186a212b20044198026a41106a212a20044198026a41086a2125202d211e02400240024002400340201e2f0120211f201e2802002120201e410c6a2901002110201e41146a2901002118201e2901042123202b201e411c6a280100360200202a2018370300202520103703002004202337039802200441003b015c20044105360220200420053602c4012004200441206a3602d0012004200441046a3602cc012004200441dc006a3602c801200420044198026a3602c001200441e0006a200441c0016a108e060240024020042f01604101470d004122102c220f450d11200f2016290100370100200f41206a201641206a221b2f01003b0100200f41186a201641186a221d290100370100200f41106a201641106a221a290100370100200f41086a201641086a221c290100370100200441d8016a41106a200441c0016a41106a280200360200200441d8016a41086a200441c0016a41086a290300370300200420042903c0013703d801200441e0006a200441d8016a108e06410121114101210e20042f01604101470d01410121114122210c4101210e02400340200441f0016a41206a2215201b2f01003b0100200441f0016a41186a2217201d290100370300200441f0016a41106a220d201a290100370300200441f0016a41086a2214201c290100370300200420162901003703f0010240200e2011470d00201141016a22032011490d132011410174220a2003200a20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7210a0240024020110d00200441003602a0010c010b200441023602a8012004200f3602a0012004201141226c3602a4010b200441386a200a2003200441a0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a220320042903f001370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441e0006a200441d8016a108e0620042f01604101460d000c030b0b20030d110c100b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441e0006a41086a200341176a290000370300200441e0006a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f3703602003290007212c20032800032128410121030b4102211a200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221b200441e0006a41086a221c290300370300200441d8016a41106a221d200441e0006a41106a220a2d00003a0000200420042f01383b01bc01200420042903603703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a0000200441f0016a41086a201b290300370300200441f0016a41106a201d2d00003a0000200420042f01bc013b0120200420042903d8013703f0014100210d2028211a202c21120b200441086a41026a220c200441206a41026a221f2d00003a0000200441c0016a41086a2215200441f0016a41086a2219290300370300200441c0016a41106a2217200441f0016a41106a22132d00003a0000200420042f01203b0108200420042903f0013703c00102400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441a0016a41086a220d2015290300370300200441a0016a41106a221420172d00003a0000200420042f01083b01b801200420042903c0013703a001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d15201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602600c010b200441023602682004200f3602602004201141226c3602640b200441f0016a20062003200441e0006a107d20042802f801210320042802f0014101460d0120042802f401210f200341226e21060b200f201141226c6a22032012370007200b2d0000211120042f01b801210b2003201a3600032003200b3b0100200341026a20113a0000200320042903a00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000201c2003411f6a290000370300200a200341276a2d00003a0000200420032f00083b01382004200341176a2900003703602003410f6a290000212e2003410b6a2800002127410121030b41022111200441bc016a41026a200441386a41026a2d00003a0000201b201c290300370300201d200a2d00003a0000200420042f01383b01bc01200420042903603703d8014101211a02402003450d00201f200441bc016a41026a2d00003a00002019201b2903003703002013201d2d00003a0000200420042f01bc013b0120200420042903d8013703f0014100211a20272111202e21210b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b0108200420042903f0013703c001201a0d07200d2015290300370300201420172d00003a0000200420042f01083b01b801200420042903c0013703a0012004200c2d00003a00ba0120082009470d04200841016a22032008490d142008410174220c2003200c20034b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7210c20080d02200441003602600c030b20030d140c130b2000201a36020420004101360200200041086a20123702000c070b200441043602682004200736026020042008412c6c3602640b200441f0016a200c2003200441e0006a107d20042802f801210320042802f0014101460d0120042802f40121072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a2021370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a20113600002003411b6a20042903a001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201e41246a221e2029470d010c060b0b20030d0e0c0d0b2000201136020420004101360200200041086a2021370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b4100211c4101210c02402026450d00202641246c450d00202d102e0b41012102410121164101211b4101211d4101211a4101210f410121150c010b02402026450d00202641246c450d00202d102e0b2001280260212d200141e4006a280200212602400240200141e8006a2802002203450d00202d200341286c6a2129200441e0006a410272211620044198026a41206a210520044198026a41186a212b20044198026a41106a212a20044198026a41086a2125202d211e02400240024002400340201e2f0124211f201e2802002120201e410c6a2901002110201e41146a2901002118201e2901042123202b201e411c6a290100370300202a2018370300202520103703002004202337039802200441003b015c20044105360220200420053602c4012004200441206a3602d0012004200441046a3602cc012004200441dc006a3602c801200420044198026a3602c001200441e0006a200441c0016a108e060240024020042f01604101470d004122102c220f450d12200f2016290100370100200f41206a201641206a221b2f01003b0100200f41186a201641186a221d290100370100200f41106a201641106a221a290100370100200f41086a201641086a221c290100370100200441d8016a41106a200441c0016a41106a280200360200200441d8016a41086a200441c0016a41086a290300370300200420042903c0013703d801200441e0006a200441d8016a108e06410121114101210e20042f01604101470d01410121114122210c4101210e02400340200441f0016a41206a2215201b2f01003b0100200441f0016a41186a2217201d290100370300200441f0016a41106a220d201a290100370300200441f0016a41086a2214201c290100370300200420162901003703f0010240200e2011470d00201141016a22032011490d142011410174220a2003200a20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7210a0240024020110d00200441003602a0010c010b200441023602a8012004200f3602a0012004201141226c3602a4010b200441386a200a2003200441a0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a220320042903f001370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441e0006a200441d8016a108e0620042f01604101460d000c030b0b20030d120c110b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441e0006a41086a200341176a290000370300200441e0006a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f3703602003290007212c20032800032128410121030b4102211a200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221b200441e0006a41086a221c290300370300200441d8016a41106a221d200441e0006a41106a220a2d00003a0000200420042f01383b01bc01200420042903603703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a0000200441f0016a41086a201b290300370300200441f0016a41106a201d2d00003a0000200420042f01bc013b0120200420042903d8013703f0014100210d2028211a202c21120b200441086a41026a220c200441206a41026a221f2d00003a0000200441c0016a41086a2215200441f0016a41086a2219290300370300200441c0016a41106a2217200441f0016a41106a22132d00003a0000200420042f01203b0108200420042903f0013703c00102400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441a0016a41086a220d2015290300370300200441a0016a41106a221420172d00003a0000200420042f01083b01b801200420042903c0013703a001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d16201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602600c010b200441023602682004200f3602602004201141226c3602640b200441f0016a20062003200441e0006a107d20042802f801210320042802f0014101460d0120042802f401210f200341226e21060b200f201141226c6a22032012370007200b2d0000211120042f01b801210b2003201a3600032003200b3b0100200341026a20113a0000200320042903a00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000201c2003411f6a290000370300200a200341276a2d00003a0000200420032f00083b01382004200341176a2900003703602003410f6a290000212e2003410b6a2800002127410121030b41022111200441bc016a41026a200441386a41026a2d00003a0000201b201c290300370300201d200a2d00003a0000200420042f01383b01bc01200420042903603703d8014101211a02402003450d00201f200441bc016a41026a2d00003a00002019201b2903003703002013201d2d00003a0000200420042f01bc013b0120200420042903d8013703f0014100211a20272111202e21210b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b0108200420042903f0013703c001201a0d07200d2015290300370300201420172d00003a0000200420042f01083b01b801200420042903c0013703a0012004200c2d00003a00ba0120082009470d04200841016a22032008490d152008410174220c2003200c20034b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7210c20080d02200441003602600c030b20030d150c140b2000201a36020420004101360200200041086a20123702000c070b200441043602682004200736026020042008412c6c3602640b200441f0016a200c2003200441e0006a107d20042802f801210320042802f0014101460d0120042802f40121072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a2021370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a20113600002003411b6a20042903a001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201e41286a221e2029470d010c060b0b20030d0f0c0e0b2000201136020420004101360200200041086a2021370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b410021154101210c02402026450d00202641286c450d00202d102e0b41012102410121164101211b4101211d4101211a4101210f0c010b02402026450d00202641286c450d00202d102e0b200128026c2126200141f0006a280200212402400240200141f4006a2802002203450d0020262003412c6c6a212d200441e0006a4102722116200441f0016a41246a2105200441f0016a41206a212b200441f0016a41186a212a200441f0016a41106a2125200441f0016a41086a21282026211b02400240024002400340201b2f0128211f201b2802002120201b410c6a2901002110201b41146a2901002118201b411c6a2901002123201b2901042112202b201b41246a280100360200202a20233703002025201837030020282010370300200420123703f001200441003b015c20044105360220200420053602c4012004200441206a3602d0012004200441046a3602cc012004200441dc006a3602c8012004200441f0016a3602c001200441e0006a200441c0016a108e060240024020042f01604101470d004122102c220f450d13200f2016290100370100200f41206a201641206a221d2f01003b0100200f41186a201641186a221a290100370100200f41106a201641106a221c290100370100200f41086a201641086a220a290100370100200441d8016a41106a200441c0016a41106a280200360200200441d8016a41086a200441c0016a41086a290300370300200420042903c0013703d801200441e0006a200441d8016a108e06410121114101210e20042f01604101470d01410121114122210c4101210e0240034020044198026a41206a2215201d2f01003b010020044198026a41186a2217201a29010037030020044198026a41106a220d201c29010037030020044198026a41086a2214200a29010037030020042016290100370398020240200e2011470d00201141016a22032011490d152011410174221e2003201e20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7211e0240024020110d00200441003602a0010c010b200441023602a8012004200f3602a0012004201141226c3602a4010b200441386a201e2003200441a0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a2203200429039802370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441e0006a200441d8016a108e0620042f01604101460d000c030b0b20030d130c120b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441e0006a41086a200341176a290000370300200441e0006a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f3703602003290007212e20032800032127410121030b4102211c200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221d200441e0006a41086a220a290300370300200441d8016a41106a221a200441e0006a41106a221e2d00003a0000200420042f01383b01bc01200420042903603703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a000020044198026a41086a201d29030037030020044198026a41106a201a2d00003a0000200420042f01bc013b0120200420042903d801370398024100210d2027211c202e21210b200441086a41026a220c200441206a41026a221f2d00003a0000200441c0016a41086a221520044198026a41086a2219290300370300200441c0016a41106a221720044198026a41106a22132d00003a0000200420042f01203b010820042004290398023703c00102400240024002400240200d0d00200441b8016a41026a2206200c2d00003a0000200441a0016a41086a220d2015290300370300200441a0016a41106a221420172d00003a0000200420042f01083b01b801200420042903c0013703a001024002400240200e2011460d002011210b200e21110c010b201141016a22032011490d172011410174220b2003200b20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7210b0240024020110d00200441003602600c010b200441023602682004200f3602602004201141226c3602640b20044198026a200b2003200441e0006a107d20042802a00221032004280298024101460d01200428029c02210f200341226e210b0b200f201141226c6a2203202137000720062d0000211120042f01b80121062003201c360003200320063b0100200341026a20113a0000200320042903a00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000200a2003411f6a290000370300201e200341276a2d00003a0000200420032f00083b01382004200341176a2900003703602003410f6a290000212f2003410b6a2800002129410121030b4102211c200441bc016a41026a200441386a41026a2d00003a0000201d200a290300370300201a201e2d00003a0000200420042f01383b01bc01200420042903603703d8014101211102402003450d00201f200441bc016a41026a2d00003a00002019201d2903003703002013201a2d00003a0000200420042f01bc013b0120200420042903d80137039802410021112029211c202f212c0b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b010820042004290398023703c00120110d07200d2015290300370300201420172d00003a0000200420042f01083b01b801200420042903c0013703a0012004200c2d00003a00ba0120082009470d04200841016a22032008490d16200841017422112003201120034b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7211120080d02200441003602600c030b20030d160c150b2000201c36020420004101360200200041086a20213702000c070b200441043602682004200736026020042008412c6c3602640b20044198026a20112003200441e0006a107d20042802a00221032004280298024101460d01200428029c0221072003412c6e21090b20072008412c6c6a2203200e41016a3602082003200b3602042003200f360200200341136a202c370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a201c3600002003411b6a20042903a001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201b412c6a221b202d470d010c060b0b20030d100c0f0b2000201c36020420004101360200200041086a202c370200200b21110c010b200042013702000b2011450d00201141226c450d00200f102e0b4100210f4101210c02402024450d002024412c6c450d002026102e0b41012102410121164101211b4101211d4101211a0c010b02402024450d002024412c6c450d002026102e0b20012802782126200141fc006a28020021240240024020014180016a2802002203450d002026200341306c6a212d200441f0016a410272211620044188016a2105200441e0006a41206a212b200441e0006a41186a212a200441e0006a41106a2125200441e0006a41086a21282026211b02400240024002400340201b2f012c211f201b2802002120201b410c6a2901002110201b41146a2901002118201b411c6a2901002123201b2901042112202b201b41246a290100370300202a2023370300202520183703002028201037030020042012370360200441003b015c20044105360220200420053602c4012004200441206a3602d0012004200441046a3602cc012004200441dc006a3602c8012004200441e0006a3602c001200441f0016a200441c0016a108e060240024020042f01f0014101470d004122102c220f450d14200f2016290100370100200f41206a201641206a221d2f01003b0100200f41186a201641186a221a290100370100200f41106a201641106a221c290100370100200f41086a201641086a220a290100370100200441d8016a41106a200441c0016a41106a280200360200200441d8016a41086a200441c0016a41086a290300370300200420042903c0013703d801200441f0016a200441d8016a108e06410121114101210e20042f01f0014101470d01410121114122210c4101210e0240034020044198026a41206a2215201d2f01003b010020044198026a41186a2217201a29010037030020044198026a41106a220d201c29010037030020044198026a41086a2214200a29010037030020042016290100370398020240200e2011470d00201141016a22032011490d162011410174221e2003201e20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7211e0240024020110d00200441003602a0010c010b200441023602a8012004200f3602a0012004201141226c3602a4010b200441386a201e2003200441a0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a2203200429039802370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441f0016a200441d8016a108e0620042f01f0014101460d000c030b0b20030d140c130b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441f0016a41086a200341176a290000370300200441f0016a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f3703f0012003290007212e20032800032127410121030b4102211c200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221d200441f0016a41086a220a290300370300200441d8016a41106a221a200441f0016a41106a221e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a000020044198026a41086a201d29030037030020044198026a41106a201a2d00003a0000200420042f01bc013b0120200420042903d801370398024100210d2027211c202e21210b200441086a41026a220c200441206a41026a221f2d00003a0000200441c0016a41086a221520044198026a41086a2219290300370300200441c0016a41106a221720044198026a41106a22132d00003a0000200420042f01203b010820042004290398023703c00102400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441a0016a41086a220d2015290300370300200441a0016a41106a221420172d00003a0000200420042f01083b01b801200420042903c0013703a001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d18201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602f0010c010b200441023602f8012004200f3602f0012004201141226c3602f4010b20044198026a20062003200441f0016a107d20042802a00221032004280298024101460d01200428029c02210f200341226e21060b200f201141226c6a22032021370007200b2d0000211120042f01b801210b2003201c3600032003200b3b0100200341026a20113a0000200320042903a00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000200a2003411f6a290000370300201e200341276a2d00003a0000200420032f00083b01382004200341176a2900003703f0012003410f6a290000212f2003410b6a2800002129410121030b41022111200441bc016a41026a200441386a41026a2d00003a0000201d200a290300370300201a201e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101211c02402003450d00201f200441bc016a41026a2d00003a00002019201d2903003703002013201a2d00003a0000200420042f01bc013b0120200420042903d801370398024100211c20292111202f212c0b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b010820042004290398023703c001201c0d07200d2015290300370300201420172d00003a0000200420042f01083b01b801200420042903c0013703a0012004200c2d00003a00ba0120082009470d04200841016a22032008490d172008410174220c2003200c20034b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7210c20080d02200441003602f0010c030b20030d170c160b2000201c36020420004101360200200041086a20213702000c070b200441043602f801200420073602f00120042008412c6c3602f4010b20044198026a200c2003200441f0016a107d20042802a00221032004280298024101460d01200428029c0221072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a202c370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a20113600002003411b6a20042903a001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201b41306a221b202d470d010c060b0b20030d110c100b2000201136020420004101360200200041086a202c370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b4100211a4101210c02402024450d00202441306c450d002026102e0b41012102410121164101211b4101211d0c010b02402024450d00202441306c450d002026102e0b200128028401212420014188016a2802002130024002402001418c016a2802002203450d002024200341346c6a2126200441f0016a4102722116200441e0006a412c6a210520044188016a212b200441e0006a41206a212a200441e0006a41186a2125200441e0006a41106a2128200441e0006a41086a21272024211b02400240024002400340201b2f0130211f201b2802002120201b410c6a2901002110201b41146a2901002118201b411c6a2901002123201b41246a2901002112201b2901042121202b201b412c6a280100360200202a201237030020252023370300202820183703002027201037030020042021370360200441003b015c20044105360220200420053602c4012004200441206a3602d0012004200441046a3602cc012004200441dc006a3602c8012004200441e0006a3602c001200441f0016a200441c0016a108e060240024020042f01f0014101470d004122102c220f450d15200f2016290100370100200f41206a201641206a221d2f01003b0100200f41186a201641186a221a290100370100200f41106a201641106a221c290100370100200f41086a201641086a220a290100370100200441d8016a41106a200441c0016a41106a280200360200200441d8016a41086a200441c0016a41086a290300370300200420042903c0013703d801200441f0016a200441d8016a108e06410121114101210e20042f01f0014101470d01410121114122210c4101210e0240034020044198026a41206a2215201d2f01003b010020044198026a41186a2217201a29010037030020044198026a41106a220d201c29010037030020044198026a41086a2214200a29010037030020042016290100370398020240200e2011470d00201141016a22032011490d172011410174221e2003201e20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7211e0240024020110d00200441003602a0010c010b200441023602a8012004200f3602a0012004201141226c3602a4010b200441386a201e2003200441a0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a2203200429039802370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441f0016a200441d8016a108e0620042f01f0014101460d000c030b0b20030d150c140b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441f0016a41086a200341176a290000370300200441f0016a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f3703f0012003290007212f20032800032129410121030b4102211c200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221d200441f0016a41086a220a290300370300200441d8016a41106a221a200441f0016a41106a221e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a000020044198026a41086a201d29030037030020044198026a41106a201a2d00003a0000200420042f01bc013b0120200420042903d801370398024100210d2029211c202f212c0b200441086a41026a220c200441206a41026a221f2d00003a0000200441c0016a41086a221520044198026a41086a2219290300370300200441c0016a41106a221720044198026a41106a22132d00003a0000200420042f01203b010820042004290398023703c00102400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441a0016a41086a220d2015290300370300200441a0016a41106a221420172d00003a0000200420042f01083b01b801200420042903c0013703a001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d19201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602f0010c010b200441023602f8012004200f3602f0012004201141226c3602f4010b20044198026a20062003200441f0016a107d20042802a00221032004280298024101460d01200428029c02210f200341226e21060b200f201141226c6a2203202c370007200b2d0000211120042f01b801210b2003201c3600032003200b3b0100200341026a20113a0000200320042903a00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000200a2003411f6a290000370300201e200341276a2d00003a0000200420032f00083b01382004200341176a2900003703f0012003410f6a29000021312003410b6a280000212d410121030b4102211c200441bc016a41026a200441386a41026a2d00003a0000201d200a290300370300201a201e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101211102402003450d00201f200441bc016a41026a2d00003a00002019201d2903003703002013201a2d00003a0000200420042f01bc013b0120200420042903d8013703980241002111202d211c2031212e0b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b010820042004290398023703c00120110d07200d2015290300370300201420172d00003a0000200420042f01083b01b801200420042903c0013703a0012004200c2d00003a00ba0120082009470d04200841016a22032008490d18200841017422112003201120034b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7211120080d02200441003602f0010c030b20030d180c170b2000201c36020420004101360200200041086a202c3702000c070b200441043602f801200420073602f00120042008412c6c3602f4010b20044198026a20112003200441f0016a107d20042802a00221032004280298024101460d01200428029c0221072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a202e370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a201c3600002003411b6a20042903a001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201b41346a221b2026470d010c060b0b20030d120c110b2000201c36020420004101360200200041086a202e370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b4100211d4101210c02402030450d00203041346c450d002024102e0b41012102410121164101211b0c010b02402030450d00203041346c450d002024102e0b200128029001212420014194016a28020021300240024020014198016a2802002203450d002024200341386c6a2126200441f0016a410272211620044190016a210520044188016a212b200441e0006a41206a212a200441e0006a41186a2125200441e0006a41106a2128200441e0006a41086a21272024211b02400240024002400340201b2f0134211f201b2802002120201b410c6a2901002110201b41146a2901002118201b411c6a2901002123201b41246a2901002112201b2901042121202b201b412c6a290100370300202a201237030020252023370300202820183703002027201037030020042021370360200441003b015c20044105360220200420053602c4012004200441206a3602d0012004200441046a3602cc012004200441dc006a3602c8012004200441e0006a3602c001200441f0016a200441c0016a108e060240024020042f01f0014101470d004122102c220f450d16200f2016290100370100200f41206a201641206a221d2f01003b0100200f41186a201641186a221a290100370100200f41106a201641106a221c290100370100200f41086a201641086a220a290100370100200441d8016a41106a200441c0016a41106a280200360200200441d8016a41086a200441c0016a41086a290300370300200420042903c0013703d801200441f0016a200441d8016a108e06410121114101210e20042f01f0014101470d01410121114122210c4101210e0240034020044198026a41206a2215201d2f01003b010020044198026a41186a2217201a29010037030020044198026a41106a220d201c29010037030020044198026a41086a2214200a29010037030020042016290100370398020240200e2011470d00201141016a22032011490d182011410174221e2003201e20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7211e0240024020110d00200441003602a0010c010b200441023602a8012004200f3602a0012004201141226c3602a4010b200441386a201e2003200441a0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a2203200429039802370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441f0016a200441d8016a108e0620042f01f0014101460d000c030b0b20030d160c150b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441f0016a41086a200341176a290000370300200441f0016a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f3703f0012003290007212f20032800032129410121030b4102211c200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221d200441f0016a41086a220a290300370300200441d8016a41106a221a200441f0016a41106a221e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a000020044198026a41086a201d29030037030020044198026a41106a201a2d00003a0000200420042f01bc013b0120200420042903d801370398024100210d2029211c202f212c0b200441086a41026a220c200441206a41026a221f2d00003a0000200441c0016a41086a221520044198026a41086a2219290300370300200441c0016a41106a221720044198026a41106a22132d00003a0000200420042f01203b010820042004290398023703c00102400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441a0016a41086a220d2015290300370300200441a0016a41106a221420172d00003a0000200420042f01083b01b801200420042903c0013703a001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d1a201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602f0010c010b200441023602f8012004200f3602f0012004201141226c3602f4010b20044198026a20062003200441f0016a107d20042802a00221032004280298024101460d01200428029c02210f200341226e21060b200f201141226c6a2203202c370007200b2d0000211120042f01b801210b2003201c3600032003200b3b0100200341026a20113a0000200320042903a00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000200a2003411f6a290000370300201e200341276a2d00003a0000200420032f00083b01382004200341176a2900003703f0012003410f6a29000021312003410b6a280000212d410121030b41022111200441bc016a41026a200441386a41026a2d00003a0000201d200a290300370300201a201e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101211c02402003450d00201f200441bc016a41026a2d00003a00002019201d2903003703002013201a2d00003a0000200420042f01bc013b0120200420042903d801370398024100211c202d21112031212e0b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b010820042004290398023703c001201c0d07200d2015290300370300201420172d00003a0000200420042f01083b01b801200420042903c0013703a0012004200c2d00003a00ba0120082009470d04200841016a22032008490d192008410174220c2003200c20034b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7210c20080d02200441003602f0010c030b20030d190c180b2000201c36020420004101360200200041086a202c3702000c070b200441043602f801200420073602f00120042008412c6c3602f4010b20044198026a200c2003200441f0016a107d20042802a00221032004280298024101460d01200428029c0221072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a202e370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a20113600002003411b6a20042903a001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201b41386a221b2026470d010c060b0b20030d130c120b2000201136020420004101360200200041086a202e370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b4100211b4101210c02402030450d00203041386c450d002024102e0b41012102410121160c010b02402030450d00203041386c450d002024102e0b200128029c012130200141a0016a280200213202400240200141a4016a2802002203450d0020302003413c6c6a2124200441f0016a410272211b200441e0006a41346a210520044190016a212b20044188016a212a200441e0006a41206a2125200441e0006a41186a2128200441e0006a41106a2127200441e0006a41086a2129203021160240024002400240034020162f0138211f201628020021202016410c6a2901002110201641146a29010021182016411c6a2901002123201641246a29010021122016412c6a29010021212016290104212c202b201641346a280100360200202a2021370300202520123703002028202337030020272018370300202920103703002004202c370360200441003b015c20044105360220200420053602c4012004200441206a3602d0012004200441046a3602cc012004200441dc006a3602c8012004200441e0006a3602c001200441f0016a200441c0016a108e060240024020042f01f0014101470d004122102c220f450d17200f201b290100370100200f41206a201b41206a221d2f01003b0100200f41186a201b41186a221a290100370100200f41106a201b41106a221c290100370100200f41086a201b41086a220a290100370100200441d8016a41106a200441c0016a41106a280200360200200441d8016a41086a200441c0016a41086a290300370300200420042903c0013703d801200441f0016a200441d8016a108e06410121114101210e20042f01f0014101470d01410121114122210c4101210e0240034020044198026a41206a2215201d2f01003b010020044198026a41186a2217201a29010037030020044198026a41106a220d201c29010037030020044198026a41086a2214200a2901003703002004201b290100370398020240200e2011470d00201141016a22032011490d192011410174221e2003201e20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7211e0240024020110d00200441003602a0010c010b200441023602a8012004200f3602a0012004201141226c3602a4010b200441386a201e2003200441a0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a2203200429039802370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441f0016a200441d8016a108e0620042f01f0014101460d000c030b0b20030d170c160b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441f0016a41086a200341176a290000370300200441f0016a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f3703f001200329000721312003280003212d410121030b4102211c200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221d200441f0016a41086a220a290300370300200441d8016a41106a221a200441f0016a41106a221e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a000020044198026a41086a201d29030037030020044198026a41106a201a2d00003a0000200420042f01bc013b0120200420042903d801370398024100210d202d211c2031212e0b200441086a41026a220c200441206a41026a221f2d00003a0000200441c0016a41086a221520044198026a41086a2219290300370300200441c0016a41106a221720044198026a41106a22132d00003a0000200420042f01203b010820042004290398023703c00102400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441a0016a41086a220d2015290300370300200441a0016a41106a221420172d00003a0000200420042f01083b01b801200420042903c0013703a001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d1b201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602f0010c010b200441023602f8012004200f3602f0012004201141226c3602f4010b20044198026a20062003200441f0016a107d20042802a00221032004280298024101460d01200428029c02210f200341226e21060b200f201141226c6a2203202e370007200b2d0000211120042f01b801210b2003201c3600032003200b3b0100200341026a20113a0000200320042903a00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000200a2003411f6a290000370300201e200341276a2d00003a0000200420032f00083b01382004200341176a2900003703f0012003410f6a29000021332003410b6a2800002126410121030b4102211c200441bc016a41026a200441386a41026a2d00003a0000201d200a290300370300201a201e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101211102402003450d00201f200441bc016a41026a2d00003a00002019201d2903003703002013201a2d00003a0000200420042f01bc013b0120200420042903d80137039802410021112026211c2033212f0b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b010820042004290398023703c00120110d07200d2015290300370300201420172d00003a0000200420042f01083b01b801200420042903c0013703a0012004200c2d00003a00ba0120082009470d04200841016a22032008490d1a200841017422112003201120034b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7211120080d02200441003602f0010c030b20030d1a0c190b2000201c36020420004101360200200041086a202e3702000c070b200441043602f801200420073602f00120042008412c6c3602f4010b20044198026a20112003200441f0016a107d20042802a00221032004280298024101460d01200428029c0221072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a202f370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a201c3600002003411b6a20042903a001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a21082016413c6a22162024470d010c060b0b20030d140c130b2000201c36020420004101360200200041086a202f370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b410021164101210c02402032450d002032413c6c450d002030102e0b410121020c010b02402032450d002032413c6c450d002030102e0b20012802a8012130200141ac016a28020021320240200141b0016a2802002203450d00203020034106746a2124200441f0016a410272211b200441e0006a41386a210520044190016a212b20044188016a212a200441e0006a41206a2125200441e0006a41186a2128200441e0006a41106a2127200441e0006a41086a2129203021160240024002400240034020162f013c211f201628020021202016410c6a2901002110201641146a29010021182016411c6a2901002123201641246a29010021122016412c6a29010021212016290104212c202b201641346a290100370300202a2021370300202520123703002028202337030020272018370300202920103703002004202c370360200441003b015c20044105360220200420053602c4012004200441206a3602d0012004200441046a3602cc012004200441dc006a3602c8012004200441e0006a3602c001200441f0016a200441c0016a108e060240024020042f01f0014101470d004122102c220f450d17200f201b290100370100200f41206a201b41206a221d2f01003b0100200f41186a201b41186a221a290100370100200f41106a201b41106a221c290100370100200f41086a201b41086a220a290100370100200441d8016a41106a200441c0016a41106a280200360200200441d8016a41086a200441c0016a41086a290300370300200420042903c0013703d801200441f0016a200441d8016a108e06410121114101210e20042f01f0014101470d01410121114122210c4101210e0240034020044198026a41206a2215201d2f01003b010020044198026a41186a2217201a29010037030020044198026a41106a220d201c29010037030020044198026a41086a2214200a2901003703002004201b290100370398020240200e2011470d00201141016a22032011490d192011410174221e2003201e20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7211e0240024020110d00200441003602a0010c010b200441023602a8012004200f3602a0012004201141226c3602a4010b200441386a201e2003200441a0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a2203200429039802370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441f0016a200441d8016a108e0620042f01f0014101460d000c030b0b20030d170c160b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441f0016a41086a200341176a290000370300200441f0016a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f3703f001200329000721312003280003212d410121030b4102211c200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221d200441f0016a41086a220a290300370300200441d8016a41106a221a200441f0016a41106a221e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a000020044198026a41086a201d29030037030020044198026a41106a201a2d00003a0000200420042f01bc013b0120200420042903d801370398024100210d202d211c2031212e0b200441086a41026a220c200441206a41026a221f2d00003a0000200441c0016a41086a221520044198026a41086a2219290300370300200441c0016a41106a221720044198026a41106a22132d00003a0000200420042f01203b010820042004290398023703c00102400240024002400240200d0d00200441b8016a41026a2206200c2d00003a0000200441a0016a41086a220d2015290300370300200441a0016a41106a221420172d00003a0000200420042f01083b01b801200420042903c0013703a001024002400240200e2011460d002011210b200e21110c010b201141016a22032011490d1b2011410174220b2003200b20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7210b0240024020110d00200441003602f0010c010b200441023602f8012004200f3602f0012004201141226c3602f4010b20044198026a200b2003200441f0016a107d20042802a00221032004280298024101460d01200428029c02210f200341226e210b0b200f201141226c6a2203202e37000720062d0000211120042f01b80121062003201c360003200320063b0100200341026a20113a0000200320042903a00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000200a2003411f6a290000370300201e200341276a2d00003a0000200420032f00083b01382004200341176a2900003703f0012003410f6a29000021332003410b6a2800002126410121030b41022111200441bc016a41026a200441386a41026a2d00003a0000201d200a290300370300201a201e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101211c02402003450d00201f200441bc016a41026a2d00003a00002019201d2903003703002013201a2d00003a0000200420042f01bc013b0120200420042903d801370398024100211c202621112033212f0b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b010820042004290398023703c001201c0d07200d2015290300370300201420172d00003a0000200420042f01083b01b801200420042903c0013703a0012004200c2d00003a00ba0120082009470d04200841016a22032008490d1a2008410174220c2003200c20034b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7210c20080d02200441003602f0010c030b20030d1a0c190b2000201c36020420004101360200200041086a202e3702000c070b200441043602f801200420073602f00120042008412c6c3602f4010b20044198026a200c2003200441f0016a107d20042802a00221032004280298024101460d01200428029c0221072003412c6e21090b20072008412c6c6a2203200e41016a3602082003200b3602042003200f360200200341136a202f370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a20113600002003411b6a20042903a001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201641c0006a22162024470d010c060b0b20030d140c130b2000201136020420004101360200200041086a202f370200200b21110c010b200042013702000b2011450d00201141226c450d00200f102e0b410021024101210c0240203241ffffff1f710d00410021160c020b2030102e410021160c010b0240203241ffffff1f71450d002030102e0b20012802b4012132200141b8016a2802002134200141bc016a2802002203450d0c2032200341c4006c6a2130200441f0016a410272211b200441e0006a413c6a2105200441e0006a41386a212b20044190016a212a20044188016a2125200441e0006a41206a2128200441e0006a41186a2127200441e0006a41106a2129200441e0006a41086a212d203221160240024002400240034020162f0140211f201628020021202016410c6a2901002110201641146a29010021182016411c6a2901002123201641246a29010021122016412c6a2901002121201641346a290100212c2016290104212e202b2016413c6a280100360200202a202c37030020252021370300202820123703002027202337030020292018370300202d20103703002004202e370360200441003b015c20044105360220200420053602c4012004200441206a3602d0012004200441046a3602cc012004200441dc006a3602c8012004200441e0006a3602c001200441f0016a200441c0016a108e060240024020042f01f0014101470d004122102c220f450d16200f201b290100370100200f41206a201b41206a221d2f01003b0100200f41186a201b41186a221a290100370100200f41106a201b41106a221c290100370100200f41086a201b41086a220a290100370100200441d8016a41106a200441c0016a41106a280200360200200441d8016a41086a200441c0016a41086a290300370300200420042903c0013703d801200441f0016a200441d8016a108e06410121114101210e20042f01f0014101470d01410121114122210c4101210e0240034020044198026a41206a2215201d2f01003b010020044198026a41186a2217201a29010037030020044198026a41106a220d201c29010037030020044198026a41086a2214200a2901003703002004201b290100370398020240200e2011470d00201141016a22032011490d182011410174221e2003201e20034b1b22034104200341044b1bad42227e2210422088a74541017421032010a7211e0240024020110d00200441003602a0010c010b200441023602a8012004200f3602a0012004201141226c3602a4010b200441386a201e2003200441a0016a107d2004280240210320042802384101460d02200428023c210f200341226e21110b200f200c6a2203200429039802370100200341206a20152f01003b0100200341186a2017290300370100200341106a200d290300370100200341086a2014290300370100200c41226a210c200e41016a210e200441f0016a200441d8016a108e0620042f01f0014101460d000c030b0b20030d160c150b410021114102210f4100210e0b0240200428022022034105460d002004290224211002402011450d00201141226c450d00200f102e0b20002003360204200041013602002000410c6a20104220883e0200200041086a20103e02000c050b20042f015c222241ffff03460d024100210302402004280204220c280208201f4d0d00200441386a41026a200c280200201f4105746a220341026a2d00003a0000200441f0016a41086a200341176a290000370300200441f0016a41106a2003411f6a2d00003a0000200420032f00003b01382004200329000f3703f0012003290007213320032800032126410121030b4102211c200441bc016a41026a200441386a41026a2d00003a0000200441d8016a41086a221d200441f0016a41086a220a290300370300200441d8016a41106a221a200441f0016a41106a221e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101210d02402003450d00200441206a41026a200441bc016a41026a2d00003a000020044198026a41086a201d29030037030020044198026a41106a201a2d00003a0000200420042f01bc013b0120200420042903d801370398024100210d2026211c2033212f0b200441086a41026a220c200441206a41026a221f2d00003a0000200441c0016a41086a221520044198026a41086a2219290300370300200441c0016a41106a221720044198026a41106a22132d00003a0000200420042f01203b010820042004290398023703c00102400240024002400240200d0d00200441b8016a41026a220b200c2d00003a0000200441a0016a41086a220d2015290300370300200441a0016a41106a221420172d00003a0000200420042f01083b01b801200420042903c0013703a001024002400240200e2011460d0020112106200e21110c010b201141016a22032011490d1a201141017422062003200620034b1b22034104200341044b1bad42227e2210422088a74541017421032010a721060240024020110d00200441003602f0010c010b200441023602f8012004200f3602f0012004201141226c3602f4010b20044198026a20062003200441f0016a107d20042802a00221032004280298024101460d01200428029c02210f200341226e21060b200f201141226c6a2203202f370007200b2d0000211120042f01b801210b2003201c3600032003200b3b0100200341026a20113a0000200320042903a00137000f200341176a200d2903003700002003411f6a20142d00003a000020032022417f733b0120410021030240200228020820204d0d00200441386a41026a2002280200202041386c6a2203410a6a2d00003a0000200a2003411f6a290000370300201e200341276a2d00003a0000200420032f00083b01382004200341176a2900003703f0012003410f6a29000021352003410b6a2800002124410121030b41022111200441bc016a41026a200441386a41026a2d00003a0000201d200a290300370300201a201e2d00003a0000200420042f01383b01bc01200420042903f0013703d8014101211c02402003450d00201f200441bc016a41026a2d00003a00002019201d2903003703002013201a2d00003a0000200420042f01bc013b0120200420042903d801370398024100211c20242111203521310b200c201f2d00003a000020152019290300370300201720132d00003a0000200420042f01203b010820042004290398023703c001201c0d07200d2015290300370300201420172d00003a0000200420042f01083b01b801200420042903c0013703a0012004200c2d00003a00ba0120082009470d04200841016a22032008490d192008410174220c2003200c20034b1b22034104200341044b1bad422c7e2210422088a74541027421032010a7210c20080d02200441003602f0010c030b20030d190c180b2000201c36020420004101360200200041086a202f3702000c070b200441043602f801200420073602f00120042008412c6c3602f4010b20044198026a200c2003200441f0016a107d20042802a00221032004280298024101460d01200428029c0221072003412c6e21090b20072008412c6c6a2203200e41016a360208200320063602042003200f360200200341136a2031370000200320042f01b8013b010c2003410e6a20042d00ba013a00002003410f6a20113600002003411b6a20042903a001370000200341236a200d2903003700002003412b6a20142d00003a0000200841016a2108201641c4006a22162030470d010c120b0b20030d130c120b2000201136020420004101360200200041086a2031370200200621110c010b200042013702000b2011450d00201141226c450d00200f102e0b4100210c02402034450d00203441c4006c450d002032102e41002102410021160c010b41002102410021160b4100211b0b4100211d0b4100211a0b4100210f0b410021150b4100211c0b4100210a0b410021170b4100210d0b410021140b4100210e4100211e0b02402008450d002008412c6c21112007210303400240200341046a2802002208450d00200841226c450d002003280200102e0b2003412c6a2103201141546a22110d000b0b02402009450d002009412c6c450d002007102e0b0240201e450d00200141106a2802002203450d002003410c6c450d00200128020c102e0b0240200e450d002001411c6a28020041ffffffff0071450d002001280218102e0b02402014450d00200141286a2802002203450d00200341146c450d002001280224102e0b0240200d450d00200141346a2802002203450d00200341186c450d002001280230102e0b02402017450d00200141c0006a2802002203450d002003411c6c450d00200128023c102e0b0240200a450d00200141cc006a28020041ffffff3f71450d002001280248102e0b0240201c450d00200141d8006a2802002203450d00200341246c450d002001280254102e0b02402015450d00200141e4006a2802002203450d00200341286c450d002001280260102e0b0240200f450d00200141f0006a2802002203450d002003412c6c450d00200128026c102e0b0240201a450d00200141fc006a2802002203450d00200341306c450d002001280278102e0b0240201d450d0020014188016a2802002203450d00200341346c450d00200128028401102e0b0240201b450d0020014194016a2802002203450d00200341386c450d00200128029001102e0b02402016450d00200141a0016a2802002203450d002003413c6c450d00200128029c01102e0b02402002450d00200141ac016a28020041ffffff1f71450d0020012802a801102e0b200c450d01200141b8016a2802002203450d01200341c4006c450d0120012802b401102e0c010b02402034450d00203441c4006c450d002032102e0b20002007360204200041003602002000410c6a2008360200200041086a20093602000b200441c0026a24000f0b1038000b1036000be90504077f017e017f027e23004180016b210202400240200128020022032001280204460d00200128021021042001200341046a3602004102210520032f010021062001280208220720072f0100200341026a2f010022076a220341ffff03200341ffff03491b3b0100024002402001410c6a280200280200220128020820064b0d00200241e8006a41106a200241d0006a41106a2d00003a0000200241e8006a41086a200241d0006a41086a29000037030020022002290050370368410121010c010b200241d0006a41086a200128020020064105746a220141176a2203290000370300200241d0006a41106a2001411f6a22082d00003a00002002200129000f370350200129000721092001280003210520012d0002210620012f0000210a200241e8006a41106a20082d000022083a0000200241e8006a41086a2003290000220b3703002002200129000f220c370368200241386a41106a20083a0000200241386a41086a200b3703002002200c370338410021010b200241206a41086a2203200241386a41086a290300370300200241206a41106a2208200241386a41106a2d00003a000020022002290338370320024002402001450d00200220053602682002200937026c200228006921012004410b6a20094238883c0000200441096a20094228883d0000200420094208883e000520042001360001200420053a0000410021030c010b200241e8006a41106a20082d00003a0000200241e8006a41086a200329030037030020022002290320370368410121030b200241d0006a41086a2204200241e8006a41086a290300370300200241d0006a41106a2208200241e8006a41106a2d00003a000020022002290368370350410021012003450d012000200a3b010220002002290350370011200041096a2009370000200041056a2005360000200041046a20063a0000200041226a20073b0100200041196a2004290300370000200041216a20082d00003a0000200041013b01000f0b410021010b200020013b01000bc10201037f230041106b2202240002404120102c2203450d0020024220370204200220033602002002200041106a412010742001200228020022032002280208107402402002280204450d002003102e0b200020011091024120102c2203450d0020024220370204200220033602002002200041306a412010742001200228020022032002280208107402402002280204450d002003102e0b4120102c2203450d0020024220370204200220033602002002200041d0006a412010742001200228020022032002280208107402402002280204450d002003102e0b200028020421032000410c6a2802002200200110760240200041246c2200450d0003402002200310ef042001200228020022042002280208107402402002280204450d002004102e0b200341246a21032000415c6a22000d000b0b200241106a24000f0b1036000bae0401047f230041106b22022400200220002903003703002001200241081074200041106a210302400240024020002903084201510d00200241003a000020012002410110742002200029031037030020012002410810742001200041e0016a412010744120102c2204450d02200242203702042002200436020020022003410c6a412010742001200228020022042002280208107402402002280204450d002004102e0b2002200041186a280200360200200120024104107420012003412c6a41c00010744120102c2204450d02200041a0016a21052002422037020420022004360200200220004180016a412010742001200228020022002002280208107402402002280204450d002000102e0b2002200328026c36020020012002410410742001200541c00010740c010b200241013a000020012002410110742002200029031037030020012002410810742001200041e0016a412010744120102c2204450d01200242203702042002200436020020022003410c6a412010742001200228020022042002280208107402402002280204450d002004102e0b2002200041186a280200360200200120024104107420012003412c6a41c00010744120102c2204450d01200041a0016a21052002422037020420022004360200200220004180016a412010742001200228020022002002280208107402402002280204450d002000102e0b2002200328026c36020020012002410410742001200541c00010740b200241106a24000f0b1036000b84660b087f017e107f037e047f017e047f017e047f017e027f230041206b22022400200041003602082000420137020002402001280208220341ffffffff01712003470d0020034103742204417f4c0d002001280200210502400240024020040d00410421060c010b2004102c2206450d010b0240024002402004410376220720034f0d00200441027622082003200820034b1b22084104200841044b1b220841ffffffff01712008464102742109200841037421080240024020040d00200241003602100c010b200241186a410436020020022004360214200220063602100b200220082009200241106a107d200241086a2802002108024020022802004101460d0020022802042106200841037621070c020b20080d030c040b20030d00410021050c010b200520046a2108200341037441786a410376210920062103034020052802002104200341046a200541046a2f01003b010020032004360200200341086a2103200541086a22052008470d000b200941016a21050b20052000107602402005450d00200620054103746a210420062105034002400240024002402005280200220341c000490d00200341808001490d012003418080808004490d02200241033a00102000200241106a41011074200220033602102000200241106a410410740c030b200220034102743a00102000200241106a410110740c020b200220034102744101723b01102000200241106a410210740c010b200220034102744102723602102000200241106a410410740b024002400240200541046a2f0100220341c000490d00200341808001490d01200220034102744102723602102000200241106a410410740c020b200220034102743a00102000200241106a410110740c010b200220034102744101723b01102000200241106a410210740b200541086a22052004470d000b0b200141146a2802002203ad420c7e220a422088a70d01200aa72204417f4c0d01200128020c21050240024020040d004104210b0c010b2004102c220b450d010b0240024002402004410c6e220c20034f0d00200c41017422082003200820034b1b22084104200841044b1bad420c7e220a422088a7454102742108200aa72109024002402004410b4b0d00200241003602100c010b200241186a41043602002002200b3602102002200c410c6c3602140b200220092008200241106a107d200241086a2802002104024020022802004101460d002002280204210b2004410c6e210c0c020b2004450d040c030b20030d00410021050c010b20052003410c6c6a21042003410c6c41746a410c6e2108200b2103034020032005290200370200200341086a200541086a2f01003b01002003410c6a21032005410c6a22052004470d000b200841016a21050b20052000107602402005450d002005410c6c2104200b21050340200541046a210802400240024002402005280200220341c000490d00200341808001490d012003418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220034102743a00102000200241106a410110740c020b200220034102744101723b01102000200241106a410210740c010b200220034102744102723602102000200241106a410410740b2008200010fd04024002400240200541086a2f0100220341c000490d00200341808001490d01200220034102744102723602102000200241106a410410740c020b200220034102743a00102000200241106a410110740c010b200220034102744101723b01102000200241106a410210740b2005410c6a2105200441746a22040d000b0b200141206a280200220341ffffffff00712003470d0120034104742204417f4c0d01200128021821054104210d02402004450d002004102c220d450d010b0240024002402004410476220e20034f0d00200441037622082003200820034b1b22084104200841044b1b220841ffffffff00712008464102742109200841047421080240024020040d00200241003602100c010b200241186a4104360200200220043602142002200d3602100b200220082009200241106a107d200241086a2802002108024020022802004101460d002002280204210d2008410476210e0c020b2008450d040c030b20030d00410021050c010b200520046a2104200341047441706a4104762108200d21030340200320052802003602002003410c6a2005410c6a2f01003b0100200341046a200541046a290200370200200341106a2103200541106a22052004470d000b200841016a21050b20052000107602402005450d0020054104742104200d2105034002400240024002402005280200220341c000490d00200341808001490d012003418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220034102743a00102000200241106a410110740c020b200220034102744101723b01102000200241106a410210740c010b200220034102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd040240024002402005410c6a2f0100220341c000490d00200341808001490d01200220034102744102723602102000200241106a410410740c020b200220034102743a00102000200241106a410110740c010b200220034102744101723b01102000200241106a410210740b200541106a2105200441706a22040d000b0b2001412c6a2802002203ad42147e220a422088a70d01200aa72204417f4c0d01200128022421050240024020040d004104210f0c010b2004102c220f450d010b024002400240200441146e221020034f0d00201041017422082003200820034b1b22084104200841044b1bad42147e220a422088a7454102742108200aa7210902400240200441134b0d00200241003602100c010b200241186a41043602002002200f3602102002201041146c3602140b200220092008200241106a107d200241086a2802002104024020022802004101460d002002280204210f200441146e21100c020b2004450d040c030b20030d00410021050c010b2005200341146c6a2104200341146c416c6a41146e2108200f2103034020032005280200360200200341106a200541106a2f01003b01002003410c6a2005410c6a280200360200200341046a200541046a290200370200200341146a2103200541146a22052004470d000b200841016a21050b20052000107602402005450d00200541146c2104200f2105034002400240024002402005280200220341c000490d00200341808001490d012003418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220034102743a00102000200241106a410110740c020b200220034102744101723b01102000200241106a410210740c010b200220034102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04024002400240200541106a2f0100220341c000490d00200341808001490d01200220034102744102723602102000200241106a410410740c020b200220034102743a00102000200241106a410110740c010b200220034102744101723b01102000200241106a410210740b200541146a21052004416c6a22040d000b0b200141386a2802002203ad42187e220a422088a70d01200aa72204417f4c0d01200128023021050240024020040d00410421110c010b2004102c2211450d010b024002400240200441186e221220034f0d00201241017422082003200820034b1b22084104200841044b1bad42187e220a422088a7454102742108200aa7210902400240200441174b0d00200241003602100c010b200241186a4104360200200220113602102002201241186c3602140b200220092008200241106a107d200241086a2802002104024020022802004101460d0020022802042111200441186e21120c020b2004450d040c030b20030d00410021050c010b2005200341186c6a2104200341186c41686a41186e210820112103034020032005280200360200200341146a200541146a2f01003b01002003410c6a2005410c6a290200370200200341046a200541046a290200370200200341186a2103200541186a22052004470d000b200841016a21050b20052000107602402005450d00200541186c21084100210303400240024002400240201120036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04024002400240200541146a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b2008200341186a2203470d000b0b200141c4006a2802002203ad421c7e220a422088a70d01200aa72204417f4c0d01200128023c21050240024020040d00410421130c010b2004102c2213450d010b0240024002402004411c6e221420034f0d00201441017422082003200820034b1b22084104200841044b1bad421c7e220a422088a7454102742108200aa72109024002402004411b4b0d00200241003602100c010b200241186a41043602002002201336021020022014411c6c3602140b200220092008200241106a107d200241086a2802002104024020022802004101460d00200228020421132004411c6e21140c020b2004450d040c030b20030d00410021050c010b20052003411c6c6a21042003411c6c41646a411c6e210820132103034020032005280200360200200341186a200541186a2f01003b0100200341146a200541146a2802003602002003410c6a2005410c6a290200370200200341046a200541046a2902003702002003411c6a21032005411c6a22052004470d000b200841016a21050b20052000107602402005450d002005411c6c21084100210303400240024002400240201320036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04200541146a200010fd04024002400240200541186a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b20082003411c6a2203470d000b0b200141d0006a280200220341ffffff3f712003470d0120034105742204417f4c0d01200128024821050240024020040d00410421150c010b2004102c2215450d010b0240024002402004410576221620034f0d00200441047622082003200820034b1b22084104200841044b1b220841ffffff3f712008464102742109200841057421080240024020040d00200241003602100c010b200241186a410436020020022004360214200220153602100b200220082009200241106a107d200241086a2802002108024020022802004101460d0020022802042115200841057621160c020b2008450d040c030b20030d00410021050c010b200520046a2104200341057441606a4105762108201521030340200320052802003602002003411c6a2005411c6a2f01003b0100200341146a200541146a2902003702002003410c6a2005410c6a290200370200200341046a200541046a290200370200200341206a2103200541206a22052004470d000b200841016a21050b20052000107602402005450d00200541057421084100210303400240024002400240201520036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04200541146a200010fd04200541186a200010fd040240024002402005411c6a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b2008200341206a2203470d000b0b200141dc006a2802002203ad42247e220a422088a70d01200aa72204417f4c0d01200128025421050240024020040d00410421170c010b2004102c2217450d010b024002400240200441246e221820034f0d00201841017422082003200820034b1b22084104200841044b1bad42247e220a422088a7454102742108200aa7210902400240200441234b0d00200241003602100c010b200241186a4104360200200220173602102002201841246c3602140b200220092008200241106a107d200241086a2802002104024020022802004101460d0020022802042117200441246e21180c020b2004450d040c030b20030d00410021050c010b2005200341246c6a2104200341246c415c6a41246e210820172103034020032005280200360200200341206a200541206a2f01003b01002003411c6a2005411c6a280200360200200341146a200541146a2902003702002003410c6a2005410c6a290200370200200341046a200541046a290200370200200341246a2103200541246a22052004470d000b200841016a21050b20052000107602402005450d00200541246c21084100210303400240024002400240201720036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04200541146a200010fd04200541186a200010fd042005411c6a200010fd04024002400240200541206a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b2008200341246a2203470d000b0b200141e8006a2802002203ad42287e220a422088a70d01200aa72204417f4c0d01200128026021050240024020040d00410421190c010b2004102c2219450d010b024002400240200441286e221a20034f0d00201a41017422082003200820034b1b22084104200841044b1bad42287e220a422088a7454102742108200aa7210902400240200441274b0d00200241003602100c010b200241186a4104360200200220193602102002201a41286c3602140b200220092008200241106a107d200241086a2802002104024020022802004101460d0020022802042119200441286e211a0c020b2004450d040c030b20030d00410021050c010b2005200341286c6a2104200341286c41586a41286e2108201921030340200541046a290200210a2005410c6a290200211b200541146a290200211c2005411c6a290200211d20032005280200360200200341246a200541246a2f01003b01002003411c6a201d370200200341146a201c3702002003410c6a201b370200200341046a200a370200200341286a2103200541286a22052004470d000b200841016a21050b20052000107602402005450d00200541286c21084100210303400240024002400240201920036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04200541146a200010fd04200541186a200010fd042005411c6a200010fd04200541206a200010fd04024002400240200541246a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b2008200341286a2203470d000b0b200141f4006a2802002203ad422c7e220a422088a70d01200aa72204417f4c0d01200128026c21050240024020040d004104211e0c010b2004102c221e450d010b0240024002402004412c6e221f20034f0d00201f41017422082003200820034b1b22084104200841044b1bad422c7e220a422088a7454102742108200aa72109024002402004412b4b0d00200241003602100c010b200241186a41043602002002201e3602102002201f412c6c3602140b200220092008200241106a107d200241086a2802002104024020022802004101460d002002280204211e2004412c6e211f0c020b2004450d040c030b20030d00410021050c010b20052003412c6c6a21082003412c6c41546a412c6e2109201e21030340200541046a290200210a2005410c6a290200211b200541146a290200211c2005411c6a290200211d200541246a280200210420032005280200360200200341286a200541286a2f01003b0100200341246a20043602002003411c6a201d370200200341146a201c3702002003410c6a201b370200200341046a200a3702002003412c6a21032005412c6a22052008470d000b200941016a21050b20052000107602402005450d002005412c6c21084100210303400240024002400240201e20036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04200541146a200010fd04200541186a200010fd042005411c6a200010fd04200541206a200010fd04200541246a200010fd04024002400240200541286a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b20082003412c6a2203470d000b0b20014180016a2802002203ad42307e220a422088a70d01200aa72204417f4c0d01200128027821050240024020040d00410421200c010b2004102c2220450d010b024002400240200441306e222120034f0d00202141017422082003200820034b1b22084104200841044b1bad42307e220a422088a7454102742108200aa72109024002402004412f4b0d00200241003602100c010b200241186a4104360200200220203602102002202141306c3602140b200220092008200241106a107d200241086a2802002104024020022802004101460d0020022802042120200441306e21210c020b2004450d040c030b20030d00410021050c010b2005200341306c6a2108200341306c41506a41306e2109202021030340200541046a290200210a2005410c6a290200211b200541146a290200211c2005411c6a290200211d200541246a2902002122200528020021042003412c6a2005412c6a2f01003b0100200341246a20223702002003411c6a201d370200200341146a201c3702002003410c6a201b370200200341046a200a37020020032004360200200341306a2103200541306a22052008470d000b200941016a21050b20052000107602402005450d00200541306c21084100210303400240024002400240202020036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04200541146a200010fd04200541186a200010fd042005411c6a200010fd04200541206a200010fd04200541246a200010fd04200541286a200010fd040240024002402005412c6a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b2008200341306a2203470d000b0b2001418c016a2802002203ad42347e220a422088a70d01200aa72204417f4c0d0120012802840121050240024020040d00410421230c010b2004102c2223450d010b024002400240200441346e222420034f0d00202441017422082003200820034b1b22084104200841044b1bad42347e220a422088a7454102742108200aa7210902400240200441334b0d00200241003602100c010b200241186a4104360200200220233602102002202441346c3602140b200220092008200241106a107d200241086a2802002104024020022802004101460d0020022802042123200441346e21240c020b2004450d040c030b20030d00410021050c010b2005200341346c6a2109200341346c414c6a41346e2125202321030340200541046a290200210a2005410c6a290200211b200541146a290200211c2005411c6a290200211d200541246a29020021222005412c6a280200210420052802002108200341306a200541306a2f01003b01002003412c6a2004360200200341246a20223702002003411c6a201d370200200341146a201c3702002003410c6a201b370200200341046a200a37020020032008360200200341346a2103200541346a22052009470d000b202541016a21050b20052000107602402005450d00200541346c21084100210303400240024002400240202320036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04200541146a200010fd04200541186a200010fd042005411c6a200010fd04200541206a200010fd04200541246a200010fd04200541286a200010fd042005412c6a200010fd04024002400240200541306a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b2008200341346a2203470d000b0b20014198016a2802002203ad42387e220a422088a70d01200aa72204417f4c0d0120012802900121050240024020040d00410421250c010b2004102c2225450d010b024002400240200441386e222620034f0d00202641017422082003200820034b1b22084104200841044b1bad42387e220a422088a7454102742108200aa7210902400240200441374b0d00200241003602100c010b200241186a4104360200200220253602102002202641386c3602140b200220092008200241106a107d200241086a2802002104024020022802004101460d0020022802042125200441386e21260c020b2004450d040c030b20030d00410021050c010b2005200341386c6a2108200341386c41486a41386e2109202521030340200541046a290200210a2005410c6a290200211b200541146a290200211c2005411c6a290200211d200541246a29020021222005412c6a290200212720052802002104200341346a200541346a2f01003b01002003412c6a2027370200200341246a20223702002003411c6a201d370200200341146a201c3702002003410c6a201b370200200341046a200a37020020032004360200200341386a2103200541386a22052008470d000b200941016a21050b20052000107602402005450d00200541386c21084100210303400240024002400240202520036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04200541146a200010fd04200541186a200010fd042005411c6a200010fd04200541206a200010fd04200541246a200010fd04200541286a200010fd042005412c6a200010fd04200541306a200010fd04024002400240200541346a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b2008200341386a2203470d000b0b200141a4016a2802002203ad423c7e220a422088a70d01200aa72204417f4c0d01200128029c0121050240024020040d00410421280c010b2004102c2228450d010b0240024002402004413c6e222920034f0d00202941017422082003200820034b1b22084104200841044b1bad423c7e220a422088a7454102742108200aa72109024002402004413b4b0d00200241003602100c010b200241186a41043602002002202836021020022029413c6c3602140b200220092008200241106a107d200241086a2802002104024020022802004101460d00200228020421282004413c6e21290c020b2004450d040c030b20030d00410021050c010b20052003413c6c6a21092003413c6c41446a413c6e212a202821030340200541046a290200210a2005410c6a290200211b200541146a290200211c2005411c6a290200211d200541246a29020021222005412c6a2902002127200541346a280200210420052802002108200341386a200541386a2f01003b0100200341346a20043602002003412c6a2027370200200341246a20223702002003411c6a201d370200200341146a201c3702002003410c6a201b370200200341046a200a370200200320083602002003413c6a21032005413c6a22052009470d000b202a41016a21050b20052000107602402005450d002005413c6c21084100210303400240024002400240202820036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04200541146a200010fd04200541186a200010fd042005411c6a200010fd04200541206a200010fd04200541246a200010fd04200541286a200010fd042005412c6a200010fd04200541306a200010fd04200541346a200010fd04024002400240200541386a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b20082003413c6a2203470d000b0b200141b0016a280200220341ffffff1f712003470d0120034106742204417f4c0d0120012802a80121050240024020040d00410421090c010b2004102c2209450d010b0240024002402004410676222b20034f0d00200441057622082003200820034b1b22084104200841044b1b220841ffffff1f71200846410274212a200841067421080240024020040d00200241003602100c010b200241186a410436020020022004360214200220093602100b20022008202a200241106a107d200241086a2802002108024020022802004101460d00200228020421092008410676212b0c020b2008450d040c030b20030d00410021050c010b200520046a2108200341067441406a410676212a200921030340200541046a290200210a2005410c6a290200211b200541146a290200211c2005411c6a290200211d200541246a29020021222005412c6a2902002127200541346a290200212c200528020021042003413c6a2005413c6a2f01003b0100200341346a202c3702002003412c6a2027370200200341246a20223702002003411c6a201d370200200341146a201c3702002003410c6a201b370200200341046a200a37020020032004360200200341c0006a2103200541c0006a22052008470d000b202a41016a21050b20052000107602402005450d00200541067421084100210303400240024002400240200920036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04200541146a200010fd04200541186a200010fd042005411c6a200010fd04200541206a200010fd04200541246a200010fd04200541286a200010fd042005412c6a200010fd04200541306a200010fd04200541346a200010fd04200541386a200010fd040240024002402005413c6a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b2008200341c0006a2203470d000b0b200141bc016a2802002203ad42c4007e220a422088a70d01200aa72204417f4c0d0120012802b40121050240024020040d004104212a0c010b2004102c222a450d010b024002400240200441c4006e222d20034f0d00202d41017422082003200820034b1b22084104200841044b1bad42c4007e220a422088a7454102742108200aa7210102400240200441c3004b0d00200241003602100c010b200241186a41043602002002202a3602102002202d41c4006c3602140b200220012008200241106a107d200241086a2802002104024020022802004101460d002002280204212a200441c4006e212d0c020b2004450d040c030b20030d00410021050c010b2005200341c4006c6a2101200341c4006c41bc7f6a41c4006e212e202a21030340200541046a290200210a2005410c6a290200211b200541146a290200211c2005411c6a290200211d200541246a29020021222005412c6a2902002127200541346a290200212c2005413c6a280200210420052802002108200341c0006a200541c0006a2f01003b01002003413c6a2004360200200341346a202c3702002003412c6a2027370200200341246a20223702002003411c6a201d370200200341146a201c3702002003410c6a201b370200200341046a200a37020020032008360200200341c4006a2103200541c4006a22052001470d000b202e41016a21050b20052000107602402005450d00200541c4006c21084100210303400240024002400240202a20036a2205280200220441c000490d00200441808001490d012004418080808004490d02200241033a00102000200241106a41011074200220052802003602102000200241106a410410740c030b200220044102743a00102000200241106a410110740c020b200220044102744101723b01102000200241106a410210740c010b200220044102744102723602102000200241106a410410740b200541046a200010fd04200541086a200010fd042005410c6a200010fd04200541106a200010fd04200541146a200010fd04200541186a200010fd042005411c6a200010fd04200541206a200010fd04200541246a200010fd04200541286a200010fd042005412c6a200010fd04200541306a200010fd04200541346a200010fd04200541386a200010fd042005413c6a200010fd04024002400240200541c0006a2f0100220541c000490d00200541808001490d01200220054102744102723602102000200241106a410410740c020b200220054102743a00102000200241106a410110740c010b200220054102744101723b01102000200241106a410210740b2008200341c4006a2203470d000b0b0240202d450d00202d41c4006c450d00202a102e0b0240202b450d002009102e0b02402029450d002029413c6c450d002028102e0b02402026450d00202641386c450d002025102e0b02402024450d00202441346c450d002023102e0b02402021450d00202141306c450d002020102e0b0240201f450d00201f412c6c450d00201e102e0b0240201a450d00201a41286c450d002019102e0b02402018450d00201841246c450d002017102e0b02402016450d002015102e0b02402014450d002014411c6c450d002013102e0b02402012450d00201241186c450d002011102e0b02402010450d00201041146c450d00200f102e0b0240200e450d00200d102e0b0240200c450d00200c410c6c450d00200b102e0b02402007450d002006102e0b200241206a24000f0b1036000b1038000b040041010b040041010b040041010bf5be010f057f017e017f017e077f017e147f017e027f017e047f017e077f017e0e7f230041c0196b22022400200241f8116a200110ad0102400240024002400240024020022802f8110d0020022802fc11220320012802002802044103762204200420034b1b22044103742205417f4c0d050240024020040d00410421050c010b2005102c2205450d050b2001200128020441016a22063602042004ad21070240200620012802084b0d00024002402003450d000340200241f0116a200110ad0120022802f0110d0320022802f4112106200241e8116a200110fb0420022f01e8110d0320022f01ea112108024020074220882209a722042007a7470d00200441016a220a2004490d0a2004410174220b200a200a200b491b220a4104200a41044b1b220a41ffffffff0171200a46410274210b200a410374210a0240024020040d0020024100360280180c010b20024104360288182002200536028018200220094203863e0284180b200241c0186a200a200b20024180186a107d20022802c818210a20022802c0184101460d0320022802c418210520074220882209a72104200a410376ad21070b200520044103746a220420083b0104200420063602002009422086200742ffffffff0f83844280808080107c21072003417f6a22030d000b200128020421060b20012006417f6a3602042005450d022007422088a741037422040d03200521040c040b200a0d050c060b200742ffffffff0183500d002005102e0b200041003602000c020b200520046a21032005210403402004200429020022093e0200200441046a20094220883d0100200441086a22042003470d000b0b2007a7210a200241e0116a200110ad01024002400240024020022802e0110d0020022802e41122062001280200280204410c6e2203200320064b1bad420c7e2207422088a70d062007a72203417f4c0d060240024020030d00410421080c010b2003102c2208450d060b2001200128020441016a220b3602042003410c6ead21070240200b20012802084b0d00024002402006450d000340200241d8116a200110ad0120022802d8110d0320022802dc11210b200241d0116a200110fb0420022f01d0110d0320022f01d211210c200241c8116a200110fb0420022f01c8110d0320022f01ca11210d200241c0116a200110fb0420022f01c0110d0320022f01c211210e024020074220882209a722032007a7470d00200341016a220f2003490d0b20034101742210200f200f2010491b220f4104200f41044b1bad420c7e2209422088a745410274210f2009a721100240024020030d0020024100360280180c010b2002410436028818200220083602801820022003410c6c360284180b200241c0186a2010200f20024180186a107d20022802c818210f20022802c0184101460d0320022802c418210820074220882209a72103200f410c6ead21070b20082003410c6c6a2203200e3b01082003200c3b01042003200b360200200341066a200d3b01002009422086200742ffffffff0f83844280808080107c21072006417f6a22060d000b2001280204210b0b2001200b417f6a3602042008450d022007422088a7410c6c22030d03200821030c040b200f450d070c060b2007a72204450d002004410c6c450d002008102e0b200041003602000c020b200820036a21062008210303402003410c6a22032006470d000b0b2007a72106200241b8116a200110ad01200320086b410c6d210f0240024020022802b8110d004104210c20022802bc11220b200128020028020441047622032003200b4b1b2203410474220d417f4c0d0502402003450d00200d102c220c450d050b2001200128020441016a220d3602042003ad21070240200d20012802084b0d0002400240024002400240200b450d000340200241b0116a200110ad0120022802b0110d0620022802b411210e200241003a008818200241a8116a200110fb0420022f01a8110d0620022f01aa112103200241a0116a200110fb0420022f01a0110d0620022f01a211210d200241013a0088182002200d3b018218200220033b01801820024198116a200110fb0420022f0198110d0520022f019a11210320024190116a200110fb0420022f0190110d05200220022f0192113b018618200220033b018418200229038018210920024188116a200110fb0420022f0188110d0620022f018a112110024020074220882211a722032007a7470d00200341016a220d2003490d0d20034101742212200d200d2012491b220d4104200d41044b1b220d41ffffffff0071200d464102742112200d410474210d0240024020030d0020024100360280180c010b20024104360288182002200c36028018200220114204863e0284180b200241c0186a200d201220024180186a107d20022802c818210d20022802c0184101460d0320022802c418210c200d410476ad21070b200c20034104746a220d20103b010c200d2009370204200d200e360200200742ffffffff0f83200341016aad422086842107200b417f6a220b0d000b2001280204210d0b2001200d417f6a360204200c450d052007422088a741047422030d01200c21030c020b200d450d090c080b200c20036a210b200c21030340200341106a2203200b470d000b0b2007a7210d20024180116a200110ad01024002402002280280110d00200228028411220e200128020028020441146e220b200b200e4b1bad42147e2207422088a70d092007a7220b417f4c0d0902400240200b0d00410421120c010b200b102c2212450d090b2001200128020441016a2210360204200b41146ead21070240201020012802084b0d0002400240024002400240200e450d00200241c0186a41086a21130340200241f8106a200110ad0120022802f8100d0620022802fc102114200241003a008c18200241f0106a200110fb0420022f01f0100d0620022f01f210210b200241e8106a200110fb0420022f01e8100d0620022f01ea102110200241013a008c18200220103b0182182002200b3b018018200241e0106a200110fb0420022f01e0100d0520022f01e210210b200241d8106a200110fb0420022f01d8100d0520022f01da102110200241023a008c18200220103b0186182002200b3b018418200241d0106a200110fb0420022f01d0100d0520022f01d210210b200241c8106a200110fb0420022f01c8100d05200220022f01ca103b018a182002200b3b018818201320022802881836020020022002290380183703c018200241c0106a200110fb0420022f01c0100d0620022f01c210211520024180176a41086a2013280200220b360200200241c0166a41086a2216200b360200200220022903c018220937038017200220093703c01602402007422088a7220b2007a7470d00200b41016a2210200b490d11200b4101742217201020102017491b22104104201041044b1bad42147e2207422088a74541027421102007a7211702400240200b0d0020024100360280180c010b200241043602881820022012360280182002200b41146c360284180b200241c0186a2017201020024180186a107d20022802c818211020022802c0184101460d0320022802c4182112201041146ead21070b2012200b41146c6a22102014360200201020022903c0163702042010410c6a2016280200360200201020153b0110200742ffffffff0f83200b41016aad422086842107200e417f6a220e0d000b200128020421100b20012010417f6a3602042012450d052007422088a741146c220b0d012012210b0c020b2010450d0d0c0c0b2012200b6a210e2012210b0340200b41146a220b200e470d000b0b2007a7210e200241b8106a200110ad01200b20126b41146d21150240024020022802b8100d0020022802bc102210200128020028020441186e220b200b20104b1bad42187e2207422088a70d0d2007a7220b417f4c0d0d02400240200b0d00410421130c010b200b102c2213450d0d0b2001200128020441016a2214360204200b41186ead21070240201420012802084b0d00024002400240024002402010450d000340200241b0106a200110ad0120022802b0100d0620022802b4102116200241003a009018200241a8106a200110fb0420022f01a8100d0620022f01aa10210b200241a0106a200110fb0420022f01a0100d0620022f01a2102114200241013a009018200220143b0182182002200b3b01801820024198106a200110fb0420022f0198100d0520022f019a10210b20024190106a200110fb0420022f0190100d0520022f0192102114200241023a009018200220143b0186182002200b3b01841820024188106a200110fb0420022f0188100d0520022f018a10210b20024180106a200110fb0420022f0180100d0520022f0182102114200241033a009018200220143b018a182002200b3b018818200241f80f6a200110fb0420022f01f80f0d0520022f01fa0f210b200241f00f6a200110fb0420022f01f00f0d05200220022f01f20f3b018e182002200b3b018c18200241c0186a41086a220b20024180186a41086a29030037030020022002290380183703c018200241e80f6a200110fb0420022f01e80f0d0620022f01ea0f211720024180176a41086a200b2903002209370300200241c0166a41086a22182009370300200220022903c018220937038017200220093703c01602402007422088a7220b2007a7470d00200b41016a2214200b490d15200b4101742219201420142019491b22144104201441044b1bad42187e2207422088a74541027421142007a7211902400240200b0d0020024100360280180c010b200241043602881820022013360280182002200b41186c360284180b200241c0186a2019201420024180186a107d20022802c818211420022802c0184101460d0320022802c4182113201441186ead21070b2013200b41186c6a22142016360200201420022903c0163702042014410c6a2018290300370200201420173b0114200742ffffffff0f83200b41016aad4220868421072010417f6a22100d000b200128020421140b20012014417f6a3602042013450d052007422088a741186c220b0d012013210b0c020b2014450d110c100b2013200b6a21102013210b0340200b41186a220b2010470d000b0b2007a72110200241e00f6a200110ad01200b20136b41186d21180240024020022802e00f0d0020022802e40f220b2001280200280204411c6e22142014200b4b1bad421c7e2207422088a70d112007a72214417f4c0d110240024020140d00410421170c010b2014102c2217450d110b2001200128020441016a22163602042014411c6ead21070240201620012802084b0d0002400240024002400240200b450d00200241c0186a41106a21190340200241d80f6a200110ad0120022802d80f0d0620022802dc0f211a200241003a009418200241d00f6a200110fb0420022f01d00f0d0620022f01d20f2114200241c80f6a200110fb0420022f01c80f0d0620022f01ca0f2116200241013a009418200220163b018218200220143b018018200241c00f6a200110fb0420022f01c00f0d0520022f01c20f2114200241b80f6a200110fb0420022f01b80f0d0520022f01ba0f2116200241023a009418200220163b018618200220143b018418200241b00f6a200110fb0420022f01b00f0d0520022f01b20f2114200241a80f6a200110fb0420022f01a80f0d0520022f01aa0f2116200241033a009418200220163b018a18200220143b018818200241a00f6a200110fb0420022f01a00f0d0520022f01a20f2114200241980f6a200110fb0420022f01980f0d0520022f019a0f2116200241043a009418200220163b018e18200220143b018c18200241900f6a200110fb0420022f01900f0d0520022f01920f2114200241880f6a200110fb0420022f01880f0d0520022f018a0f2116200241c0186a41086a221b20024180186a41086a290300370300200220163b019218200220143b0190182019200228029018360200200241053a00941820022002290380183703c018200241800f6a200110fb0420022f01800f0d0620022f01820f211c20024180176a41086a201b290300220937030020024180176a41106a20192802002214360200200241c0166a41086a221b2009370300200241c0166a41106a221d2014360200200220022903c018220937038017200220093703c01602402007422088a722142007a7470d00201441016a22162014490d192014410174221e20162016201e491b22164104201641044b1bad421c7e2207422088a74541027421162007a7211e0240024020140d0020024100360280180c010b2002410436028818200220173602801820022014411c6c360284180b200241c0186a201e201620024180186a107d20022802c818211620022802c0184101460d0320022802c41821172016411c6ead21070b20172014411c6c6a2216201a360200201620022903c0163702042016410c6a201b290300370200201641146a201d2802003602002016201c3b0118200742ffffffff0f83201441016aad422086842107200b417f6a220b0d000b200128020421160b20012016417f6a3602042017450d052007422088a7411c6c220b0d012017210b0c020b2016450d150c140b2017200b6a21142017210b0340200b411c6a220b2014470d000b0b2007a72114200241f80e6a200110ad01200b20176b411c6d211a0240024020022802f80e0d0020022802fc0e220b200128020028020441057622162016200b4b1b22164105742219417f4c0d150240024020160d00410421190c010b2019102c2219450d150b2001200128020441016a221b3602042016ad21070240201b20012802084b0d0002400240024002400240200b450d000340200241f00e6a200110ad0120022802f00e0d0620022802f40e211c200241003a009818200241e80e6a200110fb0420022f01e80e0d0620022f01ea0e2116200241e00e6a200110fb0420022f01e00e0d0620022f01e20e211b200241013a0098182002201b3b018218200220163b018018200241d80e6a200110fb0420022f01d80e0d0520022f01da0e2116200241d00e6a200110fb0420022f01d00e0d0520022f01d20e211b200241023a0098182002201b3b018618200220163b018418200241c80e6a200110fb0420022f01c80e0d0520022f01ca0e2116200241c00e6a200110fb0420022f01c00e0d0520022f01c20e211b200241033a0098182002201b3b018a18200220163b018818200241b80e6a200110fb0420022f01b80e0d0520022f01ba0e2116200241b00e6a200110fb0420022f01b00e0d0520022f01b20e211b200241043a0098182002201b3b018e18200220163b018c18200241a80e6a200110fb0420022f01a80e0d0520022f01aa0e2116200241a00e6a200110fb0420022f01a00e0d0520022f01a20e211b200241053a0098182002201b3b019218200220163b019018200241980e6a200110fb0420022f01980e0d0520022f019a0e2116200241900e6a200110fb0420022f01900e0d0520022f01920e211b200241c0186a41086a221d20024180186a41086a2903003703002002201b3b019618200220163b019418200241c0186a41106a221620024180186a41106a290300370300200241063a00981820022002290380183703c018200241880e6a200110fb0420022f01880e0d0620022f018a0e211e20024180176a41086a201d290300220937030020024180176a41106a20162903002211370300200241c0166a41086a221d2009370300200241c0166a41106a221f2011370300200220022903c018220937038017200220093703c016024020074220882209a7221b2007a7470d00201b41016a2216201b490d1d201b4101742220201620162020491b22164104201641044b1b221641ffffff3f7120164641027421202016410574211602400240201b0d0020024100360280180c010b20024104360288182002201936028018200220094205863e0284180b200241c0186a2016202020024180186a107d20022802c818211620022802c0184101460d0320022802c41821192016410576ad21070b2019201b4105746a2216201c360200201620022903c0163702042016410c6a201d290300370200201641146a201f2903003702002016201e3b011c200742ffffffff0f83201b41016aad422086842107200b417f6a220b0d000b2001280204211b0b2001201b417f6a3602042019450d052007422088a7410574220b0d012019210b0c020b2016450d190c180b2019200b6a21162019210b0340200b41206a220b2016470d000b0b2007a72116200241800e6a200110ad010240024020022802800e0d0020022802840e221c200128020028020441246e221b201b201c4b1bad42247e2207422088a70d192007a7221b417f4c0d1902400240201b0d004104211d0c010b201b102c221d450d190b2001200128020441016a221e360204201b41246ead21070240201e20012802084b0d0002400240024002400240201c450d00200241c0176a41186a211f0340200241f80d6a200110ad0120022802f80d0d0620022802fc0d2120200241003a009c18200241f00d6a200110fb0420022f01f00d0d0620022f01f20d211b200241e80d6a200110fb0420022f01e80d0d0620022f01ea0d211e200241013a009c182002201e3b0182182002201b3b018018200241e00d6a200110fb0420022f01e00d0d0520022f01e20d211b200241d80d6a200110fb0420022f01d80d0d0520022f01da0d211e200241023a009c182002201e3b0186182002201b3b018418200241d00d6a200110fb0420022f01d00d0d0520022f01d20d211b200241c80d6a200110fb0420022f01c80d0d0520022f01ca0d211e200241033a009c182002201e3b018a182002201b3b018818200241c00d6a200110fb0420022f01c00d0d0520022f01c20d211b200241b80d6a200110fb0420022f01b80d0d0520022f01ba0d211e200241043a009c182002201e3b018e182002201b3b018c18200241b00d6a200110fb0420022f01b00d0d0520022f01b20d211b200241a80d6a200110fb0420022f01a80d0d0520022f01aa0d211e200241053a009c182002201e3b0192182002201b3b019018200241a00d6a200110fb0420022f01a00d0d0520022f01a20d211b200241980d6a200110fb0420022f01980d0d0520022f019a0d211e200241063a009c182002201e3b0196182002201b3b019418200241900d6a200110fb0420022f01900d0d0520022f01920d211b200241880d6a200110fb0420022f01880d0d0520022f018a0d211e200241c0176a41106a222120024180186a41106a290300370300200241c0176a41086a222220024180186a41086a2903003703002002201e3b019a182002201b3b019818201f200228029818360200200241073a009c18200220022903801822093703c018200220093703c017200241800d6a200110fb0420022f01800d0d0620022f01820d2123200241c0166a41086a20222903002209370300200241c0166a41106a20212903002211370300200241c0166a41186a201f280200221b36020020024180166a41086a2221200937030020024180166a41106a2222201137030020024180166a41186a2224201b360200200220022903c01722093703c016200220093703801602402007422088a7221e2007a7470d00201e41016a221b201e490d21201e4101742225201b201b2025491b221b4104201b41044b1bad42247e2207422088a745410274211b2007a7212502400240201e0d0020024100360280180c010b20024104360288182002201d360280182002201e41246c360284180b200241c0186a2025201b20024180186a107d20022802c818211b20022802c0184101460d0320022802c418211d201b41246ead21070b201d201e41246c6a221b2020360200201b200229038016370204201b410c6a2021290300370200201b41146a2022290300370200201b411c6a2024280200360200201b20233b0120200742ffffffff0f83201e41016aad422086842107201c417f6a221c0d000b2001280204211e0b2001201e417f6a360204201d450d052007422088a741246c221b0d01201d211b0c020b201b450d1d0c1c0b201d201b6a211c201d211b0340201b41246a221b201c470d000b0b2007a7211c200241f80c6a200110ad01201b201d6b41246d21200240024020022802f80c0d0020022802fc0c221e200128020028020441286e221b201b201e4b1bad42287e2207422088a70d1d2007a7221b417f4c0d1d02400240201b0d004104211f0c010b201b102c221f450d1d0b2001200128020441016a2221360204201b41286ead21070240202120012802084b0d0002400240024002400240201e450d000340200241f00c6a200110ad0120022802f00c0d0620022802f40c2122200241003a00a018200241e80c6a200110fb0420022f01e80c0d0620022f01ea0c211b200241e00c6a200110fb0420022f01e00c0d0620022f01e20c2121200241013a00a018200220213b0182182002201b3b018018200241d80c6a200110fb0420022f01d80c0d0520022f01da0c211b200241d00c6a200110fb0420022f01d00c0d0520022f01d20c2121200241023a00a018200220213b0186182002201b3b018418200241c80c6a200110fb0420022f01c80c0d0520022f01ca0c211b200241c00c6a200110fb0420022f01c00c0d0520022f01c20c2121200241033a00a018200220213b018a182002201b3b018818200241b80c6a200110fb0420022f01b80c0d0520022f01ba0c211b200241b00c6a200110fb0420022f01b00c0d0520022f01b20c2121200241043a00a018200220213b018e182002201b3b018c18200241a80c6a200110fb0420022f01a80c0d0520022f01aa0c211b200241a00c6a200110fb0420022f01a00c0d0520022f01a20c2121200241053a00a018200220213b0192182002201b3b019018200241980c6a200110fb0420022f01980c0d0520022f019a0c211b200241900c6a200110fb0420022f01900c0d0520022f01920c2121200241063a00a018200220213b0196182002201b3b019418200241880c6a200110fb0420022f01880c0d0520022f018a0c211b200241800c6a200110fb0420022f01800c0d0520022f01820c2121200241073a00a018200220213b019a182002201b3b019818200241f80b6a200110fb0420022f01f80b0d0520022f01fa0b211b200241f00b6a200110fb0420022f01f00b0d0520022f01f20b2121200241c0176a41106a222320024180186a41106a290300370300200220213b019e182002201b3b019c18200241c0176a41186a221b20024180186a41186a290300370300200241083a00a018200241c0176a41086a222120024180186a41086a290300370300200220022903801822093703c018200220093703c017200241e80b6a200110fb0420022f01e80b0d0620022f01ea0b2124200241c0166a41086a20212903002209370300200241c0166a41106a20232903002211370300200241c0166a41186a201b290300222637030020024180166a41086a2223200937030020024180166a41106a2225201137030020024180166a41186a22272026370300200220022903c01722093703c016200220093703801602402007422088a722212007a7470d00202141016a221b2021490d2520214101742228201b201b2028491b221b4104201b41044b1bad42287e2207422088a745410274211b2007a721280240024020210d0020024100360280180c010b20024104360288182002201f360280182002202141286c360284180b200241c0186a2028201b20024180186a107d20022802c818211b20022802c0184101460d0320022802c418211f201b41286ead21070b201f202141286c6a221b2022360200201b200229038016370204201b410c6a2023290300370200201b41146a2025290300370200201b411c6a2027290300370200201b20243b0124200742ffffffff0f83202141016aad422086842107201e417f6a221e0d000b200128020421210b20012021417f6a360204201f450d052007422088a741286c221b0d01201f211b0c020b201b450d210c200b201f201b6a211e201f211b0340201b41286a221b201e470d000b0b2007a7211e200241e00b6a200110ad01201b201f6b41286d21220240024020022802e00b0d0020022802e40b22212001280200280204412c6e221b201b20214b1bad422c7e2207422088a70d212007a7221b417f4c0d2102400240201b0d00410421230c010b201b102c2223450d210b2001200128020441016a2224360204201b412c6ead21070240202420012802084b0d00024002400240024002402021450d000340200241d80b6a200110ad0120022802d80b0d0620022802dc0b2125200241003a00a418200241d00b6a200110fb0420022f01d00b0d0620022f01d20b211b200241c80b6a200110fb0420022f01c80b0d0620022f01ca0b2124200241013a00a418200220243b0182182002201b3b018018200241c00b6a200110fb0420022f01c00b0d0520022f01c20b211b200241b80b6a200110fb0420022f01b80b0d0520022f01ba0b2124200241023a00a418200220243b0186182002201b3b018418200241b00b6a200110fb0420022f01b00b0d0520022f01b20b211b200241a80b6a200110fb0420022f01a80b0d0520022f01aa0b2124200241033a00a418200220243b018a182002201b3b018818200241a00b6a200110fb0420022f01a00b0d0520022f01a20b211b200241980b6a200110fb0420022f01980b0d0520022f019a0b2124200241043a00a418200220243b018e182002201b3b018c18200241900b6a200110fb0420022f01900b0d0520022f01920b211b200241880b6a200110fb0420022f01880b0d0520022f018a0b2124200241053a00a418200220243b0192182002201b3b019018200241800b6a200110fb0420022f01800b0d0520022f01820b211b200241f80a6a200110fb0420022f01f80a0d0520022f01fa0a2124200241063a00a418200220243b0196182002201b3b019418200241f00a6a200110fb0420022f01f00a0d0520022f01f20a211b200241e80a6a200110fb0420022f01e80a0d0520022f01ea0a2124200241073a00a418200220243b019a182002201b3b019818200241e00a6a200110fb0420022f01e00a0d0520022f01e20a211b200241d80a6a200110fb0420022f01d80a0d0520022f01da0a2124200241083a00a418200220243b019e182002201b3b019c18200241d00a6a200110fb0420022f01d00a0d0520022f01d20a211b200241c80a6a200110fb0420022f01c80a0d05200220022f01ca0a3b01a2182002201b3b01a018200241093a00a418200241c0186a41086a20024180186a41086a2903002209370300200241c0186a41106a20024180186a41106a2903002211370300200241c0186a41186a20024180186a41186a2903002226370300200241c0186a41206a20022802a018221b360200200220022903801822293703c018200241c0176a41206a2224201b360200200241c0176a41186a22272026370300200241c0176a41106a22282011370300200241c0176a41086a222a2009370300200220293703c017200241c00a6a200110fb0420022f01c00a0d0620022f01c20a212b20024180176a41206a2024280200221b360200200241c0166a41086a202a2903002209370300200241c0166a41106a20282903002211370300200241c0166a41186a20272903002226370300200241c0166a41206a201b36020020024180166a41086a2227200937030020024180166a41106a2228201137030020024180166a41186a222a202637030020024180166a41206a222c201b360200200220022903c01722093703c016200220093703801602402007422088a722242007a7470d00202441016a221b2024490d292024410174222d201b201b202d491b221b4104201b41044b1bad422c7e2207422088a745410274211b2007a7212d0240024020240d0020024100360280180c010b2002410436028818200220233602801820022024412c6c360284180b200241c0186a202d201b20024180186a107d20022802c818211b20022802c0184101460d0320022802c4182123201b412c6ead21070b20232024412c6c6a221b2025360200201b200229038016370204201b410c6a2027290300370200201b41146a2028290300370200201b411c6a202a290300370200201b41246a202c280200360200201b202b3b0128200742ffffffff0f83202441016aad4220868421072021417f6a22210d000b200128020421240b20012024417f6a3602042023450d052007422088a7412c6c221b0d012023211b0c020b201b450d250c240b2023201b6a21212023211b0340201b412c6a221b2021470d000b0b2007a72121200241b80a6a200110ad01201b20236b412c6d21250240024020022802b80a0d0020022802bc0a2224200128020028020441306e221b201b20244b1bad42307e2207422088a70d252007a7221b417f4c0d2502400240201b0d00410421270c010b201b102c2227450d250b2001200128020441016a2228360204201b41306ead21070240202820012802084b0d00024002400240024002402024450d000340200241b00a6a200110ad0120022802b00a0d0620022802b40a212a200241003a00a818200241a80a6a200110fb0420022f01a80a0d0620022f01aa0a211b200241a00a6a200110fb0420022f01a00a0d0620022f01a20a2128200241013a00a818200220283b0182182002201b3b018018200241980a6a200110fb0420022f01980a0d0520022f019a0a211b200241900a6a200110fb0420022f01900a0d0520022f01920a2128200241023a00a818200220283b0186182002201b3b018418200241880a6a200110fb0420022f01880a0d0520022f018a0a211b200241800a6a200110fb0420022f01800a0d0520022f01820a2128200241033a00a818200220283b018a182002201b3b018818200241f8096a200110fb0420022f01f8090d0520022f01fa09211b200241f0096a200110fb0420022f01f0090d0520022f01f2092128200241043a00a818200220283b018e182002201b3b018c18200241e8096a200110fb0420022f01e8090d0520022f01ea09211b200241e0096a200110fb0420022f01e0090d0520022f01e2092128200241053a00a818200220283b0192182002201b3b019018200241d8096a200110fb0420022f01d8090d0520022f01da09211b200241d0096a200110fb0420022f01d0090d0520022f01d2092128200241063a00a818200220283b0196182002201b3b019418200241c8096a200110fb0420022f01c8090d0520022f01ca09211b200241c0096a200110fb0420022f01c0090d0520022f01c2092128200241073a00a818200220283b019a182002201b3b019818200241b8096a200110fb0420022f01b8090d0520022f01ba09211b200241b0096a200110fb0420022f01b0090d0520022f01b2092128200241083a00a818200220283b019e182002201b3b019c18200241a8096a200110fb0420022f01a8090d0520022f01aa09211b200241a0096a200110fb0420022f01a0090d0520022f01a2092128200241093a00a818200220283b01a2182002201b3b01a01820024198096a200110fb0420022f0198090d0520022f019a09211b20024190096a200110fb0420022f0190090d05200220022f0192093b01a6182002201b3b01a4182002410a3a00a818200241c0186a41086a20024180186a41086a2903002209370300200241c0186a41106a20024180186a41106a2903002211370300200241c0186a41186a20024180186a41186a2903002226370300200241c0186a41206a20024180186a41206a29030022293703002002200229038018222e3703c018200241c0176a41206a221b2029370300200241c0176a41186a22282026370300200241c0176a41106a222b2011370300200241c0176a41086a222c20093703002002202e3703c01720024188096a200110fb0420022f0188090d0620022f018a09212d20024180176a41206a201b2903002209370300200241c0166a41086a202c2903002211370300200241c0166a41106a202b2903002226370300200241c0166a41186a20282903002229370300200241c0166a41206a200937030020024180166a41086a222b201137030020024180166a41106a222c202637030020024180166a41186a222f202937030020024180166a41206a22302009370300200220022903c01722093703c016200220093703801602402007422088a722282007a7470d00202841016a221b2028490d2d20284101742231201b201b2031491b221b4104201b41044b1bad42307e2207422088a745410274211b2007a721310240024020280d0020024100360280180c010b200241043602881820022027360280182002202841306c360284180b200241c0186a2031201b20024180186a107d20022802c818211b20022802c0184101460d0320022802c4182127201b41306ead21070b2027202841306c6a221b202a360200201b200229038016370204201b410c6a202b290300370200201b41146a202c290300370200201b411c6a202f290300370200201b41246a2030290300370200201b202d3b012c200742ffffffff0f83202841016aad4220868421072024417f6a22240d000b200128020421280b20012028417f6a3602042027450d052007422088a741306c221b0d012027211b0c020b201b450d290c280b2027201b6a21242027211b0340201b41306a221b2024470d000b0b2007a7212420024180096a200110ad01201b20276b41306d212a024002402002280280090d002002280284092228200128020028020441346e221b201b20284b1bad42347e2207422088a70d292007a7221b417f4c0d2902400240201b0d004104212b0c010b201b102c222b450d290b2001200128020441016a222c360204201b41346ead21070240202c20012802084b0d00024002400240024002402028450d000340200241f8086a200110ad0120022802f8080d0620022802fc08212d200241003a00ac18200241f0086a200110fb0420022f01f0080d0620022f01f208211b200241e8086a200110fb0420022f01e8080d0620022f01ea08212c200241013a00ac182002202c3b0182182002201b3b018018200241e0086a200110fb0420022f01e0080d0520022f01e208211b200241d8086a200110fb0420022f01d8080d0520022f01da08212c200241023a00ac182002202c3b0186182002201b3b018418200241d0086a200110fb0420022f01d0080d0520022f01d208211b200241c8086a200110fb0420022f01c8080d0520022f01ca08212c200241033a00ac182002202c3b018a182002201b3b018818200241c0086a200110fb0420022f01c0080d0520022f01c208211b200241b8086a200110fb0420022f01b8080d0520022f01ba08212c200241043a00ac182002202c3b018e182002201b3b018c18200241b0086a200110fb0420022f01b0080d0520022f01b208211b200241a8086a200110fb0420022f01a8080d0520022f01aa08212c200241053a00ac182002202c3b0192182002201b3b019018200241a0086a200110fb0420022f01a0080d0520022f01a208211b20024198086a200110fb0420022f0198080d0520022f019a08212c200241063a00ac182002202c3b0196182002201b3b01941820024190086a200110fb0420022f0190080d0520022f019208211b20024188086a200110fb0420022f0188080d0520022f018a08212c200241073a00ac182002202c3b019a182002201b3b01981820024180086a200110fb0420022f0180080d0520022f018208211b200241f8076a200110fb0420022f01f8070d0520022f01fa07212c200241083a00ac182002202c3b019e182002201b3b019c18200241f0076a200110fb0420022f01f0070d0520022f01f207211b200241e8076a200110fb0420022f01e8070d0520022f01ea07212c200241093a00ac182002202c3b01a2182002201b3b01a018200241e0076a200110fb0420022f01e0070d0520022f01e207211b200241d8076a200110fb0420022f01d8070d0520022f01da07212c2002410a3a00ac182002202c3b01a6182002201b3b01a418200241d0076a200110fb0420022f01d0070d0520022f01d207211b200241c8076a200110fb0420022f01c8070d05200220022f01ca073b01aa182002201b3b01a8182002410b3a00ac18200241c0186a41086a20024180186a41086a2903002209370300200241c0186a41106a20024180186a41106a2903002211370300200241c0186a41186a20024180186a41186a2903002226370300200241c0186a41206a20024180186a41206a2903002229370300200241c0186a41286a20022802a818221b3602002002200229038018222e3703c018200241c0176a41286a222c201b360200200241c0176a41206a222f2029370300200241c0176a41186a22302026370300200241c0176a41106a22312011370300200241c0176a41086a223220093703002002202e3703c017200241c0076a200110fb0420022f01c0070d0620022f01c207213320024180176a41286a202c280200221b36020020024180176a41206a202f2903002209370300200241c0166a41086a20322903002211370300200241c0166a41106a20312903002226370300200241c0166a41186a20302903002229370300200241c0166a41206a2009370300200241c0166a41286a201b360200200220022903c017222e3703c01620024180166a41286a222f201b36020020024180166a41206a2230200937030020024180166a41186a2231202937030020024180166a41106a2232202637030020024180166a41086a223420113703002002202e3703801602402007422088a7222c2007a7470d00202c41016a221b202c490d31202c4101742235201b201b2035491b221b4104201b41044b1bad42347e2207422088a745410274211b2007a7213502400240202c0d0020024100360280180c010b20024104360288182002202b360280182002202c41346c360284180b200241c0186a2035201b20024180186a107d20022802c818211b20022802c0184101460d0320022802c418212b201b41346ead21070b202b202c41346c6a221b202d360200201b200229038016370204201b410c6a2034290300370200201b41146a2032290300370200201b411c6a2031290300370200201b41246a2030290300370200201b412c6a202f280200360200201b20333b0130200742ffffffff0f83202c41016aad4220868421072028417f6a22280d000b2001280204212c0b2001202c417f6a360204202b450d052007422088a741346c221b0d01202b211b0c020b201b450d2d0c2c0b202b201b6a2128202b211b0340201b41346a221b2028470d000b0b2007a72128200241b8076a200110ad01201b202b6b41346d212d0240024020022802b8070d0020022802bc07222c200128020028020441386e221b201b202c4b1bad42387e2207422088a70d2d2007a7221b417f4c0d2d02400240201b0d004104212f0c010b201b102c222f450d2d0b2001200128020441016a2230360204201b41386ead21070240203020012802084b0d0002400240024002400240202c450d000340200241b0076a200110ad0120022802b0070d0620022802b4072131200241003a00b018200241a8076a200110fb0420022f01a8070d0620022f01aa07211b200241a0076a200110fb0420022f01a0070d0620022f01a2072130200241013a00b018200220303b0182182002201b3b01801820024198076a200110fb0420022f0198070d0520022f019a07211b20024190076a200110fb0420022f0190070d0520022f0192072130200241023a00b018200220303b0186182002201b3b01841820024188076a200110fb0420022f0188070d0520022f018a07211b20024180076a200110fb0420022f0180070d0520022f0182072130200241033a00b018200220303b018a182002201b3b018818200241f8066a200110fb0420022f01f8060d0520022f01fa06211b200241f0066a200110fb0420022f01f0060d0520022f01f2062130200241043a00b018200220303b018e182002201b3b018c18200241e8066a200110fb0420022f01e8060d0520022f01ea06211b200241e0066a200110fb0420022f01e0060d0520022f01e2062130200241053a00b018200220303b0192182002201b3b019018200241d8066a200110fb0420022f01d8060d0520022f01da06211b200241d0066a200110fb0420022f01d0060d0520022f01d2062130200241063a00b018200220303b0196182002201b3b019418200241c8066a200110fb0420022f01c8060d0520022f01ca06211b200241c0066a200110fb0420022f01c0060d0520022f01c2062130200241073a00b018200220303b019a182002201b3b019818200241b8066a200110fb0420022f01b8060d0520022f01ba06211b200241b0066a200110fb0420022f01b0060d0520022f01b2062130200241083a00b018200220303b019e182002201b3b019c18200241a8066a200110fb0420022f01a8060d0520022f01aa06211b200241a0066a200110fb0420022f01a0060d0520022f01a2062130200241093a00b018200220303b01a2182002201b3b01a01820024198066a200110fb0420022f0198060d0520022f019a06211b20024190066a200110fb0420022f0190060d0520022f01920621302002410a3a00b018200220303b01a6182002201b3b01a41820024188066a200110fb0420022f0188060d0520022f018a06211b20024180066a200110fb0420022f0180060d0520022f01820621302002410b3a00b018200220303b01aa182002201b3b01a818200241f8056a200110fb0420022f01f8050d0520022f01fa05211b200241f0056a200110fb0420022f01f0050d05200220022f01f2053b01ae182002201b3b01ac182002410c3a00b018200241c0186a41086a20024180186a41086a2903002209370300200241c0186a41106a20024180186a41106a2903002211370300200241c0186a41186a20024180186a41186a2903002226370300200241c0186a41206a20024180186a41206a2903002229370300200241c0186a41286a20024180186a41286a290300222e370300200220022903801822363703c018200241c0176a41286a221b202e370300200241c0176a41206a22302029370300200241c0176a41186a22322026370300200241c0176a41106a22332011370300200241c0176a41086a22342009370300200220363703c017200241e8056a200110fb0420022f01e8050d0620022f01ea05213520024180176a41286a201b290300220937030020024180176a41206a20302903002211370300200241c0166a41086a20342903002226370300200241c0166a41106a20332903002229370300200241c0166a41186a2032290300222e370300200241c0166a41206a2011370300200241c0166a41286a2009370300200220022903c01722363703c01620024180166a41286a2232200937030020024180166a41206a2233201137030020024180166a41186a2234202e37030020024180166a41106a2237202937030020024180166a41086a22382026370300200220363703801602402007422088a722302007a7470d00203041016a221b2030490d3520304101742239201b201b2039491b221b4104201b41044b1bad42387e2207422088a745410274211b2007a721390240024020300d0020024100360280180c010b20024104360288182002202f360280182002203041386c360284180b200241c0186a2039201b20024180186a107d20022802c818211b20022802c0184101460d0320022802c418212f201b41386ead21070b202f203041386c6a221b2031360200201b200229038016370204201b410c6a2038290300370200201b41146a2037290300370200201b411c6a2034290300370200201b41246a2033290300370200201b412c6a2032290300370200201b20353b0134200742ffffffff0f83203041016aad422086842107202c417f6a222c0d000b200128020421300b20012030417f6a360204202f450d052007422088a741386c221b0d01202f211b0c020b201b450d310c300b202f201b6a212c202f211b0340201b41386a221b202c470d000b0b2007a7212c200241e0056a200110ad01201b202f6b41386d21310240024020022802e0050d0020022802e40522302001280200280204413c6e221b201b20304b1bad423c7e2207422088a70d312007a7221b417f4c0d3102400240201b0d00410421320c010b201b102c2232450d310b2001200128020441016a2233360204201b413c6ead21070240203320012802084b0d00024002400240024002402030450d000340200241d8056a200110ad0120022802d8050d0620022802dc052134200241003a00b418200241d0056a200110fb0420022f01d0050d0620022f01d205211b200241c8056a200110fb0420022f01c8050d0620022f01ca052133200241013a00b418200220333b0182182002201b3b018018200241c0056a200110fb0420022f01c0050d0520022f01c205211b200241b8056a200110fb0420022f01b8050d0520022f01ba052133200241023a00b418200220333b0186182002201b3b018418200241b0056a200110fb0420022f01b0050d0520022f01b205211b200241a8056a200110fb0420022f01a8050d0520022f01aa052133200241033a00b418200220333b018a182002201b3b018818200241a0056a200110fb0420022f01a0050d0520022f01a205211b20024198056a200110fb0420022f0198050d0520022f019a052133200241043a00b418200220333b018e182002201b3b018c1820024190056a200110fb0420022f0190050d0520022f019205211b20024188056a200110fb0420022f0188050d0520022f018a052133200241053a00b418200220333b0192182002201b3b01901820024180056a200110fb0420022f0180050d0520022f018205211b200241f8046a200110fb0420022f01f8040d0520022f01fa042133200241063a00b418200220333b0196182002201b3b019418200241f0046a200110fb0420022f01f0040d0520022f01f204211b200241e8046a200110fb0420022f01e8040d0520022f01ea042133200241073a00b418200220333b019a182002201b3b019818200241e0046a200110fb0420022f01e0040d0520022f01e204211b200241d8046a200110fb0420022f01d8040d0520022f01da042133200241083a00b418200220333b019e182002201b3b019c18200241d0046a200110fb0420022f01d0040d0520022f01d204211b200241c8046a200110fb0420022f01c8040d0520022f01ca042133200241093a00b418200220333b01a2182002201b3b01a018200241c0046a200110fb0420022f01c0040d0520022f01c204211b200241b8046a200110fb0420022f01b8040d0520022f01ba0421332002410a3a00b418200220333b01a6182002201b3b01a418200241b0046a200110fb0420022f01b0040d0520022f01b204211b200241a8046a200110fb0420022f01a8040d0520022f01aa0421332002410b3a00b418200220333b01aa182002201b3b01a818200241a0046a200110fb0420022f01a0040d0520022f01a204211b20024198046a200110fb0420022f0198040d0520022f019a0421332002410c3a00b418200220333b01ae182002201b3b01ac1820024190046a200110fb0420022f0190040d0520022f019204211b20024188046a200110fb0420022f0188040d05200220022f018a043b01b2182002201b3b01b0182002410d3a00b418200241c0186a41086a223a20024180186a41086a290300370300200241c0186a41106a223920024180186a41106a290300370300200241c0186a41186a223820024180186a41186a290300370300200241c0186a41206a223720024180186a41206a290300370300200241c0186a41286a223520024180186a41286a290300370300200241c0186a41306a223320022802b01836020020022002290380183703c018200241c0176a41306a221b2033280200360200200241c0176a41286a22332035290300370300200241c0176a41206a22352037290300370300200241c0176a41186a22372038290300370300200241c0176a41106a22382039290300370300200241c0176a41086a2239203a290300370300200220022903c0183703c01720024180046a200110fb0420022f0180040d0620022f018204213a20024180176a41306a201b280200221b36020020024180176a41286a2033290300220937030020024180176a41206a20352903002211370300200241c0166a41086a22332039290300370300200241c0166a41106a22352038290300370300200241c0166a41186a22382037290300370300200241c0166a41206a22372011370300200241c0166a41286a22392009370300200241c0166a41306a223b201b360200200220022903c0173703c01620024180166a41306a223c203b28020036020020024180166a41286a223b203929030037030020024180166a41206a2239203729030037030020024180166a41186a2237203829030037030020024180166a41106a2238203529030037030020024180166a41086a22352033290300370300200220022903c0163703801602402007422088a722332007a7470d00203341016a221b2033490d392033410174223d201b201b203d491b221b4104201b41044b1bad423c7e2207422088a745410274211b2007a7213d0240024020330d0020024100360280180c010b2002410436028818200220323602801820022033413c6c360284180b200241c0186a203d201b20024180186a107d20022802c818211b20022802c0184101460d0320022802c4182132201b413c6ead21070b20322033413c6c6a221b2034360200201b200229038016370204201b410c6a2035290300370200201b41146a2038290300370200201b411c6a2037290300370200201b41246a2039290300370200201b412c6a203b290300370200201b41346a203c280200360200201b203a3b0138200742ffffffff0f83203341016aad4220868421072030417f6a22300d000b200128020421330b20012033417f6a3602042032450d052007422088a7413c6c221b0d012032211b0c020b201b450d350c340b2032201b6a21302032211b0340201b413c6a221b2030470d000b0b2007a72133200241f8036a200110ad01201b20326b413c6d21370240024020022802f8030d0020022802fc0322302001280200280204410676221b201b20304b1b221b4106742234417f4c0d3502400240201b0d00410421340c010b2034102c2234450d350b2001200128020441016a2235360204201bad21070240203520012802084b0d00024002400240024002402030450d000340200241f0036a200110ad0120022802f0030d0620022802f4032138200241003a00b818200241e8036a200110fb0420022f01e8030d0620022f01ea03211b200241e0036a200110fb0420022f01e0030d0620022f01e2032135200241013a00b818200220353b0182182002201b3b018018200241d8036a200110fb0420022f01d8030d0520022f01da03211b200241d0036a200110fb0420022f01d0030d0520022f01d2032135200241023a00b818200220353b0186182002201b3b018418200241c8036a200110fb0420022f01c8030d0520022f01ca03211b200241c0036a200110fb0420022f01c0030d0520022f01c2032135200241033a00b818200220353b018a182002201b3b018818200241b8036a200110fb0420022f01b8030d0520022f01ba03211b200241b0036a200110fb0420022f01b0030d0520022f01b2032135200241043a00b818200220353b018e182002201b3b018c18200241a8036a200110fb0420022f01a8030d0520022f01aa03211b200241a0036a200110fb0420022f01a0030d0520022f01a2032135200241053a00b818200220353b0192182002201b3b01901820024198036a200110fb0420022f0198030d0520022f019a03211b20024190036a200110fb0420022f0190030d0520022f0192032135200241063a00b818200220353b0196182002201b3b01941820024188036a200110fb0420022f0188030d0520022f018a03211b20024180036a200110fb0420022f0180030d0520022f0182032135200241073a00b818200220353b019a182002201b3b019818200241f8026a200110fb0420022f01f8020d0520022f01fa02211b200241f0026a200110fb0420022f01f0020d0520022f01f2022135200241083a00b818200220353b019e182002201b3b019c18200241e8026a200110fb0420022f01e8020d0520022f01ea02211b200241e0026a200110fb0420022f01e0020d0520022f01e2022135200241093a00b818200220353b01a2182002201b3b01a018200241d8026a200110fb0420022f01d8020d0520022f01da02211b200241d0026a200110fb0420022f01d0020d0520022f01d20221352002410a3a00b818200220353b01a6182002201b3b01a418200241c8026a200110fb0420022f01c8020d0520022f01ca02211b200241c0026a200110fb0420022f01c0020d0520022f01c20221352002410b3a00b818200220353b01aa182002201b3b01a818200241b8026a200110fb0420022f01b8020d0520022f01ba02211b200241b0026a200110fb0420022f01b0020d0520022f01b20221352002410c3a00b818200220353b01ae182002201b3b01ac18200241a8026a200110fb0420022f01a8020d0520022f01aa02211b200241a0026a200110fb0420022f01a0020d0520022f01a20221352002410d3a00b818200220353b01b2182002201b3b01b01820024198026a200110fb0420022f0198020d0520022f019a02211b20024190026a200110fb0420022f0190020d05200220022f0192023b01b6182002201b3b01b4182002410e3a00b818200241c0186a41086a223d20024180186a41086a290300370300200241c0186a41106a223c20024180186a41106a290300370300200241c0186a41186a223b20024180186a41186a290300370300200241c0186a41206a223a20024180186a41206a290300370300200241c0186a41286a223920024180186a41286a290300370300200241c0186a41306a223520024180186a41306a29030037030020022002290380183703c018200241c0176a41306a221b2035290300370300200241c0176a41286a22352039290300370300200241c0176a41206a2239203a290300370300200241c0176a41186a223a203b290300370300200241c0176a41106a223b203c290300370300200241c0176a41086a223c203d290300370300200220022903c0183703c01720024188026a200110fb0420022f0188020d0620022f018a02213d20024180176a41306a201b290300220937030020024180176a41286a2035290300221137030020024180176a41206a20392903002226370300200241c0166a41086a221b203c290300370300200241c0166a41106a2235203b290300370300200241c0166a41186a2239203a290300370300200241c0166a41206a223a2026370300200241c0166a41286a223b2011370300200241c0166a41306a223c2009370300200220022903c0173703c01620024180166a41306a223e203c29030037030020024180166a41286a223c203b29030037030020024180166a41206a223b203a29030037030020024180166a41186a223a203929030037030020024180166a41106a2239203529030037030020024180166a41086a223f201b290300370300200220022903c01637038016024020074220882209a722352007a7470d00203541016a221b2035490d3d20354101742240201b201b2040491b221b4104201b41044b1b221b41ffffff1f71201b464102742140201b410674211b0240024020350d0020024100360280180c010b20024104360288182002203436028018200220094206863e0284180b200241c0186a201b204020024180186a107d20022802c818211b20022802c0184101460d0320022802c4182134201b410676ad21070b203420354106746a221b2038360200201b200229038016370204201b410c6a203f290300370200201b41146a2039290300370200201b411c6a203a290300370200201b41246a203b290300370200201b412c6a203c290300370200201b41346a203e290300370200201b203d3b013c200742ffffffff0f83203541016aad4220868421072030417f6a22300d000b200128020421350b20012035417f6a3602042034450d052007422088a7410674221b0d012034211b0c020b201b450d390c380b2034201b6a21302034211b0340201b41c0006a221b2030470d000b0b2007a7213a20024180026a200110ad0102402002280280020d002002280284022239200128020028020441c4006e2230203020394b1bad42c4007e2207422088a70d382007a72235417f4c0d380240024020350d00410421300c010b2035102c2230450d380b2001200128020441016a2238360204203541c4006ead21070240203820012802084b0d00024002400240024002402039450d000340200241f8016a200110ad0120022802f8010d0620022802fc01213b200241003a00bc18200241f0016a200110fb0420022f01f0010d0620022f01f2012135200241e8016a200110fb0420022f01e8010d0620022f01ea012138200241013a00bc18200220383b018218200220353b018018200241e0016a200110fb0420022f01e0010d0520022f01e2012135200241d8016a200110fb0420022f01d8010d0520022f01da012138200241023a00bc18200220383b018618200220353b018418200241d0016a200110fb0420022f01d0010d0520022f01d2012135200241c8016a200110fb0420022f01c8010d0520022f01ca012138200241033a00bc18200220383b018a18200220353b018818200241c0016a200110fb0420022f01c0010d0520022f01c2012135200241b8016a200110fb0420022f01b8010d0520022f01ba012138200241043a00bc18200220383b018e18200220353b018c18200241b0016a200110fb0420022f01b0010d0520022f01b2012135200241a8016a200110fb0420022f01a8010d0520022f01aa012138200241053a00bc18200220383b019218200220353b019018200241a0016a200110fb0420022f01a0010d0520022f01a201213520024198016a200110fb0420022f0198010d0520022f019a012138200241063a00bc18200220383b019618200220353b01941820024190016a200110fb0420022f0190010d0520022f019201213520024188016a200110fb0420022f0188010d0520022f018a012138200241073a00bc18200220383b019a18200220353b01981820024180016a200110fb0420022f0180010d0520022f0182012135200241f8006a200110fb0420022f01780d0520022f017a2138200241083a00bc18200220383b019e18200220353b019c18200241f0006a200110fb0420022f01700d0520022f01722135200241e8006a200110fb0420022f01680d0520022f016a2138200241093a00bc18200220383b01a218200220353b01a018200241e0006a200110fb0420022f01600d0520022f01622135200241d8006a200110fb0420022f01580d0520022f015a21382002410a3a00bc18200220383b01a618200220353b01a418200241d0006a200110fb0420022f01500d0520022f01522135200241c8006a200110fb0420022f01480d0520022f014a21382002410b3a00bc18200220383b01aa18200220353b01a818200241c0006a200110fb0420022f01400d0520022f01422135200241386a200110fb0420022f01380d0520022f013a21382002410c3a00bc18200220383b01ae18200220353b01ac18200241306a200110fb0420022f01300d0520022f01322135200241286a200110fb0420022f01280d0520022f012a21382002410d3a00bc18200220383b01b218200220353b01b018200241206a200110fb0420022f01200d0520022f01222135200241186a200110fb0420022f01180d0520022f011a21382002410e3a00bc18200220383b01b618200220353b01b418200241106a200110fb0420022f01100d0520022f01122135200241086a200110fb0420022f01080d05200220022f010a3b01ba18200220353b01b8182002410f3a00bc18200241c0186a41086a223820024180186a41086a290300370300200241c0186a41106a223c20024180186a41106a290300370300200241c0186a41186a223d20024180186a41186a290300370300200241c0186a41206a223e20024180186a41206a290300370300200241c0186a41286a223f20024180186a41286a290300370300200241c0186a41306a224020024180186a41306a290300370300200241c0186a41386a224120022802b81836020020022002290380183703c018200241c0176a41086a22352038290300370300200241c0176a41106a2238203c290300370300200241c0176a41186a223c203d290300370300200241c0176a41206a223d203e290300370300200241c0176a41286a223e203f290300370300200241c0176a41306a223f2040290300370300200241c0176a41386a22402041280200360200200220022903c0183703c0172002200110fb0420022f01000d0620022f0102214120024180176a41386a2040280200224036020020024180176a41306a203f290300220937030020024180176a41286a203e290300221137030020024180176a41206a203d2903002226370300200241c0166a41086a223d2035290300370300200241c0166a41106a22352038290300370300200241c0166a41186a2238203c290300370300200241c0166a41206a223c2026370300200241c0166a41286a223e2011370300200241c0166a41306a223f2009370300200241c0166a41386a22422040360200200220022903c0173703c01620024180166a41386a2240204228020036020020024180166a41306a2242203f29030037030020024180166a41286a223f203e29030037030020024180166a41206a223e203c29030037030020024180166a41186a223c203829030037030020024180166a41106a2243203529030037030020024180166a41086a2244203d290300370300200220022903c0163703801602402007422088a722382007a7470d00203841016a22352038490d402038410174223d20352035203d491b22354104203541044b1bad42c4007e2207422088a74541027421352007a7213d0240024020380d0020024100360280180c010b200241043602881820022030360280182002203841c4006c360284180b200241c0186a203d203520024180186a107d20022802c818213520022802c0184101460d0320022802c4182130203541c4006ead21070b2030203841c4006c6a2235203b36020020352002290380163702042035410c6a2044290300370200203541146a20432903003702002035411c6a203c290300370200203541246a203e2903003702002035412c6a203f290300370200203541346a20422903003702002035413c6a2040280200360200203520413b0140200742ffffffff0f83203841016aad4220868421072039417f6a22390d000b200128020421380b20012038417f6a3602042030450d05200420056b41037521352003200c6b4104752103200b20196b410575210b201b20346b410675211b2007a721382007422088a741c4006c22040d01203021040c020b2035450d3c0c3b0b203020046a2101203021040340200441c4006a22042001470d000b0b2000200a36020420002005360200200041b8016a2038360200200041b4016a2030360200200041b0016a201b360200200041ac016a203a360200200041a8016a2034360200200041a4016a2037360200200041a0016a20333602002000419c016a203236020020004198016a203136020020004194016a202c36020020004190016a202f3602002000418c016a202d36020020004188016a202836020020004184016a202b36020020004180016a202a360200200041fc006a2024360200200041f8006a2027360200200041f4006a2025360200200041f0006a2021360200200041ec006a2023360200200041e8006a2022360200200041e4006a201e360200200041e0006a201f360200200041dc006a2020360200200041d8006a201c360200200041d4006a201d360200200041d0006a200b360200200041cc006a2016360200200041c8006a2019360200200041c4006a201a360200200041c0006a20143602002000413c6a2017360200200041386a2018360200200041346a2010360200200041306a20133602002000412c6a2015360200200041286a200e360200200041246a2012360200200041206a20033602002000411c6a200d360200200041186a200c360200200041146a200f360200200041106a20063602002000410c6a2008360200200041086a2035360200200041bc016a200420306b41c4006d3602000c380b200241003a00bc180b2007a72204450d00200441c4006c450d002030102e0b20004100360200203a41ffffff1f71450d032034102e0c030b200241003a00b8180b200742ffffff1f83500d002034102e0b200041003602000b2033450d032033413c6c450d032032102e0c030b200241003a00b4180b2007a72204450d002004413c6c450d002032102e0b200041003602000b202c450d03202c41386c450d03202f102e0c030b200241003a00b0180b2007a72204450d00200441386c450d00202f102e0b200041003602000b2028450d03202841346c450d03202b102e0c030b200241003a00ac180b2007a72204450d00200441346c450d00202b102e0b200041003602000b2024450d03202441306c450d032027102e0c030b200241003a00a8180b2007a72204450d00200441306c450d002027102e0b200041003602000b2021450d032021412c6c450d032023102e0c030b200241003a00a4180b2007a72204450d002004412c6c450d002023102e0b200041003602000b201e450d03201e41286c450d03201f102e0c030b200241003a00a0180b2007a72204450d00200441286c450d00201f102e0b200041003602000b201c450d03201c41246c450d03201d102e0c030b200241003a009c180b2007a72204450d00200441246c450d00201d102e0b200041003602000b201641ffffff3f71450d032019102e0c030b200241003a0098180b200742ffffff3f83500d002019102e0b200041003602000b2014450d032014411c6c450d032017102e0c030b200241003a0094180b2007a72204450d002004411c6c450d002017102e0b200041003602000b2010450d03201041186c450d032013102e0c030b200241003a0090180b2007a72204450d00200441186c450d002013102e0b200041003602000b200e450d03200e41146c450d032012102e0c030b200241003a008c180b2007a72204450d00200441146c450d002012102e0b200041003602000b200d41ffffffff0071450d03200c102e0c030b200241003a0088180b200742ffffffff0083500d00200c102e0b200041003602000b2006450d002006410c6c450d002008102e0b200a41ffffffff0171450d002005102e0b200241c0196a24000f0b1036000b1038000ba9b9010f057f017e027f017e067f017e147f017e027f017e047f017e077f017e0e7f230041c0196b22022400200241f8116a200110ab0102400240024002400240024020022802f8110d0020022802fc11220320012802044103762204200420034b1b22044103742205417f4c0d050240024020040d00410421060c010b2005102c2206450d050b2004ad21070240024002402003450d000340200241f0116a200110ab0120022802f0110d0320022802f4112108200241e8116a200110fc0420022f01e8110d0320022f01ea11210902402007422088220aa722052007a72204470d00200441016a22052004490d0a2004410174220b2005200b20054b1b22054104200541044b1b220541ffffffff0171200546410274210b200541037421050240024020040d0020024100360280180c010b2002410436028818200220063602801820022004410374360284180b200241c0186a2005200b20024180186a107d20022802c818210420022802c0184101460d0320022802c41821062007422088220aa721052004410376ad21070b200620054103746a220420093b010420042008360200200a422086200742ffffffff0f83844280808080107c21072003417f6a22030d000b0b2006450d022007422088a741037422040d03200621040c040b20040d050c060b200742ffffffff0183500d002006102e0b200041003602000c020b200620046a210520062104034020042004290200220a3e0200200441046a200a4220883d0100200441086a22042005470d000b0b2007a7210c200241e0116a200110ab01024002400240024020022802e0110d0020022802e41122032001280204410c6e2205200520034b1bad420c7e2207422088a70d062007a72205417f4c0d060240024020050d00410421080c010b2005102c2208450d060b2005410c6ead21070240024002402003450d000340200241d8116a200110ab0120022802d8110d0320022802dc11210b200241d0116a200110fc0420022f01d0110d0320022f01d211210d200241c8116a200110fc0420022f01c8110d0320022f01ca11210e200241c0116a200110fc0420022f01c0110d0320022f01c211210f02402007422088220aa722092007a72205470d00200541016a22092005490d0b200541017422102009201020094b1b22094104200941044b1bad420c7e220a422088a7454102742109200aa721100240024020050d0020024100360280180c010b2002410436028818200220083602801820022005410c6c360284180b200241c0186a2010200920024180186a107d20022802c818210520022802c0184101460d0320022802c41821082007422088220aa721092005410c6ead21070b20082009410c6c6a2205200f3b01082005200d3b01042005200b360200200541066a200e3b0100200a422086200742ffffffff0f83844280808080107c21072003417f6a22030d000b0b2008450d022007422088a7410c6c22050d03200821050c040b2005450d070c060b2007a72204450d002004410c6c450d002008102e0b200041003602000c020b200820056a21032008210503402005410c6a22052003470d000b0b2007a7210d200241b8116a200110ab01200520086b410c6d21100240024020022802b8110d004104210b20022802bc11220320012802044104762205200520034b1b22054104742209417f4c0d0502402005450d002009102c220b450d050b2005ad21070240024002400240024002402003450d000340200241b0116a200110ab0120022802b0110d0620022802b411210e200241003a008818200241a8116a200110fc0420022f01a8110d0620022f01aa112105200241a0116a200110fc0420022f01a0110d0620022f01a2112109200241013a008818200220093b018218200220053b01801820024198116a200110fc0420022f0198110d0520022f019a11210520024190116a200110fc0420022f0190110d05200220022f0192113b018618200220053b018418200229038018210a20024188116a200110fc0420022f0188110d0620022f018a11210f024020074220882211a722052007a7470d00200541016a22092005490d0d20054101742212200920092012491b22094104200941044b1b220941ffffffff00712009464102742112200941047421090240024020050d0020024100360280180c010b20024104360288182002200b36028018200220114204863e0284180b200241c0186a2009201220024180186a107d20022802c818210920022802c0184101460d0320022802c418210b2009410476ad21070b200b20054104746a2209200f3b010c2009200a3702042009200e360200200742ffffffff0f83200541016aad4220868421072003417f6a22030d000b0b200b450d052007422088a741047422050d01200b21050c020b2009450d090c080b200b20056a2103200b21050340200541106a22052003470d000b0b2007a7211220024180116a200110ab01024002402002280280110d00200228028411220e200128020441146e22032003200e4b1bad42147e2207422088a70d092007a72203417f4c0d090240024020030d004104210f0c010b2003102c220f450d090b200341146ead2107024002400240024002400240200e450d00200241c0186a41086a21130340200241f8106a200110ab0120022802f8100d0620022802fc102114200241003a008c18200241f0106a200110fc0420022f01f0100d0620022f01f2102103200241e8106a200110fc0420022f01e8100d0620022f01ea102109200241013a008c18200220093b018218200220033b018018200241e0106a200110fc0420022f01e0100d0520022f01e2102103200241d8106a200110fc0420022f01d8100d0520022f01da102109200241023a008c18200220093b018618200220033b018418200241d0106a200110fc0420022f01d0100d0520022f01d2102103200241c8106a200110fc0420022f01c8100d05200220022f01ca103b018a18200220033b018818201320022802881836020020022002290380183703c018200241c0106a200110fc0420022f01c0100d0620022f01c210211520024180176a41086a20132802002203360200200241c0166a41086a22162003360200200220022903c018220a370380172002200a3703c01602402007422088a722032007a7470d00200341016a22092003490d1120034101742217200920092017491b22094104200941044b1bad42147e2207422088a74541027421092007a721170240024020030d0020024100360280180c010b20024104360288182002200f360280182002200341146c360284180b200241c0186a2017200920024180186a107d20022802c818210920022802c0184101460d0320022802c418210f200941146ead21070b200f200341146c6a22092014360200200920022903c0163702042009410c6a2016280200360200200920153b0110200742ffffffff0f83200341016aad422086842107200e417f6a220e0d000b0b200f450d052007422088a741146c22030d01200f21030c020b2009450d0d0c0c0b200f20036a2109200f21030340200341146a22032009470d000b0b2007a72109200241b8106a200110ab012003200f6b41146d21180240024020022802b8100d0020022802bc102213200128020441186e2203200320134b1bad42187e2207422088a70d0d2007a72203417f4c0d0d0240024020030d00410421140c010b2003102c2214450d0d0b200341186ead21070240024002400240024002402013450d000340200241b0106a200110ab0120022802b0100d0620022802b4102115200241003a009018200241a8106a200110fc0420022f01a8100d0620022f01aa102103200241a0106a200110fc0420022f01a0100d0620022f01a210210e200241013a0090182002200e3b018218200220033b01801820024198106a200110fc0420022f0198100d0520022f019a10210320024190106a200110fc0420022f0190100d0520022f019210210e200241023a0090182002200e3b018618200220033b01841820024188106a200110fc0420022f0188100d0520022f018a10210320024180106a200110fc0420022f0180100d0520022f018210210e200241033a0090182002200e3b018a18200220033b018818200241f80f6a200110fc0420022f01f80f0d0520022f01fa0f2103200241f00f6a200110fc0420022f01f00f0d05200220022f01f20f3b018e18200220033b018c18200241c0186a41086a220320024180186a41086a29030037030020022002290380183703c018200241e80f6a200110fc0420022f01e80f0d0620022f01ea0f211620024180176a41086a2003290300220a370300200241c0166a41086a2217200a370300200220022903c018220a370380172002200a3703c01602402007422088a722032007a7470d00200341016a220e2003490d1520034101742219200e200e2019491b220e4104200e41044b1bad42187e2207422088a745410274210e2007a721190240024020030d0020024100360280180c010b200241043602881820022014360280182002200341186c360284180b200241c0186a2019200e20024180186a107d20022802c818210e20022802c0184101460d0320022802c4182114200e41186ead21070b2014200341186c6a220e2015360200200e20022903c016370204200e410c6a2017290300370200200e20163b0114200742ffffffff0f83200341016aad4220868421072013417f6a22130d000b0b2014450d052007422088a741186c22030d01201421030c020b200e450d110c100b201420036a210e201421030340200341186a2203200e470d000b0b2007a7210e200241e00f6a200110ab01200320146b41186d211a0240024020022802e00f0d0020022802e40f22152001280204411c6e2203200320154b1bad421c7e2207422088a70d112007a72203417f4c0d110240024020030d00410421160c010b2003102c2216450d110b2003411c6ead21070240024002400240024002402015450d00200241c0186a41106a21170340200241d80f6a200110ab0120022802d80f0d0620022802dc0f2119200241003a009418200241d00f6a200110fc0420022f01d00f0d0620022f01d20f2103200241c80f6a200110fc0420022f01c80f0d0620022f01ca0f2113200241013a009418200220133b018218200220033b018018200241c00f6a200110fc0420022f01c00f0d0520022f01c20f2103200241b80f6a200110fc0420022f01b80f0d0520022f01ba0f2113200241023a009418200220133b018618200220033b018418200241b00f6a200110fc0420022f01b00f0d0520022f01b20f2103200241a80f6a200110fc0420022f01a80f0d0520022f01aa0f2113200241033a009418200220133b018a18200220033b018818200241a00f6a200110fc0420022f01a00f0d0520022f01a20f2103200241980f6a200110fc0420022f01980f0d0520022f019a0f2113200241043a009418200220133b018e18200220033b018c18200241900f6a200110fc0420022f01900f0d0520022f01920f2103200241880f6a200110fc0420022f01880f0d0520022f018a0f2113200241c0186a41086a221b20024180186a41086a290300370300200220133b019218200220033b0190182017200228029018360200200241053a00941820022002290380183703c018200241800f6a200110fc0420022f01800f0d0620022f01820f211c20024180176a41086a201b290300220a37030020024180176a41106a20172802002203360200200241c0166a41086a221b200a370300200241c0166a41106a221d2003360200200220022903c018220a370380172002200a3703c01602402007422088a722032007a7470d00200341016a22132003490d192003410174221e20132013201e491b22134104201341044b1bad421c7e2207422088a74541027421132007a7211e0240024020030d0020024100360280180c010b2002410436028818200220163602801820022003411c6c360284180b200241c0186a201e201320024180186a107d20022802c818211320022802c0184101460d0320022802c41821162013411c6ead21070b20162003411c6c6a22132019360200201320022903c0163702042013410c6a201b290300370200201341146a201d2802003602002013201c3b0118200742ffffffff0f83200341016aad4220868421072015417f6a22150d000b0b2016450d052007422088a7411c6c22030d01201621030c020b2013450d150c140b201620036a21132016210303402003411c6a22032013470d000b0b2007a72113200241f80e6a200110ab01200320166b411c6d211b0240024020022802f80e0d0020022802fc0e221720012802044105762203200320174b1b22034105742215417f4c0d150240024020030d00410421190c010b2015102c2219450d150b2003ad21070240024002400240024002402017450d000340200241f00e6a200110ab0120022802f00e0d0620022802f40e211c200241003a009818200241e80e6a200110fc0420022f01e80e0d0620022f01ea0e2103200241e00e6a200110fc0420022f01e00e0d0620022f01e20e2115200241013a009818200220153b018218200220033b018018200241d80e6a200110fc0420022f01d80e0d0520022f01da0e2103200241d00e6a200110fc0420022f01d00e0d0520022f01d20e2115200241023a009818200220153b018618200220033b018418200241c80e6a200110fc0420022f01c80e0d0520022f01ca0e2103200241c00e6a200110fc0420022f01c00e0d0520022f01c20e2115200241033a009818200220153b018a18200220033b018818200241b80e6a200110fc0420022f01b80e0d0520022f01ba0e2103200241b00e6a200110fc0420022f01b00e0d0520022f01b20e2115200241043a009818200220153b018e18200220033b018c18200241a80e6a200110fc0420022f01a80e0d0520022f01aa0e2103200241a00e6a200110fc0420022f01a00e0d0520022f01a20e2115200241053a009818200220153b019218200220033b019018200241980e6a200110fc0420022f01980e0d0520022f019a0e2103200241900e6a200110fc0420022f01900e0d0520022f01920e2115200241c0186a41086a221d20024180186a41086a290300370300200220153b019618200220033b019418200241c0186a41106a220320024180186a41106a290300370300200241063a00981820022002290380183703c018200241880e6a200110fc0420022f01880e0d0620022f018a0e211e20024180176a41086a201d290300220a37030020024180176a41106a20032903002211370300200241c0166a41086a221d200a370300200241c0166a41106a221f2011370300200220022903c018220a370380172002200a3703c01602402007422088220aa722152007a7470d00201541016a22032015490d1d20154101742220200320032020491b22034104200341044b1b220341ffffff3f712003464102742120200341057421030240024020150d0020024100360280180c010b200241043602881820022019360280182002200a4205863e0284180b200241c0186a2003202020024180186a107d20022802c818210320022802c0184101460d0320022802c41821192003410576ad21070b201920154105746a2203201c360200200320022903c0163702042003410c6a201d290300370200200341146a201f2903003702002003201e3b011c200742ffffffff0f83201541016aad4220868421072017417f6a22170d000b0b2019450d052007422088a741057422030d01201921030c020b2003450d190c180b201920036a2115201921030340200341206a22032015470d000b0b2007a72117200241800e6a200110ab010240024020022802800e0d0020022802840e221c200128020441246e22152015201c4b1bad42247e2207422088a70d192007a72215417f4c0d190240024020150d004104211e0c010b2015102c221e450d190b201541246ead2107024002400240024002400240201c450d00200241c0176a41186a211f0340200241f80d6a200110ab0120022802f80d0d0620022802fc0d2120200241003a009c18200241f00d6a200110fc0420022f01f00d0d0620022f01f20d2115200241e80d6a200110fc0420022f01e80d0d0620022f01ea0d211d200241013a009c182002201d3b018218200220153b018018200241e00d6a200110fc0420022f01e00d0d0520022f01e20d2115200241d80d6a200110fc0420022f01d80d0d0520022f01da0d211d200241023a009c182002201d3b018618200220153b018418200241d00d6a200110fc0420022f01d00d0d0520022f01d20d2115200241c80d6a200110fc0420022f01c80d0d0520022f01ca0d211d200241033a009c182002201d3b018a18200220153b018818200241c00d6a200110fc0420022f01c00d0d0520022f01c20d2115200241b80d6a200110fc0420022f01b80d0d0520022f01ba0d211d200241043a009c182002201d3b018e18200220153b018c18200241b00d6a200110fc0420022f01b00d0d0520022f01b20d2115200241a80d6a200110fc0420022f01a80d0d0520022f01aa0d211d200241053a009c182002201d3b019218200220153b019018200241a00d6a200110fc0420022f01a00d0d0520022f01a20d2115200241980d6a200110fc0420022f01980d0d0520022f019a0d211d200241063a009c182002201d3b019618200220153b019418200241900d6a200110fc0420022f01900d0d0520022f01920d2115200241880d6a200110fc0420022f01880d0d0520022f018a0d211d200241c0176a41106a222120024180186a41106a290300370300200241c0176a41086a222220024180186a41086a2903003703002002201d3b019a18200220153b019818201f200228029818360200200241073a009c182002200229038018220a3703c0182002200a3703c017200241800d6a200110fc0420022f01800d0d0620022f01820d2123200241c0166a41086a2022290300220a370300200241c0166a41106a20212903002211370300200241c0166a41186a201f280200221536020020024180166a41086a2221200a37030020024180166a41106a2222201137030020024180166a41186a22242015360200200220022903c017220a3703c0162002200a3703801602402007422088a7221d2007a7470d00201d41016a2215201d490d21201d4101742225201520152025491b22154104201541044b1bad42247e2207422088a74541027421152007a7212502400240201d0d0020024100360280180c010b20024104360288182002201e360280182002201d41246c360284180b200241c0186a2025201520024180186a107d20022802c818211520022802c0184101460d0320022802c418211e201541246ead21070b201e201d41246c6a2215202036020020152002290380163702042015410c6a2021290300370200201541146a20222903003702002015411c6a2024280200360200201520233b0120200742ffffffff0f83201d41016aad422086842107201c417f6a221c0d000b0b201e450d052007422088a741246c22150d01201e21150c020b2015450d1d0c1c0b201e20156a211c201e21150340201541246a2215201c470d000b0b2007a7211c200241f80c6a200110ab012015201e6b41246d21210240024020022802f80c0d0020022802fc0c221d200128020441286e22152015201d4b1bad42287e2207422088a70d1d2007a72215417f4c0d1d0240024020150d00410421200c010b2015102c2220450d1d0b201541286ead2107024002400240024002400240201d450d000340200241f00c6a200110ab0120022802f00c0d0620022802f40c2122200241003a00a018200241e80c6a200110fc0420022f01e80c0d0620022f01ea0c2115200241e00c6a200110fc0420022f01e00c0d0620022f01e20c211f200241013a00a0182002201f3b018218200220153b018018200241d80c6a200110fc0420022f01d80c0d0520022f01da0c2115200241d00c6a200110fc0420022f01d00c0d0520022f01d20c211f200241023a00a0182002201f3b018618200220153b018418200241c80c6a200110fc0420022f01c80c0d0520022f01ca0c2115200241c00c6a200110fc0420022f01c00c0d0520022f01c20c211f200241033a00a0182002201f3b018a18200220153b018818200241b80c6a200110fc0420022f01b80c0d0520022f01ba0c2115200241b00c6a200110fc0420022f01b00c0d0520022f01b20c211f200241043a00a0182002201f3b018e18200220153b018c18200241a80c6a200110fc0420022f01a80c0d0520022f01aa0c2115200241a00c6a200110fc0420022f01a00c0d0520022f01a20c211f200241053a00a0182002201f3b019218200220153b019018200241980c6a200110fc0420022f01980c0d0520022f019a0c2115200241900c6a200110fc0420022f01900c0d0520022f01920c211f200241063a00a0182002201f3b019618200220153b019418200241880c6a200110fc0420022f01880c0d0520022f018a0c2115200241800c6a200110fc0420022f01800c0d0520022f01820c211f200241073a00a0182002201f3b019a18200220153b019818200241f80b6a200110fc0420022f01f80b0d0520022f01fa0b2115200241f00b6a200110fc0420022f01f00b0d0520022f01f20b211f200241c0176a41106a222320024180186a41106a2903003703002002201f3b019e18200220153b019c18200241c0176a41186a221520024180186a41186a290300370300200241083a00a018200241c0176a41086a221f20024180186a41086a2903003703002002200229038018220a3703c0182002200a3703c017200241e80b6a200110fc0420022f01e80b0d0620022f01ea0b2124200241c0166a41086a201f290300220a370300200241c0166a41106a20232903002211370300200241c0166a41186a2015290300222637030020024180166a41086a2223200a37030020024180166a41106a2225201137030020024180166a41186a22272026370300200220022903c017220a3703c0162002200a3703801602402007422088a7221f2007a7470d00201f41016a2215201f490d25201f4101742228201520152028491b22154104201541044b1bad42287e2207422088a74541027421152007a7212802400240201f0d0020024100360280180c010b200241043602881820022020360280182002201f41286c360284180b200241c0186a2028201520024180186a107d20022802c818211520022802c0184101460d0320022802c4182120201541286ead21070b2020201f41286c6a2215202236020020152002290380163702042015410c6a2023290300370200201541146a20252903003702002015411c6a2027290300370200201520243b0124200742ffffffff0f83201f41016aad422086842107201d417f6a221d0d000b0b2020450d052007422088a741286c22150d01202021150c020b2015450d210c200b202020156a211d202021150340201541286a2215201d470d000b0b2007a7211d200241e00b6a200110ab01201520206b41286d21240240024020022802e00b0d0020022802e40b221f2001280204412c6e22152015201f4b1bad422c7e2207422088a70d212007a72215417f4c0d210240024020150d00410421220c010b2015102c2222450d210b2015412c6ead2107024002400240024002400240201f450d000340200241d80b6a200110ab0120022802d80b0d0620022802dc0b2125200241003a00a418200241d00b6a200110fc0420022f01d00b0d0620022f01d20b2115200241c80b6a200110fc0420022f01c80b0d0620022f01ca0b2123200241013a00a418200220233b018218200220153b018018200241c00b6a200110fc0420022f01c00b0d0520022f01c20b2115200241b80b6a200110fc0420022f01b80b0d0520022f01ba0b2123200241023a00a418200220233b018618200220153b018418200241b00b6a200110fc0420022f01b00b0d0520022f01b20b2115200241a80b6a200110fc0420022f01a80b0d0520022f01aa0b2123200241033a00a418200220233b018a18200220153b018818200241a00b6a200110fc0420022f01a00b0d0520022f01a20b2115200241980b6a200110fc0420022f01980b0d0520022f019a0b2123200241043a00a418200220233b018e18200220153b018c18200241900b6a200110fc0420022f01900b0d0520022f01920b2115200241880b6a200110fc0420022f01880b0d0520022f018a0b2123200241053a00a418200220233b019218200220153b019018200241800b6a200110fc0420022f01800b0d0520022f01820b2115200241f80a6a200110fc0420022f01f80a0d0520022f01fa0a2123200241063a00a418200220233b019618200220153b019418200241f00a6a200110fc0420022f01f00a0d0520022f01f20a2115200241e80a6a200110fc0420022f01e80a0d0520022f01ea0a2123200241073a00a418200220233b019a18200220153b019818200241e00a6a200110fc0420022f01e00a0d0520022f01e20a2115200241d80a6a200110fc0420022f01d80a0d0520022f01da0a2123200241083a00a418200220233b019e18200220153b019c18200241d00a6a200110fc0420022f01d00a0d0520022f01d20a2115200241c80a6a200110fc0420022f01c80a0d05200220022f01ca0a3b01a218200220153b01a018200241093a00a418200241c0186a41086a20024180186a41086a290300220a370300200241c0186a41106a20024180186a41106a2903002211370300200241c0186a41186a20024180186a41186a2903002226370300200241c0186a41206a20022802a0182215360200200220022903801822293703c018200241c0176a41206a22232015360200200241c0176a41186a22272026370300200241c0176a41106a22282011370300200241c0176a41086a222a200a370300200220293703c017200241c00a6a200110fc0420022f01c00a0d0620022f01c20a212b20024180176a41206a20232802002215360200200241c0166a41086a202a290300220a370300200241c0166a41106a20282903002211370300200241c0166a41186a20272903002226370300200241c0166a41206a201536020020024180166a41086a2227200a37030020024180166a41106a2228201137030020024180166a41186a222a202637030020024180166a41206a222c2015360200200220022903c017220a3703c0162002200a3703801602402007422088a722232007a7470d00202341016a22152023490d292023410174222d20152015202d491b22154104201541044b1bad422c7e2207422088a74541027421152007a7212d0240024020230d0020024100360280180c010b2002410436028818200220223602801820022023412c6c360284180b200241c0186a202d201520024180186a107d20022802c818211520022802c0184101460d0320022802c41821222015412c6ead21070b20222023412c6c6a2215202536020020152002290380163702042015410c6a2027290300370200201541146a20282903003702002015411c6a202a290300370200201541246a202c2802003602002015202b3b0128200742ffffffff0f83202341016aad422086842107201f417f6a221f0d000b0b2022450d052007422088a7412c6c22150d01202221150c020b2015450d250c240b202220156a211f2022211503402015412c6a2215201f470d000b0b2007a7211f200241b80a6a200110ab01201520226b412c6d21280240024020022802b80a0d0020022802bc0a2215200128020441306e2223202320154b1bad42307e2207422088a70d252007a72223417f4c0d250240024020230d00410421250c010b2023102c2225450d250b202341306ead21070240024002400240024002402015450d000340200241b00a6a200110ab0120022802b00a0d0620022802b40a212a200241003a00a818200241a80a6a200110fc0420022f01a80a0d0620022f01aa0a2123200241a00a6a200110fc0420022f01a00a0d0620022f01a20a2127200241013a00a818200220273b018218200220233b018018200241980a6a200110fc0420022f01980a0d0520022f019a0a2123200241900a6a200110fc0420022f01900a0d0520022f01920a2127200241023a00a818200220273b018618200220233b018418200241880a6a200110fc0420022f01880a0d0520022f018a0a2123200241800a6a200110fc0420022f01800a0d0520022f01820a2127200241033a00a818200220273b018a18200220233b018818200241f8096a200110fc0420022f01f8090d0520022f01fa092123200241f0096a200110fc0420022f01f0090d0520022f01f2092127200241043a00a818200220273b018e18200220233b018c18200241e8096a200110fc0420022f01e8090d0520022f01ea092123200241e0096a200110fc0420022f01e0090d0520022f01e2092127200241053a00a818200220273b019218200220233b019018200241d8096a200110fc0420022f01d8090d0520022f01da092123200241d0096a200110fc0420022f01d0090d0520022f01d2092127200241063a00a818200220273b019618200220233b019418200241c8096a200110fc0420022f01c8090d0520022f01ca092123200241c0096a200110fc0420022f01c0090d0520022f01c2092127200241073a00a818200220273b019a18200220233b019818200241b8096a200110fc0420022f01b8090d0520022f01ba092123200241b0096a200110fc0420022f01b0090d0520022f01b2092127200241083a00a818200220273b019e18200220233b019c18200241a8096a200110fc0420022f01a8090d0520022f01aa092123200241a0096a200110fc0420022f01a0090d0520022f01a2092127200241093a00a818200220273b01a218200220233b01a01820024198096a200110fc0420022f0198090d0520022f019a09212320024190096a200110fc0420022f0190090d05200220022f0192093b01a618200220233b01a4182002410a3a00a818200241c0186a41086a20024180186a41086a290300220a370300200241c0186a41106a20024180186a41106a2903002211370300200241c0186a41186a20024180186a41186a2903002226370300200241c0186a41206a20024180186a41206a29030022293703002002200229038018222e3703c018200241c0176a41206a22232029370300200241c0176a41186a22272026370300200241c0176a41106a222b2011370300200241c0176a41086a222c200a3703002002202e3703c01720024188096a200110fc0420022f0188090d0620022f018a09212d20024180176a41206a2023290300220a370300200241c0166a41086a202c2903002211370300200241c0166a41106a202b2903002226370300200241c0166a41186a20272903002229370300200241c0166a41206a200a37030020024180166a41086a222b201137030020024180166a41106a222c202637030020024180166a41186a222f202937030020024180166a41206a2230200a370300200220022903c017220a3703c0162002200a3703801602402007422088a722272007a7470d00202741016a22232027490d2d20274101742231202320232031491b22234104202341044b1bad42307e2207422088a74541027421232007a721310240024020270d0020024100360280180c010b200241043602881820022025360280182002202741306c360284180b200241c0186a2031202320024180186a107d20022802c818212320022802c0184101460d0320022802c4182125202341306ead21070b2025202741306c6a2223202a36020020232002290380163702042023410c6a202b290300370200202341146a202c2903003702002023411c6a202f290300370200202341246a20302903003702002023202d3b012c200742ffffffff0f83202741016aad4220868421072015417f6a22150d000b0b2025450d052007422088a741306c22150d01202521150c020b2023450d290c280b202520156a2123202521150340201541306a22152023470d000b0b2007a7212320024180096a200110ab01201520256b41306d212c024002402002280280090d002002280284092227200128020441346e2215201520274b1bad42347e2207422088a70d292007a72215417f4c0d290240024020150d004104212a0c010b2015102c222a450d290b201541346ead21070240024002400240024002402027450d000340200241f8086a200110ab0120022802f8080d0620022802fc08212d200241003a00ac18200241f0086a200110fc0420022f01f0080d0620022f01f2082115200241e8086a200110fc0420022f01e8080d0620022f01ea08212b200241013a00ac182002202b3b018218200220153b018018200241e0086a200110fc0420022f01e0080d0520022f01e2082115200241d8086a200110fc0420022f01d8080d0520022f01da08212b200241023a00ac182002202b3b018618200220153b018418200241d0086a200110fc0420022f01d0080d0520022f01d2082115200241c8086a200110fc0420022f01c8080d0520022f01ca08212b200241033a00ac182002202b3b018a18200220153b018818200241c0086a200110fc0420022f01c0080d0520022f01c2082115200241b8086a200110fc0420022f01b8080d0520022f01ba08212b200241043a00ac182002202b3b018e18200220153b018c18200241b0086a200110fc0420022f01b0080d0520022f01b2082115200241a8086a200110fc0420022f01a8080d0520022f01aa08212b200241053a00ac182002202b3b019218200220153b019018200241a0086a200110fc0420022f01a0080d0520022f01a208211520024198086a200110fc0420022f0198080d0520022f019a08212b200241063a00ac182002202b3b019618200220153b01941820024190086a200110fc0420022f0190080d0520022f019208211520024188086a200110fc0420022f0188080d0520022f018a08212b200241073a00ac182002202b3b019a18200220153b01981820024180086a200110fc0420022f0180080d0520022f0182082115200241f8076a200110fc0420022f01f8070d0520022f01fa07212b200241083a00ac182002202b3b019e18200220153b019c18200241f0076a200110fc0420022f01f0070d0520022f01f2072115200241e8076a200110fc0420022f01e8070d0520022f01ea07212b200241093a00ac182002202b3b01a218200220153b01a018200241e0076a200110fc0420022f01e0070d0520022f01e2072115200241d8076a200110fc0420022f01d8070d0520022f01da07212b2002410a3a00ac182002202b3b01a618200220153b01a418200241d0076a200110fc0420022f01d0070d0520022f01d2072115200241c8076a200110fc0420022f01c8070d05200220022f01ca073b01aa18200220153b01a8182002410b3a00ac18200241c0186a41086a20024180186a41086a290300220a370300200241c0186a41106a20024180186a41106a2903002211370300200241c0186a41186a20024180186a41186a2903002226370300200241c0186a41206a20024180186a41206a2903002229370300200241c0186a41286a20022802a81822153602002002200229038018222e3703c018200241c0176a41286a222b2015360200200241c0176a41206a222f2029370300200241c0176a41186a22302026370300200241c0176a41106a22312011370300200241c0176a41086a2232200a3703002002202e3703c017200241c0076a200110fc0420022f01c0070d0620022f01c207213320024180176a41286a202b280200221536020020024180176a41206a202f290300220a370300200241c0166a41086a20322903002211370300200241c0166a41106a20312903002226370300200241c0166a41186a20302903002229370300200241c0166a41206a200a370300200241c0166a41286a2015360200200220022903c017222e3703c01620024180166a41286a222f201536020020024180166a41206a2230200a37030020024180166a41186a2231202937030020024180166a41106a2232202637030020024180166a41086a223420113703002002202e3703801602402007422088a7222b2007a7470d00202b41016a2215202b490d31202b4101742235201520152035491b22154104201541044b1bad42347e2207422088a74541027421152007a7213502400240202b0d0020024100360280180c010b20024104360288182002202a360280182002202b41346c360284180b200241c0186a2035201520024180186a107d20022802c818211520022802c0184101460d0320022802c418212a201541346ead21070b202a202b41346c6a2215202d36020020152002290380163702042015410c6a2034290300370200201541146a20322903003702002015411c6a2031290300370200201541246a20302903003702002015412c6a202f280200360200201520333b0130200742ffffffff0f83202b41016aad4220868421072027417f6a22270d000b0b202a450d052007422088a741346c22150d01202a21150c020b2015450d2d0c2c0b202a20156a2127202a21150340201541346a22152027470d000b0b2007a72127200241b8076a200110ab012015202a6b41346d212f0240024020022802b8070d0020022802bc072215200128020441386e222b202b20154b1bad42387e2207422088a70d2d2007a7222b417f4c0d2d02400240202b0d004104212d0c010b202b102c222d450d2d0b202b41386ead21070240024002400240024002402015450d000340200241b0076a200110ab0120022802b0070d0620022802b4072131200241003a00b018200241a8076a200110fc0420022f01a8070d0620022f01aa07212b200241a0076a200110fc0420022f01a0070d0620022f01a2072130200241013a00b018200220303b0182182002202b3b01801820024198076a200110fc0420022f0198070d0520022f019a07212b20024190076a200110fc0420022f0190070d0520022f0192072130200241023a00b018200220303b0186182002202b3b01841820024188076a200110fc0420022f0188070d0520022f018a07212b20024180076a200110fc0420022f0180070d0520022f0182072130200241033a00b018200220303b018a182002202b3b018818200241f8066a200110fc0420022f01f8060d0520022f01fa06212b200241f0066a200110fc0420022f01f0060d0520022f01f2062130200241043a00b018200220303b018e182002202b3b018c18200241e8066a200110fc0420022f01e8060d0520022f01ea06212b200241e0066a200110fc0420022f01e0060d0520022f01e2062130200241053a00b018200220303b0192182002202b3b019018200241d8066a200110fc0420022f01d8060d0520022f01da06212b200241d0066a200110fc0420022f01d0060d0520022f01d2062130200241063a00b018200220303b0196182002202b3b019418200241c8066a200110fc0420022f01c8060d0520022f01ca06212b200241c0066a200110fc0420022f01c0060d0520022f01c2062130200241073a00b018200220303b019a182002202b3b019818200241b8066a200110fc0420022f01b8060d0520022f01ba06212b200241b0066a200110fc0420022f01b0060d0520022f01b2062130200241083a00b018200220303b019e182002202b3b019c18200241a8066a200110fc0420022f01a8060d0520022f01aa06212b200241a0066a200110fc0420022f01a0060d0520022f01a2062130200241093a00b018200220303b01a2182002202b3b01a01820024198066a200110fc0420022f0198060d0520022f019a06212b20024190066a200110fc0420022f0190060d0520022f01920621302002410a3a00b018200220303b01a6182002202b3b01a41820024188066a200110fc0420022f0188060d0520022f018a06212b20024180066a200110fc0420022f0180060d0520022f01820621302002410b3a00b018200220303b01aa182002202b3b01a818200241f8056a200110fc0420022f01f8050d0520022f01fa05212b200241f0056a200110fc0420022f01f0050d05200220022f01f2053b01ae182002202b3b01ac182002410c3a00b018200241c0186a41086a20024180186a41086a290300220a370300200241c0186a41106a20024180186a41106a2903002211370300200241c0186a41186a20024180186a41186a2903002226370300200241c0186a41206a20024180186a41206a2903002229370300200241c0186a41286a20024180186a41286a290300222e370300200220022903801822363703c018200241c0176a41286a222b202e370300200241c0176a41206a22302029370300200241c0176a41186a22322026370300200241c0176a41106a22332011370300200241c0176a41086a2234200a370300200220363703c017200241e8056a200110fc0420022f01e8050d0620022f01ea05213520024180176a41286a202b290300220a37030020024180176a41206a20302903002211370300200241c0166a41086a20342903002226370300200241c0166a41106a20332903002229370300200241c0166a41186a2032290300222e370300200241c0166a41206a2011370300200241c0166a41286a200a370300200220022903c01722363703c01620024180166a41286a2232200a37030020024180166a41206a2233201137030020024180166a41186a2234202e37030020024180166a41106a2237202937030020024180166a41086a22382026370300200220363703801602402007422088a722302007a7470d00203041016a222b2030490d3520304101742239202b202b2039491b222b4104202b41044b1bad42387e2207422088a745410274212b2007a721390240024020300d0020024100360280180c010b20024104360288182002202d360280182002203041386c360284180b200241c0186a2039202b20024180186a107d20022802c818212b20022802c0184101460d0320022802c418212d202b41386ead21070b202d203041386c6a222b2031360200202b200229038016370204202b410c6a2038290300370200202b41146a2037290300370200202b411c6a2034290300370200202b41246a2033290300370200202b412c6a2032290300370200202b20353b0134200742ffffffff0f83203041016aad4220868421072015417f6a22150d000b0b202d450d052007422088a741386c22150d01202d21150c020b202b450d310c300b202d20156a212b202d21150340201541386a2215202b470d000b0b2007a7212b200241e0056a200110ab012015202d6b41386d21320240024020022802e0050d0020022802e40522152001280204413c6e2230203020154b1bad423c7e2207422088a70d312007a72230417f4c0d310240024020300d00410421310c010b2030102c2231450d310b2030413c6ead21070240024002400240024002402015450d000340200241d8056a200110ab0120022802d8050d0620022802dc052134200241003a00b418200241d0056a200110fc0420022f01d0050d0620022f01d2052130200241c8056a200110fc0420022f01c8050d0620022f01ca052133200241013a00b418200220333b018218200220303b018018200241c0056a200110fc0420022f01c0050d0520022f01c2052130200241b8056a200110fc0420022f01b8050d0520022f01ba052133200241023a00b418200220333b018618200220303b018418200241b0056a200110fc0420022f01b0050d0520022f01b2052130200241a8056a200110fc0420022f01a8050d0520022f01aa052133200241033a00b418200220333b018a18200220303b018818200241a0056a200110fc0420022f01a0050d0520022f01a205213020024198056a200110fc0420022f0198050d0520022f019a052133200241043a00b418200220333b018e18200220303b018c1820024190056a200110fc0420022f0190050d0520022f019205213020024188056a200110fc0420022f0188050d0520022f018a052133200241053a00b418200220333b019218200220303b01901820024180056a200110fc0420022f0180050d0520022f0182052130200241f8046a200110fc0420022f01f8040d0520022f01fa042133200241063a00b418200220333b019618200220303b019418200241f0046a200110fc0420022f01f0040d0520022f01f2042130200241e8046a200110fc0420022f01e8040d0520022f01ea042133200241073a00b418200220333b019a18200220303b019818200241e0046a200110fc0420022f01e0040d0520022f01e2042130200241d8046a200110fc0420022f01d8040d0520022f01da042133200241083a00b418200220333b019e18200220303b019c18200241d0046a200110fc0420022f01d0040d0520022f01d2042130200241c8046a200110fc0420022f01c8040d0520022f01ca042133200241093a00b418200220333b01a218200220303b01a018200241c0046a200110fc0420022f01c0040d0520022f01c2042130200241b8046a200110fc0420022f01b8040d0520022f01ba0421332002410a3a00b418200220333b01a618200220303b01a418200241b0046a200110fc0420022f01b0040d0520022f01b2042130200241a8046a200110fc0420022f01a8040d0520022f01aa0421332002410b3a00b418200220333b01aa18200220303b01a818200241a0046a200110fc0420022f01a0040d0520022f01a204213020024198046a200110fc0420022f0198040d0520022f019a0421332002410c3a00b418200220333b01ae18200220303b01ac1820024190046a200110fc0420022f0190040d0520022f019204213020024188046a200110fc0420022f0188040d05200220022f018a043b01b218200220303b01b0182002410d3a00b418200241c0186a41086a223020024180186a41086a290300370300200241c0186a41106a223320024180186a41106a290300370300200241c0186a41186a223520024180186a41186a290300370300200241c0186a41206a223720024180186a41206a290300370300200241c0186a41286a223820024180186a41286a290300370300200241c0186a41306a223920022802b01836020020022002290380183703c018200241c0176a41306a223a2039280200360200200241c0176a41286a22392038290300370300200241c0176a41206a22382037290300370300200241c0176a41186a22372035290300370300200241c0176a41106a22352033290300370300200241c0176a41086a22332030290300370300200220022903c0183703c01720024180046a200110fc0420022f0180040d0620022f018204213b20024180176a41306a203a280200223036020020024180176a41286a2039290300220a37030020024180176a41206a20382903002211370300200241c0166a41086a22382033290300370300200241c0166a41106a22332035290300370300200241c0166a41186a22352037290300370300200241c0166a41206a22372011370300200241c0166a41286a2239200a370300200241c0166a41306a223a2030360200200220022903c0173703c01620024180166a41306a223c203a28020036020020024180166a41286a223a203929030037030020024180166a41206a2239203729030037030020024180166a41186a2237203529030037030020024180166a41106a2235203329030037030020024180166a41086a223d2038290300370300200220022903c0163703801602402007422088a722332007a7470d00203341016a22302033490d3920334101742238203020302038491b22304104203041044b1bad423c7e2207422088a74541027421302007a721380240024020330d0020024100360280180c010b2002410436028818200220313602801820022033413c6c360284180b200241c0186a2038203020024180186a107d20022802c818213020022802c0184101460d0320022802c41821312030413c6ead21070b20312033413c6c6a2230203436020020302002290380163702042030410c6a203d290300370200203041146a20352903003702002030411c6a2037290300370200203041246a20392903003702002030412c6a203a290300370200203041346a203c2802003602002030203b3b0138200742ffffffff0f83203341016aad4220868421072015417f6a22150d000b0b2031450d052007422088a7413c6c22150d01203121150c020b2030450d350c340b203120156a21302031211503402015413c6a22152030470d000b0b2007a72130200241f8036a200110ab01201520316b413c6d21350240024020022802f8030d0020022802fc03221520012802044106762233203320154b1b22334106742234417f4c0d350240024020330d00410421340c010b2034102c2234450d350b2033ad21070240024002400240024002402015450d000340200241f0036a200110ab0120022802f0030d0620022802f4032138200241003a00b818200241e8036a200110fc0420022f01e8030d0620022f01ea032133200241e0036a200110fc0420022f01e0030d0620022f01e2032137200241013a00b818200220373b018218200220333b018018200241d8036a200110fc0420022f01d8030d0520022f01da032133200241d0036a200110fc0420022f01d0030d0520022f01d2032137200241023a00b818200220373b018618200220333b018418200241c8036a200110fc0420022f01c8030d0520022f01ca032133200241c0036a200110fc0420022f01c0030d0520022f01c2032137200241033a00b818200220373b018a18200220333b018818200241b8036a200110fc0420022f01b8030d0520022f01ba032133200241b0036a200110fc0420022f01b0030d0520022f01b2032137200241043a00b818200220373b018e18200220333b018c18200241a8036a200110fc0420022f01a8030d0520022f01aa032133200241a0036a200110fc0420022f01a0030d0520022f01a2032137200241053a00b818200220373b019218200220333b01901820024198036a200110fc0420022f0198030d0520022f019a03213320024190036a200110fc0420022f0190030d0520022f0192032137200241063a00b818200220373b019618200220333b01941820024188036a200110fc0420022f0188030d0520022f018a03213320024180036a200110fc0420022f0180030d0520022f0182032137200241073a00b818200220373b019a18200220333b019818200241f8026a200110fc0420022f01f8020d0520022f01fa022133200241f0026a200110fc0420022f01f0020d0520022f01f2022137200241083a00b818200220373b019e18200220333b019c18200241e8026a200110fc0420022f01e8020d0520022f01ea022133200241e0026a200110fc0420022f01e0020d0520022f01e2022137200241093a00b818200220373b01a218200220333b01a018200241d8026a200110fc0420022f01d8020d0520022f01da022133200241d0026a200110fc0420022f01d0020d0520022f01d20221372002410a3a00b818200220373b01a618200220333b01a418200241c8026a200110fc0420022f01c8020d0520022f01ca022133200241c0026a200110fc0420022f01c0020d0520022f01c20221372002410b3a00b818200220373b01aa18200220333b01a818200241b8026a200110fc0420022f01b8020d0520022f01ba022133200241b0026a200110fc0420022f01b0020d0520022f01b20221372002410c3a00b818200220373b01ae18200220333b01ac18200241a8026a200110fc0420022f01a8020d0520022f01aa022133200241a0026a200110fc0420022f01a0020d0520022f01a20221372002410d3a00b818200220373b01b218200220333b01b01820024198026a200110fc0420022f0198020d0520022f019a02213320024190026a200110fc0420022f0190020d05200220022f0192023b01b618200220333b01b4182002410e3a00b818200241c0186a41086a223320024180186a41086a290300370300200241c0186a41106a223720024180186a41106a290300370300200241c0186a41186a223920024180186a41186a290300370300200241c0186a41206a223a20024180186a41206a290300370300200241c0186a41286a223b20024180186a41286a290300370300200241c0186a41306a223c20024180186a41306a29030037030020022002290380183703c018200241c0176a41306a223d203c290300370300200241c0176a41286a223c203b290300370300200241c0176a41206a223b203a290300370300200241c0176a41186a223a2039290300370300200241c0176a41106a22392037290300370300200241c0176a41086a22372033290300370300200220022903c0183703c01720024188026a200110fc0420022f0188020d0620022f018a02213e20024180176a41306a203d290300220a37030020024180176a41286a203c290300221137030020024180176a41206a203b2903002226370300200241c0166a41086a22332037290300370300200241c0166a41106a22372039290300370300200241c0166a41186a2239203a290300370300200241c0166a41206a223a2026370300200241c0166a41286a223b2011370300200241c0166a41306a223c200a370300200220022903c0173703c01620024180166a41306a223d203c29030037030020024180166a41286a223c203b29030037030020024180166a41206a223b203a29030037030020024180166a41186a223a203929030037030020024180166a41106a2239203729030037030020024180166a41086a223f2033290300370300200220022903c0163703801602402007422088220aa722372007a7470d00203741016a22332037490d3d20374101742240203320332040491b22334104203341044b1b223341ffffff1f712033464102742140203341067421330240024020370d0020024100360280180c010b200241043602881820022034360280182002200a4206863e0284180b200241c0186a2033204020024180186a107d20022802c818213320022802c0184101460d0320022802c41821342033410676ad21070b203420374106746a2233203836020020332002290380163702042033410c6a203f290300370200203341146a20392903003702002033411c6a203a290300370200203341246a203b2903003702002033412c6a203c290300370200203341346a203d2903003702002033203e3b013c200742ffffffff0f83203741016aad4220868421072015417f6a22150d000b0b2034450d052007422088a741067422150d01203421150c020b2033450d390c380b203420156a2133203421150340201541c0006a22152033470d000b0b2007a7213320024180026a200110ab0102402002280280020d002002280284022237200128020441c4006e2238203820374b1bad42c4007e2207422088a70d382007a72238417f4c0d380240024020380d00410421390c010b2038102c2239450d380b203841c4006ead21070240024002400240024002402037450d000340200241f8016a200110ab0120022802f8010d0620022802fc01213b200241003a00bc18200241f0016a200110fc0420022f01f0010d0620022f01f2012138200241e8016a200110fc0420022f01e8010d0620022f01ea01213a200241013a00bc182002203a3b018218200220383b018018200241e0016a200110fc0420022f01e0010d0520022f01e2012138200241d8016a200110fc0420022f01d8010d0520022f01da01213a200241023a00bc182002203a3b018618200220383b018418200241d0016a200110fc0420022f01d0010d0520022f01d2012138200241c8016a200110fc0420022f01c8010d0520022f01ca01213a200241033a00bc182002203a3b018a18200220383b018818200241c0016a200110fc0420022f01c0010d0520022f01c2012138200241b8016a200110fc0420022f01b8010d0520022f01ba01213a200241043a00bc182002203a3b018e18200220383b018c18200241b0016a200110fc0420022f01b0010d0520022f01b2012138200241a8016a200110fc0420022f01a8010d0520022f01aa01213a200241053a00bc182002203a3b019218200220383b019018200241a0016a200110fc0420022f01a0010d0520022f01a201213820024198016a200110fc0420022f0198010d0520022f019a01213a200241063a00bc182002203a3b019618200220383b01941820024190016a200110fc0420022f0190010d0520022f019201213820024188016a200110fc0420022f0188010d0520022f018a01213a200241073a00bc182002203a3b019a18200220383b01981820024180016a200110fc0420022f0180010d0520022f0182012138200241f8006a200110fc0420022f01780d0520022f017a213a200241083a00bc182002203a3b019e18200220383b019c18200241f0006a200110fc0420022f01700d0520022f01722138200241e8006a200110fc0420022f01680d0520022f016a213a200241093a00bc182002203a3b01a218200220383b01a018200241e0006a200110fc0420022f01600d0520022f01622138200241d8006a200110fc0420022f01580d0520022f015a213a2002410a3a00bc182002203a3b01a618200220383b01a418200241d0006a200110fc0420022f01500d0520022f01522138200241c8006a200110fc0420022f01480d0520022f014a213a2002410b3a00bc182002203a3b01aa18200220383b01a818200241c0006a200110fc0420022f01400d0520022f01422138200241386a200110fc0420022f01380d0520022f013a213a2002410c3a00bc182002203a3b01ae18200220383b01ac18200241306a200110fc0420022f01300d0520022f01322138200241286a200110fc0420022f01280d0520022f012a213a2002410d3a00bc182002203a3b01b218200220383b01b018200241206a200110fc0420022f01200d0520022f01222138200241186a200110fc0420022f01180d0520022f011a213a2002410e3a00bc182002203a3b01b618200220383b01b418200241106a200110fc0420022f01100d0520022f01122138200241086a200110fc0420022f01080d05200220022f010a3b01ba18200220383b01b8182002410f3a00bc18200241c0186a41086a223820024180186a41086a290300370300200241c0186a41106a223a20024180186a41106a290300370300200241c0186a41186a223c20024180186a41186a290300370300200241c0186a41206a223d20024180186a41206a290300370300200241c0186a41286a223e20024180186a41286a290300370300200241c0186a41306a223f20024180186a41306a290300370300200241c0186a41386a224020022802b81836020020022002290380183703c018200241c0176a41086a22412038290300370300200241c0176a41106a2238203a290300370300200241c0176a41186a223a203c290300370300200241c0176a41206a223c203d290300370300200241c0176a41286a223d203e290300370300200241c0176a41306a223e203f290300370300200241c0176a41386a223f2040280200360200200220022903c0183703c0172002200110fc0420022f01000d0620022f0102214020024180176a41386a203f280200223f36020020024180176a41306a203e290300220a37030020024180176a41286a203d290300221137030020024180176a41206a203c2903002226370300200241c0166a41086a223c2041290300370300200241c0166a41106a223d2038290300370300200241c0166a41186a2238203a290300370300200241c0166a41206a223a2026370300200241c0166a41286a223e2011370300200241c0166a41306a2241200a370300200241c0166a41386a2242203f360200200220022903c0173703c01620024180166a41386a223f204228020036020020024180166a41306a2242204129030037030020024180166a41286a2241203e29030037030020024180166a41206a223e203a29030037030020024180166a41186a2243203829030037030020024180166a41106a2244203d29030037030020024180166a41086a223d203c290300370300200220022903c0163703801602402007422088a7223a2007a7470d00203a41016a2238203a490d40203a410174223c20382038203c491b22384104203841044b1bad42c4007e2207422088a74541027421382007a7213c02400240203a0d0020024100360280180c010b200241043602881820022039360280182002203a41c4006c360284180b200241c0186a203c203820024180186a107d20022802c818213820022802c0184101460d0320022802c4182139203841c4006ead21070b2039203a41c4006c6a2238203b36020020382002290380163702042038410c6a203d290300370200203841146a20442903003702002038411c6a2043290300370200203841246a203e2903003702002038412c6a2041290300370200203841346a20422903003702002038413c6a203f280200360200203820403b0140200742ffffffff0f83203a41016aad4220868421072037417f6a22370d000b0b2039450d05200420066b41037521372005200b6b4104752105200320196b4105752103201520346b41067521152007a721382007422088a741c4006c22040d01203921040c020b2038450d3c0c3b0b203920046a2101203921040340200441c4006a22042001470d000b0b2000200c36020420002006360200200041b8016a2038360200200041b4016a2039360200200041b0016a2015360200200041ac016a2033360200200041a8016a2034360200200041a4016a2035360200200041a0016a20303602002000419c016a203136020020004198016a203236020020004194016a202b36020020004190016a202d3602002000418c016a202f36020020004188016a202736020020004184016a202a36020020004180016a202c360200200041fc006a2023360200200041f8006a2025360200200041f4006a2028360200200041f0006a201f360200200041ec006a2022360200200041e8006a2024360200200041e4006a201d360200200041e0006a2020360200200041dc006a2021360200200041d8006a201c360200200041d4006a201e360200200041d0006a2003360200200041cc006a2017360200200041c8006a2019360200200041c4006a201b360200200041c0006a20133602002000413c6a2016360200200041386a201a360200200041346a200e360200200041306a20143602002000412c6a2018360200200041286a2009360200200041246a200f360200200041206a20053602002000411c6a2012360200200041186a200b360200200041146a2010360200200041106a200d3602002000410c6a2008360200200041086a2037360200200041bc016a200420396b41c4006d3602000c380b200241003a00bc180b2007a72204450d00200441c4006c450d002039102e0b20004100360200203341ffffff1f71450d032034102e0c030b200241003a00b8180b200742ffffff1f83500d002034102e0b200041003602000b2030450d032030413c6c450d032031102e0c030b200241003a00b4180b2007a72204450d002004413c6c450d002031102e0b200041003602000b202b450d03202b41386c450d03202d102e0c030b200241003a00b0180b2007a72204450d00200441386c450d00202d102e0b200041003602000b2027450d03202741346c450d03202a102e0c030b200241003a00ac180b2007a72204450d00200441346c450d00202a102e0b200041003602000b2023450d03202341306c450d032025102e0c030b200241003a00a8180b2007a72204450d00200441306c450d002025102e0b200041003602000b201f450d03201f412c6c450d032022102e0c030b200241003a00a4180b2007a72204450d002004412c6c450d002022102e0b200041003602000b201d450d03201d41286c450d032020102e0c030b200241003a00a0180b2007a72204450d00200441286c450d002020102e0b200041003602000b201c450d03201c41246c450d03201e102e0c030b200241003a009c180b2007a72204450d00200441246c450d00201e102e0b200041003602000b201741ffffff3f71450d032019102e0c030b200241003a0098180b200742ffffff3f83500d002019102e0b200041003602000b2013450d032013411c6c450d032016102e0c030b200241003a0094180b2007a72204450d002004411c6c450d002016102e0b200041003602000b200e450d03200e41186c450d032014102e0c030b200241003a0090180b2007a72204450d00200441186c450d002014102e0b200041003602000b2009450d03200941146c450d03200f102e0c030b200241003a008c180b2007a72204450d00200441146c450d00200f102e0b200041003602000b201241ffffffff0071450d03200b102e0c030b200241003a0088180b200742ffffffff0083500d00200b102e0b200041003602000b200d450d00200d410c6c450d002008102e0b200c41ffffffff0171450d002006102e0b200241c0196a24000f0b1036000b1038000bc61e01097f230041f0006b2202240020024200370204024020012802082203450d0020034103742104200128020041046a21030340200220032f0100109806200341086a2103200441786a22040d000b0b0240200141146a2802002203450d002003410c6c2104200128020c41086a2103034020032f0100210520022003417c6a2f0100109806200220051098062003410c6a2103200441746a22040d000b0b0240200141206a2802002203450d00200341047421042001280218410c6a210303402002200341786a2f010010980620022003417c6a2f0100109806200220032f0100109806200341106a2103200441706a22040d000b0b02402001412c6a2802002203450d00200341146c2104200128022441106a210303402002200341746a2f01001098062002200341786a2f010010980620022003417c6a2f0100109806200220032f0100109806200341146a21032004416c6a22040d000b0b0240200141386a2802002203450d00200341186c2104200128023041146a210303402002200341706a2f01001098062002200341746a2f01001098062002200341786a2f010010980620022003417c6a2f0100109806200220032f0100109806200341186a2103200441686a22040d000b0b0240200141c4006a2802002203450d00200128023c21052003411c6c21064100210403402002200520046a220341046a2f01001098062002200341086a2f010010980620022003410c6a2f01001098062002200341106a2f01001098062002200341146a2f01001098062002200341186a2f010010980620062004411c6a2204470d000b0b0240200141d0006a2802002203450d0020012802482105200341057421064100210403402002200520046a220341046a2f01001098062002200341086a2f010010980620022003410c6a2f01001098062002200341106a2f01001098062002200341146a2f01001098062002200341186a2f010010980620022003411c6a2f01001098062006200441206a2204470d000b0b0240200141dc006a2802002203450d0020012802542105200341246c21064100210403402002200520046a220341046a2f01001098062002200341086a2f010010980620022003410c6a2f01001098062002200341106a2f01001098062002200341146a2f01001098062002200341186a2f010010980620022003411c6a2f01001098062002200341206a2f01001098062006200441246a2204470d000b0b0240200141e8006a2802002203450d0020012802602105200341286c21064100210403402002200520046a220341046a2f01001098062002200341086a2f010010980620022003410c6a2f01001098062002200341106a2f01001098062002200341146a2f01001098062002200341186a2f010010980620022003411c6a2f01001098062002200341206a2f01001098062002200341246a2f01001098062006200441286a2204470d000b0b0240200141f4006a2802002203450d00200128026c21052003412c6c21064100210403402002200520046a220341046a2f01001098062002200341086a2f010010980620022003410c6a2f01001098062002200341106a2f01001098062002200341146a2f01001098062002200341186a2f010010980620022003411c6a2f01001098062002200341206a2f01001098062002200341246a2f01001098062002200341286a2f010010980620062004412c6a2204470d000b0b024020014180016a2802002203450d0020012802782105200341306c21064100210403402002200520046a220341046a2f01001098062002200341086a2f010010980620022003410c6a2f01001098062002200341106a2f01001098062002200341146a2f01001098062002200341186a2f010010980620022003411c6a2f01001098062002200341206a2f01001098062002200341246a2f01001098062002200341286a2f010010980620022003412c6a2f01001098062006200441306a2204470d000b0b02402001418c016a2802002203450d002001280284012105200341346c21064100210403402002200520046a220341046a2f01001098062002200341086a2f010010980620022003410c6a2f01001098062002200341106a2f01001098062002200341146a2f01001098062002200341186a2f010010980620022003411c6a2f01001098062002200341206a2f01001098062002200341246a2f01001098062002200341286a2f010010980620022003412c6a2f01001098062002200341306a2f01001098062006200441346a2204470d000b0b024020014198016a2802002203450d002001280290012105200341386c21064100210403402002200520046a220341046a2f01001098062002200341086a2f010010980620022003410c6a2f01001098062002200341106a2f01001098062002200341146a2f01001098062002200341186a2f010010980620022003411c6a2f01001098062002200341206a2f01001098062002200341246a2f01001098062002200341286a2f010010980620022003412c6a2f01001098062002200341306a2f01001098062002200341346a2f01001098062006200441386a2204470d000b0b0240200141a4016a2802002203450d00200128029c0121052003413c6c21064100210403402002200520046a220341046a2f01001098062002200341086a2f010010980620022003410c6a2f01001098062002200341106a2f01001098062002200341146a2f01001098062002200341186a2f010010980620022003411c6a2f01001098062002200341206a2f01001098062002200341246a2f01001098062002200341286a2f010010980620022003412c6a2f01001098062002200341306a2f01001098062002200341346a2f01001098062002200341386a2f010010980620062004413c6a2204470d000b0b0240200141b0016a2802002203450d0020012802a8012105200341067421064100210403402002200520046a220341046a2f01001098062002200341086a2f010010980620022003410c6a2f01001098062002200341106a2f01001098062002200341146a2f01001098062002200341186a2f010010980620022003411c6a2f01001098062002200341206a2f01001098062002200341246a2f01001098062002200341286a2f010010980620022003412c6a2f01001098062002200341306a2f01001098062002200341346a2f01001098062002200341386a2f010010980620022003413c6a2f01001098062006200441c0006a2204470d000b0b0240200141bc016a2802002203450d0020012802b4012105200341c4006c21014100210403402002200520046a220341046a2f01001098062002200341086a2f010010980620022003410c6a2f01001098062002200341106a2f01001098062002200341146a2f01001098062002200341186a2f010010980620022003411c6a2f01001098062002200341206a2f01001098062002200341246a2f01001098062002200341286a2f010010980620022003412c6a2f01001098062002200341306a2f01001098062002200341346a2f01001098062002200341386a2f010010980620022003413c6a2f01001098062002200341c0006a2f01001098062001200441c4006a2204470d000b0b02400240200228020422050d004100210541002103410021060c010b200228020821062002280200210420052103034020052f010621012004450d012004417f6a2104200520014102746a41206a2802002105200328022021030c000b0b200241246a2001360200200241206a200536020020022006360228200242003703182002200336021420022004360210024002400240024002400240024002402006450d0020022006417f6a22063602282003450d0141002105024002400340200520032f0106490d010240200328020022010d002003102e410021030c030b20032f010421052003102e200441016a2104200121030c000b0b200541016a2101200320054101746a41086a2f010021072004450d00200320014102746a41206a2802002103024020044101460d00410121050340200328022021032004200541016a2205470d000b0b410021010b200220013602182002200336021420024100360210417f200641016a220320032006491b220420046a22032004490d052003417f4c0d052003102c2208450d02200820073b0100200241306a41186a200241106a41186a2802002204360200200241306a41106a200241106a41106a290300370300200241306a41086a200241106a41086a2903003703002002200229031037033041012106200341017621072004450d0620022004417f6a220936024820022802342203450d032002280238210520022802302104024002400340200520032f0106490d010240200328020022010d002003102e410021030c030b20032f010421052003102e200441016a2104200121030c000b0b200541016a2101200320054101746a41086a2f0100210a2004450d00200320014102746a41206a2802002103024020044101460d00410121050340200328022021032004200541016a2205470d000b0b410021010b20022001360238200220033602342002410036023041012106034002400240024020072006470d00200720066b417f200941016a220320032009491b22034f0d00200620036a22032006490d09200741017422042003200420034b1b22034104200341044b1b220320036a220520034f41017421030240024020070d00200241003602600c010b2002410236026820022004360264200220083602600b200241d0006a20052003200241e0006a107d2002280258210320022802504101460d0120022802542108200341017621070b200820064101746a200a3b0100200641016a2106200228024822030d010c090b20030d040c070b20022003417f6a220936024820022802342203450d05410120022802306b210420022802382105024002400340200520032f0106490d010240200328020022010d002003102e410021030c030b20032f010421052003102e2004417f6a2104200121030c000b0b200541016a2101200320054101746a41086a2f0100210a20044101460d00200320014102746a41206a280200210302402004450d004100210503402003280220210320042005417f6a2205470d000b0b410021010b2002200136023820022003360234200241003602300c000b0b2000410036020820004202370200200241106a10bf020c060b41e8aac700412b41f8b7c0001039000b1036000b41e8aac700412b41f8b7c0001039000b41e8aac700412b41f8b7c0001039000b1038000b200241306a10bf022000200636020820002007360204200020083602000b200241f0006a24000b870e010c7f024002400240024002400240024002400240024002400240024020002802042202450d00200028020021030c010b4120102c2202450d0141002103200241003b01062002410036020020002002360204200041003602000b200141ffff037121040240034020022f01062205410174210641002107417f210802400340024020062007470d00200521080c020b200220076a2109200841016a2108200741026a2107417f200941086a2f01002209200447200920044b1b41016a0e03010300010b0b02402003450d002003417f6a2103200220084102746a41206a28020021020c010b0b0240024020022f01062207410a4b0d00200241086a2104200741016a21090240200841016a220620074b0d00200420064101746a200420084101746a20092008417f736a41017410ea081a0b200420084101746a20013b0100200220093b01060c010b410521074100210602400240200841054f0d0041042107200821040c010b41052104024002402008417b6a0e020201000b200841796a210441012106410621070c010b41002104410121060b4120102c2208450d02200841003b010620084100360200200820022f010622032007417f736a22093b01062009410c4f0d032003200741016a22056b2009470d04200241086a220320074101746a2f0100210a200841086a200320054101746a200941017410e9081a200220073b01062008200220061b220741086a210920072f0106220341016a21060240200441016a220520034b0d00200920054101746a200920044101746a20062004417f736a41017410ea081a0b200920044101746a20013b0100200720063b0106024002400240200228020022030d00410021010c010b410021012008210b200a210c03404101450d0820022f0104210920032f01062205410b490d024100210641042107024020094105490d0020092107024002402009417b6a0e020201000b200941796a210941012106410621070c010b4100210941012106410521070b41d000102c2208450d05200841003b010620084100360200200820032f0106220a2007417f736a22023b01062002410c4f0d09200a200741016a22046b2002470d0a200341086a220d20074101746a2f0100210a200841086a200d20044101746a200241017410e9081a200320073b010620082f0106220241016a210d2002410c4f0d0b200520076b2207200d470d0c200141016a2101200841206a200320044102746a41206a200741027410e9081a4100210702400340200820074102746a41206a280200220420073b0104200420083602002007200720024922046a220720024b0d0120040d000b0b2008200320061b220441086a210220042f0106220541016a21060240200941016a220720054b0d00200220074101746a200220094101746a2009417f7320066a41017410ea081a0b200220094101746a200c3b0100200441206a21020240200941026a220c200541026a22054f0d002002200c4102746a200220074102746a2007417f7320056a41027410ea081a0b200220074102746a200b360200200420063b01060240200720054f0d00200420094102746a41246a2107034020072802002202200941016a22093b010420022004360200200741046a210720062009470d000b0b200321022003280200220721032008210b200a210c20070d000b0b20002802042202450d0b2000280200210441d000102c2207450d0320072002360220200741003b010620074100360200200241003b010420022007360200200020073602042000200441016a36020020042001470d0c20072f01062202410b4f0d0d2007200241016a22043b0106200720024101746a41086a200a3b0100200720044102746a41206a2008360200200820043b0104200820073602002000200028020841016a3602080f0b200941016a2107200341086a210220032f0106220841016a21040240200920084f22050d00200220074101746a200220094101746a2009417f7320046a41017410ea081a0b200220094101746a200c3b0100200341206a2102200841026a2106024020050d00200941027420026a41086a200220074102746a2007417f7320066a41027410ea081a0b200220074102746a200b360200200320043b0106200720064f0d00200841016a210420032007417f6a22074102746a41246a2108034020082802002202200741016a22073b010420022003360200200841046a210820042007470d000b0b2000200028020841016a3602080b0f0b1036000b2009410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b41ac9cc700413541e49cc7001039000b2002410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b200d410c41f49cc700104d000b41f49bc7004128419c9cc7001039000b41e8aac700412b4194abc7001039000b41e899c700413041989ac7001039000b41a89ac700412041c89ac7001039000bfd8c0103087f057ebb017f230041e00a6b22042400200420033602bc08200441f8096a4200370300200441f0096a4280808080c000370300200441e0096a4200370300200441d8096a4280808080c000370300200441c0086a4188016a4200370300200441c0096a4280808080c000370300200441b0096a4200370300200441a8096a4280808080c00037030020044198096a420037030020044190096a4280808080c00037030020044180096a4200370300200441c0086a41386a4280808080c000370300200441c0086a41286a4200370300200441c0086a41206a4280808080c000370300200441c0086a41106a4200370300200442043703e809200442043703d009200442043703b809200442043703a0092004420437038809200442043703f008200442043703d80820044280808080c0003703c808200442043703c0082001280200220520012802082203412c6c22066a210720012802042108200521010240024002402003450d00200641546a2103200441a00a6a41186a2109200441a00a6a41106a210a200441a00a6a41086a210b2005210602400340200641046a290200210c200628020021012009200641246a290200370300200a2006411c6a290200370300200b200641146a29020037030020042006410c6a2902003703a00a024020010d002006412c6a21010c030b200441800a6a41186a2009290300220d370300200441800a6a41106a200a290300220e370300200441800a6a41086a200b290300220f370300200420042903a00a22103703800a2009200d370300200a200e370300200b200f370300200420103703a00a02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200c422088a70e1113000102030405060708090a0b0c0d0e0f140b2002280200200441a00a6a10a0022211450d14201128020021122004200441bc086a2001109a06024020042f01002213450d0020042f010221140240024020042802c808221120042802c408470d00201141016a22152011490da201201141017422162015201620154b1b22154104201541044b1b221541ffffffff01712015464102742116201541037421150240024020110d00200441003602d00a0c010b200441043602d80a200420042802c0083602d00a200420114103743602d40a0b200441c00a6a20152016200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602c008200420114103763602c40820042802c80821110b20042802c00820114103746a22112014201720131b22173b010420112012360200200420042802c80841016a3602c8080c110b2011450da0010ca2010b20004281808080203702000c9c010b2002280200200441a00a6a10a0022211450d1420112802002112200441106a200441bc086a2001109a0620042f01102213450d1520042f0112211420012f01202115200441086a200441bc086a200141226a109a06024020042f01082216450d0020042f010a21180240024020042802d408221120042802d008470d00201141016a22192011490da1012011410174221a2019201a20194b1b22194104201941044b1bad420c7e220d422088a7454102742119200da7211a0240024020110d00200441003602d00a0c010b200441043602d80a200420042802cc083602d00a20042011410c6c3602d40a0b200441c00a6a201a2019200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602cc0820042011410c6e3602d00820042802d40821110b20042802cc082011410c6c6a22112018201b20161b221b3b010820112014201c20131b221c3b010420112012360200201141066a20153b0100200420042802d40841016a3602d4080c100b20110da1010c9f010b20004281808080203702000c9b010b2002280200200441a00a6a10a0022211450d1520112802002112200441286a200441bc086a2001109a0620042f01282213450d1620042f012a211420012f01202115200441206a200441bc086a200141226a109a0620042f01202216450d1720042f01222118200141c2006a2f01002119200441186a200441bc086a200141c4006a109a06024020042f0118221a450d0020042f011a211d0240024020042802e008221120042802dc08470d00201141016a221e2011490da0012011410174221f201e201f201e4b1b221e4104201e41044b1b221e41ffffffff0071201e46410274211f201e410474211e0240024020110d00200441003602d00a0c010b200420042802d8083602d00a200441043602d80a200420114104743602d40a0b200441c00a6a201e201f200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602d808200420114104763602dc0820042802e00821110b20042802d80820114104746a2211201d2020201a1b22203b010c20112014202120131b22213b0104201120123602002011410a6a20193b0100201141086a2018202220161b22223b0100201141066a20153b0100200420042802e00841016a3602e0080c0f0b20110da0010c9e010b20004281808080203702000c9a010b2002280200200441a00a6a10a0022211450d1720112802002112200441c8006a200441bc086a2001109a0620042f01482213450d1820042f014a211420012f01202115200441c0006a200441bc086a200141226a109a0620042f01402216450d1920042f01422118200141c2006a2f01002119200441386a200441bc086a200141c4006a109a0620042f0138221a450d1a20042f013a211d200141e4006a2f0100211e200441306a200441bc086a200141e6006a109a06024020042f0130221f450d0020042f013221230240024020042802ec08221120042802e808470d00201141016a22242011490d9f01201141017422252024202520244b1b22244104202441044b1bad42147e220d422088a7454102742124200da721250240024020110d00200441003602d00a0c010b200441043602d80a200420042802e4083602d00a2004201141146c3602d40a0b200441c00a6a20252024200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602e4082004201141146e3602e80820042802ec0821110b20042802e408201141146c6a221120232026201f1b22263b011020112014202720131b22273b0104201120123602002011410e6a201e3b01002011410c6a201d2028201a1b22283b01002011410a6a20193b0100201141086a2018202920161b22293b0100201141066a20153b0100200420042802ec0841016a3602ec080c0e0b20110d9f010c9d010b20004281808080203702000c99010b2002280200200441a00a6a10a0022211450d1a20112802002112200441f0006a200441bc086a2001109a0620042f01702213450d1b20042f0172211420012f01202115200441e8006a200441bc086a200141226a109a0620042f01682216450d1c20042f016a2118200141c2006a2f01002119200441e0006a200441bc086a200141c4006a109a0620042f0160221a450d1d20042f0162211d200141e4006a2f0100211e200441d8006a200441bc086a200141e6006a109a0620042f0158221f450d1e20042f015a212320014186016a2f01002124200441d0006a200441bc086a20014188016a109a06024020042f01502225450d0020042f0152212a0240024020042802f808221120042802f408470d00201141016a222b2011490d9e012011410174222c202b202c202b4b1b222b4104202b41044b1bad42187e220d422088a745410274212b200da7212c0240024020110d00200441003602d00a0c010b200441043602d80a200420042802f0083602d00a2004201141186c3602d40a0b200441c00a6a202c202b200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602f0082004201141186e3602f40820042802f80821110b20042802f008201141186c6a2211202a202d20251b222d3b011420112014202e20131b222e3b010420112012360200201141126a20243b0100201141106a2023202f201f1b222f3b01002011410e6a201e3b01002011410c6a201d2030201a1b22303b01002011410a6a20193b0100201141086a2018203120161b22313b0100201141066a20153b0100200420042802f80841016a3602f8080c0d0b20110d9e010c9c010b20004281808080203702000c98010b2002280200200441a00a6a10a0022211450d1e20112802002112200441a0016a200441bc086a2001109a0620042f01a0012213450d1f20042f01a201211420012f0120211520044198016a200441bc086a200141226a109a0620042f0198012216450d2020042f019a012118200141c2006a2f0100211920044190016a200441bc086a200141c4006a109a0620042f019001221a450d2120042f019201211d200141e4006a2f0100211e20044188016a200441bc086a200141e6006a109a0620042f018801221f450d2220042f018a01212320014186016a2f0100212420044180016a200441bc086a20014188016a109a0620042f0180012225450d2320042f018201212a200141a8016a2f0100212b200441f8006a200441bc086a200141aa016a109a06024020042f0178222c450d0020042f017a2132024002402004280284092211200428028009470d00201141016a22332011490d9d01201141017422342033203420334b1b22334104203341044b1bad421c7e220d422088a7454102742133200da721340240024020110d00200441003602d00a0c010b200441043602d80a200420042802fc083602d00a20042011411c6c3602d40a0b200441c00a6a20342033200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602fc0820042011411c6e3602800920042802840921110b20042802fc082011411c6c6a221120322035202c1b22353b011820112014203620131b22363b010420112012360200201141166a202b3b0100201141146a202a203720251b22373b0100201141126a20243b0100201141106a20232038201f1b22383b01002011410e6a201e3b01002011410c6a201d2039201a1b22393b01002011410a6a20193b0100201141086a2018203a20161b223a3b0100201141066a20153b0100200420042802840941016a360284090c0c0b20110d9d010c9b010b20004281808080203702000c97010b2002280200200441a00a6a10a0022211450d2320112802002112200441d8016a200441bc086a2001109a0620042f01d8012213450d2420042f01da01211420012f01202115200441d0016a200441bc086a200141226a109a0620042f01d0012216450d2520042f01d2012118200141c2006a2f01002119200441c8016a200441bc086a200141c4006a109a0620042f01c801221a450d2620042f01ca01211d200141e4006a2f0100211e200441c0016a200441bc086a200141e6006a109a0620042f01c001221f450d2720042f01c201212320014186016a2f01002124200441b8016a200441bc086a20014188016a109a0620042f01b8012225450d2820042f01ba01212a200141a8016a2f0100212b200441b0016a200441bc086a200141aa016a109a0620042f01b001222c450d2920042f01b2012132200141ca016a2f01002133200441a8016a200441bc086a200141cc016a109a06024020042f01a8012234450d0020042f01aa01213b024002402004280290092211200428028c09470d00201141016a223c2011490d9c012011410174223d203c203d203c4b1b223c4104203c41044b1b223c41ffffff3f71203c46410274213d203c410574213c0240024020110d00200441003602d00a0c010b200441043602d80a20042004280288093602d00a200420114105743602d40a0b200441c00a6a203c203d200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a360288092004201141057636028c0920042802900921110b20042802880920114105746a2211203b203e20341b223e3b011c20112014203f20131b223f3b0104201120123602002011411a6a20333b0100201141186a20322040202c1b22403b0100201141166a202b3b0100201141146a202a204120251b22413b0100201141126a20243b0100201141106a20232042201f1b22423b01002011410e6a201e3b01002011410c6a201d2043201a1b22433b01002011410a6a20193b0100201141086a2018204420161b22443b0100201141066a20153b0100200420042802900941016a360290090c0b0b20110d9c010c9a010b20004281808080203702000c96010b2002280200200441a00a6a10a0022211450d292011280200211220044198026a200441bc086a2001109a0620042f0198022213450d2a20042f019a02211420012f0120211520044190026a200441bc086a200141226a109a0620042f0190022216450d2b20042f0192022118200141c2006a2f0100211920044188026a200441bc086a200141c4006a109a0620042f018802221a450d2c20042f018a02211d200141e4006a2f0100211e20044180026a200441bc086a200141e6006a109a0620042f018002221f450d2d20042f018202212320014186016a2f01002124200441f8016a200441bc086a20014188016a109a0620042f01f8012225450d2e20042f01fa01212a200141a8016a2f0100212b200441f0016a200441bc086a200141aa016a109a0620042f01f001222c450d2f20042f01f2012132200141ca016a2f01002133200441e8016a200441bc086a200141cc016a109a0620042f01e8012234450d3020042f01ea01213b200141ec016a2f0100213c200441e0016a200441bc086a200141ee016a109a06024020042f01e001223d450d0020042f01e201214502400240200428029c092211200428029809470d00201141016a22462011490d9b01201141017422472046204720464b1b22464104204641044b1bad42247e220d422088a7454102742146200da721470240024020110d00200441003602d00a0c010b200441043602d80a20042004280294093602d00a2004201141246c3602d40a0b200441c00a6a20472046200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a360294092004201141246e36029809200428029c0921110b200428029409201141246c6a221120452048203d1b22483b012020112014204920131b22493b0104201120123602002011411e6a203c3b01002011411c6a203b204a20341b224a3b01002011411a6a20333b0100201141186a2032204b202c1b224b3b0100201141166a202b3b0100201141146a202a204c20251b224c3b0100201141126a20243b0100201141106a2023204d201f1b224d3b01002011410e6a201e3b01002011410c6a201d204e201a1b224e3b01002011410a6a20193b0100201141086a2018204f20161b224f3b0100201141066a20153b01002004200428029c0941016a36029c090c0a0b20110d9b010c99010b20004281808080203702000c95010b2002280200200441a00a6a10a0022211450d3020112802002112200441e0026a200441bc086a2001109a0620042f01e0022213450d3120042f01e202211420012f01202115200441d8026a200441bc086a200141226a109a0620042f01d8022216450d3220042f01da022118200141c2006a2f01002119200441d0026a200441bc086a200141c4006a109a0620042f01d002221a450d3320042f01d202211d200141e4006a2f0100211e200441c8026a200441bc086a200141e6006a109a0620042f01c802221f450d3420042f01ca02212320014186016a2f01002124200441c0026a200441bc086a20014188016a109a0620042f01c0022225450d3520042f01c202212a200141a8016a2f0100212b200441b8026a200441bc086a200141aa016a109a0620042f01b802222c450d3620042f01ba022132200141ca016a2f01002133200441b0026a200441bc086a200141cc016a109a0620042f01b0022234450d3720042f01b202213b200141ec016a2f0100213c200441a8026a200441bc086a200141ee016a109a0620042f01a802223d450d3820042f01aa0221452001418e026a2f01002146200441a0026a200441bc086a20014190026a109a06024020042f01a0022247450d0020042f01a20221500240024020042802a809221120042802a409470d00201141016a22512011490d9a01201141017422522051205220514b1b22514104205141044b1bad42287e220d422088a7454102742151200da721520240024020110d00200441003602d00a0c010b200441043602d80a200420042802a0093602d00a2004201141286c3602d40a0b200441c00a6a20522051200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602a0092004201141286e3602a40920042802a80921110b20042802a009201141286c6a22112050205320471b22533b012420112014205420131b22543b010420112012360200201141226a20463b0100201141206a20452055203d1b22553b01002011411e6a203c3b01002011411c6a203b205620341b22563b01002011411a6a20333b0100201141186a20322057202c1b22573b0100201141166a202b3b0100201141146a202a205820251b22583b0100201141126a20243b0100201141106a20232059201f1b22593b01002011410e6a201e3b01002011410c6a201d205a201a1b225a3b01002011410a6a20193b0100201141086a2018205b20161b225b3b0100201141066a20153b0100200420042802a80941016a3602a8090c090b20110d9a010c98010b20004281808080203702000c94010b2002280200200441a00a6a10a0022211450d3820112802002112200441b0036a200441bc086a2001109a0620042f01b0032213450d3920042f01b203211420012f01202115200441a8036a200441bc086a200141226a109a0620042f01a8032216450d3a20042f01aa032118200141c2006a2f01002119200441a0036a200441bc086a200141c4006a109a0620042f01a003221a450d3b20042f01a203211d200141e4006a2f0100211e20044198036a200441bc086a200141e6006a109a0620042f019803221f450d3c20042f019a03212320014186016a2f0100212420044190036a200441bc086a20014188016a109a0620042f0190032225450d3d20042f019203212a200141a8016a2f0100212b20044188036a200441bc086a200141aa016a109a0620042f018803222c450d3e20042f018a032132200141ca016a2f0100213320044180036a200441bc086a200141cc016a109a0620042f0180032234450d3f20042f018203213b200141ec016a2f0100213c200441f8026a200441bc086a200141ee016a109a0620042f01f802223d450d4020042f01fa0221452001418e026a2f01002146200441f0026a200441bc086a20014190026a109a0620042f01f0022247450d4120042f01f2022150200141b0026a2f01002151200441e8026a200441bc086a200141b2026a109a06024020042f01e8022252450d0020042f01ea02215c0240024020042802b409221120042802b009470d00201141016a225d2011490d99012011410174225e205d205e205d4b1b225d4104205d41044b1bad422c7e220d422088a745410274215d200da7215e0240024020110d00200441003602d00a0c010b200441043602d80a200420042802ac093602d00a20042011412c6c3602d40a0b200441c00a6a205e205d200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602ac0920042011412c6e3602b00920042802b40921110b20042802ac092011412c6c6a2211205c205f20521b225f3b012820112014206020131b22603b010420112012360200201141266a20513b0100201141246a2050206120471b22613b0100201141226a20463b0100201141206a20452062203d1b22623b01002011411e6a203c3b01002011411c6a203b206320341b22633b01002011411a6a20333b0100201141186a20322064202c1b22643b0100201141166a202b3b0100201141146a202a206520251b22653b0100201141126a20243b0100201141106a20232066201f1b22663b01002011410e6a201e3b01002011410c6a201d2067201a1b22673b01002011410a6a20193b0100201141086a2018206820161b22683b0100201141066a20153b0100200420042802b40941016a3602b4090c080b20110d99010c97010b20004281808080203702000c93010b2002280200200441a00a6a10a0022211450d412011280200211220044188046a200441bc086a2001109a0620042f0188042213450d4220042f018a04211420012f0120211520044180046a200441bc086a200141226a109a0620042f0180042216450d4320042f0182042118200141c2006a2f01002119200441f8036a200441bc086a200141c4006a109a0620042f01f803221a450d4420042f01fa03211d200141e4006a2f0100211e200441f0036a200441bc086a200141e6006a109a0620042f01f003221f450d4520042f01f203212320014186016a2f01002124200441e8036a200441bc086a20014188016a109a0620042f01e8032225450d4620042f01ea03212a200141a8016a2f0100212b200441e0036a200441bc086a200141aa016a109a0620042f01e003222c450d4720042f01e2032132200141ca016a2f01002133200441d8036a200441bc086a200141cc016a109a0620042f01d8032234450d4820042f01da03213b200141ec016a2f0100213c200441d0036a200441bc086a200141ee016a109a0620042f01d003223d450d4920042f01d20321452001418e026a2f01002146200441c8036a200441bc086a20014190026a109a0620042f01c8032247450d4a20042f01ca032150200141b0026a2f01002151200441c0036a200441bc086a200141b2026a109a0620042f01c0032252450d4b20042f01c203215c200141d2026a2f0100215d200441b8036a200441bc086a200141d4026a109a06024020042f01b803225e450d0020042f01ba0321690240024020042802c009221120042802bc09470d00201141016a226a2011490d98012011410174226b206a206b206a4b1b226a4104206a41044b1bad42307e220d422088a745410274216a200da7216b0240024020110d00200441003602d00a0c010b200441043602d80a200420042802b8093602d00a2004201141306c3602d40a0b200441c00a6a206b206a200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602b8092004201141306e3602bc0920042802c00921110b20042802b809201141306c6a22112069206c205e1b226c3b012c20112014206d20131b226d3b0104201120123602002011412a6a205d3b0100201141286a205c206e20521b226e3b0100201141266a20513b0100201141246a2050206f20471b226f3b0100201141226a20463b0100201141206a20452070203d1b22703b01002011411e6a203c3b01002011411c6a203b207120341b22713b01002011411a6a20333b0100201141186a20322072202c1b22723b0100201141166a202b3b0100201141146a202a207320251b22733b0100201141126a20243b0100201141106a20232074201f1b22743b01002011410e6a201e3b01002011410c6a201d2075201a1b22753b01002011410a6a20193b0100201141086a2018207620161b22763b0100201141066a20153b0100200420042802c00941016a3602c0090c070b20110d98010c96010b20004281808080203702000c92010b2002280200200441a00a6a10a0022211450d4b20112802002112200441e8046a200441bc086a2001109a0620042f01e8042213450d4c20042f01ea04211420012f01202115200441e0046a200441bc086a200141226a109a0620042f01e0042216450d4d20042f01e2042118200141c2006a2f01002119200441d8046a200441bc086a200141c4006a109a0620042f01d804221a450d4e20042f01da04211d200141e4006a2f0100211e200441d0046a200441bc086a200141e6006a109a0620042f01d004221f450d4f20042f01d204212320014186016a2f01002124200441c8046a200441bc086a20014188016a109a0620042f01c8042225450d5020042f01ca04212a200141a8016a2f0100212b200441c0046a200441bc086a200141aa016a109a0620042f01c004222c450d5120042f01c2042132200141ca016a2f01002133200441b8046a200441bc086a200141cc016a109a0620042f01b8042234450d5220042f01ba04213b200141ec016a2f0100213c200441b0046a200441bc086a200141ee016a109a0620042f01b004223d450d5320042f01b20421452001418e026a2f01002146200441a8046a200441bc086a20014190026a109a0620042f01a8042247450d5420042f01aa042150200141b0026a2f01002151200441a0046a200441bc086a200141b2026a109a0620042f01a0042252450d5520042f01a204215c200141d2026a2f0100215d20044198046a200441bc086a200141d4026a109a0620042f019804225e450d5620042f019a042169200141f4026a2f0100216a20044190046a200441bc086a200141f6026a109a06024020042f019004226b450d0020042f01920421770240024020042802cc09221120042802c809470d00201141016a22782011490d9701201141017422792078207920784b1b22784104207841044b1bad42347e220d422088a7454102742178200da721790240024020110d00200441003602d00a0c010b200441043602d80a200420042802c4093602d00a2004201141346c3602d40a0b200441c00a6a20792078200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602c4092004201141346e3602c80920042802cc0921110b20042802c409201141346c6a22112077207a206b1b227a3b013020112014207b20131b227b3b0104201120123602002011412e6a206a3b01002011412c6a2069207c205e1b227c3b01002011412a6a205d3b0100201141286a205c207d20521b227d3b0100201141266a20513b0100201141246a2050207e20471b227e3b0100201141226a20463b0100201141206a2045207f203d1b227f3b01002011411e6a203c3b01002011411c6a203b20800120341b2280013b01002011411a6a20333b0100201141186a2032208101202c1b2281013b0100201141166a202b3b0100201141146a202a20820120251b2282013b0100201141126a20243b0100201141106a2023208301201f1b2283013b01002011410e6a201e3b01002011410c6a201d208401201a1b2284013b01002011410a6a20193b0100201141086a201820850120161b2285013b0100201141066a20153b0100200420042802cc0941016a3602cc090c060b20110d97010c95010b20004281808080203702000c91010b2002280200200441a00a6a10a0022211450d5620112802002112200441d0056a200441bc086a2001109a0620042f01d0052213450d5720042f01d205211420012f01202115200441c8056a200441bc086a200141226a109a0620042f01c8052216450d5820042f01ca052118200141c2006a2f01002119200441c0056a200441bc086a200141c4006a109a0620042f01c005221a450d5920042f01c205211d200141e4006a2f0100211e200441b8056a200441bc086a200141e6006a109a0620042f01b805221f450d5a20042f01ba05212320014186016a2f01002124200441b0056a200441bc086a20014188016a109a0620042f01b0052225450d5b20042f01b205212a200141a8016a2f0100212b200441a8056a200441bc086a200141aa016a109a0620042f01a805222c450d5c20042f01aa052132200141ca016a2f01002133200441a0056a200441bc086a200141cc016a109a0620042f01a0052234450d5d20042f01a205213b200141ec016a2f0100213c20044198056a200441bc086a200141ee016a109a0620042f019805223d450d5e20042f019a0521452001418e026a2f0100214620044190056a200441bc086a20014190026a109a0620042f0190052247450d5f20042f0192052150200141b0026a2f0100215120044188056a200441bc086a200141b2026a109a0620042f0188052252450d6020042f018a05215c200141d2026a2f0100215d20044180056a200441bc086a200141d4026a109a0620042f018005225e450d6120042f0182052169200141f4026a2f0100216a200441f8046a200441bc086a200141f6026a109a0620042f01f804226b450d6220042f01fa04217720014196036a2f01002178200441f0046a200441bc086a20014198036a109a06024020042f01f0042279450d0020042f01f2042186010240024020042802d809221120042802d409470d00201141016a2287012011490d960120114101742288012087012088012087014b1b228701410420870141044b1bad42387e220d422088a745410274218701200da72188010240024020110d00200441003602d00a0c010b200441043602d80a200420042802d0093602d00a2004201141386c3602d40a0b200441c00a6a208801208701200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602d0092004201141386e3602d40920042802d80921110b20042802d009201141386c6a221120860120890120791b2289013b013420112014208a0120131b228a013b010420112012360200201141326a20783b0100201141306a2077208b01206b1b228b013b01002011412e6a206a3b01002011412c6a2069208c01205e1b228c013b01002011412a6a205d3b0100201141286a205c208d0120521b228d013b0100201141266a20513b0100201141246a2050208e0120471b228e013b0100201141226a20463b0100201141206a2045208f01203d1b228f013b01002011411e6a203c3b01002011411c6a203b20900120341b2290013b01002011411a6a20333b0100201141186a2032209101202c1b2291013b0100201141166a202b3b0100201141146a202a20920120251b2292013b0100201141126a20243b0100201141106a2023209301201f1b2293013b01002011410e6a201e3b01002011410c6a201d209401201a1b2294013b01002011410a6a20193b0100201141086a201820950120161b2295013b0100201141066a20153b0100200420042802d80941016a3602d8090c050b20110d96010c94010b20004281808080203702000c90010b2002280200200441a00a6a10a0022211450d6220112802002112200441c0066a200441bc086a2001109a0620042f01c0062213450d6320042f01c206211420012f01202115200441b8066a200441bc086a200141226a109a0620042f01b8062216450d6420042f01ba062118200141c2006a2f01002119200441b0066a200441bc086a200141c4006a109a0620042f01b006221a450d6520042f01b206211d200141e4006a2f0100211e200441a8066a200441bc086a200141e6006a109a0620042f01a806221f450d6620042f01aa06212320014186016a2f01002124200441a0066a200441bc086a20014188016a109a0620042f01a0062225450d6720042f01a206212a200141a8016a2f0100212b20044198066a200441bc086a200141aa016a109a0620042f019806222c450d6820042f019a062132200141ca016a2f0100213320044190066a200441bc086a200141cc016a109a0620042f0190062234450d6920042f019206213b200141ec016a2f0100213c20044188066a200441bc086a200141ee016a109a0620042f018806223d450d6a20042f018a0621452001418e026a2f0100214620044180066a200441bc086a20014190026a109a0620042f0180062247450d6b20042f0182062150200141b0026a2f01002151200441f8056a200441bc086a200141b2026a109a0620042f01f8052252450d6c20042f01fa05215c200141d2026a2f0100215d200441f0056a200441bc086a200141d4026a109a0620042f01f005225e450d6d20042f01f2052169200141f4026a2f0100216a200441e8056a200441bc086a200141f6026a109a0620042f01e805226b450d6e20042f01ea05217720014196036a2f01002178200441e0056a200441bc086a20014198036a109a0620042f01e0052279450d6f20042f01e205218601200141b8036a2f0100218701200441d8056a200441bc086a200141ba036a109a06024020042f01d805228801450d0020042f01da052196010240024020042802e409221120042802e009470d00201141016a2297012011490d950120114101742298012097012098012097014b1b229701410420970141044b1bad423c7e220d422088a745410274219701200da72198010240024020110d00200441003602d00a0c010b200441043602d80a200420042802dc093602d00a20042011413c6c3602d40a0b200441c00a6a209801209701200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602dc0920042011413c6e3602e00920042802e40921110b20042802dc092011413c6c6a22112096012099012088011b2299013b013820112014209a0120131b229a013b010420112012360200201141366a2087013b0100201141346a208601209b0120791b229b013b0100201141326a20783b0100201141306a2077209c01206b1b229c013b01002011412e6a206a3b01002011412c6a2069209d01205e1b229d013b01002011412a6a205d3b0100201141286a205c209e0120521b229e013b0100201141266a20513b0100201141246a2050209f0120471b229f013b0100201141226a20463b0100201141206a204520a001203d1b22a0013b01002011411e6a203c3b01002011411c6a203b20a10120341b22a1013b01002011411a6a20333b0100201141186a203220a201202c1b22a2013b0100201141166a202b3b0100201141146a202a20a30120251b22a3013b0100201141126a20243b0100201141106a202320a401201f1b22a4013b01002011410e6a201e3b01002011410c6a201d20a501201a1b22a5013b01002011410a6a20193b0100201141086a201820a60120161b22a6013b0100201141066a20153b0100200420042802e40941016a3602e4090c040b20110d95010c93010b20004281808080203702000c8f010b2002280200200441a00a6a10a0022211450d6f20112802002112200441b8076a200441bc086a2001109a0620042f01b8072213450d7020042f01ba07211420012f01202115200441b0076a200441bc086a200141226a109a0620042f01b0072216450d7120042f01b2072118200141c2006a2f01002119200441a8076a200441bc086a200141c4006a109a0620042f01a807221a450d7220042f01aa07211d200141e4006a2f0100211e200441a0076a200441bc086a200141e6006a109a0620042f01a007221f450d7320042f01a207212320014186016a2f0100212420044198076a200441bc086a20014188016a109a0620042f0198072225450d7420042f019a07212a200141a8016a2f0100212b20044190076a200441bc086a200141aa016a109a0620042f019007222c450d7520042f0192072132200141ca016a2f0100213320044188076a200441bc086a200141cc016a109a0620042f0188072234450d7620042f018a07213b200141ec016a2f0100213c20044180076a200441bc086a200141ee016a109a0620042f018007223d450d7720042f01820721452001418e026a2f01002146200441f8066a200441bc086a20014190026a109a0620042f01f8062247450d7820042f01fa062150200141b0026a2f01002151200441f0066a200441bc086a200141b2026a109a0620042f01f0062252450d7920042f01f206215c200141d2026a2f0100215d200441e8066a200441bc086a200141d4026a109a0620042f01e806225e450d7a20042f01ea062169200141f4026a2f0100216a200441e0066a200441bc086a200141f6026a109a0620042f01e006226b450d7b20042f01e206217720014196036a2f01002178200441d8066a200441bc086a20014198036a109a0620042f01d8062279450d7c20042f01da06218601200141b8036a2f0100218701200441d0066a200441bc086a200141ba036a109a0620042f01d006228801450d7d20042f01d206219601200141da036a2f0100219701200441c8066a200441bc086a200141dc036a109a06024020042f01c806229801450d0020042f01ca0621a7010240024020042802f009221120042802ec09470d00201141016a22a8012011490d9401201141017422a90120a80120a90120a8014b1b22a801410420a80141044b1b22a80141ffffff1f7120a8014641027421a90120a80141067421a8010240024020110d00200441003602d00a0c010b200441043602d80a200420042802e8093602d00a200420114106743602d40a0b200441c00a6a20a80120a901200441d00a6a107d20042802c80a211120042802c00a4101460d01200420042802c40a3602e809200420114106763602ec0920042802f00921110b20042802e80920114106746a221120a70120aa012098011b22aa013b013c2011201420ab0120131b22ab013b0104201120123602002011413a6a2097013b0100201141386a20960120ac012088011b22ac013b0100201141366a2087013b0100201141346a20860120ad0120791b22ad013b0100201141326a20783b0100201141306a207720ae01206b1b22ae013b01002011412e6a206a3b01002011412c6a206920af01205e1b22af013b01002011412a6a205d3b0100201141286a205c20b00120521b22b0013b0100201141266a20513b0100201141246a205020b10120471b22b1013b0100201141226a20463b0100201141206a204520b201203d1b22b2013b01002011411e6a203c3b01002011411c6a203b20b30120341b22b3013b01002011411a6a20333b0100201141186a203220b401202c1b22b4013b0100201141166a202b3b0100201141146a202a20b50120251b22b5013b0100201141126a20243b0100201141106a202320b601201f1b22b6013b01002011410e6a201e3b01002011410c6a201d20b701201a1b22b7013b01002011410a6a20193b0100201141086a201820b80120161b22b8013b0100201141066a20153b0100200420042802f00941016a3602f0090c030b20110d94010c92010b20004281808080203702000c8e010b2002280200200441a00a6a10a0022211450d7d20112802002112200441b8086a200441bc086a2001109a0620042f01b8082213450d7e20042f01ba08211420012f01202115200441b0086a200441bc086a200141226a109a0620042f01b0082216450d7f20042f01b2082118200141c2006a2f01002119200441a8086a200441bc086a200141c4006a109a0620042f01a808221a450d800120042f01aa08211d200141e4006a2f0100211e200441a0086a200441bc086a200141e6006a109a0620042f01a008221f450d810120042f01a208212320014186016a2f0100212420044198086a200441bc086a20014188016a109a0620042f0198082225450d820120042f019a08212a200141a8016a2f0100212b20044190086a200441bc086a200141aa016a109a0620042f019008222c450d830120042f0192082132200141ca016a2f0100213320044188086a200441bc086a200141cc016a109a0620042f0188082234450d840120042f018a08213b200141ec016a2f0100213c20044180086a200441bc086a200141ee016a109a0620042f018008223d450d850120042f01820821452001418e026a2f01002146200441f8076a200441bc086a20014190026a109a0620042f01f8072247450d860120042f01fa072150200141b0026a2f01002151200441f0076a200441bc086a200141b2026a109a0620042f01f0072252450d870120042f01f207215c200141d2026a2f0100215d200441e8076a200441bc086a200141d4026a109a0620042f01e807225e450d880120042f01ea072169200141f4026a2f0100216a200441e0076a200441bc086a200141f6026a109a0620042f01e007226b450d890120042f01e207217720014196036a2f01002178200441d8076a200441bc086a20014198036a109a0620042f01d8072279450d8a0120042f01da07218601200141b8036a2f0100218701200441d0076a200441bc086a200141ba036a109a0620042f01d007228801450d8b0120042f01d207219601200141da036a2f0100219701200441c8076a200441bc086a200141dc036a109a0620042f01c807229801450d8c0120042f01ca0721a701200141fc036a2f010021a801200441c0076a200441bc086a200141fe036a109a0620042f01c00722a901450d0220042f01c20721b901024020042802fc09221120042802f809470d00201141016a22ba012011490d9101201141017422bb0120ba0120bb0120ba014b1b22ba01410420ba0141044b1bad42c4007e220d422088a74541027421ba01200da721bb010240024020110d00200441003602d00a0c010b200441043602d80a200420042802f4093602d00a2004201141c4006c3602d40a0b200441c00a6a20bb0120ba01200441d00a6a107d20042802c80a211120042802c00a4101460d02200420042802c40a3602f4092004201141c4006e3602f80920042802fc0921110b20042802f409201141c4006c6a221120b90120bc0120a9011b22bc013b01402011201420bd0120131b22bd013b0104201120123602002011413e6a20a8013b01002011413c6a20a70120be012098011b22be013b01002011413a6a2097013b0100201141386a20960120bf012088011b22bf013b0100201141366a2087013b0100201141346a20860120c00120791b22c0013b0100201141326a20783b0100201141306a207720c101206b1b22c1013b01002011412e6a206a3b01002011412c6a206920c201205e1b22c2013b01002011412a6a205d3b0100201141286a205c20c30120521b22c3013b0100201141266a20513b0100201141246a205020c40120471b22c4013b0100201141226a20463b0100201141206a204520c501203d1b22c5013b01002011411e6a203c3b01002011411c6a203b20c60120341b22c6013b01002011411a6a20333b0100201141186a203220c701202c1b22c7013b0100201141166a202b3b0100201141146a202a20c80120251b22c8013b0100201141126a20243b0100201141106a202320c901201f1b22c9013b01002011410e6a201e3b01002011410c6a201d20ca01201a1b22ca013b01002011410a6a20193b0100201141086a201820cb0120161b22cb013b0100201141066a20153b0100200420042802fc0941016a3602fc090b200ca72211450d8e01201141226c450d8e010c8d010b20110d90010c8e010b20004281808080203702000c8a010b200ca72211450d8b01201141226c0d8a010c8b010b20004281808080103702000c88010b20004281808080203702000c87010b20004281808080203702000c86010b20004281808080203702000c85010b20004281808080203702000c84010b20004281808080203702000c83010b20004281808080203702000c82010b20004281808080203702000c81010b20004281808080203702000c80010b20004281808080203702000c7f0b20004281808080203702000c7e0b20004281808080203702000c7d0b20004281808080203702000c7c0b20004281808080203702000c7b0b20004281808080203702000c7a0b20004281808080203702000c790b20004281808080203702000c780b20004281808080203702000c770b20004281808080203702000c760b20004281808080203702000c750b20004281808080203702000c740b20004281808080203702000c730b20004281808080203702000c720b20004281808080203702000c710b20004281808080203702000c700b20004281808080203702000c6f0b20004281808080203702000c6e0b20004281808080203702000c6d0b20004281808080203702000c6c0b20004281808080203702000c6b0b20004281808080203702000c6a0b20004281808080203702000c690b20004281808080203702000c680b20004281808080203702000c670b20004281808080203702000c660b20004281808080203702000c650b20004281808080203702000c640b20004281808080203702000c630b20004281808080203702000c620b20004281808080203702000c610b20004281808080203702000c600b20004281808080203702000c5f0b20004281808080203702000c5e0b20004281808080203702000c5d0b20004281808080203702000c5c0b20004281808080203702000c5b0b20004281808080203702000c5a0b20004281808080203702000c590b20004281808080203702000c580b20004281808080203702000c570b20004281808080203702000c560b20004281808080203702000c550b20004281808080203702000c540b20004281808080203702000c530b20004281808080203702000c520b20004281808080203702000c510b20004281808080203702000c500b20004281808080203702000c4f0b20004281808080203702000c4e0b20004281808080203702000c4d0b20004281808080203702000c4c0b20004281808080203702000c4b0b20004281808080203702000c4a0b20004281808080203702000c490b20004281808080203702000c480b20004281808080203702000c470b20004281808080203702000c460b20004281808080203702000c450b20004281808080203702000c440b20004281808080203702000c430b20004281808080203702000c420b20004281808080203702000c410b20004281808080203702000c400b20004281808080203702000c3f0b20004281808080203702000c3e0b20004281808080203702000c3d0b20004281808080203702000c3c0b20004281808080203702000c3b0b20004281808080203702000c3a0b20004281808080203702000c390b20004281808080203702000c380b20004281808080203702000c370b20004281808080203702000c360b20004281808080203702000c350b20004281808080203702000c340b20004281808080203702000c330b20004281808080203702000c320b20004281808080203702000c310b20004281808080203702000c300b20004281808080203702000c2f0b20004281808080203702000c2e0b20004281808080203702000c2d0b20004281808080203702000c2c0b20004281808080203702000c2b0b20004281808080203702000c2a0b20004281808080203702000c290b20004281808080203702000c280b20004281808080203702000c270b20004281808080203702000c260b20004281808080203702000c250b20004281808080203702000c240b20004281808080203702000c230b20004281808080203702000c220b20004281808080203702000c210b20004281808080203702000c200b20004281808080203702000c1f0b20004281808080203702000c1e0b20004281808080203702000c1d0b20004281808080203702000c1c0b20004281808080203702000c1b0b20004281808080203702000c1a0b20004281808080203702000c190b20004281808080203702000c180b20004281808080203702000c170b20004281808080203702000c160b20004281808080203702000c150b20004281808080203702000c140b20004281808080203702000c130b20004281808080203702000c120b20004281808080203702000c110b20004281808080203702000c100b20004281808080203702000c0f0b20004281808080203702000c0e0b20004281808080203702000c0d0b20004281808080203702000c0c0b20004281808080203702000c0b0b20004281808080203702000c0a0b20004281808080203702000c090b20004281808080203702000c080b20004281808080203702000c070b20004281808080203702000c060b20004281808080203702000c050b20004281808080203702000c040b20004281808080203702000c030b20004281808080203702000c020b20004281808080203702000c010b20004281808080203702000b0240200ca72207450d00200741226c450d002001102e0b02402003450d002006412c6a210103400240200141046a2802002206450d00200641226c450d002001280200102e0b2001412c6a2101200341546a22030d000b0b02402008450d002008412c6c450d002005102e0b200441c0086a109b060c070b2001102e0b200341546a21032006412c6a22062007470d010c040b0b1038000b1036000b20072001460d00034020012203412c6a21010240200341046a2802002206450d00200641226c450d002003280200102e0b20072001470d000b0b02402008450d002008412c6c450d002005102e0b200041046a200441c0086a41c00110e9081a200041003602000b200441e00a6a24000bc60101067f02400240200128020022012802042203450d00200128020021040340200341046a210520032f015e22064102742101410021070240024003402001450d0120022005280200412010ec082208450d022001417c6a2101200741016a2107200541046a21052008417f4a0d000b2007417f6a21060b2004450d022004417f6a2104200320064102746a41e0006a28020021030c010b0b200320074102746a41306a2802002205418080044921010c010b410021010b200020053b0102200020013b01000bf70301017f0240200041046a28020041ffffffff0171450d002000280200102e0b0240200041106a2802002201450d002001410c6c450d00200028020c102e0b02402000411c6a28020041ffffffff0071450d002000280218102e0b0240200041286a2802002201450d00200141146c450d002000280224102e0b0240200041346a2802002201450d00200141186c450d002000280230102e0b0240200041c0006a2802002201450d002001411c6c450d00200028023c102e0b0240200041cc006a28020041ffffff3f71450d002000280248102e0b0240200041d8006a2802002201450d00200141246c450d002000280254102e0b0240200041e4006a2802002201450d00200141286c450d002000280260102e0b0240200041f0006a2802002201450d002001412c6c450d00200028026c102e0b0240200041fc006a2802002201450d00200141306c450d002000280278102e0b024020004188016a2802002201450d00200141346c450d00200028028401102e0b024020004194016a2802002201450d00200141386c450d00200028029001102e0b0240200041a0016a2802002201450d002001413c6c450d00200028029c01102e0b0240200041ac016a28020041ffffff1f71450d0020002802a801102e0b0240200041b8016a2802002201450d00200141c4006c450d0020002802b401102e0b0b8c5103037f017e017f230041106b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000e18000102030405060708090a0b0c0d0e0f1011121314151617180b200241003a00002001200241011074024002400240024002400240200041086a2d00000e060001020304051d0b200241003a00002001200241011074200041106a290300200041186a2d0000200041196a2d0000200110be030c1c0b200241013a000020012002410110742000410c6a2d00002000410d6a2d00002000410e6a2d00002001109d06200041186a290300200041206a2d0000200041216a2d0000200110be030c1b0b200241023a000020012002410110740c1a0b200241033a000020012002410110742001200041096a412010740c190b200241043a000020012002410110742001200041096a412010740c180b200241053a000020012002410110742001200041096a412010744120102c2203450d1820024220370204200220033602002002200041296a41201074200120022802002200200228020810742002280204450d172000102e0c170b200241013a00002001200241011074024002400240200041046a2802000e03000102190b200241003a000020012002410110742002200041086a280200360200200120024104107420022000410c6a28020036020020012002410410740c180b200241013a000020012002410110742002200041086a280200360200200120024104107420022000410c6a28020036020020012002410410740c170b200241023a000020012002410110742002200041086a280200360200200120024104107420022000410c6a280200360200200120024104107402400240200041106a28020022030d00200241003a000020012002410110740c010b200241013a00002001200241011074200041186a28020022042001107620012003200410740b024020002d001c4106460d00200241013a0000200120024101107420002d001c2000411d6a2d00002000411e6a2d00002001109d060c170b200241003a000020012002410110740c160b200241043a00002001200241011074024002400240200041046a2d00000e03000102180b200241003a000020012002410110742001200041056a412010742002200041286a28020036020020012002410410740c170b200241013a000020012002410110742002200041086a28020036020020012002410410740c160b200241023a000020012002410110742002200041286a28020036020020012002410410742001200041056a412010740c150b200241053a0000200120024101107402400240024002400240024002400240200041086a2d00000e080001020304050607000b200241003a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c1b0b200241013a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c1a0b200241023a000020012002410110742001200041096a412010742001200041296a41201074200041d0006a29030021052002200041d8006a2903003703082002200537030020012002411010740c190b200241033a000020012002410110742001200041096a41201074200041306a29030021052002200041386a290300370308200220053703002001200241101074200041c0006a29030021052002200041c8006a2903003703082002200537030020012002411010740c180b200241043a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c170b200241053a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c160b200241063a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c150b200241073a000020012002410110742001200041096a412010742001200041296a41201074200041d0006a29030021052002200041d8006a2903003703082002200537030020012002411010740240200041c9006a2d00004101460d00200241003a000020012002410110740c150b200241013a000020012002410110740c140b200241073a00002001200241011074024002400240024002400240024002400240200041086a2d00000e090001020304050607081c0b200241003a0000200120024101107420022000410c6a2802003602002001200241041074200041106a29030021052002200041186a290300370308200220053703002001200241101074200041206a29030021052002200041286a2903003703082002200537030020012002411010740c1b0b200241013a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c1a0b200241023a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c190b200241033a0000200120024101107420022000410c6a28020036020020012002410410740c180b200241043a000020012002410110740c170b200241053a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c160b200241063a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c150b200241073a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c140b200241083a000020012002410110742001200041096a412010742001200041296a412010740c130b200241083a00002001200241011074200241003a000020012002410110742001200041106a41101074200041046a28020021032000410c6a28020022042001107620012003200410742002200041206a2d00003a000020012002410110740c120b200241093a00002001200241011074200241003a000020012002410110742002200041046a28020036020020012002410410740c110b2002410b3a00002001200241011074024002400240200041046a2802000e03000102130b200241003a00002001200241011074200041086a2802002103200041106a280200220020011076200041286c2200450d12200320006a2100034020012003412010742002200341206a2903003703002001200241081074200341286a22032000470d000c130b0b200241013a000020012002410110740c110b200241023a000020012002410110740c100b2002410c3a00002001200241011074024002400240200041046a2d00000e03000102120b200241003a000020012002410110742001200041056a412010740c110b200241013a000020012002410110740c100b200241023a00002001200241011074200041086a2802002103200041106a280200220020011076200041d0006c2200450d0f03402003200110a101200341d0006a2103200041b07f6a22000d000c100b0b2002410e3a00002001200241011074024002400240024002400240024002400240024002400240024002400240024002400240200041086a2d00000e12000102030405060708090a0b0c0d0e0f1011200b200241003a0000200120024101107420022000410c6a2802003602002001200241041074200041106a29030021052002200041186a2903003703082002200537030020012002411010740c1f0b200241013a0000200120024101107420022000410c6a2802003602002001200241041074200041206a29030021052002200041286a290300370308200220053703002001200241101074200041106a2802002103200041186a2802002200200110762000450d1e2000410574210003402001200341201074200341206a2103200041606a22000d000c1f0b0b200241023a000020012002410110740c1d0b200241033a0000200120024101107420022000410c6a2802003602002001200241041074024002400240200041096a2d00000e030001021f0b200241003a000020012002410110740c1e0b200241013a000020012002410110740c1d0b200241023a000020012002410110740c1c0b200241043a0000200120024101107420022000410c6a28020036020020012002410410740c1b0b200241053a0000200120024101107420022000410c6a28020036020020012002410410740c1a0b200241063a0000200120024101107420022000410c6a28020036020020012002410410740c190b200241073a0000200120024101107420022000410c6a28020036020020012002410410742002200041096a2d00003a000020012002410110740c180b200241083a000020012002410110742001200041096a412010742001200041296a412010740c170b200241093a000020012002410110742001200041096a412010740c160b2002410a3a000020012002410110742001200041096a412010744120102c2203450d1620024220370204200220033602002002200041296a412010742001200228020022032002280208107402402002280204450d002003102e0b2002200028024c36020020012002410410740c150b2002410b3a000020012002410110744120102c2203450d15200041296a210420024220370204200220033602002002200041096a412010742001200228020022032002280208107402402002280204450d002003102e0b2001200441201074200029035021052002200041d8006a2903003703082002200537030020012002411010740c140b2002410c3a000020012002410110744120102c2203450d14200041296a210420024220370204200220033602002002200041096a412010742001200228020022032002280208107402402002280204450d002003102e0b2001200441201074200029035021052002200041d8006a2903003703082002200537030020012002411010740c130b2002410d3a000020012002410110744120102c2203450d1320024220370204200220033602002002200041096a412010742001200228020022032002280208107402402002280204450d002003102e0b2002200028022c36020020012002410410740c120b2002410e3a000020012002410110744120102c2203450d1220024220370204200220033602002002200041096a412010742001200228020022032002280208107402402002280204450d002003102e0b2002200028022c36020020012002410410740c110b2002410f3a000020012002410110744120102c2203450d11200041c9006a2104200041296a210620024220370204200220033602002002200041096a412010742001200228020022032002280208107402402002280204450d002003102e0b2001200641201074200029037021052002200041f8006a29030037030820022005370300200120024110107420012004412010740c100b200241103a000020012002410110742001200041096a412010740c0f0b200241113a000020012002410110744120102c2203450d0f20024220370204200220033602002002200041096a41201074200120022802002200200228020810742002280204450d0e2000102e0c0e0b2002410f3a000020012002410110740240024002400240024002400240200041046a2d00000e0700010203040506140b200241003a000020012002410110742001200041056a412010742002200041c8006a28020036020020012002410410744120102c2203450d1420024220370204200220033602002002200041256a412010742001200228020022032002280208107402402002280204450d002003102e0b2002200028024c36020020012002410410740c130b200241013a000020012002410110742001200041056a412010744120102c2203450d1320024220370204200220033602002002200041256a412010742001200228020022032002280208107402402002280204450d002003102e0b200220002d00453a000020012002410110742002200028024836020020012002410410742002200028024c36020020012002410410740c120b200241023a000020012002410110744120102c2203450d1220024220370204200220033602002002200041056a41201074200120022802002200200228020810742002280204450d112000102e0c110b200241033a000020012002410110744120102c2203450d1120024220370204200220033602002002200041056a41201074200120022802002200200228020810742002280204450d102000102e0c100b200241043a000020012002410110744120102c2203450d1020024220370204200220033602002002200041056a412010742001200228020022032002280208107402402002280204450d002003102e0b024020002d00284106460d00200241013a0000200120024101107420002d0028200041296a2d00002000412a6a2d00002001109d060c100b200241003a000020012002410110740c0f0b200241053a000020012002410110744120102c2203450d0f20024220370204200220033602002002200041056a412010742001200228020022032002280208107402402002280204450d002003102e0b024020002d00284106460d00200241013a0000200120024101107420002d0028200041296a2d00002000412a6a2d00002001109d060c0f0b200241003a000020012002410110740c0e0b200241063a000020012002410110744120102c2203450d0e20024220370204200220033602002002200041056a412010742001200228020022032002280208107402402002280204450d002003102e0b2002200028022836020020012002410410742002200028022c36020020012002410410740c0d0b200241103a000020012002410110740240024002400240024002400240200041046a2d00000e0700010203040506130b200241003a000020012002410110742001200041056a412010742002200041c8006a28020036020020012002410410744120102c2203450d1320024220370204200220033602002002200041256a412010742001200228020022032002280208107402402002280204450d002003102e0b2002200028024c36020020012002410410740c120b200241013a000020012002410110742001200041056a412010744120102c2203450d1220024220370204200220033602002002200041256a412010742001200228020022032002280208107402402002280204450d002003102e0b200220002d00453a000020012002410110742002200028024836020020012002410410742002200028024c36020020012002410410740c110b200241023a000020012002410110744120102c2203450d1120024220370204200220033602002002200041056a41201074200120022802002200200228020810742002280204450d102000102e0c100b200241033a000020012002410110744120102c2203450d1020024220370204200220033602002002200041056a41201074200120022802002200200228020810742002280204450d0f2000102e0c0f0b200241043a000020012002410110744120102c2203450d0f20024220370204200220033602002002200041056a412010742001200228020022032002280208107402402002280204450d002003102e0b024020002d00284106460d00200241013a0000200120024101107420002d0028200041296a2d00002000412a6a2d00002001109d060c0f0b200241003a000020012002410110740c0e0b200241053a000020012002410110744120102c2203450d0e20024220370204200220033602002002200041056a412010742001200228020022032002280208107402402002280204450d002003102e0b024020002d00284106460d00200241013a0000200120024101107420002d0028200041296a2d00002000412a6a2d00002001109d060c0e0b200241003a000020012002410110740c0d0b200241063a000020012002410110744120102c2203450d0d20024220370204200220033602002002200041056a412010742001200228020022032002280208107402402002280204450d002003102e0b2002200028022836020020012002410410742002200028022c36020020012002410410740c0c0b200241113a000020012002410110740240024002400240024002400240200041086a2d00000e0700010203040506120b200241003a000020012002410110742000410c6a2802002103200041146a280200220020011076200041306c2200450d11200320006a210003402001200341201074200341206a29030021052002200341286a290300370308200220053703002001200241101074200341306a22032000470d000c120b0b200241013a000020012002410110740c100b200241023a000020012002410110740c0f0b200241033a000020012002410110742001200041096a412010740c0e0b200241043a000020012002410110742001200041096a412010740c0d0b200241053a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c0c0b200241063a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c0b0b200241123a0000200120024101107402400240024002400240024020002d00010e06000102030405100b200241003a000020012002410110740c0f0b200241013a000020012002410110740c0e0b200241023a000020012002410110740c0d0b200241033a000020012002410110740c0c0b200241043a000020012002410110740c0b0b200241053a000020012002410110740c0a0b200241133a000020012002410110740240024002400240024002400240200041086a2d00000e0700010203040506100b200241003a0000200120024101107420022000410c6a28020036020020012002410410740c0f0b200241013a00002001200241011074200041106a29030021052002200041186a2903003703082002200537030020012002411010740c0e0b200241023a0000200120024101107420022000412c6a2802003602002001200241041074200041306a29030021052002200041386a2903003703082002200537030020012002411010742001200041096a412010740c0d0b200241033a0000200120024101107420022000410c6a2802003602002001200241041074200041106a29030021052002200041186a2903003703082002200537030020012002411010740c0c0b200241043a00002001200241011074200041106a29030021052002200041186a2903003703082002200537030020012002411010740c0b0b200241053a00002001200241011074200041106a29030021052002200041186a2903003703082002200537030020012002411010740c0a0b200241063a00002001200241011074200041106a29030021052002200041186a2903003703082002200537030020012002411010740c090b200241183a00002001200241011074200241003a000020012002410110742001200041186a412010742001200041386a41141074200041086a29030021052002200041106a2903003703082002200537030020012002411010740c080b200241193a00002001200241011074200041096a21030240200041086a2d00004101460d00200241003a000020012002410110742001200341201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c080b200241013a0000200120024101107420012003412010740c070b2002411a3a000020012002410110740240200041086a2d00004106460d00200241003a000020012002410110742002200041046a280200360200200120024104107420002d0008200041096a2d00002000410a6a2d00002001109d060c070b200241013a000020012002410110740c060b2002411c3a000020012002410110740240024002400240024002400240024002400240200041086a2d00000e0a000102030405060708090f0b200241003a000020012002410110742001200041096a412010740c0e0b200241013a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c0d0b200241023a000020012002410110742001200041096a41201074200041306a29030021052002200041386a2903003703082002200537030020012002411010740c0c0b200241033a000020012002410110742001200041096a4120107420022000412c6a28020036020020012002410410740c0b0b200241043a000020012002410110742001200041096a4120107420022000412c6a28020036020020012002410410740c0a0b200241053a000020012002410110742001200041096a4120107420022000412c6a28020036020020012002410410740c090b200241063a0000200120024101107420022000410c6a28020036020020012002410410740c080b200241073a000020012002410110742001200041096a412010742001200041296a41201074200041d0006a29030021052002200041d8006a2903003703082002200537030020012002411010740c070b200241083a000020012002410110742001200041096a412010742001200041296a41201074200041d0006a29030021052002200041d8006a2903003703082002200537030020012002411010740c060b200241093a000020012002410110742001200041096a412010742001200041296a41201074200041d0006a29030021052002200041d8006a2903003703082002200537030020012002411010740c050b2002411d3a00002001200241011074024002400240200041046a2d00000e03000102070b200241003a000020012002410110740240200041086a2d00004106460d00200241013a0000200120024101107420002d0008200041096a2d00002000410a6a2d00002001109d060c070b200241003a000020012002410110740c060b200241013a000020012002410110742001200041056a412010742001200041256a412010740240024002400240024002400240200041c5006a2d00000e0700010203060405060b200241003a000020012002410110740c050b200241013a000020012002410110740c040b200241023a000020012002410110740c030b200241033a000020012002410110740c020b200241053a000020012002410110740c010b200241063a000020012002410110740b200220002f01463b010020012002410210740c050b200241023a000020012002410110742001200041056a412010742001200041256a412010744120102c2203450d0520024220370204200220033602002002200041c5006a41201074200120022802002200200228020810742002280204450d042000102e0c040b2002411e3a000020012002410110740240024002400240200041046a2d00000e0400010203000b200241003a000020012002410110742001200041056a412010742001200041256a412010742001200041c5006a412010740c060b200241013a000020012002410110742001200041056a412010742002200041e8006a28020036020020012002410410742002200041ec006a28020036020020012002410410742001200041256a412010742001200041c5006a412010740c050b200241023a000020012002410110742001200041056a412010742002200041e8006a28020036020020012002410410742002200041ec006a28020036020020012002410410742001200041256a412010742001200041c5006a412010740240200041f0006a2d00004106460d00200241013a0000200120024101107420002d0070200041f1006a2d0000200041f2006a2d00002001109d060c050b200241003a000020012002410110740c040b200241033a000020012002410110742001200041056a412010742002200041e8006a28020036020020012002410410742002200041ec006a28020036020020012002410410742001200041256a412010742001200041c5006a412010740c030b200241223a000020012002410110740240024002400240024002400240200041086a2d00000e0700010203040506090b200241003a0000200120024101107420022000410c6a28020036020020012002410410740c080b200241013a0000200120024101107420022000410c6a2802003602002001200241041074200041106a29030021052002200041186a2903003703082002200537030020012002411010740c070b200241023a0000200120024101107420022000410c6a28020036020020012002410410740c060b200241033a0000200120024101107420022000412c6a28020036020020012002410410742001200041096a412010740c050b200241043a0000200120024101107420022000412c6a2802003602002001200241041074200041306a29030021052002200041386a2903003703082002200537030020012002411010742001200041096a412010740c040b200241053a0000200120024101107420022000410c6a28020036020020012002410410740c030b200241063a0000200120024101107420022000410c6a28020036020020012002410410740c020b200241233a0000200120024101107402400240024002400240200041086a2d00000e050001020304060b200241003a000020012002410110744120102c2203450d0620024220370204200220033602002002200041096a41201074200120022802002200200228020810742002280204450d052000102e0c050b200241013a000020012002410110744120102c2203450d0520024220370204200220033602002002200041096a41201074200120022802002200200228020810742002280204450d042000102e0c040b200241023a000020012002410110744120102c2203450d04200041296a210420024220370204200220033602002002200041096a412010742001200228020022032002280208107402402002280204450d002003102e0b2001200441201074200029035021052002200041d8006a2903003703082002200537030020012002411010740c030b200241033a000020012002410110744120102c2203450d0320024220370204200220033602002002200041096a41201074200120022802002200200228020810742002280204450d022000102e0c020b200241043a000020012002410110744120102c2203450d02200041296a210420024220370204200220033602002002200041096a412010742001200228020022032002280208107402402002280204450d002003102e0b2001200441201074200029035021052002200041d8006a2903003703082002200537030020012002411010740c010b200241243a000020012002410110740240024002400240024002400240200041046a2d00000e06000102030405070b200241003a00002001200241011074024002400240200041056a2d00000e03000102090b200241003a000020012002410110740c080b200241013a000020012002410110740c070b200241023a000020012002410110740c060b200241013a000020012002410110740240200041056a2d000022004103470d00200241003a000020012002410110740c060b200241013a0000200120024101107402400240024020000e03000102080b200241003a000020012002410110740c070b200241013a000020012002410110740c060b200241023a000020012002410110740c050b200241023a000020012002410110742001200041056a412010740c040b200241033a000020012002410110742001200041056a412010740c030b200241043a000020012002410110742002200041086a2802003602000c010b200241053a000020012002410110742002200041086a2802003602000b20012002410410740b200241106a24000f0b1036000bd20101017f230041106b220424000240024002400240024002400240200041ff01710e06000102030405060b200441003a000f20032004410f6a410110740c050b200441013a000f20032004410f6a410110740c040b200441023a000f20032004410f6a410110740c030b200441033a000f20032004410f6a41011074200420013a000f20032004410f6a41011074200420023a000f20032004410f6a410110740c020b200441043a000f20032004410f6a410110740c010b200441053a000f20032004410f6a410110740b200441106a24000b1300200041063602042000418cc7cb003602000b130020004103360204200041c4fcc4003602000b130020004103360204200041f0e6c2003602000b130020004108360204200041ec82c8003602000b1300200041093602042000419cdec6003602000b130020004101360204200041c8aac0003602000b130020004101360204200041ccadc0003602000b130020004103360204200041e0a7c0003602000b130020004103360204200041c883c9003602000b130020004112360204200041b897cb003602000b130020004107360204200041e4edc9003602000b13002000410736020420004184aec2003602000b130020004106360204200041b8b9cc003602000b130020004107360204200041d894c4003602000b13002000410136020420004198f9c1003602000b130020004102360204200041d8eac7003602000b130020004102360204200041e8afc0003602000b13002000410a360204200041f8bec3003602000b13002000410336020420004184fbc0003602000b130020004104360204200041e4f9c3003602000b13002000410736020420004198e4c0003602000b1300200041053602042000419ce3c7003602000b130020004106360204200041d4afc8003602000b7201017f200028020022012001280200417f6a3602000240200028020022012802000d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200028020041046a22012001280200417f6a3602002000280200220041046a2802000d002000102e0b0b980301037f0240200028020022022802082001200228020c28020c110100450d00200041286a2d0000210002400240200128020022024117470d00024002400240024020012d0004417e6a0e050001020403040b2000450d0320012d0025220341ff01712000460d034101210420004101470d05200341ff0171450d050c040b2000450d0220012d0025220341ff01712000460d024101210420004101470d04200341ff0171450d040c030b20000d0341010f0b20000d0241010f0b4101210402400240024002400240024020000e0706010203000405060b000b2002411a4b0d05410120027441cfffbf3f710d04024020024104460d0020024114470d0641012104200141086a280200417f6a41024f0d060c050b20012d0004220141054b0d05410121044101200174412a71450d050c040b2002411a4b0d0441012002744180c0973171450d040c030b200241154b0d034101200274418085800171450d030c020b02402002416b6a0e020200030b200141086a2d0000410a470d020c010b20024117470d0120012d00044109470d010b20040f0b41000b7d01017f2000200110b6062102200028020022012001280200417f6a3602000240200028020022012802000d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200028020041046a22012001280200417f6a3602002000280200220041046a2802000d002000102e0b20020bb51302117f097e230041c0026b2202240020024198016a10f4040240024020022d0098014101460d002000410110f0060c010b200241e8016a22034200370300200241e0016a22044200370300200241d0016a41086a22054200370300200242003703d00120024180026a41a5fec600411a108102200520024180026a41086a220629000037030020022002290080023703d00120024180026a4194c5c800410e10810220032006290000370300200420022900800237030020024190016a200241d0016a4120108e022002280294012103200228029001210520024180026a200141306a1097062003410020051b21032002280288022105024020022802840241808080807872418080808078460d00200228028002102e0b024020032005460d002000410210f0060c010b200241d0016a41186a22064200370300200241d0016a41106a22074200370300200241d0016a41086a22054200370300200242003703d00120024180026a41a5fec600411a108102200520024180026a41086a220329000037030020022002290080023703d00120024180026a4184c4c800410e108102200441086a2003290000370000200420022900800237000020024180026a200241d0016a10ab05200241a0016a41086a22042003290300370300200241a0016a41106a220820024180026a41106a2209290300370300200241a0016a41186a220a20024180026a41186a220b290300370300200241a0016a41206a220c20024180026a41206a220d290300370300200241a0016a41286a220e20024180026a41286a220f29030037030020022002290380023703a001024020022d00bc024103460d0020022802b002211020022802b402211120022802b8022112200241d0016a41286a200141286a290300370300200241d0016a41206a200141206a2903003703002006200141186a2903003703002007200141106a2903003703002005200141086a290300370300200220012903003703d001200f200e290300370300200d200c290300370300200b200a2903003703002009200829030037030020032004290300370300200220022903a0013703800202400240024002404106102c2201450d0020024180016a200229038002221320024180026a41086a2903002214428094ebdc03420010e608200241f0006a20132014428094ebdc03420010e708200241e0006a2002290370200241f0006a41086a29030042a0c21e420010e808200241d0016a41086a290300211520022903d00121160240024020022903602217200229038001221842d00f80a7201842a0c21e7e428094ebdc03824200526aad7c2218200241e0006a41086a2903002018201754ad7c2217844200520d00417f20162013852015201485844200522016201354201520145420152014511b1b21040c010b0240427f201320187c221920192013542204201420177c2004ad7c221920145420192014511b22041b221a4200201320187d221b201b201356201420177d2013201854ad7d221820145620182014511b22031b221b56427f201920041b22174200201820031b22185620172018511b0d00417f20162013852015201485844200522016201354201520145420152014511b1b21040c010b4100210402400240417f2016201b852015201885844200522016201b54201520185420152018511b1b41016a0e03000201020b417f41002016201a54201520175420152017511b1b21040c010b2016201a56201520175620152017511b21040b200120043a00012001201620135a201520145a20152014511b3a0000200241306a200229039002221320024180026a41186a2903002214428094ebdc03420010e608200241d0006a20132014428094ebdc03420010e708200241c0006a2002290350200241d0006a41086a29030042a0c21e420010e808200241d0016a41186a290300211520022903e001211602400240200229034022172002290330221842d00f80a7201842a0c21e7e428094ebdc03824200526aad7c2218200241c0006a41086a2903002018201754ad7c22178450450d00417f20162013852015201485844200522016201354201520145420152014511b1b21040c010b0240427f201320187c221920192013542204201420177c2004ad7c221920145420192014511b22041b221a4200201320187d221b201b201356201420177d2013201854ad7d221820145620182014511b22031b221b56427f201920041b22174200201820031b22185620172018511b0d00417f20162013852015201485844200522016201354201520145420152014511b1b21040c010b4100210402400240417f2016201b852015201885844200522016201b54201520185420152018511b1b41016a0e03010200020b2016201a56201520175620152017511b21040c010b417f41002016201a54201520175420152017511b1b21040b200120043a00032001201620135a201520145a20152014511b3a0002200220022903a002221320024180026a41286a2903002214428094ebdc03420010e608200241206a20132014428094ebdc03420010e708200241106a2002290320200241206a41086a29030042a0c21e420010e808200241d0016a41286a290300211520022903f001211602400240200229031022172002290300221842d00f80a7201842a0c21e7e428094ebdc03824200526aad7c2218200241106a41086a2903002018201754ad7c221784500d000240427f201320187c221920192013542204201420177c2004ad7c221920145420192014511b22041b221a4200201320187d221b201b201356201420177d2013201854ad7d221820145620182014511b22031b221b56427f201920041b22174200201820031b22185620172018511b0d00417f20162013852015201485844200522016201354201520145420152014511b1b21040c020b4100210402400240417f2016201b852015201885844200522016201b54201520185420152018511b1b41016a0e03010300030b2016201a56201520175620152017511b21040c020b417f41002016201a54201520175420152017511b1b21040c010b417f20162013852015201485844200522016201354201520145420152014511b1b21040b200120043a00052001201620135a201520145a20152014511b3a00044100210520012c00010e020102030b1036000b20012d0000450d01024020012c00030e020001020b20012d0002450d0120012d000541ff014621050c010b410121050b2001102e02402012450d0020124106742104201041346a21010340024020012802002203450d00200341306c450d002001417c6a280200102e0b200141c0006a2101200441406a22040d000b0b0240201141ffffff1f71450d002010102e0b20050d002000410310f0060c010b200041063a00000b200241c0026a24000bdc2204057f027e157f097e23004190056b22022400200241306a200141306a41c00110e9081a200241f0016a41286a200141286a290300370300200241f0016a41206a200141206a290300370300200241f0016a41186a200141186a290300370300200241f0016a41106a200141106a290300370300200241f0016a41086a200141086a290300370300200220012903003703f00120012802f0012103200241a0046a41186a22044200370300200241a0046a41106a22014200370300200241a0046a41086a22054200370300200242003703a004200241e0026a41a5fec600411a1081022005200241e0026a41086a2206290000370300200220022900e0023703a004200241e0026a4180c3c800410510810220042006290000370300200120022900e002370300200241286a200241a0046a4120108e020240024002402003200228022c410120022802281b460d0020004281808080c0013703000c010b200241a0026a200241306a109706200442003703002001420037030020054200370300200242003703a004200241e0026a41a5fec600411a10810220052006290000370300200220022900e0023703a004200241e0026a4194c5c800410e108102200141086a2006290000370000200120022900e002370000200241206a200241a0046a4120108e020240024002400240024002402002280220450d00024020022802a80220022802242204460d0020004281808080d0003703000c020b200241e0026a10f504024020022802e0022201450d00200241c0046a41086a200241f4026a28020022053602002002200241ec026a29020022073703c004200220022902e40222083702b402200220013602b002200241c0026a41086a2005360200200220073703c002200242003702d40202402008422088a72205450d00200541386c2106200141086a2101410021050340200241e0026a41186a200141186a290000370300200241e0026a41106a200141106a290000370300200241e0026a41086a200141086a290000370300200220012900003703e002200141386a2101200241d0026a200241e0026a200510a402200541016a2105200641486a22060d000b0b20022802a402210920022802a002210a024002402004450d000240024020022802c802200a2f010022014b0d0041002101410a210b0c010b2002418c056a41026a20022802c00220014105746a220141026a2d00003a000020024180056a200141176a29000037030020024188056a2001411f6a2d00003a0000200220012f00003b018c052002200129000f3703f804200129000721072001280003210541012101410d210b0b200241c0046a41086a2206200241f8046a41086a290300370300200241c0046a41106a2203200241f8046a41106a2d00003a0000200220022903f80422083703e004200220022f018c053b01a004200220083703c00420022002418e056a2d00003a00a204200220073700a704200220053600a304200241bf046a20032d00003a0000200241b7046a2006290300370000200220022903c0043700af042001450d01200241e0026a41186a2201200241a0046a41186a290300370300200241e0026a41106a200241a0046a41106a290300370300200241e0026a41086a200241a0046a41086a290300370300200220022903a0043703e0024120102c220c450d06200c20022903e002370000200c41186a2001290300370000200c41106a200241e0026a41106a290300370000200c41086a200241e0026a41086a2903003700000240024020044101460d00200241af046a210d0240024020022802c802200a2f010222014b0d0041002106410a210b0c010b2002418c056a41026a20022802c00220014105746a220141026a2d00003a000020024180056a200141176a29000037030020024188056a2001411f6a2d00003a0000200220012f00003b018c052002200129000f3703f8042001290007210720012800032103410121060b200241e0026a41086a2201200241f8046a41086a220e290300370300200241e0026a41106a2205200241f8046a41106a220f2d00003a0000200220022903f80422083703e004200220022f018c053b01a004200220083703e00220022002418c056a41026a22102d00003a00a204200220073700a704200220033600a304200d20022903e002370000200d41086a22112001290300370000200d41106a221220052d00003a000020060d010b41012104410121130c080b200a41046a2114200241c0046a41186a2215200241a0046a41186a2216290300370300200241c0046a41106a2217200241a0046a41106a2218290300370300200241c0046a41086a2219200241a0046a41086a221a290300370300200220022903a0043703c0042004410174417c6a21034120211b41022113410121040340200241e0026a41186a221c20152903003703002005201729030037030020012019290300370300200220022903c0043703e00202400240024002402013417f6a2004470d00200441016a22062004490d0a2004410174221d2006201d20064b1b22064104200641044b1b220641ffffff3f71200646211d200641057421060240024020040d00200241003602a0040c010b200241013602a8042002200c3602a004200220044105743602a4040b200241f8046a2006201d200241a0046a107d200228028005210620022802f8044101460d0120022802fc04210c200641057621040b200c201b6a220620022903e002370000200641186a201c290300370000200641106a2005290300370000200641086a20012903003700002003450d0b20022802c80220142f010022064b0d0141002106410a210b0c020b2006450d080c090b201020022802c00220064105746a220641026a2d00003a0000200e200641176a290000370300200f2006411f6a2d00003a0000200220062f00003b018c052002200629000f3703f804200629000721072006280003211c410121060b2001200e2903003703002005200f2d00003a0000200220022903f80422083703e004200220022f018c053b01a004200220083703e002200220102d00003a00a204200220073700a7042002201c3600a304200d20022903e00237000020112001290300370000201220052d00003a00002006450d08201441026a211420152016290300370300201720182903003703002019201a290300370300200220022903a0043703c004201b41206a211b201341016a21132003417e6a21030c000b0b410d210b0b410021044101210c0240200941808080807872418080808078460d00200a102e0b410021130c060b20004281808080e0003703000c010b20004281808080e0003703000b20022802a40241808080807872418080808078460d0420022802a002102e0c040b1038000b1036000b200941808080807872418080808078460d00200a102e0b02400240200b410d460d000240200441ffffff3f71450d00200c102e0b2000200b36020441012106200041013602002000410c6a41003602000c010b200241e0026a200241306a41c00110e9081a200241c0046a200241e0026a200241b0026a200241c0026a108d060240024020022802c0044101470d0020022902c40421072000410c6a200241c0046a410c6a28020036020020002007370204200041013602000c010b20022802c404211b200241c8046a280200211402400240200241c0046a410c6a280200220b412c6c2201450d00201b20016a210e201b2101034041092105200241d0026a2001410c6a10a0022206450d0220022802b802200628020022064d0d022001412c6a210a20022802b002200641386c6a220541306a211720012802002203200128020841226c6a2115200541286a21190240034020152003460d01200341226a211c20172802004105742101201928020021050340024020010d00410821050c060b200141606a210120052003412010ec082106200541206a210520060d000b201c21030c000b0b200a2101200a200e470d000b0b2002200b3602c804200220143602c4042002201b3602c004200241e0026a200241c0046a200241d0026a200241b0026a10e706024020022802e0024101470d0020022902e40221072000410c6a200241e0026a410c6a28020036020020002007370204200041013602000c020b200241e8026a22052802002103200241e0026a200c201320022802e4022214200241e0026a410c6a2201280200221b10b7040240024020022802e0024101460d002005280200211520022802e402210b02400240200128020022130d00427f211e4200211f420021204200212142002122427f21230c010b20134106742105200b41206a2101427f211e427f212342002121420021224200211f4200212003402002200141086a2903002207420020012903002208420010e808200241106a200842002008420010e808427f2020427f200241106a41086a29030022242002290300222520257c7c22252007200229030822268420268442005220252024547222061b7c201f427f200229031020061b7c2224201f542206ad7c221f2006201f202054201f2020511b22061b2120427f202420061b211f200720232008201e54200720235420072023511b22061b21232008201e20061b211e427f202220077c202120087c22082021542206ad7c22072006200720225420072022511b22061b2122427f200820061b2121200141c0006a2101200541406a22050d000b0b200241e0026a41286a2020370300200241e0026a41186a20223703002002201f37038003200220213703f0022002201e3703e002200220233703e8020240200241e0026a200241f0016a413010ec08450d0020004281808080b00137030002402013450d0020134106742105200b41346a21010340024020012802002206450d00200641306c450d002001417c6a280200102e0b200141c0006a2101200541406a22050d000b0b201541ffffff1f71450d02200b102e0c020b20004100360200200041086a20022903f001370300200041c4006a41023a0000200041c0006a20133602002000413c6a2015360200200041386a200b360200200041306a200241f0016a41286a290300370300200041286a200241f0016a41206a290300370300200041206a200241f0016a41186a290300370300200041186a200241f0016a41106a290300370300200041106a200241f0016a41086a2903003703000240201b450d00201b412c6c21052014210103400240200141046a2802002206450d00200641306c450d002001280200102e0b2001412c6a2101200541546a22050d000b0b02402003450d002003412c6c450d002014102e0b0240200441ffffff3f71450d00200c102e0b200241d0026a10bc02024020022802c40241ffffff3f71450d0020022802c002102e0b024020022802b8022201450d00200141386c210520022802b002412c6a210103400240200128020041ffffff3f71450d002001417c6a280200102e0b200141386a2101200541486a22050d000b0b20022802b4022201450d06200141386c450d0620022802b002102e0c060b20022902e40221072000410c6a200128020036020020002007370204200041013602000b0240201b450d00201b412c6c21052014210103400240200141046a2802002206450d00200641306c450d002001280200102e0b2001412c6a2101200541546a22050d000b0b2003450d012003412c6c450d012014102e0c010b20004101360200200020053602040240200b450d00200b412c6c2105201b210103400240200141046a2802002206450d00200641226c450d002001280200102e0b2001412c6a2101200541546a22050d000b0b2014450d002014412c6c450d00201b102e0b41002106200441ffffff3f71450d00200c102e0b200241d0026a10bc02024020022802c40241ffffff3f71450d0020022802c002102e0b024020022802b8022201450d00200141386c210520022802b002412c6a210103400240200128020041ffffff3f71450d002001417c6a280200102e0b200141386a2101200541486a22050d000b0b024020022802b4022201450d00200141386c450d0020022802b002102e0b2006450d010b200241306a109b060b20024190056a24000b130020002002ad4220862001ad84101710da080bcc0101037f200028022822012001280200417f6a220236020020002d0001210302400240024020002d00000d004100210020020d022001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a22023602002002450d010c020b4101210020020d012001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d010b2001102e0b200341ff01714102472000720bf10101047f230041c0006b220224004191cdc20021034109210441042105024002400240024002400240200141ff01710e06000102030405000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a419c8ecc001044000b4186cdc2002103410b2104410021050c030b41feccc200210341082104410121050c020b41f9ccc200210341052104410221050c010b41eeccc2002103410b2104410321050b20004183083b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000bf30202047f017e230041a0026b220224002002200010c802200241a0016a200228020022032002280208220410c902200241f4016a2802002105200241f0016a280200210020022903a0012106200241d8006a200241a8016a41c80010e9081a0240024020064201510d0041002100200241106a410041c80010eb081a410021050c010b200241106a200241d8006a41c80010e9081a0b024002402000200572450d00417f200041016a220120012000491b21000c010b20012802002100200241a0016a41086a41033a0000200241a9016a2000290000370000200241b1016a200041086a290000370000200241b9016a200041106a290000370000200241c1016a200041186a290000370000200241003a00a001200241a0016a10fe01410121000b200241a8016a200241106a41c80010e9082101200241f4016a2005360200200241f0016a2000360200200242013703a00120032004200110c80502402002280204450d002003102e0b200241a0026a24000bf20304037f017e047f027e23004190026b22022400200241086a200010c802200241186a200228020822002002280210220310c902200241f0006a41086a2204200241e0006a28020036020020022903182105200242003703182002200241d8006a22062903003703700240024020054201520d00200241306a2903002105200241ec006a2802002107200241e8006a2802002108200241e4006a28020021092002290328210a2002290320210b20024180016a41086a2004280200360200200220022903703703800141012104024002400240200841014b0d002007200972450d0220090d01410121080b2006200229038001370300200241286a200a370300200241ec006a2007360200200241e4006a2009360200200241306a2005370300200641086a20024180016a41086a2802003602002002200b3703202002420137031820022008417f6a36026820002003200241186a41086a10c8050c030b410221040c020b2001280200210420024190016a41086a41043a000020024199016a2004290000370000200241a1016a200441086a290000370000200241a9016a200441106a290000370000200241b1016a200441186a290000370000200241003a00900120024190016a10fe010b2000200310ff01410021040b0240200228020c450d002000102e0b20024190026a240020040b9b0201047f230041c0006b2202240041c893c9002103410621044108210502400240024002400240024002400240200141ff01710e080001020304050607000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a41a4a9cc001044000b41b693c900210341122105410021040c050b41a693c900210341102105410121040c040b419993c9002103410d2105410221040c030b418d93c9002103410c2105410321040c020b418193c9002103410c2105410421040c010b41ed92c900210341142105410521040b200041830c3b0100200041086a2005360200200041046a2003360200200041026a20043a0000200241c0006a24000bf10101047f230041c0006b2202240041fdc3c10021034109210441042105024002400240024002400240200141ff01710e06000102030405000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a41848fcc001044000b41f1c3c1002103410c2104410021050c030b41dac3c100210341172104410121050c020b41cdc3c1002103410d2104410221050c010b41c7c3c100210341062104410321050b20004183123b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000b935608027f017e027f017e017f027e237f057e230041c0076b22042400200241106a2205290300210620032802102107200328020021082002290300210920044184036a200241e8016a2900003702002004418c036a200241f0016a29000037020020044194036a200241f8016a290000370200200441e7e485f3063602f8022004200241e0016a2900003702fc0220044180056a41106a200328021036020020044180056a41086a200341086a2902003703002004200329020037038005200441d0056a200441f8026a20044180056a109d040240024002400240200428029006220a450d00200441f8006a413e6a200441d0056a41386a290300370100200441f8006a41366a200441d0056a41306a290300370100200441f8006a412e6a200441d0056a41286a290300370100200441f8006a41266a200441d0056a41206a290300370100200441f8006a411e6a200441d0056a41186a290300370100200441f8006a41166a200441d0056a41106a290300370100200441f8006a410e6a200441d0056a41086a290300370100200420042903d00537017e20044198066a290300210b2004280294062103200441c8036a200441f8006a41c60010e9081a200441386a41086a200441c8036a410e6a290100370300200441386a41106a200441c8036a41166a290100370300200441386a41186a200441c8036a411e6a290100370300200441386a41206a200441c8036a41266a290100370300200441386a41286a200441c8036a412e6a290100370300200441386a41306a200441c8036a41366a290100370300200441386a41386a200441c8036a413e6a290100370300200420042901ce033703382002290308210c200441f8006a200541f00110e9081a02400240200c4201520d00200441d0056a200441f8006a41f00110e9081a0240200441d0056a410c6a200441c0066a412010ec080d0020042802d80520042802bc06460d020b200441ec036a2205200441d0056a41086a220241206a280200360200200441e4036a220d200241186a290200370200200441dc036a220e200241106a290200370200200441c8036a410c6a220f200241086a290200370200200441013602c803200420022902003702cc03200441c8036a200441a0076a2210200441fc056a20042903d005200910880721112005200441bc066a220241206a280200360200200d200241186a290200370200200e200241106a290200370200200f200241086a290200370200200441013602c803200420022902003702cc03200441c8036a2010200441e0066a20042903d005200910880721022011450d012002450d010c030b200441d0056a200441f8006a41f00110e9081a0240200441d0056a410c6a200441c0066a412010ec080d0020042802d80520042802bc06460d010b200441ec036a2205200441d0056a41086a220241206a280200360200200441e4036a220d200241186a290200370200200441dc036a220e200241106a290200370200200441c8036a410c6a220f200241086a290200370200200441003602c803200420022902003702cc03200441c8036a200441a0076a2210200441fc056a20042903d005200910880721112005200441bc066a220241206a280200360200200d200241186a290200370200200e200241106a290200370200200f200241086a290200370200200441003602c803200420022902003702cc03200441c8036a2010200441e0066a20042903d005200910880721022011450d0020020d020b200441f8006a410610b007200441df056a200441f8006a41086a2802002202360000200420042903783700d705200041186a41003a000020004200370308200020042900d005370019200041216a200441d0056a41086a290000370000200041286a2002360000200042013703000c020b200441f8006a410510b007200441df056a200441f8006a41086a2802002202360000200420042903783700d705200041186a41003a000020004200370308200020042900d005370019200041216a200441d0056a41086a290000370000200041286a2002360000200042013703000c020b0240024020094200520d00200441d0056a420010ac07200441206a20042802d005220520042802d805108e022004280224210d20042802202102024020042802d405450d002005102e0b4101210e0c010b200441d0056a2009427f7c10ac07200441306a20042802d005220d20042802d805108e022004280234210520042802302102024020042802d405450d00200d102e0b024020024101460d00200441f8006a410610b007200441df056a200441f8006a41086a2802002202360000200420042903783700d705200041186a41003a000020004200370308200020042900d005370019200041216a200441d0056a41086a290000370000200041286a2002360000200042013703000c020b200441d0056a200910ac07200441286a20042802d005220e20042802d805108e02200428022c210d20042802282102024020042802d405450d00200e102e0b4100210e0b024020024101460d00200441f8006a410610b007200441df056a200441f8006a41086a2802002202360000200420042903783700d705200041186a41003a000020004200370308200020042900d005370019200041216a200441d0056a41086a290000370000200041286a2002360000200042013703000c010b024002402008200d4b0d00410121124102200820054d200e1b22024102460d012002410171450d010b200441f8006a410610b007200441df056a200441f8006a41086a2802002202360000200420042903783700d705200041186a41003a000020004200370308200020042900d005370019200041216a200441d0056a41086a290000370000200041286a2002360000200042013703000c010b20012d00002202410146221341057421142001411f6a2d000021052001411e6a2d0000210d2001411d6a2d0000210e2001411c6a2d0000210f2001411b6a2d000021102001411a6a2d00002111200141196a2d00002115200141186a2d00002116200141176a2d00002117200141166a2d00002118200141156a2d00002119200141146a2d0000211a200141136a2d0000211b200141126a2d0000211c200141116a2d0000211d2001410f6a2d0000211e2001410e6a2d0000211f2001410d6a2d000021202001410c6a2d000021212001410b6a2d000021222001410a6a2d00002123200141096a2d00002124200141076a2d00002125200141066a2d00002126200141056a2d00002127200141036a2d00002128200141206a2d0000212920012d0010212a20012d0008212b20012d0004212c20012d0002212d20012d0001212e0240024020024101470d002014102c2212450d010b024002400240024002402014410576222f20134f0d00201441047622012013200120134b1b22014104200141044b1b41057421010240024020024101460d00200441003602d0050c010b200441d8056a4101360200200420143602d405200420123602d0050b200441f8006a20014101200441d0056a107d20044180016a280200210120042802784101460d01200428027c21122001410576212f0b20020d01410021010c020b2001450d020c030b410021012012210203402002411f6a20293a00002002202e41ff0171202d4108747241ffff0371202841ff0171202c4108747241107472ad202741ff017120264108747241ffff0371202541ff0171202b4108747241107472ad422086843700002002202441ff017120234108747241ffff0371202241ff017120214108747241107472ad202041ff0171201f4108747241ffff0371201e41ff0171202a4108747241107472ad422086843700082002411e6a20053a0000200241106a201d41ff0171201c4108747241ffff0371201b41ff0171201a4108747241107472ad201941ff017120184108747241ffff0371201741ff017120164108747241107472ad422086843700002002411c6a200e41ff0171200d410874723b0000200241186a201541ff017120114108747241ffff0371201041ff0171200f4108747241107472360000200241206a2102200141016a2101410041ff01710d000b0b200441d0016a200b370300200441cc016a2003360200200441f8006a41d0006a2203200a360200200441f8006a41186a200441386a41086a290300370300200441f8006a41206a200441386a41106a290300370300200441f8006a41286a200441386a41186a290300370300200441f8006a41306a220a200441386a41206a290300370300200441f8006a41386a220d200441386a41286a290300370300200441b8016a220e200441386a41306a290300370300200441f8006a41c8006a220f200441386a41386a2903003703002004200637038001200420093703782004200429033837038801200420073602dc01200420083602d80141d000102c2205450d01200441a0046a41086a2208200441f8006a41106a220241086a290300370300200441a0046a41106a2210200241106a290300370300200441a0046a41186a2211200241186a290300370300200420022903003703a004200a290300210c200d290300210b200e2903002130200f2903002131200441d0056a200310c501200541386a203137030020052030370330200541286a200b3703002005200c370320200541186a2011290300370300200541106a2010290300370300200541086a2008290300370300200520042903a004370300200520042903d005370340200541c8006a200441d0056a41086a280200360200200420013602f0022004202f3602ec02200420123602e8024100211b200441003602c805200442013703c005200420093703d005200441c0056a200441d0056a41081074200420063703d005200441c0056a200441d0056a41081074200441d0056a418997c500108a03200441c8036a20042802d005220320042802d805108b0320042902cc03420020042802c80322021b210c2002410120021b210d024020042802d405450d002003102e0b2004200c4220883e029c042004200d36029804200441186a20044198046a10ab01410821194100211a024020042802180d00200428021c220f200428029c0441306e22022002200f4b1bad42307e220b422088a70d01200ba72202417f4c0d010240024020020d00410821100c010b2002102c2210450d030b200241306e210e02400240200f0d004100210f0c010b410021110340024002400240200428029c0422034108490d00200428029804220a290000210b2004200a41086a360298042004200341786a220236029c0420024108490d00201141016a21152004200341706a220836029c042004200a41106a36029804200a290008213041002102200441003a00f0052003416f6a21030240034020082002460d01200441d0056a20026a200a20026a220141106a2d00003a00002004200141116a360298042004200241016a22013a00f0052004200336029c042003417f6a21032001210220014120470d000b200441c8036a41186a2202200441d0056a41186a290300370300200441c8036a41106a2203200441d0056a41106a290300370300200441c8036a41086a220a200441d0056a41086a290300370300200420042903d0053703c803200141ff01714120490d0120044180056a41086a200a2903002231370300200441e0046a41186a22012002290300370300200441e0046a41106a22022003290300370300200441e0046a41086a22032031370300200420042903c803223137038005200420313703e004200441c0046a41186a220a2001290300370300200441c0046a41106a22012002290300370300200441c0046a41086a22082003290300370300200420042903e0043703c0042011200e470d03200e41016a2202200e4f0d020c070b200241ff0171450d00200441003a00f0050b4100211b410821190240200e450d00200e41306c450d002010102e0b4100211a0c040b200e41017422032002200320024b1b22024104200241044b1bad42307e2231422088a74541037421022031a7210302400240200e0d00200441003602d0050c010b200441083602d805200420103602d0052004200e41306c3602d4050b200441c8036a20032002200441d0056a107d20042802d0032102024020042802c8034101470d0020020d060c050b20042802cc032110200241306e210e0b2010201141306c6a220220303703082002200b370300200220042903c004370310200241186a2008290300370300200241206a2001290300370300200241286a200a290300370300201521112015200f470d000b0b200f410020101b211a200e410020101b211b2010410820101b21190b200441d0056a418997c500200441c0056a108c03200441c8036a20042802d005220320042802d805108d0320042902cc03420020042802c80322021b210b024020042802d405450d002003102e0b200b422088213020042802c805212a20042802c405212720042802c00521280240200ca7450d00200d102e0b2002410120021b21262030a7211d200ba7211c200441d0056a41086a2202200541086a290300370300200441d0056a41106a2203200541106a290300370300200441d0056a41186a2201200541186a290300370300200441d0056a41206a220a200541206a290300370300200441d0056a41286a2208200541286a290300370300200441d0056a41306a220d200541306a290300370300200441d0056a41386a220e200541386a290300370300200441c8036a41086a220f200541cc006a280200360200200420052903003703d005200420052902443703c80302400240200528024022100d004100210a0c010b20044180056a41386a2211200e29030037030020044180056a41306a220e200d29030037030020044180056a41286a220d200829030037030020044180056a41206a2208200a29030037030020044180056a41186a220a200129030037030020044180056a41106a2201200329030037030020044180056a41086a22032002290300370300200441c0056a41086a2202200f280200360200200420042903d00537038005200420042903c8033703c005200441f8026a41386a2011290300370300200441f8026a41306a200e290300370300200441f8026a41286a200d290300370300200441f8026a41206a2008290300370300200441f8026a41186a200a290300370300200441f8026a41106a2001290300370300200441f8026a41086a200329030037030020042004290380053703f802200420103602b803200441bc036a220320042903c005370200200341086a2002280200360200200442013703d005200441003602d805200420093703c803200441d0056a200441c8036a41081074200420063703c803200441d0056a200441c8036a41081074200441e4056a410029009197453702002004410029008997453702dc052004200441f8026a3602ec05200441e0046a200441d0056a10ae01024020042802d405450d0020042802d005102e0b200441d0056a200441e0046a108e0320042802d005220320042802d805108f022102024020042802d405450d002003102e0b02400240024020020d00200441c8036a200441f8026a41d00010e9081a200441c0046a200441e8026a10c801200441d0056a200441c8036a41d00010e9081a200441d0056a41d0006a220241086a200441c0046a41086a280200360200200220042903c004370200200441c8036a200441e0046a108e0320042802c803220220042802d003200441d0056a108f03024020042802cc03450d002002102e0b02402004280294062202450d00200241306c450d00200428029006102e0b024020042802a40641ffffff3f71450d0020042802a006102e0b200441c8036a41186a220e200441e0046a41186a290300370300200441c8036a41106a220f200441e0046a41106a290300370300200441c8036a41086a2210200441e0046a41086a290300370300200420042903e0043703c803410021020240201a0e020302000b41002102201a210303400240417f20192003410176220a20026a220841306c6a220d290300220c200952200c2009541b22010d00417f200d290308220c200652200c2006541b21010b2002200820014101461b21022003200a6b220341014d0d020c000b0b4100210a20042802bc032202450d02200241306c450d0220042802b803102e0c020b02400240417f2019200241306c6a2201290300220c200952200c2009541b22030d0041ff0121032001290308220c2006540d01200c20065221030b2003450d010b2002200341ff017141ff01466a21020b200441d0056a41186a200e290300370300200441d0056a41106a200f290300370300200441d0056a41086a2010290300370300200420042903c8033703d00502400240201a2002490d000240201a201b470d00201b41016a2203201b490d04201b41017422012003200120034b1b22034104200341044b1bad42307e220c422088a7454103742103200ca7210102400240201b0d00200441003602c0040c010b200441083602c804200420193602c0042004201b41306c3602c4040b200441a0046a20012003200441c0046a107d20042802a804210320042802a0044101460d0220042802a4042119200341306e211b0b2019200241306c6a220341306a2003201a20026b41306c10ea081a2003200637030820032009370300200341286a200441d0056a41186a2201290300370300200341206a200441d0056a41106a2208290300370300200341186a200441d0056a41086a220d290300370300200320042903d0053703102001200441c8036a41186a2903003703002008200441c8036a41106a290300370300200d200441c8036a41086a290300370300200420042903c8033703d0050240201d201c470d00201c41016a2202201c490d04201c41017422032002200320024b1b22024104200241044b1b220241ffffff3f7120024621032002410574210202400240201c0d00200441003602c0040c010b200441013602c804200420263602c0042004201c4105743602c4040b200441a0046a20022003200441c0046a107d20042802a8042102024020042802a0044101470d0020020d060c050b20042802a40421262002410576211c0b4101210a201a41016a211a2026201d4105746a220220042903d005370000200241186a2001290300370000200241106a2008290300370000200241086a200d290300370000201d41016a211d0c020b2002201a1045000b20030d020c010b200541d0006a220220026b220341d0006d210102402003450d00200141d0006c2103200241c4006a21020340024020022802002201450d00200141306c450d002002417c6a280200102e0b200241d0006a2102200341b07f6a22030d000b0b2005102e024002400240200a450d00024002400240201d450d00201d410574210520044194066a2102202621030340200441c0056a2003108e03200441d0056a20042802c005220a20042802c805109003200441c8036a41086a2208200441d0056a41086a290300370300200441c8036a41106a220d200441d0056a41106a290300370300200441c8036a41186a220e200441d0056a41186a290300370300200441c8036a41206a220f200441d0056a41206a290300370300200441c8036a41286a2210200441d0056a41286a290300370300200441c8036a41306a2211200441d0056a41306a290300370300200441c8036a41386a2215200441d0056a41386a290300370300200441e0046a41086a2216200241086a290200370300200441e0046a41106a2217200241106a290200370300200441e0046a41186a2218200241186a280200360200200420042903d0053703c803200420022902003703e00402402004280290062201450d00200441f8026a41386a2015290300370300200441f8026a41306a2011290300370300200441f8026a41286a2010290300370300200441f8026a41206a200f290300370300200441f8026a41186a200e290300370300200441f8026a41106a200d290300370300200441f8026a41086a2008290300370300200441c0046a41086a2016290300370300200441c0046a41106a2017290300370300200441c0046a41186a2018280200360200200420042903c8033703f802200420042903e0043703c0040b024020042802c405450d00200a102e0b20010d02200341206a2103200541606a22050d000b0b4200210c4108210a0c010b20044180056a41386a2202200441f8026a41386a29030037030020044180056a41306a2208200441f8026a41306a29030037030020044180056a41286a220d200441f8026a41286a29030037030020044180056a41206a220e200441f8026a41206a29030037030020044180056a41186a220f200441f8026a41186a29030037030020044180056a41106a2210200441f8026a41106a29030037030020044180056a41086a2211200441f8026a41086a290300370300200441a0046a41086a2215200441c0046a41086a290300370300200441a0046a41106a2216200441c0046a41106a290300370300200441a0046a41186a2217200441c0046a41186a280200360200200420042903f80237038005200420042903c0043703a00441e000102c220a450d05200a200429038005370300200a2001360240200a20042903a004370244200a41386a2002290300370300200a41306a2008290300370300200a41286a200d290300370300200a41206a200e290300370300200a41186a200f290300370300200a41106a2010290300370300200a41086a2011290300370300200a41cc006a2015290300370200200a41d4006a2016290300370200200a41dc006a2017280200360200024020054120470d00428180808010210c0c010b200341206a210f2026201d4105746a222541606a212b200441d0056a41c4006a2102428180808010210c0340200f21030340200441c0056a2003108e03200441d0056a20042802c005220e20042802c805109003200441c8036a41086a2205200441d0056a41086a221e290300370300200441c8036a41106a2208200441d0056a41106a221f290300370300200441c8036a41186a220d200441d0056a41186a2220290300370300200441c8036a41206a220f200441d0056a41206a2221290300370300200441c8036a41286a2210200441d0056a41286a2222290300370300200441c8036a41306a2211200441d0056a41306a2223290300370300200441c8036a41386a2215200441d0056a41386a2224290300370300200441e0046a41086a2216200241086a290200370300200441e0046a41106a2217200241106a290200370300200441e0046a41186a2218200241186a280200360200200420042903d0053703c803200420022902003703e00402402004280290062201450d00200441f8026a41386a2015290300370300200441f8026a41306a2011290300370300200441f8026a41286a2010290300370300200441f8026a41206a200f290300370300200441f8026a41186a200d290300370300200441f8026a41106a2008290300370300200441f8026a41086a2005290300370300200441c0046a41086a2016290300370300200441c0046a41106a2017290300370300200441c0046a41186a2018280200360200200420042903c8033703f802200420042903e0043703c0040b024020042802c405450d00200e102e0b024020010d002025200341206a2203470d010c030b0b20044180056a41386a220e200441f8026a41386a29030037030020044180056a41306a220f200441f8026a41306a29030037030020044180056a41286a2210200441f8026a41286a29030037030020044180056a41206a2211200441f8026a41206a29030037030020044180056a41186a2215200441f8026a41186a29030037030020044180056a41106a2216200441f8026a41106a29030037030020044180056a41086a2217200441f8026a41086a290300370300200441a0046a41086a2218200441c0046a41086a290300370300200441a0046a41106a222c200441c0046a41106a290300370300200441a0046a41186a222d200441c0046a41186a280200360200200420042903f80237038005200420042903c0043703a004201e2017290300370300201f20162903003703002020201529030037030020212011290300370300202220102903003703002023200f2903003703002024200e29030037030020042004290380053703d005200520182903003703002008202c290300370300200d202d280200360200200420042903a0043703c80302400240200c422088a7220e200ca7460d00200c210b0c010b200e41016a220f200e490d06200e4101742210200f200f2010491b220f4104200f41044b1bad42e0007e220b422088a745410374210f200ba7211002400240200e0d00200441003602f8020c010b20044108360280032004200a3602f8022004200e41e0006c3602fc020b200441e0046a2010200f200441f8026a107d20042802e804210f20042802e0044101460d0420042802e404210a200f41e0006ead210b0b200341206a210f200a200e41e0006c6a220e20042903d005370300200e41106a201f290300370300200e41086a201e2903003703002023290300213020242903002131202229030021322021290300213320202903002134200e41c0006a2001360200200e41186a2034370300200e41206a2033370300200e41286a2032370300200e41386a2031370300200e41306a2030370300200e41c4006a20042903c803370200200e41cc006a2005290300370200200e41d4006a2008290300370200200e41dc006a200d280200360200200b42ffffffff0f83200c4280808080107c4280808080708384210c202b2003470d000b0b200441f0056a201a360200200441ec056a201b360200200441e4056a201d360200200441e0056a201c360200200420193602e805200420263602dc052004202a3602d805200420273602d405200420283602d005201a41306c4104722202417f4c0d032002102c2203450d042004410036028003200420023602fc02200420033602f802201a200441f8026a10760240201a450d002019201a41306c6a2101201921020340200420022903003703c803200441f8026a200441c8036a410810742004200241086a2903003703c803200441f8026a200441c8036a410810744120102c2203450d06200442203702cc03200420033602c803200441c8036a200241106a220241201074200441f8026a20042802c803220320042802d0031074024020042802cc03450d002003102e0b200241206a22022001470d000b0b200441c8036a418997c500108a0320042802c803220220042802d003200441f8026a10c502024020042802cc03450d002002102e0b024020042802fc02450d0020042802f802102e0b200441c8036a418997c500200441d0056a108c0320042802c803220220042802d003200441dc056a109103024020042802cc03450d002002102e0b02402027450d002028102e0b0240201c41ffffff3f71450d002026102e0b201b450d02201b41306c450d022019102e0c020b02402027450d002028102e0b0240201c41ffffff3f71450d002026102e0b4100210a0240201b450d00201b41306c450d002019102e0b0c010b200f0d020c010b024020042802ec0241ffffff3f71450d0020042802e802102e0b0240200a0d00024020042802cc012202450d00200241306c450d0020042802c801102e0b200441f8006a410710b007200441df056a200441f8006a41086a2802002202360000200420042903783700d705200041186a41003a000020004200370308200020042900d005370019200041216a200441d0056a41086a290000370000200041286a2002360000200042013703000c040b02400240024020074101200741014b1b2202418094ebdc036e2002418094ebdc03704100476a22034101200341014b1b220320024b0d002002200c422088a7220541036c220120022001491b20036ead428094ebdc037e200220036ead80a7109e042101200541ffffffff03712005470d0320054102742202417f4c0d030240024020020d00410421080c010b2002102c2208450d050b02402002410276220720054f0d00200241017622032005200320054b1b22034104200341044b1b220341ffffffff03712003464102742107200341027421030240024020020d00200441003602d0050c010b200441d8056a4104360200200420023602d405200420083602d0050b200441c8036a20032007200441d0056a107d200441d0036a2802002102024020042802c8034101460d0020042802cc032108200241027621070c030b20020d050c040b20050d01410021020c020b41d0d8c800411941bcd7cc001039000b2005210320082102034020022001360200200241046a21022003417f6a22030d000b200521020b200441086a200a20052008200220042802d801109203200442013703f8022004410036028003200420093703d005200441f8026a200441d0056a41081074200420063703d005200441f8026a200441d0056a410810742004418c036a4100290091974537020020044100290089974537028403200441e3036a200441f8026a41186a280200360000200441db036a200441f8026a41106a290300370000200441d3036a200429038003370000200420042903f8023700cb03200441d9056a200441c8036a41086a290000370000200441e1056a200441c8036a41106a290000370000200441d0056a41186a200441df036a290000370000200441f0056a41013a0000200441053a00d005200420042900c8033700d105200441d0056a10fe0102402007450d002008102e0b02402005450d00200541e0006c2103200a41d4006a210203400240200241706a2802002201450d00200141306c450d002002416c6a280200102e0b0240200228020041ffffff3f71450d002002417c6a280200102e0b200241e0006a2102200341a07f6a22030d000b0b0240200ca72202450d00200241e0006c450d00200a102e0b024020042802cc012202450d00200241306c450d0020042802c801102e0b2000420037030820004200370300200041186a41013a00000c030b1038000b1036000b2003450d00200341306c450d00200a102e0b200441c0076a24000b860301037f230041e0006b22032400200341086a41bed8c8004108108102200341186a41a4fcc8004112108102200320013602482003200341c8006a410410a301370338200341dc006a2201200341c8006a41046a3602002003200341386a41086a3602542003200341c8006a3602582003200341386a360250200341286a200341d0006a107c200320023602442003200341c4006a410410a3013703482001200341c4006a41046a3602002003200341c8006a41086a3602542003200341c4006a3602582003200341c8006a360250200341386a200341d0006a107c0240024020032802302201200328024022046a41206a2202417f4c0d000240024020020d00410121050c010b2002102c2205450d020b2000410036020820002002360204200020053602002000200341086a411010742000200341186a4110107420002003280228220220011074200020032802382201200410740240200328023c450d002001102e0b0240200328022c450d002002102e0b200341e0006a24000f0b1038000b1036000baff4020b027f027e077f027e047f0e7e027f057e047f047e0e7f230022032104200341c00b6b41607122032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e1a000102030405060708090a0b0c0d0e0f10111213141516171819000b200341d40a6a4101360200200342013702c40a2003419cc3cb003602c00a200341043602940920034194c3cb0036029009200320034190096a3602d00a200341c00a6a41c0accb001044000b200141306a2903002105200141286a2903002106200341e0066a41186a200141196a290000370300200341e0066a41106a200141116a290000370300200341e0066a41086a200141096a290000370300200320012900013703e006200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a200241186a290200370300200341c00a6a41106a200241106a290200370300200341c00a6a41086a200241086a290200370300200320022902003703c00a20034190096a200341c00a6a10c102200341b8046a41086a220220034190096a41096a290000370300200341b8046a41106a220120034190096a41116a290000370300200341b8046a41186a220720034190096a41196a29000037030020032003290091093703b80420032d0090094101460d25200341d8046a41186a2007290300370300200341d8046a41106a2001290300370300200341d8046a41086a2002290300370300200320032903b8043703d8040240024020064280a094a58d1d5441002005501b450d00200341c0056a41011093080c010b20034198066a2201420037030020034190066a2202420037030020034180066a41086a220742003703002003420037038006200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c00737038006200341c0076a41b4f6ca00410f10810220012008290000370300200220032900c007370300200341286a20034180066a4120108e02200328022c21092003280228210a2001420037030020024200370300200742003703002003420037038006200341c0076a41de80ca00410910810220072008290000370300200320032900c00737038006200341c0076a418c81ca00410b10810220012008290000370300200220032900c00737030020034194096a41003a00002003410036029009200341206a20034180066a412020034190096a4105410010ca0402402003280220450d00200320032802242201410520014105491b3602c40a200320034190096a3602c00a200341186a200341c00a6a10ab0120032802180d00200328021c41e400490d00200341c0056a41231093080c010b200341c00a6a41186a2201200341e0066a41186a290300370300200341c00a6a41106a2207200341e0066a41106a290300370300200341c00a6a41086a2208200341e0066a41086a290300370300200320032903e0063703c00a20034190096a200341c00a6a10b7080240200328029409220b450d00200328029009210c200142003703002007420037030020084200370300200342003703c00a20034188086a41d9fcc6004106108102200820034188086a41086a220d29000037030020032003290088083703c00a20034188086a4180f4cb0041061081022001200d2900003703002007200329008808370300200341106a200341c00a6a4120108e0202402003280214410020032802101b200c4f0d00200341c0056a410610930820032802980941ffffff3f71450d02200b102e0c020b20032802980941ffffff3f71450d00200b102e0b200341c00a6a200341d8046a2006200510c302200341ca066a220120032d00c30a3a0000200320032f00c10a3b01c806024020032d00c00a22074106470d0020034180066a41186a420037030020034180066a41106a420037030020034180066a41086a220142003703002003420037038006200341c0076a41de80ca0041091081022001200341c0076a41086a2207290000370300200320032900c00737038006200341c0076a41b4f6ca00410f108102200241086a2007290000370000200220032900c007370000200320094100200a1b220141016a3602c00a20034180066a4120200341c00a6a410410b2012003200341d8046a36028006200341c0076a200110940820032802c807210820032802c00721074118102c2209450d6020034218370294092003200936029009410120034190096a107620034190096a20032802800641201074200320053703c80a200320063703c00a20034190096a200341c00a6a4110107420072008200328029009220920032802980910b2010240200328029409450d002009102e0b024020032802c407450d002007102e0b200341cc0a6a200341e0066a41086a290300370200200341d40a6a200341e0066a41106a290300370200200341dc0a6a200341e0066a41186a290300370200200341ec0a6a200341d8046a41086a290300370200200341f40a6a200341d8046a41106a290300370200200341fc0a6a200341d8046a41186a290300370200200320013602c00a200320032903e0063702c40a200320032903d8043702e40a20034180066a41186a420037030020034180066a41106a420037030020034180066a41086a220742003703002003420037038006200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c00737038006200341c0076a418c81ca00410b108102200241086a2008290000370000200220032900c0073700004104102c2202450d60200342043702c407200320023602c0072003200136029009200341c0076a20034190096a410410744120102c2202450d602003422037029409200320023602900920034190096a200341c00a6a41047241201074200341c0076a200328029009220220032802980910740240200328029409450d002002102e0b200341c0076a200341e40a6a4120107420034190096a41086a200341c0076a41086a280200360200200320032903c0073703900920034180066a412020034190096a10c702200341d80a6a2005370300200341d00a6a2006370300200341cc0a6a2001360200200341c00a6a41086a41003a0000200341093a00c00a200341c00a6a10fe01200341063a00c0050c630b20032902c40a2105200320073a00c005200320032f01c8063b00c105200320053702c405200320012d00003a00c3050b20032d00c0054106460d6120032902c40521050c600b200141086a2802002109200141046a2802002101200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a200241186a290200370300200341c00a6a41106a200241106a290200370300200341c00a6a41086a200241086a290200370300200320022902003703c00a20034190096a200341c00a6a10c102200341b8046a41086a220220034199096a290000370300200341b8046a41106a2207200341a1096a290000370300200341b8046a41186a2208200341a9096a29000037030020032003290091093703b80420032d0090094101460d23200341d8046a41186a2008290300370300200341d8046a41106a2007290300370300200341d8046a41086a2002290300370300200320032903b8043703d804200341c00a6a200110940820032802c80a210820032802c00a21024100210720034190096a41046a41003a00002003410036029009200341306a2002200820034190096a4105410010ca04024002402003280230450d0020032802342107200341003a00f00802402007410520074105491b2207450d002007417f6a210b024020032d0090092207410371220a4103460d00024002400240200a0e03000102000b2007410276210a410121070c050b200b450d0220032d009109410874200772220741ffff0371418002490d02200741fcff0371410276210a410121070c040b200b4103490d0120032f00910920032d00930941107472410874200772220741ffff034d0d012007410276210a410121070c030b200741034b0d00200b4104490d0041012107200328009109220a41ffffffff034b0d020b41c4a6c000412010ef022002200810c907410021070b0b024020032802c40a450d002002102e0b2007450d220240200a20094d0d00200341c0076a41201093080c5b0b20034190096a2001109408200341c00a6a200328029009220a20032802980910ae052003280294092102024002400240024020032802c00a2208450d00200341d80a6a2903002105200341d00a6a2903002106200341c80a6a280200210920032802c40a210702402002450d00200a102e0b200341c00a6a200341d8046a2006200510c302200341ca066a220220032d00c30a3a0000200320032f00c10a3b01c80620032d00c00a220a4106470d0320034180066a41186a220a200341d8046a41186a29030037030020034180066a41106a220b200341d8046a41106a29030037030020034180066a41086a220c200341d8046a41086a290300370300200320032903d8043703800620092007470d02200741016a220220074f0d010c620b02402002450d00200a102e0b200341c0076a41021093080c5d0b2007410174220d2002200d20024b1b22024104200241044b1b220241ffffff3f71200246210d200241057421020240024020070d00200341003602c00a0c010b200341c80a6a4101360200200320083602c00a200320074105743602c40a0b20034190096a2002200d200341c00a6a107d20034198096a280200210202402003280290094101470d002002450d610c600b2003280294092108200241057621070b200820094105746a2202200329038006370000200241186a200a290300370000200241106a200b290300370000200241086a200c290300370000200341e0066a2001109408200941016a22024105744114722201417f4c0d5f20032802e806210b20032802e006210a2001102c220c450d5e200341003602980920032001360294092003200c36029009200220034190096a107602402002450d00200941057441206a210120082102034020034190096a200241201074200241206a2102200141606a22010d000b0b200320063703c00a200320053703c80a20034190096a200341c00a6a41101074200a200b200328029009220220032802980910b2010240200328029409450d002002102e0b024020032802e406450d00200a102e0b0240200741ffffff3f71450d002008102e0b200341063a00c0070c5d0b20032902c40a21052003200a3a00c007200320032f01c8063b00c107200320053702c407200320022d00003a00c307200741ffffff3f71450d5a2008102e0c5a0b200141046a2802002108200341d0086a41046a22092001410f6a2d00003a000020032001410b6a2800003602d008200141186a2903002105200141106a2903002106200141286a290300210e200141206a290300210f2001410a6a2d00002110200141096a2d00002111200141086a2d00002112200341c00a6a41286a220a200241286a280200360200200341c00a6a41206a220b200241206a290200370300200341c00a6a41186a220c200241186a290200370300200341c00a6a41106a220d200241106a290200370300200341c00a6a41086a2213200241086a290200370300200320022902003703c00a20034190096a200341c00a6a10c10220034180066a41086a220220034190096a41096a29000037030020034180066a41106a2201200341a1096a29000037030020034180066a41186a2207200341a9096a29000037030020032003290091093703800620032d0090094101460d1e200341c0076a41186a2007290300370300200341c0076a41106a2001290300370300200341c0076a41086a200229030037030020032003290380063703c00720034198046a41046a20092d00003a0000200320032802d00836029804200341f0086a2008108905200341c00a6a20032802f008220920032802f808108a052002200341800b6a2903003703002001200341880b6a2903003703002007200341900b6a29030037030020034180066a41206a200341980b6a29030037030020034180066a41286a200341a00b6a290300370300200320032800c10a3602c806200320032800c40a3600cb062003200341f80a6a2903003703800602400240024020032d00c00a22024102460d00200341f00a6a2903002114200a2903002115200b2903002116200c2903002117200d290300211820132903002119200341c0056a41286a220120034180066a41286a290300370300200341c0056a41206a220720034180066a41206a290300370300200341c0056a41186a220a20034180066a41186a290300370300200341c0056a41106a220b20034180066a41106a290300370300200341c0056a41086a220c20034180066a41086a29030037030020032003290380063703c005024020032802f408450d002009102e0b200341c00a6a41286a2001290300370300200341c00a6a41206a2007290300370300200341c00a6a41186a200a290300370300200341c00a6a41106a200b290300370300200341c00a6a41086a200c290300370300200320032903c0053703c00a02402002450d0020034190096a4111109308200341d8046a20034190096a41e40010e9081a0c020b20034190096a412c6a201437020020034190096a411c6a201637020020034190096a410c6a201837020020034190096a413c6a200341c00a6a41086a29030037020020034190096a41c4006a200341c00a6a41106a220229030037020020034190096a41cc006a200341c00a6a41186a29030037020020034190096a41d4006a200341c00a6a41206a29030037020020034190096a41dc006a200341c00a6a41286a290300370200200320153702b409200320173702a4092003201937029409200320032903c00a3702c409200341d8046a20034190096a41e40010e9081a200341e0066a41086a200341d8046a413c6a290200370300200341e0066a41106a200341d8046a41c4006a290200370300200341e0066a41186a200341d8046a41cc006a290200370300200341e0066a41206a200341d8046a41d4006a290200370300200341e0066a41286a200341d8046a41dc006a2902003703002003200329028c053703e006200341d8046a410c6a290200211a200341d8046a411c6a290200211b200341d8046a412c6a290200211820032902dc04211c20032902ec04211d20032902fc04211e20034190096a200341c0076a10c802200341c00a6a200328029009220720032802980910c902427f2005200e7c2006200f7c22172006542201ad7c22142001201420055420142005511b220b1b2005201241ff017141014622011b2115427f2017200b1b200620011b21192002290300420020032903c00a42015122021b211620032903c80a420020021b211f0240200328029409450d002007102e0b2019201f56201520165620152016511b450d0220034188086a411b1093080c590b024020032802f408450d002009102e0b20034190096a4111109308200341d8046a20034190096a41e40010e9081a0b20034188086a41086a200341d8046a41086a280200360200200320032902d804370388080c570b200341c0056a200341c0076a10b808200341c00a6a20032802c00520032802c80510b105200341e8086a41026a220220032d00c30a3a000041082107200341d0066a41086a200341a00b6a290300370300200320032f00c10a3b01e8082003200341980b6a2903003703d006200341900b6a2903002120200341880b6a2903002121200341ac0b6a2802002122200341a80b6a28020021230240024020032d00c00a220c4102470d00420021244100210d42002125420021264100211342002119420021274200211f420021284100210c0c010b200341d80a6a2903002127200341d00a6a2903002119200341e80a6a2903002128200341e00a6a290300211f200341800b6a2903002126200341f80a6a2903002125200341c00a6a41086a280200210d200341cc0a6a2802002113200341f00a6a290300212420032802c40a2107200341c0086a41026a20022d00003a000020034190096a41086a200341d0066a41086a290300370300200320032f01e8083b01c008200320032903d006370390090b0240200c450d0020034180066a41181093080c4f0b41002101024002400240024020130e025000010b41002102200728020022012008460d01200120084921010c4f0b4100210220132101034020022001410176220920026a220a2007200a41306c6a28020020084b1b2102200120096b220141014b0d000b02402007200241306c6a28020022012008460d00201341e4004b0d02200220012008496a21010c4f0b201320024d0d220b2007200241306c6a220141206a2109200141186a2903002116200141106a222929030021152001410a6a210a200141096a222a2d0000212b0240024002400240024020012d0008222c4101470d00200141286a290300212d2009290300212e20034198016a20152016420a420010e70820034188016a202e202d420a420010e708201e20157d222f201e56201820167d201e201554ad7d221620185620162018511b0d02202f202e7d2230202f562016202d7d202f202e54ad7d221520165620152016511b0d02201c20032903980122167d222f201c56201a20034198016a41086a2903007d201c201654ad7d2216201a562016201a511b0d01201d20032903880122187d221e201d56201b20034188016a41086a2903007d201d201854ad7d2218201b562018201b511b450d032030211e20152118202f211c2016211a0c020b02400240200a2d0000223141ff0171450d0041062132024002400240024002400240024020314107710e0700010203040506000b410021320c050b410121320c040b410221320c030b410321320c020b410421320c010b410521320b200341b8016a201642002032ad222e420010e808200341c8016a20154200202e420010e808427f200341d0016a290300222e20032903b8017c223020032903c0014200522030202e547222321b212d427f20032903c80120321b212e0c010b200341a8016a20152016420a420010e708200341b0016a290300212d20032903a801212e0b201e20157d2230201e56201820167d201e201554ad7d221520185620152018511b0d010240202b41ff01710d00201d202e7d2218201d56201b202d7d201d202e54ad7d2216201b562016201b511b0d012018211d2016211b201c212f201a21160c040b201c202e7d222f201c56201a202d7d201c202e54ad7d2216201a562016201a511b450d030b2030211e201521180b20034180066a411a1093080c510b201e211d2018211b0b201320024d0d20200141086a2101202c0d4a202b41ff0171222b4102460d4a4200201520287d2030201f54ad7d22182030201f7d221e203056201820155620182015511b222c1b21184200201e202c1b211e0240202b0d004200201b20277d201d201954ad7d2215201d20197d221a201d562015201b562015201b511b222b1b211b4200201a202b1b211d0c4c0b4200201620277d202f201954ad7d2215202f20197d221c202f56201520165620152016511b222b1b211a4200201c202b1b211c0c4c0b20034180066a41211093080c4e0b200141046a280200210b200241196a2d0000210c200241186a2d0000210d200241166a2f01002113200241156a2d00002112200241146a2d00002110200241126a2f01002111200241116a2d00002122200241106a2d000021232002410c6a2802002109200241086a280200210a200241046a2802002108200241026a2f0100212b2002280228210120022d0001212920022d00002107200341c00a6a41086a200241226a28010036020020032002411a6a2901003703c00a02400240024020074101470d0020012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200841ff0171450d010c480b20074103460d0120070d482008410876210220084110762107200a411076212a200a410876212c200941107621322009410876213120032903c00a210520012001280200417f6a22333602002003200537039009024020330d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22332033280200417f6a223336020020330d002001102e0b2003200c3a00d70a2003200d3a00d60a200320133b01d40a200320123a00d30a200320103a00d20a200320113b01d00a200320223a00cf0a200320233a00ce0a200320323b01cc0a200320313a00cb0a200320093a00ca0a2003202a3b01c80a2003202c3a00c70a2003200a3a00c60a200320073b01c40a200320023a00c30a200320083a00c20a2003202b3b01c00a20032003290390093703d80a202941ff0171450d014110102c2202450d5d200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d5d20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220736020020070d482002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22072007280200417f6a220736020020070d482002102e0c480b200a41036c2009410174490d460b200341f0086a200b108905200341c00a6a20032802f008220220032802f808108a0520034180066a41086a2201200341800b6a29030037030020034180066a41106a2207200341880b6a29030037030020034180066a41186a2208200341900b6a29030037030020034180066a41206a2209200341980b6a29030037030020034180066a41286a220a200341a00b6a290300370300200320032800c10a3602c806200320032800c40a3600cb062003200341f80a6a2903003703800602400240024020032d00c00a220c4102460d00200341f00a6a2903002116200341c00a6a41286a2903002117200341c00a6a41206a2903002118200341c00a6a41186a2903002119200341c00a6a41106a290300211f200341c00a6a41086a290300211e200341c0056a41286a200a290300370300200341c0056a41206a2009290300370300200341c0056a41186a2008290300370300200341c0056a41106a2007290300370300200341c0056a41086a200129030037030020032003290380063703c005024020032802f408450d002002102e0b200341c0076a41086a200341c0056a41086a2903002205370300200341c0076a41106a200341c0056a41106a2903002206370300200341c0076a41186a200341c0056a41186a290300220e370300200341c0076a41206a200341c0056a41206a290300220f370300200341c0076a41286a200341c0056a41286a2903002214370300200320032903c00522153703c007200341c00a6a41286a22082014370300200341c00a6a41206a2209200f370300200341c00a6a41186a2202200e370300200341c00a6a41106a22012006370300200341c00a6a41086a22072005370300200320153703c00a0240200c450d0020034190096a4111109308200341d8046a20034190096a41e40010e9081a0c020b200341bc096a2016370200200341ac096a20183702002003419c096a201f370200200341cc096a2007290300370200200341d4096a2001290300370200200341dc096a2002290300370200200341e4096a2009290300370200200341ec096a2008290300370200200320173702b409200320193702a4092003201e37029409200320032903c00a3702c409200341d8046a20034190096a41e40010e9081a200341e0066a200341dc046a41e00010e9081a20034180066a41186a200341b0076a290300220537030020034180066a41106a200341a8076a290300220637030020034180066a41086a200341a0076a290300220e3703002003200329039807220f3703800620022005370300200120063703002007200e3703002003200f3703c00a20034190096a200341c00a6a10b9082003280290092201200328029809108f0221020240200328029409450d002001102e0b2002450d0220034188086a41041093080c460b024020032802f408450d002002102e0b20034190096a4111109308200341d8046a20034190096a41e40010e9081a0b20034188086a41086a200341d8046a41086a280200360200200320032902d804370388080c440b200341c00a6a41186a20034180066a41186a290300370300200341c00a6a41106a20034180066a41106a290300370300200341c00a6a41086a220120034180066a41086a29030037030020032003290380063703c00a20034190096a200341c00a6a10b90820032802900921022003280298092107200341013a00f00820022007200341f0086a410110b2010240200328029409450d002002102e0b200341cc0a6a200b360200200141063a0000200341093a00c00a200341c00a6a10fe01200341c00a6a200b10890520032802c00a220220032802c80a10ff01024020032802c40a450d002002102e0b200341063a0088080c440b20034190096a41186a200141196a29000037030020034190096a41106a200141116a29000037030020034190096a41086a200141096a2900003703002003200129000137039009200241026a2f0100210b200241046a2802002108200241086a28020021092002410c6a280200210a200241106a2d0000210c200241116a2d0000210d200241126a2f01002113200241146a2d00002112200241156a2d00002110200241166a2f01002111200241186a2d00002122200241196a2d0000212320022d0001212b2002280228210120022d00002107200341c00a6a41086a200241226a28010036020020032002411a6a2901003703c00a024002400240024020074101470d0020012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200841ff01710d002009410174200a4f0d030b4110102c2202450d5e200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d5e20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220736020020070d012002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22072007280200417f6a220736020020070d012002102e0c010b20074103460d0120070d002008410876210220084110762107200941107621292009410876212a200a411076212c200a410876213220032903c00a210520012001280200417f6a2231360200200320053703d804024020310d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22312031280200417f6a223136020020310d002001102e0b200320233a00d70a200320223a00d60a200320113b01d40a200320103a00d30a200320123a00d20a200320133b01d00a2003200d3a00cf0a2003200c3a00ce0a2003202c3b01cc0a200320323a00cb0a2003200a3a00ca0a200320293b01c80a2003202a3a00c70a200320093a00c60a200320073b01c40a200320023a00c30a200320083a00c20a2003200b3b01c00a200320032903d8043703d80a202b41ff0171450d014110102c2202450d5d200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d5d20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220736020020070d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22072007280200417f6a220736020020070d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200341023a00e0060c010b20034180066a41186a2201420037030020034180066a41106a2202420037030020034180066a41086a220742003703002003420037038006200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c00737038006200341c0076a418081ca00410c10810220012008290000370300200220032900c0073703000240024020034180066a4120108f020d00200341c00a6a41186a20034190096a41186a290300370300200341c00a6a41106a20034190096a41106a290300370300200341c00a6a41086a20034190096a41086a29030037030020032003290390093703c00a200341d8046a200341c00a6a10b708024020032802dc042201450d0020032802d8042107200341d80a6a22084200370300200341d00a6a22094200370300200341c00a6a41086a220a4200370300200342003703c00a20034188086a41d9fcc6004106108102200a20034188086a41086a220b29000037030020032003290088083703c00a20034188086a4180f4cb0041061081022008200b2900003703002009200329008808370300200341d8016a200341c00a6a4120108e02024020032802dc01410020032802d8011b20074f0d00200341e0066a410610930820032802e00441ffffff3f71450d032001102e0c030b20032802e00441ffffff3f71450d002001102e0b200341c00a6a41186a20034190096a41186a290300370300200341c00a6a41106a20034190096a41106a290300370300200341c00a6a41086a20034190096a41086a29030037030020032003290390093703c00a200341003a00e00a20034180066a41186a420037030020034180066a41106a420037030020034180066a41086a220142003703002003420037038006200341c0076a41de80ca0041091081022001200341c0076a41086a2207290000370300200320032900c00737038006200341c0076a418081ca00410c108102200241086a2007290000370000200220032900c00737000020034180066a200341c00a6a10ca05200341063a00e0060c440b200341e0066a41051093080b20032d00e0064106460d420b20032802e0062102200020032902e406370024200041206a2002360000200041186a41003a00002000420037030820004201370300200424000f0b20034190096a41186a200141196a29000037030020034190096a41106a200141116a29000037030020034190096a41086a200141096a2900003703002003200129000137039009200241026a2f0100210b200241046a2802002108200241086a28020021092002410c6a280200210a200241106a2d0000210c200241116a2d0000210d200241126a2f01002113200241146a2d00002112200241156a2d00002110200241166a2f01002111200241186a2d00002122200241196a2d0000212320022d0001212b2002280228210120022d00002107200341c00a6a41086a200241226a28010036020020032002411a6a2901003703c00a02400240024020074101470d0020012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200841ff0171450d010c410b20074103460d0120070d412008410876210220084110762107200941107621292009410876212a200a411076212c200a410876213220032903c00a210520012001280200417f6a2231360200200320053703d804024020310d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22312031280200417f6a223136020020310d002001102e0b200320233a00d70a200320223a00d60a200320113b01d40a200320103a00d30a200320123a00d20a200320133b01d00a2003200d3a00cf0a2003200c3a00ce0a2003202c3b01cc0a200320323a00cb0a2003200a3a00ca0a200320293b01c80a2003202a3a00c70a200320093a00c60a200320073b01c40a200320023a00c30a200320083a00c20a2003200b3b01c00a200320032903d8043703d80a202b41ff0171450d014110102c2202450d5b200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d5b20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220736020020070d412002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22072007280200417f6a220736020020070d412002102e0c410b200941056c200a41036c490d3f0b200341c00a6a41186a20034190096a41186a290300370300200341c00a6a41106a20034190096a41106a290300370300200341c00a6a41086a20034190096a41086a29030037030020032003290390093703c00a200341023a00e00a20034180066a41186a2202420037030020034180066a41106a2201420037030020034180066a41086a220742003703002003420037038006200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c00737038006200341c0076a418081ca00410c10810220022008290000370300200120032900c00737030020034180066a200341c00a6a10ca05200041186a41003a000020004200370308200020032800e0063600192000411c6a200341e3066a28000036000020004200370300200424000f0b20034190096a41186a200141196a29000037030020034190096a41106a200141116a29000037030020034190096a41086a200141096a2900003703002003200129000137039009200241026a2f0100210b200241046a2802002108200241086a28020021092002410c6a280200210a200241106a2d0000210c200241116a2d0000210d200241126a2f01002113200241146a2d00002112200241156a2d00002110200241166a2f01002111200241186a2d00002122200241196a2d0000212320022d0001212b2002280228210120022d00002107200341c00a6a41086a200241226a28010036020020032002411a6a2901003703c00a02400240024020074101470d0020012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200841ff01710d002009200a4f0d030b4110102c2202450d5b200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d5b20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220736020020070d012002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22072007280200417f6a220736020020070d012002102e0c010b20074103460d0120070d002008410876210220084110762107200941107621292009410876212a200a411076212c200a410876213220032903c00a210520012001280200417f6a2231360200200320053703d804024020310d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22312031280200417f6a223136020020310d002001102e0b200320233a00d70a200320223a00d60a200320113b01d40a200320103a00d30a200320123a00d20a200320133b01d00a2003200d3a00cf0a2003200c3a00ce0a2003202c3b01cc0a200320323a00cb0a2003200a3a00ca0a200320293b01c80a2003202a3a00c70a200320093a00c60a200320073b01c40a200320023a00c30a200320083a00c20a2003200b3b01c00a200320032903d8043703d80a202b41ff0171450d014110102c2202450d5a200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d5a20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220736020020070d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22072007280200417f6a220736020020070d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200341f0086a41026a200341c0056a41026a2d000022023a0000200320032f00c00522013b01f008200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a000020004201370300200424000f0b200341c00a6a41186a20034190096a41186a290300370300200341c00a6a41106a20034190096a41106a290300370300200341c00a6a41086a20034190096a41086a29030037030020032003290390093703c00a200341013a00e00a20034180066a41186a2202420037030020034180066a41106a2201420037030020034180066a41086a220742003703002003420037038006200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c00737038006200341c0076a418081ca00410c10810220022008290000370300200120032900c00737030020034180066a200341c00a6a10ca05200041186a41003a000020004200370308200020032800e0063600192000411c6a200341e3066a28000036000020004200370300200424000f0b200141286a2802002134200141246a2802002109200241266a2f00002135200241226a28000021082002411a6a2900002105200241196a2d0000210b200241186a2d0000210c200241166a2f0000210d200241156a2d00002129200241146a2d0000212a200241126a2f0000212c200241116a2d00002132200241106a2d000021312002410e6a2f000021122002410d6a2d000021102002410c6a2d000021112002410a6a2f00002122200241096a2d00002123200241086a2d0000212b200241066a2f00002133200241056a2d00002136200241046a2d00002113200241026a2f000021372002280228210720022d0001213820022d00002102200341d8046a41186a200141196a290000370300200341d8046a41106a200141116a290000370300200341d8046a41086a200141096a290000370300200320012900013703d804200941880e490d37200320083602c80a200320053703c00a0240200241ff017122014102470d0020072007280200417f6a220236020020032902c40a2106024020020d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b201341ff01710d364101210a2022411074202341087472202b7241036c2012411074201041087472201172410174490d36410021010c350b024020014103470d00410021014101210a0c350b200241ff01710d3620072007280200417f6a22023602002003200537039009024020020d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b2003200b3a00d70a2003200c3a00d60a2003200d3b01d40a200320293a00d30a2003202a3a00d20a2003202c3b01d00a200320323a00cf0a200320313a00ce0a200320123b01cc0a200320103a00cb0a200320113a00ca0a200320223b01c80a200320233a00c70a2003202b3a00c60a200320333b01c40a200320363a00c30a200320133a00c20a200320373b01c00a200320032903900922053703d80a0240203841ff01710d00410321020c380b4110102c2201450d57200141f8f7c60036020c2001410136020820014281808080103702004110102c2207450d5720074190f8c60036020c20074101360208200742818080801037020020012001280200417f6a220a36020041002102200a0d372001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a220a200a280200417f6a220a360200200a0d372001102e0c370b200341f8066a200141196a290000370300200341e0066a41106a200141116a290000370300200341e0066a41086a200141096a290000370300200320012900013703e0062002280228210102400240024020022d00004102470d00200241246a2802002107200241226a2f01002108200241216a2d00002109200241206a2d0000210a2002411e6a2f0100210b2002411d6a2d0000210c2002411c6a2d0000212b2002411a6a2f01002129200241196a2d0000212a200241116a2900002105200241106a2d0000210d2002410e6a2f000021132002410d6a2d000021122002410c6a2d000021102002410a6a2f00002111200241096a2d00002122200241086a2d00002123200241066a2f0000212c200241056a2d00002132200241046a2d0000210220012001280200417f6a2231360200024020310d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22312031280200417f6a223136020020310d002001102e0b200320073a00df0a200320083b00dd0a200320093a00dc0a2003200a3a00db0a2003200b3b00d90a2003200c3a00d80a2003202b3a00d70a200320293b00d50a2003202a3a00d40a200320053702cc0a2003200d3a00cb0a200320133b00c90a200320123a00c80a200320103a00c70a200320113b00c50a200320223a00c40a200320233a00c30a2003202c3b00c10a200320323a00c00a200241ff01714101460d014110102c2202450d59200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d5920014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220736020020070d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22072007280200417f6a220736020020070d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200341023a00c0050c010b200320032d00c20a3a00da04200320032f01c00a3b01d804200320073a00f704200320083b00f504200320093a00f4042003200a3a00f3042003200b3b00f1042003200c3a00f0042003200d3a00e304200320133b00e104200320123a00e004200320103a00df04200320113b00dd04200320223a00dc04200320233a00db04200320032903d00a3703e804200320053c00e404200320054218883c00e704200320054208883d00e504200341b8046a41186a22024200370300200341b8046a41106a22014200370300200341b8046a41086a22074200370300200342003703b804200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c0073703b804200341c0076a418081ca00410c10810220022008290000370300200120032900c007370300200341c00a6a200341b8046a10aa0520032d00e00a210220034180066a41186a2201200341c00a6a41186a220729030037030020034180066a41106a2208200341c00a6a41106a220929030037030020034180066a41086a220a200341c00a6a41086a220b290300370300200320032903c00a370380060240024020024103460d0020034190096a41186a2001290300220537030020034190096a41106a2008290300220637030020034190096a41086a200a290300220e3703002003200329038006220f370390092007200537030020092006370300200b200e3703002003200f3703c00a0240200341e0066a200341c00a6a412010ec08450d00200341c0056a41021093080c020b20034190096a200341e0066a10ba08200341c00a6a200328029009220220032802980910b70520032903c80a210520032802c40a21010240200328029409450d002002102e0b2001410120011b210941002102024002400240024002402005420020011b22054220882206a7220a0e020201000b41002102200a210103402001410176220820026a210720072002200920074105746a200341d8046a412010ec084101481b2102200120086b220141014b0d000b0b200920024105746a200341d8046a412010ec082207450d02200341c00a6a41186a200341d8046a41186a290300370300200341c00a6a41106a200341d8046a41106a290300370300200341c00a6a41086a200341d8046a41086a290300370300200320032903d8043703c00a200341c00a6a210120022007411f766a2207200a4d0d012007200a1045000b200341c00a6a41186a200341d8046a41186a290300370300200341c00a6a41106a200341d8046a41106a290300370300200341c00a6a41086a200341d8046a41086a290300370300200320032903d8043703c00a41002107200341c00a6a21010b024002400240200a2005a7460d00200521060c010b200a41016a2202200a490d5d200a4101742208200220022008491b22024104200241044b1b220241ffffff3f7120024621082002410574210202400240200a0d0020034100360290090c010b20034198096a41013602002003200936029009200320064205863e0294090b200341c0076a2002200820034190096a107d200341c8076a280200210220032802c0074101460d0120032802c40721092002410576ad21060b200920074105746a220241206a2002200a20076b41057410ea081a200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a29000037000020022001290000370000200341c00a6a41186a22014200370300200341c00a6a41106a22074200370300200341c00a6a41086a22024200370300200342003703c00a20034188086a41d9fcc6004106108102200220034188086a41086a220829000037030020032003290088083703c00a20034188086a4180f4cb004106108102200120082900003703002007200329008808370300200341e8016a200341c00a6a4120108e0220032802e801210120032802ec0121072002200642ffffffff0f8320054280808080107c4280808080708384370300200320093602c40a2003200741c093066a41c0930620011b22023602c00a20034190096a200341e0066a10ba082003280290092201200328029809200341c00a6a10bf050240200328029409450d002001102e0b0240200642ffffff3f83500d002009102e0b200341c00a6a41086a410a3a0000200341c00a6a41096a20032903d804370000200341e90a6a20032903e006370000200341d10a6a200341d8046a41086a290300370000200341d90a6a200341d8046a41106a290300370000200341e10a6a200341d8046a41186a290300370000200341f10a6a200341e0066a41086a290300370000200341f90a6a200341e0066a41106a290300370000200341810b6a200341e0066a41186a290300370000200341093a00c00a2003418c0b6a2002360200200341c00a6a10fe0120034180066a41186a2202420037030020034180066a41106a2201420037030020034180066a41086a220742003703002003420037038006200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c00737038006200341c0076a418081ca00410c10810220022008290000370300200120032900c00737030020034180066a412010ff01200341063a00c0050c370b2002450d5b0c5a0b200341c0056a410a109308200542ffffff3f83500d012009102e0c010b200341c0056a41091093080b20032d00c0054106460d330b20032802c0052102200020032902c405370024200041206a2002360000200041186a41003a00002000420037030820004201370300200424000f0b200141046a2802002101200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a200241186a290200370300200341c00a6a41106a200241106a290200370300200341c00a6a41086a2207200241086a290200370300200320022902003703c00a200341c00a6a10a7050d16200341cc0a6a2001360200200741063a0000200341093a00c00a200341c00a6a10fe01200341c00a6a200110890520032802c00a220220032802c80a10ff01024020032802c40a450d002002102e0b200041186a41003a00002000420037030820002003280090093600192000411c6a20034193096a28000036000020004200370300200424000f0b200141046a2802002101200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a200241186a290200370300200341c00a6a41106a200241106a290200370300200341c00a6a41086a200241086a290200370300200320022902003703c00a200341c00a6a10a7050d14200320013602e806200342e4cab5fbb6ccdcb0e3003703e006410c102c2202450d542003420c3702c407200320023602c007200341c0076a200341e0066a41081074200320013602c00a200341c0076a200341c00a6a41041074200341033a00c00a20034190096a41086a20032802c807360200200320032903c00737039009200341d8046a200341c00a6a20034190096a10c304024020032d00d8044106470d00200341063a0080060c300b20034180066a410210930820032d0080064106460d2f20032902840621050c2e0b200141306a2903002105200141286a2903002106200141216a2d0000210b20034198046a41186a2207200141196a29000037030020034198046a41106a2208200141116a29000037030020034198046a41086a2209200141096a2900003703002003200129000137039804200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a200241186a290200370300200341c00a6a41106a200241106a290200370300200341c00a6a41086a200241086a290200370300200320022902003703c00a20034190096a200341c00a6a10c10220034180066a41086a220220034190096a41096a29000037030020034180066a41106a220120034190096a41116a29000037030020034180066a41186a220a20034190096a41196a29000037030020032003290091093703800620032d0090094101460d11200341b8046a41186a200a290300220e370300200341b8046a41106a2001290300220f370300200341b8046a41086a20022903002214370300200320032903800622153703b80420034188086a41186a200e37030020034188086a41106a200f37030020034188086a41086a20143703002003201537038808200341f0086a41186a2007290300370300200341f0086a41106a2008290300370300200341f0086a41086a200929030037030020032003290398043703f008024020034188086a200341f0086a412010ec080d00200341c00a6a411f1093080c2c0b20034190096a20034188086a10c802200341c00a6a200328029009220120032802980910c902200341d00a6a290300420020032903c00a42015122021b210e20032903c80a420020021b210f0240200328029409450d002001102e0b0240200f20065a200e20055a200e2005511b0d00200341c00a6a411b1093080c2c0b200341a8086a20034188086a10b808200341c00a6a20032802a808223720032802b008223910b105200341e8086a41026a220220032d00c30a3a0000200341d0066a41086a2201200341a00b6a290300370300200320032f00c10a3b01e8082003200341980b6a2903003703d006200341ac0b6a280200213a0240024020032d00c00a22074102470d0020034190096a41206a220241003602004200211420034190096a41106a420037030020034190096a41186a4200370300200341083602c40520034190096a41086a4200370300200342003703c805200341003a00c005200342003703d005200342003703d805200342003703900920034190096a41306a29030021192002290300211b20032903b809211f4200210e4200210f420021150c010b200341c00a6a41186a2903002116200341c00a6a41106a2903002117200341e80a6a290300210e200341c00a6a41206a2903002114200341f80a6a2903002115200341900b6a2903002119200341880b6a290300211f200341c00a6a41086a2802002108200341cc0a6a2802002109200341c00a6a41306a290300210f20032802c40a210a20034190096a41206a200341c00a6a41c0006a290300221b37030020034190096a41306a201937030020034190096a41c0006a2001290300370300200320173703d005200320153703a80920032014370390092003201f3703b809200320073a00c005200320032f01e8083b00c105200320093602cc05200320083602c8052003200a3602c4052003200f3703a009200320032903d0063703c809200320163703d8052003200e37039809200320022d00003a00c3052003200341a80b6a280200220a3602b8080b200342003703d807200320053703d007200320063703c807200320032903f0083700e1062003200341f0086a41086a2903003700e9062003200341f0086a41106a2903003700f1062003200341f0086a41176a2900003700f8062003200b3a00c107200320032d008f093a00c007200320153703d8072003200f3703d0072003200e3703c807200341013a00e00620032903e006211620032903e806211820032903f006211e20032903f806211a200320032903d805221d3703f806200320032903d00522273703f006200320032903c805221c3703e806200320032903c00522173703e0062003201a3703d8052003201e3703d005200320183703c805200320163703c00520032903c007211e200320143703c007200341a8096a4200370300200320053703a00920032006370398092003201e3703900920032903c809211e200341c0096a4200370300200342003703c809200342003703b809200342003703b00920032903d009211a200342003703d009200341003602b808200341c8096a2108200341b8096a2109200341b0096a21012016a721070240024002402017a741ff01714101460d002017422088a7210c201ca7210a201c422088a70d02200920034190096a200741ff017141014622021b2207200e37030820072014370300200341a8096a200341c0056a41107220021b2207201d37030820072027370300200820034190096a41106a20021b220720153703082007200f370300200341b8086a200120021b201ba7360200200a450d01200a41306c450d01200c102e0c010b200341c00a6a41176a200341e0066a410172220241176a290000370000200341c00a6a41106a200241106a290000370300200341c00a6a41086a200241086a290000370300200320022900003703c00a20032014a7220c3a00df0a4106210202400240024002400240024002400240200c41087641ff01710e0706000102030405060b410121020c040b410221020c030b410321020c020b410421020c010b410521020b200341b0026a200f42002002ad2214420010e808200341c0026a200e42002014420010e808427f200341c8026a290300221420032903b0027c221620032903b80242005220162014547222021b2114427f20032903c00220021b21160c010b200341a0026a200e200f420a420010e708200341a8026a290300211420032903a00221160b200341c00a6a20162014200e200f10bb081a200920034190096a200741ff017141014622021b220720193703082007201f370300200820034190096a41106a20021b2207201a3703082007201e3703002001200341c0056a41187220021b201b37030020034190096a41186a200341c0056a41107220021b2015370300200341b8086a200120021b200a3602000b02400240200b41ff0171450d00410621020240024002400240024002400240200b4107710e0700010203040506000b410021020c050b410121020c040b410221020c030b410321020c020b410421020c010b410521020b20034180026a200542002002ad220e420010e80820034190026a20064200200e420010e808427f20034198026a290300220e2003290380027c220f200329038802420052200f200e547222021b211a427f20032903900220021b211c0c010b200341f0016a20062005420a420010e708200341f8016a290300211a20032903f001211c0b200341c0086a200341f0086a10b808200341c00a6a20032802c008223b20032802c808223c10b105200341e8086a41026a220220032d00c30a3a000041082138200341d0066a41086a2201200341a00b6a290300370300200320032f00c10a3b01e8082003200341980b6a2903003703d006200341900b6a290300211b200341880b6a2903002128200341ac0b6a280200213d200341a80b6a280200213e0240024020032d00c00a22344102470d004200211f4100213541002136420021184200211e4200211942002121420021204200211d410021340c010b200341d80a6a2903002118200341d00a6a290300211f200341e80a6a2903002119200341e00a6a290300211e200341800b6a290300211d200341f80a6a2903002120200341c00a6a41086a2802002135200341cc0a6a2802002136200341f00a6a290300212120032802c40a2107200341e4086a41026a20022d00003a0000200341d0086a41086a2001290300370300200320032f01e8083b01e408200320032903d0063703d0084101210120344101460d14200721380b427f201920057c201e20067c220f201e542202ad7c220e2002200e201954200e2019511b22021b2119427f200f20021b211e427f2018201a7c201f201c7c220f201f542202ad7c220e2002200e201854200e2018511b22021b2118427f200f20021b211f0240203641306c2202450d00203820026a210c200341f80a6a2101200341c00a6a410172220d41036a2113203821020340200241306a21070240200241086a2d00004101710d00200241096a2d00002133200341d0066a2002280200108905200341c00a6a20032802d006220820032802d8062212108a0520034180066a41086a2229200141086a221029000037030020034180066a41106a222a200141106a221129000037030020034180066a41186a222c200141186a222229000037030020034180066a41206a2232200141206a222329000037030020034180066a41286a2231200141286a222b2900003703002003200d2800003602c806200320132800003600cb062003200129000037038006200341c00a6a41306a2109200341c00a6a41206a210a200341c00a6a41106a210b0240024020032d00c00a22024102470d00410221020c010b2009290300210e200a2903002114200b290300211520032903e80a210f20032903d80a211620032903c80a2117200341d8046a41086a2029290300370300200341d8046a41106a202a290300370300200341d8046a41186a202c290300370300200341d8046a41206a2032290300370300200341d8046a41286a2031290300370300200320032800cb063600eb08200320032802c8063602e80820032003290380063703d80420020d00427f200e20057c200f20067c2227200f542202ad7c220f2002200f200e54200f200e511b22021b210e427f202720021b210f0240024020334101710d00427f2014201a7c2016201c7c22272016542202ad7c22162002201620145420162014511b22021b2114427f202720021b21160c010b427f2015201a7c2017201c7c22272017542202ad7c22172002201720155420172015511b22021b2115427f202720021b21170b410021020b200d20032802e808360000200120032903d8043703002009200e370300200a2014370300200b2015370300201320032800eb083600002010200341d8046a41086a2903003703002011200341d8046a41106a2903003703002022200341d8046a41186a2903003703002023200341d8046a41206a290300370300202b200341d8046a41286a2903003703002003200f3703e80a200320163703d80a200320173703c80a200320023a00c00a0240024020024102470d002008201210ff010c010b20034100360288062003420137038006200341c00a6a20034180066a10bc0520082012200328028006220220032802880610b201200328028406450d002002102e0b20032802d406450d002008102e0b20072102200c2007470d000b0b2038210720342101203621020c2a0b200341c00a6a411d10930820032902c40a210520032802c00a21020240200a450d00200a41306c450d00200c102e0b41012101200741ff01710d2a2018a72207450d2a200741306c450d2a2016422088a7102e0c2a0b200341c00a6a41286a2208200241286a280200360200200341c00a6a41206a2209200241206a290200370300200341c00a6a41186a220a200241186a290200370300200341c00a6a41106a220b200241106a290200370300200341c00a6a41086a220c200241086a290200370300200320022902003703c00a20034190096a200341c00a6a10c10220034180066a41086a220220034199096a29000037030020034180066a41106a2201200341a1096a29000037030020034180066a41186a2207200341a9096a29000037030020032003290091093703800620032d0090094101460d0f200341b8046a41186a20072903002205370300200341b8046a41106a20012903002206370300200341b8046a41086a2002290300220e3703002003200329038006220f3703b804200341f0086a41186a2005370300200341f0086a41106a2006370300200341f0086a41086a200e3703002003200f3703f00820034198046a200341f0086a10b808200341c00a6a200328029804220720032802a004220d10b105200341e8086a41026a220220032d00c30a3a0000200341d0066a41086a200341a00b6a290300370300200320032f00c10a3b01e8082003200341980b6a2903003703d0060240024020032d00c00a22014102470d0042002106200342003703d805200342003703d005200342003703c805200342003703c00520034200370388064100210a200341003a00800620034108360284062003420037039006200342003703980620034100360290094100210142002105420021150c010b200341880b6a290300210f200341800b6a2903002114200341f80a6a2903002115200829030021062009290300210e200a2903002116200b2903002117200341f00a6a2903002105200341cc0a6a2802002108200c280200210920032802c40a210a200341a0096a200341900b6a290300370300200341b0096a200341d8066a29030037030020032017370390062003200f37039809200320013a008006200320032f01e8083b0081062003200836028c0620032009360288062003200a36028406200320153703d805200320053703d005200320032903d0063703a809200320163703980620032014370390092003200e3703c005200320063703c805200320022d00003a0083062003200341a80b6a28020022083602a808200e420888a72101200ea7210a0b200341083602e406200341003a00e006200341003602c007200329039806210e200342003703980620032903900621142003420037039006200329038806210f2003420037038806200342003703d805200342003703d005200342003703c805200342003703c0052003200e3703f806200320143703f0062003200f3703e80620032903d80721162003200341a8096a220229030022173703d80720032903d0072118200320032903a009221e3703d00720032903c80721192003200329039809221a3703c80720032903e006210e200320032903800622143703e0062003200e3703800620032903c007211f2003200329039009221c3703c00720022016370300200320183703a00920032019370398092003201f37039009200ea7210902400240024002402014a741ff0171220b4101470d0020032903b009210e200341ef046a20032900f806370000200341e8046a20032900f106370300200341d8046a41086a20032900e906370300200320032900e1063703d8042003200a3a00f70402400240200141ff0171450d0041062102024002400240024002400240024020014107710e0700010203040506000b410021020c050b410121020c040b410221020c030b410321020c020b410421020c010b410521020b200341e8026a200542002002ad220f420010e808200341f8026a20064200200f420010e808427f20034180036a290300220f20032903e8027c221420032903f0024200522014200f547222021b210f427f20032903f80220021b21140c010b200341d8026a20062005420a420010e708200341e0026a290300210f20032903d80221140b200341d8046a2014200f2006200510bb082102200341c00a6a41186a220a4200370300200341c00a6a41106a220b4200370300200341c00a6a41086a220c4200370300200342003703c00a20034188086a41d9fcc6004106108102200c20034188086a41086a221329000037030020032003290088083703c00a20034188086a4180f4cb004106108102200a2013290000370300200b200329008808370300200341d0026a200341c00a6a4120108e0220032802d402410020032802d0021b210c4180c09306210b0240024002400240024020014107710e0706000102030407060b4180ce18210b0c060b41809c31210b0c050b4180b8e200210b0c040b4180f0c401210b0c030b4180e08903210b0c020b200341c00a6a411c10930820032902c40a210520032802c00a21020240200b0d00200fa72201450d00200141306c450d002014422088a7102e0b41012101200941ff01710d0241010d0241010d02200e422088a7102e410121010c020b4100210b0b20034190096a41086a200341c0056a200941ff017141014622011b2209201e3703082009201a37030020034190096a20034180066a41187220011b201c370300200341c0056a41187220034180066a41107220011b2015370300200341a8086a20034190096a20011b2008200b200c6a2209200820094b1b36020020034190096a41186a200341c0056a41107220011b2201200e20052017200656200e200556200e2005511b22081b37030820012017200620081b370300200a200329039806370300200341f80a6a20032903d805370300200341f00a6a20032903d005370300200341e80a6a20032903c805370300200341c00a6a41206a20032903c005370300200341800b6a200329039009370300200341880b6a200329039809370300200341900b6a20034190096a41106a290300370300200341980b6a20032903a809370300200341a00b6a20034190096a41206a290300370300200341a80b6a20032802a80836020020032003290390063703d00a200320032903880622063703c80a200320032903800622053703c00a024002402005a7220141ff01714102470d002007200d10ff010c010b200341d8046a200341c00a6a10c2042007200d20032802d804220820032802e00410b201024020032802dc04450d002008102e0b200141ff01710d002006a72201450d00200141306c450d002005422088a7102e0b410021010b0240200328029c04450d002007102e0b20010d27200341c00a6a41086a41093a0000200341c00a6a41096a20032903f008370000200341d10a6a200341f0086a41086a290300370000200341d90a6a200341f0086a41106a290300370000200341e10a6a200341f0086a41186a290300370000200341093a00c00a200341c00a6a10fe01200320032800d0083602c0082003200341d3086a2800003600c308200041186a41003a0000200041106a2002ad220542f0cfe9037e200542c0f0f50b7e7c20054280c2d72f7e7c42d08dc582017c37030020004201370308200020032802c0083600192000411c6a20032800c30836000020004200370300200424000f0b200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a200241186a290200370300200341c00a6a41106a200241106a290200370300200341c00a6a41086a200241086a290200370300200320022902003703c00a0240200341c00a6a10a705450d00200341e0066a41026a200341d8046a41026a2d000022023a0000200320032f00d80422013b01e006200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a000020004201370300200424000f0b20034180066a41186a2202420037030020034180066a41106a2201420037030020034180066a41086a220742003703002003420037038006200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c00737038006200341c0076a418c81ca00410b10810220022008290000370300200120032900c00737030020034180066a412010ff01200041186a41003a00002000420037030820002003280090093600192000411c6a20034193096a28000036000020004200370300200424000f0b2001410c6a2802002108200141086a2802002107200141046a2802002101200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a200241186a290200370300200341c00a6a41106a200241106a290200370300200341c00a6a41086a200241086a290200370300200320022902003703c00a20034190096a200341c00a6a10c10220034180066a41086a220220034199096a29000037030020034180066a41106a2209200341a1096a29000037030020034180066a41186a220a200341a9096a29000037030020032003290091093703800602400240024020032d0090094101460d00200341d8046a41186a200a290300370300200341d8046a41106a2009290300370300200341d8046a41086a200229030037030020032003290380063703d804200320083602c80a200320073602c40a200320013602c00a200341e0066a200341d8046a200341c00a6a10bc08200341c8066a41026a220120032d00e3063a0000200320032f00e1063b01c80620032d00e00622024106460d0220032902e4062105200341c0056a41026a20012d00003a0000200320032f01c8063b01c0050c010b4102210202402007450d002001102e0b0b200341f0086a41026a200341c0056a41026a2d000022013a0000200320032f01c00522073b01f008200041206a20023a0000200041186a41003a000020004200370308200020073b0021200041236a20013a00002000200537002420004201370300200424000f0b200041186a41003a000020004200370308200020032800c0073600192000411c6a200341c3076a28000036000020004200370300200424000f0b2001410c6a2802002132200141086a2802002129200141046a280200212c4101212b200241246a2802002107200241226a2f01002108200241216a2d00002109200241206a2d0000210a2002411e6a2f0100210b2002411d6a2d0000210c200241106a2d0000210d2002410e6a2f000021132002410d6a2d000021122002410c6a2d000021102002410a6a2f01002111200241096a2d00002122200241086a2d0000212320022802282101024020022d00004101470d002002411c6a2d0000212a2002411a6a2f01002131200241196a2d00002133200241116a2900002106200241066a2f01002136200241056a2d00002137200241046a2d0000210220012001280200417f6a2238360200024020380d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22382038280200417f6a223836020020380d002001102e0b200320073a00df0a200320083b00dd0a200320093a00dc0a2003200a3a00db0a2003200b3b00d90a2003200c3a00d80a2003202a3a00d70a200320313b00d50a200320333a00d40a200320063702cc0a2003200d3a00cb0a200320133b00c90a200320123a00c80a200320103a00c70a200320113b00c50a200320223a00c40a200320233a00c30a200320363b00c10a200320373a00c00a200241ff01714101460d0c4110102c2202450d50200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d5020014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a222a360200202a0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a222a202a280200417f6a222a360200202a0d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0c230b2001410c6a2802002108200141086a2802002107200141046a2802002101200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a200241186a290200370300200341c00a6a41106a200241106a290200370300200341c00a6a41086a200241086a290200370300200320022902003703c00a20034190096a200341c00a6a10c10220034180066a41086a220220034199096a29000037030020034180066a41106a2209200341a1096a29000037030020034180066a41186a220a200341a9096a29000037030020032003290091093703800602400240024020032d0090094101460d00200341d8046a41186a200a290300370300200341d8046a41106a2009290300370300200341d8046a41086a200229030037030020032003290380063703d804200320083602c80a200320073602c40a200320013602c00a200341e0066a200341d8046a200341c00a6a10bd08200341c8066a41026a220120032d00e3063a0000200320032f00e1063b01c80620032d00e00622024106460d0220032902e4062105200341f0086a41026a20012d00003a0000200320032f01c8063b01f0080c010b4102210202402007450d002001102e0b0b20034188086a41026a2201200341f0086a41026a2d00003a0000200320032800c0073602c005200320032f01f0083b0188082003200341c3076a2800003600c305200041186a41003a000020004200370308200020032802c0053600192000411c6a20032800c305360000200041206a20023a0000200041246a2005370200200020032f0188083b0021200041236a20012d00003a000020004201370300200424000f0b200320032800c0073602c0052003200341c3076a2800003600c305200041186a41013a000020004200370308200020032802c0053600192000411c6a20032800c30536000020004200370300200424000f0b2001410c6a2802002132200141086a2802002129200141046a280200212c4101212b200241246a2802002107200241226a2f01002108200241216a2d00002109200241206a2d0000210a2002411e6a2f0100210b2002411d6a2d0000210c200241106a2d0000210d2002410e6a2f000021132002410d6a2d000021122002410c6a2d000021102002410a6a2f01002111200241096a2d00002122200241086a2d0000212320022802282101024020022d00004101470d002002411c6a2d0000212a2002411a6a2f01002131200241196a2d00002133200241116a2900002106200241066a2f01002136200241056a2d00002137200241046a2d0000210220012001280200417f6a2238360200024020380d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22382038280200417f6a223836020020380d002001102e0b200320073a00df0a200320083b00dd0a200320093a00dc0a2003200a3a00db0a2003200b3b00d90a2003200c3a00d80a2003202a3a00d70a200320313b00d50a200320333a00d40a200320063702cc0a2003200d3a00cb0a200320133b00c90a200320123a00c80a200320103a00c70a200320113b00c50a200320223a00c40a200320233a00c30a200320363b00c10a200320373a00c00a200241ff01714101460d094110102c2202450d4e200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d4e20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a222a360200202a0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a222a202a280200417f6a222a360200202a0d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0c200b200141246a2802002113200341c0056a41186a2207200141196a290000370300200341c0056a41106a2208200141116a290000370300200341c0056a41086a2209200141096a290000370300200320012900013703c005200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a2201200241186a290200370300200341c00a6a41106a220a200241106a290200370300200341c00a6a41086a220b200241086a290200370300200320022902003703c00a20034190096a200341c00a6a10c102200341b8046a41086a220220034190096a41096a290000370300200341b8046a41106a220c20034190096a41116a290000370300200341b8046a41186a220d20034190096a41196a29000037030020032003290091093703b8040240024020032d0090094101460d00200341c0076a41186a200d290300370300200341c0076a41106a200c290300370300200341c0076a41086a2002290300370300200320032903b8043703c007200341e4066a41003b0100200341003602e00620012007290300370300200a2008290300370300200b2009290300370300200320032903c0053703c00a20034190096a200341c00a6a10be0820034198036a2003280290092201200328029809200341e0066a4106410010ca0402402003280298030d00200341c00a6a41101093080c1e0b2003200328029c032202410620024106491b22023602dc042003200341e0066a3602d804200341003a00f0080240024002402002450d0020032002417f6a3602dc042003200341e0066a4101723602d80420032d00e0060e020102000b4190c1cb00412910ef02200341c00a6a41101093080c1f0b200341c00a6a41101093080c1e0b20034190036a200341d8046a10ab01200328029003450d014190c1cb00412910ef02200341c00a6a41101093080c1d0b200341023a0098040c1e0b20032802940321020240200328029409450d002001102e0b0240200220134d0d0020034198046a41201093080c1d0b200341f0086a200341c0056a109808200341c00a6a20032802f008220220032802f80810ad0520034190096a41086a2201200341c90a6a29000037030020034190096a41106a2207200341d10a6a29000037030020034190096a41186a2208200341d90a6a29000037030020034190096a411f6a2209200341e00a6a280000360000200320032900c10a3703900902400240024020032d00c00a220a4102460d00200341880b6a2903002105200341800b6a2903002106200341f80a6a2802002112200341f40a6a2802002113200341f00a6a280200210b200341e80a6a280200210c200341e40a6a280200210d200341d8046a411f6a2009280000360000200341d8046a41186a2008290300370300200341d8046a41106a2007290300370300200341d8046a41086a200129030037030020032003290390093703d804024020032802f408450d002002102e0b200341c00a6a411f6a200341d8046a411f6a280000360000200341c00a6a41186a2202200341d8046a41186a290300370300200341c00a6a41106a2201200341d8046a41106a290300370300200341c00a6a41086a2207200341d8046a41086a290300370300200320032903d8043703c00a200a450d01200341e0066a41186a2002290300370300200341e0066a41106a2001290300370300200341e0066a41086a2007290300370300200320032903c00a3703e0060240200c450d00200d102e0b20034180066a41086a200341e0066a41086a290300220e37030020034180066a41106a200341e0066a41106a290300220f37030020034180066a41186a200341e0066a41186a2903002214370300200320032903e00622153703800620034190096a41186a201437030020034190096a41106a200f37030020034190096a41086a200e3703002003201537039009200341c00a6a41186a22024200370300200341c00a6a41106a22014200370300200341c00a6a41086a22074200370300200342003703c00a20034188086a41d9fcc6004106108102200720034188086a41086a220829000037030020032003290088083703c00a20034188086a4180f4cb00410610810220022008290000370300200120032900880837030020034188036a200341c00a6a4120108e02200328028c0341002003280288031b2202200b4180ce184100200341c0076a20034190096a412010ec081b6a4180ce186a4f0d0220034198046a410e1093080c1f0b20032802f408450d002002102e0b20034198046a41101093080c1d0b02402013450d00200220124b0d0020034198046a410f1093080c1d0b200341d8046a20034190096a200341c0076a200620054100108904200341c00a6a200341c0056a10980820032802c00a220220032802c80a10ff01024020032802c40a450d002002102e0b200341c00a6a41086a410f3a0000200341e90a6a200329039009370000200341d10a6a200341c0056a41086a290300370000200341d90a6a200341c0056a41106a290300370000200341e10a6a200341c0056a41186a290300370000200341f10a6a20034190096a41086a290300370000200341f90a6a20034190096a41106a290300370000200341810b6a20034190096a41186a290300370000200341093a00c00a200341c00a6a41096a20032903c005370000200341b00b6a2006370300200341b80b6a2005370300200341a10b6a200341c0076a41186a290300370000200341990b6a200341c0076a41106a290300370000200341910b6a200341c0076a41086a290300370000200341890b6a20032903c007370000200341c00a6a10fe01200341063a0098040c1e0b200341d8046a41186a200141196a290000370300200341d8046a41106a200141116a290000370300200341d8046a41086a200141096a290000370300200320012900013703d804200341c00a6a41286a2201200241286a280200360200200341c00a6a41206a2207200241206a290200370300200341c00a6a41186a2209200241186a290200370300200341c00a6a41106a220a200241106a290200370300200341c00a6a41086a220b200241086a290200370300200320022902003703c00a20034190096a200341c00a6a10c10202400240024020032d0090094101460d00200341c0076a200341d8046a10b808200341c00a6a20032802c007220820032802c807220c10b105200341e8086a41026a220220032d00c30a3a0000200341d0066a41086a200341c00a6a41e0006a290300370300200320032f00c10a3b01e8082003200341c00a6a41d8006a2903003703d0060240024020032d00c00a220d4102470d00200341a0096a4200370300200341a8096a4200370300200341b0096a4200370300200341b8096a420037030020034190096a41306a420037030020034190096a41386a420037030020034190096a41c0006a4100360200200341083602940920034190096a41086a4200370300200341003a0090090c010b200341c00a6a41c8006a2903002105200341c00a6a41c0006a2903002106200341c00a6a41386a290300210e2001290300210f2007290300211420092903002115200a2903002116200341c00a6a41306a2903002117200341c00a6a410c6a2802002101200b280200210720032802c40a210920034190096a41d0006a200341c00a6a41d0006a29030037030020034190096a41c8006a200537030020034190096a41c0006a200637030020034190096a41386a200e370300200341b8096a200f370300200341b0096a2014370300200341a8096a2015370300200341a0096a201637030020034190096a41306a201737030020034190096a410c6a200136020020034190096a41086a200736020020034190096a41d8006a20032903d00637030020034190096a41e0006a200341d0066a41086a2903003703002003200d3a009009200320032f01e8083b0091092003200936029409200320022d00003a00930920034190096a41e8006a200341c00a6a41e8006a2903003703000b200341d80a6a22024200370300200341c00a6a41106a22014200370300200341c00a6a41086a22074200370300200342003703c00a20034188086a41d9fcc6004106108102200720034188086a41086a220929000037030020032003290088083703c00a20034188086a4180f4cb004106108102200220092900003703002001200329008808370300200341a0036a200341c00a6a4120108e020240200341f8096a200341d0096a20032d009009220241014622011b28020020032802a403410020032802a0031b4b0d00200341e8096a200341c0096a20011b22014200370300200141106a4100360200200141086a42003703000b0240024020024101470d00200341c0096a290300210e200341b8096a290300210f0c010b200341c8096a290300210e20034190096a41306a290300210f2003419c096a28020041306c2201450d0020032802940941206a21020340200241706a22072903002106200741086a29030021050240200241686a2d00004101470d00427f2005200241086a2903007c200620022903007c22142006542207ad7c22062007200620055420062005511b22071b2105427f201420071b21060b200e20052006200f542005200e542005200e511b22071b210e200f200620071b210f200241306a2102200141506a22010d000b0b200341c00a6a20034190096a41f00010e9081a0240024020032d00c00a22024102470d002008200c10ff010c010b200341e0066a200341c00a6a10c2042008200c20032802e006220120032802e80610b201024020032802e406450d002001102e0b20020d00200341c80a6a2802002202450d00200241306c450d0020032802c40a102e0b024020032802c407450d002008102e0b200f200e844200520d0142e4cab5fbb6ccdcb0e300200341d8046a10ea020c020b200341f0086a41026a200341c0056a41026a2d000022023a0000200320032f00c00522013b01f008200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a000020004201370300200424000f0b42e4cab5fbb6ccdcb0e300200341d8046a200f200e41021085060b200041186a41003a00002000420037030820002003280080063600192000411c6a20034183066a28000036000020004200370300200424000f0b200141046a2802002101200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a200241186a290200370300200341c00a6a41106a200241106a290200370300200341c00a6a41086a200241086a290200370300200320022902003703c00a20034190096a200341c00a6a10c10220034180066a41086a220220034199096a29000037030020034180066a41106a2207200341a1096a29000037030020034180066a41186a2208200341a9096a29000037030020032003290091093703800602400240024020032d0090094101470d00200341023a00e0060c010b200341d8046a41186a2008290300370300200341d8046a41106a2007290300370300200341d8046a41086a200229030037030020032003290380063703d804200341e0066a200341d8046a2001410010bf0820032d00e0064106460d0120032902e40621050b20032802e006210320002005370024200041206a2003360000200041186a41003a00002000420037030820004201370300200424000f0b20004200370308200020032800c007360019200041186a41003a00002000411c6a200341c3076a28000036000020004200370300200424000f0b200141246a2802002107200341e0066a41186a200141196a290000370300200341e0066a41106a200141116a290000370300200341e0066a41086a200141096a290000370300200320012900013703e006200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a200241186a290200370300200341c00a6a41106a200241106a290200370300200341c00a6a41086a200241086a290200370300200320022902003703c00a20034190096a200341c00a6a10c10220034180066a41086a220220034190096a41096a29000037030020034180066a41106a220120034190096a41116a29000037030020034180066a41186a220820034190096a41196a29000037030020032003290091093703800620032d0090094101460d03200341d8046a41186a2008290300370300200341d8046a41106a2001290300370300200341d8046a41086a200229030037030020032003290380063703d804200341c00a6a200341e0066a2007200341e0066a200341d8046a412010ec0841004710bf08200341c8066a41026a220120032d00c30a3a0000200320032f00c10a3b01c806024020032d00c00a22024106460d0020032902c40a2105200341c0056a41026a20012d00003a0000200320032f01c8063b01c0050c180b200041186a41003a000020004200370308200020032800c0073600192000411c6a200341c3076a28000036000020004200370300200424000f0b200141246a280200210720034190096a41186a2208200141196a29000037030020034190096a41106a2209200141116a29000037030020034190096a41086a220a200141096a2900003703002003200129000137039009200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a2201200241186a290200370300200341c00a6a41106a220b200241106a290200370300200341c00a6a41086a220c200241086a290200370300200320022902003703c00a024002400240200341c00a6a10a705450d00200341023a00d8040c010b20012008290300370300200b2009290300370300200c200a29030037030020032003290390093703c00a200341d8046a200341c00a6a200710970820032d00d8044106460d0120032902dc0421050b20032802d804210320002005370024200041206a2003360000200041186a41003a00002000420037030820004201370300200424000f0b20004200370308200020032800e006360019200041186a41003a00002000411c6a200341e3066a28000036000020004200370300200424000f0b200141286a280200210a200141246a2802002109200341e0066a41186a200141196a290000370300200341e0066a41106a200141116a290000370300200341e0066a41086a200141096a290000370300200320012900013703e00620022802282101024020022d000022070d002002411a6a2901002105200241196a2d00002107200241186a2d00002108200241166a2f0100210b200241156a2d0000210c200241146a2d0000210d200241126a2f01002113200241116a2d00002112200241106a2d000021102002410e6a2f010021112002410d6a2d000021222002410c6a2d000021232002410a6a2f0100212b200241096a2d00002129200241086a2d0000212a200241066a2f0100212c200241056a2d00002132200241046a2d00002131200241026a2f0100213320022d0001210220012001280200417f6a2236360200024020360d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22362036280200417f6a223636020020360d002001102e0b200320053701d80a200320073a00d70a200320083a00d60a2003200b3b01d40a2003200c3a00d30a2003200d3a00d20a200320133b01d00a200320123a00cf0a200320103a00ce0a200320113b01cc0a200320223a00cb0a200320233a00ca0a2003202b3b01c80a200320293a00c70a2003202a3a00c60a2003202c3b01c40a200320323a00c30a200320313a00c20a200320333b01c00a0240200241ff01710d00410321070c010b4110102c2202450d48200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d4820014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a22083602004100210720080d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22082008280200417f6a220836020020080d002002102e0b024020074103460d0020012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b20034198046a41026a20034188086a41026a2d000022023a0000200320032f00880822013b019804200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a000020004201370300200424000f0b200341c80a6a4200370300200342ffffffff1f3703c00a20034190096a200341e0066a10ba082003280290092202200328029809200341c00a6a10bf050240200328029409450d002002102e0b20034180066a109108200328028806220b450d14200b41c4006c41bc7f6a2101200b410274417c6a41027641016a210841002107200328028006210202400340200241046a200341e0066a412010ec08450d01200141bc7f6a2101200241c4006a21022008200741016a2207470d000c160b0b200228020021072002200241c4006a200110ea081a2003200b417f6a3602880620034190096a2007109408200341c00a6a2003280290092202200328029809220110ae05024020032802c00a220b450d002002200110ff010b200341d80a6a2903002114200341d00a6a290300211520032902c40a21160240200328029409450d002002102e0b200b450d142016422088a74105742207450d13200341d8046a41086a2108200b21020340200241086a2900002105200241106a29000021062002290000210e20034190096a41186a200241186a29000037030020034190096a41106a200637030020034190096a41086a20053703002003200e37039009200341b8036a20034190096a2015201410cb0220032903b80321052003200341b8036a41086a29030022063703c80a200320053703c00a0240024020052006844200520d002003200341c00a6a3602d804200341d8046a10cc020c010b200342f0f2bda1a7ee9cb9f9003703d804200341c00a6a200341d8046a10cd02200341a8036a200341c00a6a2005200610fd01200341d8046a41106a200341a8036a41086a290300220f20067d20032903a803220e200554ad7d2006200f7d2005200e54ad7d200e200556200f200656200f2006511b22011b3703002003200e20057d2005200e7d20011b3703e00420032001ad3703d8040240024020010d00200320083602c007200341c0076a10cc020c010b200320083602c007200341c0076a10ce020b200341c00a6a41186a2006370300200320053703d00a200341063a00c80a2003410e3a00c00a200341c00a6a10fe010b200241206a2102200741606a22070d000c140b0b200141046a2802002109200341c00a6a41286a200241286a280200360200200341c00a6a41206a200241206a290200370300200341c00a6a41186a200241186a290200370300200341c00a6a41106a200241106a290200370300200341c00a6a41086a200241086a290200370300200320022902003703c00a200341c00a6a10fd0641ff01714102460d0e20034190096a10910820032802980921084100210a200341003602980902402008450d004100210c200328029009210b4100210a410021010240034002400240200a450d00200b200141c4006c6a2102200b2001200c6a41c4006c6a2107034020022802002009460d022007200241c40010e9082107200241c4006a2102200741c4006a21072008200141016a22014b0d000c040b0b200b200141c4006c6a2102034020022802002009460d01200241c4006a21022008200141016a22014b0d000b4100210a0c030b200c417f6a210c200a41016a210a2008200141016a22014b0d000b0b0240200a0d004100210a0c010b200b2001200a6b41c4006c6a200b200141c4006c6a200820016b41c4006c10ea081a0b20032008200a6b220236029809200341c00a6a41086a2002360200200320032903900922053703c00a024002402005a722020d0020034198066a2202420037030020034190066a2201420037030020034180066a41086a220742003703002003420037038006200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c00737038006200341c0076a418c81ca00410b10810220022008290000370300200120032900c00737030020034180066a412010ff010c010b20034198066a2201420037030020034190066a2207420037030020034180066a41086a220842003703002003420037038006200341c0076a41de80ca0041091081022008200341c0076a41086a220a290000370300200320032900c00737038006200341c0076a418c81ca00410b1081022001200a290000370300200720032900c00737030020034180066a200341c00a6a10c40520032802c40a2201450d00200141c4006c450d002002102e0b20034190096a2009109408200341c00a6a2003280290092202200328029809220110ae05024020032802c00a2209450d002002200110ff010b2003280294092101024020090d002001450d112002102e0c110b200341d80a6a2903002114200341d00a6a2903002115200341c80a6a280200210720032802c40a210a02402001450d002002102e0b20074105742207450d0f200341d8046a41086a2108200921020340200241086a2900002105200241106a29000021062002290000210e20034190096a41186a200241186a29000037030020034190096a41106a200637030020034190096a41086a20053703002003200e37039009200341e8036a20034190096a2015201410cb0220032903e80321052003200341e8036a41086a29030022063703c80a200320053703c00a0240024020052006844200520d002003200341c00a6a3602d804200341d8046a10cc020c010b200342f0f2bda1a7ee9cb9f9003703d804200341c00a6a200341d8046a10cd02200341d8036a200341c00a6a2005200610fd01200341d8046a41106a200341d8036a41086a290300220f20067d20032903d803220e200554ad7d2006200f7d2005200e54ad7d200e200556200f200656200f2006511b22011b3703002003200e20057d2005200e7d20011b3703e00420032001ad3703d8040240024020010d00200320083602e006200341e0066a10cc020c010b200320083602e006200341e0066a10ce020b200341c00a6a41186a2006370300200320053703d00a200341063a00c80a2003410e3a00c00a200341c00a6a10fe010b200241206a2102200741606a22070d000c100b0b410221020c130b20034190096a41026a20032d00c20a22023a0000200341d8046a41026a20023a0000200320032f01c00a22023b019009200320023b01d8042006420888a721022006421888a7210120032903d00a21052006a7212a4100212b0c170b20034190096a41026a20032d00c20a22023a0000200341d8046a41026a20023a0000200320032f01c00a22023b019009200320023b01d8042006420888a721022006421888a7210120032903d00a21052006a7212a4100212b0c170b410221020c170b410221020c1a0b427f201b20057c202820067c220f2028542202ad7c220e2002200e201b54200e201b511b22021b211b427f200f20021b2128427f201d201a7c2020201c7c220f2020542202ad7c220e2002200e201d54200e201d511b22021b211d427f200f20021b2120410121020c160b200341023a0080060c190b200341e0066a41026a200341d8046a41026a2d000022023a0000200320032f00d80422013b01e006200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a000020004201370300200424000f0b200341023a0088080c380b200220134180c1cb00103c000b2002201341f0c0cb00103c000b200341c0076a41021093080c370b200341023a00c0070c370b200341023a00c0050c3a0b200341c00a6a41026a200341c0056a41026a2d000022023a0000200320032f00c00522013b01c00a200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a0000420121050c020b200a41ffffff3f71450d002009102e0b4200210520004200370308200020032800c00a360019200041186a41003a00002000411c6a200341c30a6a2800003600000b20002005370300200424000f0b201642ffffff3f83500d00200b102e0b200341c00a6a41086a20034180066a41086a280200360200200320032903800622053703c00a024002402005a722020d00200341d0046a22024200370300200341c8046a22014200370300200341b8046a41086a22074200370300200342003703b804200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c0073703b804200341c0076a418c81ca00410b10810220022008290000370300200120032900c007370300200341b8046a412010ff010c010b200341d0046a22014200370300200341c8046a22074200370300200341b8046a41086a22084200370300200342003703b804200341c0076a41de80ca0041091081022008200341c0076a41086a220b290000370300200320032900c0073703b804200341c0076a418c81ca00410b1081022001200b290000370300200720032900c007370300200341b8046a200341c00a6a10c40520032802c40a2201450d00200141c4006c450d002002102e0b20034180066a41186a2202420037030020034180066a41106a2201420037030020034180066a41086a220742003703002003420037038006200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c00737038006200341c0076a418081ca00410c10810220022008290000370300200120032900c007370300200341c00a6a20034180066a10aa0520032d00e00a2102200341b8046a41186a2201200341c00a6a41186a290300370300200341b8046a41106a2207200341c00a6a41106a290300370300200341b8046a41086a2208200341c00a6a41086a290300370300200320032903c00a3703b804024020024103460d0020034190096a41186a200129030037030020034190096a41106a200729030037030020034190096a41086a2008290300370300200320032903b80437039009200320023a00b00920034190096a200341e0066a412010ec080d00200341d0046a22024200370300200341c8046a22014200370300200341b8046a41086a22074200370300200342003703b804200341c0076a41de80ca0041091081022007200341c0076a41086a2208290000370300200320032900c0073703b804200341c0076a418081ca00410c10810220022008290000370300200120032900c007370300200341b8046a412010ff010b02402009450d0020034190096a200a108905200341c00a6a2003280290092202200328029809108a0520034180066a41086a2201200341800b6a29030037030020034180066a41106a2207200341880b6a29030037030020034180066a41186a2208200341900b6a29030037030020034180066a41206a2209200341980b6a29030037030020034180066a41286a220b200341a00b6a290300370300200320032800c10a3602c806200320032800c40a3600cb062003200341f80a6a290300370380060240024020032d00c00a220c4102460d00200341f00a6a2903002116200341c00a6a41286a2903002117200341c00a6a41206a2903002118200341c00a6a41186a2903002119200341c00a6a41106a290300211f200341c00a6a41086a290300211e200341c0056a41286a200b290300370300200341c0056a41206a2009290300370300200341c0056a41186a2008290300370300200341c0056a41106a2007290300370300200341c0056a41086a200129030037030020032003290380063703c0050240200328029409450d002002102e0b200341c0076a41086a200341c0056a41086a2903002205370300200341c0076a41106a200341c0056a41106a2903002206370300200341c0076a41186a200341c0056a41186a290300220e370300200341c0076a41206a200341c0056a41206a290300220f370300200341c0076a41286a200341c0056a41286a2903002214370300200320032903c00522153703c007200341c00a6a41286a22022014370300200341c00a6a41206a2201200f370300200341c00a6a41186a2207200e370300200341c00a6a41106a22082006370300200341c00a6a41086a22092005370300200320153703c00a200c450d01200341d8046a41111093080c020b0240200328029409450d002002102e0b200341d8046a41111093080c010b20034184056a2016370200200341f4046a2018370200200341d8046a410c6a201f37020020034194056a20092903003702002003419c056a2008290300370200200341a4056a2007290300370200200341ac056a2001290300370200200341b4056a2002290300370200200320173702fc04200320193702ec042003201e3702dc04200320032903c00a37028c0520034190096a200341dc046a41e00010e9081a200341c8096a200341e0066a412010ec080d00200341c00a6a410c6a200a360200200341c80a6a41063a0000200341093a00c00a200341c00a6a10fe01200341c00a6a200a10890520032802c00a220220032802c80a10ff0120032802c40a450d002002102e0b200341c00a6a41086a41113a0000200341093a00c00a200341c00a6a41096a20032903e006370000200341c00a6a41116a200341e0066a41086a290300370000200341d90a6a200341f0066a290300370000200341e10a6a200341e0066a41186a290300370000200341c00a6a10fe01200041186a41003a000020004200370308200020032800f0083600192000411c6a200341f3086a28000036000020004200370300200424000f0b200341f0086a41026a200341c0056a41026a2d000022013a0000200320032f01c00522073b01f008200041206a20023a0000200041186a41003a000020004200370308200020073b0021200041236a20013a00002000200537002420004201370300200424000f0b20032902c40a210520032802c00a21020240200328029409450d002001102e0b2003200537029c0420032002360298040b20032d0098044106460d01200329029c0421050b200328029804210320002005370024200041206a2003360000200041186a41003a00002000420037030820004201370300200424000f0b20004200370308200020032800d008360019200041186a41003a00002000411c6a200341d3086a28000036000020004200370300200424000f0b200320032f01d8043b018006200320073a009f06200320083b009d06200320093a009c062003200a3a009b062003200b3b0099062003200c3a0098062003200537039006200320013a008f06200320023b008d062003202a3a008c062003200d3a008b06200320133b008906200320123a008806200320103a008706200320113b008506200320223a008406200320233a008306410221022003200341d8046a41026a2d00003a008206024002400240202b0d00200341b8046a41186a20034180066a41186a2903002205370300200341b8046a41106a20034180066a41106a2903002206370300200341b8046a41086a20034180066a41086a290300220e3703002003200329038006220f3703b804200341c00a6a41186a2005370300200341c00a6a41106a2006370300200341c00a6a41086a200e3703002003200f3703c00a200320323602980920032029360294092003202c36029009200341d8046a200341c00a6a20034190096a10bd08200341c8066a41026a20032d00db043a0000200320032f00d9043b01c80620032d00d80422024106460d0220032902dc042105200341c0056a41026a200341c8066a41026a2d00003a0000200320032f01c8063b01c0050c010b02402029450d00202c102e0b0b200341f0086a41026a2201200341c0056a41026a2d00003a0000200320032800e0063602c007200320032f01c0053b01f0082003200341e3066a2800003600c307200041186a41003a000020004200370308200020032802c0073600192000411c6a20032800c307360000200041206a20023a0000200041246a2005370200200020032f01f0083b0021200041236a20012d00003a000020004201370300200424000f0b200320032800e0063602c0072003200341e3066a2800003600c307200041186a41013a000020004200370308200020032802c0073600192000411c6a20032800c30736000020004200370300200424000f0b200320032f01d8043b018006200320073a009f06200320083b009d06200320093a009c062003200a3a009b062003200b3b0099062003200c3a0098062003200537039006200320013a008f06200320023b008d062003202a3a008c062003200d3a008b06200320133b008906200320123a008806200320103a008706200320113b008506200320223a008406200320233a008306410221022003200341d8046a41026a2d00003a008206024002400240202b0d00200341b8046a41186a20034180066a41186a2903002205370300200341b8046a41106a20034180066a41106a2903002206370300200341b8046a41086a20034180066a41086a290300220e3703002003200329038006220f3703b804200341c00a6a41186a2005370300200341c00a6a41106a2006370300200341c00a6a41086a200e3703002003200f3703c00a200320323602980920032029360294092003202c36029009200341d8046a200341c00a6a20034190096a10bc08200341c8066a41026a20032d00db043a0000200320032f00d9043b01c80620032d00d80422024106460d0220032902dc042105200341c0076a41026a200341c8066a41026a2d00003a0000200320032f01c8063b01c0070c010b02402029450d00202c102e0b0b200341c0056a41026a200341c0076a41026a2d000022013a0000200320032f01c00722073b01c005200041206a20023a0000200041186a41003a000020004200370308200020073b0021200041236a20013a00002000200537002420004201370300200424000f0b200041186a41003a000020004200370308200020032800e0063600192000411c6a200341e3066a28000036000020004200370300200424000f0b200320032800d0083602c0082003200341d3086a2800003600c308200041186a41003a000020004200370308200020032802c0083600192000411c6a20032800c308360000200041246a2005370200200041206a200236020020004201370300200424000f0b200341900b6a201b370300200341880b6a2028370300200341800b6a201d370300200341f80a6a2020370300200341e80a6a2019370300200341e00a6a201e370300200341d80a6a2018370300200341d00a6a201f370300200341f00a6a2021370300200341cc0a6a2036360200200341c00a6a41086a2035360200200341980b6a20032903d008370300200341ac0b6a203d360200200341a80b6a203e360200200341a00b6a200341d0086a41086a290300370300200320032f01e4083b00c10a200320073602c40a2003200341e4086a41026a2d00003a00c30a200320013a00c00a0240024020014102470d00203b203c10ff010c010b200341d8046a200341c00a6a10c204203b203c20032802d804220820032802e00410b201024020032802dc04450d002008102e0b20010d002035450d00203541306c450d002007102e0b024020032802c408450d00203b102e0b20034188086a20062005108307200341d80a6a20032903d805370300200320032903d0053703d00a200320032903c80522063703c80a200320032903c00522053703c00a200341e00a6a20034190096a41c80010e9081a200341ac0b6a203a360200200341a80b6a20032802b80836020002402005a7220141ff01714102470d002037203910ff01410021010c010b200341d8046a200341c00a6a10c2042037203920032802d804220720032802e00410b201024020032802dc04450d002007102e0b0240200141ff01710d002006a72201450d00200141306c450d002005422088a7102e0b410021010b024020032802ac08450d002037102e0b20010d01200341c00a6a41086a41083a0000200341e90a6a20032903f008370000200341093a00c00a200341c00a6a41096a200329038808370000200341d10a6a20034188086a41086a290300370000200341d90a6a20034188086a41106a290300370000200341e10a6a20034188086a41186a290300370000200341f10a6a200341f0086a41086a290300370000200341f90a6a200341f0086a41106a290300370000200341810b6a200341f0086a41186a290300370000200341c00a6a10fe01200320032800910436028804200320034194046a28000036008b04200041186a41003a0000200041106a2002ad220542d8d4ea037e200542c0f0f50b7e7c20054280c2d72f7e7c42b8b8c589027c3703002000420137030820002003280288043600192000411c6a200328008b0436000020004200370300200424000f0b20032902c40a210520032802c00a21020b200320032800910436028804200320034194046a28000036008b04200041186a41003a00002000420037030820002003280288043600192000411c6a200328008b04360000200041246a2005370200200041206a200236020020004201370300200424000f0b200328028006210320002005370024200041206a2003360000200041186a41003a00002000420037030820004201370300200424000f0b20004200370308200020032800c005360019200041186a41003a00002000411c6a200341c3056a28000036000020004200370300200424000f0b20004200370308200020032800f008360019200041186a41003a00002000411c6a200341f3086a28000036000020004200370300200424000f0b0c030b20032005421888a73a00c30a20032005421088a73a00c20a20032005a73b01c00a200320063702c40a20032903c00a21054110102c2202450d21200241f8f7c60036020c2002410136020820024281808080103702004110102c2207450d212006422088210620074190f8c60036020c20074101360208200742818080801037020020022002280200417f6a2201360200024020010d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b2006a72108410221020b20032005370294092003200b3a0093092003200c3a0092092003200d3b0190090b41002101200241ff0171410346220a0d00200341e60a6a20353b0100200341e20a6a2008360100200341da0a6a2005370100200341d90a6a200b3a0000200341d80a6a200c3a0000200341d60a6a200d3b0100200341d50a6a20293a0000200341d40a6a202a3a0000200341d20a6a202c3b0100200341d10a6a20323a0000200341d00a6a20313a0000200341ce0a6a20123b0100200341cd0a6a20103a0000200341cc0a6a20113a0000200341ca0a6a20223b0100200341c90a6a20233a0000200341c80a6a202b3a0000200320073602e80a200320333b01c60a200320363a00c50a200320133a00c40a200320373b01c20a200320383a00c10a200320023a00c00a41012101200341c00a6a10fd0641ff01714102470d00200341023a00c0050c010b200341b8046a41186a22024200370300200341b8046a41106a22084200370300200341b8046a41086a220b4200370300200342003703b804200341c0076a41de80ca004109108102200b200341c0076a41086a220c290000370300200320032900c0073703b804200341c0076a418081ca00410c1081022002200c290000370300200820032900c007370300200341c00a6a200341b8046a10aa0520032d00e00a210220034180066a41186a2208200341c00a6a41186a29030037030020034180066a41106a200341c00a6a41106a29030037030020034180066a41086a200341c00a6a41086a290300370300200320032903c00a370380060240024020024103460d00200341f7066a220b2008290000370000200341e0066a41106a220820034180066a41116a290000370300200341e0066a41086a20034180066a41096a2900002205370300200320032900810622063703e00620032d008006210c20034190096a41096a200537000020034190096a41116a200829030037000020034190096a41186a200b2900003700002003200c3a0090092003200637009109024020020d00200341c0056a41071093080c020b0240200341d8046a20034190096a412010ec08450d00200341c0056a41081093080c020b20034180066a41186a2208420037030020034180066a41106a220b420037030020034180066a41086a220c42003703002003420037038006200341c0076a41de80ca004109108102200c200341c0076a41086a220d290000370300200320032900c00737038006200341c0076a418081ca00410c1081022008200d290000370300200b20032900c00737030020034180066a412010ff01200341c00a6a41186a22084200370300200341c00a6a41106a220b4200370300200341c00a6a41086a220c4200370300200342003703c00a20034188086a41d9fcc6004106108102200c20034188086a41086a220d29000037030020032003290088083703c00a20034188086a4180f4cb0041061081022008200d290000370300200b200329008808370300200341e0016a200341c00a6a4120108e0220032802e401210d20032802e00121132008200341d8046a41186a290300370300200b200341d8046a41106a290300370300200c200341d8046a41086a290300370300200320032903d8043703c00a200d410020131b20096a200341c00a6a200220341095082001200a720d0320072007280200417f6a220236020020020d032007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d032007102e0c030b200341c0056a41021093080b02402001200a724101460d0020072007280200417f6a220236020020020d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22022002280200417f6a220236020020020d002007102e0b20032d00c0054106460d020b20032802c0052102200020032902c405370024200041206a2002360000200041186a41003a00002000420037030820004201370300200424000f0b200341063a00c0050b20004200370308200020032800f008360019200041186a41003a00002000411c6a200341f3086a28000036000020004200370300200424000f0b4110102c2202450d1a200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1a20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220736020020070d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22072007280200417f6a220736020020070d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200341f0086a41026a200341c0056a41026a2d000022023a0000200320032f00c00522013b01f008200041206a41023a0000200041186a41003a000020004200370308200020013b0021200041236a20023a000020004201370300200424000f0b20004200370308200020032800c005360019200041186a41003a00002000411c6a200341c3056a28000036000020004200370300200424000f0b20032d0088084106470d030b20004200370308200020032800b804360019200041186a41003a00002000411c6a200341bb046a28000036000020004200370300200424000f0b4110102c2202450d15200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1520014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220736020020070d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22072007280200417f6a220736020020070d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200341023a0088080b20032802880821022000200329028c08370024200041206a2002360000200041186a41003a00002000420037030820004201370300200424000f0b2030211e201521180b202f211c2016211a0b200341c00a6a41046a222b20034198046a41046a2d00003a000020032003280298043602c00a202a20113a0000200120123a0000200a20103a00002007200241306c6a2202410f6a202b2d00003a00002002410b6a20032802c00a36000020292005370308202920063703002009200e3703082009200f3703000c010b200341f0086a41046a20034198046a41046a2d00003a000020032003280298043602f00820132001490d0202402013200d470d00200d41016a2202200d490d11200d41017422092002200920024b1b22024104200241044b1bad42307e2215422088a74541037421022015a7210902400240200d0d00200341003602c00a0c010b200341c00a6a41086a4108360200200320073602c00a2003200d41306c3602c40a0b200341d8046a20092002200341c00a6a107d200341e0046a280200210220032802d8044101460d0520032802dc042107200241306e210d0b2007200141306c6a220241306a2002201320016b41306c10ea081a2002410a6a20103a0000200241096a20113a0000200220123a000820022008360200200241286a200e370300200241206a200f370300200241186a2005370300200241106a20063703002002410b6a20032802f0083600002002410f6a200341f4086a2d00003a0000201341016a21130b0240024002400240201241ff01714101470d00200341c8006a20062005420a420010e708200341386a200f200e420a420010e708201e20067c2216201e542202201820057c2002ad7c221520185420152018511b0d022016200f7c220f20165422022015200e7c2002ad7c220e201554200e2015511b0d02201c20032903487c2216201c542202201a200341c8006a41086a2903007c2002ad7c2215201a542015201a511b0d01201d20032903387c221e201d542202201b200341386a41086a2903007c2002ad7c2218201b542018201b511b450d09200f211e200e21182016211c2015211a0c020b02400240201041ff0171450d0041062102024002400240024002400240024020104107710e0700010203040506000b410021020c050b410121020c040b410221020c030b410321020c020b410421020c010b410521020b200341e8006a200542002002ad220e420010e808200341f8006a20064200200e420010e808427f20034180016a290300220e20032903687c220f2003290370420052200f200e547222021b2115427f200329037820021b21160c010b200341d8006a20062005420a420010e708200341e0006a2903002115200329035821160b201e20067c220f201e542202201820057c2002ad7c220e201854200e2018511b0d010240201141ff01710d00201d20167c221e201d542202201b20157c2002ad7c2218201b542018201b511b0d01201241ff0171450d060c080b201c20167c2216201c542202201a20157c2002ad7c2215201a542015201a511b450d020b200f211e200e21180b20034180066a41191093080c010b0240201241ff01710d00201141ff01714102460d00427f201520277c201620197c22182016542202ad7c22162002201620155420162015511b22021b2115427f201820021b2116427f200e20287c200f201f7c2218200f542202ad7c220f2002200f200e54200f200e511b22021b210e427f201820021b210f0b201d211e201b21180c050b024020032d00800622024106470d00201e210f2018210e201d211e201b2118201c2116201a21150c060b200341ca066a20032d0083063a0000200320032f0081063b01c80620032902840621190240200c0d00200d450d00200d41306c450d002007102e0b201e210f2018210e201d211e201b2118201c2116201a21150c060b200120131045000b427f201820277c201e20197c2216201e542202ad7c22152002201520185420152018511b22021b2118427f201620021b211e427f200e20287c200f201f7c2215200f542202ad7c220f2002200f200e54200f200e511b22021b210e427f201520021b210f0c010b2002450d0b0c0a0b201c2116201a21150b200341063a0080060b200341900b6a2020370300200341880b6a2021370300200341800b6a2026370300200341f80a6a2025370300200341e80a6a2028370300200341e00a6a201f370300200341d80a6a2027370300200341d00a6a2019370300200341f00a6a2024370300200341cc0a6a2013360200200341c00a6a41086a200d360200200341980b6a200329039009370300200341ac0b6a2022360200200341a80b6a2023360200200341a00b6a20034190096a41086a290300370300200320032f01c0083b00c10a200320073602c40a2003200341c0086a41026a2d00003a00c30a2003200c3a00c00a20032802c805210220032802c005210102400240200c4102470d002001200210ff010c010b200341d8046a200341c00a6a10c2042001200220032802d804220920032802e00410b201024020032802dc04450d002009102e0b200c0d00200d450d00200d41306c450d002007102e0b200341ca066a20032d0083063a0000200320032f0081063b01c8062003290284062119410621020b024020032802c405450d0020032802c005102e0b200341a8086a41026a2201200341c8066a41026a2d00003a0000200320032f01c8063b01a808024020024106470d00200341c0076a427f2017200b1b2006201241ff017141014622021b427f2014200b1b200520021b108307200341f00a6a200e370300200341c00a6a41286a200f370300200341c00a6a41206a2018370300200341c00a6a41186a201e370300200341c00a6a41106a2015370300200341f80a6a20032903e006370300200341800b6a200341e8066a290300370300200341880b6a200341e0066a41106a290300370300200341900b6a200341e0066a41186a290300370300200341980b6a200341e0066a41206a290300370300200341a00b6a200341e0066a41286a290300370300200320163703c80a200341003a00c00a200341d8046a200810890520032802e004210120032802d804210220034100360298092003420137039009200341c00a6a20034190096a10bc0520022001200328029009220720032802980910b2010240200328029409450d002007102e0b024020032802dc04450d002002102e0b200341063a0088080c030b200320023a008808200320032f01a8083b0089082003201937028c08200320012d00003a008b080b20032d0088084106460d01200329028c0821050b200328028808210320002005370024200041206a2003360000200041186a41003a00002000420037030820004201370300200424000f0b20004200370308200020032800b804360019200041186a41003a00002000411c6a200341bb046a28000036000020004200370300200424000f0b20032d00c0074106460d0120032902c40721050b20032802c007210320002005370024200041206a2003360000200041186a41003a00002000420037030820004201370300200424000f0b20004200370308200020032800c005360019200041186a41003a00002000411c6a200341c3056a28000036000020004200370300200424000f0b1036000b1038000b20032802c005210320002005370024200041206a2003360000200041186a41003a00002000420037030820004201370300200424000f0b20004200370308200020032800f008360019200041186a41003a00002000411c6a200341f3086a28000036000020004200370300200424000bec7a08077f027e017f017e027f017e067f037e230041a00a6b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0700010203040506000b200341c4076a4101360200200342013702b4072003419cc3cb003602b007200341043602fc0420034194c3cb003602f8042003200341f8046a3602c007200341b0076a41b8afc9001044000b20012d000121042001412c6a2802002105200141286a2802002106200141246a2802002107200341c8026a41186a2001411a6a290000370300200341c8026a41106a200141126a290000370300200341c8026a41086a2001410a6a2900003703002003200141026a2900003703c802200341b0076a41286a200241286a280200360200200341b0076a41206a200241206a290200370300200341b0076a41186a2208200241186a290200370300200341b0076a41106a2201200241106a290200370300200341b0076a41086a2209200241086a290200370300200320022902003703b007024002400240200341b0076a10a7050d00200842003703002001420037030020094200370300200342003703b007200341f8046a41c8afc90041131081022009200341f8046a41086a2202290000370300200320032900f8043703b007200341f8046a41c7c3cb00410710810220082002290000370300200120032900f804370300200341f8046a200341b0076a10880320032802f804210220032902fc04210a2007200510fc02200341b0076a200720052002410120021b2208200a420020021b220a422088220ba710fe022001280200210120032802b407210220032802b007210920032802bc07220c200341c4076a2802002007200510f5020240200141ffffff3f71450d00200c102e0b0240200241ffffff3f71450d002009102e0b200341f8006a41186a2201200341c8026a41186a290300370300200341f8006a41106a2202200341c8026a41106a290300370300200341f8006a41086a2209200341c8026a41086a290300370300200320032903c802370378200441ff01710d01200341f8046a41186a22014200370300200341f8046a41106a22024200370300200341f8046a41086a22094200370300200342003703f80420034198016a41c8afc9004113108102200920034198016a41086a220429000037030020032003290098013703f80420034198016a41dbc3cb004105108102200120042900003703002002200329009801370300200341f8046a412010ff010c020b0240200641ffffff3f71450d002007102e0b200320032800b8013602f801200320032900a802370388022003200341bb016a2800003600fb012003200341af026a28000036008f02200041186a41003a000020004200370308200020032802f8013600192000411c6a20032800fb01360000200041206a41023a00002000200329038802370021200041286a200328008f02360000200042013703000c200b200341b0076a41186a2001290300370300200341b0076a41106a2002290300370300200341b0076a41086a2009290300370300200320032903783703b007200341f0096a41186a22014200370300200341f0096a41106a22024200370300200341f0096a41086a22094200370300200342003703f009200341f8046a41c8afc90041131081022009200341f8046a41086a2204290000370300200320032900f8043703f009200341f8046a41dbc3cb00410510810220012004290000370300200220032900f8043703004120102c2201450d1a200342203702fc04200320013602f804200341f8046a200341b0076a41201074200341f0096a412020032802f804220120032802800510b20120032802fc04450d002001102e0b2005ad42b882077e200b42c0b5e5097e7c210b0240200641ffffff3f71450d002007102e0b200b42a0c0b291397c210b0240200a42ffffff3f83500d002008102e0b200320032800b8013602f8012003200341bb016a2800003600fb01200041186a41003a0000200041106a200b37030020004201370308200020032802f8013600192000411c6a20032800fb01360000200042003703000c1e0b200141086a2802002104200141046a2802002105200341b0076a41286a200241286a280200360200200341b0076a41206a200241206a290200370300200341b0076a41186a2201200241186a290200370300200341b0076a41106a2207200241106a290200370300200341b0076a41086a2206200241086a290200370300200320022902003703b007200341f8046a200341b0076a10c102200341f8006a41086a220220034181056a290000370300200341f8006a41106a220820034189056a290000370300200341f8006a41186a220920034191056a290000370300200320032900f90437037820032d00f8044101460d0820034198016a41186a200929030037030020034198016a41106a200829030037030020034198016a41086a20022903003703002003200329037837039801200142003703002007420037030020064200370300200342003703b007200341f8046a41c8afc90041131081022006200341f8046a41086a2202290000370300200320032900f8043703b007200341f8046a41c7c3cb00410710810220012002290000370300200720032900f804370300200341f8046a200341b0076a10880320032902fc04420020032802f80422021b220a422088220ba741057421012002410120021b22062102024002400240024003402001450d01200141606a2101200220034198016a412010ec082107200241206a210220070d000b200341003602b807200342013703b0072005200341b0076a10900220032802b8072107024020032802b407450d0020032802b007102e0b0240200720044d0d00200341b0076a410a10f307200320032900b1073703602003200341b8076a2800003600670c020b2003410036028005200342013703f8042005200341f8046a109002200341b0076a20032802f80420032802800510b00120034188026a41186a200341b0076a41186a29030037030020034188026a41106a200341b0076a41106a29030037030020034188026a41086a200341b0076a41086a290300370300200320032903b00737038802024020032802fc04450d0020032802f804102e0b200341f8046a200541b00210e9081a200341a8026a41086a20034198016a41086a290300370300200341a8026a41106a20034198016a41106a290300370300200341a8026a41186a20034198016a41186a29030037030020032003290398013703a8024110102c2202450d1c200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1c20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a2208360200024020080d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22082008280200417f6a220836020020080d002002102e0b024002402001280208200341f8046a200128020c28020c1101000d0041022102200341e8026a41023a0000200341e0026a41003a000020012001280200417f6a22083602004200210d200342003703d002200342013703c802024020080d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22082008280200417f6a220836020020080d002001102e0b200341f8046a10dc02410121010c010b200341b0076a200341f8046a41b00210e9081a200341fd096a200341b0026a290300370000200341850a6a200341b8026a2903003700002003418d0a6a200341c0026a290300370000200341950a6a20032f00783b0000200341970a6a200341fa006a2d00003a0000200341013a00f409200341013a00f009200320032903a8023700f509200320013602980a200341c8026a200341b0076a200341f0096a10dd0220032903c8024201512101200341e8026a2d0000210220032903d002210d0b200341f8046a41186a20034188026a41186a290300370300200341f8046a41106a20034188026a41106a290300370300200341f8046a41086a20034188026a41086a29030037030020032003290388023703f8042003200341f0026a2800003600b707200320032900e9023703b0070240024020010d00410621010c010b200320032800b7073600ff01200320032903b0073703f80141062101200d4202510d00200320032800ff013600ef01200320032903f8013703e801200221010b200341f0096a41086a2202200341f8046a41086a290300370300200341f0096a41106a2208200341f8046a41106a290300370300200341f0096a41186a2209200341f8046a41186a290300370300200320032903f8043703f009200320032903e8013703d801200320032800ef013600df01200341053a00b4072003410a3a00b007200341bd076a2002290300370000200341c5076a2008290300370000200341cd076a2009290300370000200341d8076a20013a0000200320032903f0093700b507200341d5076a20032f00e5013b0000200341d7076a200341e7016a2d00003a0000200341d9076a20032903d801370000200341e0076a20032800df01360000200341fc076a200341b8016a41186a280200360200200341f4076a200341b8016a41106a290200370200200341ec076a200341b8016a41086a290200370200200341e4076a20032902b801370200200341b0076a10fe01200da70d024200210b0c030b200341b0076a410110f307200320032900b1073703602003200341b8076a2800003600670b20032d00b0072101200a42ffffff3f83500d1e2006102e0c1e0b427f2007ad42a01f7e200b4280eb067e7c42d8bbe3167c220b200341c8026a41106a2903007c220d200d200b541b210d4201210b0b0240200a42ffffff3f83500d002006102e0b2005102e2003200341f4006a28000036005b20032003280071360258200041186a41003a0000200041106a200d3703002000200b370308200020032802583600192000411c6a200328005b360000200042003703000c1d0b2001410c6a2802002104200141086a2802002105200141046a280200210c200341b0076a41286a200241286a280200360200200341b0076a41206a200241206a290200370300200341b0076a41186a2201200241186a290200370300200341b0076a41106a2206200241106a290200370300200341b0076a41086a2207200241086a290200370300200320022902003703b007200341f8046a200341b0076a10c102200341c8026a41086a220220034181056a290000370300200341c8026a41106a220820034189056a290000370300200341c8026a41186a220920034191056a290000370300200320032900f9043703c80202400240024020032d00f8044101460d0020034188026a41186a200929030037030020034188026a41106a200829030037030020034188026a41086a2002290300370300200320032903c80237038802200142003703002006420037030020074200370300200342003703b007200341f8046a41c8afc90041131081022007200341f8046a41086a2202290000370300200320032900f8043703b007200341f8046a41c7c3cb00410710810220012002290000370300200620032900f804370300200341f8046a200341b0076a10880320032902fc04420020032802f80422021b220b422088220aa741057421012002410120021b2208210203402001450d02200141606a2101200220034188026a412010ec082107200241206a210220070d000b200341003602b807200342013703b0072005200341b0076a10900220032802b8072101024020032802b407450d0020032802b007102e0b200120044d0d02200341b0076a410a10f3070c1b0b410221010c1c0b200341b0076a410110f3070c190b2003410036028005200342013703f8042005200341f8046a109002200341b0076a20032802f80420032802800510b001200341a8026a41186a2202200341b0076a41186a2207290300370300200341a8026a41106a2209200341b0076a41106a2204290300370300200341a8026a41086a220e200341b0076a41086a220f290300370300200320032903b0073703a802024020032802fc04450d0020032802f804102e0b2007200229030037030020042009290300370300200f200e290300370300200320032903a8023703b007200341f8046a200341b0076a10f40720032802f8042207200328028005108f022102024020032802fc04450d002007102e0b02402002450d00200341b0076a410210f3070c190b024002400240200c41014b0d00200341c8076a4200370300200341c0076a4200370300200341b0076a41086a22024200370300200342003703b007200341f8046a41c8afc90041131081022002200341f8046a41086a2207290000370300200320032900f8043703b007200341f8046a41c7c3cb004107108102200641086a2007290000370000200620032900f804370000200341c8026a200341b0076a1088030240024020032802c80222020d00410021090c010b20032902cc02220d422088a72109200d42ffffff3f83500d002002102e0b200341f8046a200541b00210e9081a4110102c2207450d1a200741f8f7c60036020c2007410136020820074281808080103702004110102c2202450d1a20024190f8c60036020c20024101360208200242818080801037020020072007280200417f6a2206360200024020060d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22062006280200417f6a220636020020060d002007102e0b024002402002280208200341f8046a200228020c28020c1101000d0041022107200341e8026a41023a0000200341e0026a41003a000020022002280200417f6a22063602004200210d200342003703d002200342013703c802024020060d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22062006280200417f6a220636020020060d002002102e0b200341f8046a10dc02410121020c010b200341b0076a200341f8046a41b00210e9081a200341fc096a2009360200200341f0096a41086a4101360200200341f0096a41106a200329019801370300200341880a6a20034198016a41086a290100370300200341f0096a41206a20034198016a41106a290100370300200341003a00f409200341013a00f009200320032f00783b00f5092003200341fa006a2d00003a00f709200320023602980a200341c8026a200341b0076a200341f0096a10dd0220032903c8024201512102200341c8026a41206a2d0000210720032903d002210d0b200341f0096a41186a200341a8026a41186a290300370300200341f0096a41106a200341a8026a41106a290300370300200341f0096a41086a200341a8026a41086a290300370300200320032903a8023703f0092003200341f0026a2800003600b707200320032900e9023703b0070240024020020d00410621020c010b200320032800b7073600ff01200320032903b0073703f80141062102200d4202510d00200320032800ff013600ef01200320032903f8013703e801200721020b200341f8006a41086a2207200341f0096a41086a290300370300200341f8006a41106a2206200341f0096a41106a290300370300200341f8006a41186a2209200341f0096a41186a290300370300200320032903f009370378200320032903e8013703d801200320032800ef013600df01200341043a00b4072003410a3a00b007200341bd076a2007290300370000200341c5076a2006290300370000200341cd076a2009290300370000200341d8076a20023a0000200320032903783700b507200341d5076a20032f00e5013b0000200341d7076a200341e7016a2d00003a0000200341d9076a20032903d801370000200341e0076a20032800df01360000200341fc076a200341b8016a41186a280200360200200341f4076a200341b8016a41106a290200370200200341ec076a200341b8016a41086a290200370200200341e4076a20032902b801370200200341b0076a10fe010240200da70d004200210d0c020b427f2001ad42a01f7e200a42e8dd0d7e7c42d8ce86257c220a200341c8026a41106a2903007c220d200d200a541b210a4201210d0c010b200341b0076a41186a4200370300200341b0076a41106a4200370300200341b0076a41086a22024200370300200342003703b007200341f8046a41c8afc90041131081022002200341f8046a41086a2209290000370300200320032900f8043703b007200341f8046a41dbafc9004109108102200641086a2009290000370000200620032900f804370000200341f8046a200341b0076a4120108d0320032802f804210220032902fc04210d200341f8046a41186a220e200341a8026a41186a290300370300200341f8046a41106a220f200341a8026a41106a2903003703002009200341a8026a41086a290300370300200320032903a8023703f8042002410120021b21070240024002400240200d420020021b220d4220882210a72202200da7470d00200241016a22042002490d1820024101742211200420042011491b22044104200441044b1b220441ffffff3f712004462111200441057421040240024020020d00200341003602b0070c010b200341b8076a4101360200200320073602b007200320104205863e02b4070b200341c8026a20042011200341b0076a107d200341d0026a280200210420032802c8024101460d0120032802cc022107200d422088a721022004410576ad210d0b200720024105746a220420032903f804370000200441186a200e290300370000200441106a200f290300370000200441086a2009290300370000200241016a220241e4004b0d04200320073602b0072003200d42ffffffff0f832002ad2210422086843702b40720070d0120034190056a2202420037030020034188056a22074200370300200341f8046a41086a22094200370300200342003703f80420034198016a41c8afc9004113108102200920034198016a41086a220429000037030020032003290098013703f80420034198016a41dbafc9004109108102200220042900003703002007200329009801370300200341f8046a412010ff010c020b2004450d160c1b0b20034190056a2202420037030020034188056a22094200370300200341f8046a41086a22044200370300200342003703f80420034198016a41c8afc9004113108102200420034198016a41086a220e29000037030020032003290098013703f80420034198016a41dbafc90041091081022002200e2900003703002009200329009801370300200341f8046a200341b0076a10e6042007450d00200d42ffffff3f83500d002007102e0b200341f8046a41186a22024200370300200341f8046a41106a22074200370300200341f8046a41086a22094200370300200342003703f80420034198016a41c8afc9004113108102200920034198016a41086a220429000037030020032003290098013703f80420034198016a41e4afc900410d108102200220042900003703002007200329009801370300200341186a200341f8046a4120108e02200328021c210e2003280218210f200242003703002007420037030020094200370300200342003703f80420034198016a41c8afc90041131081022009200429000037030020032003290098013703f80420034198016a41e4afc900410d108102200220042900003703002007200329009801370300200341106a200341f8046a4120108e022003280210211120032802142112200242003703002007420037030020094200370300200342003703f80420034198016a41c8afc90041131081022009200429000037030020032003290098013703f80420034198016a41e4afc900410d1081022002200429000037030020072003290098013703002003201241016a410120111b3602b007200341f8046a4120200341b0076a410410b201200341b0076a200541b00210e9081a2002200341a8026a41186a2903003703002007200341a8026a41106a2903003703002009200341a8026a41086a290300370300200320032903a8023703f804200341c8026a200341f8046a10f40720032802c802210220032802d0022107200342013703f8042003410036028005200341b0076a200341f8046a1090022002200720032802f80420032802800510b201024020032802fc04450d0020032802f804102e0b024020032802cc02450d002002102e0b200341b0076a108b02200341b0076a41186a4200370300200341b0076a41106a4200370300200341b0076a41086a22024200370300200342003703b007200341f8046a41d9fcc60041061081022002200341f8046a41086a2207290000370300200320032900f8043703b007200341f8046a4180f4cb004106108102200641086a2007290000370000200620032900f804370000200341086a200341b0076a4120108e02200328020c2106200328020821094120102c2202450d192002200329038802370000200241186a20034188026a41186a290300370000200241106a20034188026a41106a290300370000200241086a20034188026a41086a290300370000200341cc076a4100360200200341bc076a4281808080103702002003200641c093066a41c0930620091b3602d0074201210d200342013702c407200320023602b8072003200c3602b4072003200e4100200f1b22063602b007200341f8046a41186a200341a8026a41186a290300370300200341f8046a41106a200341a8026a41106a2903003703002007200341a8026a41086a290300370300200320032903a8023703f804200341c8026a200341f8046a10f50720032802c802220720032802d002200341b0076a10be05024020032802cc02450d002007102e0b2002102e200341bd076a20034188026a41086a290300370000200341c5076a20034188026a41106a290300370000200341cd076a20034188026a41186a290300370000200341d5076a20032903a802370000200341dd076a200341a8026a41086a290300370000200341e5076a200341a8026a41106a290300370000200341ed076a200341a8026a41186a290300370000200341fc076a200c360200200341f8076a2006360200200341003a00b4072003410a3a00b00720032003290388023700b5072001ad4288277e200a42a08a077e7c201042f8fe1c7e7c42a0c28084027c210a200341b0076a10fe010b0240200b42ffffff3f83500d002008102e0b2005102e2003200341e3006a28000036004b20032003280060360248200041186a41003a0000200041106a200a3703002000200d370308200020032802483600192000411c6a200328004b360000200042003703000c1d0b200341b0076a410810f30720032902b407210a20032802b0072101200d42ffffff3f83500d192007102e0c190b200141216a2d00002104200141246a2802002109200341a8026a41186a200141196a290000370300200341a8026a41106a200141116a290000370300200341a8026a41086a200141096a290000370300200320012900013703a802200341b0076a41286a200241286a280200360200200341b0076a41206a200241206a290200370300200341b0076a41186a2201200241186a290200370300200341b0076a41106a2207200241106a290200370300200341b0076a41086a2205200241086a290200370300200320022902003703b007200341f8046a200341b0076a10c102200341f8006a41086a2202200341f8046a41096a290000370300200341f8006a41106a2206200341f8046a41116a290000370300200341f8006a41186a2208200341f8046a41196a290000370300200320032900f904370378024002400240024020032d00f8044101460d00200341c8026a41186a2008290300370300200341c8026a41106a2006290300370300200341c8026a41086a2002290300370300200320032903783703c802200142003703002007420037030020054200370300200342003703b007200341f8046a41c8afc90041131081022005200341f8046a41086a2202290000370300200320032900f8043703b007200341f8046a41c7c3cb00410710810220012002290000370300200720032900f804370300200341f8046a200341b0076a10880320032902fc04420020032802f80422021b220a422088220ba741057421012002410120021b2208210203402001450d02200141606a21012002200341c8026a412010ec082107200241206a210220070d000b200341f8046a200341a8026a10f607200341b0076a20032802f804220220032802800510b30520032802fc04210120032802b807220c450d02200341d0076a2802002113200341cc076a280200210f200341c8076a2802002112200341c4076a2802002114200341c0076a280200210e20032802bc07211120032903b007210d02402001450d002002102e0b2009200da7460d03200341b0076a410410f307200320032900b107370388022003200341b8076a28000036008f020c110b410221010c120b200341b0076a410110f307200320032900b107370388022003200341b8076a28000036008f0220032d00b00721010c100b02402001450d002002102e0b200341b0076a410310f307200320032900b107370388022003200341b8076a28000036008f0220032d00b00721010c0f0b4100210202400240200e0d004101210641002107410021090c010b200e41057441606a41057641016a210541002107200c2101034002402001200341c8026a412010ec080d0041002106410121090c020b200141206a2101410121062005200741016a2207470d000b41002109200521070b02400240024002400240200f450d00200f41057441606a41057641016a2105410021022014210103402001200341c8026a412010ec08450d02200141206a21012005200241016a2202470d000b200521020b2009450d01200441ff01710d03410021050c020b200441ff0171450d052006450d0241002105410121060c130b4100210641012105200441ff01710d120b200341f8046a41186a2202200341c8026a41186a290300370300200341f8046a41106a2206200341c8026a41106a290300370300200341f8046a41086a2215200341c8026a41086a290300370300200320032903c8023703f8040240200f2012470d00201241016a22012012490d13201241017422162001201620014b1b22014104200141044b1b220141ffffff3f712001462116200141057421010240024020120d00200341003602b0070c010b200341b8076a4101360200200320143602b007200320124105743602b4070b200341f0096a20012016200341b0076a107d200341f8096a2802002101024020032802f0094101470d0020010d190c140b20032802f4092114200141057621120b2014200f4105746a220120032903f804370000200141186a2002290300370000200141106a2006290300370000200141086a2015290300370000200f41016a210f2009450d15200e20074d0d04200c200e417f6a220e4105746a220129000021102001290008211720012900102118200c20074105746a220241186a200141186a2900003700002002201837001020022017370008200220103700000c150b200341b0076a410510f307200320032900b107370388022003200341b8076a28000036008f020c0d0b200141286a2802002108200141306a290300210b200141246a2802002107200341a8026a41186a200141196a290000370300200341a8026a41106a200141116a290000370300200341a8026a41086a200141096a290000370300200320012900013703a802200341b0076a41286a200241286a280200360200200341b0076a41206a2201200241206a290200370300200341b0076a41186a2205200241186a290200370300200341b0076a41106a2206200241106a290200370300200341b0076a41086a200241086a290200370300200320022902003703b007200341f8046a200341b0076a10c10202400240024020032d00f8044101460d00200341f8046a200341a8026a10f607200341b0076a20032802f804220920032802800510b30520032802fc042102024020032802b8072204450d002001280200210f200341cc076a280200210c20052802002105200341c4076a280200210e2006280200210120032802bc07210620032903b007210d02402002450d002009102e0b2007200da7460d03200341b0076a410410f307200320032900b107370388022003200341b8076a28000036008f0220032d00b0072102410121070c0c0b02402002450d002009102e0b200341b0076a410310f307200320032900b107370388022003200341b8076a28000036008f0220032d00b00721020c010b410221020b4200210a410021010c0b0b200d422088a7210942002110200341c8076a22074200370300200341c0076a22024200370300200341b0076a41086a22114200370300200342003703b007200341f8046a41c8afc90041131081022011200341f8046a41086a2212290000370300200320032900f8043703b007200341f8046a41c7c3cb00410710810220072012290000370300200220032900f804370300200341c8026a200341b0076a1088030240024020032802c80222070d00410021110c010b20032902cc02220a4220882210a72111200a42ffffff3f83500d002007102e0b0240024020012009490d00200341b0076a200341a8026a2008200b10f70720032d00b407210220032802b0072108200341f8046a200341b0076a41057241b30210e9081a41012107024020084101460d00200341e8096a350200210a200341c8026a200341fb046a41b00210e9081a200341bd076a200341a8026a41086a2202290300370000200341c5076a200341a8026a41106a2207290300370000200341cd076a200341a8026a41186a2208290300370000200341dc076a200c360200200341d8076a2001360200200341063a00b4072003410a3a00b007200320032903a8023700b507200341b0076a10fe0120034194056a200c360200200341f8046a41186a2005360200200341f8046a41106a200136020020034184056a20063602002003200f360298052003200e36028c0520032004360280052003200d3703f804200341f0096a41186a2008290300370300200341f0096a41106a2007290300370300200341f0096a41086a2002290300370300200320032903a8023703f009200341b0076a200341c8026a41b00210e9081a200341386a2011200341f8046a200341f0096a200341b0076a10f807427f200a42b8177e201042b0c60d7e7c200335024042b09c1b7e7c42e0c3b9dc017c220a20032903387c220b200b200a541b210b0c020b200320032900f804370388022003200341ff046a28000036008f020c0a0b4100210741002011200c6b2212201220114b1b2009490d074200210a200341b0076a41186a4200370300200341b0076a41106a4200370300200341b0076a41086a22074200370300200342003703b007200341f8046a41d9fcc60041061081022007200341f8046a41086a2212290000370300200320032900f8043703b007200341f8046a4180f4cb004106108102200241086a2012290000370000200220032900f804370000200341306a200341b0076a4120108e0202402003280234410020032802301b200f4f0d00200341b0076a410710f307200320032900b107370388022003200728000036008f0220032d00b007210241012107410021010c0b0b200341f0096a41186a22024200370300200341f0096a41106a22074200370300200341f0096a41086a22144200370300200342003703f00920034198016a41c8afc9004113108102201420034198016a41086a221329000037030020032003290098013703f00920034198016a41dbc3cb004105108102200220132900003703002007200329009801370300200341b0076a200341f0096a412010f40220032d00b0072102200341f8046a41186a200341c9076a290000370300200341f8046a41106a200341c1076a2900003703002012200341b9076a290000370300200320032900b1073703f8040240024020024101460d00410221020c010b200341c8026a41186a200341f8046a41186a290300220a370300200341c8026a41106a200341f8046a41106a2903002217370300200341c8026a41086a200341f8046a41086a2903002218370300200320032903f80422193703c802200341b0076a41186a200a370300200341b0076a41106a2017370300200341b0076a41086a2018370300200320193703b00720014105742102200421070340024020020d00410021020c020b200241606a21022007200341b0076a412010ec082112200741206a210720120d000b410121020b41002107410020112001200c6a6b2212200220024102477122021b200c6a21142012410020021b20016a22122009490d04200341b0076a200341a8026a2008200b10f70720032d00b407210220032802b0072108200341f8046a200341b0076a41057241b30210e9081a4101210720084101460d05200341e8096a350200210a200341c8026a200341fb046a41b00210e9081a200341bd076a200341a8026a41086a2202290300370000200341c5076a200341a8026a41106a2207290300370000200341cd076a200341a8026a41186a2208290300370000200341dc076a2014360200200341d8076a2012360200200341063a00b4072003410a3a00b007200320032903a8023700b507200341b0076a10fe0120034194056a200c360200200341f8046a41186a2005360200200341f8046a41106a200136020020034184056a20063602002003200f360298052003200e36028c0520032004360280052003200d3703f804200341f0096a41186a2008290300370300200341f0096a41106a2007290300370300200341f0096a41086a2002290300370300200320032903a8023703f009200341b0076a200341c8026a41b00210e9081a200341206a2011200341f8046a200341f0096a200341b0076a10f807427f200a42b8177e201042e0b60d7e7c20033502284280ac1b7e7c42e0fdcfea017c220a20032903207c220b200b200a541b210b0b4201210a410021010c0b0b200341c8026a41186a2207200141196a290000370300200341c8026a41106a2205200141116a290000370300200341c8026a41086a2206200141096a290000370300200320012900013703c802200341b0076a41286a200241286a280200360200200341b0076a41206a200241206a290200370300200341b0076a41186a2201200241186a290200370300200341b0076a41106a2208200241106a290200370300200341b0076a41086a2209200241086a290200370300200320022902003703b00702400240200341b0076a10a705450d00200320032800a80236028802200320032900f0093703b0072003200341ab026a28000036008b022003200341f7096a2800003600b707200041186a41003a00002000420037030820002003280288023600192000411c6a200328008b02360000200041206a41023a0000200020032903b007370021200041286a20032800b7073600004201210a0c010b200341f8046a41186a22022007290300220a370300200341f8046a41106a22072005290300220b370300200341f8046a41086a22052006290300220d370300200320032903c80222103703f804200341bd076a200d370000200341c5076a200b370000200341cd076a200a3700002003410a3a00b007200320103700b507200341033a00b407200341b0076a10fe01200120022903003703002008200729030037030020092005290300370300200320032903f8043703b007200341b0076a10f9072101200320032800a802360288022003200341a8026a41036a28000036008b02200041186a41003a0000200041106a2001ad42d0be1a7e42d0deb8a7017c3703002000420137030820002003280288023600192000411c6a200328008b023600004200210a0b2000200a3703000c190b200341b0076a410510f307200320032900b107370388022003200341b8076a28000036008f020c0a0b2007200e1042000b200341dc076a2014360200200341d8076a2012360200200341bd076a2201200341a8026a41086a2202290300370000200341c5076a2208200341a8026a41106a2209290300370000200341cd076a220c200341a8026a41186a220f290300370000200341063a00b4072003410a3a00b007200320032903a8023700b507200341b0076a10fe01200341f8006a41186a2211200f290300220a370300200341f8006a41106a220f2009290300220b370300200341f8006a41086a22092002290300220d370300200320032903a80222173703782001200d3700002008200b370000200c200a370000200341033a00b4072003410a3a00b007200320173700b507200341b0076a10fe01200341b0076a41186a2011290300370300200341b0076a41106a200f290300370300200341b0076a41086a2009290300370300200320032903783703b007201042c8be0d7e200341b0076a10f907ad42a0ce1a7e7c42c8b9d4d5017c210b0c030b200320032900f804370388022003200341ff046a28000036008f020c030b410221010c130b200341dc076a200c360200200341d8076a2001360200200341bd076a2201200341a8026a41086a2202290300370000200341c5076a2208200341a8026a41106a2209290300370000200341cd076a220c200341a8026a41186a220f290300370000200341063a00b4072003410a3a00b007200320032903a8023700b507200341b0076a10fe01200341f8046a41186a2211200f290300220a370300200341f8046a41106a220f2009290300220b370300200341f8046a41086a22092002290300220d370300200320032903a80222173703f8042001200d3700002008200b370000200c200a370000200341033a00b4072003410a3a00b007200320173700b507200341b0076a10fe01200341b0076a41186a2011290300370300200341b0076a41106a200f290300370300200341b0076a41086a2009290300370300200320032903f8043703b007201042a89f0d7e200341b0076a10f907ad42e8b61a7e7c42a0adc1c7017c210b0b4201210a410121010c010b4200210a410021010b0240200641ffffff3f71450d002004102e0b0240200541ffffff3f71450d00200e102e0b2007450d010b200320032800f8013602e80120032003290388023703b8012003200328008f023600bf012003200341fb016a2800003600eb01200041186a20013a0000200041106a200b3703002000200a370308200020032802e8013600192000411c6a20032800eb01360000200041206a20023a0000200020032903b801370021200041286a20032800bf01360000200042013703000c0f0b200320032800f8013602e8012003200341fb016a2800003600eb01200041186a20013a0000200041106a200b3703002000200a370308200020032802e8013600192000411c6a20032800eb01360000200042003703000c0e0b20032d00b00721010240201141ffffff3f71450d00200c102e0b201241ffffff3f71450d002014102e0b200a42ffffff3f83500d002008102e0b200320032800b8013602f8012003200329038802370398012003200328008f0236009f012003200341bb016a2800003600fb01200041186a41003a000020004200370308200020032802f8013600192000411c6a20032800fb01360000200041206a20013a00002000200329039801370021200041286a200328009f01360000200042013703000c0b0b200341f0096a41186a2207200341c8026a41186a290300370300200341f0096a41106a2209200341c8026a41106a290300370300200341f0096a41086a2215200341c8026a41086a290300370300200320032903c8023703f009200e2011470d02201141016a22012011490d00201141017422162001201620014b1b22014104200141044b1b220141ffffff3f712001462116200141057421010240024020110d00200341003602b0070c010b200341b8076a41013602002003200c3602b007200320114105743602b4070b200341f8046a20012016200341b0076a107d20034180056a280200210120032802f8044101470d0120010d050b1038000b20032802fc04210c200141057621110b200c200e4105746a220120032903f009370000200141186a2007290300370000200141106a2009290300370000200141086a2015290300370000200e41016a210e2006450d00200f20024d0d012014200f417f6a220f4105746a220129000021102001290008211720012900102118201420024105746a220241186a200141186a2900003700002002201837001020022017370008200220103700000b200341d5076a20032903a802370000200341bd076a200341c8026a41086a290300370000200341c5076a200341c8026a41106a290300370000200341cd076a200341c8026a41186a290300370000200341dd076a200341a8026a41086a290300370000200341e5076a200341a8026a41106a290300370000200341ed076a200341a8026a41186a290300370000200341013a00b4072003410a3a00b007200320032903c8023700b507200341fc076a200f360200200341f8076a200e360200200341f5076a20043a0000200341b0076a10fe01200341cc076a200f360200200341b0076a41186a2012360200200341b0076a41106a200e360200200341bc076a2011360200200320133602d007200320143602c4072003200c3602b8072003200d3703b007200341f8046a200341a8026a10f60720032802f8042201200328028005200341b0076a10be05024020032802fc04450d002001102e0b0240201141ffffff3f71450d00200c102e0b0240201241ffffff3f71450d002014102e0b200b42e8ce127e4280cbd9d7007c210b0240200a42ffffff3f83500d002008102e0b200320032800b8013602f8012003200341bb016a2800003600fb01200041186a20053a0000200041106a200b37030020004201370308200020032802f8013600192000411c6a20032800fb01360000200042003703000c060b2002200f1042000b1036000b20032902b407210a20032802b00721010b200b42ffffff3f83500d002008102e0b2005108b022005102e2003200341e3006a28000036004b20032003280060360248200041186a41003a000020004200370308200020032802483600192000411c6a200328004b360000200041246a200a370200200041206a2001360200200042013703000c010b2005108b022005102e2003200341f4006a28000036005b20032003280071360258200320032903603703482003200328006736004f200041186a41003a000020004200370308200020032802583600192000411c6a200328005b360000200041206a20013a000020002003290348370021200041286a200328004f360000200042013703000b200341a00a6a24000b8b7a040a7f047e067f037e230041a00a6b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0700010203040506000b200341c4076a4101360200200342013702b4072003419cc3cb003602b007200341043602fc0420034194c3cb003602f8042003200341f8046a3602c007200341b0076a41b8afc9001044000b20012d000121042001412c6a2802002105200141286a2802002106200141246a2802002107200341c8026a41186a22082001411a6a290000370300200341c8026a41106a2209200141126a290000370300200341c8026a41086a220a2001410a6a2900003703002003200141026a2900003703c802200341b0076a41286a200241286a280200360200200341b0076a41206a200241206a290200370300200341b0076a41186a2201200241186a290200370300200341b0076a41106a220b200241106a290200370300200341b0076a41086a220c200241086a290200370300200320022902003703b007024002400240200341b0076a10a7050d0020014200370300200b4200370300200c4200370300200342003703b007200341f8046a4181b0c9004113108102200c200341f8046a41086a2202290000370300200320032900f8043703b007200341f8046a41c7c3cb00410710810220012002290000370300200b20032900f804370300200341f8046a200341b0076a10880320032802f804210120032902fc04210d2007200510fc02200720052001410120011b2202200d420020011b220d422088220ea710fc07200341f8006a41186a2008290300370300200341f8006a41106a2009290300370300200341f8006a41086a200a290300370300200320032903c802370378200441ff01710d0120034190056a2201420037030020034188056a220b4200370300200341f8046a41086a220c4200370300200342003703f80420034198016a4181b0c9004113108102200c20034198016a41086a220429000037030020032003290098013703f80420034198016a41dbc3cb00410510810220012004290000370300200b200329009801370300200341f8046a412010ff010c020b0240200641ffffff3f71450d002007102e0b200320032800b8013602f801200320032900a802370388022003200341bb016a2800003600fb012003200341af026a28000036008f02200041186a41003a000020004200370308200020032802f8013600192000411c6a20032800fb01360000200041206a41023a00002000200329038802370021200041286a200328008f02360000200042013703000c200b200341b0076a41186a200341f8006a41186a290300370300200341b0076a41106a200341f8006a41106a290300370300200341b0076a41086a200341f8006a41086a290300370300200320032903783703b007200341f0096a41186a22014200370300200341f0096a41106a220b4200370300200341f0096a41086a220c4200370300200342003703f009200341f8046a4181b0c9004113108102200c200341f8046a41086a2204290000370300200320032900f8043703f009200341f8046a41dbc3cb00410510810220012004290000370300200b20032900f8043703004120102c2201450d1a200342203702fc04200320013602f804200341f8046a200341b0076a41201074200341f0096a412020032802f804220120032802800510b20120032802fc04450d002001102e0b2005ad42b882077e200e42c0b5e5097e7c210e0240200641ffffff3f71450d002007102e0b200e42a0c0b291397c210e0240200d42ffffff3f83500d002002102e0b200320032800b8013602f8012003200341bb016a2800003600fb01200041186a41003a0000200041106a200e37030020004201370308200020032802f8013600192000411c6a20032800fb01360000200042003703000c1e0b200141086a2802002104200141046a2802002105200341b0076a41286a200241286a280200360200200341b0076a41206a200241206a290200370300200341b0076a41186a2201200241186a290200370300200341b0076a41106a2207200241106a290200370300200341b0076a41086a2206200241086a290200370300200320022902003703b007200341f8046a200341b0076a10c102200341f8006a41086a220220034181056a290000370300200341f8006a41106a220b20034189056a290000370300200341f8006a41186a220c20034191056a290000370300200320032900f90437037820032d00f8044101460d0820034198016a41186a200c29030037030020034198016a41106a200b29030037030020034198016a41086a20022903003703002003200329037837039801200142003703002007420037030020064200370300200342003703b007200341f8046a4181b0c90041131081022006200341f8046a41086a2202290000370300200320032900f8043703b007200341f8046a41c7c3cb00410710810220012002290000370300200720032900f804370300200341f8046a200341b0076a10880320032902fc04420020032802f80422021b220d422088220ea741057421012002410120021b22062102024002400240024003402001450d01200141606a2101200220034198016a412010ec082107200241206a210220070d000b200341003602b807200342013703b0072005200341b0076a10900220032802b8072107024020032802b407450d0020032802b007102e0b0240200720044d0d00200341b0076a410a10fd07200320032900b1073703602003200341b8076a2800003600670c020b2003410036028005200342013703f8042005200341f8046a109002200341b0076a20032802f80420032802800510b00120034188026a41186a200341b0076a41186a29030037030020034188026a41106a200341b0076a41106a29030037030020034188026a41086a200341b0076a41086a290300370300200320032903b00737038802024020032802fc04450d0020032802f804102e0b200341f8046a200541b00210e9081a200341a8026a41086a20034198016a41086a290300370300200341a8026a41106a20034198016a41106a290300370300200341a8026a41186a20034198016a41186a29030037030020032003290398013703a8024110102c2202450d1c200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1c20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220b3602000240200b0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220b200b280200417f6a220b360200200b0d002002102e0b024002402001280208200341f8046a200128020c28020c1101000d0041022102200341e8026a41023a0000200341e0026a41003a000020012001280200417f6a220b3602004200210f200342003703d002200342013703c8020240200b0d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a220b200b280200417f6a220b360200200b0d002001102e0b200341f8046a10dc02410121010c010b200341b0076a200341f8046a41b00210e9081a200341fd096a200341b0026a290300370000200341850a6a200341b8026a2903003700002003418d0a6a200341c0026a290300370000200341950a6a20032f00783b0000200341023a00f009200341970a6a200341f8006a41026a2d00003a0000200341013a00f409200320032903a8023700f509200320013602980a200341c8026a200341b0076a200341f0096a10dd0220032903c8024201512101200341e8026a2d0000210220032903d002210f0b200341f8046a41186a20034188026a41186a290300370300200341f8046a41106a20034188026a41106a290300370300200341f8046a41086a20034188026a41086a29030037030020032003290388023703f8042003200341f0026a2800003600b707200320032900e9023703b0070240024020010d00410621010c010b200320032800b7073600ff01200320032903b0073703f80141062101200f4202510d00200320032800ff013600ef01200320032903f8013703e801200221010b200341f0096a41086a2202200341f8046a41086a290300370300200341f0096a41106a220b200341f8046a41106a290300370300200341f0096a41186a220c200341f8046a41186a290300370300200320032903f8043703f009200320032903e8013703d801200320032800ef013600df01200341053a00b4072003410b3a00b007200341bd076a2002290300370000200341c5076a200b290300370000200341cd076a200c290300370000200341d8076a20013a0000200320032903f0093700b507200341d5076a20032f00e5013b0000200341d7076a200341e7016a2d00003a0000200341d9076a20032903d801370000200341e0076a20032800df01360000200341fc076a200341b8016a41186a280200360200200341f4076a200341b8016a41106a290200370200200341ec076a200341b8016a41086a290200370200200341e4076a20032902b801370200200341b0076a10fe01200fa70d024200210e0c030b200341b0076a410110fd07200320032900b1073703602003200341b8076a2800003600670b20032d00b0072101200d42ffffff3f83500d1e2006102e0c1e0b427f2007ad42a01f7e200e4280eb067e7c42d8bbe3167c220e200341c8026a41106a2903007c220f200f200e541b210f4201210e0b0240200d42ffffff3f83500d002006102e0b2005102e2003200341f4006a28000036005b20032003280071360258200041186a41003a0000200041106a200f3703002000200e370308200020032802583600192000411c6a200328005b360000200042003703000c1d0b2001410c6a2802002104200141086a2802002105200141046a2802002108200341b0076a41286a200241286a280200360200200341b0076a41206a200241206a290200370300200341b0076a41186a2201200241186a290200370300200341b0076a41106a2206200241106a290200370300200341b0076a41086a2207200241086a290200370300200320022902003703b007200341f8046a200341b0076a10c102200341c8026a41086a220220034181056a290000370300200341c8026a41106a220b20034189056a290000370300200341c8026a41186a220c20034191056a290000370300200320032900f9043703c80202400240024020032d00f8044101460d0020034188026a41186a200c29030037030020034188026a41106a200b29030037030020034188026a41086a2002290300370300200320032903c80237038802200142003703002006420037030020074200370300200342003703b007200341f8046a4181b0c90041131081022007200341f8046a41086a2202290000370300200320032900f8043703b007200341f8046a41c7c3cb00410710810220012002290000370300200620032900f804370300200341f8046a200341b0076a10880320032902fc04420020032802f80422021b220e422088220da741057421012002410120021b220b210203402001450d02200141606a2101200220034188026a412010ec082107200241206a210220070d000b200341003602b807200342013703b0072005200341b0076a10900220032802b8072101024020032802b407450d0020032802b007102e0b200120044d0d02200341b0076a410a10fd070c1b0b410221010c1c0b200341b0076a410110fd070c190b2003410036028005200342013703f8042005200341f8046a109002200341b0076a20032802f80420032802800510b001200341a8026a41186a2202200341b0076a41186a2207290300370300200341a8026a41106a220c200341b0076a41106a2204290300370300200341a8026a41086a2209200341b0076a41086a220a290300370300200320032903b0073703a802024020032802fc04450d0020032802f804102e0b200720022903003703002004200c290300370300200a2009290300370300200320032903a8023703b007200341f8046a200341b0076a10fe0720032802f8042207200328028005108f022102024020032802fc04450d002007102e0b02402002450d00200341b0076a410210fd070c190b024002400240200841014b0d00200341c8076a4200370300200341c0076a4200370300200341b0076a41086a22024200370300200342003703b007200341f8046a4181b0c90041131081022002200341f8046a41086a2207290000370300200320032900f8043703b007200341f8046a41c7c3cb004107108102200641086a2007290000370000200620032900f804370000200341c8026a200341b0076a1088030240024020032802c80222020d004100210c0c010b20032902cc02220f422088a7210c200f42ffffff3f83500d002002102e0b200341f8046a200541b00210e9081a4110102c2207450d1a200741f8f7c60036020c2007410136020820074281808080103702004110102c2202450d1a20024190f8c60036020c20024101360208200242818080801037020020072007280200417f6a2206360200024020060d002007280208200728020c2802001103000240200728020c280204450d002007280208102e0b200741046a22062006280200417f6a220636020020060d002007102e0b024002402002280208200341f8046a200228020c28020c1101000d0041022107200341e8026a41023a0000200341e0026a41003a000020022002280200417f6a22063602004200210f200342003703d002200342013703c802024020060d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22062006280200417f6a220636020020060d002002102e0b200341f8046a10dc02410121020c010b200341b0076a200341f8046a41b00210e9081a200341fc096a200c360200200341f0096a41086a4101360200200341f0096a41106a200329019801370300200341880a6a20034198016a41086a290100370300200341f0096a41206a20034198016a41106a290100370300200341003a00f409200320032f00783b00f509200320023602980a200341023a00f0092003200341f8006a41026a2d00003a00f709200341c8026a200341b0076a200341f0096a10dd0220032903c8024201512102200341c8026a41206a2d0000210720032903d002210f0b200341f0096a41186a200341a8026a41186a290300370300200341f0096a41106a200341a8026a41106a290300370300200341f0096a41086a200341a8026a41086a290300370300200320032903a8023703f0092003200341f0026a2800003600b707200320032900e9023703b0070240024020020d00410621020c010b200320032800b7073600ff01200320032903b0073703f80141062102200f4202510d00200320032800ff013600ef01200320032903f8013703e801200721020b200341f8006a41086a2207200341f0096a41086a290300370300200341f8006a41106a2206200341f0096a41106a290300370300200341f8006a41186a220c200341f0096a41186a290300370300200320032903f009370378200320032903e8013703d801200320032800ef013600df01200341043a00b4072003410b3a00b007200341bd076a2007290300370000200341c5076a2006290300370000200341cd076a200c290300370000200341d8076a20023a0000200320032903783700b507200341d5076a20032f00e5013b0000200341d7076a200341e7016a2d00003a0000200341d9076a20032903d801370000200341e0076a20032800df01360000200341fc076a200341b8016a41186a280200360200200341f4076a200341b8016a41106a290200370200200341ec076a200341b8016a41086a290200370200200341e4076a20032902b801370200200341b0076a10fe010240200fa70d004200210f0c020b427f2001ad42a01f7e200d42e8dd0d7e7c42d8ce86257c220d200341c8026a41106a2903007c220f200f200d541b210d4201210f0c010b200341b0076a41186a4200370300200341b0076a41106a4200370300200341b0076a41086a22024200370300200342003703b007200341f8046a4181b0c90041131081022002200341f8046a41086a220c290000370300200320032900f8043703b007200341f8046a41dbafc9004109108102200641086a200c290000370000200620032900f804370000200341f8046a200341b0076a4120108d0320032802f804210220032902fc04210f200341f8046a41186a2209200341a8026a41186a290300370300200341f8046a41106a220a200341a8026a41106a290300370300200c200341a8026a41086a290300370300200320032903a8023703f8042002410120021b21070240024002400240200f420020021b220f4220882210a72202200fa7470d00200241016a22042002490d1820024101742211200420042011491b22044104200441044b1b220441ffffff3f712004462111200441057421040240024020020d00200341003602b0070c010b200341b8076a4101360200200320073602b007200320104205863e02b4070b200341c8026a20042011200341b0076a107d200341d0026a280200210420032802c8024101460d0120032802cc022107200f422088a721022004410576ad210f0b200720024105746a220420032903f804370000200441186a2009290300370000200441106a200a290300370000200441086a200c290300370000200241016a220241e4004b0d04200320073602b0072003200f42ffffffff0f832002ad2210422086843702b40720070d0120034190056a2202420037030020034188056a22074200370300200341f8046a41086a220c4200370300200342003703f80420034198016a4181b0c9004113108102200c20034198016a41086a220429000037030020032003290098013703f80420034198016a41dbafc9004109108102200220042900003703002007200329009801370300200341f8046a412010ff010c020b2004450d160c1b0b20034190056a2202420037030020034188056a220c4200370300200341f8046a41086a22044200370300200342003703f80420034198016a4181b0c9004113108102200420034198016a41086a220929000037030020032003290098013703f80420034198016a41dbafc900410910810220022009290000370300200c200329009801370300200341f8046a200341b0076a10e6042007450d00200f42ffffff3f83500d002007102e0b200341f8046a41186a22024200370300200341f8046a41106a22074200370300200341f8046a41086a220c4200370300200342003703f80420034198016a4181b0c9004113108102200c20034198016a41086a220429000037030020032003290098013703f80420034198016a41e4afc900410d108102200220042900003703002007200329009801370300200341186a200341f8046a4120108e02200328021c21092003280218210a2002420037030020074200370300200c4200370300200342003703f80420034198016a4181b0c9004113108102200c200429000037030020032003290098013703f80420034198016a41e4afc900410d108102200220042900003703002007200329009801370300200341106a200341f8046a4120108e0220032802102111200328021421122002420037030020074200370300200c4200370300200342003703f80420034198016a4181b0c9004113108102200c200429000037030020032003290098013703f80420034198016a41e4afc900410d1081022002200429000037030020072003290098013703002003201241016a410120111b3602b007200341f8046a4120200341b0076a410410b201200341b0076a200541b00210e9081a2002200341a8026a41186a2903003703002007200341a8026a41106a290300370300200c200341a8026a41086a290300370300200320032903a8023703f804200341c8026a200341f8046a10fe0720032802c802210220032802d0022107200342013703f8042003410036028005200341b0076a200341f8046a1090022002200720032802f80420032802800510b201024020032802fc04450d0020032802f804102e0b024020032802cc02450d002002102e0b200341b0076a108b02200341b0076a41186a4200370300200341b0076a41106a4200370300200341b0076a41086a22024200370300200342003703b007200341f8046a41d9fcc60041061081022002200341f8046a41086a2207290000370300200320032900f8043703b007200341f8046a4180f4cb004106108102200641086a2007290000370000200620032900f804370000200341086a200341b0076a4120108e02200328020c21062003280208210c4120102c2202450d192002200329038802370000200241186a20034188026a41186a290300370000200241106a20034188026a41106a290300370000200241086a20034188026a41086a290300370000200341cc076a4100360200200341bc076a4281808080103702002003200641c093066a41c09306200c1b3602d0074201210f200342013702c407200320023602b807200320083602b407200320094100200a1b22063602b007200341f8046a41186a200341a8026a41186a290300370300200341f8046a41106a200341a8026a41106a2903003703002007200341a8026a41086a290300370300200320032903a8023703f804200341c8026a200341f8046a10ff0720032802c802220720032802d002200341b0076a10be05024020032802cc02450d002007102e0b2002102e200341bd076a20034188026a41086a290300370000200341c5076a20034188026a41106a290300370000200341cd076a20034188026a41186a290300370000200341d5076a20032903a802370000200341dd076a200341a8026a41086a290300370000200341e5076a200341a8026a41106a290300370000200341ed076a200341a8026a41186a290300370000200341fc076a2008360200200341f8076a2006360200200341003a00b4072003410b3a00b00720032003290388023700b5072001ad4288277e200d42a08a077e7c201042f8fe1c7e7c42a0c28084027c210d200341b0076a10fe010b0240200e42ffffff3f83500d00200b102e0b2005102e2003200341e3006a28000036004b20032003280060360248200041186a41003a0000200041106a200d3703002000200f370308200020032802483600192000411c6a200328004b360000200042003703000c1d0b200341b0076a410810fd0720032902b407210d20032802b0072101200f42ffffff3f83500d192007102e0c190b200141216a2d00002104200141246a280200210c200341a8026a41186a200141196a290000370300200341a8026a41106a200141116a290000370300200341a8026a41086a200141096a290000370300200320012900013703a802200341b0076a41286a200241286a280200360200200341b0076a41206a200241206a290200370300200341b0076a41186a2201200241186a290200370300200341b0076a41106a2207200241106a290200370300200341b0076a41086a2205200241086a290200370300200320022902003703b007200341f8046a200341b0076a10c102200341f8006a41086a2202200341f8046a41096a290000370300200341f8006a41106a2206200341f8046a41116a290000370300200341f8006a41186a220b200341f8046a41196a290000370300200320032900f904370378024002400240024020032d00f8044101460d00200341c8026a41186a200b290300370300200341c8026a41106a2006290300370300200341c8026a41086a2002290300370300200320032903783703c802200142003703002007420037030020054200370300200342003703b007200341f8046a4181b0c90041131081022005200341f8046a41086a2202290000370300200320032900f8043703b007200341f8046a41c7c3cb00410710810220012002290000370300200720032900f804370300200341f8046a200341b0076a10880320032902fc04420020032802f80422021b220d422088220ea741057421012002410120021b220b210203402001450d02200141606a21012002200341c8026a412010ec082107200241206a210220070d000b200341f8046a200341a8026a108008200341b0076a20032802f804220220032802800510b30520032802fc04210120032802b8072208450d02200341d0076a2802002113200341cc076a280200210a200341c8076a2802002112200341c4076a2802002114200341c0076a280200210920032802bc07211120032903b007210f02402001450d002002102e0b200c200fa7460d03200341b0076a410410fd07200320032900b107370388022003200341b8076a28000036008f020c110b410221010c120b200341b0076a410110fd07200320032900b107370388022003200341b8076a28000036008f0220032d00b00721010c100b02402001450d002002102e0b200341b0076a410310fd07200320032900b107370388022003200341b8076a28000036008f0220032d00b00721010c0f0b410021020240024020090d0041012106410021074100210c0c010b200941057441606a41057641016a21054100210720082101034002402001200341c8026a412010ec080d00410021064101210c0c020b200141206a2101410121062005200741016a2207470d000b4100210c200521070b02400240024002400240200a450d00200a41057441606a41057641016a2105410021022014210103402001200341c8026a412010ec08450d02200141206a21012005200241016a2202470d000b200521020b200c450d01200441ff01710d03410021050c020b200441ff0171450d052006450d0241002105410121060c130b4100210641012105200441ff01710d120b200341f8046a41186a2202200341c8026a41186a290300370300200341f8046a41106a2206200341c8026a41106a290300370300200341f8046a41086a2215200341c8026a41086a290300370300200320032903c8023703f8040240200a2012470d00201241016a22012012490d13201241017422162001201620014b1b22014104200141044b1b220141ffffff3f712001462116200141057421010240024020120d00200341003602b0070c010b200341b8076a4101360200200320143602b007200320124105743602b4070b200341f0096a20012016200341b0076a107d200341f8096a2802002101024020032802f0094101470d0020010d190c140b20032802f4092114200141057621120b2014200a4105746a220120032903f804370000200141186a2002290300370000200141106a2006290300370000200141086a2015290300370000200a41016a210a200c450d15200920074d0d0420082009417f6a22094105746a220129000021102001290008211720012900102118200820074105746a220241186a200141186a2900003700002002201837001020022017370008200220103700000c150b200341b0076a410510fd07200320032900b107370388022003200341b8076a28000036008f020c0d0b200141286a280200210b200141306a290300210e200141246a2802002107200341a8026a41186a200141196a290000370300200341a8026a41106a200141116a290000370300200341a8026a41086a200141096a290000370300200320012900013703a802200341b0076a41286a200241286a280200360200200341b0076a41206a2201200241206a290200370300200341b0076a41186a2205200241186a290200370300200341b0076a41106a2206200241106a290200370300200341b0076a41086a200241086a290200370300200320022902003703b007200341f8046a200341b0076a10c10202400240024020032d00f8044101460d00200341f8046a200341a8026a108008200341b0076a20032802f804220c20032802800510b30520032802fc042102024020032802b8072204450d002001280200210a200341cc076a280200210820052802002105200341c4076a28020021092006280200210120032802bc07210620032903b007210f02402002450d00200c102e0b2007200fa7460d03200341b0076a410410fd07200320032900b107370388022003200341b8076a28000036008f0220032d00b0072102410121070c0c0b02402002450d00200c102e0b200341b0076a410310fd07200320032900b107370388022003200341b8076a28000036008f0220032d00b00721020c010b410221020b4200210d410021010c0b0b200f422088a7210c42002110200341c8076a22074200370300200341c0076a22024200370300200341b0076a41086a22114200370300200342003703b007200341f8046a4181b0c90041131081022011200341f8046a41086a2212290000370300200320032900f8043703b007200341f8046a41c7c3cb00410710810220072012290000370300200220032900f804370300200341c8026a200341b0076a1088030240024020032802c80222070d00410021110c010b20032902cc02220d4220882210a72111200d42ffffff3f83500d002007102e0b024002402001200c490d00200341b0076a200341a8026a200b200e10810820032d00b407210220032802b007210b200341f8046a200341b0076a41057241b30210e9081a410121070240200b4101460d00200341e8096a350200210d200341c8026a200341fb046a41b00210e9081a200341bd076a200341a8026a41086a2202290300370000200341c5076a200341a8026a41106a2207290300370000200341cd076a200341a8026a41186a220b290300370000200341dc076a2008360200200341d8076a2001360200200341063a00b4072003410b3a00b007200320032903a8023700b507200341b0076a10fe0120034194056a2008360200200341f8046a41186a2005360200200341f8046a41106a200136020020034184056a20063602002003200a360298052003200936028c0520032004360280052003200f3703f804200341f0096a41186a200b290300370300200341f0096a41106a2007290300370300200341f0096a41086a2002290300370300200320032903a8023703f009200341b0076a200341c8026a41b00210e9081a200341386a2011200341f8046a200341f0096a200341b0076a108208427f200d42b8177e201042b0c60d7e7c200335024042b09c1b7e7c42e0c3b9dc017c220d20032903387c220e200e200d541b210e0c020b200320032900f804370388022003200341ff046a28000036008f020c0a0b410021074100201120086b2212201220114b1b200c490d074200210d200341b0076a41186a4200370300200341b0076a41106a4200370300200341b0076a41086a22074200370300200342003703b007200341f8046a41d9fcc60041061081022007200341f8046a41086a2212290000370300200320032900f8043703b007200341f8046a4180f4cb004106108102200241086a2012290000370000200220032900f804370000200341306a200341b0076a4120108e0202402003280234410020032802301b200a4f0d00200341b0076a410710fd07200320032900b107370388022003200728000036008f0220032d00b007210241012107410021010c0b0b200341f0096a41186a22024200370300200341f0096a41106a22074200370300200341f0096a41086a22144200370300200342003703f00920034198016a4181b0c9004113108102201420034198016a41086a221329000037030020032003290098013703f00920034198016a41dbc3cb004105108102200220132900003703002007200329009801370300200341b0076a200341f0096a412010f40220032d00b0072102200341f8046a41186a200341c9076a290000370300200341f8046a41106a200341c1076a2900003703002012200341b9076a290000370300200320032900b1073703f8040240024020024101460d00410221020c010b200341c8026a41186a200341f8046a41186a290300220d370300200341c8026a41106a200341f8046a41106a2903002217370300200341c8026a41086a200341f8046a41086a2903002218370300200320032903f80422193703c802200341b0076a41186a200d370300200341b0076a41106a2017370300200341b0076a41086a2018370300200320193703b00720014105742102200421070340024020020d00410021020c020b200241606a21022007200341b0076a412010ec082112200741206a210720120d000b410121020b4100210741002011200120086a6b2212200220024102477122021b20086a21142012410020021b20016a2212200c490d04200341b0076a200341a8026a200b200e10810820032d00b407210220032802b007210b200341f8046a200341b0076a41057241b30210e9081a41012107200b4101460d05200341e8096a350200210d200341c8026a200341fb046a41b00210e9081a200341bd076a200341a8026a41086a2202290300370000200341c5076a200341a8026a41106a2207290300370000200341cd076a200341a8026a41186a220b290300370000200341dc076a2014360200200341d8076a2012360200200341063a00b4072003410b3a00b007200320032903a8023700b507200341b0076a10fe0120034194056a2008360200200341f8046a41186a2005360200200341f8046a41106a200136020020034184056a20063602002003200a360298052003200936028c0520032004360280052003200f3703f804200341f0096a41186a200b290300370300200341f0096a41106a2007290300370300200341f0096a41086a2002290300370300200320032903a8023703f009200341b0076a200341c8026a41b00210e9081a200341206a2011200341f8046a200341f0096a200341b0076a108208427f200d42b8177e201042e0b60d7e7c20033502284280ac1b7e7c42e0fdcfea017c220d20032903207c220e200e200d541b210e0b4201210d410021010c0b0b200341c8026a41186a2207200141196a290000370300200341c8026a41106a2205200141116a290000370300200341c8026a41086a2206200141096a290000370300200320012900013703c802200341b0076a41286a200241286a280200360200200341b0076a41206a200241206a290200370300200341b0076a41186a2201200241186a290200370300200341b0076a41106a220b200241106a290200370300200341b0076a41086a220c200241086a290200370300200320022902003703b00702400240200341b0076a10a705450d00200320032800a80236028802200320032900f0093703b0072003200341ab026a28000036008b022003200341f7096a2800003600b707200041186a41003a00002000420037030820002003280288023600192000411c6a200328008b02360000200041206a41023a0000200020032903b007370021200041286a20032800b7073600004201210d0c010b200341f8046a41186a22022007290300220d370300200341f8046a41106a22072005290300220e370300200341f8046a41086a22052006290300220f370300200320032903c80222103703f804200341bd076a200f370000200341c5076a200e370000200341cd076a200d3700002003410b3a00b007200320103700b507200341033a00b407200341b0076a10fe0120012002290300370300200b2007290300370300200c2005290300370300200320032903f8043703b007200341b0076a1083082101200320032800a802360288022003200341a8026a41036a28000036008b02200041186a41003a0000200041106a2001ad42d0be1a7e42d0deb8a7017c3703002000420137030820002003280288023600192000411c6a200328008b023600004200210d0b2000200d3703000c190b200341b0076a410510fd07200320032900b107370388022003200341b8076a28000036008f020c0a0b200720091042000b200341dc076a2014360200200341d8076a2012360200200341bd076a2201200341a8026a41086a2202290300370000200341c5076a220b200341a8026a41106a220c290300370000200341cd076a2208200341a8026a41186a220a290300370000200341063a00b4072003410b3a00b007200320032903a8023700b507200341b0076a10fe01200341f8006a41186a2211200a290300220d370300200341f8006a41106a220a200c290300220e370300200341f8006a41086a220c2002290300220f370300200320032903a80222173703782001200f370000200b200e3700002008200d370000200341033a00b4072003410b3a00b007200320173700b507200341b0076a10fe01200341b0076a41186a2011290300370300200341b0076a41106a200a290300370300200341b0076a41086a200c290300370300200320032903783703b007201042c8be0d7e200341b0076a108308ad42a0ce1a7e7c42c8b9d4d5017c210e0c030b200320032900f804370388022003200341ff046a28000036008f020c030b410221010c130b200341dc076a2008360200200341d8076a2001360200200341bd076a2201200341a8026a41086a2202290300370000200341c5076a220b200341a8026a41106a220c290300370000200341cd076a2208200341a8026a41186a220a290300370000200341063a00b4072003410b3a00b007200320032903a8023700b507200341b0076a10fe01200341f8046a41186a2211200a290300220d370300200341f8046a41106a220a200c290300220e370300200341f8046a41086a220c2002290300220f370300200320032903a80222173703f8042001200f370000200b200e3700002008200d370000200341033a00b4072003410b3a00b007200320173700b507200341b0076a10fe01200341b0076a41186a2011290300370300200341b0076a41106a200a290300370300200341b0076a41086a200c290300370300200320032903f8043703b007201042a89f0d7e200341b0076a108308ad42e8b61a7e7c42a0adc1c7017c210e0b4201210d410121010c010b4200210d410021010b0240200641ffffff3f71450d002004102e0b0240200541ffffff3f71450d002009102e0b2007450d010b200320032800f8013602e80120032003290388023703b8012003200328008f023600bf012003200341fb016a2800003600eb01200041186a20013a0000200041106a200e3703002000200d370308200020032802e8013600192000411c6a20032800eb01360000200041206a20023a0000200020032903b801370021200041286a20032800bf01360000200042013703000c0f0b200320032800f8013602e8012003200341fb016a2800003600eb01200041186a20013a0000200041106a200e3703002000200d370308200020032802e8013600192000411c6a20032800eb01360000200042003703000c0e0b20032d00b00721010240201141ffffff3f71450d002008102e0b201241ffffff3f71450d002014102e0b200d42ffffff3f83500d00200b102e0b200320032800b8013602f8012003200329038802370398012003200328008f0236009f012003200341bb016a2800003600fb01200041186a41003a000020004200370308200020032802f8013600192000411c6a20032800fb01360000200041206a20013a00002000200329039801370021200041286a200328009f01360000200042013703000c0b0b200341f0096a41186a2207200341c8026a41186a290300370300200341f0096a41106a220c200341c8026a41106a290300370300200341f0096a41086a2215200341c8026a41086a290300370300200320032903c8023703f00920092011470d02201141016a22012011490d00201141017422162001201620014b1b22014104200141044b1b220141ffffff3f712001462116200141057421010240024020110d00200341003602b0070c010b200341b8076a4101360200200320083602b007200320114105743602b4070b200341f8046a20012016200341b0076a107d20034180056a280200210120032802f8044101470d0120010d050b1038000b20032802fc042108200141057621110b200820094105746a220120032903f009370000200141186a2007290300370000200141106a200c290300370000200141086a2015290300370000200941016a21092006450d00200a20024d0d012014200a417f6a220a4105746a220129000021102001290008211720012900102118201420024105746a220241186a200141186a2900003700002002201837001020022017370008200220103700000b200341d5076a20032903a802370000200341bd076a200341c8026a41086a290300370000200341c5076a200341c8026a41106a290300370000200341cd076a200341c8026a41186a290300370000200341dd076a200341a8026a41086a290300370000200341e5076a200341a8026a41106a290300370000200341ed076a200341a8026a41186a290300370000200341013a00b4072003410b3a00b007200320032903c8023700b507200341fc076a200a360200200341f8076a2009360200200341f5076a20043a0000200341b0076a10fe01200341cc076a200a360200200341b0076a41186a2012360200200341b0076a41106a2009360200200341bc076a2011360200200320133602d007200320143602c407200320083602b8072003200f3703b007200341f8046a200341a8026a10800820032802f8042201200328028005200341b0076a10be05024020032802fc04450d002001102e0b0240201141ffffff3f71450d002008102e0b0240201241ffffff3f71450d002014102e0b200e42e8ce127e4280cbd9d7007c210e0240200d42ffffff3f83500d00200b102e0b200320032800b8013602f8012003200341bb016a2800003600fb01200041186a20053a0000200041106a200e37030020004201370308200020032802f8013600192000411c6a20032800fb01360000200042003703000c060b2002200a1042000b1036000b20032902b407210d20032802b00721010b200e42ffffff3f83500d00200b102e0b2005108b022005102e2003200341e3006a28000036004b20032003280060360248200041186a41003a000020004200370308200020032802483600192000411c6a200328004b360000200041246a200d370200200041206a2001360200200042013703000c010b2005108b022005102e2003200341f4006a28000036005b20032003280071360258200320032903603703482003200328006736004f200041186a41003a000020004200370308200020032802583600192000411c6a200328005b360000200041206a20013a000020002003290348370021200041286a200328004f360000200042013703000b200341a00a6a24000bec7b06017f017e147f057e1a7f017e23004190076b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0700010203040507000b2003419c056a41013602002003420137028c052003419cc3cb0036028805200341043602840420034194c3cb0036028004200320034180046a3602980520034188056a41d4cec8001044000b200341c0016a41086a2001412c6a2802003602002003200141246a2902003703c001200341d0036a41186a200141196a290000370300200341d0036a41106a200141116a290000370300200341d0036a41086a200141096a290000370300200320012900013703d0032002411a6a2901002104200241196a2d00002105200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620022d0001211720022d00002101200228022822022002280200417f6a2218360200024002400240024020010d00024020180d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b201741ff01714101470d01200320043703f801200320053a00f701200320063a00f601200320073b01f401200320083a00f301200320093a00f2012003200a3b01f0012003200b3a00ef012003200c3a00ee012003200d3b01ec012003200e3a00eb012003200f3a00ea01200320103b01e801200320113a00e701200320123a00e601200320133b01e401200320143a00e301200320153a00e201200320163b01e00120032802c8012202418080014d0d02200341f0036a41011098070c030b20180d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b200341023a00f0030c010b20034190066a20032802c0012217200210b001200341d8026a41186a20034190066a41186a290300370300200341d8026a41106a20034190066a41106a290300370300200341d8026a41086a20034190066a41086a29030037030020032003290390063703d80220034188056a200341d8026a1099072003280288052218200328029005108f0221010240200328028c05450d002018102e0b02402001450d00200341f0036a41021098070c010b2003200341d0036a36028c052003200341d8026a3602880520034180046a20034188056a108f0520034188056a20034180046a109a072003280288052218200328029005108f0221010240200328028c05450d002018102e0b02402001450d00200341f0036a41021098070c010b200341086a2002ad42004280c2d72f420010e80820034188056a200341e0016a200329030822194280c8afa0257c2204200341086a41086a2903002004201954ad7c221910c302200320032900890537039006200320034188056a41086a28000036009706024020032d00880522024106470d0020034188056a200341d8026a1099072003280288052202200328029005200341c0016a10c3050240200328028c05450d002002102e0b200341a8056a4100360200200341b4056a200341d8026a41086a290300370200200341bc056a200341d8026a41106a290300370200200341c4056a200341d8026a41186a290300370200200341d4056a200341d0036a41086a290300370200200341dc056a200341d0036a41106a290300370200200341e4056a200341d0036a41186a29030037020020032019370390052003200437038805200342083703a0052003410036029805200320032903d8023702ac05200320032903d0033702cc0520034184066a200341e0016a41186a290300370200200341fc056a200341e0016a41106a290300370200200341f4056a200341e0016a41086a290300370200200341013a008c06200320032903e0013702ec0520034190066a20034180046a109a07200328029006220220032802980620034188056a10bb050240200328029406450d002002102e0b20034188056a41086a41003a000020034191056a20032903800437000020034199056a20034180046a41086a290300370000200341a1056a20034180046a41106a290300370000200341a9056a20034180046a41186a290300370000200341163a00880520034188056a10fe01200341063a00f00320032802c401450d182017102e0c180b200341f0036a41086a200328009706360000200320023a00f00320032003290390063700f1030b024020032802c401450d0020032802c001102e0b20032d00f0034106460d1620032802f0032102200020032902f403370024200041206a2002360000200041186a41003a000020004200370308200042013703000c170b200341c0016a41186a200141196a290000370300200341c0016a41106a200141116a290000370300200341c0016a41086a200141096a290000370300200320012900013703c0012002411a6a2901002104200241196a2d00002105200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620022d0001211720022d00002101200228022822022002280200417f6a2218360200024002400240024020010d00024020180d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b201741ff01714101470d01200320043703e803200320053a00e703200320063a00e603200320073b01e403200320083a00e303200320093a00e2032003200a3b01e0032003200b3a00df032003200c3a00de032003200d3b01dc032003200e3a00db032003200f3a00da03200320103b01d803200320113a00d703200320123a00d603200320133b01d403200320143a00d303200320153a00d203200320163b01d003200341f0036a200341c0016a109a0720034188056a20032802f003220120032802f80310b40520034190056a29030021042003290388052119200328029805210220034190066a2003419c056a41f40010e9081a20024102460d02200341d8026a20034190066a41f40010e9081a024020032802f403450d002001102e0b200341e0016a200341d8026a41f40010e9081a20032004370388042003201937038004200320023602900420034194046a200341e0016a41f40010e9081a200341e4046a200341d0036a412010ec08450d03200341b0016a41041098072003419c046a2802002202450d16200241306c450d16200328029804102e0c160b20180d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b200341023a00b0010c150b024020032802f403450d002001102e0b200341b0016a41031098070c130b20034188056a200341a4046a109907200328028805220220032802900510ff010240200328028c05450d002002102e0b20034188056a200341c0016a109a07200328028805220220032802900510ff010240200328028c05450d002002102e0b02402019200484500d00200341186a200341d0036a2019200410fb010b20034188056a41086a41033a000020034191056a20032903c00137000020034199056a200341c0016a41086a290300370000200341a1056a200341d0016a290300370000200341a9056a200341d8016a290300370000200341163a00880520034188056a10fe0102402003419c046a2802002202450d00200241306c450d00200328029804102e0b200341063a00b0010c140b200141386a2903002119200141306a290300211a200341c0016a41086a2001412c6a2802003602002003200141246a2902003703c001200341d0036a41186a200141196a290000370300200341d0036a41106a200141116a290000370300200341d0036a41086a200141096a290000370300200320012900013703d0032002411a6a2901002104200241196a2d00002105200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620022d0001211720022d00002101200228022822022002280200417f6a221836020002400240024020010d00024020180d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b201741ff01714101470d01200320043703f801200320053a00f701200320063a00f601200320073b01f401200320083a00f301200320093a00f2012003200a3b01f0012003200b3a00ef012003200c3a00ee012003200d3b01ec012003200e3a00eb012003200f3a00ea01200320103b01e801200320113a00e701200320123a00e601200320133b01e401200320143a00e301200320153a00e201200320163b01e001200341e0016a10c3030d02200341023a00f0030c120b20180d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b200341023a00f0030c100b20034190066a20032802c00120032802c80110b001200341d8026a41186a20034190066a41186a290300370300200341d8026a41106a20034190066a41106a290300370300200341d8026a41086a20034190066a41086a29030037030020032003290390063703d80220034188056a200341d8026a1099072003280288052201200328029005108f0221020240200328028c05450d002001102e0b02402002450d00200341f0036a41021098070c100b2003200341d0036a36028c052003200341d8026a3602880520034180046a20034188056a108f0520034188056a200341d8026a1099072003280288052202200328029005200341c0016a10c3050240200328028c05450d002002102e0b2003290380042104200329038804211b200329039004211c200341a9056a200329039804370000200341a1056a201c37000020034199056a201b37000020034191056a200437000020034188056a41086a220141003a0000200341163a00880520034188056a10fe014130102c2202450d0d2002201a370320200220032903e001370100200241286a2019370300200241186a200341e0016a41186a2218290300370100200241106a200341e0016a41106a2217290300370100200241086a200341e0016a41086a220529030037010020034188056a41106a410036020020014200370300200341a4056a428180808010370200200341b4056a200341d8026a41086a290300370200200341bc056a200341d8026a41106a290300370200200341c4056a200341d8026a41186a2903003702002003420037038805200320023602a005200320032903d8023702ac05200341d4056a200341d0036a41086a290300370200200341dc056a200341d0036a41106a290300370200200341e4056a200341d0036a41186a290300370200200320032903d0033702cc0520034184066a2018290300370200200341fc056a2017290300370200200341f4056a2005290300370200200320032903e0013702ec05200341003a008c0620034190066a20034180046a109a07200328029006220120032802980620034188056a10bb050240200328029406450d002001102e0b2002102e200341063a00f00320032802c401450d1020032802c001102e0c100b200141306a2903002119200141286a290300211a200341c0016a41186a200141196a290000370300200341c0016a41106a200141116a290000370300200341c0016a41086a200141096a290000370300200320012900013703c0012002411a6a2901002104200241196a2d00002105200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620022d0001211720022d00002101200228022822022002280200417f6a2218360200024002400240024002400240024002400240024020010d00024020180d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b201741ff01714101470d01200320043703e803200320053a00e703200320063a00e603200320073b01e403200320083a00e303200320093a00e2032003200a3b01e0032003200b3a00df032003200c3a00de032003200d3b01dc032003200e3a00db032003200f3a00da03200320103b01d803200320113a00d703200320123a00d603200320133b01d403200320143a00d303200320153a00d203200320163b01d003200341d0036a10c303450d0120034190066a41186a200341c0016a41186a29030037030020034190066a41106a200341c0016a41106a29030037030020034190066a41086a200341c0016a41086a290300370300200320032903c00137039006200341f0036a20034190066a109b0720034188056a20032802f003220120032802f80310b40520034188056a41086a2903002104200329038805211b200328029805210220034190066a2003419c056a41f40010e9081a20024102460d02200341d8026a20034190066a41f40010e9081a024020032802f403450d002001102e0b200341e0016a200341d8026a41f40010e9081a20032004370388042003201b37038004200320023602900420034194046a200341e0016a41f40010e9081a200341d8026a41186a2201200341d0036a41186a290300370300200341d8026a41106a2218200341d0036a41106a290300370300200341d8026a41086a2217200341d0036a41086a290300370300200320032903d0033703d80241002102200328029804210520034180046a41206a28020022060e020504030b20180d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b200341023a00b0010c150b024020032802f403450d002001102e0b200341b0016a410310980720032d00b0014106460d0620032902b40121040c140b410021022006210103402001410176221720026a2118201820022005201841306c6a200341d8026a412010ec084101481b2102200120176b220141014b0d000b0b2005200241306c6a2201200341d8026a412010ec082218450d0220034188056a41186a200341d8026a41186a29030037030020034188056a41106a200341d8026a41106a29030037030020034188056a41086a200341d8026a41086a290300370300200320032903d8023703880520034188056a2101200620022018411f766a22184f0d01201820061045000b20034188056a41186a200129030037030020034188056a41106a201829030037030020034188056a41086a2017290300370300200320032903d802370388054100211820034188056a21010b0240024020062003419c046a280200470d00200641016a22022006490d10200641017422172002201720024b1b22024104200241044b1bad42307e2204422088a74541037421022004a721170240024020060d0020034100360290060c010b20034190066a41086a410836020020032005360290062003200641306c360294060b200341e0016a2017200220034190066a107d200341e8016a280200210220032802e0014101460d01200320032802e4012205360298042003200241306e36029c040b2005201841306c6a220241306a2002200620186b41306c10ea081a200141086a2903002104200141106a290300211b200141186a290300211c2001290300211d200241286a20193703002002201a370320200241186a201c370300200241106a201b370300200241086a20043703002002201d3703002003200641016a3602a0040c020b2002450d0e0c0f0b200620024d0d0320032901da02210420032901e202211b20032801ea02211820032f01ee02211720032903f002211c200120032f01d8023b01002005200241306c6a2202201a3703202002201c370318200220173b0116200220183601122002201b37010a20022004370102200241286a20193703000b20034180046a41186a2117200341a8066a2201420037030020034190066a41106a2202420037030020034190066a41086a221842003703002003420037039006200341e0016a418ef9c00041101081022018200341e0016a41086a2205290000370300200320032900e00137039006200341e0016a41c7c3cb00410710810220012005290000370300200220032900e00137030020034188056a20034190066a10f102200329028c05210420032003280288052201410820011b221836029005200320183602880520032004420020011b22043e028c05200320182004422088a74106746a3602940520034190066a20034188056a10c00120032003280290062201360288052003200120032802980622184105746a36028c050240024020180d00410021180c010b2003200141206a36028805200121180b200320183602e0012017200341e0016a20034188056a10bb01024020032802940641ffffff3f71450d002001102e0b200341a8066a420037030020034190066a41106a420037030020034190066a41086a220142003703002003420037039006200341e0016a418ef9c00041101081022001200341e0016a41086a2218290000370300200320032900e00137039006200341e0016a41c7c3cb004107108102200241086a2018290000370000200220032900e00137000020034188056a20034190066a10f102200329028c05210420032003280288052201410820011b221836029005200320183602880520032004420020011b22043e028c05200320182004422088a74106746a3602940520034190066a20034188056a10c0012003280298062101024020032802940641ffffff3f71450d00200328029006102e0b024020032802a004200141016a410176490d002003280290044101460d00200341a8066a4200370300200341a0066a420037030020034190066a41086a220142003703002003420037039006200341e0016a41d9fcc60041061081022001200341e0016a41086a2218290000370300200320032900e00137039006200341e0016a4180f4cb004106108102200241086a2018290000370000200220032900e001370000200341286a20034190066a4120108e0220034101360290042003200328022c41c0f0006a41c0f00020032802281b3602940420032903c001210420032903c801211920032903d001211a200341a9056a20032903d801370000200341a1056a201a37000020034199056a201937000020034191056a200437000020034188056a41086a41013a0000200341163a00880520034188056a10fe010b20034188056a20034180046a41880110e9081a20034190066a200341c0016a109a07200328029006220220032802980620034188056a10bb050240200328029406450d002002102e0b0240200341a4056a2802002202450d00200241306c450d0020032802a005102e0b200341063a00b0010b20004200370308200020032800a901360019200041186a41003a00002000411c6a200341ac016a280000360000200042003703000c140b200141196a290000211d200141186a2d0000211e200141176a2d0000211f200141156a2f00002120200141146a2d00002121200141136a2d00002122200141116a2f00002123200141106a2d000021242001410f6a2d000021252001410d6a2f000021262001410c6a2d000021272001410b6a2d00002128200141096a2f00002129200141086a2d0000212a200141076a2d0000212b200141056a2f0000212c200141046a2d0000212d200141036a2d0000212e20022d0001211720022d0000211820012f0001212f200228022822022002280200417f6a2201360200024002400240024020180d00024020010d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b201741ff01714101470d012003201d3703a8062003201e3a00a7062003201f3a00a606200320203b01a406200320213a00a306200320223a00a206200320233b01a006200320243a009f06200320253a009e06200320263b019c06200320273a009b06200320283a009a06200320293b0198062003202a3a0097062003202b3a0096062003202c3b0194062003202d3a0093062003202e3a0092062003202f3b019006200341d0036a20034190066a109b0720034188056a20032802d003220120032802d80310b40520034190056a29030021042003290388052119200328029805210220034190066a2003419c056a41f40010e9081a20024102460d02200341d8026a20034190066a41f40010e9081a024020032802d403450d002001102e0b200341e0016a200341d8026a41f40010e9081a20032004370388042003201937038004200320023602900420034194046a200341e0016a41f40010e9081a20024101470d06200341a8066a22014200370300200341a0066a2202420037030020034190066a41086a221842003703002003420037039006200341e0016a41d9fcc60041061081022018200341e0016a41086a2217290000370300200320032900e00137039006200341e0016a4180f4cb00410610810220012017290000370300200220032900e001370300200341f0006a20034190066a4120108e022003280274410020032802701b2003280294044f0d03200341f0036a41061098070c070b20010d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22012001280200417f6a220136020020010d002002102e0b200341023a00f0030c070b024020032802d403450d002001102e0b200341f0036a41031098070c050b20034188056a200341a4046a109907200328028805220120032802900510ff010240200328028c05450d002001102e0b2003201d3703a0052003201e3a009f052003201f3a009e05200320203b019c05200320213a009b05200320223a009a05200320233b019805200320243a009705200320253a009605200320263b019405200320273a009305200320283a009205200320293b0190052003202a3a008f052003202b3a008e052003202c3b018c052003202d3a008b052003202e3a008a052003202f3b01880520034190066a20034188056a109b07200328029006220120032802980610ff010240200328029406450d002001102e0b20034188056a20034180046a41880110e9081a200341c0016a41086a20034188056a41206a280200360200200320032903a0053703c001200341a8066a420037030020034190066a41106a420037030020034190066a41086a220142003703002003420037039006200341e0016a418ef9c00041101081022001200341e0016a41086a2218290000370300200320032900e00137039006200341e0016a41c7c3cb004107108102200241086a2018290000370000200220032900e001370000200341d8026a20034190066a10f10220032902dc022104200320032802d8022202410820021b220136029806200320013602900620032004420020021b22043e029406200320012004422088a74106746a36029c06200341d8026a20034190066a10c001200320032802d8022202360290062003200220032802e00222014105746a360294060240024020010d00410021010c010b2003200241206a36029006200221010b200320013602e001200341c0016a200341e0016a20034190066a10bb01024020032802dc0241ffffff3f71450d002002102e0b20032802c001211302400240024020032802c801221641144b0d00201641014d0d0a20132016417f6a221841306c6a2107410021170340201620182202417f6a2218490d030240201620186b22094102490d002013200241306c6a220241206a22052903002013201841306c6a220141206a2206290300221a5a200241286a22082903002219200141286a220a29030022045a20192004511b0d0020034190066a41186a220b200141186a220c29030037030020034190066a41106a220d200141106a220e29030037030020034190066a41086a220f200141086a22102903003703002003200129030037039006200120022903003703002010200241086a290300370300200e200241106a290300370300200c200241186a29030037030020062005290300370300200a2008290300370300024020094103490d002017417f6a210841002101200721020340200241d0006a2205290300201a5a200241d8006a2206290300221920045a20192004511b0d0120082001460d05200241286a2006290300370300200241206a2005290300370300200241186a200241c8006a290300370300200241106a200241c0006a290300370300200241086a200241386a2903003703002002200241306a22052903003703002005210220172001417f6a2201470d000b200521020b2002201a3703202002200329039006370300200241286a2004370300200241186a200b290300370300200241106a200d290300370300200241086a200f2903003703000b200741506a21072017417f6a211720180d000c0b0b0b2016410176ad42307e2204422088a70d0c2004a72230417f4c0d0c2030102c2231450d0d201341506a2132201341907f6a21334104210c410021344100210a20162110034020102107410021104101210602402007417f6a2217450d0002400240024002400240024002402013201741306c6a220241206a290300200741306c220820136a41406a2201290300221954200241286a290300221a200141086a290300220454201a2004511b0d002007417e6a2106203320086a210241002110410021010340024020062001470d00200721060c090b20192002290300221b5a21182004200241086a290300221a5121172004201a5a2105200241506a2102200141016a2101201b2119201a21042018200520171b0d000b200141016a21062001417f7320076a21170c010b203320086a210202400340024020174101470d00410021170c020b20192002290300221b5421012004200241086a290300221a5121182004201a542105200241506a21022017417f6a2117201b2119201a21042001200520181b0d000b0b20072017490d01200720164b0d02200720176b22064101762218450d00203220086a21022013201741306c6a2101034020034190066a41286a2205200141286a220829030037030020034190066a41206a2209200141206a220b29030037030020034190066a41186a220d200141186a220e29030037030020034190066a41106a220f200141106a221029030037030020034190066a41086a2211200141086a22122903003703002003200129030037039006200241086a22142903002104200241106a22152903002119200241186a2235290300211a200241206a2236290300211b200241286a2237290300211c200120022903003703002008201c370300200b201b370300200e201a370300201020193703002012200437030020372005290300370300203620092903003703002035200d2903003703002015200f290300370300201420112903003703002002200329039006370300200241506a2102200141306a21012018417f6a22180d000b0b024020170d00201721100c060b0240200641094d0d00201721100c060b200720164b0d03201720076b21182013201741306c6a2108034020072017417f6a2210490d050240200720106b22064102490d002013201741306c6a220241206a22172903002013201041306c6a220141206a2205290300221a5a200241286a22092903002219200141286a220b29030022045a20192004511b0d0020034190066a41186a220d200141186a220e29030037030020034190066a41106a220f200141106a221129030037030020034190066a41086a2212200141086a22142903003703002003200129030037039006200120022903003703002014200241086a2903003703002011200241106a290300370300200e200241186a29030037030020052017290300370300200b2009290300370300024020064103490d0041012101200821020340200241d0006a2217290300201a5a200241d8006a2205290300221920045a20192004511b0d01201820016a4101460d06200241286a2005290300370300200241206a2017290300370300200241186a200241c8006a290300370300200241106a200241c0006a290300370300200241086a200241386a2903003703002002200241306a2217290300370300201721022018200141016a22016a0d000b201721020b2002201a3703202002200329039006370300200241286a2004370300200241186a200d290300370300200241106a200f290300370300200241086a20122903003703000b2010450d06200841506a21082018417f6a2118201021172006410a4f0d060c000b0b2017200741e4d1cc001057000b2007201641e4d1cc00104d000b2001200641d4d1cc00103c000b20072017417f6a2210490d002007201641f4d1cc00104d000b2010200741f4d1cc001057000b0240200a2034470d00203441016a22022034490d0e203441017422012002200120024b1b22024104200241044b1b220241ffffffff01712002464102742101200241037421020240024020340d0020034100360290060c010b20034104360298062003200c3602900620032034410374360294060b200341d8026a2002200120034190066a107d20032802e0022102024020032802d8024101470d0020020d100c0f0b20032802dc02210c200241037621340b200c200a4103746a2202200636020420022010360200200a41016a2211210a024020114102490d0002400240024003400240024002400240200c2011220a417f6a22114103746a2202280200450d00200a410374200c6a220541746a2802002217200228020422014d0d00200a41024d0d08200c200a417d6a22024103746a2802042218200120176a4d0d01200a41034d0d08200541646a280200201820176a4b0d080c010b200a4103490d0120022802042101200c200a417d6a22024103746a28020421180b20182001490d010b200a417e6a21020b0240200a200241016a22124d0d00200a20024d0d02200c20024103746a220d2802042214200d2802006a2202200c20124103746a220e280200220f490d03200220164b0d04200d41046a21152013200f41306c6a2209200e280204220b41306c22016a2117200241306c2118024002402002200f6b2206200b6b2202200b490d0020312009200110e908220820016a210502400240200b4101480d002006200b4a0d010b20092102200821010c020b201320186a210720082101200921020340200220172001201741206a290300200141206a29030054201741286a2903002204200141286a29030022195420042019511b22061b2218290300370300200241086a201841086a290300370300200241106a201841106a290300370300200241186a201841186a290300370300200241206a201841206a290300370300200241286a201841286a2903003703002001200141306a20061b2101200241306a2102201741306a201720061b221720074f0d02200520014b0d000c020b0b20312017200241306c220110e908220620016a210502400240200b4101480d00200241014e0d010b20172102200621010c010b203220186a21182017210203402018200241506a2207200541506a2208200541706a2201290300200241706a221729030054200141086a2903002204201741086a29030022195420042019511b22171b2201290300370300201841086a200141086a290300370300201841106a200141106a290300370300201841186a200141186a290300370300201841206a200141206a290300370300201841286a200141286a2903003703002005200820171b2105024020092007200220171b2202490d00200621010c020b201841506a21182006210120062005490d000b0b20022001200520016b221820184130706b10e9081a20152014200b6a360200200d200f360200200e200e41086a200a2012417f736a41037410ea081a4101210a201141014d0d050c010b0b2012200a4184d2cc00103c000b2002200a4194d2cc00103c000b200f200241a4d2cc001057000b2002201641a4d2cc00104d000b2010450d090c000b0b410120016b200941d4d1cc00103c000b2018201641c4d1cc001056000b2002200641ecd3c800103c000b200341d0036a41186a2218200141196a290000370300200341d0036a41106a2217200141116a290000370300200341d0036a41086a2205200141096a290000370300200320012900013703d0032002280228210102400240024002400240024002400240024020022d00000e0400010203020b20022d0001210220012001280200417f6a2206360200024020060d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22062006280200417f6a220636020020060d002001102e0b200241ff0171450d024110102c2202450d11200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1120014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a221836020020180d012002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22182018280200417f6a221836020020180d012002102e0c010b200241046a2d00002106200241086a28020021072002410c6a280200210820012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200641ff01710d00200741017420084b0d020b4110102c2202450d10200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1020014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a221836020020180d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22182018280200417f6a221836020020180d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b200341023a00f0030c010b20034188056a41186a201829030037030020034188056a41106a201729030037030020034188056a41086a2005290300370300200320032903d00337038805200341c0016a20034188056a109b0720034188056a20032802c001220220032802c801220110b405024020032802980522184102460d002002200110ff0120034190056a2903002104200329038805211920034190066a20034188056a41146a41f40010e9081a200341d8026a20034190066a41f40010e9081a024020032802c401450d002002102e0b200341e0016a200341d8026a41f40010e9081a20032018360290042003201937038004200320043703880420034180046a41146a200341e0016a41f40010e9081a2019200484500d0320034188016a200341e4046a2019200410cb022003290388012104200320034188016a41086a290300221937039005200320043703880520042019844200520d02200320034188056a3602900620034190066a10cc020c030b20034190066a2003419c056a41f40010e9081a024020032802c401450d002002102e0b200341f0036a410310980720032d00f0034106460d0320032902f40321040b20032802f003210220002004370024200041206a2002360000200041186a41003a000020004200370308420121040c030b200342f0f2bda1a7ee9cb9f9003703900620034188056a20034190066a10cd02200341f8006a20034188056a2004201910fd01200341a0066a200341f8006a41086a290300221b20197d2003290378221a200454ad7d2019201b7d2004201a54ad7d201a200456201b201956201b2019511b22021b3703002003201a20047d2004201a7d20021b3703980620032002ad3703900620034190066a41086a21010240024020020d00200320013602d802200341d8026a10cc020c010b200320013602d802200341d8026a10ce020b200341a0056a201937030020034198056a200437030020034190056a41063a00002003410e3a00880520034188056a10fe010b20034188056a200341a4046a109907200328028805220220032802900510ff010240200328028c05450d002002102e0b20034180046a41086a2903002104200329038004211920034188056a41086a41043a000020034191056a20032903d00337000020034199056a200341d0036a41086a290300370000200341a1056a200341e0036a290300370000200341a9056a200341e8036a290300370000200341b1056a20032902e404370000200341b9056a200341ec046a290200370000200341c1056a200341f4046a290200370000200341c9056a200341fc046a290200370000200341163a008805200341e0056a2004370300200341d8056a201937030020034188056a10fe0102402003419c046a2802002202450d00200241306c450d00200328029804102e0b200341063a00f0030b42002104200042003703082000200328008805360019200041186a41003a00002000411c6a2003418b056a2800003600000b200020043703000c110b200341f0036a41051098070b2003419c046a2802002202450d00200241306c450d00200328029804102e0b20032d00f0034106460d0320032902f40321040b20032802f003210220002004370024200041206a2002360000200041186a41003a000020004200370308200042013703000c0d0b0240203441ffffffff0171450d00200c102e0b2030413070210220304130490d0020302002460d002031102e0b200342f0f2bda1a7ee9cb9f90037039006200341e0016a20034190066a10cd02200342f0f2bda1a7ee9cb9f90037039006200341d8026a20034190066a10cd02200341d0036a200341d8026a10c80220034190066a20032802d003220220032802d80310c9022003290390062104200341a0066a2903002119200329039806211a024020032802d403450d002002102e0b20032802c8012202200241017622014d0d0120032802c001200141306c6a2202290320221b4200201a4200200442015122011b22044280b8d0df5a7c221a201a2004562019420020011b221920044280c8afa02554ad7d221a201956200442ffc7afa025561b22011b221c56200241286a29030022044200201a20011b22195620042019511b21020240200329038805221a20034190056a290300223884500d00200341e0006a200341ec056a201a203810fb010b2019200420021b2119201c201b20021b2104024020032d008c06450d0020034188056a41e4006a2202200341cc056a412010ec08450d00200341d0006a2004201942e400420010e608200341c0006a2004201942e400420010e708200341306a2003290340200341c0006a41086a2903004214420010e80820034190066a200341e0016a20022003290330221b2003280250220141ffff037141056e200141146c41fcff037141e4007041324b6aad42ff01837c221a200341306a41086a290300201a201b54ad7c221b410010ca022019201b7d2004201a54ad7d21192004201a7d21040b200341d8026a200341e0016a200341cc056a20042019410010ca02200341b1066a201d370000200341b0066a201e3a0000200341af066a201f3a0000200341ad066a20203b0000200341ac066a20213a0000200341ab066a20223a0000200341a9066a20233b0000200341a8066a20243a0000200341a7066a20253a0000200341a5066a20263b0000200341a4066a20273a0000200341a3066a20283a0000200341a1066a20293b0000200341a0066a202a3a00002003419f066a202b3a00002003419d066a202c3b00002003419c066a202d3a00002003419b066a202e3a000020034199066a202f3b000020034198066a41023a0000200341163a009006200341e0066a2004370300200341e8066a2019370300200341d1066a200341e4056a290200370000200341c9066a200341dc056a290200370000200341c1066a200341d4056a290200370000200341b9066a20032902cc0537000020034190066a10fe01024020032802c4012202450d00200241306c450d0020032802c001102e0b200341063a00f0030b20004200370308200020032800b001360019200041186a41003a00002000411c6a200341b3016a280000360000200042003703000c0a0b2001200241fcd3c800103c000b1038000b1036000b20032802b001210220002004370024200041206a2002360000200041186a41003a000020004200370308200042013703000c060b024020032802c401450d0020032802c001102e0b20032d00f0034106460d0020032802f0032102200020032902f403370024200041206a2002360000200041186a41003a000020004200370308200042013703000c050b20004200370308200020032800b001360019200041186a41003a00002000411c6a200341b3016a280000360000200042003703000c040b20032d00b0014106460d0120032902b40121040b20032802b001210220002004370024200041206a2002360000200041186a41003a000020004200370308200042013703000c020b20004200370308200020032800a901360019200041186a41003a00002000411c6a200341ac016a280000360000200042003703000c010b20004200370308200020032800b001360019200041186a41003a00002000411c6a200341b3016a280000360000200042003703000b20034190076a24000b8e7906097f017e0b7f037e037f017e230041c0026b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e080001020304050607000b200341d4016a4101360200200342013702c4012003419cc3cb003602c0012003410436029c0120034194c3cb0036029801200320034198016a3602d001200341c0016a41a4c3cb001044000b20034198016a41186a200141196a29000037030020034198016a41106a200141116a29000037030020034198016a41086a200141096a29000037030020032001290001370398012002410e6a2f010021042002410d6a2d000021052002410c6a2d000021062002410a6a2f01002107200241096a2d00002108200241086a2d00002109200241046a2d0000210a20022802282101024020022d0000220b0d002002411a6a290100210c200241196a2d0000210b200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113200241066a2f01002114200241056a2d00002115200241026a2f0100211620022d0001210220012001280200417f6a2217360200024020170d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22172017280200417f6a221736020020170d002001102e0b2003200c3703d8012003200b3a00d7012003200d3a00d6012003200e3b01d4012003200f3a00d301200320103a00d201200320113b01d001200320123a00cf01200320133a00ce01200320043b01cc01200320053a00cb01200320063a00ca01200320073b01c801200320083a00c701200320093a00c601200320143b01c401200320153a00c3012003200a3a00c201200320163b01c0010240200241ff01710d004103210b0c010b4110102c2202450d18200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1820014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220d3602004100210b200d0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220d200d280200417f6a220d360200200d0d002002102e0b0240024002400240200b417f6a0e03000102010b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200a41ff01710d00200741107420084108747220097241017420044110742005410874722006724b0d020b4110102c2202450d1a200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1a20014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220b360200200b0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220b200b280200417f6a220b360200200b0d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b410221020c010b200341d8016a22024200370300200341d0016a22014200370300200341c0016a41086a220b4200370300200342003703c001200341c8006a41b4c3cb004113108102200b200341c8006a41086a220a290000370300200320032900483703c001200341c8006a41c7c3cb0041071081022002200a29000037030020012003290048370300200341f8006a200341c0016a1088030240200328027822040d0041002106200341003602302003420137032841012104410021050c170b2003200329027c220c37022c20032004360228200ca721054100210202400240200c422088a722060e021801000b410021022006210103402001410176220a20026a210b200b20022004200b4105746a20034198016a412010ec084101481b21022001200a6b220141014b0d000b0b0240200420024105746a20034198016a412010ec082201450d00200341c0016a41186a20034198016a41186a290300370300200341c0016a41106a20034198016a41106a290300370300200341c0016a41086a20034198016a41086a29030037030020032003290398013703c001200620022001411f766a220b490d08200341c0016a21010c180b0240200541ffffff3f71450d002004102e0b410321020b200041cec3cb00360024200041123b002120004200370308200041286a410d360000200041206a20023a0000200041186a41003a0000200042013703000c180b200341f8006a41186a200141196a290000370300200341f8006a41106a200141116a290000370300200341f8006a41086a200141096a290000370300200320012900013703782002410e6a2f010021042002410d6a2d000021052002410c6a2d000021062002410a6a2f01002107200241096a2d00002108200241086a2d00002109200241046a2d0000210a20022802282101024020022d0000220b0d002002411a6a290100210c200241196a2d0000210b200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113200241066a2f01002114200241056a2d00002115200241026a2f0100211620022d0001210220012001280200417f6a2217360200024020170d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22172017280200417f6a221736020020170d002001102e0b2003200c3703d8012003200b3a00d7012003200d3a00d6012003200e3b01d4012003200f3a00d301200320103a00d201200320113b01d001200320123a00cf01200320133a00ce01200320043b01cc01200320053a00cb01200320063a00ca01200320073b01c801200320083a00c701200320093a00c601200320143b01c401200320153a00c3012003200a3a00c201200320163b01c0010240200241ff01710d004103210b0c010b4110102c2202450d17200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1720014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220d3602004100210b200d0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220d200d280200417f6a220d360200200d0d002002102e0b0240024002400240200b417f6a0e03000102010b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200a41ff01710d00200741107420084108747220097241017420044110742005410874722006724b0d020b4110102c2202450d19200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1920014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220b360200200b0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220b200b280200417f6a220b360200200b0d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b410221020c010b200341d8016a22024200370300200341d0016a22014200370300200341c0016a41086a220b4200370300200342003703c001200341c8006a41b4c3cb004113108102200b200341c8006a41086a220a290000370300200320032900483703c001200341c8006a41c7c3cb0041071081022002200a2900003703002001200329004837030020034198016a200341c0016a1088030240024020032802980122040d0020034100360210200342013703080c010b2003200329029c01220c37020c20032004360208200ca741ffffff3f71210641002102024002400240200c422088a722050e020201000b410021022005210103402001410176220a20026a210b200b20022004200b4105746a200341f8006a412010ec084101481b21022001200a6b220141014b0d000b0b200420024105746a200341f8006a412010ec080d00200520024d0d09200420024105746a2201200141206a20052002417f736a41057410ea081a20032005417f6a2202360210200341c0016a41186a220b4200370300200341c0016a41106a220a4200370300200341c0016a41086a22074200370300200342003703c00120034198016a41b4c3cb004113108102200720034198016a41086a220129000037030020032003290098013703c00120034198016a41c7c3cb004107108102200b2001290000370300200a200329009801370300200341c0016a200341086a109a03200b200341f8006a41186a290300370300200a200341f8006a41106a2903003703002007200341f8006a41086a290300370300200320032903783703c001200341c0016a41012004200210840820034198016a41186a220a420037030020034198016a41106a22074200370300200142003703002003420037039801200341c8006a41b4c3cb0041131081022001200341c8006a41086a220b2900003703002003200329004837039801200341c8006a41dbc3cb004105108102200a200b29000037030020072003290048370300200341c0016a20034198016a412010f40220032d00c0012108200341c8006a41186a2209200341d9016a290000370300200341c8006a41106a220d200341d1016a290000370300200b200341c9016a290000370300200320032900c101370348024020084101470d00200341286a41186a2009290300220c370300200341286a41106a200d2903002218370300200341286a41086a200b290300221937030020032003290348221a370328200a200c37030020072018370300200120193703002003201a370398014100210102400240024002402005417f6a0e020201000b4100210103402002410176220a20016a210b200b20012004200b4105746a20034198016a412010ec084101481b21012002200a6b220241014b0d000b0b200420014105746a20034198016a412010ec08450d010b200341e0006a22024200370300200341d8006a22014200370300200341c8006a41086a220b420037030020034200370348200341c0016a41b4c3cb004113108102200b200341c0016a41086a220a290000370300200320032900c001370348200341c0016a41dbc3cb0041051081022002200a290000370300200120032900c001370300200341c8006a412010ff010c010b200341d9016a200341b0016a290300370000200341d1016a200341a8016a290300370000200341c9016a200341a0016a29030037000020032003290398013700c101200341013a00c001200341c0016a1086080b2003418d023b01c001200341c0016a10fe0102402006450d002004102e0b200041186a41003a000020004200370308200020032800683600192000411c6a200341eb006a280000360000200042003703000c1a0b2006450d002004102e0b410321020b200041e0c3cb0036002420004192023b002120004200370308200041286a4109360000200041206a20023a0000200041186a41003a0000200042013703000c170b200341086a41186a200141196a290000370300200341086a41106a200141116a290000370300200341086a41086a200141096a29000037030020032001290001370308200341f8006a41186a200141396a290000370300200341f8006a41106a200141316a290000370300200341f8006a41086a200141296a2900003703002003200141216a2900003703782002410e6a2f010021042002410d6a2d000021052002410c6a2d000021062002410a6a2f01002107200241096a2d00002108200241086a2d00002109200241046a2d0000210a20022802282101024020022d0000220b0d002002411a6a290100210c200241196a2d0000210b200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113200241066a2f01002114200241056a2d00002115200241026a2f0100211620022d0001210220012001280200417f6a2217360200024020170d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22172017280200417f6a221736020020170d002001102e0b2003200c3703d8012003200b3a00d7012003200d3a00d6012003200e3b01d4012003200f3a00d301200320103a00d201200320113b01d001200320123a00cf01200320133a00ce01200320043b01cc01200320053a00cb01200320063a00ca01200320073b01c801200320083a00c701200320093a00c601200320143b01c401200320153a00c3012003200a3a00c201200320163b01c0010240200241ff01710d004103210b0c010b4110102c2202450d16200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1620014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220d3602004100210b200d0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220d200d280200417f6a220d360200200d0d002002102e0b024002400240200b417f6a0e03000102010b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200a41ff01710d00200741107420084108747220097241017420044110742005410874722006724b0d020b4110102c2202450d17200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1720014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220b360200200b0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220b200b280200417f6a220b360200200b0d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b410221020c100b200341086a200341f8006a412010ec08450d11200341d8016a22024200370300200341d0016a22014200370300200341c0016a41086a220b4200370300200342003703c001200341c8006a41b4c3cb004113108102200b200341c8006a41086a220a290000370300200320032900483703c001200341c8006a41c7c3cb0041071081022002200a2900003703002001200329004837030020034198016a200341c0016a108803024020032802980122040d0020034100360270200342013703684109210641e0c3cb002107410121050c0f0b2003200329029c01220c37026c2003200436026841012105200ca741ffffff3f7121094100210241e0c3cb0021074109210602400240200c422088a722080e020f01000b410021022008210103402001410176220a20026a210b200b20022004200b4105746a200341086a412010ec084101481b21022001200a6b220141014b0d000b0b200420024105746a200341086a412010ec080d0d4100210541002101024020080e02110d000b410021012008210b0340200b410176220620016a210a200a20012004200a4105746a200341f8006a412010ec084101481b2101200b20066b220b41014b0d000c0d0b0b2002410e6a2f010021072002410d6a2d000021082002410c6a2d000021092002410a6a2f0100210d200241096a2d0000210e200241086a2d0000210f200241046a2d000021042001410c6a2802002105200141086a2802002106200141046a280200210a20022802282101024020022d0000220b0d002002411a6a290100210c200241196a2d0000210b200241186a2d00002110200241166a2f01002111200241156a2d00002112200241146a2d00002113200241126a2f01002114200241116a2d00002115200241106a2d00002116200241066a2f01002117200241056a2d0000211b200241026a2f0100211c20022d0001210220012001280200417f6a221d3602000240201d0d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a221d201d280200417f6a221d360200201d0d002001102e0b2003200c3703d8012003200b3a00d701200320103a00d601200320113b01d401200320123a00d301200320133a00d201200320143b01d001200320153a00cf01200320163a00ce01200320073b01cc01200320083a00cb01200320093a00ca012003200d3b01c8012003200e3a00c7012003200f3a00c601200320173b01c4012003201b3a00c301200320043a00c2012003201c3b01c0010240200241ff01710d004103210b0c010b4110102c2202450d15200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1520014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a22103602004100210b20100d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a22102010280200417f6a221036020020100d002002102e0b024002400240200b417f6a0e03000102010b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200441ff01710d00200d411074200e41087472200f7241017420074110742008410874722009724b0d020b4110102c2202450d16200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1620014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220b360200200b0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220b200b280200417f6a220b360200200b0d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200641ffffff3f71450d00200a102e0b20004200370308200041206a41023a0000200041186a41003a0000200042013703000c160b200a200510fc02200341c0016a41186a22014200370300200341c0016a41106a220b4200370300200341c0016a41086a22044200370300200342003703c001200341c8006a41b4c3cb0041131081022004200341c8006a41086a2202290000370300200320032900483703c001200341c8006a41c7c3cb00410710810220012002290000370300200b200329004837030020034198016a200341c0016a108803200a20052003280298012201410120011b2208200329029c01420020011b220c422088a710fc0720034198016a41186a2201420037030020034198016a41106a220b420037030020034198016a41086a220442003703002003420037039801200341c8006a41b4c3cb004113108102200420022900003703002003200329004837039801200341c8006a41dbc3cb00410510810220012002290000370300200b2003290048370300200341c0016a20034198016a412010f40220032d00c0012107200341c8006a41186a2209200341d9016a290000370300200341c8006a41106a220d200341d1016a2900003703002002200341c9016a290000370300200320032900c101370348024020074101470d00200341286a41186a20092903002218370300200341286a41106a200d2903002219370300200341286a41086a2002290300221a37030020032003290348221e37032820012018370300200b20193703002004201a3703002003201e3703980141002102024002400240024020050e020201000b410021022005210103402001410176220420026a210b200b2002200a200b4105746a20034198016a412010ec084101481b2102200120046b220141014b0d000b0b200a20024105746a20034198016a412010ec08450d010b200341e0006a22024200370300200341d8006a22014200370300200341c8006a41086a220b420037030020034200370348200341c0016a41b4c3cb004113108102200b200341c0016a41086a2204290000370300200320032900c001370348200341c0016a41dbc3cb00410510810220022004290000370300200120032900c001370300200341c8006a412010ff010c010b200341d9016a200341b0016a290300370000200341d1016a200341a8016a290300370000200341c9016a200341a0016a29030037000020032003290398013700c101200341013a00c001200341c0016a1086080b2005ad4220862006ad8421180240200c42ffffff3f83500d002008102e0b2003201837029c012003200a36029801200341c8006a41186a22024200370300200341d8006a22014200370300200341c8006a41086a220b420037030020034200370348200341c0016a41b4c3cb004113108102200b200341c0016a41086a2204290000370300200320032900c001370348200341c0016a41c7c3cb00410710810220022004290000370300200120032900c001370300200341c8006a20034198016a109a030240200641ffffff3f71450d00200a102e0b2003418d063b01c001200341c0016a10fe01200041186a41003a000020004200370308200020032800783600192000411c6a200341fb006a280000360000200042003703000c150b200341086a41186a200141196a290000370300200341086a41106a200141116a290000370300200341086a41086a200141096a29000037030020032001290001370308200341c0016a41286a200241286a280200360200200341c0016a41206a200241206a290200370300200341c0016a41186a200241186a290200370300200341c0016a41106a200241106a290200370300200341c0016a41086a200241086a290200370300200320022902003703c00120034198016a200341c0016a10c102200341286a41086a220220034198016a41096a290000370300200341286a41106a220120034198016a41116a290000370300200341286a41186a220b20034198016a41196a2900003703002003200329009901370328024020032d0098014101460d00200341f8006a41186a200b290300370300200341f8006a41106a2001290300370300200341f8006a41086a200229030037030020032003290328370378200341f8006a200341086a412010ec08450d08200341d8016a22024200370300200341d0016a22014200370300200341c0016a41086a220b4200370300200342003703c001200341c8006a41b4c3cb004113108102200b200341c8006a41086a220a290000370300200320032900483703c001200341c8006a41c7c3cb0041071081022002200a2900003703002001200329004837030020034198016a200341c0016a108803024020032802980122040d0020034100360230200342013703284109210641e0c3cb00210741012105410321020c0a0b2003200329029c01220c37022c2003200436022841012105200ca741ffffff3f7121094100210241e0c3cb0021074109210602400240200c422088a722080e020801000b410021022008210103402001410176220a20026a210b200b20022004200b4105746a200341f8006a412010ec084101481b21022001200a6b220141014b0d000b0b200420024105746a200341f8006a412010ec080d064100210541002101024020080e020806000b410021012008210b0340200b410176220620016a210a200a20012004200a4105746a200341086a412010ec084101481b2101200b20066b220b41014b0d000c060b0b410221020c080b20034198016a41186a200141196a29000037030020034198016a41106a200141116a29000037030020034198016a41086a200141096a29000037030020032001290001370398012002410e6a2f010021042002410d6a2d000021052002410c6a2d000021062002410a6a2f01002107200241096a2d00002108200241086a2d00002109200241046a2d0000210a20022802282101024020022d0000220b0d002002411a6a290100210c200241196a2d0000210b200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113200241066a2f01002114200241056a2d00002115200241026a2f0100211620022d0001210220012001280200417f6a2217360200024020170d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22172017280200417f6a221736020020170d002001102e0b2003200c3701d8012003200b3a00d7012003200d3a00d6012003200e3b01d4012003200f3a00d301200320103a00d201200320113b01d001200320123a00cf01200320133a00ce01200320043b01cc01200320053a00cb01200320063a00ca01200320073b01c801200320083a00c701200320093a00c601200320143b01c401200320153a00c3012003200a3a00c201200320163b01c0010240200241ff01710d004103210b0c010b4110102c2202450d13200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1320014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220d3602004100210b200d0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220d200d280200417f6a220d360200200d0d002002102e0b0240024002400240200b417f6a0e03000102010b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200a41ff01710d00200741107420084108747220097241017420044110742005410874722006724b0d020b4110102c2202450d15200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1520014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220b360200200b0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220b200b280200417f6a220b360200200b0d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b410221020c010b200341d8016a22024200370300200341d0016a22014200370300200341c0016a41086a220b4200370300200342003703c001200341c8006a41b4c3cb004113108102200b200341c8006a41086a220a290000370300200320032900483703c001200341c8006a41c7c3cb0041071081022002200a29000037030020012003290048370300200341f8006a200341c0016a10880320032802782201410120011b210441002102024002400240200329027c420020011b220c422088a722010e020201000b4100210203402001410176220a20026a210b200b20022004200b4105746a20034198016a412010ec084101481b21022001200a6b220141014b0d000b0b200420024105746a20034198016a412010ec080d000240200c42ffffff3f83500d002004102e0b200341e0006a22024200370300200341d8006a22014200370300200341c8006a41086a220b420037030020034200370348200341c0016a41b4c3cb004113108102200b200341c0016a41086a220a290000370300200320032900c001370348200341c0016a41dbc3cb0041051081022002200a290000370300200120032900c0013703004120102c2202450d14200342203702c401200320023602c001200341c0016a20034198016a41201074200341c8006a412020032802c001220220032802c80110b201024020032802c401450d002002102e0b200341d9016a20034198016a41186a290300370000200341d1016a200341a8016a290300370000200341c9016a200341a0016a29030037000020032003290398013700c101200341013a00c001200341c0016a108608200041186a41003a000020004200370308200020032800283600192000411c6a2003412b6a280000360000200042003703000c150b0240200c42ffffff3f83500d002004102e0b410321020b200041e0c3cb0036002420004192023b002120004200370308200041286a4109360000200041206a20023a0000200041186a41003a0000200042013703000c130b2002410e6a2f010021042002410d6a2d000021052002410c6a2d000021062002410a6a2f01002107200241096a2d00002108200241086a2d00002109200241046a2d0000210a20022802282101024020022d0000220b0d002002411a6a290100210c200241196a2d0000210b200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113200241066a2f01002114200241056a2d00002115200241026a2f0100211620022d0001210220012001280200417f6a2217360200024020170d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22172017280200417f6a221736020020170d002001102e0b2003200c3701d8012003200b3a00d7012003200d3a00d6012003200e3b01d4012003200f3a00d301200320103a00d201200320113b01d001200320123a00cf01200320133a00ce01200320043b01cc01200320053a00cb01200320063a00ca01200320073b01c801200320083a00c701200320093a00c601200320143b01c401200320153a00c3012003200a3a00c201200320163b01c0010240200241ff01710d004103210b0c010b4110102c2202450d12200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1220014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220d3602004100210b200d0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220d200d280200417f6a220d360200200d0d002002102e0b0240024002400240200b417f6a0e03000102010b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b0240200a41ff01710d00200741107420084108747220097241017420044110742005410874722006724b0d020b4110102c2202450d14200241f8f7c60036020c2002410136020820024281808080103702004110102c2201450d1420014190f8c60036020c20014101360208200142818080801037020020022002280200417f6a220b360200200b0d002002280208200228020c2802001103000240200228020c280204450d002002280208102e0b200241046a220b200b280200417f6a220b360200200b0d002002102e0b20012001280200417f6a2202360200024020020d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22022002280200417f6a220236020020020d002001102e0b20004200370308200041206a41023a0000200041186a41003a00004201210c0c010b4200210c200341c8006a41186a22024200370300200341d8006a22014200370300200341c8006a41086a220b420037030020034200370348200341c0016a41b4c3cb004113108102200b200341c0016a41086a220a290000370300200320032900c001370348200341c0016a41dbc3cb0041051081022002200a290000370300200120032900c001370300200341c8006a412010ff01200341003a00c001200341c0016a108608200041186a41003a000020004200370308200020032800c0013600192000411c6a200341c3016a2800003600000b2000200c3703000c120b200b20061045000b200220051046000b200420014105746a200341086a412010ec080d0141cec3cb002107410d21060b02402009450d002004102e0b410321020c020b20034198016a41186a2201200341086a41186a29030037030020034198016a41106a220b200341086a41106a29030037030020034198016a41086a220a200341086a41086a2903003703002003200329030837039801200820024d0d02200420024105746a2202200329039801370000200241186a2001290300370000200241106a200b290300370000200241086a200a2903003700002004200810fc02200341c8006a41186a22014200370300200341c8006a41106a22024200370300200341c8006a41086a220b420037030020034200370348200341c0016a41b4c3cb004113108102200b200341c0016a41086a220a290000370300200320032900c001370348200341c0016a41c7c3cb0041071081022001200a290000370300200220032900c001370300200341c8006a200341286a109a03200341c0016a41186a200341f8006a41186a290300370300200341c0016a41106a200341f8006a41106a290300370300200a200341f8006a41086a290300370300200320032903783703c00141012105200341c0016a4101200420081084082001420037030020024200370300200b420037030020034200370348200341c0016a41b4c3cb004113108102200b200a290000370300200320032900c001370348200341c0016a41dbc3cb0041051081022001200a290000370300200220032900c001370300200341c0016a200341c8006a412010f40220032d00c001210a2001200341c0016a41196a2900003703002002200341c0016a41116a290000370300200b200341c0016a41096a290000370300200320032900c10137034802400240200a4101460d0041002105200341003a0098010c010b20034198016a41096a200341d0006a29030037000020034198016a41116a200341d8006a29030037000020034198016a41196a200341e0006a290300370000200341013a00980120032003290348370099010b200341d9016a20034190016a290300370000200341d1016a20034188016a290300370000200341c9016a20034180016a290300370000200320032903783700c101200341013a00c00102402005450d0020034198016a410172200341c0016a410172412010ec080d00200341e0006a4200370300200341d8006a4200370300200341c8006a41086a2201420037030020034200370348200341c0016a41b4c3cb0041131081022001200341c0016a41086a220b290000370300200320032900c001370348200341c0016a41dbc3cb004105108102200241086a200b290000370000200220032900c0013700004120102c2202450d0d200342203702c401200320023602c001200341c0016a200341086a41201074200341c8006a412020032802c001220220032802c80110b201024020032802c401450d002002102e0b200341d9016a200341206a290300370000200341d1016a200341186a290300370000200341c9016a200341106a290300370000200320032903083700c101200341013a00c001200341c0016a1086080b2009450d002004102e0b2003418d083b01c001200341c0016a10fe01200041186a41003a000020004200370308200020032800683600192000411c6a200341eb006a280000360000200042003703000c0c0b20002007360024200020053a0022200041123a002120004200370308200041286a2006360000200041206a20023a0000200041186a41003a0000200042013703000c0b0b2002200841fcc3cb00103c000b200420014105746a200341f8006a412010ec080d0341cec3cb002107410d21060b2009450d002004102e0b410321020b20002007360024200020053a0022200041123a002120004200370308200041286a2006360000200041206a20023a0000200041186a41003a0000200042013703000c060b200341c0016a41186a2201200341f8006a41186a290300370300200341c0016a41106a220b200341f8006a41106a290300370300200341c0016a41086a220a200341f8006a41086a290300370300200320032903783703c001200820024d0d01200420024105746a220220032903c001370000200241186a2001290300370000200241106a200b290300370000200241086a200a2903003700002004200810fc0220014200370300200b4200370300200a4200370300200342003703c00120034198016a41b4c3cb004113108102200a20034198016a41086a220229000037030020032003290098013703c00120034198016a41c7c3cb00410710810220012002290000370300200b200329009801370300200341c0016a200341e8006a109a032001200341086a41186a290300370300200b200341086a41106a290300370300200a200341086a41086a290300370300200320032903083703c001200341c0016a41012004200810840820034198016a41186a220b420037030020034198016a41106a220a4200370300200242003703002003420037039801200341c8006a41b4c3cb0041131081022002200341c8006a41086a22012900003703002003200329004837039801200341c8006a41dbc3cb004105108102200b2001290000370300200a2003290048370300200341c0016a20034198016a412010f40220032d00c0012102200341c8006a41186a200341d9016a290000370300200341c8006a41106a200341d1016a2900003703002001200341c9016a290000370300200320032900c101370348024020024101470d00200341286a41186a200341c8006a41186a220a290300220c370300200341286a41106a200341c8006a41106a22052903002218370300200341286a41086a200341c8006a41086a2206290300221937030020032003290348221a37032820034198016a41186a200c37030020034198016a41106a201837030020034198016a41086a20193703002003201a3703980141002102024002400240024020080e020201000b4100210203402008410176220b20026a210120012002200420014105746a20034198016a412010ec084101481b21022008200b6b220841014b0d000b0b200420024105746a20034198016a412010ec08450d010b200a4200370300200542003703002006420037030020034200370348200341c0016a41b4c3cb0041131081022006200341c0016a41086a2202290000370300200320032900c001370348200341c0016a41dbc3cb004105108102200a2002290000370300200520032900c001370300200341c8006a412010ff010c010b200341d9016a200341b0016a290300370000200341d1016a200341a8016a290300370000200341c9016a200341a0016a29030037000020032003290398013700c101200341013a00c001200341c0016a1086080b2003418d043b01c001200341c0016a10fe012009450d002004102e0b2000420037030820002003280001360019200041186a41003a00002000411c6a200341046a280000360000200042003703000c040b2002200841ecc3cb00103c000b200341c0016a41186a20034198016a41186a290300370300200341c0016a41106a20034198016a41106a290300370300200341c0016a41086a20034198016a41086a29030037030020032003290398013703c0014100210b200341c0016a21010b0240024020062005470d00200541016a22022005490d042005410174220a2002200a20024b1b22024104200241044b1b220241ffffff3f71200246210a200241057421020240024020050d00200341003602780c010b20034180016a4101360200200320043602782003200541057436027c0b200341c8006a2002200a200341f8006a107d200341d0006a280200210220032802484101460d012003200328024c22043602282003200241057636022c0b2004200b4105746a220241206a20022006200b6b41057410ea081a20022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a2900003700002003200641016a2201360230200341c8006a41186a220b4200370300200341c8006a41106a220a4200370300200341c8006a41086a2204420037030020034200370348200341c0016a41b4c3cb0041131081022004200341c0016a41086a2202290000370300200320032900c001370348200341c0016a41c7c3cb004107108102200b2002290000370300200a20032900c001370300200341c8006a200341286a109a03200341c0016a41186a20034198016a41186a290300370300200341c0016a41106a20034198016a41106a290300370300200220034198016a41086a29030037030020032003290398013703c00141d4e2cc0041002003280228220220011084082003410d3b01c001200341c0016a10fe010240200328022c41ffffff3f71450d002002102e0b200041186a41003a000020004200370308200020032800083600192000411c6a2003410b6a280000360000200042003703000c020b2002450d020b1036000b200341c0026a24000f0b1038000be33a0b037f017e037f017e047f017e017f037e027f017e0c7f230041d0096b22022400024002400240200128020422034108490d002001280200220429000021052001200341786a22063602042001200441086a22073602002006450d0120072d000021062001200341776a22083602042001200741016a36020002400240024002400240024020060e020001070b20084108490d062007290001210920012003416f6a220a3602042001200741096a36020041002107200241003a00a80820032106200a210b0240024002400340200a2007460d0120024188086a20076a200420076a220841116a2d00003a000020012006416e6a3602042001200841126a3602002002200741016a22083a00a8082006417f6a2106200b417f6a210b2008210720084120470d000b20024188076a41086a220720024188086a41086a29030037030020024188076a41106a220a20024188086a41106a29030037030020024188076a41186a220c20024188086a41186a290300370300200220022903880837038807200841ff0171411f4d0d09200320086b416f6a210d200241e8036a41086a2007290300370300200241e8036a41106a200a290300370300200241e8036a41186a200c2903003703002002200229038807220e3703c8052002200e3703e80341002107200241003a00a808200420086a210f2006416e6a210a0340200d2007460d0220024188086a20076a200f20076a220c41116a2d00003a00002001200a3602042001200c41126a3602002002200741016a220c3a00a808200a417f6a210a2003417f6a2103200c2107200c4120470d000b20024188076a41086a220720024188086a41086a29030037030020024188076a41106a220320024188086a41106a29030037030020024188076a41186a220a20024188086a41186a290300370300200220022903880837038807200c41ff0171411f4d0d09200241c8056a41086a2007290300370300200241c8056a41106a2003290300370300200241c8056a41186a200a29030037030020022002290388073703c8052006200c6b2207416f6a4104490d092004200b411f200b411f491b6a20086a41126a280000210820012007416b6a360204200241e8066a41086a2207200241c8056a41086a290300370300200241e8066a41106a2203200241c8056a41106a290300370300200241e8066a41186a2204200241c8056a41186a2903003703002001200f200c6a41156a360200200220022903c8053703e80620024188086a200110a70120022d0088084101460d0920024188076a41386a200241c1086a290000220e37030020024188076a41306a200241b9086a290000221037030020024188076a41286a200241b1086a290000221137030020024188076a41206a200241a9086a290000221237030020024188066a41086a220620024191086a29000037030020024188066a41106a220b20024199086a29000037030020024188066a41186a220a200241a1086a29000037030020024188066a41206a220c201237030020024188066a41286a220d201137030020024188066a41306a220f201037030020024188066a41386a2213200e370300200220022900890837038806200241c8066a41186a22142004290300370300200241c8066a41106a22042003290300370300200241c8066a41086a22032007290300370300200220022903e8063703c806200241a8056a41186a22072014290300370300200241a8056a41106a22142004290300370300200241a8056a41086a22042003290300370300200220022903c8063703a805200241e8046a41386a22032013290300370300200241e8046a41306a2213200f290300370300200241e8046a41286a220f200d290300370300200241e8046a41206a220d200c290300370300200241e8046a41186a220c200a290300370300200241e8046a41106a220a200b290300370300200241e8046a41086a220b200629030037030020022002290388063703e804200241c8046a41186a2007290300370300200241c8046a41106a2014290300370300200241c8046a41086a2004290300370300200220022903a8053703c80420024188046a41386a200329030037030020024188046a41306a201329030037030020024188046a41286a200f29030037030020024188046a41206a200d29030037030020024188046a41186a200c29030037030020024188046a41106a200a29030037030020024188046a41086a200b290300370300200220022903e8043703880441002107200241003a00a80820012802042106417f2103034020062007460d0320024188086a20076a200128020022042d00003a00002001200620036a3602042001200441016a3602002002200741016a22043a00a8082003417f6a21032004210720044120470d000b20024188076a41086a220720024188086a41086a29030037030020024188076a41106a220320024188086a41106a29030037030020024188076a41186a220b20024188086a41186a290300370300200220022903880837038807200441ff0171411f4d0d09200241c8056a41086a2007290300370300200241c8056a41106a2003290300370300200241c8056a41186a200b29030037030020022002290388073703c805200620046b22074104490d0920012802002204280000210320012007417c6a3602042001200441046a360200200241e8066a41086a2207200241c8056a41086a290300370300200241e8066a41106a2204200241c8056a41106a290300370300200241e8066a41186a2206200241c8056a41186a290300370300200220022903c8053703e80620024188086a200110a70120022d0088084101460d0920024188076a41386a200241c1086a290000220e37030020024188076a41306a200241b9086a290000221037030020024188076a41286a200241b1086a290000221137030020024188076a41206a200241a9086a290000221237030020024188076a41186a200241a1086a290000221537030020024188066a41086a220120024191086a29000037030020024188066a41106a220b20024199086a29000037030020024188066a41186a220a201537030020024188066a41206a220c201237030020024188066a41286a220d201137030020024188066a41306a220f201037030020024188066a41386a2213200e370300200220022900890837038806200241c8066a41186a22142006290300370300200241c8066a41106a22062004290300370300200241c8066a41086a22042007290300370300200220022903e8063703c806200241a8056a41186a22072014290300370300200241a8056a41106a22142006290300370300200241a8056a41086a22062004290300370300200220022903c8063703a805200241e8046a41386a22042013290300370300200241e8046a41306a2213200f290300370300200241e8046a41286a220f200d290300370300200241e8046a41206a220d200c290300370300200241e8046a41186a220c200a290300370300200241e8046a41106a220a200b290300370300200241e8046a41086a220b200129030037030020022002290388063703e804200241c8026a41186a2007290300370300200241c8026a41106a2014290300370300200241c8026a41086a2006290300370300200220022903a8053703c80220024188026a41386a200429030037030020024188026a41306a201329030037030020024188026a41286a200f29030037030020024188026a41206a200d29030037030020024188026a41186a200c29030037030020024188026a41106a200a29030037030020024188026a41086a200b290300370300200220022903e80437038802200241c8036a41186a2201200241e8036a41186a290300370300200241c8036a41106a2207200241e8036a41106a290300370300200241c8036a41086a2204200241e8036a41086a290300370300200220022903e8033703c803200241a8036a41186a200241c8046a41186a290300370300200241a8036a41106a200241c8046a41106a290300370300200241a8036a41086a200241c8046a41086a290300370300200220022903c8043703a803200241e8026a41386a20024188046a41386a290300370300200241e8026a41306a20024188046a41306a290300370300200241e8026a41286a20024188046a41286a290300370300200241e8026a41206a20024188046a41206a290300370300200241e8026a41186a20024188046a41186a290300370300200241e8026a41106a20024188046a41106a290300370300200241e8026a41086a20024188046a41086a29030037030020022002290388043703e802200241e8016a41186a2001290300370300200241e8016a41106a2007290300370300200241e8016a41086a2004290300370300200220022903c8033703e8014200210e0c040b200741ff0171450d08200241003a00a8080c080b200741ff0171450d07200241003a00a8080c070b200741ff0171450d06200241003a00a8080c060b20084108490d052007290001210920012003416f6a220a3602042001200741096a36020041002107200241003a00a80820032106200a210b0340200a2007460d0220024188086a20076a200420076a220841116a2d00003a000020012006416e6a3602042001200841126a3602002002200741016a22083a00a8082006417f6a2106200b417f6a210b2008210720084120470d000b20024188076a41086a220720024188086a41086a29030037030020024188076a41106a220a20024188086a41106a29030037030020024188076a41186a220c20024188086a41186a290300370300200220022903880837038807200841ff0171411f4d0d05200320086b416f6a210d200241e8036a41086a2007290300370300200241e8036a41106a200a290300370300200241e8036a41186a200c2903003703002002200229038807220e3703c8052002200e3703e80341002107200241003a00a808200420086a210f2006416e6a210a0340200d2007460d0320024188086a20076a200f20076a220c41116a2d00003a00002001200a3602042001200c41126a3602002002200741016a220c3a00a808200a417f6a210a2003417f6a2103200c2107200c4120470d000b20024188076a41086a220720024188086a41086a29030037030020024188076a41106a220320024188086a41106a29030037030020024188076a41186a220a20024188086a41186a290300370300200220022903880837038807200c41ff0171411f4d0d05200241c8056a41086a2007290300370300200241c8056a41106a2003290300370300200241c8056a41186a200a29030037030020022002290388073703c8052006200c6b2207416f6a4104490d052004200b411f200b411f491b6a20086a41126a280000210820012007416b6a360204200241e8066a41086a2207200241c8056a41086a290300370300200241e8066a41106a2203200241c8056a41106a290300370300200241e8066a41186a2204200241c8056a41186a2903003703002001200f200c6a41156a360200200220022903c8053703e80620024188086a200110a70120022d0088084101460d0520024188076a41386a200241c1086a290000220e37030020024188076a41306a200241b9086a290000221037030020024188076a41286a200241b1086a290000221137030020024188076a41206a200241a9086a290000221237030020024188066a41086a220620024191086a29000037030020024188066a41106a220b20024199086a29000037030020024188066a41186a220a200241a1086a29000037030020024188066a41206a220c201237030020024188066a41286a220d201137030020024188066a41306a220f201037030020024188066a41386a2213200e370300200220022900890837038806200241c8066a41186a22142004290300370300200241c8066a41106a22042003290300370300200241c8066a41086a22032007290300370300200220022903e8063703c806200241a8056a41186a22072014290300370300200241a8056a41106a22142004290300370300200241a8056a41086a22042003290300370300200220022903c8063703a805200241e8046a41386a22032013290300370300200241e8046a41306a2213200f290300370300200241e8046a41286a220f200d290300370300200241e8046a41206a220d200c290300370300200241e8046a41186a220c200a290300370300200241e8046a41106a220a200b290300370300200241e8046a41086a220b200629030037030020022002290388063703e804200241c8046a41186a2007290300370300200241c8046a41106a2014290300370300200241c8046a41086a2004290300370300200220022903a8053703c80420024188046a41386a200329030037030020024188046a41306a201329030037030020024188046a41286a200f29030037030020024188046a41206a200d29030037030020024188046a41186a200c29030037030020024188046a41106a200a29030037030020024188046a41086a200b290300370300200220022903e8043703880441002107200241003a00a80820012802042106417f2103034020062007460d0420024188086a20076a200128020022042d00003a00002001200620036a3602042001200441016a3602002002200741016a22043a00a8082003417f6a21032004210720044120470d000b20024188076a41086a220720024188086a41086a29030037030020024188076a41106a220320024188086a41106a29030037030020024188076a41186a220b20024188086a41186a290300370300200220022903880837038807200441ff0171411f4d0d05200241c8056a41086a2007290300370300200241c8056a41106a2003290300370300200241c8056a41186a200b29030037030020022002290388073703c805200620046b22074104490d0520012802002204280000210320012007417c6a3602042001200441046a360200200241e8066a41086a2207200241c8056a41086a290300370300200241e8066a41106a2204200241c8056a41106a290300370300200241e8066a41186a2206200241c8056a41186a290300370300200220022903c8053703e80620024188086a200110a70120022d0088084101460d0520024188076a41386a200241c1086a290000220e37030020024188076a41306a200241b9086a290000221037030020024188076a41286a200241b1086a290000221137030020024188076a41206a200241a9086a290000221237030020024188076a41186a200241a1086a290000221537030020024188066a41086a220120024191086a29000037030020024188066a41106a220b20024199086a29000037030020024188066a41186a220a201537030020024188066a41206a220c201237030020024188066a41286a220d201137030020024188066a41306a220f201037030020024188066a41386a2213200e370300200220022900890837038806200241c8066a41186a22142006290300370300200241c8066a41106a22062004290300370300200241c8066a41086a22042007290300370300200220022903e8063703c806200241a8056a41186a22072014290300370300200241a8056a41106a22142006290300370300200241a8056a41086a22062004290300370300200220022903c8063703a805200241e8046a41386a22042013290300370300200241e8046a41306a2213200f290300370300200241e8046a41286a220f200d290300370300200241e8046a41206a220d200c290300370300200241e8046a41186a220c200a290300370300200241e8046a41106a220a200b290300370300200241e8046a41086a220b200129030037030020022002290388063703e804200241c8026a41186a2007290300370300200241c8026a41106a2014290300370300200241c8026a41086a2006290300370300200220022903a8053703c80220024188026a41386a200429030037030020024188026a41306a201329030037030020024188026a41286a200f29030037030020024188026a41206a200d29030037030020024188026a41186a200c29030037030020024188026a41106a200a29030037030020024188026a41086a200b290300370300200220022903e80437038802200241c8036a41186a2201200241e8036a41186a290300370300200241c8036a41106a2207200241e8036a41106a290300370300200241c8036a41086a2204200241e8036a41086a290300370300200220022903e8033703c803200241a8036a41186a200241c8046a41186a290300370300200241a8036a41106a200241c8046a41106a290300370300200241a8036a41086a200241c8046a41086a290300370300200220022903c8043703a803200241e8026a41386a20024188046a41386a290300370300200241e8026a41306a20024188046a41306a290300370300200241e8026a41286a20024188046a41286a290300370300200241e8026a41206a20024188046a41206a290300370300200241e8026a41186a20024188046a41186a290300370300200241e8026a41106a20024188046a41106a290300370300200241e8026a41086a20024188046a41086a29030037030020022002290388043703e802200241e8016a41186a2001290300370300200241e8016a41106a2007290300370300200241e8016a41086a2004290300370300200220022903c8033703e8014201210e0b200241c8016a41186a2201200241a8036a41186a290300370300200241c8016a41106a2207200241a8036a41106a290300370300200241c8016a41086a2204200241a8036a41086a29030037030020024188016a41086a2206200241e8026a41086a29030037030020024188016a41106a220b200241e8026a41106a29030037030020024188016a41186a220a200241e8026a41186a29030037030020024188016a41206a220c200241e8026a41206a29030037030020024188016a41286a220d200241e8026a41286a29030037030020024188016a41306a220f200241e8026a41306a29030037030020024188016a41386a2213200241e8026a41386a290300370300200220022903a8033703c801200220022903e80237038801200241e8006a41186a2214200241c8026a41186a290300370300200241e8006a41106a2216200241c8026a41106a290300370300200241e8006a41086a2217200241c8026a41086a290300370300200241286a41386a221820024188026a41386a290300370300200241286a41306a221920024188026a41306a290300370300200241286a41286a221a20024188026a41286a290300370300200241286a41206a221b20024188026a41206a290300370300200241286a41186a221c20024188026a41186a290300370300200241286a41106a221d20024188026a41106a290300370300200241286a41086a221e20024188026a41086a290300370300200220022903c8023703682002200229038802370328200241086a41186a221f200241e8016a41186a290300370300200241086a41106a2220200241e8016a41106a290300370300200241086a41086a2221200241e8016a41086a290300370300200220022903e801370308200041186a2008360200200020093703102000200e37030820002005370300200020022903c80137021c200041246a20042903003702002000412c6a2007290300370200200041346a2001290300370200200020022903880137023c200041c4006a2006290300370200200041cc006a200b290300370200200041d4006a200a290300370200200041dc006a200c290300370200200041e4006a200d290300370200200041ec006a200f290300370200200041f4006a20132903003702002000200336027c20004198016a201429030037020020004190016a201629030037020020004188016a201729030037020020004180016a2002290368370200200041d8016a2018290300370200200041d0016a2019290300370200200041c8016a201a290300370200200041c0016a201b290300370200200041b8016a201c290300370200200041b0016a201d290300370200200041a8016a201e290300370200200041a0016a2002290328370200200041f8016a201f290300370300200041f0016a2020290300370300200041e8016a2021290300370300200041e0016a20022903083703000c050b200741ff0171450d03200241003a00a8080c030b200741ff0171450d02200241003a00a8080c020b200741ff0171450d01200241003a00a8080c010b200042023703080c010b200042023703080b200241d0096a24000bde17020b7f057e23004190076b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a36020020050e06010203040506070b200041073a00000c1a0b200241086a200110ab0102402002280208450d0020024100360280040c190b20024180046a2001200228020c1092012002280280042205450d18200228028404210420012802042206450d0620024188046a2802002107200128020022032d0000210820012006417f6a22063602042001200341016a360200410021030240024020080e020100080b20024180046a200110930120022d0080044101460d07200241e8016a20024199046a290000370300200241e0016a20024191046a290000370300200241d8016a20024189046a29000037030020022002290081043703d00120012802042106410121030b200241d0006a41186a2208200241d0016a41186a290300370300200241d0006a41106a2209200241d0016a41106a290300370300200241d0006a41086a220a200241d0016a41086a290300370300200220022903d001370350024020064104490d002001280200220b280000210c20012006417c6a3602042001200b41046a360200200241b0016a41086a200a290300220d370300200241b0016a41106a2009290300220e370300200241b0016a41186a2008290300220f3703002002200229035022103703b001200020033a0001200041013a0000200041026a20103700002000410a6a200d370000200041126a200e3700002000411a6a200f370000200041306a200c3602002000412c6a2007360100200041286a2004360100200041246a2005360100200041226a20022f0190013b01000c1a0b200041073a00000c070b20024180046a20011098012002280280042105200241d0016a20024180046a41047241ac0210e9081a024002402005411c460d0020024180046a200241d0016a41ac0210e9081a41b002102c22040d010c180b200041073a00000c190b20042005360200200441046a20024180046a41ac0210e9081a200241106a200110ab01024020022802100d0020022802142101200041023a0000200020022f00b0013b0001200041086a2001360200200041046a20043602002000410c6a2002290250370200200041036a200241b0016a41026a2d00003a0000200041146a200241d0006a41086a2902003702002000411c6a200241e0006a290200370200200041246a200241e8006a2902003702002000412c6a200241f0006a290200370200200041346a200241f8006a2802003602000c190b200041073a00002004108b022004102e0c180b200241206a200110ab0120022802200d072002280224210620024180046a20011098012002280280042105200241d0016a20024180046a41047241ac0210e9081a2005411c460d0620024180046a200241d0016a41ac0210e9081a41b002102c2204450d1520042005360200200441046a20024180046a41ac0210e9081a200241186a200110ab01024020022802180d00200228021c2101200041033a0000200020022f00b0013b00012000410c6a2001360200200041086a2004360200200041046a2006360200200041106a2002290350370300200041036a200241b2016a2d00003a0000200041186a200241d0006a41086a290300370300200041206a200241d0006a41106a290300370300200041286a200241d0006a41186a290300370300200041306a200241d0006a41206a2903003703000c180b200041073a00002004108b022004102e0c170b41002105200241003a00a0042003417e6a21030240034020062005460d0120024180046a20056a200420056a220841016a2d00003a0000200120033602042001200841026a3602002002200541016a22083a00a0042003417f6a21032008210520084120460d100c000b0b200541ff0171450d0f200241003a00a0040c0f0b41002105200241003a00a0042003417e6a21030240034020062005460d0120024180046a20056a200420056a220841016a2d00003a0000200120033602042001200841026a3602002002200541016a22083a00a0042003417f6a21032008210520084120460d0a0c000b0b200541ff0171450d09200241003a00a0040c090b41002105200241003a00a0042003417e6a21030240034020062005460d0120024180046a20056a200420056a220841016a2d00003a0000200120033602042001200841026a3602002002200541016a22083a00a0042003417f6a21032008210520084120460d070c000b0b200541ff0171450d06200241003a00a0040c060b200041073a00000c130b200041073a00000b200441ffffff3f71450d112005102e0c110b200041073a00000c100b200041073a00000c0f0b200241d0016a41086a220120024180046a41086a290300370300200241d0016a41106a220520024180046a41106a290300370300200241d0016a41186a220420024180046a41186a29030037030020022002290380043703d001200841ff0171411f4d0d00200241b0016a41086a2001290300220d370300200241b0016a41106a2005290300220e370300200241b0016a41186a2004290300220f370300200220022903d00122103703b001200041063a000020002010370001200041096a200d370000200041116a200e370000200041196a200f370000200041216a200229009001370000200041296a20024190016a41086a290000370000200041306a2002419f016a2900003700000c0e0b200041073a00000c0d0b200241d0016a41086a220520024180046a41086a290300370300200241d0016a41106a220420024180046a41106a290300370300200241d0016a41186a220620024180046a41186a29030037030020022002290380043703d001200841ff0171411f4d0d00200241b0016a41086a2005290300370300200241b0016a41106a2004290300370300200241b0016a41186a2006290300370300200220022903d0013703b001200241c8006a200110ab0120022802480d01200228024c2105200241386a200110d9042002290338a70d022002290340210d200241306a200110ab0120022802300d032002280234210120024190016a41186a200241b0016a41186a290300220e37030020024190016a41106a200241b0016a41106a290300220f37030020024190016a41086a200241b0016a41086a2903002210370300200220022903b001221137039001200041053a000020002011370001200041096a2010370000200041116a200f370000200041196a200e370000200041216a20022f0080013b0000200041236a20024182016a2d00003a0000200041306a200d370300200041286a2001360200200041246a20053602000c0c0b200041073a00000c0b0b200041073a00000c0a0b200041073a00000c090b200041073a00000c080b200241d0016a41086a220520024180046a41086a290300370300200241d0016a41106a220420024180046a41106a290300370300200241d0016a41186a220620024180046a41186a29030037030020022002290380043703d001200841ff0171411f4d0d00200241b0016a41086a2005290300370300200241b0016a41106a2004290300370300200241b0016a41186a2006290300370300200220022903d0013703b001200241286a200110ab0120022802280d0120012802042205450d04200228022c2103200128020022042d0000210620012005417f6a3602042001200441016a3602004100210120060e020302040b200041073a00000c060b200041073a00000c050b410121010b20024190016a41186a200241b0016a41186a290300220d37030020024190016a41106a200241b0016a41106a290300220e37030020024190016a41086a200241b0016a41086a290300220f370300200220022903b001221037039001200041043a000020002010370001200041096a200f370000200041116a200e370000200041196a200d370000200041246a2003360200200041216a20013a0000200041286a200229038001370300200041306a20024180016a41086a2903003703000c030b200041073a00000c020b1036000b200041073a00000b20024190076a24000bb20401057f23004180056b22022400024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a36020020050e03010203040b200041043b01000c080b2002200110ab0102402002280200450d00200241003602200c070b200241206a200120022802041097012002280220450d06200241da026a200241206a41086a280200360100200220022903203701d202200041013b0100200020022901d002370102200041086a200241d6026a2901003701000c070b024020064102490d0020042f0001210520012003417d6a3602042001200441036a360200200241d0026a200110980120022802d0022101200241206a200241d0026a41047241ac0210e9081a024002402001411c460d00200241d0026a200241206a41ac0210e9081a41b002102c22030d011036000b200041043b01000c080b20032001360200200341046a200241d0026a41ac0210e9081a200041046a2003360200200020053b0102200041023b01000c070b200041043b01000c060b200241086a200110ab012002280208450d01200241003602200c020b200041043b01000c040b200241206a2001200228020c10970120022802200d010b200041043b01000c020b200241da026a200241206a41086a280200360100200220022903203701d202200041033b0100200020022901d002370102200041086a200241d6026a2901003701000c010b200041043b01000b20024180056a24000bb54507047f017e017f027e047f077e107f230041d00d6b220224000240024002402001280200220328020422044108490d002003280200220529000021062003200441786a3602042003200541086a360200200128020022032802042204450d01200328020022052d0000210720032004417f6a3602042003200541016a3602000240024002400240024002400240024020070e020001090b2001280200220328020422044108490d082003280200220529000021082003200441786a3602042003200541086a36020041002104200241003a00a80a024002400240024002400340200128020022032802042205450d01200241880a6a20046a200328020022072d00003a000020032005417f6a3602042003200741016a3602002002200441016a22033a00a80a2003210420034120470d000b200241d00a6a41186a200241880a6a41186a2903002209370300200241c8096a41086a2203200241880a6a41086a290300370300200241c8096a41106a2204200241880a6a41106a290300370300200241c8096a41186a22052009370300200220022903880a3703c809200241e8036a41186a2005290300370300200241e8036a41106a2004290300370300200241e8036a41086a2003290300370300200220022903c8093703e80341002104200241003a00a80a0340200128020022032802042205450d02200241880a6a20046a200328020022072d00003a000020032005417f6a3602042003200741016a3602002002200441016a22033a00a80a2003210420034120470d000b200241d00a6a41186a200241880a6a41186a2903002209370300200241c8096a41086a2204200241880a6a41086a290300370300200241c8096a41106a2205200241880a6a41106a290300370300200241c8096a41186a22072009370300200220022903880a3703c80920012802002203280204220a4104490d0d2003280200220b280000210c2003200a417c6a3602042003200b41046a360200200241e8066a41086a2004290300370300200241e8066a41106a2005290300370300200241e8066a41186a2007290300370300200220022903c8093703e80641002104200241003a00c80a0340200128020022032802042205450d03200241880a6a20046a200328020022072d00003a000020032005417f6a3602042003200741016a3602002002200441016a22033a00c80a20032104200341c000470d000b200241d00a6a41086a2203200241880a6a41086a290300370300200241d00a6a41106a2204200241880a6a41106a290300370300200241d00a6a41186a2205200241880a6a41186a290300370300200241d00a6a41206a2207200241880a6a41206a290300370300200241d00a6a41286a220a200241880a6a41286a290300370300200241d00a6a41306a220b200241880a6a41306a290300370300200241d00a6a41386a220d200241880a6a41386a290300370300200220022903880a3703d00a200241c8096a41086a2003290300220e370300200241c8096a41106a20042903002209370300200241c8096a41186a2005290300220f370300200241c8096a41206a20072903002210370300200241c8096a41286a200a2903002211370300200241c8096a41306a200b2903002212370300200241c8096a41386a2203200d290300370300200220022903d00a22133703c80920024188076a41306a201237030020024188076a41286a201137030020024188076a41206a201037030020024188076a41186a200f37030020024188076a41106a200937030020024188076a41386a2003290300221437030020024188066a41306a2203201237030020024188066a41286a2204201137030020024188066a41206a2205201037030020024188066a41186a2207200f37030020024188066a41106a220a200937030020024188066a41086a220b200e37030020024188066a41386a220d20143703002002201337038806200241c8066a41186a2215200241e8066a41186a290300370300200241c8066a41106a2216200241e8066a41106a290300370300200241c8066a41086a2217200241e8066a41086a290300370300200220022903e8063703c806200241a8056a41186a22182015290300370300200241a8056a41106a22152016290300370300200241a8056a41086a22162017290300370300200220022903c8063703a805200241e8046a41386a2217200d290300370300200241e8046a41306a220d2003290300370300200241e8046a41286a22032004290300370300200241e8046a41206a22042005290300370300200241e8046a41186a22052007290300370300200241e8046a41106a2207200a290300370300200241e8046a41086a220a200b29030037030020022002290388063703e804200241c8046a41186a2018290300370300200241c8046a41106a2015290300370300200241c8046a41086a2016290300370300200220022903a8053703c80420024188046a41386a201729030037030020024188046a41306a200d29030037030020024188046a41286a200329030037030020024188046a41206a200429030037030020024188046a41186a200529030037030020024188046a41106a200729030037030020024188046a41086a200a290300370300200220022903e8043703880441002104200241003a00a80a0340200128020022032802042205450d04200241880a6a20046a200328020022072d00003a000020032005417f6a3602042003200741016a3602002002200441016a22033a00a80a2003210420034120470d000b200241d00a6a41186a200241880a6a41186a2903002209370300200241c8096a41086a2204200241880a6a41086a290300370300200241c8096a41106a2205200241880a6a41106a290300370300200241c8096a41186a22072009370300200220022903880a3703c80920012802002203280204220a4104490d0d2003280200220d280000210b2003200a417c6a3602042003200d41046a360200200241e8066a41086a2004290300370300200241e8066a41106a2005290300370300200241e8066a41186a2007290300370300200220022903c8093703e80641002104200241003a00c80a0340200128020022032802042205450d05200241880a6a20046a200328020022072d00003a000020032005417f6a3602042003200741016a3602002002200441016a22033a00c80a20032104200341c000470d000b200241d00a6a41086a2201200241880a6a41086a290300370300200241d00a6a41106a2203200241880a6a41106a290300370300200241d00a6a41186a2204200241880a6a41186a290300370300200241d00a6a41206a2205200241880a6a41206a290300370300200241d00a6a41286a2207200241880a6a41286a290300370300200241d00a6a41306a220a200241880a6a41306a290300370300200241d00a6a41386a220d200241880a6a41386a290300370300200220022903880a3703d00a200241c8096a41386a2215200d290300370300200241c8096a41306a200a2903002209370300200241c8096a41286a2007290300220f370300200241c8096a41206a20052903002210370300200241c8096a41186a20042903002211370300200241c8096a41106a20032903002212370300200241c8096a41086a2001290300220e370300200220022903d00a22133703c80920024188076a41306a2201200937030020024188076a41286a2203200f37030020024188076a41206a2204201037030020024188076a41186a2205201137030020024188076a41106a2207201237030020024188076a41086a220a200e37030020024188076a41386a220d2015290300370300200220133703880720024188066a41386a2215200d29030037030020024188066a41306a220d200129030037030020024188066a41286a2201200329030037030020024188066a41206a2203200429030037030020024188066a41186a2204200529030037030020024188066a41106a2205200729030037030020024188066a41086a2207200a290300370300200220022903880737038806200241c8066a41186a220a200241e8066a41186a290300370300200241c8066a41106a2216200241e8066a41106a290300370300200241c8066a41086a2217200241e8066a41086a290300370300200220022903e8063703c806200241a8056a41186a2218200a290300370300200241a8056a41106a220a2016290300370300200241a8056a41086a22162017290300370300200220022903c8063703a805200241e8046a41386a22172015290300370300200241e8046a41306a2215200d290300370300200241e8046a41286a220d2001290300370300200241e8046a41206a22012003290300370300200241e8046a41186a22032004290300370300200241e8046a41106a22042005290300370300200241e8046a41086a2205200729030037030020022002290388063703e804200241c8026a41186a2018290300370300200241c8026a41106a200a290300370300200241c8026a41086a2016290300370300200220022903a8053703c80220024188026a41386a201729030037030020024188026a41306a201529030037030020024188026a41286a200d29030037030020024188026a41206a200129030037030020024188026a41186a200329030037030020024188026a41106a200429030037030020024188026a41086a2005290300370300200220022903e80437038802200241c8036a41186a2201200241e8036a41186a290300370300200241c8036a41106a2203200241e8036a41106a290300370300200241c8036a41086a2204200241e8036a41086a290300370300200220022903e8033703c803200241a8036a41186a200241c8046a41186a290300370300200241a8036a41106a200241c8046a41106a290300370300200241a8036a41086a200241c8046a41086a290300370300200220022903c8043703a803200241e8026a41386a20024188046a41386a290300370300200241e8026a41306a20024188046a41306a290300370300200241e8026a41286a20024188046a41286a290300370300200241e8026a41206a20024188046a41206a290300370300200241e8026a41186a20024188046a41186a290300370300200241e8026a41106a20024188046a41106a290300370300200241e8026a41086a20024188046a41086a29030037030020022002290388043703e802200241e8016a41186a2001290300370300200241e8016a41106a2003290300370300200241e8016a41086a2004290300370300200220022903c8033703e801420021090c060b200441ff0171450d0c200241003a00a80a0c0c0b200441ff0171450d0b200241003a00a80a0c0b0b200441ff0171450d0a200241003a00c80a0c0a0b200441ff0171450d09200241003a00a80a0c090b200441ff0171450d08200241003a00c80a0c080b2001280200220328020422044108490d072003280200220529000021082003200441786a3602042003200541086a36020041002104200241003a00a80a0340200128020022032802042205450d02200241880a6a20046a200328020022072d00003a000020032005417f6a3602042003200741016a3602002002200441016a22033a00a80a2003210420034120470d000b200241d00a6a41186a200241880a6a41186a2903002209370300200241c8096a41086a2203200241880a6a41086a290300370300200241c8096a41106a2204200241880a6a41106a290300370300200241c8096a41186a22052009370300200220022903880a3703c809200241e8036a41186a2005290300370300200241e8036a41106a2004290300370300200241e8036a41086a2003290300370300200220022903c8093703e80341002104200241003a00a80a0340200128020022032802042205450d03200241880a6a20046a200328020022072d00003a000020032005417f6a3602042003200741016a3602002002200441016a22033a00a80a2003210420034120470d000b200241d00a6a41186a200241880a6a41186a2903002209370300200241c8096a41086a2204200241880a6a41086a290300370300200241c8096a41106a2205200241880a6a41106a290300370300200241c8096a41186a22072009370300200220022903880a3703c80920012802002203280204220a4104490d072003280200220b280000210c2003200a417c6a3602042003200b41046a360200200241e8066a41086a2004290300370300200241e8066a41106a2005290300370300200241e8066a41186a2007290300370300200220022903c8093703e80641002104200241003a00c80a0340200128020022032802042205450d04200241880a6a20046a200328020022072d00003a000020032005417f6a3602042003200741016a3602002002200441016a22033a00c80a20032104200341c000470d000b200241d00a6a41086a2203200241880a6a41086a290300370300200241d00a6a41106a2204200241880a6a41106a290300370300200241d00a6a41186a2205200241880a6a41186a290300370300200241d00a6a41206a2207200241880a6a41206a290300370300200241d00a6a41286a220a200241880a6a41286a290300370300200241d00a6a41306a220b200241880a6a41306a290300370300200241d00a6a41386a220d200241880a6a41386a290300370300200220022903880a3703d00a200241c8096a41086a2003290300220e370300200241c8096a41106a20042903002209370300200241c8096a41186a2005290300220f370300200241c8096a41206a20072903002210370300200241c8096a41286a200a2903002211370300200241c8096a41306a200b2903002212370300200241c8096a41386a2203200d290300370300200220022903d00a22133703c80920024188076a41306a201237030020024188076a41286a201137030020024188076a41206a201037030020024188076a41186a200f37030020024188076a41106a200937030020024188076a41386a2003290300221437030020024188066a41306a2203201237030020024188066a41286a2204201137030020024188066a41206a2205201037030020024188066a41186a2207200f37030020024188066a41106a220a200937030020024188066a41086a220b200e37030020024188066a41386a220d20143703002002201337038806200241c8066a41186a2215200241e8066a41186a290300370300200241c8066a41106a2216200241e8066a41106a290300370300200241c8066a41086a2217200241e8066a41086a290300370300200220022903e8063703c806200241a8056a41186a22182015290300370300200241a8056a41106a22152016290300370300200241a8056a41086a22162017290300370300200220022903c8063703a805200241e8046a41386a2217200d290300370300200241e8046a41306a220d2003290300370300200241e8046a41286a22032004290300370300200241e8046a41206a22042005290300370300200241e8046a41186a22052007290300370300200241e8046a41106a2207200a290300370300200241e8046a41086a220a200b29030037030020022002290388063703e804200241c8046a41186a2018290300370300200241c8046a41106a2015290300370300200241c8046a41086a2016290300370300200220022903a8053703c80420024188046a41386a201729030037030020024188046a41306a200d29030037030020024188046a41286a200329030037030020024188046a41206a200429030037030020024188046a41186a200529030037030020024188046a41106a200729030037030020024188046a41086a200a290300370300200220022903e8043703880441002104200241003a00a80a0340200128020022032802042205450d05200241880a6a20046a200328020022072d00003a000020032005417f6a3602042003200741016a3602002002200441016a22033a00a80a2003210420034120470d000b200241d00a6a41186a200241880a6a41186a2903002209370300200241c8096a41086a2204200241880a6a41086a290300370300200241c8096a41106a2205200241880a6a41106a290300370300200241c8096a41186a22072009370300200220022903880a3703c80920012802002203280204220a4104490d072003280200220d280000210b2003200a417c6a3602042003200d41046a360200200241e8066a41086a2004290300370300200241e8066a41106a2005290300370300200241e8066a41186a2007290300370300200220022903c8093703e80641002104200241003a00c80a0340200128020022032802042205450d06200241880a6a20046a200328020022072d00003a000020032005417f6a3602042003200741016a3602002002200441016a22033a00c80a20032104200341c000470d000b200241d00a6a41086a2201200241880a6a41086a290300370300200241d00a6a41106a2203200241880a6a41106a290300370300200241d00a6a41186a2204200241880a6a41186a290300370300200241d00a6a41206a2205200241880a6a41206a290300370300200241d00a6a41286a2207200241880a6a41286a290300370300200241d00a6a41306a220a200241880a6a41306a290300370300200241d00a6a41386a220d200241880a6a41386a290300370300200220022903880a3703d00a200241c8096a41386a2215200d290300370300200241c8096a41306a200a2903002209370300200241c8096a41286a2007290300220f370300200241c8096a41206a20052903002210370300200241c8096a41186a20042903002211370300200241c8096a41106a20032903002212370300200241c8096a41086a2001290300220e370300200220022903d00a22133703c80920024188076a41306a2201200937030020024188076a41286a2203200f37030020024188076a41206a2204201037030020024188076a41186a2205201137030020024188076a41106a2207201237030020024188076a41086a220a200e37030020024188076a41386a220d2015290300370300200220133703880720024188066a41386a2215200d29030037030020024188066a41306a220d200129030037030020024188066a41286a2201200329030037030020024188066a41206a2203200429030037030020024188066a41186a2204200529030037030020024188066a41106a2205200729030037030020024188066a41086a2207200a290300370300200220022903880737038806200241c8066a41186a220a200241e8066a41186a290300370300200241c8066a41106a2216200241e8066a41106a290300370300200241c8066a41086a2217200241e8066a41086a290300370300200220022903e8063703c806200241a8056a41186a2218200a290300370300200241a8056a41106a220a2016290300370300200241a8056a41086a22162017290300370300200220022903c8063703a805200241e8046a41386a22172015290300370300200241e8046a41306a2215200d290300370300200241e8046a41286a220d2001290300370300200241e8046a41206a22012003290300370300200241e8046a41186a22032004290300370300200241e8046a41106a22042005290300370300200241e8046a41086a2205200729030037030020022002290388063703e804200241c8026a41186a2018290300370300200241c8026a41106a200a290300370300200241c8026a41086a2016290300370300200220022903a8053703c80220024188026a41386a201729030037030020024188026a41306a201529030037030020024188026a41286a200d29030037030020024188026a41206a200129030037030020024188026a41186a200329030037030020024188026a41106a200429030037030020024188026a41086a2005290300370300200220022903e80437038802200241c8036a41186a2201200241e8036a41186a290300370300200241c8036a41106a2203200241e8036a41106a290300370300200241c8036a41086a2204200241e8036a41086a290300370300200220022903e8033703c803200241a8036a41186a200241c8046a41186a290300370300200241a8036a41106a200241c8046a41106a290300370300200241a8036a41086a200241c8046a41086a290300370300200220022903c8043703a803200241e8026a41386a20024188046a41386a290300370300200241e8026a41306a20024188046a41306a290300370300200241e8026a41286a20024188046a41286a290300370300200241e8026a41206a20024188046a41206a290300370300200241e8026a41186a20024188046a41186a290300370300200241e8026a41106a20024188046a41106a290300370300200241e8026a41086a20024188046a41086a29030037030020022002290388043703e802200241e8016a41186a2001290300370300200241e8016a41106a2003290300370300200241e8016a41086a2004290300370300200220022903c8033703e801420121090b200241c8016a41186a2201200241a8036a41186a290300370300200241c8016a41106a2203200241a8036a41106a290300370300200241c8016a41086a2204200241a8036a41086a29030037030020024188016a41086a2205200241e8026a41086a29030037030020024188016a41106a2207200241e8026a41106a29030037030020024188016a41186a220a200241e8026a41186a29030037030020024188016a41206a220d200241e8026a41206a29030037030020024188016a41286a2215200241e8026a41286a29030037030020024188016a41306a2216200241e8026a41306a29030037030020024188016a41386a2217200241e8026a41386a290300370300200220022903a8033703c801200220022903e80237038801200241e8006a41186a2218200241c8026a41186a290300370300200241e8006a41106a2219200241c8026a41106a290300370300200241e8006a41086a221a200241c8026a41086a290300370300200241286a41386a221b20024188026a41386a290300370300200241286a41306a221c20024188026a41306a290300370300200241286a41286a221d20024188026a41286a290300370300200241286a41206a221e20024188026a41206a290300370300200241286a41186a221f20024188026a41186a290300370300200241286a41106a222020024188026a41106a290300370300200241286a41086a222120024188026a41086a290300370300200220022903c8023703682002200229038802370328200241086a41186a2222200241e8016a41186a290300370300200241086a41106a2223200241e8016a41106a290300370300200241086a41086a2224200241e8016a41086a290300370300200220022903e801370308200041186a200c360200200020083703102000200937030820002006370300200020022903c80137021c200041246a20042903003702002000412c6a2003290300370200200041346a2001290300370200200020022903880137023c200041c4006a2005290300370200200041cc006a2007290300370200200041d4006a200a290300370200200041dc006a200d290300370200200041e4006a2015290300370200200041ec006a2016290300370200200041f4006a20172903003702002000200b36027c20004198016a201829030037020020004190016a201929030037020020004188016a201a29030037020020004180016a2002290368370200200041d8016a201b290300370200200041d0016a201c290300370200200041c8016a201d290300370200200041c0016a201e290300370200200041b8016a201f290300370200200041b0016a2020290300370200200041a8016a2021290300370200200041a0016a2002290328370200200041f8016a2022290300370300200041f0016a2023290300370300200041e8016a2024290300370300200041e0016a20022903083703000c070b200441ff0171450d05200241003a00a80a0c050b200441ff0171450d04200241003a00a80a0c040b200441ff0171450d03200241003a00c80a0c030b200441ff0171450d02200241003a00a80a0c020b200441ff0171450d01200241003a00c80a0c010b200042023703080c010b200042023703080b200241d00d6a24000bdc1704087f037e037f027e230041a0086b220224000240024002400240024002400240024002400240024002400240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020020060e06010203040506070b200041073a00000c0a0b20024190046a200110e40102402002280290042207450d0020022802940421080240200128020022032802042204450d0020024198046a2802002109200328020022052d0000210620032004417f6a3602042003200541016a3602004100210302400240024020060e020100030b41002104200241003a00b0040340200128020022032802042205450d0220024190046a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00b0042003210420034120470d000b200241e0016a41086a20024190046a41086a290300220a37030020024190016a41186a20024190046a41186a290300220b37030020024190016a41106a20024190046a41106a290300220c370300200241c0016a41186a200b370300200241c0016a41106a200c370300200241c0016a41086a200a37030020022002290390043703c001410121030b200241f0006a41186a2204200241c0016a41186a290300370300200241f0006a41106a2205200241c0016a41106a290300370300200241f0006a41086a2206200241c0016a41086a290300370300200220022903c00137037020012802002201280204220d4104490d092001280200220e280000210f2001200d417c6a3602042001200e41046a360200200241d0006a41086a2006290300220a370300200241d0006a41106a2005290300220b370300200241d0006a41186a2004290300220c370300200220022903702210370350200020033a0001200041013a0000200041026a20103700002000410a6a200a370000200041126a200b3700002000411a6a200c370000200041306a200f3602002000412c6a2009360100200041286a2008360100200041246a2007360100200041226a20022f014e3b01000c0c0b200441ff0171450d00200241003a00b0040b200041073a00000c080b200041073a00000c090b2001200128020441016a220336020402400240200320012802084b0d0020024190046a20011095012002280290042103200241e0016a20024190046a41047241ac0210e9081a2003411c460d0020024190046a200241e0016a41ac0210e9081a41b002102c22040d010c0b0b200041073a00000c090b20042003360200200441046a20024190046a41ac0210e9081a20012001280204417f6a360204200241086a200110ad012002280208450d07200041073a00002004108b022004102e0c080b200241186a200110ad0102400240024020022802180d00200228021c21052001200128020441016a2203360204200320012802084b0d0120024190046a20011095012002280290042103200241e0016a20024190046a41047241ac0210e9081a2003411c460d0120024190046a200241e0016a41ac0210e9081a41b002102c2204450d0b20042003360200200441046a20024190046a41ac0210e9081a20012001280204417f6a360204200241106a200110ad0120022802100d0220022802142101200041033a0000200020022f00c0013b00012000410c6a2001360200200041086a2004360200200041046a2005360200200041106a200229039001370300200041036a200241c2016a2d00003a0000200041186a20024190016a41086a290300370300200041206a20024190016a41106a290300370300200041286a20024190016a41186a290300370300200041306a20024190016a41206a2903003703000c0a0b200041073a00000c090b200041073a00000c080b200041073a00002004108b022004102e0c070b41002104200241003a00b004024002400240024002400340200128020022032802042205450d0120024190046a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00b0042003210420034120470d000b200241e0016a41186a20024190046a41186a290300220a37030020024190016a41086a20024190046a41086a29030037030020024190016a41106a20024190046a41106a29030037030020024190016a41186a200a370300200220022903900437039001200241206a200110ad0120022802200d01200128020022012802042203450d0420022802242106200128020022042d0000210520012003417f6a3602042001200441016a3602004100210120050e020302040b0240200441ff0171450d00200241003a00b0040b200041073a00000c0a0b200041073a00000c090b410121010b200241c0016a41186a20024190016a41186a290300220a370300200241c0016a41106a20024190016a41106a290300220b370300200241c0016a41086a20024190016a41086a290300220c370300200220022903900122103703c001200041043a000020002010370001200041096a200c370000200041116a200b370000200041196a200a370000200041246a2006360200200041216a20013a0000200041286a2002290370370300200041306a200241f0006a41086a2903003703000c070b200041073a00000c060b41002104200241003a00b00402400240024002400340200128020022032802042205450d0120024190046a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00b0042003210420034120470d000b200241e0016a41186a20024190046a41186a290300220a37030020024190016a41086a20024190046a41086a29030037030020024190016a41106a20024190046a41106a29030037030020024190016a41186a200a370300200220022903900437039001200241c0006a200110ad0120022802400d0120022802442103200241306a200110da042002290330a70d022002290338210a200241286a200110ad0120022802280d03200228022c2101200241c0016a41186a20024190016a41186a290300220b370300200241c0016a41106a20024190016a41106a290300220c370300200241c0016a41086a20024190016a41086a2903002210370300200220022903900122113703c001200041053a000020002011370001200041096a2010370000200041116a200c370000200041196a200b370000200041216a20022f00703b0000200041236a200241f2006a2d00003a0000200041306a200a370300200041286a2001360200200041246a20033602000c090b0240200441ff0171450d00200241003a00b0040b200041073a00000c080b200041073a00000c070b200041073a00000c060b200041073a00000c050b41002104200241003a00b00402400340200128020022032802042205450d0120024190046a20046a200328020022062d00003a000020032005417f6a3602042003200641016a3602002002200441016a22033a00b0042003210420034120470d000b200241e0016a41186a20024190046a41186a290300220a37030020024190016a41086a220120024190046a41086a29030037030020024190016a41106a220320024190046a41106a29030037030020024190016a41186a2204200a370300200220022903900437039001200041063a00002000200229039001370001200041096a2001290300370000200041116a2003290300370000200041196a2004290300370000200041216a20022900c001370000200041296a200241c0016a41086a290000370000200041306a200241cf016a2900003700000c050b0240200441ff0171450d00200241003a00b0040b200041073a00000c040b200041073a00000c030b200041073a00000b200841ffffff3f71450d012007102e0c010b200228020c2101200041023a0000200020022f00c0013b0001200041086a2001360200200041046a20043602002000410c6a200229029001370200200041036a200241c0016a41026a2d00003a0000200041146a20024190016a41086a2902003702002000411c6a200241a0016a290200370200200041246a200241a8016a2902003702002000412c6a200241b0016a290200370200200041346a200241b8016a2802003602000b200241a0086a24000f0b1036000beb0401057f23004180056b2202240002400240024002400240024002400240024002400240200128020022032802042204450d00200328020022052d0000210620032004417f6a3602042003200541016a36020020060e03010203040b200041043b01000c090b2002200110ad0102402002280200450d00200241003602200c080b200241206a200120022802041094012002280220450d07200241da026a200241206a41086a280200360100200220022903203701d202200041013b0100200020022901d002370102200041086a200241d6026a2901003701000c080b024002402001280200220328020422044102490d00200328020022052f0000210620032004417e6a3602042003200541026a3602002001200128020441016a2203360204200320012802084b0d01200241d0026a200110950120022802d0022103200241206a200241d0026a41047241ac0210e9081a2003411c460d01200241d0026a200241206a41ac0210e9081a41b002102c2204450d0620042003360200200441046a200241d0026a41ac0210e9081a200041046a2004360200200020063b0102200041023b010020012001280204417f6a3602040c090b200041043b01000c080b200041043b01000c070b200241086a200110ad012002280208450d01200241003602200c020b200041043b01000c050b200241206a2001200228020c10940120022802200d020b200041043b01000c030b1036000b200241da026a200241206a41086a280200360100200220022903203701d202200041033b0100200020022901d002370102200041086a200241d6026a2901003701000c010b200041043b01000b20024180056a24000ba40e01127f230041b0026b2203240020012802002104200128020422052f01062106200341f0006a41386a2207200541086a2208200128020822094106746a220141386a290000370300200341f0006a41306a220a200141306a290000370300200341f0006a41286a220b200141286a290000370300200341f0006a41206a220c200141206a290000370300200341f0006a41186a220d200141186a290000370300200341f0006a41106a220e200141106a290000370300200341f0006a41086a220f200141086a2900003703002003200129000037037020012008200941016a22104106746a20062009417f736a220841067410ea081a200341b0016a41186a2211200541c8056a221220094105746a220141186a290000370300200341b0016a41106a2213200141106a290000370300200341b0016a41086a2214200141086a290000370300200320012900003703b0012001201220104105746a200841057410ea081a20052006417f6a22013b0106200341d0016a41386a2007290300370300200341d0016a41306a200a290300370300200341d0016a41286a200b290300370300200341d0016a41206a200c290300370300200341d0016a41186a200d290300370300200341d0016a41106a200e290300370300200341d0016a41086a200f29030037030020034198026a2014290300370300200341a0026a2013290300370300200341a8026a2011290300370300200320032903703703d001200320032903b00137039002200341106a200341d0016a41e00010e9081a200341d0016a200341106a41e00010e9081a0240200141ffff037141044b0d0002400240024020052802002206450d00200441016a21080240024020052f010422070d0020062f01060d01200341246a4101360200200342013702142003419cc3cb0036021020034104360274200341849dc7003602702003200341f0006a360220200341106a418c9dc7001044000b024020062007417f6a22074102746a41a8086a280200220a2f0106200141ffff03716a41016a410b4b0d00200341286a2005360200200341206a200a360200200320043602242003200436021c200320073602182003200636021420032008360210200341b0016a200341106a4101200910cf060c040b200341286a2005360200200341206a200a360200200320043602242003200436021c200320073602182003200636021420032008360210200341106a410110d006200320103602b8010c020b0240200141ffff0371200741027420066a41ac086a28020022012f01066a41016a410b4b0d00200341286a2001360200200341206a2005360200200320043602242003200436021c200320073602182003200636021420032008360210200341b0016a200341106a4100200910cf060c030b200341286a2001360200200341206a2005360200200320043602242003200436021c200320073602182003200636021420032008360210200341106a410110d1060b200320093602b8010b200320053602b401200320043602b0010b20032802b801210920032802b001210420032802b40122052802002201450d0020012f0106220741044b0d00200141066a2108200441016a21060240034020012802002210450d01200741ffff0371210b200641016a210a024002400240024020012f010422070d0020102f01060d01200341246a4101360200200342013702142003419cc3cb0036021020034104360274200341849dc7003602702003200341f0006a360220200341106a418c9dc7001044000b20102007417f6a220c4102746a41a8086a28020021072003200136028801200320063602840120032007360280012003200636027c2003200c360278200320103602742003200a360270024020072f010620082f01006a41016a410b4b0d00200341106a41186a200341f0006a41186a280200360200200341106a41106a200341f0006a41106a290300370300200341106a41086a200341f0006a41086a29030037030020032003290370370310200341086a200341106a10d206200328020c2101200328020821060c030b200341f0006a4105200b6b10d0060c010b2003200741027420106a41ac086a280200220c36028801200320063602840120032001360280012003200636027c20032007360278200320103602742003200a360270024020082f0100200c2f01066a41016a410b4b0d00200341106a41186a200341f0006a41186a280200360200200341106a41106a200341f0006a41106a290300370300200341106a41086a200341f0006a41086a290300370300200320032903703703102003200341106a10d20620032802042101200328020021060c020b200341f0006a4105200b6b10d1060b410021010b2001450d02200141066a210820012f0106220741044d0d000c020b0b200741ffff03710d00200241013a00000b2000200341d0016a41e00010e908220141e8006a2009360200200141e4006a200536020020012004360260200341b0026a24000bc50701167f230041e0006b22042400024002400240200141186a28020022052f01062206200141106a28020022072f0106220820021b2003490d00200841016a220920066a220a410c4f0d01200128020c210b2001280208210c2001280200210d2001280204220e2f0106210f2007200a3b0106200441386a2210200e41086a2211200c4106746a221241386a290000370300200441306a2213201241306a290000370300200441286a2214201241286a290000370300200441206a2215201241206a290000370300200441186a2216201241186a290000370300200441106a2217201241106a290000370300200441086a2218201241086a2900003703002004201229000037030020122011200c41016a22014106746a200f200c417f736a221141067410ea081a200741086a221920084106746a221241386a2010290300370000201241306a2013290300370000201241286a2014290300370000201241206a2015290300370000201241186a2016290300370000201241106a2017290300370000201241086a201829030037000020122004290300370000201920094106746a200541086a200641067410e9081a200441c0006a41186a2210200e41c8056a2213200c4105746a221241186a290000370300200441c0006a41106a2214201241106a290000370300200441c0006a41086a2215201241086a290000370300200420122900003703402012201320014105746a201141057410ea081a200741c8056a221120084105746a221241186a2010290300370000201241106a2014290300370000201241086a201529030037000020122004290340370000201120094105746a200541c8056a200641057410e9081a200e41a8086a221220014102746a200c410274220c20126a41086a200f2001417f736a41027441046a10ea081a02402001200f4f0d00200c200e6a41ac086a211203402012280200220c20013b0104200c200e360200201241046a2112200f200141016a2201470d000b0b200e200e2f0106417f6a3b01060240200d4102490d002006200a20096b470d03200720094102746a41a8086a200541a8086a200641016a41027410e9081a200a20084d0d00200641016a210c200720084102746a41ac086a21012009211203402001280200220e20123b0104200e2007360200200141046a2101201241016a2112200c417f6a220c0d000b0b2005102e200020073602042000200b36020020002009410020021b20036a360208200441e0006a24000f0b41f09fc7004191014184a1c7001039000b419c9dc700412a41c89dc7001039000b41f49bc7004128419c9cc7001039000be307040c7f017e017f0c7e0240024002400240200041186a2802002f0106220220016a2203410c4f0d00200041106a28020022042f010622052001490d012004200520016b22063b0106200041186a220428020020033b0106200428020041086a220720014106746a2007200241067410ea081a200428020041c8056a220720014105746a2007200241057410ea081a2005200641016a22076b22022001417f6a470d02200428020041086a200041106a220828020020074106746a41086a2002410674220910e9081a200428020041c8056a200828020020074105746a41c8056a2002410574220a10e9081a200041046a280200220b2000280208220c4106746a220241c0006a220d290000210e2008280200220f20064105746a220541e0056a2900002110200541c8056a2900002111200541d0056a2900002112200541d8056a2900002113200f20064106746a220641086a2900002114200641106a2900002115200641186a2900002116200641206a2900002117200641286a2900002118200641306a2900002119200641386a290000211a200d200641c0006a290000370000200241386a2206290000211b2006201a370000200241306a2206290000211a20062019370000200241286a2206290000211920062018370000200241206a2206290000211820062017370000200241186a2206290000211720062016370000200241106a2206290000211620062015370000200241086a2202290000211520022014370000200b200c4105746a220241d8056a2206290000211420062013370000200241d0056a2206290000211320062012370000200241c8056a2206290000211220062011370000200241e0056a2202290000211120022010370000200428020020096a220241c0006a200e370000200241386a201b370000200241306a201a370000200241286a2019370000200241206a2018370000200241186a2017370000200241106a2016370000200241086a20153700002004280200200a6a220241e0056a2011370000200241d8056a2014370000200241d0056a2013370000200241c8056a2012370000200028020c21020240024020002802140d002002450d010c050b2002450d04200828020021022004280200220641a8086a2200200141027422046a2000200320016b41027441046a10ea081a2000200220074102746a41a8086a200410e9081a200341016a21044100210103402000280200220220013b010420022006360200200041046a21002004200141016a2201470d000b0b0f0b41e49ec700413341989fc7001039000b41a89fc700412741d09fc7001039000b41f49bc7004128419c9cc7001039000b41e2a0cc00412841e09fc7001039000bb60806097f017e037f047e017f087e0240024002400240200041106a28020022022f0106220320016a2204410c4f0d00200041186a2802002f010622052001490d01200220043b0106200041186a2206280200200520016b22073b0106200041046a2802002208200028020822094106746a220241206a220a290000210b2006280200220c2001417f6a220d410574220e6a220541e0056a290000210f200541c8056a2900002110200541d0056a2900002111200541d8056a2900002112200c200d41067422136a220541286a2900002114200541306a2900002115200541386a2900002116200541c0006a2900002117200541086a2900002118200541106a2900002119200541186a290000211a200a200541206a290000370000200241186a2205290000211b2005201a370000200241106a2205290000211a20052019370000200241086a2205290000211920052018370000200241c0006a2205290000211820052017370000200241386a2205290000211720052016370000200241306a2205290000211620052015370000200241286a2202290000211520022014370000200820094105746a220241d8056a2205290000211420052012370000200241d0056a2205290000211220052011370000200241c8056a2205290000211120052010370000200241e0056a220229000021102002200f370000200041106a220528020020034106746a220241c0006a2018370000200241386a2017370000200241306a2016370000200241286a2015370000200241206a200b370000200241186a201b370000200241106a201a370000200241086a2019370000200528020020034105746a220241e0056a2010370000200241d8056a2014370000200241d0056a2012370000200241c8056a2011370000200d2004200341016a22026b470d02200528020020024106746a41086a200628020041086a201310e9081a200528020020024105746a41c8056a200628020041c8056a200e10e9081a200628020041086a220d200d20014106746a200741067410ea081a200628020041c8056a220d200d20014105746a200741057410ea081a200028020c210d0240024020002802140d00200d450d010c050b200d450d042005280200220d20024102746a41a8086a2006280200220641a8086a22002001410274220510e9081a2000200020056a200741027441046a10ea081a0240200420034d0d002003410274200d6a41ac086a210003402000280200220520023b01042005200d360200200041046a2100200241016a21022001417f6a22010d000b0b2007417f460d00200641a8086a2102200741016a21054100210003402002280200220120003b010420012006360200200241046a21022005200041016a2200470d000b0b0f0b41d89dc7004132418c9ec7001039000b419c9ec700412841c49ec7001039000b41f49bc7004128419c9cc7001039000b41e2a0cc00412841d49ec7001039000b8c0701157f230041e0006b2202240002400240200141106a28020022032f0106220441016a2205200141186a28020022062f010622076a2208410c4f0d00200128020821092001280200210a2001280204220b2f0106210c200320083b0106200241386a220d200b41086a220e20094106746a220f41386a290000370300200241306a2210200f41306a290000370300200241286a2211200f41286a290000370300200241206a2212200f41206a290000370300200241186a2213200f41186a290000370300200241106a2214200f41106a290000370300200241086a2215200f41086a2900003703002002200f290000370300200f200e200941016a22014106746a200c2009417f736a220e41067410ea081a200341086a221620044106746a220f41386a200d290300370000200f41306a2010290300370000200f41286a2011290300370000200f41206a2012290300370000200f41186a2013290300370000200f41106a2014290300370000200f41086a2015290300370000200f2002290300370000201620054106746a200641086a200741067410e9081a200241c0006a41186a220d200b41c8056a221020094105746a220f41186a290000370300200241c0006a41106a2211200f41106a290000370300200241c0006a41086a2212200f41086a2900003703002002200f290000370340200f201020014105746a200e41057410ea081a200341c8056a220e20044105746a220f41186a200d290300370000200f41106a2011290300370000200f41086a2012290300370000200f2002290340370000200e20054105746a200641c8056a200741057410e9081a200b41a8086a220f20014102746a20094102742209200f6a41086a200c2001417f736a41027441046a10ea081a02402001200c4f0d002009200b6a41ac086a210f0340200f280200220920013b01042009200b360200200f41046a210f200c200141016a2201470d000b0b200b200b2f0106417f6a3b01060240200a4102490d002007200820056b470d02200320054102746a41a8086a200641a8086a200741016a41027410e9081a200820044d0d00200741016a210f200441027420036a41ac086a210103402001280200220920053b010420092003360200200141046a2101200541016a2105200f417f6a220f0d000b0b2006102e2000200b3602042000200a360200200241e0006a24000f0b419c9dc700412a41c89dc7001039000b41f49bc7004128419c9cc7001039000b130020004108360204200041a8a1c7003602000bb90706057f017e017f017e037f037e23004180016b22022400200241106a200110d8062002280210210120022002280218220336022420022001360220200241286a2001200310ed02024002400240024020022802282204450d00200228022c21052002200241306a28020036023c20022004360238200241086a200241386a10ab010240024020022802080d0002400240200228020c2206200228023c4105762201200120064b1b22014105742203417f4c0d000240024020010d00410821030c010b2003102c2203450d080b2001ad2107024002402006450d00200241d8006a41036a21080340200241e8006a200241386a10a50120022d00684101460d04200228023c22014110490d04200229006921092002200141706a220a36023c20022002280238220b41106a220c360238200a450d04200b41086a290000210d200b290000210e20022001416f6a36023c2002200c41016a3602384100210b024002400240200c2d00000e03020001070b4101210b0c010b4102210b0b20022002280058360240200220082800003600432002200228004336005320022002280240360250200220022802503602482002200228005336004b02402007422088220fa722012007a7470d00200141016a220c2001490d042001410174220a200c200c200a491b220c4104200c41044b1b220c41ffffff3f71200c46410374210a200c410574210c0240024020010d00200241003602680c010b20024108360270200220033602682002200f4205863e026c0b200241d8006a200c200a200241e8006a107d2002280260210c20022802584101460d03200228025c2103200742808080807083200c410576ad8421070b200320014105746a2201200b3a00182001200d3703082001200e37030020012009370310200120022802483600192001411c6a200228004b36000020074280808080107c21072006417f6a22060d000b0b2003450d030c040b200c0d070b1038000b0240200742ffffff3f83500d002003102e0b0b4100210320024100360260200242013703582002410a3602442002200241206a3602402002200241d8006a360250200241fc006a41013602002002420137026c200241909dc5003602682002200241c0006a360278200241d0006a419cebc000200241e8006a103d1a2002280258200228026010ef02200228025c450d002002280258102e0b02402005450d002004102e0b20030d010b20004100360208200042083702000c010b20002007370204200020033602000b02402002280214450d002002280210102e0b20024180016a24000f0b1036000bf91106027f0a7e017f017e037f047e230041a0026b22032400200341c0006a200010c802200341a0016a20032802402204200328024810c902200341a0016a41386a2903002105200341a0016a41306a2903002106200341a0016a41286a2903002107200341a0016a41206a2903002108200341a0016a41186a2903002109200341a0016a41106a290300210a200341e0016a290300210b20032903a801210c20032903a001210d200341f0006a41086a200341f0016a2903003703002003200341e8016a29030037037002400240200d4201510d0042002108200341386a4200370300200341306a4200370300200341286a4200370300200341206a4200370300200341186a4200370300200341106a4200370300200341086a4200370300200342003703004200210c4200210a4200210942002107420021064200210d420021050c010b200341206a2007370300200341286a2006370300200341106a2009370300200341306a2005370300200320083703182003200c3703002003200b3703382003200a370308200c210d200a21050b02402003280244450d002004102e0b02400240200d2005844200520d0020072003290310842006200341186a29030084844200520d002003290330200341386a2903008450450d004200210e4100210f0c010b4201210e4101210f0b420021100240200e4201510d004200210c4200210a42002109420021080b0240024020020d00420021054200210b420021070c010b2002410574211142002110420021054200210b42002107200121040340024002400240200441186a2d00002212417f6a41ff017141014b0d002007200441086a2903002206200b2004290300220d56200720065620072006511b22131b2107200b200d20131b210b201241ff01714102460d010c020b201241ff01710d01200441086a29030021062004290300210d0b200520062010200d56200520065620052006511b22121b21052010200d20121b21100b200441206a2104201141606a22110d000b0b200341d8016a2005370300200341c8016a221120073703002003200c3703a001200320103703d0012003200b3703c001200320083703b8012003200a3703a801200320093703b001420021074201210d200e420152ad210b02400240427f200c20097c22062006200c542204200a20087c2004ad7c2206200a542006200a511b22041b221042ffc7afa02556427f200620041b22064200522006501b0d002009200c842008200a848422075021044200210d2007420052ad21070c010b200341d0016a290300211420112903002115200341c0016a2903002116200341b0016a290300210e20032903b801211720032903a801210820032903a0012109410121040b200341e8006a2006370300200341e0006a22112010370300200341d0006a200a3703002003200c370348200320073703582003200b3703400240024002400240200f200d420152720d00200320003602a0012000200341a0016a10bd060c010b0240200f4101732212200d420151720d00200320003602a0012000200341a0016a10be0641ff017122124103460d01024020120e03030200030b20040d03200320113602a001200341a0016a10cc020c030b200d4201522012710d010b20034180016a200010c802200341a0016a2003280280012211200328028801221210c90220032903a0012106200341f0006a41086a2204200341f0016a2903003703002003200341e8016a2903003703700240024020064201510d0020034190016a41086a420037030020034200370390010c010b20034190016a41086a200429030037030020032003290370370390010b200341e8016a200329039001370300200341f0016a20034190016a41086a290300370300200342013703a001200341d8016a20144200200d42015122041b370300200341d0016a2015420020041b370300200341a0016a41286a2016420020041b370300200341c0016a2017420020041b370300200341b8016a200e420020041b370300200341a0016a41106a2008420020041b370300200341e0016a2005420020041b37030020032009420020041b3703a80120112012200341a0016a41086a10c8050240200328028401450d002011102e0b200341c0006a41106a290300210a200341c0006a41286a29030021062003290348210c200329036021102003290340210b200329035821070b0240200b4201520d00200341d8016a200a370300200341d0016a200c370300200341a0016a41086a41003a0000200341a9016a2000290000370000200341b1016a200041086a290000370000200341b9016a200041106a290000370000200341c1016a200041186a290000370000200341033a00a001200341a0016a10fe010b02400240200750450d00420021070c010b200341a0016a41186a200041186a290000370300200341a0016a41106a200041106a290000370300200341a0016a41086a200041086a290000370300200320002900003703a001420121070b200341186a200341a0016a41186a2204290300220d370300200341106a200341a0016a41106a22112903002205370300200341086a200341a0016a41086a290300220b370300200320032903a001220a370300200341d0016a2006370300200341c8016a221220103703002011200b37030020042005370300200341c0016a200d370300200320073703a0012003200a3703a801200341a0016a10d20420032903a001500d0020032012360240200341c0006a10cc020b200341a0016a200010d80620032802a001221120032802a801108f022104024020032802a401450d002011102e0b024002400240024020020d00200341a0016a200010d80620032802a001221120032802a80110ff01024020032802a401450d002011102e0b2004450d012000108a060c010b2003200010d80620024105744104722211417f4c0d0120032802082113200328020021122011102c220f450d02200341003602a801200320113602a4012003200f3602a0012002200341a0016a107620012002200341a0016a109e012012201320032802a001221120032802a80110b201024020032802a401450d002011102e0b02402003280204450d002012102e0b20040d0020001083061a0b200341a0026a24000f0b1038000b1036000bc70101047f230041c0006b220224004109210341ceeac7002104410221050240024002400240200141ff01710e0400010203000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602242002418883ca003602202002200241206a360218200241086a41b4eac7001044000b410a210341c4eac7002104410021050c010b411721034194a4c7002104410121050b20004183323b0100200041086a2003360200200041046a2004360200200041026a20053a0000200241c0006a24000bcf0202027f047e230041f0006b220724000240024020022003844200520d00200041063a00000c010b200741e0006a200110c802200741086a20072802602208200728026810c90220072903084201512101200741386a2903002102200741306a2903002103200741c8006a2903002109200741c0006a290300210a02402007280264450d002008102e0b2002420020011b210b2003420020011b210c2009420020011b2102200a420020011b210302400240024041004102410120044101711b200441ff01714101461b0e03020100020b200b2002200c200356200b200256200b2002511b22011b2102200c200320011b21030c010b200c2103200b21020b02402003200558200220065820022006511b0d00200041830a3b0100200041086a4115360200200041046a41a0a3c700360200200041026a41013a00000c010b200041063a00000b200741f0006a24000bac0201037f230041e0006b22022400200241f8fcc6004108108102200241106a41f0faca004105108102024002404120102c2203450d002002422037023420022003360230200241306a200141201074200241c0006a200228023022012002280238220310d803200241dc006a200120036a360200200220013602582002200241d0006a3602542002200241c0006a360250200241206a200241d0006a107c02402002280234450d002001102e0b2002280228220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b20004100360208200020013602042000200436020020002002411010742000200241106a411010742000200228022022012003107402402002280224450d002001102e0b200241e0006a24000f0b1036000b1038000b8e3504087f017e047f0d7e230041a0036b2201240020014190016a2202420037030020014188016a22034200370300200141f8006a41086a2204420037030020014200370378200141b0026a41a0dac800410f1081022004200141b0026a41086a2205290000370300200120012900b002370378200141b0026a41afdac800410d10810220022005290000370300200320012900b00237030020014120360294032001200141f8006a36029003200141e8006a200141f8006a412010ed0202400240200128026822020d00410221040c010b200128026c21062001200141e8006a41086a28020022043602e402200120023602e0020240024020044104490d00200228000021052001200241046a3602e00220012004417c6a22073602e40220074104490d00200228000421072001200441786a3602e4022001200241086a3602e002200141e0006a200141e0026a10ab0102402001280260450d00200141003602f0020c010b200141f0026a200141e0026a200128026410990120012802f0022208450d0020012902f402210941002104200141003a00d0020240024020012802e402220a450d0020012802e002220b2d0000210c2001200a417f6a220d3602e4022001200b41016a3602e0020240200c4101460d000c040b200d41044f0d010b0c020b200b280001210c2001200a417b6a3602e4022001200b41056a3602e002410121040c010b200141003602b802200142013703b0022001410a3602d402200120014190036a3602d0022001200141b0026a36029c0320014184036a4101360200200142013702f402200141909dc5003602f0022001200141d0026a360280032001419c036a419cebc000200141f0026a103d1a20012802b00220012802b80210ef02024020012802b402450d0020012802b002102e0b410221040b2006450d002002102e0b0240024002400240024002400240024020044102460d0020014188036a200c360200200141fc026a20093702002001200436028403200120083602f802200120073602f402200120053602f002200141f8026a2108024020052000470d00024020044101460d00200141b0026a200810e00120014188016a200736020020014184016a200141b8026a28020036020020014100360278200120012903b00237027c200141f8006a108c060c010b200141b0026a200810e0012001418c016a2007360200200141f8006a41086a20012903b00237030020014188016a200141b0026a41086a2802003602002001200c36027c20014101360278200141f8006a108c060b024020012802f40220012802f0026a2000470d0020014180036a28020041286c4105722202417f4c0d022002102c2204450d0620014100360280012001200236027c20012004360278200141013a00d002200141f8006a200141d0026a4101107420012802f80221022001280280032204200141f8006a10760240200441286c2204450d00200220046a21040340200141f8006a2002412010742001200241206a2903003703b002200141f8006a200141b0026a41081074200241286a22022004470d000b0b41bcdac80041142001280278220220012802800110b2010240200128027c450d002002102e0b200141f8006a41086a2202200829020037030020014188016a2204200841086a2802003602002001410036027c200141073a0078200141f8006a10fe0120014190016a4200370300200442003703002002420037030020014200370378200141b0026a41a0dac800410f1081022002200141b0026a41086a2204290000370300200120012900b002370378200141b0026a41afdac800410d108102200341086a2004290000370000200320012900b002370000200141f8006a412010ff010c010b20012802fc022202450d00200241286c450d0020012802f802102e0b20014190016a420037030020014188016a4200370300200141f8006a41086a2202420037030020014200370378200141b0026a41a0dac800410f1081022002200141b0026a41086a2204290000370300200120012900b002370378200141b0026a41d0dac8004105108102200341086a2004290000370000200320012900b002370000200141203602e4022001200141f8006a3602e002200141e8006a200141f8006a412010ed02024020012802682202450d00200141e8006a41086a2802002105200128026c210741002104200141003a00d0020240024002402005450d0002400240024020022d00000e0405000102030b2005417f6a4108490d0220022900012109410121040c040b410221040c020b2005417f6a4108490d0020022900012109410321040c020b200141003602b802200142013703b0022001410a3602d4022001200141e0026a3602d0022001200141b0026a3602900320014184036a4101360200200142013702f402200141909dc5003602f0022001200141d0026a3602800320014190036a419cebc000200141f0026a103d1a20012802b00220012802b80210ef02024020012802b402450d0020012802b002102e0b410421040b0b02402007450d002002102e0b024002402004417f6a0e03010200020b2009422088a7210202402009a722042000470d00200141043602782001200236027c200141f8006a108c060b200220046a2000470d0120014190016a420037030020014188016a4200370300200141f8006a41086a2202420037030020014200370378200141b0026a41a0dac800410f1081022002200141b0026a41086a2204290000370300200120012900b002370378200141b0026a41d0dac8004105108102200341086a2004290000370000200320012900b002370000200141f0026a41002001200110da06200141f8006a412020012802f002220220012802f80210b201024020012802f402450d002002102e0b2001410236027c200141073a0078200141f8006a10fe010c010b2009422088a7210202402009a722042000470d00200141033602782001200236027c200141f8006a108c060b200220046a2000470d0020014190016a420037030020014188016a4200370300200141f8006a41086a2202420037030020014200370378200141b0026a41a0dac800410f1081022002200141b0026a41086a2204290000370300200120012900b002370378200141b0026a41d0dac8004105108102200341086a2004290000370000200320012900b002370000200141f0026a41022001200110da06200141f8006a412020012802f002220220012802f80210b201024020012802f402450d002002102e0b2001410136027c200141073a0078200141f8006a10fe010b200141f0026a109403024020012903f002427f7c4202540d00200141f0026a41106a2903002109200141b0026a41186a22044200370300200141b0026a41106a22034200370300200141b0026a41086a22024200370300200142003703b002200141e8006a41e8fcc60041091081022002200141e8006a41086a2200290000370300200120012900683703b002200141e8006a41b08ec90041031081022004200029000037030020032001290068370300200141d0006a200141b0026a108503200141c0006a2001290358420020012802501b220e42e80780420042e807420010e808200141f8006a41186a22044200370300200141f8006a41106a22034200370300200141f8006a41086a2200420037030020014200370378200141b0026a4192fdc600410710810220002002290000370300200120012900b002370378200141b0026a41d0adc600410910810220042002290000370300200320012900b002370300200141003602b802200142013703b002200120093e0268200141b0026a200141e8006a41041074200141013a00d002200141b0026a200141d0026a41011074200120012903402209200e42e807827c220e427f200141c0006a41086a290300200e200954ad7c501b370368200141b0026a200141e8006a41081074200141f8006a412020012802b002220220012802b80210b20120012802b402450d002002102e0b20014190016a22034200370300200141f8006a41106a22024200370300200141f8006a41086a2204420037030020014200370378200141f0026a4190dac800410a1081022004200141f0026a41086a2200290000370300200120012900f002370378200141f0026a419adac800410610810220032000290000370300200220012900f002370300200141f8006a412010ff0120034200370300200242003703002004420037030020014200370378200141f0026a4190dac800410a10810220042000290000370300200120012900f002370378200141f0026a41d097c900410c10810220032000290000370300200220012900f002370300200141f8006a412010ff0120034200370300200242003703002004420037030020014200370378200141f0026a4180fdc600411210810220042000290000370300200120012900f002370378200141f0026a41dc98c500411110810220032000290000370300200220012900f002370300200141286a200141f8006a10e904200141286a41106a290300210f2001290330211020012802282103200141f8006a4201420042808090bbbad6adf00d420042c0843d420010ea040240024020012802784101470d00427f2111427f21090c010b20022903002109200429030021110b200141f8006a10a903200141f8006a41086a200141a8016a200141a0016a290300501b290300210e200141c8026a22044200370300200141b0026a41106a22004200370300200141b0026a41086a22054200370300200142003703b002200141e8006a41d9fcc60041061081022005200141e8006a41086a2207290000370300200120012900683703b002200141e8006a41d4f2cb00410b1081022004200729000037030020002001290068370300200141f0026a200141b0026a10f20420012903f802211220012903f0022113200141f0026a4203420042808090bbbad6adf00d420042a08d06420010ea04200e2012420020134201511b22122012200e561b21120240024020012802f0024101470d00427f2113427f21140c010b200141f0026a41106a2903002114200141f0026a41086a29030021130b200141186a200e42808090bbbad6adf00d8222154200428080e4ceceb58bbc03420010e808200141086a2001290318200141186a41086a29030042808090bbbad6adf00d420010e608200141f0026a2012200e42808090bbbad6adf00d80428080e4ceceb58bbc037e20154202882001290308428080c89d9deb96f80656200141086a41086a29030022154200522015501bad7c7c2215201220155622041b22162015201220041b22177d42002016201754ad7d42808090bbbad6adf00d4200200e4201200e4201561b420010ea040240024020012802f0024101470d00427f210e427f21160c010b20014180036a2903002116200141f0026a41086a290300210e0b200141f0026a200e2016200e201642808090bbbad6adf00d420010ea040240024020012802f0024101470d00427f2117427f21180c010b20014180036a2903002118200141f8026a29030021170b200141f0026a201320142013201442808090bbbad6adf00d420010ea040240024020012802f0024101470d00427f2119427f211a0c010b20014180036a290300211a200141f8026a29030021190b200141f0026a2019201a42808090bbbad6adf00d4200428080a0f6f4acdbe01b420010ea0420012802f0024101460d052011201042808090bbbad6adf00d20031b22195421042009200f420020031b220f5121032009200f54210020014180036a22052903002110200141f8026a2207290300211a200141f0026a20132014200e201642808090bbbad6adf00d420010ea040240024020012802f0024101470d00427f2116427f21140c010b20052903002114200729030021160b2004200020031b2104200141f0026a201a20102017201842808090bbbad6adf00d420010ea040240024020012802f0024101470d00427f2110427f21170c010b20014180036a2903002117200141f8026a29030021100b200f200920041b210e2019201120041b21130240024020122015540d00427f2115200141f0026a427f201620107c221220122016542204201420177c2004ad7c221220145420122014511b22041b427f201220041b2013200e42808090bbbad6adf00d420010ea040240024020012802f0024101470d00427f21120c010b20014180036a2903002112200141f8026a29030021150b427f200e20127c201320157c22142013542204ad7c221220042012200e542012200e511b22041b220e2009427f201420041b2212201156200e200956200e2009511b22041b21092012201120041b210e0c010b200141f0026a4200201620107d22122012201656201420177d2016201054ad7d221220145620122014511b22041b4200201220041b2013200e42808090bbbad6adf00d420010ea040240024020012802f0024101470d00427f2112427f21140c010b20014180036a2903002114200141f8026a29030021120b4200200e20147d2013201254ad7d2214201320127d22122013562014200e562014200e511b22041b220e20094200201220041b2212201156200e200956200e2009511b22041b21092012201120041b210e0b200141f8006a41186a4200370300200141f8006a41106a4200370300200141f8006a41086a2204420037030020014200370378200141f0026a4180fdc60041121081022004200141f0026a41086a2203290000370300200120012900f002370378200141f0026a41dc98c5004111108102200241086a2003290000370000200220012900f002370000200120093703f8022001200e3703f002200141f8006a4120200141f0026a411010b201200141b0026a41186a22044200370300200141b0026a41106a22024200370300200141b0026a41086a22034200370300200142003703b002200141e8006a41e8fcc60041091081022003200141e8006a41086a2200290000370300200120012900683703b002200141e8006a41d48ec90041091081022004200029000037030020022001290068370300200141b0026a108603220441ff01714102460d06200141b0026a412010ff012004410171450d06200141b0026a41186a4200370300200141b0026a41106a4200370300200141b0026a41086a22044200370300200142003703b002200141e8006a41a8f8c60041041081022004200141e8006a41086a2203290000370300200120012900683703b002200141e8006a41978cc500410b108102200241086a200329000037000020022001290068370000200141f8006a200141b0026a10a004024020012d007822044102460d00200141b0026a412010ff010b200141f0026a41186a20014191016a290000370300200141f0026a41106a20014189016a290000370300200141f0026a41086a20014181016a290000370300200120012900793703f0020240200441037122044103460d0020040e03040004040b200141f8006a41186a200141f0026a41186a290300370300200141f8006a41106a200141f0026a41106a290300370300200141f8006a41086a200141f0026a41086a290300370300200120012903f002370378200141b0026a41186a4200370300200141b0026a41106a4200370300200141b0026a41086a22044200370300200142003703b002200141e8006a41a8f8c60041041081022004200141e8006a41086a2203290000370300200120012900683703b002200141e8006a41ee8bc500410c108102200241086a2003290000370000200220012900683700002001200141b0026a4120108e0241002104200141b0026a2001280204410020012802001b220510db06200141e8006a20012802b002220720012802b80210b60502400240200128026822030d00200141003602d802200142013703d00241012103410021000c010b2001200129026c22093702d402200120033602d0022009422088a721002009a721040b024020012802b402450d002007102e0b200041ff014b0d01200141b0026a41186a220c200141f8006a41186a290300370300200141b0026a41106a2208200141f8006a41106a290300370300200141b0026a41086a2206200141f8006a41086a290300370300200120012903783703b0020240024020002004470d00200441016a22072004490d022004410174220a2007200a20074b1b22074104200741044b1b220741ffffff3f71200746210a200741057421070240024020040d00200141003602680c010b200141f0006a4101360200200120033602682001200441057436026c0b200141e0026a2007200a200141e8006a107d200141e8026a280200210420012802e0024101460d01200120012802e40222033602d0022001200441057622043602d4020b200320004105746a220720012903b002370000200741186a200c290300370000200741106a2008290300370000200741086a20062903003700002001200041016a3602d8022005200141d0026a10dc060c030b20040d040b1038000b4120102c2200450d0220002001290378370000200041186a200141f8006a41186a290300370000200041106a200141f8006a41106a290300370000200041086a200141f8006a41086a29030037000020014281808080103702b402200120003602b002200541016a2205200141b0026a10dc062000102e200141b0026a41186a4200370300200141b0026a41106a4200370300200141b0026a41086a22004200370300200142003703b002200141e8006a41a8f8c60041041081022000200141e8006a41086a2207290000370300200120012900683703b002200141e8006a41ee8bc500410c108102200241086a20072900003700002002200129006837000020012005360268200141b0026a4120200141e8006a410410b2010b200441ffffff3f71450d002003102e0b200141c8026a22004200370300200141c0026a22054200370300200141b0026a41086a22044200370300200142003703b002200141e8006a41a8f8c60041041081022004200141e8006a41086a2203290000370300200120012900683703b002200141e8006a41848cc5004113108102200241086a2207200329000037000020022001290068370000200141b0026a412010ff01200042003703002005420037030020044200370300200142003703b002200141e8006a41a8f8c600410410810220042003290000370300200120012900683703b002200141e8006a41a28cc50041081081022007200329000037000020022001290068370000200141b0026a412010ff01200141a0036a24000f0b1036000b10dd06000b41d2d9c800412b4180dac8001039000bd00101017f230041106b2204240020004100360208200042013702000240024002400240024020010e0400010203000b200441003a000c20002004410c6a410110740c030b200441013a000c20002004410c6a410110742004200236020c20002004410c6a410410742004200336020c20002004410c6a410410740c020b200441023a000c20002004410c6a410110740c010b200441033a000c20002004410c6a410110742004200236020c20002004410c6a410410742004200336020c20002004410c6a410410740b200441106a24000b850201037f230041d0006b22022400200241086a41a8f8c6004104108102200241186a4197dbc8004111108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000bd60101057f230041206b220224002002200010db0602400240200128020822004105744104722203417f4c0d002001280200210120022802082104200228020021052003102c2206450d012002410036021820022003360214200220063602102000200241106a107602402000450d00200041057421000340200241106a200141201074200141206a2101200041606a22000d000b0b2005200420022802102201200228021810b20102402002280214450d002001102e0b02402002280204450d002005102e0b200241206a24000f0b1038000b1036000b110041c9dbcc00411f41e8dbcc001039000ba7cc010a077f017e027f017e177f037e0b7f027e067f037e230022012102200141a0136b41607122012400200141b8016a10f40402400240024020012d00b8014101470d0020012802bc012000470d00200141a0056a41014196a9c700412410df0602400240024020012802a0052203450d00200141a8056a28020041034d0d0002402003280000220420004b0d00200441056a2000490d010b20012802a405450d012003102e0c030b200120003602c001200120003602b003200141d80f6a41086a200141a0056a41086a280200360200200120012903a0053703d80f41014196a9c7004124200141d80f6a200141b0036a410410e0060d010b0c010b200141d80f6a10e10620012802d80f410b702105200141d80f6a10f5040240024002400240024020012802d80f2206450d00200141d80f6a41106a22072903002108200141e40f6a2209280200210a20012902dc0f210b200141d00e6a41186a22044200370300200141d00e6a41106a220c4200370300200141d00e6a41086a220d4200370300200142003703d00e200141d80f6a41a5fec600411a108102200d200141d80f6a41086a2203290000370300200120012900d80f3703d00e200141d80f6a4194c5c800410e10810220042003290000370300200c20012900d80f370300200141b0016a200141d00e6a4120108e02024020012802b001450d0020012802b401210e200120083702940d2001200a3602900d2001200b3702a405200120063602a005200141d80f6a200141900d6a200141a0056a10b904200141f00e6a41086a20032802002204360200200120012903d80f220b3703f00e200141800f6a41086a200141ec0f6a2802002206360200200120012902e40f22083703800f200141900d6a41086a20043602002001200b3703900d200141a0056a41086a2006360200200120083703a005200141d80f6a200e200141900d6a200141a0056a10e206200141a80a6a41086a200141d80f6a41186a280200360200200120072903003703a80a024020012802d80f4101470d000c060b2003280200210f2009280200210420012802dc0f2110200141900f6a41086a200141a80a6a41086a280200360200200120012903a80a3703900f200141900f6a20054200420010c004201020044102746a2107024002400240200e0d00201021032010210d0c010b201021032010210d2004450d0020044102742105201021032010210d024003402003220641046a210320062802002204450d022004280208220a41016a41004c0d032004200a36020802400240200441f4006a2d00000d0020042004280200417f6a220636020020060d01200441046a22062006280200417f6a220636020020060d012004102e0c010b200d2004360200200d41046a210d200e417f6a220e450d020b2005417c6a22050d000b200721030c010b200641046a21030b0240200720036b2204450d00200441027541027421040340200328020022062006280200417f6a3602000240200328020022062802000d00200641046a22062006280200417f6a3602002003280200220641046a2802000d002006102e0b200341046a21032004417c6a22040d000b0b02400240200d20106b2211410275221241144b0d00201241014d0d074102210320102012417e6a22044102746a2106034020122004490d022006200310e3062006417c6a2106200341016a21032004417f6a2204417f470d000c080b0b2012410176220341ffffffff03712003470d0a20034102742213417f4c0d0a2013102c2214450d092010417c6a2115201041746a21164104211741002118410021192012211a0340201a210a4100211a410121040240200a417f6a220d450d000240024002400240024002400240024002400240024002402010200d4102746a2802002203280208220441016a41004c0d00200320043602082010200a417e6a22054102746a2802002204280208220641016a41004c0d01200328025021032004200636020820032004280250490d042016200a4102746a21034100211a410021060340024020052006470d00200a21040c0e0b200341046a2802002204280208220d41016a41004c0d032004200d3602082003280200220d280208220e41016a41004c0d0420042802502104200d200e3602082003417c6a2103200641016a21062004200d2802504f0d000b200641016a21042006417f73200a6a210d0c050b41bcd9cc004118200141d80f6a41c4f8c90041d4f8c900103e000b41bcd9cc004118200141d80f6a41c4f8c90041d4f8c900103e000b41bcd9cc004118200141d80f6a41c4f8c90041d4f8c900103e000b41bcd9cc004118200141d80f6a41c4f8c90041d4f8c900103e000b2016200a41027422056a2103024003400240200d4101470d004100210d0c020b200341046a2802002204280208220641016a41004c0d032004200636020820032802002206280208220e41016a41004c0d04200428025021042006200e3602082003417c6a2103200d417f6a210d20042006280250490d000b0b200a200d490d03200a20124b0d04200a200d6b2204410176220e450d002010200d4102746a2103201520056a21060340200328020021052003200628020036020020062005360200200341046a21032006417c6a2106200e417f6a220e0d000b0b0240200d0d00200d211a0c070b0240200441094d0d00200d211a0c070b200a20124b0d04200a200d6b2104200d417f6a21032015200d4102746a21060340200a2003490d0d2006200441016a220410e3062003417f6a220d20034f0d062006417c6a2106200d21032004410a490d000c060b0b41bcd9cc004118200141d80f6a41c4f8c90041d4f8c900103e000b41bcd9cc004118200141d80f6a41c4f8c90041d4f8c900103e000b200d200a41e4d1cc001057000b200a201241e4d1cc00104d000b200a200d417f6a2203490d07200a201241f4d1cc00104d000b200d41016a211a0b024020192018470d00201841016a22032018490d0c201841017422062003200620034b1b22034104200341044b1b220341ffffffff01712003464102742106200341037421030240024020180d00200141003602d80f0c010b200141043602e00f200120173602d80f200120184103743602dc0f0b200141a0056a20032006200141d80f6a107d20012802a8052103024020012802a0054101470d0020030d0c0c0d0b20012802a4052117200341037621180b201720194103746a220320043602042003201a360200201941016a221b21190240201b4102490d000240024002400240024002400240034002400240024002402017201b2219417f6a221b4103746a2203280200450d00201941037420176a220e41746a280200220d200328020422044d0d00201941024d0d0c20172019417d6a22034103746a28020422062004200d6a4d0d01201941034d0d0c200e41646a2802002006200d6a4b0d0c0c010b20194103490d012003280204210420172019417d6a22034103746a28020421060b20062004490d010b2019417e6a21030b02402019200341016a221c4d0d00201920034d0d02201720034103746a221d280204221e201d2802006a22032017201c4103746a221f2802002220490d03200320124b0d04201020204102746a2221201f280204222241027422046a21062003410274210e02400240200320206b220520226b22032022490d0020142021200410e908220320046a210d0240024020224101480d00200520224a0d010b20212104200321030c020b2010200e6a2107200321032021210403402006280200220e280208220541016a41004c0d08200e200536020820032802002205280208220a41016a41004c0d09200e280250210e2005200a360208200420062003200e200528025049220e1b2802003602002003200341046a200e1b2103200441046a2104200641046a2006200e1b220620074f0d02200d20034b0d000c020b0b201420062003410274220410e908220720046a210d0240024020224101480d00200341014e0d010b20062104200721030c010b2015200e6a210a200621040340200d417c6a22032802002206280208220e41016a41004c0d092006200e3602082004417c6a220e2802002205280208220941016a41004c0d0a2006280250210620052009360208200a200e2003200620052802504922061b280200360200200d200320061b210d02402021200e200420061b2204490d00200721030c020b200a417c6a210a200721032007200d490d000b0b20042003200d20036b417c7110e9081a201d41046a201e20226a360200201d2020360200201f201f41086a2019201c417f736a41037410ea081a41012119201b41014d0d090c010b0b201c20194184d2cc00103c000b200320194194d2cc00103c000b2020200341a4d2cc001057000b2003201241a4d2cc00104d000b41bcd9cc004118200141d80f6a41c4f8c90041d4f8c900103e000b41bcd9cc004118200141d80f6a41c4f8c90041d4f8c900103e000b41bcd9cc004118200141d80f6a41c4f8c90041d4f8c900103e000b41bcd9cc004118200141d80f6a41c4f8c90041d4f8c900103e000b201a450d060c000b0b2004201241c4d1cc001056000b41bcd9cc004118200141d80f6a4190b7c00041a0b7c000103e000b0240200842ffffff3f83500d00200a102e0b0240200b422088a72203450d00200341386c21042006412c6a210303400240200328020041ffffff3f71450d002003417c6a280200102e0b200341386a2103200441486a22040d000b0b200ba72203450d00200341386c450d002006102e0b20014198076a200141d8086a41c00110e9081a0c040b2003200a41f4d1cc001057000b0240201841ffffffff0171450d002017102e0b2013450d002014102e0b20012802980f210420012802940f2106200120012802900f22033602a80f200120063602a40f200120033602a00f20012003200441e0006c6a221d3602ac0f4104211e024002402004450d00200141900d6a410472211f200141d80f6a41346a2104024002400340200141a0056a41286a220d200341286a290300370300200141a0056a41206a220e200341206a290300370300200141a0056a41186a2205200341186a290300370300200141a0056a41106a220a200341106a290300370300200141a0056a41086a2207200341086a290300370300200120032903003703a005200341306a2802002106200141a80a6a41086a22092003413c6a290200370300200141a80a6a41106a2221200341c4006a290200370300200141a80a6a41186a2219200341cc006a290200370300200141a80a6a41206a2222200341d4006a290200370300200141a80a6a41286a2217200341dc006a2802003602002001200341346a2902003703a80a2006450d01200141d80f6a41286a200d290300370300200141d80f6a41206a200e290300370300200141d80f6a41186a2005290300370300200141d80f6a41106a200a290300370300200141d80f6a41086a2007290300370300200420012903a80a370200200441086a2009290300370200200441106a2021290300370200200441186a2019290300370200200441206a2022290300370200200441286a2017280200360200200120012903a0053703d80f2001200636028810200141900d6a200141d80f6a10e406024020012802900d22060d00200341e0006a2203201d470d010c030b0b200141b00f6a41206a201f41206a290200220b370300200141b00f6a41186a201f41186a2902002208370300200141b00f6a41106a201f41106a2902002223370300200141b00f6a41086a201f41086a29020022243703002001200341e0006a3602a80f2001201f29020022253703b00f20012802b40f210720012802d40f212220012802cc0f211920012802c40f212120012802bc0f2109412c102c221e450d06201e2022360228201e200ba7221b360224201e2019360220201e2008a7222036021c201e2021360218201e2023a7221f360214201e2009360210201e2024a7221d36020c201e2007360208201e2025a72217360204201e2006360200200141d00e6a41086a200141a00f6a41086a290300220b370300200120012903a00f3703d00e024002400240200ba7220620012802dc0e2226470d0041012127410121130c010b200141d80f6a41346a2104200141900d6a410472212841012127410121130340200141a0056a41286a220d2006220341286a290300370300200141a0056a41206a220e200341206a290300370300200141a0056a41186a2205200341186a290300370300200141a0056a41106a220a200341106a290300370300200141a0056a41086a221c200341086a290300370300200120032903003703a005200341306a2802002106200141a80a6a41086a22142003413c6a290200370300200141a80a6a41106a221a200341c4006a290200370300200141a80a6a41186a2218200341cc006a290200370300200141a80a6a41206a2215200341d4006a290200370300200141a80a6a41286a2216200341dc006a2802003602002001200341346a2902003703a80a024002402006450d00200141d80f6a41286a200d290300370300200141d80f6a41206a220d200e290300370300200141d80f6a41186a220e2005290300370300200141d80f6a41106a2205200a290300370300200141d80f6a41086a220a201c290300370300200420012903a80a370200200441086a2014290300370200200441106a201a290300370200200441186a2018290300370200200441206a2015290300370200200441286a2016280200360200200120012903a0053703d80f2001200636028810200141900d6a200141d80f6a10e40620012802900d22060d01200341e0006a22062026470d020b2001200341e0006a3602d80e0c020b200141b00f6a41106a202841106a290200220b370300200141e00b6a41086a221c202841086a290200370300200141e00b6a41106a2214200b370300200141e00b6a41186a221a202841186a290200370300200141e00b6a41206a2218202841206a2902003703002001200341e0006a3602d80e200120282902003703e00b200d2018290300370300200e201a29030037030020052014290300370300200a201c290300370300200120012903e00b3703d80f024020132027470d00202741016a22032027490d0b2027410174221c2003201c20034b1b22034104200341044b1bad422c7e220b422088a7454102742103200ba7211c0240024020270d00200141003602a0050c010b200141043602a8052001201e3602a00520012027412c6c3602a4050b200141900d6a201c2003200141a0056a107d20012802980d210320012802900d4101460d0320012802940d211e2003412c6e21270b201e2013412c6c6a220320063602002003410c6a200a290300370200200320012903d80f370204200341146a20052903003702002003411c6a200e290300370200200341246a200d290300370200201341016a211320012802d80e220620012802dc0e2226470d000b0b200141d00e6a10ac020c040b2003450d070c060b200341e0006a211d0b2001201d3602a80f0b200141a00f6a10ac0241002127410021130b2013412c6c2104410021030240034020042003460d01200141a8016a201e20036a10be042003412c6a210320012802a801450d000b02402013450d002013412c6c2104201e210303400240200341046a2802002206450d00200641226c450d002003280200102e0b2003412c6a2103200441546a22040d000b0b02402027450d002027412c6c450d00201e102e0b02402011450d0020124102742104201021030340200328020022062006280200417f6a3602000240200328020022062802000d00200641046a22062006280200417f6a3602002003280200220641046a2802000d002006102e0b200341046a21032004417c6a22040d000b0b200f41ffffffff0371450d012010102e0c010b2012ad42307e220b422088a70d03200ba72203417f4c0d030240024020030d00410821290c010b2003102c2229450d030b0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200341306e222a20124f0d00202a41017422042012200420124b1b22044104200441044b1bad42307e220b422088a7454103742104200ba72106024002402003412f4b0d00200141003602d80f0c010b200141d80f6a41086a4108360200200120293602d80f2001202a41306c3602dc0f0b200141a0056a20062004200141d80f6a107d200141a8056a280200210320012802a0054101460d0120012802a4052129200341306e212a0b2012410274210420110d0141002118201021030c020b2003450d170c160b201020046a21152012410274210d2011417c6a41027641016a2116200141d00e6a41186a210e200141d00e6a41106a2105200141d00e6a41086a210a410021182029210420102106024003400240200628020022030d00200641046a21030c020b200328020841016a221c41004c0d032003201c360208200e200341ec006a2900003703002005200341e4006a290000370300200a200341dc006a2900003703002001200341d4006a2900003703d00e2003280208221c41016a221241004c0d0420032012360208200e290300210b20052903002108200a29030021232003201c417f6a360208200141d80f6a41086a221c2023370300200141d80f6a41106a22122008370300200141d80f6a41186a2214200b370300200120012903d00e3703d80f200341c8006a290300210b2003290340210820032003280200417f6a221a3602000240201a0d00200341046a221a201a280200417f6a221a360200201a0d002003102e0b200641046a2106200420012903d80f370300201c29030021232012290300212420142903002125200441286a200b370300200441206a2008370300200441186a2025370300200441106a2024370300200441086a2023370300200441306a2104201841016a2118200d417c6a220d0d000b20152103201621180b201520036b220441027521120b02402004450d00201241027421040340200328020022062006280200417f6a3602000240200328020022062802000d00200641046a22062006280200417f6a3602002003280200220641046a2802000d002006102e0b200341046a21032004417c6a22040d000b0b0240200f41ffffffff0371450d002010102e0b200141d80f6a10f504024020012802d80f2203450d00200141e40f6a2802002104200141d80f6a41106a290300210b200120012902dc0f37029c0a200120033602980a2001200b3702f40e200120043602f00e200141e80e6a4200370300200141d00e6a41106a4200370300200141d00e6a41086a22034200370300200142003703d00e200141d80f6a41a5fec600411a1081022003200141d80f6a41086a2204290000370300200120012900d80f3703d00e200141d80f6a4194c5c800410e108102200c41086a2004290000370000200c20012900d80f370000200141a0016a200141d00e6a4120108e02024020012802a001450d0020012802a401212b200142003702840f024020012802a00a2203450d00200341386c210620012802980a41086a2103410021040340200141d80f6a41186a200341186a290000370300200141d80f6a41106a200341106a290000370300200141d80f6a41086a200341086a290000370300200120032900003703d80f200341386a2103200141800f6a200141d80f6a200410a402200441016a2104200641486a22060d000b0b2001200141800f6a3602a40a200142003702940f024020012802f80e2203450d0020012802f00e220520034105746a21154100210d41002112034002400240200d450d0020012802900f211c0c010b41e000102c220d450d194100211c200d4100360200200d41003b015e2001200d3602940f200141003602900f0b200541206a2114024002400340200d41046a211a200d2f015e2210410274210e41002103417f2104024003400240200e2003470d00201021040c020b2005200d20036a220a41046a280200412010ec082206450d03200441016a2104200341046a21032006417f4a0d000b0b0240201c450d00201c417f6a211c200d20044102746a41e0006a280200210d0c010b0b024002402010410a4b0d00201041016a21030240200420104f0d00201a200441016a41027422066a201a2004410274220e6a20032004417f736a410274220a10ea081a200d41306a221c20066a201c200e6a200a10ea081a0b201a200441027422046a2005360200200d20046a41306a2012360200200d20033b015e0c010b4100210a4104210302400240200441054f0d00200421060c010b4105210341052106024002402004417b6a0e020201000b200441796a21064101210a410621030c010b410021064101210a0b41e000102c2204450d1b200441003b015e200441003602002004200d2f015e221c2003417f736a220e3b015e200e410c4f0d09201c200341016a22106b200e470d0a200d41306a221c200341027422116a2802002116201a20116a2802002111200441046a201a201041027422106a200e410274220e10e9081a200441306a201c20106a200e10e9081a200d20033b015e2004200d200a1b220341046a210e20032f015e221c41016a210a0240200641016a2210201c4b0d00200e2010410274221c6a200e200641027422106a200a2006417f736a410274221a10ea081a200341306a2226201c6a202620106a201a10ea081a0b200e200641027422066a2005360200200320066a41306a20123602002003200a3b015e024002400240200d280200220a0d004100211a0c010b4100211a201121262016210f200421280340200d2f015c210e200a2f015e221c410b490d0241002105410421030240200e4105490d00200e210302400240200e417b6a0e020201000b200e41796a210e41012105410621030c010b4100210e41012105410521030b419001102c2204450d1e200441003b015e200441003602002004200a2f015e220d2003417f736a22063b015e2006410c4f0d0e200d200341016a22106b2006470d0f200a41306a222c2003410274220d6a2802002116200a41046a222d200d6a2802002111200441046a202d2010410274220d6a2006410274220610e9081a200441306a202c200d6a200610e9081a200a20033b015e20042f015e220641016a21102006410c4f0d10201c20036b22032010470d11201a41016a211a200441e0006a200a200d6a41e0006a200341027410e9081a4100210302400340200420034102746a41e0006a280200220d20033b015c200d200436020020032003200649220d6a220320064b0d01200d0d000b0b2004200a20051b220d41046a222c200e410274221c6a2110200d2f015e220641016a210502400240200e41016a220320064d0d0020102026360200200d41306a21100c010b202c2003410274222d6a2010200e417f7320056a410274222c10ea081a20102026360200200d41306a2210202d6a2010201c6a202c10ea081a0b2010201c6a200f360200200d41e0006a21100240200e41026a2226200641026a22064f0d00201020264102746a201020034102746a2003417f7320066a41027410ea081a0b201020034102746a2028360200200d20053b015e0240200320064f0d00200d201c6a41e4006a2103034020032802002206200e41016a220e3b015c2006200d360200200341046a21032005200e470d000b0b200a210d200a2802002203210a201121262016210f2004212820030d000b0b20012802940f2206450d1020012802900f210d419001102c2203450d1c20032006360260200341003b015e2003410036020020062003360200200641003b015c200120033602940f2001200d41016a3602900f200d201a470d1120032f015e2206410b4f0d122003200641016a220d3b015e200320064102746a220641306a2016360200200641046a2011360200200341e0006a200d4102746a2004360200200420033602002004200d3b015c200120012802980f41016a3602980f0c030b200a41046a2104201c41016a210602400240200e201c490d002004200e41027422036a2026360200200a20036a41306a200f360200200a41e0006a2104201c41026a210d200e41016a21030c010b2004200e41016a2203410274220d6a2004200e41027422056a2204200e417f7320066a410274220e10ea081a20042026360200200a41306a2204200d6a200420056a2204200e10ea081a2004200f3602002005200a41e0006a22046a41086a2004200d6a2003417f73201c41026a220d6a41027410ea081a0b20042003410274220e6a2028360200200a20063b015e2003200d4f0d00200a200e6a41e0006a210403402004280200220620033b015c2006200a360200200441046a2104200d200341016a2203470d000b0b200120012802980f41016a3602980f0c010b200a41306a20123602000b20142015460d01201241016a211220012802940f210d201421050c000b0b201e2013412c6c6a211c0240024020130d00201e2104201e21030c010b200141a0056a410c6a2110200141a0056a4104722104200141e00b6a41206a210d200141e00b6a41186a210e200141e00b6a41106a2105200141e00b6a41086a210a201e21060340200622032802002106200d200341246a290200370300200e2003411c6a2902003703002005200341146a290200370300200a2003410c6a2902003703002001200341046a2902003703e00b024020060d002003412c6a21040c020b200420012903e00b370200200441086a200a290300370200200441106a2005290300370200200441186a200e290300370200200441206a200d290300370200200120063602a0054200210b0240200141800f6a201010a0022206450d0020012802a00a200628020022064d0d0020012802980a200641386c6a290300210b0b200141d80f6a41286a200141a0056a41286a280200360200200141d80f6a41206a200141a0056a41206a290300370300200141d80f6a41186a200141a0056a41186a290300370300200141d80f6a41106a200141a0056a41106a290300370300200141d80f6a41086a200141a0056a41086a290300370300200120012903a0053703d80f200141900d6a200141d80f6a200b420010bd04200341286a200141900d6a41286a280200360200200341206a200141900d6a41206a290300370200200341186a200141900d6a41186a290300370200200341106a200141900d6a41106a290300370200200341086a200141900d6a41086a290300370200200320012903900d3702002003412c6a2206201c470d000b2003412c6a2103201c21040b2027ad210b201c20046b2206412c6d210d02402006450d00200d412c6c210603400240200441046a280200220d450d00200d41226c450d002004280200102e0b2004412c6a2104200641546a22060d000b0b2003201e6b220e412c6d220d412c6c2104200dad422086200b842108201e210602400340200621032004450d014200210b0240200141800f6a2003410c6a10a0022206450d0020012802a00a200628020022064d0d0020012802980a200641386c6a290300210b0b2003412c6a210620014198016a2003200b420010bf04200441546a2104200128029801450d000b0240200e450d00201e200d412c6c6a210d201e2103034020032204412c6a21030240200441046a2802002206450d00200641306c450d002004280200102e0b200d2003470d000b0b2027450d0f2027412c6c450d0f201e102e0c0f0b200120083702a40f2001201e3602a00f201e200d412c6c6a212d200141a00f6a10e5060240200e0d00201e211c201e21050c0e0b200141e00b6a41086a2112200141e00b6a41206a212e200141e00b6a41186a212f200141e00b6a41106a2130201e211c02400340201c22052802002114202e200541246a2213290200370300202f2005411c6a22112902003703002030200541146a222629020037030020122005410c6a290200370300200120052902043703e00b2005412c6a211c2014450d0f200141a80a6a41086a220f201241086a290200370300200141a80a6a41106a2228201241106a290200370300200141a80a6a41186a222c201241186a290200370300200120122902003703a80a20012802e00b21160240024020012802e40b220e41306c220d0d00420021084200210b0c010b201441206a210342002108200d21044200210b0340427f200b200341086a2903007c200820032903007c22232008542206ad7c220820062008200b542008200b511b22061b210b427f202320061b2108200341306a2103200441506a22040d000b0b024002400240200e41306c2204450d002014200d6a2110201421030340200341286a2903002123200341206a2903002124200341086a2903002125200341106a290300213120032903002132200141d00e6a41186a2206200341186a290300370300200141d00e6a41106a220d2031370300200141d00e6a41086a220e2025370300200120323703d00e202420232008200b10e606220a41ffff03710d02200341306a2103200441506a22040d000b0b410021154102211a02402016450d00201641306c450d002014102e0b4100210a0c010b200141900d6a41086a2215200e290300370300200141900d6a41106a2233200d290300370300200141900d6a41186a22342006290300370300200120012903d00e22233703a005200120233703900d4122102c221a450d19201a20012903900d370100201a200a3b0120201a41186a2034290300370100201a41106a2033290300370100201a41086a20152903003701000240024020044130470d00410121154101210a0c010b200341306a2134201041506a2135410121154101210a03402034210302400340200341286a2903002123200341206a29030021242006200341186a290300370300200d200341106a290300370300200e200341086a290300370300200120032903003703d00e202420232008200b10e606220441ffff03710d012010200341306a2203470d000c030b0b200141a0056a41086a200e2903002223370300200141a0056a41106a200d2903002224370300200141a0056a41186a20062903002225370300200120012903d00e22313703a005200141d80f6a41186a22362025370300200141d80f6a41106a22372024370300200141d80f6a41086a22382023370300200120313703d80f0240200a2015470d00201541016a22332015490d1d201541017422342033203420334b1b22334104203341044b1bad42227e2223422088a74541017421332023a721340240024020150d00200141003602900d0c010b200141023602980d2001201a3602900d2001201541226c3602940d0b200141b00f6a20342033200141900d6a107d20012802b80f211520012802b00f4101460d0520012802b40f211a201541226e21150b200341306a2134201a200a41226c6a223320012903d80f370100203829030021232037290300212420362903002125203320043b0120203341186a2025370100203341106a2024370100203341086a2023370100200a41016a210a20352003470d000b0b2016450d00201641306c450d002014102e0b200141d80f6a41186a2203202c290300370300200141d80f6a41106a22042028290300370300200141d80f6a41086a2206200f290300370300200120012903a80a3703d80f200520153602042005201a3602002005200a360208200520012903d80f37020c202620062903003702002011200429030037020020132003290300370200201c202d470d000b201c2105202d211c0c0e0b2015450d170c160b024020012802f40e41ffffff3f71450d0020012802f00e102e0b024020012802a00a2203450d00200341386c210420012802980a412c6a210303400240200328020041ffffff3f71450d002003417c6a280200102e0b200341386a2103200441486a22040d000b0b200128029c0a2203450d00200341386c450d0020012802980a102e0b0240202a450d00202a41306c450d002029102e0b02402013450d00201e2013412c6c6a210d201e2103034020032204412c6a21030240200441046a2802002206450d00200641226c450d002004280200102e0b200d2003470d000b0b2027450d122027412c6c450d12201e102e0c120b41bcd9cc004118200141d80f6a41f09cc50041c09dc500103e000b41bcd9cc004118200141d80f6a41f09cc50041d09dc500103e000b200e410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b2006410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b2010410c41f49cc700104d000b41f49bc7004128419c9cc7001039000b41e8aac700412b4194abc7001039000b41e899c700413041989ac7001039000b41a89ac700412041c89ac7001039000b202d201c6b2203412c6d210402402003450d002004412c6c210303400240201c41046a2802002204450d00200441306c450d00201c280200102e0b201c412c6a211c200341546a22030d000b0b201e2005201e6b220d412c6d2206412c6c6a2104201e21030240034020042003460d0120014190016a200310be042003412c6a2103200128029001450d000b0240200d450d00201e2006412c6c6a210d201e2103034020032204412c6a21030240200441046a2802002206450d00200641226c450d002004280200102e0b200d2003470d000b0b2027450d012027412c6c450d01201e102e0c010b200120063602980d200120273602940d2001201e3602900d200141d80f6a200141900d6a200141a40a6a200141900f6a109906200141e00f6a280200210e200141e40f6a280200210620012802dc0f210520012802d80f2103200141a0056a200141e80f6a41b40110e9081a20034101460d00200141a80a6a200141a0056a41b40110e9081a20012802a00a212f20012802f80e2135200141d80f6a10df040240024002400240200141f00f6a2903004200510d00200141f80f6a210a02400240202f0d00410021040c010b4200200a290300220b42809ce8af6d7c22082008200b561b210b2035ad42889b047e202fad222442f0aefa017e7c2108202bad42a0ede0017e2123202f21030240202f410176220d450d00202f21040340024002400240417f2008202442e8aede067e7c20237c4280e59af7007c2224200b522024200b541b41016a0e03000501000b02402004200d6a220320044f0d00200421030c040b2003202f490d01200421030c030b2004200d6b220320044d0d00200421030c020b20032004460d022003ad212420032104200d410176220d0d000b0b024003402003220441016a2203202f4b0d0120082003ad42e8aede067e7c20237c4280e59af7007c200b540d000b0b4100211c02402004417f6a20044b0d000340024020082004ad42e8aede067e7c20237c4280e59af7007c200b560d002004211c0c020b2004417e6a21032004417f6a220d21042003200d4d0d000b0b202f201c201c202f4b1b21040b2001200e3602dc0f200120053602d80f200120063602e00f200141e40f6a200141a80a6a41b40110e9081a02400240417f417f417f417f417f417f417f417f417f417f417f417f417f417f417f2006200141ec0f6a2802006a220320032006491b2203200a2802006a220d200d2003491b220320014184106a2802006a220d200d2003491b220320014190106a2802006a220d200d2003491b22032001419c106a2802006a220d200d2003491b2203200141a8106a2802006a220d200d2003491b2203200141b4106a2802006a220d200d2003491b2203200141c0106a2802006a220d200d2003491b2203200141cc106a2802006a220d200d2003491b2203200141d8106a2802006a220d200d2003491b2203200141e4106a2802006a220d200d2003491b2203200141f0106a2802006a220d200d2003491b2203200141fc106a2802006a220d200d2003491b2203200141d80f6a41b0016a2802006a220d200d2003491b220320014194116a2802006a220d200d2003491b220320046b223320034b0d0020330d010b20012802e40f2103200141a0056a200141e80f6a41b00110e9081a200141e00b6a200141a0056a41b00110e9081a0c070b200141b00f6a10f50420012802b00f2210450d0320012902b40f21080240200141c00f6a29030042ffffff3f83500d00200141bc0f6a280200102e0b2008422088a7220d41386c220641386d2203ad42287e220b422088a70d0d200ba72204417f4c0d0d0240024020040d00410821260c010b2004102c2226450d0d0b0240024002400240200441286e223620034f0d002036410174220e2003200e20034b1b220e4104200e41044b1bad42287e220b422088a745410374210e200ba7210502400240200441274b0d00200141003602b00f0c010b200141b00f6a41086a4108360200200120263602b00f2001203641286c3602b40f0b200141d00e6a2005200e200141b00f6a107d200141d80e6a280200210420012802d00e4101460d0120012802d40e2126200441286e21360b201020066a221e2010470d014100212c2010210e0c020b2004450d0f0c0e0b200d41037441786a41037641016a21124100212c2010210320262104024003402003290300210b200141b00f6a41186a2206200341206a290300370300200141b00f6a41106a220d200341186a290300370300200141b00f6a41086a220e200341106a2903003703002001200341086a2903003703b00f0240200341286a280200221c0d00200341386a210e0c020b2003412c6a2802002105200141d00e6a41186a220a2006290300370300200141d00e6a41106a2206200d290300370300200141d00e6a41086a220d200e290300370300200120012903b00f3703d00e0240200541ffffff3f71450d00201c102e0b200420012903d00e370300200441186a200a290300370300200441106a2006290300370300200441086a200d290300370300200441206a200b370300200441286a2104202c41016a212c200341386a2203201e470d000b201e210e2012212c0b201e200e6b220641386d21030b2008a7210d02402006450d00200341386c2104200e412c6a210303400240200328020041ffffff3f71450d002003417c6a280200102e0b200341386a2103200441486a22040d000b0b0240200d450d00200d41386c450d002010102e0b024002400240202c41144b0d00202c41014d0d052026202c417f6a220641286c6a21054100210d0340202c20062203417f6a2206490d030240202c20066b221c4102490d002026200341286c6a220341206a220e2903002026200641286c6a220441206a220a290300220b5a0d00200141d00e6a41186a221e200441186a2210290300370300200141d00e6a41106a2212200441106a2214290300370300200141d00e6a41086a221a200441086a2215290300370300200120042903003703d00e200420032903003703002015200341086a2903003703002014200341106a2903003703002010200341186a290300370300200a200e2903003703000240201c4103490d00200d417f6a210a41002104200521030340200341c8006a220e290300200b5a0d01200a2004460d05200341206a200e290300370300200341186a200341c0006a290300370300200341106a200341386a290300370300200341086a200341306a2903003703002003200341286a220e290300370300200e2103200d2004417f6a2204470d000b200e21030b200320012903d00e3703002003200b370320200341186a201e290300370300200341106a2012290300370300200341086a201a2903003703000b200541586a2105200d417f6a210d20060d000c060b0b202c410176ad42287e220b422088a70d0f200ba72237417f4c0d0f2037102c222d450d0e202641586a2130202641a87f6a2134410421144100212e41002110202c2113034020132105410021134101210e02402005417f6a220d450d0002400240024002400240024002402026200d41286c6a41206a290300200541286c220a20266a41506a290300220b540d002005417e6a210d2034200a6a2104410021134100210303400240200d2003470d002005210e0c090b200341016a2103200b200429030022085a2106200441586a21042008210b20060d000b200341016a210e2003417f7320056a210d0c010b2034200a6a2103024003400240200d4101470d004100210d0c020b200d417f6a210d200b20032903002208542104200341586a21032008210b20040d000b0b2005200d490d012005202c4b0d022005200d6b220e4101762206450d002030200a6a21032026200d41286c6a21040340200141b00f6a41206a220a200441206a221c290300370300200141b00f6a41186a221e200441186a2212290300370300200141b00f6a41106a221a200441106a2215290300370300200141b00f6a41086a2216200441086a2213290300370300200120042903003703b00f200341206a2227290300210b200341186a22112903002108200341106a220f2903002123200341086a2228290300212420042003290300370300201320243703002015202337030020122008370300201c200b3703002027200a2903003703002011201e290300370300200f201a29030037030020282016290300370300200320012903b00f370300200341586a2103200441286a21042006417f6a22060d000b0b0240200d0d00200d21130c060b0240200e41094d0d00200d21130c060b2005202c4b0d03200d20056b21062026200d41286c6a210a03402005200d417f6a2213490d050240200520136b220e4102490d002026200d41286c6a220341206a220d2903002026201341286c6a220441206a221c290300220b5a0d00200141d00e6a41186a221e200441186a2212290300370300200141d00e6a41106a221a200441106a2215290300370300200141d00e6a41086a2216200441086a2227290300370300200120042903003703d00e200420032903003703002027200341086a2903003703002015200341106a2903003703002012200341186a290300370300201c200d2903003703000240200e4103490d0041012104200a21030340200341c8006a220d290300200b5a0d01200620046a4101460d06200341206a200d290300370300200341186a200341c0006a290300370300200341106a200341386a290300370300200341086a200341306a2903003703002003200341286a220d290300370300200d21032006200441016a22046a0d000b200d21030b200320012903d00e3703002003200b370320200341186a201e290300370300200341106a201a290300370300200341086a20162903003703000b2013450d06200a41586a210a2006417f6a21062013210d200e410a4f0d060c000b0b200d200541e4d1cc001057000b2005202c41e4d1cc00104d000b2004200e41d4d1cc00103c000b2005200d417f6a2213490d002005202c41f4d1cc00104d000b2013200541f4d1cc001057000b02402010202e470d00202e41016a2203202e490d11202e41017422042003200420034b1b22034104200341044b1b220341ffffffff017120034641027421042003410374210302400240202e0d00200141003602b00f0c010b200141043602b80f200120143602b00f2001202e4103743602b40f0b200141d00e6a20032004200141b00f6a107d20012802d80e2103024020012802d00e4101470d002003450d120c110b20012802d40e21142003410376212e0b201420104103746a2203200e36020420032013360200201041016a22272110024020274102490d0002400240024003400240024002400240201420272210417f6a22274103746a2203280200450d00201041037420146a220e41746a280200220d200328020422044d0d00201041024d0d0820142010417d6a22034103746a28020422062004200d6a4d0d01201041034d0d08200e41646a2802002006200d6a4b0d080c010b20104103490d012003280204210420142010417d6a22034103746a28020421060b20062004490d010b2010417e6a21030b02402010200341016a22114d0d00201020034d0d02201420034103746a221a280204220f201a2802006a2203201420114103746a22152802002216490d032003202c4b0d04201a41046a21282026201641286c6a221e2015280204221241286c22046a210e200341286c210602400240200320166b220520126b22032012490d00202d201e200410e908221c20046a210d0240024020124101480d00200520124a0d010b201e2103201c21040c020b202620066a210a201c2104201e210303402003200e2004200e41206a290300200441206a2903005422051b2206290300370300200341206a200641206a290300370300200341186a200641186a290300370300200341106a200641106a290300370300200341086a200641086a2903003703002004200441286a20051b2104200341286a2103200e41286a200e20051b220e200a4f0d02200d20044b0d000c020b0b202d200e200341286c220410e908220520046a210d0240024020124101480d00200341014e0d010b200e2103200521040c010b203020066a2106200e210303402006200341586a220a200d41586a221c200d41786a290300200341786a29030054220e1b2204290300370300200641206a200441206a290300370300200641186a200441186a290300370300200641106a200441106a290300370300200641086a200441086a290300370300200d201c200e1b210d0240201e200a2003200e1b2203490d00200521040c020b200641586a2106200521042005200d490d000b0b20032004200d20046b220620064128706b10e9081a2028200f20126a360200201a20163602002015201541086a20102011417f736a41037410ea081a41012110202741014d0d050c010b0b201120104184d2cc00103c000b200320104194d2cc00103c000b2016200341a4d2cc001057000b2003202c41a4d2cc00104d000b2013450d040c000b0b410120046b201c41d4d1cc00103c000b2006202c41c4d1cc001056000b41baa9c700413e41f8a9c700105d000b0240202e41ffffffff0171450d002014102e0b2037412870210320374128490d0020372003460d00202d102e0b2026202c41286c6a211e4100210a20012802a40a2110202621050340201e2005460d03024002400240024002400240024002400240024002400240024002400240024002402010200510a0022203450d0020032802002103024020012802e00f220e450d00200e41037441786a41037641016a210d4100210620012802d80f2104034020042802002003460d03200441086a2104200d200641016a2206470d000b0b024020012802ec0f221c450d00201c410c6c41746a2106201c410274417c6a41027641016a210e4100210d20012802e40f2104034020042802002003460d04200641746a21062004410c6a2104200e200d41016a220d470d000b0b024020012802f80f220e450d00200e41047441706a41047641016a210d4100210620012802f00f2104034020042802002003460d05200441106a2104200d200641016a2206470d000b0b0240200128028410221c450d00201c41146c416c6a2106201c410274417c6a41027641016a210e4100210d20012802fc0f2104034020042802002003460d062006416c6a2106200441146a2104200e200d41016a220d470d000b0b0240200128029010221c450d00201c41186c41686a2106201c41037441786a41037641016a210e4100210d2001280288102104034020042802002003460d07200641686a2106200441186a2104200e200d41016a220d470d000b0b0240200128029c10221c450d00201c411c6c41646a2106201c410274417c6a41027641016a210e4100210d2001280294102104034020042802002003460d08200641646a21062004411c6a2104200e200d41016a220d470d000b0b024020012802a810220e450d00200e41057441606a41057641016a210d4100210620012802a0102104034020042802002003460d09200441206a2104200d200641016a2206470d000b0b024020012802b410221c450d00201c41246c415c6a2106201c410274417c6a41027641016a210e4100210d20012802ac102104034020042802002003460d0a2006415c6a2106200441246a2104200e200d41016a220d470d000b0b024020012802c010221c450d00201c41286c41586a2106201c41037441786a41037641016a210e4100210d20012802b8102104034020042802002003460d0b200641586a2106200441286a2104200e200d41016a220d470d000b0b024020012802cc10221c450d00201c412c6c41546a2106201c410274417c6a41027641016a210e4100210d20012802c4102104034020042802002003460d0c200641546a21062004412c6a2104200e200d41016a220d470d000b0b024020012802d810221c450d00201c41306c41506a2106201c41047441706a41047641016a210e4100210d20012802d0102104034020042802002003460d0d200641506a2106200441306a2104200e200d41016a220d470d000b0b024020012802e410221c450d00201c41346c414c6a2106201c410274417c6a41027641016a210e4100210d20012802dc102104034020042802002003460d0e2006414c6a2106200441346a2104200e200d41016a220d470d000b0b024020012802f010221c450d00201c41386c41486a2106201c41037441786a41037641016a210e4100210d20012802e8102104034020042802002003460d0f200641486a2106200441386a2104200e200d41016a220d470d000b0b024020012802fc10221c450d00201c413c6c41446a2106201c410274417c6a41027641016a210e4100210d20012802f4102104034020042802002003460d10200641446a21062004413c6a2104200e200d41016a220d470d000b0b024002400240200128028811220e450d00200e41067441406a41067641016a210d410021062001280280112104034020042802002003460d02200441c0006a2104200d200641016a2206470d000b0b024020012802941122120d00410021040c130b201241c4006c41bc7f6a210d2012410274417c6a41027641016a211c4100210e200128028c112106034020062802002003460d02200d41bc7f6a210d200641c4006a210641002104201c200e41016a220e470d000c130b0b2004200441c0006a200e2006417f736a41067410ea081a2001200e417f6a360288110c100b2006200641c4006a200d10ea081a20012012417f6a360294110c0f0b2036450d11203641286c450d112026102e0c110b2004200441086a200e2006417f736a41037410ea081a2001200e417f6a3602e00f0c0d0b20042004410c6a200610ea081a2001201c417f6a3602ec0f0c0c0b2004200441106a200e2006417f736a41047410ea081a2001200e417f6a3602f80f0c0b0b2004200441146a200610ea081a2001201c417f6a360284100c0a0b2004200441186a200610ea081a2001201c417f6a360290100c090b20042004411c6a200610ea081a2001201c417f6a36029c100c080b2004200441206a200e2006417f736a41057410ea081a2001200e417f6a3602a8100c070b2004200441246a200610ea081a2001201c417f6a3602b4100c060b2004200441286a200610ea081a2001201c417f6a3602c0100c050b20042004412c6a200610ea081a2001201c417f6a3602cc100c040b2004200441306a200610ea081a2001201c417f6a3602d8100c030b2004200441346a200610ea081a2001201c417f6a3602e4100c020b2004200441386a200610ea081a2001201c417f6a3602f0100c010b20042004413c6a200610ea081a2001201c417f6a3602fc100b410121040b200541286a2105200a20046a220a2033490d000c030b0b200141d80f6a109b060b202a450d02202a41306c450d022029102e0c020b20012802e40f210320012802e00f210620012802dc0f210e20012802d80f2105200141a0056a200141e80f6a41b00110e9081a02402036450d00203641286c450d002026102e0b200141e00b6a200141a0056a41b00110e9081a0b2001200336029c0d200120063602980d2001200e3602940d200120053602900d200141a00d6a200141e00b6a41b00110e9081a20012029201841306c6a3602e40f200120293602e00f2001202a3602dc0f200120293602d80f200141b00f6a200141d80f6a10c201200141a0056a200141900d6a10ca0120012802b80f210320012802b00f211c200141d80f6a200141a0056a41c00110e9081a200141e00b6a200141d80f6a200141980a6a200141f00e6a108d06024020012802e00b4101460d00200141e00b6a41086a280200210420012802e40b21062001200141e00b6a410c6a2802003602e80b200120043602e40b200120063602e00b200141d80f6a200141e00b6a200141800f6a200141980a6a10e70620012802d80f4101460d00200141d80f6a41086a280200211e200141d80f6a201c200320012802dc0f2212200141d80f6a410c6a280200221010b704024020012802d80f4101460d00200141e00f6a280200211820012802dc0f2114200141e40f6a2802002203410674211a024020030d0042002131417f210e20142103420021234200213242002124417f2105417f210a417f21150c040b201441206a2103201a2105427f2139427f21254200213242002124420021314200212303400240200341106a280200220a0d00200341206a21032039422088a721052025422088a721152039a7210e2025a7210a0c050b200341146a280200210e200141f0006a200341086a290300220b420020032903002208420010e80820014180016a200842002008420010e8082031427f200129038001200b2001290378223a84203a8442005220014180016a41086a290300223a2001290370223b203b7c7c223b203a547222041b7c223a20315422062023427f203b20041b7c2006ad7c223120235420312023511b21042008203954200b202554200b2025511b2106203220087c223b203254220d2024200b7c200dad7c223220245420322024511b210d0240200e450d00200e41306c450d00200a102e0b427f203120041b2123427f203a20041b2131200b202520061b21252008203920061b2139427f2032200d1b2124427f203b200d1b2132200341c0006a2103200541406a22050d000b2039422088a721052025422088a721152039a7210e2025a7210a0c040b02402010450d002010412c6c21042012210303400240200341046a2802002206450d00200641306c450d002003280200102e0b2003412c6a2103200441546a22040d000b0b201e450d00201e412c6c450d002012102e0b024020012802b40f41ffffff3f71450d00201c102e0b200141900d6a109b060b200141900f6a10bd02200141800f6a10bc02024020012802f40e41ffffff3f71450d0020012802f00e102e0b024020012802a00a2203450d00200341386c210420012802980a412c6a210303400240200328020041ffffff3f71450d002003417c6a280200102e0b200341386a2103200441486a22040d000b0b200128029c0a2203450d02200341386c450d0220012802980a102e0c020b2014201a6a220d2003460d0003402003220441c0006a21030240200441346a2802002206450d00200641306c450d00200441306a280200102e0b200d2003470d000b0b0240201841ffffff1f71450d002014102e0b02402010450d002010412c6c21042012210303400240200341046a2802002206450d00200641306c450d002003280200102e0b2003412c6a2103200441546a22040d000b0b0240201e450d00201e412c6c450d002012102e0b200141e80e6a4200370300200141e00e6a4200370300200141d00e6a41086a22034200370300200142003703d00e200141d80f6a41a5fec600411a1081022003200141d80f6a41086a2204290000370300200120012900d80f3703d00e200141d80f6a4180c3c8004105108102200c41086a2004290000370000200c20012900d80f370000200141e8006a200141d00e6a4120108e02200128026c21062001280268210d200141d8086a200141900d6a41c00110e9081a024020012802b40f41ffffff3f71450d00201c102e0b200141900f6a10bd02200141800f6a10bc02024020012802f40e41ffffff3f71450d0020012802f00e102e0b024020012802a00a2203450d00200341386c210420012802980a412c6a210303400240200328020041ffffff3f71450d002003417c6a280200102e0b200341386a2103200441486a22040d000b0b20064101200d1b21040240200128029c0a2203450d00200341386c450d0020012802980a102e0b20014198076a200141d8086a41c00110e9081a200141a0056a41286a22062023370300200141a0056a41186a220d2024370300200120313703c005200120323703b005200120153602ac052001200a3602a805200120053602a4052001200e3602a005200141a0056a41306a20014198076a41c00110e90821032001200436029007200141d80f6a200141a0056a10b8060240024020012d00d80f4106470d00200141900d6a200310ca01200141d80f6a41286a2006290300370300200141d80f6a41206a200141a0056a41206a290300370300200141d80f6a41186a200d290300370300200141d80f6a41106a200141a0056a41106a290300370300200141d80f6a41086a200141a0056a41086a290300370300200120012903a0053703d80f2001280290072104200141d80f6a41306a200141900d6a41c00110e9081a200120043602c811200141d8086a200141d80f6a10b90620012802d8084101470d010b2003109b060c020b20014194096a280200210e20014190096a280200210d0240200141d8086a41c0006a2802002203450d0020034106742104200d41346a21030340024020032802002206450d00200641306c450d002003417c6a280200102e0b200341c0006a2103200441406a22040d000b0b200141ac056a21030240200e41ffffff1f71450d00200d102e0b20012903a005210b20012802a8052104200141b0036a200341ec0110e9081a200141c0016a200141b0036a41ec0110e9081a200141a0056a200141c0016a41ec0110e9081a20014180116a2004360200200141f8106a200b3703002001411b3602f010200142023703c01020014184116a200141a0056a41ec0110e9081a200141f4126a2035360200200141f0126a202f3602002001200141d80f6a3602b003200141c0016a200141b0036a109005200141b0036a41086a200141c0016a41086a280200360200200120012903c0013703b003200141b0036a10e8061a024020012903c0104202510d0020012d00d80f41ff01714102470d0020012802e00f450d0020012802dc0f102e0b200141f0106a108b020c010b20014198076a200141d8086a41c00110e9081a0b024010e906450d00200141d80f6a41186a220e4200370300200141d80f6a41106a22044200370300200141d80f6a41086a22034200370300200142003703d80f200141a0056a41a8f8c60041041081022003200141a0056a41086a2206290000370300200120012900a0053703d80f200141a0056a41c98bc500410b108102200e2006290000370300200420012900a005370300200141d8006a200141d80f6a1085032001290360210820012802582105200141d00e6a41186a220a4200370300200141d00e6a41106a220d4200370300200141d00e6a41086a221c4200370300200142003703d00e200141d80f6a41a8f8c6004104108102201c2003290000370300200120012900d80f3703d00e200141d80f6a41fa8bc500410a108102200a2003290000370300200d20012900d80f370300200141c8006a200141d00e6a108503200141386a2001290350420020012802481b420042e012420010e80802400240024002400240200129034050450d002001290338210b200e42003703002004420037030020034200370300200142003703d80f200141a0056a41a8f8c600410410810220032006290000370300200120012900a0053703d80f200141a0056a41e38bc500410b108102200441086a2006290000370000200420012900a005370000200141286a200141d80f6a1085030240200b2001290330420020012802281b7c2223200b540d00024042002008420020051b220b20237d22082008200b561b42017c220b42e012200b42e012541b421880a741ff017141314b0d00200120223602840c2001201b3602800c200120193602fc0b200120203602f80b200120213602f40b2001201f3602f00b200120093602ec0b2001201d3602e80b200120073602e40b200120173602e00b41002103200141e00b6a211e200141b00f6a21170c060b200141d00e6a41186a4200370300200141d00e6a41106a4200370300200141d00e6a41086a22044200370300200142003703d00e200141d80f6a41a081ca0041071081022004200141d80f6a41086a2203290000370300200120012900d80f3703d00e200141d80f6a41e4d1c100410c108102200d41086a2003290000370000200d20012900d80f370000200141206a200141d00e6a4120108e022001280224212720012802202111200141d80f6a41186a22044200370300200141d80f6a41106a2206420037030020034200370300200142003703d80f200141a0056a41bed8c80041081081022003200141a0056a41086a220d290000370300200120012900a0053703d80f200141a0056a41e9d8c80041041081022004200d290000370300200620012900a005370300200141b0036a41046a41003a0000200141003602b003200141186a200141d80f6a4120200141b0036a4105410010ca040240024002402001280218450d002001200128021c2203410520034105491b3602a4052001200141b0036a3602a005200141106a200141a0056a10ab012001280210450d010b410021160c010b200128021421160b200141b0036a108703200141d80f6a41e9dabdf30610ea0620012802dc0f211320012802d80f22102103024020012802e00f2204450d0020044105742104201021030340200341206a2103200441606a22040d000b0b02400240200320106b410575221241144b0d00201241014d0d0620102012417e6a22034105746a210441022106034020122003490d022004200610eb06200441606a2104200641016a21062003417f6a2203417f470d000c070b0b2012410176220341ffffff3f712003470d0920034105742226417f4c0d092026102c2214450d08201041606a2115201041a07f6a210c4104212241002118410021212012211a0340201a211b4100211a410121060240201b417f6a220d450d000240024002400240024002402010200d4105746a201b410574220520106a41406a412010ec084100480d00201b417e6a210d200c20056a21034100211a4100210403400240200d2004470d00201b21060c080b200441016a2104200341206a2003412010ec082106200341606a21032006417f4a0d000b200441016a21062004417f73201b6a210d0c010b200c20056a2103024003400240200d4101470d004100210d0c020b200d417f6a210d200341206a2003412010ec082104200341606a210320044100480d000b0b201b200d490d01201b20124b0d02201b200d6b2206410176220e450d00201520056a21032010200d4105746a21040340200141d00e6a41186a2205200441186a220a290000370300200141d00e6a41106a2207200441106a2209290000370300200141d00e6a41086a2219200441086a2217290000370300200120042900003703d00e200341086a221d290000210b200341106a221f2900002108200341186a2220290000212320042003290000370000200a2023370000200920083700002017200b37000020202005290300370000201f2007290300370000201d2019290300370000200320012903d00e370000200341606a2103200441206a2104200e417f6a220e0d000b0b0240200d0d00200d211a0c050b0240200641094d0d00200d211a0c050b201b20124b0d02201b200d6b2106200d417f6a21032015200d4105746a21040340201b2003490d0a2004200641016a220610eb062003417f6a220d20034f0d04200441606a2104200d21032006410a490d000c040b0b200d201b41e4d1cc001057000b201b201241e4d1cc00104d000b201b200d417f6a2203490d06201b201241f4d1cc00104d000b200d41016a211a0b024020212018470d00201841016a22032018490d0b201841017422042003200420034b1b22034104200341044b1b220341ffffffff01712003464102742104200341037421030240024020180d00200141003602d80f0c010b200141043602e00f200120223602d80f200120184103743602dc0f0b200141a0056a20032004200141d80f6a107d20012802a8052103024020012802a0054101470d002003450d0c0c0b0b20012802a4052122200341037621180b202220214103746a220320063602042003201a360200202141016a22202121024020204102490d0002400240024003400240024002400240202220202221417f6a22204103746a2203280200450d00202141037420226a220e41746a280200220d200328020422044d0d00202141024d0d0820222021417d6a22034103746a28020422062004200d6a4d0d01202141034d0d08200e41646a2802002006200d6a4b0d080c010b20214103490d012003280204210420222021417d6a22034103746a28020421060b20062004490d010b2021417e6a21030b02402021200341016a221b4d0d00202120034d0d02202220034103746a2217280204221c20172802006a22032022201b4103746a221d280200221f490d03200320124b0d04201741046a211e2010201f4105746a2209201d280204221941057422046a210d20034105742106024002402003201f6b220520196b22032019490d0020142009200410e908220720046a210e0240024020194101480d00200520194a0d010b20092103200721040c020b201020066a210a200721042009210303402003200d2004200d2004412010ec0841004822051b2206290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a2900003700002004200441206a20051b2104200341206a2103200d41206a200d20051b220d200a4f0d02200e20044b0d000c020b0b2014200d2003410574220410e908220720046a210e0240024020194101480d00200341014e0d010b200d2103200721040c010b201520066a2106200d21030340200341606a2104200e41606a210d20062004200d200d2004412010ec08410048220a1b2205290000370000200641186a200541186a290000370000200641106a200541106a290000370000200641086a200541086a290000370000200e200d200a1b210e0240200920042003200a1b2203490d00200721040c020b200641606a2106200721042007200e490d000b0b20032004200e20046b41607110e9081a201e201c20196a3602002017201f360200201d201d41086a2021201b417f736a41037410ea081a41012121202041014d0d050c010b0b201b20214184d2cc00103c000b200320214194d2cc00103c000b201f200341a4d2cc001057000b2003201241a4d2cc00104d000b201a450d050c000b0b2003201241c4d1cc001056000b41e8b2c40041fa0041f4b3c400105d000b41e8b2c40041fa0041e4b3c400105d000b2003201b41f4d1cc001057000b0240201841ffffffff0171450d002022102e0b2026450d002014102e0b20012802b403210420012802b003210320012802b8032106200120163602d40f200120003602d00f20012027410020111b220d3602cc0f200120123602c80f200120133602c40f200120103602c00f200141003602bc0f2001200320064105746a22063602b80f200120033602b40f200120043602b00f200120163602840c200120003602800c2001200d3602fc0b200120123602f80b200120133602f40b200120103602f00b200141003602ec0b200120063602e80b200120033602e40b200120043602e00b200141e00b6a211e200141b00f6a21170b200141d80f6a41106a2204201741106a221d290200220b370300200141d80f6a41186a2206201741186a221f2902002208370300200141b0036a41086a220d201741086a2220290200370300200141b0036a41106a220e200b370300200141b0036a41186a22052008370300200141b0036a41206a220a201741206a221b290200370300200141c0016a41206a2207200141a0056a41206a290200370300200141c0016a41186a2209200141a0056a41186a290200370300200141c0016a41106a2221200141a0056a41106a290200370300200141c0016a41086a2219200141a0056a41086a290200370300200120172902003703b003200120012902a0053703c001200141900d6a41206a2222200141d80f6a41206a221c290300370300200141900d6a41186a22102006290300370300200141900d6a41106a22122004290300370300200141900d6a41086a2214200141d80f6a41086a221a290300370300200120012903d80f3703900d200120033602dc0f200141013602d80f201a20012903b0033703002004200d2903003703002006200e290300370300201c200529030037030020014180106a200a29030037030020014100360288102001418c106a220320012903c00137020020014194106a20192903003702002001419c106a2021290300370200200141a4106a2009290300370200200141ac106a2007290300370200200141003602b410200141d8106a2022290300370300200141d0106a2010290300370300200141c8106a2012290300370300200141c0106a2014290300370300200141b8106a221020012903900d370300200141b4106a211c20014188106a2122200141f40f6a2106200141ec0f6a210d200141e40f6a210e20014190106a210920014198106a2121200141a0106a2119410021040340024002402004450d00202210ec064108470d0102402001280288102204450d000240200128028c1041ffffff3f71450d002004102e0b20012802a01041ffffff3f71450d00200128029c10102e0b20032017290200370200200341086a2020290200370200200341106a201d290200370200200341186a201f290200370200200341206a201b29020037020020014100360288100b20062902002108200620012903b805370200200d2902002123200d20012903b005370200200e2902002124200e20012903a805370200200141003602a00520012902dc0f210b200120012903a0053702dc0f0240200ba72204450d0020012802fc0f2105200128028010210a20012802841021072001200b37038810200920243703002021202337030020192008370300200120073602b0102001200a3602ac10200120053602a8100c020b024020012802b410450d00201c10ec064108470d01024020012802b4102203450d000240200141b8106a28020041ffffff3f71450d002003102e0b200141cc106a28020041ffffff3f71450d0020012802c810102e0b2010201e290200370200201041086a201e41086a290200370200201041106a201e41106a290200370200201041186a201e41186a290200370200201041206a201e41206a290200370200200141003602b4100b024020012802d80f450d0020012802dc0f2203450d00024020012802e00f41ffffff3f71450d002003102e0b200141f40f6a28020041ffffff3f71450d00200141f00f6a280200102e0b02402001280288102203450d000240200128028c1041ffffff3f71450d002003102e0b20012802a01041ffffff3f71450d00200128029c10102e0b20012802b4102203450d020240200141b8106a28020041ffffff3f71450d002003102e0b200141cc106a28020041ffffff3f71450d0220012802c810102e0c020b20012802881021040c000b0b200224000f0b1036000b1038000b1800200020014101472003ad4220862002ad84101a10da080b8d0101017f230041206b22062400200641086a200310dc0820004101472002ad4220862001ad84200641186a200641106a2200200628020822014101461b2903002005ad4220862004ad841019210202402001450d002000280200450d00200628020c102e0b024020032802002201450d00200341046a280200450d002001102e0b200641206a240020024101460b4401017f2000101d2201290000370000200041186a200141186a290000370000200041106a200141106a290000370000200041086a200141086a2900003700002001102e0bc11d09097f027e057f017e027f017e017f047e037f230041f0006b220424000240200241086a22052802002206200120062001491b2207450d00410021080240024002400240024003402002280200210902402006410274220a450d00200a210b2009210c02400340200c28020022012802080d012001417f3602080240200141f4006a2d00000d0002402001290330220d200141386a290300220e844200520d00200142013703202001427f370310200141286a4200370300200141186a427f3703000c010b200441086a427f427f200d200e10e7082001427f370320200141286a427f370300200141186a200441086a41086a290300370300200120042903083703100b200c41046a210c20014100360208200b417c6a220b0d000c020b0b4194dacc004110200441186a41c498c90041d498c900103e000b2003280200220f2003280208221041e0006c6a211102402010450d00200f21120340024020122802382201450d00200141d8006c2113201228023041306a210c02400340200c28020022012802080d01417f210b2001417f3602080240200141f4006a2d00000d002001290330220d200141386a290300220e84500d00200441186a2012290310201241186a2903002012290300201241086a290300200d200e10ea0420012001290310220d427f200d427f20042903202004280218410146220b1b22147c220e200e200d542215200141186a2216290300220d427f200441186a41106a290300200b1b22177c2015ad7c220e200d54200e200d511b220b1b20142017845022151b3703102016200d427f200e200b1b20151b3703002001280208210b0b2001200b41016a360208200c41d8006a210c201341a87f6a2213450d020c000b0b4194dacc004110200441186a41c498c900418499c900103e000b201241e0006a22122011470d000b0b200841016a21182009200a6a2116200641027421012009417c6a210b03402001450d07200b41046a220b280200220c280208221341016a41004c0d06200c20133602082001417c6a2101200c41f4006a2d00000d000b200b2802002213280208220c41016a41004c0d042013200c36020802402001450d00200b41046a210c201341286a2903002114201341186a2903002119201329032021172013290310211a0340200c2802002201280208221341016a41004c0d05200120133602080240200141f4006a2d00000d0020012013360208200141186a290300210d2001290310210e02400240024020172001290320221b852014200141286a290300221c85844200520d00201a200e542019200d542019200d511b0d03201a200e852019200d858442005221120c010b2017201484500d01201b201c84500d024110102c2201450d072001201a3e020c2001201a4220883e0208200120193e0204200120194220883e020020044284808080c00037025420042001360250200441d0006a10bb074110102c2201450d072001201b3e020c2001201b4220883e02082001201c3e02042001201c4220883e020020044284808080c00037026420042001360260200441e0006a10bb07200441186a41086a2213200441d0006a41086a221228020036020020042004290350370318200441306a200441186a200441e0006a10bc070240200428026441ffffffff0371450d002004280260102e0b4110102c2201450d072001200e3e020c2001200e4220883e02082001200d3e02042001200d4220883e020020044284808080c00037025420042001360250200441d0006a10bb074110102c2201450d07200120173e020c200120174220883e0208200120143e0204200120144220883e020020044284808080c00037026420042001360260200441e0006a10bb072013201228020036020020042004290350370318200441c0006a200441186a200441e0006a10bc070240200428026441ffffffff0371450d002004280260102e0b2004280230211d024002402004280238221e0d0041012106410021130c010b201e4102742212417c6a41027641016a211541002113201d2101034002402001280200450d00410021060c020b200141046a210141012106201341016a21132012417c6a22120d000b201521130b2004280240210a024002400240024002402004280248221f450d00200a201f4102746a210941002112201f2115200a2101034020012802000d022015417f6a2115201241016a2112200141046a22012009470d000b0b410121124100210920060d010c030b410121092006450d010b410020096b21120c010b201e2013490d07417f201f20126b2212201e20136b22064720062012491b22120d00201d20134102746a21092015200620152006491b41016a211541002113034002402015417f6a22150d00410021120c020b200120136a2112200920136a2106201341046a2113417f20062802002206201228020022124720062012491b2212450d000b0b0240200428024441ffffffff0371450d00200a102e0b200428023441ffffffff0371450d00201d102e0b20124101470d010b200e211a200d2119201b2117201c2114200c210b0b200c41046a220c2016470d000b0b200b450d060240200b280200220c2802080d00417f2101200c417f360208200c2008360250200c41f4006a41013a000002402010450d00200c41106a41c4006a21120340200f221341e0006a210f02402013280238220b450d0020132802302101200b41d8006c210b03400240200141346a2012412010ec080d00201341186a22152903002117200c41186a2216290300210d20132903102114200c290310210e200c2903202119200141186a200c41286a2206290300370300200141106a20193703002001200d4200200d20177d200e201454ad7d2219200e20147d221b200e562019200d562019200d511b22091b201420178450220a1b3703082001200e4200201b20091b200a1b3703002016290300210d2006290300210e200c29031021142013200c290320370320201341286a200e370300201320143703102015200d3703000b200141d8006a2101200b41a87f6a220b0d000b0b200f2011470d000b200c28020821010b200c200141016a36020820182007460d0720052802002106201821080c010b0b4194dacc004110200441186a41c498c900419499c900103e000b2013201e41d4dacc001056000b1036000b41bcd9cc004118200441186a41f09cc50041f498c900103e000b41bcd9cc004118200441186a41b4ebc00041e09dc500103e000b41bcd9cc004118200441186a41e498c90041f498c900103e000b20032802002201200328020841e0006c6a2111200441286a2116024003400240024002402001220b2011460d00200b41386a220a280200220c0d0141002115200a4100360200410021090c020b200441186a41086a2201200241086a280200360200200441186a41146a200341086a2802003602002000410036020020002002290200370204200420032902003702242000410c6a2001290300370200200041146a200441286a2903003702000c030b200b2802302101200c41d8006c2113024003400240200141306a2212280200220c280208221541016a41004a0d0041bcd9cc004118200441186a41e498c90041a499c900103e000b200c201536020802400240200c41f4006a2d0000450d00200441186a200b290300200b41086a2903002001290300200141086a290300200b290310200b41186a29030010ea042004290320210d200141286a427f20162903002004280218410146220c1b370300200141206a427f200d200c1b3703000c010b200141286a4200370300200141206a42003703000b02402012280200220c2802080d00200c417f360208200141206a290300210d200141286a290300210e200c4100360208200c427f200d200c29034022147c220d200d2014542212200e200c41c8006a2215290300220d7c2012ad7c220e200d54200e200d511b22121b3703402015427f200e20121b370300200141d8006a2101201341a87f6a2213450d020c010b0b4194dacc004110200441186a41c498c90041b499c900103e000b200a280200211541002109200a41003602002015450d0041002106410021094100210c02400340024002402009450d00200c41d8006c21010340200b280230221220016a221341206a290300201341286a290300844200510d02201220066a20016a201341d80010e9081a200141d8006a21012015200c41016a220c4b0d000c040b0b200b2802302212200c41d8006c6a41206a210103402001290300200141086a29030084500d01200141d8006a21012015200c41016a220c4b0d000b410021090c030b2012200c41d8006c6a220128023022132013280200417f6a360200200c41016a210c0240200128023022132802000d00201341046a22132013280200417f6a360200200141306a280200220141046a2802000d002001102e0b200941016a2109200641a87f6a21062015200c4b0d000b0b024020090d00410021090c010b200b2802302201200c20096b41d8006c6a2001200c41d8006c6a2015200c6b41d8006c10ea081a0b200b41e0006a2101200a201520096b3602002004200b10bb042004280200220c450d000b200428020421012000428180808030370200200041086a2001ad422086200cad8437020020032802002115024020032802082201450d002015200141e0006c6a211220152101034002402001221341386a2802002201450d00200141d8006c210c201328023041306a210103402001280200220b200b280200417f6a36020002402001280200220b2802000d00200b41046a220b200b280200417f6a3602002001280200220b41046a2802000d00200b102e0b200141d8006a2101200c41a87f6a220c0d000b0b201341e0006a21010240201341346a280200220c450d00200c41d8006c450d002013280230102e0b20012012470d000b0b0240200341046a2802002201450d00200141e0006c450d002015102e0b200228020021130240200241086a2802002201450d002001410274210c2013210103402001280200220b200b280200417f6a36020002402001280200220b2802000d00200b41046a220b200b280200417f6a3602002001280200220b41046a2802000d00200b102e0b200141046a2101200c417c6a220c0d000b0b200241046a28020041ffffffff0371450d002013102e0b200441f0006a24000b930301067f230041106b2202240002400240024002400240024020014102490d0020002802042203280208220441016a41004c0d022003200436020820002802002204280208220541016a41004c0d032003280250210320042005360208200320042802504f0d00200028020021032000200028020436020002400240200141034f0d00200041046a21000c010b200041046a21042001417f6a21060340200441046a22002802002205280208220741016a41004c0d06200520073602082003280208220741016a41004c0d072005280250210520032007360208024020052003280250490d00200421000c020b2006450d0320042000280200360200200021042006417f6a22064101470d000b0b200020033602000b200241106a24000f0b2001200141d4d1cc00103c000b41bcd9cc004118200241086a41c4f8c90041d4f8c900103e000b41bcd9cc004118200241086a41c4f8c90041d4f8c900103e000b41bcd9cc004118200241086a41c4f8c90041d4f8c900103e000b41bcd9cc004118200241086a41c4f8c90041d4f8c900103e000bb51006037f017e017f017e0c7f027e23004180026b22022400200141346a2802002103200141386a2802002104200141086a29030021052001280230210620012903002107200241086a41186a200141d4006a290000370300200241086a41106a200141cc006a290000370300200241086a41086a200141c4006a2900003703002002200129003c37030820022005370330200220073703282006200441d8006c22086a21092006210102400240024002402004450d004100210a20024198016a41086a210b20024198016a41106a210c20024198016a41186a210d024002400340200b2006200a6a2201413c6a290200370300200c200141c4006a290200370300200d200141cc006a29020037030020024198016a41206a200141d4006a2802003602002002200141346a29020037039801200141306a280200220e450d02200141286a2903002105200141206a2903002107200241e0016a41186a220f200d290300370300200241e0016a41106a2210200c290300370300200241e0016a41086a2211200b29030037030020022002290398013703e00102400240200720052002290328200241286a41086a29030010e606221241ffff03710d004100210f0c010b200241c0016a41186a200f290300370300200241c0016a41106a2010290300370300200241c0016a41086a2011290300370300200220022903e0013703c0014101210f201221130b200e200e280200417f6a2210360200024020100d00200e41046a22102010280200417f6a221036020020100d00200e102e0b200f0d012008200a41d8006a220a470d000b200921010c020b200241386a41086a220e200241c0016a41086a290300370300200241386a41106a220b200241c0016a41106a290300370300200241386a41186a220c200241c0016a41186a290300370300200220022903c00122053703582002200537033802404122102c2208450d0020082002290338370100200820133b0120200841186a200c290300370100200841106a200b290300370100200841086a200e290300370100200220093602442002200141d8006a220b3602402002200336023c200220063602382002200241286a360248024002400240200441d8006c41a87f6a200a470d0041012103410121040c010b20024198016a41086a210a20024198016a41106a210c20024198016a41186a210d410121034101210403402002200b220141d8006a220b360240200141306a280200210e200141286a2903002105200141206a2903002107200a2001413c6a290200370300200c200141c4006a290200370300200d200141cc006a29020037030020024198016a41206a200141d4006a2802003602002002200141346a2902003703980102400240200e450d00200241e0016a41186a2210200d290300370300200241e0016a41106a2211200c290300370300200241e0016a41086a2212200a29030037030020022002290398013703e00102400240200720052002280248220f290300200f41086a29030010e606220641ffff03710d004100210f0c010b200241c0016a41186a2010290300370300200241c0016a41106a2011290300370300200241c0016a41086a2012290300370300200220022903e0013703c0014101210f200621130b200e200e280200417f6a2210360200024020100d00200e41046a22102010280200417f6a221036020020100d00200e102e0b200f0d012009200b470d020b200141d8006a210b0c020b200241d8006a41086a200241c0016a41086a2903002205370300200241d8006a41106a200241c0016a41106a2903002207370300200241d8006a41186a200241c0016a41186a2903002214370300200220022903c0012215370358200d2014370300200c2007370300200a20053703002002201537039801024020042003470d00200341016a22012003490d092003410174220e2001200e20014b1b22014104200141044b1bad42227e2205422088a74541017421012005a7210e0240024020030d00200241003602e0010c010b200241023602e801200220083602e0012002200341226c3602e4010b200241c0016a200e2001200241e0016a107d20022802c801210120022802c0014101460d0320022802c4012108200141226e21030b2008200441226c6a2201200229039801370100200c2903002105200d2903002107200a2903002114200120133b0120200141086a2014370100200141186a2007370100200141106a2005370100200441016a21042002280240220b20022802442209470d000b0b2009200b6b220141d8006d210e02402001450d00200e41d8006c210e200b41306a210103402001280200220a200a280200417f6a36020002402001280200220a2802000d00200a41046a220a200a280200417f6a3602002001280200220a41046a2802000d00200a102e0b200141d8006a2101200e41a87f6a220e0d000b0b0240200228023c2201450d00200141d8006c450d002002280238102e0b2004450d042000200336020420002008360200200041086a20043602002000410c6a2002290308370000200041146a200241086a41086a2903003700002000411c6a200241186a290300370000200041246a200241206a2903003700000c050b2001450d050b1036000b200141d8006a21010b024020092001460d000340200141306a220e280200220a200a280200417f6a360200200141d8006a21010240200e280200220a2802000d00200a41046a220a200a280200417f6a360200200e280200220e41046a2802000d00200e102e0b20092001470d000b0b02402003450d00200341d8006c450d002006102e0b200041003602000c010b200041003602002003450d00200341226c450d002008102e0b20024180026a24000f0b1038000bd6d20102517f0d7e230041c0076b22012400200141003602e4022001420037020c0240024002400240200041086a220228020022030d002001410036020c0c010b200141f8016a41c0006a2104200141c8066a41c0006a2105200141a8036a41c0006a2106200141c8066a41206a2107200141386a41206a2108200141186a41106a2109200141186a41186a210a200141c8066a41d8006a210b200141c8066a41d0006a210c200141c8066a41c8006a210d4100210e03400240024002402002280200220f200e4d0d00200141186a41086a22102000280200200e412c6c22116a220f41146a2900003703002009200f411c6a290000370300200a200f41246a2900003703002001200f29000c370318200f280208221241ffffff3f712012470d0620124105742213417f4c0d06200f280200210f0240024020130d00410121140c010b2013102c2214450d060b0240024002402013410576221520124f0d00201341047622162012201620124b1b22164104201641044b1b221641ffffff3f712016462117201641057421160240024020130d00200141003602c8060c010b200141013602d006200120133602cc06200120143602c8060b200141c8056a20162017200141c8066a107d20012802d005211320012802c8054101460d0120012802cc052114201341057621150b200f200f201241306c22136a460d03201341506a41306e21182014211203402012200f290000370000201241186a200f41186a290000370000201241106a200f41106a290000370000201241086a200f41086a290000370000201241206a2112200f41306a210f201341506a22130d000b201841016a22194102490d032019417f6a20196c410176220f41ffffff1f71200f470d08200f410674220f417f4c0d084101211a4101211b0240200f450d00200f102c221b450d080b201441206a211c200f410676211d410021134100211e0c010b20130d060c070b03400240201e220f41016a221e20194f0d0002400240200f20194f0d00201a201a2019201a20194b1b6b211f2014200f4105746a2116201e2019201e20194b1b2120201341017421212013410674211720182122201c21120340200141a8066a41186a220f201641186a290000370300200141a8066a41106a2223201641106a290000370300200141a8066a41086a2224201641086a290000370300200120162900003703a806201f450d02200141c8066a41186a2225200f290300370300200141c8066a41106a22262023290300370300200141c8066a41086a22232024290300370300200120012903a8063703c80620072012290000370000200741086a201241086a290000370000200741106a201241106a290000370000200741186a201241186a290000370000024002402013201d470d00201341016a220f2013490d0d2021200f2021200f4b1b220f4104200f41044b1b220f41ffffff1f71200f462124200f410674210f0240024020130d00200141003602c8050c010b200141013602d005200120173602cc052001201b3602c8050b20014188046a200f2024200141c8056a107d200128029004210f2001280288044101460d01200128028c04211b200f410676211d0b201b20176a220f20012903c806370000200f41386a200141c8066a41386a290300370000200f41306a200141c8066a41306a290300370000200f41286a200141c8066a41286a290300370000200f41206a2007290300370000200f41186a2025290300370000200f41106a2026290300370000200f41086a2023290300370000201f41016a211f201241206a2112202141026a2121201741c0006a2117201341016a21132022417f6a2222450d040c010b0b200f450d0a0c090b200f201941b8aac700103c000b2020201941c8aac700103c000b2018417f6a2118201a41016a211a201c41206a211c201e2019470d000b2013450d02201b20134106746a2127201b21230340200141386a41386a202341386a290000370300200141386a41306a202341306a290000370300200141386a41286a202341286a2900003703002008202341206a290000370300200141386a41186a202341186a220f290000370300200141386a41106a202341106a2212290000370300200141386a41086a202341086a221329000037030020012023290000370338200141f8006a41186a2216200f290000370300200141f8006a41106a220f2012290000370300200141f8006a41086a221220132900003703002001202329000037037820014198016a41186a200841186a221329000037030020014198016a41106a200841106a221729000037030020014198016a41086a200841086a221f2900003703002001200829000037039801200141c8066a41186a22252016290300370300200141c8066a41106a2226200f290300370300200141c8066a41086a2219201229030037030020072008290000370000200741086a201f290000370000200741106a2017290000370000200741186a2013290000370000200120012903783703c80602400240200128020c221f450d00200128020821210c010b41a808102c221f450d0741002121201f41003b0106201f41003602002001201f36020c200141003602080b202341c0006a21230340201f41286a210f201f2f010621164100211203400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020162012460d0002400240200141c8066a200f41606a412010ec082213450d002013417f4c0d010c270b2007200f412010ec082213450d02201341004e0d260b201221160b2021450d012021417f6a2121201f20164102746a41a8086a280200211f0c260b2002280200221e200e4d0d022000280200222220116a220f28020841306c2216450d22201f20124105746a41c8056a2124200f280200210f41002113034002400240200f200141f8006a412010ec080d00410121170c010b200f20014198016a412010ec084521170b200f41306a210f201720136a2113201641506a22160d000b20134102470d22201e412c6c210f202241546a21130340200f450d23200f41546a210f2013412c6a21132022410c6a21162022412c6a212220162024412010ec080d000b0240201341086a280200220f450d0020132802002217200f41306c22226a2116410021130340201720136a220f200141f8006a412010ec08450d03200f20014198016a412010ec08450d032022201341306a2213470d000b0b4108211e4100211a0c0f0b200141b8016a41386a220f200141c8066a41386a2228290300370300200141b8016a41306a2212200141c8066a41306a2229290300370300200141b8016a41286a2213200141c8066a41286a222a290300370300200141b8016a41206a22172007290300370300200141b8016a41186a22212025290300370300200141b8016a41106a22222026290300370300200141b8016a41086a22242019290300370300200120012903c8063703b801200141a8036a41386a222b200f290300370300200141a8036a41306a222c2012290300370300200141a8036a41286a222d2013290300370300200141a8036a41206a222e2017290300370300200141a8036a41186a222f2021290300370300200141a8036a41106a22302022290300370300200141a8036a41086a22312024290300370300200120012903b8013703a803200141a8066a41186a2232200a290300370300200141a8066a41106a22332009290300370300200141a8066a41086a22342010290300370300200120012903183703a8060240201f2f0106220f410a4b0d00200141c8056a41186a22172032290300370300200141c8056a41106a22212033290300370300200141c8056a41086a22222034290300370300200120012903a8063703c8052028202b2903003703002029202c290300370300202a202d2903003703002007202e2903003703002025202f2903003703002026203029030037030020192031290300370300200120012903a8033703c806201f41086a2113200f41016a21120240201641016a2224200f4b221e0d00201320244106746a201320164106746a20122016417f736a41067410ea081a0b201320164106746a220f20012903c806370000200f41386a2028290300370000200f41306a2029290300370000200f41286a202a290300370000200f41206a2007290300370000200f41186a2025290300370000200f41106a2026290300370000200f41086a2019290300370000200141e8026a41186a22132017290300370300200141e8026a41106a22172021290300370300200141e8026a41086a22212022290300370300200120012903c8053703e802201f41c8056a210f0240201e0d00200f20244105746a200f20164105746a20122016417f736a41057410ea081a0b200f20164105746a220f20012903e802370000200f41186a2013290300370000200f41106a2017290300370000200f41086a2021290300370000201f20123b01060c210b410021214104211302400240201641054f0d00201621170c010b4105211341052117024002402016417b6a0e020201000b201641796a211741012121410621130c010b41002117410121210b41a808102c2212450d2b201241003b0106201241003602002012201f2f010622222013417f736a22163b0106200141c8056a41386a2235201f41086a222420134106746a220f41386a290000370300200141c8056a41306a2236200f41306a290000370300200141c8056a41286a2237200f41286a290000370300200141c8056a41206a2238200f41206a290000370300200141c8056a41186a2239200f41186a290000370300200141c8056a41106a223a200f41106a290000370300200141c8056a41086a223b200f41086a2900003703002001200f2900003703c805200141e8026a41186a223c201f41c8056a221e20134105746a220f41186a290000370300200141e8026a41106a223d200f41106a290000370300200141e8026a41086a223e200f41086a2900003703002001200f2900003703e8022016410c4f0d022022201341016a220f6b2016470d03201241086a2024200f4106746a201641067410e9081a201241c8056a201e200f4105746a201641057410e9081a201f20133b01062028203529030037030020292036290300370300202a203729030037030020072038290300370300202520392903003703002026203a2903003703002019203b290300370300200520012903e802370000200541086a223f203e290300370000200541106a2240203d290300370000200541186a2241203c290300370000200120012903c8053703c806200141c8056a200141c8066a41e00010e9081a200141e8046a41186a22422032290300370300200141e8046a41106a22432033290300370300200141e8046a41086a22442034290300370300200120012903a8063703e8042012201f20211b22132f0106210f2028202b2903003703002029202c290300370300202a202d2903003703002007202e2903003703002025202f2903003703002026203029030037030020192031290300370300200120012903a8033703c806201341086a2121200f41016a21160240201741016a2222200f4b22240d00202120224106746a202120174106746a20162017417f736a41067410ea081a0b202120174106746a220f20012903c806370000200f41386a2028290300370000200f41306a2029290300370000200f41286a202a290300370000200f41206a2007290300370000200f41186a2025290300370000200f41106a2026290300370000200f41086a2019290300370000203c2042290300370300203d2043290300370300203e2044290300370300200120012903e8043703e802201341c8056a210f024020240d00200f20224105746a200f20174105746a20162017417f736a41057410ea081a0b200f20174105746a220f20012903e802370000200f41186a203c290300370000200f41106a203d290300370000200f41086a203e290300370000201320163b010620014188046a200141c8056a41e00010e9081a200141a8036a20014188046a41e00010e9081a024002400240201f28020022210d00410021450c010b41002145201221460340201f2f01042117200141e8046a41386a2247202b290300370300200141e8046a41306a2248202c290300370300200141e8046a41286a2249202d290300370300200141e8046a41206a224a202e2903003703002042202f2903003703002043203029030037030020442031290300370300200120012903a8033703e804200141a8056a41186a224b200641186a290000370300200141a8056a41106a224c200641106a290000370300200141a8056a41086a224d200641086a290000370300200120062900003703a8054101450d0720212f0106224e410b490d024100212041042116024020174105490d0020172116024002402017417b6a0e020201000b201741796a211741012120410621160c010b4100211741012120410521160b41d808102c2212450d2e201241003b010620124100360200201220212f0106224f2016417f736a22133b010620014188046a41386a221f202141086a225020164106746a220f41386a29000037030020014188046a41306a2222200f41306a29000037030020014188046a41286a2224200f41286a29000037030020014188046a41206a221e200f41206a29000037030020014188046a41186a221a200f41186a29000037030020014188046a41106a2218200f41106a29000037030020014188046a41086a221c200f41086a2900003703002001200f29000037038804203c202141c8056a225120164105746a220f41186a290000370300203d200f41106a290000370300203e200f41086a2900003703002001200f2900003703e8022013410c4f0d08204f201641016a220f6b2013470d09201241086a2050200f4106746a201341067410e9081a201241c8056a2051200f4105746a201341057410e9081a202120163b01062028201f29030037030020292022290300370300202a20242903003703002007201e2903003703002025201a290300370300202620182903003703002019201c290300370300200520012903e802370000203f203e2903003700002040203d2903003700002041203c29030037000020012001290388043703c80620122f0106221341016a214f2013410c4f0d0a204e20166b2216204f470d0b204541016a2145201241a8086a2021200f4102746a41a8086a201641027410e9081a4100210f024003402012200f4102746a41a8086a2802002216200f3b010420162012360200200f200f20134922166a220f20134b0d0120160d000b0b200141c8056a200141c8066a41e00010e9081a201f20472903003703002022204829030037030020242049290300370300201e204a290300370300201a204229030037030020182043290300370300201c2044290300370300200120012903e804370388042032204b2903003703002033204c2903003703002034204d290300370300200120012903a8053703a8062012202120201b22162f010621202028201f29030037030020292022290300370300202a20242903003703002007201e2903003703002025201a290300370300202620182903003703002019201c29030037030020012001290388043703c806201641086a210f202041016a211f0240201741016a221320204b22220d00200f20134106746a200f20174106746a2017417f73201f6a41067410ea081a0b200f20174106746a220f20012903c806370000200f41386a2028290300370000200f41306a2029290300370000200f41286a202a290300370000200f41206a2007290300370000200f41186a2025290300370000200f41106a2026290300370000200f41086a201929030037000020014188036a41186a2224203229030037030020014188036a41106a221e203329030037030020014188036a41086a221a2034290300370300200120012903a80637038803201641c8056a210f024020220d00200f20134105746a200f20174105746a2017417f73201f6a41057410ea081a0b200f20174105746a220f200129038803370000200f41186a2024290300370000200f41106a201e290300370000200f41086a201a290300370000201641a8086a210f0240201741026a2224202041026a22224f0d00200f20244102746a200f20134102746a2013417f7320226a41027410ea081a0b200f20134102746a20463602002016201f3b01060240201320224f0d00201620174102746a41ac086a210f0340200f2802002213201741016a22173b010420132016360200200f41046a210f201f2017470d000b0b200141a8036a200141c8056a41e00010e9081a2021211f2021280200220f212120122146200f0d000b0b200141f8016a200141a8036a41e00010e9081a203b200141f8016a41086a290200370300203a200141f8016a41106a2902003703002039200141f8016a41186a2902003703002038200141f8016a41206a2902003703002037200141f8016a41286a2902003703002036200141f8016a41306a2902003703002035200141f8016a41386a2902003703002034200441086a2902003703002033200441106a2902003703002032200441186a290200370300200120012902f8013703c805200120042902003703a806200128020c2213450d0a2001280208211641d808102c220f450d2c200f20133602a808200f41003b0106200f4100360200201341003b01042013200f3602002001200f36020c2001201641016a3602082028203529030037030020292036290300370300202a203729030037030020072038290300370300202520392903003703002026203a2903003703002019203b290300370300200120012903c8053703c80620014188046a41186a2217203229030037030020014188046a41106a221f203329030037030020014188046a41086a22212034290300370300200120012903a8063703880420162045470d0b200f2f01062216410b4f0d0c200f20164106746a221341086a20012903c806370000201341106a2019290300370000201341186a2026290300370000201341206a2025290300370000201341286a2007290300370000201341306a202a290300370000201341386a2029290300370000201341c0006a2028290300370000200f20164105746a221341c8056a200129038804370000201341d0056a2021290300370000201341d8056a201f290300370000201341e0056a2017290300370000200f201641016a22133b0106200f20134102746a41a8086a2012360200201220133b01042012200f3602002001200128021041016a36021020121a0c220b20014188046a41386a220f204729030037030020014188046a41306a2212204829030037030020014188046a41286a2216204929030037030020014188046a41206a221f204a29030037030020014188046a41186a2222204229030037030020014188046a41106a2224204329030037030020014188046a41086a221e2044290300370300200120012903e804370388042032204b2903003703002033204c2903003703002034204d290300370300200120012903a8053703a80620212f010621132028200f29030037030020292012290300370300202a20162903003703002007201f29030037030020252022290300370300202620242903003703002019201e29030037030020012001290388043703c806201741016a2112202141086a210f201341016a21160240201720134f221f0d00200f20124106746a200f20174106746a2017417f7320166a41067410ea081a0b200f20174106746a220f20012903c806370000200f41386a2028290300370000200f41306a2029290300370000200f41286a202a290300370000200f41206a2007290300370000200f41186a2025290300370000200f41106a2026290300370000200f41086a201929030037000020014188036a41186a2222203229030037030020014188036a41106a2224203329030037030020014188036a41086a22252034290300370300200120012903a80637038803202141c8056a210f0240201f0d00200f20124105746a200f20174105746a2017417f7320166a41057410ea081a0b200f20174105746a220f200129038803370000200f41186a2022290300370000200f41106a2024290300370000200f41086a2025290300370000202141a8086a210f201341026a21130240201f0d002017410274200f6a41086a200f20124102746a2012417f7320136a41027410ea081a0b200f20124102746a2046360200202120163b0106201220134f0d2020212012417f6a220f4102746a41ac086a2112034020122802002213200f41016a220f3b010420132021360200201241046a21122016200f470d000c210b0b2019200f41086a2903003703002026200f41106a2903003703002025200f41186a2903003703002001200f2903003703c806200f41286a2903002152200f41206a29030021534130102c221e450d2a201e2053370320201e20012903c806370300201e41286a2052370300201e41186a2025290300370300201e41106a2026290300370300201e41086a2019290300370300200120163602cc052001200f41306a220f3602c805200120014198016a3602d4052001200141f8006a3602d005202241506a2013460d0b4101211a200141f8006a211720014198016a21224101211803402001200f41306a22133602c8050240200f2017412010ec08450d00200f2022412010ec08450d002013210f20162013470d010c0e0b200f41286a2903002152200f41206a29030021532025200f41186a2903003703002026200f41106a2903003703002019200f41086a2903003703002001200f2903003703c806024002402018201a470d00201a41016a220f201a490d2e201a4101742213200f2013200f4b1b220f4104200f41044b1bad42307e2254422088a745410374210f2054a7211302400240201a0d0020014100360288040c010b20014108360290042001201e360288042001201a41306c36028c040b200141a8036a2013200f20014188046a107d20012802b003210f20012802a8034101460d0120012802ac03211e200f41306e211a0b201e201841306c6a220f20012903c806370300202629030021542025290300215520192903002156200f2053370320200f41086a2056370300200f41286a2052370300200f41186a2055370300200f41106a2054370300201841016a211820012802c805220f20012802cc052216460d0e20012802d405212220012802d00521170c010b0b200f450d2b0c2a0b200e201e41d8aac700103c000b2016410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b41ac9cc700413541e49cc7001039000b2013410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b204f410c41f49cc700104d000b41f49bc7004128419c9cc7001039000b41e8aac700412b4194abc7001039000b41e899c700413041989ac7001039000b41a89ac700412041c89ac7001039000b4101211a0c010b201841014d0d0020184102470d0b41e000102c2218450d1d2002280200220f200e4d0d010240200028020020116a220f28020841306c22170d00410221200c100b200f280200210f4102212041002113024002400240034002400240200f200141f8006a412010ec08450d00200f20014198016a412010ec080d010b200141a8066a41186a2216200f41186a290300370300200141a8066a41106a2222200f41106a290300370300200141a8066a41086a221c200f41086a2903003703002001200f2903003703a806200f41286a2903002152200f41206a2903002153024020132020470d00201341016a22202013490d24201341017422282020202820204b1b22204104202041044b1bad42307e2254422088a74541037421202054a721280240024020130d00200141003602c8060c010b200141083602d006200120183602c8062001201341306c3602cc060b200141c8056a20282020200141c8066a107d20012802d005212020012802c8054101460d0320012802cc052118202041306e21200b201c2903002154202229030021552016290300215620012903a80621572018201341306c6a2216205337032020162057370300201641286a2052370300201641186a2056370300201641106a2055370300201641086a2054370300201341016a21130b200f41306a210f201741506a22170d000b20134102470d120240201e2018412010ec08450d00200141c8066a41286a220f201e41286a22132903003703002007201e41206a22162903003703002025201e41186a22172903003703002026201e41106a22222903003703002019201e41086a221c2903003703002001201e2903003703c8062013201e41d8006a22282903003703002016201e41d0006a22132903003703002017201e41c8006a22162903003703002022201e41c0006a2217290300370300201c201e41386a2222290300370300201e201e2903303703002028200f29030037030020132007290300370300201620252903003703002017202629030037030020222019290300370300201e20012903c8063703300b2001427f3703d0052001427f3703c805200141003602a80641c00141e000201e1b41e0004100201e1b20181b21132018201e72221c0d014108210f0c020b2020450d200c1f0b2013102c220f450d1e0b200141003602f0042001200f3602e8042001201341306e22173602ec0402400240024020180d0041022113201e0d01410021220c020b41044102201e1b21130b41002116410021220240201720134f0d00201741017422222013202220134b1b22134104201341044b1b41306c211302400240201c0d00200141003602c8060c010b200141083602d0062001200f3602c8062001201741306c3602cc060b20014188046a20134108200141c8066a107d20012802900421132001280288044101460d052001200128028c04220f3602e8042001201341306e3602ec0420012802f00421220b200f202241306c6a210f02402018450d00201841e0006a221c2018460d00200141c8056a41086a290300215420012903c805215841002116201821130340201341306a21170240201341206a2903002253205856201341286a290300225220545620522054511b0d00200120533703c805200120163602a806200120523703d00520532158205221540b200f2013290300370300201341086a2903002155201341106a2903002156201341186a2903002157200f41286a2052370300200f41206a2053370300200f41186a2057370300200f41106a2056370300200f41086a2055370300200f41306a210f201641016a211620172113201c2017470d000b202220166a21220b201e450d00201e41e0006a221c201e460d00200141c8056a41086a290300215420012903c8052158201e21130340201341306a21170240201341206a2903002253205856201341286a290300225220545620522054511b0d00200120533703c805200120163602a806200120523703d00520532158205221540b200f2013290300370300201341086a2903002155201341106a2903002156201341186a2903002157200f41286a2052370300200f41206a2053370300200f41186a2057370300200f41106a2056370300200f41086a2055370300200f41306a210f201641016a2116202241016a212220172113201c2017470d000b0b200120223602f00420012802a806210f200141003602c80620014188046a41104104200141c8066a107d200128029004211302402001280288044101470d002013450d1f0c1e0b200128028c042232200f360200201341027621330240024020012802a806220f41014b0d00200141003602c80620014188046a41104104200141c8066a107d20012802900421132001280288044101460d06200128028c0422294101200f6b360200024020334101470d0020014284808080c0003702cc06200120323602c80620014188046a41104104200141c8066a107d20012802900421162001280288044101460d08200128028c042132201641027621330b20324103200f6b36020420012802a806210f024002402013410276222a4101470d0020014284808080c0003702cc06200120293602c80620014188046a41104104200141c8066a107d20012802900421132001280288044101460d01200128028c0421292013410276212a0b2029200f41026a3602040c020b2013450d200c1f0b200141003602c80620014188046a41104104200141c8066a107d20012802900421132001280288044101460d07200128028c042229200f410171410373220f360200024020334101470d0020014284808080c0003702cc06200120323602c80620014188046a41104104200141c8066a107d20012802900421162001280288044101460d09200128028c042132201641027621330b2032200f417e6a36020420012802a806210f02402013410276222a4101470d0020014284808080c0003702cc06200120293602c80620014188046a41104104200141c8066a107d20012802900421132001280288044101460d0a200128028c0421292013410276212a0b2029200f417e6a3602040b4104102c220f450d1d200142013702fc012001200f3602f801024002402029280200220f41014b0d002025200a2903003703002026200929030037030020192010290300370300200120012903183703c8060c010b2025202441186a2900003703002026202441106a2900003703002019202441086a290000370300200120242900003703c8060b024020022802002213450d002000280200221c2013412c6c6a212803400240201c410c6a200141c8066a412010ec080d00201c2802082216450d00201c2802002113201641306c21174100212220012802f004211603402016200f4d0d060240201320012802e804200f41306c6a412010ec08450d00201341306a2113202241016a2122201741506a22170d010c020b0b201341206a2216427f2016290300225220012903c8057c225320532052542216201341286a22132903002252200141c8056a41086a2903007c2016ad7c225320525420532052511b22161b3703002013427f205320161b3703000b201c412c6a221c2028470d000b0b024002402029280204220f4102490d002025202441186a2900003703002026202441106a2900003703002019202441086a290000370300200120242900003703c8060c010b2025200a2903003703002026200929030037030020192010290300370300200120012903183703c8060b024020022802002213450d002000280200221c2013412c6c6a212803400240201c410c6a200141c8066a412010ec080d00201c2802082216450d00201c2802002113201641306c21174100212220012802f004211603402016200f4d0d060240201320012802e804200f41306c6a412010ec08450d00201341306a2113202241016a2122201741506a22170d010c020b0b201341206a2216427f2016290300225220012903c8057c225320532052542216201341286a22132903002252200141c8056a41086a2903007c2016ad7c225320525420532052511b22161b3703002013427f205320161b3703000b201c412c6a221c2028470d000b0b202a0d090c0a0b20242001290318370000202441186a200a290300370000202441106a2009290300370000202441086a20102903003700000c0f0b200e200f41a4abc700103c000b200f201641b4abc700103c000b2013450d1a0c190b2013450d190c180b2016450d180c170b2013450d170c160b2016450d160c150b2013450d150c140b2029102e0b024002402032280200220f41014b0d002025200a2903003703002026200929030037030020192010290300370300200120012903183703c8060c010b2025202441186a2900003703002026202441106a2900003703002019202441086a290000370300200120242900003703c8060b024002400240024020022802002213450d002000280200221c2013412c6c6a212803400240201c410c6a200141c8066a412010ec080d00201c41086a222a2802002229450d00201c2802002113202941306c41506a21174100212220012802f004211603402016200f4d0d040240201320012802e804200f41306c6a412010ec08450d00201341306a2113202241016a2122201741506a22174150470d010c020b0b0240201341206a2216290300225320012903c805225556201341286a22222903002252200141c8056a41086a29030022545620522054511b0d002013201341306a201710ea081a202a2029417f6a3602000240200128028002221320012802fc01470d00201341016a22162013490d1b201341017422172016201720164b1b22164104201641044b1b221641ffffffff03712016464102742117201641027421160240024020130d0020014100360288040c010b2001410436029004200120012802f801360288042001201341027436028c040b200141a8036a2016201720014188046a107d20012802b003211320012802a8034101460d0b200120012802ac033602f801200120134102763602fc0120012802800221130b20012802f80120134102746a200f360200200120012802e40241016a3602e402200120012802800241016a360280020c010b20224200205220547d2053205554ad7d2254205320557d2255205356205420525620542052511b22131b37030020164200205520131b3703000b201c412c6a221c2028470d000b0b024002402032280204220f4102490d002025202441186a2900003703002026202441106a2900003703002019202441086a290000370300200120242900003703c8060c010b2025200a2903003703002026200929030037030020192010290300370300200120012903183703c8060b024020022802002213450d00200028020022262013412c6c6a2119034002402026410c6a200141c8066a412010ec080d00202641086a2228280200221c450d0020262802002113201c41306c41506a21174100212220012802f004211603402016200f4d0d040240201320012802e804200f41306c6a412010ec08450d00201341306a2113202241016a2122201741506a22174150470d010c020b0b0240201341206a2216290300225320012903c805225556201341286a22222903002252200141c8056a41086a29030022545620522054511b0d002013201341306a201710ea081a2028201c417f6a3602000240200128028002221320012802fc01470d00201341016a22162013490d1b201341017422172016201720164b1b22164104201641044b1b221641ffffffff0371201646410274211720164102742116024002402013450d002001410436029004200120012802f801360288042001201341027436028c040c010b20014100360288040b200141a8036a2016201720014188046a107d20012802b003211320012802a8034101460d0b200120012802ac033602f801200120134102763602fc0120012802800221130b20012802f80120134102746a200f360200200120012802e40241016a3602e402200120012802800241016a360280020c010b20224200205220547d2053205554ad7d2254205320557d2255205356205420525620542052511b22131b37030020164200205520131b3703000b2026412c6a22262019470d000b0b20330d010c020b200f201641c4abc700103c000b2032102e0b20012802f8012222417c6a2116200128028002410274220f211302400340024020130d00410021160c020b2013417c6a2113201641046a221628020041014b0d000b0b20012802fc012126202221130240024002400340200f450d01200f417c6a210f20132802002117201341046a211320174102490d000b0240202641ffffffff0371450d002022102e0b20160d0120242001290318370000202441186a200a290300370000202441106a2009290300370000202441086a20102903003700000c020b0240202641ffffffff0371450d002022102e0b20160d0141d4abc70041294180acc7001039000b200141003a00a803024002402021450d002021417f6a2113201f20124102746a41a8086a280200210f02400340200f2f010621122013450d012013417f6a2113200f20124102746a41a8086a280200210f0c000b0b200141003602880420012012417f6a410020121b360290042001200f410020121b36028c04200141c8066a20014188046a200141a8036a10ce0620252903002152200141c8066a41386a22172903002153200141c8066a41306a221f2903002154200141c8066a41286a22212903002155200b2903002156200c2903002157200d290300215820012903d806215920012903d006215a20012903c806215b20012903e806215c200129038807215d20012802a80721160240024020012802b007221320012802ac0722122f01064f0d002012210f0c010b034002402012280200220f0d004100210f0c020b201641016a211620122f01042113200f21122013200f2f01064f0d000b0b200f20134106746a221241206a2222290000215e20222052370000201241186a2222290000215220222059370000201241106a222229000021592022205a370000201241086a2222290000215a2022205b370000201241c0006a2222290000215b20222053370000201241386a2222290000215320222054370000201241306a2222290000215420222055370000201241286a221229000021552012205c370000200f20134105746a221241d8056a2222290000215c20222057370000201241d0056a2222290000215720222058370000201241c8056a222229000021582022205d370000201241e0056a2212290000215d20122056370000201341016a211202402016450d00200f20124102746a41a8086a280200210f02402016417f6a2212450d000340200f2802a808210f2012417f6a22120d000b0b410021120b200d205737030020212054370300200c205c370300201f2053370300200b205d3703002017205b3703002025205e3703002001205837038807200120553703e8062001205a3703c806200120123602b0072001200f3602ac07200141003602a807200120593703d006200120523703d8060c010b20012012360290042001201f36028c042001410036028804200141c8066a20014188046a200141a8036a10ce060b20012001280210417f6a36021020012d00a803450d00200128020c220f450d0220012802082212450d032001200f2802a808221336020c20012012417f6a36020820134100360200200f102e0b024020012802ec04220f450d00200f41306c450d0020012802e804102e0b2020450d00202041306c450d002018102e0b201a450d07201a41306c0d050c070b41e8aac700412b4190acc7001039000b41b39bc700412141d49bc7001039000b2013450d0f0c0e0b2020450d00202041306c450d002018102e0b201a450d02201a41306c450d020b201e102e0c010b2001200128021041016a3602100b20232027470d030c060b201241016a2112200f41c0006a210f0c000b0b0b0b200e200f41a8aac700103c000b4100211d4101211b0b0240201d41ffffff1f71450d00201b102e0b200e41016a210e02402015450d002014102e0b200e2003470d000b200128020c210f2001410036020c200f450d00024020012802082212450d002012417f6a21120340200f2802a808210f2012450d012012417f6a21120c000b0b024020012802102216450d00200141c8066a41c0006a21174100210703402016417f6a2116410121120240024003402007200f2f0106490d010240200f28020022130d00200f102e4100210f0c030b200f2f01042107200f102e2012417f6a21122013210f0c000b0b20014188046a41386a221f200f20074106746a221341c0006a29000037030020014188046a41306a2221201341386a29000037030020014188046a41286a2222201341306a29000037030020014188046a41206a2223201341286a29000037030020014188046a41186a2224201341206a29000037030020014188046a41106a2225201341186a29000037030020014188046a41086a2226201341106a2900003703002001201341086a2900003703880420014188036a41186a221b200f20074105746a221341e0056a29000037030020014188036a41106a221d201341d8056a29000037030020014188036a41086a2219201341d0056a2900003703002001201341c8056a29000037038803200741016a2107024020124101460d00200f20074102746a41a8086a280200210f02402012450d000340201241016a220720124f2113200f2802a808210f2007211220130d000b0b410021070b2017200129038803370000200141c8066a41386a201f290300370300200141c8066a41306a2021290300370300200141c8066a41286a2022290300370300200141c8066a41206a2023290300370300200141c8066a41186a2024290300370300200141c8066a41106a2025290300370300200141c8066a41086a2026290300370300201741086a2019290300370000201741106a201d290300370000201741186a201b29030037000020012001290388043703c806200141c8056a200141c8066a41e00010e9081a0b20160d000b0b0340200f2802002112200f102e2012210f20120d000b0b200141003602d8022001420037029c0102400240200041086a222828020022020d002001410036029c010c010b20282802002112200141c8066a410472211d200141386a41106a2142200141386a41186a2143200141a8036a41206a213d4100211602400340200120163602dc02201220164d0d01201641016a2114200141386a41086a22442000280200220f2016412c6c6a220741146a29000037030020422007411c6a2900003703002043200741246a2900003703002001200729000c3703384100212003400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200f2016412c6c6a220f28020820204b0d002014211620142002470d2c200128029c01210f2001410036029c01200f450d2e2001280298012212450d012012417f6a21120340200f2802a003210f2012450d022012417f6a21120c000b0b200141a8066a41186a200f280200202041306c6a220f41186a2207290300370300200141a8066a41106a200f41106a2213290300370300200141a8066a41086a200f41086a22172903003703002001200f2903003703a806200141e8046a41186a221f2043290300370300200141e8046a41106a22212042290300370300200141e8046a41086a22222044290300370300200120012903383703e804200141003a008805200141f8016a41186a22122007290000370300200141f8016a41106a22072013290000370300200141f8016a41086a221320172900003703002001200f2900003703f801200141013a00980220014198016a200141e8046a109f02211720014198016a200141f8016a109f022125200141c8056a41186a221a2043290300370300200141c8056a41106a22182042290300370300200141c8056a41086a221c2044290300370300200120012903383703c805200141003a00e805200141c8066a20014198016a200141c8056a10a302203d20012d0088053a0000200141a8036a41186a222a201f290300370300200141a8036a41106a22322021290300370300200141a8036a41086a22332022290300370300200120012903e8043703a8030240024020012802c8064101460d00200141c8056a41306a201d41306a280200360200200141c8056a41286a201d41286a290200370300200141c8056a41206a201d41206a290200370300201a201d41186a2902003703002018201d41106a290200370300201c201d41086a2902003703002001201d2902003703c80520014188046a41086a221f203329030037030020014188046a41106a2221203229030037030020014188046a41186a2222202a29030037030020014188046a41206a2223203d2d00003a0000200120012903a803370388044134102c220f450d30200f4200370208200f428180808010370200200f200129038804370210200f20012f00b8013b0031200f41186a201f290300370200200f41206a2021290300370200200f41286a2022290300370200200f41306a20232d00003a0000200f41336a200141b8016a41026a2d00003a0000200141c8056a200f10ed06210f0c010b20012802d00620012802d4064102746a41046a210f0b200f280200222428020041016a220f41014d0d1e2024200f360200201a201229030037030020182007290300370300201c2013290300370300200120012903f8013703c805200141013a00e805200141c8066a20014198016a200141c8056a10a302203d200141f8016a41206a2d00003a0000202a20122903003703002032200729030037030020332013290300370300200120012903f8013703a8030240024020012802c8064101460d00200141c8056a41306a201d41306a280200360200200141c8056a41286a201d41286a290200370300200141c8056a41206a201d41206a290200370300201a201d41186a2902003703002018201d41106a290200370300201c201d41086a2902003703002001201d2902003703c80520014188046a41086a2212203329030037030020014188046a41106a2207203229030037030020014188046a41186a2213202a29030037030020014188046a41206a221f203d2d00003a0000200120012903a803370388044134102c220f450d30200f4200370208200f428180808010370200200f200129038804370210200f20012f00b8013b0031200f41186a2012290300370200200f41206a2007290300370200200f41286a2013290300370200200f41306a201f2d00003a0000200f41336a200141b8016a41026a2d00003a0000200141c8056a200f10ed06210f0c010b20012802d00620012802d4064102746a41046a210f0b200f2802002223280200221241016a220f41014d0d1e2023200f360200024002400240024002400240024020170d0020250d01202428020041016a220f41014d0d252024200f36020020232802080d0a2023417f3602080240202328020c220f450d00200f200f280200417f6a360200202328020c220f2802000d00200f410c6a10cd04202328020c41046a220f200f280200417f6a360200202328020c220f41046a2802000d00200f102e0b2023202436020c2023202328020841016a3602080c2f0b2025450d01200141c8066a202410ee0620012802d406214720012802d006214c20012802cc06213c20012802c806210e200141c8066a202310ee0620012802d406214620012802d006214d20012802cc06213e0240200e20012802c8062245460d00200e28020841016a220f41004c0d08200e200f3602082045280208220f41016a221241004c0d0920452012360208200e41106a204541106a412010ec080d03200e2d003020452d0030470d032045200f360208200e200e280208417f6a3602080b203e2046410274221e6a2122203c204741027422196a211220190d03410021170c040b2012417e4f0d232023201241026a36020020242802080d092024417f3602080240202428020c220f450d00200f200f280200417f6a360200202428020c220f2802000d00200f410c6a10cd04202428020c41046a220f200f280200417f6a360200202428020c220f41046a2802000d00200f102e0b2024202336020c2024202428020841016a3602080c2d0b202428020041016a220f41014d0d222024200f36020020232802080d092023417f3602080240202328020c220f450d00200f200f280200417f6a360200202328020c220f2802000d00200f410c6a10cd04202328020c41046a220f200f280200417f6a360200202328020c220f41046a2802000d00200f102e0b2023202436020c2023202328020841016a3602080c2c0b2045200f360208200e200e280208417f6a360208204dad422086203ead842252204cad422086203cad842253204720464b220f1b2254a72116024020462047200f1b22074102742212450d00201620126a21254101211341002121201621172016211f0340024020214101710d00202520176b4102762013417f6a4d0d02201720134102746a21170b20172025460d012017450d01201f280200222128020041016a221341014d0d2320212013360200201728020022132802080d0b201f41046a211f2013417f3602080240201328020c2222450d0020222022280200417f6a360200201328020c22222802000d002022410c6a10cd04201328020c41046a22222022280200417f6a360200201328020c222241046a2802000d002022102e0b201741046a21172013202136020c410121212013201328020841016a360208410021132025201f470d000b0b2007450d0a20472046200f1b221f0d024100410041e0acc700103c000b204641ffffffff0371212541002117202221132012211603400240203e2013470d00202521170c020b024002402016417c6a2216280200220f2013417c6a22132802002207460d00200f28020841016a221f41004c0d0d200f201f3602082007280208221f41016a222141004c0d0e20072021360208200f41106a200741106a412010ec080d01200f2d003020072d0030470d012007201f360208200f200f280208417f6a3602080b201741016a2117203c2016470d010c020b0b2007201f360208200f200f280208417f6a3602080b204720176b211f204620176b225141016a210702400240203e450d0020072022203e6b410276220f200f20074b1b410020071b201f2012203c6b410276220f200f201f4b1b4100201f1b6a210f0c010b201f2012203c6b410276220f200f201f4b1b4100201f1b210f0b200f41ffffffff0371200f470d30200f4102742213417f4c0d300240024020130d004104210f0c010b2013102c220f450d300b20014100360290032001200f3602880320012013410276221336028c0302400240203e450d0020072022203e6b4102762216201620074b1b410020071b201f2012203c6b41027622162016201f4b1b4100201f1b6a21160c010b201f2012203c6b41027622162016201f4b1b4100201f1b21160b0240024020132016490d00410021260c010b201341017422212016202120164b1b22164104201641044b1b221641ffffffff03712016464102742121201641027421160240024020130d00200141003602c8060c010b200141043602d0062001200f3602c806200120134102743602cc060b200141c8056a20162021200141c8066a107d20012802d005211320012802c8054101460d1d200120012802cc05220f360288032001201341027636028c0320012802900321260b200f20264102746a210f0240203e450d002007450d00203e201e6a21212046417f7320176a2113202620466a20176b41016a2122203e2107034020212007460d012007280200221628020041016a221741014d0d2120162017360200200f2016360200202641016a2126200f41046a210f200741046a2107201341016a221620134f21172016211320170d000b202221260b0240201f450d0002402012203c6b4102762207201f4d0d002007201f417f736a221320074f0d01201220134102746b417c6a203c20132007491b21120b2012203c460d0003402012417c6a2212280200220728020041016a221341014d0d2120072013360200200f2007360200202641016a2126200f41046a210f203c2012470d000b0b20012026360290032001427f3703b0052001427f3703a805200141b8016a41186a224e4200370300200141b8016a41106a224f4200370300200141b8016a41086a22504200370300200142003703b801202a42003703002032420037030020334200370300200142003703a80341002106200141003602e002200141003602e402200120014188036a360208200120014188036a360218410021254100214b4100213402402026450d00427f21534100214b200128028803211b41002134427f215220262125410021210340202520214d0d0d201b20214102746a280200220f280208221241016a41004c0d0e202141016a21220240200f2d00300d00200f201236020820014188046a41186a2225200f41286a29000037030020014188046a41106a2208200f41206a29000037030020014188046a41086a2229200f41186a2900003703002001200f29001037038804200128029003220f20224100200f417f6a20214b1b22124d0d10201b20124102746a280200220f280208221241016a41004c0d11200f2012360208201a200f41286a2900003703002018200f41206a290000370300201c200f41186a2900003703002001200f2900103703c805200128029003220f2021200f20211b417f6a22124d0d12201b20124102746a280200220f280208221241016a41004c0d13200f2012360208200141c8066a41186a2248200f41286a290000370300200141c8066a41106a2249200f41206a290000370300200141c8066a41086a224a200f41186a2900003703002001200f2900103703c8062028280200412c6c221221072000280200220f41546a22162117200f2113024003402007450d01200741546a21072017412c6a21172013410c6a211f2013412c6a2113201f20014188046a412010ec080d000b201741086a28020041306c21072017280200211303402007450d01200741506a21072013200141c8056a412010ec082117201341306a221f211320170d000b2053201f41706a22072903002255582052200741086a29030022545820522054511b0d002050201c290300370300204f2018290300370300204e201a2903003703002033202929030037030020322008290300370300202a2025290300370300200120553703a805200120012903c8053703b80120012001290388043703a803200120213602e002200120543703b0054101214b200141013602e4022021213420552153205421520b03402012450d01201241546a21122016412c6a2116200f410c6a2107200f412c6a210f200720014188046a412010ec080d000b201641086a28020041306c210f201628020021120340200f450d01200f41506a210f2012200141c8066a412010ec082107201241306a2213211220070d000b2053201341706a220f2903002255582052200f41086a29030022545820522054511b0d002050204a290300370300204f2049290300370300204e20482903003703002033202929030037030020322008290300370300202a2025290300370300200120553703a805200120012903c8063703b80120012001290388043703a803200120213602e002200120543703b0054100214b200141003602e4022021213420552153205421520b20012802900321252022212120222026470d000b0b20014100360290042001420437038804204b20346a214941012129024020250d004100210f0c1f0b20494101712108410021062025210f4100211f03402001201f360278200f201f4d0d122001280288032213201f4102746a280200220f28020841016a221241004c0d13201f41016a211b200f20123602082001200f41086a22073602ec022001200f410c6a3602e8020240200f2d00300d00201f210f0240201f0d00200128021841086a280200210f0b2001280290032212200f417f6a220f4d0d152013200f4102746a280200220f28020841016a221241004c0d16200f20123602082001200f41086a3602cc052001200f410c6a3602c805024002402028280200220f0d00201b210f0c010b20002802002216200f412c6c6a212141002117034002402016410c6a20012802e80241046a412010ec080d00201641086a22262802002222450d002016280200210f20012802c80541046a2113202241306c41506a21124100210702400340200f2013412010ec08450d01200f41306a210f200741016a2107201241506a22124150470d000c020b0b200f41286a22072903002152200f41206a22132903002153200141a8056a41086a290300215520012903a805215402400240201f4101710d0002402008450d00427f205220557c205320547c22542053542248ad7c22532048205320525420532052511b22481b2152427f205420481b21530c020b4200205220557d2053205454ad7d2255205320547d2254205356205520525620552052511b22481b21524200205420481b21530c010b02402008450d004200205220557d2053205454ad7d2255205320547d2254205356205520525620552052511b22481b21524200205420481b21530c010b427f205220557c205320547c22542053542248ad7c22532048205320525420532052511b22481b2152427f205420481b21530b0240024020532052844200520d0020012802dc022107200f200f41306a201210ea081a20262022417f6a360200200120012802d80241016a3602d8024100202920072017461b21292001280278221f20012802e0022234470d0120012802e4020d01201f21340c020b20072052370300201320533703000c010b200128029003220f201f4d0d1a200128028803201f4102746a280200220f28020041016a221241014d0d24200f2012360200201f21120240201f0d00200128021841086a28020021120b20012802900322072012417f6a22124d0d1b20012802880320124102746a280200221228020041016a220741014d0d242012200736020002402006200128028c04470d0020014188046a10bc0120012802900421060b20012802880420064103746a220720123602042007200f3602002001200641016a2206360290040b201741016a21172016412c6a22162021470d000b201f41016a210f0b2001280290032212200f4100200128020841086a280200417f6a201f4b1b220f4d0d19200128028803200f4102746a280200220f28020841016a221241004c0d1a200f20123602082001200f41086a22073602cc062001200f410c6a3602c80602402028280200220f450d0020002802002216200f412c6c6a212141002117034002402016410c6a20012802e80241046a412010ec080d00201641086a22262802002222450d002016280200210f20012802c80641046a2113202241306c41506a21124100210702400340200f2013412010ec08450d01200f41306a210f200741016a2107201241506a22124150470d000c020b0b200f41286a22072903002152200f41206a22132903002153200141a8056a41086a290300215520012903a805215402400240201f4101710d0002402008450d004200205220557d2053205454ad7d2255205320547d2254205356205520525620552052511b22481b21524200205420481b21530c020b427f205220557c205320547c22542053542248ad7c22532048205320525420532052511b22481b2152427f205420481b21530c010b02402008450d00427f205220557c205320547c22542053542248ad7c22532048205320525420532052511b22481b2152427f205420481b21530c010b4200205220557d2053205454ad7d2255205320547d2254205356205520525620552052511b22481b21524200205420481b21530b0240024020532052844200520d0020012802dc022107200f200f41306a201210ea081a20262022417f6a360200200120012802d80241016a3602d8024100202920072017461b21292001280278221f20012802e0022234470d0120012802e4024101470d01201f21340c020b20072052370300201320533703000c010b200128029003220f201f4d0d1e200128028803201f4102746a280200220f28020041016a221241014d0d24200f20123602002001280290032207201f41016a4100200128020841086a280200417f6a201f4b1b22124d0d1f20012802880320124102746a280200221228020041016a220741014d0d242012200736020002402006200128028c04470d0020014188046a10bc0120012802900421060b20012802880420064103746a220720123602042007200f3602002001200641016a2206360290040b201741016a21172016412c6a22162021470d000b20012802cc06220728020021120b20072012417f6a36020020012802cc05220f200f280200417f6a36020020012802ec02220728020021120b20072012417f6a360200200128029003210f201b211f201b2025460d1e0c000b0b20532052200f1b2252a72217280200220728020041016a220f41014d0d1e2007200f3602002016280200220f2802080d1a200f417f3602080240200f28020c2213450d0020132013280200417f6a360200200f28020c22132802000d002013410c6a10cd04200f28020c41046a22132013280200417f6a360200200f28020c221341046a2802000d002013102e0b200f200736020c200f200f28020841016a360208201f41027421072017210f0340200f28020022132013280200417f6a3602000240200f28020022132802000d002013410c6a10cd04200f28020041046a22132013280200417f6a360200200f280200221341046a2802000d002013102e0b200f41046a210f2007417c6a22070d000b024020524280808080f0ffffff3f83500d002017102e0b2016210f0340200f28020022072007280200417f6a3602000240200f28020022072802000d002007410c6a10cd04200f28020041046a22072007280200417f6a360200200f280200220741046a2802000d002007102e0b200f41046a210f2012417c6a22120d000b024020544280808080f0ffffff3f83500d002016102e0b20452045280200417f6a220f360200202041016a2120200f0d272045410c6a10cd04204541046a220f200f280200417f6a220f360200200f0d272045102e0c270b024020012802a0012217450d004100210720014188036a41186a211f20014188036a41106a212120014188036a41086a212203402017417f6a2117410121120240024003402007200f2f0132490d010240200f28020022130d00200f102e0c030b200f2f01302107200f102e2012417f6a21122013210f0c000b0b201f200f200741216c6a221341cc006a2900003703002021201341c4006a29000037030020222013413c6a2900003703002001201341346a29000037038803200741016a2113200f20074102746a41046a28020021160240024020124101470d00201321070c010b200f20134102746a41a0036a280200210f02402012450d000340201241016a220720124f2113200f2802a003210f2007211220130d000b0b410021070b200141e8026a41186a201f290300370300200141e8026a41106a2021290300370300200141e8026a41086a202229030037030020012001290388033703e8020b20162016280200417f6a2212360200024020120d002016410c6a10cd04201641046a22122012280200417f6a221236020020120d002016102e0b20170d000b0b0340200f2802002112200f102e2012210f20120d000c2d0b0b41bcd9cc004118200141b8076a41c0acc70041c4bfcc00103e000b41bcd9cc004118200141b8076a41c0acc70041d4bfcc00103e000b4194dacc004110200141b8076a4190c1cc0041b0c1cc00103e000b4194dacc004110200141b8076a4190c1cc0041b0c1cc00103e000b4194dacc004110200141b8076a4190c1cc0041b0c1cc00103e000b4194dacc004110200141b8076a4190c1cc0041b0c1cc00103e000b4100410041d0acc700103c000b41bcd9cc004118200141b8076a41c0acc70041c4bfcc00103e000b41bcd9cc004118200141b8076a41c0acc70041d4bfcc00103e000b2021202541f0acc700103c000b41bcd9cc004118200141b8076a41c0acc7004180adc700103e000b2012200f4190adc700103c000b41bcd9cc004118200141b8076a41c0acc70041a0adc700103e000b2012200f41b0adc700103c000b41bcd9cc004118200141b8076a41c0acc70041c0adc700103e000b201f200f41d0adc700103c000b41bcd9cc004118200141b8076a41c0acc70041e0adc700103e000b200f201241f0adc700103c000b41bcd9cc004118200141b8076a41c0acc7004180aec700103e000b201f200f4190aec700103c000b2012200741a0aec700103c000b200f201241b0aec700103c000b41bcd9cc004118200141b8076a41c0acc70041c0aec700103e000b201f200f41d0aec700103c000b2012200741e0aec700103c000b4194dacc004110200141b8076a4190c1cc0041b0c1cc00103e000b2013450d130c120b20012802e402214b0b024002402034200f417f6a470d00204b4101460d010b41c000102c2212450d11201220012903a803370000201220012903b801370020201241186a202a290300370000201241106a2032290300370000201241086a2033290300370000201241286a2050290300370000201241306a204f290300370000201241386a204e29030037000002400240204920514d0d0002400240024002400240024002402047417f6a2222450d0020474101204741014b1b417f6a2121410021130340201322072047460d02203c20074102746a221f280200220f280200221641016a221341014d0d0b200f2013360200200f280208221741016a41004c0d03200741016a2113200f2017360208200f2016360200201a200f41286a2900003703002018200f41206a290000370300201c200f41186a2900003703002001200f2900103703c80520072021460d04203c20134102746a2217280200220f280200220741016a221641014d0d0b200f2016360200200f280208221641016a41004c0d05200f2016360208200f2007360200200141c8066a41186a200f41286a290000370300200141c8066a41106a200f41206a290000370300200141c8066a41086a200f41186a2900003703002001200f2900103703c8064100210f02400340200f41c000460d012012200f6a2107200f41206a210f2007200141c8056a412010ec080d000b4100210f0340200f41c000460d012012200f6a2107200f41206a210f2007200141c8066a412010ec080d000c030b0b201f280200220728020041016a220f41014d0d0b2007200f3602002017280200220f2802080d06200f417f3602080240200f28020c2216450d0020162016280200417f6a360200200f28020c22162802000d002016410c6a10cd04200f28020c41046a22162016280200417f6a360200200f28020c221641046a2802000d002016102e0b200f200736020c200f200f28020841016a36020820132022470d000b0b202328020041016a220f41014d0d092023200f36020020242802080d052024417f3602080240202428020c220f450d00200f200f280200417f6a360200202428020c220f2802000d00200f410c6a10cd04202428020c41046a220f200f280200417f6a360200202428020c220f41046a2802000d00200f102e0b2024202336020c2024202428020841016a3602080c070b2047204741f0aec700103c000b41bcd9cc004118200141b8076a41c0acc7004180afc700103e000b201320474190afc700103c000b41bcd9cc004118200141b8076a41c0acc70041a0afc700103e000b4194dacc004110200141b8076a4190c1cc0041b0c1cc00103e000b4194dacc004110200141b8076a4190c1cc0041b0c1cc00103e000b02402046417f6a2222450d0020464101204641014b1b417f6a2121410021130340201322072046460d05203e20074102746a221f280200220f280200221641016a221341014d0d04200f2013360200200f280208221741016a41004c0d06200741016a2113200f2017360208200f2016360200201a200f41286a2900003703002018200f41206a290000370300201c200f41186a2900003703002001200f2900103703c80520072021460d07203e20134102746a2217280200220f280200220741016a221641014d0d04200f2016360200200f280208221641016a41004c0d08200f2016360208200f2007360200200141c8066a41186a200f41286a290000370300200141c8066a41106a200f41206a290000370300200141c8066a41086a200f41186a2900003703002001200f2900103703c8064100210f02400340200f41c000460d012012200f6a2107200f41206a210f2007200141c8056a412010ec080d000b4100210f0340200f41c000460d012012200f6a2107200f41206a210f2007200141c8066a412010ec080d000c030b0b201f280200220728020041016a220f41014d0d042007200f3602002017280200220f2802080d09200f417f3602080240200f28020c2216450d0020162016280200417f6a360200200f28020c22162802000d002016410c6a10cd04200f28020c41046a22162016280200417f6a360200200f28020c221641046a2802000d002016102e0b200f200736020c200f200f28020841016a36020820132022470d000b0b202428020041016a220f41014d0d022024200f36020020232802080d082023417f3602080240202328020c220f450d00200f200f280200417f6a360200202328020c220f2802000d00200f410c6a10cd04202328020c41046a220f200f280200417f6a360200202328020c220f41046a2802000d00200f102e0b2023202436020c2023202328020841016a3602080b2012102e0b200128028804221720064103746a2113200128028c04211f20172112024002402006450d0020172107024003402007280200220f450d0102400240200f200741046a280200221210ef06450d00200f2802080d0d200f417f3602080240200f28020c2216450d0020162016280200417f6a360200200f28020c22162802000d002016410c6a10cd04200f28020c41046a22162016280200417f6a360200200f28020c221641046a2802000d002016102e0b200f410036020c200f200f28020841016a3602080c010b2012200f10ef06450d0020122802080d0d2012417f3602080240201228020c2216450d0020162016280200417f6a360200201228020c22162802000d002016410c6a10cd04201228020c41046a22162016280200417f6a360200201228020c221641046a2802000d002016102e0b2012410036020c2012201228020841016a3602080b20122012280200417f6a2216360200024020160d002012410c6a10cd04201241046a22162016280200417f6a221636020020160d002012102e0b200f200f280200417f6a2212360200024020120d00200f410c6a10cd04200f41046a22122012280200417f6a221236020020120d00200f102e0b200741086a22072013470d000c030b0b200741086a21120b20132012460d0003402012220f28020022122012280200417f6a3602000240200f28020022122802000d002012410c6a10cd04200f28020041046a22122012280200417f6a360200200f280200221241046a2802000d002012102e0b200f41086a2112200f41046a220f28020022072007280200417f6a3602000240200f28020022072802000d002007410c6a10cd04200f28020041046a22072007280200417f6a360200200f280200220f41046a2802000d00200f102e0b20132012470d000b0b0240201f41ffffffff0171450d002017102e0b02402001280290032212450d00200128028803210f201241027421120340200f28020022072007280200417f6a3602000240200f28020022072802000d002007410c6a10cd04200f28020041046a22072007280200417f6a360200200f280200220741046a2802000d002007102e0b200f41046a210f2012417c6a22120d000b0b0240200128028c0341ffffffff0371450d00200128028803102e0b02402046450d00203e210f0340200f28020022122012280200417f6a3602000240200f28020022122802000d002012410c6a10cd04200f28020041046a22122012280200417f6a360200200f280200221241046a2802000d002012102e0b200f41046a210f201e417c6a221e0d000b0b0240204d41ffffffff0371450d00203e102e0b20452045280200417f6a220f3602000240200f0d002045410c6a10cd04204541046a220f200f280200417f6a220f360200200f0d002045102e0b202941ff0171210702402047450d00203c210f0340200f28020022122012280200417f6a3602000240200f28020022122802000d002012410c6a10cd04200f28020041046a22122012280200417f6a360200200f280200221241046a2802000d002012102e0b200f41046a210f2019417c6a22190d000b0b202020076a2120204c41ffffffff0371450d09203c102e0c090b00000b2046204641b0afc700103c000b41bcd9cc004118200141b8076a41c0acc70041c0afc700103e000b2013204641d0afc700103c000b41bcd9cc004118200141b8076a41c0acc70041e0afc700103e000b4194dacc004110200141b8076a4190c1cc0041b0c1cc00103e000b4194dacc004110200141b8076a4190c1cc0041b0c1cc00103e000b4194dacc004110200141b8076a4190c1cc0041a0c1cc00103e000b4194dacc004110200141b8076a4190c1cc0041a0c1cc00103e000b200e200e280200417f6a220f3602000240200f0d00200e410c6a10cd04200e41046a220f200f280200417f6a220f360200200f0d00200e102e0b20232023280200417f6a220f3602000240200f0d002023410c6a10cd04202341046a220f200f280200417f6a220f360200200f0d002023102e0b20242024280200417f6a220f3602000240200f0d002024410c6a10cd04202441046a220f200f280200417f6a220f360200200f0d002024102e0b20012802dc0221160c010b20232023280200417f6a220f3602000240200f0d002023410c6a10cd04202341046a220f200f280200417f6a220f360200200f0d002023102e0b20242024280200417f6a220f3602000240200f0d002024410c6a10cd04202441046a220f200f280200417f6a220f360200200f0d002024102e0b202041016a21200b2000280200210f2028280200221220164b0d000b0b2016201241b0acc700103c000b2016201241a0acc700103c000b200141c0076a24000f0b1036000b1038000ba50302027f037e230041d0006b22042400200441386a20024201200242015620034200522003501b22051b22022003420020051b220342ffff03420010e708200441286a2002200342ffff03420010e608200441186a20022003200429033822062004290328200441286a41086a29030084420052ad7c220742012007420156200441386a41086a2903002007200654ad7c22074200522007501b22051b22062007420020051b220710e7080240024002402004290318220842808004544100200441186a41086a290300501b450d00200441086a200220002002200054200320015420032001511b22051b2003200120051b2006200710e7082004290308220342808004544100200441086a41086a290300501b450d012008a741ffff037122050d0241d0d8c80041194180a1c9001039000b2004411136024c2004419cd5cc0036024841add5cc0041de00200441c8006a41bcdcc8004180a1c900103e000b2004411136024c2004419cd5cc0036024841add5cc0041de00200441c8006a41bcdcc8004180a1c900103e000b200441d0006a24002003a741ffff037141ffff036c20056e0baf08030b7f017e017f230041d0016b2204240020042003360214200420023602102001280200220520012802082202412c6c22066a2107200128020421080240024020020d0020052102200521010c010b200441f0006a410c6a2109200441f0006a4104722103200441186a41086a210a200441186a41106a210b200441186a41186a210c200441186a41206a210d200521020340200a20022201410c6a290200370300200b200141146a290200370300200c2001411c6a290200370300200d200141246a2902003703002004200141046a2902003703182001412c6a21022001280200220e450d0120032004290318370200200341086a200a290300370200200341106a200b290300370200200341186a200c290300370200200341206a200d2903003702002004200e3602704200210f02402004280210200910a002220e450d0020042802142210280208200e280200220e4d0d002010280200200e41386c6a290300210f0b200441a0016a41286a200441f0006a41286a280200360200200441a0016a41206a200441f0006a41206a290300370300200441a0016a41186a200441f0006a41186a290300370300200441a0016a41106a200441f0006a41106a290300370300200441a0016a41086a200441f0006a41086a290300370300200420042903703703a001200441c0006a200441a0016a200f420010bd04200141286a200441c0006a41286a280200360200200141206a200441c0006a41206a290300370200200141186a200441c0006a41186a290300370200200141106a200441c0006a41106a290300370200200141086a200441c0006a41086a29030037020020012004290340370200200641546a22060d000b20022101200721020b200720026b2203412c6d210602402003450d002006412c6c210303400240200241046a2802002206450d00200641226c450d002002280200102e0b2002412c6a2102200341546a22030d000b0b200441053602a001200120056b220b412c6d220a412c6c21022005210302400340200321012002450d014200210f024020042802102001410c6a10a0022203450d0020042802142206280208200328020022034d0d002006280200200341386c6a290300210f0b2001412c6a2103200441086a2001200f420010bf04200241546a210220042802082201450d000b200428020c2102200441033602a00120042002ad4220862001ad843702a4010b0240024020042802a00122014105470d00200020053602042000410c6a200a360200200041086a2008360200410021010c010b20042902a401210f20002001360204200041086a200f3702000240200b450d00200a412c6c21022005210103400240200141046a2802002203450d00200341306c450d002001280200102e0b2001412c6a2101200241546a22020d000b0b410121012008450d002008412c6c450d002005102e0b20002001360200200441d0016a24000b850103027f017e027f230041106b22012400024002400240200035020842208620002802002202ad84101e2203428080808010540d00410021042003a722052d00000e020201000b41cae0cc00412e200141086a41f8e0cc004188e1cc00103e000b410121040b2005102e0240200041046a280200450d002002102e0b200141106a240020040b070010184101460b8b0705017f017e077f037e027f23004180026b220224002002200136020c0240024002402002410c6a10082203422088a722010d0020004100360208200042013702000c010b2002200136021420022003a722043602102002200241106a10ab01024002400240024020022802000d002002280204220520022802144105762201200120054b1b22014105742206417f4c0d050240024020010d00410121070c010b2006102c2207450d030b2001ad210302402005450d00410021080340200241003a00b8012002280214417f6a2101200841016a210841002106024002400240024003402001417f460d0120024198016a20066a200228021022092d00003a00002002200941016a3602102002200641016a22093a00b801200220013602142001417f6a21012009210620094120470d000b200241c0016a41086a220120024198016a41086a290300370300200241c0016a41106a220620024198016a41106a290300370300200241c0016a41186a220a20024198016a41186a29030037030020022002290398013703c001200941ff0171411f4d0d01200241386a41086a2001290300220b370300200241386a41106a2006290300220c370300200241386a41186a200a290300220d370300200241186a41186a2209200d370300200241186a41106a220a200c370300200241186a41086a220e200b370300200220022903c001220b3703582002200b3703382002200b3703182003422088220ba722012003a7470d03200141016a220620014f0d020c0b0b200641ff0171450d00200241003a00b8010b200342ffffff3f83500d042007102e0c040b2001410174220f20062006200f491b22064104200641044b1b220641ffffff3f71200646210f200641057421060240024020010d0020024100360298010c010b200241013602a00120022007360298012002200b4205863e029c010b200241c0016a2006200f20024198016a107d20022802c801210620022802c0014101460d0420022802c40121072006410576ad21030b200720014105746a22062002290318370000200641186a2009290300370000200641106a200a290300370000200641086a200e290300370000200342ffffffff0f83200141016aad42208684210320082005470d000b0b20070d030b41cae0cc00412e20024198016a41c4dfcc0041d4dfcc00103e000b2006450d030b1036000b20002003370204200020073602002004102e0b20024180026a24000f0b1038000bfa0203027f017e067f230041206b220224000240024020014102490d00200041206a22032000412010ec08417f4a0d002000290000210420002003290000370000200241186a2205200041186a2206290000370300200241106a2207200041106a2208290000370300200241086a2209200041086a220a290000370300200a200341086a2900003700002008200341106a2900003700002006200341186a29000037000020022004370300024020014103490d00200041206a210320002001417f6a22064105746a21080340200341206a22002002412010ec08417f4a0d012006450d0320032000290000370000200341186a200041186a290000370000200341106a200041106a290000370000200341086a200041086a290000370000200021032006417f6a22064101470d000b200821030b20032002290300370000200341186a2005290300370000200341106a2007290300370000200341086a20092903003700000b200241206a24000f0b2001200141d4d1cc00103c000bb719030a7f047e0d7f230041a0076b220124000240024020002802082202200028020c2203470d00410821020c010b2000200241206a22043602082000280210210520014190026a41186a200241186a29000037030020014190026a41106a200241106a29000037030020014190026a41086a200241086a2900003703002001200229000037039002200028021421064100210202400240024002402000411c6a28020022070e020201000b410021022007210803402008410176220920026a210a200a20022006200a4105746a20014190026a412010ec084101481b2102200820096b220841014b0d000b0b200620024105746a20014190026a412010ec08450d010b03402000200541016a2205360210024020042003470d00410821020c030b2000200441206a220936020820014190026a41186a200441186a29000037030020014190026a41106a200441106a29000037030020014190026a41086a200441086a290000370300200120042900003703900241002102200921040240024020070e020201000b410021022007210403402004410176220a20026a210820082002200620084105746a20014190026a412010ec084101481b21022004200a6b220441014b0d000b0b20092104200620024105746a20014190026a412010ec080d000b0b02400240200720024d0d00200141186a200620024105746a220241186a290000220b370300200141106a200241106a290000220c370300200141086a200241086a290000220d37030020012002290000220e3703002000200541016a360210200041246a2802002109200041286a280200210320002802202107200141206a41186a200b370300200141206a41106a200c370300200141206a41086a200d3703002001200e370320410221022005109e070d0202400240411b102c220a450d00200a41176a4100280093db48360000200a41106a410029008cdb48370000200a41086a4100290084db48370000200a41002900fcda483700004104102c2202450d00200142043702c401200120023602c0012001200536029002200141c0016a20014190026a4104107420012802c401210820012802c0012104024020012802c80122020d00411b210f2002411b6a21000c040b2002411b6a22002002490d012001429b80808010370294022001200a36029002200141d8056a20004136200041364b1b410120014190026a107d200141e0056a280200210f024020012802d8054101460d0020012802dc05210a0c040b200f450d010b1036000b1038000b2002200741ecdac800103c000b200a411b6a2004200210e9081a02402008450d002004102e0b200141c0016a4101200a200010df0602400240024002400240024002400240024020012802c0012202450d00200141c8016a28020022044104490d002004417c714104460d0020022800002007470d00200228000441036a20094b0d010b200141003602e005200142013703d805200120073602900241042102200141d8056a20014190026a410410742001200936029002200141d8056a20014190026a4104107420012802d805210420012802e005210820014190026a41086a200141c0016a41086a280200360200200120012903c001370390024101200a200020014190026a2004200810e0062108024020012802dc05450d002004102e0b2008450d0120014190026a109f072001280290022210450d04200141a0026a280200211120014190026a410c6a2802002112200141a4026a280200211320014190026a41086a2802002114200128029402211520014100360288022001420137038002200120093602900220014180026a20014190026a41041074201420014180026a107620014180026a201020141074201320014180026a107602402013450d0020122013410c6c6a210620122102034020022802002104200241086a280200220820014180026a107620014180026a2004200810742002410c6a22022006470d000b0b200120073602900220014180026a20014190026a41041074200120053602900220014180026a20014190026a41041074200120033602900220014180026a20014190026a4104107420014190026a41e9dabdf306200141206a200128028002220420012802880210a0074101210220012d0090024101460d02410321080c030b024020012802c401450d002002102e0b410121020b200f0d050c060b200141fe016a20012d0093023a0000200141d8056a41086a200141a4026a290200370300200141e8056a200141ac026a290200370300200141f0056a200141b4026a290200370300200141f8056a200141bc026a29020037030020014180066a200141c4026a29020037030020014185066a200141c9026a290000370000200120012f0091023b01fc0120012001419c026a2902003703d80520014190026a41086a28020021062001280294022108410021020b200141f8016a41026a2216200141fc016a41026a2d00003a0000200141c0016a41086a2217200141d8056a41086a290300370300200141c0016a41106a2218200141d8056a41106a290300370300200141c0016a41186a2219200141d8056a41186a290300370300200141c0016a41206a221a200141d8056a41206a290300370300200141c0016a41286a221b200141d8056a41286a290300370300200141c0016a41306a200141d8056a41306a290300370300200120012f01fc013b01f801200120012903d8053703c001024020020d00200141bc016a41026a20162d00003a000020014190026a41086a201729030037030020014190026a41106a201829030037030020014190026a41186a201929030037030020014190026a41206a201a29030037030020014190026a41286a201b29030037030020014190026a412d6a200141c0016a412d6a290000370000200120012f01f8013b01bc01200120012903c001370390020240200128028402450d002004102e0b200120012f01bc013b01d8052001200141be016a2d00003a00da05410021020c030b0240200128028402450d002004102e0b02402015450d002010102e0b02402013450d002013410c6c21042012210203400240200241046a280200450d002002280200102e0b2002410c6a2102200441746a22040d000b0b4101210202402011450d002011410c6c450d002012102e0b20082109200621100c010b41012102410521090b0b20014180016a41086a220420014190026a41086a29030037030020014180016a41106a221620014190026a41106a29030037030020014180016a41186a221720014190026a41186a29030037030020014180016a41206a221820014190026a41206a29030037030020014180016a41286a221920014190026a41286a29030037030020014180016a412d6a221a20014190026a412d6a290000370000200120012d00da053a00ba01200120012f01d8053b01b80120012001290390023703800102400240024020020d00200141c0006a41086a22022004290300370300200141c0006a41106a22042016290300370300200141c0006a41186a22162017290300370300200141c0006a41206a22172018290300370300200141c0006a41286a22182019290300370300200141c0006a412d6a2219201a290000370000200120012d00ba013a007e200120012f01b8013b017c2001200129038001370340200141d0036a2003360200200141cc036a2005360200200141c8036a2007360200200141c4036a2013360200200141c0036a2011360200200141bc036a2012360200200141b8036a2014360200200141b4036a2015360200200141b0036a2010360200200141ac036a200936020020014190026a41c4016a20012f017c3b0100200141d6036a20012d007e3a0000200141db036a2006360000200141d7036a20083600002001410b3602a803200142023703f8022001418c046a201929000037000020014187046a2018290300370000200141ff036a2017290300370000200141f7036a2016290300370000200141ef036a2004290300370000200141e7036a2002290300370000200120012903403700df0320014194046a200141d8056a41c40110e9081a200120014190026a3602d805200141c0016a200141d8056a109005200141d8056a41086a200141c0016a41086a280200360200200120012903c0013703d805200141d8056a10e8062104024020012903f8024202510d0020012d00900241ff01714102470d00200128029802450d00200128029402102e0b200141a8036a108b02410721024106210920040d010c020b4107210220094107460d010b20014100360298022001420137039002200120073602d80520014190026a200141d8056a41041074200141003602d80520014190026a200141d8056a410410744101200a2000200128029002220220012802980210a1070240200128029402450d002002102e0b200921020b200f450d010b200a102e0b200141a0076a240020020bc41c07127f017e017f017e017f027e097f230041b0016b22022400200028020821032000280200210420002802042105200241206a41206a2206200041306a2d00003a0000200241206a41186a2207200041286a290000370300200241206a41106a2208200041206a290000370300200241206a41086a2209200041186a29000037030020022000290010370320024002400240024002400240024002400240024002400240024002400240024002400240024020052f0132220a410a4b0d0020024188016a41206a20062d00003a000020024188016a41186a200729030037030020024188016a41106a200829030037030020024188016a41086a20092903003703002002200229032037038801200541346a2106200a41016a2107200341016a2208200a4d0d012006200341216c6a220a200229038801370000200a41206a20024188016a41206a2d00003a0000200a41186a20024188016a41186a290300370000200a41106a20024188016a41106a290300370000200a41086a20024188016a41086a290300370000200541046a210a0c020b4105210a4100210b02400240200341054f0d004104210a200321060c010b41052106024002402003417b6a0e020201000b200341796a21064101210b4106210a0c010b410021064101210b0b41a003102c2203450d05200341003b013220034100360200200320052f0132220c200a417f736a22073b013220024190016a200541346a220d200a41216c6a2208410c6a29000037030020024198016a200841146a2900003703002002419d016a200841196a29000037000020022008290004370388012007410c4f0d06200c200a41016a22096b2007470d07200541046a220c200a4102746a280200210e2008280000210f200341346a200d200941216c6a200741216c10e9081a200341046a200c20094102746a200741027410e9081a2005200a3b0132200241e8006a41086a20024188016a41086a2208290300370300200241e8006a41106a20024188016a41106a2209290300370300200241e8006a41156a20024188016a41156a290000370000200220022903880137036820032005200b1b220a2f0132210720024188016a41206a220d200241206a41206a2d00003a000020024188016a41186a2210200241206a41186a2903003703002009200241206a41106a2903003703002008200241206a41086a2903003703002002200229032037038801200a41346a210b200741016a210c02400240200641016a221120074d0d00200b200641216c6a2207200229038801370000200741206a200d2d00003a0000200741186a2010290300370000200741106a2009290300370000200741086a2008290300370000200a41046a21070c010b200b201141216c6a200b200641216c6a220b200720066b41216c10ea081a200b41206a200d2d00003a0000200b41186a2010290300370000200b41106a2009290300370000200b41086a2008290300370000200b200229038801370000200a41046a220720114102746a200720064102746a200c2006417f736a41027410ea081a0b200720064102746a22122001360200200a200c3b0132200241086a2213200241e8006a41086a22102903002214370300200241106a2215200241e8006a41106a22112903002216370300200241186a200241e8006a41186a2217290300221837030020022002290368221937030020172018370300201120163703002010201437030020022019370368200528020022010d02410021040c030b2006200841216c6a2006200341216c6a2206200a20036b41216c10ea081a200641206a20024188016a41206a2d00003a0000200641186a20024188016a41186a290300370000200641106a20024188016a41106a290300370000200641086a20024188016a41086a2903003700002006200229038801370000200541046a220a20084102746a200a20034102746a20072003417f736a41027410ea081a0b200a20034102746a22122001360200200520073b01320c0e0b200e211a4100210a2003211b200f211c034020052f01302107200241c8006a41156a221d200241e8006a41156a290000370000200241c8006a41106a221e2011290300370300200241c8006a41086a221f2010290300370300200220022903683703482004200a470d0620012f01322209410b490d024100210841042105024020074105490d0020072105024002402007417b6a0e020201000b200741796a210741012108410621050c010b4100210741012108410521050b41d003102c2203450d03200341003b013220034100360200200320012f0132220b2005417f736a220a3b0132200141346a220c200541216c6a2206280000210f200241156a2220200641196a2900003700002015200641146a29000037030020132006410c6a29000037030020022006290004370300200a410c4f0d07200b200541016a22066b200a470d08200141046a220b20054102746a280200210e200341346a200c200641216c6a200a41216c10e9081a200341046a200b200641027422066a200a41027410e9081a200120053b013220024188016a41086a220b201329030037030020024188016a41106a220c201529030037030020024188016a41156a220d2020290000370000200220022903003703880120032f0132220a41016a2120200a410c4f0d09200920056b22052020470d0a200441016a2104200341a0036a200120066a41a0036a200541027410e9081a4100210502400340200320054102746a41a0036a280200220620053b01302006200336020020052005200a4922066a2205200a4b0d0120060d000b0b200241206a41186a222020024188016a41186a290300370300200241206a41106a2221200c290300370300200241206a41086a2222200b29030037030020022002290388013703202003200120081b22062f01322109200d201d290000370000200c201e290300370300200b201f2903003703002002200229034837038801200641346a210a0240200741016a220520094b221d0d00200a200541216c6a200a200741216c6a200920076b41216c10ea081a0b200941016a2108200a200741216c6a220a201c360000200a200229038801370004200a410c6a200b290300370000200a41146a200c290300370000200a41196a200d290000370000200641046a210a0240201d0d00200a20054102746a200a20074102746a2007417f7320086a41027410ea081a0b200a2007410274220b6a201a360200200641a0036a210a0240200741026a220c200941026a22094f0d00200a200c4102746a200a20054102746a2005417f7320096a41027410ea081a0b200a20054102746a201b360200200620083b01320240200520094f0d002006200b6a41a4036a210503402005280200220a200741016a22073b0130200a2006360200200541046a210520082007470d000b0b2010202229030037030020112021290300370300201720202903003703002002200229032037036820012105200128020022062101200e211a2004210a2003211b200f211c20060d000b0b20024188016a41186a201729030037030020024188016a41106a2011290300221437030020024188016a41086a2010290300221637030020022002290368221837038801200241e8006a41156a20024188016a41156a290000370000201120143703002010201637030020022018370368200028020c220a2802042206450d09200a280200210741d003102c2205450d01200520063602a003200541003b013220054100360200200641003b013020062005360200200a2005360204200a200741016a360200200241206a41156a200241e8006a41156a290000370000200241206a41106a200241e8006a41106a290300370300200241206a41086a200241e8006a41086a2903003703002002200229036837032020072004470d0a20052f01322207410b4f0d0b2005200741216c6a220641346a200f360000200641386a2002290320370000200641c0006a200241286a290300370000200641c8006a200241306a290300370000200641cd006a200241356a2900003700002005200741016a22063b0132200520064102746a41a0036a2003360200200520074102746a41046a200e360200200320063b013020032005360200200a200a28020841016a3602080c0d0b20012f0132210320024188016a41156a2209200241c8006a41156a29000037000020024188016a41106a2204200241c8006a41106a29030037030020024188016a41086a220b200241c8006a41086a2903003703002002200229034837038801200741016a2105200141346a210a0240200320074d22060d00200a200541216c6a200a200741216c6a200320076b41216c10ea081a0b200341016a2108200a200741216c6a220a201c360000200a200229038801370004200a410c6a200b290300370000200a41146a2004290300370000200a41196a2009290000370000200141046a210a024020060d00200a20054102746a200a20074102746a2007417f7320086a41027410ea081a0b200a200741027422096a201a360200200141a0036a210a200341026a2107024020060d002009200a6a41086a200a20054102746a2005417f7320076a41027410ea081a0b200a20054102746a201b360200200120083b0132200520074f0d0b200341016a210620012005417f6a22054102746a41a4036a210303402003280200220a200541016a22053b0130200a2001360200200341046a210320062005470d000c0c0b0b1036000b2007410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b41ac9cc700413541e49cc7001039000b200a410b41e49bc700104d000b41f49bc7004128419c9cc7001039000b2020410c41f49cc700104d000b41f49bc7004128419c9cc7001039000b41e8aac700412b4194abc7001039000b41e899c700413041989ac7001039000b41a89ac700412041c89ac7001039000b200028020c2205200528020841016a3602080b200241b0016a240020120be80a010f7f230041206b220224000240200128020041016a220341014d0d002001200336020020024100360210200241104104200241106a107d200241086a28020021030240024002400240024020022802004101460d00200228020422042001360200200128020041016a220541024f0d010c050b2003450d010c030b2001200536020020024100360210200241104104200241106a107d200241086a28020021060240024020022802004101460d00200228020422072001360200200128020041016a22054102490d052003410276210820012005360200200641027621094104210a4101210b0240024002400340200541016a220341014d0d0920012003360200200128020841016a220341004c0d0120012003360208200128020c2205450d07200541106a210c2007200b410274220d6a210e2007210602400340200e2006460d01200628020022032005460d09200328020841016a220f41004c0d042003200f3602082005280208220f41016a221041004c0d05200520103602080240200341106a200c412010ec080d0020032d003020052d0030470d002005200f36020820032003280208417f6a3602080c0a0b200641046a21062005200f36020820032003280208417f6a3602080c000b0b200128020c220328020041016a220541014d0d09200320053602000240200b2008470d00200b41016a2205200b490d07200b41017422062005200620054b1b22054104200541044b1b220541ffffffff037120054641027421062005410274210502400240200b0d00200241003602100c010b20024104360218200220043602102002200d3602140b200220052006200241106a107d2002280208210520022802004101460d0620022802042104200541027621080b2004200d6a2003360200200128020c220328020041016a220541014d0d092003200536020020012001280200417f6a2205360200024020050d002001410c6a10cd04200141046a22052005280200417f6a220536020020050d002001102e0b200328020041016a220541014d0d092003200536020002400240200b2009470d00200b41016a2205200b490d08200b41017422062005200620054b1b22054104200541044b1b220541ffffffff037120054641027421062005410274210502400240200b0d00200241003602100c010b20024104360218200220073602102002200d3602140b200220052006200241106a107d2002280208210520022802004101460d0120022802042107200541027621090b2007200d6a200336020020012001280208417f6a36020820012001280200417f6a2205360200024020050d002001410c6a10cd04200141046a22052005280200417f6a220536020020050d002001102e0b200b41016a210b200a41046a210a20032802002105200321010c010b0b20050d070c050b41bcd9cc004118200241106a41a4bfcc0041c0c1cc00103e000b41bcd9cc004118200241106a41c4ffc40041c4bfcc00103e000b41bcd9cc004118200241106a41c4ffc40041d4bfcc00103e000b20060d030c010b20050d020b1038000b20012001280208417f6a36020820012001280200417f6a2203360200024020030d002001410c6a10cd04200141046a22032003280200417f6a220336020020030d002001102e0b20002004360204200020013602002000410c6a200b360200200041086a20083602000240200b450d00200721030340200328020022052005280200417f6a3602000240200328020022052802000d002005410c6a10cd04200328020041046a22052005280200417f6a3602002003280200220541046a2802000d002005102e0b200341046a2103200a417c6a220a0d000b0b0240200941ffffffff0371450d002007102e0b200241206a24000f0b1036000b00000bae0201047f230041106b220224004100210302400240024002400240024002402000280208220441016a220541004c0d0020002004360208200028020c2204450d0620002005360208024020042001470d00410121030c060b200428020841016a220341004c0d01200420033602082001280208220541016a220341004c0d0220012003360208200441106a200141106a412010ec080d034101210320042d003020012d0030470d030c040b41bcd9cc004118200241086a41a4bfcc0041b4bfcc00103e000b41bcd9cc004118200241086a41a4bfcc0041c4bfcc00103e000b41bcd9cc004118200241086a41a4bfcc0041d4bfcc00103e000b410021030b2001200536020820042004280208417f6a360208200028020821050b20002005417f6a3602080b200241106a240020030bc80101047f230041c0006b220224004119210341e0b2c7002104410221050240024002400240200141ff01710e0400010203000b2002411c6a41013602002002420137020c2002419cc3cb00360208200241043602242002418883ca003602202002200241206a360218200241086a41c4afc8001044000b411a21034198b2c7002104410021050c010b411b210341bcb2c7002104410121050b20004183c8003b0100200041086a2003360200200041046a2004360200200041026a20053a0000200241c0006a24000b130020004103360204200041c4b1c7003602000bc40403027f017e037f230041a0036b22022400200241d0026a410c6a200041f0016a290200370200200241e4026a200041f8016a290200370200200241ec026a20004180026a290200370200200241e2c289ab063602d002200220002902e8013702d4022001280200210320024190036a200141046a10c301200241f8026a410c6a20024190036a41086a280200360200200220033602f80220022002290390033702fc02200220012802103602880320024180026a200241d0026a200241f8026a109d0402400240024020022802c002450d00200241a8016a41056a20024180026a41d00010e9081a200241d0006a200241a8016a41d50010e9081a2002200241d0006a41056a41d00010e908220141a8016a200141d00010e9081a200141d0006a410c6a210320002903002104410021054100210002400340200041d000460d014108102c2206450d0420014208370254200120063602502001200437038002200141d0006a20014180026a41081074200341086a41002900a197453700002003410029009997453700002001200141a8016a20006a36026c20014180026a200141d0006a10ae0102402001280254450d002001280250102e0b200141d0006a20014180026a108e03200128025022072001280258108f02210602402001280254450d002007102e0b200041d0006a210020060d000b410221050b0240200141ec016a2802002200450d00200041306c450d00200141e8016a280200102e0b41800621010c010b4100210541800821010b200241a0036a240020012005720f0b1036000b130020004106360204200041b4b4c7003602000b3400200041bad7c70036020420004100360200200041146a4102360200200041106a41c4d7c700360200200041086a42083702000b130020004105360204200041f8dcc7003602000b4401027f230041106b2202240002404104102c22030d001036000b200042043702042000200336020020024180800136020c20002002410c6a41041074200241106a24000b4901027f230041106b2202240002404110102c22030d001036000b20004210370204200020033602002002420037030820024280c2d72f3703002000200241101074200241106a24000b4a01027f230041106b2202240002404110102c22030d001036000b20004210370204200020033602002002420037030820024280c8afa0253703002000200241101074200241106a24000b4201027f230041106b2202240002404101102c22030d001036000b2000420137020420002003360200200241143a000f20002002410f6a41011074200241106a24000b4401027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241c0f00036020c20002002410c6a41041074200241106a24000bab0301087f230041106b2203240020032000200220016b10fc060240024020032802004101470d00200341086a2802000d0141d0f0cc00411141e4f0cc001039000b02400240200028020022044125490d002000410c6a22052802002106200041086a28020021070c010b200041056a21072004210620002105412421040b024002400240200620044f0d00034020022001460d02200720066a20012d00003a0000200141016a21012004200641016a2206470d000b200421060b2005200636020020012002460d01200141016a21062000410c6a2108200041056a210920012d0000210a034002400240200028020022074125490d00200028020c210120002802082105200821040c010b200721012000210420092105412421070b024020012007470d0020032000410110fc06024020032802004101470d00200341086a2802000d0541d0f0cc00411141e4f0cc001039000b200028020c210120002802082105200821040b200520016a200a3a00002004200428020041016a36020020022006460d0220062d0000210a200641016a21060c000b0b200520063602000b200341106a24000f0b1036000baa0301047f02400240200128020022034125490d002001410c6a2802002104200321050c010b41242105200321040b0240200520046b2002490d00200041003602000f0b0240024002400240200420026a22022004490d004100417f2002417f6a677620024102491b220441016a22052004490d000240024020034125490d002001410c6a2802002104200141086a2802002102200321060c010b200141056a210241242106200321040b200420054b0d010240200541244b0d000240200341244b0d00200041003602000f0b200141003a0004200141056a2002200410e9081a200120043602002002102e0c040b20062005460d030240200341244b0d0002402005102c2203450d0020032002200410e9081a0c040b2000200536020420004101360200200041086a41013602000f0b200220062005103022030d022000200536020420004101360200200041086a41013602000f0b2000200536020420004101360200200041086a41003602000f0b41c2f1cc00412041e4f1cc001039000b200141013a0004200120053602002001410c6a2004360200200141086a20033602000b200041003602000bd60501047f20002802282101024002400240024020002d000022024102470d002000410c6a2802002102200041086a2802002103200041046a280200210020012001280200417f6a2204360200024020040d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22042004280200417f6a220436020020040d002001102e0b0240200041ff01710d0041002104200320024f0d030b4110102c2200450d03200041f8f7c60036020c2000410136020820004281808080103702004110102c2201450d0320014190f8c60036020c20014101360208200142818080801037020020002000280200417f6a220436020020040d012000280208200028020c2802001103000240200028020c280204450d002000280208102e0b200041046a22042004280200417f6a220436020020040d012000102e0c010b410021040240024020020e0400010103010b20002d0001210020012001280200417f6a2204360200024020040d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22042004280200417f6a220436020020040d002001102e0b0240200041ff01710d0041010f0b4110102c2200450d03200041f8f7c60036020c2000410136020820004281808080103702004110102c2201450d0320014190f8c60036020c20014101360208200142818080801037020020002000280200417f6a220436020020040d012000280208200028020c2802001103000240200028020c280204450d002000280208102e0b200041046a22042004280200417f6a220436020020040d012000102e0c010b4101210420024103460d010b20012001280200417f6a22003602004102210420000d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22002000280200417f6a220036020020000d002001102e0b20040f0b1036000be21205027f0c7e037f027e017f230041c0026b220524000240024020022003844200520d0020004100360200200041106a4200370300200041086a42003703000c010b2005200136020c200541d0006a200110c802200541c0016a20052802502206200528025810c902200541c0016a41386a2903002107200541c0016a41306a2903002108200541c0016a41286a2903002109200541c0016a41206a290300210a200541c0016a41186a290300210b200541c0016a41106a290300210c20054180026a290300210d20052903c801210e20052903c001210f20054190016a41086a20054190026a290300370300200520054188026a2903003703900102400240200f4201510d004200210d200541106a41386a4200370300200541106a41306a4200370300200541106a41286a4200370300200541106a41206a4200370300200541106a41186a4200370300200541106a41106a4200370300200541106a41086a4200370300200542003703104200210a4200210942002108420021074200210e4200210c4200210b42002110420021114200210f420021120c010b200541106a41206a2009370300200541106a41286a2008370300200541106a41106a200b370300200541106a41306a20073703002005200a3703282005200e3703102005200d3703482005200c3703182009211020082111200e210f200c21120b02402005280254450d002006102e0b02400240200f2012844200520d0020102005290320842011200541286a29030084844200520d002005290340200541c8006a2903008450450d0042002110410021130c010b42012110410121130b024020104201510d004200210a4200210b4200210d4200210942002108420021074200210e4200210c0b41032106024002400240200e20027d2212200e56200c20037d200e200254ad7d220f200c56200f200c511b450d004113211441c8a3c700211541052101410321130c010b02402012200b7c221642ffc7afa02556200f200a7c20162012542214ad7c22114200522011501b0d00200e200b7c221742ffc7afa02556200c200a7c2017200e54ad7c220e420052200e501b450d00410921144180a4c700211541052113410521010c010b200541c0016a20012002200320042012200f10d706024020052d00c00122064106460d00200541c8016a280200211420052802c401211520052d00c301210420052d00c201211320052d00c10121010c010b200541e8016a22152008370300200541f0016a221820073703002005200b3703d001200541d8016a200a370300200520093703e001200520123703c0012005200f3703c8014200210c2002422088a721062002a7210402400240427f201620142011200f542011200f511b22141b220242ffc7afa02556427f201120141b220e420052200e501b0d002012200b84200f200a8484220c5021144200210b200c420052ad210c0c010b2018290300211720152903002116200541e0016a2903002111200541d0016a290300210920052903d801210720052903c801210820052903c001210a4201210b410121140b200541f8006a200e370300200541f0006a22152002370300200541e0006a200f370300200520123703582005200337038801200520063602840120052004360280012005200c37036820052010420152ad22033703500240024002400240024002402013200b420152720d00200520013602c0012001200541c0016a10bd060c010b024020134101732206200b420151720d00200520013602c0012001200541c0016a10be0641ff017122064103460d01024020060e03030200030b20054180016a2101024020140d00200520153602c001200541c0016a10cc020b200520013602c001200541c0016a10cc02410421064100210441002113410021010c070b200b4201522006710d020b200541a0016a200110c802200541c0016a20052802a001220420052802a801221310c90220052903c001210e20054190016a41086a220620054190026a290300370300200520054188026a2903003703900102400240200e4201510d00200541b0016a41086a4200370300200542003703b0010c010b200541b0016a41086a200629030037030020052005290390013703b0010b20054188026a20052903b00137030020054190026a200541b0016a41086a290300370300200542013703c001200541c0016a41386a20174200200b42015122061b370300200541f0016a2016420020061b370300200541c0016a41286a2011420020061b370300200541e0016a2007420020061b370300200541d8016a2009420020061b370300200541c0016a41106a2008420020061b37030020054180026a200d420020061b3703002005200a420020061b3703c80120042013200541c0016a41086a10c805024020052802a401450d002004102e0b200541d0006a41106a290300210f200541d0006a41286a290300210e200541d0006a41386a290300210920052903582112200529037021022005290380012108200529035021032005290368210c0c030b20054188016a29030021090c010b20054188016a29030021090b20052903800121080b024020034201520d00200541f8016a200f370300200541f0016a2012370300200541c0016a41086a41003a0000200541c9016a2001290000370000200541d1016a200141086a290000370000200541d9016a200141106a290000370000200541e1016a200141186a290000370000200541033a00c001200541c0016a10fe010b02400240200c50450d004200210c0c010b200541c0016a41086a200528020c220141086a290000370300200541c0016a41106a200141106a290000370300200541c0016a41186a200141186a290000370300200520012900003703c0014201210c0b200541d0006a41186a200541c0016a41186a22012903002203370300200541d0006a41106a200541c0016a41106a2206290300220b370300200541d0006a41086a200541c0016a41086a290300220a370300200520052903c001220f370350200541f0016a200e370300200541e8016a220420023703002006200a3703002001200b370300200541e0016a20033703002005200c3703c0012005200f3703c801200541c0016a10d204024020052903c001500d0020052004360210200541106a10cc020b20004100360200200041106a2009370300200041086a20083703000c020b2014ad4220862015ad84210e0b200041086a200e3702002000410136020020002004411874201341ff017141107472200141ff0171410874722006723602040b200541c0026a24000bdb0403027f027e037f230041a0036b22022400200241d0026a410c6a200041e8016a290200370200200241e4026a200041f0016a290200370200200241ec026a200041f8016a290200370200200241e7e485f3063602d0022002200041e0016a2902003702d4022001280200210320024190036a200141046a10c301200241f8026a410c6a20024190036a41086a280200360200200220033602f80220022002290390033702fc02200220012802103602880320024180026a200241d0026a200241f8026a109d040240024020022802c002450d00200241a8016a41056a20024180026a41d00010e9081a200241d0006a200241a8016a41d50010e9081a2002200241d0006a41056a41d00010e9082101200041106a290300210420002903002105200141a8016a200141d00010e9081a200141d0006a410c6a2103410021064100210002400340200041d000460d0120014201370350200141003602582001200537038002200141d0006a20014180026a410810742001200437038002200141d0006a20014180026a41081074200341086a410029009197453700002003410029008997453700002001200141a8016a20006a36026c20014180026a200141d0006a10ae0102402001280254450d002001280250102e0b200141d0006a20014180026a108e03200128025022072001280258108f02210802402001280254450d002007102e0b200041d0006a210020080d000b410221060b0240200141ec016a2802002200450d00200041306c450d00200141e8016a280200102e0b41800621010c010b4100210641800821010b200241a0036a240020012006720b130020004104360204200041fcedc7003602000b3400200041bcdbc80036020420004100360200200041146a4101360200200041106a41a480c800360200200041086a42073702000b130020004101360204200041cc81c8003602000b900706027f017e027f017e087f057e23002203210420034180016b4160712203240042e4cab5fbb6ccdcb0e3002105200342e4cab5fbb6ccdcb0e3003703180240024002402001200284500d00200341e0006a200010d40620032802602106200328026421074201210802400240200328026822090d002006210a0c010b200620094105746a210b200341c0006a41196a210c200621092006210a0340200341286a41106a220d200941106a290300370300200341286a41086a220e200941086a29030037030020032009290300370328200941186a2d0000210f2003200941196a28000036022020032009411c6a280000360023200f4103460d01200c2003280220360000200c41036a22102003280023360000200341c0006a41106a200d2903002211370300200341c0006a41086a220d200e290300370300200320032903283703402003200f3a005802400240024020112003290318520d002008a7210e200341033a0078200329037021052003290360211220032903682113200329037821080240200e41ff0171220e4103470d0020122101201321020c030b200d2903002211200220032903402214200156201120025620112002511b220d1b211120142001200d1b2114200f4102200f200e461b210f2003290350211520122101201321020c010b2003200c28000036026020032010280000360063200d290300211120032903402114200329035021150b200a2014370300200a200f3a0018200a2015370310200a2003280260360019200a2011370308200a411c6a2003280063360000200a41206a210a0b200941206a2209200b470d000b0b200a20066b410575210902400240200842ff018342038550450d00200721030c010b0240024020092007460d0020072103200921070c010b200741016a22092007490d042007410174220a2009200a20094b1b22094104200941044b1b220941ffffff3f71200946410374210a200941057421090240024020070d00200341003602600c010b200341e0006a41086a410836020020032006360260200320074105743602640b200341c0006a2009200a200341e0006a107d200341c8006a280200210920032802404101460d0320032802442106200941057621030b200620074105746a220920053703102009200237030820092001370300200941186a2008370300200741016a21090b20002006200910d506200341ffffff3f71450d002006102e0b200424000f0b2009450d001036000b1038000b130020004104360204200041888dc8003602000b3400200041f8fcc60036020420004100360200200041146a4104360200200041106a41c8a7c800360200200041086a42083702000b130020004101360204200041acaec8003602000bf00101037f230041106b2202240020004100360208200042013702002001200010e805200141106a200010e8052002200128022036020c20002002410c6a410410742002200128022436020c20002002410c6a410410742002200128022836020c20002002410c6a41041074200141306a2802002103200141386a200141346a200128022c4101461b28020022042000107602402004410c6c2204450d00200320046a2104034020002003410810742002200341086a28020036020c20002002410c6a410410742003410c6a22032004470d000b0b2002200128023c36020c20002002410c6a41041074200241106a24000bcf0301027f230041206b2205240020054100360208200542013703000240024002400240024020002802000e03000102030b200541003a00102005200541106a410110744120102c2206450d032005422037021420052006360210200541106a200041086a412010742005200528021022062005280218107402402005280214450d002006102e0b200520002802043602102005200541106a410410740c020b200541013a00102005200541106a410110744120102c2206450d022005422037021420052006360210200541106a200041086a412010742005200528021022062005280218107402402005280214450d002006102e0b200520002802043602102005200541106a410410740c010b200541023a00102005200541106a410110744120102c2206450d012005422037021420052006360210200541106a200041086a412010742005200528021022062005280218107402402005280214450d002006102e0b200520002802043602102005200541106a410410740b200520033703102005200541106a41081074200520043703102005200541106a4108107420022005280200220620052802082001108907210002402005280204450d002006102e0b200541206a240020000f0b1036000b150020002002ad4220862001ad84200310034101460b130020004101360204200041ecb7c8003602000b3400200041a5fec60036020420004100360200200041146a4106360200200041106a41f0bec800360200200041086a421a3702000b130020004103360204200041c8cac8003602000b4301027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241d80436020c20002002410c6a41041074200241106a24000b100020002802002000280204200110680bbc0201037f23004180016b2202240020002802002100024002400240024020012802002203411071450d0020002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141ac88c0004102200220006a4180016a410020006b104b21000c010b2000280200210402402003412071450d00410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d03200141ac88c0004102200220006a4180016a410020006b104b21000c010b2004ad2001104821000b20024180016a240020000f0b2004418001419c88c0001056000b2004418001419c88c0001056000b8a0702027f047e230041f0016b2202240020002802002100024002400240024020012802002203411071450d00200041086a290300210420002903002105418001210002400340024020000d00410021000c020b200241f0006a20006a417f6a2005a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b20004181014f0d030b200141ac88c0004102200241f0006a20006a41800120006b104b21000c010b200041086a29030021042000290300210502402003412071450d00418001210002400340024020000d00410021000c020b200241f0006a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b20004181014f0d040b200141ac88c0004102200241f0006a20006a41800120006b104b21000c010b2002412736026c02400240200442ffff1f560d0020054213882004422d868442bda282a38eab04802104420021060c010b200241386a2005420042f3b2d8c19e9ebdcc957f420010e808200241286a2005420042d2e1aadaeda7c987f600420010e808200241d8006a2004420042f3b2d8c19e9ebdcc957f420010e808200241c8006a2004420042d2e1aadaeda7c987f600420010e808200241c8006a41086a290300200241286a41086a290300200241386a41086a290300220620022903287c2204200654ad7c220720022903487c2206200754ad7c2006200241d8006a41086a290300200420022903587c200454ad7c7c2204200654ad7c2207423e8821062004423e8820074202868421040b200241186a20042006428080e0b0b79fb79cf500427f10e808200229031820057c200241f0006a200241ec006a106702402004200684500d00200241f0006a41146a4130200228026c416c6a10eb081a2002411436026c200241086a20044213882006422d8684220542bda282a38eab048022062004428080e0b0b79fb79cf500427f10e808200229030820047c200241f0006a200241ec006a1067200542bda282a38eab04540d00200241f1006a4130200228026c417f6a10eb081a20022006a74130723a00702002410036026c0b200141d4e2cc004100200241f0006a200228026c22006a412720006b104b21000b200241f0016a240020000f0b2000418001419c88c0001056000b2000418001419c88c0001056000ba90705017f047e027f017e017f230041c0016b22022400200241b0016a200141186a2903002203200041186a29020085420020012903102204200029021085420010e808200241a0016a2003200041086a2902008542002004200029020085420010e8082001200141086a2903002205200241a0016a41086a29030020022903a001857c2005200241b0016a41086a29030020022903b001857c200129030042adfed5e4d485fda8d8007e42a0cbbf9599b5a19f0a7c8542178985421789220637030002400240200028022022074125490d002000412c6a2802002107200041286a28020021080c010b200041256a21080b20024190016a20062007ad220985420042adfed5e4d485fda8d800420010e808200120024198016a2903002002290390018520097c42adfed5e4d485fda8d8007e22063703000240024002400240024020074109490d00200741104d0d01200241c0006a2003200720086a41706a220a41086a2900008542002004200a29000085420010e80820012005200241c0006a41086a2903002002290340857c20068542178922063703000340200241306a2003200841086a2900008542002004200829000085420010e808200841106a21082005200241306a41086a2903002002290330857c2006854217892106200741706a220741104b0d000c040b0b0240200741014b0d002007450d0420024180016a2006200831000085420042adfed5e4d485fda8d800420010e80820024188016a2903002002290380018521060c030b200741034b0d01200241f0006a200720086a417f6a310000422086200833000084200685420042adfed5e4d485fda8d800420010e808200241f8006a29030020022903708521060c020b200241d0006a2003200720086a41786a2900008542002004200829000085420010e8082005200241d8006a2903002002290350857c20068542178921060c010b200241e0006a2003200720086a417c6a3500008542002004200835000085420010e8082005200241e8006a2903002002290360857c20068542178921060b200120063703000b02400240200041cc006a2d00000d0020022006420042adfed5e4d485fda8d800420010e808200241086a29030020022903008521060c010b200241206a2006420185420042adfed5e4d485fda8d800420010e808200241106a200241206a41086a290300200229032085200041cd006a31000085420042adfed5e4d485fda8d800420010e808200241106a41086a29030020022903108521060b20012006370300200241c0016a24000b6901017f230041206b220324002003200136020420032000360200200341086a41106a200241106a290200370300200341086a41086a200241086a29020037030020032002290200370308200341a4cec800200341046a41a4cec800200341086a4180a2cc001058000bd30202027f017e23004180016b2202240020002802002100024002400240024020012802002203411071450d0020002903002104418001210002400340024020000d00410021000c020b200220006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004181014f0d030b200141ac88c0004102200220006a41800120006b104b21000c010b2000290300210402402003412071450d00418001210002400340024020000d00410021000c020b200220006a417f6a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004181014f0d040b200141ac88c0004102200220006a41800120006b104b21000c010b20042001104821000b20024180016a240020000f0b2000418001419c88c0001056000b2000418001419c88c0001056000b13002000410636020420004194cfc8003602000b110041e2a0cc00412841acd3c8001039000b110041e2a0cc00412841bcd3c8001039000bfb0501087f230041206b22042400024002400240200141086a280200220541036a2206417f4c0d0020012d000021072001280204210820012d000121094101210102402006450d002006102c2201450d020b20002001360200200041086a4100360200200041046a2006360200200541017420076a220141ffff03200141ffff03491b220641c0006a41ff0020062006413e2006413e491b220a461b21012006200a6b21064101210a02400340024002400240200a41ff01714102470d002001210b0c010b4100210b200a410171450d004100210a0c010b2006450d020240200641ff014b0d002006417f6a21014102210a410021060c010b200641817e6a210641ff0121014102210a0b200420013a00102000200441106a41011074200b21010c000b0b024002400240024020070d00200041046a2802002106200041086a28020021010c010b0240200041086a220b280200220a200041046a2802002206470d00200a41016a2201200a490d04200a41017422062001200620014b1b22014108200141084b1b210102400240200a0d00200441003602100c010b200441106a41086a41013602002004200a360214200420002802003602100b200420014101200441106a10d104200441086a280200210620042802004101460d0220002004280204360200200041046a20063602000b200b200a41016a22013602002000280200200a6a2009410f713a00000b200620016b2005490d01200028020021060c040b2006450d010c020b200120056a220a2001490d002006410174220b200a200b200a4b1b220a4108200a41084b1b210a0240024020060d00200441003602100c010b200441106a41086a410136020020042006360214200420002802003602100b2004200a4101200441106a10d104200441086a280200210a024020042802004101460d00200020042802042206360200200041046a200a3602000c030b200a0d010b1038000b1036000b200620016a2008200510e9081a200041086a200120056a3602002003200010762000200220031074200441206a24000bff0101047f230041c0006b2202240041aab4c700210341092104410521050240024002400240024002400240200141ff01710e0700010203040506000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a41c4c5cb001044000b419eb4c7002103410c2104410021050c040b4192b4c7002103410c2104410121050c030b4188b4c7002103410a2104410221050c020b41ffb3c7002103410321050c010b41f6b3c7002103410421050b20004183c6003b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000bf50101047f230041306b22022400200241bad7c7004108108102200241106a41dcd9c7004107108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bb40201037f230041e0006b22022400200241086a41bad7c7004108108102200241186a41f4d8c7004104108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241c8006a41086a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000bb40201037f230041e0006b22022400200241086a41bad7c7004108108102200241186a41f4d8c7004104108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241c8006a41086a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000b1300200041033602042000418cd4c8003602000b9a0801097f230041e0006b220224000240024020012802202203109e07450d0020004180063b0001200041013a0000200041036a410a3a00000c010b200241386a22044200370300200241306a22054200370300200241206a41086a420037030020024200370320200241206a41a081ca004107108102200241c0006a41e4d1c100410c1081022004200241c0006a41086a29000037030020052002290040370300200241086a200241206a4120108e020240200128021c200228020c410020022802081b2206460d0020004180063b0001200041013a0000200041036a410a3a00000c010b200241106a10870302400240200228021822052001280224460d00200041800e3b0001200041013a0000200041036a410a3a00000c010b0240200520034b0d0020004180083b0001200041013a0000200041036a410a3a00000c010b200141286a2107200228021020034105746a2108200241003602282002420137032020022001280200360240200241206a200241c0006a41041074200128020421042001410c6a2802002209200241206a1076200241206a200420091074200141106a2802002104200141186a2802002209200241206a10762006210a02402009450d0020042009410c6c6a2109034020042802002103200441086a2802002205200241206a1076200241206a2003200510742004410c6a22042009470d000b2001280224210520012802202103200128021c210a0b2002200a360240200241206a200241c0006a4104107420022003360240200241206a200241c0006a4104107420022005360240200241206a200241c0006a410410742007200228022022012002280228200810fa04210402402002280224450d002001102e0b024020040d0020004180083b0001200041013a0000200041036a410a3a00000c010b0240024002404110102c2204450d0020024210370254200220043602504108200241d0006a1076200241d0006a41bed8c8004108107420022006360220200241d0006a200241206a41041074200241d0006a20084120107420024100360220200241c0006a41304104200241206a107d200241c0006a41086a280200210120022802404101470d012001450d020b1036000b200228024422042002290350370200200441086a200241d0006a41086a280200360200200220022800203602402002200241236a280000360043200041306a41013a00002000412c6a4101360200200041286a2001410c6e360200200041246a2004360200200041206a4100360200200041186a4204370300200041106a42b009370300200041086a427f370300200041003a0000200041316a2002280240360000200041346a2002280043360000200228021441ffffff3f71450d022002280210102e0c020b1038000b200228021441ffffff3f71450d002002280210102e0b200241e0006a24000bdc0102037f017e230041306b22012400200141186a22024200370300200141106a22034200370300200141086a420037030020014200370300200141a081ca004107108102200141206a41f09dc500410a1081022002200141206a41086a29000037030020032001290020370300200141206a200110880320012802202202410120021b21030240024002402001290224420020021b2204422088a720004b0d0041002100200442ffffff3f8350450d010c020b2000200320004105746a10be012100200442ffffff3f83500d010b2003102e0b200141306a240020000bec0505017f017e097f027e027f230041306b2201240002400240101c2202422088a722030d002001200336020c200141013602080c010b2001200336020c20012002a7220436020820042d0000210520012003417f6a36020c2001200441016a3602080240024002400240024020050e020001050b200141206a200141086a10db0820012802202206450d04200141286a2802002107200128022421082001200141086a10ab0120012802000d03024020012802042209200128020c410c6e2205200520094b1bad420c7e2202422088a70d002002a72205417f4c0d000240024020050d004104210a0c010b2005102c220a450d040b2005410c6ead2102024002402009450d000340200141206a200141086a10db0802402001280220220b0d0002402002422088a72205450d002005410c6c2109200a210503400240200541046a280200450d002005280200102e0b2005410c6a2105200941746a22090d000b0b2002a72205450d082005410c6c450d08200a102e0c080b2001290224210c02402002422088220da722052002a7470d00200541016a220e2005490d042005410174220f200e200e200f491b220e4104200e41044b1bad420c7e220d422088a745410274210e200da7210f0240024020050d00200141003602200c010b200141043602282001200a36022020012005410c6c3602240b200141106a200f200e200141206a107d2001280218210e20012802104101460d032001280214210a2002422088220da72105200e410c6ead21020b200a2005410c6c6a2205200c3702042005200b360200200d422086200242ffffffff0f83844280808080107c21022009417f6a22090d000b0b200a450d0520060d030c060b200e0d030b1038000b410021060b2000200836020420002006360200200041106a20023702002000410c6a200a360200200041086a200736020002402003450d002004102e0b200141306a24000f0b1036000b2008450d002006102e0b41cae0cc00412e200141206a41f8e0cc004188e1cc00103e000bd10302017f017e230041a0016b220524002005200136020c024002402005410c6a20022004ad4220862003ad8410092206422088a722030d00410121020c010b2006a721020b200520033602542005200236025002402003450d0020022d0000210420052003417f6a3602542005200241016a360250410021030240024020040e020100020b200541d8006a200541d0006a10a70120052d00584101460d01200541c8006a20054191016a290000370300200541c0006a20054189016a290000370300200541386a20054181016a290000370300200541306a200541f9006a290000370300200541286a200541f1006a290000370300200541206a200541e9006a290000370300200541186a200541e1006a29000037030020052005290059370310410121030b200020033a000020002005290310370001200041096a200541186a290300370000200041116a200541206a290300370000200041196a200541286a290300370000200041216a200541306a290300370000200041296a200541386a290300370000200041316a200541c0006a290300370000200041396a200541c8006a2903003700002002102e200541a0016a24000f0b41cae0cc00412e200541d8006a41f8e0cc004188e1cc00103e000b1d0020004101472002ad4220862001ad842004ad4220862003ad84101b0b930201017f230041106b22022400200220002903003703082001200241086a410810740240024020002903084201510d00200241003a00082001200241086a410110740c010b200241013a00082001200241086a410110742002200041106a2903003703082001200241086a410810740b0240024020002903184201510d00200241003a00082001200241086a410110740c010b200241013a00082001200241086a410110742002200041206a2903003703082001200241086a410810740b0240024020002903284201510d00200241003a00082001200241086a410110740c010b200241013a00082001200241086a410110742002200041306a2903003703082001200241086a410810740b200241106a24000b850201037f230041d0006b22022400200241086a41d9fcc6004106108102200241186a41d8f3cb00410d108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000b830101037f230041206b2202240020022000108c02200228020821032002280200210002404120102c2204450d002002422037021420022004360210200241106a2001412010742000200320022802102201200228021810b20102402002280214450d002001102e0b02402002280204450d002000102e0b200241206a24000f0b1036000b130020004103360204200041d0ddc8003602000b3400200041a0dac80036020420004100360200200041146a4106360200200041106a41fce8c800360200200041086a420f3702000b4201027f230041106b2202240002404108102c22030d001036000b2000420837020420002003360200200242003703082000200241086a41081074200241106a24000b0d00200041002000200010da060b3001017f0240200128020022022001280204470d00200041003602000f0b2001200241e0016a3602002000200210d0030b290020004101360204200041086a200128020420012802006b41e0016e2201360200200020013602000ba20801087f230041d0006b22052400200541306a22064200370300200541286a22074200370300200541186a41086a2208420037030020054200370318200541386a41a0dac800410f1081022008200541386a41086a220929000037030020052005290038370318200541386a41afdac800410d1081022006200929000037030020072005290038370300024002400240200541186a4120108f020d0020064200370300200742003703002008420037030020054200370318200541186a41d9fcc6004106108102200541386a4180f4cb0041061081022006200929000037030020072005290038370300200541106a200541186a4120108e022005280214410020052802101b2106024020034101470d00200541306a220a4200370300200541286a220b4200370300200541186a41086a2208420037030020054200370318200541386a41a0dac800410f1081022008200541386a41086a220929000037030020052005290038370318200541386a41fcedc800410a108102200741086a220c200929000037000020072005290038370000200541086a200541186a4120108e0202402005280208450d00200528020c20064d0d002000410410b0070c030b200a4200370300200b42003703002008420037030020054200370318200541386a41a0dac800410f1081022008200929000037030020052005290038370318200541386a41fcedc800410a108102200c2009290000370000200720052900383700002005200241017420066a360238200541186a4120200541386a410410b2010b200128020421082001280200210920012802082101200541306a4200370300200541286a4200370300200541186a41086a220a420037030020054200370318200541386a41a0dac800410f108102200a200541386a41086a220b29000037030020052005290038370318200541386a41afdac800410d108102200741086a200b29000037000020072005290038370000200541003602402005420137033820052006360248200541386a200541c8006a4104107420052002360248200541386a200541c8006a410410742001200541386a10760240200141286c2207450d00200920076a2101200921070340200541386a2007412010742005200741206a290300370348200541386a200541c8006a41081074200741286a22072001470d000b0b0240024020034101460d00200541003a0048200541386a200541c8006a410110740c010b200541013a0048200541386a200541c8006a4101107420052004360248200541386a200541c8006a410410740b200541186a412020052802382207200528024010b2010240200528023c450d002007102e0b02402008450d00200841286c450d002009102e0b200041063a00000c020b2000410310b0070b200141046a2802002207450d00200741286c450d002001280200102e0b200541d0006a24000b840201047f230041d0006b22022400200241a0dac800410f108102200241106a4194efc800410c108102200220013703302002200241306a410810a301370338200241c0006a410c6a200241306a41086a3602002002200241386a41086a3602442002200241306a3602482002200241386a360240200241206a200241c0006a107c024002402002280228220341206a2204417f4c0d000240024020040d00410121050c010b2004102c2205450d020b20004100360208200020043602042000200536020020002002411010742000200241106a411010742000200228022022042003107402402002280224450d002004102e0b200241d0006a24000f0b1038000b1036000bd30302057f017e230041b0016b2202240002400240200128020022032001280204470d00200041003602000c010b2001200341e0016a3602002002200341206a41e2c289ab0610d103200228020421042002280200210541002101200241003a00680240024002400240034020042001460d01200241c8006a20016a200520016a2d00003a00002002200141016a22063a00682006210120064120460d020c000b0b200141ff0171450d01200241003a00680c010b200241f0006a41086a2201200241c8006a41086a290300370300200241f0006a41106a2204200241c8006a41106a290300370300200241f0006a41186a2205200241c8006a41186a29030037030020022002290348370370200641ff0171411f4d0d00200241286a41186a20052903002207370300200241086a41086a2001290300370300200241086a41106a2004290300370300200241086a41186a2007370300200220022903703703080c010b200241106a4200370300200241186a4200370300200241206a4200370300200242003703080b20002003360200200020022903083700042000410c6a200241106a290300370000200041146a200241186a2903003700002000411c6a200241206a2903003700000b200241b0016a24000b3001017f0240200128020022022001280204470d00200041003602000f0b2001200241e0016a3602002000200210d2030bd30302057f017e230041b0016b2202240002400240200128020022032001280204470d00200041003602000c010b2001200341e0016a3602002002200341206a41e1ea91cb0610d103200228020421042002280200210541002101200241003a00680240024002400240034020042001460d01200241c8006a20016a200520016a2d00003a00002002200141016a22063a00682006210120064120460d020c000b0b200141ff0171450d01200241003a00680c010b200241f0006a41086a2201200241c8006a41086a290300370300200241f0006a41106a2204200241c8006a41106a290300370300200241f0006a41186a2205200241c8006a41186a29030037030020022002290348370370200641ff0171411f4d0d00200241286a41186a20052903002207370300200241086a41086a2001290300370300200241086a41106a2004290300370300200241086a41186a2007370300200220022903703703080c010b200241106a4200370300200241186a4200370300200241206a4200370300200242003703080b20002003360200200020022903083700042000410c6a200241106a290300370000200041146a200241186a2903003700002000411c6a200241206a2903003700000b200241b0016a24000b9b0201047f230041c0006b2202240041baddc8002103411621044106210502400240024002400240024002400240200141ff01710e080001020304050607000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a41b48dcc001044000b41afddc8002103410b2104410021050c050b41a3ddc8002103410c2104410121050c040b4196ddc8002103410d2104410221050c030b418fddc800210341072104410321050c020b41f7dcc800210341182104410421050c010b41dfdcc800210341182104410521050b20004183163b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000b130020004101360204200041c8f3c8003602000b3400200041bed8c80036020420004100360200200041146a4104360200200041106a41b0f8c800360200200041086a42083702000b1300200041013602042000418487c9003602000b3400200041e8fcc60036020420004100360200200041146a4102360200200041106a41808dc900360200200041086a42093702000b130020004101360204200041cc8fc9003602000b4301027f230041106b2202240002404108102c22030d001036000b2000420837020420002003360200200242b8173703082000200241086a41081074200241106a24000b130020004101360204200041d093c9003602000b340020004190dac80036020420004100360200200041146a4103360200200041106a41dc94c900360200200041086a420a3702000b02000b2f01017f02404104102c22020d001036000b2000420437020420002002360200410020001076410441002000109f010b810201057f0240024002400240200041086a2802002201450d0020014102742102410021032000280200220421050240034020052802000d01200541046a2105200341016a21032002417c6a22020d000b2001417f6a21030b2003450d0020012003490d01200120036b220541ffffffff03712005470d0220054102742202417f4c0d024104210102402002450d002002102c2201450d040b2001200420034102746a200541027410e9082103200241027621020240200041046a28020041ffffffff0371450d002000280200102e0b20002003360200200041086a2005360200200041046a20023602000b0f0b2003200141dcd8cc001056000b1038000b1036000b9c04030d7f017e017f02400240200241086a2802002203200141086a28020022046a22054101200541014b1b220641ffffffff03712006470d0020064102742205417f4c0d0002400240024020050d00410421070c010b200510322207450d010b20002007360200200041086a2006360200200020054102763602042004450d022006417f6a2108200341027420022802006a417c6a2109200641027420076a417c6a210a4100210b200141086a210c2004210d0240034002400240024002400240024002402004200d200b417f736a220e4d0d002001280200200e4102746a220f280200450d06024020030d00410021000c060b420021104100210020092102200a21050340200d200e4d0d022003200320006a2211417f6a4d0d032006200820006a22114d0d0420052002350200200f3502007e20107c20053502007c22103e02002002417c6a21022005417c6a21052010422088211020032000417f6a22006a450d050c000b0b200e200441ccd7cc00103c000b200e200d41ccd7cc00103c000b2011417f6a200341ccd7cc00103c000b2011200641ccd7cc00103c000b2010a721000b2006200b20036a417f736a220520064f0d02200720054102746a20003602000b200b41016a220b2004460d04200a417c6a210a2008417f6a2108200c280200210d0c000b0b2005200641ecd8cc00103c000b1036000b1038000b0240200141046a28020041ffffffff0371450d002001280200102e0b0bab1006037f017e017f017e0c7f027e23004180026b22022400200141346a2802002103200141386a2802002104200141086a29030021052001280230210620012903002107200241086a41186a200141d4006a290000370300200241086a41106a200141cc006a290000370300200241086a41086a200141c4006a2900003703002002200129003c37030820022005370330200220073703282006200441d8006c22086a21092006210102400240024002402004450d004100210a20024198016a41086a210b20024198016a41106a210c20024198016a41186a210d024002400340200b2006200a6a2201413c6a290200370300200c200141c4006a290200370300200d200141cc006a29020037030020024198016a41206a200141d4006a2802003602002002200141346a29020037039801200141306a280200220e450d02200141286a2903002105200141206a2903002107200241e0016a41186a220f200d290300370300200241e0016a41106a2210200c290300370300200241e0016a41086a2211200b29030037030020022002290398013703e00102400240200720052002290328200241286a41086a29030010820522120d004100210f0c010b200241c0016a41186a200f290300370300200241c0016a41106a2010290300370300200241c0016a41086a2011290300370300200220022903e0013703c0014101210f201221130b200e200e280200417f6a2210360200024020100d00200e41046a22102010280200417f6a221036020020100d00200e102e0b200f0d012008200a41d8006a220a470d000b200921010c020b200241386a41086a220e200241c0016a41086a290300370300200241386a41106a220b200241c0016a41106a290300370300200241386a41186a220c200241c0016a41186a290300370300200220022903c00122053703582002200537033802404124102c2208450d002008200229033837020020082013360220200841186a200c290300370200200841106a200b290300370200200841086a200e290300370200200220093602442002200141d8006a220b3602402002200336023c200220063602382002200241286a360248024002400240200441d8006c41a87f6a200a470d0041012103410121040c010b20024198016a41086a210a20024198016a41106a210c20024198016a41186a210d410121034101210403402002200b220141d8006a220b360240200141306a280200210e200141286a2903002105200141206a2903002107200a2001413c6a290200370300200c200141c4006a290200370300200d200141cc006a29020037030020024198016a41206a200141d4006a2802003602002002200141346a2902003703980102400240200e450d00200241e0016a41186a2210200d290300370300200241e0016a41106a2211200c290300370300200241e0016a41086a2212200a29030037030020022002290398013703e00102400240200720052002280248220f290300200f41086a29030010820522060d004100210f0c010b200241c0016a41186a2010290300370300200241c0016a41106a2011290300370300200241c0016a41086a2012290300370300200220022903e0013703c0014101210f200621130b200e200e280200417f6a2210360200024020100d00200e41046a22102010280200417f6a221036020020100d00200e102e0b200f0d012009200b470d020b200141d8006a210b0c020b200241d8006a41086a200241c0016a41086a2903002205370300200241d8006a41106a200241c0016a41106a2903002207370300200241d8006a41186a200241c0016a41186a2903002214370300200220022903c0012215370358200d2014370300200c2007370300200a20053703002002201537039801024020042003470d00200341016a22012003490d092003410174220e2001200e20014b1b22014104200141044b1bad42247e2205422088a74541027421012005a7210e0240024020030d00200241003602e0010c010b200241043602e801200220083602e0012002200341246c3602e4010b200241c0016a200e2001200241e0016a107d20022802c801210120022802c0014101460d0320022802c4012108200141246e21030b2008200441246c6a2201200229039801370200200c2903002105200d2903002107200a290300211420012013360220200141086a2014370200200141186a2007370200200141106a2005370200200441016a21042002280240220b20022802442209470d000b0b2009200b6b220141d8006d210e02402001450d00200e41d8006c210e200b41306a210103402001280200220a200a280200417f6a36020002402001280200220a2802000d00200a41046a220a200a280200417f6a3602002001280200220a41046a2802000d00200a102e0b200141d8006a2101200e41a87f6a220e0d000b0b0240200228023c2201450d00200141d8006c450d002002280238102e0b2004450d042000200336020420002008360200200041086a20043602002000410c6a2002290308370000200041146a200241086a41086a2903003700002000411c6a200241186a290300370000200041246a200241206a2903003700000c050b2001450d050b1036000b200141d8006a21010b024020092001460d000340200141306a220e280200220a200a280200417f6a360200200141d8006a21010240200e280200220a2802000d00200a41046a220a200a280200417f6a360200200e280200220e41046a2802000d00200e102e0b20092001470d000b0b02402003450d00200341d8006c450d002006102e0b200041003602000c010b200041003602002003450d00200341246c450d002008102e0b20024180026a24000f0b1038000b130020004107360204200041d499c9003602000b13002000410236020420004188a0c9003602000b13002000410736020420004190a1c9003602000b1f0002402000280200450d00200041086a280200450d002000280204102e0b0b940202017f027e230041e0006b2202240002402001450d00200241d4006a410f3602002002411c6a41023602002002420237020c200241a0a7c9003602082002410436024c20024198a7c9003602482002200241c8006a3602182002200241d8006a360250200241086a41b0a7c9001044000b200241c0006a41002903e8f846370300200241386a41002903e0f846370300200241306a41002903d8f846370300200241286a41002903d0f846370300200241206a41002903c8f846370300200241186a41002903c0f846370300200241106a41002903b8f846370300200241002903b0f846370308200241c8006a200241086a1087072002350250210320023502482104200241e0006a240020042003422086840bfd1d02087f047e230041900a6b22022400200242808080808020370214200220013602a4062002200041d4e2cc0020011b3602a0062002200241a0066a360210200241b0066a200241106a10990202400240024020022802b4062203450d00200241bc066a280200210420022802b806210520022802b0062106200241e0026a200241c0066a41e00010e9081a200241b0066a200241106a10ec0120022802b00622070d0102402004450d00200441246c21002003210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b2005450d00200541246c450d002003102e0b200241f0016a200241f0006a41e00010e9081a0c010b200241b8066a280200210820022802b4062109200241f0006a200241e0026a41e00010e9081a200241f0016a200241f0006a41e00010e9081a200241b8056a200241f0016a41e00010e9081a0240024020022802102802040d00200241b0066a200241b8056a41e00010e9081a0c010b02402004450d00200441246c21002003210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402005450d00200541246c450d002003102e0b02402008450d00200841c8036c210020072103034002402003220141e8006a2903004202510d0020012d00004102470d00200141086a280200450d00200141046a280200102e0b200141c8036a210320014198016a109601200041b87c6a22000d000b0b410021032009450d00200941c8036c450d002007102e0b2003450d00200241106a200241b0066a41e00010e9081a200241fc006a2004360200200241f0006a41086a20053602002002200336027420022006360270200241f0006a41106a200241106a41e00010e9082101200241e8016a2008360200200241e4016a2009360200200220073602e001200241f0006a10c4070240024002400240024002402006450d00200241b8056a2006417f6a108c02200241b0066a20022802b805220320022802c005108d0220022d00b0062100200241e0026a41186a2206200241c9066a290000370300200241e0026a41106a200241c1066a290000370300200241e0026a41086a200241b9066a290000370300200220022900b1063703e0020240024020004101460d00200241f0016a41186a420037030020024180026a4200370300200241f8016a4200370300200242003703f0010c010b200241f0016a41186a2006290300370300200241f0016a41106a200241e0026a41106a290300370300200241f0016a41086a200241e0026a41086a290300370300200220022903e0023703f0010b024020022802bc05450d002003102e0b200241f0016a2001412010ec080d0010c507200241f0016a200241f0006a41f00010e9081a2007200841c8036c6a210320022802f001210602400240024020080d00200721000c010b200241b0066a41f0006a21002007210102400340200241b8056a200141e80010e9081a200141e8006a290300210a200241e0026a200141f0006a41d80210e9081a200a4203510d01200241b0066a200241b8056a41e80010e9081a2002200a370398072000200241e0026a41d80210e9081a200241a0066a200241b0066a10c60720022d00a0060d05200141c8036a22012003470d000c030b0b200141c8036a21000b20032000460d002007200841c8036c6a210303402000220141c8036a21000240200141e8006a2903004202510d0020012d00004102470d00200141086a280200450d00200141046a280200102e0b20014198016a108b0220032000470d000b0b02402009450d00200941c8036c450d002007102e0b200241fcc6cb004110108e02200228020421080240200228020022094101470d0041fcc6cb00411010ff010b200241e0026a41186a22014200370300200241e0026a41106a22004200370300200241e0026a41086a22034200370300200242003703e002200241b0066a41d9fcc60041061081022003200241b0066a41086a2207290000370300200220022900b0063703e002200241b0066a41acf2cb00410e10810220012007290000370300200020022900b00637030020022008410020091b3602b006200241e0026a4120200241b0066a410410b2014101200210eb04200142003703002000420037030020034200370300200242003703e002200241b0066a41d9fcc600410610810220032007290000370300200220022900b0063703e002200241b0066a41d4f2cb00410b10810220012007290000370300200020022900b006370300200241b0066a200241e0026a10f20420022903b006210a200241b0066a41106a290300210b20022903b806210c200241b0066a41186a290300210d200241b0066a10a903024020022903b806427f427f200c4200200a42015122011b220a200b420020011b7c220b200b200a541b220a200d420020011b7c220b200b200a541b580d004200410210f1040b200610d90610c707450d02200241b0066a10c8072002200241f0016a410c6a28020022083602a0062002200241b0066a410c6a28020022013602b80520082001470d032008450d0520022802b406210920022802f401210641002103034002400240200620036a22012d00002207200920036a22002d0000470d0002400240024002400240024020070e06000304050102000b200141016a200041016a412010ec080d050c060b200141046a2802002205200041046a280200470d042005450d05200141086a280200200041086a280200470d042001410c6a2802002000410c6a280200470d040c050b2001410c6a28020022052000410c6a280200470d03200141046a280200200041046a280200200510ec080d030c040b200141016a280000200041016a280000470d02200141106a2802002205200041106a280200470d02200141086a280200200041086a280200200510ec080d020c030b200141016a280000200041016a280000470d01200141106a2802002205200041106a280200470d01200141086a280200200041086a280200200510ec080d010c020b200141016a280000200041016a280000470d00200141106a2802002205200041106a280200470d00200141086a280200200041086a280200200510ec08450d010b418ba4cc00411410ef02200241e0026a200110ef0420022802e002220720022802e80210c907024020022802e402450d002007102e0b200241e0026a200010ef0420022802e002220720022802e80210c907024020022802e402450d002007102e0b20012d000020002d00002207470d060b024002400240024002400240024020070e06050203040001050b200141046a2802002207200041046a280200470d0b2007450d05200141086a280200200041086a280200470d0b2001410c6a2802002000410c6a280200470d0b0c050b2001410c6a28020022072000410c6a280200470d0a200141046a280200200041046a280200200710ec080d0a0c040b200141016a280000200041016a280000470d09200141106a2802002207200041106a280200470d09200141086a280200200041086a280200200710ec080d090c030b200141016a280000200041016a280000470d08200141106a2802002207200041106a280200470d08200141086a280200200041086a280200200710ec080d080c020b200141016a280000200041016a280000470d07200141106a2802002207200041106a280200470d07200141086a280200200041086a280200200710ec08450d010c070b200141016a200041016a412010ec080d060b200341246a21032008417f6a22080d000c060b0b418aa1cc00411c41a8a1cc001039000b200241086a20022f00a10620022d00a3064110747210fb05200220022903083703f809200241c4066a4101360200200242013702b406200241c4e2cc003602b006200241043602840a2002200241800a6a3602c0062002200241f8096a3602800a200241b0066a41b8a1cc001044000b41c8a1cc00411e41e8a1cc001039000b200241f4026a4100360200200241f0026a41d4e2cc00360200200242013702e402200241f8a1cc003602e002200241a0066a200241b8056a200241e0026a109207000b4190a2cc00412741b8a2cc001039000b0240200241f0016a41306a2201200241b0066a41306a2200412010ec08450d0041dee8cc00410e10ef022001412010c9072000412010c9070b024020012000412010ec08450d0041c8a2cc00412841f0a2cc001039000b0240200241f0016a41d0006a200241b0066a41d0006a412010ec080d00024020022802bc062200450d0020022802b4062101200041246c210003400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b0240200241b8066a2802002201450d00200141246c450d0020022802b406102e0b024020022802fc012200450d0020022802f4012101200041246c210003400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b0240200241f8016a2802002201450d00200141246c450d0020022802f401102e0b200241900a6a240042010f0b4180a3cc00412441a4a3cc001039000b200241fc006a410f360200200241f4026a4102360200200242023702e402200241a0a7c9003602e00220024104360274200241e4a7c9003602702002200241f0006a3602f0022002200241880a6a360278200241e0026a41b0a7c9001044000b99cc010a0b7f027e047f017e017f097e037f027e087f047e230041f0096b2201240020014100360298042001420437039004024002400240024002400240024002400240024002402000410c6a28020041246c2202450d0020002802042103410421044104210541002106410021070340024020032d00004101470d00200341106a2802002208417f4c0d0c200341086a2802002109200341016a280000210a0240024020080d004101210b0c010b2008102c220b450d0c0b200b2009200810e90821092001200a3602a00520014190096a41086a220b200141b0086a41086a2902003703002001200a3602c004200120012800a3053600c304200120012902b00837039009024020072006470d0020062006470d00200641016a220a2006490d0d20064101742204200a2004200a4b1b220a4104200a41044b1bad42247e220c422088a745410274210a200ca721040240024020060d0020014100360280060c010b200141043602880620012005360280062001200641246c360284060b200141b8056a2004200a20014180066a107d20012802c005210620012802b8054101460d04200120012802bc052204360290042001200641246e2206360294040b2004200741246c6a220741013a000020012802c004210a20012800c3042105200720083602102007200836020c20072009360208200741046a20053600002007200a36000120072001290390093702142007411c6a200b290300370200200120012802980441016a220736029804200421050b200341246a21032002415c6a22020d000b0b200141d8046a22034200370300200141c0046a41106a22064200370300200141c0046a41086a22074200370300200142003703c004200141e0046a41d9fcc60041061081022007200141e0046a41086a290300370300200120012903e0043703c004200141f0046a41ccf6cb0041121081022003200141f0046a41086a290300370300200620012903f004370300200141203602a4052001200141c0046a3602a005200141b0086a200141c0046a412010ed0220012802b00822070d01410221080c020b20060d070c080b20012802b40821042001200141b0086a41086a2802003602bc05200120073602b80520014188046a200141b8056a10ab01200128028c04210a024002402001280288040d0020014180046a200141b8056a10ab012001280280040d0020012802bc0522082001280284042203490d002003417f4c0d090240024020030d00410121020c010b200310322202450d0920012802bc0521080b024020082003490d00200220012802b805200310e9081a20012802bc0522082003490d042001200820036b3602bc05200120012802b80520036a3602b805410121080c020b2002102e0b200141003602980920014201370390092001410a360294052001200141a0056a36029005200120014190096a3602f00420014194066a41013602002001420137028406200141909dc50036028006200120014190056a36029006200141f0046a419cebc00020014180066a103d1a20012802900920012802980910ef020240200128029409450d00200128029009102e0b410221080b2004450d002007102e0b024020084102460d00410121070240200a411e490d0041002107024020034108470d00200229000042f0deb1db968cd9b7f4005121070b200741017321070b02402003450d002002102e0b20070d004200210d20014190096a210e0c050b2001418c066a41002903b8f8463702002001411e36028006200141002903b0f84637028406200141c0046a41186a22074200370300200141d0046a22084200370300200141c0046a41086a22034200370300200142003703c004200141e0046a41d9fcc60041061081022003200141e0046a41086a2202290300370300200120012903e0043703c004200141f0046a41ccf6cb004112108102200641086a220a200141f0046a41086a2204290300370000200620012903f00437000020014100360298092001420137039009411e20014190096a107620014180066a41047220014190096a10e805200141c0046a4120200128029009220920012802980910b2010240200128029409450d002009102e0b200742003703002008420037030020034200370300200142003703c004200141e0046a41d9fcc600410610810220032002290300370300200120012903e0043703c004200141f0046a41c0f7cb004118108102200a2004290300370000200620012903f0043700000240200141c0046a108603220341ff01714102460d002003410171450d004200210c20014190056a210f0c040b200141c0046a41186a4200370300200141c0046a41106a4200370300200141c0046a41086a22034200370300200142003703c004200141e0046a41d9fcc60041061081022003200141e0046a41086a290300370300200120012903e0043703c004200141f0046a41c0f7cb004118108102200641086a200141f0046a41086a290300370000200620012903f004370000200141013a009005200141c0046a412020014190056a410110b201200141e0046a41d9fcc6004106108102200141f0046a41dcf1cb0041071081024120102c2203450d05200142203702bc05200120033602b805200141b8056a200141e0046a41101074200141b8056a200141f0046a4110107420012802c0052208417f4c0d0620012802b805210a0240024020080d00410121030c010b2008102c2203450d060b20014180066a2003200a200810e9082008108b052008ad220c422086200c84210c2001280280062207450d02200141b8066a210e200141a8066a211020014198066a2111034020032102200c211220072103024002402008200129028406220c422088a722074b0d00200a2003200810ec08450d010b200ca7450d032003102e0c030b02402012a7450d002002102e0b200120073602c404200120033602c004200141b0086a2003200710ed020240024020012802b0082202450d0020012802b408210402400240024020012802b80822094104490d002009417c71220b4104460d00200b4108460d00200941746a4110490d00200941646a4110490d00200941546a4110490d00200941446a410f4b0d010b200141003602980920014201370390092001410a360294052001200141c0046a36029005200120014190096a3602a00520014101360294062001420137028406200141909dc50036028006200120014190056a36029006200141a0056a419cebc00020014180066a103d1a20012802900920012802980910ef020240200128029409450d00200128029009102e0b410021090c010b2002280000210f2002280004211320022800082105200241146a2900002114200229000c2115200241c4006a2900002116200241346a2900002117200241246a2900002118200229003c2119200229002c211a200229001c211b410121090b02402004450d002002102e0b2009450d00200820074b0d01200141d4e2cc00200320086a41106a200720086b22024110491b3602900920014100200241706a2204200420024b1b3602940920014180066a20014190096a10930120012d0080064101460d00200e20163703002010201737030020112018370300200120193703b0062001201a3703a0062001201b370390062001201537038006200141003602cc06200120053602c806200120133602c4062001200f3602c00620012014370388062003200720014180066a10c9050b20014180066a20032007108b0520012802800622070d010c040b0b2008200741c4dbc8001056000b2003200841b8b2c0001056000b2012210c200221030b0240200ca7450d002003102e0b024020012802bc05450d00200a102e0b20014180066a10a903200129038806210c20014190056a210f0b200141b0086a41d9fcc600410610810220014190096a419f8dcc00411410810220014180066a41086a200141b0086a41086a220329020037030020014180066a41106a20012903900937030020014180066a41186a20014190096a41086a290300370300200120012902b0083703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00900520014190096a200f41011074200141003a00900520014190096a200f4101107420014180066a4120200128029009220720012802980910b2010240200128029409450d002007102e0b200141c0046a41186a4200370300200141c0046a41106a4200370300200141c0046a41086a22074200370300200142003703c004200141b8056a41a8f8c60041041081022007200141b8056a41086a290000370300200120012900b8053703c004200141b0086a41d48bc500410f108102200641086a2003290000370000200620012900b008370000200141203602a4052001200141c0046a3602a005200141b0086a200141c0046a412010ed0241042103024020012802b0082207450d0020012802b40821082001200141b8086a28020022033602bc05200120073602b805200141003a009005024002402003450d0020012003417f6a3602bc052001200741016a3602b8054103210302400240024020072d00000e020100030b20014180066a200141b8056a10950220012d00900622034103460d01200141e0046a41086a20014180066a41086a290300221237030020014190096a41086a22022012370300200120012800910636028005200120014194066a28000036008305200120012903800637039009200120012802800536029005200120012800830536009305200141f0046a41086a200229030037030020012001290390093703f00420012001280093053600b30520012001280290053602b0050b20014180066a41086a200141f0046a41086a290300370300200120012800b30536008b05200120012802b00536028805200120012903f004370380062001200128028805360290052001200128008b05360093050c020b200120012903e004370390090b200141003602980920014201370390092001410a360294052001200141a0056a36029005200120014190096a3602f00420014194066a41013602002001420137028406200141909dc50036028006200120014190056a36029006200141f0046a419cebc00020014180066a103d1a20012802900920012802980910ef020240200128029409450d00200128029009102e0b410421030b2008450d002007102e0b200141e0046a41086a220820014180066a41086a29030037030020012001290380063703e00420012001280290053602800520012001280093053600830541032107024020034104460d0020014190096a41086a2008290300370300200120012903e0043703900920012001280280053602b00820012001280083053600b308200321070b42c0b6fc9a012117024020074103460d0020014194066a20012800b30836000020014180066a41086a20014190096a41086a290300370300200120012903900937038006200120073a009006200120012802b0083600910620014180066a10ed0442c0f8d3ca0121170b200141d8046a22074200370300200141c0046a41106a22084200370300200141c0046a41086a22034200370300200142003703c004200141e0046a41a8f8c60041041081022003200141e0046a41086a2202290300370300200120012903e0043703c004200141f0046a41d48bc500410f108102200641086a220a200141f0046a41086a2204290300370000200620012903f004370000200141c0046a412010ff01200742003703002008420037030020034200370300200142003703c004200141e0046a41a8f8c600410410810220032002290300370300200120012903e0043703c004200141f0046a418c8bc500410b108102200a2004290300370000200620012903f004370000200141c0046a42014204410210c205200742003703002008420037030020034200370300200142003703c004200141e0046a41a8f8c600410410810220032002290300370300200120012903e0043703c004200141f0046a41d48bc500410f108102200a2004290300370000200620012903f004370000200141c0046a42014204410210c205200141e0046a418ef9c0004110108102200141f0046a41fbafc90041061081024120102c2203450d012001422037029409200120033602900920014190096a200141e0046a4110107420014190096a200141f0046a411010742001280298092208417f4c0d0220012802900921054101210202402008450d002008102c2202450d020b427f200c4280c2d72f7c22122012200c541b211920022005200810e9081a20014198066a21132008210a20082107034020014180066a20022007108b05024002400240024002402001280280062203450d002001280284062104024020012802880622072008490d0020052003200810ec08450d020b2004450d002003102e0b0240200a450d002002102e0b0240200128029409450d002005102e0b20014180066a10df04200129038806210c200141c0046a41a5fec600411a108102200141b8056a419f8dcc00411410810220014180066a41086a2207200141c0046a41086a220829000037030020014180066a41106a220220012900b80537030020014180066a41186a220a200141b8056a41086a2204290000370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220920012802980910b201200141b0086a41106a21030240200128029409450d002009102e0b200141c0046a41f4d8c7004104108102200141b8056a419f8dcc004114108102200320012900b805370000200341086a20042900003700002007200829000037030020022003290300370300200a200141b0086a41186a290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220720012802980910b2010240200128029409450d002007102e0b200141c0046a419dfec6004108108102200141b0086a419f8dcc00411410810220014190096a41086a2207200141c0046a41086a29000037030020014190096a41106a220820012900b008370300200141a8096a2202200141b0086a41086a220a290000370300200120012900c0043703900920014100360288062001420137038006200141033b01b00820014180066a200141b0086a41021074200141003a00b00820014180066a200141b0086a41011074200141003a00b00820014180066a200141b0086a4101107420014190096a4120200128028006220420012802880610b2010240200128028406450d002004102e0b200141b8056a4195fec6004108108102200141b0086a419f8dcc0041141081022007200141b8056a41086a290000370300200820012900b0083703002002200a290000370300200120012900b8053703900920014100360288062001420137038006200141033b01b00820014180066a200141b0086a41021074200141003a00b00820014180066a200141b0086a41011074200141003a00b00820014180066a200141b0086a4101107420014190096a4120200128028006220720012802880610b2010240200128028406450d002007102e0b200141e0046a4190fec6004105108102200141f0046a419f8dcc004114108102200141c0046a41086a2207200141e0046a41086a290300370300200141c0046a41106a20012903f004370300200141c0046a41186a200141f0046a41086a290300370300200120012903e0043703c00420014100360288062001420137038006200141033b01900920014180066a20014190096a41021074200141003a00900920014180066a20014190096a41011074200141003a00900920014180066a20014190096a41011074200141c0046a4120200128028006220820012802880610b2010240200128028406450d002008102e0b200141c0046a4188fec6004108108102200141b8056a419f8dcc004114108102200141b0086a41086a2007290000370300200141b0086a41106a20012900b805370300200141b0086a41186a200141b8056a41086a290000370300200120012900c0043703b00820014100360288062001420137038006200141033b01900920014180066a20014190096a41021074200141003a00900920014180066a20014190096a41011074200141003a00900920014180066a20014190096a41011074200141b0086a4120200128028006220720012802880610b2010240200128028406450d002007102e0b200141c0046a4181fec6004107108102200141b0086a419f8dcc00411410810220014180066a41086a2207200141c0046a41086a29000037030020014180066a41106a220820012900b00837030020014180066a41186a2202200141b0086a41086a220a290000370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00900520014190096a200f41011074200141003a00900520014190096a200f4101107420014180066a4120200128029009220420012802980910b2010240200128029409450d002004102e0b200141b8056a41bcdbc8004107108102200141b0086a419f8dcc004114108102200620012900b008370000200641086a200a2900003700002007200141b8056a41086a2900003703002008200141c0046a41106a2903003703002002200141c0046a41186a290300370300200120012900b8053703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220720012802980910b2010240200128029409450d002007102e0b20014180066a41106a2108200141e0046a41b6d1cc004106108102200141f0046a419f8dcc004114108102200320012903f004370000200341086a200141f0046a41086a29030037000020014180066a41086a200141e0046a41086a29030037030020014180066a41106a2207200141b0086a41106a29030037030020014180066a41186a220a200141b0086a41186a290300370300200120012903e0043703800620014100360298092001420137039009200141003b01b00820014190096a200141b0086a41021074200141083a00b00820014190096a200141b0086a410110742001411e3a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220220012802980910b2010240200128029409450d002002102e0b20014180066a41106a2102200141c0046a41bad7c7004108108102200141b8056a419f8dcc004114108102200820012900b805370000200841086a200141b8056a41086a29000037000020014190096a41086a200141c0046a41086a29000037030020014190096a41106a200729030037030020014190096a41186a200a290300370300200120012900c0043703900920014100360288062001420137038006200141033b01b00820014180066a200141b0086a41021074200141003a00b00820014180066a200141b0086a41011074200141003a00b00820014180066a200141b0086a4101107420014190096a4120200128028006220720012802880610b2010240200128028406450d002007102e0b20014190096a41106a2107200141b8056a41eefdc6004113108102200141b0086a419f8dcc004114108102200220012900b008370000200241086a200141b0086a41086a2202290000370000200141c0046a41086a200141b8056a41086a290000370300200141c0046a41106a20014180066a41106a290300370300200141c0046a41186a20014180066a41186a290300370300200120012900b8053703c00420014100360288062001420137038006200141033b01900920014180066a20014190096a41021074200141003a00900520014180066a200f41011074200141003a00900520014180066a200f41011074200141c0046a4120200128028006220a20012802880610b2010240200128028406450d00200a102e0b200141e0046a41ddfdc6004111108102200141f0046a419f8dcc004114108102200720012903f004370000200741086a200141f0046a41086a2903003700002002200141e0046a41086a290300370300200141b0086a41106a20014190096a41106a290300370300200141b0086a41186a20014190096a41186a290300370300200120012903e0043703b00820014100360288062001420137038006200141033b01900920014180066a20014190096a41021074200141003a00900920014180066a20014190096a41011074200141003a00900920014180066a20014190096a41011074200141b0086a4120200128028006220220012802880610b2010240200128028406450d002002102e0b200141c0046a41cbfdc6004112108102200141b8056a419f8dcc004114108102200320012900b805370000200341086a2202200141b8056a41086a220a29000037000020014180066a41086a2204200141c0046a41086a220929000037030020014180066a41106a220b200141b0086a41106a220529030037030020014180066a41186a2213200141b0086a41186a220e290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009221020012802980910b2010240200128029409450d002010102e0b200141c0046a41c4fdc6004107108102200141b8056a419f8dcc004114108102200320012900b8053700002002200a29000037000020042009290000370300200b20052903003703002013200e290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220220012802980910b2010240200128029409450d002002102e0b200141e0046a41de80ca004109108102200141f0046a419f8dcc004114108102200820012903f004370000200841086a200141f0046a41086a29030037000020014190096a41086a200141e0046a41086a29030037030020014190096a41106a220220014180066a41106a29030037030020014190096a41186a220a20014180066a41186a290300370300200120012903e0043703900920014100360288062001420137038006200141033b01b00820014180066a200141b0086a41021074200141003a00b00820014180066a200141b0086a41011074200141003a00b00820014180066a200141b0086a4101107420014190096a4120200128028006220420012802880610b2010240200128028406450d002004102e0b200141c0046a41b2fdc6004112108102200141b8056a419f8dcc004114108102200720012900b805370000200741086a200141b8056a41086a290000370000200141b0086a41086a200141c0046a41086a290000370300200141b0086a41106a2002290300370300200141b0086a41186a200a290300370300200120012900c0043703b00820014100360288062001420137038006200141033b01900920014180066a20014190096a41021074200141003a00900920014180066a20014190096a41011074200141003a00900920014180066a20014190096a41011074200141b0086a4120200128028006220220012802880610b2010240200128028406450d002002102e0b200141e0046a41bed8c8004108108102200141f0046a419f8dcc004114108102200320012903f004370000200341086a2202200141f0046a41086a220a29030037000020014180066a41086a2204200141e0046a41086a220929030037030020014180066a41106a220b200141b0086a41106a220529030037030020014180066a41186a2213200141b0086a41186a220e290300370300200120012903e0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009221020012802980910b2010240200128029409450d002010102e0b200141e0046a41abfdc6004107108102200141f0046a419f8dcc004114108102200320012903f0043700002002200a29030037000020042009290300370300200b20052903003703002013200e290300370300200120012903e0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220220012802980910b2010240200128029409450d002002102e0b200141c0046a41a081ca004107108102200141b8056a419f8dcc004114108102200820012900b805370000200841086a200141b8056a41086a29000037000020014190096a41086a200141c0046a41086a29000037030020014190096a41106a220820014180066a41106a29030037030020014190096a41186a220220014180066a41186a290300370300200120012900c0043703900920014100360288062001420137038006200141033b01b00820014180066a200141b0086a41021074200141003a00b00820014180066a200141b0086a41011074200141003a00b00820014180066a200141b0086a4101107420014190096a4120200128028006220a20012802880610b2010240200128028406450d00200a102e0b200141e0046a41a1fdc600410a108102200141f0046a419f8dcc004114108102200720012903f004370000200741086a200141f0046a41086a290300370000200141b0086a41086a200141e0046a41086a290300370300200141b0086a41106a2008290300370300200141b0086a41186a2002290300370300200120012903e0043703b00820014100360288062001420137038006200141033b01900920014180066a20014190096a41021074200141003a00900920014180066a20014190096a41011074200141003a00900920014180066a20014190096a41011074200141b0086a4120200128028006220820012802880610b2010240200128028406450d002008102e0b200141c0046a4199fdc6004108108102200141b8056a419f8dcc004114108102200320012900b805370000200341086a200141b8056a41086a29000037000020014180066a41086a200141c0046a41086a29000037030020014180066a41106a200141b0086a41106a29030037030020014180066a41186a200141b0086a41186a290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220820012802980910b2010240200128029409450d002008102e0b20014190096a41186a420037030020014190096a41106a420037030020014190096a41086a220842003703002001420037039009200141e0046a4192fdc60041071081022008200141e0046a41086a290300370300200120012903e00437039009200141f0046a419cfdca00410e108102200741086a200141f0046a41086a290300370000200720012903f004370000200141203602c404200120014190096a3602c004200141b8056a20014190096a412010ed0220012802b80522080d01410621070c020b0240200a450d002002102e0b20014180066a2003200710e90220012802a0062209450d022013290300210c20014180066a41086a29030021152001290390062112200129038006211420012903a806211b20012802a406210b20014100200720086b220241786a220a200a20024b1b3602b408200141d4e2cc00200320086a41086a20024108491b3602b00820014180066a200141b0086a109301024020012d0080064101470d00200321022004210a200b41ffffff3f71450d042009102e0c030b420021184280e8eda1ba01211a024020124280cab5ee0185200c84500d0020124280e8eda1ba0185200c84500d002012211a200c21180b201320183703002001201a3703900620012014370380062001201b3703a806200120093602a00620012015370388062001200b3602a4062003200720014180066a10b905200b41ffffff3f71450d022009102e0c020b200141c0056a280200210220012802bc05210a41002107200141003a00a005024002402002450d000240024002400240024020082d00000e06060001020304050b410121070c050b410221070c040b410321070c030b410421070c020b410521070c010b200141003602b808200142013703b0082001410a360294052001200141c0046a360290052001200141b0086a3602a00520014194066a41013602002001420137028406200141909dc50036028006200120014190056a36029006200141a0056a419cebc00020014180066a103d1a20012802b00820012802b80810ef02024020012802b408450d0020012802b008102e0b410621070b200a450d002008102e0b42c0acb7a20b2112024020074104470d00200141c8086a22084200370300200141c0086a22024200370300200141b0086a41086a22074200370300200142003703b008200141c0046a4192fdc60041071081022007200141c0046a41086a220a290000370300200120012900c0043703b008200141b8056a41dd8cc5004112108102200341086a2204200141b8056a41086a2209290000370000200320012900b805370000200141b0086a412010ff01200842003703002002420037030020074200370300200142003703b008200141c0046a4192fdc60041071081022007200a290000370300200120012900c0043703b008200141b8056a419c8dc500411210810220042009290000370000200320012900b805370000200141b0086a412010ff01200842003703002002420037030020074200370300200142003703b008200141c0046a4192fdc60041071081022007200a290000370300200120012900c0043703b008200141b8056a41fa8cc500410d10810220042009290000370000200320012900b805370000200141b0086a412010ff01200842003703002002420037030020074200370300200142003703b008200141c0046a4192fdc60041071081022007200a290000370300200120012900c0043703b008200141b8056a41ef8cc500410b10810220042009290000370000200320012900b805370000200141b0086a412010ff01200842003703002002420037030020074200370300200142003703b008200141c0046a4192fdc60041071081022007200a290000370300200120012900c0043703b008200141b8056a41cc8cc500411110810220042009290000370000200320012900b805370000200141b0086a412010ff01200842003703002002420037030020074200370300200142003703b008200141c0046a4192fdc60041071081022007200a290000370300200120012900c0043703b008200141b8056a41878dc500411510810220042009290000370000200320012900b805370000200141b0086a412010ff01200842003703002002420037030020074200370300200142003703b008200141c0046a4192fdc60041071081022007200a290000370300200120012900c0043703b008200141b8056a419cfdca00410e10810220042009290000370000200320012900b80537000020014100360288062001420137038006200141053a00a00520014180066a200141a0056a41011074200141b0086a4120200128028006220720012802880610b2010240200128028406450d002007102e0b42808aa6e40d21120b200141c0046a4192fdc6004107108102200141b8056a419f8dcc004114108102200320012900b805370000200341086a2207200141b8056a41086a220829000037000020014180066a41086a2202200141c0046a41086a220a29000037030020014180066a41106a2204200141b0086a41106a220929030037030020014180066a41186a220b200141b0086a41186a2205290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00900520014190096a200f41011074200141003a00900520014190096a200f4101107420014180066a4120200128029009221320012802980910b2010240200128029409450d002013102e0b200141c0046a4190dac800410a108102200141b8056a419f8dcc004114108102200320012900b805370000200720082900003700002002200a29000037030020042009290300370300200b2005290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220720012802980910b2010240200128029409450d002007102e0b200141c0046a4180fdc6004112108102200141b8056a419f8dcc004114108102200320012900b805370000200341086a2207200141b8056a41086a220829000037000020014180066a41086a2202200141c0046a41086a220a29000037030020014180066a41106a2204200141b0086a41106a220929030037030020014180066a41186a220b200141b0086a41186a2205290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009221320012802980910b2010240200128029409450d002013102e0b2017200c7c210c200141c0046a41f8fcc6004108108102200141b8056a419f8dcc004114108102200320012900b805370000200720082900003700002002200a29000037030020042009290300370300200b2005290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220720012802980910b2010240200128029409450d002007102e0b200c2017542107200141c0046a41f1fcc6004107108102200141b8056a419f8dcc004114108102200320012900b805370000200341086a2208200141b8056a41086a220229000037000020014180066a41086a220a200141c0046a41086a220429000037030020014180066a41106a2209200141b0086a41106a220b29030037030020014180066a41186a2205200141b0086a41186a2213290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220f20012802980910b2010240200128029409450d00200f102e0b427f200c20071b210c200141c0046a41e8fcc6004109108102200141b8056a419f8dcc004114108102200320012900b80537000020082002290000370000200a20042900003703002009200b29030037030020052013290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220720012802980910b2010240200128029409450d002007102e0b2019200c7c210c200141c0046a41a8f8c6004104108102200141b8056a419f8dcc004114108102200320012900b805370000200341086a2207200141b8056a41086a220829000037000020014180066a41086a2202200141c0046a41086a220a29000037030020014180066a41106a2204200141b0086a41106a220929030037030020014180066a41186a220b200141b0086a41186a2205290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009221320012802980910b2010240200128029409450d002013102e0b200c2019542113200141c0046a41dffcc6004109108102200141b8056a419f8dcc004114108102200320012900b805370000200720082900003700002002200a29000037030020042009290300370300200b2005290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00b00820014190096a200141b0086a41011074200141003a00b00820014190096a200141b0086a4101107420014180066a4120200128029009220720012802980910b2010240200128029409450d002007102e0b427f200c20131b210c200141c0046a41f4c2cc004118108102200141b8056a419f8dcc004114108102200320012900b805370000200341086a200141b8056a41086a29000037000020014180066a41086a200141c0046a41086a29000037030020014180066a41106a200141b0086a41106a29030037030020014180066a41186a200141b0086a41186a290300370300200120012900c0043703800620014100360298092001420137039009200141033b01b00820014190096a200141b0086a41021074200141003a00a00520014190096a200141a0056a41011074200141003a00a00520014190096a200141a0056a4101107420014180066a4120200128029009220320012802980910b2010240200128029409450d002003102e0b427f200c20127c22122012200c541b210d20014190096a210e0c020b200321022004210a0c000b0b4102200110eb04200141003602800641fcc6cb00411020014180066a410410b201200141c0046a41186a22074200370300200141c0046a41106a22084200370300200141c0046a41086a22034200370300200142003703c004200141e0046a41d9fcc60041061081022003200141e0046a41086a2202290300370300200120012903e0043703c004200141f0046a4180f4cb004106108102200641086a220a200141f0046a41086a2209290300370000200620012903f00437000020012000280200220436028006200141c0046a412020014180066a410410b20120014190046a10ee04200041106a220b10f0042004417f6a200b10a407200742003703002008420037030020034200370300200142003703c004200141e0046a41d9fcc600410610810220032002290300370300200120012903e0043703c004200141f0046a41d4f2cb00410b108102200a2009290300370000200620012903f004370000200141c0046a412010ff01200742003703002008420037030020034200370300200142003703c004200141e0046a41d9fcc600410610810220032002290300370300200120012903e0043703c004200141f0046a41e0f4cb004106108102200a2009290300370000200620012903f004370000200141c0046a412010ff01200742003703002008420037030020034200370300200142003703c004200141e0046a41d9fcc600410610810220032002290300370300200120012903e0043703c004200141f0046a41a4f5cb00410a108102200a2009290300370000200620012903f004370000200141c0046a412010ff01200742003703002008420037030020034200370300200142003703c004200141e0046a41d9fcc600410610810220032002290300370300200120012903e0043703c004200141f0046a41c0f5cb00410b108102200a2009290300370000200620012903f004370000200141c0046a412010890320014190096a41186a220b420037030020014190096a41106a2200420037030020014190096a41086a220542003703002001420037039009200141c0046a4192fdc600410710810220052003290000370300200120012900c00437039009200141b0086a4194adc600410a108102200b200141b0086a41086a2213290000370300200020012900b008370300200141f8036a200e4120108e0220012802fc03210f20012802f8032110200b420037030020004200370300200542003703002001420037039009200141c0046a4192fdc600410710810220052003290000370300200120012900c00437039009200141b0086a4198b7c6004115108102200b2013290000370300200020012900b008370300200141f0036a200e4120108e0220012802f403210b20012802f003210520014180066a200f410020101b109503200141e8036a2001280280062210200128028806108e0220012802ec03211320012802e803210f0240200128028406450d002010102e0b200742003703002008420037030020034200370300200142003703c004200141e0046a41a8f8c600410410810220032002290300370300200120012903e0043703c004200141f0046a41fa8bc500410a108102200a2009290300370000200620012903f004370000200141d8036a200141c0046a108503200141c8036a20012903e003420020012802d8031b420042e012420010e808024002400240024020012903d00350450d0020012903c803210c20014198066a2207420037030020014190066a2209420037030020014180066a41086a220342003703002001420037038006200141b8056a41a8f8c60041041081022003200141b8056a41086a2208290000370300200120012900b80537038006200141b0086a41e38bc500410b1081022007200141b0086a41086a2202290000370300200920012900b008370300200141b8036a20014180066a108503200c20012903c003420020012802b8031b7c2212200c540d012007420037030020094200370300200342003703002001420037038006200141b8056a41a8f8c600410410810220032008290000370300200120012900b80537038006200141b0086a41c98bc500410b108102200941086a2002290000370000200920012900b008370000200141a8036a20014180066a1085034100417f2004417f41004100417f2004427f201242e0127c220c200c2012541b221220012903b003420020012802a8031b7d220ca7417f200c428080808010541b6a220320032004491b200c2012561b220320046b2207200720034b1b22034100410041064100200b410020051b220720134100200f1b6b2208200820074b1b6b2207200741064b1b2207417f6a2208200820074b1b41e0126c6a220720072003491b6a220320032004491b220320046b2207200720034b1b2108200141a0036a10f40442a082c0dd00211c0240024020012d00a0032202417e6a22074102200741ff01714102491b41ff01710e020001050b200320044d0d04200841d8044b0d040c030b200320044d0d03200841d904490d020c030b41e8b2c40041fa0041e4b3c400105d000b41e8b2c40041fa0041f4b3c400105d000b4290cad9c400210c42002112024002400240200241ff01714103460d0020014180066a410141ffff0310ef052001280280064101460d0320014198066a2208290300210c20014190066a220328020021072001418c066a2213280200210a20014180066a41086a2202280200210b20014180066a4101417f10e9052001280280064101460d022008290300211220032802002105201328020021132002280200210f2008420037030020034200370300200242003703002001420037038006200141b0086a4192fdc60041071081022002200141b0086a41086a2210290000370300200120012900b00837038006200141b0086a41b4aac600410e10810220082010290000370300200320012900b00837030020014198036a20014180066a4120108e02200741ffff034b0d01200128029c0341002001280298031b211d200120073602bc05200120053602b80520014198066a2210420037030020014180066a41106a2211420037030020014180066a41086a220842003703002001420037038006200141b0086a41a5fec600411a1081022008200141b0086a41086a2202290000370300200120012900b00837038006200141b0086a41ccc5c8004110108102200341086a221e2002290000370000200320012900b00837000020014100360298092001420137039009200141b8056a20014190096a109102200141b8056a41047220014190096a10910220014180066a4120200128029009221f20012802980910b2010240200128029409450d00201f102e0b2010420037030020114200370300200842003703002001420037038006200141b0086a41a5fec600411a10810220082002290000370300200120012900b00837038006200141b0086a4194c5c800410e108102201e2002290000370000200320012900b0083700002001201d3602900920014180066a412020014190096a410410b201200141a4096a200736020020014190096a41106a200a3602002001200b36029c09200120053602980920012013360294092001200f360290092010420037030020114200370300200842003703002001420037038006200141b0086a41a5fec600411a10810220082002290000370300200120012900b00837038006200141b0086a41c8c4c8004108108102201e2002290000370000200320012900b008370000200141003602b808200142013703b00820014190096a200141b0086a10b6012007200141b0086a107602402007450d0020074105742107200b21030340200141b0086a200341201074200341206a2103200741606a22070d000b0b20014180066a412020012802b008220320012802b80810b201024020012802b408450d002003102e0b02402005450d00200541386c2107200f412c6a210303400240200328020041ffffff3f71450d002003417c6a280200102e0b200341386a2103200741486a22070d000b0b02402013450d00201341386c450d00200f102e0b0240200a41ffffff3f71450d00200b102e0b427f427f200c20127c22122012200c541b220c42c0b6fc9a017c22122012200c541b21124290bad8ce02210c0b4101200410ec04200141d8046a4200370300200141d0046a4200370300200141c0046a41086a22034200370300200142003703c004200141e0046a41a5fec600411a1081022003200141e0046a41086a290300370300200120012903e0043703c004200141f0046a4180c3c8004105108102200641086a200141f0046a41086a290300370000200620012903f00437000020014190036a200141c0046a4120108e0220014180066a41086a20012802940341012001280290031b360200200141053a008406200141173a008006427f200c427f20124280c2d72f7c221520152012541b7c22122012200c541b211c20014180066a10fe010c020b02402005450d00200541386c2107200f412c6a210303400240200328020041ffffff3f71450d002003417c6a280200102e0b200341386a2103200741486a22070d000b0b2013450d00201341386c450d00200f102e0b200a41ffffff3f71450d00200b102e0b42002120420021210240200441808c15700d00200142f0f2bda1a7ee9cb9f9003703800620014190096a20014180066a10cd02200141b0086a20014190096a10c80220014180066a20012802b008220a20012802b80810c9024100210341002107410021084100210202402001290380064201520d0020014190066a28020021072001280288062102200128028c06210820012802940621030b024020012802b408450d00200a102e0b200142002003ad4220862007ad8422122008ad4220862002ad84220c4280c8afa02554ad7d2215200c4280b8d0df5a7c2214200c562015201256200c42ffc7afa025561b22031b220c3703980520014200201420031b22123703900520014180066a41186a200c37030020014180066a41106a201237030020014180066a41086a221341013a00002001410e3a00800620014180066a10fe01200142f0f2bda1a7ee9cb9f90037038006200141b8056a20014180066a10cd0241002110200141003a008005200142003703a805200142003703a00520014190096a41186a2222420037030020014190096a41106a2223420037030020014190096a41086a220a42003703002001420037039009200141c0046a41bad7c7004108108102200a200141c0046a41086a2224290000370300200120012900c00437039009200141b0086a4194ccc2004109108102200041086a2225200141b0086a41086a2226290000370000200020012900b00837000020014180066a200e109b03200129028406220c4200200128028006221d1b221b42ffffffff0f832118200c422088211a201d4104201d1b21110240201b422088a7220b450d0020014180066a41096a2127200141d0096a211f200141b0096a21284100211e200141b8066a21294100211041002107024003400240024002402010450d00201120074102746a210320112007201e6a4102746a21080340200141c0046a2003280200220510d60320014180066a20012802c004220f20012802c80410b805200129038006210c20014190096a201341e00010e9081a410021020240200c4201520d00200141b0086a20014190096a41e00010e9081a410121020b024020012802c404450d00200f102e0b2002450d0320014190096a200141b0086a41e00010e9081a200129039005221520012903900922145420014190056a41086a290300220c200a290300221254200c2012511b450d02200141013a00800520082003280200360200200341046a2103200841046a2108200741016a2207200b490d000c050b0b201120074102746a21030340200141c0046a2003280200220510d60320014180066a20012802c004220220012802c80410b805200129038006210c20014190096a201341e00010e9081a410021080240200c4201520d00200141b0086a20014190096a41e00010e9081a410121080b024020012802c404450d002002102e0b2008450d0220014190096a200141b0086a41e00010e9081a200129039005221520012903900922145a20014190056a41086a290300220c200a29030022125a200c2012511b0d01200341046a2103200141013a008005200741016a2207200b490d000b410021100c040b2001201520147d370390052001200c20127d2015201454ad7d3703980520014180066a200510d603200128028006220320012802880610ff010240200128028406450d002003102e0b20014180036a202820012903a009202229030010fb01200141f0026a201f200129039009200a29030010fd01200141a0056a41086a2203427f2003290300220c200141f0026a41086a2903007c20012903a005221220012903f0027c22152012542203ad7c221220032012200c542012200c511b22031b3703002001427f201520031b3703a005200129039009210c2029200a2903003703002027201f290000370000202741086a201f41086a290000370000202741106a201f41106a290000370000202741186a201f41186a2900003700002001200c3703b006200141023a0088062001410e3a008006200120053602ac0620014180066a10fe010b201e417f6a211e201041016a2110200741016a2207200b490d000b0b024020100d00410021100c010b2011200720106b4102746a201120074102746a200b20076b41027410ea081a0b201a4200201d1b210c200120113602800620012018200b20106bad42208684370284062022420037030020234200370300200a42003703002001420037039009200141c0046a41bad7c7004108108102200a2024290000370300200120012900c00437039009200141b0086a4194ccc200410910810220252026290000370000200020012900b008370000200e20014180066a10c7050240201b42ffffffff0383500d002011102e0b200120014180056a3602b0082001200141a0056a3602b005200120014190056a36028805200141d8046a22004200370300200141d0046a220e4200370300200141c0046a41086a22134200370300200142003703c004200141e0046a41bad7c70041081081022013200141e0046a41086a2210290300370300200120012903e0043703c004200141f0046a41c0dac000410f108102200641086a2211200141f0046a41086a221e290300370000200620012903f004370000200c42f89fb81d7e200c42c0d1e1237e7c2115200c4280c6868f017e211420014180066a200141c0046a109b03200129028406420020012802800622031b221242ffffffff0f83211b2003410420031b2105024002402012422088220ca7220a0d004100210b0c010b4100210f4100210b410021070240034002400240200b450d00200520074102746a210320052007200f6a4102746a21080340200120032802002202360290092001200141b0086a36028c06200120014190096a360288062001200141b0056a36028406200120014188056a36028006200220014180066a10f801450d0220082003280200360200200341046a2103200841046a2108200741016a2207200a490d000c040b0b200520074102746a21030340200120032802002208360290092001200141b0086a36028c06200120014190096a360288062001200141b0056a36028406200120014188056a36028006200820014180066a10f801450d01200341046a2103200741016a2207200a490d000b4100210b0c030b200f417f6a210f200b41016a210b200741016a2207200a490d000b0b0240200b0d004100210b0c010b20052007200b6b4102746a200520074102746a200a20076b41027410ea081a0b201520147c211520012005360280062001201b200a200b6bad422086843702840620004200370300200e420037030020134200370300200142003703c004200141e0046a41bad7c700410810810220132010290300370300200120012903e0043703c004200141f0046a41c0dac000410f1081022011201e290300370000200620012903f004370000200141c0046a20014180066a10c7050240201242ffffffff0383500d002005102e0b201542f8a8df8c017c2115200c42c0b6fc1d7e200c42c0d1e1237e7c200c4280c6868f017e7c2114024020012d0080050d0042002117200141e0026a200129039005221220014190056a41086a2203290300220c42c0843d420010e608200141d0026a2012200c42c0843d420010e708200141c0026a20012903d002200141d0026a41086a2903004290ce00420010e8082003200c200c200141c0026a41086a29030020012903c002221b20012903e002221842e40080a720184290ce007e42c0843d8242a0c21e566aad7c2218201b54ad7c221b2018201256201b200c56201b200c511b22071b221b7d20122012201820071b220c54ad7d37030020012012200c7d3703900502400240200c201b844200520d00200142003703880620014200370380064200211942002112420021180c010b200141d8046a22084200370300200141c0046a41106a22024200370300200141c0046a41086a22034200370300200142003703c004200141e0046a41f8fcc60041081081022003200141e0046a41086a220a290300370300200120012903e0043703c004200141f0046a41a8aac800410d108102200641086a220b200141f0046a41086a2205290300370000200620012903f004370000200141a8026a200141c0046a412010f802200141a8026a41106a290300211220012903b002211820012802a8022107200842003703002002420037030020034200370300200142003703c004200141e0046a41f8fcc60041081081022003200a290300370300200120012903e0043703c004200141f0046a41a8aac800410d108102200b2005290300370000200620012903f004370000200142002012420020071b2212201b7d2018420020071b2218200c54ad7d221a2018200c7d2217201856201a201256201a2012511b22031b3703880620014200201720031b37038006200141c0046a412020014180066a411010b2012001201b370388062001200c370380062012201b20031b21192018200c20031b211720014180066a109803200129038806211820012903800621120b200141a8056a2203427f2003290300221a20197c20012903a005221920177c22162019542203ad7c221720032017201a542017201a511b22031b3703002001427f201620031b3703a005200120123703800620012018370388060240024020122018844200520d00200120014180066a3602900920014190096a10cc020c010b20012018370388062001201237038006200120014180066a3602900920014190096a10cc020b20014198066a201b37030020014190066a200c37030020014188066a41043a00002001410e3a00800620014180066a10fe010b201420157c211520014190096a200141b8056a20012903a005220c200141a0056a41086a2903002212410210fe060240024002402001280290090d0020014180066a41106a20014190096a41106a290300221b20127d2001290398092214200c54ad7d2012201b7d200c201454ad7d2014200c56201b201256201b2012511b22031b37030020012014200c7d200c20147d20031b3703880620012003ad3703800620014180066a41086a210720030d01200120073602b008200141b0086a10ce020c020b419dccc20041ca0010ef0220012012370388062001200c37038006200120014180066a3602900920014190096a10ce020c010b200120073602b008200141b0086a10cc020b201542c0b2cd3b7c2121200129039005210c20014198066a20014190056a41086a29030037030020014190066a200c37030020014180066a41086a41053a00002001410e3a00800620014180066a10fe010b0240200441c09306700d0010f70221200b20014180066a10a903200129038806212a42002112024020044180ce18700d0020014198066a420037030020014190066a420037030020014180066a41086a220342003703002001420037038006200141b8056a41de80ca0041091081022003200141b8056a41086a290000370300200120012900b80537038006200141b0086a41a8fbca004115108102200941086a200141b0086a41086a290000370000200920012900b0083700000240024020014180066a108603220341ff01714102460d0020014180066a412010ff012003410171450d0020014180066a2004109008024020012d0080064106460d0020014190096a20041096080c020b200141063a0090090c010b20014180066a2004109608024020012d0080064106460d0020014190096a20041090080c010b200141063a0090090b0240024020012d0090094106460d0020014180066a41131093080c010b200141063a0080060b202a21120b20014198066a2207420037030020014190066a220842003703004108210a20014180066a41086a220342003703002001420037038006200141b8056a41de80ca0041091081022003200141b8056a41086a2202290000370300200120012900b80537038006200141b0086a41f4f8ca00410d108102200941086a220b200141b0086a41086a2205290000370000200920012900b008370000200141a0026a20014180066a4120108e0220012802a402211320012802a002210f2007420037030020084200370300200342003703002001420037038006200141b8056a41de80ca00410910810220032002290000370300200120012900b80537038006200141b0086a41ccf8ca00410f108102200b2005290000370000200920012900b00837000020014198026a20014180066a4120108e02200128029c0221032001280298022107200120043602f00420012003410020071b22003602a405200120134100200f1b220e3602a0052001200141f0046a3602a80520014180066a200141a0056a200141a0056a200141a0056a41086a1088050240024020012d00e00622034103460d0020014190096a20014180066a41e00010e9081a200120014180066a41e4006a28000036008b05200120012800e1063602880541e800102c220a450d02200a20014190096a41e00010e908220720033a00602007200128028805360061200741e4006a200128008b05360000200141c0046a41086a220b200141a0056a41086a280200360200200120012903a0053703c00420014180066a200141c0046a200141c0046a200b108805024020012d00e00622094103470d0041012102410121070c020b41c9012108200141e1066a220541036a211341012102410121070240034020014190096a20014180066a41e00010e9081a200120132800003600b305200120052800003602b00520014180066a20014190096a41e00010e9081a200120012800b30536009305200120012802b00536029005024020072002470d00200241016a22032002490d062002410174220f2003200f20034b1b22034104200341044b1bad42e8007e220c422088a7454103742103200ca7210f0240024020020d00200141003602b0080c010b200141083602b8082001200a3602b0082001200241e8006c3602b4080b200141b8056a200f2003200141b0086a107d20012802c005210320012802b8054101460d0220012802bc05210a200341e8006e21020b200a20086a2203419f7f6a20014180066a41e00010e9081a2003417f6a20093a00002003200128029005360000200341036a20012800930536000020014180066a200141c0046a200141c0046a200b108805200841e8006a2108200741016a210720012d00e00622094103470d000c030b0b2003450d030c020b41002102410021070b427f41002000200e6b2203200320004b1bad220c428899d2027e200c42c0f0f50b7e7c20127c42d0f4c53f7c220c200c2012541b210c02402007450d00200a280200210920014180066a200a41046a41dc0010e9081a2001200a41e1006a280000360280052001200a41e4006a28000036008305200a41e0006a2d000022054103460d00200a200741e8006c6a210f200141c8096a211320014180066a41086a212220014180066a4101722127200141b0086a41046a210020014180066a41096a211e200141e9096a220e41036a2110200141b8096a2111200a21080340200141b0086a20014180066a41dc0010e9081a20012001280083053600b30520012001280280053602b00520014190096a200041d80010e9081a200e20012802b005360000201020012800b305360000200120053a00e809200141c0046a41186a4200370300200141c0046a41106a4200370300200141c0046a41086a22034200370300200142003703c004200141e0046a41f8fcc60041081081022003200141e0046a41086a290300370300200120012903e0043703c004200141f0046a41a8aac800410d108102200641086a200141f0046a41086a290300370000200620012903f00437000020014180026a200141c0046a412010f80220014180026a41106a29030021152001280280022107200129038802211420014190096a41186a290300211620014190096a41086a290300212b20012903a009212c200129039009212d41002103024020012903b009221a42028820112903002218423e8684220c2018420288221284500d0041002103200c201a85201220188584500d00410021030340200141f0016a201a2018200341046a41fe007110e408200341026a210320012903f001220c200141f0016a41086a290300221284500d01200c201a8520122018858450450d000b0b2015420020071b21172014420020071b2119200841e8006a210b42002114420021120340200141d0016a20124201862014423f88842212420020144201862214420184220c420010e808200141e0016a200c4200200c420010e8080240201220012903d801221584201584420052200141e0016a41086a290300221520012903d001221b201b7c7c221b201554720d0020012903e0012115200141c0016a201a2018200341ff007110e40820122012201520012903c00156201b200141c0016a41086a290300221556201b2015511b22071b21122014200c20071b21140b02402003450d0041002003417e6a2207200720034b1b21030c010b0b41002103024020194202882017423e8684220c2017420288221584500d00200c201985201520178584500d00410021030340200141b0016a20192017200341046a41fe007110e408200341026a210320012903b001220c200141b0016a41086a290300221584500d01200c20198520152017858450450d000b0b420021154200210c034020014190016a200c4201862015423f8884220c420020154201862215420184221b420010e808200141a0016a201b4200201b420010e8080240200c200129039801221884201884420052200141a0016a41086a2903002218200129039001221a201a7c7c221a201854720d0020012903a001211820014180016a20192017200341ff007110e408200c200c201820012903800156201a20014180016a41086a290300221856201a2018511b22071b210c2015201b20071b21150b02402003450d0041002003417e6a2207200720034b1b21030c010b0b02400240024002402014201284500d00024002400240024002400240200541ff01710e03000102000b0340200141306a202c20162014201210e70820152215200c221b844200510d04200141306a41086a290300210c20012903302118200141206a202d202b2015201b10e70820182001290320221754200c200141206a41086a290300221a54200c201a5122031b0d032017201854201a200c5420031b0d06200141106a202c20162014201210e6082001202d202b2015201b10e6082001290300220c200141086a290300221884500d062014212d2012212b200c2114201821122015212c201b211620012903102215200141106a41086a290300220c8450450d000c030b0b034020122112201421142015200c844200510d04200141f0006a202c20162015200c10e708200141e0006a202d202b2014201210e7082001290370221a2001290360221754200141f0006a41086a290300221b200141e0006a41086a290300221854201b20185122031b0d022017201a542018201b5420031b0d05200141d0006a202c20162015200c10e608200141c0006a202d202b2014201210e6082001290340221b200141c0006a41086a290300221884500d052015212d200c212b201b21152018210c2014212c2012211620012903502214200141d0006a41086a29030022128450450d000c020b0b202d202c58202b201658202b2016511b0d030b2001200936028c06200141043a008806200141093a00800620014180066a10fe01024020012802c40922030d0020014180066a41186a201341186a29000037030020014180066a41106a201341106a2900003703002022201341086a2900003703002001201329000037038006200141b8056a20014180066a2009109708410121030c060b200141c0046a201310980820014180066a20012802c004220520012802c804221d10ad05200320046a2107024020012d00800622034103712223410346221f0d00024020030e03000100000b02400240201f0d0020230e03010001010b20012802a806450d0020012802a406102e0b202720012f00a0053b0000202741026a200141a0056a41026a2d00003a000041002103200141003a00800620012007360284062022200141b8056a41c80010e9081a0c040b200120073602b806200141013602b40620034102470d032005201d10ff010c040b41d0d8c8004119418cd5cc001039000b41d0d8c8004119418cd5cc001039000b2001200936028c06200141053a008806200141093a00800620014180066a10fe01410021030c020b200141003602c005200142013703b80520014180066a200141b8056a10ac082005201d20012802b805221f20012802c00510b201024020012802bc05450d00201f102e0b0240200341037122034103460d0020030e03010001010b20012802a806450d0020012802a406102e0b024020012802c404450d002005102e0b2001200936029805200142e4cab5fbb6ccdcb0e30037039005410c102c2203450d032001420c3702f404200120033602f004200141f0046a20014190056a410810742001200936028006200141f0046a20014180066a41041074200141a0056a41086a20012802f804360200200120012903f0043703a005200141003b01b805201e2013290000370000201e41086a201341086a290000370000201e41106a201341106a290000370000201e41186a201341186a290000370000200141173a0088062001410d36028006200120093602ac06200141c0046a200141a0056a41002007410020014100413f200141b8056a20014180066a10c9044101210320012802c0044101470d0041ac80ca00413210ef020b2001200436028406200120033a008106200141013a008006200141b8056a200910890520012802c005210720012802b80521032001410036029809200142013703900920014180066a20014190096a10bc0520032007200128029009220920012802980910b2010240200128029409450d002009102e0b024020012802bc05450d002003102e0b0240200b200f460d002008280268210920014180066a200841ec006a41dc0010e9081a2001200841c9016a280000360280052001200841cc016a28000036008305200841c8016a2103200b210820032d000022054103470d010b0b202a210c0b02402002450d00200241e8006c450d00200a102e0b2004108303211220014180066a10a903427f427f200d427f201c427f2021427f2020427f200c20127c22122012200c541b7c220c200c2020541b7c220c200c2021541b7c220c200c201c541b7c220c200c200d541b220c2001290380067c22122012200c541b410210f1044100410010eb04200128029004210802402001280298042203450d00200341246c21072008210303400240024002400240024020032d00000e050400010204030b2003410c6a280200450d03200341086a280200102e0c030b2003410c6a280200450d02200341086a280200102e0c020b2003410c6a280200450d01200341086a280200102e0c010b200341086a280200450d00200341046a280200102e0b200341246a21032007415c6a22070d000b0b02402001280294042203450d00200341246c450d002008102e0b200141f0096a24000f0b1036000b1038000b0400100b0ba33f04067f087e057f027e230041b0126b22022400200220013602900a200241f0006a200241900a6a109005200228027821032002280270210420022802742105200241900a6a200141c80310e9081a20024188076a200241900a6a108a0220022d008807210120022f008907210620022d008b07210720024180046a20024188076a41047241840310e9081a02400240024002400240024002400240024020014101460d0020024180016a20024180046a41046a41800310e9081a200241e8006a41fcc6cb004110108e02200228026c21012002280268210620022003360290072002200536028c072002200436028807200241900a6a2001410020061b10a30720022802900a220120022802980a20024188076a10c502024020022802940a450d002001102e0b02402005450d002004102e0b200241d80d6a20024180016a41d0006a109704200241900a6a20024180016a41800310e9081a02400240024002400240024002400240024020022903b00a22084202520d0020022903d80d20022d00e00d2003109f05220141ff01714102470d08200241a0076a4200370300200241a8076a4200370300200241b0076a4200370300200242003703800f200242003703900720024200370388072002420037039807200242003703b80720022802e00a417e6a0e1a010b0b0b0b0b0b0b02040b0b0b0b0b0b0b050b0b0b0b0b0b0b060b0b200241980e6a41186a200241900a6a41186a290300370300200241980e6a41106a200241900a6a41106a290300370300200241980e6a41086a200241900a6a41086a290300370300200220022903900a3703980e200241900a6a41c0006a2903002109200241900a6a41386a290300210a200241900a6a41c8006a280200210120022903b80a210b200241f0116a41186a22054200370300200241f0116a41106a22044200370300200241f0116a41086a22064200370300200242003703f011200241d0116a41d9fcc60041061081022006200241d0116a41086a2207290000370300200220022900d0113703f011200241d0116a4180f4cb00410610810220052007290000370300200420022900d011370300200241e0006a200241f0116a4120108e02024020084201520d00200b4200510d0a0b200241d0116a200241980e6a10c80220024188076a20022802d011220420022802d81110c90220024188076a41c8006a2802002105200229038807210820024188116a41086a20024188076a41106a29030037030020024188116a41106a20024188076a41186a29030037030020024188116a41186a20024188076a41206a29030037030020024188116a41206a20024188076a41286a29030037030020024188116a41286a220620024188076a41306a29030037030020024188116a41306a220720024188076a41386a29030037030020024188116a41386a20024188076a41c0006a290300370300200220022903900737038811200241a0106a41086a200241dc076a280200360200200220022902d4073703a0100240024020084201510d00200241a8126a4200370300200241f0116a41306a4200370300200241f0116a41286a420037030020024190126a420037030020024188126a420037030020024180126a4200370300200241f0116a41086a420037030041002105200241e0116a41086a4100360200200242003703f011200242003703e0110c010b200241f0116a41386a20024188116a41386a290300370300200241f0116a41306a2007290300370300200241f0116a41286a2006290300370300200241f0116a41206a20024188116a41206a290300370300200241f0116a41186a20024188116a41186a290300370300200241f0116a41106a20024188116a41106a290300370300200241f0116a41086a20024188116a41086a290300370300200241e0116a41086a200241a0106a41086a28020036020020022002290388113703f011200220022903a0103703e0110b024020022802d411450d002004102e0b024020052001470d0020024188076a41386a200241f0116a41386a29030037030020024188076a41306a200241f0116a41306a29030037030020024188076a41286a200241f0116a41286a29030037030020024188076a41206a200241f0116a41206a29030037030020024188076a41186a200241f0116a41186a29030037030020024188076a41106a200241f0116a41106a29030037030020024188076a41086a200241f0116a41086a290300370300200220022903f011370388072002200141016a3602c807200241d4076a200241e0116a41086a280200360200200220022903e0113702cc0720024188116a200241980e6a10c802200228028811220120022802901120024188076a10c9050240200228028c11450d002001102e0b418012210120022d00e00d22054102460d0e20022903d80d220820052003109f05220141ff01714102470d0e20024188076a20032008200a200920022d00e10d410047200510e7044200210c4200210b4200210802402002290388074201520d00427f427f20024198076a2903002208200241a8076a2903007c200229039007220b200241a0076a2903007c220d200b542201ad7c220b2001200b200854200b2008511b22011b2208200241b8076a2903007c427f200d20011b220b200241b0076a2903007c220d200b542201ad7c220b2001200b200854200b2008511b22011b2108427f200d20011b210b0b02400240024002400240200b20022903c007220d84200820024188076a41c0006a290300220e848450450d000c010b20024188076a200241980e6a427f200b200d7c220c200c200b5422012008200e7c2001ad7c220b200854200b2008511b22011b427f200b20011b41014111200a200984501b10fe062002280288074101460d0120024198076a290300210f200229039007210e4201210c0b200241a0106a41086a200241980e6a41086a2903002208370300200241a0106a41106a200241980e6a41106a290300220b370300200241a0106a41186a200241980e6a41186a290300220d37030020024188116a41c0006a200f370300200241c0116a2201200e37030020024188116a41186a200837030020024188116a41206a200b37030020024188116a41286a200d370300200220022903980e22083703a0102002200a3703881120022008370398112002200c3703b811200220093703901120024188076a200241980e6a200241900a6a41d0006a10800320022d0088074101460d01200241b4076a280200210720024188076a41286a2802002104200241ac076a2802002110200241a4076a280200210620024188076a41186a2802002111024020024188076a41206a2802002201450d002001410c6c21052011210103400240200141046a280200450d002001280200102e0b2001410c6a2101200541746a22050d000b0b02402006450d002006410c6c450d002011102e0b02402007450d002007410c6c21052010210103400240200141046a280200450d002001280200102e0b2001410c6a2101200541746a22050d000b0b2004450d022004410c6c450d022010102e0c020b200241a0106a41086a200241f0116a41086a290300370300200241a0106a41106a200241f0116a41106a290300370300200241a0106a41186a200241f0116a41186a290300370300200220022903f0113703a01041800221010c100b20022d00890722054102470d0e0b200241c0106a20024188116a41c80010e9081a200241d00f6a41046a200241c0106a41c80010e9081a200241800f6a200241d00f6a41cc0010e9081a200241b80e6a200241800f6a41046a41c80010e9081a200241f80d6a41086a200241980e6a41086a290300370300200241f80d6a41106a200241980e6a41106a290300370300200241f80d6a41186a200241980e6a41186a290300370300200220022903980e3703f80d20024187046a200241b80e6a41c80010e9081a410121010c0c0b418006418004200520014b1b21010c0d0b4100210141002105200241e80a6a2802004102470d05200241800b6a200241ec0a6a10f20622014180feff077141087621050c010b4100210141002105200241e80a6a2802004102470d04200241800b6a200241ec0a6a10ff0622014180feff077141087621050b200141ff01714102470d030c070b200241d00f6a200241e40a6a109d07024020022d00d00f4101460d00200241fc0f6a2802002107200241f80f6a2802002104200241f40f6a2802002110200241ec0f6a2802002106200241e80f6a28020021110240200241f00f6a2802002201450d002001410c6c21052011210103400240200141046a280200450d002001280200102e0b2001410c6a2101200541746a22050d000b0b02402006450d002006410c6c450d002011102e0b02402007450d002007410c6c21052010210103400240200141046a280200450d002001280200102e0b2001410c6a2101200541746a22050d000b0b2004450d072004410c6c450d072010102e0c070b20022d00d10f22014102460d0620022f01d20f21050c020b200241d00f6a200241e80a6a10df02024020022d00d00f4101460d00200241fc0f6a2802002107200241f80f6a2802002104200241f40f6a2802002110200241ec0f6a2802002106200241e80f6a28020021110240200241f00f6a2802002201450d002001410c6c21052011210103400240200141046a280200450d002001280200102e0b2001410c6a2101200541746a22050d000b0b02402006450d002006410c6c450d002011102e0b02402007450d002007410c6c21052010210103400240200141046a280200450d002001280200102e0b2001410c6a2101200541746a22050d000b0b2004450d062004410c6c450d062010102e0c060b20022d00d10f22014102460d0520022f01d20f21050c010b200241d00f6a200241e80a6a10b80641002101410021050240024020022d00d00f417d6a0e0400010106010b20022d00d20f21050b200541087441077221050b2005410874200141ff017172210120022903b807500d072002200241c0076a3602d00f200241d00f6a10cc020c070b200241800f6a41186a200241d00f6a41186a290300370300200241800f6a41106a200241d00f6a41106a2903003703000c060b2000200620074110747222013b0001200041013a0000200041036a20014110763a00002005450d072004102e0c070b41d0e7cc00411941ece7cc001039000b20024187046a20024188076a41c80010e9081a410021010b200241a0106a41186a2205200241f80d6a41186a290300370300200241a0106a41106a2204200241f80d6a41106a290300370300200241a0106a41086a2206200241f80d6a41086a290300370300200220022903f80d3703a010200241d00f6a20024187046a41c80010e9081a20024180046a200241e00a6a41b00210e9081a20024188076a41186a2207200529030037030020024188076a41106a2205200429030037030020024188076a41086a22102006290300370300200220022903a010370388074102210402402001450d00200241800f6a41186a2007290300370300200241800f6a41106a2005290300370300200241800f6a41086a201029030037030020022002290388073703800f410121040b200241c0106a41086a200241800f6a41086a290300370300200241c0106a41106a200241800f6a41106a290300370300200241c0106a41186a200241800f6a41186a290300370300200220022903800f3703c01002404110102c2205450d00200541f8f7c60036020c2005410136020820054281808080103702004110102c2201450d0020014190f8c60036020c20014101360208200142818080801037020020052005280200417f6a2206360200024020060d002005280208200528020c2802001103000240200528020c280204450d002005280208102e0b200541046a22062006280200417f6a220636020020060d002005102e0b02400240200128020820024180046a200128020c28020c1101000d00200241a8116a41023a0000200241a0116a41003a000020012001280200417f6a22053602002002420037039011420121082002420137038811024020050d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22052005280200417f6a220536020020050d002001102e0b20024180046a10dc020c010b20024188076a20024180046a41b00210e9081a2002418a0f6a200241c8106a290300370100200241920f6a200241d0106a2903003701002002419a0f6a200241d8106a290300370100200241a00f6a200241de106a290100370100200220043a00810f200241003a00800f200220022903c0103701820f200220013602a80f20024188116a20024188076a200241800f6a10dd0220022903881121080b20024198116a2903002109200241a0116a2d00002106200229039011210a20024180046a200241d00f6a41c80010e9081a200241a8116a2d0000210520022d00e00d21010240024002400240024002402008500d00200a4202510d00200141ff01714102470d004102210120054106460d00200241b0116a2802002104200241ac116a280200210120023100aa11210820023100a911210b41e09fc500410d10ef024191eacc00410d10ef020240024002400240024020050e06000102030406000b2001200410ef020c060b41f8e9cc00410d10ef020c050b41eee9cc00410a10ef020c040b200b10cc08200810cc082001450d032001200410ef020c030b41dce9cc00411210ef020c020b20022903d80d21084200210e0240200a4201520d0020082009580d004200200820097d220b200b2008561b210b200241f0116a41186a22124200370300200241f0116a41106a22044200370300200241f0116a41086a22074200370300200242003703f011200241d0116a41d9fcc60041061081022007200241d0116a41086a2210290000370300200220022900d0113703f011200241d0116a41d4f2cb00410b10810220122010290000370300200420022900d01137030020024188076a200241f0116a10f2042002200229039007420020022903880742015122111b3703800f200220024188076a41106a2213290300420020111b3703c010200220024188076a41186a2214290300420020111b3703b80e200241b80e6a211102400240024020014103710e03010002010b200241c0106a21110c010b200241800f6a21110b201142002011290300220c200b7d220b200b200c561b370300201420022903b80e370300201320022903c010370300200220022903800f370390072002420137038807201242003703002004420037030020074200370300200242003703f011200241d0116a41d9fcc600410610810220072010290000370300200220022900d0113703f011200241d0116a41d4f2cb00410b108102200441086a2010290000370000200420022900d011370000200241f0116a20024188076a41086a10f3040b20024180046a41c0006a290300210c200241b8046a290300210b20024180046a41086a290300210d20022903b0042115200229038004210f200241b80e6a41186a20024180046a41286a290300370300200241b80e6a41106a20024180046a41206a290300370300200241b80e6a41086a20024180046a41186a29030037030020022002290390043703b80e20024188076a20032008200920092008561b2008200a4201511b200f200d20022d00e10d410146200641ff017141014672200110e7044200210802402002290388074201520d00427f427f20024188076a41106a290300220820024188076a41206a2903007c200229039007220920024188076a41186a2903007c220a2009542201ad7c22092001200920085420092008511b22011b2208200241b8076a2903007c427f200a20011b220920024188076a41286a2903007c220a2009542201ad7c22092001200920085420092008511b22011b2108427f200a20011b210e0b024020154201520d0020024188076a200241b80e6a4200200b427f200e20022903c0077c22092009200e542201200820024188076a41c0006a2903007c2001ad7c220920085420092008511b22011b22087d220a200a200b56200c427f200920011b7d200b200854ad7d2208200c562008200c511b22011b4200200820011b108b06420020024188076a41086a29030020022802880741014622011b2208200b7d200b20087d2008200b56420020024188076a41106a29030020011b220a200c56200a200c511b22011b2109200a200c7d2008200b54ad7d200c200a7d200b200854ad7d20011b210820010d05200241800f6a41106a200d20082009200f562008200d562008200d511b22011b220a370300200241a00f6a22042009200f200920011b220b7d2215370300200241a80f6a2008200a7d2009200b54ad7d220e370300200242003703980f200242023703800f2002200b3703880f200241c0006a200b420042d000420010e808200241306a200a420042d000420010e808200241d0006a2002290340200241c0006a41086a290300220820022903307c220c42e400420010e708200242dc9e8aae8f85d7c702200241d0006a41086a2903002002290338420052200c2008547222011b2208200a42c2eba3e1f5d1f0fa28200229035020011b220d200b542008200a542008200a511b22011b220c370390072002200d200b20011b220837038807427f200a200c7d200b200854ad7d220a200e7c200920087d220d200b20087d2216542201ad7c220b2001200b200a54200b200a511b22011b2109427f200d20011b210b024002402008200c844200520d00200220024188076a3602c010200241c0106a10cc020c010b200242f0f2bda1a7ee9cb9f9003703c01020024188076a200241c0106a10cd02200241206a20024188076a2008200c10fd01200241d0106a200241206a41086a290300220f200c7d2002290320220d200854ad7d200c200f7d2008200d54ad7d200d200856200f200c56200f200c511b22011b3703002002200d20087d2008200d7d20011b3703c81020022001ad3703c010200241c0106a41086a21030240024020010d00200220033602f011200241f0116a10cc020c010b200220033602f011200241f0116a10ce020b200241a0076a200c37030020024198076a200837030020024190076a41063a00002002410e3a00880720024188076a10fe010b2002200b370388072002200937039007024002402016201584200a200e84844200520d00200220024188076a3602c010200241c0106a10cc020c010b200241c0106a10e20420024188076a10e204200241106a20024188076a200b200910fd0120024180126a200241106a41086a290300220a20097d20022903102208200b54ad7d2009200a7d200b200854ad7d2008200b56200a200956200a2009511b22011b37030020022008200b7d200b20087d20011b3703f81120022001ad3703f011200241f0116a41086a21030240024020010d00200220033602980e200241980e6a10cc020c010b200220033602980e200241980e6a10ce020b200241c0076a2009370300200241b8076a200b37030020024188076a41086a41043a000020024191076a20022903c01037000020024199076a200241c0106a41086a290300370000200241a1076a200241d0106a290300370000200241a9076a200241d8106a290300370000200241033a00880720024188076a10fe010b0240024020022903800f22084202560d002008a70e03010001010b2002200241800f6a41086a3602880720024188076a10cc020b024020022903980f22084202560d002008a70e03010001010b200220043602880720024188076a10cc020b200241ec0d6a41026a2201200241a9116a220441026a2d00003a0000200220042f000022043b01f00d200220043b01ec0d20022902ac11210b20022903d80d2208200229039811220920092008561b2008200229039011220d4201511b210820022903e00d2109200229038811220a4201510d022009210c410021040c030b4185eacc00410c10ef020b418010210120022903b004500d072002200241b8046a3602880720024188076a10cc020c070b200241d00f6a41026a20012d00003a0000200220022f01ec0d3b01d00f410121042008210c200b21080b200241900a6a41086a20043a0000200241990a6a20022f0080043b00002002419c0a6a20053a00002002419d0a6a20022f01d00f3b0000200241900a6a41206a2009370300200241900a6a41186a200c370300200241900a6a41106a2008370300200241b80a6a2002290388073703002002419b0a6a20024180046a41026a2d00003a00002002419f0a6a200241d00f6a41026a2d00003a0000200241c00a6a20024188076a41086a290300370300200241c80a6a20024188076a41106a290300370300200241d00a6a20024188076a41186a290300370300200241d80a6a20024188076a41206a290300370300200241003a00900a200241900a6a10fe01200241086a41fcc6cb004110108e022002200228020c41016a410120022802081b22043602900a41fcc6cb004110200241900a6a410410b2014100200410eb04200241900a6a41026a20012d00003a0000200220022f01ec0d3b01900a02400240200a4201510d00410621010c010b20024188076a41026a2204200241900a6a41026a22032d00003a0000200220022f01900a3b01880741062101200d4202510d00200320042d00003a0000200220022f0188073b01900a200521010b200041003a0000200041046a20013a0000200041056a20022f01900a3b0000200041086a200b370000200041076a200241920a6a2d00003a00000c060b20022009370388072002200837039007200220024188076a3602800f200241800f6a10ce0241800221010c040b1036000b20022f018a074108742104024020022903b811500d00200220013602880720024188076a10cc020b200420057221010b200241800f6a200241d00f6a41cc0010e9081a0b200241e00a6a108b020b200241f00d6a41026a200241f40d6a41026a2d00003a0000200220022f01f40d3b01f00d200041036a20014110763a0000200020013b0001200041013a00000b200241b0126a24000b070010044101460ba922030a7f027e027f230041c0026b22012400200141f0016a41186a22024200370300200141f0016a41106a22034200370300200141f0016a41086a22044200370300200142003703f001200141c8016a41d9fcc60041061081022004200141c8016a41086a2205290000370300200120012900c8013703f001200141c8016a41e8f7cb00410e10810220022005290000370300200320012900c801370300200141f0016a412010ff01200242003703002003420037030020044200370300200142003703f001200141c8016a41d9fcc600410610810220042005290000370300200120012900c8013703f001200141c8016a4188f3cb00411010810220022005290000370300200320012900c801370300200141f0016a412010ff01200242003703002003420037030020044200370300200142003703f001200141c8016a41d9fcc600410610810220042005290000370300200120012900c8013703f001200141c8016a4180f4cb00410610810220022005290000370300200320012900c801370300200141086a200141f0016a4120108e02200128020c210620012802082107200242003703002003420037030020044200370300200142003703f001200141c8016a41d9fcc600410610810220042005290000370300200120012900c8013703f001200141c8016a41a0f4cb00410a10810220022005290000370300200320012900c801370300200141c8016a200141f0016a4120108d0220012d00c80121052002200141e1016a2900003703002003200141d9016a2900003703002004200141d1016a290000370300200120012900c9013703f0010240024020054101460d00200141106a41186a4200370300200141106a41106a4200370300200141106a41086a4200370300200142003703100c010b200141106a41186a2002290300370300200141106a41106a2003290300370300200141106a41086a2004290300370300200120012903f0013703100b20014188026a2205420037030020014180026a22084200370300200141f0016a41086a22024200370300200142003703f001200141c8016a41d9fcc60041061081022002200141c8016a41086a2204290000370300200120012900c8013703f001200141c8016a41b4f4cb004106108102200341086a22092004290000370000200320012900c801370000200141c8016a200141f0016a10a10420012802c801210a20012902cc01210b200542003703002008420037030020024200370300200142003703f001200141c8016a41d9fcc600410610810220022004290000370300200120012900c8013703f001200141c8016a41acf2cb00410e10810220092004290000370000200320012900c8013700002001200141f0016a4120108e0241012103200128020421020240024020012802004101460d00410021030c010b200141f0016a412010ff010b02402002410020031b2209ad420c7e220c422088a70d00200ca72203417f4c0d00024002400240024002400240024020030d004104210d0c010b2003102c220d450d010b0240024002402003410c6e220e20094f0d00200e41017422022009200220094b1b22024104200241044b1bad420c7e220c422088a7454102742102200ca72104024002402003410b4b0d00200141003602c8010c010b200141d0016a41043602002001200d3602c8012001200e410c6c3602cc010b200141f0016a20042002200141c8016a107d200141f8016a2802002103024020012802f0014101460d0020012802f401210d2003410c6e210e0c020b20030d030c080b20090d00410021090c010b41002103200d21020340200141f0016a200310a307200141c8016a20012802f001220520012802f8012208108b030240024020012802c80122040d004200210c410121040c010b2005200810ff0120012902cc01210c0b200341016a2103024020012802f401450d002005102e0b20022004360200200241046a200c3702002002410c6a210220092003470d000b0b200120093602d0012001200e3602cc012001200d3602c801200141306a200141c8016a10cd0802402006410020071b220541e212490d00200141c8016a41002005419f6d6a2203200320054b1b108c0220012802c801220320012802d00110ff0120012802cc01450d002003102e0b20014180016a10ce0820012802880121022001280280012103200141003a00e8012002450d04200120032d00003a00c801200141013a00e80120024101460d03200120032d00013a00c901200141023a00e80120024102460d03200120032d00023a00ca01200141033a00e80120024103460d03200120032d00033a00cb01200141043a00e80120024104460d03200120032d00043a00cc01200141053a00e80120024105460d03200120032d00053a00cd01200141063a00e80120024106460d03200120032d00063a00ce01200141073a00e80120024107460d03200120032d00073a00cf01200141083a00e80120024108460d03200120032d00083a00d001200141093a00e80120024109460d03200120032d00093a00d1012001410a3a00e8012002410a460d03200120032d000a3a00d2012001410b3a00e8012002410b460d03200120032d000b3a00d3012001410c3a00e8012002410c460d03200120032d000c3a00d4012001410d3a00e8012002410d460d03200120032d000d3a00d5012001410e3a00e8012002410e460d03200120032d000e3a00d6012001410f3a00e8012002410f460d03200120032d000f3a00d701200141103a00e80120024110460d03200120032d00103a00d801200141113a00e80120024111460d03200120032d00113a00d901200141123a00e80120024112460d03200120032d00123a00da01200141133a00e80120024113460d03200120032d00133a00db01200141143a00e80120024114460d03200120032d00143a00dc01200141153a00e80120024115460d03200120032d00153a00dd01200141163a00e80120024116460d03200120032d00163a00de01200141173a00e80120024117460d03200120032d00173a00df01200141183a00e80120024118460d03200120032d00183a00e001200141193a00e80120024119460d03200120032d00193a00e1012001411a3a00e8012002411a460d03200120032d001a3a00e2012001411b3a00e8012002411b460d03200120032d001b3a00e3012001411c3a00e8012002411c460d03200120032d001c3a00e4012001411d3a00e8012002411d460d03200120032d001d3a00e5012001411e3a00e8012002411e460d03200120032d001e3a00e6012001411f3a00e8012002411f460d03200141d0006a41106a200141c8016a41106a290300370300200141d0006a41086a200141c8016a41086a290300370300200120032d001f3a00e701200141d0006a41186a200141c8016a41186a290300370300200141203a00e801200120012903c801220c3703f0012001200c3703500240200128028401450d002003102e0b200141003602f801200142013703f0014120102c2203450d00200142203702cc01200120033602c801200141c8016a200141106a41201074200141f0016a20012802c801220320012802d0011074024020012802cc01450d002003102e0b200141f0006a20012802f001220320012802f80110cf08024020012802f401450d002003102e0b200b4200200a1b210c200a4104200a1b21040240024020012802702203450d00200141f8006a28020021022001280274210d200141003a00e8012002450d04200120032d00003a00c801200141013a00e80120024101460d03200120032d00013a00c901200141023a00e80120024102460d03200120032d00023a00ca01200141033a00e80120024103460d03200120032d00033a00cb01200141043a00e80120024104460d03200120032d00043a00cc01200141053a00e80120024105460d03200120032d00053a00cd01200141063a00e80120024106460d03200120032d00063a00ce01200141073a00e80120024107460d03200120032d00073a00cf01200141083a00e80120024108460d03200120032d00083a00d001200141093a00e80120024109460d03200120032d00093a00d1012001410a3a00e8012002410a460d03200120032d000a3a00d2012001410b3a00e8012002410b460d03200120032d000b3a00d3012001410c3a00e8012002410c460d03200120032d000c3a00d4012001410d3a00e8012002410d460d03200120032d000d3a00d5012001410e3a00e8012002410e460d03200120032d000e3a00d6012001410f3a00e8012002410f460d03200120032d000f3a00d701200141103a00e80120024110460d03200120032d00103a00d801200141113a00e80120024111460d03200120032d00113a00d901200141123a00e80120024112460d03200120032d00123a00da01200141133a00e80120024113460d03200120032d00133a00db01200141143a00e80120024114460d03200120032d00143a00dc01200141153a00e80120024115460d03200120032d00153a00dd01200141163a00e80120024116460d03200120032d00163a00de01200141173a00e80120024117460d03200120032d00173a00df01200141183a00e80120024118460d03200120032d00183a00e001200141193a00e80120024119460d03200120032d00193a00e1012001411a3a00e8012002411a460d03200120032d001a3a00e2012001411b3a00e8012002411b460d03200120032d001b3a00e3012001411c3a00e8012002411c460d03200120032d001c3a00e4012001411d3a00e8012002411d460d03200120032d001d3a00e5012001411e3a00e8012002411e460d03200120032d001e3a00e6012001411f3a00e8012002411f460d0320014180016a41106a2202200141c8016a41106a220829030037030020014180016a41086a220e200141c8016a41086a2209290300370300200120032d001f3a00e70120014180016a41186a2206200141c8016a41186a220a290300370300200141203a00e801200120012903c801220b3703f0012001200b370380012009200e29030037030020082002290300370300200a200629030037030020012001290380013703c801200141a4016a41026a220e200141fd006a41026a2d00003a0000200120012f007d3b01a40102400240200c422088a72202200ca7460d00200c210b0c010b200241016a22062002490d0820024101742207200620062007491b22064104200641044b1bad42247e220b422088a7454102742106200ba721070240024020020d00200141003602f0010c010b200141f8016a4104360200200120043602f0012001200241246c3602f4010b200141b0026a20072006200141f0016a107d200141b8026a280200210220012802b0024101460d0220012802b4022104200c42808080807083200241246ead84210b200c422088a721020b2004200241246c6a220241003a0000200220012903c801370001200241096a2009290300370000200241116a2008290300370000200241196a200a290300370000200220012f01a4013b0021200241236a200e2d00003a0000200b4280808080107c210c200d450d002003102e0b200020012903103700102000200536020020002001290350370030200041286a200141106a41186a290300370000200041206a200141106a41106a290300370000200041186a200141106a41086a290300370000200041386a200141d0006a41086a290300370000200041c0006a200141d0006a41106a290300370000200041c8006a200141d0006a41186a290300370000200041086a200c37020020002004360204200041e8006a200141306a41186a290300370000200041e0006a200141306a41106a290300370000200041d8006a200141306a41086a29030037000020002001290330370050200141c0026a24000f0b2002450d050b1036000b200141003a00e8010b41d1a4cc00412c200141c8016a4180a5cc0041a0a5cc00103e000b200141003a00e8010b41d1a4cc00412c200141c8016a4180a5cc004190a5cc00103e000b1038000b0e002001ad4220862000ad8410140bd20501057f230041d0026b22022400200242808080808020370204200220013602142002200041d4e2cc0020011b3602102002200241106a360200200241d8016a2002109902200241e4016a280200210320022802e001210420022802dc01210520022802d8012106200241f8006a200241e8016a41e00010e9081a02402005450d00200241186a200241f8006a41e00010e9081a0240024020022802002802040d00200241f8006a200241186a41e00010e9081a0c010b02402003450d00200341246c21002005210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402004450d00200441246c450d002005102e0b410021050b2005450d00200241d8016a410c6a2003360200200241d8016a41086a2004360200200220053602dc01200220063602d801200241e8016a200241f8006a41e00010e9081a200241d8016a10c40702402003450d00200341246c21002005210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402004450d00200441246c450d002005102e0b200241d0026a240042010f0b200241246a410f360200200241ec016a4102360200200242023702dc01200241a0a7c9003602d8012002410436021c200241fca7c9003602182002200241186a3602e8012002200241c8026a360220200241d8016a41b0a7c9001044000b840c04017f017e097f017e230041306b220224000240024002400240024020010d0020024100360220200242043703184108102c2201450d0420014110360204200141b1afc8003602002002200141086a36020c200220013602082002410136020420022001360200200241186a200210a9014108102c2201450d042001410e360204200141cdb7c0003602002002200141086a36020c200220013602082002410136020420022001360200200241186a200210a9014108102c2201450d042001410c360204200141dbb7c0003602002002200141086a36020c200220013602082002410136020420022001360200200241186a200210a9014108102c2201450d042001410e360204200141e7b7c0003602002002200141086a36020c200220013602082002410136020420022001360200200241186a200210a9014108102c2201450d042001410a360204200141b4d8c8003602002002200141086a36020c200220013602082002410136020420022001360200200241186a200210a9014108102c2201450d042001410b360204200141d59fc5003602002002200141086a36020c200220013602082002410136020420022001360200200241186a200210a9014108102c2201450d0420014118360204200141e48ac5003602002002200141086a36020c200220013602082002410136020420022001360200200241186a200210a9014108102c2201450d0420014112360204200141c4f9c0003602002002200141086a36020c200220013602082002410136020420022001360200200241186a200210a90120022802202201ad420c7e2203422088a70d032003a72204417f4c0d0320022802182105200228021c21060240024020040d00410421070c010b2004102c2207450d050b02402004410c6e220820014f0d00200841017422092001200920014b1b22094104200941044b1bad420c7e2203422088a74541027421092003a7210a024002402004410b4b0d00200241003602000c010b200241086a41043602002002200736020020022008410c6c3602040b200241186a200a20092002107d200241206a2802002104024020022802184101460d00200228021c21072004410c6e21080c030b2004450d040c050b20010d01410021090c020b200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c20024194a8c9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b200520014103746a210b200141037441786a41037641016a210c41002109200721012005210403402004280200220a450d01200141086a200441046a280200360200200141046a200a360200200141003602002001410c6a2101200941016a2109200441086a2204200b470d000b200c21090b0240200641ffffffff0171450d002005102e0b2002410036020820024201370300200241edcad18b063602182002200241186a410410742002410c3a00182002200241186a41011074411f2002107641d8fec600411f20021079200241043a00182002200241186a4101107420092002107602402009450d002009410c6c2104200741086a210103402001417c6a28020021092001280200220a2002107620022009200a10742001410c6a2101200441746a22040d000b0b200228020821012002280204210a2002280200210902402008450d002008410c6c450d002007102e0b200141046a2204417f4c0d0002400240024002400240024020040d002002410036020820022004360204200241013602000c010b2004102c220b450d0620024100360208200220043602042002200b360200200141c000490d01200141808001490d022001418080808004490d030b200241033a00182002200241186a41011074200220013602182002200241186a410410740c030b200220014102743a00182002200241186a410110740c020b200220014102744101723b01182002200241186a410210740c010b200220014102744102723602182002200241186a410410740b2002200920011074200235020821032002350200210d0240200a450d002009102e0b200241306a24002003422086200d840f0b1038000b1036000bde0504017f017e017f017e230041f00a6b22022400200242808080808020370204200220013602142002200041d4e2cc0020011b3602102002200241106a360200200241a0076a200210ed01200241b8066a200241a0076a41e80010e9081a2002290388082103200241e0036a200241a0076a41f0006a41d80210e9081a0240024020034203510d00200241186a200241b8066a41e80010e9081a2002200337038001200241186a41f0006a200241e0036a41d80210e90821010240024020022802002802040d00200241e0036a200241186a41e80010e9081a200241a0076a200141d80210e9081a0c010b024020034202510d0020022d001841ff01714102470d002002280220450d00200228021c102e0b200241b0016a108b02420321030b20034203510d00200241b8066a200241e0036a41e80010e9081a200241186a200241a0076a41d80210e9081a200241a0076a200241b8066a41e80010e9081a200220033703880820024190086a200241186a41d80210e9081a200241e0036a200241a0076a10c6074101410220022d00e00322014101461b2200102c2204450d01200241003602a807200220003602a407200220043602a0070240024020014101470d00200241013a0018200241a0076a200241186a41011074200241e0036a410172200241a0076a108e050c010b200241003a0018200241a0076a200241186a41011074024020022d00e40322014106460d00200241013a0018200241a0076a200241186a41011074200120022d00e50320022d00e603200241a0076a109d060c010b200241003a0018200241a0076a200241186a410110740b20023502a807210320023502a0072105200241f00a6a240020052003422086840f0b200241c4066a410f3602002002412c6a41023602002002420237021c200241a0a7c900360218200241043602bc06200241a4a8c9003602b8062002200241b8066a3602282002200241e80a6a3602c006200241186a41b0a7c9001044000b1036000ba30a02067f047e23004180026b220224000240024020010d00200241086a41fcc6cb004110108e02200228020c21030240200228020822044101470d0041fcc6cb00411010ff010b200241c8016a41186a22014200370300200241c8016a41106a22054200370300200241c8016a41086a22064200370300200242003703c801200241106a41d9fcc60041061081022006200241106a41086a2207290000370300200220022900103703c801200241106a41acf2cb00410e108102200120072900003703002005200229001037030020022003410020041b360210200241c8016a4120200241106a410410b2014101200210eb04200142003703002005420037030020064200370300200242003703c801200241106a41d9fcc600410610810220062007290000370300200220022900103703c801200241106a4180f4cb00410610810220012007290000370300200520022900103703002002200241c8016a4120108e022002280204210320022802002104200142003703002005420037030020064200370300200242003703c801200241106a41d9fcc600410610810220062007290000370300200220022900103703c801200241106a41d4f2cb00410b1081022001200729000037030020052002290010370300200241106a200241c8016a10f20420022903102108200241106a41106a29030021092002290318210a200241106a41186a290300210b200241106a10a9032003410020041b210502402002290318427f427f200a4200200842015122011b22082009420020011b7c220920092008541b2208200b420020011b7c220920092008541b580d004200410210f1040b200510d906200241106a10c807200241003602f001200242013703e8014120102c2201450d01200242203702cc01200220013602c801200241c8016a200241206a41201074200241e8016a20022802c801220120022802d0011074024020022802cc01450d002001102e0b200241106a200241e8016a1091024120102c2201450d01200242203702cc01200220013602c801200241c8016a200241c0006a41201074200241e8016a20022802c801220120022802d0011074024020022802cc01450d002001102e0b4120102c2201450d01200242203702cc01200220013602c801200241c8016a200241e0006a41201074200241e8016a20022802c801220120022802d0011074024020022802cc01450d002001102e0b200228021421032002411c6a2802002207200241e8016a10760240200741246c2205450d00200321010340200241c8016a200110ef04200241e8016a20022802c801220620022802d0011074024020022802cc01450d002006102e0b200141246a21012005415c6a22050d000b0b20023502f001210820023502e801210902402007450d00200741246c21052003210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012005415c6a22050d000b0b0240200241186a2802002201450d00200141246c450d002003102e0b20024180026a240020084220862009840f0b200241d4016a410f360200200241246a410236020020024202370214200241a0a7c900360210200241043602cc01200241bca8c9003602c8012002200241c8016a3602202002200241f8016a3602d001200241106a41b0a7c9001044000b1036000bd40704017f017e017f017e230041f0036b220224002002428080808080203702dc022002200136022c2002200041d4e2cc0020011b3602282002200241286a3602d802200241386a200241d8026a10ef01024002400240024020022802384101460d0020024180036a41086a2201200241c4006a2802003602002002200229023c37038003024020022802d8022802040d00200241186a41086a2001280200220136020020022002290380032203370318200241286a41086a200136020020022003370328200241386a200241286a108e0120022802384101460d02200241386a41086a22012903002103200241386a41186a22004200370300200241386a41106a220442003703002001420037030020024200370338200241386a41e8fcc600410910810220024180036a41b08ec9004103108102200020024180036a41086a22012900003703002004200229008003370300200241086a200241386a10850320022802082104200229031021052002410036023820024180036a41a00e4108200241386a107d2001280200210002402002280280034101470d002000450d040c050b20022802840320024180036a41e80010e908220142023703682001410336029801200120022903d802370370200141f8006a200241d8026a41086a29030037030020014180016a200241d8026a41106a29030037030020014188016a200241d8026a41186a29030037030020014190016a200241f8026a290300370300200141a0016a2003200542b8177c42b81720041b220520032005561b370300200141a8016a200241386a41a00210e9081a200241286a10f10141cc03102c2204450d04200242cc03370284032002200436028003410120024180036a1076200220013602d802200241386a200241d8026a10900520024180036a20022802382204200228024010740240200228023c450d002004102e0b20023502800321032002350288032105024020012903684202510d0020012d00004102470d00200141086a280200450d00200141046a280200102e0b20014198016a109601200041c8037021040240200041c803490d0020002004460d002001102e0b200241f0036a240020054220862003840f0b20024180036a10f1010b2002418c036a410f360200200241cc006a41023602002002420237023c200241a0a7c9003602382002410436028403200241d4a8c90036028003200220024180036a3602482002200241e8036a36028803200241386a41b0a7c9001044000b20024188036a200241c4006a2902003703002002200229023c3703800341e4a4c900412820024180036a418ca5c900419ca5c900103e000b1038000b1036000bfe1a070a7f017e057f027e037f027e057f230041c0056b2202240020024280808080802037021c2002200136022c2002200041d4e2cc0020011b3602282002200241286a360218200241c8046a200241186a109902024020022802cc042203450d00200241d4046a280200210420022802d004210520022802c8042101200241e8036a200241d8046a41e00010e9081a200241c8046a200241186a10ec01024020022802c80422060d0002402004450d00200441246c21002003210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b2005450d01200541246c450d012003102e0c010b200241c8046a41086a280200210720022802cc04210820024188036a200241e8036a41e00010e9081a200241a8026a20024188036a41e00010e9081a200241c8046a200241186a10ef01024020022802c8044101470d0002402004450d00200441246c21002003210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402005450d00200541246c450d002003102e0b02402007450d00200741c8036c210020062109034002402009220141e8006a2903004202510d0020012d00004102470d00200141086a280200450d00200141046a280200102e0b200141c8036a210920014198016a109601200041b87c6a22000d000b0b2008450d01200841c8036c450d012006102e0c010b200241b8016a41086a2200200241c8046a410c6a280200360200200220022902cc043703b801200241c8016a200241a8026a41e00010e9081a200241306a410c6a2004360200200241306a41086a20053602002002200336023420022001360230200241c0006a200241c8016a41e00010e9081a200241a8016a2007360200200241a4016a2008360200200241b4016a2000280200360200200220063602a001200220022903b8013702ac01200241ac016a210a0240024020022802182802040d00200241e8036a41086a200a41086a2802003602002002200a2902003703e8030c010b02402004450d00200441246c210103400240024002400240024020032d00000e050400010204030b2003410c6a280200450d03200341086a280200102e0c030b2003410c6a280200450d02200341086a280200102e0c020b2003410c6a280200450d01200341086a280200102e0c010b200341086a280200450d00200341046a280200102e0b200341246a21032001415c6a22010d000b0b02402005450d00200541246c450d002002280234102e0b02402007450d00200741c8036c210020062109034002402009220141e8006a2903004202510d0020012d00004102470d00200141086a280200450d00200141046a280200102e0b200141c8036a210920014198016a109601200041b87c6a22000d000b0b02402008450d00200841c8036c450d002006102e0b200a10f101410021030b2003450d00200241c8016a41086a200241e8036a41086a220b2802002201360200200220022903e803220c3703c801200241a8026a41086a20013602002002200c3703a802200241013b01f403200242003702ec0302400240024002402007450d002006200741c8036c6a210d200241c8046a410472210e200241c0006a210f200241c8006a2110200621110340201141e8006a2903004202520d0102402011280298014103470d0020112903a0012112200241306a200241a8026a108e010240024020022802304101460d002002290338210c20104200370300200f4200370300200241306a41086a2201420037030020024200370330200241c8046a41e8fcc60041091081022001200241c8046a41086a2200290000370300200220022900c804370330200241c8046a41b08ec9004103108102200f41086a2000290000370000200f20022900c804370000200241086a200241306a10850302402012200c42b0ea017c580d00201342808080807083211341dea5c900ad210c4280808080d00421124100211441012115410021160c020b2012200229031042b8177c42b81720022802081b220c5a0d02200c42808080807083211241002115410121140c010b2002290338220c428080808070832112200228023421164101211541002114201742808080807083200235024084221721130b200220133703d804200220163602cc04200220153602c80420022012200c42ffffffff0f838422183703d004024002400240024020022d00f503450d004131210141b8a6c90021000c010b0240024002402015450d00200241e8036a10f101200242003702ec03200242f4d2b59bc7ae98b8303703300c010b20022802ec03210a200242f4d2b59bc7ae98b830370330200a450d0020022802e80321190c010b41e401102c220a450d0841002119200a4100360200200a41003b018a012002200a3602ec03200241003602e8030b2012422088a7211a200ca7211b02400340200a2f018a01221c410374211d41002101417f2100024003400240201d2001470d00201c21000c020b200241306a200a20016a418c016a410810ec082209450d03200041016a2100200141086a21012009417f4a0d000b0b02402019450d002019417f6a2119200a20004102746a41e4016a280200210a0c010b0b200242f4d2b59bc7ae98b830370340200220003602382002200a360234200241003602302002200241e8036a36023c2002410036029003200242013703880320150d02200241003a00b80120024188036a200241b8016a41011074200220183703b80120024188036a200241b8016a410810740c030b412d210141e9a6c90021000b20022001360234200220003602304183a6c9004122200241306a41a8a6c90041aca5c900103e000b200241013a00b80120024188036a200241b8016a41011074200e20024188036a10e8050b200241306a20024188036a10f001200220153a00f503200241003a00f40302402015450d0020024188036a41086a200241e8036a41086a290300370300200220022903e803370388032016450d04201a450d04201b102e0c040b2014201645720d00201a450d00201b102e0b201141c8036a2211200d470d000b0b20024188036a41086a200b290300370300200220022903e803370388030b200241a8026a10f10102402004450d00200441246c21002003210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402005450d00200541246c450d002003102e0b02402007450d00200741c8036c210020062109034002402009220141e8006a2903004202510d0020012d00004102470d00200141086a280200450d00200141046a280200102e0b200141c8036a210920014198016a109601200041b87c6a22000d000b0b02402008450d00200841c8036c450d002006102e0b200241003602d004200242013703c804200220022d0094033a00b801200241c8046a200241b8016a41011074200220022d0095033a00b801200241c8046a200241b8016a41011074200228029003220a200241c8046a10760240200228028c0322000d0041002101410021004100210a0c020b200228028803210920002101034020002f018a01211d2009450d022009417f6a21092000201d4102746a41e4016a280200210020012802e40121010c000b0b1036000b200241c4006a201d360200200241c0006a20003602002002200a3602482002420037033820022001360234200241003602300240200a450d0003402002200a417f6a360248200241306a410020011b221d280200210902400240201d280208220a201d28020422002f018a014f0d00200021010c010b03400240200028020022010d00410021010c020b200941016a210920002f018801210a20012100200a20012f018a014f0d000b0b200a41016a21190240024020090d00200121000c010b200120194102746a41e4016a280200210002402009417f6a2209450d00034020002802e40121002009417f6a22090d000b0b410021190b201d2000360204201d4100360200201d2019360208200241c8046a2001200a4103746a418c016a410810742001200a410c6c6a220141046a28020021002001410c6a2802002201200241c8046a1076200241c8046a2000200110742002280248220a450d01200228023421010c000b0b20023502d004210c20023502c804211220024188036a10f101200241c0056a24002012200c422086840f0b200241d4046a410f360200200241c4006a410236020020024202370234200241a0a7c900360230200241043602cc04200241f0a8c9003602c8042002200241c8046a3602402002200241b8056a3602d004200241306a41b0a7c9001044000bbd0702087f027e23004180016b2202240002400240024020010d00200241003602082002420137030020024100360230200241d8006a41204101200241306a107d200241d8006a41086a22012802002103024020022802584101470d002003450d020c030b200228025c21042002200336020420022004360200200241d8006a41186a22034200370300200241d8006a41106a220442003703002001420037030020024200370358200241106a41a8f8c60041041081022001200241106a41086a220529000037030020022002290010370358200241106a41978bc500410e1081022003200529000037030020042002290010370300200241306a200241d8006a10a30420022d003021052003200241c9006a2900003703002004200241c1006a2900003703002001200241396a290000370300200220022900313703580240024020054101460d00200241106a41186a4200370300200241106a41106a4200370300200241186a4200370300200242003703100c010b200241106a41186a2003290300370300200241106a41106a2004290300370300200241106a41086a200241d8006a41086a290300370300200220022903583703100b2002200241106a41201074200241d8006a20022802002206200228020810b001200241306a41186a2205200241d8006a41186a2201290300370300200241306a41106a2207200241d8006a41106a2203290300370300200241306a41086a2208200241d8006a41086a22042903003703002002200229035837033020014200370300200342003703002004420037030020024200370358200241106a41a8f8c60041041081022004200241106a41086a220929000037030020022002290010370358200241106a41b08bc500410a1081022001200929000037030020032002290010370300200241106a200241d8006a4120109d0302402002280204450d002006102e0b2004200829030037030020032007290300370300200120052903003703002002200229033037035820024100360218200242013703104120102c2201450d022002422037023420022001360230200241306a200241d8006a41201074200241106a200228023022012002280238107402402002280234450d002001102e0b2002350218210a2002350210210b20024180016a2400200b200a422086840f0b200241e4006a410f360200200241c4006a410236020020024202370234200241a0a7c9003602302002410436025c20024188a9c9003602582002200241d8006a3602402002200241f8006a360260200241306a41b0a7c9001044000b1038000b1036000bbf5d05027f027e0c7f077e027f230041e0176b220224002002428080808080203702ac17200220013602e4162002200041d4e2cc0020011b22033602e0162002200241e0166a3602a81741002100200241003a00901102400240024002402001450d0020022001417f6a3602e4162002200341016a3602e016024020032d00000e03030200010b410221000c020b420321040c020b410121000b200241c0076a200241a8176a10ed0142032104024020022903a80822054203520d000c010b2002418f0b6a200241c0076a41e80010e9081a20024190116a200241b0086a41d80210e9081a200241286a200241880b6a41ef0010e9081a200521040b200241d0066a200241286a41ef0010e9081a200241880e6a20024190116a41d80210e9081a02400240024002400240024002400240024020044203510d00200220003a00800320024180036a410172200241d0066a41ef0010e9082101200241f0036a2004370300200241f8036a200241880e6a41d80210e90821030240024020022802a8172802040d0020024190116a200141ef0010e9081a200241c0076a200341d80210e9081a0c010b024020044202510d0020022d0088034102470d0020024190036a280200450d00200228028c03102e0b200241a0046a108b02420321040b20044203510d0020024180036a20024190116a41ef0010e9081a200241d0066a20024187036a41e80010e9081a200241286a200241c0076a41d80210e9081a200241c0076a200241d0066a41e80010e9081a200220043703a808200241b0086a200241286a41d80210e9081a2002200241c0076a3602901120024180036a20024190116a10900520022802880321060240200228028403450d00200228028003102e0b20024180036a200241c0076a41c80310e9081a20024190116a20024180036a108a0220022d009011210120022f009111210320022d0093112107200241880e6a20024190116a41047241840310e9081a024020014101460d00200241880b6a200241880e6a41046a41800310e9081a20024198146a200241d80b6a22081097040240024020022903a80b4202520d0020024190116a41206a2201420037030020024190116a41186a22034280808080c000370300200241013a00b811200242043703a0112002427f37039811200242003703901120024180036a41206a2207420037030020024180036a41186a22094280808080c000370300200241013a00a80320024204370390032002427f370388032002420037038003200241f0146a20024190116a20024180036a10d20720024190116a41286a220a200241f0146a41286a2903003703002001200241f0146a41206a2903003703002003200241f0146a41186a29030037030020024190116a41106a220b200241f0146a41106a29030037030020024190116a41086a220c200241f0146a41086a290300370300200220022903f014370390112007420037030020094280808080c000370300200241013a00a80320024204370390032002427f370388032002420037038003200241a0156a20024190116a20024180036a10d207200a200241a0156a41286a2903003703002001200241a0156a41206a2903003703002003200241a0156a41186a290300370300200b200241a0156a41106a290300370300200c200241a0156a41086a290300370300200220022903a015370390112007420037030020094280808080c000370300200241013a00a80320024204370390032002427f370388032002420037038003200241d0156a20024190116a20024180036a10d207200a200241d0156a41286a2903003703002001200241d0156a41206a2903003703002003200241d0156a41186a290300370300200b200241d0156a41106a290300370300200c200241d0156a41086a290300370300200220022903d015370390112007420037030020094280808080c000370300200241013a00a80320024204370390032002427f37038803200242003703800320024180166a20024190116a20024180036a10d207200a20024180166a41286a290300370300200120024180166a41206a290300370300200320024180166a41186a290300370300200b20024180166a41106a290300370300200c20024180166a41086a2903003703002002200229038016370390112007420037030020094280808080c000370300200241013a00a80320024204370390032002427f370388032002420037038003200241b0166a20024190116a20024180036a10d207200241a8176a41286a220d200241b0166a41286a290300370300200241a8176a41206a220e200241b0166a41206a290300370300200241a8176a41186a220f200241b0166a41186a290300370300200241a8176a41106a2210200241b0166a41106a290300370300200241a8176a41086a2211200241b0166a41086a290300370300200220022903b0163703a81720024180036a20022903981420022d00a014200610a005200c20024180036a410c6a290200370300200b20024180036a41146a290200370300200320024180036a411c6a290200370300200120024180036a41246a290200370300200a20024180036a412c6a290200370300200241c0116a200241b4036a28020036020020022002290284033703901120022d0080034101470d0120022d008303210720022f008103210920022802b81721030240200f2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b0240200241bc176a2802002201450d002001410c6c450d002003102e0b2007411074210720022802c41721030240200241cc176a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b200920077221010240200241c8176a2802002200450d002000410c6c450d002003102e0b200241013a008003200220013b008103200220014110763a0083032008108b020c0a0b20024190116a41206a2200420037030020024190116a41186a22034280808080c000370300200241013a00b811200242043703a011427f21042002427f37039811200242003703901120024180036a41206a2207420037030020024180036a41186a22014280808080c000370300200241013a00a80320024204370390032002427f370388032002420037038003200241c0146a20024190116a20024180036a10d20720024190116a41286a2209200241c0146a41286a2903003703002000200241c0146a41206a2903003703002003200241c0146a41186a29030037030020024190116a41106a220a200241c0146a41106a29030037030020024190116a41086a220b200241c0146a41086a290300370300200220022903c014370390112007420037030020014280808080c000370300200241013a00a80320024204370390032002427f370388032002420037038003200241f0146a20024190116a20024180036a10d2072009200241f0146a41286a2903003703002000200241f0146a41206a2903003703002003200241f0146a41186a290300370300200a200241f0146a41106a290300370300200b200241f0146a41086a290300370300200220022903f014370390112007420037030020014280808080c000370300200241013a00a80320024204370390032002427f370388032002420037038003200241a0156a20024190116a20024180036a10d2072009200241a0156a41286a2903003703002000200241a0156a41206a2903003703002003200241a0156a41186a290300370300200a200241a0156a41106a290300370300200b200241a0156a41086a290300370300200220022903a015370390112001420037030020024180036a41106a2203420037030020024180036a41086a220942003703002002420037038003200241880e6a41d9fcc60041061081022009200241880e6a41086a2200290000370300200220022900880e37038003200241880e6a4180f4cb00410610810220012000290000370300200320022900880e370300200241206a20024180036a4120108e022002280224410020022802201bad2105024020022903a80b4201520d0020022903b00b22044200510d04200241b80b6a290300221220047c4200200520127d221220122005561b22127c20122004827d21040b2007420037030020014280808080c000370300200220022800880e3602a81720022002418b0e6a2800003600ab17200241ac036a20022800ab17360000200241013a00a8032002420437039003200242003703800320024200200420057d220520052004561b37038803200220022802a8173600a903200241d0156a20024190116a20024180036a10d207200241880e6a41286a200241d0156a41286a290300370300200241880e6a41206a200241d0156a41206a290300370300200241880e6a41186a200241d0156a41186a290300370300200241880e6a41106a200241d0156a41106a2903003703002000200241d0156a41086a290300370300200220022903d0153703880e200241a8176a200241880b6a10c80220024180036a20022802a817220020022802b01710c902200241c8036a28020041002002290380034201511b2101024020022802ac17450d002000102e0b0240024020022802d00b22002001490d00410c102c2203450d0c410421074104102c2209450d0c2002420437028403200220093602800320024180036a200241880b6a41201074200220003602a81720024180036a200241a8176a41041074200341086a2002280288033602002003200229038003370200410021090240200120004f0d00410c102c2207450d0d4104102c2201450d0d2002420437028403200220013602800320024180036a200241880b6a4120107420022000417f6a3602a81720024180036a200241a8176a41041074200741086a2002280288033602002007200229038003370200410121090b20024190116a41206a42818080801037030020024190116a41186a2201200936020020024190116a41146a2009360200200220022800e0163602b8142002200241e3166a2800003600bb1420024190116a412c6a20022800bb14360000200241013a00b811200220033602ac11200220073602a0112002427f370398112002420037039011200220022802b8143600b91120024180166a200241880e6a20024190116a10d207200241a8176a41286a20024180166a41286a290300370300200241a8176a41206a20024180166a41206a290300370300200241a8176a41186a20024180166a41186a290300370300200241a8176a41106a20024180166a41106a290300370300200241a8176a41086a20024180166a41086a29030037030020022002290380163703a817024020022d00a01422004102470d0020024198116a2002418c036a29020037030020024190116a41106a20024180036a41146a29020037030020012002419c036a290200370300200241b0116a200241a4036a29020037030020024190116a41286a20024180036a412c6a290200370300200241c0116a200241b4036a28020036020020022002290284033703901141801221010c0a0b20024180036a2002290398142000200610a00520024190116a41086a20024180036a410c6a29020037030020024190116a41106a20024180036a41146a290200370300200120024180036a411c6a29020037030020024190116a41206a20024180036a41246a29020037030020024190116a41286a20024180036a412c6a290200370300200241c0116a200241b4036a28020036020020022002290284033703901120022d0080034101470d0120022f00810320022d0083034110747221010c090b200220022800e0163602b8142002200241e3166a2800003600bb142002410a3a00830320024180063b008103200241013a00800320022802980e21030240200241a00e6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b02402002419c0e6a2802002201450d002001410c6c450d002003102e0b20022802a40e21030240200241ac0e6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b200241a80e6a2802002201450d092001410c6c450d092003102e2008108b020c0a0b200241880e6a41286a2201200241bc116a290200370300200241880e6a41206a220320024190116a41246a290200370300200241880e6a41186a220720024190116a411c6a290200370300200241880e6a41106a2209200241a4116a290200370300200241880e6a41086a220a20024190116a410c6a29020037030020022002290294113703880e200241b0166a200241a8176a200241880e6a10d2072001200241b0166a41286a2903003703002003200241b0166a41206a2903003703002007200241b0166a41186a2903003703002009200241b0166a41106a290300370300200a200241b0166a41086a290300370300200220022903b0163703880e20024180036a2006200229039814221320022903c00b2214200241880b6a41c0006a290300221520022d00a114410047200010e704420021054200210402402002290380034201520d00427f427f20024180036a41106a2903002204200241a0036a2903007c200229038803220520024180036a41186a2903007c22122005542201ad7c22052001200520045420052004511b22011b2204200241b0036a2903007c427f201220011b220520024180036a41286a2903007c22122005542201ad7c22052001200520045420052004511b22011b2104427f201220011b21050b427f200420024180036a41c0006a29030022167c200520022903b80322177c22182005542201ad7c22122001201220045420122004511b22011b2112427f201820011b2118024002400240024020052017842004201684844200520d00200220183703a817200242003703b817200220123703b0170c010b20024190176a200241880b6a20182012410141112014201584501b10fe062002280290174101460d01200241c0176a2201200229039817370300200241c8176a200241a0176a290300370300200220183703a817200242013703b817200220123703b017200220013602800320024180036a10cc020b20024180036a10a9032002290388032104200241013a00b811200220124200418080f00120064101200641014b1b6ead220520042013420120134201561b80220420042005561b2204420010e808200241106a201842002004420010e80820024190116a41206a2200420037030020024190116a41186a22034280808080c0003703002002200241ab146a2800003600bb14200220022800a8143602b81420024190116a412c6a220720022800bb14360000200242043703a011200220022802b8143600b91120022903082105200241106a41086a2903002104200229030021122002427f370398112002427f20022903102005420052200420127c22052004547222011b427f427f200520011b501b37039011200241e0166a200241880e6a20024190116a10d207200241880e6a41286a200241e0166a41286a290300370300200241880e6a41206a200241e0166a41206a290300370300200241880e6a41186a2201200241e0166a41186a290300370300200241880e6a41106a200241e0166a41106a290300370300200241880e6a41086a200241e0166a41086a290300370300200220022903e0163703880e20024180036a200241880b6a20081080032002200241b1036a2800003602b8142002200241b4036a2800003600bb1420022d0080034101460d01200241b0036a22012d0000210920024180036a41286a220a280200210b20024180036a41246a280200210c20024180036a41206a2206280200210f2002419c036a280200210d20024180036a41186a220e280200211020024180036a41106a2211290300210420024180036a41086a2219290300210520024190116a41246a20024180036a412c6a2802003602002000200b3602002003200f360200200241a4116a200d360200200720022800bb14360000200220093a00b8112002200c3602ac11200220103602a01120022004370398112002200537039011200220022802b8143600b911200241a8176a200241880e6a20024190116a10d207201920022903a8173703002011200241a8176a41086a290300370300200e200241a8176a41106a2903003703002006200241a8176a41186a290300370300200a200241a8176a41206a2903003703002001200241a8176a41286a290300370300200241003a0080032008108b020c0b0b200220022800a8143602b8142002200241ab146a2800003600bb14200241003a00830320024180023b008103200241013a00800320022802980e21030240200241a00e6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b02402002419c0e6a2802002201450d002001410c6c450d002003102e0b20022802a40e21030240200241ac0e6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b200241a80e6a2802002201450d092001410c6c450d092003102e2008108b020c0a0b20022d008303210020022f0081032103200241013a0080032002200320004110747222003b008103200220004110763a00830320022802980e2103024020012802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b02402002419c0e6a2802002201450d002001410c6c450d002003102e0b20022802a40e21030240200241ac0e6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b200241a80e6a2802002201450d082001410c6c450d082003102e2008108b020c090b200241880e6a41286a20024190116a412c6a290200370300200241880e6a41206a220620024190116a41246a290200370300200241880e6a41186a221920024190116a411c6a290200370300200241880e6a41106a20024190116a41146a290200370300200241880e6a41086a221a20024190116a410c6a29020037030020022002290294113703880e200241e0166a200241a8176a200241880e6a10d207200a200241e0166a41286a2903003703002001200241e0166a41206a2903003703002003200241e0166a41186a290300370300200b200241e0166a41106a290300370300200c200241e0166a41086a290300370300200220022903e016370390112007420037030020094280808080c000370300200241013a00a80320024204370390032002427f370388032002420037038003200241a8176a20024190116a20024180036a10d207200a200d2903003703002001200e2903003703002003200f290300370300200b2010290300370300200c2011290300370300200220022903a817370390112007420037030020094280808080c000370300200241013a00a80320024204370390032002427f370388032002420037038003200241880e6a20024190116a20024180036a10d207200241c0146a410c6a201a290300370200200220022903880e3702c414200241880e6a41146a28020021032019280200210120062802002107200241880e6a41246a280200210920022802980e210a20022802a40e210b20022903b00e210420024190176a41106a200241c0146a41106a28020036020020024190176a41086a200241c0146a41086a290200370300200220022902c01437039017200241a8146a41086a20024190176a410c6a29020037030020022002290294173703a814024002400240024002400240024020022802d80b417e6a0e1a0100000000000000020500000000000000030000000000000004000b200241003a00830320024181023b0081030c0a0b0240200241e00b6a2802004102460d002002410a3a008303200241003b0081030c0a0b0240200041ff01714102490d002002410a3a008303200241003b0081030c0a0b0240200241f80b6a200241e40b6a10f206220c41ff01714102470d0020024180036a41086a427f370300200241b4036a2200411036020020024180036a41206a420037030020024180036a41186a4280808080c0003703002002427f37038003200241d8b2c4003602b003200241013a00a8032002420437039003200241a8176a41186a200241f80d6a2903002205370300200241a8176a41106a200241f00d6a2903002212370300200241a8176a41086a200241e80d6a29030022183703002002200241e00d6a29030022133703a817200220022903f80b22163703c81720024190116a41106a201837030020024190116a41186a201237030020024190116a41206a2005370300200241b8116a220c20163703002002200241b0036a360290112002201337039811411c102c2206450d0f2002421c37028416200220063602801620022802b00321062000280200220020024180166a107620024180166a20062000107420024180166a20024190116a41086a412010742002200c2903003703b01620024180166a200241b0166a410810740240024020022802a403220c20022802a0032200470d00200041016a220c2000490d0b20004101742206200c2006200c4b1b220c4104200c41044b1bad420c7e2205422088a745410274210c2005a721060240024020000d0020024100360290110c010b20024198116a41043602002002200228029c033602901120022000410c6c360294110b200241b0166a2006200c20024190116a107d200241b8166a280200210020022802b0164101460d01200220022802b41636029c0320022000410c6e3602a00320022802a403210c0b200228029c03200c410c6c6a2200200229038016370200200041086a20024180166a41086a28020036020020024190116a41086a220020024198036a220c290300370300200220022802a40341016a3602a40320024190116a41106a2206200241a0036a220f2903003703002002200229039003370390112002200241a9036a220d2900003703b0162002200d41076a2900003700b716200229038003210520024180036a41106a4280ce1837030020024180036a41086a2005370300200241a8036a2006290300370300200f2000290300370300200c20022903901137030041002100200241b0036a41003a0000200241b4036a20022800b316360000200241b1036a20022802b016360000200241003a0080030c0c0b2000450d090c0f0b41012100200241013a0080032002200c3b0081032002200c4110763a0083030c0a0b0240200241e00b6a2802004102460d002002410a3a008303200241003b0081030c090b0240200041ff01714102490d002002410a3a008303200241003b0081030c090b0240200241f80b6a200241e40b6a10ff06220c41ff01714102470d0020024190116a41086a427f370300200241c4116a2200411336020020024190116a41206a420037030020024190116a41186a4280808080c0003703002002427f37039011200241ccdcc8003602c011200241013a00b811200242043703a011200241a8176a41106a200241e00d6a2903002205370300200241a8176a41186a200241e80d6a2903002212370300200241a8176a41206a200241f00d6a29030022183703002002200241d80d6a29030022133703b0172002200241880c6a29030022163703d017200220022903f80b22173703a81720024180036a41106a220c201337030020024180036a41186a200537030020024180036a41206a2012370300200241a8036a201837030020024180036a41306a22062016370300200220024190116a41306a3602800320022017370388034127102c220f450d0e20024227370284162002200f3602801620022802c011210f2000280200220020024180166a107620024180166a200f2000107420024180166a200c4120107420022002290388033703b01620024180166a200241b0166a41081074200220062903003703b01620024180166a200241b0166a410810740240024020022802b411220c20022802b0112200470d00200041016a220c2000490d0a20004101742206200c2006200c4b1b220c4104200c41044b1bad420c7e2205422088a745410274210c2005a721060240024020000d0020024100360280030c010b20024188036a4104360200200220022802ac113602800320022000410c6c360284030b200241b0166a2006200c20024180036a107d200241b8166a280200210020022802b0164101460d01200220022802b4163602ac1120022000410c6e3602b01120022802b411210c0b20022802ac11200c410c6c6a2200200229038016370200200041086a20024180166a41086a280200360200200241b0166a41086a220020024190116a41186a290300370300200220022802b41141016a3602b411200241b0166a41106a220c20024190116a41206a290300370300200220022903a0113703b0162002200241b9116a2206290000370380162002200641076a29000037008716200229039011210520024180036a41106a4280ce1837030020024180036a41086a2005370300200241a8036a200c29030037030020024180036a41206a200029030037030020024180036a41186a20022903b01637030041002100200241b0036a41003a0000200241b4036a200228008316360000200241b1036a200228028016360000200241003a0080030c0b0b20000d0e0c080b41012100200241013a0080032002200c3b0081032002200c4110763a0083030c090b20024180036a200241e00b6a10df020c020b0240200041ff01714102490d002002410a3a008303200241003b0081030c070b20024190116a200241e00b6a10b806024020022d009011220c4106460d00200241800e3b00810341012100200241013a008003200220022d0092114100200c4103461b3a0083030c080b200241e80b6a290300210520022903e00b2112200241d00d6a28020021004118102c220c450d0b200242183702ac172002200c3602a8174110200241a8176a1076200241a8176a41e6b3c700411010742002200036028003200241a8176a20024180036a4104107441002100200241003602800320024190116a4130410420024180036a107d20024190116a41086a280200210602402002280290114101470d0020060d0c0c060b200228029411220c20022903a817370200200c41086a200241a8176a41086a28020036020020024180036a41306a41003a0000200241ac036a4101360200200241a8036a2006410c6e360200200241a4036a200c360200200241a0036a410036020020024198036a420437030020024180036a41106a42d80437030020024180036a41086a427f2012427f2005501b220542e5cc99b3e6cc99b3667c221220122005541b37030020022002280090113602b016200220024193116a2800003600b316200241b4036a20022800b316360000200241b1036a20022802b016360000200241003a0080030c070b20024180036a200241dc0b6a109d070b20022d00800321000c050b200241013a0080032002200320074110747222013b008103200220014110763a0083030c070b200241940e6a410f36020020024194036a41023602002002420237028403200241a0a7c900360280032002410436028c0e2002419ca9c9003602880e2002200241880e6a360290032002200241d8176a3602900e20024180036a41b0a7c9001044000b41d0e7cc00411941ece7cc001039000b1038000b41012100200241013a0080030b200241880e6a41086a220c20024180036a410c6a290200370300200241880e6a41106a20024180036a41146a290200370300200241880e6a41186a220620024180036a411c6a290200370300200241880e6a41206a220f20024180036a41246a290200370300200241880e6a41286a20024180036a412c6a290200370300200241880e6a41306a200241b4036a28020036020020022002290284033703880e0240200041ff01714101460d00200241e0166a41286a2200200241880e6a412c6a290200370300200241e0166a41206a220d200241880e6a41246a220e290200370300200241e0166a41186a2210200241880e6a411c6a290200370300200241e0166a41106a2211200241880e6a41146a2219290200370300200241e0166a41086a221a200241880e6a410c6a2902003703002002200229028c0e3703e016200c200241a8146a41086a290300370300200e2009360200200f20073602002006200136020020192003360200200220022903a8143703880e200220043703b00e2002200b3602a40e2002200a3602980e20024190116a41286a200029030037030020024190116a41206a200d29030037030020024190116a41186a201029030037030020024190116a41106a201129030037030020024190116a41086a201a290300370300200220022903e01637039011200241a8176a200241880e6a20024190116a10d20720024180036a41086a20022903a81737030020024180036a41106a200241a8176a41086a29030037030020024180036a41186a200241a8176a41106a29030037030020024180036a41206a200241a8176a41186a29030037030020024180036a41286a200241a8176a41206a29030037030020024180036a41306a200241a8176a41286a290300370300200241003a0080032008108b020c030b20022d008303210020022f008103210c200241013a0080032002200c20004110747222003b008103200220004110763a00830302402001450d002001410c6c2100200a210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b02402003450d002003410c6c450d00200a102e0b02402009450d002009410c6c2100200b210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b2007450d012007410c6c450d01200b102e0c010b200241013a008003200220013b008103200220014110763a00830320022802b81721030240200241c0176a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b0240200241bc176a2802002201450d002001410c6c450d002003102e0b20022802c41721030240200241cc176a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b200241c8176a2802002201450d002001410c6c450d002003102e2008108b020c010b2008108b020b4101102c2201450d00200242013702c407200220013602c0070240024020022d0080034101470d00200241013a009011200241c0076a20024190116a4101107420024180036a410172200241c0076a108e050c010b200241003a009011200241c0076a20024190116a41011074200220024180036a41086a29030037039011200241c0076a20024190116a4108107420024198036a2802002101200241a0036a2802002200200241c0076a107602402000450d0020012000410c6c6a2107034020012802002100200141086a2802002203200241c0076a1076200241c0076a2000200310742001410c6a22012007470d000b0b200241a4036a2802002101200241ac036a2802002200200241c0076a107602402000450d0020012000410c6c6a2107034020012802002100200141086a2802002203200241c0076a1076200241c0076a2000200310742001410c6a22012007470d000b0b200220024190036a29030037039011200241c0076a20024190116a410810742002200241b0036a2d00003a009011200241c0076a20024190116a410110740b20023502c807210420023502c0072105024020022d0080030d000240200241a0036a2802002200450d0020024198036a28020021012000410c6c210003400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b02402002419c036a2802002201450d002001410c6c450d00200228029803102e0b0240200241ac036a2802002200450d00200241a4036a28020021012000410c6c210003400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b200241a8036a2802002201450d002001410c6c450d0020022802a403102e0b200241e0176a240020044220862005840f0b1036000bb30304017f027e067f027e230041206b22032400200229030021042001290300210520022802102106200141106a200241186a2207280200220810e0082001280210200141186a2209280200220a410c6c6a20062008410c6c10e9081a200741003602002009200a20086a2208360200200341086a200836020020032001290210370300200228021c21072001411c6a200241246a2209280200220810e008200128021c200141246a220a280200220b410c6c6a20072008410c6c10e9081a20094100360200200a200b20086a2208360200200341106a41086a20083602002003200129021c3703102002290308210c2001290308210d0240024020012d0028450d004101210120022d00280d010b410021010b200020032903003702102000200329031037021c200020013a0028200041186a200341086a280200360200200041246a200341106a41086a2802003602002000200c200d200d200c561b3703082000427f200520047c220c200c2005541b3703000240200241146a2802002201450d002001410c6c450d002006102e0b0240200241206a2802002201450d002001410c6c450d002007102e0b200341206a24000bb30b01087f230041f0026b220224002002428080808080203702dc02200220013602cc022002200041d4e2cc0020011b3602c8022002200241c8026a3602d802200241c8016a200241d8026a109902200241d4016a280200210320022802d001210420022802cc01210520022802c8012106200241e8006a200241d8016a41e00010e9081a024002402005450d00200241086a200241e8006a41e00010e9081a0240024020022802d8022802040d00200241e8006a200241086a41e00010e9081a0c010b02402003450d00200341246c21002005210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402004450d00200441246c450d002005102e0b410021050b2005450d00200241d4016a2003360200200241c8016a41086a2004360200200220053602cc01200220063602c801200241c8016a41106a200241e8006a41e00010e9082107200241b8026a200241c8016a41047210c7014102200110eb042002410036026841fcc6cb004110200241e8006a410410b201200241e8006a41186a22014200370300200241e8006a41106a22004200370300200241e8006a41086a2208420037030020024200370368200241086a41d9fcc60041061081022008200241086a41086a220929000037030020022002290008370368200241086a4180f4cb004106108102200120092900003703002000200229000837030020022006360208200241e8006a4120200241086a410410b201200241b8026a10ee04200710f0042006417f6a200710a40720014200370300200042003703002008420037030020024200370368200241086a41d9fcc60041061081022008200929000037030020022002290008370368200241086a41d4f2cb00410b1081022001200929000037030020002002290008370300200241e8006a412010ff01200241086a200241c8016a109a042001200241086a41186a2903003703002000200241086a41106a2903003703002008200929030037030020022002290308370368200241c8026a2006108c0220022802d002210020022802c80221014120102c2208450d01200242203702dc02200220083602d802200241d8026a200241e8006a412010742001200020022802d802220820022802e00210b201024020022802dc02450d002008102e0b024020022802cc02450d002001102e0b200610de0620022802b8022106024020022802c0022201450d00200141246c21002006210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b024020022802bc022201450d00200141246c450d002006102e0b02402003450d00200341246c21002005210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402004450d00200441246c450d002005102e0b200241f0026a240042010f0b200241146a410f360200200241dc016a4102360200200242023702cc01200241a0a7c9003602c8012002410436020c200241b8a9c9003602082002200241086a3602d8012002200241e8026a360210200241c8016a41b0a7c9001044000b1036000bab0102017f027e230041306b220224000240024020010d004104102c2201450d0120024204370204200220013602004100200210762002350208210320023502002104200241306a240020042003422086840f0b200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c200241d0a9c9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b1036000be10102017f027e230041306b220224000240024020010d004104102c2201450d012002420437020420022001360200410020021076200241003602182002200241186a41041074200241003602182002200241186a41041074200241003602182002200241186a410410742002350208210320023502002104200241306a240020042003422086840f0b200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c200241e4a9c9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b1036000bab0102017f027e230041306b220224000240024020010d004104102c2201450d0120024204370204200220013602004100200210762002350208210320023502002104200241306a240020042003422086840f0b200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c200241fca9c9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b1036000bcb0102017f027e230041306b2202240002400240200041d4e2cc0020011b200110fc0541ff01714103460d004101102c2201450d012002420137020420022001360200200241003a00182002200241186a410110742002350208210320023502002104200241306a240020042003422086840f0b200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c20024198aac9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b1036000bb210040d7f017e017f017e230041f0006b22022400200242808080808020370254200220013602642002200041d4e2cc0020011b22003602602002200241e0006a3602500240024002400240024002400240024020014104490d0020022001417c6a3602642002200041046a360260200241286a200241d0006a10e80120022802282203450d00200241306a2802002104200228022c2105200241206a200241d0006a10ad010240024020022802200d004104210620022802242207200228025022012802044104762200200020074b1b22084104742200417f4c0d0902402008450d002000102c2206450d050b2002200228025441016a22003602540240024002400240200020022802584b0d00024020070d00410021070c030b2007417f6a21094100210a4100210b024002400340200128020422004104490d022001280200220c280000210d20012000417c6a3602042001200c41046a360200200241186a200241d0006a10ad0120022802180d022001280204220c200228021c2200490d022000417f4c0d100240024020000d004101210e0c010b20001032220e450d0c2001280204210c0b200c2000490d01200e2001280200200010e908210c2001280204220e2000490d0c2001200e20006b3602042001200128020020006a360200200c450d02024002400240200b2008460d002008210e200b21080c010b200841016a22012008490d122008410174220e2001200e20014b1b22014104200141044b1b220141ffffffff0071200146410274210e200141047421010240024020080d00200241003602280c010b20022006360228200241043602302002200841047436022c0b200241c0006a2001200e200241286a107d2002280248210120022802404101460d01200228024421062001410476210e0b200620084104746a2201200c3602042001200d360200200141086a2000ad220f422086200f843702002009200b460d05200b41016a210b200a41106a210a20022802502101200e21080c010b0b20010d0a0c0f0b200e102e0b200b450d00200641086a2101034002402001280200450d002001417c6a280200102e0b200141106a2101200a41706a220a0d000b0b200841ffffffff00710d020c030b20022802542100200e21080b20022000417f6a3602542006450d01200228025021014100210b200241003a0040024020012802042200450d002001280200220c2d0000210d20012000417f6a3602042001200c41016a360200024002400240200d0e020100030b200241106a200241d0006a10ad0120022802100d022001280204220c20022802142200490d022000417f4c0d0d0240024020000d004101210b0c010b20001032220b450d092001280204210c0b200c2000490d01200b2001280200200010e908210c2001280204220d2000490d0a2001200d20006b3602042001200128020020006a360200200c450d022000ad220f422086200f84210f0b200fa72110200241086a200241d0006a10ad01024020022802080d002001280204220c200228020c2200490d002000417f4c0d0d0240024020000d004101210d0c010b20001032220d450d092001280204210c0b0240200c2000490d00200d2001280200200010e908210c2001280204220e2000490d0c2001200e20006b3602042001200128020020006a360200200c450d012000ad220f422086200f84a7210e0240200128020422004104490d0020012000417c6a220a36020420012001280200220941046a360200200a41034b0d070b200e450d010b200d102e0b200b450d012010450d010b200b102e0b02402007450d00200741047421004100210103400240200620016a220b41086a280200450d00200b41046a280200102e0b2000200141106a2201470d000b0b200841ffffffff0071450d010b2006102e0b02402004450d002004410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b2005450d012005410c6c450d012003102e0c010b2001200041786a3602042001200941086a3602002003450d002002280250280204450d0102402004450d002004410c6c21004100210103400240200320016a220d41046a280200450d00200d280200102e0b20002001410c6a2201470d000b0b02402005450d002005410c6c450d002003102e0b02402007450d0020074104742100200641086a2101034002402001280200450d002001417c6a280200102e0b200141106a2101200041706a22000d000b0b0240200841ffffffff0071450d002006102e0b0240200b450d002010450d00200b102e0b200e450d00200c102e0b200241cc006a410f3602002002413c6a41023602002002420237022c200241a0a7c90036022820024104360244200241bcaac9003602402002200241c0006a3602382002200241e8006a360248200241286a41b0a7c9001044000b02402004450d002004410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b02402005450d002005410c6c450d002003102e0b02402007450d0020074104742100200641086a2101034002402001280200450d002001417c6a280200102e0b200141106a2101200041706a22000d000b0b0240200841ffffffff0071450d002006102e0b0240200b450d002010450d00200b102e0b0240200e450d00200c102e0b4101102c22010d040b1036000b2000200e41b8b2c0001056000b2000200d41b8b2c0001056000b2000200e41b8b2c0001056000b2002420137022c20022001360228200241003a0040200241286a200241c0006a410110742002350230210f20023502282111200241f0006a24002011200f422086840f0b1038000bb70102017f027e230041306b220224000240024020010d004104102c2201450d012002420437020420022001360200200241003602182002200241186a410410742002350208210320023502002104200241306a240020042003422086840f0b200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c200241dcaac9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b1036000bba0102017f027e230041306b220224000240024020014104470d004101102c2201450d012002420137020420022001360200200241003a00182002200241186a410110742002350208210320023502002104200241306a240020042003422086840f0b200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c200241fcaac9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b1036000b950102017f017e230041306b220224000240200041d4e2cc0020011b200110fc0541ff01714103470d00200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c20024190abc9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b20024100360200200210ce042103200241306a240020030b910102017f017e230041306b220224000240024020014108470d002001417c714104470d010b200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c200241a8abc9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b20024100360200200210ce042103200241306a240020030be30303017f027e017f230041e0026b220224000240024020014104470d0020024100360284024101102c2201450d01200242013702c402200220013602c002200241003a00d702200241c0026a200241d7026a4101107420023502c002210320023502c802210402402002280284022201450d000240200228028c022205450d002005410c6c210503400240200141046a280200450d002001280200102e0b2001410c6a2101200541746a22050d000b0b02402002280288022201450d002001410c6c450d00200228028402102e0b024020024198026a2802002201450d002001410474210520024190026a28020041086a2101034002402001280200450d002001417c6a280200102e0b200141106a2101200541706a22050d000b0b024020024194026a28020041ffffffff0071450d00200228029002102e0b02402002419c026a2802002201450d00200241a0026a280200450d002001102e0b200241ac026a280200450d00200241a8026a280200102e0b200241e0026a240020044220862003840f0b200241cc026a410f360200200241146a410236020020024202370204200241a0a7c900360200200241043602c402200241ccabc9003602c0022002200241c0026a3602102002200241d8026a3602c802200241b0a7c9001044000b1036000bab0102017f027e230041306b220224000240024020010d004104102c2201450d0120024204370204200220013602004100200210762002350208210320023502002104200241306a240020042003422086840f0b200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c200241f4abc9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b1036000bae0102017f027e230041306b220224000240024020014104470d004104102c2201450d0120024204370204200220013602004100200210762002350208210320023502002104200241306a240020042003422086840f0b200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c2002418cacc9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b1036000bae0102017f027e230041306b220224000240024020014104470d004104102c2201450d0120024204370204200220013602004100200210762002350208210320023502002104200241306a240020042003422086840f0b200241246a410f360200200241146a410236020020024202370204200241a0a7c9003602002002410436021c200241a0acc9003602182002200241186a3602102002200241286a360220200241b0a7c9001044000b1036000bd30704067f017e017f037e230041f0006b22022400024002400240024020010d002002411436021c200241bcdac800360218200241206a41bcdac800411410ed0202400240024020022802202201450d00200228022421032002200241286a280200220436023c200220013602380240024002402004450d0020012d0000210520022004417f6a36023c2002200141016a3602382002200241386a10ab0102402002280200450d00200241003602500c010b200241d0006a200241386a200228020410990120022802502206450d004101210720022902542108200541ff01714101460d012008a72204450d00200441286c450d002006102e0b4100210720024100360210200242013703082002410a3602442002200241186a3602402002200241086a36024c41012104200241e4006a410136020020024201370254200241909dc5003602502002200241c0006a360260200241cc006a419cebc000200241d0006a103d1a2002280208200228021010ef020240200228020c450d002002280208102e0b0c010b2002200636022c200220083702302008422088a721052008a72109410021040b02402003450d002001102e0b2004450d010b200242003702304108210641002105410021090c010b20070d0020062802082205ad42287e2208422088a70d022008a72203417f4c0d02024020030d0041082106410021090c010b200628020021012003102c2206450d03200341286e210920034128490d00200621042009210703402003450d012007450d05200141086a2903002108200141106a290300210a2001290320210b2001290300210c200441186a200141186a290300370300200441106a200a370300200441086a20083703002004200c370300200441206a200b370300200441286a2104200341586a2103200141286a21012007417f6a22070d000b0b200541286c4104722201417f4c0d012001102c2204450d022002410036025820022001360254200220043602502005200241d0006a10760240200541286c2201450d00200620016a2104200621010340200241d0006a2001412010742002200141206a290300370308200241d0006a200241086a41081074200141286a22012004470d000b0b200235025821082002350250210a02402009450d00200941286c450d002006102e0b200241f0006a24002008422086200a840f0b200241146a410f360200200241e4006a410236020020024202370254200241a0a7c9003602502002410436020c200241c8acc9003602082002200241086a3602602002200241e8006a360210200241d0006a41b0a7c9001044000b1038000b1036000b200920094188decc00103c000bb80804017f027e027f017e230041f0076b220224002002428080808080203702cc07200220013602dc072002200041d4e2cc0020011b3602d8072002200241d8076a3602c80720024180046a200241c8076a10cb06024020022903880422034202510d00200229038004210420024180026a20024190046a41f00110e9081a200241086a200241c8076a10ad0120022802080d0020022802dc072200200228020c2201490d0002400240024002402001417f4c0d000240024020010d00410121050c010b200110322205450d0420022802dc0721000b0240024020002001490d00200520022802d807200110e908210020022802dc07220520014f0d012001200541b8b2c0001056000b2005102e0c050b2002200520016b22053602dc07200220022802d80720016a3602d807200241106a20024180026a41f00110e9081a2005450d01420221032001450d022000102e0c020b1038000b20024180046a200241106a41f00110e9081a0b20034202510d01200241106a20024180046a41f00110e9081a20024180026a200241106a41f00110e9081a200220013602dc07200220003602d80720024180046a200241d8076a10f7010240024020022802840422050d00410021050c010b200241d0076a20024190046a28020036020020022002290388043703c80720022802800421060b02402001450d002000102e0b20024180046a41086a2200200241c8076a41086a2201280200360200200220022903c80737038004024002402005450d00200241f0036a41086a20002802002200360200200220022903800422073703f003200241a8056a2005360200200241a4056a2006360200200241a0056a4102360200200241ac056a2007370200200241b4056a2000360200200241c0056a2003370300200241b8056a20043703002002410a36029805200242023703e804200241c8056a20024180026a41f00110e9081a200241c0076a2001290300370300200241b8076a20022903c807370300200220024180046a3602c807200241d8076a200241c8076a1090052001200241d8076a41086a280200360200200220022903d8073703c807200241c8076a10e8061a024020022903e8044202510d0020022d00800441ff01714102470d00200228028804450d00200228028404102e0b20024198056a108b02410121010c010b410021010b4101102c2200450d00200242013702840420022000360280040240024020010d00200241003a00800220024180046a20024180026a410110740c010b200241013a00800220024180046a20024180026a410110740b20023502880421032002350280042104200241f0076a240020042003422086840f0b1036000b2002411c6a410f36020020024194026a41023602002002420237028402200241a0a7c9003602800220024104360214200241e4acc9003602102002200241106a360290022002200241e8076a36021820024180026a41b0a7c9001044000b902508047f017e037f017e027f027e0f7f037e230041d0056b22022400024020014108490d00200241003a008004200041d4e2cc0020011b41086a2103200141786a2104410021010340200241003a008801024020042001470d00200141ff0171450d02200241003a0080040c020b200241e0036a20016a200320016a2d00003a00002002200141016a22003a0080042000210120004120470d000b20024188016a41186a2201200241e0036a41186a29030037030020024188016a41106a2203200241e0036a41106a29030037030020024188016a41086a2205200241e0036a41086a290300370300200220022903e00337038801200041ff01714120490d00200241286a41086a2005290300370300200241286a41106a2003290300370300200241286a41186a2001290300370300200220022903880122063703482002200637032820042000470d00200241e0036a41186a2205200241286a41186a22072903002206370300200241e0036a41106a2208200241286a41106a2209290300220a3703004108210b200241e0036a41086a2204200241286a41086a220c290300220d37030020022002290328220e3703e003200241086a41186a2006370300200241086a41106a200a370300200241086a41086a200d3703002002200e370308200241e8006a41186a2006370300200241e8006a41106a200a370300200241e8006a41086a200d3703002002200e3703682007420037030020094200370300200c420037030020024200370328200241e0036a41a081ca004107108102200c2004290000370300200220022900e003370328200241e0036a41e4d1c100410c10810220072004290000370300200920022900e0033703002002200241286a4120108e022002280204210f200228020021102007420037030020094200370300200c420037030020024200370328200241e0036a41a081ca004107108102200c2004290000370300200220022900e003370328200241e0036a41f09dc500410a10810220072004290000370300200920022900e003370300200241e0036a200241286a10880320022802e0032201410120011b211120022902e403420020011b2206a72112024002400240024002400240024002402006422088a72201450d002011200141057422136a2114200241bc056a2115200241e0036a41206a2100201121010340200241b8036a41186a2203200141186a2216290000370300200241b8036a41106a2217200141106a2218290000370300200241b8036a41086a2219200141086a221a290000370300200220012900003703b803200241c8006a41086a221b201a290000370300200241c8006a41106a221a2018290000370300200241c8006a41186a2218201629000037030020022001290000370348200520032903003703002008201729030037030020042019290300370300200220022903b8033703e00320024198056a200241e0036a10bf01200720182903003703002009201a290300370300200c201b290300370300200220022903483703280240024020022802b80522030d00410021030c010b2000200229039805370300200041186a20024198056a41186a290300370300200041106a20024198056a41106a290300370300200041086a20024198056a41086a29030037030020052007290300370300200820092903003703002004200c29030037030020024188056a41086a201541086a280200360200200220022903283703e003200220152902003703880520024188016a41386a200241e0036a41386a29030037030020024188016a41306a200241e0036a41306a29030037030020024188016a41286a200241e0036a41286a29030037030020024188016a41206a200029030037030020024188016a41186a200529030037030020024188016a41106a200829030037030020024188016a41086a2004290300370300200220022903e003370388010b20030d02200141206a2101201341606a22130d000b0b0240201241ffffff3f71450d002011102e0b41002118410021190c010b20024188026a41386a220020024188016a41386a29030037030020024188026a41306a220420024188016a41306a29030037030020024188026a41286a220520024188016a41286a29030037030020024188026a41206a220820024188016a41206a29030037030020024188026a41186a220720024188016a41186a29030037030020024188026a41106a220920024188016a41106a29030037030020024188026a41086a220c20024188016a41086a290300370300200241e8046a41086a221620024188056a41086a28020036020020022002290388013703880220022002290388053703e804200241e0026a41086a2217200c290300370300200241e0026a41106a220c2009290300370300200241e0026a41186a22092007290300370300200241e0026a41206a22072008290300370300200241e0026a41286a22082005290300370300200241e0026a41306a22052004290300370300200241e0026a41386a22042000290300370300200241f8046a41086a2200201628020036020020022002290388023703e002200220022903e8043703f80441d000102c220b450d05200b20022903e002370300200b2003360240200b20022903f804370244200b41386a2004290300370300200b41306a2005290300370300200b41286a2008290300370300200b41206a2007290300370300200b41186a2009290300370300200b41106a200c290300370300200b41086a2017290300370300200b41cc006a20002802003602000240024020134120470d0041012119410121180c010b200141206a2109201441606a211a200241bc056a2117200241e0036a41206a210041012119410121180340200921010340200241b8036a41186a2204200141186a2203290000370300200241b8036a41106a2208200141106a2205290000370300200241b8036a41086a2207200141086a2209290000370300200220012900003703b803200241c8006a41186a220c2003290000370300200241c8006a41106a22132005290000370300200241c8006a41086a2216200929000037030020022001290000370348200241e0036a41186a22032004290300370300200241e0036a41106a22052008290300370300200241e0036a41086a22082007290300370300200220022903b8033703e00320024198056a200241e0036a10bf01200241286a41186a2207200c290300370300200241286a41106a22092013290300370300200241286a41086a220c2016290300370300200220022903483703280240024020022802b80522040d00410021040c010b2000200229039805370300200041186a20024198056a41186a290300370300200041106a20024198056a41106a290300370300200041086a20024198056a41086a29030037030020032007290300370300200520092903003703002008200c29030037030020024188056a41086a201741086a280200360200200220022903283703e003200220172902003703880520024188016a41386a200241e0036a41386a29030037030020024188016a41306a200241e0036a41306a29030037030020024188016a41286a200241e0036a41286a29030037030020024188016a41206a200029030037030020024188016a41186a200329030037030020024188016a41106a200529030037030020024188016a41086a2008290300370300200220022903e003370388010b024020040d002014200141206a2201470d010c030b0b20024188026a41386a220720024188016a41386a29030037030020024188026a41306a220920024188016a41306a29030037030020024188026a41286a220c20024188016a41286a29030037030020024188026a41206a221320024188016a41206a29030037030020024188026a41186a221620024188016a41186a29030037030020024188026a41106a221b20024188016a41106a29030037030020024188026a41086a221520024188016a41086a290300370300200241e8046a41086a221c20024188056a41086a28020036020020022002290388013703880220022002290388053703e804200241e0026a41086a221d2015290300370300200241e0026a41106a2215201b290300370300200241e0026a41186a221b2016290300370300200241e0026a41206a22162013290300370300200241e0026a41286a2213200c290300370300200241e0026a41306a220c2009290300370300200241e0026a41386a22092007290300370300200241f8046a41086a2207201c28020036020020022002290388023703e002200220022903e8043703f8042008201d290300370300200520152903003703002003201b29030037030020002016290300370300200241e0036a41286a22162013290300370300200241e0036a41306a2213200c290300370300200241e0036a41386a220c2009290300370300200220022903e0023703e00320024198056a41086a221b2007280200360200200220022903f80437039805024020182019470d00201941016a22072019490d07201941017422092007200920074b1b22074104200741044b1bad42d0007e2206422088a74541037421072006a721090240024020190d0020024100360288010c010b20024108360290012002200b360288012002201941d0006c36028c010b20024188026a2009200720024188016a107d20022802900221072002280288024101460d04200228028c02210b200741d0006e21190b200141206a2109200b201841d0006c6a220720022903e003370300200529030021062003290300210a2000290300210d2016290300210e2013290300211e200c290300211f2008290300212020072004360240200741086a2020370300200741386a201f370300200741306a201e370300200741286a200e370300200741206a200d370300200741186a200a370300200741106a20063703002007200229039805370244200741cc006a201b280200360200201841016a2118201a2001470d000b0b201241ffffff3f71450d002011102e0b200220183602a0052002201936029c052002200b36029805200241e0036a20024198056a10a30341002101024020022802e0034101460d00200241b8036a41206a20024188046a280200360200200241b8036a41186a200241e0036a41206a290300370300200241b8036a41106a200241e0036a41186a290300370300200241b8036a41086a200241e0036a41106a2903003703002002200241e0036a41086a2903003703b8032002418c046a2802002101200241e0026a20024190046a41d80010e9081a0b20024198056a41086a2200200241b8036a41086a29030037030020024198056a41106a2204200241b8036a41106a29030037030020024198056a41186a2203200241b8036a41186a29030037030020024198056a41206a2205200241b8036a41206a280200360200200220022903b80337039805200241e0036a200241e0026a41d80010e9081a02402001450d0020024188016a41206a200528020036020020024188016a41186a200329030037030020024188016a41106a200429030037030020024188016a41086a200029030037030020022002290398053703880120024188026a200241e0036a41d80010e9081a200241ac016a2001360200200241b0016a20024188026a41d80010e9081a200241e0036a41186a200241e8006a41186a290300370300200241e0036a41106a200241e8006a41106a290300370300200241e0036a41086a200241e8006a41086a290300370300200220022903683703e003200241e0026a20024188016a41e7e485f306200241e0036a10e40720022902e402210620022802e002210420024188016a10b80220040d020b4100210120024100360288010c020b2007450d020c030b200241e8036a2006370300200220183602f003200220043602e4032002200f410020101b3602e00320024188016a200241e0036a1097022006a7210302402006422088a72201450d002001410c6c21002004210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b02402003450d002003410c6c450d002004102e0b024020022802880122010d00410021010c010b20024190016a2802002100200228028c0121030b4101102c2204450d01200242013702e403200220043602e0030240024020010d00200241003a008801200241e0036a20024188016a410110740c010b200241013a008801200241e0036a20024188016a410110742000200241e0036a1076200241e0036a2001200010740b20023502e803210620023502e003210a02402001450d002003450d002001102e0b200241d0056a24002006422086200a840f0b1038000b1036000b20024194016a410f360200200241f4036a4102360200200242023702e403200241a0a7c9003602e0032002410436028c012002419cadc90036028801200220024188016a3602f0032002200241c8056a36029001200241e0036a41b0a7c9001044000b891003037f017e067f230041e0016b220424000240024002400240024002400240024002400240200141e0006a22052001413c6a412010ec08450d00200441d0006a41186a200541186a290000370300200441d0006a41106a200541106a290000370300200441d0006a41086a200541086a2900003703002004200529000037035002402001200441d0006a10af022206450d00200628020c41004a0d010b200441206a41086a2201200541086a290000370300200441206a41106a2203200541106a290000370300200441206a41186a2202200541186a290000370300200420052900003703204130102c2205450d01200541003a00002005200429032037000120052004290050370021200541096a2001290300370000200541116a2003290300370000200541196a2002290300370000200541286a2201200441d7006a2900003700000240024020052d00000e040a0a000a010b200541086a280200450d09200541046a280200102e0c090b2001280200450d08200541246a280200102e0c080b2004410036020c20042005360208200441bc81ca0036020420042001360200200442003703182004420437031020044188016a4120360200200420033602840120042002360280014124102c2205450d00200442243702a401200420053602a001200441a0016a20044180016a410410744120200441a0016a1076200441a0016a200341201074200441d0006a200420042802a001220120042802a801200441106a10a702024002400240024020042802504101470d0002400240200428025422052d00000e0403030003010b200541086a280200450d02200541046a280200102e0c020b200541286a280200450d01200541246a280200102e0c010b20042802542202450d0102400240200441d8006a2903002207422088a741044f0d00410021050c010b20022800002103410121050b2007a7450d022002102e0c020b2005102e0b410021050b024020042802a401450d002001102e0b0240024002402005450d0020042003360244200441d0006a2004200441c4006a4104200441106a10a702024020042802504101470d0002400240200428025422052d00000e040a0a000a010b200541086a280200450d09200541046a280200102e0c090b200541286a280200450d08200541246a280200102e0c080b20042802542202450d08200441d8006a29030021072004200236024820042007422088a7220636024c41002105200441003a00702006417f6a210102400240034020062005460d01200441d0006a20056a200220056a22032d00003a00002004200341016a3602482004200541016a22033a00702004200136024c2001417f6a21012003210520034120470d000b200441a0016a41086a2205200441d0006a41086a290300370300200441a0016a41106a2201200441d0006a41106a290300370300200441a0016a41186a2206200441d0006a41186a290300370300200420042903503703a001200341ff0171411f4b0d010c030b200541ff0171450d02200441003a0070410021050c030b200441206a41086a2005290300370300200441206a41106a2001290300370300200441206a41186a2006290300370300200420042903a001370320200441d0006a200441c8006a10850520042802702205450d01200441f4006a28020021010c020b200041003602000c080b410021050b02402007a7450d002002102e0b2005450d0502402001450d00200141306c450d002005102e0b2004280214210820042802102109200442043703102004280218210620044100360218200641306c220a41306d2202ad420c7e2207422088a70d032007a72201417f4c0d034104210502402001450d002001102c2205450d010b2000200536020041002103200041086a4100360200200041046a2001410c6e220b36020002400240200b20024f0d00200b410174220c2002200c20024b1b220c4104200c41044b1bad420c7e2207422088a745410274210c2007a7210d024002402001410b4b0d00200441003602500c010b200441d8006a4104360200200420053602502004200b410c6c3602540b200441a0016a200d200c200441d0006a107d200441a8016a280200210120042802a0014101460d01200020042802a4012205360200200041046a2001410c6e3602000b20060d02200921010c030b2001450d030b1036000b2009200a6a210a200641306c2102200941306a2101200641047441706a41047641016a210b4100210302400340200141546a2802002206450d01200541046a200141586a290200370200200520063602002005410c6a2105200141306a2101200341016a2103200241506a22020d000b200a2101200b21030b200a20016b220a41306d21020b200041086a20033602000240200a450d00200241306c2103200141086a2105034002402005280200450d002005417c6a280200102e0b200541306a2105200341506a22030d000b0b02402008450d00200841306c450d002009102e0b20042802102103024020042802182205450d00200541306c2101200341086a2105034002402005280200450d002005417c6a280200102e0b200541306a2105200141506a22010d000b0b20042802142205450d05200541306c450d052003102e0c050b1038000b2005102e0b200041003602000b20042802102103024020042802182205450d00200541306c2101200341086a2105034002402005280200450d002005417c6a280200102e0b200541306a2105200141506a22010d000b0b20042802142205450d01200541306c450d012003102e0c010b2005102e200041003602000b200441e0016a24000b8c0804057f017e037f017e230041c0016b22022400024020010d0020024198016a41186a2203420037030020024198016a41106a2204420037030020024198016a41086a220542003703002002420037039801200241f0006a41a8f8c60041041081022005200241f0006a41086a22012900003703002002200229007037039801200241f0006a41a58bc500410b1081022003200129000037030020042002290070370300200220024198016a10a2042002280200210620022902042107200241186a22084200370300200241106a22094200370300200241086a220a420037030020024200370300200241f0006a41a8f8c6004104108102200a200129000037030020022002290070370300200241f0006a41c28cc500410a1081022008200129000037030020092002290070370300200241f0006a200210a30420022d00702101200320024189016a290000370300200420024181016a2900003703002005200241f9006a29000037030020022002290071370398012007420020061b21072006410820061b21080240024020014101460d00200241d0006a41186a4200370300200241d0006a41106a4200370300200241d0006a41086a4200370300200242003703500c010b200241d0006a41186a2003290300370300200241d0006a41106a2004290300370300200241d0006a41086a200529030037030020022002290398013703500b200241246a2007370200200241186a4204370300200241346a200241d0006a41086a2903003702002002413c6a200241e0006a290300370200200241c4006a200241d0006a41186a29030037020020024201370310200242e012370308200242f02e3703002002200229035037022c200241023a004c200220083602202002410036027820024201370370200242f02e37039801200241f0006a20024198016a41081074200242e01237039801200241f0006a20024198016a410810742002420137039801200241f0006a20024198016a410810742002420437039801200241f0006a20024198016a410810742007422088a72201200241f0006a10762007a721030240200141286c2201450d00200820016a2106200821010340200241f0006a2001412010742002200141206a29030037039801200241f0006a20024198016a41081074200141286a22012006470d000b0b200241f0006a2002412c6a41201074200241023a009801200241f0006a20024198016a41011074200235027021072002350278210b02402003450d00200341286c450d002008102e0b200241c0016a2400200b4220862007840f0b200241fc006a410f360200200241146a410236020020024202370204200241a0a7c90036020020024104360274200241c0adc9003602702002200241f0006a3602102002200241b8016a360278200241b0a7c9001044000b820402047f027e230041f0006b22022400024002400240024020010d00200241d0006a22014200370300200241c8006a22034200370300200241386a41086a2204420037030020024200370338200241386a41a8f8c6004104108102200241d8006a41fa8bc500410a1081022001200241d8006a41086a220529000037030020032002290058370300200241286a200241386a108503200241186a2002290330420020022802281b420042e012420010e808200229032050450d012002290318210620014200370300200342003703002004420037030020024200370338200241386a41a8f8c6004104108102200241d8006a41e38bc500410b1081022001200529000037030020032002290058370300200241086a200241386a10850320062002290310420020022802081b7c22072006540d024108102c2201450d032002420837023c2002200136023820022007370358200241386a200241d8006a410810742002350240210620023502382107200241f0006a240020072006422086840f0b200241e4006a410f360200200241cc006a41023602002002420237023c200241a0a7c9003602382002410436025c200241d8adc9003602582002200241d8006a3602482002200241e8006a360260200241386a41b0a7c9001044000b41e8b2c40041fa0041e4b3c400105d000b41e8b2c40041fa0041f4b3c400105d000b1036000be10c04047f017e037f027e23004190026b22022400024002400240024020010d00200241e8016a41186a22034200370300200241e8016a41106a22014200370300200241e8016a41086a22044200370300200242003703e801200241c8006a41a8f8c60041041081022004200241c8006a41086a2205290000370300200220022900483703e801200241c8006a41fa8bc500410a1081022003200529000037030020012002290048370300200241386a200241e8016a1085032002290340210620022802382107200241c8006a41186a22084200370300200241c8006a41106a220942003703002005420037030020024200370348200241c8006a41a8f8c6004104108102200241e8016a41fa8bc500410a10810220082004290000370300200920022900e801370300200241286a200241c8006a108503200241186a2002290330420020022802281b420042e012420010e808200229032050450d012002290318210a200342003703002001420037030020044200370300200242003703e801200241c8006a41a8f8c600410410810220042005290000370300200220022900483703e801200241c8006a41e38bc500410b108102200141086a200529000037000020012002290048370000200241086a200241e8016a108503200a2002290310420020022802081b7c220b200a540d02200241e8016a41186a22054200370300200241e8016a41106a22034200370300200241e8016a41086a22044200370300200242003703e801200241c8006a41a8f8c60041041081022004200241c8006a41086a2208290000370300200220022900483703e801200241c8006a41a58bc500410b108102200141086a200829000037000020012002290048370000200241c8006a200241e8016a10a20420022802482109200229024c210a200542003703002003420037030020044200370300200242003703e801200241c8006a41a8f8c600410410810220042008290000370300200220022900483703e801200241c8006a41c28cc500410a1081022005200829000037030020032002290048370300200241c8006a200241e8016a10a30420022d004821082005200241e1006a2900003703002003200241d9006a2900003703002004200241d1006a290000370300200220022900493703e8010240024020084101460d00200241a8016a41186a4200370300200241a8016a41106a4200370300200241a8016a41086a4200370300200242003703a8010c010b200241a8016a41186a2005290300370300200241a8016a41106a2003290300370300200241a8016a41086a2004290300370300200220022903e8013703a8010b200241e8016a41186a4200370300200241e8016a41106a4200370300200241e8016a41086a22044200370300200242003703e801200241c8006a41a8f8c60041041081022004200241c8006a41086a2205290000370300200220022900483703e801200241c8006a418c8bc500410b108102200141086a200529000037000020012002290048370000200241c8006a200241e8016a10b005200241d8016a41086a22012005290300370300200220022903483703d801200220022800593602d0012002200241dc006a2800003600d30120022d005822054103460d0320042001290300370300200241fc006a200a420020091b220a3702002002418c016a200241a8016a41086a29030037020020024194016a200241a8016a41106a2903003702002002419c016a200241a8016a41186a290300370200200220022903d8013703e801200220022802d0013602c801200220022800d3013600cb0120022009410820091b2203360278200242e0123703582002200b37035020022006420020071b370348200220022903a80137028401200241e8006a2004290300370300200220022903e801370360200241c8006a41286a20053a0000200241f4006a20022800cb01360000200241f1006a20022802c801360000200241c8006a10cf0421060240200aa72201450d00200141286c450d002003102e0b20024190026a240020060f0b200241f4016a410f360200200241dc006a41023602002002420237024c200241a0a7c900360248200241043602ec01200241f4adc9003602e8012002200241e8016a360258200220024188026a3602f001200241c8006a41b0a7c9001044000b41e8b2c40041fa0041e4b3c400105d000b41e8b2c40041fa0041f4b3c400105d000b41a8b6c40041c8004180b7c400105d000bde0d05047f027e027f017e047f23004190026b220224000240024002400240024020010d0020024180026a22034200370300200241f8016a22014200370300200241e8016a41086a22044200370300200242003703e801200241306a41a8f8c60041041081022004200241306a41086a2205290000370300200220022900303703e801200241306a41fa8bc500410a1081022003200529000037030020012002290030370300200241206a200241e8016a1085032002290328420020022802201b220642017c22072006540d01200241106a2007420042e012420010e808200229031850450d022002290310210620024180026a22054200370300200241f8016a22084200370300200241e8016a41086a22034200370300200242003703e801200241306a41a8f8c60041041081022003200241306a41086a2204290000370300200220022900303703e801200241306a41e38bc500410b108102200141086a22092004290000370000200120022900303700002002200241e8016a10850320062002290308420020022802001b7c220a2006540d03200542003703002008420037030020034200370300200242003703e801200241306a41a8f8c600410410810220032004290000370300200220022900303703e801200241306a41ba8bc500410f1081022009200429000037000020012002290030370000200241306a200241e8016a10a2042002280230210920022902342106200542003703002008420037030020034200370300200242003703e801200241306a41a8f8c600410410810220032004290000370300200220022900303703e801200241306a41978bc500410e1081022005200429000037030020082002290030370300200241306a200241e8016a10a30420022d003021042005200241c9006a2900003703002008200241c1006a2900003703002003200241396a290000370300200220022900313703e8010240024020044101460d00200241a8016a4200370300200241a0016a420037030020024198016a420037030020024200370390010c010b20024190016a41186a200241e8016a41186a29030037030020024190016a41106a200241e8016a41106a29030037030020024190016a41086a200241e8016a41086a290300370300200220022903e801370390010b20024180026a22084200370300200241f8016a220b4200370300200241e8016a41086a22044200370300200242003703e801200241306a41a8f8c60041041081022004200241306a41086a2203290000370300200220022900303703e801200241306a41d48bc500410f108102200141086a220c200329000037000020012002290030370000200241306a200241e8016a10b005200241c0016a41086a220d2003290300370300200220022903303703c001200220022800413602b8012002200241c4006a220e2800003600bb010240024020022d004022054103470d0020084200370300200b420037030020044200370300200242003703e801200241306a41a8f8c600410410810220042003290000370300200220022900303703e801200241306a418c8bc500410b108102200c200329000037000020012002290030370000200241306a200241e8016a10b005200241d8016a41086a2003290300370300200220022903303703d801200220022800413602d0012002200e2800003600d30120022d004022054103460d06200241e8016a41086a200241d8016a41086a290300370300200220022903d8013703e801200220022802d0013602b001200220022800d3013600b3010c010b2004200d290300370300200220022903c0013703e801200220022802b8013602b001200220022800bb013600b3010b200241e4006a2006420020091b2206370200200241f4006a20024190016a41086a290300370200200241fc006a200241a0016a29030037020020024184016a200241a8016a290300370200200241d0006a200241e8016a41086a29030037030020022009410820091b2203360260200242e0123703402002200a37033820022007370330200220022903900137026c200220022903e801370348200241306a41286a20053a0000200241d9006a20022802b001360000200241dc006a20022800b301360000200241306a10cf04210702402006a72201450d00200141286c450d002003102e0b20024190026a240020070f0b200241f4016a410f360200200241c4006a410236020020024202370234200241a0a7c900360230200241043602ec012002418caec9003602e8012002200241e8016a360240200220024188026a3602f001200241306a41b0a7c9001044000b41a8b5c40041ef004198b6c400105d000b41e8b2c40041fa0041e4b3c400105d000b41e8b2c40041fa0041f4b3c400105d000b41a8b6c40041c80041f0b6c400105d000b902508047f017e037f017e027f027e0f7f037e230041d0056b22022400024020014108490d00200241003a008004200041d4e2cc0020011b41086a2103200141786a2104410021010340200241003a008801024020042001470d00200141ff0171450d02200241003a0080040c020b200241e0036a20016a200320016a2d00003a00002002200141016a22003a0080042000210120004120470d000b20024188016a41186a2201200241e0036a41186a29030037030020024188016a41106a2203200241e0036a41106a29030037030020024188016a41086a2205200241e0036a41086a290300370300200220022903e00337038801200041ff01714120490d00200241286a41086a2005290300370300200241286a41106a2003290300370300200241286a41186a2001290300370300200220022903880122063703482002200637032820042000470d00200241e0036a41186a2205200241286a41186a22072903002206370300200241e0036a41106a2208200241286a41106a2209290300220a3703004108210b200241e0036a41086a2204200241286a41086a220c290300220d37030020022002290328220e3703e003200241086a41186a2006370300200241086a41106a200a370300200241086a41086a200d3703002002200e370308200241e8006a41186a2006370300200241e8006a41106a200a370300200241e8006a41086a200d3703002002200e3703682007420037030020094200370300200c420037030020024200370328200241e0036a41a081ca004107108102200c2004290000370300200220022900e003370328200241e0036a41e4d1c100410c10810220072004290000370300200920022900e0033703002002200241286a4120108e022002280204210f200228020021102007420037030020094200370300200c420037030020024200370328200241e0036a41a081ca004107108102200c2004290000370300200220022900e003370328200241e0036a41f09dc500410a10810220072004290000370300200920022900e003370300200241e0036a200241286a10880320022802e0032201410120011b211120022902e403420020011b2206a72112024002400240024002400240024002402006422088a72201450d002011200141057422136a2114200241bc056a2115200241e0036a41206a2100201121010340200241b8036a41186a2203200141186a2216290000370300200241b8036a41106a2217200141106a2218290000370300200241b8036a41086a2219200141086a221a290000370300200220012900003703b803200241c8006a41086a221b201a290000370300200241c8006a41106a221a2018290000370300200241c8006a41186a2218201629000037030020022001290000370348200520032903003703002008201729030037030020042019290300370300200220022903b8033703e00320024198056a200241e0036a10bf01200720182903003703002009201a290300370300200c201b290300370300200220022903483703280240024020022802b80522030d00410021030c010b2000200229039805370300200041186a20024198056a41186a290300370300200041106a20024198056a41106a290300370300200041086a20024198056a41086a29030037030020052007290300370300200820092903003703002004200c29030037030020024188056a41086a201541086a280200360200200220022903283703e003200220152902003703880520024188016a41386a200241e0036a41386a29030037030020024188016a41306a200241e0036a41306a29030037030020024188016a41286a200241e0036a41286a29030037030020024188016a41206a200029030037030020024188016a41186a200529030037030020024188016a41106a200829030037030020024188016a41086a2004290300370300200220022903e003370388010b20030d02200141206a2101201341606a22130d000b0b0240201241ffffff3f71450d002011102e0b41002118410021190c010b20024188026a41386a220020024188016a41386a29030037030020024188026a41306a220420024188016a41306a29030037030020024188026a41286a220520024188016a41286a29030037030020024188026a41206a220820024188016a41206a29030037030020024188026a41186a220720024188016a41186a29030037030020024188026a41106a220920024188016a41106a29030037030020024188026a41086a220c20024188016a41086a290300370300200241e8046a41086a221620024188056a41086a28020036020020022002290388013703880220022002290388053703e804200241e0026a41086a2217200c290300370300200241e0026a41106a220c2009290300370300200241e0026a41186a22092007290300370300200241e0026a41206a22072008290300370300200241e0026a41286a22082005290300370300200241e0026a41306a22052004290300370300200241e0026a41386a22042000290300370300200241f8046a41086a2200201628020036020020022002290388023703e002200220022903e8043703f80441d000102c220b450d05200b20022903e002370300200b2003360240200b20022903f804370244200b41386a2004290300370300200b41306a2005290300370300200b41286a2008290300370300200b41206a2007290300370300200b41186a2009290300370300200b41106a200c290300370300200b41086a2017290300370300200b41cc006a20002802003602000240024020134120470d0041012119410121180c010b200141206a2109201441606a211a200241bc056a2117200241e0036a41206a210041012119410121180340200921010340200241b8036a41186a2204200141186a2203290000370300200241b8036a41106a2208200141106a2205290000370300200241b8036a41086a2207200141086a2209290000370300200220012900003703b803200241c8006a41186a220c2003290000370300200241c8006a41106a22132005290000370300200241c8006a41086a2216200929000037030020022001290000370348200241e0036a41186a22032004290300370300200241e0036a41106a22052008290300370300200241e0036a41086a22082007290300370300200220022903b8033703e00320024198056a200241e0036a10bf01200241286a41186a2207200c290300370300200241286a41106a22092013290300370300200241286a41086a220c2016290300370300200220022903483703280240024020022802b80522040d00410021040c010b2000200229039805370300200041186a20024198056a41186a290300370300200041106a20024198056a41106a290300370300200041086a20024198056a41086a29030037030020032007290300370300200520092903003703002008200c29030037030020024188056a41086a201741086a280200360200200220022903283703e003200220172902003703880520024188016a41386a200241e0036a41386a29030037030020024188016a41306a200241e0036a41306a29030037030020024188016a41286a200241e0036a41286a29030037030020024188016a41206a200029030037030020024188016a41186a200329030037030020024188016a41106a200529030037030020024188016a41086a2008290300370300200220022903e003370388010b024020040d002014200141206a2201470d010c030b0b20024188026a41386a220720024188016a41386a29030037030020024188026a41306a220920024188016a41306a29030037030020024188026a41286a220c20024188016a41286a29030037030020024188026a41206a221320024188016a41206a29030037030020024188026a41186a221620024188016a41186a29030037030020024188026a41106a221b20024188016a41106a29030037030020024188026a41086a221520024188016a41086a290300370300200241e8046a41086a221c20024188056a41086a28020036020020022002290388013703880220022002290388053703e804200241e0026a41086a221d2015290300370300200241e0026a41106a2215201b290300370300200241e0026a41186a221b2016290300370300200241e0026a41206a22162013290300370300200241e0026a41286a2213200c290300370300200241e0026a41306a220c2009290300370300200241e0026a41386a22092007290300370300200241f8046a41086a2207201c28020036020020022002290388023703e002200220022903e8043703f8042008201d290300370300200520152903003703002003201b29030037030020002016290300370300200241e0036a41286a22162013290300370300200241e0036a41306a2213200c290300370300200241e0036a41386a220c2009290300370300200220022903e0023703e00320024198056a41086a221b2007280200360200200220022903f80437039805024020182019470d00201941016a22072019490d07201941017422092007200920074b1b22074104200741044b1bad42d0007e2206422088a74541037421072006a721090240024020190d0020024100360288010c010b20024108360290012002200b360288012002201941d0006c36028c010b20024188026a2009200720024188016a107d20022802900221072002280288024101460d04200228028c02210b200741d0006e21190b200141206a2109200b201841d0006c6a220720022903e003370300200529030021062003290300210a2000290300210d2016290300210e2013290300211e200c290300211f2008290300212020072004360240200741086a2020370300200741386a201f370300200741306a201e370300200741286a200e370300200741206a200d370300200741186a200a370300200741106a20063703002007200229039805370244200741cc006a201b280200360200201841016a2118201a2001470d000b0b201241ffffff3f71450d002011102e0b200220183602a0052002201936029c052002200b36029805200241e0036a20024198056a10a30341002101024020022802e0034101460d00200241b8036a41206a20024188046a280200360200200241b8036a41186a200241e0036a41206a290300370300200241b8036a41106a200241e0036a41186a290300370300200241b8036a41086a200241e0036a41106a2903003703002002200241e0036a41086a2903003703b8032002418c046a2802002101200241e0026a20024190046a41d80010e9081a0b20024198056a41086a2200200241b8036a41086a29030037030020024198056a41106a2204200241b8036a41106a29030037030020024198056a41186a2203200241b8036a41186a29030037030020024198056a41206a2205200241b8036a41206a280200360200200220022903b80337039805200241e0036a200241e0026a41d80010e9081a02402001450d0020024188016a41206a200528020036020020024188016a41186a200329030037030020024188016a41106a200429030037030020024188016a41086a200029030037030020022002290398053703880120024188026a200241e0036a41d80010e9081a200241ac016a2001360200200241b0016a20024188026a41d80010e9081a200241e0036a41186a200241e8006a41186a290300370300200241e0036a41106a200241e8006a41106a290300370300200241e0036a41086a200241e8006a41086a290300370300200220022903683703e003200241e0026a20024188016a41e2c289ab06200241e0036a10e40720022902e402210620022802e002210420024188016a10b80220040d020b4100210120024100360288010c020b2007450d020c030b200241e8036a2006370300200220183602f003200220043602e4032002200f410020101b3602e00320024188016a200241e0036a1097022006a7210302402006422088a72201450d002001410c6c21002004210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b02402003450d002003410c6c450d002004102e0b024020022802880122010d00410021010c010b20024190016a2802002100200228028c0121030b4101102c2204450d01200242013702e403200220043602e0030240024020010d00200241003a008801200241e0036a20024188016a410110740c010b200241013a008801200241e0036a20024188016a410110742000200241e0036a1076200241e0036a2001200010740b20023502e803210620023502e003210a02402001450d002003450d002001102e0b200241d0056a24002006422086200a840f0b1038000b1036000b20024194016a410f360200200241f4036a4102360200200242023702e403200241a0a7c9003602e0032002410436028c012002419cadc90036028801200220024188016a3602f0032002200241c8056a36029001200241e0036a41b0a7c9001044000be115020a7f027e230041d00b6b2202240020024280808080802037020c2002200136021c2002200041d4e2cc0020011b3602182002200241186a36020820024180086a200241086a1098020240024002400240024002402002418c086a2802002203450d00200241f0076a41086a20024180086a41086a28020036020020022002290380083703f00720024190086a280200210420024194086a280200210520024188076a20024198086a41e40010e9081a20024184096a280200210620024180086a4180016a2802002107200241fc086a280200210820024188066a20024188096a41800110e9081a2002200241086a10ad01024020022802000d0020022802082201280204220020022802042209490d002009417f4c0d030240024020090d004101210a0c010b20091032220a450d06200128020421000b024020002009490d00200a2001280200200910e9081a200128020422002009490d072001200020096b3602042001200128020020096a360200200241f8056a41086a200241f0076a41086a280200360200200220022903f0073703f80520024190056a20024188076a41e40010e9081a20024190046a20024188066a41800110e9081a0c030b200a102e0b02402005450d00200541246c21002003210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402004450d00200441246c450d002003102e0b02402006450d00200641246c21002008210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b2007450d00200741246c450d002008102e0b410021030b20024180046a41086a2201200241f8056a41086a280200360200200220022903f8053703800420024198036a20024190056a41e40010e9081a20024198026a20024190046a41800110e9081a2003450d0120024188026a41086a2001280200360200200220022903800437038802200241a0016a20024198036a41e40010e9081a200241206a20024198026a41800110e9081a0240024020022802082802040d0020024190056a41086a20024188026a41086a28020036020020022002290388023703900520024188066a200241a0016a41e40010e9081a20024180086a200241206a41800110e9081a0c010b02402005450d00200541246c21002003210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402004450d00200441246c450d002003102e0b02402006450d00200641246c21002008210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402007450d00200741246c450d002008102e0b410021032009450d00200a102e0b2003450d01200241f0076a41086a220120024190056a41086a28020036020020022002290390053703f00720024188076a20024188066a41e40010e9081a20024190046a20024180086a41800110e9081a200241a0016a41086a2001280200360200200220022903f0073703a001200241206a20024188076a41e40010e9081a20024188066a20024190046a41800110e9081a20022009360294052002200a3602900520024180086a20024190056a10f7010240024020022802840822010d00410021010c010b20024198026a41086a20024190086a28020036020020022002290388083703980220022802800821000b02402009450d00200a102e0b200241f8056a41086a220920024198026a41086a220a28020036020020022002290398023703f805024002402001450d0020024198036a41086a220b2009280200360200200220022903f8053703980320024180086a20024198026a41e80010e9081a200241a8096a2001360200200241a4096a2000360200200241a0096a4102360200200241f8086a20024190056a41086a220129030037030020024180086a4180016a200241a0056a29030037030020024188096a200241a8056a29030037030020024190096a200241b0056a290300370300200241ac096a200229039803370200200241b4096a200b280200360200200241023602980920022002290390053703f008200242023703e808200241c4096a2003360200200241c8096a2004360200200241cc096a2005360200200241c0096a200241a0016a41086a280200360200200241b8096a20022903a001370300200241d0096a200241206a41e40010e9081a200241bc0a6a2006360200200241b80a6a2007360200200241b40a6a2008360200200241c00a6a20024188066a41800110e9081a200220024180086a3602980220024190056a20024198026a109005200a200128020036020020022002290390053703980220024198026a10e8061a024020022903e8084202510d0020022d00800841ff01714102470d00200228028808450d00200228028408102e0b20024198096a108b02410121010c010b02402005450d00200541246c21002003210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402004450d00200441246c450d002003102e0b02402006450d00200641246c21002008210103400240024002400240024020012d00000e050400010204030b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b410021012007450d00200741246c450d002008102e0b4101102c2200450d02200242013702840820022000360280080240024020010d00200241003a00880620024180086a20024188066a410110740c010b200241013a00880620024180086a20024188066a410110740b200235028808210c200235028008210d200241d00b6a2400200d200c422086840f0b1038000b200241a4026a410f360200200241a4046a41023602002002420237029404200241a0a7c900360290042002410436029c02200241e4acc90036029802200220024198026a3602a0042002200241c80b6a3602a00220024190046a41b0a7c9001044000b1036000b2009200041b8b2c0001056000b901706057f017e017f037e157f017e230041c0006b22022400024002400240024002400240024002400240024020010d00200241306a22014200370300200241286a22034200370300200241186a41086a2204420037030020024200370318200241186a41b2fdc6004112108102200241086a41e9d8c80041041081022001200241086a41086a220529000037030020032002290008370300200241086a200241186a10ac0520022802082106200229020c210720014200370300200342003703002004420037030020024200370318200241186a41b2fdc6004112108102200241086a41b4d3c10041081081022001200529000037030020032002290008370300200241086a200241186a10ac052006410120061b21080240024002402007420020061b2209a7220420094220882207a722016b200229020c4200200228020822031b220a422088220ba722064f0d00200120066a22052001490d0c200441017422012005200120054b1b22014104200141044b1b220141ffffff3f712001462105200141057421010240024020040d00200241003602180c010b200241206a4101360200200220083602182002200441057436021c0b200241086a20012005200241186a107d200241106a280200210420022802084101460d01200228020c210820094220882207a721012004410576ad21090b200820014105746a2003410120031b2201200641057410e9081a2007200b7c21070240200a42ffffff3f83500d002001102e0b2007a7220c41144b0d01200c41014b0d050c080b2004450d0a0c090b200c410176220141ffffff3f712001470d092001410574220d417f4c0d09200d102c220e450d08200841606a210f200841a07f6a2110410421114100211241002113200c2114034020142115410021144101210602402015417f6a2204450d00024002400240024002400240200820044105746a2015410574221620086a41406a412010ec084100480d002015417e6a2104201020166a210141002114410021030340024020042003470d00201521060c080b200341016a2103200141206a2001412010ec082106200141606a21012006417f4a0d000b200341016a21062003417f7320156a21040c010b201020166a210102400340024020044101470d00410021040c020b2004417f6a2104200141206a2001412010ec082103200141606a210120034100480d000b0b20152004490d012015200c4b0d02201520046b22064101762205450d00200f20166a2101200820044105746a21030340200241186a41186a2216200341186a2217290000370300200241186a41106a2218200341106a2219290000370300200241186a41086a221a200341086a221b29000037030020022003290000370318200141086a221c2900002107200141106a221d290000210a200141186a221e290000210b200320012900003700002017200b3700002019200a370000201b2007370000201e2016290300370000201d2018290300370000201c201a29030037000020012002290318370000200141606a2101200341206a21032005417f6a22050d000b0b024020040d00200421140c050b0240200641094d0d00200421140c050b2015200c4b0d02201520046b21062004417f6a2101200f20044105746a2103034020152001490d082003200641016a220610eb062001417f6a220420014f0d04200341606a2103200421012006410a490d000c040b0b2004201541e4d1cc001057000b2015200c41e4d1cc00104d000b20152004417f6a2201490d042015200c41f4d1cc00104d000b200441016a21140b024020132012470d00201241016a22012012490d0b201241017422032001200320014b1b22014104200141044b1b220141ffffffff01712001464102742103200141037421010240024020120d00200241003602180c010b20024104360220200220113602182002201241037436021c0b200241086a20012003200241186a107d20022802102101024020022802084101470d0020010d0b0c0c0b200228020c2111200141037621120b201120134103746a2201200636020420012014360200201341016a221e21130240201e4102490d00024002400240034002400240024002402011201e2213417f6a221e4103746a2201280200450d00201341037420116a220541746a2802002204200128020422034d0d00201341024d0d0820112013417d6a22014103746a2802042206200320046a4d0d01201341034d0d08200541646a280200200620046a4b0d080c010b20134103490d012001280204210320112013417d6a22014103746a28020421060b20062003490d010b2013417e6a21010b02402013200141016a22154d0d00201320014d0d02201120014103746a221b280204221f201b2802006a2201201120154103746a221c280200221d490d032001200c4b0d04201b41046a21202008201d4105746a2219201c280204221a41057422036a210420014105742106024002402001201d6b2216201a6b2201201a490d00200e2019200310e908221820036a210502400240201a4101480d002016201a4a0d010b20192101201821030c020b200820066a21172018210320192101034020012004200320042003412010ec0841004822161b2206290000370000200141186a200641186a290000370000200141106a200641106a290000370000200141086a200641086a2900003700002003200341206a20161b2103200141206a2101200441206a200420161b220420174f0d02200520034b0d000c020b0b200e20042001410574220310e908221820036a210502400240201a4101480d00200141014e0d010b20042101201821030c010b200f20066a2106200421010340200141606a2103200541606a210420062003200420042003412010ec0841004822171b2216290000370000200641186a201641186a290000370000200641106a201641106a290000370000200641086a201641086a2900003700002005200420171b2105024020192003200120171b2201490d00201821030c020b200641606a21062018210320182005490d000b0b20012003200520036b41607110e9081a2020201f201a6a360200201b201d360200201c201c41086a20132015417f736a41037410ea081a41012113201e41014d0d050c010b0b201520134184d2cc00103c000b200120134194d2cc00103c000b201d200141a4d2cc001057000b2001200c41a4d2cc00104d000b2014450d030c000b0b200241146a410f3602002002412c6a41023602002002420237021c200241a0a7c9003602182002410436020c200241a0aec9003602082002200241086a3602282002200241386a360210200241186a41b0a7c9001044000b2001201541f4d1cc001057000b0240201241ffffffff0171450d002011102e0b200d450d01200e102e0c010b2008200c417e6a22014105746a21034102210603402001200c4b0d022003200610eb06200341606a2103200641016a21062001417f6a2201417f470d000b0b200c4102490d01200841206a21014101210641012103034002402001200341057420086a220441606a412010ec08450d00024020062003460d002001290000210720012004290000370000200141186a2205290000210a2005200441186a2216290000370000200141106a2205290000210b2005200441106a2217290000370000200141086a220529000021212005200441086a2218290000370000201820213700002017200b3700002016200a370000200420073700000b200341016a21030b200141206a2101200c200641016a2206470d000b2003200c4d0d0241c4f1c000412341e8f1c0001039000b2001200c41c4d1cc001056000b200c21030b20034105744104722201417f4c0d012001102c2206450d00200241003602202002200136021c200220063602182003200241186a107602402003450d0020034105742103200821010340200241186a200141201074200141206a2101200341606a22030d000b0b200235022021072002350218210a0240200942ffffff3f83500d002008102e0b200241c0006a24002007422086200a840f0b1036000b1038000b890e04027f017e027f017e230041a0036b2202240020024280808080802037020c200220013602ec022002200041d4e2cc0020011b22003602e8022002200241e8026a360208024002400240024002402001450d0020022001417f6a22013602ec022002200041016a3602e802024002400240024020002d00000e020100040b2002200241086a10ad0120022802000d0320022802ec02220320022802042200490d032000417f4c0d060240024020000d00410121010c010b200010322201450d0820022802ec0221030b20032000490d02200120022802e802200010e9081a20022802ec0222032000490d042002200320006b22033602ec02200220022802e80220006a3602e80220030d012000ad220442208620048421040c050b20010d02410021010c040b2000450d010b2001102e0b200241f4026a410f3602002002411c6a41023602002002420237020c200241a0a7c900360208200241043602ec02200241b4aec9003602e8022002200241e8026a360218200220024198036a3602f002200241086a41b0a7c9001044000b2000200341b8b2c0001056000b410021030240024020010d00410021050c010b2004422088a72200417f4c0d010240024020000d00410121050c010b2000102c2205450d030b20052001200010e9081a0b200241106a220620003602002002200036020c20022005360208200241c8016a41e7e485f306200241086a10ed070240024020010d000c010b2004422088a72200417f4c0d010240024020000d00410121030c010b2000102c2203450d030b20032001200010e9081a0b200620003602002002200036020c20022003360208200241e8016a41e2c289ab06200241086a10ee07410021030240024020010d00410021050c010b2004422088a72200417f4c0d010240024020000d00410121050c010b2000102c2205450d030b20052001200010e9081a0b200241106a220620003602002002200036020c2002200536020820024188026a41e9dabdf306200241086a10ee070240024020010d000c010b2004422088a72200417f4c0d010240024020000d00410121030c010b2000102c2203450d030b20032001200010e9081a0b200620003602002002200036020c20022003360208200241a8026a41f0c2c98b06200241086a10ee07410021050240024020010d00410021030c010b2004422088a72200417f4c0d010240024020000d00410121030c010b2000102c2203450d030b20032001200010e9081a0b200241086a41086a220620003602002002200036020c20022003360208200241c8026a41e1e69df306200241086a10ee070240024020010d00410021030c010b2004422088a72200417f4c0d010240024020000d00410121030c010b2000102c2203450d030b20032001200010e9081a200121050b20024188036a41086a20003602002002200036028c032002200336028803200241e8026a41e1ea91cb0620024188036a10ee072006200241c8016a41086a290300370300200241086a41106a200241c8016a41106a290300370300200241086a41186a200241c8016a41186a290300370300200241306a200241e8016a41086a290300370300200241386a200241e8016a41106a290300370300200241c0006a200241e8016a41186a290300370300200241d0006a20024188026a41086a290300370300200241d8006a20024188026a41106a290300370300200241e0006a20024188026a41186a290300370300200220022903c801370308200220022903e801370328200220022903880237034820024180016a200241a8026a41186a290300370300200241f8006a200241a8026a41106a290300370300200241f0006a200241a8026a41086a29030037030020024190016a200241c8026a41086a29030037030020024198016a200241c8026a41106a290300370300200241a0016a200241c8026a41186a290300370300200241b0016a200241e8026a41086a290300370300200241b8016a200241e8026a41106a290300370300200241c0016a200241e8026a41186a290300370300200220022903a802370368200220022903c80237038801200220022903e8023703a8012002420137038803200241003602900320024188036a200241086a4120107420024188036a200241086a41206a4120107420024188036a200241c8006a4120107420024188036a200241e8006a4120107420024188036a20024188016a4120107420024188036a200241a8016a4120107402402001450d002004a7450d002005102e0b200228029003220041046a2201417f4c0d0020022802880321030240024020010d00410121050c010b2001102c2205450d020b200241003602102002200136020c200220053602082000200241086a1076200241086a20032000107420023502102104200235020821070240200228028c03450d002003102e0b200241a0036a240020044220862007840f0b1038000b1036000bff0101067f230041c0006b2203240020032001360204200341086a200210dc08200341206a41186a2204200341046a200341086a41106a200341086a41086a2205200328020822064101461b2903001002220141186a290000370300200341206a41106a2207200141106a290000370300200341206a41086a2208200141086a290000370300200320012900003703202001102e200041186a2004290300370000200041106a2007290300370000200041086a20082903003700002000200329032037000002402006450d002005280200450d00200328020c102e0b024020022802002200450d00200241046a280200450d002000102e0b200341c0006a24000bff0101067f230041c0006b2203240020032001360204200341086a200210dc08200341206a41186a2204200341046a200341086a41106a200341086a41086a2205200328020822064101461b2903001007220141186a290000370300200341206a41106a2207200141106a290000370300200341206a41086a2208200141086a290000370300200320012900003703202001102e200041186a2004290300370000200041106a2007290300370000200041086a20082903003700002000200329032037000002402006450d002005280200450d00200328020c102e0b024020022802002200450d00200241046a280200450d002000102e0b200341c0006a24000bef1103037f017e017f230041c0036b220224002002428080808080203702cc012002200136020c2002200041d4e2cc0020011b3602082002200241086a3602c8012002200241c8016a10ad010240024002400240024020022802000d00200228020c220020022802042201490d002001417f4c0d040240024020010d00410121030c010b200110322203450d04200228020c21000b024020002001490d0020032002280208200110e9082104200228020c22002001490d032002200020016b36020c2002200228020820016a3602082004450d012001ad22054220862005842105200228020c450d022005a7450d010b2003102e0b200241146a410f360200200241dc016a4102360200200242023702cc01200241a0a7c9003602c8012002410436020c200241d4aec9003602082002200241086a3602d8012002200241b8036a360210200241c8016a41b0a7c9001044000b200220054220883e0294032002200436029003200241c8016a20024190036a109903024002400240024002400240024002400240024020022d00c8014101470d00410021010c010b200241086a200241c8016a41017241c00110e9081a200241c8016a200241086a41c00110e9081a4120102c2200450d0a200020022903c801370000200041186a200241c8016a41186a290300370000200041106a200241c8016a41106a290300370000200041086a200241c8016a41086a290300370000200241003602a80320024198036a41c0004104200241a8036a107d20024198036a41086a28020021062002280298034101460d01200228029c03220141e7e485f30636020c200142a08080808004370204200120003602004120102c2203450d0a200320022903e801370000200341186a20024180026a290300370000200341106a200241f8016a290300370000200341086a200241f0016a2903003700000240200641047622004101470d0020024290808080c0003702ac03200220013602a80320024198036a41c0004104200241a8036a107d20024198036a41086a28020021002002280298034101460d03200228029c032101200041047621000b200120033602102001411c6a41e2c289ab06360200200141146a42a080808080043702004120102c2203450d0a2003200229038802370000200341186a200241a0026a290300370000200341106a20024198026a290300370000200341086a20024190026a290300370000024020004102470d00200242a0808080c0003702ac03200220013602a80320024198036a41c0004104200241a8036a107d20024198036a41086a28020021002002280298034101460d04200228029c032101200041047621000b200120033602202001412c6a41e9dabdf306360200200141246a42a080808080043702004120102c2203450d0a200320022903a802370000200341186a200241c0026a290300370000200341106a200241b8026a290300370000200341086a200241b0026a290300370000024020004103470d00200242b0808080c0003702ac03200220013602a80320024198036a41e0004104200241a8036a107d20024198036a41086a28020021002002280298034101460d05200228029c032101200041047621000b200120033602302001413c6a41f0c2c98b06360200200141346a42a080808080043702004120102c2203450d0a200320022903c802370000200341186a200241e0026a290300370000200341106a200241d8026a290300370000200341086a200241d0026a290300370000024020004104470d00200242c0808080c0003702ac03200220013602a80320024198036a4180014104200241a8036a107d20024198036a41086a28020021002002280298034101460d06200228029c032101200041047621000b20012003360240200141cc006a41e1e69df306360200200141c4006a42a080808080043702004120102c2203450d0a200320022903e802370000200341186a20024180036a290300370000200341106a200241f8026a290300370000200341086a200241f0026a290300370000024020004105470d00200242d0808080c0003702ac03200220013602a80320024198036a41a0014104200241a8036a107d20024198036a41086a28020021002002280298034101460d07200228029c032101200041047621000b20012003360250200141dc006a41e1ea91cb06360200200141d4006a42a080808080043702000b02402005a7450d002004102e0b41e500410120011b2204102c2203450d09200241003602d001200220043602cc01200220033602c80120010d06200241003a0008200241c8016a200241086a4101107420022802c801210420022802d00121030c070b20060d080c090b2000450d080c070b2000450d070c060b2000450d060c050b2000450d050c040b2000450d040c030b200241013a0008200241c8016a200241086a410110744106200241c8016a10762001280200210420012802082203200241c8016a1076200241c8016a200420031074200241c8016a2001410c6a410410742001280210210420012802182203200241c8016a1076200241c8016a200420031074200241c8016a2001411c6a410410742001280220210420012802282203200241c8016a1076200241c8016a200420031074200241c8016a2001412c6a410410742001280230210420012802382203200241c8016a1076200241c8016a200420031074200241c8016a2001413c6a410410742001280240210420012802482203200241c8016a1076200241c8016a200420031074200241c8016a200141cc006a410410742001280250210420012802582203200241c8016a1076200241c8016a200420031074200241c8016a200141dc006a4104107420022802d001210320022802c80121040240200141046a280200450d002001280200102e0b0240200141146a280200450d002001280210102e0b0240200141246a280200450d002001280220102e0b0240200141346a280200450d002001280230102e0b0240200141c4006a280200450d002001280240102e0b0240200141d4006a280200450d002001280250102e0b200041ffffffff0071450d002001102e0b200241c0036a24002003ad4220862004ad840f0b2001200041b8b2c0001056000b1036000b1038000b9a0c02067f047e23004190026b22022400200241003a00800102402001450d002002200041d4e2cc0020011b22002d00003a0060200241013a008001024020014101460d00200220002d00013a0061200241023a00800120014102460d00200220002d00023a0062200241033a00800120014103460d00200220002d00033a0063200241043a00800120014104460d00200220002d00043a0064200241053a00800120014105460d00200220002d00053a0065200241063a00800120014106460d00200220002d00063a0066200241073a00800120014107460d00200220002d00073a0067200241083a00800120014108460d00200220002d00083a0068200241093a00800120014109460d00200220002d00093a00692002410a3a0080012001410a460d00200220002d000a3a006a2002410b3a0080012001410b460d00200220002d000b3a006b2002410c3a0080012001410c460d00200220002d000c3a006c2002410d3a0080012001410d460d00200220002d000d3a006d2002410e3a0080012001410e460d00200220002d000e3a006e2002410f3a0080012001410f460d00200220002d000f3a006f200241103a00800120014110460d00200220002d00103a0070200241113a00800120014111460d00200220002d00113a0071200241123a00800120014112460d00200220002d00123a0072200241133a00800120014113460d00200220002d00133a0073200241143a00800120014114460d00200220002d00143a0074200241153a00800120014115460d00200220002d00153a0075200241163a00800120014116460d00200220002d00163a0076200241173a00800120014117460d00200220002d00173a0077200241183a00800120014118460d00200220002d00183a0078200241193a00800120014119460d00200220002d00193a00792002411a3a0080012001411a460d00200220002d001a3a007a2002411b3a0080012001411b460d00200220002d001b3a007b2002411c3a0080012001411c460d00200220002d001c3a007c2002411d3a0080012001411d460d00200220002d001d3a007d2002411e3a0080012001411e460d00200220002d001e3a007e2002411f3a0080012001411f460d00200241106a2203200241e0006a41106a2204290300370300200241086a2205200241e0006a41086a2206290300370300200220002d001f3a007f200241186a2200200241e0006a41186a2207290300370300200241203a0080012002200229036022083703202002200837030020014120470d01200241206a41186a20002903002208370300200241206a41106a20032903002209370300200241206a41086a2005290300220a37030020022002290300220b37032020072008370300200420093703002006200a3703002002200b370360200241b8016a41d9fcc6004106108102200241c8016a41dcf1cb004107108102024002404120102c2201450d00200242203702ec01200220013602e801200241e8016a200241e0006a41201074200241f8016a20022802e801220120022802f001220010d8032002410c6a200120006a36020020022001360208200220024188026a3602042002200241f8016a360200200241d8016a2002107c024020022802ec01450d002001102e0b20022802e001220041206a2201417f4c0d010240024020010d00410121030c010b2001102c2203450d010b2002410036020820022001360204200220033602002002200241b8016a411010742002200241c8016a41101074200220022802d801220120001074024020022802dc01450d002001102e0b200241e0006a20022802002200200228020810c902200241a8016a28020021012002290360210802402002280204450d002000102e0b4104102c2200450d00200242043702642002200036026020022001410020084201511b360220200241e0006a200241206a41041074200235026821082002350260210920024190026a240020092008422086840f0b1036000b1038000b200241003a0080010b2002412c6a410f360200200241f4006a410236020020024202370264200241a0a7c90036026020024104360224200241f0aec9003602202002200241206a360270200220024188026a360228200241e0006a41b0a7c9001044000bd10504017f027e017f037e23004180086b22022400200241d0036a200041d4e2cc0020011b200110a602024020022903b8044203510d00200241d0036a41c8036a2802002101200241086a200241d0036a41c80310e9081a200241d0036a200241086a41c80310e9081a200241a0076a200241e8046a220010970442002103200241b0076a200120022903a00722044200420020022d00a90741004720022d00a807220510e70442002106024020022903b0074201520d00427f427f200241c0076a2903002206200241d0076a2903007c20022903b8072203200241c8076a2903007c22072003542201ad7c22032001200320065420032006511b22011b2206200241e0076a2903007c427f200720011b2203200241d8076a2903007c22072003542201ad7c22032001200320065420032006511b22011b2106427f200720011b21030b200241f0076a290300210720022903e8072108024020022903b8044202510d0020022d00d00341ff01714102470d0020022802d803450d0020022802d403102e0b2000108b022002410036021020024201370308200220043703d003200241086a200241d0036a41081074024002400240024020050e03000102030b200241003a00d003200241086a200241d0036a410110740c020b200241013a00d003200241086a200241d0036a410110740c010b200241023a00d003200241086a200241d0036a410110740b2002427f200620077c200320087c22042003542201ad7c22032001200320065420032006511b22011b3703d8032002427f200420011b3703d003200241086a200241d0036a41101074200235021021062002350208210320024180086a240020032006422086840f0b200241bc076a410f3602002002411c6a41023602002002420237020c200241a0a7c900360208200241043602b40720024188afc9003602b0072002200241b0076a3602182002200241f8076a3602b807200241086a41b0a7c9001044000bd60402017f027e23004180086b2202240020024198046a200041d4e2cc0020011b200110a60202402002290380054203510d0020024198046a41c8036a2802002101200241d0006a20024198046a41c80310e9081a20024198046a200241d0006a41c80310e9081a200241e8076a200241b0056a2200109704200241086a200120022903e8074200420020022d00f10741004720022d00f00710e70402402002290380054202510d0020022d00980441ff01714102470d0020022802a004450d00200228029c04102e0b2000108b0220024100360258200242013703500240024020022903084201510d00200241003a009804200241d0006a20024198046a410110740c010b200241013a009804200241d0006a20024198046a41011074200229031021032002200241086a41106a2903003703a0042002200337039804200241d0006a20024198046a41101074200241206a29030021032002200241286a2903003703a0042002200337039804200241d0006a20024198046a41101074200241306a29030021032002200241386a2903003703a0042002200337039804200241d0006a20024198046a411010740b200229034021032002200241c8006a2903003703a0042002200337039804200241d0006a20024198046a41101074200235025821032002350250210420024180086a240020042003422086840f0b200241146a410f360200200241e4006a410236020020024202370254200241a0a7c9003602502002410436020c2002419cafc9003602082002200241086a3602602002200241f8076a360210200241d0006a41b0a7c9001044000bd60201047f230041c0006b2202240041d0b0c9002103411321044109210502400240024002400240024002400240024002400240200141ff01710e0b000102030405060708090a000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a418caacc001044000b41e0c3cb00210341092104410021050c080b41a186ca00210341112104410121050c070b41c986ca002103410f2104410221050c060b41c6b0c9002103410a2104410321050c050b41b9b0c9002103410d2104410421050c040b41a7b0c900210341122104410521050c030b41ab85ca00210341082104410621050c020b41e086ca00210341102104410721050c010b4194b0c9002103410821050b200041831e3b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000bf50101047f230041306b22022400200241c8afc9004113108102200241106a41f1afc900410a108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bf50101047f230041306b22022400200241c8afc9004113108102200241106a41fbafc9004106108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bf50101047f230041306b22022400200241c8afc9004113108102200241106a41fbafc9004106108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000ba70401037f230041900c6b22042400200441106a200110fb07200441086a20042802102205200428021841d4e2cc004100410010ca0402400240024002402004280208450d000240200428020c220620024d0d00200441a8076a410a10f307200041013602002000410c6a200441b0076a280200360200200020042903a8073702040c020b200441d8096a200110fb07200441a8076a20042802d809220220042802e00910af0520042802a8072101200441e4096a200441a8076a41047241ac0210e9081a024002402001411c460d00200441fc046a200441e4096a41ac0210e9081a024020042802dc09450d002002102e0b200441d0026a200441fc046a41ac0210e9081a20042001360220200441206a410472200441d0026a41ac0210e9081a200441a8076a200441206a10970420042903a8072003580d01200441a8076a410910f307200041013602002000410c6a200441b0076a280200360200200020042903a807370204200441206a108b020c030b024020042802dc09450d002002102e0b200441a8076a410310f307200041013602002000410c6a200441b0076a280200360200200020042903a8073702040c020b200041086a200441206a41b00210e9081a20004100360200200041b8026a20063602002004280214450d030c020b200441a8076a410310f307200041013602002000410c6a200441b0076a280200360200200020042903a8073702040b2004280214450d010b2005102e0b200441900c6a24000bb40b06017f017e047f017e017f017e23004190066b22052400200541bd036a200341086a290000370000200541c5036a200341106a290000370000200541cd036a200341186a290000370000200541023a00b4032005410a3a00b003200520032900003700b503200541b0036a10fe01200541b0036a200410970420052903b00321062002280204210702404110102c2208450d00200841f8f7c60036020c2008410136020820084281808080103702004110102c2209450d0020094190f8c60036020c20094101360208200942818080801037020020082008280200417f6a220a3602000240200a0d002008280208200828020c2802001103000240200828020c280204450d002008280208102e0b200841046a220a200a280200417f6a220a360200200a0d002008102e0b200541d8006a200441b00210e9081a200541a0036a41026a2208200541256a41026a2d00003a000020054188036a41086a22042005410c6a41086a29010037030020054188036a41106a220a2005410c6a41106a290100370300200520052f00253b01a0032005200529010c37038803024002402009280208200541d8006a200928020c28020c1101000d00200541c8006a41023a0000200541c0006a41003a000020092009280200417f6a22083602004200210b2005420037033020054201370328024020080d002009280208200928020c2802001103000240200928020c280204450d002009280208102e0b200941046a22082008280200417f6a220836020020080d002009102e0b200541d8006a10dc0241012109410221080c010b200541b0036a200541d8006a41b00210e9081a200541ec056a2001360200200541e0056a41086a2007360200200541e0056a41106a200529038803370300200541f8056a2004290300370300200541e0056a41206a200a290300370300200541003a00e405200541013a00e005200520052f01a0033b00e505200520082d00003a00e7052005200936028806200541286a200541b0036a200541e0056a10dd0220052903284201512109200541286a41206a2d000021082005290330210b0b200541b0036a41186a200341186a290000370300200541b0036a41106a200341106a290000370300200541b0036a41086a200341086a290000370300200520032900003703b0032005200541d0006a28000036005f200520052900493703580240024020090d00410621090c010b2005200528005f3600e705200520052903583703e00541062109200b4202510d00200520052800e70536008f03200520052903e00537038803200821090b200541d8006a41086a2208200541b0036a41086a2204290300370300200541d8006a41106a220a200541b0036a41106a2201290300370300200541d8006a41186a2207200541b0036a41186a220c290300370300200520052903b00337035820052005290388033703a0032005200528008f033600a703200541043a00b4032005410a3a00b003200541bd036a2008290300370000200541c5036a200a290300370000200541cd036a2007290300370000200541d8036a20093a0000200520052903583700b503200541d5036a20052f0088033b0000200541d7036a2005418a036a2d00003a0000200541d9036a20052903a003370000200541e0036a20052800a703360000200541fc036a200541e0056a41186a280200360200200541f4036a200541e0056a41106a290200370200200541ec036a200541e0056a41086a290200370200200541e4036a20052902e005370200200541b0036a10fe01200541286a41106a290300210d200c200341186a2900003703002001200341106a2900003703002004200341086a290000370300200520032900003703b003200541b0036a10f907210302402002410c6a28020041ffffff3f71450d002002280208102e0b0240200241186a28020041ffffff3f71450d002002280214102e0b200020033602082000200d2006200ba71b37030020054190066a24000f0b1036000bba0503067f027e067f230041c0006b22012400200141106a200010fb0720012802102202200128021810ff0102402001280214450d002002102e0b200141106a200010f60720012802102202200128021810ff0102402001280214450d002002102e0b200141106a41186a22034200370300200141106a41106a22044200370300200141106a41086a2205420037030020014200370310200141106a41c8afc9004113108102200141306a41dbafc90041091081022003200141306a41086a220629000037030020042001290030370300200141306a200141106a4120108d0320012902344200200128023022021b220742ffffffff0f8321082002410120021b2109024002402007422088a7220a0d004100210b0c010b4100210c4100210b4100210d0240034002400240200b450d002009200d4105746a21022009200d200c6a4105746a210e034020022000412010ec08450d02200e2002290000370000200e41186a200241186a290000370000200e41106a200241106a290000370000200e41086a200241086a290000370000200e41206a210e200241206a2102200d41016a220d200a490d000c040b0b2009200d4105746a2102034020022000412010ec08450d01200241206a2102200d41016a220d200a490d000b4100210b0c030b200c417f6a210c200b41016a210b200d41016a220d200a490d000b0b0240200b0d004100210b0c010b2009200d200b6b4105746a2009200d4105746a200a200d6b41057410ea081a0b2001200936020020012008200a200b6b2202ad4220868437020420034200370300200442003703002005420037030020014200370310200141106a41c8afc9004113108102200141306a41dbafc90041091081022003200629000037030020042001290030370300200141106a200110e6040240200742ffffff3f83500d002009102e0b200141c0006a2400200241016a0bfa0203027f017e067f230041206b220224000240024020014102490d00200041206a22032000412010ec08417f4a0d002000290000210420002003290000370000200241186a2205200041186a2206290000370300200241106a2207200041106a2208290000370300200241086a2209200041086a220a290000370300200a200341086a2900003700002008200341106a2900003700002006200341186a29000037000020022004370300024020014103490d00200041206a210320002001417f6a22064105746a21080340200341206a22002002412010ec08417f4a0d012006450d0320032000290000370000200341186a200041186a290000370000200341106a200041106a290000370000200341086a200041086a290000370000200021032006417f6a22064101470d000b200821030b20032002290300370000200341186a2005290300370000200341106a2007290300370000200341086a20092903003700000b200241206a24000f0b2001200141d4d1cc00103c000bf50101047f230041306b22022400200241c8afc9004113108102200241106a41f1afc900410a108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000be909010e7f230041c0006b220424002002410020031b21052000410020011b2106200241206a200220031b2107200041206a200020011b2108200020014105746a2109200220034105746a210a4101210b41002103410021024101210c4100210d4100210e02400240034002400240024020050d002006450d010c020b02402006450d00024020052006412010ec08220f0d00410020082008200946220f1b2106410020072007200a4622101b21052008200841206a200f1b21082007200741206a20101b21070c040b200f417f4a0d02200441186a220f200541186a290000370300200441106a2210200541106a290000370300200441086a2211200541086a2900003703002004200529000037030002400240200e200d470d00200d41016a2205200d490d07200d410174220e2005200e20054b1b22054104200541044b1b220541ffffff3f71200546210e2005410574210502400240200d0d00200441003602300c010b200441013602382004200c3602302004200d4105743602340b200441206a2005200e200441306a107d2004280228210520042802204101460d012004280224210c200d210e2005410576210d0b200c200e4105746a22052004290300370000200541186a200f290300370000200541106a2010290300370000200541086a2011290300370000410020072007200a46220f1b2105200e41016a210e2007200741206a200f1b21070c040b20050d040c050b200441186a220f200541186a290000370300200441106a2210200541106a290000370300200441086a2211200541086a2900003703002004200529000037030002400240200e200d470d00200d41016a2206200d490d06200d41017422052006200520064b1b22064104200641044b1b220641ffffff3f7120064621052006410574210602400240200d0d00200441003602300c010b200441013602382004200c3602302004200d4105743602340b200441206a20062005200441306a107d2004280228210620042802204101460d012004280224210c200d210e2006410576210d0b200c200e4105746a22062004290300370000200641186a200f290300370000200641106a2010290300370000200641086a201129030037000041002106410020072007200a46220f1b2105200e41016a210e2007200741206a200f1b21070c030b20060d030c040b200c200e200020011084080240200d41ffffff3f71450d00200c102e0b0240200341ffffff3f71450d00200b102e0b200441c0006a24000f0b200441186a220f200641186a290000370300200441106a2210200641106a290000370300200441086a2211200641086a290000370300200420062900003703000240024020022003470d00200341016a22062003490d04200341017422022006200220064b1b22064104200641044b1b220641ffffff3f712006462102200641057421060240024020030d00200441003602300c010b200441013602382004200b360230200420034105743602340b200441206a20062002200441306a107d2004280228210620042802204101460d012004280224210b20032102200641057621030b200b20024105746a22062004290300370000200641186a200f290300370000200641106a2010290300370000200641086a2011290300370000410020082008200946220f1b2106200241016a21022008200841206a200f1b21080c010b0b2006450d010b1036000b1038000bd60201047f230041c0006b2202240041d0b0c9002103411321044109210502400240024002400240024002400240024002400240200141ff01710e0b000102030405060708090a000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a418caacc001044000b41e0c3cb00210341092104410021050c080b41a186ca00210341112104410121050c070b41c986ca002103410f2104410221050c060b41c6b0c9002103410a2104410321050c050b41b9b0c9002103410d2104410421050c040b41a7b0c900210341122104410521050c030b41ab85ca00210341082104410621050c020b41e086ca00210341102104410721050c010b4194b0c9002103410821050b20004183203b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000bf50101047f230041306b2202240020024181b0c9004113108102200241106a41f1afc900410a108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bf50101047f230041306b2202240020024181b0c9004113108102200241106a41fbafc9004106108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bf50101047f230041306b2202240020024181b0c9004113108102200241106a41fbafc9004106108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000ba70401037f230041900c6b22042400200441106a2001108508200441086a20042802102205200428021841d4e2cc004100410010ca0402400240024002402004280208450d000240200428020c220620024d0d00200441a8076a410a10fd07200041013602002000410c6a200441b0076a280200360200200020042903a8073702040c020b200441d8096a2001108508200441a8076a20042802d809220220042802e00910af0520042802a8072101200441e4096a200441a8076a41047241ac0210e9081a024002402001411c460d00200441fc046a200441e4096a41ac0210e9081a024020042802dc09450d002002102e0b200441d0026a200441fc046a41ac0210e9081a20042001360220200441206a410472200441d0026a41ac0210e9081a200441a8076a200441206a10970420042903a8072003580d01200441a8076a410910fd07200041013602002000410c6a200441b0076a280200360200200020042903a807370204200441206a108b020c030b024020042802dc09450d002002102e0b200441a8076a410310fd07200041013602002000410c6a200441b0076a280200360200200020042903a8073702040c020b200041086a200441206a41b00210e9081a20004100360200200041b8026a20063602002004280214450d030c020b200441a8076a410310fd07200041013602002000410c6a200441b0076a280200360200200020042903a8073702040b2004280214450d010b2005102e0b200441900c6a24000bb40b06017f017e047f017e017f017e23004190066b22052400200541bd036a200341086a290000370000200541c5036a200341106a290000370000200541cd036a200341186a290000370000200541023a00b4032005410b3a00b003200520032900003700b503200541b0036a10fe01200541b0036a200410970420052903b00321062002280204210702404110102c2208450d00200841f8f7c60036020c2008410136020820084281808080103702004110102c2209450d0020094190f8c60036020c20094101360208200942818080801037020020082008280200417f6a220a3602000240200a0d002008280208200828020c2802001103000240200828020c280204450d002008280208102e0b200841046a220a200a280200417f6a220a360200200a0d002008102e0b200541d8006a200441b00210e9081a200541a0036a41026a2208200541256a41026a2d00003a000020054188036a41086a22042005410c6a41086a29010037030020054188036a41106a220a2005410c6a41106a290100370300200520052f00253b01a0032005200529010c37038803024002402009280208200541d8006a200928020c28020c1101000d00200541c8006a41023a0000200541c0006a41003a000020092009280200417f6a22083602004200210b2005420037033020054201370328024020080d002009280208200928020c2802001103000240200928020c280204450d002009280208102e0b200941046a22082008280200417f6a220836020020080d002009102e0b200541d8006a10dc0241012109410221080c010b200541b0036a200541d8006a41b00210e9081a200541ec056a2001360200200541e0056a41086a2007360200200541e0056a41106a200529038803370300200541f8056a2004290300370300200541e0056a41206a200a290300370300200541003a00e405200520052f01a0033b00e5052005200936028806200541023a00e005200520082d00003a00e705200541286a200541b0036a200541e0056a10dd0220052903284201512109200541286a41206a2d000021082005290330210b0b200541b0036a41186a200341186a290000370300200541b0036a41106a200341106a290000370300200541b0036a41086a200341086a290000370300200520032900003703b0032005200541d0006a28000036005f200520052900493703580240024020090d00410621090c010b2005200528005f3600e705200520052903583703e00541062109200b4202510d00200520052800e70536008f03200520052903e00537038803200821090b200541d8006a41086a2208200541b0036a41086a2204290300370300200541d8006a41106a220a200541b0036a41106a2201290300370300200541d8006a41186a2207200541b0036a41186a220c290300370300200520052903b00337035820052005290388033703a0032005200528008f033600a703200541043a00b4032005410b3a00b003200541bd036a2008290300370000200541c5036a200a290300370000200541cd036a2007290300370000200541d8036a20093a0000200520052903583700b503200541d5036a20052f0088033b0000200541d7036a2005418a036a2d00003a0000200541d9036a20052903a003370000200541e0036a20052800a703360000200541fc036a200541e0056a41186a280200360200200541f4036a200541e0056a41106a290200370200200541ec036a200541e0056a41086a290200370200200541e4036a20052902e005370200200541b0036a10fe01200541286a41106a290300210d200c200341186a2900003703002001200341106a2900003703002004200341086a290000370300200520032900003703b003200541b0036a108308210302402002410c6a28020041ffffff3f71450d002002280208102e0b0240200241186a28020041ffffff3f71450d002002280214102e0b200020033602082000200d2006200ba71b37030020054190066a24000f0b1036000bba0503067f027e067f230041c0006b22012400200141106a200010850820012802102202200128021810ff0102402001280214450d002002102e0b200141106a200010800820012802102202200128021810ff0102402001280214450d002002102e0b200141106a41186a22034200370300200141106a41106a22044200370300200141106a41086a2205420037030020014200370310200141106a4181b0c9004113108102200141306a41dbafc90041091081022003200141306a41086a220629000037030020042001290030370300200141306a200141106a4120108d0320012902344200200128023022021b220742ffffffff0f8321082002410120021b2109024002402007422088a7220a0d004100210b0c010b4100210c4100210b4100210d0240034002400240200b450d002009200d4105746a21022009200d200c6a4105746a210e034020022000412010ec08450d02200e2002290000370000200e41186a200241186a290000370000200e41106a200241106a290000370000200e41086a200241086a290000370000200e41206a210e200241206a2102200d41016a220d200a490d000c040b0b2009200d4105746a2102034020022000412010ec08450d01200241206a2102200d41016a220d200a490d000b4100210b0c030b200c417f6a210c200b41016a210b200d41016a220d200a490d000b0b0240200b0d004100210b0c010b2009200d200b6b4105746a2009200d4105746a200a200d6b41057410ea081a0b2001200936020020012008200a200b6b2202ad4220868437020420034200370300200442003703002005420037030020014200370310200141106a4181b0c9004113108102200141306a41dbafc90041091081022003200629000037030020042001290030370300200141106a200110e6040240200742ffffff3f83500d002009102e0b200141c0006a2400200241016a0bc210050b7f017e087f087e0b7f230022042105200441c0016b4160712206240002400240200141ffffff3f712001470d0020014105742207417f4c0d0041012108024002402007450d002007102c2208450d0120074105762109200821042007210a0340200a450d0120042000290000370000200441086a200041086a290000370000200441106a200041106a290000370000200441186a200041186a290000370000200441206a2104200a41606a210a200041206a21002009417f6a22090d000b0b2008200110fc02200641e0006a41186a220b4200370300200641e0006a41106a220c4200370300200641e0006a41086a220d42003703002006420037036020064180016a4181b0c9004113108102200d20064180016a41086a2200290000370300200620062900800137036020064180016a41dbafc9004109108102200b2000290000370300200c20062900800137030020064180016a200641e0006a4120108d032006280280012204410120041b210e200629028401420020041b220f422088a72204450d02200e20044105746a2110200641206a410c72211120064180016a410c6a2112200e2113034020064180016a41186a2214201341186a29000037030020064180016a41106a201341106a2900003703002000201341086a2900003703002006201329000037038001200641106a20064180016a10ff0720064180016a200628021022152006280218221610b305200d201241086a290200370300200c201241106a2802003602002006201229020037036020062802a00121170240200628028801220a450d00200629038001211820112006290360370200201141086a200d290300370200201141106a200c28020036020020062018370320201721040b2006200a360228200641003602880120062903382119200620062903980122183703382006290330211a2006200629039001221b3703302006290320211c2006200629038001221d3703202006290328211e2006200629038801221f37032802400240201ea722200d00200421170c010b2006201c3703402006201e3703482006201a370350201e422088a721212006201937035802400240201aa722040d00201a422088a721222019422088a721042019a72123202021240c010b202020044105746a212220202125202021240340200b202541186a2900002218370300200c202541106a290000221b370300200d202541086a290000221d37030020002025290000221e370000200041086a2226201d370000200041106a2227201b370000200041186a222820183700002006201e37036020062024360284012006202036028001202541206a212541002104024002400240024020010e020201000b410021042001210a0340200a410176222920046a210920092004200820094105746a2000412010ec084101481b2104200a20296b220a41014b0d000b0b200820044105746a2000412010ec08450d010b20242000290000370000202441186a2028290000370000202441106a2027290000370000202441086a2026290000370000202441206a21240b20252022470d000b200628025c210420062802582123200628025421220b201fa7212a2006202136024c200620203602482006202420206b4105753602500240024020040d00202221240c010b202220044105746a212020222125202221240340200b202541186a2900002218370300200c202541106a290000221b370300200d202541086a290000221d37030020002025290000221e370000200041086a2226201d370000200041106a2227201b370000200041186a222820183700002006201e37036020062024360284012006202236028001202541206a212541002104024002400240024020010e020201000b410021042001210a0340200a410176222920046a210920092004200820094105746a2000412010ec084101481b2104200a20296b220a41014b0d000b0b200820044105746a2000412010ec08450d010b20242000290000370000202441186a2028290000370000202441106a2027290000370000202441086a2026290000370000202441206a21240b20252020470d000b0b20062023360258200620223602542006202420226b41057536025c2006290348211f2006290340211d2006290350211b200629035821180240202a450d000240200628022c41ffffff3f71450d002006280228102e0b200628023841ffffff3f71450d002006280234102e0b2006201d3703202006201f3703282006201b370330200620183703380b2006201f370388012006201b37039001201420183703002006201d37038001200620173602a00102400240201fa722040d002015201610ff010c010b2018a7210a2015201620064180016a10c0050240201f422088a741ffffff3f71450d002004102e0b200a41ffffff3f71450d00201b422088a7102e0b201341206a211302402006280214450d002015102e0b2017210420132010470d000c030b0b1036000b1038000b0240200f42ffffff3f83500d00200e102e0b20064198016a2200420037030020064190016a2204420037030020064180016a41086a220a42003703002006420037038001200641e0006a4181b0c9004113108102200a200641e0006a41086a22092900003703002006200629006037038001200641e0006a41c7c3cb004107108102200020092900003703002004200629006037030020064180016a2002200310c5052000420037030020044200370300200a42003703002006420037038001200641e0006a4181b0c9004113108102200a20092900003703002006200629006037038001200641e0006a41dbc3cb004105108102200020092900003703002004200629006037030020064180016a412010ff0102402007450d002008102e0b200524000bf50101047f230041306b2202240020024181b0c9004113108102200241106a41f1afc900410a108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bdc0301057f230041f0006b2201240020002d00002102200141186a2203200041196a290000370300200141106a2204200041116a290000370300200141086a2205200041096a2900003703002001200029000137030002400240024020020d00200141c0006a41186a22004200370300200141c0006a41106a22024200370300200141c0006a41086a420037030020014200370340200141c0006a4181b0c9004113108102200141206a41dbc3cb0041051081022000200141206a41086a29000037030020022001290020370300200141c0006a412010ff010c010b200141206a41186a2003290300370300200141206a41106a2004290300370300200141206a41086a200529030037030020012001290300370320200141c0006a41186a22004200370300200141c0006a41106a22024200370300200141c0006a41086a420037030020014200370340200141c0006a4181b0c9004113108102200141e0006a41dbc3cb0041051081022000200141e0006a41086a290000370300200220012900603703004120102c2200450d012001422037026420012000360260200141e0006a200141206a41201074200141c0006a412020012802602200200128026810b2012001280264450d002000102e0b200141f0006a24000f0b1036000b130020004106360204200041e4b0c9003602000b3400200041c8afc90036020420004100360200200041146a4106360200200041106a41d4e0c900360200200041086a42133702000b2501017f230041306b22022400200241003602102000200241086a10e705200241306a24000b2901017f230041106b2202240020024100360208200242013703002000200210b301200241106a24000b340020004181b0c90036020420004100360200200041146a4106360200200041106a41f4e8c900360200200041086a42133702000b4201027f230041106b2202240002404101102c22030d001036000b2000420137020420002003360200200241003a000f20002002410f6a41011074200241106a24000b6401027f230041c0026b220224002002411c36020802404101102c2203450d002000420137020420002003360200200241003a00bf022000200241bf026a4101107402402002280208411c460d00200241086a108b020b200241c0026a24000f0b1036000be22505027f017e027f017e037f230041b0046b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c0102030405060708090a0b0c0d0e0f101112131415161718191a1b00010b200241086a200141386a10ca0120024180026a41286a200141306a29030037030020024180026a41206a200141286a29030037030020024180026a41186a200141206a29030037030020024180026a41106a200141186a29030037030020024180026a41086a200141106a2903003703002002200141086a29030037038002200141f8016a280200210320024180026a41306a200241086a41c00110e9081a20014180026a2903002104200241086a20024180026a41f00110e9081a200041086a200241086a41f00110e9081a20004180026a2004370300200041f8016a20033602002000411b3602000c1b0b20024180026a200141086a10cb0120004100360200200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c1a0b20024180026a200141046a10cc0120004101360200200041246a200241a0026a2802003602002000411c6a20024198026a290300370200200041146a20024190026a2903003702002000410c6a20024188026a29030037020020002002290380023702040c190b20024180026a200141086a10cd01200041086a20024180026a41a00210e9081a200041023602000c180b20004103360200200041086a200141086a2903003703000c170b41042103200141046a210502400240024002400240024002400240024020012d0004417f6a0e050102030405000b41e2a0cc00412841e89bc4001039000b200141086a2802002105410121030c040b41022103200241086a41026a200541036a2d00003a000020024180026a41086a200141146a29020037030020024190026a2001411c6a29020037030020024198026a200141246a2d00003a0000200220052f00013b010820022001410c6a29020037038002200141086a2802002105200141286a28020021010c040b200141086a2802002105410321030c020b2002410a6a200541036a2d00003a000020024180026a41086a200141146a29020037030020024190026a2001411c6a29020037030020024198026a200141246a2d00003a0000200220052f00013b010820022001410c6a2902003703800220012d00254100472106200141086a2802002105200141286a28020021010c030b200141086a2802002105410521030b0b0b200020033a0004200020022f01083b0005200020063a0025200020022f01fc013b0126200041086a20053602002000410c6a200229038002370200200041286a2001360200200041076a2002410a6a2d00003a0000200041146a20024180026a41086a2903003702002000411c6a20024190026a290300370200200041246a20024198026a2d00003a0000200041043602000c160b20024180026a200141086a10ce01200041086a20024180026a41e00010e9081a200041053602000c150b20024180026a200141046a10cf01200041063602002000410c6a20024188026a28020036020020002002290380023702040c140b20024180026a200141086a10d001200041086a20024180026a41d80010e9081a200041073602000c130b10d101000b02400240200128020422050d00410021030c010b20024180026a41186a200141286a29000037030020024180026a41106a200141206a29000037030020024188026a200141186a29000037030020024180026a41286a200141386a29000037030020024180026a41306a200141c0006a29000037030020024180026a41386a200141c8006a29000037030020024180026a41c8006a200141d8006a29000037030020024180026a41d0006a200141e0006a29000037030020024180026a41d8006a200141e8006a2900003703002002200141106a290000370380022002200141306a2900003703a0022002200141d0006a2900003703c00220024180026a41f8006a20014188016a29000037030020024180026a41f0006a20014180016a29000037030020024180026a41e8006a200141f8006a29000037030020024180026a4198016a200141a8016a29000037030020024180026a4190016a200141a0016a29000037030020024180026a4188016a20014198016a29000037030020024180026a41b8016a200141c8016a29000037030020024180026a41b0016a200141c0016a29000037030020024180026a41a8016a200141b8016a2900003703002002200141f0006a2900003703e002200220014190016a290000370380032002200141b0016a2900003703a0032001410c6a2802002201417f4c0d130240024020010d00410121030c010b2001102c2203450d150b20032005200110e9081a200241086a20024180026a41c00110e9081a0b200020033602042000410c6a2001360200200041086a2001360200200041106a200241086a41c00110e9081a200041093602000c110b20024180026a200141086a10d201200041086a20024180026a41980210e9081a2000410a3602000c100b20024180026a200141046a10d301200041046a20024180026a41e80010e9081a2000410b3602000c0f0b10d401000b20024180026a200141086a10d5012000410d360200200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0d0b20024180026a200141086a10d6012000410e360200200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0c0b20024180026a200141086a10d6012000410f360200200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0b0b20024180026a200141086a10d70120004110360200200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c0a0b200141046a2103410721050240024002400240024002400240024020012d0004417f6a0e0701020304050607000b41e2a0cc00412841a4c3cb001039000b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410121050c050b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410221050c040b20024180026a41186a200341196a29000037030020024180026a41106a200341116a29000037030020024180026a41086a200341096a290000370300200241086a41086a200341296a290000370300200241086a41106a200341316a290000370300200241086a41186a200341396a29000037030020022003290001370380022002200341216a290000370308410321050c030b200241086a200141086a10c8012002418b026a200241086a41086a2802003600002002200229030837008302410421050c020b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410521050c010b20024198026a200341196a29000037030020024190026a200341116a29000037030020024188026a200341096a2900003703002002200329000137038002410621050b200020053a0004200020022903800237000520002002290308370025200020022f00fc013b00452000410d6a20024180026a41086a290300370000200041156a20024180026a41106a2903003700002000411d6a20024180026a41186a2903003700002000412d6a200241086a41086a290300370000200041356a200241086a41106a2903003700002000413d6a200241086a41186a290300370000200041c7006a200241fe016a2d00003a0000200041113602000c090b024002400240024002400240200141086a280200417f6a0e03010203000b41e2a0cc0041284184ccc2001039000b200141386a2903002104200141306a29030021074101210841012109024002400240024002402001410c6a2d00000e050104020300010b4104210920024180026a41046a200141206a2d00003a000020022001411c6a2800003602800220012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a28020021050c030b20024188026a200141246a29000037030020024180026a41106a2001412c6a2d00003a000020022001411c6a2900003703800220012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a2802002105410021090c020b200141186a2802002203417f4c0d0f200141106a28020021010240024020030d00410121050c010b2003102c2205450d110b20052001200310e9081a410221092003210a0c010b20024188026a200141246a29000037030020024180026a41106a2001412c6a2d00003a000020022001411c6a2900003703800220012f000d2001410f6a2d0000411074722106200141186a280200210a200141146a2802002103200141106a2802002105410321090b200241086a41106a20024180026a41106a2d00003a0000200241086a41086a20024180026a41086a290300370300200241046a41026a200241fc016a41026a2d00003a00002002200229038002370308200220022f00fc013b01040c030b2001410c6a28020022094108762106410221080c010b2001410c6a28020022094108762106410321080b0b200020022f01043b002d20004112360200200041386a2004370300200041306a2007370300200041186a200a360200200041146a2003360200200041106a2005360200200041086a20083602002000411c6a20022903083702002000410c6a2006410874200941ff017172360200200041246a200241086a41086a2903003702002000412c6a200241086a41106a2d00003a00002000412f6a200241066a2d00003a00000c080b20024180026a200141086a10d801200041086a20024180026a41f00010e9081a200041133602000c070b20024180026a200141086a10d901200041086a20024180026a41f80010e9081a200041143602000c060b024002400240024020012f0104417f6a0e03010200010b20024180026a200141086a10c90120022902840221042002280280022103410321010c020b20024180026a200141086a10c90120022902840221042002280280022103410121010c010b20012f0106210541b002102c2203450d0820024180026a200141086a28020010da01200320024180026a41b00210e9081a410221010b200020013b0104200041153602002000410c6a2004370200200041086a2003360200200041066a20053b01000c050b20024180026a200141086a10db01200041086a20024180026a41a80210e9081a200041163602000c040b20024180026a200141046a10dc01200041046a20024180026a41c80010e9081a200041173602000c030b20024180026a200141086a10dd01200041086a20024180026a41c80010e9081a200041183602000c020b20024180026a200141086a10de0120004119360200200041c0006a20024180026a41386a290300370300200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000c010b20024180026a200141086a10df012000411a360200200041c0006a20024180026a41386a290300370300200041386a20024180026a41306a290300370300200041306a20024180026a41286a290300370300200041286a20024180026a41206a290300370300200041206a20024180026a41186a290300370300200041186a20024180026a41106a290300370300200041106a20024180026a41086a290300370300200041086a2002290380023703000b200241b0046a24000f0b1038000b1036000b13002000410a360204200041c4fac9003602000bf30a04077f027e047f077e23002202210320024180026b41607122022400200241c0006a10910820022802402104024002400240024002400240024020022802482205450d00200241286a2004280200109208024020054101470d004100210620024180016a21070c030b200241286a41106a2903004200200228022822081b21092002290330420020081b210a200441c4006a2108200541c4006c41bc7f6a210b41002106200241106a41106a210c2004210d410121070340200241106a20082802001092082009200c29030042002002280210220e1b220f200a20022903184200200e1b2210562009200f562009200f511b220e1b2109200a2010200e1b210a20062007200e1b2106200d2008200e1b210d200741016a2107200841c4006a2108200b41bc7f6a220b0d000b2002200a3703800120022006360290012002200937038801200d0d010b2000411310930820022802442202450d02200241c4006c450d022004102e200324000f0b20024180016a2107200520064d0d020b2004200641c4006c6a220841186a220d290200210a20042005417f6a220641c4006c220b6a220e41c0006a280200210c200e41206a290200210f200e41286a2902002110200e41306a2902002111200e41386a2902002112200e2902002113200e2902082109200e2902102114200d200e41186a290200370200200829021021152008201437021020082902082114200820093702082008290200210920082013370200200841386a2012370200200841306a2011370200200841286a2010370200200841206a220e2802002105200e200f370200200841c0006a200c360200200220063602482002201537039001200220143703880120022009370380012002200a37039801200241d0006a41186a2007411c6a280000360200200241d0006a41106a200741146a290000370300200241d0006a41086a2007410c6a290000370300200220072900043703502002280244210e20024180016a41186a2208420037030020024180016a41106a2207420037030020024180016a41086a4200370300200242003703800120024180016a41de80ca004109108102200241f0006a418c81ca00410b1081022008200241f0006a41086a29000037030020072002290070370300200b41046a2208417f4c0d020240024020080d00410121070c010b2008102c2207450d040b2002410036027820022008360274200220073602702006200241f0006a107620042006200241f0006a109b0120024180016a412020022802702208200228027810b20102402002280274450d002008102e0b2009a721060240200e450d00200e41c4006c450d002004102e0b200241f0006a200610940820024180016a200228027022082002280278220e10ae0502402002280280012207450d002008200e10ff010b2002280274210e0240024020070d00200e450d012008102e0c010b20024198016a290300210920024190016a290300210a20024188016a280200210d200228028401210b0240200e450d002008102e0b0240200d450d00200d410574210e20072108034020022008200a200910fb01200841206a2108200e41606a220e0d000b0b200241a8016a2009370300200241a0016a200a37030020024180016a41186a2208200d36020020024194016a200b36020020024180016a41106a220e20073602002002418c016a200636020020024180016a41086a220741013a0000200241093a00800120024180016a10fe012008200241d0006a41186a280200360200200e200241d0006a41106a2903003703002007200241d0006a41086a29030037030020022002290350370380012002200536029c0120014180ce186a20024180016a41004180ce181095080b200041063a00000b200324000f0b200620051042000b1038000b1036000ba60d03077f017e0a7f23004190036b22012400200141206a22024200370300200141186a22034200370300200141086a41086a420037030020014200370308200141086a41de80ca004109108102200141a8026a418c81ca00410b1081022002200141a8026a41086a290000370300200320012900a8023703002001412036022c2001200141086a360228200141306a200141086a412010ed0202400240200128023022040d00410021050c010b200128023421062001200141306a41086a280200360244200120043602402001200141c0006a10ab010240024020012802000d000240024020012802042207200128024441c4006e2202200220074b1bad42c4007e2208422088a70d002008a72202417f4c0d000240024020020d00410421050c010b2002102c2205450d020b200241c4006ead2108024002402007450d00200141a8026a41017221094100210a03400240024002400240200128024422034104490d00200a41016a210a2001280240220b280000210c20012003417c6a220d3602442001200b41046a36024041002102200141003a00c8022003417b6a210302400340200d2002460d01200141a8026a20026a200b20026a220e41046a2d00003a00002001200e41056a3602402001200241016a220e3a00c802200120033602442003417f6a2103200e2102200e4120470d000b200141f0026a41186a2202200141a8026a41186a290300370300200141f0026a41106a2203200141a8026a41106a290300370300200141f0026a41086a220b200141a8026a41086a290300370300200120012903a8023703f002200e41ff01714120490d0120014188026a41086a220e200b29030037030020014188026a41106a220b200329030037030020014188026a41186a22032002290300370300200120012903f00237038802200141a8026a200141c0006a10930120012d00a8024101460d01200141e8016a41186a22022003290300370300200141e8016a41106a2203200b290300370300200141e8016a41086a220b200e29030037030020012001290388023703e801200141c8016a41086a220e200941086a290000370300200141c8016a41106a220d200941106a290000370300200141c8016a41186a220f200941186a290000370300200120092900003703c801200141a8016a41186a22102002290300370300200141a8016a41106a22022003290300370300200141a8016a41086a2203200b290300370300200120012903e8013703a80120014188016a41186a220b200f29030037030020014188016a41106a220f200d29030037030020014188016a41086a220d200e290300370300200120012903c80137038801200141e8006a41186a220e2010290300370300200141e8006a41106a22102002290300370300200141e8006a41086a22112003290300370300200120012903a801370368200141c8006a41186a2212200b290300370300200141c8006a41106a220b200f290300370300200141c8006a41086a220f200d29030037030020012001290388013703482008422088a722032008a7470d04200341016a22022003490d082003410174220d20022002200d491b22024104200241044b1bad42c4007e2208422088a74541027421022008a7210d20030d02200141003602a8020c030b200241ff0171450d00200141003a00c8020b2008a721022002450d08200241c4006c450d082005102e0c080b200141043602b002200120053602a8022001200341c4006c3602ac020b200141f0026a200d2002200141a8026a107d20012802f802210220012802f0024101460d0320012802f4022105200241c4006ead21080b2005200341c4006c6a2202200c360200200220012903683702042002410c6a2011290300370200200241146a20102903003702002002411c6a200e290300370200200220012903483702242002412c6a200f290300370200200241346a200b2903003702002002413c6a2012290300370200200842ffffffff0f83200341016aad422086842108200a2007470d000b0b2005450d030c040b20020d010b1038000b1036000b41002105200141003602f802200142013703f0022001410a3602d4022001200141286a3602d0022001200141f0026a36028802200141bc026a4101360200200142013702ac02200141909dc5003602a8022001200141d0026a3602b80220014188026a419cebc000200141a8026a103d1a20012802f00220012802f80210ef0220012802f402450d0020012802f002102e0b2006450d002004102e0b0240024020050d0020004100360208200042043702000c010b20002008370204200020053602000b20014190036a24000bd10102027f047e230041c0006b22022400200241306a2001109408200241106a20022802302201200228023810ae050240024020022802102203450d0020022902142104200241286a2903002105200241206a290300210602402002280234450d002001102e0b2002200620052004422088420010e808200241086a29030021054201210620022903002107200442ffffff3f83500d012003102e0c010b02402002280234450d002001102e0b420021060b2000200737030820002006370300200041106a2005370300200241c0006a24000be70601047f230041c0006b2202240041e086ca0021034110210441222105024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141ff01710e24000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223000b2002413c6a41013602002002420137022c2002419cc3cb00360228200241043602242002418883ca003602202002200241206a360238200241286a41bca8cc001044000b41d886ca00210341082104410021050c210b41c986ca002103410f2104410121050c200b41c186ca00210341082104410221050c1f0b41b286ca002103410f2104410321050c1e0b41a186ca00210341112104410421050c1d0b418e86ca00210341132104410521050c1c0b41fd85ca00210341112104410621050c1b0b41f285ca002103410b2104410721050c1a0b41e885ca002103410a2104410821050c190b41db85ca002103410d2104410921050c180b41cf85ca002103410c2104410a21050c170b41be85ca00210341112104410b21050c160b41b385ca002103410b2104410c21050c150b41ab85ca00210341082104410d21050c140b41a385ca00210341082104410e21050c130b419485ca002103410f2105410f21040c120b418385ca00210341112104411021050c110b41f484ca002103410f2104411121050c100b41e984ca002103410b2104411221050c0f0b41e084ca00210341092104411321050c0e0b41d684ca002103410a2104411421050c0d0b41ce84ca00210341082104411521050c0c0b41c284ca002103410c2104411621050c0b0b41b184ca00210341112104411721050c0a0b41a984ca00210341082104411821050c090b41a084ca00210341092104411921050c080b418f84ca00210341112104411a21050c070b418284ca002103410d2104411b21050c060b41f883ca002103410a2104411c21050c050b41e783ca00210341112104411d21050c040b41df83ca00210341082104411e21050c030b41d083ca002103410f2104411f21050c020b41c183ca002103410f2104412021050c010b41b383ca002103410e2104412121050b200041831c3b0100200041086a2004360200200041046a2003360200200041026a20053a0000200241c0006a24000b850201037f230041d0006b22022400200241086a41de80ca004109108102200241186a419781ca004109108102200220013602342002200241346a410410a301370338200241cc006a200241346a41046a3602002002200241c0006a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107c024002402002280230220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241d0006a24000f0b1038000b1036000bf30501077f230041e0016b22042400200441d0006a41186a22054200370300200441d0006a41106a22064200370300200441d0006a41086a2207420037030020044200370350200441086a41de80ca0041091081022007200441086a41086a220829000037030020042004290008370350200441086a41ccf8ca00410f10810220052008290000370300200620042900083703002004200441d0006a4120108e02200428020421092004280200210a20054200370300200642003703002007420037030020044200370350200441086a41de80ca0041091081022007200829000037030020042004290008370350200441086a41ccf8ca00410f1081022005200829000037030020062004290008370300200420094100200a1b220541016a360208200441d0006a4120200441086a410410b201200441376a42003700002004412f6a4200370000200441276a42003700002004411f6a4200370000200441086a410f6a42003700002004420037000f200441d0006a41096a2008290000370000200441e1006a200441086a41106a290000370000200441e9006a200441086a41186a290000370000200441f1006a200441086a41206a290000370000200441f9006a200441306a29000037000020044180016a42003700002004418c016a200336020020044188016a200036020020044190016a200129000037030020044198016a200141086a290000370300200441a0016a200141106a290000370300200441a8016a200141186a290000370300200441003a005020042004290008370051200441b0016a20023a0000200441c0006a20051089052004280248210820042802402101200441003602d801200442013703d001200441d0006a200441d0016a10bc052001200820042802d001220620042802d80110b201024020042802d401450d002006102e0b02402004280244450d002001102e0b200441dc006a2005360200200441d8006a41033a0000200441093a0050200441d0006a41096a20023a0000200441d0006a10fe01200441e0016a24000b8d04010b7f230041e0016b22022400200241206a41186a22034200370300200241206a41106a22044200370300200241206a41086a2205420037030020024200370320200241e0006a41de80ca0041091081022005200241e0006a41086a220629000037030020022002290060370320200241e0006a418081ca00410c1081022003200629000037030020042002290060370300200241e0006a200241206a10aa050240024020022d00800122034103470d00200041131093080c010b200241206a412010ff01200241086a22042006290300370300200241106a2205200241e0006a41106a2207290300370300200241186a2208200241e0006a41186a220929030037030020022002290360370300200241c0006a41186a220a4200370300200241c0006a41106a220b4200370300200241c0006a41086a220c420037030020024200370340200241e0006a41de80ca004109108102200c200629000037030020022002290060370340200241e0006a41a8fbca004115108102200a2006290000370300200b2002290060370300200241013a0060200241c0006a4120200241e0006a410110b201200641023a0000200241093a0060200241e0006a10fe012009200829030037030020072005290300370300200620042903003703002002200229030037036020014180ce186a200241e0006a20034180ce18109508200041063a00000b200241e0016a24000bf60d040a7f027e027f027e230041b0096b2203240020034190016a2001109808200341d0066a2003280290012204200328029801220510ad0541022106024020032d00d006220741024622080d002004200510ff010b200341f8036a411f6a2209200341f0066a280000360000200341f8036a41186a220a200341e9066a290000370300200341f8036a41106a220b200341e1066a290000370300200341f8036a41086a220c200341d9066a290000370300200320032900d1063703f80320034198076a290300210d20034190076a290300210e200341fc066a280200210f200341f8066a2802002110200341f4066a2802002105024020080d00200341c8006a411f6a2009280000360000200341c8006a41186a200a290300370300200341c8006a41106a200b290300370300200341c8006a41086a200c290300370300200320032903f803370348200721060b0240200328029401450d002004102e0b024002400240024002400240200641037122044103460d0020040e03010001010b200341f0006a41186a2206200341c8006a41186a290300370300200341f0006a41106a2204200341c8006a41106a290300370300200341f0006a41086a2208200341c8006a41086a290300370300200320032903483703702003200f3602c403200320053602c00320034190016a200341c0036a1098010240200328029001411c460d00200341386a200341f0006a200e200d10fb01200341a8076a200d370300200341a0076a200e370300200341d0066a41086a410c3a0000200341f9066a200329037037000020034181076a200829030037000020034189076a200429030037000020034191076a2006290300370000200341e1066a200141086a290000370000200341e9066a200141106a290000370000200341f1066a200141186a2900003700002001290000210d200341093a00d006200341d0066a41096a200d370000200341d0066a10fe01200341f8036a20034190016a41b00210e9081a4110102c2201450d02200141f8f7c60036020c200141013602082001428180808010370200024002404101200341f8036a1093060d00200341e8036a41023a000041002106200341e0036a41003a000020012001280200417f6a2204360200200342003703d003200342013703c803024020040d002001280208200128020c2802001103000240200128020c280204450d002001280208102e0b200141046a22042004280200417f6a220436020020040d002001102e0b200341f8036a10dc020c010b200341d0066a200341f8036a41b00210e9081a2003418a096a200341b2066a29010037010020034192096a200341ba066a2901003701002003419a096a200341c2066a290100370100200341a0096a200341c8066a290100370100200341003b018009200320032901aa0637018209200320013602a809200341c8036a200341d0066a20034180096a10dd0220032903c8035021060b200341dc066a2002360200200341d8066a41073a0000200341093a00d006200341d0066a41096a20063a0000200341d0066a10fe01200041063a000020100d040c050b200341186a200341f0006a200e200d10cb022003290318210d2003200341186a41086a290300220e3703d8062003200d3703d00602400240200d200e844200520d002003200341d0066a3602f803200341f8036a10cc020c010b200342f0f2bda1a7ee9cb9f9003703f803200341d0066a200341f8036a10cd02200341086a200341d0066a200d200e10fd0120034188046a200341086a41086a2903002211200e7d20032903082212200d54ad7d200e20117d200d201254ad7d2012200d562011200e562011200e511b22061b37030020032012200d7d200d20127d20061b3703800420032006ad3703f803200341f8036a41086a21040240024020060d00200320043602c803200341c8036a10cc020c010b200320043602c803200341c8036a10ce020b200341e8066a200e370300200341e0066a200d370300200341d8066a41063a00002003410e3a00d006200341d0066a10fe010b200341d0066a41086a410d3a0000200341fc066a20023602002001290000210d200341093a00d006200341d0066a41096a200d370000200341e1066a200141086a290000370000200341e9066a200141106a290000370000200341f1066a200141186a290000370000200341d0066a10fe012000411210930820100d030c040b200341d0066a41086a410e3a0000200341fc066a20023602002001290000210d200341093a00d006200341d0066a41096a200d370000200341e1066a200141086a290000370000200341e9066a200141106a290000370000200341f1066a200141186a290000370000200341d0066a10fe0120004110109308200641037122014103460d0120010e03030103030b1036000b2010450d010b2005102e0b200341b0096a24000bf50101047f230041306b22022400200241de80ca004109108102200241106a41f780ca004109108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000be70301047f23004180016b22022400200241386a41a081ca004107108102200241d8006a41a781ca0041121081022002200136027c2002200241fc006a410410a3013703282002410c6a200241fc006a41046a3602002002200241306a3602042002200241fc006a3602082002200241286a360200200241c8006a2002107c024002402002280250220341206a2201417f4c0d000240024020010d00410121040c010b2001102c2204450d020b200241003602302002200136022c20022004360228200241286a200241386a41101074200241286a200241d8006a41101074200241286a20022802482201200310740240200228024c450d002001102e0b200220022802282201200228023010a503200241e0006a22032002410c6a290200370300200241d8006a41106a200241146a290200370300200241f0006a22042002411c6a290200370300200241f8006a2205200241246a280200360200200220022902043703580240024020022802004101460d00200041003602000c010b20004101360200200020022903583702042000410c6a2003290300370200200041146a200241e8006a2903003702002000411c6a2004290300370200200041246a20052802003602000b0240200228022c450d002001102e0b20024180016a24000f0b1038000b1036000bcc0d04037f017e057f077e230041b0026b220424000240024002400240024002400240200141e0006a22052001413c6a412010ec08450d0020044180016a41186a200541186a29000037030020044180016a41106a200541106a29000037030020044180016a41086a200541086a29000037030020042005290000370380010240200120044180016a10af022206450d00200628020c41004a0d010b200441e0006a41086a2201200541086a290000370300200441e0006a41106a2203200541106a290000370300200441e0006a41186a2202200541186a290000370300200420052900003703604130102c2205450d01200541003a0000200520042903603700012005200429008001370021200541096a2001290300370000200541116a2003290300370000200541196a2002290300370000200541286a220120044187016a29000037000002400240024020052d00000e0402020002010b200541086a280200450d01200541046a280200102e0c010b2001280200450d00200541246a280200102e0b2005102e200041003602400c060b2004410036021420042005360210200441bc81ca0036020c20042001360208200441c8016a4120360200200420033602c401200420023602c0014124102c2205450d002004422437021c20042005360218200441186a200441c0016a410410744120200441186a1076200441186a20034120107420044180016a200441086a20042802182205200428022010aa020240200428021c450d002005102e0b02402004280280014101470d000240024020042802840122052d00000e0407070007010b200541086a280200450d06200541046a280200102e0c060b200541286a280200450d05200541246a280200102e0c050b02402004280284012205450d000240024020044188016a2903002207422088a741044f0d00410021010c010b20052800002103410121010b02402007a7450d002005102e0b2001450d002004200336021820044180016a200441086a200441186a410410aa0202402004280280014101470d000240024020042802840122052d00000e0407070007010b200541086a280200450d06200541046a280200102e0c060b200541286a280200450d05200541246a280200102e0c050b024020042802840122020d00200041003602400c070b200420044188016a2903002207422088a7220636025c2004200236025841002105200441003a00382006417f6a21010240034020062005460d01200441186a20056a200220056a22032d00003a00002004200341016a3602582004200541016a22033a00382004200136025c2001417f6a21012003210520034120460d040c000b0b0240200541ff0171450d00200441003a00380b410021050c030b200041003602400c050b1036000b200441c0016a41086a2205200441186a41086a290300370300200441c0016a41106a2201200441186a41106a290300370300200441c0016a41186a2206200441186a41186a290300370300200420042903183703c0010240200341ff0171411f4b0d00410021050c010b200441e0006a41086a2005290300370300200441e0006a41106a2001290300370300200441e0006a41186a2006290300370300200420042903c001370360200441c0016a200441d8006a108505024020042802e00122050d00410021050c010b20044180016a41186a2201200441e0006a41186a29030037030020044180016a41106a2203200441e0006a41106a29030037030020044180016a41086a2206200441e0006a41086a29030037030020044180016a41286a2208200441c0016a41086a29030037030020044180016a41306a2209200441c0016a41106a29030037030020044180016a41386a220a200441c0016a41186a290300370300200441f0016a41086a220b200441ec016a2802003602002004200429036037038001200420042903c0013703a0012004200441e4016a2902003703f001200441186a41386a220c200a290300370300200441186a41306a2009290300220d370300200441186a41286a2008290300220e370300200441186a41206a20042903a001220f370300200441186a41186a20012903002210370300200441186a41106a20032903002211370300200441186a41086a2006290300221237030020042004290380012213370318200041306a200d370300200041286a200e370300200041206a200f370300200041186a2010370300200041106a2011370300200041086a201237030020002013370300200041386a200c290300370300200020042903f001370244200041cc006a200b2802003602000b200020053602402007a7450d022002102e0c020b2005102e200041003602400c010b2005102e200041003602400b200441b0026a24000bca32021a7f0c7e23002201210220014180056b41607122012400200041246a220328020022042802002105200341d0a1c00036020020002802202106200041003602202000412c6a2203280200210720034100360200200041286a41003602002001200036021c2004200641016a22086a2109200441046a21032005417f7341808182847871210a200141a0026a410572210b200141a0026a41276a210c200141a0026a41206a210d2004210502400240034002400240200a0d000340024020032009490d004100210e0c060b200541c07d6a21052003280200210e200341046a220f2103200e41808182847871220e418081828478460d000b200e41808182847873220a417f6a200a71210e0c010b200a417f6a200a71210e2005450d022003210f0b20014180046a41186a221020054100200a684103766b41d0006c6a221141b07f6a220341186a29020037030020014180046a41106a2212200341106a29020037030020014180046a41086a2213200341086a2902003703002001200329020037038004201141506a280200210a201141546a2d00002111200c200341cc006a280000360000200d200341c5006a290000370300200141a0026a41186a22142003413d6a290000370300200141a0026a41106a2215200341356a290000370300200141a0026a41086a22162003412d6a290000370300200120032900253703a0022007417f6a2107024020114102470d00200f21030c030b200141b8036a41186a22032010290300370300200141b8036a41106a22172012290300370300200141b8036a41086a22182013290300370300200141a8016a41086a22192016290300370300200141a8016a41106a22162015290300370300200141a8016a41186a22152014290300370300200141a8016a41206a2214200d290300370300200141a8016a41276a221a200c28000036000020012001290380043703b803200120012903a0023703a801201020032903003703002012201729030037030020132018290300370300200120012903b80337038004200b20012903a801370000200b41086a2019290300370000200b41106a2016290300370000200b41186a2015290300370000200b41206a2014290300370000200b41276a201a280000360000200120113a00a4022001200a3602a002200128021c220341d0006a2802002111200328024c210302400240200a4125490d0020012802ac02210a20012802a80221100c010b200b21100b200120012f01cc023b01c8042001200a3602c404200120103602c004200320014180046a200141c0046a201128021c110600024020012802a0024125490d0020012802a802102e0b200f2103200e210a0c000b0b410021050b02402007450d00034002400240200e0d000340200320094f0d04200541c07d6a21052003280200210e200341046a220f2103200e41808182847871220e418081828478460d000b200e41808182847873220e417f6a200e71210b200f21030c010b2005450d02200e417f6a200e71210b0b200e68210f200b210e20054100200f4103766b41d0006c6a220f41506a2802004125490d00200f41586a280200102e200b210e0c000b0b024002402006450d00200441ff01200641056a10eb081a200641074d0d00200841037641076c21030c010b200621030b200020063602202000412c6a4100360200200041286a2003360200200041246a2004360200024002400240024002400240200128021c22052d00584101460d00200541dc006a28020021030240200541c8006a220b280200220e200e417f6a2209200541c0006a220f280200220e2005413c6a220a2802006b716b4101470d00200a10a502200b280200417f6a2109200f280200210e0b200f2009200e41016a71360200200541c4006a280200200e4102746a200336020002400240024002400240024002400240024002400240200541386a280200220e20034d0d00200541306a2209280200200341fc006c6a2203290210211b200320012903b0023702102003290208211c200320012903a802370208200341186a220e290200211d200e20012903b802370200200141003a00a002200141003602a4022003290200211e200320012903a002370200200141206a41086a220e200341e8006a290200370300200141206a41106a220f200341f0006a290200370300200141206a41186a220b200341f8006a2802003602002001201b370390012001201c370388012001201e37038001200120032902603703202001201d370398012003290240211f200341c8006a2902002120200341d0006a2902002121200341d8006a290200212220032902202123200341286a2902002124200341306a29020021252001200341386a29020022263703782001202537037020012024370368200120233703602001202237035820012021370350200120203703482001201f3703400240201ea741ff01714101470d00200141a8016a41176a220a200129009801221e370000200141a8016a41106a2211200129009101221c370300200141a8016a41086a2210200129008901221b37030020052802542203200129008101221d37000020032023a722053a001f200341086a201b370000200341106a201c370000200341176a201e3700002001201d3703a801200141a0026a41d8006a2022370300200141a0026a41d0006a2021370300200141a0026a41c8006a2020370300200141e0026a201f370300200141dc026a200128027c360200200141d4026a2001290274370200200141cc026a200129026c370200200120012902643702c40220014180036a2001290320370300200141a0026a41e8006a200e290300370300200141a0026a41f0006a200f290300370300200141a0026a41f8006a200b280200360200200141a9026a2010290300370000200141b1026a2011290300370000200141a0026a41186a200a290000370000200120012903a8013700a102200141c0026a20053a0000200141013a00a0022009200141a0026a109d082103200128021c220141003a0058200141dc006a20033602000c0c0b201ca72105201c422088a72103200141003602d401200141003a00ac01200141003602a801200141e8016a41106a2001280258360200200141e8016a41086a2001290350370300200120012903483703e80102400240024002400240201e422088a70e050102030400010b200141c0026a2024370300200141b8026a2023370300200141b0026a201d370300200141a8026a201b370300200141c8026a2025370300200120053602a002200120033602a4020240024020034125490d00201b422088a7210b201da721030c010b200141a9026a210b0b2005410176210f024002402005410171450d002003200f4d0d08200b200f6a2d0000410f71210e4100210a200f41016a210f0c010b2003200f490d064101210a4100210e0b200341017420056b220541ffff03200541ffff03491b220541017641036a2211102c2210450d142003200f6b2109200b200f6a210f200141003602e001200120113602dc01200120103602d80102402026422088a72218410020181b2211450d00200120053602840420014181023b01800420014180046a200141d8016a10ff0541002105200a450d0a410021030c0d0b2001200536028404200141013b01800420014180046a200141d8016a10ff0541002105200a450d0a410021030c0b0b4101102c2203450d13200141013602dc01200120033602d801200341003a0000200141013602e0010c0d0b200141c0026a2024370300200141b8026a2023370300200141b0026a201d370300200141a8026a201b370300200141c8026a2025370300200120053602a002200120033602a4020240024020034125490d00201b422088a72109201da721030c010b200141a9026a21090b2005410176210e024002402005410171450d002003200e4d0d08200141013a00800420014188046a2003200e41016a22056b3602002001200920056a3602840420012009200e6a2d0000410f713a0081040c010b2003200e490d0620014188046a2003200e6b360200200141003b01800420012009200e6a360284040b200141d8016a20014180046a2026a72203201fa710970702402026422088a7450d002003102e0b20012802a4024125490d0c200141ac026a280200102e0c0c0b200141c0026a2024370300200141b8026a2023370300200141b0026a201d370300200141a8026a201b370300200141c8026a2025370300200120053602a002200120033602a4020240024020034125490d00201b422088a7210e201da721030c010b200141a9026a210e0b200120053602e803200120033602e4032001200e3602e003200141c0046a200141e0036a109e08200141a8016a200141e0036a41002001109f082103200128021c2105200141b8036a41086a201f370300200141b8036a41106a20012903e801370300200141d0036a200141e8016a41086a290300370300200141d8036a200141e8016a41106a280200360200200120263703b80320014180046a2005200141b8036a200141a8016a10a008200141a8016a200310a108109607000b109507000b2003200e419482ca00103c000b200f200341e0eecc001056000b200f200341f0eecc00103c000b200e200341e0eecc001056000b200e200341f0eecc00103c000b410121030c020b410121030b03400240024020030e020001010b200520094f0d03200f20056a2d0000210e200541016a2105410121030c010b02400240024020012802e001220320012802dc01470d00200341016a220b2003490d0b2003410174220a200b200a200b4b1b220b4108200b41084b1b210b0240024020030d0020014100360280040c010b20014180046a41086a41013602002001200336028404200120012802d801360280040b200141b8036a200b410120014180046a107d200141c0036a280200210b20012802b8034101460d0120012802bc03210a2001200b3602dc012001200a3602d8010b20012802d80120036a200e3a00002001200341016a3602e0010c010b200b0d0a0c090b410021030c000b0b03400240024020030e020001010b200520094f0d02200f20056a2d0000210e200541016a2105410121030c010b02400240024020012802e001220320012802dc01470d00200341016a220b2003490d0a2003410174220a200b200a200b4b1b220b4108200b41084b1b210b0240024020030d0020014100360280040c010b20014180046a41086a41013602002001200336028404200120012802d801360280040b200141b8036a200b410120014180046a107d200141c0036a280200210b20012802b8034101460d0120012802bc03210a2001200b3602dc012001200a3602d8010b20012802d80120036a200e3a00002001200341016a3602e0010c010b200b450d080c090b410021030c000b0b20012802e00122162103024002400240024002400240201620012802dc01470d00201641016a22032016490d0b201641017422052003200520034b1b22034108200341084b1b21030240024020160d0020014100360280040c010b20014180046a41086a41013602002001201636028404200120012802d801360280040b200141b8036a2003410120014180046a107d200141c0036a280200210320012802b8034101460d0120012802bc032105200120033602dc01200120053602d80120012802e00121030b20012802d80120036a41003a0000200120012802e00141016a22033602e001024002400240200320012802dc01470d00200341016a22052003490d0d2003410174220e2005200e20054b1b22054108200541084b1b21050240024020030d0020014100360280040c010b20014180046a41086a41013602002001200336028404200120012802d801360280040b200141b8036a2005410120014180046a107d200141c0036a280200210320012802b8034101460d0120012802bc032105200120033602dc01200120053602d80120012802e00121030b2026a7221741c0046a211420012802d80120036a41003a0000200120012802e00141016a3602e00102402011450d00201f422088a72203200141d8016a1076200141d8016a2011200310740b20142017470d0141002111410021030c040b20030d0c0c0b0b20014180046a410172210e200141a9026a2119200141c0046a41017221054100210a20172103410021114101210b02400340200141023a0080042003290200211e200129039804211c2001290390042123200129038804211b20032001290380043702002003290208211d2003201b3702082003290210211b20032023370210200341186a220929020021232009201c370200200120233703d8042001201b3703d0042001201d3703c8042001201e3703c004200341206a280200210720014180046a41176a2210200541176a29000037000020014180046a41106a2209200541106a29000037030020014180046a41086a220f200541086a29000037030020012005290000370380040240201ea7220c41ff017122124103470d0020114180fe037141087621030c060b200141e0036a41176a22132010290000370000200141e0036a41106a22102009290300370300200141e0036a41086a200f290300221e3703002001200129038004221c3703e003200141c0046a41176a220d2013290000370000200141c0046a41106a22132010290300370300200141c0046a41086a2210201e3703002001201c3703c00402400240024020124102470d00200141023a00b8030c010b0240024020012802a40222124125490d0020012802b002211220012802ac0221150c010b201921150b200120012802a0023602f804200120123602f404200120153602f004200141a8016a200141f0046a4101200a109f082112200128021c2115200e20012903c004370000200e41086a2010290300370000200e41106a2013290300370000200e41176a200d2900003700002001200c3a008004200120073602a004200141b8036a201520014180046a200141a8016a10a008200141a8016a201210a10820012d00b8034103460d010b20014180046a41206a200141b8036a41206a29030037030020014180046a41186a200141b8036a41186a2903003703002009200141b8036a41106a290300370300200f200141b8036a41086a290300370300200120012903b803221e37038004410021090240024002400240201ea741ff0171417f6a0e020103000b4120200141d8016a1076200141d8016a200e412010740c010b200141c0046a41186a200e41186a2900003703002013200e41106a2900003703002010200e41086a2900003703002001200e2900003703c00420012802a404220941214f0d042009200141d8016a1076200141d8016a200141c0046a200910740b200b21090b200a41016a210a200b410174210b20092011722111200341246a22032014460d040c010b0b20114180fe037141087621030c050b2009412041ccd3c800104d000b20030d0a0c090b20114180fe037141087621030b200141033a00c00420014197046a20012900d80437000020014190046a20012900d10437030020014188046a20012900c904370300200120012900c104370380040b200141033a00b8030b201641026a21052016417e4f0d0220012802e001220e2005490d0320012802d80120166a2003410874201141ff0171723b000002402018450d00201fa7450d002018102e0b2017102e20012802a4024125490d00200141ac026a280200102e0b200128021c220341d0006a2802002105200328024c210320014180046a41086a41002802cca140360200200141002902c4a14037038004200141a0026a200320014180046a20012802d80120012802e0012005280214110500200128021c2203280254220520012903a002370000200541086a200141a0026a41086a290300370000200541106a200141a0026a41106a290300370000200541186a200141a0026a41186a2903003700002003200328027c41016a36027c2003280254220541186a290000211e200541106a290000211c200541086a290000211f200341d9006a2005290000370000200341013a0058200341e1006a201f370000200341e9006a201c370000200341f1006a201e370000024020012802dc01450d0020012802d801102e0b20012802a8014125490d00200141b0016a280200102e0b0240200041386a2802002203450d0020002802302101200341fc006c210303400240024020012d00000d00200141046a10e2010c010b200141246a10e2010b200141fc006a2101200341847f6a22030d000b0b0240200041346a2802002201450d00200141fc006c450d002000280230102e0b200041c8006a280200210102400240200041c0006a28020022032000413c6a2802002205490d00200120034f0d012003200141b4f1c000104d000b20012005490d030b0240200141ffffffff0371450d00200041c4006a280200102e0b024020002802202205450d0002402000412c6a280200450d00200041246a280200220341046a2101200520036a41016a210e2003280200417f73418081828478712105024003400240024020050d0003402001200e4f0d04200341c07d6a210320012802002105200141046a220921012005418081828478712205418081828478460d000b2005418081828478732205417f6a200571210f200921010c010b2003450d022005417f6a200571210f0b2005682109200f21052003410020094103766b41d0006c6a220941506a2802004125490d00200941586a280200102e200f21050c000b0b200028022021050b200041246a280200200541016aad42d0007ea76b102e0b200224000f0b2016200541dcd3c8001057000b2005200e41dcd3c800104d000b41c4f1c000412341e8f1c0001039000b1038000b1036000b960401037f23004190016b2206240041002107200641003602080240024020012d00584101460d00200141dc006a28020021080c010b200641366a200141db006a2d00003a0000200641206a200141e8006a290000370300200641286a200141f0006a290000370300200641306a200141f8006a2d00003a00002006200141d9006a2f00003b01342006200141e0006a290000370318200141dc006a2800002108410121070b200641c8006a41086a2006290318370300200641c8006a41106a200641186a41086a290300370300200641c8006a41186a200641186a41106a290300370300200641e8006a200641186a41186a280200360200200620073a0048200620062f01343b00492006200836024c2006200641366a2d00003a004b200641003602782006200336027420062002360270024002402005417f4c0d004101210702402005450d002005102c2207450d020b2006200536028401200620073602800120072004200510e9081a2006200536028801200641386a2001200641c8006a200641f0006a20064180016a200641086a10ad08200628023c21050240024020062802384101460d00200141003a00582000200629030837020420004100360200200141dc006a20053602002000410c6a200641106a2802003602000c010b200041013602002000200536020420062802082201450d00200628020c450d002001102e0b20064190016a24000f0b1038000b1036000bdd0302047f017e230041a0016b220224000240024002400240200028020c2203200041106a280200470d002002200141fc0010e90821030240024020002802082201200041046a280200470d00200141016a22042001490d04200141017422052004200520044b1b22044104200441044b1bad42fc007e2206422088a74541027421042006a721050240024020010d0020034100360290010c010b20034198016a41043602002003200141fc006c3602940120032000280200360290010b20034180016a2005200420034190016a107d20034188016a28020021012003280280014101460d012000200328028401360200200041046a200141fc006e360200200028020821010b2000280200200141fc006c6a200341fc0010e9081a20002000280208220341016a3602080c020b2001450d021036000b2000410c6a200041186a280200417f6a200341016a71360200200041146a28020020034102746a28020021032002200141fc0010e90821012000280208220420034d0d020240024020002802002200200341fc006c6a22042d00000d002000200341fc006c6a41046a10e2010c010b2000200341fc006c6a41246a10e2010b2004200141fc0010e9081a0b200241a0016a240020030f0b1038000b2003200441f882ca00103c000bb80101057f2001280208220241017621032001280204210402400240024002402002410171450d00200420034d0d034101210220012802002205200341016a22066a2101200520036a2d0000410f712105200621030c010b20042003490d01200128020020036a210141002105410021020b200020023a000c20002001360204200041003602002000410d6a20053a0000200041086a200420036b3602000f0b2003200441e0eecc001056000b2003200441f0eecc00103c000b960a01127f230041106b2204240002400240024002400240024020010d00410021010c010b200141086a28020022054101762106200141046a2802002107024002400240024002400240024002402005410171450d00200720064b0d012006200741f0eecc00103c000b20072006490d02200720066b2108200128020020066a21090c010b20002001280200220120066a2d0000410f7110e3082007200641016a22066b2108200120066a21090b0240024002400240024002400240200028020022014125490d002000412c6a210a2000410c6a2206280200410174200028022c470d02200628020021010c010b2000412c6a210a2001410174200028022c470d020b20042000200810fc06024020042802004101470d00200441086a2802000d0c41d0f0cc00411141e4f0cc001039000b02400240200028020022064125490d002000410c6a28020022062001490d08200041086a280200210b0c010b20062001490d07200041056a210b0b200b20016a220b20086a200b200620016b10ea081a200b2009200810e9081a0240024020002802004125490d002000410c6a21010c010b200021010b2001200620086a3602000c090b20080d01410021080c080b20080d01410021080c070b2000410c6a280200220b2006280200417f6a22064b0d01200b21010c0b0b20012001417f6a22064d0d0a200041056a20066a2d0000417071210b0c030b200041086a28020020066a2d0000417071210b20014125490d022000410c6a2802002101200041086a280200210c0c030b2006200741e0eecc001056000b41f4f1cc00411e4194f2cc001039000b200041056a210c0b200120064d0d03200c20066a200b3a000020092d0000210b02400240200028020022014125490d002000410c6a2802002101200041086a280200210c0c010b200041056a210c0b200120064d0d04200c20066a220120012d0000200b410476723a0000024002402008417f6a220d0d004100210d0c010b2008417f6a210e20084101200841014b1b417f6a210f410021012000410c6a2110200041086a2111200041056a21120340024002400240024020082001460d00200f2001460d01200920016a22062d00002113200641016a2d00002114024002402000280200220c4125490d0020102802002106201128020021152010210b0c010b200c21062000210b201221154124210c0b2006200c470d0320042000410110fc0620042802004101470d02200441086a2802000d0841d0f0cc00411141e4f0cc001039000b2008200841c0eecc00103c000b200141016a200841d0eecc00103c000b2000410c6a220b2802002106201128020021150b201520066a201441f001714104762013410474723a0000200b200b28020041016a360200200e200141016a2201470d000b0b2009200d6a2d00002115024002402000280200220b4125490d002000410c6a22012802002106200041086a280200210c0c010b200041056a210c200b2106200021014124210b0b02402006200b470d0020042000410110fc06024020042802004101470d00200441086a2802000d0441d0f0cc00411141e4f0cc001039000b2000410c6a22012802002106200041086a280200210c0b200c20066a20154104743a00002001200128020041016a3602000b200a200a28020020084101746a360200200741017420056b21010b02402002450d002000200310e308200141016a21010b200441106a240020010f0b1036000b2006200141a0eecc00103c000b2006200141b0eecc00103c000b200620014190eecc00103c000bec2603067f067e0d7f230022042105200441e0036b416071220424002004200336021420042001360210024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00004101460d00200241046a28020021020240200141c8006a220628020022032003417f6a2207200141c0006a220828020022032001413c6a22092802006b716b4101470d00200910a5022006280200417f6a2107200828020021030b20082007200341016a71360200200141c4006a28020020034102746a2002360200200141386a280200220320024d0d022001280230200241fc006c6a2201290210210a200120042903f0013702102001290208210b200120042903e801370208200441d8006a2001290240220c370300200441386a22032001290220370300200441f8006a2001290260370300200141186a2202290200210d200220042903f801370200200441003a00e001200441003602e4012001290200210e200120042903e001370200200441186a41d8006a2207200141d8006a290200370300200441186a41d0006a2208200141d0006a290200370300200441186a41c8006a2206200141c8006a290200370300200441186a41386a200141386a290200220f370300200441186a41306a2209200141306a290200370300200441186a41286a2210200141286a290200370300200441186a41186a2211200d370300200441186a41e8006a200141e8006a290200370300200441186a41f0006a200141f0006a290200370300200441186a41f8006a200141f8006a2802003602002004200a3703282004200b3703202004200e370318200ea741ff01714101460d01200ba72102200b422088a72101200c422088a72112200fa72113200441c0016a41086a22142003290300370300200441c0016a41106a22032010290300370300200441c0016a41186a2009290300370300200441a8016a41086a2008290300370300200441a8016a41106a2007280200360200200420112903003703c001200420062903003703a801200441d4006a290200220fa7211502400240024002400240200e422088a70e050102030400010b200441e0016a41086a200a370300200441e0016a41106a20042903c001370300200441e0016a41186a201429030037030020044180026a200329030037030020044188026a200441c0016a41186a290300370300200420023602e001200420013602e4010240024020014125490d00200a422088a7210620042802f00121010c010b200441e9016a21060b20024101762108024002402002410171450d00200120084d0d0a200620086a2d0000410f71210341002109200841016a21080c010b20012008490d0841012109410021030b200141017420026b220241ffff03200241ffff03491b220241017641036a2210102c2211450d19200120086b2107200620086a2108200441003602a0012004201036029c01200420113602980102402015410020151b2210450d00200420023602e40220044181023b01e002200441e0026a20044198016a10ff05410021022009450d0c410021010c0f0b200420023602e402200441013b01e002200441e0026a20044198016a10ff05410021022009450d0c410021010c0d0b4101102c2201450d182004410136029c012004200136029801200141003a0000200441013602a0010c0f0b200441e0016a41086a200a370300200441e0016a41106a20042903c001370300200441e0016a41186a201429030037030020044180026a200329030037030020044188026a200441c0016a41186a290300370300200420023602e001200420013602e4010240024020014125490d00200a422088a7210720042802f00121010c010b200441e9016a21070b20024101762103024002402002410171450d00200120034d0d0a200441013a00e002200441e8026a2001200341016a22026b3602002004200720026a3602e4022004200720036a2d0000410f713a00e1020c010b20012003490d08200441e8026a200120036b360200200441003b01e0022004200720036a3602e4020b20044198016a200441e0026a2013200f422088a710970702402015450d002013102e0b20042802e4014125490d0e200441ec016a280200102e0c0e0b200441e0016a41086a200a370300200441e0016a41106a20042903c001370300200441e0016a41186a201429030037030020044180026a200329030037030020044188026a200441c0016a41186a290300370300200420023602e001200420013602e4010240024020014125490d00200a422088a7210020042802f00121010c010b200441e9016a21000b200420023602c802200420013602c402200420003602c002200441a0036a200441c0026a109e082004280214200441c0026a41002004109f08210120042802102102200441a4026a201236020020044198026a41106a20042903a801370300200441b0026a200441b0016a290300370300200441b8026a200441a8016a41106a2802003602002004200f37029c022004201336029802200441e0026a200220044198026a2004280214220410a0082004200110a108109607000b109507000b200041003a000020002002290001370001200041196a200241196a290000370000200041116a200241116a290000370000200041096a200241096a2900003700000c120b20002004290019370001200041003a0000200041196a200441186a41196a290000370000200041116a200441186a41116a290000370000200041096a200441186a41096a2900003700000c0b0b20022003419482ca00103c000b2008200141e0eecc001056000b2008200141f0eecc00103c000b2003200141e0eecc001056000b2003200141f0eecc00103c000b410121010c020b410121010b03400240024020010e020001010b200220074f0d03200820026a2d00002103200241016a2102410121010c010b02400240024020042802a0012201200428029c01470d00200141016a22062001490d0e200141017422092006200920064b1b22064108200641084b1b21060240024020010d00200441003602e0020c010b200441e0026a41086a4101360200200420013602e40220042004280298013602e0020b20044198026a20064101200441e0026a107d200441a0026a28020021062004280298024101460d01200428029c0221092004200636029c0120042009360298010b20042802980120016a20033a00002004200141016a3602a0010c010b20060d0d0c0c0b410021010c000b0b03400240024020010e020001010b200220074f0d02200820026a2d00002103200241016a2102410121010c010b02400240024020042802a0012201200428029c01470d00200141016a22062001490d0d200141017422092006200920064b1b22064108200641084b1b21060240024020010d00200441003602e0020c010b200441e0026a41086a4101360200200420013602e40220042004280298013602e0020b20044198026a20064101200441e0026a107d200441a0026a28020021062004280298024101460d01200428029c0221092004200636029c0120042009360298010b20042802980120016a20033a00002004200141016a3602a0010c010b2006450d0b0c0c0b410021010c000b0b20042802a001221621010240024002400240024002402016200428029c01470d00201641016a22012016490d0e201641017422022001200220014b1b22014108200141084b1b21010240024020160d00200441003602e0020c010b200441e0026a41086a4101360200200420163602e40220042004280298013602e0020b20044198026a20014101200441e0026a107d200441a0026a28020021012004280298024101460d01200428029c0221022004200136029c01200420023602980120042802a00121010b20042802980120016a41003a0000200420042802a00141016a22013602a0010240024002402001200428029c01470d00200141016a22022001490d10200141017422032002200320024b1b22024108200241084b1b21020240024020010d00200441003602e0020c010b200441e0026a41086a4101360200200420013602e40220042004280298013602e0020b20044198026a20024101200441e0026a107d200441a0026a28020021012004280298024101460d01200428029c0221022004200136029c01200420023602980120042802a00121010b201341c0046a211720042802980120016a41003a0000200420042802a00141016a3602a00102402010450d00201220044198016a107620044198016a2010201210740b20172013470d0141002110410021010c040b20010d0f0c0e0b200441e0026a4101722103200441e9016a2118200441a0036a41017221024100210920132101410021104101210602400340200441023a00e0022001290200210e20042903f802210b20042903f002210a20042903e802210d200120042903e0023702002001290208210c2001200d3702082001290210210d2001200a370210200141186a2207290200210a2007200b3702002004200a3703b8032004200d3703b0032004200c3703a8032004200e3703a003200141206a2802002119200441e0026a41176a2211200241176a290000370000200441e0026a41106a2207200241106a290000370300200441e0026a41086a2208200241086a290000370300200420022900003703e0020240200ea7221a41ff017122144103470d0020104180fe037141087621010c060b200441c0026a41176a22122011290000370000200441c0026a41106a22112007290300370300200441c0026a41086a2008290300220e370300200420042903e002220b3703c002200441a0036a41176a221b2012290000370000200441a0036a41106a22122011290300370300200441a0036a41086a2211200e3703002004200b3703a00302400240024020144102470d00200441023a0098020c010b0240024020042802e40122144125490d0020042802f001211420042802ec01211c0c010b2018211c0b200420042802e0013602d803200420143602d4032004201c3602d0032004280214200441d0036a41012009109f0821142004280210211c200320042903a003370000200341086a2011290300370000200341106a2012290300370000200341176a201b2900003700002004201a3a00e002200420193602800320044198026a201c200441e0026a2004280214221910a0082019201410a10820042d0098024103460d010b200441e0026a41206a20044198026a41206a290300370300200441e0026a41186a20044198026a41186a290300370300200720044198026a41106a290300370300200820044198026a41086a2903003703002004200429039802220e3703e002410021070240024002400240200ea741ff0171417f6a0e020103000b412020044198016a107620044198016a2003412010740c010b200441a0036a41186a200341186a2900003703002012200341106a2900003703002011200341086a290000370300200420032900003703a003200428028403220741214f0d04200720044198016a107620044198016a200441a0036a200710740b200621070b200941016a21092006410174210620072010722110200141246a22012017460d040c010b0b20104180fe037141087621010c050b2007412041ccd3c800104d000b20010d0d0c0c0b20104180fe037141087621010b200441033a00a003200441f7026a20042900b803370000200441f0026a20042900b103370300200441e8026a20042900a903370300200420042900a1033703e0020b200441033a0098020b201641026a21022016417e4f0d0220042802a00122032002490d0320042802980120166a2001410874201041ff0171723b000002402015450d00200f428080808010540d002015102e0b2013102e20042802e4014125490d00200441ec016a280200102e0b0240024020042802a00122014120490d002004280210220241d0006a2802002108200228024c21062004280214220728022c22094101762102200728020021030240024020094101710d000240024020034125490d002007410c6a2802002103200741086a28020021070c010b200741056a21070b20032002490d07200420073602e002410021030c010b0240024020034125490d002007410c6a220928020022032002490d0a200741086a2210280200210720092802002103201028020021090c010b20032002490d09200741056a220721090b200320024d0d07200441e9026a200920026a2d000041f001713a0000200420073602e002410121030b200420033a00e802200420023602e402200441e0016a2006200441e0026a20042802980120012008280214110500200020042903e001370001200041096a200441e8016a290300370000200041116a200441f0016a290300370000200041196a200441f8016a290300370000200041003a000020042802102201200128027c41016a36027c0c010b200441f8016a22024200370300200441f0016a22034200370300200441e8016a22074200370300200442003703e001200441e0016a200428029801200110e9081a200041246a2001360200200041013a0000200041196a2002290300370000200041116a2003290300370000200041096a2007290300370000200020042903e0013700010b0240200428029c01450d00200428029801102e0b20042d0018450d060b2004413c6a10e201200524000f0b2016200241dcd3c8001057000b2002200341dcd3c800104d000b2002200341e0edcc00104d000b200220034180eecc00103c000b2002200341f0edcc00104d000b200524000f0b1038000b1036000b960301057f0240024002402001450d000240200028022c220220014b0d0002400240200028020022014125490d002000410c6a220228020021010c010b200021020b02402001450d00200241003602000b2000410036022c0f0b200220016b2203410176200341017122046a210202400240200028020022014125490d002000410c6a28020021050c010b200121050b0240200220054f0d002000410c6a2106200220056b41016a210203400240024020014125490d0020062802002101200621050c010b200021050b02402001450d0020052001417f6a3602000b2002450d01200241016a2102200028020021010c000b0b2000200336022c2004450d0002400240200028020022014125490d002000410c6a220528020022012001417f6a22024d0d04200041086a220628020020026a2d0000417071210020052802002101200628020021050c010b2001417f6a220220014f0d03200041056a220520026a2d000041707121000b200120024d0d01200520026a20003a00000b0f0b2002200141d0edcc00103c000b2002200141c0edcc00103c000b130020004119360204200041f086ca003602000b3400200041de80ca0036020420004100360200200041146a410e360200200041106a41e4ecca00360200200041086a42093702000b7c01017f230041f0006b22022400200241106a4200370300200241186a4200370300200241206a4200370300200241286a4200370300200241306a4200370300200241386a4200370300200241c0006a410036020020024108360204200241086a4200370300200241003a00002000200210c204200241f0006a24000b2f01017f02404104102c22020d001036000b2000420437020420002002360200410020001076410441002000109b010b130020004108360204200041b48bcb003602000b4301027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241e40036020c20002002410c6a41041074200241106a24000b4401027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241c0930636020c20002002410c6a41041074200241106a24000b4301027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241880e36020c20002002410c6a41041074200241106a24000b4b01027f230041106b2202240002404110102c22030d001036000b20004210370204200020033602002002420037030820024280a094a58d1d3703002000200241101074200241106a24000b4401027f230041106b2202240002404104102c22030d001036000b200042043702042000200336020020024180ce1836020c20002002410c6a41041074200241106a24000b880202037f017e230041106b220224000240024020002d00004101460d00200241003a000020012002410110742002200041046a28020036020020012002410410740c010b200241013a00002001200241011074200041246a28020021032000412c6a28020022042001107620012003200410742001200041016a41201074200041c0006a29030021052002200041c8006a2903003703082002200537030020012002411010742002200041306a28020036020020012002410410740240200041346a2802004101460d00200241003a000020012002410110740c010b200241013a000020012002410110742002200041386a28020036020020012002410410740b200241106a24000bba3205077f017e017f0b7e0b7f230022062107200641e0086b416071220624000240024002400240024002400240024002400240024002400240024020022d00004101470d00200641b8036a200241196a290000370300200641b0036a200241116a290000370300200641a8036a200241096a290000370300200620022900013703a003200328020822084101762102200328020421092003280200210a0240024020084101710d00024020092002490d00410021090c020b2002200941a0f0cc00104d000b20092002490d03200220094f0d04200a20026a2d00004170712108410121090b200141d0006a280200210b200128024c210c200641e9046a20083a0000200620093a00e804200620023602e4042006200a3602e004200620062f01c8073b01ea0420064188086a200c200641a0036a200641e0046a200b28020c1104000240024020062802880822090d00200641f0056a2201200641ab036a290000370300200641e8056a41106a2203200641b3036a290000370300200641fd056a2209200641b8036a290000370000200620062900a3033703e80520062d00a203210520062f01a003210a4130102c22020d011036000b200629028c08210d200641c0046a41186a200641a0036a41186a2208290300370300200641c0046a41106a200641a0036a41106a220b290300370300200641c0046a41086a200641a0036a41086a220c290300370300200620062903a0033703c004200641e0046a200641c0046a2009200d422088a7200141306a220e10ae0820062802e404210220062802e004210a20064188086a200641e0046a41086a41d40010e9081a200a4101460d0c200641e0036a20064188086a41d40010e9081a200620023602840520064188056a200641e0036a41d40010e9081a200641f9046a2008290300370000200641f1046a200b290300370000200641e9046a200c290300370000200641013a00e004200620062903a0033700e104200e200641e0046a109d082102200da7450d022009102e0c020b2002200a20054110747222053b0001200241013a0000200220062903e805370004200220062900e004370021200241036a20054110763a00002002410c6a2001290300370000200241146a2003290300370000200241196a2009290000370000200241286a200641e7046a2900003700000c0c0b200241046a28020021020b0240200141c8006a220b28020022092009417f6a2208200141c0006a220a28020022092001413c6a220c2802006b716b4101470d00200c10a502200b280200417f6a2108200a28020021090b200a2008200941016a71360200200141c4006a28020020094102746a2002360200200141386a280200220920024d0d02200141306a220a280200200241fc006c6a2202290210210f200220062903f00437021020022902082110200220062903e804370208200241186a22092902002111200920062903f804370200200641003a00e004200641003602e4042002290200210d200220062903e00437020020022902402112200241c8006a2902002113200241d0006a2902002114200241d8006a290200211520022902202116200241286a2902002117200241306a2902002118200241386a290200211920064180036a41086a2209200241e8006a29020037030020064180036a41106a2208200241f0006a29020037030020064180036a41186a220b200241f8006a280200360200200620113703f8032006200f3703f003200620103703e8032006200d3703e003200620193703d804200620183703d004200620173703c804200620163703c004200620153703b803200620143703b003200620133703a803200620123703a0032006200229026037038003200641d0036a41086a2202200441086a280200360200200620042902003703d00302400240024002400240024002400240200da7220c41ff01714101470d002003280200211a2003280204211b2003280208210e20064188076a41186a20062802fc0336020020064188076a41106a20062902f40337030020064188076a41086a20062902ec03370300200620062902e40337038807200641bc086a2015370200200641b4086a201437020020064188086a41246a2013370200200641a4086a201237020020064188086a41186a20062802dc0436020020064188086a41106a20062902d40437030020064188086a41086a20062902cc04370300200620062902c4043703880820064188086a413c6a20062903800337020020064188086a41c4006a2009290300370200200641d4086a2008290300370200200641dc086a200b280200360200200641e8056a41086a2002280200360200200620062903d0033703e805200641e0046a200120064188086a2003200641e8056a200510af0820062802e404210220062802e0044101460d07200d420888a721092016a72103200641e8076a41186a220820064180056a280200360200200641e8076a41106a220b200641e0046a41186a290300370300200641e8076a41086a221c200641e0046a41106a221d290300370300200641c8076a41086a221e2006418d056a290000370300200641c8076a41106a221f20064195056a290000370300200641c8076a41176a2220200641e0046a413c6a29000037000020062006290085053703c8072006200641e0046a41086a22212903003703e807200641e0046a41246a2d00002104200641a8076a41086a2222200641ad056a290000370300200641a8076a41106a2223200641b5056a290000370300200641a8076a41176a2224200641bc056a280000360000200620062900a5053703a807200641e0046a41c4006a2d0000210520020e03020501020b200641bc086a2019370200200641b4086a201837020020064188086a41246a2017370200200641a4086a201637020020064188086a41186a20062802fc0336020020064188086a41106a20062902f40337030020064188086a41086a20062902ec0337030020064188086a413c6a20062903a00337020020064188086a41c4006a20062903a803370200200641d4086a20062903b003370200200641dc086a20062802b803360200200620062902e4033703880820064188076a41086a2002280200360200200620062903d00337038807200641e0046a200120064188086a200320064188076a200510af0820062802e404210220062802e0044101460d06200641e8056a41186a220520064180056a280200360200200641e8056a41106a2208200641e0046a41186a290300370300200641e8056a41086a220b200641e0046a41106a290300370300200641c8076a41086a220c2006418d056a290000370300200641c8076a41106a220e20064195056a290000370300200641c8076a41176a221a200641e0046a413c6a29000037000020062006290085053703c8072006200641e0046a41086a2903003703e805200641e0046a41246a2d00002103200641e8076a41086a221b200641ad056a290000370300200641e8076a41106a221c200641b5056a290000370300200641e8076a41176a221d200641bc056a280000360000200620062900a5053703e807200641e0046a41c4006a2d0000210441022101024020020e03000304000b200641e8066a41186a2005280200360200200641e8066a41106a2008290300370300200641e8066a41086a200b290300370300200641c8066a41086a200c290300370300200641c8066a41106a200e290300370300200641c8066a41176a201a290000370000200641a8066a41086a201b290300370300200641a8066a41106a201c290300370300200641a8066a41176a201d280000360000200620062903e8053703e806200620062903c8073703c806200620062903e8073703a80641002101410121090c030b200e410176210202400240200e4101710d000240201b2002490d00410021040c020b2002201b41a0f0cc00104d000b201b2002490d0a2002201b4f0d0b201a20026a2d00004170712108410121040b20064188086a201a200210b008200641b5086a20083a0000200641eb046a20064188076a41086a290300370000200641f3046a20064188076a41106a290300370000200641fb046a20064188076a41186a280200360000200641e0046a41286a20064188086a41086a29030037030020064190056a20064188086a41106a29030037030020064198056a20064188086a41186a290300370300200641a0056a200641a8086a290300370300200620043a00b408200641a8056a20064188086a41286a290300370300200620033a00ff0420062006290388073700e304200620062903880837038005200620093b01e004200620094110763a00e2042001200641e0046a10b108410221010c040b200e410176210202400240200e4101710d000240201b2002490d00410021080c020b2002201b41a0f0cc00104d000b201b2002490d0b2002201b4f0d0c201a20026a2d0000417071210b410121080b20064188086a201a200210b008200641b5086a200b3a0000200641eb046a20064188076a41086a290300370000200641f3046a20064188076a41106a290300370000200641fb046a20064188076a41186a280200360000200641e0046a41286a20064188086a41086a29030037030020064190056a20064188086a41106a29030037030020064198056a20064188086a41186a290300370300200641a0056a200641a8086a290300370300200620083a00b408200641a8056a20064188086a41286a290300370300200620033a00ff0420062006290388073700e304200620062903880837038005200620093b01e004200620094110763a00e2042001200641e0046a10b108200641e8066a41086a200641e8076a41086a290300370300200641e8066a41106a200641e8076a41106a290300370300200641e8066a41186a200641e8076a41186a280200360200200641c8066a41086a200641c8076a41086a290300370300200641c8066a41106a200641c8076a41106a290300370300200641c8066a41176a200641c8076a41176a290000370000200641a8066a41086a200641a8076a41086a290300370300200641a8066a41106a200641a8076a41106a290300370300200641a8066a41176a200641a8076a41176a280000360000200620062903e8073703e806200620062903c8073703c806200620062903a8073703a806410021014101210920042103200521040c030b200641e8066a41186a2005280200360200200641e8066a41106a2008290300370300200641e8066a41086a200b290300370300200641c8066a41086a200c290300370300200641c8066a41106a200e290300370300200641c8066a41176a201a290000370000200641a8066a41086a201b290300370300200641a8066a41106a201c290300370300200641a8066a41176a201d280000360000200620062903e8053703e806200620062903c8073703c806200620062903e8073703a80641002109410021010b410021020c0a0b200641e8066a41086a20064188076a41086a290300370300200641e8066a41106a20064188076a41106a290300370300200641e8066a41186a20064188076a41186a280200360200200641eb046a201c290300370000200641f3046a200b290300370000200641fb046a2008280200360000200641a8066a41176a2020290000370000200641a8066a41106a201f290300370300200641a8066a41086a201e29030037030020062006290388073703e806200620062903e8073700e304200620062903c8073703a80620064188066a41176a202428000036000020064188066a41106a202329030037030020064188066a41086a2022290300370300200641c8066a41176a200641e0046a41176a290000370000200641c8066a41106a201d290000370300200641c8066a41086a2021290000370300200620062903a80737038806200620062900e0043703c80641012101410021090b200c41807e7121020c080b410121010c080b2002200941b0f0cc00104d000b2002200941c0f0cc00103c000b20022009419482ca00103c000b2002201b41b0f0cc00104d000b2002201b41c0f0cc00103c000b2002201b41b0f0cc00104d000b2002201b41c0f0cc00103c000b200641c8076a41186a200641e8066a41186a280200360200200641c8076a41106a200641e8066a41106a290300370300200641c8076a41086a200641e8066a41086a290300370300200641e0046a41086a200641c8066a41086a290300370300200641e0046a41106a200641c8066a41106a290300370300200641e0046a41176a200641c8066a41176a29000037000020064188086a41086a200641a8066a41086a29030037030020064188086a41106a200641a8066a41106a29030037030020064188086a41176a200641a8066a41176a290000370000200620062903e8063703c807200620062903c8063703e004200620062903a80637038808200641e8056a41176a20064188066a41176a280000360000200641e8056a41106a20064188066a41106a290300370300200641e8056a41086a20064188066a41086a29030037030020062006290388063703e80520012002722102410021010b200641e0026a41086a2208200641c8076a41086a290300370300200641e0026a41106a220b200641c8076a41106a290300370300200641e0026a41186a220c200641c8076a41186a280200360200200641c0026a41086a220e200641e0046a41086a290300370300200641c0026a41106a221a200641e0046a41106a290300370300200641c0026a41176a221b200641e0046a41176a290000370000200620062903c8073703e002200620062903e0043703c002200641a0026a41176a221c20064188086a41176a290000370000200641a0026a41106a221d20064188086a41106a290300370300200641a0026a41086a221e20064188086a41086a29030037030020064180026a41086a221f200641e8056a41086a29030037030020064180026a41106a2220200641e8056a41106a29030037030020064180026a41176a2221200641e8056a41176a28000036000020062006290388083703a002200620062903e805370380020240024020010d00200641e0016a41186a200c280200360200200641e0016a41106a200b290300370300200641e0016a41086a2008290300370300200641c0016a41086a200e290300370300200641c0016a41106a201a290300370300200641c0016a41176a201b290000370000200641a0016a41086a201e290300370300200641a0016a41106a201d290300370300200641a0016a41176a201c290000370000200620062903e0023703e001200620062903c0023703c001200620062903a0023703a00120064180016a41176a202128000036000020064180016a41106a202029030037030020064180016a41086a201f290300370300200620062903800237038001200241ff01714102460d01200641e0006a41186a2201200641e0016a41186a280200360200200641e0006a41106a2208200641e0016a41106a290300370300200641e0006a41086a220b200641e0016a41086a290300370300200641c0006a41086a220c200641c0016a41086a290300370300200641c0006a41106a220e200641c0016a41106a290300370300200641c0006a41176a221a200641c0016a41176a290000370000200641206a41086a221b200641a0016a41086a290300370300200641206a41106a221c200641a0016a41106a290300370300200641206a41176a221d200641a0016a41176a290000370000200620062903e001370360200620062903c001370340200620062903a001370320200641176a221e20064180016a41176a280000360000200641106a221f20064180016a41106a290300370300200641086a222020064180016a41086a2903003703002006200629038001370300200641c0046a41086a2221200b290300370300200641c0046a41106a220b2008290300370300200641c0046a41186a22082001280200360200200620062903603703c00420064188086a41086a2201200c29030037030020064188086a41106a220c200e29030037030020064188086a41176a220e201a2900003700002006200629034037038808200641e0036a41086a221a201b290300370300200641e0036a41106a221b201c290300370300200641e0036a41176a221c201d290000370000200620062903203703e003200641a0036a41176a221d201e280000360000200641a0036a41106a221e201f290300370300200641a0036a41086a221f2020290300370300200620062903003703a00320064180056a20033a0000200620023a00e004200620024118763a00e304200620024108763b00e104200641ec046a2021290300370200200641f4046a200b290300370200200641fc046a2008280200360200200620062903c0043702e40420064181056a20062903880837000020064189056a200129030037000020064191056a200c29030037000020064198056a200e290000370000200641a0056a20043a0000200641b8056a201c290000370000200641b1056a201b290300370000200641a9056a201a290300370000200641a1056a20062903e003370000200641c0056a20053a0000200641d8056a201d280000360000200641d1056a201e290300370000200641c9056a201f290300370000200641c1056a20062903a003370000200a200641e0046a109d082106200041086a20093a00002000200636020420004100360200200724000f0b20004101360200200020023602040c030b41d0accb00411841e8accb00105d000b200da7450d002009102e0b2000410136020020002002360204200441046a280200450d002004280200102e200724000f0b200724000ba3a3011f047f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e017f017e027f017e087f017e087f230041b00e6b22052400200541086a2002200310a802024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020052d00084101470d0020052d00092102200541900e6a41086a2203200141086a290000370300200541900e6a41106a2204200141106a290000370300200541900e6a41186a2206200141186a290000370300200520012900003703900e4130102c22010d010c2a0b200541d4016a2802002107200541d0016a2802002108200541c8016a2903002109200541c4016a280200210a200541bc016a290200210b200541b8016a280200210c200541b0016a290300210d200541ac016a280200210e200541a4016a290200210f200541a0016a280200211020054198016a290300211120054194016a28020021122005418c016a290200211320054188016a280200211420054180016a2903002115200541fc006a2802002116200541f4006a2902002117200541f0006a2802002118200541e8006a2903002119200541e4006a280200211a200541dc006a290200211b200541086a41d0006a280200211c200541086a41c8006a290300211d200541086a41c4006a280200211e200541086a413c6a290200211f200541086a41386a2802002120200541386a2903002121200541086a412c6a2802002122200541086a41246a22232902002124200541286a22252802002126200541086a411c6a22272802002128200541086a41186a22292802002102200541086a41146a222a280200212b200541086a410c6a222c290200212d200541086a41086a222e280200212f41002130200528020c0e051502030401150b200141033a0000200120052903900e370001200120023a0021200120052901e00d370122200141096a2003290300370000200141116a2004290300370000200141196a2006290300370000200141286a200541e60d6a29010037010020004101360200200020013602040c270b200541e0016a2802002106200541dc016a2802002131200541d8016a28020021324102210302400240202b4102470d0041002102410021330c010b200541900e6a41186a2233200141186a290000370300200541900e6a41106a2234200141106a290000370300200541900e6a41086a2235200141086a290000370300200520012900003703900e200541e00d6a41086a2028360200200520023602e40d2005202b3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012102024020052802084101460d002033200541286a2903003703002034200541086a41186a2903003703002035200541086a41106a2903003703002005200541086a41086a2903003703900e410021020b200341807e7121330b200541c0066a41186a2234200541900e6a41186a290300370300200541c0066a41106a2235200541900e6a41106a290300370300200541c0066a41086a222b200541900e6a41086a290300370300200520052903900e3703c0062033200341ff017172213320020d03200541a0066a41186a2034290300370300200541a0066a41106a2035290300370300200541a0066a41086a202b290300370300200520052903c0063703a006410221024100210341002134024020264102460d00200541900e6a41186a2234200141186a290000370300200541900e6a41106a2235200141106a290000370300200541900e6a41086a222b200141086a290000370300200520012900003703900e200520243702e40d200520263602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210241012103024020052802084101460d002034200541286a2903003703002035200541086a41186a290300370300202b200541086a41106a2903003703002005200541086a41086a2903003703900e410021030b200241807e7121340b20054180076a41186a2235200541900e6a41186a29030037030020054180076a41106a222b200541900e6a41106a29030037030020054180076a41086a2230200541900e6a41086a290300370300200520052903900e370380072034200241ff017172210220030d04200541e0066a41186a2035290300370300200541e0066a41106a202b290300370300200541e0066a41086a203029030037030020052005290380073703e006410221034100213441002135024020224102460d00200541900e6a41186a2235200141186a290000370300200541900e6a41106a222b200141106a290000370300200541900e6a41086a2230200141086a290000370300200520012900003703900e200520213702e40d200520223602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d002035200541286a290300370300202b200541086a41186a2903003703002030200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e7121350b200541c0076a41186a222b200541900e6a41186a290300370300200541c0076a41106a2230200541900e6a41106a290300370300200541c0076a41086a222e200541900e6a41086a290300370300200520052903900e3703c0072035200341ff017172213520340d05200541a0076a41186a202b290300370300200541a0076a41106a2030290300370300200541a0076a41086a202e290300370300200520052903c0073703a00741022103410021344100212b024020204102460d00200541900e6a41186a222b200141186a290000370300200541900e6a41106a2230200141106a290000370300200541900e6a41086a222e200141086a290000370300200520012900003703900e2005201f3702e40d200520203602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d00202b200541286a2903003703002030200541086a41186a290300370300202e200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e71212b0b20054180086a41186a2230200541900e6a41186a29030037030020054180086a41106a222e200541900e6a41106a29030037030020054180086a41086a2225200541900e6a41086a290300370300200520052903900e37038008202b200341ff017172212b20340d06200541e0076a41186a2030290300370300200541e0076a41106a202e290300370300200541e0076a41086a202529030037030020052005290380083703e0074102210341002134410021300240201e4102460d00200541900e6a41186a2230200141186a290000370300200541900e6a41106a222e200141106a290000370300200541900e6a41086a2225200141086a290000370300200520012900003703900e2005201d3702e40d2005201e3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d002030200541286a290300370300202e200541086a41186a2903003703002025200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e7121300b200541c0086a41186a222e200541900e6a41186a290300370300200541c0086a41106a2225200541900e6a41106a290300370300200541c0086a41086a2229200541900e6a41086a290300370300200520052903900e3703c0082030200341ff017172213020340d07200541a0086a41186a202e290300370300200541a0086a41106a2025290300370300200541a0086a41086a2029290300370300200520052903c0083703a00841022103410021344100212e0240201c4102460d00200541900e6a41186a222e200141186a290000370300200541900e6a41106a2225200141106a290000370300200541900e6a41086a2229200141086a290000370300200520012900003703900e2005201b3702e40d2005201c3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d00202e200541286a2903003703002025200541086a41186a2903003703002029200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e71212e0b20054180096a41186a2225200541900e6a41186a29030037030020054180096a41106a2229200541900e6a41106a29030037030020054180096a41086a222c200541900e6a41086a290300370300200520052903900e37038009202e200341ff017172212e20340d08200541e0086a41186a2025290300370300200541e0086a41106a2029290300370300200541e0086a41086a202c29030037030020052005290380093703e0084102210341002134410021250240201a4102460d00200541900e6a41186a2225200141186a290000370300200541900e6a41106a2229200141106a290000370300200541900e6a41086a222c200141086a290000370300200520012900003703900e200520193702e40d2005201a3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d002025200541286a2903003703002029200541086a41186a290300370300202c200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e7121250b200541c0096a41186a2229200541900e6a41186a290300370300200541c0096a41106a222c200541900e6a41106a290300370300200541c0096a41086a2228200541900e6a41086a290300370300200520052903900e3703c0092025200341ff017172212520340d09200541a0096a41186a2029290300370300200541a0096a41106a202c290300370300200541a0096a41086a2028290300370300200520052903c0093703a009410221034100213441002129024020184102460d00200541900e6a41186a2229200141186a290000370300200541900e6a41106a222c200141106a290000370300200541900e6a41086a2228200141086a290000370300200520012900003703900e200520173702e40d200520183602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d002029200541286a290300370300202c200541086a41186a2903003703002028200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e7121290b200541800a6a41186a222c200541900e6a41186a290300370300200541800a6a41106a2228200541900e6a41106a290300370300200541800a6a41086a2226200541900e6a41086a290300370300200520052903900e3703800a2029200341ff017172212920340d0a200541e0096a41186a202c290300370300200541e0096a41106a2028290300370300200541e0096a41086a2026290300370300200520052903800a3703e00941022103410021344100212c024020164102460d00200541900e6a41186a222c200141186a290000370300200541900e6a41106a2228200141106a290000370300200541900e6a41086a2226200141086a290000370300200520012900003703900e200520153702e40d200520163602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d00202c200541286a2903003703002028200541086a41186a2903003703002026200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e71212c0b200541c00a6a41186a2228200541900e6a41186a290300370300200541c00a6a41106a2226200541900e6a41106a290300370300200541c00a6a41086a2223200541900e6a41086a290300370300200520052903900e3703c00a202c200341ff017172212c20340d0b200541a00a6a41186a2028290300370300200541a00a6a41106a2026290300370300200541a00a6a41086a2023290300370300200520052903c00a3703a00a410221034100213441002128024020144102460d00200541900e6a41186a2228200141186a290000370300200541900e6a41106a2226200141106a290000370300200541900e6a41086a2223200141086a290000370300200520012900003703900e200520133702e40d200520143602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d002028200541286a2903003703002026200541086a41186a2903003703002023200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e7121280b200541800b6a41186a2226200541900e6a41186a290300370300200541800b6a41106a2223200541900e6a41106a290300370300200541800b6a41086a2227200541900e6a41086a290300370300200520052903900e3703800b2028200341ff017172212820340d0c200541e00a6a41186a2026290300370300200541e00a6a41106a2023290300370300200541e00a6a41086a2027290300370300200520052903800b3703e00a410221034100213441002126024020124102460d00200541900e6a41186a2226200141186a290000370300200541900e6a41106a2223200141106a290000370300200541900e6a41086a2227200141086a290000370300200520012900003703900e200520113702e40d200520123602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d002026200541286a2903003703002023200541086a41186a2903003703002027200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e7121260b200541c00b6a41186a2223200541900e6a41186a290300370300200541c00b6a41106a2227200541900e6a41106a290300370300200541c00b6a41086a222a200541900e6a41086a290300370300200520052903900e3703c00b2026200341ff017172212620340d0d200541a00b6a41186a2023290300370300200541a00b6a41106a2027290300370300200541a00b6a41086a202a290300370300200520052903c00b3703a00b410221034100213441002123024020104102460d00200541900e6a41186a2223200141186a290000370300200541900e6a41106a2227200141106a290000370300200541900e6a41086a222a200141086a290000370300200520012900003703900e2005200f3702e40d200520103602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d002023200541286a2903003703002027200541086a41186a290300370300202a200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e7121230b200541800c6a41186a2227200541900e6a41186a290300370300200541800c6a41106a222a200541900e6a41106a290300370300200541800c6a41086a2222200541900e6a41086a290300370300200520052903900e3703800c2023200341ff017172212320340d0e200541e00b6a41186a2027290300370300200541e00b6a41106a202a290300370300200541e00b6a41086a2022290300370300200520052903800c3703e00b4102210341002134410021270240200e4102460d00200541900e6a41186a2227200141186a290000370300200541900e6a41106a222a200141106a290000370300200541900e6a41086a2222200141086a290000370300200520012900003703900e2005200d3702e40d2005200e3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d002027200541286a290300370300202a200541086a41186a2903003703002022200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e7121270b200541c00c6a41186a222a200541900e6a41186a290300370300200541c00c6a41106a2222200541900e6a41106a290300370300200541c00c6a41086a2220200541900e6a41086a290300370300200520052903900e3703c00c2027200341ff017172212720340d0f200541a00c6a41186a202a290300370300200541a00c6a41106a2022290300370300200541a00c6a41086a2020290300370300200520052903c00c3703a00c41022103410021344100212a0240200c4102460d00200541900e6a41186a222a200141186a290000370300200541900e6a41106a2222200141106a290000370300200541900e6a41086a2220200141086a290000370300200520012900003703900e2005200b3702e40d2005200c3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012134024020052802084101460d00202a200541286a2903003703002022200541086a41186a2903003703002020200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200341807e71212a0b200541800d6a41186a2222200541900e6a41186a290300370300200541800d6a41106a2220200541900e6a41106a290300370300200541800d6a41086a221e200541900e6a41086a290300370300200520052903900e3703800d202a200341ff017172212a20340d10200541e00c6a41186a2022290300370300200541e00c6a41106a2020290300370300200541e00c6a41086a201e290300370300200520052903800d3703e00c4102213441002103410021220240200a4102460d00200541900e6a41186a2222200141186a290000370300200541900e6a41106a2220200141106a290000370300200541900e6a41086a221e200141086a290000370300200520012900003703900e200520093702e40d2005200a3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c213441012103024020052802084101460d002022200541286a2903003703002020200541086a41186a290300370300201e200541086a41106a2903003703002005200541086a41086a2903003703900e410021030b203441807e712122203441ff017121340b200541c00d6a41186a2220200541900e6a41186a290300370300200541c00d6a41106a221e200541900e6a41106a290300370300200541c00d6a41086a221c200541900e6a41086a290300370300200520052903900e3703c00d2022203472213420030d24200541a00d6a41186a2020290300370300200541a00d6a41106a201e290300370300200541a00d6a41086a201c290300370300200520052903c00d3703a00d4102210320084102470d1141002101410021040c120b200541086a202f202da710b008200541900e6a41086a2029290300370300200541900e6a41106a2025290300370300200541900e6a41186a200541306a2802003602002005200541086a41106a2903003703900e2002417f4c0d14202c2802002135202e2802002134200528020c210720052802082133410121304101210302402002450d002002102c2203450d270b202d422088a721312003202b200210e9081a20054180026a41186a200541900e6a41186a28020036020020054180026a41106a200541900e6a41106a29030037030020054180026a41086a200541900e6a41086a290300370300200520052903900e37038002200221320c120b200541086a202f202da710b008200541e00d6a41086a2029290300370300200541e00d6a41106a22312025290300370300200541e00d6a41186a200541306a2802003602002005200541086a41106a22062903003703e00d202c2802002135202e2802002134200528020c210720052802082133200541900e6a41186a200141186a290000370300200541900e6a41106a200141106a290000370300200541900e6a41086a200141086a290000370300200520012900003703900e200541a00d6a41086a2028360200200520023602a40d2005202b3602a00d200541086a200541900e6a200541a00d6a200410b208200541c00d6a41086a2027290200370300200541c00d6a41106a220120232802003602002005202a2902003703c00d200528020c2103024020052802084101460d00202e290300212420062802002106200541e8016a41106a2001280200360200200541e8016a41086a200541c00d6a41086a29030037030020054180026a41086a200541e00d6a41086a29030037030020054180026a41106a203129030037030020054180026a41186a200541e00d6a41186a280200360200200520052903c00d3703e801200520052903e00d370380022024422088a72132202d422088a721312024a72102410221300c120b200041013602002000200336020420334125490d242034102e0c240b4102210341002133410021060240202f4102460d00200541900e6a41186a2233200141186a290000370300200541900e6a41106a2234200141106a290000370300200541900e6a41086a2235200141086a290000370300200520012900003703900e2005202d3702e40d2005202f3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012106024020052802084101460d002033200541286a2903003703002034200541086a41186a2903003703002035200541086a41106a2903003703002005200541086a41086a2903003703900e410021060b200341807e7121330b200541c0066a41186a2234200541900e6a41186a290300370300200541c0066a41106a2235200541900e6a41106a290300370300200541c0066a41086a2231200541900e6a41086a290300370300200520052903900e3703c006200341ff0171203372213320060d11200541a0066a41186a2034290300370300200541a0066a41106a2035290300370300200541a0066a41086a2031290300370300200520052903c0063703a0064102210302400240202b4102470d0041002106410021020c010b200541900e6a41186a2206200141186a290000370300200541900e6a41106a2234200141106a290000370300200541900e6a41086a2235200141086a290000370300200520012900003703900e200541e00d6a41086a2028360200200520023602e40d2005202b3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210341012102024020052802084101460d002006200541286a2903003703002034200541086a41186a2903003703002035200541086a41106a2903003703002005200541086a41086a2903003703900e410021020b200341807e7121060b20054180076a41186a2234200541900e6a41186a29030037030020054180076a41106a2235200541900e6a41106a29030037030020054180076a41086a222b200541900e6a41086a290300370300200520052903900e37038007200341ff0171200672210320020d13200541e0066a41186a2034290300370300200541e0066a41106a2035290300370300200541e0066a41086a202b29030037030020052005290380073703e006410221024100213441002106024020264102460d00200541900e6a41186a2234200141186a290000370300200541900e6a41106a2235200141106a290000370300200541900e6a41086a222b200141086a290000370300200520012900003703900e200520243702e40d200520263602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210241012106024020052802084101460d002034200541286a2903003703002035200541086a41186a290300370300202b200541086a41106a2903003703002005200541086a41086a2903003703900e410021060b200241807e7121340b200541c0076a41186a2235200541900e6a41186a290300370300200541c0076a41106a222b200541900e6a41106a290300370300200541c0076a41086a2231200541900e6a41086a290300370300200520052903900e3703c007200241ff0171203472210220060d14200541a0076a41186a2035290300370300200541a0076a41106a202b290300370300200541a0076a41086a2031290300370300200520052903c0073703a007410221064100213541002134024020224102460d00200541900e6a41186a2235200141186a290000370300200541900e6a41106a222b200141106a290000370300200541900e6a41086a2231200141086a290000370300200520012900003703900e200520213702e40d200520223602e00d200541086a200541900e6a200541e00d6a200410b208200528020c210641012134024020052802084101460d002035200541286a290300370300202b200541086a41186a2903003703002031200541086a41106a2903003703002005200541086a41086a2903003703900e410021340b200641807e7121350b20054180086a41186a222b200541900e6a41186a29030037030020054180086a41106a2231200541900e6a41106a29030037030020054180086a41086a2232200541900e6a41086a290300370300200520052903900e37038008200641ff0171203572210620340d15200541e0076a41186a202b290300370300200541e0076a41106a2031290300370300200541e0076a41086a203229030037030020052005290380083703e007410221344100212b41002135024020204102460d00200541900e6a41186a222b200141186a290000370300200541900e6a41106a2231200141106a290000370300200541900e6a41086a2232200141086a290000370300200520012900003703900e2005201f3702e40d200520203602e00d200541086a200541900e6a200541e00d6a200410b208200528020c213441012135024020052802084101460d00202b200541286a2903003703002031200541086a41186a2903003703002032200541086a41106a2903003703002005200541086a41086a2903003703900e410021350b203441807e71212b0b200541c0086a41186a2231200541900e6a41186a290300370300200541c0086a41106a2232200541900e6a41106a290300370300200541c0086a41086a2230200541900e6a41086a290300370300200520052903900e3703c008203441ff0171202b72213420350d16200541a0086a41186a2031290300370300200541a0086a41106a2032290300370300200541a0086a41086a2030290300370300200520052903c0083703a00841022135410021314100212b0240201e4102460d00200541900e6a41186a2231200141186a290000370300200541900e6a41106a2232200141106a290000370300200541900e6a41086a2230200141086a290000370300200520012900003703900e2005201d3702e40d2005201e3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c21354101212b024020052802084101460d002031200541286a2903003703002032200541086a41186a2903003703002030200541086a41106a2903003703002005200541086a41086a2903003703900e4100212b0b203541807e7121310b20054180096a41186a2232200541900e6a41186a29030037030020054180096a41106a2230200541900e6a41106a29030037030020054180096a41086a222f200541900e6a41086a290300370300200520052903900e37038009203541ff01712031722135202b0d17200541e0086a41186a2032290300370300200541e0086a41106a2030290300370300200541e0086a41086a202f29030037030020052005290380093703e0084102212b41002132410021310240201c4102460d00200541900e6a41186a2232200141186a290000370300200541900e6a41106a2230200141106a290000370300200541900e6a41086a222f200141086a290000370300200520012900003703900e2005201b3702e40d2005201c3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c212b41012131024020052802084101460d002032200541286a2903003703002030200541086a41186a290300370300202f200541086a41106a2903003703002005200541086a41086a2903003703900e410021310b202b41807e7121320b200541c0096a41186a2230200541900e6a41186a290300370300200541c0096a41106a222f200541900e6a41106a290300370300200541c0096a41086a222e200541900e6a41086a290300370300200520052903900e3703c009202b41ff0171203272212b20310d18200541a0096a41186a2030290300370300200541a0096a41106a202f290300370300200541a0096a41086a202e290300370300200520052903c0093703a0094102213141002130410021320240201a4102460d00200541900e6a41186a2230200141186a290000370300200541900e6a41106a222f200141106a290000370300200541900e6a41086a222e200141086a290000370300200520012900003703900e200520193702e40d2005201a3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c213141012132024020052802084101460d002030200541286a290300370300202f200541086a41186a290300370300202e200541086a41106a2903003703002005200541086a41086a2903003703900e410021320b203141807e7121300b200541800a6a41186a222f200541900e6a41186a290300370300200541800a6a41106a222e200541900e6a41106a290300370300200541800a6a41086a2225200541900e6a41086a290300370300200520052903900e3703800a203141ff0171203072213020320d19200541e0096a41186a202f290300370300200541e0096a41106a202e290300370300200541e0096a41086a2025290300370300200520052903800a3703e009410221314100212f41002132024020184102460d00200541900e6a41186a222f200141186a290000370300200541900e6a41106a222e200141106a290000370300200541900e6a41086a2225200141086a290000370300200520012900003703900e200520173702e40d200520183602e00d200541086a200541900e6a200541e00d6a200410b208200528020c213141012132024020052802084101460d00202f200541286a290300370300202e200541086a41186a2903003703002025200541086a41106a2903003703002005200541086a41086a2903003703900e410021320b203141807e71212f0b200541c00a6a41186a222e200541900e6a41186a290300370300200541c00a6a41106a2225200541900e6a41106a290300370300200541c00a6a41086a2229200541900e6a41086a290300370300200520052903900e3703c00a203141ff0171202f72212f20320d1a200541a00a6a41186a202e290300370300200541a00a6a41106a2025290300370300200541a00a6a41086a2029290300370300200520052903c00a3703a00a410221314100212e41002132024020164102460d00200541900e6a41186a222e200141186a290000370300200541900e6a41106a2225200141106a290000370300200541900e6a41086a2229200141086a290000370300200520012900003703900e200520153702e40d200520163602e00d200541086a200541900e6a200541e00d6a200410b208200528020c213141012132024020052802084101460d00202e200541286a2903003703002025200541086a41186a2903003703002029200541086a41106a2903003703002005200541086a41086a2903003703900e410021320b203141807e71212e0b200541800b6a41186a2225200541900e6a41186a290300370300200541800b6a41106a2229200541900e6a41106a290300370300200541800b6a41086a222c200541900e6a41086a290300370300200520052903900e3703800b203141ff0171202e72212e20320d1b200541e00a6a41186a2025290300370300200541e00a6a41106a2029290300370300200541e00a6a41086a202c290300370300200520052903800b3703e00a410221314100212541002132024020144102460d00200541900e6a41186a2225200141186a290000370300200541900e6a41106a2229200141106a290000370300200541900e6a41086a222c200141086a290000370300200520012900003703900e200520133702e40d200520143602e00d200541086a200541900e6a200541e00d6a200410b208200528020c213141012132024020052802084101460d002025200541286a2903003703002029200541086a41186a290300370300202c200541086a41106a2903003703002005200541086a41086a2903003703900e410021320b203141807e7121250b200541c00b6a41186a2229200541900e6a41186a290300370300200541c00b6a41106a222c200541900e6a41106a290300370300200541c00b6a41086a2228200541900e6a41086a290300370300200520052903900e3703c00b203141ff0171202572212520320d1c200541a00b6a41186a2029290300370300200541a00b6a41106a202c290300370300200541a00b6a41086a2028290300370300200520052903c00b3703a00b410221314100213241002129024020124102460d00200541900e6a41186a2229200141186a290000370300200541900e6a41106a222c200141106a290000370300200541900e6a41086a2228200141086a290000370300200520012900003703900e200520113702e40d200520123602e00d200541086a200541900e6a200541e00d6a200410b208200528020c213141012132024020052802084101460d002029200541286a290300370300202c200541086a41186a2903003703002028200541086a41106a2903003703002005200541086a41086a2903003703900e410021320b203141807e7121290b200541800c6a41186a222c200541900e6a41186a290300370300200541800c6a41106a2228200541900e6a41106a290300370300200541800c6a41086a2226200541900e6a41086a290300370300200520052903900e3703800c2029203141ff017172212920320d1d200541e00b6a41186a202c290300370300200541e00b6a41106a2028290300370300200541e00b6a41086a2026290300370300200520052903800c3703e00b41022131410021324100212c024020104102460d00200541900e6a41186a222c200141186a290000370300200541900e6a41106a2228200141106a290000370300200541900e6a41086a2226200141086a290000370300200520012900003703900e2005200f3702e40d200520103602e00d200541086a200541900e6a200541e00d6a200410b208200528020c213141012132024020052802084101460d00202c200541286a2903003703002028200541086a41186a2903003703002026200541086a41106a2903003703002005200541086a41086a2903003703900e410021320b203141807e71212c0b200541c00c6a41186a2228200541900e6a41186a290300370300200541c00c6a41106a2226200541900e6a41106a290300370300200541c00c6a41086a2223200541900e6a41086a290300370300200520052903900e3703c00c202c203141ff017172212c20320d1e200541a00c6a41186a2028290300370300200541a00c6a41106a2026290300370300200541a00c6a41086a2023290300370300200520052903c00c3703a00c4102213141002132410021280240200e4102460d00200541900e6a41186a2228200141186a290000370300200541900e6a41106a2226200141106a290000370300200541900e6a41086a2223200141086a290000370300200520012900003703900e2005200d3702e40d2005200e3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c213141012132024020052802084101460d002028200541286a2903003703002026200541086a41186a2903003703002023200541086a41106a2903003703002005200541086a41086a2903003703900e410021320b203141807e7121280b200541800d6a41186a2226200541900e6a41186a290300370300200541800d6a41106a2223200541900e6a41106a290300370300200541800d6a41086a2227200541900e6a41086a290300370300200520052903900e3703800d2028203141ff017172212820320d1f200541e00c6a41186a2026290300370300200541e00c6a41106a2023290300370300200541e00c6a41086a2027290300370300200520052903800d3703e00c4102213241002131410021260240200c4102460d00200541900e6a41186a2226200141186a290000370300200541900e6a41106a2223200141106a290000370300200541900e6a41086a2227200141086a290000370300200520012900003703900e2005200b3702e40d2005200c3602e00d200541086a200541900e6a200541e00d6a200410b208200528020c213241012131024020052802084101460d002026200541286a2903003703002023200541086a41186a2903003703002027200541086a41106a2903003703002005200541086a41086a2903003703900e410021310b203241807e712126203241ff017121320b200541c00d6a41186a2223200541900e6a41186a290300370300200541c00d6a41106a2227200541900e6a41106a290300370300200541c00d6a41086a222a200541900e6a41086a290300370300200520052903900e3703c00d2026203272213220310d20200541a00d6a41186a2023290300370300200541a00d6a41106a2027290300370300200541a00d6a41086a202a290300370300200520052903c00d3703a00d4102212641002131410021230240200a4102460d00200541900e6a41186a2226200141186a290000370300200541900e6a41106a2223200141106a290000370300200541900e6a41086a2227200141086a290000370300200520012900003703900e200520093702840e2005200a3602800e200541086a200541900e6a200541800e6a200410b208200528020c210141012131024020052802084101460d002026200541286a2903003703002023200541086a41186a2903003703002027200541086a41106a2903003703002005200541086a41086a2903003703900e410021310b200141807e712123200141ff017121260b200541e00d6a41186a2204200541900e6a41186a290300370300200541e00d6a41106a2227200541900e6a41106a290300370300200541e00d6a41086a222a200541900e6a41086a290300370300200520052903900e3703e00d20232026722101024020310d00200541a0026a41186a2004290300370300200541a0026a41106a2027290300370300200541a0026a41086a202a29030037030020054180066a41086a200541a0066a41086a29030037030020054180066a41106a200541a0066a41106a29030037030020054180066a41186a200541a0066a41186a290300370300200541e0056a41086a200541e0066a41086a290300370300200541e0056a41106a200541e0066a41106a290300370300200541e0056a41186a200541e0066a41186a290300370300200520052903e00d3703a002200520052903a00637038006200520052903e0063703e005200541c0056a41186a200541a0076a41186a290300370300200541c0056a41106a200541a0076a41106a290300370300200541c0056a41086a200541a0076a41086a290300370300200541a0056a41086a200541e0076a41086a290300370300200541a0056a41106a200541e0076a41106a290300370300200541a0056a41186a200541e0076a41186a29030037030020054180056a41086a200541a0086a41086a29030037030020054180056a41106a200541a0086a41106a29030037030020054180056a41186a200541a0086a41186a290300370300200520052903a0073703c005200520052903e0073703a005200520052903a00837038005200541e0046a41186a200541e0086a41186a290300370300200541e0046a41106a200541e0086a41106a290300370300200541e0046a41086a200541e0086a41086a290300370300200541c0046a41186a200541a0096a41186a290300370300200541c0046a41106a200541a0096a41106a290300370300200541c0046a41086a200541a0096a41086a290300370300200541a0046a41186a200541e0096a41186a290300370300200541a0046a41106a200541e0096a41106a290300370300200541a0046a41086a200541e0096a41086a290300370300200520052903e0083703e004200520052903a0093703c004200520052903e0093703a00420054180046a41186a200541a00a6a41186a29030037030020054180046a41106a200541a00a6a41106a29030037030020054180046a41086a200541a00a6a41086a290300370300200520052903a00a37038004200541e0036a41186a200541e00a6a41186a290300370300200541e0036a41106a200541e00a6a41106a290300370300200541e0036a41086a200541e00a6a41086a290300370300200520052903e00a3703e003200541c0036a41186a200541a00b6a41186a290300370300200541c0036a41106a200541a00b6a41106a290300370300200541c0036a41086a200541a00b6a41086a290300370300200520052903a00b3703c003200541a0036a41186a200541e00b6a41186a290300370300200541a0036a41106a200541e00b6a41106a290300370300200541a0036a41086a200541e00b6a41086a290300370300200520052903e00b3703a00320054180036a41186a200541a00c6a41186a29030037030020054180036a41106a200541a00c6a41106a29030037030020054180036a41086a200541a00c6a41086a290300370300200520052903a00c37038003200541e0026a41186a200541e00c6a41186a290300370300200541e0026a41106a200541e00c6a41106a290300370300200541e0026a41086a200541e00c6a41086a290300370300200520052903e00c3703e002200541c0026a41186a200541a00d6a41186a290300370300200541c0026a41106a200541a00d6a41106a290300370300200541c0026a41086a200541a00d6a41086a290300370300200520052903a00d3703c00241c004102c2231450d2520312033360200203120052903800637020420312003360224203120052903e0053702282031410c6a20054180066a41086a290300370200203141146a20054180066a41106a2903003702002031411c6a20054180066a41186a290300370200203141306a200541e0056a41086a290300370200203141386a200541e0056a41106a290300370200203141c0006a200541e0056a41186a290300370200203120023602482031200636026c203120052903c00537024c203141d4006a200541c0056a41086a290300370200203141dc006a200541c0056a41106a290300370200203141e4006a200541c0056a41186a290300370200203120052903a005370270203141f8006a200541a0056a41086a29030037020020314180016a200541a0056a41106a29030037020020314188016a200541a0056a41186a2903003702002031203436029001203120353602b401203141ac016a20054180056a41186a290300370200203141a4016a20054180056a41106a2903003702002031419c016a20054180056a41086a290300370200203120052903800537029401203141d0016a200541e0046a41186a290300370200203141c8016a200541e0046a41106a290300370200203141c0016a200541e0046a41086a290300370200203120052903e0043702b8012031202b3602d801203141f4016a200541c0046a41186a290300370200203141ec016a200541c0046a41106a290300370200203141e4016a200541c0046a41086a290300370200203120052903c0043702dc01203120303602fc0120314198026a200541a0046a41186a29030037020020314190026a200541a0046a41106a29030037020020314188026a200541a0046a41086a290300370200203120052903a004370280022031202f3602a002203141bc026a20054180046a41186a290300370200203141b4026a20054180046a41106a290300370200203141ac026a20054180046a41086a29030037020020312005290380043702a4022031202e3602c402203141e0026a200541e0036a41186a290300370200203141d8026a200541e0036a41106a290300370200203141d0026a200541e0036a41086a290300370200203120052903e0033702c802203120253602e80220314184036a200541c0036a41186a290300370200203141fc026a200541c0036a41106a290300370200203141f4026a200541c0036a41086a290300370200203120052903c0033702ec022031202936028c03203141a8036a200541a0036a41186a290300370200203141a0036a200541a0036a41106a29030037020020314198036a200541a0036a41086a290300370200203120052903a003370290032031202c3602b003203141cc036a20054180036a41186a290300370200203141c4036a20054180036a41106a290300370200203141bc036a20054180036a41086a29030037020020312005290380033702b403203120283602d403203141f0036a200541e0026a41186a290300370200203141e8036a200541e0026a41106a290300370200203141e0036a200541e0026a41086a290300370200203120052903e0023702d803203120323602f80320314194046a200541c0026a41186a2903003702002031418c046a200541c0026a41106a29030037020020314184046a200541c0026a41086a290300370200203120052903c0023702fc032031200136029c04203141b8046a200541a0026a41186a290300370200203141b0046a200541a0026a41106a290300370200203141a8046a200541a0026a41086a290300370200203120052903a0023702a00441032130024020080d0041002133200721340c120b2007417f4c0d130240024020070d00410121330c010b2007102c2233450d260b20332008200710e9081a200721340c110b20004101360200200020013602040c230b20004101360200200020333602040c220b20004101360200200020023602040c210b20004101360200200020353602040c200b200041013602002000202b3602040c1f0b20004101360200200020303602040c1e0b200041013602002000202e3602040c1d0b20004101360200200020253602040c1c0b20004101360200200020293602040c1b0b200041013602002000202c3602040c1a0b20004101360200200020283602040c190b20004101360200200020263602040c180b20004101360200200020233602040c170b20004101360200200020273602040c160b200041013602002000202a3602040c150b200541900e6a41186a2222200141186a290000370300200541900e6a41106a2220200141106a290000370300200541900e6a41086a221e200141086a290000370300200520012900003703900e200541800e6a41086a2032360200200520073602840e200520083602800e200541086a200541900e6a200541800e6a200410b208200528020c210341012101024020052802084101460d002022200541286a2903003703002020200541086a41186a290300370300201e200541086a41106a2903003703002005200541086a41086a2903003703900e410021010b200341807e712104200341ff017121030b200541e00d6a41186a2207200541900e6a41186a290300370300200541e00d6a41106a2232200541900e6a41106a290300370300200541e00d6a41086a2222200541900e6a41086a290300370300200520052903900e3703e00d2004200372210420010d12200541a0026a41186a2007290300370300200541a0026a41106a2032290300370300200541a0026a41086a202229030037030020054180066a41086a200541a0066a41086a29030037030020054180066a41106a200541a0066a41106a29030037030020054180066a41186a200541a0066a41186a290300370300200541e0056a41086a200541e0066a41086a290300370300200541e0056a41106a200541e0066a41106a290300370300200541e0056a41186a200541e0066a41186a290300370300200520052903e00d3703a002200520052903a00637038006200520052903e0063703e005200541c0056a41186a200541a0076a41186a290300370300200541c0056a41106a200541a0076a41106a290300370300200541c0056a41086a200541a0076a41086a290300370300200541a0056a41086a200541e0076a41086a290300370300200541a0056a41106a200541e0076a41106a290300370300200541a0056a41186a200541e0076a41186a29030037030020054180056a41086a200541a0086a41086a29030037030020054180056a41106a200541a0086a41106a29030037030020054180056a41186a200541a0086a41186a290300370300200520052903a0073703c005200520052903e0073703a005200520052903a00837038005200541e0046a41186a200541e0086a41186a290300370300200541e0046a41106a200541e0086a41106a290300370300200541e0046a41086a200541e0086a41086a290300370300200541c0046a41186a200541a0096a41186a290300370300200541c0046a41106a200541a0096a41106a290300370300200541c0046a41086a200541a0096a41086a290300370300200541a0046a41186a200541e0096a41186a290300370300200541a0046a41106a200541e0096a41106a290300370300200541a0046a41086a200541e0096a41086a290300370300200520052903e0083703e004200520052903a0093703c004200520052903e0093703a00420054180046a41186a200541a00a6a41186a29030037030020054180046a41106a200541a00a6a41106a29030037030020054180046a41086a200541a00a6a41086a290300370300200520052903a00a37038004200541e0036a41186a200541e00a6a41186a290300370300200541e0036a41106a200541e00a6a41106a290300370300200541e0036a41086a200541e00a6a41086a290300370300200520052903e00a3703e003200541c0036a41186a200541a00b6a41186a290300370300200541c0036a41106a200541a00b6a41106a290300370300200541c0036a41086a200541a00b6a41086a290300370300200520052903a00b3703c003200541a0036a41186a200541e00b6a41186a290300370300200541a0036a41106a200541e00b6a41106a290300370300200541a0036a41086a200541e00b6a41086a290300370300200520052903e00b3703a00320054180036a41186a200541a00c6a41186a29030037030020054180036a41106a200541a00c6a41106a29030037030020054180036a41086a200541a00c6a41086a290300370300200520052903a00c37038003200541e0026a41186a200541e00c6a41186a290300370300200541e0026a41106a200541e00c6a41106a290300370300200541e0026a41086a200541e00c6a41086a290300370300200520052903e00c3703e002200541c0026a41186a200541a00d6a41186a290300370300200541c0026a41106a200541a00d6a41106a290300370300200541c0026a41086a200541a00d6a41086a290300370300200520052903a00d3703c00241c004102c2203450d1420032033360200200320052903800637020420032002360224200320052903e0053702282003410c6a20054180066a41086a290300370200200341146a20054180066a41106a2903003702002003411c6a20054180066a41186a290300370200200341306a200541e0056a41086a290300370200200341386a200541e0056a41106a290300370200200341c0006a200541e0056a41186a290300370200200320353602482003202b36026c200320052903c00537024c200341d4006a200541c0056a41086a290300370200200341dc006a200541c0056a41106a290300370200200341e4006a200541c0056a41186a290300370200200320052903a005370270200341f8006a200541a0056a41086a29030037020020034180016a200541a0056a41106a29030037020020034188016a200541a0056a41186a29030037020020032030360290012003202e3602b401200341ac016a20054180056a41186a290300370200200341a4016a20054180056a41106a2903003702002003419c016a20054180056a41086a290300370200200320052903800537029401200341d0016a200541e0046a41186a290300370200200341c8016a200541e0046a41106a290300370200200341c0016a200541e0046a41086a290300370200200320052903e0043702b801200320253602d801200341f4016a200541c0046a41186a290300370200200341ec016a200541c0046a41106a290300370200200341e4016a200541c0046a41086a290300370200200320052903c0043702dc01200320293602fc0120034198026a200541a0046a41186a29030037020020034190026a200541a0046a41106a29030037020020034188026a200541a0046a41086a290300370200200320052903a004370280022003202c3602a002200341bc026a20054180046a41186a290300370200200341b4026a20054180046a41106a290300370200200341ac026a20054180046a41086a29030037020020032005290380043702a402200320283602c402200341e0026a200541e0036a41186a290300370200200341d8026a200541e0036a41106a290300370200200341d0026a200541e0036a41086a290300370200200320052903e0033702c802200320263602e80220034184036a200541c0036a41186a290300370200200341fc026a200541c0036a41106a290300370200200341f4026a200541c0036a41086a290300370200200320052903c0033702ec022003202336028c03200341a8036a200541a0036a41186a290300370200200341a0036a200541a0036a41106a29030037020020034198036a200541a0036a41086a290300370200200320052903a00337029003200320273602b003200341cc036a20054180036a41186a290300370200200341c4036a20054180036a41106a290300370200200341bc036a20054180036a41086a29030037020020032005290380033702b4032003202a3602d403200341f0036a200541e0026a41186a290300370200200341e8036a200541e0026a41106a290300370200200341e0036a200541e0026a41086a290300370200200320052903e0023702d803200320343602f80320034194046a200541c0026a41186a2903003702002003418c046a200541c0026a41106a29030037020020034184046a200541c0026a41086a290300370200200320052903c0023702fc032003200436029c04200341b8046a200541a0026a41186a290300370200200341b0046a200541a0026a41106a290300370200200341a8046a200541a0026a41086a290300370200200320052903a0023702a004200541086a202f202da710b008200541900e6a41086a2201200541086a41186a290300370300200541900e6a41106a2204200541286a290300370300200541900e6a41186a222b200541306a2802003602002005200541086a41106a2903003703900e200541086a410c6a2802002135200541086a41086a2802002134200528020c2107200528020821330240024020310d00410021020c010b2006417f4c0d030240024020060d00410121020c010b2006102c2202450d160b20022031200610e9081a0b202d422088a7213120054180026a41186a202b28020036020020054180026a41106a200429030037030020054180026a41086a2001290300370300200520052903900e3703800241042130200621320b20002030360204200041186a2035360200200041146a2034360200200041106a20073602002000410c6a2033360200200041086a20313602002000411c6a200529038002370200200041c4006a2006360200200041386a2003360200200041c8006a20052903e801370200200041246a20054180026a41086a2903003702002000412c6a20054180026a41106a290300370200200041346a20054180026a41186a280200360200200041d0006a200541e8016a41086a290300370200200041d8006a200541e8016a41106a2802003602002000413c6a2032ad4220862002ad84370200200041003602000c120b20004101360200200020333602040c110b1038000b20004101360200200020033602040c0f0b20004101360200200020023602040c0e0b20004101360200200020063602040c0d0b20004101360200200020343602040c0c0b20004101360200200020353602040c0b0b200041013602002000202b3602040c0a0b20004101360200200020303602040c090b200041013602002000202f3602040c080b200041013602002000202e3602040c070b20004101360200200020253602040c060b20004101360200200020293602040c050b200041013602002000202c3602040c040b20004101360200200020283602040c030b20004101360200200020323602040c020b20004101360200200020343602040c010b20004101360200200020043602040b200541b00e6a24000f0b1036000bae5303117f047e037f23002206210720064180056b41607122062400200641106a41086a200341086a280200360200200620032902003703100240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022802000e050104000203010b20064180016a2002412c6a290200370300200641f8006a200241246a290200370300200641d8006a41186a2002411c6a290200370300200641d8006a41106a2208200241146a290200370300200641d8006a41086a2002410c6a29020037030020062002290204370358200641a6016a200241376a2d00003a000020064188016a41086a200241c4006a29020037030020064188016a41106a200241cc006a29020037030020064188016a41186a200241d4006a280200360200200620022f00353b01a40120062002413c6a29020037038801200241346a2d00002109200241386a280200210a02400240200628025c220b4125490d002008280200210b200641d8006a410c6a280200210c0c010b200641e1006a210c0b20062006280258220d3602b0012006200c3602a8012006280214210e2006280218210f2006200b3602ac010240200b4101742210200d6b2211200e410174200f6b2202200220114b1b2212450d00410021022006280210211302400340200f20026a22084101762214200e4f0d0c200d20026a22154101762216200b4f0d0d201320146a2d00002214410f71201441f0017141047620084101711b200c20166a2d00002208410f71200841047620154101711b470d012012200241016a2202470d000b201221020b20020d060b2010200d470d0441f8accb00412a41a4adcb001039000b4101211520062802142208200628021822144101762202490d0a20064180046a200628021020026a200820026b10b008200641386a41086a20064194046a290200370300200641c8006a2006419c046a290200370300200641d0006a200641a4046a29020037030020062006418c046a2902003703382014410171210220064180046a41086a2802002108200628028404211620062802800421032004290204211720042802002111410021140c280b200241106a280200210d2002410c6a280200210c200241086a280200210b2002280204210202402006280214221441017420062802182208470d0020042802082108410021140240200b450d00200d2008470d00200b2004280200200d10ec08452114200d21080b2004280204211620042802002103024020052802002215450d00200541046a280200450d002015102e0b2005200c3602042005200b360200200541086a200d360200200641386a41086a20064180046a41086a290200370300200641386a41106a20064180046a41106a290200370300200641386a41186a20064180046a41186a290200370300200641206a41086a20064198036a41086a290200370300200641206a41106a20064198036a41106a28020036020020062006290280043703382006200629029803370320410321150c280b2008410176221520144f0d0a200628021020156a2d000021142003200328020841016a36020820022014410f71201441047620084101711b221541246c6a22082902102118200820062903900437021020082902082119200820062903880437020820082902002117200641023a0080042008200629038004370200200841186a2214290200211a201420062903980437020002400240024002402017a741ff01714102470d0020032802042216200328020822054101762214490d0f20064198036a200328020020146a201620146b10b0082006418c046a20062902980337020020064194046a20064198036a41086a2902003702002006419c046a200641a8036a29020037020020064180046a41246a200641b0036a290200370200200641ac046a200641b8036a290200370200200641b4046a200641c0036a280200360200200641b8046a2004290200370300200641c0046a200441086a280200360200200641013602840420064180046a41086a200541017136020041002114200641003a0080042002201541246c6a41046a200141306a20064180046a109d08360200200841003a00000c010b200641a0046a200828022036020020064180046a41186a201a37030020062019370388042006201737038004200620183703900420064198036a41086a200441086a2802003602002006200429020037039803200641c0026a200120064180046a200320064198036a200510ad0820062802c402211620062802c0024101460d01200641c0026a41086a2d0000210341002114200841003a00002002201541246c6a41046a2016360200200341ff0171450d020b41032115200b2103200c2116200d21080c290b20004101360200200020163602040240200b450d00200c450d00200b102e0b2002102e200724000f0b2000428080808010370200200041186a200d360200200041146a200c360200200041106a200b3602002000410c6a2002360200200041086a4103360200200724000f0b200641c0036a2002412c6a290200370300200641b8036a200241246a290200370300200641b0036a2002411c6a290200370300200641a8036a2208200241146a29020037030020064198036a41086a2002410c6a2902003703002006200229020437039803200241346a2802002111200241386a28020021102002413c6a280200211b200241c0006a280200211c02400240200628029c03220b4125490d002008280200210b20064198036a410c6a280200210c0c010b200641a1036a210c0b2006200628029803220d360290012006200c360288012006280214210e2006280218210f2006200b36028c01410021020240200b410174200d6b2209200e410174200f6b220a200a20094b1b2212450d00200628021021130340200f20026a22084101762214200e4f0d0d200d20026a22154101762216200b4f0d0e201320146a2d00002214410f71201441f0017141047620084101711b200c20166a2d00002208410f71200841047620154101711b470d012012200241016a2202470d000b201221020b0240024002400240024020022009470d002009200a460d010b200220094f0d01200b200d200241016a22126a22144101762208490d12200641d8006a200c20086a200b20086b10b008200641e8016a41086a2216200641d8006a41086a290300370300200641e8016a41106a2203200641d8006a41106a290300370300200641e8016a41186a2205200641d8006a41186a290300370300200641e8016a41206a220e200641d8006a41206a290300370300200641e8016a41286a220f200641d8006a41286a280200360200200620062903583703e801200d20026a220d4101762208200b4f0d13200c20086a2d0000210810b308211520064180046a41086a20144101713602002006418c046a220b20062903e80137020020064194046a20162903003702002006419c046a200329030037020020064180046a41246a2005290300370200200641ac046a200e290300370200200641b4046a200f280200360200200641c4046a201c360200200641c0046a201b360200200641bc046a2010360200200641b8046a20113602002006410436028404200641c8046a20062902b801370300200641d0046a200641b8016a41086a290200370300200641d8046a200641b8016a41106a28020036020041002114200641003a00800420152008410f712008410476200d4101711b41246c6a2208200141306a220320064180046a109d08360204200841003a000020062802142208410174200628021822166b2002470d0220064180046a20064188016a200210b408200641386a41086a20064180046a41186a290300370300200641386a41106a200641a0046a290300370300200641386a41186a200641a8046a290300370300200620064180046a41106a290300370338200b280200210820064180046a41086a28020021162004280208210b2004290200211720062802840421032006280280042102201521110c280b4100211402402010450d00201c2004280208470d0020102004280200201c10ec084521140b200b200d4101762202490d1020064180046a200c20026a200b20026b10b008200641c0026a41086a221520064194046a290200370300200641c0026a41106a220c2006419c046a290200370300200641c0026a41186a220e200641a4046a29020037030020062006418c046a2902003703c002200d410171210220064180046a41086a220d2802002108200628028404211620062802800421032004280208210b20042902002117024020052802002204450d00200541046a280200450d002004102e0b2005201b36020420052010360200200541086a201c360200200641386a41086a2015290300370300200641386a41106a200c290300370300200641386a41186a200e290300370300200641206a41086a200d290200370300200641206a41106a20064180046a41106a280200360200200620062903c00237033820062006290280043703200c270b200f20026a22144101762208200e4f0d12200628021020086a2d000021082003200220032802086a41016a36020820112008410f71200841047620144101711b221441246c6a22022902102118200220062903900437021020022902082119200220062903880437020820022902002117200641023a0080042002200629038004370200200241186a2208290200211a20082006290398043702002017a741ff01714102470d0120032802042215200328020822164101762208490d15200641c0026a200328020020086a201520086b10b0082006418c046a20062902c00237020020064194046a200641c0026a41086a2902003702002006419c046a200641d0026a29020037020020064180046a41246a200641d8026a290200370200200641ac046a200641e0026a290200370200200641b4046a200641e8026a280200360200200641b8046a2004290200370300200641c0046a200441086a280200360200200641013602840420064180046a41086a2016410171360200200641003a0080042011201441246c6a41046a200141306a20064180046a109d08360200200241003a00000c250b201620026a220b410176220d20084f0d122008201620126a22054101762214490d132006280210220c200d6a2d00002116200641c0026a200c20146a200820146b10b0082006418c046a220820062902c00237020020064194046a200641c0026a41086a2902003702002006419c046a200641c0026a41106a29020037020020064180046a41246a200641c0026a41186a290200370200200641ac046a200641c0026a41206a290200370200200641b4046a200641c0026a41286a280200360200200641b8046a2004290200370300200641c0046a200441086a280200360200200641013602840420064180046a41086a2204200541017136020041002114200641003a00800420152016410f71201641f00171410476200b4101711b41246c6a2216200320064180046a109d08360204201641003a000020064180046a20064188016a200210b408200641386a41086a20064180046a41186a290300370300200641386a41106a20064180046a41206a290300370300200641386a41186a20064180046a41286a290300370300200620064180046a41106a29030037033820082802002108200428020021162006280284042103200628028004210242002117201521110c250b200641a0046a200228022036020020064180046a41186a201a370300200620193703880420062017370380042006201837039004200641c0026a41086a200441086a280200360200200620042902003703c002200641e8016a200120064180046a2003200641c0026a200510ad0820062802ec012108024020062802e8014101460d00200641e8016a41086a2d00002115200241003a00002011201441246c6a41046a2008360200201541ff01710d24200b200d4101762202490d1520064180046a200c20026a200b20026b10b0082000410c6a200d41017136020020004281808080c000370204200041c8006a201c360200200041c4006a201b360200200041c0006a20103602002000413c6a2011360200200041106a200629028004370200200041186a20064188046a290200370200200041206a20064180046a41106a290200370200200041286a20064180046a41186a290200370200200041306a20064180046a41206a290200370200200041386a20064180046a41286a280200360200200041003602000c220b200041013602002000200836020402402010450d00201b450d002010102e0b2011102e0c210b200641e8026a2002412c6a290200370300200641e0026a200241246a290200370300200641d8026a2002411c6a290200370300200641d0026a2208200241146a290200370300200641c0026a41086a2002410c6a290200370300200620022902043703c0022002413c6a2802002109200241386a280200211c200241346a28020021100240024020062802c402220b4125490d002008280200210b200641c0026a410c6a280200210d0c010b200641c9026a210d0b410021020240200b41017420062802c002220c6b22112006280214220e4101742006280218220f6b220a200a20114b1b2212450d00200628021021130340200f20026a22084101762214200e4f0d16200c20026a22154101762216200b4f0d17201320146a2d00002214410f71201441f0017141047620084101711b200d20166a2d00002208410f71200841047620154101711b470d012012200241016a2202470d000b201221020b024002400240024020022011470d002011200a460d010b200220114f0d0110b3082108200c20026a22154101762216200b4f0d19200b201541016a220c4101762214490d1a200d20166a2d0000211620064198036a200d20146a200b20146b10b0082006418c046a220b20062902980337020020064180046a41146a220d20064198036a41086a220e29020037020020064180046a411c6a220f20064198036a41106a221229020037020020064180046a41246a221320064198036a41186a29020037020020064180046a412c6a221120064198036a41206a29020037020020064180046a41346a220a20064198036a41286a280200360200200641c0046a221b2009360200200641bc046a2209201c36020020064180046a41386a2010360200200641013602840420064180046a41086a2210200c41017136020041002114200641003a00800420082016410f71201641f0017141047620154101711b41246c6a2215200141306a20064180046a109d08360204201541003a000020064180046a200641106a200210b408200641a8016a41086a2202200b280200360200200641d8006a41086a221520064180046a41186a220c290300370300200641d8006a41106a221620064180046a41206a290300370300200641d8006a41186a221c20064180046a41286a29030037030020062006290284043703a801200620064180046a41106a221d290300370358200620062802800436029c032006410436029803200e20062903a8013703002012200228020036020020064198036a41386a410036020020064198036a41346a200836020020064198036a41146a200629035837020020064198036a411c6a201529030037020020064198036a41246a201629030037020020064198036a412c6a201c290300370200200641dc036a20062902880137020020064198036a41cc006a20064188016a41086a29020037020020064198036a41d4006a20064188016a41106a280200360200200641f0036a41086a200441086a280200360200200620042902003703f00320064180046a200120064198036a2003200641f0036a200510af08200641e8016a41086a22052013290200370300200641e8016a41106a220e2011290200370300200641e8016a41186a2212200a2902003703002006200f2902003703e80120102802002115200b2802002102201d2802002103200d2802002116200c280200210820092802002111201b2903002117200641c8046a280200210b200628028404210d2006280280042104200641b8016a41106a220c200641dc046a280200360200200641b8016a41086a220f20064180046a41d4006a290200370300200620064180046a41cc006a2902003703b80120044101460d07200641386a41186a2012290300370300200641386a41106a200e290300370300200641386a41086a2005290300370300200641206a41086a200f290300370300200641206a41106a200c280200360200200620062903e801370338200620062903b8013703200c020b41002102024020092004280208470d0020102004280200200910ec084521020b024020052802002208450d00200541046a280200450d002008102e0b2005201c36020420052010360200200541086a2009360200024020020d00200620062802c0023602800420064180046a41047221150240024020062802c40222084125490d00200641d0026a2802002108200641cc026a28020021020c010b200641c9026a21020b4100211420064180046a41086a221641003a0000200641003602840420152002200220086a10fb06200641386a41086a20064180046a41186a290300370300200641386a41106a200641a0046a290300370300200641386a41186a200641a8046a290300370300200641206a41086a20064198036a41086a290200370300200641206a41106a20064198036a41106a280200360200200620064180046a41106a29030037033820062006290298033703202006418c046a280200210820162802002116200429020421172004280200211120062802840421032006280280042102410121150c020b200620062802c0023602800420064180046a41047221140240024020062802c40222084125490d00200641d0026a2802002108200641cc026a28020021020c010b200641c9026a21020b20064180046a41086a221541003a0000200641003602840420142002200220086a10fb06200641386a41086a20064180046a41186a290300370300200641386a41106a200641a0046a290300370300200641386a41186a200641a8046a290300370300200641206a41086a20064198036a41086a290200370300200641206a41106a20064198036a41106a280200360200200620064180046a41106a29030037033820062006290298033703202006418c046a28020021082015280200211620042902042117200428020021112006280284042103200628028004210241012115410121140c010b200b200c4101762202490d19200641e8016a200d20026a200b20026b10b00810b308210220064198036a41086a20062902e80137030020064198036a41106a200641e8016a41086a29020037030020064198036a41186a200641e8016a41106a29020037030020064198036a41206a200641e8016a41186a29020037030020064198036a41286a200641e8016a41206a290200370300200641c8036a200641e8016a41286a28020036020020064198036a41c0006a200936020020064198036a413c6a201c360200200641d0036a201036020020064198036a41346a20023602002006200c41017136029c03200641043602980320064188016a41086a200441086a280200360200200620042902003703880120064180046a200120064198036a200320064188016a200510af08200641d8006a41086a2204200641a4046a290200370300200641d8006a41106a220d200641ac046a290200370300200641d8006a41186a220520064180046a41346a29020037030020062006419c046a29020037035820064180046a41086a28020021152006418c046a280200210220064180046a41106a280200210320064194046a280200211620064180046a41186a280200210820064180046a413c6a280200211120064180046a41c0006a2903002117200641c8046a280200210b200628028404210c2006280280042114200641b8016a41106a220e200641dc046a280200360200200641b8016a41086a220f200641d4046a2902003703002006200641cc046a2902003703b80120144101460d1a200641386a41186a2005290300370300200641386a41106a200d290300370300200641386a41086a2004290300370300200641206a41086a200f290300370300200641206a41106a200e28020036020020062006290358370338200620062903b801370320410021140b20062802c4024125490d26200641cc026a280200102e0c260b200d4101762202200b4f0d19200c20026a2d0000210210b30821080240024020114101470d0020064198036a41026a200641a4016a41026a2d00003a000020064180046a41086a20064188016a41086a29030037030020064180046a41106a20064188016a41106a29030037030020064180046a41186a20064188016a41186a280200360200200620062f01a4013b0198032006200629038801370380040c010b200b200d41016a22154101762214490d1b20064198036a200c20146a200b20146b10b00820064180046a41086a20154101713602002006418c046a20062902980337020020064194046a20064198036a41086a2902003702002006419c046a20064198036a41106a290200370200200641a4046a20064198036a41186a290200370200200641ac046a200641b8036a290200370200200641b4046a200641c0036a280200360200200641b8046a20093a0000200641b9046a20062f01a4013b00002006410236028404200641bb046a200641a4016a41026a2d00003a0000200641bc046a200a360200200641c0046a200629038801370300200641c8046a20064188016a41086a290300370300200641d0046a20064188016a41106a290300370300200641d8046a20064188016a41186a28020036020041002109200641003a008004200141306a20064180046a109d08210a0b20082002410f712002410476200d4101711b41246c6a220220093a0000200220062f0198033b00012002200a3602042002200629038004370208200241036a2006419a036a2d00003a0000200241106a20064180046a41086a2215290300370200200241186a20064180046a41106a2216290300370200200241206a20064180046a41186a220b2802003602004100211420064198036a41086a41003602002006200836029c032006410336029803200641b8016a41086a200441086a280200360200200620042902003703b80120064180046a200120064198036a2003200641b8016a200510af08200641c0026a41086a220d20064180046a41246a290200370300200641c0026a41106a2205200641ac046a290200370300200641c0026a41186a220c200641b4046a29020037030020062006419c046a2902003703c002201528020021152006418c046a28020021022016280200210320064194046a2802002116200b2802002108200641bc046a2802002111200641c0046a2903002117200641c8046a280200210b200628028404210e2006280280042104200641e8016a41106a220f200641dc046a280200360200200641e8016a41086a2212200641d4046a2902003703002006200641cc046a2902003703e80120044101460d01200641386a41186a200c290300370300200641386a41106a2005290300370300200641386a41086a200d290300370300200641206a41086a2012290300370300200641206a41106a200f280200360200200620062903c002370338200620062903e8013703200c1e0b0240024020022011460d00200b200d20026a22144101762208490d1c200641b8016a200c20086a200b20086b10b0082003200328020820026a36020820064198036a41086a221620062902b80137030020064198036a41106a220b200641b8016a41086a29020037030020064198036a41186a220d200641b8016a41106a29020037030020064198036a41206a220c200641b8016a41186a29020037030020064198036a41286a220e200641b8016a41206a29020037030020064198036a41306a200641b8016a41286a280200360200200641cc036a20093a00002006201441017136029c03410221152006410236029803200641cf036a200641a4016a41026a2d00003a0000200620062f01a4013b00cd03200641d0036a200a360200200641ec036a20064188016a41186a280200360200200641e4036a20064188016a41106a290300370200200641dc036a20064188016a41086a290300370200200641d4036a200629038801370200200641f0036a41086a200441086a280200360200200620042902003703f00320064180046a200120064198036a2003200641f0036a200510af0820062802840421142006280280042108200641c0026a20064180046a41086a41d80010e9081a20084101460d01200641e8016a200641c0026a41d80010e9081a20064198036a200641a8016a200210b40820064180046a410472200641e8016a41d80010e9081a41002111200641003a008004200141306a20064180046a109d082102200641386a41086a200d290300370300200641386a41106a200c290300370300200641386a41186a200e2903003703002006200b2903003703382002ad211720162802002116200641a4036a28020021082006280298032102200628029c032103410021140c1f0b2003200328020820116a36020820064180046a41086a20062903880137030020064180046a41106a20064188016a41086a29030037030020064180046a41186a20064188016a41106a290300370300200641a0046a20064188016a41186a280200360200200620093a008004200620062f01a4013b0081042006200641a6016a2d00003a0083042006200a3602840420064198036a41086a200441086a2802003602002006200429020037039803200641c0026a200120064180046a200320064198036a200510ad0820062802c4022115024020062802c0024101460d00200b200d4101762202490d1d200641c0026a41086a2d0000210820064180046a200c20026a200b20026b10b008200641386a41086a20064194046a290200370300200641386a41106a2006419c046a290200370300200641d0006a200641a4046a290200370300200641206a41086a20064198036a41086a290200370300200641206a41106a20064198036a41106a28020036020020062006418c046a2902003703382006200629029803370320200d4101712102200841ff017145211420064180046a41086a2802002108200628028404211620062802800421032015ad211741022115410021110c1f0b20004101360200200020153602040c020b20004101360200200020143602040c010b200041013602002000200e3602040b200628025c4125490d1d200641e4006a280200102e200724000f0b200041013602002000200d3602040c190b2014200e41e0efcc00103c000b2016200b41e0efcc00103c000b2002200841f0efcc001056000b2015201441e0efcc00103c000b2014201641f0efcc001056000b2014200e41e0efcc00103c000b2016200b41e0efcc00103c000b2002200b41f0efcc001056000b2008200b41f0efcc001056000b2008200b41e0efcc00103c000b2008200e41e0efcc00103c000b200d200841e0efcc00103c000b2014200841f0efcc001056000b2008201541f0efcc001056000b2002200b41f0efcc001056000b2014200e41e0efcc00103c000b2016200b41e0efcc00103c000b2016200b41e0efcc00103c000b2014200b41f0efcc001056000b2002200b41f0efcc001056000b200041013602002000200c3602040c040b2002200b41e0efcc00103c000b2014200b41f0efcc001056000b2008200b41f0efcc001056000b2002200b41f0efcc001056000b20062802c4024125490d02200641cc026a280200102e0c020b200628025c4125490d06200641e4006a280200102e0c060b200628029c034125490d00200641a4036a280200102e200724000f0b200724000f0b200b200d4101762202490d0120064180046a200c20026a200b20026b10b008200641386a41086a20064194046a290200370300200641c8006a2006419c046a290200370300200641d0006a200641a4046a29020037030020062006418c046a290200370338200d4101712102201bad4220862010ad84211720064180046a41086a28020021082006280284042116200628028004210341002114201c210b0b0240200628029c034125490d00200641a4036a280200102e0b410421150c020b2002200b41f0efcc001056000b0b20002014360204200041186a2008360200200041146a2016360200200041106a20033602002000410c6a2002360200200041086a20153602002000411c6a2006290338370200200041c8006a200b360200200041c0006a20173702002000413c6a2011360200200041cc006a2006290320370200200041246a200641386a41086a2903003702002000412c6a200641386a41106a290300370200200041346a200641386a41186a290300370200200041d4006a200641206a41086a290300370200200041dc006a200641206a41106a28020036020020004100360200200724000bd50301087f230041106b22032400200041003a00042000410036020020032000200210fc060240024020032802004101470d00200341086a2802000d0141d0f0cc00411141e4f0cc001039000b02400240200028020022044125490d002000410c6a22052802002106200041086a28020021070c010b200041056a21072004210620002105412421040b02400240024020062004490d00200121080c010b2002210920012108024003402009450d01200720066a20082d00003a00002009417f6a2109200841016a21082004200641016a2206470d000b200421060c010b200520063602000c010b20052006360200200120026a22012008460d00200841016a21062000410c6a2105200041056a210a20082d00002102034002400240200028020022044125490d00200028020c210820002802082107200521090c010b2004210820002109200a2107412421040b024020082004470d0020032000410110fc06024020032802004101470d00200341086a2802000d0441d0f0cc00411141e4f0cc001039000b200028020c210820002802082107200521090b200720086a20023a00002009200928020041016a36020020012006460d0120062d00002102200641016a21060c000b0b200341106a24000f0b1036000b880903017f027e177f230041d0016b22022400200241186a200141d00010e9081a20024188016a20002903182000290308853703002002200029031022033703782002200029030022043703702002200320048537038001200241186a200241f0006a109107200241086a2002290378420020022903702203420010e8084104210520002802202206200241106a290300200229030885200389a7220771220841046a200671210902400240024002400240200041246a280200220a20086a280000220b2007411976220c41818284086c220d732201417f73200141fffdfb776a7141808182847871220e0d004104210f200b21100340200921012010201041017471418081828478710d0320062001200f6a41046a712109200f41046a2205210f200d200a20016a280000221073220e417f73200e41fffdfb776a7141808182847871220e450d000c020b0b200b211020082101200a450d010b200e417f6a200e71210f2001200e684103766a210e200241186a41256a2111200241c4006a2802002112200241c0006a280200211320022802382114200241e4006a2d000041ff01712115200241186a41cd006a2d000041ff0171211603400240200241186a200a41002006200e716b41d0006c6a220e41b07f6a2217412010ec080d00200e41506a2118201321192012211a0240201441254f0d00201121192014211a0b024002402018280200221b4125490d00200e415c6a280200211b200e41586a28020021180c010b201841056a21180b201a201b470d0020192018201a10ec080d002015200e417c6a2d0000470d002015450d032016201741cd006a2d000041ff0171460d030b02400240200f450d00200f210e0c010b2005210f0340200921012010201041017471418081828478710d0320062001200f6a41046a712109200f41046a2205210f200d200a20016a280000221073220e417f73200e41fffdfb776a7141808182847871220e450d000b0b200e417f6a200e71210f2001200e684103766a210e0c000b0b200041206a210f2002200036026c200241f0006a200241186a41d00010e9081a4104210102400340200b4180818284787122100d01200820016a2110200141046a2101200a201020067122086a280000210b0c000b0b0240200a20106841037620086a20067122016a2c000022104100480d00200a200a280200418081828478716841037622016a2d000021100b200041286a280200210802402010410171220b450d0020080d00200241c0016a200f200241ec006a10b508200028022022062007712110200041246a280200210a4104210103402010220820016a2006712110200141046a2101200a20086a28000041808182847871220f450d000b0240200a200f6841037620086a20067122016a2c00004100480d00200a280200418081828478716841037621010b200028022821080b20002008200b6b360228200a20016a200c3a000020062001417c6a71200a6a41046a200c3a0000200a410020016b41d0006c6a41b07f6a200241f0006a41d00010e9081a2000412c6a2201200128020041016a3602000c010b20144125490d002013102e0b200241d0016a24000bc40801047f230041f0026b22042400024002400240024002400240024020022802004101470d00200241086a280200210520022802042102200441d0016a41186a200141186a290000370300200441d0016a41106a200141106a290000370300200441d0016a41086a200141086a290000370300200420012900003703d001200441f0016a200441d0016a20022005200310ae0820042802f401210120042802f0012102200441f8006a200441f0016a41086a220541d40010e9081a20024101460d05200441206a200441f8006a41d40010e9081a200420013602f4012005200441206a41d40010e9081a41002102200441003a00f0012003200441f0016a109d0821010c010b2002280204210302400240200241086a28020022024120460d00200441f0016a41186a200141186a290000370300200441f0016a41106a200141106a290000370300200441f0016a41086a200141086a290000370300200420012900003703f0012002417f4c0d040240024020020d00410121010c010b2002102c2201450d060b20012003200210e9082103200441f8006a41186a2205200441f0016a41186a290300370300200441f8006a41106a2206200441f0016a41106a290300370300200441f8006a41086a2207200441f0016a41086a290300370300200420042903f0013703784130102c2201450d05200141043a000020012004290378370001200120042f00f0013b00212001200236002c2001200236002820012003360024200141096a2007290300370000200141116a2006290300370000200141196a2005290300370000200141236a200441f2016a2d00003a0000410121020c010b200441f8006a41026a200341026a2d00003a0000200441f0016a41086a2003410f6a29000037030020044180026a200341176a29000037030020044188026a2003411f6a2d00003a0000200420032f00003b0178200420032900073703f00120032800032101410021020b200441d0016a41026a2203200441f8006a41026a2d00003a0000200441206a41086a2205200441f0016a41086a290300370300200441206a41106a2206200441f0016a41106a290300370300200441206a41186a2207200441f0016a41186a2d00003a0000200420042f01783b01d001200420042903f00137032020020d012004411c6a41026a20032d00003a0000200441086a2005290300370300200441106a2006290300370300200441186a20072d00003a0000200420042f01d0013b011c20042004290320370300410121020b200020023a000420004100360200200041056a20042f011c3b0000200041086a20013602002000410c6a2004290300370200200041076a2004411e6a2d00003a0000200041146a200441086a2903003702002000411c6a200441106a290300370200200041246a200441186a2802003602000c040b20004101360200200020013602040c030b1038000b1036000b20004101360200200020013602040b200441f0026a24000b800d01027f230041b0046b22002400024041c004102c22010d001036000b200141023a00002001200029008d04370001200141023a0024200120002900ea03370025200141096a2000418d046a41086a290000370000200141116a2000418d046a41106a290000370000200141196a2000418d046a41186a290000370000200141206a2000418d046a411f6a2800003600002001412d6a200041ea036a41086a290000370000200141356a200041ea036a41106a2900003700002001413d6a200041ea036a41186a290000370000200141c4006a200041ea036a411f6a280000360000200141023a0048200141023a006c200120002900c703370049200141d1006a200041c7036a41086a290000370000200141d9006a200041c7036a41106a290000370000200141e1006a200041c7036a41186a290000370000200141e8006a200041c7036a411f6a280000360000200120002900a40337006d200141f5006a200041a4036a41086a290000370000200141fd006a200041a4036a41106a29000037000020014185016a200041a4036a41186a2900003700002001418c016a200041a4036a411f6a280000360000200141023a009001200141023a00b40120012000290081033700910120014199016a20004181036a41086a290000370000200141a1016a20004181036a41106a290000370000200141a9016a20004181036a41186a290000370000200141b0016a20004181036a411f6a280000360000200120002900de023700b501200141bd016a200041de026a41086a290000370000200141c5016a200041de026a41106a290000370000200141cd016a200041de026a41186a290000370000200141d4016a200041de026a411f6a280000360000200141023a00d801200141f8016a200041bb026a411f6a280000360000200141f1016a200041bb026a41186a290000370000200141e9016a200041bb026a41106a290000370000200141e1016a200041bb026a41086a290000370000200120002900bb023700d901200141023a00fc012001419c026a20004198026a411f6a28000036000020014195026a20004198026a41186a2900003700002001418d026a20004198026a41106a29000037000020014185026a20004198026a41086a29000037000020012000290098023700fd01200141023a00a002200141c0026a200041f5016a411f6a280000360000200141b9026a200041f5016a41186a290000370000200141b1026a200041f5016a41106a290000370000200141a9026a200041f5016a41086a290000370000200120002900f5013700a102200141023a00c402200141e4026a200041d2016a411f6a280000360000200141dd026a200041d2016a41186a290000370000200141d5026a200041d2016a41106a290000370000200141cd026a200041d2016a41086a290000370000200120002900d2013700c502200141023a00e80220014188036a200041af016a411f6a28000036000020014181036a200041af016a41186a290000370000200141f9026a200041af016a41106a290000370000200141f1026a200041af016a41086a290000370000200120002900af013700e902200141023a008c03200141ac036a2000418c016a411f6a280000360000200141a5036a2000418c016a41186a2900003700002001419d036a2000418c016a41106a29000037000020014195036a2000418c016a41086a2900003700002001200029008c0137008d03200141023a00b003200141d0036a200041e9006a411f6a280000360000200141c9036a200041e9006a41186a290000370000200141c1036a200041e9006a41106a290000370000200141b9036a200041e9006a41086a290000370000200120002900693700b103200141023a00d403200141f4036a200041c6006a411f6a280000360000200141ed036a200041c6006a41186a290000370000200141e5036a200041c6006a41106a290000370000200141dd036a200041c6006a41086a290000370000200120002900463700d503200141023a00f80320014198046a200041236a411f6a28000036000020014191046a200041236a41186a29000037000020014189046a200041236a41106a29000037000020014181046a200041236a41086a290000370000200120002900233700f903200141023a009c04200141bc046a2000411f6a280000360000200141b5046a200041186a290000370000200141ad046a200041106a290000370000200141a5046a200041086a2900003700002001200029000037009d04200041b0046a240020010bf310010a7f230041e0006b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2802002204410174200141086a28020022056b20024b0d00200420054101762202490d01200341206a200128020020026a200420026b10b00820002005410171360200200020032903203702042000410c6a200341286a290300370200200041146a200341306a2903003702002000411c6a200341386a290300370200200041246a200341c0006a2903003702002000412c6a200341c8006a2802003602000c150b20054101762106200520026a22074101762108024020074101710d0020082006490d0220042008490d03200128020020066a210202400240200820066b220141244b0d00200341206a2002200110e9081a200341d0006a41026a200341206a41026a2d00003a0000200341086a200341336a290000370300200341106a2003413b6a290000370300200341186a200341c3006a2d00003a0000200320032f00203b01502003200329002b3703002003280023210420032800272102410021060c010b2001417f4c0d052001102c2204450d0620042002200110e9081a41012106200121020b2000200136020420002005410171360200200041086a20063a0000200041096a20032f01503b0000200041106a20023602002000410c6a2004360200200041146a20032903003702002000410b6a200341d2006a2d00003a00002000411c6a200341086a290300370200200041246a200341106a2903003702002000412c6a200341186a2802003602000c150b200841016a22072006490d05200820044f0d06200128020020066a210802400240200720066b220441244b0d00200341206a2008200410e9081a2003411c6a41026a200341206a41026a2d00003a0000200341086a200341336a290000370300200341106a2003413b6a290000370300200341186a200341c3006a2d00003a0000200320032f00203b011c2003200329002b3703002003280023210120032800272106410021080c010b2004417f4c0d042004102c2201450d0520012008200410e9081a41012108200421060b200341206a4104722109200341296a220720032f011c3b0000200341206a41106a220a20063602002003412c6a2001360200200341346a20032903003702002003412b6a2003411e6a2d00003a00002003413c6a200341086a290300370200200341c4006a200341106a290300370200200341cc006a200341186a280200360200200320083a00282003200436022420032002410171220236022002402005410171220520024d0d000240024020044125490d002006417f6a220b0d0120012d000021040c150b2004417f6a220b450d090b200b417f6a210c410021010340200141016a21050240024020044125490d002003280230220420014d0d102003280230220420054d0d11200328022c20016a2d00004104742102200328022c20016a41016a2d0000410476210620032802302104200328022c21080c010b200420014d0d0f200420054d0d10200720016a22062d00004104742102200641016a2d00004104762106200721080b200420014d0d0a200820016a20062002723a00000240200c2001460d0020032802242104200521010c010b0b02400240200328022422014125490d0020032802302201200b4d0d11200328022c200b6a2d0000210420032802302101200328022c21070c010b2001200b4d0d102007200b6a2d000021040b2001200b4d0d0a2007200b6a21010c130b200520024f0d130240024020044125490d00200a21050c010b200421062009210520072101412421040b024020062004470d00200341d0006a2009410110fc06024020032802504101470d00200341d8006a2802000d0641d0f0cc00411141e4f0cc001039000b20032802302106200328022c2101200a21050b200120066a41003a00002005200528020041016a36020002400240200328022422044125490d00200328023021010c010b200421010b024020014102490d002001417e6a21010340200141016a21050240024020044125490d002003280230220420014d0d132003280230220420054d0d14200328022c20016a2d00004104742102200328022c20016a41016a2d0000410476210620032802302104200328022c21080c010b200420014d0d12200420054d0d13200720016a22062d00004104742102200641016a2d00004104762106200721080b200420054d0d0c200820016a41016a20062002723a00002001417f6a210120032802242104200541014b0d000b0b0240024020044125490d002003280230450d13200328022c2d0000210120032802302104200328022c21070c010b2004450d1220032d002921010b2004450d0b2007200141f001714104763a00000c130b2002200441f0efcc001056000b200620084180f0cc001057000b200820044180f0cc00104d000b1038000b1036000b200620074190f0cc001057000b200720044190f0cc00104d000b20032d00292104200721010c0a0b2001200441ecf4cc00103c000b200b2001418cf5cc00103c000b200141016a200441c4f2cc00103c000b4100410041acf5cc00103c000b2001200441ccf4cc00103c000b200141016a200441dcf4cc00103c000b200b200141fcf4cc00103c000b2001200441a4f2cc00103c000b200141016a200441b4f2cc00103c000b41004100419cf5cc00103c000b200120044104743a00000b02400240200328022422014125490d00200328023021010c010b2009210a0b02402001450d00200a2001417f6a3602000b20002003290320370200200041286a200341206a41286a290300370200200041206a200341206a41206a290300370200200041186a200341206a41186a290300370200200041106a200341206a41106a290300370200200041086a200341206a41086a2903003702000b200341e0006a24000bcc0f06087f017e077f017e017f027e230041e0006b220324000240024002400240024002400240200128020c220441016a22052004490d000240200520012802002206200641016a220741037641076c20064108491b22064101764b0d004100210641002105024003400240024020064101710d00200520074f0d0320052106200541016a21050c010b200541036a220620054922080d0220062007492209450d022007200541046a20081b200720091b21050b200141046a28020020066a220620062802002206410776417f73418182840871200641fffefdfb07726a360200410121060c000b0b200141046a2802002105200128020041016a22064104490d05200520066a20052800003600000c060b024002402005200641016a2206200520064b1b22050d0041d0a1c0002108410021094100210a0c010b02400240200541074b0d004104410820054104491b21050c010b200541ffffffff01712005470d03417f2005410374220541076e417f6a677641016a41012005410d4b1b21050b2005ad42d0007e220b422088a70d03200ba72206200541046a22096a22082006490d032008102c2208450d04200820066a220841ff01200910eb081a2005417f6a2209200541037641076c20094108491b210a0b200141046a280200220c41046a210d200c20076a210e200c280200417f734180818284787121072002280200210f200341d8006a2110200341086a211103400240024020070d0002400340200d200e4f0d01200c41c07d6a210c200d2802002105200d41046a2206210d2005418081828478712205418081828478460d000b2005418081828478732207417f6a20077121122006210d0c020b2001200436020c200041003602002001200a20046b3602082001280200210520012009360200200141046a22062802002107200620083602002005450d092007200541016aad42d0007ea76b102e0c090b2007417f6a20077121120b2010200f290318200f290308853703002003200f290310220b3703482003200f29030022133703402003200b20138537035041002105200c41002007684103766b41d0006c6a41b07f6a2214200341c0006a1091072003200329034842002003290340220b420010e8082011290300200329030085200b89220ba721060340200541046a2205200620097122076a2106200820076a280000418081828478712202450d000b0240200820026841037620076a20097122056a2c00004100480d002008280200418081828478716841037621050b200820056a200ba741197622063a00002005417c6a20097120086a41046a20063a00002008410020056b41d0006c6a41b07f6a201441d00010e9081a201221070c000b0b41accdcc00411c41c8cdcc001039000b41accdcc00411c41c8cdcc001039000b41accdcc00411c41c8cdcc001039000b1036000b200541046a2005200610ea081a0b4100210502402001280200220a417f460d002002280200210c200141046a210e200341c0006a41186a2110200341106a41086a21114100210603400240200e2802002205200622146a2d0000418001470d00410020146b210403402010200c290318200c290308853703002003200c290310220b3703482003200c29030022133703402003200b2013853703502005200441d0006c6a220f41b07f6a220d200341c0006a109107200341106a200329034842002003290340220b420010e808200e280200210920012802002108410021052011290300200329031085200b89220ba7221221060340200541046a2205200620087122076a2106200920076a280000418081828478712202450d000b0240200920026841037620076a20087122056a2c00004100480d002009280200418081828478716841037621050b02402005200820127122066b201420066b7320087141034b0d00200920146a200ba741197622053a000020082014417c6a7120096a41046a20053a00000c020b200920056a22062d000021072006200ba741197622023a00002005417c6a20087120096a41046a20023a00000240200741ff01470d00200e280200220620146a41ff013a0000200620012802002014417c6a716a41046a41ff013a0000200e280200410020056b41d0006c6a41b07f6a200d41d00010e9081a0c020b200e280200410020056b41d0006c6a220741b07f6a2205290200210b2005200d290200370200200541186a220629020021132006200d41186a2208290200370200200541106a220629020021152006200d41106a2209290200370200200541086a220529020021162005200d41086a2206290200370200200d200b370200200620163702002009201537020020082013370200200741506a220541186a2208290200210b2008200f41506a220641186a2209290200370200200541106a220829020021132008200641106a2202290200370200200541086a220829020021152008200641086a220d2902003702002005290200211620052006290200370200200620163702002009200b37020020022013370200200d2015370200200741706a220541086a2207290000210b2007200f41706a220641086a22082900003700002005290000211320052006290000370000200620133700002008200b370000200e28020021050c000b0b201441016a21062014200a470d000b20012802002205200541016a41037641076c20054108491b21050b2000410036020020012005200128020c6b3602080b200341e0006a24000b130020004123360204200041b4adcb003602000b8c0301047f230041d0006b22022400200241186a200141186a290000370300200241106a200141106a290000370300200241086a200141086a29000037030020022001290000370300200241206a41de80ca004109108102200241306a41a8fcca004109108102024002404120102c2201450d002002422037024420022001360240200241c0006a20024120107420022802482201417f4c0d01200228024021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280244450d002003102e0b200141206a2203417f4c0d012003102c2205450d00200241003602482002200336024420022005360240200241c0006a200241206a41101074200241c0006a200241306a41101074200241c0006a20042001107402402001450d002004102e0b200220022802402203200228024810b705024020022802042201450d0020002002290308370208200020022802003602000b2000200136020402402002280244450d002003102e0b200241d0006a24000f0b1036000b1038000bb40201037f230041e0006b22022400200241086a41de80ca004109108102200241186a4184faca004108108102024002404120102c2203450d002002422037023c20022003360238200241386a2001412010742002200228023822012002280240220310a301370348200241dc006a200120036a360200200220013602582002200241c8006a41086a3602542002200241c8006a360250200241286a200241d0006a107c0240200228023c450d002001102e0b2002280230220341206a2201417f4c0d010240024020010d00410121040c010b2001102c2204450d010b2000410036020820002001360204200020043602002000200241086a411010742000200241186a41101074200020022802282201200310740240200228022c450d002001102e0b200241e0006a24000f0b1036000b1038000bf50101047f230041306b22022400200241de80ca004109108102200241106a41f4fcca00410d108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000bf50101047f230041306b22022400200241de80ca004109108102200241106a41a8fcca004109108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000b950f0a067f027e017f017e027f067e017f027e127f067e230041a0026b220524002005200010b808200541306a200528020022062005280208220710b105200541b0016a41026a220020052d00333a000041082108200541e8016a41086a220920054190016a290300370300200541e8016a41106a220a20054198016a290300370300200520052f00313b01b001200520054188016a2903003703e80120054180016a290300210b200541f8006a290300210c024002400240024020052d0030220d4102470d004200210e4100210f410021104200211142002112420021134200211442002115420021164100210d0c010b200541f0006a2903002116200541e8006a2903002115200541d8006a2903002113200541d0006a2903002112200541c8006a2903002111200541306a41106a290300210e200541e0006a29030021142005413c6a2802002110200541306a41086a280200210f200528023421172005412c6a41026a20002d00003a0000200541106a41086a2009290300370300200541106a41106a200a290300370300200520052f01b0013b012c200520052903e80137031041012100200d4101460d01201721080b4200201320047d2012200354ad7d2218201220037d2219201256201820135620182013511b22001b21134200201920001b21124200201120027d200e200154ad7d2218200e20017d2219200e56201820115620182011511b22001b21114200201920001b210e0240201041306c2200450d00200820006a211a200541e8006a2117200541306a410172221b41036a211c200821000340200041306a21090240200041086a2d00004101710d00200041096a2d0000211d200541a0016a2000280200108905200541306a20052802a001220a20052802a801221e108a05200541e8016a41086a221f201741086a2220290000370300200541e8016a41106a2221201741106a2222290000370300200541e8016a41186a2223201741186a2224290000370300200541e8016a41206a2225201741206a2226290000370300200541e8016a41286a2227201741286a22282900003703002005201b280000360298022005201c28000036009b02200520172900003703e801200541306a41306a2129200541306a41206a212a200541306a41106a212b0240024020052d003022004102470d00410221000c010b20292903002119202a290300212c202b290300212d200529035821182005290348212e2005290338212f200541b0016a41086a201f290300370300200541b0016a41106a2021290300370300200541b0016a41186a2023290300370300200541b0016a41206a2025290300370300200541b0016a41286a20272903003703002005200528009b023600e30120052005280298023602e001200520052903e8013703b00120000d004200201920047d2018200354ad7d2230201820037d2231201856203020195620302019511b22001b21194200203120001b211802400240201d4101710d004200202c20027d202e200154ad7d2230202e20017d2231202e562030202c562030202c511b22001b212c4200203120001b212e0c010b4200202d20027d202f200154ad7d2230202f20017d2231202f562030202d562030202d511b22001b212d4200203120001b212f0b410021000b201b20052802e001360000201720052903b00137030020292019370300202a202c370300202b202d370300201c20052800e3013600002020200541b0016a41086a2903003703002022200541b0016a41106a2903003703002024200541b0016a41186a2903003703002026200541b0016a41206a2903003703002028200541b0016a41286a290300370300200520183703582005202e3703482005202f370338200520003a00300240024020004102470d00200a201e10ff010c010b200541003602f001200542013703e801200541306a200541e8016a10bc05200a201e20052802e801220020052802f00110b20120052802ec01450d002000102e0b20052802a401450d00200a102e0b20092100201a2009470d000b0b20082117200d2100201021090c010b4200200b20047d200c200354ad7d2218200c20037d2219200c562018200b562018200b511b22091b210b4200201920091b210c4200201620027d2015200154ad7d2218201520017d2219201556201820165620182016511b22091b21164200201920091b2115410121090b20054180016a200b370300200541f8006a200c370300200541f0006a2016370300200541e8006a2015370300200541d8006a2013370300200541d0006a2012370300200541c8006a2011370300200541306a41106a200e370300200541e0006a20143703002005413c6a2010360200200541306a41086a200f36020020054188016a200529031037030020054190016a200541106a41086a29030037030020054198016a200541106a41106a290300370300200520052f012c3b00312005201736023420052005412c6a41026a2d00003a0033200520003a00300240024020004102470d002006200710ff010c010b200541e8016a200541306a10c2042006200720052802e801220a20052802f00110b201024020052802ec01450d00200a102e0b20000d00200f450d00200f41306c450d002017102e0b02402005280204450d002006102e0b200541a0026a240020090bad0802057f027e23004180026b2203240020034180016a20022802002204200241086a280200220510b001200341206a41186a20034180016a41186a290000370300200341206a41106a20034180016a41106a290000370300200341206a41086a20034180016a41086a290000370300200320032900800137032020034180016a200341206a1098082003280280012206200328028801108f0221070240200328028401450d002006102e0b0240024002402007450d002000410c1093080c010b200341106a2005ad42004280c2d72f420010e80820034180016a200120032903102208200341106a41086a290300220910c3022003200329008101370360200320034180016a41086a2207280000360067024020032d00800122064106470d0020034180016a41186a2206420037030020034180016a41106a2205420037030020074200370300200342003703800120034180016a41d9fcc6004106108102200341e0006a4180f4cb0041061081022006200341e0006a41086a220729000037030020052003290060370300200341086a20034180016a4120108e02200328020c210620032802082105200341cc006a200241086a28000036000020032002290000370044200341c8016a2009370300200341c0016a2008370300200341a1016a2003290041370000200341a8016a200341c8006a290000370000200341b4016a4100360200200341b0016a2006410020051b36020020034189016a200141086a29000037000020034191016a200141106a29000037000020034199016a200141186a290000370000200341013a0080012003200129000037008101200341e0006a41186a200341206a41186a290300370300200341e0006a41106a200341206a41106a2903003703002007200341206a41086a29030037030020032003290320370360200341d0006a200341e0006a10be082003280250210220032802582107200341003602682003420137036020034180016a200341e0006a10ac082002200720032802602206200328026810b20102402003280264450d002006102e0b02402003280254450d002002102e0b0240200341a8016a280200450d00200341a4016a280200102e0b200341d8016a2009370300200341d0016a200837030020034180016a41086a410b3a000020034191016a200341206a41086a29030037000020034199016a200341206a41106a290300370000200341a1016a200341206a41186a290300370000200341a9016a2001290000370000200341b1016a200141086a290000370000200341b9016a200141106a290000370000200341c1016a200141186a290000370000200341093a00800120034180016a41096a200329032037000020034180016a10fe01200041063a00000c020b200020063a000020002003290360370001200041086a20032800673600000b200241046a280200450d002004102e0b20034180026a24000bab0a07037f017e017f017e017f027e037f230041f0016b22032400200341f0006a20022802002204200228020810b001200341106a41186a200341f0006a41186a22052900002206370300200341106a41106a200341f0006a41106a22072900002208370300200341106a41086a200341f0006a41086a2209290000220a37030020032003290070220b370310200341003a004020052006370300200720083703002009200a3703002003200b370370200341d0006a200341f0006a10be08200341086a200328025022052003280258200341c0006a4101410010ca0402400240024020032802080d00200341f0006a410d10930820032802540d010c020b0240024002400240200328020c450d0020032d00400e020102000b4190c1cb00412910ef02200341f0006a410d1093080c020b200341063a00700c010b200341f0006a410c1093080b2003280254450d010b2005102e0b200320032900713703302003200341f0006a41086a2800003600370240024002400240024020032d007022054106470d00200341d0006a200341106a109808200341f0006a20032802502207200328025810ad052003280254210520032d007022094102460d0120034198016a280200210c20034194016a280200210d2003280274210e02402005450d002007102e0b20090d02200341f0006a41186a22054200370300200341f0006a41106a22074200370300200341f0006a41086a420037030020034200370370200341f0006a41d9fcc6004106108102200341d0006a4180f4cb0041061081022005200341d0006a41086a2209290000370300200720032900503703002003200341f0006a4120108e0220032802042105200328020021072003413b6a200241086a28000036000020032002290000370033200341b8016a4200370300200341b0016a420037030020034191016a200329003037000020034198016a200341376a290000370000200341a8016a200e360200200341a4016a4101360200200341a0016a2005410020071b360200200341f9006a200141086a29000037000020034181016a200141106a29000037000020034189016a200141186a290000370000200341013a007020032001290000370071200341d0006a41186a200341106a41186a290300370300200341d0006a41106a200341106a41106a2903003703002009200341106a41086a29030037030020032003290310370350200341c0006a200341d0006a10be0820032802402102200328024821052003410036025820034201370350200341f0006a200341d0006a10ac082002200520032802502207200328025810b20102402003280254450d002007102e0b02402003280244450d002002102e0b024020034198016a280200450d0020034194016a280200102e0b200341c8016a4200370300200341c0016a4200370300200341f0006a41086a410b3a000020034181016a200341106a41086a29030037000020034189016a200341106a41106a29030037000020034191016a200341106a41186a29030037000020034199016a2001290000370000200341a1016a200141086a290000370000200341a9016a200141106a290000370000200341b1016a200141186a290000370000200341093a0070200341f0006a41096a2003290310370000200341f0006a10fe01200041063a00000c040b200020053a000020002003290330370001200041086a20032800373600000c020b02402005450d002007102e0b2000410d1093080c010b0240200c450d00200d102e0b2000410c1093080b200241046a280200450d002004102e0b200341f0016a24000bf50101047f230041306b22022400200241de80ca004109108102200241106a41f780ca004109108102024002404120102c2203450d002002422037022420022003360220200241206a20014120107420022802282201417f4c0d01200228022021030240024020010d00410121040c010b2001102c2204450d010b20042003200110e908210402402002280224450d002003102e0b200141206a2203417f4c0d012003102c2205450d0020004100360208200020033602042000200536020020002002411010742000200241106a41101074200020042001107402402001450d002004102e0b200241306a24000f0b1036000b1038000b8e1d08077f067e0a7f017e017f057e017f067e23004190046b22042400200441a0026a2002108905200441d0026a20042802a002220520042802a802108a05200441d0036a41086a220620044190036a290300370300200441d0036a41106a220720044198036a290300370300200441d0036a41186a2208200441a0036a290300370300200441d0036a41206a2209200441a8036a290300370300200441d0036a41286a220a200441b0036a290300370300200420044188036a2903003703d00320044180036a290300210b200441d0026a41286a290300210c200441d0026a41206a290300210d200441d0026a41186a290300210e200441d0026a41106a290300210f200441d0026a41086a290300211020042802d402211120042d00d1022112024020042d00d00222134102460d00200441e0006a41286a200a290300370300200441e0006a41206a2009290300370300200441e0006a41186a2008290300370300200441e0006a41106a2007290300370300200441e0006a41086a2006290300370300200420042903d0033703600b024020042802a402450d002005102e0b200441a0016a41286a2205200441e0006a41286a290300370300200441a0016a41206a2206200441e0006a41206a290300370300200441a0016a41186a2207200441e0006a41186a290300370300200441a0016a41106a2214200441e0006a41106a290300370300200441a0016a41086a2215200441e0006a41086a290300370300200420042903603703a001200441d0016a200110b808200441d0026a20042802d001221620042802d80110b105200441a0026a41026a220120042d00d3023a0000200441d0036a41086a2004419c036a290200370300200441d0036a41106a2217200441a4036a290200370300200441d0036a41186a2218200441ac036a290200370300200441d0036a41206a2219200441b4036a290200370300200441d0036a41286a221a200441bc036a280200360200200420042f00d1023b01a002200420044194036a2902003703d0030240024020042d00d00222094102470d004200211b4100210a4100211c4200211d4200211e4200211f42002120420021214100212241082108410021090c010b20044188036a290300212120044180036a2903002120200441d0026a41286a290300211f200441d0026a41206a290300211e200441d0026a41186a290300211d200441d0026a41106a290300211b20044190036a2802002122200441dc026a280200211c200441d0026a41086a280200210a20042802d40221082004418c026a41026a20012d00003a0000200441e0016a41086a200441d0036a41086a290300370300200441e0016a41106a2017290300370300200441e0016a41186a2018290300370300200441e0016a41206a2019290300370300200441e0016a41286a201a280200360200200420042f01a0023b018c02200420042903d0033703e0010b200441a0026a41286a2005290300370300200441a0026a41206a2006290300370300200441a0026a41186a2007290300370300200441a0026a41106a2014290300370300200441a0026a41086a2015290300370300200420042903a0013703a0020240024002400240024020090d004100210102400240024002400240024002400240024002400240201c0e020201000b41002101201c2105034020012005410176220620016a22072008200741306c6a28020020024b1b2101200520066b220541014b0d000b0b2008200141306c6a2802002002470d002013410371417f6a0e020208010b20044190026a41161093080c0a0b200441d0036a41286a200441a0026a41286a290300370300200441d0036a41206a200441a0026a41206a290300370300200441d0036a41186a200441a0026a41186a290300370300200441d0036a41106a200441a0026a41106a290300370300200441d0036a41086a200441a0026a41086a290300370300200420042903a0023703d00302402003450d0020044190026a41171093080c0a0b201c20014d0d012008200141306c6a220541186a2903002123200541106a29030021240240024020052d000822064101470d00200541286a2903002125200541206a2903002126200441186a20242023420a420010e708200441086a20262025420a420010e708200c20247d2227200c56200b20237d200c202454ad7d2224200b562024200b511b0d01202720267d2228202756202420257d2027202654ad7d220c202456200c2024511b0d0120102004290318220b7d2224201056200f200441186a41086a2903007d2010200b54ad7d220b200f56200b200f511b0d01200e2004290308220f7d2223200e56200d200441086a41086a2903007d200e200f54ad7d220e200d56200e200d511b450d070c010b200541096a2d00002107024002402005410a6a2d0000221441ff0171450d0041062105024002400240024002400240024020144107710e0700010203040506000b410021050c050b410121050c040b410221050c030b410321050c020b410421050c010b410521050b200441386a202342002005ad2226420010e808200441c8006a202442002026420010e808427f200441d0006a290300222620042903387c2225200429034042005220252026547222051b2125427f200429034820051b21260c010b200441286a20242023420a420010e708200441306a2903002125200429032821260b200c20247d2228200c56200b20237d200c202454ad7d220c200b56200c200b511b0d000240200741ff01710d00200e20267d2223200e56200d20257d200e202654ad7d220e200d56200e200d511b0d0120060d06200741ff01714102460d064200200e201d7d2023201b54ad7d220b2023201b7d220d202356200b200e56200b200e511b22051b210e4200200d20051b21234200200c201f7d2028201e54ad7d220b2028201e7d220d202856200b200c56200b200c511b22051b210c4200200d20051b21280c060b201020267d2224201056200f20257d2010202654ad7d220b200f56200b200f511b450d040b20044190026a411a1093080c090b201c20014d0d012008200141306c6a22052d00080d05200541096a2d000045201241ff0171410047460d05200541186a290300210b200541106a290300210c4180c09306210602400240024002400240024002402005410a6a2d00004107710e0700010203040506000b410021060c050b4180ce1821060c040b41809c3121060c030b4180b8e20021060c020b4180f0c40121060c010b4180e0890321060b200441e8026a22054200370300200441e0026a22074200370300200441d0026a41086a4200370300200442003703d002200441d0026a41d9fcc6004106108102200441d0036a4180f4cb0041061081022005200441d0036a41086a290000370300200720042900d003370300200441d8006a200441d0026a4120108e02200428025c410020042802581b200620116a22054f0d0502402003450d0020044190026a41171093080c090b2021200b2020200c562021200b562021200b511b22061b21212020200c20061b212020222005202220054b1b21220c050b2001201c41bcc1cb00103c000b2001201c41ccc1cb00103c000b024020060d00200741ff01714102460d004200200b201d7d2024201b54ad7d220f2024201b7d2210202456200f200b56200f200b511b22051b210b4200201020051b21244200200c201f7d2028201e54ad7d220f2028201e7d2210202856200f200c56200f200c511b22051b210c4200201020051b21280b200e2123200d210e0c010b20102124200f210b0b20044180036a200c370300200441d0026a41286a2028370300200441d0026a41206a200e370300200441d0026a41186a2023370300200441d0026a41106a200b37030020044188036a20042903d00337030020044190036a200441d8036a29030037030020044198036a200441d0036a41106a290300370300200441a0036a200441d0036a41186a290300370300200441a8036a200441d0036a41206a290300370300200441b0036a200441d0036a41286a290300370300200420243703d802200441003a00d002200441c0036a200210890520042802c803210620042802c003210520044100360288042004420137038004200441d0026a20044180046a10bc0520052006200428028004220720042802880410b2010240200428028404450d002007102e0b20042802c403450d002005102e0b201c20014d0d012008200141306c6a2205200541306a201c2001417f736a41306c10ea081a201c417f6a211c0b200441063a0090020c020b2001201c1046000b20042d00900222014106460d0020042004290091023703d003200420044198026a2800003600d70320090d01200a450d01200a41306c450d012008102e0c010b20044188036a202137030020044180036a2020370300200441d0026a41286a201f370300200441d0026a41206a201e370300200441d0026a41186a201d370300200441d0026a41106a201b37030020044190036a2022360200200441dc026a201c360200200441d0026a41086a200a36020020044194036a20042903e0013702002004419c036a200441e0016a41086a290300370200200441a4036a200441e0016a41106a290300370200200441ac036a200441e0016a41186a290300370200200441b4036a200441e0016a41206a290300370200200441bc036a200441e0016a41286a280200360200200420042f018c023b00d102200420083602d40220042004418c026a41026a2d00003a00d302200420093a00d00220042802d801210120042802d00121160240024020094102470d002016200110ff010c010b200441d0036a200441d0026a10c2042016200120042802d003220520042802d80310b20120042802d403450d002005102e0b024020090d00200a450d00200a41306c450d002008102e0b20042004290091023703d003200420044198026a2800003600d703410621010b024020042802d401450d002016102e0b200420042903d00337039001200420042800d7033600970141062105024020014106460d002000200429039001370001200041086a200428009701360000200121050b200020053a000020044190046a24000bf30201037f024002400240024002400240024020002d0000417f6a0e0c000606060106020304060605060b200041046a2802004102490d05200041106a2802002201450d05200041146a280200450d052001102e0f0b200041086a280200450d04200041046a280200102e0c040b200041046a2802000d032000410c6a2802002201450d03200141286c450d03200041086a280200102e0f0b200041046a2d00004102490d020240200041106a2802002201450d00200141d0006c2102200041086a28020041c4006a21010340024020012802002203450d00200341306c450d002001417c6a280200102e0b200141d0006a2101200241b07f6a22020d000b0b2000410c6a2802002201450d02200141d0006c450d022000280208102e0f0b200041086a2d00004101470d01200041146a28020041ffffff3f71450d01200041106a280200102e0f0b200041086a2d00000d00200041106a2802002201450d00200141306c450d002000410c6a280200102e0f0b0b130020004100360204200041d4e2cc003602000b13002000410a360204200041b4cccb003602000b3400200041d9fcc60036020420004100360200200041146a4110360200200041106a41dce6cb00360200200041086a42063702000b130020004106360204200041b883cc003602000b920101017f230041c0006b22022400200241386a41002903e8f846370300200241306a41002903e0f846370300200241286a41002903d8f846370300200241206a41002903d0f846370300200241186a41002903c8f846370300200241106a41002903c0f846370300200241086a41002903b8f846370300200241002903b0f84637030020002002108707200241c0006a24000b4c01017f230041106b220224002000410036020820004201370200200242c0f0f50b3703082000200241086a4108107420024280c2d72f3703082000200241086a41081074200241106a24000b4301027f230041106b2202240002404104102c22030d001036000b2000420437020420002003360200200241e01236020c20002002410c6a41041074200241106a24000b6101017f230041106b2202240020004100360208200042013702002002418080f0013602082000200241086a410410742002418080c00236020c20002002410c6a410410742002418080c0023602042000200241046a41041074200241106a24000b7701017f230041c0016b22022400200210a9032000410036020820004201370200200220022903003703b8012000200241b8016a41081074200220022903083703b8012000200241b8016a41081074200241106a200010a207200241c8006a200010a20720024180016a200010a207200241c0016a24000b8726040c7f0a7e037f0e7e230041f0036b22052400200541d0016a200010e505200541f0026a20052802d001220620052802d80110f402200541206a41086a2207200541f9026a290000370300200541206a41106a220820054181036a290000370300200541206a41186a220920054189036a290000370300200520052900f1023703204100210a024020052d00f0024101470d0020054190026a41186a200929030037030020054190026a41106a200829030037030020054190026a41086a200729030037030020052005290320370390024101210a0b024020052802d401450d002006102e0b0240200a450d00200541186a20054190026a41186a2206290300370300200541106a20054190026a41106a2207290300370300200541086a20054190026a41086a22082903003703002005200529039002370300200541c0016a200510d305200541f0026a20052802c001220920052802c80110e60520054198016a41086a220b200541f0026a41086a29030037030020054198016a41106a220c200541f0026a41106a29030037030020054198016a41186a220d200541f0026a41186a29030037030020082005419c036a2902003703002007200541a4036a2902003703002006200541ac036a29020037030020054190026a41206a220e200541b4036a29020037030020054190026a41286a220f200541bc036a29020037030020054190026a41306a2210200541c4036a280200360200200520052903f002370398012005200529029403370390020240200528029003220a450d00200541f8006a41186a200d290300370300200541f8006a41106a200c290300370300200541f8006a41086a200b290300370300200541d0016a41086a2008290300370300200541d0016a41106a2007290300370300200541d0016a41186a2006290300370300200541d0016a41206a200e290300370300200541d0016a41286a200f290300370300200541d0016a41306a2010280200360200200520052903980137037820052005290390023703d0010b024020052802c401450d002009102e0b200a450d00200541c4006a20052903d001370200200541206a41186a2206200541f8006a41186a290300370300200541206a41106a2207200541f8006a41106a290300370300200541206a41086a2208200541f8006a41086a290300370300200541cc006a200541d0016a41086a290300370200200541d4006a200541d0016a41106a290300370200200541dc006a200541d0016a41186a290300370200200541e4006a200541f0016a290300370200200541ec006a200541d0016a41286a290300370200200541f4006a20054180026a280200360200200520052903783703202005200a360240200542003703f80220054280c8afa0253703f00220082903002111200529032021120240024020072903002213200120132001542006290300221420025420142002511b22071b22152014200220071b22168450450d0020122117201121180c010b2006201420167d2013201554ad7d22193703002005201320157d22173703300240024020174280c8afa0255620194200522019501b450d0020152113201621140c010b200541386a420037030020054200370330201920027c201720017c2201201754ad7c21020b20054200201120147d2012201354ad7d2215201220137d2219201256201520115620152011511b22061b221837032820054200201920061b2217370320200220147d2001201354ad7d2102200120137d21010b02400240024002400240024002400240200541206a41286a280200220641186c0d00410021062005280248210a0c010b200641186c2108200641037441786a41037641016a210b41002106024003400240200a2903002213200120012013562002200a41086a220929030022145620022014511b22071b22152014200220071b221684500d00200a201320157d2217370300200a201420167d2013201554ad7d221937030802400240201720052903f002562019200541f0026a41086a29030022185620192018511b450d002001211920152113201621140c010b200a4200370308200a4200370300200220197c200120177c2219200154ad7c21020b200541206a41086a220742002007290300220120147d20052903202215201354ad7d2216201520137d2217201556201620015620162001511b22071b221837030020054200201720071b2217370320200220147d2019201354ad7d2102201920137d210120092903002114200a29030021130b20132014844200520d01200a41186a210a200641016a2106200841686a22080d000b200b21060b2005280248220a2006490d010b200541003602480240200a20066b220a450d0002402006450d00200528024022072007200641186c6a200a41186c10ea081a200541286a2903002118200529032021170b2005200a3602480b2012201758201120185820112018511b0d05201220177d2214201256201120187d2012201754ad7d221320115620132011511b210a20054190026a200010c802200541f0026a200528029002220620052802980210c90220054190036a290300210120054188036a290300211520054180036a290300211620052903f802211220052903f00221020240200528029402450d002006102e0b42002013200a1b211142002014200a1b21184200211320024201520d0342002119201821172011211a2012201584201620018484500d04200541f0026a41c8006a2108200541f0026a41086a211b20054190026a41306a211020054190026a41206a211c41002106200541f0026a41386a210f200541f0026a41106a210d200541d0016a41286a210c200541d0016a41186a211d02400340200520003602bc0120054190026a200010c802200541f0026a200528029002220a20052802980210c902200f2903002119200541f0026a41306a22072903002102200541f0026a41206a220e2903002116200d29030021132005290398032101200529038803211720052903f802211420052903b003211220052903f0022115200541c0016a41086a200841086a290300370300200520082903003703c0010240024020154201510d0042002112200541d0016a41386a4200370300200541d0016a41306a4200370300200c4200370300200541d0016a41206a4200370300201d4200370300200541d0016a41106a4200370300200541d0016a41086a4200370300200542003703d001420021014200210242002114420021130c010b200c2002370300200541d0016a41306a2019370300200520013703f001200520143703d0012005201237038802200520173703e001200520133703d801200520163703e8010b0240200528029402450d00200a102e0b0240024020142013844200520d00200120052903e00184200529038002842002201d29030084200541d0016a41386a290300848450450d00420021014100210a0c010b200541d0016a41106a2903002114200541d0016a41306a290300211e200c290300211f200541d0016a41206a290300212020052903d801211320052903d00121154201210120052903e80121024101210a0b024020014201522209450d004200211442002112420021204200211f4200211e4200210242002115420021130b201821162011211702402006450d004200200220137c201420157c2201201454ad7c221920014280c8afa02554ad7d221620014280b8d0df5a7c22172001562016201956200142ffc7afa025561b220b1b22012011201842002017200b1b221956201120015620112001511b220b1b211720192018200b1b21160b2013201720132015201656201320175620132017511b220b1b22197d201520162015200b1b221354ad7d2101201520137d211502400240201620137d221a201720197d2016201354ad7d221684500d00201120197d2018201354ad7d201620022014201a56200220165620022016511b220b1b22177d201820137d2221201a2014200b1b221654ad7d211a200220177d2014201654ad7d2102201720197c201620137c2213201654ad7c2119202120167d2117201420167d21140c010b201120197d2018201354ad7d211a201820137d21170b200541f0026a41286a220b201f370300200541f0026a41186a20023703002007201e37030020052020370390032005201437038003200520153703f002200520013703f8022009ad212002400240427f201520147c221620162015542209200120027c2009ad7c221620015420162001511b22091b221f42ffc7afa02556427f201620091b22164200522016501b0d0020222016201520148420012002848422025022071b21222023201f20071b2123420021142002420052ad21020c010b20072903002124200b2903002125200e2903002126200d2903002127200529038803212820052903f802212920052903f002212a4201211442002102410121072012212b0b20054190026a41c8006a201a37030020054190026a41386a201937030020054190026a41286a202237030020054190026a41106a2001370300200520173703d002200520133703c002200520233703b0022005201537039802200520023703a80220052020370390020240200a2014420152720d00200520003602f0022000200541f0026a10bd060c040b200a410173220a2014420151720d01200520003602f00202402000200541f0026a10be0641ff0171220a4102460d00200a0d04200541d8026a290300211a200541c8026a2903002119200541b8026a2903002122200541a0026a290300210120052903d002211720052903c002211320052903b0022123200529039802211520052903a802210220052903900221200c050b024020070d002005201c3602f002200541f0026a10cc020b200520103602f002200541f0026a10cc02200641016a22064102470d000b420021130c040b2014420152200a71450d010c020b2006200a41b4b3c000104d000b200541e0026a200010c802200541f0026a20052802e002220a20052802e802220610c90220052903f0022113200541c0016a41086a2207200841086a290300370300200520082903003703c0010240024020134201510d00200541f8006a41086a4200370300200542003703780c010b200541f8006a41086a2007290300370300200520052903c0013703780b024020144201510d004200212a420021294200212642002125420021244200212b42002127420021280b20082005290378370300200541a0036a202537030020054190036a2028370300200541f0026a41106a2029370300200541f0026a41386a2024370300200841086a200541f8006a41086a290300370300200520263703980320052027370388032005202a3703f8022005202b3703b003200542013703f002200a2006201b10c805024020052802e402450d00200a102e0b20054190026a41106a2903002101200541b8026a290300212220054190026a41386a2903002119200541d8026a290300211a200529039802211520052903b002212320052903c002211320052903d0022117200529039002212020052903a80221020b024020204201520d00200541a8036a2001370300200541a0036a2015370300200541f0026a41086a41003a0000200541f9026a200029000037000020054181036a200041086a29000037000020054189036a200041106a29000037000020054191036a200041186a290000370000200541033a00f002200541f0026a10fe010b02400240200250450d00420021140c010b200541f0026a41086a20052802bc01220a41086a290000370300200541f0026a41106a200a41106a290000370300200541f0026a41186a200a41186a2900003703002005200a2900003703f002420121140b20054198016a41186a200541f0026a41186a220a290300220237030020054198016a41106a200541f0026a41106a2206290300220137030020054198016a41086a200541f0026a41086a2903002215370300200520052903f002221637039801200541a0036a202237030020054198036a2207202337030020062015370300200a200137030020054190036a2002370300200520143703f002200520163703f802200541f0026a10d20420052903f002500d01200520073602900220054190026a10cc020c010b42002119201821172011211a0b2004427f2004290300221420137c22132013201454220a200441086a2206290300221320197c200aad7c221420135420142013511b220a1b3703002006427f2014200a1b37030002402017201a84500d00200342002003290300221320177d22142014201356200341086a220a2903002214201a7d2013201754ad7d221320145620132014511b22061b370300200a4200201320061b3703000b42f3e885db96cddbb320200541206a41386a2005290320200541206a41086a290300411f1085062005200541206a10d205200541f0026a41386a2011370300200541a0036a2018370300200541f0026a41086a41023a0000200541f9026a200029000037000020054181036a200041086a29000037000020054189036a200041106a29000037000020054191036a200041186a290000370000200541043a00f002200541f0026a10fe010b02402005280244220a450d00200a41186c450d002005280240102e0b200541d0006a28020041ffffffff0371450d00200528024c102e0b200541f0036a24000b130020004103360204200041d490cc003602000b0600200010150ba40301097f230041206b220224000240024020012802082203410c6c41046a2204417f4c0d00200128020021050240024020040d00410121060c010b2004102c2206450d020b20024100360208200220043602042002200636020020032002107602402003450d0020052003410c6c6a210720052104034020042802002106200441086a28020022082002107620022006200810742004410c6a22042007470d000b0b20022802042106200241186a2208200235020842208620022802002209ad84100c220441186a290000370300200241106a2207200441106a290000370300200241086a220a200441086a290000370300200220042900003703002004102e200041186a2008290300370000200041106a2007290300370000200041086a200a2903003700002000200229030037000002402006450d002009102e0b02402003450d002003410c6c21062005210403400240200441046a280200450d002004280200102e0b2004410c6a2104200641746a22060d000b0b0240200141046a2802002204450d002004410c6c450d002005102e0b200241206a24000f0b1038000b1036000b3b02017e017f0240024010292201422088a722020d0020004101360200410021020c010b20002001a73602000b20002002360208200020023602040b130020002002ad4220862001ad84102010da080b130020004107360204200041f4aacc003602000b3400200041b4c3cb0036020420004100360200200041146a4102360200200041106a41fcb6cc00360200200041086a42133702000b3400200041f4c2cc0036020420004100360200200041146a4101360200200041106a418cc3cc00360200200041086a42183702000bcf0403017f017e037f230041b0016b22032400024002402001200210062204422088a72201450d002001417f6a21050240024002402004a722062d00000e020001030b41002101200341003a0069200641016a21070240034020052001460d01200341c8006a20016a200720016a2d00003a00002003200141016a22023a00692002210120024121460d030c000b0b200141ff0171450d02200341003a00690c020b2005450d014100210202400240024020062d00010e03020100040b410221020c010b410121020b200341086a41186a200341c8006a41186a290000370300200341086a41106a200341c8006a41106a290000370300200341086a41086a200341c8006a41086a2900003703002003200329004837030841012105200341086a21010c020b200341f0006a41086a2201200341d1006a290000370300200341f0006a41106a2205200341d9006a290000370300200341f0006a41186a2207200341e1006a29000037030020032003290049370370200241ff017141204d0d0020032d00482102200341286a41186a20072903002204370300200341086a41086a2001290300370300200341086a41106a2005290300370300200341086a41186a20043703002003200329037037030841002105200341086a21010c010b41cae0cc00412e200341c8006a41f8e0cc004188e1cc00103e000b200020023a0001200020053a0000200041026a20012900003700002000410a6a200141086a290000370000200041126a200141106a2900003700002000411a6a200141186a2900003700002006102e200341b0016a24000b130020004105360204200041e4c6cc003602000bba0203027f027e037f230041206b22022400200241106a41086a2203200141086a28020036020020022001290200370310200241106a10bb070240024020032802002201410574418101490d00200041bdd8cc0036020420004101360200200041086a411d3602000c010b0240024020010d0042002104420021050c010b2002280210220341786a21062003200141027422016a417c6a280200210741002103200241086a21084200210442002105034020022007ad4200200341e0007110ed08200829030020057c2002290300220520047c2204200554ad7c210520014104460d01200341206a2103200620016a28020021072001417c6a21010c000b0b20004100360200200041106a2005370300200041086a20043703000b0240200228021441ffffffff0371450d002002280210102e0b200241206a24000bd003030a7f017e027f02400240024002400240200141086a2802002203200241086a2802002204200320044b1b220541016a22064101200641014b1b220741ffffffff03712007470d0020074102742206417f4c0d000240024020060d00410421080c010b200610322208450d020b20002008360200200041086a200736020020002006410276360204024020050d00410021000c050b2007417f6a21062004417f6a220920044b210a200741027420086a417c6a210b2002280200210c410021024200210d03404100210002402003417f6a220e20034b0d00410021002003200e20026b220f4d0d0041002100200f200e4b0d002001280200200f4102746a28020021000b4100210e0240200a0d002004200920026b220f4d0d00200f20094b0d00200c200f4102746a280200210e0b200720064d0d03200b200d2000ad7c200ead7c220d3e0200200b417c6a210b2006417f6a2106200d422088210d2005200241016a2202460d040c000b0b1038000b1036000b2006200741ecd8cc00103c000b200da721000b024020072005417f736a220620074f0d00200820064102746a20003602000240200141046a28020041ffffffff0371450d002001280200102e0b0f0b2006200741ecd8cc00103c000be30303047f017e057f230041106b22012400024002400240024002400240024020002802002202280200220341016a41004c0d002002200336020020002802042203280200220441016a41004c0d0120022903082105200320043602002000280208220441086a2802002206200028020c220728020022086b41016a220920064f0d024101200028021428020020086a6b22062000280210220841086a28020022006a220a20064f0d0302400240200542ffffffff0f560d00410021002005200428020020094102746a3502007e20032903084220862008280200200a4102746a35020084580d010b20022802000d052002410036020020022002290308427f7c370308200441086a2802002200200020072802006b22024d0d0620032802000d07200428020020024102746a3502002105200341003602002003200520032903087c370308410121000b200141106a240020000f0b41bcd9cc004118200141086a41d4d9cc0041f4d9cc00103e000b41bcd9cc004118200141086a41d4d9cc004184dacc00103e000b2009200641ccd7cc00103c000b200a200041ccd7cc00103c000b4194dacc004110200141086a41a4dacc0041b4dacc00103e000b2002200041ccd7cc00103c000b4194dacc004110200141086a41a4dacc0041c4dacc00103e000b1c002001280218419eeacc00410f2001411c6a28020028020c1100000b5601017f4104210502400240024002400240200041ff0171417f6a0e050001020304000b410021050c030b410121050c020b410221050c010b410321050b20052002ad4220862001ad842004ad4220862003ad8410010bbb0101047f230041206b22022400024002402001422088a722030d002002200336020c200241013602080c010b2002200336020c20022001a7220436020820042d0000210520022003417f6a36020c2002200441016a360208410021030240024020050e020100020b200241106a200241086a10db0820022802102203450d01200229021421010b20002001370204200020033602002004102e200241206a24000f0b41cae0cc00412e200241106a41f8e0cc004188e1cc00103e000bed0102047f017e230041106b22022400200241086a200110ab01024002400240024002402002280208450d00200041003602000c010b024020012802042203200228020c2204490d002004417f4c0d020240024020040d00410121050c010b200410322205450d04200128020421030b024020032004490d0020052001280200200410e9082103200128020422052004490d0520002004ad2206422086200684370204200020033602002001200520046b3602042001200128020020046a3602000c020b2005102e0b200041003602000b200241106a24000f0b1038000b1036000b2004200541b8b2c0001056000bec0101047f230041106b22022400024002400240200128020022030d00410121040c010b0240200141086a28020041056a2204417f4c0d0020040d0141012105410021040c020b1038000b2004102c22050d001036000b2002410036020820022004360204200220053602000240024020030d00200241003a000f20022002410f6a410110740c010b200241013a000f20022002410f6a41011074200141086a28020022042002107620022003200410740b20002002290300370204200041013602002000410c6a20022802082204360200200041106a2004ad422086200235020084370300200241106a24000bb10301047f230041c0006b22022400200028020021034101210002402001280218418c9dc000410c2001411c6a28020028020c1100000d0002400240200328020822000d0020032802002200200328020428020c11070042f4f99ee6eea3aaf9fe00520d012002200036020c2002411036021420022002410c6a36021020012802182104200128021c2105410121002002413c6a41013602002002420237022c200241989dc0003602282002200241106a36023820042005200241286a103d0d020c010b2002200036020c2002411136021420022002410c6a36021020012802182104200128021c2105410121002002413c6a41013602002002420237022c200241989dc0003602282002200241106a36023820042005200241286a103d0d010b200328020c2100200241106a41146a4101360200200241106a410c6a410136020020022000410c6a3602202002200041086a360218200241043602142002200036021020012802182100200128021c2101200241286a41146a41033602002002420337022c200241a89dc0003602282002200241106a36023820002001200241286a103d21000b200241c0006a240020000b06002000100d0b06002000100e0be50102037f017e230041206b22022400024002400240200041046a2802002203200028020822046b20014f0d00200420016a22012004490d02200341017422042001200420014b1b22014104200141044b1bad420c7e2205422088a74541027421012005a721040240024020030d00200241003602100c010b200241186a410436020020022003410c6c360214200220002802003602100b200220042001200241106a107d200241086a280200210120022802004101460d0120002002280204360200200041046a2001410c6e3602000b200241206a24000f0b2001450d001036000b1038000b1c002001280218419eeacc00410f2001411c6a28020028020c1100000b1c002001280218419eeacc00410f2001411c6a28020028020c1100000bc00201057f230041106b22022400024002400240024020002d002c4101710d0002400240200028020022034125490d002000410c6a22042802002105200041086a28020021060c010b200041056a21062003210520002104412421030b024020052003470d0020022000410110fc06024020022802004101470d00200241086a2802000d0441d0f0cc00411141e4f0cc001039000b2000410c6a22042802002105200041086a28020021060b200620056a20014104743a00002004200428020041016a3602000c010b02400240200028020022044125490d002000410c6a2802002104200041086a28020021050c010b200041056a21050b2005450d022004450d02200420056a417f6a220420042d00002001723a00000b2000200028022c41016a36022c200241106a24000f0b1036000b4198eccc00413a41d4eccc00105d000b5801017e02400240200341c00071450d0020022003413f71ad882101420021020c010b2003450d002002410020036b413f71ad8620012003413f71ad220488842101200220048821020b20002001370300200020023703080baa0604017f017e017f057e230041206b22052400024002400240024002400240024002402004500d00420021062001200354200220045420022004511b0d052002500d05200541106a20032004200479a7200279a76b220741ff007110ed0842012007413f71ad862108200541186a29030021092005290310210a4200210603402001200a7d210b0240200220097d2001200a54ad7d220c4200530d0020062008842106200b20035a200c20045a200c2004511b450d03200b2101200c21020b200a4201882009423f8684210a20084201882108200942018821090c000b0b4200210c024020024200520d0020012001200380220620037e7d21010c060b0240200220035a0d0020052003200441c000200279a7200379a76b22076b413f20071b220741ff007110ed0842012007413f71ad86210c200541086a290300210a200529030021094200210b034002402002200a7d2001200954ad7d22084200530d00200120097d2101200c200b84210b20084200510d04200821020b2009420188200a423f86842109200c420188210c200a420188210a0c000b0b20022003510d0320022002200380220820037e7d210c0240200342ffffffff0f560d00200c422086200142208884220a200a200380220a20037e7d422086200142ffffffff0f838422092009200380220920037e7d2101200a4220862009842106200a42208820088421084200210c0c070b0240200120035a200c20045a200c2004511b0d00420021060c070b2004423f86200342018884210a2003423f862109428080808080808080807f21024200210403400240200c200a7d2001200954ad7d220b4200530d00200120097d210120022004842104200b4200510d04200b210c0b2009420188200a423f8684210920024201882102200a420188210a0c000b0b42002108200b21010c050b2001200380220a200b8421062001200a20037e7d21014200210c0c030b2001200380220a20048421062001200a20037e7d21014200210c0c030b20012001200280220620027e7d21014200210c420121080c020b2002210c0b420021080b2000200137031020002006370300200041186a200c37030020002008370308200541206a24000b3c01017f230041206b220524002005200120022003200410e508200529031021012000200541186a29030037030820002001370300200541206a24000b3c01017f230041206b220524002005200120022003200410e508200529030021012000200541086a29030037030820002001370300200541206a24000b6e01077e2000200342ffffffff0f832205200142208822067e220720034220882208200142ffffffff0f8322097e7c220a422086220b200520097e7c22053703002000200a200754ad422086200a42208884200820067e7c2005200b54ad7c200420017e200320027e7c7c3703080b3601017f02402002450d00200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000b0b20000b6f01017f02400240200020016b20024f0d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000c020b0b2002450d00200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000b0b20000b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200041016a2100200141016a21012002417f6a2202450d020c000b0b200420056b21030b20030b5801017e02400240200341c00071450d0020012003413f71ad862102420021010c010b2003450d0020022003413f71ad2204862001410020036b413f71ad88842102200120048621010b20002001370300200020023703080b0bfef50c0200418080c0000be7f50c100010001c00000018020000050000006c6962726172792f616c6c6f632f7372632f7261775f7665632e7273c00010004b0000005a010000130000001200000004000000040000001300000014000000150000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f720012000000000000000100000016000000a800100018000000420200001c0000006c6962726172792f616c6c6f632f7372632f666d742e72732f72757374632f653337613133636333353934303034363633373338626431386438313030653664623936363663662f6c6962726172792f636f72652f7372632f666d742f6d6f642e72730050011000160000006601100016000000780f100001000000340110001c000000ee0400000d0000006c6962726172792f616c6c6f632f7372632f7665632f6d6f642e7273737761705f72656d6f766520696e6465782028697320292073686f756c64206265203c206c656e2028697320a401100014000000b801100017000000780f100001000000340110001c000000150500000d000000696e73657274696f6e20696e6465782028697320292073686f756c64206265203c3d206c656e202869732000f8011000120000006601100016000000780f100001000000340110001c000000450500000d00000072656d6f76616c20696e646578202869732000002c021000200000004c0210001200000012000000000000000100000017000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e64657820697320303030313032303330343035303630373038303931303131313231333134313531363137313831393230323132323233323432353236323732383239333033313332333333343335333633373338333934303431343234333434343534363437343834393530353135323533353435353536353735383539363036313632363336343635363636373638363937303731373237333734373537363737373837393830383138323833383438353836383738383839393039313932393339343935393639373938393900003803100010000000480310002200000072616e676520656e6420696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e677468205b2e2e2e5d00d00310000b000000da0d1000160000000f04100001000000b80d10000e000000c60d100004000000ca0d1000100000000f04100001000000d00310000b000000db03100026000000010410000800000009041000060000000f041000010000006279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f6620606018041000020000002e2e0000520410001b0000006500000014000000307800004004100012000000480310002200000072616e676520737461727420696e646578206c6962726172792f636f72652f7372632f666d742f6e756d2e727300010305050606030706080809110a1c0b190c140d100e0d0f0410031212130916011705180219031a071c021d011f1620032b032c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff0900d6091000250000000a0000001c000000ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f00d11454964658084b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f7475962f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab35280b80e003190801042f043404070301070607110a500f1207550703041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a06213f4c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b32d740c80d61a0c0580ff0580df0cee0d03848d033709815c1480b80880cb2a38030a06380846080c06740b1e035a0459098083181c0a16094c04808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d00d6091000250000001a000000360000000006010103010402080809020a050b020e041001110212051311140115021702190d1c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f802f902fa02fb010c273b3e4e4f8f9e9e9f060709363d3e56f3d0d1041418363756577faaaeafbd35e01287898e9e040d0e11122931343a4546494a4e4f64655cb6b71b1c07080a0b141736393aa8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d0aeaf79cc6e6f935e227b0503042d036603012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a8126524e28082a561c1417094e041e0f430e19070a0648082709750b3f412a063b050a0651060105100305808b621e48080a80a65e22450b0a060d1339070a362c041080c03c64530c48090a46451b4808531d398107460a1d03474937030e080a0639070a81361980b7010f320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140050b020e97f80884d62a09a2f7811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a80ae381d0d2c040907020e06809a83d8080d030d03740c59070c140c0438080a062808224e81540c15030305070919070709030d072980cb250a84066c6962726172792f636f72652f7372632f756e69636f64652f7072696e7461626c652e7273000c0a100016000000220a10000d000000736c69636520696e64657820737461727473206174202062757420656e647320617420000003000083042000910560005d13a0001217a01e0c20e01eef2c202b2a30a02b6fa6602c02a8e02c1efbe02d00fea0359effe035fd016136010aa136240d6137ab0ee1382f182139301c6146f31ea14af06a614e4f6fa14e9dbc214f65d1e14f00da215000e0e15130e16153ece2a154d0e8e15420002e55f001bf55900d100028000000520000003e00000000700007002d0101010201020101480b30151001650702060202010423011e1b5b0b3a09090118040109010301052b03770f0120370101010408040103070a021d013a0101010204080109010a021a010202390104020402020303011e0203010b0239010405010204011402160601013a0101020104080107030a021e013b0101010c0109012801030139030503010407020b021d013a01020102010301050207020b021c02390201010204080109010a021d0148010401020301010801510102070c08620102090b064a021b0101010101370e01050102050b0124090166040106010202021902040310040d01020206010f01000300031d031d021e02400201070801020b09012d03770222017603040209010603db0202013a010107010101010208060a020130113f0430070101050128090c0220040202010338010102030101033a0802029803010d0107040106010302c63a01050001c32100038d016020000669020004010a200250020001030104011902050197021a120d012608190b2e0330010204020227014306020202020c0108012f01330101030202050201012a020801ee010201040100010010101000020001e201950500030102050428030401a50200040002990bb001360f3803310402024503240501083e010c0234090a0402015f03020101020601a0010308150239020101010116010e070305c308020301011701510102060101020101020102eb010204060201021b025508020101026a0101010206010165030204010500090102f5010a0201010401900402020401200a280602040801090602032e0d010200070106010152160207010201027a060301010201070101480203010101000200053b0700013f0451010002000101030405080802071e0494030037043208010e011605010f000701110207010201050007000400076d07006080f000000000900d1000280000004b00000028000000900d10002800000057000000160000006c6962726172792f636f72652f7372632f756e69636f64652f756e69636f64655f646174612e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f6620603d3d00003c0e100019000000550e100012000000670e10000c0000000f041000010000003c0e100019000000550e100012000000670e10000c00000020311300020000000f04100001000000617373657274696f6e206661696c65643a2060286c6566742020726967687429600a20206c6566743a2060602c0a2072696768743a2060426f72726f774572726f72426f72726f774d75744572726f7270616e69636b656420617420c10e100001000000c20e1000030000005431130000000000c00e100001000000c00e1000010000003a27272c2020202020000000ec0e1000200000003200000021000000ec0e10002000000033000000120000006c6962726172792f636f72652f7372632f666d742f6275696c646572732e72731c0f1000200000005a000000050000006c6962726172792f636f72652f7372632f736c6963652f6d656d6368722e72732c200000120000000c0000000400000018000000190000001a0000002c0a00001200000004000000040000001b0000001c0000001d00000028280a2c290a5d617373657274696f6e206661696c65643a202a63757272203e20313900520410001b000000e6010000050000005b000000cc0f10001b0000001308000016000000cc0f10001b0000000c0800001e0000006c6962726172792f636f72652f7372632f666d742f6d6f642e727330620001021200000001000000010000001e0000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f73797374656d2f7372632f6c696d6974732e72734275696c6465722066696e6973686564207769746820606275696c645f6f725f70616e6963603b205468652070616e69632069732065787065637465642069662072756e74696d65207765696768747320617265206e6f7420636f727265637400fc0f100057000000aa01000016000000543113000000000000000000ffffffff00000000010000000000000082800000000000008a8000000000008000800080000000808b800000000000000100008000000000818000800000008009800000000000808a00000000000000880000000000000009800080000000000a000080000000008b800080000000008b0000000000008089800000000000800380000000000080028000000000008080000000000000800a800000000000000a0000800000008081800080000000808080000000000080010000800000000008800080000000801200000004000000040000001f00000001a8010001605354524f424576312e302e320000cc1110004f000000680000000d0000002f636172676f2d686f6d652f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6d65726c696e2d322e302e302f7372632f7374726f62652e727300f2121000190000000b1310001600000000000000200000000400000002000000000000000200000000000000030000000100000020000000040000000200000000000000020000000000000003000000cc1110004f000000880000000d000000b41210003e000000cc1110004f0000009100000009000000cc1110004f0000005e00000009000000cc1110004f0000005f00000009000000596f75207573656420746865205420666c61672c207768696368207468697320696d706c656d656e746174696f6e20646f65736e277420737570706f7274596f7520747269656420746f20636f6e74696e7565206f702020627574206368616e67656420666c61677320746f20000000cc1110004f0000007c00000015000000cc1110004f0000007d0000000d0000004661696c656420746f206465636f646520636f6d70616374207533322061743a496e76616c6964526f756e6457726f6e6757696e6e6572436f756e74536e617073686f74556e617661696c61626c654e706f73456c656374696f6e0012000000040000000400000020000000496e76616c6964566f7465496e76616c6964566f746572496e76616c696457696e6e6572496e76616c696453636f726500000000641410000e00000000000000741410000100000000000000000000007c141000010000000000000000000000841410000600000000000000543113000000000000000000000000008c141000010000000000000000000000941410000700000000000000543113000000000000000000000000009c14100001000000000000004e6577417574686f7269746965730000291510000d000000f3141000360000005061757365640000cc14100027000000526573756d656400a4141000280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e205c5b617574686f726974795f7365745c5d417574686f726974794c69737400002813130056000000bd0000002e000000000000007415100007000000000000007c1510000300000000000000000000009415100004000000000000004f6666656e636500c248110004000000c64811000e000000a1fb120004000000b41510005500000009161000530000005c16100046000000a21610001d00000020546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e6420286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e206c61737420656c656d656e7420696e64696361746573206f6620746865206f6666656e636520776173206170706c69656420287472756529206f7220717565756564202866616c736529205c5b6b696e642c2074696d65736c6f742c206170706c6965645c5d2e53746f72656452616e6765000000000000f81610000a0000000000000028b111000100000000000000000000000417100002000000000000004e657753657373696f6e000014171000590000006d17100022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e7420697320746865205c5b73657373696f6e5f696e6465785c5d2c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e74696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672e000000004018100010000000000000005018100002000000000000000000000060181000020000000000000000000000701810000e00000000000000543113000000000000000000000000008018100001000000000000004261746368496e746572727570746564cbed120003000000113513000d000000bb1810005600000011191000240000004261746368436f6d706c6574656400008818100033000000204261746368206f66206469737061746368657320636f6d706c657465642066756c6c792077697468206e6f206572726f722e204261746368206f66206469737061746368657320646964206e6f7420636f6d706c6574652066756c6c792e20496e646578206f66206669727374206661696c696e6720646973706174636820676976656e2c2061732077656c6c20617320746865206572726f722e205c5b696e6465782c206572726f725c5d000000481910005a00000067000000120000002f636172676f2d686f6d652f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d322e302e302f7372632f636f6465632e7273436f646563206572726f724572726f720000c41910004c00000076060000240000002f72757374632f653337613133636333353934303034363633373338626431386438313030653664623936363663662f6c6962726172792f616c6c6f632f7372632f7665632f6d6f642e727300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000100000021000000647c1200660000005c0000001f00000056524648617368565246526573756c747672662d696e7672662d6f7574436865636b547856657273696f6e436865636b47656e65736973436865636b4d6f7274616c697479000000081c10005a000000af050000350000002f72757374632f653337613133636333353934303034363633373338626431386438313030653664623936363663662f6c6962726172792f616c6c6f632f7372632f636f6c6c656374696f6e732f62747265652f6d61702e7273627450656e64696e675061796f7574496e76616c6964466565496e76616c696456616c75655265717569726543757261746f72556e657870656374656453746174757300000000000000341e10000e00000000000000441e1000020000000000000000000000741e10000c0000000000000000000000d41e10000e00000000000000e41e1000010000000000000000000000fc1e10000800000000000000000000003c1f10000f000000000000004c1f1000030000000000000000000000941f1000070000000000000000000000cc1f10001000000000000000e41e1000010000000000000000000000dc1f10001200000000000000000000006c2010000e00000000000000e41e10000100000000000000000000007c201000080000000000000000000000bc2010000c00000000000000c8201000020000000000000000000000f82010000a0000000000000000000000482110000c00000000000000e41e1000010000000000000000000000542110000900000000000000000000009c2110000c00000000000000e41e1000010000000000000000000000a82110000a0000000000000000000000f821100014000000000000000c2210000200000000000000000000003c2210000a0000000000000070726f706f73655f626f756e747900000000000048b6120005000000000000004db6120015000000000000002d2b10000b0000000000000042ec120007000000d42910001600000054311300000000006c0e1300340000005431130000000000c0ea110055000000ea291000550000003f2a10001a0000005431130000000000592a10003f000000982a10001a000000b22a10004a000000fc2a100031000000617070726f76655f626f756e74790000000000004623100009000000000000004f231000140000007c291000580000001f0211002b00000054311300000000004a0211002c0000005431130000000000f2eb12000b000000638711000800000036ec12000c00000070726f706f73655f63757261746f7200000000004623100009000000000000004f231000140000000000000075291000070000000000000085fc11002300000000000000e5ca100003000000000000004db6120015000000502910002500000054311300000000004a0211002c0000005431130000000000f2eb12000b000000638711000800000036ec12000c000000756e61737369676e5f63757261746f724c2610002000000054311300000000006c261000480000005431130000000000b42610005a0000000e2710004300000054311300000000005127100059000000aa27100058000000022810004e00000054311300000000005028100058000000a828100059000000012910004f0000005431130000000000f2eb12000b000000638711000800000036ec12000c0000006163636570745f63757261746f720000b625100026000000dc2510004b000000543113000000000027261000250000005431130000000000f2eb12000b000000638711000800000036ec12000c00000061776172645f626f756e7479000000004623100009000000000000004f2310001400000000000000b80411000b0000000000000085fc110023000000e6241000660000005431130000000000b82210004600000054311300000000004c251000230000006f251000470000005431130000000000f2eb12000b000000638711000800000036ec12000c000000636c61696d5f626f756e74793d2410003c0000005431130000000000792410004a0000005431130000000000c3241000230000005431130000000000f2eb12000b000000638711000800000036ec12000c000000636c6f73655f626f756e7479632310004f000000b2231000340000005431130000000000e623100033000000543113000000000019241000240000005431130000000000f2eb12000b000000638711000800000036ec12000c000000657874656e645f626f756e74795f657870697279000000004623100009000000000000004f231000140000000000000006f31200070000000000000042ec1200070000008c2210002c0000005431130000000000b8221000460000005431130000000000fe2210002400000022231000240000005431130000000000f2eb12000b000000638711000800000036ec12000c00000020457874656e6420746865206578706972792074696d65206f6620616e2061637469766520626f756e74792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f66207468697320626f756e74792e202d2060626f756e74795f6964603a20426f756e747920494420746f20657874656e642e202d206072656d61726b603a206164646974696f6e616c20696e666f726d6174696f6e2e626f756e74795f6964436f6d706163743c426f756e7479496e6465783e2043616e63656c20612070726f706f736564206f722061637469766520626f756e74792e20416c6c207468652066756e64732077696c6c2062652073656e7420746f20747265617375727920616e64207468652063757261746f72206465706f7369742077696c6c20626520756e726573657276656420696620706f737369626c652e204f6e6c792060543a3a52656a6563744f726967696e602069732061626c6520746f2063616e63656c206120626f756e74792e202d2060626f756e74795f6964603a20426f756e747920494420746f2063616e63656c2e20436c61696d20746865207061796f75742066726f6d20616e206177617264656420626f756e7479206166746572207061796f75742064656c61792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652062656e6566696369617279206f66207468697320626f756e74792e202d2060626f756e74795f6964603a20426f756e747920494420746f20636c61696d2e20417761726420626f756e747920746f20612062656e6566696369617279206163636f756e742e205468652062656e65666963696172792077696c6c2062652061626c6520746f20636c61696d207468652066756e647320616674657220612064656c61792e202d2060626f756e74795f6964603a20426f756e747920494420746f2061776172642e202d206062656e6566696369617279603a205468652062656e6566696369617279206163636f756e742077686f6d2077696c6c207265636569766520746865207061796f75742e20416363657074207468652063757261746f7220726f6c6520666f72206120626f756e74792e2041206465706f7369742077696c6c2062652072657365727665642066726f6d2063757261746f7220616e6420726566756e642075706f6e207375636365737366756c207061796f75742e204d6179206f6e6c792062652063616c6c65642066726f6d207468652063757261746f722e20556e61737369676e2063757261746f722066726f6d206120626f756e74792e20546869732066756e6374696f6e2063616e206f6e6c792062652063616c6c656420627920746865206052656a6563744f726967696e602061207369676e6564206f726967696e2e20496620746869732066756e6374696f6e2069732063616c6c656420627920746865206052656a6563744f726967696e602c20776520617373756d652074686174207468652063757261746f72206973206d616c6963696f7573206f7220696e6163746976652e204173206120726573756c742c2077652077696c6c20736c617368207468652063757261746f72207768656e20706f737369626c652e20496620746865206f726967696e206973207468652063757261746f722c2077652074616b6520746869732061732061207369676e20746865792061726520756e61626c6520746f20646f207468656972206a6f6220616e6420746865792077696c6c696e676c7920676976652075702e20576520636f756c6420736c617368207468656d2c2062757420666f72206e6f7720776520616c6c6f77207468656d20746f207265636f766572207468656972206465706f73697420616e64206578697420776974686f75742069737375652e20285765206d61792077616e7420746f206368616e67652074686973206966206974206973206162757365642e292046696e616c6c792c20746865206f726967696e2063616e20626520616e796f6e6520696620616e64206f6e6c79206966207468652063757261746f722069732022696e616374697665222e205468697320616c6c6f777320616e796f6e6520696e2074686520636f6d6d756e69747920746f2063616c6c206f7574207468617420612063757261746f72206973206e6f7420646f696e67207468656972206475652064696c6967656e63652c20616e642077652073686f756c64207069636b2061206e65772063757261746f722e20496e20746869732063617365207468652063757261746f722073686f756c6420616c736f20626520736c61736865642e2041737369676e20612063757261746f7220746f20612066756e64656420626f756e74792e63757261746f7220417070726f7665206120626f756e74792070726f706f73616c2e2041742061206c617465722074696d652c2074686520626f756e74792077696c6c2062652066756e64656420616e64206265636f6d65206163746976652050726f706f73652061206e657720626f756e74792e2060446174614465706f736974506572427974656020666f722065616368206279746520696e2060726561736f6e602e2049742077696c6c20626520756e72657365727665642075706f6e20617070726f76616c2c206f7220736c6173686564207768656e2072656a65637465642e202d206063757261746f72603a205468652063757261746f72206163636f756e742077686f6d2077696c6c206d616e616765207468697320626f756e74792e202d2060666565603a205468652063757261746f72206665652e202d206076616c7565603a2054686520746f74616c207061796d656e7420616d6f756e74206f66207468697320626f756e74792c2063757261746f722066656520696e636c756465642e202d20606465736372697074696f6e603a20546865206465736372697074696f6e206f66207468697320626f756e74792e6465736372697074696f6e00000000982c10000b0000000000000000000000a32c10000b0000000000000000000000000000000000000000000000000000000000000054311300b02c10000000000000000000c02c1000010000000000000001000000000000001dbf1100080000000105000000000000a32c10000b00000000000000c82c1000320000000000000000000000000000000000000054311300fc2c100000000000000000000c2d100001000000000000000000000000000000142d1000120000000105000000000000a32c10000b0000000000000042ec1200070000000000000000000000000000000000000054311300282d10000000000000000000382d100001000000000000000000000000000000402d10000f00000000000000000000004f2d1000100000000000000000000000000000000000000000000000000000000000000054311300602d10000000000000000000702d1000010000000000000001000000426f756e7479436f756e74426f756e7479496e646578000012000000000000000100000022000000f12d100030000000426f756e74793c543a3a4163636f756e7449642c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265723e000012000000000000000100000023000000d32d10001e000000426f756e74794465736372697074696f6e73000012000000000000000100000023000000b32d100020000000426f756e7479417070726f76616c735665633c426f756e7479496e6465783e0012000000000000000100000024000000782d10003b00000020426f756e747920696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f74207965742066756e6465642e20546865206465736372697074696f6e206f66206561636820626f756e74792e20426f756e7469657320746861742068617665206265656e206d6164652e204e756d626572206f6620626f756e74792070726f706f73616c7320746861742068617665206265656e206d6164652e000000000000000cf01100120000000000000057a912000c0000000000000054311300ac2f10000000000000000000bc2f1000010000000000000000000000c42f1000110000000000000057a912000c0000000000000054311300d82f10000000000000000000e82f1000010000000000000000000000f02f10001800000000000000a9f912000e000000000000005431130008301000000000000000000018301000010000000000000000000000203010001200000000000000a9f912000e0000000000000054311300343010000000000000000000443010000100000000000000000000004c3010001400000000000000fc0711000700000000000000543113006030100000000000000000007030100001000000000000000000000078301000120000000000000057a912000c00000000000000543113008c30100000000000000000009c30100001000000000000000000000038f011001300000000000000cbed1200030000000000000054311300a430100000000000000000005cf01100010000000000000012000000000000000100000025000000d63110003f000000426f756e74794465706f73697442617365000000120000000000000001000000260000009c3110003a000000426f756e74794465706f7369745061796f757444656c6179120000000000000001000000270000004631100056000000426f756e7479557064617465506572696f640000120000000000000001000000280000002b3110001b000000426f756e747943757261746f724465706f73697412000000000000000100000029000000d03010005b000000426f756e747956616c75654d696e696d756d00001200000000000000010000002a000000b43010001c0000001200000000000000010000002b000000204d696e696d756d2076616c756520666f72206120626f756e74792e2050657263656e74616765206f66207468652063757261746f722066656520746861742077696c6c20626520726573657276656420757066726f6e74206173206465706f73697420666f7220626f756e74792063757261746f722e20426f756e7479206475726174696f6e20696e20626c6f636b732e205468652064656c617920706572696f6420666f72207768696368206120626f756e74792062656e6566696369617279206e65656420746f2077616974206265666f726520636c61696d20746865207061796f75742e2054686520616d6f756e742068656c64206f6e206465706f73697420666f7220706c6163696e67206120626f756e74792070726f706f73616c2e2054686520616d6f756e742068656c64206f6e206465706f7369742070657220627974652077697468696e20626f756e7479206465736372697074696f6e2e000000000000004c3310000e000000000000005c331000010000000000000000000000643310000100000000000000000000006c3310000e000000000000007c3310000200000000000000000000008c3310000100000000000000000000009433100012000000000000005c331000010000000000000000000000a8331000010000000000000000000000b03310000d00000000000000c0331000020000000000000000000000d0331000010000000000000000000000d83310000d00000000000000e833100003000000000000000000000000341000010000000000000000000000083410000e000000000000005c33100001000000000000000000000018341000010000000000000000000000203410000e000000000000005c331000010000000000000000000000303410000100000000000000426f756e747950726f706f7365640000a32c10000b0000007d3510001f000000426f756e747952656a65637465640000a32c10000b000000d5d11200070000003935100044000000426f756e7479426563616d6541637469766500000035100039000000426f756e747941776172646564000000a32c10000b00000079e5120009000000c33410003d000000426f756e7479436c61696d6564000000a32c10000b000000d5d112000700000079e51200090000008034100043000000426f756e747943616e63656c656400005f34100021000000426f756e7479457874656e64656400003834100027000000204120626f756e74792065787069727920697320657874656e6465642e205c5b696e6465785c5d204120626f756e74792069732063616e63656c6c65642e205c5b696e6465785c5d204120626f756e747920697320636c61696d65642062792062656e65666963696172792e205c5b696e6465782c207061796f75742c2062656e65666963696172795c5d204120626f756e7479206973206177617264656420746f20612062656e65666963696172792e205c5b696e6465782c2062656e65666963696172795c5d204120626f756e74792070726f706f73616c2069732066756e64656420616e6420626563616d65206163746976652e205c5b696e6465785c5d204120626f756e74792070726f706f73616c207761732072656a65637465643b2066756e6473207765726520736c61736865642e205c5b696e6465782c20626f6e645c5d204e657720626f756e74792070726f706f73616c2e205c5b696e6465785c5d1200000004000000040000002c0000002d0000002e00000012000000000000000100000021000000617373657274696f6e206661696c65643a2073656c662e6361702829203d3d206f6c645f636170202a203200003610005e0000002d0800000d0000002f72757374632f653337613133636333353934303034363633373338626431386438313030653664623936363663662f6c6962726172792f616c6c6f632f7372632f636f6c6c656374696f6e732f7665635f64657175652f6d6f642e72730000c012130056000000030100000100000000000000d0ff10001c000000000000001c1711000100000000000000000000004ab510000c00000000000000241711000100000000000000000000001eda11000c000000000000003c281200010000000000000000000000951c100010000000000000006c371000010000000000000000000000871c10000e00000000000000743710000100000000000000000000007b1c10000c000000000000007c371000010000000000000000000000711c10000a0000000000000084371000010000000000000000000000641c10000d000000000000008c3710000200000000000000000000002ada110009000000000000009c371000010000000000000093381000210000007b3810001800000065381000160000005138100014000000f63710001c000000123810003f000000a4371000520000002054686520626f756e746965732063616e6e6f7420626520636c61696d65642f636c6f73656420626563617573652069742773207374696c6c20696e2074686520636f756e74646f776e20706572696f642e204120626f756e7479207061796f75742069732070656e64696e672e20546f2063616e63656c2074686520626f756e74792c20796f75206d75737420756e61737369676e20616e6420736c617368207468652063757261746f722e20496e76616c696420626f756e7479206665652e20496e76616c696420626f756e74792076616c75652e205265717569726520626f756e74792063757261746f722e2054686520626f756e74792073746174757320697320756e65787065637465642ef838100066000000200000000e000000617373657274696f6e206661696c65643a206d6964203c3d2073656c662e6c656e282900483513004d000000ff050000090000002f72757374632f653337613133636333353934303034363633373338626431386438313030653664623936363663662f6c6962726172792f616c6c6f632f7372632f636f6c6c656374696f6e732f7665635f64657175652f72696e675f736c696365732e727300002f00000060000000080000003000000031000000320000003300000034000000350000003600000014211300600000006f010000010000004c06130053000000a00000000f0000006d6f646c70792f70726f78795f5f5f5f00000000000000000000000000000000000000000000000000000000000000000000000007000000e020130023000000d8000000010000006d6f76655f636c61696d617474657374636c61696d5f6174746573746d696e745f636c61696d000000000000c03a10001800000000000000d83a1000010000000000000000000000e03a10001000000000000000f03a1000010000000000000000000000f83a10001000000000000000083b1000010000000000000000000000103b10000c000000000000001c3b10000200000000000000000000002c3b100010000000000000003c3b1000010000000000000000000000443b10001300000000000000583b10000100000000000000496e76616c6964457468657265756d5369676e6174757265523c10001c0000005369676e65724861734e6f436c61696d333c10001f00000053656e6465724861734e6f436c61696d0f3c100024000000506f74556e646572666c6f77af3b100059000000083c100007000000496e76616c696453746174656d656e748a3b10002500000056657374656442616c616e636545786973747300603b10002a00000020546865206163636f756e7420616c7265616479206861732061207665737465642062616c616e63652e2041206e65656465642073746174656d656e7420776173206e6f7420696e636c756465642e2054686572652773206e6f7420656e6f75676820696e2074686520706f7420746f20706179206f757420736f6d6520756e76657374656420616d6f756e742e2047656e6572616c6c7920696d706c6965732061206c6f676963206572726f722e204163636f756e742049442073656e64696e6720747820686173206e6f20636c61696d2e20457468657265756d206164647265737320686173206e6f20636c61696d2e20496e76616c696420457468657265756d207369676e61747572652e636c61696d7319457468657265756d205369676e6564204d6573736167653a0a50687261676d656e456c656374696f6e43616e6469646174657352756e6e65727355700000001421130060000000990300002c00000050726576616c696461746541747465737473507265636c61696d735175657565644b657973546f74616c4e6f206f746865722076657374696e67207363686564756c65206578697374732c20617320636865636b65642061626f76653b20716564000000120000000c0000000400000037000000e020130023000000bf01000012000000556e616e6e6f756e6365644475706c6963617465556e70726f787961626c654e6f7450726f7879546f6f4d616e794e6f53656c6650726f787900000000000000083e10000d00000000000000183e1000010000000000000000000000203e1000010000000000000000000000283e10001000000000000000383e1000040000000000000000000000583e1000020000000000000000000000683e10000900000000000000743e10000300000000000000000000008c3e1000010000000000000050726f78794578656375746564000000637a12000e000000863f10003b000000416e6f6e796d6f75734372656174656479e512000900000079e51200090000007d3f100009000000a50e130003000000e83e10003b000000233f10005a000000416e6e6f756e63656400000079e512000900000079e512000900000082e5120004000000943e10005400000020416e20616e6e6f756e63656d656e742077617320706c6163656420746f206d616b6520612063616c6c20696e20746865206675747572652e205c5b7265616c2c2070726f78792c2063616c6c5f686173685c5d20416e6f6e796d6f7573206163636f756e7420686173206265656e2063726561746564206279206e65772070726f7879207769746820676976656e20646973616d626967756174696f6e20696e64657820616e642070726f787920747970652e205c5b616e6f6e796d6f75732c2077686f2c2070726f78795f747970652c20646973616d626967756174696f6e5f696e6465785c5d50726f78795479706520412070726f78792077617320657865637574656420636f72726563746c792c20776974682074686520676976656e205c5b726573756c745c5d2e000000000000007c411000050000000000000084411000030000000000000000000000cc4110000f000000000000000000000044421000090000000000000050421000030000000000000000000000984210000d0000000000000000000000004310000c00000000000000504210000300000000000000000000000c4310000b0000000000000000000000644310000e0000000000000054311300000000000000000000000000744310000a0000000000000000000000c44310000900000000000000d043100003000000000000000000000018441000170000000000000000000000d04410000e00000000000000e044100005000000000000000000000058451000140000000000000000000000f845100008000000000000000046100002000000000000000000000030461000150000000000000000000000d8461000130000000000000000461000020000000000000000000000ec4610001000000000000000000000006c471000130000000000000080471000020000000000000000000000b0471000100000000000000000000000304810000f0000000000000040481000040000000000000000000000a0481000110000000000000070726f787900000000000000ef4a10000400000000000000e3f812000c00000000000000f34a10001000000000000000034b10001400000000000000a80e13000400000000000000ac0e130018000000b3581000540000007c4910000d0000005431130000000000894910002b00000054311300000000006c0e1300340000005431130000000000355f12000c000000b449100044000000f849100059000000514a1000350000005431130000000000f2eb12000b000000535210004000000036ec12000c0000006164645f70726f787900000000000000f48c12000800000000000000e3f812000c000000000000009a5210000a00000000000000a45210000c000000000000001fae12000500000000000000a9f912000e000000dc5710005200000054311300000000006c0e1300340000005431130000000000355f12000c0000002e58100045000000735810004000000007551000540000005b551000060000005431130000000000f2eb12000b000000535210004000000036ec12000c00000072656d6f76655f70726f7879165710002b00000054311300000000006c0e1300340000005431130000000000355f12000c000000415710004a0000008b571000510000005431130000000000f2eb12000b000000535210004000000036ec12000c00000072656d6f76655f70726f7869657300003b5610002e00000054311300000000006c0e13003400000054311300000000006956100056000000bf561000570000005431130000000000f2eb12000b000000535210004000000036ec12000c000000616e6f6e796d6f7573000000000000009a5210000a00000000000000a45210000c000000000000001fae12000500000000000000a9f912000e00000000000000a00e13000500000000000000a50e130003000000d65210004f00000025531000400000005431130000000000655310001c00000054311300000000008153100055000000d6531000540000002a5410001f00000049541000550000009e54100058000000f65410001100000007551000540000005b5510000600000054311300000000006155100055000000b6551000270000005431130000000000dd5510003a0000005431130000000000f2eb12000b000000535210004000000036ec12000c00000017561000240000006b696c6c5f616e6f6e796d6f7573000000000000935210000700000000000000e3f812000c000000000000009a5210000a00000000000000a45210000c00000000000000a00e13000500000000000000a50e13000300000000000000b05210000600000000000000b65210001700000000000000cd5210000900000000000000d2a012000c000000264f10002e0000005431130000000000544f100053000000a74f10000e0000005431130000000000b54f1000570000000c5010002b000000543113000000000037501000540000008b50100054000000df50100041000000205110005000000070511000530000005431130000000000c351100053000000165210003d0000005431130000000000f2eb12000b000000535210004000000036ec12000c000000616e6e6f756e636500000000ef4a10000400000000000000e3f812000c000000000000008cf010000900000000000000554c10000d000000294d10004200000054311300000000006b4d100058000000c34d10004a00000054311300000000000d4e1000450000005431130000000000524e100043000000954e1000470000005431130000000000dc4e10004a0000005431130000000000355f12000c000000b449100044000000e34c1000460000005431130000000000f2eb12000b000000864a1000190000009f4a100027000000c64a10002900000036ec12000c00000072656d6f76655f616e6e6f756e63656d656e7400624c10001d00000054311300000000007f4c100057000000d64c10000d00000054311300000000006c0e1300340000005431130000000000355f12000c000000b449100044000000e34c1000460000005431130000000000f2eb12000b000000864a1000190000009f4a100027000000c64a10002900000036ec12000c00000072656a6563745f616e6e6f756e63656d656e740000000000f48c12000800000000000000e3f812000c000000000000008cf010000900000000000000554c10000d000000174b10002d0000005431130000000000444b1000590000009d4b10004a00000054311300000000006c0e1300340000005431130000000000355f12000c000000e74b10003e000000254c1000300000005431130000000000f2eb12000b000000864a1000190000009f4a100027000000c64a10002900000036ec12000c00000070726f78795f616e6e6f756e6365640000000000f48c12000800000000000000e3f812000c00000000000000ef4a10000400000000000000e3f812000c00000000000000f34a10001000000000000000034b10001400000000000000a80e13000400000000000000ac0e13001800000028491000540000007c4910000d0000005431130000000000894910002b00000054311300000000006c0e1300340000005431130000000000355f12000c000000b449100044000000f849100059000000514a1000350000005431130000000000f2eb12000b000000864a1000190000009f4a100027000000c64a10002900000036ec12000c0000002044697370617463682074686520676976656e206063616c6c602066726f6d20616e206163636f756e742074686174207468652073656e64657220697320617574686f72697a656420666f72207468726f75676820606164645f70726f7879602e2052656d6f76657320616e7920636f72726573706f6e64696e6720616e6e6f756e63656d656e742873292e202d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e202d2060666f7263655f70726f78795f74797065603a2053706563696679207468652065786163742070726f7879207479706520746f206265207573656420616e6420636865636b656420666f7220746869732063616c6c2e202d206063616c6c603a205468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e2057656967687420697320612066756e6374696f6e206f663a202d20413a20746865206e756d626572206f6620616e6e6f756e63656d656e7473206d6164652e202d20503a20746865206e756d626572206f662070726f78696573207468652075736572206861732e7265616c666f7263655f70726f78795f747970654f7074696f6e3c543a3a50726f7879547970653e2052656d6f76652074686520676976656e20616e6e6f756e63656d656e74206f6620612064656c65676174652e204d61792062652063616c6c6564206279206120746172676574202870726f7869656429206163636f756e7420746f2072656d6f766520612063616c6c2074686174206f6e65206f662074686569722064656c65676174657320286064656c656761746560292068617320616e6e6f756e63656420746865792077616e7420746f20657865637574652e20546865206465706f7369742069732072657475726e65642e202d206064656c6567617465603a20546865206163636f756e7420746861742070726576696f75736c7920616e6e6f756e636564207468652063616c6c2e202d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652e43616c6c486173684f663c543e2052656d6f7665206120676976656e20616e6e6f756e63656d656e742e204d61792062652063616c6c656420627920612070726f7879206163636f756e7420746f2072656d6f766520612063616c6c20746865792070726576696f75736c7920616e6e6f756e63656420616e642072657475726e20746865206465706f7369742e202d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e205075626c697368207468652068617368206f6620612070726f78792d63616c6c20746861742077696c6c206265206d61646520696e20746865206675747572652e2054686973206d7573742062652063616c6c656420736f6d65206e756d626572206f6620626c6f636b73206265666f72652074686520636f72726573706f6e64696e67206070726f78796020697320617474656d70746564206966207468652064656c6179206173736f6369617465642077697468207468652070726f78792072656c6174696f6e736869702069732067726561746572207468616e207a65726f2e204e6f206d6f7265207468616e20604d617850656e64696e676020616e6e6f756e63656d656e7473206d6179206265206d61646520617420616e79206f6e652074696d652e20546869732077696c6c2074616b652061206465706f736974206f662060416e6e6f756e63656d656e744465706f736974466163746f72602061732077656c6c2061732060416e6e6f756e63656d656e744465706f736974426173656020696620746865726520617265206e6f206f746865722070656e64696e6720616e6e6f756e63656d656e74732e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420612070726f7879206f6620607265616c602e2052656d6f76657320612070726576696f75736c7920737061776e656420616e6f6e796d6f75732070726f78792e205741524e494e473a202a2a416c6c2061636365737320746f2074686973206163636f756e742077696c6c206265206c6f73742e2a2a20416e792066756e64732068656c6420696e2069742077696c6c20626520696e61636365737369626c652e205265717569726573206120605369676e656460206f726967696e2c20616e64207468652073656e646572206163636f756e74206d7573742068617665206265656e206372656174656420627920612063616c6c20746f2060616e6f6e796d6f757360207769746820636f72726573706f6e64696e6720706172616d65746572732e202d2060737061776e6572603a20546865206163636f756e742074686174206f726967696e616c6c792063616c6c65642060616e6f6e796d6f75736020746f206372656174652074686973206163636f756e742e202d2060696e646578603a2054686520646973616d626967756174696f6e20696e646578206f726967696e616c6c792070617373656420746f2060616e6f6e796d6f7573602e2050726f6261626c79206030602e202d206070726f78795f74797065603a205468652070726f78792074797065206f726967696e616c6c792070617373656420746f2060616e6f6e796d6f7573602e202d2060686569676874603a2054686520686569676874206f662074686520636861696e207768656e207468652063616c6c20746f2060616e6f6e796d6f757360207761732070726f6365737365642e202d20606578745f696e646578603a205468652065787472696e73696320696e64657820696e207768696368207468652063616c6c20746f2060616e6f6e796d6f757360207761732070726f6365737365642e204661696c73207769746820604e6f5065726d697373696f6e6020696e2063617365207468652063616c6c6572206973206e6f7420612070726576696f75736c79206372656174656420616e6f6e796d6f7573206163636f756e742077686f73652060616e6f6e796d6f7573602063616c6c2068617320636f72726573706f6e64696e6720706172616d65746572732e2057656967687420697320612066756e6374696f6e206f6620746865206e756d626572206f662070726f7869657320746865207573657220686173202850292e737061776e657270726f78795f74797065543a3a50726f787954797065686569676874436f6d706163743c543a3a426c6f636b4e756d6265723e6578745f696e64657820537061776e2061206672657368206e6577206163636f756e7420746861742069732067756172616e7465656420746f206265206f746865727769736520696e61636365737369626c652c20616e6420696e697469616c697a65206974207769746820612070726f7879206f66206070726f78795f747970656020666f7220606f726967696e602073656e6465722e205265717569726573206120605369676e656460206f726967696e2e202d206070726f78795f74797065603a205468652074797065206f66207468652070726f78792074686174207468652073656e6465722077696c6c2062652072656769737465726564206173206f76657220746865206e6577206163636f756e742e20546869732077696c6c20616c6d6f737420616c7761797320626520746865206d6f7374207065726d697373697665206050726f7879547970656020706f737369626c6520746f20616c6c6f7720666f72206d6178696d756d20666c65786962696c6974792e202d2060696e646578603a204120646973616d626967756174696f6e20696e6465782c20696e206361736520746869732069732063616c6c6564206d756c7469706c652074696d657320696e207468652073616d65207472616e73616374696f6e2028652e672e207769746820607574696c6974793a3a626174636860292e20556e6c65737320796f75277265207573696e67206062617463686020796f752070726f6261626c79206a7573742077616e7420746f20757365206030602e202d206064656c6179603a2054686520616e6e6f756e63656d656e7420706572696f64207265717569726564206f662074686520696e697469616c2070726f78792e2057696c6c2067656e6572616c6c79206265207a65726f2e204661696c73207769746820604475706c69636174656020696620746869732068617320616c7265616479206265656e2063616c6c656420696e2074686973207472616e73616374696f6e2c2066726f6d207468652073616d652073656e6465722c2077697468207468652073616d6520706172616d65746572732e204661696c732069662074686572652061726520696e73756666696369656e742066756e647320746f2070617920666f72206465706f7369742e20544f444f3a204d69676874206265206f76657220636f756e74696e672031207265616420556e726567697374657220616c6c2070726f7879206163636f756e747320666f72207468652073656e6465722e205741524e494e473a2054686973206d61792062652063616c6c6564206f6e206163636f756e747320637265617465642062792060616e6f6e796d6f7573602c20686f776576657220696620646f6e652c207468656e2074686520756e726573657276656420666565732077696c6c20626520696e61636365737369626c652e202a2a416c6c2061636365737320746f2074686973206163636f756e742077696c6c206265206c6f73742e2a2a20556e726567697374657220612070726f7879206163636f756e7420666f72207468652073656e6465722e202d206070726f7879603a20546865206163636f756e74207468617420746865206063616c6c65726020776f756c64206c696b6520746f2072656d6f766520617320612070726f78792e202d206070726f78795f74797065603a20546865207065726d697373696f6e732063757272656e746c7920656e61626c656420666f72207468652072656d6f7665642070726f7879206163636f756e742e20526567697374657220612070726f7879206163636f756e7420666f72207468652073656e64657220746861742069732061626c6520746f206d616b652063616c6c73206f6e2069747320626568616c662e202d206070726f7879603a20546865206163636f756e74207468617420746865206063616c6c65726020776f756c64206c696b6520746f206d616b6520612070726f78792e202d206070726f78795f74797065603a20546865207065726d697373696f6e7320616c6c6f77656420666f7220746869732070726f7879206163636f756e742e2044697370617463682074686520676976656e206063616c6c602066726f6d20616e206163636f756e742074686174207468652073656e64657220697320617574686f726973656420666f72207468726f7567680000000000a82d1200070000000105000000000000e3f812000c00000000000000b85910005100000000000000000000000000000000000000543113000c5a100000000000000000001c5a100002000000000000000100000000000000af2d12000d0000000105000000000000e3f812000c000000000000002c5a10004f00000000000000000000000000000000000000543113007c5a100000000000000000008c5a1000010000000000000001000000285665633c50726f7879446566696e6974696f6e3c543a3a4163636f756e7449642c20543a3a50726f7879547970652c20543a3a426c6f636b4e756d6265723e3e2c0a2042616c616e63654f663c543e2900000012000000000000000100000038000000bf5a100051000000105b100048000000285665633c416e6e6f756e63656d656e743c543a3a4163636f756e7449642c2043616c6c486173684f663c543e2c20543a3a426c6f636b4e756d6265723e3e2c0a2042616c616e63654f663c543e290012000000000000000100000039000000945a10002b0000002054686520616e6e6f756e63656d656e7473206d616465206279207468652070726f787920286b6579292e2054686520736574206f66206163636f756e742070726f786965732e204d61707320746865206163636f756e74207768696368206861732064656c65676174656420746f20746865206163636f756e747320776869636820617265206265696e672064656c65676174656420746f2c20746f67657468657220776974682074686520616d6f756e742068656c64206f6e206465706f7369742e00000000a85c1000100000000000000057a912000c0000000000000054311300b85c10000000000000000000c85c1000040000000000000000000000e85c1000120000000000000057a912000c0000000000000054311300fc5c100000000000000000000c5d1000050000000000000000000000345d10000a00000000000000a50e1300030000000000000054311300405d10000000000000000000505d1000010000000000000000000000585d10000a00000000000000cbed1200030000000000000054311300645d10000000000000000000745d10000100000000000000000000007c5d1000170000000000000057a912000c0000000000000054311300945d10000000000000000000a45d1000030000000000000000000000bc5d1000190000000000000057a912000c0000000000000054311300d85d10000000000000000000e85d1000040000000000000050726f78794465706f736974426173651200000000000000010000003a000000fa6010004400000054311300000000003e611000400000007e6110004900000050726f78794465706f736974466163746f7200001200000000000000010000003b000000e95f10002f0000005431130000000000186010005a0000007260100058000000ca601000300000004d617850726f7869657300001200000000000000010000003c000000ad5f10003c0000004d617850656e64696e6700001200000000000000010000003d0000005c5f100051000000416e6e6f756e63656d656e744465706f73697442617365001200000000000000010000003a000000b65e10004c0000005431130000000000025f10005a000000416e6e6f756e63656d656e744465706f736974466163746f720000001200000000000000010000003e000000085e10003500000054311300000000003d5e100056000000935e1000230000002054686520616d6f756e74206f662063757272656e6379206e65656465642070657220616e6e6f756e63656d656e74206d6164652e20546869732069732068656c6420666f7220616464696e6720616e20604163636f756e744964602c2060486173686020616e642060426c6f636b4e756d6265726020287479706963616c6c792036382062797465732920696e746f2061207072652d6578697374696e672073746f726167652076616c75652e20546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e6720616e20616e6e6f756e63656d656e742e20546869732069732068656c64207768656e2061206e65772073746f72616765206974656d20686f6c64696e672061206042616c616e636560206973206372656174656420287479706963616c6c79203136206279746573292e20546865206d6178696d756d20616d6f756e74206f662074696d652d64656c6179656420616e6e6f756e63656d656e747320746861742061726520616c6c6f77656420746f2062652070656e64696e672e20546865206d6178696d756d20616d6f756e74206f662070726f7869657320616c6c6f77656420666f7220612073696e676c65206163636f756e742e2054686520616d6f756e74206f662063757272656e6379206e6565646564207065722070726f78792061646465642e20546869732069732068656c6420666f7220616464696e6720333220627974657320706c757320616e20696e7374616e6365206f66206050726f78795479706560206d6f726520696e746f2061207072652d6578697374696e672073746f726167652076616c75652e20546875732c207768656e20636f6e6669677572696e67206050726f78794465706f736974466163746f7260206f6e652073686f756c642074616b6520696e746f206163636f756e7420603332202b2070726f78795f747970652e656e636f646528292e6c656e282960206279746573206f6620646174612e20546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e6720612070726f78792e20546869732069732068656c6420666f7220616e206164646974696f6e616c2073746f72616765206974656d2077686f73652076616c75652073697a65206973206073697a656f662842616c616e6365296020627974657320616e642077686f7365206b65792073697a65206973206073697a656f66284163636f756e74496429602062797465732e4e6f4b6579734475706c6963617465644b65794e6f4173736f63696174656456616c696461746f724964496e76616c696450726f6f664e6f4163636f756e7400000000000060621000080000000000000068621000020000000000000000000000986210000e0000000000000000000000086310000a0000000000000054311300000000000000000000000000146310000c000000000000007365745f6b657973000000007aee1200040000000000000042661000070000000000000049661000050000000000000042ec120007000000186510003a0000005265100048000000a7631000310000005431130000000000d8631000350000005431130000000000f2eb12000b000000c9e91100150000003a641000560000009a6510003c000000d665100029000000ff65100021000000206610002200000036ec12000c00000070757267655f6b65797300007463100033000000a7631000310000005431130000000000d8631000350000005431130000000000f2eb12000b0000000d6410002d0000003a64100056000000906410003c000000cc64100029000000f56410002300000036ec12000c0000002052656d6f76657320616e792073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c65722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d20436f6d706c65786974793a20604f2831296020696e206e756d626572206f66206b65792074797065732e20202041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f662060543a3a4b6579733a3a6b65795f6964732829602077686963682069732066697865642e202d20446252656164733a2060543a3a56616c696461746f7249644f66602c20604e6578744b657973602c20606f726967696e206163636f756e7460202d2044625772697465733a20604e6578744b657973602c20606f726967696e206163636f756e7460202d20446257726974657320706572206b65792069643a20604b65794f776e646572602053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b657973602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e202d20446252656164733a20606f726967696e206163636f756e74602c2060543a3a56616c696461746f7249644f66602c20604e6578744b65797360202d2044625772697465733a20606f726967696e206163636f756e74602c20604e6578744b65797360202d204462526561647320706572206b65792069643a20604b65794f776e657260202d20446257726974657320706572206b65792069643a20604b65794f776e657260543a3a4b65797370726f6f66000000000000f04e11000a0000000000000000000000b8681000130000000000000000000000000000000000000000000000000000000000000054311300cc6810000000000000000000dc68100001000000000000000100000000000000e46810000c0000000000000000000000a03712000c0000000000000000000000000000000000000000000000000000000000000054311300f068100000000000000000000069100001000000000000000100000000000000086910000d0000000000000000000000a1fb12000400000000000000000000000000000000000000000000000000000000000000543113001869100000000000000000002869100002000000000000000100000000000000df3c10000a0000000000000000000000386910001e0000000000000000000000000000000000000000000000000000000000000054311300586910000000000000000000686910000200000000000000010000000000000078691000120000000000000000000000e47311000800000000000000000000000000000000000000000000000000000000000000543113008c69100000000000000000009c69100003000000000000000100000000000000b4691000080000000105000000000000bc6910000e0000000000000042661000070000000000000000000000000000000000000054311300cc6910000000000000000000dc69100001000000000000000000000000000000e4691000080000000105000000000000ec6910001400000000000000bc6910000e0000000000000000000000000000000000000054311300006a10000000000000000000106a10000100000000000000000000005665633c543a3a56616c696461746f7249643e001200000000000000010000003f0000000a6c10001f00000043757272656e74496e64657812000000000000000100000022000000ec6b10001e0000005175657565644368616e67656400000012000000000000000100000023000000756b10004e000000c36b1000290000005665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e000012000000000000000100000040000000ee6a10004f0000003d6b10003800000044697361626c656456616c696461746f7273000012000000000000000100000024000000816a1000200000005431130000000000a16a10004d0000004e6578744b657973543a3a56616c696461746f7249640000120000000000000001000000230000005a6a1000270000004b65794f776e6572284b65795479706549642c205665633c75383e2912000000000000000100000023000000186a10004200000020546865206f776e6572206f662061206b65792e20546865206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e20496e6469636573206f662064697361626c65642076616c696461746f72732e205468652073657420697320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e732061206e657720736574206f66206964656e7469746965732e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f727320686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e0000000000000078a710000500000000000000086d1000020000000000000000000000386d10001800000000000000000000000c3a10000a00000000000000f86d1000040000000000000000000000586e10000f0000000000000000000000003a10000c00000000000000d06e1000030000000000000000000000186f10001a0000000000000000000000fa3910000600000000000000e86f100001000000000000000000000000701000110000000000000000000000f03910000a0000000000000088701000030000000000000000000000543113000000000000000000000000005b0c12000400000000000000e3f812000c00000000000000b07510001200000000000000c27510000e000000477710002300000054311300000000006073100032000000543113000000000088711000150000006a77100042000000dd731000200000005431130000000000fd7310001b000000ac771000260000005431130000000000d27710002a0000005431130000000000355f12000c000000cd7410003700000004751000440000004875100028000000543113000000000080721000090000008972100040000000fc77100039000000543113000000000006731000170000008d8511000a00000000000000791b13000300000000000000d37010000f0000000000000048b61200050000000000000057a912000c00000000000000ee7610001000000000000000fe76100034000000000000001d73100009000000000000003277100015000000d075100022000000543113000000000075fa1100320000005431130000000000355f12000c000000f27510003d0000002f761000340000006376100043000000543113000000000080721000090000008972100040000000a676100048000000543113000000000006731000170000008d8511000a000000000000005b0c12000400000000000000e3f812000c00000000000000b07510001200000000000000c27510000e000000000000001d731000090000000000000042ec120007000000267310003a0000005431130000000000607310003200000054311300000000008871100015000000927310004b000000dd731000200000005431130000000000fd7310001b0000001874100031000000543113000000000049741000530000009c741000310000005431130000000000355f12000c000000cd7410003700000004751000440000004875100028000000267210005a0000005431130000000000807210000900000089721000400000007075100040000000543113000000000006731000170000008d8511000a000000000000001d731000090000000000000042ec120007000000f07010003e00000054311300000000002e7110005a000000543113000000000088711000150000009d7110004b000000e87110003e0000005431130000000000355f12000c000000267210005a000000543113000000000080721000090000008972100040000000c97210003d000000543113000000000006731000170000008d8511000a00000000000000d07010000300000000000000d37010000f00000000000000871913000300000000000000d37010000f00000000000000e27010000e000000000000002c701200140000006f6c64457468657265756d416464726573736d617962655f707265636c61696d2041747465737420746f20612073746174656d656e742c206e656564656420746f2066696e616c697a652074686520636c61696d732070726f636573732e205741524e494e473a20496e73656375726520756e6c65737320796f757220636861696e20696e636c75646573206050726576616c69646174654174746573747360206173206120605369676e6564457874656e73696f6e602e20556e7369676e65642056616c69646174696f6e3a20412063616c6c20746f20617474657374206973206465656d65642076616c6964206966207468652073656e6465722068617320612060507265636c61696d60207265676973746572656420616e642070726f76696465732061206073746174656d656e746020776869636820697320657870656374656420666f7220746865206163636f756e742e202d206073746174656d656e74603a20546865206964656e74697479206f66207468652073746174656d656e74207768696368206973206265696e6720617474657374656420746f20696e20746865207369676e61747572652e203c7765696768743e2054686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732e2057656967687420696e636c75646573206c6f67696320746f20646f207072652d76616c69646174696f6e206f6e2060617474657374602063616c6c2e20546f74616c20436f6d706c65786974793a204f28312973746174656d656e74204d616b65206120636c61696d20746f20636f6c6c65637420796f757220444f5473206279207369676e696e6720612073746174656d656e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e20412063616c6c20746f2060636c61696d5f61747465737460206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d61746368657320746865206578706563746564207369676e6564206d657373616765206f663a203e20457468657265756d205369676e6564204d6573736167653a203e2028636f6e666967757265642070726566697820737472696e67292861646472657373292873746174656d656e742920616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e743b20746865206073746174656d656e7460206d757374206d617463682074686174207768696368206973206578706563746564206163636f7264696e6720746f20796f757220707572636861736520617272616e67656d656e742e202d206064657374603a205468652064657374696e6174696f6e206163636f756e7420746f207061796f75742074686520636c61696d2e202d2060657468657265756d5f7369676e6174757265603a20546865207369676e6174757265206f6620616e20657468657265756d207369676e6564206d657373616765202020206d61746368696e672074686520666f726d6174206465736372696265642061626f76652e2057656967687420696e636c75646573206c6f67696320746f2076616c696461746520756e7369676e65642060636c61696d5f617474657374602063616c6c2e657468657265756d5f7369676e617475726545636473615369676e6174757265204d696e742061206e657720636c61696d20746f20636f6c6c65637420444f54732e202d206077686f603a2054686520457468657265756d206164647265737320616c6c6f77656420746f20636f6c6c656374207468697320636c61696d2e202d206076616c7565603a20546865206e756d626572206f6620444f547320746861742077696c6c20626520636c61696d65642e202d206076657374696e675f7363686564756c65603a20416e206f7074696f6e616c2076657374696e67207363686564756c6520666f7220746865736520444f54732e20576520617373756d6520776f7273742063617365207468617420626f74682076657374696e6720616e642073746174656d656e74206973206265696e6720696e7365727465642e76657374696e675f7363686564756c654f7074696f6e3c2842616c616e63654f663c543e2c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d626572293e4f7074696f6e3c53746174656d656e744b696e643e204d616b65206120636c61696d20746f20636f6c6c65637420796f757220444f54732e20412063616c6c20746f20636c61696d206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d617463686573203e2028636f6e666967757265642070726566697820737472696e672928616464726573732920616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e742e2057656967687420696e636c75646573206c6f67696320746f2076616c696461746520756e7369676e65642060636c61696d602063616c6c2e00000000000000b6281300060000000106000000000000d37010000f0000000000000057a912000c0000000000000000000000000000000000000054311300f079100000000000000000005431130000000000000000000000000000000000e93c100005000000000000000000000057a912000c0000000000000000000000000000000000000000000000000000000000000054311300007a100000000000000000005431130000000000000000000100000000000000bc2d1200070000000106000000000000d37010000f00000000000000107a10002c00000000000000000000000000000000000000543113003c7a100000000000000000004c7a100004000000000000000000000000000000bc281300070000000106000000000000d37010000f000000000000006c7a10000d00000000000000000000000000000000000000543113007c7a100000000000000000008c7a100001000000000000000000000000000000d63c1000090000000106000000000000e3f812000c00000000000000d37010000f0000000000000000000000000000000000000054311300947a10000000000000000000a47a100001000000000000000000000012000000000000000100000023000000120000000000000001000000410000002842616c616e63654f663c543e2c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265722912000000000000000100000023000000277b10001e000000457b100043000000887b100039000000c17b10003300000053746174656d656e744b696e6400000012000000000000000100000023000000f77a10003000000012000000000000000100000023000000ac7a10004b000000205072652d636c61696d656420457468657265756d206163636f756e74732c20627920746865204163636f756e74204944207468617420746865792061726520636c61696d656420746f2e205468652073746174656d656e74206b696e642074686174206d757374206265207369676e65642c20696620616e792e2056657374696e67207363686564756c6520666f72206120636c61696d2e2046697273742062616c616e63652069732074686520746f74616c20616d6f756e7420746861742073686f756c642062652068656c6420666f722076657374696e672e205365636f6e642062616c616e636520697320686f77206d7563682073686f756c6420626520756e6c6f636b65642070657220626c6f636b2e2054686520626c6f636b206e756d626572206973207768656e207468652076657374696e672073686f756c642073746172742e000000002c7c10000600000000000000327c1000050000000000000054311300387c10000000000000000000487c10000100000000000000507265666978265b75385d0012000000000000000100000042000000507c10004500000020546865205072656669782074686174206973207573656420696e207369676e656420457468657265756d206d6573736167657320666f722074686973206e6574776f726b00000000000000c47c10000700000000000000cc7c1000030000000000000000000000e47c10000100000000000000436c61696d65640079e5120009000000d37010000f000000d5d1120007000000ec7c10003b00000020536f6d656f6e6520636c61696d656420736f6d6520444f54732e205b77686f2c20657468657265756d5f616464726573732c20616d6f756e745d496e76616c696452656e6f756e63696e67496e76616c6964566f7465436f756e74496e76616c69645769746e65737344617461496e73756666696369656e7443616e64696461746546756e647352756e6e657255705375626d69744d656d6265725375626d69744475706c69636174656443616e6469646174655265706f727453656c664d7573744265566f746572556e61626c65546f506179426f6e644c6f7742616c616e63654d6178696d756d566f7465734578636565646564546f6f4d616e79566f7465734e6f566f746573556e61626c65546f566f7465496e76616c69645265706c6163656d656e7400000000d488120004000000000000001c7f10000200000000000000000000004c7f1000170000000000000000000000048010000c00000000000000543113000000000000000000000000001080100005000000000000000000000038801000100000000000000048801000010000000000000000000000608010000f0000000000000000000000d88010001200000000000000ec80100001000000000000000000000004811000110000000000000000000000e41613000d000000000000008c811000020000000000000000000000bc8110000e00000000000000000000002c821000140000000000000040821000020000000000000000000000708210000a0000000000000000000000398f100005000000000000002c1a1300110000000000000048b6120005000000000000004db6120015000000128c100057000000698c1000390000005431130000000000a28c100058000000fa8c10005400000054311300000000004e8d100014000000628d100012000000748d100056000000ca8d10004500000054311300000000000f8e1000540000005431130000000000498a10003100000054311300000000007a8a10000c0000005431130000000000638e100056000000b98e10002b0000005431130000000000f2eb12000b000000e48e10005500000036ec12000c00000072656d6f76655f766f746572878b10001c0000005431130000000000a38b10002f0000005431130000000000d28b1000400000007375626d69745f63616e64696461637900000000788b10000f00000000000000d2a012000c00000078891000450000005431130000000000bd89100058000000158a1000340000005431130000000000498a10003100000054311300000000007a8a10000c0000005431130000000000868a100058000000de8a1000570000005431130000000000f2eb12000b000000358b10004300000036ec12000c00000072656e6f756e63655f63616e646964616379000000000000648910000a000000000000006e8910000a0000001486100054000000688610001000000054311300000000007886100053000000cb8610003d000000088710005900000061871000240000008587100056000000db87100056000000318810005b0000008c8810004d0000005431130000000000d9881000520000005431130000000000f2eb12000b0000002b8910003900000036ec12000c00000000000000791b1300030000000000000085fc11002300000000000000058610000f00000000000000a1fb1200040000001d84100057000000748410002000000054311300000000009484100056000000ea8410004000000054311300000000007f8310002f00000054311300000000002a851000510000005431130000000000f2eb12000b0000007b85100055000000d08510003500000036ec12000c000000636c65616e5f646566756e63745f766f7465727300000000068410000b00000000000000cbed12000300000000000000118410000c00000000000000cbed120003000000c082100052000000128310002c00000054311300000000003e8310004100000054311300000000007f8310002f0000005431130000000000f2eb12000b000000ae8310005800000036ec12000c00000020436c65616e20616c6c20766f746572732077686f2061726520646566756e63742028692e652e207468657920646f206e6f7420736572766520616e7920707572706f736520617420616c6c292e20546865206465706f736974206f66207468652072656d6f76656420766f74657273206172652072657475726e65642e205468697320697320616e20726f6f742066756e6374696f6e20746f2062652075736564206f6e6c7920666f7220636c65616e696e67207468652073746174652e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520726f6f742e2054686520746f74616c206e756d626572206f6620766f7465727320616e642074686f736520746861742061726520646566756e6374206d7573742062652070726f7669646564206173207769746e65737320646174612e5f6e756d5f766f746572735f6e756d5f646566756e63742052656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c7920616e642074686520626f6e64206f6620746865206f7574676f696e67206d656d62657220697320736c61736865642e20496620612072756e6e65722d757020697320617661696c61626c652c207468656e2074686520626573742072756e6e65722d75702077696c6c2062652072656d6f76656420616e64207265706c6163657320746865206f7574676f696e67206d656d6265722e204f74686572776973652c2061206e65772070687261676d656e20656c656374696f6e20697320737461727465642e204e6f74652074686174207468697320646f6573206e6f7420616666656374207468652064657369676e6174656420626c6f636b206e756d626572206f6620746865206e65787420656c656374696f6e2e20496620776520686176652061207265706c6163656d656e742c20776520757365206120736d616c6c207765696768742e20456c73652c2073696e63652074686973206973206120726f6f742063616c6c20616e642077696c6c20676f20696e746f2070687261676d656e2c20776520617373756d652066756c6c20626c6f636b20666f72206e6f772e6861735f7265706c6163656d656e742052656e6f756e6365206f6e65277320696e74656e74696f6e20746f20626520612063616e64696461746520666f7220746865206e65787420656c656374696f6e20726f756e642e203320706f74656e7469616c206f7574636f6d65732065786973743a202d20606f726967696e6020697320612063616e64696461746520616e64206e6f7420656c656374656420696e20616e79207365742e20496e207468697320636173652c20746865206465706f736974206973202020756e72657365727665642c2072657475726e656420616e64206f726967696e2069732072656d6f76656420617320612063616e6469646174652e202d20606f726967696e6020697320612063757272656e742072756e6e65722d75702e20496e207468697320636173652c20746865206465706f73697420697320756e72657365727665642c2072657475726e656420616e642020206f726967696e2069732072656d6f76656420617320612072756e6e65722d75702e202d20606f726967696e6020697320612063757272656e74206d656d6265722e20496e207468697320636173652c20746865206465706f73697420697320756e726573657276656420616e64206f726967696e20697320202072656d6f7665642061732061206d656d6265722c20636f6e73657175656e746c79206e6f74206265696e6720612063616e64696461746520666f7220746865206e65787420726f756e6420616e796d6f72652e20202053696d696c617220746f205b6072656d6f76655f6d656d62657273605d2c206966207265706c6163656d656e742072756e6e657273206578697374732c20746865792061726520696d6d6564696174656c7920757365642e202020496620746865207072696d652069732072656e6f756e63696e672c207468656e206e6f207072696d652077696c6c20657869737420756e74696c20746865206e65787420726f756e642e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642c20616e642068617665206f6e65206f66207468652061626f766520726f6c65732e205468652074797065206f662072656e6f756e63696e67206d7573742062652070726f7669646564206173207769746e65737320646174612e72656e6f756e63696e6752656e6f756e63696e67205375626d6974206f6e6573656c6620666f722063616e6469646163792e204120666978656420616d6f756e74206f66206465706f736974206973207265636f726465642e20416c6c2063616e64696461746573206172652077697065642061742074686520656e64206f6620746865207465726d2e205468657920656974686572206265636f6d652061206d656d6265722f72756e6e65722d75702c206f72206c65617665207468652073797374656d207768696c65207468656972206465706f73697420697320736c61736865642e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642e20232323205761726e696e67204576656e20696620612063616e64696461746520656e6473207570206265696e672061206d656d6265722c2074686579206d7573742063616c6c205b6043616c6c3a3a72656e6f756e63655f63616e646964616379605d20746f20676574207468656972206465706f736974206261636b2e204c6f73696e67207468652073706f7420696e20616e20656c656374696f6e2077696c6c20616c77617973206c65616420746f206120736c6173682e20546865206e756d626572206f662063757272656e742063616e64696461746573206d7573742062652070726f7669646564206173207769746e65737320646174612e63616e6469646174655f636f756e742052656d6f766520606f726967696e60206173206120766f7465722e20546869732072656d6f76657320746865206c6f636b20616e642072657475726e7320746865206465706f7369742e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e656420616e64206265206120766f7465722e20566f746520666f72206120736574206f662063616e6469646174657320666f7220746865207570636f6d696e6720726f756e64206f6620656c656374696f6e2e20546869732063616e2062652063616c6c656420746f207365742074686520696e697469616c20766f7465732c206f722075706461746520616c7265616479206578697374696e6720766f7465732e2055706f6e20696e697469616c20766f74696e672c206076616c75656020756e697473206f66206077686f6027732062616c616e6365206973206c6f636b656420616e642061206465706f73697420616d6f756e742069732072657365727665642e20546865206465706f736974206973206261736564206f6e20746865206e756d626572206f6620766f74657320616e642063616e2062652075706461746564206f7665722074696d652e205468652060766f746573602073686f756c643a2020202d206e6f7420626520656d7074792e2020202d206265206c657373207468616e20746865206e756d626572206f6620706f737369626c652063616e646964617465732e204e6f7465207468617420616c6c2063757272656e74206d656d6265727320616e64202020202072756e6e6572732d75702061726520616c736f206175746f6d61746963616c6c792063616e6469646174657320666f7220746865206e65787420726f756e642e204966206076616c756560206973206d6f7265207468616e206077686f60277320746f74616c2062616c616e63652c207468656e20746865206d6178696d756d206f66207468652074776f20697320757365642e2049742069732074686520726573706f6e736962696c697479206f66207468652063616c6c657220746f202a2a4e4f542a2a20706c61636520616c6c206f662074686569722062616c616e636520696e746f20746865206c6f636b20616e64206b65657020736f6d6520666f722066757274686572206f7065726174696f6e732e20576520617373756d6520746865206d6178696d756d2077656967687420616d6f6e6720616c6c20332063617365733a20766f74655f657175616c2c20766f74655f6d6f726520616e6420766f74655f6c6573732e766f746573000000000000c7e11200070000000000000000000000f89010002b00000000000000000000000000000000000000000000000000000000000000543113002491100000000000000000003491100003000000000000000100000000000000a83c1000090000000000000000000000f89010002b00000000000000000000000000000000000000000000000000000000000000543113004c91100000000000000000005c911000040000000000000001000000000000009e3c10000a00000000000000000000007c911000210000000000000000000000000000000000000000000000000000000000000054311300a09110000000000000000000b091100006000000000000000100000000000000e09110000e0000000000000000000000cbed1200030000000000000000000000000000000000000000000000000000000000000054311300f091100000000000000000000092100001000000000000000100000000000000fb571200060000000105000000000000e3f812000c00000000000000089210002100000000000000000000000000000000000000543113002c92100000000000000000003c9210000300000000000000010000005665633c53656174486f6c6465723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3e0012000000000000000100000043000000809410001d0000005431130000000000ac9310002e00000012000000000000000100000043000000da931000210000005431130000000000fb93100056000000519410002f0000005665633c28543a3a4163636f756e7449642c2042616c616e63654f663c543e293e0000001200000000000000010000003f0000000393100056000000599310003400000054311300000000008d9310001f0000005431130000000000ac9310002e000000456c656374696f6e526f756e6473000012000000000000000100000022000000b392100050000000566f7465723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00000012000000000000000100000044000000549210002e0000005431130000000000829210003100000020566f74657320616e64206c6f636b6564207374616b65206f66206120706172746963756c617220766f7465722e2054574f582d4e4f54453a205341464520617320604163636f756e7449646020697320612063727970746f20686173682e2054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e65642c206578636c7564696e6720746865207570636f6d696e67206f6e652e205468652070726573656e742063616e646964617465206c6973742e20412063757272656e74206d656d626572206f722072756e6e65722d75702063616e206e6576657220656e746572207468697320766563746f7220616e6420697320616c7761797320696d706c696369746c7920617373756d656420746f20626520612063616e6469646174652e205365636f6e6420656c656d656e7420697320746865206465706f7369742e20496e76617269616e743a20416c7761797320736f72746564206261736564206f6e206163636f756e742069642e205468652063757272656e742072657365727665642072756e6e6572732d75702e20496e76617269616e743a20416c7761797320736f72746564206261736564206f6e2072616e6b2028776f72736520746f2062657374292e2055706f6e2072656d6f76616c206f662061206d656d6265722c20746865206c6173742028692e652e205f626573745f292072756e6e65722d75702077696c6c206265207265706c616365642e205468652063757272656e7420656c6563746564206d656d626572732e00000000000000289610000d0000000000000057a912000c000000000000005431130038961000000000000000000054311300000000000000000000000000489610000e0000000000000057a912000c00000000000000543113005896100000000000000000005431130000000000000000000000000068961000100000000000000057a912000c000000000000005431130078961000000000000000000054311300000000000000000000000000889610000e00000000000000cbed120003000000000000005431130098961000000000000000000054311300000000000000000000000000a89610001000000000000000cbed1200030000000000000054311300b8961000000000000000000054311300000000000000000000000000c89610000c00000000000000a9f912000e0000000000000054311300d4961000000000000000000054311300000000000000000000000000a00811000800000000000000e49610000e0000000000000054311300f4961000000000000000000054311300000000000000000043616e646964616379426f6e6400000012000000000000000100000045000000566f74696e67426f6e6442617365000012000000000000000100000046000000566f74696e67426f6e64466163746f7212000000000000000100000047000000446573697265644d656d626572730000120000000000000001000000480000004465736972656452756e6e6572735570120000000000000001000000490000005465726d4475726174696f6e1200000000000000010000004a0000004c6f636b4964656e74696669657200001200000000000000010000004b0000000000000038981000070000000000000040981000010000000000000000000000489810000400000000000000000000006898100009000000000000005431130000000000000000000000000074981000020000000000000000000000849810000d0000000000000054311300000000000000000000000000949810000100000000000000000000009c9810000c00000000000000fce41200010000000000000000000000a8981000020000000000000000000000b89810000900000000000000fce41200010000000000000000000000c4981000010000000000000000000000cc9810001000000000000000c0f51100020000000000000000000000dc981000040000000000000000000000fc9810001100000000000000c0f511000200000000000000000000001099100001000000000000004e65775465726d00ad9c1000190000004d9b10005a000000a79b100056000000fd9b10005a000000579c100056000000456d7074795465726d000000cd9a10004d0000001a9b100033000000456c656374696f6e4572726f72000000939a10003a0000004d656d6265724b69636b6564319a100055000000869a10000d00000052656e6f756e6365640000000a9a10002700000043616e646964617465536c61736865646e99100057000000c59910000b0000005431130000000000d09910003a00000053656174486f6c646572536c617368656400000018991000560000002041205c5b7365617420686f6c6465725c5d2077617320736c6173686564206279205c5b616d6f756e745c5d206279206265696e6720666f72636566756c6c792072656d6f7665642066726f6d20746865207365742e2041205c5b63616e6469646174655c5d2077617320736c6173686564206279205c5b616d6f756e745c5d2064756520746f206661696c696e6720746f206f627461696e20612073656174206173206d656d626572206f722072756e6e65722d75702e204e6f74652074686174206f6c64206d656d6265727320616e642072756e6e6572732d75702061726520616c736f2063616e646964617465732e20536f6d656f6e65206861732072656e6f756e6365642074686569722063616e6469646163792e2041205c5b6d656d6265725c5d20686173206265656e2072656d6f7665642e20546869732073686f756c6420616c7761797320626520666f6c6c6f7765642062792065697468657220604e65775465726d60206f722060456d7074795465726d602e20496e7465726e616c206572726f722068617070656e6564207768696c6520747279696e6720746f20706572666f726d20656c656374696f6e2e204e6f20286f72206e6f7420656e6f756768292063616e64696461746573206578697374656420666f72207468697320726f756e642e205468697320697320646966666572656e742066726f6d20604e65775465726d285c5b5c5d29602e2053656520746865206465736372697074696f6e206f6620604e65775465726d602e2041206e6577207465726d2077697468205c5b6e65775f6d656d626572735c5d2e205468697320696e64696361746573207468617420656e6f7567682063616e64696461746573206578697374656420746f2072756e2074686520656c656374696f6e2c206e6f74207468617420656e6f756768206861766520686173206265656e20656c65637465642e2054686520696e6e65722076616c7565206d757374206265206578616d696e656420666f72207468697320707572706f73652e204120604e65775465726d285c5b5c5d296020696e64696361746573207468617420736f6d652063616e6469646174657320676f7420746865697220626f6e6420736c617368656420616e64206e6f6e65207765726520656c65637465642c207768696c73742060456d7074795465726d60206d65616e732074686174206e6f2063616e64696461746573206578697374656420746f20626567696e20776974682e5665633c284163636f756e7449642c2042616c616e6365293e000000000000f16110000c00000000000000549d1000010000000000000000000000da61100017000000000000005c9d1000010000000000000000000000cd6110000d00000000000000649d1000010000000000000000000000c761100006000000000000006c9d1000010000000000000000000000fd6110000900000000000000749d100001000000000000002f9e100019000000079e100028000000ed9d10001a000000c39d10002a0000007c9d100047000000204b65792073657474696e67206163636f756e74206973206e6f74206c6976652c20736f206974277320696d706f737369626c6520746f206173736f6369617465206b6579732e204e6f206b65797320617265206173736f63696174656420776974682074686973206163636f756e742e2052656769737465726564206475706c6963617465206b65792e204e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e20496e76616c6964206f776e6572736869702070726f6f662e000000006f3d10000700000000000000289f10000100000000000000000000008b3311000800000000000000309f1000010000000000000000000000673d10000800000000000000389f10000100000000000000000000005c3d10000b00000000000000409f1000010000000000000000000000533d10000900000000000000489f1000010000000000000000000000428212000c00000000000000509f1000010000000000000000000000483d10000b00000000000000589f1000010000000000000000000000763d10000b00000000000000609f10000100000000000000b4a010004900000096a010001e00000062a010003400000019a0100049000000fd9f10001c000000b79f100046000000829f100035000000689f10001a0000002043616e6e6f74206164642073656c662061732070726f78792e20416e6e6f756e63656d656e742c206966206d61646520617420616c6c2c20776173206d61646520746f6f20726563656e746c792e2043616c6c206d6179206e6f74206265206d6164652062792070726f78792062656361757365206974206d617920657363616c617465206974732070726976696c656765732e204163636f756e7420697320616c726561647920612070726f78792e20412063616c6c20776869636820697320696e636f6d70617469626c652077697468207468652070726f7879207479706527732066696c7465722077617320617474656d707465642e2053656e646572206973206e6f7420612070726f7879206f6620746865206163636f756e7420746f2062652070726f786965642e2050726f787920726567697374726174696f6e206e6f7420666f756e642e2054686572652061726520746f6f206d616e792070726f786965732072656769737465726564206f7220746f6f206d616e7920616e6e6f756e63656d656e74732070656e64696e672e00000000000000f67d10000c00000000000000dca21000010000000000000000000000ef7d10000700000000000000e4a21000010000000000000000000000e37d10000c00000000000000eca21000010000000000000000000000cf7d10001400000000000000f4a21000010000000000000000000000c57d10000a00000000000000fca21000010000000000000000000000b67d10000f0000000000000004a31000010000000000000000000000ab7d10000b000000000000000ca31000010000000000000000000000a17d10000a0000000000000014a310000100000000000000000000008e7d100013000000000000001ca31000010000000000000000000000827d10000c0000000000000024a31000010000000000000000000000747d10000e000000000000002ca310000100000000000000000000005a7d10001a0000000000000034a31000010000000000000000000000e0e1120009000000000000003ca31000010000000000000000000000487d1000120000000000000044a31000010000000000000000000000387d100010000000000000004ca31000010000000000000000000000277d1000110000000000000054a31000010000000000000000000000027e100012000000000000005ca310000100000000000000d1a5100031000000aba510002600000089a510002200000062a510002700000030a510003200000011a510001f00000000a5100011000000eca4100014000000cba4100021000000a8a410002300000085a41000230000005fa410002600000051a410000e00000018a4100039000000e4a3100034000000a4a310004000000064a31000400000002050726564696374696f6e20726567617264696e67207265706c6163656d656e74206166746572206d656d6265722072656d6f76616c2069732077726f6e672e205468652072656e6f756e63696e67206f726967696e2070726573656e74656420612077726f6e67206052656e6f756e63696e676020706172616d657465722e205468652070726f766964656420636f756e74206f66206e756d626572206f6620766f74657320697320696e636f72726563742e205468652070726f766964656420636f756e74206f66206e756d626572206f662063616e6469646174657320697320696e636f72726563742e204e6f742061206d656d6265722e2043616e64696461746520646f6573206e6f74206861766520656e6f7567682066756e64732e2052756e6e65722063616e6e6f742072652d7375626d69742063616e6469646163792e204d656d6265722063616e6e6f742072652d7375626d69742063616e6469646163792e204475706c6963617465642063616e646964617465207375626d697373696f6e2e2043616e6e6f74207265706f72742073656c662e204d757374206265206120766f7465722e20566f7465722063616e206e6f742070617920766f74696e6720626f6e642e2043616e6e6f7420766f74652077697468207374616b65206c657373207468616e206d696e696d756d2062616c616e63652e2043616e6e6f7420766f7465206d6f7265207468616e206d6178696d756d20616c6c6f7765642e2043616e6e6f7420766f7465206d6f7265207468616e2063616e646964617465732e204d75737420766f746520666f72206174206c65617374206f6e652063616e6469646174652e2043616e6e6f7420766f7465207768656e206e6f2063616e64696461746573206f72206d656d626572732065786973742e0000e613130056000000e900000001000000417070726f76616c73496e636f6e73697374656e74207374617465202d20636f756c646e277420736574746c6520696d62616c616e636520666f722066756e6473207370656e7420627920747265617375727953757065724f664e6f745472616e73666572496e5573654e6f744f776e65724e6f7441737369676e65645065726d616e656e7400000000000078a71000050000000000000080a7100001000000000000000000000098a7100012000000000000000000000038071200080000000000000028a8100002000000000000000000000058a81000140000000000000000000000f8a81000040000000000000080a71000010000000000000000000000fca810001200000000000000000000002c0912000e000000000000008ca91000030000000000000000000000d4a910001500000000000000000000007caa1000060000000000000080a7100001000000000000000000000084aa10001100000000000000636c61696d00000000000000a00e13000500000000000000d7ae10000f00000097b11000270000005431130000000000beb110003800000054311300000000006c0e1300340000005431130000000000f6b110003d000000543113000000000016ae1000250000005431130000000000f2eb12000b000000bcfb11000a00000028ac10002700000020b01000190000006cac10000d00000079ac1000140000008dac10002500000036ec12000c00000000000000871913000300000000000000e3f812000c00000000000000a00e13000500000000000000d7ae10000f00000039b010005800000091b010002f00000054311300000000006c0e1300340000005431130000000000c0b010004a0000006dad100058000000543113000000000016ae1000250000005431130000000000f2eb12000b000000bcfb11000a00000028ac1000270000000ab110001a0000006cac10000d00000079ac100014000000c0ef12000d00000024b11000390000005db110003a00000036ec12000c00000066726565e6ae10002600000054311300000000000caf100058000000543113000000000064af1000560000005431130000000000baaf1000440000005431130000000000feaf1000220000005431130000000000f2eb12000b000000bcfb11000a00000028ac10002700000020b01000190000006cac10000d00000079ac1000140000008dac10002500000036ec12000c00000000000000871913000300000000000000e3f812000c00000000000000a00e13000500000000000000d7ae10000f000000000000007caa10000600000000000000a1fb120004000000b2ac10005600000008ad10003b000000543113000000000075fa110032000000543113000000000043ad10002a0000006dad100058000000c5ad100051000000543113000000000016ae1000250000005431130000000000f2eb12000b000000bcfb11000a00000028ac1000270000003bae10001f0000006cac10000d00000079ac100014000000c0ef12000d0000005aae10003e00000098ae10003f00000036ec12000c000000667265657a6500000cab10005a000000543113000000000066ab100057000000bdab10001c0000005431130000000000d9ab10002c000000543113000000000005ac1000230000005431130000000000f2eb12000b000000bcfb11000a00000028ac1000270000004fac10001d0000006cac10000d00000079ac1000140000008dac10002500000036ec12000c00000020467265657a6520616e20696e64657820736f2069742077696c6c20616c7761797320706f696e7420746f207468652073656e646572206163636f756e742e205468697320636f6e73756d657320746865206465706f7369742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d75737420686176652061206e6f6e2d66726f7a656e206163636f756e742060696e646578602e202d2060696e646578603a2074686520696e64657820746f2062652066726f7a656e20696e20706c6163652e20456d6974732060496e64657846726f7a656e60206966207375636365737366756c2e202d204f6e652073746f72616765206d75746174696f6e2028636f64656320604f28312960292e202d20557020746f206f6e6520736c617368206f7065726174696f6e2e202d204f6e65206576656e742e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d204442205765696768743a203120526561642f577269746520284163636f756e74732920466f72636520616e20696e64657820746f20616e206163636f756e742e205468697320646f65736e277420726571756972652061206465706f7369742e2049662074686520696e64657820697320616c72656164792068656c642c207468656e20616e79206465706f736974206973207265696d62757273656420746f206974732063757272656e74206f776e65722e202d2060696e646578603a2074686520696e64657820746f206265202872652d2961737369676e65642e202d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e202d2060667265657a65603a2069662073657420746f206074727565602c2077696c6c20667265657a652074686520696e64657820736f2069742063616e6e6f74206265207472616e736665727265642e20456d6974732060496e64657841737369676e656460206966207375636365737366756c2e202d20557020746f206f6e652072657365727665206f7065726174696f6e2e202020202d2052656164733a20496e6469636573204163636f756e74732c2053797374656d204163636f756e7420286f726967696e616c206f776e657229202020202d205772697465733a20496e6469636573204163636f756e74732c2053797374656d204163636f756e7420286f726967696e616c206f776e657229543a3a4163636f756e74496e646578204672656520757020616e20696e646578206f776e6564206279207468652073656e6465722e205061796d656e743a20416e792070726576696f7573206465706f73697420706c6163656420666f722074686520696e64657820697320756e726573657276656420696e207468652073656e646572206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206f776e2074686520696e6465782e202d2060696e646578603a2074686520696e64657820746f2062652066726565642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e20456d6974732060496e646578467265656460206966207375636365737366756c2e202d204f6e652072657365727665206f7065726174696f6e2e2041737369676e20616e20696e64657820616c7265616479206f776e6564206279207468652073656e64657220746f20616e6f74686572206163636f756e742e205468652062616c616e6365207265736572766174696f6e206973206566666563746976656c79207472616e7366657272656420746f20746865206e6577206163636f756e742e202d2060696e646578603a2074686520696e64657820746f2062652072652d61737369676e65642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e202d204f6e65207472616e73666572206f7065726174696f6e2e202020202d2052656164733a20496e6469636573204163636f756e74732c2053797374656d204163636f756e742028726563697069656e7429202020202d205772697465733a20496e6469636573204163636f756e74732c2053797374656d204163636f756e742028726563697069656e74292041737369676e20616e2070726576696f75736c7920756e61737369676e656420696e6465782e205061796d656e743a20604465706f736974602069732072657365727665642066726f6d207468652073656e646572206163636f756e742e202d2060696e646578603a2074686520696e64657820746f20626520636c61696d65642e2054686973206d757374206e6f7420626520696e207573652e00000000008cb21000080000000102000000000000d7ae10000f0000000000000094b21000220000000000000000000000000000000000000054311300b8b210000000000000000000c8b210000100000000000000000000004163636f756e747328543a3a4163636f756e7449642c2042616c616e63654f663c543e2c20626f6f6c29000012000000000000000100000023000000d0b210002200000020546865206c6f6f6b75702066726f6d20696e64657820746f206163636f756e742e00000000000048031200070000000000000057a912000c00000000000000543113002cb3100000000000000000003cb3100001000000000000001200000000000000010000002a00000044b310002b00000020546865206465706f736974206e656564656420666f7220726573657276696e6720616e20696e6465782e0000000000f4b310000d0000000000000004b4100002000000000000000000000014b410000100000000000000000000001cb410000a0000000000000028b4100001000000000000000000000030b4100001000000000000000000000038b410000b0000000000000044b4100002000000000000000000000054b410000100000000000000496e64657841737369676e656400000079e5120009000000a6b410000c000000ecb410002d000000496e64657846726565640000a6b410000c000000b2b410003a000000496e64657846726f7a656e00a6b410000c00000079e51200090000005cb410004a0000002041206163636f756e7420696e64657820686173206265656e2066726f7a656e20746f206974732063757272656e74206163636f756e742049442e205c5b696e6465782c2077686f5c5d4163636f756e74496e6465782041206163636f756e7420696e64657820686173206265656e2066726565642075702028756e61737369676e6564292e205c5b696e6465785c5d2041206163636f756e7420696e646578207761732061737369676e65642e205c5b696e6465782c2077686f5c5d4e6f74537562546f6f4d616e7952656769737472617273546f6f4d616e794669656c6473496e76616c6964546172676574496e76616c6964496e646578496e76616c69644a756467656d656e744a756467656d656e74476976656e537469636b794a756467656d656e744e6f4964656e746974794665654368616e676564456d707479496e6465784e6f744e616d6564546f6f4d616e795375624163636f756e74734e6f744f776e6564000000000058b810000d0000000000000068b8100001000000000000000000000080b810000d0000000000000000000000e8b810000c00000000000000f4b810000100000000000000000000000cb91000130000000000000000000000a4b910000800000000000000acb91000010000000000000000000000c4b910001500000000000000000000006cba10000e00000000000000543113000000000000000000000000007cba10001200000000000000000000000cbb1000110000000000000020bb100002000000000000000000000050bb100017000000000000000000000008bc10000e0000000000000018bc100001000000000000000000000030bc1000110000000000000000000000b8bc10000700000000000000c0bc1000020000000000000000000000f0bc10000d000000000000000000000058bd10000e0000000000000068bd100002000000000000000000000098bd10000d000000000000000000000000be10000a000000000000000cbe10000200000000000000000000003cbe10000d0000000000000000000000a4be10001100000000000000b8be100003000000000000000000000000bf100013000000000000000000000098bf10000d0000000000000024f81100010000000000000000000000a8bf100013000000000000000000000040c01000070000000000000048c0100002000000000000000000000078c01000070000000000000000000000b0c010000a0000000000000048c01000020000000000000000000000bcc01000040000000000000000000000dcc010000a00000000000000e8c0100001000000000000000000000000c1100007000000000000000000000038c1100008000000000000005431130000000000000000000000000040c110000a000000000000006164645f7265676973747261720000000000000069d510000700000000000000e3f812000c00000048d410001f000000543113000000000067d41000400000005431130000000000a7d410002b0000005431130000000000d2d41000260000005431130000000000f2eb12000b000000f8d410004a00000042d51000270000006cac10000d00000036ec12000c0000007365745f6964656e746974790000000038d4100004000000000000003cd410000c0000003ed210004b000000543113000000000089d2100056000000dfd210001500000054311300000000006c0e1300340000005431130000000000f4d2100024000000543113000000000018d31000230000005431130000000000f2eb12000b0000003bd31000120000004dd310004800000095d3100039000000ced3100021000000efd31000490000006cac10000d00000036ec12000c0000007365745f737562730000000021d21000040000000000000025d2100019000000f7cf10002400000054311300000000001bd010005600000071d010004c00000054311300000000003ac2100059000000acce10000a0000005431130000000000bdd010002d0000005431130000000000f2eb12000b000000ead010000d000000f7d010003a00000022cf10003600000031d1100022000000946412000600000053d11000380000008bd1100030000000bbd1100031000000ecd110003500000036ec12000c000000636c6561725f6964656e74697479000021ce10004f000000543113000000000070ce10003c00000054311300000000003ac2100059000000acce10000a0000005431130000000000b6ce1000270000005431130000000000f2eb12000b000000ddce100011000000eece10003400000022cf10003600000058cf100049000000a1cf100023000000c4cf1000330000006cac10000d00000036ec12000c000000726571756573745f6a756467656d656e74000000000000003bc81000090000000000000044c8100017000000000000001ace100007000000000000004db612001500000060cc100026000000543113000000000086cc100056000000dccc100007000000543113000000000042cb10004e00000090cb1000150000005431130000000000e3cc1000480000002bcd100056000000543113000000000081cd10000d0000008ecd10002f000000bdcd1000040000005431130000000000c1cd10002a0000005431130000000000f2eb12000b000000b6c710000e00000004c6100021000000ebcd10002f0000006cac10000d00000036ec12000c00000063616e63656c5f726571756573740000000000003bc81000090000000000000052cc10000e000000e8ca10001b000000543113000000000003cb10003f000000543113000000000042cb10004e00000090cb1000150000005431130000000000a5cb1000520000005431130000000000f7cb10002c0000005431130000000000f2eb12000b000000b6c710000e00000004c610002100000023cc10002300000046cc10000c00000036ec12000c0000007365745f6665650000000000a00e1300050000000000000044c810001700000000000000e5ca100003000000000000004db61200150000004eca100047000000543113000000000071c6100056000000a6c81000290000005431130000000000cfc810003e00000095ca1000160000005431130000000000f2eb12000b00000051c910000a0000005bc910001f000000abca10003a00000036ec12000c0000007365745f6163636f756e745f6964000000000000a00e1300050000000000000044c810001700000000000000871913000300000000000000e3f812000c000000c8c9100030000000543113000000000071c6100056000000a6c81000290000005431130000000000cfc810003e000000f8c910001d0000005431130000000000f2eb12000b00000051c910000a0000005bc910001f00000015ca10003900000036ec12000c0000007365745f6669656c6473000000000000a00e1300050000000000000044c810001700000000000000b4c910000600000000000000bac910000e0000007bc810002b000000543113000000000071c6100056000000a6c81000290000005431130000000000cfc810003e0000000dc91000440000005431130000000000f2eb12000b00000051c910000a0000005bc910001f0000007ac910003a00000036ec12000c00000070726f766964655f6a756467656d656e74000000000000003bc81000090000000000000044c810001700000000000000739a1200060000000000000085fc110023000000000000005bc81000090000000000000064c810001700000042c610002f000000543113000000000071c6100056000000c7c610002d0000005431130000000000f4c610004900000058c5100056000000aec510001e0000003dc7100053000000543113000000000090c71000260000005431130000000000f2eb12000b000000b6c710000e000000c4c7100022000000e6c71000260000000cc810002f0000006cac10000d00000036ec12000c0000006b696c6c5f6964656e74697479000000fcc310005100000054311300000000004dc4100059000000a6c4100052000000f8c4100021000000543113000000000019c510003f000000543113000000000058c5100056000000aec510001e0000005431130000000000ccc51000260000005431130000000000f2eb12000b000000f2c510001200000004c610002100000025c610001d0000006cac10000d00000036ec12000c0000006164645f737562000000000091c31000030000000000000085fc11002300000000000000f4c310000400000000000000f8c3100004000000c8c310002c0000005431130000000000b4c11000580000006bc310000f00000054311300000000003ac21000590000007ac310001700000072656e616d655f737562000094c310003400000054311300000000003ac21000590000007ac310001700000072656d6f76655f73756200000000000091c31000030000000000000085fc1100230000003ac31000310000005431130000000000b4c11000580000006bc310000f00000054311300000000003ac21000590000007ac3100017000000717569745f73756290c11000240000005431130000000000b4c11000580000000cc210002e00000054311300000000003ac210005900000093c21000100000005431130000000000a3c2100052000000f5c21000450000002052656d6f7665207468652073656e6465722061732061207375622d6163636f756e742e205061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c20626520726570617472696174656420746f207468652073656e64657220282a6e6f742a20746865206f726967696e616c206465706f7369746f72292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d7573742068617665206120726567697374657265642073757065722d6964656e746974792e204e4f54453a20546869732073686f756c64206e6f74206e6f726d616c6c7920626520757365642c206275742069732070726f766964656420696e207468652063617365207468617420746865206e6f6e2d20636f6e74726f6c6c6572206f6620616e206163636f756e74206973206d616c6963696f75736c7920726567697374657265642061732061207375622d6163636f756e742e2052656d6f76652074686520676976656e206163636f756e742066726f6d207468652073656e646572277320737562732e20746f207468652073656e6465722e20737562206964656e74697479206f662060737562602e73756220416c74657220746865206173736f636961746564206e616d65206f662074686520676976656e207375622d6163636f756e742e204164642074686520676976656e206163636f756e7420746f207468652073656e646572277320737562732e64617461446174612052656d6f766520616e206163636f756e742773206964656e7469747920616e64207375622d6163636f756e7420696e666f726d6174696f6e20616e6420736c61736820746865206465706f736974732e205061796d656e743a2052657365727665642062616c616e6365732066726f6d20607365745f737562736020616e6420607365745f6964656e74697479602061726520736c617368656420616e642068616e646c65642062792060536c617368602e20566572696669636174696f6e2072657175657374206465706f7369747320617265206e6f742072657475726e65643b20746865792073686f756c642062652063616e63656c6c6564206d616e75616c6c79207573696e67206063616e63656c5f72657175657374602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206d617463682060543a3a466f7263654f726967696e602e202d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e742020207769746820612072656769737465726564206964656e746974792e20456d69747320604964656e746974794b696c6c656460206966207375636365737366756c2e202d20604f2852202b2053202b205829602e202d204f6e652062616c616e63652d72657365727665206f7065726174696f6e2e202d206053202b2032602073746f72616765206d75746174696f6e732e2050726f766964652061206a756467656d656e7420666f7220616e206163636f756e742773206964656e746974792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74206f6620746865207265676973747261722077686f736520696e64657820697320607265675f696e646578602e202d20607265675f696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206265696e67206d6164652e202d20606a756467656d656e74603a20746865206a756467656d656e74206f662074686520726567697374726172206f6620696e64657820607265675f696e646578602061626f75742060746172676574602e20456d69747320604a756467656d656e74476976656e60206966207375636365737366756c2e202d20604f2852202b205829602e202d204f6e652062616c616e63652d7472616e73666572206f7065726174696f6e2e202d20557020746f206f6e65206163636f756e742d6c6f6f6b7570206f7065726174696f6e2e202d2053746f726167653a2031207265616420604f285229602c2031206d757461746520604f2852202b205829602e7265675f696e646578436f6d706163743c526567697374726172496e6465783e6a756467656d656e744a756467656d656e743c42616c616e63654f663c543e3e2053657420746865206669656c6420696e666f726d6174696f6e20666f722061207265676973747261722e206f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e202d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e202d20606669656c6473603a20746865206669656c64732074686174207468652072656769737472617220636f6e6365726e73207468656d73656c76657320776974682e202d20604f285229602e202d204f6e652073746f72616765206d75746174696f6e20604f285229602e202d2042656e63686d61726b3a20372e343634202b2052202a20302e33323520c2b57320286d696e207371756172657320616e616c79736973296669656c64734964656e746974794669656c6473204368616e676520746865206163636f756e74206173736f63696174656420776974682061207265676973747261722e202d20606e6577603a20746865206e6577206163636f756e742049442e202d2042656e63686d61726b3a20382e383233202b2052202a20302e333220c2b57320286d696e207371756172657320616e616c797369732920536574207468652066656520726571756972656420666f722061206a756467656d656e7420746f206265207265717565737465642066726f6d2061207265676973747261722e202d2060666565603a20746865206e6577206665652e202d2042656e63686d61726b3a20372e333135202b2052202a20302e33323920c2b57320286d696e207371756172657320616e616c79736973296665652043616e63656c20612070726576696f757320726571756573742e205061796d656e743a20412070726576696f75736c79207265736572766564206465706f7369742069732072657475726e6564206f6e20737563636573732e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564206964656e746974792e202d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206e6f206c6f6e676572207265717565737465642e20456d69747320604a756467656d656e74556e72657175657374656460206966207375636365737366756c2e202d204f6e652073746f72616765206d75746174696f6e20604f2852202b205829602e202d204f6e65206576656e74526567697374726172496e64657820526571756573742061206a756467656d656e742066726f6d2061207265676973747261722e205061796d656e743a204174206d6f737420606d61785f666565602077696c6c20626520726573657276656420666f72207061796d656e7420746f2074686520726567697374726172206966206a756467656d656e7420676976656e2e202d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973207265717565737465642e202d20606d61785f666565603a20546865206d6178696d756d206665652074686174206d617920626520706169642e20546869732073686f756c64206a757374206265206175746f2d706f70756c617465642061733a206060606e6f636f6d70696c652053656c663a3a7265676973747261727328292e676574287265675f696e646578292e756e7772617028292e6665652060606020456d69747320604a756467656d656e7452657175657374656460206966207375636365737366756c2e202d2053746f726167653a2031207265616420604f285229602c2031206d757461746520604f2858202b205229602e6d61785f66656520436c65617220616e206163636f756e742773206964656e7469747920696e666f20616e6420616c6c207375622d6163636f756e747320616e642072657475726e20616c6c206465706f736974732e205061796d656e743a20416c6c2072657365727665642062616c616e636573206f6e20746865206163636f756e74206172652072657475726e65642e206964656e746974792e20456d69747320604964656e74697479436c656172656460206966207375636365737366756c2e202d20604f2852202b2053202b205829602020202d20776865726520605260207265676973747261722d636f756e742028676f7665726e616e63652d626f756e646564292e2020202d2077686572652060536020737562732d636f756e742028686172642d20616e64206465706f7369742d626f756e646564292e2020202d20776865726520605860206164646974696f6e616c2d6669656c642d636f756e7420286465706f7369742d626f756e64656420616e6420636f64652d626f756e646564292e202d204f6e652062616c616e63652d756e72657365727665206f7065726174696f6e2e202d206032602073746f7261676520726561647320616e64206053202b2032602073746f726167652064656c6574696f6e732e2053657420746865207375622d6163636f756e7473206f66207468652073656e6465722e205061796d656e743a20416e79206167677265676174652062616c616e63652072657365727665642062792070726576696f757320607365745f73756273602063616c6c732077696c6c2062652072657475726e656420616e6420616e20616d6f756e7420605375624163636f756e744465706f736974602077696c6c20626520726573657276656420666f722065616368206974656d20696e206073756273602e202d206073756273603a20546865206964656e74697479277320286e657729207375622d6163636f756e74732e202d20604f2850202b205329602020202d20776865726520605060206f6c642d737562732d636f756e742028686172642d20616e64206465706f7369742d626f756e646564292e202d204174206d6f7374206f6e652062616c616e6365206f7065726174696f6e732e2020202d206050202b2053602073746f72616765206d75746174696f6e732028636f64656320636f6d706c657869747920604f28312960292020202d204f6e652073746f7261676520726561642028636f64656320636f6d706c657869747920604f28502960292e2020202d204f6e652073746f726167652077726974652028636f64656320636f6d706c657869747920604f28532960292e2020202d204f6e652073746f726167652d6578697374732028604964656e746974794f663a3a636f6e7461696e735f6b657960292e737562735665633c28543a3a4163636f756e7449642c2044617461293e2053657420616e206163636f756e742773206964656e7469747920696e666f726d6174696f6e20616e6420726573657276652074686520617070726f707269617465206465706f7369742e20496620746865206163636f756e7420616c726561647920686173206964656e7469747920696e666f726d6174696f6e2c20746865206465706f7369742069732074616b656e2061732070617274207061796d656e7420666f7220746865206e6577206465706f7369742e202d2060696e666f603a20546865206964656e7469747920696e666f726d6174696f6e2e20456d69747320604964656e7469747953657460206966207375636365737366756c2e202d20604f2858202b205827202b205229602020202d20776865726520605860206164646974696f6e616c2d6669656c642d636f756e7420286465706f7369742d626f756e64656420616e6420636f64652d626f756e646564292020202d20776865726520605260206a756467656d656e74732d636f756e7420287265676973747261722d636f756e742d626f756e64656429202d204f6e652062616c616e63652072657365727665206f7065726174696f6e2e202d204f6e652073746f72616765206d75746174696f6e2028636f6465632d7265616420604f285827202b205229602c20636f6465632d777269746520604f2858202b20522960292e696e666f4964656e74697479496e666f2041646420612072656769737472617220746f207468652073797374656d2e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060543a3a5265676973747261724f726967696e602e202d20606163636f756e74603a20746865206163636f756e74206f6620746865207265676973747261722e20456d6974732060526567697374726172416464656460206966207375636365737366756c2e202d20604f2852296020776865726520605260207265676973747261722d636f756e742028676f7665726e616e63652d626f756e64656420616e6420636f64652d626f756e646564292e202d204f6e652073746f72616765206d75746174696f6e2028636f64656320604f28522960292e6163636f756e7400000000d0d610000a0000000105000000000000e3f812000c00000000000000dad610001a0000000000000000000000000000000000000054311300f4d61000000000000000000004d710000300000000000000000000000000000067a61000070000000102000000000000e3f812000c000000000000001cd7100014000000000000000000000000000000000000005431130030d71000000000000000000040d710000200000000000000000000000000000050d71000060000000105000000000000e3f812000c0000000000000056d7100021000000000000000000000000000000000000005431130078d71000000000000000000088d7100005000000000000000100000000000000b0d710000a0000000000000000000000bad71000360000000000000000000000000000000000000000000000000000000000000054311300f0d71000000000000000000000d810000400000000000000010000004964656e746974794f66526567697374726174696f6e3c42616c616e63654f663c543e3e1200000000000000010000004c00000008da1000480000005431130000000000f2c112003000000028543a3a4163636f756e7449642c2044617461291200000000000000010000004d0000005cd9100058000000b4d9100054000000537562734f662842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e29001200000000000000010000004e000000e7d810002e000000543113000000000015d91000470000005431130000000000f2c1120030000000526567697374726172735665633c4f7074696f6e3c526567697374726172496e666f3c42616c616e63654f663c543e2c20543a3a4163636f756e7449643e3e3e1200000000000000010000004f00000020d810005300000073d810002a00000054311300000000009dd810004a0000002054686520736574206f6620726567697374726172732e204e6f7420657870656374656420746f206765742076657279206269672061732063616e206f6e6c79206265206164646564207468726f7567682061207370656369616c206f726967696e20286c696b656c79206120636f756e63696c206d6f74696f6e292e2054686520696e64657820696e746f20746869732063616e206265206361737420746f2060526567697374726172496e6465786020746f2067657420612076616c69642076616c75652e20416c7465726e6174697665202273756222206964656e746974696573206f662074686973206163636f756e742e20546865206669727374206974656d20697320746865206465706f7369742c20746865207365636f6e64206973206120766563746f72206f6620746865206163636f756e74732e205468652073757065722d6964656e74697479206f6620616e20616c7465726e6174697665202273756222206964656e7469747920746f676574686572207769746820697473206e616d652c2077697468696e207468617420636f6e746578742e20496620746865206163636f756e74206973206e6f7420736f6d65206f74686572206163636f756e742773207375622d6964656e746974792c207468656e206a75737420604e6f6e65602e20496e666f726d6174696f6e20746861742069732070657274696e656e7420746f206964656e746966792074686520656e7469747920626568696e6420616e206163636f756e742e00000000a0db10000c0000000000000057a912000c0000000000000054311300acdb10000000000000000000bcdb1000010000000000000000000000c4db10000c0000000000000057a912000c0000000000000054311300d0db10000000000000000000e0db1000010000000000000000000000e8db1000110000000000000057a912000c0000000000000054311300fcdb100000000000000000000cdc100003000000000000000000000024dc10000e00000000000000cbed120003000000000000005431130034dc1000000000000000000044dc10000100000000000000000000004cdc10001300000000000000cbed120003000000000000005431130060dc1000000000000000000070dc100002000000000000000000000080dc10000d00000000000000cbed120003000000000000005431130090dc10000000000000000000a0dc1000020000000000000042617369634465706f7369741200000000000000010000005000000041df1000360000004669656c644465706f7369741200000000000000010000003e000000f6de10004b0000005375624163636f756e744465706f73697400000012000000000000000100000051000000f7dd10005900000050de10005c000000acde10004a0000004d61785375624163636f756e7473000012000000000000000100000052000000b4dd1000430000004d61784164646974696f6e616c4669656c6473001200000000000000010000005200000023dd1000590000007cdd1000380000004d61785265676973747261727300000012000000000000000100000049000000b0dc10005400000004dd10001f000000204d61786d696d756d206e756d626572206f66207265676973747261727320616c6c6f77656420696e207468652073797374656d2e204e656564656420746f20626f756e642074686520636f6d706c6578697479206f662c20652e672e2c207570646174696e67206a756467656d656e74732e204d6178696d756d206e756d626572206f66206164646974696f6e616c206669656c64732074686174206d61792062652073746f72656420696e20616e2049442e204e656564656420746f20626f756e642074686520492f4f20726571756972656420746f2061636365737320616e206964656e746974792c206275742063616e2062652070726574747920686967682e20546865206d6178696d756d206e756d626572206f66207375622d6163636f756e747320616c6c6f77656420706572206964656e746966696564206163636f756e742e2054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564207375626163636f756e742e20546869732073686f756c64206163636f756e7420666f722074686520666163742074686174206f6e652073746f72616765206974656d27732076616c75652077696c6c20696e637265617365206279207468652073697a65206f6620616e206163636f756e742049442c20616e642074686572652077696c6c20626520616e6f746865722074726965206974656d2077686f73652076616c7565206973207468652073697a65206f6620616e206163636f756e7420494420706c75732033322062797465732e2054686520616d6f756e742068656c64206f6e206465706f73697420706572206164646974696f6e616c206669656c6420666f7220612072656769737465726564206964656e746974792e2054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564206964656e746974792e000000000030e110000b00000000000000fce412000100000000000000000000003ce1100001000000000000000000000044e110000f00000000000000c0f5110002000000000000000000000054e110000100000000000000000000005ce110000e00000000000000c0f511000200000000000000000000006ce1100001000000000000000000000074e11000120000000000000088e1100002000000000000000000000098e11000010000000000000000000000a0e11000140000000000000088e11000020000000000000000000000b4e1100001000000000000000000000066b510000e0000000000000088e11000020000000000000000000000bce11000010000000000000000000000c4e110000e00000000000000d4e11000010000000000000000000000dce11000010000000000000000000000e4e110001000000000000000fc021200030000000000000000000000f4e11000010000000000000000000000fce110001200000000000000fc02120003000000000000000000000010e2100002000000000000000000000020e210001200000000000000fc02120003000000000000000000000034e2100002000000000000004964656e7469747953657400f6e41000440000004964656e74697479436c656172656400b1e41000450000004964656e746974794b696c6c656400006ee41000430000004a756467656d656e74526571756573746564000079e512000900000052cc10000e0000002de41000410000004a756467656d656e74556e726571756573746564f1e310003c000000afe31000420000005265676973747261724164646564000052cc10000e00000084e310002b0000005375624964656e7469747941646465642fe31000550000005375624964656e7469747952656d6f7665640000d5e210004300000018e31000170000005375624964656e746974795265766f6b6564000044e21000470000008be210004a0000002041207375622d6964656e746974792077617320636c65617265642c20616e642074686520676976656e206465706f7369742072657061747269617465642066726f6d20746865206d61696e206964656e74697479206163636f756e7420746f20746865207375622d6964656e74697479206163636f756e742e205c5b7375622c206d61696e2c206465706f7369745c5d2041207375622d6964656e74697479207761732072656d6f7665642066726f6d20616e206964656e7469747920616e6420746865206465706f7369742066726565642e205c5b7375622c206d61696e2c206465706f7369745c5d2041207375622d6964656e746974792077617320616464656420746f20616e206964656e7469747920616e6420746865206465706f73697420706169642e205c5b7375622c206d61696e2c206465706f7369745c5d204120726567697374726172207761732061646465642e205c5b7265676973747261725f696e6465785c5d2041206a756467656d656e742077617320676976656e2062792061207265676973747261722e205c5b7461726765742c207265676973747261725f696e6465785c5d2041206a756467656d656e74207265717565737420776173207265747261637465642e205c5b77686f2c207265676973747261725f696e6465785c5d2041206a756467656d656e74207761732061736b65642066726f6d2061207265676973747261722e205c5b77686f2c207265676973747261725f696e6465785c5d2041206e616d65207761732072656d6f76656420616e642074686520676976656e2062616c616e636520736c61736865642e205c5b77686f2c206465706f7369745c5d2041206e616d652077617320636c65617265642c20616e642074686520676976656e2062616c616e63652072657475726e65642e205c5b77686f2c206465706f7369745c5d2041206e616d652077617320736574206f72207265736574202877686963682077696c6c2072656d6f766520616c6c206a756467656d656e7473292e205c5b77686f5c5d4d6178576569676874546f6f4c6f77556e657870656374656454696d65706f696e7457726f6e6754696d65706f696e744e6f54696d65706f696e7453656e646572496e5369676e61746f726965735369676e61746f726965734f75744f664f72646572546f6f4d616e795369676e61746f72696573546f6f4665775369676e61746f726965734e6f417070726f76616c734e6565646564416c7265616479417070726f7665644d696e696d756d5468726573686f6c64416c726561647953746f72656400000000000000b0e610001400000000000000c4e61000020000000000000000000000f4e6100010000000000000000000000074e7100008000000000000007ce710000600000000000000000000000ce810002e00000000000000000000007ce9100010000000000000008ce9100005000000000000000000000004ea100024000000000000000000000024eb10000f0000000000000034eb100004000000000000000000000094eb10001a0000000000000061735f6d756c74695f7468726573686f6c645f310000000059f0100011000000000000002c1a13001100000000000000a80e13000400000000000000ac0e130018000000d5f710005500000054311300000000006c0e13003400000054311300000000002af81000500000007af8100041000000eaf41000230000005431130000000000bbf810002f0000005431130000000000f2eb12000b000000eaf8100047000000fbf610002000000031f9100012000000aef710001300000036ec12000c00000061735f6d756c746900000000176b12000900000000000000a50e1300030000000000000059f0100011000000000000002c1a130011000000000000007df410000f000000000000008cf410002100000000000000a80e13000400000000000000c1f710000a00000000000000cbf710000a00000000000000a1fb12000400000000000000adf410000a00000000000000b7f41000060000009df0100056000000f3f010003f0000005431130000000000bdf410002d000000543113000000000032f110004c0000007ef1100050000000cef110000e00000054311300000000006c0e1300340000005431130000000000ecec10005600000042ed10005100000093ed10001c000000dcf110005700000033f210005500000088f2100036000000eaf410002300000054311300000000000df510004800000055f510004700000054311300000000009cf5100057000000f3f510005600000049f61000380000005431130000000000f2eb12000b00000081f610001500000064ee10003400000098ee100050000000e8ee10005200000096f61000490000003aef1000300000000cf310003600000042f310003f0000006cac10000d000000dff610001c00000081f310004c000000cdf3100024000000f1f310002d000000fbf6100020000000c0ef12000d0000001bf710004900000064f710004a000000aef710001300000036ec12000c000000617070726f76655f61735f6d756c746900000000176b12000900000000000000a50e1300030000000000000059f0100011000000000000002c1a130011000000000000007df410000f000000000000008cf4100021000000000000008cf01000090000000000000095f010000800000000000000adf410000a00000000000000b7f41000060000009df0100056000000f3f010003f000000543113000000000032f110004c0000007ef1100050000000cef110000e00000054311300000000006c0e1300340000005431130000000000ecec10005600000042ed10005100000093ed10001c000000dcf110005700000033f210005500000088f210003600000026ee1000340000005431130000000000bef210004e0000005431130000000000f2eb12000b0000005aee10000a00000064ee10003400000098ee100050000000e8ee1000520000003aef1000300000000cf310003600000042f310003f0000006cac10000d00000081f310004c000000cdf3100024000000f1f310002d000000a9ef100023000000c0ef12000d0000001ef410002f0000004df410003000000036ec12000c00000063616e63656c5f61735f6d756c74690000000000176b12000900000000000000a50e1300030000000000000059f0100011000000000000002c1a130011000000000000006af01000090000000000000073f0100019000000000000008cf01000090000000000000095f010000800000064ec100056000000baec10003200000054311300000000006c0e1300340000005431130000000000ecec10005600000042ed10005100000093ed10001c000000afed10005800000007ee10001f00000026ee1000340000005431130000000000f2eb12000b0000005aee10000a00000064ee10003400000098ee100050000000e8ee1000520000003aef1000300000006cac10000d0000006aef1000220000008cef10001d000000a9ef100023000000c0ef12000d000000ccef10004600000012f010004700000036ec12000c0000002043616e63656c2061207072652d6578697374696e672c206f6e2d676f696e67206d756c7469736967207472616e73616374696f6e2e20416e79206465706f7369742072657365727665642070726576696f75736c7920666f722074686973206f7065726174696f6e2077696c6c20626520756e7265736572766564206f6e20737563636573732e202d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e202d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869732064697370617463682e204d6179206e6f7420626520656d7074792e202d206074696d65706f696e74603a205468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e20666f7220746869732064697370617463682e202d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e202d20604f285329602e202d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e202d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f662020207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2e202d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602e202d20492f4f3a2031207265616420604f285329602c206f6e652072656d6f76652e202d2053746f726167653a2072656d6f766573206f6e65206974656d2e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d20202020202d20526561643a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d2c20526566756e64204163636f756e742c2043616c6c7320202020202d2057726974653a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d2c20526566756e64204163636f756e742c2043616c6c736f746865725f7369676e61746f7269657374696d65706f696e7454696d65706f696e743c543a3a426c6f636b4e756d6265723e63616c6c5f686173685b75383b2033325d20526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e7420696620617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e205061796d656e743a20604465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c757320607468726573686f6c64602074696d657320604465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f722069732063616e63656c6c65642e202d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e204966206974206973206e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2e204e4f54453a2049662074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2077616e7420746f20757365206061735f6d756c74696020696e73746561642e202d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292e202d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e202d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c207769746820612020206465706f7369742074616b656e20666f7220697473206c69666574696d65206f66202020604465706f73697442617365202b207468726573686f6c64202a204465706f736974466163746f72602e20202020202d20526561643a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d20202020202d2057726974653a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d6d617962655f74696d65706f696e744f7074696f6e3c54696d65706f696e743c543a3a426c6f636b4e756d6265723e3e6d61785f7765696768745765696768742049662074686572652061726520656e6f7567682c207468656e206469737061746368207468652063616c6c2e202d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e204e4f54453a20556e6c6573732074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2067656e6572616c6c792077616e7420746f207573652060617070726f76655f61735f6d756c74696020696e73746561642c2073696e6365206974206f6e6c7920726571756972657320612068617368206f66207468652063616c6c2e20526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c7420696620607468726573686f6c64602069732065786163746c79206031602e204f7468657277697365206f6e20737563636573732c20726573756c7420697320604f6b6020616e642074686520726573756c742066726f6d2074686520696e746572696f722063616c6c2c206966206974207761732065786563757465642c206d617920626520666f756e6420696e20746865206465706f736974656420604d756c7469736967457865637574656460206576656e742e202d20604f2853202b205a202b2043616c6c29602e202d204f6e652063616c6c20656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285a296020776865726520605a602069732074782d6c656e2e202d2054686520776569676874206f6620746865206063616c6c602e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d20202020202d2052656164733a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d2c2043616c6c7320286966206073746f72655f63616c6c602920202020202d205772697465733a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d2c2043616c6c7320286966206073746f72655f63616c6c6029202d20506c75732043616c6c205765696768744f706171756543616c6c73746f72655f63616c6c20496d6d6564696174656c792064697370617463682061206d756c74692d7369676e61747572652063616c6c207573696e6720612073696e676c6520617070726f76616c2066726f6d207468652063616c6c65722e202d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f206172652070617274206f6620746865206d756c74692d7369676e61747572652c2062757420646f206e6f7420706172746963697061746520696e2074686520617070726f76616c2070726f636573732e20526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c742e204f285a202b204329207768657265205a20697320746865206c656e677468206f66207468652063616c6c20616e6420432069747320657865637574696f6e207765696768742e202d204442205765696768743a204e6f6e650000000000f4f91000090000000205020000000000e3f812000c0000000000000095f010000800000000000000fdf9100034000000000000005431130034fa1000000000000000000044fa1000010000000000000000000000000000004cfa100005000000010600000000000095f01000080000000000000051fa10002800000000000000000000000000000000000000543113007cfa10000000000000000000543113000000000000000000000000004d756c7469736967734d756c74697369673c543a3a426c6f636b4e756d6265722c2042616c616e63654f663c543e2c20543a3a4163636f756e7449643e000000120000000000000001000000230000008cfa10002500000043616c6c73284f706171756543616c6c2c20543a3a4163636f756e7449642c2042616c616e63654f663c543e29000000120000000000000001000000230000002054686520736574206f66206f70656e206d756c7469736967206f7065726174696f6e732e000000000000005cfb10000b0000000000000057a912000c000000000000005431130068fb1000000000000000000078fb100002000000000000000000000088fb10000d0000000000000057a912000c000000000000005431130098fb10000000000000000000a8fb1000010000000000000000000000b0fb10000e00000000000000a50e1300030000000000000054311300c0fb10000000000000000000d0fb100001000000000000004465706f7369744261736500120000000000000001000000530000006dfc10005c000000c9fc10001b0000004465706f736974466163746f720000001200000000000000010000004700000018fc1000550000004d61785369676e61746f72696573000012000000000000000100000054000000d8fb10004000000020546865206d6178696d756d20616d6f756e74206f66207369676e61746f7269657320616c6c6f77656420666f72206120676976656e206d756c74697369672e2054686520616d6f756e74206f662063757272656e6379206e65656465642070657220756e6974207468726573686f6c64207768656e206372656174696e672061206d756c746973696720657865637574696f6e2e20546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e672061206d756c746973696720657865637574696f6e206f7220746f2073746f726520612064697370617463682063616c6c20666f72206c617465722e0000000094fd10000b00000000000000a0fd1000030000000000000000000000b8fd1000010000000000000000000000c0fd10001000000000000000d0fd1000040000000000000000000000f0fd100002000000000000000000000000fe1000100000000000000010fe100005000000000000000000000038fe100001000000000000000000000040fe10001100000000000000d0fd100004000000000000000000000054fe100001000000000000004e65774d756c74697369670079e512000900000079e512000900000020ff10000800000089ff1000470000004d756c7469736967417070726f76616c79e51200090000000aff10001600000079e512000900000020ff10000800000028ff1000330000005bff10002e0000004d756c7469736967457865637574656479e51200090000000aff10001600000079e512000900000020ff100008000000637a12000e000000b4fe1000560000004d756c746973696743616e63656c6c65640000005cfe1000580000002041206d756c7469736967206f7065726174696f6e20686173206265656e2063616e63656c6c65642e205c5b63616e63656c6c696e672c2074696d65706f696e742c206d756c74697369672c2063616c6c5f686173685c5d2041206d756c7469736967206f7065726174696f6e20686173206265656e2065786563757465642e205c5b617070726f76696e672c2074696d65706f696e742c206d756c74697369672c2063616c6c5f686173685c5d54696d65706f696e743c426c6f636b4e756d6265723e43616c6c486173682041206d756c7469736967206f7065726174696f6e20686173206265656e20617070726f76656420627920736f6d656f6e652e205c5b617070726f76696e672c2074696d65706f696e742c206d756c74697369672c2063616c6c5f686173685c5d2041206e6577206d756c7469736967206f7065726174696f6e2068617320626567756e2e205c5b617070726f76696e672c206d756c74697369672c2063616c6c5f686173685c5d496e73756666696369656e7450726f706f7365727342616c616e636500000000700011000d0000000000000080001100020000000000000000000000b0001100090000000000000000000000f80011000f00000000000000080111000100000000000000000000002001110009000000000000000000000068011100100000000000000008011100010000000000000000000000780111000a0000000000000070726f706f73655f7370656e640000000000000048b612000500000000000000a00411001800000000000000b80411000b0000000000000085fc1100230000008b0311004b000000d60311004d00000023041100150000005431130000000000f2eb12000b0000000403110013000000380411002d000000650411003b00000036ec12000c00000072656a6563745f70726f706f73616c0000000000800311000b000000000000008765120016000000c50211003f0000005431130000000000f2df11002b0000005431130000000000f2eb12000b000000040311001300000017031100340000004b0311003500000036ec12000c000000617070726f76655f70726f706f73616cc8011100570000001f0211002b00000054311300000000004a0211002c0000005431130000000000f2eb12000b00000076021100140000008a02110024000000ae0211001700000036ec12000c00000020417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e204d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a417070726f76654f726967696e602e202d20436f6d706c65786974793a204f2831292e202d20446252656164733a206050726f706f73616c73602c2060417070726f76616c7360202d20446257726974653a2060417070726f76616c73602052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e202d20436f6d706c65786974793a204f283129202d20446252656164733a206050726f706f73616c73602c206072656a65637465642070726f706f736572206163636f756e7460202d2044625772697465733a206050726f706f73616c73602c206072656a65637465642070726f706f736572206163636f756e746070726f706f73616c5f69642050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e202d20446252656164733a206050726f706f73616c436f756e74602c20606f726967696e206163636f756e7460202d2044625772697465733a206050726f706f73616c436f756e74602c206050726f706f73616c73602c20606f726967696e206163636f756e7460436f6d706163743c42616c616e63654f663c542c20493e3e62656e65666963696172790000000000e45712000d0000000000000000000000357c12000d0000000000000000000000000000000000000000000000000000000000000054311300cc0511000000000000000000dc05110001000000000000000100000000000000db571200090000000105000000000000357c12000d00000000000000e40511002700000000000000000000000000000000000000543113000c06110000000000000000001c0611000100000000000000000000000000000014a61000090000000000000000000000240611001200000000000000000000000000000000000000000000000000000000000000543113003806110000000000000000004806110001000000000000000100000012000000000000000100000022000000ad0611002900000050726f706f73616c3c543a3a4163636f756e7449642c2042616c616e63654f663c542c20493e3e00120000000000000001000000230000008e0611001f0000005665633c50726f706f73616c496e6465783e000012000000000000000100000024000000500611003e0000002050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e000000000000f00711000c00000000000000fc07110007000000000000005431130004081100000000000000000014081100020000000000000000000000240811001300000000000000370811000f000000000000005431130048081100000000000000000058081100010000000000000000000000600811000b00000000000000a9f912000e00000000000000543113006c08110000000000000000007c081100010000000000000000000000840811000400000000000000fc07110007000000000000005431130088081100000000000000000098081100010000000000000000000000a00811000800000000000000a0081100080000000000000054311300a80811000000000000000000b8081100010000000000000050726f706f73616c426f6e645065726d696c6c0012000000000000000100000055000000be09110055000000130a11004400000050726f706f73616c426f6e644d696e696d756d42616c616e63654f663c542c20493e0000120000000000000001000000450000006c091100520000005370656e64506572696f6400120000000000000001000000560000004a091100220000004275726e1200000000000000010000005700000006091100440000004d6f64756c65496412000000000000000100000058000000c008110046000000205468652074726561737572792773206d6f64756c652069642c207573656420666f72206465726976696e672069747320736f7665726569676e206163636f756e742049442e2050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e204672616374696f6e206f6620612070726f706f73616c27732076616c756520746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c616365207468652070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f6573206e6f742e0000000000d0ce120008000000000000008c0b1100010000000000000000000000940b11000100000000000000000000009c0b11000800000000000000a40b1100010000000000000000000000ac0b1100010000000000000000000000b40b11000700000000000000bc0b1100030000000000000000000000d40b1100010000000000000000000000dc0b11000800000000000000e40b1100020000000000000000000000f40b1100010000000000000000000000fc0b11000500000000000000a40b1100010000000000000000000000040c11000100000000000000000000000c0c11000800000000000000a40b1100010000000000000000000000140c1100020000000000000000000000480312000700000000000000a40b1100010000000000000000000000240c11000100000000000000357c12000d000000c40d1100210000005370656e64696e67d5d1120007000000750d11004f0000004177617264656400357c12000d000000d5d112000700000079e51200090000002e0d11004700000052656a6563746564357c12000d000000d5d1120007000000e50c1100490000004275726e74000000b90c11002c000000526f6c6c6f766572580c11004c000000a40c1100150000002c0c11002c00000020536f6d652066756e64732068617665206265656e206465706f73697465642e205c5b6465706f7369745c5d205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e205c5b6275646765745f72656d61696e696e675c5d20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e205c5b6275726e5c5d20412070726f706f73616c207761732072656a65637465643b2066756e6473207765726520736c61736865642e205c5b70726f706f73616c5f696e6465782c20736c61736865645c5d20536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205c5b70726f706f73616c5f696e6465782c2061776172642c2062656e65666963696172795c5d205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e205c5b6275646765745f72656d61696e696e675c5d204e65772070726f706f73616c2e205c5b70726f706f73616c5f696e6465785c5d0000002c0713005500000069000000010000002813130056000000ef010000010000009013130056000000c10000000100000000000000a9b510001200000000000000d80f11000100000000000000000000008b3311000800000000000000e00f1100010000000000000000000000a1b510000800000000000000e80f110001000000000000000000000097b510000a00000000000000f00f11000100000000000000000000008db510000a00000000000000f80f110001000000000000000000000083b510000a000000000000000010110001000000000000000000000074b510000f000000000000000810110001000000000000000000000066b510000e000000000000001010110001000000000000000000000056b510001000000000000000181011000100000000000000000000004ab510000c00000000000000201011000100000000000000000000003db510000d000000000000002810110001000000000000000000000030b510000d00000000000000301011000100000000000000000000001fb510001100000000000000381011000100000000000000000000007a5011000e000000000000004010110001000000000000000000000019b51000060000000000000048101100010000000000000000000000bbb510000800000000000000501011000100000000000000c911110018000000b4111100150000009f11110015000000921111000d00000082111100100000006f111100130000005d111100120000004c11110011000000391111001300000023111100160000000c11110017000000f01011001c000000b51011003b000000981011001d0000007b1011001d0000005810110023000000205375622d6163636f756e742069736e2774206f776e65642062792073656e6465722e2053656e646572206973206e6f742061207375622d6163636f756e742e204163636f756e7420494420697320616c7265616479206e616d65642e204d6178696d756d20616d6f756e74206f66207265676973747261727320726561636865642e2043616e6e6f742061646420616e79206d6f72652e20546f6f206d616e79206164646974696f6e616c206669656c64732e205468652074617267657420697320696e76616c69642e2054686520696e64657820697320696e76616c69642e20496e76616c6964206a756467656d656e742e204a756467656d656e7420676976656e2e20537469636b79206a756467656d656e742e204e6f206964656e7469747920666f756e642e20466565206973206368616e6765642e20456d70747920696e6465782e204163636f756e742069736e2774206e616d65642e204163636f756e742069736e277420666f756e642e20546f6f206d616e7920737562732d6163636f756e74732e00000000000000e0e5100010000000000000006c131100010000000000000000000000d1e510000f0000000000000074131100010000000000000000000000c0e5100011000000000000007c131100010000000000000000000000afe510001100000000000000841311000100000000000000000000009de5100012000000000000008c13110001000000000000000000000088e5100015000000000000009413110001000000000000000000000075e5100013000000000000009c1311000100000000000000000000008b3311000800000000000000a41311000100000000000000000000007ea610000800000000000000ac1311000100000000000000000000006ae510000b00000000000000b41311000100000000000000000000005ce510000e00000000000000bc13110001000000000000000000000049e510001300000000000000c41311000100000000000000000000003ae510000f00000000000000cc131100010000000000000000000000f0e510000d00000000000000d41311000100000000000000c316110020000000971611002c0000006f16110028000000441611002b000000181611002c000000d415110044000000901511004400000058151100380000000c1511004c000000c414110048000000781411004c0000003a1411003e0000000514110035000000dc1311002900000020546865206461746120746f2062652073746f72656420697320616c72656164792073746f7265642e20546865206d6178696d756d2077656967687420696e666f726d6174696f6e2070726f76696465642077617320746f6f206c6f772e20412074696d65706f696e742077617320676976656e2c20796574206e6f206d756c7469736967206f7065726174696f6e20697320756e6465727761792e204120646966666572656e742074696d65706f696e742077617320676976656e20746f20746865206d756c7469736967206f7065726174696f6e207468617420697320756e6465727761792e204e6f2074696d65706f696e742077617320676976656e2c2079657420746865206d756c7469736967206f7065726174696f6e20697320616c726561647920756e6465727761792e204f6e6c7920746865206163636f756e742074686174206f726967696e616c6c79206372656174656420746865206d756c74697369672069732061626c6520746f2063616e63656c2069742e204d756c7469736967206f7065726174696f6e206e6f7420666f756e64207768656e20617474656d7074696e6720746f2063616e63656c2e205468652073656e6465722077617320636f6e7461696e656420696e20746865206f74686572207369676e61746f726965733b2069742073686f756c646e27742062652e20546865207369676e61746f7269657320776572652070726f7669646564206f7574206f66206f726465723b20746865792073686f756c64206265206f7264657265642e2054686572652061726520746f6f206d616e79207369676e61746f7269657320696e20746865206c6973742e2054686572652061726520746f6f20666577207369676e61746f7269657320696e20746865206c6973742e2043616c6c20646f65736e2774206e65656420616e7920286d6f72652920617070726f76616c732e2043616c6c20697320616c726561647920617070726f7665642062792074686973207369676e61746f72792e205468726573686f6c64206d7573742062652032206f7220677265617465722e0000000000d0ff10001c000000000000001c1711000100000000000000000000004ab510000c00000000000000241711000100000000000000511711001f0000002c17110025000000204e6f2070726f706f73616c206f7220626f756e7479206174207468617420696e6465782e2050726f706f73657227732062616c616e636520697320746f6f206c6f772e2813130056000000020300001d0000002813130056000000cc03000036000000a0171100520000005c0100000f0000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f626162652f7372632f6c69622e7273000004181100610000002e000000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f617574686f726974792d646973636f766572792f7372632f6c69622e72734c6f6f6b7570007c18110057000000c0000000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f7363686564756c65722f7372632f6c69622e72734167656e6461000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004261626545717569766f636174696f6e736c6f74206e756d626572206973207536343b2069742073686f756c642072656c61746520696e20736f6d652077617920746f2077616c6c20636c6f636b2074696d653b20696620753634206973206e6f7420656e6f7567682077652073686f756c6420637261736820666f72207361666574793b207165642e0000a017110052000000640200000e000000a017110052000000660200003b00000054696d657374616d7020736c6f74206d757374206d61746368206043757272656e74536c6f746000a0171100520000003e0300000900000065706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b20716564000000a017110052000000060200000e000000a0171100520000000e0200000e00000065706f636820696e646578206973207536343b20697420697320616c77617973206f6e6c7920696e6372656d656e746564206279206f6e653b20696620753634206973206e6f7420656e6f7567682077652073686f756c6420637261736820666f72207361666574793b207165642e00a0171100520000004b0200004600000045706f6368436f6e66696720697320696e697469616c697a656420696e2067656e657369733b207765206e65766572206074616b6560206f7220606b696c6c602069743b20716564a0171100520000005702000029000000a017110052000000440200002d000000a017110052000000a70000000f00000000000000542f12001300000000000000241c1100020000000000000000000000541c1100040000000000000000000000b82f12001c00000000000000241c1100020000000000000000000000741c1100080000000000000000000000b41c11001200000000000000c81c1100010000000000000000000000e01c11000400000000000000000000002034120012000000000000000a1f11001c000000000000005c3412000f000000000000006b34120010000000341e110043000000771e110042000000b91e110044000000fd1e11000d000000341e110043000000771e110042000000b91e110044000000fd1e11000d00000046331200440000008a33120046000000d033120046000000163412000a000000706c616e5f636f6e6669675f6368616e67650000000000001a1e11000600000000000000201e110014000000001d110058000000581d110055000000ad1d110057000000041e11001600000020506c616e20616e2065706f636820636f6e666967206368616e67652e205468652065706f636820636f6e666967206368616e6765206973207265636f7264656420616e642077696c6c20626520656e6163746564206f6e20746865206e6578742063616c6c20746f2060656e6163745f65706f63685f6368616e6765602e2054686520636f6e6669672077696c6c20626520616374697661746564206f6e652065706f63682061667465722e204d756c7469706c652063616c6c7320746f2074686973206d6574686f642077696c6c207265706c61636520616e79206578697374696e6720706c616e6e656420636f6e666967206368616e6765207468617420686164206e6f74206265656e20656e6163746564207965742e636f6e6669674e657874436f6e66696744657363726970746f72205265706f727420617574686f726974792065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c20766572696679207468652065717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f6620616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63652077696c6c206265207265706f727465642e45717569766f636174696f6e50726f6f663c543a3a4865616465723e000000000000fa4511000a0000000000000000000000e8f21200030000000000000000000000000000000000000000000000000000000000000054311300a82411000000000000000000b824110001000000000000000100000000000000a54511000b0000000000000000000000c0241100270000000000000000000000000000000000000000000000000000000000000054311300e82411000000000000000000f824110001000000000000000100000000000000e34511000b0000000000000000000000002511000400000000000000000000000000000000000000000000000000000000000000543113000425110000000000000000001425110002000000000000000100000000000000c94511000b0000000000000000000000002511000400000000000000000000000000000000000000000000000000000000000000543113000425110000000000000000002425110001000000000000000100000000000000424611000a00000000000000000000002c251100160000000000000000000000000000000000000000000000000000000000000054311300442511000000000000000000542511000a0000000000000001000000000000002a461100180000000000000000000000201e1100140000000000000000000000000000000000000000000000000000000000000054311300a42511000000000000000000b425110001000000000000000000000000000000974511000e00000000000000000000002c251100160000000000000000000000000000000000000000000000000000000000000054311300442511000000000000000000bc25110001000000000000000100000000000000ba4511000f0000000000000000000000c0241100270000000000000000000000000000000000000000000000000000000000000054311300e82411000000000000000000c425110001000000000000000100000000000000ee4511000c0000000000000000000000cbed1200030000000000000000000000000000000000000000000000000000000000000054311300cc2511000000000000000000dc25110009000000000000000100000000000000972d1200110000000105000000000000cbed12000300000000000000242611001b00000000000000000000000000000000000000543113004026110000000000000000005026110001000000000000000100000000000000174611000b0000000000000000000000582611000f0000000000000000000000000000000000000000000000000000000000000054311300682611000000000000000000782611000200000000000000000000000000000004461100130000000000000000000000582611000f00000000000000000000000000000000000000000000000000000000000000543113008826110000000000000000009826110003000000000000000100000000000000b04511000a000000000000000000000027371200200000000000000000000000000000000000000000000000000000000000000054311300b02611000000000000000000c02611000500000000000000010000000000000022461100080000000000000000000000a9f912000e0000000000000000000000000000000000000000000000000000000000000054311300cc2511000000000000000000e8261100050000000000000001000000000000008c4511000b0000000000000000000000102711001600000000000000000000000000000000000000000000000000000000000000543113002827110000000000000000003827110001000000000000000000000000000000d44511000f00000000000000000000001027110016000000000000000000000000000000000000000000000000000000000000005431130028271100000000000000000040271100020000000000000000000000120000000000000001000000590000005c301100150000005665633c28417574686f7269747949642c2042616265417574686f72697479576569676874293e001200000000000000010000003f000000413011001b000000536c6f7412000000000000000100000059000000df2f11003e0000001d30110024000000ca2f1100150000007363686e6f72726b656c3a3a52616e646f6d6e65737300001200000000000000010000005a000000042e11002e0000005431130000000000322e11000b00000054311300000000003d2e1100410000007e2e11003e000000bc2e110045000000012f110045000000462f110041000000872f11004300000012000000000000000100000023000000ac2d110058000000952d1100170000007d2d11001800000012000000000000000100000022000000382c11001f0000005431130000000000572c11003d000000942c110040000000d42c1100250000005431130000000000f92c11003b000000342d110042000000762d1100070000005665633c7363686e6f72726b656c3a3a52616e646f6d6e6573733e001200000000000000010000003f000000f32b1100450000004d6179626552616e646f6d6e65737300120000000000000001000000230000006c2b110040000000ac2b110047000000120000000000000001000000230000007b2a110057000000d22a110054000000262b1100460000001200000000000000010000005b000000212911005700000078291100050000007d29110052000000cf29110056000000252a110056000000362811003600000054311300000000006c28110045000000b128110044000000f52811002c0000004261626545706f6368436f6e66696775726174696f6e000012000000000000000100000023000000d527110061000000502711004b0000009b2711003a0000002054686520636f6e66696775726174696f6e20666f7220746865206e6578742065706f63682c20604e6f6e65602069662074686520636f6e6669672077696c6c206e6f74206368616e67652028796f752063616e2066616c6c6261636b20746f206045706f6368436f6e6669676020696e737465616420696e20746861742063617365292e2054686520636f6e66696775726174696f6e20666f72207468652063757272656e742065706f63682e2053686f756c64206e6576657220626520604e6f6e656020617320697420697320696e697469616c697a656420696e2067656e657369732e20486f77206c617465207468652063757272656e7420626c6f636b20697320636f6d706172656420746f2069747320706172656e742e205468697320656e74727920697320706f70756c617465642061732070617274206f6620626c6f636b20657865637574696f6e20616e6420697320636c65616e6564207570206f6e20626c6f636b2066696e616c697a6174696f6e2e205175657279696e6720746869732073746f7261676520656e747279206f757473696465206f6620626c6f636b20657865637574696f6e20636f6e746578742073686f756c6420616c77617973207969656c64207a65726f2e2054686520626c6f636b206e756d62657273207768656e20746865206c61737420616e642063757272656e742065706f6368206861766520737461727465642c20726573706563746976656c7920604e2d316020616e6420604e602e204e4f54453a20576520747261636b207468697320697320696e206f7264657220746f20616e6e6f746174652074686520626c6f636b206e756d626572207768656e206120676976656e20706f6f6c206f6620656e74726f7079207761732066697865642028692e652e20697420776173206b6e6f776e20746f20636861696e206f6273657276657273292e2053696e63652065706f6368732061726520646566696e656420696e20736c6f74732c207768696368206d617920626520736b69707065642c2074686520626c6f636b206e756d62657273206d6179206e6f74206c696e6520757020776974682074686520736c6f74206e756d626572732e2054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e29207468617420696e636c756465732074686520565246206f75747075742067656e657261746564206174207468697320626c6f636b2e2054686973206669656c642073686f756c6420616c7761797320626520706f70756c6174656420647572696e6720626c6f636b2070726f63657373696e6720756e6c657373207365636f6e6461727920706c61696e20736c6f74732061726520656e61626c65642028776869636820646f6e277420636f6e7461696e206120565246206f7574707574292e2054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d6560206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e2054574f582d4e4f54453a20605365676d656e74496e6465786020697320616e20696e6372656173696e6720696e74656765722c20736f2074686973206973206f6b61792e2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e205765206d616b6520612074726164656f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e2057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f2060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e20576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572792065706f63682e204e6578742065706f636820617574686f7269746965732e204e6578742065706f63682072616e646f6d6e6573732e2050656e64696e672065706f636820636f6e66696775726174696f6e206368616e676520746861742077696c6c206265206170706c696564207768656e20746865206e6578742065706f636820697320656e61637465642e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2043757272656e7420736c6f74206e756d6265722e2054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e2054686973206973203020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e00000000000000e43011000d00000000000000e8f21200030000000000000054311300f43011000000000000000000043111000300000000000000000000001c31110011000000000000003347120009000000000000005431130030311100000000000000000040311100050000000000000045706f63684475726174696f6e0000001200000000000000010000005c000000983211003b000000d33211004600000019331100480000004578706563746564426c6f636b54696d650000001200000000000000010000005d0000006831110041000000a931110044000000ed311100410000002e32110042000000703211002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e2054686520616d6f756e74206f662074696d652c20696e20736c6f74732c207468617420656163682065706f63682073686f756c64206c6173742e204e4f54453a2043757272656e746c79206974206973206e6f7420706f737369626c6520746f206368616e6765207468652065706f6368206475726174696f6e2061667465722074686520636861696e2068617320737461727465642e20417474656d7074696e6720746f20646f20736f2077696c6c20627269636b20626c6f636b2070726f64756374696f6e2e0000007c18110057000000b300000001000000546172676574426c6f636b4e756d626572496e506173744e6f74466f756e644661696c6564546f5363686564756c6552657363686564756c654e6f4368616e676500000000000000a8fc11000800000000000000c0341100040000000000000000000000203511000a000000000000000000000070351100060000000000000078351100020000000000000000000000a83511000a0000000000000000000000f83511000e0000000000000008361100050000000000000000000000803611000a0000000000000000000000d03611000c00000000000000dc361100010000000000000000000000f43611000a0000000000000000000000443711000e0000000000000054371100040000000000000000000000b4371100050000000000000000000000dc3711001400000000000000f037110005000000000000000000000068381100050000000000000000000000e93a11000400000000000000a9f912000e00000000000000d83811000e00000000000000e638110028000000000000000e3911000800000000000000163911001200000000000000a80e13000400000000000000ac0e1300180000004b3b11001d0000005431130000000000f2eb12000b0000008839110028000000683b110024000000c0ef12000d000000383b1100130000008c3b110014000000a03b11004f00000036ec12000c00000063616e63656c000000000000e93a11000400000000000000a9f912000e00000000000000a00e13000500000000000000cbed120003000000ed3a1100260000005431130000000000f2eb12000b0000008839110028000000133b110025000000c0ef12000d000000383b110013000000f03911001c0000000c3a11005000000036ec12000c0000007363686564756c655f6e616d6564000000000000d1381100020000000000000042ec12000700000000000000e93a11000400000000000000a9f912000e00000000000000d83811000e00000000000000e638110028000000000000000e3911000800000000000000163911001200000000000000a80e13000400000000000000ac0e1300180000005c3a1100170000005431130000000000f2eb12000b0000008839110028000000733a110023000000c0ef12000d000000d53911001b000000f03911001c000000963a11005300000036ec12000c00000063616e63656c5f6e616d656400000000d1381100020000000000000042ec120007000000693911001f0000005431130000000000f2eb12000b0000008839110028000000b039110025000000c0ef12000d000000d53911001b000000f03911001c0000000c3a11005000000036ec12000c0000007363686564756c655f6166746572000000000000d33811000500000000000000a9f912000e00000000000000d83811000e00000000000000e638110028000000000000000e3911000800000000000000163911001200000000000000a80e13000400000000000000ac0e130018000000283911002b0000005431130000000000f2eb12000b000000533911001600000036ec12000c0000007363686564756c655f6e616d65645f616674657200000000d1381100020000000000000042ec12000700000000000000d33811000500000000000000a9f912000e00000000000000d83811000e00000000000000e638110028000000000000000e3911000800000000000000163911001200000000000000a80e13000400000000000000ac0e13001800000090381100250000005431130000000000f2eb12000b000000b53811001c00000036ec12000c000000205363686564756c652061206e616d6564207461736b20616674657220612064656c61792e2053616d65206173205b607363686564756c655f6e616d6564605d2e696461667465726d617962655f706572696f6469634f7074696f6e3c7363686564756c653a3a506572696f643c543a3a426c6f636b4e756d6265723e3e7072696f726974797363686564756c653a3a5072696f7269747920416e6f6e796d6f75736c79207363686564756c652061207461736b20616674657220612064656c61792e2053616d65206173205b607363686564756c65605d2e2043616e63656c2061206e616d6564207363686564756c6564207461736b2e202d2053203d204e756d626572206f6620616c7265616479207363686564756c65642063616c6c73202d2042617365205765696768743a2032342e3931202b20322e393037202a205320c2b57320202020202d20526561643a204167656e64612c204c6f6f6b757020202020202d2057726974653a204167656e64612c204c6f6f6b7570202d2057696c6c20757365206261736520776569676874206f66203130302077686963682073686f756c6420626520676f6f6420666f7220757020746f203330207363686564756c65642063616c6c73205363686564756c652061206e616d6564207461736b2e202d2042617365205765696768743a2032392e36202b202e313539202a205320c2b573202d2057696c6c20757365206261736520776569676874206f662033352077686963682073686f756c6420626520676f6f6420666f72206d6f7265207468616e203330207363686564756c65642063616c6c737768656e2043616e63656c20616e20616e6f6e796d6f75736c79207363686564756c6564207461736b2e202d2042617365205765696768743a2032322e3135202b20322e383639202a205320c2b57320202020202d20526561643a204167656e646120416e6f6e796d6f75736c79207363686564756c652061207461736b2e202d2042617365205765696768743a2032322e3239202b202e313236202a205320c2b57320202020202d2057726974653a204167656e6461202d2057696c6c20757365206261736520776569676874206f662032352077686963682073686f756c6420626520676f6f6420666f7220757020746f203330207363686564756c65642063616c6c730000000000d3181100060000000105000000000000a9f912000e00000000000000f83c11005c0000000000000000000000000000000000000054311300543d11000000000000000000643d1100010000000000000001000000000000006518110006000000010500000000000042ec120007000000000000006c3d11001b0000000000000000000000000000000000000054311300883d11000000000000000000983d1100010000000000000000000000000000009cbe12000e0000000000000000000000aabe1200080000000000000000000000000000000000000000000000000000000000000054311300a03d11000000000000000000c4be12000300000000000000010000005665633c4f7074696f6e3c5363686564756c65643c3c5420617320436f6e6669673e3a3a43616c6c2c20543a3a426c6f636b4e756d6265722c20543a3a0a50616c6c6574734f726967696e2c20543a3a4163636f756e7449643e3e3e1200000000000000010000003f000000f03d1100530000005461736b416464726573733c543a3a426c6f636b4e756d6265723e0012000000000000000100000023000000b03d1100400000001200000000000000010000005e000000204c6f6f6b75702066726f6d206964656e7469747920746f2074686520626c6f636b206e756d62657220616e6420696e646578206f6620746865207461736b2e204974656d7320746f2062652065786563757465642c20696e64657865642062792074686520626c6f636b206e756d626572207468617420746865792073686f756c64206265206578656375746564206f6e2e0000000000c83e11000900000000000000d43e1100020000000000000000000000e43e1100010000000000000000000000ec3e11000800000000000000d43e1100020000000000000000000000f43e1100010000000000000000000000fc3e11000a00000000000000083f1100030000000000000000000000203f110001000000000000005363686564756c656400000085d312000b000000cbed1200030000009e3f11002500000043616e63656c65647a3f110024000000446973706174636865640000533f1100180000006b3f11000f000000637a12000e000000283f11002b000000204469737061746368656420736f6d65207461736b2e205c5b7461736b2c2069642c20726573756c745c5d5461736b416464726573733c426c6f636b4e756d6265723e4f7074696f6e3c5665633c75383e3e2043616e63656c656420736f6d65207461736b2e205c5b7768656e2c20696e6465785c5d205363686564756c656420736f6d65207461736b2e205c5b7768656e2c20696e6465785c5d00120000000000000001000000210000000440110061000000ab010000290000001200000000000000010000005f0000000440110061000000ae010000340000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f6e706f732d656c656374696f6e732f7372632f6c69622e7273766563746f72207769746820706f736974697665206c656e6774682077696c6c20686176652061206d61783b20716564000000dc7c120067000000780000000e0000006974657261746f72207769746820706f736974697665206c656e6774682077696c6c20686176652061206d696e3b207165640000dc7c1200670000007c0000000e000000dc7c120067000000890000002c000000dc7c120067000000950000002b0000006c656e677468206f6620656c65637465645f65646765732069732067726561746572207468616e206f7220657175616c20323b206c6173745f696e64657820696e64657820697320617420746865206d696e696d756d20656c65637465645f65646765732e6c656e2829202d20313b20696e6465782069732077697468696e2072616e67653b207165640000dc7c1200670000009f00000034000000dc7c120067000000a200000011000000dc7c120067000000ac0000002c000000dc7c120067000000b80000002c000000dc7c12006700000055000000210000000440110061000000a30100002c000000dc7c1200670000006d0000002200000004401100610000002303000025000000044011006100000023030000360000000440110061000000290300002f00000000000000933311001000000000000000a84211000100000000000000000000008b3311000800000000000000b0421100010000000000000000000000743311001700000000000000b8421100010000000000000000000000a33311001200000000000000c042110001000000000000004f4311001a0000002f43110020000000054311002a000000c84211003d0000002052657363686564756c65206661696c6564206265636175736520697420646f6573206e6f74206368616e6765207363686564756c65642074696d652e20476976656e2074617267657420626c6f636b206e756d62657220697320696e2074686520706173742e2043616e6e6f742066696e6420746865207363686564756c65642063616c6c2e204661696c656420746f207363686564756c6520612063616c6c000000000000005f2e12001800000000000000d04d1200010000000000000000000000772e12001800000000000000c84d1200010000000000000000000000ba2e12001600000000000000d84d1200010000000000000050726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b207165640000284411005c0000005701000011000000844411003d0000000000000000000000284411005c0000005e010000110000002f636172676f2d686f6d652f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d322e302e302f7372632f636f6d706163742e7273736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b20716564000000284411005c00000083010000110000000000000000000000000000000000000000000000284411005c0000008a01000011000000084511005c00000034000000120000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f72756e74696d652f7372632f63757276652e72734368617267655472616e73616374696f6e5061796d656e7444656665727265644f6666656e63657345706f6368436f6e6669674e65787452616e646f6d6e657373417574686f72697469657345706f636853746172744e657874417574686f72697469657343757272656e74536c6f744e65787445706f6368436f6e66696747656e65736973536c6f745365676d656e74496e64657845706f6368496e646578417574686f7256726652616e646f6d6e657373496e697469616c697a65644c6174656e65737350656e64696e6745706f6368436f6e6669674368616e676552616e646f6d6e657373457261456c656374696f6e537461747573536e617073686f7456616c696461746f727351756575656453636f7265517565756564456c6563746564497343757272656e7453657373696f6e46696e616c536e617073686f744e6f6d696e61746f727300000000000010481100070000000105000000000000174811000d000000000000002448110034000000000000000000000000000000000000005431130058481100000000000000000068481100010000000000000000000000000000007c451100100000000000000000000000704811001900000000000000000000000000000000000000000000000000000000000000543113008c48110000000000000000009c48110002000000000000000100000000000000ac481100160000000205050000000000c24811000400000000000000c64811000e00000000000000d4481100120000000000000054311300e84811000000000000000000f84811000100000000000000010000000000000000491100120000000105000000000000c2481100040000000000000042ec1200070000000000000000000000000000000000000054311300144911000000000000000000244911000600000000000000010000005265706f7274735265706f727449644f663c543e4f6666656e636544657461696c733c543a3a4163636f756e7449642c20543a3a4964656e74696669636174696f6e5475706c653e12000000000000000100000060000000274b1100520000005665633c44656665727265644f6666656e63654f663c543e3e00000012000000000000000100000061000000bd4a110059000000164b110011000000436f6e63757272656e745265706f727473496e6465784b696e644f706171756554696d65536c6f745665633c5265706f727449644f663c543e3e000012000000000000000100000062000000734a11004a0000005265706f72747342794b696e64496e64657800001200000000000000010000006300000054491100440000005431130000000000984911002f0000005431130000000000c749110052000000194a11005a00000020456e756d65726174657320616c6c207265706f727473206f662061206b696e6420616c6f6e672077697468207468652074696d6520746865792068617070656e65642e20416c6c207265706f7274732061726520736f72746564206279207468652074696d65206f66206f6666656e63652e204e6f74652074686174207468652061637475616c2074797065206f662074686973206d617070696e6720697320605665633c75383e602c207468697320697320626563617573652076616c756573206f6620646966666572656e7420747970657320617265206e6f7420737570706f7274656420617420746865206d6f6d656e7420736f2077652061726520646f696e6720746865206d616e75616c2073657269616c697a6174696f6e2e204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e204465666572726564207265706f72747320746861742068617665206265656e2072656a656374656420627920746865206f6666656e63652068616e646c657220616e64206e65656420746f206265207375626d69747465642061742061206c617465722074696d652e20546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e696d2d6f6e6c696e653a6f66666c696e6772616e6470613a65717569766f6361626162653a65717569766f636174696f000000000000005c4c11001100000000000000000000006d4c11000a0000000000000000000000000000000000000000000000000000000000000054311300784c1100000000000000000054311300000000000000000001000000000000009cbe12000e0000000000000000000000aabe1200080000000000000000000000000000000000000000000000000000000000000054311300884c11000000000000000000543113000000000000000000010000004e6578744665654d756c7469706c6965724d756c7469706c69657200120000000000000001000000640000001200000000000000010000005e00000000000000084d1100120000000000000057a912000c00000000000000543113001c4d110000000000000000002c4d1100010000000000000000000000344d11000b000000000000003f4d1100290000000000000054311300684d11000000000000000000784d110001000000000000005472616e73616374696f6e42797465466565000012000000000000000100000065000000c34d110043000000576569676874546f4665655665633c576569676874546f466565436f656666696369656e743c42616c616e63654f663c543e3e3e12000000000000000100000066000000804d1100430000002054686520706f6c796e6f6d69616c2074686174206973206170706c69656420696e206f7264657220746f20646572697665206665652066726f6d207765696768742e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e0000184e11005600000074000000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f6f6666656e6365732f7372632f6c69622e7273000012000000000000000100000021000000dc7c120067000000650000001e000000984e11001a0000004552524f523a20436f7272757074656420737461746520617420457261735374616b657273000000647c1200660000006c0000001d000000647c1200660000006c00000039000000647c120066000000a70000001f00000056616c696461746f72730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000784f11005d00000021020000330000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f737570706f72742f7372632f73746f726167652f6d6f642e7273436865636b576569676874426164206d616e6461746f727945726173526577617264506f696e747356616c696461746f72536c617368496e4572614e6f6d696e61746f72536c617368496e4572615370616e536c617368536c617368696e675370616e73546f6f4d616e79546172676574734261645374617465496e636f7272656374536c617368696e675370616e73496e636f7272656374486973746f72794465707468416c7265616479436c61696d65644e6f74536f72746564416e64556e69717565496e76616c69644e756d6265724f664e6f6d696e6174696f6e73496e76616c6964457261546f52657761726446756e6465645461726765744e6f556e6c6f636b4368756e6b4e6f4d6f72654368756e6b73496e73756666696369656e7456616c7565496e76616c6964536c617368496e6465784475706c6963617465496e646578456d70747954617267657473416c7265616479506169726564416c7265616479426f6e6465644e6f7453746173684e6f74436f6e74726f6c6c65724261645461726765744e6f6d696e61746f72734c6564676572000000000064551100040000000000000068551100030000000000000000000000b0551100160000000000000000000000605611000a000000000000006c561100010000000000000000000000845611001500000000000000000000002c5711000600000000000000345711000100000000000000000000004c5711002000000000000000000000004c581100110000000000000060581100010000000000000000000000785811001f00000000000000000000007059110008000000000000007859110001000000000000000000000090591100110000000000000000000000185a11000800000000000000205a1100010000000000000000000000385a1100130000000000000000000000d05a1100050000000000000054311300000000000000000000000000d85a1100110000000000000000000000605b110009000000000000006c5b1100010000000000000000000000845b1100100000000000000000000000045c11000e00000000000000145c11000100000000000000000000002c5c1100100000000000000000000000ac5c11001300000000000000c05c1100010000000000000000000000d85c1100080000000000000000000000185d11001800000000000000305d1100010000000000000000000000485d1100070000000000000000000000805d11001500000000000000985d1100010000000000000000000000b05d1100070000000000000000000000e85d11000d0000000000000054311300000000000000000000000000f85d1100090000000000000000000000405e11000d0000000000000054311300000000000000000000000000505e11000a0000000000000000000000a05e11001100000000000000b45e1100010000000000000000000000cc5e11000800000000000000000000000c5f11000d000000000000001c5f11000200000000000000000000004c5f11000a00000000000000000000009c5f1100140000000000000054311300000000000000000000000000b05f1100080000000000000000000000f05f1100150000000000000008601100020000000000000000000000386011000d0000000000000000000000a06011000e00000000000000b0601100020000000000000000000000e06011001c0000000000000000000000c0611100060000000000000034571100010000000000000000000000c86111000e00000000000000000000003862110011000000000000004c6211000200000000000000000000007c621100150000000000000000000000246311000a000000000000001c5f1100020000000000000000000000306311000f0000000000000000000000a86311000400000000000000ac631100010000000000000000000000c46311000d00000000000000626f6e6400000000407911000a0000000000000085fc1100230000000000000048b6120005000000000000004db612001500000000000000a87911000500000000000000ad7911001f000000f4871100590000004d8811002100000054311300000000006e8811004c0000005431130000000000ba88110049000000543113000000000053871100100000005431130000000000f2eb12000b00000003891100350000006387110008000000388911001a00000054311300000000005289110054000000a689110050000000f6891100130000008b7711000d000000c15f12000b000000098a11004c000000558a11003800000036ec12000c000000626f6e645f6578747261000000000000e68711000e000000000000004db61200150000009785110059000000f08511000d0000005431130000000000fd851100540000005186110059000000aa861100130000005431130000000000bd86110058000000158711003e000000543113000000000053871100100000005431130000000000f2eb12000b000000287811003a00000063871100080000000d851100100000006b8711000d000000c15f12000b0000007887110045000000bd8711002900000036ec12000c000000756e626f6e6400000000000048b6120005000000000000004db612001500000028811100550000007d81110040000000bd811100490000005431130000000000068211005200000058821100300000005431130000000000888211004f000000d78211004f000000268311003f00000054311300000000009c64110055000000fe7911004300000054311300000000006583110012000000543113000000000077831100260000005431130000000000f2eb12000b0000009d831100500000006278110026000000ed83110059000000468411005c000000a284110054000000f6841100170000000d85110010000000ba7811000b0000008b7711000d000000c15f12000b0000001d8511004700000064851100290000008d8511000a00000077697468647261775f756e626f6e646564000000000000009d7511001200000000000000cbed120003000000147d11004b00000054311300000000005f7d11004d000000ac7d11001300000054311300000000009c64110055000000fe791100430000005431130000000000bf7d1100130000005431130000000000d27d11001b0000005431130000000000f2eb12000b000000ed7d110055000000427e110051000000937e11003d000000d07e11005e0000008878110032000000756d1100100000002e7f110042000000707f110008000000787f110049000000c17f11002a000000eb7f110006000000f17f11005100000042801100230000006580110054000000b98011002c000000c56811001d000000e58011004300000036ec12000c00000076616c696461746500000000017d11000500000000000000067d11000e000000837c11003a0000005431130000000000656411003700000054311300000000009c64110055000000fe791100430000005431130000000000f2eb12000b000000287811003a00000062781100260000008878110032000000157011000c0000008b7711000d000000c15f12000b000000bd7c110024000000e17c11002000000036ec12000c0000006e6f6d696e617465000000007c7c110007000000000000006366110028000000a17a1100440000005431130000000000e57a110054000000bb6c11002300000054311300000000009c64110055000000fe791100430000005431130000000000f2eb12000b000000397b11004c000000857b110040000000c57b110036000000787911000a000000fb7b11000d000000087c110021000000c15f12000b000000297c1100320000005b7c11002100000036ec12000c0000006368696c6c000000cc791100320000005431130000000000656411003700000054311300000000009c64110055000000fe791100430000005431130000000000f2eb12000b000000287811003a000000417a1100150000008878110032000000567a1100090000008b7711000d000000c15f12000b0000005f7a110022000000817a11002000000036ec12000c0000007365745f706179656500000000000000a87911000500000000000000ad7911001f0000004a7911002e0000005431130000000000656411003700000054311300000000009c641100550000005431130000000000f2eb12000b000000287811003a00000062781100260000008878110032000000787911000a0000004f7411000f000000c0ef12000d0000008279110013000000957911001300000036ec12000c0000007365745f636f6e74726f6c6c6572000000000000407911000a0000000000000085fc110023000000af77110024000000543113000000000065641100370000005431130000000000d3771100550000005431130000000000f2eb12000b000000287811003a00000062781100260000008878110032000000ba7811000b0000008b7711000d000000c15f12000b000000c57811003d000000027911003e00000036ec12000c0000007365745f76616c696461746f725f636f756e740000000000871913000300000000000000d2a012000c000000667711002500000054311300000000002d741100220000005431130000000000f2eb12000b0000008b7711000d000000987711001700000036ec12000c000000696e6372656173655f76616c696461746f725f636f756e74000000005c7711000a00000000000000d2a012000c000000317711002b00000054311300000000002d741100220000005431130000000000f2eb12000b0000000a7711002100000036ec12000c0000007363616c655f76616c696461746f725f636f756e74000000000000002b7711000600000000000000c1ef110007000000d57611003500000054311300000000002d741100220000005431130000000000f2eb12000b0000000a7711002100000036ec12000c000000666f7263655f6e6f5f65726173000000a97611002c00000054311300000000002d741100220000005431130000000000f2eb12000b00000088761100100000004f7411000f0000005e7411001200000036ec12000c000000666f7263655f6e65775f6572610000000d76110053000000607611002800000054311300000000002d741100220000005431130000000000f2eb12000b00000088761100100000004f7411000f000000987611001100000036ec12000c0000007365745f696e76756c6e657261626c657300000000000000007611000d000000000000002c1a130011000000af7511003300000054311300000000002d741100220000005431130000000000f2eb12000b000000e275110007000000e97511001700000036ec12000c000000666f7263655f756e7374616b6500000000000000987511000500000000000000e3f812000c000000000000009d7511001200000000000000cbed120003000000707411004300000054311300000000002d741100220000005431130000000000f2eb12000b000000b37411003b000000ee7411002e0000001c751100610000007d7511001b00000036ec12000c000000666f7263655f6e65775f6572615f616c77617973ec7311004100000054311300000000002d741100220000005431130000000000f2eb12000b0000004f7411000f0000005e7411001200000036ec12000c00000063616e63656c5f64656665727265645f736c617368000000000000008b72110003000000000000008e7211000800000000000000d77311000d00000000000000e47311000800000096721100260000005431130000000000bc7211002d0000005431130000000000e9721100410000005431130000000000f2eb12000b0000002a731100150000003f7311002e0000006d73110035000000a27311001a000000bc7311001b00000036ec12000c0000007061796f75745f7374616b6572730000000000007c7211000f00000000000000e3f812000c000000000000008b72110003000000000000008e72110008000000f36d1100440000005431130000000000376e1100530000008a6e11004a000000d46e11004d0000005431130000000000216f110056000000776f11001e0000005431130000000000956f1100400000005431130000000000f2eb12000b000000d56f110040000000f40d120031000000157011000c0000002170110047000000687011000800000070701100220000009270110031000000c15f12000b000000c37011004a0000000d7111004b00000058711100440000009c711100360000005431130000000000d271110054000000267211005600000036ec12000c0000007265626f6e6400002e6c1100380000005431130000000000666c110055000000bb6c1100230000005431130000000000f2eb12000b000000de6c110035000000136d110025000000386d11003d000000756d110010000000c0ef12000d000000856d110040000000c56d11002e00000036ec12000c0000007365745f686973746f72795f646570746800000000000000fa6b110011000000000000000b6c110011000000000000001c6c11001200000000000000d2a012000c000000e26811004c0000002e691100200000005431130000000000355f12000c0000004e691100440000009269110052000000e469110051000000356a110051000000866a1100280000005431130000000000ae6a1100150000005431130000000000f2eb12000b000000c36a110038000000fb6a11000f000000c0ef12000d0000000a6b110028000000326b11001c0000004e6b11004c0000009a6b11006000000036ec12000c000000726561705f737461736800008b66110058000000e3661100580000003b6711003e0000005431130000000000796711002400000054311300000000009d671100400000005431130000000000f2eb12000b000000dd67110049000000c15f12000b00000026681100360000005c68110069000000c56811001d00000036ec12000c0000006b69636b00000000791b1300030000000000000063661100280000002c641100390000005431130000000000656411003700000054311300000000009c64110055000000f164110052000000436511002600000054311300000000006965110054000000bd651100310000005431130000000000ee65110056000000446611001f0000002052656d6f76652074686520676976656e206e6f6d696e6174696f6e732066726f6d207468652063616c6c696e672076616c696461746f722e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e20416e642c2069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e2054686520636f6e74726f6c6c6572206163636f756e742073686f756c6420726570726573656e7420612076616c696461746f722e202d206077686f603a2041206c697374206f66206e6f6d696e61746f72207374617368206163636f756e74732077686f20617265206e6f6d696e6174696e6720746869732076616c696461746f7220776869636820202073686f756c64206e6f206c6f6e676572206265206e6f6d696e6174696e6720746869732076616c696461746f722e204e6f74653a204d616b696e6720746869732063616c6c206f6e6c79206d616b65732073656e736520696620796f7520666972737420736574207468652076616c696461746f7220707265666572656e63657320746f20626c6f636b20616e792066757274686572206e6f6d696e6174696f6e732e5665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e2052656d6f766520616c6c20646174612073747275637475726520636f6e6365726e696e672061207374616b65722f7374617368206f6e6365206974732062616c616e636520697320617420746865206d696e696d756d2e205468697320697320657373656e7469616c6c79206571756976616c656e7420746f206077697468647261775f756e626f6e64656460206578636570742069742063616e2062652063616c6c656420627920616e796f6e6520616e6420746865207461726765742060737461736860206d7573742068617665206e6f2066756e6473206c656674206265796f6e64207468652045442e20546869732063616e2062652063616c6c65642066726f6d20616e79206f726967696e2e202d20607374617368603a20546865207374617368206163636f756e7420746f20726561702e204974732062616c616e6365206d757374206265207a65726f2e20436f6d706c65786974793a204f285329207768657265205320697320746865206e756d626572206f6620736c617368696e67207370616e73206f6e20746865206163636f756e742e202d2052656164733a205374617368204163636f756e742c20426f6e6465642c20536c617368696e67205370616e732c204c6f636b73202d205772697465733a20426f6e6465642c20536c617368696e67205370616e73202869662053203e2030292c204c65646765722c2050617965652c2056616c696461746f72732c204e6f6d696e61746f72732c205374617368204163636f756e742c204c6f636b73202d2057726974657320456163683a205370616e536c617368202a2053205365742060486973746f72794465707468602076616c75652e20546869732066756e6374696f6e2077696c6c2064656c65746520616e7920686973746f727920696e666f726d6174696f6e207768656e2060486973746f727944657074686020697320726564756365642e202d20606e65775f686973746f72795f6465707468603a20546865206e657720686973746f727920646570746820796f7520776f756c64206c696b6520746f207365742e202d20606572615f6974656d735f64656c65746564603a20546865206e756d626572206f66206974656d7320746861742077696c6c2062652064656c6574656420627920746869732064697370617463682e20202020546869732073686f756c64207265706f727420616c6c207468652073746f72616765206974656d7320746861742077696c6c2062652064656c6574656420627920636c656172696e67206f6c642020202065726120686973746f72792e204e656564656420746f207265706f727420616e2061636375726174652077656967687420666f72207468652064697370617463682e20547275737465642062792020202060526f6f746020746f207265706f727420616e206163637572617465206e756d6265722e204f726967696e206d75737420626520726f6f742e202d20453a204e756d626572206f6620686973746f7279206465707468732072656d6f7665642c20692e652e203130202d3e2037203d2033202d205765696768743a204f28452920202020202d2052656164733a2043757272656e74204572612c20486973746f727920446570746820202020202d205772697465733a20486973746f727920446570746820202020202d20436c6561722050726566697820456163683a20457261205374616b6572732c204572615374616b657273436c69707065642c204572617356616c696461746f72507265667320202020202d2057726974657320456163683a204572617356616c696461746f725265776172642c2045726173526577617264506f696e74732c2045726173546f74616c5374616b652c2045726173537461727453657373696f6e496e6465786e65775f686973746f72795f6465707468436f6d706163743c457261496e6465783e5f6572615f6974656d735f64656c65746564205265626f6e64206120706f7274696f6e206f6620746865207374617368207363686564756c656420746f20626520756e6c6f636b65642e20546865206469737061746368206f726967696e206d757374206265207369676e65642062792074686520636f6e74726f6c6c65722c20616e642069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d2054696d6520636f6d706c65786974793a204f284c292c207768657265204c20697320756e6c6f636b696e67206368756e6b73202d20426f756e64656420627920604d41585f554e4c4f434b494e475f4348554e4b53602e202d2053746f72616765206368616e6765733a2043616e277420696e6372656173652073746f726167652c206f6e6c792064656372656173652069742e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d20202020202d2052656164733a20457261456c656374696f6e5374617475732c204c65646765722c204c6f636b732c205b4f726967696e204163636f756e745d20202020202d205772697465733a205b4f726967696e204163636f756e745d2c204c6f636b732c204c656467657220506179206f757420616c6c20746865207374616b65727320626568696e6420612073696e676c652076616c696461746f7220666f7220612073696e676c65206572612e202d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e205468656972206e6f6d696e61746f72732c20757020746f20202060543a3a4d61784e6f6d696e61746f72526577617264656450657256616c696461746f72602c2077696c6c20616c736f207265636569766520746865697220726577617264732e202d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e20546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966206974206973206e6f74206f6e65206f6620746865207374616b6572732e20546869732063616e206f6e6c792062652063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d2054696d6520636f6d706c65786974793a206174206d6f7374204f284d61784e6f6d696e61746f72526577617264656450657256616c696461746f72292e202d2d2d2d2d2d2d2d2d2d2d204e20697320746865204e756d626572206f66207061796f75747320666f72207468652076616c696461746f722028696e636c7564696e67207468652076616c696461746f7229205765696768743a202d205265776172642044657374696e6174696f6e205374616b65643a204f284e29202d205265776172642044657374696e6174696f6e20436f6e74726f6c6c657220284372656174696e67293a204f284e29202d20526561643a20457261456c656374696f6e5374617475732c2043757272656e744572612c20486973746f727944657074682c204572617356616c696461746f725265776172642c202020202020202020457261735374616b657273436c69707065642c2045726173526577617264506f696e74732c204572617356616c696461746f725072656673202838206974656d7329202d205265616420456163683a20426f6e6465642c204c65646765722c2050617965652c204c6f636b732c2053797374656d204163636f756e74202835206974656d7329202d20577269746520456163683a2053797374656d204163636f756e742c204c6f636b732c204c6564676572202833206974656d73292020204e4f54453a20776569676874732061726520617373756d696e672074686174207061796f75747320617265206d61646520746f20616c697665207374617368206163636f756e7420285374616b6564292e202020506179696e67206576656e2061206465616420636f6e74726f6c6c65722069732063686561706572207765696768742d776973652e20576520646f6e277420646f20616e7920726566756e647320686572652e76616c696461746f725f7374617368657261457261496e6465782043616e63656c20656e6163746d656e74206f66206120646566657272656420736c6173682e2043616e2062652063616c6c6564206279207468652060543a3a536c61736843616e63656c4f726967696e602e20506172616d65746572733a2065726120616e6420696e6469636573206f662074686520736c617368657320666f7220746861742065726120746f206b696c6c2e20436f6d706c65786974793a204f2855202b2053292077697468205520756e6170706c69656420736c6173686573207765696768746564207769746820553d3130303020616e64205320697320746865206e756d626572206f6620736c61736820696e646963657320746f2062652063616e63656c65642e202d20526561643a20556e6170706c69656420536c6173686573202d2057726974653a20556e6170706c69656420536c6173686573736c6173685f696e64696365735665633c7533323e20466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f662073657373696f6e7320696e646566696e6974656c792e20546865206469737061746368206f726967696e206d75737420626520526f6f742e202d205765696768743a204f283129202d2057726974653a20466f72636545726120466f72636520612063757272656e74207374616b657220746f206265636f6d6520636f6d706c6574656c7920756e7374616b65642c20696d6d6564696174656c792e204f285329207768657265205320697320746865206e756d626572206f6620736c617368696e67207370616e7320746f2062652072656d6f7665642052656164733a20426f6e6465642c20536c617368696e67205370616e732c204163636f756e742c204c6f636b73205772697465733a20426f6e6465642c20536c617368696e67205370616e73202869662053203e2030292c204c65646765722c2050617965652c2056616c696461746f72732c204e6f6d696e61746f72732c204163636f756e742c204c6f636b732057726974657320456163683a205370616e536c617368202a205373746173686e756d5f736c617368696e675f7370616e7320536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e202d204f285629202d2057726974653a20496e76756c6e657261626c6573696e76756c6e657261626c657320466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c20626520726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e202d204e6f20617267756d656e74732e202d20577269746520466f72636545726120466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e205363616c652075702074686520696465616c206e756d626572206f662076616c696461746f7273206279206120666163746f722e2053616d65206173205b607365745f76616c696461746f725f636f756e74605d2e666163746f7220496e6372656d656e74732074686520696465616c206e756d626572206f662076616c696461746f72732e6164646974696f6e616c20536574732074686520696465616c206e756d626572206f662076616c696461746f72732e205765696768743a204f2831292057726974653a2056616c696461746f7220436f756e74202852652d297365742074686520636f6e74726f6c6c6572206f6620612073746173682e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e202d2d2d2d2d2d2d2d2d2d202d20526561643a20426f6e6465642c204c6564676572204e657720436f6e74726f6c6c65722c204c6564676572204f6c6420436f6e74726f6c6c6572202d2057726974653a20426f6e6465642c204c6564676572204e657720436f6e74726f6c6c65722c204c6564676572204f6c6420436f6e74726f6c6c6572636f6e74726f6c6c6572202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e202d2d2d2d2d2d2d2d2d20202020202d20526561643a204c656467657220202020202d2057726974653a205061796565706179656552657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e20416e642c2069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d20436f6e7461696e73206f6e6520726561642e202d2d2d2d2d2d2d2d202d20526561643a20457261456c656374696f6e5374617475732c204c6564676572202d2057726974653a2056616c696461746f72732c204e6f6d696e61746f7273204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546869732063616e206f6e6c792062652063616c6c6564207768656e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f662060746172676574736020284e292077686963682069732063617070656420617420436f6d7061637441737369676e6d656e74733a3a4c494d495420284d41585f4e4f4d494e4154494f4e53292e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e205765696768743a204f284e29207768657265204e20697320746865206e756d626572206f662074617267657473202d2052656164733a2045726120456c656374696f6e205374617475732c204c65646765722c2043757272656e7420457261202d205772697465733a2056616c696461746f72732c204e6f6d696e61746f727374617267657473204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e202d20526561643a2045726120456c656374696f6e205374617475732c204c6564676572202d2057726974653a204e6f6d696e61746f72732c2056616c696461746f7273707265667356616c696461746f7250726566732052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e20456d697473206057697468647261776e602e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e20436f6d706c6578697479204f285329207768657265205320697320746865206e756d626572206f6620736c617368696e67207370616e7320746f2072656d6f7665205570646174653a202d2052656164733a20457261456c656374696f6e5374617475732c204c65646765722c2043757272656e74204572612c204c6f636b732c205b4f726967696e204163636f756e745d202d205772697465733a205b4f726967696e204163636f756e745d2c204c6f636b732c204c6564676572204b696c6c3a202d2052656164733a20457261456c656374696f6e5374617475732c204c65646765722c2043757272656e74204572612c20426f6e6465642c20536c617368696e67205370616e732c205b4f726967696e2020204163636f756e745d2c204c6f636b732c2042616c616e63654f66207374617368202d205772697465733a20426f6e6465642c20536c617368696e67205370616e73202869662053203e2030292c204c65646765722c2050617965652c2056616c696461746f72732c204e6f6d696e61746f72732c2020205b4f726967696e204163636f756e745d2c204c6f636b732c2042616c616e63654f662073746173682e204e4f54453a2057656967687420616e6e6f746174696f6e20697320746865206b696c6c207363656e6172696f2c20776520726566756e64206f74686572776973652e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e20456d6974732060556e626f6e646564602e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c6564207669612020206077697468647261775f756e626f6e646564602e202d204f6e6520444220656e7472792e202d20526561643a20457261456c656374696f6e5374617475732c204c65646765722c2043757272656e744572612c204c6f636b732c2042616c616e63654f662053746173682c202d2057726974653a204c6f636b732c204c65646765722c2042616c616e63654f662053746173682c203c2f7765696768743e2041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c657220616e642069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e20456d6974732060426f6e646564602e202d204f2831292e202d2d2d2d2d2d2d2d2d2d2d2d202d20526561643a2045726120456c656374696f6e205374617475732c20426f6e6465642c204c65646765722c205b4f726967696e204163636f756e745d2c204c6f636b73202d2057726974653a205b4f726967696e204163636f756e745d2c204c6f636b732c204c65646765726d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d20526561643a20426f6e6465642c204c65646765722c205b4f726967696e204163636f756e745d2c2043757272656e74204572612c20486973746f72792044657074682c204c6f636b73202d2057726974653a20426f6e6465642c2050617965652c205b4f726967696e204163636f756e745d2c204c6f636b732c204c656467657200000000000000e09411000c0000000000000000000000cbed1200030000000000000000000000000000000000000000000000000000000000000054311300ec9411000000000000000000fc94110007000000000000000100000000000000349511000e0000000000000000000000cbed120003000000000000000000000000000000000000000000000000000000000000005431130044951100000000000000000054951100010000000000000001000000000000005c951100150000000000000000000000cbed120003000000000000000000000000000000000000000000000000000000000000005431130074951100000000000000000084951100010000000000000001000000000000008c9511000d00000000000000000000002c1a13001100000000000000000000000000000000000000000000000000000000000000543113009c9511000000000000000000ac95110003000000000000000100000000000000c4951100060000000105000000000000e3f812000c00000000000000e3f812000c0000000000000000000000000000000000000054311300cc9511000000000000000000dc9511000100000000000000000000000000000069511100060000000102000000000000e3f812000c00000000000000e4951100290000000000000000000000000000000000000054311300109611000000000000000000209611000100000000000000000000000000000028961100050000000105000000000000e3f812000c00000000000000ad7911001f00000000000000000000000000000000000000543113003096110000000000000000004096110001000000000000000100000000000000f04e11000a0000000105000000000000e3f812000c00000000000000067d11000e000000000000000000000000000000000000005431130048961100000000000000000058961100010000000000000001000000000000005f5111000a0000000105000000000000e3f812000c00000000000000609611001900000000000000000000000000000000000000543113007c96110000000000000000008c96110001000000000000000000000000000000949611000a00000000000000000000008e721100080000000000000000000000000000000000000000000000000000000000000054311300a09611000000000000000000b096110004000000000000000000000000000000d0961100090000000000000000000000d99611000d0000000000000000000000000000000000000000000000000000000000000054311300e89611000000000000000000f896110004000000000000000000000000000000189711001500000001050000000000008e7211000800000000000000a03712000c00000000000000000000000000000000000000543113003097110000000000000000004097110004000000000000000000000000000000b24e11000b00000002050500000000008e7211000800000000000000e3f812000c00000000000000609711002400000000000000543113008497110000000000000000009497110006000000000000000100000000000000c49711001200000002050500000000008e7211000800000000000000e3f812000c0000000000000060971100240000000000000054311300d89711000000000000000000e89711000b000000000000000100000000000000409811001200000002050500000000008e7211000800000000000000e3f812000c00000000000000067d11000e000000000000005431130054981100000000000000000064981100050000000000000001000000000000008c9811001300000001050000000000008e721100080000000000000057a912000c0000000000000000000000000000000000000054311300a09811000000000000000000b098110003000000000000000000000000000000ed4f11001000000001050000000000008e7211000800000000000000c89811001d0000000000000000000000000000000000000054311300e89811000000000000000000f898110002000000000000000100000000000000089911000e00000001050000000000008e721100080000000000000057a912000c00000000000000000000000000000000000000543113001899110000000000000000002899110002000000000000000100000000000000389911000800000000000000000000004099110007000000000000000000000000000000000000000000000000000000000000005431130048991100000000000000000058991100010000000000000001000000000000006099110013000000000000000000000055f3120007000000000000000000000000000000000000000000000000000000000000005431130074991100000000000000000084991100030000000000000001000000000000009c99110013000000000000000000000057a912000c0000000000000000000000000000000000000000000000000000000000000054311300b09911000000000000000000c099110002000000000000000100000000000000d09911001000000001050000000000008e7211000800000000000000e09911002f0000000000000000000000000000000000000054311300109a11000000000000000000209a110001000000000000000100000000000000289a11000a0000000000000000000000329a11001d0000000000000000000000000000000000000000000000000000000000000054311300509a11000000000000000000609a110004000000000000000100000000000000fd4f11001300000002050500000000008e7211000800000000000000e3f812000c00000000000000809a1100170000000000000054311300989a11000000000000000000a89a110002000000000000000000000000000000105011001300000002050500000000008e7211000800000000000000e3f812000c0000000000000057a912000c0000000000000054311300b89a11000000000000000000c89a1100010000000000000000000000000000002c5011000d0000000105000000000000e3f812000c00000000000000d09a1100170000000000000000000000000000000000000054311300e89a11000000000000000000f89a11000100000000000000000000000000000023501100090000000105000000000000009b11002300000000000000239b1100220000000000000000000000000000000000000054311300489b11000000000000000000589b110002000000000000000100000000000000689b11001600000000000000000000008e721100080000000000000000000000000000000000000000000000000000000000000054311300809b11000000000000000000909b110001000000000000000000000000000000989b1100150000000000000000000000a03712000c0000000000000000000000000000000000000000000000000000000000000054311300b09b11000000000000000000c09b1100030000000000000001000000000000009cbe12000e0000000000000000000000aabe1200080000000000000000000000000000000000000000000000000000000000000054311300d89b11000000000000000000e89b1100040000000000000001000000486973746f72794465707468120000000000000001000000670000009fa91100230000005431130000000000c2a911004e000000543113000000000010aa11005800000068aa11004e000000b6aa11000c00000056616c696461746f72436f756e7400001200000000000000010000002200000075a911002a0000004d696e696d756d56616c696461746f72436f756e740000001200000000000000010000002200000025a9110050000000496e76756c6e657261626c65730000001200000000000000010000003f00000051a8110056000000a7a8110053000000faa811002b000000426f6e64656400001200000000000000010000002300000011a81100400000005374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00000012000000000000000100000023000000c0a711005100000050617965650000001200000000000000010000005e00000087a71100390000001200000000000000010000006800000036a71100510000004e6f6d696e6174696f6e733c543a3a4163636f756e7449643e00000012000000000000000100000023000000dda611005900000043757272656e744572610000120000000000000001000000230000004da6110017000000543113000000000064a6110059000000bda6110020000000416374697665457261416374697665457261496e666f00001200000000000000010000002300000096a51100360000005431130000000000cca511005600000022a611002b00000045726173537461727453657373696f6e496e64657800000012000000000000000100000023000000b6a411004c000000543113000000000002a51100580000005aa511003c0000004578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e1200000000000000010000006900000098a411001e000000543113000000000038a2110058000000543113000000000090a211002a00000048a4110050000000457261735374616b657273436c6970706564000012000000000000000100000069000000baa21100260000005431130000000000e0a211005600000036a31100370000006da3110047000000b4a311003d0000005431130000000000f1a3110057000000543113000000000090a211002a00000048a41100500000004572617356616c696461746f725072656673000012000000000000000100000068000000f4a1110044000000543113000000000038a2110058000000543113000000000090a211002a0000004572617356616c696461746f7252657761726400120000000000000001000000230000006aa11100420000005431130000000000aca1110048000000457261526577617264506f696e74733c543a3a4163636f756e7449643e0000001200000000000000010000006a000000f6a011002b00000021a111004900000045726173546f74616c5374616b6500001200000000000000010000004100000074a011003b000000afa0110047000000466f726365457261466f7263696e67001200000000000000010000005e0000005fa0110015000000536c6173685265776172644672616374696f6e0012000000000000000100000022000000e89f11003e000000543113000000000026a011003900000043616e63656c6564536c6173685061796f75740012000000000000000100000041000000689f110045000000ad9f11003b000000556e6170706c696564536c61736865735665633c556e6170706c696564536c6173683c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3e001200000000000000010000006b000000379f110031000000426f6e646564457261735665633c28457261496e6465782c2053657373696f6e496e646578293e001200000000000000010000006c0000008d9e1100490000005431130000000000d69e110032000000089f11002f0000002850657262696c6c2c2042616c616e63654f663c543e290012000000000000000100000023000000209e110051000000719e11001c00000012000000000000000100000023000000c89d110058000000736c617368696e673a3a536c617368696e675370616e730012000000000000000100000023000000a59d11002300000028543a3a4163636f756e7449642c20736c617368696e673a3a5370616e496e64657829736c617368696e673a3a5370616e5265636f72643c42616c616e63654f663c543e3e0000001200000000000000010000006d000000289d11004f000000779d11002e0000004561726c69657374556e6170706c696564536c617368000012000000000000000100000023000000e99c11003f00000043757272656e74506c616e6e656453657373696f6e00000012000000000000000100000022000000639c11003a00000054311300000000009d9c11004c0000001200000000000000010000006e000000089c110033000000dcbe12001f00000054311300000000003b9c1100280000002054727565206966206e6574776f726b20686173206265656e20757067726164656420746f20746869732076657273696f6e2e20546869732069732073657420746f2076362e302e3020666f72206e6577206e6574776f726b732e20546865206c61737420706c616e6e65642073657373696f6e207363686564756c6564206279207468652073657373696f6e2070616c6c65742e2054686973206973206261736963616c6c7920696e2073796e632077697468207468652063616c6c20746f205b6053657373696f6e4d616e616765723a3a6e65775f73657373696f6e605d2e20546865206561726c696573742065726120666f72207768696368207765206861766520612070656e64696e672c20756e6170706c69656420736c6173682e205265636f72647320696e666f726d6174696f6e2061626f757420746865206d6178696d756d20736c617368206f6620612073746173682077697468696e206120736c617368696e67207370616e2c2061732077656c6c20617320686f77206d7563682072657761726420686173206265656e2070616964206f75742e20536c617368696e67207370616e7320666f72207374617368206163636f756e74732e20416c6c20736c617368696e67206576656e7473206f6e206e6f6d696e61746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682076616c7565206f6620746865206572612e20416c6c20736c617368696e67206576656e7473206f6e2076616c696461746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682070726f706f7274696f6e20616e6420736c6173682076616c7565206f6620746865206572612e2041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e204d75737420636f6e7461696e7320696e666f726d6174696f6e20666f72206572617320666f72207468652072616e67653a20605b6163746976655f657261202d20626f756e64696e675f6475726174696f6e3b206163746976655f6572615d6020416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e2054686520616d6f756e74206f662063757272656e637920676976656e20746f207265706f7274657273206f66206120736c617368206576656e74207768696368207761732063616e63656c65642062792065787472616f7264696e6172792063697263756d7374616e6365732028652e672e20676f7665726e616e6365292e205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e204d6f6465206f662065726120666f7263696e672e2054686520746f74616c20616d6f756e74207374616b656420666f7220746865206c6173742060484953544f52595f44455054486020657261732e20496620746f74616c206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207374616b652069732072657475726e65642e205265776172647320666f7220746865206c6173742060484953544f52595f44455054486020657261732e20496620726577617264206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207265776172642069732072657475726e65642e2054686520746f74616c2076616c696461746f7220657261207061796f757420666f7220746865206c6173742060484953544f52595f44455054486020657261732e2045726173207468617420686176656e27742066696e697368656420796574206f7220686173206265656e2072656d6f76656420646f65736e27742068617665207265776172642e2053696d696c617220746f2060457261735374616b657273602c207468697320686f6c64732074686520707265666572656e636573206f662076616c696461746f72732e2054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e2049732069742072656d6f7665642061667465722060484953544f52595f44455054486020657261732e20436c6970706564204578706f73757265206f662076616c696461746f72206174206572612e20546869732069732073696d696c617220746f205b60457261735374616b657273605d20627574206e756d626572206f66206e6f6d696e61746f7273206578706f736564206973207265647563656420746f207468652060543a3a4d61784e6f6d696e61746f72526577617264656450657256616c696461746f72602062696767657374207374616b6572732e20284e6f74653a20746865206669656c642060746f74616c6020616e6420606f776e60206f6620746865206578706f737572652072656d61696e7320756e6368616e676564292e2054686973206973207573656420746f206c696d69742074686520692f6f20636f737420666f7220746865206e6f6d696e61746f72207061796f75742e2054686973206973206b657965642066697374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e204578706f73757265206f662076616c696461746f72206174206572612e205468652073657373696f6e20696e646578206174207768696368207468652065726120737461727420666f7220746865206c6173742060484953544f52595f44455054486020657261732e204e6f74653a205468697320747261636b7320746865207374617274696e672073657373696f6e2028692e652e2073657373696f6e20696e646578207768656e20657261207374617274206265696e67206163746976652920666f7220746865206572617320696e20605b43757272656e74457261202d20484953544f52595f44455054482c2043757272656e744572615d602e20546865206163746976652065726120696e666f726d6174696f6e2c20697420686f6c647320696e64657820616e642073746172742e2054686520616374697665206572612069732074686520657261206265696e672063757272656e746c792072657761726465642e2056616c696461746f7220736574206f66207468697320657261206d75737420626520657175616c20746f205b6053657373696f6e496e746572666163653a3a76616c696461746f7273605d2e205468652063757272656e742065726120696e6465782e205468697320697320746865206c617465737420706c616e6e6564206572612c20646570656e64696e67206f6e20686f77207468652053657373696f6e2070616c6c657420717565756573207468652076616c696461746f72207365742c206974206d6967687420626520616374697665206f72206e6f742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e204e756d626572206f66206572617320746f206b65657020696e20686973746f72792e20496e666f726d6174696f6e206973206b65707420666f72206572617320696e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e204d757374206265206d6f7265207468616e20746865206e756d626572206f6620657261732064656c617965642062792073657373696f6e206f74686572776973652e20492e652e2061637469766520657261206d75737420616c7761797320626520696e20686973746f72792e20492e652e20606163746976655f657261203e2063757272656e745f657261202d20686973746f72795f646570746860206d7573742062652067756172616e746565642e000000000000dcab11000e00000000000000a03712000c0000000000000054311300ecab11000000000000000000fcab110001000000000000000000000004ac11000f000000000000008e72110008000000000000005431130014ac1100000000000000000024ac11000100000000000000000000002cac110012000000000000008e72110008000000000000005431130040ac1100000000000000000050ac110005000000000000000000000078ac11002000000000000000cbed120003000000000000005431130098ac11000000000000000000a8ac1100040000000000000000000000c8ac11000e00000000000000cbed1200030000000000000054311300d8ac11000000000000000000e8ac1100010000000000000053657373696f6e7350657245726100001200000000000000010000006f000000feae11001c000000426f6e64696e674475726174696f6e0012000000000000000100000070000000c5ae110039000000536c61736844656665724475726174696f6e000012000000000000000100000071000000fdad11004000000054311300000000003dae11002f0000006cae11004b000000b7ae11000e0000004d61784e6f6d696e61746f72526577617264656450657256616c696461746f72120000000000000001000000720000001dad11003e00000054311300000000005bad11005a000000b5ad1100480000004d61784e6f6d696e6174696f6e73000012000000000000000100000073000000f0ac11002d000000204d6178696d756d206e756d626572206f66206e6f6d696e6174696f6e7320706572206e6f6d696e61746f722e20546865206d6178696d756d206e756d626572206f66206e6f6d696e61746f727320726577617264656420666f7220656163682076616c696461746f722e20466f7220656163682076616c696461746f72206f6e6c79207468652060244d61784e6f6d696e61746f72526577617264656450657256616c696461746f72602062696767657374207374616b6572732063616e20636c61696d207468656972207265776172642e2054686973207573656420746f206c696d69742074686520692f6f20636f737420666f7220746865206e6f6d696e61746f72207061796f75742e204e756d626572206f662065726173207468617420736c6173686573206172652064656665727265642062792c20616674657220636f6d7075746174696f6e2e20546869732073686f756c64206265206c657373207468616e2074686520626f6e64696e67206475726174696f6e2e2053657420746f203020696620736c61736865732073686f756c64206265206170706c69656420696d6d6564696174656c792c20776974686f7574206f70706f7274756e69747920666f7220696e74657276656e74696f6e2e204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e000000000000a8b011000900000000000000b4b01100030000000000000000000000ccb01100030000000000000000000000e4b011000600000000000000c0f51100020000000000000000000000ecb01100010000000000000000000000f4b011000500000000000000c0f51100020000000000000000000000fcb011000200000000000000000000000cb111001a0000000000000028b1110001000000000000000000000030b1110002000000000000000000000040b111000f000000000000005431130000000000000000000000000050b11100010000000000000000000000c49511000600000000000000c0f5110002000000000000000000000058b1110004000000000000000000000078b111000800000000000000c0f5110002000000000000000000000080b1110001000000000000000000000088b111000900000000000000c0f5110002000000000000000000000094b11100020000000000000000000000a4b111000600000000000000bccf1200020000000000000000000000acb1110001000000000000004572615061796f75740000008e72110008000000d5d1120007000000d5d1120007000000aeb411005600000004b511003100000035b511002b00000052657761726400006fb411003f000000536c61736800000010b411004900000059b41100160000004f6c64536c617368696e675265706f72744469736361726465640000a03712000c000000a5b3110047000000ecb31100240000005374616b696e67456c656374696f6e0083b3110022000000b1b21100350000005431130000000000e6b21100540000003ab3110049000000556e626f6e6465647ab211003700000057697468647261776e000000f7b11100570000004eb211002c0000004b69636b65640000b4b11100430000002041206e6f6d696e61746f7220686173206265656e206b69636b65642066726f6d20612076616c696461746f722e205c5b6e6f6d696e61746f722c2073746173685c5d20416e206163636f756e74206861732063616c6c6564206077697468647261775f756e626f6e6465646020616e642072656d6f76656420756e626f6e64696e67206368756e6b7320776f727468206042616c616e6365602066726f6d2074686520756e6c6f636b696e672071756575652e205c5b73746173682c20616d6f756e745c5d20416e206163636f756e742068617320756e626f6e646564207468697320616d6f756e742e205c5b73746173682c20616d6f756e745c5d20416e206163636f756e742068617320626f6e646564207468697320616d6f756e742e205c5b73746173682c20616d6f756e745c5d204e4f54453a2054686973206576656e74206973206f6e6c7920656d6974746564207768656e2066756e64732061726520626f6e64656420766961206120646973706174636861626c652e204e6f7461626c792c2069742077696c6c206e6f7420626520656d697474656420666f72207374616b696e672072657761726473207768656e20746865792061726520616464656420746f207374616b652e2041206e657720736574206f66207374616b6572732077617320656c65637465642e20416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64206e6f742062652070726f6365737365642e205c5b73657373696f6e5f696e6465785c5d204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e205c5b76616c696461746f722c20616d6f756e745c5d20546865207374616b657220686173206265656e207265776172646564206279207468697320616d6f756e742e205c5b73746173682c20616d6f756e745c5d2054686520657261207061796f757420686173206265656e207365743b207468652066697273742062616c616e6365206973207468652076616c696461746f722d7061796f75743b20746865207365636f6e64206973207468652072656d61696e6465722066726f6d20746865206d6178696d756d20616d6f756e74206f66207265776172642e205c5b6572615f696e6465782c2076616c696461746f725f7061796f75742c2072656d61696e6465725c5d566f74657220736e617073686f7420746f6f2062696754617267657420736e617073686f7420746f6f206269674572726f723a2073746172745f73657373696f6e5f696e646578206d7573742062652073657420666f722063757272656e745f6572615761726e696e673a20412073657373696f6e206170706561727320746f2068617665206265656e20736b69707065642e00fc07130055000000940400000100000000000000495111000d0000000000000034b811000100000000000000000000004151110008000000000000003cb81100010000000000000000000000345111000d0000000000000044b81100010000000000000000000000275111000d000000000000004cb811000100000000000000000000001b5111000c0000000000000054b811000100000000000000000000000d5111000e000000000000005cb81100010000000000000000000000fc501100110000000000000064b81100010000000000000000000000eb50110011000000000000006cb81100010000000000000000000000df5011000c0000000000000074b81100010000000000000000000000d25011000d000000000000007cb81100010000000000000000000000c65011000c0000000000000084b81100010000000000000000000000b450110012000000000000008cb811000100000000000000000000009a5011001a0000000000000094b811000100000000000000000000008850110012000000000000009cb811000100000000000000000000007a5011000e00000000000000a4b81100010000000000000000000000655011001500000000000000acb811000100000000000000000000004f5011001600000000000000b4b81100010000000000000000000000475011000800000000000000bcb81100010000000000000000000000395011000e00000000000000c4b81100010000000000000000000000565111000900000000000000ccb811000100000000000000ddbb11001a000000c8bb110015000000afbb11001900000091bb11001e00000078bb11001900000067bb11001100000045bb11002200000012bb110033000000edba110025000000c4ba11002900000091ba1100330000007aba1100170000005bba11001f0000003aba110021000000f7b9110043000000c6b911003100000099b911002d0000004ab911004f00000024b9110026000000d4b81100500000002041206e6f6d696e6174696f6e207461726765742077617320737570706c69656420746861742077617320626c6f636b6564206f72206f7468657277697365206e6f7420612076616c696461746f722e20546f6f206d616e79206e6f6d696e6174696f6e207461726765747320737570706c6965642e20496e7465726e616c20737461746520686173206265636f6d6520736f6d65686f7720636f7272757074656420616e6420746865206f7065726174696f6e2063616e6e6f7420636f6e74696e75652e20496e636f7272656374206e756d626572206f6620736c617368696e67207370616e732070726f76696465642e20496e636f72726563742070726576696f757320686973746f727920646570746820696e7075742070726f76696465642e205265776172647320666f72207468697320657261206861766520616c7265616479206265656e20636c61696d656420666f7220746869732076616c696461746f722e204974656d7320617265206e6f7420736f7274656420616e6420756e697175652e20496e76616c6964206e756d626572206f66206e6f6d696e6174696f6e732e20496e76616c69642065726120746f207265776172642e20417474656d7074696e6720746f2074617267657420612073746173682074686174207374696c6c206861732066756e64732e2043616e206e6f74207265626f6e6420776974686f757420756e6c6f636b696e67206368756e6b732e2043616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b732e2043616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e63652e20536c617368207265636f726420696e646578206f7574206f6620626f756e64732e204475706c696361746520696e6465782e20546172676574732063616e6e6f7420626520656d7074792e20436f6e74726f6c6c657220697320616c7265616479207061697265642e20537461736820697320616c726561647920626f6e6465642e204e6f742061207374617368206163636f756e742e204e6f74206120636f6e74726f6c6c6572206163636f756e742e0012000000000000000100000074000000740000007500000012000000000000000100000074000000760000007500000042616265000000000000000070bc110008000000000000000000000078bc11000f00000000000000000000001e000000000000000000000088bc11000c0000000000000007000000706f6c6b61646f747061726974792d706f6c6b61646f7400df6acb689907609b0300000037e397fc7c91f5e40100000040fe3ad401f8959a04000000d2bc9897eed08f1502000000f78b278be53f454c02000000af2c0297a23e6d3d01000000ed99c5acb25eedf502000000cbca25e39f14238702000000687ad44ad37f03c201000000ab3c0572291feb8b01000000bc9d89904f5b923f0100000037c8bb1350a9a2a8010000006772616e62616265696d6f6e706172616173676e617564690000000040787d018017b42c00e1f505483e332d280479051065b22d80cb0905d88b312e68b0a604b8aeb02ec06a4e0498d12f2ff0c5ff0360f8ae2f70b4b903401b2e30f8477b030842ad30b0a94303e8642c31181e1203c887ab3150f9e502c0a62a32e8a6be02a0c9a932289e9b0268f02833f8657c02780ba833c89860024032273408d147026849a63498c031023070253570151e02408ba43510910c0220ae2336f8f4fc0160c1a236600eef0140e4213780aae20198f3a03748a2d70138f71f38a8cecd0190069f38780cc501a8f61d396040bd01701d9d39204bb601c82c1c3a3019b00190539b3a2093aa0190471a3b50a9a501783f993b3848a10100ca9a3b9838a10150617920444f547320746f2074686520506f6c6b61646f74206163636f756e743a53797374656d5363686564756c657254696d657374616d70496e646963657342616c616e6365735472616e73616374696f6e5061796d656e745374616b696e674f6666656e636573486973746f726963616c4772616e647061417574686f72697479446973636f76657279436f756e63696c546563686e6963616c436f6d6d6974746565456c656374696f6e7350687261676d656e546563686e6963616c4d656d626572736869705574696c6974794964656e7469747950726f78794d756c7469736967426f756e74696573456c656374696f6e50726f76696465724d756c7469506861736500770000002c000000040000007800000078000000790000000000000059be110006000000000000007a000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000007c0000000000000000000000000000007d0000000000000000000000000000007e000000000000000000000000000000000000007421130018000000000000007f000000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000000000000000000000000000000800000000000000000000000000000008000000000000000000000001f000000000000005fbe110009000000000000008100000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000008300000000000000000000000000000080000000000000000000000000000000840000000000000000000000010000000000000028bc110004000000000000008500000000000000000000000000000000000000000000000000000000000000860000000000000000000000020000000000000000000000000000000000000087000000000000000000000000000000880000000000000000000000020000000000000068be1100090000000000000089000000000000000000000000000000000000000000000000000000000000008a000000000000000000000002000000000000000000000000000000000000008b000000000000000000000000000000800000000000000000000000030000000000000071be110007000000000000008c000000000000000000000000000000000000000000000000000000000000008d0000000000000000000000000000008e0000000000000000000000000000008f000000000000000000000000000000800000000000000000000000040000000000000078be110008000000000000009000000000000000000000000000000000000000000000000000000000000000910000000000000000000000000000009200000000000000000000000000000093000000000000000000000000000000940000000000000000000000050000000000000080be1100120000000000000095000000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000000000000000000000000000000960000000000000000000000000000008000000000000000000000002000000000000000102d12000a000000000000009700000000000000000000000000000000000000000000000000000000000000980000000000000000000000020000000000000000000000000000000000000080000000000000000000000000000000990000000000000000000000060000000000000092be110007000000000000009a000000000000000000000000000000000000000000000000000000000000009b0000000000000000000000000000009c0000000000000000000000000000009d0000000000000000000000000000009e0000000000000000000000070000000000000099be110008000000000000009f0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000a0000000000000000000000000000000800000000000000000000000000000008000000000000000000000000800000000000000a1be11000a0000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000000000000000000000000000000800000000000000000000000000000008000000000000000000000002100000000000000a08012000700000000000000a100000000000000000000000000000000000000000000000000000000000000a2000000000000000000000000000000a300000000000000000000000000000080000000000000000000000000000000a400000000000000000000000900000000000000abbe11000700000000000000a500000000000000000000000000000000000000000000000000000000000000a6000000000000000000000000000000a700000000000000000000000000000080000000000000000000000000000000a800000000000000000000000b000000000000003e2c12000800000000000000a900000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000ab00000000000000000000000000000080000000000000000000000000000000ac00000000000000000000000c00000000000000b2be1100120000000200000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000200000000000000000000000000000000000000800000000000000000000000000000008000000000000000000000000d000000000000005e8012000900000000000000ad00000000000000000000000000000000000000000000000000000000000000ae000000000000000000000000000000af000000000000000000000000000000b0000000000000000000000000000000b100000000000000000000000e00000000000000c4be11000700000000000000b200000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000b400000000000000000000000000000080000000000000000000000000000000b500000000000000000000000f00000000000000cbbe11001200000000000000b600000000000000000000000000000000000000000000000000000000000000b3000000000000000000000000000000b400000000000000000000000000000080000000000000000000000000000000b500000000000000000000001000000000000000ddbe11001100000000000000b700000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000b9000000000000000000000000000000ba000000000000000000000000000000bb00000000000000000000001100000000000000eebe11001300000000000000bc00000000000000000000000000000000000000000000000000000000000000bd000000000000000000000000000000be000000000000000000000000000000800000000000000000000000000000008000000000000000000000001200000000000000baeb11000800000000000000bf00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000c1000000000000000000000000000000c2000000000000000000000000000000c300000000000000000000001300000000000000b62813000600000000000000c400000000000000000000000000000000000000000000000000000000000000c5000000000000000000000000000000c6000000000000000000000000000000c7000000000000000000000000000000c800000000000000000000001800000000000000bc2d12000700000000000000c900000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000cb000000000000000000000000000000cc000000000000000000000000000000cd0000000000000000000000190000000000000001bf110007000000020000000000000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000000000cf000000000000000000000000000000800000000000000000000000000000008000000000000000000000001a0000000000000008bf11000800000000000000d000000000000000000000000000000000000000000000000000000000000000d1000000000000000000000000000000d2000000000000000000000000000000d3000000000000000000000000000000d400000000000000000000001c0000000000000010bf11000500000000000000d500000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000d7000000000000000000000000000000d8000000000000000000000000000000d900000000000000000000001d0000000000000015bf11000800000000000000da00000000000000000000000000000000000000000000000000000000000000db000000000000000000000000000000dc000000000000000000000000000000dd000000000000000000000000000000de00000000000000000000001e000000000000001dbf11000800000000000000df00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000e1000000000000000000000000000000e2000000000000000000000000000000e30000000000000000000000220000000000000074ec11000400000000000000e400000000000000000000000000000000000000000000000000000000000000e5000000000000000000000000000000e6000000000000000000000000000000e7000000000000000000000000000000e80000000000000000000000230000000000000025bf11001a00000000000000e900000000000000000000000000000000000000000000000000000000000000ea000000000000000000000000000000eb000000000000000000000000000000ec000000000000000000000000000000ed000000000000000000000024000000617373657274696f6e206661696c65643a20656467652e686569676874203d3d2073656c662e686569676874202d203158cd11005b0000007702000009000000617373657274696f6e206661696c65643a20696478203c20434150414349545958cd11005b0000007b020000090000002f72757374632f653337613133636333353934303034363633373338626431386438313030653664623936363663662f6c6962726172792f616c6c6f632f7372632f636f6c6c656374696f6e732f62747265652f6e6f64652e7273617373657274696f6e206661696c65643a2073656c662e686569676874203e203058cd11005b000000d40000000900000058cd11005b0000002b04000016000000617373657274696f6e206661696c65643a207372632e6c656e2829203d3d206473742e6c656e282958cd11005b000000b006000005000000617373657274696f6e206661696c65643a20656467652e686569676874203d3d2073656c662e6e6f64652e686569676874202d203100000058cd11005b000000990300000900000058cd11005b0000006a0400001600000094d011001300000058cd11005b000000a60400001f000000617373657274696f6e206661696c65643a206e65775f6c6566745f6c656e203c3d204341504143495459000058cd11005b000000da04000009000000617373657274696f6e206661696c65643a206f6c645f6c6566745f6c656e202b20636f756e74203c3d204341504143495459000058cd11005b0000008d0500000d000000617373657274696f6e206661696c65643a206f6c645f72696768745f6c656e203e3d20636f756e7458cd11005b0000008e0500000d00000058cd11005b000000be05000016000000617373657274696f6e206661696c65643a206f6c645f72696768745f6c656e202b20636f756e74203c3d2043415041434954590058cd11005b0000004e0500000d000000617373657274696f6e206661696c65643a206f6c645f6c6566745f6c656e203e3d20636f756e740058cd11005b0000004f0500000d00000058cd11005b0000007e05000016000000617373657274696f6e206661696c65643a206d6174636820747261636b5f656467655f696478207b5c6e202020204c6566744f7252696768743a3a4c6566742869647829203d3e20696478203c3d206f6c645f6c6566745f6c656e2c5c6e202020204c6566744f7252696768743a3a52696768742869647829203d3e20696478203c3d2072696768745f6c656e2c5c6e7d00000058cd11005b0000002005000009000000656d70747920696e7465726e616c206e6f6465000000000088d111000e0000000000000098d11100010000000000000000000000a0d111001500000000000000b8d11100010000000000000000000000298212000800000000000000c0d11100010000000000000000000000c8d111001300000000000000dcd11100010000000000000000000000e4d111001200000000000000f8d1110001000000000000000000000000d2110009000000000000000cd2110001000000000000000000000014d2110017000000000000002cd2110001000000000000000000000034d211000b0000000000000040d21100010000000000000056657374696e6742616c616e636500006ad31100270000004c69717569646974795265737472696374696f6e7300000038d31100320000001bd311001d000000496e73756666696369656e7442616c616e636500fdd211001e0000004578697374656e7469616c4465706f7369740000c2d211003b0000004b656570416c6976650000009ed21100240000004578697374696e6756657374696e675363686564756c65006bd2110033000000446561644163636f756e740048d21100230000002042656e6566696369617279206163636f756e74206d757374207072652d657869737420412076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e74205472616e736665722f7061796d656e7420776f756c64206b696c6c206163636f756e742056616c756520746f6f206c6f7720746f20637265617465206163636f756e742064756520746f206578697374656e7469616c206465706f7369742042616c616e636520746f6f206c6f7720746f2073656e642076616c756520476f7420616e206f766572666c6f7720616674657220616464696e67204163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c2056657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c756500000026e3120056000000e20000000f00000079d411001d00000024d4110055000000d10000000f0000007573657220646f6573206e6f74206861766520616e206578697374696e672076657374696e67207363686564756c653b20712e652e642e00120000000c000000040000003700000024d41100550000001e0100001200000024d411005500000045010000120000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f76657374696e672f7372632f6c69622e72735f5f5068616e746f6d4974656d2063616e6e6f7420626520757365642e7061726974792f6d756c74692d70686173652d756e7369676e65642d656c656374696f6e4e6f726d616c2065787472696e73696373206861766520776569676874206c696d697420636f6e666967757265642062792064656661756c743b2071656408d5110020000000780000000a0000002f6275696c642f72756e74696d652f636f6d6d6f6e2f7372632f6c69622e7273f0d71100640000007300000013000000f0d71100640000004800000018000000f0d7110064000000480000002a000000f0d71100640000008a0000001800000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75650054d8110060000000220100002e000000f0d7110064000000b600000019000000f0d71100640000000101000042000000f0d711006400000015010000420000004475706c696361746520766f74657220286f72206f7468657220636f727275707420696e707574292e000000f0d7110064000000360100002100000054d8110060000000d80100002a000000f0d71100640000005901000015000000f0d71100640000005e0100001e00000012000000000000000100000021000000f0d7110064000000610000001a000000f0d7110064000000610000002c000000f0d7110064000000cb01000018000000f0d7110064000000cb01000021000000f0d7110064000000ce01000024000000f0d7110064000000ce01000039000000f0d7110064000000cf01000024000000f0d7110064000000cf01000039000000f0d7110064000000f301000023000000f0d7110064000000f30100002c000000f0d7110064000000f501000024000000f0d7110064000000f501000039000000f0d71100640000001802000035000000f0d71100640000001902000035000000f0d71100640000002202000024000000f0d71100640000002202000039000000f0d71100640000004402000035000000f0d71100640000004502000035000000f0d71100640000005a0200002b000000f0d71100640000005a02000046000000f0d71100640000005b02000028000000f0d71100640000005b02000047000000f0d7110064000000650200002b000000f0d71100640000006502000047000000f0d71100640000006602000028000000f0d711006400000066020000480000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f6e706f732d656c656374696f6e732f7372632f7265647563652e72732f72757374632f653337613133636333353934303034363633373338626431386438313030653664623936363663662f6c6962726172792f616c6c6f632f7372632f636f6c6c656374696f6e732f62747265652f6d61702f656e7472792e72737375626d69745f756e7369676e6564000000000018d911001a0000000000000034d911000100000000000000000000003cd911001b0000000000000058d9110001000000000000000000000060d9110019000000000000007cd91100010000000000000050726544697370617463684561726c795375626d697373696f6e0000ccd911001a000000507265446973706174636857726f6e6757696e6e6572436f756e7400a9d911002300000050726544697370617463685765616b5375626d697373696f6e00000084d9110025000000205375626d697373696f6e2077617320746f6f207765616b2c2073636f72652d776973652e2057726f6e67206e756d626572206f662077696e6e6572732070726573656e7465642e205375626d697373696f6e2077617320746f6f206561726c792e4f6666636861696e456c656374696f6e5374696c6c4f70656e4e6f7446696e646572556e6b6e6f776e546970416c72656164794b6e6f776e526561736f6e546f6f4269675072656d617475726500000000003cdb11000e000000000000004cdb11000200000000000000000000007cdb110013000000000000000000000014dc11000b0000000000000020dc110001000000000000000000000038dc1100130000000000000000000000d0dc11000700000000000000d8dc110003000000000000000000000020dd1100160000000000000000000000d0dd11000300000000000000d4dd110002000000000000000000000004de1100190000000000000000000000ccde1100090000000000000020dc1100010000000000000000000000d8de110011000000000000000000000060df1100090000000000000020dc11000100000000000000000000006cdf11000c000000000000007265706f72745f617765736f6d6500000000000059e81100060000000000000042ec12000700000000000000791b13000300000000000000e3f812000c00000069ea11005700000054311300000000006c0e1300340000005431130000000000c0ea11005500000015eb110030000000543113000000000010e611005800000068e61100170000007fe611003b0000005431130000000000bae611001e0000005431130000000000f2eb12000b00000045eb11003300000078eb1100250000009deb11001d0000003be811001e00000036ec12000c000000726574726163745f7469700000000000c6e511000400000000000000b7f91200070000005fe81100550000005431130000000000b4e81100380000005431130000000000ece811005400000040e911005100000091e911001400000054311300000000005ce1110059000000b5e11100580000005431130000000000a5e91100240000005431130000000000f2eb12000b000000c9e9110015000000dee911003700000015ea11002400000039ea11003000000036ec12000c0000007469705f6e6577000000000059e81100060000000000000042ec12000700000000000000791b13000300000000000000e3f812000c00000000000000cae5110009000000000000004db6120015000000d3e511003d0000005431130000000000fce211005500000051e311001d000000543113000000000010e611005800000068e61100170000007fe611003b000000d4e311005400000028e41100360000005431130000000000bae611001e0000005431130000000000f2eb12000b000000d8e61100550000002de71100300000005de71100420000009fe7110043000000e2e71100390000001be81100200000003be811001e00000036ec12000c0000007469700000000000c6e511000400000000000000b7f912000700000000000000cae5110009000000000000004db6120015000000cfe211002d0000005431130000000000fce211005500000051e311001d00000054311300000000005ce11100590000006ee3110058000000c6e311000e000000d4e311005400000028e411003600000054311300000000005ee4110059000000b7e411000d0000005431130000000000f2eb12000b0000000de2110039000000c4e41100450000007de0110040000000bde0110041000000543113000000000009e511005800000061e511003500000096e511001d000000b3e511001300000036ec12000c000000636c6f73655f746970000000fee011001800000054311300000000006c0e130034000000543113000000000016e111004600000054311300000000005ce1110059000000b5e11100580000005431130000000000f2eb12000b0000000de211003900000046e21100270000007de0110040000000bde01100410000006de211002b00000098e211003700000036ec12000c000000736c6173685f746970000000ccdf1100260000005431130000000000f2df11002b00000054311300000000001de011003e00000054311300000000005be01100220000005431130000000000f2eb12000b0000007de0110040000000bde011004100000036ec12000c0000002052656d6f766520616e6420736c61736820616e20616c72656164792d6f70656e207469702e204d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a52656a6563744f726967696e602e204173206120726573756c742c207468652066696e64657220697320736c617368656420616e6420746865206465706f7369747320617265206c6f73742e20456d6974732060546970536c617368656460206966207375636365737366756c2e202020605460206973206368617267656420617320757070657220626f756e6420676976656e2062792060436f6e7461696e734c656e677468426f756e64602e2020205468652061637475616c20636f737420646570656e6473206f6e2074686520696d706c656d656e746174696f6e206f662060543a3a54697070657273602e20436c6f736520616e64207061796f75742061207469702e2054686520746970206964656e74696669656420627920606861736860206d75737420686176652066696e69736865642069747320636f756e74646f776e20706572696f642e202d206068617368603a20546865206964656e74697479206f6620746865206f70656e2074697020666f722077686963682061207469702076616c7565206973206465636c617265642e205468697320697320666f726d65642020206173207468652068617368206f6620746865207475706c65206f6620746865206f726967696e616c207469702060726561736f6e6020616e64207468652062656e6566696369617279206163636f756e742049442e202d20436f6d706c65786974793a20604f285429602077686572652060546020697320746865206e756d626572206f6620746970706572732e2020206465636f64696e6720605469707065726020766563206f66206c656e677468206054602e202d20446252656164733a206054697073602c206054697070657273602c20607469702066696e64657260202d2044625772697465733a2060526561736f6e73602c206054697073602c206054697070657273602c20607469702066696e64657260204465636c6172652061207469702076616c756520666f7220616e20616c72656164792d6f70656e207469702e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062652061206d656d626572206f662074686520605469707065727360207365742e2020206173207468652068617368206f6620746865207475706c65206f66207468652068617368206f6620746865206f726967696e616c207469702060726561736f6e6020616e64207468652062656e65666963696172792020206163636f756e742049442e202d20607469705f76616c7565603a2054686520616d6f756e74206f66207469702074686174207468652073656e64657220776f756c64206c696b6520746f20676976652e20546865206d656469616e2074697020202076616c7565206f662061637469766520746970706572732077696c6c20626520676976656e20746f20746865206077686f602e20456d6974732060546970436c6f73696e676020696620746865207468726573686f6c64206f66207469707065727320686173206265656e207265616368656420616e642074686520636f756e74646f776e20706572696f642068617320737461727465642e2020206465636f64696e6720605469707065726020766563206f66206c656e677468206054602c20696e736572742074697020616e6420636865636b20636c6f73696e672c20202041637475616c6c792077656967687420636f756c64206265206c6f77657220617320697420646570656e6473206f6e20686f77206d616e7920746970732061726520696e20604f70656e5469706020627574206974202020697320776569676874656420617320696620616c6d6f73742066756c6c20692e65206f66206c656e6774682060542d31602e202d20446252656164733a206054697070657273602c20605469707360202d2044625772697465733a20605469707360686173687469705f76616c7565204769766520612074697020666f7220736f6d657468696e67206e65773b206e6f2066696e6465722773206665652077696c6c2062652074616b656e2e202d2060726561736f6e603a2054686520726561736f6e20666f722c206f7220746865207468696e6720746861742064657365727665732c20746865207469703b2067656e6572616c6c7920746869732077696c6c20626520202061205554462d382d656e636f6465642055524c2e202d206077686f603a20546865206163636f756e742077686963682073686f756c6420626520637265646974656420666f7220746865207469702e20456d69747320604e657754697060206966207375636365737366756c2e202d20436f6d706c65786974793a20604f2852202b2054296020776865726520605260206c656e677468206f662060726561736f6e602c2060546020697320746865206e756d626572206f6620746970706572732e2020202d20604f285429603a206465636f64696e6720605469707065726020766563206f66206c656e677468206054602020202020605460206973206368617267656420617320757070657220626f756e6420676976656e2062792060436f6e7461696e734c656e677468426f756e64602e20202020205468652061637475616c20636f737420646570656e6473206f6e2074686520696d706c656d656e746174696f6e206f662060543a3a54697070657273602e2020202d20604f285229603a2068617368696e6720616e6420656e636f64696e67206f6620726561736f6e206f66206c656e67746820605260202d20446252656164733a206054697070657273602c2060526561736f6e7360202d2044625772697465733a2060526561736f6e73602c20605469707360726561736f6e20526574726163742061207072696f72207469702d7265706f72742066726f6d20607265706f72745f617765736f6d65602c20616e642063616e63656c207468652070726f63657373206f662074697070696e672e204966207375636365737366756c2c20746865206f726967696e616c206465706f7369742077696c6c20626520756e72657365727665642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642074686520746970206964656e74696669656420627920606861736860206d7573742068617665206265656e207265706f7274656420627920746865207369676e696e67206163636f756e74207468726f75676820607265706f72745f617765736f6d65602028616e64206e6f74207468726f75676820607469705f6e657760292e20456d697473206054697052657472616374656460206966207375636365737366756c2e202d20436f6d706c65786974793a20604f283129602020202d20446570656e6473206f6e20746865206c656e677468206f662060543a3a48617368602077686963682069732066697865642e202d20446252656164733a206054697073602c20606f726967696e206163636f756e7460202d2044625772697465733a2060526561736f6e73602c206054697073602c20606f726967696e206163636f756e7460205265706f727420736f6d657468696e672060726561736f6e60207468617420646573657276657320612074697020616e6420636c61696d20616e79206576656e7475616c207468652066696e6465722773206665652e205061796d656e743a20605469705265706f72744465706f73697442617365602077696c6c2062652072657365727665642066726f6d20746865206f726967696e206163636f756e742c2061732077656c6c2061732060446174614465706f736974506572427974656020666f722065616368206279746520696e2060726561736f6e602e202d20436f6d706c65786974793a20604f2852296020776865726520605260206c656e677468206f662060726561736f6e602e2020202d20656e636f64696e6720616e642068617368696e67206f662027726561736f6e27202d20446252656164733a2060526561736f6e73602c20605469707360547265617375727900000000000074ec1100040000000105000000000000b7f91200070000000000000078ec11003c0000000000000000000000000000000000000054311300b4ec11000000000000000000c4ec110003000000000000000000000000000000dcec1100070000000106000000000000b7f91200070000000000000042ec1200070000000000000000000000000000000000000054311300e4ec11000000000000000000f4ec1100020000000000000000000000546970734f70656e5469703c543a3a4163636f756e7449642c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265722c20543a3a486173683e12000000000000000100000023000000aeed11005900000007ee11004f00000056ee110020000000526561736f6e73001200000000000000010000002300000004ed11005200000056ed1100580000002053696d706c6520707265696d616765206c6f6f6b75702066726f6d2074686520726561736f6e2773206861736820746f20746865206f726967696e616c20646174612e20416761696e2c2068617320616e20696e73656375726520656e756d657261626c6520686173682073696e636520746865206b65792069732067756172616e7465656420746f2062652074686520726573756c74206f6620612073656375726520686173682e20546970734d6170207468617420617265206e6f742079657420636f6d706c657465642e204b65796564206279207468652068617368206f66206028726561736f6e2c2077686f29602066726f6d207468652076616c75652e2054686973206861732074686520696e73656375726520656e756d657261626c6520686173682066756e6374696f6e2073696e636520746865206b657920697473656c6620697320616c72656164792067756172616e7465656420746f20626520612073656375726520686173682e00000000000090ef11000c00000000000000a9f912000e00000000000000543113009cef11000000000000000000acef1100010000000000000000000000b4ef11000d00000000000000c1ef1100070000000000000054311300c8ef11000000000000000000d8ef1100010000000000000000000000e0ef1100140000000000000057a912000c0000000000000054311300f4ef1100000000000000000004f011000100000000000000000000000cf01100120000000000000057a912000c000000000000005431130020f01100000000000000000030f0110001000000000000000000000038f011001300000000000000cbed12000300000000000000543113004cf0110000000000000000005cf011000100000000000000546970436f756e74646f776e120000000000000001000000ee00000049f111005100000054697046696e6465727346656550657263656e74120000000000000001000000ef000000fdf011004c0000005469705265706f72744465706f7369744261736512000000000000000100000026000000c8f0110035000000446174614465706f7369745065724279746500001200000000000000010000002500000086f01100420000004d6178696d756d526561736f6e4c656e677468001200000000000000010000002b00000064f0110022000000204d6178696d756d2061636365707461626c6520726561736f6e206c656e6774682e2054686520616d6f756e742068656c64206f6e206465706f7369742070657220627974652077697468696e2074686520746970207265706f727420726561736f6e2e2054686520616d6f756e742068656c64206f6e206465706f73697420666f7220706c6163696e67206120746970207265706f72742e2054686520616d6f756e74206f66207468652066696e616c2074697020776869636820676f657320746f20746865206f726967696e616c207265706f72746572206f6620746865207469702e2054686520706572696f6420666f722077686963682061207469702072656d61696e73206f70656e20616674657220697320686173206163686965766564207468726573686f6c6420746970706572732e00000000000078f211000600000000000000e8d0120001000000000000000000000080f2110001000000000000000000000088f211000a00000000000000e8d0120001000000000000000000000094f211000100000000000000000000009cf21100090000000000000020d01200030000000000000000000000a8f21100010000000000000000000000b0f211000c00000000000000e8d01200010000000000000000000000bcf21100010000000000000000000000c4f211000a0000000000000020d01200030000000000000000000000d0f2110001000000000000004e65775469700000cbf3110033000000546970436c6f73696e67000087f3110044000000546970436c6f7365640000004bf311003c00000054697052657472616374656419f3110032000000546970536c61736865640000d8f21100410000002041207469702073756767657374696f6e20686173206265656e20736c61736865642e205c5b7469705f686173682c2066696e6465722c206465706f7369745c5d2041207469702073756767657374696f6e20686173206265656e207265747261637465642e205c5b7469705f686173685c5d2041207469702073756767657374696f6e20686173206265656e20636c6f7365642e205c5b7469705f686173682c2077686f2c207061796f75745c5d2041207469702073756767657374696f6e206861732072656163686564207468726573686f6c6420616e6420697320636c6f73696e672e205c5b7469705f686173685c5d2041206e6577207469702073756767657374696f6e20686173206265656e206f70656e65642e205c5b7469705f686173685c5d496e76616c696420756e7369676e6564207375626d697373696f6e206d7573742070726f6475636520696e76616c696420626c6f636b20616e6420646570726976652076616c696461746f722066726f6d20746865697220617574686f72696e67207265776172642e00c8f411006b000000d70200003b000000c8f411006b000000db0200002b000000c8f411006b000000de0200000d000000c8f411006b000000df0200000d000000120000000c00000004000000f0000000c8f411006b000000e20200004e0000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f656c656374696f6e2d70726f76696465722d6d756c74692d70686173652f7372632f6c69622e72730024d4110055000000c40000000f0000004e6f7456657374696e67416d6f756e744c6f770000000000b0f511000e00000000000000c0f51100020000000000000000000000d0f51100030000000000000000000000e8f511001000000000000000fce41200010000000000000000000000f8f51100010000000000000056657374696e6755706461746564000079e5120009000000d5d112000700000047f61100560000009df6110046000000e3f611001600000056657374696e67436f6d706c6574656400f611004700000020416e205c5b6163636f756e745c5d20686173206265636f6d652066756c6c79207665737465642e204e6f20667572746865722076657374696e672063616e2068617070656e2e2054686520616d6f756e742076657374656420686173206265656e20757064617465642e205468697320636f756c6420696e646963617465206d6f72652066756e64732061726520617661696c61626c652e205468652062616c616e636520676976656e2069732074686520616d6f756e74207768696368206973206c65667420756e7665737465642028616e642074687573206c6f636b6564292e205c5b6163636f756e742c20756e7665737465645c5d00000000000000acf71100040000000000000054311300000000000000000000000000b0f711000d000000000000000000000018f811000a0000000000000024f811000100000000000000000000003cf811000f0000000000000000000000b4f811000f00000000000000c4f81100020000000000000000000000f4f8110010000000000000000000000074f9110015000000000000008cf91100030000000000000000000000d4f91100110000000000000076657374fefe11002f00000054311300000000002dff11005800000034fe11001a00000054311300000000004efe1100350000005431130000000000f2eb12000b000000bcfb11000a00000085ff11001e000000a3ff11003f000000e2ff11004000000036ec12000c000000766573745f6f74686572000000000000739a1200060000000000000085fc110023000000b0fd11002f00000054311300000000006c0e1300340000005431130000000000dffd11005500000034fe11001a00000054311300000000004efe1100350000005431130000000000f2eb12000b000000bcfb11000a000000f3fc11001e00000083fe11003d000000c0fe11003e00000036ec12000c0000007665737465645f7472616e736665720000000000739a1200060000000000000085fc11002300000000000000a8fc11000800000000000000b0fc110029000000d9fc11001a00000054311300000000006c0e1300340000005431130000000000e2fa11004500000027fb11004000000067fb11003d0000005431130000000000a4fb1100180000005431130000000000f2eb12000b000000bcfb11000a000000f3fc11001e00000011fd11004f00000060fd11005000000036ec12000c000000666f7263655f7665737465645f7472616e73666572000000000000007ffc1100060000000000000085fc11002300000000000000739a1200060000000000000085fc11002300000000000000a8fc11000800000000000000b0fc1100290000005cfa110019000000543113000000000075fa1100320000005431130000000000a7fa11003b000000e2fa11004500000027fb11004000000067fb11003d0000005431130000000000a4fb1100180000005431130000000000f2eb12000b000000bcfb11000a000000c6fb11001e000000e4fb11004d00000031fc11004e00000036ec12000c00000020466f726365206120766573746564207472616e736665722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e202d2060736f75726365603a20546865206163636f756e742077686f73652066756e64732073686f756c64206265207472616e736665727265642e202d2060746172676574603a20546865206163636f756e7420746861742073686f756c64206265207472616e7366657272656420746865207665737465642066756e64732e202d2060616d6f756e74603a2054686520616d6f756e74206f662066756e647320746f207472616e7366657220616e642077696c6c206265207665737465642e202d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e20456d697473206056657374696e6743726561746564602e202d20604f283129602e202d2044625765696768743a20342052656164732c20342057726974657320202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e742c20536f75726365204163636f756e7420202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e742c20536f75726365204163636f756e74736f757263653c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263657363686564756c6556657374696e67496e666f3c42616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265723e20437265617465206120766573746564207472616e736665722e202d2044625765696768743a20332052656164732c20332057726974657320202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e742c205b53656e646572204163636f756e745d20202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e742c205b53656e646572204163636f756e745d20556e6c6f636b20616e79207665737465642066756e6473206f662061206074617267657460206163636f756e742e202d2060746172676574603a20546865206163636f756e742077686f7365207665737465642066756e64732073686f756c6420626520756e6c6f636b65642e204d75737420686176652066756e6473207374696c6c206c6f636b656420756e64657220746869732070616c6c65742e20456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e20202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e7420202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e7420556e6c6f636b20616e79207665737465642066756e6473206f66207468652073656e646572206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e6473207374696c6c202d2044625765696768743a20322052656164732c20322057726974657320202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c205b53656e646572204163636f756e745d20202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c205b53656e646572204163636f756e745d000000000000bc2d1200070000000102000000000000e3f812000c00000000000000b0fc11002900000000000000000000000000000000000000543113007c00120000000000000000008c00120001000000000000000000000012000000000000000100000023000000940012003600000020496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e00000000000004011200110000000000000057a912000c00000000000000543113001801120000000000000000002801120001000000000000004d696e5665737465645472616e7366657200000012000000000000000100000045000000300112003a00000020546865206d696e696d756d20616d6f756e74207472616e7366657272656420746f2063616c6c20607665737465645f7472616e73666572602e000000000000cc0212000700000000000000c0f51100020000000000000000000000d4021200010000000000000000000000dc0212000800000000000000c0f51100020000000000000000000000e4021200020000000000000000000000f40212000800000000000000fc021200030000000000000000000000140312000100000000000000000000001c0312000a000000000000002803120003000000000000000000000040031200010000000000000000000000480312000700000000000000c0f5110002000000000000000000000050031200010000000000000000000000580312000800000000000000c0f5110002000000000000000000000060031200010000000000000000000000680312000a00000000000000c0f51100020000000000000000000000740312000100000000000000000000007c031200120000000000000090031200040000000000000000000000b00312000300000000000000456e646f776564003c06120049000000447573744c6f7374b80512005000000008061200340000005472616e7366657279e512000900000079e5120009000000d5d1120007000000900512002800000042616c616e6365536574000079e5120009000000d5d1120007000000d5d11200070000005d051200330000004465706f7369740015051200480000005265736572766564cd04120048000000556e72657365727665640000830412004a000000526573657276655265706174726961746564000079e512000900000079e5120009000000d5d11200070000007d04120006000000c8031200540000001c04120037000000530412002a00000020536f6d652062616c616e636520776173206d6f7665642066726f6d207468652072657365727665206f6620746865206669727374206163636f756e7420746f20746865207365636f6e64206163636f756e742e2046696e616c20617267756d656e7420696e64696361746573207468652064657374696e6174696f6e2062616c616e636520747970652e205c5b66726f6d2c20746f2c2062616c616e63652c2064657374696e6174696f6e5f7374617475735c5d53746174757320536f6d652062616c616e63652077617320756e726573657276656420286d6f7665642066726f6d20726573657276656420746f2066726565292e205c5b77686f2c2076616c75655c5d20536f6d652062616c616e63652077617320726573657276656420286d6f7665642066726f6d206672656520746f207265736572766564292e205c5b77686f2c2076616c75655c5d20536f6d6520616d6f756e7420776173206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e205c5b77686f2c206465706f7369745c5d20412062616c616e6365207761732073657420627920726f6f742e205c5b77686f2c20667265652c2072657365727665645c5d205472616e73666572207375636365656465642e205c5b66726f6d2c20746f2c2076616c75655c5d20416e206163636f756e74207761732072656d6f7665642077686f73652062616c616e636520776173206e6f6e2d7a65726f206275742062656c6f77204578697374656e7469616c4465706f7369742c20726573756c74696e6720696e20616e206f75747269676874206c6f73732e205c5b6163636f756e742c2062616c616e63655c5d20416e206163636f756e74207761732063726561746564207769746820736f6d6520667265652062616c616e63652e205c5b6163636f756e742c20667265655f62616c616e63655c5d0000000000000038071200080000000000000040071200020000000000000000000000700712001b0000000000000000000000480812000b00000000000000540812000300000000000000000000009c0812001200000000000000000000002c0912000e000000000000003c09120003000000000000000000000084091200060000000000000000000000b4091200130000000000000040071200020000000000000000000000c80912000b000000000000007472616e73666572000000005b0c1200040000000000000085fc1100230000000000000048b6120005000000000000005f0c120013000000b70e1200360000005431130000000000ed0e1200420000002f0f120048000000770f120045000000bc0f12002d0000005431130000000000e90f1200460000005431130000000000f2eb12000b0000002f1012004c0000007b10120033000000ae1012005a0000005431130000000000081112001300000054311300000000001b111200540000006f1112004b000000ba11120035000000ef111200580000004712120052000000991212003e000000d712120022000000f9121200510000004a13120037000000811312004500000036ec12000c0000007365745f62616c616e63650000000000791b1300030000000000000085fc11002300000000000000a30e120008000000000000005f0c12001300000000000000ab0e12000c000000000000005f0c120013000000720c1200250000005431130000000000970c120048000000df0c120042000000210d120046000000670d1200400000005431130000000000a70d12002d0000005431130000000000f2eb12000b000000d40d120020000000f40d120031000000250e1200160000003b0e12000f0000004a0e12001a000000640e1200190000007d0e12002600000036ec12000c000000666f7263655f7472616e736665720000000000007ffc1100060000000000000085fc110023000000000000005b0c1200040000000000000085fc1100230000000000000048b6120005000000000000005f0c120013000000880b120054000000dc0b12000b000000f2eb12000b000000e70b120050000000370c12002400000036ec12000c0000007472616e736665725f6b6565705f616c69766500200a120054000000740a1200100000005431130000000000840a12002f0000005431130000000000b30a120031000000f2eb12000b000000e40a12003a0000001e0b120018000000360b1200470000007d0b12000b0000002053616d6520617320746865205b607472616e73666572605d2063616c6c2c206275742077697468206120636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e20393925206f66207468652074696d6520796f752077616e74205b607472616e73666572605d20696e73746561642e205b607472616e73666572605d3a207374727563742e50616c6c65742e68746d6c236d6574686f642e7472616e73666572202d2043686561706572207468616e207472616e736665722062656361757365206163636f756e742063616e6e6f74206265206b696c6c65642e202d2042617365205765696768743a2035312e3420c2b573202d204442205765696768743a2031205265616420616e64203120577269746520746f2064657374202873656e64657220697320696e206f7665726c617920616c72656164792920233c2f7765696768743e2045786163746c7920617320607472616e73666572602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74206d6179206265207370656369666965642e202d2053616d65206173207472616e736665722c20627574206164646974696f6e616c207265616420616e6420777269746520626563617573652074686520736f75726365206163636f756e742069732020206e6f7420617373756d656420746f20626520696e20746865206f7665726c61792e64657374436f6d706163743c543a3a42616c616e63653e20536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e63652028606672616d655f73797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a20202020202d204372656174696e673a2032372e353620c2b57320202020202d204b696c6c696e673a2033352e313120c2b573202d204442205765696768743a203120526561642c203120577269746520746f206077686f606e65775f667265656e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c20747269676765722060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e636564602e2020202d20607472616e736665725f6b6565705f616c6976656020776f726b73207468652073616d652077617920617320607472616e73666572602c206275742068617320616e206164646974696f6e616c2020202020636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a2037332e363420c2b5732c20776f7273742063617365207363656e6172696f20286163636f756e7420637265617465642c206163636f756e742072656d6f76656429202d204442205765696768743a2031205265616420616e64203120577269746520746f2064657374696e6174696f6e206163636f756e74202d204f726967696e206163636f756e7420697320616c726561647920696e206d656d6f72792c20736f206e6f204442206f7065726174696f6e7320666f72207468656d2e000000000000281512000d0000000000000000000000351512000a00000000000000000000000000000000000000000000000000000000000000543113004015120000000000000000005015120001000000000000000100000000000000dcf81200070000000102000000000000e3f812000c0000000000000058151200170000000000000000000000000000000000000054311300701512000000000000000000801512000300000000000000010000000000000070bd1200050000000102000000000000e3f812000c00000000000000981512001c0000000000000000000000000000000000000054311300b41512000000000000000000c4151200020000000000000001000000000000009cbe12000e0000000000000000000000aabe1200080000000000000000000000000000000000000000000000000000000000000054311300d41512000000000000000000e4151200030000000000000001000000546f74616c49737375616e6365543a3a42616c616e6365001200000000000000010000004100000006171200260000004163636f756e74446174613c543a3a42616c616e63653e00120000000000000001000000f10000009b1612001b0000005431130000000000b6161200500000005665633c42616c616e63654c6f636b3c543a3a42616c616e63653e3e120000000000000001000000f2000000241612002e00000052161200490000001200000000000000010000005e000000dcbe12001f0000005431130000000000fc1512002800000020546869732069732073657420746f2076322e302e3020666f72206e6577206e6574776f726b732e20416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e204e4f54453a2053686f756c64206f6e6c79206265206163636573736564207768656e2073657474696e672c206368616e67696e6720616e642066726565696e672061206c6f636b2e205468652062616c616e6365206f6620616e206163636f756e742e204e4f54453a2054686973206973206f6e6c79207573656420696e207468652063617365207468617420746869732070616c6c6574206973207573656420746f2073746f72652062616c616e6365732e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e00000000e4d111001200000000000000351512000a0000000000000054311300641712000000000000000000741712000100000000000000120000000000000001000000260000007c1712003500000020546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e436865636b5370656356657273696f6e000000c8f411006b000000040300000f00000000000000dc1812000e00000000000000ec181200010000000000000000000000f41812000400000000000000000000001419120011000000000000002819120001000000000000000000000030191200020000000000000000000000401912000800000000000000fce4120001000000000000000000000048191200010000000000000000000000501912000700000000000000fce4120001000000000000000000000058191200010000000000000000000000601912001200000000000000741912000100000000000000000000007c19120001000000000000000000000084191200140000000000000074191200010000000000000000000000981912000100000000000000536f6c7574696f6e53746f7265640000dd1b12000f0000001d1b12002e00000054311300000000004b1b1200500000009b1b120042000000456c656374696f6e46696e616c697a6564000000061b120017000000971a120056000000ed1a12001900000052657761726465644d1a12004a000000536c617368656400041a1200490000005369676e65645068617365537461727465640000cbed120003000000d319120031000000556e7369676e6564506861736553746172746564a0191200330000002054686520756e7369676e6564207068617365206f662074686520676976656e20726f756e642068617320737461727465642e20546865207369676e6564207068617365206f662074686520676976656e20726f756e642068617320737461727465642e20416e206163636f756e7420686173206265656e20736c617368656420666f72207375626d697474696e6720616e20696e76616c6964207369676e6564207375626d697373696f6e2e20416e206163636f756e7420686173206265656e20726577617264656420666f72207468656972207369676e6564207375626d697373696f6e206265696e672066696e616c697a65642e2054686520656c656374696f6e20686173206265656e2066696e616c697a65642c20776974682060536f6d6560206f662074686520676976656e20636f6d7075746174696f6e2c206f7220656c73652069662074686520656c656374696f6e206661696c65642c20604e6f6e65602e4f7074696f6e3c456c656374696f6e436f6d707574653e204120736f6c7574696f6e207761732073746f72656420776974682074686520676976656e20636f6d707574652e2049662074686520736f6c7574696f6e206973207369676e65642c2074686973206d65616e732074686174206974206861736e277420796574206265656e2070726f6365737365642e2049662074686520736f6c7574696f6e20697320756e7369676e65642c2074686973206d65616e7320746861742069742068617320616c736f206265656e2070726f6365737365642e456c656374696f6e436f6d7075746500000000b4d811000f00000000000000181c1200020000000000000000000000481c12000e0000000000000000000000301f12000800000000000000381f12001900000000000000511f12000700000000000000581f120016000000b81c12002a0000005431130000000000e21c1200330000005431130000000000151d120050000000651d120056000000bb1d120058000000131e1200110000005431130000000000241e1200570000007b1e120054000000cf1e1200280000005431130000000000f71e120039000000205375626d6974206120736f6c7574696f6e20666f722074686520756e7369676e65642070686173652e20546865206469737061746368206f726967696e20666f20746869732063616c6c206d757374206265205f5f6e6f6e655f5f2e2054686973207375626d697373696f6e20697320636865636b6564206f6e2074686520666c792e204d6f72656f7665722c207468697320756e7369676e656420736f6c7574696f6e206973206f6e6c792076616c696461746564207768656e207375626d697474656420746f2074686520706f6f6c2066726f6d20746865202a2a6c6f63616c2a2a206e6f64652e204566666563746976656c792c2074686973206d65616e732074686174206f6e6c79206163746976652076616c696461746f72732063616e207375626d69742074686973207472616e73616374696f6e207768656e20617574686f72696e67206120626c6f636b202873696d696c617220746f20616e20696e686572656e74292e20546f2070726576656e7420616e7920696e636f727265637420736f6c7574696f6e2028616e642074687573207761737465642074696d652f776569676874292c2074686973207472616e73616374696f6e2077696c6c2070616e69632069662074686520736f6c7574696f6e207375626d6974746564206279207468652076616c696461746f7220697320696e76616c696420696e20616e79207761792c206566666563746976656c792070757474696e6720746865697220617574686f72696e6720726577617264206174207269736b2e204e6f206465706f736974206f7220726577617264206973206173736f63696174656420776974682074686973207375626d697373696f6e2e736f6c7574696f6e526177536f6c7574696f6e3c436f6d706163744f663c543e3e7769746e657373536f6c7574696f6e4f72536e617073686f7453697a6500000000000080211200050000000000000000000000cbed12000300000000000000000000000000000000000000000000000000000000000000543113008821120000000000000000009821120006000000000000000100000000000000c82112000c0000000000000000000000d4211200150000000000000000000000000000000000000000000000000000000000000054311300ec2112000000000000000000fc21120001000000000000000100000000000000042212000e0000000000000000000000122212001b0000000000000000000000000000000000000000000000000000000000000054311300302212000000000000000000402212000100000000000000000000000000000048221200080000000000000000000000502212001b00000000000000000000000000000000000000000000000000000000000000543113006c22120000000000000000007c22120003000000000000000000000000000000942212000e0000000000000000000000cbed1200030000000000000000000000000000000000000000000000000000000000000054311300a42212000000000000000000b422120003000000000000000000000000000000cc221200100000000000000000000000581f1200160000000000000000000000000000000000000000000000000000000000000054311300dc2212000000000000000000ec221200030000000000000000000000526f756e64000000120000000000000001000000f3000000582412002b00000054311300000000008324120055000000d82412001b0000005431130000000000f32412005300000043757272656e74506861736550686173653c543a3a426c6f636b4e756d6265723e0000001200000000000000010000005e000000492412000f000000517565756564536f6c7574696f6e5265616479536f6c7574696f6e3c543a3a4163636f756e7449643e00000012000000000000000100000023000000fa2312004f000000536e617073686f74526f756e64536e617073686f743c543a3a4163636f756e7449643e0012000000000000000100000023000000872312001c0000005431130000000000a3231200570000004465736972656454617267657473000012000000000000000100000023000000542312003300000054311300000000002a2312002a000000536e617073686f744d6574616461746112000000000000000100000023000000042312002600000054311300000000002a2312002a00000020546865206d65746164617461206f6620746865205b60526f756e64536e617073686f74605d204f6e6c7920657869737473207768656e205b60536e617073686f74605d2069732070726573656e742e2044657369726564206e756d626572206f66207461726765747320746f20656c65637420666f72207468697320726f756e642e20536e617073686f742064617461206f662074686520726f756e642e205468697320697320637265617465642061742074686520626567696e6e696e67206f6620746865207369676e656420706861736520616e6420636c65617265642075706f6e2063616c6c696e672060656c656374602e2043757272656e74206265737420736f6c7574696f6e2c207369676e6564206f7220756e7369676e65642c2071756575656420746f2062652072657475726e65642075706f6e2060656c656374602e2043757272656e742070686173652e20496e7465726e616c20636f756e74657220666f7220746865206e756d626572206f6620726f756e64732e20546869732069732075736566756c20666f722064652d6475706c69636174696f6e206f66207472616e73616374696f6e73207375626d697474656420746f2074686520706f6f6c2c20616e642067656e6572616c20646961676e6f7374696373206f66207468652070616c6c65742e2054686973206973206d6572656c7920696e6372656d656e746564206f6e6365207065722065766572792074696d65207468617420616e20757073747265616d2060656c656374602069732063616c6c65642e000000000000f02512000d00000000000000a9f912000e000000000000005431130000261200000000000000000010261200010000000000000000000000182612000b00000000000000a9f912000e0000000000000054311300242612000000000000000000342612000100000000000000000000003c2612001c0000000000000055f31200070000000000000054311300582612000000000000000000682612000200000000000000556e7369676e65645068617365000000120000000000000001000000f400000002271200200000005369676e656450686173650012000000000000000100000022000000e42612001e000000536f6c7574696f6e496d70726f76656d656e745468726573686f6c64120000000000000001000000290000007826120053000000cb2612001900000020546865206d696e696d756d20616d6f756e74206f6620696d70726f76656d656e7420746f2074686520736f6c7574696f6e2073636f7265207468617420646566696e6573206120736f6c7574696f6e2061732022626574746572222028696e20616e79207068617365292e204475726174696f6e206f6620746865207369676e65642070686173652e204475726174696f6e206f662074686520756e7369676e65642070686173652e0000120000000400000004000000f5000000120000000400000004000000f6000000120000000400000004000000f7000000d4e2120052000000c100000001000000a83513005e000000710000002e000000a83513005e0000009000000034000000a83513005e0000006900000034000000000000001eda11000c000000000000003c28120001000000000000000000000012da11000c000000000000004428120001000000000000000000000008da11000a000000000000004c281200010000000000000000000000ffd91100090000000000000054281200010000000000000000000000f6d9110009000000000000005c2812000100000000000000000000002ada11000900000000000000642812000100000000000000882912002200000065291200230000004c291200190000000429120048000000b92812004b0000006c2812004d00000020546865207469702063616e6e6f7420626520636c61696d65642f636c6f73656420626563617573652069742773207374696c6c20696e2074686520636f756e74646f776e20706572696f642e20546865207469702063616e6e6f7420626520636c61696d65642f636c6f736564206265636175736520746865726520617265206e6f7420656e6f7567682074697070657273207965742e20546865206163636f756e7420617474656d7074696e6720746f20726574726163742074686520746970206973206e6f74207468652066696e646572206f6620746865207469702e2054686520746970206861736820697320756e6b6e6f776e2e20546865207469702077617320616c726561647920666f756e642f737461727465642e2054686520726561736f6e20676976656e206973206a75737420746f6f206269672e0000a83513005e000000ba00000009000000a83513005e000000b300000009000000a83513005e000000d400000011000000a83513005e000000d900000009000000d4e2120052000000cd01000018000000d4e2120052000000fb0100001a0000000000000044f511000a00000000000000602a120001000000000000000000000014d211001700000000000000682a12000100000000000000000000004ef511000900000000000000702a12000100000000000000112b120022000000ba2a120057000000782a12004200000020416d6f756e74206265696e67207472616e7366657272656420697320746f6f206c6f7720746f2063726561746520612076657374696e67207363686564756c652e20416e206578697374696e672076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e7420746861742063616e6e6f7420626520636c6f6262657265642e20546865206163636f756e7420676976656e206973206e6f742076657374696e672e54696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b00d42b120057000000c20000000d00000054696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b730000d42b120057000000c40000000d0000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f74696d657374616d702f7372632f6c69622e72737672662d6e6d2d706b436865636b4e6f6e6365496d4f6e6c696e6500000000000000000000617474656d707420746f20646976696465206279207a65726f4b657973417574686f726564426c6f636b732f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f696d2d6f6e6c696e652f7372632f6c69622e727354696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b000000d42b120057000000a70000000d000000417574686f7273686970417574686f724772616e64706146696e616c69747950656e64696e674368616e67653a6772616e6470615f617574686f7269746965735374617465556e636c657348656172746265617441667465720000007b2c1200570000004e020000340000007061726974792f696d2d6f6e6c696e652d6865617274626561742f556e646572436f6e737472756374696f6e50726f78696573416e6e6f756e63656d656e747356657374696e6700d42d120067000000b4000000380000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f737570706f72742f7372632f73746f726167652f67656e657261746f722f6d61702e727300120000000800000004000000f80000004772616e64706145717569766f636174696f6e496e76616c696445717569766f636174696f6e50726f6f66496e76616c69644b65794f776e65727368697050726f6f66546f6f536f6f6e4368616e676550656e64696e67526573756d654661696c656450617573654661696c65644475706c69636174654f6666656e63655265706f727400000000542f12001300000000000000682f1200020000000000000000000000982f1200040000000000000000000000b82f12001c00000000000000682f1200020000000000000000000000d42f12000900000000000000000000001c3012000c00000000000000283012000200000000000000000000005830120007000000000000007265706f72745f65717569766f636174696f6e0000000000203412001200000000000000323412002a000000000000005c3412000f000000000000006b341200100000007432120043000000b73212003e000000f53212003f00000034331200120000007265706f72745f65717569766f636174696f6e5f756e7369676e65647432120043000000b73212003e000000f53212003f0000003433120012000000543113000000000046331200440000008a33120046000000d033120046000000163412000a0000006e6f74655f7374616c6c6564000000001fae12000500000000000000a9f912000e00000000000000593212001b00000000000000a9f912000e0000009030120047000000d73012004a00000021311200480000006931120045000000ae3112004a000000f83112004a0000004232120017000000204e6f74652074686174207468652063757272656e7420617574686f7269747920736574206f6620746865204752414e4450412066696e616c6974792067616467657420686173207374616c6c65642e20546869732077696c6c2074726967676572206120666f7263656420617574686f7269747920736574206368616e67652061742074686520626567696e6e696e67206f6620746865206e6578742073657373696f6e2c20746f20626520656e6163746564206064656c61796020626c6f636b7320616674657220746861742e205468652064656c61792073686f756c64206265206869676820656e6f75676820746f20736166656c7920617373756d6520746861742074686520626c6f636b207369676e616c6c696e672074686520666f72636564206368616e67652077696c6c206e6f742062652072652d6f726765642028652e672e203130303020626c6f636b73292e20546865204752414e44504120766f746572732077696c6c20737461727420746865206e657720617574686f7269747920736574207573696e672074686520676976656e2066696e616c697a656420626c6f636b20617320626173652e204f6e6c792063616c6c61626c6520627920726f6f742e626573745f66696e616c697a65645f626c6f636b5f6e756d626572205265706f727420766f7465722065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c20766572696679207468652065717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f6620616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63652077696c6c206265207265706f727465642e20546869732065787472696e736963206d7573742062652063616c6c656420756e7369676e656420616e642069742069732065787065637465642074686174206f6e6c7920626c6f636b20617574686f72732077696c6c2063616c6c206974202876616c69646174656420696e206056616c6964617465556e7369676e656460292c20617320737563682069662074686520626c6f636b20617574686f7220697320646566696e65642069742077696c6c20626520646566696e6564206173207468652065717569766f636174696f6e207265706f727465722e65717569766f636174696f6e5f70726f6f6645717569766f636174696f6e50726f6f663c543a3a486173682c20543a3a426c6f636b4e756d6265723e6b65795f6f776e65725f70726f6f66543a3a4b65794f776e657250726f6f660000000000502d12000500000000000000000000008c3612001b0000000000000000000000000000000000000000000000000000000000000054311300a83612000000000000000000b8361200010000000000000001000000000000002f2d12000d0000000000000000000000c0361200230000000000000000000000000000000000000000000000000000000000000054311300e43612000000000000000000f436120001000000000000000000000000000000fc3612000a0000000000000000000000a9f912000e0000000000000000000000000000000000000000000000000000000000000054311300083712000000000000000000183712000100000000000000000000000000000020371200070000000000000000000000273712002000000000000000000000000000000000000000000000000000000000000000543113004837120000000000000000005837120001000000000000000000000000000000603712000c00000000000000000000006c3712000500000000000000000000000000000000000000000000000000000000000000543113007437120000000000000000008437120002000000000000000100000000000000943712000c00000001050000000000006c3712000500000000000000a03712000c0000000000000000000000000000000000000054311300ac3712000000000000000000bc37120004000000000000000000000053746f72656453746174653c543a3a426c6f636b4e756d6265723e00120000000000000001000000f9000000863912002400000053746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723e001200000000000000010000002300000055391200310000004e657874466f72636564000012000000000000000100000023000000263912002f0000005374616c6c656428543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d626572290012000000000000000100000023000000023912002400000043757272656e7453657449645365744964000000120000000000000001000000590000007a38120057000000d138120031000000536574496453657373696f6e53657373696f6e496e64657812000000000000000100000023000000dc37120056000000323812001a00000054311300000000004c3812002e0000002041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f7220776869636820697473206d656d62657273207765726520726573706f6e7369626c652e2054574f582d4e4f54453a2060536574496460206973206e6f7420756e646572207573657220636f6e74726f6c2e20546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c69746965732920696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e20607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e496e76616c69644b65794475706c6963617465644865617274626561740000000000f43912000900000000000000003a1200020000000000000000000000303a1200090000000000000068656172746265617400000000000000f43912000900000000000000de3b12001900000000000000f73b12000a00000000000000013c12002f000000f2eb12000b000000783a120050000000c83a120040000000083b1200230000002b3b12002c000000573b12004f000000a63b120017000000bd3b12002100000036ec12000c000000202d20436f6d706c65786974793a20604f284b202b20452960207768657265204b206973206c656e677468206f6620604b6579736020286865617274626561742e76616c696461746f72735f6c656e29202020616e642045206973206c656e677468206f6620606865617274626561742e6e6574776f726b5f73746174652e65787465726e616c5f61646472657373602020202d20604f284b29603a206465636f64696e67206f66206c656e67746820604b602020202d20604f284529603a206465636f64696e672f656e636f64696e67206f66206c656e67746820604560202d20446252656164733a2070616c6c65745f73657373696f6e206056616c696461746f7273602c2070616c6c65745f73657373696f6e206043757272656e74496e646578602c20604b657973602c2020206052656365697665644865617274626561747360202d2044625772697465733a2060526563656976656448656172746265617473604865617274626561743c543a3a426c6f636b4e756d6265723e5f7369676e61747572653c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e6174757265000000005b2d12000e0000000000000000000000a9f912000e0000000000000000000000000000000000000000000000000000000000000054311300903d12000000000000000000a03d12000b000000000000000100000000000000692c1200040000000000000000000000f83d12001300000000000000000000000000000000000000000000000000000000000000543113000c3e120000000000000000001c3e120001000000000000000100000000000000243e1200120000000205050000000000a03712000c00000000000000363e1200090000000000000042ec1200070000000000000054311300403e12000000000000000000503e1200020000000000000000000000000000006d2c12000e0000000205050000000000a03712000c00000000000000603e12000e00000000000000cbed1200030000000000000054311300703e12000000000000000000803e120002000000000000000100000012000000000000000100000022000000973f120047000000de3f1200090000005431130000000000e73f120049000000304012004d0000007d40120046000000c34012002a0000005431130000000000ed4012004e0000003b4112004b00000086411200400000005665633c543a3a417574686f7269747949643e001200000000000000010000003f000000633f12003400000052656365697665644865617274626561747341757468496e6465780012000000000000000100000023000000073f12003c000000433f12002000000056616c696461746f7249643c543e000012000000000000000100000022000000903e120045000000d53e12003200000020466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206056616c696461746f7249643c543e6020746f20746865206e756d626572206f6620626c6f636b7320617574686f7265642062792074686520676976656e20617574686f726974792e20466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206041757468496e6465786020746f20606f6666636861696e3a3a4f70617175654e6574776f726b5374617465602e205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e2054686520626c6f636b206e756d6265722061667465722077686963682069742773206f6b20746f2073656e64206865617274626561747320696e207468652063757272656e742073657373696f6e2e2041742074686520626567696e6e696e67206f6620656163682073657373696f6e20776520736574207468697320746f20612076616c756520746861742073686f756c642066616c6c20726f7567686c7920696e20746865206d6964646c65206f66207468652073657373696f6e206475726174696f6e2e20546865206964656120697320746f206669727374207761697420666f72207468652076616c696461746f727320746f2070726f64756365206120626c6f636b20696e207468652063757272656e742073657373696f6e2c20736f20746861742074686520686561727462656174206c61746572206f6e2077696c6c206e6f74206265206e65636573736172792e20546869732076616c75652077696c6c206f6e6c79206265207573656420617320612066616c6c6261636b206966207765206661696c20746f2067657420612070726f7065722073657373696f6e2070726f677265737320657374696d6174652066726f6d20604e65787453657373696f6e526f746174696f6e602c2061732074686f736520657374696d617465732073686f756c64206265206d6f7265206163637572617465207468656e207468652076616c75652077652063616c63756c61746520666f7220604865617274626561744166746572602e0000000000004c421200110000000000000060421200010000000000000000000000684212000100000000000000000000007042120007000000000000005431130000000000000000000000000078421200010000000000000000000000804212000b000000000000008c4212000100000000000000000000009442120001000000000000004865617274626561745265636569766564000000794312000b0000003843120041000000416c6c476f6f64000343120035000000536f6d654f66666c696e6500eb421200180000009c4212004f0000002041742074686520656e64206f66207468652073657373696f6e2c206174206c65617374206f6e652076616c696461746f722077617320666f756e6420746f206265205c5b6f66666c696e655c5d2e5665633c4964656e74696669636174696f6e5475706c653e2041742074686520656e64206f66207468652073657373696f6e2c206e6f206f6666656e63652077617320636f6d6d69747465642e2041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f72697479496460205c5b617574686f726974795f69645c5d417574686f72697479496400000000b04312000300000000000000b4431200010000000000000000000000cc4312000f0000000000000073657400000000006946120003000000000000006c46120012000000444412001600000054311300000000005a44120056000000b0441200360000005431130000000000e6441200510000003745120011000000543113000000000048451200360000005431130000000000f2eb12000b0000007e4512004d000000cb45120068000000334612003600000036ec12000c00000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e202d20604f2831296020284e6f7465207468617420696d706c656d656e746174696f6e73206f6620604f6e54696d657374616d7053657460206d75737420616c736f20626520604f2831296029202d20312073746f72616765207265616420616e6420312073746f72616765206d75746174696f6e2028636f64656320604f28312960292e202862656361757365206f6620604469645570646174653a3a74616b656020696e20606f6e5f66696e616c697a656029202d2031206576656e742068616e646c657220606f6e5f74696d657374616d705f736574602e204d75737420626520604f283129602e6e6f77436f6d706163743c543a3a4d6f6d656e743e00000000000030471200030000000000000000000000334712000900000000000000000000000000000000000000000000000000000000000000543113003c47120000000000000000004c4712000100000000000000010000000000000054471200090000000000000000000000a1fb1200040000000000000000000000000000000000000000000000000000000000000054311300604712000000000000000000704712000100000000000000010000004e6f77543a3a4d6f6d656e7412000000000000000100000059000000a54712002400000044696455706461746500000012000000000000000100000023000000784712002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e00000000000000044812000d00000000000000334712000900000000000000543113001448120000000000000000002448120004000000000000004d696e696d756d506572696f64000000120000000000000001000000fa000000444812005a0000009e4812005a000000f848120059000000514912001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e556e636c65416c7265616479496e636c75646564546f6f48696768556e636c6547656e65736973556e636c65546f6f4d616e79556e636c6573556e636c6573416c7265616479536574496e76616c6964556e636c65506172656e744f6c64556e636c6500000000fc4912000a00000000000000084a1200010000000000000000000000204a120001000000000000007365745f756e636c6573000000000000414a12000a000000000000004b4a12000e000000284a1200190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e00000000000000552d1200060000000000000000000000644b12003a0000000000000000000000000000000000000000000000000000000000000054311300a04b12000000000000000000b04b1200010000000000000001000000000000001a2d1200060000000000000000000000e3f812000c0000000000000000000000000000000000000000000000000000000000000054311300b84b12000000000000000000c84b120001000000000000000000000000000000d04b12000c0000000000000000000000a1fb1200040000000000000000000000000000000000000000000000000000000000000054311300dc4b12000000000000000000ec4b12000100000000000000010000005665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e0000120000000000000001000000fb0000003c4c12000700000012000000000000000100000023000000234c120019000000446964536574556e636c657312000000000000000100000023000000f44b12002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c6573001200000000000000010000005f000000647c120066000000860000002700000012000000000000000100000021000000647c120066000000a60000001c000000647c1200660000009500000034000000647c120066000000a900000029000000647c120066000000bd0000001f000000647c120066000000c900000030000000c406130055000000f30000000100000000000000af2e12000b00000000000000984d1200020000000000000000000000a32e12000c00000000000000a84d1200020000000000000000000000962e12000d00000000000000b84d12000100000000000000000000008f2e12000700000000000000c04d1200010000000000000000000000772e12001800000000000000c84d12000100000000000000000000005f2e12001800000000000000d04d1200010000000000000000000000ba2e12001600000000000000d84d12000100000000000000994f120042000000db4f12002a0000002b4f120045000000704f120029000000f04e12003b000000c04e120030000000734e12004d000000264e12004d000000e04d120046000000204120676976656e2065717569766f636174696f6e207265706f72742069732076616c69642062757420616c72656164792070726576696f75736c79207265706f727465642e20416e2065717569766f636174696f6e2070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e2041206b6579206f776e6572736869702070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e2043616e6e6f74207369676e616c20666f72636564206368616e676520736f20736f6f6e206166746572206c6173742e20417474656d707420746f207369676e616c204752414e445041206368616e67652077697468206f6e6520616c72656164792070656e64696e672e20417474656d707420746f207369676e616c204752414e44504120726573756d65207768656e2074686520617574686f72697479207365742069736e2774207061757365642028656974686572206c697665206f7220616c72656164792070656e64696e6720726573756d65292e20417474656d707420746f207369676e616c204752414e445041207061757365207768656e2074686520617574686f72697479207365742069736e2774206c697665202865697468657220706175736564206f7220616c72656164792070656e64696e67207061757365292e00000000000000aa3912000a0000000000000040501200010000000000000000000000b4391200130000000000000048501200010000000000000066501200190000005050120016000000204475706c696361746564206865617274626561742e204e6f6e206578697374656e74207075626c6963206b65792e000b2b1300640000003d0500000100000000000000b6491200120000000000000054511200010000000000000000000000a649120010000000000000005c511200010000000000000000000000994912000d00000000000000645112000100000000000000000000008d4912000c000000000000006c511200010000000000000000000000814912000c00000000000000745112000100000000000000000000006d49120014000000000000007c511200010000000000000000000000c84912000800000000000000845112000100000000000000415212002300000020521200210000000f52120011000000f951120016000000d951120020000000ba5112001f0000008c5112002e0000002054686520756e636c652069736e277420726563656e7420656e6f75676820746f20626520696e636c756465642e2054686520756e636c6520697320616c726561647920696e636c756465642e2054686520756e636c6520697320746f6f206869676820696e20636861696e2e2054686520756e636c652069732067656e657369732e20546f6f206d616e7920756e636c65732e20556e636c657320616c72656164792073657420696e2074686520626c6f636b2e2054686520756e636c6520706172656e74206e6f7420696e2074686520636861696e2e4765747320616e64206465636f6465732074696d657374616d7020696e686572656e742064617461fc0000001000000004000000fd000000d42b120057000000d900000012000000bc52120022000000bc030000010000002f6275696c642f72756e74696d652f706f6c6b61646f742f7372632f6c69622e727354696d657374616d7020746f6f2066617220696e2066757475726520746f206163636570745468657265206973206f6e6c79206f6e6520666174616c206572726f723b20716564000000120000000800000004000000fe0000004e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f7221496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473210000db53120007000000c05312001b0000002031130002000000bc52120022000000620400000100000042616420696e70757420646174612070726f766964656420746f2076657273696f6e0000ec5312000d000000657865637574655f626c6f636b0000000454120010000000696e697469616c697a655f626c6f636b1c541200080000006d657461646174612c5412000f0000006170706c795f65787472696e73696300445412000e00000066696e616c697a655f626c6f636b00005c54120013000000696e686572656e745f65787472696e7369637300785412000f000000636865636b5f696e686572656e747300905412000b00000072616e646f6d5f7365656400a45412001400000076616c69646174655f7472616e73616374696f6ec05412000f0000006f6666636861696e5f776f726b657200d85412000a00000076616c696461746f72730000ec5412001000000076616c696461746f725f67726f7570730455120012000000617661696c6162696c6974795f636f726573000020551200190000007065727369737465645f76616c69646174696f6e5f646174610000004455120018000000636865636b5f76616c69646174696f6e5f6f757470757473645512001700000073657373696f6e5f696e6465785f666f725f6368696c6400845512000c00000073657373696f6e5f696e666f985512000f00000076616c69646174696f6e5f636f646500b05512001a000000686973746f726963616c5f76616c69646174696f6e5f636f64650000d45512001e00000063616e6469646174655f70656e64696e675f617661696c6162696c6974790000fc5512001000000063616e6469646174655f6576656e7473145612000c000000646d715f636f6e74656e7473285612001e000000696e626f756e645f68726d705f6368616e6e656c735f636f6e74656e7473000050561200130000006772616e6470615f617574686f726974696573006c5612002d0000007375626d69745f7265706f72745f65717569766f636174696f6e5f756e7369676e65645f65787472696e736963000000a45612001c00000067656e65726174655f6b65795f6f776e6572736869705f70726f6f66c85612000d000000636f6e66696775726174696f6e000000e05612001300000063757272656e745f65706f63685f737461727400fc5612000d00000063757272656e745f65706f6368000000145712000a0000006e6578745f65706f63680000285712000b000000617574686f726974696573003c5712001500000067656e65726174655f73657373696f6e5f6b6579730000005c571200130000006465636f64655f73657373696f6e5f6b65797300785712000d0000006163636f756e745f6e6f6e6365000000905712000a00000071756572795f696e666f0000a45712001100000071756572795f6665655f64657461696c730000001c151300580000001601000001000000496e7374616e636531436f6c6c65637469766550726f706f73616c7350726f706f73616c436f756e7450726f706f73616c4f66566f74696e67496e7374616e636532436f6c6c65637469766557726f6e6750726f706f73616c576569676874416c7265616479496e697469616c697a65644475706c6963617465566f746557726f6e67496e64657857726f6e6750726f706f73616c4c656e67746800000000006c5912000b0000000000000078591200030000000000000000000000c0591200180000000000000000000000805a12000700000000000000885a1200020000000000000000000000b85a12000a0000000000000000000000bc8712000700000000000000085b1200030000000000000000000000505b12001b0000000000000000000000d48812000400000000000000285c1200030000000000000000000000705c12000e0000000000000000000000e05c12000500000000000000e85c1200040000000000000000000000485d12001e0000000000000000000000385e12001300000000000000c88912000100000000000000000000004c5e12000d000000000000007365745f6d656d6265727300000000001c7012000b000000000000002c1a130011000000000000002770120005000000000000002c7012001400000000000000407012000900000000000000497012000b000000526c1200210000005431130000000000736c120052000000c56c120039000000fe6c12004e0000004c6d12002b0000005431130000000000776d12001600000054311300000000008d6d120055000000e26d1200490000005431130000000000f2eb12000b0000009e6312000a0000002b6e120015000000406e120039000000796e120039000000b26e1200270000009464120006000000d96e12005d000000366f12003c000000726f120052000000c46f12005800000036ec12000c00000065786563757465000000000001b512000800000000000000346b12001f00000000000000c16512000c00000000000000d2a012000c000000536b12003d0000005431130000000000906b12002b0000005431130000000000f2eb12000b0000009e6312000a000000bb6b1200610000001c6c120036000000796712000a00000036ec12000c00000000000000176b12000900000000000000206b1200140000000000000001b512000800000000000000346b12001f00000000000000c16512000c00000000000000d2a012000c0000008a6712003f0000005431130000000000c9671200220000005431130000000000eb671200510000003c681200160000005431130000000000f2eb12000b0000009e6312000a000000526812002c000000c663120039000000ff631200380000007e68120032000000b06812003e000000ee6812004000000094641200060000002e6912002e0000005c6912003d000000996912002b000000c469120043000000076a12002f000000366a1200370000006d6a12003a000000a76a120034000000db6a1200300000000b6b12000c00000036ec12000c0000000000000001b512000800000000000000b7f912000700000000000000a00e13000500000000000000876512001600000000000000836712000700000000000000a1fb120004000000cd6512003d00000054311300000000000a6612002400000054311300000000002e66120053000000816612005a000000f2eb12000b0000009e6312000a000000db6612004300000094641200060000001e6712002c0000004a6712002f000000796712000a00000036ec12000c000000636c6f736500000000000000389712000d00000000000000b7f912000700000000000000a00e130005000000000000008765120016000000000000009d6512001500000000000000b26512000f00000000000000c16512000c00000000000000d2a012000c000000076012005400000054311300000000005b601200560000005431130000000000b160120053000000046112003000000054311300000000003461120053000000876112004a0000005431130000000000d1611200590000002a6212005800000054311300000000008262120063000000e5621200590000003e631200600000005431130000000000f2eb12000b0000009e6312000a000000a86312001e000000c663120039000000ff6312003800000037641200330000006a6412002a00000094641200060000009a64120044000000de641200600000003e65120038000000766512001100000036ec12000c000000646973617070726f76655f70726f706f73616c00b45e12005e0000005431130000000000125f1200230000005431130000000000355f12000c000000415f1200480000005431130000000000f2eb12000b000000895f120038000000c15f12000b000000cc5f120013000000df5f12002800000036ec12000c00000020446973617070726f766520612070726f706f73616c2c20636c6f73652c20616e642072656d6f76652069742066726f6d207468652073797374656d2c207265676172646c657373206f66206974732063757272656e742073746174652e204d7573742062652063616c6c65642062792074686520526f6f74206f726967696e2e20506172616d65746572733a202a206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20746861742073686f756c6420626520646973617070726f7665642e20436f6d706c65786974793a204f285029207768657265205020697320746865206e756d626572206f66206d61782070726f706f73616c73204442205765696768743a202a2052656164733a2050726f706f73616c73202a205772697465733a20566f74696e672c2050726f706f73616c732c2050726f706f73616c4f6620436c6f7365206120766f746520746861742069732065697468657220617070726f7665642c20646973617070726f766564206f722077686f736520766f74696e6720706572696f642068617320656e6465642e204d61792062652063616c6c656420627920616e79207369676e6564206163636f756e7420696e206f7264657220746f2066696e69736820766f74696e6720616e6420636c6f7365207468652070726f706f73616c2e2049662063616c6c6564206265666f72652074686520656e64206f662074686520766f74696e6720706572696f642069742077696c6c206f6e6c7920636c6f73652074686520766f74652069662069742069732068617320656e6f75676820766f74657320746f20626520617070726f766564206f7220646973617070726f7665642e2049662063616c6c65642061667465722074686520656e64206f662074686520766f74696e6720706572696f642061627374656e74696f6e732061726520636f756e7465642061732072656a656374696f6e7320756e6c6573732074686572652069732061207072696d65206d656d6265722073657420616e6420746865207072696d65206d656d626572206361737420616e20617070726f76616c2e2049662074686520636c6f7365206f7065726174696f6e20636f6d706c65746573207375636365737366756c6c79207769746820646973617070726f76616c2c20746865207472616e73616374696f6e206665652077696c6c206265207761697665642e204f746865727769736520657865637574696f6e206f662074686520617070726f766564206f7065726174696f6e2077696c6c206265206368617267656420746f207468652063616c6c65722e202b206070726f706f73616c5f7765696768745f626f756e64603a20546865206d6178696d756d20616d6f756e74206f662077656967687420636f6e73756d656420627920657865637574696e672074686520636c6f7365642070726f706f73616c2e202b20606c656e6774685f626f756e64603a2054686520757070657220626f756e6420666f7220746865206c656e677468206f66207468652070726f706f73616c20696e2073746f726167652e20436865636b656420766961202020202020202020202020202020202020206073746f726167653a3a726561646020736f206974206973206073697a655f6f663a3a3c7533323e2829203d3d203460206c6172676572207468616e207468652070757265206c656e6774682e20232320576569676874202d20604f2842202b204d202b205031202b20503229602077686572653a2020202d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e646564292020202d20604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564292020202d20605031602069732074686520636f6d706c6578697479206f66206070726f706f73616c6020707265696d6167652e2020202d20605032602069732070726f706f73616c2d636f756e742028636f64652d626f756e64656429202d2044423a20202d20322073746f726167652072656164732028604d656d62657273603a20636f64656320604f284d29602c20605072696d65603a20636f64656320604f283129602920202d2033206d75746174696f6e73202860566f74696e67603a20636f64656320604f284d29602c206050726f706f73616c4f66603a20636f64656320604f284229602c206050726f706f73616c73603a20636f64656320604f28503229602920202d20616e79206d75746174696f6e7320646f6e65207768696c6520657865637574696e67206070726f706f73616c6020286050316029202d20757020746f2033206576656e7473436f6d706163743c50726f706f73616c496e6465783e70726f706f73616c5f7765696768745f626f756e64436f6d706163743c5765696768743e6c656e6774685f626f756e642041646420616e20617965206f72206e617920766f746520666f72207468652073656e64657220746f2074686520676976656e2070726f706f73616c2e205265717569726573207468652073656e64657220746f2062652061206d656d6265722e205472616e73616374696f6e20666565732077696c6c2062652077616976656420696620746865206d656d62657220697320766f74696e67206f6e20616e7920706172746963756c61722070726f706f73616c20666f72207468652066697273742074696d6520616e64207468652063616c6c206973207375636365737366756c2e2053756273657175656e7420766f7465206368616e6765732077696c6c206368617267652061206665652e202d20604f284d296020776865726520604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564292020202d20312073746f72616765207265616420604d656d62657273602028636f64656320604f284d2960292020202d20312073746f72616765206d75746174696f6e2060566f74696e67602028636f64656320604f284d296029202d2031206576656e74617070726f7665204164642061206e65772070726f706f73616c20746f2065697468657220626520766f746564206f6e206f72206578656375746564206469726563746c792e205265717569726573207468652073656e64657220746f206265206d656d6265722e20607468726573686f6c64602064657465726d696e65732077686574686572206070726f706f73616c60206973206578656375746564206469726563746c792028607468726573686f6c64203c20326029206f722070757420757020666f7220766f74696e672e202d20604f2842202b204d202b2050312960206f7220604f2842202b204d202b20503229602077686572653a2020202d206272616e6368696e6720697320696e666c75656e63656420627920607468726573686f6c64602077686572653a20202020202d20605031602069732070726f706f73616c20657865637574696f6e20636f6d706c65786974792028607468726573686f6c64203c2032602920202020202d20605032602069732070726f706f73616c732d636f756e742028636f64652d626f756e646564292028607468726573686f6c64203e3d203260292020202d20312073746f726167652072656164206069735f6d656d626572602028636f64656320604f284d2960292020202d20312073746f726167652072656164206050726f706f73616c4f663a3a636f6e7461696e735f6b6579602028636f64656320604f28312960292020202d20444220616363657373657320696e666c75656e63656420627920607468726573686f6c64603a20202020202d204549544845522073746f7261676520616363657373657320646f6e65206279206070726f706f73616c602028607468726573686f6c64203c2032602920202020202d204f522070726f706f73616c20696e73657274696f6e2028607468726573686f6c64203c3d20326029202020202020202d20312073746f72616765206d75746174696f6e206050726f706f73616c73602028636f64656320604f285032296029202020202020202d20312073746f72616765206d75746174696f6e206050726f706f73616c436f756e74602028636f64656320604f2831296029202020202020202d20312073746f72616765207772697465206050726f706f73616c4f66602028636f64656320604f2842296029202020202020202d20312073746f726167652077726974652060566f74696e67602028636f64656320604f284d2960292020202d2031206576656e747468726573686f6c64436f6d706163743c4d656d626572436f756e743e426f783c3c5420617320436f6e6669673c493e3e3a3a50726f706f73616c3e20446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e204f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e202d20604f284d202b2050296020776865726520604d60206d656d626572732d636f756e742028636f64652d626f756e6465642920616e642060506020636f6d706c6578697479206f66206469737061746368696e67206070726f706f73616c60202d2044423a203120726561642028636f64656320604f284d296029202b20444220616363657373206f66206070726f706f73616c60205365742074686520636f6c6c6563746976652773206d656d626572736869702e202d20606e65775f6d656d62657273603a20546865206e6577206d656d626572206c6973742e204265206e69636520746f2074686520636861696e20616e642070726f7669646520697420736f727465642e202d20607072696d65603a20546865207072696d65206d656d6265722077686f736520766f74652073657473207468652064656661756c742e202d20606f6c645f636f756e74603a2054686520757070657220626f756e6420666f72207468652070726576696f7573206e756d626572206f66206d656d6265727320696e2073746f726167652e202020202020202020202020202020205573656420666f722077656967687420657374696d6174696f6e2e20526571756972657320726f6f74206f726967696e2e204e4f54453a20446f6573206e6f7420656e666f7263652074686520657870656374656420604d61784d656d6265727360206c696d6974206f6e2074686520616d6f756e74206f66206d656d626572732c20627574202020202020207468652077656967687420657374696d6174696f6e732072656c79206f6e20697420746f20657374696d61746520646973706174636861626c65207765696768742e202d20604f284d50202b204e29602077686572653a2020202d20604d60206f6c642d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564292020202d20604e60206e65772d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564292020202d206050602070726f706f73616c732d636f756e742028636f64652d626f756e646564292020202d20312073746f72616765206d75746174696f6e2028636f64656320604f284d296020726561642c20604f284e29602077726974652920666f722072656164696e6720616e642077726974696e6720746865206d656d626572732020202d20312073746f7261676520726561642028636f64656320604f285029602920666f722072656164696e67207468652070726f706f73616c732020202d206050602073746f72616765206d75746174696f6e732028636f64656320604f284d29602920666f72207570646174696e672074686520766f74657320666f7220656163682070726f706f73616c2020202d20312073746f726167652077726974652028636f64656320604f283129602920666f722064656c6574696e6720746865206f6c6420607072696d656020616e642073657474696e6720746865206e6577206f6e656e65775f6d656d626572737072696d654f7074696f6e3c543a3a4163636f756e7449643e6f6c645f636f756e744d656d626572436f756e7400000000db571200090000000000000000000000f22113000c00000000000000000000000000000000000000000000000000000000000000543113006472120000000000000000007472120001000000000000000100000000000000f15712000a0000000106000000000000b7f9120007000000000000007c7212001a0000000000000000000000000000000000000054311300987212000000000000000000a872120001000000000000000000000000000000fb571200060000000106000000000000b7f912000700000000000000b0721200230000000000000000000000000000000000000054311300d47212000000000000000000e472120001000000000000000000000000000000e45712000d0000000000000000000000cbed1200030000000000000000000000000000000000000000000000000000000000000054311300ec7212000000000000000000fc72120001000000000000000100000000000000c7e112000700000000000000000000002c1a13001100000000000000000000000000000000000000000000000000000000000000543113000473120000000000000000001473120001000000000000000100000000000000dbe11200050000000000000000000000e3f812000c00000000000000000000000000000000000000000000000000000000000000543113001c73120000000000000000002c731200010000000000000000000000120000000000000001000000620000004d741200240000003c5420617320436f6e6669673c493e3e3a3a50726f706f73616c0000120000000000000001000000ff0000001a74120033000000566f7465733c543a3a4163636f756e7449642c20543a3a426c6f636b4e756d6265723e0012000000000000000100000000010000ed7312002d00000012000000000000000100000022000000db731200120000001200000000000000010000003f0000008d7312004e00000012000000000000000100000023000000347312005900000020546865207072696d65206d656d62657220746861742068656c70732064657465726d696e65207468652064656661756c7420766f7465206265686176696f7220696e2063617365206f6620616273656e746174696f6e732e205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e2050726f706f73616c7320736f206661722e20566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e2054686520686173686573206f6620746865206163746976652070726f706f73616c732e00000000000000db571200090000000000000000000000f22113000c00000000000000000000000000000000000000000000000000000000000000543113008476120000000000000000007472120001000000000000000100000000000000f15712000a0000000106000000000000b7f9120007000000000000007c7212001a0000000000000000000000000000000000000054311300947612000000000000000000a872120001000000000000000000000000000000fb571200060000000106000000000000b7f912000700000000000000b0721200230000000000000000000000000000000000000054311300a47612000000000000000000e472120001000000000000000000000000000000e45712000d0000000000000000000000cbed1200030000000000000000000000000000000000000000000000000000000000000054311300b47612000000000000000000fc72120001000000000000000100000000000000c7e112000700000000000000000000002c1a1300110000000000000000000000000000000000000000000000000000000000000054311300c476120000000000000000001473120001000000000000000100000000000000dbe11200050000000000000000000000e3f812000c0000000000000000000000000000000000000000000000000000000000000054311300d476120000000000000000002c73120001000000000000000000000012000000000000000100000062000000120000000000000001000000ff00000012000000000000000100000000010000120000000000000001000000220000001200000000000000010000003f0000001200000000000000010000002300000000000000d0ce1200080000000000000018781200040000000000000000000000387812000300000000000000000000005078120005000000000000005878120005000000000000000000000080781200030000000000000000000000987812000800000000000000e8d01200010000000000000000000000a0781200020000000000000000000000b07812000b00000000000000e8d01200010000000000000000000000bc78120002000000000000000000000090cf12000800000000000000cc781200020000000000000000000000dc781200020000000000000000000000ec7812000e00000000000000cc781200020000000000000000000000fc7812000200000000000000000000000c7912000600000000000000147912000300000000000000000000002c791200020000000000000079e5120009000000357c12000d00000082e5120004000000497012000b0000009c7b120053000000ef7b120010000000ff7b120036000000566f74656400000079e512000900000082e5120004000000a1fb120004000000497012000b000000497012000b000000e97a1200420000002b7b120046000000717b12002b000000417070726f766564b87a120031000000a67a120012000000446973617070726f76656400717a120035000000a67a12001200000082e5120004000000637a12000e0000001a7a120049000000007a12001a0000004d656d62657245786563757465640000ad79120053000000007a12001a000000436c6f736564000082e5120004000000497012000b000000497012000b0000003c79120056000000927912001b00000020412070726f706f73616c2077617320636c6f736564206265636175736520697473207468726573686f6c64207761732072656163686564206f7220616674657220697473206475726174696f6e207761732075702e205c5b70726f706f73616c5f686173682c207965732c206e6f5c5d20412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b20726573756c742077696c6c20626520604f6b602069662069742072657475726e656420776974686f7574206572726f722e205c5b70726f706f73616c5f686173682c20726573756c745c5d2041206d6f74696f6e207761732065786563757465643b20726573756c742077696c6c20626520604f6b602069662069742072657475726e656420776974686f7574206572726f722e4469737061746368526573756c742041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e205c5b70726f706f73616c5f686173685c5d2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e205c5b6163636f756e742c2070726f706f73616c5f686173682c20766f7465642c207965732c206e6f5c5d2041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20604d656d626572436f756e7460292e205c5b6163636f756e742c2070726f706f73616c5f696e6465782c2070726f706f73616c5f686173682c207468726573686f6c645c5d50726f706f73616c496e646578000012000000000000000100000021000000647c12006600000062000000270000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f6e706f732d656c656374696f6e732f7372632f70687261676d656e2e72730000dc7c1200670000008e0000002f0000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f6e706f732d656c656374696f6e732f7372632f62616c616e63696e672e72730000000000e0e1120009000000000000005c7e1200010000000000000000000000218312001100000000000000647e1200010000000000000000000000498312000f000000000000006c7e1200010000000000000000000000465812000a00000000000000747e1200010000000000000000000000395812000d000000000000007c7e1200010000000000000000000000275812001200000000000000847e1200010000000000000000000000ab82120008000000000000008c7e1200010000000000000000000000608312001000000000000000947e12000100000000000000000000001458120013000000000000009c7e1200010000000000000000000000505812001300000000000000a47e120001000000000000001480120018000000f47f120020000000e07f120014000000cf7f120011000000b87f120017000000977f120021000000567f120041000000167f120040000000e17e120035000000ac7e1200350000002054686520676976656e206c656e67746820626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e2054686520676976656e2077656967687420626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e2054686572652063616e206f6e6c792062652061206d6178696d756d206f6620604d617850726f706f73616c7360206163746976652070726f706f73616c732e2054686520636c6f73652063616c6c20776173206d61646520746f6f206561726c792c206265666f72652074686520656e64206f662074686520766f74696e672e204d656d626572732061726520616c726561647920696e697469616c697a656421204475706c696361746520766f74652069676e6f726564204d69736d61746368656420696e6465782050726f706f73616c206d757374206578697374204475706c69636174652070726f706f73616c73206e6f7420616c6c6f776564204163636f756e74206973206e6f742061206d656d6265724c4f474943204552524f523a2062616b655f7265666572656e64756d2f7363686564756c655f6e616d6564206661696c656444656d6f63726163795265666572656e64756d496e666f4f66507265696d616765734e65787445787465726e616c5075626c696350726f70734465706f7369744f6653657373696f6e486973746f726963616c53657373696f6e730000002f000000600000000800000001010000020100002f0000006000000008000000300000003100000032000000330000003400000035000000360000006661696c656420746f20696e7365727420696e746f207472696500002481120054000000740100001b0000002f636172676f2d686f6d652f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32322e332f7372632f7472696564626d75742e72732481120054000000670100000d0000009081120023000000605f5f49676e6f7265602063616e206e6576657220626520636f6e7374727563746564496e76616c69645769746e6573734d6178566f7465735265616368656457726f6e675570706572426f756e644e6f6e73656e7365496e7374616e744e6f74416c6c6f776564566f74657345786973744e6f7444656c65676174696e67496e73756666696369656e7446756e6473556e646572666c6f774f766572666c6f77416c726561647944656c65676174696e674e6f5065726d697373696f6e4e6f74566f7465724e6f74457870697265644e6f744c6f636b65644e6f6e6557616974696e67507265696d616765496e76616c69645265666572656e64756d496e76616c6964507265696d6167654d697373696e67496d6d696e656e74546f6f4561726c794e6f74496d6d696e656e744475706c6963617465507265696d6167654e6f7444656c656761746564416c72656164795665746f65644e6f50726f706f73616c496e76616c6964486173684e6f7453696d706c654d616a6f7269747950726f706f73616c426c61636b6c69737465644475706c696361746550726f706f73616c416c726561647943616e63656c6564426164496e64657850726f706f73616c4d697373696e6756616c75654c6f77546f6f4d616e7950726f706f73616c7300000000bc8712000700000000000000c4871200020000000000000000000000f48712000b00000000000000000000004c881200060000000000000054881200020000000000000000000000848812000a0000000000000000000000d48812000400000000000000d8881200020000000000000000000000088912000900000000000000000000005089120010000000000000006089120001000000000000000000000078891200080000000000000000000000b88912001000000000000000c8891200010000000000000000000000e0891200090000000000000000000000288a12001900000000000000c8891200010000000000000000000000448a12000b00000000000000000000009c8a12001800000000000000c8891200010000000000000000000000b48a12000b00000000000000000000000c8b12000a00000000000000188b1200030000000000000000000000608b12000f0000000000000000000000d88b12000d00000000000000c8891200010000000000000000000000e88b1200090000000000000000000000308c12001100000000000000448c12000100000000000000000000005c8c1200070000000000000000000000948c12000d00000000000000a48c1200010000000000000000000000bc8c1200070000000000000000000000f48c12000800000000000000fc8c1200030000000000000000000000448d1200140000000000000000000000e48d12000a0000000000000054311300000000000000000000000000f08d12000c0000000000000000000000508e1200160000000000000054311300000000000000000000000000688e1200050000000000000000000000908e12000d00000000000000a08e1200010000000000000000000000b88e12000a0000000000000000000000088f12001900000000000000a08e1200010000000000000000000000248f12000100000000000000000000002c8f12001600000000000000a08e1200010000000000000000000000448f12000c0000000000000000000000a48f12002200000000000000a08e1200010000000000000000000000c88f1200010000000000000000000000d08f12000d00000000000000e08f1200020000000000000000000000109012000f000000000000000000000088901200060000000000000090901200010000000000000000000000a8901200070000000000000000000000e09012000b00000000000000ec901200010000000000000000000000049112001b0000000000000000000000dc9112001100000000000000f0911200020000000000000000000000209212000f0000000000000000000000989212000e00000000000000a8921200020000000000000000000000d8921200010000000000000000000000e09212000900000000000000ec9212000200000000000000000000001c9312000f0000000000000000000000949312000f00000000000000a4931200010000000000000000000000bc931200070000000000000070726f706f73650000000000389712000d00000000000000b7f91200070000000000000048b6120005000000000000004db61200150000001cb5120028000000543113000000000044b51200460000008ab51200210000005431130000000000abb5120036000000e1b5120046000000543113000000000027b6120012000000543113000000000039b612000f0000007365636f6e6400000000000001b512000800000000000000c1941200120000000000000009b512001300000000000000d2a012000c00000037b312002e000000543113000000000065b3120041000000a6b31200450000005431130000000000ebb31200330000001eb41200510000006fb412004a0000005431130000000000b9b4120048000000766f74650000000072aa120009000000000000007baa12001800000000000000d488120004000000000000001eb3120019000000fcb112004d00000049b212002f00000054311300000000000b99120033000000543113000000000078b2120038000000b0b21200220000005431130000000000d2b212004c000000656d657267656e63795f63616e63656c0000000072aa12000900000000000000bf9712000f00000034b112005400000078b012000c000000543113000000000088b112003f0000005431130000000000c7b1120035000000543113000000000008a412001000000065787465726e616c5f70726f706f736500000000389712000d00000000000000b7f91200070000002cb012004c00000078b012000c000000543113000000000084b012003b0000005431130000000000d2ae1200360000005431130000000000bfb012004600000005b112002f00000065787465726e616c5f70726f706f73655f6d616a6f7269747900000082af120056000000d8af1200180000005431130000000000f0af12003c0000005431130000000000d2ae120036000000543113000000000008af1200530000005baf120027000000543113000000000003ae12000f00000065787465726e616c5f70726f706f73655f64656661756c7424ae12005200000076ae120021000000543113000000000097ae12003b0000005431130000000000d2ae120036000000543113000000000008af1200530000005baf120027000000543113000000000003ae12000f000000666173745f747261636b000000000000389712000d00000000000000b7f91200070000000000000012ae12000d00000000000000a9f912000e000000000000001fae12000500000000000000a9f912000e00000095ab120054000000e9ab12005900000042ac12003b00000054311300000000007dac1200350000005431130000000000b2ac12003e000000f0ac12005800000048ad1200260000006ead120055000000c3ad12002f0000005431130000000000f2ad120011000000543113000000000003ae12000f0000007665746f5f65787465726e616c00000093aa12002f0000005431130000000000c2aa1200370000005431130000000000f9aa12004c000000543113000000000045ab120010000000543113000000000055ab12004000000063616e63656c5f7265666572656e64756d0000000000000072aa120009000000000000007baa12001800000015aa1200150000005431130000000000d7a312003100000054311300000000002aaa120036000000543113000000000060aa12001200000063616e63656c5f7175657565640000000000000010aa12000500000000000000bf9712000f00000063a91200280000005431130000000000d7a312003100000054311300000000008ba91200320000005431130000000000bda912005300000064656c6567617465000000003aa912000200000000000000e3f812000c000000000000003ca912000a0000000000000046a912000a0000000000000050a91200070000000000000057a912000c000000dca512004f00000054311300000000002ba612005600000081a61200330000005431130000000000b4a61200580000000ca712001e0000002aa712005700000081a71200260000005431130000000000a7a7120052000000f9a71200560000004fa8120051000000a0a8120055000000f5a8120032000000543113000000000027a9120013000000543113000000000059a5120050000000a9a5120033000000756e64656c6567617465000018a412003400000054311300000000004ca4120058000000a4a41200380000005431130000000000dca41200520000002ea5120016000000543113000000000044a5120015000000543113000000000059a5120050000000a9a5120033000000636c6561725f7075626c69635f70726f706f73616c730000baa312001d0000005431130000000000d7a3120031000000543113000000000008a41200100000006e6f74655f707265696d61676500000000000000aaa31200100000000000000042ec12000700000009a312005800000061a312004900000054311300000000000b99120033000000543113000000000029a212003200000054311300000000005ba2120017000000543113000000000072a21200540000006e6f74655f707265696d6167655f6f7065726174696f6e616c000000c6a21200430000006e6f74655f696d6d696e656e745f707265696d61676500002aa11200510000007ba1120050000000cba112004e00000019a212001000000054311300000000000b99120033000000543113000000000029a212003200000054311300000000005ba2120017000000543113000000000072a21200540000006e6f74655f696d6d696e656e745f707265696d6167655f6f7065726174696f6e616c0000dea012004c000000726561705f707265696d61676500000000000000389712000d00000000000000b7f912000700000000000000baa012001800000000000000d2a012000c000000a19e12003d00000054311300000000000b991200330000005431130000000000de9e120034000000129f12004b0000005d9f12004000000054311300000000009d9f120054000000f19f12005700000048a012002c000000543113000000000074a012001800000054311300000000008ca012002e000000756e6c6f636b000000000000739a12000600000000000000e3f812000c000000199e12002900000054311300000000000b991200330000005431130000000000429e12002f0000005431130000000000719e12003000000072656d6f76655f766f74650000000000a00e13000500000000000000bf9712000f000000ce971200200000005431130000000000799a1200040000007d9a120023000000a09a120020000000c09a120025000000e59a120040000000259b1200360000005b9b1200220000007d9b120058000000d59b1200170000005431130000000000ec9b12002b000000179c12003c000000539c1200380000008b9c120030000000bb9c120057000000129d120057000000699d12003a0000005431130000000000a39d120053000000f69d1200230000005431130000000000a89912003e0000005431130000000000e6991200560000003c9a12003700000072656d6f76655f6f746865725f766f746500000000000000739a12000600000000000000e3f812000c00000000000000a00e13000500000000000000bf9712000f000000ce971200200000005431130000000000ee97120054000000429812004c0000008e98120056000000e49812002700000054311300000000000b9912003300000054311300000000003e991200540000009299120016000000a89912003e0000005431130000000000e6991200560000003c9a120037000000656e6163745f70726f706f73616c000000000000389712000d00000000000000b7f912000700000000000000a00e13000500000000000000bf9712000f0000006b97120054000000626c61636b6c69737400000000000000389712000d00000000000000b7f912000700000000000000459712000f000000000000005497120017000000d3941200520000002595120010000000543113000000000035951200550000008a95120055000000df9512001b0000005431130000000000fa9512003c0000005431130000000000369612003f0000007596120052000000c79612000b0000005431130000000000d296120051000000239712001500000063616e63656c5f70726f706f73616c0000000000b79412000a00000000000000c194120012000000f493120013000000543113000000000007941200410000005431130000000000489412003500000054311300000000007d9412003a0000002052656d6f766520612070726f706f73616c2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c50726f706f73616c4f726967696e602e202d206070726f705f696e646578603a2054686520696e646578206f66207468652070726f706f73616c20746f2063616e63656c2e205765696768743a20604f28702960207768657265206070203d205075626c696350726f70733a3a3c543e3a3a6465636f64655f6c656e28296070726f705f696e646578436f6d706163743c50726f70496e6465783e205065726d616e656e746c7920706c61636520612070726f706f73616c20696e746f2074686520626c61636b6c6973742e20546869732070726576656e74732069742066726f6d2065766572206265696e672070726f706f73656420616761696e2e2049662063616c6c6564206f6e206120717565756564207075626c6963206f722065787465726e616c2070726f706f73616c2c207468656e20746869732077696c6c20726573756c7420696e206974206265696e672072656d6f7665642e2049662074686520607265665f696e6465786020737570706c69656420697320616e20616374697665207265666572656e64756d2077697468207468652070726f706f73616c20686173682c207468656e2069742077696c6c2062652063616e63656c6c65642e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d7573742062652060426c61636b6c6973744f726967696e602e202d206070726f706f73616c5f68617368603a205468652070726f706f73616c206861736820746f20626c61636b6c697374207065726d616e656e746c792e202d20607265665f696e646578603a20416e206f6e676f696e67207265666572656e64756d2077686f73652068617368206973206070726f706f73616c5f68617368602c2077686963682077696c6c2062652063616e63656c6c65642e205765696768743a20604f28702960202874686f756768206173207468697320697320616e20686967682d70726976696c6567652064697370617463682c20776520617373756d65206974206861732061202020726561736f6e61626c652076616c7565292e70726f706f73616c5f686173686d617962655f7265665f696e6465784f7074696f6e3c5265666572656e64756d496e6465783e20456e61637420612070726f706f73616c2066726f6d2061207265666572656e64756d2e20466f72206e6f77207765206a757374206d616b65207468652077656967687420626520746865206d6178696d756d2e5265666572656e64756d496e6465782052656d6f7665206120766f746520666f722061207265666572656e64756d2e2049662074686520607461726765746020697320657175616c20746f20746865207369676e65722c207468656e20746869732066756e6374696f6e2069732065786163746c79206571756976616c656e7420746f206072656d6f76655f766f7465602e204966206e6f7420657175616c20746f20746865207369676e65722c207468656e2074686520766f7465206d757374206861766520657870697265642c20656974686572206265636175736520746865207265666572656e64756d207761732063616e63656c6c65642c20626563617573652074686520766f746572206c6f737420746865207265666572656e64756d206f7220626563617573652074686520636f6e76696374696f6e20706572696f64206973206f7665722e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e202d2060746172676574603a20546865206163636f756e74206f662074686520766f746520746f2062652072656d6f7665643b2074686973206163636f756e74206d757374206861766520766f74656420666f722020207265666572656e64756d2060696e646578602e202d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e205765696768743a20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2e2020205765696768742069732063616c63756c6174656420666f7220746865206d6178696d756d206e756d626572206f6620766f74652e7461726765742049663a202d20746865207265666572656e64756d207761732063616e63656c6c65642c206f72202d20746865207265666572656e64756d206973206f6e676f696e672c206f72202d20746865207265666572656e64756d2068617320656e646564207375636820746861742020202d2074686520766f7465206f6620746865206163636f756e742077617320696e206f70706f736974696f6e20746f2074686520726573756c743b206f722020202d20746865726520776173206e6f20636f6e76696374696f6e20746f20746865206163636f756e74277320766f74653b206f722020202d20746865206163636f756e74206d61646520612073706c697420766f7465202e2e2e7468656e2074686520766f74652069732072656d6f76656420636c65616e6c7920616e64206120666f6c6c6f77696e672063616c6c20746f2060756e6c6f636b60206d617920726573756c7420696e206d6f72652066756e6473206265696e6720617661696c61626c652e2049662c20686f77657665722c20746865207265666572656e64756d2068617320656e64656420616e643a202d2069742066696e697368656420636f72726573706f6e64696e6720746f2074686520766f7465206f6620746865206163636f756e742c20616e64202d20746865206163636f756e74206d6164652061207374616e6461726420766f7465207769746820636f6e76696374696f6e2c20616e64202d20746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e206973206e6f74206f766572202e2e2e7468656e20746865206c6f636b2077696c6c206265206167677265676174656420696e746f20746865206f766572616c6c206163636f756e742773206c6f636b2c207768696368206d617920696e766f6c7665202a6f7665726c6f636b696e672a20287768657265207468652074776f206c6f636b732061726520636f6d62696e656420696e746f20612073696e676c65206c6f636b207468617420697320746865206d6178696d756d206f6620626f74682074686520616d6f756e74206c6f636b656420616e64207468652074696d65206973206974206c6f636b656420666f72292e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e6572206d7573742068617665206120766f7465207265676973746572656420666f72207265666572656e64756d2060696e646578602e20556e6c6f636b20746f6b656e732074686174206861766520616e2065787069726564206c6f636b2e202d2060746172676574603a20546865206163636f756e7420746f2072656d6f766520746865206c6f636b206f6e2e205765696768743a20604f2852296020776974682052206e756d626572206f6620766f7465206f66207461726765742e2052656d6f766520616e20657870697265642070726f706f73616c20707265696d61676520616e6420636f6c6c65637420746865206465706f7369742e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f6620612070726f706f73616c2e202d206070726f706f73616c5f6c656e6774685f75707065725f626f756e64603a20616e20757070657220626f756e64206f6e206c656e677468206f66207468652070726f706f73616c2e20202045787472696e736963206973207765696768746564206163636f7264696e6720746f20746869732076616c75652077697468206e6f20726566756e642e20546869732077696c6c206f6e6c7920776f726b2061667465722060566f74696e67506572696f646020626c6f636b732066726f6d207468652074696d6520746861742074686520707265696d61676520776173206e6f7465642c2069662069742773207468652073616d65206163636f756e7420646f696e672069742e2049662069742773206120646966666572656e74206163636f756e742c207468656e206974276c6c206f6e6c7920776f726b20616e206164646974696f6e616c2060456e6163746d656e74506572696f6460206c617465722e20456d6974732060507265696d616765526561706564602e205765696768743a20604f284429602077686572652044206973206c656e677468206f662070726f706f73616c2e70726f706f73616c5f6c656e5f75707065725f626f756e64436f6d706163743c7533323e2053616d6520617320606e6f74655f696d6d696e656e745f707265696d6167656020627574206f726967696e20697320604f7065726174696f6e616c507265696d6167654f726967696e602e2052656769737465722074686520707265696d61676520666f7220616e207570636f6d696e672070726f706f73616c2e2054686973207265717569726573207468652070726f706f73616c20746f20626520696e207468652064697370617463682071756575652e204e6f206465706f736974206973206e65656465642e205768656e20746869732063616c6c206973207375636365737366756c2c20692e652e2074686520707265696d61676520686173206e6f74206265656e2075706c6f61646564206265666f726520616e64206d61746368657320736f6d6520696d6d696e656e742070726f706f73616c2c206e6f2066656520697320706169642e202d2060656e636f6465645f70726f706f73616c603a2054686520707265696d616765206f6620612070726f706f73616c2e20456d6974732060507265696d6167654e6f746564602e205765696768743a20604f28452960207769746820452073697a65206f662060656e636f6465645f70726f706f73616c60202870726f7465637465642062792061207265717569726564206465706f736974292e2053616d6520617320606e6f74655f707265696d6167656020627574206f726967696e20697320604f7065726174696f6e616c507265696d6167654f726967696e602e2052656769737465722074686520707265696d61676520666f7220616e207570636f6d696e672070726f706f73616c2e205468697320646f65736e27742072657175697265207468652070726f706f73616c20746f20626520696e207468652064697370617463682071756575652062757420646f657320726571756972652061206465706f7369742c2072657475726e6564206f6e636520656e61637465642e656e636f6465645f70726f706f73616c20436c6561727320616c6c207075626c69632070726f706f73616c732e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e205765696768743a20604f283129602e20556e64656c65676174652074686520766f74696e6720706f776572206f66207468652073656e64696e67206163636f756e742e20546f6b656e73206d617920626520756e6c6f636b656420666f6c6c6f77696e67206f6e636520616e20616d6f756e74206f662074696d6520636f6e73697374656e74207769746820746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e2077697468207768696368207468652064656c65676174696f6e20776173206973737565642e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062652063757272656e746c792064656c65676174696e672e20456d6974732060556e64656c656761746564602e205765696768743a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722064656c65676174696e6720746f20686173202020766f746564206f6e2e205765696768742069732063686172676564206173206966206d6178696d756d20766f7465732e2044656c65676174652074686520766f74696e6720706f77657220287769746820736f6d6520676976656e20636f6e76696374696f6e29206f66207468652073656e64696e67206163636f756e742e205468652062616c616e63652064656c656761746564206973206c6f636b656420666f72206173206c6f6e6720617320697427732064656c6567617465642c20616e64207468657265616674657220666f72207468652074696d6520617070726f70726961746520666f722074686520636f6e76696374696f6e2773206c6f636b20706572696f642e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e696e67206163636f756e74206d757374206569746865723a2020202d2062652064656c65676174696e6720616c72656164793b206f722020202d2068617665206e6f20766f74696e67206163746976697479202869662074686572652069732c207468656e2069742077696c6c206e65656420746f2062652072656d6f7665642f636f6e736f6c69646174656420202020207468726f7567682060726561705f766f746560206f722060756e766f746560292e202d2060746f603a20546865206163636f756e742077686f736520766f74696e6720746865206074617267657460206163636f756e74277320766f74696e6720706f7765722077696c6c20666f6c6c6f772e202d2060636f6e76696374696f6e603a2054686520636f6e76696374696f6e20746861742077696c6c20626520617474616368656420746f207468652064656c65676174656420766f7465732e205768656e207468652020206163636f756e7420697320756e64656c6567617465642c207468652066756e64732077696c6c206265206c6f636b656420666f722074686520636f72726573706f6e64696e6720706572696f642e202d206062616c616e6365603a2054686520616d6f756e74206f6620746865206163636f756e7427732062616c616e636520746f206265207573656420696e2064656c65676174696e672e2054686973206d7573742020206e6f74206265206d6f7265207468616e20746865206163636f756e7427732063757272656e742062616c616e63652e20456d697473206044656c656761746564602e746f636f6e76696374696f6e436f6e76696374696f6e62616c616e636542616c616e63654f663c543e2043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e202d20607768696368603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e205765696768743a20604f284429602077686572652060446020697320746865206974656d7320696e207468652064697370617463682071756575652e205765696768746564206173206044203d203130602e77686963682052656d6f76652061207265666572656e64756d2e202d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e2023205765696768743a20604f283129602e7265665f696e646578436f6d706163743c5265666572656e64756d496e6465783e205665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520605665746f4f726967696e602e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c20746f207665746f20616e6420626c61636b6c6973742e20456d69747320605665746f6564602e205765696768743a20604f2856202b206c6f6728562929602077686572652056206973206e756d626572206f6620606578697374696e67207665746f65727360205363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c656420696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e6520627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e20546865206469737061746368206f6620746869732063616c6c206d757374206265206046617374547261636b4f726967696e602e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e202d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e20496e6372656173656420746f2020206046617374547261636b566f74696e67506572696f646020696620746f6f206c6f772e202d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265202020656e61637465642e205468697320646f65736e277420686176652061206d696e696d756d20616d6f756e742e20456d697473206053746172746564602e205765696768743a20604f28312960766f74696e675f706572696f6464656c6179205363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c44656661756c744f726967696e602e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e20556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061207072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e205363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c4d616a6f726974794f726967696e602e205363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206045787465726e616c4f726967696e602e205765696768743a20604f2856296020776974682056206e756d626572206f66207665746f65727320696e2074686520626c61636b6c697374206f662070726f706f73616c2e2020204465636f64696e6720766563206f66206c656e67746820562e2043686172676564206173206d6178696d756d205363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d6520546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c6c6174696f6e4f726967696e602e202d607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e20566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f20766f746520666f722e202d2060766f7465603a2054686520766f746520636f6e66696775726174696f6e2e205765696768743a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722068617320766f746564206f6e2e4163636f756e74566f74653c42616c616e63654f663c543e3e205369676e616c732061677265656d656e742077697468206120706172746963756c61722070726f706f73616c2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e647320746f20636f76657220746865206465706f7369742c20657175616c20746f20746865206f726967696e616c206465706f7369742e202d206070726f706f73616c603a2054686520696e646578206f66207468652070726f706f73616c20746f207365636f6e642e202d20607365636f6e64735f75707065725f626f756e64603a20616e20757070657220626f756e64206f6e207468652063757272656e74206e756d626572206f66207365636f6e6473206f6e207468697320202070726f706f73616c2e2045787472696e736963206973207765696768746564206163636f7264696e6720746f20746869732076616c75652077697468206e6f20726566756e642e205765696768743a20604f28532960207768657265205320697320746865206e756d626572206f66207365636f6e647320612070726f706f73616c20616c7265616479206861732e70726f706f73616c7365636f6e64735f75707065725f626f756e642050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e647320746f20636f76657220746865206465706f7369742e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20707265696d6167652e202d206076616c7565603a2054686520616d6f756e74206f66206465706f73697420286d757374206265206174206c6561737420604d696e696d756d4465706f73697460292e20456d697473206050726f706f736564602e205765696768743a20604f2870296076616c7565436f6d706163743c42616c616e63654f663c543e3e00000000000034bb12000f000000000000000000000043bb12000900000000000000000000000000000000000000000000000000000000000000543113004cbb120000000000000000005cbb1200010000000000000001000000000000008c8012000b000000000000000000000064bb12002700000000000000000000000000000000000000000000000000000000000000543113008cbb120000000000000000009cbb1200010000000000000001000000000000009780120009000000010500000000000043bb12000900000000000000a4bb1200210000000000000000000000000000000000000054311300c8bb12000000000000000000d8bb12000300000000000000000000000000000077801200090000000106000000000000b7f912000700000000000000f0bb12003a00000000000000000000000000000000000000543113002cbc120000000000000000003cbc1200020000000000000000000000000000004cbc12000f0000000000000000000000bf9712000f00000000000000000000000000000000000000000000000000000000000000543113005cbc120000000000000000006cbc12000100000000000000010000000000000074bc12000d0000000000000000000000bf9712000f000000000000000000000000000000000000000000000000000000000000005431130084bc1200000000000000000094bc12000200000000000000010000000000000067801200100000000105000000000000bf9712000f00000000000000a4bc1200350000000000000000000000000000000000000054311300dcbc12000000000000000000ecbc12000300000000000000000000000000000004bd1200080000000105000000000000e3f812000c000000000000000cbd120032000000000000000000000000000000000000005431130040bd1200000000000000000050bd12000400000000000000010000000000000070bd1200050000000105000000000000e3f812000c00000000000000a9f912000e000000000000000000000000000000000000005431130078bd1200000000000000000088bd120004000000000000000000000000000000a8bd1200150000000000000000000000a1fb1200040000000000000000000000000000000000000000000000000000000000000054311300c0bd12000000000000000000d0bd120002000000000000000100000000000000808012000c0000000000000000000000e0bd1200180000000000000000000000000000000000000000000000000000000000000054311300f8bd1200000000000000000008be12000400000000000000000000000000000028be1200090000000106000000000000b7f91200070000000000000031be120023000000000000000000000000000000000000005431130054be1200000000000000000064be12000200000000000000000000000000000074be12000d0000000106000000000000b7f912000700000000000000a1fb120004000000000000000000000000000000000000005431130084be1200000000000000000094be1200010000000000000001000000000000009cbe12000e0000000000000000000000aabe1200080000000000000000000000000000000000000000000000000000000000000054311300b4be12000000000000000000c4be12000300000000000000000000005075626c696350726f70436f756e7450726f70496e6465781200000000000000010000002200000075c512003d0000005665633c2850726f70496e6465782c20543a3a486173682c20543a3a4163636f756e744964293e00120000000000000001000000030100002dc5120048000000285665633c543a3a4163636f756e7449643e2c2042616c616e63654f663c543e2900000012000000000000000100000023000000d6c41200210000005431130000000000f7c4120036000000507265696d6167655374617475733c543a3a4163636f756e7449642c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265723e00001200000000000000010000002300000045c41200580000009dc41200390000005265666572656e64756d436f756e740012000000000000000100000022000000f9c312004c0000004c6f77657374556e62616b65640000001200000000000000010000002200000079c3120049000000c2c31200370000005265666572656e64756d496e666f3c543a3a426c6f636b4e756d6265722c20543a3a486173682c2042616c616e63654f663c543e3e000000120000000000000001000000230000000ac312002d000000543113000000000037c3120042000000566f74696e674f66566f74696e673c42616c616e63654f663c543e2c20543a3a4163636f756e7449642c20543a3a426c6f636b4e756d6265723e00001200000000000000010000000401000022c212005700000079c21200570000005431130000000000d0c212003a0000004c6f636b730000001200000000000000010000002300000047c11200570000009ec11200540000005431130000000000f2c11200300000004c6173745461626c656457617345787465726e616c00000012000000000000000100000023000000e7c01200560000003dc112000a00000028543a3a486173682c20566f74655468726573686f6c642912000000000000000100000023000000f9bf1200560000004fc0120055000000a4c0120029000000cdc012001a000000426c61636b6c69737428543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e29120000000000000001000000230000006bbf120054000000bfbf12003a00000043616e63656c6c6174696f6e730000001200000000000000010000002300000021bf12004a00000053746f7261676556657273696f6e52656c6561736573000012000000000000000100000023000000dcbe12001f0000005431130000000000fbbe1200260000002053746f726167652076657273696f6e206f66207468652070616c6c65742e204e6577206e6574776f726b732073746172742077697468206c6173742076657273696f6e2e205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e2041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d6265722028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e20546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e20546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743a202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f72202d20605075626c696350726f70736020697320656d7074792e205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c69632070726f706f73616c2e204163636f756e747320666f7220776869636820746865726520617265206c6f636b7320696e20616374696f6e207768696368206d61792062652072656d6f76656420617420736f6d6520706f696e7420696e20746865206675747572652e205468652076616c75652069732074686520626c6f636b206e756d62657220617420776869636820746865206c6f636b206578706972657320616e64206d61792062652072656d6f7665642e2054574f582d4e4f54453a204f4b20e2809520604163636f756e7449646020697320612073656375726520686173682e20416c6c20766f74657320666f72206120706172746963756c617220766f7465722e2057652073746f7265207468652062616c616e636520666f7220746865206e756d626572206f6620766f74657320746861742077652068617665207265636f726465642e20546865207365636f6e64206974656d2069732074686520746f74616c20616d6f756e74206f662064656c65676174696f6e732c20746861742077696c6c2062652061646465642e2054574f582d4e4f54453a205341464520617320604163636f756e7449646073206172652063727970746f2068617368657320616e797761792e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e2054574f582d4e4f54453a205341464520617320696e646578657320617265206e6f7420756e64657220616e2061747461636b6572e280997320636f6e74726f6c2e20546865206c6f77657374207265666572656e64756d20696e64657820726570726573656e74696e6720616e20756e62616b6564207265666572656e64756d2e20457175616c20746f20605265666572656e64756d436f756e74602069662074686572652069736e2774206120756e62616b6564207265666572656e64756d2e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e204d6170206f662068617368657320746f207468652070726f706f73616c20707265696d6167652c20616c6f6e6720776974682077686f207265676973746572656420697420616e64207468656972206465706f7369742e2054686520626c6f636b206e756d6265722069732074686520626c6f636b20617420776869636820697420776173206465706f73697465642e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e2054574f582d4e4f54453a20536166652c20617320696e6372656173696e6720696e7465676572206b6579732061726520736166652e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865207365636f6e64206974656d206973207468652070726f706f73616c277320686173682e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e00000000000074c712000f00000000000000a9f912000e000000000000005431130084c71200000000000000000094c71200050000000000000000000000bcc712000c00000000000000a9f912000e0000000000000054311300c8c712000000000000000000d8c71200010000000000000000000000e0c712000c00000000000000a9f912000e0000000000000054311300ecc712000000000000000000fcc7120001000000000000000000000004c812000e0000000000000057a912000c000000000000005431130014c81200000000000000000024c812000100000000000000000000002cc812001500000000000000a9f912000e000000000000005431130044c81200000000000000000054c812000100000000000000000000005cc812000d00000000000000a9f912000e00000000000000543113006cc8120000000000000000007cc8120001000000000000000000000084c81200130000000000000057a912000c000000000000005431130098c812000000000000000000a8c81200010000000000000000000000b0c812000800000000000000cbed1200030000000000000054311300b8c812000000000000000000c8c812000100000000000000456e6163746d656e74506572696f6400120000000000000001000000050100008dca12005c0000005431130000000000e9ca12004c00000035cb12005a0000008fcb1200270000004c61756e6368506572696f641200000000000000010000000501000054ca120039000000566f74696e67506572696f641200000000000000010000000501000026ca12002e0000004d696e696d756d4465706f736974000012000000000000000100000045000000d9c912004d00000046617374547261636b566f74696e67506572696f64000000120000000000000001000000060100009ec912003b000000436f6f6c6f6666506572696f640000001200000000000000010000004a00000046c9120058000000507265696d616765427974654465706f7369740012000000000000000100000025000000fcc812004a0000004d6178566f74657312000000000000000100000052000000d0c812002c00000020546865206d6178696d756d206e756d626572206f6620766f74657320666f7220616e206163636f756e742e2054686520616d6f756e74206f662062616c616e63652074686174206d757374206265206465706f7369746564207065722062797465206f6620707265696d6167652073746f7265642e20506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f7220616e20656d657267656e6379207265666572656e64756d2e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e20546865206d696e696d756d20706572696f64206f66206c6f636b696e6720616e642074686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e2049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e73757265207468617420766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e000000000000d0ce12000800000000000000d8ce1200020000000000000000000000e8ce1200010000000000000000000000f0ce12000600000000000000f8ce120003000000000000000000000010cf120001000000000000000000000018cf12000e000000000000005431130000000000000000000000000028cf120001000000000000000000000030cf1200070000000000000038cf120002000000000000000000000048cf120001000000000000000000000050cf1200060000000000000058cf120001000000000000000000000060cf120001000000000000000000000068cf1200090000000000000058cf120001000000000000000000000074cf12000100000000000000000000007ccf1200090000000000000058cf120001000000000000000000000088cf120001000000000000000000000090cf1200080000000000000098cf1200020000000000000000000000a8cf1200010000000000000000000000b0cf12000900000000000000bccf1200020000000000000000000000cccf1200010000000000000000000000d4cf12000b00000000000000fce41200010000000000000000000000e0cf1200010000000000000000000000e8cf12000600000000000000f0cf120003000000000000000000000008d0120001000000000000000000000010d012000d0000000000000020d0120003000000000000000000000038d0120001000000000000000000000040d012000c0000000000000020d012000300000000000000000000004cd01200020000000000000000000000748212000f000000000000005cd012000200000000000000000000006cd01200020000000000000000000000948212000f000000000000005cd012000200000000000000000000007cd012000200000000000000000000008cd012000e000000000000009cd01200040000000000000000000000bcd01200020000000000000000000000ccd012000800000000000000fce41200010000000000000000000000d4d01200010000000000000000000000dcd012000b00000000000000e8d01200010000000000000000000000f0d01200010000000000000050726f706f73656443bb120009000000d5d1120007000000bcd512004c0000005461626c6564000043bb120009000000d5d1120007000000aed512000e0000004fd512005f00000045787465726e616c5461626c6564000029d51200260000005374617274656400bf9712000f0000001cd512000d000000ebd41200310000005061737365640000bf9712000f000000b1d412003a0000004e6f7450617373656400000077d412003a00000043616e63656c6c656400000048d412002f0000004578656375746564bf9712000f000000a1fb12000400000016d412003200000044656c65676174656400000079e512000900000079e5120009000000ced3120048000000556e64656c6567617465640090d312003e0000005665746f6564000079e512000900000082e512000400000085d312000b00000041d3120044000000507265696d6167654e6f74656400000082e512000400000079e5120009000000d5d1120007000000e9d2120058000000507265696d616765557365647fd2120045000000c4d212002500000082e5120004000000bf9712000f0000003cd21200430000001fd212001d000000dcd11200430000001fd212001d000000507265696d616765526561706564000082e512000400000079e5120009000000d5d112000700000079e51200090000005dd112004b000000a8d112002d000000556e6c6f636b65642ed112002f000000426c61636b6c69737465640082e5120004000000f8d012003600000020412070726f706f73616c205c5b686173685c5d20686173206265656e20626c61636b6c6973746564207065726d616e656e746c792e20416e205c5b6163636f756e745c5d20686173206265656e20756e6c6f636b6564207375636365737366756c6c792e2041207265676973746572656420707265696d616765207761732072656d6f76656420616e6420746865206465706f73697420636f6c6c656374656420627920746865207265617065722e205c5b70726f706f73616c5f686173682c2070726f76696465722c206465706f7369742c207265617065725c5d42616c616e636520412070726f706f73616c20636f756c64206e6f7420626520657865637574656420626563617573652069747320707265696d61676520776173206d697373696e672e205c5b70726f706f73616c5f686173682c207265665f696e6465785c5d20412070726f706f73616c20636f756c64206e6f7420626520657865637574656420626563617573652069747320707265696d6167652077617320696e76616c69642e20412070726f706f73616c20707265696d616765207761732072656d6f76656420616e6420757365642028746865206465706f736974207761732072657475726e6564292e205c5b70726f706f73616c5f686173682c2070726f76696465722c206465706f7369745c5d20412070726f706f73616c277320707265696d61676520776173206e6f7465642c20616e6420746865206465706f7369742074616b656e2e205c5b70726f706f73616c5f686173682c2077686f2c206465706f7369745c5d20416e2065787465726e616c2070726f706f73616c20686173206265656e207665746f65642e205c5b77686f2c2070726f706f73616c5f686173682c20756e74696c5c5d426c6f636b4e756d62657220416e205c5b6163636f756e745c5d206861732063616e63656c6c656420612070726576696f75732064656c65676174696f6e206f7065726174696f6e2e20416e206163636f756e74206861732064656c65676174656420746865697220766f746520746f20616e6f74686572206163636f756e742e205c5b77686f2c207461726765745c5d20412070726f706f73616c20686173206265656e20656e61637465642e205c5b7265665f696e6465782c2069735f6f6b5c5d2041207265666572656e64756d20686173206265656e2063616e63656c6c65642e205c5b7265665f696e6465785c5d20412070726f706f73616c20686173206265656e2072656a6563746564206279207265666572656e64756d2e205c5b7265665f696e6465785c5d20412070726f706f73616c20686173206265656e20617070726f766564206279207265666572656e64756d2e205c5b7265665f696e6465785c5d2041207265666572656e64756d2068617320626567756e2e205c5b7265665f696e6465782c207468726573686f6c645c5d566f74655468726573686f6c6420416e2065787465726e616c2070726f706f73616c20686173206265656e207461626c65642e2041207075626c69632070726f706f73616c20686173206265656e207461626c656420666f72207265666572656e64756d20766f74652e205c5b70726f706f73616c5f696e6465782c206465706f7369742c206465706f7369746f72735c5d5665633c4163636f756e7449643e2041206d6f74696f6e20686173206265656e2070726f706f7365642062792061207075626c6963206163636f756e742e205c5b70726f706f73616c5f696e6465782c206465706f7369745c5d4661696c656420746f2067656e657261746520686973746f726963616c20616e6365737472792d696e636c7573696f6e2070726f6f662e004c141300570000001b02000001000000496e73657274696f6e206e657665722064656c657465732e2481120054000000640200000d000000617373657274696f6e206661696c65643a20216578697374696e675f6b65792e69735f656d70747928290000248112005400000080030000150000000000000058831200080000000000000088da1200010000000000000000000000498312000f0000000000000090da120001000000000000000000000041831200080000000000000098da1200010000000000000000000000328312000f00000000000000a0da1200010000000000000000000000218312001100000000000000a8da12000100000000000000000000000e8312001300000000000000b0da1200010000000000000000000000fd8212001100000000000000b8da1200010000000000000000000000f28212000b00000000000000c0da1200010000000000000000000000e88212000a00000000000000c8da1200010000000000000000000000db8212000d00000000000000d0da1200010000000000000000000000cf8212000c00000000000000d8da1200010000000000000000000000be8212001100000000000000e0da1200010000000000000000000000b38212000b00000000000000e8da1200010000000000000000000000ab8212000800000000000000f0da1200010000000000000000000000a38212000800000000000000f8da1200010000000000000000000000948212000f0000000000000000db120001000000000000000000000083821200110000000000000008db1200010000000000000000000000748212000f0000000000000010db1200010000000000000000000000698212000b0000000000000018db120001000000000000000000000060821200090000000000000020db1200010000000000000000000000568212000a0000000000000028db12000100000000000000000000004e821200080000000000000030db1200010000000000000000000000428212000c0000000000000038db120001000000000000000000000031821200110000000000000040db120001000000000000000000000029821200080000000000000048db120001000000000000000000000020821200090000000000000050db12000100000000000000000000000f821200110000000000000058db1200010000000000000000000000028212000d0000000000000060db1200010000000000000000000000f88112000a0000000000000068db1200020000000000000000000000e7811200110000000000000078db1200010000000000000000000000df811200080000000000000080db1200010000000000000000000000d08112000f0000000000000088db1200010000000000000000000000c18112000f0000000000000090db1200010000000000000000000000b38112000e0000000000000098db1200010000000000000000000000608312001000000000000000a0db120001000000000000004fe012000e00000037e012001800000029e012000e00000003e0120026000000eddf120016000000d2df12001b000000a7df12002b0000009adf12000d00000085df1200150000005edf12002700000050df12000e00000039df1200170000002cdf12000d00000022df12000a00000019df12000900000006df120013000000e4de120022000000d3de120011000000bede12001500000095de12002900000059de12003c00000027de120032000000f4dd120033000000d1dd120023000000a8dd1200290000007edd12002a0000003edd12004000000015dd12002900000084dc120056000000dadc12003b0000004ddc12003700000027dc12002600000012dc120015000000f1db120021000000cddb120024000000a8db120025000000204d6178696d756d206e756d626572206f662070726f706f73616c7320726561636865642e205468652070726f7669646564207769746e65737320646174612069732077726f6e672e204d6178696d756d206e756d626572206f6620766f74657320726561636865642e20496e76616c696420757070657220626f756e642e2044656c65676174696f6e20746f206f6e6573656c66206d616b6573206e6f2073656e73652e2054686520696e7374616e74207265666572656e64756d206f726967696e2069732063757272656e746c7920646973616c6c6f7765642e20546865206163636f756e742063757272656e746c792068617320766f74657320617474616368656420746f20697420616e6420746865206f7065726174696f6e2063616e6e6f74207375636365656420756e74696c207468657365206172652072656d6f7665642c20656974686572207468726f7567682060756e766f746560206f722060726561705f766f7465602e20546865206163636f756e74206973206e6f742063757272656e746c792064656c65676174696e672e20546f6f206869676820612062616c616e6365207761732070726f7669646564207468617420746865206163636f756e742063616e6e6f74206166666f72642e20416e20756e657870656374656420696e746567657220756e646572666c6f77206f636375727265642e20416e20756e657870656374656420696e7465676572206f766572666c6f77206f636375727265642e20546865206163636f756e7420697320616c72656164792064656c65676174696e672e20546865206163746f7220686173206e6f207065726d697373696f6e20746f20636f6e647563742074686520616374696f6e2e2054686520676976656e206163636f756e7420646964206e6f7420766f7465206f6e20746865207265666572656e64756d2e20546865206c6f636b206f6e20746865206163636f756e7420746f20626520756e6c6f636b656420686173206e6f742079657420657870697265642e2054686520746172676574206163636f756e7420646f6573206e6f7420686176652061206c6f636b2e204e6f2070726f706f73616c732077616974696e6720496e76616c696420707265696d61676520566f746520676976656e20666f7220696e76616c6964207265666572656e64756d20507265696d616765206e6f7420666f756e6420496d6d696e656e7420546f6f206561726c79204e6f7420696d6d696e656e7420507265696d61676520616c7265616479206e6f746564204e6f742064656c656761746564204964656e74697479206d6179206e6f74207665746f20612070726f706f73616c207477696365204e6f2065787465726e616c2070726f706f73616c20496e76616c69642068617368204e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974792050726f706f73616c207374696c6c20626c61636b6c69737465642050726f706f73616c20616c7265616479206d6164652043616e6e6f742063616e63656c207468652073616d652070726f706f73616c20747769636520556e6b6e6f776e20696e6465782050726f706f73616c20646f6573206e6f742065786973742056616c756520746f6f206c6f77000000120000000100000001000000070100004c14130057000000e70400002d0000004c14130057000000e8040000300000004661696c656420746f206465636f64652060507265696d616765537461747573602076617269616e740000004c14130057000000170500002d0000004c141300570000001e050000400000003a6865617070616765735370656356657273696f6e4e65656473546f496e637265617365496e76616c6964537065634e616d654661696c6564546f4578747261637452756e74696d6556657273696f6e3a636f64653a6368616e6765735f747269652f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f73797374656d2f7372632f6c69622e727300008ee212002300000064e212002a0000000ce21200580000006f00000001000000496e7374616e6365314d656d626572736869704d656d62657273416c72656164794d656d6265725072696d654e6f744d656d6265720000000ce2120058000000a70000000d0000000ce2120058000000d6000000110000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f6d656d626572736869702f7372632f6c69622e7273696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a205f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e6d6f646c70792f7574696c6973756261000000d4e2120052000000af000000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f746970732f7372632f6c69622e72732f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f62616c616e6365732f7372632f6c69622e72733a65787472696e7369635f696e6465780000000094e412001000000000000000a4e41200010000000000000000000000ace41200010000000000000000000000b4e412000f00000000000000c4e41200020000000000000000000000d4e41200010000000000000000000000dce412000b0000000000000054311300000000000000000000000000e8e41200010000000000000000000000f0e412000a00000000000000fce4120001000000000000000000000004e512000100000000000000000000000ce512000d00000000000000fce412000100000000000000000000001ce5120001000000000000000000000024e5120008000000000000002ce512000200000000000000000000003ce51200010000000000000045787472696e73696353756363657373fae512000c00000006e612002e00000045787472696e7369634661696c656400113513000d000000fae512000c000000d5e5120025000000436f64655570646174656400c0e51200150000004e65774163636f756e74000079e5120009000000a1e512001f0000004b696c6c65644163636f756e7400000086e512001b00000052656d61726b656479e512000900000082e512000400000044e5120035000000204f6e206f6e2d636861696e2072656d61726b2068617070656e65642e205c5b6f726967696e2c2072656d61726b5f686173685c5d4163636f756e7449644861736820416e205c5b6163636f756e745c5d20776173207265617065642e2041206e6577205c5b6163636f756e745c5d2077617320637265617465642e20603a636f6465602077617320757064617465642e20416e2065787472696e736963206661696c65642e205c5b6572726f722c20696e666f5c5d4469737061746368496e666f20416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e205c5b696e666f5c5d00000000ece712000a00000000000000f8e7120001000000000000000000000010e8120001000000000000000000000018e81200060000000000000020e8120001000000000000000000000038e8120005000000000000000000000060e812000e0000000000000070e8120001000000000000000000000088e81200080000000000000000000000c8e812000800000000000000d0e81200010000000000000000000000e8e812000a000000000000000000000038e912001700000000000000d0e8120001000000000000000000000050e9120008000000000000000000000090e912001700000000000000a8e91200010000000000000000000000c0e912000a000000000000000000000010ea12000b000000000000001cea120001000000000000000000000034ea120008000000000000000000000074ea12000c0000000000000080ea120001000000000000000000000098ea1200080000000000000000000000d8ea12000b00000000000000e4ea120002000000000000000000000014eb12000b00000000000000000000006ceb1200110000000000000080eb120001000000000000000000000098eb1200060000000000000066696c6c5f626c6f636b0000000000004ff31200060000000000000055f31200070000000df312004200000072656d61726b00000000000006f31200070000000000000042ec120007000000ebf212001b0000005431130000000000f2eb12000b0000003cef12000900000036ec12000c0000007365745f686561705f7061676573000000000000e3f212000500000000000000e8f212000300000060f212003f0000005431130000000000f2eb12000b0000003cef1200090000009ff2120013000000b2f2120019000000cbf212001800000036ec12000c0000007365745f636f6465000000005cf21200040000000000000042ec12000700000014f112001a0000005431130000000000f2eb12000b0000002ef112004d00000095f01200220000007bf112005e0000002bec12000b000000d9f112005f00000038f212002400000036ec12000c0000007365745f636f64655f776974686f75745f636865636b73002af01200470000005431130000000000f2eb12000b00000071f012002400000095f01200220000002bec12000b000000b7f012005d00000036ec12000c0000007365745f6368616e6765735f747269655f636f6e6669670000000000f7ef120013000000000000000af012002000000014ef1200280000005431130000000000f2eb12000b0000003cef12000900000045ef12002c00000071ef120036000000a7ef120019000000c0ef12000d000000cdef12002a00000036ec12000c0000007365745f73746f72616765000000000002ef1200050000000000000007ef12000d00000086ee12001b0000005431130000000000f2eb12000b000000a1ee120025000000c6ee12001f000000e5ee12001d00000060ee12001a00000036ec12000c0000006b696c6c5f73746f72616765000000007aee120004000000000000007eee120008000000ceed12001e0000005431130000000000f2eb12000b000000eced12003f0000002bee12001900000044ee12001c00000060ee12001a00000036ec12000c0000006b696c6c5f7072656669780000000000baed12000600000000000000c0ed12000300000000000000c3ed12000800000000000000cbed12000300000049ec12004500000054311300000000008eec12004f000000ddec1200500000005431130000000000f2eb12000b0000002ded12003700000064ed1200190000007ded12001d0000009aed12002000000036ec12000c00000072656d61726b5f776974685f6576656e740000000000000018e81200060000000000000042ec120007000000c8eb12002a0000005431130000000000f2eb12000b000000fdeb12002e0000002bec12000b00000036ec12000c000000204d616b6520736f6d65206f6e2d636861696e2072656d61726b20616e6420656d6974206576656e742e2023203c7765696768743e202d20604f28622960207768657265206220697320746865206c656e677468206f66207468652072656d61726b2e202d2031206576656e742e2023203c2f7765696768743e5665633c75383e204b696c6c20616c6c2073746f72616765206974656d7320776974682061206b657920746861742073746172747320776974682074686520676976656e207072656669782e202a2a4e4f54453a2a2a2057652072656c79206f6e2074686520526f6f74206f726967696e20746f2070726f7669646520757320746865206e756d626572206f66207375626b65797320756e6465722074686520707265666978207765206172652072656d6f76696e6720746f2061636375726174656c792063616c63756c6174652074686520776569676874206f6620746869732066756e6374696f6e2e202d20604f285029602077686572652060506020616d6f756e74206f66206b657973207769746820707265666978206070726566697860202d206050602073746f726167652064656c6574696f6e732e202d2042617365205765696768743a20302e383334202a205020c2b573202d205772697465733a204e756d626572206f66207375626b657973202b20317072656669784b65795f7375626b657973753332204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e202d20604f28494b296020776865726520604960206c656e677468206f6620606b6579736020616e6420604b60206c656e677468206f66206f6e65206b6579202d206049602073746f726167652064656c6574696f6e732e202d2042617365205765696768743a202e333738202a206920c2b573202d205772697465733a204e756d626572206f66206974656d736b6579735665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e202d20604f2849296020776865726520604960206c656e677468206f6620606974656d7360202d206049602073746f72616765207772697465732028604f28312960292e202d2042617365205765696768743a20302e353638202a206920c2b5736974656d735665633c4b657956616c75653e2053657420746865206e6577206368616e676573207472696520636f6e66696775726174696f6e2e202d20604f28312960202d20312073746f72616765207772697465206f722064656c6574652028636f64656320604f28312960292e202d20312063616c6c20746f20606465706f7369745f6c6f67603a20557365732060617070656e6460204150492c20736f204f283129202d2042617365205765696768743a20372e32313820c2b573202d204442205765696768743a20202020202d205772697465733a204368616e67657320547269652c2053797374656d204469676573746368616e6765735f747269655f636f6e6669674f7074696f6e3c4368616e67657354726965436f6e66696775726174696f6e3e2053657420746865206e65772072756e74696d6520636f646520776974686f757420646f696e6720616e7920636865636b73206f662074686520676976656e2060636f6465602e202d20604f2843296020776865726520604360206c656e677468206f662060636f646560202d20312073746f726167652077726974652028636f64656320604f28432960292e2054686520776569676874206f6620746869732066756e6374696f6e20697320646570656e64656e74206f6e207468652072756e74696d652e2057652077696c6c207472656174207468697320617320612066756c6c20626c6f636b2e2053657420746865206e65772072756e74696d6520636f64652e202d20604f2843202b2053296020776865726520604360206c656e677468206f662060636f64656020616e642060536020636f6d706c6578697479206f66206063616e5f7365745f636f646560202d20312063616c6c20746f206063616e5f7365745f636f6465603a20604f28532960202863616c6c73206073705f696f3a3a6d6973633a3a72756e74696d655f76657273696f6e6020776869636820697320657870656e73697665292e2054686520776569676874206f6620746869732066756e6374696f6e20697320646570656e64656e74206f6e207468652072756e74696d652c206275742067656e6572616c6c792074686973206973207665727920657870656e736976652e2057652077696c6c207472656174207468697320617320612066756c6c20626c6f636b2e636f64652053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e202d20312073746f726167652077726974652e202d2042617365205765696768743a20312e34303520c2b573202d203120777269746520746f20484541505f50414745537061676573753634204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b204120646973706174636820746861742077696c6c2066696c6c2074686520626c6f636b2077656967687420757020746f2074686520676976656e20726174696f2e5f726174696f50657262696c6c00000000dcf81200070000000102000000000000e3f812000c00000000000000eff8120025000000000000000000000000000000000000005431130014f91200000000000000000024f91200010000000000000001000000000000002cf912000e0000000000000000000000cbed12000300000000000000000000000000000000000000000000000000000000000000543113003cf9120000000000000000004cf912000100000000000000000000000000000054f912000b00000000000000000000005ff912000e000000000000000000000000000000000000000000000000000000000000005431130070f91200000000000000000080f912000100000000000000010000000000000088f91200100000000000000000000000cbed12000300000000000000000000000000000000000000000000000000000000000000543113003cf91200000000000000000098f9120001000000000000000000000000000000a0f91200090000000105000000000000a9f912000e00000000000000b7f91200070000000000000000000000000000000000000054311300c0f912000000000000000000d0f9120001000000000000000100000000000000d8f912000d0000000105000000000000cbed1200030000000000000042ec1200070000000000000000000000000000000000000054311300e8f912000000000000000000f8f912000100000000000000010000000000000000fa1200060000000000000000000000a9f912000e000000000000000000000000000000000000000000000000000000000000005431130008fa1200000000000000000018fa12000100000000000000010000000000000020fa12000a0000000000000000000000b7f91200070000000000000000000000000000000000000000000000000000000000000054311300c0f9120000000000000000002cfa12000100000000000000010000000000000034fa12000600000000000000000000003afa12000b000000000000000000000000000000000000000000000000000000000000005431130048fa1200000000000000000058fa12000100000000000000010000000000000060fa120006000000000000000000000066fa12002300000000000000000000000000000000000000000000000000000000000000543113008cfa120000000000000000009cfa120001000000000000000100000000000000a4fa12000a0000000000000000000000aefa12000a000000000000000000000000000000000000000000000000000000000000005431130008fa12000000000000000000b8fa120001000000000000000100000000000000c0fa12000b0000000102000000000000b7f912000700000000000000cbfa1200210000000000000000000000000000000000000054311300ecfa12000000000000000000fcfa12000a0000000000000001000000000000004cfb12001200000000000000000000005efb120016000000000000000000000000000000000000000000000000000000000000005431130074fb1200000000000000000084fb1200010000000000000000000000000000008cfb1200150000000000000000000000a1fb1200040000000000000000000000000000000000000000000000000000000000000054311300a8fb12000000000000000000b8fb120001000000000000000100000000000000c0fb1200180000000000000000000000a1fb1200040000000000000000000000000000000000000000000000000000000000000054311300a8fb12000000000000000000d8fb120002000000000000000100000000000000e8fb12000e0000000000000000000000f6fb1200050000000000000000000000000000000000000000000000000000000000000054311300fcfb120000000000000000000cfc12000100000000000000000000004163636f756e74543a3a4163636f756e7449644163636f756e74496e666f3c543a3a496e6465782c20543a3a4163636f756e74446174613e120000000000000001000000080100007e0113003a00000045787472696e736963436f756e74000012000000000000000100000023000000500113002e000000426c6f636b576569676874436f6e73756d6564576569676874000000120000000000000001000000090100002e01130022000000416c6c45787472696e736963734c656ede00130050000000426c6f636b48617368543a3a426c6f636b4e756d626572543a3a4861736800001200000000000000010000000a010000b80013002600000045787472696e7369634461746100000012000000000000000100000063000000690013004f0000004e756d6265720000120000000000000001000000220000002700130042000000506172656e744861736800000b0013001c0000004469676573744469676573744f663c543e0000001200000000000000010000003f000000cfff12003c0000004576656e74735665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e0000001200000000000000010000003f000000a7ff1200280000004576656e74436f756e744576656e74496e64657879ff12002e0000004576656e74546f706963735665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e1200000000000000010000006c00000047fd12004900000090fd1200250000005431130000000000b5fd12005400000009fe1200510000005afe120039000000543113000000000093fe120053000000e6fe12005300000039ff1200400000004c61737452756e74696d65557067726164654c61737452756e74696d6555706772616465496e666f12000000000000000100000023000000f2fc1200550000005570677261646564546f553332526566436f756e74626f6f6c000000120000000000000001000000230000009ffc1200530000005570677261646564546f547269706c65526566436f756e7436fc1200570000008dfc120012000000457865637574696f6e50686173655068617365001200000000000000010000002300000014fc1200220000002054686520657865637574696f6e207068617365206f662074686520626c6f636b2e2054727565206966207765206861766520757067726164656420736f2074686174204163636f756e74496e666f20636f6e7461696e73207468726565207479706573206f662060526566436f756e74602e2046616c7365202864656661756c7429206966206e6f742e2054727565206966207765206861766520757067726164656420736f207468617420607479706520526566436f756e74602069732060753332602e2046616c7365202864656661756c7429206966206e6f742e2053746f726573207468652060737065635f76657273696f6e6020616e642060737065635f6e616d6560206f66207768656e20746865206c6173742072756e74696d6520757067726164652068617070656e65642e204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e205468652063757272656e742077656967687420666f722074686520626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e205468652066756c6c206163636f756e7420696e666f726d6174696f6e20666f72206120706172746963756c6172206163636f756e742049442e00000000080313000c000000000000001403130014000000000000005431130028031300000000000000000038031300010000000000000000000000400313000b000000000000004b03130013000000000000005431130060031300000000000000000070031300010000000000000000000000780313000e00000000000000a9f912000e000000000000005431130088031300000000000000000098031300010000000000000000000000a00313000800000000000000a80313000f0000000000000054311300b80313000000000000000000c8031300010000000000000000000000d00313000700000000000000d70313000e0000000000000054311300e80313000000000000000000f8031300010000000000000000000000000413000a000000000000000a0413000200000000000000543113000c04130000000000000000001c0413000500000000000000426c6f636b576569676874736c696d6974733a3a426c6f636b576569676874731200000000000000010000000b0100000606130034000000426c6f636b4c656e6774686c696d6974733a3a426c6f636b4c656e67746800001200000000000000010000000c010000dc0513002a000000426c6f636b48617368436f756e7400001200000000000000010000000d0100008705130055000000446257656967687452756e74696d654462576569676874001200000000000000010000000e010000450513004200000056657273696f6e52756e74696d6556657273696f6e0000001200000000000000010000000f010000240513002100000053533538507265666978753812000000000000000100000023000000440413002a00000054311300000000006e0413004e000000bc0413004c000000080513001c000000205468652064657369676e61746564205353383520707265666978206f66207468697320636861696e2e2054686973207265706c6163657320746865202273733538466f726d6174222070726f7065727479206465636c6172656420696e2074686520636861696e20737065632e20526561736f6e2069732074686174207468652072756e74696d652073686f756c64206b6e6f772061626f7574207468652070726566697820696e206f7264657220746f206d616b6520757365206f6620697420617320616e206964656e746966696572206f662074686520636861696e2e204765742074686520636861696e27732063757272656e742076657273696f6e2e2054686520776569676874206f662072756e74696d65206461746162617365206f7065726174696f6e73207468652072756e74696d652063616e20696e766f6b652e204d6178696d756d206e756d626572206f6620626c6f636b206e756d62657220746f20626c6f636b2068617368206d617070696e677320746f206b65657020286f6c64657374207072756e6564206669727374292e20546865206d6178696d756d206c656e677468206f66206120626c6f636b2028696e206279746573292e20426c6f636b20262065787472696e7369637320776569676874733a20626173652076616c75657320616e64206c696d6974732e00004c0613005300000015020000100000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f70726f78792f7372632f6c69622e72733a5f5f50414c4c45545f56455253494f4e5f5f3a00c406130055000000be000000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f6772616e6470612f7372632f6c69622e72730000002c071300550000005a000000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f696e64696365732f7372632f6c69622e72730000009407130055000000ec010000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f73657373696f6e2f7372632f6c69622e7273000000fc0713005500000066040000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f7374616b696e672f7372632f6c69622e727300000000000000d80813000500000000000000e0081300010000000000000000000000f8081300120000000000000000000000880913000d0000000000000098091300020000000000000000000000c80913000d0000000000000000000000300a13000900000000000000e00813000100000000000000000000003c0a13000d000000000000006261746368000000000000004510130005000000000000004a10130018000000c40e1300200000005431130000000000290b13001f0000005431130000000000480b13003c0000005431130000000000840b130058000000dc0b1300330000005431130000000000f2eb12000b0000000f0c13004100000036ec12000c0000005431130000000000e40e1300560000003a0f13004d000000870f130056000000dd0f130054000000311013001400000061735f6465726976617469766500000000000000a00e13000500000000000000a50e13000300000000000000a80e13000400000000000000ac0e130018000000500c1300380000005431130000000000880c130056000000de0c13003000000054311300000000000e0d130052000000600d130059000000b90d1300550000000e0e13002000000054311300000000002e0e13003e00000054311300000000006c0e13003400000062617463685f616c6c000000a40a13003c000000e00a1300490000005431130000000000290b13001f0000005431130000000000480b13003c0000005431130000000000840b130058000000dc0b1300330000005431130000000000f2eb12000b0000000f0c13004100000036ec12000c0000002053656e642061206261746368206f662064697370617463682063616c6c7320616e642061746f6d6963616c6c792065786563757465207468656d2e205468652077686f6c65207472616e73616374696f6e2077696c6c20726f6c6c6261636b20616e64206661696c20696620616e79206f66207468652063616c6c73206661696c65642e204d61792062652063616c6c65642066726f6d20616e79206f726967696e2e202d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e204966206f726967696e20697320726f6f74207468656e2063616c6c2061726520646973706174636820776974686f757420636865636b696e67206f726967696e2066696c7465722e20285468697320696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e202d20436f6d706c65786974793a204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e2053656e6420612063616c6c207468726f75676820616e20696e64657865642070736575646f6e796d206f66207468652073656e6465722e2046696c7465722066726f6d206f726967696e206172652070617373656420616c6f6e672e205468652063616c6c2077696c6c2062652064697370617463686564207769746820616e206f726967696e20776869636820757365207468652073616d652066696c74657220617320746865206f726967696e206f6620746869732063616c6c2e204e4f54453a20496620796f75206e65656420746f20656e73757265207468617420616e79206163636f756e742d62617365642066696c746572696e67206973206e6f7420686f6e6f7265642028692e652e206265636175736520796f7520657870656374206070726f78796020746f2068617665206265656e2075736564207072696f7220696e207468652063616c6c20737461636b20616e6420796f7520646f206e6f742077616e74207468652063616c6c207265737472696374696f6e7320746f206170706c7920746f20616e79207375622d6163636f756e7473292c207468656e20757365206061735f6d756c74695f7468726573686f6c645f316020696e20746865204d756c74697369672070616c6c657420696e73746561642e204e4f54453a205072696f7220746f2076657273696f6e202a31322c2074686973207761732063616c6c6564206061735f6c696d697465645f737562602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e696e64657875313663616c6c426f783c3c5420617320436f6e6669673e3a3a43616c6c3e2053656e642061206261746368206f662064697370617463682063616c6c732e20546869732077696c6c2072657475726e20604f6b6020696e20616c6c2063697263756d7374616e6365732e20546f2064657465726d696e65207468652073756363657373206f66207468652062617463682c20616e206576656e74206973206465706f73697465642e20496620612063616c6c206661696c656420616e64207468652062617463682077617320696e7465727275707465642c207468656e2074686520604261746368496e74657272757074656460206576656e74206973206465706f73697465642c20616c6f6e67207769746820746865206e756d626572206f66207375636365737366756c2063616c6c73206d61646520616e6420746865206572726f72206f6620746865206661696c65642063616c6c2e20496620616c6c2077657265207375636365737366756c2c207468656e2074686520604261746368436f6d706c6574656460206576656e74206973206465706f73697465642e63616c6c735665633c3c5420617320436f6e6669673e3a3a43616c6c3e696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f6465506172656e7420686173682073686f756c642062652076616c69642e0000b4111300570000003501000009000000b4111300570000005d0100000d0000005369676e617475726520766572696669636174696f6e206661696c65642e0000b4111300570000004e010000110000001f12130032000000b411130057000000b901000009000000446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e00b411130057000000c10100000d00000053746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642eb411130057000000c7010000090000005472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642eb411130057000000c9010000090000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f6578656375746976652f7372632f6c69622e72734469676573744974656d206e6f7420657175616c4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e4e6f646520697320636f6e6669677572656420746f20757365207468652073616d6520686173683b20716564000000120000000000000001000000100100003ee1120054000000430500000e0000003ee11200540000004b05000016000000c012130056000000ea000000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f626f756e746965732f7372632f6c69622e727300002813130056000000c9010000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f6964656e746974792f7372632f6c69622e72730000901313005600000088000000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f6d756c74697369672f7372632f6c69622e72732f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f74726561737572792f7372632f6c69622e72734c14130057000000cf010000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f64656d6f63726163792f7372632f6c69622e727300b414130058000000a5000000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f617574686f72736869702f7372632f6c69622e72731c15130058000000f1000000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f636f6c6c6563746976652f7372632f6c69622e727300000000a81613000a00000000000000b4161300010000000000000000000000cc161300030000000000000000000000e41613000d00000000000000b4161300010000000000000000000000f41613000300000000000000000000000c1713000b000000000000001817130002000000000000000000000048171300050000000000000000000000701713000d000000000000008017130001000000000000000000000098171300040000000000000000000000b81713000a00000000000000c4171300010000000000000000000000dc171300050000000000000000000000041813000900000000000000b416130001000000000000000000000010181300030000000000000000000000281813000b00000000000000543113000000000000000000000000003418130003000000000000006164645f6d656d626572000000000000791b13000300000000000000e3f812000c000000321b13001f0000005431130000000000511b13002800000072656d6f76655f6d656d626572000000e31a1300240000005431130000000000071b13002b000000737761705f6d656d6265720000000000da1a13000600000000000000e3f812000c00000000000000e01a13000300000000000000e3f812000c0000003d1a13003000000054311300000000006d1a1300290000005431130000000000961a13004400000072657365745f6d656d6265727300000000000000251a130007000000000000002c1a1300110000008a19130056000000e01913001b0000005431130000000000fb1913002a0000006368616e67655f6b6579000000000000871913000300000000000000e3f812000c000000cc181300360000005431130000000000021913003d00000054311300000000003f191300480000007365745f7072696d650000009c181300300000005431130000000000721813002a000000636c6561725f7072696d65004c181300260000005431130000000000721813002a0000002052656d6f766520746865207072696d65206d656d626572206966206974206578697374732e204d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a5072696d654f726967696e602e2053657420746865207072696d65206d656d6265722e204d75737420626520612063757272656e74206d656d6265722e2053776170206f7574207468652073656e64696e67206d656d62657220666f7220736f6d65206f74686572206b657920606e6577602e204d6179206f6e6c792062652063616c6c65642066726f6d20605369676e656460206f726967696e206f6620612063757272656e74206d656d6265722e205072696d65206d656d62657273686970206973207061737365642066726f6d20746865206f726967696e206163636f756e7420746f20606e6577602c20696620657874616e742e6e6577204368616e676520746865206d656d6265727368697020746f2061206e6577207365742c20646973726567617264696e6720746865206578697374696e67206d656d626572736869702e204265206e69636520616e64207061737320606d656d6265727360207072652d736f727465642e204d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a52657365744f726967696e602e6d656d626572735665633c543a3a4163636f756e7449643e2053776170206f7574206f6e65206d656d626572206072656d6f76656020666f7220616e6f746865722060616464602e204d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a537761704f726967696e602e205072696d65206d656d62657273686970206973202a6e6f742a207061737365642066726f6d206072656d6f76656020746f2060616464602c20696620657874616e742e72656d6f76656164642052656d6f76652061206d656d626572206077686f602066726f6d20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a52656d6f76654f726967696e602e204164642061206d656d626572206077686f6020746f20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a4164644f726967696e602e77686f00000000c7e112000700000000000000000000002c1a13001100000000000000000000000000000000000000000000000000000000000000543113002c1c130000000000000000003c1c130001000000000000000100000000000000dbe11200050000000000000000000000e3f812000c0000000000000000000000000000000000000000000000000000000000000054311300441c13000000000000000000541c13000100000000000000000000001200000000000000010000003f000000851c130032000000120000000000000001000000230000005c1c130029000000205468652063757272656e74207072696d65206d656d6265722c206966206f6e65206578697374732e205468652063757272656e74206d656d626572736869702c2073746f72656420617320616e206f726465726564205665632e0000000000c01d13000b0000000000000054311300000000000000000000000000cc1d1300010000000000000000000000d41d13000d0000000000000054311300000000000000000000000000e41d1300010000000000000000000000ec1d13000e0000000000000054311300000000000000000000000000fc1d1300010000000000000000000000041e13000c0000000000000054311300000000000000000000000000101e1300010000000000000000000000181e13000a0000000000000054311300000000000000000000000000241e13000100000000000000000000002c1e13000500000000000000341e13000100000000000000000000003c1e130001000000000000004d656d626572416464656400691f1300390000004d656d62657252656d6f7665640000002e1f13003b0000004d656d62657273537761707065640000f71e1300370000004d656d626572735265736574b11e1300460000004b65794368616e67656400008f1e13002200000044756d6d79000000601e13002f000000441e13001c000000205068616e746f6d206d656d6265722c206e6576657220757365642e73705f7374643a3a6d61726b65723a3a5068616e746f6d446174613c284163636f756e7449642c204576656e74293e204f6e65206f6620746865206d656d6265727327206b657973206368616e6765642e20546865206d656d62657273686970207761732072657365743b2073656520746865207472616e73616374696f6e20666f722077686f20746865206e6577207365742069732e2054776f206d656d62657273207765726520737761707065643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732072656d6f7665643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732061646465643b2073656520746865207472616e73616374696f6e20666f722077686f2e0000120000000000000001000000210000002c201300620000006800000010000000e41f1300480000003a0400000f000000e41f1300480000003a040000220000002f72757374632f653337613133636333353934303034363633373338626431386438313030653664623936363663662f6c6962726172792f636f72652f7372632f63656c6c2e72732f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f6e706f732d656c656374696f6e732f7372632f6e6f64652e727300001200000000000000010000005f0000002c20130062000000700000000d0000002c20130062000000750000000d0000002c20130062000000890000003b000000e020130023000000a0000000010000002f6275696c642f72756e74696d652f636f6d6d6f6e2f7372632f636c61696d732e72730014211300600000002d010000010000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f656c656374696f6e732d70687261676d656e2f7372632f6c69622e727352616e646f6d6e657373436f6c6c656374697665466c697000000000e42113000e0000000000000000000000f22113000c00000000000000000000000000000000000000000000000000000000000000543113000022130000000000000000001022130003000000000000000100000052616e646f6d4d6174657269616c5665633c543a3a486173683e00001200000000000000010000006200000028221300580000008022130058000000d82213001100000020536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e672062756666657220776974682060626c6f636b5f6e756d626572202520383160206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e0000003ee1120054000000180100000f0000000c23130055000000710000000f0000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f7574696c6974792f7372632f6c69622e72730000000000000000e112000f00000000000000f0231300020000000000000000000000e6e012001a00000000000000002413000200000000000000000000000fe112001d00000000000000102413000300000000000000000000002824130013000000000000003c241300010000000000000000000000442413000f00000000000000542413000100000000000000cf25130045000000ba251300150000006925130051000000ba25130015000000ea2413003c000000543113000000000026251300430000004e6f6e44656661756c74436f6d706f7369746500aa241300400000004e6f6e5a65726f526566436f756e74005c2413004e0000002054686572652069732061206e6f6e2d7a65726f207265666572656e636520636f756e742070726576656e74696e6720746865206163636f756e742066726f6d206265696e67207075726765642e20537569636964652063616c6c6564207768656e20746865206163636f756e7420686173206e6f6e2d64656661756c7420636f6d706f7369746520646174612e204661696c656420746f2065787472616374207468652072756e74696d652076657273696f6e2066726f6d20746865206e65772072756e74696d652e204569746865722063616c6c696e672060436f72655f76657273696f6e60206f72206465636f64696e67206052756e74696d6556657273696f6e60206661696c65642e205468652073706563696669636174696f6e2076657273696f6e206973206e6f7420616c6c6f77656420746f206465637265617365206265747765656e207468652063757272656e742072756e74696d6520616e6420746865206e65772072756e74696d652e20546865206e616d65206f662073706563696669636174696f6e20646f6573206e6f74206d61746368206265747765656e207468652063757272656e742072756e74696d651c261300170000005f5f49676e6f72652063616e6e6f74206265207573656400442613006800000055000000110000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f6672616d652f72616e646f6d6e6573732d636f6c6c6563746976652d666c69702f7372632f6c69622e727348617368207461626c65206361706163697479206f766572666c6f77d8261300530000004f000000280000002f636172676f2d686f6d652f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6861736862726f776e2d302e392e312f7372632f7261772f6d6f642e7273492068657265627920616772656520746f20746865207465726d73206f66207468652073746174656d656e742077686f7365205348412d323536206d756c74696861736820697320516d58456b4d61686668484a507a5433526a6b58695a56466937375a655665757874416a686f6a47524e59636b7a2e202854686973206d617920626520666f756e64206174207468652055524c3a2068747470733a2f2f73746174656d656e742e706f6c6b61646f742e6e6574776f726b2f736166742e68746d6c29492068657265627920616772656520746f20746865207465726d73206f66207468652073746174656d656e742077686f7365205348412d323536206d756c74696861736820697320516d63315859715436533339574e70325565695255725a6963685557555070474554684445366441623366364e792e202854686973206d617920626520666f756e64206174207468652055524c3a2068747470733a2f2f73746174656d656e742e706f6c6b61646f742e6e6574776f726b2f726567756c61722e68746d6c29436c61696d735369676e696e6700182f13004a0000001a04000022000000182f13004a0000007103000036000000182f13004a0000003604000015000000182f13004a000000440400001e000000182f13004a0000004d04000018000000182f13004a0000004e04000019000000182f13004a000000510400001a00000073756d206f6620696e7075742063616e6e6f742066697420696e206054606c656e677468206f6620696e7075742069732067726561746572207468616e207a65726f3b206974206d757374206861766520612066697273743b207165640000002c2a13005d000000e60000000e0000002c2a13005d000000c90000003000000050726f6f662070726f766964656420696e20746865206d6f64756c6520646f633b207165642e00002c2a13005d000000cb000000160000002c2a13005d000000d50000002c0000002c2a13005d000000d7000000120000002c2a13005d000000eb000000300000002c2a13005d000000fa000000210000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f61726974686d657469632f7372632f6c69622e72730000006f2b13004d000000da010000010000004661696c656420746f20636f6e7665727471202f206365696c28712f246d617829203c20246d61782e204d6163726f2070726576656e747320616e792074797065206265696e672063726561746564207468617420646f6573206e6f74207361746973667920746869733b207165642f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f61726974686d657469632f7372632f7065725f7468696e67732e72732f72757374632f653337613133636333353934303034363633373338626431386438313030653664623936363663662f6c6962726172792f636f72652f7372632f6f70732f61726974682e72730b2b1300640000005105000001000000dc2b1300610000006f000000090000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f61726974686d657469632f7372632f62696775696e742e727363616e6e6f74206669742061206e756d62657220696e746f20753132380000dc2b1300610000009e0000001b000000dc2b1300610000008000000009000000dc2b130061000000920000000900000000000000617474656d707420746f20646976696465206279207a65726f000000dc2b130061000000460000000d000000616c7265616479206d757461626c7920626f72726f77656412000000000000000100000021000000dc2b1300610000007a0100001a000000dc2b1300610000006801000028000000dc2b1300610000006901000028000000616c726561647920626f72726f7765641200000000000000010000005f000000dc2b130061000000710100001b000000dc2b130061000000720100001b000000dc2b130061000000d60100001c0000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f61726974686d657469632f7372632f66697865645f706f696e742e7273617474656d707420746f206469766964652077697468206f766572666c6f77642d1300650000004b0600000100000072656d696e646572206f6620646976206279206320697320616c77617973206c657373207468616e20633b2071656400120000000800000004000000f8000000612e1300680000006a00000012000000726573756c742063616e6e6f742066697420696e20753132382f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f61726974686d657469632f7372632f68656c706572735f3132386269742e727342616265565246496e4f7574436f6e7465787442414245736c6f74206e756d62657263757272656e742065706f6368636861696e2072616e646f6d6e657373182f13004a000000c4000000110000002f72757374632f653337613133636333353934303034363633373338626431386438313030653664623936363663662f6c6962726172792f616c6c6f632f7372632f736c6963652e72730000742f13004e000000cd000000200000002f636172676f2d686f6d652f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f61727261797665632d302e352e322f7372632f6c69622e7273000012000000000000000100000010010000e42f130066000000ce0000002a0000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f72756e74696d652d696e746572666163652f7372632f696d706c732e7273486f737420746f207761736d2076616c7565732061726520656e636f64656420636f72726563746c793b2071656412000000000000000100000010010000983013006800000009010000260000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f72756e74696d652d696e746572666163652f7372632f706173735f62792e7273373113000d0000002231130015000000543113000000000020311300020000003a20696e73756666696369656e7420636170616369747943617061636974794572726f72543113000000000072756e74696d650052756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e675472616e73616374696f6e206469737061746368206973206d616e6461746f72793b207472616e73616374696f6e73206d6179206e6f742068617665206d616e6461746f727920646973706174636865732e412063616c6c20776173206c6162656c6c6564206173206d616e6461746f72792c2062757420726573756c74656420696e20616e204572726f722e5472616e73616374696f6e20776f756c6420657868617573742074686520626c6f636b206c696d6974735472616e73616374696f6e2068617320616e20616e6369656e7420626972746820626c6f636b5472616e73616374696f6e20686173206120626164207369676e61747572655472616e73616374696f6e206973206f757464617465645472616e73616374696f6e2077696c6c2062652076616c696420696e2074686520667574757265496e6162696c69747920746f2070617920736f6d6520666565732028652e672e206163636f756e742062616c616e636520746f6f206c6f77295472616e73616374696f6e2063616c6c206973206e6f74206578706563746564496e76616c69645472616e73616374696f6e20637573746f6d206572726f72436f756c64206e6f742066696e6420616e20756e7369676e65642076616c696461746f7220666f722074686520756e7369676e6564207472616e73616374696f6e436f756c64206e6f74206c6f6f6b757020696e666f726d6174696f6e20726571756972656420746f2076616c696461746520746865207472616e73616374696f6e556e6b6e6f776e5472616e73616374696f6e20637573746f6d206572726f7200000000000000617474656d707420746f20646976696465206279207a65726f000000fc33130062000000600000002b0000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f72756e74696d652f7372632f67656e657269632f6572612e727348617368206e6f7420657175616c2f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f72756e74696d652f7372632f7472616974732e72730000006c3413005d0000005904000013000000436f6e73756d65722072656d61696e696e67426164206f726967696e43616e6e6f74206c6f6f6b75704e6f2070726f76696465727344697370617463684572726f723c7761736d3a73747269707065643e4475706c69636174655265706f72744f6666656e63654572726f722f72757374632f653337613133636333353934303034363633373338626431386438313030653664623936363663662f6c6962726172792f636f72652f7372632f736c6963652f6d6f642e7273000000a83513005e000000470000001f0000002f636172676f2d686f6d652f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f333635356639622f7072696d6974697665732f747269652f7372632f6e6f64655f636f6465632e72730000a83513005e00000050000000140000006c656e20213d20302073696e6365206c656e2025203220213d20303b20696e6e6572206861732061206c61737420656c656d656e743b207165640000643613005b0000003d000000120000002f636172676f2d686f6d652f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32322e332f7372632f6e6962626c652f6e6962626c657665632e727300643613005b0000006000000033000000643613005b000000600000000d000000643613005b000000690000000f000000643613005b0000006b0000000f000000643613005b0000006b0000003e000000643613005b0000009100000039000000643613005b0000009100000011000000643613005b0000009300000011000000643613005b0000009400000040000000643613005b000000940000004e000000803713005d0000009800000017000000803713005d00000096000000290000002f636172676f2d686f6d652f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32322e332f7372632f6e6962626c652f6e6962626c65736c6963652e7273000000f4391300550000004d0000001c000000803713005d0000004000000012000000803713005d0000004f0000002d000000803713005d0000005500000032000000803713005d000000dd0000000f000000803713005d000000df0000000f000000803713005d000000df0000003d0000006361706163697479206f766572666c6f77000000743813004e000000fb000000360000002f636172676f2d686f6d652f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f736d616c6c7665632d312e362e312f7372632f6c69622e7273617373657274696f6e206661696c65643a206e65775f636170203e3d206c656e0000743813004e000000320300000d000000617373657274696f6e206661696c65643a20696e646578203c3d206c656e0000743813004e0000005f05000009000000f4391300550000008d0000003c000000f4391300550000008d00000051000000f4391300550000008d00000031000000743913004f0000004b00000042000000743913004f0000004a0000003e0000002f636172676f2d686f6d652f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32322e332f7372632f6e6f64652e727300743913004f0000006b00000022000000743913004f0000009a00000032000000743913004f000000aa0000003e0000002f636172676f2d686f6d652f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32322e332f7372632f6e6962626c652f6d6f642e7273000000f4391300550000008600000031000000f4391300550000008600000042000000f4391300550000008600000026000000f439130055000000870000001d000000f439130055000000870000000d000000f4391300550000008e00000018000000f4391300550000008e0000000d00000063616c6c65642060526573756c743a3a756e77726170282960206f6e20616e2060457272602076616c75650041e8f5cc000b044f8167f700a98706046e616d6501a08706ee0800206578745f6f6666636861696e5f696e6465785f7365745f76657273696f6e5f3101196578745f6c6f6767696e675f6c6f675f76657273696f6e5f3102256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f3103236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f3104286578745f63727970746f5f66696e6973685f62617463685f7665726966795f76657273696f6e5f31052c6578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f76657273696f6e5f3106376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f3107256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f3108286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f3109216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f310a236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f320b276578745f63727970746f5f73746172745f62617463685f7665726966795f76657273696f6e5f310c2a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f310d1c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f310e1e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f310f206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f3110206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f3111206578745f68617368696e675f6b656363616b5f3235365f76657273696f6e5f31121e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f31131d6578745f68617368696e675f74776f785f36345f76657273696f6e5f31141c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f31151c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f31161d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f3117226578745f6d6973635f72756e74696d655f76657273696f6e5f76657273696f6e5f3118236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f3119346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f311a286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f311b286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f311c246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f311d226578745f6f6666636861696e5f72616e646f6d5f736565645f76657273696f6e5f311e296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f311f1c6578745f73746f726167655f617070656e645f76657273696f6e5f3120226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f31211b6578745f73746f726167655f636c6561725f76657273696f6e5f3122226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f3123286578745f73746f726167655f636f6d6d69745f7472616e73616374696f6e5f76657273696f6e5f31241c6578745f73746f726167655f6578697374735f76657273696f6e5f3125196578745f73746f726167655f6765745f76657273696f6e5f31261e6578745f73746f726167655f6e6578745f6b65795f76657273696f6e5f31271a6578745f73746f726167655f726561645f76657273696f6e5f31282a6578745f73746f726167655f726f6c6c6261636b5f7472616e73616374696f6e5f76657273696f6e5f31291a6578745f73746f726167655f726f6f745f76657273696f6e5f312a196578745f73746f726167655f7365745f76657273696f6e5f312b276578745f73746f726167655f73746172745f7472616e73616374696f6e5f76657273696f6e5f312c0c5f5f727573745f616c6c6f632d0a5f5f72675f616c6c6f632e0e5f5f727573745f6465616c6c6f632f0c5f5f72675f6465616c6c6f63300e5f5f727573745f7265616c6c6f63310c5f5f72675f7265616c6c6f6332135f5f727573745f616c6c6f635f7a65726f656433115f5f72675f616c6c6f635f7a65726f6564341a5f5f727573745f616c6c6f635f6572726f725f68616e646c657235085f5f72675f6f6f6d3633616c6c6f633a3a616c6c6f633a3a68616e646c655f616c6c6f635f6572726f723a3a68396233356666353366373862336237323708727573745f6f6f6d3834616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68643334613339623261323062343861613929636f72653a3a70616e69636b696e673a3a70616e69633a3a68353931663938323162363132633033313a2e616c6c6f633a3a7261775f7665633a3a66696e6973685f67726f773a3a68393363643365663835616537633939663b25616c6c6f633a3a666d743a3a666f726d61743a3a68363637613739353430383938353533383c36636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a68363764373564386363303561366261643d23636f72653a3a666d743a3a77726974653a3a68333133363666353338663366656331343e33636f72653a3a6f7074696f6e3a3a6578706563745f6e6f6e655f6661696c65643a3a68343335616366613232373730646637323f3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6833663662333835306339386135636265403b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6830336366666363666263313264333165413a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68303036356465623766386363306231344243616c6c6f633a3a7665633a3a5665633c542c413e3a3a737761705f72656d6f76653a3a6173736572745f6661696c65643a3a6864303363393639353330646266643136434e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a6837626136613033376164623563643230442d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a6830346365373030363561383039666238453e616c6c6f633a3a7665633a3a5665633c542c413e3a3a696e736572743a3a6173736572745f6661696c65643a3a6835623134346337343862643833363930463e616c6c6f633a3a7665633a3a5665633c542c413e3a3a72656d6f76653a3a6173736572745f6661696c65643a3a68666632366462653536343266386664624739636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653a3a63616c6c5f6f6e63653a3a6830393437373039326132383231633461482f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a68353833323565656365316333313739374911727573745f626567696e5f756e77696e644a313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a68353933346235316230646562653930614b35636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a68343636326361636365353764666465384c43636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a68356536643061626130396633326235324d3f636f72653a3a736c6963653a3a696e6465783a3a736c6963655f656e645f696e6465785f6c656e5f6661696c3a3a68366334396438333039613035633366324e2c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a68336264306663356131363761396636344f2e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a683036366638383363343461393435306350323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6834616263393066366631306163663061514a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686338363461636433656463666534326652323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68626661316230393363356565656336385347636f72653a3a756e69636f64653a3a756e69636f64655f646174613a3a6772617068656d655f657874656e643a3a6c6f6f6b75703a3a68663135356233306366366635633062655439636f72653a3a756e69636f64653a3a7072696e7461626c653a3a69735f7072696e7461626c653a3a6839396635326564306263383232343831554c636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a68373232653131323836353764373364302e33385641636f72653a3a736c6963653a3a696e6465783a3a736c6963655f73746172745f696e6465785f6c656e5f6661696c3a3a6838376139393138343461356136613264573d636f72653a3a736c6963653a3a696e6465783a3a736c6963655f696e6465785f6f726465725f6661696c3a3a68663065623763363063366164626633345838636f72653a3a70616e69636b696e673a3a6173736572745f6661696c65643a3a696e6e65723a3a683961613437343833393465613936323859303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68373630353135393538663833323238625a443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68616461363265643536366238623237615b453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68333961633465323730636264613361655c483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68396364363938613032303366376637655d2e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a68313238646263363361373762363462335e323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68653164623931393231326131373863655f323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683334393932343863336163653936613960533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6833636330623732656235383131376131612f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a6861663264376134626331363838373132622e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a6832336431393265383735306239363134633a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6863396239323564376434343463386336643b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6834336661353362343232643664383637653a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68326132353136316331386631363162376639636f72653a3a666d743a3a6275696c646572733a3a44656275675475706c653a3a6669656c643a3a68663934343663353338336538346530666731636f72653a3a666d743a3a6e756d3a3a70617273655f7536345f696e746f3a3a683836356665636331363439653662386668313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68636166353765616336643835636166376947636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a42696e61727920666f722069383e3a3a666d743a3a68393534666231363062643530303465346a3e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68303461626364316137336361656135626b5a637572766532353531395f64616c656b3a3a6261636b656e643a3a73657269616c3a3a7536343a3a6669656c643a3a4669656c64456c656d656e7435313a3a746f5f62797465733a3a68376437393064393161666331616134356c9201637572766532353531395f64616c656b3a3a6669656c643a3a3c696d706c20737562746c653a3a436f6e7374616e7454696d65457120666f7220637572766532353531395f64616c656b3a3a6261636b656e643a3a73657269616c3a3a7536343a3a6669656c643a3a4669656c64456c656d656e7435313e3a3a63745f65713a3a68396364656461363836373161653962666d24737562746c653a3a626c61636b5f626f783a3a68643538663262386531326262666438636e57637572766532353531395f64616c656b3a3a6261636b656e643a3a73657269616c3a3a7536343a3a6669656c643a3a4669656c64456c656d656e7435313a3a706f77326b3a3a68663236333730613433323836636163336f7e637572766532353531395f64616c656b3a3a6669656c643a3a3c696d706c20637572766532353531395f64616c656b3a3a6261636b656e643a3a73657269616c3a3a7536343a3a6669656c643a3a4669656c64456c656d656e7435313e3a3a737172745f726174696f5f693a3a6835363363396339363265323062373362705c637572766532353531395f64616c656b3a3a6261636b656e643a3a73657269616c3a3a7536343a3a6669656c643a3a4669656c64456c656d656e7435313a3a66726f6d5f62797465733a3a6832616238363561393631373334363633715a637572766532353531395f64616c656b3a3a72697374726574746f3a3a52697374726574746f506f696e743a3a656c6c696761746f725f72697374726574746f5f666c61766f723a3a68646461343666623535616233393161667249637572766532353531395f64616c656b3a3a7363616c61723a3a5363616c61723a3a66726f6d5f63616e6f6e6963616c5f62797465733a3a6839653365336238643333303431333564737b6672616d655f6d657461646174613a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206672616d655f6d657461646174613a3a53746f726167654861736865723e3a3a656e636f64655f746f3a3a683162656163376433656139313636306274423c73705f7374643a3a57726974657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a683363633661343561353130333135336375417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a6831636432373064666631313861613763766c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683563616634656137383534663333653777417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a683538303330336534653561396266326478417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a683637333262303539623133663935393579417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a68366466653838653631316263313030307a417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a68373364323466643532356561656535617b417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a68396561313134623133303139396634327c633c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a737065635f66726f6d5f697465723a3a5370656346726f6d497465723c542c493e3e3a3a66726f6d5f697465723a3a68373565373763666662363932356332627d2e616c6c6f633a3a7261775f7665633a3a66696e6973685f67726f773a3a68323639383637313236343665326136667e543c6672616d655f73797374656d3a3a6c696d6974733a3a56616c69646174696f6e4572726f727320617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68303564386661663138656538646536617f4c6672616d655f73797374656d3a3a6c696d6974733a3a426c6f636b576569676874734275696c6465723a3a6275696c645f6f725f70616e69633a3a68326463313939646664376530366331378001206b656363616b3a3a66313630303a3a68643136653639383530623363363336348101366d65726c696e3a3a7472616e7363726970743a3a5472616e7363726970743a3a6e65773a3a68663937363338316633643532623636308201366d65726c696e3a3a7374726f62653a3a5374726f62653132383a3a626567696e5f6f703a3a6834393265303662376564646166353330830131636f72653a3a70616e69636b696e673a3a6173736572745f6661696c65643a3a68353165396237626139333239313435378401416d65726c696e3a3a7472616e7363726970743a3a5472616e7363726970743a3a617070656e645f6d6573736167653a3a683832386436623530666233383133386185013d6d65726c696e3a3a7472616e7363726970743a3a5472616e7363726970743a3a617070656e645f7536343a3a68633365386666383661313861373738328601426d65726c696e3a3a7472616e7363726970743a3a5472616e7363726970743a3a6368616c6c656e67655f62797465733a3a68313833653739663961616235383637398701303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68316334646132633061303238396231668801643c70616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a466561736962696c6974794572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68356639353562323537383963303132628901303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68656632323534336265633130646631348a01573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a68393563343662346135636139623633318b01633c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a737065635f66726f6d5f697465723a3a5370656346726f6d497465723c542c493e3e3a3a66726f6d5f697465723a3a68306264653266643331303639363735368c014470616c6c65745f7374616b696e673a3a736c617368696e673a3a536c617368696e675370616e733a3a656e645f7370616e3a3a68343665356663366630336239626165618d014170616c6c65745f7374616b696e673a3a736c617368696e673a3a536c617368696e675370616e733a3a7072756e653a3a68396461336662633239336538376636628e013a70616c6c65745f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a68303534383936373432303432306536618f01503c7061726974795f7363616c655f636f6465633a3a6572726f723a3a4572726f7220617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683464303838633264376634643433323490014e3c7061726974795f7363616c655f636f6465633a3a6572726f723a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686263323663363266356563326365633891013f7061726974795f7363616c655f636f6465633a3a636f6465633a3a4f75747075743a3a707573685f627974653a3a68646535356531343739363262616232369201417061726974795f7363616c655f636f6465633a3a636f6465633a3a6465636f64655f7665635f776974685f6c656e3a3a683137326236353437366635353032356593017873705f636f72653a3a63727970746f3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f636f72653a3a63727970746f3a3a4163636f756e74496433323e3a3a6465636f64653a3a68343434323965343630393164333930619401417061726974795f7363616c655f636f6465633a3a636f6465633a3a6465636f64655f7665635f776974685f6c656e3a3a6838663036663234333538316330343764950173706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f7220706f6c6b61646f745f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a6866333132353766373030613764323632960143636f72653a3a7074723a3a64726f705f696e5f706c6163653c706f6c6b61646f745f72756e74696d653a3a43616c6c3e3a3a68323931336639633538376534623864329701417061726974795f7363616c655f636f6465633a3a636f6465633a3a6465636f64655f7665635f776974685f6c656e3a3a6865666161663031646263306131393837980173706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f7220706f6c6b61646f745f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a68623461303361656462343538393566379901417061726974795f7363616c655f636f6465633a3a636f6465633a3a6465636f64655f7665635f776974685f6c656e3a3a68666263373066313237623664313738319a01417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a68326431613761636333306632303331659b01417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a68333465323539333162346531636436639c01417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a68336561663130383731353339303430349d01417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a68346165376234343061616363373966649e01417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a68373663633033393565653930663335389f01417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a6838626231363161623938393934393263a001417061726974795f7363616c655f636f6465633a3a636f6465633a3a656e636f64655f736c6963655f6e6f5f6c656e3a3a6839343435623732353264366531656437a1017f7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202851302c5230293e3a3a656e636f64655f746f3a3a6866613131656361613263343663353034a201437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6836633266613633383763613136303466a3014673705f696f3a3a68617368696e673a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a74776f785f36343a3a6862666666623834363238363136323839a401483c5b543b20335d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6838313536336661333561653762326136a501483c5b543b20385d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6831396132646534623066383332363739a601493c5b543b2033325d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6863623661636139343162313336393138a701493c5b543b2036345d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6838303933396439656231303661383563a801493c5b543b2036355d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6863383263363163623836653938303562a90183013c616c6c6f633a3a7665633a3a5665633c542c413e20617320616c6c6f633a3a7665633a3a737065635f657874656e643a3a53706563457874656e643c542c616c6c6f633a3a7665633a3a696e746f5f697465723a3a496e746f497465723c543e3e3e3a3a737065635f657874656e643a3a6834333433623739616665303932333864aa017c7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c5230293e3a3a6465636f64653a3a6835376539633762336138623139633366ab016b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830333032626636346534653237353864ac017c7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c5230293e3a3a6465636f64653a3a6835623230663231363165303530636137ad016b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6866303535343637373665303230366363ae01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6862663364636463663734333139353536af01723c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6833333331313533346166363863323539b0014973705f696f3a3a68617368696e673a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a626c616b65325f3235363a3a6832313066356631633064313636643162b1014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6839383566636366333564323132633461b2014273705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a7365743a3a6864326433663631373330386337633833b301433c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6831386466333633666639376330326663b401433c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6836623163333939616130323131633837b501433c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6862316237633535636335393331633438b601463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6831356366376132373661656236306439b701463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6831393433366263323536323035633439b801463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6839386532353430376132336634383739b901463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6864366238393961663663623862623565ba012f616c6c6f633a3a7665633a3a5665633c542c413e3a3a696e736572743a3a6862313463363838616531366339623262bb012f616c6c6f633a3a7665633a3a5665633c542c413e3a3a72657461696e3a3a6864303139346364376564376632653738bc0130616c6c6f633a3a7665633a3a5665633c542c413e3a3a726573657276653a3a6862633437373533393538393931366631bd01753c636f72653a3a697465723a3a61646170746572733a3a66696c7465725f6d61703a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6834303462643035383132356562386236be013d70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a69735f6f6e6c696e655f6175783a3a6864343637623435636430623230393830bf01ef023c70616c6c65745f7374616b696e673a3a4578706f737572654f663c543e2061732073705f72756e74696d653a3a7472616974733a3a436f6e766572743c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449642c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c70616c6c65745f7374616b696e673a3a4578706f737572653c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449642c3c3c542061732070616c6c65745f7374616b696e673a3a436f6e6669673e3a3a43757272656e6379206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3e3a3a636f6e766572743a3a6865303165636431646561633832386130c0018901616c6c6f633a3a7665633a3a736f757263655f697465725f6d61726b65723a3a3c696d706c20616c6c6f633a3a7665633a3a737065635f66726f6d5f697465723a3a5370656346726f6d497465723c542c493e20666f7220616c6c6f633a3a7665633a3a5665633c543e3e3a3a66726f6d5f697465723a3a6834363866663161336634646662653265c10137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6864613239663237353833366134393731c2018901616c6c6f633a3a7665633a3a736f757263655f697465725f6d61726b65723a3a3c696d706c20616c6c6f633a3a7665633a3a737065635f66726f6d5f697465723a3a5370656346726f6d497465723c542c493e20666f7220616c6c6f633a3a7665633a3a5665633c543e3e3a3a66726f6d5f697465723a3a6865613730666433376438633331646166c301463c616c6c6f633a3a7665633a3a5665633c542c413e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831346533613663623564663536666133c401463c616c6c6f633a3a7665633a3a5665633c542c413e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6834613933633464303834333065643936c501463c616c6c6f633a3a7665633a3a5665633c542c413e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836303537393062333330306164356637c601463c616c6c6f633a3a7665633a3a5665633c542c413e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836356137396265346564383636373961c701463c616c6c6f633a3a7665633a3a5665633c542c413e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837313931373435626662633434323366c801463c616c6c6f633a3a7665633a3a5665633c542c413e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837643465373234323262363634313861c901463c616c6c6f633a3a7665633a3a5665633c542c413e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837643839626330393337326466386362ca01593c706f6c6b61646f745f72756e74696d653a3a4e706f73436f6d70616374536f6c7574696f6e313620617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837333664376631306164343464663161cb016e6672616d655f73797374656d3a3a70616c6c65743a3a5f3a3a3c696d706c20636f72653a3a636c6f6e653a3a436c6f6e6520666f72206672616d655f73797374656d3a3a70616c6c65743a3a43616c6c3c543e3e3a3a636c6f6e653a3a6831323638366561316134663633343835cc014b3c70616c6c65745f7363686564756c65723a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6864623866366639643663633431383265cd016c70616c6c65745f626162653a3a70616c6c65743a3a5f3a3a3c696d706c20636f72653a3a636c6f6e653a3a436c6f6e6520666f722070616c6c65745f626162653a3a70616c6c65743a3a43616c6c3c543e3e3a3a636c6f6e653a3a6837383361613533666636313562646361ce017670616c6c65745f62616c616e6365733a3a70616c6c65743a3a5f3a3a3c696d706c20636f72653a3a636c6f6e653a3a436c6f6e6520666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a43616c6c3c542c493e3e3a3a636c6f6e653a3a6832363164653063313634666635363162cf014c3c70616c6c65745f617574686f72736869703a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6865653466643830656361663864633265d001493c70616c6c65745f7374616b696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838666433303361643661323836343566d1014a3c70616c6c65745f6f6666656e6365733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831663061313664386462333362636338d201493c70616c6c65745f6772616e6470613a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6833376165643665316663643739303161d3014b3c70616c6c65745f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6835343831313631613336386534353337d401553c70616c6c65745f617574686f726974795f646973636f766572793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837313034663531313462333966646661d5014b3c70616c6c65745f64656d6f63726163793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6839666530363334663366393230333034d6014e3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830653536616134646335643235646137d701543c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838313437393230313536316437303734d8015a3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830336430613931656339373162303366d9017270616c6c65745f76657374696e673a3a70616c6c65743a3a5f3a3a3c696d706c20636f72653a3a636c6f6e653a3a436c6f6e6520666f722070616c6c65745f76657374696e673a3a70616c6c65743a3a43616c6c3c543e3e3a3a636c6f6e653a3a6865633234666532306563376234343334da014d3c706f6c6b61646f745f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68346635346532643136633036353534392e37393131db014a3c70616c6c65745f6964656e746974793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830643932653066343137613861643839dc016e70616c6c65745f70726f78793a3a70616c6c65743a3a5f3a3a3c696d706c20636f72653a3a636c6f6e653a3a436c6f6e6520666f722070616c6c65745f70726f78793a3a70616c6c65743a3a43616c6c3c543e3e3a3a636c6f6e653a3a6834613966316330373064656234363832dd014a3c70616c6c65745f6d756c74697369673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6839313735663538626235363334363836de014a3c70616c6c65745f626f756e746965733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831656462306664313263653864316266df01463c70616c6c65745f746970733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6862613164376164343261313264326466e001463c616c6c6f633a3a7665633a3a5665633c542c413e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6865613535616363646537613037386539e101483c616c6c6f633a3a7665633a3a5665633c542c413e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6838303265616436643865666533353761e2015c636f72653a3a7074723a3a64726f705f696e5f706c6163653c747269655f64623a3a7472696564626d75743a3a4e6f64653c7072696d69746976655f74797065733a3a483235363e3e3a3a6865363831383635643166643564323865e301543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6834383261343630393333326134326266e401543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6835356239373466663865663336636665e501543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6836383964306330643238303636323565e601a30173705f72756e74696d653a3a6d756c7469616464726573733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f72756e74696d653a3a6d756c7469616464726573733a3a4d756c7469416464726573733c4163636f756e7449642c4163636f756e74496e6465783e3e3a3a6465636f64653a3a6837373966626133363039643039633130e701543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837643539393962306662626634663963e801543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6839396138643766363633353339373038e901543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6862303830613235616131623864373537ea01543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6863316366336538323838306431313134eb01a30173705f72756e74696d653a3a6d756c7469616464726573733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f72756e74696d653a3a6d756c7469616464726573733a3a4d756c7469416464726573733c4163636f756e7449642c4163636f756e74496e6465783e3e3a3a6465636f64653a3a6862316637393732636333366234616539ec01543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6863633864643930663538363632356235ed019c013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6839346666333763376364373037646262ee01623c616c6c6f633a3a7665633a3a5665633c542c413e20617320616c6c6f633a3a7665633a3a737065635f657874656e643a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6833333437303064656532633961353763ef016f3c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830623534306634353365383133623065f00152616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a656e7472793a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6835363337656364623930343331326231f101613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6832363133633830663161376437393065f201723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6837646237386237343839393362373631f301407363686e6f72726b656c3a3a7672663a3a5652464f75747075743a3a6174746163685f696e7075745f686173683a3a6833623437323866663336313532616233f401457363686e6f72726b656c3a3a706f696e74733a3a52697374726574746f426f74683a3a66726f6d5f636f6d707265737365643a3a6836623232303364313364656139386139f501a60173705f72756e74696d653a3a6d756c7469616464726573733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f72756e74696d653a3a6d756c7469616464726573733a3a4d756c7469416464726573733c4163636f756e7449642c4163636f756e74496e6465783e3e3a3a656e636f64655f746f3a3a6830323861626262393936346364313439f6017273705f73657373696f6e3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f73657373696f6e3a3a4d656d6265727368697050726f6f663e3a3a6465636f64653a3a6836653432643666363338623138656535f7017273705f73657373696f6e3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f73657373696f6e3a3a4d656d6265727368697050726f6f663e3a3a6465636f64653a3a6839343863376230663337363533613733f801776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6d75746174653a3a6837323536646466373939663761393636f9015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862323066383061383637646331343662fa01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834333936376332633132393964646638fb01b80170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a756e726573657276653a3a6834316330613832386262346332313663fc01573c49642061732073705f72756e74696d653a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3c543e3e3a3a696e746f5f7375625f6163636f756e743a3a6839386431656634393434363831303630fd01b50170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a6465706f7369745f6372656174696e673a3a6835666133383763306132623164326139fe015e6672616d655f73797374656d3a3a3c696d706c206672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3e3a3a6465706f7369745f6576656e745f696e64657865643a3a6835626334326665303936353434373961ff014473705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a636c6561723a3a68346134363733353037653435373239368002950170616c6c65745f626f756e746965733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f626f756e746965733a3a426f756e74793c4163636f756e7449642c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a683836323732623763633739373164653381024773705f696f3a3a68617368696e673a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a74776f785f3132383a3a686233633163373235303031363932636482026c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686332666438616232643963643236623883023d70616c6c65745f626f756e746965733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a686137653033376266306337336539323684023f70616c6c65745f626f756e746965733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68373736383462363133633365306339308502703c70616c6c65745f626f756e746965733a3a5f5f47657442797465537472756374426f756e7479436f756e743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686161633861616139356362633466643186024870616c6c65745f626f756e746965733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68313166383733393161316536393835328702a1013c70616c6c65745f626f756e746965733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f756e747943757261746f724465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686261323764323161396437643264353588029f013c70616c6c65745f626f756e746965733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f756e7479557064617465506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68646131336231653366663965626337318902a5013c70616c6c65745f626f756e746965733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f756e74794465706f7369745061796f757444656c617944656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68616263393661646633646638376363618a029f013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073705f72756e74696d653a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a68346639326161646435363062373164648b0248636f72653a3a7074723a3a64726f705f696e5f706c6163653c706f6c6b61646f745f72756e74696d653a3a43616c6c3e3a3a68323931336639633538376534623864322e313432358c025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68333939373138323566613065396463388d02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68653562653633373365646164633831398e02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68303134383831383335653235316462648f024573705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6578697374733a3a6839376131343563396531323964633665900276706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a686361393330626465623166386435306291026f3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68633461656239623633353630633063329202553c73705f72756e74696d653a3a4d756c74695369676e61747572652061732073705f72756e74696d653a3a7472616974733a3a5665726966793e3a3a7665726966793a3a686237316635333161643164613262656193028c0173705f636f6e73656e7375735f626162653a3a646967657374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f636f6e73656e7375735f626162653a3a646967657374733a3a5072654469676573743e3a3a6465636f64653a3a68616635386165363233633966653764319402683c73705f636f6e73656e7375735f7672663a3a7363686e6f72726b656c3a3a56524650726f6f66206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68656636326139663434306438653364369502970173705f636f6e73656e7375735f626162653a3a646967657374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f636f6e73656e7375735f626162653a3a646967657374733a3a4e657874436f6e66696744657363726970746f723e3a3a6465636f64653a3a686162663463613866346436393435616296029a0173705f636f6e73656e7375735f626162653a3a646967657374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f636f6e73656e7375735f626162653a3a646967657374733a3a4e657874436f6e66696744657363726970746f723e3a3a656e636f64655f746f3a3a683939383236366265356137643030313297023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a683164343665666133393136303264326198028f0173705f636f6e73656e7375735f736c6f74733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f636f6e73656e7375735f736c6f74733a3a45717569766f636174696f6e50726f6f663c4865616465722c49643e3e3a3a6465636f64653a3a68333135346336303035323866333031329902723c73705f72756e74696d653a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68623231666632396164616331653838649a028f0173705f636f6e73656e7375735f736c6f74733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f636f6e73656e7375735f736c6f74733a3a45717569766f636174696f6e50726f6f663c4865616465722c49643e3e3a3a6465636f64653a3a68623566303733383937623663383465349b02723c73705f72756e74696d653a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68613332623433393933313031653361629c023a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68313966616163363634303864623934669d023b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a68363763306632616666393765366234629e023a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68666363356433616135306235396631329f024e616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a636f6e7461696e735f6b65793a3a6838376533363161653833333837656238a00245616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a6765743a3a6833646530326462666133613238363739a10245616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a6765743a3a6861333765623834336637643765326537a20245616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a6765743a3a6864383238373766343238663833313338a30247616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a656e7472793a3a6831383231633937386265376630353764a40248616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6863653637343566353364303332326632a50243616c6c6f633a3a636f6c6c656374696f6e733a3a7665635f64657175653a3a56656344657175653c543e3a3a67726f773a3a6834366165333765353832353364353264a602633c54206173207061726974795f7363616c655f636f6465633a3a64657074685f6c696d69743a3a4465636f64654c696d69743e3a3a6465636f64655f616c6c5f776974685f64657074685f6c696d69743a3a6831626665303966343531373238393166a7024d3c747269655f64623a3a7472696564623a3a5472696544423c4c3e20617320747269655f64623a3a547269653c4c3e3e3a3a6765745f776974683a3a6864356339653839303865303166386234a80239747269655f64623a3a6e6f64655f636f6465633a3a4e6f6465436f6465633a3a6465636f64653a3a6862383639363639626634646539366230a902503c61727261797665633a3a6572726f72733a3a43617061636974794572726f723c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837393632333430663930373534656332aa0225747269655f64623a3a547269653a3a6765743a3a6866356631613264326561623833396537ab02553c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c542c4d3e20617320636f72653a3a64656661756c743a3a44656661756c743e3a3a64656661756c743a3a6865366635633032326130396239613338ac02583c616c6c6f633a3a7665633a3a696e746f5f697465723a3a496e746f497465723c542c413e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6862333533653566623136316432346166ad02603c70616c6c65745f626f756e746965733a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6863643063343637366665323465363736ae024f3c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c542c4d3e20617320686173685f64623a3a4861736844423c482c543e3e3a3a6765743a3a6862333438336234343239643938366136af02366861736862726f776e3a3a6d61703a3a486173684d61703c4b2c562c533e3a3a6765743a3a6836383163343836306161303736623932b002523c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c542c4d3e20617320686173685f64623a3a4861736844423c482c543e3e3a3a696e736572743a3a6862353066336439303265626363366361b102533c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c542c4d3e20617320686173685f64623a3a4861736844423c482c543e3e3a3a656d706c6163653a3a6836396266313934303966653233633661b202386861736862726f776e3a3a6d61703a3a486173684d61703c4b2c562c533e3a3a656e7472793a3a6861633566643236653362313731346564b3023d6861736862726f776e3a3a6d61703a3a566163616e74456e7472793c4b2c562c533e3a3a696e736572743a3a6832663430376337386336316663386234b4023e6861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a726573657276655f7265686173683a3a6836393838383263396365666231343762b502523c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c542c4d3e20617320686173685f64623a3a4861736844423c482c543e3e3a3a72656d6f76653a3a6834343961373437343133653934373134b602543c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c542c4d3e20617320686173685f64623a3a4861736844423c482c543e3e3a3a636f6e7461696e733a3a6836613232666166626466643133653064b702583c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c542c4d3e20617320686173685f64623a3a41734861736844423c482c543e3e3a3a61735f686173685f64623a3a6831303435346136373839353264626566b802a901636f72653a3a7074723a3a64726f705f696e5f706c6163653c6d656d6f72795f64623a3a4d656d6f727944423c73705f72756e74696d653a3a7472616974733a3a426c616b6554776f3235362c6d656d6f72795f64623a3a486173684b65793c73705f72756e74696d653a3a7472616974733a3a426c616b6554776f3235363e2c616c6c6f633a3a7665633a3a5665633c75383e3e3e3a3a6830313666303233366232343132373036b9025c3c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c542c4d3e20617320686173685f64623a3a41734861736844423c482c543e3e3a3a61735f686173685f64625f6d75743a3a6862353561343564316233626532616638ba02523c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c542c4d3e20617320686173685f64623a3a4861736844425265663c482c543e3e3a3a6765743a3a6833666134393265626263313234643331bb02573c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c542c4d3e20617320686173685f64623a3a4861736844425265663c482c543e3e3a3a636f6e7461696e733a3a6832353132323963613832383432363161bc02613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6835356538336166333663326664663035bd02613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6836366136613134663532333430396563be02613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6836656237306566616438356130326136bf02613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6830653166636430626666306463643362c002763c70616c6c65745f626f756e746965733a3a43616c6c3c543e206173206672616d655f737570706f72743a3a7472616974733a3a556e66696c7465726564446973706174636861626c653e3a3a64697370617463685f6279706173735f66696c7465723a3a6837333134666566333966323865373037c1022e6672616d655f73797374656d3a3a656e737572655f7369676e65643a3a6839343964386432313865623034363961c2027d70616c6c65745f626f756e746965733a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f626f756e746965733a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6830316431626334633937303137663333c302b60170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a726573657276653a3a6864633331623132306161326533656433c4025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865636133326566366233613338363261c502386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6866656538323763633632613763386363c602456672616d655f737570706f72743a3a7472616974733a3a456e737572654f726967696e3a3a656e737572655f6f726967696e3a3a6832613563363731373162363064633563c7024573705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a617070656e643a3a6836363166386537346163613530663636c8025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6835333133343234393238633635316166c902386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861636633653336613230613037376439ca02ad0170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a7472616e736665723a3a6865396164326362343735366132323265cb02bd0170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a736c6173685f72657365727665643a3a6834326431633664613265613535356166cc026d6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a76616c75653a3a53746f7261676556616c75653c5072656669782c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a6d75746174653a3a6865303635646432626431333966613665cd024873705f72756e74696d653a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a6864613330323036363463316562626164ce026d6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a76616c75653a3a53746f7261676556616c75653c5072656669782c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a6d75746174653a3a6866373065393061653031306163623163cf027b3c70616c6c65745f70726f78793a3a70616c6c65743a3a43616c6c3c543e206173206672616d655f737570706f72743a3a7472616974733a3a556e66696c7465726564446973706174636861626c653e3a3a64697370617463685f6279706173735f66696c7465723a3a6863323436633639653065323733663230d0025370616c6c65745f70726f78793a3a3c696d706c2070616c6c65745f70726f78793a3a70616c6c65743a3a50616c6c65743c543e3e3a3a66696e645f70726f78793a3a6836643264353862306537313934316562d102870170616c6c65745f70726f78793a3a70616c6c65743a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f70726f78793a3a70616c6c65743a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6833613734306530326565636236353064d2025170616c6c65745f70726f78793a3a3c696d706c2070616c6c65745f70726f78793a3a70616c6c65743a3a50616c6c65743c543e3e3a3a646f5f70726f78793a3a6861626666386330363533623131643365d3025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864663863313664333937366561663565d402386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830313536623363663230626436303530d50239636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a62696e6172795f7365617263683a3a6864656233663764633761666130346633d602386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6836363332326262393633366466346238d702437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6838343739323633656631306665336536d802483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6862656566353337386265376665623366d9025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6838633632623463383365333765343632da02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862616538653038373033623734343136db02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6862633935623837613635623363323666dc0248636f72653a3a7074723a3a64726f705f696e5f706c6163653c706f6c6b61646f745f72756e74696d653a3a43616c6c3e3a3a68323931336639633538376534623864322e33373630dd02743c706f6c6b61646f745f72756e74696d653a3a43616c6c206173206672616d655f737570706f72743a3a7472616974733a3a556e66696c7465726564446973706174636861626c653e3a3a64697370617463685f6279706173735f66696c7465723a3a6866376339643565333066316637366539de02703c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6838383431316236383566343135386235df027a3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e2061732073705f72756e74696d653a3a7472616974733a3a56616c6964617465556e7369676e65643e3a3a76616c69646174655f756e7369676e65643a3a6866313835343566303438646230356434e0027f73705f636f72653a3a63727970746f3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f636f72653a3a63727970746f3a3a4163636f756e74496433323e3a3a7573696e675f656e636f6465643a3a6834646261363539653937333039303266e1024a706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a6574685f7265636f7665723a3a6837393037393133346164616130393932e2025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864363861396235313731643365393731e3025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6834353966663333393336303734636463e402386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866633037643535393132366639303334e5024973705f696f3a3a68617368696e673a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6b656363616b5f3235363a3a6864616135626130643861616139646232e6025573705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a736563703235366b315f65636473615f7265636f7665723a3a6864636565653466323033633166623335e7025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6861373938656635346334393466316334e8024870616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a646f5f72656d6f76655f766f7465723a3a6837613534613936326538626338313738e902386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836663265636539333735653538626434ea02b80170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a72656d6f76655f6c6f636b3a3a6866353463643063333039303236396433eb024570616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a69735f63616e6469646174653a3a6861376664643039656332306164643332ec02766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a6839393961666664333765366238666335ed024273705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6765743a3a6831363732623435356437613030613832ee02303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861386633346532343837656333623162ef024673705f696f3a3a6d6973633a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a7072696e745f757466383a3a6832303234666164356461343966643938f0025270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a72656d6f76655f616e645f7265706c6163655f6d656d6265723a3a6839336539653134363262316565623731f102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832626263616635393132643937623365f202386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6835346161376630656365626266353932f302910170616c6c65745f656c656374696f6e735f70687261676d656e3a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6831646263383135343261336565623361f402386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831633739396334366139386635363639f502a2013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6863333430376532623132663963313036f60296013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e3e3a3a7365745f7072696d653a3a6833653861373335306333393533366464f7024470616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a646f5f70687261676d656e3a3a6839333534373134303735366363633234f802386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839646134353138643739373663656438f90239636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653a3a63616c6c5f6f6e63653a3a6833316464633234363330386135626331fa026e3c6672616d655f737570706f72743a3a73746f726167653a3a5072656669784974657261746f723c543e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6839306636323863363234323766353731fb023c73705f6e706f735f656c656374696f6e733a3a70687261676d656e3a3a7365715f70687261676d656e3a3a6866653763663162343763383161613737fc022b616c6c6f633a3a736c6963653a3a6d657267655f736f72743a3a6832373766356437373265383862363166fd022c616c6c6f633a3a736c6963653a3a696e736572745f686561643a3a6839353035626533656131336430376139fe02546672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a636f6d707574655f6d656d626572735f646966665f736f727465643a3a6864373639333235343237623535383661ff02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a683931343463366132343662386133306180037c3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a50726576616c6964617465417474657374733c543e2061732073705f72756e74696d653a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a686631623730353566656361646332643581035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68396262336162323333376464316366348203386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68653266656339393830336566663932308303753c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a683863366563343733643565666262323384035470616c6c65745f626162653a3a3c696d706c2070616c6c65745f626162653a3a70616c6c65743a3a50616c6c65743c543e3e3a3a646f5f696e697469616c697a653a3a68393031313835393863386331343736398503386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68346464386337303732326363373361378603386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68666665373861346335363539303865308703766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a68616333363936303163616465336262358803386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683839343062383635373837343838396389034b73705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a636c6561725f7072656669783a3a68636634393736343337343039336533378a035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68383231643532353261656439636466398b03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68616130323337666437356664323533338c03706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a68633363396264323135316637346238378d03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68386335616564636663316638646336348e035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68646364383632626661303034663633378f03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a68653165303339313735323330313334629003386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68643931303533376433363038393336379103386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6837663964633738333231383962666231920382023c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e2061732073705f7374616b696e673a3a6f6666656e63653a3a4f6e4f6666656e636548616e646c65723c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449642c283c542061732070616c6c65745f73657373696f6e3a3a436f6e6669673e3a3a56616c696461746f7249642c3c542061732070616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a436f6e6669673e3a3a46756c6c4964656e74696669636174696f6e292c7536343e3e3a3a6f6e5f6f6666656e63653a3a683837653765363039393930313364383293034973705f696f3a3a6f6666636861696e5f696e6465783a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a7365743a3a68636561653863643562313830613534319403766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a686331383037313533356633646338326495035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683933386336343338383963373230663696035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683063626564653761313532393438336497035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683630616630313838373337396132343198036d6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a76616c75653a3a53746f7261676556616c75653c5072656669782c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a6d75746174653a3a686633613361393035353865333365313999037a706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f7220706f6c6b61646f745f72756e74696d653a3a53657373696f6e4b6579733e3a3a6465636f64653a3a68656534346165336165636465343638329a03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a68373333306132393265643230383130399b03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68393166363235366561623235373236659c033770616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a73746172745f6572613a3a68303064666132633662303936613639669d03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68363662663036373735633136383533379e03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a68343835373832323630633236306662359f033570616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6e65775f6572613a3a6831343033303131653062646464626462a003766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a6830616364373330383063346464383766a103706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6835306437333539646535353961646534a203386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836353132613637363566313839353639a3034b70616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a50726f76696e67547269653c543e3a3a67656e65726174655f666f723a3a6866613062373062353833656639636238a4035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839373836663833313834623966356537a503386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836666563336566656234323238366436a6035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865383832613836623933623138313534a703386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862343966623735346136353530383765a803a1013c285475706c65456c656d656e74302c5475706c65456c656d656e74312c5475706c65456c656d656e74322c5475706c65456c656d656e74332c5475706c65456c656d656e74342c5475706c65456c656d656e7435292061732070616c6c65745f73657373696f6e3a3a53657373696f6e48616e646c65723c4149643e3e3a3a6f6e5f6e65775f73657373696f6e3a3a6864376661636132313263636566333234a903603c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a426c6f636b57656967687473206173206672616d655f737570706f72743a3a7472616974733a3a4765743c493e3e3a3a6765743a3a6835396263393435653263373465313736aa03753c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6831666133666564653833383234353232ab035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6836373932393537613630613139303139ac034c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a70726f636573735f636c61696d3a3a6830643834343264333366626634343639ad035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839303163353866646466353433383031ae03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830373636366630623133336137666566af03746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6837633366623861306633373432376130b0039d01706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6834613130373535623232396531663134b1035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863383930363461363366316465363234b203746672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a6d61703a3a53746f726167654d61703c5072656669782c4861736865722c4b65792c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a696e736572743a3a6839373061383763393135386465323031b3035870616c6c65745f76657374696e673a3a3c696d706c2070616c6c65745f76657374696e673a3a70616c6c65743a3a50616c6c65743c543e3e3a3a7570646174655f6c6f636b3a3a6865356538333531313866306234633261b4034270616c6c65745f70726f78793a3a70616c6c65743a3a50616c6c65743c543e3a3a63616c6c5f66756e6374696f6e733a3a6836353133613337623862353530303463b5034470616c6c65745f70726f78793a3a70616c6c65743a3a50616c6c65743c543e3a3a73746f726167655f6d657461646174613a3a6830303933313366303666306264326362b6034d70616c6c65745f70726f78793a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6834626432386134346437613463333534b7039c013c70616c6c65745f70726f78793a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d617850656e64696e6744656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839636666316631353330663537373634b8039c013c70616c6c65745f70726f78793a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d617850726f7869657344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861363264626165653234336537663065b903a4013c70616c6c65745f70726f78793a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f78794465706f736974466163746f7244656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835633736363432366363383639653833ba03a2013c70616c6c65745f70726f78793a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f78794465706f7369744261736544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832313336633039653537383934656233bb03483c706f6c6b61646f745f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6834663534653264313663303635353439bc037e70616c6c65745f70726f78793a3a70616c6c65743a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f70726f78793a3a70616c6c65743a3a43616c6c3c543e3e3a3a6465636f64653a3a6861323533316463633835653737373333bd037e70616c6c65745f70726f78793a3a70616c6c65743a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f70726f78793a3a70616c6c65743a3a43616c6c3c543e3e3a3a6465636f64653a3a6862346162346162366366336432316364be038a016672616d655f737570706f72743a3a776569676874733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206672616d655f737570706f72743a3a776569676874733a3a4469737061746368496e666f3e3a3a656e636f64655f746f3a3a6835653130633433366633656665336235bf033c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863616437373135646331623130633936c0033e70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6861396461363365363765616363333036c1036e3c70616c6c65745f73657373696f6e3a3a5f5f476574427974655374727563745175657565644b6579733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831363538333962626465366135333039c2035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6834386637303037336261396437616439c30396013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a436f6e7461696e733c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e3e3a3a636f6e7461696e733a3a6863366532336563353362646431336332c4034d706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6839323431346233346432306361633731c5034f706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832636366396435396336623439366530c60358706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6865313136353432626239663234363332c703a3013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a636c61696d733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726566697844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833633365626638613162646562656530c8034770616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6865386561343536333461363033333634c9034970616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866346233323761663365326135363232ca03753c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a5f5f47657442797465537472756374566f74696e673c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865366462353566333565313933326431cb03763c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a5f5f476574427974655374727563744d656d626572733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832383763343539326366393239646566cc035270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6836353761323739313431373934363265cd039f013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6f64756c65496444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863626365613235613233663838363839ce03a5013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a446573697265644d656d6265727344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864663737643336383337613332306562cf03a5013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67426f6e644261736544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836323262653630653339343430323731d0036a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a6861636135363437333366376435383836d1035d3c706f6c6b61646f745f72756e74696d653a3a53657373696f6e4b6579732061732073705f72756e74696d653a3a7472616974733a3a4f70617175654b6579733e3a3a6765745f7261773a3a6837663863666435666561356439303937d2036a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a6866363962626435656663366537383631d3035f3c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6833626666356136303962326266313764d403653c70616c6c65745f70726f78793a3a70616c6c65743a3a50616c6c65743c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6833356639626233643038346339393834d5036a3c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6866636132313639646637383334303638d6035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862653066643335623339626330643838d7035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837343438343531353165646336646335d8034973705f696f3a3a68617368696e673a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a626c616b65325f3132383a3a6836373938353364663563393861396532d9033c70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6833306639303937393364613637366535da033e70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838643939323762633730323536663137db034770616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6861323133336262373065356537353038dc0393013c70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863353763626532623966633061363964dd033d70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6831336536643533656436303837613538de033f70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6833663462383563643138323533363666df036f3c70616c6c65745f6964656e746974793a3a5f5f47657442797465537472756374526567697374726172733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863393234396361643063626564613932e0036b3c70616c6c65745f6964656e746974793a3a5f5f47657442797465537472756374537562734f663c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864356538356631626131363838333132e1036c3c70616c6c65745f6964656e746974793a3a5f5f4765744279746553747275637453757065724f663c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836633661613966626134376434626562e2036f3c70616c6c65745f6964656e746974793a3a5f5f476574427974655374727563744964656e746974794f663c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835356638333534346532663037656164e3034a636f72653a3a7074723a3a64726f705f696e5f706c6163653c70616c6c65745f6964656e746974793a3a4964656e74697479496e666f3e3a3a6835363532633932383730616537363761e4034870616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6832306633653532663330306463343135e5039a013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d61785265676973747261727344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834313435633435646337336563646338e6039e013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5375624163636f756e744465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861623366383532396636653366336464e70399013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4669656c644465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864636637366133386663636364353630e80399013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a42617369634465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830663531393062393861653838643666e903850170616c6c65745f6964656e746974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f6964656e746974793a3a526567697374726174696f6e3c42616c616e63653e3e3a3a656e636f64655f746f3a3a6865333837336532643536343666613861ea03820170616c6c65745f6964656e746974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f6964656e746974793a3a4a756467656d656e743c42616c616e63653e3e3a3a656e636f64655f746f3a3a6836313661346630333738383731633432eb03573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6839346437366261643037623237653735ec03573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6862333836386437353330343962656362ed03573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6832303736366165333465373666616163ee033d70616c6c65745f6d756c74697369673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864306566633638646636366233643930ef033f70616c6c65745f6d756c74697369673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6839663835323535366665376264323335f0034870616c6c65745f6d756c74697369673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6835636338613863653034386235653135f1039b013c70616c6c65745f6d756c74697369673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d61785369676e61746f7269657344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832303365363332613866646430396362f2039a013c70616c6c65745f6d756c74697369673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4465706f736974466163746f7244656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864396231386162303333656133313730f30398013c70616c6c65745f6d756c74697369673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4465706f7369744261736544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838643436663732383137323037366138f4033f70616c6c65745f74726561737572793a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6838326165393938666630636331353861f5034170616c6c65745f74726561737572793a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6835666538313231366365396362663362f603703c70616c6c65745f74726561737572793a3a5f5f47657442797465537472756374417070726f76616c733c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862383932643864333533313934663438f7034a70616c6c65745f74726561737572793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6839643936633239303039666331396661f80399013c70616c6c65745f74726561737572793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6f64756c65496444656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863306238616364646261363865323239f90395013c70616c6c65745f74726561737572793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4275726e44656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865633262653666653539663761653333fa039c013c70616c6c65745f74726561737572793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5370656e64506572696f6444656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861646630373639353636333831653061fb039d013c70616c6c65745f74726561737572793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f706f73616c426f6e6444656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839643539366538343762393066393362fc03603c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6831643331336231336334666138643065fd03603c70616c6c65745f6d756c74697369673a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6861333432313564643131373737303232fe03623c70616c6c65745f74726561737572793a3a4d6f64756c653c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6837633863353133336365643263626230ff035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68336439633230316464653065333135318004763c70616c6c65745f6964656e746974793a3a43616c6c3c543e206173206672616d655f737570706f72743a3a7472616974733a3a556e66696c7465726564446973706174636861626c653e3a3a64697370617463685f6279706173735f66696c7465723a3a68343834306132656462303138313331308104766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a68626564663437333565326366373265348204386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a683962396637383936356238653836303383047d70616c6c65745f6964656e746974793a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f6964656e746974793a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a683130643133663937396631343638623484045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68653063663231626531393462383464328504386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68646537643636636364656530373735308604386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a686463363165393636616564323834313587045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68653131643263386135343964343839348804386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68313334306262333666323966326562378904c20170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a726570617472696174655f72657365727665643a3a68616462666635313762333464663866618a04386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a68366364363233303036396533373834658b04386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a68373231663730343165363035663865618c0448636f72653a3a7074723a3a64726f705f696e5f706c6163653c706f6c6b61646f745f72756e74696d653a3a43616c6c3e3a3a68323931336639633538376534623864322e313936368d044770616c6c65745f6d756c74697369673a3a4d6f64756c653c543e3a3a656e737572655f736f727465645f616e645f696e736572743a3a68343335333836303531366237323937348e047d70616c6c65745f6d756c74697369673a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f6d756c74697369673a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a68323237653366396337616534383335348f043670616c6c65745f6d756c74697369673a3a4d6f64756c653c543e3a3a6f7065726174653a3a68616463633732353463656637653537349004437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68376361303836333334393736623535399104706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a68343061396537663831636236326632619204386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683633623765646561343538636333333093044570616c6c65745f6d756c74697369673a3a4d6f64756c653c543e3a3a73746f72655f63616c6c5f616e645f726573657276653a3a68323430386535656565666339343063669404386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a686566643932633663623038613836366595045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68323032383837323661363461666436389604386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68333131656566626538653064373865399704693c706f6c6b61646f745f72756e74696d653a3a43616c6c206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a683462393330303139653165316662623898043970616c6c65745f6d756c74697369673a3a4d6f64756c653c543e3a3a636c6561725f63616c6c3a3a686538346231626332646434613538343499045d70616c6c65745f626162653a3a3c696d706c2070616c6c65745f626162653a3a70616c6c65743a3a50616c6c65743c543e3e3a3a646f5f7265706f72745f65717569766f636174696f6e3a3a68613132646131633262386639373930639a043473705f72756e74696d653a3a7472616974733a3a486173683a3a686173685f6f663a3a68616230333232646265626164393335359b044b73705f636f6e73656e7375735f626162653a3a636865636b5f65717569766f636174696f6e5f70726f6f663a3a7b7b636c6f737572657d7d3a3a68616362316438626136393136623965309c045d3c73705f72756e74696d653a3a44697370617463684572726f7257697468506f7374496e666f3c543e20617320636f72653a3a636f6e766572743a3a46726f6d3c453e3e3a3a66726f6d3a3a68306431663965353836643261306238649d0495013c70616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a4b65794f776e657250726f6f6653797374656d3c2873705f636f72653a3a63727970746f3a3a4b65795479706549642c44293e3e3a3a636865636b5f70726f6f663a3a68323730653566616534363162306534629e043d73705f61726974686d657469633a3a7065725f7468696e67733a3a50657262696c6c3a3a7371756172653a3a68613435383139626232663061646631369f04763c70616c6c65745f617574686f726974795f646973636f766572793a3a43616c6c3c543e206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6865626466643235336163643433393530a004386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861393962303137326439373231663330a104386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864653331393230386662366432346235a204386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865343363353732613638383430363436a304386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832656465363336313862363431626363a4043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6834336434353863643363326339653332a5046d6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a76616c75653a3a53746f7261676556616c75653c5072656669782c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a617070656e643a3a6830386461383561386636303133313438a604386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6864346436613861386633396238643038a7045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839346462326262323766323730333833a8044d3c706f6c6b61646f745f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68346635346532643136633036353534392e31393734a9045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6836636535656131383561353736636634aa04776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a617070656e643a3a6835636131613035303530356235343434ab04a70170616c6c65745f7363686564756c65723a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f7363686564756c65723a3a5363686564756c656456323c43616c6c2c426c6f636b4e756d6265722c50616c6c6574734f726967696e2c4163636f756e7449643e3e3a3a656e636f64655f746f3a3a6832326166356638373438666136333132ac044170616c6c65745f626162653a3a70616c6c65743a3a50616c6c65743c543e3a3a63616c6c5f66756e6374696f6e733a3a6836333839303937316532626565666261ad044370616c6c65745f626162653a3a70616c6c65743a3a50616c6c65743c543e3a3a73746f726167655f6d657461646174613a3a6864623934656133363064393565313530ae044c70616c6c65745f626162653a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6833323335323762663566633439643335af04a2013c70616c6c65745f626162653a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835376365393532636533626636323130b0049e013c70616c6c65745f626162653a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834336337333932323031383333613036b1048f0170616c6c65745f64656d6f63726163793a3a766f74653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f64656d6f63726163793a3a766f74653a3a4163636f756e74566f74653c42616c616e63653e3e3a3a6465636f64653a3a6862323037393738343931626230316262b204920170616c6c65745f64656d6f63726163793a3a766f74653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a766f74653a3a4163636f756e74566f74653c42616c616e63653e3e3a3a656e636f64655f746f3a3a6836623835616336316263393232313361b3043e70616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6834613261623933666330363330633631b4044070616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6836636632666533343364346461373734b504743c70616c6c65745f7363686564756c65723a3a5f5f4765744279746553747275637453746f7261676556657273696f6e3c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864323633666330323330333033626436b6043f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6833616463366263363537346437313436b7043173705f6e706f735f656c656374696f6e733a3a746f5f737570706f7274733a3a6861666439373331643136633831316439b80437616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6837653863323639363931353362363861b9043273705f6e706f735f656c656374696f6e733a3a73657475705f696e707574733a3a6837656238313935316432393166323736ba0468636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6864363661356139383836363239653032bb044d73705f6e706f735f656c656374696f6e733a3a566f7465723c4163636f756e7449643e3a3a7472795f6e6f726d616c697a655f656c65637465643a3a6862653563363137363963393538356463bc045a3c616c6c6f633a3a7665633a3a5665633c753132383e2061732073705f61726974686d657469633a3a4e6f726d616c697a61626c653c753132383e3e3a3a6e6f726d616c697a653a3a6839303136313262656538323130313339bd044a73705f6e706f735f656c656374696f6e733a3a41737369676e6d656e743c4163636f756e7449642c503e3a3a696e746f5f7374616b65643a3a6833633237383735663837336439383439be044c73705f6e706f735f656c656374696f6e733a3a41737369676e6d656e743c4163636f756e7449642c503e3a3a7472795f6e6f726d616c697a653a3a6864306632373462636138386433636534bf045073705f6e706f735f656c656374696f6e733a3a5374616b656441737369676e6d656e743c4163636f756e7449643e3a3a7472795f6e6f726d616c697a653a3a6838393566656563623433653033623266c0043873705f6e706f735f656c656374696f6e733a3a62616c616e63696e673a3a62616c616e63653a3a6865653666636530363964346438663566c1042c616c6c6f633a3a736c6963653a3a696e736572745f686561643a3a6833386661393063363663633439663732c2043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6839623564343334343237623536333236c3043f70616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a646f5f63616e63656c5f6e616d65643a3a6830646634316432383231353463363938c4045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6836306633616134616634663532316234c504386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834363936613138316330633037626238c6044f3c706f6c6b61646f745f72756e74696d653a3a4f726967696e43616c6c657220617320636f72653a3a636d703a3a5061727469616c45713e3a3a6e653a3a6861353539633235333930353666633537c704386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6836646634616365623336623264343462c8047f70616c6c65745f7363686564756c65723a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f7363686564756c65723a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6832653238613266313864373332313135c9044170616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a646f5f7363686564756c655f6e616d65643a3a6837386236343764333735336132633966ca044373705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a726561643a3a6831613263386662613833353065656134cb04433c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6832303430316436366632336562393734cc04433c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6864323062653836376362326563383664cd04a201636f72653a3a7074723a3a64726f705f696e5f706c6163653c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c616c6c6f633a3a72633a3a52633c636f72653a3a63656c6c3a3a52656643656c6c3c73705f6e706f735f656c656374696f6e733a3a6e6f64653a3a4e6f64653c73705f636f72653a3a63727970746f3a3a4163636f756e74496433323e3e3e3e3e3a3a6837363339396666656266653065656630ce043d73705f636f72653a3a746f5f7375627374726174655f7761736d5f666e5f72657475726e5f76616c75653a3a6862323164393930633331366331653238cf043d73705f636f72653a3a746f5f7375627374726174655f7761736d5f666e5f72657475726e5f76616c75653a3a6864613162393666633238333736316235d0047873705f636f72653a3a63727970746f3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f636f72653a3a63727970746f3a3a4163636f756e74496433323e3a3a6465636f64653a3a6839653731326130306137363933643834d1042e616c6c6f633a3a7261775f7665633a3a66696e6973685f67726f773a3a6838636564306562626163616539663337d204553c70616c6c65745f62616c616e6365733a3a44757374436c65616e65723c542c493e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6831393635353932326232643331663061d304613c70616c6c65745f7363686564756c65723a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6830643665333666343930383536653763d404643c70616c6c65745f626162653a3a70616c6c65743a3a50616c6c65743c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6864323534363337313136316339346264d504773c70616c6c65745f7363686564756c65723a3a43616c6c3c543e206173206672616d655f737570706f72743a3a7472616974733a3a556e66696c7465726564446973706174636861626c653e3a3a64697370617463685f6279706173735f66696c7465723a3a6838333861376663303063633431663265d6043b70616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a646f5f7363686564756c653a3a6866323966343436646662376466373666d7046b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830643630363462633439636166353032d8046b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6861356438653733353039373863343265d9046b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6834383032623466376565646238316231da046b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6865346463656637306165656164633965db046c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6866333633353564336365303233666139dc04713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6837383339636535356637343265343164dd0431636f72653a3a70616e69636b696e673a3a6173736572745f6661696c65643a3a6866323565313332343861393263626530de0431636f72653a3a70616e69636b696e673a3a6173736572745f6661696c65643a3a6834643763613939306565626363626661df043d706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a426c6f636b576569676874733a3a6765743a3a6839336264306338383566663261346531e004960173705f7374616b696e673a3a6f6666656e63653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f7374616b696e673a3a6f6666656e63653a3a4f6666656e636544657461696c733c5265706f727465722c4f6666656e6465723e3e3a3a6465636f64653a3a6835643836663139373036633835393739e104766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a6837633634353565626638336465343134e2043770616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a6838386434346435343262333762663130e3043b70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a7265776172645f62795f6964733a3a6833613233366363376165393766373839e4043f70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a6e6f74655f617574686f72736869703a3a6862656335633264633061643630396338e504386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6865373630323731363931666466336637e604386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6836613936376334333532623439653034e7044970616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a636f6d707574655f6665655f7261773a3a6833313031393864326262626331316266e804466672616d655f737570706f72743a3a776569676874733a3a576569676874546f466565506f6c796e6f6d69616c3a3a63616c633a3a6865373736303062323863386331366232e904386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839336333623635346562636164666565ea044673705f61726974686d657469633a3a68656c706572735f3132386269743a3a6d756c7469706c795f62795f726174696f6e616c3a3a6836323434636635306439633764393262eb046a6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a76616c75653a3a53746f7261676556616c75653c5072656669782c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a7075743a3a6832313162326636663932336336663534ec046a6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a76616c75653a3a53746f7261676556616c75653c5072656669782c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a7075743a3a6832333463393638646133323561613739ed046a6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a76616c75653a3a53746f7261676556616c75653c5072656669782c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a7075743a3a6838303130323133373864313238393238ee046a6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a76616c75653a3a53746f7261676556616c75653c5072656669782c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a7075743a3a6862376561653564663330316439393734ef046f3c73705f72756e74696d653a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6832626337626565653336326334336162f0046a6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a76616c75653a3a53746f7261676556616c75653c5072656669782c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a7075743a3a6863303061626262333264383135303233f1046d6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a76616c75653a3a53746f7261676556616c75653c5072656669782c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a6d75746174653a3a6863666364363534303031613462356464f204386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830326436653762386232393466663866f304386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6865303732613930666335646532396335f404766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a6834386465396533616565656337346163f504766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a6865313039633563643564363934653166f6043f70616c6c65745f6f6666656e6365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832326533616338643335626530323932f704773c70616c6c65745f6f6666656e6365733a3a5f5f476574427974655374727563745265706f72747342794b696e64496e6465783c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866343532663030373334383733316630f804753c70616c6c65745f6f6666656e6365733a3a5f5f4765744279746553747275637444656665727265644f6666656e6365733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861356461326230653532363737636462f9046c3c70616c6c65745f6f6666656e6365733a3a5f5f476574427974655374727563745265706f7274733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838313236373063623331663966383931fa044c73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7665726966793a3a6830613965313635396366646564303966fb046b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7531363e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6832653266643130383536646633363061fc046b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7531363e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6839343765653431363262323061613237fd047f7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202851302c5230293e3a3a656e636f64655f746f3a3a6865373061616163386239666130363838fe044a70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6830393632663566333561323836306233ff0481013c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a5f5f476574427974655374727563744e6578744665654d756c7469706c6965723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683331323734323632373466396464306180055370616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68303761656332643535353339393662658105a3013c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a576569676874546f46656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686466393631616138663536343965313782056d3c73705f61726974686d657469633a3a7065725f7468696e67733a3a50657262696c6c2061732073705f61726974686d657469633a3a7065725f7468696e67733a3a5065725468696e673e3a3a66726f6d5f726174696f6e616c3a3a68383663353535316139383136366332658305aa013c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686637306535626133336433333937313384056b3c70616c6c65745f6f6666656e6365733a3a43616c6c3c543e206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a68383863306366663831316637316639658505860170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7374616b696e673a3a4578706f737572653c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a686331383030646435646334643637613086055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68663262386133633435316564373834348705386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683966363261303166333530653539376688056c3c636f72653a3a697465723a3a61646170746572733a3a6d61703a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a683265393663626364336636313832623389055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68313262333364613838313462333930318a05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68643763383630303539346561306131328b054773705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6e6578745f6b65793a3a68313461663835393261663033343962308c056e3c6672616d655f737570706f72743a3a73746f726167653a3a5072656669784974657261746f723c543e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68393763346161356563383833653037328d056e3c6672616d655f737570706f72743a3a73746f726167653a3a5072656669784974657261746f723c543e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68643561393230653530363430303762388e05aa0173705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a5472616e73616374696f6e56616c69646974794572726f723e3a3a656e636f64655f746f3a3a68333733393737303633633263373539328f053473705f72756e74696d653a3a7472616974733a3a486173683a3a686173685f6f663a3a683562323837343836313038356464333490053e73705f72756e74696d653a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6865313839373563656665383534623036910591017061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220284b302c4c302c4d302c4e302c4f302c50302c51302c5230293e3a3a656e636f64655f746f3a3a6836313165353933613362643063666566920556616c6c6f633a3a7665633a3a73706c6963653a3a3c696d706c20616c6c6f633a3a7665633a3a647261696e3a3a447261696e3c542c413e3e3a3a6d6f76655f7461696c3a3a683230316331323265376166613434316193057d3c6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a4f6e456d7074794765747465723c56616c75652c4f6e456d7074793e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683064313361386638656634663465356194057d3c6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a4f6e456d7074794765747465723c56616c75652c4f6e456d7074793e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68333537373339303165376334353334379505483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683339613336303035363632613033653796057d3c6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a4f6e456d7074794765747465723c56616c75652c4f6e456d7074793e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683436363230653539666334613733303297057d3c6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a4f6e456d7074794765747465723c56616c75652c4f6e456d7074793e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683861643761303761393437333532643598057d3c6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a4f6e456d7074794765747465723c56616c75652c4f6e456d7074793e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683933373561386462396163306136636299057d3c6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a4f6e456d7074794765747465723c56616c75652c4f6e456d7074793e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68613531623630613964323164643464669a057d3c6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a4f6e456d7074794765747465723c56616c75652c4f6e456d7074793e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68613934383166663564333230643134669b057d3c6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a4f6e456d7074794765747465723c56616c75652c4f6e456d7074793e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68643266346534643665346335393534629c057d3c6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a4f6e456d7074794765747465723c56616c75652c4f6e456d7074793e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68643332623666633033313831643832349d057d3c6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a4f6e456d7074794765747465723c56616c75652c4f6e456d7074793e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68653266306466316236316335346162389e057d3c6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a4f6e456d7074794765747465723c56616c75652c4f6e456d7074793e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68653938356566663732356331313734399f055a6672616d655f73797374656d3a3a657874656e73696f6e733a3a636865636b5f7765696768743a3a436865636b5765696768743c543e3a3a646f5f7072655f64697370617463683a3a6862613239353437326664666130663865a005566672616d655f73797374656d3a3a657874656e73696f6e733a3a636865636b5f7765696768743a3a436865636b5765696768743c543e3a3a646f5f76616c69646174653a3a6836346530343863656535626261613033a1055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864323337336331306362393638323834a205386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836353338613935353563323364323263a30552616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a656e7472793a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6837653236653931393464303138396139a4053b6672616d655f737570706f72743a3a73746f726167653a3a776974685f7472616e73616374696f6e3a3a6862333062653837363832313266366661a5055073705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a73746172745f7472616e73616374696f6e3a3a6837353866333538383836366262313833a6054a3c706f6c6b61646f745f72756e74696d653a3a4f726967696e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830316439303835303930643336646266a7052c6672616d655f73797374656d3a3a656e737572655f726f6f743a3a6862393135316334303165306664316163a8055373705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a726f6c6c6261636b5f7472616e73616374696f6e3a3a6831613238343538616562323333623365a9055173705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a636f6d6d69745f7472616e73616374696f6e3a3a6865366663303539313834383933383230aa05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831643937633731653330323337633762ab05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832643961383431353139353338653735ac05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834373637326331373635326364666137ad05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835383234346161313063306332663761ae05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835393565626236303631393766363431af05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835623730313937313632333432333932b005386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835633265386438666234383431343835b105386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836613939653831643238323934356462b205386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836623961626330303432363963353738b305386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837356131316635626461616532333934b405386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838346337303766323939666337666165b505910173705f72756e74696d653a3a67656e657269633a3a6469676573743a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f72756e74696d653a3a67656e657269633a3a6469676573743a3a4469676573743c486173683e3e3a3a6465636f64653a3a6866666336666134643839666262333835b605386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864663336393061613039396331623435b705386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866323063323866616466663064373537b805386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866366239393637393833333632396137b905386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6830316136386237323036336239633663ba05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6830643638343464326239303732323166bb05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6830663565303730346330626235653361bc05a80170616c6c65745f64656d6f63726163793a3a74797065733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a74797065733a3a5265666572656e64756d496e666f3c426c6f636b4e756d6265722c486173682c42616c616e63653e3e3a3a656e636f64655f746f3a3a6833393132613565306130396636393732bd05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6832343739386131613963336566386332be05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6832363339643130326162623731343763bf05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6832366263653762613239363739393930c005386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6832376531366333376562353033343765c105386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6832656230313163333037663435396531c205386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6834643235363165353934383638396537c305386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6836306331653766613032373836613262c405386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6836653639353430666537393530633838c505386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6838363836393238386266666238313865c605386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6839326638653363346263393337653339c705386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6839366337303361393739623433363232c805386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6863303235313133316334333266626566c905386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6863326461626430396566656437343665ca05386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6863616539373034656664623065633761cb05706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6833653836366563376335633738386664cc05706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6866376137383338643362313433613164cd055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862386636626264613439633538303738ce05746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6837333564613637336162323864636436cf055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862623638393463303330663962663533d005776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6833616664303937343536316235653066d1055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832616531656461653438336631336333d205776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6838376165303239623432383536346539d3055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831336432646263346231336162303132d4053c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863396137663838326432336334333939d5053e70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832303863386262643862623133393935d605723c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637453746f7261676556657273696f6e3c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835366430613662623731386566376637d7056d3c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563745370616e536c6173683c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836623764343038353064363961333834d805743c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374556e6170706c696564536c61736865733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830353866643664613931386235616134d905723c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637445726173546f74616c5374616b653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830393732306461303364366661303734da05743c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637445726173526577617264506f696e74733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830313730626366343634353064313732db05763c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563744572617356616c696461746f7250726566733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866323537386534666539396561646666dc05763c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374457261735374616b657273436c69707065643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837396262346565386539666132613537dd05713c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374496e76756c6e657261626c65733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864373564656237393562663337356534de05703c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374486973746f727944657074683c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862393438633139346433393264303231df054770616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864333731303266376631656233626462e0059a013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d61784e6f6d696e6174696f6e7344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862316563666466336362353732636634e105ac013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d61784e6f6d696e61746f72526577617264656450657256616c696461746f7244656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835366432366438313262626561373339e2059e013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a536c61736844656665724475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864366363633532663232303464303266e3059b013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f6e64696e674475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866383436366565316631636661613531e4059a013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53657373696f6e7350657245726144656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833633864336336663064643236656437e5055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831613962636330343532353134396239e605386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838623130303734623563643737623936e7053c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6866346262366538363138313361393064e8053f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6839396539393962343666316539663831e905d0013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e206173206672616d655f656c656374696f6e5f70726f76696465725f737570706f72743a3a456c656374696f6e4461746150726f76696465723c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a426c6f636b4e756d6265723e3e3a3a766f746572733a3a6861613465663133393363346436366538ea0539636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653a3a63616c6c5f6f6e63653a3a6830616136646231633364343130616636eb056e3c6672616d655f737570706f72743a3a73746f726167653a3a5072656669784974657261746f723c543e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6861383361306561303339653736323336ec0539636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653a3a63616c6c5f6f6e63653a3a6839613363303536613561633134353838ed0539636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653a3a63616c6c5f6f6e63653a3a6835363937353737356631643834343931ee055270616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a736c61736861626c655f62616c616e63655f6f665f666e3a3a7b7b636c6f737572657d7d3a3a6832656162393334393363636135636163ef05d1013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e206173206672616d655f656c656374696f6e5f70726f76696465725f737570706f72743a3a456c656374696f6e4461746150726f76696465723c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a426c6f636b4e756d6265723e3e3a3a746172676574733a3a6833373539653864663034336232303035f005cc013c70616c6c65745f7374616b696e673a3a53746173684f663c543e2061732073705f72756e74696d653a3a7472616974733a3a436f6e766572743c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449642c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e3e3e3a3a636f6e766572743a3a6833333639353361653765356138333730f105766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a6832313230346639623837663461353834f2054970616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a6572615f7370616e3a3a6833353231613262323063323434653335f3057d3c542061732070616c6c65745f7374616b696e673a3a53657373696f6e496e746572666163653c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e3e3a3a64697361626c655f76616c696461746f723a3a6865313636356666353965663735656635f4055e70616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a636f6d706172655f616e645f7570646174655f7370616e5f736c6173683a3a6862326431313064646332393230633263f505386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864306137353530333533356338386336f6054370616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a636c6561725f6572615f696e666f726d6174696f6e3a3a6835366537623239626234643366313734f705706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6831373762373438633364363031303364f805706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6837316635336364323239333131663934f9055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6861376666363138303133663662613333fa053870616c6c65745f7374616b696e673a3a736c617368696e673a3a6170706c795f736c6173683a3a6865396138653035383033373036363936fb05363c5420617320636f72653a3a636f6e766572743a3a496e746f3c553e3e3a3a696e746f3a3a6831376533363964343461323066633165fc05633c54206173207061726974795f7363616c655f636f6465633a3a64657074685f6c696d69743a3a4465636f64654c696d69743e3a3a6465636f64655f616c6c5f776974685f64657074685f6c696d69743a3a6866313931336463333735633731643032fd05593c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6836366231633538313031306538666335fe05593c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6861316164323531636364396565643633ff05653c73705f747269653a3a6e6f64655f6865616465723a3a4e6f6465486561646572206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683739303464376339343638306565336180065f3c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a68383132653264383139316437363663668106753c70616c6c65745f7374616b696e673a3a43616c6c3c543e206173206672616d655f737570706f72743a3a7472616974733a3a556e66696c7465726564446973706174636861626c653e3a3a64697370617463685f6279706173735f66696c7465723a3a683066363038653139616363383838396582067b70616c6c65745f7374616b696e673a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f7374616b696e673a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a68666132613161363532643639346335358306566672616d655f73797374656d3a3a3c696d706c206672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3e3a3a696e635f636f6e73756d6572733a3a683935616432666537343033363537643984065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68336638313234363166356261656134308506b50170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a7365745f6c6f636b3a3a683132343765663161663238623839663686063870616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a68616361383233333830336231373834358706386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683433623430353133663736656534663688066b3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a686538663162333530633139393962663589063970616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a68616466396639623663313633313636648a06566672616d655f73797374656d3a3a3c696d706c206672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3e3a3a6465635f636f6e73756d6572733a3a68653130613938326666366230323637398b06ba0170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a6465706f7369745f696e746f5f6578697374696e673a3a68353564396361386662633731346566668c063970616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a68653036386231613066313364316639398d06733c706f6c6b61646f745f72756e74696d653a3a4e706f73436f6d70616374536f6c7574696f6e31362061732073705f6e706f735f656c656374696f6e733a3a436f6d70616374536f6c7574696f6e3e3a3a696e746f5f61737369676e6d656e743a3a68383662656637653638616137393934358e066b3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68303439363935306666643166343161348f06753c73705f72756e74696d653a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a686434613438666561653964313739346590068e0173705f66696e616c6974795f6772616e6470613a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f66696e616c6974795f6772616e6470613a3a45717569766f636174696f6e50726f6f663c482c4e3e3e3a3a656e636f64655f746f3a3a68326336633638653366333463383831379106693c706f6c6b61646f745f72756e74696d653a3a4e706f73436f6d70616374536f6c7574696f6e3136206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6833376233626338346637333131316562920637636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743a3a63616c6c5f6d75743a3a68306163316662333937636132363265639306773c706f6c6b61646f745f72756e74696d653a3a4f726967696e20617320636f72653a3a636f6e766572743a3a46726f6d3c706f6c6b61646f745f72756e74696d653a3a4f726967696e43616c6c65723e3e3a3a66726f6d3a3a7b7b636c6f737572657d7d3a3a6864353432643866363432373837353136940648636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653a3a63616c6c5f6f6e63657b7b767461626c652e7368696d7d7d3a3a68373561353066643937393262346164649506693c706f6c6b61646f745f72756e74696d653a3a4e706f73436f6d70616374536f6c7574696f6e3136206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68336666643431633331376139313436339606693c706f6c6b61646f745f72756e74696d653a3a4e706f73436f6d70616374536f6c7574696f6e3136206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68356534653061306461343764373239629706723c706f6c6b61646f745f72756e74696d653a3a4e706f73436f6d70616374536f6c7574696f6e31362061732073705f6e706f735f656c656374696f6e733a3a436f6d70616374536f6c7574696f6e3e3a3a756e697175655f746172676574733a3a6865386439303736323031383930613532980646616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a7365743a3a42547265655365743c543e3a3a696e736572743a3a68373830363234353663656366626435659906733c706f6c6b61646f745f72756e74696d653a3a4e706f73436f6d70616374536f6c7574696f6e31362061732073705f6e706f735f656c656374696f6e733a3a436f6d70616374536f6c7574696f6e3e3a3a66726f6d5f61737369676e6d656e743a3a68323861626238346565343235633038619a065d636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e3c413e20666f722026463e3a3a63616c6c3a3a68316431306565363665383137303163649b0654636f72653a3a7074723a3a64726f705f696e5f706c6163653c706f6c6b61646f745f72756e74696d653a3a4e706f73436f6d70616374536f6c7574696f6e31363e3a3a68373239643065616231303334343434649c0677706f6c6b61646f745f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f72756e74696d653a3a4576656e743e3a3a656e636f64655f746f3a3a68343037663536306235326365623031319d067373705f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a656e636f64655f746f3a3a68383332353664653833633230623434349e064a706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6672616d655f73797374656d3a3a68633533306532643962323361356432329f064e706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7363686564756c65723a3a6830343563623461633633616633326532a0064c706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f696e64696365733a3a6836363263636437316231393864633661a1064d706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f62616c616e6365733a3a6834643537343163373334653762353235a2064c706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7374616b696e673a3a6863366363363534326164313330383764a3064d706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6f6666656e6365733a3a6865653236326230333833363332313837a4064c706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f73657373696f6e3a3a6832383136353735303865316336386130a5064c706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6772616e6470613a3a6864643434393862306234306465613630a6064e706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f696d5f6f6e6c696e653a3a6830396239663264316464666363366366a7064e706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f64656d6f63726163793a3a6863383939333330653036343133636338a80659706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f636f6c6c6563746976655f496e7374616e6365313a3a6830663736633337636262633466623766a90657706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f656c656374696f6e735f70687261676d656e3a3a6833316566313062376164653065643930aa0659706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6d656d626572736869705f496e7374616e6365313a3a6864393739616531376563313166363633ab064d706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f74726561737572793a3a6839373430313532346666616632383537ac0644706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636c61696d733a3a6833633236623266643062646136343637ad064c706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f76657374696e673a3a6837306133653037343936393464343732ae064c706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7574696c6974793a3a6863613261393336373431333365393038af064d706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6964656e746974793a3a6835343436376138376564343435336165b0064a706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f70726f78793a3a6866346565396162613464333736636138b1064d706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6d756c74697369673a3a6835313237353862393831666339386533b2064d706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f626f756e746965733a3a6863383165663062323734326364663161b30649706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f746970733a3a6838613230663464626366393935333833b40662706f6c6b61646f745f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a6830333665383266366133646635623532b506eb01636f72653a3a7074723a3a64726f705f696e5f706c6163653c3c706f6c6b61646f745f72756e74696d653a3a4f726967696e206173206672616d655f737570706f72743a3a7472616974733a3a4f726967696e54726169743e3a3a6164645f66696c7465723c70616c6c65745f70726f78793a3a3c696d706c2070616c6c65745f70726f78793a3a70616c6c65743a3a50616c6c65743c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e3e3a3a646f5f70726f78793a3a7b7b636c6f737572657d7d3e3a3a7b7b636c6f737572657d7d3e3a3a6835653732376263343238633233386536b6066c3c706f6c6b61646f745f72756e74696d653a3a4f726967696e206173206672616d655f737570706f72743a3a7472616974733a3a4f726967696e54726169743e3a3a6164645f66696c7465723a3a7b7b636c6f737572657d7d3a3a6833663166663730393666313564653234b70648636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653a3a63616c6c5f6f6e63657b7b767461626c652e7368696d7d7d3a3a6861386533653264643231363530323735b8069f0170616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a756e7369676e65643a3a3c696d706c2070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a70616c6c65743a3a50616c6c65743c543e3e3a3a756e7369676e65645f7072655f64697370617463685f636865636b733a3a6838353734646366663966393261353232b9068a0170616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a3c696d706c2070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a70616c6c65743a3a50616c6c65743c543e3e3a3a666561736962696c6974795f636865636b3a3a6839666265626461343831626234663530ba064b73705f696f3a3a6d6973633a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a72756e74696d655f76657273696f6e3a3a6863393133363666363361356239393737bb062c6672616d655f73797374656d3a3a656e737572655f6e6f6e653a3a6838666165653839613434383838393631bc067b70616c6c65745f696e64696365733a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f696e64696365733a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6839636665643530373033653237643538bd06746672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a6d61703a3a53746f726167654d61703c5072656669782c4861736865722c4b65792c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a6d75746174653a3a6861636534633130646463376238343565be067f6672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a6d61703a3a53746f726167654d61703c5072656669782c4861736865722c4b65792c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a7472795f6d75746174655f6578697374733a3a6837633334313964376563323739653062bf06810170616c6c65745f617574686f72736869703a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f617574686f72736869703a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6863636331393630363137353164623866c0067b70616c6c65745f73657373696f6e3a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f73657373696f6e3a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6831643266363066313230343139616235c1064470616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a646f5f7265706f72745f65717569766f636174696f6e3a3a6834633531326432636333643438623334c206706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6866666530636335643365353938343235c306773c70616c6c65745f64656d6f63726163793a3a43616c6c3c543e206173206672616d655f737570706f72743a3a7472616974733a3a556e66696c7465726564446973706174636861626c653e3a3a64697370617463685f6279706173735f66696c7465723a3a6833316537376466316466336237366465c4067a3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a556e66696c7465726564446973706174636861626c653e3a3a64697370617463685f6279706173735f66696c7465723a3a6861346366646165313636653465313362c5067a3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a556e66696c7465726564446973706174636861626c653e3a3a64697370617463685f6279706173735f66696c7465723a3a6862636137306562356438353963643832c606723c70616c6c65745f746970733a3a43616c6c3c543e206173206672616d655f737570706f72743a3a7472616974733a3a556e66696c7465726564446973706174636861626c653e3a3a64697370617463685f6279706173735f66696c7465723a3a6834656439643435616462366261393364c7067a3c70616c6c65745f6d656d626572736869703a3a43616c6c3c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a556e66696c7465726564446973706174636861626c653e3a3a64697370617463685f6279706173735f66696c7465723a3a6838383664383761393533303662363932c8068b0173705f66696e616c6974795f6772616e6470613a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f66696e616c6974795f6772616e6470613a3a45717569766f636174696f6e50726f6f663c482c4e3e3e3a3a6465636f64653a3a6834663162393161383030666132333133c9067a70616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a6862373233643533353561376434613365ca06820170616c6c65745f7574696c6974793a3a70616c6c65743a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7574696c6974793a3a70616c6c65743a3a43616c6c3c543e3e3a3a6465636f64653a3a6839313231626235656464613035323664cb068b0173705f66696e616c6974795f6772616e6470613a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f66696e616c6974795f6772616e6470613a3a45717569766f636174696f6e50726f6f663c482c4e3e3e3a3a6465636f64653a3a6862363265666136613065656162303061cc067a70616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a6834313734613634613561363034333835cd06820170616c6c65745f7574696c6974793a3a70616c6c65743a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7574696c6974793a3a70616c6c65743a3a43616c6c3c543e3e3a3a6465636f64653a3a6866393632313564363330306139316663ce06aa02616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a72656d6f76653a3a3c696d706c20616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a48616e646c653c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4e6f64655265663c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4d75742c4b2c562c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4c6561663e2c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4b563e3e3a3a72656d6f76655f6c6561665f6b763a3a6831326231626237366633613265643166cf0664616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a42616c616e63696e67436f6e746578743c4b2c563e3a3a6d657267655f747261636b696e675f6368696c645f656467653a3a6834613135623035366339373064663466d0065a616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a42616c616e63696e67436f6e746578743c4b2c563e3a3a62756c6b5f737465616c5f6c6566743a3a6839373631616434366137666633663038d1065b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a42616c616e63696e67436f6e746578743c4b2c563e3a3a62756c6b5f737465616c5f72696768743a3a6833623236626563373231363965336138d20660616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a42616c616e63696e67436f6e746578743c4b2c563e3a3a6d657267655f747261636b696e675f706172656e743a3a6832396434643637313235613766616333d3066a3c70616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6838623336303130376562623263643733d406746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6866636233386232326539336533383834d5065d70616c6c65745f62616c616e6365733a3a3c696d706c2070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a7570646174655f6c6f636b733a3a6834613766636634393833666561656530d6068b0170616c6c65745f76657374696e673a3a70616c6c65743a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f76657374696e673a3a70616c6c65743a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6861653739363863613338343432656438d706b80170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a656e737572655f63616e5f77697468647261773a3a6861363633313632636362303766363562d8065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6830653531663865323337316366303162d906713c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e46696e616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a6839313333616264623863313661653734da063c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6866633038643266646333373838653065db065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6836353862316235363864666330316264dc06746672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a6d61703a3a53746f726167654d61703c5072656669782c4861736865722c4b65792c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a696e736572743a3a6861306631376465613164376234356366dd06653c73705f61726974686d657469633a3a66697865645f706f696e743a3a46697865645531323820617320636f72653a3a6f70733a3a61726974683a3a4469763e3a3a6469763a3a7b7b636c6f737572657d7d3a3a6836646264376163336466616536346330de06793c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6666636861696e576f726b65723c426c6f636b4e756d6265723e3e3a3a6f6666636861696e5f776f726b65723a3a6862356566323264353830663737626461df065173705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6c6f63616c5f73746f726167655f6765743a3a6831663133626331643463393964333062e0065d73705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365743a3a6836343435643638623563666537326366e1064b73705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a72616e646f6d5f736565643a3a6837363461653665316561386261306666e2064173705f6e706f735f656c656374696f6e733a3a70687261676d656e3a3a7365715f70687261676d656e5f636f72653a3a6864656165626337636562623464356238e3062c616c6c6f633a3a736c6963653a3a696e736572745f686561643a3a6835363033663238376535366635643132e40668636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6838646230373634623032363235643965e5063473705f6e706f735f656c656374696f6e733a3a7265647563653a3a7265647563653a3a6863623362313762393064376632646566e6066c3c73705f61726974686d657469633a3a7065725f7468696e67733a3a5065725531362061732073705f61726974686d657469633a3a7065725f7468696e67733a3a5065725468696e673e3a3a66726f6d5f726174696f6e616c3a3a6839633136396230663230626265313230e7065473705f6e706f735f656c656374696f6e733a3a68656c706572733a3a61737369676e6d656e745f726174696f5f746f5f7374616b65645f6e6f726d616c697a65643a3a6863396330346266316531333338633530e8065273705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a7375626d69745f7472616e73616374696f6e3a3a6833393331636537313666306666626631e9064c73705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a69735f76616c696461746f723a3a6831313939326437643965646234323365ea065173705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7075626c69635f6b6579733a3a6831396162613737386265343636386630eb062c616c6c6f633a3a736c6963653a3a696e736572745f686561643a3a6837646662396631373438333433643361ec06683c636f72653a3a697465723a3a61646170746572733a3a6d61703a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6837666139653366323631663166346137ed0652616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a656e7472793a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6834363766373065653562313664333265ee063973705f6e706f735f656c656374696f6e733a3a6e6f64653a3a4e6f64653c413e3a3a726f6f743a3a6836353762643739356162663838333132ef064173705f6e706f735f656c656374696f6e733a3a6e6f64653a3a4e6f64653c413e3a3a69735f706172656e745f6f663a3a6862373337326162336335323434353838f006b70170616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a70616c6c65743a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a70616c6c65743a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6830623133326664326435626239636231f1067d3c70616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a70616c6c65743a3a50616c6c65743c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6833643230393638366537613839643032f2063e70616c6c65745f626162653a3a65717569766f636174696f6e3a3a69735f6b6e6f776e5f6f6666656e63653a3a6835393139376165383938386535393633f3063970616c6c65745f746970733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6865653939373134313561373134633238f4063b70616c6c65745f746970733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6864373531303166393166636539626663f5064470616c6c65745f746970733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6865646336393635343532386562363733f6069c013c70616c6c65745f746970733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178696d756d526561736f6e4c656e67746844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839333432336131373765653335373836f7069b013c70616c6c65745f746970733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a446174614465706f7369745065724279746544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863313065383237386539666665366433f8069d013c70616c6c65745f746970733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5469705265706f72744465706f7369744261736544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833313438343239623934343731306630f90696013c70616c6c65745f746970733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a54697046696e6465727346656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831313866366661326264363766306638fa0695013c70616c6c65745f746970733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a546970436f756e74646f776e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830623634333663333230373430353530fb06773c736d616c6c7665633a3a536d616c6c5665633c413e20617320636f72653a3a697465723a3a7472616974733a3a636f6c6c6563743a3a457874656e643c3c4120617320736d616c6c7665633a3a41727261793e3a3a4974656d3e3e3a3a657874656e643a3a6831303732383530353835363063336439fc0635736d616c6c7665633a3a536d616c6c5665633c413e3a3a7472795f726573657276653a3a6833396535633963356162343336383137fd06456672616d655f737570706f72743a3a7472616974733a3a456e737572654f726967696e3a3a656e737572655f6f726967696e3a3a6864303364343161333339636632666339fe06ad0170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a77697468647261773a3a6862396136656138366162616538653863ff064170616c6c65745f6772616e6470613a3a65717569766f636174696f6e3a3a69735f6b6e6f776e5f6f6666656e63653a3a683939393638636662383564613461646480074470616c6c65745f76657374696e673a3a70616c6c65743a3a50616c6c65743c543e3a3a63616c6c5f66756e6374696f6e733a3a683934313731376134633138386330383981074670616c6c65745f76657374696e673a3a70616c6c65743a3a50616c6c65743c543e3a3a73746f726167655f6d657461646174613a3a683939633866306463323936633939356682074f70616c6c65745f76657374696e673a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68393631633832383033393835323764328307b80170616c6c65745f62616c616e6365733a3a3c696d706c206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e20666f722070616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3e3a3a657874656e645f6c6f636b3a3a683066386430656265323534343066613384074770616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3a3a63616c6c5f66756e6374696f6e733a3a683538386261303939323333323638316685074970616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3a3a73746f726167655f6d657461646174613a3a683535646638323962393638313964393386075270616c6c65745f62616c616e6365733a3a70616c6c65743a3a50616c6c65743c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a686234643039613832376261363833386287073c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a686337383330306365343165643839656388073f73705f66696e616c6974795f6772616e6470613a3a636865636b5f6d6573736167655f7369676e61747572653a3a683838666661633330363066353037313489074c73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a656432353531395f7665726966793a3a68306566363730336231636563376535628a075a70616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a70616c6c65743a3a50616c6c65743c543e3a3a63616c6c5f66756e6374696f6e733a3a68653861633666363634353936306663358b075c70616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a70616c6c65743a3a50616c6c65743c543e3a3a73746f726167655f6d657461646174613a3a68326438346366363330653935613831658c076570616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68303330363838626366316161373034648d07b7013c70616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a556e7369676e6564506861736544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68653330653662313434663931333766668e07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68303766643431353838616530343835348f07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68363563666361303461643365383230369007303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683834313834653361326539356262376391074d636f72653a3a686173683a3a696d706c733a3a3c696d706c20636f72653a3a686173683a3a4861736820666f722028412c42293e3a3a686173683a3a6833366162666661326664313765373432920731636f72653a3a70616e69636b696e673a3a6173736572745f6661696c65643a3a68326230343036313238656364623736629307303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683839313332316231613035373332333494075c3c70616c6c65745f746970733a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a68623334616537623135666134616535619507653c73705f747269653a3a6e6f64655f636f6465633a3a4e6f6465436f6465633c483e20617320747269655f64623a3a6e6f64655f636f6465633a3a4e6f6465436f6465633e3a3a6272616e63685f6e6f64653a3a68316432343166346161396165353165359607683c73705f747269653a3a6e6f64655f636f6465633a3a4e6f6465436f6465633c483e20617320747269655f64623a3a6e6f64655f636f6465633a3a4e6f6465436f6465633e3a3a657874656e73696f6e5f6e6f64653a3a68666163353931376334663230626131329707633c73705f747269653a3a6e6f64655f636f6465633a3a4e6f6465436f6465633c483e20617320747269655f64623a3a6e6f64655f636f6465633a3a4e6f6465436f6465633e3a3a6c6561665f6e6f64653a3a683637396435643435653538346539633598077570616c6c65745f746970733a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f746970733a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a683062353935316364383239613864306199075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68393565653830363537366133666339649a075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68393637346265636432336263323731619b075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68376461383761633531396136366635329c07673c70616c6c65745f76657374696e673a3a70616c6c65743a3a50616c6c65743c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a68323733333634386365333064373365359d076b3c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e2061732073705f72756e74696d653a3a7472616974733a3a56616c6964617465556e7369676e65643e3a3a76616c69646174655f756e7369676e65643a3a68633666373263666436316633346430359e073970616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a69735f6f6e6c696e653a3a68643531366230633230316536643861639f074d73705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6e6574776f726b5f73746174653a3a6837366633656261633635313664653936a0074a73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7369676e3a3a6839343039653237363331643733643462a1075173705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6c6f63616c5f73746f726167655f7365743a3a6865646535616139353838393332656239a20789016672616d655f73797374656d3a3a6c696d6974733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206672616d655f73797374656d3a3a6c696d6974733a3a57656967687473506572436c6173733e3a3a656e636f64655f746f3a3a6862636134306238366437396463386536a3075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6866316539636235663166363735666464a407746672616d655f737570706f72743a3a73746f726167653a3a74797065733a3a6d61703a3a53746f726167654d61703c5072656669782c4861736865722c4b65792c56616c75652c51756572794b696e642c4f6e456d7074793e3a3a696e736572743a3a6863333663393065356636616135386639a5073c70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6831633739343534383165643434656439a6073e70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865343136643566613662363639366139a707703c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637443757272656e7453657449643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837386230633231333864343164663632a807693c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831373062383564383464623064336333a907683c636f72653a3a697465723a3a61646170746572733a3a6d61703a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833393361613437373062326535343834aa076d3c636f72653a3a697465723a3a61646170746572733a3a6d61703a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a6836663536633966373939373337376563ab073d70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a7363686564756c655f6368616e67653a3a6866336265333233646139653737343964ac075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863323932666135316334623838333331ad07683c636f72653a3a697465723a3a61646170746572733a3a6d61703a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6832343934393637653333383464626533ae07683c636f72653a3a697465723a3a61646170746572733a3a6d61703a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6865656333626230383165636166623433af07683c636f72653a3a697465723a3a61646170746572733a3a6d61703a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6830353361376663373932363861613436b0077b70616c6c65745f6772616e6470613a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f6772616e6470613a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6835313464323165636637376662323464b1073e70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6834666334663666303636323736616661b2074070616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6837623833616162616162323461376361b3074670616c6c65745f74696d657374616d703a3a70616c6c65743a3a50616c6c65743c543e3a3a63616c6c5f66756e6374696f6e733a3a6866303739613931373161326662363464b4074870616c6c65745f74696d657374616d703a3a70616c6c65743a3a50616c6c65743c543e3a3a73746f726167655f6d657461646174613a3a6861353765316366333361366333633063b5075170616c6c65745f74696d657374616d703a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6836633066663635353532643130613463b607a3013c70616c6c65745f74696d657374616d703a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835616262373535383462626330336162b7073f70616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6836333265646131653835656164306535b8074170616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835316630616631643533306164363337b90776636f72653a3a7074723a3a64726f705f696e5f706c6163653c70616c6c65745f617574686f72736869703a3a5f5f47657442797465537472756374446964536574556e636c65733c706f6c6b61646f745f72756e74696d653a3a52756e74696d653e3e3a3a6834393363313239663536613264613531ba076d3c70616c6c65745f617574686f72736869703a3a5f5f47657442797465537472756374556e636c65733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833396462353861613365393162646334bb073a73705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6c73747269703a3a6837376366303362363038396365653739bc073773705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6d756c3a3a6833646639636462376665356132393865bd0768636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6861666635343962323737363430653163be075f3c70616c6c65745f6772616e6470613a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6865656261323637653632663034333335bf07613c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6830373261633761343532623137303830c007623c70616c6c65745f617574686f72736869703a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6839653935346131356639623933656465c10756636f72653a3a7074723a3a64726f705f696e5f706c6163653c73705f72756e74696d653a3a72756e74696d655f737472696e673a3a52756e74696d65537472696e673e3a3a6837393664306338396333386437396133c2070c436f72655f76657273696f6ec30712436f72655f657865637574655f626c6f636bc40784016672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c50616c6c6574732c434f6e52756e74696d65557067726164653e3a3a696e697469616c697a655f626c6f636b3a3a6834336538626164326166376465326438c5075073705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a73746172745f62617463685f7665726966793a3a6835313338376262656362313437306265c60783016672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c50616c6c6574732c434f6e52756e74696d65557067726164653e3a3a6170706c795f65787472696e7369633a3a6861653661663038313261636237646263c7075173705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a66696e6973685f62617463685f7665726966793a3a6863363232353331336166663764663032c807516672616d655f73797374656d3a3a3c696d706c206672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3e3a3a66696e616c697a653a3a6834303430326133633966333064633461c9074573705f696f3a3a6d6973633a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a7072696e745f6865783a3a6862386435623830303863633162396663ca0715436f72655f696e697469616c697a655f626c6f636bcb07114d657461646174615f6d65746164617461cc071c426c6f636b4275696c6465725f6170706c795f65787472696e736963cd071b426c6f636b4275696c6465725f66696e616c697a655f626c6f636bce0720426c6f636b4275696c6465725f696e686572656e745f65787472696e73696373cf071c426c6f636b4275696c6465725f636865636b5f696e686572656e7473d00718426c6f636b4275696c6465725f72616e646f6d5f73656564d1072b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6ed2075373705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a6836633731633462363732346364653561d307214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b6572d4071850617261636861696e486f73745f76616c696461746f7273d5071e50617261636861696e486f73745f76616c696461746f725f67726f757073d6072050617261636861696e486f73745f617661696c6162696c6974795f636f726573d7072750617261636861696e486f73745f7065727369737465645f76616c69646174696f6e5f64617461d8072650617261636861696e486f73745f636865636b5f76616c69646174696f6e5f6f757470757473d9072550617261636861696e486f73745f73657373696f6e5f696e6465785f666f725f6368696c64da071a50617261636861696e486f73745f73657373696f6e5f696e666fdb071d50617261636861696e486f73745f76616c69646174696f6e5f636f6465dc072850617261636861696e486f73745f686973746f726963616c5f76616c69646174696f6e5f636f6465dd072c50617261636861696e486f73745f63616e6469646174655f70656e64696e675f617661696c6162696c697479de071e50617261636861696e486f73745f63616e6469646174655f6576656e7473df071a50617261636861696e486f73745f646d715f636f6e74656e7473e0072c50617261636861696e486f73745f696e626f756e645f68726d705f6368616e6e656c735f636f6e74656e7473e1071e4772616e6470614170695f6772616e6470615f617574686f726974696573e207384772616e6470614170695f7375626d69745f7265706f72745f65717569766f636174696f6e5f756e7369676e65645f65787472696e736963e307274772616e6470614170695f67656e65726174655f6b65795f6f776e6572736869705f70726f6f66e4074470616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a50726f76696e67547269653c543e3a3a70726f76653a3a6862353563613736306565303739663864e50715426162654170695f636f6e66696775726174696f6ee6071b426162654170695f63757272656e745f65706f63685f7374617274e70715426162654170695f63757272656e745f65706f6368e80712426162654170695f6e6578745f65706f6368e90724426162654170695f67656e65726174655f6b65795f6f776e6572736869705f70726f6f66ea0735426162654170695f7375626d69745f7265706f72745f65717569766f636174696f6e5f756e7369676e65645f65787472696e736963eb0721417574686f72697479446973636f766572794170695f617574686f726974696573ec072153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b657973ed074e73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a656432353531395f67656e65726174653a3a6863316664303463336532393065383031ee074e73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f67656e65726174653a3a6830313637663336366230613437643830ef071f53657373696f6e4b6579735f6465636f64655f73657373696f6e5f6b657973f0071d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e6365f107205472616e73616374696f6e5061796d656e744170695f71756572795f696e666ff207275472616e73616374696f6e5061796d656e744170695f71756572795f6665655f64657461696c73f307830170616c6c65745f636f6c6c6563746976653a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f636f6c6c6563746976653a3a4572726f723c542c493e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6837366366306236343239633336346133f4075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6838323564643865386538326634636137f5075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6835646635343932306635313230396635f6075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839623866663838306462356462366633f7074c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a76616c69646174655f616e645f6765745f70726f706f73616c3a3a6835383738633938646139636463383363f8074670616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a646f5f617070726f76655f70726f706f73616c3a3a6838653139343831643130326339306638f9074270616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a72656d6f76655f70726f706f73616c3a3a6865303531363937393766396365393461fa072c616c6c6f633a3a736c6963653a3a696e736572745f686561643a3a6864343766383466303632386139386262fb075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837663362303763353866343366666461fc074b6672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a7365745f6d656d626572735f736f727465643a3a6863383931636133346333653565313438fd07830170616c6c65745f636f6c6c6563746976653a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f636f6c6c6563746976653a3a4572726f723c542c493e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6833343662323764346164313939386465fe075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6866666531316339363163666533383837ff075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683436303235633831373737643065306480085c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683061653464613831333762613265323881084c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a76616c69646174655f616e645f6765745f70726f706f73616c3a3a683066386131616664366164376537323382084670616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a646f5f617070726f76655f70726f706f73616c3a3a683062373262663362306536303635616583084270616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a72656d6f76655f70726f706f73616c3a3a68396335383162363865316262663662348408a2013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a686131333432636236633538333033626285085c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6866306131636265626437386138336561860896013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a70616c6c65743a3a436f6e6669673e3a3a4163636f756e7449643e3e3a3a7365745f7072696d653a3a683561303064343761363034353233336687084170616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a683139386339666561356130613965366388084370616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a686131316338626234366439366163306589086f3c70616c6c65745f636f6c6c6563746976653a3a5f5f47657442797465537472756374566f74696e673c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68333436313139666638363463346633388a08723c70616c6c65745f636f6c6c6563746976653a3a5f5f4765744279746553747275637450726f706f73616c733c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68326163316338343739373230326563378b084370616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a68626233626332356262373738636234308c086e3c70616c6c65745f636f6c6c6563746976653a3a5f5f476574427974655374727563745072696d653c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68333738613237356232326266373862628d08733c70616c6c65745f636f6c6c6563746976653a3a5f5f4765744279746553747275637450726f706f73616c4f663c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68383939653138373865333633323838668e084d3c706f6c6b61646f745f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68346635346532643136633036353534392e363937328f08643c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a683665326539326334656339383738303690083d70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f7075626c69633a3a68343565346563316566663739383464659108766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a683433396565613161396532623065363992083b70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6261636b696e675f666f723a3a683336636231396430393338623133383693087f70616c6c65745f64656d6f63726163793a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f64656d6f63726163793a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a686366613838626465313465613938636594085c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683137653066643032383435373265656395084170616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a696e6a6563745f7265666572656e64756d3a3a683235333066646533623766313861313596083f70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f65787465726e616c3a3a683831636464306133346563613035636497084170616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a646f5f656e6163745f70726f706f73616c3a3a686631343139626261653835626136663198085c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68383937653834613432613437396661339908746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a68323861656363306435656436313465359a084470616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a50726f76696e67547269653c543e3a3a71756572793a3a68633666616435613335656264623861319b087c636f72653a3a7074723a3a64726f705f696e5f706c6163653c747269655f64623a3a7472696564626d75743a3a5472696544424d75743c73705f747269653a3a4c61796f75743c73705f72756e74696d653a3a7472616974733a3a426c616b6554776f3235363e3e3e3a3a68623036343462396563343165383362349c08543c747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e20617320747269655f64623a3a547269654d75743c4c3e3e3a3a696e736572743a3a68303064623137386465633734336631659d083c747269655f64623a3a7472696564626d75743a3a4e6f646553746f726167653c483e3a3a616c6c6f633a3a68393864623333663535313233366138329e0860747269655f64623a3a6e6962626c653a3a6e6962626c65736c6963653a3a3c696d706c20747269655f64623a3a6e6962626c653a3a4e6962626c65536c6963653e3a3a72696768745f697465723a3a68616238393463313266656332346637319f0872747269655f64623a3a6e6962626c653a3a6e6962626c657665633a3a3c696d706c20747269655f64623a3a6e6962626c653a3a4e6962626c655665633e3a3a617070656e645f6f7074696f6e616c5f736c6963655f616e645f6e6962626c653a3a6836653736666533383834643761313239a00841747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e3a3a636f6d6d69745f6368696c643a3a6839653238373934313839323633326237a1085c747269655f64623a3a6e6962626c653a3a6e6962626c657665633a3a3c696d706c20747269655f64623a3a6e6962626c653a3a4e6962626c655665633e3a3a64726f705f6c617374733a3a6833323163613533323735333564343337a2083e70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830343832343138376665383763653430a3084070616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6831643935653165343136663162303161a4086e3c70616c6c65745f64656d6f63726163793a3a5f5f47657442797465537472756374566f74696e674f663c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832643462356236373332373237316463a508713c70616c6c65745f64656d6f63726163793a3a5f5f476574427974655374727563745075626c696350726f70733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861333236303938373931393338386337a6084970616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6836343035316338316565616332373862a70896013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178566f74657344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830313333636361373338303238323064a8089b013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a436f6f6c6f6666506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836616232356135633538313336343532a908a3013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a46617374547261636b566f74696e67506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834656635643263636136636536636534aa089c013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d4465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831323837323963353639616336303935ab089a013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4c61756e6368506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863616336353031653831646635323936ac089f0170616c6c65745f64656d6f63726163793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a507265696d6167655374617475733c4163636f756e7449642c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6838333237653339333564346164663135ad083e747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e3a3a696e736572745f61743a3a6832643664353862306532313263386564ae083c747269655f64623a3a7472696564626d75743a3a4e6f64653c4f3e3a3a66726f6d5f656e636f6465643a3a6865343062323736383762663765313037af0845747269655f64623a3a7472696564626d75743a3a5472696544424d75743c4c3e3a3a696e736572745f696e73706563746f723a3a6837393432366333356233616362323162b008363c5420617320636f72653a3a636f6e766572743a3a496e746f3c553e3e3a3a696e746f3a3a6837646562303534633066303162313865b108376861736862726f776e3a3a7365743a3a486173685365743c542c533e3a3a696e736572743a3a6866333364323638623538366661306235b2083e747269655f64623a3a7472696564626d75743a3a4e6f64653c4f3e3a3a696e6c696e655f6f725f686173683a3a6861366133313430376230646333353037b30835747269655f64623a3a7472696564626d75743a3a656d7074795f6368696c6472656e3a3a6835626562303166386464643235656631b40865747269655f64623a3a6e6962626c653a3a6e6962626c65736c6963653a3a3c696d706c20747269655f64623a3a6e6962626c653a3a4e6962626c65536c6963653e3a3a746f5f73746f7265645f72616e67653a3a6864396463663637383466636331636465b5083e6861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a726573657276655f7265686173683a3a6832636234393366356435393163626233b608613c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6861653239386236663234623935653462b708746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6833363039663237306637383536363065b8085c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6830323631656634626633323963623736b9085c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862323761343537616337343939323230ba085c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6830363663383638633766336134336562bb084a70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7265647563655f757073747265616d5f64656c65676174696f6e3a3a6835336239336431666330376435633136bc084370616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6e6f74655f707265696d6167655f696e6e65723a3a6864336336646661373232343834383165bd084c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6e6f74655f696d6d696e656e745f707265696d6167655f696e6e65723a3a6832626130643239626263616437363364be085c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862346565313361383234636332306133bf083f70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f72656d6f76655f766f74653a3a6861346562643962366133653032613635c00844636f72653a3a7074723a3a64726f705f696e5f706c6163653c706f6c6b61646f745f72756e74696d653a3a4576656e743e3a3a6836303961353238303039633736633937c108723c70616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6861333432383834623135346138336439c208426672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3a3a63616c6c5f66756e6374696f6e733a3a6839626431643765366561363131396464c308446672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3a3a73746f726167655f6d657461646174613a3a6865366366316461646338633236313635c4084d6672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6830393934343264396266616462353166c50899013c6672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a56657273696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864643535663730653463633739626439c6089a013c6672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a446257656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833343233623861666163366636633539c708a0013c6672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b48617368436f756e7444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861303838663336396165656430336164c8089d013c6672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b4c656e67746844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830303437613765363533353462343462c9089e013c6672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b5765696768747344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866323738396566366239353234653861ca083570616c6c65745f7374616b696e673a3a736c617368696e673a3a646f5f736c6173683a3a6861306535393762633130323039313466cb084470616c6c65745f7574696c6974793a3a70616c6c65743a3a50616c6c65743c543e3a3a63616c6c5f66756e6374696f6e733a3a6837376230396663383066666662383562cc084573705f696f3a3a6d6973633a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a7072696e745f6e756d3a3a6837663964343033643738623936343163cd085373705f696f3a3a747269653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a626c616b65325f3235365f6f7264657265645f726f6f743a3a6831383334336639663463383961363534ce084373705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a726f6f743a3a6865373734303961613634313366316635cf084b73705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6368616e6765735f726f6f743a3a6861313365373864363132663964373063d0084170616c6c65745f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6834626630666562363565346335356635d1084370616c6c65745f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6832656262643239623937666239643561d2085170616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6833653263393930613663303034306132d3086073705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a736563703235366b315f65636473615f7265636f7665725f636f6d707265737365643a3a6862326437663338623634366537343762d408653c6672616d655f73797374656d3a3a70616c6c65743a3a50616c6c65743c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6831316330663165316463613862623066d5083d3c5420617320636f72653a3a636f6e766572743a3a547279496e746f3c553e3e3a3a7472795f696e746f3a3a6837343439376331393031616237353061d6083773705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6164643a3a6839313462303231323362636235353463d7084473705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6469763a3a7b7b636c6f737572657d7d3a3a6834353636623433636231353966383365d808413c73705f696e686572656e74733a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833386136323834363330313937393864d9084273705f696f3a3a6c6f6767696e673a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6c6f673a3a6865663666663431653361616162396435da087773705f72756e74696d655f696e746572666163653a3a706173735f62793a3a3c696d706c2073705f72756e74696d655f696e746572666163653a3a7761736d3a3a46726f6d46464956616c756520666f7220543e3a3a66726f6d5f6666695f76616c75653a3a6837666662626535633239343833356365db08543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6832363831323331623561376363343334dc087773705f72756e74696d655f696e746572666163653a3a706173735f62793a3a3c696d706c2073705f72756e74696d655f696e746572666163653a3a7761736d3a3a496e746f46464956616c756520666f7220543e3a3a696e746f5f6666695f76616c75653a3a6865336635623032656337336461316337dd08323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6831383161396339356337373439376137de084573705f696f3a3a616c6c6f6361746f723a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a667265653a3a6834613665353738343364633938366265df084773705f696f3a3a616c6c6f6361746f723a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6d616c6c6f633a3a6839386165653164666364396236386334e00830616c6c6f633a3a7665633a3a5665633c542c413e3a3a726573657276653a3a6833666437333332326536333036393532e108473c73705f72756e74696d653a3a44697370617463684572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832623636363136623332626131336165e208573c73705f72756e74696d653a3a72756e74696d655f737472696e673a3a52756e74696d65537472696e6720617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833313066316330396365373161616361e30856747269655f64623a3a6e6962626c653a3a6e6962626c657665633a3a3c696d706c20747269655f64623a3a6e6962626c653a3a4e6962626c655665633e3a3a707573683a3a6833656264343631643335346637366166e408095f5f6c736872746933e5084c636f6d70696c65725f6275696c74696e733a3a696e743a3a7370656369616c697a65645f6469765f72656d3a3a753132385f6469765f72656d3a3a6866353635306232313761613464643134e608095f5f756d6f64746933e708095f5f75646976746933e808085f5f6d756c746933e908066d656d637079ea08076d656d6d6f7665eb08066d656d736574ec080462636d70ed08095f5f6173686c74693300550970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105727573746325312e35322e302d6e696768746c79202865333761313363633320323032312d30322d323829" + } +} diff --git a/polkadot/node/service/chain-specs/rococo.json b/polkadot/node/service/chain-specs/rococo.json new file mode 100644 index 0000000000000000000000000000000000000000..43dc959b57677145629019e0b57924f5a251f280 --- /dev/null +++ b/polkadot/node/service/chain-specs/rococo.json @@ -0,0 +1,219 @@ +{ + "name": "Rococo", + "id": "rococo_v2_2", + "chainType": "Live", + "bootNodes": [ + "/dns/rococo-bootnode-0.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWGikJMBmRiG5ofCqn8aijCijgfmZR5H9f53yUF3srm6Nm", + "/dns/rococo-bootnode-1.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWLDfH9mHRCidrd5NfQjp7rRMUcJSEUwSvEKyu7xU2cG3d", + "/dns/rococo-bootnode-2.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWSikgbrcWjVgSed7r1uXk4TeAieDnHKtrPDVZBu5XkQha", + "/dns/rococo-bootnode-3.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWPeKuW1BBPv4pNr8xqEv7jqy7rQnS3oq9U7xTCvj9qt2k", + "/dns/rococo-bootnode-4.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWNy7K8TNaP2Whcp3tsjBVUg2HcKMUvAArsimjvd1g31w4", + "/dns/rococo-bootnode-5.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWAVV9DZfvJp2brvs5zcQDTBFxNmEFJKy2dsvezWL4Bmy8", + "/dns/rococo-bootnode-6.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWM3hvXvaShyp7drQCavFHuwobkYdnCp2uHU5iRRAQwsw2", + "/dns/rococo-bootnode-7.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWSbGtxfWCwn1tdmfZYESbmxzbTG2LKwKUrioDaZBcdMY4", + "/dns/rococo-bootnode-0.polkadot.io/tcp/443/wss/p2p/12D3KooWGikJMBmRiG5ofCqn8aijCijgfmZR5H9f53yUF3srm6Nm", + "/dns/rococo-bootnode-1.polkadot.io/tcp/443/wss/p2p/12D3KooWLDfH9mHRCidrd5NfQjp7rRMUcJSEUwSvEKyu7xU2cG3d", + "/dns/rococo-bootnode-2.polkadot.io/tcp/443/wss/p2p/12D3KooWSikgbrcWjVgSed7r1uXk4TeAieDnHKtrPDVZBu5XkQha", + "/dns/rococo-bootnode-3.polkadot.io/tcp/443/wss/p2p/12D3KooWPeKuW1BBPv4pNr8xqEv7jqy7rQnS3oq9U7xTCvj9qt2k", + "/dns/rococo-bootnode-4.polkadot.io/tcp/443/wss/p2p/12D3KooWNy7K8TNaP2Whcp3tsjBVUg2HcKMUvAArsimjvd1g31w4", + "/dns/rococo-bootnode-5.polkadot.io/tcp/443/wss/p2p/12D3KooWAVV9DZfvJp2brvs5zcQDTBFxNmEFJKy2dsvezWL4Bmy8", + "/dns/rococo-bootnode-6.polkadot.io/tcp/443/wss/p2p/12D3KooWM3hvXvaShyp7drQCavFHuwobkYdnCp2uHU5iRRAQwsw2", + "/dns/rococo-bootnode-7.polkadot.io/tcp/443/wss/p2p/12D3KooWSbGtxfWCwn1tdmfZYESbmxzbTG2LKwKUrioDaZBcdMY4" + ], + "telemetryEndpoints": [ + [ + "/dns/telemetry.polkadot.io/tcp/443/x-parity-wss/%2Fsubmit%2F", + 0 + ] + ], + "protocolId": "rococo", + "properties": { + "ss58Format": 42, + "tokenDecimals": 12, + "tokenSymbol": "ROC" + }, + "forkBlocks": null, + "badBlocks": null, + "lightSyncState": null, + "codeSubstitutes": {}, + "genesis": { + "raw": { + "top": { + "0x06de3d8a54d27e44a9d5ce189618f22d4e7b9012096b41c4eb3aaf947f6ea429": "0x0200", + "0x06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385": "0x0000300000800000080000000000100000c8000005000000050000000200000002000000000050000000100000e8764817000000040000000400000000000000000000000000000000000000000000000000000000000000000000000800000000200000040000000400000000001000b00400000000000000000000140000000400000004000000000000000000060000006400000002000000c8000000020000001900000000000000020000000200000000c817a804000000000200000005000000", + "0x084e7f70a295a190e2e33fd3f8cdfcc24e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x08c41974a97dbf15cfbec28365bea2da4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x08c41974a97dbf15cfbec28365bea2da5e0621c4869aa60c02be9adcc98a0d1d": "0x20034f68c5661a41930c82f26a662276bf89f33467e1c850f2fb8ef687fe43d6227603a90c2bb6d3b7000020f6152fe2e5002fa970fd1f42aafb6c8edda8dacc2ea77e039d065fe4f9234f0a4f13cc3ae585f2691e9c25afa469618abb6645111f607a530307d29bbf6a5c4061c2157b44fda33b7bb4ec52a5a0305668c74688cedf288d5802fb0330356e63a35dd930bc74525edf28b3bf5eb44aab9e9e4962c8309aaba6a6020019a8bb188f8145d02fa855e9c36e9914457d37c500e03634b5223aa5702474033f1a6d47fe86f88934e4b83b9fae903b92b5dcf4fec97d5e3e8bf4f39df03685025e84e95ed043e387ddb8668176b42f8e2773ddd84f7f58a6d9bf436a4b527986", + "0x08c41974a97dbf15cfbec28365bea2da8f05bccc2f70ec66a32999c5761156be": "0x0000000000000000", + "0x08c41974a97dbf15cfbec28365bea2daaacf00b9b41fda7a9268821c2a2b3e4c": "0x20034f68c5661a41930c82f26a662276bf89f33467e1c850f2fb8ef687fe43d6227603a90c2bb6d3b7000020f6152fe2e5002fa970fd1f42aafb6c8edda8dacc2ea77e039d065fe4f9234f0a4f13cc3ae585f2691e9c25afa469618abb6645111f607a530307d29bbf6a5c4061c2157b44fda33b7bb4ec52a5a0305668c74688cedf288d5802fb0330356e63a35dd930bc74525edf28b3bf5eb44aab9e9e4962c8309aaba6a6020019a8bb188f8145d02fa855e9c36e9914457d37c500e03634b5223aa5702474033f1a6d47fe86f88934e4b83b9fae903b92b5dcf4fec97d5e3e8bf4f39df03685025e84e95ed043e387ddb8668176b42f8e2773ddd84f7f58a6d9bf436a4b527986", + "0x1405f2411d0af5a7ff397e7c9dc68d194e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x1405f2411d0af5a7ff397e7c9dc68d196323ae84c43568be0d1394d5d0d522c4": "0x02000000", + "0x1809d78346727a0ef58c0fa03bafa3234e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x196e027349017067f9eb56e2c4d9ded54e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x1a736d37504c2e3fb73dad160c55b2914e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d": "0x20a076ef1280d768051f21d060623da3ab5b56944d681d303ed2d4bf658c5bed35010000000000000038757d0de00a0c739e7d7984ef4bc01161bd61e198b7c01b618425c16bb5bd5f0100000000000000d2644c1ab2c63a3ad8d40ad70d4b260969e3abfe6d7e6665f50dc9f6365c9d2a0100000000000000764186bc30fd5a02477f19948dc723d6d57ab174debd4f80ed6038ec960bfe2101000000000000007c94715e5dd8ab54221b1b6b2bfa5666f593f28a92a18e28052531de1bd808130100000000000000bab3cccdcc34401e9b3971b96a662686cf755aa869a5c4b762199ce531b12c5b0100000000000000720537e2c1c554654d73b3889c3ef4c3c2f95a65dd3f7c185ebe4afebed783720100000000000000da6b2df18f0f9001a6dcf1d301b92534fe9b1f3ccfa10c49449fee93adaa83490100000000000000", + "0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000", + "0x1cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4c": "0x20a076ef1280d768051f21d060623da3ab5b56944d681d303ed2d4bf658c5bed35010000000000000038757d0de00a0c739e7d7984ef4bc01161bd61e198b7c01b618425c16bb5bd5f0100000000000000d2644c1ab2c63a3ad8d40ad70d4b260969e3abfe6d7e6665f50dc9f6365c9d2a0100000000000000764186bc30fd5a02477f19948dc723d6d57ab174debd4f80ed6038ec960bfe2101000000000000007c94715e5dd8ab54221b1b6b2bfa5666f593f28a92a18e28052531de1bd808130100000000000000bab3cccdcc34401e9b3971b96a662686cf755aa869a5c4b762199ce531b12c5b0100000000000000720537e2c1c554654d73b3889c3ef4c3c2f95a65dd3f7c185ebe4afebed783720100000000000000da6b2df18f0f9001a6dcf1d301b92534fe9b1f3ccfa10c49449fee93adaa83490100000000000000", + "0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0100000000000000040000000000000002", + "0x2099d7f109d6e535fb000bba623fd4404c014e6bf8b8c2c011e7290b85696bb3": "0x20f49eae66a0ac9f610316906ec8f1a0928e20d7059d76a5ca53cbcb5a9b50dd3cf6f8fe475130d21165446a02fb1dbce3a7bf36412e5d98f4f0473aed9252f3492c57f81fd311c1ab53813c6817fe67f8947f8d39258252663b3384ab4195494d2496f28d887d84705c6dae98aee8bf90fc5ad10bb5545eca1de6b68425b70f7c306ac5c772fe858942f92b6e28bd82fb7dd8cdd25f9a4626c1b0eee075fcb531160ea09c5717270e958a3da42673fa011613a9539b2e4ebcad8626bc117ca04a64d59feddb3d00316a55906953fb3db8985797472bd2e6c7ea1ab730cc339d7f4e262811acdfe94528bfc3c65036080426a0e1301b9ada8d687a70ffcae99c26", + "0x2099d7f109d6e535fb000bba623fd4404e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x2099d7f109d6e535fb000bba623fd4409f99a2ce711f3a31b2fc05604c93f179": "0x20f49eae66a0ac9f610316906ec8f1a0928e20d7059d76a5ca53cbcb5a9b50dd3cf6f8fe475130d21165446a02fb1dbce3a7bf36412e5d98f4f0473aed9252f3492c57f81fd311c1ab53813c6817fe67f8947f8d39258252663b3384ab4195494d2496f28d887d84705c6dae98aee8bf90fc5ad10bb5545eca1de6b68425b70f7c306ac5c772fe858942f92b6e28bd82fb7dd8cdd25f9a4626c1b0eee075fcb531160ea09c5717270e958a3da42673fa011613a9539b2e4ebcad8626bc117ca04a64d59feddb3d00316a55906953fb3db8985797472bd2e6c7ea1ab730cc339d7f4e262811acdfe94528bfc3c65036080426a0e1301b9ada8d687a70ffcae99c26", + "0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01", + "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9050f9ffb4503e7865bae8a399c89a5da52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649": "0x00000000000000000100000000000000000064a7b3b6e00d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da90d10cc4959af6a68eba3bc06d5c7bc28520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a": "0x0000000001000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da914076ec446ba6876ba5cb99bdb7129be8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47": "0x0000000001000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da945315c068df2baa1c677b9b3e81f7439fa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00": "0x0000000001000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9935ae9d4cb148940af99a366d100d5af02ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864": "0x0000000001000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da995445d4efb6eae1971fb125f6190c49202a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16": "0x0000000001000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da99677d775b618280f5c76d192b43ea38c38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404": "0x0000000001000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9a606acaa4558183a2102457959a213a192ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f": "0x0000000001000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b483908290ae9b936c519917440306ea62475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a": "0x0000000001000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x998f18726f636f636f", + "0x2762c81376aaa894b6f64c67e58cc6504e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x2b06af9719ac64d755623cda8ddd9b944e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x2b06af9719ac64d755623cda8ddd9b949f99a2ce711f3a31b2fc05604c93f179": "0x2086975a37211f8704e947a365b720f7a3e2757988eaa7d0f197e83dba355ef74348a910c0af90898f11bd57d37ceaea53c78994f8e1833a7ade483c9a84bde055ee93e26259decb89afcf17ef2aa0fa2db2e1042fb8f56ecfb24d19eae86298788e95b9b5b4dc69790b67b566567ca8bf8cdef3a3a8bb65393c0d1d1c87cd2d2cd2f9d537ffa59919a4028afdb627c14c14c97a1547e13e8e82203d2049b15b1ac4a980da30939d5bb9e4a734d12bf81259ae286aa21fa4b65405347fa40eff35560d90ca51e9c9481b8a9810060e04d0708d246714960439f804e5c6f40ca65192156f54a114ee191415898f2da013d9db6a5362d6b36330d5fc23e27360ab66", + "0x2b46c0ae62c8114b3eda55630f11ff3a0f4cf0917788d791142ff6c1f216e7b3": "0x00", + "0x2b46c0ae62c8114b3eda55630f11ff3a4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x2b46c0ae62c8114b3eda55630f11ff3afe6d4a58cccf03d052c50ccbfa0311c7": "0x52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649", + "0x2ce461329fdf4be12bce01afc0af09bc4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", + "0x2ce461329fdf4be12bce01afc0af09bcba7fb8745735dc3be2a2c61a72c39e78": "0x00", + "0x2f85f1e1378cb2d7b83adbaf0b5869c24e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0x2f85f1e1378cb2d7b83adbaf0b5869c2ff3ae12770bea2e48d9bde7385e7a25f": "0x0000000002000000", + "0x31a3a2ce3603138b8b352e8f192ca55a4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x38653611363acac183fe5c86aa85f77b0f4cf0917788d791142ff6c1f216e7b3": "0x00", + "0x38653611363acac183fe5c86aa85f77b4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x38653611363acac183fe5c86aa85f77bfe6d4a58cccf03d052c50ccbfa0311c7": "0x52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649", + "0x3a636f6465": "0x52bc537646db8e0528b52ffd00589c9b044ee2c5de12521040ec381d7b04e003d545abfe38ed9fa1139deccebf67615500b32060027cf47266f80b144514ee1f24fb3e00147918a63b7e9769dcb9893ce34affc1f8d444582ee9d0da8bf9b4a4edddd6a4dc52ca245300146f118812debec5fa7981f98060a217cde557243f89972407b50bf301c1d09bb364bef4395dfa8cb0189b328e31d385ecd90c175f3c09cf66b8b0c1475934dad8b3ce5d9222994473a08e689e5acd4fcebe719742f5e9f2db9a9bab32de9c9f75f9f1d72f2c927f72eb5be4e6f413ab5da7d9ae7679edf5e6c7ea1675edeb1878d337e6e44743bb66f5f0f527e776593fdd50bae69be466978276713cf96345f250bf21b3093d2b65bce921b379eab14ba1a85bd4a7db6f768b528f322039bff8f2e35ec84d198fd17c943d752bedd29c7a51ff783299cc08a43edb255dd39cfd815a7e5cb73cf933414a7dce6bbb45576678a17deadeaef8d459a840bbd80c173478ea50da359d7a0cf184f8d4b92559fe443034e21fbacb64321965359e8221b7f111cdf307311a29135bf4703e530fb967e7fe690f8b3c7b88e499c93c3bf3117ef656bba4b397d03f1664d7be8d1be0b1193cb8fcead9cc1d5fbe7f782693c9b680a1ce6bcefdc360b8f39ab3fc29a263698c991cee88a2095073db2efa9a6b666240e6b51b4ef1f9e8f32ef1f8a3b3fcb1608c2ebffe66f3445f80c77a9e19cd5e7b3633861c1f9d77222cc6a26c208c968cbab0095e7b685f4a97d2a57429d7bc9452ca2958c86099e28a173d3eb709ecdc6d6c82c7331cd8bcb7abbd27ab5ded3bed9adf331cbef876ae7f24383f2cf2adf3edd1a7ca163d7efea465774be9f6e5cd59229dba6c79c3f83dbf7d8b2ea38732ba748e2e4572fc269bbf72a3ea9ffd15addb24c77c247a18c697cebec90ff4a4b3739782bc76935cfce47757344ecd5fe1527c6428ca5e08858fdededd0a5326fbe8b153c1937d74ae5dfc2de38f77bae1d8f8b95d613bfb6c8f1eb273b7b85bd34ff0da576897c2f20275ace3033636c19b1eb29eba4fbb426ba45da1d76a57e8f3d4a997d02ef974a6658fa7aed33f0d2279fa6191a7eeb5ab9d3a4ebba453a7ceb52b3a75dea1570acf9e3f88c508dbd87927f479e91b7ff1b7d82599dd8acedd8a372c923f3b7649e255613a7ffcdbc65d0ada0dfd35b7dd715ccd6eddb0483eca59edda5cba4ebbea564fa71b9e1ce5a7ca79cfeeb5abba749c769d5cfa56bff8dbe9e36e71b7388f5d0af167b7b81b728ef2faf1735f91fc936fb139ca14d78f7ffbf85127d6b35bf993c5416e1ee69e50e7f9869a5397be49e6f985f1855060b75f117de6be7ddb9ae34ebbf1e32fb4cf2e3b8e2beed6363be615d7ad9d6e49afeeddaa52fbe60de36bce9ff771b7dae9b5dd6a8fd52e7ee9f3e3f776b14bb7f267caa4b7f8880c775ebacff3073154a4406c8c82c7331c64cf33591b023ccf6ec8e2fddbb93b803793a9f9707e3b50dbe8d6b2fce1e609bd8f1e7a1fda6f9fed626fe77669ce3edb55fdd9b7faf16b5ffc8d5d9ee4629744bbd1abce9d02b8fa163b1534af37d45cf3ad3b15bcd79cbbd9ade9dc25a10ed49a732737eeec0d636fbd7ea1d5ea17ceafce5d12eb5bfdc2047cf58dbbd30d69f893d72fe4d957d7be5053000b15681283959086afceddaa0e24b58ffff409c9a6a6a636af79fd42243f7d8b5cfda6af50bfda4fa8be76c3f8f50ac5a6a6a6a60f634f7d8b9cf6f17357249f5eee56383fce8fbb155d7edcad10e7a38d92065b689f7deb2f7efc62e4fae39feda2cebec5c8d1e85b73ecb50bb929e3496fa72ebb24f4462ffa2639fac5ef2e3a77d2819abb24ed40bd452e7efcfdc5e7ce01fcd1811aa86331c620362ec1db54bc137a2f9ddb159d9ddbd53e3d7eb35bd237767931b42f9dbb24dc2de9408dc48b1f3d273a7fdf9c25df3767493bf5767a8be2c7cbdd9a379ccf2e9d3b15a2f70ddba30335efc82bc57bfe202663d4b231f3784653e9036fc46c6432990c04c366ca183d3fef6cec5300233f1ed38d39e085f6db6dbbf8cc962fdfceb58b673aecf1ed5ebbd8db71da15bd9dc547e2b7f34e5f29fefc412cc6036c6c82c7b31b9af8d03ebb6d179b0981d2b373fd13417656bbf8cc962fcfceede20f759e9d77f84af1e70f6231a2b045e77685ecf172b7d8d9633102d97826537aae1b1ff1986e3c82c774638f9db51b2662087850037513829b2e6e966e98b8a9e2868a9b296ebedc3c71e3e546e9e6881b236e8ab821e266cb8d969b1d6e926eb2dce87063c58d183739dcdc7003c52a8f559b550d563458cdb18a63b56645c7ca8e951c2b19ac62b072c1aa05ab345667b83cb8369c1e1c08382e1c0f1c10dc0f9c0fa81b5032ef0ecf0e0f0d6f049b0bb637b6156c6a6e94d854b0b5b1bd80bb6263c1c6060148e0acf0f8f0fa885be20e148b150bb61678676c29e0be705eba341c145c976e0d6e89ee049d09ec169c0cb8187071706b6e3e10e3886b221c2b34d104f18cf845f42286207211bb8860c4302b36918aa844548a4944282212f188d8438ca2862a110c021e88861b2c6ea4b8e97223c44d10ab3e567cace0882058c160a566c586b78757038f8de6a17ff0d27866bc32decc138117860786f7851782d50a566e785a78597408bc2b3c2bbc25af0acf8bf784e784d784f78317c40d12de0e1e17ef03de164f8be7c3cd105e0f1e083c1dbc2c1e9277e4dde0f1e02579407846374edc347103e626899b28547aa8f250e1a1ba4355c70a05ab363cd9cd152a3b54365035a9fa50f1e1e5e0e1e009e161f186f0ba784578447848b416ef8866c333228aa7e429e12da1da437503ef8b97840785278537455be151e181692e3c2cbc2d9a098f0baf0b2f8ce785c784aa062a1a44362b3d3c31de18151b151daa39542f50bda17281aa052a16a8e450c9401503551caa14a8d2f41d2a13a8d450ad81a22a818a04aa349ca8d0509da13aa32aa31a41935199a12a4345a6cbb4193d46f5850a8e88874a0b150c5457a8c0a8a2504111cfa89a5031a15a428584ea8898864a8d6a052a37542a50b5a162438502d51aaa13a8d0a8cca8985464a8c65089a11aa312a39af50854225085d16ba8c05079a10a81aa0b551815172d856a0b55162a2c5456a8965455a8a8504da19242f545e545f584ca099512ab3556275029a99258eda132623503551755102a20543fa87c50f5a002818a8b8a07d50eaa2d2a2daa0fa87450655125a9725021a98e5446b10f1516150eaa1b54b25453aa8f141fa93d523748e991ca23d5268547ea8e941da93a523648d5204583149b141da939523348c99192412a06a938526b5270a460907a41ea8d940b522d48b120a526b582941b2915a4da48a520c5460a059d269526b546ea0429133409526aa44a9022412a8d149ad4085268a4ce489d49994995499991628a364895912223ee911a23e6912293122335262526354b892015460a8cd417292f52214875910a93e2a275486d91d22295450a8bd415292b524ba92a5254a4c0a4a64849b181541441a92f195821e525f544ca89541329266209524ba4944829a590481d91322255447b91222235449f91ead245b4999410a9205240a47ee834fa8ac622e543aa8714081a4d8a87d40ea92d292da90fb41a291d52595249a91c5248a9a394510a4b0a87d40d2959d7d4f5d1f1d135e8f6e86ed0e9d1b5e9f0e8eee8ece8eae86c10f9e8681069d0b1e9e8e8e6e866d0c9d1c9a08b411747b7a683a38341f782ee8d488278829882a882e846c7824e4db7824e055d1b5d0a3a2a3a293a2864e888e8ba6c6e7419dc1b340ad40fa71870479c487042e374e654866e59313920d6204e11da312c192b869dc52f560aeb846de274c349566b506950d9d434aa1755899ad464687468736040fba2c94e655010502e9407bac38c63aee9281a8afe32e1e8144c30e617d38b1982d9c50c33b9985b4c2d6616138b79c5b4622ecd2a261513cc9c624a31a39850cc2fd3cb7c623a319b984ccc25a612536926319198474c236611938839c4ec328598414c20e60fd387d9c304c11c437e21ef9075c81a4c2e720a29850442fe20b934974e872e8bb4414463950215a21d5d47b3a0db50cda051d054f4091a4c97a04dd04274108d469fe92e2d467b693bba8916d3b3164187d15f7416fd443bd15d749806416fd15af45257d14b7851f4144d4403d13da8daf496fe40dfb0c26355c7ca06ab3b5a169be20da21e2b15c4360d46bc23d611a5886ae20a220a621b918d9826ae11d588238868a219f1892882e825865114bb442162d2ea054f5c68c2a46d008107b0b04ac38024318788348386658bcf719be3d43288c8890b4cac38098a8109932d4a285482983041710c9ae28293222a33bcc0a4e849d050142854a23061d201b82a23e885105663709517a8446152c350d00c424ca258f9222a4132d4e084055f91e1a02754aa5061e2e409952a0e28a2324395274f7ec84a0c0a546921849518269a12c54951082b117050d00b5688a240a96128e84a942941509804c1e084882848062641454e648852441444c509038a6658a14a0be02a0c0af80a0c86524414e44291922a4faa3ca902015f7dc14444415386acbaf8b1e242860600596dc14541444c5e080a0283acb48052e549101422ab2b98a88620294435042d89c0b7b2228a95af81284a026af86fb564c2aa8a9d15154c4310959bd5142c05c7f0a48a95a09c55143c34030c515ea052e5099328563ec8052720901514fc42952a43569858891203d15010150e54615243909410565f184a101518a2105199e149952b5166100a62523454c54ad090919517861285495110d1d00c4f3a583dc14441518aa20c5589a16806274c606012c5ca3bb102858a93a1143c5839c131103989e1ae9ae0a0212b4c8286a2cc201434c484e8852b563e5831c14554826478e18a95d66a09260a2aaa728509132a5574564a700d2e3051229a1244858a93189e30b122c3500c4ca05099a18a0b54a2245144a5ca13264232404182abbc2064750413155109ba126404c340250a142a4156980415398112050a15274f8aac88e02028559e0c590dc143555e200a22eac244453358299aa10a005642c83003119113105641b0932227509850a912054a50115114a2a1202b21ac7e60a2a0a12a4f98d45014654a14179c4c89e2e48a135ff9c0445666a8320403130f563d30d1509522a22a0a7032e48405d60a04cc8128567e2848ca50150aacf0ad78e0a0a019826678400b50826080c1490b0258edc044529e04c5f0e4034c544425682828062a517ca50395282fe4ac92f84914222a51868a68086252c3142b569c30190a823225ca0ca0942755a6803aab1c5806264e8a9c40715214d480d50aa90351a638895214854a14202b2c2ce54995292e30092a9ae149100d4137ab1b78a80a02b802a86650cf84217b8e6d3c93c93ec664079a66a419452bb14e0738801da044093b8063571b7b7a8c6de79c3172c719a38c316a3a761a891d7f749fdaf68fd38ffef1e3c70ffba3fef8f1a3fbc7cd8f031c20c638edecd81e489dda5a03ba67b436ced90ce8396b5beeee1b5bad6d59a34eb78e119d9eb556dbfdcd6e9f96534776cb960da43d38803cc9967d92f1a6bbb1dd9a66638cd6d6da565a1ba3ed8e4bdada8e76b64e4bdb3d75ba63b7d56ce5dab1da2a422f408bdd32ca18675b3b8fc4d8b635db5a6b5a5befeed6acd63dada6d99eadc54e75c78e9683b636c6d955848ed3da193bb6085fabd01da3eda980e63a6ddb38a38d1ed8e8d1ce4ea1bbdbcee9818dd146db6d7fda48f7eca9c91c2dce1bd6ec96dd9d806e4d2ae9197b769d75da6a6d12db1d13a0b5d6dd5384b693c5ddcd1c58db5adbd6348b80186337d8f3a6bbdaeeae3776d66a65d759a38db365db19bb3df8b6ed8165c58e76862025d06c96d69ad6f1a6234bb37dc362f54da3c0e2ee6aadd63707e88eb15b9bb36f0e60808ae484236dad2d809455d639abac56a7d66a44b694d2c88fab5a5bab35c184dad2846edb9a2dc1f6076d653701ac071a6bce683bf66c126ced683df0605a5b7b04db22d86eeba355dbd5dad64498db8c6d670fa035db13e4eb6e19bb88d6d14a29adb5d3fee8d93d7bdaee689bce9bad65cfc9415b3b5bb68c72f6b4d6f60f01f4a9bbb5ee68bb6dcfeeaedd76da1880386df368b69bd2793367dbd62a4e1b0200da76c7486476d7b6ddddb663b4316a52ca396dcf19a3edee39a5b4b5edec38bb6df79c33ce19a7bc892c0faa6ddbddd15adb5ac706618763e4183fb8d1c658ebac1cdbc6d8dd1d63d4b1dc9f9fe6241263dbe6c8b13d88733690d933760fd1b1ad9333e79cd1ce96b36dc78e1d59724b7b73737373d3379a7673336f98b87142762ecc40c4234394222a330c5dae8810274143424888f242d09095cb010c55a674000208ac29415782a630a1c1890c4c60a012050618aa4c21d2c150109520184e35044961f224ca141766b0d20a226222431528549c0c5d169428539c5c614214e583140d4131e8b062208a4225ca0bad189e14397121040e5a41608842f40129725244c444ca50150e140551d9c18142c50993a021275664a8f2a4043ac5c9932a535a1b0d4150a8446142258a93189ebcf042154fbd50340393222a5186ac30794214458621234009fae0079310444414346445862a4f980c055da9f2246888891322284f82988c20c5650209569e04fd449141862a4f5a529e387161ca942a4301b8e111a8548952f4c40911152743454c8a869c141185b00ac163125e885280114c308184212226558aacd430f4e40314511151141a8274ba1a82a43029a221888a071b8f00854a90152b4e744e42544c42952a434ca0040d054119aac2c46502094151868a0220c5c9932741527c23ea2095d375c01505c110c236e42468ca132641303819aa5244c404ca9428313c6152346506272f0441e129c135c46502094e43150e1479803242c2084c480892e2648a0b4c60a0122506222731b826830757a804c9c92330a152250ad150d015264141432f3019aa52e4e4499529539c3029a22148e70a952089c35dc35015198264d0ae5009923e2a2e9a292cb6d5580c0683c16032366130182c766ac230541386c16cd78461b00883c562131661b0d9040683c56c138ec534182c16ab4d3816a3b1da241661b209734c6bc2b0580c169331d90416b9492cc260b0d86c02636ec230182c269bc4620cd64d18d64d1806eb26b1088b4d6051ce26b1188b4d601116eb261c8b4d38168bc562b4097793588cc562b2c90a93059199a30c444e38409c01030924c4a4b9c2062083eca14f0b2e9381d1b5b42b84c8a56351ce25e4a41e63b594ba744bbd52aacd2f26e9e7326c9c911de5e2595ffc4d7271fa9d7276b7e0c90db6d883d7291edaf8265b8c3d78d143ae8bcff191e8ed5cbb38d6417df211cdd9e9a651eadcc9d0c61e3c8b72ba39b54ead53dfaca3ac757a724a29750ef88875f93cdbf22536b975e9cf62d644f13676d673aacbefcff90ac6ba76b2f5a3dddca1728b4d287e03d12505cea9f74714bf4f570afdc27eeaf11b8adc43bdc8be1037fde6dd29e11ce528df2e7520c97da78fa773cef9c9b78d6edca580f2537f61ecdbc3934be79c3b154ece395057df3c7e9b9f3ece65b7c47af478997ba20335f7857d23f7c4663f5db12f24fb903d7bfdc2a2f85aec1644d977943dfbd63f1df0a448e70fa32c0e343eae106f78be619475d3f9bb329f7d7e4b54cf2e3fe623e19c5748f51c72d387d2db81e4e742decb280b63e3feb13ebff8679e8af15a1bef5f95be789f9d0a2d3461e6c314fa283ae2c322190c6a3e2ce22213fab0a805683e7a380308ca38438d1a25283648bc103735f5b1c408163a3e268945785dc5f3ac4b976fa5e719106dbef53c03e2cbcb2e16e1c92d9e6746a4e0e3ec795644111f80e7191165bcf4d8ad6065328d9b9f7cfb19311aa2fa57fa61188a75deeab15b42bd6f385bc2889fde4e3b253326c64fa79f14ea2151ece7bd0244dbe827c44d4d4d2bf857af378cd1ef0a1025223f1da8fba362bcf615f54f8fdd12223f974c6fd73e29ad84aa40bddea2edb95b21cf9430e28bfa4a7c4d7efedae73f8bb6178a1f4378ee9208b5ece5773f764984a64cf6ed73d4e0ebf88d725aa784dbf8e81b534dd3b429a3a6d9562a7abffc7c1e1663b4b52abc107e56a9494d636f8ebacca95256b7da9753a3f6cd972fa3d44e272dc5cec7c74fbe5659c63a53cc6d3c7f7776ab9b7be2105edff0f47add0ae1e765752bd628d76c72935f24c22bf3461391082f3abfcf108d3c9ef950c70be0378e593cea928b0258a8400f6da494b2d5ae1ceac31b96ab40131fc84c704ef9831adfa940bbc2569376855e0ced9accf4d3a733c07ddac5b31fc2fcf412fa8782f366ae98def8c972fca43e3fbd48bb42e9ad1863a42ea933472fd29e3dfe4ebbe610538ff41322129dbb0544b951a94929bf50ba079efacb061b6015d6378c7dbb647bc37629f586d2d943295dded0866fe7ef8eee5b7f324aef25d1e592e89a4fd76917a51fbf87c3b31e46f0f4a3efe1b42bf2d1471fcf5d131761a75f6c7aee645c841da8e9d7b21b3e329b53161bc720521b47203cce4e211bc71fbc397d4eb75cbba48bd0ce9baaaf944fb2c74e092f61efe85373fef6f8b56fdad74e57d0bcbd7e52b44f73d93540f366153476ed8611f5859bc7ed93529dbd3b25f5e55567e7069c9c6fec846830c2e106d90fa19c28f628940b851cb8011f4d4fc468befca0c36f4e14fbed72b75037e425a7dba5807a4dd328a5734e296577c7f8b45312bfbab48efaf8e9c65c774a50979d764a50cfdc13a250394baab3b3d79006be52ac5bb75fa879bbf6f18a7b9e6d69e227f7d0cfb28c9d227d23c8c62678d1dbbdf666f9ed3c7ba73972f1da432e02205582ed79a603d319107ca1e5033af877002fb4d199394a87b2452cde5c6db35b382cb42bf42f588d9f3e5debe9af510f39cd6b6e447385d68ba15da11124ed92af7905da78cd33d03f13949c86c9bc86f3a11196bde63aedead7344d63d372b0583ad2bd76499c4f61932a15a853a7f2e3af9a7559ddba26a5662bfdaec497df95f8d63aad5eafbfbd52343fb96c8066bdba665dba2624ad157a51fa92c96437fc2639eeacd5340792dd25b1b56a5a6d2df62d5febe65e94524a29a542b5a9a9698fafbe35671da8e72724df5ea1ed869273f98545fd2947f9c65d12ee8af753a6ec860fad0bd53d6e68fa2bf6adcf4fcae69dbca11786a19d42d608871b7ee88af6d5afd4278a7d951fca6d281de5f216f5a7ae50dce3b7ee2beadf9cfb84e46f37478538fbe9b34b321df5c9d0fae6f3bbd23f7deb7e946f918b54df50be7df58642af9f2efd0ba9c77ac3d8d798a4be5e73693fd9d2ad0349a197fca25bf92151eca34b17924fad90fce9dda9307f5e29d4dbbb5b3255a0574a7479855e1fca8fdece9d0adeb79fbe4df5e5f497b349eb5bac1edd7ed565ec94b457b75fbb54a1bd5697d65ae74e052b4d16102b62a95bd7349722bdfa66a5953e54c4bdf422eda54b2bfd4dde5a692f7391ee945097d73a90949f4e74fb45afdaa59fec5288933dc64555181024b58938c41bb8a4e1f2a563301b4eb2b5cd8f3f76dec2167d53699bb3f43016515fa704e5d281e4dbc82c65e466fe9c7b7c9e5d5341f314a26b401d3f7efe583add629d6e754a4eaaf89bd72d949fdc86b18ff663cd6fd3be2bf1c3f8288fdf95f828d4dc6447295342f27394c83ff9e93af7b0c7d73ed49562fde4f1e39f9d906d80f5d355519fde79a03a7bb4dd628bba61ec51a72f5c40f49303c9f8b59f3efe2d72dca1ae907ce92759bf9e7ffb8539f10ac5d704f0dc2589ae916013a1093d3e50c41a32de5801c8dcc6bd31afdef0bc6733658c3ebe013c23ed8a463e7a7424ed527d748fbef361093ee7d7014fcaf4103e7c3eb3e50bf391d0e7b5d816394d05d46bae510fe70d613f3d3c35805df0daf5a2397fd4b56f0222ac21a609649f5ff8fa19569f1233e2ad87b0d79cf9046611429e6d81c117c5b7970abff142b2a9e9ebf5f26287c5ac6003d22b0b5fafdd707a787a19c23b77176034b8801cc2b76c35b68db99814c2dd4a815f43f39d64a6c3ecdb912880012bb04b8fdd01a6535740bb421f236e9cf976240c6857fc2e5242919dbbd3ad76ceb280244ba75dfcdc29892fe48546befd0be3b30349fe606fa45dd2db914846d3516c1c651eaad5ae0fa8699a650f15b74b5ab98152df98c80b61c8e3990e5a9e9f7f93dc6c578c6fdb253dfa3603eb8b58dfda3724c44ddf5e547ffa4639d91f734fd8ad405dc66fd7be9c25548a74eafc5ab72484a7de5d12fa492aad8fdcd360f4d82591dedd0aad9797b9a72f73a7c54623aaa6f3ce36bffbd4b99d51de1d03622290fd459403f5c6d1076f7394c72d852f3cb914ce37df505fb87d392a4c99ec3b9f2f9f3befafbf73a0ee2f7e17a23c4705d4a3ae906ae5bcc6fbacbce5ac1d79d2aaa5544e5946ba6d93e32e09c755759453dfbc2fc773fe30f69ea3be219f178a7fa5a8dff3d497e3f10d3ef5f56fcdf5271ff5b11d9ffae46f924b7df3b7cab1e5ac1a1f9f92af4af93639ce39532ad4c76da8be4e61753fdb2de9a92f769a4b41f9e621cab963404c049b739742f46ddb1ca8b7d92900e8998b84a8d829898e4225413950cb4e05946fbec54e49fc90e31ee93672ec38537de310de94ddf09d4bdf4e5f38ffe4b253c26464b2efee9010b391c9bee8e6552e6511f72a4f39772b58497d4342287c73cfc98bb44f85fd27efbea1941769af72ee9630517d4244be3df509a1f0917b4ebe45ae6b3f7d61fc9373c780d8f7652e72e2be930349a0066a76fb85d1b939aeeaf5ba759f5e56b73abe2a563b362b5e7466d6c6ce6ef908fd4ae89694e27d42d64b8f2e7fac4b6fc99f9374237cc4b94773e9a7cffb6cf3686ee50fab793497cee2e0a587decb2d5a3e2ce1a573c047e24ba7fcb49f675bb0006a8e2bcea3c72e677afcfe9ce93cdba2c5731936ce3c159a5fe737bbc5dcc33ca3dd6cb6e829f00bc5a64f8c0db23cab59cfb3243264921bcfea567749d8e3f36ccb16cf129adf5d12a1d8f427ee69ef2e854f76ecf18bcf9f506cfa78a7e59e7621543c9e25b5f9907beec447b8ddf211d4f32c498ed5f32c4bd2b3ba957a9e6519e2595376649a6ac9838c529b1f17c99fd38be44725d18562f4f931baf4788be2cf18c1d8b68d3bc9bed14ffba678d4999d4ea0fd86b1970e0365974456607adf570c7c496fb05f31303a7749647ba85d6a7d8ac7cf2d449ff7050391c008a1f09a47907ef26a5f289f7a7fd38124fdf8e7d720772d48303a504b0663121663111667ef50e91d7346ead1e99c13298e9f734e3a719e674826f89b67329620e343cf83d03cb4ec35c7c8fa79a76724b9b05c404869708b3f5c012199c13cfce1e9db23ff002189611efe7620ece26f34df7da3a7f340cd3b518b91051bef8473e97d8b30cfb32ce4f8b0bf9dd53ccfb448f3cd47e20f094d80ba7516ac766da06e35ebb576b15ce852989646af4c923c128d64926b249bd9b74b1f129a80e6d459a0cedd04722640bd7abd36684e6f4e74ea3190c11c16aa9f9c41ee845838257d3b0418ac57d682e6392c287dfb2b36bf7c3b0ce4ae859c7859e836ddc63a77157869b2cdb7cbdb6d244fbbbd5226793aec364c69ac4b97d6ad1a344cdfbe3597564afafed25d9acb771af9b3e6db231ac9d32e6fce04a453a7d706ebf2b2f97606190ca39a34df0bcc04e21c5a94918138f80b265d26a317261d07d9860c7e908116a82393fc895d28abd1dcde9c074490254fd8b29e3301ebd5ed8d4c92a7bdfa68bc865e963c6154fa0ef3d1c338fbf6f9c5302684f18b8f73e9f903188dd3aeb1e5b0d01e3d06f24e28959ebd3f963cf163c913fab3c3e08531ccb3b3371bf9c3679c402393c9643780ec91893dcee40f83ec318cfcb94123c41b32701626450609ca7059fa728488325f6632306ca5ee9274c21957ccc0b065b10d1b0194000f3796646018d73c4735610c2379d8c3665aa3264da379064399f4ecbcc3578a547afe00d6b1d88d8220485200410a0208d20ddef3ec88062917b0cc08b18283e732b074f163c170ca96df6c9e5e80d73d9be142cdcf67335ccc001663dd5108141f4dd0c0880630d0230e3064a53ef45aa4550f0814bad0830463cc800d355b80d46dbbbaa7ee69393242524a291de38c0f4f69ad9aa679d5eaec2887d5b3183dc87865b4fe897571c5124b286863031b4c0186f699fbd07b664917a89631636662f448a222c5b260c9c2056bb2c8e00928b6328c92c8a0420cea7966c407955ccc9ddef11ac9c04207a4ae3eaf576375ae0ed49efc611da33786703e12b51bc64dfbac063c4dfe7892277a74e79eb29eceb270e2a9cffe8932994c8604d2a7379cb2f3d43d0d78fcd1f97a38dbb3983c92f8eeb90ca3127ce8f9d4d2b2bb77d8dad9b7f90d0911c57ad8af44d9f3179e86ac17c9a765dac8a2d54699149c6990abf6d58feb56fb05bceaa1fd960ed45ebbe40d53e017aa3ffd74a7f765ae5df5daad39edf45d913f6f38dd5ea1aac4be506c7acd37ed0ba76b439a17c94f22a536a05e29da15aad33b15ec2b99eda2f78a7c79db278ccdeb1f963cd243d6b34767b780d72ee78f376ff4e2777461d33e7eef9aab5ffb16bbe8dbe4d893d3a557975d92aa6d1ae56697247a77d36597447ad4bef8b1090ac4dfc18c174956287537572a7dce39e79c734e9e5ffca6507d7aa54cff42e944b19fce9d92e9d237fb85d6514e5dbba1b5b56a1aa5734ad9af79d82ad43f395fed0b236b1e1d480ad5475d29dae90ba913c594681ebfd0fac9b7d317c9782854a3ac73371da8515f77494ed17efc1bed929c66a700fed31737d9a9603dde50ca74e956caf4f859fb49d19cfa36391bbbe9dc69f49b369e623ddad8e56deccd6e699ee4d19cad4febd2c339adcf15ac4b998ed32d6d32fff8481ecde70da97bddd2a887de12d54ba13e9d5ecd997f58f230ffb8e4d1bc6f48bd7da31fab5b9af7e7754bf3f9e1744bf30978def387de6bbec56e89eaa7e3d08f5f7649fa466f7a770ae09f11bca1bfbdb65b9ae603a6bde93ee7959e51cf24e085eeed0a7d76da15f2ec35d7bc457d7a58e43567cfba8f758d7942fbf6b66704663a928360a8d71bda0f7d5e73ded1ae149e4d2ea66fecd1163ceade33194868f1fc233d6ca7bef5f7b1f64dfbdd92fa52dab53b6dbbfa86f3359fceec6a0fb56bbb359ddef9fcd3fb636ef59cce3b338a8ddb157100433be5cf0b8c355a3c11821a9cc00ed447f7a2b3da653f721779d8e209dc11928de50f972088337c2c31051439740143eb3a7de87de8d3df923f1364e70a54977604b681040a948e00234711768b2f7cfa46bfead1a903758c377afd5cdb8738af79153167a4e162044a74e851cd600943c6092854cf649ab8e3b9e799511a2ab7d898575ca8f3d155cf678ef8e1593a1b471ebc762ea9012c10c28a1bc0e8a103111a993052cf66c82c35a58067bf7a0fd4dcdfcef695b4d73e40260a254e53743b2ca00c28ce90c1c509ba70810720e00209ad6a292eb06c51077503b5b1cbdb54b45acf0833b966ec92c813149a76c56bd6a96f965a6a6ff47a43adb58a5106135f9d55350a2bc11c6248d0c61b6b9c009c437ee2f1c4ff8c1eeb811aa8bd6731c8e043a349120805cce1059b17ec91658714e86cd1c66c8b156cc1f4dbf3181388317b099b8303c2a0c28e366d666bac20e74c0e3bace0ed33938c8e4a291b95d699c50954cfb32ccab046a72f6c7c99238c1e511021240b1164f1c39698105968c9a20f14d8800813747046e6258b2e1ad219248cce1c2df1e49ec7c8a18467668b2c5948f1014a359a45970f3dd7c28443192c419ec52863cbcfe759163f6461344617633c6b8e284224401932253023090b3e8c3e789e61c1c677cf332ccef0a423b973649e78e5043676193d475e25fdd2f9cc962ffdec4612d03f560d4ebb7886c50c4de82386186f80f0a1f7ad6e26c6cc870f91843bcf2e3b3eca33e2996dd7698bdc9d8a373279683accc6fe45a6f94dee91378cc5253c9e2d7df1738e19438b6785b14936cfd17b85d3ad1ccd79e645162f3d47bb4afa358fcf45d03c7b05a0f48f9c95d02e36a305d3fb3093d19469a1e6434663c4b1c9c2cc87dc468b0160d4d12d7efa31000c39bac52f3f0680c1a65ba1dd6917eb990160ecd12d7ea06ecdc7e956bc5e2cc3b39e512f81e1d915685c81c6b373edfac16c70604af36cc68c377e00cf6698befca6f2e487d33cedade185566e3276a7987bac97e825c9c1e8cec416cbf0aa6704a665dcd934232407b94d2012299033ed47b7915e1c36de9180c7e23c9c97ac4b3d2330d1911c04d3ce64bafc4e28e956fa0ad2255fc91a7b648d4ac9ccacb194ac49596dadf2ea744b7afbe90bfda5c76dfc85cc6e3dacceecd5a3947ab95b548bfc853164d698bdd6f00b8be8b3dba38dd9c51eb6b34bbfb47dded971baa6ece6f6d8edede2ef84beb23b36a36c628b2de5a449a6d625b15ced6c97645e1b299301c1cc48998b6460c74ad1eb4cd9795ac2cb22dd921a1210ccc4d13eafce59c4c72773da14243f59da67bb252fb5947a811901c1c4c8499f9746bce95bec9214759279a317d80e08867ab733e5ca0a77be4eeeb3ddaad716d19f2e377ac326a16becfcfae921ab883e95de7346a629e9f3a547ef74a09e62e4466d2b21f4a218cd6ba86955d3a6b4d427a545763e528d86f6d9e7a347315ebcf1d55781b867e5f40b99ccaf901849dd70e7538e3ac9cdc3e996dd73dba76e95773e3feb9df59c25f6a7db9f376749e7d33bebb653617a7743ea53ca743badb576ce6929dd4e74523aada5d35a4aa7b594d2ebdd4ab1ba959ad55a6b6d2a455394d254e538cb59cb59cbd994a75225a4be22dd5a796ba75b2b17c3456ee55be438e674bab5f293a77cfb4ed4765dd775965a4b29b594526b29a5d6da5b42b7363f7d2192df38cee3386b5bddda68a594d24a378ea31ca594729452ba853abfa5a0d1df24d753f66f1a4739ad5332e536e79cdc9cb5a5e56cdc2427e7e4e6b4b5d6bb39d7adcd398efb6d73ea5e0afc46b86772959b1ca51ca5945a0f29e528b573526a3da494a3d4ce49a9f590528e523be756b795776be5dc2e2e468ea3f5da6ead3cae72b7e5adbc7de54092fb6ebe700a93f9e92b5f6d2a3f7daa128a74ebe4aa2f34f227df3ace39a9941cc751ca7194524ab9fa75eba74ccd8e72da5651f674b2a8ba691ced664aaada8b2b4e951ac23d27a71ae5c29d3f791453b7ca719782e7299f9fd775db54514a29ed2e0957d42d392e4ace434a29e578f6f3ea746b3a4eb7a67b5fb8f393bba5bace3dd3e3186f525aa9576729b5d64a3dacb5d65a6badb5d6cdc35a6bdd28ad75f3b0d65a374a6bdd3cacb5d68dd229535f386547eb92506fcdcfbb758a958b633c763ae70cfd4fbe71cb49b51ad9a674b8e7e429d0bb6d72560fe79cb3d63a67f570ce396badd56bad97ffc6c916a86badb5d65a6badb5d65a6badb5d65a6badb5d65a6bad95d2f9d3298b7e5eb74ebeddd07ef5cd2d679d5d93ed744dd9b2a9a94f682943f1b9a9e92d45a16e5f58b96e9dbc4f7e0aa718f9e9a7934dc5ae39b94d143d691cb72b9c4e5dabdd3ac17329348af1d8bbbdda0fa7f3095efce9dc2daea99086d7be703e4f764d0f99afb78a556ae0d6ea70f050b628b28846568a2964d720dfee45a1e68be44b97958fc81399d99d41d9d0a488430a363329f29822690a20a6e832855214536431c518de146698e066053fa680c18f9b158e4fed638b2d9e4d51c7b71701a3a55b8f24043e32813cce872d7de88af7ec42fe57e4cf5ef6437e9bdcfc84fc46b9f9b19e83df2a37bf20bf596e7e3f7e3b71f3bbf90dc5cd6f84df366e7e3ebf71dcfcb8df3a6e7ea8df52dcfcb4df54dcfce86f1e37bff9db6abbe1e6d7bffd5879373f705277a8c87b11d8e7ecb976f195496cf1005ec8fa6eb5ab7558fa2ed238edfaf1ed5c519714709eb947092d4ac8e607d828d9f14a72609951216b2ec618bba9d072344fcf332aaa48aa5fbea9308242d1868a315484d1ba5021c74bf951d1061525e89e67549051bde7191535b05cfcaac0e184e2823a7344c4c6c58d08ae8a2caaa802e544c74532290e8d8a724f7b17f93c0373e6378f8b4b5644ca3db38a393e5a23b8e759152df8c947281f3973b4c5b3565cfcdadcd8e719981178aa54c76da893ad1a9db223af52374b6c29f0924c7b9e55d146b483a348ea9613d3b94d74667989c238e3d6b7472b947c7ac86d4246336fd87af6b0256fd8fae8ecad66892a61e1a5bc8d9f3c6434274f79d8fab0995437e4361fca3593cb54237f5e916de06e2b499ee6238d2e2b258f394781cd3697bebfacf16e779836df3d933c8de6c3d886d17c94711ebfac3cf41b0f593f3cf4709c250f4d8a6d3c990d51969494c4850b17c9c3d3dede5dba481e9eb6212a491e9ef62f1f36936d264fb2913faf11809eb7cb36408004910509e2ed3349fe70e02f96b7b7da9d9d75db3df973249b9a9a402c9b1fb55bf92307e85d9fe8f10b90200efb017aee39901bbfacee11100e562b5f9dfc74738f80b038b836dcdcf88d03b92c7954ae72963f3fee11078e85f3a3232c9b0371d6b5e1c70fffe11c5cc6b947388e85eb9cc1a3232c9b3378f44a220018e4dae05d1b38ce39c7f1ee8b4b5ebd9dfff8a29a2faef9be98e68bf1238abd155ef496d5e90d6dea86ad0fe51a6fef3eb9867bda63165e1865214d8ab21274a104112fa001134c4872e0a1c30c9a4029d10803832364797801d2cea38e276439c8a00059f258af1c83232c694ca0023040963c283f394d923fdcc685898f2fbaa0514a4387fc6935d7865e23061d607b51f350c8dae51af9f38aa08fe46947ddd09e6e68ed0dbd7a434fbb21cb27f4ef35dfeef31d3d946be8d22926611d3bcdd51e958d17b2b81597bc21cd51ce475de7a7944b6bfddad06ddea7d3766db09ccf6de3ae0d27951f7171c9138a5f99b8473a83479cbf920800aaae0d5beadac045ad8dd646fe74f7a8fba2b5913cd2b97bc431ddd0b77bb4cdf886acd33d3a3996ea47310c4b9ee9f386de875a9b7b641d4bbd3660894d2098e90c1ec5a5be61952d7943286f8f58783cfbb2d45f34344c5f78f665e951f1cb17f9f3c222613fc07a723f5516ebe4791fc62faf240280960f34200a6cc02f71c99bde378c42935e220f2b534fd81f7fb4c28b56786155d2da8455294dfcd21f56a6ca247fe217c923dd5acffb1256267f5955aa4c5589dff85043a3b5d1d090f0a126d3be6832ba44d3d0259c0fa71a9a34d5a03e9c5c66987072a11fca995c23bbc859b3915d98d8b4928ce94b2bb5f912c6363e5116da97697c42fb3262e1c52bbcf8ed61fc52d9c8d89cde121bef8492cbbfbc89923319f5c9c9cdde9794cd5aa6ba2febd55f72facb3a775fcda697acf86091dec95f29b97928d9f94b729ee4f28a685e1cb9b0f06aa56dd56a248f74edbe9a44361e9754ce9c949d662d9b713e27364b6c964e5e5bcde639839b87add4a971a61e7a290fd9535d4f5d8ba6e32e6bbb5e73395dcf5e161ad80fb05e0b6a97c17959f2b4e4f2fc014c158b8d3a63e39d30b27969abb37bf247737696fca1ceeef2673a3b16d9d404a29c7e58e4fceaf702e2f67b71e0b01f60f559fda5395204357f719974facb3a52b4fe924e4f543a0ac80f3528478a20ca5f40eecb08a90339304a420104e24811e4407a908b1441203837ca248f5473912288ba2f1fc9237d75ad481ee9a7fb6a2279a47b17298254baeabee24cf2484f5da408dafbf2248ff4ee4625c923bdde17779122a8dded462e9287a2e1a2b9e651a593877136d138ab719fea6ca83388f230aad19c41d485fd00a9873c3b5dd80f703a8315b4b27edae7499ee8f463499ee8f373c913d93c7f00c389c5ae68b60e1889519208603bd224227f900052478a600b914892381d46928433849124e97820efab7a120138466294d4034e47d2408ac348922a104692a40ac2489238e080912411613192a410c0be2fcd9308a03112232c154cf201db9124386fc748923ac54892502a469274e3319224212b46927441e9ec378c242900a0bc2fea4904a88c2489824892ba132349028262244943c08924090470de97f42402444692649b912479929124b126234972dacece8ca4ef6b3aec07586b6b5abd2c4ab5ebc9fb4a2200281d8bbc56f2444f2200f8fa21e585fd00930800f675981627d3a6e29ee82a3ec21e77423afbf68da5f3279db87c7bb80a69976f0f3b78f6c83f94973c7f79e327143d2e7957ea0b45d90b11c51e001ec61e009728a44adff1a9175f801186084270722c138b2cb4d8828b305d5051c592155780612475facbb13cc1488cb0a8c0241fb03a9217469234bf3092240e0a46928413052349d291829124ed80533092a422e0bcafa412c0ea58a8128c24c92ec148923c26184912ab094692e44e3092a41658bd9d2a31927a5ff4e6800278baaf974cbb39a000dafb8a4d312607f095030ae0bcaf1a8e42906445992c9ac0570e2880f5be607018c146972f697c008d903850cbf1ce5f4bdf9e84035a8d6a3a9e6a9fd119c459fe0a42fd474433c457edcd0fbc9efc05a685eb1ff8ebf3cbc6fd9b44dcd574e044fce58177e02f5973a9a71d070188108fb21bc799ddf82b0907acae62354adf1c388acb3708f775f29dcbc207f70574efcbca37ddef2b12b92fefe0bea407b759f7e51384fa8ffb8a68865ccfd33c755f2c79da756e9cc59c8b5404b4ee633de4191b2b84e51dacfc14c4d17ca7dc93b394bf94bebdeba51f6eb928452e1ddcd7c959377201725f5186735f7d735f4845c0eaaafb8a6c9ab4d294717025174623d34e41701c08e7da8dbfc0b4b039e72f34df28df66df2747351b959f94961ac87d698e737b755feddd979ca5ee2b2abd7ae935b9fcb8522972a1dacd7d8169c1f395bf5e605ad0dcfa2ba90430a5a1f9f61798163aa752aeeecbba7725775f72bbaf39933ceda8fb6a36a7fb9a4aaa2b971a0d97008c3c66d3de97111207a6ee0b4c0bd6a7bfa69a6f4f2a019cf765ef542379daa76bf735e97dcd25c9d3de5d29d5687a8c81071a5a98b9014dece20227e058c34b8575195958d1431a7b1401ce3bd9489ef670aa598ab388c693bdcb923c3091db506e84c402ad1b9d1cc98b49f0917885b8e96912dcf351247884f6eda347f008eda88f1ac123b4db8f16c123b4d78f12c123681eb21a2eb249a65da3241d217884f62080b08ee420fd61073c5d2cb2a909d43c8c4a4a5ca851520b34423202521e7884f61d5a20ddc202eda51ef6526d6aea03056b942942695ea3a4124023eb4846409a038fd08ec4815aa687924d9ce3046cb8200926364006ab57120871822e723863062083f562a94d4d4df61a21f98014a905d2231ea1dd08c9416ac423b463513535353581d5c3c9e6dba94cfed4cbcc135d63b1a8e7c99f7999a9ec9b0817890ed47476632d759a6066c95bc2b414cfea169bc1c3cbb3987bf83614f4f9cc91145772f82e20f6ecaf084e41147b7630df96376294fe812d12e171f267858f893be61b5ede30ca9ee57765febccc92bdf9e51783e011d8b96bb5ab07233cb6a9bc85a43627eca5e6829f57483635d9d33c5d2af686d6a7c4ac60f3dab51eca1b271a3cbcbd5e36d887d1a546c50046b3d768784985d1e0f29a871df8a95d16be8421c21a63260f675ee779c603156f0458bdc882b86105963864d3a317d9902d4efca034048252154cb2222bfcc67b9189b0c618d9150318cd68e8c06bee05077e03ac57c66f807c5fec302a482881821bf690c9407a654632999597f393de1d771358b1c08d27fac0d2d404b202705ede58536db6359797de5f073c299a87f0a176a3966e6909e223433eef853dc630f0e8cc775e23a41e707ad20f504bbb705eba901b335e38e5a3966e49f779010b463336e18551cb4b0ff9052ffdc5ee499e18c87618c145125c2ca991c9c0e9d1c1f8c9a6143b3081c312608046483d60f4a41fa0115283d4930e00469f5fd201c0179816a2bf58903cd2239a973efd05a605eaf3be80248f747a5f605a981eefcb258ff4797d58f2cc66d14346c377e460869719b011050b48709386c7602c6030d1cdba786372608929420893184895524a291a699e7a5d3800c797357cccc1061e6a9851868f3a6655050238667830d95184d2991e98d050aa2235040c9a18c10e6a34318322e828e38c3cd0c8814b1e3698a34b155a42e082199051c6066da0a00429a630be6c9402e08c399e6a5563f9d0022d4c42907982892d7180da18678871460ab6e7d919613cea15617b6ab33396680f750c1952209d7184111bbbbc19e64b89de1e726fe7d65fe823fd011d18c1185cf4610796299000e59807eafe427f80124fd4c146892560e0051912be00c38b1d6e8c4972038c62f0c091a629cb166bdc71c7988f11a86bb0b1fc89456102234e900409e6104305e0875e5bc09b5a652f5e55d8c1440e67d4c8010d48cfa439d302aa85524addfbe2a956b5d49630e4d0220f3a9ad0e28a3c503853e6358d4e9e3f9e6767b8f0e699a49c38ce70b1f54c119c36abd5a29a7367ce3967cb5bb3334649eebed3c187eea3d523b6d422e60bd4c8420935ec10019b03c4314b93447786f019c1d20bee28c3861347063083c677cccc3e741f4b8fa89a992e72a89a36a7992c7e4ecfc3999979e243cfa98c9aa69949e2354da393e7cdf3cccc166f3617d7e88c6f7cf570e60c0577a02e0e0f4b8c4962cac368cc1b4e8015c9d7190b76f070b8e799991b3ef45c9b410c29a307e5410c1274e0c103164b88618313e888635646062cd8a1a50e52b6e822823034780304761c21c389323faae7591919507904eab90c116a4ecf6588f8522449cc1a622ce5208b020c5905f8d06b51124160182dc5a08f1b3ca1861132982002e7b9cc1075d823f24891507d197bee92347d2cc61936eef9c7084cd88e253681394a2c51ec8b84ea4f8f7dec439ce790fbd0c3400864c858a2069f7a26238a366590002208109e6766e431a3a3368dd669e7696e73439da8a59552aad1498418a4133ca5744e54ec3c3c49399cef7843d6649e293b672f721e5a9487ac9f29a7cea9db5dfee16e68b71b7aa89fd82f1d84672f5a109ef9a77a38e4a58740dec3eea553fed15c9eacb59e17b2a847ef2e49bcd1f3e9938fc4107411c49897203c50c7286cc6a4a463a29f7c3b7da818bd192fca99e9b35b6fb2583f43fad1d1d089c3193d90f9e97c9ab1536c2b3676b14bea60051268da15e39ced8a71cad9ea563c9d6c956d4356f5d0d33cde8e2ea3d728a34ba7dff46f296577bbad33195b4a295bca96cc925936f709edcccccccc5da627a594777a46609a4b609726a5579f6e5dedce3bab87734e7963471959ddbab267cf3a2947ab6fb5efec566be114eea7cb3ec26b9fd7da58b17893721965a4c1014c1c722851059924ec40e3470e302b30a37b36c38b15501906cb1035fa59cc0acc88decef34570a2872052cf657821cb21007c0ce1c1f3cc8c14bc7d26c34b1bdd1a62a3fe44b4e9410ca6d0b41b16f976a9338b41d20d773ebed72e172b7e1c688af84c243666b1a61781591c697e3e8b7123054018b11a3250e30839b8e03003374c10a3a60f2627ce7cf75c460835cc40335d32c73a2ea0d22cb0336ef0c308c6600107094a48220b1a387059bac876389325cc77cf6770c872a21355cf20257db55feb69d2e9f4ce69a75647206b3ddd2db5c6b8b8028c2eea18130513196025c0d77a06872c5fa9a73dcfe260fad07d2c4d220001f031c30b11d25b3bbec3a769a7193efcc4f9d9dc9a739e2c9d2c7f4cf8410a32b3338cc450034e127ece9919627ed2cab4871094ce39674c2ff8290438e7a473e7e67956c71d0fe479c684e643f7f1418c8ccbd2921819cffa40f3a10d27d3ecdbaddd6919366666962da594524a3a392aa594724a249a5a45f890e343161f6fb436d58cb2a318e6c93c7522eb79f28c38dd62d722ed295b52e954f3f08428a99cde8d72768b7dca3965649ecc539b94755beb2cb2cb61a13aff86ba464846c0ea4916dc4e75bb28afdfc95a7979a513e069b784e17879bde4507ff10caca17a0d279fae29db27206b9f3087e23b75cf91978593d30b010627800253ca3d3c23bb985b38383f24ab93bc90c5ea83e9db755aac752db40c3cf9263f76faa9209d6f185fde240b9ebc5de3a845ebe5742b4bf2d0f0726a9a66af94a27e79afc89ffee36bb724849fd74b0dd5a76bca964d4d53ce199f9b9ac0ca3c99a797eadc4d0005eec975c05a3d7be8fde9f927320f7bbce17476ffb984c84be91cbce8349c969373ce088b313a85a861dbd836f6d82f334bd9f16d25619fdbe4689784af4d42bb14e26fac4d4d931d35ed948a2ad8a856edc9f2ac4d5c5ad34a692417eb95676de2d29a564ad354ab5a9bb8b4a6959a6a94676de2d29aa673d6262eb5cb90676d9a7d5335529cf194921da5ec4fc66c3c5db1f18eed16373d94720252e43c3a3a3a3a3a3a3af2a4576b53d32747398dab9cd29a5e6a338b496de449dff86453b383008356f2781f168f3db4329cfc0cb6cb34df524d65639b2b58233aad22484e1acab27929dd4a77efe338a04609c056f9c39292e778d92fa5e34867c9d3b5ac22524a29a54f2b7a8b0ab1d18308227ee0d2051e23b0a67bbb04f0d35b33f8e9457c7e93811837e010e3061c62dc88018b71030eed2b163e282d5a190cd14d3fa1ea8783a39dacd6039b808c973b9a906e7087123e32c8419bfc03caf2e401cc0d468411c10b982001132270614ad72c3da54f6bd5e187a538a29042090723a818401c484fa7c6c445ab370dadcef2dc052098def2dff1d6d4f1944a4ae9fd4002c29019838e229e80410ac09ea7eeb1e4783a6fcbcf182991c59d52336bf4784a29d5aaa6e1b89919ec70e4a867337194f9eed90c1c6458950f3e9c4579e8edf195fb2aad73d65aa62fdb17c6b7a86f6787a52a740853461a476bf6006b91af5090f93aa60a147cbd2d3ab6d8664ab2d6933fce821dacb77ca75546186b5dfe7863a4e171f5c86043461b6e17dda2450af2f0620b1948d1c40f02c0c30c1c6468dad7f21df79d76596da75bb19e39228d967bcb63f94e1bee833aa9e08c1623701883298b9067a62f29d0c850813a8db1741a238ca765c818452461460e316e20e304c7c6926349175075ab271f994c8665ccac6adb455d16638fe661a3e6e10fed6b64b4348fc6edb23b1031f10226bab8c18b2a640120d345e9ebc9a9673f1c6bbd7651b71ea751ad3370e3cc192c61e810054f0b709891f901684c180e9ec56099c24f748724a42d5bbcd882060a2ed6b4c8b8d1830e2a58020e2dd0387334440871e4717a3643860e4124a19034471a38c4e185154000a0e906deb39931d2e041274d135288e0a88d29ba00410b003ccfc6c82ae0563b2179764d9fa5a96d4fa7d3b56d28ad629cb1c3d7b8d57a594cb33295bf562031a793fd70ba5a6bddf93a13c3e5eb9349923cfc738a91293d7d162346970f3daf5a0e22b801298c1b20d9e7d918b33337acc112061e4662f288028b8703051e5f9fc944a1c6879e6b916da24be61ea6eac546a59451065e3f6f5a52585bd429f532cf4e7da75d1f3c751be6a973ed6a30983ef49edaa7f4037fa678427c7633f8488ceddd37a670f3b1cccdd3d6344d63ee899a6b37d4b41b99b8a7e916720eaf3d0c367f53c68b68de670023dce173c421470d5278c136aba8827ba41f218a69708ff44805f748a7cef40ac588868f4c347cc6cf1bd1708f0cbc9b47134f20011fe1974c1fc63430f0dc883f405f848079f8a57374017d3126c2e0e316cf1fde7c18d3bcf498a65d405f64c12d7ee9b18d7802d0176158047e258e8b8de391273db43cf302cdcfd9b37967c2b0498f5ed27c647ac9f49129cae1f12c0c354f061d6b3eac3f0b230debfb997e492c43ded92511da79a38f4fbc506c8a2f99e209fcec30f0d8a3173e42148d3e7ae11ef623444f7cb1e623d30bc5a6ae01b10c25f189c8c44788a633f74897654433f84864e21e7633b8873d96e123d1d9f988bc423e9336dee9e939cdcdd3aef8535d7a1123096857b43a2f9b873ddcf1d0e7e7e4211216337d374fbb46e78e84c9d8ec68828dfb796e2e7f8638bb02acc89f2ef247c723cad981e4cfc9d963903f0170f6c845feb87fa0727623f227e5ec4de48f07ce1e93e40fe7ec7149fe8080e3ec3ef2e787b35740fedc387b94c99f109c3defc059cece82fc21e2ec34c89f20ce1e95e4cf157243fb42bc3f1d1e6f39009c7e43ee518e0f71edfb60c73ff0cfebe7f7480380f3b8fd02708f9a7a007cfb40b847207cbee3dde741afbe106e08ae79cb817cf71e7d701d04e7e023728f0200c4ad77f01d1d11711d9f79f1e585384e11d003223ec455df11919b4500e051e7443cc75139374b0a74d7b9471db8ca87dc2c40c0a3ea39ced2711c47f98fef4807c787786a88a71ce76691e0110747436e961ef068e543528ef2f91da56e160380479b1341dd2c3ae011ca735ce766c1018f747cfacd7704c4de2c1d8047d673bc6f160b1ee978bb0cc0cd12c1231c1fe2406e160d3c4a3911a737cb0d7804c4551ee43be2b95972c0231da7ad9b65073c62b9ca4370ee3b0ae16641814737dacda2028f3827e200b8598c80479ae7b8f71d61398a8120dc2c2180473a2efdbb5978c0a320ae3af9e7d7e377b473b33478e4f910c77214033fb8590e001ea99cc83d3ae1f80fbff1957b9e258244fcde2c3fe0d1c973ee518e6789e0e7df91ce3dca12411d2782f2937b740fbea31f3ee41ee974e02ce7c0833810cf12c19c7b747474a4f29477cef9e64052c8079b7d071feb6b491e760e3e16240f7b908f06c9c30ee48b4a92871de7b39287fdc7e72379d86fbe0a481ef6d517659287ddfbe217c9c3aefa3cc9c39efa8c481ef6ee6b2279d8b92f26491ef6ed8b4b92871df5b1240ffbe903923cecf68b41f2b0d72f72913cecda17c3481e76fab9e4619f9f02240fbbfcac481ef6fe6217c933933cec302f16611d480b458b8f10792013da5c08e5422717b22e545d487321ea424415cd4b27e2d94f4f3214b9a1ed868ef221d40d754e3e74ba21cbfa90bd214ef5a17a434ff321ed861cf5213a249d0b93eab82d4c9854c76d61c2a8419d6c55a30675b2558d1ad4c9563561521db7850993baa1ed6ee87137646d61bec3c830920bea64abe482ba272b6f5d83b26bbebdae29329bcd66b3ee52d3b4f5428f45bbcbb74f36df5db61bc67e2bf26cd8b061c386e9db231b26262626a6c81495a252548a4a34b469d3a64d1b1628a361342dabb5662b6cbd46a70bbce833493bddd0a3ac9f33e90d4faaa137f458cf9252cd77ac8b05486aaf65aa65d72de5ecee03e41c09e553debe2f98e69aaba4f7a40e3bb975769d9e563aece494d5de8e144198e6b3ba950e43e14c6f8759d736a7d5612897ceeedda8a6f57618756d75f2eab0edc6836dbe398cf5e092424281dded3c7f21a1c0d4c54204e5b0d3b692ae4d87516f4f1202aafce527876d5e1d09057a170b91d47d9daab77598f4e94942c08ebbdb65d4c927755875eb2f18758abad35fb0d3b5d661d5a78555ed05a31326fb7a9bb08a3504db940778e578921050ded7f41792064a172202ab6980f2be9052a0f4a420e0148a93625135250901a5bfb0104142d179b11079c13a0f922404148273e3a5b615a7d2c10972e3a5b61faa152bc80d8e97da80ac7ee004c1f16eecd47e00f18604c1b949398c734f673b55ea30cda59721391d388b3a8b75b110f117cca2723ae8c05f30d4b4ac0717504748109c1b6f7318e7297f21a1c09c8b854853531328a403d67d25090139b82f18ca83e0dc78a9ed54a9c33897fe82590f8273e3a5b6937418e7d55fb0e94170fc0503e237fe82fd70cf5fb095a7fc0553f9e62f58e7d5619c9ffc05d33cc8dd01723d9ceb3f2ececdd5595d967759aaab93ba38dddd7118777dbb1eeaf2e972f6ce36217abdb64d687fc1b4cbb50926b4c3e6b56d427479679bd0ce0ecb8927a68da7f4a655b316754a393bb771292fea95e72a1c67c749fd0d8e1769ffc38b82bc908ac53d101fba329f032f9a1fc48b705e0885cf192aba79960f15a1be031fbaa27d8e17f50b191a2af2de031f2ab23fc475bc88f542f2890c15a57ee84a3f91dbeec127b927fa906f724f749d8f724ff49cefc43dd1857c967ba277f055ee89cefa34ee89cec1c7714ff420dfc63dd1817c28ee898ef3fdf852dc13fde6ebb827faeaf3b827baf7adbe1bee899efa82704ff4ee03c23dd1b90f877ba26fdf0fee898efa3ae09ee8a78fc53dd1edc701f744af9f0ef744d7be1cee894e3f21dc137d7e43b827bafc3c20c23dd1631e44d966e37611699a0b1121a2d485884e279413715ce7442a95e74437373f9c9dd52e22298138bb4ebb888204e1c0d9bd5d442c178a4ec472a10eae94212121254a84a20be1b89074a1950ba55c68fae64b882c894d4d4d44ed42b16f28149bae08f90e6ec8ba424442e7e08641747080dc50e2dc90b5fa71c39bd50d7152de0d55a91b7a9b5f11f2dd0db92b448443ddf07445c84fbf22e4ed0d79f6e115215f6f58d378ed0a11a15788c80daf087979c329358d971e16692fef9520df77c763ac38bb98433ef4340a543a4495d91e52e831440dbeb0b9588831e9a494f361f5850996c0c20a30d650f19999c30561823ccfc21071a25a6aedaf93d61a46f6b5d67a9abe9d3ed6c943ef4fb5d6ea5c83afa9af5eeb29bac5c2871a2ccf82dcf398313c3c7d1e3386cd879ed7936f9aa6b96bd4c696e8e30d304d6a00512607d77252420a204ee0060e3cbca0871510614ae344a9089ea2b430c1962e661fb23e7afc68a68ba58f31ba085e7b64d4a9c8b35b0fb99fdef4e9a8d3e94e9db0f5734ef758e0acd7ef126779316275eb328b25ed4b29e5d64438db0c1e4a434be2e74c9f3f7d89f6f34a6133783011a1ada874a9574a44490d42c710a21192d1248002e315004030241a8e86f3400ef4f00314801086a858524417c8a228c851144651c618430021001800803186848886043412b71b6f028abe6f8458d9354aadc435a657d0da5cae46e81fcbb718ed3d60fe12f11cd33fb06031342429fca29fbda6ada9867e43f5594b93d124a5bcc71edafea7955d340b3a5b4a6ce0a97dc63a9376625447cb353552454c0a768e406694fef7e8d9581f1d6d970e0ecdc604aa4204b71408c4fa517bcc6ad1b325b827b2b20a70c55df1d1ed2044083986905d0d37f9c442dc26fcf1b7d94fe8f0baa75a009e839f4a5532d12cdddef5e2ff27bb4d785239bc37ccb5376c958e76815625294d2e77372ea890244abaf8d1fb305ea932e1d532c3012387fc1ed7b5b15efa01f6f95f14966f2f5a685dfea32e3114f22706dfac751c88b4c7c0fade7abf43d6d517168deec5b91547b84e1db8c4ce3c25a7f6d18c6bb39c55cdde95a96d8698566664169a320f188ce5960c668635c233ff510250afa3000e2f66395f00356eae80b54127434d93b1e00ac2632ad8e72cfd3ea58226ca482819c1043c9b2c95515067e91301094277fc8f50e6bb767d82759471842204eda88e095303c15500fb57c1e62e8b70c81f82b752144a40f2534d86b46b726742be29aca2fe1664a41c451ae03b500856bac220e7b0a062ad7939661a5690e9b5d98ae1d366fb01045691263f6b57ae4d68c7fe8a6ad166a385dc503074eb5ac5ec14651dd5b926eee1afdf1f936a3f7c4fe904d048a98371f1cc8df593433bf98a4591dea80ea247384fb5eb1afa1318b02caf64ef20199690e0e87aed9b018357cdeca13a2170476036386246558899c93a94a27624334437ddb39cd9f911a5db2288607d8dbacc30f4e72ca4d22075a4d64e2e9660353998510359173b1cf2680aa939feb2d16eb6e8c7eed14846868d5f1d5c79e377545e8a3226f984a7a779fcc4af6ab7c3273a83f5656c0deea7c03625fe6a214a1fe29114c53970dfac3f30f27870f1549b01a268c178d0a05ef0b9a44ab4d73c9b1f32da9dda54ab26f9cd650cc8398dd1fb3515d69db0d0cbea998ff07b16d7d5ff6728b9877de1874dc27a79603941bc9264ab4dd15648362ce20a661c0799cd4ddfd2f7af72aa08daea0978f40f7862eaab9fba0759cdb5f1c01d7d209ec112582c4981ea9bbfd277aed98fdc1d9e76c4b484d4e0027cffe78d585d1f4de36583a6c2b3f2956d2d698ecb15967ac3dbe3d478f3ac9ed498793986dd992355c6c5e5d0ed6d6a008798d56156cbb1fed468c149204708e0b46227dd1e517ba1b27e1ad1cea09208e485e59962e7c60a4a6bf98337621153354c742fed558fb55f3267260d8e998e180f20b4f9066531e5b3d3afa2c7aeec91152048f6e40fefca5c5330852916f82cde50989872f62081fa3093073b57e67caf2412d3d02859e2da0fb9d2cf9a785cf0c922ed106b01d397b7206bcddd51ed2325c89e2ecce8d89a735e29c572758ad0fbf8077985081f008f8602861eb2e356d8b74bab821cba3fdca4907de1642511642fb7a0f3de44ec516ccde1a09a0eca1ecdb357c0a25aa006ee0056d6385779009c6ee8434ec16b9b811e5fa03cff346733663b175b29f9278e8028e4e4eadc4543f1624e4531870b5809ee40edde853da3895e4d99ba3dff136aaa3dd28bf9d3e11ee4161874d48a61eeea9eadd318db848877f7cbfadff65be4c2678939be8e0b1accb9181a09d8ae8b860c2b0944966ff748ead3b5dc235956dc16df3df9d5db22dc430fb7daaccad2db1f162315ca12a90f7e735be1a2b1448c9c8f10ff1120c67f82e8b7c57fb18977a01e1e21f76bb11e1c20ce19b85be016159e3110393d950c8908ef84b210961425967667afc900c39d7e0b2c1b700bb162f031501feec83ee2d3fd0cd473d342f62f942ea1ee4c924b5f70ca03cc60c2218395219e7b28551f4997d9253cac05a89846791f06a3c8d60ee44431197700ae2de0304a24d6025181f642ac79205e39acdcc325a030ac124998de1cd554c16abfa40600ff5921c431c92ba5ee6cbab1fad59d29b8c6a6f1e6f9f7d871ece30c94227c6953edd9c214dc131145e71ad52d20e1fd89c6fa8f29c704ea9235be351554e0d32c26e5e92ec753a48f27bb6f4d0549ea32cfecac7c39098b247fd6720172994667bab87fe25706c253b3a02576ad27132bb8525de9ab8466f573410001874ac7e8848e1e908c383e52f7354e411f1d98db746641cbd0db24531d9277c867dd7e3155e0712c7a03d525c208339d12f65337a82b2d86d9a3450d663c7c2172ced312f9944d84478e0fb584aa73286197e3894ee5f4f9441d5dc3beb9236350a24e3c6bbb5896947d14dadc33cedd773a7da8520c240729d5d4f170f6cb1ddd5caf5b57e3c6ef48c8c591630279d17cedeb709572c087c6969ddd673602ab818474226c447223b532d49e5d891b4877a4a19c9e02e6fb37b1af3c2a4982344df036dcf678998d6e5ac62800dbb699fcb6cfea54bc3c0b04afabe984ed0e6c6ee967dde48248d3effc8b35ef5787f45c44122d7f6d490b9c56eaa087d3cfc4e8c0a92ae91b1b378cb6ac4f87c0e6c9c10167d6b6f42b25d40fa8a1c1249c4e16642aa6d01d401488adaa620e1df52d773df4e52c756fefc5a9adc395179ccac76d8dc508f60a457ca3618888ccd05290bf0c2c135981cc636ee98061fc22ca4fba5d0cea3570a4dda558ff0934cde2976e17593a3ad925b2296a778f3207fd8f738e325c6e732a61a4f23897ccac6955f04b471ea86fe8a7706d27bb6da82a11f2667ff5aa2189dc033975901cc86fa808184fe6e11d72d2cd78d3e51e800b7c3545adc32ed9262ea64ccadc42f6e790813721330624d7a79c78a66f15bb192d00c2098c20413ad7c02ef846add00a1cb7bdf75dd0ac9083c28652d12138f44e37bc6b43e9c6a87acc6e6f91e0815ac39418f4a4d297c2f7af09f60f3b014df02cb4e2e0a8376337488151a7a38232d703a1e4b65f86099edf03255e50ea0612c544d8a836201a429c233df4c68ee9fe38e560cf7740cb705c34fb0689c4a3b62be1fc51997c75c35b1b71840085058cb72f1a6d6839103fd774837219262732de86a0503304448a7c5aee038c00c0f4531f5b2586add2b9fee05c2dd705a874446878cadd98c55e0f12b492f7dbff4b43add1d81dfc44081804bf363d1c2f3dc572fbbee278464885058c51da05914d7243c5b7680572f829b7361db00a33e38221899e1cc6ff2195798ddb58f472faea2059f2a2ac81ff06845448b4d601b6d4b555bc650d31670828595be0f1ee256e31c8ad2889929ea8806ff71fa3cb364c541ec7f2b6635ef1a0f21cc3d5d638620da15b254a675a4efa7e5c4e6790bd04f5f21eafe5ad2ebe7cd817a34ac493e1b3d38f9569ab0541ec0503902cb41252e51be65c91d5cbfd4446c27d03072bea7f0594d5f20feb2600b28fe73ef9c38ec581feb5ab982bf1fd372b30eec8168d459b77693d01f6b0cbca463048208125f7bca73407a4a2977269b25629d286484b07f87e772cf1126c6245e28dd5dd22475e407250a612af74c2e4a3e5ab8ac4b56f78c25b5925b1d40ccf3f620fe72d5b044bdd61adf7865ab5ccc811078e797bdafb510103d0888ee492384dd29c7cdc0881f3f525af4c8c25fa565ed5ecb19d5f3291ad3999bfbff537bc362daf2698da88aeb169089f419cf8e86d3055710b552a4be2eea9160a3ab9b84fdf13e8b0c52248f2b6d319456586690148b67829a931195363ac9d633bd4ebeb0f87fc430fb85d6d0ba46f336a4a8f23e821bb122712bc71a96ad537b955cf609fd7f89bbec45df0913ac526980b4909558b9ea1b5fa5adbdb2985768636c28bebcb2d126c30770c41f1593a6b3215b20c0074b297218ba937be032ba70244b6c68231a89a9347919d2b9095d8b69a1a7a6a0324c6ceb27fb42fcacbfa3cf417a7df37a40c8bc2b7b58687e4f309ff9a74468006dfac9c9e5f8d0c0de97e26b6b547484e2a881118b138d8b9750b48c8ccc37dc55dbf9b2fcf69f815da874f59aa0c1a39caa48aa4f00e6360bc2cf971cfb41e14ca4ff7d4dce8c8f8e24a60947480d2104ce66f3f0501356738e5b131f9affc6a6725d36a11bedc91637af8fcd12f9f23225940837ffde864c43f6967600d4b0984341515262b2c4d82c649e309bb60cf5b24873f4abd4d4fd39e96550a1f0e86e1bb1988e95de6ddb38aeb01211699f07364f65b920812315b5d92282e3a965f5a88389097cc37d6711add8a0666b3f5b78617d984be5e0837ad96c91b42b21054b0030a654f59e23eacddeb05554e32d5998298cdc01a75ea4a035cb563dc948c54c333684889a1698214fb53c3f54e8004d5136e70a5f15d2c43730a2801e1696c64c1addc76794284fb29652d02ce3c8141dd1e6d32fc1c8ceeeaf34e9e27de3fa3b98554d45ce748db2daf2e9e4ab6d759191339d8a0b03d6ef61591b92fa4e6334944170352feaf3bdd6fa0d2b2372238f2d125a3bf7b57157b0cf4abe684f7c8d64925c87269b413df6f2566267225a9803ad5b8eb1a1b0ee234ee3f658114a7d3b8c0e9250406ca260e539607465d9e1247cc4a11c5afdf30c393e1597f50b064ba1505c8721e8746413c9f6b685f4ce81c1dfd1c821c218839ee50e215cbb3c80e22e43980cd43722ccd99ea3f0e86de50a7d604eaa979625a2d1f465d692c62fde682bbcbfcf18ae1e7d860745249737549b83a8bdf4c70faaf0c9d2778ca42b9ce737970c00599e40733bc46a49e559328f33b89aa76aca0bb557c9ce501f53b5f092dc2ac1dce13b6ab422bb7e0519b06a1afcdfa1818732912278e45b33152ac841e0c21984f30157c0ce80aa89aaac61611db2da83a5136d4b693203974aa8becc85bf238945365d9145656b36d37a78a03dea1cdd5c57cf0b55387557a8ec8350eebe9a18943f2e44af3f7a371263d007b6fc844a811fc64c779d35cd0cbe4ed1a73959ce7addd462696179547d30c60c01f8c475f7cd50a1b6834b02f033d5e08a6d928090424c5e92d541ea7ef62dfd2a629f25b29f4fab4297e1fa21fb714a1a9dc1835447d0951f5566cb00a0e3bebc19205bb262d303c1a0cfb7339236f1d2f3aaa8f6b561f9e253f453f2c2f0befbdc5b48e9fa694f65aae058e73c78feacbae01e537e25b400777e2bee2c3478b4153e79152dca8b1200d18610fd93f4abb5599399c0b88ce130cdfd1976c4fdd09e9f7eec3a05dc110cb930f49f62185a5046b1d3111876a6464cbfe799dfcfcf81ced3dd0108f4c6ccfda60fce09a703aaa6cd8dbd3d112f6f7454ac136ace6601f74b711dc13a5bf39a8ea88f3736a4156a7c91efeabeee34fd97cfec43a27e57a6143805b671aac117977c55fc988c2a096d6be499d22cb3d29e6e10e5e09bad3a820dae21c86867f1dd8d08f26eb25dc997ef5b318b930b249ed8c4e768020290b2191090379225de06f9a11f0d10b32a536af18f8f4e3e3f5c00a68911c6d2f660c4c92c518f3d0c03f265fcff2e330abc14f7bdbca99a861f8e2843a25362f9b1920106563910cb6fba01a62dfa6db32e81c805f2cc94aa405fd760a74783067248b7e7246360261ce9503d1d68e95308ca9cf6e7d60f5c1e5e0d46fbb94281746ddd2807eee46f5e096bc97c5affac56720298e869ebbf1eef8157e41cb93d0e587c6584378f9e0e0e4e5605d9683db9a83d136924eb8da8a6cf48041a067652b6e8afab34902f17081cb6c35336c4598eb1c2dc213cf28a09c6e096bea306e7676c3eef956b1f3a516fdadae9fc50741fc69c4b21efe240221a22ae29a203118e3b83f4e3c8d24f3309736216f6fb6cb4faa10b975c6adeb9d7d46b0cab7d7a6f947b1284a77434e1c1a7accc42a97f56d3494207d0601b3241d244b3e53d49560a02dbbb027db0bd146805cc4268fc5a4e928b6b8444aec1e7e5cae769709621fafc3a6be1216278c80785a95fabc97e819533aa0b861aa19fed700344bb09eb641e09fe35286cddc868c2d465bc662b218284d58de19f66f71b131ca602fc1bb9e53254ed9a0d7603c81be04b11a04a720e1d369ddd506ff913da2c4268b44d8a01d551f5b3d8b9b4970f7394396c450f8b7c915f380c79249a639920080247f785f9ee5d70404afe44d8c996566873225d33b76ee7ae74f9ee2f75ed0d172aea79ac8093b407e79116349ada86b31e4a89c3b1c758cb76d48b5d49b0ea61a5375dfaa4f4e17b64d2a3fafeb151d0098915d92d6e76770811b6cedbe2b47a3ddedc8e12424e75c2d0767384ce79e0d0f410a82effdde512ec2d5a672e875ee1a79fef06f1d81ac3c7551ae519394490e98ad22388f34d5bc6d7f395468bcf80942a481d755d766be56e7afa773a4eb64b2f555bafa1a4701771368892429386fab5c830d82d80fbc0ee6df903239f9860699655693e031dd9e6de5329929d4509fe6839329620241e217aad03dcdca726aa2352d9f0244b008943a96d4d231444a8c1838aabb10a4779b9bb790b2f85097fe9a733692911a2fcfd0a1ab62d7d6d1fa842fccb608a4e0414dd7771772c11a300c4ac0e468e0e438d0bac47ee5364fd005b6a3c92d2191258988eac2d1b174790b76a14425e61b8992499c196a4bb4c623c5d2d675e2cc71413a4dfa106f0156d0a2e90079883e7c6ce960570b37d83109e40b698e8918875de8b660633d81843ec1f1fd1674c3d1736373eef9a737582a2347f713abc1bbcff17489e2609e4b226b0b30436c49087dddac524bf77183b727a43f4ca84c55d1fce57184d25f31be5aa2ef0c09abcbd83c4b3d20be0ba9105326a472f36487662f298bc4149fba7bb9586b80b8dc588d027a3c9f6206629fb80c60dc5b5fdb59c4690e95d27ba754db729ec6ec4500cc01a46e4259e573509f1526ba07943d8a8c7243993693b56a6a0cb3c6b9dd6a40564193d8e20c27c5bfc1ce19a0ebf90a252e053e68425bee6e88346c5c86cd103b2c9ca2bc9e343e62edc4689df8791d29b12a9bce2fe3fc5240a64956ed72229ff42d7e162a419b9b6325c7bccf8dff26ee6ded478927ce31bf72a6a8610f6f933b4c5da9e5a6677eff5b4761917e1248e8b5f6b3f41594137550d9acce31c82e09afa9df58f5b625bd75115185a2fe6785d651afa61662540f7031f631a9f7043c02e8a150cf8de3bf22a0641827867845b4c0453951af41de4c45acf5274e62f59f1775cc8aa79609a556a61d7c5132b324ad61b0323f6e2264f6880e31e19ccfafc7849e5818aede8e2c7f882c24b0778f70dbbb7b735fc98e71fdff013701dc48cdfd07f063bbb1fddfa8f4020ae7e3ee1dad27eba25c9b668ff2e203b6d8eb4412bdf9132e18f2a9212c33946cf321ccebb3f2b40b8ca0f6990a434155c341b23f913fe1ff30f2b08b2f4870a7310a850107f4d0537d310a69379257e958bd70b7b25489592d898bcb12ea735cb991ac08077aefae29525662ed4a379133e06ec9d6c2218c0ddfdbbc32be2772a5d43309f724734b00719faa28a12fa2f68b5aa9a8684f62ef0fe6e6568ab65d9df9399797d23096944c36ce55007a75caa019b9786c82690def7e57954d45870f686d67b23cff2860be07dc3978bc08ee0fcdef7091d77e2fed1154e9b517af5e67c5c935ed697cf4812ab4ed77dd3ca2910669c210ff02c0802ed77d894c865b8a6ab7fd9719989d951d0867774ff8036df504d35e8f9e7f27702f0313788ec39b1c69a10064146f40cfc63a12d32ddb7bbb3f2291f2e2c7612da0ef68a4f3b38f0dbaa7c454bc395b065ea8975848037f73f07c6ce85e67490dfa8c1dd91e2c46c317a6e9a3036fb913c7c36be3f4f1d615d6f0b0f2ac894a15f79430de50efbc4001c0900f602f7d4c6a16d2fc214a1790e4838e8abbb0ca2c47eeddc7a1d70a1694178cfc08194c5d76e56aa1758f11a11f4b216c62ee06d29e2c1d4e2501c9b7d93d46da1896c4484b87b141942778d7ae4d12d5fe0b5c48c3de8ce9566a8b2235f9a3a6c6b9835225a4c6656ec7acc77d2f63e15d5d2869e880a484795dfbede11804732da4b83d2e25b3484c87c485ad33d54e0f67d717f6a2a37dc2a82fe0f976a2a084fcc46b8d8d0cb2337fbb769fc7b4bc45940e3aae9bbd16878cf000ba80ad4733960a3eedcc086a5b911181415aba66405dbc7583b8115c82add0583af011366ced65b143c7b78b6aafb4deaf4e0575b23d6bc1e353315068a70e83df3482de5e47b9693484826c0390109e1a364e82b16e08fee09b49fdefce2a36f4fa24975188f4145cb4553c7cdd4397b29c87a63fd90c89a10c369ee218be9713f3089257265137b8c989698cdaf141b94464e1e809b52d37fa7c341997567a1ce91569def28a33f5adb83201f81c1a6aa4510a0e3513540359a82ac226dcceb50859417f6631cc7676f2f8f22d218a519bad6adb118b533d3fd48b62ddec2d7148488e1934bf816b5ed4b7e79a732e2430aafa662350ea007e81c35a5ac1bb0e3675d556dab05f802900a9685ec008c22e8deac2c12ddd9779899e9e296f7d84c7d9a392654effb8b108b79d0d56f846060f90f92fbb99b1b991607177c5c5407cd7e86b5e09f664dd8679d4e1ffdd9f88b0ecf18daf016d1a4748f203dfc2ad6bcfc529b0ff6e93bff1838f633b0e8b2db88dbb23747723df0fec76995c05ab9f290c4ecfbac1e0fa79da143f01e221dab14ee9756e77696166ce0d65c68f84a4da04db66c4dc5091c261b4207326babb76667a8a2e2b32232d48ee32a7f9fdd2d9180ff0f71058014a239c6665825438e6244c8418e462cc38ccd0ccc9fee7aabf517eb7b16c63f0b1d75516318f477f9e194445e6a8a00e24af0a7d8ba91f4ed8f8fe15077d89d754651902d447e9575a5227366d68c788c40ce95963df010025215d4eb7e887c3447b762c0385a0539ba0a8e43fd26217db89705be82754e313478c1f1fc3da891bf6f2acd32837d9f7460ecad53838ed28455f01a4c48eaad9bbea19636a90833ab357ae8956af3e8ef77372a40e0bad3d3bc217278f6d189f84f83b614efd303767ab54e0e53eca68281cd335b314b64e55af25e8414e38d59c8c9d56d9503ff02f7f5692ac25f1081b9d2a61be73cc834197eae1d77f7c374e30d85da85bd02bd8f500b45740d3499dc050e313cc4a7157c411e4588090ebfa56f7fceaeb1043ef45811cd043b062f00dc5e0ee85bc89b3434f76786c904bb9682cfaf45fb501fbf13391d234191ffce3abd37e0edb0e3108539a08dce9bb02ffa3815d15e639946da543e110a2211195b5fddb756099a920afb0ef3cc38f4e0ad484d8c61e37a65dbc5a85eb55fe08a4d5f95ba9e5723b5cf50f2174ddcda428386f3b932b936f9ae3baba7a0013784e5b9dfc8ef4fa49905961dc98a58c8739bfd4b92c0e8c578e6b8b42af08c0a49b23cf21c89f8d910396094fbba25fc25c1cc6b9361319cdce3def18ea79098248ee50eeb20928f408f30257fd074b9c186ab86075ad98c46b84b8e3e6d2e2f44d3496ee95ec19a06bd1eb458875c6d65eb781d728caf1e30987f9dd025ac81ddc1c8fb5edc27ed97e4e0199f2a2f1fb9a9ab04b1708871baf52eef9c31ec51e8de8619be72a14fdfa7110824da2dd1b22bd852f3adfbbf6cea930d85a95183c45dfbb9270685b35bef9718bfa516ee32e3b7063f2a58e15383b370406898060bed50252e80c6b3ec742e65314eec7166120ca9f8dbcad08f7d0c1bab25931341c5326b89fff0dbc4ab7da4a78c25a175c3bd5f658de3af8160d7d570df407c53e4fb52b86d39820673f8b42628bd85e1badbce5707f4542e8d9feaa75b4c68a9f5cda39483d865bc61e60da84c708c36ba3270e745e486760bad3edc4d66aa387882d4c3715f2d6200c6ba8790cdea6c009898d357f2f43ffbad7aac11bccb1a9cfc80921986cb763df9c0944e84fb9585102512675f4a201eed07998133b627d8f02420022389a08840634d225edea04b652b6c2a1b0f648ee25bd495819b740e40b7d59f39990582e66c60f1faa342e222ff0882898a85ba5ef8a254a211168742f98398ee7dd654e47515be1ed8a51387fa460333895e8859508e2d515fd0dd5dcc5e4f8d65ec01b0294ebcb566c988443442b5f4f79c42562e68cc0c11086e0d662601fecf0818bd60a6620d94aa76eb656c69e409da1ad87a5020d6f67f20885a6f70d8926d204abb330721c0fb0a61784aa2ff0d74eb41dad9905577e8d405cb7909c507e2d903851d41b828aa5752764513b20b212bece1754446f0490c81eb6a29719504400f8d7273d04590181b66c5df170f4a422feb9d89669dccaa2acad3a5222e37482308e003a3aacc85f41235549affd35066f14a4f7b3e4a9aa6224265bdb36b19bb54a054745d6cd161acc1bee1de265e240cba64ea6cf4c9f573bd6d4bee75881ceb156b6d415231f9c33363a23c5341f86dbad4148e948266588a0db51017e86549cf6d92c7eed3dfaf204eafec8cca82c63c8827d613d0b3e5e5be467b1cf8ff3f1bc8cf663eb741b06086a9dae3b848a5446fe531ae528cf89936cfa17ca1e1952212446934882119808a4de52f69821e4c31736c2026b433d5250909baa2d0893615314243ec8453223d17c0c67140690fd99aae2c8e30da08b547aa675dd1d04aefbefc0702eafacb39735f4271bded77c60c8bf00e00740ec30f561866572bb74b8aa7d2fc6b3e9b514d6e82c9bf53ddb8751f491670ae2af941958dba1e6e060cc3d923466365a862ccd539a4be39c901e921c4c673be5f6d42407e351a89a7def0a8385f9bea636f6cba090c60292f0b784dd508533ae8ee9b095c9f537c719c206fa44004c6d1b6bdf297466eb8b392b68ec5de8bbdd898611859977eec4cfd1f91e4fd0d7b10810279aca62cd133eb8f0fd052535e726e78a665a044f113e335f4dfeccbc90e818608732b07ff374546d23208ea5b1d3a96cb68dce06308fd6da3cc80a30cdc92369f5c7d45f1a8b8928c9770e0e2fc215be5df48fe8e2dfb48294c9d0bca764c1f301372b90d48654e2d01bbbd53d46a5b0aebaa2212526272bc922072c61f487ff3277eb5ea6c5c07761cb8a548863db5b094022dc9214c17bb92d64839ffd673c91e2bd3d359c0b52d94891a7341241d2164b5256654191184baac60637b431bc9ec8775410481788d3dd2d1e8ee10b6a5c596b4402a2a8712a9c482554f8f1e4422175a637d408e0dbfc52968607d6e1da971c5d878b3b9069a1b6c2e8320d51623ca6e5a8d68a78aa68a0ffc7a05fc7742e15aca718abda9578fddc39cea17a21348e01056cb3d06aff6cf5120129d969d113ea40b14b824c6fdce73c1711aeb644100b2a2c7a7ba5d3407bd192c397e06221b3f18f588bd53850757df31e176a29775fb2ec5b91fa01982cb4e0ee5fda3f9f5231985155956f154568c401dccf41345229252b9c4c9bf730e081417c2c7d040d6e2083da8ca0bc2476cab892c921347f5838cfff6814d83b6eac58a24ad1400dfdcd69306ba161dd5941b920a820c7acb782c9748849624409c954215ed5f8ff703cad9e15492c2228b575941fc3b0933c8303a310c080ba3ce09dd6bfc464de485713a12332e183ccf126999656da1cfc7607e8d823b29596f1a0c9c006c6f21cdd394066a0c83baff44d9bab20261fed3afbd454f809042234fc3a61931b0d8087a39267557542ff825bb9c300023d8dc4fbe17e80fd606dc11e705895296879acf943d555befbd0b0a222e2d16e5a646fd769fde3eef9072099e0c168108643bec6fd15a5715eadc19ba7279bc624c6cda7c749c7f3194f4dfda685980a148aa0f9110e385f8389d677cd2682df9a1ac4b2516a01153373d4fc9b10be359456b05cc70ff65985187f4492e26b8f352499372652e37a4fc48721ddd1a6fccea8966730535407cd1ba993fa8f1be57f6313b51d36307526d08d170af801605ba6d3e45de5075751f1ea3f559a5215530a22c54bab6debe4db7c32e47ccb5e3bbf090e7b72ed2de40616cddac4cceb3a30a14cf242d547db0952afaac5bc3b008cd50560f389d2cf8b5271adf2a5bebcf99a8ab40739b15f7b67b02098d8cb7f96fb598be7bafbaedc47f56d4aa37da21b2bec143f52c901986c07156d7604c448485cd3950ce1d23f53fa345a3e9b88ac9b3c02edacb564df3408e9c23659e70753af05732603a968bcadeb3e0b7715a1db34d6745fd755a36bf53603cf4c3af450468010fc610e461c43bd38f1cf50b06bea85bc2b42d1e861214282744008518b02ed9a15aad74126028c95406a5cbc5541df593511b328ceddb95536aa8277b090f7220ac8a97d309d1235fceaf074828860926b44941820f3845099d217d2671a6ba9f947b769372923380b807204a66113012b047f789bb741203b7683d7b7beb49d644f5f14f707120e453a08167a434cd506d5d6d24594b30865b3ca7cb90a75e82139e3780f6963862ba89111f42731c2ea789f7bf6ee3c698c3a3c2501107182b58a5ceec5b42f5f572a35e56ce0ded4547202578d85d81ceec688df6a71603b3561ebf53cfb1562c778e6d6ac5f7280bb5004c0c217eb84183db3d9753814b05501d28dbcdcfea1cb369cdbb9628d1fd36987982874da9ddf139a833d8375b6a574346f8ef6dad1de3adacb477b7fe4ef47e7ede8bd1df5b7a37f7bf4378ef6d6915ec7d166f283fb39c911bf380346c6b9d196bf0f794160989e51f68a5ef5ccca2d13c1dfa78e3575f05c49369f6fbc65b099e20ae54b0b2b9c3d1637c9eedc7facedcd959fad551609c703eff9711d4768b3e61b36ee03720130496c5c17f3ccbfd769023867a1119bf8144ed659cbe51c2607f0e385bd3f54b0ea2c37c42d4610427508180b2e1155d9c96212c61927ff4406ebdb58f8d7b7fd517312e1af357f8ce3402addb45a0051328e1a000c7a9b42c7baa2251a4cf8551ecb0f093b02daa33afb9893a2fedc4d7871550156941cd4efad5b69aa4e6b3be103ca3041cb14ea8a0ac2226c14e47a07f63f1819557848363dd0ae1fe81897ff8df5a8fee4b2e14285198a1a3fbd76275fa3833738e04e6961584632541572f8eefbab72f802745b819d01b074eceb70c028388db1178a1c8ead31b40dc33d1ba3632b427d8f6f9f739c688438a9a9a52b11eed3311d48abf879fc051f898540e022fdd27a123d2c7c2cc157f4cdaf290874ec3c647feef78c785cf5edd4a4d4a69b8fbd2b32f320164d998467600bfba4ba8b02ea4f940eb95ba2d99c7118dd15c432c7e93ced03981be683108c6dcaabf629c6f46018f837800f8781555799637cf6932665dff143817d027338fabb5f9ba9c3017cef2fdf951a8492e90569513c1a8bc7ded9e92ceda6a269df89d57b4eecde7762f79e1bdb3d0ec7c67cb8a15c4e32e356c3732d627640bad17d8419ae37abfca924cb48eac6016ef2920046dfbc15003f69bce03030698561c7d773d5493d59931e3f248e39d40e8f48e517ca8375da1c1d5c999821b8ead6896dfccceeb5166ad2d0e8a82e163330c1c6e40e97033fbe807251cb609aed760f8814c75da99d9109983463bc7141eccddf2394cdb6dbd778417526ecee53658d3a21bf69d1794449cdcd90c6c3286ec1670100819d961d18f13181056142d2773932dcbf54e8e1d6ce74e230d221f8bed109d663e6614735a375e2d52fdb6a6864025c8b09ecbca8bd6124f3754263c5a77b515d8890822df102bb755a2eaff5e4df2d7a1768d055d1d751e15da0ce30e90677df266deb09606ae4d548373e4e09a340ae887841301893bacdc2cadc1305c65012751de87c6633eb05479c07182da5ec38ce7ef786ecb3ef9c3b8b660d53405b508cbb990f098892412362f45b0ba13ea9712bea21577c64794d4552f3da9912cb48324d5d2e497404d740b3a8c109c5bd6ef77441754e5a581317bd12856616a1b9945e7e0c58dbc1d3be59add9d08ca603e2f934965131ea216c2e1aeed461ac13669fd24d03af9c609011157ae1f2bf106211d53c7cee2ed07d7a94f9f019a3644335c22849eb0300b653de609d542ea91aab567842756ba58f574c62ef757722ad37132eb62eca3f8345d2159345f57fc40b2c5f99f45bc26d5277f4679eb90cc6f13c2818dc76adceaa811e90f04c7574a1547d05454880cc272a9a1130f75450a688206cff36784687009bf0a318f597b8dd90e5c4228a44a43e66d95a9dca10e0beef3d1773820f82ce5ea3a8f8ebc886235d1b2a4e2aa343779530acfc2d76a833597b7012f439e73ae7e8c3a3e7c98f6d5bfdff3834439cabc68da08be2a67672920bef3743132a551b96b4e4d556cfe3dab453abc33e429d7aee9d43e8a5b4fcc585d2be174d1a72c883ac6bf1f95807633e88f23bd70c1eee9b3aea9e123090fd6a75247e1f4975b847a07b90d65bc78ca2afb8faab6a4f4c4105b41a7b71911a6eabcac24abde3eab91fa4c0ed44fc6c0050354da8f18016afb22e15e2a2c2586023a0042ba8cae566466dffea30da8cf56d5754ca71e1a18ec743d01341949e80ba484dd68aa1a964657993066448552a718851fc7efe6db54f31d548d50cd241ef2b8438a057a9caa58da43e26ca105a5a43a4b9f113c3d909c6f4be81bd0aa71d64a34ef9dd3a633d425706fbc5045b4e6db5ddb8b16dd6e96598383b47cddf93ff1cb53f9b94c01d04b5648dab1d6e0e3fcb26edf7c7118f34ec6b76ab1d420edfe56cee314fff5ff8f02e8c0462483c222061e669c085c53b5f33d5a0409c93298bab908610c747e2098f1c18be4638442821351a7fb0508abb8c9c437a42ec97117d924ea33fb97f523338c5b91944c42b12daffff5788436e09123a4c0a82f7dcd80953ff8763574c85655c3ac6a0e6ec55c1485773d88742ad70bec0a9d66bc0c92bdfd3162d68a9d68bf185fb8981b86e8b2cde8e7a7847f755a5c59717b0b6da8505213b1c2cc5a8dde1326e3e66127d80ea34b83a9af8bb65a4277be6c88921b59fb07b36d8f57c5c0cf73749588b9800bd95012cd7fb2a14d51f7cec396253527219910142818f95cead1d0492eb773adb9f65d9643c00abdfdf9f0c7a82a864aaedad99d5c1120d431f14c29bf59488a8690836808e0116ffd50d920d0fe9c8d7308ad42f58c5f83dc65fd05ec3e1052d6850a5175e46c5378709d2233a4063edfd13ee0a61e4e75f620c6f91abb7e04434038abd838a9327dca7171b9ae7908d82bdafa145584a507b38029cd6bc0ab7ffc3f1ffa27026b3fc6a688aa57a6e816b4ef727288873617eeaac2dacb1655014a10a29bea9e828b569eca6033f29efec26fd400539f50ae020151008caaf0360fc2bbac755cf7a62ad250cefc86dd009f33272d69980179da5a9bf74f37e2909986daaffe52cd1d1c40309d8867bf0784f1345e5058bdb82dece59bc071a899060d935420b6150161b9bdb8a0e547ff971a6cdd5c69a7f847e865d2fd25e247c74132b13b8b8e8d18a281a5c555e1f24194d45e437ee11d2ebb83ffa28bf774c9ccdecfe4780d02ee29df679cb5cfefe6b339c184c8a34243f02c32893fe45c855bb1de1d23daff40a15b071e090ce0879f82607a64ec74338693dfadee9d21ad02613441a7d7c73962a6a37034d3952c0faba35415e05161791f4296b9f94dfd12650e973c2059ff7269d3d7a54ca3a9808e3e50fb31ffe2031f90d1e84137df8838b61a97b80c8ce2ba811884693d404f6fb354df7d065124c34e74220ead75846ad9ccfb2220e062ec96debe019f66fd45f045213025bddddc6e4a8e95f9c92f7e469805fd3890cedbed47a58bf6eaeaa0ff1a8fc7fe506856fc6085597eee9fb021534c8e88ec754e1c3904d9280272c12d8647018d4a30c24f0c759c3865c54c3d7c412e9f6aa2aa3b3a1f3798294e0c7f82c2730222d2822401eb8fe493d42349464002feb685a2e2b15c0e1f1fbb253d6874453bf30efba91d6bf7b92d3e79247d8c6ee60de38cccd212ab2e546929eb346314649231f1f642a493f159f0e7c225851403b26cf3a4e8432aa2bcb56a6f69b620717daf846df638aedf99144af60b42e4f31256ad0b448069d76e65dd11d20e67a90ddfc0124e8125c48a564867f7070f020b6246fe18a46b88c04288dc4b021cd2d44bd920981139d88108ff622958916a8f0defff5c3db9418e9734c0ed595b58d539d92743d3c4a6a3571069611634576b93476fcb1b53e7676d9c00a965b38c98d6eef346458f1ddb5a83df4c8c962c1f6d10ae29f1c0b5cf43c1b7fc4241c4a9b5a350cce64ea39cd4dcbf72d13643995b1ea9666982545d256e652fdd2b8c6deae894347c6df3709f07231a6a9ba5e8ed866002b70f08fcbb32e9e32b7df694d8d549e58e03fa4254c48d45f712f9e4126e0d03d6725e7a13e91a7edda08d0f9087dad84b3448a0af8fa031275aaff5d3c3be26fc39bca36ba3ecb2120fe1d986b7302c5a5c7e2ddbd83688034b1865494438d9f84468283966bdae272ed0636886b426a6e790d3656e7cacb39356c68fa1e1555a30a64d5b0698022c8826a33a43c44a383bb4a6a2e3a0b15ef69023e6ecfb3c971e4e8afc2fa47f14f2658ca0fbf69a452c4cf6cebdd39e3cb375b0b0c402064eddb604c8e6e376f4dae5cd1acf2000574ac73125760deca46e5d853b2353ed683c73af6a7a0c341a19d810786427ef3ce1db38236244c36a99347676cd2a28298dd00d2626c14925165a0045da072e54a66edc3544ad628c110b4382616f9ad8d87b3969b4bd3f849ac743734d0834aedf55dc5ee21d98978cba2b1d549ef47e262aedcf0c0ccab7b66dddabe715527894c76faa758874567a9713a88568efbbb5075d0da8c455a3aa77546329212652c22f1e7af6e1cb220e790e5b036846f6e61d011105c008e91838335bb78201284ecf10a15482b01f0f094b8165530817a234a8f8e44e440d29af190f5eb2ecf2f2571c822f7863ccf0bf4322e6f5a0c67ecac91585d159dff0bdc484c0e43da9cac02185c9ffb0598b3fa5a65b9ae88dc5db18c199fb26ae203db82c0c243751de9bf475f1ff64917b9520256d2eaa54fdcc4bda09c95c72f32fdd00685b22050911c117222957847165bb3ab52647534a3165e701d7bca9e141f0c17775729c1b228873a2ca451cd06eebcb26683e64152cefac64679f1a0cca9b220274913877d64347ac213cc594b6549aa0802be96cba937d9537a18e6894bb7e862e09cd552cf841e65b3140296052b21d10aaf03b6664a0004e08839ba5c5c9acf036841fbbd633236d801ababa4c3b82b4eea847251bb7baa76c899955c4ae8ce47b3ac110bb068865ee550931691331a2e660c6a4829c49b45f4d0da59b3d8dea8cf3996626385d5d2518a9c6ff6c9d1bab8ddb02bfe9b75aed7b8bf41374a49d118002b549d3a4dae071ab616e15038381e28e5894e6d561405275243ca2865db209dba3ee0ac51f4a4c538aaf537b58d78372424144e82790ed73cc1b8e418a6bda42ef7c0193d9605f69d62fe1806451f8bd2dfcd11dc98bc6663e737a6d8df03a7114726ab401b3832e709dc64f09df0244f980e4c99e4e5ca26064e8103fc5366836dbd84ce94b0e85866d1cb96e8d3fc792f835e432f461cc91319625445c77a653c9f16b2eb74e683f42a5b119775c9a971b06b2a0454dc40eb524b50fd3f976a652b93fbcc0cdbeb4657978e0a56a7ab366b925f81f73eb8db46235cd495dc795f38252921f592ed95920f191e4e0d0db1c81450fe188d82024886327084243d408c126c641300ad88f36c6e0eb8b3b8f6abc8e11673a0a76f1139543c6e1ccb650fc352a8e1cdbd8dc0e00b7b3ef7f8cc67e87f0ec0789cd66646c4adf4277f7461be6e58a1b754e52a65410a259fca19c3698fe86eb54d84596515cd2c55259d31d6089017f544d57cb19418d0d9e3827078d26b3ede484336fd9468386acb6bd40b7cf27a97c2ef38f2ab2d5689e24eb2bc15df3fedca31ad9eb55be0732a5142c79483b7b4c940f6bc82e0d57312656eb9ac0b48196e6e24421a699d35ea7c8fb65c8d84aeae35daad92701ad99926434cbe1ac90ccdb80d2838583bf11b43ac26e610214e4b09f63de4ab46a2e1030e67c55671393f6dfeb1ad0263cf8288e7c86cdd7f01aad5697650c4ed76e7b091fa688b19f9782b1caffae3746d3aa623ebd768203ea8b008f200ae7bb65a2a344f0031dbf8c15d94dc25b2fb13f33965fd8f9455b3df4ba18aa1989a2955b38c0d5a6f4975b9e10f5459ae3ccbbf70e7e6e7aa9b3c171f2de063c3b35966229ce60aacd2ee1a8e4010e20238e0b0bb346826812efff3b857d723b13c48f75b77b01bea2ab54966f46f88317204d2afb99ccb4eb7cb302ca1d72f4e9107d0108017fa9d7f2ad976e5adefab36a6c250fe78cd24eceb323fecd06a40aeee80988048de12d9d85e0908bd9daa2403f92e7d1aed8809039842b2f70b4dfbe1b9097b7ca3e5e50e41c5d0184c504f70e20bad0799d136efc9d45760346797508c058a612410c33e8fd1215fef3a83475ffc7fd957ef6396efc4ac0e44cbc5df301ec81453c8f5fb00a80daa060df0cf71a56800bf00e77809473c40977a397901fd983488d425125130d1238b2c8cbeac99b81d308280230d11c758f920a2e6ce51c99f97beaa05161f04b2f1ddf325170369e3df3ad8921fa7229eef95068dea0705ae55d2dcf4f1c830bedc4eed2f2b65aa8dbed45c1574a364b04494f725003705999e2bb12b843705aef947ffff07f1ff7af2b40d05dd975e161e7af4fd936fedb2fb9261f97ad993ac5036c3d0376638c50f1ac4b5247e265810448206712a7093d1b4e1ac5bcf5b6f630509a80175c791de7f28334441477fd0910332e25d81337c8d1441b2365e69e3cd90f28f23adb853eca704ed38be76d2432813e5e4910d5ba28d4ba086e052d56b1d0e8eb43f88e89752eb1ecf2b8a0d0d54b6f41cba4045e3b962cc0ac30f7fa3a8b465d7b585f10e12d3a35cc9b49874d7f78a39f78a163027b322be33902cb4a4223e33242b810a9bcb5e1d889ec3e62b409533b88515a6b5ef4d4fc50320772a96f8537c57d4398a6fb7b79932fba7f4c78a6eacb07b6664e35979e899c2f74666478887ac7c74f83ba2d840890c76b3416b67ef1d6c50aa50faf8a558e88454a0770be0ba4351754e0dc3c16630539a60d059e88a134a40b06b049d4aba8872a6bcaee454e9a29f802adcf4b5e358513f7d9c112ad43c4ea1c99b7406390940c991f0a203e7ae752976302f7c3c6997653ccaab549e1e5a085aaf6139018b474b0037111f0213de6a30d41eda26b89c80700b29f0aa7ff6745c9a9fb8a260b465459a0794e77dc21c8aba5a89bddd9aaed1f0fe9966d6bd2b2d6d3a07147420c435eb7570d9847e3aeba5ee71e6aa604392038a2ae9db30088df9550220c225f29500502ab5cb40e9b10b9959dce667f129a101d745f450b7c9d0bba86eed80c2214c158765b3fd013db4e3ec1796e04164632529fa3092605e4f4fea06e6b9c6c51dc43341841b69a832bab16ed725abc785e337a34d04687a49cb56844b098202e5d6131c41222d0409294afa5258c59045b809e83fa5d956df94c8424cc2338df8ee0763dd19061d296e928ed08e162890fa2d3757a842f5c41829dbd4211888b5103528b3b0b808b1608354fab3f60096ecde52ed077d67a0c3f12160c0d88b3e459ba7594583111ac4b3fab002fd26877461489d516c3b086f9b8ec89fddf6df71fe5c0724214ed8b93f7cf10f8373917401b67d0caf49793fa0ad66223280b321151a1b033f5490320fffa01e14bc351544d099641ca6d29bc03d994b8a6cb1b928d9b870f5f9d42c91305009dfe034074416927f7fcb4c6d73d6fbdcd2ad24fdc4e45d3ceae7f832a185bda004f56a53824b6293f2cf394122a3dfffc15e441eec8bda07647ba3aebba6522202d49f85697f9c8b25b91fd3b26309e7f1b2afb4d4d38b6414f8b81d87f4a712e2e43087591fc206e71ac76401cf6e4f0cae824c30ed51e71501c20ada6532638bff576cb1ef41cd8435f8ee570a2e369766b7c45f3f82fe09d333dc26705b681f0cd1c7630200e441c76e091d74ceb1fe549107a80eee768c8e672675be09cf42d568a437d1f1a455435cf5d13e02a0fbf8cdd7e465805e01bb7c43b33d7aae02c308ca02f7f7d2e0b90535b16f97af7344f5b06b4a9232035a118cf092f35f121a81dd71bcc445359661df69ef91ccf0e57f107bef3ccefe7e9f5e2947d82cdd4711ff8897470f7b28b18810f0dd85f5a8ec7ab959b1590e2cdbf5af1b733594613bcfb6834dc9b523e0577f6dd25463e0f9837e712c1438cc6f4145cd0bfe0fad33f0f53eb67f53c9527f1fc30191d0b9dc7ed5561c23378ef3a635c9d3c3b19c20d423aa1069b7761ec47a109c74181ab8560eb1b0a93377e3ea69910eef2f0345071ab20d00c1c9be9cb2c98ae792e7d7366081050b6d727dc0a96c0de02e4cad3de7e55b3d51b48bc1fa97fe0bef4fa6992ac422590eaa4e03d5b80231a24d027b0de2c8567f991f0581069a386753f8fc0128ee3edf3c7f80ff4c48a443b8c45a7cb7b171f116051e233b0b92b59fa614a9b9844a8230f8fff0a81b7075cb2b0c5054ac7bd24f8afacba33bb99d26531ecfea0bdc829c0be04f26e1854518d1eebe7046a0dce1fbebf5870813aa2d876d0a22c5c57528a07448597f8da6240d0fba56df46a28dd03d529c5368eb83108ad5abbc6ad15a74ab3946d38eb6d5d77ee97158f91671d45f213f8ffae13a0bf0265d2120696be36fb6af490e960bc00cb073fa9d7d97afb7d7ea31c100dc061339d0872ddd5cd1e927b08c4a9dd588161d355320c3f04b561e62f3b0314df74f2fb7d627fe1ebb2d72eb4705fc35cbfff629746eecb73f87eeac38b0d505a8ff74c35f67ecf6d31cf5524e7b49bc66dc38555b0723541d661e8f570be84bbcb67070f3e6da6b16abdba219e4560ed3234fede26e360410a2faffdc7c0e50e05c07c00ae6030dc5f98a2d21940335be52038c9026b71fe06ccfe3a9691107efd1d2f86ab2d3759d5ad08e560f2406647881282b6c82d2996a81e8bf309ba31f77d613b2cd0c7c28fba40046947ea05bd31cfc317d4e9d7283211e56426e2e4ba30c82c73d934bbd3653c15fd07b6d79ecca906e439315999a3d10fbe6e986dd778950de56d0d666ee57765835db6e9f4f8ae3de319ab516828af1fe2debc5e3bdbb516ee875ddf96d2de5d6188c4e4070c7c4ac061f30caad7f90e83f66ad6816593d9aedb9457c6d701b317d745cd6e61cc6e8d6110369a99a282d8c9a118be539e448930e1b4f6ad46e1e07d6444f418b499b8538c5f0779031f6e7c5b67d9c9c0c3586206e29464afe730be328dff84b6406a0b8fe51b2efccb24d38c4e227feb362cb9baf1ae8684c06b7ab306718101c05cd02a084f083016f89ab289514e6c1c3dbe450be0ee266710f7a8eae3f502a048774d714111dfafe5153254fc38df3ef4b30d5e9498f5abb6e069f8608372d01074606f3650c8428fb6f37c0869ae9f16be221011f2614f5c6aa96ec69322ccb29a46ecd6aed4f0cca3526961dcd45a5618475fb1eb5d0f6d7663c388e9de672b48f6791d5b9805c8fcc6489edad4c072c380c50fa24721dc80976aad6f4d960017be27e4595f2a88e12d68e0a9495973be8d4884dddc83c164722c1b7cf3eac55aa5df960565029885083aa16533bb315e330619904cd0d5e31103f74b29d215908ec56a0f1c1ff839e97dc915bb37e1389ce98e66f0d6e20900ef3fbed98472e0706a9914be4134ae1ff082cd02b0ce622d56058cb2c511e248e8052a98e3e185d183cf2635cd438e0563990a9e282aa24bd55a5a5c517a6c03998541ef603065e37aa81f766b1e6c6f3e3ea1afe79cb50e7a8826d9998bde6c48c378412475834513067a81ee38ef4a62501abf78980cf2795d3ff481d16752349de56305430a8d02b20da8d5070ceefb560dcbd86924cf25ff476b60e8158a1c75c181c0da2db46fb09c20b30f87276af684275c84aa6ee4dd6344ad5c32d4a7def13140e55fdb3c19212dd42b99e606b334187c460e3ee4311603466b7243b16c2402af100e08c6e163dbf434a2fc69d7d0980ca20cefa24f228f75330e24f3853c7399e03d0cfbf8df4d4199f248f2ab048df7a45a4ed499c7b7e0241afd778adc06fd803f14f5220dcf5bae332bcf84ae8520e3a19146cf4c0dadc96745d3e835ad9f131dc245fdf0ba904dcd1be186ea31f41407abb3eb18a35be542aa64e353150d6e1b2a0158897570f799e78e992c2f33096e2926fc8e83a9ff5434c3d7b06acb3fc833156f927086e90dde933c08ac9ca853c844b3ce8703b63008a3b456cd17cadc4689fc29c238d802790d03eb75e6fb42f7e0a80e0c696a6fc466973b783de552667c123c24cbb8481d0ffb4219da0a2fc05b5b1c32fb8d3f04e18a66b71d6dc582a153beee09056dd880256652307f39212990a23b14198d550491def7491cc4170035ea91dd71696c127ff4af2cc45bfaf6cfda8581c464d5102b06234926a921cc00066c1989e232b89aa8d86405c1d247345fc7e492585dd63f5c7c593eccc2389da17117f9111fcc9c0307fa19bbf0d33acdda46c39b2b3cd8ded86be62238028cc77205c7cdf218bc914bc82af2f498d1a6ef28214870a8d0c8d3fc49b2d367ca7420599de16f8b1da7226070110346e90894f749e551a43b116a304acf0fac753e395a2ba3f6305c78621a8561ac9177fac9d42ea3af7f3c9773e3852ebfaa67156b03728238368f78612bc29ff9802b12e75a549c9f196ecd6cb4c949661cdf10ffd8141d46071c24df9b2b689fd9bb454ee1729c34e16fa4be9fba495a220f7247b2e993020fa1fe6715f975f1be74be81b5f9c4fbad1b21797e1c4fc1eee00d78ad31107c1452054b627cfe0cb630c88e8771fc0838fe775113d66572c0b3969d579c588e754a6f2501ac913e94a28e67fef552b00411be85dfc6c93937b322b7da8f3520c5afce745cf104235c0b3139074958884446084aa36f57f78fb0e55f1870d345bfcb580351eae9ade968dfe14a5e840c40935562ac044706bafb3686d4dc43c4f21f3d4f87b52ace9f29248d32b30ccbe5a1e5a69d326543efd93a4bfa173ecf171a6dfd8bd37e367dcfd06937484cfbc99bbfa1679e11a2af85a7a0e05722c36a4e7dce42b29c578bba15f858e0018899668487df550b58d7d7e9d7bfb844b565b986291e8baa2000728e25b8d77aa1f3b46d0a1fc013815005900f7dfccf48ce2edbaf0ffd0cb95a6da061cd6b4f5d59a3e42cf850464faeb120f4ca86fc4c48a8095d3b5f7081c91c39c36073508f4256bf942bbebe4c732bfb4d8dc89c84a1281eddd6310befcd0b223018ccd424c09f2365998b01edacfe0baff02830f0e95a803e1e3e2c786d90497115572440734c33a26df1842bd6ab152f96a6d6490c7e373fa3404fb67dc571f5c34478fd01c5ef72df829c8abb8e6d3829911bb5b3e4009da2729d3ffaf4d0b74821a9d807ef5b7b7bddfa16ca2fddcd4cb777f967b5f6ed942a8c7251d8dc1eb6047aee0a12355de90525af27c5a60ee61a0cdf2852dd673ad1e67d171906b2051bdb05ca5cfbf8c80183d76edb85ad67b12be80e81b2cb1d84ea59ab52a853e43b2878ce441ecfa5cf41c63c9db189effd11133e09d41c14c6095f013a0d96ba11c62cf30254808929d59ae321564b0009c6821080c25cc6dce23e859aef2c18c6ab67daf3504a8929b083e254710a730b2954eccd97b09c4e3e021a793065904b4cd4c7ab33a991dfbb91308c203af58bf5049f1d51832fe8853694f26592cda7c069ec498ff6420e6be7ba608afc711fef92896ddfee1134d30cea4f31dccb7b78f1db141c0115923756affe1b1806a5ed8f492eb9ff6aca9c3c22903b7f1ba55e9c870d3ace34a990e21902dcc5e8a2462f78a5fb31e020df0a3a53bf194a77bdd791ea1abd519e81d9cf41d2b27d2e6b17236ec21081c31efb47d587d6f7b9edb168b7e33d1ff73efd2279ff3942ccce2748e5e5be9753863b631e5549ead800ff7b4c9b021054b3959cbac0240a344af6786264ca7afa07e3c80c811941484030c6b5bc02ce6a69d2547c33691dc08c561b7ee10a74683d7e2715b505bd2e8b3f7a09abd68979df6aa8db1feb159050d1cc56385cee3a150d883566ee9c7c606f6a41488ed6fc8eb71aa8bf61d85a28c12f5a725e8d6792609b0fbc6a87db2ebdfb0475bd17f1ba0deb4ad93924a021cb8040b43a424a2e4c03fd1bf7e7da9042e4720d0db7f9877699d055676ef4d04e9725c10c50788c3299e385cb9f3836ee4e0035a5dd29273e0033d450062dea46097243fca637edaf79fdffa35bf4b1fcf479b845b4e305a194b29e19fb2261c92cf0cae5108fe232f920f825123245bf3960b3d59a6bb3768402a77920e2160d16bbca4c37689da4892c896490d07391e7062dfec6da92bf93ba943cee55cbb2bd78ed5f7c6eefc7168540997741ef842f67f0f65fb0f3ec50f0042d5fce836fe7bc1eba33431606e721e1b1587b863649241148089ef9785466567f44412cff7e20dae7f8c282bfb34378aa005b80660fc23758654ae59f037f2dce2aef74b5d004b40d35797626c5c602f5cbb57e26d0fb443acd8b241f86f311dce9eb69a556552be86c0ae0ab52f34d143d6d60e557308cd19af0266145ff7d540a71cc4f4781bca83dd695a267fe74ce445b03e3b9f07de5c4cb14bf4d2f39cc73309ccf2612d36f81a4001be5871c6c4d51a5bd07c314637a6089cffb3ee4693cd4370a4313e01b753116eb06fc26dbcd6a011c96204b685a32b189ddcd7025ace6a0824a3784a5989044f604e4eb8fbedf99c8d56b49dc6046cf21008a2c8ed531ab5121f7bfc0f6b29283e0eb4fc16e724af6be3d2c8c830f97582cce2c90ff78fa402347c48c40623f8d86fcadc7bdf9667ba9f3b5c30add10007825b89d130ad4210d1c436dc27e3d0247bbf9848ca8d8fc5250551fe3a66386ca69273811cd921c43654c191d1eb3c6733152fc9e9f05d3fa4ea2410d7574b27a6027003d41e9c1346da8728f95e7b5d25559981ef374310a2b89ed19f718c6a534bbf02c7a20804d5ae7c67b66bbbcb114b0a5a3ef3c7341733601580012d04c293ba624d8ee22fec83b1de0d7367980cc5b69e80fea040087d6517249b68320b4520afc4c4c70d003fdc67d40763f83ca759bd8e22b6f1ffba10068b529eb951bfadbffea96e17ebcba63cdc821c6f867a4ed4d21edcc06ad713af0654d5a18a6a9f3110b8705e5d897b6d30ab46046da4429427d913603344d43487a6a46235b6beae00b19d33377a0ec66ee17659fa5ff59601dbe59e52434eca3baab183a10c6074fd05c79a173251e1591e199b8a8769d131e2b7846fcdc38fe45a6115708bd6487d0080f190f9a06553f6cc9240445cd22e2b89059aae76524be09115643ede30a5892d398d99bad9898619b97f2f027e08cfe7336fffd4ecd116cdca01720288521296516101caa18b007bf1079fbb019210f64f78100b366edc6f4767d381a6567e2c9a6b71bc6ec1198dbda8c6e7a926e668a3790281f479ca88aaf3014babe629a18f0a3a6b1ba09b2a840c0a858c78d4b006d9842b2bcb4d06f13c0f4a06ef7e72ae2682747a3e3ef3e7466ea81e82c053c690570e9d911d9db2f0af51d83542650a47c2c0f4bc5037512ee3cfaa78255f95026a1571dd714087a8884183cda6951e7c1ea019bb19c8d5bd5b92faf3810100a5b9a72953a88069d28d447fc3ada2066028f5225117cd73bbb415575b0acf0f07374da09f26da6e02a4f004be2f0563105d301656493a7ddd83ca709f70d83b58300fbfb2374322f7603394ae667c0bb2d96c4399747f0874bf26991ea26926107df3d9c0e01e8fcee6ef01eb1b15c3b17e6108b02fb558c1ccc45e441ddb5247dbdab26d2384904608217bcbbd03f110a610e70faa4ae454be304a347788308281c4483a4f749eacc408edc00004d408065258416184008506a6d8905e2f0001257a419324ed9a4cbaec25831310c9400b283a00bc7a926022060daa6002084309298149018329744ef079461950931a64910935098a4227049e8b116604450ca48042083a3b3b61349941077486e8b00d0e1e347985d8b99a73229f340a7fe83c62235f9d635226557bf61c93a81115525c815d72bccbec77e78e101d56d7de3db3da316bd38d81241462ef264fbb569e65683ceba8f16cc39fa3907d8e53dce73884c2738462e33912a5f01ca3a8f01c8b56788e52c0e768d47a8e5358788e472d3c472a2e3c47a41bcfb1ca0bcf3109c7732443e659be60789639313c4b1d199ea5919767b9737a964750cf92e77b964806f02c7b04f02c9d08c0b3f4b1e15926a9e15902d1f02c9500e05906e978964b669ea590eb594e11439f25144c2511ccb38c8265517dae333cab589ecffad63334a737039146d8f4b963b293078b6afa913b79606ce6f08b6677583d9b4a72583deb62b3985487f9a462b2a90659aabba3b1cad4ae8a9494338d5430a6cea75db99170129a151a356e2f0a3652506105b0c5420b2edc7801870c0c314479b1b4e864a91494a54603b0f4480096520980a54836585aa5064b9368b0940c0058eca5c362393316d37159cc08b683553b8bec3c62d9af89a87c599b06671369705eeb2a8dd42eed4ed3bf4fd3f3f7d17fff6650bbbe9b8f613e55cf9bf75cf1e7f2acc2df639cf96e8679f70ec6cea00964a7920627edb463edabe93ae9d10454222f1b99d3ae9609547a76ef314a24b0a7ba9ecd1b6eb1b9a3e0f9926d223c37fcd90d6336e62006490885f143c0eab272a0fffedddc985e56f7985dd6b73367b6707ef2fca096014577c9f1cffad0e07c661d50463dce93c8a874731a68491176a1944a209d21708eab695a2687be58f50c813145cc8886c080a20d85018496d19aef8689e994062757733a9fced101758e2c6aee7c3aa029189276650e7f9fa745edfa3e3f89e64ce9f33369cecc70193e4f73da15c3e7a94ebb60b84be6f374a75d383e4f8fb4eb85cf539e76ddf83c45d22e173e4f7bdad5c2e7a913ed62e1f3d4a75dadcfd324ed023f4f81dab5c2e7a99276a9f0791ad4ae143e4f97b4cbc6e7a950bb50f83c9da25df7f374a85df6f3144abbfe794ad4ae1a9fa751da45e3f3544abb667c9e1ab52be6f3944abbbccfd32aed5a7d9e26b50be6f3948c76a93e8fbddaf5f2792ca75d2e9fc774dad5f279cc48bb529fc776da85fa3c76a45da7cf633c58cf2c9a332b9faccff9e769548fb3929d33d82983a5af06e763b034a7c179182cd5b1d44883f3382cdd79c1d21b96f23438ef82a5481a9c6fc1d21e162c75a2c1f996a5a0a52b58aa82a529586ac3d2250dcea360a95083f3d7d2291a9cb7f3b7144a0d4b891a9ca76169144b8b1a9c9f61a99406e7632c35b2f4a8c1f9153b8b666b9e65e7d16ccd7b54f0bc0909cfafaae07998243cafa264e0f997179e77c9c1f32d2923781e851dc1f32c36ce56b571b66e689c5d3ae513a212b58b769aadd8e9947635769f3b1f29b4640531ccb24fd3615445289b598f1433080286d4048a1fd0ce47d6d078fed3bcd74beac81ae88d30b55f10354f2222296a402489b2ebbd92f0bc97d3ae0f03c2803c80bd9ac8a0c951a540555e465548b083930a444b9af0032744e0d94a4446af9e1e2214210bed86101055f40821f56048d35e63148128091ba0018719210991048889105240b1adec108105111322849084a301447b982421099e11132a3c4580e084d445134043d082031bd6d3462f287a8a4004243493d07c3119224a276404308a08a2f411012541098794042b72984fd0a8a64d22a12a46aa1ea1242471692126ba9d25b400679a6384e7b58c1269974dbb26021afbb46bbe4bd2ae0ccf7335e7e77b17ab96a4c12cfbee046a700665cf6e07d4e0fc0ff4cea006e7a712cd7e4054211403cd19d4ae388de61111913913adf8229439787ec5c6b08bf57bfc6a3ecc524062fa8eda9a531635c3dfa393a427e0f8f5108d849840b4e20bdc7d1acd4cdf59a6bba3b1e9de27d19c51e8ab5d46a614202a78ce8984e74cc293e6e069f23ea076e5269a4a34ccde1feddddc31799fa63b771a9c5fc49f95b8db3cf97d1a9006e7bd3b8f44e068029d1d22843a77e691ce27b35d920667e7c3dd9fdc11b52bc7a428edbad4a13d5a602294cecf27d4634a29501520d042f64cd1833322ecf4a55abadbfdd13e8da6168d9abc006735fb249a7756ece64423229230bd44de4e772371543712a7743371e8cdc4f1e4949f54f883790d76132a769a89014901e96abbba55aad90292c29509b5bd06652fa162cf2a2c376a29c62ceda49a372029bc61191bd4a008274d5082c41332c828e1d864085cb0707cc244074fa400226a008a120c010826469630451361b685099e5071040f645a0b169045131d8431440ba2c8011092ac80a2a16af0648c249d952550948002274a884190932947c84a2fa051c40ea8e0c08a2182b0841f24c1044958010be8ab09103e4082888aa31093c20429638ca1841b43064ec660e2648c24b8c3d1c918232891a0eb91f2d5b8c33c2444d103309010822fb8c07d9c7d37644818628a1070f6640361708184107c61847b5a8ba9cd52e886cc051d70d205eecb6f479602239a74b12343e28a264806c89e6c200c23dc110a067ca28d8e0beca3338182b86729b4ed64c91381d9c7616ecff2b53dc72495518e459b4cd691635f0ed10dff4865843bcb22dc5c88c0e24ea8bbf94688bb59f6dc18bd5ed108a787623408a881e97dc0f3c7f352891446175db56d342865624bbed22cd3ad4e4f2af688b3f92c737a52593ad4c07decfed07feecbcae198fe985e79c4021f24810193288e8014e6be20b59179b101200c01471bb2afe89e946adf411f640018b6433ec800a8aca28b36b2ecc1339bbe72fa2e9ade496f759aa20ec1b0297bf73c04c32befaefc76ac74a69bec26830ce0d1d44325161c63119e71c57add45cf64bb7b76e527964a136772cd1b36bdf2100c9bda74ec9d690895bedfc9584d97afadd6db55ee2b37ab7c98332ea7395d63a9a9e7da72d4b32ad5e272636cad3c7b8b5d79caae1c65574c261b1bfc4e9fddb0f2cef469fae96695e92c3757d3eb5db9f9d8b4a3bbc964bdd34c8fb339dbab74f3b6dd5cb59b55d9cd0765f0d4d154a3db0e4a9125c2ccd42a5fa7566f57737eb69a6ab0b32c3f3755832d530db6a7dadedb263f1d269e4fcd9952cd3be7b76f87b7451b7d2371e89c499853524a3bcee4608f3ffdec87ecf4a4f623a60f699f76372893e86490590619fd92f146dfe0feeb85b52b23885d00f7a5662dd039d0ec43363c31761971609dc3c49f051a671f02e66c394ddae3b763e2ecce5b0322b0c1bc3a39d1b46ddb5438c3664bd37cd4e388d929f3b6cd2bd3603f01e00c36b48e2970e330b19a13856690572d81039c8f7bf6acb10a268030dd59e9d4ccf6d8d971e8eeeeeeeeee0cd314a0b7779bfdd1b4977ed09e692fddd393aa3de219c369259e5756edd98743c45a0edaf5ae0d0df6b30e1deda2efdbd0ae76a1c19ee0e7555d7e51e54e36e90cba468f5a9a71aed22a112ad63182f4cad376655eacf259f6d5dc14a6b5afc2de1f0e11637748e30cc72fbb2c1d2cd098de79bd06372154f9bc35952edae8e89c73ce39e794826786511b9d04bf1ab0a7d4acc25315d32eafc119e5dd1a9c11698aa08b36264b3b779c505a9676593ccccbf79897d72eafcd8f767b6ce7ae0d4bfbe938e1761b967685f490af2ba607a9d7c6a69ee5f238e1bcd7e6273f71511727bc3f5a3d6171b234b3d59f9687b42c56e6169cad96f7272a6a0c4bdfde952c4eb8599cd03b67b96bd602126bf7ac0e13cbd7f6d2b5f1e11299adbe901e621881d9ea07e92186dc7b8861698b48b86534c27dacc91eb9f3f1703d3b9f9558abf9be59ee9ed5ae0524f6fed9208dbd7e7f427ac873d7c6863b7725d08db3d5bd8718e6c8e7c82b83e42510ee187a61fc6a248ee1666518bf9a883b4873f50e132c928e640dfdc2d8cd928a17d29ba551d819cebc99991685931b1ca1d83fa49f1dc860063baf57486d0c3bf9d564ef4ada59a5bba371e9db7138803c119923df433e62f91ca7607932b08c4358beb469f6005120b932588076451f609965d4c606676850822eb44bb543451418d8fab28b0001963b8d3327dde9a28ddc3b581e02557e4c5882a72894a17c959741209652280e45222ca31196f1084b242c63520a4a18c227ccf2a583e511904f0f0f9692a8779674b15d9adce89c5ba944336f70d61e40925e53fa69b3c7afa66787f5b3fe3cb5fda63d92d2775b3a44296d509eb2fa7408d3a41d22b84f67d75e53ab6153c6699a947e7d8fb3c9ac045d43e179452fd64e26fce1def1c032787b17abf7f8d56c3670f79205228337b041ee0d723a1aec6fefaf66bb3300a1ca6ceddab6f7c17669ef18dcdd7846274508c2f11d98290f770f07635d174ddbd6755dbec1ddfd6cc4253b84f390c6dfbd7bffa8121247e9dce91189c32b5dbad3a047959038bc73a577d493d1b3a573f67b0203281df5e2b7dd4c046f2f593a34e79783863bef661cecbd64e95083a56f36e3e0adc6bb41b4ce7e355cc769ca5e83d16f56bb7188c435f49865d11bf18c4259922eb337d4c8ae94b25f118c236c03c71e4822be956a56c25969cbb22ccb328cd6540b3836918107eab524b6520ab0de2e676d504a3528b8ed665503b46c0823b6c022075c2041011134a0450a28a5946698d0761b508e08036b385f66db50b0615c17483865a56ceb522a307c4a600095c0082a8121d4ad88b96b9aa669cfde6d167c83d8b7d3f46d80251b0d6a9a966546afd78b888c0b9c6559961de5742b1ad98e54242a27ba158f926c1811a5524903d8151c4882b152a98461188661a55209c34a4f5c684da9be30f2c59152492b954a5d2cc1a552e9a952690b8213414802dec66dbc5d1811a552a9542a699aa6c96ba52e5460ea946aca92295314710028523002263e4081078a8618ea02c949aabca052f2a24a171af8bc70c28b2446689aa60979a1a4c90b84103344a61d817382234938e288883166d0c3832e8830a219a8a20c20a8e8200b22aa2c09b11d608c8b2f88c09c2802c6a8112f2847241929a1451354e8c0092720f0a9128473a54c6a1b876559b609318366990e294a29a5d408cac51738d79ba053810c8a3046193b36504194ba830ea092f8811341802209438c116639e0620993148e425cf8745c84c006a323a3a22ee386aae6ddd8a0a5ddcd8c868c88b8a09aa55455c828f9e0042b1bb685ceb6c5cea6695ac90721f0369a5201616733a269334aa552a9e4830d78936e434e48754af5839d4d8c53296e74934234b30ceb8116274dca0e119aa669562c51050b3836094a42867b01428d188661580f8830b692811d42473809c1132476404688e1400646b062062f4f27054f8800c4030506318072032b64a045154f4859c1d10a2b4490c59223d9131dc0923842a3500f5e49ccb8d168446bda115764c181232e8e576061440b3070aec734a44ab5986118867981b12ccbb22c8b14c451488b1468a144c5281639726080458b21346d331201319868628c1260f193436484a225704200429665599615e5a0722c30519179502a132204612a62872a2fb80110626460094db280410e68910b4a4528b0385e71450c8a8ed4cd080c1481541404113c70c2103c28c22b383af100179d6dc4e4149da266c7b06358dfede6e399413c319b5dc05876f9ede86f41329b7b60202e607a4c6252a69d74b5b3a2093c582841882c76e8101d1426820c0053e0383eba6081841c2ca8146145069c8053385ab1440b640d580d2b1990028c2a50909469180730cc48c9132348e9c10f84ba08312c8280310e6439381f3001139ea0c4106a4083286c80c5164c4010050b8e573421c78b2ed756c0890542e82009141938220b2822f069628b317ac688010d9e28800536b00112585045cf0d9c28e0b9f68f1aa54e526b337db4082229b4b991371003288c9de366c61352f8d890b22335651c2246908257c87971ce6418e809bb1ab07811c978f1eb4c58ecc857bbcdd69cc1c02802063daff0f3e29cd18e4269328151d20a910978b0bcb5043d2508c2d20241b432ca48c29908667102e9e4c539232344134321ca462e19c21248e1cd6442c7e64612e1054e50e0e206d80c9a38a2cd04068cbc427a9b1bfa9b921234b013d2bb511fd4e6c011c2d0095b0453746014761996695d250330f009bb5494420c2f82427ae36ce184b14500322803e847db3c20dd842a4f33a5dd3e2d90546db0371a742eb18a114a00824e688312b2180a6da211ac48415078a31dd9cc232e7284c29b97209b198a62a01366369882c52bbc79098a1946b5d992c80545000abb971e147be9f438210e0f19e9451b2c854a4c3af003a0d006bb6743a472f34203244821123c8f134a1b2496b1617207cb4d06cb9b79e09b2dca93120085a5ae4233a5d52c90ae82bb4edadc11753c9b1318d065f5a036acd860ee2558bec4e3848a5728371004131c2485f43821cda436869a0db252461964608eeeb049c15a67834c2c81ae82b59b8b18c140ba0ad6345588d918963a150974248cc40006bae8096d6e5047400a63e7b8994d88ab18284faa108aa10dc290812c84c28ee5c539c3dad1ed24e704416177400b279062cc0c2fce99223c64624cc38b73c64607cb431901109677c8c434de9035bc3867e215525c0014368eef2e6bb069a01920e104aff086e3014ff8c3d2610a969df5e29ca161466a6f56889a0c1e1c853fac1ce4b56b38787ee1c5ce0d0e2a4549589dadde6eb4a330760ecda3d6e627bbcdcd8b66f72688fadec2c3b22463c994713015253d300a6727af7d0d1a3362582b18557c716949a14e2c75c5143faf8b912ba96092423d713a6b010ad5f23cf69c9f98314ab1534cbbb4414ae933f9e11025a65412c99e1044ad352dd39022bec44d67aac159bd76c2c7bd709c3c357341786eafade844aaa197d04bc756fbd53eb3d51308f37901b5cf9c99443d432aa18a05bd54aa5a7db0cc96bcb1d882e64c8c312806512d081341ed17d66e2624ade9f34c1f96c52a5772d5b4e72c086bf7566e56993c9b2d6930136a9714a176c996cf821abc995083601785a0caa4a06c49cf6c617f7e35122ba2c788b0a11ea1c6823023ac8bec855b3e6741e0fe8adb82fa59cf9cf1beacc7eb19c2928630240c8981db1bf202f3d424628604f6322132f98d0009126e242f29c32eff19a99fceb7d339b0fb04f7fce994dec9cfc74a196594f184b0748b04315fbacdf6d265f928bd7b778b6c2fdd1f56a42167573e1e62485f463d8f94f9ebc1fde948e90dcd19ef68b6b4d43a84fb9f92065bc8908a3f24e28dfe6744c4d1f78ee6cc67a4f3a7e38414fe8ee0be77e41d1de10eb3e7844f674651bfa00fe8635223ce1f106ef9cd2661790f68c703923a9303918625e28c175b3bb2061971c8f76712717a20bab0c3f8e06e02374fc511476c9ab4d3746c8273639159ba35287970d3dbe1274431170d7471862aa594f36ef276d379cbca81e2f8e5205f2f2c3f6d6389bd76c9bb3151fb59f284a0f64c01cb778e4791494b298463a421dead659c261bf186c490c81c3c7be83002b325bf837bee50497d809ab740e5a9390bca291cbbaf3b9ad8b681115bfd2d4909b88d80b411cd1687a707aaec8eda252f6b6bb0a7122aa0ea33b1a31edc9f4b604732b96615779e68047c93f5ba259fcd25a22b36286d56e1d22b8c1a9b50710463184b6a579e3c3cedcaa525b8a75db9f42a2d6917aba6b0a376c52654e4e03e46a52792764521608c0cdc5fe03c9dc0fd2ea36638c3dd1102282ebde2c7631b9a2d1bb1c9d6bb09cdd665f120c3ec2c1fd94d37ddecdbd09c29e574ab7f3add86661d9af2e67bdbd0b70de17e29a7674a427dbad94bc5acdc6c63e5decd2e78ff6e9e01e7d20bf74b423d23e3dd3c03b872b30bcf365431299c4b4b360fe7d212214164195876d850a660181c9f3801c25d7b5ccde91cfa3a62cd574e68ceb0e665f1909dbb0fd3eb2d52bae9dc2df2d3a374d365cd22ddb3cb9a37d9cf385b33892a9fd40f472a9ae4e00d77d33b957772a0def48d49bca1bdeff1cc192ec9eb9933a5ed2a6f67fae86cddb3e7f3f1d02177697be890fbdc40ed9266abd56a6179cb8de17c972491727754ca4ad3f404776a379c7d3e3ae4dec9306a6412061958e2dc1db52b773b5d52bb3217c42d69570c42bb22933096e07e47a56764d89181fbb1db6957cb3b35507377c4f291d5678f21f6fda8cf8e7d3dc8d0c4753df146bf470a20ce5667f2a6a52f9cbd70d75ed71369e0be1e3a344d9e39c3713c3c4596339a37e4cd35033577472b43eda29f6f507a91b2c4063d90d2214c7ffa6a681872a6eb99ad8e34801169a00ff2826082ecba23e07edc3c233c6dbf7097f2e427bb9e39534a4a1d752acff1cc196e53e152d29c6179eae60d7573e582e60ccbfb5dcf9c61b95cf6ef6695e9decdf52b5c50dde6cd9be9c6d9eae9c1fd8eb3322cd9ce62a046cce291a37d3b0b9698256f537a76eedcb5a9371d27cc5c510d8f9c9ceca59b637abd5e4f67b299dd61c9d7e3842c79593c6437bd4776d3e54dd7e647de1ea6d7fbc27dd3ed6c74ba24dcc70971c2d0c4a33b9aad8ee13452bddf10bf6bdfde1dfba9fbe9dbd138883cbd70890caea773f4b34f246aee8e4a49967b758e5212ee7b497aa6dbd95182fb9ecfdcb6a3c9d31df1744793a73bea8ee62587a4c106c2fd6e67ce784abad5ef90bc25b87f15781950878c0ebc337976787c80828486baa37944e57a2ec7d3e03482e3c1cdf261aa373d86dd996c9120b867b7c92ecb472dbd3e8636dc4b5ff978708f1f0ffbc39299a1c14e5a314a5a797734677a4552494d162794dd5187d4364ec2390bc21d2bbdcb57336b908f62c41bfd3c3130228e7ed7d2d3e3d1a9395bd2bdd0226a2fa15a194f7861792711356743b83fc50d8d8570974d193753c6c1595083fd96ef86c6770e913dce9cda1d7548730627ec77497386867d6f27d220e9cdde4bdeece96c412edeb442e4876cb80b43e2682c6f0746bcd13975f26c7553d5abc0f37447f186103573457863126ff43dbb09c51bfdce6e4136dbb1590fee6f3eb8af6540b8cf15cd191eb3d5dfb65ab9a20eb39bd1f42a12cd206a963d41b8df5199407448b73b7a55968e88735746ad383669c2049c75e0feeae4a4f610ce1812eee78984083b8a37fa4fa8b93bc23d77b07cee8e70a0294083fd764245f5cc9bbec970e8f6421036cfdbb02252a9192a0d78daec61ba75cd9cf236c5b05933338c4eaf6dc4d3e64af3967d35ad7d38442c6596124f6cb63cc6a1726ed1450fb3b5d26a6da4103b3a100ab11f8a7918f625414a6807d425995f4d770d08d5f46c16355833a3ec905806ed0745511ad4a4d4ef7a3adeabc1322a8e67ef55b51e541ccf93c8cbc9669459d439a62745cd93488611bf1a8ca13322c3e35723039206a7c974194ca6ae7b0ccfdfb3779ff574ba7fcfdeabfb0f9fa703c3a7ccf3566180c17a3adecbcbf15ef4190c36e2d2e6bd3c1dd3ed7aba9d186ca72383ed7890f07c87d455e992c8f05e4d65d8999af7d2c91d924ebb3c23ed4a7548accf773cedc2e1e22273a7689754a212451aba4843c797c7f8d22cdfbb293a22895d868a3a29dd949e896118754a92e0f92e68ce7438df7dd90c9a4bda15a7e0799a79f2cb01f5dc09f97c3b24ce5e7de64c23cdd67c0ccf1b0c9d8fccb30a68cecc2d57199e5594a671d8498404f3f9b9a382b94c23c11c864682790c5775197654aaefd8992c7d74faec2da5c1f9db45b74bdff7c52324266020f932baeaa6126fcc9b6c0734c5a85ddfbbcef3408d786ea0b27ad495f884234121766bb0410b8442ecb27a6036d8c56e73f3a3dde6e6c73bcbb7d2ca7142d671c27aa7d1d400d1663f242aea5cfd61f223c5e8eb4edf443a647716ddfe5a4ae7e8299d633e5cd9dc5284509c67153cff628560384f22248a73c75331abe3c1f32de5a85dd10b3cdf547ac25cf1b67d32c69b6bfd88a67c691105feae4e0fbe2734db9d08ce8efab421136b2cfa185e2255c88acc06bbb661cf30ecfbee51a076f7def5f79c3dfbfc6abe6f148b2a311d32b177f9d578c7ec67e3a74377cfb39ae75d43793662adcb3aecda746b9e622cbb44be24134c221b9b9bb8c50a725e21f69bfbf3c2bb585ba0499e607936a1a86f81c5e6b0c0c25fb02cbc85f757c3c23beab1d86885144dbcc22edad48f0255fb0b77e132946ace4f46ab90c1e60dcbf02e56998ef202c3e3570383a6fdc8dc381d7a390c8fe15f17434d66d341a82d9f3886e7d45ffef2c5707f70790c14a831dce50a22201cc3b377f4dbf1ddbce1efa9cb234059762257500132f55c818511b9c48e93208eb4ac0bdc78357f5089d0eedee3ea11e6aa67b6f389377c220dd9a7ea6615cccdaad5355d894bde6312cceaf2080c0c11cf4a6c235f9247f6c8245289cc913a30ab46f23c1b31914d8567d0ccbc57bbb46777e78a1a1bccdf5fdef23c773e1b71ca0e99d8e5382c6d30bfbcbf1c5c1ec3e58780ec661cecf2185cde49cfc56a2e2ed79e65998b8d588be199cdb426862b5f445e2cc530dcd0f8bb320787953a56d41bb78b6815b5e5c60665786e196c0ba75688c42ebcf0164ebf9a17ce62855861390bf68717aefd85d374f782cd5eb859e217bee9707ac1469c49ad859f6c46bdc3bc17ee133a0f596e97a45bf3051b710b9662161bc3f8b5c0828d782aa933c059ee50d4b34b876cd0957a8bfae9d4f8f5f8d14e50593eb0b39ce516f98aa8ac2dac93f53d862c8f61c9c610a3c1d605d63eab6a709ec5be06354f22a02160ede6791485887802ea23a276b15222ed62810dce67b703bade91eefbde7d9ff6cc7bcedef934d80169df41fb0fd981da956d59a6323d7b67b21d50833e5d92eed94d36e2eeabc9b80f878867feee0cba93c7b37307a8892e463fb5d8b8c0130c3ce90d6229013bedeab29b3b2598d53d1a1551c1da2b7b6765669011dac1dacd2e51bcf1532b153110a3eb926825a83f64ff9e81c42962520da4f4149124fbf72eb3de97602d4ef1ed803aa5b6f3be6b16489c027fdfed3aac8a8f88fa0d81ba2b96d5a3648313968e137e3931a95f3fd84ba84a12e88ed0183a3b11efec1c31c5049a02973e24213a0024a4042da6e8810936cf094a0851e939a20658a9c70808293d401ce188206dca0f911019313842055caa67ca112538c11da1138321e5189c2791ce1826a01293810ec8688c1b00153105151a20414a0ba22670a00a8c9a3d3b4e8c4002242745f8811150d48e28870926395018b1020d8917134460040ab012520f94ef0504239e004a124ab2a2095a422a022624451013462831913229a240caa4a041134610b1ed50a3262de800456232a50a2380c05c806000069527e82495b817144a7890b8182ca189922108a1148311514e4f131ab0a00733886a59e7a36949474b981c2dc1d3054f19f608e109b943240515425a46b9984ca87912d9c8104bc2f2954f2704758ef915bb6193c944c368348da6b44b66529948b34abb4e49ed4291d1ae548bcb8b919d233c487a9c589da669a7cd1dda75b4d3e6ce8c358351812ba4a08217fed878d7d19b3d4c35aac23b9b817858bb0a2dd81977c1d2f80d5be32fd81f87d52e63610e83a58fc1aa2e83057fb2dd517685a76c0a6fb1f72e5685bf581b6fd9140a9f39022cd80a2435c37a13a834ec1641148660efd32382bd47108537110a9fd8da9b6db087c2e76f630451b84dd4e0f46e47b1a1a9407190c25d01ec547712cd2b669459d4e09c44f38aaf03faca763e347bee7c90aad0ecdf8759560fec2b5fb936343ab0cbea218638ccd63c4e88134a1c3c68f2d2816737069250d75fcd298beccea2196512add49c09d439e631666368b299fae0e3a90a20ce8ed91fedcaae0cc2ac046a506650ae100c0301716c304b9f06c1274c90e02c7d849292045191440fa622099e22292576278a528461d8744195dfa5248a22a560098238cbb214b63db35d7765cdb2ec3ed1cfbe1bf0b8a58f4cd22e6e49bb4c975eb761dbddd17833d9c672a85d124b2853e8c90b86a44edd9022963aedca92471ae95a314fe24ee2cfca08d6b8eca9b142e39d8cb346c455f6d4b8b2a74149e3661cbcf2952b9d68f089bed73d4befee68ecbd5e0eb5abb1bc849294d333a61d19a55d518a2992b09c82a594af293c80915c9084b32403cb30cbdac5264a8480e5a5119b0c0323c0dbbd124a0fb5a066d94323985df66422187b04330dbbc4de239d681703be9aecfe68505ef2b44b5e2269d7b10c2272827d90b2c05d845d9e00677248ce8bbde5fef8a09ebabc049a337d1fa8a76491a66537cb309c1efdd4b1dba3e52ed7c60607a787cb53d7e607bbcde92ec76e0f1b96ab7c5236866dfba9fb68b9cb2de2f216978b13b6bc48caa5e531646197c583cb53f7e1f2d42df2d383e5aa1739dde53e544f3d758bb02ce0e5a99365692c96a5b95816f619c709559685dde538618b65656d59d9e759dec1c468318739ebab67e9c3dade5d7be76267b06c9cadec6619c4cabe3a4e086359d959c7093bdb83e5f39be581e5f39a959ff46950dec80749aa24a1e7f50a59d8638e13b2b0c31c278489c15aeef296bbb056aaf755cfd2072754a9827c583e64d897613f86457e7a8445602e0b7bea2f575d16767dbc3cf5976bf3c3e2f1f21e62f8727d64494a881182100cbd5e363a1dbefce695ba6ab6e45c82c40bb0c062cacb0d22ab5a2c4ee8e222df12e4934a3df57e86819e19a6ec8f58b4cd168b8744c2162744a16c9cad5914801ca13086323c5970b6e459ac04b1976a03d52c87767eb02677b2976adf1cfafac972a8087b29016b374ba3a112f6f8d5d8342839285dce0fe703de8e5949a4c58e28cb5ebad469d7cab32c9346599649230d4aeef1aba95cce4f77221e7ada86b573570ed9eddbad57e26ee54a1deffe38b572c8ca1db263974caaec691776a27645a9d3e04ee7c0ae9c3eb325ef108cda385bb3f5223284a44c0709a541f927fa997d42e761dfa667faf244da55ba916e65121389a52b755650255183b241f9a982aa5d960e1b1a94cf3a8a84a4886268e8c76cc96ff5c79c9157c496fc0db4c05272816511962f551fdc18bb7228de909f3f354b9fa120a02e7056491f9937f98eb27accf73c4e48af2c9243b3251f8f700403b37c74917923c6c2c26e1030f0dbb27c7491f9ef070f568f8903cd6cc9be9268b6b69051a8f4fa70bc9b89233102e874d1464b6c6768505e1d574666eac0b24fedcab48bd58f58fe180770763388bd6277567ae7ad94b6133a9944e38d0e8f4cc2fd802eda795b5d17238dae8b7582e1cfecba09a9bb2d3179626cc10550069489e1118fc29f49e5064406b7ca039188c64824bbc1f9eafa94c648b71a3a638c194823d1bd6c644e2403a7a40d28112a8b121dc08e6049d4bc610ed4bc618d28fc991608cfb7cd1a11eed32254201a119eb34d7209a4da7fe26626853fd446075323d4096426614a698d9408951ea1769cadd85286294e2005cb5729a534001dc1abcad084d25301151e522db0e1be382de5ab6b1b6005e586f30d9697c61b9b4fcd9bf744cd5b3c4dcb4b318d37aa096acb38354ddbb652a9c4498ee3b6af467e9b82260e954ae7382e7627bbaecb388eeb66096aaeb8eb6ae225ea9cf0477a29da0d2485e7f564ecd2d77d359ebcf7d5f4bdaf46be6d134e38e1449d4dd4ece1a89232ca95959588dd5a63fa6ed0566cc0f12b5f8d900c8b8c5dbf9a583d1696d309854ab5d01653c6c124a899e2d3e9d4a1bcd38742a1bc54eaab914f7d35f1d616193b959254707c2ade78e22622853ff12d5f8d6cf96a46505d5c5c5ebe9af8f232038e57e9c0f12a1919230c0ccc6ab5aa35ac78037bf154dfcb8ba752a954a998d8536383f2664fc656a9be9a0ae3c1c078de1337aaf0277ef5d5c8afbe9a783d950af73d162b2666c68c151a34620d59635b42044c84606522a939b544cddea66577f5adbc55b7e256abd56a55da56abd56ad5320513ce94359c744d71830dde06288fe8a9a2c677524ad9a69af3d397a77344bb1d19aa454456d4bcedf4e5bb96ddfd6da7b7231bcfc6d3a07cde7676369e76c5ced976da45af3dc6775f8da8af16a541f95945cd154b7a59b1bb39b287bbf16a43ed921a14ac156119d4c9581b933845738018ed08cb6717746039059612dbb423232aed8a3ed0323b7127bdcc36eea626630e14b7a4719ab6230d6e3b0dca9cfb9335a41d2caf19b54b5e9bd2ae572701e74d076b481a1296076b6f3d4d3b2b68404b5aa9b46d32cc2c265bce79a413d22f5c7ab4914b3b78c33ecc19563c761c56bc3dfe7ddf65451b7a79591127dc86bed265d07667955b83db395b676bbbc9c639f4dd79eb9d55debe492a2bb2e265c5d31edde97d78c7b08e153f4462d67c0ff9ef7d8959f14530160fdfe57b7c457ee2ed613af622dfe58bfcf4ed817541f874ee2b4733a72b83b6be2b37ce56bc59a5da64d09cf96c6ddfb65cb72a0d6ea59c06b7794baf06b7924ee7d872e9356764b8cdf8965ba767b6b6ff46abd3b02b9f615d1e6359ceb2f52b8b3a8c3dfdc5b69cb3a9c78f35699a868de10c1bc3181b43ae67fba6e3237bb6ec6e490d6e8f7743da90f06663d86129a8391ae1cd0455c342e82663f0c9a078633bd5c189cc999fbe2c5f794ebdcbe365cdcb4345bfdd874760ce70dfb05f56fccb71b6cb8a97c5c3cae963bc3d5cfe726dea5d6ec3f295e36c742a5183220dadd2a2de006fbf026f8f374b2678dbe29ce9a6274b10699078e3817ee53de857e4e9fbf6e0ee726db0c790fb2eefc374ec1659b9e9f216f9e9b172d38bc87fe791d3f214ea2796d71c7ace010d6e747bb5db59ecf6938d733bcaa66c9cdb5b6c528b8d61cac610656378b23164b131ac5c041adcded78706b74f236abe118b07f9ef3fe4f71f2bf43de4e9b5f9e9dbbc6f0f7aeedc668a21f78e5a6941569f1e27b461f565f1208fbd87b4f9e9abc2ae149aaded369737a441b3b519a97d213b24de21ef9dc58364f990c78e5d5edbe26c3d5eb5bdc6e3ed9e8d71b6aecc6cc5c6d1c6767f28b5e0749f36906174dac8eea4934e4ae333bd20767fb0521a7ba8c350a065d846b98de34a942b6d34c656b7fa98adb1d5f4062182e9e99d3713874e2ad4451b1933c2b31bc330ecd38812614699fc59b113d40c67d7a76679845b5ef92959520d7a0d62c7ee346ab085c87823dec08c8cd0451b7913c2d9667b6c76a33bf0be3d933e522b713273c6bbd9dd58b49b6b5565a1d499db16762cdba79da6813498b24965d9737e68cb2712359361b67a16b36749c47a963caa67d903f32c7d5c9e25d0cb5976fbcab21cc6a2aeb2a757cbd2ba95bb787fb1dfe347d3ac18c2d818aa6c0c5f6c0c5daa8d61c7830867cf9e63118f3913c3ace54e80de081c35b675e92cf731dfb7487f9e65b29458ecd67195c79c61692ffd98332cefee837b897bc715e1ce72595af6ce7eb6b22c33d260268d8837b2c78fa6a90eaafc57138495fa292083d06ba7518450256a963a4150df9e733acbe965a52e0feeb2e8bbe384a5cba297c5c3f6ee299d4843e34c9e0067720438931fc099dc0036419d5808c53912f58834d0674f409c9146c456f64c6ee007387b7679a54ebc911d2b41ddce72fa8e7e2c1ef53dc4b0ded251f79142cf0aac2823acd7a6fef4f8613cba6bf393baa8eedb23eec15d9bd365692c2c1e4adfeea3f4ed16f9e9d1af2f325fba2ccd473dcb2dd2af97a5dd1e629893b3f29cef39dd4bcf313dc77b0ef7ed31dc4ed33d1accb2976c76ce66ef7c70760f0867ff8270769310cebe628770f6c5b0b331e46c0ca5ce6c653f2e8f06b3ecd388ca23677eeb1b0fa7698dd2693a3aefdd71a567d0b3d17bdfb31da6491dac3d4722ac65b66e5139ed07272c599c304947264d16d418f6b77fb6b4b751ddaccc6c69ef2e2aabc7b7dbafd9d29e65b076cd86767f983d7fbad8ae186fa632d9a473c68373ce8b550cfb1667b46397d2379d94d2033428df376ff1f3468b438312cf190bd0a0bc7dec469abed807329a655886d1db00b1d481e5508412896294c79694892d49135bf259478d2deb45708b3482f274471492c1f40699c02bc66e9009608a83d8608a61ec06b1c194dee9614dabdc4667b1e71b4c40cd32323a6ca0e9ae3974ce1a914010039c55f1065deca6a9067f2c205188603fcf701870cce0a69da06e1687d9eaaf106582449939f3630269d77dcd16100fcf0ba4c1be03906ac4394e399e1467f9ca40ddb094d9644ecfd4b0df5f8df6630244fa38080d7d8603b0d479591986e7e9737eb4ae4acdf138f06857c45d8990bc8098b971cc6e0ed9bf1b6ca86e5073c5cdda621a9471e847370e9d3732ea4ed65a083a1c1aeccf60ab41c205b11571bc8db701b62bde78c137d80727206bd0328c6e5a86514a8df014294793d226088997df5e38662f1ced10896f90381e20ca8b038fced1d7806abeb682ea8076e588d4a3676a906822b622eee370801a245210a5c8f704640dd9fb42e40c76fa1c992083c02d5bf259da88e3a2105bfd1664a80070c18f371a05b54ec06b82107a809e9147dd8aefe3d0ae7e4d49c2f1394ac971a8e71ca313e2bd30f668234fa0c65dac947b96984d61f7599ebe93d6ca6bf80739e59577469ceb9c9161eb4889048c7135bb3f524aeccaa4197bc4cf9694728baa3d913d7e3ffad583fbf7efda7897bbac1e5b77e591ec4e7e3ee26c698f5f0f32dc3e5bdc359cf0a5f7d783bb766db47337ce56964638cb233c2f91be1e64983d7e3cc870bbaad9a207678b5eb3ac1e311e27ec92a4109ecfad8367105986349a33b2e868ce48a2d9429a3372a84a0dcc8a9fe0c1431abffb7d591bc6c15d864c6a9d12e0a4243a81e4cdc499b43445f7181b3255e3ad01e2c9292552986b96c131aae6718cdd4aea256d0d1a3362582b18d58b4b4b0a7562a92ba6cfebb8d2a665189d2de38d7e62c6beb127135db491a59013356f581a01e3a828bcc99c280a3b0ee1e08b1fe88437a59c1e56766da214af293be10d4684574873c003c413de644890423a0396c7993259932f98f0843637357a42ec37db0f7842fa2c7be9da4429449081a4b0f4ecb27c64f79e5d1bb9f30224f88436d96fb0318e427aefdac41caca068282c5d9becdeac108537d8173c21bd3894d2538ac4054873624d54f9194495aa96592035218a4393880546548818003184c92452d0039451b10514495a0e52f083b451f103c45149074d14715644d10123313c8004466ed20c4071e4514c054b2489114507b321083008dab2e9d568efa4cd356f586a975f8d7667f76987503182000a6de86fa40eb6000a7fb8e3849d8d4256e6b5bbec4e67908983c46ddb485033109984b94de28873e6450c2e5e1193dbb5b150a6cc206a6cb073bca678b193ea1c523e110411445163f9a0c74eaf8df4620326380a6f568842aa833194f884372f4132581a418a902cd16b83726268881e3b4eb8cd1637430e50d084507883c1a087278c9d039331d3b01154210feba971b65e9e308425ec843313a2090e08853731ca0c6410ea70a1cdf68a6238514528ec308a69f1c6164478be81e64c8ecfb87dd6edc3e4b82c6c5beb5e20cff68a1a09a19fcdc732d86c5245ac7aa7b2b2ae76788f79fc56ab3b04c3defbbbc17bcc55d1236de94e0ff52ee5f1a266ba83a7d7453d3dd32423252b96e73d91e35ccdf959dd1f3e748e4f286a0526fe8175d459af573dd5d2b275abe5299b2b6e41a18ef2ec4baae5a64e335f605aceea50acd376a1ce7a4c8c75f9c93e41e3a81bbbc5627d46cab25a7008225bce7afc5a725c06e4b03164b1ee0f251589855b6febdecbe3c6a3d782b9cbcd14bb3c86194ed30c88a169aee67aef393fab13f190c6f7ec3de652237a34a5de7ba646b8fe07efd2a34b8dea147a44bf9a182ca6aeec0f1fb8a8a853ccfbab69545f788e45db940186c7cca2ea1df368d7c4a1f32c0f2254ef390e1d80c76a6e514d377df50375fa71d4fde9bee5b6b4dc0e6a2020d4d573afe60faa91ea71cee8467a79eae60dbf5cdebca12eebe67aba59855fde72b3ea74a951bc317f92128b7cf0821e4c2de8947bd439e6fb8b5954255ebda341accf37ceac7b37b73ce53de627fb83f798779ecd129fde492fc69e3ebf1daba31ebf1c5647b5dc218d4f377bb780c4a7a71e63593f5956c7a271aaa467685c96f71832a05bf3a9cbf24eb117453364e0013cc348f54e7aacd4a5b3a8365e7df2a0ae9e29109d9ff7469ae1b37ebec968970caf76c590a31369f04ecf8d713cc61a2891c4318fe3d8bb582991aca181248ef99969a5e1fdd42c2956cb291929d6ddd19895a247d80bd3c18e60482812ab2505d4ae4c7bb0126a3483a5532a15245a0548d610230e994f99e7c6b981bc4b93e28df91d9c7c4059063438bd138d9bf31313e3dd4e8ab18da483ba8ad99c2da3d4d58d0dba9ca65dec8dbf582152c666181c36c3e0176c6e32f0fc0c6a34a4b1f71b3759160d2e40eb348dc3e4d165d4472124afa991a7ba798b0c68593aa55b5ecbc6f0c68d4bdb8bbaba3efc6870e6a0c6bbd082a50dbab05640a1563ee0d36af5e9c57831313137af8eba8db45aad9efaca76528313b55a61852885507cba403300c2636cf601c7789ee7ad56312afc6457b867538fb1292babb76385afdefdddb0c2577785155e1393ea2a0dce9497c23b1b7cf25ca867efa9db489d673bc97b5759c10c69dcd29eeda496066a57cbe7aa93da15f1aa57431ab79ca61f01a31d9ce38f93c73add1d8d4f3f1870a473a4673a2007b42b5e01c508cf24ba73059426e02c5f57d80049ac82e74f2b6f47cb57384d671cbc72b2832a38e6a877edad602356c14a0cfad0ae156e9678854f1acf5beb31ceb0f0acc2ab15aec259b031b65ad63b0d1b63abc33cd032a04115ec0f1cd4159e63d10d0c6870e621185edde5fded10f3d53d7bba99e2f8ed48ddfb0a56e21f0ce8993a572aac54506185bacb5538fd6a54b8b2ca17eee2c97a37537c3a7d65b30d5e5d7e35ab94cdab3ba471cb65ed90f8e53167e5d0f298b73ce6a77730f6f4ae4b7d65533628d43ddd9bdf0e31479d7e3bc43c75330e5e1d65e70deaea31f74e1fd238260675330e465154ea9ecd97b4b7e9d18aa532bc7a5661ef71f51c833def343308111c73fa4ac31907c7a06c100dc79caeacdec9c3bc9863df0d3131a7f81473a3f9eca85ddd332a78e60c29ab82679684674606d65e393ada4ebf70c429dc9f1c8bb08dfb73a44c93a891370466c5d8cdc29cc5badcda98b758ef28d8d3afbd21e2d45fec0d11a3eebb58578facc7af66759a46c1663e18195815168b19ad584c4a4b8ff57a78708e459502cdd67c0335385b4903cd2c6a6e20395f9ee7bd913c6fc6b12aed8ab924ca72480ac9a0974c8d6080b0a423784603c100dd9b55f8e626c2f3e62ec2f3dedc4778566957e3d93826e360ef2b54cc59a8bba331ea2719f18c4c028852392aa247d80b1b5ab2049c311dec0845429d625a8ead8e7d352d97127d35ab4ba3c058e96265ca4a2ab24a8333c622c5066bccafc6c3de29d09ca1711ab462d1b80d746383a66fe59ec77ade5e9e6bcbf3339865b20ebc7a8c39ccea1d8c6551bd8bb154652910a53408c6d6af6620c1338cf08cc776ad3e23e60d14633b28e64a6e23207e853467bc7b670161ef2f8f73c6bbcbe39cf1def23867bca71ebda3bc9fce8333c5de0a0609f64c57d90dbf58a40ce2dc485906e746ca3a706e240ab462bd9bde1d0444833e5a64833aa1d44c89b091a5532c3da254344b9168159ad420194f2a86e3500c46803335d288b86679b2084834cd054ecabb6d923b66398ec3bc1917ba25d335d2cd53c964169c4eaaf60c9ea64dcf369fa5c1304fda40bf9a8eb3254bf3d56c57c715351f37cdcc8e35ed0289c132931288c13668bc0d55cad364d0455795977ba62f515cc2b67e296ef16a364baf5d598c5708c54326ee6662be98f0a276180bc3b2eeee96c1dddd54706399946957ae2d756c36f4dcac8e4e7a9946d3c74edb3564d2581d6154f9ac8346103b8845102bdd8576956eb6c1197641fae540718683311d36d0744bcad2019b38bb2e744c832dffc2bae8a20de9357d7f3532b6a9dfc5c8fe2695aa78439a78fce84145f5c101ed1222b10a4b49238d8490032c233f23ce94a22ad220b13c4c74d11ec4c0892ab0f4e28c8c4b07464b738606e59ca9bac939279db7e9e90c209ef49a26433fe9dce6b66d57a6411d33d01a33803a1a9432584a1ded92320d4a6a6a99a9a35d1169eb0f0853a63c9a65d9bf59dae8cd40c039c5636bfea59b55f8be7f6c78db6ef601fb7238a6a7991910709300b835f58010d65e390d6af11d0ca6413862fa95d374ad2b916e5f900df5ee069f386a2ba5f7f45aad6fee849a5eb5d367c6575724ee1ae74c1b71b7063e383e99c1148c03c727345802aec10db000e8b57a7a7f355fcde9769222db5188725035eddcb79ea971e5e5e59c7da15747fac821620061e93a32dc4e6b5228d44cd25646479068848760f8648339971b4e3737f7b634363f3dfaf4dad0f7e5315bda6d841c9bb89f6c504d374814c2df23c5dc353de22f13c1f50998bb8b0d223177bbf65233c2b631ecdaeb53feb894959893a8171e8261ee4e20161cd42440dd8a559db3a7c7ca49ef05b3a8b8c7d8ae58b3c2992ebf1af9d548ee5dacf5d1745bc90cd59471f089c548e69decea9f65396701d65797df0e2ce7ee0fdc591e7fe0fedd957f36dbe0cf02a80f49dd74e9b703cb4d2c9f9cc5c1dfea36480dfc03eb11a36c901a98f515fb5d8957efaf06e627db3ded84657d319dd464d8d334f7ef8482e9f574d35fcebd9cfb7eeabc58bbafa6c6bbaf66c69d93a77bf277ce74eee6ef520007a35edf71a8575beff2ef1e0addb783e9b5568bbac94e173b794e3b9c8e3a87e2587250f3d4c1daf3e4f95cde9dbe1a179369eab4abc6b54f23ed9a71ed73e774d3a9c6396eab81fa6a6a5c59bf1a9fe99b71d377c38c19d766445c8362ce461cb93b5fde7d283c31af7a3967facbbbd44f379f2e6f363d9f2e0570f08c7f48f0ca4ddf593a48ac5d62edb2fe1a77a9a9afd7644fa8a77efafc7658b9e966ee2bef6f87efa89bb967d3bfd3cc93cd363f983ea37ec6cda65a673cd2885f0d8dd37487028f3e0adab7848c19f4e02896e0f864498e0ac72733b802afdcf4e9a37d26d13e83e692120a05145057880ff9be0f7a296f1179fa2236f2fed838ea287cc5460abf4fe12944dca16ca06c1c65038582f6d5dc771de783fea7a250f5a8d73a63c6abcb517835994ed395e3bcf89d6ec6c13dc4b04d36db60d363bb7e78a21fb1e9d5d4759d17bf1b566e9678e5c7c41df5d8026099ae101ff494de22f4312c6243ef8fe9fd18a2cef2edf09d7b67b228fc3e7e35f7a61a47e1261dea51b83facbcd2ccb6315cb111a36cb6c1d93e75cec68f4380cb4d347d6d27591d6abcde8c836bbcf4d59cec234edda6ac67bdd365fdea50e32eaf71e7abf1e9b993668e7838ffbd7e35dfc99e9cd4a7deb17c35a9f8d59cfe7d0dd4b5fbec8cbb5889e5877afc7238dd8c834fafff62f73cfb76589971ce5200079f1e3f04d49f7efa6a665c59b919dcc7d1f8f7dd4083c669dc2c31ea9df468d88867ec80fae9e67a7b4983da5143b3a53d652976919f8fa2d9d24ed3f2db412b83a8416dc5a2839adb48680ad111109576e54682b56bb97b709576e55e8235a22e9a3341f487e68c50bba2e9dc6db11907c73c7e3cc4b087343ebd814ef787d3b9db410d6a3b70ff4c37dd4c011cfcdd1cf3d36d24edd34bda15735bae9d6602f5cc99e9137b4ca676a2def47c7ac7693fd9e9d3a076ef08f53ba7754f83daab1dd2f8e3bce93393e088237e128511ccfd87ef1177262fce191f664b3b61514b3bb3a569ef28a55f4d3dfd6a56aeb2117799b73a3da9119f3e934c9f769dae9d4edb7703f720b30cfad570f787efdcb50f01df6d9f9b1b4983da5d1e2bc79de52cff9e1b88e33e7b72525337bdfbbe1a53fc6a60beb344a972e555fbee7d35df95959e6ce34e7a270be4bbe95dfc503f590b487cfa67817cff8eb23a4c20a6b382487cbac49fc427cbfa27bb4dac0b81d860ea342d31cc235eadaeac302b1818161696ef11ab5457d64ff57d2f2f2f97a583c42e97d8e566895bee0f2ce7de48dac5820096d7cfaf867b4cdd7e35c852eb5756bef2d5d4af7c352bf9bbdca90da233c5a79b6ca60278f5e9cd899dc374221ed29f4ebf1cf277eedc69a6c956fac3d24162d32536fd64f30fa8366a176aca77edf48851ffbe1ad495f5843afdc321e2d3ddbe1bbe0799655c960e983bcb6d9d06b5de6950fb8aed230d36cf0ed6389628552635a8fdbb12e9a84110d49e7b475669507bbfb0f67e754ea9b4b94cf7890d09a94a37a52c38a8591a61edd2a85ddcb5cb29da630b803b6d0178e7beb500741e76e7eeb500ba73efbe1a2e7e35427ac8cf6b63232720af901e622875664bd3bc6b8f616b9ef6aed3eed91eed40b3a57d8b616b3f61a1bd9bd32bd9ec9bc52e3f1e622885664b3bf63e7d7f3c7224d16c69a796c5b56571a7cfb2cbe291bd871866f72143ec32c4ee5d16f7cbe2e87dc8a97df6e5616e1a47e610a38b9f32dac6524a29a594524a69c3ca28656cf95e42176d74dbd46143048614008c526444456b09bab0b577699ff0ae0bdd9a9759f6016b9769972ce5dae96869652c38842a9fc11b5c6870ea9833f3ef7460eee67a1d786ea75f8dbccfc0766d9f7721e26e7e35db1d82e1defab274c82c8061eddab8f46f17c5a87c953aa3c1124c083d41d26e0c76777777776b19b5d1387e32251d20788f334e946dc26ecf96474aa28b61a41d4b5e9b7e0c435e3e8671da0e03cbc7df5085123c5528b1537a61f9ee678b097fb07ed75d2c668fdb353b83b4296768b730ac850189699b43c4c31fec661c8c35d613066de405ced26808d39e489df301ea1cf2138a9a5d7be9ddbbcc72efbaad44f482aa437633766dc8c45ceaca24dd9229ed663e1856ba591a0df5ed2e96a4c1beaf327096464398500870c7a865324983d99540d247faf84ca0899d7659cce43465989671a52edb2cc55dcfd88d3bbac9d8da3aba31e007111b0c8b4454e02c85b02b6950be481a0d659f4a6050b6b612a8831a94b16e5b0b615104ee408cbdb465dfdec9a14d3b4d6f9b4ab541e92e90a71ea8a44af4f6d128271953442292000004a314003030180e894503f27822a8ca3e14800c91b658724c17864110831042c6184008000000000022300243c609802a598d551b641ee87a7f52e0bd36e77bfb45d92b65c49905768bf85e5f39779001ca2140e2cb1bb5070624d4ee7501a7d4e2f8a4c68815c79ad693ab1194d07c8ca6d467341a5c0f6c0520c7be240a23bebcef2c54790985185c79a8604012e881ba001a5d2fbc7a8b05f96c4cca84313587b2c809cce1ae1f8c7fa504666a7e3717cf6a4ddb49ca40cc427f897503a67905e84ddde7e2ba29231f565b2db92ba78c7837e4e1a2277cf66a426c72d13f2fce19f81af16be060a0dac87224a82a431989d89b24dc9e57ed50a1959ff11fd01dfb0fdbd17c455221008983c5563bef0c03fc9860d2cf545fe75d235df4a46554748ce15793c73aff7aa761d4111d0fcfcfe76e2f1459e98454a55bca1b2c6975512c7f8f7765a70232d20949e71388dea9a397510724c3491ddaf78236328edc3ff8177cf981d49245420c459270c41676010b340cb662074614be096fb6038c4ce1093d363180635f54d996548237d0c76d04435bfae82b7a15bac748867d02d4f4734037815bbaf615236c6e7695dae9a88dd707820781634da23fa1369846e4e47bb93d5588f44601e8a34c7bc8495605d4d5bdb0975e26c33f17a9cd25fa5a906369b1217e844110680c3a360f5e4617e3af35e84be91fe47a0d8df55039d9965974c1dd00aa8b4d8d4e1554e582265a3387d81675da5f5355c825ed92ebcc932dbec66c8607c9acbd329a625c930055dd95dc1928192df5dd4e340b6ea5d2c2f194b8f3d186db41222314c559eed75bb6b9a034d38fe9efd81352db726d8b33a6711474b63f882c552ed6e648365297dc29a57b1990a8072d0120ff38e713e776fb3b0ca57b97fe15464c26e3c8a00eaadffbf011c4c4448ebc368ed5fe432632246c4cbc0ab434a1a0810bba50978554c5d1e52305d4c627ff4d2e023d0b7baaeba36a84deed17d2e661fab287b4653dc3ffcea30615038722cb0771dd5b66c8768c7ee5ee1b478fb072e615faf0713dfa4d419b63e848f54abc2ea87f5a8e147a44f8eabea65918777a7958ff06282b90131a8ca90e128b3d2b54c203db9abc56b324a2e5b7b1c55c44253c0f7eda75a0f8a074be9405866eef2f781d8b602d1fa50381d3153320e71d2bc048e1f2aaec448ed4a71f8537627327d13b2f0e3ac6585a857fe7f69b438eecf7e12ec25fa002db041fcc23acf982e8c895d87bc8c20c6ca7c514b89047814092b84430d2a9659b0d940719cb953e3f75cc15be8efa209b11405c4d10bc79e0216eefdb081f76a1b7b83b1edfd4e1d055fb39cd650a4d8631fa3076ff85df4c9a1644833cc74611d2188fd42f303696248281a76241318b329f4d0384ab679fb93363786b997dea90b6e3cf2682913fc6caff5124727df9dab64e0b510958c5ffda6c230a339811d4808a60792a220630539d42e31260694ee932ea2fa97b5762c31494161b12000fe9e6c22a7296f88e5eb086e4f3694f48510d579767a39840e69137aa64e780782be44d53287340d9992aba4ffa8e7ef2b1930f1abce9e210763e21df2ac44a2755f203e1c553c8ba100109aa2b16d34812f45901f0a7ebbc8f7cbbcb04a1e0ac2790a0a598d823049427f87472705207ed4554aa583a1413011d654ac23d09c8699dd1e7cd13220dacb5e1c9cfd5d6f7c4240eae0320422f16b132d499c63585551f801982479d6fac6e29cbde4a1366536ac30e53bdfcb5d46e528e5f8fb7c28ea79f913252f72ca285b2f8f1f1b34c473010a5a0babacbbcdd0346abb919029d5be7b8e28cbd40f3e12ee5c4ae1c4c377f100873e198cf7cc1dfc4c4a464f29d23b22ae43a5ee425c6eb05f08e8326040a711df42a2ba040378d314110102149644238199998204337dbea94977cc9f5471f4338db055d446599ac1462edea31133e4daa21614e524d774316f7a98d689dabf188b5c7422be788cc632749620bca4550d06acda0687c4cda4c4877ec41744c70964ffb070ab0b8851f68a22fceb9eda5d34fa80d7d69cd73db9ff8b303d080d4bb74a578085d3662eaa0e3c6b89728dc05e87f2dc101c6c28c829910aa37e200f0efeb9d3f7b9deff1143eafdc9929ea628a8406e8e649f08c7f9df7339450cacb39f5e185b728f66e5a28fd7dfca48190dc6ffd72613b19a8a377ca0f6c7ec6cbb200baa2c5794a1a4dd3301a9a4d14287a37ad436bd810fbe2f4f6262da82ebf5424d3bff499f462c96881cac0b86c273a807021a2abe5891e4335fc6652553d2617005d6185f1fe375a1671b4ff64813f55d503436b321291aff32f15fe937bcdce392058d32b1777ec78c4327e904aa0cb0420ff3ea5b064d2bc4624d0b24abb0f9378ebd07f2a23527b83b83121a77e5a65448a5b5eba0a8d2c683f0ac980558be4bdc9741f8ec22eea6328c4eed05f420c1269b64afa8777e262ec95471df7e20aed1538455efbb06c86127ca8254a4ad51f0d7968a8ac3500e247e8f9d4d153e35a4fc459c37b046e08c2c705d096471e6abf889bf4fe8b20bd19c07b1abdafd629a4457d5e2250a4508efbb10e9ae27cabe029f2ae6c62a3fadf07dcea680e7ea929fec0931f2c944fb9ce6e9174637ee2fde76d1236b98477724f2f5c62ea6c3d7b485c8e28f7339f2535f31b747f9b1238c86a231f09ef92bc996da578d45d715fe249e8db27d483273a9d966a28f2e09cf6c0f189219a8a0495489892f8ee59828986f57e163474a206c1fcfcfd01d64165f14a796603cb5f5ce4b4348f68881920471c094745e852064f903da5601f63e43b692dc18aa15edb2980e4f97f4bfb8ea7952e5286d8f89af566bd8cb76a619b9def22057b205833c2edc8e6efe9a27856fd5e5aa27069368af843a2004ae588b52f3f37c146cd8d69a7fbbec62ddb78db9976c3f426838fb0a4f32dfed981c4f3b1bf2a18880e1804496993d37b254c7bd08f36c545079fd5c319d27a24e3fdeac3983829597f79fb2a299fd2211dc6f87bdbcd977e1cec46916a6745e5e6c37df0d2c114440f314736cc2a32edf220fb6d11752d5c91eb5eabefdae43a4409d3fcb457ac83f32f0beb210ced6621b9e9eaadb4d8792a856ad4c265484d19261b81f191e5b41591a023c5db4502999625d401459c1922c4648c4eb353116ae20b3253d8be20079d83e0896536273f44896daf5f2f35bd8e6d9c9d5add27a40f3c53088073a4d2687d7d8b308a990bf11e4acac0a18c4aa2e8ee8621500be425dd97c0630493666fa37efcfb35742ad46ce315eecaff7394bf639f779cf6dfa24c2b834b696ba820a641cb5b3dcda1061bff76289b99ef91f0da357436196ffc8be704780c33067add9be6d14db08445141d2e461ba157089411ec765e77571a48df33d213ea15f6ebdde2e4851ce246253ccde41fcc523105ff0698c358decc302623d0705f3a2e4260c52629a73d126a49146cb3a8620aa8146137c489ab966c47293cad29b24e593faa29822d03819b894b3a129cd2eddf13599e82bdcfbd473544df8108043df7afe5d271d75f6c3c222b178036d440dc25e5ba302d2e48891ec05da09a9a74a4ec72591778ad2918c65db95dd9813bd9647fe9d1afc2a7c159d0d8885846896ca7fd8211b00e4756da166648938fbb2cdca986ccd84cd70e64fd2f7c09cdbafdd38df2fbaa50e51cb1b2f9fcd979e03827417bf1fe4e00cadb1a0d6a5e30c92b43f1751a1284866e05996de3e8ed95adc1309d81f4662dd2bd38cd3be445a6a5503e6d58197dff004069ae0d157ac70e751f2aa4c480086698cfe0822f6129b6e2f7739f860d6e007d19865abd029224f24ea6091f3675c266afe0d70c7df6bcec51c79f5a59c1410be3f11e11204b500d1eb6640dd79d568455ab0e8933b6f43b1b323dd512d59efaf783a64e32424ae7dab98024c5da5c8b21e7650492e181ed15404fc0ba18b5929803035174ad2abaed665fcedef9b395a34debf957f695a58217b403e1158a0c3b40f0479adb5f5adfaeccfbd18acd09f05babc2ae1fb9c9751948a0fa302fd26142fcd579829fdf516dc5d025246e95f894ed3c81410731d748b3cb95bc3696431c4892efd93093bde0015d982ca72a16681ae471f24bb0130df03eb96c1b8e1d97b023aee3736ceac198f888b0bfa2957cb295322c5f171866a96e643cb0ccb5f9de251b763335a4e1eda74ebb75f5f30d42032763840c8942cf16cda3257313179d3dca65d4f92054f8b6d0f2eb888252edbbf2584e5b623945406eda10dce7e3c64d213dbd1f526307baf8113247b3b7d3902d3cdeddc6f9fa6947d1327e075f5dfbdb62eeead9d996d565d0bf75ee6057af0c233809c9bea546cb4c0215ef0cd659f16e771eccf9661d80e4084dcc4bd0d1b35ffb84714f895ff187f25e761fdacbb8fa0515cc1b82c7dd6ba87d17aca8edc4920a0dece342c2a329d3d726c300795794bd28b70a22988c00b0b431b47461dec1f9079a71985c97a285a4aea7a52eedb54d1965653c4c07d428327cc301f8ab63987747786b8934dcb517bd88db1ce7cba385ec65500d89ec6b4885eca8c3222e7e7ee8e3df6f165a67f6b6f644f365ed8e15cc31d3bfcbb3cad2f7506b48471b5445350780cbaa6227b7662af83e067d80c1b0a4e6e46e3ac74d64d4ee657ac02940007bf50f1c98faaaf1620cea6ac8a42827aed2b767cdf7b2d3b357b364f615c0aed12286d2a98a9fa492d3e6418e52fef66568035ca0c8a6f8de76d458d545f1e96417594f1171fa54b17f34fbffefb6d0427d7fe7acaee4fd30c53787239e7c1ca8ee2ed191dab15aba368bd9b1f6499af85a4666081a67bceaf8b2827c0e36b52ad897ed9d4ceea5f4698bea0e0548aca1bf81ed3b32d8f40dbac94210e6d33045dfe396b93682ca7c97bead5e46d92f55681d5b73ae22d4165b94506511107211ab028c7dd0c286397cccbd5f3341d40f480424be9754bb0122708c3b2d7d037647406534899a2f30139ceec529b11e0d2efdd0e168f9ac83276ed042f8bab908d4fcc9d33535b14ab4524448ba6f27bc6bfe2cc34b05edad9fc07090e709cf21d1c650edf43cac8119d6702a8af351fb444934ccf8172c641994cc7bff490920e89e29b41696fa4413832a0123763e4b462e8ffcee25a1d90b15baef47d333aefbcdcaca502e77d7db91595ca25c49dbc645afce141bb20d0f15942714b0649f9c876de52039e248384a65acfd44081a82c7129a1102cfa47f3254a0a51b3486826382f6b5c12f7a96cb3b40c917fb77c9da5eb734ac0a862bc914b6e558055ce9d947b66d04867e1168f741b02380315c08e54d637e0f3b01e8071704db49b9e751dbc52c47452b9d96c9ba806333be840af94b550d5e51eaef28176b46b1da730f8e770c134b0428fa5a292db5e857f6a5dd26f76b596c824671f29e14582532e5e8b8f4712403f545f8e1b8728f506ca9aaa4f938b475b4e613824fd29fdf8f53ee8a687c30356951aa8251c43bf217c8b0188556eff35553ae4a13d56921dd037cc9f5c02a33d11442bf22c463d99d98e10ad45857b58198981341289643f8da0cf3c3e42dea376929f81c33c179464ffe69409a6e819410f53aadd778a80bcf197d6ec58db20d36c115a06c138557f52a0f75cfdc13f4dcf4e615340ec3063b0a5ea13eb3b45135ed4c92e475a7e2cc6eeca5904b08aa9bcaddb2e34523dfe8b0d3ed500bb0a984ad22c0dcaa0099a3ef21c61ea3d588f0c42c2354490630d963b8603e03e975996554f1fe71963f2789094a0e189f13f80ef488eb3c46aa232da87501a2300753511a5b15c1211fc1430f317be8f5b2c5e626895bffc4f012e15cd4932c3e4a93e5d5a918915018b28680857050fb443c51ba28ab80f81e84d4bf42a336ea21a0453134fbafafd21660cc197999582b058bc90326931d5baa9c3644ebcf99fcebd94515bd9f24da3e9ec095f54c7a4f9d5834ca789235031dc393b6927da06575921d7dc43a8173ab78d5fc3ecbcb1dcabb10e93821c86c2413fcadafa8e9016cd750299a15590deeab84fd75073cc219a4cfd7eb44a703cdfa5dc7561c06009cc3ea2ff34923a66324602bb25524ab6fabcf2438566292dbe20da7700e87884722adca5c1eaa23ecc7b485c2434c59e9dc0abd3e4de5163884595ee73a455ea1c52d33edd848552e11ef2190d7ae6bf59cf82aa78e97e83f8dd26bfda65f876a24ce5cbbd150c6c4681c3f34bcf33217489818e085aee8aeb2f755e46e5e2fc0efa37205ae0dee1a3f3059100093fff6d26070ab4c0ff45239b9c6774c5a79630bf04fb60f39d912c14cb3fc77abded3f91e9b281df0daca8a6a50e733762ac9ddf05ec2fc738f79bbcafd7afd2f637a8dfd3e060cc361c8292499a5057c368bec8a666be49505e463206f0927d671e8c7d9efae3b2dfdbd344915acfde4efa107d90ab12eabe7fa14ea2d22eb900ecb5d50e24052c6d22fc5fd69daca2ed39fdd9475a9b287d5f655c6efa5600a7a2c3d7212a4527bd73da440efdc3e2b4f0b8129880356c843317ca76c460640272103ec15fdc1d3180e340c20c21a8d65ba158816175dea2d696f3a3911ae91c72bbffe501c036e8ab17747b3127b08797734cd28e28f420d37cd5f55993d95cb3a6e37521eb20e76997bc57399cbd2f0d3a4fcbf991a9424512fc3735153a179ce9f773ba74fc2f12bf18987089e3be22aa04edece367ea2db34853d58fb9821eb3d4c879161002de461744e6a5ac70d1fdccbed48557b61699db6a729ef944e5080e737da0e93b0cb6d9cc0a419a1e71d5f7bddd4b5363ba2103081fa3a94938e1420c47d4d6c59440640028dc13c59b9b451a70eb35c410da6e6d0bea900700173f2799922ee372739076f54da58336727b06dd856cb4aadace3e45293c577743149cbe08f6c4f5338fd5e98d78e922962c3cf340e4d70e305869e9bb3eb5b180db5581bcf3ad561c8d9486927bace386d621bfd8039dc2f70b69f8279e4c997a7fc3c8441e4dc953cbc63eaf515031db87036ee675c01486df1879451e3904cad2cb5248bd549d8520e9601e28dc05e77b58ee963bc5a6e448fe079db1e16cc5cc97bd642f05fd7a26bce8c7b0bb51fe021e466151ceb99bf7190e306332684ea3bb11ac197f9964e09fe9761b2139fd13ede62181a6e01283ce9b68357aeca3c441bf44e81b115abd712f1e1cb4665ad84297caf165f2e1b2c5ee79810eed5f98c51024a605ecc2033d99f44b2a135e7f82a6faf5f14dc3bf6945bac529335af43c3b4462efda7dc680124e9ed4506ea7cbe81ddfb13d9f122041411e87126caec48152bcc1d007b70735a35f5b652330fdd35c2047ac432839e526372fdbe314527f5b642e2540f32c933edaca8e6d052253fd539f54379e9be691cb6846455bedd270dc095829b79492924b9ed49de6974a653177bde0a086fdf32e13509bfc76fef02e81dac59534508b2e80349c345dac0bc5e9ecb04ce7b65b6c883068db554b0ec6a58b672801f2462ac6ce05aaa74e668fa4ea395ac1409bd06345b5d24cd692d4364035055f449816ecd2a95e73f30a31c8ff33a857b5beb490e45f63f00f141c60ae82648f3567322e56c2fd8110e746f203cd6946d62a72b6beb4c60e591899ee41d97d38d02552d2c2e6ffb9ce00f1a3388be49ca70a2ccace9e524cb1e7ab56790dc0374159fa04bdbaa8a8fb2c1221523eb2759e18dcfcda28f0f86a832d4b0a04ebe194f819bc829950d0dc2a257304387cefc143cb1163c44a943ec3d8f0a1123841c061ce57b603a88a0364d02ac499e409c08890802c4c3c3723fdb20f7ec1f622069e7e96e979e0d12a1eff9c7ed396def37daf7e37ec907354dc00e820b776e7e65d1d1e561dc856f8e94fa52454ea001d2d427e3f62854dc3da1f3f0ae17200ce242c58fdbf8c7877f6edf72b26da44aea71a8a6eec5461679b1a1a2d8a220ea48819e9b0db43e98b6fdcb07f61a840705729896788183f50979d1a90abad35e329030ad28564e221748cdc5cb1c837fb88c22351258b1047c2571db2234a2f4e73111682bc4cb49dc4d082acfa952b5cca7731c6de51a3c4b40930cfe8dc7f4f67b43093d70f4a5b38e252bbdab882a14cf02f9c700def4927a6687c7f8dacd847bb067f79160ffcf05774d16905f531a28cec3354cac3dd5dd50e5daf6559dca9ff2b5245272dfebac1595a0dc051c56e372d805eaea880759c7b72a9791fb64c8584a81807f16fa6c043f4b69dfb1e087390720e3ef4ffec71483329d7c20e5458db8484ed9b34b1438192d91eb5e6c5f44df80433bfab089da45dd17a0f074c6157df10d214dce09c9b74ef1e8e782b4689ae6e8563def626d2a8bc5a570b628a0ed9d5b2b735840277de8f200cd42fd1f26a1cba47dcc638f40849247e1db704576a387b5c52bb6396d0ecbe01ff85b2d0804dc6eda844c7a69a6a9cc616c8712aa139bef4906e05b26aba8532c254baf6b2eee1d2a9618fde7190bce7389c1e8dba5a9859659e601869b1d4eb3c53aecbcd5e096a34ed97fb04893c048da9ba2f82d7662465a3cb8757c48268cd432e0a934856403146a92c1c7a0c9c0187eb66dce0b13444a29a28f6a3eea51ae97070d2f5bb19e6b01485b9e724f9cbdee6431a2396abbc787915debd6b696176d390b17d609d5b197e8735d614efd3f81159deb1b80d754a684cd8f49a818701825c1a3bee13b2c4a0491c9f60f69014a308fd82935000f94704274aab02e86201d3df05bb0afd9aa4c3245057626a2157be073fafbf770072a16068e66193afcc47daafcbf029ac6320e8c571a7d5ef9c0b02570c974cb7380a8f211a725ab5909c5f253ad0f74d5745919cb05493c2ebe6976671ec58e33bf0f7da5266c1f1547695466ba868d21ff9801b7e0102019511e95df000b1c3780842343f523cfb91f6c667e9b5ec1dc6a27b2a260d213f66974a32af63e25280a6812a100ce66a4852d620228fcaebb858e66aa03617a2a572d61d7821d674fca361760269ec28181d34155aed4384623cb218dfbebd8060aee23dab42121fbefb31eabd5651ecf5a47dba0b101eb23f2cbb74c4ee059884978a4c920f52e37d6f255d5268d017ad61e8045072e5afe61275a6f5092d57257c0da8dd23fcab7b04508482cf8df55e76baa711029306d88c188d9ee584853de9d28792e78d78f4a320bead26616b00b8dbc67de2d5a3e1a56225030fe79e2e9e33e593a45602d5a617b2e6144885838cb516b69605b8d939f57e5e99aead830a13594435577d28d9d3bab18955b85b5e8c4972e834f9210faec58be70aacb10062c348e2239b72be886fec1cfa0fc5e5995145654dd44a50d65ff4ca485c0261fa1149b386b4180e8cbaf96a7edfba1ed241c8b86b3e561fe1db0ef4ff52c524b8a8dd279d12fd9447ffdc5a55cc1717d0ab07eb1b66289e21094d31690b9e99abf5cb56a1158a306f55396342f28ece254e07fcb2d73f83379f0b87bcfb7cd888b34438297179cf40045aee6dac031dbb1185ae979e19f555a087ffad87c1ae8d9487f1b83ed2871f7cd071b7ed03361b81028e95742ff189df11870da6bcd9bd7d223ff8a17ec66b7ea46580768c60c808d2e96c1853954b0f964885c62ad20fbb3796c3b975ed396f313bdd16828f13010f29ad226ebb7bc188d0d25f7a9357ab97c70cfcc056213456d1ad6ea10e6a38530994161747ada01f26f46d030d0832cd94b2deefa0a3c635cf51650d9822bcba9cbbb4af874358724374976b2d239a8ef7ba29508404719a20b44ebdb665a31c78ef4b35e7935039d4e28eb433d1ab903d437164085d361c6f7222f99a85e02ac343aa891df6a79c3495e98e50c1e6df50b7f7f71cf2deffea3c8c8a312e6a40aec5d7d0011a7ec39b6b161aefe1fda6d947a427efb6ab3da63389d49354cc02498cb9fb37fae077ab13369c0ca99b1a191334c4d40e061cd84b755d16bee5152d42169cb13a332ac291bfe995dd59bf4aa37ce4f723c3ebf8cc9ec7cc49494f90c452e9824702317a364092c30fd7a31bbaa558f7ea92d0a8e691e0588887961a87bb7a80cb67643c33f2edbb6f4172184a9163f75f80476ac810e70ed908a4a4725f187d9b42ee73940c15546262b0e7445413a7a616509d9dc2853cca695fd1c647b80883272b31b487d46d4f6dc2b2f00d49ca02d762400dd8848cb555be9c04ec5f3058a36c3285196ccf28afeefc643eb4811cab11134849601457b3e19d2a7a445914dfe0c8f4617d0f649e1f343043e259c90ac2ca24e1dccf172c4a2818c8b7ec5ea8d173afd244590e8c8d5d5c5c8a64ad3cf2997b33d519c3949ff8cc5dfe55394ac560ce55ee1e045f04c467f1e4e5522dd30cecde9fd0cc1e66701a736be7f28a7b15d68bae80eff9a360ad3a669568edadd55960b36c7255437260f508b4c37b25dc742aa25af647b909bb732b1b73859e4378e7b07d3f54d381622c3d03a962636f491f5652b911e0f2363141f6bd9e5bf02af6807399843c34284da59e2ac0cb20ff7d7b4d9d662b8072e9b6f4b40aa1e882c3b0f191860c1ac2a0f30d430f4f6f615f62f27aaaeaeba0b34a1233c559e0817b053b7c50782f93eaf46cece014169daaa1b8c81287bbdc5c05e43e9ec39d399a78733f842e3b1995cd525c42d08dd03c51a0680226f2f84fccef4116f8dd41472d0b35561f42720e5a9b9a4def3ec0482f1c55e311c6620f9030f237f4826485e05bdbef561715df50e8664923a2fc03f295d15404c4c7b009760829bec6631f1660a13510f792806aa961c2ca13a22d074b4ba39d90d05b3c10f8f5374173c3d5ec63fef2bb3e39ca0e1aadb17273fc511d7f7ca8f58972b90c946e30d908e46e7acfbf1616a59c04195b107769850fed4c3354055b2067366c925c84d8ca3aff0f4639209b0b24d726a72ba0d531e900f687d26800a685e37a4493e2ad45680901b683a28e095b825a87095628ab8817d7d3b70ed93f1959280825e06529b5400cc3b28de6949bf824e2e32ac564c13cb76146748c45d6010cb9ad3c5ff109ec75b970c6a1d9066743596334c033c12413021298176b688a6d1cf3d4bd12592f16a4367df663188a74b130290d245dd21192f822115522a06c140b76c6f58f67805ffd9651c1b50ed35c0d1264c5d70b0318f85686a6fa0663c492ad500e4f6ba84e75088fcabf171398311caf21bfb6aa10f760f501b3a77497d63506e90fa77a38ffd5565f8721fa9f43f5668d014af9ab1edddfe30c3e19ec36ca9ac4860b016b49bc9ed58749853badaaf1197874ee1a9b409b77ea9e450f1901922b1e06967680617143c467ba4388f1d3dfc54027df90e8be63d30c250c0ccdffb8ab1ef281a1097b306f3f1c5e873d175d4d35d059e31d73e86c85dc7a9adca9b9615ecbb5c9f64e2d9ae9cd0d80171f66d5cc84d10734ee8081c088e7a84aa4fc520d8470fd61bf230f2533a7360a63f80b5f4a338ba455d9aaa8e9766e2c3a13a0fd66caf2fb212339f1d6c4ba17b9ee1e9b6c39738dc13641a2213be73f527124012c10cdf7b5bfe95f2177a29228ab08370b761be053aaf5154814c442f3554e983bd3764b49ad3129e51c0dbc9885aca83501785717aed6c4be1154dc555ca53b9764b81da08245c9dad426ecb3ac479a7db229fc23b87b49e90293c3f2d5fee2843bf0dcde6e7717763ca9c3aa1da05eadd41e6df8c1fc45438a518b433dec6e0efab359943a78398464d6973a757fcb07dcffa51d432cd702006f3d0d4861d99b4d1ea32a6645022df5d24a5db5389a99bace9242204998001b9efbc9f2f50042dba8050a94658cb2279d0adbe2b21bd619087889cba6103ad970abf8e83b7671222d6b29012c2a31262c18f04ce498224785200749a0989ffe4357b0b167fec4c97ebd037fe1a48d34124c014d751b339bcbb85563241b0fa53197cce525f041f374db19737e2128585fc08fb2c873ce61516380931b6cd4fc085ee3f7e2fdac1d1e0cafcd81c07b17b8b610a06c5308875521dd34a7d58be1fd294705735baa4c6a989f044eb033b02910917a7763b9bb02c164afc544c1ffdb3a4807d92dddb54312105fd4d1b885f15b9421a6812476c0776590123004e12462cef412eb8466b50bdc7a0c8104aedc039b2926070afc77f3a4d0bef9578728df5ac936620415104776351c99967806d27485f3cabe4f73f338e19395081e1918cd5221899b7262f7bd36bb82c89c57c43a0248a81ebed859b559613a066e34c90fe3c44335306ec03ba48c047be4e80a08e70a4acf3f1b7e2036478de78c4ff78f05dbd3965ac70c83ea807ac09d8e60d2fd03d7b5074256042d138e66624ae64ae60214172512a7e07d3f7877a0375423bc9ace51c07475496debb328436551d2799b63706f38382db60831cb5e8f85b7ff61e06ac7e2b35fc03eca24d80d64f9949c1be6feefcb5ad22d80269e8380008b04c1106079607b0037652da8e2bb6f8a60f94a89a36639ffcd81b2ebd17eea9a560bfd7493ebb278cf61e8a589f6467209224a96c3f023b0afddea1ad700329530568a3d85ed89e7ea52c84693241d9813ee4bbeed16f310e4a3829961511c08209f917a2a4abe337c31bb1d83d13d3bb4cf346d511f424223ab4c0c08c07ca11418a810d04fe55ce0813aa3304e9dab1725906205d7967f155b2c30a12e17dc47276431d3d7a778a78afb29cf109054a85d39459e2c6c759108787c67a3adc5c74cd55b68101939f1218e0597543eb055c7de358349966e490fdd548d43d3ca33ae9a396f5f3556f11d3a4535509336420deb8072373e4c65c22aed31b28bd9157382b40e27697c80b31c7a405c179855e0c733d346b01144469c13bc21c58d688509c24e044704d8b8ab3920284bcf28c8063d4c8f28eb47aa7404165f76c35498fd35e2383fcb9c46a968a64abdeb8a7816f78e22135d03eb1c208f017ad7ff2ef6afba19d9ed01154180ab550bdd0aa444e774093fabdfb972e0f590e268fb8d0287145c55baa281089f28f2064311c973659a82e234bf2b9ac671aa485747e968e99b4ffe4268864a572390deda52b55009024f387a2ec6032078729a29718851b404ff48fd0c15c190612660d5d9b9bb11d0849a0c1acf8b951c2f22cb8ee9705a0261e5dbf70015d1b9c533a581f0bae600201605f6425145b24d0cf5cb4c8061f804205e5c1b02466e25a4294286f814f285dd8dd0c048603eb7401440e3f7686a62ab8a7e55ac0a9cf3f1c6d21c074aa63712b62679d4bb8d15c7af2dce05984781c1115f9944b06538d1d0d6b0e60b110f7a0bec59fd8277148bef374c3d65364f494f5f6c947222f416928216c8132a1884dfd20967a245d55a4e4148f1734f586ff2f80f3674e6285f70274c97b538625fc6b69ecfbb6118c782dedb846f86550f5e9719fd6853ee6bf797b8d4f879fb84858fe1fe09e2ffc788f6abcbf46576143ba6b687e93c14dcb7e55d2d9ecb9084811355e84ac7603e365e63a9c941054f94186ec74b758636f159fbceca6a53b43aa7bc2a80abf044eaf2bef781483a1040c46fd0db08d0832c7a0b9bde6718dec55022ca6e582852c60434725049999f245b9f5fe9693cec6d5e45170fbd732326850808f37772c0ac8b3c587fc9c96e4dd81e424192050eb7c7c2b1ae0ced1c1214e84be61b9b00f3ab92fae4eca9fee03bf676d58ed53f32f414dc605eaf184def775bad0c30b3f234aaee3399f05a6bdda907816287c7e6dfdb2e231cc9adcb97226dad0e6e197310985a473c0ed471bc5a9e7ea5dc013243d1306d0031a87aa60a5b8f6454f5848377fa8cc15fa9014ff623f2215bba7204df507f1774349b33639623eabb3a9a4a2f4926b68a2323b26670a7b87c7f04eeee3f42e765d6fcaac963aa91bac74505f154311b0483404633ef1a5905ec4714d359e5a8687eb1f7da150f5f7da0b872a75df542993fa12a49c23448d02d6fedd32158f7661e3dbaf1b8d3a7bacf67522efbeb23895f530ecb8a0c30ac1166919b93537bf469cc70462572c7d6a07d283dc50865201cbc63837c901d87aa98a1317cbcf798097100c1ca6b908c495af0cb93c42620132965179c9d0189f0ca6897d50bb0550c541a3112251800e3e55d91ebdbb3363e13cb9b77d59e4e46896a4d7e1dba4d0c06502a47ae38cd50c8e0a0f2e9b54f864ae1c59e5a69262a6e6992bdbb1c0023ea19e82414c104b58e6cfe7d21bc4dc49dffa1c35fc6726f30903af0cada0c63e4330290063de42c27c37c5b77e7f53f0a060f946e785b2d4e2c934f452436620cbdbd7e6cacdfef1691d13fdab6de591d0d91fc05cf9e7e2d861738af1874c3085812e736c427c1c50bfc397b22476dda2486a302793866a51a319edbe946625a672b12ebcea6a2d114a3c5c6131deba95378b02a0288b944f30e2793958f7efd4428d77e3cc4f0893c24530ae76b78f9fb4ee769eb4449327e78e5d2d199ac1fdaf326d0e6151427e1ae4ccbd3743adddc351b11c26c333c94c75d9863aa50cab16dea7ff8548d485de97db0bdf8ef65bfa7b2b85b0c8d646ae52029cb7470223f78529293d6a1143835ddf81bb8708a30c839a48d017c58480bca1759bd12e88ca615c114b483001efce5efd6505db901a615d94045fe9138627c00a1e6449bf486c9aa477407d0b037770751d47ad8e310ec3349c3839fcb4f9cfd266fcfb239af51cde1d6d63a86a70087127e8041e63f713626124ad003a7d7df5c868fe18362e27f6a060346d70876860e7c49c3570896ebc4557129baa765d7f729eff93751d88030d82384d112725688fbe36043959c6b4264c603aa2888c06352af27d23ac1e43b2b316e8285bf31c556adf313e24c116550faa907dd26c8dad094d8a84c72dc6354dd192c2492df285d60554690080d7451446a488154ded0de46023f2e5486d5e0fe2dea202a6de08e262538301741121797042137340d5dbf10c599751cdbd29976eac1ef721d2d378d353ae05d41703a4fb9edcc45037697199983433f1dc445c6e038ee1d3936932ddd0aac411c7bb5b89c35a018f913430971efa546c0aa4c5ee23a030b65fc304d46e4a0aeba9e700c4219c7097786f2f837ada98859d9c87d9f571644386f61ba21ab4e056a371a90217d5649d3a2320e4a4241dadb1deea69aa06ad6e92bf550012204543f307b519352a03405421a4a7e23613499e0338134ba637afd9a634851abda9b412490df80ced8fdb5d1c840d6fcf973b1c7ce012bf08afc04f4001a6100dc2fb9cac0cbda27d2de63c1fb6ea4a5e930084d3f5b0a47f25a97e0d45d647ffe077c4701aa09500d8fd19d449cc7f248487b4ec096b11adfc2445ed7eeddaf5807eb2a9093ad996020842f6db1779292cb2aab59a3bafd5c4fd9110ca5a84df39cd88d7ff31728f74999a976d73f5ef10fb403655187e202efbb67c7adca752c8a64a52a2dece450a784c119a1d3db884270a6573c97cec4156a22420e8c985449171662a2bd859137de1c28911c45b0f2c67940f31de8b6a536419a8070ba4b3f411a7bab3952f24e90c329b71e8caf83940d72b87ae82016c392b9721b00e932cf706e1aa47f90d89a41821d0bf826753bbb65b7a4683adaae0fc9f4daceb99c8d456c3ae6a894d4096a1c5e9114dd063991583861f33865dd1af11172c6f4691fa277ea59462c620343dbfff5bdfa3fef2bd13d0338a729d9a8146fde85ce6d116b804c05d452c446264724d8b0b3f5056212aaafeb7ab216f8e569d4264992ba3acafbf53ac41b9c88d403c69853fb1801ad7519c38b3f4fc80b9a3ff381a67183a101b7c1fcd0d66ba308d357d41f3f1e234f7e94b10a07be5614cf6a7e132274d043cbdb25d0148d12ec6642d20bf935723ee35e6970cb98870c16cfd86bddeffe641a1ae7ab6142365ac2f601b533f283281868421edb592b5401a60778aa88003d5990c5d4d7d382a9bf3ac1413d28b5ca5329c21126a38353fd8bbdf3fccb7799ad996eb082489307e6ebdb6128604473da99b5f2dec0871b7add434540af2f1b7de878d064807448d00961528948a2d56ece01d452bec1e414182687009a96c82dd562ff7cbbac69ab817a5bd905cf73e9c33fa5337bdf2973df2133dc93b3fc99f7ae9938e2f27f07bba2746871bba0326caa408847d6df9105ddb6c8e6a9ee4219e914b460354c4af5aba4b559040d227f0cb47236e6205f7e2698f03405b77039a9adfb49b777d71b85294216c84bfc17f65093e7ffa276044bbe13d50593271aa087515ea605aa624fe0f724a6e5e000f06f2a45eba271f92f95fcc3b21d10375f906c4040bdbe0fb2e51dc85f283673582b41423c5d4e069d747e73c3e26a548380fcd2601cd0bd580be5d1e7b601565eb9f8fc1510574793ed9d698be4ba1f51269aacdfd1903f3f012fd09710e464c005bc671bbb7582224aa1813acf61ca9ee84bfae6fe80483002e04c8a116f3926b7f2b53fd553e2c4cab197cd132e97303b89eb33df33b507de56ce9cb97774843c33eb883b50a7bb5311da4e629ccf3bdba1a51186ec20e8ded992d4b4a7809e287bedd8c825cdbb7dc0b8c8e0b95589be30db7cbdb070a8f1455d0eb9cbc98a1692da76e408ea70c006d60695dd25e545cd0a9ab7cf1de7fff4fc316964241486638ad738d907cedacb1eba61a8b1c6c484c50bf6aee27bb6e393e7f311bb1b15a8bd64537cc1649655bd1532a971d7b2ac4d4bf774562815ca7c124a6638e5ce8665d7c88af02cd6e8de91f28734d7c0dea78aa0e6c62789fe1fb678d4a82f6ecbab14b56ef6888747be6af06bd19c78a5012c603c80e76a6d12afe20f735995451f4128bdba1052d1de00296a2922492aaa6579a2573be14e1b654ff79ac42194e5b44c1d84e832430c625924b218fa3dd7f23b9bc40f58701b4027c3c9b53b3bd9f8934de7deb426e4db8b0a19aeae1348398d2a2a57110941261ee3ca484af804f2b5335caa964ffa632abb4c9907ab620cc13165753d1066f37d432d0679f3c775347106196d7dd83a86d7a14b86bef0795fd183330cb067981ec1e1fd3cbd4b9a183c57ca303313bdae0014ee1c0993c240b726e3f737fdb44f6c2ea8bf57ce6c8b0fd93b20ab33eb6ad558c49d424ea0674dadea110d03269bc56097a747e06aac98d923314e574a14ac82f10c5161798a61365cea86c1b6bc6560c870547da41bc33db5d916accdf551e5b7a4735479801e1d1d14ed20c17a5fb94e22a08d6f644e3954bbfc748c5cbddb01541f3b03424e0e76b901c70f7fcec0896e7dc06ae8fef467a07fc5df17719340408b6c8fefbe53f1fdcc732ea9c7d97b4c15549ed12fc6f967cf2fda1c89b850d76a87eaabd1b822a108fe36b57520ba95c7154f94bb15d7e25aaf5878b5a4e3530e871aa354a2a5a53b47932cec93d61ccaebcc77384f88c4dbc4f07bf02d61be9d6afa04bde4c5a5d913e5ca56a1c4ddb26d2a6a991056fa5ad679fdb87941825b825e478af1c286d5ce24b10edfcb0db0e2dbeccb89200ce824391cb0b0bcab78a8169306a289ba1488466b75468765942b3b321db6b3328975d9b35228383a00d2516002e2e99ad5c4ec4dc5b5ea33cc2867a226bdfde8e0ebd49ffb6933ea7b12777dfcf7a1a328edb2d0b36ab05c006be3a274c38c8733f1f1c0c961510c0e8d49051b98ce07fc420ed8c170ebd17b1530e2a8b55bbdee72ab9754b260a24699df026107cdacbe05c87be52bf45a2e532267ae88aa30f45f872f94c5243772a0543effb8571010b42017da7668d05bdc83252a22d889fc42a01882cb682962934ecbc63ceb8a35535624d6f398882421b67d711c520646f2acdd0fe6ef614b925b262640ba24aca3a99bc42bc3c6851ca154182094805878342c0dd9a1e29f9464e9462c4ebca67af309ec8bdbb73b51be3586e025fb7fb1cbd327454494c3b58cc675b1b537e55cf03e13f8348f61cdb391fd8bb120471c172b852c26d9869f89de892a6605c408d5b22ab2ffe6392fe52d834650b52727a8c30403793b1d8f225634eb4ea7a8aeb96d5f0381089c2f43d6000ea5096a030c68de421627f2536688e11b303db2bfecf18ab96c47f2dec0f140bf93546da08505cc61d6710d35623163050581024db631ef7a07665392c2f60f481945c45e430663217da6d5998881f86fe731fbd493e44e70d96d87cc7529b68200ba88b4017fd2e70c30c29275c839e58b0bb75f6477cf8eb0f5d3dc3ad2330e61abca5fb2d5417c1806a25c83c59a23fd69abf10abfc5bd283925cd226291c4f283b241fc0083ac6df7956760e79d0a19d94409411d991bfb459b9d79ff68c2b8d460d5a5bbe69d2887b0858a5958a2edd4701328fc2a62aedd66ffabb1497ce8a90342212568d1bae65eefaabc072b21321e4846169015e5141b42a2175af58238176b5069ef839781ca8381f0027716f7053e4867d4b52f59cc080be88aee976cf8498edf2c3bd1b5ec09c505ef6599de08259ec95d8e005398a6991ee45ff1868908d5da34e3a05d4a324a43af2d119769735a232f3572e510f28bbf8da762292f7ae4c6f868205c84461783f4ba0a31f45d6dce2b667affbd956c8b4c927b070f1947db13a19cad94b270dc252ed7e9823b05553bf9e3aa11457b78fee1da5b5a1bb91cde80bbe910e95086c5f4746dcdc60c08226620db7431aca4a6b0c3e76b13b8cfb4c545bf7c667f015cd17abfcf0623442abf78868e996f5b101cc01108b25e6bb78ff11c0878833d2340a6025b3d42be2e64125b81eb95cb470e33e0315f40bcee4b9b8d7fe4de50fd3e99467d9d2f8e646ada2faa101478a55a57bc00227eb77b0f718403003b352cfb5b210ef72cfacf277b99a02d3668b80808ab2717998580b384a5dc582e0567de8df06b0bcdc06adbab46687ddf6454220be09b3972396e74b9eb4d85a79c738e83b233739c69cfb7782a8f20cabef22fa831b7cdb2d3f095e34c4226d5d52bf1e279a99d429a758935e3d30e07b9224f0a0c0699c6649288854e51d0513b912f222954f507c2d57b78b5fda1a97970f29f60ce287dc0da3cebcca2e0ae298fa11fffc5012a3eef3773af401336e3c156d05a8091787cbaefc5270a78f5136d2bcea0e1a7610612e663cd35266bbadce3a6698f167f275025b4f42d1c43ccb83a96269c52b6cc717eda988b3ff19218ca19d1e15aa9238937d19d71237cc9b68167b009afc476e64e50c8142cd24eb4b6d393eedc90a3d9aa11642fefd7a79077362baa56c99e3a3aad182c4d35da371893baefe0ed1fd3513d27aa9488520b2ddbe54394695ab186c4b5b32259745951925d83ab9050a07f8a6104d975bea43ae540a0ba3da6fc262eb46006f311eb59c5a41dc19b9f5e835d3b8def587648876cf7284f3d8e7ab3e92a609d136510f93b8db3fccced1a48531e1fa11b689cbbce2175aa5b948618dc146b72980f891fdc0a952824e208f4cf02da5e22c96300e84bd9fb065fee697b9a5200e879e47989f77b49b4e6871914be33e80bdd96bee90fcf74c8644a6be9a444d788f92e4f72e87a3f2c296de4b9fd5c406db91e76143d766825dcb40b355b320b54dd29837d28ecba1b2f47c3a859dcc1e0021ecaf67425f45f254f6ed5634702f355c07530ddcfe5be4ca295eab4e941506f605b99e8d3d054b41551fae7e214dad3fd818541cab499843edf772175e531aa892fb7203fba757601898ee2c88553315532947f33ad3827272da84a8fe40dce1802d9f9f3d37383f41636fa3650b1e09d55a9808a3e5d4b7b8d1c9ef108ec2cef8c8a0a8f04ad55000441626b96330438bd2b2dddab03e84c7924d5a77a877ec0f86bd735ffb8598caeae4a2aac0c7b565f9b193abc7a0a4435658d3f665ac14068d31a828e89d5621ec0f132f5c82970c1fa8f33c436280e91047523cc3e440525b123b3bace98f53030c2c4131aa1233e78b1a2ad033d424d476bdcf698fc9e5e8f25f7836704eb9b9467cd04396d500ce20885358e5999fe07b0b84ca565c926eaa2acb85eeddd28d8fe742b661bfa8960966aa030a104fe644df3a1f94e735ca6ad8be9a678c944ff5cf8dabc4e042e4bf4cca5e32ea2187c98f02f57a97f61d313b48ef1f9290ec7db29c11f2f4ebb7623fd33a6d4f62c73994100cdf4c7df4600abad663eb0b761f52cdc5e87c0ce3c6c336d5c7a25d8be0049e161422195f7f94810335947adaaccebfdc3de530a6d23ded1b3a01188ebf673c717912480d494b230f17a96df30f7df7244caac231b7661567cf2d4b6b98f81eb6b8f66a7eac30a47a701e6cbe48b194174af09d884dafb2e7b044255392252cb697ee847630cab7c308a91d0627151562ef6a8d2255032d7e21c6b5b8aa32b1d4543737d69d9afbf6a8385e35848d7149a6331a5c7d023af3e857d3b676bed4998c3ca1600efc72280197616c71e80ab9bc7f917fb264259d4ddaa159f01f6c712519172c5ac29b2a24fcb0585a697844fcd2093ef789e1547091f2075dbc69fd961ee787bfa0a45969b8391bd6c4874476fb9d8524bdcd04ead886f6c605ec04abefc46726c553bf6ce429938104a70ca5bcc2900ac5f7ca28f2679d21129961899fce656e613812a363d41dec517bdca4ffdf9024074774058273dba9fa1baabb44a83bf7f2694e6732bb5d2505c9c9e1c540a287db69bb30f025120942d0a3352287be7d4b2c3e1424338a86fdf465afb312308422fac1cf6d0cdae911a83c87a04ad28fda4c90278d19c0a2eaaba1645b1b679968340a84f2ff839235b40646aa59df7823d8521b56e4d2e52b5037b2b498e8ff39407e44df3e0783457307378e18aa8ab9e5111de5f12c5e70c64691494a5875b1fa36c3507db8509c085b0ce58b91a23494c7ff211c83473428066bca552fa4a407258ebe5dfd3b3c30322831bb6f64bee50937cf1394d58332cb41de6aa53f7fda7a89b66fe6ad0f17908f53211a7f647ba0131f4bfdeaba76cffef727c712aac9d4eeb40c7cf684a013b05c87d738c5c3c564665a1e47d01d50e0b5532b9442246a792caa07a7fbf82ef9eac24ee39f4d2ffa235d2bf75a1500b9229808116b8d11b6d40ce8bb67e82058b9eac197793d398c171ff9587058f1bba33f218e35c43b3ed5819321ac788f4bf8da326741b803eb9a4c937d2700996072f6df83db063ee0f5c9bb271c930b1cad1e8a621c2854b9061a0d8385f28605018f5b99934af9208d547d67afab081b534c3da1d3592b87b0cbf3abfe15e9d87fe3ebf287646614f9451d1baed977f9b8e3d7bec28c6a08fd7cd5759e4307455f1caedfb5c9d2e4edcc93d3f59ca803551b455eb344d69b39e064a2fb202673320cf40c4b145a8d5c0fbe142b067503e8d54fb792d7f983a0775db9685903f55d55e1eb9e9ee9a5b084d42db299477132f3077d5383f48684f60f9e40aee7e57aa32321164dac666b50764a055c9d5ab69f95ffed412c517ef6c09bc6903c4d69400b5c0ffa0c7bfab02b68a4aecc7f291b430320001af4b196590dd0144ec8d7e6ddd2d67740bf7fcbc83f8f1853a4722adc45c06905ce0105a52afa95d49d360797f9e33ea386a8246b261b16f942517ed0fbf1885c6a58b4be078cfd091807ced212970f22767b79a4f0883022fa79c7d139a993405d19bfd9634879b714e09f6c3154fba306fa3b2830a138f1bca3af418f2ae0e3bbabe99bf03e48263236aa842e8c788470731222276de58096785ce6fce38ee2387d38a562fbd30e944b8a5d86314d5b019c04d5b54c8593b92217266fc4b1aa6e0d5041425d038b2a23a78a779f1ff1a0e445f2f23e740292c0ee3f21953ab3c81a64187f24b5c49c49ca3b976003096b5e5ae0bf8630744add40323f6e96ebbed25016d06d6d305af9511c044ab79310ba9b080f87080feed0fc3e4458ea5056954e53aa3831c0a15ebc8aec0df30eb6a539567bfb43c47ab9c13bd60e521994cc27ed79112be1eea680235250a27c20c8de6609ee53842533c525a2982ce6a0fd5006df4b228cc9af84a09cc199c8d8db21b8b478f1608fd032c826d875d4a0239ce63ff6aeb314d0b2870761d31876078000059705c856ad136fca391e488302298702006c439498c9220cf8069237359507d8923a6395b88fa82a95d82076271fe58006792c0259cc933fb8c8273dcbf08d51a48cb0f9219fc9ad34f7e398e5cfcb46dc739680a9e806f79057e5132506a0322dacb413c8de673b1b594556afdb319afc50a70361ed5830fdb7cf3f1194c3775d9b835c22e43382e4f2440786700153b510e0abb83aed1cf0f9adce94e07e00321fbf63c0ebb8a169f5006562633820d0c7dd7b17225bacc44a3e58b3f2d015e5fc478524a0a718986519d28276604dd731471c9b153da407472a4b4b3b67131401513de94f365f65a64751cd080523c4712298247df8a8b1ecd74128cd57536b33178213f0d2c3e50aecc1822eda6cccf7a44f5ec40762dea894219e465aa725e3b266a30a0c67b1ef4188d2242cf238e24653a89645a7ceab23018958c3bf35ddd3ae6986ba552e24c950c315f879c6eae4157d7526f0ce6c6d97364392e9d8b630060eb6b7a7cdca51751bdf8195368465e47d9e417cef3c47fae9a07da749b98350e0e76723d6b4a478cbc6111465003d3367e21093cf7e86c65ed3ca3375794d086fbc1f58c2835ce52c0444170bdd2aff1a2b2fcbcc14136e2d859b95ede4612bd588548e491b127ea2e01ad15e3ab2bb2de92f54e45af3904af0fd476576b9b6d78e4a1b086b6c6b9a343cf117257ba1b550a0bf8056ddeb626889fa375e40cc11f4cc94dbfe8df1aed71daaf18f7cd1e9166cfaefc3fe61b440b5813fa40f59f0f37e1f80f3d3ee552bcc1aae752454cc0e3ebb2dd48ea1f4671556e489585899602759c5f25ebafd7d28f4406f561e0fd720778439d10a211c2b85ae8a95fba3c33b29a252dce46e26cbfc1d8a09135945b2d2a8a0bcce303b8309263906ebdb7ebbdeef34d6ee7365190fe32bc47dc258ea006fc7086044a3017ed7ceadb0be2796bfe57c3a3ccd1960bc229a325515a7c4642081b7b4ff7dc194ab7d0bbc3981c3689b7e322e00bcd1d785c03f49a7e6fdb5680ccda8b230733fcecfe4f841e3963f3f57196613a9069e30bd8cd2f8d770e57f0a630346c7ca7258562d705d1e9c61db43f398135ed363fe1b0b9f6a5ba27181f87ecc1ab133879dd9491262d9aa330bc43a95d9948bfcba2acd45374e0c44e2edaf1597531b523034e447d9812d27233806ac61cc507c628846b6d6217ad82259c5b18084ba3bb6f27fa9785cbd496fbcc5bc3fa3af9390cad105a9d3ca0a27bb70ab4f61712a7cb41ddc371e23994685e20505e6cb1c00537eb962a0b145a565f3b40926dbdb425bdb36810f30a9bb9b07a7c483e2ee39367bbd109738a77bce70ec9e8c70cbaab860be02326328af1ef92667666924b31087c9769f54017fdd964e3e1b6548c413d6f1094106c7859540bdcf09809dc49acc90a908ebd1fa10918ef04be6a7eb6387893158fa5fad557278f60e4283fca0d0a7c38735814d2eb0dee020a11b8ad5cc1768cbbaf233b5ceb52ea2b4847ab4fb7ded73fc170088631b3ce0bf76b0c8a66a64fb55c40204c73d576132556a804ae077971f148d079098dde4eec0ab9132128e52407c4286f6783f43ee7a3f042c672f82059faa2ac8aa6ff345de3d6585eecc6a11472bc2339947440fa7f4831d71f8498293dd82e1c218f5fff4da2750405fa38ac301c385aabecb886cfeff1fd9c068fee521bcb2d5bf0b580111eaa9152b3bbcdf0ce437ae47715ee3026935cad34bff9c59f55ef3f9bfa69cd71d21361d76524922bbe559c246263ad6eb717ef363feb25070a71a537f8cbc75d19c7a525ca3b86a765d894a69fca2a4e52304babc3874ee9594c8bdd56480682eb42f2d5b21515236b4c9336456133f6fc625e99a8fb4b85ddee56a09844121f5470d37367379186130290d7f824a508e8873753c6a4916bed61f428c77cdb30390b86625ae4cf9ab289b29e4bda06ee57da81ab9f92e96eb3496f11005b51f6adfe2fb2426a60d8d97d6ad94ce075693c59d5a182d0a60f58e0570d066e7fac5da30b27d7f8cd608c93c013fe5daf6ab6947eee674ea5370c3eb25d4caef2452e4bee9e46a55232fa54ee12d7105735768ba3e4dfe6f550061bb7bcf83a5c3afbb350d17f8038c9ae3da04b1b28054c723ebc2199d64593b7ceb88dc9d6bfeead47c6a277eda76e064d8977eb4751d1b94bed39393363796873620fc07b29de2dca4ae45aceaafbf6de3d570415531c43caed48ee233c1c9615487475caa18843466dca0043441ecf8215ec331b6bc7af98d67d46ce1e5108055e713153dcb47cc2f58d8cc64023ec3e8565ca883d76cefa77b74a52c2ef115c2a73c431412a7821c6f2412e8cf618a78fcbf1568d52d580778e2861b46991d4e8db903d751edd9692ba12395945c1431ba01b05b002c113b1825d131fcb164102a6b9747276474e3623171a6d6e81876006941dff4047687184f1d51d40276d67e9b89e3fb88d666139235408a296878279115d989e71f17b503230d95fc908547fcbfbe80672899432d9f73ca1feabe5aa691820a33253f4ec82810d99feb22bc4ab6313d11bb057f9de618012e33d261e1a8ada9b20ddcd790380252c4fb2b8850d50111047445da18c60f1d2a55323e6358255bea608753943954cf818f6ab0c06325e9157f12f8b9f0a126dff29928f59c593e149d01f5452c551a2da319ba54a2cbae0d6acc5994c8b6c685366f941c4ab101085b3fcc84ba0fe9331a1016aee65310184342f208affdb27743410d7a35382d2d1182ce007bf17a05d03f8e46f10a342fa8575aba8a8c771ae4c3338c75cadf71b12bf92147c3a7f321ad491f50581a8911ea66e381a9014294e238ecf9ea183e68f84b55e092bc6e810790e2cdc05b3879cf7767db58cfd1dec6785f268a1288d68381242d6ad999f341069023f8db9251e825a920475bf777b050ecedf152c5d0166f550c6df15685d1164fd5186df1548d911d4f9518dbf15489b11d5e9518ba89d16c2aa054686b025ee0293714b01d1e7d9ca053036935d79ac343cadc894e5f0843d5f4dcdeca435b6512a2838c3ccf8c015920c35106cccbca01f036bf703f1242eeafc6776a7f2f6feb1b6afbd84fa9e07b0304e90c12bc1c8705e3711a5d79298ec091b4b4466d99e90643a96ac65305041d8854a5dc68f77e5e0ef6793492f8af77336924fabbcddfb5745db5969e4fb98a4fa3a5f66f2141f5f7a6449b0f585cf9be119de43fce4a6d41a97c51ed480e860175c7400bcb3092d988a2416672e08999e31f4f4f902788265184447ba69e9583f19bdcfc8977eea06f54237f6ccdfcee4935809fd4e022cbbb5f59f159ac300434949526e73ed6e29365eaa4831145e3e5544fa207e0eb0582e20493e7072fdf5557cc914b5a9a73566115f97718c8379061e85161db465ad5169ae1a14093384169058e428c1e99c165f7a3845e506dfa5f0292b94466a21fe85654e0257bbc5e6770f6c733ebe51950cc9b6977e85f54cbc66960ee5b1a725eb99a8e2ad111db455ec24b675431519fa5d7d966128993f58b53fbe703acb8c4e49ad19daa68b6830241d7d2112d8b716fc3c42eed41944b5b1cfd6078435088ec102c64b32a432141b19ce68403d22e91cd31a8189f20c32974e4ccdc4c3b8078bf1f8bbdee7974e28a0cc9b55c3de9cd7d44a1dbd898696176e6b01398de1b4e70cf6abcb7a1f6226d4152eb387b58e0cc7f7e82f64521aa4bfb079e606ca1dae4b6f88c131b5cb442f6fb44c3d7566615a1175b42ba01a0c76308bf15b0a95d1e5033760ad8f3991be9c91f74bbc19c3f60b46d944870cd603ef49bc72c8abd46e1cb2a420c4d4ba6c820e227b95027f9ac60fa1f976ece0431e48dba4544471092461310eee5bb539688aa8405237d2753a8383f4bc9e2eb154aa6ef861aa6b0dba98e5370f4e2d86fd8ff2a4c048db77d979b70b09fca9d68a0730c587baf068296fb23affc26549eac5bed73b13965bcca324f594e16aa4649805164ad59989c0201ec9250e1d41f44b187bac5a0104b3f48831bfdfb36a18f971f1a86f28f76e4e1d6085d760da3c2adf9d489b0e9587f79685fba5a4516ad8813936b94124b15690cc233d2a923625d2956ba1b161b2e8c17bafa1cd9ec37f5ce42aa6a6c1aece3678edd5ffa7f10696b9462c76ee6757187c475abd8a15dfc6f320546855f7e64b60e1296edb9471084145c01abd9b700cf69462473e7b08f090b4b6aec4e20bbc21cdf6ea6dd76b598b50d390a1cb82fc87b0f1c5ff275fd2bdb69583ff97348354f984c57376133fa7259b89c3e91f40c5b35b9ad07f7b7bb4871bfb663dc4fcb4054e3ec8408a1c8ca9ae933ba00027e823cc28aaa012e5a5aaa22653c1c3340af1adcd2032c0ff3a0f079eb482816f1ed6c43771bb5496b71624e8da4fe756ded327e75c1a6300597bfae3a7dfb9ac6fc939bed1477ecc56dca29c370ca78fa8d104569282a804e3c0b3215e750c89705e2a9867de5a42fe50eb0a2d9ccb5f2fe4deefc0b799006af9e2979381a5e45c34bb771acc8b1a32180468908840cbcaf845fd95e0537079206d26e88545964145372908cdaae8eed834b6fff827dc9247d34cd7c792d31723c16e6755782e058f97adbdc8a5294b462e8d7d246090d3d2aaef62f77422c924ef25a13181e2cd0b42131ffc0723d6a33d9541198f31a0c8c41ab06c4e4eda9a626652af4c0ab0a9c780535923e44e4b06c5c584a47a8959e1b6e97e3c98f42f4b0de5a3e9f09f1a7dc028d50c1f221de1ac336033e5c04bb6e6c5ddb17b4112ea73c46631446e53298c056c62154284744c295932f094f8294a3ab01704f2402ce75bc4661b96ec6f0e699b60e75bde0bd9d9348354eba4afea01c558e2715e885eb5ff4c6772160add7863be2cf2635046f1f390d7b9b71e25571bd7a142e9ecd395ef5ce858cbe522e3ae0bf108b3f7efa5d9751020ea694449693821c66fe9caacd2a59afb340aa68054ee78e1b39ec5105a2d27b979902caf9e5b90e955efbd330532e95bf8499b9846bdb612616deaebd5618961bfdd8627e0681ada4b77c4fb0ea3ec643027df0af2b6e8927ac2006a8f37b383f065245837b80eb2878b479842c510c2e3c8b4b0ac7044872edc20fa83a3c9252d4fad8728cea1e6c5ee7629e7e23b779a3d7ff40e8e9911216c0468da18fa1f61cbfcb0316deab88a1ef34abf47ee3e1e8ec484fba09168a0f85660df6450ff588e42353798c43c2543baec5369ab6cd427b33f233b95848460d3a75db8a12296cb133837ce96266c5c8e228f83281b28cacbe163dab1387385451edccdd78c14bb970cf879a1750d22aab62d5dd5c57ea2d730154e7e4ec09da8ea15729d23dda1444024625e66efef593ececd704500775a269b0f431903a3b6f83d0ac3608a42148a25230c7093ed8ae4680dc20df1ccbbc9df5aff56c5cb333e187435400b44dd2c919d7a178c3f0c2299030b0a7efc3167d4e2451884242d547a83dde02a61378a244b414c3018079df9c6143e7a3615b708958b60bb9b4b6518a6877b9b850873c8328ba6236fcf9984ccb368e89b807015f74fa0a80de0dd506a61cbda39bb3700988961f48fbd6067144c6c335059ad497467978548f9ebaa6d201aa42297ac9d85a682f7a456ceadd79a3206d2dfed581865c49b16a3ee462460107ed8cd1e11f7e222271eb8b2640bf84bf8a8241b1d839579e3081e33d24ae0919573e2e0c179f0cb40608f6602661b4013247b316102f9c299599c5bfa0c9e3ab15471a453ff5bdda75a72929e93d1cbe111fefac4b550966fbe6c2a2d2ca8dccde31dcdcc8189fa64336c7f304c6c2465a116b5d0d40a0c6ae388d5c49bff882fb4e90e1bf3648e11b9f6d20699283811de48de3d5f1a70f90e14158b3abd001b5d38acde7002f91eabdf66993f668e607bbb261c2ceab158f74d5e813db945f1f312ce8ff88e3164b5bc2600a999beb0fd8f7cb45bfd1a3b95cc6cf89db46e38264686be43ace4012b8a4796e3291aaef33a10b74b54ceefa13332e8d93bbc0614612ed5af6a3234ddd5f51abee93c726664a35a9172e71cb10a983160214d3922a8656dafcbb968001706c47428419eb21ad298e817a6b6b40ed1c08e037ebc40176b63fa6b6f71f18d2547aa89745faa0319c3f1c69e1612142edcb879ed9459a06f3a64f72fc0b8aa03377984fc2a2006042caf069a550584cd1cae5a7eb37c74d876c483da4f1074492c0adcf441a8dcd4b2c6a13366d4ee74dc686ec16b43bde595ba2f801aa8f971ca308367e5c0ddf428780374a581234bd21a0648dd38fc3f5210e0de6d813f42a7fd62114bd6af5ba6aef0681c9a0e4f5edc3240519e6f9e6ff9934af5a92111d8d3456ef1028e62515ed4fed47017491d04a4012db3bc8a2ee64d2ea8f325e0294ed8548df2a31d326309cab1c08d9d3fa394eea20e5856386be3085d6206bf4f71b6b1de94eaaf40f8e5e6a2f2995652b86096c2ba3a335867c80bbde26bf291dc92af5e87861332a385ecc77ef0ca2e1d6466360c3e82a828f850f419cab7d4f788717600164142779a8682316ebc86171e6448e1c725162d6859c46fb066e0c028c6358e8b441a7803ed32056983d0988fcfef2c20a25932655a269fbe3f4d54123266f2014a34541577363c6939ad92f16cbeabe02cd88e8fd03a0a015ccb10d94dfcd7c9189a1d25c4520d900d9c66d0ce1268ef20b338f28f71b1f633e24ee11e47773f2c0fc63102534f790c17862f97966fdf61f1e402bc2017978a71ea211306839cd42e6cbdf9c304164f1ff02d7096a2c93e379eab4d4a282fcdf9e2c99d64b2558add3590d057139e5309ead0f85b84e7517afbd8ef9c8a2c5546500101fb6b42b142f3658471e963609aa1c235ef885d893e09adc91dbf8de2f161305f546556a0c796634c2e4ce8738ef3675c3f8a32ae63ca8eecf8bf380a69de58dde92fdd681bcd7f8cbc2cd5d9a48da2e9f422cec80a5a3578687bcfaec368ffbaef3cedf4013d9a4977734668ffdac75723e3e93b22a5b123d8322e3c218cd44dc567049af7bc81f42b963abc8f0289d154f8e8a3a093430f123927102ebf049020cbe9dea0e4ff4e505dae21d0a2c3b62ad01ef097ac1e04361bc7fa300b60b8a54357bc7911f382dcefa20af8d257fa615412ffc5a3bd223fd2d2594039e3e8f2a2918da44fca1f1112b8c1e255c5e864ed4259704b002bb2031f981c485f4494be4a615568f509cad8d35e134c4f248475d10ada9ba46fa0eaacefd32de91ddfa21fcc2372b5c403732a898fd1cd2b5187e9107157c2b25f5af4dd13034085f678c8314e12c7cd88b933e928e7e4884994afbeaec4f4015788221020ad63a323a850f1e305294274554c1bb93c513b8aa343fc78cb708055d17cd36187617af462871c5c0081b7c8d1101d5b8faae48dd799dd017356890722c4b696ea5e464a330fc23a011fe3dadd4433550abf7fd0cd9acc34b7213457f557e48d0411f74ee412feae166eb6a9c663d9d664f5a34f87e4e17c4f2412d2c35ebdd898549c9ec605613d2abd74b6ad39ce0d0534ffa976e377a5dfae48432d0dc14b5d83b29e1700d1801d4dc150fe0a7c7e2887ed95697ec5ef652dc1cec9ff73986ded6864cab4ca00832f4a7713747e7fd9ad157e173c99373296aeeea73afa4ee82e200e53e313f4f29a88221dce81e6870734f300a80abe3a613cf6deef8dcc6b37a0551e9d7b9e35d417d9574708f4b2ccf4fd9019958bd6763cdf3565084ddb48228ec05810ac10b06981544bb8ce04c730220aa14754035dbed7d130404e64b6a2f1aa6205c9b404ce9bfc84da7c13365b65f8b3ce592ab02c0e19e1697c3b9cfc4b8be6acea2952998abd62bbe7d9e5d0bf8d55ad80404ea1dee98425881029d2709f739901982844304ff4c0048503fd49349a0fcecee5cf3e9b2f48420adfab4e845de6bf3e55a02deee2a023b02b401f8a40b8b384bce23f53b94af0d49deb69e9bbb7d217ca886b4e9b04b72d08ec8dcc934c39fef86509aac0bd1c145e96b71900e825d38fb16090c55751dcded9f26078a08b9377ffc42fa10b044bf018440831f2af46b00309a1cf130c317332eff071af3b0e7e99755327a48824197ca87a966ff3ea827c76c4cf9477b2543fda14d24516fd9067b7403dab544563f07b4db5318b8a6ca12ca6f234621da3b7c76cc0acf167374caccf2251de2da8378d15dbda89c831f117067ef387eb1d0a185705ab57c3e6384576f074757e4588048c0af03829ececcacc0b04316479b28a2e95b6638c01ab845bcb2e4a1f31c44339e0f4eac80d26c1f981831e02209e8e26e0650012278368dcec779ca0760cb4c85f67046b025de2de07a36b3c4b0628467f832dd1e2a1b3dae8964d9f79737ab973e48be22dabbed1840eac35796ccdac0de3c1cbcfbe1abd012c62dee49fbe86f76febdef00d8cfa4688f499c14d7b818a0aed037427a48a20c1ef4e1c8c319e05f4bc16a97c0f5044ddfea28554e9b4bc1df754907dfb5e3029ec7d82ec10d6706fe7709b97bf64525c454c5e6d69acfe8f020be833b8c06b5c99fbd4ae2a49ddb953f061a83f6370d446fe02be4a92c7583cb364330c03b031ee2b84923d7d2f1bc6242c8e5334170b9c03f1c61c8cf11c65e29f76079214a59702a589ffbf9900f6745dede6b1e70831876c34359986fdcf1a92ce8e2b19b43ef556f888eaaf3794c0f116ba0658e0a1b20062c944cee63ed65d2a350d8f60e03766d1fb79cb16b6ffb405b7d28ee222d64ede22f0102584c8795ea128b1bdc602b27b7af150a07b90691257a73ce5146bc180fa545f9d2c10ba0c28e11a4c4a9b4b7aca5e65f01caaab461eaa031d106e58e21baf6d5c8ce3d3f8768c434e6c203d318e630e76876d1115306be191c23d3381610e44cc8403468551664564151a0a7aacc8b2820b6c7dd3068ef05d9f766a1fd2131505d30b09b9883e6c12da3068815213458694313c32968bd1b4009e782b6b26b01f620eb45e5fbb1c2ae87e6d0dfdee5f84feef65d62d819c6df42df616d5b73a75fb136154f92f856ef42d7c08797479f3d3e20b36f35ff92192ce79d1092c17252f3916be10fd5ba460c140d4055fe238efd53bf6ee142a8ddafd0c3895d6709e9c5b844dbc496ee33929d8f6514e51978b02855fd873766d1f959aa2f4b1516926634516b8fc9837788a4563397cbad06386d5b22a77d18e22099e419e02411748eb48fc16319ffcb7d7d36866831c3df9e1d35520e0386c8fb2e51627aee1f2d1f2b8bd31648e6bdebc1917dd5c0257dc69b2f9d3c7dcd56ee0ff81064fb4c008a889a107dc3d8bcb0dd59cd3a79130d96491cb885af14ce9554d32ab8ab2450523ac1aa9ff48bfb10be6ccc0933e5f15b131eda9cea1ff5cb3f1df7ec33eb43af3ff63d352881d6bc5be9682f9cec412d48e10a31f3c55ae61353d03e172960e8f220e20f0e4c883e0f00488e050c510a277c37e75aa6bfe743c954c5dc907ecb6ee83bd22b16f424c621faa8972a895b0c57074bcd33ce9e7e99a9e26a01fc20d9f3d18bf969bdfc19fc34a68fc1d2e543ddcda06657fbffe278f6da1a4b6b699af73f087e4cfd00b2fb9b5e0abe07b833e4ff7628f72a526628330bb8a370b940e83f845988a50509a3dd7835cb82030d2ae90a2bceac40d5816e3636bf7b6dc1bc37d485c3580495dc27f79144ba7f896c4f0a820cff107edb755051da2bfaf864e4154c87de638dd67df2464e2a7b1c2db5969501ebc352baada42a2bcae830a0aa0b0782559ffa1d0881c098ba59c68569061e4920f67d70dcf3bb175f72b4619ddcf0b721b7eacd6c6442fdce473adeb09a5719317a7ad06bd36b1d5ac252922baf8ec24dbb52d35581124d499439ca196093a03e9391d1a66607e0351e0a8f111ff948e47b3b50bcbb83d709556870beda1f2752ac5ccb1cc1ad4351e7dbbdecc41bd42304fd7d1d2d2dc6369ac58e1f475f474537de3e2f6084bdcc3dfdcf4f0598bf4743e27c2e91a4d6402f697d7fa5fd956872072ac10e9322e7fa8cf9b7792d53cf914247b0c3ef1f76c1d89d66c573cadea75983ed66cfeec48d07d6efe1d0c454cd1b6b1c1d49c17b348ce32593d13281e3db979470e4e905defab1b95aa2864e03b1511979271986ed887ab09a8147e97fd87557786ba92fe5ad3fdbdf6010add255dc9817404066ffbb599f2a89516fd760fe04ea537fe2688cc52881a5c54cec26ec003e92196fbdd98e479c0fa072f12f6dc67c207700854dadc129cc8eb81d7345223c04337251f5d62cc737199d04a809c8072c8a2c8d3af58aef47fca569e66697ca418032cd126d666985416ef2e11419d2acf38f8169bd4592f3ec16acd12e0e75fea8fe1f62585f63586bd4dfed0c02d5aa88c1d1cb3d84592a2ffa9b8da0dbfa54eba0356a114a7d8db36b8e94cc2a09a704d3f71ecd2c36c33c0842f9082f08a20630ef8f677713fcba99604d8ac84c784668b6fd5304a2f9ed4915018940ecad4367c8813b04626f782e6f40e1632cc005ea34ad570786b2de53f0022370b16ffa64a1a004979e5b4984cd22b74f804c6e4468db7621b6b762bfd2f1bd7b6a8a5996fde009fc8f858cc4bf5d2e21e00d4f49349e23cc7a7f594e2b2715afb79102c3556b1407b2e3b371e3d4040e2537433d6170ed43c9b99e78dc936297083c4834b12ef6837a1eff44e54b817b09fe3c2ea49e4b78a54e6587877d9b2b27a72fe03b9ba88e9abbc3a5f6d1717733963a4effa1081816992bb55f375deb26cb515aaf0ce0876415bab880a07f611ea4badf212f52e56cdcdc3cd27d3a9712eecea5a02fad5e72e591e2715b1d5b99ba18467f8964b4470b0e73594aa5b58b9bfd74ee5daacb4c924326b7c9a8a0b0b32115f7d005473a599c70ff66021c523ff26357fafa8bf03a355c7bd30197da52ae5b80135ff7df566ff28b2c9b56159c453f3d127ce5951ab6232076d80ebb356fd577f28a8867d45537647d0888c535bc50baec8d854a1870c4eb57f3d5d7b25889c1f86f5724e404026b2c950dde126e27085c1a4a2c5cfdf34de8829a17bc77619aba434a6ec96b85c5374166c6de8db4aff42ecbea1d9e0b5a919e70e7cfa0a1bff162a6f10ffb6ac5bb0f04fd5a2baf1903b71f4f657f5807c0375cc469040adc9bbf58209a19271d454962da8c292cca9545248ca5aa0834b8a094478cd72dbb1cfe314689e1a0ebc454d821ed9f8a01104026b108b27ca51a7a2d3cf13511fdcfc3fc169057b1971a48dd9adadf8c20b546885a2384ecbde5de01df0b400c770bf2d589caa432c1f23308740afa33a7ccf983a59379843863faa05bf558820f1425044f48187ce0d7dd2fe89fc7b80be28cd9834e06f1f0e055f8127e152303745d5aa57495528180802a152cab144abb4ad931774249baeb17a49568a954a294d210742c4e9a5c8c49879813d892edb1dbc0abae499507aa3c4fd51ea89aa2a5ea93bbf13eb92237e06dc80e6c2e568878418660525e02f0c8dd0420871b3a9ae82808b4d396654c74272f743f56382a065f3178c10e3fd055f0dbf3e7dd0c44a978a03b75a03b75a4ef5bdd748d2ae94a30fe9612ea1ae540f7e22e4b74b983366b72b114284e9714ea569e08a344c7d2956e8f92dbf3c2f4497acb0a3c8926917a8316c88b4b81b61b3b4c5da01692e9b1591e78cdb3a92c5607b50db56d9a26399cd26da8be99aca9e5284bf1cab6906ccf8bb7d8cdce2670aa537d7bca6ed7441d00bec30e20084ace86774f9a4ed68057402d2996065dc01d3eb5d0b1fc2dd75c5cbea34a37956e42ddccf2ddb3df77297661b93f56326e4b4a698257dbd6524a6da04b5d035d2a654f5fd91d2c00accaf6b83738d4cd4830cab4ddf4ec79dbbd6fcff10ee6639694e7b1d8203f2c903865fb8f6695c018f1069ee36ec41f41c0ed7615227e0461b5acfe64d6ee05b86d73c90f3ec5a45494a7539d6ca6f8c513558f0ee76f488cfaeab1dbb64d3b2207eae0b675913d1ea86f26d3c581fae6cd3774e0bd9bc19bc09f9e4d26f0a6e7984a2695696532dd9c3acbb5148beda02d3a0864f138ee86e5cacefbc8eba0aee281b7a7e8274124fa64d6cee51fa87aec40f0ceeec54b244bafc0f32ed6670b6f8e5962212ad59228f0eae60fabfe63ded9bdb8a59b25deeec5030c103bbca6271b3a956a9b6ee87207c917b6a76819f35b7cee2705f824c0e7003e2f9d348bc667109f974c9a35a33467ab0797b3663e2f9f344b9ba1593aa1850e17cdd0cc2636af59279df7549e077aa04a3349bc994c200d5803044d2fbd06cddc365b3299bed9de3653092c8125b0048207e2a56f366f25d5c16ddbb67baa1d705841e5eedfa7f6d9aed2fd7beea0afab34eb1ba94ea5522927c1a50d2c4d0ec70fb207f05e2946f6b0bda43a68bdd7b4b6959e77b08ac54aec35f8cd8257d995ea323866816b1ad4e61119ad37ef3b321d6e57d5cc221856695d659c23969b58b6cc8912b6405952672afde8be726dc57650c7622aa5de6253a93cbb0e277512cc795831adacac3cc69587b89b951653cb4b2d07ef8a95586bb1a97b16b438a47bd7588eb27907a3a4e99ae9ae7278371dc7fb0e36d90c9e0507fc6907833fc81e58542daf99240b73adb716cbc33d1b71cae6631e605e024b25afe48138fc7bc49f8d585a09dad2f779345e0d0fbcf75dbe060d085e9bdbc802f9c14527f1f71db4cdf1802979e03df849cfbbc7c3a588bb9130f7ae0f3653ecc3419b7d780f979c0d1f6e9738c1c7d18a26aec05aa3ecf6edd6ccd56b1a65512f95262e65797ae44a28d3753a539c75fa07198429723c2e683710dc36f0db39ee66ab99a0dd6eb237ef68287b7ac9aa6e8c399d2ed3aceda76fdccde9ca2e6681b792951c0e0dd7ccede26e3c0b9e044fb00e385a41022522d00287385a2102289807a770b4c20459606d6e350a8532b1779b86c4de05bdc7c82022f6ae4c87a0e95906e7efde5928269de5d974969b653078116743e292e9e053281b3b6cc91fcbcd547238392ca71875734e28d2d5e96cbaab9b69c5e07f9041a46ecee9a87b6f2e07ca6bc93ba79bc3f28a27c7a36296fb83ec0194c1de0fb207af6455f7ac6a7483bab143d4298743c3e0fd41f680baa649ce86e92c8fdca9e583e31d345d2bd9d435d9d821f8c89dae0defa087e3bd740db429161b3b2c3d7a25d3ed7991da9eb2a3ab5ed8b6d9fe830c22e2edde0f1fc960d0bbe695ac77cf964c67f14a2c2f59d54f162c95aea95462b9e7994af74a2cf73c5389e5e66cff81c59477583cd022c1aa11ea1a91b9e46e6a48aaabbed204a7de62050a98c0a96fd734b955eea6bf209908d69938a7e5a9bf5b9dbb0072bcabee1dc471fa76f376c9f150dde301da4c31c87271985ebaa97463e9279b4d1fdd00abb3bca687f05eba5e159d77f032db3d8bbaa6a9eed98c84c77657a56f371dbccaae4a67b9eab159abd2c551fae9a792677a4ce991bb21f10a75bd2a3ad5dd2ef3c8f158bd74735657e9345edd9b755a00f6e272fc70d52b8763e592aeba99bbb4c3ee9e74caed6879eacdedd86e96b8e5a96b2d3627c129d5b76b9b55598a63e2d4b5ba6d46606f52c9edc897769875266eb93903d9b67137fd148f493bdc0e5eecdd4cfa77f30e4eddefa47f29fb3d48b3be3bbf9da64eba96b2417e3418ba54ea35dd07af491ea2a6b1592c2f5d2b59d469bbc9964c3858de42b1c9c6e5fd645726d33575b5dbe8d6a1c9847ae9a79b7568323d723c58eee8a7abba397db02f984f8fb967f157366320c70f077784b6476e63956e325560079b8ebae92bd5b5283bd081df6ebab9b1e92c2fd99ce123f8c5bdc7f65efa0b1bdba5f49a6973160f7bd788c4aa956d0e4763d5cdd90e7e72397ec0b11dfc0ede22de9ec15760076f9be9268ba374b56b5359f0d3b3f97421ce6273120c5ed4cda39fae4e6370032568fb35f387932cc542d8ac8347b7b1f9081e1ddbdce1d163b48dbb91b9b2ab79e46e6a5ed33296e28dbb1171cd2d8204eb48fc8314bcdd8c04e7f4f0fb2cb1ea1a699c9160fb91f5aae8ec7bf8f61077b389b804441b976b72c3c1071bf1b5d95e9dc638f4702d1e00e08392109a6de8b6efd8ae7a4d837795235e75d5cd613d3e626db2a1bbf9b1862ee2edce39a5f4600a4149b89c5c4e5c4cae27ae261dceb041aa742e36daf46029d624d7834b0ff7c70e36da001102622b81a592278d904c7820ddc10269172090b04d29e338c0792ad9b61e4914a08b2ebab0a129ddb330df2c0f072dc7ddf0708d071b3023988f381c18986b72e3c14a1a181b310fa5db416ae8729cf213043238e140146636ee66e6dacc0cc775f7e47422cc7cc9f616decd1021cd02ef79335662c9e97096bd5a1dc6fe6144cb182286eb92e224074608f9b15d8c0934743f801841a4593a9486018377db382fcbbaeefbfe98981ca7703740e64a47f9f61cd5c167d59b8a0e278743757b0a28a15ed94015ddc06ba33158959c40d5469fd0cb8a0833ef5920417e34150d057c53f1b369d2fbf61caa9e02b4340b202aa0b40c93cd4d059e67e920951454346b8bd2ac18062be20cf90454a96eeef0066e13c80828005a825532aecfcabbc4330918a4414303aa3ecbd0650aa4ba2653cf0bd38df03eff4284f41ce2d5419b33e405a73ee405a38234cbbb39a9a33eaf695a96a9be7cacda9e43ac52e5a47efaea2dafc00e069f296639cb419b037a2f792fb18060cb41dbd2a25279a7af5e337f7488fa89c3012fea64adc4da0b8b84c88bd42bb0834b3f792fd99ceddeb5528985e5963c9b7ac9a68aec8075bc4b1cb91c157b1747ec7065757f7488233ea1ee8b17ffb1fd00d2e1246da7abed76d04f0fc630c9d072d4299542a14010044110dc0e5ef59a19b9d12975d0e6fe90d451a7dccde9dac9ca6e2557af5ca7c3096563ea238b2375991a22df599cd4b7d45756a7712a47fe935f996e96d8f4b99d3e6bd6e99be9dd3593ed2a1d14d4999e3b688b2cf1aa74ef6e364bcaf24dd2cee646bb6ababe2330bc3d8358057ebb2a853a1db4434e5f9da2acec5a5a46afdc8d885b5eb9d36b1a6529ae992b1bb18962165be4083ebdc5ea343e7d64751adb387d7b5b9cd3b79b22f25d070a7cd7c1860c948a0e8fdccdf79a7eb1f1517d8b0eeab0ca183aefa92f39829419e0fbbd5de673e6d9bc83b3f792ea4803bdc429ad27120b25b9a598601215ea5f2975cdb362e84a47f128dd1cd4bfe7a0ee59d477956d293afc8efaf79a066ff681c16f36bfe0ed5a9066cdd2c79261958a02dd3ce4057bffa17936c8d4a2f39ee314204180e686b79f4c31f0f652a77eb2a01df28251b7a7e82761e83ebbcab15df5ed14b0d7e166d5495ecf8bab7a8b76991da48ab8b7d081e153bda6bfd0c97f4b84d044d5dbec51ec795245eb8a9207ee906f708810f01ad1e17c1020de6b7a52e10e4556a240a0b4140a27d4097de249cb594adea717ba4c8132969b33ef5de804701d3ebbd0e9f0c8f1c0e120916681374b4ce44786bbaec3dd87bbe38e5ea13aeae6ec7473c7724b37bf34b9d0952e9d22258b2ef79355e82edfa0451b1d7dcd1eb3678ab33a848e9e72382a97a33e3b66732a87231f7a66e54317bbb97ed263b67e554f71bdeeaade487b0bdd5feb9c4b683146fdae2d9e66f431eb51f2c519db1767748c30a1874237a18bc61eead25dd7d641b780067df96d8561524a29a594524aacca480c6b92c381e1be31c248ec1dcaac0a5d3c0f087e5670022800e1148e555c51056b242d72387a4a3709f7d2fbcdd3aced6659baf66287344b46d1a245b3a47cd481b98db3a46856b679bccca259f276932d9aa5c309908b78971ff01b5a1acdca3ede52f8685666009066e51f978f3d7ff6d803e3d7630fcc711e3302de3de61e978fb9e7c5b3c7dcd3f2eb31f7ec70211eb301dedd66028b66e51b97b79dc83da0a4d2acdcb37a50b3728f0e2fc0e3238dc7d3201e9fcd78fc06c4e33b053cfe23e21900e7f118e3433c9e66c7e36b681e5f63e6f137588fd721e3f13d1af0f81f0b78fc919bc723d1c123d31280921f98f0614902981c600a4c458dc7cb9f666509a559b97bcc2b8f9756342b7b8f99f41c8f97539a9545c7f1785965008f597bcde31b8a398384dae4f0f8e6c1c1b67c0610635b3e3c7ab02d9f1d3cd8960fce8b6df9dc04c0b67c8470b12d1f1c5a025c655b3e0a28e229dbf27180bd2d9f0c2417711e2905f070402a4504909b1d70055c24ba226e5640aa081e44f848e1f0803b8405f2000b010b0410dbd91d4052403cc001079252c08bb848642920330e440a0808dc0cc4cd40fc01a9ab44ea2d1f07dcdc630fe42ac0be887b95e8e12d9f1937f7a43e0388d48138112a227c9c876a88ef50f1a0a10ae244a8ae12aa9e7b1e43dcef8879cb87c6cd3daad30842f520fed9964f031870946df92c800818b7e5937de4218e83e28143040ab5c3c7cd449cc745a21be2661ea8217076e840fdc0a188db80e1a308180a8021c3078c0ec68d0f948c2288b80f148f0f7191c8503e58978192a1809b65dc2ce345a0ae12a8b77c88b8b907c67d9c078c0ff1abc4cb5b3eac9b7b5067c9405dc6777c3b741ce7b3f19b0f87e69bf98eef2af1f5fc3836fe1b1edef2a1b9b9e73bcdccf7999f6ccb270108388b6df91c6047cb6df9641dd9c68560c11162070bcb8d8e9b771ce722d1d9b81987c5861037352e12580f1c867861d3825bf0102d3c5a7cd0d1d2b5601dd8103bae8305e7362e12198b8e1fee030b8f9b7db8d9870fc172956079cb67c7cd3d2dd7f102a7e536947079cbe7879b7b58fe830f2cf7e137a79b1a17e264737c91c884903909e037a7abc4a9e7c585c0c1e6c5310e578900bce5237373cfe93202385d0037d9964f0e1c0cf0926df9e0b859dd964faef19a8b44966d8428c04d09d7bce553e3e69b0b7191e86c6e16a2645300ace62281ddc0c106785b3eb9e6045811e003580dc0c60a67e5d55875ab01d4c03c1b37af5112e2361789ace553c366e55e09e766ef66ef364a5789d25b3e3737f7ac5e031462751bf02a81c35b3e2b37f794bee295ee1d5f2430dc63836b32dc6322c0077091c85a3e051880bc8da93bbe486c5809d35b3e3537f7802f404800f003b84874b847c96dc2ab44f8968fbcb9c774d9ddfcee359346103380a09961c99011c00f3ec4d81cde839de7c1c25c24d22687bfd8f900d81d2e92b6c9e12e763eb43a5c24d32687dbf201408c713b8a0ee371b0f3d762b7b6fe163b0c5bffc2626fb1f5a0c5beb2f52a3b7aca86fed9d15136f4931d9dc5866eb2a3976ce89b1561cf5e53d040155be0158b2541091572803b3b51a0812863c0d25e1f104210173692ed19dd56e223bfd9e6b117d99ed0edc198f4d4db33ef93bc837522202f7b48a2ed7492951d9aa477a624dd1dd08e61cb90a7428831c6cc5229a1a0c566456aa515513a8ca752220c941f2aa690e24914503cd161bc754ee9a4096d49e373adb572d289254c2891ad0e250f92233a44860831a2a3f47e9162d7e7adb5333a837408249bb9326cbafcf0d143c78d1a3534683a8ca752c6286727e91dda2a0d48200904458b31f274a2591d994829e5bc31ca9cb994326762153f5858c233e50f175b689145fc7e6413299878a267b69f98e289f7d133d1a647b31ac7c734d64b9ae544ffb415dda4a3c0b29960d94fb0ec29b06c2858f655abcc27d914ddcf17e552c229b897e0bef309fa233fa9344b0b9e6e354f87cd93e514c945b34ea5a7c82933283b42759295b24c8b32a3cc49e79c73ceab46dc4ffa868e0e65a9879c825b4a799651e44fd7dd04f79950dcdde3c6123a1d3fe68cacf76ece6a77f347baf9f5a39bc398faed669a3c4f391b8d459762d1a13cfda9116524b81f43d1ade95086fac98c82e56fe8681696c9211228a38004c27d6bc49f9a664d3abfce5d9d781d5202d09b153b0c42779cbf70ae01e70f7f1d63e7afbfefd6d0cb9b69d4761bedb69a39938a2ef3d3e279ea82e77da88934721fed31818050032c6f4dd322bad3675b47a0ba04051bfcc974ead789a133514a1f04fb85519d2a8dd449052db26227459d4874b3e851f4d0a3cd0f892ebab1c350945146aa53b1ec26b44965ba004937907073316a6ea36de8e4e72f2538f482a326ba421401f4e64925cb3e118eefa66c00eaa6e0f8a66be84cb40a15ec49954e4e201cdf92d46d61f68c413da31638624163116ad79641d8903dc858041c0f000cab5598b42515e8ecd884177a5d1856319ad5194e9a65a1502856518b6edc44184d0700b6ba5d58968544dac68d483c605b968562422cc4d1c45ca2aa51eeebd1a5247d1ded60b2d026b5ec85aaa193a2ada3db9645980068226cd3626c17572537ca468f744eda210c296f0e5dcfe24cfd15a254ca5c535e128bbfee9cd87cd42e89bd74182f994598d832daba892ec6acc3a2e8e6eef26a899a264b4c9f623eb0dbae4e26e6a7526f96da244fab2e5cd9bc92cadb62a94b269334b1008025c2a4bcadb4752651dd44976597e9a59a68f649d3d0c9f727b193890563395da7b0c3785a51957e33a5da32b9ca4a2c5b9f240a8b9e32afa068e8e4bf4e4305c1d7a9cdc734c678f371b441748f76e66414bb4e32a5f5a7a9b6c8e1d067593dbde23c8c21618abb89177d1b161fb1500a9b5776a7bc97cd1da60aad32109331c2e48884eb45a58f32adec8bc3d64d74af3686628432ec12d1d5163628fbdd048e972f6884899f2098dde882676ed36f39ae2d7dedc526616c7d9778ba85dde8193a9982e926ba4a29a594b64c6a812b681a494aee46f6ec286746b99b2a83935d1786b515580a86611887d338931b1d0335432727499e54868ee162e2cf180e10b2e982ba953174b92b954a479e90019332a9e0783a06cd64a2d36432995a4692966197a66955a313c482341963d6755269f3bca472be4a192f9c65db9d2a2f2164e10c27a5434cd3c6603218cdc4a2d3cb18c4a571339b8926a6d91023136b8ccafdf502bfefaad14718f9f0f5224978b0768cbbe14c18d7753286737238280e4dccd91aad1b2da39f0491ed1977a3dd1a2a9de4322f74211a9a2d43a1500c8d22c57287ce192343d372888902a697508a685e56a8e28a29724993214419638c3146296394523eca18a59432462979e88a525a65660bb33ef5f5594e76a3cd75713762bddb9d21f87526baa45914d39e39dec8b0eb3ada85de1b44e86868d8970ea58ffca44dcc7a55db211c57708ca733ce286a4fbdf4525e9ef9950f06348f0dbd3cf3ae8a9036f3d2665e243e0888361b8859d8c8f3c42c6c8ab091ef2418b4285b291c87900410ae220c5270ace20a25385e01c72ac070059c352b5611062af00aee6b240ac417995d708187c42c22bd949702f32b1cf1b27930bd1498779503cf9b71222642812d68b1005d1cc211a0c0b18a274c79c1710846e002cbd39ea9f966808024d074911f3d26ce5429b347e42217b948ba554acf3cbdf983c17511d774bda2c3be554a9dd232e4a710babc83bbef2ac7cd137082eb23dede376fdd560b3de2acebbb7511b77cba0fd72bb63aa5597d73bf929eebbb5ba5d4d7e72a25a7de3ae58a9f8e926cec905629754a87320fd9e64f277a95d2ac2bea14a9dd88b2a645a7366f984e2cb2ac57b48b1c9166bd55ca0c4247ba13a84329cfd3f5b5f7b6513cb7db333fe74db2d9f888de77c88645d74477456bfaf1665905ea5ca9542913085d8e3f4073a63621bac84f01cb6701cbd72f00cd99689345ae4a8930b24aa1320519f09439a5bbeb50775decfae42a45d22aa5d2634a30269a1585000628581e9b0283d233b2054f30279a158760842660a6d9e4e38c29913f21c039c4946c98122c5f6933b9d1a4870b7ebc20080c843c41a459591ea109969741a84e2c6956ae3cc03c8833da0b385a71058873fc895968218373fc41c931489ca51317952ba84aa9750a1cdccd6874c308330afbc8e8126975dcb7e718c4b5cee421fabcf947d02ca343a4c37e92de0925913bb36a540842c10d8e40825aaf2bf66037005dc4314675e29b6ac0f9d99422393a852e7f58c6ae99d372a75667ee682bf78e60efc60e576e462231e51eb567569b358a8ed317c5789c95c79a9e16af748e76d26b7a8e462befe3ac8cde7d7a9c1e6999cebcd1381c8d49a64beea6344156f7852f589e7237941e46f6545637b97a66257eb35697a9679f37bf386a766f392a87aee0a89f37cf539c1dec3dc32bf1daf0bec2217a3c8e287ade71e2ce0a7db5d93b7703748f43acdc744d6e2ba36bda111ef3d2af785f89ae0dedf538f5a2e3d42bca478ee0f998bdb3d0ae3fba5e155d5f9d69a237a77bbc39304e7526a65767e2ee52183948a79f1c0e182faeeaf4e6964bc1ab7a733b523b52cfe8ccb81cb93f57ae89b65196ba3903a12ddb412f5db959759db9ba7907677775d5c7dd7ccfecea28abc2ab2bbfd1e7cdaa6b994aa21e391be0471a7ddaef9dcd4770f7ef2b4faddc2cf10abd14d5e378af9be8ae70c48b8e132f9ad3765fe9b9eed9152bf17cea97a55fe1f0be729c951d4cef0ac7cae97156b8d339ba39dfb5ef6a6de3e8b3f3916b7adade733d779a1a6917bd6d673311dc3deb10b9bef2d804083dded82e2b37f7b96724b15de2cdddb92a3222f1688e6ecebc46ba36afd9585959a111afac7ca4450e6707afbcafea47dfc1de5dc58bbe83a9f5de967ec566895770280e8ae39d3e5a1cde36b2da2387b3f2d48a8df8fbe9299b93e01dbc5af90a473f1e6707afdc150efa95e3783713c1a99bb977576762ed2bdc77b026f1f7bd667e9674b25908e6ce62f311ccfd9b33d4a6549af31a91385870d64832c52b2b3573c566a73623c1a49e501d691abdd3d2d0006364bef0c5f418dd076e1d9e1b5d59f144afefbe72f30e5ec9f0f43e2df7c8adbcc8147127d9887bae6b93bbe1b0bc3a1367e3b69b3591c8f660d742a18c89094e4af1f56da1a3b7f3c0ec39a53b2591b58236d064dc0969f3f6fda470398279d4bf8c4641fbbc9039d3a7272cf4ef7e7346bb22d4cd59566fa422ef87a78d909965353d4dd009991dc0530378c635e09963196473f4a4e39ba7941022738645895c32d2a0b07d162bdf59d149b67e644de7bc6b76e591ab69958d362cda8f1fa95b4343131f0add0c60970fdd0cf8f8c0ae6720f4beabf879441e25a47f7abc6c365d48d01d1f99127585cc3e51c12809088930335ed145eea6c8eafb2b208b9c4e7f3a3dca8ade6fd5cb9feeeabb3d4277757ae83b3658e83efa2124a2f74fd7877ce8a18ba46ad2ae4e97dfb169bb3add9fbe13ea4286342b26a18a169392ce14d9c2708e4152c97c52851653c0592e71a2841638cb261feaf483074f3c570708bdef23f4be487c4ed72e92eca19fae0fecf222b98e65e07abdc866c0c7c77557a76720bbabd35d1da07fbd08f97a9d5a04441b966ab58744dc3ddb7dc5921eb91e2cb7d5eab28b5ed3970d9669f3a379d27c37a38d90e93283fc6861af6f65bf2eea11028560737aa09b1dc89c2459d969da6d51674bd9fdac76cf963de7a4731ae119564d3dc3125d644b0ce5c5e1184a9c7370ed1bdf338bf9d24ddffd3a1b9315b372723732ab3488e8728c72a3593a7acc78c58fa6d4521a1dde1a1a4c43690731c1f9f419a54055c9139cf04405590035090194afa5b4a00c381f67314218c112274e649d6346d9a31ec9ddc47b77e85a9dc435dd02cd470f1df3468735669d351dc6d0fb33449f514a23b3323161c4be6fce5a6bd5a978f6c466fd81b21884e38c2ef1f3523c392ae9dd8e30bbe79cdddddd545e1d899b1a81fef0f0f03c61f365b1fbe20c834623d39146f802be69db6049365da664409d05853211c63dcbe0484303c73f472829d5eb25922251a8e523a312c48528246dc459b372b8b514619c76af140a755917ca42215bfad6bd746c63b1a6189ebe1a2c37b29cad6cb75add3cc4a4b25b0c4faad76896ea662298e5dda56c16c393cee9a9d76856eae62398e5fdcfd2189e32c9ed98f87b0d2498e57d948d313cdd9a6631d9adb99b127582b762638749da48bbb9c3a29b658fa1a881546ec7c4d96f64b7ef4317bb357474d85974f5fd1acd6a99d046eb4f8e89813bca8de9d23130a53f6e807304ba3155928b0175829c18c5b02b06bb688c4c675796613d5a12da64574c5fe6a5ebad6939e59c35061a9531867d73d792de4687f5d4f65c97766b975a27a574d2d936c0b4eca295d56c120a893ea16849dc27dc9f4ee69329c5a46232d19f4b662813cde6a21f238ab9f21d7b8ee8d9b3e85b871c0ed1bd5a087b7f955d74b0c33ec9f469f4b77e27c27a8b06676b2a993ca2e7c983fba2dfb4d8ddadc32b8a0e85a29b6d34c3a66d8ae475041e5cdf51f4939e692adaa51eca1456fc5c11050b29594cd102d7b805aecf4d054728a6684297b3aeabd101d69bbe9808e52fd93679c02084ba993af08bf1175c6570a5119ff5ccd62ef5b1ab6db318ca224870cb9594194d8d9e192de1e1e1d1804dbd690aae9d6370c50110aef5090ece80338d0f574965532953075326868632a17bd875fc692d6c5ba88b516e74c3f1aad7d434ec0ae3df21b5618772ce18e386b3bf342b9b99ed5f7ffc8cf10ed9f0fc411534c654267ce4172caf550c7b08c3b07e560f83d6c66ce80abd8fddc7965d2f3ae4a50e79a94fcc39277d69abd32f7d4adfa743a02ffd32040934a25532a9553269126566fe3c51454a219dc8297eaca8d711242fd7c8cec6302cecafc33fae23d3453e0b1d993392c974916752258718d64b26a21d702d02f7bfafeb32ca809c83669bc3711cba404d484698fa9a9ae42674ed8ab21bd7846e03712d5a811663d06c6b5aebcb457a0dedd31c13db1ed2a535140a89eac18df60bbeaea945775d610cfb2fb87de03a925b9c122386fd8302c9315af41acd12613753dcb7a6c319ea7ea1fd826b072581f3b1cca494198c3ab4440dd57a7c89ba0ef737e79591627a752aee1e683146c67ee6b19b378c4989055d4217b1ac82dc425907854e6626e862e20c0c77cce28c0cf717e375d5b442172f6d76e72f7b44c5557e66d80f0bb06bda39d1761b12733ef2761dfa90bec46d46d77470fcd7ac79a5fd649eef3adbd1d0d799be8b3dda211b9ecf6cf7859ee5e375ed5409dd76eea451165d7c9fdb2c0dc17f9bd714aa3842942aac00147774b18a2b3081411cabb04210be3e6d3cb545305c0409fa24384698f979b391898b1899da158b6038de2ca3cecc14477c3d7dbdb888bc5b873262ec395fafbf2ec65e3f6f4efdd661671dd622baeb35a7be0886e78dc4d3e7d4cfd78b1325c7e345304c9f615a99a06114c3303a69bd2257e426741b12639a48bbb61832e108e2f87cd3730c1ca9c9d26897f9d9591a126b72a73d633a77bb6b225b43239a53b3129b6ccbf4256e1342027375e52fcd5ab9a61ab1c9b69220627ae921f72843f3ae6132f628e41e61b41b7237dc6b26c9e61dacd1d0a8117572c88649a4bbcaa15160c3dc7dd1b44f118da1c6fda559dccd48b0487b0cb51b8aee4b8793c6a4e9709e4687f334d40a1a53ef741d6acdd9b3e78d59bbd93c35c8942037b9ba2e4c4a29a594524ec16ee8d0d103c3b0ee1643d7fd9afe2135ac267bad71b56c0c3352f1d54e1a4341b51aed1c4ca7639f5ecddd54492b9d618817752d3a638c31d22b74d2c96cf9482d46123af9f050baabbbe86687e7943dd0a28d0efbbc9481197a786ce825a59fbf9ebf9f38253e67c674482f2d8d91b72774ec1ae57260cfc92eaf6538b63ff1bc39bb11893d0bc9f44ce8f431210bb60bc531f4f3fb7a645f97bd8666353aa4177559289336646fb40c7a8a84aca6437a6b7448653aa437a6439a96414fa37439fe6ca14bc7cc9765d9bf0e2976df217d83a1cbc00ee9b3c7f8e64ccded11628abf1fbb3a3aa447e8aedb65d1085d7cce2250680b32a803f531c607cadff0d133120d4faa48624996c1325a41676c1619c2f0c41631f41d4a8d5d9479a75afb7538ef8ad67483b48beef72342179fbf08449b8ea0490c8056b0849f14bcc18994288a332e599bce49bb4a7abf2e765f16f954b22ccb4455ba8e30a2d0cd599665a26fab1ba06ce8faa1d70d747dd19431a956c9d55635d0f5b32c88ee60c61e0f630b8dd60bcb42a24c44eb8565212c44a59d4ca1f5c2b22ba3f5c22a56453ea1522f7a55914f689df1a70aed9c559e96dddd1d92212644f13ac51e3b0c91224cffb2a22eba2344b70886e3753309777cf6ac66d305fb75631631ecde385d9868940bda74522ea6ac314e259d3fdad78d024729706c2a707c22bac477bfc10952d61a92dd72ca39eb9c95448a33ae391ac51995725c9c41ebb6c519f3d270cf684c24caa1d085e539eb9c75c638639cb456cae262186b9d34c2cc3bb1ce628c31c6186328c3442dea82169b25654b396756eb5ca269dd6ab55aad56abd56ab55aad56abd56ab55aad56abd56ab55a2dd38decb268067a2fec0a1c8f6152703c354397332ccbb24c1b350ca8121a33554295501a8f34c11289132c913841c2045325d20a9a94b2bbe7c471e1186126d763dbb278b5c07106c94bc639a232b39840b5d6ebba32ba5501ffcf9465d996519e186178f00bc2d1b4c9a08dbbe138ced491381c89b592575ae94aa552a994d2caa069ad4417af45ebc4469be5136b6dce6c9e4ba6b4132af2499556a2cb198e6ad056f111af6c481c6fc412939ad668b15995d2ae3289269f75fdeeeeee6e493fa5a4934afac99ce1ee70cb7e91ee501e3bfd7579498cca7a8494b788bc39f4197da673f63f846c7ebee8a03132319bf68e46306d6ce4c338534c69b53b143b5604c335646485e9cd7986fb5286ae910c4bfaad8b15d8c1fdbe3a4530dca324b4c97ab24b233dbda8acd2093e82d2faec3232b1bcb9d29766d1f93fc1f3319a55b1945a841d9ce59bf2f0b46a38bfc46d92905dd8f8c0088a5c1229e514917e87b624428bcdeab249074a6394b5d20c7b56ef1f67c7d4396ba0492ab179a0c89e74537c3f8f12e28d064849b68489166350acc2132593822350f61c4393655f3b8931fe890c60411a3daedcfc753777a4dbadd1cd19e0a2a6b3a0499a7038e2cf135854d9e282c62c769acc08858a8e81753283c18cb2fb2bf5c61972a7ca9682169b45e575d1ebf28ab123d12d747252d9f7a5431ae3baef303e49efd4a64858810f64341a4ddbe69c73ce39b5ad7ecd021f23143d728fd165fbc8c6e8b2b97c4a088b900780e365c499af0811ac69ffe64c96c9c881eb69b24cbb8925e7e02a1fcab0cbd46dddb708125c65e28ca67347d417152a18010ba6c439897478a4654c7aaa858ec83c6285b48cf9688374384fb130459e405bf998fd7991c82820e10b3c364892c8102c61041e9bd947920415862cf0d8cc2349429d78828acdbc3ef149280ace10c5a6af8ffc8e4d92963eb418436a37f1f415d37ec431709f761d52263a39457775db35477d4a47d73c66e7bcaeed0a0992cd67dbd442f7d1b38cf40aec60ec5d7c3d6673e2abc43e391bf45777e38874cc921e49b747c96db2bbb58bc4d9e866dc15b2dd2059ddeacdba2c74f49d5d3439d085ae3d674b60557ed3451ebb34228cecae2ba4de2058e866044a4277b07919e1890a7830839a24215b82659ccf5ec4c46806b4cb1f31866ec8b6e174913fb0d0bdd143a3d8b317813dcbea3c765735da64580c8d282626c378b03ccf9c5955f94cc99c59d5471becf287ec42bf21eb65941fd7bd51e97cdf8833fa5ff8b2d04d216b42cc95578685a08edf14ba262001779f0a919ca2c3fe6919fdf981ee334248b3b0e718a45dd99bbb3942bb344d14dff0838526ba6a3645b3a8e84b2a728b9e911a008a4380d204f714dc520bdcf20adccfae288388387eb6ecd10505876ebe111d76d8f5df9c8936fd6a3f0f74f4761dc882ae8b0d4ef8cc0f74f1924a19458e26e8e28c88a5945fc0320b587e8563a79e5228641451545e12ba1845fe982e724e0d7cb467866cf8eba84629add8c4e6f57a43bb8e7237d71cb2e15ae9a5c086af9e4e3027d90cdd0614138a8ea259d7fb494bd154f44f43c191e69692c5708b92058efd8305be02472b70dc74b0e831dcde1c0e8ab5ed0816c5186ed7684301c5e4724cac3d6e9afc95d92a563c818fa038b7942a1df6b3a882fbfd647e5fd701a117c59c6cb27221d62cc3b06eec1d0a6559c8ea501ca2d865fac04d1b7159a623c5b09ba2d36b6bee66946362aff348975fe948dcd5a8c8f66cda26b5cb1d18d18d3ddb43f6c668977ee56e1e4a1cfaa689280e856cd8852e84134386bb11dd1851f650e85287ae72600f3d748d509c5d7ac10e9be259ad4c8734315ce8e4734c4dd23ba219228146a97d99b466d945d9cc324a29ad174d18435e703dfd00a5b5522abc9768a1d5e3b18a2c7081e7656a7c2cc102cf9b7a46da4459ca9a1461e6358d740a862ebbf7958bced9234e473ddaccf2782c508163a4d0d4e41820325788827347034f13ce3b47c408a39365f6082345305c5f4476818b603a2b1cc7dc23e66e4e11d905aed74886b16738fbac9cbdac0c8d96d922376a582345b022343231f5d9af634778ef4eb247988c4cbc72942d720473d7aa5d491860f9021cb96aa50b701639e904470e23d922478a6078e59ccd319dbb96d9236eea2d82e11cd4eb23b7037573ae67b81e27e213cb35327176f3758b60987bbdc9926c4e77495fb1d9bb45304c7a96fd38bb462626fd6856ad3ff7f91e51e0791fcda238abd5669291c9d923b0932eed1145305c6fc67ebdc8119c43ba520b55edc608d3bdeb48b7dacc66367a8fdcf3c419f7dc3893987b9638e36e7673ad4590e0ac4eb0c3ecaeb2d71eed5a4f12db95dc66f41861483ddb8d11863b77449118618ad4d34498f92215d8c1f57e1166be5e5387a4db33ba32ed327bb66beac768977991a55153a35de62f0e47e27a0ddb64d7e18ce9f0d7638ec1d95dd54b277865236b01962ca8d78d4c7c3d93f0c46e110ccb158e0cd767b85e529c11710602cf98661999583e495fd816022394c009ee01472338518666ad72cc5fafd799781280feba4626ae57e7c2b5f29037d7cd1288878707575353e9ba1c5b43319bce6cce396b8c898539a5acb5d65a65953da56c59ebcd145b1a1d4a4a7f56f0016a8558eb4334746fa4221ab70ee5754d34eb14dd101643b7665aebecc2d6acbeaeabaf9edd7376d9e7ac99146156c6b0c366851dce1ed1a5d12e73f6a45983a1931dce8742a1be665fd7bcfaca5e0e6ecd6a13d6d7187ea0b002dc8f439ca48005ac4e669af3f0f0f0fcd8c41f1c2bbd9d932570fee22441964093095d7cdf3c44020d914053d0a413cd6aecc3e363646868688fbfd1ac8dfb88e495be946a05b6f0340bc6e365ab59b7d7097a1c9e65130044f9048e120a1c651438c6182515b88718f32ca1e01805472b708c8f39b03ca21e05100a2014c0cd48700e97ffc1c6188639c41043275fb20f1f6c8ce892c5001263ff203d5810348207fb7d4260acc934e4c5761d9100d86dd3d9c166d911174b63984398437833121ce3f23ad818c31c2e0062e070a3164c60ba059e57a2a4cab5b2255b49b8b056f2481e9e5b245cb460d8235594bcb03a5b30d16289042d01ed102d9c5859215498a8ac11593449d920310472f2592031a447591da72b28164fb0581ad185de64a1601aadd89102cfcb8e468d92a5a1b9e15919191d2bf625ba642f3ef00cc31f241b23069091fd837016048dd8ecf709c1d3641a22b25d472464371d3cb318d2ec0846af19437a63cf5412bad349e40e09239981f696444fdaddddddddddddb4298d41d3475bf96824338a6e5584fcfc9c512469c94393262a50410a52800214306172821398c004252881134e9080042318810844b064490842d04413200001134c7ce0031ef040073aa044090738b0c4124a28d16a2591c40636a0010d481ec9d345176f78831bdcc005176d68031bd8b0863554a9a20635a4210d6840c3165b9ce10c66304319ca1014047e3a14771b11dcddd4a1b84d1b8db16d109bd25a1f638759cb88a757e87ae6e38ded22a56d9d39af4d1ba35de2435d8bd27718e3f33b397f7e80e5a38ce9275af7d424ba9ce1d6aa6dd593b6256ee3337ab55bd69958a4a4e34eadd06ddddd1ce53826babe111df6b568a3437d84042b9ce048051c91900428180949f8e9f4db462d1f93163ad44fcf99cd12afa0be72f3677586d0a1fe1d75ede272a03efaca3d9b33facab5d257ac573222b187ba67473da4ebf40ce9f43ec96eedd244e60cb5199d6ec67285986e100f74d829161df7eddd9c2179efd2fbfdbe42d72bb74372afe9cae1689c3170c52b1b8d36b0c3c720d92ba77ea8e42b18499b1a654ccd0c0400000803150000201410884442916844a8aac30f14800f8ca248784c1748931c87611032061963004100000040860668140a02dc9200d57379a4ac196ca5fb88b7af5d64008ac9b8882b7c1d99403178209922970de1f7445f1e7aa8ab24fb0ce8b51c7383fdbf4919b760c82ec1e5bf1af2d59dd0e7915c09059dbfd2ec16e03df931cbbc25f9730bf35565fa29a8b9fa5b191fefd507fe70597dd9cb755a28d5ff3fa90ce35127681de82432ef37e8a55066e3803a2e49b4b44c424c3c52a6a6a2152778a28917263bdebdfa2331a1662315b3a150c3c522b6aebde5feea333061aa81a98ee1a24d63844a4f160e17d06983bbdc9a8acb935bb888048643eb284f0a14a2aaed52b848f564e405801684f10980a952af848bb44730c76b9d35805e8d857f3282529e4f223adb220648c25bcc6cf908eb65fa9b854a9042e19db56c087caed06e9dd2f3adcac5bf2ea26226dbcb7ee29dd280d75d9b4fcbd14db269399571b7078836a8da17f9fac13fcb2c26d657f39e52a80154274f76c8b1e5c6c2592019c0b552241bb46f010ffa6c739f0702c32fd05b5f3237e7d85b3811595a1022381361132cdc2219ca9e974a3acb96f8cc95f186e0d67488557fb783957a676ed7a2cba312aae7d81a25fa2476ac4b2076b85e5a8d245f901e13d35f498a598c1767512033f29031999842cc87ca100f5628a3e30951586dfd9a701889ae3f4bd54cf1b633c5149ef860018cdef3cf56352bddbb640504f64070268d735a3a05603a81ab2904a39f8d02d1cf0ecd9dd10b477b23d4f507b4713ead5269fd525144bc0d3915c1b118034815f9574031d732b6570e5ef82dda5277b5054e0e2374c03a03407f10f546468c622078c8fa197293d9926bf021b8bd8e3fdc79280879025c1e378d4f487722baaf27c1225a0e80d2ba36d432889264c9b18a54d7ae98815debda679ebddd1f9f2a90c56e6328997ed0166330821bb64c98e80bbeb02058b7a3529fc1dfc9d3cfd9842683237ac01dba456937c40c25069429f1dc5efc646740f5e488fe8ee832bc977c6d17d2bdf97ca25847838e78fbdc620c51ea018ef8f7531ec314fa87d80699118ab1e496029a70817e59b5f0c6d7fea2e2002f16965f0cba3d06ad286abbb4c164e274b71884f9c8a4a1ceab617a15ddd629fb14a0cc55b4f6f60ad4fb8f50662c713c60d45727ac4aad5827382c6b0acd0f76755cfe774094dc126c0ca9f60cf6f71527cee9fd49aef7108335c569af42a1a87ad32fe9809334d339c528a5c6d6d6014516908254043504a1c09891984bb71a711df44e14725ded47dae2db37d2323a5ec54e93e2ccc726a5231aec7ed333a6fcb7d7ba0a5887e48a2805e8c8f2479e3f70cdfc5bfc7cba20440cfd6ae947d86f7adf5cbf8644ff31bfc20337a2e597418ebb3ae542827b494394f2ae2d9425c66af0f2edd5145b3a2bf9e05aae838040c09e37ee8993a5f2320cb23570ff2b232e3a41e634ee57b245ccafe5a6652ec701e3f69b7d9715f5e72f95d5522737e8ae654f87b31650dc788f7d5e105b44987ad29d6b085daa147497559166f7b100b2d588f18dd4abb9cecac9b824e11ec818c480595826c44af07305873c183511aa6164b5220e15b9f2a7fa9a72c545a3a40eb9ed61d653a3a34f314e4e728bf9d73239df252efd4ea58bdc85ddd3d63969069d34b68c1964c029b8f466afa77036a93c57b87d4027cf85f10ea33f4c44cecd64c5c121513a84b851190e7a6993c0e0ffdf761749e93b55d1a4680feba7f5db120c0df28de1d43743dab0a2f68f97889d76fb4318a0f53f35d4b83cfd23666f5ac0d44879a8b492502e7e69a3a426967ea3f1d0445a060db828e64a4bf679ee57c4f243ebb31bc60b437ab45cd761c493b8b7cc25fa5e5a37c3468f1043dcc2fa00f5bc9d8f859dd68cb279021967270cc59a36ab33d5df2bc319b16e2e5dff5f4c15a5b58490500d86bdcec3bcccbe7da0c5af88322d2ae4924eb6e260adf97b88604e291e6990f9ad40d3a318bed7175ec00a6d82508d2b330fa52bdcc5e5ca2c29ce1a0c207ef6e4fcca4238173e6fdb02ad8470f62c704947677a46c6a242984770b692e55635b94936720f878b5fa7c78bbae0a3bc9a0956a8b9ef856465fcdbe076fb76996803beed085011c3f06e2af96a48ad2c111f5ed69eba40d07e83e507f3456d1001b2033f7f7bbf2d0eb22cabe746c6c66de3a77a5396e15c0cb467aa5c9ebe4367a850b3cc156b45f2fcf47262ab3646f2d9cc5b4b049d478c923a4ca55b27e8130a44ac8f80ac4f090460734f9b961b6a560114628c15b9040488b63d18bdaa5655c3140cd6e3c942d29efc793d6caced31702299641484d9aadd6681349a03799276da8b7702c8c032791826f58505588e0e2da58822ed8917c5a77713fafe7eb1b67d1f8bbe2ff61310cf7f876fff2b4d41b1e21baba5fc2b19d8f578407d26de2d6c640f47953034490f58f9d219ffe8cd55e6d0c1fd860d13a5da45f6e4947ce6363dd872690d6647b826cfac9f8e05581e7c10a966621d4e3f9f067c6bfd73d1b2fe91d5c88e7bba282e7a9363e6fec01a07bd38f0fd3b7b296de6be19efdfd36d62b7729a015853542c97acff0956831ab17f5f5bf3f6f576b1f3d56f10f627a9c77418b0a392402987ecfe8d48ddb81b88a2a2475d17b9928ecdb2094920b868c33ee0be25918f4860351fbd1d166222e90094de1382d180f75361408106d48c322a1e9119e46c74852d83f4ab961dea1976a99c6fc9502bc49d12c2e3362528e8af9bb126b2bd1ac80969577c66adfee63c8bf44f11376f99287cf879f02d5a458288cbfe787c9e045802cd57c4486152563a6c3a19b697b71af96ad2d4ee75c39b8e5635bc4928a77645822b1ef7eaf4b16d913aab7cf22575966001ef4293e59c6b7fe23d14d1d95d85ecff3b9a8c738d22fc589d255404b9036f5f2b2249dfc5c42261e89692a050040633c4031efa2842a4b5df752298109de501f1d09c68d0cdd38a743b3235944b02a9318696cd54dd662167796bf02266523b1be0848a1827364653795cc8aa25c999c446619ff8f6ce0f80c28d579a418cea408768a6893793389fb3bb6071f4db1ccc13769c45d6e3acbf554dcde9aaf69a42bdc0fcf47f8cc7c1bd95560cd1e20ba6a8debe3f357409fd6fe919c804c4b9c365eb7ff3c9ce30dc110301e14416d8ed16c308c3acbb2a0ca140ba810d72ad195ae185a96d185e50e3941ba440497644bf5e3d512cf7b62753328002b213415e89983efe9c549a94186d54115635e6fd32f490d5a048d6378c503312230931326de034859cde0d647b0037d1d43f35f8bcc8fe45346d482f15bc29656f4e8e77ac22f0ae3a73e12060a624082d07d6022a9115b2998608956c2bd4398fb1789a09d59835893f10f41dbfe0bf85a106c1cb2bbb00d06c60a34e24fa5cd1e7f811fae0effd7cd8a1ed36b03463a4cf09f9905a5a4ec677563f4d5af0ff538ebdcaeeb1e504665ef1eea26dc404687a3b403e9cb0e62874939fbb30646f15ff41c3b3569d63caa8392d26fedd5f31f543f041b71add8e0eb0992c370553cc860e87533e11cfc5309a48d36f20d946b604f0254f28db6f83270f21a0881d4f05af9c934a115b5bcb0e0e1a8f10d6b69ca4e4a4ae5ed66843489baf89b55133e34623a2aaebeff31ecc5896b728f9943566c2275c7de2c6afb3c4b11959c21045ce68ac3b7529cf4e863a1bf85044c02fa8c171b81957b6d393740e09ee58c13d43d6cfdaeaf2aed3087ac768e9721b574bac393774d9a3ae927198a124591043312caa72b3fd2b22fdb75e97e1c4201d43e3c13cf38a4c7a164130533d2ef507ce5815086032cf0f93bf146b4e8a3561ffe87733855a3415890fd7b128c6d0ca7a3eb8ec1f7c099b01ae2a83fae2f1ea56310af7e14fdb0e805d5dd9d9ffb8cf6ccc7ca84225c81772b220c0888c47079b9b2dd5eafa2eca40ead655ecae89db4c8750f813915f5babc5cd3e4a9d46f930dae17d3a9c2db78ee13b4664c47b69bab5e66cd27f3adefc8026c28c11086fc2cb5fa176068f94551330654f797feed6a152ce0aaea585a6dde42122ab73270d82bf1ddba312238f0f9ef298cf27ab6d664d2f01102b8e25acb2583a510e42f472a01697368710d9aa4550c964cac0fa01b11d9ac973235555213f608dcf00039ac38ab6792496208b951fc56c63f7fcb58930236395e991ac442645b078eabe0c90ef52e17f85b849354dfc503f3b84d51a151528ab4a6d2f6f17d54d95466e3611c64162dc6b15429626879196b38ce860e336f1527d653af4a0446ac9f0100b21a94312532f518d3781990863faac0505947c486faa6ecec48236595334433b2d459df3bc13133b3e96008276fec6de8d57c37b368254b60de1992d52cb7fa10cbe0eae85f41215d44fe28bc195be8b11d642ca0553c2730a8a7bae02406fbdc16897868b0d3cb3d76ad430b4946035b446ebf8c4a9156423cd5be47f67502d1f606719a67b5b749b0246fd5dec18c1fcdf26b6681bd797b3785106b8e9a9af8f3b41706142e7407045398ed5068d057fa5061c680e92ce616cbe36f70d6e0923dad53e65265ba32e1fcff13755b077ee93036d6e6b5db7ddfd13aaa64a46be6e8a74b133735dbe94b3d38c3a05744ff8d2aac4eb2217819a6311c438f39215a7acc7c7f6f26314f9349de5b8024d5897ec8e042d19b4b5272f7d0283d17704ec836582108cf91e1f406214d88bd3e3cef5f432c7bca56adf18b4d1be6d15361f81502f748a4ac4e23a6396819277334d53050180f85dc7ad445873e2a6dbb068052f8dc6577a8dd7452784974adf286e74c24b5b18cce47b15dd25af6318f4d0b95145b3b140aa1cc8a575e0bb5d590c17fb948e6aeba3f15ae5db930b8bf647a36bb1328f8f399b66ffa3fdf30bad4b4003670234ee4b0ad271c0c6049174bc924112c477164c0ad1ad2481d7246ae266dd3437423b05a23ba7c2ba6a6b8ea2457ed13914d4f3069622c1b6ef2860337d6925ae118292cfccb60bed8fb2a794ee5b14503904306ca04ddb0383d18b959140206faca09eac89ced56cab73c8673a6397fbe6653f5f2bfbfbcc04c5c07c5ca0887cb7485307e7766edcc48b42b2603cdfbf9daa4f6f84bd4286638dfd53506928fe69a072815be11114bcde9e9c19e8fbc91e33aa647c823786e1320087b5681d6fbe6f8ce8394105d8bf06f2a3c59834fd40e0596e5d8ce3d005f81fc156f3ebfce6842aea98a635500aa6eca6e76a64a4d16626883daee0ff45ab5195d0c145e455a0d39ec110ac82f58c3a449b0aa116891b38a75e0736f31fb264cf8ae1ca0c16b74edccadb1615fd35b2ed3e8f1bd098b5735bdb96e0a1b7b773be6d007041fdb105a1d9cd50e418e74532ccab075add5e07a11b877acfd671ef4a781db0605de72e72a578f04d2efcd832b8ec13515ea14a3475d6fa8446765c9bb0729935c181ef56399e2191d24049558ee27764e19ebef9a65db8cb1846c035c958efab761c24793441ad8a7ebd4b9459db0bd29d5ceae7027f31c91a8c35a90823839c3f4be6408a474d48bf89a2290328dacf58a11130c338782278d8e4678bc0befe6ee2de37f839879faf37dbccfcb8713ca495af3c11fa9ab28c146d5083578d04be37fb3ef969e4ab70ee641d35a841a37aed598a3a2bbb3e231251a4a344e2f82c3ed7a2ddfe24ed80b228a3dc7eb12d57e95c79acdb3e1766d4762bea3cfcab7460cbad70e24ff3f37e033cbf3c0085aad76f312ff787b01233eab4d1f0757f18b5daffcf8118370eecc62597c50b3a8032af5783af4a5da5cdfc2aa3ad9acf67bcb1c396049153bc28a7026ba5f7895391d30e11ac736157a97f1d55fb90fcbcaf543b98bf3d28ef8bd5e7bbfc70bdaf83106dfd6f247b310faebe0af1b1f75279b9b047c8ec1f469305b21ac81b8b0028211ae36034ad512f80ff036baea7453ccfd633e50b03abb69e3b8d0b5264f78a37f98e390e91882f098e642274a052a232a48986df9c49e34bfd78a77f3bfed0119d7677198f36d45f6c912efe9a51a5b1c60236e640afc03e2d6d9a21dd8d29161811013d4d0576c233d9a882cf830ff63dff906dbeb28dece378eea6d9cd1cf8a2524fd03a0a773bddab81611530ab26a6b399d716d7a62b24576c33ea565429c07bf4558cae38ffb709009c436442488d5b5d2651e1ee722a164176ff8984eb6eebcaffbf3e35ddb969f5b5cff2e96e384a9e9d9bbc678d3c054fb9203586f1c9a523329eb90d07e6225ebcc4a2d092ad591447bdde49444aac1daeb692e802585a330b424c7cc4b66213d7022b6c866c1b4fa3360f26fe4171e282c49d55ee018858abcb551e953166927b63f672620908cf82146bdfe79cce7e987b3a60a80abb2f192773a0fb2fa8a163ac9bc5382dd35e1fc1562574d4c90bf9aab64ae6fd036cc38a0da67218082c119e7a68fb523f3d2af0f4fb6f2e825fab219ee1a147dcd3f5a90670df19454cb576b7a75ab6a474d9c6f083e1d84fdebc9d0e3e4f492c3e8595762bce4db93689df59ebffb2e8980c01eeafab729e3a3925ccbff65fec5af930e2e42fdfd3fdb25977dc5116614f72a279de693b26d49991769d7c7caacbbd279306476317a088befce684ff5134064482b335d47c65d20b0ba2ef77e4502d3c5c334556c22fcbbf3bce9cccaa9240fd32eb30cde1afa92347baf837cfdb621a3e89df3c0b8e0043549b1e774818daa40568389e33b6a74eb3cfefeea01e8fe88f6d7a5c38bf817f4864149ec0b9b86d9f243715cc6d17457aca4664ed7a67c6bc869f3974aaa9cf17ac2d2a82515f19e27896621cbae51377a3a964ec69f90a7f6f1d837b9008f36e89ddba1970e2c4b03838855e5469a0e6291c144c17a308ff390999342929ca4d9634a7b524eeb151b1aaddd3c1d24bacaa87ef14c476b2cf946c585d3be12fa818fd72895a7d1c622eac3337741658f3212b6380c9f30863857180bd39a8f793f61e7e86020e2e2397efa91ca5918673080d430ffa94575ffd2e1ebdbe104ab121e434181e8fe69416974681562e430faa11f4d9cf5cc2065fcf8ca90d03f9d46197f348d869f226bb0121444c37160389f34d28455cd1bb4f48962b5ac59c43d0f2aab9d4b7624e5fcc9c232908baf17355d29cdfb863798e643571e6e824b94c1dbbc56485181586b415a8c0344f0c93d1ff8b9dfada96ba46870e96274901f7d0798ac36a8561756bc98c1309678ae382025c179e59026816e6f225e991b0b948361f291487fca2430d910c0f4e7a3dbb0ca0fce25322b7a4bb247adb8c925b97b1228b6d29b4381dc5a9a66eca5ca7555cab6a14fa6f12dcde27ecbd8106f72dd66c97192e08683b84142f367baab1f1c59e90d0cbb69c00a85cb4f85566a48783dc8d90a2bdcb55f51543673122a318bc37f9c3e1fc7993ef33b18398c13e9a94781e22a14faba3347fad036b0e82482faa0b22a140cd87ddec262f2779db4b282686e9639fd6f423d48cf0bf0a91e8111e4644dc4442e52eae2a1a44277d24223e87849dfd40c6545e3525503c2560ca0629262fa250098c4f772bc5871491f0efd167bb5cb002622b11b15dfa04c9a2d7b27d20fa6a09c2e2c9a19a69401f12a32590b3e3a0ef6e28b82f7de6d517414f668b03630bb373ad60cbea204a3d17ad163e06268b0fff081eb8dd8a333b7f749b7f80320510c9391886863257ce2e57762d3e4fd538cf81f8a3c779ce8fc1781f5349eb5838570dec20f30556cb27c6c8142b87978d07878c058d0ea8d6d244744e4da4b8caf4798b6d111ef7c8d3cb07315080d28e2bf6212aa0fffabfdde00d6b60045e359e143db0005796313f74c50bb803ef10b51a4b7a9ba4fbe17ea0187aa00ace6996d1e7a63fa50c7937dcf06a5f5a57c20298c613b0c2c7d327af0bb6808988ebb2df751d145ceab82e36de16dc5a57c4df2a477ff9597f21780f2af4e47fe90dc08a15608ec6f89b85840880cec7f5edc8330f4ed653656f7d1b7a95bae5e3e3032c55d469bbe7a767e0948ec27052956db701619763ce4c7f38482307d8024a01cc493ed01b8543b41e0fab77b94a14db83b883ee4e1a45ceaa06d68414dd697171bfe9bdd6c8ddcd168b992c79cdb3468970f92fc9faacfde9c333e44a1e72925e5aa612767561ad074328e63564db8acf565d924db8764038397ddccd447174440f58bfd6ebab1df64e0068ecafda0a055a4a756a68d4a94d52a716651db44475d692d649cb66a5ba00bc02762b969fc5503b35df6c79b488dfc80d432cc3508372dadc9e98269fb5be81d47ce5be43ecbffaa8b134badc7752fda3ca04fbebd2441221df0bc9764e66558f31b5b1222e5effc80b6bf68e706e6fc90cb123005941a4ad7c181da50df22c8dd4a0a3b3f111cd6432cfe6bbcbc2f37dc4b2ad4041acc9994d96cb3ad71fce608cd76d2c26dcbee6be0801414ba9952f3e6592a54563685a9a2db3d896a901cd72e93fa82dee9a2e472192db503a50ef6e0c6f39e553b20a3046b69dffeb72dd683e4fe80fdf13e2b309f966623e9a808f4de49389f26d427c37219f4cc86713f1b5097c32713e4d88ef26f09d89f96e223e9b904f26cab789f8de443e32219f26c27713f0c9c47c3611df9bc82713e4dbc462ff82ce6726e4ab89f86e62be9920df26e06b13f9ccc47c36019f4dc83713e5d3047c6f029f99984f13e3bbcd175f9c19480b6954798482eca5aa29915a7e5ea8c77bac4f568f6f514ce5393de9fc7975d0db5e8a066e2f12894ad55c8aa510acd0f36db4533f7ebfc89e5c7ef448d89f5258492e9da79e159ff6b9eeac334d890a63004b5cf099564b9f8081a7127f92e05bc0b843aec3564a563106a5bef796574c242100e405de5f912a75399fb2a4ff81aefc990d5e745f1e2886c94da6e773d2dbaeffc5d88d67c3f220798624d5a45dacf8100a348c93b070dc8cc1a7a82b453271e8a5f7ec0aec3905bb61320c56027b792100ac431f387b269d95f6a1555855d05c5f154e708b25b0b4546a308fee1725a715beb938ccc4bdcee5fe07ce13ebc4ff560aa2f92f43480eecbe9596a57fb76aae07edeab413100a7ecb953d58b61860322add6d28e56076617bdcb06cd608783cd7d24421b95129a9eae1c077d88081c73a2703b3d95a72a4cd4069010d04ad31ae423b0eacb0be605cbd6c60527f34c4e026df6280c0c325a132d1f6e6a479980473afb12836b232421c7ee82a7f118c76eb63f80c9c96c9db5dd8383036ae7b1d6d7084993b003205d75dd876bf7c4616796c45671e32723d6b2a37c711c7000da43f26e2f6885650e4000d2c842b4d28570f9de09b067d939343db7b171490802a03767711409f227d64aef206f80314ae966558ecbbcc4915da8c3525e72dc835ede2b062d16349f7258c5018a3551c0ac0f75fddbd61a4f69f6cced200b3e2564636e4be755f0d16bc0fca76eb204aa9d400af7cc066947e931a10bbabe3ffcaa7eb060ba99e05569789f1643cbb8e650f296b6654ae21a3fd9e58b2e9248f28535872089f2251e992cc6b64dc8ea54e7883f73220ede0da51e49f471bae240f41042c1fe3ea0a4f75fb7c653089440a8b6349e453a3b73ea5ca1dd4da31418f6e202edaebb384d312c1b21eed62779fa5d7ddc1739b52597d3b3e107dd4402c7e2e0fa609f1337715f5e90b2a4982daf6753afad3fb722ab2debeca08ed3c64e6a56c744381e637d6d5be9371ac41eed81fe44c5e953e5be9088f34aa3729fdc369a75f9c3add8557b5f3f5e6c7fa33d68de24f53328c885baceb98a2cb74c238def064e7643b90e539feebaf0b546176836a8f0a59cf5c11a3ebd65229ad82060e918a2cfdcd34a63174a72becece75d9bc5ba405b5037790599ccdb282e6f1d5064c574f2e9c54dbec9381623ae6cf2121151c6715c04c9172b2a582140e802e93ad42b3161c47c98f96c1b438c7819b940e3a86da082fd4d6e8cc239a3e326eb4467476ffefea53ba814c9fd5d6a69344b90179f773ca6983c3c54936351d7b1aa8f6894aaeb94eec83add8b033fea3ac3d678de75be132e3c7a3d5ef17dd70171b62247c7a3525b43e8316eac547195d442e0a789f5c7b5aef5e69e507144b538d26587be181ead4a0b6eb128d679e24424afcbba10a90084a8107195e5acf3563ce0dfaccdc92952cba06dbe8b48a760d29b2ec3e3dde8f4b1056d0abd2cd445c3e492d207344c4963742b192d063f13f77a98cd48f201e4c53162639d392eadf8be9fa8dd5a67dfc45dd7c110fce9b0a09a29672ef3b00391d719d5d09dbcf6ca42d77a2789bf796a8641e8c918eb45c675fac31353d49e5397c0fd400908c3f962bcd6ae60817a928c05809b8d58eba3d813e17588c49a7614be18aa43605afff3e5a8084d3c13fdc6538b4332a43ac722e37a68c463702abababd2e90bc101d94e8f19238642a67f1f9d0afb3e4f78b595c3771d9296535aa87bb14c7027916532d14e95bba483952e81a0847365150cfe64789e961aa2d67b64861e9a327eb3fe0daf7a7479af62f418dc313e970979b03732756b43c1f236f277d60d9717a2dedd0cd382dc7b00ba86f15c6e5ce2a36e57fd6a9b206be25c81ee19901f968224fa07c96e1e60404251e58160c67dbb2bf904db74baafd6137710c2d9de29bd40a84d0e7f811e798109417cecf9a6e504a2f3af331e90ad68293422ae528543ac38fb6657a1c9bdea13eb6b64824f114b018f13ba29f1a37dedb3d9ba6170f458d08ae68fa69c08774585c2c7b16d01a42f4460a901e99ea836cde7a1d8be509c0b9bfa7596db3b57b5653bfb79c71cc757a246c36ef9299d779038658b9d0d82c0a1aeaaa2c03f81199a6dc66ab0cdd5933cd1857e881699d9b911f5041801c720128c3e94eaa07975b06238341cb8034fdebd9461cda7295533524f437c77b03eaebb48397fde5857d09cf0f91c2e2c772f0eb09bc85416033700372070c29d5a9edae14e003c3edde727543685622ffd5fd4f174d275e8c287afc787cf6d3de085f24f61ea6158aceffef8587bdb0e7ae1bdb356072737fd1ae7cee7f8c8dd6d75e6df7887d4c3a77b65d18cbc4bc53b680c1ac68a8013282b329124cdca0fc83d4632247a08bb584d073aee35ff3ce2ac7e9dc92e703fdfa371004123946495a7c13c092bd193d1e4f689317fb8b438e4a0eead3b138d2439d30634627ef07147bb0a0ca4efd8d692e48c3cc702003f3fa6b110d2be1efdf917309a57f27cf726d803b338e1ecc66212f012c2f85ef0f1acbb798bdcf08c8310940731ec10c716f034851ca20d954ef9cd4af922e34d468fab4f3014830fe8be6315900219277281ae125ccbaf751c6629ad4b7a8e33ac1b6dedf748f5b40df45fa1bb2fbb97f5974ea0f117093e69cb443935f1df0288dc35ed28bf594ac91bdeedd89d3aadc1f1743f775ffd7dca07844b3a74c2788cb917dff25a87f052e4d227cb8040633f4d4b003a22be264c2c77988d4c754986f3826ca7c4092bf7ffdf70a9908796b087c2410d51944209002a5adc96db7648716a5fda60cb7f7ce95d15a6c4a84e4096bd5b26c0d2f8c54cfac45a5216aecd3b407206f5ed9b842ffb78291e5c8c44421f256efbf09b11732449725782cdd9341c483b86958fd59c80335e72478234d128c69491a543dd43f831b2aa50768b58d80c63352b00d2e7dcb08cf844a29778c20e08cc48e80b80b0da629123c448e04abb3eee5f7a193ea17a88037521d400adabea35d6970b0ffe460f9b62efd76d3d354a52bc2ccc04a9f8142a2e0d79450061123a791f03b48d71fe30c8a95974aecbd0026973b74a332785c5ef78f617296eee3080298e643152f65003bb3c293004fe635985c3002206c5fb953ec99f1ab50c28c800d8e8ba0e84b369377c5ef03a7b61a2627ff4ec433d396837b72bfbbaad93df8c108b67baf49d844129c076eefd8f5399a35997d9900cd55c12867d25f32056b57f5429208530e26e36ee7179622eabcfbc0788dfc64bd972f960e6fa63a8b5a8f4e1212ae68b7bd2a804ea30fe23da1356ef051e8772929047729515242991a246a8f0b67947b3304cb5e8911b78881020f8c281060cc29184b9493082397fe2ec898ba9c1735823bb9f41407998ff3aa11dc11eef92c9f94a1b28c39b7553bae42daa85507d1b97a7dc6a241deb3d0db2a4a14d2047ea35e28846c5ff46100d179e78e3ed482f9f0bb38ab9e8bac642c46179f87d5724513b96ad4acb4759cdb17ddef770e23dafbeb34dd9f3f9db7aa03ebb9bac5c027e7ef7d78482fc85dbd83d17870f80ffbbf614e5bba0acc61d3e480b849061764e7e9a7234fa0be3fd61420fbd0f3090254d7fb0c025cdd43bd8d062bc5af018bba6c7073a165e61434c715cf070e09634e44e91fbae67193b402acf05d801fe9760f6079e9a677b3c5c4609e1c22bcf7db249dd78dc2d0a51ae214bcc86124bcef4694f7efb1fc0b635384e026f43e314f25c287d64181390b3cd8479f5cc4796f4ab2a540ec516e1d525dc80ddd3e26d238b7288b97e842c2757ba3a54cb7509b18857be82b37182cd1464c7e3eb2df2923e8d3aabe1ed8fe8db0502115fb3748f36aa43c29945f3d30b273aa9e4516b5b3754879d8ab1fe7bd946a97f52d229dd5afd6cab4ddf0c4e66095b17225ec4eabb40d51383fceebde54a7fecc52d07b81389c32db03006148f121c6a5714ae528ea0ff351e4d4e1e8051aee9c80334715397c41f20a03341d817ba17978e010b23419d532ed61ccebc29882c0951f39764e0a539f282805c11949badddc40a67a27679e263f78aa77bbeb8c29fd8c5d43f4be64d2921b9a525b06579fac0c808e06d1aacfc69b10b449e0acbdf1498368f636ad1c075fe534f9ab41f61af86833a3a0b9dca170ff0e7fcb7fa705ccac1a59a0c0c7db9a770ac097d6c72f97a01fe2e36a19eab9ecaaef2b92a08b10bf57c34d0a74731ea05635fbfbaebdbad8be4bfb12c6a3f61fc4f0e1faebcdd8671057835a47db3be8f798492e8a409d908dea1ff370c91723c5d873c45a71234b04b1ada56807956c7e9aa8ccd19bf6f5248dcd8f5f5b2558d388de448da27d5a64c70b541e548a7391a2006c629452c49a847f52c5495ac871e9fda5354c4a25ee73d8bf7af4ba4410ef8d073373ad12f0754240f421fdabab81f14322ad2dd4da197db20e94b2ce055e6693f529ccefd4ac7c2bcc6c7dc00eda0e36b2df93878505d82b8fc67eb62bb77642fc8f115521bfd0d4c58c86d3b68086d62d90e5dbe39a7fd3f54dc06a73640d06d3faedd40c97e3ae142a009fc67b036c4b85ba45787220f7ca83974913a2e235b5a7d844c5bb3cfe0c6a5b0d229a17961e1b5644af351767046c240ab804276a83b2f6083cdbcc80fbf7387b985329d163a6e7b97986df5c483a5f2f28b87c0b42c51188464292d5b4ebd9b8dfc6f6d895be4ae9f98f2b9ccee0a88b36bccce1212f1905bc4637d02c430e8a73fd8db0151c10c2ea552f11ba27a186edc681e2ea0f2cca047c9bf0834040728abe57d01b55155d19b3e15b4ee034df832b524f73ca995e07691db8ad7d0cb9888458bc9a7e76dd8797ad1f5d5a6fcbfb9dae67f313ad36079f2523e8d331f03d7fc994f7a82b07492938ac655f5e46f73f876cd2a2b930d277f2a7890c769a02f1427d875a7e53a93ff55ab6435dadbfd7a0be7df3da75fe01d62a4ca00fcea12b729755b0ba0acc0d9f2b273cd136e4d291274eaa8f9a529c3eef46c78fc496539cc2c42db1b9c91976e9e5bc93eae02067b45bc5d91f3301c13a5b717688300924dde2cb4b5754522584d59cc3e9140fac159625188678f5817cdc268de3813dabc794c5e23da3ada7af9c980937ca822bdc05a59347ddf3980189e7d10228af1e955e296243d6ab439da0e02c4a4b0f584706f456e0dfc14cda3742760e7afb8a144f812dfa123091314ec5325559d7143e45a94c4831e38e05637f58f210dc5982b04dad3f09f6a0c2fa4d11072525ab2b86c8ae815ec71e2a095633eba0af1ed1b69fd9b2f0446b6166118624faf252c9b176ca7f9b453eed8dfdfda6b164bc532b3ea150e9c4e6329c552c0c51b1a6ad890e5c5d0f3938c55eb9554c7eab45457749dea93608b592dc5f4ce505bc3bf1921ae08a837c7754cc9b87323d2af6f672251024a04229bcc11915fda8a07221fe4394bc952cc7a2f3116b473c0d2692ee08babfbe16cbc4f8029e44365c310a421b5e3b06430bfa6554ec6fba8bb0b65aa07145e7ce3a35cf080a99da7e163b7b4855ff056a306f820f565abf5f795aa8f27e9ee1b539fe190486894aa3fd5869989c24dd649dfc13320a7230365ad5bf2b67d7602e99d8d2aba46e55b47f8818107667de6e5e7c2c0e0cc79eab44c5a7d2945fc0fcb7678f691b67d1f66ddf96809803f3d8d428eee6c8470207a037a8a725a04436c45f879ace61ecc0564e8f9b5f213810774eb08dd663811111d606ef3141add19043df82a381c1fcf57f864885f835c9a76ddeea740f81a6ac1cc11fa67c739c6ff686969f1d8886141fe5d646a15f9e9d2876b31499dca3acd0d3a4054b4de9710add988e41ad17c7961d7ac76bc31422ad95a29fc78a55e763c250cf508485ee4a2c03778bac7c7c694aad3f44523ddc89a7dcb905a8e934251c8a83aa20a87002b7c994587bb0220fb29c087ebf88bf9f904a80ac92d1833810e546c0a1fceaa86fea841a8e4b0d63200774bccbdd34fb4bbd884137698aeb2a4361c64cabb47197ca612b36c5bbcf4d124a9cd491e69b17cb957c4b998bbe929cf2d4640dbd778b5089286145512b5460d3adb80ea0df2b07504cd9be6104a1e65ba65badbb9aa40d5e7068f08c65fd68191efd81a131d0ccc8fdd03f81f3d86a0e96e22b62af2c7561cadece80c42ecd11d118206eb3e984ccccd3232bac4fbea94c8023ab81cf28531d362549c2cf59277681afdb16f63ff48654e8d03e137cb875a19eff13710eeca3b4302478cb317df242321f6cdc0afbe04cdde50ac532db4f543c3a51eb452a83c46d164be89e9bea6a374172e7c715a8691a98dd2b50755207ae924067f67674a1aa3e47b5d0ea0b18b9b107f4205eb5cd2025364e9b738d8e4d6eb7004ff72c5b2cdc692d54a222d00db76a5f1a7e5254f82aead2c1e65311e8d7e6d4b6890592cbdf35bc6548181cf859c15b4d746059b2360ade0ac44e9cad8ceab3d184faad9dead37d0c406ebda2d376dabe3f6d3e0ca88d60c24ec4b87133bf06b992c2399e4821f085e9c18e6e42f40321322bce63624dca946d126ca7bcda0820d367782378cf5fe3fc7e3967bd4a9a7349291466f91dd0d4692b151d9165516b1f2a3626477afdd359611bb9db42ef5bf6c90b5d3c1cb0267b0a5224a0dc2b7d129d3292413204655db7cd23f35c1f5dde5b2e6e60fd8ff41c82b14777f34d89ccc19b9d56af147d31ef529f54ed08ed600a1795f0d2632681fec9cc94fb8ec2c7f9662c555512a0e854483f140dae62671967da7c1a39fc5c7c4b7263f11ddcda38891e920f2f938228d1e1e1226ac2f78d92c8f70bb03519d717ee2059d5a917091e4066c958d5702e5bbd2928d3241502fd44c70c9331e059a998a18755443ed505faaf4d335c1358dd4211902653ee461e7f122c9366fa2778cc1d948a68a672a4934d2319a83116adf2624c9a0c43f0a975b4cd0b55df0e0aa907b5852530d89ea0a6a7450778a1a71edaf1286c364fe2a7306d179faee10179680406544d6a3bdfbddce25dd31e0077d86d6887c1cf59b21664619554fb093785634a378f3e9e81d80405e0602d696d5c5853aac31a472f076bedd71f01b840daa49f6d0be511647f6fa0f7d2552bff2cdd68a803c201de934447e55e03c1cd3380a6a19041a0759ba7342d5b3e95df1bf5173ffa3b478a5cb23b1b1a6717ed62e088abea98cc87eb4cdcf5cd63700a126bbcd451f20290a380b5f71be943941d3f9f21930d463c14126b25998423d038efecc865f7e18334bfbf8409462866acf3860a8100ed64ac6397f6412ce332c792f0bd4d1e0e7bfa51f33f1dd62a5d1ac9661ac68eb7934700f2a4ccf4fd4f5ce7d81c196233ee9f106ac3d0d9bc8dd668e8c0df60157a0833f8ab790afab033a18bff45ed00d60f0b6441fef8dea53b76647afd9b181c7258db9e0ecda47d2d7a1ecaa5cded7272bc7be656f2142315a8f6913e5a48edadd8ce23ad231019d099cdee6e087fdd3220e7d033b1cc412561d43827836a52d317b96c00c24fa3e69713a23ae9ab33e96f39bbee8cc749fa4c40356f4c90e04e131a3ebf38e282c383662a2d1b20c00266adab2fb3035042354b5dfdbfafd029addda9222bef9c7418f34bdaec8aba3b6b428491f433f64d8248dbd1741649ca5207b44078c8c29251fe434097bd07d04b9ffda835e389f794d7a637fa4a6b8d149c750868a7193de1a79989be8e940fbe9b9fa60c38c78abf7f815c3f11394303d40a96e6f5bc8afe34eee27d9a975b2614ef29032cc986965184f93a6dc74a26102dfe8e91b48b05f2cbba649734e3c45ab0527346f3a8a92c5ad3df31d8264bfed9f7e21ac1573b98ee5fc26a518232cdb47e4919664ace450a97fb8f5c02862148fcf99e6b7bb93f89e67a0fbedd0442c2d3d3be9b1a378268e42ba9d27b916f75eb9efb5d77f7356697c4646e83dfaa933ec8f31015541411aafbb4b0024fb692766043af8cf9cbd222ed8ddc42a4d72a48823e670889ae1001b84c3e23786906556566670bd2c86bbc53637b68d2921f09e11a074892b0fbd63e890a1825a4a37e7332c2d5eb2a6c747b8472d6ad402b100122202e8176cd4eb6923bc0cd14ab887ac54635a81fe25f438251a4c994022b469a105c127fa4e946b3c72d4292da17bc6814c67ae2f38f70c4d05ad38979538eaad00344cd64a9d224fa75a25fcb333a5af7a2c0c112a0a0e0581baa9496c397b741a2ca2b229e15c662455bc1db67745ce19e44fbf774935e28008455ea0e5b3759e86706fa3fc081f24b0792223f33738b0734327039478db56cc82c34312804aa088662bb642b61e2d13c742bfc4de6601c98aa290486d8964ae57f0b3854903f01d6d3a804c51f7b493cfe88b407ed5bc86fc7f05754b35b1db8724749de3b8a7416be7eb9a34a9eae4b484c0f2fe3b982c5240974fdbe87aca5d792fd36565d0480b0288a93c1f8cf364614b918390ecee8514abf6985118854154fe0faa8c06c3aba33ca5685e7713ae2ef526a75e5231846ab46ad6a4ac348827ab23113e5829fa6172ea60242654f160afa6892fa1d61135a1ceae49a954ef7ce13685877347ce43f44d5f0e2830ff80db608f1f6e444f31189ae6f83a5d2acf6aa53a116b81da2607f7b64e924df49176d4f864e8a44b0ae75a4c92b82777c2b3a8aaa15adf787cccadab688dc75748cb7a2f493f645483a2a96044c2d0c0342d181db2c7b235a4025d76963eaaa6c692c358b9e18d94c27c3fb0d067d720f284fd261ec60deeaf1170375d7a478f2497ea5e8f107b2fad1cdc4e701bd424a0d408e277558afff5241e33536892954b0120bfd769288a73d68851dd3922365c8de3a908d1f59207e8abc98d6375972ea8bee94f920ccf921625f92495ef101f1c49cd9e13e7e688fc38d4cb016e72eb36669ed0db117e7c0814dbfbe9b46bb78848d6e29542d847521c4802dbf3c1b6e91cab527ba0f4f3caa23a5858264ed339ae60510e1c49e5ad01c80afa954df456f265911b166ce624fba18edd8451f20fca9bb005c64034bdfafbdf0ead249a859820313f5212b6f6c652722af8bf170c7d830d23850c5de5a8ebeeb3888f054e58dd1344337298bd10e677b4c9c315ac2c9c40f7819c1a6102393ec7720ab525260e224fa12ce17039189db640022ae40e32aa4615c8c0800791c5e14f1c35c5a847f5448e4160ce3e49d4955816ffee278f516e264e170a9fefdf640435e2527648921d241937589b5170dc26f53bcdab06a997d5f8bbc021fab01aa94e5520f1d15ec28ae20e342049d04633df2e9fdedf4467cb1c36c316de76e01776a01d6cf72d16a508a1cfb5e16ba4ad421aa3cb23c44995345b46474d2a16439abe87ef2d3c0ed0010769ea6b5d598b34608692f1fac2ce21e922a3ccd76183cc78c447c2661cee6a65da4f7ee124ac9151aaac29a1d0f29a00eae1df217c7e0890f7905c4696d35a04891951372229dadd06ebbe09841161f4f750a08e45d273b8096f423be37c1826068af03e9a7aa5f7bf9f3292c6f1f748242d2c31213b37a3c1c34e56021cfa4f091a341052f487bb2a957260845ec661d905cc475a20172ea243284f6d7e95ae1fa9768efa1c481551011529642a3aa6f4dd59b098dc9dc363fefb396610b1c101149590834bfa7e1637ae662ef9b6bd8ca2f02977997a980debe77053d520ab6f0fce16bac5687d1a22f4aed3d9b547be64a97697b4f24b5191596f759326c5f4c2eec3ecd825eaee0e947926443f4b538626b9bb6dd638523968563448cdef3f4d41ecb9f033e7bab110882489d7a38f2bd7d133adb2228250c64e967d809f267d109da0ce7396b9f034c8a06f1a57e8010fc1da0387e1c0adfd5b0612a3a79215234783ed9844ce8ff591306668dffc39e0bebbeea02b2f16c8e99ad5824330dc75c488baa1fb3217cb966b63f26ed6c29906bf41e959de99023ef06f1ff08ff45bfcaa4c247355dcbf5524e1942bdf0c4987a067608794d585c11893277ca4f3554bd7e3d128c501ef8587cd6e69b5ecb69a1638fe916f5f54e55acffcaf58f7eba9e1cf9f57d353e1df484de0bdb2b24d655e86b5ff696d328db24bbf38e4b84b813f18db98bf03577998bbdf75c6813e9a38ff7bf0cb2f4a58c927aa133ec85f21f97f36b69b3d7aa355258416772ffe3551a881004a3692726a8fd40bb7904d4f202675c76037ac9d588a6433c28ad510f321bca40f42c09a5959db9918a81343196a87a034840893e8fbe95f01bfd3cc7afbe14bfcc8bd5754e5f880006374c1ba0d02bab6065cea4ad938069279a1d0f89ca7c72a8a4034c51739ecd450dc134070dfa9fdb8f8c62812ea7070232c613110968765afb28ef57a985a23ba7de57da8a2945266effdb01b8204fac5dd43208c4243afa4e2ce0341828378840d5f10ab2ca1225903652770e684cbcb09c14673993f02daac36284c66d79a10d2a24aeb5afe6d49c8c6e910281cd54dd094e78de1cf45ad10b28ede4264bd963017b409887d8e0613157a48b6410592b0821430539a0432f2fcb92f82b89a2763f49cf830081fafd44409d0a31cc1587ee1930423f889d29b1ab79e1a0dd0b7ba7588a9198903963eb75cab185eaa04809cc622605d7da8174b2b9491c04eac829b737a02282b62385cc88edae0caeb1ce3237fcb3e00a204506ea6a52291d96351fba5798ff5d7b910e5e407addf409b82ac7aa83863044fa960240979be11aced9d1bd14d689843a2336e75405f126b775b8dc25837315487a6e6cc5ba3213bd60535484acb4473c436ee4d6a2bbca32dd7932ae837e5ac08ef2d22e8b80a558219dc643fa18201025877478bb4229dcb421175386f855d1d4837d718e4ab497025cb829f250972665dfa058fa10bdc2fb5fc10be66c0292eba6be805154563b0813e692df92033ade8c86f0ba8ddd4b5d3b23c0d31f766ef510776a5b874b59323457c98d838dadb72ecba017648a9a9075f68866c86ddc3a352eb47c374fc5eb204f0b5851569a6411b0140ba47344cc2da303448820086f57590a973666204a10bfb402a21dfc862f68ffe18284b81474a1385605e67f192fabc30ac8164c3e8153775ee8383ada608a3bb87cd3128520a6ac17ec7454b7013164c515e815f6ca8c28c411d3ccb95c8292dbf9852219ca60e5a3ae49afb929244106e6537e203d953595579e0d193640e6c19b0f9bdb22fba8be65d56212756e0f0025abdc4801d1940fdbaa16e3176810c0951f8fb8285bbd1f0fde80df7caa8a5c4f28ebf960b5a2a55025f9079197cc5d0524afa4be805510567364e6230707576e1a981061e94f7c5e3b41b7e4983beb820f1eff4a81e8f2bacd049710b3bf2833cfb1b81c33261198722438420f261683118ac8e1f7109f5375e880198d64ead6ad1b9e6103f1a6b4bb49772a9a729e64c0a05ed3acaa9b7881ece4cc21f756e80765e322bd1c45b7c95f393b3ff62f985ba77fd0464386d83f874d39e210fa89d421fcfb56486d81651c8f83c4592ffedd5ead2c584faee0584e476ae77ad4c66fded4aa39f46fe26d2768de140c90d146cc5242e5d02e45d73ce3f55d637c802725686ce0a2bdb88b81f7a1c9f050488f4dcf24a9fe979e23780d13c30f3dea1ed3a5143b3a9e2b7e9ce61f117da2b1227ca5e7781f89294ac8ff42964dcfd273ab0a3f59c3f384ba7830c952151e52d14a6b52cfd3c7318a54f8ef3d7431bceab00f3a5b1cc2ca35ff9a0c5ff34d90c451f56f9bab5421cb1481aa77d606f908428f2020160189cbcd110e1d1c7b740be9e6d820f749074713b40f1506e6d0db43441562502315e1d85ee208c044073f2ce229ab0124ca49e418bc371a69cab63bcec25a14eb48cd48faba688efab0657817f547bc3b63d04f6e20dd181b723be9c1d827b8d9d1f13f4b308acac8a4066aedcad144e615b4972e5b3b7437e4eec60f889176bcdc1c7959535501a5f729a9e0e7d52daa79228875ea80171367dfa18a81e4de083090f810c6fbb330342dd72877e53cd6c09efa01d3c1bdfa9e707d93cc1bd006d9b7075d0e4edc953a4ac011b038ac04c82c76ba25a094b29f8a2b1e5ab11c71a95fbee13558894d927eeb71f0d5daec39f074871dedca1c4eec2a6b2a49a304fd0c35ec02358fec58e6badde0d31644e0f8251170a201ed45383120a03d9338a2103f0d799efa7c97c5313d6d867e0dd3b465df6e82b76d44ea7297cd5f4c53698106e3ace0e9ed7b9a150a734fa33453fddfe29af1a479891cc5c763aabff3aad0d9946373516e684ed67ac1df8dbe9aa051a4f452ee16870408946d6f6e993df9942437024e0f3a2d444e260da47214c3ac3d0d5b0f195a60e2b70d4da44d9d66b74db3d2dc43337165d441d294a9cf19e6fc320dcb4b31b5dfeb6afbba1487a48f4614a15901a05692bcb0082bdaf5326e50db3dc9fcdbb11556f756aa0edab3cb3e3c05160fff9c63d1f4d0c46388935e533e0e8c8ffabfa5d50ee6cc7303e6ebe6c9ba07a4e3c43ad7ab71e90500125e2c973e632e5736ee333f5157579e2686aa33c9dc67abe074fa2945ea0923e6fe17a00324cad7b7f08d7a6b183e99945ade638c33b1358f0688d89aa1f7d8de722081109e7125e67ec80473c59a8308e7203a11a76563954a6f41657ba92b8241ea215a670012a9e8bac085685194c20be66b903d64291d21d3b3d87e4536aaec457574ad396ea1a7404e3e3be91000f6cb6190019252eb010774b8ed21148848392ccd968ae067d3e767314c5408ebcb9f1961165c895f6594a1ac0f1fc1541aeebf48270a23f9223fb3c1d72dc1241af678640ff589f7f6b443bd34f06a2b65086d47e6db142e333b64009c1d198c40f11e732917969b4f995774f194145002d69d52047111d4357d2d8349a9db9f927ca4997c042e3aa14db263ba8c0b9b9df9725484fbd685cbb300194a4f14ac38430f54289501fa9caaa74bb4539e0eb2d7bac1ac27fbd65e190c63d8d1588ad28d2b64ef178cf3ffd51aa3c4c16fd83717133900607a2b18d5140a13526ac4ec295fbf96d44981227df7de0c1326e7dff7ab1b4f72c93659e36d5dca06db3cf0b7ca946a5cb970871656d75eb9c20b894a5a84fed3c618357eea781f3e0e7f4174879fcfddd011288f1538350dd95694568b1c1c72f158b878e59c16c6e251749981321b1cf126c1b31b7c7d4f373223bab87ba830024e144932af071876fbb42cc6c73aae2049cbed34ae08888f2ba4508289043093d16f73b9667adafe5b4f7f9dff5685b896338130574e5a67fdb7f7aa6f9b138011a6068a9b9906e155338af34c0e3a84d984dee6e32944b7c4e3f76d226283a2d8f6375818e2f2c851823c01c7e858e5b5338386493bb3dab806268fee5a4683ffb6a813d1b16c4c7b01ddb8902f45548b5933fea5bac789a91e7f65e08941068d97ae626141806308b15f48249b4a4e0486da9cb0e02ec02324dce2ba1e24f98c79988ef2c61382c67b531233f2f357986e2fc31915d94f944aa8cf5d43a66146d2e8cc5cd7cdad92d73d04d6b408e03ba0541da3e8c3a15d6302a087077c3539e64052c4d88ce10a58505798d5d52d9d5e530fda3c8e9cb08979ccedc9eba20a445a49a93a8e4f08342531c3b84526503f820af0ef2c6d34cdaf90b08a4d1522755efdbce3f73c76c83118c585cddcc85596c5145143b469d9fb9d68c2026bc8f0b745a1896f509e6a3d3113e2ec12015824b2755a1200100f2170a43b90d0172edf8a553af736f7bbecb9c83e166666cef722df7db74cbaa50cc52fdf8d21da662ad5a9da7058495710f193fdf8251bfef4d15ffb43f10f311bf1dd6e42794c3cdeb88ab3c5e03f102dbf8566849574baf725a095591e2322b85381fcfdcdb998b919009802a5481d60cff2eb52df9baacc7630b70d33d8dec7688e2750dc78912f0335331b990b4d9c544a74f9c2c7d567885e941ad966dfef976589defff92d91caf7b3d1e11245c47b057de3d0448cbb329f5899871f4ab70edcaf45ffdf99e5f7c90f21329347a335339ae5ef3ce5d0ab12e97cb4a73722bdeae11fd7d21dc9a876948d99fb9150925a0c9e68f017d76dd9f5b309e1e83d40b53c8c372e973a9820c13b648b6ead684cb4decc7ef37776a5135748883ce91c724262e05381e2e6dd18b457d16de81afda47d52f69bd1e35450ba797430f65bd2536de0f6c5f355b9687f8a54def2595922a46796bb33f6f28880564a75a20cf5c36874c2c8cd1414fb2396aba790ba1a826a351892c32adc01e04cc9533c5f2698c873a1fc7210ce84095e8bcb9ea7e42c2f22f34362d585efd426baf9862007d4d269bcc66bfe771675f31d515d9f37b08a09715b3a9b2d003111e6717d38dfffb63ce8544022f00aefbb92a59a5c1ce2814f781895551321c3926b802cacea65fae4cd36580e14198cb37084334f4a5375fc640e50aec170884b3f1fe07795be88ea48c0405dc37b48cce7ef7f16c5f7c1254d6bd4c72f4112b554f4490dff252efbede28fae69cebe88d47d835d74bd060bcf62bbb3d72950a62b20ba379ee57a537d6235b2b36db769d25e6816eb9cd19135b520adc5e7c1a0799e583b9233cb1a27f88e9dd5098f305f862e5a37de12a7e16d2f822720fa2451ca51104023ca14e41cbb689b51173d418e355a620ce1bb0b167843717c7b6bcdc11ab1b45eaa3741962cc174df90f1e60c7ba365cd93044dea27c0f9108242587e1f9848a688510297b7c82b1d33b6950df769f49041db2c4691a61aa55e7ab83cd4c374397244e3f680c30e92f634f7584479f7cbf42f477294c0f85b55127140514122770462c648c698a892243793aaa73f2a13e9769920124e7fc1287b6f6dfc0435d783a1c1147ccbfb470fc4a8d1d97ea98b69b2ed7c096b39114325c0d684ce912172316a2d200aa7f04be4ec3aef812f9dbb30a25e83aa9e42569c047c608ee0308915f3d7dca84fdccfe510ae89b6bd3b46017af884820dbf38b6f1b45a57c85eb02a15c57e5163a901e3347280c07d3a4e73134000c2cb487148d481cea72b80028bf085ca8e73b3623063e114caf9da4145aeeb12968095896501860e975a11580d0eae2a3d5c33989367d458889dc2d28c08b9112fe11001c97380c1eb6fe7a25dba22aead30cfe1adb2ea257389ff7716a8311668d18cb8936d400206d38b05770eaecae52f1b511691f903913b93b050ea2ce3570c0ec4d7f3c5a5bd11b81a46cc718e3ab53f98619bec9dbd1f8288dddd92b4dd63e91a80ce3a8d1f172c7783397b92064d7168d1163554943502e17364e5c6523122353075192e0d6a26cbe5c936620c4d63885103681f28af78c2e6ee1f2b23e42198d7b0b6853273481a9c2733e07f66433e9819d5085f6ec8d02ca76dc795d11d88f97af46eb1b4e5ab245d76bf509ee0a57a92c6e22c9b2b9d38bd3011c8b09336bf566a54652eebbe1e43164d14cd99730914b6704004c67835d5ad39acc8b8055cb763daaaa893cd9a6a2afe49f08f560cdac4946fc203605dac223d48d845f0202ab662d2e4e53406409ba12c58312c7c445f54ea899020a2a0337cb996acb2d58f1223b9b86831c0796354ae2d6e94b9052b662787e1532ad1140559915106546c054e92329a8ebfbe584e5e5efffe114251d306b01974e458057f53242065ce9e82ca9ae7c7d7c1c8d7881aad44457f72d9e8cd698a7c863ff50bdde639ed1dde26bb06c85c1caf065d05364cf254daf4b2cde2dceeafad9834a15c9155c6c6af3947239ba6b038ef7423e55f5a759ee8d678de0cbf49504224c2375189d886030e7f349c343ca323bb28c50900467afb90e288a1521b951298c7f8ca546407176ec78d2021ef956a27161b42b638cabe64153ec248ade2d2c43527c094703865cc019c3e7ed80ac6feb44479ef54e32521b9bec6b3cc19ae818c0e057a286efe92fa8730f6822603f7fc34aa1ee2ae133fdf115550e53ffcb66397d93896816763475c81ef984b39cb596f0d0fd946faebeaebfe50b7912d183114d81671c64160c7bdb56c9c2c851dec100a251320e550d0d83fac62c00ee21bd68adbc9aed05b4ff3b17667362ccddf59a9fa6136a62995bb40f5d183ce6f74cc68b4bb1e46c744942d53295bcc97b5857fa3c6ab828895f45ffaf50505bb106347ce8c4114d59aef64d0c75a4e55b2bcbdb2b285f9caec352ba492fc7dd9dce1ceb944ed7747580d3093964eb3eb81b7582490040405cf6e8d50cfb63de93be8364e8dd4c84f753d3edfb88313bc66d0e3333fd7b4aa8283be0988a129f9ef9128e5ad43e88ce339dc6aea175252193b16a0e16ed3efe9c8d4457ed868a344d4b81f55182de1ae2fbccffb1ebbd32e2e71be599deb95dd9a793bc9cf751aa0375181ce1ae4812298df86393ec97f9381eb4c82b44b7ecbbbab0d4c13ab618cdf78665ebf1099c80a60572c46b4311d05f2e9b38293b6836e1510a008d879be8ba1703236787e001e404eed90171b98f67f8122d7b6729ed1a28dbd15ffbd04444f82fe3e8f0ccfd6f9ecd16bb614fb536477f2fdc0a28835c92369c8f832fb40e520dd03ca06e8ad0c7408032c2269870aa5dbb6cbe4fedb039215f472f755a81ecf5bf2523ed244a9c035e1570312a7aaa6ec4160701cf2724585838d0ecddc2ec1e4b58192e41d7ca1b39e09812b53901e7336679385b96b7ba2dc40e9a22ccdbc4abe83b03fe4a9c914565b0c50d161af6c5a57f6a044597882216bc2e83e43269770b9feca792b979ac3ec20cc74621b568bbca6a34e01cf0984cca21a991a7ff47e5d8f4a1ea9f1b876bc51de9ec45f0d9fc3f63ef3f52cc7c90e8359f7a8d7b5a2edc18654905e70fed2f1548354fe716cc3a638ec8ef9f882e84716b8716b8a6c3dbf88f7651cd3780a90b7d5e62ff826444099a5b88873ccb44fa1c9469f7fc6a04c12669e67729a437e9b4ac6b052d1769479147f90ad72d043fdc0158ae7fed26e606e4fb3fdc07e6852e3b78fcdc8d6a2535105d11cd40552b51d30b676e06eac77337e547fdfa4ce89822c1a56284a420f346ae090b2cee7580c2b7168a7487de4bccecfce36108b61f98c1d8fbedd526e3f9ea9e748abb2009b7abc4080c8bd0b8aa7f840f49f20a3a123ace45decbc0bf655329e574e11d190d71c839f3332b5e48b011ce325ef6b5d6b99e0121c83252e1e04e0f8bed050b0caca00b60a96140f4dd47596aa5166e45a21202c4e1a2efbed5b682c4e4052570bb06a1510bb4f3d3e5866118129bcaf07d1a5f5b207efb7fa11db03c811270f1527ca7b98be3456a8b80764a3cfc42c8aa71a54410f87a91f94f53ea05b0797d4f9eb0e72c17e28f64448e1e57a2598ee42ce4f1adce325e818ac8871209f12ee33dd3a580bf7634daaa5d17f2d7862b8d20f2e571efd8f7f293cc9ce484191cb3f697f309508203e57f8de5800cd2740a810a526a55fdf4c1a8705b157e159578174eaf004886795eb23cf1074981294d5e8bc7567f157c2eceff4e68614e82573455807563b998da043c86fb491555e73fdc1fb67287a19b7550a3ddad8ffc68ed52be5c9728f1546be1d1c74437cba5d4f8a84c48124b458748a93d951f98dc9b4817469889e05d3d9f98df6ed5d2f92d7cc9b743e04bfd3f5d1546d5f72306a2309ac9ceae18b6b288ef4fc016b04db010ddf5276eb4b18fb6daa21a196a93582170b6c9a2e0a982952450ed6c1947f58b0f20ca3594293ba988233d88727a33b3cb062f7d738764a5f26b1f1d351992207e3d720317d90d1218dab71bb09f4615d4aeef548aea0fe7d5f78d20a00a283869af3b3e5de80b6498d82c4f885ff9b9dc63346cc284adb36f7b1216e0bfa1cfd6a10af8a1260cfb1b8172d78fc5e3c5de7c31cc5c312dd1ffaeaa0883ce6088fb4cc54c75e968a38011a040486169f05507508e3663873f482827f546d9330479fce0b0c755d79c92110e8e0a5ae5c71e683be1a764300652c65b1abf55c143c5f2f13c0bbddd9bdc27302222321db0892e72bb0f78327c7846afde8aae3d11ed60214c3ded0baaddd6e9b3c0ca1450582287070cc24feb51fbff72cbefcd7275ac10ce65b718998368adbbfd0ad0d27e9636bfd900c1e38803dec96ddbc3aa308ab5d6c36cb4b618fa576c6e568b198f82dd8345018ae26dc82cda4d33cffe49cfc83d13c54d9c740fb8503e49c8b4a7ec7241006abdb4e45778a963d87fa6648af7c5819a10d99684decd6fb0251c572f61a20668402f909a48df034273cc015ee6722376899b73c49825858ca0383613de9120fa57b6493c1ff2063f2297e7ecce74cf7fe5f552ac456159370064cd7adf1e08b0166a4448e01b0027859984f0d8900a7a686222a6540c0da5fa317523e6a6364cc5ae5862492f72ddbbb25155ea2e8d3e4570102910cc1650c8f1f4d50993a2874c30ae94380208be581215f34be4d65e8e86393e08c8265b0ca907e7b56ac1d299a76a1b08449a11b6a994dd6092ad972a68567d84efab0be1fc019b86b5eaec4af9a4a2999673f66253d76ad9303e7aa16940ec7c9a8fd6449cb26c4ba45598b015140b8fbdc46914df7277bacbced9df6fc1e8e4a939126708efdf78b2313d1a76018cea3a49dd68269ba3d052f55e9b7112b68c039eb1270fa3a74752a3357044105aa44872a026bbee6dd7df29e71e55d65fca643908d51de13e542352f386fbf7ec735d9ecdde8239907fea50116173c35e4ffc22cf36151d2c5f2a4d2c23354fabe760b53800a7c3062aebc37fa348a2dff9698b6408322656f3542f8afcdb1fae95aa005a70af1794ab151c834d58c781fd4c4da5492bb459eee66be7b84cfd2d4a68833ee80ea6b4d26c77224c157c8ee8630dfc17bdc353b6dfdf54d204e8d7b9dd24aab972974972e0f7222f1865d9fdcda00110c7bec7fac372534382049f171cb7727fa595ae6be7b7e05736f1302acb3d55d8154edcb2ab76efbb2523becf575d30bc5efc984600a00842b0354ef5147f1d4fcc3a84cc564070fc3248914203604ff1cc3a5ebd91ccf95ff3f546d104e0089e8e8cfc038010b0bc3c3b052b78301e7ebade9f440451194e5c8780c62ce4b6b4a31ca238ec405265afb71179c284030ef9d07569a002a5c5943faa2f4d152217b30d44b5fca2863356dfc40549af674141c4930920b424da9a131e03fa62cd0aaa9e46b606f2afb44658091e68f6f7305f0cf4e904b82d6aef2329159a38b22469bd2edc688a180a4c8f1c247cf73c20d464ace5369b2e39dbf9cbad6f85f01ed63dec1e1ef1b424fcee92ee79fa53ad0261c114a7a8cb117c3051887e8951183853da5ee425c14e74f54c290364b37bd9a37e858ce717d00ebcdda3c799232f119ca13113272980f3d0aaeeaf98d0918b0493ae2b04211ce4ff9f68b35236f545b1dfb31b2b3bd4e833db6def808b1c3de9ca62033a1a5d64d4adf398c087230fce496c0755f8553a27a48a430a65cc2b58aa4d5406b76c66588dd6077f8048c0c4879719904fa85491f47e51c73ad6820660a9f29a3417b7c7c12d777f121758c624083ead289e54b36002bbdb899b1cc6571b0671799405f0b4d9c6e6b40c5dd540dba73c5a45118fc16fc2ecdb16eaed4b9a2682c29888b74dad3e66cfc188eefe038dc60d0489819319ee216634e6c5956a4388ab8a8680b5af7481190c0bb50b941830cac9e8a474ebba6358cd6de9a41b16b9cfdbd11d308d61b7e28321df110448f766a52784f51ca0a52d12df66bf8372fa3473e710e5fe080c34e71767348a06836b521c23bc93a66d5ef962981550c638735831ab21715322c85b0cf7d690dd4a179cef2ae7876abaa037c371eab0a12259950372e34d772650e44db57833fd497dc402eb8cf70eb7da136c11999a1468bbe6c8af9488a620bde758944f0887257b3c72ab317a6590d46a80fbdda4a999617a46e6dc2bc0297b3992ac09cd6f23d587839c30de64c7600f2954debe3cde0195d71baabced2f4f45209912a9e63a235a1dca768ef8ad35ae65d9b2e2c9d73553991ac9d4ee340d81bab4b71ca8367603b94a1c21ab47444b6f652b79d8273a615f37c0f64d763852b9c4611ac726132e2250dd1e112052801582bbad973fc5191b228b475c5bfd1bee725b0e50af91eeec8d88b6071fb738c820c49ff5ff032a676bdab184ddb452eaa247e89b2d78ecbf9e37bf002a2730fdd4f2813aa8a3339454d900575adb98a88c937b603c203041929668590021842e1767a26b4ce11ab64a947fa1bac18b292e8002ddbe5b04ea0f8072b1f127c86d1ace472634d92821169288f5dcae76a46df1b09f2ce5e56e0e7107e00fec13ec5b93c20975c395fdcffb2331471e544e4b36f06bcdc840b74903e909711232411bf812fe013658100dc492474c346a83a760ed564e85eeeee8545321daa94041e466991a8589c16941f4506aab90e99c5c8de4bb7032e363250961cbd034db9ddcb522284294d10e7c1409bc78f18037c8d1dbc1dc337c1149cc8480153e2135d9d51fc6391743d069d0b3c71d6c193b336c92965d1a0f0706d09abd76e295ec90f6418cb9ebed2943ea3054fba6ed6d66dc4693adf5c886c88d4435c6027bd2c3278ff96089f25b448783a1d8ce15d87dddd0c7715d0d71d4dbc80d8cd795ae22a404d14ce8ed6cb27c69122897667342c3069da779749da6aa347a817ef57b0d5d1d04e7677a293940a81209fd71279fb4dbc1ba85e8e9a407a8c44837289669f909fc42fdc654134a7b9385ee014a30a75476ca34775e01f5515236a55ff11850399589c3adf0e1aa351e88dfe76c855433ff379c322f65823899588c6c20dab9eb3f5c1fdc7121567f331a5088ca47838549b6b43754e231f82e46dfad5b9b3b59440c40dbfe525f7931a28497f6cab7d100bdecf43b6a632075c40fe2ab01c6b18c7e24a3c2b94bbcdfe5c31f2540e91cdc072cb8a1eb9fa022f5198bc6797a8892841dd6b19730f9d46f68977b290490ee830f5fee20646212f2f554d142dd2d01ffedc52b085352022ef8652e71ecbe946d4882282496ac985b97903907e90a765b9e0e53d5a73be6e345922f01ab75c204219ea143bd8a3d4c15a2f1691e98bdabe3d91bdd6224066ea717937d182590e83fdc885380d55085a308899bbf0688e4bdf0b670bfc9c14cdfc2f42b93acbdd20900a2848a85c287f30a659cd70537e8c18020747b9716fdc2bd48c412876b083c621300bd2bd933f5c676d324b750617a2b56b161a0fa673d7a2cd9335675a622e8f7d705e6a957b50852f61ba97be6fc0219712fdaf3f386d93f65801cdb9c957ae5018a9cc52dadd7ebde1d7f7b46b0303e806d09b237a359f33a563b7000625fc57e8b1bd166adf4719ec5da47c4295ef16913229cffc40ae5c0b3517981dd2fdbcd6a7ae07a1aca98ed42399f8cbe4ec2562e1608ce2f6cec6bab3d613ef6a30d28bc5c73e66a669474c58df777c544edf63a8912fcb17d5d07432984bc903843fb0d2ed6a76a053ab67bd36a9e688ab374d88592ce206719de33b5109de540b74002ac2db7e1aa31076f312e2658b73b8e5674eba7b08639d92c80591b39798a5888611178dc1d6046c2162034a99cb7a5ab830716498df656dcbb6a2573681208bd3002fc80bdc5ebe298b2b73f469739bd97eb8990c7780b3274a64540ac1ec80f060134d61d0323242d1b85e46cc505ffb9890bda971a7bbd8d987745fe9c720e9637dfc2753a51b235ec72d36a72603b1fda6778a69fef203cbad3af7ac88ac65e686e8007bd70fa3f2b30c4565b970ad26e4ce40959b98042126c2fb37ac07d98015a4768ad48c81d7ce52285fd217d684bef1daf501c7138b10f09459c24e13c54f2c802e883d8ea72a440224fbbb2378ea0d875d750fe85fdf08726d5c59a929907e23514311846f7d4111f7d3036586dc3952e842182ee45fa5332c8e127f338b8e1f0d1820a698fa7170c474917e246a4a2e639a9aea28981470a169223c45b2c7858990958788e7bf4eef2c574516d57efd2e86b80058bc8cefc751a65efaf6b610092e7c7e7523c2ffcbd6b026d8c7500bad449f872e8036efc4dce68aef73573ecd0e182e4ebaf566eb0197ed60d2bfddb42cc0f857c0128ff59ca5e73b9ad9d91be7f5d3c40600c793adf8bda7edc4cbd7034b35506cfe47dcf67e470cf6b7192daf9000344cb3472808f34e3b368706b2ab4d0248c9af70760e18c1bcdd85bea785b1e23c15e0c7a3d3037073cf5853e900223e4752a8b442343b8095ed86db7d45bb63859c0d4004eb43ea9e98c7aeb8bf6f36512fc639193f962d77ffc3a9da5a7b9dfea76d573585fb9f37e222d453f3c1520320b65c175851acc77538774df4e156131ec287306a32e9a285ce4671bc3a330b71d18e6f24b65c69dbf62e05d2170a3fe5118fb7eb42109ab61b1abd85274bcc19ea4789242c045da8999164f3be1e65406e5870086efcab7a81858fd7df721662f7b77527fe009457ebd2e31140f9f5cce007b7cf979b01d86c4f7e9d26fb4452f002e729b740a0139ada08e4efae7ba571b77210188e3972ebf4e3bb987f7e7af57b1b857ee70fed7a8c446bff3787f2e9fe86aa4f7bcaf4608481e650809490703f1bdeeb3b63d88d482a57d97fe6e3fb02835a71b45723865a164079167fde7834f906e34f14d08ff13a40b78079ab6f713c0c1dfbd90e0756dc052d873804d303bae52e2ec557606fbe7a1489b57912f02f479b52c5db6363bdd749be91c651dabf095de100653a7e65f24ed345d7e2ca322063f206160224fa032b9481637211b49bc1adad6d71d6ab4e23572ab2554ade509dde629fa81b70eb4fc60e363cd55f05b7a25a302fdddc79ae30a2bff836a0770751a3f95c49357097237646648f262f5defc4775c9ae8c9f846b7d989bf3d115a7a87bba9de483f9f704914b1c1738f08b1afc06d2d38237d0524381b97a3250f220579e81d54ea2d989d1f91250173344d2d62f9732923f4244b63ba7fe77a581d29981dd8191e16bd063bced31ff449f53ffb5a1723a3e176f449b88de3ce083cc6ba4cfb731fe2d09dc95fb2b9d0f40b0b563c14d486b26812ac88197a919b9f5b6f7c75f512d50a059a2817ddde0db9f3ea85d679b4f7925800d0ce30cd036dd0efd9cc9d3fdc415f370eda67f491c6df98483f3fed8d86c9bf85cc6b28dd00eb6c48aca7fdaab30c230af5382620c963d441e9a8b35ec9d53fefb4a58871e097bee0f539149bcfb76437033d911cc634454cde1711a1c790874dc621f73b066ca8c80a32806439f84b0702f2483bce74d80bc75161eac2c5b2c150bc874bd5985e2e4026d18d628e40e5ed2af8662634d6447c5084264a5b8503c515934e36f4607083df28a07a088468f2e9f4d66541c205d01c8074a6b6566a04701725b6902938f35d4262ac57b97861b875966395b5e3f44f45652b8bc237cf79ecc7f76508d008ac581b9fb356e66bbc29d814043ad55cbbdf91281b93e1cc798b2847815c1408e61094793ff44f4650cc2f92f983c0f6606648a0727841d3411b31fef5d1864bbe473475c50ea7eb8f6ae81137abe93a751186598a4a63f9cbad5d534045cc7ee6095e801c2266472700fa8f56aed4c40cd78cdf97b192f9546085fddaffdef3b22d488cdae91025135375c7b990d45bc00fa01ea5f0b6c2535c54f3987bcbe8b0fd76559043c05342474058b5561501d8b498cdc94d5a5700e261a0ee6ce54290a8acb2bf4df46a1c0c36c9015d63e8b201aec66d0d6fae06841fbf8ecfe0189bc11a5b3a8c95b91b070c1a8f90327ea48d3751265e58ce79ec7b8304d806433c4996883bc21b4279473c86ea1c7b636ac7c9e0e1f38779e5d43f549e16f8786d458b1c62f6925fda1b193dc91695bc6b84ef0025b5726b79b66f7460e919988a2acb8ac5db2f59bc5f5c5f443227a37e82a2bbf54965ba524a26d0739332da09c30e639a784e0f4c371e72a2974dcd7f88ebe4dacbb4e35599a6470d3a08d41ab6f8ff217fb39c6a3b1b12d3e21e4472ff26b67f8b6ac97eeba1d954dfc26abf6880c102ab2b8836615a970b79e5a9fb76906039eb58f8d544321d3b44015df2943720bcb15461d2e8156ebe77b6f0256c7d26cdae2d9499f07362d5393613de2b1a539005ae0eac952bffe3bea93da8e1763f7c9040f68e5d77c1f5c74d0a37904e38cc6a67c541e5c6c4f638a096a0264bde08c6bb33c80fda9522223c10535f60420f698584542913cb40017d849074ffe1abc1938f143be73958034010b6d8352008bce7818605eed9036b85c6f5ef51d4a8d4d8b414e8c27ada29cb8b09c467f306f7c85528776ec093b96308534804ba7f0ecc3de3a79c0dd7052578b7d9d1ac7881300e51b85ce7404394390d801eb7337a379806bd61b0419e86d6b41eded56c0977fa4fd513aebb56cb393f956bf1266beac3fbe661f96ef4594f331155b81bd926c301b7095a0dd68530d2868faadd388dd30969e322b5295937c7d41866b50c074ea1029eecffd671fdb9354d746465261b268a24b53d61019c7a816fb465473021270fd26e12e2f310417053401c82e9e7eaed62caae6c01b9255e8617d820507978ed1bf220165e91cc02a6f22cc2013a1860eba352636a11360cf0f5b208505c50af876c9b8be1e0d1f8f8466de73588bae80597200060cac3f7fccaf02f40eff3ce05615b2b4a3061eeaa38c4b7a91299404ce82846455e18f39c315def08b4cb69f482586426a7c9892d10577a820fb8c1439ce3c645853528c03e0e8c5022417194954e46a47b1d13dca6039add0a94572094b24a07cad73b9b679f6fbad34030c24831a2cdcef7814839beb92cf5e04213e21097445058d021a2e7d142d5f057ade155c93446d775e514123dfce431354f41ad54aebc401aa81ab72fffde7bcbbda59452ca2403b5083109770911c9b62728c3fc24322a1a760eeec44a49046d3e7d2f4188ef9919e64c9a493c1e1825a04e9ae6e8b4e90f893bab192290fb9446309bd25fcd3077aa96d1263e8d97b18ac13c43b4a18f42d14f9a5c0d737bbc893bf28c3efdc706b9fcecd8a4b7da9aab7d4a8a37f46e4fb2d7dada7ec83e278684ec9fc37196ab68abad110d1fb21300861f2b7c0fd97ff3c9fe38093ebb3007df55d7259e7813b38b81bbfe48c171b01a6fe2e464b7f1b0ed90fd7dc49b986d18b9e93031d06e3dd9cba8986e1ac763e7064acede30aa67d921de6871cc2d876779428323fb27a152ebc2dac675327926cfccfcc09064deb09bd49050b9cf4e312b744a9ff1bccbc2c6759d4cb6c1e28d9dd25dca6cda113423ccac34994ecbdbbd580465381edb638be094334f6c31079d32d2c764f51d3c74ecd8ac12d91fa3d8ecf127ec70140c269480a1aea5f95155744aedc9e55a11b275e1b16bb31ad49642b9675161aabad1bc4d6942d492b9fc841ea8bcf1b034345b4a55b35513e809d8e421bf845ab11d19ecde2bb3c384cde9c4729c8054bfb8a009d195ebf3e0786a3d81e3a9f66ba51a9b28c81eee034be1da8a7d5a0df7dd6f60b7bd6c92ab4dfbaa0700001b30359339c6de5a558c373586a965e9b64d2ec9d5f69a14dadb5338b2630e0c916cb83e120c39abbf7fadbdd66a9a7e912b8624bab6fd3af33f4016f40a28d8f458f95021851454f0b1ea6183c20a9a05f0c7dff0c84ec0312107009b2a00340248b9807aa1049d1d3b3a60c831800f8817648600b90006e80e10430c5bad7bdb1a0b23204b00c673855819ea0c74c85480a461010cf8c1c20a362b1552b8e9c00d06187272562b6badb563b23f76af86d5aa250a9a1b9a10a4478cc2d603dca16789c275382366d915dcd58747d9854eb6b5d6c7f6139d2a92e8b4edf7e078ec57abad8f2cab2964f186aa30572f692325574b53d854d8e4cf95b4f11542273bc61b3b43aac2567790abad66819236aeb991bd7eed92fdab37edca82f4387dc356b83fa6fdfb58b4472e466da41b0b1c8fd56e365aef636f1fbb8fd570ff0856abfdfa3f381e5b6f680b38399b1c22dbaff684aab98d8f1e28d0ec4fca78cf1283d80fe79c732a510d91d9f365f6d00ae82fa17ba847a55b1b8bea2891c891e3a3ae67adb5563ae5ac5e2bad5e69ad745aa323a28c74772925a5d43a59fbe3b4fd6b124eee73cc7cda31a2b0338c908911e5ee52ca39e713a59466db64adfc8a44531bf9de1ac83172cca63fd9d8f29b90c42cf2251325228752684b1d528a448ed9d2ba7b49223b134c30a186a645202020243223a24ca0ecbf714252d831b62494bc41d1b4988fd0ee52ca2857b5566bedbdb736815d0cc334ea2552ccdd7f4e8ec729a5b5566a2990b52c68aa4b50a0588dc814c3b02214d1c0e390000e491c8e6d02271b078fc37d0538781c14f09edfd959413e127f3a710b16913d2cfa110c730871a0dbbe6a88076daba70e73c82cfaa17dd510bcad4e22b3ab1ea24ef68c13f49e3dc1242579a1d444a794524ecf22a5ac938bf52a699c314ecf2269757b291c746673d289cd39e79c93d249e7a474da39e99c73ce49e7a473ce39e9a473d21f66889a73ce49279d93d2e973529c03cd29ceea9c95de5b2bbdd5d63ae79cb3528acd0cc719e3dc3a8d8839e79c94ce3967fde75173969993ce492776e9a473d2e971153f9cb3ce49e7a4b587ec3f7dce39e7bd64c40aa566f54345847edc45640f6b7bcd0eb13fad46b7aa5b188bbe8c439bd69e82b58225d8f6b3fb617c1cb31833ec5a01ec18f590cad25741a53a74caa76ead7dfb34c638443591fa56df105955c76963e4002caaa5a4758c5a6badf4a9feacb5ca1d683e99aa8f764ae79c53ca9f71ce2c6a1039c49c2b227b58f82d38847e6c612cfc3262b55eace7c73053b02986614796c84df5b72347830abbea2115d45a6b9cd36bfcb0d65ae39cb4d65ae39cfa297583b6f6741bc3c9b4e74bfb51aea27db7d1e51140d42718a594d2da03ad94e6c8f1cdba43fe814a4a292a5382e6cfa14e27a864e6f3cbbc7c6d7bfb4932ec6bdc31ea285182036adf4f32e1e8d94a92dc377a7af6126cdf5f82daf743267b6317b44e70c0b6fd7b7f3e86836ac8d7efed63d82fd138e48d6918e48aba2057b4c74aaee8cf9bc4eaa125f6ab1eaa7f3ffbdf3e834952b0e76b58e65330a18b654952b0f34ff0c8f6f3b5fa7dfac87d2c739de4e23035f6193cb2646eecfd3770c9dc19fd475ae5fcebd0a794d20b86ae6409b6ed7335fc9e41ea604675d3d7eccedbfdb8afce3bbfadbf6510060b2659c51b4aed91a1560e4bfbb893c47833a4fd50eb599aee215faee8f6f62b06aaf26f1be853b650dd340b2ab176fb6ccb66b48cc661eaec311087b93d9b41ea64f67fd34f80d499d8cae821ecc45630b49f61d67ebef5d65b333b9368150df6ebd7b71ad7619c8ef1e6ce2d72f4e28c28f4bd60ead994e66cea420fb9a29fc4625653fa981eea740f6943f510a7a9b4a1bf811a1865f8180c7f531badfcb0d65aeb9c33d9d0762a19e85332a14cc34025188661f6ef7d1ce6be3a4c72b7cb90e4d69f4f73904e6cf5ba50592d9d314e0965c7b732ca8e5fa5941d5f4a1f36c6bc91c6120c4a9bfe971516d4152b98503ce2503c8a4b719f39e798fc068a031f238d547fc194725cdaf1134000940b3bfed891f68836f1a90e2946e7d4a6b4b4d2f85bceeb9b125a6db55aad56abd56ab55aad56abd56ab55aad56abd56ab55aad56abd56ab55aad18658c1255428c324629a59c5407cdf1793359a6e3360d67d8b5954ee9349d9329659c8894464a63d4219356fd21fb5324f3e9e911a4945246f7a85d4a2965a09152caaa83742969a45eb4ebdaf7e96beeeeee98bb7bde3ba4a60ea8cdddddeb0e8b613a76886118e63976e8ee5e77700ab4dddd9dfef890e567de038661984fc6300cc3ea0edbe6693709cf681b9d4f1789879cb7adea50799071e732467b329c84b510c3300c0c5121edc2e9748f78c8f27188611826b3d51d304d66da3699b66379a34f1a76f7b26ff32ceeee588ecdb37816cf72e9b6619ffd86c11db29f5b939bcb2d647242b0df99c56088dabe63a346c8f25dcec73e2a1b6a1ee78da83e47f5382ad537a97120b99aaf023d68a8b6bc0a568553e1e47ce46afee67d54ff384e587163bae671be48cde3682645f499dce8264545529ff34d70fe3eced76895535d44f5355fa399bc6e92d22a8bf346eee3e0bc11d4e77ccea33e47abfc23abe6555ae5dac784f7c1799af739e17dc0f7a9f9941396b7047e3fe017346de683e067f421e1b4d0020846164eca63f25e5670447c7c72bee67d705ef534349fc2c951d5d4d6565bd8c5037b581cd1fbbaaf2c2943aa2d571833894c44f5610b113f281148dc56e89390c4a4eccf280a56922b2df92802c13fdf1551e7be803c48f5719c39836cc56e1ada4cec307135bfd22628f6fc9ad8f3b52dc336fd1dc59b30fa62da4a8db10bbbae5c79c156b9c8fee17d5dd9ee2b02c17b3efd21df473d56f7d79a3b9dcb3586a9f68a5df6498bcd919eb8c87487f689069b835809bf30d39e5fb9c8d2b1dca37d8fe68ecabeea22cd1d95d52a1b525ff346685ea59be43ccdd7e8264545729e86e69bf8f89456d98facd4475692a7c08985e3d1dec10f4ade8e85e3f99e7c2d2c36aa8405e7b87db7effa86c802c06b2d3ccefbdc7c8fb75a8535111f5ae539ba854f7d91163e85a39b1415011fe79ba0f039dfc2bb2e72f3a94f69263d7413f071fe268bcd41d9da91e351d990fa9a2f92fa1acda4c83e1314b4ca3fe7efa7deea2235af351350dfcf7923a8c7799c477dcdc720b51cb0c7e380287c0ba0fe1b10fc1f600acf02e8e35700576f03aaf091230200ede3b37a9f14dea7c7ebf751e17d7cbc0f0a0f7e0c32078c2c1c30b25a0023eb068cac1f6064b10046d60a6064d95c2ca046a1878f145458adc0c852018cac14c0c8f20146560f30b25000234b5fa47b94211d71447cfe799cf026a4be86e6551f8304c1c802bf1fa03d6d52e009471fd29eff60d206238b07185927809165420d1859aaeea53bd7d70abd235796cde73eca0323bf0f2e896f7f1c3477320c0b0a4ae13b8a37f3af1437287342654e9953d517e8fed00fefefd03bdaf3c30c69236548195286e46931df3ba24104e261117534140e32187b7a5d6cb1f9169b0af7156fe66b958b3cf7d79a36758b1c5921769920c49428413dac0b46167661d97b5ff577e485c1b2e77f5744a06933df68cf8f687ead2c19ebfa830466cf33f67cdbadb1e77b93f52035e2f84f544d76dab467587db68f78e3af612b57185b6010b40506405992e0b3a54eccf2c61b1b48ea7c526c50a17a5a7062ddaf5aa0b41db720fde051dfb922104fe92294becfa4842356ea234724a573a6cd94ab59831caee68e5bb460c30727c477ce285d147ead6cc72d5714fdb0431862744a5df7922fcc2c327e9f224cfbced5bda44e44edb8250b974db7185bd41656816a945a94c3fbe2a262497d4ce9ceb5703744d6bd60c5227b2f6fc96bf25e5e1a7bb6f67d5d307187e6539fa15e7efcda9a3b34fa828936f353990eef19184ac768237578d7d0b78d3dbfb525285b4d5630ec5e7327b2baa6dd39edf97aed89691583628c9104aa4b96f08ace356d26b7ed60170dba6c26a75c9dab5ef15549edf06bcd845f6b0c4c297bab44c6263732fc0698acd5ab261f679f285ff0e12d12d40de48371e73e76cd9dab3b57885d323bec5c32db3bd7dcf99e449bf9f32be2b5e7d79921046fd75feb2867e167830d0795f0f1c6bb703c58088c4d0718753cdd25c455095d38064cf7428bdc0d4e9a30d2410849702922c30c5694363a3e0758820eb79de375801ae85e381eed6740df31cc1d20926d5728d2667e0ef00bc723f39af62375347d5fc7635267e675e810c9b6b597794d03eb4f4b9bd1a163e6e7ebd03868e6fd0b6e08b6673e86198394d1f1716b0cc8da1f40d321a343ab68c831826dcf682ca4a97fe122165732e1b665b48fab99f72fdafb178e01737b8f85b49fd1f33318e34a46e3a0cebf682c2457f3391ebcf9171c56a1c8d5fc8d47eada6aca210ebac14138080b794c14f41c0c8ec7b5f79a41cede7ee88d21f70b8c4442ae32c85f6390b16b4f2f62c6d8767f50be965c7d3f1e948465879d6bcfef5c73e77e506403b0ed602c9827f1664ab9c3090839fc82f6dcdfcffe5af166ba6b9aa63d2657da7fad08246e0d2b62895604e27beed831667f2fd82ec84b94e1af79980db5afe4f06bed68dac186d4c13f6bb0e9877a875f6bcfff9eccff5a1188fc590515455e62cfaf883d5f8b7132cd34aed55b3e0b3f6e5ac0c901400004e0c20b516707860100a131c149cec19d507a95e862324929e56492abe8ee4868996269472fc678da5e76cc0205cace3950427b0e61d9532f91fb04a81d96a0a7a7672f41ed18725b7ef805e1228efc7026723bcaecf8b1823893ee2a432b77dcd77e7d595f7a95744e2a311d73d8ff448b3d2a952c1dab6cb02fdfc894afbd91f9dbcbd7369510df34ee18a4ca1fb33650c5d24095730067f727116cdadc97f7ef631a0372756f74925256f178b5586bad31c0000305820d19cbfe9c73e6ac56d65afba89884aafa8867354aad48ae0b03fa912b272c4d8b1c0f058bccb79a499e350546dbdfb9212c298718d18c48aecbff48fd98c676214a83e44a3ea5b4566a944424759cc8a8821855518a11499dbae5635698b67cec85a52177a8117645eac42db0786df9415ab67c2c694b6984850f7688b9b6dcc20a313bc49668750a923a21264548ea3851b6dda869d6b9cd41df35282bd56ccfeeda4646d7b5b51ddb045545e6d4f266397fcddb2c4703c5a4489d10fbd9f2b378e347eaf84b2bb6fceb8a4066b6ff55927749eee4db2475e4768f3b1851b4f1a7d1a88851ab32413b723650caf1549acd5a776c5b1d9a5363449e963c6b4cc2b08a55cc2b18623c988394a8568c0823aaf56e70d80aca70fedae56ec858961ac995a44860189390683c2f321272488d6252925188bdb3b89e4c7f8b23d36751f0ce97468382321e72488d82b67c6a34c10d8ecbf154aa9a52a552a9a84715eea6572d264777ef91002dea689a6b3ae70ed99d2ea1bb6223f0a74df5117f2a9aaa88df1059d2b5aa88bf7d7bc314f4b85615b12a6ab5aa88fded37cdc48f10071211cb6a557dfb4e58b18704b1c8923fb18b65198681aa21f7f1e38b61f766d8d5e1928d7d04a346b2fdb499ef60be21b256d366a2a64d0443e8c90f2bb2fcc3dc09c18b132bb2e8cc81a62a22738836f801ab4845c33ca21a12dff6eca855db89d4aa2259a699f81b4098c2c5cae18522379258454b3610c9b6ef8739e08f570d998f3da6c34f326d0d3df6b4db9e3a5cb2ed0777bb0e5196563b3bed2b27646e4db7b2d7fcc452ab1d6665f84e8dc61faef0a1dea1f7a241b991ca5e0f5018dea1f7dab95abb8ea6431c147e2d1cf443a63accbacce4d0be4f91d4de11927c4146e11d35c955d59916b99abf7143a456cd1e9f1e1f7248399e1caf78836545c49ef843991ff6447571ecd91501bf216de6fb605072149426e535a19577f2b352271762fcfc4e4c8c385e6d6746ecd0883a19feb00bc29eaf4d608bb9fe04381e6b7bc83502544b96c01633f712f05e021c8ff7e517e259e492f0ccbc10a7b13e39c7f77a99e73eac3348e8be82ee6bdffbba4c738dfb9ad9757b4b4c52a76a8fbdebc71a78c45f723c1e18f997d4ad698f5f82d83b86698f49aea687460ebd57565b33ddab5bdaf2e3bc317bbe4cf7b467e7e2411a3848025cbd92adf65e5c60cbb24f51f616e0e8772fe98f5f4aef5c748b8c737034608e0677e7c0e69c0cf5b597a0d51cbf05f11dbadf29c99d7bc10f8ab4999d6bee50d6d7ba4cf725579e560d91aa0924575280beadede8a5d583972f93873c7f6614b9fad9f3cb1772871c76aef9c5176e75b01af6b5b09d21f520c72e6c206ddf9993d40933a43073f22a5dd82072d786c2f68e22ce7c8d669a9155d8c78de56c8113ca6ccd3372f8b5bed6dcb9af7c5f616dc9237258eb5fb1da6361dd8e7558b3dd6a49f785992ac0dd1059d815478ebbc802db6c410e3b17c67064df9293c177ce57637bdbd14bcb894db77fd8b9bad8dfb1e3162cb2d8dcf6020349c880170dbc91eb06be700009d976e00b0f1c21df0fd8000446080118e1d31117922288208c111081046294600849c65032c6044a4b847002327070235714dc20056da800072b706201ea7bc41d9f89d4e5891d7734c915d0d78a37609a042187329c0021d79e303afc20df1d967860c327073df8c0071dfcd08396194fd600822988262867082166881d10a1c60f1a45f0c088348e48230a0f904023093594d801909825cec89589a62698a4ace18419f989fa06b8df03287410e4832872d00236a45812fac1943054803054065110aa8099c2898a9795368a7050851b56dcc048082e20e3056360a07465081e034e06bc3bd71859065be7ba7253bdd8bc30de2baee66b325066f0ccf733de5d52aaf26d962049df9f3a768991efeb32e578efbd9f2962028d68839fbde3b770a3afcadffd2744b3162277963b88a6d1fcefe8c322777c38271868913bddcf17052877b42809467016c76329e8023743b415c45e82333bb40c9ac662e07866023083916c9b8b2dad2db7d401923a718b15a13dbf53923a91087b3e56923a53b27cc85d637b5e0c1c4f8e00b8106e51533e27b4aa7edce192bab92fe1c30f8912dc8be6d266481e44eacc29ba8ef106cb320c3fb6bf4d41957fdce244133b6e71a2b52fe8a3b16e6d4111e23e3e602c1e6e1c71c4c12ab21f0120dfe6e064a0db6a9adc716ba17d6924cbaffa487dba8fd4ef5cdd6b88ccc9aa87d41f211e460e6b4bcaeacadcebd02af9f4c6d39e8ff493b4e5c63c0c057af90246c677c72d5ac860df1dbdfc00c617216c80b19e21b6f8051136c058cfcf16b1462bf6a547dc417dfc1f2804a9f6c983544d9b5c6a29512016c2563c088e024b116fe687b4077bbe1b8183e2cdfcfa45a6466cde831cb7e02269fb165c201971c1c8d2b263940d0929ff804e2e23999f1fa9f338c3aed7577f7e8899b612b9bf27f1a67ead7853b55f270fcc7d79affbf25ed763f29abcd711db115bfd22d71d7a47496c314bac845d2ff9c2fc1944c6fe6b7d4adfeb5bfa59aa216faa79aa0ebf9fed49703644d6d79a36525fa6972bc17d4fe2cd0eb612df2e6fee64b8cdfbd01bc2dda5f65e1e93dc79d67cef25e4829808c4417245eb0b6122f982f7921e537dfc54caa650364927b91ad346963ac65518bd184214db39b0b3ce9575b8fd805e8ae881e6240427d438437305d1650b27cd486651c61a9b0eb51f2989a4cecfd7649c302ce7f98a37de8b0db99a4f9d68935cd52fd815f43bc4447b7ef552bdc861e63484c895de75aecc291200f5f3b336e24e9625da4cd4cccc0e33a70c29439a3b289d2585b565c125e4125b06cac87ca6fdc85a6bad124492e38bf265493aee6057b4998fad9003b01dc8f60753db67b667dbdfa3eb1049d482c12c2943c29dd679d731b1d5a46cb712aa84a7bae6048b6fee252e811be2af3d2a7f3646aee66b66ef3559de470ebbe2cdcc9eb44f7134b856c97f07e278b44a838c5fb8d62eaf975c2d61d70bbb9a76886dff4e7b1d9009d7197d0f0c33a8c477135b4dca738738080749d93290bee4eacb802192e89425491dac693a44c2e90c09cc92bac8fe5ab2242e39cc90549249aed298944be23e8ddc4bde36b6c2d1802b166add06f4878cc5e85cd8d5e5a00365dc68e7c2ae273614d829499b6913764b1ea40b23e2cc9f63c49bf9a1dc343c493c8e94f7fa9a80e28927381e1ce44150401145f4283414cddf3792fad45fdda4a8084a7f13956b1591fba86fc2a4c8084a3749fdfdab55de84e6515fe43eeafd519a49916692f3a86782f3f79db0222bb2689424a1c177cd2be1a94fa4e62397b25f4b69cf97dfeb9ba8fc693ef5f78da05ea59bd07cea8da8bee6555ff3a8b728f0fbb9382a9a9a140abfbc97f7cae28d09d1c9298c0be69ec1c3350ed8c632ef1b8a40866a7efea744dc41fdfc0f0a9eec5d46e9b3ebdce8ba2e4cdcc1aece09e7a0097768f02491dec7e87376da4b0dca8d5dd855e3b5a592f567eea8a44a55f3a857d5c813a444924912690ac7535334526097141b55ca2176b910c7934425ff89a854f2849a8f9c4afbf8dcbc0f8ff731e171dee7dfa785f7013f27c9fdd4fba09ee6ad56494de404ed8455a3fa22f755a9bfefba088ae651b24241812abfa0ca6940953fea232b05aafcef479696037e3f382068420b3cfe86d5420e112645456a3ef54ceeab744a33417d8d16630b3c06c6010e835d1e2443425d2634a64c9932c5a950a1e244d18990907c0c2cc59e9f8a3a3828aee67bafdaaa2daffe744c4aecf9ba736dc9be7d8abcecc30f88cc8d1d44d4a1ff1d113d48e6e438f3f260cfa7cec920b796e9cb19a79c9db699eccf5d3fe464acd4c61b9aa35c6da03f0ae436aa0aa12a361a30b2349c51784d43c3e3514fc383864504024caeafb99f7a23a8af417d0a85fa26387f2f086293136d2990c7145b0ae4a179952d05f2f8c8f1a452291e9ffa263935388fc3e33ecde7bc119c4f7dea7168bec87d1e1f5945504ff3a8a7d12aab55346f04e779e82645348fa3993c939a1c23341230c375d4c3a2d14c54a99cc761d5d4a4e2b4c9c9c14141fbc81ead53aacf7923349fd24d524ff3393439df8426b2583dde52f5f46cef357754fe391ed3dc51b90e9d2b06495bc600497289416b4f2e31e8719c7d72046202dfb6cad29e4a31cb5cb404ede9455a809c0172c7ecee7a6d8c1bf84e6d89e13a1d10bc53c3751076af29ba579e92bb97eb2b497bde6be50a9267a7f9fb5a5d26b99a3f60928f6aca34ba28f557c78e5bb0d821d392245f989fcab4c89d67591e474bdeebf57a7d3f5fab8b6322b90ac2476ce430739a3e70d72268473522172d7ea4c7c69e5fa9d8221571452457f39d8aa873bdc41591d4b94972757f7a90d7c82176d5e0ca9e351092b6e9fe88c96e9fe60e5d23dacca76dd0278ab70a7e50e2cd2744b4918284b46ae4fbf7a76ada14638c403053963b8755e41af7481fdf216d22030739c1850c21a7020745209c10cb831cdefbe1d7923a594605e1a06963d3c8e13dc2227590a48e778469ef057a69c895d724b5c784460ebf56164fd4e0b4ed0ecec8a1f7ca9c300c8583e68e7706d11a7b7e1b7b4e706a9b83b5d6aa71dbc6f1709c7ccfa863d2344dd3f747ae3cca8e2203edd5fcaec855907d8ac28b9424a9f32df119fd609972b6c38f6e3868ee441691d1c647de2bdebc3825b864a1b4ebfd896a70c9e28b77347768ae7784f28ebca3cf7bdd9fc9d5e0316dca84850b70bd223b0d7ed8df8e5e9e80d93f94c6759833ec38fe15dca26881192d9042075208e54068cad2142a61a80c95314404a60552bc72e8bdb0172685036a6b69fc88f28d3b26bc6c482184834cf3d8bf5c1896330af5bf5ae9c033237a458840f07b62e20eeabd20084db941eab529b545e5bec8c835afea894eadf8f4d303d40a3b57644a35491d185e39ae3026a160c839dfb141654829138d91b52a62e4b0bb81d24eeaa716a41363b12b67fb6bc5d404ae52205efd70baa0ea480aa130b2d01457cefe4ea1024696217a2f6ba986a90cd920e31f22fa226b4f89aa7cc943f7c3fbb261ccb862bcbf68642e546a6d348c659990a3f67ccbe5e31196b0d3729c297fc61b75e86b2f8ff8678f8991b3b8e510d10d732dd09e5ba4edc27ac95849aa3476d94fcadadbd7bc4aa41603dade929786e7bd2210e9bdbcabd5560daa40b5a5c4bf27df12338bfc5be3250ccb19bb783018a6339a365ec369cfaa4405a2065189a847d4a10ac5a6a26eb6cb136f8ac27a71add52a1556a2ed92c3af95e5bae3961ab4911571811457f3aba8506a943d3f1b535b78572d5a2d39b32d8adfe2b738c83bc25e1a4919bfa5943eb55b06fa764ef3c0c86f317e0fc484e4cef596bcd7efda3a23dacc5f036b63cf37c29e7fc5bcae19178d5b841b849d0921738aabf91268cfb75d582ed885da9243eff571f9e1caf62d759028171f266bbe77f449a95178e0b45623d79ad592a5b51ac59a962c39cd391ab277fbe4383303b14f55c31bc709c1ac96ec1c7e09d68fda03a36615cc1ee37832ed794b58d532afb6e4aa1a552f7000014415d8765f66604b75b42088a1d5dece557598c33e6991e921c0930b4e3f50984ee9ba8e4ac745a632b4c51051965cdfade33852ae567b7f8dca9016997b7f9e7893445403a22a5954b94bf735c57d610963b30d7b1dcfbec518638cf11418632a3016d97bec372aacd020d3d71ebf95aeeb8aba2b7251154755583103231964ecb3c701a63a5a17844e4ccd401f76fb6b5b0adb1f5bfdc819c21813e118e4fbc29d0fb49ddb85d105a10b837aa22a5772ea372c843057ccf541dcb99f7d10ece72dc24563cfa73ba84faa32050c32ea65887be83ef6e1d7f220d17142ba75e041f0b7a6a0e205597b9a6118e538e10adb9f6eded6637b9c3b1774d676c1c8aa32859529a8700115568cb295222b7251155564550d4d0a756b308c26e7140af5efb222de60638bb21546568c5c4045be2f59dad3770116ff829dd2143668668a171c6d7981d1f753df9bffea8ca238127587d845848f0b5e0003bf5283a8adb89aefa4f6b80e778b942759f1fb6b43e436c44627c2076a3cb1c4644e2b19367b44ae41949f142d648dd2c3e61ddd32e2ced59f94a42f7ec8f168dacc0fbbc94596b92c016649ae2693ad9225a884977093d4f129f67ccc4604e252eab80ec7e3ee25cbecc8450a0c84705bd4d67dd59616b9a16eb443dabbea6746a9740d188c466ba8bbe242011d958edb33fc5a5180acbd5fc1c8523ebdf174b5efd0b77cea23573db4478b1d54b43582e884b42914b99a3488a2e5a480ad734520b2fa16a85b5b77e9de34f6fcdaf22017cc0d5381d8f3b505483071e77bf2b51ab0cd24366ba7c4cf684fcc44a443fc4279115b5cc183a01e56d8b9b6ac52ab6890716d7f19d776add29a261b4dbbdb714b161d4829b4553f8a4096f8ee64360c6bef60984e5f191d6239675abfa6c3d50abfb0cb4a91eb87d8a5a505d9d6b7ef73b35164fb36284f19b5e852765b0355f4b5772157d35329db9772daff7ebe965cd5d7a8935c8da142ae9e4abeb77817506c3feef609e9bd3c7f2d2f4cc4e212c37276ad64cd92ad66b2af7d68ffbe2e93bfb59749ea583ded65baafbb745dc620a5ebae73719189b14ee4fa0e625bf3e8eeee31c9dd5329d7bf3b5a29998bebcec5c325c5dd3df7dee797f9ed679e95a35aac933511753428a20e9522ea60df7d39ce7c0f92451cd7b6ff37036e32d9e31c753522db45dd3288703cf68974f126e86b9f3da679ac0bc3e29aefc18516cb44ee5c3e1863733b7a6995b1b5784b5cbeb961170e2362977497ba93129cd99adce80f19f5291f72902bd686ee6b748c8cefd5f04bfa120c314e88c5af85beef12dd17ebfb923eda4bd0db9afe88e2cd9497e9e5f3f6259877e484f8d76f499dfaf669d07e2ab9c44c97fcbaa59e4bf7355f51b5e3162c43cc34e48a690b1d2273e94288fc054d9b2e92e893dca5e2ced78a36f33f22b0d2d2768d5d1a76494e06bcb16b89ecbf61ab7559dadea58b50e4b140f932bd6488ea1199d21f4a915cd717e553222f499d78bf1febfe7b7ed1d99ff755b3e98e5e5a5df814f9d77250e66bd922748025decc77b0dbf6392152cf2fdc4c4aea8293c85a9090f6fc8bea5cf2821f14d417657f4fbe20e28d187bfe6691c8daeb8945ae8ee46abe8d92e757ad868dc81159dab039e711f5f72fea9db092c8d99e5feb50eaad1119957af996e391d58b0c7ab6c730ce233f28dfbc2257d3c8d65bf52d22cbcfc6481da9eb8f74b0b67ef2fdb012d988c032972eeeeb89ec96086ac4010ef07700c753b50370943ddf019cbfcf9e31c8cbb49b32fec12db99a1868cfc73f76882c44a66fa164fa9a0d22d70f3320b2bf4afb2deb6c8c5c65493a7b43674e0fc03b34522b046ad522709db21ddea7096014d8eeeb32adc2973acc4f72a1e3a8146dd645452c999a1100100080005315000020100c08c5c21171202a82f5011400106f864a6a563a9286035110a3288aa220a3142184004000328a9019a2a90202646a851d4b22eb3345b17a5caec43f58d3e69d11aa5b30c35bd2d8d9034db3147f496f4bf87a70872cd044e5c2931bd9f5899bf02a3aa17739cf4d09fb9984172595d631f860745db10448950a4adefa8a774819a948fe89190a005eb4fe20c671079938ae56325d27bfcae446a9770ebdc810d16b199b2dd9e3cb5629df56263d30267f8cc5aa67350867daa91554b9a7f91eb9cc5310d991d8ca51efccfe9a28b4e77d46b2c9ff0e6fa8bd0bf08d570e24b800529e30f9c57693f9bba9482469db57e72b79aa9fd1c9dd89f2e6aabf700f206279088f724e40776cba7a5841a3a88be57c3bd1a3a0ed2894f3c84e2453f4c1580527013cc64b01598fc25df5a982e206d2107a759ca1d081007b8e68c0c09d0576753ddc43113c35d52c1937ddfc37924055c38d82c47bb243c4f246db43338f09d019fb4a65c76d54c3c63cad7c5be1f5ec13d852c4b674d1c1265e41e9166ce99a888e45810d0b3a1759508171a5a9447800ba07167286da3c1bed3e1daadc2af6dc38eb64481ad247cdcdc28712d1ebea015fb465bbe35f7ef1ee9c7199139e69a8a029567f5888f244c03ac3dc5e3cb9ce0dced9248ca3bca407624329144cd70642e4872b1784ed7f0eea419045e977f12901faef49209b974e09bb7a2ba32206746429eb12a3e89e64056db3509ab334aea6cf82a5ec9411982954aa2a57f3e979687620927baa07e9e8fda18e9b5dcb733bc5726cbe1709d3d3374f3658171785d9aa41d110c4c06b9cc0ad169a31693157466872fe48218f1dfc6b701f4d11ba83b1119ba94776bb87485c077222374c1373d6a59f4747ece7111751c8a85d22371c44265a34520ae910d682e8061c7d5f2d715df2e8fe30e81edadf7c4c7562cb8c26a5c19b613590551a0aa81a8b159dab6fff3915dfcb80ed1f8a3a0fb61187bc5bb2790e5e0a9731d99162387180dff9f179014ee6fc433f20595f7a46cab243609f941e20c6ca94058311be302194c0691afa15ca1030d9b8d77c1e0982d161a85d049d0e7dbad63c5a054fb17a74e6b6274eab23c6f5b29720e24d22ed0b30a30c98b1a194d28eb5f6f7c456845640ec05e7d135f42ca9e871eed3b51a7313f57f38924cadacb8d27beb3f542d942d6fc793398b4bda003da068b8987b60db0e18b35ee52cf6edb0a11e62ec69328ac24b44a3792a24fb76da6bd295838c8696dfa99e0d6143ea049cf4f0e9a6f3500819b1da43e6294ac04f0fea011fcc650df8f8d11c2526d5392d731988dc0e500ffd640450b2b0aaaa3f231ef7b73030d9c5de429a0ade50b031ba02a667ea7f9c82f75c84b5f3fb9b37952983014077021bf704b8dd61b6dffe0a9c48be7e3c57fdd64c20d7f404aa162780d8969e855f9140c58c3d55b66201dc9c5eee4250698944b819088d48f1e2cc5e6ae8a3f6aa40c6fad1bb2aa3db2459e7aaca034a4e6a60927f5989abe3202fb05c4a2d55e62d8fd33a247d4ebd494f10279dca7cae916194bd1fa619863f84b221f99c8de112067f3433807ac9d6eacae9f2123d1146bf82d5270e28818013002c11992bff8a0e87fba14a33fbc31bacd14575975b273103edc73168d8a3fcdca94f8e79a667975eba3203f976f548639f7e079d6465a2f8bb3ead73d7ee07d6a9bff783d5a1737790df665ac5405cc99b9ceb05757ca4129cb2293d7544b7c08eae218f7c6be0853af1f06639487940bb021ee6b616a12edf4b42b96cc478f70e47ce41cc89045221fa4d97b95cc1e77939371766d0ce8f0377dafba5e75a0b5633372d933afa340e560be7e0354f0259f1589d4cfd6533d481292cb6d34b53041e153c8efa64fe9bcfaa54c8e6619eefd87b740348652f8bcf7da064fd0dbff4f00b40824ea1c931e6ae5b80ef6ebfe99ebeddb34ed797c9253bc128a9ffbbf748997abf9a99106e7ec1909eb4cf9e15b0c6efa41c0f165b516c6a1c1a6c818d36a58a8b618c355978d5b2f6f30f1976f55766d47e86f5c58d96538e574cfdf94e24b8cb0bd78a393ae6d75b33057d241a4706b5f0cf4a21b2797cec72ccb0d5e50e8fc16aa6bbc70a7774106322c4917dec959161e613fcd50cde7213975492159fbceee2b352c9d45140ff3ffe700c89ebe819a9c39a9f169672cf4300ba58a6f3da4c8297d62d1ef38b724fe0ba84a1082a2090784e53ef73bb81381ff14fb2c9b81f1b0f07c1e37901a6877a2a858f7b9fa64b489d9559773c77591ba3e88f86b496efaaddb0835c8455ce305e29893a852225b04b8bdcbc98d830b0fe13f010cdc0e31f841cac50114ae59776577a7ac7f42777c778d1edacfec9603103e8ed20dd4863dd29c38c3e5872ec508cd74999eccea8ab31ecc768c7f45676117b9abb477fe5162bb9be7b7a9a64554b9fdb48ae4e2e3dc88c8cb111427021cd70876a27cf0af7e1ef453a9c5b6ddfc563659aeb55564fa3981d1c28d15e3788e8b1419943a13393002b8064d9773a5d9104394b44c7db123585cd0a5596f66ad8db544c0a07a647ddcd0f5515f2b9e3cd3843a1e44119df8168005b6b21e83d5e32bd43a329163ad9bd68eb0bd81820b9df9e7b88f739db3f405bfab514d037d70ede83a7522c33fb93692e14dbddab079c514130442f3f114bfb71c14bb9fa9e903a2b013289aa54706e0db94fbd2ee39e718c6062301ca66c12196013262e69e0131ac24517f8461f983610df5b545b812abb0e1314bf720ea1d903fe0267bd5c2128fccc5c6adbc3fd5799ddf2d29b1c33e3e0012e88170175d1c94a3ed103559598491de0db57e3472159b3d18dcbb48cd654d99c041fd821d97e94d9835c468890cea09619d8669311277afcdf83f3c1664f426064eda0d19a7e4211fb639d24090139ed06c173ef68c78e5be2685694f29114701f1407b18e397c584796b0d3616eed85f177f209b2b8f91af74b4198171b439bac12d676ab0bfca07347fbd9fc1047308db52f306a7fe0b6139129f87e72fe0d4d848ac2c285dee94e9447e60c764c24b21a5b4ee512b306df00da498a05f69d5d7ce03417e5c0d07ddbd7ff3daa9b41d9ef16653822f62b8687dbd496d5d664cf61cd0d501ae2629e95a5aad8746bf7a77e6d15bb3633f3c682e9bac88a8b1443eba79f6f82970608eb5d2b866f4899a1c0b0688ccb166d38b8fe707e13e9dcdde290b2f15bde7829cb6dc5d104337efe9ea0c320fd2e0855288b3fc698044aae568594e3ac1bc145ba08defaff5a8f10826828598ab4f191a3e711a64902cb5769625d7c5d12aed3088eabc7ab4a52a486da100d496644e8db6670fb6dc1bf19dbcf9e291dd4d4cdea8101e82236225abd091eb14198374fc5c665ddc63e993c1ea99a8b4ea06916673359b23f1add085fe6040d81fd32a137725c2bbf17a3d4d5dac263430adfa2a161d6dd8c1467829263079e13c42c96e173f13e6e0a39996107bab0e350b2a9349551d206b1b5dfb2da12e676e62216a3aaeb022e8a44f866ea518b242bccab4d3dafe9b8511632c85b2e3e414c8661030ee88f445a17efdd72cf3cf9b03818829f43e4d668485912bffa22d8ef46e47b4ddc712a245a395cfa75711a96a7c4ec3a99d7a23ad2b72dd0b9e07e71f3791c3fcb57d07c53f4a095cd9702b55142f140cb2bd7eae1e6c409d45133d961e0c7d998c57f9f4651a51fea159ad207fac0a4c9794dfac88b883d828c6c752b07a3d838635ec52925ec01a3d150dc99ecc3610889c43eeba006a30de39a5702d0fa496e71915b7ab16c86470fcefd8a9d0f2d7713a0e2a8f04abaeb8c0d0383dedaf68c23f91291ce9993e384a32aa4a3766fa48dee1e6471d96bc0cf60fe5580cbbcc23fe7bd747c93c08529289a14d2a1962944edeefcbec31edfc02e802b3bab7217a049b54ef9d8397530565ff3b559ba906a71b5fd7481d5ddafc6db7175545b268983d47926fc75d301e90dd0e2f861218d2c56ed7d06f7eacc92383c286b27bca03680cf64d8a7c2204645d2afd8e13e04476f5e034dc6082f2fae93740ae8d10fe838a636afed76b6d8d0ccab97f8c417a23c99a003be207dda95c1c8aea15c04d6cd6ef3564fde8c61c05c7d7edce4fd892bbe80882dd3bc9b74b2ab665cb8c556ecd370a2dda547295617d911107d69fc6a96cadc549617ccd8377e6711fb82abc49009e42330e1dc9f8845f63ea27bf1b9946f75b8f078f3bb9ee02ef93144ea49054e86df37d7733fa2bef9d6985ca0f231151c7cf748ede949719b78ef70f10e5b52aa4c02ffd93417e943029fda433291de20e4426b9ac2d2ec9c4ab9cf87ccc35689885b998f70dd3680573e8489ff43957bf492e7272c8566fcf844ddcefdc185b03a75582968ac773f9cb61a696753871d20097fc8139761b1040a9f57a0822b89a6f11974dc96d5363f4f4751ef2f839b1f24954ed345752cbe755d00e533b46764bd84bc519dbb732c441ff940079c26d5a7cb189f56e0e81c88609528621e1cb95ebd3ff717e53415a6819f1369eee016e4fa2ae0df31049bdff3b193e80e189be1f3804ae4f160412e7c5f78d9a7904765331ff57b5725dfd92cb51682e7521ca4a250effe8d22874374c023e80680e9f1c7f69dc8a21b732ca656072a7179b51dc1540bf2f5f60b16f0b28e48b83d1cdfc764a7b724230bcbdafca4694897c3137899f039fcf22b8601f6c530a4ccbbd1cc0a0c18db6c4635283f27e9f98f28ccd01b17c360f11cce817de9c84ca22365e4ab346ce614277d4486c215753eda6104db863075cacd611da0236e1a38bcf69ffb1975f4f7820f5dd6f9fff73e22b30e34befbb9465947a589e7268c59d78466d576a2a5624ee2ba290c7072b42041db6275e3d33f3f8118d39bc1dfbcb71ef62404fba09b6a528a2c6446a6d6df79b7553f5f3366b03cfc1498a79f827de4fff5993a86dbbd4fb2d0ab33232db32c20ecd0eeb4c001e37918a3da6fabbe570217dac736e58b752445a1da275220723b8e6288805b1ef9ce010fbce57557f7e1a10cb280120054d64760823c81efccf39f2100f70a2fd675440eb437a0b5e8d38da5b0259168f417d102ad1105b9f22725c58e1e26eab87cc967a368a384a5d0bc13ae2b0bd8321c71a2997500e1e7f1b297c32cb9cce263e0b74064e257e9b81bc7b7d4a7f0bda0a7fa6a41ecc6f3d58c09f57066444134f106c19254f3c645e6ffcd57f841318fbe006e7b0c494ee2bf1096ed65908ff5e6286ae1e6e94f906843d2007a2b253e18f906010f962a2ad89b2676a270580d503ae57a53fa58cf97c8fc2b486cc8a8432ea30dcccbb775ce6fde00fa495c524118f679c68ef17ff1e45ea6889aa5d5f2583ccf10e170e48f9328485e6a7bef5c9554e1daaf08d9c9c4b7c4cc1c099cb3c4ce16311bbd7ee18570e210512350931bb64ac429e53ac7b66897ec4b354ddf744d24a394e15595f3b5668d832787c6ee395374a8f704295f0b87fd75b11734b6b3b256119503d2f9f5e705230eb49bd53c66221fdabd8feebfde23195e07357d442f496adacb5e6b8786c737fd96875bbeff28e6a9e860f1172e7b13e06c9cec3b61401d059bc3f9605e3330fb405e053ed4a53776643caca012484075c0b062cd29d2437072804462057d3b4ca9720104bcf2cf67336c689084d4992fbdd6f7f3c38151a5907aab93a95d6520139e3309f5f03d3385ea56a7cbda509efa9063d6ec90323b9393c17d41e1852ddb01d5eb062e7e6590c75db382cfab29f0c1a7ef1d09c7c8d229577a811c5e0604087b31b6d3c61e6d58cb42873b16bb78edf576a3ba675bbe039b3a93d0c231781f0a40c40a4a69c49f0b81163f17e4d9f392e30435b2b235686a94343cf1531d4a4e6e25034efeed219fc27b45a51b77a7c974b99c4e8c16df14814e8c3b1e2e7b42ee292d8eacb120f29e5db386f9e472014c1b39745181c937dc7753f0a77649595a867c0101fbac96a4c8913f7fd2e3311e2d23c4d638d6cc29f8828e695045e1e7483baad427162f6156314025e4e0ee678bb87af7a66bf05b0f4c024aa2741b0b688b7595b1b3cab46acefc1ef791e81c5b65e5f0c81c6a0ac10a0d539ec25de0a1e540c4a4ada318c7577700b64906afe7c2ee210df8e86d507a1d954030babebd008b0d5636a1f70b0b0e95afb2c740487ff2e2137f2800642625387fc89a3962b613655ed0586c43bf5acbc4ad984091628200ad04bf93399d49b58cf587cd28c453a0b1e3db6394404c1061e2a5821995cacc1185de1045083f94f57f4ea588aa823d0c8ac60f836d5813426e28f8b4129f50e7ffe232c6042b816a0ef279f13b6d59d6f0a9009b9c0f5249a654d37fc16872395a7516b46e13fd4d6a1267f88b96fadb45d0a5a669bf9615e01a18dd4b0687445e96237e0e05f3981b883c97277a4371b4adf98e39be3e9144939642fec2f2814393e694a30eed9c47a853d0bbc261e707aac00040f4bec9c8879805d959902c4809b8ec5970a8ec1bd31a5a8fd149d45cdfeb138995eb4d215d0e04f1442f52566d3eed024396a5f5aab2dc4435fb0d06e233ca8460cc2901a09b5fe71337d7c8a0895431491d95b6a741465f1e1bb29ebf9dc3d99ab9595954ccf3462d4d63bf6fa3918579c6edc466c90ccfed614fce3353809658a6253d0d03fa441758897fd50c493445d20651dfa030611abbbf021f545d6c67a450799372c74e325b772dcda6f7cd847b67509f5edbc8538795832b6760be3bbecb9fa72fadafd0c8869c5f58fd88cf367d7d102b89585aca544d3d586598118b3ab0af4adb181ec9bd7d46c52674a772b64ccc12b59107ece7af06e25f37cd7295d232f7db64f28335aaf0fe7d95c374375166b04bcb4d6f80c0f062e6932ff1fa1ed0a66220b4937ae652169f2289ef19acb84026e70a210e60f3816b7b9cf44f14c2f0a4f26486c1776489be9beabf4ad3c91c3a53ec73d69130fbf12dabbe605d1d30654c2f23c0af4646cc74485ebff865e701e6df1efca10cec7262af963d8bc8b80d191738a2f128ee868b1253aac36134decb9b4cd5a7e848de2e621d4d5bf4d53aaccc7afd127b7fb38d674bd336a254529580eb62f625b3aae471083ca49d4a42de76b960e35e3b69b7e88373449cb273a0fdd1f3bc7c56366b779d41899b3ddc024aef4e2844e0046fcd77889009fad397d42e0a5c64821620b4befa17e3630bf95e2223ebdecad872236206f7f2e80b0e1348fc5ed5db20772248b09f688ee66d1acb9038e6bd5844c15d214a73ede2d47f3e4abb1ee54f3902e8e72abd8c5920a0efd0aa522ecd621d3e04f4241c803685089b0aaa032d570854139cac8ee8fab0cb4e1750150e47a2b6c695f1832a1a87dbae36ac8eb6d00e1912de9bcb5430fbc9fe05564c6adc32f3d505b015f594573e550ce51de7196beef0960378140aa818fbf6fbbce123bba0a7af01eb93946ce6b01f09757c98ce9e176bd65f723aac353a3666fdf6f3871c24c1663ed7cca60c3b9d0da712938c28f84c37f3a981fd02b91ff63ab3d726c093b5910d04e951ec2380377d80159c4b33b3ca78d9c27eb7d71d0f2d3d7b0a3dd86ca881fc3764a19fc3d34b527d617938a9a7e03f7143b986ab500a91b14b0c18a8de14b31a1c5ae36e85e34862f2f3ef97a86df5bded41ed3a920e5e2560b3ec21ba404e1b4542e292c72d2a9df5731ff165a84b6b1dc9fa87755c7682d812538407642332c64361abca5c6434f7f70ce4e6b51ee894615c2eff2d5528c864f450fcf76edb0cdeb242a6318900f3b87f0609aa0ea52e1bd530f2c06a16fe9d17eede1b1a976ade08bc4288223c54588ddbe33452db81ec4ed76748b8c0bf52fd6d9791dcd44737d4ee16fccd591ec36f443d52be7529a0f51cbb7e7f17bbcc7261b981d2bc343ff46d9c71db9d4581a77c39fb129911bfe61e81364611439e3bcbdef94ee9cc5dd0c4b014464d59f19771c399dfa76cfb6e9a113ca4efc63ebd8f6b4b60bfaaa710c46a667048453b578c0b2d1fc6fc1bc8a286f1254191d953eb30aeccbfda6c56665a2d9f171bf4b4098b6a1af892be768c66140e3e8b3fd240ef1cf9b95b8f84759930b7d8eb75b43fbcf61e8febb40b33e5a20011f6914063bc3bab8f7e5ef6b7703366ee931a5b0c11a4071647185f67df26c60605dbc30c2f1daee4a0f7ef1cb566eceaa415de13dea6a4efce4803900fd0076055a095899524de9c2af94b31e275e699846535a28537a3c06aa7e78584a24f860eabe0e7a636c48ad7cf0b97a46d2c7bfc37b1bee7632ed1f3ae2c2dfe0e45e2fa3370909698a02a685ee27aaced9e00d777ce79591fce7b5af6db88906c612fd7358cc3d1c101a10b9930bdf93366534d08587dc9e1b55e523dc260df37cbd9396ac2df41b8ef1024202a168016254fc20d777a306ac6a06eba9499524ac9b6a4585ab24e58999047c7e4c859b8b91019df7e4ce912277c2a70497198e84d2fd25386821634b92c0be8e1a725ce6628cf7c912e64c9d72fb2c7a967998dec4762a97d22fe1180ac6bf8e4a7766db5ac6a8918b0d8bd511ce3f9344641ffa004f2b14869bd08f6eca853654ed62ce998a9a632f88fefd82818dc0be06fc7fa4e08883023843059d968de2ea1f3819bd98d39bc50db318c8c3b069ac6b6a67cc5b21102427e886517d219c2d2f5c6457e135d2dc11074293110436826212619d6b02ab87463b03c26590a0b033b31828b6d4f45f4e4b0d4bd6b66732dd5366618c69a65be84c5b3d6f9b243a0f4666d22ff49d349f8baf5fb4ae5c336e3ee2d68cbbaca32112fc04ca31f60d9f1e1573c31a4673f5af0274c0c1a66ebea2b83a0e1693e2a85430a62aa126f320dc7fb3b75e0910180f494fb49beb5c8bb7262f015127f21778e20d007329b02385428dd1d25ce28418cbe5fb471ec4f9f3ded306d268efb2fd1362dcb85cbb0454c877a2d259375b4ceeb67746a17db194b19834206347238def795eea0f680738a38cb1b01e896a1721a0e844dfb0a7e318cf8c962b817ebb149877cc127ceb147e8575cc48f567e828d345b9445f70d25d05c0ac77ff76e908a56ca1b77eb56a333216f050a148c4ce5e28c5bc8114d29c2e87f9b2c2534d9cc0dc03ec335874e5e54f92efd3a824b7f9236b62a096e257eae336463a978019fafbb6653c1846dbb5ba6c091ff449afd4d194fdebf44a3c2b8844ea3650bfc39c61186113087ba6d4d7d7881129b8322bb74cc31f7eb7d84e780d7cad957e88fd222312be8b35f8161dceba4b6ed3cd017fc1452dcc98f7e131774dec2ba95039b7b55a99e6c148e8fcd756bd059ab33fa89e65b7790c685d6b91ca20a8bef606efaf9814bdef72d0d081d6e6a5a4968f9139796d181fdb44d30d9093cb400a7d829e07da5197f61b41d1e8f6afc4c63659dc83995fd962d6c3397e306373344ac5f469a0a760da8202833f7c3ec5b733d3f8bc11923e623f7a7bb9ccf15a066167c1b1bb90904a037ece1550b77e0729d138b327e4a3c1c71efe022473c23f58a1cff669f3dbf591455fbe4fed3fc811d649c5a1106ff217bc1d2ffec859d0067ce67440fa49fb2aebb3f05604b5d1d8e4f0ca908d7a40dc01e614b7a085bd55b8fc8c2633e8ac5e39c14d85dfc8600541c88c8cdf5a8c680431adb0bdea20841a9cc84b705109bc0bcec4fcad3b9d06e891a838453a257fc373c39ff7275992f1162ada93be5989b1b1d9b67837d2ab5db1e3b8a3e74104f9ff502c3d5bf00a21e713deff629a9ab1e7477430a93db68d7a47d964e1904f4955cda97dcb73e5a89ce964c3a05d5786cd6a6f15232a7d926f87066f4ada279324f4adeb260fa74359c0c2c0c84a1fa73be8cfd039ce8c117821faad14801a198c3e971ce1f44118b7aa413ed4e7ef37341d0ae380885c584686a3f2f43398f6077f79b4d3fe409dd579b6847ad143a99d4440db23f139b5fb6dda862cf7622ef64d34528e67436ad8529cfc98173e620b50ab32eeeb3e61a31785dcaf610f4709a0e5bb4878b7a50194dba750a5031a09d8ec6702413e0d1698fedbc2398c05b8350d0324162c53a28827bfefd95c5f64e63c9803a5cb2cdaa6bf58634af649b1090f893b01820c4aed27db364c8d5924d2ffa7c5de6139ab91f8188803a44beb7af08088e3064e9bdfc91de42c870af4d4c76116c980e81aee77d114d5896d3b87ffa8b817de14fc282b2bf33bfe01b500bc1b525197cdf20024dbd1b0318553f04933983fc08453574e9a302206bad467a7d201b88442263773a3529d4c680c25bda741460ba5ce95a19e86a0640b4641629d1c04a54afe8be890dab47045308a1b979f628ff25d3f6ad5d6c78561fc761f2b332bfe66bdfb75982589db86826b336d73c56193f48d27b937d1dc275e4c49b94d51c161cbbdb5667cbe4665f8d9e2f17d4e1245aaf1c2313dbc4894df5fdf51d0dd4ff8e98a25402acff5c2b9ec772fd6b1198d353363c75ab28ba706729ab545e056e2b90c317585b0bda0c743a6d0d4f65b635cf957112da613ab2f0ca6dd34beb1749903dd9c49daccdcad5fb8fb2b872e52316adaf7dced2c5cbcfb2bc72e133962d2f7dced2d5cb8fb2bc70e733962d2f7dccd2d54bfefc099744d07b62aaf274a46136d5d6b2db9393b9ee8b5c7646dc39c3607f806a01119bc4e0b91865851677b70ecb6bd71f65e1faeae72c58b9fa188b6bd79f65e1f2eac7ac59b9fa188b4bd79f65e1faeec72c58b8fb18ababeee5f3bb938d2342e39815bc5951a911db230d5c012230a4112d4926a24d0e83397b0c42b5ca43f71f373d099574d113cb124468457da594dce3d42a171c04a1c991b64d91f492d2ad4b86eba8981681ddac7932361bb9b07dc968fbec680bec3e5bc2034fdfd7c47dcf3e1b05a7a2fa89a32215dccf2da30cea42697f1e12ba3933ff498b0f618d6b3bb28b4f7e4ac0c6c5b8014b05cc77e51314ae52083ac80f471f8a708a1d1ba38416ba73684319db7b15066f55bd6931b107b00ddcce61ef8c680ed3162bc7e73328669d7e163a746986acdc51f48d635ce852c66909bd32fd109582bc6c07a283854a7a7dfe80c7658f206f241b24171032ed415867da98cafd1123751182a247b9e320db7c2c9a6f03d875d79d2a017baadc04f5d278f1487cac48e01c0db1310bcfdac2a51f41f6f7c287b81c2a03e24a213d631fa8acc71331d4c3476ed22b336622cf107507a4fd4a9f68d89f677dd5315115e4e6a0de8d879a4a179dd42985acb4bc2531b1a751e3d7d6612a0327639e59b32fc59b373fa129e8201b7ed0b2591d09535bf3658a74562649efe81431ca49f67f6162e5794e0be85eec2b1b52a1d1e02d902f74e2e2c8a992e987ddeb2a78fc43432e3c72377dd32c519aa546cde27026a9a984b202d7a9add1d23396362265e973a705a3977387888e3c23a527dab47d6154611bc310eb1322543376df8ad4f74d852488e4233f5ec78e45a63efb99410b189a78cd0702c33712fc48adc6f320dd551dc15301ce4edd24a0b10453090e347ef9cf97445329e5af13432aec18d5a2f5a9d30a489a265a7d1ff53e2ff69a896afffeba90059c56b94f92af82c76fea97fdeb0837ca2068b7833228c5846318f7d394a9c4c7a1e0c326144ec82d08a17c97cdb4c9a15b1a482d47d20c14ac396e5fa0ec3958152829caa93464402842573714eeb1d6e10163cf612b2093ae7388c250403337b61f0c8a9c5faa13b7ec2dfc8d32330255e879a7be65bc20d8f1a162e14ded4ba5cb5b689d482b141d15d13aa4fe3eafa5b7ee5edf39ef1ded459dcb5a3569309706eca8eed8c11d6b9c6f6117a450b54b10d09c8160ebd23c7ac807a069e22d67edda74de7f1f99fbdbf85ebec07913b2d88372b700fcf77220739927942b24fcb3c4d0a1a2b7e66ab0616fae5b86898d9172950fd27b9f4f6cb2a95b32f434996a5ce30268918b9954dccf17964b936c80b97844b449f9b2b21a9bf3508cbd254961237b4b2a4a00183a1a5742edaab323c6170aa4510300c807d0fd80a4af17a20f7bfca81b878854afab82271299b0882c5dce76ea4259d152527a1259af8744fa63f932bbb711d9b4d3b37d0aa94349f78b069c3489db0fa825ffe1aa1424494642d9a75428d572d0962c7a3901fb5b3a850f8b255ea260f7809ea5233ff93bd8e74d8a7d362331662fe29ab26ce5b54165f74942fa1e093c75304a61353e9848a02dcab925885b657c49df5c73d28f336dae9259290c0f9af9848fc4c1fb25d70f95118d8654b5c4fe1885c28eebd174f070e1e851f9002c09c7a473030a42a3863f6b30336bff4f6cda286c0613866b690b09c9d99c69b3e7e1c156cbb28c3700b6cd481757b3b51019acad5e1ac4b5353e92dde733649e9625ead0e9f21abb36961bd9ab04ddd6a909b49bb64b3e03b84ce8050158a580ac48d9c0616cd91541f27eaacfa6c16e5f65e3e9c8c4a203558c03c583f886e20a85d573aeca70b98172d8813e92efd7c4f72cd72bcfe526a97ae17300c77901f7ff439b00b47818a203d6bae25d59661984485bd6c09d80364d92ee00fc6d4016139b3d42bd42148f2f1de25c4ac67ced12583a250394ec959d55fb6f622a6207e45d66deb56795377438ea4b51d95eee143c9c81c0e5305663c2f2bec7e649687a791159f25999cc8506a53dcacd1513b818ced8e7af5a0cb8f051f955a387fbea8481ae920774ce1dfcac25f46c0c336af790ed1169832d3bb6e7c3aaf3735177ed92e707564a4b2b6809f2259d814ae6f8b3ecaf3bdda2fa2beee7f3b0ef76bc8f0f622217f6adc34411d5628e37c1eea8f20214acdca138825ddb484f33e0210ecc700152dd88d88c35edc6c7bb158115f11c4ae339bda9a1af71d12c10807964fc206d323d53b7083101289ce08c26ba80753575d2bbc84b67cc68cc2fb785456b2ba6bd624eb5037725a8e1370cb937c89b39b2be9659745ed5657547a0c58f3fe66bbad2446c5e55925854ff500a02c1231142b0841fc01c0a7e46c41a4c8666b1247ded0426579af6b22b96920906540ec9b292de6c845246c479809cdb5859c33ac08444c11e7306417683a6222bf3305d9073206b2f04e8c780c3357ba8371aedd39d22c715fb1a1a9f991f59e5af33aa1cd290c66559de7aa0911a0954dadb7b67151f6362088aab6fb3840d6ff88013c42e110f18639983c3d64cfa55e83a2aab3b43f7e2e012fcbd2c84a75bc4782723d10429e60261f9c54a6dfd7c2620d2f9e8ffb3e5f697fb6a07c4ab66c6d570b1ee29b1dc5f597d0c9aaea7165fee844e5a2a38f6e62c4cab099ae1b209422d2e5e9913a287f61d36c8f19bb4f789a31b7ab11eb97907647ba333d718924400d6c04adf7b07dfb901f132002f7fe44597aae4cbe2ff2c164fa2b77457089e013c393a1b5836509fc7d211b90a7511206f66c3a36cdae0435f28b0a6bf00358eb2b579ca809bb17ec80f784b288517f92eee11b3f794e56dc29a4cafb910f701f24a2ea3a5a135ddd3154884105a49efee2ee12afbefde9cc3cf84c3c7f6a79d848296cab0a1c6af1c5f524b2d577d36be336e96aa7f6931ed2ec2af71046361d5428e55e90349c1b1ae4adc59c6684b3e31ec98bd4665b7fde216904c7bf6153bbc0a850ecad851fbee086de3862f7810bf172c2ef4de69b144c660bceb0bf7cba374b72b76ac735835b552cd2981eac374f90a642d9227107a47d4b1e4714d412734bda7124113648e77c406e686031b9793f492c287656916edc0024a68c0809d97c5ce291d2e5f3a06da3dc59b8d1fde6cc6f1d81ef6956aef2d138abc728dc1c466f0e0c220c4c9e206fc4080295ee1b107868b7120947803641ec38d6e3aeb550b6f31ecc81e90ad0fd2a845bedd43681b4970dad6cf6f9f0a9f92af5da094046e12401088b4c50da0775f583204369e75b6f3c628e19593b55a71603d0a7fcc2f477e2d291b68c00faaffbb1727578cf7206dd16407b8ce662ff222337b1390eca2bca03706471ea7b63261a190bdc069143dca67a4b8191131d2b4e36cf94cdb3a5eaf881a0816225524e6d27ee57f3a612418147302f6592dc6d435723bace82b01b956233486fb945e5630e66ca3759dc67a9aebb7bb8984237e9d927060c48a65943a77b960c40c419a1392c08944a1855bae402a09f272be43ff215196477c5590583622b200610d0f60ad3ea5aaa3dd880ef4b233fd1c1ab27984a9cbbe5ce304aacd71c21a539cdec6e4a465eee778591131658518a2bf1866b94c36f9b1c77679e98acf576f52d3f13d2f9e9ded4950f885dabfe4747d6556fbd578fcef07619bc3402ce68c2d0214bfd419b096057f29f8e24a0f8c3daf874b2c38f9c13f722ffb15425f380a8761b649ab99d35b5b7c903ece8d34c7d6a403bbe314d525ad48897f16d0648cf69575922f15505b0b2d83c60237a89d77a2df6792e58b9325f6adaed38eccf3049ae87eac38166c9e370a3b4b5352f2e5a1b7abc0f84355cc52bcd763a3c23d19c266e553e07bf7b4a510d2cc18e737f3c0f6cab50d7dc714318e68bd04fed6db643c81b8b443cf817cef280929ffdc09b371e59db45c87097be90d18ab972752f59bf2278d5e88f66499e0b2946df96542a575090fee82491ac4ecf7bc0302eee7d681eb4337c7958bb477608233260face943dbd05fbe8b9e297bc7a7e4641089b99333c1518d8f0085be0f77ab2ddf3a2dfdbdc501749e42d073f4349554864ec8974a9e2e46ed049299be1c1d727bff27cc5e69abad04a9968d982f1e9a9e1c8d02a1e3f8792a89ce47cd6fbc4a836ef845e72a6184e23004247c15de57c68051471b6ab3482b784198e3429133c4e34ade585ecb7b310c38c34465565d0cb09cfd62ded6c1e044cd2e0d8c8645959536600c1a7e141e7a8df0f7514c7d34aa9ef07b08bdf9a74cda59324163acf7040d8a93cb8cc8a2e4b4f6e1877b03e226dba58b06a5eb9c983774b0698435e79bbd1c081d88c2cf26f7988e668246b77066cac19ab20095b31df4938542113be8f05f3bc84c90fcc752c0ac88214e463a928c184fece897fc6ae02acbf3f1c4ce812c41f377f3a7601a43fdfe5845c12091752b61e6f36e18e2270a17a10b11841be0838b575223c06e8a0e1a4c4456ce801220a5454bf04b554d506145f97280560f897e9866b281d422f0f7656a949139df53b0ce70b97aaa73be88e62a69438da2c1957162140c0a308962dd6646273eb20af9ea369b1791d4264605a12446006d3c62a93ca1aba6b265d3da60ab1f69468029cea48bb726960352a08d230939b7be1839d6da0a258969e1892ae0d92c3f1e499c268164e12047efe0b920bc7ddc87b74ae0421a84bc0c3ba3852fdc54908998a79374bcac77c35b5fecdd6ce676019a23145431a025301e3d4405174c022444f0175dbc5926d41e81fd09680f2145b8ecf5f70c9b585ae45bb4ac06db206e62d361271b51f386b40213f9238911547d4538a75d0b2b6d41bdcd0df82fbffbb009f5354f96484ca40131e54ccd766a4295f52c7264130cb9d73fd1ed9740bbb1e6f1cdfbcaf0ceaa1acca1a6964305717b82ca20a5af98a3173b3b094e73869af2a7db0c55fcf22d151fa6c18f14abd8ff96fd57a10ae90b36dab430921674de50b1c8c3ef532c1d862c2fcc7603ea62e9fb853e9ac6f5a65b3444b0ee68bdffd206ecb18b5790be1d0fdc52e36630b5adbd6885dc8e9e838c4763353a1d63bde93f6e980e1406815507093b7e439bb44cd4dc2401968519dc67edf81c3d44db450852a8db12458525d027eeb0bb4158de369d5566a4c7be52ce5ff622dfe29b425a7400725b5ebf22d03beee306e53b441d0d471086e24d3d2d517d026abaa40d9a7eb996a13c688d792390dac60948cd5054e84895d73aa8421c99fd169a629803d128c0f602b94c1e1269a82246d8dac6761757c64dc0f9c7a55bf0791bd09758547ec3f7dbc62fd04841f59be9a6c819c9e2e78a2f0487a4ba88f0ed1622bd7d8f09453bb3c31aa9e8766d7d8dca6f59d94d75e509ed5251132cc2d8816bd9656b66eb3d07943a49502c0d7d6d30a132f6adca872df96892be4283b2e4c436a6c1207b6175d079953e5fb4e0a5498114257d38e2ad548bc1c3c04c9a12cfa6bf38c9c2a5cfa0e208204bf82b1303c56fe3b4dadd1b8ac555171111f4d1645dd8d05d58f55ecf60af214f89ee16a5d3f3e6f53a884ba2a0b499b6d4e627ba8d61061baf350cc324878124218a2d44d71df082283212b6bac0e5d93561e8c7791de6ba131b1d67feeaa2a58099e070ef2264ea75be449f70a07bf98d181ddd51069d0c3790c1dda3ebaa2b0139efd14603029a190f1a49e85bad0720335587123c7237cf8544be4a463e8a8b56bc98e34280d5b90f06fb9f6c864260100bde7da0b0547738387ce379cd66418099f0ef031327cd01695b408819c64c71d75cb123eefe8e9fc10989b6813be4305fc5318e0fe229e4d368b189e7645aee8849a49cbb8c69596763584893d36f42c4b3079cb9e098b71ad6d411122c6b081509d037120085649679ccdf12b8c181fff4472fa38dd4a54669b9d1391d935162d1a56b80b0b465c09d3785c5666a8c24492663192fa80324f93070d09c9e87779ba7ec8bc64c82c72d49c8f06b9e9f44d58cbae93a44472003ed40ac427e5d0f6e54aee8a8e84b67ec92d21c10aea0f3db71e41be29868d732127038a8e4ae758ca2121026c5a179e70690a23b70809abc9c290cfb7b5bc0ece20896e3764d478b03443ad71e05baefde176bd201b0acf173ff8f30babb5fd05b096558d18242b0b92935ee8c680564a971e8212b48d238237f04231d1a31cafd41bae173f835c0395cc24001b0e95453524733cc625506fbb3f9e67d09d04a6f9f7efe9cd3e7447e72c99356033ce8e7e2ce2a9bef5aa45fedb37920ed5b00169d1325c0fdee01c0ce61a4bfbc5ff3a1bc062d531c8afef5d00814c5d671525e71a1df1a63aaa81891b31e4376a13d7cfe677b4cee478b1da1a90d10b5c07602c83074f33c0755e365711099f07a13a672da4fb4b003bca2375d8c080fd5644df931a8bfa046075d5ac62cbaa49104e26d364f55c33ccdc51e045e5aa03bba1c5c7efef1bb3c952ff1b82e8b061b1cbc8dc4c5538428ce4eee51e57b6a39428aec4b4a6da33aa13057cfdfdeae376e1911da02c6aebb7e6ab6be955cbd2c5cb63bdf2b2dfeafed7b47f489a71422ca6be0cd8fde519c9e3cf88f1c63c9530a08221c015e2a4b23f2330d22f4e0b41db5627cd914965c382113535c3efcaaca40bf7a55012b8a45530d4e1322e36d2c53c58886c99caf51bac7eb6b0aa95a4552df5cb5f6dc7d7f66c0b96eeec94d1e914437410c17f7f5dd3ab7b99b09f4db4a9a40c5bb106ea34970e7515bd26cd188420f893869f103250048b1a017c8759ea7b1fc56f4c65242a206388567c992a6a8b36011630c685a997fa364799f9f10662c8c58a6e636608c177d2a2e230e9d8da89d370089280f22adb54d7f6aad3b956e0f91cf3d3ded5585d37a39500f072dca80c13f51f83ac981345c657afe314d86e8ec4141be343422a8fbf444248ce107037b336854ca28dca0e6f67a0d900a1581c222fe6a3622d6f7a1d3d9754994addb4e77a66ce88a8f78d09089f8b6abd17aba42e1704eb8e9032987ecada954252146beeb01f3814fcf64bfd808026d82b6c23a47db5d95aac03c460c638e220a8b0d2d3b5e96daf350a45278148757a7aa7f4b748392f0b0772434c2e3af4c73009709c56fbab5e7dfac7c0e0473c4ccb17ad625e1202daf8a0473ed7c882d157e479fefa8e398ddf66162e9d83b7dcd0b027a6bbdfb33b98fa16d819445eced39ff8e41d8c8af64a30be23f9f7b5cb75dce27d84a97ffdd627a0a411c3aea9f7d7e1f30b52eafa25d8912c4103e55a85aae041edd3fb3324ca9b1fc3ab7ba809762e15f87d15d128a0a2b34a361e04761569f410c29e38da2cb5db9c81d55e3e5177a93c1deb4a09212ad1328ed80d7745ac73f82ba6adafd63e883d5a5d2a42e8fa8c60f9113a53ae151f9b02cfa5b19eafe396fce1e5431c76713e4ad1d3147f74390ab3695f302b337616ae7b4f6e87fa61b6af5ff387905e3443f1de0b6ffaa86e02ee401c7d34e7c61a81b397980e7871ffaba755acba054582fe14088a3ff2499fea4abcbf0fce5339848f5451b0b01440dcbc3c7701def5da8de500b04acc3ab172fea7eafad7a4f1a2a4f58311a4384af7cc4c0baceb3d9fe59f29be09fcd9356a98df3ecf5ce3d3748f05d8d904cf1da52734a5b70e667ae275db3674845e6eb34969e94ea41cb59a5bc897c008c9cec088e31e3056f077c72c50241aacede9ff77ed61dffff01e3b5b1bbb45f814c0c9007c081a51c5e9ac30560c8d01498e758fd22a63ed9630f79b36f950802c6b8db99b1821f22106ced24c0bb66e5483779d6e090596ef353c4e3e9ba9d19db1406dfdccdcb5988aef35ab6f7f066127000e0ebfcbcd6e03cbd356a5cca39cd5c72e922e6abb05658f3924343b09f060b73cc34288480d383784eabd452bbf675ffe1154e4fe1c444652503580876fca3da8698d7f873f91ec070e396f421139acee847958980c6623224434170f3d0cae04133e0d13e60b3f71d88384c74f1a9b4205f7b39dca8c779c1cb231d7ecc128c07bb10df163bc1a238ae6dfab5cefbbb407d723eb9ea4000087ff957c480dd2c16cebc07ee486f5838b086b5fee2fae123e65162bbca699e16c95d9602d32613e11026cfdb2de5d5c7d8df6815f70c4f0bdb84d46dfca04396c592bbb5c89e7b90df04aa331c73c6a4146588a1d5f43ea83aef28ea700e223d64e1918167b8f067ba75ac00cf0b45ec50d043b381d620d629435bd0339bc549d62a793926d41c5a87d170cb59f1841dc89f3b18d42200b3ce9713552d5a5dcef4b221b9c183d0a39d418a2e45d0c36884bfa41f1345f91636076b2cf5abe4464857df2d46cf207f5539add3e1c6b39c9704db7a9613d2afa691ce1f34309f598357f06aed186ea8270230c29497065fb8c2b8632f279c0713c652a7735ef24b1f743500d9b45375a2ac1e09778bc5e814ee665f5ef463cb5442515556ac18f8f4449ce57f8c3dc08d137bc06ea342c3f7eb133e45e76f55d29776a1ebbc83509423c2604ab6f613448038dbfd9a8f44d3891c22d34baa546c31e9cbe10c44d8c4655c3f08a2745d6f094494ca282a5e460f9ad84423d610d155e76ab5b2490ed344c00bdfa15003c55938c3223104b9dcdcfb5494560bba9c788b06859f5ad548e491789c303f876aab89e57eed1402fb6ee2967614f09ad8d19b7c2ebf6b747fe039a9ca17e2555e7d0f63c39241a6a754004a7de7658bd7378ae7db1ae8af34c1f2bc53ac67422792229784e1102973e8126e410eca01cd323bfdf064f3102147d438011ce24c670509c9440e1829a8aca0ac92c857f65df38a33994ac6d6784400b5265e6fa81298c24528399669200b22b58a4c51da441662ddce17f6b45a696c5b731ce5de8feb5fd8a1c7d5a375e99a39ac4369f09df0f701e066573422ee1364c862c559127564405a8e41e51d84aa63e6734a27d5ae06935fae7beb6c52ffb46979a38bc756e1aa8b7d72c7c050a1183e96aacfd6af691871c7ad32d7990984a4332a85fbf3e86096a1bf327d664665231e63a841c0d0f2a149629e819e83d7c34e15533ca22260d9e75cca57f51fe95017742e162f547830f6ea927f77ef08e6c01678c731d1b81513df51c49a7d0e14547183fb0245f93a70a539bdca80ff841548dad8b57fffae7a721c03031173c287b14f7bbda48a2acf09c17357d0331efa7e831677942f829a7d988613e439f24ad9c2caa80f9645cc77bbf026092caff40004cbc262f670669c4d617d7781a3fcec46d29d0bccd2c264c2759421a898a109e637c881c6ab645c6a48586df6942c478ece460873b6b39a09a07665fab372c7717850b149b7ac437090095fceaa218e05224b62a117f764925dbf51c30e9ce8adbc7c12146da909f44cfaca57036a8635d559a875c81435859d104374e1a6dfe1d0391ed21cccbc424a14cd40184f342e68d23ce91d3cef7841977e61078e2ebd1da71db6b33cf12d52295217386e562c7e03feaaf751745ea2b5899990a61dbb314e1aedc394ee4303babbd75eba4f4a0d6383c357b315406802f1ba330c0b2aa4c751744ae0b570a343f9560161656a296118f3f3361d443149044b4dadd286f0ca9afbf450e2182ecf9fcd5543359f4384a38c3a82d901f763fbe465d996bd38817135f188c738b4fb909109b6fd2871e88975b1c6ffd334581c88af316df50db37861c5841c12e69866f5d17db4e78387955d46596d5da5a2abefc6b59d260210599fcac9adaeebec979bed829d1862dc72608ccd8cd8d842c1131511305d826d0f560c238800242a9de37f9a3f7c687f9287e21131ce0e1069e02dcc2a6c53d13e6c56302946498287e3cc143cc3fc2ae10156dd0c3fab0499d959fa1e8700c765098c54cb9c84fe0038d79c07776ad7583080265f6e5f7e4c28e9fd1674cf80281d568a0bb2449f685befe805f3569a5c210d620b19ec1eba1df9fad594b07da3f1041aa037c669c056788d700d16088e77e216f39e539d4284aa6da382c277034662c4341c0e6da206e9e15efe26b634cea4e7d71185641e1a488189cb4f4d96bb24944539039c70e91668cffa3c178171d3b64731eed63b266c49a8846370bc1684359488e6cd3a6ecd14150a83e060530223b1c50f6440a288cf025619abad32c6110d05b2b8040af037f209c6274aba81b152141317eb3fb0766d6bb2d15ec75a48391d542f07826d38288d2a37007e7736fb243fee4f0f506630f8de668081fd53ec2ffb59562442215a808380fc1265028754f2c27a0ceeacceffa6f0fc47de4fff084a14c9f561094995c80f4987facb124d2fa3d03fe6b05b95cac244ad1eadbe160dd6d1cc91ea0dbb2806fffa3d10da2009f2ee946b76d94813749d3e346a1607861176b678aaf64a9855532d5753b86bd97c7cecaf10329381adba84c4f2e86c1f43e1558d0896d31dccfb6e7300e9d9de1c72edbcf24da4d7fafe4d336e011f195fa3bf28e62ad18879570fc1b4bb5b767a490c305bd3046a22a76330ca264814d1a07c45635bc839159e41f07b3083c94b876e3689717a2ab8022af0d17a4a04221704188f9b2b4c5112dbc2e94db102d0dfe661c87b2b1ce9bfb43135849ce4d06be6f996dab1a06bfbf846e3335c01da2d08c5875ef81155b2030192545dc87fd7084df7c0bb19bcdfa5007bc706b3c9213d61c8c2b03be92a406556225f8536a13c8f7bbdb18ba14b49e9dee8008d3c448ecb826916572079a1a74e7956c3f4dffc3d3ec836be860e04536f0e118d435f00f4a0d07b87b35c5a80254ca3807de8252c13226708aefd5fca425697a6c1bc2c87c60d2224aed8f5e175c73058f15f89c6d9cd9fe5f384fbc091e806a5c73d01f9279aa023ce5433852228beac7059443bfeb39b8b01b456e44b2a063b98fddc24d2d37a46447e66607af1da9683709d220e49f4209a188dfda9c80e2c6a7a987293703b673a14c7f8b525912ca9500f2c1be6aa9e73376ea62b226d40d2aab789c90cc082b02169b2f74f0d044d6895fd45708789d06262ca778382a1e2adac7314301f9060cf41c1acc22c68c2132c226f952f7249e623a4127b14966247468093c1f0a7438106976251380d8617a37758187b81add23755bf5adff003abea3e1258d969760d7a0033aa02c0d45a909c22ac31cf863af45330c3e0ddf04123823123140fa7c95e581a3bc07649561b4fde04b9ccba67731810f913d78e86a8310f8a6181cbc258c90f1a53562130ba0752f575e99984cdf0c0aa819a8e6e5e2178317d0eb8448d2d41c139a132980cbccc7134c0f906c7d57bf60e0db3a0840ffba268204405aa015697cc91b257916bf86e91504573451d05662851331c0eb4461d85ad27e9f5302ad6414c96c1a79f772e628ae9a67e2322d1879f5fcfebea2f5438091eacf757068b593ec4b613f410001fe040e4cb597b7979ec17316c1b2aa04db29d47ac1692d8a6a8bb7b11cc9883e1322706bf773705ed87bfa498943eb4ad8daac5dbaf7ed89692de682f9d1f95721142699f457f3cd3e5082dcb1062bf8f7b174fc3d5434ef4d4b5e18566ca53abae9b5b438d92b259334b1dddadd022345eae820d0e3fa8cc9a5b8d325ec3b2251d0d7ed6d6ad6d14ba4d6a11e72f5146c24f34a030f0e08918719046adfcfdac714cea1cb35d59f35f06050f292769427c999e042b79d8cdfb8285d6f43f7dfb01e6edb46492428dc3d29f33f7bbd337e6e8c429fe2da06d3c10d366e1d88f37dcf4229a7f7792ea52f04bfae049066325826005e1315d4c68072a994de74e166093cf2b897d0cabbfb3f20acbcd311e1e900943f4cc22c7682235e2d5355cbd74eace32068421f920df0028ccc594f5e33425eb4eb75704a8e56d004e6ecb390605d53ed3b0205bcf1d2c60cb196605d5be67acc8386fe73a3b292ef2aff1e173cad3b783db87c1f82f0d4d4f434d778177a49cd9338e0bb073de5141769e735e80cd738c14a0e9dcb182b6ee338664b1da5a24880c96950b52ce5dc75853a4371274b4980ee16934c7406ff819dc40e9589ec25e19e0f62fcc259ec3d04742a1c087d431b9f3585542b95ddd532afa76dc177ed7ba264068b131981b2af85d173b3fe9724124ee70d367883a39aa7d976a9b71dffe6bd57755f2b1b3b8d74c652beae6cd3f19ac343f38b4e81a1c4071d06195962ec44596a9e2e2086cc6f339d98958b43bf51a44e9788b26518b1c5d554df8f02c6fd151eb48c28db8b443865de2b646aa0fe4830e2018864f318f4987ca1c33edf7893e8712e83b0fb479643c801ed5f1cb8646893c4a73b31334d22df037a76921d680f0a964dba3f20b07544b9f3a2d288179dd880df9255515fd79137899fb3de092ac68a630b867d6c797712170f9334c60ba4d85478f404c1b0a1a5f61b7d2ddaa6b08648027541c108edd2cbaa6cbe8af68ebac6f2a01c7a7dd87ea31b4a9ffb3eb048ce89577235ae3f198b35f1bd4aa0a487588a632bc8973d99fd27e038ffdf9e8460ff60e14deb8f85f580e4508c8bfdcab1059d3d609df9f801ffc54f349a8cf7fb750c73f26b2df4a2a2cd9fffda57865b2ddb2c0ef781c8768ad199777ea8f54c60ec87ceefa3129ccca95a6a1dfc43ce340b7aa740d845276c5bc66ffaef3069ece5069dbff40abf350b944ae2e33141c475af9816460227ba34fab60564630ba4afdc82c7aede0b40cf18bf7f0d673c46c532fa2aabb068bb08e67942eabe5c698815c9c9ed7d298294015fb757a58a53b04ac207c8b20b20b0ea86c8c208fd0071f93e8c97229247d78cbef0968b8e78743ff1c86b9cb33107d646ffd3afad60ae8a0e13544622100c4d847972af18eccf418016dd7c18b082e7714756b51aecc9519683d187506cbbf4883655efa7e8e1fa67f19f4173c3702c25227c5e4c4396905dd6bc45065e94baa3fff9d158362576332b9be3da30eaf3c385e4808a6be0144d49aa4dd6ccda0702eeaee03e082e6917a095d240ce125f58c0bd4bdf09635048d8fbba44577d39e509d8650c83e53a11ea22cac96dd0ddfca3a3d164300315822abdfd3a3f1e83514002094b527c862616c24cc86ff64e091a46f7ae396aee50d2f8b9f1a57f377fd90746576921ad43f9720fc1f60f222bef8f0f1423d71125337ea07eed1793fcf0c56cea3766d5770b05e56195a48308acb50970e085349e227bffdff46716d76ced45d11b40cf29aa737187e3dd187b431039c4e38b0e0bc86fe4ba16da068d5416bed0b6c9a3c18a4f239008329409825020e334e1a463f19a6880112d0b45b413606feff76409f09ac92e6465455a234f134907269158a3c09d9b89615b0bbe0e68bd10e56e69f305684f8102999ba8a35c3886b443a044331174cc443e8c01df5a0efc7b8ef01cf813bbed5e15bc880ad17761ce5f78479830f906e9d85b874acf9e497dc2a6c817f131d8982044428b84b1278848fc51f3512c7d6603b2f13479d5b0534652e74cab8ff3a364186c0bb6e720d1d86546f05d5dd507d93f66df52856298bb525cfcceb070b1fafc397a427291dc57a7dcd303dc22a28e2561a97d60fa8e32c07cccfac93625ac316d8a1dbc271312bb5f881c827f28b3da3d0f5370c1493a46458a90eed295ccca1b0853feb532f6d4fb81552e60f8fb24de95201d4d5a232a038b1d48e37343774e2f75fa1fbc8cf62acc9b74a968f771fb520278165e9d6fdcf9ce1a431a31da16f3cd230430342b92aea77249936499be2363f80f35ce717fc81d0ee3570f0067f86556b70306dbcad82d1a510b0c4db683b11a4bbf143dd8b8b52230a52b58b9e8aa25d2aa83bab58413a0164b75b6997f955b68214f863d214eee9e1bacc122dd7ace81b29c9e0e22a3aff587c96a70c156d4d05c60f1341f289b60eab15c7d1204907b49b3355c5b152a8676b17bb38ee861689b7eae2f8fd73169ff43d9708610461b6da7c4cfb8cb85f974160db45aa601ca36fe7d3cc296d512b8cbc645875c136a7f67fd72a908c9c8bac80fb0a67f930cdf5764fe63660aa5d90e9ac2d065eb0dddb71df98c3822a0e0576f266ad33d12e067db70fd476b30704d7b7eabc0d63a66b4ca9b1f484ffd7043739ac4b49841754afcdba26bf23c2f3bd4c5cf3dee01eff7b828aca2919d01126b3af67c45e3c0f544e1d2a186a30dc77405eae58aa086966c23fd3665653d744b54d7e6cdfd1dd0e90e924264dbaf0e21c8d1ad2780db39e22d12e250e79cd638367d8fe52a02a7e22e25386e8dc25f7534ca8a1748f8194fc4f13ea4971fae26279cbb6761a64bc310c0e701c53f5e5a3c33e098cbb821e428d6a42019b24b1124412ed322e0cf23cb40c890aa15417fdeffaad423c92ba86282fc6b8f41085d78a5dc48c14a5e15af92d9d9c9c7a39a4580117c09f0c3abb28391c0985acb773282cc9eae6d8fecb860aceac44d049dc0e21124e6bc4131892730e0d154b7f2098e9e5d0e08f835215acafd6636a1db91e059b93c09d2fd8c9a1d7f6c290668f814b51859811fd5a5e4bded124cea5fd56b88e7b0a9c4dfae8759401ee5a488fd9e41a250598e8fd8b7593dc6a825779a4b8dd19040548a641b7fe16f1a0d757b23a079b4c1a2ea2d904d7a013b0cdfbf5d05064482d77e42ef7c4e4eae28bb0904c758359a29d008196913e282cb652af74f1ab044c5091e49b505130dc46df4784c85d4f28ccaf12e989d15f6707cd88a14bf90499a01ecb74dc6bc9b65ded2485b719a9580ccba32c253087e992ef7e4039f8a5bb35c3c790ad4101e303861014b907da3c4ce9b1b6c4d3d92474d2b88b137eb3dc5e6d7ebd5eca867f32e023170cf5fc89f911ed69d2a3d23e47e9ddb27dd3d89c938ae62153f16345f8fc8c52f8c1c3d235b70f104fead271901680ed85f11e09e7a787491671ab3634db8d3caf991c1392499622d119b73b7f30482526a520c13a19884ffcd5af7b2bbec2da04f5ee8bd87fd05cb87dba18337c62bbf140b33b1fdb51c61b46f4ffbf6805aa3c1c9fb86c20339c220ab9f19a39f5e3f404a3fc43211a148d1f5411b962b6e626fcaf81056ceeb34a7c2f5cf1d3124bd1947d1f1a67e43159cc274f4264de26780e689852e7856e42c1e7cb33d018c9a1efafa0c1f1f51c7820a470ff6005f2549b0cf38825943ac762ef32ebea0d3e7026ea5330ce9f65be116bbaff49f3696376477c654443aef1a00544e419672e24a23644c865d5822108a11a9623d00844d4608d64bfc648bf937ef426d7084201696566edd360708194e0359d7385eadf3c8534c030e60379bc73ce099f89a852b83ae48c70f988562464c85f64cddc4304cf55dcf1b4e2818f55add49046f277136d84ce1a1feb9785258677c927d7df46ad915250856d7cf172de4480b0a56b956eb546541676197582eddd9bcdbb883825140ea2441976f33e3178210196cd6cc209d2f206c868cf26430db47d547a57243fb75f8ac9cd60ce0a230d33aa832d018236a5955c73c39615b68d41e3a931823bdc8e448dd1840080cdbf7c3a460bb0acf6d691cee6313b3ea016fca8279d1050aeddbe4bf8ee0b065e697d4349bb37ccaef111a69f891eaffbb45173483d4d2c493c6a8a28336643481c295ee366f2879b9d069457118e67406b2c0be35cc186f3942c428974f1f72ef943b46b0a96c4765bb1374b1ae0148c064c05e7347496dca23885ac9ebb1d441a7bb2c908497998bd79959d82166a51b3785be3724834587dce65284ea903a43808a1f1ddaaf4d261d0a910afd76a5fa75a19a520fb72e775167d92e2c2ddda871832e391ed0ea93f243ffd002631ce1acb8fe2a9fae0c8adcb2d8120ec8abcd919817f3b32890be349e82313033a934ac1122e9d87682825ca2a7eb4b1392a423a23544749d3ea5f48b97b140912545737f12da5bf92195f235d7f4d16bcd613d183e5e06d9da0b378c3be186ef3b4ec46cf9c10dc36c60125b3dba054b8bab65c48ec2775ede86c9d91ae08047d896471500e5b6ea3a35a10671b19c157b9838f0fbc8046aa77b34029525d3aa65cd6207afe54feffbd1a8d6d5be0e34cdec8429d7bc833a0955856321dbfac8a0d79379d05d528c82561ba541360361c38d7f35ecac6c7b1e20c8a4e6c43d24f08fe6cf0c21853ac0b82102651c56bd07041dd211305e40b188259216215c2e92c220832f892cbc5dc5f604d70dcc5d6780b87af5af35bb5fc0be36940a287b07dc841b8da05518b13deacfe18115a18930236a8ce5418b6183197047b71af9d4f03500d2761fb4471570a527e1b840366b00e0244de8896164383f6fdb2d1d07c6baf04c1d1c7d128dae850472749a1c4d0423845b479cb5d4a6c4339bbd12e0603dbacc2fa877e8bf81a427a5bb413b047ef841ee2d845b645d1db76ca415407de884a88077377baddb5856374a73c20d599fdd6558350246600770618aa29618e2b9faff17f1b71b423023b2218e96b8bbac58458b61a32fea4fc770a737711ded5581ce737ea449699e14b97ee86fee48cf826681c61b0fdccff0eca9f5ab1854c2ac4ae8d105f410ae44fdc4376417052854ea368a22e0f3e64b0aeaed38413073043637eceb135618317100d5b7e8f301c2b7f20932d5984a8098204431acf238c868d324243854a539294d94c0aa4224f6d1be4589d35a137087fabd0c70ed4d5a7e6588ffb889fb89bc9f8579283da74a84fd1245f9b094564c690be84574a8690b7eb08669327dfe7455a8cc2df256a707f374dd7e7939d4bd5edb1bd744101049e15500586f816ff70423ec637aacb49bfcf39e845eb77cf89cb92d4a740eaf6d5de3f673468d899ef6c9a9ca448ec00e920db93df2f064800ce405915c3f5013e4fc43784c8e7592310ddd2bba3d33c5642f93271ed937962e287d73b5a4c833a189f6619bce1602002734ec9f1774fe423f4591d6081c11801f9d3fa5a229e1e3c7d5178733ca79c63aa4d1d0ccd9de7d39cf00a034fcaa4f0181c0a37536a0e08130d2bcfe4296230cac96a21888ad7debe700875aadb6382fa398e29512f03ab47e7bb7da7c594a9f92d51afdb30a6f8a63375b51897080555ff2b35793a9c395434e1dd59b789ce8a996856dd44b7e626b8553bd15af109d6aa4f30d6cd44b3ea26f85971110f02b271d730f7b49438df4e5fc9d06dd0f747c2ec367d66ce13f4309998d2ace02ed3650cb7947855a2d2b13d3c3c2c0d4c076424959d3ee9a116518561c7d06422470ac2a522a036b656238fee19a2ab99da1e1e19584e66bfff6524e384437ef9d1d52074bff377b2e35d4d2ec6a7d237f917199c5e0cc4957b416888eccf6051df1ae110229de11412dc3bca6edfd6bd85f0efc5253fd5d6aabcbe08665b274fc79b37dc0ce5230461ea790562aafe6c853e97669a687ef97f1e518d71af81dac464f1188feb3d9c8f80e579e25af409794f1742bbb9912e3d382e62d328a77d4ff92bf33306272be12cf839752dd96604f7d58f1903c336c935e4a1fc156d84ec012368a7e8c226dd5240bb68555674639446a16a5e3e1431bb37b7395bf119b13f292f353ae85984e3525a959777524a1643c3e502f9b36f81d54a62da6c845a1a3ed561d0d095bea9fab8bf9e7afb3e26a1807922479cef79c63a7cf2b142238dfe9848d2f2410467240ab8c1686784a62ac40536831f86542f365d8c15153c1283fb4c47d9386929e07839cbfd1ca0002714608bd789ccff5af86c2ae7b2db8e794d0d5584087fb86d807d33f8eba0df3648dc2f31fe8f80256c51708cb2c953eee21bb708d6919fc8d28cb2d901d0ca90c03a545e38f8ecf0831654c1f5b4eba04205f6c012bdd9c03d68986c3477391d4f828c0435586cdbdcefe2ab71c46892bd7320df8eb18655701b9b3d8bfd3cfc48061eb1bf03b37dd619e2a8122cff28a26448ba180682a9ebd65a8044e196ce130dbee2716104d4ba30993e823148681f105255a26f9034c91e925ea2c3799094e132aeb0c87e1e31507311e5b8624642bb423b76c90ea300e271c6d62760d68026571977e4e47c7a29af68e41d03ea6fe67a55205e554d072f5f041ebb5c16cf80a54a07cf7056a0791bd3cc5373eef3fcd7331d632f22b5df29554c6b8cb75e17611be3d8efa8c9fd8940d1ed80a71b3b75475133a9942b87a7e6a9090935217bef2da5943225191c087e075907a377f11e2e7c11c0852f01b8f0050017bea4d457855558eda93c9567d5393b3fa72de4f8dcd7587dd5d89daeee81131065839e576f4b96bc32842adf52c15965ab2a2505aba4e870893a2c144dc88770b5ea565f83e3ebc7583dcf3765d9700c8cbab45bdd7e81918e7ac95f6dd98e77fa61d9b841a3069ec1baabf76ef737eecadbb8ff352e8ca771efcfb83c3cbe319e75e1cbe9e70474fa390165581b12f5a89b07183162702de201660a5f6413db39661917c7ddb2c6edd0df4a69a9fcb7030f2218613116164c53735fa506490dcba7d80075500b0165b85ae5f82e07ae51f94b4353c3f2298f4446e5ef90dfb886583ee565eeabb07cca1b715f25c7db742fb3faeefb3b4c83a4314d4d8e57d52091c9f1d526476795e339301e06ae810103d7a83ec7779886a6a6fbfa4864549fe357f085c77bfce53cb9eb97e9bebe4c8e573d1c758d8be8bebe11395ef55858791efebf97f1fd8efa50af158c72c5c7990c0c230bc6bdcf02e3391e6ebf64190fdde5e20dacabeaa8a93bbdf1137dbcff503a35fe43edd8f80fc533e33f540f8dff502f140cbf77ebdfb8aab77153bec655f9ee1faffc0c1e9ec695f170e4e29d2bb6503f3387c37463d184b69d762e002725db8e00a416d08bbf13a1b0b37bdbe981dd9e0a2738d196481040a18c84f622516f3bb1456ad29363566611c8167d031d825e7c8e234025bd9af43a29392d79b50fa7249c96a0841cdf5f3e9c5ead090df90098b0f4730c70001289840097fc920005c0fc004410422c80c7104430a001314538e00132103022023d2430010a1c51010b5cc0070632a0810d70a0031ef8f181cf63e956d543426a5bfc82dd5e8220042f0d065f5be69208e2d588fd34a1785242821294a0aa7c260b13904e80021a21d5e674f399164bc8f10696a665c0042a5cb5be90ac0708f65231129144e53cf14d5640a726e42db59041a7977b5ac096d312a0177fdb29796f3ba757a5010b5a703ac98972b162033297e469fc653b3c3d75e64e0b4eae26f597582e8caf5da83f39de3eecde277d1817a563baa81c5745f2c928120aa8710e6a175ce01af243a58135b5e6a9289a4994c0a2b0d9cbcd2706a7bad7cd87498e317fce5c2fb85ae65c23426ac272f3fba2e423957e3479fabb44dcf5cbdc3218baa68c52425aa2fec01dce4477dd350f72d4428be54691e42569db644f1a4a94d250449506b6e6af9e44950616b5592125aa34b0269468dbe1e13828da7e3ea7a23282317dc72d4446d457e19457a15c5c0c6a923b6b4cbc0562717a1257a2a0274e804cefe24142c8a794b845163dca65338a5282e229a15c167f19de542fd216ef8fc47c52102651c1f913c46024b7063b7d0bf482188a147192065485edef14447a42122205b9f7a46fe71a5485fa554e2318974e1272af0d70079c53cb7e3e49c3a86cbb950796241484857b5e24b501aec428ba3097ee87ea71e22d730b6f210db50f7e43c2a2d48d72edd8919348292929aa26293eaad18e919dd4cc992ece858ae894223afdc01da7532745133370d4ab3e61bffa5383ba5fbd11f557dd4a557760555ef5df1cc5e0a8581d57d55969309a409d40ca778e6356aff2f0a56f29a3727446446444dc6b40e672af0655a15ac44e1d9dd3146ce7509a3f920fc5714f0776e3d9d97260b5ffb61d920e28e5260e604b3675b0aa4d58983f944be5498f8a82933b9d237e03a145f41faa0839b694fe432d01e50403d4ff505614c0655fea7f2829d400073948a4cfc1d2a96088eacf0e6cfc79f69121ba24adcec06a5f75ac7fc581fd502e94126f813167e22dfd2a548f8e0ce00b724cad20c74709f9c4d68686fc138182d200d9807a4346cd618e84e8775c6f60b7114cb581d59e1b9daad042bda0a108ca81179af5a16890e38b2a115b6b60b5278d789cde9f1271fa2e898e47f7a8d2c07127732491d24808d1f7db9110a76ffcd57c7a534e509e0f212a85e2e2058993da49342aad72a083ad48375763607b7391cbd111213a5e90383e523794eb67e077abb9473130b25ac6f6edfab3dc249f1c1914d92a0b9c8831b0fe037deeebab3e0b4dca42723de880e9c04991fee8441d6263d6b1dbb6ede0077a033b9fbe0dac8c4ed86fd621b63d7f2868d819a97778d082cc291451c0c0ceef99796044ba78145b1d62bd32612927fbb756dd564fb92ee2c40eec97bdc0d625ec9c459220e981133c98ae76d2b6b9e08ecd8a1a3cc90ee4caa14356d460498ef185e42384fca572758185a92d10d51b4bf337eb8d3fb759d8121814e4209a2eb863c256add3b559d557fff9137713c6dc6312c3d9ac0a933e9b3c7177ca908a262461891bb861d24983f8530e2648e7095960bbe234b14074f6e973faa415a7ded8cedf74598183a1ec390c56e000a88390bfd4a9735d81853866df460d98b9aac04ecce1efc50b92cf8bfc6d3e312b8872b879a9f5c6ceffa62b956b0aecbc5a86f46bd684bcc571275f4a5ed1a74ff7e9fe9dddb76ddb46a2e9ea2fd51beb2fb273b0540e760221731cac9321cf872ff0e543b972cca825b298812a533858bf59ee117d83fde616f2fc893bd993c4bd9a650fe706db3373d0faf436d8fe2038b212f33bf788c7cc13f7d38bd2812b4d40567c521624a00c85e79268ab2f9dd8c190eddfc1136c70a2dae289d79f277676a05883a576078d12859c14a54f3c7142e57c28222292859c0b4a0514cc9029ca15b38c137dbd3013dfefb3fbc8b355adbaf576f4ec1b6504d3b67fc83efb3a02227bc75a6b27fb849011211f1ca9420d4778aa9051851aa4a8a28a2daa885145156af8c11669104283905015671012aac2c9cf4f1555703b4dea81f48a74e895e3731cc7715b13f7503827a113d0e9c9490c37a736d4fc9d847a50bac98ef090aeb0239ca669dac391ea472fac48bbdec49d04e99ca2af59296b8fad42b0f2b787b085b245a1d852f9ec2be6704cc9b292b558f4aafbc3f7022b31b3e94f7f7a1717e5c2300104c8823925ca9f8c7d9f455f7a17f7586c45a1c8028219c6e2ab41b028fc8932a769505801935245623dc7114c8f2398f8d0b2d8d234fc01f138bf3edc93cfdd1e4bac432963b1954196a66d4ff1a7ca64ac628f8d84f83c1222cbdb47eee51fe12ddacbf7c16d23188e62201ea7e18e470c819737ec4cb09423e89eccc27e1e8bb933f1034826eec9d2ed1cf77839c20956fa6039858554301145fe2410ecac4296a62cca3e2d8b9ebb596ed8d261ba9db5cc64534edb08e6c48d442e3ac1dc237b250057e4eb88ad09344bbe3c4315c690e5c32f64f9b2075c913f597a8c4cbca59231c982857592e5279b1ce9644a7318e11b24da7746cc1ffd08d774474a0f5f463f5dbc4a61b36b234bfe7482fd642c0a3c205d9bfde73095c752e980d1bb4f64c95864c91f691748aa89fb44967c91ff64e9244b20597bbf5fca01f1c56347ac3ff7da0592cadbf7169b78cc631e8b3ef127fa449f289d897b4252c835ec31f7a48f0f40be50963fa5e03e0ef325def2e9c8e0d0077fb22c658cf664f9d2651064f90b65fea21be936b33901688183b6b3cc5a2887e0badb7dcedfb45376156f967f8c524a291f8ea27fc34c33a55c289d7a7bf4e8d1fd7bb66c27f2e30dac0777c02c3dca110c37e5c719bd1515f6ab403aa28defc9287fb3f171a00f153db90ac526b8b6c2aea0b8e81eaf4d370122153666e9397f9f287bc467e0e0431a30069541020173c3951823d44c29f149ee0f67f81f8edccfba3005c208e4e26234fc20ccc53d872d41b81784b7c4b8e79ff24189cee10fe34b9786ad7c354c70339ca44b0357fc6346f85be50f0ef588ad1aa844fb600298c3df251c82598cf24f46015cf18ff8836b981182ddc926d6c1f2b178fe137f2a55c41e3f9751d3273cbabbbbbbbbbbbbbbbb4f22b8bbfb4b48c3b9f676d1283e815864089dc0261c5c92473d786b8798f256103f96903836911d0a29bc21b024414763ff3904fb2366f85305e595ef01a32c4730212bcb73a2204aefd9362b12439f19b91e94e00b4924b1b07d7d9a4d586c1d0c232ba3ad2375505e3848eb3c492b2d6e977b3207c9c94ad92f52e5a5fc86bdf8af63a8ffdac7f4ddadaf7269f62f2ef72eeef6a63b7ad415b989f3115b4059be0cca52fa904116f7cd09cf4820d8efa70fba09b822bf47ad0357e4cf2e65bf47414e3f4f4850b4af27dca5b0fc8f2d24f6e57bb1455f7e4c6c911e77a747c1ba13ee8aa8f5fd4f284c933d7d1aedebdbc8927c7a4d5fbaf149d75b07eef02c9390e510b294224b28b26c9fae88faa897a98fc234484e4f13bffe09cbd037611a7f0a5fec8d29c544ff12c6c1d1be3e8ee87136179f527e95afc9df3891fc51bdf085b64e6449cf3df9527e5cc2cacc67b3f14c94e34e2990549e9245d54ddcebf6f9f101b4c7a07dfea5bf7d5c89143a7296a9bac7b5d82afcf9b708601c77df80239de3ee712f896f1952a104474711f14587102cf78325540085eef196fa0d047dc75f2a57fffc2390549e9a663265d8220064358c0eb8d24ce81e1d0dfb3ad63d99d7285efc3b46693fc435f07bc39dacf43d8de52b6dfa46c0afb8467bf814d72091a981313da04f033510eda07ef832fd980689c43210d2c06f9b17f7c960fe9b374c870f85c11ad6d1499da49d6f27bf0649f635fdf46b904c2c531f7e0ded24ee222ea29fbe4c3fc532f0ebd754fc6306c1f67f7027b64c0059fe29c896b03398812b0e8772c3b2372cb6fc3bd62ef873c63b8bb10643ed72d839d967bc231c824252725be0200db87d7c99ede3c38fdad36cf4b3b77969176781907bedb264d4ba44c71f8cb16c1ce662b61ef1eb1b417fc335dbd3afb80689ccf6b446fb883bd92ef4e743cb3d4b6c0e470b234bb2b8d0893f18636151d9b49039670fd7ef9242085b0b9e0cafd0a289eef6b8b31191524e78835eb387bb22287645d0cfe88a20306cdbb671dc155abcae08daa2a465c804070a2bcaf08a2037944aa592b5575c8103775c4186186495f7b6855793273370cae80d6d54a66b515879143421fc95f2577ff0e6b36d714a6163fe483ea552f511b92b412571afc88e7b11a523050f684518f2e9fbba0f2c9c821b8432cae52da6ff464dd1e32da84fc11d281f1f258524db0eca488e27255c915f4ab8d1899b433aa35c984bef2ede47302e9e2395ac260433f56842edc3b6b3ed70270a872de8108a3ea16218823bda4082d51458e16a9f1ec4b21327980d88905e24588e40d98a8eaaa87414e6ba93e36b149ad0e915371f94157e804e2f29a06f27cbf2b1e4f865aaffbc124b097f2c9ef722fcbdca6678a552ad4a1c13f722ae2f586faf1a9b8f8d19347858b936aecad7b8ddd3b8ab9f11e379b830fedeff942b835bb99bcfe6b3fd6cb8fad4d896bda55ff59b132cd8af94c3bd7e754f8f48e5ba72727c98eb95ddf40cf108ed94744e2f52506c21a158e5578fd33dfec61d876372b07c0e19954ff9fe14fcddd3ac3eafc396cb81b1cce3be4fb9fd9272e10ba7fd683e300d56a7702f562635567d684c00f5555f3d00200037bc141b3d5c1e5e0077e50370733c002e8df7ee0e7fe3eaf0362e8e4fb9ac87012aa729d8f8d30858abaad22a2b6599b10010b09f9787f016ff186f898ea78ec62e5f8f603b96bf07f281e774b5aa5641c8d08836c64adde54344d019ae448b233de709d52b8b9cc55a6c86bf54ce9e56f810c26a53def22af82b08b184b5d62ccb7e8062628c55ab5fa5067fb2f413ac8daa2cfbfa5c36ed63810a2a7878a6e089cdd018a5cfa67002012e814b96f8cee967feb413773991c642a7b768a01ef21b1f3269ebd0d3c4ddea1159fd38be00647fd83bb2b74e2d542bf5fe17ee18bd7feaa2fe7449443a476fffc5ec2f7d5a31135bfd8a2c22ed4337e91cfd2a13fe54b68449f853714322dc4d88e4ee5737d9be5571fbcffbe7e7e776ee1fd13784824d13f27c95ca5a4a1ae18b1560813c25f4fc66bf409ed0f389027777b8443a5c92a77b96ed64384348b431b9488b6d275329a0884dc419b8748905cba223b64e4fff476c69df39adf3402af8c382bf6ce863c91f4bbf7850cc320fd2dcddbfa81377b2cc5a95eaffff55aa2fcb4c5262bc50995c702831aea6f22f6ef71c8ac9858bc740b9f085f32882222cd0e7324dcb704d96b9a6411a6513eb32eafcfa4856dae3748fdab24722038fa087622bf5f4db27b6501f24a33dea394cd33dcae6e56b21bfa1ce43752cfe52b75f4e3788d2d4852f1e14978829f036f8194ed9a430b0ffb847817c00f4657c64c27a108da7907e8d9b3d8d7bfa1917e5f14dbd49f5316e67dfc5dffbe2e1a883f1a61efa3dd45f99cac0ee138bf5d0e76acff68aadce715744f6dc1ba169cf69b8cb70e74e5fa39f510f82597d5f7fe21e7d99b918e00a7d38f2201823e83cdfbefd20289f4ddcc1c09cc9e43d9ec459f4a32bc9d47ba60fec8ac3dd7c6ec3ddc43448e6c432a799bb186efbd59dd9474178745ebd8f6060bc8f624cbfc5789b172efbed65b2df7efe76fa189826f5a7a741f9ec6d9c982e8c24af4c8126f69f9f4c834eef79753d667b07c0970d77307e7b9b970ec6f632da6f9806098ca75179ed616019d46fab2b731c7545984caba7916ffa1596d11e8569e26797fbd3dd5eeb8ae0b8f8dbd7c8e7506fc4f6275c137fc3a777f19853b7b30f5f528f723b8b531ee7c5e3a03cea71548fe3e271527f7af882f2daedaae976b5bb5d55b95d1207c017d37327540ac5c50b55ca7d59ec3dde93693371211f8a37d11575e24ee4f1a0c8a2edd331f728fdb884f5df5c0867d342321bcf64ec44f8759691b2c015ed33d8aaafe14c46eaf22d64519c65d34b34e528a3fb44c1490f0f0e8fce4c94d11b429985f4c8492c24115bd9e7d48fad0dffd0be5fb2fba3dfd254bc81fd216526a949a2244a9a7ec4247e5e3d7ae0d08d2be72479e8abdcec247a7bbbe9e276f3c54595e0cba947cf0ba807907431611dd25b99a804599e1f33146ddc8ff6c15d529ade84bb22b4af6f84f675abb84bd5d77097920fade9674c261c2de9511e5ad4ff40bd44e168b5377dea66f6caa019120afefa26f53f522f53385a2df5f302714f9aa494b38ae808264887fa1f41e76932fd4c5dfadae3644f7a13ee5038a6e2ce54c29d49867ed59ebe09cb645fbf621ad28f0bc45952fe802bd20736e6d393aecd6ee9670f6cfdd2cb1cfdf432da9f300d12d3d3c4d7dee4d9d7c4a7b89b46645fc235fe19eea68b7753bbdd11f2c695a3b3c3e363e21e30e86787b3715a8a018ba6655a5669a86c6716b8d2ff90d53f2f4bf620496477150bdce1197e84303a04ecc7927d077771dfe1c68928e29711f128dddddddddddddd63cc522d9a910533a35956b34ae7859095c578c3514a29a52d299df423a55f679c32dac0a5e8264b28e2360dcace5f96e1d63f9bfbc6691a9c531003502652656e078d935280ad1e10ee8866b05ac8d20a593e0560cb333064a94596300d594a7792a58423984d66229b5265f7ece30d3293fbb71ba41e19bdf7c81f2ae1b93f8828eb9b4ee64758c8e8477805374842a0bdbf90172421d0be13627bff0d038979c4c35fd3beb3f621884eb42072931d7355e49c7d2cb27cd9c43df993dd08f6934d620aecf6fe3e700ff7e04f14726f286eb11d1103eb5aeb5fe4d7118ce631b03da2dcee17bf28d4637b3914ef9191086496b1d8f2584ce52d32169744987b31266964af9e8a3e91253febef9eeb6e8425b12d971c197d768fb8fe65f4d127e22f831b46bde6e29248148aaeeaf173847c19934e62bc54e22c291249d88b189630f9924ae20bfc6526fcd914fe54314625ee49f9924a248c138d60b84c899963773c441f3fbee845d8023942b8429f6bbf1f0d1f111145c0bd12599e91eb5f98a3be8f848899de1278e6bec6470122a2085fe8d5972321248fe8b123297bbfdffd21660e3f5ca9efe2df05728c3206fe3218f8b32b1ce5cb29dc935cc592c73db9c9973bd288b738963adb9539ee69b2817898b7742f3f2ef196955db7caddd63d1dc174b86df7e41eb12599384b3ec61f14caf2933199ab8fecaf5d1f6d58c68a60b5ff640c753fc71c7c77e22d1142d843c3dee4ba133258ee513fd89d7890b748d55b559c40bc8c84f6a98f1a47049be2e00f36f5da734edd47301af626fee342689f7a1993dac7e72e121aeeea6b1f7157b10c8cac0f8897392df5dc4dbd0693c21ee44043d098987e130a7de36b7765d5ae1507abbf0b9a6c179a6c172eba5b6a3c734efaf5679c73ce49f194936e9c68442a59d3099542712163eb458fb7a86aa6e9e4a0a45027932d9146226ed378e8342284c485397bce39e79c73ce3967cf39e79c73ce39e79c93ce4929a594524a29a5b48dcc39279d73ce39e7cc622707cd681ccdead60107cbbb61a3060d992e92056edcdd18c7f477c146db681b36ba9350c2460d1a33da460d1a337a860d1b356a746555af561c2cef868d1a3466c4c4204a75c0c1f26eb44a87afcfe95075d00107a5944529a594524aa977a32ba594d24a637c553dbc3168d5aaa683ea7642d0af5f69ad95565a6ba59556add64a2bad37eafdda5fdbf3706817c7d75bb38daff8eb8caf9555bd5a71b0bc1bfd5d90f1534aa28ffde22bb66ce45431de9bfcf4102c1695e444964eb6e3af1ed2394dc43db6cb27b22213b80574028120163a0ae01016837af076781aaa958d2f6779c45f0c2ad81831dec5a3126f7926b229d5ea69e42fbebc1d74f84f891c67721c8a2c1fea237272727254ffcaf11559fe2f1f1b97cd14363d39da10c951c8508e42e090a3cd4d8e36383966d6851a28b2fc29fe843cc971c67f427e7214e224472140f9fe27240ae1c9117faaa79a0a7f0df4c58f5f8134508e8155eef96bb713a23fcf9de7108bd1a77b58f084501649b27f4f93a61de34ef66fe92140d113e4ea48448b4677c75b8c784b7de771517bf68f4a1c6ee1addec19230fc64f7f8933d02658f658f4db23fed28cad17bee26d3b8df77cbb9c9f7c6f7d5f20d2258acaf57071f11215f878f3ad8f8bed46de06f2220ece626e377f119df44ccc0c16a380ad239c6f8cab1577c451d6e3f69a1c8f2fe01eaa1201cb79be4c456f74496ff2b83d99c9ceccff2cec976fcbddb437c62ab6fda75e32661e32a51e3ceb8e74fe3d200c5d6069ce5fe336e8c7bfef8cadceb43c8f3fe55aa17128a98a3b7e3d137b987b8e73fcaa24cc36538e211736eb20ff772125a862322e2d7a744c8afb89f545782429999e18847c36e6e728c7bddc43df79e4276a633097d0702e6faa2f70f22b646effe3d7cf8ff4822b64eef3f135ba8f7ef9bd84aa1bcbb787ff1ae7a9fef53782b7bff8ea9bc7ffb37506cadde61bc7f0bc11d3164bcbf8ed8facf2c7f655cdb3f70a57d3a96d32f6ebbb8283789fb23b2222bfee9f688b9a5eb72755cd1cd222bb2362dc69f4372fc6a24c7a737e24ec84efe8034508e6fc43d1ef7fcb32a32b19f95dcb46921249b16d23654931154bbfbe9c398f5ac53e45e7f94463a1f098a65762f42f7883a721d613e3850c8955384d6186ff95864827e00d1f116a84477774eeea6d587b734149264d14273ff06bc257a1c0901a93003119619a2c78f1e313e323f82080a0a2248668818991e436441784bfcfe21bca5003adaf6f09eb53d9a111deec55ae543f9d2bdee6ea9695aa6699acc3429bf0cb78e25f047fa1205c4a823e6833f51c70e1519501738d8e211c6160ed2f8349f2c9f8b353bfe547265adc7d5cfbbd24aa526606b06b2e08e986530e4520c4191e5a300b6b61564c94456750d5a1b769dc872d824673f135b9be339e3ac35c618638c51fb5a2a693f6f8c23184d2b954a5a2996de9f9a54583c497423cee3463c6adf3733eec121c71f4b76299af3bd89471d6b58c36a4c356c2ef98aa3caa7d2b08e79c36660f155ee91518b4066202cd95d60b00be4474aa9545beb9d4912951ee53994fba3f41f0c0222ea9dc69f4d792c606ef2ef44d2eb174cbec798c87723ce23d268e494f15f36c459a4fbf9c8a4f71cd789aca95dcf99d75d4334156cf10acff971887b92f430bb7c9f539b3f49cf71a449e2b47ed2d4b008b46e12a7f59326d7244dd41afeef0279ce4419f8cb6260184313fb4dc3c13df9b05d7e0b7503b917632cfdf01694970f2495515619854646419941f93a824199892d2f82bfbec15fbb34fc750eccab2bb38df7fb895d27fee7d85fc65b3495a11eeaa19e69ed231ec23d19ed511e8e808891714f4a9556d2b4ec35968c447c95d7fe63c9da4a0956e56147a8a87c8c2cd1878871cf15105f65262bd98844c41de9bfceb823e11f3a77dc67d9db640e77468c7e7b0790fa57bfbd4dd64ad0b955beafca4715bcba3de2b7d86fb12f57a4d9b36133c69427a9a229de2164aa488bd7eaf8ce90eb14711d4fe22db1e5aec8922f7e55f21c77b927dd95a50ff11c6f893162cf7197bb3ce72587534f6a5877a89d547d951f3e957d716198580264c1ece2ce5b8fa05a0d8b2cf9d049843014fc89b2ec3334a2d10e25893e95a7636b12eccc3e47303334eec9beb1b1e53a29961c5fbb99714f3e0fab13654c9e2f5d279252a3eb4293c8f3e94c9e4f9de7b399a1e91b6e3482d132202cd9b366c9132ba069964b2f5f017e005942cdd00c1521df5ee25ecc5bdc71c71ae69e6c58c75a59d6afdfb0f595fbfaa2114cb59d47263922a24e1ef135915f9b1259d52aaa686c5eb6ff5cc78bb8275f3407eb3b5e5f16bec46ca5114cb71d05f127c5e8f2a3378ed75245c2b6240605e12d90c65bd0679a48969f8be48893e573a6d10f1167c73df9d195a5ebb48e09e0ca09e47fad17b40ae44b1738bd88b720d4093222348527b99a4fcbd101ac18820316423fb48eee355100059c6da8d4ecb685490e158d40000400f314002028100c864362c16038266abafa14000f7a9848765ea048a324475114660c22c610028801008088c0c0c84cd50468d7a814714ab8e1010b61f70e433600f81b1e264287a437d4b6145b6652b87b508c19e67f618e5bb50ee4bd67a74db7d485cc23ddfa84561ca467b4829ea654e8971957b11f8c95e0418cbfe3bd75f096680c4d45950e1587077d6c3af1e208a4f12336446adfe15e1331640c03281cab104d49a0723812fa004db8280eda3d7b6078889895e2d18c1ae7dde657924541a92578209d9ad02f79340357047646123e3cdad50fd8557f192ecb5877781d13896f5c456f45ff9226fe3f09c6ef8adcf8dc084bbe7fc889e75f0250138e7342ec0195559956e613305652e0ed17689862bb87eb103d6aefb296a461144ff9db1c4d071feba713086f0d3feaea0d53dd8956ae6854d4bb148fde52bd101dd16b27f5bdaf1ff29e6e44727bd18fd6d72539a348ee3ab2b4a23c49884541f750824581eb937fab8fa96d6a947f7aa0bc57040bca39bdf76c1be16dccc5b2138aff0eed17909f09790ae424efcdcd294962b43e134d8c12f6d89c04f624a547cabdb9bdcc03819f1eb5f97b1b82b81202e213bbed124b74fe63e4347b6e9efe690e088f657ac20a291f5edf3ae45fc20e2e8ae0ef7ff5a925d96ed6daf9f7060896a22afd6c55f5838393f353103d08129275f9c7942ff16c93805720ac7a4a1f083246a0adc8cde67263ab61e87781f8fdda8b607c6ec4b07e818ad7e0a21f09ccefb5bd0ca400f25fa08045d4124e79e1703385d1d1eab99306644f95caf7e0727e6ca87afd4a9925262c1fd175d6e5ee9a41425f0faa5b4ffe7994e54b1cf90190ce3154347a5da4043edd3754ed135ab82559913f144137f9818feb9f86741797b0599ff39b7a813f2125d97e3aa84d1a084552050b7cf1483acab404535cf2c7f6b59709bab03cf03b9cd05b02b089428b4ef5eb750db2e9c064331ffe2e13dcc74bdb939162d5f5ac51b53d53d48516b387d240cab1d4939060401de95588d8272ec0550a42d8fc632fd0726a48774143c9344cacb84209afd0523aeed3c9c0923a5b2a94751449447e8cd90defc41772790059dbf3d70d60a7234219161db58e568ec5075238e1a277e646760aa0223205ce5edde8a423ae939fcb1f42be570962e982c42ef2df0536dc2a8af975c49adf7026743c2ac425d104d974832ef5f7f6e6cc0f8a4d57d87d73d704d0412f5000c23efdc8670495e291bfa0f4d960c3c1797d13d52441bc1fb3a761b06d521816bcd7252abfff7b4fcf2dd6a28700891d5af6ed05a472d38356b0b71840b0821e355df0a981c58cbec0920854602b17d20c989e7217fb9778f4b53fd392583a33cbf8c82350445f0fb6e7c1a24f8460b95ecce77ff5a7610b55476878e532acd481ade5cb9acbda1fe9692cc29e6972d7e15f9d7d29f86fba661340f8fb749c63c6ac180e1786ae95287642155212752e32cb1989f66acecd372dd0976c0140a399745b376f76218f5c76c83a3f9c6b1bbb8222a94486ad9e0cac064b848363cc6ac519c250fc63c67a0410a3ae886111eb3d81390091a2c70303d7df5c0b6949d0f19c47e68135fa809953be3c949fd84a32360c56e9c659bc2228d1028a4ff9e29a345c0c0b4a6ef27af34748848ea10e03f55c5dc7994c4ff555cb3d91f644185ba3842ef067542dc74267b60f2a641e2b87a444848f6a7b576963cdd67367eb912eabd603510674d28656d3cd0034ed4952d0a6664b69e20483081ded9128ef05beb3ef3ec33370af0bfdc581ea00412f700d15ebf0db39188cec0195fffe9f26da2c9d1cc89eb4ef1c92204a9912a9c212d0785bbb6bd4174631a14de01110920c675fe287bbd5de64fa03f99b021767425b316ec7c314759b701c00e55ea27bd00d773c5da0fa2b27defb6df3d5e2ed8aa0e9c36479a355cf8cba081b7eb38018631d3f1cb4410d6a4a9ead94fe0dd109f90aebc76f8b740ca6169329ac86a8cc62b1c06b1f651bb2446e6cb0dde07438d6f75422e7f469347213ed391fd017d598c0a1869a0258130325289e2d2362da1f1d052c68eb8099b5faf409577d50b4803fcc4bb7f25440d4211be747b9adce2d3ac91f609427ac90e141dce51d68303c881fe3265a167af5351ae9b8c2afa68f14d1a7cf9d0be685b0c9c6e74e15b80f695d3aed8c796f7a1ff589f395db714a0b86255826cbcde8e2cc839b3c44f547c7352f0c7f9a7849bd15865e8cb7b0dd8a73a53fdfd3ad738a80a25850a351f9936b55f7ec9c4a452be4cc54f3caca6062a0ab51fcfaf5014ee8c68bc023073a106c13913adfd6beb3bc4ae9d29d2829d2a729237b08adbb44ef760c0d1affc7022f26f4751ecfb483bed04911b46357bb51f26d04b5015c67f5ac025f94a7d1a36cd13953e2aa1840c312b3f15911fecd900e1233e044f0d18ddc32d03cd5251e0cfdfb519c50aca83af4b3b7d43f4df08f72a13add57c905a2dd033b7299dd56f1b2d7aed0bf04f730c165b10b2cd4409a682a98b013159d41c378ec13e62e117116cf7070c722efc2d0620ec5238ed0b308fd8debeb0725a1bf1115fdade499fcceb9f8ecf73fbeb0c0dcfbe62fa91162ecfdd52e13b79bafcf79b3f4d3a6cffde70a778d9d8b0475472c26002a61137a87ceb50b6d407f53c904c5bd7b1428a7f661d80c79b1e0506cc8d49777096e42134c7c57b8e9c92158cfb455e704de52f4b113c34bf30c72950d54ebad403bfa14062e3df85cc50666b2a56f04cccd4f9cbaa160559002e0a39fff46cb9238901f8ee020684e961d42eb0e20a8604a4e06c831fd7ba933cea68361f7e8543026f244b6c89a37a100e0baca0abbd9bf9fe4d73445b88fc462178cd6f446024038d520bae8895fa10018d0e8a7109a2514794c002c2fc6ae181e98fb6a1a0c3d56e94009ff9fbd053317eb90499539d866c998b69047b137ea10fa3fbd5523a723e5f75c4886d695244322bcf5f4cbae166249cf54f54200c184d502d91b6df37fb4fefc73f922457334ed8506b152782d2ba65bff3aceadbb26331d2bbca992ba906ac40763c3ad27d1e226529c1b647204e9d1c910b29b965d016a66d423ba5073636cb2a50583ae126abec329d2425a047931b602cac6f5d585512042e5869f6ca1d78a48e51b5e245db6e7912252cfc1414455369befa3874e2a8037a82cdd0ef7ba81e00dcb0e30466f84598f9994c0116987fa4352f910e10714190157f15823d16a23ff4bdba16c67f46fc4e39014c71a3a1f1d45c35221ec0382f1d1c1918f35750fb30cba5797a012ebee3de1b306e53e65b21e7cd6c84feb20da9d662bc397b22b90c130955bd540357573f2ce1ad583afb295e5483fdcfcf4a6d65c61fc8dd0d0a065b77c22a2f7ac9c7eac716b62cc2ffb966ae66c4b695a8fe63a34ebe386554322722fe83becf9625bd692aee6d8c21267001ebb409f5302702c8c2964b5a879e2183fe53a3c02d40a0590959388ecf36395de13ee6e965311e7b81306f4f20558248daa2b4ad42268dceb1f239e280e67ed12fa17c1dca26103c82201491ccae90eaee141602365c412e67b3c76a96f0b0705e05b070255e78c7c30c9a5c114c3930842d0df61b9845602aea4573af7262d321d9d2d977436fadd193c02750e654e67e6abe75ec3fa38e2e3f57b49bcc19e94651ce27068279fcea6533aefdac2bfc4ed4f0e82829aafb669679253eda165439660f7891e40c0a1e3e094b4b1baf6cc046ffbd801830b049f45dfbef88ab2d7f1c046906f9dae06b87bd636673db0024ae6a10324945f69a9542f321f294a4151699f85016e1931e729a091ef80109280156c73f5b04f9966aeebfdfcec31ad0d18beb0263333c749a0494e5088516f767e1062ec6250d7d7a590fcb2ad20d5ad7dc76471a7ee48d213d0a711ceda5ef021fd0223bdee1e03929d5e4534e82aafc88d393ba6940661b54957ebb01c0fa30c78669e24053dcf436ed717d2fd6d63fef0b803887a758f80edccad6649e94e269bf970403bbc068131ca76b6e6a8d8ca3d529c2ece2ec9b719558abb0f99037f6f41af9cca99512668cf431bfbad371917fcace72f2734ec52792d6cb2b4da112ee93f2c25507e139d1b65449f238107bffc986ce15bc1d59e6cdd894750da53e783ba136e420bed08bae2decf6c7dd8fa4cd7273b0294c53de492232c039317ef9365dcc22550ef8f1b68443001715a4dec87d874b1c9c1d50440997942ec6a29f3c90b51010b9f07caceab6ea50050b635dbdb717b5ae4f27566cbac6bcf92709535cafd9005d86f80ca9f5068abcc411926b54631ef4255b136d0e9db13983c5033ace75e8d1e6176f9fd02f9e7db596905e8bc583ca34c5ede81a251def6d6724fa397bb130b9032f250ee0b060bb6e3724f9974d1d1c5465ddae9454615a150f42c3d9c0b6543448faa2ca608729fafb9a176d1d656bfd9658992d3a6f289c0957d319f16227a3dd1644fd4b52e4c6de80e14494611a143f6f859c2065167b2b2493c1e3599b9f598b1daf553165c9bdc2c70418bc6277ee75538564c78684d46d90bd6904fad3573adc962638e844dfac49ce126ab492d7323ab21bc208c96868f4b6e325d57dc54dffb32a2209d9b6c1714d75831c2292312272af2213bff91e970eb8140aee051f7611dff47430222d70a06e45a35f489ed43d01d713ab1dd6594d00f1bb8fc29574b3e08d3f03b4e8a416c167450ad0f48cddbf88065fa1bd0cef11b642252ec965282146949a098f777f9cb0643a2169b0ea312bcf36681b5893903c34cda7d75f3809d594cc6705031505fb10d39b2ab3c9ce7979ed9a7f52074090b6956c0434145e438d109481720d1fb0341aa465341fa29da2360321f3e9ba0e7503560ba9f83bb1d4edee54887a635f0b89b4d86f0e7b3907c28fe39c731ce6f1e87a6a89489199863754f469c6c707c15489d442f73d08b1d8e2066ba8b14e18bccb15c5aa74a4da632a1f8ff9a222ab761c3df5282b359991e1929e9cc7316abd66497698aa465e783e2bdd84c57fffe5e88d7b915062d6f8511388b1ccbc11b903a647316aea581104e1814e187fef7824ab8859dc642f9a24ea88eee4243f6c845e66c9e0e76f0ebb76fbf3e906a854159ccf14aadff26bea616b5659e236aa5a29b27028fb0569f427478722616158de2ce5bfd6f416a11da18af5a11e2e11097de30e5561e17d626c1f442b8e39ac52b1630291fc658a32d71fdcc75e7ac489df421fce720d677f0fa0d7d1ab63f42b23056db21282eb9770c4b2de34000f0a6d058c1470c9275f962612100d3552bdc023b8206f6cc71426ebd9917c50aa7aee23e23f8a9f221a452d2f0d09971fa10044384f950970052b91fa1e278a96c9e1e558364092639980b998f8b470fe5b2d2311eb9e5fb79de59b85fa4ff835b349f9dcd6d486e211931306731e2ea67eecd73f64ee4930e3e912fa13f0912aca4d6fa15b2eae5873fa1dea504af815a7a53a981414a7c656ca0683155aa2b1b2f3e656d3bf195b3c55c222143140ce6997ccdbde74f983e451a60a4b9c74e10ed1eaf86df6654045bb257c4a3455f4771fddfc0985694146b0910a4cbfbdad47c82c76d655c808f5dca37b7d617249a33339e053e03c2b529f811b5aa9505c6f8e0c13dcb47e973099312bc4a559bbde6a345ed359027520084d510f465e9ef21709032701a9a05289e9f8b15f3c52fcdc97b580424e5c1559b5e5578302c33acd194d1f62ab09eba01eeaa52eebdf66381a1689380251f01bba95709d5e7a23a25b5b8b581b09c011898d30ef11a51d6dfc478efb080e3d9ed6a7fbd2624c8846d8590c0ad7799101463400ba8dd47dc4b86399276e67bd49564cfd5fe84de86aaa257979d23c6814a5e1a55aef0b7d34c18b49c921e9b3248738bf7146a4c86ae6ef82b0c1bb3aac733bec5fc6dee0bc286ecaecfdd789d54eb9745e13bdec8f11dbd6ff3d1a7df8631ff31214234775a01c026534ed4cabed0ee2ded1da182793e8e5761a3d80cb4f8f973b7f65792cea0add3a9b790f76438a57856db2cc2d961cc667001f453fe309d8c2a598952955a2855e7a255f80377043daaafb0e0b2ee7e2f68c6aa2e06c275e54a75260cbb632bdba422d4bff05dd629bc052bc1be9548e1c8234b3158ef494520a71fe983b2c28ff9ef1969d329057a5c88d6464efbaeeea6d42ff01def64086524ab1c393e17a1ebc32097cfd087ae15ed3c26277b8d78419190ae88c54b861f8bc227cb372c290aa4455a7a56b98c79734c7f6840938a4c3935566f916920d151a034edb60e898b60ccfe72f3784b65ada65f53d5f03478917d6e8e3189febb4935dad89d7297b0f5ed40502d9a3b659c57f1f478e55dce9d264a0906bd11e49cb5e0672d40aed589016332b321008c3bd769a2cc66eeafb86c68a8a76cf04151202c75233bb0f6ae2bfbdfca401e2536713a39fc8ef6c05f8c373639bb1a6999d0f5150e366e73b8d4bab9acdaad12a6ea0337121e41b36e06cda04f883437a4b0270cc186bf71d6d9510efec18b776e2eb1a64f36e5d4a74ce32a67bc673d9f50f990f49256fd549553aa4caefad321d13d4c4afaa5019584939a3ea98dfde4d6ac03d04768ca90ae5eab0350942e77562eb1619cd4b762e2fc92f54ed22830abbb8745fb1d417fc59c416b6128385502aeab7da80b483a003a01d93d55a1598a5df7cd25630fc6b3234fad9b7a37a1c10770a66186c0adaa844a98eef4e0a5c07323d3d0da5f3656750f3380885f0048e6eb00968f362f8c61c4e66e8f874133b499cbd90a03b8a4d40cb7bdf586e10251a11a9665ef123ed900c42380298f3602c4f58c591e71a0c6458be3b570c81d1ad321af9cc419bde5acf7a76c080cda093352119f62f2588107acb0d4f92d7dfced96d54cf712791fdbbf50603e576e91687cf54d8367911b7f57ba59317678c3ed6a9e15d375782ea0859a6a0721bd6885e0b95ce0874b81b4e6187c7d303ecf00045c7eae2086b841f1ac3200d44d0d9a0cbea32400bcb7003868b25b04839a0840d35fe8b9d7de2f35d4bfec94b8f687e62f22cf63e8c8e2700200f82e5d8455c162ff8f076c98040ede95e10ec85142fab70bda5682827bc4a407d786d4a10872851a4e74becda9c5d6a260ae5f5116d83401f58018ab525de9967356b44a224a2db7dcdcfb89d38dadf55d84d74e334eb61b4221d173f988dc1a6373681e16e0adcd5e663972c04ddaa6763c20f06eea0d5771f6c66b59f825ab60bf42ff0d68c2c42935548013e0c4697bbc108f8a5b70d0302ef4e9fd5ece4b38511007129f3b35acd0262e27c7ffe9870ba889af29d3c52771810b03f230208e7ccc0202c4e174f10ed04a1ad535f65318c1f39cc0c490168de0abcf96b33055ebff86b86440974e3456c84860e2f6a7a40b707070d647343c83aa175d03a6d5b36d3e21f2ae2f751413c7f3e8dd42478e0647d5be8865103098c76f875d4fc5dd11f6c1e5ae0bfcfb215f64c0a2cb509b0a0b63ab105435235080908ac88bcb6e27b75dd096d26dd87e25d23acbb6a1390c20135d96731a060feec157032be07b500260dc7ef2dc8c79408264fa9ceb0792914928258390c6af93b100ab30022da96eb1ae6ee7e17ce872f49ba3a87ea4c5a9543430530016a7280c972e087545bf853f8ded1884d3b4b454540f21d16f672e0d861c2c5e1b8aaac48ac868685eb1165f80803b1698c9aadc61058dcc6409a089feb1038580b582724f6d2c9a50874aa70908da0ec068fb9e18b07d3050ce9a8471462930ac81621e01af3617f14bd39f4f8eb5f8374341f31a8b7ca9236931aebccf96b24693c04a499c22f3063e16376ef5e4c35a12585568c863844f6b5dd3ba8e9c0b5117f1c2842b15a8381542ab1154bfe38e2b47b89caccd57e8ee310f6d179148f2cbad253317b7b779cbd5fa9254e39f147d413c8a558a321ea3e31301f935c75a3ca7166e729eabb603a546fbfc787b4467599815c4c2d8c6586b32a451fec6d56dfeb9d1dd246cbeb4fdf18609a8fff5fea7cea6d76c2f1f30a6d62ee17003dbc6aa2e17f1634162b36d0351739a0cdfe4a9fbfde6709ebe216c0751ed0cd238f11e01474f64eeb0ea7e430a409d709936a8d785b54297c7adafd37ca8d76f786e6852db4ca3b17aa85e49ad7b7518232ad2331af09aeee14a476bfb5d00178bd0cf84013fe0a7cfab5a5402b1f17fcd4e541579454dcf986feda1d9ecf49bd77f9e601ae8d69a7d9a49b86e93d9c29d1cd37105926ff4efa5762774db8047be916983ed4c7d6fd0cd37739b494218addcc6e2551bdfeaa4d64d4efe0c79fc233787a99be99447ab0113e817da99537c9e780e01384cb93702b98e1b44c15c75d9bbcde7fc70e7fe9e28afd5a515a0620e4aab94450dc0174348d4a6f187f70da52b53d32ca7899a9307ee18c8206e5fd286b92f970354e816ac528683c965b19425a397897241095771119206f71aa968b0e63750afb88a3bae8e2b2245e48d1d087c4c0a29f13329ca1b800c40af3bab2422eb644e21a9846db05449340cb3394b05dd05fffa1e887eed874e82d5b11418df9ced4793f2c7358631a637253afb9980300fd4e5526b1b950dad368897a87fce83d8ff557d4bcffd1b47c3b39a2ea368ff58b3e856985ec2e29b5b9cf5ff098ab8f2c785a5c691fddf9ec836db3f6708844a092697eb2e8715617265fb4b3df4bff9b90a35a9fbc1f66f8b1343ee3c95d6b7b4d5ecba32ea863ebcc3eb819333011a2bfdf8cfbaba108fea9f8a6cbe543effe9e40f9727549bc11ce39479acceac935c2a258fe05fffe1d55ed9ca85148d96dfc60541d3a4b61643d0e45b975e78d420d82f84f2b7960e68a45d33684cc36b7423a128fac46b917e922e55bf9f104ba637fa39ec3009a31578ca4392dbbc364c243e7656aa88ec62a8344721d0efc97ba6ece8a4b06598dde6f54fa772468d245cc7b5334125c0acf852b1e13011281e42c4a44eb3787743cfe7d1fb7e4123285b146e9c14f3317adbbe148bd69819bf25fbdeeac77db3f4d44db0c3619dc82e6d1651dd93a2f6de98ed8e03a0a426526588874e1f2fe84b4fcbd87533994be098ae1556de949eb32dfdbae4801f06f598019cf808edfa5eb139ba0bf5dde5d43680de7df67899deb285fa6fb66f327d75d0d44c45a7ef4350d4972b75cd283d2c02be6572250433e157d9b59d7a39802df344f796fe589938fe506a3e5098f51b312a6f6a72215b775535b1e6e07e970f880af765ce83dccded28668f771192bd392f71c3d2a85cd94442d325215c0f8ad35f087852dbc14bd6db1eefc8ad592cb0e56f0012c333f341d1ee53136766f728c3ebd4b1385e7d1a1999943cc14c806a0e52fd96ca79200d608d3c2bb4e459d9a841751377f099d3f625198f404807674a79b699460f7ee7183444f9283164730914c1922a36ce2be74ab1232ce3a0298108e337ae3ea2b363b58912d9b220f770c1edc05be2a5482328468d37713a5526ae07accac8cb2e95a82d99be836aa3923f1320e7e5b9fdd2e47adf94729557f13718ca20071989e3c8503c9ff0a0f21e00587610e8221885819dae33a835c2b36464f555064d4b8312622f28c3432dfd7ead442febd0340c13626a90d5774d55d38c10ff85ba40d3a0a137a25ce49c1323404fed2d70177346b61696d6a718ec899bac1028816f8e13b961ee43189bce4af2479c0d13fcf189c18aaffab26dbee4300848ed58348d07f121b21921497010e252fb6995c5222a02102692009a502974b3423c7d9c2047887288c0bfb10011f24da5d645ae828958bd2879d108fcf5e1895caf773e7c4081b46e71b213f8f9a640c76a1577102c2f176c500ddfba34359ba2e7e46722299d68881e4e7fee04cd8d9d804418e9d09ad833a5a0ddf4475107ea8d0483b3b0f6d408ab2d60863528e33ebc45745e8dfb5fd36a8d9e7cc3c49f98e8ad917c9052f06a85458d667dddf4ea9349b63fcc6852e575209050dbaf72d5dc3f0c6c2e07ca4b392029e195f96cc9b58839f4d7b94ea4f179b349570b1c7d555c91122f6ec8d7393f9aaed138d2c2afa871af78ea4c8841b77d5661035d0a48c7917133e5a045b016987e72707438eeef6af4e609aa7b6e58effd9b1181108a4ebc0ca38c222961dc67256b579b03a1b760d5c1650c8e6d940d683c60945ac7daa9e109fac71b7e3ef7419b33b0d389927ecb3da125257452860fab3ace2f511b5611efe2d06d980ce521331c7fd6ed0531750a7bdb51714f68276127254ee78dbd3c32767e86c18dc58f62afe78441a564526ccebfa3830a23f4cb02adf024d760ee3de71e51739aa07e816c4925456f5989c3b0a048d88e045c10b1cb7a451529faf25d60db4c372121e9eae67b2afdff50c324d1a5cb8ba06984341e388328143b1f2f0f2a622c8404c215ac4b1d372bc84cc73927dff0b2a5b9066181720acd23545137d2406ee2e2f46a10e2d7ac6c11ed02717b8f88659812c3d2f9889f52dcfc18031195e24d5b38be652dcbdd289721e86eb2623e8760c2ffbfb34490f68a3b2839f80f2fe8b78bad4aa4d720cb031319e295b0a365b0b1b8871dc9d1cc0181e0c36ad59054196b0fc736e8fe3f4a771807e2cdd6e7da08d91f801230a973f7820e20b505ecdd1f40bc8001d5a1ff797e5bb11e31eae73de7ffd30dfabced1103f1c802e71544058f37f4580771b0830bc0e09bedf222e03e0dfa5fd76a880b658734666d5b68eb06e5b1bb6569c28ac24deb9ce6bac73d2836aa58b0f8192baa47b6d006a057df2167c53714773d4b473e382f6bf50a0b3e83c3d883c6e526bac98ef6f729fd47f996ee35c0b3d263cd221f9937c33dec89d0e3960395d132fb6d79babba76ba9613f4be49d41c340a545766ed1b5324241ff0029cf14913cfa04158ba9d4ad27827a07ce6efdadeabfbefb3fd4243b6b478aaba04e522cf574f740a1580dddc768020e9240d99931861a5442f46fa80d34b0d23ea74472f026727870a216c61fb2aaad408faf8c82723ac5fb42c5c6b543a3874718edaddb4853488225008298c7715e388dfd96a0ea78c65806ff0d2c0ce1292b71da47b487ea089ca14c0b343ea5df42033a888c77f960ca6d9e8a77b5052abb7685b6adc95b2931922b724ba539733761b044eb24eed950a7bf08884e59380f8e9b87b45b2cf11282a930acfb2438e75715ea00b9fabb3f1d32d37876b3967b9d19c20a6491176c9779ade2f11041d4a0261cc28923e36af96616b27e0c27002b3a7b365a2843482f2bb6bc12530029a82e849aff075ea9ee9bde0b0a495c5ff2270dcd3aaf4ceb1d930dc85cc021c655fc483c80dc6c4f9cab1bd773dde02e4648d0d8c94ed0b520ab6f0a893c92837ee81632a72730c7b64c828c639a807c92dc41870a1d8b4e0437e871fd387431bfaf356b26bef886fe7857ddf97c2dd3ae2014a6f2e496ee1e078dd3eee2f0fd586395e7614fcd34fae0b6f969db9dd1b35e6f10097311ead7fd65e92b9d4f1e5c4ca2b77fcf34ce9de3c811145ecfc0cc7a186ec18e6e98726ea4db6e95f8183079ca7f4bcaf044bde37e379b33de621ebb8a51a98c22bbbde09c1e1022591c58fd81b5163d9911f21b621e4df1684a06389223746b1ecd397c262513c492b156835930d39917917c9b932b26d6dab0ec83dc47e50778e3c62dc04a79a4089664c0026b9522c06d5c45b290dbe9278e2cfc1d340e9f246d702dd6c19af68affef8a9bddbb37b01c648b5284f69b87d55cfc2065e75d6a006ce471e7ce03f344d14f621347d1e76ae1f7d58c50132dabb16e2364052d9a866c0e524d87687bd190017fa7fd6f8e617598c5e1d36b0d86fc904354eec0695047c0675bca5519ed9b8c7a8c1fae3faae64f850b7833163202267f70e1021661ee882a678eadf6f4bf85522e06b9b6b7ff05c3b38e9c5ad87d6dfa36a69294754af4afa7150825232d01630671dd2ee033a3e17d95783e8f4412bad20ed3f14a00ff1b424cdeb94294d25055ad842d1d22c175bdc14e39d8f83bf4edcd8879f70e1c65021686391861cded27f8a66ce8d485e9772319d4357a733c41d2ed8481567abc5f407c7790a12af581b76284f798b3acb96a6b302ea8261d1328f1e62e542085c13f21bc9805e3b347f34136481bd1ba9731cd8bc296ccfda35c2994b48df931efb6725681fee68db631f56498dfd8aa952f41df020c7b73c18606217b86371ec7dd25624bf6287bcc83751c6c15c85ae60e29e28704364a808f089bb77e01fd95c45876ea0fa80b57a0be64a4dd9aadd87bdee52c5b7de4a4bf39ef9af2b9b814abff5cf9fce4bdc10d26f913fddb058d56d132c7688e08385dfa0636417f901f3e49deac087f91fbd63f89928f0ecee1aff0674ae011550a14426b8940afc99f857a8d1f89e96b599fe0014f621008fe89bd815603a0395a3c6a6dc40e591517e508212c1a4a411365f2c95876f0a9d32c4c778912feb25560c62f03e23bf82b7e55ebdda16f7b32c1962d987321786c123ac840ee700b4f5ecaea6e65b43d1e8a41cb7a16a4c373458fcb9a7494892a445470c12d8efceea4d638d3944e25bdebe1144cb12572dc740a4edb660bc4df79ed576f2c1d2ec91004baedb702297fa20c983e6c85bc24c59d2f586e6f24ac8b608b8c18ce92c37b8c7d2092052f28d10b56648f50ab007d3c263caaef3d8618d885036efd27607d664c55ee095107b161b25ff693c1331c75fe8afdb2f0f09e4fcb638f8e848de924ad489f68388e52d96dbde3110593e8de5b8912ac25114bce2b95fb685e3fbbe8e64e422e46ed9dd9108602805e8ccbb6a3518766087841476c987d067de13b4cc59fec17802e049a55722ae8f68c0d4a266a43d8bc462e4b927ae1a6abf2da2fd83b4db311685aeefca998a633d7e819ca124fe24dc88a6d17a01845004229136db85aefe1519632c9cd062c4888863e77db5a707399b17e11bba720a0309cde2fc0004317951428cceb5919cafc6239d44c5f31d36b24d2480d1dba03b91a84c32864344be29c920bc6726445a581979d2af3bad1289e661a0d44e740e5c7dcbc30345f112b94a23c7bb1210bae9c941ad2fc3142137b81aac2552ef82ddd27702d0ed1b3e6c918c114144d603384ca56dfa077a833e8ac620da47b66389a8c019a9d6df7538bc98616c53ef66cbc3e6186845dc4e169a1aac40ff3507f4c2b53b2dd4be52aa507b2276d1590cf5b93ffe1a125c88d18bca955d242ca4459ad6cdbfee19576c43226c9923207dd750b13935005c80b7ede524755e759dcd94c0b59ef04a7b11775e603ed118ddeb448ae07dfbc6f6d569759867b0c9de3825d4021ea2913799c8b66e660f894307f5719dad681e0d90413203df6de942bca0155d711a4c538e04ba89486862a9d2dab9559cc27d06583a168dd49ee7b18e428e7286566ab061a6561eb68ac46978b1295d26ba25e53623d0b3057bf880770eae2b8c0de7483d9eae8f627c2765cd2fc35de2ff5e3281903a922d154a3d16152785111fdf42e7357f767c94f09c8f3ae559bbb460af99bd80833b08d2d93e8739fcb2f864ede2934ba958cb7dfe61c70e8007a79deb66b2ecb8b8e90ab1c6ac4d38453f8640fdd2cae17b9829fcf5c2062f1b021f0f16708c2fb9243aca1aca56f44c457e848982bcdd8716b13381b1b65ad969d55140710781a8b07c52ef9c0966c04a4eb0795831172f58803f533b1a84d95670480ab760e7d26f2d34fa023dc6d1c0bb4426003cd7ee5f53e7fff3010cce8ac348df3c5127a769a82111892d656728a1a66839004747fab286e9992527e5c43521bf2cf9e881765c3c490ea120401c5cd1a6067337c3c939212c1ce6e40f4273975540da24c6a7714bc685eaa6c9fb2f57b178454b77abaa0ae489aa7ee9cb8cfb676e6ff68e65fabb0abba29050de0ac67c42cd7069bb10cfa9af25850d68c123bf89f23d734457ba58fa28f4e4a1545041ffc0e8457a47278506e0543ebef3a38345441326da0acbcd7be25e4e050be08df5da066f518628bf0b30b25570b8cc315210cd0af3bb9e54cf37b82cd49d7c614270348957eb6bd4f333daac9df33860332c33f9a47bf40cc0826574db9854ef626dba1f8e9c5afd1bd8b5918987e43e0f5018110c54e42ef9896f976b9a10861b4d9d183969f12301fac78ca0e3b4d8d3c1858b50f536c3cd3dc82c5d71a985826d7dfbca025e49ae8f628bafc8c56d88c26a65542202c80a8a6f50b9156a681fe17d40f97329ca4897d9410f18c39bc4d9d085d907f50572572e821de4d95b8871dd8f864c287453c975874083d4f216d341a313a03f226c5f570ff19a1906eabd65ca293e63164f6e513a5063ee1f7dc81fd903aed6369130f1aa35528fe1ed4a5290b4514fadaa06d28881b1eb7e548ef9e5fdf9d4b24dfa4ddeeccac49e43e6aba3874cdb2563c00dbde117c1e788f64bb6c7b1272b8fb7d882b58e58d59e064eae46c3f244aabb4db145c01ba1f867873286b237067e274a28b86500b6782a5a1c268c8846b79f57f74f2211f6f437f9128ba068fa2fbbef36fe6dca1f332e1ca0377fed8e8c94c0ba63fa888f574d5b544c7923efe1b2ab096429de30b9dd6e0cd7e7fe8bacf2d4e27bc60ff7586ba9efd36ba5df562a380e92c383930f4e712d33972174828d3d3c3662c59a4fb0641a2557b845ec8af9dc21f024ab95bb6cc8e0dea4bd0428bd24e58bfcce1dac89d7d1c96c1f2f46a2b17d644829ec5bbc7ee6d24bb01a2ace86a95ff5466ab537d06ec953fd4f7fceabe3206aa8603ccbd24e30f8dd42c18d03f03c9e533fd98afbbb952e2eef61f8e25163b1673022c6253a013715b856b0751024d373f75c6d5ff092acd557d1d7e079ff8883deb8281351bdfc2a2041203fada9cc8536bfa6caee8e821467894899540e0e326c8473481d54dc998a025ff8257dc94d04ef800e590add143c549a2b639c5544606c18a6e5d87e37992248eb268f7b5444f4be3af3ac4c26b7110febfe487071d439bb0052be04a8c82bd64a51529244fd235e9cd9058cda1152977049afd2fb359942884c3c071cf758a89fcd863b2b6ad6ca928fbfa26a99c8e1f148e1430f9593d0447ef1538a2fd05713bdf5343119f6ce0b92e0bc6b58774daa0f8fe2af6af298a8b7c1bf821bce46f12fca11b36116528560a41f18fefc7b33a6402ec472f5f82b68b986265301c29cddce443bfc620af4add33aaf33dfeb1fb7a133363e33fae07ba92df56f123909601067607deea72730580ef058b42bdbcdfe107deb56cc83a1e642bd3b5882ba224e499ed52077fa17dcd7d5e0861bf0e0244739cf63be57f7192d89415118777183bc5cedfe99b6efe9ed01afec0c86c4653ad19bc401c2268030d20620b2891485a721d66945d03d5f7c6cafa2fd9181aefd890ee40c3ba7b01bfc79f3f137e0f142ea0ce7bda13703f94cef654244f12f8a91ae4b755526972ba0dff7c7cb2c6273b68929a8dafd8f59fc6de9537a6e4467bd6d5612ab2cf63e530793296e23b3c8f92290adb38dcd22ffd2ee9c73da604c3d19e0b0baac95730693204d57480eab580f23c15432358e2639724cb1894bddd33d2b6c8650a5899bd3ed995436ec638c6e9e4405329c28e2d30f9874545966be440628b8c1a0ccccd04afc13e159eabd7c296ea1cfda387bd97022ac6dbb12714f77e3183f4bd719b37c2a9092ee25daf15ecd3ed51fec3a25eecac1c8e5405b56eefe8c913b081588d2ae8a9ecea71effeeab01bff972af42b6aa561e1a3fb525c3b13d405a1b12f81f21f48cfb8c1152ee3861bb54fefce1010dbcbca69ee340455624d06fa46e332b5dc20ab3cb05fc082e580ea8a23f24845f87dac3d6a4dac6a0c6b97e9accc2b8ae08a19669053e30f5f1380a899c27c4ae05d2783e93e379c1faa417e758a729bc6e80cd7c7eb40b2dff7a46e240fa2bb7f0fd5e0d11ba0b809cefe0dfd9daefe5a585b6070225caf32af0814f7f7059d9e8d6e5459b97148664b8347da66104f002f2ea4eca6a29029a8167d59cdf14fa9d6fe9b031dfc9d2a828e2d4cdc2c9e7f0c7441d0c78b1c14f05c6ab0e5eeb41d145e406b18ba24272a4c5016d0b05a9b8fd4dd7809a4578b93082dff8c5c013719fc9c8719ab9b0ecc0f87c1b4a64aa621882ebcbf73aa081b9a1e62909bdc0da9bdd830f9c1ee9cba2467c2273e73ed6fc9f36891362ee6d0bb40cca2440a03b85a377132d5024cd3df606f16217301075f3ad4c6c8cc85ffeffbfac9b0ea2317b31daf744e3f5ca6452179c2361522f3630c6dcde2489cf578bd194ff412c6d1bd57de329611cefb32e3c9f5a7588b061d3c8024f368664ca34529a7fc9d935dda29f46709d1de50c03355e77f802304339bce4f01056b53919de2c266770f77a86f22c7d13b2931305f4a29f79295bc2da53c2f1c3fa3fa3c18f306ec195a63c0f269f3c5be0997021a1e5018649f603f87bea1d146db8fe16f235580755e0a351f28672d7dbfc728c280eb950efb30cbd6a24caaf3cd062d4db8f0584cc97e2549fa898ad0fba60b6ddcbc3215fd35b396b4627fd04020f62f2aca825b9172847c29d354ed67d9a325514f78d0cd8ec5946a6fa7b1ce740ed22ccf81c2ed298c10e25cf20f2ee3b3f616e01f6a018804d13a5e3c1e23c3304d047b0d69c5dab541aa3d023052c114221550a2d3940c7e3412b02ae548695ff00163670dd5f9f0ac7c0c4315fd19fb8d290098b0d307350bfb182f6411553c84cb98d8ea28319117ed24ed52ccd97a241529d4ea1365f554021a95e2006bf9ee7c2e7b573ef74a55225d53ea95e85cbfd0a302102e9e67032e9e4d33fd1b78feeca86985a672a31a0d011da6a42c5e10804fa6ed3f9fd2278663e830f068be37ce7d56ca0ad0e90728e3c9747a5c2f4ef938fff8631c49c1d1a6f2aa3a6103497ccd547b222415f591cb7d189c6a953cb9efa67280cf2eb0eb5e53104641816ef594ff3cc0a029250b4399e5244f47d49eda32a8313eec1559b1a1699549230e45a759f884d26fca4ebe1fdc1702b3e0818846a35e46591629ed3dfcf074e9dbc06d2d5663852e00b9276805df1a409836ac752a2a8e51ba3f897e04bb936c3e250d8d0ceea04d90e84c80e36d633638cc1872d8d53d13aba7dd8b55621836c6b4af88c61e83b9f3a0a350e0801b1668898eb2b141529c7c2848d0f42f6f2ee81e1f6581680ba0451e528b35d85d0025bbd787b4627cf76047730a12c85dfd4f8f9a239b2b867582d6e746d79e128ebf66c7e44a16d32002536af1b1cf067acb204460bf4c69b8fd5906414816811d2dee6cc6f3cb1a57168ef12776ca09488c5c88dd014d5ebef3ea2d579b7b4a4ec0132cf9d6f60671f2b5a088aff3673b2363358f840f0de240afb36fca5cd8c0904d5c4418ac1688eeb9117c05caf0f2cf811a440196bb215fda26e9b72493889b1091f9c744b5f2818d1c9501ea423088cf3e08c4d49c203b249acfd8162513d1046cc55cce56d18dd2029877d8f725c0010e33b4aaf1a10644eeb9fd5362502b5551c5854b80d19b09f7abf88b729007dae4dc5c0cb74b3521309f6a083d95130289276c59cb3758d07ec4f9d1bfe2f44501c1dd8a987e34a12b0d8083947ba305d7e1c4b86d15e2555c00215d8c8f4dd05e4d828230a14626f07ba47a6510168b93a3ca166b1d06bc4c6e5234d5fcd6aaa42433dfc22ca562b5837a45ccc05cd8a5b11628b1c38bbbf92e3315d952486e752b10584aeacce0ee34c12b8d3de51b2fc568203e0580b75b2d70669e3205b65c15fdbe4dcac02074ce41b9ee3a18edb2c5a4436074c6254451661aa7fcf174b69552c870866223613d02d4519aea97fa1ce16b7780cf94a0a16b503f782c65b3b79ac0252da077e1fca5e2e10f5cb2a096fcb580b8f3c510b68164ca1ec84a8755e4e921d7285e649e3d2f270c8777fa6d0d126f6c04b671d8a95b1ce2895b923ec9af86ebdf106cde8d31650e1e6c2a8f343dc2a6d441209cfb8881294265ed43e386fe2a5ba8b0a285d8fd0ed60d38ecff4474f370da5a7de03f34bb19dbb954db674055657c12f66e94c18a9bd8d8a57edcf58064b55334147020332a602a0c795720e84e335826209bce3c9b7e6a01ca7659934b1a6cd3b038c0b0afdd97e46da39f6b23f98c27b73d4fbce93801d227f9d6a839937acb03b2eddcc96d632fd9b670fe85a6c7c56b6440b867e023551907813dc26efc4b74895948918841e98fff5b126fd37da8e9c8faa0140611101f3ee0e79214f62c8cee65f39f967f87d8131b355a7d06f1ae411962e3285bb886a9e0cc822c55c4264e831770a68caa5db09b265590b5f6c23e03ecfc7944037011eb8a3440de59a5768e4ebdaa7b4489b9577bcbeef6225a3b69fcc1bdfc3855fa97e88b332b26afba99fbaa11529618122d7a6647782cffb2594272aad96cee0cb20f240923067bb1f2e2499797cbae46cc823ae7f6b55ac5385873fe61ae092941a33cae8e08518c51ec0f961a9bc1527670692ee03e10a51c061a76f610440e952d3c4de41091a38e43c209ada273fa01836b5812ef058fe640d219f4a2b36c7b905cea78503ff34a053735dd8d55fcefc9d96ec826c8977b831e620d139b009c5b2c435654eb43b08806050de15d05c988f23e6c382f3b1c1a2e813256a2eb2534294988ebb8f86efe99cfa60e42f51a573ed22f3538dae0c53dd5df5c40916182d21ba204ed8e88d10c9ec096ba4fe6b781314a35b22c1c8eff2fa560b469199940483740494db04c5e03ae78606149190498465dfd680f1d2bb959a8459e2863bd05f65277bdc43408bcbe168278fdfd7b9e5e49fc3ceb0cc8a37e144041aecf2862d603026a3a2624f845604ebbb9412be4a35204bd428565e6cffce43e574058792ef809d1a1f2d7656a003d6366126b1037c59ac4cd620d319338b3b821c62466169bb2fa9a67d1971cb56cbf4d310631b398214696fd9b216612631633c49bc4cce20c319318b3d8940dbec8b664f691af12779af5dd286e16678a99c54d624d31a358a3b829c6b862a62d31529bc18c95f095ec69fae4ebb39c3a8b5a02d76235cbf01578fa5b0facda7e20dfdaf243ead31eacebdb9ed7e56c023bf830b700e76881cd7ba328bc2ca41279612fa7c567387f201762eff77b26cdcb47270b7949838b738350d25d412d83ee69452dbb1b39ca14bb45d552fc25ecefa78b9e441fdbc4d2b0a9063508f6d1b995a67628e520f6917f2990bd3b57574b3026c61365f81581e487cd2a8e07e83108234358991d811c0b47601123830cd80c9607aa0abc3fb33c38e639c6523870d331db0dd05d6c29bb16e25bb03f09698d2de4a1a7929f2afc815ce7f92bd569e72522b4b42a33c55aca20dc24396218af79d3c0ae54246f4fed016da9cb55cee266506a5d5639f3b408d191567a3af57bb152f17374df4289e5efe4bdd44529807e343964fb0c020ee9cb8125bc04c21fcb3d26246b717a4c984ae3484fade974fccf44daa4e8b15d340313748492bdb02bac22f29e1530b417d2c425dab4f4eb5d20b2995a653d4280b69469dbd1f83999397d222a22494a81741e866c9b9f0defb888e7f5351caa83b688a61e9340e63e7ac72cb3670f39444b6805da3a21313b8eda5c3f15f21534218a939dc3ec6df456d541fe6f9101fef1ad2cc46e96127c9de780ccc74f2e6590900fb1bdac1e48c651ff302007dd415d8c6cebbf3d55d3c932766edbcf8665d557762eff4f68e4f26c9f7e63ef8127d8bc5dff9bc9818630eb98871c296d4f9af2720f281c2668c46e800b83375c00e609251d36c47abb04cb013339bf01c7841c901c5c6af5cc800a422db30f3e09045763e4f09e1a5a183a688f733d8aac60313661ea74d8bfcf9c43e8a2bf74772c785e7fce83957c13af4549f010aa89c4754b32706921541fccc3a4c8d93584aa8d66cadc1d5127a9b6398290c331f17ed4b1ac1c1037920e1983c92515bb8b2af1ec4dca82e6e1a70fdb6d8daabc279ce02c0d9ca22c4530c07060ea9cf4b0b58328ec3738af3fcd6562f143c7f811c7dff2d1bbf156f6346e5def194ab8f937521e1bd6000d5a6bdee2a12d9c5ac0992807f1f2f5a6500e14034ebee607afe27fdc8332087b940d573181483cebf3ae6a6701c251c9f7b7bb1441f1c8c312e92223cfac70c3aa17580161638025d31f6a321c557a9c0af9fcccd0b577dd4b6151d3d34a1066e68ed971cdd06460a1d732eb07cc67055a85234aab1cf502ecb416ab8d547ee7286fb34c8e78752c9b2b5ad44c587532b334aeca82b74c418420cb6470ff82d2a6e7f8f9eb4037705fcb6329d6f8a1d5c366d6e5d9c17d7439b6d42177c8c6cf1d631b86c05cda7866a6bb917f27e32bd5da79a2a6e42ac91c5df87b59b94351104f70f4c914ec598d5551dc193a4723d938c4a2cc205df0c2c3dba0d7c9d27d1a0de78d6874d7d52f5b01d3a605e73a7719c98412c07ec6f884640c90cc52098f438de6318648923e06ef32bcd0adcee75ce4bc417d0e0d9ba5088d3607fcd83d04b9c58927e5c9a8cfda71044493fb2bfd7352d8bd71bc80b6470b6fa040040e6d6ab1ef203a0e9d0344d90695bc48eb1efb08bcbd6c3f59b144525fac1c4ce6a5db015b054b84393c78f03380556aa271794b409b6e90f71e6c22d28d1b844dab2792ef8c5d97210bf8258e1ad6e23c52eca17e6a2acdbe6130943c0fbddd1391cc418dac0a610f2d7fc415993e8bb77033dab2d93a289b0011df2c2f0050d492c7dc2390a9227025d7aad61bc6f353e2f2c50c7b734b9862ae6163503105e27533384520a239f124b08802d7e204520e5974ae8843de624c68865b259fb14187437c834c1ef3173ac86424b26e87233debff7d201ac24b7e3485412156cbd403510850d0c11aba52a479662387cb48cfde7bdb6d582233c8211d2783301903a30e3b46ab07df438a6c5889bb553179c96d7bf0dee83089232449c0a5e280802b7452648b40c898f3566f710b5c6b999bedf6a5d1eb74133c5398db53a7138e57c7a2168ee7e07b3f313d38bf5e73a76b7d460892faa8a027d8ee40b3b5817efcc41a7bdc57313701077da44359ffcfc93d56c32bdc3b53b178c855e5a73bb530d01e601150731b51d486570848352e7db1c8d8a6040dc398724d4b767ce956871c61149c7d6ca18cc03ae0e2747416000b36a4127e699dbc204f5c1c83875c85c2496ebb3290c8c143a5c01aee4509909bdf3a7bb88cf5f0440bbaf4e1fe9ad1d5bb2c7b644f2e19fbbb2f95393e6bf3ba8e2b7959a135b5bca59bfb7c8e5fbb8cfb0140965fa80d7ce7ce5ec32b16a1fee2472c4df31a01d5394f53e1ce09cc9704cd3a12b443294df8f6ee1d41bb65dd99db30be6ea874e9c8923c97b79d0da8ef7d4b8a1d16d8ba0064e394b02b553f34c28402109ab953ebadd3d0adc27e6c844ecfd4fbf27d8b8c0bfc447a8224b9c23dca144a58ed2e51d87de2f6b39b70cfdcaccc97062e3fe92fea7280d8a0d3ad662357436e7e49e37971c8bedfd1b8373843e205042e6bf3a0f52742386a1b35db01f8c53aab6b99b4eb5926db92c81c7a93ade62df37dd3cffe7f6058f06e0ada371ec716e1a56047308fd2424aa37d604874dd87220decca939ce848b6b792f1735a4549a175722f122725476e201261c6d42093259ecbc1f4eeebe231f28521af19e171e4c24a195570250a2c38ecd2154e65dcce26970d6f6b10950a19d16880dbfb605ec3a648a66ca46ccaf1789d5a0a04b7cf15cfc7bd077c7ad57207b70bb51b58d7497e20c196fa097bd7aac1d170e55f36b60ca8838309901958f2a9f005697aff26d94fe803712e428efde16da57f390846d3b54d93cd21b60741dd4232d81772518f196ab819b0a40ce0f1662ce6777f849a902d9d2f2815eaf41bb638159472d603f8e02ef03bf4de5ebcf7ba4856ae1c177cc247908d66516f2ec2b201d4d77c52a2f026dbfffbad87bf15fcaac4262f0eb6bccd36be642687685a08a12483cc07189e8ba6254bd7e3d90c43d118e9e67408802c159e065d34e5d31cba88a4500d99a67e260a97b0e367e818cfaba15e0900b42e3870298b3265172a0aa62920dc15a9437c62a3445321d648492e8fd69acc8817c6310e8a2502c6e0f8a5013a8697e57fdd1516f9743d8d598b0290a7bd59361e1ba09270776229c45554922158af7de5a879a90157dde1a2a87f8b0e946d4a60dcf860d2b2204ec45a7af50cf6fb2a7977007728b0481a7c977df35617432d21c66e4f71cdd3112d71b6523234d2ac40e89e607a521a9110dd6998d4d437ad5dfb30fefcde61cf86c6cb4c72e1c9e9e6ea0ca652f01219f9b82f79f9d71d6d8c474a198046a775f559f3b2dbad46e8ad28f5505c056f3434f2c47be472724a809d1f65dc2f448d05577ea18e5db7c638b7f66ed4c1167b7c0b32c0fd1d5578a885776df76d1006b8eef45b4698794b6b2412cf94e784d8c29d5bb0d1a6148648aa905cc6251b6f860b302759b6308e0468c16e788833d59821582483b563b3c7133bc29c163648e02f8b45172de40dc909b9aa956c46040876824813be37f07528046dfd4794e695ffec399f3a4d8cb427c2d12046eddb48b0f72a39700630dbcb399de9ddb7e913e8c1b819c5305a6327cc144cfbba8cd9060b70aaf612d526c0eb9100734802a35372223cefe607357ad63ad8385e08d41852e4ad3ac96a048147b8b8df4845264118c5830cee66ab96834e9de0eeba2c5d92597361f77ad5e9b9e6fcd95202e2585c165b4319e7b0df0c1437816020453c69a439ee4c3d2f74fa12df01a3860ba69592b7ce5f36a950c946fed00afe3794275403e6b9c21dbf1f22cf88ac10f61a1095abe144dbcf13139b2122e9244570be16516e18299d7b576fae2fea6b1c82ea72753a227b300febf463192ce8162dfa292da4d11721d64d233a500a405e0e88272ea653de933aec26dab7204635a3c10d549d2256e783fe8c1611d86d33eb1086ce56e23f585f5f838832de89d23203e2c487025e9e1173c39cecccd5a72021f251c8a017628bc22a849c77b3d6c9f78b5cdf253a25bbf1da3d6abb485eb5d488d8208033b9086ee4a7c8945c0145d0ecdf1f036dbb52990758dd7d997c700216826f83a752cb91c1a8927d6981ff93f6d4b45cb5bf0e17e28708e574c95c4e59d033f1db94868a9d355393e81dc9f4c2876dc84c1e6d401ab876d6263e3d29eb30e7a84144ab73ec66844a80035b4fc4ffd487371e8ec0f224b8472fa5b728efaec4094dc9948267b774a77e665a0415c5a7b0ffb32eae0de21428418d6ec97d6d5087392545587292aec6c5c0ceffe25a37f39ba5275011a8d29cc81b00017f13d20e746b42a39c21f6750a23ff0b4335d81efa5ebd105a538db8e7ef05cecb84d63c2f776e02ec00881ebfbdf314e4cd11d316baf9ce00f31674915e4fe1883e5fb8de36ae5005ada5f6196bebe8f96dd48cb31bf45d043c91b017e725ac6225b7f933cff8a8c3a8fe36aadc01dda2a3f6eda56f24a9dc302d1e1fc36173ba4b362bc02784eb596abe48977c0c3b55931ccebe9f4f5b4f328851cff9c510de81dd88bc225785e8ef12561cfe17cd49a6328d2907300acca296040ad7656ed07f2e595c72c6ac44fb05f1643d25c50102ef2867458f05718080db0456370090a031366be3e24cd7024f6468993ee6c04fc1b86a4b756076e9c3b6b1a9063a1479743a2b946a9939121e50ef56ce13f1f01e8e421b1bf7050931cb6eacea1cf3994c7950daf83d5db47d8517f80384087e0ff82b0a36d2534e65b470eecddaf9631f60fd7bd49901587938fdfd2317d8899ecb14602fbf8728c1f1a7263f8dea75128af5ab21fda71daf4d6e954642452f75a74695ef4635364892473427e8876cf3399e7edc16de9e4b966616453d96a270b91bb791abb41f0b36dcc8ef28d09c63e4bb6e123e0ebf775d1da3e469ce11649ce6b01eca4ed62821cc9ba842cd11ed9a989a15fdb8761b1bcc16a71c531b858fe3c3fc4f5ecceacf657c166de85e442cae92844e70c5c7f680821b787e6b06c29ccc372ebdf8f21fd2e444b962045cf4c28ee79bdefc6a79b0ec93c0f9d1b26f0dd9a862e3218b3181192e5dd81619209f3441bf2a9a56dc889303ade16ad80b9bfe9afe9b470b05f52d086fb4199a12e5c5b9f93aae6624746c7aaac13294034d07cbf57b6b42077dd95674d67c9b229a6d517dc951fdb0425917a7099b93ae4479f4c45f63018a1d6bd8a4bd54c9ef3e097a66aabc0b1f301b38335f9191db35a107311916d66c41905c92b4cf8b9adf1938b31d589795978e92822cd90dd2ce0cce07fdc113666efbbf9eed3c720e4618a17bd75027377f215200b1fb8b7bce4977936b28789ca82e2d20f1736a51f1303ba53216f7f2d4e825acbfa2735c62b33712276f56983e0bbc2621abf489e976d38d769b1f8c560ebc815bd9001b63f9ccdb85d60ba0931e507ab9c4487aabd5dd6a6c940d7b796ec8bdf192bd6aee4a3e597fb55b1c1a9543c0a87d320bcae7a19165431f1aaf24555fab79ac92e5d01593f0274c1d3c395c6ea71772c0d140ec68ce23b795d18b3da25ff5183f1c59dac63589787dd11f3ccf48f8af72954df5cdbaf8fae1085da87443ff05259d38a0a0f127b4c7aceae280e4291313a9f1d4ee68e6919d222665f5bbca80a6fa5230a0302ac17c57ce684a920024908b2d23a019101e4dd3f5ce493469e96c50373bf7ee74bc94edad6875a0dec5fa4470b76421ec43000677b23c306de206949aed23d6b3bc57b6b4a52da50c7630d10093e9f0b623b08a473c714a1d88c2d10b7adb255b3322f2bbbbb442b66664576c77097444e905a6009f009e00396766c10ea6343b94524a29a5ccc241e905144913555957b5d8c54b47dc8af4a004982294004d0965427fe3c117b3f5b22a6a9222e87168c56e3a382c501850b11708930258221dc21e39f8791db769d9bec2300c7be4e0e775dca6653b5f39bcbe6def2d40f196acf7de7559a6691cec91839fd7719b96edd950e7812269a22aebaa16bb38ebc8fe0b32a2b3060c17362eaba22629821e8736534e681e8d8b2592a142c8ef7236d4d9b898ad9755519314418f439b0f8f0ea5e2c473f07b0e7ee0f771fe9c839fd7719b967de0d8608c71a40dc54def5cf7c85f03144913555957b5d8c539cad950e79920e1c3a383c32285b5d65adb3bd79d6b0f69a1a1e44873ce393ad4c9b477ae7be4fa3144d24455d6552d7671761e28e38bd97a5915354911f4484743690040e36289a0a853d75aebd45256adf792f5deb9ee93eb0e9999c5c9015be721d33946c6ffef2684d7bdd7bde775dd028c8c0f0794c96f10031304cb8831c6b2c68aa3fcad4c2a3089611836e5c464ef5cf7c81f84f3409134519575558b5d9ca39c0dc517b3f5b22a6a9222e87168333d9c8b183171a5063fafe3362d8bf7de2b35f8791db769598df54690cbb2efd3daf3346ddbb4d4e0e775dca66593df0aa8cc08893befbdb799cd9d9a8332f9fd409134519575558b5d9c634c1886e14b26e46ff19d97b0d35a6ba794b677aefbe4fa4750e7812269a22aebaa16bb3847391b0c17b3f5b22a6a9222e8716823e1e31b3824628d3566daf307ffbbe4e0e775dca665cc067febc85c96c886655916e6c126c4ffbfc4c860a000648670cffd2fc0c860f0214248c87ffffdf7417830220c3b0f3b77a04c7e8780e0de1562202d45f8ff2f1380649ffd7f9611288040c2bc442291302f895918869eb70583d4a882c14fd21c628e440289a19931d60112a060784006b108053108c32084104208111042081110012146400831c430ccd801166e30133385ebf9db761bdc109814cf2fd7f908581223802e54b3e37b8f474abfd8afa2a8662f53de28571e4320c7889f885cc307850a81572d4f6901a313e3fdf8910cbb62ee1a930a6c0df3de040196617ec30b185dedbb28416fab5c2c2e91ba563ef1de9660ab9584cf6ec1ff12fd1d3ee3ec4ae06d74aad92a653cf818429d2e3142e712e2465fd7bb778f6e76ceb607d2c7a4810f0a78041176cba074924cce20f72c272935ec33fbf8f9bc52e1f90b9baa7d0eddc20c3efbecd3103eba64c9f5eeaf427ebf683bfaa9766e9581231e710a380579bc635b2e8bf82f0ca786ac088d8bf573f2d95202973c2ac601dec723cbec9abf47793a0a71ea856d58f01a856b66e089764bfe1b6202c1893ad910bcaa4893bbf57794d0994bf66b948ddddf0d7338d59dfcb8eec9ea4232444f408c26b87270fd32407bb77e2270ef7cfe6a5eb96d343bbca2e42f8435d8af5e0f81532da4266dc03a378f4312ef5230ffd80a22dd6e34c8512710a8a7e9debef52fa0e71ff5184bf3ef1a70108e08a9b7008488a09883c26979202fe9f98c4a84836f75686e9217856b747ab5fedcc4cfffb4082e79a2e81de60f8edbf40a7b26ff434924842f513b0fbe1332600d2ac8bb3ad8d1999f748f9442875ef73df4abb959a846841716a2cd2bde711748edaabfef30719d54cbd548e9d0ab86aa4324d3e2b6b5a0a27d7aea8ac2cfbbeeb64ee723323f7dc0cc1323d214ee3732574f9b31a7fa56ea02ab7d94df185e3f36fece505a678ccbf56b92bdab4236876a316e231c6e9b4076e4f78bc659e9fdc6f98a47763d38f1f77a2b2b318ad2cc18e546c0bfb8cf78deb377f3533df1db3ac5d11bcacfeeb8ad9cbb6b89dc6b687d7a68f0d7cb1ce2b2293fbb302c874f403efbb7500074d584ba7b9320d3ffc643aaca37f54016a5802d61b693114069c87cf7266b0ad4bdb6cffee13f2fcbb4eda5d8aefffe4df4e8f383656716f5dc7fe901f62fd4a280344a1897e5627ca222dcd3fa04710efa32cd87723b8cd6a782d4b13f81657d7dc3a0748b861cd72e0aafd1b21341a2d4a783627c877febefff202d306ea27d6759058045fe7b0411c8ff3d9aba6c48b84eb9b38be1322aa26bb2fee38b20a0d37eae8d49fef49a477410122e6fb9ae9f02fa76ca51c20563cb21ee3b12e6d5a571cf1f3b3eafd8479080f69f0c0a002250d6feadaaaa2b87def7f0cc9b5bfc419da3feb31c8113107e96296bcd7f0cb49cf2a5b811f02ffbbdc8f32f38000da942a0a3827d1ca8b2f3e11a90f8334f211b27d8fb622920e03e0ef93ef5f75382ee6dede3b0efab7eef3698701a5bd86bbf0a65f3b2d4af5e9ffd1ed8d95038fc31b8d8bf70b1a3962a66e6b4383e3c388fed5891b3bfa386465463a213a3733c963c0f075164621b7611c022cf62e89e6865490c513499a3bc11f82f37bdc8f12f38001aa942a0a38a2fb7a594765e7ea2c2f0509adaec3c9a89f7551705cb6fc07f0bfadb862ff73a019a0cfb5aa64f83d8cfe04ee31700e39a7f8d1a105163589e37caa5d3b608d8e651beeb24d6f1837ed0105502a1c9d7e1af6e7b13b478fee5a85f8af28b69b37c6731fecd49166b9a1fe5f2377a0a8f010f00150fa37e9dae8a0eae4c350993bd1f3cd57ac19f1325b50cdb5de7b0ea149dc4330b3a4738e57154e5693485326993764a1ebff3673352c2bf4f201769df13011fd7f986f0bf0e05a0e143c109e769cba2b9fb36b7ffa1199d9c38d009edc3189d40631c269a8448c8acacb7afa08040e0fa54cff81cfa35994f7175f9b6c5927f4150a25f8265ffbe21404acdd4971ce0bee279a562d75ef5da42e37ae055a3f424994e43ef590cf602487fb1a4dd59cb1214c5afcd4aef744a4bba7c5e9e0347ea1bdf4efbea46fff8d24b5072599f2d8f78ef4cb88d85d8a70bccaae42e277a7d8950e0ae5d43d790df80915c85088051889954b24b349ce5057e5205631053205e15271df95c32d36724ffc26847aece08654a393b89bb06fdc617d13772c92f2c8cd9c6d8f7c2580185d2124ba8f298a2aa11030bd1edb4bc720350dc34f29b19e30dd1b3b6355b6b092184ecbdf7de7bef4a104b101310700b2ff4b056f6e1a9d1ed4566babd589db955ed6e2fb6493cd96797e4e9799cf5229eec85696b7f61624a72b209bc45620a14135356e74a115376279eecad6d4918b72d7b1b7b40840bc40fe3132b6d13f049f693cff7d2e55993b349b6c0a56c04e571f275e630ddf4fa6ec4d22b574ac2b24c5838efb67d58c6c82bb94884198255c9307277b5a398b289c7f6f74d72570c38e59ddca6dc6e2f29d7e2c9de788a47d817390223c6651a70e9272f71727b3979f2a53ff99367279c6dc5937d0a6799c493fdcc02979ef252e9f27d723fe4dfb399839ba6397f52fae44a4779a7704650ecc9ed51382da2ec6b6b6f75e48d912d4e3cd9c3c896e505dc61b7d6da7f3ef23e97987ab7d79e8d4acaa1df67e3b61de5ae5482a1d01f77a1a0dd5d2820c8b6eceb35aec863b5da3ee330cec4e3e2ba78e5af4c3f20b421115edc0618c8061e169c6f4224720d30720b144cd172494b09257c1b88a94e25c21bda5868f9c9059c1643cbfb5ae4e31f6e20843910c22251c2fc02219c8134374d851530bc9442422b620a0a286bf0fb7df4033384792d3837371bb83d804fb879100b2d2116132b72247738c33b3978630669861b12257f2f2e958ac4937cc243c9638183057913338c8130373063b8248f780a9190200bdec4d37b076fdee18dbc8930a119640f07d64e9f62e380df6b51d2bd85f37ba58e3360dac7936cc26b6dd5daca968829aa55ec955e7bfd753040bbcd46ae6bcfe8c6433bfd516f9fd5df5b8efed68b00f695956a0cd0819a3a96a07f174f37501f0f13b5154ff2b4c8917a3b9b57a778c47ce5ce04fcde9dd66397acb29668d6059b142879f5d1d7f314988731708aa8824b643010536f8b22323d7bd2575fcbbc04de7d6ee8599b906698373f6927ae735e32c18f6552095a81fda3ef3663ae44c2fd7229bfbfbf975f6403be3d60e92eabe5290ef04a0bc330ce09523f26dd035fbf2b17b6a5d7f588c1869d9530ccdaed372286728b6116c3300cbbae631786b2b2f26c09d528dd5e504618117d8583fde4c905cbb60b7c7dc51eff3dfb68d50db87b70c05d958181fadb5e50cf5afb066cdd80b3c3db1d1dd844a78b36b05c25fa0d219e45cb066c7192b02711d1260ef42d09fc70e6d0a463f4c3220d306812e92a5c47a455e2ca4a36f1b8bef21cd757564ea4ed49294721d21648ec946c015804e9f124aef4eb994e8f6eb7175276e51cd9af7c9d4843fbd151568834e45ea3640bc02246f123aef48c03715df4020700b6db2496659308b106dcc9204ebf0ad745d12aa4d817de705c39fbca48e519f75048f6a7df88904422cd5099f115aebb0e02226db3078c30a2e103609358ed5d9d1029dad2edc5da83549ea242e35538d852e7f610bfd0741a87b90bfd5e47392429617f2931faca6f67a3bc921f7cb67214ae1b7dc6490db8be92455be0ebd935f88b4341b9fdc57551f475b82901b38974f81513e9a35b52def1e269e52f9e461fe52e8a281afe1a3d860ed8267b942cda025b786d25ff309d947f806e0f445e79c6d38ccf8dc76907280f914bb7b9a39167280391714b22e52a2a5c37a455ce59a8921d5ecf300da492a2f2928a8acd1388ec983b22ad92e34bdb8b8cab70f1972bfd6d4a44a91353315f87b9f44c85933ab2a5f2cb44c6e93ae4647cc47551f4e819b7bdc8b849899443140eaa48b98ba253b2117c1c4fa60bf68b26199ff12bff90f1151979a5e519f792b8fa92c1c1cc7e66b9ebe267dc1e5b9497aeaf1ca2e42e661c89eb3ed0a477404c1f8808f8dcf4f7c92fa246b9cb3ee35d908832e58ef41931c51e6611c0be8e0264db11fb921b8fd3bf0261b7f26b743be2765cf67005e52fe33ad28958f940977237e3a40c44f6ca8c15d83264fc8694c19d88e0ba0df48cb770dded198fc17551f48c99210ec0dff61280dcd340629f7e236adc6cbaedb8320d73c780fec1f2ec27ae837d650f18d1195251eaf00e4845af74d7591e85116dff22ca662c87dc0cd91d6c0f18d12bb96340df884674108f40640771b9bd04f1ecd22e4e36dc5eac6d82e101c075363b11bd6821bee51b3aa52038d824a2e4df8a8525431d35b088d05bcb968e34e094d79a2a68d080ad0eee9c6069781887f1aed20cf1ec6d28b9a340a31c76114ff2caa44e96337b067cffb61d3f56bef2ec2d17d866b9239bd85b33e0d1ed8c9dc2ca940177d2ce7456c6ca5826f8cab5067b3ce98b789264c0f659b632b01bfd7af6f0e82aa3d1caaf959bde5dcf66567e29b1f21fd74c4c5d2552be9e3d2b7176c6ca4c6165ac7dd675da9c6b4dae3df164e22a4fa589a708e0ceca8066a88829a823a3bd8c952bb3acb9bd58a8c343a30b2bf32159d21fb6d6e68ca16366227a9123f6da31e0ceb25e5256ae2c7725d01571451e0bc6513827587a8820b8d7b6853b8859999978843ceeac8c9d89a977c95615c200756e97c414296257e9804bff183d7b0905e6eeb664c828e1286979191cc82e51e94aa9d7ad62ed755d17d7019795ec6df06fde8601779605f3e8ba48871356d26c387bc4cdb661c0a45c676070b50a2b5a1e556beca5b960c0f0a4e3df1a1b68f383a79136aa7568f95a07a892371225532f9ef640ad85f6e5b4cd3fe041cf208c0f27da1a2e34ba9ff08acaededb52c5ba7dcdd21728769e4aee4f21aa752ee6a803ef116243f1ac6752fa74bdcd518d7a4e58b271cb0b10cba582fa769bc73e2e54896bcb15fc0d93b792391c8d6121c5a51c1a9f1582e2e0da185166aa51d3322143bae0c9bb60864ab6413e456ea697050cc580fb22c3ba3c4d6306989c27a39ab23735e9a5bb3e5207dcb258e76666564ac8ca5d1e1ae765bb075694a2a33647b0177b2350364bb807f68c064fa0c3414e93bbb9312c813f6bd9695afe42e0428b71fd52a682a0f69c62f07c5947114ee09db3280c83659560e26bdb3ac2de0d0ef472faf61001517234a27224867c125150d936e36fa758d0eb9194fd806a17019dd5e66ccd87280402650963a2b9c64124f2d2de00eea846c887bdd24aade0a736f85fb5e9cdc792df2234e36910f71323432c809626fb31232bb94f1b7adfc46b49f1089d16df6ebbaae6b941d5e1767afcbdaebf6a0edc5de9017673fe26e446bbf6d2f365be168e40e368d679c8cfb2943c6e34e4cddcbf8677b91912196339d414d0677573848359477373d0991e8a0dc94c8da66a8238738c8743acaca8eac2b2c22bb8c54599644497b799a913b3c44eeae4e4cd1b8bc9759c0f7349e3d2c5bf12499c4935cf9c5c1860d2fc29f0f87b9951c23cb922aa83323671928f9ca9675411d7965692d8ed1edafccddd3e05e876243ce1ede7e242f779e8d785f2112afefaf9db64a30cb2dcb215797bcb6628a2577b0590eca4cd97b2a2bc352735896c4933c8b95413d888372770110e35796616998dd345a390ed8a31fd75166c8380ed828960bbcf2d12fce03b24d3cb25fcfb20864affcb529ab5e842e83a3f1191ce8236e88af70a75f4ecb421cca6970320ee2667c086ef413b7728dbb201a0f5d7a11539dbc01d1c83862d300ddc4c596ad98823a31857b26cc9372874608746990bced89171ac7013b34c4e3f6c4cbe938600ff18c6a260ef6d5448c2000cfe0abf1d3f21bd1c4bd262200b933410b71f9166ebe162288e882b41042e47b05fee974ca406a9f86b8dc5e8ce067705362886b8fdb8b76fa10a72c994494fccb1059b6ba6ba3c5211a075fcb498867939a4e87af88d367901e62876c219ed1cc9eac10b726d385c81d911ee2f226eebd96d3e7f632c46970261ea66ba77120b24d87db0ed3b52c02d9343290daa0d033bbbd80683c6e2f3472077ae819dc9e7820d04f3f401f02f453be3698c6dfa604e843e47b85880b0cfaebd0638020e83b40a68b40662653280e0971f0b50cf10c9a1e371d1306a64d190ad075f88ab83e83b4e97288675133712288d726a63a6aba1c02140ae527649f72077b88d76263cab566e36a15b1d2c4933c92559aecf2e22acf1698a7e5c9e5fd9ce4f750a82c0a2277da7d2800e4878a913b95869c64e160b364cfa94bde8abd6cebda5e2ccc7ba3b7f2583a0a7476d9d2481d2157fa88eba4dc81c175592e3d2b6998832b969782c78878b00b13f77a06371b84f28863a1bcbd02ce19d7b974b644dbbf7b63e9160b9cfdfa0a37bae59c70e9d1e810623c6249d55ca1cc56815c869225841042948fb83a53659ac493d4d102a3bc833ab0095481b96ba2b38f1eb71cdcca250a071beac0265a5f7f91d4974a5f570bcab46cd99bb2cd5d137dbd78b2f0d7eb9511c438138cbf8ef114cea4fdf56631d9924c489cd491ad1ef89f1ce4c7f87874963a453cc92c0bc2f22056aec86c6657ee4d3cc94b73ab88a79a6b03803f21feb617217e6b32bb6273244a92526e2f8dc9ce2149870ead00f3adb13276269e3e177d8e90b2a5220775d447b92ba150394e305f108e55125329ef4aad627a875bc5f421b86e7669e590b376a7af675c4764a6339dee2cabede8a432343cca175cb2d0d8adf003343ca2614b100f65595255ef9f1c71b223ec4a23237c727e48231cb34979be96d92b5c47a4570ee50a9772cb817e711d75e2ed74cab3cb9a5e8d885e3723315f89724a4a369968fc6d49941eba2c7100380ad7d5682c0fc175b843dca581e264006093e0d1018003079936dd66a6431177f2d1e588b3389635b2497c703fc9a61ea29ffc4474fb956ef2c0b487574eb71721aa807f6860f4f7ebd101902d2b9ea4ca887b2deaae739cc9c78990cf4ffe381e30485b20d17ec4bdb8f1c0241770072107245a16bcdb0b8ae9f5c559964d327ac6d924c789a991bd656587b367430eb665a170b3311e4534fc055f2e8cf3804b430bd3d82dd7b134d6a92c51224243e2c12c6d88ccd569ec426cbac8a4b1675c97e500690b6f48cb39a135e4b2436ee56fbb48dbcb4a861848bc36f12401c0cd168294ef0df6e144bf3595a6d2549a4a53692a8d44799671b7e6d26481b357114fb256114ff295e65e8c4b25161618fa38b988e55910cfa01644ae332c5c95a9362db167b7dc0f2c77d004330ed8a578b2ac1269b4e2840b76d993b891fc95bf55dc9a17940c310a378d7c0eb78fb576f4fac375c0a561fe71dd1e5bc956b2cb75c0a5b1fc037229cfde966599e53a977b71e956c65a4b051c2fe333de59992659d38bef246ec4c1ed65c5c4756fec2a1c0ad7e1c632abcbb2132e6d7d9cfcb322d3d86f44c85dcf565c1acb570a77c9d429ea4c4cd94b1da9129dee501e202a4c8d699922e20247987e407032274a9c285951de4ce1ae26f73acb20966b3df75619867d25833083a36c0433087abdc2e99018974efd80632c82460f37d20b38f40cd19dd4e9d9618014be60e2e4a61ea27ffec9413e17e5e72177091742b0591d99c727b222b29ac149199c8c813a2f9ea0cb758cb3cfb2aab934f6ecc19b9e0366961369f80793680bf8441a6e309b76ac3c7b8e956727d277837f9bcabff2ee28b97bac86a387f227574e44480177b2d59df2e84fa264d2330efb85bd849d7046b8b8ec40526ec1255c3e2e90f5c9a61e9f8b2efa4022abf787eb9f0cc3308c6118cea61ef8a28b30063a86309475dc30408dae86dc819b680b2cd9823a7007ea409dc7922a898696920e2d0f593a3c1066b3b3a0c2152d3f63e614510500d6c3e969d292d59dd4e9a13870e8e96ec248d1728541564c7550a7ab3c3931d5551a2b1353492a4d4ce978e589a979257649cb69592d2513a823a5d48947c8ebc8564baaa0ed58545a44c1c99a44ee104864661954421b70e80053f3850a1164a2382e3d1b32d41dcb2908000c81a2771802623101a77f35e4ebeeadb9c3b88405172864c11db873d16011bf01c4d3f4ee607bf36ca434fd4572739a5e2c34bd5834bdaf2ca9aaf9de4854ad91aa4a849b2b744d02ab69959128ba448d91281a83caaa3194feb601cb57987b2310204422c294a01095d0f40fc622348d96467626353983e706a7e4de6be9ae0e3cdcee4d3c5d3660a98a3f78287a22dc24343d7d42a4792d9482782a1c3098b6d9bb76b876c0b09f7cefd92bb2f022ceb3616afba8e4d99030b8367892074f0aa12455d0873b9c242a0ea535e032c42fb4fdcd03aebf78c0568744d9c76b077cdfb3bf76c03177af8bb68739e82d13f164df291dd4a93d77c05dac8935f75afb5b071c0fe114f7d24127e2d8df8ba5b54fca2867f050f6d6bebbd65a99d7622d4edb6330570e9794f78aff8e5fd7f16cc07be1104a5f172e710f755dbbbaf7f5beaeebbaae3f966b06d963e926abb1279ffdf5025f7ffc19805dc7773c1bd7624f62d8c59fcc3d14760ccb58fe6bc1debd31ec8f05cb3f260b4609a3d333bef866300cbd76c0b361ec9190464c3b94fd7cc6c195e55e43163c958491816de2b5ac208c545de0be833878d97b26cfeb89dc173d8f5d7f1867ea9161cfea89ac8c643a326e89b79231b09ff75e6bed69dc038c3470019428e8f918634fcbf77c21617a80bbd8137b606e1d30ec533ccd22f1347fe980bbd8137ba4eac69eab43461e4f0d7d82896709c2f4f47ceca93a346a7318c1687bc017245d31c0f4570fb87bcb49397acca469864252297fc1006339684b118f1752c47a36e0e52f0e645e8bcc322aee1430cd198db4a225a2fb7aafcc66b88ca6cb66e869628a4a8aafd3671797d164331915d90c7c46454c4d7b219c912ab87af066d14e8e48279ebcf8f4e87c6a60620a1e7e7ab21919453c338b7ae229a2007722253c2d676662aafbf4d0c45446c5a747e445cb775a8fa4221e9e988a2d65846122a148494cf57c7a7036e3806bf5e9b1389f1e8b834730366655886cee1eb00987dd60b62c29f095f2bdbb079c3de05a659f9d7b45364d38d6d985651731258fa914ba2b3d0af38c2d796212647ac6d6b3a1d2a4215dd24b624aeac423e02927af1760f82cda02cb4cc60cd963e9321ca9b597dec006193d7c8fc6f71e332b5a3e837fef740afc9cb0398fcb6ae2c9427bf78065d39cd5d0d71aa9b23816c7d6b4c49903ee6c2bcecbdcdd996d2b939505401061890a8e243a1b7e81464edf8ce6c33323c4f3d9943d703e3a64b267ce789a770fd84e8971b0a71ca20b7027cac93d40c4c8014b9ec983bb4ce66a770fb86a40cc3c1b2a7ddf01c12a3da16f123a207ed037c6199eeab601cfa16f8c3cf4bdb503be7ec5684955ca0ecc194d5fdcd5b429073ce570b5600f781a79570cee5276527652bab8315a0f75ff52f4f0b6f5e06d0c323c55eec93d6ae87b98c948553dfd9c912a6b97d896d5792c510e88a6b3ab05962b49d4bddc8ce018dc0111d317887b20a4b83a4d3fb219ddc4e07936b6a68fe1458c9e1398989201e8074d6d77293baa949d87a207d13c1ba3a6a74f81c3530131f3522976e8fb8b0518089878bacf3d40ccd83d6019acbe8ae04e94936f9e0d1c502e8b792dd70a724fdf0331933263ba4bd911e5f4bddd1c105732582ac01d08e62a82e93f3cf1444130229c67e3f5fd8747aa32997b9fd265343c3219a94ad991a87b2ca7ecc4d37d96b293022c83e7ce791f9f0c9e2a79ae950c1e89baef64f0f44dd9e97bfdc6685d39464ba26e17a3d5178899bea79113e2c91e4bc7a2d32b351d27d3f3b27a7ea5e6d950e9952b5690f4b4d7dd03aec7309b9eafb5d6952b9a5bb1229e566e566ae229b64ee3a08df1c8015f28c0352b3252056307c64ea3b0601d3084584a69e17b0f464b93add4c414edf9152b9af4fc4a6ba549544115f0ac5c11530f8b1c2ce9b92293a4e78a0d4ecf959c9e5386758798ee5698f45cb9e9f90cab2b55c454076347866626a6ba952a6862aa43599922a6a0137a36a1bb152a5a3c66c3e0c1b6d0d5e63496d335c3d8b97fc0b0b1773060749161f0c4134eb782849e7ec00f0b1bf47407a3a7e76f1f60ecf43c0c1d4b239ac1765e4bf7c9c1bcc07a7a1ee3f9a2a7e553726ab534282c289a11cdf46ccdec3d1bf1ee015f0fb856f4acee6ea3b07a9e722b351235f5c0f35a3e37cf06fcfcc501eeaecc792df3b7bbbd39e05ad18cf148d4ecc1dd4a4dcf77184fcf6ea58645476e2cecbad87561f10d3ad7c574c4543c03a27d3146895ae249d46345d16309263e10db6084024d605601f35a267a2c01692c109eacd17fa7f8fb669038e7949583ab292b07576fbb818ad53788227def128414b446772c2d7b5f1059c4f050576678b200e39c652c51f77de3e9feba008b7a624afbbda875f1bd2dc0da63aa7b2c4c62ea5e4523552a988bb18aa62fc845052355d96f3c95a4cc1d0b16a9b454c1f4d5b4acbd88cae40d304bebd9d84a7ac0746071435f1634f47d10317d8390e91bc44cdf2068fafec660fcec5a66696581498771884fba0f4c7a7621a6ed389bb4e3bf958fec30b21052366df9ab9344dd67d9a4659303ecf17dd8e32c44081692dd882cc0a9fb544f4cc5df7b7128a75a7deff15d418dbe2607d867ef619f655007a4f647d47a2d987ef722181560f94ed412b5a42aaeeedf9604c6d292a8fbab028c7d0878f61b0296fd34b9edb8fd7936b50fd7a1f4a78bd19fc720fde944fd7927e4c3755b7f3e37256a7743faf3ec6a1faeb3fd39dd94b0dd11d1ea10b0fd70b9b3ab65dbf60f07446f1c0edb9f6717d4e267fb87e37ae3ba12f4e71906df753f3f3633b4e4aefe703fb6d3db2d097abbf198df6eb71df3f41af7ae1003564b4ec6108630045c77cc967cdcaecce3bacc3ffe5a833b3a348e01389888493cdd563c5d2a885a3b36dab1c32d87bc698978ba7fdd239e6ef772762e2aa0a0b5dcb1f05c6769dd2c632cadbe6f4903b9ea75dd882a961c12ebc8055718438f1552585163aa2fbd38f1c30de15fccdd756f6b0d02e55cb8a887ac4e4a6bad9fcfeaa4b59e565a6ba593d506397f1b9aaef7676392788a9115718a6023315fd9f7dbefded840564c1251f1564606145e016de08d9cd006dec809ab88a718e34d01ee644e8cd18bc8ea98d2e19a610dbcdd01d6017e8f54523fd41e5420e077f8140b030c9f625780df1f8c2bd0e018810a23a4c02827adf65e58a66d1f8b8292cd11ba7b4c1b64b21c2cddcb8cb09884458ed034e07bfb0ee3c0f7f270b3f9ca1b9c02b2c0f799dc78dc18b71c6f66f65ed715105557ca92220aded02171f50236ed88ddd5fa5e4ad9c2f2b5b3889f0dac610bb0ec0ec3186394d37e3a22ef922463c6252638e74ada926909218490e6d9882d218d9cf134c57d2df259f501ce2094fd5ecbf60d48151c0244c9cf7797d67725fbeef7dde91a02c47ee52e95fde62e00dd419adbdc09d11da429c129e026c023681722cb01e82ed66019eaa4ba8b3551868a481367e46b52cf430744e25e7e01cfc6bcfcc5c12a5e8b14c2530044e266f8835784bc14ba06135c8eb43ccd3008af45be83b106d2d4b44c3f20acb44ec8b6a88a1d6689a8ed91dba098f58a37a8c063e2d9d07a3b059e8dd7bd3bf4f6e2f0b6674fb12fc0f5db291053f6db9b88a9fbed1888a9eb38aa42dbab1070f75a1b90db9b902af9ed703b135215bfe5ed7d7277b3c9023c3f3a3ce8f33e409fa0fbc01f6521f1f859d4de653f1278a80d07d69fccc46bd94eb3c0f3306e7280fcbc0ff999851ce9811f2f04f420477a8c4e7a90233d441f3dc893f7110f230bc18fd9f4c946e24939c8280711652c519d11bd75357afbe4ce00bd65df4ee08086fb0ef7762805edb9edc80e63e2693bd53edcb6551fe0cfab0fb0f6a21dc4bd15c61c13dbe1f60f9735dcb47f38d94c6cbf176bb9c3a5d27f3ac9cea597782ddb676b229eb67f3213f1b46d7f2c5bfe71652c91282f16d07e31f552114a0ac5145e14a14811724e44210cfa6cdabdb04cdb3e201c126ddae80221ab871f68fc824c0ec8ecc98078a233eb8827ba443c82bec891eca200bf732cf1440fdf7b0fe6533cb101bf78baae77988d6c7f9925aab6d37fe3181051f4d9d42e5573a5e39e006b19ce64280383a1a5cfb0a7bd3cfb07dc3d9c4b14fdfd12cc44a3f4d60faf0ba9daf150f4945234504a690bbd1470966dee1e774d51baa7cfdedde3cb95deefbdfd8d58d24ee9a5975eed251c4f94de077ebf26fa5d7bfa129df6d252fb329c89270a65e2893e0258a6e9cf1253ddc3a14f0131054f99b83ade65e2511deff459cae39d26f30194b60ff00b0c2fdfbb22a7a526b3894d2e661a7617711e16b8906949262d3fa78e431873a292b8242a89380f47478ca989f3fc94dbcb2c7264ea88a99c7884bcedc13bcf861b5eea27899229205e172d714e599d3b9e0e1823517305715322cb9986e5e0cc3060f872b536dccaca4e3bcba4970e2769f92ce2c41c17e04ea539a8c3e4bd071f7c70de7a6a0054dd1c712410b18be8867792c7c1b1f781a1e218dd3d1e9a9f44c9e8eef1cc1c674d52712a2be27495d5b2e64489c9a0c234bdfae500df7eb6dfb3a9d51ce0da2f079876cd019efd728065bf6756dbe2a6616f61a382ab2e52d1f4d66e2f7526fe037cc038c01de4814d634a8a3745d3fa5a7fed1eb0cd69ab07db83a988343155454c41981763a4ca9ee60177b02fed5d0ff2403a3c14fdeb2b439ed7426fb6f91245eada992c1e30fc63d24fa76bb677c0f0a6db63c01da9e991bc167aeb058e875b8ed8b1e6b550e8453c51d8134ff435439e78a2f4b3088ea797db8e7928453cd120f144b380bb520e70cd0186107e6a26c514ac3055090fd3095bddddeb21015f11f011becb5a9339c0420a6208d0ef027848ccbfff0f0b2998e9878514186913cd38403d6a1b315c5a8ae8770c919879cb91d26743e201a6e9b32b55310673e0816ff5a4cba984af54997ad8cfcf1c24c6600e3c2b7b222b79c9e098a6ef6e4fd30b265aeeca8f91f91a12451f391c275d239ea88b44d901bfd57c772df756f746aa668d44d1d35973d3b49bd9e4ae8d44d1431ca86449d3df9eab4854c1c8b94b62ea6da105244d9b34bd3977a729e451e282377477799a4a96169a7477bf68fa0e379491ce9aa6a7d70632e18aeeb4ee5c96d0dd4b72235570453f5917e6d9787d6da4aa665a1155134944d1d3bf9b789a03ee2ece4dcb5f9c94facea5e9bb1ae7d9b84e6eb868c062683a59313eb29a3e8397499a4e24f144e3f6a2dd542f6e9a76cc17279ea81c70776f709afedec454772f92a88230f7464aafc594c43031664cc8e015f01de59ce5de7b6dac96564b2fadb4464c752e47a40a3e9e860727e8aef492cc15642f85b30f6771e4805f63cc050dff7056803351d03066b6a0e184b9efe6091ae2c34b39bc01a6a4cea51b9e0dd073fcd0c9161e72f6d0f02f77b2a7a1d4434ab6641d1a5ed2a1e16cfcc7bdc61a3e4a9c88b9d71227e6c8d63c8427fa882373ba89313e7eef61fccf07a73f9ff75e2635d07b9fcf677b1f0c5fcbfb87db380dbb4a95ebb04ed42936e70c99099ea573d1ee1f0e1fc6418414c24b3760f9784a4f986228e97cacf4f5199d4fb4050c845e04b04fe5936ac016c638648fa5c30f3ed804bf1f0008ec1dd972815f1389f001d96309413c96354e350c105350ccc624966b8f05b180851cd6a4920855f424c2929e518ca49c745ece4925adcf2ad7d1dccdfc43d6eee86dacf3efd9c820162f79a7a5b5523bafbc220633ed3d1b4fab5964f159e472bc8602c2792d9ede9f00024320ff849d8f5c6c221286005e36c1f048402cd8a8e0dec6dc6941507e9fa17001b3ce80d1c20b9b9644b49c2e2d2b8da09697d0082dff8080e30fe1d018cedc6116acb397c295aec02c914fa5218db26596f026299f166fc86978170344950a4b2bc1534323669c31101e4922c67808bdd02fb2641083ee2e94f36e816196ef2933618d03075791ebdef5074ee8b1590db13488591d89eff09337d8de7d364e6cc89634889613b2648c47b2ea527f23666ac09918e02083181c9d21a09cd5bc6fb6e2a95ec24d83560a4e3043cf2ac8900a0718d9c54c1a64d70cbb58be996b3d54fdfb3cc39b736883cd93499cf94554379bcc2ebada5ba8e40b44d8590519627370569f0719327710b33a02b9c723ea2d57424329e2c87b2f7a44575b5d4fb9d9d2c1b535a906b700c20c58ab2043ac0b685647e287cc22b45647e03b5cba676849296f30cb504fba7e3279366ad7dc95ee1087aedd5d43d74a8b288199eec575d74d373f719f23f6cd4fc03ff43503becf3fbaebf2960177b3b543473cd59b5e93e2a93efe01e39d6ccbd967f69a69396e3bb0ecf0afe1a6049689805c541251f519a6c5a993655adcb01ca9cdce6cd52ab99743fe144ff527a9b2af8f5b4095cd4bbc54bab976a1ebe1f6c2443cd53a73e2a9bed689335b38b3a5c9c48843f658b2576b34dd36faf872945c01b31a42a920b3baa02329c12b9ad25ae12f13ac238a78043de43e104fb046aa7e088f3cd583d08a670336a56568fa85a614f2504aa9023094271779985de289425516127146c413bd01620a26819d5ea35dc0b4bb6f2f38bb5ae9e4f213196a28fedce6e1f639e43a23401c6cac72af2167046cf8e96ae55ec36f104228e107420821d660e64ef144eb9643fef144ff054055963ff05209532d77f775218a78a2548c01439a0c67ae18b08e1503220a427871a9a6a675681d3541a7a5fc93327b52157aab1067ea711f7a28079161062cc0d40f914b7456f786a48e189a72e1349be634953514a31c704228446d4c4c61a7736218169b6214424843c7b84c4487fe5e4359c794428754c17c6182c01e2eb4c0661564c81d026b75447b9021710637abfb9a234f7565cdb371d2f4d20a4ae51a9aca3234bdfc42d32c94ac80a52099d0f4b765454cd9e0e053d0673be66a0cf00d0384c9dd2df5050386dcfd02ce1e9e54c413a58947d0e3d0cfd03cc10b2ea8a254c254c6c413959152c4139559ca2cc19d8ca1b162b6da5c956e50b294881d2f310c6162e211f4d70ba74b4f54d6c423a84d3c821ecb55d6c4139556c413b5e901969735d28662aff5d8956fae94dec81a4a29a5945ed6d4603af7440acc26cee0f897610d73bdb53648880c35a85905197272b33a727d483cc1ceca5a23d80de89c7f9dfc41cf9f4ee88c3d32f740180ef4b0a027f6b72da143a2e6121235a59494f6e1a96efce2d9803d6d7061f0a40a7a7601c3863d7183a7197be21113261e31afb85da7dcc5cdae8986d9440f81d0366273cc33848145226a9edac818d803a1c692696ae36d7aefe502d7c7fcb4a9695914808e1660b46cce7a23588ef9ea925f4414ad875db3ecb1c1dded29d59b2fad2e2c2a5970470358d913539df40226a6ba2945d353f9454c79318b34fd932f4e994864ca5b832c7bda8da96dcbf2dbb8bb7d6eb5d67aaf5f138eeb9d81aa169f63b71c694a4a298d5b035e4b9b23de9a70c477e53eb983fdf9ac9f12873feff0e737e2bc1daef4af35184d37c9c75793c49395832ce2f8225c92bdd423c431c64853c50b8c5bc842f893c9ec524a29e537901485b0e30f8661b9232241b023121b52d28da9d0470fbdbb9df2141847b909f467204ed31e23f451e892c776ed206e7bc6754d74964dd8e5f1a709fbe71a280365a00c94bb26da84659cbb26ba89d67eec929bf26a929ba0dc3df116414a8380486307fd26d025a86380e8dbe9a6233b288bb6c0d927dc1a001bc46d7f5b03608b7e236e59b405d632102a3a28ff107dcb3f625cbbe43a519ef194423bc6df4d72e30177c4c82f9e52601c254f20126e498c1efadb9290a15128f48c6a320b69a3aa854259ee482119caa593425ce9ca3ee549593e5ef0ca44327eae65d025776fa9743833d858aa4eb4bff7d1e7a2dcdd50fe1ce7aef4f909f71eeaf34f967f5cc7ae8d0371efca2eec93415cf7067d76337a5e1ecbdccd902163654545c5644a49414129954e4e62c4800183441a8d44a250086310e8f3d9364dcb320cbb7a5e2d45a23cdf59188ff1f76ce07774142377b5e74987c1bdd742ca5d6df9906d397aaf2584b914feccddf6f77792b903fdbd89de0ee23e9c08606759fea11d7bdc78c063d7f1344dd3362de3b05f9cc6fd98975cd7446f015f76975dfbf67b8dfb813df68deedeb70c8436f6a7f57511a1e99ae8b7aa95c3213fdf130980301ac2902856783a193da458c03b5e090d580cdde3423de5e0dfa603fe46849750c08e27a9820f151faa115f4bfc9928e9a0c34b5dac92638529d041e55d2537f1f9de6d2ebdabc4d37c3c95e269febd475fd5f1ba9753e3d154d1ddbd306d1b91de65f21e5155e4480868ff181dc653f081506af4894ffa8ccf2f1153a2cf271290c5d14fb89191d06f4418dce833b810d0fe81633ccb5eee224c3f4b697ec236c5b7db6b4815e8f35926b5b7e588f1936730b8ee2de330fe9e6ae51d6e18a5867119dc0aa7c265d674cad9bf5cdf01a117de72f0af7b9ffcbd5a4bd3a6e493a3e49397720906877fc2e1185cf78e9f490d0687ffb69781d0a659c7886300b704d723a266be114ff38e017ff2966f13dcd59855bb21b50e08edf7eb86016a2cc11507c3dfffd147293c054221a638e0eb63ccf0b3860190f4fc068044d5b3438e0262ea59818b2a7a967ad4dd63c970b1857e5df47cb5fb634a25a666cf4f964e0206b32216cc3a6fa4aff431caf8096313b46041ce9f15b280847e5ab040a74d32e3e86e3f0d6fa02d2e9e189f8cf311494cc98e588858f454dd1c6f246a7ed6494f3d5135aed0734e2c51f34ad4a43575a6d64a698c371d6f78669c4690695a6badf5f7de0ab7c0ef19c6bd150c8c8d44a10dae28365f45a10d672fbbf7e61ff5175c91f0952ad29fe81b46ca97e250a9b45decbdacd6eda52271dd2b67708dbf6bc077cad37bffb9afbf213f9f4ff6d7252c5542b60731f5101dbb28ab80c8eaf417e5a9a2181e8a9e46961b9abee3babb2ff25cd7e7f2061b1764c81446e8596daff5b6e82f131a2404b31067f2118a3912451fcad146a268c491287a5bb4e7b67aaa4ed3d7d6bdf7de0bc207cd34e8767b01e1dbed05678867dfd72d09d8a0dcc1aead78a2b64653ed35626ac321447f2a16051b6460563d5d392e1ebbd98979051ee156d3564c513f74cd100763997e40405ab71b2ca7e1e7747141a9e6bc912868ea8171261fd8b3671967d64814644914bc8c017c8a44018671ce0855330622116168526626d673ce39678c54d51d898287a519d310d69d8b678db90789fb6c725cece9453cf5c4d4cc7247a2ae3c7b20eec91353f3f0d38ba8a2c10ad63cd46b05bc80268a5aee48d5a4c343c1433d343c4143da82863caf051eee34cc584e8d58163c2d33b8418c5a3983b3df9056d36cfe91fd5a1b376bb32ccbb2dbd7967b6bc0dded77af0d32a4083439abcfb3ec9af6184d3db04bbb9cc19dd53a007bfa87f6d7423e0f62ea113af650560191153ef67af36ca0b47c451211107a5797b4ac4a5ae25bc2a397262b346f26ab63240a73261f78cec81e89925346d29a18e0aede488902dc45980de445771387100dca6f484c6724a0420f6822f77a83f9610f7b3ae33ad89371f5d8843d4dbf5084a6f40adcd59b7ab3f1d88a19a1b4a674fd55f26cbc96b35e2e74fdf59a23559f7c7124aabece2a7307bae9fa8487aaaf3861e88a454e571a89aa3312556b4e9db96dc05726a6e4e79c534aa904a87a11a6b445165dff60d5a915c2ed05ff8a78aad126de6097e7e6b4a46af47a75bad69cd792d59c988262c625bc96fa988457447d7d5d1255b5d324cd028f2ee473d285803e7a7c7d86e7e8a00b21fd7321a3831e49ffdcc7e873d27d7c4ef201fa8854eb57a3d0af5f738642a28be4bc2e6a419fdaaa3527c4bdbe423bec4d3cb6871eeaa93dbb343983e9af7c73e2a91e7320eeb624aafec33d7871e680b37c239eeab15c239eeaaf7a58eb6dd58b53eb55124fb524ef7d17271e5173e211b507f417e7d65f9eae97dbb5dcbd6cc0f3f1d2e6b5d47a0c73274826cb629c910ad963e928cc839faced932555530c0f353f5b13a7f116a617f134b1be308410f26c1cd64d6c00345baf6566ad98826223c06b9917c02b625e6584cb965dae7f2ee41e7421d73fef3013b3f56c60169bd785807eaf7718f47b1fa0dfeb1e741ff720d005d29e3ddb7247a4b7ce0922485a9b0de10ff8bae5d872c6691cec261a762cb089789a14d88044cd9a67cfe489a73be79c7f2e8fc2cc9b45367f75177930676442cfc332bcf86ca4f43c64f26cc4d29c77ce3bf48c43cf35f4fc9b3388b5353105058455782df3108b57c4fc8449226a9e8575135205897033879ef58f493c4d03dc8847cc5f1efa36d8ba17c79a1d0ce70cebb5ccd32cf076fcaec44a02bf2cf4404527a05f163d6368b8c1679f832e047fbb90cfa703f0b7fbf81c6472c0767c1fdb710e72a48744f900fd9383602b9ce1219c91a80973c9009d1144945430a959a2aa8644cd98b23230865e01d7773086c78caeaf1c84314c226a7eaacc095bb254bad78b77ce095b73c05a863051cc789a13efc02bb7e0cd17de47fabbc3842cb5eec5b8d49683629ebac2b7859533c10c5b6fc0376ab80117a0c66b99af015b97cc15434fc869fb1d5ce34d124f9602f164ed759988273b71f264c593bdb52e370ef6d15a6badb5f6d61ef46cc8cf1c37d8ec60da438287a29a90a7729151047936204462be83532831011fb93c28d900c340054d29e0443cd10dc4d307e211d4fe76f1769868228a202499a3782d94b4ea30647936e2e1e75361094f1d371cb061add4e5c601d3d30ed4f402785860c1e5b5d0772ea06723dea6c2648f8505719e01f114239c309f1e4fd70d38c6c718e38e8cd108d96331229e2884204a7fbbc0dd6341b8810e6360f05438468a676396acf0a4c0849210a00d9ae6c02c348547ee6fc4d4059d7e09a98271fa5a309e5dc8e8d885c078767d3e1b302646c21821d84717921dc6b18fde233b0cec2313e86f45ca41b0d5288368a71dfeee607c10f7031e3f83a1d32d076c10080402e1f81c74d38ecf41cff13948040281365108f48b39ed50fb877b02fe018ad91888cf8bf7850e6e0989a2c7b8ab801b6fc036d770792c8ca5ea0294eaa1e99b782df4314f27e6b2ec904884cecb09344d8374114ff449e289529c7804fdede27e058fd908de912a9c61cc8dc131a51a79037ca4293d8cc35395246a0776f16cc892109a461ed8a0290c4a5105b80fa53b600cab91288a23a3da0ebefdee0e8eafda640116220474d185e0876a9e0d223c1574c38503eb98e14e1658c8911ea1e30b111d7421a16757839b29be87e8a0f7d84c313b4074d07d88f2932850c6f711ca7046a2e8710e82ad40f962abb73a1263a63b12457f2fde81cf1e218c8103ce2e4576ee73c8d18644bae698afaf38b6d79b766cafcfb1bd6696d7624fa49f49c7ebfa1caf6bd6decdb6f1c36587d937ee09f80728e60efdbd18974a5d761664a9d063a7b00b15151229c21d982442166cf26cc80b9544b82442264d0f63249481333006cb70279ee81bf095214c8e229ee87503ee4a4d033d2f1744af31202967ceccd900bec1b341eaf99745efea0c620ee56a45b5913952b63ec7fe56d987937c68d2b4bb992313535d8cd189a92a454e4c3d2df8b064d6297ad698253e10670a18a4ed41a7697733270a750f3953aab65f70ce8f919ba56645e88adeb820709541d2af9b421f1daeaa4c8d892729e2a94e51637030e835c6c7fd968564bf9e591ba2a650a8c65429e6eb4d4d12552f8b3a451f667a56d1b3d6f4ac363d2b9290a43367c9c489a9f879a9848b2bb84de03a299b42746322fb756a925546a22a8d2994679de9395b39ad2b9be8af4bae4706c58bf697564c89827c4619eda28069fad7d831ecdb89acae6cea7165d3276e0f38227f3d6e0fb8a61e272727b27a9b8f183fc94262e42b51d1944df2af438fd77e23c288f9891fa1bf78ea228e1118d7b291181488a8f9182418390a26b44721bd2875d1d3e4bd50e852c28726ec42e234e939e76d02ce4010d31ec63629b32d47ecbae1885ae8690f711d888a381395b8e349c70bdf952f75b49a8849d3c72f9a5e9a88d33a629a881375ccb4c8992825b588c33a6e222ef44cd3b6177c34b4881b40671f0d4499609864e248d55c1251f39349ced4b902ee680ffd22a69870363568116744671f2d724f0b2458d122ee88861b88ea5098a4e7b57e5ae4200bb4d5459c9499032f10c43e50c96bc9c26b9917715b47cacd87ee15b8d61a98789a558a989297e959a9e829e117f134a13663968069cf6cc9495b55269e668cc139352a4ebb9c4a31313131554a25f134654e9653e64815ac22a2e6adb85740244ac0a06b31c6186384333344c4537c0d392f868b869e6ee8b9cd1a9333e2b044cdb79a4034227d433aa1f58350ceb4839a76502a392d2425a79d522c69ee8038a135889e4a12e572899a577e1275b3ac7986569a9e3586d698de5873562184903d968ea4d3f55995dd26e5b66dad26513580ed8a1e265b92cd66db98345c496c636eec31071f174d68fa71a1863774119d6adc84132d3a93f049f97942b6e8a532509104246d3390d84fd806c16cd133c9863bb4c602510dda84ffb86883101a1f72267c524fcc0c4b1a1f72f3d9bb0ffb705b4bee71d18627f4b45374157122b86db395a20f7da780556ce2a9e6bfed25ff4694b80390d536ff90073db35acd7aa8783aaf498b9583451ebeb0315874b75db1d56c4920ce644d9611b36657b4cd4c4895e909d8f86f057bd0041c9a15cd261fdae9691642af652624aad66f40aa82d07c7a21f419b224aab3530eb27e0c60a00f9d091a6fd89d02467906b5d84289add824a69eb8af356ab8b8749740e0d0af2671a70b2d30ca0f7919bf1199b897fb7b1cf70c6a12c0391efe9528f89cfdad5ecfac86850547aa34a91ac5d2d48208a226a2ea83b0f0d9c0174208215e5b52a5e5ade66600fc45003cc3f55bcde9f40e743ae96f5b628435bcc18e5469af3686c6a3f1f75436e6a1ea69944a9ac9748c070d3bd9b6b16ab61c244994c4d4b624a62015d070536b570b0363615848e012cca013cfe0858c41720626714b82c7ac912a938fecdab38dc6017045ca588fc98776d249398391a83a6d9e8d2546198b41666326ab46a7d5f4b141c7a6fb69a1736304633bd1c6d452e906f51eea18e38fb6179c846703bf923e7ae772b34411527e1235ca9b8d44cd8dc76c12476435e288ace0f6b2d52401bf9544451d4ce24a310d18671cb0a7105e8bf651963052a5e5ca235180bbc9ca2294b5557ab5554b7f6f882130ce95677ba95edc4815766fbda917bf2b6d076d2fd841db6495a1b63656dd815328436552bba04c6c98d48c01670c30320f366fe78a28e46146caae979f29e2a9feb3bdc8733309afa51e7333e3668d44d5ad2646d76f365b12de76020410cf30278b4c242764b0c2c66c13899d89a96edb36241b2ba608f0fa2d494cbd3648d1aab9aab754c4d434c3144d333348d1f5598624a6b624ea55069d6ea3a9adca24a6a014cad082d796c4d4ecc663628c279e6e1618cf0906c41f3e575b1b0dc633e3f53106f8b5f2d49e8d26a6fefadaaa43d77f06272b8f54c1d5c98681c8a289a86969f9965b3e73cb61ee4addbbe538679a56371e30c7fc62819f0d58c4035044008a084011ef4a1d80634e16c164f8a269cb225d6b76454c412464e8026f49cc770536cc4d094ad26e46e5a4f223695e4bfd64b93c6e78db048043888679aba1c2311ecc8b989254c453cdf1aec0863e79576043d74f1b88c4ebfa592355a49357d2f67a393385f06c0c012231e303904562aaf2010666c843d7479ed82355f4f066f341af5dcb4246a77f2bcccd066d4a40986ed0f600fa207065125dfb28c716173bd3b8fb1165285eae1c3f39ead4cbc8b18bd86a4137d1443cd50d40d62465ee649b018f20613ed2f62bb7dcca415ce7047c76a78053f070d3b48353747ded6c8c95a2de4ef1b4c08315511557f51b92988a49ccace6e6645626a6ec13f03fecf18681d427e03b288fa36aab7909de8c0443f14414fd63bbfc132180176d19886c78517ec2b63cce1dde1123a5c05904b2e52bcc4684681fe57a19b709d06bf9d12cb3bde83762ccdb26406f637ad003a9fd047c47a44576269eea7fd86c65ec1454c4d3167007678c683336f0c6e67aba92270bb386cca1ed103bb47daf051e81ac07c8c7630407c54ce15008c07577005c476a2038017050b87050cc2e82ebe40fba3e001c14b085eb24165d4f04d7493574fd105c276970ddf685ae477150c413d76533e87a0070dd1482ebb627747d105cc7c2c275b24d5c27bbb331ddc684aee7b80e7f00484c612843da00066c8ce55e3f014f51ae40da46d1f6a15bc992280ab46540db1efdb152581928e06ec37824aa7ee33a1dbdcd380161d7cdacb5d65a8be17ce937a2fd8464acac883e4386e82721d1411fd131d12fd1af4824ca9d8eb628449ca8e1448d2e1de593eb8874e94fc0d8c658293619b732338e613677f92b27dde7dc57e0458797cf20872f398bf14fb083b05bc86dc75ca7a331fcfcbd08628821861862aca34d335fb9d3a1a34517dd90d84efb2782190d821a6d4d781ee5f33986b74f81187e3a08f353fe7e7cbee51f27c777a246e3ec448dfe9c1ce572e3513a7edc769ce49c8148cce5f91c3adc92001d3b06e2ba218db1c57874f21662f2f8364f50ee84540dc3709e40646333f28c8756381b134f33bec28566e40e3626037be819c6599978aa0f7136e60d183b0e19a56fcfa08c5faed3d1f72251e732a1e5f09fc412638bb13dacd112db191c1039e7cf98f393afdcb968dc947194db0c377945dc9301656ca2dc11e96a70bf8c3f19fa5c20f2658480c83973b9bb9f914f4057ce73abc1d8741184f987fc56fa26bf6d97f1036e0b20a2c31e42083978954beec736bb2322d31dca6776a2466fef9ca801b7d2bb21ad46b989eb7434caed4bb189a9b7bda4a470b7a7f6a98900ee8081f16c2fa563f9c513ce87833832585eda1ad1230ea8e4216e5bb25ddcb6711b4e3c4d56859975334bc6c8182962ea9253c4542731de0eafbbe5cdc6c6c09edceba23177c2c1ec1027a63eaf874a608b72cce763633e9fcfaf544d6b6fbfd1df36a4c6ea08ce261eb3ed67db6cda9133222d129de2093e9e20c6235577558ff5c49496b71a89da6c242ae775f60677937539a79298ea9c7069d125cc12e76ecec0e34bee2ca778b29acddb664534c3569359711353360381fd625f9fe1c494c9feb57c86a46b06a9a81ca4a2cec4531970b7c119cdc6d66b5c56235115ba58016d0cacb13112e504dc6d355d2655998d5469db4d6fac4d49d7ada6b6ac88aab7c21cc7a4b34bc3dc0052d019a6610e002c60426719065fbc59fdccdf88276db9c78a4142df26e04e8a0eb79737b9d9d9c3787b91f8777b99cf38b82271f8a1f047dc7d287c2d6e38308edb363f11454388ad14988356c6c6f4c0b3b77e5aec200cfdac20032088b8c94a124fd5c81097d59199c408e9903342bf44e34b693b96161d734eb834e53210c85a0bda30066d2fd3da27fae33a9128eb4831e9cadea0b87e634ad6b3343e357e5215034b55766c634487c1695c1018d77e7113185dc3e1260f2c9f04851f837b0f05833bd26374ed19e62c871bc7c61cdd76e0fe618f8f715b4d3cd58bb8c016c6f6324575db6133119b15dba90d2723a46f564404c47c457afd565349dc66c3049cd9643532060258fbf667051900c1c6589998aaad78aa75f331ba267afd4c32713290c808e9da9685b4d0f6022f31de2eb90ef46da4c98fb617791b1353b0ebab0ec6ac76afc05bcdcd869361aeb2e2a96e56c414be4dd70d496facaec75cbd89a7fad8b862da50ccdb72bb97315295bd5ed6fa182b2351f524ce898ed4f6910fd80952db1418989a8ed96a5e4bfd5d02fe8054d59b7a8c47f26c36db155d0f71304fd7e80ee26c3b9d4b0d51ee4e2e38773f958eb79acd0a5bd380274e7d4503eeb259636d56633325e0cfe1b777f5667b4076530fd2611c460e0257a41359ddd1495988f6512ba60cf091646209a9b2c7c7f8f01067d375ccfeb5964d3db48f3eca41e835ad02d1387bc839a17528d4b9705874117e42e2edd6867083b2135a7f2ccef291798c036273d83f01fac31ffed0369b78f4bc9d41d7e7a0ebed0f625e4bdd6ccc56d35b4dd76fdb5663ed5643d291316412a9f00463a8ef49e0a7c51d62fa5da19f165eb0fa456eef79a187b532f5788c2b740093b3927908286775e4c24012b0f6889d9ec8aa62d9e400f9f91ef2f3d8670e7204cb3dee690e422f4f64550feb61128824bf78bade411644124ff597c320bcb1c15a8eb0c666daeb1dacb119765803ad38c1687107259d0aad30a72b64b2b2cfb0eba4aeafa5180883817a18f3bae85aff7422059888294e8ba75aa3e16bc87a2bacc11e17386bd604e42f06968035f0e6d6e00de426608d1146040177b0e6c6dafa1a6beb4925a992afa7873c516a219bae7fab2b559447a2ea312e95fe8eeec8b4dcc961f25631ca9ed294229e2a8f54d11c89a27487d4f5a524ad42e3a84e4e1554091c709ef0da60f2413f3fb310d303de8ac88afead56d3c75dcd2c64feaee2b7bf1512f0e7d783cc5fb831713d085cd9fba82b1a04aea8a43bf1c4138fb87a6c0e427fdfeac399e4ad8febf737e2f441bf99e43198959531c9fc561b27649ec6c95d3912550f0798964e14de70138528501dd992aafac921910525b0563447aab420350541a0016b45e51748c0dae7ed31987cf5c41316134f558aeb70353993a45c0cb6b2d79223e0ab75e56801d31da9d2b2493e085c6987ab18a9a22c2a5593e2c804b9302b7b71d8125854125314e7d70adc5156d75316c5b1dc1139e370d3f4eaa902a6068b61f5f45c5f6811079aae7255a1d01d5684d4ddd543935096c459c0dd9553d3f534d31a89aa578e545d3d17cb0de0eeeac110621876c96dd877d0913b40c7edc5e400fa791ff433f774bd8f49798880bb09d358f4b43a7206e80c6e2f4fc64f0c818c0622a3638602c61c37fc800e44d043d79984aeef507acee4e4c82be7cac950c02be7ea792d35eae15d3dcf467602dc82d2d5b3e974dd9a74ad2e004257ec075db11c74c566d0156b4157ec045d9f71979278aa74e7b55c381c14b06d11dc9584b843bf8d89c78259997cd8dfdf2cc4b4b2f7ad6e4402b4e41e1679c8a2dff612bb88a78ac55c3d12556f0da63c74e7eac11d45d2f514098474870b1cbba3f0eab9bea8c76ab02ba2eab141a61e2bd285155d293645d70e83e98acd74d579c34e635674c562ba1e46b913531dad2287761153f0095d6fbaa35e74ed2be75a92454e007ce8b8ed80343027e05a724f8b238ca1df3601fb18b8ca00be1161e4140fc2373faf6f107077f560311293e97af54879f5743dad82d648d57c3db5912a7a9a96f5a5904d1c2289c0c9f920de6783d4315a9604a629b07ca8a4ac92d6c124764cd18c000010009313002038180c880583f1704422e790de0f14000da1b05078521b46394c216410218480000c000000001000000068dc5f0be7d9c165952132ece6cf6c51687c059a64928acd874c2224f9e9efb6550d0791b94d910a5915c4b2ab46b316839f469aa81d13e6a7e0c5a24e86bac3aadf993d6f561df7b5e42be2b839819bd27dbdcb538f78d93c281bf00715ea954dc92c04d44e3748676b1f61b8a3fc2f8a0aebaf2895bac1e6405ece8490b5343ded7829de5efc80fbad04aa70d009d423e7bbd7d43af39433425cf7be4d211b87026dd9695853c5bf436913dfdc86bf4cf77f1a12b02e7d2d04fcc611b491fd19503cbe377297b04f72d15b4312261ee1e5d2c3025a3da53116b623136ec4164f469337ba63909135ffb22e58ae26ef7c8e25e028084f201ca759e6c70e907381f16b5898080e4e366e029b80ff68c1d15d1025ccb898f12b09a20c774c93ec8efee7a76b60e64f5a5c1db84caaecf9f9e83e3fa3a0f08ae6b778c426401079d8ea5f6bd6dacd81a51994392cf42888aca23f3cb7727801843fafe914bb46d95977ba9564709185fa08d4f0aca4309956d1fdfacf42f40f1496f906f91f6ace29bca78d0b8a1eb7c4166b5a8a346850f33209f10836b2acc1cc23ec97b9cd9919072c81586952f1c7f5b7068aa889ec5a432fb6b051f5c7b652727d079d2399f733ba2704bc3322fda452df3cb4e6e5b913f79ed3fadc920a6238ab9c4fa7d04274600c8e7c7eab33992d0072bce74a692d51e328272f22d560726d9773ed2237dd9bd3ad83710c21cfa53e528d3e551d72cbff59ee90c58f3d51b5c14118abc4d07999e82c35eed3f20ad2e594ddf5d3f93ae96edbcbadb3844149dc35d8a603a56f71b0e10494d6bb5b6ba2a0dca092ac9b2fc36521ac716510ebc9c16601a62a13e91a1c4945cbccef65c1a11a540cab23c5c39af49afee5c2733ada46d4cd3b8f7874eb62ae52ef80830f99a89acd2d8fc8d2610e8fc25c759546fcc6fbd7cd359c9ab09f097147a42be13fd982bb14b508a15124489678eb38b3ad8945da1295a886334e4de870de8212a20cc47026492a3da4e34b7366d34ed3380d3855c9113a3464b45c7b6457a895a206e36bf98c8e1d97fc530ea5cc2320644a810216d5d9dfbeee75b8e39b9ea55f20f8d90d4cccdc59f14d5ed07dd0819d257434414b3d68e61d3b71ff611b7a1e296f6f3c23186710867fb66c6938043ca21484582de2a410159991e819f56305c10a2f9887261cd641dc6a34e1b0ab81b2a913c7cb58f661d8114622d005cceac09219a3ae5940764a84d0d437ffcbfa40baa49501746923da101248104dfc7a243284fd2ef54cc7b4c2dd38f68746e199533cce4af748b0bf2ffd12b150b2fa53e79dfd0996d8f53a9180e06e8c9f7a71ba381bbc28d1c6f131544fc0610f281fa2b099830ee01524d069ab1a4d4418ba05e17c0413b08c6e5e3950000c35a8ea0c6a99a69f07fc9baff1d057d0590eeddfa9a5592ab9b4dd17ea955bad2773456e335ff9e71f78315242033b561a42bf01df6b1f1dd15524c2257d03cfc91f67013dbfd7af604455dc1a3493d548d1a7b60105d36b099f1e21e02e7bcdad425e6c296b85f9e899189f627a1a2e21dab9eae67dc9d7d59413499f4744d94d449d82293611803626a7416c0a2b5873ffd3a8168f0289091bd076c6a98a76791f3cebb63a42530fd8d060e2ef6033c20125c783cb07a42007f43b7d22a19a00e03795442ef811114148eaa1a55bb6e5f5e107a230583394107c40ffb237090fed66dd72e003ac251c611b2c49e15bec509e870d4aa5b188005923f8e13c5dca38aa2030e02de55a110dcf36d659f69c6d71e311e0c177581c6133a54d1db50180adde5f0a2373134e382037e537c0dba01e091bd3ac0e2e0b062f5581b807bc4518a45a528e69c1e00e68856e9602d13dd8f0669daaa2b883ac9b4e3068f735264769d8f3f310d3c4a29dbfbb4304007bf61abba6cb06b4f6e837390e6f7274cdec1042bb0d11ccd25b39f5b706b313c2fe9ca059876f2680f9cbc3fcb7468a53443eb0fa9542610b909cff60eb7fa4fa0a953c27a0478801ccd7b67ea7e11947794233ac6c34c555c7f39c72dcb10e12324bfa8408d6ba22780abb05d64a3fa7f611d3b9701ac2b26a34b5ac48bc25ed461e912dc23d173911108b59f895690bd42ee732b7487e9e38de7c26ebce9afe53f252470ed34eb24c54f37191fe21351bfdc70259d75cabec346bab5dbd9e8958454cd8db946c138b3f81fe27525a990ae83f0bb51dd55032433c53cafccb4df0a1ba5db6d89c768d208014318961270dcb3f59c39f10bba13107d392f0a20f8ca95d4f53fb181d36913d96ec1eec4b3c38005addd20e837a7fe5672f46853a496d552da91ebe412535d4f9cce549875fe3b8ddd307797c3d7cf26b3b1b343a865c3ca690f2dc54821dda9c5b45c1a74ab37decd0d31d522ee4a2e980aa7b606a92a610a4db7bd428c003e397d46c0b77a3499ad82bfceae9020826f87365cbdf0f226b8cb3f199d94ac1ae686ed9938b6bcb772218176dad9098e5ae31574cc2df59b87311f4e192930f64ee70ba29f9b53db929dd9c4ee94953e9695f4a8a04c49e39237b6fe64b585fb8749856c544c7a746957369bb0e926c8804df19174cb0f07d4fac17202fefb341dc98595937d3c8ed91b9cc88aaba78910f089d86140241dcf47548e671e492810f05d0c5e497435b32fd7e58a81fed2dc25fea76391eb4c3b90b9128049aeb049c3e008da36a1238d219b88e11aa0ae16a984d6c48442cf8079479dd05927a371061052ac9ea3b583e24e2c25a57f97b5b211540c9e1bca826df26ad94aecfd1c378575f92f93cfa1357f4d27732c081694a1aab8973a59e162765bf038fab47db8710076f0fcb800c1ca73eba20ca60eaa333ba9093e9a0998166da13595c6f8dc7a036ad15b7c95e44d609be36b47171ff4c7b402cd665af60923ac9d434560a4d85a3ad36d735de1b5f5de803efc3c8dd61dc15a6cfa7ca33a694f696b8998e29ef3bb8001912ee533bf7ab1abdb45ff62677f4b0df5c8ee762b6276c7501ef7cfcd6ce5991c71a457ef6a6d532e6dd1a0b9da752e10b82b94f3f0b286cc5117e79387d669718c680acac16cf980e72a4acb3cc5126ccef81c52c5a65d8dfcefb96e4435e2876993138a1ad524c11290c7188d17c9ecec1d8560defb610c61d98170df6c985d46f6d8b277cbbaf82b985d09634f9878d880ba1b51c73024949b13292087009d5cef207988b7007ff0aa22687331b29a70b2a3cd87b6328882615be1c1f8645611d1d6f3277b2738fe983115c1ba1a3b953d699047499e63cef003ae4b8f544cf9e170a8650c6044fc4a53ca9514342a5c49664c48a5bb9692e7f0f2bc8c4015c1ecf81c96a7580f584a01d5fdaf2a359fb0237fe7a67fd2b4a6e5f1c736a9bd99ba1f67c094bc8dd3e01cf0bc5cf3870036d89ccb8d3896a6a2f6a9fc21bb2de88254a2875a60fdd6b4019bf8356572d2c48bd12894e6c061945be86e76386a82eb07c26762ab971cddd7f49fd538a5853762dacb6a3be9dc237798af886e8134bc72cf0d9431950f7b9d6ecf85d991ca9294e416223bd81710a74d40f5dd6760b61395a7639be3381f93f0c7b19f6ac33f88ce73195b8a0c6aaef8f1e57d8d494002adb7c594728a4f843289d1ee09d28163584f2ef9ff8fc1a9c3399c2e64c0639c3ffe965716fc827188574e250cc1f0386b3e60998b06d845dbd21934c6fc1180c7497ccc6b3932b7215fab7926b893a505d5153537f67ab9a6daa009019a89c6e9599dbb26fd7a2f70020ad35911c039e513a2d1ea07c20a43c848cc283a0a6995146d5634daf3259e2adcbb4137e85209b8a4b263a04e80cdc0d5197cfc84e591914c41902c444d59fe9e7dfc5e389a6eaba36e34fb8ca9cd4653279e9ad901b34ab04ecff49e2c0c94c598504db937e948f14fece61f7ca46cf22d4d77b0b4096bfd9f54d3c9dc92879277644f6719ee5a4f3252b9b365e1ee4cb1239ebd11295de7721713f9e9a546d9dce3ecd96a2da0b02a5132140a73b38a450b240478c040520ba594a2eeac9d5e7ba523092cca4dc6f1dcff5fbbc429d54d656096a636ddb2f2003fcdbc4a4939abfbb713c7d8b4f66bf9feb3a500538a91dfbd6c64f06ceffc047b4d7033480178cc6de179a90c1eadb078e39de9e6333ab46741ff0358d784e49415c67321477e478604bf0125b34a9041e435af5762de4e63d090601c325969e75e58c6d0f8b970c20cb58a9578b6d899b5ce8e9d5e4fa8fd73a1dc3fcba9c0b2fb77de53280f63910582c8b695e78f0328f009b41dcd21681d8e636a5eb3941f9acb42da12ae61ef4e43863aa81b09579cab79540562338718a2f57216bfc3d14bbd3bc95da24afbe19cb2d4943489f434901798e0795c9e89885076981a8b047214b6218e6712707281746a20a9f9bc426da6d2f9c700a65e3a266c786464c84af1f4256c5f2e72a3ce1086d4bc0693a8d02c2d7a935a37fd8ab63faa2259384862386f7c44c7c317ae49f9084ae8a078764d932f886ebc93eb069ea7dc0f4c2989a19b9f8a5b15c4cca85fa03c4383c6c866676b25722dd298f37d161342390974ac3a1af89a1522ea82e3cc8d870fe4b4e9ec8b8792c2cb746303a038fd698ccb06f37f5f0c479a001b984deb048214a9a8dc354a8e0eea5f56c856a6f9d59e94249c8bc93016d149af9aac15e9288384fbe91a61860b3d24ab1651d5553d0f4bd51c2e9927cb9205441759f9ed911bf8654d2684bdc564f1344349d2bd557bef6d5b70a9a26fdbf908385b25296c0570f53adf52d49848c915d8cfd4183aa0e238de5d9130d8d2bd3158a24676d718751217679690f0dd6efe4e0777b1ae31ad1585fcbdabe78fb977959e81c87bf6a9871737ff13c619ff66bdbb058f702c117e01d30de85b089095dbb3de4d04dea4ca093c1dac104d1b5b6e7455c79bf1269de116e886a2f016b4e32f9a02b94e04fcaf3a8bd55e3f1fbffeee7966e562ec064ca644c41a2d67f17468622281efab470ba3b8c1a68f48cf82d5433ee58e8b4c0f2e9e26b81d5f251b42c45476e4ba40b50b48353ab0a459b00c608d46ba08e435c06a3cc83e06f6530e7e1ecfbad2fb781ab89331f06685799ed1c22ef16686efef6459b8ce2262d8281843857172eda7fc21f83e98bd6a021813eefdbddae5a8f5212d1a0bb6f77fdbec6bb686568992e3ed021689a716133d6962a49312c9bc10877b48b0f890bdcf496b57dad9d57b912c99e6808e35c234e0b688bbae356c45f535c80f178fefa19707a0e775143a9be5445e6469567faa4f92f9b1340d05d9c96c20119f51493c4c243322abf1f02a07a646a9ef82c4d75d7e9f2aa5f2c1b01d77eba8a3d314eb9d89a217c5018918a5acd5f040d9405f638ef58cf876516d7bd59a1b32eace7faa3000478dbc90e565e229e5e69c7a2ea118705ca1c03fc946250c5c57190f02dd259d5e2b81920a7e6a0725173877633ac4be4269fa7ef58f44af9a2c220d651e38c21cfaa9d43af6243b572114360d13831c4d0bfc5e70bc78a30f3dbe1cfb18e0ce06a539b83bd0b244852790e2ea9f6755dcb2f00f7b92b6cea704cb327c86a0c2be433e70ccb3c87e48e4cac5f3d71022d9c77556f3df6bedaa447c34d7a43f6eb202670e90ab2614659d113c76459b7180cd8439736b2902d68697bb899023d04031de6cde2ae622e8ad53579bae6dceb07841cf6263b0ce856524359f2255f542474bf3ef3a0efa516b31732e8668ee5e986696e944967d8c229ede95af0f2e285243174f0d7f786d341dde24559047960a773984e55663e9c80d3aad25f23d66334745940c87269160e663adc5a63c82835cafcb2d7f03eccc3f983b76b7688f637a33c8258dfd9f26d2ce63a9dfde2e9883a444729e5e57b5d95872171ab25f3ddb573e4ca905c0277b435e4abb899ca08d86c26e7390eac148e48f656dc04b8e51d71b355ab284436e67b248904163ca70f426c52c0568ee6e5bc33bcb343a5befcc6b09461b0781ec1a37531b021dbe120bf37499a88ff2914f1da630b5b159baf3c9661365a64cb855138ca2b889d35358dbc6f03207ba03d4310b1c9ba023d37408f521273deb2dc2c7e6c8ab1a66d927d66eb3882f0f0ef05328cafc2d40113ddd57336329a76ad6b6a919ba5e8ead973d0c7e361ea821a09487422e1169511b03c29a46769bc6dd5ba8c3ff8ecd05543022188a2d9bf5707f20735dd489a21f256399f45b32a13b651666c975bb492e71650b69825a78c783a7b21cc0c392b1efea4b3cf02c7589d4ba106b769003ac862860a1ac939380fd4610f895e0790e5e2de68bf5b648ce1638c78c81b29386207767f656212d0b2ea59b620388dec810ba1f296dc5da87da057f8e313d0450da11699ba8709a925119cb21ed85596569c0b1a518f648a1fa30ae906879338c6242cad4cdc8ad7d777083ea520c5c94b7e778e6131e2bda4e662a923f713a913121844bb0c6f74be59dfa533a3e93b08122a728e58ad70871eccfe1587448ffa946009f234575f570e2d00cbfb034d4d9b7633f285c8bff275be0b84ab764f506caea4e069f514ce35695d1b03d6003ac443bbfeda3dc89a72f10fff6a96304e984f3888babd72fab1d809c472a2f6d598cd0b3f1114277251468b442567563d2a69226385412f68f80eb609da1baaaa0600343376cc31386797af988b66e1b808a564584664fa4dc053772ade3946e43441c4b13403525a737492d7a5c7169385842e608cc66547fb0bc0f8fbf8177185c5ad446c2f1a21dfa9d43514d528f32ae85a2bdc101f59ef8db91855001069470b073743678b23ad8c3deb2b32b178e4f72e929a712c0741b8889842374640fc0adac86e67c37971544bbd9e5362d1cbb16b621954092b29ab296cb1b35220758c6c5803c15716da1e48ff5caf44e7467f357ed98396faa21888012466074856a47c16b27cb80bf95b017db16d85c4c0b94fa4ccccc0e9f2fe80fcb9225f31d2221a16440b90483e39ed8bd6bc95276f4d5c330ae749b248ac5aeab116282a82178d518571dc184888f2a1a8817847c25f0f206828a8e0c8db16b0a278fc39eccb9249fca051e8666bee105ce8cda88506845528162b1364085d51b007a8b4f1f26447390aba486cc61000d17c01d7298ccd3b37e9aa873a3ed0b76e2740a38300b179abaf9c23228599cf5aa2aac73c8cc3ae143db990c55acfcb1d1f384ab5d710b2464e4a1eb74dd8c7770659fbe50bd0540b270ead5c20bb136995e8cf9d9da15292e0d033072f7981001459dacdbaf63c0d9f82bca3b64a6a400647efdef67a4eb1d430cb613f00053a584a5941f4cb473999c05ee7e55e0f5d85adac6a4b88f7d7528593c82c8b76cf6657a5b7ae6a23904358d735e9610947d42ad8c6842c36575f1c7792c9e36b66a7529278355b105714a31afb210b3ac4e7783346219d45de23560c173d8907f6838d3fa52ee8f93510bfebb59880d1679a6e8cbea3bda388e57676fbcd4a8da8ba888a897621f758a02631a36041086844da64b73b8ee254856b87844e65f46382d4ab44fc8fee34356581cbb49d9b52e2d39dbaf653ddb1493e4a54c4812c575ea9db93663cb44cedea65ba72a9554bfc373e470ddca12d08366485f4f178ca10632aa3efae107346aaa897d7b2cdddec60d2918dff961c1cb93276c44d37630b612bb1baff0e586af6f184ebb2f399ac62ed8193674821fe1283428c3508a90cbad1baf9ef5dfd87d844c6f38d634108812712e39bc3c0b2418fb3979fc341750e5423b0650eb990314f652049a65320829b2290673f8aadf301e23de0e28688fc68b8170e7383f051441cab6d18e0d04a7bbb15d01d58cb1072965ced6d1b253666a79eb9d8c3ae058076884b88714891433d254e1b18fa14ee46c066cf036cc4340da24f0ae7e04870aa77e430f7c54c7a7895f5d8a34bfda28966423163a6fa5869506a08018bc673a0538dc3327267c8e68cdbfe88dd300cb0c071988557e52214138b0f479028adb66e44d20de7b7a2ffa6c2333b925a094bf2c965a443015c166713cd14515d168a085dd08c8d6048c03576b68ed5e368cb0c523b95afac2013856c9d69b234532ab050e9b5ea3cd93df2c51b26dc055b2aef8a885155895a9675a50a42534f40dd23a00cba9c42074f09b9b107fb45389aabd388b00e149035f81cfabee10f77b27b0973245d778b45f3c94f00c27a0e598791a73f448a270254308488c16000da4512c13bed0b59c571d048b09cd7c0125100c332a5d9672d810a2b3647cc0882aecc4ca8d0dd72294207e3753388e530e408c206ce053b4b754f0e68b856df8a4c894505f636457283bae13b3bf44c7ba6412a10bc52a468cd50b3f8ccd5c2bdae1863e0f71dc3dab48d51a4a4b682cc55eb82656662022ce23049297821381975d99f8b06653abb1282ba680619624eb97a7628e3de8e247170e4f59bb0fccb1f9c755430a06bd3f5af59ebc40cda1989998306ec2506b15cdbb6bdbc77e9988b728b01aad31200b9006ba0c5dc52678fa215b84156cdc5e00833ab47b40a0a479cf1834e5293f4b6c88913b39405f3a11b468504241a7108fc794bcdeb9e5443b4284e4523ad0f8cdeb72ac36e83392f225e9c486c6b5f73b3b49777f9549da1b273e1ea6dcda91814858ff8af98bcfb2a5ea9e3d7728e00df2a767cc40143f3443910cef1b358dd7d63b07ad767ef2b1463a5cec97e1db30c9301638b76794baf024e34aedf9a0018b464b40318e182ee2d0c753539425b5cbc17572aca33b8232850a6a108c609c15f38f10ea9085f90f32df538797542c6bb786b95aa39008dfe3a68273f997d12af8188fc670e819c8129cbff5a153a283dacdc2546f1034c3e1cb1ceed704815c1518e0a171f0a77f410636bb8afc1cad1efac7d38f1ee018a6ce79553e70c8c487e26c4b7f4aafc0594963a202adbe9fee65f1a070fce4ab463a7ec2e0c200a020f30a1bde69d755da863d990814eac658e6d4f13f45847eee989894ba622c423095bb32c49f6a389fdd15f0b78277d39873b8ef18f252f33140f1c5f2dafcb9f8e6800c6dfedf40fe6a59d5d0fcfb163827bcbc2f69194d4c589ca4d29e1675dda36a471d1ab1c56e731218fcadcaf60757bed61d80c18c445a640bc25f6cd3d43cdac0d8058734ea5e49d54caab4e0d8d87ac775d475911b1b2a1c633663bc34558fcba56885f88934dee716edc828cdfc3b5b43d3f8e3931e6eef482fa08571390984e8e0445dd13524c29a2d896768592b1191ac96b90a6c583d2ad34e37f507546e4b8ab997a30c4bb62fd23e64843dcd881f269dc5045d5e0e41366e37d349fd74c116e6339d5f0bcec2d4996a3213a424867bef53e1ad44b3b6da050026b339013534956ead9f5aa066166beefa09b8d289fe1245965af42b956e60f15a8165d0cf1b57aa77b85b50ac2419ca04a3c812ea82bea210804ee8bba2de5b0396a51c5100e9afef1a09757d93a08f8a6a3f005d4845afe690e6dab742f946a50856de390eb2ea2d1c552f4c35a2d6dfb618c7a5998bfeaceeb6639174024c4899a4f1a28cd00048813ea43dd41eeafc3f8ce22e899e49040908651444e669db02bb14fa77267089759921e49e81550a548e0f8bbc6019b0f70520e83076280ad647902492ee9d0b491926104ec6be484f3a991845aa43ef343738bdec67af2090f02425f5aab1c2909891f801c086e4df6eb45876d755c78a36fb88ae0cef2c824c2397a4ada1b5d979a0baa3c7720aa4414a67f84a3aff413f0545056be52dfe9b44f1d038e01c72ee0d29ed3b6a4efb71575e40d37bdc1034d6fd59b9fdf266d107e400de6ee0def8bb2c57bc3b093befb50b2f8d8871479ca9706631ca0ee0ecef051b6610890a1198f43c3c85b904328ab20b1ca4861361958abfe084c16876972a235a4305d9d95a55e9d1595f5438bebf1e812662dd3fe4f5cd4c7dabf1ed40500158d8a785b86963f436e1bf1345a98f68817e6aea52e936f0034c1641c06f1341854e16f64bb8de11b793860f634d32449df063816d73ce00c701ed77c21031c2bcad73a137723d37c04787470082f3b85d75b8fd77f4c5156ed23bed0b6a596d3deecff5ff4fd5c905ab29fe0a0954a041f4b1e2d77e4da2ab5e89c51aab7bbc9acb1a80ddebc46a0773b4e975cbcc249cee036036bbf2f9001bd534c1063cde71d8cf98a8e8cc12223a64dbb17370dc5aa720a2e409fef77197f38d752d71500921a6e386b0318e9ec46a0282bfb0e47fc54a8f1feb7ca2b74f88ca1ae5ed3de634b87af6965d80ce4f70d5a6a9ca04765e90cd5b79265303cb9adf64508f00ea576bdd7c141b2b6c5388047bcc610c77cd30ff3865274331e367a938cef43a8b3293b490cea0f111b78ca52e8c73afb57c895d54a527822249107a346f6ae2d3aaa7e121e88e839d9d07942c6a3082e0411434c473f4e98ce2323658a5f16e6ea306b741fef66c755d0786d1e892537cb565871b08ecffd5d7152ae989517ea456829bde74eb8ed0c375fc36fe384c33444e44f371cd8fe6bc0b2848e212d013bcc584157935cfec77c1b343439e3f341ba49e785b4d132bfbadfcd06e488a35479f44a67433776ee4c4c609db286ab8a4c223bc43f57a09d5ca89c0c951bc1f68fb3c5b1afa0265a4a4b5a6600334d1d212bf7da4330cada9877d170e179da647c6913428b88a09c54c6590070afc595d20248c8ad356c9152da0b0e378c6b2818c677f9c40b023d8a2b3a3165f5393393d8bcf56a202a56e84da1230344b74e17797f0b9187c57155e4f7fe787b2ade2a7080de1e8e107cc48f43dba5486c9bf215d4bc6bef1bf42806e356e78a3608986606d39eaa6d2b46baec69b81981813f6b8a6558a089131677df99c39f7dab38fc50fbd4db2415e151f8081662bddace975be16201e7135b068b3462d90f1b2ea238f591e1c02628c00e4f555938dd6f17c11d763e743959de67e212dd822580f6167e043eb747f75ef4a28782ec757c2ed1e8d45f4fcdaaa1f066d173cd5ec5e54c04d2f86e1515f1dd33ae90975d9429b88e614f7a3b8921a7371c5abb1b182b1b71636635a6a785a92903e6977d45628ab9b83f791d7d2926e9266e1d153dee9dace2a51eae2b8a11ca27501b6289182c004cb4efe638b5fd743b657842b5cf6013012c957c65291fb29daf2c3653d33326412baf703060f049ddfde0800441ae7ba1f3f2af976227938436288bb38ad7d6b30f5a928559c3012c8b6c5e880e90d625ec95256a81f42ac496b82530781442b9fdf3a1d44605d0157bb188d1c796f2419ea9b3a072b0463448ed81a7ca51e6cf12c2b75d8f03eab2ef507c834299c45d22b789fcaceb9d25a98837183d6388ae0e8318f2c6c411443959dc525560f6566dcae2e6630ba3d1b712bd20e57c8c4a334e596cb0bda22d20c0c5ca4a78163fc57a0dfaf6757558e3adcf3fcec82c9ec407714860370cb3226ae88edcff94d1ba9110343f32b9ca603066334e3fa6083fd4a8534fece09f3e2cffbad73c37e83f3e54fe7aafc5a6e048fbbe8eed9ee7703d87ae22ace83bf7a04ff1e9a1ca4c38e655a5a7f526aae6507f5bcf0a871bf4d17fd291772ea2280c066cef9426b2dd1cfb77a4b024e0e401969c5e871a5c2ec117808294f3957fb9599e4aff80057f162d0766cc967aa0d528fc923fe41c399e7b354aea0625aefb53c17e0f54c452c1ca7d8acc184e6ea40457a7c362184fefbeb997b3dc291327e9d02c37a53c5c89364523198ca33b7b490fa29d323ebf0e8c4023125b4fb03c8337669c0d6e0b58c4e6f7cdf3e8a208674ab9e2c996d6abda27b8121fb3ddf0b304e93e636f13b455e611b88434410b6d10f75aed4ee38efcd0ed9554f7a586be78168347bf5e29bc155030d09f8dc931416fb3a091207802ddb626347d420fdedc25806c6486011d31e94c317d2e63a440c85241fe6450d791d90541cae1dab32a50970223778f9223f1d21da63b582244877b56516915791ea368fa319deaeae284d5049b33177b2e70a8ea87a6982dfa86a266589ba22cb240abc222f1d3b54de5f76167a5116f3cbe472f9a3f19bfaa08f422814f9a8c99ebb41c9103c5ef706cf09960ecb138386985634878924ae6f515ce55cd03a5d844ab2108298c9acfb23dfbe05c3fbc316237a5894730b947cf4430f3ad6e7e6da67014715d7b27d41a3cd0b259226003263aacbba144aecb5a8ac5348cc30aa38ac85d6860e214153740ad43ad4682ba22a074a8187f8eebc0aa3fb1832a774c79b6fec5e16755ed0a8456e871b90408b48ac5460c5b9d3835cc9cb009ca320b562e3aadbee0ef1f0fff43dfe200fba3839fb4f0a4ac6dbb90a2cdc1fa91d277aa0002c7dae70fb5e42322ffd3f1270bc8bc2d05e53e4b80b59056dfc20db121c602471f6cc301b98587abe28cd8d4050dfca770bc133d63585bcc5eeeb39c2e816e35d0c0882e7d874b8490be6620c9114889d254f4ea18d2a7d4b033bbfc8ccc9bef13020bbe7d46a4089eac6e32b4085e27bb3398e4546165b7c69b38a2083ff414732c4d4f310f92b8491a6ff1082d0bd1a48f11a3465fae90d7cc65f722c742f2147593a50ea7e6c15e45c0c1d925c133e05410e42d9e6aa9dcce0eaebde775b8f0180315c14008efe00a0df08ad4cd35ae5c90d327f83ccdc32eada8e34cdd4bf323b65ed7cda416367e7aa29b0cb556f36ab7abcbdca556c8010d9d4ac4eb39934459aec424e97b2bbeeab24ea65fe54aa9f6f40bc9c2e6986da943b03766b1114ece46903e04146abd9d3c5b8f412c11b0a9fdc53c2bafee353596c5fc56d8ceb11706bc40e0d6043fb204793dc41cc596b56e4e336c524c1b5bc98f5b6df98a3a0ac872b59f0e6141b1a9e198954d6adea1f25614646e54e117041b84eb4b51d32f35e37e3f44765de538340608cb83035b0ad800b0881c11af6d254f7c52b83ac450af2703de1b59d67d02af83657617375f230424011cf4462beb209c8efdfd647b7f3eb453df84e17ea930a4201ccc19dc6c761a9510af8ca42c686ec0a115db810409e4c94bbfe9e95e0464cd350ed80f75a7ddf8680f0052286380fe164faffddbe925d0520e4ea5599339ba63a8422a575638663e48b4655933a96e06481d1ac706c45c8d3bef1cba63035bf4ce5f0be620fa8722056cb6b4a4e4cf59e210b4d9b8fb3929c159b2e5c503f73487fe1cb12a50d417e58a146a7ce9dca636ee0a96b340835cfc98f32b681e1c25d79735a7755e335cfed912b3e608c28ec71a1010c4a985f103bd6a600b52778819808376d5e1edef917a830d043eff7eb8b2e3ea2e10713e88988a90bfb4bc53bee22cc50d70df99daf79550d8fc35fa259cf31d4df82cf1d01db105cc179a8a4e8bbfcd8cb7dc03ec2ba9a751e78699286588d99423913581015d4068f951acd82e5e9e2d3fc9a6844bb454751ebd166c1c12b53661b7c2dabd1256f8d470e43b51fbe051448cc68caf8f1ba3020b3d8b6c1085807d75cc102b6864100ca0876fd27c8e15ff86f657a488ba6f54918ce595fe66c17953a6200921893cb99eff7f5af9b5f565a3ebd5fb2299c0e7c21d817c60829b7f8659e55fc45ac150068f2f89cebbecd48ddf4df2fc965e7874d88f776a0a95207403494218180870e2c364691e7aaaca82a20232dcc085e85ed7069b02916a948bd0bd6f951f1de0679fac1e3ed3002423e50b9cc699d0e11e405cf1708488b820e71a0f59290f1c85d846f32806227820a196032662dcd3259e950df0fef4b9e9346cd73d313062c4a5b2bd57c2fd8f3fed7d99240e4f937999a3c0eacdf6b9016380cd02f5b2d671fc1423d80c843a599a201054a2b663be0e6cf705ef8cdf03038b60ff4643dbe32cd7eb5e7ce3663aba6ae405be178791ad367be6dad0dc45b99c2c6ef5ddaef611852aee2a1ce609a5d12be607531ee4fe86f3c4968776c4f2cacb22a8d4953d9c41e686b417f1814a63b2b01e717f05b0b4347aacaed750d87197fdaaabc1798b0a610881f991c29a68c3c0a88cd2c9d10b404652c3bc5561f893c82c7aa35b14b14e92f30465c13ca2e0cb0e9a32816a78cbeea436a5955d4215c220b6349d784cf87e71aecba40299c0b5ee7ed36eb1532138d7a9d0616a8a2c14458042e1c25103284af69486728465d92eef01a48acc827c5da9df7a72346d498274c7efcc73c4b95f6e11e3100ffc26abfa850e4c412a9b94b7ef16242b82e344698df0dd2899888df07d21bdf65c422e7b9a8d25ad71cdda5b0b281d073a331b035109b2c96ed8b116819249e9417fa436a933b99a395236226e309b99b3a13988c923886a2d10afe18b9b7ac03d12c5ea097850c2a4c9b0f44c0b8b1f0fee6ed13744ca2b8b9cfbd9c87e7e8c21c51396b47365ac75554ae9df2096ec9fc41a52b1cac23622ad6f6262e090a01551b31ff5b0900169f6e2d2a3e73079153f401da597b02e5cd900a945411ea595180a6eb5a264fb5b14fe0556a402eec283e3bd650e502e085c254cc386bf79ec18d7f4afd616d7f0eaad1fc21a9846dbc92c195e5819da9166b6f3a513e8f21c50523620a0c9f738b323d23424eb6526aa259f1a8d03967c6d2688f4c655a0afb0b4e94049f551ec3df8cd6bc9e687493014290247daf4215e0937be1bab8896e1a37e24ae0bf1ae5cdf3c4c34b44e62e2c5be1332e56088a213137712d6ac805f8e4f1ca65a1234bf1cab78a62829e87e38ae384d570668fd384e719ab41c687c74bc6234b54cd0fb625cc5346599a0fa6d1c626ada1241dbaf4a2a56457298bffbc43d063a3990a980452153707e0f84624438824cddf77c66cbd3372c486db2f16b345ad10dca1d6fe0154f001eb0e83bb1f3f55de592a05f2ba62502740d966c7d89a64ec862f0b68e1960a8a8ab0cbef3f4cbd23bc296200d4fbe5527f318376117c11edcbe82324180aa30f072a127d01aca40775d77dc17aad0409bc1fa1dc735793622a1d6c21820d3e2e86acbd03625a35a601c554807a161c6833c5b2a3eee02bf8b16509d3f2186936163971a48a85202ead72148ffb69003740f71a1c15e5b9ba66299b558524d5429c823d1845f263a19d4a44c8b6b6344760e8b35d3346f6c9b26f2f2e29ef9b50b661fe22382a61af7bfdbe5623ac9dcf71e7c2d08654741125ffbdc83639523587cc27366f477bd334e2596e7b486ec0417ca43d953fe18b7a8d9e13b1c428634034ac57464cc699f3adc1fbd9645a7dd2d61269e9a05df6640a218d09d449109dd6a8c4c76823f2303387196bcd53aa4b434c9e9709152864bf6a0efd3f71a7090d811e0963e5b262071171bc1b93640ed2c6e847c49f2d20767f6cb3fced8a815e3ec7d6b2dafb83f7c29125b6cb2c680302bbabd2076cdeb5ef428d5991f91f61975b8d29cdbcedc9ae14793a90a35c74be952b134a6103411f8bb38cad6c58b4ffbdca3004b6f3c6693d54cadb92bc0b14d58aba5c0b50e40aca10e878171c8bab09a0791f69efd6c8de118fa29e5c64b4a322e0bda3a5e5f4e11344fb3ec500738eba6842e00d133aaf72a418f5ecb08604a8778d1ea22483096cf2df6af372785daa220cb7848b132ac2edd96b3780feeac0961f42371487cdd12831bec53f527ce34fb30de7890c43f425b4e0bd13e510a2efe8e9dd7a380296d55c65d9955cbafcabd7bf49148b5a74d24e500c757e9a930dae31efb8b2d312ea851174240ae5d0d50c812017699c41f33b86e468f9f69b51ae31e892252515b39d57c67df510cc2f06708d001b803c3d717d945c7923b941d8b4e3b3dd9a484183d6df4efa7c7f5fa51c5857609f646c7d9b8fb12c64b33a21f83d7a94a0e4a36550ea194d8ecacc09a8de30c556c1f303a4867d83cc4ff3c1e20a206ec8e9d2edc5708c1a647c2bdad13cdf6c740f4b03f803d1a87c430f278a20fdaa741d0b6fe14d0f4d3e06ee6e6b3d3dc44b7834f8cbe3cfa9f90acc93ba1bba0e98d5f7a47ca9d36723466ad71f0db00030440b4b642e19094f44cd1222a0caab1a1983a3b622c780861234db6c612f4fdd24d651d52ff527eab5e49f8a784bedc5bc276fe2fbb3006bad604a04f2486882eb97a0900c697dc0fc5d2e47fdc23d5fc1fffda1b6f655f116df35162272d8781ae26604f8085f1d1391e520ecefb182cfcf0113271c86f46220dce4c35b8dc329665b7ac7f185d281adbb9e911f26028d616db1d722218dce5429d14205e1e5cb650828de6b91f0498edf7eac04515219cda945994271846c40524d86f03fb2b90a60056a1acb501b95acbf50e14e87608b130af4bafe002cb1dcbd11177fe120a1d656cd73310fbc9cd0611a161bc8816b083acca116ad00c91d0243834c6c047399760a106b8bffe9ba51be9d606a176288ff4021216a09bfe7584f09d496f254e0a5fa818d6d9af05aaa28090d69dc64b4fee4bf9532e694ef0333465620c97cf3a999b57897b747da677b7c4542a617fb256291636defde8c27c0df21ae823cec230ce8b4232411890cbf2a8d005ffa7fe17617bb560fc0287647b59dac1cc67d3a4876fe579a8ab29afb833a7bc28e341cbf4eaea54d1aa54b4d1026b4f02037be8c7f1700562f1369c259b060eacf32f912aae18fcaee4d250cb67c5ac336fbaea4df852ca4ea15b5bc0a0eab2431c441d17f29fa9ea526a10c970b68eac5cf38e1c86f6ca0996e04350394cce0cda4c89c00fe0a9515803d718459a4c31e6a44f904ca93925c43177faca79726002b94c30779ae0f37e9d3a1c7273081e982259393012b723902015be8fd6535a21c44986e2632c18ccacdb6d7ff9983d305c6356e139356d02a6020abb8f182de61363304ed550b6006aec3b76b4df9ce522c13a5e8df9f239a0b1db4b033bc2d68d9cba249284700e746bec33a96aaf03424102ead8f41dea713885742a6c16923c0c0b95ecfb0a0c1585dddc70fc0a78690d9adcfb2b3773affe99c8e6f405796c161804bee72a3a799ec03fa9a5779a17993ceca92c2da76851e8c458e58dd403b9a344b35adb724252bb74280b11310f98033175bf68d393525702acd45582944bbd94425b95f1b71be44d4def999f10f9f6e756024fd54612418ba99f9f124188f949c1940762126f0287f8502bce793ec1b36f6f900a169cba52286686ef8c9e2c071d2db18ad088bdd2d9d7e3ce0f160bea0013d4afad8e2fb5821d91634e20be39ab459f4d3d1ffcd02c7d1a7b117107068f06008f837c28a80b5d4ecee2984cb016454f8abf6d876e7173170593a51fc41f8f4dab5f2ea63e0fe306479a53bba2c02412c20945ef547180a3ba4f1bb0d7ca64767e871b3d520a6ce09c545019512485b22b6d60e855845273b01f0fff47d4258bdd11f56b1ac41f109efdf87b9f2cd6f9bb02ac4b0787fac5ca8a76e2f034538cfd3a9dd3123ae0673a43c94759d574c0eb1238600990d02b0254f445b6a0abe4a71c18dac08f388a498f1cbb02284ac88b837425e714052b6d8d491e3590fae72c5e60a2936b3829b14bc4766a8a7e2a49cca104e1877a1e12bd4050f0b930abe5cd9dbda9a0a347909b7a144ae814e9eb69622a3eb2012f6087d88f6ea9bc267d7f7ec09a9e685d58151ef63b1591095ab61f990beb52d671ae97b270687a7852a040fc29d80bc3db1d0db508eb6cd3d9e6b0b3b1e10cadbedbb360d3de100609045afa296c3680634cc50fa5a46e7755cab35a40c334ce92204c5340172fd39f59363a4226e4db9ddc2383ebd1df1a0690cbe6904bd8460872cae9c43dafe65f9a0fb601f9a88c4c9090ab49bc11e4d519e1044f5e6092bc00db3c07e2ec30a721a2405e3fc1dbed214ddbb5bb51cc3428d7870f847c6cac405bf4bf3acea871213bc2de52c8f87fc437cd168c614b121489d45bfb03c454915ceab953a5a335baac00486743edff772be7f1ca14985a544cab720007fbd485b7a7b65b3e0a705f2477b26efc1845e355b460fadffc8558660ac8871d217bf3d13276a6302c078989ed599d79e033ab58a137dcb7f48437d24d3d5c3dd9d0e134a5423b865af6605d346218913c998c3317fb8d423d073cce33eb261b1b24ab9297a4cc03a459e8fb874ef31e5010b4241db2a1444071e98c00c465f04c52b9cef0818a14ad5cb029f22b57597688c185452b97a2abd204bb276b6c4035a6a772e5a4b0811c1607ce35a6209b153e70c05505100858b9aade4858958b578b8d3d0c28d56535b9c0d1be36cbe6ffdc3ac5a7c38cf2cb50899d86888db7b08b1317e1bf1888bb8256247858f6c483a20445110e6ce571ecd0f5ea9dc8f83d2e7b28cd95816ed3811d5173aebeb3194158216c43439b8b02c493b50e06ad3c88d0d50409b102eecb596409e71fc2776addc2f9c3491d9312e28465530ec4e89023b69f1d2ce783770c70e03e3f064f1215b510e4ad2fe40de165426715aea9107d9d62a8ce849c7f33fb67b337173590ce30802153f37345a4ddd420482689dfc4b7693463f01829f800e4f7e1d546b2d70c9895cdca0e559bb0175fa11a390741546a84398921a14935640de794d449ae8ed1773b5486d69ff07627547d13aae166d634a0b8bf7046feccfe610054829991a5147c96722558d7dac58b562d2323600ba5b1ac6d750562b70e512a14ef0082de3086f2be05ee83a03ea3799fd0bcd5cfb08580eacf2d41f14f45a8468d84554764eaeb6c00732c0ac30973d00d8880538305cdfca16b1d44b32cc3a1440863283dd75e158d829d32e721a8872baa0229ede57d5644f8f5eb087dbf4b09cf06d85db823b435daa94e4604695f2c8e78348d2d32db8d14527ca4abca053dd1c009345bcdfd1cf41461232193a384afca6f281364a790fdef0f26e29dc3af8eef86cc5af382e936f29115f7f5d43682937a95be952b9811f43ad847b03d68ebec82a70cd31943e06071442dcd9819cc828f1ad59a59f6300adc219da30399d5a3668fa8b56c7498212d4e6bc6e57b4ec2dc516219ab0e6c3d091100bda00b2c8b6843bc1afbd8b6ce8c1b5ba296c33a3c1afadefcaac2fce1dbc87275068fc2d18beb33042c185a1e6278fba275d732f202ab3a969a2abc20ae61ab1c772f9996d4c0d097a37fb2487746ccfff1f9100cf201dcdf46ac6a50a0511b2da2a83afbf68fd801e752b2ee63e17c5fdee799ddd47692f1084be4913c8012fd110c7066284ae0b8bfa38672d6513912236aafadd1f14626ef2eca227d27de17c17ab44046dcb83f82f6ea11c6dd159a0dab4c8293f108b0470f41d188711bfbc1ae9c6b49dbc31724ff84f56b7bf6c0d6c57f1ad8da249333d063bf211ee061006b540250ac19881fc0a9944f0304a1a7d4d87fc9b6ef7159af517157c8e031f34a7608a41f942372f3f8a5ded7783c324944dc4734111debc4389951ac63717256daa36e996f58ee6d78848ff302b7e1a376d514ec32d62bc8df791651052f30ced8034601acd6f87f108576ce08ff9620cf3073411f85ac71156592e7a326af424c8d7c9d2b572f4b945087168213367ef893f98a3871f2854958038517540e15ed0737917c04e16b05d8177118301187b77106c8afc7f883294a20c606af2aa10a90560485f7671dd1966f47e1f937f14baa249e2c722540804fe170cd308ea7e0e919bfbb82e7d3a481ae1d695260206249f8b8bbeb2a60b57575cf45f3fb075983cdf78f2d0a8d233a51d901ae66217b39fe23ca4abf6e06923ce3e8d99433ee2a51d25234c6d9c9ea07fcf09a1ac51b0c43d29076190d86b3b215c40241892c6f47949510e29574a93754c43cde07291df8d0bc7dd80f43e3b5491f475a0ac54745eaf9c07b44f01a5f65b9b09f1a9f4204a6a59aabba31762665034591a52e3556c220096f5c6eccabbec0d1bda685aa9a2b886310e9cb01142474e4ee66c13338cbef19dd9e847a83510fd79aaa70861f2253e92a79f336691a4535097b34c086709ba55c9ac71e36c12942868630ea7e04689e755d8488c8426b9f3c22826b542921562836647b842450abd5b4172e50880135f3484342f1ae0d04caa668ecccb530246588534de22c08f29f01dc7d75e382a0f95fac495a10a466d3a5463f6b11a38fc1b2df6e880ae612e2f6171976753d40979569dd59e8567fb7cc088a0760476510f6a9aff2240ff517b0f376d7aa700dd5ef2f595c5022e49c560e9432fa5e735a9b7a49c921a5d19f18a7fb92ee6f409b17302474c0915d317c35e5a92b28e6b08954596c934d37281302d002757e82eef9569301daa24c122b7bfefac37c63b7a0094f5aa7a9de4134f6df4e68a936be7be24ae80ca14d9293edc2fd7803591dc93f70f4f6e058dfdce6b0be046971ea698531f4aeb22a9db0b07dde21f87178649bbc94b27538ce71ef0323a3b08bf911542e8ef7b15551f50369014abaf2a041afe52280f5f4d8af249bcc881b2cd118e6d428a04f018b2728e46fb20425fcd519b4b15ac6cfc40959cde40a9a754fa1e7bfdbd3c5a96b3dfcd221748d600f985e206f39aa77c3e727f9332995f28a2a15694b06a96861b0588001cc05746e7f702f64e7566f410f752ac248f0bfee51866c29b0646e02ddcf9b94ebc8163704090c8db227df379470dc112e77cec6f79416c67c02a85813a2ae74a103ee21672c5de02dd42a96a16b541aa8f205fb233ff2e31f3157400c897c7045e880a350e0f1d55af96be7ec38942a50bab5a018c81aaca6f7a2c4f82e34406d78ddf200cda9287155ea2c7412c354b351de6edb4a7f3a2467fe2cc8a6101fa5489ef2fe75f760fc2f8d38b42c858a0d9aa8d6fa92921b8cd38fe69bb8a6412bd71b8e7f1445bcf43d07b47baf274a89f6cdfac7396ecb3878a50cd27e303f5bd071b8d457f66f5cc5b1dee317f10b0092615e056083e715fd66f95b3f667348d2cf0098d895197d06d0d43715288814c5ce9dfdcf9b10e38032c7afd3334363721aec620d0f81a68ff3dd436fb9afab18f2e24044fc85479b56aa0357ad09104a689a3bc62193b5bb8ffea513181df61505cccecc0f9cb0a19b9d541ca3865bf718135f367e98c89455001a64f29dc5f0f252ae3693182fd83f5a2423f71655d292fe41fa2649130070126dd52ae6165eaed060e21684efa0a9a80cbc58d444b28b5b9e4391d83ac7f0050fe8519ab0a8c07480219019470281b153304aa14811afdfb3e4cf7eedd04a1b86feb45e8b3dd6acc5d0058de963bf22ff496c98005dd2ce5119712ff4dbf7020c26cf65059f16e6018487dab49810406baacd59711dfcb323b5be27ac0ed3e9435660d08a99d20558c6eb4d22dd519c52c9ced7e97b878cdeec08445cfa7110f6b489023514850201b500ed5f240ae20630d50010034dc588ce2e319ac257ac8a5631a9b39227d62b6091573e15ff200463da1a8ec5e0e27a5c4cb45f7f4eafa2011c7edd73f370eea29e30d3d5d9de073aa7ad5bb46f6a4885f45fff5b368fce93ff455126a6f89b515a9063ba87ac89be822095b117d974c60912d00c32572776e01e207408e2d3a4f9bd65d4652e6082af883a819549a668411ce521d058680f7ad556fb026ced79c9f0f0dd11e55458e69adadfd45168ad2ddcc4ffc474c6a26c28aae0f8c8d9f4886935179d748aee41f0f9fc2135f141046d12c8b9acc94b9a43c0471c0fdf867d7c938c99552d850790a02e5799e1ab006796456ed76ad7ad7fb47b025cf35035b7f71acb45d2863d77c116d8b85a1a6bfd88ace8a915ada157f4fece161f427dba417c823ce3c665512a3a8413270efe7ce60923d3c7007a1fcf2f61740ed6503152a7305b87a93ccfdb4a42aa8295c9a1e9f82716cf93c0e072660149de84ba5f684a83dc82cbd3368b32b4193f8a96967683e23d93d49764d54293696065530fa88b1d2a55e06aea1cb46b4a15f27efede0214d4b7c49e04b11eb5187587991dfd0b8cd37b0b427050dc7fd2a9cc42a4d577a283d86d0aeb9509b29fa21d13ea16805e612d90761f18e9592a225a6e1884e0772a69026185508bf2abbd6529a7adbbebf6b6596f9301da80a82fcee7dfcf25e8bbc504a3a818375528ae538841d3d660175bd413f8fb899b1866d8b7220993c85324f73c16343aa997f13bdfefee1e295f178b76c9a11606217af34fcbde34826d5d227028d9982808b8b7a2088959adca01458b125f10ff37d102e802f76e45da6a60b9670770a350dba820ba846e186c7d0cf44ea1233d1a12fe92c592842b66c86caa9717f7e14715f4993b707b1a4a414fe3f9547f2a109c47fb28c9beed0e62dc7e900f49f1d5e641e0b207038b3f144126003a871302ec644c3bfdc1149b80cd668013b644788651504de6e81afc55c4a22c96c3f67ab8c6b24cac09c30e734250391987556a927cc16d4f72f2f0d25e7d5f8c7185c5951eb524331f146afb17747a365d70e5960f6df5f38640f11facafecd0d7c78d43682bfc405ac6a4c5ebcd5a1ff187a4d06253ec2b20ab3c9ba9014a0d0d8e4c243d8574a362c2f0de3194b969fc4c633e1b46857a2302fae1b70f471d3a4b90763ce3b689ca301846dfb3c4c160c1bb811a0d10fd9d0d8c3571ca1b4f915ca0d85aea89f6e279eba44f54e853bfb001311f88ba0e475d5dd86d4aa4c61e54eb8b7010c6d75791f7084df892c487cc1af74b408b9000ea5494125e7b31af2a6e9827ee5aa74408bc3131da72b25d15730d0caf2935e709fce2b02d20e44e8c83627864b69cfb302bd405a02677980c2c8fb234c3cf560f42d4126207a5cbc22c2efd82ca7078a387b14d15c9470a1298455e5e9bb0235f908cf95454ea1360131e581bad35fd139f26022560cc9ddbee743fec0793694745a335614083c0a51a3f2a96549a528829367dd8d295c0dae1f407599b4587c70a9b8a71c3eb3c2c1cbd5930456eef0097536fda652d8a957f6aa32ff9816068ab813120a5b505fc8496c6488eb50a64cbe825db50184bb0fb417298399fca47e2ad5de39919a926b2636004acccac2a4d908e328d997ab2617999cafde73cf7f95243fe21b9ee5384a8444053cbb8ba5eab5181d97b9fa5eb17ed561d56dece9d21b426dbe050f40d1d780cf61c2d90148be57f66f9ad5daff84e031f8237ece69c5d44a0f5a589b06b478f7dba3a34e5e9c7642742dff3f3467df0d3efed10549d1bd8a37769ccacc173ff665cc1379dc36eade015f91f8dd1c21cae0e9dd3648509a319acc0cc8ef07df7fb5eee20ddda0bd5a94f5659bd14489666d6d713d44b996e8304011a7ff38712c4d0a81b529b241f65462ea4292645238b9391848647a9d34726eb7162c10ba2a10690030f80bc963e57113423129f3e8cf825508d62c39be4bbde6610781cb2fe689982e5ce0419d35eca0bef6fc466187015bb03327ff82eedb14c59fbcced7e7291046b097596d24842357e376e66737158a4083ca3783e255fbd0f6869099cfe8f3728f17bab1d0de81d717619324e7aee583e96f0adb92baf3c9577edd67a880232013ecc6acf581c74c8a4e46767f4d707d448afd5068494cf6334ab190692716ce863168707f3c0c1db0027a57d100f348fad9f3519bb6a82d6e6633ccd2d44716d2950d2d5cbc89836216e52e9f0df1b2f2307043f082e38636e3c8c77cebf782169b44092a98488b0971465344a4a72a107ecd7b93718fea92938ca4510baff33c6fbb5242cc1dcce58d6d81eee0904fdb51df2eb05685580c6bc8a6321e51213238b85a9cde98b191f04a7a462817a49297e08266199e18d45886fa58699c86f152c1fe8a1615dd1aa29c129dc882316ea4adf63df567c9af7f01f2f1b3be61892d4befd564a0d03cc81bbc39bbc518380dca488a20072a14c06bff7f1d86b41d3d98cfc8a981b0508106229489e00f95e5314a0016f2a3fabb862a612dd704d89b89eb91225bac4441d8d81fed40eb0353e5d642cb7e8924743385a427bc0332208493cde558ff72adcf44d585171204a5ebd8b82291adc0109354e351c0d6938868e6092e205fb10b3660d0648c926b8f47fff486cf10e667d1142a30ff4cbc4e8e7fa5a912830bc1948103a01611032843059b47cb0e04aa7525d0eade983375847eb36fa84f9f6a1d215113a059afbc578261a8cd0f751858065ca72443fa3be6011cdce0a0399d1c280861c7100e02764d2eb902037834bb939f856476332e0d66e6ff12c607c7a58947ec6e1d04443734856e03985294f1c4ffecca0d3ab9124e111963cee9452d12312d1f60d70755ae00822b9c6e9ef0503b1c10d37d3033c9ef67b5fa10a17ce5cfafeda74fe5321cbf8c7b69b597689a58c8c5f43636c682e48870fc6124e525dc82f8fe20aa827520bff1f137b8bec7ed17b149a10ffba9f90858ddc52dcd4f8e9365119fd3396e9942f5f4a838a7b67c66360df00b8db0e81832d2284011dac8837c5351312a2ed50e360543ee646beb4448eb7b1ff2becc767eb7dd498fcfd1f52b8a8ea24bde99c3421646b5ced19a706a6b9b96dc7df7bb54c08a2de5f0fe0a9a5b8f56bde3d8d2a750220941e3164ee73f2800bbd2dbf0f56a30fa5590f08e6ca1564e4bf37c615e6f03b44d6de4728e91f52953018d05e1a8924720d1b4bbe3c618d743a9560608ba9c286ca53f874ed46691db5af2dd5379e0019dff111003d65afed41b04abb5fe9c0205b016a5a3f4708c31a09230212823f8d6cf176def298c1c94f9f0125232d33e3c84366d049da31ce356cc5a488b44f8f48bc6f48f0251a63444c538e23923608c48ae8b7b5c5127b945012ba82ffff3f02873ca5be48e13c6a144e9c9f3abdd5df60fc66c09e069b57757e47ed1b9ec3a9b3e988d9e02bf58eb886fec2ffc9833961a42bda58fd841f278ca05a3784e879237e0e6b9aa02704f8087abf48288e4fb1bec129a85f3d5614ae0657204cda076f217cf74a0a63f75ed7cd57d659d96f086aa198d244b0f58b952adc3a82058e248f6861a64a82745545b8fda98689ae7f75b226c7ad950060b3ecaa7c79a9a1b6ceb72935320ec6fc57445780b0dabd2f9ee7100513d5b42d3ad4e83cdb6d3194984aef9921e4338d31ba212d387d68fc8902a7abf5cb3e06a21bd62872e6609f813d0d7ee6422378b116c6278ada452ec6d52823025d40f77d1ea6765d3fab536bd331aa819b75453df5121643a5f12d0a76f44ed746f57f5e966b2c097c836c971bf808a6841c6c49d88356d341f8b1cf8dee02dcb4ece4a81c5fa1a9411e59c76c9027da29711197317833cdd22096ff196c07184381a4c1a2ca6f1ebf393dcadd8ccd62baaa55633c43f6d195c8b5d9d6595150244e9dba15829ef4754f79af4ca99264b75f9bc09ee31377f5b1d51fb6ee5c25f3da829f3de4702c7ac9ecf6967ee7dbca78c5269e323f467fcc539067deda6c44d5a168ca6c35cc611112c4bdf229dc148ca469f21b4dfc1017b6e50133cb8bf697b0a3bf39eb291057da8ebf685380bbc2561a8b57084d3cc06fbd7a35530974c0aac5d09545378781f482eda9d10249ded5c48c053f6b9da9502fa32f6dfdc1fdfa1d67e18613cac8652e84b4002ea632885908c1778e0b7cdf8e50c99eb909818ea8f9f61e1823f074608d8fe7e571a193a8e658cf09cd55a0058f11285546f6620b1b7fef65bfb61692cced4fca18862c516205e058101f9d7f48e9cb3bb2acabf550162183e30494515a8785a379691da8b5b0ec302fc67bc7629f0e0b9ef75a61b015713389916c82161c8c22ce6740ca2d519bc138545cad87a2243cc5fe10a02ffcdb1203af95e544bc68e6c0d1f89e526ff4da10ca14f447cfa759c51942d3ec3cde28506786a8fd2cb48912b27add4be2cbe0fcd445e42a52953eb1f5f8faa1aab76d8755bcb71effd1b784ad3ef60a62aeaf3882de59c98a28ba902029859e6248e4dff8b5e178c73a36d7160f2cf4870063c543775501df895fadad783e177cb10693bd4dccfee8e5258b07edd19bfbc21e2bf298436ec0e47240179166864710f11347a6d9dec36a56f0f535451d7f25bd1bee9566070d6ef151b964520b82c487c6440a54c2ed0e0e16b0b32e6c45e08a948000fdd8b6cd73cbd45ece49b3f558afd904b8d0ebb201e01a22e9ed0594eb1d5ac4aed6111034ef24b8eaecef94c98d94b00087be982b8d8d0b1557de3bab27b17e94f41e7435a90a55d7cf1082ced8069456446fde8925217ffdda59e16b9021c076243ecfa857d309bc404eca579d06d4828783817e9908170aaf2a6fd00e5cac3c6807824208f7f3057a599af05798370a81c8c98c052948baf095e8f4c792798e61981064d668806ea5bbcc72dc6a8329a0eee832ddc9929a08af1fa94c64502a73a4cd3a83dd0264149861ba44b91d1c3aab82a5f55fc66331f2fdc9ac14dfb2398f822775462ffa92dc509cb2720cf2bb9646cac715a160f473a6d5732de579edd2f557d1e8eb46a30ba469669c512318f550bde4e6e1090665b446475a14e7f3079a36bcab36b05b254435ba3877ecb91fe87e19b26ae0d4808bae174a86a4b5fdf9e6165d0c5f741c66187a98c3d0e1e77c2031748969eda388f63d8ccbf1aeb41234757d2607e7972d7a695efb7c1dce0647ab2bdba217c70b37832c49ef5d1227693587e11d282efa7b9811eebdf01a2ad871d1678e7a47be454f06d2fbe39e7533effc173ef496770388388afdfee7fd128aef295a988641af8c59b0eeb6095f289e0b8fcaf7b5af6318457eee5e542664fb7b24140b5d0b2ab6bfe9c2dc26524d16474bc784fa46feabf244d20bd4853dcc17b17429a6ff65ee9d1bae7fe7bf17fe07fb1670b31db5c9c9a82468a67f455a01e744fd181f30cc8d77385057b5c58b38289ede3f048475dddbb038e6b2d527d91955bb948ad5dda9aa80e5374e8685f13f3d18ea62e0caa0edf38052d461ac5de90cbdae28d7178eef8e0ae897129f6ad4d3b47ca8de0f05076238184df2be7e223efae12b1f918bd7ea7e2920d5420676b64cd3aa960fcb3edb48c9a999110befa3eb9907b2a1d22b85f40d28e36e96364e7b97f7e30a93c4d1979de460f8735d0e7329bf83794e1dd9ca5585e93384c5e6dc638dd46356435b8bd2a00b6be1164dffdeb3e987222fd9391b99f4734ee6e7b7d1f8adba94ec506e651cbd4b2443097e6ce98095397793468715682119befbe37151d80fb6fb90078cdba41665e4e0072174983f1e1d19ce38c7271a81853a3eebc949d275cd2d66b0164080ccc2d9f5c2f21c2f41983bb167bbf2081295072c5c942a8709ad111dadac0e6e6cc812302d473aa1c83963d6b79ada248e7658ff9b0fcc276bf3c9e1c9d6acd03c67f9328e1b302b65ea08fa5baa04ed9f925d939b441b091cdd4277933bf6ba324cf5438bf6e8e24c5852235be67e25aa1ea56b1d88b371baa9138e8b8518ec88c84f34803f3b3cabb684c9ed361393260f0838b13e2ebb3e48f2b0e4a25bcd3a57459945755819402028decf4fdf1ad656607a018e5f70d7e347594f9ab87adc1bd7c0b2ba23f86b81a24341399dea54198d033079f6af5abae5a1cc99a4989bee23dfe1fca2110525c73cab76f3a2987f186b50b1f4858ab9c1214eea05e3260957d14e02b00cf54b24cc4d5577978541659ee78cd921422dce54c4a48a8e952cc18b97ac9086ef82efe711efeff2c70bc88ed7094f52861bc4e3c62bfd628268a3a3e016503200532619f541bd7badb6b9d036f8c7e6163579c7e7d7c33ecc6ff4dfa809da4eed604dc95c98de6b02b9b171369402dcf2937217788a8b199a6f774eb58e5a5c17d6778c23f0334ecebe2a9a1b1662f0ba8abbdf77e1e93825fc3c644e8e9ef292b28bda42f8b8e82986f3866d2f2e8c542b8c93dc2355ba6e1d42d051fbf2b5a3b49e0b0c94da42c7bbebb58774693b68e2627b7e37fe5c734424610ac42e7662c9f03cac2e6965060dde9d959c25274cb9b9a10ebbb2dd7d496153da040f294f2c3f82a7cb34ec1df0e24e6c96b7ebb55d742a40a8a3af476f215e9a5e701f1edc7dcf5c50c1dd69a0a68f84a55093d9ee33eb926169044b3b1aaf2e79ec7edce9a95c91a975a31c1db1afd6238598ce7c77c61b999f46e47eba770f913650122cde793188169674693c6db6994e40c5157cd37fd2cae4ccb5a10d3b369a75ec27b9f763241697542990ccd4b9f65242824839363c99686f7a8c8278c968f6e70d5eb4dd53dd1bbf5690c25730795dfffdd323bdd1a37aa8473dd453bdd20bbdd543f4ce8df9bde81baffc8a1c8c7fb38d68165da16cb4dfc7f47da980b6210d4b055cdc646e8e24937e1395bbe52772b28db31643286970a575c424850964115c581d0c34f23595d64a2752fb234a53e5766956c0dea5e63439b682518fb6ce54f8c80390477929f79dbc1473cdc385d9afb94a3d1bf50aad346e9ca643d2abd42fa3d007f5420d6d5936ca2978bda5fedceaa23658a6c8dc7ec67546d1425c5950fca57fd7b7525f57f5bae671b385998b6ae89b898265574a2ed2b27565ca76554f53a70ca1778c1dea1361c6f4b3e08070109ff710f1c7add9dadae4cbb2a978a531bebee5076a0cc6c7ac919f648fa6b97a9df371754c988c4990394f1a0eae11fd7cebe84e63ddc312624c3760d341e0a09bb21288d5aa08d844d12f8d74a3d47fc0984e6fed91d2923fcab9d67142ba08bda3b041158d251de25327ccbe918429510c7f358088a2aa5094e5d58db3e65e89f038166982fe8d21f62ebbb594e1c3260dcf5cf11f9c88fd5662d17a5d494da4c846156b5f61557e713d0cb4738c25d8a78d4b37e62bd77aa963ddcbca778c2e4ccb840a45bcc275dc1b36c1e82a182747eec233b73a617feec225af304aa170230891e4259a512cfb8fb46f081b48883f17cb68a2c3f911d1e62cfb217fd6d5d5bed21d21c5e2d146798022ca5d6337dec7884bb88db12a1a982f030c24933758f4ade9388e0eeb778b553a81c8f4e9e10ccfd3707aec654cda17cad05cdae33998540cb33a5b26f9e8dc8a54c16a8254df4300ba87bd6816ec06042dc79a9731ed3cd222c539b83d86aae0f62d48ade47a214a1658722a18354fec5fdd096087952361d11f3cd83d7df7ea3580c3eaf1e0aba8fe73a8833a232c385756a3d94d5c478188aec13a6ecf52cf237aa4a6e7671e43c9ddf490575c8613bad0c4d2ae086f3fb268cc00293c96bce12d63f5bf212849f562c8ef460524cb1f055cf911c92a59ad0d25caf6075dcb1389f6550e174d88755f8094f74678af1d7445eae78f4d950b8e1be468098c8d4c9918d42188727c39e69504b422f75a206427a087c3fa3701b00c8747d41d6606b1648c89b894e22f179a0206d029a46b61248b9b72e1db2732f5fa45344cce38dc4626ab0bef20195d4c8aea593cb9cc55483c582407a835f1c0e1c37166a457103d3eeb48a16485d45648fe52a4e7178f9eb7299c2d76425020fae39ee99e2241a2dd32b319bc1efe617333305bd019a004392d8ca46ffaaac71d6308fdf868e5083f84d6a357f5566ff5548fead5cd402ffda4777a57eff4ae977aab577aa1a7f4365a104cdcc451269ce51be5feaeb55b6364c5ccaecfc2721d63a4aff372cde5f1e655ba94197edcc25ede5e6f724d12c3ef42f63a3a052797fab86ff65995dbbec420e977cea55f6ea75d46293e9d2bc23445ec97962c1517c49f8262a5c42d3793e8b4b710ec74aa11a0f2e75f224ad2fef27fabd7da4cdc3a0f5ddaa4cc8d4c720bcad9a0938b5b227c8a832b6f84f68909e53dfad02d96427fd85bb7a465c050b83047eca3ac5829178048bb18ce8e0ad23a7d62f24bbbc90db97e7c0fc7940b30cf48fbbc2c6a2dbf0eebaf5ee796726e7db8fe8df7cf475bbb2fa2d2c7dfee99391cf9306318ad413e62ba7d60ba1b692d7a6fdbce66e0eec2cf8d44b06364e869988f3433331f33d558e68588b8fdab179df6d6c38bc94b61ed9be9afa565b619b6c7762b769b33ed5d84b0075276caecc118653c3fa52ac15fdd80a3962b07ea18a3a5ffce6a630b3475e632de02be6febf11bca9f8f8adb711b43f3454788d8271bc5c5f5c8bd56bedc01f17e536ce954d7c284fb6c3b2b31680511f3f2d6b25d564f17347f4fdf943052cea079e5de03fab753bdcde24f41e3b5c3a7cfd39335e7a1c92017574f9a362fdce69d8733ad8d134384ff65b628e2de7d542e5e14379cef7ca0b499c360ea27f9dd0ba051d48b5d3c7dc9e48b31f3529cfc4ce104562bbc6662c4bbfb1a9a10708b63563e8ad6966605aea6b3904572028c1346d86e50733ce255b6355d1027072b1506007715a974e1e4d3d8d550d9ea6cacaccb92d74fd20f892ab88ac6ee4d0113027d81894e8fff9c28661de1193e4471baeef300255939dfae980c0513f9723b2cd2bc3c99c3b9b5c89f23a09b562b5c9e8e05ac6631464d90f9bbcd9e419a9047b7e48786723264992b817faa5fbebb34d5c19a5ef86492204db8dcfcfb7e8b51a4894874620a36b0147c9e0e60494c31ee3308dc1f5c6b1962680015422882c114c35ddb852e90df1ef9967c285b417528527aedca440572f7597b18344b7376139ed94f75e310b132490579920a427a48eda01d4a74a05f7b48c4a158b5b41c7c749ed9b739ee32d988b23c373ff98ff074440b27c657795cafe7c0eeaeb7371b9aacd2053d1c1168720da49e79e60538aa955c4f11392adca07929d8c9f676e06b5e8124e098820cd3cc21f8ea9a8ab1e73588894a80773142d2cb70da816ca64b6a49bf3f9aafb443c0ef8f52522902a373033733df992406d1e83afbeaa262b68de6c2416c2ceef3cac4e81c3f8ff52bcfc22ad209dd47569166858e55fd83b3a549224a0c2f7d6c6ccf5336f335acb15e2087499375747c33aae134a167635db3120cb6c7f570dc462479f75ca183ab8564ddff9a7354a1d18bbc7d94dad691ad3fc1698c4d2dca8f17a01b804a698dfb5e8d3125c9b98e3d4d3f32c0fcac5700b0e97c5195d06443132ebd2d77e58ef774d8e3777e39d1e3d7edf364e1da102c5ad24f84490eebc7c45fefed25ab1e9854f202b91b8bf0d2c52a2c04fc15c8414a47431f885550d2c1c12fe460753058786ac1f2908a6240c4b2ba1d1842b5c230ab7f2d3ff730c6f5416a7715326a4ae41c673daa757e7fca1ee41652a8d12d496193e175002a529fe0684e43a943de20ac081f5cf34437e3b22d19dd2b13017ac328198e61c577d9a70178e6865237d40d0bcb0d9cca59527c81ba718ab1a498e91b69ddc36238ee6094fa4a4e74b95b696de650bcaf7bd033e36eafebfceceb1eddf4b289af9b96980f2d5b56e44c2ba437e188a53c1d1e3eb1a119e423b2d5e38b83ffc9e9b597111212839b157e5698d8ce71b209ffd84e1eab55b6d8a3d9ba1899cb2d377c01a691d914b82dbc89fd9651e5c7b1db2379379ad72f3284fe4044ff5c8ef737e23503f48cfcb2edfea9aa34c24587529b4c8eb8893012bbeaa48825bf58148e5e688fad97371e9ff95a923201b0cd4f599ff44bff5d750ef3dcd0e2062487af9921850d09d8914aa298781dce1b68570903ce123a1860ea8aa09a3748f74e3ab985c8b233b818bcbcd9def7db71c5f97bc597c3ecad50baa5ceed8d3870d73282f660f6afeb6036b8f081ed6c320dfbe63b8eab0b469435b709f17027e051e2e01fd1f26e58b66e38d6ec93fc97848bd11988e854ade0fc3ac2649b5a287180a05c5f71c42ebab758a183da2fa2057c754a9cb41bcee5ec3d0fdef8f14e8d1cbf41a0ee95daea1449c8f6890e3fa320c28571229f459619ab5378c08047e2da467f74a894be86747f56f035c49255922fa7a8d9067b6cd4336c88d96343c5258c6a0002ce722091305ab22b87cce2d6d066ebd36fc917871a72adce27e23891b2af41b31e329710fe6a0b28241582c209b624289274a697431b91552d3a38ed6b69eeb4c5f54574c8c46d745574ecd2a88db2ea5cc3962535f5a276ba3e3f6ed8417805c8f49ded74b5b2ca3992e2434806884bb9269490fc0043f2060f6d49304b7e867a8c2f2aea976db1fd8a2b31f61040df80a1289e919bef8d7b6abb1eb08bb2c73bb88074f017c8821f1da35831d50db36127a289880cfcbaaf7e4ff6c6c9314ff67d577897033d9f39e04b738ed988cd16e48dd72b8cb88e5ecc8b2c75bd5cede8049284deba965f59c14849a85e9c76e8e0a5732ab9e509eadb3bfd9a3acf3239d90c7ba0f5d0e3313de6d4d48429fee0794c6e8f764bc5452718f4adee26ffa81431f6a04ce9422d85d39a67b4a1409c3843d9a6429c73542d228322a752fac117f0656e767dcab38dc9124560766261a8b1d2288d3a56964b63bf42ca45d1d3fa1ad604f48fe5a0bc68bb5ef88cca933837c54a053575e063c337db261d8fab76fa36e8d47f6d45c8b30b7f198cebe74539ee520211ec1afdf47839c0f68514079de8e7ebe513db434bb8dde30947d35a6e7ba37c70e4840d40641b935a4e9bcd93a634f2018888d5f745561f6e1778ab6587c476b71bb40232322d2d98018c4ffcb0e024aee4ed579d57f416e930824ce44eadbe3054bda2a0d580a7dc88bfd88d2b3de2f7ad4bf9b8e904cf3cc20f6918ccc0b13f94981ac699bc6b5991eb1f31dbef86edd86e1f32541e8478ad5b71985395b42051450e1a073e83163e5638214ac2fda496eca377d6a1d132a3b86a32108c411c2909f5918dc3bc58896df6d87c94eee38c52b4a7241043e3882cf0d8abf72c88670b4d3dab74b4218142252c45a519992410de76e9e7e466e041eaf7a550c54a57dd0a73b3200240f8369e2e3a8d65a8b524ba604442000da7c7f595e2d7937e67c130937e748347c2e51b3b0ed2e3fdb8cfc4172a1999f0e22e48e652739b0db521ddd87ec54d77976ff0d92ac3899f561bc0f6d388e88d03246d9c346d20a036d069254429366ca6216a5b1dcc3ae5cd552f03abf756362532a27615dd6622f2f42f222f0d5ef273553c1371526b421828b4494c5bbc40a1c14ced3c677433721df983f45622145a0c8bc34839547c10ada2b8018ea05ddfbe71414c76422bec38e7ad7b624dc0b017227d82914f34ee138b7942e33ec1884f18e989c4fa24639f604c796280c5c5ad32b008dd74204e90b1b2bb40f43ead71fe1cad95561490247c9c9ea084d37ceb4ded5591e004431fb07cae871b3d4f268dfaec2aca3e2e6f7564822232288580ee77707e57d94c55ec2704b502ad2fb95dc1467020ac5e5c7b74e9c5a456b95f75ba1e3ef93ff10bd6fade1013e63215482a2d80beeb9e3b3251853734886a8f2cebc1da92e51f3da6b9884378127cd06c94ee67b01b11b7c4784c88cd5f3f7b97b2c4ccb40df92414863bbe43965573ee5a87bf9ef0d3e94459326216756d4026c47978a33a25b5688fc358741ce92dba338ae313e1c4c75dd6db5c70e6fe41b75a86d03601a9236edd44de29f6d87d289a714452821161402d36b48931d8a246e935e8b817813c7acb1933cfa19140f5410f8af443e4f877c168505b88e1f73a4745a5cb835bc18cf9a5a70c417c7ee89a18873cfba8ebe4c4d62c4a36b0244a4ae1827fc353194d8c112c27018bab8973425be6500a67c23fa909e91b0a09d095bf4ccf7f947e80087f4973f32c8c66080f5f34c3f84c2325f8aea09541a062c0a192545bfc86deac27c1ef50150b6566386f074b62ae4824da91e438c0c244b176bab5d53e2a8bcb2df9a70fb8361f42fdd672ea1e244c96a006d7928fe3696f7eb3b2e1085b49ce027d38a09c0d19a5c8f685c1e2c1e2d527df4d79f716ce7c9bff2e02607dddab7958364b5309585b8dd2ab662ff434afb19b6d004d6abe6add00bc3fe2078051cca2a6b759474e370f14b0b9761aa836494eabb44410a582b4014410518fac4e0c3417d360f38714ff6f9f650d62ef09815cdd49f5d93de4ddf12d7ffb7e235b538b696c63922a356a15a5f62aea6ce13910bb856c1d8be860f5fe4b92148216d205e579059eea84e9ad9455751ab88eff49af79d9f11a299bb1c5f532c7071779bd841a7968a38af32d2889a9a29e2edf4aa93fb6ba34102d934c1e074f774a768f70fa0d8921ec6efe9451f80eb99618248b32856870b51fdeafcc310162a775e0a8a114d5348036a9aadd8ab32669ec420d58869a78b55b47578b5bf9acff5ebdad5b69ce89607c9c9e39e5b43846636eac0fbd60a108d4ef593a0222dfa91fe39c48911c2038504d3f4539ebd04cae0849799488e7f00f37d7b2af42f105e086b36290263e48b43e4b40c86f2be5e5ddd06671a6941ce787c3ddd0e54a872bcfc00983f8108d32d048d0994f5c9e80cae2d2ac650dd0fe39c017a8d78803f4c163392e636ac2fe50e0e9ca5c6ae2acad12ad61b6c99437514c99807b34c715a324bb899811f1800ab5d39921597be8188e5bc845e680223ac35e1fd5e36e951d86af4d7738befc2534abc41eddb7ca5aac567d059c9281c2850e22ff091d0db7e8a39e0cae3c762961e509d4565af9b961d9a38df8c2777d5a459238ab77ac7a78d62be00fe6d839968ad2e2fe66aff3b296aa4c6a9a51699841098ec395279609328ac68086eaaa809af5b8e7e0c03aa4fdf2721a81c5cc1da420ae3c0d82f6f90df28db08948fb3b7fa3365597b9336930d272cd8a322e816a3604bb3388c50ff13bf10be95a8f7aa6f939b382c43e5ed4a84bcd5c6785800bbfb04ba148d9eb86030816bfe2881d7222364550bbe96bac64a01d8f83b07a8ccd3cbddcef0c9c77338d12063b8623a95c2d52af363ea93040047039726c4d3f2b7fde0f5c0a3a8308ec1e915f8c9c99f940e0950341d4104c423cdb0bdcba3095f8d55319dc236ff13426a861e53e2c6c4a400061ff07e4fe531ab229e8342a3b8e624fd0e14bb4302755f588d735c3cd89fa4e33e7cec55a6eed539482152ce9110fbaafd0d3184852e2fbb379d298ca369759152adb6a10ff4f12ddd396269c8787cdde441c35a7949267467b625764019f0449c19d52ba1bb79288328819ed7522d3578a8ef0492fa61199d1d6160d9b0cc39fdb4e0da7850f4baba985de484a05957cf234b91679196d1db50f9aa57f3f9cb66438c2bab9d0bbcb68730b0ad304b7a308361fc096d12ec9fe6ed8c19826f4e8dc7502276cc91189cd24e476dfbd33302464325f7bf3b117c3956f7886d1a365a853208e9a5a1ea7b4c885e505df57a13a24962d0f1c86cfb7deb01bedffc191e67234601f5972e165450a260745b415d0596a09081b391f1f34b2f1a18bfee9c87b78da60f88b0d513de3af8ce073e90180e09ba8a0a01486fbd4b02de020f0768bdac17a06bf1e442368c12bde7f78657f65a20343a2fb7e7db5050ca1c6c7fd4147d4af8608b1af0025fe02400e07a0b80a0107d6b6508629ce715c595c1c58d90debb020d9a43dea87b4fe2022ee9b18db2115b95e05a0ab32d38cef391bcf9ebe5252f3170e743582502056347893d44525a80cfd6b987870a8e14cc2c324b0e87688962751cbd2c15e35b08545dba18b2eb529211f7b7659bba8749b77b32deca8e505976922fc18cebdfdab2ffdbade0862850e90953296530c61800afae7c297e594fc3d91935901b9a6aa55a9bad8a591297e0e7ca1294f8b684ba0d6c38d2944c4b9fc56223257fbd87909f5d130f4eb1808c87b525154904cf0e0960707b17d5e75aa1d3ee77bf8f15e07db15c5a1b6ae31e0db4f0aa2382a1475588dd2053293ee6336a102d56cce38cb40c20b9c98aeae6031f20dd7861b7a25fc8b844d8b29209e4e353a5a00105097274f856ba9d621122f210e878a44471f6634c47d78bc7fa971e3542b83f92e6668da79d003cf3ce6007e686e072e982a7c1e60ab6662fe5212a0ccdd9ae26bb7e6602e08abd1f4d9b1527d11a89cd8cf3a1234fc3245fa21e7d4b3e7a21c23afd0b5b721303276f4fc03d0932481974722822e443bb41656d2af05ac0be8246fb1524134f13eb696523b0853d2878086c3cd7e282eaa069e80032fb3df7aaab6ab9d932b7a13bb05b020a7b184c6493e6450691a4c9df2553228b0ce3fa9c5c15fae0224c1092c792f78bd3783b41216d2dca8059adc64da757246d853b18ff00350459f5a700a707a1c28009f90c2e1b4bb4df7fdcc472ea3cd0e916ac88bfecccfe34bbda5b7419b1eeeff94bb99f146a6019f8323bfd9661a17259215eb2977ac5dbd7e768c273f37ee0460a0667a35f010468810e3177feef38a7e954303b3ea9fc4f621543601ba88cd684a374ddcfe0546ce2c0425003e2bdb3d163b0e7bb3fdf3e8655765731b35e3ce2ba8acfd2123843d453bf2396a53a8cd2a39562e3803d2a163d8d30b001e890b9ee1979b06527602c1b3c0e14bc095958322be37980ab8d3d71ea9fe56f240c001fbd5da9e7db96a2d610531803fdd0ef361afcbbc45d02eb3988501fd586609a39e80f02816ef9c0f222e576ae6b77ca15e89ae9151067f7c25877cce84f0b61809507216dd8ee326ef7c330bb38d53422242d58c82f58cfd8baf1b08d73a3367caedf3f51e43b4adcfdcaadb4b1562208c57c89a8eb20b65fb00d55e54b500c28f2c92e54b366364863e3e3e3700b42d8c161281594c78e76c0878d3c0c974e278625173613e0681dd1179cba065eba90e58673e6057ee9b0228400bf3f5b1f626dc01bbea8278fd01bb7be4e7f509250e99c852c13748d7dc9698289c9c9025fce250663a81b3866891501b825d0f4091537c96460fddf7b87aeb9abab9da9123b93a0b61c5200fa2208e30ba5fd309cc5a45fddf7691f604c5b15281e8fa0aa5a01698dcad6498523bf7e01c360638c0c579ca8827b016eab597b6f3d7e10469aa9181adcb33761b3c8e0551e6516c2508959eb1ab9ea8f3cfd8ddf00f9b0718fa752680452ac0c85e8ee9b5eb0331b9f7af10c97d1a519f7f9dc722d6a1ba05d07d89b1018f2b2f59cac83167ae683df5e02cc7ee74832eba57d5d2a3f6542d8cdd9187542b15f7782004e0aee0ad99776eb9046e001acb30983e0852bfe0eea8d8715972118875d983288a62805b3c5d3e24ec8d6f71e943fa779f8b32cc38a5b28bb8cfbe34ad8e0cb0a4cc74e2a1506640e02377be58b8cef50ba7bb05552abb934a3c41637875237b7f0dbcde60963fefb50529f4f41ef326121015dac97000ec5cbc1223cd187c7846b60ec10b2905e7043d3a8131e30f23856f0b38f6574826dc2321be86565531b5eaa55d5403e4cdaeb2e41a18e4eae73896bde9fccc4e6b34f4ad0a721f01aa38b09504c1b457d3c4adf17c4bb44b0175d3970082f61f39bd8786f909b25632be48d50e99ba7cc0d69aceee0572667e48785513c8e8af7f58a934cfe1ca0e96272c3f17d2a7a1d4eea48f86488fb4bacff1e49108ec166077e099b5c4ef6295f724d800cbc016059e7eae87ad2c5c82a9b646db39dc7ece7e8dd8071bda625f50aa4320fff46594f21eea73e1ddec3a7ff54a162a22d0905c9891275cc67d435d7cb148d0d01770141d950c9c2c93aa9c7919e34d9bfa56a581202faaec97237bc4edeb86f405cd9230e11c829bda395355fc1a700cb61fe6221ca9866c6557f6769e29ae4b08df0e15cade25507277b6a25138a12febe74938181ac941009ea14ee441463397e0001dd90813e46edbf911a6dd2b9fd2cc1e266ece489b94c84617e720653589b8dc0ac150b82cd2f865b99d2e104e6f8cf9807e6133b278e7d7cfcb1e494682385b89b855fdc63b24944de092dffe4e2bd910020d3e9a690e6daca6bcc33420178f14b4c38b7c71e477133ca1624e788f21853e11a7886f37896aa0d369764a2cf03efbce0435c79c73e313ac9283b34964aac5ad411727f8f2566c7278ae631bbed68fb6b640d6678dc778fc1eb57437d43ec67700a37bfc507c4670d1ebfef7d293c1868a0aa46742ec5f60815cb9432803e42080f2a3ab2861b8de87118ea22d63af4ff256bcbd8c996d135c3a5716e8d4236923113f5a964bb7c5013771e2185c893898a9f112ce1460dfa12ba74bbda191c7194f33b72e5d5ee78246c3b1227dd5db0ce0b4fbcb214ae1be2c5f8dc640d094681c594a603fec8e867c8f4cb7428e7aff290080e142754f62047359bc407eca5e1d2dc090a2b1d0829a62bab70550c9099168749bee53f1a1ec8c83de61f4abfc7834236f1dc8357503a59a9fe7c69f6091676b7babbbfe0fab957ae7ed9ced0a537f77fcd3831ca297f23e1fded1fa7acfb5ca40af41c1eef721c7acb4228591f8a4e69b49a97986a8ad05a385a22f4ffe182eed8793707a36c08f67b815883d58cae03ae3580b54fcf55104be8e2cb172176203e7626797d5f8ae1e9014afd601844b1f46bec270ddd4442ed737db8b01b555c188fcfdf74ccb1e317ae9a637f89caafb358369588a2804b2bbf5f564091de996bbde2504cbd6a123992cdca366232f1985849c97042021380be7090471f5935da4fd8f59fc8edb0394c368b47d0b692c0a46311ee4ca8e8977b17e9d937deed75cd3db0b2008e0703a7cf8215c22cae9a31277ab5141117809320496df445a25af731839ba89f9dc423004744b0a22b6ce8860bda83740cd2a0d37931f620a6ea8ff694a5126e4e77218200733fb7addbd03909d74a429be65b71edb99639d92f08b940934fd9ca58579736809070b5638b317f9dccd5c8ec1056e99e7c04b5e58d6f3ce82244a33fc4ed10098cda0779127e3049da951389665578768ce64f6ae86c89046cee2e820326b0a44d8daeb07573990dbd02112d88094a955fc44ff98b459fbbb75730607b750831c41ef3d9cdd5e19153e356919ae0fe27497674e481cc05873b254a83a08d0ed747d7f88f534e2c78da2902a04bd9fb486b427af6c6c0bb1b26892024a7d28b75622f9b287a973c6e8bb781cd2d5ddf572811bda8080d60dbbf098e8b52c97f1a86c63706a858058b00f80f90b86039cedcfa854d83112a3a1430598011417d465b31e62ec64ee0d2802e01abccc2debf9a6c4bb2e909bee4557dad7685931869002143c2a9c128308926d60110ef95a4df6037178739130ef19de80d75ee82d2a471077e0bd399be5a3508b35666a763bd38387a440f47898a1996980c7267f71a703695127cd17682257c456f4780948d6f54c3d9139a02d906d68658cb257ca8c720576a0096eebaa582159b7d0c7833f5becb6d5e891a18d6151afa8b7fee30f044992849bb4488eff2931d10427c8f29bf2a855e8881e7b50030502290ad6437d10c1d9249222b408d634e81582716b3f3b2554ed14f7963602d368f7909905fe81a61eaf8f2a6d42a1677eade5bbb1fb77e40895374f50fd561c7ce5307b985f55e1adaf652a74a3f67e1b9089a26fbe1158dca1e304206b94261016cd1fad1dac7f6a3a7b28e231c1e9203acdeaec7d59b18bd217de9e03a53d7e5e4eb33dd0624d2c0843a2a070740db34adbd4066a923354b54ad095091b0a730b53f4ff3668b2cc289c709747cd0a66d6c1de60412588f320cf0b27b80a4c855a01f1ac1098a72d9d0c3d1bd76149900820a1a83a99d98988909d01b621a0788211ddffb34bd0b356beeb1d3af2254fdb807e703e1fe0117191b218e1cd3aa3405c44c83c010d7b6e6e54e302459fe8970b22560471c1a7bf6c4d08d79ef3207ee563a3bd85201928d1590062419c6d77176db8a83c05cd8f717a3cb378870c2778e244e2f487cc9246190ee26e82ea00e7397a7460e93b529c9b3856451e573dcf3f6b914ebe8ed5233ee229024350414e9af8f7343be346f4d602daea00bd4040bd3bd0a246d4d31630d2045bd652a59b92b5ed9b6aabf9a6268a6da1004459d506974e9f25f11aa6e2f4b4d3c0cf464b1e19f4657a5ad421b23d4181f7bebaa453481bd7073028e73bce441a8c74646dce51b5d33a9423e9bbcb8361ed8ea5425f59bcd267bd1ee5adb48d9c52bdfe8d39728d556dfcaf7a8e9b8020714fd415c33927a0f4d1e7ad8b8151f727c495c650dafd87e7f59778278650ee5c45cbed41c757c11877409aecf8778115470c3834ee5266f38152f1e55768eba37145ef148f8554144521b86cef638909994cd295fc3b368b4fc9fbb48c9bccca3f4f61a5c127de2d537d6357249ab0997c46fbe7de3f21523cbe4b012d02769888e7148d0f2427ed153ed0d044cc8141bf34c305a47de3da14794058b52bc9fd19805dd981e7ce0907db8c644abe718a35678caf31d6621e0863d333c53d07b3e66c6a2098cfc026297ff2704d538c459f3a3626f35fa08a15f7f20917c45f47bbc427abd8757a050bd1770ab725ff9b548c2d6e580812c3b3f47443d53b7fd5053f09ad323d1d9255e98cc8fe8d3ab4e57824728e13c32f4f0715ce4b71c351cabc3c1d5498912369b86064c265b06ae58e27a2049b7197a72ae7db90624c956893395c600e12afd8f0fea9d0f3fd516154a7c9b518706b0a5d4b2a3e2349b6bcf7e4c0e48a4b0c08e45bc6d6b8490d0577641b8c263d53079b0d1c17c05c4b255c188e5a2d02f6911c79d275268b8845c5bdad28f0c68f9e693ebfa0070778aba3e8c74b86a60c655fcb00548fa67dba8edb9fee9cee265431c5f0343fec49edc63e369f21a353b47632f4e72910aa89fb0afce840dcde14a5421fb50e026b1dd4f9704836d57e1bebf4db5ec87a8a15b0887ad14af221e8d2f4055d5ac467b83d99f0644d6466dc91160b7acd990d35f39dd38c1c52509863fe0630a44ce08706b5002ae8db28d0a1afe61b0eaf194479fc1daeb69c9ee371ecd809abd452c8aa1b59d8f3c840cdd8e6a0139657887912ca022839355a75d7a785bd99024cc5942d95633009695817bd3ca8148c02a7e741c6374005039cc43e6c526d9c5b913cf00bbcb05806703258162e56215efdb519b70204cdb197e80ba60ff01082f2569598a270e5345169eb8ed28b5526a8ad215507a6c75118ed9dbdb50719406477fbd8aa7e6940e08abc002d7867f0dcb3670d325e12f699b325792a103e40588086b577fdd3612e42f4c5ad0a472cbc3b00ec55f0490ec357f5508c17876fe12107592b43c5154c75ffb224f110b26bbdb1783ffe952c8763343d4d1fd2927b437e1db7de3fc064a35761f4117d3d1273030b015a7dc06c1feadee5268ea3acb534c550d6aa4bf14bb75b9816192c91ea6816c033f70fc0d8aedf849c44bb7b2db591b23fa96ba3ec04f9b7245afa03da880f1ac50351a6992d60f6a86221ee0341f8688185e011bcf791cdf0f67e107c7e1841ea02b952d59979c0ec760865c3206d81a5adbf5230e41610ec6f440b37d601c9f22c3907d315939ff011e72b8e1b36b7bea57ca924821aaf82f38a67c04e7f7a0960e9668f64264ad42b9a93da999141195e83bceb9dcd8552c1a1cd37f774045a3683e43065104f3e7dcb21f2991060cfee7869a31f4598d58151c07695ade914eabf0c1a4f0210cc016f1e232c89e1e5b13b9206d1717838505af0b703b81facf9dde18e90f4e3e92c6a2d29bba83f365a3e5ba772a5d5691dca154d564fe47a2b17e64f685e18a693b0936e1344595e7f5a2a6e8788b4709c8934f033f4d1678dc1883b8cfa41b66a43e5d55f4dcc7d65e794dceea093f1c45fe0eb8ea5c89204fc4d35660ea1242ea76c2f66e8238f9c249898ac10d1548c291be8a02a98cd5db52f4ee079f86d281fc1b6f29cb8658372e8f3fde5aba2c40e12609ca60a87e2bfab0bad0e585b02bc4c41d33bbb6eba229678204cccd9ac002e33dc601f893f47aa3cd4cdd8f7a5077c8de8d619cc115a462453c87764580a9197adbadaf7b1f30d3587a76a0fa7e5e2e099e3e11275069e17185d12357ff706b410065850787f063fed5fa4f583d270cf2b1d8d27f6a443519d3805419f0fd1933387c7c832f9c87d4ed0d2f579b2ac88c2711c71e3d29c2b743b8e9bc06dc7de0148199b984ac0deed19b405a273910877b9c0f7c1a6f507c86fe3b20010f490c1fd104b385a2b9cdd1b965c467a16a870262eef81fd88a808fcc78f04681d61539b63432838cf080dd21ba1af888e87986b5c9c35006ca28ec009b7049ee74d98f0627e11431b9c531fb104636a483b3386194679e5a0528688e3d541d4afd1830b94a03dd54d88038335389c828450f3392b13e20612d062e54d0bbec1dca06687b972f5fa0e850cb1be95d409ce04860b1d9da33e0838afe911b73edb5e03ad88764f71a65c21372587d3bf84f9d58591e50a05a542544d77fce8254d037c117cfa1e49389a9a0f2f18dc657b42f4e5fe71a742ec45ad21b8a32b873b86a4c987f1dfffd3d6321e56d9be4e899398bdb09c82f5ee8f36c446cb83375e56b493310b4f4f64b0f01eed194316ca07deff161203c4290c4688f7616aceb619eee6a0b5f49ca2b3082398a30a3d94326099e4e272434120a079b25033268745332fd3148dea820ac6321bdf7b8376c195caecf8ed11269588678315163003928d16b000ae82386585a92490bddc8d5be6be7086076518b43a8afce03a2d510243f3eacfb0c11fb7de9d1e5612f838107770b52ed0d48a85541b33d18078abf3951f00cf71958de5b61c264c8ea03660748eb5ee68195f18273149707cee5d783bd13d9ea4e5ec8fb6a9004f8e785bb143af75c805c649539ccefa42738cc845c26f14d5004fa9765518315fa74a79514b77412cc18d76ff144948e6eb996874f4b0dd595c3b222b3858283584c40255f2f5d170e5270388a410c792ccbe3c15d6f7bda38061e93f31ef1b13f59775eea6c4c760029e0e74619ee67813f7e12e38091f24757c0fe610a08c1130f2a96d7d55a993abddbea36c7fe4795738954802829ace71dd28897bf3f08112dd9a14e9dda394e8cf835199ba5a25bbd226aea1c58191d9d2801de64650c1319f83ebebfeffc33b5dd9cc39fd4745bcf218b1f9eb827911d5decad17bd49bd65016ccee6faeb78358457628cf14f33cacd62b34a7a5a2c9a08229b5593e381995eaf8aafafbb530ea248d78613e17cf5bda4f680472c3a7ba3300183cfe3c87d70b8278d46f0aa2481f59abf7e1448338cd86b06ffcea8f55b8d266c1efde5bb10d3f6ae9f844d8e7567d3db754105cc48802bf51cceb4bf1b5d31045e23ceb51d1aa5b05bc360981e6e53ea82684a2525607c499ac054a5e4808eeea18ece8c06db3c66a32d6783b957da986a8171ce55efc469b8bf06e888ab5fd51d6ed65abffa246a42cb78595bcd745b87c0db646b32c569f8024842d4d8c19786207091038c7816bd7258046c960ab7f59d3d6c07f14036a0849ed6229cb8d100f5776e4209c16acacb9b15899fd5be7fbf06c57ac3659d1b64002efd0cf53302bce52649d0a794961b1ca7a2124c032287c422920adb41f9b2127eb655dc24fa19ef30f5d8683e86b236d99f67ce3531d0faed9cd1e3405f26ed4deabc979a35ddf5dc46491dd30f6219d84150a72cb32bc0f11613a4415e03b7d839199c14bf6cbdfd11d2787eabccc6614bbe182c044850ec910ab70a18db58cfa559b7f4d0f64cd43b04946c2d6feda3dc1c2770953a4439e915864e3cb5f25a039f249b6a79747bf2a1ca340d598b5d981eb0ca3c169be23583a38c64168cd59e69275cfa568984bb53681a5234f4744fb254f058b8e02cd5bec60e9d2cfc4ce4772ba5c85950e2290195770d3623d52e2ca9aae5b1e4bc73971a4266192916492257aece9a5b4b174948ae75fe9005493158b5be9d040a308c4b274d8ca0093b2997e0b2b7c2377cb6710965d916efed009512b624b50b7739384034fb10f5185b9147016155761bd05e752c6364833a5b9acca6890c3206a5acb9feabb6702a01e89275540b7de0895dabadf039f0d51965f529eaaae641e7c7da33d92d0446d25ca31e1c9bec40b535aa1feb5ee03a158d169232c29788b5bd8b31c89de6bb52511987a1e24b1e5c3164c979df501ed11afe5c512fe2793a72b4461d07e265e9768839e84bdccb2cfd5ffc87a0b354099a5f018a9f4811d2667d144a533ac59689cb3e240b3f263e1c262a47727ff1425264c5aa46975b8a0a86adb826c646f0872e52735035fa63a3e9fd9c0a726a8cc5adf308f0530d7eb96a871ccabd63e00434ab9a838c8259cb0081edb12b72691d41a5daf3a1f5316101df1796a854004142ae2c3e3c5c83e03e06aacc2df9b4faa57a472392927d80ad75a637ef0a8bc9e79c5fc6cfadd658c9f4220468e34d6b68a1da6a8439a9fb4c76ee49f3a1d7a26210431d19c8b6a8a5ad16fa8d0a41d06a78e49c3e79b573f262c95c5212bc558cb3eab1ed0dd01ebdb43073cf203ca36839c58309cd5261d8d84da5ca9a9d35d2c6fe15d4200ae97a244a8375a72afaa482e162491949841d48e06e3c6ab2018a4318e6ba73bf919ce394077e5541ea7c5fe190a767fbd378f8ad6dfd6d6b6d1364b88344208d97bcb2d03e809cb0990093dd420337ee970fe0e2f55bd17d73bad0ecfe5731d9e0d892d4e2c3f467d77da8fcae3f9f18be99cec19ec2198a6611414b71ca3c7b74ec3a41cb4e59859c2f22b8aea9deeaa1bcbf2ad6ed316a555a857948fa2f1f1509d85a67a3c5415556113162cd36e62cdaaeacc67a140a0e5a0adae108bcd34b35c7bc1ec27cd8586d11edf3b337c839f56dd1b8b71180a8542dd1ec2426fb42c282d94b1d0e682e5eaf1a091aed19473b5b3e82ea6d4d619a2427b0bda4c28921eeea137da19d965b60c893104ced71ed243bd6a003a27878e66d7983ecb5b8fab3b68350dd334ad86d3344e8534d26a0dc7a990461cc79d4c40c0f060a2d3e974fe4d40c050218d380cd38e611cad096118c75dc3b887b06b1e4e53218db010f71017aab8900908189a8679b61d1aa669d8b5edd05e83796e69262060689eca711cc771216ec81cc9c45c65241303aa61f590a2a99046188769e7b49ae24040dc4ac1346bdb81bd460bbdda7a68163bc48926203418582806c7711cc76d18966d5a75968ae559d47e9af6f4eb74169dea96e304b7d3392a3a8a9e0e716e0202c6ca59aa0a69f436d42b21569eb1d4cb57e259966b0f9d858652f43e22767e855ee6829d351b69a9d467e0ecae4fa14d47e9a9cfc0d38cdb3ad0db265aa2f7c723625346c098874325bb0788c71dea9d97d5b46717cdb2183b33cd315a56e6881906afd49af918173512c198f331624c8873aa0e041097d5b6a31e088873327d2482313b0d93d67031e6ec2e668c5a33cfc568d1a1478c7adb72d7a1de1e89604c8e9b15c79de5a827a612a78eaaf5d8b663e55c6bf831ee59e9277025956d3b565e93d2e1da4a5555d58a0e939b73ced931664ba56c33a85d3d704a8f9457af94ed8ba27a278c7a4ff73aa5bef21173eaa9193a6ae5b352b983204e5cf969e5a695129f3b6d3958a8b493b2adece46867ca3554a7a46018860141d962bfe8b3a3de01e2288a1de2c493a91453474f04a306733b49e15a8332bba4bc079af21934e53eca8c3acbb6f5757f7b0755b78d87c7569f6d87e82afccc66e7eaf9c0962f9b344c767e43eabd56e26680dfae00bf2f3ffcca64d9cb81dd0e0638c39802fcf02c4b49a552a995a7304da55252b25849511836fe7c487d05068c8d0ab392e2dfd4b972c73bb00e6c83b9aefc26089fa56279e4b354576eb1426b605c88e52ac552ef8d658916557da57277a8afb0a460c078f5eaf9c072d44ae5573ef3a8da482baa35298771ae3755ef0a33bdb289459db9a3f4ce3cb10e28182cd58e5d896790e90c4bf764998758795579a5a65210a725c61956013c00cfe159c6f5d230cb57be52f92c2c9b5816d147db0e1b5f21d9a8d5e381a587b8c8e82725d3a9b25155364adb8ecac64d5b0fad25467d0f396954d94045b1594a2a45d9a6a4a4a4a4a460548e8f07d4296561ebc3bbef701d0eaa7103d4dbf5f002bc9c1fea951902637ca8fde4467d2500a9de295347f59e625e7e5f4300bf5d0f95a14b007a480e3d846795fdda78aac2ac3c55af8d7a69b591963ef50c6a1e5a3d1fee638e81a6eaa52afb4d9de5b7772cea353ea3875983f64067a4541b79967a5395e577a5da487b9fad5858585850293a733a4353e92918a9d43995fadb8658a9d5e3814feb7d297a96a3de4f604c0fa0de4e00f5762ff59e877a5f0250ef0b8d7a656c0ef5cae4f0967aaf96c7a877bed67b9a514bdd65d47bed7000d43b75b84bf57c5839ea2ca96a232d57d449db8ed46bb8d697b61e9a4dfde5ec583ebfabf7e2efc07c1d7272a8f76aa92b473d46bd275b3d1f522baf2c2c376d39582a69e90aad2ca56cabaa5aa1d50a8d96f26144519665cfa67d36fb0ec7cc5c9cd9ec5336b1473d457bcb917a16595858be832d4bbdb1cc422f1f45617ce537966da48551abc703ea333095693830269aea9db65463e635aada45f59e20143154b90a716092b6113f2b0ec48130095bec037186dc1f9a87edf5eef815db8a5e389d121cf844deb490bea984bc9bce9a4018328699394a7060532ce72831629dd8916524b08009e9778e4abd81211047aa01f206873c8abe34ccb5026358420f8dbe4233cad0c588226ca85ed4b9195bf6348e764dcc140da988d26fb763c69fe957e8a7d347a4d141f5fe4a19914ebaa9deabc99da4d0493f550788aa037c84ea233d8ba2ecc43e7ae37535f7fe8c8621bdff52398e7bd730a373e7c7d1cb7276ce48a493ea7f68977ee9f722fd4e991066926997bea9de9feabd280996d2ef87ebd8b705a9b2cb652676545b2efb18bad499eefacf05b35fcaba46b65d30af8c6d9986792fc2fed030a377b30e571d1258308555b18c0416a8c01ab12f96b330c113abd91d48b725cfa6a3b3d83386319b021847e9a1678fbed3e91246e9e57c4a67a8a1ea7d23aa6d3c3c96946d3b5a3eb2d83eb6eff17db4e57832f31fd175a0a587a8e8fd92a454fe2c23d5a3e89d36447a0815223d84fa0c44a590e88516757e36bea7a0ee84bd2fa4438f1c8efa4c87fe2e69871e39d41d669af448a41a0afdda441289440a9178db01ed7d157512bdd3de0411b2842595ee06ec7b89742314f6da348ad6982ec43e7aa1253d6e34d0864af5de88484789729442b5266e3d6e5bd34917a16a77b5699bf2dedf15c5a834e5a6fb447f0ff5ab6172382ae522692a514149292799502927855ebae832531b824443fa23fd958efa9be2f9f08eaadca51016f3c623b6f4167a9f6d3968dbb1c35fad7937fdb34349f4124944daa154127ddb76903452a9542aed2022c110a534b1594a2844d9a6a4a4a4a4844ca2faa6783c843e0375a0a6e74061dc43e55b5a421f02635eea31eabd6ad33744018c23c95ba553f55efd48a4f7a7f2572a954aaf35a4a34acfa0167aaf5e9b6b136fe83d54ad21fd54ef8b7993e599ce42995db6af506617d025259d4bcc25d24b7fdb10a877955aa235a572d343671823035dfadc41db4337d1182deaa19f6ca42da16e3a5d521874ab37f46bdb517a0daa87664b97811365ba56aa773b9d5eda729c3292b42a942bab42d992e8cd8025fd6ac0924824ab92d9d353a294d62159d6afe783e7c3b3d6ab8e3102ba2899dae4263d7411851285427d075b540d6981fa4d8992e87d967414cd5a23d1d38d2d510bd827eda93e1f3c1e4237d1fba8b0a1cfc0cca4f566d537e3116b04f67b91ea137e628d1ea2d665605f1603d54fddaa563bab413c973e3cf5d005a3f092328efb43d61812d23751c8bb811600c07082a7ee9ab9bbbfadc765553a78852183b161d872f5ea2d3e1c30a3c91198d3640b198f34ccbd9e13b005f33e2330f1e1a8e031142e944cc18a1d74a1832c74900697d730cacaba304f07a24882288a28904481240a254a4a00058a19661085122544209148241289c486339ce10c422082104a104514258002c50c3390228a1b441145144890cc200a11122990209102491437401245143310c960063298c10c649063e3b3ecf19449ba8b154e77f16ac34e55e455d186270f478c5c280263ae0a070dc33d564770a048e285ce3b12c58b9cc845efbfae2272ac9e9c32c696f26a98582f66e30d216a4005d3602b440d94b00b66d9b617a6b55cb081c916cee4f775bd17c498ee0cbb30cc8a3a47b042c749439d2358917304243469ccba8ab82f0e805580443c9e67a5b8ae6335d72dac869430af738eab6a445c3a92fab816883e886898ae8f06d1dd15d32222c5e31cf8971a16ce1cc51861a545c63011ca6ed891869430533c586ae2ed8d354573f8ba0c46589b0b3f80010ebcd00258bbee6c4b111cfdeb185152a3616075c48f77e44161032184958ca2df2702cb8f0396b90d96f914606d9e2fd330dcf9078bf93f02c69ca00bfce9fec4cc4d2eee400fd14dc7156dac4082d878ce386a832f01763c4b53836954d3c6e561e53fb4855daa6f336c758d9e27531d35ae03ac9434d3ca9f4ea753ce0c8c3902bac0e7e4f41188f007379a5beb72153745b0f1ba324999c6fb8b7ffd8a5e0a81c71a0d039f12282dcd043a4fd400c75a073d2ba1607a2c144ccb42c1c42c14cccbf2f66bcb01fa582b8ac05a9103163483b59ab0d6ad5b4fccfb8c8886e9eb6a0b051364f9990782815dac330aa64823a288cb04b39fc94d873c77474477d6558209371d6dd1607ebe3d2553523b11d8b51a440af9209108ed1eed3738de33b8c334ac4b24ccea5d24984c30cbb296dc67b54d07b4d2be224cc3825128dc812e5e0c8162ad5b3098efd9af4d07b470878979f920c2d0c5c50281e5c4ccaa04e2c6e3aa96f5f96d47b35030331a1fdd594f9dbab3ce56a53beba7285a8d43acf51debcaeabd6003b4da8019e862dd93fd45d3ae0789d7ea55e1b1fa025daca3aca7c45aed4577d665c127155a2e986d9de1339c969e2ade7b3ff5af7e399229b18f5fbf7eeff2000e8c49d230fc8eb48d77ae212ce653f2562004288c148992350bb15ce11693df9fe521edab34fd38a63a5f2ec5ca5c5735a73c9de2613da297e8aedf0c65483391e978963b883714c10113299c50218d44216e823e9b9669db0734b99068442a611dc85e675533df48e9e8b6ef1960981374793022eede3f5b665d9ee912ec857d19e0ee5d08e8f2bed57bcdd3a9aaf7dca4b34b68f0867c5e7b71a9203ec13080c21cb822093b5724218ae52bb0e880e52c8c2444f8ae58b223451a72d0c4122bd6ab5ac218a1ecea5d4bc876785aa78fb2c630bb08d3e83791eeba8f9313dfef268dd3384db49186e125c02c9c4e5d7543d15d675ae6b9d6b32ad35d6bf4076ba666eff79b5d26a333d6b3accefc709299691cda49da461f4261f26f3b996c39be4a04b3218d54a3a7d6b1a02c033f794110e1a38877ad605ef601631e0e211e9d71c3e4eb9af374fafba53d903d0fccb6ac0436e8c0bef3274bf5bb3427baab2bcbbab530b15ffd0cfe4e69efb40f6e1786c93e76293bc3b28d07f6a6357df9ace97df192c2d8f017766e241e8f076bab9297f07c5f64bfdff5d9884109031d4f8c0f8b3104d3f4d35f668a02634a153ba4371efbf162e188de173b7a4cd230d73c31065dde4d947aa6e8ee3de23431b163877f4a445509a9921e95c81aa9e8ee4df19e1d51d6b10c636014e8f21e05fb7b8422098675167b974522cf9b90171c52c09ae261233c8c47669a6184319e462358af2dd678a5605e18254ac3c4bf18ffe053f16c478f4cd807471442e9eec9c858ec997c03b2da80d1e73d2898f29ebf5f937273cf208944fa0eb6a41ad262deded848efefb4a3f8f990e8c68ea80544d446dad0fc0ce428dce9eec12eba7b51de756951203ff841929db706340e862e92de0a897c65238451ba7bef969109ab6582d98f611c4fc7728cae3e3a804f1ae69d8948e141e23697bd7edb327fe3f16c56c1d6b18ef08df8fec58259fd4227f655f4f170a57d0dc3bedfcd76559969dc6891c863f4823ab0ed830dfb310da6f12c9cea091cb284481180708509a2e4608a1c3861790da3acac0b935aa0a93796e3d3594113e76ea9c5ec31d867a30d938f44769d5bae05c556d5667533badbfea295e96e86c87ce94e66c6ece00aa60cdf003157e724d8aae22e96d8aaaa9e98d615497062b75b1e7b65ac135824983be2b18f68cafa9c716471dbe1b1324c4356313f57e6f306c07f6a7f030de88fea063e1504d5b38ca357c672d939b80d617dfbfcde5e178c29fdfaedae97a80c74a9441374d56d3bc1dc3ee3332d23aab3deb963db42549ea3353f642cf61f323daebcf5d2305bd5305b054d1068cb110a519aeddc45af676be2ef467381ae3d03d1976e7e9bb566030db1dd42f2f9463fa3633eafde358cf6ea1ffa43bb6c97ed5eb499d59fbaab4e3ce2ad5a83d5d4ecae6adb5fccdf2904ebc8583216942b665738e3c4a1b3a735e57e8748ac0d091e3d3605bc1f32b6b3d6ba5e9af7d603f65feafdb22a58136bf44b773cfaefafd6704dd1bc54946c2d23f3745faec7dbcd08b5c0b9e2090cd6a0238215c47311e38bb19f80628c31c696f271d154e87a9f1518c6c9f3a1876c678877eb2c3c292b59c528636c2731c62a4619638c31c6782746ae370cb1909b99463fd3d843240e49395d917dcf5efff6df21c3c4bf5b0cf3eb4370cc85e01b9c8547c0c770ea0284822de25d5588571d99f22f3e7e107e9869fc58e484f8cb0f8f5d1c8410c24b0a462cccae23931f177c83db09dfe0e4a9b350dd081863d57672d50ba261275fb0f005ba74d005364c3c94f2ede4f514b0c8753bb1c0cb16beb0d28818017681c72e0e1ede89c788f5012bcc60c51366b0e2092bac806205142b72e005149de508238cf1578dddf58bf55e578cf4aae2bbe3b41aaee0c434de9947f5de749d15892e2b12896ea20ce745d412d1cb42aa75f73a1c52ccb40f8e118277341bcf7fe1988e27c75c237a4776740474e9ef741be6e897777270cf5a24fa4c8b2a92d03b54858c704831a71030c607e8097cb9723cf59ee655c9c950ecd5dd9019ad13647c287f19126def05a3308d1771a2287911a731a6f1feaeab8f710c73f4c1978601d8270017fbae14fb2ef762ce0e18ca60cacc0a6419cf77c5eed84f02d9cb6992051cfe9d3225e54bc344dbaff1c476cc0d9cb682073a96756c77e3b85356f1e1307938705aa04a418ead21051f04f485cab48d86cd5c9dfb335dc17e382f894cc24b120f7d4de8cbe9ae1f4ef73d5895e2bed8b6ea63018431026097fed5dd7f79491e4e77fd0b67c6fe6246a703f69eec0b8c42c62d1efe8c864955d6e34956222f47083bb0b1f2840c5fbd5a7691ec424077906fc40b46010a7b718e0c8ce9c30701ad88021316be056af61dc1de91ed2b06f35e3e94c4c05e7632f3ba067938faf0105ed59359f9802ef0c71d6df1b2deb6e309818058fdb8a3ed7af6ae20ba837f9b05ad3a0383f95e493564d6b9e5c214bfb2d112d1c367bc0727b498d74f173d6369df96438561666523b5f2952c634dc4048a2dec8b6299c90caa7082292cb59cc5098c681af68ce5726266df36eb07d005aecca03d1c4201713a46e631bf578d73c7cc7845fb09bb783c4fd8c5b31131e30149acf5cdd2ded683f4ce348b563b739426fbf68a6af506e96e3ef3d0ec918641f5ded879cfdf06e2334f2738c92eb71ed5b9bb4fbdd1569e73d70a6e3dac6fbdf5f054de7abc6fd7a62d99af3a56dde7f99cda9bd93db4aa4eafaa7b7ea2dc2e9ecf400fe54a89377f9fcdac9643fb4653d5391ad053d5e73f55a599ff68cf385a1d443fd7b4cf375a81280ddff9abfd730f4dcd4a533af7945669e6b9f34d07a5b673d75ed194e8a157cf4c94f4121dfdf3f150d24dd4f312c973df5669484f7d3e0ffafd7c3b47531f5029057ae89f97a876121d7da3a397687692c6483c51a5e19e027d5efb05559a79edfced598882ce51eddba4da2b0a7a8856e7e89c5ae5677908c0bef703daaa2ad1f63dd372803c2b35cd08f301a92e7f51be45df67a024f59051a36210bbb9afd930f4ebf2788e617d5de7aecfeba02bbbfeb9be5dd7ae67cfaeeb8911f0baaecfb4e8ded850bc4565f609a2b7b3d93f74a31abd97cdeafd95f63a467f64f04252fd6d3bb27e241416a2afa6f7c7a31549ac6afad166206e18ee072392f8b82129721cb10a79e9fe83ed8494e191114fcfde91d37ca719812e7245c6f957c378cea693f543c67b1b22abd77efacd117b65fc07efd8d32baa999e59f4c21ca0b6a80eac5ed36db2cf4021b6ba454114c82359a42ab31ee3bdeccbac478e625766d59aeaa46755a6acded88bd67ba351138954fadb72a4a00a29d4d72b4b24bafc27c7f848bb758d7b557b58d77abc63d79ed11b6d06aa345865eca61fe073d0673a01dab19abd545da3f1595653d86fd11476d02dacd260e7ce55f71d857dac97ce5b8fcfb15af3b16cda6ad5a6ede759e8a68faa8d07e921ee6e7b8c1abbdbeafbd77b1ba2aaf7b5655552abb4abda80bd0eb71c2dbf2ead5e7855a2ab8a0e45a2bf614455568f909eba933b54ba932dcf3889496a895b8e962f6141ffa3a07a63eb88b55ac2becb82ae7507d21ee9a7ff0e029db71ea0969bce55abd6b43c6ba91775ad9e31db42ab97c40d96bdba96b0395cd38e3d07caed02c2aed1cbfd7f4a3c6bfd75ada99e1d6e3c48cfb21b5b555cbdd993b0284669b06ad10cd4a2725056af109bdd64ca5a5ade424987d7c69a7e7a97b0a6577a356b3295684c5555896749871b0dc9927eb2b61ca63f71d25d163a394cdea799d0b4ea560e9f5feb1aed26507b93b8e5d0e295036d236d43b4f5148f0a1ca9e3d9aa9a680a25d1c94510adaa59cdabbb140fd0ab57b605462c47c1321647a8b03a32ed55adbb47d307cd0f1647925817cb58b0000e96371e59459243bd4487d54543e09617d137457792893662e5b1ea6c3fb72e8afd536d3bb003815f641f4d86c7088c99edf2de9da4e686794f5711e67d46ae6831ec71fbd48a8b0a7e31575e6d3a9e35bb2d2a4ccf57b8bbe78412a64684793ba78b843611bc5d17c9b25b163cd230b7bdb0f25232d1302c97514228ac7c0621e802a0a7fe431515209e0c0182012096e5645c46bd178096ab17742096e52ee3990c5acfd114144a06a5e7288cf73604e82b87441a66e5f27048c378e1011628338d2407106f39b87908332332ae5f1977792683521932cec9a8f71600979d8c7a0150a14b8545ec8545b833733ad47bb21c64421e1691285882b3c472076d39b8ac1fd41ae748f5c955058ff00d6e6969697916df13f3764e117b5dbe99f00db6f2f37911f68b1f8e7b0eb4993408648138509d1ca88522f1eca43948487b3be7ce1c6cf518b4abb48b50da4d9c360b4522da15aa04b4302a7767ba0a5502daec290ac4b2993c8a2a016d8ad4b48a5ede91cf3a47e7300d796d087347b4cc34b8df2e929dce26c3b47e2fad3b899dab0ca2d15a3f78c75a952587c037b2cbadded39580d6faa8a9268499d330dce53b8bec3254eff5d9a448c20ed1ea59176926da48e734936ed29da5d3d00d73fb5cc79b5c88be24ddc9148faac66acf087d4d4c0aa2cf89eee43f7493d7e84bc96ed239dd492ca6a75e324a1be655b9bb0ac74875b5c85a03730e653c20a394b0ab30c2146f053a506c73bf9630625764c6989788479c64773ac5783a35a9175e6ab7756a0d98b7b75affa2e2a4640a2186b7e5b042c0180af4a17c3656de29229ac1ca2a44734e1c9a604f8047d408e208cbea1bd1f4887e5fcdb3deebfdeca2471821017e12fb5743238e8042c8cc5ccd0858fb5ed71519308dd039a26124d0303afcc4c7fba180a10993292c63f18428efa3d37bef976bc284c947c618bbe35f7cfde27bb0f67b0f07d9fb186c601f8be52563b8a2a7e52564e8c018bc004f969790a18a152862197e5000cb4bc840054902fb2e7acb4bcac0821f2c2f2943132acd0829515821cb4ba08061c5f212284ab89690a109bb595e620615dc0821943760a01978547690a52c2f31c312ec4943595e62861d7bda362f5c2ff0e5084c7022084ec4202839c253c9087b035f983948b01c022d42a0e359d37c6fb6f855c564e52a3fff609798c61b63b2d32a67d5af5abd114c96ccf1067bd207f1f2c6286394ccdd49e620161e26e690f7da62b3e0f34e5b1dbe8636d2be7a696b98ef2c8438a367bc192d2a1aacfac73b02854d77376655320e6897fe05af59040fe61156f4d1508a27f3c34b6729e994c81d5491c5888d30beae53bff71e36eaaee3d9465ad92df631d77b594aee032b6240c407b2aa2e86f0d69fac0c23ac57ad465abdd5a50f0daf0ac76b3439f0228c94980c2603218410420821765955f8a15da04cabd48bd70097508507bc08029320e8bc7e1c77c03c7ba667da054c84c007377877f3903d9e0cb587c4b351d61aed025fba934ae6cb9377df8ece7b3eb670529f4e7744dc5e3e989a1a66bc9686f92af8cb3a2fd8b663fe05c66497f69255223cd7c585a7d32e97bb783a1a1a66ca6ad00898f39e9cefdaf5545a6094d7193278762223f3c3113641f0999d58e62ef89584fc98742ddd719f78dac0794312223021052640c0c19f1c734384074f904ce1091c60c20e70bc215064f2d5e5dbe2a5a4413479afbba1dcaa5a55f6c7c8c2f86ecd5495558d38a26df46512b8af6eadfad0edc556d7bab62c23f79396631ef30deb2d62ce56bf5cf58b31d3a8eafd31b2f2b1c6ee2447c8d64dd55515324da68b172e745c7c0bcb308bfee13463b65856e151c7cc4097fe7b8f263e1c714bc242cd46c631c3dddddd40809b110dd30bb0f03934c9be57122661e135106f2c338d9b775921a4c5848fddbd7798b297e5c34c7833045bc9eeee8b317959315e922586699eb8e5e8867992b1df2b5acc342233913f9889ad7690653c995fcbe41d331d828c6bcc2a34affcbb7522525c55f5ce753e7a1ac9bf575555d54c4fd387778dfa34b2d52dcbb21eaf9833261129208c8c6bcc8c99ab9786812772597fe93e56d38f97c7ead59d7c4809b3cf164258a5bc2c7ac54ce311e94e32e442a014f65bee5908f4646053ef891802d11cbba7d6c45fd6f31d6c4d1588a584e81eedd1f37ed1e51f8efc834244a2570928a24878aedda24800b12c90256c8d566da0c56e652f4423bdefda0874030402d5fbae3dd619f88004b1317222faa33b191fffb67f26f7f9640de4fd15611af2d5239886fcab12e84e7215c9ec4f9540bbc8476a019b7679f419794db48bfcb5ed78da3302ab228ec5fe9eb02f0616bb12d062bf8c052b7ff90910cb5a299aeb5508dc278222bab30e83197d1411c262c62bb12c91937ef261866498a5d2e74561ee21f67d87f9398991b78062096039470b1cdb7f5074f7badb49dbd062dec6d1b1cf3acfc6b056a2e453916c9fe9c681315b6d23a6db62fbeaee36d2ddbbc9481fe937d1479c68180b78de4ec030ccb7f34ef02ad57bfad46bd348b67fdefb47ff7cb66da42711ade9261eb4a64b879b0ed04fa75a2a7df40fe94dda6a4fd12e2fda8d320ede46b595f41694f055e10c55229d43067bbd1daedac0ce7aaf2d7e7e54249bf6e43909d24a22913864078a61dee7e45ac27cd242fa465a5a1ab26b74a31eed9322316d946d95dd254aa592e74dab5b4e70c284afeef1782a8fc7036d4dcaab5ba6ea01962fae679c65ef9ad5d4aa4f1237f6e6f3b9e6f9f09df39e49693cdf3cff98e6fc08b1335bc26403e7e7e6d9b68cfbe7291d1a76b69e47be31fab6c10da2b60dc2cd0243ac0d4421317d44e54dd4066e9ba669da1297f39aa6699aa669123302d3300dd32ef9d3bc24c76ddcc66d18ade130ec9e739cb6c15984dbb052a9b444896aa55249cb608c0758bef8e28b2f7098ce1d737a56411eda56ef12f0e2a19dbbab201253e5766166ceaec72d8785e454b9b9634c37516e972cc32233fd4620ef371ac0648053355d9bcf0cf4d93658fd43b72cfb67fb5c23a53ea06d4b850e7af68aa6b87f5e793c22b86d9f0ffda6b64a331f02fd43539f87be3d2bd1d14954247a361265483c9b9d8683dae7da070ac0be27a18908a28a60e1240defbd6e2c9cc021c628251653287259460210be8827888da31bf42ae3781288f568b481f6bdcb9a75c3bcb720cb32defa5c55952565f578e84b5ac5c7c37bc56ffa28dbf7aa57913e2b63ffd14ef17bc7c22316bed7c3b2af2b104b3273bccdb339de61ff463e29456b269838ddbd4097fe75cd793afd10077bb9623e2b2628dbaee359ecc3dd5c74f7840bbdd35d6098130d0913ab3009d498cc68652a1f35175c38d942ea7016b1ca260d03231966c5e9ae7fbdea2ebb37dbf61b1be365a46c3fb57a3cc8cfc099dea8e7925e5d58eb17e2bc74d75ca861de29bbb0fd87844ad79f11238c518918ac7c89462c8c95910c0719b73c1adf9af4224681696828cfbe1a63bcfe6cfac2fa62557a687ebedd739ea7d245e740678e21dd3a73898ea8885e8d5d663d590f613137ad7a0eb71db0d664157a3cf55ed2c69aeaf0d77553d51a7969675a5a59abc7437cd5e3e13d47c8d32af9842cc3300cc3304c8e36cf31ea7986611886611886719af478300fe6b9c7e339e6c130cce3c1300cc3eec112c01896b1ed4116cf177316e446d814e0cfc067558f48ae67925200085663bb74530008338d7bd1885c9580876578cb4b8debc2b8e1c532dd5f72667482d01122c7874ece7d2122a786cecccbfbbc278e4faa27b2f71e7cccba8e67afcf3457d452c27cbf6a8d1f5ef8f05c9580f605618928a2fae84e87799e6890710b8c575b22de7bef3d2b88f767bb1f7730c21cf225d21adbad12c4f08436123528b6df8e8f17fbb2f7de4ecb98dd1a3683f5be63efc542ebd539be9818e766f26262547e2ef33157e5e772af2c6c9f1fcc9b76f6b39859d983d2303d6ab1f06fa7bbf780097fdf8eed2ea0e448b961ee70e1c910baeb9883832450449ce8c4919e02df48bddf4ef80663616243a01cbb9339388871ed0832a761582a9149b04862fb5b3811c1d82466d15d3f20d142b60fd6d805d3e85b816fec7816f28d8c6fb0edcfcae752e65061de084552518469d9f987533921251139c48b28dd754c43777d1dcfbe4e49205869e7531894439039dd41c9505f3943d2a3928a25f3761228a213478830251530264259c96a4a17a11ce11d4905d3e8738750608ca402ba3421a1e01bf0bd52ef957d74d021d58430e51024150df3f725938659795f66d1302aefcb2d582eca52eaa5ef344289698851e291e844c4e96eae5c6e39542e573eba8ed74ef8c6b37d4aa54e77fd9ef2945a93423a9554c82174d767a132a7bbfe0a9530a86c426516d249aaca2dba234527baeb8853e391eefa0ff5471452d15d431cad8ad9920ad88619fa95928acb6699a4a2af8beabd5268887b8b7e4fa3dfd9385a57edbe28ef212ab71c5c8ddd61b7a8fc4527452276df4ba399a462f6cbeb023b769d37212d38a490afa8fcdb810f8abc34282821efa68aa738b4b48020e91f3ae7687e46ff843e29696eff7c46b5067ece9f7a239a3796744ec6ecf3b94a759376995ea5549e023aea30b87fce7d1b1dc2cfb96d561ad14317852a873ea25774fe01409f9fe904700fd5101693fb7609cf5112e99f9a0a1d5ef4ed1f9a0a7dfe13aa34a1500d3203397a45b742a07f4eaa212ce6a7dab4053d546b409fb546e59fbe5c8ddda5bed57b18f4469bf26ae3f1feb9dc68542a7cf64fbda81abb4ba9cf1eb7214c37559f4fb555db3f87a67a3760ab675b0eed55f5d9b2db407baaa767f074d23ebfb87abcb6699b1647cf46d4f49b101d9d1b8634a2a173b4a1cfa4a08fa869f450bdba0b556d54b56fdab5698e5e4ffb6822d1efe87cee1ce9f31da27adb8a3e97b0a57325caed12225d3439ae2af1ec87f419d5ed49dc58f8cf8786ce5111a5e1fef9d06d6a9eed23043eab699f81ef198dd643af8de563f42e11836472cb216d1a08fc6204414ebc6bf750ed1fd07c965534bb8756df288de755bdafc736b3cf3d14e4a95788e5eaf6ec235d741215d68a3d48175dd21ed9e733cfad23ccebba758409ef392b01533caabfbf57c7c2093b3686652c9ac0a4e65da22bd1b6c674cff58cbf4dcfb6d1a9a366fb685a56efe79eed1efae16ffccf79d28cd2cc6b9f2dfb08799b8e090a02da3edf6896c48dd5ae7d5e4a874d671ae5f79846e942ec7cd7db56e38649e2dd7791586288f54c0a44889dbce99849dc58cfb3d1fe49f1f07c7e7a6a0d7f0b12c4ce4f7aa79ddcfc462f4df52d6e9e6ff5d26cdbb5807db27ae437b99d0f8a93bb876654835767cfce67f56667be31390cfb3ca35a8d9fd062aff1bc6192d67852f3f29e633435ef3906aa48d06ce7cf4a935dbbc7539568eba1b988584fadf9fcdd24fae7187d43acb6bd21f6d17ffe361ed949ef8d467492673b6f3c442759f7d01bc45e9bde688a26bbe8d9454f08a23ba874cc16b5558e3a4523000004003314000028100c078422b160301e9296b90f14800c99aa5274541787410ca39031861862080008080000008080608011023c0a65d02d969001976e6a5355da80b189a8eb43e7769e705822ea65323676c4db6ddaa9a1b46cf2430c41c09125f976e5af07f9b3f0446bbd18856ce9baf243cb0d5456e32682048006a58d1daedb259f775a8c260cee071be071f186ff81f938473000a5d969435a9892cc1d35a671bb400f457ac40eb709f6c2c9b41f3d5848fc42e77b51cf57e0494a1151d30f05ae1a97891f8a7ea857b60f35a52cb143b5a701db80f59368aa19491b4bb227ef04999e8a64f7b7f8d479134f6c46c8f53a7de5d85156b10bcd924f3a3a03abed6da612102984b99876e4d72afae85a17adc67c6c1169fbb5b4b5d5e2e3b519d39f9f879a1449931f8af306ffd1bfc8677636b6571de673d3e15896be10a2e9c836acb7097e9a6ef0dae33b05db7af9161bfd83acdb6671e4cd8b9aa22c30f761b343edaa831947b6c178864178f34dc246abd1d2cd81b79406c7f52bf30b390276176ceefaff7ff8dec9ecfcf8cdf87055d10473c0688483105704ba6e8ca22a34dbfc262ce67149b61a5c1d2ae417f24bc4a1daa1e9c0bc7a31b9c04baf0e22f61d7972db5fd96e180c4dd8f5c08bab8a931e63f40c10090d95ec2988c6d750d8df2aecea7cddd225687a73eddfd5e4fcd0eec6250d6865a05f95120b88bdbc36505e6646345466f459f25fdbb9485ab7d3673b4d666f94c1bd7aae1f3f6d9cc5e848d85b565a381239e8c1008b520158eb068ea676dbb8f16073f63882e7c03e7c474488ec720f3a60c72ceebd582e73819818b742fcb61252e5dfc3f015bd9249d8c3395ff0a1ac645aecd1d83e6108eeade167c6530538f0486aa4086c9a5e7c06fbf2e7e53602b3342e48d1958d2dd64b644d36aa4dc033d7548a3a179c28c6f1bbe4cc3ae89eeba1f719ade81e8d9290859a4cea7aac80c8b3b3933e0785d21cc6ca7363e6c8d46353a74e3c288e9cbd31b6d0c6dc5840f9d50d5863cd376f368b8ed13b8d0d63530b80e5613f944b4a4f01282811b610445eae5b07e822f86fe8d21eeb6a6dc5d2e456d882479cccc36556ad42839de4556f2c6e25196f499dd24482b85ca56c6a18f0e38efe49907e5e334219ccc839bcff50a10068a8340b69d2e5c109e609cbb0f00139c3d52fc59b46ffd98774219818d160366a58ebd570871dbe958e6198505f2a9cc854d2cf36190dcd52ad2783fe5b36b6d60e65d7e3c2c6aa88ea8e81b46e2771cd673d6dc32232d93b2c5a40c06e1c4b9347aa21595f45322626241b4b66ae0113b9b10f19a393859ef04daf632191898440adb25ce39b79da2569c87412d8ece15172150187072c9621df2e4be6fce5b945f40e480e5b95ad343b1ef6dcf8e71a9bd3d6b6d6cb2d5ca77b6595196c53a3b2bfc1856a925c838ce55d8ab1273be04cb9062c0d55b4d16ab40e4bf7964e30eb2b64fc8957f844388304610d0e5e7308b6ece323adf16b6dbdb4bcdfca619b515981357a72b976a7a923407a40a9026ad01d0aa3124064dd12a451cc52aa973114d480a1bb7ae5a04649718d894ba43933290028146c975daa5f24c52ee8d8c87c84785fa366541d367a2381d6ba76a7b6eb9e4858b8051147da03ed0a89bacb877ab37803ac51438b9c3f99b4953e7e8d1fe20fe4fefc400d66eea4250c871c6fd3b3d4cdc4e9212c16a234ecf39f0713fb64435595d2e8e7ca3c163dbae23e2157f21914644b3e84d57d99a3417f47834461ccee898664cd4887f486231ca588321f39f91b1a1ddbcd4cd4364e8468e433922dd55d1831c2c63704bd1c5317eae21133ac98e32f012dd14e6a309867e8488ac58f104552a25726ae46b0a892c3056a0d33c33bd2f834c497581a95425d6023e0b5466998d053fb29f36ba97d1618992471c7647bc5fe1d64d61a0d549f11343488e05a8330dab4b86d8462546bac803ebb17a3609e6ac48b21828d710837db97ab1667adc1254ca14af18456daa0088ce9a74e525b7e21537d8d1c51366870686c9b55be3675bed926045a129d5a18bad45a45dde77a957f334c7263d0c5b6a39c030f91b375135d626f3261c817f902a158f6fd97b6f80a80dd9b2915dcbadb6e39d696d1cb510eb0cb06928a6fda8178bfa29dd3077d06b4d52a66c8051f2ae4ff683b09f000982bf709ff9584ea2f865f75420f8630b2192bb960ad3dcc0d9d9df0add727533ca7a7a1cd8803bb05612a7c0de7d084e8533e01f0d83bac708320ce24495b5bdba27273dfcaf905d95d710f5d4c174bb26c33cb6c71c464db8fe72df763cac340996d77f02d17460092ce021522fbdb54e71afe0383f13775d76670d8484586685c61fff78ea7668c1215e355198c86013ebdbb7afe576685f7f703b0aed1a2b886bb441c4dddd96c688b0c7e529b3a45e8ef141bbc0e68b10a03224e17016984354a32a9922e665192efec053416ae69a474b0a03be50a1b194594f81b13f87f93793575d29998439559bd3566e8002dcc683a015218ed911cd7d9a43205c5b1919a3124a83c4498084deb419f9e134a770de944fba2999e2f62b1c8bb6164e555c8879f728992d4bca5c347c6d72c1765fc1be517abb2410ff3e760d024a272452991327dff68438b2d50da502524e85ac551cbd4cc4a561e8cc3ecf4acebb91ec33451647a57e5b9fdca800e350e639afba8a6e1a8b8094f8d38574dc39b365ae147b54379f731489c403209341e9887251cd11d4cca66153ea0b5728951d482c7b3c1deb9114f81f13bbfe50f6c2ddc38a2d8d16bcfd73b7ae21f8d880a537e778bae92f43e3a2cf97edeb6f64db442efd720942f1fed41c12eab8c4dc5d22078c04961b31bcc4f5d1783d7325337c5a55b940c05e3d13528ab9d08e2a2e9e726d2447d2efa903284057456c59bdb84a692594a1475fa544ecc7aca4e7f7f95dc34ed4f604734c72f5e37c4913b9cf7a63a5c9ab3ff40e3f72cf48a1020b723e8c0ed858a7728dcd72f3d81b4b04ed7352c21f44c52bcdb49c81333dd9c1caf0e899fc66fd7534ba59495feb80c8ef409509aa6ad76d435f496288cf98b1d04d82b016bb54ece34d52ab2007072b42f519d0149efdc434a5e714c90e8ef91c3441debc0c3ce8728ed951a3eef9a89a047304c406ea4e2b4774041a7cec199d3967131b8b18ea6f3080bf24e492fecb7e1ea3816791d594f277d584745bace2efd760da8d34130671e63c0db2c44bf883a08a61c04143169a4d4de422c411595f8464fa435b58102ed03c5fb297ac614dfeca9e6272544665a64d13ac30fd8d54669b9a498bd9dbc1d1a11ea083b34277d47852d2a59bb8769de18484edf1393bbcf4cecb91fe4028255924e100a7ed0a53442410128bb93621b5e046342e82ee29537c674b0a5e833d7b999f85c620d718dd90847d2718af7bc477a42f3278cd738f4c06251a94a0cc0fa158ff43c9452fbaf2418a90a9648de83d74639e8afc0ccdffcb5e2fe8b95688551bc16233dc421e695c37880b3c2da4f7af40b7aacdf63e959fc1e3d62c223f230530f0fcfa1f127b3d1ebc34eaa0c537aa45de8e12f1d41d58ad0ab39c984d2be81258ba85fdc9093d551a4f0c07906dd293d2201891646d20929b8d293f82b4b8ff31bd534e8f4255d90dd23e4ce05542b400cb8c024010dfe477ef68bb3667227c9edf11c8d97305d4aadae798c3c576a56db465fa73cae82854ad9303dbb33d950aebfdd6263d48b6e5406ef6dce72cce4a5864e0edf0ad1497fbae8c881fb1253c477713794454e619aa3ba7c7a5ccf861e1b6f93948aa7c0cb4be569cf714268cf6c3702274b9e4e241e0fff87bbb09898234d23df7cbbb4a701e612190d632dc11dc923785ff693ef6b6803eed918ef65c9035b5aec6a9c33087f8e158532798a1c7e77f200c6e1c0cb2a46c1752ec17b6159f4eca6ce94b6cb8352f5b96e868641b6214205c2b761eb460ea1acd9cdaf9927c7e5a223d960742af4fdc41ca02740728d0a7e325772c1d07f626675322360afda936af020fc560513fcf96b3edbd465f5c7b467ac678d01114b66f4bdea04ed859ab55a066f981225761659975c1c15feb1043c598cabbd570c05b5dec54f0ae898e930aeaa15668c14c4346c7a8dcc78382a25d374a216eab0482269631aeee4519df4565de7b2bf9899dbaa7630b6394dd35f10421a17f21c0f6be25e5cbe67898700dcc7a431d836cf3095d02cae9b07e5708cfdd4526dcbe649e69d4744fc1512f93bed4358ee109ec99a709f3e3ce532f21e97bcf1ff1fda36264a161e7505faebf55efd89c6061fd4edc8386fba25225e1aeed4bac8c7468be199e36542cb7370a1cf37fe7643d8d287004b3374f14d8953c71214f8b03979521a8ed69887d32ad177c076064a7e6a0f69485b5ed33b19a09809766e49f0868b22bd2b7b012b73a25cf043d6cf52379c9ad02c636231f33ca7d9d54eed710a6f5110bcc8b0b60aa3b4a087ab54c0c138774ba9d60a7e6eacb1ee3c3e8df570fea9a70df9b86ef6912dfaf7ae0660ef7cbecddb0abf2b5bf27d4c9881a48586440e449b6102df65b35f8d15951f44b05bf683413adb2fcb99c75a27c3aca4bc2af4f695432bbd5948ea7d73416f896c7f7dd1f86d26960c5823a4fb3a9ad8e559019eae6f849f7c79d2b394ce24c0efe732c183e27ac4214c0f0745a1100736620b9127a0864dc4b805bbbc679ccd2ee2a3127c7a3a5dce6b6a59a1e10fded4bd6c3e59bb74e6a0bd8a15d825461329b4bb72d9cd2bd71a21a1bda81e288c85de5fd09289e10cef83ca0501f8c59f348d3c67b01e60aa174f435fcfa89ef82cc3140bbfd8429c433038cece94206f7661049d987021545584fc2a8e25031eecd827bd0bd2cc936c04607effd9c4076cc238bd5dcb1ea63eeca06c3df03df864ec0481abd17dcf2d020f850ca891534095e9d8a4bd11aec268e534fc61d4dc832d5e4fbdaa9878b7e8d86da37e2a46b1496b23a7d7c074f17014742e0759963c4305aed9a5509bc1f180fcdad2e967554f815fb9c1b81b3d12032c16ba210c26bdccdc36961cc9f14fbb1913d62d8515fb8a7539ea33811043f88da3d6a4a8b452197ae09f812bd7877fd9cc3ee1f7748499d4916bbd3206718dab1150af31e187111a93ac2a2664ba32f978533903f72f596b6f51bb50f32679d7c8d6e7de3d2de7b7d4722bcd1429e496818273ce1db87ccc3d002d170b3ef3b1dc412afc0c644319506fa188f225d02e4749e555c99903467b0f3b3b3b77616b11056473694c9b0c260f818c2a2ef2e746e618347317dabead1ec4018756bdf9516d7b28b2cb90086083e919f9c800551cd9dd8f886a863407c682983ab674adcb4bcde6087e8c228ac49a8cb0d80b45e0ef46f115bd4e162cdbf5bdc71261f38d3fb70bbb476ba8a77b31a996a76dae0806322849daf5c9fc5bb081860d3df7507e5429c837909c67f271a027a63b22124d491f5f3e37fa47277bdd872255b20c995b55a57f2877cab487b9a9a9b4b0e586f609a5a5af16ed7383e17115602d2eb94efa169c610a919949bde683224eddea5102f4bedd6486b0901fb9478e7345b0b0a45ece58dbc1bc7e42cbb37f6b2f0fdada5571d4972c57d9c576215dc98729085a4ba2a0f6ab764b951d904f8424de6fa59ead9e4cade30b293d1282633f48a9b2033985bc273693c3049a775613ae7e45db11bb186a92810148052f34436fe30465b1ca571cf2725079bbd4622475d1c31f0f60e674fd83173c02b0202a784f9d4e99aecd1d93466bef78845da65f60d2f391394eef4a7760ff45a4ea9ca081e200a63dbf43f5cdea22a509660ea8bde3ac066380f197ac2b5f7517654f3a27f2a2474f48a85f6299e114bfeba6110b10b32a4f49d6b3a0e1ce13c2a46134d8f3e49a7e7b6ec4f3a9b8ca056f5c612759b774e52a4c16bc2386cbe011c226f43a098e1e03418a033229f612fbfbee3c561716d4f158236b1d899fdaf859b1500c140df3410dcb848ee39d7c50cd5b479454b1f0bf1577927b2ff247dfc3818fd07d30bfb24bdf17711bb45a71ae8d887a69765794fdbbe878e8ba7ed293b4211de1c63d2ba655c42a4ecfb0edb0c0269a2775a5af7356f5f4a6f916338ba60b780fd029920dda678eb7e54bf15458640d379981b42154817f66bf44d84c1bbc9363f5ffbd68dced91aebe8f4b632bafc8427c5dbef4d594d7ec60ab2995f178a68a0e777bc9f415d4db8239fc7c1cfba4065f0489f5491c3de833a5aa700170cfa429e095c9541a182118e1203c961957fc27cd90bc7b80373df6527a728f5f665cf05819a9868c6f0e13e4153eaeab2e7bf084f8c485f1855b6a5664843b0d4c2419f16ac5a5bd5c7189d3b7b4797d75713801dd756b01052f4c0951881e0ee80b4483c971f748f6119278e2089d4ad6522f1cf0e077079e6e9712631c2eabc32c938d62dc67e5ed0924b20842ba6342ebc6826e08e285973bc2625e4059e340888ad4dacdcc718159e3b5aa14465576e7bacf23b774fa55e627697028174329251b9082e8359ff4b53ebc992739efe04d09e26a3594a4d60e0ae18a10850689742c5d5c255753f794bc2146ebea8678c4d52789f8ae98980e20159545c49fe8c64ee50dd583d9cafa364e4880b663bf84a1a507a21759bbbbd277647f526a7cb9758b252772a6c195353c15a3b05f57b36a6122bff21244208a3c04edff3a9e5af50f8967667c1493c00bf908361ba7a86e4d235496837ec33ae05bfd3a665c8d78b1a8567eb89ae64a5348044c7cc4c0556f0b680e6604f041621e1fffe8608adc27624c4e7823fecf0c07e1db83a313a235bc30b564108d31f2ed6df677277f9947595136b42296f2a938b01dedfa4a282e051d6fc44e3c282074308ac65539943053bd64ee9533e65b7fd7ad4c60749b7d61515fed7ccf325726a72ac148900263e4e981286806cd1b929213ab928c6c6cf1be8476dacde3378617a8715d1b33f6bf327d8f112a9ebd1d0cfe907b846220e0c91b02f200ab0ec5f95fed024f420daffb9bf8389b1280b1449facf55dcd6cf301588e24db6d9fa888c9f35f740508b42a7d0ddbbdd2d3f336da9a9b9eb788c0cf243eb8c9903a3c1c25af556850e67f04d6937065180309d16e1d1a8d191f19e69b47659c55e85544c92072b093fcb060674898da4cbbb991aa52bcbcb7af484d75dc4bfd6b8b6693d4d7127ecffbec2575d0f9fc17dc19d3e990f90596d00eb42818b0801bda5be2f6153c04ac74a554f94a915f76e147fdcbd6d28e022b8918ca4a88e06402c1afcffab1371fc9dd002d2d67ab64a45039cb30e429f6b532f211ab961ddfd1b608d32bae6ecd0ae7a806673d02b07d1fb5741d4721b191cbea2325b32f5919f7ee313c91bf6acf8951d428529bd5f582824e4c365e1b854c991606503126ae79aa98711ece67b61a9ecb3c23e6481d90b806259fd73130d80e4b499131f3980475389ad167a27e21da3a28406fb1765ff8b168ee27303c43b77d9a2b52f2a597f9162fabe51f75574833baf7120dc7c8cd5f519f8cd28b283d3fe2696457009de054bd697897585baa2298c4a4884d61b2756db043930353766b90d124a7b808cfd22861d5201ca4feba2467bbd3be6bb3dfd62dbf5b541d50c93f0fc3ccc6e472c29f00c49e4aae0891728aa80f500001c08b1b46989da08f311fcec4531c01f687de4d1143b2b255688d87ae6a3a0b042c2843bdfe7343f16f7d8452ad472c8964145899b55263267dbc47d445b5edb9ceed7ea56bcf6711d3017c0b7f8b5dfb102b546a7242d8d88c55edc93724b7ff8e6e32792588022e7e8a321f20ba2c1b67a517661d6ec171c504066fe0eb731724b4df700155951855a3b728614562432532ce33a9ce43e219f80d7e1341a28109d0d2c0f0119b8e1af8a5ac069e5dd7c0d1181b780b6e04179703eca454480b0d586b5b77091ddcc030d681bece0dfc04ad7297ab71cf887d131045824bf6bd1946bcd2a41bb8f5e1751025a34d81bf2bba129128955c0bf331dcfc7a90ca2d92d8ab22c604b2111e803c720ba30dffc278ed6d00bdc85f8e551b1967103902652ad5d44089013b04c935590a88c4fd4f9fca8e329c28cdf545abd775088fe04253532ff4534324a076a18d3b61f99d14c068dba0e0633ae22771dac45c45fa43249681703652f61e59aec5b120a0e4ac31c55672ef6a85cb534f1d48717ae659aad3ae37208afc9b6d25ff69a35e7f6140ad1f8bc4590df40b075b0d1030886ef81bc12449c72d3bb4fcad0e958f69cb7d429265ab56e54e508b6c9d23082c506132e98b350658f41efa142708f3759268d96ad7275bf0098e4bb9d6653c3f7cc2da4b0a46639a617562e07ce026128aa551892be641dad96696cc78e2263258465c31231a02bbdb668ef82657a110369e2843067eaf01e3ec8aec23a4c5329f815dee2a2898ca213f3db97a5931df14f01f8ae1e191e33a752799605247eacf3238baf2e1dfc74ced2ef76c61cd23435e292050c02ae5f4a0417355192e3514786c7e98402bf5d3769807339db0344430be5693072a46623cc13a097a40b71433b3d211e2b1020695d679ae9a4ef990eaebf6a1bf6954355019e912451e9b30efb3df39a76f2e5346d58ace1534e13927315e62e65bf6d1d958727c1ac54c0c59f386017c3e4adf00ba1acde14f1eb10b2f3089c5112ddcb0acbf4b51075ac946ad50902374637d8661a4f4abfd59192928d06df0e65ee6077c2116fd393ac41766577b90a146b9aa64443f286bc2b03c8a0177e378eb0ec27ebe8927e8f0c25e867df1255d9decce711e58c71726b4d0be6005de34a8086644a3a8aee899143aed9c4130a33910b6d6e7742aa5fc408db2aeb78daf00c615dc97d6816d1a65313cc58f1c58b359b2f5b615ae3085e67ae965c1bc5b73715a4e9e228e79aa6a7b057f2e4f11f035353273240386a2d7efabb13ec995c72cabd144a85c65615f815066a02ba3434f978946cd5488458699a095634ee8f2f34279132385854663a42bef99d2295ad107fd69e47fd8e792fc4bfdae5bf26dad7800db3890f0e0c66feaf1640d07245985a322b785736e7238dfc51cd5a103aace8c3a7498d7f8de500d3ea5027b1c46cc3ed666fb70d067eca9966b9ccfb0c1ac5411c379c8fdefaeca2e99a83b4a36d2341b74b0a6c86a4067c4efd84f0320c41e74ef6a7998bdc19d0c51675795cd2b3d56d59fc11c63c9b66db62c0e3e7fe412cbb477e99b05de6a7edb2703b7e6ce0b0abfa5ec2cc1783063ef3f0566d17f792da60d74a304e7997bc30b1216c1de3bf0be60bd6b08e84f18b05fda457e5a31179d3c667b61d028324ff6ea12a1a56cb313636c148c7a77f33958d6f527b50f5fcc4a0d1fc618c806255563c98e1e1a8eaf869aec2ef8e00de6960c882938cb07b215cac948f22925a43432924f8dd93c970f05958f80ddd3245001d3722a0909f4c0968c5590bccf89513c7c2476678afc2127f86db034c62302317f52be23429cd6949737c2a5dd7bcb80170bf42ca644183b5a641ba49aa1e72400ddbd7bd258654eba337d49118d61de2d19b15466dcc38b2da403b4b338260e072308c57d565f581d648c6a9afd103e0d7fe618d012d5379de5438df454d1345c7d4a7ad2afa69b802ed4d50f4c64a5c4283b1a8bd05811c29147e6eabef30e1c7972fc906da0ba2af204da9c6caa63081450a4020ca625f0a666716133cf62026e7930acf828c0d343602addb8c3f8c13a6e2a16193d9992c738ba5d1b05215d4f828ae3fc2651dcf0c48bec97000d9121d9af7d5c4209f8d437ee28872a0110a48d33d3a90cf227628215babd331a2a5f2f52f0de7fd8d937a7b40002cd53e691d8a7dda13a62b941e226db514cc72002ed762d6a640736f177a1bb1aa44c9785bb4c97e4c92e36b04111a89e47178c6f50783aecc6801db9fbea0b93c0fac7dd0ef115c843feca11e67f5cd1fb9aa7bc8b4ef0b17bebc8eb6f78ec6246bcc52be115ba35dd3384e221f229964ce822ab93b5d10952079c417ba0f953cb3dea5cc378c77dd368fc8453a88dce3c76d302925916e1260de85e755f42987867a6c1356b58057a919efb582a80b2700a8596eb59dc58565a2d420eb568f81270e4bc7575bb7e36d1944b71ec7d0cfe09ef33d6262768d622baf61a70dd6087c48ca97dd0dbf63fd68f8edfa6d3f681b464b9019881c049b0c0f2c1956484dd79c5ecebbb8c140cc4e8c93db332fd3702293c2442ba3cd457872984d59804edceeeb75075017ca836194c57552fa815aca578de9bee41db02049d0d10b3d47d96356db405d4d26258cfc899f4f25ee00f3cb3822e15c90b3c2297bdfc99289bfdcd109f3566fc5ccbf7e2f6527b6fc58fcb0104c43fd77ba94c4445b6853eb7f93c01ec73855d0301ac9e698de614602dd6f42c7a40fae368e273a8ca29eb235a6228eacb9414c08fd6f1a08f71599f91033840d06c5d563d86c1f59aa65fb0b4349e8e705cf003e4118c393c1e31fb3885a0f5ef7702e6c9955bd796e06446f41625262dc229bf9929453f048e97e8f1c5e790c50df80e1124ce97bd84edd4f35db2abcb1d94e8eb880dfc43e307b3e709c1cc3822bc6c2371485b9054e629a1679aa2637e008488fd44bb56a01a7047226a6838ca15485368224965156e76c8a48cdbc39841ee2786a40a46e60175145006ceac066cf596770bb7c7deccd28e0de8a704a7d08a3cb6a2561bfc62c41ce1deed87edcfc35324428cac89cd537984605579880fff50923f02a833d95994d501cf5c69465ce3dd3438e4ed9ffd7fe446e1c10b9ed8575344f2c8408e258c229d027a6a97c6a08681a5f24c45078d2d487196ed256e623836486bab0387cd6b86099a384d24b7883984107d812f7781e2b66391d1f32f079901e62b045fdfd3f9d60713924a766031677d5e1687b1df33587a633e54aa3e1f2fe58bc6d4c06d1c6640c1655f3ccfc4e9fe116c48484d5c3afa7336ad21d79a010e58ee1b814bc68dac6c233927d18077d9c7787a26f8139e670c1978c24584024989b51cb66ea680fba7b18536d1be98172faeaee216aa496e8ae3473786b948b0d31b0e7a2e5b648c5f6fb2b323ba667392dc3a29b6636805ee4e41212428e81d72909048dca8524d6d57f18968cd8dd197d6d489461d6d7317ea51081126a2ef693f65b0f0e0616773002da045c0ecf01d657035db5d35322dc8a7ef510b8def6f952b29688f60141621256f2ef2b79aad94d3a75a8494d17d36ace3e753d357cdc5fa093cef7c19f92febc4274e42b07f71abc64274af5557f37438e4013e6096499d459ec707e9011308ecfb454a6413648669c594095834f9f99a28fb78ab87ab002f781bbbd7f9518732a2cd5c805eaa3bd4662250f01a60041197bc983f11c1c35a83851c50ab9a9bf505e984b01b4b3b57714532430e276998e1cf00671a8546d0d6ad1d9c0f568fea82f35753b1172f3e2af2f4b21976cc4ef6bb70ab7521617c95010dc8c87a12a53ac3389f23aca2f5db94d799ce79f661c41e1708ae2c1cca2611d4642c768c384306b09a85c541f703674d23c32de4a1968c718a5f880129e44d36ff950cff43737f9a074c7714425281ac24c2704d05db1c14082d825e234ef639fea6f5fcc1398cb92452d3344648b8f3b73b6f51f27d887d4d297599654b1f151635529b0ae4471d9ab36a06c34e1ee95933871ea7ee6c0c6944ab9d7f6a81a7cc22c9776c4a8dccb22696a3c23b559cc08354f9106fbcd141ea02d63c965df2a3cfcdb7e8398d0d33b980c225224d7b60634f37de7004d78a530b4ae2fdaabda26d7a3ecda44133e976960a6e469b912d8f91819fcccc00b526e8a63960e60a0841d0d9b9bafc812bb53708b6d5d51656ceee3adf859b38dcd699ff2f232104995a642bf16c5f9e135f5e6c1eb2794634896220461f92f23d256ef92db06f8c3e164a18992998d65fb0177d4fdd6e222b7c2cc6241b7d84622659ddd7cb6935dfc582daa13984e13c1b26881eeb41be47f812f2818c51d505e945e133ab319a2f6e82f8760b4f652b8850b9dbd49e73f37b47a64868932bd8479a6bd268a0d7e23c458ac248671e55630159786851733aba9b5239c7ab55187c4be8859cb43e35f89ecbe80efdacd9cf190b950e7daf2c5134fb34bae7edbb5278b296626b4b0b0e77f1ef8748ffffcd3181eafc6a64970dc87158408a0799a10685beb5a828db8f196429d8e951ec8ab558104bb9c5b564cdc209f83303c9f5f3a93f3f6c33b38b837e9e3e89051c03920b7314cabbb011a2aa76a51c4b7fa0ab9199b537641f0b27a3aa4b4646a98beec959510694a2e7e549dfc840eaeaf955d56f5a8bff91e5fa146114dddb0ff6d450d4fa1139da8a380d2b3bde46849563bd16560f03a7e49c47c38048e8ebb682b318508e63025b3c80223fe4e2d8f91fe8886e90e2e0a44b9bf94994821e37f99966223e8e0cac0ec461eee4c170a0e7040a3581ed718bc870285ebcd6807c9d1a30263a3aa24de1bdb88c67e0a6e30192d3cacba52f0beaf42c4cef244e489a332a0ebd3e7fa9893395e989a666ea808b877e4d3fc3e1be4ff20c7298820d6c367e4e09a523e64cc81db1ee8281f41bd154769e006c98acd34804f50ec29a412e21db69a8e1c14fa5cb6217c902f3c6dca615d9ea31044108e3938044a3db5094868f95a04a4c78b1b6f7a10581a62f09c9f7b2e9c8b53951df3838c51ffce34813bc491ca1ef9aa0333d2e92e82490f0ad4be553bbbbd4731726f819ce4f2f034521c30082b68e36df8dc40b0344ef6dd151b4e08cc9b823a61b484c7556ccc2a12366ee8a0c29e7b1b10c4a3bc062a4e7bcd9597e21669150e5a2999afe72f301d60be236f45363d3ba8d6b984515522c7c412512c89eb125a522c8a6290b28c115fa045ee83ab970246dc438dbe858057494af4816df6e19d7eab0bcb5673089e715751c2cc9ddba0b4d04d7abccf525c44fc074fc29030eca3be5954ff84c8b48a193e85ad408927c4653a70d9d3ed9d84afb82bab6d53068f1c525e775e21b4a44f2301b16266d48f76261dc3588ea4ee6e450de517f31d3a6010d54e2a3a0c8c023d0a5d34012f13b0d011e41a6bee24d9f346a3875b7ee0a55699355e438095f06d69c14b7642cc7158ba8a198b4059fb1abbe204f075ca0ce6e495c0a47895b2102e2b229e82b054f8b0247bd5372c4a6c5c9d220ed0de0e32810016b3a08913881cadd8f3461e88d781ceb16e707e24ae1c14220f8a2c54d766cc1024bf9fde5a2732f0ba43b08470846966c8c313f550016e985c032162127b7c96b3b10f0af0cbf51cc209e180b355c67dc57627de8636d8cc2e14a09e525101048f7cb0055720252b3f74a41d22c982dac63a7f52c977753d76b687bb448ececae725d440e126ff7a4cdce19b408345756c0eb36cb10a6d07947ad2dadf88d1c06e78f4745e3fb5e9a68aeedb34d3c59f8f322281bb27892815489c190f874a0eb5de38a69c7ac086e7cfbf4909528aedf1aa5ba607779256e5d480116a2451247193aaa718d0af322aba4761a2671169dbe7fc1810bd09222a7324412e7a74f3afbe887098afe48b3ca0aecb14b2c23f6368b24929e584ee0cff387a49aaaef45531a9ad1cc16e143cc61df5604c190d74db8d612cc51a5f76306279906850465dbeb6508bd149120f5cdd5c19b1e3eb542d3b280e9d8f36e8975b5dcc1d760d07a4f90cbd79b99b2c7168603823aef625f9524ac5391f6ac7bc55b095c11d72a1f7bc7b05628c2fac0100740d6ad823369554c469617cd2fd8de5965d704715633a6cf2ff5c8e9d26c07c6b9e32eb06c9a45613851aca560a56fdaa5f93380bb1b98f25c9ff3ad7e1f08acb520c1d86208684975372113c9513a02c2755f477c2268f4f20a78ded932d19cece648eece84f50208d76c7186715cea163055a3e176f4c9dc44de5f3bc2f62cf1db50dcb712a146e4f7b3bd119ede157199cb1389e4139a0c635614c966d7d4109f242b76c4a366f80cd1ea0068b216d59ac99430fce1a41b585d196f6e3e5109e86ccc208417fa0a39d6f9f7ef578cf7204628d1979724cbaaebf9ba06b9ec6c1539365e6091cf8b8e081bab6cbd630072709e53b705f5c3fc2e7a6ece46748197cd335aa64fb83961c3e4eb0632ce535592b4472c3e1dbc8b4d76ea3ee4a664eebd1e178c61b6673e45aad933cc8a880753028d28f641d0c2ecdac688322f627ce42e524c5c60da14157c45a338afc7ca3a3e5645fe4f9fd4cfc9c43f733d848582fa7f78a91a1032218b62c17600897ca0bfcf9e64c5f2ad46383103d182ac7570b85f44fd8a8c800cf68df6d24e0dc9d092cff68986b5500dcb8bb8e0ee252739d8e0b244ca4f0d13a15f85ffa2cf2a1c845f9e55a2514569e0795e9026c4794ed33445c37139f5abf03c81603f95a96bed807ac44ec0a5f742a6d717c32940fd344fb0a40e138d1733353a2c1301ee1f440f90c1f9971cb708dbe36b84f62b998304aaf554e062d3634ae512d0f5ef8574288103dd79aa5473dedef010b0270049afbe5e9ac0937ecd52dbaa79b631da3489663a1c28db117b9ae384b459401f1af9da401ac4f309c4e0928733f805a500119ea7c6ab77843a677319d69b02bba2e744f5562e242066c28649e3f575fa230b290585f243d10b8c562728e1d5dbb58382d1a81360a110c5aa40e6213ae112eb6f85b2b24d255c34369c81b32042af28009ef1067ecaca1e1b4bd4ea136e50526a2a22c102f68e25505436b37cd19ddeef25bb27faa1b2181bf602a6e7f350e14b79bacac13b28010275c57b77666d2691066ed89fbda4c720f0437bd97de721150d4bc6940a16342520961c7d0ee33d454b3c1f561375a41ac0f05c0f6ad87a64680f8ae6662e603d68c79dc8a4a8b2944d5f7ff824542d63a5390aa1c94cc7af61255afb1270a8eec03c2beae267ffa909ad123e6f9af58c930480099dc3f703b6a479187eb91f99faff240da3e1012541c7a80a24a33778eca4edf0836adb56b42cbad2beef181f326b197068d342ee213ba199cb3484c592955e278b6cc14e6f218e241a4fdb901741264ad981a83ccb9cf50c2e4531730bfdab42411637a9de7b09cc11a69621008fe9aa20c9c52ff45706f1a6168ad60eaedceeef42f06dc5c73ace822a672ed269262df5fca887e705ae317345faee0ba476d000994b957a33cf2856098b8c9c2deb3fdd399af4a411a11ccdd281157599fcda7b2fddd3b24b14e22b00953628058c828741ae5aec7167f78208d105f8406ad7d4bd4ce4befdb6290e1f387989e3ef7c300173b656f9b0d621c8fc0fdef9ea7b6d4652058e6eadab1e256ba0e9c8a67b44f6a62f0fd06dab5692542f9ab70f13a4bb9955ebdc203dd6d87426d61dc4af0dcb95fa1dbe95c9b8f880f365ca6562ce47a54a7509523810c10d3c7a4979c233983f4ff7a249d394316c0110f28208db2ce9de82026c8d8ae0dd3c858679f4303b1a15cdbe32b12de1b7a00f97ca77bf18bd59adc56cb52e5ca4d8a2bbd4c77f89ea9269c477f42580ee5102e9caf150831df12f554352ae9e4f04134ac22c2f87093bc901c97434019eb53abf102948adaee65a0ab00e2b1394c2f4b409be34a85dbc3de909c32ba9691a5a49445a7b64d8e3b42c4713d64638d2cc4f2a4d84755b21db3326a9099b3aca131121d4e6d97c1942d2ece74758cc36d037b5a6fd4ea3a6cc504300c2c66a765b6a321f05160a1d834f51fae2a3fc7bc8e393e0c59da4024d5e25558c04f9ce5a112f2a310b477f7f48ba069c42e81aae73df4cd3267d69103805b4d6c9ebf73c3ca74c7aff36ffd86370de3a47e2b8c74f1e02191ed2dc62b04551bc024508236bdb1165c9cf1a59b201cbe26d7ac6dfba06347a0e0884f50d5ecc8548b76582015f6e500c924ab2ff3efd0fc9fbd53a673150774ef39e8f04a411cf406a6a1c062eeeecbe839b1f2f79c187a1c39b6f5bfacdc1e0eb8e896b11203818ba3b134014178f1376c818a849ba6dbd861b5672f25a48b965ca35eb42eb0e37b5efab3506632be093a088c966246aa37ecd1023eb8ada8b72793d6861c8a19cc41fae2dd4089ccf427b25c6913dcf5f72a57ac649105c4382300cb03a61f6cf535a264773ea7efde961c9242fe45b01943035b7a85c7b246cfd69af1748a69e512594cc3c77ea1a11479572872b9a8bb50936cae415bf5daf27979635eb9ebc23eded6f1e0cd6c02b725f6aa80513667b100180281659be1facff678aa8ff7757c90bfb0369ac59fbf3b8a20845c357de73e4b37e63705367a69f971355a886666eaf97cd08d7d3d7774806ba6c99c5e5b897b29cb4a4fc87157bf5e899a52623ef45cf59c929e5527896d3d30b4217ba9459dd6b668f5cbdb04202cc671864142b2496bbe77a5ccc70a59c37a07259bbfb56a434e77a47c08396f99e44a96de26ebd7fe536d2b983bb34d30a925b9080f21b5f239bdf4b5bac9aa84b338fad85c95bb357cdb0f426386839c1e2986568a8714433c0c1a6fc060df60dfed6178284d8e606d45f2e3ca0a5bce7c160ec1d961bad436b78b41b8578e0609fb297033fab6f459d292f43631364d3197cc4a9a95b48c0b90a314ca0dbd4a8d3d8070ce8d34b131978348f7e9eca87f6390b519c9e6b8ad0b7edce64eec85bdb362e3ce29a680aa8c9f802acf345a345a2b5575d90835c545ee048231b0e01e2a88b16e6b846fe9ac7b29c16c69033ecec94376e108c6b0761184e55f0a17876cc7c69e21c49cdd1346e59ada77ba5c992936525fc09148eb82462832b9e63f13b8632cb8bab20033da1e38c33c82d55330696960854ccb3cd873b08c799ba6de87274f268d360a5d389bd31b4c69848305e6dc41471ecc43201fc4ff769933f4f6ee66f188e16b56142f385ee558490c368f02e07a6c8b34e5a0e9dc491967bda2c00654c8dbd591b0cf7f84e3a2fcf4204394a2090ce16583cde9d8853f30da192c35e38299b11d8583059fc8a20a00a95caa0e97948e3ed9013c13ed0240434d01229f17b382975f970cb0309484651b6fa76f0262f2e1ed3482622bc172957d28f0e14f37c062dd01e3632df70509cc12f1aac7316366a075330f88d3963c2e3427620e5b95eaba6e8c9349835aa179930f888ae62774ea6808ba663ea8417c61a32d989ecaa112cada305fb53884dbbb8093ff40a43df07070eeda6f43f10538dca3c990cfaefacaab2aa374f39f275017eb9bd5f40c134a22a2820f0c2d5290b85ffebeab0fb0c85848538353ea872fed647888b41b92e34aa3a1812f39d901112dd19a304879ac9d69e3608e9e007877d0818774758a0d6e9fd2c15f89b0917e33b6c68ef87c1ea5c105cc18f3d71762af416308ce25d8ffd923821cce33f40c143237e5f1f33ffb7d4a556d95f7972a00181925a115954410fde0aae6ce557600699fa3050316dad1934da5dfa53bb5f2dc77730ee64ddb8f896077e5e777b90b7a586a06f8eab24774a53c0a2eb5a031734130f27f7c9ea26b99899768b08114b09f0626ed21c8ab815dcb644fb05c80d89a8f5f74fcab844cb597801360119e0d41066215b61020b4512081ba5a9ad92682b4070d566ab0ab0d3368a29e6c1a0ce0c2c6cf4b2b25e193afd3b8f38c55a315db52c2b4cda3cc0e820efa4e186cc8149e6f4ae8b34e0c00556f6dfa81a51d1b2a450a596c4f572c69879620939a9ffadca5acd376006f000d512db7b618761851d52d39c41de465512c6770046a238ee44eab740f4b4e1de2b06e28ec841c94683b678e490dac94dd4fda1dd3ec8c93cbdc25fd3f39c312772ef4500e87e8dcff3c9849d0108fc395e795c5ffba819c657b4bc09ce7a15352026b4ad193ca41346f4f2a7b25256b4ef334b8e25ec6b1493b0dfdc39f1a6256511ec04c3a1818cd8af2dac28b3b5428e6828fbf8b1b2e71071d09789e27c046fcf4da67ec8e54c7cc85d26f5c19b1cad987f3ee62af33ee462e63fc26da6fa74a3628897fca5d19aa8b64d24b165fb2787108efbaf1f30443fc2dcad56627541834a666f44f3d954ff66d77dbf7bd9895db68b6d7c7507a2423db73441e9d892b612f06aa5f5bcd107a9730501f5b29d98e75749eb63d260fccaadc0ae54e8bab58a197da50511d9c5243063f63ffcde15c070b77dde783bec1d5e2cba4c06178ded2d439f33352a5c942706eb0af652d131bb16dc90f97960df7e33f8e8a5c90ccc3ff0b8ea099328115bc21c0f89ad2c9b115b6dec233208504242113bbd0e6329b2f6a44e65365a8c8b1e8d2f92e91f3069cf1b30671823439931ac21c35b30a4a930025db2d511e6c11a014d34bb97776a14e66daa54f3a0a97d2b73f1c59f17b5506c908097128e60025a0237d5ea1109f12a874c96fac8b943490c457cb2ec59c062f6d61b488e73e34598ba639c21ba4be6eedc0087cc769238cc9728bd3e149149b3c28acd2822a66245efc0a230a50a1aecb03f74fe13a8dd135c708e284dfbed0bd8cb1792bf98ec6fe708115f16e5592a102dc3b68b62766346078d2ab0c85de378f8b426c98f038b38d615275dd7320e76e4e0af52413d7d8161af8c838dd881a56486f97c3cdace709b82657612cba4b63409babfe90961d7b0beba01202180ba7096cac9cd8e5e105f4fa66f7074a4b13025d98aa9bd0c7ff42bf92988a8bd78db0045e2313fb6563e9358bd005a9c524981a5884a009dc9e9e66a89fbec884aa7513c162a3f1b0201612993f621a7dabe57a0fd167e4f75264c940fabe0bb9160a002fb7506537d0dc59ae96917c320da981263cd5b2ecdb8251ebb402332a308e58a49dc94e0af5d79855142008264919049aa7b1ade62cc18d4af2687c2f6c7ea63210ab3c0d19cfc132b42d261c377a23008d64dee4aeec096d8d42cfee951844414e66b5841418c2096bacb6fb84fe2b1e49a0d26a050048bccd08df64aeafd210a73d121bb914b95543b19d15da5306850faf2c261843e20989ff1f296238fed6fcd066f2b8d83346174c7ba412cae2fb42b68146b08735a57ac3363d7329155917aa1284589492dad2109f7bb3b1af755d038005562090a74276b5d371d25a24edb85209e5bab6b26681a0fba4f67d364eccde63cc5bfb6d0d3869bfef9508427ed3801d49644796f5e0aa54db567dd996413a3a473ccd292eab834ea2a9b88b2461052e65d3f3208321a93c43d4c4a6035d690f488eb2a5893dd541f306b8df3b3b59598a64819ae08310e7fe35c639f39b211dbb722c56fbec2fe45eae663b20b73db2f4fba4c2bd5dd3076f71483ddb015b2a13bb5f33f268c8961f8c9f68e31c40658ffbc843abcbcc007ac026814c0104f41bf016471199d602316daece47131e3c99b1885b0179807676a835a505ecf56e242c49957ab0621a27e698602a01101d81ec43a1c33370fa0ee835024155995c18f17241a7cd87a5f36a90426f9c312bab0667ab6acb6d09f8be7bc8f9814bd3780815f737c31034f39abcd9a0b74351d3d471e1dce002369f847f52087110ba15bb64ea305d9bd7424c6e2d82f83fd7ebbf4de9e5d881dde2d44d340a5651dab4d3e18cec9470b06215d9656d52dff1fff4dd47b37ce5755689ad4c1fbcea1c07c9e6918e30360252611b67542887a5210184703701ac6e871a25b448a370ddc87d5727107740073801c70e26c81d40a02d5f7ac067e189c6f831093db6420052c051a8e2bfc745a9a20f50fd7f64e3c3a24b083a0ef3f3e1c7daa94e8977ed60ec44793e809864dccf72ae956821d878e0e50d8396bb3c9026575d6c1424408bc0594fb3f2806b7268e527e640c428478504ac9888df2e5d34efbfc540648cdcb26bd092d45068c7cc01b1593c71f37541af79c2a29dbae78048efa32d82bcbbd4a88500ca284bcda1dc77ad32fdacd8d136f242b394041475db65c30fbf9b7d66fca1472b82ece2a5db960aa15e77afeadfe9c2c8579cbc195dc540d8ae0151c801ff45eb616b42f0c01367c5ee8861af0b81813149501c84d6385585c8a57f14d9393214f7c728626e1caeeb5f8f37e640b13762a89672721f3a976ba0a82b66634f0b2a9b0f31f334bd1565f9ddf3d570a336d1292800482e53cada6a0301fb8cc5250b761a266d0e25e6a163eed183a6869315d89361c51cffba16fe00154c8e431ade145d2cfe3104da08570b55cdf92144012ce1f24bbec4d830a2fac4a680eb159f1b1e1e6d2122f155c67383340af8239c34bca7339f4050bc715f85e21e9e284941ff4cf84c83c057d0e6edc3f3fe036739fe336b37d40d36163f3a68377f84e0795626aaef66c8db55b2aa674363c78c3deb652bfaaab1e6fb0cefcb68ee041e8d548a5018a76932db83a35b062f2622b8933d2882914426035a33b82580a021a4a098bba48542ae60a40c857e4d574250e91662e1ab3390c310bc69c12929ee9d93c400ae4deaeb79f0d9f13e586a0f0ec8e16481c234313dbf59c54c65f32b91ee5850700ec3c56a00d0ffc2a357943b0e6fd64a814d4e048ccd5caebda8c2a2093afc736a6861e0191e07b5bf6f3a69245f85ac771bc51102e270e352bec966871107970b4990605e7f80cd52e4cd113d63020af8c221811a5c36d2bf92737579f938a21b6d19aac3b99b950e76bbd79e6690dcbdb88daaa718ffb0e1233c03be1f46f39f4f2cbce3595c6a8d524f147815a1bba19a8079e93d6b260fd4e7482c399ce01b09943474be76d817a040173bc58fbd04e953aa6c681522f65f71b0e1045f32ba427c6f2a5cfbac8be9257232677562348d7b95b4e47d249e2c26d1479f51157d12842886a8cf73b19af0b59ede4fb5d84f9ba2d8cd527e7c1f67a2d2d6b31251362820095ffa1ab43dc42b7f2924aed2486e79b458c531919a4114f8409291efa4a95506d43a6e6d7056c5fd19bfd3830ebc4f44361f822cedad515772f4cb988af1f67885c884b46c1895b1fc74300ecf976d03f5d9c0325792c5486b33c9df2e788d2cdb0aca84bd298d68561af153a80024812c4c7ad9c4a454bc3274813e00871c2395aba80a30a795a8e29d26ac74e316418ca7023bf9f19c5ef83c6563b0503bc7915c18bbe2659247982b189e483efa3dd871de72d54651935665a244bf0c71d8c4c8ce0d9a8e9437a289f16f9ecfcf325562fed41f0509e7cb49f2991bc9252ef7fbde636b4b12844853498f9e742b8c7ca3771ea0c3b22bd9162b9dd001c75aac12165fbe0e708ac1b2650d7e3f6dbd6a476b5f403524e50c73e983b4fdb043e2145b5285adfed246331358dd911f03689722d53efd43201b877c7efc654c88daff28101db714c0cb2ba179807db23e414f28982ad932accf6a51d889f07e6cf0f91c21b6470aeb5ec3e33c0bb1c0f4ca4b23adca4d6340a735fa65e08c325d8da56935c36cf1c8c7a80a8ec48efd7c047bac754c7f33de0c4b41420d926f66986f61b62c13026f54338f2ad58e48042cc81f745429af1ee27904f4dc80d75d7ddf96e4e873f670db6e6751dbb8881b55ff5a33b8dbcb31db2c14efc55a6689f19a203f993577fd9abd5ec4965a7d031957d1678f1259bc1125afffea8d3d62f11c40ddb971adbc19cbd7f70bd119ec6d74553d43abf7765f84db86b45760728319c1ba1de43947bf16175b96a06a413d944b9d9d9416591d1928a536323e12392ec9849b33c650184c525055075f77cb8ac246e1027787f75feb5ccab593648693607fdb6101c54a017fd7045366d545eb83538818806836e6d7fd3d62aa478095c4104605897f9cbde23bccb424427a6b0ce23845c2623a5964b54b1faadffa3489626662028bd30c4ff60bf04abd5f3d82161d3393f7c14e03935373de9b739cbb079e1ff05c590d514a1f67f7d290c9b1765358c00a499a8d12069a2adbd1523a57c6f71d24bb866a2202aec890d90ed57b69b4b5fbce761a66f34adfcd6878cc524e9482f40705bb1f4ecff874bb81928495c8c4badc9191532adf7353262e7448299eb2763b907f45e46cdb3e1c9e95caa515d8b4a028dc3120be741628b003c06febdbad41f77bd78949dcc6c128a66d481f1958493803e2c8efc89f2076ed019817c29d5558c51683e50e9b4bfef31ccf6cfe13dea9d26ca8de17b888752a3ee6c3991bc3f5982afea4b1a24bbcf7b6adf0a412bc3732f93165f18f07aff27c0d9f97dc721062164f3775441c766d7a9efd06c184fefaae5f292af4c411ceb77b6aa4f154b064acd11e4e562c9705cd4a890c58812228fa6056bb5425fc5abfef9a938d61adb5596a16027acd90ea3f0404e1042340f7d61e0b03ac87b142f12ad47b3ced45b4a9901bc40b1298bede10db9f1e9e3ff133b4457ca9b3f6e7094ae9e3ef4f6202f9945e6cb1bd231e1b37b67bd0c2d597c72d601fd02465ad6b7c6d3ce08b34fcf64c7e828b1488184e061b3ecfcdd0e61f90cfb454bcce9de53338deb430a245a68dd9ab1998730ea61f0f44abc52cb4d755900229b7e29ad6ca500d78e791172c38730961cbbbe3085d2f321ec7056470de6fe3961a240e9c29c81acf61a63361b786d418dd7932ef7317828162c40d415fcfe6ceef11c62978304109733c293d4444e88244e2ca5062657067f53e44fa46419843040c9012b0eb961935a4203cf45413e8465254600f930f66b1224023a5dd1d63e09d774f63cb56c65214fab07f258175bff3883d27c834663bb74ccf1ee438265d1979b5aaf758d82a248718bf29b6c45cd135f9f53b14cd0c89c001c853968e5435fb5f1f82f39a8368bd94dfce18e1930ab3c5ecd8fa77873285a3af5b6ef84783075a2105a4068fae0193be861a2a8aa0af7a6413ab998748b58f8b8f49937a488c7914c1c97e68265489d663cb892de96ee36747e7265852d4419fa271e48ecd431bc94c9044cb61230b3512eaf3b254a2049abd0b461f2dacb089d2916212505f48881858bb8a6c4794568cee8ef45712d7ed6119d874df26d040280147b6b4460de429a46fea2c9635a50b6035073b819439b6cfea371d9090ca7ae3f467573c47ca3674bf8fe522603aeefc272f5244e9cf535701e630d11a1805fbde7b69a7247cd2b4e95d90bbcb4e00ac3b7fce4f5ce3089779514b1cffc450d41f6e9f1cc9a35c5431613c950fd8d0cc1dc7020fa8bb2b6298db204c0baadc670987fedaf24e84032929d88349adf8d3f683b8f1f96134b71d087f7a161e68fc4a362e22a09c4ea58226ee90f5db353124b6af9b3ae5e5432539e50a04e8ac7f15ac31a21b92fb33cfaaf6702d1b37f8e76f956b38acd84d1dfdcb56d677282edc0a14ccf20d4d6374d95d1f2a55ce4899c78805e4b67984790f31441d7acefc4add13e691056b998e6cb0eda0216e059faa178cb551f3b0983d1052422fa134b18e7fba1266417a44013de03c525470b80a30067b5694bc70e8d13a42181494b3aed5c7ffb7522328aaa63b17f104f712a6fb2332529f29e2b8fd7526484f31f40444782427d085733b1e514f42f3eb356f11c07880a5088f2e7798e57d142ce38a377b9c294a75e2cd81da277431e60c52fade5a3c03c8575a6b3aff85ca434f6490d6759d32ebe1761694ea850fa886a4b0aafe231b09bc8bf98e1f10b6d135cf585644a04f68fe8e6c9766547b8087a61d92cf78100c58c7576ac971268f6410bec2301fd3654e35babf4227605841968a0eb3e7c9493a3ad74dbd764c61f56bb521f8dbf846263c2875f894ad9a138bcdaf57ef99e4d0e81549d2d96fbf1cbfb5169e882bf64bb30e96b9e14cd8060fffc01739352c24789b6760c53198a707a4b63013265148bdb57c0eecc7967395ca9afbdb372280441ea36a12a59b7ef1c2a529b52f088e52fe54c67fd11fc907a4f9d7b4050c05e355f97ed8c422676cd7102ca1401ea6d7b670d54b6c37f773bd0389ba6cc1a0391368c090d4358316948ecbaab313857913cf61695bec62b9407449662b2eef0260694659709c80ac68ebedbd5744e142059108c5ee73a3dd0f8c62f3eba73a052ea2037b9193f4c194721353492cb11649dbb88aced12fb6811a796c0295989789658c7157457628f6dae259f8dde2a6151705a3475b1c38bdf402459df511bf0ddd0e88e935df4be13db235700e6bd206610b322a6259b3954665495d4421496e67dd3eb708d51eba3751b41220e4f5d65d73b44ae95631848ad5a485881d96a4cfabbde09b51d291e1c73bb2a980894742f940d3aa52dc82c016bc060a2dd4b82291ee1fba106bf02ae305e0124ef723545660fd093a1cdbdeab90f64016d7b05ccee66841a82d9edab9e38b9c9a864cfd4d2ed96debe8c88f9cdc35dcc8048b3cc4eeec5d970dc069e0cb60dbe7a6ce8b8c090b21e5de56defe0a4b2b8097c3e084059faae006a8d12bdeeff09473879657e13e8001f181b91452774b5f134cce3372dd2e288d161623192ad972b847b51480f0ce356f1c1e3871193ed7f4b7070209b88641ac6335dd1d010677f577c7ba3b1e48446161baf20c741ca4161a2a422677df6a90e94abaeb36ad63e7ae6de9623bb3743689b6fa5eba49f4626f7d08e6197409ef0768357babe470f194991096a3312dabecc6a33ecfcc8f024f1dbb92709fb4d7ca4abc4cbf5306999702ab19bac6f660319c5c5b5606a60d607575abc8c2f119922b5ec63fa495c125152c6eebe097d7aca11662549afb59107cf08fe0c44fac8255122ebfec43a6f3390ed638c0923edd28aa64754d88ae0bb50fb3fffd930eea59bf6e3114f5dae76f477441a03f9901e752b1989d155f760a32fd45abc38170f92504625edb96cc7130e7080a3a335a88ea907278e991fd6a294371cae8eee422afda0e8260be24df1ec8cf2f983ffb011eec3d5ad4c4eafd394e29ea3fb2b812d834fd94d60f4d650aaf01d685c1f7a9033cb8b3a4c2bd082e0ca03cea48d1b2ffabddf4daeab64005d4411ca42aa07131dc21473a1d04ebd028f8311d0dd23d5f3f059c38b9bed096237c3f28ef0138198c883609cd119c6beaffffd240b10cec4c649bcd926850cd5e898eb2fb59d85d09a45d6cdd7cb3c5a408367cf403e1a282aff326512ff63dd6dcaaf2efa1ce8206c29acddae5c859353731485559de0c8cb95310248b9458a058a41ad35868bcaca84f8c8ce14d8f94bb4efd35ca393f8ca14afcfc4ae131b67c865dc2624272bf6bf3c0be94a5cc1a3b415fe44557285b1cdf16ec880b9e5cdfe143cd600b943717b66accb141cdb13150d4aa60334405b4c13e99d93f870c558c42b98b7ddf6846f8340a5e28e28dea5955c942101250bf92b1d6ad0a9f0032d9d5c218194e254e65390a9a21ee0a4d41b149caf7bd04d9c3d7b4e4005c21bd547a3aec2a83a4cc14f40bbbf59a92c6976b2f5844849e67f69719ba85d0daa3feca025ea6004e8aaf5d2a620db795a78209847a48402275cf8a051ce1596c646192fbc1ba037484db1c07bf66856d2e60ab2c90fc21a21db68ad2f4cf556f5739a8bb05f9b56da730c511aac7cd06e7b3320555da689f687fd18b95789036b2d7f7d51371a8271759bebfee0f265030d919941d628469210ed2a832dd19638020529cd4abb3108a8c9b9acd6b07deb17aad43e4ec6b406b8e32728c2aa5fdc170b59100a025d436d5c5072f3cd35830c00406ace5e3bc078b4e0687e5372e2ba49ce8328fa6278a144077ac614b7bd45c47eb86223589644c98168d5b25ecdcdf13c7f0b14f74a955395d3d82fa38bf0311169369d266517a3e98d650489ad6bd9c667629bfa0d9ccdfcf2b95238a7c59c0afb387263fd9d14191f40f86e374a6d895fde2d31a246119977ad4fb702df90a9ab82b60567c4a04c68fb0f983a502f1592115a9b78624be48985fb394e0e361cb1592ec302a0f494c6b564fd607a1348bba18c116f8d0fc6a477f874454343d26c7ff462895e202a624125aa7c28e90444414103194483530ad9d925deac67a76042bd3b7de5990f31eac0990f8f0f24ca48bb733183b98e8d83ae86a76a6c2da24296eaa188b3fec61422dc31cc8b925c2362dba3d74f3bd1e12884f8249ca4835e952f04f86f33ccd785846a2f8d1e8c4ec1857895b03a316839ad876033a42379d86fb1a8f9e68613dad5e1a59257be1cc1c2efd9f633ca9a4781a40a24f07b0585e3deb5f27cfa2782518088fdf0bffa3def14c91874860c4534d7f31a8cdad813afa8b3ba0fb573bafb03780b57d0cf8aa64ebcd67b4d41c1ef3e64c49b27222b85eb625117222816fc7098b3e8ce2c6eda12445c8f7eb830cff214e100879f032fda0df4a765c5d8641efda700e661837ed8fb077661380262b979db2d20fc551d46982dff7ab5390b8957418d78197021c8e37449b797adbf8d8d01ad56f1818b4bea5d0f2c3198bfd9733d824d4c5657a671d38e00450a4669d140ba1615b790f5ace2630178d844420e27ae9f019a0de82168ebe1e2d46e27b23f7d8ea8bc9aabcccbefc895ebcb99a4ec2e2e78514a226ab925674d8fed04fdc9d5b788c6813e22e3cf2b3946e45a8aed5d2b78b960882b8a6b9d85653ed90ec03d45e1b63410343646b7c49267edf792661ed256b9c94e31033db51c34cb95946660e733907c911723ff707318a4e7c7a28e407b6d7009d930c8f078ef27b5423a918340ca17b0280f69f5098d4166440081d266ae86e0be8d644aa972d4351b9ff4645772137911fa561e6238170e1444845f8082058de2443090bb194700499876eb0200d7935070a281fbdfd6638686e473c9fdc2897189deb4d1aacec62a7d0c537dc5fa8756a2f42933e755871e18d53d30c21ce4340fed2a824e835db14a613417e0a171282321552ad5c46e76c373a1aa84dff76d292a290ed58bd3a6b44159c1dfc8b39cb2b33868ff8902f13fce54049e747380520333529a7756192fa87e7fd1871676f69c182eb584a469506917b9e79cf2beaea58afd102c971565668714f7f8db89af149da3df32865371a5b39b9746280da7769270083bd2d95578b7d48066219a45a0fb27d94743e295e42ea5ec6e863844f33dd6d0d0bbe26622a0a143b1572ab0e38ae5fe2c508856a5e1c509a2779038aef7b2a834a80fc2c12006552cd43db854a33c521d2f5580c345042f6cdd0d6a2ec0aa3c75889f41133f679c8d811dd7b41138c2a8acbdef9a37295bbc428636f40f8f3f095027430d9760572b625da5f87632932ee6b26b934b62c42e91fc9b251f649469078a7d0bf2f30ce907510b8161e47ef6d67ad501a5c8beb913ae61b22e5176a938dfd5b91f7c7e61415de939173360f3ff3b983e41ecbbc12e19448c139fe74951f251f3170cd12c3a03660cb125443c7f15b13a33e2368fd8789104bf5f588c07879ae38af3b4e6e7241a138dd52e2849a70d31d0ec18f6a6a4d8277123771e5ff7333f779856f9d1b0cf5bed811b60b5ffe0b0516589a0b7b8d9ce3beff8b532bed89fc8c1027ec78918b34a049a449e3095cdfa372ff2652380bd74f4aff3f62c7def36701dfdcc50b163fef3318279fd0b9d0585458282dbfc86facddb81beeef9e967a71526336137cc080c986c290c03e80b5990189f1941289cbeffb7f164de9809039ffa9a529bee17158eeecd7d1a567a1eca820b95037034ea43535755d37f4a3b49ff225e032c9203b27b85f926fa4dbcef1308e2965ccf31a1e059eb9638f2d5d9b9c85fd25991fb043ff8a86ddb53a2bbb1c720bbbb8271ff0864f59b847dcbd9213c4e2c07c374e55479b6411164483368a435f3f5fb49e536565fa450d5531a64c584d25e5270b90a7b2672a763a5484c24600e95d9a470981f8b94a2d194b814b44b2cf4305d9aa1aa1f54eb14169baef42972f1f84493f3208b656177beae44c05b4d9307c7350ccf74b193bb37ae51ead34b379fe6d466baca6016047924bf82fe842e71a15a85075677a18816f3a1665dcb4b22827e9ef0b1f7947fef436a7649fd812325e4ab4ae60729652390f2f94c300541c42450e25027d63ca98743e13b2f9a4660dafefaddd96c583eb8ea479c59f2d846d478d7d3baf4ac599a2cc336b8ec86c2302842a6fb940b60c1a75e03d52db39e0ddaa0d4449809c388f87a5c8989f663244aea20fb7747830855560ab283d2fc8ced7d5cf1f297c442f41a65dc5979235814381a80151125855f5c203eb414d53eacc7139909203004ee5758b1ffb1a5d54dec6db27859632746793906a65bbcd93cd92d43d9e98a0b58697847b62d3762b5d9bc7ae4142841d12eb71ccc442ae7064e5eda4831f9075e936bf7808f0f9344db9af8b22ca0fe1d1243900a181f0027d83bf9c68280e8f3be21a70fbd3bd6451802d424bb9ed00b0120b717e651812d8f892e83c0d107c9d1157bcb92d1f9442bfb7b28064d36c99e59f50fe39e92a73780a78a05a27db9025e8d225d002b5aae0c27a3413b4d10038468fd8ae4571604382d11acac37fca45c6bd58aea190a630d3100482c1d527e720163924b446f7e655a71a918f7b0e3239a7fa24890352467f122503ede81abb653d1a27690d2638227aff8448f9f12b86bb8e7e2865a4a1fb794316aa87f63345bd1c2b000170e5f49853f47f02ac6ba7945429f972effef24aa52a15392bdd8a9f7c4cd579792ba309a813f33aaa4b18ea600d992f6cff9aba80e2dc880059d5169c2377956c8cb54caddcefa8987d2011b3992e2f83240f43d996db3af5b68c51e55dec2e8adf5d65985d931b863d0cd95e22100de63da5ac34184cce769f8da1b86f6482dbd3790740442902585ed3250d943ef711854e2e7684ac1990c636fed787a4a70e1fc0812c6aad5950689cbcc03da40a6206bdd4f5185d54c375e5dfcb334378e0cf5e1b3bf21b5687d446659afcf564881062f9cf308faa0615465ee89530111c125511858ac900cc2d6cf60220145ed4c183029e692ee82aed28ea25f38f2df3016117fa5449356c052ac1628ef6f624794ac2aba9d5d47acb8053f73c644fe92c4f48cd9b255f344d9ff035873bc88ce74b212c836f9f814e30e4f60ed95149b101f15ae4b5b9aefa23a43c898d7c6f24aaf339a910c7a9a7e4de8469d1b14301d695914208a06c952d28d288b42d0b02ba1f749f765f0f679221942c663cc5defb20ff2bbb563f3940a21ef9481bb461cecc92e2ca91e03754e4cc9e42822baab5fa9b4b87a8b65c88e66f1d1118970588b91c08b610f4d1cb9cc49a75e8943c689660eca80dba9a1a20c3aa983326e9c0a4ab498c125f6089b2d1a47810d0850d84d3b4ec9a14f16c90eb24ecb1d6ba9b52a056ed36126942722b5a5ade2759f32f621e3db47a0fb48e37d98be23da4961a226ec1f1216b34db03b08f3f8e43e0be31dcc5510a785866c0772a9921bf9badbc6d91e942dfcaa594d41bc73aff114a942791b223054fcb7162e6ddd0aeec6e0af9d8a8c66172ac142a3703ead1be1207387ed361494148021fe1edb1fe91bccdc4340cd748d43038d8a395b77ee80ca6f54c48d51aef4c3ce2b1a784dd12ae1eb78089a708eccf20cc87d736746cdb3f25362d0787ed650d39104cad40088887348a174ce4ea84438164426ce70f7e7bf4502b3c2f0e5547a589900bf1d3a74c3eca8059f2515855ef6007a2935159585ed9abed5bf59321fc83c7c9d67d337f1b8015e89e607e18dbd5674a74e240c8714970e1fd2e7d36ccd548a26913be2b8ced4b86d48c9bb4f49b68d3e0e045c26a05806155323fb280ff9cbd4e189afd22f18a87018ebc583404d2e822c96686acedf0415e82b8ade856d8b56f6a299b8b20ed10a42bebbe9efe3be09fb04ab53f8c65829bd898100f4f718a310e6bf8679f1a5fc21845ae67d05e3840abeb5efb7d1b5d340362684d8b0590a06ff87234ef2cae051dbabee37d66a2e2c390ad8d6e4ae200f29306d20aab153673b80cb4a2bb6eb0ef6e56ae2e14c51b8d5c33a7261f2688948710aa487925935a3a01a89a3292406170e4d16a25815e4e90337ecb211296d1bce6e5e68782eb5a8d0588783d97f6584ba04d923f703e1f0ae5fc4228bb090c560054ada59ca191d0ce90a92b5c6bb62f8628f6cd1177248229f2ab5daa7a6c75676528d3a5a12307194630b0616f4c6fa67f70f19c156ac1e2e3d8ab3cfbe503586f66743edfca402da711ea5ea94b40c5d4a9a80ae6027fb20d20e52ad740d9395e2e65b3f00b027b77312435b22dcf183365712dbf215e2be5223b4bdaf6b3e23f7426cdf120574456fe05af635e994221fde73272b26ce872c3f6041787978cada3c4db8691994f104b8a55d4ad7d86e880be6bd530f6e9da2fe9340d8ed763345a1396165cc9dcdba48e0e62288d5a2b97b2b551d1fcd5659135c40fc52eb20fd360d244b653895ae164ce8d8905c33441e94268016858fdb368a42b9faa8ea03174d6d4f4864e6809570c6ead5630d48ce540b895d8d32409aab36e3bc04a5d59fc5dcdf7fc1c21df3b3b4e7120c624ed386ee8b398aba49763ae73e4052d45d86517862867158e249c26053a7fbe42d69f4c1c964ad80000b399681f4a8bd2b6cabebb2f7a8e0073c887c10f17977dada52f71705ad49faa2d4fad78416d9869d60f82d1848b34f986c086e19ac4db68159e5ee4e9fe3910a575c455c9bb2ef0017a853ed072c6ec110b383d7c4f4ad1be18027e45220c335a1c3e1442d1d15f7576231a94a99878e240f852fc44128ea935884875ef9a2048f9d44b24141d8b9663d40d4f9eef098732153f88150a7787776fb790e82ac9de75f4654668b8dc4a3953f7b89191d567ad2c8bc20636720d3bf08603e407f8d8fe899c746395855a674221e421915d6f0dcae357238b1932703ab3c9703782eb7a3716d4a2bcdc7bf49ba40d609df81b6870bbdaa8d26d99a6f4ea540b4323fdca7ebd58c0872b552eefffa15becd87de9b10cc5b40e5fb0dfadb875ccecc47b9cce40f7203d9d7fe00b3af8e58127be8b32b38b939887e597a14c62631f65a5e436e582ffc0de36f2444afc01b4cf24cbbe152e197e8d37d1352b6c2b3f506c4f45ad0634a8f905e80eb3da9c2ef9ff00518bee497f026927457eb1500f06562f743bb317feebde9b0b7c2f43001fe4d85af85f0b93d696e58c70fd7709b2ba82b0dc74ac58d088417c71b60f941c43678e359fc50b1982b7cc62eb2df433fa1a37be3783ca0ffde8438af9b97f6122c3e15f0b70996b2e8fca7bb49751c1c8827908a8bde709160a313cdc9f245553fa4d3deaea24e4600e54c039755615746c16442009375208794607945cc131b37e2eae9c0d48aac7de1522a820e7bc7491fce8041f1caa313a159e44d6411bb1b4d7038011ccd63570d1bd8072c7305ee6dc49c0d54205e514d3a2f1fcd29f31c18a523c63a64edf0716abe192478f16932127a64e22a308b4bed0f474d8a10aa0005760ae5513ad7ce77b3d3ff30add3a932219646b1372b6a2d6c6a66d6d65a42082184ecbdb7dc3b6c0dce0d7a0d1afeb09831a952c2b073e1b61be991e923b7e89e98b75f20864ebf3dcbfe859ee10ff220114121510aebf513c734e8d28b30087f9454e3257ba9981ef42f745008c7f4a4393e03d1884e09bad94f26875eb20c6720ce883c79c319883336ecdb95df2e0e9bf4d985397e8bf7d2c7ec2cfd61f2dabd267e06a21130439e4c4594d9e646830da27c72a6d2de991142087d7ea61decd73eedd33f9da35751251ae9557ceb681dbda37774155dc5165b1c39c2073e5891a357f11ce8557c9122438608110204081658fcf871c5155554913f2cc71d7147d41175c40fcb478ef0810f0c681505f42aaaa0f42a7e1629326448fc07851c71040d1a31629898943eaeabb05f5b61859cb976d42970c41f3976d8f0b8a2d2885da0a917238687d25e9692e251112c02f498d2e7c060b186d0c391bbf7a7a0188afa73a58f7d2b70851e74630edd15f4e229701910c8f42894b5dd4d6095e3bb0361ecd908b8376b8a8c82e3119f461ce4f662a4f415694410d0c814a34cf99c0cc806513608a1857006e6803de8c00db1b144d23fcd4ae14823c717ff62e408c4498ea61cbb1cff717925a76effb437afbaedf3059b9a2517b7e68b17f87b91b7931b73b7a40a867dd685ced69c8b7b82617d0522199e21c32056e8c9b1b35eb0f2f09f255d96ce05a5633f781412303b09896d44fa9792e12d5141655974780c1661720843237f2ff67ded107f3034327cf3705de03102f167bfbd71f7a02687d1b0a2688263e99ff7a5ac7c08c8f31acc4a4e7d762ea9976efbf491f666297636e0e872c7eea78aa791618dd0b16b5715311221d8914c3a6f8f37c35f8c183b24ec639b9cc4046612ccaa3b730a755f4e303472e9d8ed25b2d31e8e6c7afbfc98ae4afbccda614b4732696f721be9a4b737513ff643e5197beef610bd74db48ab886e3f2f6a1ea9325b668e8d82ef6e5fd1dd5a83375110f74e8cced1344dc49472b0dbe17f264e9cad9685f3734a9b2662d6e41963f4893d445245842709c68e9c7d4bae66ec9df6e6777213d9c2c60f69225da45950c47791f676b4377b27cf776b6a58e3d8b9c01ea2ff341153747b916874d28b762da6fb76f4bea33ed2ab29b2b87dda9b3304ea56d46284321e7f70dfb437fb8a1debe3d3ad3c73cc378f66cd928c8345f1a022522aa44cbc4e62705363c423ed49085b4d04fce482fda24fe67a501fa94271e4912b49a3c5070372bdbc1f8d2c7b9a7595f28502faf509557a46aee02fec57d6b385cde0217cb645b3a0e87f3183e0af5f187bcfc00b03595e79785d17c85f0c1af4f1c84c6e9977669ff6e0177d6a64cc2142feda26c39e91120ef68b3c39074ddf5079ad41c499a40ee1e386637e62948c267343e69aba24f3935e8b34628d527a96192f8aa567e732b54bf27a4d4c52a9d4492e3b179254b5b165f9c57c72088b38fda391bf79ed8be921a211da3cdd1ef719eef1cf8be11737052faee4e890b92385b44ecc1a9ef39a8659324dfb975dcb7eca3e49ae9d5e086568f8a391bfee1aea24f724a8d3fd68e4ab714ccf18f14b93d0a3fed1c873844fff327cc2430c118dc0f04b3cc9af77a704c9058a728838636a43c419da4daeddd437ca995c98af67b7c7ffe2e6f8cccccc4c4b0a9e9041ec6a5c9f1886bdba6037e8a322bfc052c7aee82425957aec5c521bc9fda6c8249dabad98fe7a2439bd30c3ae4d0cc36432c91591548f56d368341d29d1595a0b28d0b0a0164fd0a1d9685564a96907911c45f2d99de4c6acd5a04e82bf92a740dfe9279ff83379a9d7be4dfc4ded35fe7a8d1852d117703ad68051105b4fb36f13abb0cf5f2a0cdb80d76b7ce97496d6eea76938e6aad32ffc723a865f40d764c531329f40177d764a906c8070098e911afe4ef034c13132a3deef6e09d412a80d753f2a32c9e7b779b549423f4124f49a0932c94948343cf1d78f919904e3ee7d79359af6a4cbe824b77beab656d3ac0e8fae4fdcdf48ae56a3d190fcd368523aced223d2e8f17e53c43c7a91dd893a6c0fc3b41b3f9940e11e2f6edb3bc57cfa8bd349f4d1eb28dad3fb325f6bfd8b7f336bff370ff0e2c72f2eec9586913ee7fcbc5ffdb569df14362eace5796cd2878e41913fd1ab68d6d1e82c723473e87e1e28692c98f386b950b998739248988649f79b99749409a7719466afb1de2cbb21f31551729c53d49f329b1ebb1aa6df8826d3bc097fd72706014a7e895ce0c905c8f00a4998c9db06b913762462a6475d1ed59e94320514ad4a09d1cbe8228c6a8f3bccdd3141c2a5f6b873ed71303172e57696a858d3d11ea7d1703897c3a2bd1c0e088732694f725cc85a910c6cad55b427ab4d7bb2221173569252995c565c3cda9336ed4191b5cf4bb51b33f3dcd19e24e1f0a5839290cc8be60676441a81aed1c022ae2cafe9685667f9aec29668a48a6c4dfc61df45237974dc5a5377a46e2db9b58aae76b70a694fb6e44a765f5bc132d9922a1a8d45fd9e375bd9d468b060677605ab69937237ed498a650f963ced7140ac8643aff7eb2d72e9cab9aee0868442770b1f4d1ad130f7436a725e9841dd9d59fb91977c909aa6699a462357726ad84be16e4bcd9ae78e6a163dc72357f2d8cc28f94bd3b0e4891d87a3356142a5c4d45e3114d75f5419cf56b3ed684f3ec3361dedc9fb74cd14b4903c53f2548dc646a39934595e9463d204d829d25e4bd0e5f3f38e9756b0dfe5d32c7849933bc71c45c474e40863ca3cec5f44e2b1cf760fecf7a3c022b61c8f028be81829f65175f05d44724c9172e26f45f612f0f3d2b15de9202bad9775d639eb8c6098b2592a25e4e15536fa1273edcd31d8ef530910c82c437f94665d5a58c811b15e7bf3879c18ac4d514168462547867d4c0cabb3565ae9944c605e9db1b3316777579704cc54898a63ccd96ec0a2c96b4f32d44a278ac99b95447b524a4f015c184c9ad564b8838da7b8c34cf60405c4a494628861731eb687414cd2679811767e30b41e487bb57e13a3af54ceb987dee9c738e58c32c6f89eed0981478e18ec545d5769aa8e8a5381d41db1de542cb0fe562490d830ed450cab5dedb0be5078a0bd883576719546aa34017a13f1b873e94145efb4f8c07e752ed84d7093bb9ddc20a8d3e2a3e2fe5a07a67772a5c183fd20cf85e955dc0e45b380348b3bd63a19c3f0a7777243c105db110a99830de955a41b073e990cc28834abc3b10af9ab343964a14eeece7deb2e4604dbd982edfe613bd890973cda7f5ecab792b51fa95282a1153e192864eca89595534a0a89e799fe120a45da2ed11208c8a2db1bf396c1d8a04f8672a004199b50c67ced5c7a7e3842f7096ca759dce3b121189109037532a752a2410075328639403b0c48f627b2ac620eb417b57fd88ef663245ed37e727c566972f4000c140dd33bf3ea9dcc015c6a2fdebac13e512f84de131c6856e318e3ca11cdba87cae101aae3912100a8c064446db350bb03c9c1586450e36410768bc1f4910cea2319c32ff6dd1bfb06614f3e01a540a01a894110fe605072f6d0b7ec62ed1d0336ab35f2c352559ee05a037a83f0b6ddb447475ab09b4e7bf4db7c369f0fcb7546d2529d2992438f61d69248dd43327d6b6d27aa93937a45ad09b2039e4c9fe9eb4dc5912a39264f0e9e90e96b4e05e2864c5f85b4ca0078c0204be07132028d6e36d3cd1659910b919745aa7f2959b41d698f9e6a28fc594dbb0bfc5d7b890a7f29d9474aa5c2db4f7bf429bcf9b4c75dc19e64278fa914ae35d5a689a0cfe1e3e42b78cb754e88fd6acd7565ab89a03f39b9b4b020faed8aed46aae04895eda9126b2d768aa164ec2ef067b197e00f855d65b1a7f0e7996048c60e5a5d17f6eac4043bd9de0fe67c7d24838e8d409d47261082d567ddca5f36a3dd286616dd284cd9ccd756e4d2fdfa47feb2996f1392e94dee07fae89be4ecfd300cd347727c856f2c5e31824066eca00b85cc188e89990475d8b9a0ced259866510c3063dfbc04bf6d37fe4e4f8ee57e88989a08330fc9dfcc6955dbc5b4b9c5c0a99afc821ac7271983fccc54d0e6177344fefaec6e9a4231141233b829055f20ffb086733d8cd68b21c18ce68b21ced69c1922e9f6534201ac21ff6d169f76f341a559b66854e47a66c46aee847f80bdddad49a5a8359d03b178ba3053deb928019044158b6daa311b030a727ef6896eaf4b58a66a5ce22a9dd4e4f4ea10956b2a36377140ac51b314b71e3caa0db7be3caf6b57319e14f0a99b10f060911286bf793428aee8d2b63f803e11b5726e11e179ebdc27e72b9f6309cddefb3aafb61a99e1c30a727d397dcec921c75ba1f0cdcc91826c110ab31e10f95cdd012063dbebb5f8cdc61d86b0db6856ecc75477bb4da585c6b322076140285a415edd11ed73fed24ac1a7d668b55235c6b2ae8bd06fbd168941ddad1b399d1e9084bbbcd642ac25ff7d097005db6ace411077a6c66ee6e57bbd985250133867b5ca71d157d249e1b51d1f46ed8d951430e1e33333536b6c0f8419e667df18a5cd32c9aa35932d32067d0c9f41c803c5147a6a11a29ea84c8cae7f0210afd8b176126e64bbc1371268716f68b3333d1740abc0927daa31a8032e8b78d3be946713ac9eb4bf743bd44fa246131c71ce74525a190149868f412911425a1504908521db18674e78d897bd0782d5d8f55f6f8d0452f71370aeea46bf7c61459fb9689b22c9489a6c8a36bf7453ba9648912fc123a26e250217ce31add971899b3189965379986628c0a66117eb911ff9043580a2c471c69f244cd1b05843222fe64586408df903914ba289463de1bd12684fd46a409d104a43d5a059d2d32e5746a76801021c2f1703a9c902ae808c92ab365b6b8219c0e6724d39b6a4a3fd104a4590deda80694a35d3cae673704318372349f8b47eeb219d82a77a48edc9144a01c72fc6573f1b85ad715cdd27a341fed47e343b3ae9e1c0fc201e5807440429a75c121c78f686a4636a32a9a75c521c79b8840134f3601e966a81005232db9eacb898965f780d802650d52bef28d1725e8c9df143719e6daf9b69e8ccdccb020c7c40bc75bfa69efdaa90216391d633c86a70c4d44ee49166bd83179b250c3916ee7073e59ac8109d304a4f46322d2528215260fb9a29fdc0d0f7cea3579dce0e8ec282147094bf82164c8948fd704c444a4967e4e5aa52d764a474a3e261e52454a8065f2902a726a3e3ca8a1dbc43856e48a5ebed614b9a2cf746cad95d369d6756a044323f98467de10e18c6c3b5438821be249ab95e9ed9fb42ed575713a9c9066c12a14e18a4ccffd74395a25cbe186340b02a96227d316cd1fb7d39369cc29c215f2c7f9643a6f8ae085fc717c982d1f4724d35f35b67672729a356f9ad59f3f2616992a61b632cd7047459e3e09a9320f04a7001e425ad0c23214d2021f688107205786425a60a32304052de8c35603660821911999a110157021ca61836fd953ca2f6c10e51b622677844c5cf946fcc3dd6427a7b8c9d78e0a73ed64adcb3ea3cad15e9c540756621f7891c73e37d5cc32cb6b28f914a9221f41374ad0e3ec95ac3ef6933ef90b829b33550574a9b251cd4006719383a4daf1a9aa20ddfcc0621e23b8076fd1ac0fe6da897f8e3db112aa66f9088ba011cac0ae7ad53b61115996d7b03b318ebbe431a9123ae8f25ae842b9025df9ad7391205187469c767b6023bd8a98a7bd1c1b733c8947b3e4e3e709a04a103770151faf1d921539c6209a908350421050c8f19aac250eb68923e1ae39d83974c73c871cc44dc473269b82fd300fe6d9e05534cdd2543328e29a1182d5fea966b22a074b63d50c72fc462a71f27e97899317bbec6a6097f8bb76b27c77354e72e5fe611e244c72c541dc4019f199146c9c33b088fa58b9206e72fc76a388f1a2ce4535a3ca117f71217fa49b1cffdd78ed58173999742355a48f5c919a0055241e241e200b727c9c3370a600aaccfee60b62a95e58a66d5c179a1276208921942187e05af407391b5e3e52e5c218165b1e893e3e1d15e416f9c3e09ce97cf9401959d866c9d95182aa0cba491c6c38b2738fb1afe4b1fd288533d0ccb44837d829ea2b0a43e163afb37412520565515307a593d9ebbaaeeb92dd0318e89869d9a09db0c25aff068be9e44a03b3a8027e0a09ebaf0b1efbfc26bd60b1633fdaab30bb38e210ead063a6a5e6b0f359851d621c567fb04f11e1afd3fb02ef8671f4623fe4af4b65a4d821f6c6b9d8cd1aec87dde40a7f624ddc116d9af5c52aae1d4b0f233705bd7505f5f587e6aa5354176b73f8c026101b3bd4c5061b67a668af1ab126802a10e28045d05ca30a72fd14b0080c65835c230cbec803cb897282ba10a48a1a9c1c383fd624aa3a254b268a9e2a0996691bd78142563422954c242754494a6512bb134d0d9b0e3861381ad95844ca05ab522274eca1c31c4f80617d8ec7d67f308d8302fb0ae4c30eebca1198e4b294d82336a7849f189535dc35ad83438325d22c8963627691f01f2afec0a883a6a689808fd6be699a552fa5fc9a47e7d1ee3092631032cc420d72f2a6b28189a0c098b0edd57a483abc9c912aa3efc022a8a669218bc2a23d484d27d37cf61c3e505fc15b4af65f76136e9d4cc87cf6af75f24b86710b01d23ba69b7efa66823f7dad334f87d94d2e271c6df6d6c950b771da832fddce6922e06b8d25fd6b9ceddd1b878455a7c31692ffd94f97e45ab982a75298a012ce117dfc9041ad034919b6f4ce5e59d41b6c1a7a0c19667025672490845cc18f70dfc096acd4acafd4de8c38fa5d2357b069e48a06961ee6b6bd89b933fc98a04f3f038db450018db4d0c34b0af429be5c59cc04767916095bb49be5af753e9bbbcb611fdb8d7c78895d8dec9a86257679b15793f620ea6aa1ef3f10a992471ef2bc0ec4d2f6e329bcbc4dd31e6c9da6212277aac8137fcda39302e4930ad9a18010a39483d52e314869c8787bd4cbee7366b02fd997d2d6c618638cdd26a55471c289fcc1302067a0cb6fcddd40025ebb6da59452862ee5bb8360c61f0672bc0dc5289dc8da8d59ce6b503b066f0fecf17e31f2470f43e325fe7ab40291dc57ccb618a576787334f6c6acec18451d6bcc1ed8a126dbdb36aef376e163b768dd1269f4aa55f35ac3dbcb52c6c1f6310a32c2b6f9d8ae31d80ff234b16d28972a70969a95bdafc3fa8b08c77ddbbaaddb36796edbb42bfbec878a62ce3c9b35c560fb325da43a280e6c7f8350fb51eb29bdbed6c1d9361ab21e65be6f24496619e0f000879dcb01ced2254abf29e42d658a5fee5fb0200001f8c32e4a2f6aba4cf4a27dac568a5ffa34e697d1e4f92f9b2d333b926790223f04c83048112017f5b9b8be3468bccf9df2d022940815d29ea6a3d21eeab3d9c17eb487f6501fad666ad88d8c43f9a5e44781e11a3077af11334784e376aec00a704e88fd341aada60037bb6922e6e9cd5aedcdac4867a459759edba259427c9ef33161b487860030fe61990071c6b39684618510b75bed693418b5e1e214ab94a02f409ce21ab5baf875ecbb11ff70d1987d9a4531bd10b4470296f6d4a05bfc8af112c2ceccccd0b44c217e752e42e068b1bcd58dde1b300ea10cd3bb73317d6b0e7bbdf4c8a5a64bb11bd721944127dda23d18b7ce48d1f57a204eff7ff4a2d75581b8e81545adf52e5e8038965d60b903e214087ce3cadd5d602964ee700f0eeb11804623314b040a763383c01f86c20058ad3e006cf521f097922f2336bb813dd2acfac3f1a19b69d68ccf77399a1580cfcbb8475c6bc122aeeba274529cf66688142285421866ed87caa295959414cffb51286bbdc740a1ac05fdc3724aab4e3e51286b3514cada929f50a8f8aec2aeaef26bc77a584ffbdc88d31d336e00aecdba6e47d7e5686f7634530656e55bec8ee757caf7be38278400423286bfaecfb87b695bd115f7e9bd679197e5f76e5fddaf8db85fb754eed7561c7157b4167724cfa74a46f67e10d43eb1448aad0fe58340a09194fbc51c31ee17ad3012ba5fe7a8d7bddbfbb220e0d2c8f7058f471d263fa8af94e98e3d82fb301d192b41bee8fd66aed785a1991ae0b003412963f883c99d8b0170b4316d803b733ec06d20edc19432c93706c45cef47435ed765a22f15c3d0a8df4c36b0db26d2dd70d9b822560676c665e7223b97946f241012a89f0ec3ce384bb74eb34830cba4224429579dd6430e10d31ba7593b301a0e176c9df3a6189065e8e034ebd36866cc137f1efb816191957024bfc830881286e46dd6eb57c55f3d8dab5cd364b744fd009e6dd1ac01340b36abe23904fe621ee21fc442ae778146603770c63440ae44c80022d7935c4db976596bd15ceb272ce27ac5433c886f43dcee09e236cf16ec10439ca5e14ad34ed21e00eda59bb5b30ea50a895421c057ee75bb6322050922ae09e1dd745dd4547b880bf3002e0d2284b876cfb4fa7593107565c2df859528e01f964b1250d2f20f954bb29c6249a508f06f25ab541eebdf5587288b65131db99a5759f967f38911ff50f9e4edd3acd5278a887f36bba071d82a598f5ccdbb88f10f65f38b9e7f71d83fec7b07c0b11ee9ddbb02f087794f408ff716dc432355a211ef99c63b0b8d7704d0442bbc93bc07c07bc93b0b7ff74ea2b5a4f74df34e00fcade44f6b49959803aebc7b3f40cbbb015ade8f68e5f94c47aa7000663d52450170e5ddbb11f843795fc19ff5aea2e39d06ce7abc1391f548ef5ad683d22bef13aebc4fef31f087f20e037f367b17027b37e10fe5fdc29ff55e7110af3d5be71204c7411d5aca41547c696169674365a373ca3ba79c75d8d5609de3ba52a550853bfc8445980e8f71dac445385818440938790a49c169d6d7334f184409ad3caf5da16191270ff2d77cc061515c6d15ada5dde48993a736e2ae2dec287f33e32064dd2f66d689b81fcc2213b141d8b9683a72f8a858d36a9a8858063baf0969d6bcd6bac16eb01bec46aee65188384b739f453cd4bd885b80bb72ad5b22c683b8d62d01e329df348e75691c7635544e44ec6a10e042c4aec6ead761c038341d0a716f5c59886b9d4b7dd6b95c42e02fe66aba423cc69db172dfde54b91f0ccc22d338115fd55fdfb20e09025c88b394b888f04ee3c2f686f8e59d00f7c6952bfe84c003f865c47affb01b25520edb1b027f6d247bcfba1a29976200f8eb2db237a36a57b4376b1542880ae3a66d86e933be95742e3370b43595f2545723e529879d4b0a9e716736a994c81f0c97eb61fcc2da4d7b30aed6d25a02c01f8e2ce3a1ae7db01f58b0180e76d31e7705bb9ab71db7d3deacb37f707340ec6aab1d4af6fe4520cbf89cc8326ac4f8ead885f1d1d8aa096bad6bfab585ed4c31f027c4af0b71d3a56791303432f67a6168e4fa937720ee1733108f9d0dec4160afbdb9bab03def5bc98d884119f3f31c19ac874f07e29fa6b5a62d5d14eade429a05040c1200dcafadc03d79fedeaf81dce743c95ffb7cf2479e3fb99f1c92e74dee278fe479d5fde68e92fbcd23791e457fc2b03df84da32a9b4bed63c2e58ff6648b73b55ad7c41d6ed606a47526d73f6e9aa5e16838da6b76ddccb3655e21d3ad665d58751d4a2dcc63574bc3b9b41cada5a548158d0870358f843cef842c52664a8ed68232e6a7b5e4ccd53ef3aa2bb0dff314f1c4a022ca60d401459ec8c00532007972ac79e2091a6cb00b6d373e62924c0642a1788168847d0cc771b62ff70b702e91457219d8b62b7ae8c20b884417bd3b1791dc7028948138631be12fa633108df842b1143119f5592a1d6bd6c822415232fd44fac9844bb86ced459de4926e229de42fa3db9360d2a904c3702829121d762251e97e5c2eddde2f265b6ab15c2a9dc270f67ea6631f5d2962063d8adebd3b25e445ef4027390824127d261cd31946e6ee19e876e744f7054472d149f7747b47a5fbc5e4d24577647f3ae924f765842de826d0277a76936af417fbd24778c405abb2615f2ae111fe3c90bf781186e172177a0c49edbb404c8ebf372bd7e2438a98a5294799385dc001a397672bad75d64965a8c785735c5fc15bae89678cd876660ea1b55e9362776298d25f985e188546356c10a57e16666f0cab5a4631893129a56d15f0c418e32716e3c4a6ec5c6a4f6c9e6547013c497cf5b2fba6c44be34bc92b0dbdf86fe215895352a44a6ce9aff44c0f9640aba8b356da91075006fc4629ad357eb048869f59748c30a7d65a2d0065c0d7fa596b7d2c22c328efed189f29a5141600ca801f0084157f95d62a6bad95d65a6bada85ab18b524d08ada2226b5561873968b016faecf3d260d70a565ae6755d2a0cdb168a5d6543cb18be11ca17ee410fc5905372e702690c828d9f995415e755c5cce678ca3143e5389b0024cfc72618c933fb26b91ce71de518af0ac35ecad7bc5a8ef1629ff7aa5f4119f4d88dd1e5785d8a3d2883fec3be90e38541b8e09363b447bdf6529a087ad9024b8fe578cd8e328d3172bcaa267204d9a94286798b1d94012710368802835ce1060b19d6d33b514f716418c7e5aaa370823efb0360cb680b16b640232d19c661e5aa1d405fef047d55c55f5315b5d7899da8db6b05eab13b719dc3387c4427eab1631887ac424d1f9830d352372dbb4c0bbd18c6a13dc3aa88033bc5aa88550ea0cfeec4b31489039369d9ae4c0bcb76ee7242185a332d1fcc696267bb3525b776b54ba47b9a081444ea8c5c75abc1d27f7126d6f0d82fd6c41b345cd57cbc4cb63151909d5049d842310e95c448c42c2f7dd4c00b332d540b1e679869a12256a1d5a29200c52133d342b18f8963ab45a605bbc27e31f200ca684c46f605874d4a29a594524a29256661c9621c11aeebbaae5a69c5df5523adf18a914a1c019bb272040b6e9b03e6ecec400cb2075798c316934a2618c9b3093bf21442ca9d4d4aa89351ed41d911081606e9c28e39a9608525d8221b14d66ef0d2cb914e1478a5eccb788812bb27e6983146288c018592189cd3fae1a605578803ca2669dd3acb1ed9e5cd4610e12a667a237661b4e412b15882cec6ac107a17c6da435df157e732736357473238c18a2b40199f6ad8ba27971abbae0bbbe675d5d3eb9ab5ced74bcafa78ebe7a43a99fe6496ae5467529d39eb9c73ca867d551167192c6e29d8200a0682285ede2e370c97ac65c2679a8571d7381c2fd604fbadac4814f7c3be64a7f9833d9a0760a09802c74cb334dc5b9c26d2441d73c6199d9d45c60b6c97024f50e002db13cdba62469fe098509fd11bf20f7f9891e1257c2b447ed81815c080666d317f35cec0706fd15ebc9019cc4cd1ac0f1259f9c9f24774121790f7804a6c297da5aec61911cf9e4c500cb31daed108ec7abc7e57349ce16b25d6702bb0893fe28d9442e86fb1a1952b08797820cf0e4a2707622b2cdd706666a60a36fe896b3e4a29e585ebe5260a0525250315ac2042052b7af26792e19f3f140f88006428c4ea098dc91a692379c896bcc1c969b55aad56ab05458a8fd7b3b3b2023d59b3d2dfe24584a7c7e747ce489a56abd56ab55a50e460d6a2504f592162c3d3f259e9da3cbad53738393a3b36363636363636ad56abd56ab5a0f0813ed007fa409fe661c3d392b4c7e7a7679aa66bdac6c6c6c6c6c6c626f2b45aad56abd5eab169e1e4e8ec10893c36363636363636cd1379224fbcb1893c3fd88ca541d5dcc6e3016d6c6c6c6c6c6c7e6c527cbc9e431e1a49d33b3bbdd33bbdd33b30a72f1ab9ea63d6a250bfe7a5c8954c06f6c36872cb1c21f8b0554a2dfeb09e35f6c430574cce596b6d8852699c4bd820ca8c1335b114d0ed3298156c06187e0b77b7cb22b1fc0d20cb8f099bb19ba506f27cfc76c1089b95c9d0ce6565251e6b9a939202273645f6eb925726b1f7fb180e7c6c4426c419fd79e7757ae38f38a35f634f26349dd0c6264f9d78636383c54a840db2ecbb1044f922f7ebcb321b82383d3920fc45ad5342cb5dd6d53839067fd8348bfe09a902b7ebc6dfe4aad44725926f5b87b7abfb05baba5f2c12b475f79319f4a2ebea37d0b7ebc50f3a4b5faf2f1d7e8731febaabd7bbae6250c771dde34d9d56bc68a722d7ee8add411da769ef1ebb714ce7ed9f9c72cab96d31ca29a79c715362bbd6995854b7bdd340f8bbce3dfe09a9c2f2eb42d4bde2cf46f7faee953ba81e84a74dfd22d77535fe8ab9732652ec621739ae46f76b1dc7fd62ee2e62a8a87bb43a79dbae6ddbb60bd71f2f2ef793d0fbdabbb8f1a6e4982a853f5409ae274c624bf8b318ca1569d4755554b55710080412e197ee1b8809d1880b7f31f38b99b0d697ee1a4e3e96a3bd3b08043a082fb1d56b18abb673bfce2251286bebaf73dcbf98993d350a72fd8b381afe62e605aa4f4c1008744dae3e7bbc01752e59476bd775efba6fda513b30e26058ac17f6d520100804ba4caef77b7741f7abbf3699cc5d28f2a65dd8d671b1b379624e9e998b8a96d9e84915d88a5c59912b52827a3e41063fc891c21de4a43eb09b9492025265bb249237fc2855300c47b8ea7f28ab655886318410a24eb157fcd179d10c8394568ce5cb1c48fb52c136bf121cb69432de3ce10752ca191f383cc1c6a9329a69e9d14c6669c8e17c06b3d26a25ee8e2dd8e4f326f1b926a05c51bc853eb0c1b6526542ce09167e03b206363a21b614746beeeacee55ac9dce9b13b917d3b7655dcb7c316ecaa3829e513397ebb57bb4681fc25916156f2843cb9ceaba22a62db62a50a86b2f55863c73094ab5a52b54cd4cc427e8bdb5651786a44c946ba5bb6c8f19054f493bf512bf73f6fc443ae7a349331ac5ecd042ba1e4c855c7951cff8d78641eb941f7422fbebb40c0557ce87e442891eb5172a40a0a4f4eceb0b640ae9f06723d0a8f54e9e841283c283cb9b773975e0857ddd978d620d532149316d8451c0b44cb7ae920893c0fa90a7d462b3da4f8eb67d98535c358ad38c2ac48231b84570193a5bd29f1115b5f71d2c86da5bc87674a7bd785ad3c0655e825b621b9827880f33309b8829ff2856c9988d1608ad18678ce46c2a4b15bc6cc23ae9859e5cac56a2cff6171eb3adb603b07877d44ecdb4bbcf60d7b31c6ce46c433868cf7647cbebaeb7579961a335b8a99238e31e9c4595f2a683ae4ef9894c11521bcb218b35f7f1183c611289d5d59262fcc709665107226b3593307b27677f7ac73563a5b768e8dcb1f8413c219e9dce69c734e2c574a2badb5564aeb5569c56add64ec8e5cadb562734eda439f71f3c7c65f8f45d4ab5608218474e21a2b372bac150512c56ddd7175d6392b688a9b6b27061d3d818da775d6392ba8e340f3f6e74e2dcb024e08277dcc226601278493fb849737c2c2cf4748e7a473561426f3d65c9c47629ed65ae9a4909b7db0715e1cec2084f0b573818771ce49290a6c7c9d93ce492d767586c54de34ad093e1e73ca7c3c64f9869930f2985913f994e0aa9363f2d14b68dd6c086fadd0da14cc70883684bfd392f4a7bbf8d410e16720dce451f5cc36bfb10dbbea86e2c427849e7335cb2193e6209ef9d52a224ecd81e11f050463fbb1665d25ecf0b51249d556c7072b93f89d80a6c376cd07c23fe210fb1f0727fb02d011e1b6d3f42940f8899183128876e564986cd42e559f1d63c458c14692f0ec9b544249776e460391d4e47aeb22e58698d2024cf7cd303dd00ab60842bb2ca94262259c8dfc98f259cb4a4894756922af2259aec725d5e55cb9675c1dec00e3192a949a6a62ff0646a02320620b00b996621d3932c323d7142a63c4e909069b6376101aa986ae48a9ab6fc9980988a64fafbc02232edd925f14019343315698fe6f0918954b03d2ac2261e6c2292ed58530893f067512737ed793cf6307fec77d231b031f3dc986a322e58534da63f69c9935614b0bdcfa423d3f79067e912ed9586b3ad083f99e6efa4652ad2acc8d3accfda64ba23abc8132c4c46a21092e9737209a76443afb0a6ab40a6259ee42a906999d74e5a59158f32f1cc9feec4fce9f127ec288cc3740cab220e924fac8a8714077b76d2a2133bd1137a9293e9498bceeba4457293391d2d581e5907880f74e489f2c3f51c21f77b50a4d225fc30c26d91fb07c7c4db0f272f4723571bfc512bddc1e1d47335f6725870391c9066c10ca43d5a6fefc5e17037dc8fcbf1342b9e5a11a7c3e9c8155531f188d784f363bac1db0f12f1aaa9686f80f4e0e6aa110bd775c56ba7f4edbaa55f8ff73add614d375245e584fc94d824739265b7025e8f9f5cd15e4b086472c4273fdaa38722d047826cba31e1344b2bfd987864fa52a685fd389d9fbc9353d9c4c344e4a4058ba8a79f8948a6f0bb76ecb50fc6dec4a359a94c39235700c95c0fe7c3f1e194738515999e2322b3ab9eb49a7545b3e2156e9a05fa817382c5494eb3bad39fb048d28d228e6e14733392e92de87ed7c7d1648ab91a1aa902b168ee46aa602df4dbcfa62355600b904c399c0d7fdcccd6d3cadf6c5d379c8ead8145c4d36338b0f1dea7abe05a2da91d203c8694b6f031f1281d01e2039ddc2191ca375cb417a9e0841b2a38a1a6abcfa2603539d4c1461abb4137b21bf306b56fb6b219d8abd2fa6fb632b703d26ecc11733a50067d96058b713aa69af6683140f99a27532778c4164e54fd5fc42253d845ce0756757ae8322daa53288471f8481d07e9f493cbb4a4420f611c2e4e2718878fd3433f8d3e9a3779bceafd8d74655a5c34415f4397dacb15e5b1df238e5cd1371af04a7bf42934a460596ee740244320195e610e3b1c504f6269950aab1c100aa98ee3e421ec4408878b87b04c4bbcb5721571c496ab5edcd3e9be38fd8bad12d42390667d91c7a9a4e464337dd4c931679640a4087d34d22a32fec029419d2e03a2e0d35ee4610535b1252e2e84abd24f2e84abcde4c67cba30cfce86cda8eff4d2e7a964f2ee5c4c649744e72273eaa859ba163a4432d4220b46f2175ba86fb284239bfc4a3dc219a95f9372a594c9332ff52c2b79a9044219a9d7cec52447e82b784b08fb381d5a93c3d428883dbde4232dece9f374da2501f3e93975427d3b4913e41484324a1e4bee474b9053519c4cde708609ea742ab95fcd2647dd8f043975c20d3d13d4a9f492fb75367909df90f98423946172964efd5bc699987c6b13dc23d483e62d218cd91c3e5426b76996ea2c131c6754770a1f3ff9a602a4d71ed82fc2969851a7a7cde7d49d0bea5b343131790d984df0880bf62657a96e7252a564728ca1b904770ce28c13eaa6b447719af5a5b450db09d3688f5e02a3873e7ae8a4ab9200e9f5f5a44f215548f087615b098f6e1352c584ee88ae5c4510b6f58af8fa66fee04e8952ac00dca3564c693444a1918aee281333521a3688423935ec644f0d3a793ec6ca11793e0b1408e1504172fcf053e447febc3cbfd2ac20652892e7bd184798e439ff6051ff4420f3e9a57f52c84c493e4de73ebf75af251fbdded1bb7be3caa44358c48d10c864296ec43fe4ee7126d7679dcb8854723f29641ebde2afe4f4ef4637ae3cc25f779273370ad2633a1bf5a3a3346b84554a8cce9dc32fa48f708ccc5757e346fcc3758efbbeeba3d3d129f65e46a77f193d86a7c4a8bd79097c1e1317fe5e4a2e932926bdfe651423a55923fcd580b92bc11fc9643ac9270a4771e3ca27fcd5dfb8f2e825469aae143273979d8d7ad2519a45fac43d4c00bae8f3a52b8178115649003be8d841bf917dbbe84397b6c4ce013e48580a994718476c3101e8210af463f700d045e73a27ec4518476cb10fddd9d271a12b5b605701108618d3bebd9312476c89dfba1ea5593d4c0073a60cdd76b666c1981ae3e79c73c6d44ca5e43029d8cec5e7c37263b674dd24068af67a6ef38aa999de86c42ff4f22f528a0e7c32f3f213f7b0975845dff98b9962945ef5bc7744a691670c14933ce56adaaed63b57c551523abb612d25471e9d83e5e0b8b3033b37ad79cca37851c654296ae4017596850dd2b062e0c9426418440c3ff2168a5f7f4a096baeff626aa6ef178c75367a8949bb1a31f313b0588ea9b91f233312f2375e3ca6d2afdf32f2e03a8b710d328b33f8c418bbd750233bc32cce20878c82120c194ed48510c2d8402494504279655fbfaee6ecebbb4eafebd4cb178fdbd4d0cc5c17f5f21580fc72512fa5454259bd4f0f884c2fad709283c2b11f96676ec1bc8702044a7ea1d8435191d1226564d8553c5cd47f008105818541c250933f94098a13c12262ce9885190a8141ab5fb041948f46206c624b21283a3a389013003a379814c71936a037c3efa817774486dfff8c659a9661570d2eec050d302cf27717381187069976a26d434c7676b6196c9c8aabb15c07daa1f19218f97bc6b2dff3646041210e360b15030bdb0bd9130a0cac8501840416690864fb77c44723b7dcd95028edcfbc9a94949595ac43342a6222f2821149274609257fcf26b6847128d4ef025269086967a70516b6571a999a25cad0e368484e1c6c96cdf0f672c5020bdb3ba14ab899e1e53569afb715a04a521d548185eda5541c97e17398c8b89db8c8b614b87881c19e0d052f7e996c27f8f5c9dfb7998be5b13f580c00cec8ccb06b2694e1070bdb03004a736df23e1c0508eeda1e985cf1c14220b81cf8688242ed01c67bd5d7f97e1dc3b00bebe86832001c6c168c0cbfc108000c20500000035f187f01c3c5090c18304c60a860a44a5027125389040346c76d1a0c181976c180516170805219da404ca1b2d0485f228ea9793ea6becc47f9d829112fe540133b26e6239e9d93f310449102e46eac87dfdef789314c5e191f36de0f587b1bed98c58cc9ed867608656cf5c63c8432a88b2d5579ad3e3bfdf5f85a6b1679d428b26cd263795e7a38310c472b85943f98c24d864186d804c9b00a52309211606115a43024c320435a594e6aa7ec4d0aa82bc3f950c087921b255560cbf38792fb7466e50836898959382548958abd0b574cfb9c0ffb615262b8e3870da264124b5d142d3289c821bd13734a484e7dee88f8f6a9fbd4bfa993238ca752a98f5824ff4e2f39145205060602c35e01e0b4a15439b9aa572e1eea15f7cb64525fa0a450f087e5d401803fec059ef8b3159fe0949753f84b9dc39fc77271cee33014cd1d7f96bb0acb10e6b08b0ba1f7c73b0a624718262587ec512fb9a320f684f1ed55f13387f0cb85e35147dd386d684671f8e57ae8d692e00bbfc488c2a954f6d49559addc51a8185beac6542ac6185347a5708ca9fb81958cc22ff174835d0a7f3872eadc65912fb8a75229f9a9f37328140a8592252814eadc31873afe64f28fbaf1b30615238a45a26efcef8b7f322e9eba998bcbcf1d37982ede9d8b0b173529f96685ec45a3c792182364a956b8ab24c541716282438f16857a8ca9548c31868eba3031a786ea3d48ef96ed2c5dbaa6f64e77253746dae276bb05f6001d0aa9b282b103baa5fb36baa78b2e49e8964097f478314cbbe8daab695f912a977631b9d24e35d9b25dca16ed4e0c66a566de8087a833ccc4b33261d3a67365c67753da1d7dc0c49cdc13c748633cd239b96b0aa52879bed63a25c533fac8f126c790bddd36d3cd61c23e4a2917e6d08db974d14be9a477e9226cb5b0a5c3d26b9704cc25122e7df6c63cc210ca0861db5e7729aa207f1107a70e36bb13aeb6db667d3139f4f6b6431c39d4f9524556d0adefb45963cc1ebb1e15cb1f48c914bf4c8c61ae73a86899beaee042215088935845e55a9bc8dbac094d9da34016571b90129ad6d520cd1df1b366de40e75ce7529b902a50febaf2243704a58ab7816a7b1b067919f4d9b963d65c20aefbb6cd1a4e48be21f3cb657abdae75aea02640206c2af907930293627ab940a150e8734768c84be954e43a4120093a271fd31914da4a075d9280b47fdc33d065d5f0cbf512fe385c75b2acf893f5a5d2bb43a9620f21cb04aa0755acd21eba4ca950251008143af7b983d3097d532787405d0daef4ae6382cba07321fb99c225781444a27009c7a1be59dce10d77894449d14fdeaeebbaae4b2b495c3f779cee48f4be35ed5d9fa9939b728e40d7f077fcd5cd7498946a0abd56ed75de00c3ac45a1bcca811e02e12fa633d7714dccce923eb8d3e79608e17983380374ad82b04a8b2da9d2c4e7bcc106939243ff6052f2f675d94717eb6a84feb261fbab6382cba13701baf7a340f88349f1bad0bcc1ac09711ac7711ca7552965fd0da21171ea70b473d92e9341f7bb5f4aaea13be2829d1974aebb5e65f2766152b286e70d224827be4fa98832938a2803a22842d85e24f62285cc3d48701da6e03a0e9996eb9b0a3a0760fc61d104334ccc14c8cce4f0a8a1c9818213ccb4a840a605ca95bcc45ffc628e6f29444b3d19a59cb1e525ebe4a00eac7c9f461c6d4ade62b70098b9f6726027a5320e5bcbd8525629a594b14f2f3b17f9beae5ab75aa5ec4b76a5fdab4ad951deee4f8c6b0fd6eeae0d2568362bcea38109561e4623620ac61c4cc712e9928899cb81fd20cf1312c3ac95dbb11fb6b97336b607cda5cc34477a0573a6999bec5cfa94520e7800266235baa0fea29126ceb84ebbafbed7ebc55c10675cc7fe44b7845dffba7d451d39629159baafd9b95cf3baba4628415a7644d6b46b665875496c7e4a1484f6fa118d018142f0b439ec1c7af2e14dc69f97391cc839bb66d30266298f5985b4e91d31976ab23d2c59d2bfa803f4d247c225fc451dd99e929ce4dd4b0e5bc564baf6974a4a5e7a0a8f825812acd578197d6612fcb26192ee1f0c9749eff03769b626fc423ac941ef4e09125009fe6448f86534c2b8145d106794428f5ca9341afd035cb6f8a5f4ed366eb003e10f87bdc52c7274d0953764069d6ec961073a4bdb479a68c4e936ea387d24ba6874c25fcca28fb2089ff027934f175d2b12592bbafdec5c2c8b145dfbd3d5ac7d772e167443f8f4485352f2a8a359118b927b028126972d1e8d405bb638baa04b57f4adbb768b1cc9b5a7f78569c4054bba3dc94ba2d9839e744f72bbd3fba2f48dc2ae63695b637be92c6d4f2fdd787b630e9d1e5d108d80f9f42dea207977bf98dc9d4aec4bdf36d88d441d0344a2db8b4637915c76a26f2fb9b3bd2f8246078d46f88473c9925c7b61b84c7216d95d984d9144caab5a94f6e66934fac976d4767bc5ec352bf4b999a44aaeba0bd1472fd938dd826e4752bcc82190c9a097b08ae42fa4834e423ae824902d811e4725278d4abfec47b7ebbe984c7aec98b0584552bae8aa480eba8874c22a126cfacbe924379d4ef2537ba3833e3ae9a0fbc564d147a063a20eff3aec9828f908bf949c845f4e3e3a0c5782677b262f9d3cde45ed94901f9d76364eec55f8d33eb777b784ddbea1ee4745de4a25bb59d0b68d5eba456dd740db56b21f699b0d6d38742df41bbad7acd0b49fd7dbfe1d458a445fb055a8f4ac95b5498e324433120000001314000028140c8884629150302ad766290f14000e98ac50784c9a86498e440821440801001000000001001a04006e2194db9358fb9af3e6329a42e72a875ebd58afd2fcd4f98ec4b8aea9290fa8c8f096b9c77dc4368d00c0a65d763bba8893cb20613547b12209c47c83a3066bac712ba63966c3ac0184ab647b5ffc47c6df8dc33fb54689de1c626f4d30b57da2f9df669b0eed9d836acb18a839796afa417156ebb0ce938db75f9610b132d32d4aceb39ed9d807dbd0ec1daf12f02b61a43e6ed93dd8240ddd001f369a4a382797f56867e2d26d712228d8c437c87325f7f06587419556f3f52abc8f96222bf81fac43e41fb098964bddb00af8b8f0f7717d686df108182ee8a79e2c19824332583d1004cd31e04164390c0931c5b0eccc914dc4dc52538aca405e7eaf6fc63b62256d6f486166c7a7728a1f8c860d0a4f1937d9032ca27791c0b39eb086b19ed5eccd981690d5b8f5fea47adf5f25e412a29e6e89cf99388a2793996e005ba813a387e4348dd0cc96e7f4207a5bb648082d5e410bd4a815afbf88b3d198fbbc123e1e9cc66796bd2db3c4f68964d029b0f0a96d3b88dd0b41e9d947b6e88f50989546bccb0aee09a63f4c1404ba5314609c430a548fe512684e46396552efe808fe2972de1cf49bb3a8919f8752a586dea516445f3b27696eafc406a177430139a5a4a6cec348ce2cad5972233f57cd2b6dddfc611650df3515feede2674afb08a137c8bfb09047e8b4409e7c338f3b1b59ca551961377e5af622185790b83ef3b46d31e036874087e693e0efe8344a264ea50375c20f8528be84e920e1c0820474473675ac7ff292ded7365ecf4f0f90dff64c45690f07227f345ab1c1a54ee307bc2dfc8f304c1c35a43ad5258622d132c71bdf7ae01c127380358b3b97a66533919d38a40cf2be9ed19ae908d0da911d2bac7a8279ac206f37a17f164251d100ebec61590178b1490c95b93c8f33b74c0a4a25e5dd7ea9aacb70037726ffc45a5e3f86787f71d26ec598d53789a55f24fde9c20a61df6c48ffd8b17f0540503c8d235bba258737847b4313c26a9f661771056ffa46e54244ad2f346752e877a324dc99e2dff09fb6463241f60f54564a4145a805a3bd0c33fccf699f5452d0cccb21dbc5aff0adaab7dfaacecc2b3d2a67775108c9d397ca1836622ddc4a405cffd657b7225c8436bc579294c3a2e6e0ce8d87584e75985408b28fba93f12a793989038371e58ff1ee7befe187d56ac70b823fbca3f778ed229b15e484ee1d2441ed9877116679a85c051d429fafb4e3f7de69bba46db261bf9cbdddf4b4d421672dd71c0806c4a9835c1cff629d13621ff4474f6f8ef3eee85dc173a691ad513d9e325e52e8519b0ed85453c57fc90b0bb916c34c5bec2d4c298175aa9b7eff31ab9cf4a7c1f432400f7adad0d6a949a59deb5fcb6caa7ad742a303199236f483b797e021b10b433e71764ca0c5e37becc7ffa385cb86ec59fd9d452527b15aee3d681f968a62f042db4772f9aa1d7ca6d9ca0846e4465329310627da8892b71a9be9e17c53ca9b7a6e9f134d77bee57f1ad2484679108ba4f72ebbd5f71108f8e4b5c2942ed7df39e3fb6bea1fbab1aa48cdbe8ac126394558c6ed15f5fa260a042ca5e2bb5bcf3a503eeaff9f71155774c2e85ecaf12a65519ca9222beb2e2ee973aec42e7339965aa5eeabdf5f233e6021931aa0f2c31e04e9f17c2c2baa0cb99228467c8c052cd2458204a235a3c70c8d2821975a88f6365b29de914648623f24f5a29994a718e702339735c79197f489a0152e6c8b22e8af7698719ec219b870b4d7d72adee3158b57c4908476e702485f3665092c036cd319a99b2dd55e9f5a61ae58e2510b289bdaeda5b8035f136daac859a964c5225edd3c0b8c374543929f466e930f4c58d776c728db784367a3ad78cd799e0572065dc6a526be5771e961b9e4c0bed7c79f2e5928d01e7c89495385b370826e8395da4c7455014a77a02a2685ad417ba0199e064f7eb9d8039216737a544a4206cdfa6dd6c103f54052513f0fa6845c9b780fbe1607578642ed8cbdb04608062dcd99eb6c9156fffa3359bbe5231ba72c8f9d731a16ff18b1e031cbe472f2aab17b098eb4f85a4527fa4aedb8dc0e357d5747a18fdc0f5223909d85a229a79a8941f6304d42cb22fd4dc4944df4a8186ff14b5f070fce4abc35dd0adac68838f3322744b0cf17d314dfdd573587efe1452382fb80d4aac69291247c9b19ca6adfe2c572e0570e13d5792ff81ed290851cc02e002c748987a7d1bd79c40c2efd2b95b59498d7c27787f0ad885f8a66c1249c1c3b639a73628ba2ebabfe12c29418248028c939593fa3b7f8a2f1764fb2bd3c5a4c20d3eb7edb744e9726d0624b71085b642f202553a809d2085515339ebade9c313aee7a7ea6eb355e74bff389e83ab161938bd42d3783c542cdbcc616fa0917c50d63dac8842a5814b37e049f53932486d0865397c9a26453b2238e9492c09d28bb17a519af3b349b39666ec0a3e00d7811022b8a6bd8cc18448672a7daa846a0516c3c0d75e10c38dd17460f513e88acfa4da0af8ebab74c6d7917197e22c7c646356142e88a06c99c05462b4450163db2b240f6b7503d9d74034853923a4866d70450fa7c1535f4cdc6871d1ef69478ac3c6c894c667c88eb320b7bbbde27c0e2d751758803ec001a67254fe22756e47140d8bd9150553464f078ab7a027c650c900216db02e5e320c21033d5e326263d1a4fa9834a687a51921ccc503be1b557c5a3d97114721953241d4130b34e62609c5d631282b9769435ea3e26ba8c64483e752f8ed06c0b08bf93c76ffc18ff0050367e8a52ebf1e476002ef65ac53ae12bf2b753669067b658c89907982404cb56105dee7f9ba62cf830bc1cc92dea3d146915221db1e611e43109547d9dc2342cf13afe5d4662112a5cf332e64181d4fb1c4c596bc05fb622296dd3e8c89578b9b1dc1476f3af9d6c0c7c8cd38d1166193c4d1dd38954f9d3c9ae2f06793be5d9f762a6a117972fcca930c65ba54fa90810f95d5f0d69261bae36783a701532b57ff45ffa23689f2b6619434b35b17e16c3655ec7e5e60f029cece12a8a59f0959f785e422aa4a5d8fc64eab6d3a4ae1ff8e7858319a3311f2b6e45491e0cbe03d119421417da0d6bbd3e6cf65c304145d98ad1ab226ca3fca9ccfa946e20c47f59ee1aa87697b781a280fef60c31d53a4be2785770eb801f84414d3b39d5224eadabb41e96c4ac1bc1a3867f7350037d01c63c28ae238a474e1e9cd39d97b1ec33595c5730954fd5271c660f7f7d689bc75a6467e7b09aa6818cddd9d0a703f7155fa3128f3a3b6430ad23eda42243ca86ef477f2a2cd89d2046140f421dc0cd26bba33aac44975df6f69aae47dd9d4643aa527c4b0bd230cab05956637c533cebe7aa23f969b2f8d31f10b0bf82e8ea139516086bf78b67b547fe0f3d23945a85f5e73201f6ae6d1486b95ca9c3bba76e71bcb7fb3e34dd437d8848b2d996370eebfc78b9083bdc887f723b4c7f6fe8ddf232118a028218435480782b380523649f98f3f85981b9508cbaeeb5cae1e593d5b68b79006d946d7c4a223a6e2ba53cfb8d03df642a4d695eafa48e8356a79111f43210c6f9df847c5fc4b7a292f05c8491351263fdb96bebe29995f8ec10be776388e3dde35228535c02950c7b610b1fb85ba48f8489ad485374234988d08e0c3027382b95616f3ee85df4e5d706bfea4129444ab28e0944dcf7c273d79ade102f310be3d9c057933d16760a0de04410e981133ad83c2948df5690e9fdd5d8dc2f1eab74088bc44cbf121b3cf6efa3f82332ead43185b3d506e782f47b0c6ecd4358434c067122b5f06c1edc6ec1b0fbc43bdc7fc24705ff87c65c8d36f38aeec2602806fa9112336ac33ce7bde155be67c1e61e5aefd89fc8cc101a35f225e44dc0be1e845508fbfb92ba41697d1bb6f22214c2df788ac298ed2acef47904ea414d60988815f0eaa700396b86a7cc6b133ff4ce7e6fb62f01d0e0affb5b546e10025001d322c75ea0e6c93e576523956d296674b267243b28e81650f3dc041e8cd1df376027d80e03eef70c2ac13ffd1c9062e68e555456ccbafbbc5fc0b948072eabf12d31576d752e1197639eb5ccf3fc43569ce90ecee9f3c840a74b1e3f5f0c2d4be2d3fe9c92101da96571f00266fe2d480b39d923edb4572764d37886e9f18f24f09955ba1101dbef1a4f853e2c72642231d5e798773b92c9856943f653d3e6c645d9434db2760c6df299203f25385c735714d430fa5a6d2fb30370d1b45874be53144f040e6e03e9b52f8499bc7158d6328be642c064a4d74a2939a8eaa8b0780165638d1cf94030e87193b043f2533872d0f6fcb6aec0147235325792c353656d4370cbd1682287adc73af62c0687fb2b24ed55088b5aaef724692ed8828783a16f9648f91e70be7d4d080a29fac0c85516d0a7600b3a98e293d831a7f10f8df924ce1ae00b3fc60aed10715241e2a3e18d68e380b1bbfd5d70cc2623266c5408ba6692aacf55836ecf40535ee047ddc8c38c5600417e5abeb42df8e69b1b80fa1d71d42db8b2bc6ab6b82c59935425892859171f0c767215c7315b8bb27a73dd2615a2e4939added693f835fc56e1d4ee0471383c3689797acd378f14001d6bc82f50ec8655a102fce0455bc3af813f36c623029a6ca825f6c9efbbba1c1548d7cc6a5098bd4da924d75a2f8f3dc36bd0c3b0af0fe6efa72f2adc5382d22a364c37312e69e5ade212677824f0776c5b72c268a60a41d7119172c7edda4b6c152a3daf8e5b0b2328d1845eae0054e7f129026f04171b030889b93a8eeeab606063f91d6840173d04806871eaa43d547d5475d7f8f475c7636b30960ef7d60f850ab2305049b767b8203d7a69b8f704f3a12d710595954231ac4490551f63a8e848b02dbaaafd16905e437df4d5814872d9badf01ad18db74b66e608725cf8b3a2e545fc3b81fbc5d8e1d10424ed6357bcfbb4713a0238afdfb0313a75e39234e8c47899734d677afbabb90465fab3104416ae8cd67f268834bd008f03a8b91258a681f53537a34aa1142cf10a41bb25190431469630a90a82dd95526b694492cccf2900c126256a76bdcaee712ff79cb8b826c321b851dacbc4aa089bf56041b2eded775601657e5a31860edfb7551e95a6213a7c0d230f908d58dbca9efb8a31f641c0f080ecc7776100f4749b14fc4cad9274b16de9938e619e90e341185fc25e319e11dce931ee3d0c407723067391023aa4c66e4d6d5120a9604987fd94796f0eb1f3666295f279dd1a69b6b1f6f80dab30237326fb08722eacc22a51f31c6dc3ce07028455e55561ddfa9228766822b0f1ebb361b1085619e188f8131341d7703a63a1f48665e9509cfb049723efe837e307a8027baab66023125aa4998b98fb0ecfd6a49995ebccb6195598fe66f7ff3f1b5ac1e6de12c189f2a26a015d47878c5c620aeae152e6ce7c0e298644b6a5f26145122b51552de1148582b01f02938b91394f44bca2bbc8804cd412b9e634ecfd2449e77ddd08aa280f2a0ec6d28479e3aa435c2ac1113b0536931d5a87c5ff7da4044081d32cb6dbdbfd58a94ed9dece6d976afd84faa798ebc445ccf37ca8d73cb7e639c3d1d17e724619e19bba4c1e9c321e67e1dcd92472eba50d5c5d3b6e1d763818d6e98513de5fe0f240560cd998d26d85efce175e2b3e2b01f80b2b96d15d96970af08c4aeca9476263003d527ed05f5519b45ea4a28b186738ca308338f5b2888839249c00c97f41f53540e3111847c183e6e5e6d311cce32bfa4c325e325ac4d4d0249b7ee1350cf5abcde50e81ba41a51f97f5499eac7c411c991445898728130f9ec3af43619e45861c677ec6db2c6dbe83729f7556c13b9b37bb2bc0892ae1fc273cc647e1a2d647d805ab9d453b185cbfd5d256560ee82694f7a0fdfcf855a154f375fa5c9e349c24b3b2b82b2b2057c96ef9b3e338937cd067b97d930b82c6ca3a2c7ca1f31577b30a372835b0660a5a1ab0e4e9f687ac997764389529a33763c5b90817f9828c86096924f2f3884c3c0cfb49c0cf9a37e117f4080e2ebb684d650b18431a725f9ce32840df902da26361721a071da1ec83574938bb20663f905db4bc08f34ed3df0a970a26030449e206faec040acf4963f524b2487f360ff674b6f31200533c82e9c23f0059a8c7848d2c0903851a729c325cc36f448159a47928fd9d6299aabc4ee362cb04be742955bf70680847d8ad32413ae2ae74b4fb6e4d98573fcf7da6f8ec1b08add773c2c5fd0fc284bb384eac5b70b0433e31f8e1139afe4d5d9b9305159899d825246c724d84185653bc3ff9a145c4bc4d070a841e05272ed3913e2cbc906846fed581e97da173702f4c1e97c36f7a5a11b436215323c3a1d1e29e5a256fa0c54448b2a3a60aa436251a6c134242c9d72dff0704b397e92e301a4a35403004a0fc65a3295ca668835062113ffff96341cc78a9f161e0deaccf9293f5e19e34f2acbdf9812a2cf7c7478047ba9168949bef22bd1ab7b9792a59c57267d2c650f86f566dd2f2030891b0e599b2cd1fc8ed959345d1bac81c9c2cc00311622c4d30c2347f5a382cd25d830721c036e73d861d2f03fc2238a0166d18002f240015270b099ab807bc8c5df4525fbffde6a3c5da016a4ebdb8a180057fd95b28654e7f0fdb51273cfe22474ead8439c99d0e72e3416c2e360824a9c5fb272d63606b7d1c269584abf8f1543233cc5fc06c42c0a688e61faf19e768a48e11940b0728d205219110984e28fb7ab06e5e5b1a2cba9d1133f80ef5bf180cc80ef352901d7121115c3ba2f37d3d23e5bb704076501cce1468680e0034473ccf0c490a2d8c5e82af1aaad72c5a5ff4f7f504168023610a8e8385c3cbbc8d18918da38f2252e80b89db1eaedba30a76200bd5f840072c76b3f15b3472b46afc982463c964515b26f21cb5e193d05cdb17c6a5875c64ac8808fad276ec81172daa1983bd51eb9a60261e14290005130400c90d021b46d709a6278714b0c1d67502aed6e619fc592724eb8534d05725d8c4fefcb1056cf83b4b2fe6d7099ec116810d81ae9b8399acc006668c0defd8b93c16fbe9fa9a2ae7e4080fcd012e4c1916a80a9331624e2c7fb33203976bc01bbe0ded21075b4213592077fa568b245aae322d2a85b68b1e512947994c6fc9accb047f52e15db7963d92ea6ab0c4a88a66021e17d0e72de7532e20b1df9d70f672d4980656df8abd313a4e58ddd99b7a7c4f6fabc80806a449d9d65bc905fcc270d5fbe599fdb6a21942581fc6cdba644733b011fd1a85131e2f8653646b863d274581592cf60ae5287efe95365f3431ef06de86eadfc20df5088626b4af5236d7d52078d63812f8b46fd240c26f049e8f040c6e02b84f4f8e20f088f0762c758ea1b6fd030d3b81b85925861e042133de94dc25869f3195fe7203060fe0d00e718e9555434d80b502df1d0240e02752b8b755c443741c8ee3cea1f26c2b9f3fd7233b1f905162471e581ff58df6c606d79e21e0912efa1878e70157f4fd189906ff6ac2046be84030e7f32f80680484f8d60e1cbf0d2f73733e2c2c947d7d385a9dc6015c74aa3db42d7aed7907bfa2d2a1fa4d6349c1523e704b417ab12e5e0329f86fd8f6efa721ce521083e1f029a94d593569cbb018ebe7052b55fed60f9a7fe03b80ce33191c66f72578fe4f72ca8c1312ba5961ce4c0df9563b10bf61ae2655899132f0012e606acb3f70b959603b7b2caca0e9b74e4d119a48829b09d32eb98c6b6cc6e01d0598f0bb0582343ba607e600ab2f6a3c3a08904082ff2c48f75948fd077f7ef1b98b2f8ebbb349e85d98e60151fbfe903522396cabfe8450fa9c55627e0203725fdef7ad1b9a73cb234c96a8003aae2fb4f556cf64d2739247c8f6b98e8541139aaedbdf49446372c1558b70591a93a8702ffb731299b94eb55eec689fabe3179028ee83d281b804a08a4104d7518c878f11fa5a81547f203b404827111535bde090ea6bed4c731e3f1be12fcff660bb87404c7047e032614630e147df13fa81314af0f5c3419241d4de5298a9a656cebfe02391117ba0e03cd49af4a2e42e23c8ce7bd6f0dbf03a0f96bc1a88a145045f9409b3aa218c118b316d0364857f9d3dba1149180c9fd762e93b18a6c4c40e7463f6425226ddd8df62bab60fddbb30eccb5d41d1f63dba872d8d48fc6d1af59fdf6d2f2d81fec4c0b0b16f3ccfb29fd76dfdf9bf27ba27deae06eac138d16d83c3412620419fe1acddedd49ab5bb4d82a8d31f51fba56cb1306e50d195109f04da89682a0e9c2986471876d5ce9e2741031455a8562405179b30b345be2f54a47f23a3f832eb3009f966afb6c707cdfeb38c08ea2103032a5fe48e3e7e0781322911ed177388cd3e89ae632e6918ec54124950e87831e107b1eb50777c324b728ee75b66be3a046e6703b98e9ceec2e0335fec82fc7c22fe1426126ee2872da38cfb852a49893f1af5865e4f6e83b0a4e10800df654a5edb65d7d8d0009d8508315232fa637ac43e255c1229a84b8448512ef7c1c5ddf405e38bdeabd383cd64ea2570ce3e929ad6620da8782f60cee9bda9cf7006957751f035a108460232fa2b88b67a64b5e4491b6c09d9a80404c3d329694c1a8c8dbc5e4eda298a3ec41f2265f680556d07a046bfbae4b4979cef3991cce0ee7d79b860d988a8b7496d7b825b37fa3d05523c87863b8288c2228b430457e088eb05bc2c0bb4c723ab1c3f42ff36accc3d77e72fa4e77228b2dad2ad5d38a2e8393d9539a4b9f3157222b386b0d902a6a462085eab9096f89c7b8601911d7633f4d4208bc4444b7e82d49b0887e728c99530d012da3d4ac84f08bd74cf07b7ab472adaefb5ddd067bde86092b6151cdb4e734ad6ad41dda10fcbfac886307d89069a986411f92982af3717d106fe812f805924217d62c500f86247065f048e1e941a996f8e3ec90363aa45d5be74b42b4a89b19b53df2fb6da7368fe3e6ae5b258cfac63ad93d161f53cdb1d84858277713c1d1000701e611458239458951aab2463e056fac9aff0a7daa95482f2a7290e4e2bd20bcad91651578c000a73c8c9a9ee383476272e9caf3c92a3343ec07fa3a915f56dd1556b8e0ab35e79162985992468dfc9e303431db016e8a082f8eb5def3e271e48a306c409cd84515a94e83fee4b64a206c1a5da6ed6201448d25561f19397cb7e491da4d01533b16d127eeb4177408789aa4b11e7305f9d8ed1bd76f08034c7ece1ef58ad16db4522443202248f1f219aa600892083bb39ab1d3bd00b274c16ea2246ba295e974e0b6d551efa488d8cee5ad614d12bae49a234aba9ba0e7ff0c62f946f5799974bf2acdba5b28bfab176e9a432b95b35cf3b1eddca54165676c25e28445b6b942fccd5e66bb4ad33203fa491af871fc70e8cf94405ef5b233e32a03fc105fe0cf720d15643a6286c56d5495641c4f973c4985af195070c1002be1145b3f0ddf6f82ed615c5a1556a35deaa2dcd8d573d28b46b3441173ef43c0ef8d1fae37a7bf3ba54172509ff0c0f780dd4430dee422ad7e26084eed4f07b6e07c3dfb27ff2ec4f4721a7723957f2bdbe53c89cac198017ce5a3bd58b2ab3c16e8547c8b355a63de1ce76b1894021d7a170f1d506d401d941bf328ef882596e368b8ab0977d81c40b0e16a76dbdef380b6fea6e56b15a24605c12dc6732b390552c014a428459da753b7b04d03a2c1089d8bf0b4076fdc2a806c28523fc3ba1d04f94e7fc003b781b45c537a768aee4fd5381af8eb966241fd0bc5d446530f0b0a9244aa9327cc094f8ecab37d63bbed695b41177a4c57815f112391d1144097b69e5373946678896fcad58129bbf5b527d79272b808905e8e3006b0eb8e49bcaa1ac61d9b100210c8c61e178e1908ec624e866c8ff50888fda92a8d96d4ff855f4fa75cbee18f300d0c9556a48529ab2d9ea81e30d741dc0108c6cf57da152642b2cb154e910b6578f00801231823d15768366fa375aa924497b957e48ca94cdc1e47178dcdc28878ebf5b7cdb345065abee9a523238eab4d403a92f336d7287950955daafb0e4287d5efe3be43830b4b497d06724277cc571046cd575711a658ee5c4b7f6f43e34cf8b286e63a76c4292bb7e30592f06d745a3a7cab840b13a4df9cce74a49752cd54f931f22795db872df0eec3ca8ee8a3182658fd39585774459c7924827b206b10d5adc4decba3a580eb02fa9e5ed6cf4fab9980f5ee54dae8ada5fd5442909c2abdb6f16bfc92669a3ed43cc9eb67761133eb42bd4baaf3b1e3484a575c43a06725659cbfe23a2500e13756b0555e68224460573d5517b1253c230581ec35e7529d18c9c8c554b5da73cba8e22f25bc3c53ac52d2c244202853d8ccfb085c2ecc226a8f3966f1b01abaaa6befbf6b4b16158d7785e169d24ed25128eddc0e7e86f282d6cf15ba8e28b743b178f227b4d41c498b0a5e113f9c395bc69c2051bfa250ffe53fb8650934b6258d5b51ad0b211dea9432d166187cb04f0f3ce3fca63c07a19b94508334a30173999415260140e6e5837314b9e4f6a0afed7756171a84badc4a46d888a43c06e196e3d9806d3b00133a263eb337c80edffe32718483306899739f2570740954f53b9ec439db6cba285f7df3d615e06a9cac9e56de40a7cab1fe39f4c82ca90ae035bc399b3def47457d38b8f663d283c6e715eec17dd7e6795f5afd60c9bbb88e1e253c02f8d723da70e182e1e61604d109432e385bd46e4585ac7b87cf1f7b9de2a6cbe06ce2872431020da947f6c11b30d2906209e3fffd0f7064e98d4a7db73845f0f4bc8fb57698acc20844837b97165500580fd5c0111dba759483a2264770baf2161af227ba2590785701ccbec3e7618d7cf296fb548292ac6d917b8247e677cefedca9983d59ca19aa0df0801ddbc2d8f7296f1eb6ae6862c8f7a0db021675b7a444e3f8edb10d2bf0b7c6ab3c5f17adad6087d6046824ce41e1c14cc95ddce940b6d18d7a2d413c1fef1496d18285ce869432202c6851b3c063a4705339ab121f0910f22b600e883a158d25b70dbf3d161ab43bee1078c498957c33b0db5039fe9881a765a3a420d20346716af4c86384eaf5ef560f14db007e187de9f357066b2655cf0444a9bad7ae8ee98bb44a1298bcf8c24c7318466c29587188e32fbd8e81b24e1012b43b91d77b656e4a808f219c358d13cc5852818f3497750a4aadf40e960700b5df5d8c8e028c6ef62741873f109151bf57dad9eeec7adaca0dd76b6adedadb614699023ebf00922adb25703ad80c2724f586268453683b63519fef9f3fe286d68446b1baf6a9dbbaafe4944357bad99b6b32c214aa30725c4c2c092d4d2f5f87c0b71cd9895e6269c9ee650cd2489097d8a4b0f4538c4c6305ade4971819a4c40faf063b14a8768dfa48394e84cb2e3cabc8393149d8d49b75326c0d15a5d844371b1c2453b4145df619c4344ba0cf05f9d0e4edd2e5e61d9e51dd996c37874363070cf51cb05c8c6a26ec42b60c51d44c119f024c9b4fe209424c460188704aaa28b440b89e17ee7fde65170c81a5ef9165f3395e388bd676d975dc1fa610a4648bf5901238ffc48dd93eda6b48040665b3e59dd170cbb924540e8379bc7f2a10d0613adf8d9769007a9e87d36a66cb05d19f64ad0c1d9244b256b14a0587fc16c8708014c051704460bc5d0fa7bc82fae103f99842d0427a13a5c313092620f97a3178c33e277e2d10772513110840e861bc2d2e589b083c1f465f9a588c1aa1f6f2f0a7a679abd472236c3ef733ef41a2d65ecb2afcf2839e56236992a43d4cd88378c922a83c9ceb9a3ca2ec937a83207e24bda8ddf5399d64ec79b1f1dca93fcff4f65beb01bdb206abfd0946b8275fd7b47235ccbd44402791c276c8a3fa10ac54303c2dc8769d0ab758c19e13129e66d31d53326c50918d44c9e050cfb2f6d229cd0f88121864b94932d515c65526c3bd257aa186ad80275de82e03f75f3fea4881bbfd929afcc4a72f2cd2ed729a54e40a583b47bba6d199c8f40cd8cc6796d4194d292db6d293e5e5263b655feb159ad4e1973e0ea2e56974bfb6e453eaf852d64dd94ea6a58d6cbff972dd9fc95452d0f2165a027d8fedb1b6c093d3bbaef35cc287cafc8adaa443033e47949c1253df1acb997227cabaa65524b8e41c0539b3144b0d51527dae10af9c38b52ad72af95432a494296edc00b76306c369bee7964b2047670aed134bde08d44e8e6d1053c50f344304b20a01143d8e8f889e88388082ebe822aa83a7abd1031c269c971219298e4777c10f57808b8383c42550784dd8aa9db0f90350f54eae933fd8673e85e21c90ece762a0fc04d1915174c8e000a41ed84ff7e86853cdd2c0874e2953c0695878db6a75a843f4424fed4387dc8421f85058b1d9be3c6cb5fc691faacb9416be10f1a464c00eaa484ded940adbdaad5a22a403df7c17478063316842a099bb10a05f738158a4eea3f057083534605b98fab80aeba728b23602a9123fd555df3522b6a24516b5228299bd0133a493b01639f5dd279e2d4790a0cb83eddc4b0e9284fa26621fe376cf79901805d3c0ee7348d92f68b502c69a9886a120e9b14787d6e11d120ab73842c585ac3acf131feac0cec992de06eb78f3b4dc820f5f9c0249ade589d33b6fd0845439fa51179a2a31447987d9067b43632aa8359de158fced4cff56b07b022a63a78706b0fcacd0c3a910c68103d3272ea5e7087f0b77c44df59d8d3b96ef20c00f22562edcf0a01cb6b5f7f5d029b221019ee525447a2270b9b189b60633752ef8e62ac34392e353ec882d85c05fdc7cfa7d02fb7272ee6049bc8ccc506f4b914529caf0b532c4903efa3e01b2ce3a68e048eec2aed41b69a34847c40d479183501f1dfcc82fac9445d84f3a14279b7f862fde6d970441eaf1f2139c1301c885efe5cefb6ab0f0cff547abf6b2bff3e1e7f445d8ba5fcbc8c768b4e80fe8e14924008778382f731313129b393aa738498f4374e1e56b78abbad2d14250369c77a907dac890f88f6abda7db87ee0fb84521e4121edeb8f852d39be1142326e007d21f5f3ac1ae17e242bc201afcf7e578549d420ef414bfbc884cee9142e651be580880e25f27da0f9af964a3e616272df95686a72129e0116dc82a5dbda6ae04c960e84a9a5b3470d933e46492f8df90139ffd9199020e076127a6ac9e287c38406d445203c8ef978b19494e3ede8316fc5f409614288793ac52bccbed16f5d13b391ca8970b9f5ae3981c37f80757015297cf8d96e32ca45231740fc0d0b60173f404969f4e8ccedf8c0f2f8f9b560c05fcfe2c750e0c45b3b256c0cbfd2b61f0c2e5fd2dfa66bb585c0d486ccc0131d57a745242efeba8f0755ccf94de14077e905f771505130efc03ef03cee8f195bc492e600fd22991bf74751134c3b7c70d2a2b41a68018d20a6cb6a434cdaba3699f8dca2d1de1b6e4460b1ffc2e7fc475fd2fdb8435abdb57f6e0de37a08cf62179051264ce1e34e8ed10a161b6ec1f5c1d7e9bf754e091c60de0e955b953aa6b3c5efc75dfe5bfb13d66b68369087f13ba5aa46b08dd8625f1544705323ebe30e9c394696c5052d5315c031cc95d40cc49eef1c8de1b477502f18a7c7c740fbfea8f30290395206f0f8104b4ba76b2b6df131513ec3ac9d498ff88d3d55e8fa6adf51be3428b2463ae7d05d68da362bf731cdfbbfffcdcceae414a27f4111a11bc89a1fc0d17cbc400cc1a14e7a12450ddab4202ec76183ad1740a809769a4a3df34659649c07151259bce8be458dab550384cbf03722025d056764fc24f772d7bc2a692dc4d465e04f2e54631b515d3e5d82c78987c32f560dbd49c1f0bbf8043bb49b2383bbce85d1e81df20171787a26cd83bc6a746fc7200b02ddd682c92993e976f5fbc7c6e02cb4f48749ed18db9d2aa5f12c483f5b7fae896c2b529160b18e3d5baedc8535fea043696d28500742e27c66685340a7f666729002a2da75a29104e0a69fdf7bc1aafca8798577d0ee85b22e06cac29d8a17da10e690a04887a18c49a2560e3c316f6e00ec7ce0b7094778b42f3403313d6fab78d7d0171853cbcda0c9e10ac8f4b14bd4230e0fcd34426c8210077a138b6b69c734745edda13dc78110576af7be2c130b2933468d7597f7e062e48b9d79712b52d29d7d6d06dd577c33a7a0491c82ce1e419d76cf9b57efe71f7f88c026f3af6f8c5fcd6482eb1c63d49e80532ae6f2420fb4c9b7347078b35262c998f98cd69dbaa37840f9755d54e90d4f4584972bc3940dd21e5ea9bbf438aa43321986050a16bea4135de1139342609dadcc6bf04db98f1c308db60ae5d8ba0b2c67aaada5f12e6f4d36cb9f3f247a61ff72642f44be413babd829483f26a3d1077166bfbfa622c1e838c6dc0496e7cc2076457166da556ac09ddb765e11d110452f711a0ca60a83d25a1085d70cda536eed04692d1ecbab3652c28a5902fc0cbbe1ed21c89f83a473bd1821c764efd834ab5ca5e44ebddce1369bf229e8017b209ad7f9ed264accf375209c7ecc0d46477de8fe92929cad004a3ee72944541750fd51e34dfe0eea86b46046bded9ceb6b342c349fc599d3fa4e48eb722b54ca250ab570972b259ce34a11d44e480a95f08e2b5db8eb8a12559cc80a74618eeb5ab843ae78d97c112ea9183ec2bd98fdbd809ae061a1e1011be6ae1308e0df308b578417184a854c185f75be46ce0cce93b3b7d934041850b4a6f589c929795bb16003d190c3f1c543ec1fb60a1d9ee62a678222f479c6926d155822f9241112de208710a00e538c8eea67b92bc68f3921dddea216c671ad0b775cd1c21db7e0416cdcea61f834f4983e6c4da4b8eb5a11e6baa2843b72bd874d17e152c5e4135c8bd5d2b40aabaf0459072e0b47d63024077b003396bda726ecd118e25b68065856f56640859359613324b72906549b419018e59d31306f57ac82551642e2293c79bb8d885a0a37dfe640eb3ab11f72518cc7136df868f51a7d5abd4df9484d8d7c5002b1f9802b6258e627c0a576fb828215af1d233865652be3d6636a3297c5f8092ec4fedb851c6532c7834bda9c0a1771377068d5f8a020990c1dd53157361c610f5690ba82ed670fa2f2696ecbb4ac62c2713a8518388315069e658530b843c70be4528ae523dc8bd9d2d4d745d75491835be9fcb5404461d91cb40416da6c6199c0b06622ac98184b18cb3a9045fba28080444ea67601c1fae8fc3a5342762e17c5f201ee27b22681487823469f9c838d339e64feb67a426209c7fa3f7823ac407cc00db17c8083000942ffed21cec7b270c554025b0a7c1ce95d8ec8913ddd06f4e527938bd6abb5143ddc5268a504a7654032b3011d2d86e0b05863eda6f4a92fa2500707c6adcca30b536efe55a876fee3694729d7730307889e396b4d8c1513389308422121b20e4a8aa0ce77a026eb2e47931093a1c60963b126126dff63527c5a102f5d4b81c44d0e129d83e02dd8c3f5d21df486807e1a01d064bf564bd6b43d1911ea319b404b7c896323b890fda570a0cdefce1e120280e2378e76a228c7a1770900e4323219b2268bab80937aed68a6c7ac350cac593b2ac1b129249c53705c101e551e6502108dcd17fc7135fba1dbfeadf8da1d874882c9f87455fe153d060a2664a3405955eb9c1ea1dca52ca5a53e210931ea6124018a28bf2a56a102e19dd4be7846d295073ac4c095618ac24d2189e1b861fedc736a0d12b3770f0443bd3a3135a50cfeff7e350c888b3517c64e81f7bf62feebc07e9f7d21565fb9dd7591721094e52a43e3241eeb139649606a6be1b46b8d9034085c9dd9351f6b1f9e3b800b8f01b3aadb3da92ac549f00d3cb7fee9edccdfe4fa9d1ba1cda3d413630284db07521c346b7f8dae24baf496999084a588dcc121f18716fd48003667a0fe0ad886a1dfe6f971ec3fb7940f9a5557d7915375709ac9c6693e452a26f38e8057dda30ccbada1bda2884bedf891bc5024cbad012620adbdce1d2a50655ffb06d412a18d02fac9bd612845af7dd1963effc9757a0f3a3e4d838b2fd1cfe1f8f1cae667256c9f41861084ebbd69ee028a82bd51c2cfd67fa8267af29a7115c45707bf07e89996361d0dec0aed20095d34c2be004404e0b532b151b36e3626c6bd6ed2a8bd4a7ab37cae0b5882f45d05cd74cc23bf7bd4da1b789d96984e55ccc6efba83b5ff2e9a66fa6d7a12a1131158f1f1e0521433afe88ffa721ab36fefe510e0afa6e491556fc5635b63b7bdf53c2de119d09d2d10cbd510446a8977e55d6bd0adbff9b7cb42d22ff9fffd7aece1b7dbf15d04a2a4c042f4395a834a6158c3aec4fedf3cae49f45a0d85a7893038dc9b8b814638bd837e2a9d50863fc198306e87199561f7276defdb8132fa3531c35b6f9d389b0ce13d82e14903f0b1f894bb56087144e6b6e9a739c1556acce67c3f76dfbb9aab3a8d459b43675f2ba1c3a1abe6519042f361daae30b78c038f57c732d1e23f97088eac18e972390c19c98cd12f99f9ab60578f4a4a5fd4541b6c3e98aa55a217d194cf00f0c6608ed34391157b5d3858fb95fd08da595acad4fd5c6303c7ad0947f91731a810e4e4591c71e1fa79d400a3d23aafd8655165ae4db4dfd9ec4fd0b2f5a2cca56028a1cbee5c9677fe6e6c3a566773b130f8059fe489098636a71ba49e41b8d6f4e1300d71495c0e58666e145ec14803fc57844111859d9c2127ee5704ae6817f10150c653ce36c1d2db665db3d847e513f913821e951b65f3c1a4fd2e58beea2c6713f4a804f87cc03522d8c24001e49c30355c4cae05c247efcc20a2b0c837f47fa2cc9b5bcf580bb6763d36d2c651e020e824ce9516a7d23ad8536d47018c0b88fd117776f6df5d269db3bb13538aa42ddf7da55e23d4d9bb7393cd219ebb17151002883bd2d213683b7a6e4a0d795256c3460c07557630e72f959e9d864fc315b4feb1cc7ac6607266994dac8bd2027111b40d10dfed1baa22ea93e48bdfaa7662a0ffa5c66e6f7f9563e171ef61dcc1f3cc787b9547323986d863e7cd1419405404b129504204861b61139e2ee1491e2624532c987919fcee85287e4c4801a4843727c424fb6701c37ee9a650360db56458ae93cae191be49b1536b28281562b1d06f57aa9b36b0083fcd57e08100aa0173bfacb22d8e1d406d73bb3a88ee6f1b3e2e1532e483f36e6508da43da0b961529bb5568bb5228c948e4f51b7bb5581c8c1b63e8025b48edaf1348eb45924416b8b36e5a2e7ac626ecb62b55dc9ca31260f7299ebde66ce559c673cd21b2b0d2ab8a06ecd33937b1fb83ccddf2dca19a716a677c42d9ed10f901e8dc9786a7198e1265629d9cb3e05c39a6688e3a22e637c388225c0df376da3b8ac2579f8ac6a3918efe28f6f17429cfa302cd0a6dfafbdee80ea0173d60e9c631599f7b4231710c09ca0cbc21151b05d73ade888602f761806f1cc89eb319368519c226d2a66cb815858636657366fbaedb2dc1ae0a2df99630e1dedf2c410a52c0aa649c9b2fce92140f6cb8abce4c3e5ca451404abb1ed8bd7a52cdf046390cd2a82cbb551df2b89eb6357cdba3b8496430019135c53542ec0234b02911c29330b98d09d08d9c5f64b82825f3af9338a5662f012f0f3109f60d60ad5f03717f583548b45d815d801cc5cab08ab254108f03760e8accb714f77ef1f9a5d17bb45c5f0620150c6a7de779ae636e751ba568ad1c256308d260f75befe9895f9022d55e3b6ae4def0a1a43c3031627887dc11efcac4052dbe56166bd5a4ba8c5e70fc6e56869baa2cff67a963916d7c208274e94e8557bf265f3fe8ed9fe05b520aac53265962fa33e9436137132c7a5c1bf7f612f455a7c307c50b66dae1b26315b71719f5c9c2eb99d7d34bd39447365a50f691109aed0842c7cacf590ec660050216f44244393160f0877c8dd290b45da19456b5afb37c49773c8cc2fe71d18c21d9d7ebcf91c68deeba8ccdf0bd4f41dba37bfc6ba28810c8d8a6ff0a8edf9c354625f4b47123a2a15f183b7c8b24a6336a388835ecf95884cc5d9daba709ff9106d28bd989c0dccbf71e6bd889c078fb71f4fb7d5cc7a58356df406550bd2990e7cae9593a33d703ae89629311faf9e33b4bbdba32d3927bc5184313dc31cb14b05843bb3f2615058c500cf76bb44deea29c4fa160a115269f4b41cdedf02916a66ddb831d956d697cdc546082d8a310a2e58f9b1af296c4ddb89807b606ad6b0954d55dcf35eaa0c91e4291564ede9fa9c776cf523a6f8c415c2db956ecd516aaa6c098f1f9ffcd01db9e5a9718d17346136abc5b423a082085e46817538ad52a5f2db0ee889735d7460724335d490effd8bc93521d6f6df4029b5c1da09aac1470b82b2e5c6b4da4a97ff7656e7c1ada6312c30285d3a8de702fda875e4b3c9669904768d3afbca8c1edd55da498cbaa018863e82f11eb320886144a5a890455e8b6a676ebc88feaaa6dec57dd8ba946c96677b410a8d208475e83e80b355ca1196bcf3746511a7c946785828ee63422ad5fb60bdd548cadc72642018113fb61c8dd5e82bd5cd64f42b3cd82c27b050de1bbde54ed3e5469a5e01e2bdc5c386858f20007cb8c4db759e855d0a1244a2e5713fcdee740a1016588ab7ccf8e702033d9d85c14ad2139059f797682d12804a2db1aa109e8c57df7c9cc042092726f8291bf14e726f8d615fb4db8a2a5cea649323ca441e5e4cdbf9c24d20662c246b88ab55d8c115fa38c2dc45324dc1311d0d0306fdccf385d3496eba23dd57d72cb920c9801aa9b1383dfda5f06de7562b3d692ef56c94c9bdae05887986e201b4d425988815ad78d1a195a882f1729d09f18eb1b075d8fdd67a81358ad342bce40f5ea52377eb2677f47f96b20aba2352f3663b0490851fe147e84563899ebf5665dff269524683c2d0a8b2eeb20a668d761c653f14845904241ed556acf6bba6087327c041110cd2a73b628bb50c10536d2c5f12a8cdc97eee0904adc4a66761415788b958de7622f8947d48da65436d7803032c7e6cde751273ae7704030962b0a3b018d294b043792dddf3da4810030077ea6b6ecd1aab75429f8704f6abc96bfafa7cc8a918b838e96c869b2702268caa6a124101551d9e7f9d68ede38d88dd94d9a6da6371015bd939cbc30b474df8126107d9fb4329f6663d0e7375743755f5632c5d870dadc2767358ed26571a76f71df0eba9cd36506bf026a33a0ffc0e48cd384b93c8a5c463ea6f1e3b748cc79995d99058df50820bf1f1e3b326c0159608e5f669cd8f79be09e6709ccf6e72bad53f8f8d185489297715bebec30de8a421d09c2080d32e994f811046c78fc4568e04b09b61251820e64140ca6886d23e773a6414569a316dbd3929c4dfa4fed04e8aa047bb5e37cae9824b387c5d9a742e7b7a26ab381bba9f4ee22f4d9070711fa0a73a4dd06964bc3b92f7a20869d5296b3c1fab0699ed128fd8756f2e2d12a1ee0b8739454dd6abaf7c0d3e9b77cf048a5e02173f919f375485ea22c71d7bef6ff105045b59e931f5a38bff6b6c3e7874f371e77380411b9d4c5ed6031c00f02b8f49df041404049479b282c4b0e2e56929aa64200b4fb0da68e023848bd7c32f8605be3f25fdfb7430d737f1bad95652b1f8bdc4e7504fe8cce84e4a458a366be1755eb29958ebf175cd99a937c74c23af2c0a56bda3b7b5896cd64f41d4962d7bb6e14e3ad0d0edeaa31c354fedd4363005062bc15a9bbc40b6ab8f58001ffde0a8cf9fee58a30cad24520d9347de243a16f6ee43955b10b90f331337f330654450ff520c2b709885b0bdb0af0794f4e9992619e7c166e286bad53fb69f26b9fe36bd3a546d3da07c419fe6f980ac688e635948c3f1e88ab7618e5b6f2405329e95c9e858fcda59882a8fe6b641a472ea603a4227344a0d682a0c199b606cfc7c2c5ce7294efc09722d316eeb6c60df68b4c23ad4f5eab16cfb96d088d32376aa6776326609c8bf2e33fafd491afefa6aa6ad4a789cf08245ddeaacea5d3f5376d7895a8f293554ad6a3b81f33dece26fc5349c17838206fb9b1b75b1d83566641a6df3d255d86eab8bc4a468d923a061be2f5fbe1d148d8b665933cec81515e7ce16cb0c132ad2621525fcb8f3e1e9621f8ba659155700d4655037112018172080a675b05a72737a54353aafea2e474a34a9133308f337db6794dc8b1956aab0a3865acd42724bda5488dd1cb1416cb86660c2c38c1c68968f29e5977c848dd55a47b475f6c24b2878cbbe7316ad55070816067f3a05ed321994659f90b95f65a443f7e9782703a3383831081cdbf50c40408032074978aeeb81c9d99c2440d7128d673b7b52020190ea55fc3a7b550c53c4890163b1c0b8fb1ed139a565fb80ca4352519f20350b7185c6fa101c277d225d2affbe35c454802650299b359a641642d4420096410b0cb3ddd437eaa674af3e27a12246eb4351e339c461e41bbf130fa39200fab18ea7ee4faf5a7164a9b0e69f6c41efb34b7ee1b50036b795aad1a0cb09e156e595acb8bfd5e9adac718270848a2c907cf102d12de7daa4676e0176d21c7c7920877a644383ecef4be3c9c38a596172cf8cae3f914c1aac51e0f93a39eda9020edd69250a011c6ccb4115f36f417c636836c85ab379603f689ddf582e29f63bf63c15b27d855b1da0a500f839c68e2a43d6394075b8e8157c3cf9f8672b0ef255f0ee5787a42e5e28706c32fad1162a73f0a1408dc72383dcbf030788a5889cd3d71d177dfe9c691fe7dc023b795fd13bcd8a396a2a658a0264d3590faf64c5db993c003e2917979b406ac8e06a51bb73b8298ffc82717ad91f53551c2cf3a60b1d431dbfc16d1d3d9c6f198ad20972970324007ee68d6a7ead4181fb6f3cbb79f354a9211e60a2d1d95ffdc95f9f5f9eb1475e34d3340698ecad62a5edbd6a59523dd79792d4314f66b88aaa6b6c3b16f7f8a8663ebd09314eb8b015cf1de04ab984074e8c7d8860027a85fde8109281f24605b220ee300e9c9cd796e5262123b764872585a7e3ba29d425b1cc38aaa836bb468e2b55d2b45ca6c834a53b4f1805bae36e1282037d2abcbd19194945c9d50741f8bd78bce4e93c2ed35a19be7d263a77917f49ed8357e17d8da7551a23ac8a621dc27e1bfa2c762906ca6f331f0871444539b624b3a4c43447c4b2e42b1de690a22d2aed159a37e75d6ddc79c62660cef8e2ee265526c7371944bee57da2963b78a86124ef60e9ce364e595556c5082540612a509357b56a13e47ea3127eba8c0aeee8af000d5c0205703881065756c1860cbaa148ae8911abe917e73135dec60eb80540c7416fb0641722170b6d68c150fe7b294b635872a2b62c0b287975dfd82ac141dbc8237d837a8742d0bbf2249d5e1044e04bf90ceadca7ca9c1c6f434b8d34902b126ade5fb47b0782eb461ad8ee6d5444a19ebc109f2df266e586f39799dfccaa3273e955b42c705948548fc7f775c530b679865a11bff72105884c4ba318f4fc8059fca8c292bddf1cbcacf746f88f894484c40b1aad8bbdb83fa84dad5b56c89ade85c2a0d4b35952a6ec1a874452ac248e46e51f0aa05db354780072f4ffa1de0f641490b757306e28fcd6f612511585d555f4c9df142857be756959ada7e4528f36df26c0e3aab6c5a622da07181ed7651f44d7c193ef38cef4c7164f1ab3fd0441a479007f42e6dcf6f90a5afae47a6e0ae365619305a69512f5b950f09087ad24efd4c8df50242e1616722e2ecdff52a46c308bba6f5fbe7f520b98d01e098bb4a1a6df27fc285f1a20532e543adba856f957943409c49e521bea289717fe402602e372537e154cb790d8ebde3651260952f147fa8286ae9673cf4096507e1222ccc493f2cf371734e38c30d13b959f02c82496a1144b4cba613a65e69f1b373b2e55127235d9e4232564518eb42a7883943be85edbf75d85b824b429f34b6ba870a36a8287c0aa98376012010c59655a1e31564b8c6e50143a4d6bbf34900f76e9d005d0e321fd80fbc8f095e8beba545bb2fb31ea2c6b3a5e0fa6f8de73304c6a7ed16a65a7ca17cd65e878f82431a7f10190cff31cc11f91d9299480ccae46744c0cff36050ed448849f0da8e9cb7878c054b132e3fcfa507557e95a13bca80340968c3c8f6eed725c78365510a28272b1780951646685ff8a63a16ae70aed4504600cfd1526b1bfbf0af9ec08403b80cef3be92bf4783bcbdf050d15adeaec556912cacc4f4a1e5ed29684f0b6e449343f7ec2292189a07be234abd1c68373534a901a3b50e91ca591ad2e23ead3c30a9ff25e548a22b056ed1c93e9edeaefea935a7855987f233ffd6d14491e7fff21fdd2b20efb9209a8557d484af2e43de1b6c4ae176957fb5065cbfb2a9a13fd91a3d79bba4284ce397d80fedc61f6762384f11de5e0379b53bcf075142574ffa345a57e43190190a772f6a79c50bd85972c1d30c2014d5f04691d5cd0473e78adba366ecb231649ef53057c027da2ee6a7081cdcd76b3f05962b6118f7f8800a400b469da1c1061f28080f028759b0831f1e54b4401afaf9e5113d0e1fc7e7fed07670c8734c97ba088702a09e87b5fe8d254c915eb7a025b8ef32a8215176cdb7c366d97fdd5b5ea5ffddaaca11e92dcb5d548529305706cfa06a083c3225ff878e0c15119207b2c0acae416decc26afcadf85a9c8b91a8137942cc5a834edb6dc746f2846f5bd6cf3961ed49cee412ea3c649d6987aedba44dfd09c5296b487bc963278b0205f495f2cf1c38ea12bacb0f04ea8cd3b2af9cc1bcbc68b7aab1b912e696ddb31bd46369bd2bb20c29421917c7487a56100ccfb505b23978012119c7b035166febfff43b16bff18ef092b9b36c9e968f6f59f28188c2e02a4e7f6e8ba2c0974ff993a3d8b9e178a7942f141f9335ad66a2caafef1d202ba36bc28fb62698b65d7a006e504483374099549494afe360f04c8beb0013b45e4543465d5c9e83bba67aca1ac31a6ba4fe31fc7a56bc99809844bef96048f8f6df8cef72ddf0f9ac2feded7a08ce8ddbd95439a5eddbd4da5ccd9fdbbf4bdc08d61b7b24a6de86d2cde021237b825fe9c02319ac269625c7d5cb96887611e943b6f3d1458315e98f64b3f87e5f874812ee576d72a26ecc8cae3bd7bd81ac7fd4133e47ef367076d2fce2446a9a075abba123c1674e185cc778034b2549f749e98c7d816b153095dda801d0399112194d1c3f44e0d507e607d07aceb4393289a043fc68fb873641fca9e262c1609b1882cb98362b84d0fa71688b7190e850345cc18e12cbfbc6614a968ea8f98b18fb21653faa1989be64f74c3b14f9ad3262375aae08de65f5f69fc597db0f1622b09619b40f6cdaa1ee9d6f02e735ca122504ca12f539b1f2a456fcc52797b24df619f69407f00206c5e1f8f1da20428b468824a9310814907cb0f2275bb2fe7e5d3ef4d3fa9432cc3bfafb8e21b7a0ad8821900346b47d2427347ea9abd974f02fee39708d2e9ab7abdb7f92c579e13e69362421700346cd679fed04a6fa86ca8eb5b41b5670f5484b016dd323e403eb31e8f86d69ea853b55937af63470e23444628e28d31bca5949b2c0702f41b9c95977c45170b0edba06a361cef6a157eca96925c359b4e322b5c5c05957947982e2f004e10f305e142c88524178a5d30e376983e0f2665b9128f82117ffbf1f70e30282de1dd128f8e37ff12609b50cd80ebb88c6dd6cd7843f630844e1bd8fc00f326cb05c543dbaa01de46a202f242ea308ec6b6806c68a6ce7ec6b520198bcb3a82d833652fe8ddf6877613b95bf1c1049b846544c080acf3f189711fc8a0558074f6dfc4235dcefe1686f61e47db24c32ecc8478fb7746a3f28bb4887ee1b9a345fddb0b39f7d66054117142a042db5d581374c7de4c20f50d9ae8b83ba09c3b65de6f8d79ff1b3c49b1a8498dfe0faaeb60a27fd83e2d9c560e1c28b7fed1257b1f93c8b3914fe189432df01bce6f131e91f23467a777e57f03ef9f6a5240c575424e6d00b484903275f273ac1fb84d7fb1fc489a56c2c9d6c5a0a5399fedd5ef15bbe945717a1fa3d16380c9846925547e25e4f27e45c4a32f97ad727be7f0a89f0a2eea4b9fdd90d724fe17f786cee8279c79838145d9c44f8ab10a1ba795a8f9bbe77e97c1a7f1797f9c9f010f8d522020ceb9b84c9131cf0706374963b16b651b6db87cbaf0cb667c0ec173d1b1737d83d4738bb52dce80916ff48fb27d1a2a8271e208142bafcfc44a03c1087080687e400e601efb6b405c6e3dcbbd701120c79f791b1d077d30cdf1a1da5ad6733d2203f886e2b685341e3432f9cb8033e15354f235dae88026f3cb6f845227d3720f6a1dba9285e5f84873531ed4ee3f3c48a51b1eb670efb7b4135d210cfedb60f8759edbf675441aa8f4455ee47dbe7355da720a02bbcf160ed53b0249145f4acfb8a252efee5ee554a5c491f9a770377305cedcdd9dcd7926fed2fb56755f53a0fbd3528d7639c6e5ec093e8a25b4dbf23b26d6e8165de57dfc4e9157d232c19bb0bc03189dd7513ee25cf075eaba9a34e59f06f7e20607ddd7afd3757008888fc87d12f3430332e2248742d3290dc3a67925c523ee2291a595a99bd7e415f8776c035f7014830a01ea484a4c59bfff19fd344123bad88548e288ee4bdc1df714c7dfae404f0aea6ad566c9396811fdd2a9550922ccbee0524d8265a469df8feb3f4495f13ef84b15a0a0c05fc90581563faef6cc02018e701cd4bbe485e57e26d5a6df768df7fd6acafa0dc92517b2a7735fc0e00db6d96b20fc56bf39a31f58b6acbf9d6707d5cf75c638d9fc6eb8670e40bbd83c662326d4772dbe5f6166bbfd4c79ba9d38c5e0f38bb849de4bef251318d4ef79da03cf110e07e05c5e7e556e5248ff9a224c6120513ff38cc8a5f5dd5dc542b9d2089dc14c4584c9bf07e52632ae6f2b2252dc0f6cc99dad7dd3c2f3d9dae235ad9bf7b435bf207dfff4fe97e280e2f7e06b0984be6c32b3ef5188fbeacfa98a245e22e54a51f15a18b0c061720dbf26fc3f8b368c9a55e39ed44a91f8772ec5dbbf4362c2d405636edc84a7bf3f0d0ae2747c7ea301ad2c429cb6995176af5bfe18403d76720472b5b6d5ca5535ea3900445241d6e168cdcd04875fdccd44b55474aecbba43a2abaee4b14c60894629516b4ba1c4211727796945f9220b8cbf9aad96fdf9141226126ecdad95d26254d7264a67630365afb657a665677c6998966d6485d86d31b1c925c0d8ad65294e3fe1ca1fe85609c6ee529adfcd0b608ae4d9a4e5f579d30c80ef7670b7b81c69eec42e73d3f4230f10d4f31eba0f64ea08551fafd7f7637d6b5e18c31a55f191bd5cfc43102c5640e36608982883c5e879e08f7a634aa96908022d8d38488801e022c33e331265f432677f7c781d72bee5b2c17120b3c4112c4f7b3f86eaa5a524ec670691a0f72844877fd90bc0962327a187f4c587dd8fc51937dd98c161445a1a393baaf0015fcab1106bb53489059284ac2daf7320ca388ebb0f01439a281868cd00e186505af296ac4a2cdfc4cc17d78e3a0a51ae8752704a32c276329c73581c9cc8ee83604e46f1c22c1b9c6a2410148666227f93fe63b740cc786909bbdb0d8cb20fbda023df67bdad2dc7c74745a76a56a13639c1c06bf4cfacb40f3de5d73d3092ab9a49cf2eeefb659ab232128189267922030c6bc6037fc15239f055d9b9e9d5d2f601d942be46b93f406581732fc762d69126098ebb15d60cad7e86ceb45e48d2454ea9e16bd60748f086ccef3f913a58b08dca1524c666a127a1c6ef7b5e201f4a133d2d0646bf12c62766e0f249f1f96cec823a29e240ba66e166eeaec1e99c5dd386174859400a777c358caf605b2d2f3fad6e910558606cd8f926ebd1828584ea341f819ab083e96e55e4372c01ee0f0f61841dbc60b6d8da7ace844cfd6d19645d90cba8ed4b07d1c55185168e651719a0c01189b717423cfd92f8b40cbeee2f36d45ab4fc0a0af8fb5496d46351cd39f0f2dc49b192ee919bb75f78e9a8bb9a12a10b11a06f7febf9777993510c1a5f65a0fb2ba7d471326494cca739c54d72256efabda6ed56916cd125f32cacd10e911a046c5dab0c952c1150c042a2ca9fca1e060afc8ecb78415bdc00b4f0fa150e11dd7163ef1ed6581a69d2034a132e67d116425c329b7e236f6d672422d3de7968c27eba4dba0e6d0e2e723cf906cfd0d868954aebbcb6539a61925ca375eba092f5e129a2bf2f1774472b4127b21660cfdb146285e5c95d4ddba4981699f545610c08dd22488ad00ca271a0f7a7f46128f8d157960d757d198058d961d2b2bf581a2d74649e11cf490b8287aa206de788c2b31a265b33ab8f5a5b57ddf3bb063b9a99b84f15017b094a3628310e97fc77a7702568f5f4800383f8220c22d2dedbaab7a43a36aa65a37a36aa65a116483dac5ae623f8cbcdb8891b700337e226dcc04db8891b700337e026dcc48db8891b710337c08d7b88aac33e350ad57021f841e54ef50e57f129946cefe51b870ea6dca551f5135e33a1642475b3fa2cbc57ba60f95147dd2202dad3dcb2e4b6681b201c1098acac51ba437e14fb1687b8ab39d9af6625e09bf79d3f5cb8c61ecf3ab0e8f870e8245a3d99eaf18f070191c360962b2edf0b709f460b068222d43867872232336fed3c0254428843440c5e5210558f1d8ec50551aab15fc3de84c2cdd84d29f8812ea58c1e0dfeb90c061f9ecb3611f767b1a550ede02bd7fecdb06ccd19db295be0f10eace92840e00bf3cfe1f264df6a027c0ac1f5e9b223511c638dbc0e4f21b307b6b7f23fb0313ba084e2ee0ee5b660da2b66cdd55f7d8cb5fcbd577d07d8fc7c4158ff72a7dec17fad4039a59579e28bce8cdff8a1b5d08c3f9577c73d4b8b2d5816567897a93ce88e82527382e05abbefb65cfc87feffbab44a1365003ffb8be3cb7eda44c7bea62d5a73b38f31260410f5e8842b4ea33f9a17f26aae2ad96cf8b805d571323fcfe31e4834233a288513ef8052eb8fa69e25c4886075291ac5bb63929369488125072a8ef5f247b7053798daa05de84e76836f1c46bc872e9c749b0ba7181ce12673dbb141c187ff65d6139563c1ac9e2a007cf6e3977afba0daf5726732ee3ef34759b0b4ca6521a8cb447a18e8c885a3f2da0b0330088f9365415b269e17b238741e04729e37a054609bd4ac2bf521364e464c1d546769dcda565932bf3fef27ace5e5db346c36bacc0dbb51698357d317dcdba53f9de6680c49ac032e34beaa43a3175f799a440239c1741da74c0b9aa2f2b9a23b65733edc73f21c21907a8d030e84ce5fbb8074ca58abe209aeaf6b7eee3868ae8a621b5add7e1e59c520821da8a85c3bbd388f01ad6dc15f6d474115826d1ddd2b6d27640f6df150026c8684890284029eb0088846197a6cf6c626d69519d832459377cd8969e6db9e162ec788d7b5f3e37933b906b091d768dac5b14563c2fbf8c0540f2e7dd93ea020632f8cbea91f7005a0188b7f7c9ac4bfcc5414de55ad91d1582b58a4986616ea83a57b88fa9e9433bca840c3b76f88b0bee7211abed4841ec4a91706406e870ae836a3cbbd861fde9f87ca82b5254ad2d1c2bb2ed6a8c4a43a7456a3feb0b82c0ecac63ca2f7e04fdec64b1c080c877d21e2cee876fb9c0fb51c1a05a78e24fcc534ba0e1567e173c0aeb2ca9eb030b0a232590d0721a0de89b2e82f3f90a55ee0d46a9253e851325defde43401804d02794c2d7718f10739a01a9367b2c24b5d7f7bbd48c396b9eaa686e69228a25f00b35e56de8ccd9c392a9db62bebb0df40fd9f384771ab231bd08796139082aed384af3d57e2e5fa41c7cf29da7216e8a4fc09381b2493341300654196cbe9420ed9749e6b2d0b2dc0b233be5f83d77ca4ab7ebd515e1336ac99b464c4d6b3cf3609c0808054bd38f00ccc2f8e019e83406c2563dfdb60b8469f9f9ac4b5512fe9623e7c2cd2f75cff15ce66ae01b77af9852af10d8129ea451fda07df113dc86d0d42b8b85933fe1432289d4c202942531d178eabddc784cbc9ba902fdae9c785fc868dbce296909a3fe525c1f37ed30ec1836645b6154fe98762a1536ae8b30006b8c1b3a902f84cff9247dcf8a44d5511bf57c5af89b7e730a46fc7bfa12e43dff9956db248e4e171190634f9b43869bd8189b9a920f4319e7d2677cdf40441b9d92645169887532dd34725af5de7cf40cc931e9adc938d878f3c873c63f92ac6066045590b13474a5cfa9d23776b04dd7329f14b8eccda54cc1dcfa81ce2faf9049d83eda3014af7c837e3b08c5187d243d945f3d0803cb2a54253030ff69509346b668d2cf7d44598e0cd043bd88548e76e32c63f2632945f30d17b3d30c166d7fa84b29d02f288984eb8979c3a3a5ce0384a6ca90de28e2f12631c04917809892d6da9c80be4d7a3781b8a1401262f9607abc233f8f8c82d9c7df2a2f4ef742fe5e15dbdb47237ff9731f44a9ce9589f16c30d54a0fdcbbf7165e1f3519df9e51bf737b119cd86cc12b8edb7e3853c7ddeb5fe22eddb5ed19e6c7f5239b52987d8189c7d991136809b6daf70907a5f5629aa556391d5a3d10ec23d6595dc5588dd65f06753bef71260a6b8d534bd81249417c3b73029756e467b18630b455e9546e04d28e820aea437d9bb0af63f6be0d8773e81745374fd1db7b6b6673d8294e482517e76c25b2775b83f9c29db5af537a82080559b557041f9445d1a0a3e657bf2297e42f0cb8eb850e83384e4e7aa0315dc63240d69dbacf8b66322d6f2033d0121ee401a8f2ccf3b8b35ada6b2f4de3974d22933fb6fcc14f600a1b5cdd4d47909b422f06c5926f0f6dee90d4086c4e10a177295f1f2ee13fd8020f5e827a4595c0b9682f063996d905e44d7eb7f67e8b2eb769ef657675722f0df6b9f2e231680f5767386c7631ec2bca898d7d57c1d1f549c2e4aafad750885ac5226578d2f8652fdcb8ae8e51ef6aab2eb1a8522b98e8133938c1b07e844f42483ce5c5ef3026c4602d19f94dbb085939d5d089c2c92a6a3f478a53e68e7dcc8d4b23348b9ad3aa2ea524115140fb4842525e2adec14a15c52d61ef2237f2d493b3bfd0277067efc8bad456b8e9034c662c324248cb978aa9fa60159fa37429491b1136d9fad636b36f99d3c661b6c8d0d2475d65630bf575af40cd7f7ef1a45db5fba0c4e0319709621139e4cdcc598dbc8c98b85291fd87b897c64ce926e3fc8bc728ef38a6d6229356a090041935889a0b890da1922cb6a331d41e40eae41deeb6d1a53107840e916605e65e73d4c0a262f414eb2468e04bc5a5a7bf8bb1b4f8e5701dbab8589c53de245e43ef5387a88687e0c1553edcf98985bb0a80f29fa08f8e6aca40b1051079bd24248724ef199e54223448dc7509ab3890ea4e48847a8378420b99c1298cf6dacc28f2348ac50e0f5c9f7e1dc137db9b5576c84afeb5b06c98d29cae4c8706a75b017d8cef80523f3e82da369b70336a5f8865eab6ea6feeae4c0558641a37ab784a814be1fd715057013f2c939884d0a1d4b4d75bd224f2677b0a7527043a675242d51b3f188370eb6bd13c0f808c3a0376a9fb84c458dc3fea2494e322376d20abc16a86ce4a6b14fd766b9c102f48f7e555a98a21a422e5b106f11f43fd307e71fe74f3a21cbc897a3e2bbfdb7e2adb26b7b7c45813350dc7c70186cd1b13c52da0126e387a322bc5a0755c4853c4f20e48d19e0158dc273cef04f1746e282abe3c6fd55da281da5eff9e89fe8497041b7ae0ec7c66c42f3481611e1f51102f8c4cc14a4084d10210333419d7901afad75129944a7b806096600f30d90e1a9d0cc2314f1330e47af5091b873cb8b18793598f4d86a65f1f3625c32b1ca2ed4f7540167552965505aa3030c40291981d9541b3130e4a3f12f022c9e68fdaa028a4b8926d93a0122778c844c2f90ce0c25ca95b0a3c4b641eb5c62ad9ac09931c4510ea2d0c2579d3290389a8c1d2cc8a0e89c816e2fac01106ecfa0e8b17d0084ca084b4659ce700eb1b9f44eb413f607b1ae8882a2e81afe62e6d626b3c180a801d24f6687b3414cb88b9176d715547f3b2cc627be9a9d51005c89caa4e3d05a4fb09b75e5e8ab536b8dc3d449876be6e2aaa034c10e180d926965eb5e1297933ebc88518166b2f0b685a11c728758c18baf326dd8ffdda07a20065ad68fab1872a8b718a383387da2b2bb65cdf3b3bae4e8f66045290e9942c4411074a2e3b35dfc7c04a9fef472d040f2ab316a7b552d394062730ffd847b25df16132ff27a3896e629d581534a26496d54be859aab42780f3f6ee36b0c0af008dd0bb4b47b48eb1460b0c279ad67b64adfb70fb894b698266cd463ddd50829e82eaa7e89564cd3ac76afd6983c6858a05d03413e9bfaf937afcb395db1f7207880f8499507d59776c99e6515c7653cdb41c6e0ce1a5e682bf83de20ef1b0ba68c210825cd406a836ed5f9acd4fb2734f53b297c1b739eefda128363c6859d6771c862ea5778aec66803c26d999bc51b757f44a0034b5ae83fca56821c156a9181cac8444c939f718fb7a4c4c71dd577a2887d22157d699013f0501ae5a1d2ce27a64b41171cce4c547b54979cf23a9b6f0064e8407f1c4c94820745657b4b792bb65e0e67dc6422c5dd9a270776e0b51ca9b599856e34c4b4193a2bfeb979053dd68672a7738685b37185314f5f0cacf06c49190686e06de807de5fea8b53e48eda4e25e473d75820d39341f9cc1d48ef779deb3b78f19d9de6a456de823c9806bc88c8b010f8fb25f34eccfe62721283f145ffaff393efe74bc38db498f2456d21e99e08dc926032f9953b3119fd69b9a3e6c188b2908d2c2d20167976698b545ae115d7a9690b6b31911c85a4c1310d3b182f7ae77be9e7c1780412f63e46ac0dccaaf900607b177bcc5b2400f8c925213689f491d27dfb3387de4e0d6692dd069a7d468b14407aa90d588bf44ce1c44ac547cb28198077a5dfc9d79ce3299d0ca6e031433d1cf95b2e8076f26b93b9f938677e16e042d20e462477ab0feb4e19ee39347188be8ed9378c9807ecd9b8db50893bb7ec27e21746b1cdbaf035b2760b919a55273aed973391db71748832a213e33cc51e9d0851878b3563e152cb9d2487315a9aff3272db0f00d24ad482ad3531639ae586fee41942b8721dd96355dd73f043add1560a07e468826905146c3b5168f93fb05d71b86e8cc301002e6540ab46d3ffe0ceee5479f7a0466f63ccced98bc2944c37f768a5f0e942abd6f63bba51c327d2d237abf805ff495fbb9917595bc67904b11354f947c068bc2571a06afed005b180f8cafd5c7ce1d514103187b0299f2f91d2265a8ea12682237af417cffc523df49bdea0a3e7fd99db33613b47ad0f2781881d58147e6f0b16b5d41c7f69b6ba16c7a4f98f6cbd82a6a71186eb3ecf3c6c5afc84bb81464970825231d31061be76c4f24fba8c64fc4c922fc4b5faec2cd18c80a216666712aa9bcd8e6c6ecf0c6df8a73db5e626c15a0839564385a3adf52eb3d177adfb1615edab02e9094f702cf2373812446e91fc7a03aed9c6ef4037e8fbeb21166d6e12f63dec69ee6f28e0466a99dbcaa42d0e0cf4e2d4cc4db782ba5a90f3adc2fafa63bbcc650fc7c290896c4059f13fe642dcb35e29c63fa12721e499962ab92b8457dd3faa62bfdaa0fd6c26d32dafd4dcd4b889acf7519d34e2eb347e7eee8473731ab9ca39ad86d278fd6e603aa9f7ce4c90ec2985843152724746b228419d10fdc60d048eb736fdc7f2c18551c1a681e9d2152ca2dcb212883cb925638c79290a96d8aeead4ce2f054a824f512f5929572150773112e149cea79644e852c18e1b5277c453796603bbdb17a1f441b97f74dbf64331306d8442c00bc2318e588cdf49b7e7fb946c86671dd32ec295469ef8a742955b205c7a45d00846819f69edde333b1334af87b4f98a41f70a14592b8d18789b0eb20ef480975c58f60aa16a148b642571728c12c14adb25c8cf13c952de0056d24d98b393593b1495f07fe10e3a53716f49730b59320e818743b898c68e057217f13dd6b890e6e5f2de530e450ce3bebd815d82c2d799edd0f5aabcbf830d4e5f0599d566296e2ede36ca13185ba34e4c66bc3285a0e7324ae10733d7b5933fc843a3d64514cbbea83a34fd6e9275539797c6c4be486968c382c244cb035a11ed7e87f14eaa1a19d4b05faeaacd988f562343ed269f19d83b2d8056b3618141975eeb8c6f031a3a8ca934e1221f5317215bc85554f945223043e1362f1c7c3f46d543a2e4e77691fd788de5b40cd572b8f73981bb5c9d55aad5160a3d446b313e7ea2ad8461e4d56771470351b04c58377e5b3d74598e0afa6fbaea1947f726fc1e740bec80475bbb9bf029825ded0d29f74f2f2d971e2001352ea392f284569c6513dd55baf152a934036e841a50f2a6017d5483f58ce5b55030bac85bc266c36010d30ce507432028e5ae8fd42f6bf1e8bc47b9f6d2fc7d1282d1a1cf09bf0b89c21e71444202c1483b7262d2f300a19382d84d0ff4974ca4cd86a29757820e6c0ca4393d2457de019db3d5eb21e115d7b836f0833d8ccfdd6022ad5f0ab8878e1de61e0ec90d183b3fbe7af92b3212c91f54e1e83e20501908777c85cac01740dbcf55204be0384601e6af861c4d76bdcebae0996a771a4e774781dc16f53d7ec07338da4b997e6406f4d67f2e4766b496965546a484387d4d689921fa5e9952bff47d1c9e20ffb7e21b5e10dc647a541c6f009dcdda0cfb345cdced6355f658afd3d9f1319ed029b6284ffd1c422f885093d6536f99ae49a0291b45d0b066c06b0a726a99608b469b02302f64b6bdfc1045ef2783d19c7f3d644cbd608bb0860d4fe04275a289536c340500b8e03916b3836a9ee2603fda518066ab880ad4da1ba0983c75248c0e9a2554b6702075d146c9f21cd119a8c0e765c45fa302491c32cdcafe004582142c3c90f096baf02c2bf1a05bf9ec830751fa33faeb6975dfadee6230820a807a8e6631c093e27ecca4b8e70da68ed04e9db4b3803ef277f10b640122ecad20d5b4a3b06fce708281bcf27b4d7b24a47179c5cc06a6ba1b531daf4006b55e0e44a7d941b94c215f3127791cc55231440ba7d42c4d5c2841e31121186baee20a58b955ad50883afb5e1c561b20aae55a84f60158a21898d8992a2b5ce6ac177a0a7d8ac4cd3d256104ed645964551c723b566be2fb8a43bd401d40a580ad1f6c1bdfe3e85b11778fc267c7bce8a25cec05c805de064577f8828351d352bbea70e4c44edb0d131884cc40b9b52b7a3e5ba477e7422c184098590d968bf2a021249077c83bc0dfb4980d75defd90dc28643a975067334dada5c2b546f9a67dabbe9740e417dfdb034530027de3c327e40ae1a0709d92573733993b82697bce00f5b3f114fc2e2863fa9294931b527b33ab90588e2a5289c9cc67bb1fc31c4223197cc50919724d4d4d229f91d0706e63ece8042496e4ac171a7808b56ac9c7a445788bfeca8b093ba9b36bdfbc2ce59253d52ccda0547c3b75cfc3c5a24820d1273ab74fc928432fa67ffddb226681ad189a9fc68be4740124ed5c8b516d4721d76f55fcce603f3e93bab3200b9f8d33ceeb03c641092d311a9fb549936b17283fc6c8f4c11f325970f736e320534aa49b9c168f00a5289ebba0e03a00c203ca8c68b70276fd99f4eaa63e892e5c9795527b885fef9d49ea508e51caf69caad2dee23cec65e2b52c93a53905bd1cfbfec68ebfcfe39c45a57b0d58050bec6f8df6d5a740c6d537e7834f248be58c0c2df642914d5f8e21dcc62732c50911ecec4c67ee1d89e87bbc275af8b1949458f352f7df8b7e1528523eee1c6493427f579dc2d700391f47276add244bb4496df122fe0204a5566a58f7124ca91e6e683c1d129cd09162aae8357054f2984c22b49c3a80d7756f4da82ae2a504691915219f0bec78223ee2d797f79c4e4639656ed915ad2b4f7f1b183d3b5b77f3b3a54d9bf7b12843d2fe1e621100b9cf2a020656d925979d07f547afd1aaf653947508cd9280463326dd269e3f3645f8d1d509acd778a262e30f88ca0d22c9d438a62ca018bbd6e2e4634095f48722854af89f3560e1458c3c731c8ec55c221223dd1a372eb4ad288ef8a5ebfba8285e6a771080e3bdbcbde390230f5b3d00b0971dec13de5c4abba9f1c470a833814992a5a1c2eb74cea31194e33db9b92791fa2d5dcf8293a4744a4b50f1e3f62eb0d7dffbdf16fafc56670fdd16046aa0c3b5f5681c86913eadd9d2af7138239bd0a6f1db3103b8b028944eb6fe6df5d40abb3ac80ce58e1b254e885088518646c73730785ddd5e330da65aabb0de26b337c55f4df45f5d47c0ae3739381c3b6f0d223a38be863ac0c3f78b1eb376821d4b60d924aff587e4abf4fecac5147a892f374372d3ab545c16adeedd51e19c7e666df2bbded5f1dec4b8b6062519290388f3f506f16098db0eea0fa544d9e1bba89580961c4eb9dc745ed68fc75a4b0f1aabcdc8d5894eae4da542e5d8c60e2dec6671558ac8b92a430f20aacbef8734bad34cea10795c92f30ab568bc890d01e232f7686a60e9850f39406fc65bd2f8282a5b0bb04aee039496a48aa776f6667253b628b2301c1315a1f91f204e10dbe70d0bdc42001e8a6f027ef8738e346292eb09ea5dc65c6123faf939222b0f22d6238372822322b6665ba4a62ca1080800b65af9001731c992161e01fd1aa44d35ea384b95104b3bd7da12a8a5efce4c003512c65741c3b5c4bafbb876c9650c0a08d53b666b71d8f3ed70731f1cb628020fc7d1e67b046495d1d7f1924ff2615271db3619bda4698eb2e02d428cbec6a157d010bcf377123ad40124b151a1b6b49ffc45311fec7493b5076527bf709cd094d574c7f39f63db01fbd5897811dcf90fef04562c1d2961c98e47a55b84be4e925c219f403bfe84ea6ce8264aeff30ebed6d7ad29dd98b4e47eadaf600cf05b7a46f24ab0b5f6bac9c8ad60c9dc777f7ef4fb1745f01b07ef3204ca2cb276cb4d7c4630cacb1e9dcc0a4665a239b97e09f6c1e881a7e369aa2e4dd782d937d86792c36aede5b54983704cd7964f5ebc820dfc82ca9c7099bcedc7674cab10e88cbc2dd8ed0aba1ed6de6515d7837d3ac2f9419de648bb2e222ed7e25b26b4f0d78e398f53d881495d83471e24306feec9ad4da2f8fae36ec609d6b474b72b7e6bb1826b843a2a7d828562c889128022d2e1c1f58ca528ac9a6b84a5b78164e73f9c1dd53b399be78219fd8b097b7ab4063a9d0711a2a7e19afa84a4017ac709d65e8e0af3a26c1b659abf8dd27527d88d1d4a8506ecce37facea4d69ad4acdfdc28c7b8c806b814cbe57da5e53a2ab960f543f7dfd2c3227e3f5fcb7408cc3d253b91c821af9ce5e18c5484da0921907e3e1dc60043c741f157a7b3444147bac81853909608e2e88dd3d34565249883695b20573118573656d374fe05542ac2a89a0d917672e44f617cf0bbb17c45bee229568193015c11703da06bef9e04d6b90dfd8bb0067a4957ded2d796d228d31bfd55a0efd5619ccc6407b21bb1a4f699ce332c6c0761e1f8659183fc057a25757dbc9b5397554e93a2be566ef9ce0515e0174e045175882084659ef0c8a0563f470e9b7900a64bdd1e2365e2804fcf4914de9a64f89f3a21b628899a9ef00921aac8384e54401dbc6ce0a1d90cc9b63ad1ba071aeb0e723f02a7619f8ba3647982cbe490136f676efb1842a1890216de0ab210e9d59a294da067a603b830f6d80891072d81131362c64c9a2f7e66858cd5aa570afcee71dfca7bd000ad0fff232416f8fda47ed284a2e52a1fddba4258cf96d7926e96f643f197246ec32bf429571b0877892555e84f0b340a8a8756ff10b26ef5c4b695e1b4f95ec1188480f85a4f91354603032f80b69f68f06222c7bee24fa13ead9d7d1221f77e6a5bd0d9eb259d6a7e97db392b79c5e308638e419d6995934b41f2a04407caf4b938c1c83d96244792767b8cf8254b9adc03c0ad821ba6535c1fbe8356939f446f93481ccab1448c7189f34af824db890b020c5088c1d5ba4b6fbdc752cfc26abb26fbed54f98e4e52b7b7602d77eb2d10f35681c6338a6ca996150de0be02c8f2876997ebd693f4e4a19c64ed834b50889a2bd28f1c5698c83e5463963db3262c1d4ba72bb59c59190e15cf4505ad206a348e5b58234a6e679e9e0c3c6dec269eb735b9db16110133f8097968a39c5990c528b5a2639e658544e5c803bca7cbef9fe1cd7fec1dfa200dec4fe32e45e2cb2aa353ebbb94326372c0f7b9ea82bd52a69e1799817a56d5aa5cc964dc7c96f0ca675615d95b95864d6b7a5e6c4a781093e8109a1ef24bfb7157dd2e18024140807fcd846583839f907a185acc5d6e445a9fd294f3c119843b049e5067df108deafe8d0ca23cd6e2aa4e281566824090b2021fea3554db66e6d2d926c713d009d3ceff98a3c2cbaf48a43894ef47d8709288add1ae4d1d24d54ed1b11398b1249df3e2e5dee9f415a7a8e73d1a39f4e07dcfc503fd6bee813d64d5f768114a093e1406e4bba2ce79076366790f3227e4cc3311c87dd8cac136204cee515ce6ffb301ebc6b3d0204b266a31506cab44546846e30d28fbf0de6a0bf98af097e150c86fb2a1cd51dfcae5acf7f546717435efa8f241030fef1d834f334352774369209e974597a46f69d8afeac7f0e4583f12e4c898a6a311b4ec061f0774e535c6f0a212966aeeed08700723f587f7d05a138156504988f7e6b74466dbd3951f9295d171fce95c1f4d46b21687ea4323c968dc6461b93c61b65db161388062c18453847c0a407186c5017e8e267e3d48a677b7a4e7b635ae5dad9871dd3fe81576812764688e617dc618ba79ecd6059ee02d918d6e33f49d1d3c0b550fc5119ba36d3985f4a0ef4e160e29a2f6a1033f3ee81c9463fc4c140325a2ffe33f95d9cfa9f6f06a9d156b5538f18e8ceeba4e68b8a223237e3bb2fcdb0843745c047b37c9d158a134984738bf31c517504186e2edb4509e08c2a547e9f6f33afe8bd36222c935c06cc6b61c5182241429c32dbeb7d6507b806328fe3ec6ef8778e59a2f3239b9bb166bce70a0e7da04706eb5cb3429715d2ad66a6cc986796d3b70e98c9faf010904f21f2de37fd92548d082c3daa9dd4a67bf5bccf6fcdb8da8cb268a305290ac00eca9f6d2c9baa03574a2dcc2c5bde392a60640d0630379a8486be69d2a72b1ca8b5b3a258d04b434c9f2199c996e9707f315822aac1c58b881b50904c5a17048b9c06e1e017b0b4f94d916d05dfc19bfeac13457926e6d8bfb4fcfd0b8d378e3937685c26a22044026008037f564bedc3abf283f537320a09c5c4af6735c451ac83f4a97dac04ae8453a5290d1d501403621043550bac5c591ebec5604e26b754fc7d39ff0f494730c8a406290c9887705b8c8b49806698d8c52a76e9eceb93d479d27406ebaee043ceddc6530822fe9cac5983778192a8ea824fe4c38b911df6af61511491f8764388100a9944f6378a25ef56483a92b16d0d320c51eedca661aaf2f2e5baf34f40ff718440e64cae36bf046eaa187467a744c90242d7f4bcb6dda9a32946f381fffd322c2b74581598594c021319faa32d23b3fed21565ca3a9f6eec815ae9062c44ef4efd0899f9e61c711ecab29ab6f335ab45e7656884bd5b5ddcbd12fccc35657d0fb0146fc8e38e8f53ddcc423063e3fb4c08993d2b588205f5a3156d63e7460a9280e4f0bc8636028409223c7944d07ec0bb78369e8b0156f318ab9dfadd5c66a3bf39de0974ccc58ac0aca6cf71c013604ad709f1066b8bade6a467470d06aed70805400f49d4f8979600f4e43312e84789a2dc370da5a17c8f456b78979982b9e9c785b934bbdf02b135b61e3933d0a4cb5504eb732a9f76e3499c5def79f7c87fecf20f991f44399cd50d78adf40aab5e975a4407dfdf2a59c3138125ef4329c79e254163f6d0533139c2f0920a03d0dc8b8d2e4c677652f96eeded00e2960791991d2b0a23074782b4a557a61ed680d83d3e268cf67334091286849cc23b43356aedb670040ac1d54fc6e17b4cfdb339816036386b7c0452a0977857a380fd9470eed7458b1b3b2a9688ae8b8d42fdc5de942a69a3654993474726a0a07759115d6576688297347812a445db6d402cd6474491c8f80d03ce6165015cc0e3c666486bb4a9306c9eea7574abca07dc163bb0c0996010e26a9778830f92bdc90bd242ac67a6e76b021d5e3565fc5b266bb71337da2931fa953073538afcc4122461dee97eb9a7da21b40fec03b78611412e02402a64a6a80978a3687dd6569c3ba540637933c2bdda52aab271a524b0507d75e25968ae7876ed51053695d078320135f5e41a7d20d70d92979de7c5b8fdb1f5b0ff3ae7ebe81410eca27a0ce6278d56ab7b5b781272d46f1bedb520dfc110191e6c05e10d105433dc53f495db69d13e32114f8691edcfbff1363252905fbffe923b49335814fe5c73c20b6d5dc9dd6aa288fd6506fedccdb3c4d80aac5889da9a8d8ba628849b48a266423befedc82da9a5f161edc3739616939f7fbd2bd15320b750d58e10ecdc9d2a774ca273235ae1babf0f04e9a29e6342b79434f4332439c5bb0b858f98e8985cbe1492f99bee12a471bb121c6f5e06277073b9f1457b5718344a2dd57489a76a1dacb547a3f111a0d8d7bb9daf6b3d3a9d07ac264d05c616e0d1095fe012f8edcc4bc34a55d77d9af0ca5c63fac97788076f2abc282c7c90cee86d793d8a183d63484814ee6ae77c4d57bc7516a779fb945dc0944278b46a9167706491c4b70034792b8309b4c1644e3e600fa2df83b62b35a604b96db4a40f9145097e21b981feef70e68176a7c9979b5b8538e17fb26286d7c8a5ca3a7eb718e0d793b08b7477c7cf650f77d4bba7db6a57ca416213430ffa746d4179e3ce34b4addc91a1682c597458a12f6f76110d43d67874660b283209b431492c6b5f12ca25b6c0e51074f3363b070f95a7b5b0717cdbe4d71e231d18f15eabc813db573183e29a5e12e540f9212917bf5ff9c3b0804ed62dbbb25e62efeb6012715168e5292179af5aac6509890abe973dd137f86af46ae214bd038816ff6a81be58f66225926a39b10b536a0b43d23fefb1afa0225a7e05df1b111f025f20e3d55d863961fd88f96ccb24ad34576e5590e5f99de82b40596a2b23d242886d66bc6872e4ff80be3ffba34de3f495ce3494c245de091f1b3e3fcb0fc851573b777773fb01879ba2d694b8a7f825a9c4b6d3fab7944c85db50e8f733a471199882342aec3a60627c9124162f98698145c5538a6f3f937e9e9c3b5ca3289886a9371c805336732bae48b8ae1086d9a4cd8c504682b43575c559c750959a1764ae00de91f5c9900e7e660169f7995d23250ba0685f0edf1a5024a719e9f563ba6a9abf969be472a2772cc335d2bbf8e14183f2eb2ef4835b10b918d3dfd2bc57d14a4c9578040340b1da6a7466a457b2227e4547f191b8c21a3658614888633e29b136413c5c68395c0eb502b7f5f5c14a15c831be818f264b4417c0c44c856c5cd254357c3afcb922c1087af4ec4ff82ea718b8a70f223eff31bb4683a5ca7d94470923a02ddfedd5c6d6f71a000f31e7906b197df539792ad1853651066b5eae97b43e7412deac848aed5f2886574d79829669e9bfa741112562566c8dc6198fd33e7972d55e6f1ac5470f3b947ac90104ec8084fa38e1bc29d6053dbc640174766d8c966b871c4302194ad5a9a12a0a5fad46b3eb51450378ee7a1a983a272650be43eeed18872a66cc5d4da3d9d236eb96cb077000a9d58277e034d86e3b1bd5a603f5790430054966c4693000478ceac8445e4d46a7fe6f10ca524ac6760b6fa2e881d07621fa06bb57514f7558406e952993210a32fe31cf15845380d49782dbad4a5a89d1b3acf69eadef642fbca9b0e396d220ce10d56106d236d4fb8adc7b5cec1e3a859a91f4de899d7be226087d4c124aa3da7ff58b159d8da6787b2ed471ae306f7b31cc0a56f68489cfe41dff373fb3cd21bcf8bbd83875f7538eea8c09d46cbbe30e3312b31c1a63dc5c86083daa4a121c46642496e13bc89602c3feb8a98ab54e40d47a0c75d3ef26c33ef70034f5f9962edda00b5fa0401a6301bdecdd5cf6e2c4ab62898d3758e961fe97c4481a0359f99a268a1df77abe27a88ae53d5182bd95aa16230700482b19ae1a5cec7931d6f3504c500c93a3c18d52dbf47248b84c4e60862283cf2476888a8c693a0210c81bbd958cd1d40ccc11e2c0525703e8845a170a8980ec6d40f9912eee8d777331edbf8a0c07b5005529aa588eced695b2b23a884e3c37ce4991c3a0b3e93bd821d29cae9cb7fe1d6db3ab4180375c00985764bfa6230ece0c72374d602ed91349f6db758dcc55b4cc91cda6d5d9dc817d7bfa0404a0894b85f52d9cd5468dde47235eae0ee5d4a8b1b7eda9aa5718f78a45b61581fecc2f9b4ce2370e257c9ca5562e9427545db43bca87fe3ff406a930f1e02761ed2d62dcff6ad98b15e4cf659be3ed83124d25aa4c4377003d56ca120c7dcee392eae01e9ace09b0172d877d63585671f9d3f32e19286ed64d9b6e08d59d14da90f249fb84b2b23069066893754cb50deb8686035ce8c742990326b406236fd65fcddc70b1f451d064a875d2a3920b707c9d814da469dcb433d45a9ddda0286673d351372239af39007bc4388224d3b983d6361ade6d1c3c7d4382c07fc3ddca48cd20b10846a8fb4d5801943300e4e1fe302aa0654fbd9d1be7e05228e0f8130cb667dfb45c6b47b6f8813d2bb53e7c12c24fa08925dc330886701e77093a64bc02daf7c726206cc0d55da3bc2a2ca17018eb5492f286ba20c83879c7572330dc98a9de39e5548008b1c81e07cd610c8b38043f6c6286998cfac41d4a186ed5608ddccb99e4e7c10b931d653a8095e08f63335c6c63f1b5bfe6208988b839b6277d4fba3ffe008c88126f500878c5690499774f136743d0096bcc815c244a47d5d339f81ba3bbdbe37fdd7fb2d559b5dba0b2d1ff6cdf261c85af487c1a0487b42aa13bbf4b70ebd33a5fb80e469b5d24c3573dd4fad752186098fb7e1d238f8b211cb710003510ffcb67bbdbdfb23ee20318b1959ceea83d4b8d9daada78e5f04911d0944bfb6bf77a7bbdb25b426d7540052a2ce622f00f0c05f7a46cbc1329e6f504e3c87e44748a7f8f9052d4e50b7ff7da7be1e8dd0f33f84dd18a17c49d00e7b7767a2281fd72c53841c1c9c1f49805bf84da51601f745dfa87cb4970c7c2961abee08ebd9b09ddf7996d18fe645913ba2d1e8a2e67ce9f7e722ca6e06fb6a8485d81e44d2c874f22deaf647475c2937d0f73db209e99bc930670e2bd67772224305eeb64aeedab887fbba905713e6ab2e6cb0262e4397cf5f233b602a269173aec60bb7286a4452c7f68a67b9a0250bf372b6ef9243e09dc60414734d2e85e4bf5fd1ae60a6f683008737ee765959b83bc2832c72474beca610db38cc501c3d33d701e1b5b52d4e547704801730ce94b2956f93cbcc88879b456f78a63a915fcbe8e6466305aa3c98ba04d579bbc2d2cf323ebbc6010690fe6e26afa35d8eb19c7d39e8b4f706cab9f4911b45d1e25ce0c68f66685e820e50ea6fdeca9310ea1d1aad2cde99dde6e61ed27b995cfbb86de4d9484d2245770706bd7e7bdfba3fde4e10eae6c26494766617d448fb2bb5b489fcb9043280b3b51e8229cdbc3a68b07d8495343f26d34446bb65ec4a4343d40697d835b45472988f1effbf163e69c0804e0828f14946661d541b3f6cb50e348f6c104a2e6c890ddaa77ece0e035c7355bc6b73c639aba91a5bd9443d3e4581c55ee60db9044775580a5c632bf11d305925c878250c387340f6a6be50b7c01a0d0673ef95aaa4e863e4fc9363e738cd42b0e2d7f2813c8ce59276479891959c7f002c032dbbbb767f0a36619e8506e6411ad30b76369e9bf0b446071d57217e748d9f56b62e2504f16df9e3720b40e15cc15085ad87e94979e14ba993cb9c4c9f032af083586d32c656ec2c8d23eae682738f3fc84c96d756bf4f4e8ef7a25f5783ca2409221bcbc03ebd8d632b3bddd415589f415aa865dd5ff053546797afdde330176d692d56d707c286417e8328c00a829d83f149939a365bbe36fd21d4ebbbe155220c1011fa16baacea356a26bab55f18f91d7ad9153db5f3766d0379c267ff8952f8fd229276257ae27be00040be2c1e488a22a7b6a2f6d044e47f11e593390697b80a1daca2172d0f6fe5243cf90410fb78336e7661216ccf4a18c4dbfe26f93555608363c459054d222afdb2eb770cb5ca94a803268b9f8c2209bb5c23203da5b2e9883928063d6627fa946177300f80f06e73875a73dc9155ea3ee2a5cce734afc4dc54f0f596eb6273c6e3d027aff4e7c8827fd42f0be8defc5c6047a6b158eeb0c22fa176116780e5b3d0283196354dda8996c0e57d21d6b41fe70b09738c903b960a8b9a89f6c22b29c73b100f2710a4bafa22f075a033b8ed9f8516111fe798b933798dffd06ed8276b06c469459463cf4caf55c92b8bd6031a2dbef0105d73f190444f176881a0c42bd82bf14f31b2b826aec3d6e48b353ae210d2fb4fa2d0887358c72e17b726827f3b5d376d3586a62b5f90f6febca2eac50734a0aaade1ebfcf6e9dc5859a53a2cb7938a15e043cf3d4f98f788af740d76665fa9d62c146c36060f4c150c0e1ff8d667066c2630852fb30b29c694e78a8ad666d6d7377b7053d38c13a7a3171384187840585f0de7891bcb6325957004f78af0b1674cac1baffa989a3f30c05de51290533ecb1cee235dc0a7d630e7752068c670f646a2ace55e39a81598af23822f96286a4a15fd22ad74cfb6b69ea5a6967c0dd484833dd4baa7fc656d910c28c3c0fa9a3f670350a4bb666f97c0a391f78865a9a2baaf1952814b5de6017ee6ea71737cfaeb81105776b0b75bf994208bcd3729a844e445f6bb941e88fbcc838fbdd70fcaca187a1109c85a6d5460a0095701b0dba0ba03a15cd91372606f295ceb6d764b3a89fcf4c50cbcad02babbf95558505ed13407499c3d40244b7c36247396b690da40fa1b18f0fde2e2fac82fcee7aac5349667b45d5201786eed1180818d0dc411d71372e62b4ba6e163f1b9bf1e48bb8a6fbf9469a785505544425a68699326a5c82d53923250055c053f05b1c556a9850cf686e9a54952190ca3feb90e7a333a44f62390ba00fa502532ef3cc690865cd9906b3541ae4f95782c37e4fa94078fe5218108b9fe60c3058b852c855c9f09b9fe34866ea15d8baff4abfd3a69915c7fdeb906fbb9c595a2abb8421472fd490cb6f2c09afbf2a4a1b694fb74d09722d74171fb2822d78f581a21d77fddf24eeaf3e8290c5b6ce96828b6449756d17cfd08b34443efa4be44c4daa70f1f5618c54300a00653b0c1a8e56331754ffde7d21a46415a3eeff3c38f1cf928d1b1a555683ca07f7b8135a080c61af01e5edeb4563fbe8c3ba3b5fa13182cfc583f0686301bf952e4fafdd25aad956badfe15629fa6c16e346444080db98ecdd71797e62dd03aecd7af000fd7b1c134e49efa153ff7bcc0d55a4dfd09bb2f4f1f1a9a5fe7cf3a6bab54d4042598218cb9f124c5a6a25c23ce8d2789caee082e980f767b78f9fa67351a8d4683e36bed471016bfbe2e7c27f36365616a06db3f7df55e754b6bf5abdb2eadd5a7ae0a727d7a85ad4f29b57613caf5a5a8d6ccab1803574c6b612862052e4aee832239fa208b1caf5041aa27cfc42a5139a7a4528d199f9a82d5abacf9c35b3ee945b739f6c7fe894bfa252dce39bfb558d26f739c42bce82dc82df260bb7a9c1f1fbef427d8f81effe14f776607c05cb1ccaf62000932e6040e48d6291522e1d79e945883cbba2c89ba47b752555515a6547a7f4a9a2497666c284a75b4421009a56c0bac385441762a56767845acadb5ee90210e1d1404e21591a0e0f134e8454870e16d53612a72e49199b83aac9a96e106a0299ff4e6bfe9b676de348410c28f117e14406b73fe04ef4a4a6b93c219638c78cbe095942b80d6e64aabd8ec234500ad43c6677ec850848c7c6f90fa88b5f91121b2863c5f9a73ce39e77c9db4627a2ad69f9d753e08a77a29f516d93d7b7d932449ffa4f720fc44bcc54c3b4e11b5d6606b0d351cd49f4e92b4802bc397558f9b1b0ba9308ef6f8c7aa8756929223fb9bbc1d391e8a3fb42ef899955b494ab9c0ca5e31c9709340eecda6d69cc1ff4ee03fa4408ffaef156f15c8fd3e71a4b896279d5a6e5c12a598699a84fb47f78d9124646a84bc51261021030c3c4a4d646f220ad9ad40a5265c1ed32afecfba28fb43f8f1b3e30d668f81505861fdb71bf9bde7ed98ef252de6357928f0bb4686ed150f99973671c38367a924035a96192c44cc717e6b71c6266f68cca2480a444552d03d21bc167002d306337c4991244d7a2b493736c6409c2449923006602561a079e8aa07e684a654a8940cac54044948e6e54f5a18b2f590adbf9025e9b7ce0246020b7d1e508a54925e8282ba47b237939d0576ebd7f5c443a4afb5564ae99cb68794c0c697be89f02418b9375268263412aa11973ea65752f316332d5a8b2d6f14017f29724ffc172266189f4e374c52249b9031520c438851c2e428a9c8515691e394a9405a659320184434c80824d3c88da5282303bbd1508e344479d02a1207add1c8b09a328844a2551a4b20ad5dc9b5b6807ef9244a06165291a486e93dfc27035b3d18193e6592a18bd93131bd7fcc09f6fdc2fb382065fadeebf77230e1e003f25bcc39a597f026494992f27140ca9243393f3a68da6c28d57a0cb631edc04fb4db37ade2f4cd900d35e9e2708d89b9e9f766b48a84fb67b44ae3178398198466f4b3ad750b0124a07374c72301f0a6d0d7516aed66f33fea77906d1720ad350c1a48e7004936b05b0301d2a01c2d50b05b03a1b4457004530511ff91ffe33af2dea7ce5a29a4f3dfa7ef6bc0ab220b9198fb8f8419d01ef80960e2e2680d3a1027da6391203728020c82021c20410a5094bc0934e4f8032472f4000c6c8f929cb4667e34a1073d600110700084222cf841911fa001c707994c26d3c11673b0066338c33006c6eca076a0301f55d5c3f5d27913387d6545d16371f1fd7189a7a3d6c09b461323060dbcdd9b3d9ebc4591c885099e70852f4c3bd8620dc6708641201008042200d52e76e6f0bf79ee6f17eb20f94da3a3e4ff9560cac7f3f493548a35f6c6d83ca65adca36950c6f0d650d49c61aa058381dda8a8c5ddddbdebbaaeeb3a8ee3388e6b98869976a0b8cee7e87a89a276b13493a1199aa1199aa1192aa2540ba5d66e36ff9af6ea6f29ed4ea38846118d227abdcc79bdcceb655e2ff37a99d7cbbc5e72ff9472ca29a79c72ca39ea7eef9c526b379bffe85d4a76ae3d25672afd57c9f8afe2e0f74e7c85f228c9495fb5cc60a908be8848e010a09fcecd7c00045b0866a500296f434805c8bc8940aa1430f33682fce24f74528bf39cfb3200eee64066dcada9b8e16e1dc48a0d8a36777b2318777bdd8bbbd1ece27676b7e8c416afc8fd9abb493bc8fdf66e5216367944ee29b659c47c22777fe66e0e646b2a2684a20c2d0e12093892c486283c91822c98408209982dc0f628c9496b66a2aa2d4c13e6c3be9fdec57c5c2db9ebe755ffb2dfac516eeb8adcd617725b59c86dc5e4a622f70433811e0b12ad72c4db4183c792f96a024da26d1a927bea7650bf4d49e4dea6bc4d2037f24efa290c181abc590cfb6dbee4f050faedf52101eee9a797c78a7b52ee8deb79289ba6324991df7b144fe565ac78f9c15723a7f957f5e0f06aefe4b58a6559d81ab5d653e84ea06a84dda650eed73cac2e0ffd99f76d0aa24992f4a05bf07b80188977d253a4aacbc384c44f1255dd1e9d8568a9825803f008eb27d03be9118410425855553581e08e1184371e4b07ace7ed90be5f7b2cd6f7e36895e9bbfaa6beff6d8e862b727b37dfc576e7905b8719c43d8f8a1c81b44ac6486bf1054f257386e79998d10c727f0cd1d2f29922f7186995d975e60c4f651ec1058c7bfab35a2ffbf00ac1019a2190d65a25c63983c45c98297d178a95f027c27e64fcbc2fde8508fbd9fc0f6f43cb8708fa997f5d17187f7d75ebe5e887669e47c3b844fc07c66f62fce6655c1722fe535f4646c69d8a7839fa63dcc9044f87fecd9d7cbc1cfd306e860d4f87feeb66b07893110fa55fbad30b9ef674d8a615e4fe89833b88782c42e8f74f2e2d5d8089399b6943260b4800ee3fa32e80c59cfd50b863c22e802ad3f74f32782cf1fb27144095ccf74f2c782c42eaf75b57c8fc17d6fa29721d999809486b47782ad30b9ed6df788a26d04beecfc0c008c1019ba5187fc1936202d25138153913c3e57eac21cd6f2f473ff5afcbd94f855555554f5babae8bcb0f78e4a3447c22e8e7c73c72e4c807565f4d3d74b6708c57d15a7cf8dca74b921b27e24b0f5b40f8dec88a7fc8a3b52f58c72badc16f9cd2da64857dbfa5e423fcd01a109da33719a584ff7e7bef436b40fc0044ab3cdcefcf9fbf87b7f9405c1f7e78fe3ff800c4731f8090f0bb13d0f9e0b82184f0c1f8d02a3fb40a10de3cde7bef01a1421345aaa00379061c9b1ddcf38cd651fdcb404aa9bbbbbbbbbb53afee04dae34f371b7f3017f0015a41614a5ffd1f2e40f1fc1f3cf0c3103e4418a586ad79c16ecf8a0bb4f78cf38ac9f54dddc3cbd64fcf3573768f21a08b094e309256107d94c86c00e617df555f6ca82680d3e3bf682619bf41188c71d5a3213d83ed0cab17df512ef13cf59dc8b505b9bef886d248ca42b638f653cfaa87e667d563fa57adb56f37c9e5fad4fe0828164093a2268ae90e9ea72e912b97e9906e41aea0aa1242a5a81e916b4d22cbf8ad8672ad1506b956d0d54eb9d01b24bc27639aa02c8f080521cb2472f5411ab9a7ca16f7d49fd228d79f8cd84d1a49a3c702737d090b1fb9e2cd16218dc8b5259ec0c221eea9f5a91a6c19ec4643a12bb6079a852fdc2e1e00619debdf05ffc598d26992524a29a5537abdccd168341a8d46a376711f8d46514836d190524a2965942449929e8a224cc3b92ce79e739e8407c1662c9cef8f4cc01d9aef8f166b1ddcc93a9d2ceb78f74efafd0927e245327c3597122e293a1aaad1585362730d338b56b18fdfe5fe0f78e4f38feffb947447fbef3f6f07e7df23e0a960ff2089e846bb68341acb031f00c110374058e7d2607bc44f42f23ed7c64791a784c4a32429a5b08f71c8a4198b8a44548b24499224491e638c31c618638cd18462e1fc7b10bc1d9a7f3fc453c15efb0d0221f9ff0d824a7e832d8f5abbd9bcbfb8e742cf6c50119290dcf781529e2495dd2833d11b4a6f4e32634511e7c625de49bfe64626204a3f766313adf593dcf729b91acbc1beb5ff9f708a8537edc2db2677f06635d7fa7b6dfc5f8fc743512d36ee8db7b4fb63042d9f1bef993a529acc384a5686baf7c66b6efcf572c164a4e82de19b66c6e2f14e321b968395dc20c1540be5e3b15cdf4f9500eee87c3fe5d22ad65383e27460638f92522d251dcbf1682478d2a818638c3136d542b5502d548b46693e3f22afc8c96f8f0acfffb3f11e0ca594d20907d5d2988a688e94e6ce3c49949c24a5b992e671bc07c74f95d2cc6966aceaa9e8b160df4f97782c26df4f99803b9ac0eff27f7ffb1bbf6d288985a916f774fe9c5c1cd7c62db913beef6383c2fe7d7d2c9d7fffe00efb5b66a3b4fb2e25ff247808154d3428ecbe9cd5a05ec67c7828cc070af58cbc2fbc2c3c2abc29f2d301633e5914c57807bfc5ef63daf3d37b0240b9bbfba41567a6497d755dd5da48903b96a379487009d542719989aa4a4a7eba341a8f099c6e7579bc93ec6fbc76ddedc5905c7b2b35fd7d1f8bc22eb52e8ac46a24f5990b172fe3fb3e5a8ea2cadacc45f662f342868cec05f537c60dd4c798c1a19ee4e21924243ffdbf76dfa78424c68c199ddbc12598c6a44129a594d239e79c734a29a5945292244992a40ec626354c341b1a8e89e3d65a6bad95524a29a573ce39e794524a29e58a2449926452f5986c5017b787baf77da61b271409c62185c22457520a5f1b2454e4d91bd1418739e79c734a29a5941201ad7df23b7931397b2dfb92ecdf0d0a8714aae4becfc521071da87b6d94601b4f62e3a71c4a4a7eca91a35e99f324f77df06bd09c73ce39a594524af968aeef24fbcecdd84bb566e396dce75300280d1600ead23ce9406177e6290785afcc7fdf47ca930a85dd98a715cff8fee81c29b93fae2347dad0f2f17c678c7f62a1fe7a1ebb30dffb2308cf5351f61dcad96f74c88e9ab1347065cddffb3e7fdf07bb2f97dcf7718ee3388eabb5d65a2ba594524ae79c73ce6982374aadddfc6bb27387682d7b7b410051b2e7dc0fbc93ec3d377b0d48ce9ea425678f2f97b318638c31aef4cacaca0a7661ce2ecc3aa8ae416d4417d13eb0b8e20b4fc78a4b5688e810db6d5e1e46a3c263e6c8dddddd57382b6ff1f6bc8099c009cb388ee3382eab4ce0845d150f0d93cd1166553c34c8478e858f7ce4231ff9484a29a5941cc7711c4729a594d2893186332c49922449528c31c618833062c44883602015f2835344f18413f93d5ce2e908224628a22d96db00799016e47a99a3208ae8608b31ec9c6704de20f7af8c38596502276c62a1ba51bbd839ba5e6aae3af7f453bbd93c27c319766e8e26167334477334477334e79c73ce5a6badb5721cc771190e8542a1508885da41f928000563ec6f300493d8e01146541f783a60e825fbed8df21389a2e87a8121e71891fb88dc49e4fe0ea67600436ff106a780f9b073e49e7e4aaddd6cfe352de3604d8cebd1601f5d2f5714d7cbf572bd5c2fd70ba594524a33994cb93f08d7314707c01f9c310f6c005c00bca1842801f046ed0e78b31b163c8015bca1e40d8674e00d4553c19b9603e36d43039bdc1adfa04e07d40175401d5007d4f90da573a9ff3b3f0de3d5575ffd86926bdcd9bd931a5787efdceaffca8f7396c5599cc5599cc559bfa1d4b801f8ceb5feaff4f1eebabaabbbbaabbbbaeb37945ce3e6f09d7bfddff8f191eb78ebd6ad5bb76e7f43a97153be73edfff5cf1cf56b5ef31b4a8d8bf29dabf9bffdb95ebc1f0545d3fe6b5c1cbe73b1ff0b3f548b67efe2652f7b194ace7e43a9168daf710580e39077d2dfb9d99bdc4cd6e14eee9df407e0ca1cae4cb952cc3be947b952e89df4e370a39177d27fdfc7e427930b809f20657267fcd494c9bde127a74cae8c9f22657263fc24512677f393a44cee8bf968b568e0286a0d860bec5bc2c88adcc1b8d17c59d3b54b85d9ce65bd9e73ce39e768341a8d46a3aeebbaaeebe054599889c95459d8d5b11c0d9daacb84e2a9b2ae2ceb588ec6b3ee092245baaeeb26aad268381c4e3669eee35c987f64dbf2b4fece095fc277e049bc7723a803717777f7aeebbaaeeb388ee3388eb33419c7ba320d665d1dcbf15028140a8542585358a56457c77256306b379bcf3417631dd7ddc93a59d67910852b02052ae0388ee360c3344c4fd14fe828c058d7045bd39db71835b49cce65557688c60ea9ec10cb0eb9ec908e1d6287582fe47ed973ce093529179c2aebea9e205204771bcee2163d2688d9ce6505d1eeeeee0ebbaeebba8c4e957599601dcbd16099bbbbbbbbfb86825df5c01ee35ee43498ed5c41c05899c009abe0545997bbbbbbbb3bcc9d07ba278814e9ba8e4406480281402010088a5a6bad55ca593394757520108e31c618a3bbbbbb4f00a030dbb9421e0ad589aa5cd46841e3858b5a6badb5721cc7715c45b5cbc398d8826bce39e79cb5d65a6b0581402010a8b228a59452daa1240c0c0ccc13d55a6bad75566ca5ea913dac300d86f9f0289e8a1df2b4fe270429ba2130a12020e7dc4763d157bc6f2acca6c261dcddddab0ede365707c31b4aee8f59655d1d8bc1188a31180a6541b8bbbbbbbb4f5ce72b2bb1235159675219a5b2ce4433d6ca3be91f00cb0edd13448a745dd7751dc715810215701cc7719c0b0ac6a4e1d8ce65c1988ea2510c1613131313d32d80d5c804eb588ea6a1099c2aebca3a96a3e1d84e09c9fc69359dcbaa600cc46262626262629a526b379bff8c03a72ae3388ee338eed260f8667884efbd9ec7b8a485b3d77d1712ecd4becf0caa61628d16345e7494b35214a594524ab592ce29a59452ca711cc7719c4b83bca198a494524a4929a594d2cc14e79c73ce29711cc7715c10e69c73cef994524a299573ce39a7bbbb3b7d41c1a0aa1e19acb2189c0c98289e70a297e81de4f79dc4d301434f7690d11149786571581445511461189c2a0b04cae69c3383b9731803b300b500abb8a1b1d848f34b737bd758732d4b636934160fad84a47b82881769154bd2755a57d2751dc92483bac1c5e2d8ced5307d752cc7c25b1f694ab3ab63338eed94649cc9a573350c8ca239e79c73c2c07430863992fb61865d0f4e957575ac06478dc6b2f729e73cca5929aaeb388ee3388e9372d60c655d7304a4ba94524a29ddddddbbaeebbaae33895dd7759d94524a2925499224492aa1e69c73ce29b9bbbbfb9c4161b673590d7a0db23a163b07c3aeebbaaeeb32ebea600ee3388ee3328ee61fbf0600aa71e7ffda787c3d53a43292cf269549d4df1bdfb141e5ccd08cd530efa4bfa7e0dc7e82e676145e63395ce7eeeeeeeeeedef5d599301fb0eae133cc7e77be339211c6b1262ea0bf187798ce4567d2755d570698692c07e29f1ba8a4909663e9d48c00000000400073170000180c0604c341013911e4b495061480094f7c545e54362093d123b21c06661c859023c61002002000422233da062b05a45310b872d17a9117e5540efd0d79c52a65a731c8eb2b28af7afe7831e26414af4e7d75a3fc40f4c5938ba43de5a5ab13b68489bb852ad83dbde6b7bb20fe4c0bf07f939476571a5d44b082c45c80c0505d9ff8b0a24b71e890d6240394a325d4622c3add16c3227423cf07f12453fccc3fa9729ad7a8bdf95981eaba1f1a8db890aed116f6cad8adb2e11ac351d71135b53f20273c87260e7fbc6dd931b46ddb293451465d9de86e15036149899b09e2830eead782eef1494f11efc8b467a099823449b64e89ef45043725377fd7f05478290e972806ff2f6043317e7c71eb48ef587134ca4ab7878333405414739ea34cb5aee4ff9bb0f20db6ec7903aa5459d22780d75dff83eff30ac8946f625f4099e526bc4a033f281f0158b0d682a4c1b1910124481885319c984f7a5fab99d34a2373017555c93c7baee87049033d6c8e4355a6392e5717c414cba66bc96ebbe3e32440534477f54770793cec413e84218061a432feefa9c862198bdadfdb2aa9692f2f725cbf375afbc92c023a64ef6d955f4e261320f5fee91999cca89f9505a6919f3243dac4f616fdbbb4aa987e35c77d815bf7fbb5b45ad7e21b07289d7423634548d7353b839e58f7a885214f5965b0871296f3289c1a0d389e00165775c619c0a1d348b757d5d600962491663bd1c75d8eb58f838c6a85f420d80950e611be3e7060118859149067fbadb5e22d3d80688a6e9dfb63354f93a2bf2094c695135aaffa25297e80f536774219a481e4cbe3e43e7aac99c979ec053b1b81676f8383fc04753bd5b50817e96db4e5124c0f102a9ab3326f924a574959e1929a522695ba802db7016603c998660d6f10db51bc4ca71c77c5d3a25828c5bd76fda1d7d89ba9ccfd713b62f45db07e936aa0706c3a674b130d86c05e3021d79b678891de120294d12127194fdf24cbceb49a20cec3f4509c4296a7d812197e61d666192fe78542a3e02a4af4eaa96ef2e2aaa94d69922a3db311fe6082e0f564531889bc1473591218f8c34f2fe23549371fd0c442014a3094e66f843bb57e719b3847a050b19fb6e70f4fe8e2e390d29ce4e1c120986228ae0421886ff8651e109cc890f291e1ea0955f039108d9223df16f062a88943e8cea4ce0421d454fdc3c79d3ec1174ce4a6040658a01873d21319c23cffa47709d0ce0c3852a5e3ebf1f817b429461f0dede3cd896ad81cb26e4751e5f127bdbbbc86d4c95244874d67417779ba2f574909268d9a811f87fbacd2e75f4dc0a4ed3038e70403de77287f227c5a10bde843f302efaee1c6de5ed08e9aadf093392b4d3089136ab7834bf2941adbe0a4305ee85f096aa3983049dc84bd5c4f10440c05f37d5208f033e17439172caac44b6e54f82e2142a100bce52c27d2f09513ce03af4c4a5e9c05989a791d315701b7800e62631e1cef19e457c690f1d20bddbd9b066080b1366ef6c30e0518c8ae53d6a687d9603383e136f0d0166b871c6afd19ea8027cbdaceb4a58152a33606db177397b97f86a7adbd746deb99de6e372089c56bcf0a7967384f0ccc74a878bee06c37fa8c25ee6d0512d9471ac596329a742c0aea251c38a0704292cedeeaa4182a24cfe2c8c0aa9882301ebe6c62d63ffff9b55a7df96579820e622ceca65e9a130aba96b985b4dcff42a51ec1bd725e45d4b83791c4dcebd5726c0afe578d45c267f23d239ec4e1cb7d9b5ff2992df61960fa1997fc33fe177ba6c97e29dd36b20434c23a0f597f40a6635e833a490df01e2af2e4e75ceed4f08d3f53e47aecf049b2ec4921fbdf6b9b9d92ba17b76fed5d48b4e663ede618206c5beff5fab62866533efb283cc251e696d3c4dc6119dde38bcf46b623f829d74aac1a9da14b8c78ba2ff2b41c6c432871031779f491bca43907048f39f71e464ce0c64f7acf04ccec3ad521224ed93a353ae3d5e5edfc70ea0892103399bbc5923bb64a727fcb2375645fe4de1744eeeedc8d6ccf2b68ef71072453d37da244cdba474f1022b5b51e436b78e6948024b5e259d4f30eea88d79c704887a161577c44b77696f2a99ab94b68073c3df61428152fae6cc371f7e85cf93d4c78854f00ea977797e829459e0b2743cd222dccab11afcc00c417c8932129eca448f809faa57b50b174218d2d9a3535f44bcd4a7050a132a3ce99c0ec228e827e408447952dc211b11c09f3b67a240cc7784ef447680248ab820275793d8573cced684bbd2e33473d9a04d9267d49f621cedc5cba4c8c6697a726b8126408e1d33b90eb2709fd957ff9c06e352092962a7f1e1fa0ca4b642bb3c0fb1b32afb2243df08893dbf51e00a4c789cfebc86f4d4338bdaf57446f669dc0397e7a9f3a8314818e0ba0a591c87546f25eb00fe7afdb77e76f732f8f497b3963af3b13f3000d8476b3c632916f925c3079d9fe968c86a8a93195371d99caab16921d411428bb2e146546a4e893c1108da9d71df73fe9bcbe8517d953d7c66109b0dffc02a013b08b6db81b7f859d00ba8eda39abb39e249ad4aace17c1a916afb498ee4e654f556976868f06b58a249495530914ca1e415fd7cdefc2779962ee6aa97df53ffeebfbdc989e9ce3d8b0247ff37411f2c67077b484171bf1a2d9746d44684dcfd63d7baf4bef0a04a05e55814f026ab9cf93b841500df3d74178fc8e81ff9bf7dbfe31be019b02e1209e40155e57e3cf2c48c617cbc864f3fce33db541c82c75325821f469035b31775973c936bc95316144392b6749953015a9c48b052f05fbc6cfcca1d5a8a8f758386a86fd913aecd4636de331f5964bfe0aabc9ddad74551dcf7e62338eace9935428d007bb4b678551ba2044ba141e21c75d46cf319a6b999f36dc63510d6fa05d787768bc80452027379132646f92dbbd6ad29bb8e92621645545f1ab8b23c357c49619ab50ec8b63b03e618160ae0f280d796dafd02c343d288db86597582af40e90315adf358c52e0058aa02cf0a2b30b587fddac4fe82cadd0e2ee47ae0f8a99cf186bfe2c774e240e387da9f1206c2e9286bcba56c824361e163a1c09bf1946ca6fb7ca9082039170ed1a52e3829064f4351d8c50cacd725923c145f848e34694b1fcb885783126c5e4619555090504cf0a23df3ea9998cb5623e872c3fe800bf848efa4974a4ef47c77b413ac65fa03563629f4158bf0e4a0983503ab8ed6c0cd74ad1cb943e4aa60ee7755f614915fe6f2f08b01eba006aa8d8d2ab7950b2cd0485f09a50e001e51a816787bdb99f000c149d811cb0a8cbda23055b1df746e815a72d8f7495f1c46182e7f2e45e7b737e634685dc08c6a77ea9a689d9528d2121beb242dc2e5913f8189eb8f645f6ee218f6b06869664a9cb2b37af5cec0f6235521aab335b15749b29039d13207b1122cc30cee8eb186f2570115935d43955dea468e2100cd1f2b437f3f78cbf5238a0b7a1f910dbfc6baa7c2b7b7e14f63087d428c384dd53da95a7c18af0bb799032d3b9612b872fbba642758140d66775261258e9aab125b1492b0f76123e541e9225318ffb479e00742a04cd4e69ca4237d2b50ffbd737965e2eeb6a612498ce97dd237f337d7901eda4531c0029717e25568d54053567752369766790cd9b7b74f4eea1c4a7255fe23ddfaa5f9df5a6c98864baeba6b3c3b0f85da785542c9c759a3ff17b0d9ece4e2aa8703cf1e16ce719888054719b41b273067706fa51b1b647640ddbacfd9a79c9e412a9029e6c8a9759bb9437b8ea642d1be911411fb9ae6d175d2767f9c2202b57c1aa900654e68b6a65e18aea1075970bdb7cc9d5a3a162d3c1d4bec67701b7d45e0551190d53d833908397d3322455143afb201a7a07aeaf2732d017874ca952455f77acc7fb693cded9bbe3fb221d272d4783e1e7a590b65f423fc811152667ee133df3f9ce7d91c3f64d7fd6f7d88bbe6f94f32dc6e54b17b92032575935723d423c52d86030b01124b65d66e7fff161de5fd7e4e19d06bcec6d530229259d8250753bb537856778a2f9178646933e68bd63401b37fbac6347cf0ebd16f054c1b9db12ce611b3546228aa82a1466826970c9f2d7a4f65b8378adbe8d0abca7fb879ee7becbece569d0de13ff7534e0a9d299c8f8dba0d629aad6d73a6d686bdc899181b31ec6ea0d8077a1e32fba13f2872da4fa2199ef2fb67da889b3eb7906458f22b45c5ea1966562baae7ae8bf45dbd95ac35e99ab3466c2bcbaf5e230dcea05f737ea850b31d30be8e4d18ba9842785a5c9dda9f5510d3abbf361ef0c33c4dd139ee54463918cc0dbe09e8b321f448e31c8752e1030cab9301ef0e6e2968912e5da07cba361c370d88d142caa63347513762c521aa1b015712225fb1a0cf68d4d5e171ede9ce5ad34954c5125e3ac921f61258f50b320b7922f6759b4b99221c55958bf92e006b330574b4ff1fb4f71d859f40b81b0173b3da98bf5b0508005324509c288fdb106eecf32d7524caf850fc2284cffbaf9ec4ea3b3d85e72d5645d45f9c1f4a3abb88f2256ff8a05312463cd2fb733fb09feed6ec742db8e9be4768bf06e176af5764aa66f87be0777efcd32c3228ec751fc63a7d783bc80b4cdbebfef236d19524c61bd62782a943634e14d78a0d836f8c63837271dbcbcccfecd1a4932d2584eb2d2b3080da97965d4db7106ec699ac9b814a1755db1559969ccad7de18e9d74206c56dcb0a0c680e8dc71891d518d6813af1aff1455008483eb06af906714b8982c52ae303ebba49e3641a343e5f8ee2f5bd934d7ad40fb352ced2c2147ec83758cf9b67f91acb86f34da2ce325eedf94a23702e5d2f903804289ebc3ddb89e4468e17925701d53b69963846dba43071cc6f913b94cd1589ed4915cdef143e1bc7c04b06ad9ca646f316c23a4a90f3cd8e594a5c5b93177289e4010ebd83a5f99d80e01b5edf47e074e09cb6791a22abbc9d1af7553d720adc51b44c83bdbd691f948c0ed4b4410fd0122840a06a055b75deb89078b14a8c1d42dfea1d5e922d54da414c3cc07c627024eee97a498b5d1a7bd7407dca537c2310f3d9719f481d97ba23b85cd93b69018ccd18779f4765ae0a6a4d1e96f476ffc79f4e83aa4d7b548cf0c91f4177366c8b2ed94b690773e5a888838b281d5ea2ca8ed3c1a735a0eebcb78e7944b8d24b1f1b130e4d5adc293d83ba0a491cdae836cb19dd4d8f4c7ae970a6ad45229b2334aa29794880afdc66dec2b97538816a255764ddace47c2e8dd419261d6ce5d3b667f9bfb1b167a80ad7074b6c6a7cd4389c1a6637cab4fb3b9e391fe6f4cfb02fa7a20db184b15da4b69f4e329e52142a557bfe883bb783ed3920c7579e4e69103fb412ec60a636566e9926a136da0833f934e319a59c639203d8333fc88a1e567efdceff33fd260464f4fe4bbecb1cd79e734ec0988c02aacaa2e04a7e24462c6c70ce7077aa4467380d1d912a8600872d86567195ff7d96c539fff2dc92ed58fad0c3f36e94c1a6345c63378307b15435870d9219589a9329ecfdd38eb980bb97574f4bb0ec8b2afa36a2decb892f38c63081ad28bee8c85d507a7997ceb9783a68646fa607f7088602fd6f25de945966a2256669d702d2e5cadf540e992ea45bbd5c389598735b5ce4ee17ad9e71ca16742e704f2e061a01aeac38aeb5ebc86b8dbab5541bd5aafa4576f1fc6ade455bd6552cfe9c0732c96b48b4e4a8558b84181b6dae19e059e4470e3a6d052c6e53225b68a7003f779300b6c91b5544d222cbe86e920f9b20fe7a15b44639f32ca1501b4e700f09cfb7f8615fe23e7fa477de7df8a0900dd2f07c4034fc475a1e532d22d9f595dea4b34915e1a9808fc077d2cf735ab51d303bc1d8e858bce988eeee29f6930030296c4c1f9c918f2f5300e5f9366f9eaeba42f21b37d297fe35740694eae888779b09444f8fa1f8f49e4834fe270cc470e5ecf08efe8cde06bfbc330d182076e48cd798e2d734469e89d6942b7659e252b66045944b33b51521d418c60474b13649f3a6ad45fa697f3f7b026917d64caf124cbe11beb094a16a092c47aa6209dabe270a55a80f46139b478ba1ce23682b80358f53b8b16b65a468fbf4756bdc3171d4ad0b0a71bd5a6daae491361d09a297dfac59fa7fa5f42218d7c255b1d9a2bc6f16b371f0cbeeb8ee345e689e3c5cfa50a6fb96fbcafc188ebca97f9dc5a4ba60d8438fc09bbc78df4ed826ccb1da7c2d901a5287ef0cea975512b6e950da48471a6e6865fac6cf1632ae7c821fa248f78a0a42ffff195ab5460e28243000fc6b446ee2817de3fd2c786b8ac899fdf799fb1bf6aef69e5a76a0a4438550a2ab3d09182c1b1e46b5d9e48f93102539efbee779a0db4264d9e25d22cf7b921e2506ad2e4d43d3fd655c8d2df51e3148e48abdd66a5a18d1a67d8af5b430cddae8e90e4f54ea286beb07d3acc7cc26cd8c8f51b48ca38152417cd3d7a3cce08a195a290ce08b26c39a1bd589c6c35284188b6b4cda30ef87d8b50bab8302693ba112db988b1460562a1f61935716b314da13125e9b2935b401664c42c64304edd9dba16bec75dcad81e3425e8d8e7aa49b4c403ae97f6a2879b959faaff5060a2a30cb80114b5138f2f8ef504e0f240c05711d9afa00796d5f2a3202a7723e2caeb936ef17919950084f6690a96d703300195d6ac95afe5f69c601dc9672c1de381a5cc34b0723f403eec2a3cb60bae438d9b398a6c0a477e1f6e864fb8667e81d42ca5699292ce4cb02066f56c5c13933222b078f4ef460482ce212ce9621921ddb02c177c58937a215c034a3f3dd5c1651af021048027d97bfbe06da0cb15a8d18bf8e3e12bb1c13bbf10c9c9cac61ce30481c864ae4b25866c655793345fa153cf7c1bee5b4c774d7dc1f1d2407821ecfa22d9adbd189b403a7310d34757c8a881d887927927b77495f72fc4853e4d6e9fa5c18de34ad5955b206c100b1acee6cb378d5c92684164c9f3fade11a28311eabe88d91d9221a61c63ca5b321643777c9765649713c1335d684e9c6cd4921e6e99f5e809d8d147ea4e7067dbc5a5254b234f0d5de6694664d10ad753676385053a4d889f0f289fef9e34a34cf30d62e741d1f181e0b5f72a09384fab84e1fdaa44759954892de55389c0dc4b25f3604093c0db0d975ddb7a97b9e79920dbecf8cdee670c1d2f7bb37fcffa958321783b22af32c1834f212fe191cc14be30e60bf7ea04a4bf02b0e0baf6afc1e3f84d3194dae1c0ac1a21b519d74dc3718b7631ed07b295e3c72e8d1985e88de3efd5d9c1bcac3a5384948f69466419c397a38ea822a1c0d61b01b67ada27767488d7c369cfb1f79adc4dd62deb9d178b837303353c4d7d4badd1cb66877133d67f18154e3436911aa80c9d04b2d98efe0eed91bef46a05b60f74dc3b84fecaeb8690709579fd19f97fe401a336ac796cab5bcf18629be7032ffed139ec612a694dcc310d665a776f47fd7af1c90894219c05695dc80b2cad054141db9efa00349d4c0ed57ee0bb8eb26b91468b5caa4926324ec651665ca6302868a86913e5bf9d7d4dd3712cae836b51ba36a8be4d2c6a461bd957d1c1eb2f68f924144291b4c4ae62cf504b4987f46494b768d496aef0e9e36cbf6c2ad1dcf62dd3031839ae396caf4209ac4e51404840298ea615c5f6ac5ce1862d96f50f6436842a622a8f0ae51413670babb4237113a42d76f4239e1fed762e690e6f8be17b265c788a3b85ecf8f19a5fdd5f7eb0601feec2a69d317a8fb7cd7234c8860617b41b9e9ca3b8b5744387ef5c598402334549a2d9d62ad303b0be504c0fbd22c4113d2ad59683acdb8e3669640c4107fa11752e72c873a3e201554d81b06688121d2cd7238aec5b062a16b151190dc1d6be10d8cc3223fc839574d0e2cb6968a333870d499ef1bc4948847288fcdf88801d33ccfda6ee4c769ef6cea100c69466ed21180b8b26178a5f0f551a33b45637f8ec2f8f2b4d2b192459fa2a07165dc5f7291306c3a363ea85749c13221d01bba473d04e3abc1e4a07b0e30e78382e51340e12028f92bdc84c6ee4068d9b3d9465f4817ff087906b81f8ee80ffc7653588fa4e8a1123cdef8f82f2899fc87f542110961d867f40f42387c8860a505298e30a7ea40c61e088ec5198f00d1965df4b31b8bb992efc81cd1057d5a44dd721524017f943e220470c670868ee7f70f276d57ce8d4abdd1f4c8f9bd38a98b3c2b034a6b78090b7e3e19afa6f139ddb8896b8638322b66be48fa26af2ced3211bbedd37dc47336bd10ade9767f16eb6184cc60f7daf11ebac92203b2f09656890e7600ff4cd7d6c25cbbdf6887cdf22342e86300f128444dc1fdc3c1e76eae128b0778b585aba21875159b984f38470cfa40d8b4564302d54c798ee6c70192bcfef5c8c5738506b2525c3a278176031219292872ca762e0aeacaa038ea3eddbb3b32498956d3cfb7b7a3256f364a975581cf1b6bdc0a2d0bb159711b7844432780445027c46512ec5464876dfe3817e2a34227c751a782e6b1c1f7531f1be8d7101354359f70283092af67792013c953748079f20f9e90f885750e5a632f4e414e93251a5cf23409585d072ab61c1c6bdaa320ff2aa972fe18582559979a7c8c3f78d16f9ffa79c48253f0537d11036ff42e52b2138cf4f1cf9f598878fbfd6f7fac9dcf377a33daed2dc3069f3e9008299f7e0dbb9a5ef2ad59cef5db7d22fc219aadddb0b51d5c3e3de88277d14fa0facbdd14655574ef49fed6abe293d0841bdd194210a81f4610a3815ecbad5fb986120538a4749fa7f2c93d2d922b0d6b13bd29698c9ecdfc331e2839d1772acda1b03e059458d3733480a6c5e3fd4e4cfcd11be3dc277eb15261f83dd085acd6b847099de535b6e411b27c04fb92be4980ca73a03f7b7f88b94714f848ff6075e7006ff44a0bd2743ce43b89b7156bd1229c0b7f01c9b670c9d919717b769eb423c7ab53646d17c57f256a2576c8a14057b75da9f46e0cd7b6edeb9b6694e3d712ceef2950768768e5624ba5ee991f004fab3bacc08c3064dd8914dc3aa4c2c2728097577df120957214a0e0699a978855e016f1d0b58108d59a5703387f25fa1388a03228d284ab1baab24fd0c8afb6770621c0473ba581615dddf80ba6adf94937bcee67647b3d1c446218d34a1b06625ded816f3403f5c2bd7630b4644c48e11b0af3f39d03b128b34daa431adbc8dc317fd57817501f63fa4210d1870c98a93a1efc046719691be975c6c8991769b006d43291e5dbd6d0dba1b6c527ef60e684729288c4e58f8462e5dc86dd25d43eac162313dea027f0698012c244c7bd2bfe044f0703f085ee880ab3cb29ab5b4f1444d284ee23e837a3ae5d6cc03738ca2b02495c368ae1702fef6834b0c5939ff705b84c96197b712dedc88769a192d4dd84a407c4e451124a9116665cad816a77289e1a3d2c1dd2d3248f440a960ad47595a88e0607b23c5b96eeb3a0d497e5d9cc1c423f54ca2f9125504077dab52efbc1533066933016c35a32075ff169170a5d7596fea0715d6fa330aa90a248933d49d9e71f851dcd01f7cca6222832b2608464aae44cac1aee678fa9eaec8d5b66a017e195ff22ba3df56f63b6d28f889acccc011d4f112cc181d5520834332966c5a87066f72443bbcbb67e1b6a047deeaee47c23a011f7457ddf98ba4d06bbdc92e02862133fd592f4264453497036c8e0490f48269f39653bd2e9209ae4888b3d955e5deadb301945762c7a49600256aab0abb71eacff5155cc1a7796a9439846d791cdab768adb20700b20099fad05f386418b1c9fda04dc73218ae47247f87863776a0432bde8313fdb8e46c06741f1bda38a86c6a753b5a91232fd2a86a3ce360d82f178994699da36b4d29b7d31b7738c4956489c547600794d0ae4401146fcda191e4d09e564e147a66349149de296e5bb6f29224df814e164e49941e81e903d26bfadb1db11db967d5a3974bc54fc00b7e36dca4f513b3a30ec982578d9e99dcdb7ff87e807c091495281fb14de1f05549fcc83366581ff315379db4911e9ebdc9687aab6a75387160faad2296dc8077b3e3b0a8967222b6bb7825cd222128ebe3ace5c18d41c1516339a859406c749cdb124c651871320655b76a764c00a354b54b30f6211afb2e436a581c982059d235afe0c115b895cbb73938bc1e801dd9201a3d3969e910c6a6b962130784620b832ea283187da770ebd6d31483b89c683a644c30b4454005b1de488522c4fb81e48f9f827f192e3d0d5501e68784dbd7641f09c754b72b1e3bfef3a0595a57fb10d511b11d03551b0af5e6c632106c8392c24aa2e1e118ef9aa7dcf3c76d9014cf316b1fb7f3e8b83a76e07c4d9ca728e083fec0c6803cb413f28db563fb48d7dea4ec22c7a89f6ed720064a323bdd96161058c3ce425c08f1c6c4f274a5f6b20542498e737e52d33c59bd2eba8b9903e2b23d830fb79b5e8fe62a76db41c6cf7703165253fcfea02ef87238b12baa64b054a9a814eae2606138f7769190d716fcec825f7d6efd5471d3f70f2c0efa8dad8f16a249222f0b145b35a05755de3c58d6b77f8571a86c7b3ba066c3f4973a5020e194297de37159920ae9114c52c33d9f556fb1ae4961851059757fcc7c88777d69dbe16efc7118ba1185e09e81b0d1c9b15611c960ad4543d2cff0fdf1c8fa92ace9311a652b479f643e75849a64ea1d891a7194e7cb940fa83de37dc4441d26c534b8a296a156dfb0cbcb143a5651f804239a50a9ea159585a9a4821c5356036a1c7cfc5532dc560679cb2a8f4b8e457ca067a272306be143eeb960ddabde623ddcbb0b7af6986fbfef7d6e74342a9c0999ef1a00be124643a4841ba34911a21f897cb090b9f705af620b5d1444c8dc0a16d64286e5c6513373f60404b0f03be18a2544c7d7baab2ed3ffa5956e28f029864c55fedbaa58a0f9950f13a7bb9e1ddcddd26077427d38d19a6aa9125d562b582ad4dfe48e3b9f6592f8ad1d2cacc5587a2203d107998dbbe9dc3ca7f72845c38b0d173c964f805159496f227e5eaa21e47c57a346a9bbbb094db09fccc9dc5b8eb4f83b861a6f2f1390e338ffb77f9564720a26972d1c93b0e19343a543218a8c2f0b2c90000d66d387858c5a90d64a8419a3e6659adc6493103afc57fdb34ff0d7621efb5edc4d6771cdd4da838eb741c1c637ec76e420790435250886464eb0492413d408fd2128dcc0c74d40a7e5f9037e4a85a018f638f781d8c4b2eb94e6f5f028c161f736308f067276d34d16d4028740bd51e1fb7a013d8910238d574c18d94569316c96de62511f772aeaa42af0ad29cb5a753fac60e9060940ed01e1aedf4b17f4b08a2e1d4b5e02a0512805e4b2cd3202aac3117db7ab8c9df0bce7f886e2e005b0d27cbff804e9e023486ffe6f7005f2e44050a5e3aad300bf51ab71c54fe0b03fc13b32d92c44596a1cf66241ed385f40557341d521a16ab7a12a3ea2aa3c22b17323a15df6135ad9ff1b2bfad2b6b97146f0dc500137ca3f365365e99d60cd88ae2d8877d9edbb97121744747f216ad7e219b64bff399942c7d564ea3dc7408040ade73a186fda8153ab69aa095695bd17dfbae570195d358a3f9501bdb7152e83322d34bc5ae318840d7f268a50c1405e29d2776cc629ec79049a17d368a9dabd83f16d124a9d100c6d8a613e4e43f8ed1c6b7cfb0ee48e77c9d80bb502e99e891a6e371cf222ddfdc376780db04c2633d89c67320914654ed61e6e4e4a87208830f8fe2dd47aaaf0fe8e50b6c62045aca196e19b2ede38bdcbb87cdce01b5f8f44e474f934aabf2256bef1779b3999a0671ed01310f24a41b9d9a1670d1b094af9e2235e76cc0685d64bffd5e7cb5976e7e511dd24a7496a844707319a0783827106d6ae96182eda491fb61c02515da5316b55127d589fd682b3e8ada15a0bf20d37b4aded8f08de003d801fe79b256c65326c77112bf70458f5ccb84a338dd5fab79fd54047e26ab37167cc996a182112aba7c79c2c900ceb6ba4a19a996902b11c118b3224b3cdc6e35bd6ce53ea0f079265004664b3165cc4ac914159d6b4574fd6b838226bf0431d6b729003902e2026b3ff685e07fcc680606823838097ed5591ea051e3b1e86ab0474aa8739a20285bb4e8374224e8a2fa6a526af5c787361b5c3d9f60d62e740a9c33c70f493451db9b7487fdb450dc7bee8f11546c1096334005371c160114a4697801f195386495c343c1ed493c387129ad955db59e0db10da5dc761734d8f1ff4782b79d7adc33250ef6ec5605124c44eee3b1c99cb9dbe2fc6b46c6219bdd077c73010231c37c630d2040d2a261cd719a50f7612e6a96955da251a995f151934867c24fecef07db2faebed84f003a0a1490f307f0d00ebb9f8d5d1ec46eda8017400360c51ac322c32c5ee460f1d7d9f9e93ded76dbeccb4b8f4c846f1e86b5097236d2a5961e1864024054e1491a065a96556ccdffaa8cb0a6c103d32f9994978383ea21610f2f0ebe28c7eef60dbe985486482f6305d7ca246113f9be7f04b9a10e5c56b425469070c9d40bd4f0f06c50e4c09ee1da56d9289ea559c840611a1ae647cc4bb64a18699b99d7af136a5b89089c8904c72bd2476a4d60a4290e63f1d4d685f2aabc2c475cbd54cb58f826c93768918b59016013a139f74b1239f05e94298dde4f7033069dc5061d337e5d174a428324d083ada861dd26a9749da6195a622450f98312ba81bb9d4636aca1720b1de211b8e484145176bf85d1233d81eb83b5441a700cfe2972b8f9c04b51ceae4b67073b4f076dc733e04f7a5e8385cdc25d36986dc94d591d2dc4e245e294c4c99f13adddfc598168ab10b5b8cc374318483c518b66737fc4a1036142712270ffea217962617807af7fb850789938f2165a7b79c89c42cf7fedd0129e8fa6eb1c0a7b4494e04cdbf349accddd5410395ece075947cdf4031dda2ff5198f380ad7f71eabc7c64a415b4b5e7f5ed0a0bcc3789692db63de8f4f10522580d5cc57f5fc3b1d9ef092e272219a01beec0e42e0192084b3362b8cd0d740f50c9a243643b1d6ed7ea201dae93fb96b0ea19601b946d249a5438075f52659fa96015547c940a6aae4ae86449637574ec7f0717dd4abb4254f0fa199c0cb74d9d4bf852bfc4b7126e83867a8927c3846c418ec3c08d752892918b4ea32de0446f0ba21739c61cb1880f9dbb6801123fa7fbb87951d76207a52c9c6aa78bf20ca07c3d872b9183ea2ea4e17628348917d750c32307bf5c912f5b5d762630914563d0500e580834223fc142000cf9f9140246c8afaa1060417ec40a0105e427bc1018d7a36c084ee509a4037e5b4a14e5ce89c401af6e259aa48d47c298d7f7021bc4cec1520fd6b0cbf03c2af6624528e5c7822dcde799b0f528265ed6833d4a83c2331ad5753a52d7d507e70fc330fc8a5c949f926dc8144a0ac151d99f8bebfe2d988eb91ea41048ef479f6e539d4bb911bb4c1591fa240dbb6449d0d39ae6b6f1ac6f7f27d0b8cdcf973fe53e8d121253b83d05791e799e1e8dc3eebe939b605825ead463dc03863949538479f19f330aed1eed878b14e6de89372da01e076e4301da8c04e8d1bba6ba689e21692a49f2c4731ed200d0581f501c012b5606a359b97c421954c6f45f149b13c9035e5d6a34091b1f0923afee1536899d03a51e67763d945182480cc83be45e8b21b25ea34e9978b22012f00a0b2933bcff0f5225d168ca86947b1151625f32f5efd9cd0e81db23154724ece3dc0817be46a56437113411156602e9169db6aa585d7cb421451777ccbece93b0ab0b37fc0c5d5fbae36d334bb7bc114088a92e506f9f54e93d241426ac35bfa8742e160a1754e95fd03b1faf20a3c6a4a430520057c43bec8fd34546c62426bed618839286a35845d6e3ac22e1235a45d86889ca5544ac2536a19c4651df898b0f0642ca5b65fa1210009a247f1211b708b011033b156fa4d92093fd67ed6d7871b9e489d7c3d3e9f9f8d4df132d9a8b05acc9f551c96ee9ef090fd9a6b92cbd0f5501f3d9a27b0eadeafc29d6af4e6107fff5f2c78ef658a3ceea5fb4ccb60268c5d0d093609097ab31b6ce44cd61eb844901abd8b0da7796693982bccf8cce4607a41d5211e432c286f4785e65793e06e80e02bdb0c9dd7748d714c4c995f0c8e05aa65255fba2f4fde6024417935a429eb57c04b7026f1a956b04a734a3e61544ff9fd66240405b364f1b11b996bdf7edb376fbfeb2f24f42262cebb7b1c5eb6cd44a8b88627ff3893074837ece2c0caa70418b054c92e1b9be39723cf519edf693bc7bd6d88b5af30409f40085c9c5fe9524dd29ac7282091b1be85c595c1389b16eea655039c6b1df3f035b60ee93d8cf7c306b27b1d719334fcfdd5f33f66d48b3a3e504cfdf15be5f4780e3e4d681687cbe544b3b4d101fe519d49ecf94ac34932971fd417a21143484e9c623888d33120990e837b2bf19c702457cb8c1e40b2bf21163797a40e362940ea41d47fc128b2d0078e985cb4002175860022d9040041a884011987f4bf3ffb7a296c012288aa0ae4c0f4661d5188ddbc16175da8ebbcc7eb5a7a27740b8a0169ea8a04b7e19100cf29546d9b835618d56097051107212288cd42119dd7649852635d31023f5e238c572a7c3571ef3e9bf44189aae2a10ca2b75049a18f52b9b71b80a6ab952c7b072b26a38cd9a356befcb48837a106523d424aaa85865c4469684668d3dccaaa0be791d2f8182517268a5e126c755c5ad2c7c699e780a0bae804f3a6794d297a80831e3b323aa921cfe74b5415be138546e78feb93be0701742535bcba2df84633937331a7ff808f48261c9f1a12b1dc9a042eb3dad1edcaec595e8aaa1e2b3af793f131c0688aa5765612172bb18711d40ce1925da34acc58b19e8f905ccd6dcf6b88325acf50ad6283b797cbc0b90e7c3170971224dd417de0ee7219d0a150b2b447bac7121637ab7be7e789d67b56394402bfd437fd17d1216d860260e0e3ce03a5f7ec817ccb62134dc024c665b8382ff3471281704fb3a898b7842330b6c5a8dd61c8bcda00c4c5c4198a7004eb1c965c1ac0064281f574cfb4ca6dfbee20efae80c6e0c93432fafc910b4b7c312a10ad433209d65463b5209ee3d6c5bf1faaae192673d14d254806db76db7451b56d4482deaf9227aa94dfe2d2f7f62acae316a89869e077c223464f55309fe376d853998d9a0257d93b4d428a90e9aac1c6054c4324c074a8a2e0647f7f567ad4a36dc6471781fc806b7e5644b13e240baa67627cb4fa20bc2f1f7a36b76d7d9b9fefa604285a3dbf568dc1d1d3212ec173a03d74eec6dca8d0d0bf5eef43af43b3114c2cc2fcdd1ce0fcafd15eed46b183d033ecf285f5b90ab8d515c3790e1ea1117fdc1170d4353d3eefb2f7781252a85be8e3af259380f9a8617279d2e50815c182a7aa27044e190b1f457e8a820d4928977c5f070bc0e28faf1d3184cf85c3d9a6c67514d8455ff37caebd75bd355b7e7c61d397614a6fd2b23ed782d2599ff9d99f7174e4dd42bca7c2331e0407fc64cda8c98b48eda32888e9f5e7408e83d0280c582efa6234d0e96391b0f7e506995ba11f6e9b8b678004c51ab58914bc4a503067249e74d81fea3771332bfc07152b4c628c89840fa6cd69b4e699dff1f35b8b9512bdaf8053ebbd4a1e8e1760c5c11a19c1591c51691377b2e3165b20bf77cf7a92c600b67580e77e8576b9b630cc16e3aca2e641929ecf1efb97ae589678a28549f9b6ed499d061bb06facfddd68f9bf552c1186f4d28b9992d9a47aeb7d71bc14c1ce4139f6c3069ac90f84f4ad6f4e119362a9dfa16822c39b02acf82c7150ed06329a46cec80603411d89e3811843f7bcdb8283a823490d14809370d2e6d9ef5bd335b0d3ccb14585c4bdd243c183f8316ea5e401b4f39bdae0f00aeb69e73a61e69855d9859acaf1d6471928c945088eab873cc80849a465f0b7712546b18a3bbc0975d9e8d5e6c04e36bd61f9567c644284404f787612241c4624902b13374016a2fff7577b809d615f771bcb493980aed6ab11caa1788e7a13b13788cb09e6b0541a9a3bf2c616eca9b7ea194e54aeb76a458e81d40b65341c372ffc393ddd608fcd858e9d27665aa0b0fa39fa6c5e4db465f605be8667d56f02437f38f0e7526e3068852ae00f4cc015a42ff6c15c9797b84806953d025a1a9689e6d453a5b5740e3795f049d3ded9ebd4b23b2289696be683c8760b86d02e035a4a8dc7e0c1a68b154050f2b49dfe04d2191c64856bf15f076ef7ed9db11bde4128c6c5c0210f0289cf5c30100ed6d8f201f7943af3cf5c0e7c34e687dceb7ff1c58dc62f3c7e24389fa61c6e97ce64e1978cd2bc336e45616d69beab14fc62bf1a67e3b1ff6458bcd38d4d054c65e974f6cdc091f8251dc05cbf9ba9e8f77c6d11c38cbbc600ef1c570d131cfd695f1a97b2a1c9e406f01198243485c279fafdb38c99193184fc102c850fd0b8d2ff611cc63cb51ac0d443dd8c33a1e56139b9149254e118e72982884d96ce4a08961663828ed89c221ffb64d299283ff0ac8847ac2b93dc6289aeb928a2dac7436d1987c724ca0695673df5aef88c831abce2030fc1f91e26692aee68dd51112cbfa03f39f2d37730ba9763bd3ba62d73aa123db4d29c24e5aa2e1bc3d334e39189e19e6ad0f0dcfeccd4e2cd20b58a583fd858f0b7e1a7100dcd9c5b5ffb3e80f694dd246890f25e979ae5cce5b0fd0fe76fb3e97376cd7ecc211c48457e06c2426478baef2642b70cf9b102620ce763f226176553c723a860042fc04ef90c9b41cc423d555a51464936210b6fbb10997a71eff8700bae95d72343c6f96838dccc8b744422ab0378ca9aca33619be2c60c7115323fca2f3a9f10c5511a99367fbc99d57d183093eb0b458b4080b8ab5f15407de3aa9df474363b4e2ce93df3e6984a4701b946af43c6178fccd190652908f2e5ea64bb7efe6d69d3802ea67f3b0f6a43e842654ea45f6153e3a4d2e348a69664b001da68a42ab6e76854a82c81d7eae73f2218cd4fd2858766e04b9930cf7a15adfb29367ff25664c5266564c9417bfad5668a327a188e0a0775e151098e39b18741bc955732863ea8b058a92a53be8695ff43531629c4741c23dc724420143a203a74f9c0d4c8ece648fcde4c69f28bc25ad07ce88a4b42cf6d19c568d070d26497626e417d855422688ce24c8904299e7a01d9fc37dd93cb7ec0492be8226a87ccab9bcb7063c69f6c6f0488196a960b5e8e2eb81e8440f1063ae3b039dc5b99e0197d99dab598ef91703e7c0a5af1f644dd9554390604a42d624e647673870b941707b7529ae2d7e18f4e425f3e86a6f985a6efc531811f16fa2cfc8723b45eb18831ca4e053d84856ae53acc7f820aecb953a57c4e4cc549bc40968fb526e4c468b09a1d73cebdf5140c7133ee792a9a9a5580e7d4950e74fe2310cb2abda7003847547266e335024c1a87354ada7e9826810b415d500a5ec72b838f04ea5f4bbc013600dec969668c6e524fb7a97283b258dc3f232b024973971dc70a771b8ccaf64a76c5005b7efbe8944793a58414c6e6533ce93cfac3be947f1826a2b055962e9355f136f0bbf3e7ccd335c325bcc77c28b00e4c03e0d4ff201bf4f28ef5a7199c55ad94e1757257caef2b3b4ecafc975a5afb8b483bb803856090b3b4da2f37d83f9fd738ddeb19d083af566a07dc1695791e26b25d5bf4cba8b9046f013e96674ecdddeab16d2fa1865e863a5a51e3f6ca79957f54856bd005e230b31b4bc639970d57a95c3a0a52cadb0ccabc74d77cfb0ca9fa3eea0baf03cd6c2b43134b1fb117843241c622a7110cc28255215ba7f453b6e7682092a8f09af01dec95b1f0827322ce8a8293e0ec401e1f73469513ea44f5f3e13d5ea9990f4b093252a2d45743d3d6ba3d379cb2079b1facb9b2f0a24a6385095aa0e62057b9bdc276173807816a668b29fb7e500430d1c84080f4d02bf02927fc227581dd8753707d63cbd4439e3afd7df5f179ba6ee54aafd7918482cdd5948c3b3eae2c170da03fd1802fd3f60d8bcaf08738e2f6815d61fe310d23855d8972f7569607e791fe2f5e06caac5a2ab9f1ed0fa01aa2962ec16d454243a59b94e2296631c2b514aee8f5ebbd90cb9d6f76a51a280484556e99697d847552cca964e482c85df3ae8042ed643068ae839a4981d349d422aa488d3d68e98e83147cf1d1d91185d4ee600376884cef4582f8fbac760ae28ea627920f6d3e13349544a47c01f7014d2eea693ff5209b717edac6111e81d8838934d14a5e0a2d7ef90dcfc170c4647068348372b95296e316c8ae0e1c7c35d3cef788b622ccb917bd0fda60057b9a59fb3af5b5ee50fc6d88d70152fbd34b7d20595fb242f38db3e426848d5fb726b4ab022dbba6c9d0663b4adbb5b50c28a687fb135254c91ba035c6101dc9ba3f2f92cd49c83ec3c9fb47d4474ce37c7804017ab31335cb3908e71da423991ca8fb190940e67b547985cd3cd51814ae5f5a53a0e287c9c4c9de9b8631ec68915071d48548a6edcc0233777633fc760f0ba41b05b2c74935c086373c81fe719f1f154da46fe1002d9f310d2b93893795c00dcb4e511a1cd53e8ca6f40127cbd2bd3bc958c80587947cb85b91255e1b3166f7e892050bef6b236727f6373c6fdd69032d0ea537da7ef8a912a8e45069683005ef31c6cf50826c85278ce0490d9e0442cf1e06781139d9f250a4806c252565a6e07a33ddf4b8511366b8d9ec27a824c629e4dc138ffa83fbfce28c22d2c96ab4502baab5c94ddcd917b9fb8049644aa07e5f8d1112740666e2ad96686ad803663adaa4a53472f04d1ecf027ae3acc402e1cda38205c35ed5ba9ad53acd0e648a94e19628533c3b1fb0155e3c03186bebb398e4edf78876ba27f3ed12adb34d645f3512443bc0a67cc245495a63dbf97bbc842b5ed1e7155f9ca960fb8d0fb9bddc92d6edc1c8a7369f7fad3f50a8e59b196872e4500663980babadf27429503f733c0d3da14e6fc0101b09e307620bdd70ba334c78034d83d90340fd7c8551715c6637cc05890514aecf30481f10506894ca565b6fa0ccdbf9146315f20390fec0606a082841992371a3fed610989ad579faabf20c25556a2a7457446324a8e7c939d7f60c59bc33f0838afdea70b9b14e840018a35484f90c6db62cd53a00a9693f99f2e13a6daf0362c34b6d4d194a256488f1509ffec429142838e43067a74fb004d67eaa4697a02b49699f43c576465de491ae8b8566e709ec3569e57682ca36e937bdedd09d5b43606b17320f8e3b3273c4b35d0245fc223ae1136a8c1515f7dcbfcde9b3dbd8a503279ad70100d545d704b71a14668cda22c96541afdd5ad3f3de5f73d077b9e24c59b2df82733a48df4839a07a44d5ea48af376ad53bb95f4bddb4d181dc0707c6b160dab821f45b120fb96512ee9c98008a66a40848a15b3a04dd77b01e20b51fadb4c00cec42f9c6642688f0f84481fc7f98172653aa56d2e64c6b0b00220fd3d42f2b0ef501001d9e6a69dcc6428d30fb9055a7a70ed16984f0699a585c557c378f3e7565e7e3b7d7205ad73f044d07140535f88a28295fd832d34fa6ab5da4f9588a9791d34924320c5da0b2ab9bf7dc3bade1f564612b764e9e53c0f40a6585469a1e7c8ce4abeb9b5b3c8661584371c5e092659129dd42328774b27c2d18503110f220a8737b852167bc09dfbd8dd40ad2d0c13fb5cd9f02857a4d16a08fb129f6912fe1a279ffd0c0a974389871ec08636034b24e127311d22596b02e55c70e6d6de78c91c920e536b82c2fa6c5311c4c0acf8173514c939481d63e42acee28dc5d58cc84f6d89076e4315b07850a46409f75262536a9121825ec225e11d3f8ec6c1e016257b56c177dbd6e44e0919b3dbe76ebc4c9747df147aa40c1a71ff66c6bc4b49782ef1c8dd7963bac07f134b6d1476a8a51e66840bb19bf006caa000e93fa9eaaff830998ee32a9f2ddd562663921eb7f04247a08c3ba625e2a2fb86893194e00331667c6fe8865f258cd49f3066c752e2a28127d8ffdfb28579b99c9b5d560113b56fc47534aaf5a04d2c15da22b349940e28caf98a49c20cbcc5ce92228d522728f86c0b074e1fa4ece748a7e717f1878539cb0fa0aceea0b3f925032f81d8914a44b50ec678fc58c647d6b772b37948e14e3cbbdc075c5ffc7b76c5ada5272761e9cb9049ea8b53fab20a10b903afcd49e6ccaf3b165a6c9e7866e42236fa13703b83c8f3d3c496f68e4c2751e6af46a597826973189151fd6d66d728be8f45a7f5188a62b13ddbd694e1e6bcb130388b18628877c2d349cbf77157ef02248ef9d17b42e46e7ffa2cc71dbdd7ba23a695e018150e9a234bcf67f11dea7f329a73a9c54749adcaf8e308d95c57227812e7295c5cfcb8900b31cba0d363100ad072485ce690a8b3119898bdecaa7b44a6c8d10792bbdc185421bb8edfd6cff95f8f0ab00a61aaaeeca11c3b351be11b14f88ce1233d5c6760378cde2aae078ef525bcfe7660546574ad7b488e76f01a79b42e5a7888e366731d2b1e6a165ba3d076b4d52477a52c3fe1652e89fc814089eda82ff315bab83c55214c705eb3f1a4516c30a9760a1416bcdad0bdb4bf36a53b32e2cad9d10a82611163bb1941d2819f03a715ec2e10991dadb9a2bec3e1e8d991abb14fa31d7765fed9110dc38db9a79c5846a457752bcd11b149b20e9ccee3492b3d7a275da4f4e8faf6be728e9b64b6435f1aac9994736d834ad5f364067cc4a2a166751a652ec6b9ed306bf33e5d8b119697ccac5d5c872d0f713377e0be586770af18b5aee3ba61a34ea02cb759e8692ea2c2c029220f00cdd6204501d670ab4aa702246a6d6251b2b33699aaf4909105f5182ea100031492b0f9246622d72cb407c2e736113cee66c6c262eedf73382e0fee03241114370432eaa90db1646827e76042dd433db318d02a9a2049d56e95d8a87293cc54a9b71aef6d4fbf9f267801a61fd5fbc8637ff488ad2b9ea90fb095cf6e9db541cb16df5e3d2bb9cc09bd13c4318b380512636430fc6a4492007c67fa055d134ca83ad5de69c1388fd1e078ce8afdf86f478f6f0cbc50066025aa25274ceccd0778465c00fe2727df6c3314b607704d94b1cd889ee1b3893a5485dcf0ebaf65dc6a66ceb08e8866743721f4166c662d0dd546925830ab04a653691559ee9256427c67d13df430d5b101a649a7593d86cabe90345de62167e2c02e2bed706d25b5201c8f38617cfc996287178f0560f570bc133bd809b0a6455b178d7f46374ed344c144eb6cff709a389a4db7a69fae483a8e1a63c78b74b225a50aad885149b2f9aa84b253e67c254b53f5613b57a2a44cb304d1f8e40b6742ae3943b72ca366ad3d4b273d3ac088faa9cf68b5c525b631ab24acaf29a5bd779468d18388bad1042a80c0847712c35b74ad9b3f7a1a51ef28c304a403ba1780ad5d0220b942975e63536f262d150f88321e7a858e130c26ed1617bf209733672a457469a3c187c2d1c1122aa20dd444ec7b69ec736394b5c74ca3cc8272aabf447d0c24926637f83fe6a52873a335bd62113aa41158d839dfbcf847bdfc3a10a97481969e6e644a20a4a02deca0129639375e0a42bca371d0ddcd923947c886da71fc3fb3c0d1e310bcc1baae71deb7b7fe59a87eba399957e9a5006d463c1388c0e422ce3acdde71af60192b1b3549e1894cd6b40891d302cd647364d55839e009e7187fe11d5531853891da1c5770cc39ba855b39d28edfc08fe1f01ccdf65bcab3331fbe8f6729d32f1a32d53598f4b4e62615a06330a5acf43e5e58e56f163d57f0e37b5b957245adbd26ea7ee4f36a2d7f3ccd1ecf7b47856d27f43b4fa5b83412577fb02f4249d8dcc2b99a9aa3a86abc850e16b45b8f2151719bf1981ce7c9706aa9980797c7c5bdb852c7bd83c2cfb53ed0c860285c4a93d44aa61c3285b1a61c07f8f93e9b588b233f5a209ec91bd354023b6a4769d730654cdcb173480a734dbe10c8028c2beb95c040d4fa76954e84873aee53dabbf45e9e66f58cd02b409746fa5d342b4109dd16d6c2b825fe979d86e9dc543a904e27e57244fc94619230c09270e2df6bee35687311615e2934a889f57477b63abc30f24a0accb118081dae7d525db163d049ac2d9181f20de1ae5a07efe5bb16423d18a066ff72ca8e21c22cecfe0e52f660203d3af9f58fe90bfdda003f01eda1148d752be13c6fb054131a5fdff1ec93bda24f4a905ccfb656ceed0bfc5fbea4cbfe184cf5468de5398c30d45810a8464cb474681d3a0ce65db8ead60ffde8062ce0767042f24160e5f7937003034b92fc2e0ce393024cd3e044014f9ccbaa0ee07242a82303ddaa38e260260793ec32a2c21ca2c6ac894df621e065b773206279a732792a12e6db172dade7440db880f8f5f73db785c86cd9b92dd434adfae29cb0efc099e36ac2b1e0992c890f0ac5abe6091bd8230d50a65eddb27e45907382d60f7080d2113420ca566d61d4af9396522047020c3ae16ed84540dd65e866069a845b0b9a98c31962372ad215be42103773096860c97b668ec964b6bd69373e96bbb3cb6504803177eb07fdc947bed9c2faabc2d5acfab9ccfe95ac72399850057b843ecda713215f35aca5072361b588ead28b4b1c2f1113d4a508e884d74fe151cd406b9974750cacf76b1180e071049b590e2096b1823b4c2a5fd1c79c9aad8ed9c0862ee035bbd86f8016d6d811f46d4fecedb0c201037ae8c612717b2b5f6458a127e005bd4664764d3d9de8122aed9608442bd07895b2c0ca0801dbb37adb1bd74ed6b71eb02581687b76354f7f7f775109c800674c4ce1d2b3f17997b7a2b284859998f279c946447910fecffcbbce342fac8ca62c58cb448b3611e758e94791f4928b43c05a9a1090e6db54f6fe69698aecefc7b3e0c162bde116a8c0061aa8c0062a500656a19676118a1ab9a8e6cd3ca6871fd1269dbf193a167580de5be82dbc23de1008f26b0e5877ed6a56d25474ecf5c0fc9fac3c01ce944aef64a584c0036ab24686564022d1a80358f30217b264776b22a30122061bcd8b0abf2346e7bf69c6c67a1d69084ca683adb2dd222843320cbe46b203c0742af3a2a9149000a1787a548f5af5fdba25b3f8e734026684c8267befbda5945ba62465600850082b08bfbde631fb557615c03e92eeb1dffcf61593741e49f7d1f8fbf7d6df60f7b38dc756c0f39b6f08cf77df1023bff98eaa43fd17db98a4eaf9e6c8532046be28f2857cb343d807763e1578ce4c20f3d8c76e029c0cb6d960ac8b00785f83dddffc07be60e3388b6d347febabc0b3a676c64e8d8271dd7b4ea60eb58709cebbc730f79ef7f3b369f006fb4852de7440f826f39fcd07da9824cdd76d33dcdbb00efbd8611867da4cce94fb67f6b7ebbe21b0dfb68d8646a3d13c866158e6359b46f318065d106e4a17c3347f3f66ce7bede51d36a50bb2e09541fade676392f296790ae290154c812bbb20ccf43d26f79c549d283a318d7d2b903904b339bacc8fd3969c3a37248e9e2d9cd8a249cb59d35671dda3ade2a3b5dc7ef7950c2e584fbecab39eba9e5c34df710c6e7fd45e6d8555f455cb5fb1e33babbacb535a7870af75dfef3f1aa508fafd9e8633440464bedf575125fb4eb53acc7d8669a6ef799fbc1c0704aba90a93b9c5311200f497bbb2678e7a9fffe8908663a61ef61ff1447e06a721cbf733441fe46f58875d2c26e2c628739fcbf66db566e8d3cf5b2e96c5fe5e65a6fec35b288f9d0aab63e894b2195c902b71a546d1d129b345fdad956edfe8095fae3c3fda98a4adc33bb8db83377734cdfbecc7e6b80c7aabdf5b3eddf5d2e68393e529d9cf2fc6742cdd27ef3d65efe5a27ed72bcc2057920172a5a87229e5f4304ffaf29b71b856885ec93ecfe5a2fecc890b5e5329f76dc29a66135c9e983581469032e68f7d363ccc9d52758d0836084312aaeca2957d6e127b5edd1596a71417f416123289db514a3b16fb5598992596c4ed7e73f78ea52b4c7da24291eb131d725953d47441a40e85fceb7faa0e39685453b1a6ea138d225f01a49f4202c05a85ec5fa11017b0bd77df76da501eaae591b2ff061a816800ca0182417734b6dc1f68c40329e242e4370fc6708804f017c1f80dd100fe1bc66c8831fcbda3d1e5feb06b07b7512888d428f3fd37e72ceedcd845e4374cb22b22df071a05b92076357dfcca8ea9c8fe1b463b16da4939e170678b12a92da421080bd7c43c430244e7feceb343ad2a4ca1b5c2a33f4d74c84ff63769bb97d886b772835a9ad431fc755cf073e2b0cb653b79caf689a84454db94a2412317e19846f1b7e1ad0e8bc488a892b8dd8322aa0c1a758f595bf7db29c5e5a6b8dce7e4222701a25fbeec2ff6074a57bbcf39310cc328a594d65a6bad9cf7a044dd07e34bf3a08cbc79ce830fe83c88a39479f0062bf7db90076f9c727f57e38332653ab8dc8337ba20369177d9de45e44629f786e58afca4484e24acecbf013fa7921816a3ecef619005ccc7450403ba6f0cca57ce3e66cc125991b23fa8fb5c48bfb2bd865db6e770142db261504b8bfc737a89a83cc5aef88bc4641fa874410c0a7d35830c7ea37eec726fec72918a2a2d1fc4ae184fbe8d958f5d8d82657f0ca447f6ffbe263a45eee085a9689468851d44011a657ff06bc1af8f94fd2b65ff98c061f6b7b241a346013740402dfe5be6b6fa3740da3b8981d80ee117766536c0aeecadec0ec4154f42a878e2bfca92ba90382c051d61ab535cc995e4e0ee6eebaaaea2d864a75275a914d6d1d3c9d394b8a0974a9a12b74f7d72b9526118552c9a1237e3c91c3b1a340b5bfce1665ad9577c8df19401a0e2cf59f214017cfc69f294938fef2d4fe9e1e3bbcb535e7c0cc047007c6cd116e8e3c3f014938f7f3d9ec2c3bbf8f879fa32aa849ed20facf68349f207c3d74512af704fb61f6b3fd67ef048de30ee83453e38a4e4d37cb4a8721fdcc99be53e98938251c5f01022aef4a0d1a04a2e927f324d79db2cde64cfb6692cada5b9b47b07806b8c8ba41a2ee82d8dfb604d2e9150a90ccccbf3b20c8a16f99784f7836fde382ff780359516a3ad5c34524b2ea2611d75a8eb341a8d1a2e783f383300acc1b848e47d00a4d10995496560eeabc57103c0ae62811de6ce518c27c37d7077ca21ef7f82ab4900b89632291817f907000098862e7294061355a8bf72858927f2d5e0711fccf580bde522c902dbcb7df066ca9d071dc6046fa3d66bdb2cce36dc07db5cc2e13eb866125cc27568c6700b0fd147c48d511661244fbfa46445f7809879086199290ec1720f38f302674e2ef2e78187ef81e3627548d37ac034c4f46587eba1affc2efbb19fcfe7b38970204c82ca9b071d26fb9b602d7491bf0bacf180b516d658995354a199edc1d558ce8a27f2ad7d10c882482c0909163b96126cf307cfbc8d702ef0f71fec9904bbb078130cc345f2412c1ec32dd8e3164f5b9e425faf96af3c9e1da218e3a72f4fd1582ef2778de5617949a60f6a2d1a9ffc7ddf2189718bc7b05c212169f124f8ff9397e4495ab860588b6f412f0b6c3dcd82058b151204027d381026c13149f9f316831a2b6bb99f971d0bc95b5cf25b0bfa69c1e25bb0f86e4cd20a8f126c73ec483e92ce9ffd19be026f263024825f303a98a5bd4219d4589955f6bf1a7d7518ec6490be40ed07a85191fd358dd5f19f6d73bb60df9d8b5d899f69f5c80d89a3b51e7a60835c704e5254915fc359831ac613262eb8b972bf6b73d96c89173772f971abd7b6450e84419941753822472ecc210c6ec8910b559c72ec82f8cecf292e38533635baa017e3c5a8b2c8873c37f294ff99bac36df19a8b8f31e57ee041eb81076feec0831e0e3cf81b7830a481afa4a86280efa7aba85280efa7a6a84280201ef4c1020f8684b8000632f011020ffa108107431278f027f0a087020fde0a788fb5a20a8ca8e2c3b7032ecba5716bdc075c20ee02340cd0ccd064cd8aa6013105053f5f516500df3f531326aafcf0321ef4e1000f86541efc0428e0e326e5411f3227047ee6783891f3730a6befdd42a00f797b9bbaa30f8c3c30eac08803a30d8c3470616c063ed05e0c7ce0f55ce0033d2fc407be0582f8401f2af08196021f7827f0811e097ce0e708404006100fa84183e573808c1a13cc39b908e522121c73078a0eb50b556e1730d945ca45d847871ab772e396cd2d70cd2d99f3e0a78573c2ac20382617b1e8609949306c5a6b2be8412d1e3452d2027bfe91350f7e5ab2e9c35ec945dde239d07340fe1f046af10f72f1ea50bb70b958838bd0852bf7f7406a14d0c51a5c848d12a487510f2df8fffb5dac21aa44efef839895fb31f64c8fbd92a7c33b02ab29c8a0af50f048150a206781492470e3cafd1f10e93b798f0c7e5a38238fe4e9f01f1ccc82914110a993418f44e27c5a58bc72832012b809272a831ec97d64f0d35284cca047cafedceca1f40d3ac3e41c93f6b791964dc7be8ad131fa310c8bb5564aa9b4d67a6a8d71892b7f86e35a39d9d23148599675f273b9314d2b3ce4cb166b2db6314d1ba9431d4fb21d955a5a9fc6ad85da3aa5b85ac7526786c96045d5938b2e27bfcae39a6147d828e0c60cb95d403af3ca50d128d9dbefdf9821aac46aaa261751ec424202ae4cb4a8fb332f6d1b39cd16635812973e27b196e3a5a90cba8b055653ee8f15bbf85b575ec33632c59be5b78de28912f4fddbbf6de422246c52b4e37026b1cd137b1353ec796b69517fdbe80817ccb846b93fe3cab8b2879b13f396b4daa86d5c878da021478e1c3972e4c89123478e1c3972e4c89123478e1c3972e4c85eb297ec257bc95eb297ec257bc991bd642fd94bf692bd642fd94b8eec257bc95eb297ec257bc991bd642fd94bf692bde4c85eb297ec257bc991bd642fd94b8eec257bc95e5ce55961bbe576ab5dafd04d7ef294c3b88a6228140a8542a164c8902143860c19d1eba623e209c9c0a6b70c193264c80811f17025afb0519d6a9856754cafa6c96432994c26140a8542a1501f128e450b6c05b532b9098542a150281408cf1549b2f77a3cffa1100c0923553246b264ab4d2693c96432b55ab2255b267b3d2f57abd5ea4dd6544dd48499a6c94d3c70265c8c607cd9feb0cf7a89442291484e72c2b559c55e4a0b5c618b26e0167970472f18643bb8e0d66a6daddc4a5cd0c399e7f69271e0a4724b796bd57ea3dcec6a49268286ccbf550eebaa877615c352150eb763e1bafa5bcdc8bc7158d219e984c3adacf740ab657f338c75ff416d82b4a85fc39b907344697a0671640e478dbb32472cbb4a8db39c239ac344c7e8cf60cea9637058e629b3c621658ea943f3758b98b986cc1baa435a17c48672bbc53c5f774ad1cd8f43ea508667889537dc6578cb1e76c964b2adc3d5ece18b330ed3ec6197ed333806f7d55a8f28913ac4a101c7846a14904383dc262638a746698243835038f26cdcc66d15d7d0f2fced729109afaba14d38cc6f4381de293b4ae679b5e7702ab6c4d5be724e1dea4dc7b209e3497fe6830b6e28536e70b3634b6d4f6c420ec953b80639255cc432d7ae248bb6526c6a9db72cc9d4c75cfe6ca22842daa852bf73959c14269283cd5b797eac2e7d86374e19bffe8cae547e8e036fb9b77a7e87423060b405dcda7bbd9341394b4a627b260d59030ba22547f41c3528cbacc171b4ab51b32cdc4eb7f1c2edff6447c3bb7635b268b37882c521c30216542a96548ae5740ac30c0b2c19165cae30ccb0e031f1e4a40b1b556eafadfac3961a255620417257576e3bca6d49b9ad8edcb54e1d6d7fb0303a64a79d3676b5be9494da8a6db87c8b5dbcef8716f5cf8e058600588dc27dad363c892b6bfcd0a19ea5edc1599a4684e8b74d71b7fa09201555ee675f5b9ee2f2940c353578e362d9b1749f3d1c57b40737180b642b992f13f62013cad89950f78138381cf20db772bf9609eb0b4786f1838c9e36bc95ad09bc952b2dc92ace3337c4929cd26991cc989dd895b16bc63fda1293986c6caa4807359e1259ad4989a727d6ed7191dbec5a2c669a1526211499f56bdd0360c8ec6ee2c5a81273ac36ab19c794d5896ddb7e9352caee6eee5e5b05a795300ca394521bd6927f4fe75a6b2d374726a1d097d82ae24f4f8e5772dadd6ce6ba2e7ed7b1cc0c07777e9fe16c15d7e3b4d2d5ccac95be98ad360a09c05a6b1fb3d5566b316f8c62a00cdb2388f6c18f0cbefba62585bbcb6bf148b9bdd2e4ba8cd7e2d1b1ccc91b6da7ae9f1c3f93c22d4306b79337920890b9dd6584fc2d3ce46fa70c7ba4f6461dcaf3f3b2185c70ab2a1dfdf3edad2b0ddc4eb9bd93a790c815fa658f63e5eb9c54b86f4bfdb5485598eb077aa6dcde08fb46d96be950cfcf1b75a8491da33f8bc205dd85a537f2563c69cfa6554d3dc301524619e5473bb333b3d9ccdacac0333a245b724482464141101d830b722f14b45aa082468961c8fd0a01185bca26244522c618a38c52dad8e208b66852a507aafb572ce73744fc91a7cf29b199eaeead3bfa98d24bbaa451e47bfb107c76fdace5ca072d951dfd18fb4b128a92d34606d7e7e831ecabb5d68d0caee6fb370d1e1979cd873c65b2509ed241b9a86d47e531590c6b69b8580d6e624eb8a283f294b61d54ee4e4745823dc9e358598149b09f8fc3f32cb0e2e76360c5cf158f7d18f83cc96704c97fbe33e274bbdce2c54e72c55671b38f9dc7143b2068f67e464f55a7a5f3c1de0a1c5dd4e0f5d8efb478413a47d8efb6cc8e2588961c393a241789ba46070631146a213a5e1551542fc6598ad14cc7fb3cecf279ef365eb8dedf26ba1a7747131d6a2f1479ffee6a5cefe34c42c8159220482627f414926faf56938b5ae5bd3c657e3ffd4077652ff494cf6f42d6e429d87bac09fb4cd87bd6a49a24920ffb3aa491e9a2bc2a72bfc4600706b97f0372a64e29db4c63e49b4d74a85f13a21fa2bfd19fa6feb4e8fc9cf59e924699f7fef601b1df7c20a679af8f61d807ba20c46163922e8e59a395ae7cad74c18e2a77f530d171bf61ecb758e3c61e4a4091b1e7ec18c13eb3c9ec39354ae6b1d77c603701ce63aff17cc86b3eb0f3f5f3983ecfa943adf9fa9aeeb1fb98a686bc4326b91f0d7987bcf9341dfdd849c0f35d4f8a2735c0eff88fc01aae583ec953dcde958744ca2f582f585125cbd276cd4e316c822f80645654f1fc82f5620c51657eff0b32c8173e1ac55fb06202b4075f7bf045906cc117acfcc2c70b565491f64f267bbaa82c9b9e1c869e5c454fb91f73b5acebbe3ce18f42a47e2c85b2a90be3517d4cc8e587f2656578479eb04b619b54302a952a46b552b1542d92a78c2ce9963ca63f8548317675599ed687405fd978227fe24c933e7c56b38cb45d05dc7ea0cc52e52981f1b8a24acc25309e8295c0a8727b8c0d95662b5106cdc8a9d778629dfa4b168a4d6470c17bca7d51f3dd3f242f8cf6d653362f8d5065f9469cb2114d1881e2de7a8ae6b90f3422b589c185f194eb725d982cd5c19cdf9cbbbf5dd4e4bcec82d8bc74e1fc456df9ba3ce5aeae2bf7c72c4b8b6dd672e6c189b2a8ee3e7b4282f79cc953baec258e2e9ad73abcc177e5af3c57b93f6ab0caca17dfd47777dc6b4fb9ff4d604caf956734aaba209ca42e6354a06e6d2e639f3d75a809d77b719be620f74517b93bc8994ed933e5676392e8d48cb6c9a1618b26524acb0282e639c59ddbe3e81cfd88c5e87324593146c7700b0fcec31ae32bce5bfeadcc49db3acb53baa7f499015b5072af63e062745ce349bf27d45fa34a14c38a18ed4bf0ce38dc8fab3a5ad4efb8579b983a5c50c414935b8456bc1d8165c6da65c4b05a33208e9c67a3b4fc6a490617dc481b2977cddf8a1df8cb5fb67ae53e8213b49a19fd47c883eee23ce821c550a368731c2eb88dfc55eb13761383371cbc61b968d3dab836212a7be6d32313b6d84dc8b759654e5c90036e9c110f8de6bb63b96f44c95f49dc975824a459835d443c552648876052a813a63dd6b1681b1d71469e22f21e724622e008691bd5284818463b1d4a6b07dc521c51a753adcdd88e25f34690661c3cccb2a8c5f65518b27f08676e2d2dda4632a8afb15d8dce9a8c943fe7f45e66bfc5286fdf9fc1afd80d85e11e1c56f6ef6c2317f98833821939a2637c2324d4053399208d92797f6fe4b5340a68c3fb6d643fa1e6fda7666a5ac752e29438a4ec9bcc17cb3c4558223eb27f88488b73c4139c9197f2aac994fd4dcef932a18b7c1bc5ccf7222667e472c16d34da5a3652a36450e4eec1111dd97f8434526a94ec47469e0933feca1b2c121ae16e1e1409b348900ef9d692d3fc278c2af25d6af01509458278f623a4ec0fca9c494f953923d2e66eae151edac5366b70cca62c1f43e24e77654d09dc757fbbf7e7a779ef6a64b2ac0f72461ee8ae1a613cf14f98fdc14c985d7ec26dfb9a093fa111a6bc79f3b3e1ae9cb96b1b81264764ff6de429f67db319e9623f83bdfb4c723c995a6671a5a4286da34c508bbe60c226e36fddfd0d21e347efd45f2402246515b6680282543246504482fd05acabc1a27e21372ec9f3f34ef1240857e41555321a36671e4a1621331579d1c0e4cf4f3e952db26491e7d7555d6590c82bf74f1651854506e5f92df2fc623c915e0aa402c229b7fbcb0d5be26299d5be21e837042673cb9741b8605de55554a9d6335c84f432e93fe8a135b3174faeb76a51a22e65c7e261af0711bc980e35f635bc1e2d4af1a4df63b52861ab0c93c1eb4989bde90de1829795fb3d55a3805eeeef94d772c2164daaaac6e408ce518c317e65a2938952929ae4a30e3bd4999c994fb2993003a4634829ff73c954af140c155d4cb74f2fb9d96b91a68c3599a66ca70d2581b4a89bc339026be905cc11879469794ae629ee6a51ff960237950371d38f0ceeb216768ab75ad4ef437e1b1f9b0d2b88cdca459d09d2a19197b024b057961bd69ee3e42d5eece5327f46835e0b133fa33761ee4ce89fc1f3bb4dd65c9de2ab16f587210c3e7cfcf80104c8ccb6bf87c7448937add2ce6833f439bccd535565890ac2294d4d0f961839e5fedbd216c1d3a12e91f23b4483fb5967a8435dbf902bf658ce9f7e01725b18e47eb000b9df5fbac0953125aeff0c9f5809a629cf4fd6b0d95730f8bc5513f73ee8ad464e3610496148aca6adf43fb39a33520cc32a758a5bfba1b93a463b76d9ac6a6a4b68586bb17ee0ac8d6a1345a754ea9e1dbb646fb1f6a34573a3a278e6996965581ac7ea84c8562ccb7d744a36c5059d15b16c710b0fd9da448137311da37f6217fb8e37aeb551d513102eb8518928e10717ccac32ad46014594907b15860c2be3639ab28b2821aac46fd93ab06a139d623fed474b0677c5cafd937a0c8e2b14d32c2bc7b1fce5add65a587dcd5f596b6d54fef537aa6e638a27f557aa5a870b6aad556e8de28cdb388a6dcdd874cd5b469114d6225390bf6149645d6b96f5675966bb6218b6c4ed9fe15809eaaabeedcfbabbbb6c8ea20c624ad775f7edbebbbbd330ac6298563da59ea49114c540a6742fbf5f4615ecfb3b3c5bd4718d759eae19d6d8b45cd70cebb7b7335db7a6b3c62a76e93eebfad45837296bccdb62963df78136ea6aa377b83267dd9a6e5ceb77631b16040dc3e6a679787e46a9b5f1998e8562d37d76bdb5a687522e415de521fce53b08f41886fd0c073de81b027b8a37264e52dc3b5fddada3642a793b52a9965e13dea963f9dffc75457ece09fac73a16d063a509870bfa19fe1f3b96ff3c1d235e131eca4379a70e752c2d7ea3944a6137afdcf375c10d908d6b4a713bbf55ae6ea860d9841dea57101b4f4787da248557aa358365de4058e6ad05867d16954da4f427720b1509ce2cdf238129c89e080bfcb43c4133c983367b483c9ecf9e50f63c08237b567ca5af47fe80481d6a81b11678e64d0ad5e9743c1c510bdcf9c32d3c5afc0c7ee5e31e1461814c30e8e42290cdfc875d00e918fd8f5dbc300c568d03c91c738b0d84712d70cc1cdb813e8e244f292efe915dfdba5a1784c8ca45240f6256490b2c73067eceb4074558b9ff13f286c4e137240e4947aa3865266907edb6ee36b96996dc2379245467322f4dd623a582604ca056214a154385cbdd344d5869a2523b503be69c26cc444b182a6543a576c0ecc804695167c212a7a4a35130cac4c6f2972a66c5a1fc47b7913ac55d405eae967744a9147900daa014ac3b3c528943cafd454c128bdbc1ede07634b783db913b7b70926a875b78603b302a6b959f49fb819d2c4f39f27003c361fb9e61dbe6eb823647d96d677b390a61decf0dc2f0947cecf7f9b343dd9f7c304cd9ddd914ae53e1af8e21c38d0eed61a3c000bc4690301a4c69050f92e527636c194f66c7937832e389f4d0a908b1c7647ff23d6c147f79d8ef5484edaf0e497fbdc296bb3a86fcec06378ebc545c85042023013e1f7477f70fa494befc28dfbb5bca96d2dda5bbc3086550acec20dbe7fc01068c045037f9174028442bd7b9251e0f666dc4a8fb17b668c2a37ecc2a8f88c98801391a8d3427c80ec4c5320cf3e7705ca9180353c618980b669e2416e89e7b0e741f07e2a6c7252286f6a32b6b4f84bcc3fc40d992fd7511f7d1459be34d172e1131cc7125460274347064ff19ce61b06f648f800132fd8d7219c55e461f3039bfceaf19e6e1d431779f5dc6d25ae737312d6cd15378d09719033306e682dcef18033263416e202c0ff9339ecc96a351965f11d87c197d981f3107483c8890918708651c2bf63722e41d9c071132722480ffc42de57b570347ee9718d83766043819fbad7296f3ce797875778b65eab782ce18fd8898a72ccb6c56b31ed00ccb66967996659d6532cb62a66532a5b9b3d0cc672d6959ea1014aec534637966cf364820f3ac2c2e821050e9b2548af1651231458ee412b94720e0008b7a4a16e36b2e3360aeac11b399363d256f6596756c743a5e0264c8d034148f9ca773b9173bee1c7211d6b9fc1374fcd075304018d8d78e85d236a130320dcc22f6f2bdff9b1dd2d121203e63bf4d0dfd64c93bce99a13fa3a79f685cd4b64c93a9da992536db37b21e5c6f979dc19e7eab46426b65a2b3727c4f4ae6d9b4ef0c6ee1a179f479cc8fbec21e63b1ff70201667d9e3ce7dc5dd7b18fb0cae6fb1965b1cceaac962f03acbe68abdf5d25a39f2e0162bc28ed6ac55854966c6727bccfc3ca6964a1e2a330d33bd47b8602dd592a74ccd79b85cd3344d249b667aa4d0452efbf270e4956c3eb656f68f1b2b886de5a2201d1a85ee73c7ac9d92bd3d76b864df29b1b27fcbbab27bafec2f3ba59126905c26171293eb8c3a3289abd1dc6f08f9dee635d885f39c283aa591202d72db924935b66746b9869dd2fd46c225b83a254fd98c744a9b6fc40b4742957f8ad5329db807b911a665325ad7514b2a994e54cb64b4aeab7647b65a46eb5e3ba1fc47a492c9da8e45f3d86b0dd231fc63d8a1ec085ee835480db90fb911d7d229b7cbd8ece714b773865b78683f325331fc3d8d0941eee8b6340a9879ff11c98d5027ff11a964ca6aa8695eeb583417e48ec8fee0dcc1913a947ddc4833332484dca8434b68c99ebdbf29e5feae17c9c352f6694dd94f99caef90dcebbefb401beecad30b3ba3d49d0f7646d95bb696d772f26aeefbc72bb3d5c82c76f73ba34e0bf69d123612764a994ce995c4bdb804fef27e9b587ef7bdabc1650df6e048c869dc0bb3dbf7c2a832bb3cb5c7b851f6d088529e9af7cadd6bd3bf868d623fd371df969dc089aa2b92568e3cdc681cf686746ae284b52c1c9570fde3ed5077eaca53320150ff5ad65422577cef0480bcad3ca3c16905002c71bdae660f2c6b5ac1b2926059dc2b5402133f267b5cd276754515ea614354998f61d313247b5c1e208de2ef7179d8e0698307c88a233c2f0f108fab67894a7abbcf4927e6d5edc4dce3d2c468b4a0d982a68726c653ba300c31c9ae6e9a93f6c4424c21a61093c7b83cc4646d88695aac521aa244886986ec08314515cf21a61025427c10c2448829c414920a81098122e41482921a4a7abbcf4927e6d5edc43cc4d4855d151d1dba205de82994526a3531b2abc7cc497b628ea294524ae9d4c4846862345ad06c41d383524a35319a184fa1d66a62589a98676962a6c52aa51a2d6862a6c6474c54f1ac89d16841b3054d0f4d8c2646d3d2b83440342b0d4b7abbcf4927e6d5edc45c13a3a13427b423683b341436dd76a1eceae19cb427e62ccca40b35abdc42c41593521776557474e882c42eecc22eecc22eecc269b14a69574517cecc115d18553c7761574547872e48177661a694316598c88c3224e9ed3e279d9857b713f32ea42c3a064a06ea839eac86925d1d3527ed896928a72fac951a4acb8cbc1322aebc606928cd09ed08da0e0da5a150a793cbe572b95c2e0d352d5629d59cd050538342434515cf1a4a73423b82b6434369284da5c5683db4940643a5b7fb9c74625edd4ecc359449c94407264898e83029616e29a594524a29a594524a29a594524a29a594524a29a5d453f5ad9594c569a9d90911579e442291589445c740c9407d44caa22ccaa22cca0ac3300cc390352d5629654515cc4e0a8445c740c9407d501665d1170d6910daa2ae300cc3300c5d7abbcf4927e6d5edc49cb25eb05e8ce105195ef878c1c2dca424bbd239b139e9c4fc494f52dd292e655116b5d6e3d2741adac25894a5a1263dd1d3494369a82e7497cbe572b95c5dd8859a98c652580a4b61292c95d2c46862424c1e97870d9e367880488fcb536618861e57e871851e57e871851e578829a404a6add71298a84261a20a4667498f129812281ac53e5702530285922894405102530253b22a6195f8285195c4586b5232d1810912263aa24a655252a95c26256952525d9392ea55aa172ccff2b458a5b41455303b4d9a30294515cf9c49c9440726484804ccef37d1d128d6a46452324199a44c9e3031999c342dcbbc60bd18c30b3258fcc28786335cebbf6079ca2491be49228566098c8b36eb7562d46dbf78bd085fb472bf706519fb26a5a545a8c44eb33645ec140d000080006315000020140e0b4563a1300b3235d8bd0114800c799e4674689c86a44992a328a38c32c60040000008c000cc0c06230074895a59be54479965a301b49166d8c6af1996f2a1a0e2486eae3d154d3c1bbf88b959b8a78a9e8ce4608b8898b78e52a4c2a3fe3d25e383ebca0486652574355f8b35456e74e88c5f99a89f326c26dc621fffec6a6c7f0649e7acf6cba9fc9b7d2a4f48379e2624f493533263a38f780820f205635692a6c84abf21e73b44b0982f01947ca927334560abfcc3e0a8d396b9c0947cfde0234231021a51f26fb6a0ff7d4d09c845e669581e897ade95a02ebed0dce92b310bd19f913e285f8bcd18b53e89de4ba193fd52b903100e8b1f788c565261c78608e9b74235209104904645854c7ea1a58052eab438897b67d5c3a704a3d9dfa3277ffc16373c4796b450bebdcc8eb0a75d5818ca8758707a4ff92583eafceb08e9533ef12a9fb73df477fdeefed08fdb853ff9606783f408c80ca4c7c6e63b346bbc3df80ac1073ef9c4b0874b13f4098d4891024ff2cd863bb0ad1a533a24d6bf62ef2e940b1034379f12074c74a3e4d3be9e58288d261470acac4fcfa19a12888e1e8f49060e719e6b09bd2e2419877dbb7b412119131a05560206a9c230fa15a4563599dc202cff01714a8654508cb60f918a08f03f1a7fd5a5821d292ec4ccbabcdc67219b4f645ac1609cbac009743eda6a51da8b9f6756d79f59b4f8b648744efb64525b946bb9ea428e4c5cb8b8b5a097f40a093982546209c50da711e4b2273cf7fd6221c571a86e96990e77ebe8927e82d9d3c6e19899be091c82c198759774bb48d6a7ab20b17321bf3d2a704e9ff1f0e34f5e6627bfe0c9fe3183ac1729245bd35f93cfb0ff99e173db9932f6e4b5e2382ffd9008b004b883703cdc17e45aa4f4141aef9def497a2c76453aa1ba06ea3f3db671d57314881339ddbe458bf125c612bfcbe152be33820245c2a601696cf136ab02790e13db39752a8e1b741d150005352ea00bb638a3fb8d4218b5f0ab42620681e26e14b2b4f63acd83a3bbbe88d2653657bc331e48a9bc54e48edd86fffe1ff423267a3ae0d28862696f6b5840e75859231997eb0b551eeee6c959f4530382ec91f949e522d0f0014a114e3d93750c800431da161106d55f4ba4b049eb85232e2ce954ba56bd5a64c3a51d4a9e0a5e2156bd0cf1c60946e2e048fcd10f1bdf965b4af68b89241d39c1b280ef9873760f1bfddbec56ce98b97a6d9504499f46975dc28bc1ba1daf0d12624f7f32d3d97a374f570712284465f3ac397389f10c0701bc04dd1425ce2ce8b10535db6ebc918f93a86ff0e442f046d160d08636b854e4ad86f1694e635f7582baa1e9df7a1f914f9ac28c1248c66288297174d46fe4b81712389ebf63657418f6a1d846c1d5bbf32a00621d7132201b0de256992dc0725f58ecaaa6f8debab6fe490d69ae76a64a10f9746925e70023e9a05ecc99909cdbf73e70b6704027231290f3b51c23111d5d36a1da06f8e99b106031416bb504e4750438d067d22c5c2f8db39ea7d2826e811f34123b703856a4d430ade6ba3343d0ee83205535c9581f1fd94fd70a322973534d10d9869116858863788f13e312c8a7a8953728de8ac83e95296391f430f5d2214f93480bee3f202435107863c4b8a695ace8bd684f2ab5923125a34ffaef01aaa67135d0ecf73e70769a4e7316383b22ac17f792a1b2bcd8d1f1246aa7638f7be810484f0b4653803685a7cc8c94dd27212191ca55cd1722dcb2c5732d4c97f154f58c9b2ffc33dabf2879b979cfee07de784b7b47ba032072f1592043e2e9835c8e23e1e2592cc3338f0a4b6e3706eaedcd60e0965e9e99dcdc5d2812043b3b21c37fe5f103977573c5c2a3ab36724dd8f4168ba2d033c81c738c6e4af7875c65e92537b7bd3db8a99baf7dca7114d52e5033c0e0edc0a4ec7e2b946ad6d9946a7096f62edd2c372c122c8e82e2cb1ecb87b6223682286f6cb95604845c7f3201aa4590a06b6cdf4e714356d70983f978bec169e6756bcb6d5b670666ffea118d840306a081ec037b5803955db5340d4b771a39a910cb8ff9f2673225e8d31fc0bc0955d6066adef8d1b2c17aa17ce6d8496fb6e86f8d4c3cd572c74c223c663181fc55e5fff22b5558695f0389102e2cc292afa2691b8442b1379c98fff28202e4b531240f02291af8975cb1191bed9df33fe8f9099ae5e1c0ca8129e0dcfe421fe26f1ab2ccf870389db95e328ec22fcbf169e9c4cdaee3c79148ea0ef31e9bb834918cfe15def4e14f883ba87d44d211231381a097618c25998382d028c2f2c477968106e498a101faaf0c577c0e655be559306c66363d4a79fe7499d559c63ea864abb21f90c9eb4da3baf5312c3ae12b0b6118921eff17b41edf66f0e764c164eed7a897c9237b2dbd0d0e5a8ddba3855c70cc854513b9bfeca92e4825e56bc355f04427ed7ba7488a6879fadcfb4ed89ef7f055ef74770c545cdaeb0ec695d1ba47a6d5b59159d3d7ad84d54bcf611520d8e53ff4a7afde36dfeb8aa62593b67e7da216fbae457df40d8b65e4b2050ebbf6f595f13f586c46b8235768e50e2d487e087f41f6a6ffc7521b733c6a4e0dcbdee3003d5a676e626c1524607d5091f5afc1f604f2bd4e8b0c1cda8428b308624a660315876a9cbf215690bcacb9771c9b5090af572d13061768454aa6a17969344a93150af3f78d4fc622858525fe8f10c44f255d1eed3a0b5517dbbc51f97308287b9d79fa16ec6ce0a13f3765cb7e105287d6761457ea0825c77de2be1f5fe9ce7cfe575d755d5b2866f7320f1f6d68916531c88f201cbd3f065529fc4b9179193d9d9a5cea9b812747ec31717a266bcf0af147dfcecd1f20718af66d55d0beb00cd32911a133f0ada815af73bf10cf60de7f613540d1b0523b6353116a499197ff3c960b3f21d989d00d622761c2b62647050762088919cf74a7d4f99b127dc08cf88b1121703377659972d7814f5b7ffa5db7886ee1e85c9e09f924532358d327307f061c98e8374ef8701a6fac2239230288e239b13207d0e91765914c667e6dcc660bd4fa95d05dec277354794704b1f747f5efabec1dfc8471988195f5f0829724a7b33dbd56c0e738c50e12e0ce802cd90b2f8a2aca584aae32cf9a0b1f8c6429e27f66fe01c79b2fec452419d9550a06c3a554dbca907348412174137ff2134e603ba4bba47a3a80439e7d56f8a96ea5d9c9633359c4bfc17cd165d6e02ad4d30caaad53a6272a315003a777619d7b2dd97d96589fce378385f17dfd0c4e917c949b525660caa32c86f4c41cab132826b90dbfc66c256a82a185258645832265ffbe12b59ff59a0c30c655ba4aca682eb33de51f71b749a9dbf8c8a579e6b19797d23aa9a0a16d2081afa105067d201ff53407a9f26a7ab56eef821095fc87468c275826358ff4d4f52440e946bbbcea090d5cad9b752b244a9485d68d7818c012a1615e299ff2be5d39c4b644c61dbb0192ce9b020953807debc8a2f78968be09ac322e9046f22250674deccba6959d618fb412bb4c0b319ad1464253ac903476aefa29324de4405f51fd7b87a18cee3118624359c5945da6a919594d9d8904a5d19cb2f53b8d33c2b2f24fda1c185c3090f508d5ca12b0f9b08d9ce03b3a1d257fc9b6bded57f1fe41ebdc214fb0a08baeec3031cce50b022405a10442c58174358a73f47e66920139728d773835af96368fa3e7d1ccb3307b42d8e97b5f6f229afab32734983ed96195c83e24a343b1e8277c7c3c79efbc138165144093d4989d5ce9439c7ffbe19a5fbb976e6fcd53fc7a1456e6ba53845f9a248e5b97144b788cf65625eda832c754e179c3ee3a2671b825e86e669b0a9f15d4e2f99a563546ed15e01733faab2dcb17fbc64d95f05ecccb797fa6a5888db4147ee8f9a8212b081145c90b90bff59668a2e850f6cfd2e92838c96bf34fca3d440f31e97dff200e1b4c92f468d641a9f1d61c63610d597558dd8142e6d2cc300ee82d96fb55ffe6e8e7c759a86435f05e0619daf63fd296bc90f8dd3f981836a0f50ec878616efc57093b955d85a159cce4cf54a5704a12ff53ef20db6d19ba379a38d4f812a6cbb42d198e46c8f3e2673cae9a42d22aa871ad1bcd773c8d326965f115819888e45602227718a6291d185c5062270cc900275c2633f4a90e8cdfe93f1e8cdc9aa561452e766a7c228d96c5b8eeb72cbecce139fdea765d55fa469d9836e35eb9689a4dcb58285582bfa258213639ad1218ec54f8502f9a5a9579f368a5418a85e230a72570c9407cc0037170c3ed13661a02bddcb2116386d97e5dab2d3fbaec0d831b7a79e943ec1f7b7017b0bee11e8344032feb347d34b44b20a0dbe146fcf6453f9c46e802fdab74dbee5a6d29f889806bce312a5a1e70dcfb187ca2b3545cbe9644c6f04f55a3ce59a8631fc218b350af751a892907258866fdb4a4e333cc84ef24a909b19ef5de821182b80aa319e4d74512b72dfa788474fde57e27ae7de2ad0f8a0a2da9ecc5c30c692deb6d8904f7753b6fe46f58fb2e85d7b651ab109d21439d00c05fd4222f131819b22f43eca186aa8aea9566ff054213583263edf15a3603c63b800620055acd6a139b877e2f22774b0ef76ad39b0c0d072132ad830343353a40974cb264c8fa33fca602036d685948204366b10cde819297cd34e210c3a783bae070b4012b4366b7edfd20b0a06148f03db2108557d67250bf29740e702474956c364346a673312da8ae9ae6d00bd6c5aa69ced573abbe7e6520f6db585c23c370c46786ec8b3d74c0593325c46214753ab64376a7ddfd0c240503d85a4313277b859e2da505ed52c4a6f32ff10265659d33f5271af0b4fc78652d27836ede9581470e074b4c0d5f19edb83e11aa3587f84e2f7cd3830a957c23f6d41ebf39bafbdc77c42c6d381a9cab6310a1597ae8ba664f9cc4195f1931c8e3cd4f94417d97cc8db52895d0f1186430629b1f579441fa979dac0689cceb126acaa04d026710f02f25d9193fca20d000ca67bd49e860c69a68edb3d14a94c1e45e7cdf833b309243f9d48c4200082a17881a65b06679065989c6da3aa53d5bef41accadf69e20721c2600140824d84df3f7f8ca5e22f061a7cc9d333b133871e801c9a29c964a5aabed0cc6202e50b0f69f906f334c30a7badc5a8317ea34a64005e15b564e9967ca30a5ddf46ad6f033516063b224486130a4a59179bd2ecd20daebab3f66d4a250300e177b63dc05bb8d9d19da05cf76b2db4c22075a9d082cfec70d136ecbd45a4c8250a00a51eeaf3463207b0e69d6b8584b831c1fc3cd8a8b396564379673a498f9b2418c0b04cca6fe78d72395032137da0cdfb1fe4df0e08aaee54930211c632394e0033f2e8f26d723f377c7b4829d554c34d7cce1e75d5b9f1dd25556f2562e2c6eea1052c1e351122d0a2631870326d1037c4647f9d5e4f3b4882999280979526322e3ee726566a3d0169ea2f989d3408ee879fa26408cc3154eee235156042ba50f0956ea5b943017bdb8ab2377545dd14692558b6579c4596a76548d7db9e0f1277775abb8561ee4d3710f0f82bfc8785307d7347b532ae009a5f48b19f32fd97c5d04608c2f11af4461f61927bf51fa711cee529e567aba7df95e7a4151544cdc887687c9e37a22e06162c7c32dd1fde8bdcee45d9d28abc56e796a11497313d4b0d1976f09631d6db7444f16d34dab58492e79497bed57059b7c9ec3702b31a8639c0712343208849b5ba43f20085e498a2ea7599480c54938cb4fa8fa4872f59a312a4020b6e676560d217026c574acba00dac5a94c1678c91b59a2080b4f78e1fd7bd70aad0e836a75a1e079bb5aec57e3c934cc774c1ad7207eab48c2bb0e5216419ad2e93982638ba086969e6d5c60be5fb345d96b5ee9384dc2c8cf96e50b9066abfda06a2fff101026b47f5264462e1a33ce4f2194cd41ca5ff14753ced40c9919486a05e9de3f8fb77687ab5ea09500fdc1073920981f7f1a52925077804ec7381807ecf0bfcede940f8bc5a6dee06e30fe9ad525e452ce10a274c43842ed5c6fa3d2c75b8a95afde981bcadffd7b7549b9c2f5ea952afee42f6e4afa602ac0d7cafe1e413081082101428f96a8672d4793e6c4d6b850cecafaca6b1e1d9feaefbe267eb97d08481f30d6bc4a30a569acc1ff6a6e2a449fb171a95879b24152878da4197409b80e14ebab06111068c60de27b25a371147181e77e33071b45bf9de5db60a6b6656f0808ae9a414899ee5eb0c068ce8f76e405d2ea32b24e8d764d9a1f796ab90489924852e6050c98c148f58bd0b080c43a82d0bd6bb0540096d347a2abad3338a4c1d30e3c9df16b2b908ae068be0d0fa3dbf7b41120818c975a542c8439f6b2c62204e98063310307ed40a602e5439611120a5d36e610ac3aa260322812edf59e3f28011b0406d3d8f1fea1e39a8401537a9ad1f074fad6bd02a9c64a6d1bf75b18c83c92633a93ada84b29c801199e752bdef2bf2dca3158f0e25efbc47e0548432fd0b09157f9f284fedcb3329645f6d56372a5d55500e8c7e22eef641012b57ab9d4603e2232be0f25975d69ca5fd14f53c2f60c9ba9684a00786861a92dfa179604acf005ae8d8ec4d5648dc87afa66801c0a3f461d7078da0a75209fbd2aad0e15260b90832a219edbe8777319048dd423023f281b9ef635d46c2eec0120cbe67739d879c7b54693de379b50a43098e75008865b2b4638d0bdbbccbda89c616ec114bf8ea47ec5503f4896a839ca09a8f4302a880d0d43fddaf38503f0d557639c8ee698c3034088fc62dc0a59f6c4307b5d6ffd9575f5bfccd2491fe6c42b89ae5dba8b2f8d5846cdf5eaf72a16c10cb0949a7869237a8c6536142019500e5c2aaee2c666d0796eab7b5347889229ac38346d3bcb5ae300970c35ab5cebd455614baeba60eab22158f16eeb12f12f4339d62b5eef6f76e70ad242767d3f82f1ddb81f710974d432968e59fd671cba41cf7b1bd254a6c56ca2a335c49f388e2db69f43b0927cf299f5aebc6e3cc56b1b90b82d6f139a8e32610fb231192a269337baea4870a6b111b8ccc03f33a5483d629d689805c53e580418890cee7872980a91a6048b42569278e8e6b1dc30465ff293e2879c96105badc4830fd3d68ea5f5b9b402e33cd1491cb65191419642e4eaf0f46cbd13a9499eb28e0faf4acdb4e5e557ede53d6ad73ed1cba9986b034251d5f7a6010a17ebc3df8506e78060f121c26736218eb8382564e8b288c02c047336445dda0b8590cfb13ed7b4c0015cc61128276982c3082fb9c9e394cd3338006fe25d0240d8afbe5a6291902f10c2b61d7824eee59194a4ee93d87255c57049488991d62a4a2d5e4aa30bb41e45c573603b4d711cc608889fd36f988076c2019de18925d200489f1f45bee3bc241fa06a0714335b7eb46fa5d7db635165d1bd0bc62fdfb1253fab1d24780770c6435149861869524ae177d137743b536a425a3226de977a3345be03d414e47440ef1b57fb96b95fe5ae02fa541f8bf73032a12b72a77f76fccadfa947246f1f95aaa50114d6886a48b1510c03d85dfcaa280cf8e4ee09be4cbfb367052cd959f3a8b0279c5c1cc499e3320deb0463c3ecd86c9ea3dec2258ad9fd9fd40356c11c55b9f341df6412d47b7b3ab3369b1016167172eece5b4d1ece50afe4525de6a076d67b24b183de1618e22488407fad2179e17c5477dd0271fb60fbd720044f5ffec72c9a414f731bd354a6c36cb9619dedb424479ed347bfc8af6334aa438bbe1a86ef3d9ae438b78bf3dfa712b0363488d88774bed038aefe3cba928b44f365a9f6464767d8495e12eab1d60087362e6dc0985dcdf4200c8ebce2a1fbde4f103e26d0383dc22cd11aebde15281556d4e9b7c0e9a75ae81fd3823998715d90df30eec5d994ad7d12e9365ccaec88cda2d7f0308ca62438065bcef1f50ac7f7ff089dcf274d3a221d41e0645bde1e5c431579e68f3c354c74606f3e68f83f210061d2e9d0c978392a9e7968ca4d38a81dfbd2483bc8b70cb95fcd5aab434b495d870596030428caeddfbe732ee8c3129e1adb9c156a3a18d36da09fc463826c2fa19211638530f7996e2edcd32d4b2e0ac997b58d8655a33a05c63c6dac8c7632c0df210c303489059dd467447d4e6da8bb24c2843746d50f72f740a14622a29a1efaac4cb9e064083c81584b332bf2e33661889b04f1ddff74ef5656ee08a4c3d2434657e71effe95dc55cfaecc307cba8fee845693cc1480d0062a26806801a0a8d7993f2cd5f1c38bdf1bb6b68f5f684ecdf2366f50b3e425ffbc455e1c3173c89d7e531b5429676a5200295112a05c18d5cec5ac77dc52fd564b19af7fa23d3ca868c89b02484c126e00560a70cf22be06ddba51c75229c543851f871789f8eb77b114c0c68345e3934ff8cca7e2b3ea99f9a932f51bd9fcf5fde490ab4386372edd7bca356694e22163422503104552d310d0ab132f632e92a630f6906bd37fb604f88ba0893a3606dec7c56f04b0409521bed0ae8b2c2c2f6107c8bdba86857c199d19f103560e39020252aa522a4989bd94eb8902482848d90f051444b9383669c4458f395420915d29c6df834ced6bb5114a64e6696872c92c83dc8bcce3697600b42c140067ae0518fd136525b58925016f815290772efd1b4662019a0af5a0ae3b7852d0885e7787516ef8e727f22d00a3c480dd8382569eb67e1a02404713564360ccbc612ab2fe7010707cf270f9b4a09a8f00e0339950de23e7a805c03101eaa79727dd6442f1beae14a50b89c273a73391a9426c0bc0ee55b981950031ab8ece51ef1c2bbc93e525b033500853e4a7478b6d2c4015d3d7dc5c0ad68cc4be2f8dc4d5d76ed3c63077fa23d556e65ef418056c5f57095a37719d1ba2b91ba64a7589c38dcb6a2ad8718ea97bb1b0d92cb09099569ed598ef712cc9a500c60b48c074df0074af48ffce497ccda1fc8eb4731450b68f6ba06c00fba7f9b323ab63e7255ab412e5fa7db601b649f825202b0722f4d466c6f39f47b4acbc649ac0dc17467bec2b650a8469c119af76fee3822f0d1efb1f7e032bbe063e1e0732f99956aed7e1ecf7af01bbca896890f2f7a0192842243dda17f409067c8b1b2bd4995d3d19b635d8a27bfc68703b2f8b049203511985c9458cdd928c875833666243a3ea3fb8f77e5c8fdd912388ba5aa8241de23d8be278eace9cf4d604edfcce97fb908627693598a8facb6bbe2de50513557fc38249708aa1557bf03d8e737ef3c535172afa030fe00007f559a69800fff3c91d24c3478921b123d631d81c33d9b3a19303d5059b59039e9c6a2042330d39f2c268b453fa7d8a281cc468d684a23459ebfe95c5e17f488b926d9d5f4323aaaae3b3eea7877096d51fc7a79e521b8c6ad59085d0db055ea42c1a784870c92b0881552986d521f754b3c9c0379ae83d170cef085253b719365e2139402c1dae702de90d3e11edb209c91f26e40f010cee37f05a387d144368b082d06856ac098f7919697690416a0d421ddefa2d4d69a2c2a0ab628cdcb561a3e57f03db56ec9e7b3b224a7d3a69cc1c4c3aef14cf51699e5fd793a2fde9f762db0ff05084ed204832ac28cc2656a29b57f8e26d78a7fec5bb81e76da07a1868f73ab0ab85f6838d9f374dadddabe8d58759ca5e89a7412f1c7c86ebfdcb58eecd1d503c3b0d80deb2fd32b69c1425082b24ed32db83759d88e9966597fd00e1a60a5278d38360ebb1c6a6130125440f6630e3e3bfb467c6b5fded880485c2d0150b41f9c3140dc642d1bc6ded4e943e80bb43eb41af2d9d62bd9bde4e2798bc3f41e32a4b655105e50688baab4c5e95a5ab243bfb35ad129168af9bb297c9259b9bc264251efab096bd68b1c2e78450d0826c446e76d0892894d3dac7fb505b5cbaf75c1ac9fa22cb18539200df78c1697e30c0940c493198dcacb58544174b2d52f904446f4720fd30905de7a4213d0116b627fb23f37f3e403525e112f7989d8ba6868f9659506cb49db18cbdafa860fd1cded0b3ca425796fed515757461af9604cc8deb0677385be0ce222cca72c99ea1372471df41fd275bb4897f7eda55936a83b929431d4fee345dcdc1152136150d0da84b06ee4803c701c1bc225acc6a6fed9e97a08a2935583b5e2fb63736f5be5e93d5006b78c42af5c3012d1d5858270f880b7770d54664aa61379d16cd14319b26e63c5fa94a72c0efd6ea70b673f4c701809f008072c7a1a3805888ea71ca14ac1a005b78e406d177aa3520bb0c808c656551db87b43ce305631e9f82351ef2cb8377590bf1838f88720de952341b6707837285d7186f7944479bf6270a5c3b565fb6768a63c0b81df22bbaf6c55211f6c6b2f727827bcff70af0b3e3a3d54545d635f755bce882596c7b672348e76f183fe9f1f338a6b9e85438ec49993e52a1e2c521a1e77f027241b15682614db81427482a714c8f2969a3d45802c86d20678b0951081492803a94081f464490725a3e37bcd8378f226bc85a53b3e0a49b1ce4330a6d9c565c9c8106b0c054b0b1d812e71185d8c4aa7e614ae04ec8d0e51fca94d9a70a276750a405692c568b2581a147a22e0a20c69f66738b692374533cb80bb4e6288d0b910642d6c0830ca47b93905c8586df77431044515d069e4026b48b427272e0503186ac65a4625556888e157c354d88fe41c2d3aa0cd3e4588c9e6a55655ad62d5f7205b3d9a988929a547fb7309aecdf32f873f0f11008273dabaae080fe15c181987cb1364992b2505c90979c42541d80b9c51e7067e83247c7b685e93091810ec25502ad1cbfb1878f4b9a857e92b45fd4969372d8cbcfff1c4926c61ded8587216c23183804d5c4905fe7a39b2e2155027d39fc26bc1577ff58d354d04338417f3dad78b4da9379ddd010a575eec8510188aa42b3af2928c0cb82b541078a8cd17471d1e258605827c16f655502b6ad640fa5c8a6c1c23d814f3c50832f2c91e846851ba131997060d6ba79d0999806302934226501645c9cab2cfa3d529af060d34fc82ad7085189b1b07b91897c3da57fcf9992e9f022ee1293429b920041ba8faad03dc332d8e3854f2a5347426289f9ef3ce1452918787a55d127211f5939dadffb8923b1f283e9fd70d7d12d48dc8bb2f3ebb91372445659239a8b39d1dd1be83f82c32432ae4614598e8a299d96c67cc5baa9ca656ee9d55e5e38588023214447c87e97d29858f12a7ab822b2c0de7cd359f38af59d0ee59d28ebc644c03bdc286fa024f8ebb191df10dd6eafdf76b82f79d0af1d30a63f7e6466328da45ea69275f59607c2ec49a6f4fc80ff8964482ae6bb015c33afb92b7bf4914539c72dc6c01e95779e38ba275fd74116af624bc7b01dd0f95ba690afcf9b9dba056e39439133ffdb2d17b27c9c6180b7ee9b129efa468e9d40ed2628319e9e466a5bda720159d5ecdecbd18de3d04a5b1e98fb82daa0fa06696a986946ca744119965a05ffd9ed54f381a038a2d9e80f24fd8e8964baa116d589f97b166fd4c6303de77b0c936f64f31cfdc98f55c4f516aa891dec3adbc70b4603071814bb0fddedcd24371607d6d780b130d3e1344b6ab73721110474c0cd26c0da19209adeb84a9571cd1c269e65bfea8db515f916fc2e26e6e0ad71fdcb480165032dff4f45b520a99bd14d57894997d16e59afbc5899ef1b6b5c816afbc456cd35bbbeb599a77958dab076968fe64698e737bc2cff25c6886017ee85ce704440b73e2c779d946171eb77b730e7861556d672ef58a6aa0158970f6f781b8da79537f0cac2c11d5f85288ca5a4eb50c17af0971674db06a3b346120610da3685c04e064e059bbe9c600dc925dff6f94e7806e2f8bd2504a8f748ae4a873d7cafbe18bac5fabd332567098bbef54b585b5fc8c1be607b1a8ffb56235c1cc6203eb94c1b0b05ce474ad204c9ddcd8f9bbd3a66ff7f33c2b17e98f04100a466f7e1016536299ed0061426aabd6d0532298599ac5104533282489e0db219ca0c7e41f3ab4c6bf7331bfbc25899cffc7dcaa7205f3117c316f2d0015b6aaf093e215de29f6beb33a99044b9b00183ab8235003f4b1b496991b2b6dd5ee65415eebd8f0854d3084fe0728b21b69112f01c9408f19967ad7bd25aa4040371b8d2926babeac747ea83074bac1e279721fbb7ea9e4c44441cdb8087ae389b23b14d1cdff5b516b391a48f8dd48d0b4efc774bd71d13b028b782d57cdd413f3e9bbd3a826de9dc1d13be52c5f4aa458ea014dfeb5a20ecde4a3d0d70803e22157da48992bcf256af7d6fc4720c2feae3511c788344401c694f20f9ed56671d5db67ee3e80e9da95ed1f01d6f934eda4165dcabfba044cfaaf905d76ffe2d221021656a530a2817096a81c4a1d507013c8c1eb603835de9baef3108aa093f56dac6cb3416c8d9cb3a10d5e85d700b3578661f387d9016deabea196fde57bb42e6b9b78967802d2a915380c64680e487e9bbde7c628e7e9e591eac971c9ee552ddf90cda48021de0246f6027369fa2aa4db67a8c3855581d63eea39a45c900050bc1bc002196af349d3c978c695c5395b5634073b09fb08f278c8846e12891515ffab85c8e75822ad6359efbd86312e0d06806f390e4f5b7ebf0ae94e530f578c50646028aeebed7c8fe9a1a0a628b75c9f29c5e39ae2966ae203c3c7bd53d453a4843ba0eef24156a6393b16e3dcea1cb7a5c7809bccf5bf9596d7c345f3c22d903d6b674d23c15e313d53e0c0ddfcd258df06a4b6fd4b8d972b3f2b7b4d97d98b25328cab1e7bacc6dd4051d186d37efb5fc78904cc662b153461a6eaf253f6e93886a2b71c8ee03373cfae8f7c479bbf85968b9a1f2490ce8bced0c63ea57bf2630b4ea2d9e8a156495387619a413a32ede7757d3705c53c25b117bb05a0c9d8073e16c6b95e188f578c77872df15932011c04be8bf8effb076eca19e9360545c34512874c0381cf9d99a99f44111bd379172938623feb923702570cda8ac16a1261e6f443492ac064dad3e331b407940747b1b41cefcb126780ae284c6a7f76c2648b44e4504c4593302e8386e87c47e8a75727311311bda1587c03924a7a007148b13edf3f531546bab5ce2ddea9af20acffa7d7ffd07d0d93abffff464504e6d3bb1379b2d7562f536c03129014bfa1e3ed535b9a7ed2b0123c0efbe2d9fb2ee677ff082e75eee0a69b69b4d57dbb77fa9600cb03949812d7c188c01b1515e34b9cb203162aebeb1a5add3c0c848ea87c158b8462066c9a6dd747798eef5ce3e907664402bde4f03791d2f9e63c670a8b5f8e8de6857c0e73b4b8bcc93a62a3a4670a6d0f71eef846aecaf39000bc4c89ec9f9cee04625291a84ba813cc45e1e0d0df4bd09191f0bb8b9a6d4ae2e3177f3d7915eba6104a8f1db62ea9c20b3000f3a7f4623c4c477e798f5089f6da8a4423880a2dd0f7134832e2bfe80f9393344c50ee045a4a4a9b113eaaa290775838a42acc905eb4d079d00a7cba99fedad74f21c8477c2621a5863109ce671bfc66e0a9199d088051d8cf30df8e6224d2c7a808dc9d330e3251675a9c8320601f104a4bc200d7a0155671baa34453fb466c096f290ceca72d3818f271b91cbb281e08c7360ee7702677b616260f5eb0bcfd8b4282a4612464246f4d825f9754a752b8069388c304b872be21d981321b38881e63a07447cbccaafd9087eadadcf98010fd31c985687e44d090c5c8937ea8e4dd001dc5e743c3acd300a878b61bc272ba2dc44ec861d47d1d94a66843c1a4179b3edc8f1c9ba64ff2ba90d8add23188a9ce99270d929097ba84550462d9b620204e65ffdc5b66de98da18dbc1bcc4445b9a6d860c28ebff14fcdc8341033ba563697a8dd159cabc9b7db85ec29897e31b8c71837eda7d050dcdacee7b77d06cdf4ba849578469d77af9e008729d99ea5b4037c3fe3c0eb759e85aef83f91bc7e864a082fbfb2d0d4b45cf36707e0712745f02b8a895634f67a29a303d2be3fba2fa509079737c841210ee53800e8d37e510b24b23945e4150b3715521bf5916c4b16cbeae59c21b622241155894318090bea3ca15def5a3b3494d92f61d94cbed83e5660d5df082a4e04513e490dc44b1e690f49fe1c75e64a0b519a5ca802cdbef859b8180cfda0f10a13ea8c5d00334541196c019dc0f9eef525d6201f7b0e68fa7ebf26bab4d6923e6341ff84673722f800c9bf82715f7a8fe6258072f3d913183edd11b1765f757fc317bcdfa9db4d6d8c191c1b867062cbfa8b4774688dc13c54d6256e2a36b144359e29039a19a3f8bf192317187c1cef98deefe17ba8cb27c50cd6d7fe9636389780b97da7c100f221e42085397bf56b4eac6f01eb40e1f287b7d4b9cb33f14a3f4df9471ca735be6b92c254fb4d30e93aa952316c4aba73559d7734e50c179b6a5b8d8c77a829af3f0446955212490f2997f8c3b3f8460e4aa25e6bcc71eee0c99d7d4f1c1741c76c5801199086713473adb0d43f284cf43e0f5b62b07f5b3d178e12f6653d4e31c92a9d0c6fdf1f775bbef9382365ddecc075c52255c9373290b63c3d9e28f3eac98ebfb019e95683cbe9680c0e5d7e3aaa6027ee2da8a9b5d8ef48983cf25081f0b82653088bf1015474f35f2315d1340c89813b1cc4101f9546c573e4cda09dc7259c4b55671dfc71b1fa8d68afc1e41ff348330666911301d57ea2ba2e908aee4a5ad4a312c2d7dae611d627f94cd13f3bf98ae5eff94b7f556a522a21abc8360fe5fe209e83a4c0f9830c4e294331676228642955fdc8f18f76a20aeaa0d16a4ff810480ff37b74443bc1dece727ac682ce4c47908eaec3b368bf33906c57166c7a953751a38ee8eb9aa9d01a2d002ff9cacc4fdc1066da04cb3274e525d74378e5d93d3e14ec5c267a4bf46bd4f8961dcce7ca398416298b670092131f8a4887ad268612abdb73a204e621ef4c0fdc0d9fd25c62680d65ac153f899201569719bc6d432b77cc83cb998e719d870388400c6e60321c89f22c536edf872f8d1501c2a4144ab9a9707ee6a56bdb8274827a5269ea423cbc55d6cad8f8c5856c2663444be3567d3a56bc0ed8d94d99aac5a8ab51e142038a13edbf44f225b3c3d25fab872706ba3bfc35b7685d574b39b3cfe58db343a27faa1fedc1a9b970b02efb4548b915cdfe5448d7c7426c0e90e278ab1ef94efd137bd039081fef7d5c4b557b12a30fc2478a9f559d4371502ba2e988f6a1fd6e7cc202a776c4540ad7408c4e397374c1f730d72f07bc5cce4f963e61afa0c1a9f1576c0f698261e3beda703f326a90a410b4737fa65322c0400cbc637eab5288e5262b0feada4821ee290100fc8bf166c0bca83d6a53eafe59ef7247ca25b205be85410ad4e345974b7f357513c853f1a7f6b10fea5b436bf5d5ea711e9f06610f31ef755c60296571b062af91ff89cc50d33d4849e45098b3974021769e8ad876c04b2cc9df41807c62f40ba109d39649ea3b6b33b1441cf98b7aa5db19b7299bca3d8f3166cfcd2662bcfc84d03ceff36943036dc557d11ec954d0fe492006c7684ca209a80d60820b3a39509bb159cc60281c8b8e26c43d283f92a6b6b1c7ac44abe6addc69d8c9d32a269507565ad991fbc479834a003b378a86f537b63b9641309c90f0e8e8d214b7ae1c0ab89d91303fd15361e30014e3bac3c880d677bd74d3928713f2827ae04e308cd81756e21faa22f8b3e9dec40f754efabd3b49ece84409e1cfd81961f02aff73f24f80cdde0dc225ba555fe9b9c8098d65cc9a431ffd007fed33a1b53309ea51913bb63e06b4a8a14c9e5d9c9ec170da43df3c6c04de7bb7d80364087cf570dcf799a84430bc4efcfb95c5301b439d187226d33b98abd01d54201e4657c66883652caf783c4137c79dcf65b56b52270101fa4008e26dc554d8bd2a0851fe7939206270f449f846a7b0b1571bb97ffb1ec01d1c4c8d963b149e7f6b03372e474b0f40b7928e7660f007bdab719872789a312a12927cbcd495876273ee8fc3c80b187cda31ecd2627ba93e960b837a9e2d097e8353c6d8f2a0defeb5f41bcfaf5eaeaae7804fb9ffb7c4257fbcfb74f30e047bb8c1761cbccd4a61f75e4a4156d287313c0637d839a723c9019f6ec38933a85c57696b2429407961a339978aff7f84b5b318c1caa3857de0d29612f8d28d5fc59009f3cf0f5deb1d5fa13f5e9dba8679c9b71c624446b7b9d3ab85e4bcdaea0acbf3b0cc7214a1cda1988d2b587d71d51573a56e6c5159e30fd619fa451cfed2703478b03ddee77112ec30fd0656806abd4218c7c45b680a99488cafd623cf51576ea5dd1902283a987ef0d6610d40094d41978819890135e441b0772d18f040a12dbc8bf60708c998451eba799ceb2e2c6b11187478b6b5c9806138ae248dd014f09aa4e7ec9add1917efd1b3004276680acd89dd6da2d4df124cd16abc9768d22c1fd9a2ea21b9d014143f91a9a7e2f4f04f98a89996c1db03bb2d4854ac2fb4d5fdeb6c8b58f9b8296384f317575fd23c4a621af07fbd422ff323fb06251ed31631e7852d96025ed1b4bb3001ad2bb1142ae49062ea07f966911413ca2e25ac78686989a5a09e1871ab493732668246ad259642f08cf952a977fa599a1b576629f8ac07063972ee5459ca5298f502af14d05278efac3b3f2c13877951e76150017a5353d0331f74b2dd37652e9347181b2476eca2fdef15ce60371f483a0e20a7464064c312248cd666808548051526093b10671bad242f15baa92aa8905070b05003644741057a850131a91cb647b16222c9502305157423a8209cf2cb8c0a2a147c51e7a73f549898c8ad5981a4ea10f7c64e7e22914e1a4ab7dcac9fa264e45e2581ec69ab57a6088c0992bcf00bdac192cb0e047e60ff6ae35f95ab4152cd0de58302820dd2af7574c5934592885366bb4b0ed57e65715ec26ce968a889a37d1f1c9002a016adafcf5abb67e7f1843877e071e12eceed35de6d925f90c29a39910cb2cf9278555e4436238c3ed2f1b2242278371305ae21005c0fffdad67592ebf27ab89e6b497e47bfb1a17169bcddd11603fc3aaaefd8cd28503762606c7132479b87a6db3a099d182c5efcc463d596162ecfa197a900a281d1275c14b4407ed4d74472a543d6957d1b27dbf9585b0a4374bf12c197e37e7fffe803b126f8933280e886179c2d4899452060966b70f7db68e23d030f83eb0981dc35396a01f52c9cb2637ad69da9b574316051e3a0ab87ec5c6d7a3a37e89808911a3a71645b189ae636c34056fd1b019a0fe3b7d088a2b517f530e96df90bb43c76bff021e03b6261604666728e8d4394c66347b0dbe17fd318b5930b3cccc6e3dcf47fa904a381d2b956f3ba5e3ec84fd1ec7b1e2295d15fdd87453252689f167278bda178ca70eea89c528c96c315208bb84b17e269b77f762d9561091bca173b03384fcff50b303893ed841d3e68d6ba6e48945766d80343ca82dd9e9a77741bba7ef1cf29c86844243681be2be7660861dd97d8cb839b313a04e3916e8df31178109d9ec9fbdd83559a9546400f748703ef4d83fde4eab9ff72acd2cf248dcc31bf45734caba07cbd299a50be1520a241b6e0a4fd2203891092480702f81582901ef404e51354546934355d7ffaaf4d860c067514a6072d3f03da5adf8a63c8c8f77946718b2ea00caf1808125e678449c547b8744fe406ba41eca3d4a23dcbbda16c19553d56ca6bc59a215f929cb0f5910316e0c0a549ee5a51da32d8eb7e17c251d32b7ccd6b25405a8c55dcb8496d1ba5c9ec8ed2b0885050a2ff38d505ecee04f2053e4498bf4cd268571e2b1071e1f49d707ecafcbbfd3eb6878d18b84e69da29cc86ee597f9bb8692d83ddcdba7dfec9a9ff1a4d244204a361e1b68386cc65aa57bb90103341977cde03b0c7cf1458ca4cfafae6cc84e07105386926c1ab99ccb16e6f3d329b682665c29949beccc4ac802400998909bd4d8ebf38428a99809cc20fc59b0bb5a14849f7d765abb97cc948aa1050193389974888f9b9748b5a72141080562750f81aae289957b8730e00fc1471cc33841dc105a325e7366481208ef9d3033da743c46a07122dce16d6f6aeee72b0453c62b90541887a1b0879193dd8a670d55e4053e3ac48a6a4f4879a75488f0d7f1e1797af6234e24c035434e7ea42fe130ad71aa0620e1779b6db960891c72a382058e4e6bb9a289f08beb2087dd701411d89ae5ece9262607b7fddb643d69736abaaa02bde2ca255f12521557d9de6289d0094dbeb2ad206515ff74b9fed0ef81240d5443eae5b01e493b44a8588e33ae9add2a36136050f1074eeb2e8ad84c72e8ea3faae62e2a471eba9ac4c9ddbd298bac603a233b6b1f0faf0d5f474cd3be14a339dbf05bcdf5b6b0344059de2a59333707b90defaa36d3aac48bdb81506f581a7918e74c8843e512358e93abf55634407352fcf5869edb6aa9d6445275ddc1ba5c288743ca62213f533d7aea5a4666eaba8083698e2bb4e725bf5279df7a3a43d9ab4ad5d6ee3087ccff83c002b4a0a6877545ec4d428a172de0fac5aafeac079e9ef643b594ec7d69332a917fab180b8fec4380580201f1d48b84fca43cec1c0e64886204293669759909282f69365a9de88953898e4cb5ab15b3b2a7735929157cba9d0d99c48e54eca73a18fafe83780dd3b82504ea72ed1e80e8d6d11817ac81d2b975d3071fe65e7309064b08e8ccf792311f5404ce2aecb610444592404c21803455b49d1e26a6186ec5afb2a767c8993233b3c10c5ab05003a90d1f33c17bd9432477e737b2590bc5c1141fca41663a7433f6b594cd5173be94045dd3155a68d8184dd0315c992fd7695f9f6037e819f30cf2f10fee871842c021b07db9303b793a8ed2e725e7e195c503b23faf14afa17e0d1d32ab88d74c46e15d8c43a613615a662fc0ef330171f4d6094c78d8e34f632d7464412f39a434f67978a42490ebd54e2d9bb56b809758a5954b0c53c0ad8c30425ed94e469e3918cbdccdd68852be6318d52010578f4940a6ce33c16fb4f41e9af298f5b9a20b1e5276ba81a4bf43ce675eeb2242a6494dcf142c9d5022ec0f133c8c530e71d4a8b65d1ac4cc6cbde77789603f5107d94e5206fdedcdc6df429737897f53e005d1aeb23c007577e50289958d87b3684e7a18cb21149b71eb9cc8c8b85a1a1d707ccf584a72e4136f58c15c96d55796a2f3b0b0947b237a06dfd3a2a40da06a39fdae5e4ba8cd0d579ec2a54f05ae028d1edf8ea8c85022a214bd3b4e7d771c3e4463d01358a7c23ff5efebfdd70b538638eb4f47f4c59eeafd71edadfd4f19f48fd0fb9ff9ee4ff440a80496e6a72fd7b24dbc9e9caf5fecc15ef7958efa11bdf65ddb34facf52448146182c9267310cb223e260a9db5069677185bf48fcd6fa13104147d8a1247ef96a5b93f37bd93022a2d8739fad2d06d2d5500c2b775d37b2bf648bbadcb41ccfbdb977276addf1afee737263efb0b3b435653984cce7792329b2473964afe6c9142345d82d29c9446df89c4f2e3bc513f5d0a5107e201130b3fae5505617a2bd41461446c628b7888533511e72ab1d3ff3992b554972ccd5776bae0ef78296af1a501a5b59c8600b12082cb5464613cd156596abe56ef253d7b65606a7bab29222594297e817929cacd6529ba644c290a38b5a5e82adf30fb32f66104252d0cbe6d6f63ea513c67c4fa3b634eede7e608d056c8bac1ffdb01678b3372770bd086233ad905f177addf1abff7177906113fcf3b845fe2ff3e337cd8bfca90498b74a43ad34e172e514f4438196bb2bd86251869c0826562e585f0d23b8551bfc4440b7bcf8c16ca93450b518289d617f1e30b80e00d2d6752ac180f325af15fa4f9f5eae906521c8a21580e579e8fafdb8301bd818ad9b96e837ec94663f80af44cfe6ed8b47984da3a4375945ddcee20277edc120ef87090fa5302259450299526df862f4bdd5be69205a35549a2db6c7907200c848bff1f5280de8106f23bdc1e8430e83a13de40c1d763b886d1687a48e597519a0671b727c0e030d0bd906613b3cf870eae20552cb2ccc7054580d42a427ae6627eece68878bfe7e7a06546e6a6d454a4fd97d839e625463ebf87da48f10b8a33ba1d7cc049e0e94c1cb574ab127a0849498495dc4adf8e20ead9da6ee8d939c0b384a52e14aeed8fa27b51c6043febff3417c0f043a7eea09aa7ecfcb942209ab2756dd0a578019ed0ac1e7b622813ed0770821d33229cba910fa12cc6a23894c15025454de4dce43a3755dd01aad160dd9d65fdba7a5affabb32d7b54832b3335e9ca73ddbcc61b705ffabc8c6ed4dee33e49b8f1109e0c91618fb260ae0926264f0ac412e594e7bf2dd2d0f288f8321fe19eaf05ddfd2f8c84cc6e319389750e319aeb6cce3ea13364cea2664d50b554a8c9c9a3057f76d5bdd595fb6ec8750427150ad6bf6228d7335d19b8c97e3e94005d19483c04dc178bb59ac63144df1aff36e1ef0b1483bdbdf7db9590575da39cc4911602a8b95a2e0a85cd577288d683222d1212e4388058136becbaafbb462ef363bc3b2853f4c0379ac0680ca8c60c1e8344f80c8eb3bf8de85af74cb827052315bd2cec3219a964db4f1c1f54d6d29034a73bf93dd8180db4d84ccdad66e42b477c8f1171effff55609895c773ff0ec640f82c1a1a46c0a27d5cdb78db0b7dc5530686f1630a3a8323ac98ccbe17bdcb3ed64d8e55b9cc8956e88301c8179da84f75e20a289cad6c232cfa4e5d0f8995aecfa4c88da240bc35053454722ed3e417ddc8a8a151881a071751c0a0aa07e95c1eb71ecc6590320961f49a3db9127f5e1d253f471910dc14dad8157bfb0509b773cea480f18cb0428183cdfdccd1cb127da0748fee9480f4cfd3d0cdb056d26703e3dcff4a07fd49fe5145fa3473cb77e9a20aadc8a08f45337fb261a4552a7bbdcaa514b8257f3394a328af110d940ca1eefc296a8694f6f36ecccc7a4298a78413b279ba09178174599a8cf0e706d71698d1f0b9fca45856f8c2d3fab7c16ab6472ec4d5dc0b799c796ba910b0c67cc12af50c8ca359d95ac59138f05ed216ef98324b03df94b8129bad5dcdf0088c85e40dcb57b785b63c211149d1c0095143b7473295afbf81f572793481050fe11e1834633fa57bd5f192576930940f6fd23c496cc65d57f0b974bbe15b4c0269977eb5129e55127261ac91ab1b16874087017d5558902285e048a46eb9572129c2ceb425dcc880ea72c3283fb2012406369ebbd6633ce247507da4042d077bb36a9545bf548829d951fb3eddd05b53aa752aa898f6ca007b44fdccfa8b57354f02c5ac5e2a7007faf2a26c4f73ad129bd1b65228172de0e945c3d6b40825f8d790d56948998513ec5a4ffbbe0ae984059587fcac38a60f33bc39a1c398c799d6a865b10570cbb92595b3dee238b87d422903edf9d0378f67e64006c23cbe070d1cfac74458f07c0f70cf69f9f74e4c0435e41aa432c16b3f5b161e63f1ab45b77d865464aee1196d551381999bf9efdb461dc4acfbe806223e67723d3ef8db4cc8a1938027367ca65eb7579474b0663e269cf33ac24660797a8fe4b4f4f34fcc23a4ca9587bb728a530af36b5aa0bde9d0128c9957f05f655735260bac484e2daf3fbf112ff0ecdd826ff21edd75391e46316ec8f377591e8bc925d837067b296f783a9a9483b39a8ffaef0897a034480b0279a313c6919731504593f4025546c3619bd7e785f65b317824d38aa557764b0fef4dda446076e6ad0b88032061f8a82b414a2159bf358ce4e799cd1d34273ce832df27fff80367e01d029010ebfa554ed343ba32fbca194743f3fd273b6e07f1370572636495354667cafd054f9c4075b01d693af7a0911cdab8340d6f10e877487e21ad6ac9c8ed6e150692b0930c00c469a15e56c43ee50cc0de24ad98e7d3935a963d31d4eef90c002c76e431081d8ee1bf1fbd8cdc79bbd4102f2eede2c15de6cead79022eee5240108508c0e2634c6c662e36e24be031c4656d32069dc78187ff7ae68c3e68802a4504087f9f9dae8cbfb7d3c8d8e0ce8f6e7a2bd0a4611fb76c2c22dbdc713d390eda61ad128a518f4a223155ad3f16c00a20ea0dfc0999962a43dc4ee4ce232263b750eab23fef9692177d576883caf2b269adcf6cb59af547afb0a2e1e24885c7dc6fdb11d7abe2995d70db48f2da3373a8e51957b2850f55a58f631fb81fde395d63dcc3e5a4584dcba714aa47d70bb59b5f08108db9afb382126c584925d48fb3e32858d1bb48a4c3b0923b5582d91edfcadaad51c3f5aad39967695e34e318d6eade84d558bb10b88d64f7314fe85a2ada031d77ff4e30846d1b4c34db6be8fcd347dd4b3e08f354dee7912b6a31d468bb2a6301304107b37d963504345dc0fafb9d081fec6e16325d68b6a44dfea2458daddd5b232451b5b4643452b342721c51ceebd21f88685aba37a3c75903a77fba731572597899609227e48972f05c2afa3863fcc631dcc10fd8e569c957c62edc1998aa1a0b126a3c9aed64c3f82409e4b9a7951015b604d9dcbd6186866998da3add38acfca9d1bf7b77d460c623f0cb345be8d3edb62c94455ef5fac4ee958e54954ca12cb904475d3c14102670e1e367a9c74431d891afdefcae9085cb1b3e6411064aab6c3a6e04243332a57a7c9c23e2bcc1c46e897f56f0c0bfd2576672b6befe5b31d31c42ef687943c35d84551ecba839bf1ad85fd7449845f24b83bb1f099407da91647f089b9283d9c21b40e0ab211d6a971710c6f7d3bb75419d45e2a7a4c06a2539f16a44838ac18a15b472a8f38ec697afe0a3c5b099f18a12ab36d3e086a615d8656652992c2790af9f5c33a4951608c83af93c58bb4e51203b134f56872fef50bb2524a5b8460e486c01ada9114ad174cc9a8fc82ab5d68d381872761c82435b0bf705e5f7072827416fd80c1e2751ee07cb23ca2b4b7bf88d5f4e0571263834ac8d091eb8ee9ae38f748c8ac47e16de8fe8dac5ce3e9e6ad68280ba880228568e08ab4400a61b1cdaac0c4038c82a26c9d7a0e1cc3a5342b42c631be24d3ebfeb9f28e6dc33308ac65f0417a8d634c4a71a67ef004ce7cf91b11ef74d7dcaa31353712d8c128a1b9b801309cd6c68dcab869a1f2cf2765ba4ff1b42a83740949ad8a70816e637f88d0a1efa4e147caf7db6c48edacdbd0a711cd1eb065a13eeecd9cdf32c61160389f2a983fca80624b45e78677429353639820a85f381f2ce66de4d717cee73ecf70095db0fbca4f365af27611a6944b9f4d2cd596b0446000d08c48015447213309984098050a51dda30c10d193c4903ede10a26c106069422df6e0756124b878d0f72bc152b4e7c213b4b4cc4f25237ef5643415106ac7857d660eabe36e07d6e2e725c05e5914d1022258bdfdd14274afd2608a334589179ae8210884addc70328d630ec639881766cf426a073415040c609ce35c150d6dd82b060234e6888ce7c0666134e61ae0b76e45d9694dbad71b64848b902fd0e8750c21f73e5765deef33b3be5870285f09e881be2ac78316fc0f27ab87f4d1b57fcbde8a7c4aeb6c2def7fabaf4e4325af6bc30b27335226261c632ac45a2c7ff392aab31fa1139a85e5a6aaf39a851109285275da126a4f821cc4fb0b041db040ac13d20eeda3c24e26823beeeb54a41bacea9273f71a64e92df353d23ba6ac3420c158af892cd28c4d57a7549df8c6ca898c0a89547a9a5a891a788d0bf8d4799d65a1a80da7a3f3fa18a3fc3ecc80a43a5957a86d3568740d9cceb3f34567878e2a69ca4604f6ebac7236553b74ada2bc8c109eed5a7cb8430520ee25d73519d090a14ab1d977afa3c0fa5e481cc9cc7d9bb6931dcfc6681c04095ccf0bbaf251305b6f1946589b122dd4c5a09ae0e5168a83fd339ac2bed516dbf0b5cc11c9ca5e94cc22dd771b2928bbefb11e18b4d29bb471d48c16b34628425cee88a8fea506dcca31322f42df5aa536b07fcf6694f2c892cdea6aa91ecc8b1d7506038fcc52efd266cb760b9021c578a60d85809fb4d639f0ace9c608d274c9d6980e162e891fa7ac1f21a59961f3ecf1613713307cdf9b4694cef7bfbcdce464122aa7e4bc539849f7a2598facf5302549df7bd01a06d4684fd65743818c5e6d1905b0f0caf024c648efcddb72adbf3ce494cdac5fe85b8086f405b9609c769332fcbe69842343ef40192b6f9a998b322628c1ce2bd80cb86b5205829580c36f1e48e887af76eed8c32c52851a68d5f16b461d3ce473825a3a7c8b079bc086ca5db0671bbdb3201f1f27d41b84259995cf3db5e533d9ae942a7bc659d4db24cde7d1b7f17b3e54e917f6c0667446b46d64f59a3b46c3b8632754969330daa5d8e6c0643dd031c9c0f212ef26b32e66b62cd2330c6cbb4551b477b34f104aa14be0174416e59894a431fa21b2aab72df3e27c3483883c5ffe22b3318f1fdb8c15f09a13dd1d54fdd72e6e280fabeb959a9bd31f9d3df67b9d56fdc1aac90e5a25c2fbe733948e1b35f9d291d85ef482bd624529e6104fef9e8fce5401f1ccc043331e720ee40c1c94d2053126e67be42e14703e703d03b79422d3c4d5c29e760c67a7c81975af6b6b179c9f41025efe199b1aa1816736247182ab2359e497e0e0001e8ea1ad722ca3c50ef67ad1b77f98831da15364b0121033cdad6857276e2295f06d60219275a0d6d26058abc189842c1bfd318f710d2f475743f3a24824a91add1bd46f448fd91943b6801ea3ced03be17fa20b76e8dc61413bb3a8bc669458ab518b04e2e755299e66fa52faffee54a28395aa94f4948589eab1f5f5a121dd123acd2c2960a2782a4e2fc4ee08793e4d6846a97e4680b888002a1a00b3ed4c48629be43bf5df2c9c816eee39dee36b620ccdf952e58524b0451452f417efe30bf78528b3eb2928fc15bd362074e078f20bbbe9c03e5aec17a9bfcff87b900a5e2dd9c74764d4fbdb19cd99de9d8b48646f16b4de2b5498bd6b03c16bd9746aa20c6d5166dc16eb7254a2a318d27e21d5b2751278c6ed5a98a2a0655cb4a1bf9fca8618dace65a6b15e9d170797aadc8b8425fea61db74dd88f93a918d6640a4bee79ae8a780d18988e6d981f38bb8f76bc2de7c6c4a54250db65634049f5735b08be52c2d792288608394f0371d85437f5a01b003a6a26faf5ed9267aedc162854f3c1163d153e336062b4210b18ea228821406d851351589c306bec4b701d0c2b5ebed13ab1f6ecc99a6c3e1839a761ee22f943c84ec425c84c0b0764ed94d9ebb2bbf1dd2c20079c314ad58688238a933653be902f4e7e9d9beba505e31b33637cf8af2c859dc57ca0a26bcf81d03df4ad9831d065753f324930cc1a3ce00096e50b4450932e7f243e0bd290728a8f10ce942d144bba92241b01402a3ee3600859aa4ee71a4cb9d195ef390e90103d77c9ca785dbceb22ff7117fb63e1155b08e1e7527ad2169e3bc52ff32dfc33717eeb58690b49c5f6234e939f178316559c45758fd9c97e5b97ea2576d4557996f1f378d65b0ad179f2244891486a4a647aba46e667ca338a2b72ff8c01e4e32e39007e518250e0372fc50e0162072488d96a4ab10741168026c563919256f25bc2919894d8a0ab57272670185b2b2436b1cd686767d50b2ab76746237da81657a57f43b9ecbd182c712771dfdf40e3dcdffe3d2aa3b753b443e3a65fb926c62e59f5cc0022f458913cbc1905f42ac99a4f97905bfcb4f08d137b11f5e9b1c6e182926f3e67a178008b3d93be02e4f1b92ca471eedb3245c61b695aa688328855ddf99a0dab69e48075d8544712780731f2b19a514ba9460a3fac216be0dd150755597bab2c4851d7e86e499cc53c4008679186bccae19299022116ec31deafe84fff6692b4fae41fe6ad6a0d0f082512caec39103ac45284faa52e8d150c8b5d6c5f2b3f94d6a2dd3311a0832059b65d16320e404860584d8939a77731ee8956b40feffdc785841489d31f791044283af9ff625c7c5446868200d7943c7a06e17e291d5005b3b0a448c36efdee602bbf428dbd84c053de07d65b2a829529121499db72f87de55b573f6fa9ba16da80824756147120666295a44fd007c992279eaaa3561131ee5fd40cbcbb04b7ce3ca209a2c3276673e10cbc01b8fb2859ead2235b8b7850a52f98a3ac2474762ee7e021b7b46f94353696529846595d0352b999b8aff78db8faea938d0f42877bab648b6efd022af6cce996fb0dd3acb253d6724472f0397b823c5c2973745cab15897f28431d3adeb0db7359b8a6c46de1b854a9040f31282383fd43028a87da4795a1485093c99a53c43f008e37a23aba9d76b2dbf558247a3455a02a622ab7892d6bf5cc7520998d8a5e19e5893a99a43c01fde5c92afddbc98c44ca5ec7a3ebe388005ae05c26d1e94b36c6f292cca89893d130fc87891e4882e80525842439c2237dca3afe62113d9f5455f8884006a1256c11d954031a4c428d6f8e46a7eee44601dbe1dca71febad5c77b8b894d257ae9ee490822c81d84b3f77d711c1d8037ab40c13bff2ec1203dbcdca1def9bc5259fac7426be7e19e3cd282bd8bb43d6395f548988352bf9fb5232ae6f0bed64743ecfe9efdffca8f699b3b10c37aedf8448440fbc88190b95a16a7d7a00c7f6ae3930d30461b8981147b9461e72e9b2a2049f71eb7f2aef73f326b3ad5f099210a5d4afff20f7e3cdabc563e954a96d3d03a530c4ed3e4ef3506d17b12f14695473501998ecc61a1534dc370f18409be1d478f2b26bf0e752669f80d8879e6743995919b46f7d690b354903586858f29d9a2a5f9c9665edff94ed8f414b91eb8917741821f0e7878c84178ef53514973032a70d9d63955f3a39e8776fa73d675f653690eca16cb46000d2ff2d1f9376e057e8021a8811f1464df80654effff26535316649f21dcd8b80a13a3f07f45c269205747141c2f4835ab181a0cccb3a0233e341576d62c2ce1b0b7ca50a0c9a9b4d5c4f179b3f135c1a858ee50497993080c85ff0111a34480cc792c3d63b829a923a7623cc9b3dc3880ae87880c34b0893100aff71a5f03a9f0ee28fe1698dd2c5280218422881df0f90fdef99729f03a98c0213fb54ca1b255de71ed50aa2150d438485958020f997bad22a729c65698f0a75dc637af2549e82d05da78de22b249c3c5f15b3a5960e7f3c9b69a936f51b75c85d7cc4580a15841c494b1fd04c5e7123584697e94c496a9b342dc0155e311d148201d844e9181b5c4d2e279282a0cdd8ebf36c87f62b17ef19eb0f06d74c4857bcf5619f178ebd19185c22438d868dc6bd16acb0f4245f7caccf469b44b31b9851c5d4f6816968a8ae503b7e6e6acdec0a5a9d76c7a34705624dff96f4067568b741e64d558febf7670388ab44b8abe9237a2abbc70dfcf7344fb9de9202e899bfdff0d9fed8e4a8498e6da0b9d2dd63642db4b4bfc30371353c8f0ef9ababaa2b9d57c15aa58a3255fc5a3ed664fbb139aa7c6367941b8926e7701ef1895a3e20737080537fff6440d69f97e9431b5e89f651c80b8a6c8922b0eb9ee66557934371fee11c1ca557ec19c33317142b8fa64045e67c7a1003146a5a418074bd60beade0c621896d4ced241840a3bbddec5453b5ff221f6629ae0716d4c5a7af1334913633ea9e4c5551788813b4be994f40a0f1dafb453ca3b0d01a288480afffb366f8de39ec419824dcdb73a62b10b6b299849adef638f1df431b613503e41de43e54eeb6882546bf936a8c5ca836219def44eb16dc1d99af385a9c139b5df8fc97494fd2236622fc8068b788f0bbbd1ab087bf980f58b1eee6c5115403acaecde7ad30a17854cefd21ae538225951b8cbf9b912ea0aedef1574946c135ebed7eb712a256f1968234d698a6b1876e25565c177323a3e898eca2d3ed3905e33b35c8e89370e9bb6a5dcd0060cc50ee1fb9d89a60a8adbad15db5d9d27c12b654d26626980d70576bb4f0bda6e9d7455af7f4efc229297411f136aec2ea96382003b3b329ece584159f7522d457ac7dff54080e0d60601619bae638e85fa20904bbd16ed4f26bd8ba077a72224157ac9a295d5b84ec6b2bf30cf114d1aed438b14e5a12ed75b6b62b2ebad237e38ab3f50c11c7d3b6c6ea60c281271dd7c3401713a9585ce7d01ad4e150e5ba65f5849de80aebb84b8a0474b7ea495041aa12a08e99cf3dc251cefce881729eae57bdce5a177080c62f0485081ce053a1c2d81858179ba95513cd823d8c47fdeecdacb22c911032e3ee6a9904592e1c76c127f9cdd60cb2becd5020511caf4c8ce0b39a5e35fd53c5cc5382dae21f080d5f6d0691111cd2e62b8886cb859cdb992471f7b071961ee84aa643df88738649da72cf949e05e7101373f58f4c890d210428ca9c2540e34a123ee508b241f61ea51c10feeaaff3034f6c8c474fd1a62d2b4966924481242f205f72d6ca53da6c956e0e541af2b398b5b7c69a6a5c1474755f2ab0d52b2468ec2cafe06905a8aca6dcb2e596431b15b16cfd6536aa31927f07e93f1f6056f844d6907ea8b02e245c805240e4c2b2d4896e4cb76c865d02e8d8b90be510bba12d981614935ea87c7ba80f53d62b68ea3a4e03d6b6495e0e444b318b957e6299b966b731a842ca33c4f00c54bb48c60570ee7a9dd74c5ecd2fd35322688f9978ca47b469d449f15fa052c93be97728f4d7cfd980596ad7f99ef812e960ab97e660f363d7a30fb8b793e801f93fac3408e474df314835fe1ca155be3dbd21a03ff53a2973cc7e0d88a460e8135c0622fab4b8b0dfb2072293c0b9f23f6508f0c16ea3e9c3c83c29ec60f216b97f8a6875410d1f468fa06a52d820d8de0cce8142a7f1889824c8dabcb13af98fd9a0b079e94165cfa56fff2f34b965627daf9ee88ff63d43589f354c904f08e096c94f22d06f7f76e81bd613215af973cd77017ccbed42facffe4fc11a71e7b030e857dc01bb8d8581b03014dded9541c13376ec8d6c3367a0a8b66442968490bf8eb18c703f4a767502aae122fabfa877bdf00196722ecf0aa057ebad83718d094495ee431334d0c0f41ec10fc3d8d0db53c59c139f564adf26cbbbb98aedc84a334d8633773edfd838990c75fb91976b68740583c6abcfb6228f454148f6934182911ebfdc5f33f01159300ec3441d413ffd7f2fe5e0161b06cf8bb6b2214446d0b2cd5bd80ebdc72ba1dbae06d52172ff0dbcb27e2521ed42954d990321fb3ff6f96c3be80af589152a59ad383ef24c82ea7b10e20424182501c8fa4be7fe4fb64f2818c92d26299c30b0419dd885ca3c1004772c62e53825d1d60656f9f2a52425d01755220402e4e399b178b54a47eca4938376ce6352e7f368ebd0c560ae64a14be03c0e6818170df6a22186583689a7b582b388500fee426b84b479527cc5b92d18fab4ac51cb81adda7d7cde6b4db5a2478f1e1fdca1e09429dc9c80e637a4161f1cb3823a8d6d20262b2a1baa79fe3a3fa25debb2ed1381c6a0b0f138824e67e665a7e5005104bf9f9a82779a2190bebc2cb07048ddc4c7e704cbc88caa6577983210120f84dc23cf24ca05a58175362d2d79f7fd2c1b3178b4910a5e4910bdf0974c26a07792e75b38cd5aec456f1c510edc902e4adac748cf427452718cbfa111221df0b12892189d12b062001fc2bf53949be764d4a6fc8c5087fd0ccd47a3fa435e4265fd843799d76405156bcaf49d7395e82470a44feb398464285b35a25b34c3d7dc4a7339e21411e896cee7146049926b9a07f34af8da3a5422abd2cf377470e9988c52a5fd16a2cbc0062863164936204a192503a195a3af61e3a2fdc2e95c71246d23dfca6ac5a8788ba5c3835678f6b74363f61ee8159f052580bdd80d705bc4006ecd23542a58641f5c712b76ef4178709f203354a630098862602e42cd8807b36b3fe608d0afe4d8929f0056fb3c8f262a0bb8aaba394f288fc144e62e237781f8e9e16bcca068b1d078383b50e00ffd916dfae0aa7728393d5a8674cf1c450072f5ecce6e69e92485c32e36df1e11403586e948aeb5b82fbf2ff766862d3fc37eedd32ea9a371d97e07f90f2d7e0db2e1b51c2bdffa0959bed5678c431acb15f920ca50be0f7a6eeca5e735a4915df9ab9087753d099456d0210a171e5e4390ca7f402faa79717f71fe9d8141f1538a31b43eb1fc2030c0cde05e6e9109b849c07b8da2a4786811361d6594ef3c55333c616ec2c61e4acd1deaa4a3dcb423685dbd80b5b9d8231912ae62d77677215f6d485ee2c065427a203e9c1c99803018993712ebd5b6d9994d3ea1292840fa4e003281ef32dd62d62d535229fd93bbff0d83e3e161aac363a7fa24c3a90e4eb2b0507a90bfc0dd42977d741f4971e50e9b4a4c43f7a205ce3720a62403a10fc28501a72d00f5f89f04922aa4d90a4cf6b4318d4079d74955b8b15503571e444143f10053ec396d9d7b32cdd9b4a18ba97d1162501bf84a412c6e73f82b5d4df791673e17411e7a50617664d0b4913bd7a2800441614ac17f94e4fd449f4d200392b98436f5358d90ae7609631a95f4470983d34f987ea20724f4062246aec92711997e937d956f280521f4ba04e3cddca8a3011c5d968a04b74fc548c6ca2755bff84b9d5665a3f46b6a50858ae6050c22a1eff6baa22c003800abe3328eaa2a0aa818307462051f466ad7ea228597dba08eb3b560cb1070198f477805d247498ee0c0cd2264006dc657795ee5b8923dc3ccb213804be86b527bfe51825b759a369e418e876215205fcd78ebf5e3836c5f44edd6ffba20247c089ab799550652c9a1093198a6c73fc7b7087b1d0b96a92ab6bb617b3cf8ee43e51b3fe4af97436a92e5e08ff4abd3e9e6b31c4cb54b721be6f735860a4fe942a09c91c695a66d0ac8fa93ba5646487ac0d41a57fb5f44e36fc37be3278aff08911d42f299943044fac4560d48a0cce7d2f37c581f069183ea0378f47eaa3a6f56dbdc112e9a81909907ab18b0824f69fd57e8d3df1be730e02c3ef6f9f34b16ec30e6c846136058630598265121a6c9a540a659b435014e3578dc04b91599290b4968db91a170901cab1db1b081a4e3d99138d79b666447126c1fc96454bf8572b411058fb8404cae042a7f43ae57309e11a703af166e0c27f4cc406eaf218d5bf05ed2b6abcf54389a771a6472581741a7d4870c44a8c4cf1e330480622950413018944b689aaec97adf062c3ad4d61782e0de4c03fd6fd053c94b6b7bcbbda59452a62465e80af80a790a32d589f6fa5b468f2f43a78f2b3df95284926987c180231541f68f079076a264e832e2f6302218cae91da56ba126b7e75991944e9d62d790b203d960c7c9d7a3ff79f954c3af57ac63d9ce665d6049566eef4483ca29e5cad620c162d8281dae732587ad19b0fcfa9f48ca4e6bafdde73ba7c375e4ca088e2fad865dc766b8cdaef400779d2cc560558e03246a804413dded8ec41442190e796943d528a5b4562b745eac9cc1560233783c517c708643905002f66438e46507249a0d405ae4862cd183cfe7f3c17809966894e110258c702f3e46a02d4c90388189361a8d4626264390d829c9700812454e4ae04219b2c414a5212f354819b244eb05090bc689136268918390446b2fc3212f5ec8a4f6621228c8244e8bdc90249a40f16c3cb85005c3814ed26077eb709c8cdb8bda15485e8d46a5c4f89d618d13682006181bac07fe628d345e831002d66a86025ce2a1d6e7919d87fa45272a1755ed756907272ed05ebfb417447bfdd0b5ca76028de2aa7b17c4dac82343808757dac1737c08647b8a20214c959b4051e0cfce582d2620c3464d2b42f5c33cbffe4743870c6d720fa193666ea102bf3a01a20800bdf811b6c4585f390ea938b186ce4b4fda19018511fdb6ab3419be10d24ddd576732fc2ae32923ec4bcb7901dbaecad852ed76e83c737cdf892f671a1545a73a175cc20a5639fec851c6e4289fc89106214792a7babb9210eddf3c5ae0c36d02de559caeb654ce23cad9840ca48150a0f90187b847c8e98294677781bf4cc75971157dc495cb99edb4e753a5d39e3b8b5563164406b1346691c6d805a936ed0969effec85eef8a45ca745cceba5a85646e96d14b310ae75f1f319f989b51272084106a78f45cadf66557840dbdfc226a0bc9dbe7d1e20ff1df5fbd97fdb3637c7fe5595763f6c05554a5a2aea26fb9cac92ca2863181e1068252161232b32ce444a82674136a858884b0e814094c080634599c7105d3280ddc55b41ad63231bca6510ee33f1d355d60cf37f5c4557786508afef38f02fd05c205fe9c15392e8adedfb1889ffff0c35cf29fabc8dcfe732339db7f7e642b75fe2250c90b8687d3a135a6c6d80ab32a018e3029a1388a2b6f67bd01c31c5731aa265852c376b02318fbefae2a4735cc0df8050a7f4f114ff6a5f77401dac86080b8cf7b389a459fcf7efbebf93cb6dda86d9f2e9b9f654f3dc74dd1b1a89cbf2001e2838a64577b9e3ff1455b07db137130d3ce1b874516fc0a0fa806b1228e768e13db80312c671feffddc7bbf23ee9d317e9671a797386352557b37663d9c7ac419f36ff6a715ad9f67217f978bc17df1079d1fae5eecde9ad39ed6652f6c8b0b24df0f101d3c5faa5e424e748a0d787eedaa4e8eb03dac7393bf98153c559aa5d9957eb02f5f0812dcb9cb4df7e57ddb411fed98a8daf38c6981ad105bacddb68f2a7f2119ecb4ca1ad7592755d81a70fc0ccbb8538f380343798c2bdd6813158cdf61f30b118a8821621739c6efb0f9e7fbc3941f6d016d78bee4ae607022501558f4f36388fedecd25862886a8487b7742e83ad074dfa52abb11e8bde03e60338cce5fd0bb5fb917cf8104b88fc411aa960a83f3d7731fb03946e745a077ffca18f7ce20f65f704156b6c5be88f3979bee57eefea553ba0bae5c98b123f8be2643953fed419c639cc30d0753038e4fb9b8ed307f9ab888333c56d648af7127d753b86fe486ec5ff27d623c5c7c142efec9911c9fc4e57c3ae4ca477bbb2b549f80a36be5302b579665990f0db8a92f4fd58ff647a7a20592e3634ae0cffec8f113d3d9fa72537c7befbd407ec8b4d8cfb820eadbae880bcc09b8c9af7ffbe474ac94204495678e33df0542774ab634e018b7983134e0fa9689d69c1f6d66fb11e86410a7ff2361ebca424fd0ec434e34aae6602c07675d85a92b9ce1f60346730c49c51a28faf01bd019f094b2bb5684bf2a835fe2ce85749fb3542a676166c0dfe591619edd0a3382bfbb7a92cd6576a09dcd07508e9b3e40da7399ec3fc41690e631a06d871cb2b3da9b34edf98c228a34998365165a8cb144e6e011548140a20c937ca89495b2aef4837dfc4648f946e0b7f661cb0a67d859ae42018eb9738cee892bcfdbec6b0633ce71dc9475d991ac64fbeb44565292795c31af922d73564e76247bb4623bb265398d8adfab10c77ae94c27be340ad481a088d89e06b80ec00dc37a01b0e5d332ec6d872cdf155cf1cef8ebff20dfbe10f2ad7d23f0cb4e08fb249d11f56d57a29d0f24d5c75db90986f3257085e9eaaa3d251c42d867c0d9574cb3d83026f0aa451f6ecec22961820bcc307398f0822534991b29a21511904380e8446715f92e90ec0fbf8f136520437de91c81489e7995ea16ef2ce076ff4677f7474cbc30eddd158731814332edf99701d38720176481117a5c9e17e56ae9f37f9d6894a8bdd2a7dba1f367663824064732cacca5f1d48b9411b293fd2feb85d6402a8e3083ec7f6d3a255bf78791ecdde2ffb9f413d3a8afae3e328dfa4232401a15adc8fe1f27665c6d44448c7680d38089af4e329dec8f322406516438040544b201321cd244161925c5552ec426fbec302be0b87256c6fa701c038ea01c4ae92a24f337baae34ec7eb815cd3c5b37331d1d4c0cd80b4b95ebbc64dce4382fc440bf768ee3a6f93424e35a176265bfdd17a2c91e9ac95e7facfce76c67f50604d6c2d1ac011843933938c68623e64f4c7bfe31b43060eb9f1827e59a859c083d71394de6d490cc27e67e623e31ac1a7c59357f5d71e64f8ca7e28a8581016b3e7edcd7de3fbe4aa52a418b5f1564bf2b683a014cb9aa4e150bb26f1afc00e994eda09b6ae704edcd052b52472fc802b72c7b4c0af80bc97c623c55bb1a9209c9c47cfe05fcd5557e1d72e5aaf6dc571aa6c2bc803598ec249acc0293dc1c649659e04fcc2766722819eb42fcd97df60640c35c58ac624784f4b025f077a3c7487b1e3d2fb8e21f371f3c2e37f977d7477b1725cfceb9809df589b9264d6681b78041395ac05fad55a3f33ffcd5d5fcea0c0d7daf36d9692782b95e1fdc2a763fee0a0b3c3fe69ce92c67354a485d4d953c65e6cff99886a76aaaaedae43f5f6573993e3a55596d8a5ff323bbbfadd7a4c52c70bc3204a09d342c0bb8b63c550a42ceaf6f65575b93f3557bee29c0dff5982884fcdac5d5c7bffb036673f1e1aeb080e77f2199904cf68fabb8da21874cbbbbba027fce7ab7ab9855e5aea70559e88d0f837bd1e1a00280941c02e009e014036a9be78349523c2659472da6a00a9793e101b4820d41a09b60cbc0384bb461ffeb2c2b6559942c69237f78d209092367248d1492fb335b4f320bbc1d017f7225559954b5d758aea48f46d597914058def9ca78aa1aa93b32f5884cb616bb7690b90a97d528219d8a5f4390eb434f3ebd43da648938cb537748d31b2ad8a6b566f962ed9cb4d6979b4bf695fba4f6b712617f87cdf51daedc5be7bd5af7f1b89d54c997ea92ab4863fc33a2e10a6c69b962776fecf711935ad5b452553d4b89a1007f60aa63292e064510f2b1971cf695a3807cac2bc252ec06b7c407d0b75d8edac1d812614b94314745ff526e881de6f7eff0d941c676283d1f8f0c3fc2cf3c62ac40bb9cd496c1052e68c19c744a501581a494128431c612846d3481690fe4a33d7fd04713181067b26acf473a70c53fab467d239dec3f42c14968411264e4a089f963fe40428c4d8c0d15f307154a5042102c29b600cb38e78495521aad6dc24e312d66694cbfac6dc24e312d66b1c876a09ad5b7d4181d93994ebfd5da2cdbec9c73d65afd6edd201b6b2de80654d3de74b7989d72522e08f610cbead63eb6b9d82448ac6298c46cb69ca5b37239b4448e66ca05f19f99a775e3297cd36ae5e62277238fa82152a7512f9d0ad548223bd96b6411d9922f992377240eea23a530e05bcda36556c5852a1f7418737f4a7f031a05531246e5fb974993825c6b8010217f7048ee8e50b628f7cba03d788b90698f32462d5ca8f2bd88351cc6961efa1c44956c6f3a6d92ff69252f6ce4236f3b6db56fd3b15ac92b258f808c7e64d9e1fa1ac164f9242e4fcd6ed3e9485cb508e7b973c605995f6709e7922fe5c32ec3b0c75e70cd1ee3ec5f68e157ae16694fc2ec396b244bacabaebe54672b39925fa088bfe9348a2bc9e9036027c08c80bf9257c92bda681264f925399b0e49cd276170e0ca77d21a227691ab7595bcb04b6f912c3f73b527df63f01ca9b21cad6cc54ad290e597f85092024c93e5a6a3431283bf92d7a6d35cc90c8910feb32b794998ec05386a2a4dd59e34d29e7c4db5ed34aa24a7bd92571bb0f554cc5e7ea700c74da7e45562a453598b7c9be5eb6a792abefc8b0359b0977faf802c594b5e9d2cbfdabf5d6fe502c39bce6fac8ac455ff2371d59a1920cbc70a90e5dbea92f26aee0292935696af72c1ffacca5eab925f234b5a0990e57d77018e197a2afe777293e55f217f5b091ab2fc92176449c9f22bc9c9b264eb22cb3fa1812cfdf2ed0b30fcafe415e1caf4f6c69c40e3854c74928d7f8f421ffe7cd86da0b6724cc883c668822b1faa7c59ce16b8358246024377fa55a604387eebe02ccc39472e54f930980c3166054c844451c9f2b117ac437b2958d6023c572e3f1c5570650938e6e9aab900065c2e57026e4096a9045c912f3fc3d45c229ae4cb93fccd15a9bb6f3691e57f2439765f96610d96bf942c577045d6684f7e5cd996d4a13de97395e597dca7fce943fe644d9b4e95d0c89f42b29c4e64396166b29453c88cc9f2bda3aa519f0e59be9409c8f2a5153eb29442ea50e36162db20f083028d6468051b8a6419195ae10620b96e01ab0e6491f1ed61c34c4e0d5e30703181a3446e4cc67b6e3c25adc59844fa77956a33b1244bb2244bb2244bb2e43b0c64f13e5a8b3189f49f33e7370e6409c0c7199ef74f22cdd039436778de3f89e472b50c64c9e1e3c7176401c0c7181b63636c8c8db13196c6d8199ef7df82ad56cb4d0d59543e3e08204bcac755b6ca56d92a5b65ab6ce57dcdadf91b9005e563e9e35f1277f21e87c30780eb3e078e7b00709ff2e2afdd02a7c42c599eba534053bfb553b0e0142c38050b4ec19a22b7ccf1d4d5f1341a9a199a199a199a199a19ede5a6f6d4f6d6624c22fd7b1b8e6786e7fd934818b7acc59844faf73c333cef9f44b2166312e91f05e52144f9fbc203d32d3238933771304b554989aa4455a22a5195a84a5892255992255992e571779523733c32c72373b2d6cc9c99337366cecc99fe1ca66bbaa66bbaa66bbaa62bf703402585c6d0181a4363680c8da131b4455bb4455bb4d58f525775555775556b6a4dada935b5a6d6e030856db93a1ecfd5f15c1dcfd5f15c1dcfd5f15c9dacbb3ab545a3d168341a8d46a3d168328e33a1a12dda0b6b2feda5bdb4d77398ebb119ed355b3619ef9f31c3f3fe49248c6370260f83b33970a56564cb8603da70401b0e68c3016d38a00d07b4e164181b8e7dc159165ce93fe1bcc503e3b911fd0cef4938040367ccf0bc7f12096391c77a52ba20a42f719e1bed47a46f1277bd4d3a900a703ff6c129e0163f18c357bffa559ddc588e700ab845fc418e63c85d83afaf6022dbfc7d5419e250e22d55a400c32e7eb44ec936c5ee545aca647f29e3292fc56e7eed8a98d9d72f8276a5389f478b5f004a774cdf65472b479a241a90e507b8e2ef4f009802620c34bc30058458c8fe1f024e721e82022532842b2cc0a7f6a6cdf02f6c657f1f5cc66cad7e1f828019240399f00222fe419c2fbec88ea768058c92a69b623858a53df836091c7741eb5fbdfb7648d822ddd52927e2de2e63b703ab5c7b2795c0382aeeeed81530ed6467af00dbc3304529fb176659966559f637bcdd65037295bbcb91bde86fc689449f7d73d9c76d871b3f37f7b5bf1f1f5e60fcc3e88c802208ed61bc11b72bf9df8ff131de08ad2b7957fa21c6df172246775f0818afbdf6301e46e7f9be362eb7af15f0a7c6a46452322999944c2a0bd7784afb393d17e6bbcf7360505050b66ddb3c1e0f0a07db1b75b03dd0c3780d46af727d99dc977dd1dcb6ffc8cd2548fdee3eb9ca5ee4a5056e0b43bb306e82302ac8c516391fc6c0e0608bc6b9cbb123782bfd00e3b50f02c6f65a1784bbdcb43d7453f6b171f9dcd4c095f9981618c35e72ce7d5285ad01fb7bde43f21807facf0dcaefb0f984f4f33f368d4a99ffa9297dc97fa680364aef29d12787c4a17c7334bf40f9fe943fe13e5051505250b6dea6b6fdfdede72633e904a5f3d776ff3a0ae7af1729db5f99b27d69db82687fa23d49dbfe6edb8f466fc27d3cb2090ea606ecbf7df6d88fbe479f8d423f72c1db5b2af27c5108a4d9d47dd75ae3b436c5cb4396d5d7277a552355c7aebefaaaaffac2b4c03bdf7ddd570f37d96be5ee3aebbab12be0ef938369816981bb3bba0163ededed5d5ff2bf94f666f6dbd757a33c3fb3ee9339ed65d78812f8fb3c899099486eee8bdc7c9546f9cfa771237badbbd70ebe391af7b9dc4d7eb5c7048ed3e727a751471a95fd7cac6a54f7cfc7308d2acd9c3cf12acfcf38d89cfcb41cfff3ae73f1b7dd2918ca2139a27950d939e15e8fc110c69d1c5317aa7c285454f1426a51e18423af518d54bd00868a2aa488ed697d22111d1540dfd38242fe464a68795af06db401e77ce5d14d8f6adcd42eb8e23f62356a8e5ea3239dc27246363f5637232223d60867e41a1919c506ddb41af565ae21443a1019e22b7e28f903bde2078aa01764e907bdb29ad865355857d383fc75af112bce284234f9a380b2fc8d58a0970c9d0e25c3cfa24ad2bfd13573652e0cbaf1d4bd2ac7acfdac6084ee99dde7a5f3e0b869c41262e252018e10143b1232320264f11f1101da00d1c419ce0209812cfd209a3862815e70c5084cb4011a039c012a035ce9fc5598ba021b1526cef0876f214b165866598c93f31469cf3d38edc59b0f0d0baeeaaaae8fd10f200a8f6820cb4585465164528804f007c97f5e0e2991fd412f4f51c822df1f74a4415b4016fca198ec2035647f101aa08df98176b23fa80dd146f6fe02bde1a6a64310e5547c464f801e6e740357fcb351157106be029ab2f7772a3c67dd874282ece942f6c7530557fc3a15a39cec55c4d1147006e6464e802ba32110ae8c58d0fb464fc83e920234f99f6174c52bbb14208a0ae839bcaa8e99cb4dad6ae9815bb487a246d93f812cd9c317193e09b4311f86327c9468433e9499cb53d195b93c9e9b2094d442bf724156355aa8a7e52910cd671d44e3a9acc64db1a321d2de8d9b7c483480bfcb1115b2ffe8721fb002663555dc8ca6c8feaeec063a740f165b620bdc7688fdbdddedb5971c113b7056e3a90a593eeb2d7f023480bfc6b913e001a20057fca57fbcb13080289090f662200bbc4902f4fc3f1090fc815e1e2c3c57401b209b38c3dfe9fb7b70200bcc9e9dfc517d5e4037a01bd08d9b3c20266421fbfb8dec813f4fcb6fe2cbdba12401e54548a35048003d87c959f78d728a8c8cbc462c6e6433aab9b189364653c019fe3e7265d0cd88d5ca232a404ce0403e802bfef14b737a5a9e25a8e095fd3f1f1f9d9a2acf126c5aa097e7f3e0a8808b4c553040f2f779f1c8386281721af5817c0032d2a82884ec43f2073a32f20164e9f7ff401614189fa7252e5489bdf2ee9577bd6a2f09f893aa4ec57eaba3ca213b94305ddce83870c56da604864c98b830ed98744c5cb8cb50c950651934261d192a192a37e04cc75d1726772942ff20e4fbbd1d8f965a6592c0fe32d3796914fcce76aeca56147522f3e31129a535ceaff36f787ea206a1a71ce9efe6121aa2f3a7055724ab3d1912d21ea605a67fc39dd3e12ff757f62e472866d7e1e166da99b828b1fc462d70d6037f9f96fdaf54ab8dacd485bd48a66ff2930bd534ea0bd974a19af6e47c8cf4210e6651a926cb2742e64fab51ac46e1975f484896a19a3c7afc5fc826cb27b990eca59cf3a0feaa3fb23f39ccbdc3258fbf721f8f3c1afd95f4646e2ef8492e277fbb37179477f13cc679fe8a384aff435f34e783e88be87fa8c9ab51a22f89c0e7e90c3dc9cfeedbdebbd999bc72ccf77b69f7d19f386217b676f4ed7cfc0e083d2681f9f64b4f7f722626ef4f22cdb7ef5c09fbfafe240eebead79f4ffaeaa73420e6d0df68930e5405f64e87bf4ab3cb117a4c87bff20ce197db03463f1f96743b3c7f1ecaadeb2d02a2ffd05a27b53f3dd3087cf6eb7722ea74d257a344ef79d253d1fbcbc425facfc46552c4337aec6f243de53c6fc27d45c478fea254db75d0e42d177a94da791effec221033a9cbe1798c078f0924fd8da60f374afdd5aa1ca80a5ceba7037fca5b12a9cb411f1b3d461f2b2226f493fb4cba1d9e75282063ffe2afd4481cf661a449e957eba1ffe22d06029afce1a7dda7c35f373ad47d3c485ccc1e8c1bbd7332bfe0be1d37197f0a7e1397a7648b7c9397684341b1d906c9de6e4156df927571e3a1248fb05cd1e0d17f72d5a32711fdc72681b3bfa199d013f6e587a26894c9e3ffb43e1f9c6b1f23d15a6bfd6274ec27f6379c6482e1ff34d5a7f521c27d70647b26262556a364e8e3f1881e14496eced581f09331314b21edd904c99ee4fb6091e57f3c8ee326f9d6624c22fd773159ca973eb6fbdbcdf67573d9e4b7eb05f7db1d9cfda5a1195922d23271fd80b598b8dc243fad6ce2ca52537d5a9ed25ed3ba4f2b2b01eec7feb3404aae9897329eca5e8632ea4fbbcf7f88b427fdd3caf26f78a9e46ad117f59d46f51379914e8405c670390fea42f4e04295afd6af385d69aa1029a5e334ea16719cf6b0684fca5c88c25a2609d13967f6754e2a67fd7a7e46bb1d9d319afdcd7e6af3b5195fcaee8bb3931db6e1f09c7aacb29f5fb9cc5d2776d8cb18a3ac9f11397ecdf24f3f302ec7fd237294f93bf9c02af6179f7a6c587cb8f580bbafbfa65f77e2c7ee62d8534abb52fdf9451ee4c78f7fa2f16937b3ff4eab6cc341f2b1cb11ff3e966597fd7c4bbb2fd63933926cdb5cb48b550cfb18f3cdbaf818777ac1db7b6a7deaa957476e473a4269bb1d58ce41ff52ec765de9fef6f53f4772ffd71d5896ffedc0b4af1b0ef9393cddf674eb41cbf23def895f65fc4dfb93f69ecd459bf9468ee64b5f324c75ea116dc41c5f7b22b9bf6b8b3a9d9d5c0396ffb94efd78eae1b15dc777da538572442e706c092e2a158be5323383f112e20eb0d280e469d87e0d1d2c0d4bf2349cf26790d101cf5a7bb8b9ca5ab3239fbfd9e6f2a9f553b38a4928a862925a6bc52807e24830cc3e5d963de8a422792949de7e3bb08c9fa4abb83bf58833eacb0d077efaf7a43af5c052c2b4e7f207889331b03dece77ff20559e4d38ca52421b124724218dff368688df3ec63903e861c4fbd707063925f913f9cfdb3938fd32ad71e71463f3d9d5e4eaa46f538adeae6522907a50e3eade2266570ccc2a082d68c25e1302e6e3d60a0ecc34137f57073d6913428bad7ee8b39e64fdb360cf411f496e4ada72e09c903b24cd26d38489efe8d19db5c624e7b7e0473ae43dab87e8dc3ed79379f8c17ef26cb506513177146d474e24b9865c8c8062c4325e1165faaae53293cc6d53339aca84a027fd87a9a28fd50e503015b5e92a81d859fc4c41165dc70b4ed0d8763df7048bfe20ab9e1f8c09f1b0eea389de3c0154c0d37fa08c9a3db5b3069c7e82de8312ee3332c77d917ee9c5779ab1a0e9303a1c5ad8f38aef852d9158621c5bc8c3713136968e87839ff22b9304ecb62d2d75865bf01bddcc9598fa9515d3dd33087f68cc79919735a46976445d58cf1a882371f7cc11f5e4deef3554b74cee386db7f1b3e0e986157eacf111f7e77ddfdc46e779752ca39e70462524a29a51b10b4d65a6b05a2b6c8bf1f8ff11897ab677a262787c58a2a7803620263206c8bfc8bf57b774164e7dde1f0ae4b3ce4ae6d13384b01036edbd0daa29bc7a64df1e983aac0f36b4d576bae4b15e01a7ff9b5d5a8a63459569a28e85b4ff5d3c78e440b7d1a9ef21b5d67200b75cd6a836b4d7b354b018effd59a2b33857ea8f2c9569610c32f50d0afd1a89b3e404d7bb5ab2d6bd4f094b5d84931dadc248054d30790377d00e906a983a1bc694fbeac913530c3968daa2fe9cbb669937cafd901fe4859926aba261321edcf59251a7464026a74740fb636426f0fd4a4edff6a64e93f9f529b65ebb2c195fbb12db0e69af6ee3197909c7a9c54a797d36ace79eab173529d5edce793903829c465af651ffad34bb40173e8b46a54e8b3f713eba43af5d839f5d839a94e3dfc331f388774d99d7a48795af9ead4436e2eeeee5ebd76d8dd3d53028b76fce489f6fa84a6bd3ed9d9d9d9d9d9d9d9014923ed75dc644e7b6d5f270f77d6307d8a1c9fcc4c891dc772a60416913898435cf625dc27ca10268a09039a3051cc1f31324eccd0b084d8dc0c2192fb357c529d7ac0d32a639ca6c1f62e8a3e6dc2fab076f425d749e954be63ef73ce9393eed3213169d2992fc3fd31938e898b4bb992975cf6222e8326d19b76a20d984532548d127df69326df2b7be3e166bfae793725adf992ca2bff46977c66029cc37fe692ef8f328dca5a862a67dfd90f208dea926f13177146e69b4b0949094e4949abeb9b6881bf129216ce3d99f114b611391971db7f5bab64c64d9fff4e88c00f49eb84485c4598b8dabe85a901efd05ed26a6fcee91393b4daebc7dce9fb4f8c761b4e7b116e0efa8fa475e2aeed4b5a8d9a93a464c653f53bf4799256a3ee7f2744727fa56f29f6f462dd8643a43376058cffdb5ab0a37b825421baa5feaa848359c4b98b84fb261049d225ad09a451f3e58e4a4e1f1326b77f3346a65ffe379f9834330a3985e4d64c3a262ea20d98b36f19aa4c5f723247edb50e664b390d629014587e8661591744ed78b4c8f7060d017fb0d5de10f0e775c087207cf8609197bf7c98bda849d40b5786386c47348f394f5dd068b274176152b880a768b829f3927f5b4f95bc3f08eb5f040ee25384fd4f6783f8bce73d5d11d84d327b28ca9e8e869be4635ad090ef37e36e30400beccaf2a5ab3d295d9ff7fc8db69efa744640e16f44ffc7d31961dff3b4fff341f47fba2e08fbf4decd7130356077bfdb7d7ab3ee0687dd684f328046cabfe129d85dc3b51770d7592b9ddc129868657993e54bf8caf22b9df6c60e69540c42966f5b37f9b344b2c49eeaa7c91007296d136ea342d98db497e32e08138b5ca8d20373705be51b6dffdafa383e1813f8c35bfdfab3729f5cb980a280efcbf6e4e3b835dfbf5dc021f3dd8088d064a21b0ecf77c3d1855cbf5eabcdcdc5879724ea27e1f6314fec7cc0fe7e62ce1e7b0a641d745307dd44818add688c739c88a373dbc1a738e0cfe9ae2e649f39b8d90aa0ca672366052ced0b26b5e77f6336c053a588fdec8c988f7dd619014510f331ed8dc01eb6dc872d1eeddfb8b7767132dbddc89bee9bfc82b5f4f8162822146dbb6d77105e7207c189dcb6bb6549b6fc9643e08abf7c025cf16fc9f94316e9040ea664155dc82e0920a790fd3f938633bc4969cfdf4679236ff28da720a903b0511f97a505288512da935767b552e5df31f74a3f561ac4767573f13ab1ac45f05acfa45a0b2e54f99a067612629a860537ae443fb914808c1c4d9656afda00582c072c03407655ae8683b6759b87939ecf439618d22425c6243048402f40a194106429894a504a462723139209c98474323a41294129894a29a19417a017304860c4c031fef39c47b3d6a134d2e1a0e1a0725500900120072c8700d80078d53351938c2943005200273fadf4ca00340859e200b49501ac78e693b8c83415edbba5bba40ee93bb5d67e1add502a355c347020ac41236b51dc68a8490b3dcd4ae869ef5b043c7bb422b6fbae32dfd3bcf7ff5ee5d2a0d15eff0d47794fa965d9897468138d39024dd289d560426fcaf9708e40ce46c2a422925ea0e805514c794e447d29399eead52af74ab3dfab1c2c5d352425a54b7684767f6276b74bbac1ad0379c3799bf3a59c31464b8a258855be852bb6a373ce49ab945175e01544032f15fdb9b9d49f0f218bc59cc216c46968d33209f804a052b50e404caa9809b482f840ab052223133d5bd77dd126a6765f248269a78aa90d6bf07b188605f9bfe1a60e52a3868d7cbbb9ccb7180b0dfb91e87f35431b511567f47f13732cd95126b2a22ada88448033fa89e47e1b87e436025c69ef222b1382e3a4f3a3eb08c9a3ba8809777257c2d89ed80100aec81c289039e801a0a1934e300e7af23f15181fe0d9b92c2df0117a124a355ca8e21c14385aca2db6c80f40883f5207822ba10d64cfa009c48186a6997d0076b3a7cb60a711933223781170fc4b21842bf365cba822310087fcd8799c2fb91b936209a801b17c2b33d8c91dedb50e72a34103ab60c0a9cc8036b928e5839be4dbeed341cace3580bb41048c83013e78aa03f6b3b8a59032a081f6fa022aaeff1b0c6894fca98344270748599eece6b5d7ef65778a30d6a466ad8c9ba73be0d22f0cb707e4f9997e7b80a369d0888e233ac62d658ae3701c1f20600b0e9863b6458cf10a17aa7c1e04c3771717f217638cd65d1ee8d8312a206365526443c88490459105210342f603ad44a3653ee801cea07802f32024ca7610121109b574804b4624da0cce82e01873403a41d9200e70e684bc2934bb416683ac063238461acc007b1a0d510d086b54648081e01834a132850b1bd51de14ac4b94d7247b842caed477822fbf71186648faee506e56eaed4a5ee44b96a6eb5e678746c22dc24a690441692284316ae4ae749ed2886cdae7b491f38623fdc80882d1834f56318c949865663c2043b9ee11013e8384e36c1cb0a2e9e2041196ab27f94a16a6f9e810777736f96651986fdbddbdfc7b09a31ed62d87f300c377671b20e7b8cfb74dc7b7feb4c3b714614acec97a63dff0f7765dce4efb9b97eb96eb3ef011e59bbdcd586f04c3d6b7fa337ee3b225bed1a017f7e86afde64f7334016d81956ea57d3b4efbff7af898b38a33ec67da69d5cff865bf9b7e6761d03b63005512eca37ba023530722557a7d53ca94e2ff3b4c24eab0e5485547df56d76605906ff9398bf9f7a9c7aa8e1ee10bb004981e3c328db2de6a6bbe3c01e526098cb19a390538fd3cb49755a9d56f9c43aa94eabeef3447b4df399c9eebd7eb3d06d699aa6698f72432d9356eefbe13cbf8359cc6216b3285fa8c5559d175c9f7e5a6eea50ebfbb426c9778ba40bb5dcd49f9500875a19ffe6f9c6dde73b9e10ce7f3e9e2e149f08a9ddd6d7c2c142bea3126ae5f64e26ad4f532958f0d2c906c870c80a6cf28ddc875bb3b1638e218ac8fd300fe1b95164a8e017bb1d9d65a8a246e2f9eebefa58ff77dfed7b38af95adf62428201b1d8e8371d77936ed310e5405beddc72347b6434a7fb71dadb2bb92fec86090c12083814ac562cdcc6430c8c98931fa200536a29fbf8228f201321cc2c44ebeefb1ed6157862a4f3aa3b63d20db705813173238283b2fd25ef6d6f3d7b5eddeaa699a562189a6ddaff5bb2420ed6f48f4b213755f5fed6a577638cba7f333f9747e327ce408fd115972bdf1e059cbe65f19aa49b52e47877e66b283f6ca4fde2e47fdd0cbcf5e7659280b55793da008843a1d8ea33dfd8c87f9b287f9f2cabf9d9478c3210afd67eb418b1e8ffcec13d18cbe67c3313fc7edbeb8cd9d6cca176175d2acc9ac85aafd8c9bdb9370d9dfcf470e9b743c5c9dc9eea9d4d3dd9fdded240ac8a67639a616a586723f6e11d02ef7e9c85e663bf4e5a3dcff76c8acbd27eb4055601d8e932ff6f826cbfb39b4fb9aff76dfa463e1df59e79c53421317de8da7e24faf957fca961ca1005a0bdd87db1b10567b1e3a7f21b85b0f9e3f11645b0f327f23c0b61e66fe8ab046d4ad879abf23e8d683cd1f8ff937f3e4f07cd6611aa765e28b06eacc0f1261d65d5ca8f26930d9776832b4820d450890a1156ed8c9520998b2302e5736092cd60f6874305303191864b7314c64ff0b2d0c9c31c3f3fe2d0c74d8622d27413df07771703ce52d37f95b8b3189f4ef79ad8b936b2c8ca7ec5b50122d0b7345f6ef120f5de4d97d43c42efc463e8804f2e74f98e52a89d5845de4aff4809923dfe8d203648ed9f90d5cd160681a543e1360218c3dc8ffe20491007fa19becaa8c55590bd403c3c0c0c0c0c0c078703cf5b1166312e9dff33e309f1b5012d8fffbc064f71656796abec74d85a34895210e72da0007ac41014d26d5a0e00799d4de9433f041331c3283971c718632382283d71019e0e499e110194821f76b8d9a32b0c9240e073ae04a93db435d46c8721f62b0d6fffc0b193e949fa7546e0d80d2dde5da689e518b76461be59c3fedd7faf3dd25abcc982ce2aef6a4a6798e9cbb863842953b5bf9557e104c8b5d90ac73579db2fb76601c742d4659a9e4fca994f24443a551314b29e58901327a27b5ece14b4a2ce6e99434e5770bae60b2d669b5586b7d39e93b279f72a69d38e3863b9d4ead906288bbf4f834d549ba88e1caf2b11ece51ba7214601e99fe17729578981f6992667dd24b7bce915eb27cd28bbbbbbbbb090dcd98789c9342b9cab4e3912fe54a3cd04f712245d59ea4fe29292fed490c077f292f9e535e6868c64db27e29a774e44b51ad2af65f4a4a4c0a10d07f294e64a961918bda8b9f221fc7241f7a354a3eca47f2d8395c6bc53893871ba56edd293df538ad6ef8e4e8631cfe789c54f4b3cd8556131313933f99986011c47d318376e8a947c8d5271574eb033bad4214e227da0bd1b4275b44683729cd41bb104e17c2c2be2d09d95c4a35edc9984488a6c64df2718474003d4f7e042254220234c9a7984ecf7f5e6e2ea02860faa19290f64251b467d39e7c1a9a812bf2695762c1954932f92fe4ca3da9a46fc271219c50b4a4ceb60be1348a763bd42e84058eb5d8935a44c88fc9a7d52282932516593e863db6b960cea9fce3eefe913c7eff7c7660f9e4415893b6cf56da4625b4f340ac5d7602ac5525accb4ea052edc07a07b603db817d4adba864c33c1feca78a9e40aa3097ec04b876df0e8c7618696293f4b372740746318cf47912e9436fc2eda0994422612eaaec0452959d007f2050edc032e9bf1d1846e23e2a55b7dd70d01fc23f9f4fa8487bd2b504febc892b44c24955367179aa642dc6243771955c2157a808e53eadbab9e02e62acca9452da7d3bb04c09fc69652b5c72958a94725254292f29ab141faf2c4bae924e967446d147939749914fabe56a5467f99f9c4be26009f7292097bc8469d4a8fb621ebd74f76ebbb0886cdf39da39f796f3213c5b12077ab859d253192a9fb362dc7d3a9cd43ce89b744c3b32e80daf1c7d12f7b9d194beb6b950cb853ae7406fd231ed80404f7ad06f9b0b8864ad88fb62165113970e772226c0dfa7d51f57a3e6ab51b452221f2c1a55a45101aacfa8748dd476492d19d1080000003314002028140e098542b1683c228892343e14800c9aa04c76541b874912438819630c014200000000040084864902a888b26ab9efc9d34bf723edb5a6a1e6f2135e357e51f6e3854603eaaded01445cbc22c0f7d5c905b8504ec5db2de5b70b01bcf1ec7731ed6a57316f01562f5fd3d4f7dee7a045ae5ee98fdb5a1087455243d52fd898cc3e0d26117361e655c5c28f21f42052b76dc213c90453583091c82ab54494eaed41d048b2026a2010263c8ecd8b7b5d3b5a9945044b0a42d35de60ba3d08d42a23823156f8d3e854303e7b0d3f92f90e23f270d6f63f03627fe4de8840589998a4d5e0259932505f521373b6a499e8df06d5b2f88bfe1c6aede35506ca0a03d2a37690d2442532082babe9e45e6266b7bd106005df6b7f516e56d0dd224c00bfcb75e91a8cd229b31a0069106c8ecd10c940a86abe8eddc9d1743d1118bc142b97c0e20ee7498859e4ba8291e949ca3c20f995a599b473005bcc9beb6f17cd5e93d3f14bc6ff51551db8b3602e0b2bf2d5b2b6f338826015fe6bfe5ea246d16db00c0cafeb798b2c8c6e11a06f0a695fec41bc289423b2635a69b6f92685abfc841114e1ee6e2222c952e77933805e41a484eeabbf5960b6c2ed634c091dfb6b8a2a4cdc79804b0f2972daf92b25d54c30023f9baf5595da1124e3b2fed6637db9626baec318bfb849cb1c9dad62cef1d850fb6ffd877a94716899fee2a6bde851fde15403d7a029f58c5ad4db791fb3e0a47f7d0fd99b915387586d7fbd61a821e61a796fe2b0de75343cc9b232133560084e132567d09d28dc81020c2b8a62cfd16061394659c522c4c8c8ff970ccb11303198da95dccd448599bf9070a9834a22a102ae5240ff480cbf7acc8c683c2273f71ad2580f3743d8895c826c6618d1236e6e7f11682e45a5de2e8acbea07ae8144ea507f53ae838eebbd4e05fcdf887d145ac1de794fd868ca55f4ccd8cab6a2177b592feaa08afbaba8314c2a932da5c494114bdf4d3fa9b6e79bb4b4ed690fe065ed5bd9f28434a12c72dd803381d49a474dc2b6a68cba09e0e2fb6315d3c358eea7e2baaeab0f1ccad9ab8e9e91dfeb4e2d37045aae0a5748037a62a4c996c2136f0ace8f5bd787b44aacefbd79fc652765878410d305203c6221eb8602037b453736893ea3c8d9348ad572f1fedba7809107c6025ceaef1c1a8e1604a72259424471c20f15eda8ce01e4376cd12dc536d64cf048aa3d622aba020594972734b914c5b502fb0c8be56089764f5f4470a5437de7f4ce3ac1aab5d68e4f2e227c1bbe5bd78e422b0579070e84c62eb770ad9b86031423068550d4ac72478c1aa72bff479f3c27c1aeb688e788f988d0ed57eeb160bd37d620c030af51d00d8d4db9740fa3614819656fc12dd8d9070da4aed8443607d09f6059add7ba429af6b0efdcaf7329e42b502761250d5c128e668b5f84552516d8dc3adf5b518c9f5f894bbfbf6c5abd6cf366d85b9e1485813090da09b1301db8b842229cbe0e27240886eef14ded37f40e57c7cb0abdff332b78c949c6448ff638311c24737d6258d4bac1f21f864f39bf781c7c951a40bd6c96c734a5cb35acf05065188930c35f54d0518ba209eebb6c6a833cd7d8452ccdc3ccc2f598ad5e3377b3c8560224fdd5a29aec480aaaaea579e185b8d66b0531e983ace346e6967ca22351d18009564d6179743bc79bddf713598de0f44697b6920cecd26dd6bcac83caf84955fb5b4b9d0d11aa2924760d9c983ede4b01c3941ecf68e96f331c74317489431f297fdfcdfccfe6ecf3a7df5a09e30614efb67eec229850dfe7bb6ea6f7ad978809124ca60d70462ccd1ad84bd2c0a9e7f659560405005222248ddd343d31a3ecedcdf36577b371df645439ccae99ec25582ddfa842841d73628878170fe6b152321a6e7b247c9c927ea7072ba96a3a075570d06be1554b9f871981a52a58501533c83cf5f2df45ca0d18384b421042fda1a54fd864581647d3c8b2cafc3182deaeefa59ba1cffafab1406581903aaf3a7c536341486fcda660d03a5e1385b45bf600ab0958047c71b81898574f0d32c759b152f84cd50350ee7f4f51ecb1e10c20438c6ef47e1dbd1928c286a50e031e2b45d8e22c38fd932c1f20df2a12ba3477d27472d157da4dd1fd41760a2bcb7f22f9518006e3b00c0b9c24476c444d8445af3755b2501c683c74036189ce50afa535c5cd0a6510f4e99bb191820f1592579fe69eb7cb3a1f0d2e9cf87d6bf1a9bb2d9ef4dc9741adcd94001842485538fd1596e950963475233423141b8421246d270478a34010c8eed1853222d675fc084787190bef1261f3503d8f32a31ac0b88f901766f04d33f2bd1d79213bb3e0a164318262a6326e89779ecb365a0ff31009c829df0e8b626a2e2ec34c4ec39c8aec3b3471151ed5968a2d1226239528d915aae8cdc6890a5b9dae10cc0b8176ef6910a3c9ecb65197d185df7c616e3151840a28f210af4b0a57b86ee67e2a0284afe6084a088fdf4e692beeef7e42ec0b8ec5c8317cdfecf57cdc7f0e36ec37c630cd00f5283600b3ea301b3b0fc8e576759240e1420e92a482e0f2f42a932c170e2341b3f566bc73537833d090dfecd4b451ddb012b06991a77c9ab811ba5d387818f155f6bf86bf12c04d03341199efa4c47126b91c831a8b6a42e6a891b3084610f8658b89c3bb9d811bbe86a585184f4be1eebbbe04333e887b714b5096ae655b7a32af9bb4fa9aaff7101a25be4beafd7755162c55fff4ea44326a5e76b1495b34312f801e3b4d69bf0966cef032b22c611a5d1d2fe195f6795a4e48c2c6a98a3b8fda30783178e393fbbc2c5fd00c6078d3dd861f393e1e4b4214a2ff508ea3a8ab8010a32359462748695e33f56cda586f4844094990481e8bd5e009015294ea82f4cf812000aa9ff988a3c303ddd566563067df8e90aea47edb86dc310089782d0baa597119deaa0fc7443227e3451b87f1207833a227a1480b2e1982e15b411a587cf282de2c6ade34bdfa7cffb739ff1d80cbf67639c1537dc3227f63f61091175af8eb5f58ff08fe7ea00797c37b53ff1a9aee64cd0f4ee4e35fd551d4e7dd020f9e865c4854233577ad205e2f92c99ab849264a92bfdc5e6703eccaf4c2318b6bdf56fba61e36781372c12a4cf1bd67f88ec803c41507a1e073c3499e85bb52dca846adbb3136ea231a3d59ef697edc14145c8abe80f1d64281ae73e57a5f6ff93b42477bcce7de80a9b46d10b6148a3a56aa9bc70d38867c554c24af9a14467e4c922d76848d6799893c52351df2d5a54daa40104385a420539adf326ade58ea0fd168016199c21249d9f1de2f36d2d17a3a3fd978be27b3747db84b96815391e561448e78c8dab2845629a0f0d68cf9fb3365d82474f329a5fe69e692281317db2d25388ae5ecb08b346b4d283bb2a78e45d0cb8cd8b205e33e0419b0168ad888b193807a6aaf6b944245f283dd49555e7c757c210f9f9517373ef06fc8f35bb51f73bfdbdf322db65b53ec154aba317fe1c417ef6efc90cfc375d9ac8bc41af03f9ef89dc4ab829e16555fcef1dfddeeacd281b304454357586e885a49bad798b3aba24503f93beaaad79c39d7a741b1b3ae565560be07bfaf91b6aac58ca178366868e94874148c49298d262a682e0057c241af0252813c2f745e504be2fd64c80be78e2858c266c88b5c0a74daaf4d7c51e3b1c0a265ed2b647d7c1bb31362db87abbbb51e3c623f8ee9e8f371ac039e4263a373a7f5d09beddd8045fa60885bbd2474c9b50a3d8e06806f3c43391156f0079d586824f3dc9686762eff5e75edf29f85cdf2685587525fa5686c20a3e52dbb686c1051e14e26c97259aa57d40e16c2bc6d73944a52f862b0a389bd611a949b610e4230cd31fb5a0003e0a0de2d4b26c9a7e8f2acf288a53de72cc5cf5a65844e23d47bc797fef011b5769c629c1d17aa33ee0d4cb746b9bb8589734452cb5869aad567e944a1d6bdd4e8d7302923023498f5e359d054f19828004cd5afe852730a029c924e6d002882841f916d694071817774c868a82b472ad4684da8dcb39c858fff11c3ae6e1ceed5a9f8b66aeafa047ca03cbef7154e2daf708c7e1799865fcd6b8e4e0d9204a13d0ad839721c9775469a45a0b8bfa7f9a7a14a3592813ea82249c29348181531d60c0951960ccb5082eeb82d0ce432f1f8bcfe4aedc1d1a844c2caf647f71bc016d6070e9527bac7fd0106830527c5ab92248e220acb077990e2a1423779e98af875e2ce463c7b5944b9ff080a60e73756b637ac1954eb75eb5a40d4aa39f1464b4263e76eaa0d03dcd5b69dd3056a50a476361ea9d4948ca4c14dcd17d231b9f2eef5534885d811393710851970b4ebfa5266d376bf72ad6c2a6403b9c9771860ed6dc6eb2ec52052e5653611c9fb099a61cee3ff6d6c7f9f634a840bd123257bdb849ba883f9f2661b3b81587d4008abaf6ba657c9eb4b7b77e020a6f554dbacdcf6e043fe6c759970598e841098a3d6ce9ae4dcf4c64886224de07708a01f6cbb10d447bed3f610edd85088a172885610f4ba0e3998cf1618cc859a414e7851363f8e2a0f8dc8e28151ada1c7a006b72fb6d6f14fb624de01a922ca8403489281f8c9aa592371a1e413351804547b20db93a650022392e903126a9eaec70f434ef9d909718890ccdc017eb15449c4c6ba9826bcff0386443fa52b99748d576a1513ae43a56431a31d6d8a96e00da1332c8c45220433843e230610839bb2c399a8cf35db29cbf928f504089d14c52d4fe537344b2fe4bf770ee27633031ec727b0a4cdf8444b9f514bec848b8768b915d51e3e49a6a7a4577f602c171e10ff73eb7f58ed635321dffdc27b274c0223aaeed710a44ab534ad7828758e779989bbb852e3d70c7df9979790ceb584373075a55bac171b6650e370efcf62064ae03b339aad9ec62910c063d01c0ecb5066e061478f75516a9580709d2148f11efda547f7d239a142d225277f70ecc6707cc9f90bee13b404ddd056d57649f1e0163cab072fa53053a3b392c88881f81433796a11f9e899019faddfa085fb9c813dd524be8aa5212afa4de104effcefced3ee296fef58afacff577f06cf59f27080efa4083dd462c7dcbbe609f20a00378a788866702cd2621e7aeaa7f58306037fe51ee0c9b8bfe242b7fc1fc7e502ad8b118c08c81470268aeed17d835330a9f8a96c274e8efa33a396c3ee7ab2964a3d03ca4479e4d657f01ab505cf8d52ab2c27870f2034ffedfc60637bdf69e985e84322cde80ed7987546dde29dfc23af660480110fef28e721470a67b068fd43936f2c5fd3e6844f57e2c6f748775ced668ad10225a99678b0238bd427c10852f77735ba0d589d8f19e098f7bbafd11295f9ea12c411a4bb157db08f1021033e9e25f288b1e6ed3b83d00f9cae9fc29da08cf31dfe25659cac31b149f41cadcb0d266d38e06a369d5ab2e76b696901e746d63b5999b3b0fbfd348ebfac8a2009fdd63c8a007026cfbd39948ae65956a6b05774a20f37b47c1092c9d8f1ea0ce919d6fc38375b615fe9f9a562871d9072cf10c7b034f912035da534e02b8ecfcb92832fd01fa6383ee720dd537424f3483243a169c767c417e29223b623862f4e67851aa052fb31cae65d52d1d8157834ce22e6b317158618816721dca5b88315f3c41f2f987721f7ac73a85a0284ba4dc0308885e64c52451b4d3cefe2e7d2558c42ec5a7e23fada33398d881089e313aec6692ea44daa9424d8bf0f4393b035b7828f68444806d2b3c31013fdf17e6abe758f9ad4e21ce978f1a0ea9abb2756be16a185c27b37bf435e923f49a30ab38759267ffef8c639c02b90f02cffa365a309a64a371e36d6b36a9f0eb13e01c1213bf9ccab4fd8f429f2d7e099ff3af05bb48f805a8bd784fc13b20bdefcb9d2a2d0fcef977c77d95c7b90f5f0cb7926e4530fb921008e3ff421bd817d32fd75ebfeac9e0e41a790929562483a535193d0aad008bb4a8b29b1858243a1d245cfdcfdcef9fbe067a0f65c472cf2bdb6950eeff68786ab74e55e978d2837710932d2a3518dc41ccd8784cb4438fec079884af40aa1bd0f78d8e21113913b266b1ccc55ccd4f6438bc966ee49eb3a9d2c2e0593e552ca1b0f8a60333ca8bdefee00ae02d311df2ba8a10f94a1c7d2e50c3c08b346736ac1e630cfdc648c8a03de905362af2e108429b8f035aee0329518bb49127448f872a8a11cdf99ecc2a28a8c3427ac1c1af14dec376e9c0020555358621f4c6f1d2bf3cad146ccc90f3694ac12ca2942a0b66b3970acc489ef44a5023223b74bb4751ff5b5ea9b198808a0a0067014412d034ae924b8925f6357df94f9d559375627453f1295c36e4791e8cc32a48d7b2fd59a15493c67d207479403549678c3f5a900c42cd828675d24bf5e523f96fe5b586187c6a741e168ebe11af7a207d434bbcc0265ae82c665286baf0943dea1ac9cb6238c0b3ef21b204b4056070622d0fe9d736c6047d8a8ab11170dd7c1ed9311fe47102e754d2dfb629aa8a807115d0e347504f5f14bc1d5586fe1c5fc66bf7eeb3788967a347169d781158b02e0432517e38bc00c72b89cbce77044523f12c6bf122d68bb6f164e2e74efa0aacd963b85523c946ef11d26d389870de913be1b05cb27055918081f72c255be50a86d34e7ab6745d9c85d292bab33d0302544f2884a9327fa00654b6425862987c4d4ff0e382dd55e9ab50571676422673f21b3e3cba0e01ec6e5cab0554d322c0caab27f3222838758564af5ff31b221b61be0ba6062326b7dffa7f67701644073e275c0a254782796c093c419e94d079d2a78761758c8cb3deab7b4e401dae8f14fae42530f3c4c706596e664bb533e33ee2630dbcbda671a874f8ab590bdd5fa50804aa499295abce8ef580259f8deef8807c1aa5ff5eeb063fcbdc594f40a9e7db7a2790a4ddbba4a7c560f09f52ef14a491d1d070b3779be0addc95190ae268fe6317f1ae42bb9f67b568ba7b2b99de46303905df1560e9c3d71f19e0a310ebc052d52827388e54a970577c6db9b0f7c1de0fc1e6a018dd7001e31e8572dab9188df5d2d8c7387bb37a0d249af4396470dc486e2340e0c8b1bbfdfd035384d80fffc7f0d12f9b3f01c4393eb4ea50940a5f75269bd4bf2313f39f333ab347cc20092bd83842c5c961e0a5977eba0887c0ec4cc72313970d46c0fc7c37d752e4e50f847a5b8eceeecd97d7ec9444054a3da094dffcb840826b4582493296472f1ab316a7ac6cd0ba2371475fbe82b166d33a85f81b0c0037c943c2cd8a9cb47d8b71111f8a2d57713163fe67808b0e297bdc3e212baf088b1fad94eb65e20290442f9158a495257837372cdfa7a24b50de46015c569da6a9ad9c8048a137980f52c9b0bebe013363db30c9f729aee22dd7628bc920656a6189fd7ef718d01872a419cf20d0a3245df9a351a718a94c109b76259fb5de70fa5675b592030e2b403f9b26886c47d0bc26d604ccf95f8b60dd0a5daf910d812293ae0fb7c24b7a0010e595646d306a12707c329e8e60101e27354650a9325116785090c5793fb43d04ac8d8bac9d9c90d6fba52ee0ab60b2b0a882251845b66ef9874239cc8418decdf103515d28f81c7b2062255cb7337be4ea2ca2b6e2bc4f0a355ff3ad0971037cc0ee9ed0c211ea89aa336b98dbab0b56b10fbb37ac932ebd121a2b560e55060555e01b17413bcb48b3f11122527f2605dcb1f17f5375033b45e8ef657ce1f538bbbb8a997f8d0f7a73233e1efe45e4e27b0ccbc1487980730243218ee65a7be1998efb8998881373e2398bbe388cbfdbbc0f25b84ab6b2f42ff56a45575c79a0315aceb86efe909ae607c1fbc1fcc29e1aa46a08aee4f292c6d3f3d46fbac4bd0f878de872c175fbeec699889ce28d5f6bcd05695d80e21bceea4e4dcadc814e4a40d298fa2a5480086f93561bb8224a630d619fea14e682080ec4e682e0f8fda916f53315221a73edd2498ede2f1b580b0b2cebc6302f5ba98335008600940185ba669490fb1df80043f8172bc7d421f016f189510cf30c2dd16196a600a94ee5e0a3328081dd3235a16eb525bcd5590be13d14d4ba0eaae4a064c30eb30a083517f02a93c6bedce5c8626e6cefbb4a05016cab33804223ea4580d70d97de9632f95dc57f0262dd079fb9fcbbb44d5663112eb3bb0022b4b30bb0618d5743e2ae0d97b2d3f5234932e48a0a5dc14fe5fe1eaaab4aa9662419bd075f26218a0b9e761e7b4a927164fe547a7dde90fa52d29099d62b1c7389b2ff9bb725aaca053f0b6091cf43a5f024c3307d8c6b8fd1167dbfc9c6447a805ed1c4f436f186a8aeebe404da63a7b63bc9186656069843817aa336854c3c375fc0e1225a5d3124fc11e7f1a246c4be101e13c5ab916cb3d812e90bc4a2cfc6facdbe20540fd69a10ad5b54e006ea5692db2f24ca1c4f8bda7557421415dd6cf5f710c0b2fc1f8bcb99e3535d7a6270807d3db99aa0543e7f5bdb6f8c0476a640cf25e4d1c3fb19c710e94d49ae78629e34bd00a939ea26d9e444e2685f6f6f5914637434d1456c2f408716f2724c07273462daf2561913dcbfd8ce38fcd544397cc06bf8fc965964e5809652b150d7ad917984c6dabc65ba753948eb9e5417d8151538944e274ddb9e739b2a8805459a90d0192448a69e34cda81c577e0a4c58fd1075d97a04975586551db2c59be04022fc791bf681252c860b0d2f5c51de90dcb45f11088086ad8f94ab5e84d7ff163aeffa659729ca605279069bea51b675d91f4467c3329a473159b8287318bb39946166e28c0b0e4e9cc8c96a0c9862f79f6049f0b98ea609c6a0990f67886e67f3c2d9fdd27840dfbce16bf36b4d3191be9b217b56b30762351f693c85124d2c5c02bf4ca0a7f8d95c8e2fb5b6a62b5d6bf1b9a29dfbdf62c0265bd84acae4554c1dfbf7ea4f1c8170628af81643fb059f12c4071b9c64e949aca8ce0172e3ba66cf2dbd1a157da41a3537d09d0937cba9425787708f2a7bdbc7e340da477b56163a49894803b0a608122bd9d7331f374cf13a796706a16016cb5e5802e35ecfd11bcabc5fde5529da3ff35d901cd950aa521c8af8910c71259b329dc61fd79b4a4da2ad5dd546b3d1c9cf49b143d6ed8e0e9acd204981395cb88c03f3b2ce9c288373b242f437db46d3cc64a1ea73a9f6b9c4a5062cfc8f0950e35f9d64de5f82af1688d690cd56d9f82dc303820bfde3653364e41748a8f14f89087ee03466905a435d1aef3946975098dbe1fafdb0d52cece2a6d6bf8fa0e443b15069946cc60b26390459e79374e0d8ae9329f52db5c34dc9b26f20d490b29935403e6a1847ec98533617041920757244cb04e01ad8011c4efb2181d22c1f59ca6084c3784d8e3abce58052d10985207c4e35f78ea974e3383157c50deca2ad6fc1613ae7f0bc0e7ee8eb4e57d58a91f87b1849c8dac65ad667593f8c16d0312b8681926b6d7d6dc5a38bfaa4541f947a6d91dcc99a19a79861fe1d365b0f2dbb33e528455092864165a81f767cf50037a9a32fe77aa711991f0cf05c7f876ea6689b69a1fbdb4a12200dc13f378047de87e3091b198ec7c6a1df92be98b77bd4514f6f99d69f3990b0a777334e4bec3a550bdf58d9620cf6b749c324f7366f70afd94a95fd999610752c24605e86c6d01bb3807ebec318804f0b23ec7019289736c2727f260c6690f49f9f35aafe23d78cf0b872a4f96a1bd37782e01fe38fe88bc4fbec04c43fc667358492a1371acee2c6bd9a4e0bdf7d5b8ae12f351f92a09245b672ef363f0ac7e0e0f67409f683e3401d3066052fe24ba9ce93058beebfaf78c5b097ada0054ce99d61498e4fb90c7b9641a36e9f1b12a212ccd9e0f3de104056b3e9674b366acf037502314afdfadf24aeb465f707c0e85006ca33f3d4060d395b07feb2fdd24020a8a847c985e4d3f8543bcfddfb7dbefeb13417e63e3686bcba08924c8f8ed2048924b430e561357099bd3af8f7226e36619949d59168d13e083a9315cd5c04dc78a55356c86a60452004c388059a1804f291ce2cd7ec8d040b853c8425c72e4050b9ad6273da585281ec160fca2b7d53a096a4ba40ff5e751877d1727f8b0c59419d575c26d95d60af8075875e16e8c24e58178c90565e995a3106ba648c5a208b07afc1f149cd06e0a90dd8c90d0c8acc8095a3ee3db9efe11b0c4403bc502ee6d9e66225cc5357bfc16ecb83c91594de40530bcc758ea52e4f5bcbc69c113eec200d622b965643a61f004887726fde1978ff808bbae8823e70bea628d0fd4309089d74490b2aa2b31ba5168c41c7734c2640986723bf0fa3f7832d733afcf66dc8f42d78881bb3a16344662cc30eff1c081d27db8db58780f96fd1333a8276780a4ea025703a60d2ca9af3dc42ffd198808f2081a77becabad046c09e27b03c7514fea496369ab928e9d0ed4bc501dd200cdc333bcad74b709afb83e56bfba50c1aff9979ea616e09393f079178e24875505eb54a47054195942d6e1a92f7543f400b638327b38ccd225935206d57287e78ee8546e3e656e9ea086013e3ea4c8c8ca9853a5adb0069cc13159b84455a37cd93593d9b16107d22c8427ce65b418a30cbcbd48e33b3e3ba2dff033b9a3a6a4c9362d2b532af84207b28a8e41977f350ff113e37c27cdfa57e64251d133077bb493ed9daa2ebe998000d213764c8d4352a42e367ad46f407a0c23007d5826eebe4470f506c5ebb18c34d7f510d32601f7d49076b85d7d3536dea3391b761cafe9af0acd13b8429a22f56ff6b772b5b35450fe8f0e193fa47268bbbe11d7c4c594d07398af51c1ca915999ccab9daf9bdd36d8a2964f4a4d77167dafc897e165c699a7cee27a85e5921bf2ce4d0d54632999535dbc7db27e0305e1f7ecd32536f72c6a69134a7e4947bb3819894f216cb209508531b790876b334fa86251cbc27e602770e711679b18a26ea5869f2fafb5b5e505dc9c69db67d286c4a1e446af78eef98dddd5883a940c84b64887ed8fc54b3fc5cbd8073d7472b2d9a79aceab7af9bdfdb2519afaa1dfcc2fa9ed94a7d74b50aa190537b82026f02ef2b9fb18ee1eb302a8627b9e78e0851173e36f23692504ff3e7409ff9ae53624cc9d42a8fb7fbaade25a4770b7c9040901ab399bae4a35a6757c37c871853b4701b14c5f34cd69c24cb7db103d02fff11eae842f73dc19df719f41ad1e61a0894d9b9d0a9ed0ec32a8a43f910ca194cb5e9b7a74560922bae153827e18353c575375626baaf0401bb179aaf46c3af61adf1cac32a5ce1b52ffd0f59b40598473d9a5dbe30253b56f483e7afd41c2ad5a566ff16696be600d62313cef4e08c16dcda0c1087299517b4e403f66d28b3324b8ca8ab1f49d19b5bef1f7316fc4b37307f0583d3e8911239c2aa45e18da90ce3d5bba5942528f36643841f9cc057a9353b9b4217fd922d890ac4755e6a1da77c21dd8b8a64582f0478a86c28d67b2157d691cd4b71499cd3aa0d0903d40a25e3759a9893664f6897db0aaf5078e7ccafd23e827174535963dd26163a65fcc90769e58682040fe928d0bf9c497b43569fb89d80f03285d0180c6564322a369ee9c88bd55567327eeee32d7f163e3b220d19e856a24d79f14fbb14faf3ad3b4ee43060f734a860e7d6531b87e2010d7c3f06a375be6efb7d9d26346ce975489ed1a323b01794b000d3971d261ee6f6e95ffa65667b23f0f632288206c7be59f8004bb284be7980e63cb19060db96b5127b59b8d23e3c226047925955c74c038a443aa737b43c6952580a990ae26eb4420695e6c4f4716d281cbab622b5d0d1a121a6dd5f3a021b37b407b68c304edecf2c1c027976b2154d5d6d820ae6819b19af06ac599178ae25e05d05af4ec49650fb4aa9a8ad3eaec6a760b54d61234632a39e804d25383df0e1287f3a021e3550aef409238c03ccae04e40ce5dba89a8350bc6c9bd713bb2144af607f4b17aafa85f06171bad74ff80863c66f068c49cfc6f952de4e955be59868d21763b1c4b4f428619b21539954d388c8ab693a08b41ebd05eda9d9669cf1f5d1833a4fba58928d62c142890d57d77114ce138f3bbac6555bcbffc49f392d92c897ebb1f3fa131cd35ffaa232378914d89954bff9f3096ef0edab6e1b74fc3e678877c2d80d146adb449219600d044e02e25331b80622e310a711ac7024e5b8e4077e11036944efa76e5b54f809b578de28b9f413b99f69b6a7ad64bb4163ed086085611534c725c0be8c1377904d8c35cd80abaaff74e73cffc4d5f14c0521b360375e4724f6ff01e8b5d9cb580cf9c48445f4b2da22265a3b899c89c1a6ba94850b313ddea7410e3c3c94b2ec4f511abf58f5a699d6782b9b39cd2243a68c4d19487444cef12ac3cd1433cc46f4e0d01038d6a0670a3334cfee5281c6af543ed5d78e1674b1eaf073a7a65cad2939df6f1fb812eac0513746b9ea35459d6b19bd172f680cf86a385b9d9534ce01343987bf6945fa2cd2326f93932ad992cb0d380a9ff98a29ea6203a7db29ea7ec1a0a7a990cf055fe4839ef75185280d4691ac9a5ad28bdd23e15421f2f30404c46f89cf887bcf14aae3fcae1406569bd19144034d7712a9eb2eaa5d844fbdc58a23a90414c18c219a210200885a04ad966d5beacfbc2280b4f0225d650f03b02c2abdc273209d6d183b7373e2b4024e9708d7abc0cf32ab6791571a433fb8e50f524e0f29e51af201a7370794708d41d8a080b48a447ee08d7ed78673ffacbe2925107b1916ab74937dc0f1cf4f945b4caa94207256c21a2ffb0fc87157d43488dc393dbbe320ead1960c4a8d0b2784e892472b254bbf078e278eea6a031e20556fe615321ba268bd59bfbeb0c8011f8f61d31a22f58c81d566f063f41daccf409a814a6a7d6fcd597423d22f2710710e8128faff568b4e44d24398948bd8142d1c25e83e2d97a43522b914939c6711635544417929e0296bc5fa8529c569a76562d2af2ea212591937f8955aa7846774841762017c7e93076573cc210cc598920caabc1e3cc2d20318c7ed52c59b213980cf9716ace8ae28b5b290a270b83a0523edb5324d4f1ff4eafbd20c1d02ead83d80fa27c1184f330501e8eb6e60715ac16bf2ace4180d9bdc4fd38beba370960ddb9e1b174324a723fb08d3b92987ef3e479269dd97257ae50cc76b780c4ac528d7a4a301254003590e3b7b7304a2631a582010322ff74caa2f484576017217767048c9aed2a8806ea4f2bf2bb343989a5cdc7915a15678f188b699e1448bce5eeccdb471f461c7a64cfd1d762b3fc0e0a2a4465a0636bd5bcdc9dd5b7b99b3c7464464e221b918dbbb38bfe7ccc76207fbc2e93ca3dba40befc76ac0b99ace242c6c2ff914de27d1facb59da70d4d4313075b590daef329a0e1138d50d70fdeb56061ab15b2b5441f40d79b7bcba8e01f1c4c216fe6e27cb2c3f9e1924b8111817a2631fd202bb18227b6434142561e0fd46cbd4d8c29c871c78e4020229f8509aaa0726559b9b71aa9836deefa1261d48367ba1d43b4aee375a7179a7118dbb29520d3076583288d1a8a0d845869980421d4766bdcc9e07fdbfcee49175912d0089162ccc4426a8508358ac4b3db85405f2fbc88b0390e3eb5dad18638b7fb889ab451ce2f36c0526ab166a5c87b77512f4281b7b2eda06b3274e9ddee79eafd122d25d0069195a810c32903d37ad9420c281be4b489c8110997009aaa5b04453406099575349f8a31326ea608efa60c6f2611d1a23137a279ee01777136f1250609ba4fa60fa431be9bf86a2d5d517a6c5a1f1e094482861d257c0d9cdeb8a89ba785ad8198072c3b8c74746dd94d203e83e70decd2fccc66904c6d2e421e6533d01643f01ae78a6136136f9b21b259c52b1549d50d7eb34bc5a96551a1738420f9f2c337c574207cb66cb271b0b6bf4e42b18ae907e25a1a3545eb57f44f14290f853be812b14fe51739004437876a1c81f1dd2b29b22cedd2187fae870b7b92134490a829dbe0ff2a5c564c949372592a089640917157d8363044b098a888974cbd095d6ef7068b7792f7a6089b64e51683dbbb11b89fc645b21d24af18e00a18211ecb4bca7d17df76db2ba45aff38245a8583deb65aafcf07189f27eae6adcdc8b8daaf3b8d7495bc6e35b69314a76c65e261cd0b73b092b49b3a999f710cabce4aed6f13fedd1858862b81e0d7d7fe3eb47bfd9a3bd43233e1219605af45e3416e9e7546802f6e5c822dc0fa1785412150b1bea64bf3a0181d35a6375185e45ee3f9c2943fdbac5b311d8c9ccb1efb11f9532caaa54a31b9cb159255894ad8b179914888803eb23b4f438e127902f5ae15c15c7b9c357efc5665a182b452641630df82745d068e2c4edcb37b30b6aa8bf36a5285023c8461c1003144c4a366ef6abcb85ebb26e78ed545a4217a6906d9f94e9a5b3def770950be23d4cc1fe39603a5fecec9c917d630d2bd65c2e0b9a6fcfdec444ef59bb6974fadbcbd0640c63e6455ff971f1302432b9c45165f84310f2a4e0e3152e84b8749befeec31ff0c6d887ac3c99345992427e3af5e2dc0f8bbd099c63e768cb30f1d6dcb76ab0dc219cae387595a803504fa86e99b6ddaa4cb40c7a7e835005de5dcd169ac9f195134d4f6c2abc25c7775486550429b895333cbc0c2acef64db533afcb9dbf5a6e8b0f468edf0aa8831330dcefbd34ce10c3fe93854590913db8910cc9b8ae7e4b6d969ca1de391695c19f24957d229c3e077e8adcae77f116079a821d28f2a2e001790397d0e4631e5b6b6c23ab79356071713406b03a00e9c3ea8c9a9f3aae9871480bc70560d212f43bbe3133e51ddee9a1f288bc933d6fa703cc0522297dcd75630e492422596790ca8d2dbba92d6728232cc9dd907daf329663f20165c3c1bc3292ac86670e01fcfc22c5d22830127ea694d2d4be6a4285ae7b3ece0dab7524c94f569372a9b90350099622427ef161d3e6ab15229581be1aecf2624732b6f34e1584886abae127cb8aa9603bac768bed22eb2486ba87fb80a0247c23c6c28c67eb8307c4d570a23857657acd120ee8f76f001f77f4431df812e7e01529a5977b439b4ff70c740ed0d8bf07ef4af427a027953401a7ed6d3a0017b97d504d740426308527703fee5a82e6da4709c778bf1a8ad708ed03eb57f300ec433a3c7a2fe2222073f35234eb9b92b08c9f2b8da438a5174730b0d5d161e3e274afba983fa7baef2810ae5aa62c64c7895502480f7166a0b229aa1080b822c0c85d22be7a8e1b853c0e31ed32d5f2188b58b8bb91688af1b0c079a00fa1a3b9526572da013d9e85270d5a6915b56ee3699a7b4d55c9206edb8791747200e1cea80b51f21f933ddfbc97def127ae5a9c12a28739bbf80e8078339be751537eb1388eddef9493fae476ae604aa3238ede4aa4598f809975651d12a17caf74d348daa38fe3eade103caa8926312a3eaacae30aac62b57a7c88baae971a3666bd5c25f26f9ab5146e3af9229127f15f124fcd5b15dc15f9dc9945e91ef575709545ddbd07ac2a809a7bff7636a573673276a00bae25065e5aa1b3c7af94608d7901d1b2f6a3a3f27bcd3e5ac24f98ea295edf73401138fe9b98e228f0f7d503ffd6c646e0e851027292d5935384daea04e3b972ffd2531c31b44ce28401d410af0e235be6544f7938f834ef1c3a9a3c10b39f6571e9b9bfb38eb9d3e89f0181446826559c91a2cf168d59c18a3926eb75f8d2967e6c59d164b7df78d53e5348a79f72d38fc002caa6e63bb3d65a1c15205ce1d12b2a3e0deeb7c2988da583a074b05013aded003864e1ff4e2bb1070b341436d5fc53a40c5809be5936a367121226218cf6c6764dc6aa0e57a12fec1bb812f7faeab96a0e8d3b60b437912a025a31a759a5d8fb02e5383779febd383ad946dccc6cf63e34b1d9b29dd188dd9a8a1a04012838f6b860ef4422ff47e1d9176073676231ad9786bd465cdbf64d111f2cfc2d2faf43021605b72f5edfdd45180faf7ba964128a99eaa5fd6aa4c34661e2dbb1f9c29b038f74fdda1881c5a57f89453e26402ec180b86bac1c660e9d2fbe7aa239213a18bd1ce68172bc4e9d2099229b62b4ef7744cbcbf45f7d9d0d6b30f5e8f13af29e49398b6e9db65cbdb80551296bdcdb66c1b67cf83ad6fe7578a5871b1dda1f03108dd60f610596755d68b7c1999e22e02f629048c5b8d20fdec1930bc80582f369ff282bf8cadd9568726da5dba14a102883ee8b299a6347f69760b7d6e7ec893f31a3d43a0175365c260db2677c39ddace4ea1e6313138d58b52cfa06a7445b15bd2846eb9ae3aa63bebb058dc3b4508787a428c0166d0c8f5b4e39452c368b98ae0ca638acdfa35242e061efa7cbf058558bcf983ab8aa0bf681e43c291208fd66335cd2fe44d5bc96a1a48df6dfd8814f16447bdbebda5356cf813730287ef0e4d7d71aedff1bbd90c27ac90560583e890af5da40a5aee6cf7a92b930296c5ee46d43b902007d73a18e021104e4eb893a64f8c61e511c029d5df8834d1beec8256cfa0f59561c5b39a09e1590a6463f0cc9a24dc16231b6d4b72edb3b7b58caf73870c6453d412d2fa2b79f3a5b14469eed4d05a2b972c41a9f190ab0d9804f077f8fcaf93997e6ab020c04be7d7750e4d2dcabd08db6000f810b9d0546e926ba9a7ec03cc6f410a9315e8e87ffedc37e50959630bc17e957ae78cf5580e2b50453500a610df22257f82a730b9e092755548c0fb12a4dc2d16c35b0e1069e5bff3c958c8f488642a37c4e0ec043b98bc2705af87d058de4204385710dceae18d8744a3c3d1b8d16307a9c1708cc5a062ece1b8c386951bccd2199f235057a34d38bd85f8eedc289da183cab0b0514aa84b8924e54cca0b96c6d038fe4d4b02c9e31cffd3b0342546cf7b6d09ccc2a4c5a4ae495e3acbc8b722b448224fd5a64ae7650f3db694aee0916794f385df26ed8c04f038334766a703e20373f2276bbb4dadbb520d9bcf68ef398ee062c6893968480dc455d45c69624275c1fe50d485ca6d0357a2a9097344d2fcaf2de14a3fbf7217cd588c3fecd7bbd0f771356fea4a431b90882b97bfe1817ce3836c17af2b8129b36544774c130ec3c84f15eaa5298b03c764274abb97a281b3915c9fcd7662c219596fc8d3659e38c656097e999aa3eca628fce0fccbdb59c9084e6d6f86a35a1bf5103be7242cebb87299f0254c12322b47b74e817957afd46c1e50874aa570e6c76f47fe787800a09eff3e8b4b7f56ff634f9ba9de0a8798855324e763ba7cdb051baaec4442ac2099c8f36f7ba7707e6e17778955421fa6688bebadc42793a0b2e4ac02f5b6f365ad7a34474ff9bad665d838735d6a2448cd0f6dc40824497c998685bf38fd7e2962794202e8fb794d5a0c8f79e02e6a0a2cdd706ac37f7a0e797947523f23499cc80fc0e71c371d80042955ee1b9f2047cd7af69d44345774bd7c0d693c838b0f899c7e50747a0b29a14900da91b09a7d431e691fa5a5273567ab1226774a09382bdaf2f15348d36fdd38d4e17d75dd89f6c7287b3de5df807b8fda2edf408eb2b716168f05612a09352db5fd15ca9cadc90a37ad38bc9042a331f0ee4de3d43869035a9d2ee66016557c8c221300e8b913c08776e661f98af236568c745eb6a8050268dfee2d124724eff63a071c60bf378ef7024fb54b4543138b2654e178effab3bae4b188cce01cb5b4f2331b8e3e697c3aa6521a0683bc70b33b1685fdf84e679894eec9b3fd450c62c1dc0560dcfb2e0e5027141ad1ba2584b7d95567e0e6cfd8b454d097f1bfd63b1789f2121d981e338e975622961eea474682896cf010a0a584c4cf66192c37ee3c667ca18bb38c7b909ed7c07689d2a1577f43c23d42ee8b12818421943730fbd9edd234261ec9aae0e41ae2c5fdcfc5b5a0cae37d8cd6bb46408df3756884468aed7059dd3cca5d8195cc56a00901555eca96562b2ea5390e1f578baeb8cafc06373166b90fc1fd2bf7bd97deaab1f2742fabb9f039d6ea4572d8577c7aa4bb9632f1a4ca68dfa1ace30a015fadfc69104cf289b4da4ed3a58a7a3c3172ba73fcdfd6c6c60d01a3c1f093219fee9cf8b5b43f874aa72a485b62e44e0908dcd8beee845c37e31265be3a09afd0620d2621c2c78aa8f1903d1660dedb37bd6a84efc91d2e51dcf3954d31b961f3f204a8fe5e9c564b9b417d215a458a0ec496d714d0267a521c67f79344c8f3f4da26fc429f0a10bf32627adc467706e173dccc01a67f043670d5a4e9fa42b9bf53fc22d92a59512d1ae9badf891e08c401077316d2676947ec6c40a48f0a6638485e00d2c2d630a748aa253cb5a3bf965500eb3e423b48da05f8f6be52e99134e1a5193b2003536055448c4e053a10b911acc9243c6750411ee095c66c400c7d547dabcb418395a219e600ce2008993133606a46e8580e8cabb7b43c649acfe7418d7ea7b2ead224dfcbedae4f8d77f0aa0d9a4b8fcb60fad924edb1e5e8d68422b63833228aba72ca8f46ee180807c65e163063f6f16b18ea5223ca6ab3e3e2313033d4d047dc6f0ec51c634971863921b3969acf99e5164f363c26fc057e3350806b105a4133004f29fd66dba18f0a8665610d8028b2be583655b2f343a1c4d6623b397588548d40f87eb4cefd6d9567c2c1e1196b994af6522985b51247e4e58b3f80334230b1b234fb160b2845fe786dc54fa28034acc1139650cde932ce6e32004631d06917c95abdd6496529564585b31d0560226474009f96c625d85dcc5b551c0cb397e4332e69ae4faf76f2b25dac300bb46180050a97c9826e16a1abd9322d368b96bf54d3aed0bbc2440c866f7b86066b630cf35fcfba657a69489eea2d3a2bd10499e017ca5d426bfda7bc16846306c657604ea7cfa0ce0c83c7a5c6533f95821030e94984190b019f5b502826e1ae5428f50bbd324a9337dfc8ee8002564d810e0e3dcd89fb66ab3e5c23012b95cd42dfacea0a1ac1641ce14ea8c3c6f229011362614e1667603011c3a0de7a9ed665681017699a4e180dbec59e35736e3daa93e33c38c65c2efa086cd9ab284d29ed1e1c09f5fa08e5bd90efab856535c9c40a4cd979331e9c5a34ce6570e447c3c4a09f4bd2a133c2eaee88225bc0bbd7af8f2d4dd5ba8864542d7532452f52c5ea721246580619dd56bc0d8e9a3f21891d61cd7fc7453736f92e08cae8d0a9277c01e05e8f4da831478c5144819ecd0d225028b60a932c0812fb41de5e3376699507d8bb68c5332fa3376048db008156050c9990e2c7bc8014de04a84de8b6418716fcb053ef3d33147ac7041c737dc42e4a95d4a32ddbbe982882f51dc59139a6e9f6d49038cf00249e0fadb45061cc3cab341ba2fcf1ff9e68a3dab6edd9c005c11b393860efd206b9fb7c7ef4431a7f52615bebced4e61f40d22cc7d292661cd0640a9833f19d701020ca7c9b8e47178688b735dc8b0f837096e0fc0078f508cd833c4d7409668188857f9f50efcbd084b0eb86717ed99017819049ecb57a12cb9610820c0b85084ea380756c77a13b0cd41355e632a639a2a77276b250c3ab1f023a363e7b7eba11d19afe0f436c8fcc1f149111f77a9fb5533d57fb32bcca6f5967c7b33123409afd84a78678027b5a00da9ded76e04582ffc1e297942200b751769d8db0d95e2ef4b1997356309664dec9a9c62ece9ccc0bc86fbb7a5606bc24a2491f62ab218ef99ed3016b8aa053596253ce26eec46a5d08024806bb4f9c9f0ce218911aeee9ad512545d2d5b45d0946a18774b54d11cd6c88ad61e3565bfd2ea67d0440badf37fc96c6dff521bf5459eefa1a18a14cc266c00b41685ba97f0bb84f70995d68dd863cd70b45cc862528568d08c7bf3613ccb6c3c9e4b1efaaa5a0b7a3ab0d644d58db643c8c30056ae3b9e9bad5d4134a4c8e72bbcc0dd9de142b65e0e5e2d2413f9954574c46527eb1f18508e2e9fc97559f9a50de34d76f9aea0fb8c429eea868d939013b3bbed742d7e986b1ae9ead9b8e3339d8d2c72719138a9eca084f37c27924574040b2fefbf3605d6e83cf236d485addcb5cc0c438ab11cb3fa14391e64cc478ac50a10645710e624fe1c1a87e4f6e38d373b2b12f2de3c3c259617656e3d88ee841254bd7a13e8c8ba221c68a832e38e7bbbdeebaa254ada09b230c16c0d16d69696300a6cc65d08450199ed2888c35348c5f44d2060fdd31f26ed3492fc4f5ecaa3968900fc8c4b5d143033ce6b6a0bd3e633c5cec06c040784e48a2c60c09e83755c651b5d449ddd24ac556ba7425f71e4b97725b8bc383574daa49ba0e2d3843db1f19b721bd7470a5ad50c43d75c5915a3a9afacc846225933b9ed51995956f706257bf66ada40ffaec3743e24c2b8362563cdef3b2b0a06c2194ce5f450ed6342d840504b77a0c8db2543b6f8a7b5aea94334e74b38af4796c1f314cff007830ffd5430f21d9b6b09c3571aac329712cce6ff37d2549e38f2846c48510ed953b51ad436d643e8e4b7caba37d7ad05620c83bcfe189b2dd9193e70768598baee3ac7dcd11c5c823086054a28e5953122524439eb56d914e31e755c946fdc0a9c18e52ca8d9d2c9553aa0ed2b8da2bd37b0456b6cb8410b522123996a9ac660d74367ee4f0414c34ccf2274e5344d12ff63c0a2825d87a2b1d45743311797e66c8df20449478c79ffa02a7d61eeeb6255b81b1af6292f5a7e11a94254157ac9054660529fe828af7eb07e4755c5f10fdac7a8dca19619f4cc57a3b3f33d66e9fa2c5a994251abcfbdf2885a0ddc2a33057d90a5810852615c033ee50806b060b3191b9dccda2c2937490345a9093c94a142cc1932e7143053e2ca8559a98453dd2b4950e318b9ec8d9fcac81d50e3f60355203edf601b4d3bd7064c68a50f462a10cf3454e23ce69dc4cc9171a558484c45e0a3d331d3693462984e10404876db807889fc50c03cd5cb02eff49d9c124142434df0c245f8921c11197db8991b1f856957f81314241c621b8838e5a63ff756144bf5a37690ba2a65c827a987772cae00b9a58c88700895399fcc4d6a0e008d6001307566b95b9409f1b38729305a4b4333180c3835064c0184a04be71b03847e8a0cca476ac44706f7b22b50c25b7844972b667d9205f59d2cd32f24eda9a2f3e18b9641b445ca6515a10cf1fe1769931bf2f949d910973b7c2cf08a98c621a0ba11aff63962efba031d98b2d824bec792eeb0a6231665ef7fef579ae8c660094f867e7c4b03679cb54350e6a70449097491d18d301f48c88ba49110ca9a990fc8880f5bcb4bf6ad52d4d454d40ea653a4f546a430635ba820a4d5f1216b48ecddfc4e14788850469c3dae4c165a687e8890a8ecc9d9b4d94ab69535fd5c50f9d45e8d6af8f3c44aec8db784554c1671a1999d7cfaaae25a1457b30d3c5e29c62930189b20714034c30e17ac79b9cfa1b8998e9bf02e000ae68386cdc399f3f0cf7684f68b538ddb615272fdcdebd3c1b525408dd0debab19cefa39a40416a9540605cb163752e11fbb5c4f9b3079dedd8e6167ddcbf250d419a0be4896762d36e08fca83ded22c908704ab082bd7f54e1aa65e7aa5087f3b3146ca4095ee5739fca11f8da17da1c8329c9b870056df38b940252715679280013111c6754e23670197979503879518ccc76034c0e5f49ad256e3c0b18442714b63a3e476c906aa2fde4d02a18657bb8c8e64d93181a39a3930ce71bb61c928a41340160d1f0ddc527b166e493ba5277882dce480ad790b54742b2de4d493c0a5227ffa6809e86cb860da8a68bc5d0a2645bab35a57973f9b51852977f55b64733c28d88459b706d1aaa50aee66126ae0b90098132930bb3eee3479b79bb00ad16500770095f371973d268b89f9f9bd1720f95a336ef71fa88fb3e6e5a8d4bc9698904dd5a0fc482d874282b10f7557d40da26f86506074248cd7baa2a65ab954bb286381c0d811d84f02d32cf1505d3c54961c529334276a33f8ed34b01c6a2d7b27349cb087af753a73cdd8be70927e64e3f445283a822957a1490bc46380c363e2e5932f071d4ee4372edf535fbe64c364a4b99de31f8ff88653b31536136d0af15733ffe462f8c61b2292d1a5dd75812f188c9926dab01ef12882a9a1bbdf0b8871488e9ea391081b045c41686216eea40c1675d09a7c228ce501a1134e230bdac21e9b8c898580799b41ead3480ec54a3878f7833612e33ed0cf6941618616838510ae96f4bee10cf98e5c8332c3fe5d11d3d8ce472a250ecc23de7a732405f5a20a52d9ce8da83ce8505b52e13002a80b3401393e124cd9850a7db9624455dc2f13030ae1dafd513bc7d8d5fba730bc4b2b961fc6621f0f37b85b9e9c54ee2cf431a694d00c0a32a4a3ee7f405e6a66f972978ea3548f9b8c65c7aab890658f3c165279d03f80ec6d6995e318030dd9c0c3ec304a62a6fb16cf893aefc1a88a49f4dc1e398398e62df630e4c264bd2dc6e1736f1cf8b1830769d5f108b00f30f8354cff293b2b9ac5de3faa52a454d2bfa659d0b27122807f21d59e7153a4e61e64582f4c7c0efd21a4483a17bc44b3c0e0baf1fa8063642819d3ea1e89385b5eabbf327378ce32885a54e8cae539d8efcf797e3e372f67fbf9ce3d106d3e42d8e1610aff8d05470e5a8b53db88ea00737a27adb290cf5962c9909ffe1f29c25665ea55188faa4424cd6ade4c372b77e33a0eacec6d0adc934e6c26f1a5398b5700f3112199589d004e1f02c83da5b4c5a275ad9ed0785cdbd74e1c68a2213a756523e6cd14acaa06a2ca16ce4deb2402017d7fd244af980640354d8640515718d6d44b0301ed7705e92de34fd948e1fb1a64c8a247d99f4d48d94fa039ad5971e94a7c518ce7a3c49aa09458d47be7fd05ddb720d5ddccd8d11777a73397adf62e9637a2048e518ca38cd16450fda553ab85043503c2434d2985e343114d19fbcc60fe549659a0f6be730d578d8f1a70c8892b85b837b2a0af3efa18b2128c771c437e8be76d89e0420eb2a39dfe8f65056b6bf4be0eb73e891458f3bf6582056bf33d2e11b34bf5e1b59a81bf94615651cf37947d1653effbc93e969feb588ddb7950971833c27f4e46590639130208def54a13b3d5b2c90af5bfabc9867313ef235ca431793abf224f62643d8baf613dfef1b77c18705d2cf08cb8aff53d062b1ee2dfe6019327e462f5f5f82d117013dd7f06ea39ab43ac661eb636e01fe8c6e76ed05f78baaa3abf81cccbf2f6ad045b61bf0fff5c8ca9050a61456b85e0063fdca2ae740852851d41be60b1552a087c416136ccaadfcb822fdebc35f758682bdeb6782290b9bdb66356c41d7e376d0caddb1c02eb1bc062a375cc580f861a901e2c008b4bfc94da4e07e0f6018d05a2a13ee23657062a5ae5142ad80f2ad2f60fbcc9ed9064c27e603dfd95cf472e86c54572058f5959810ffa6f0f11cc8d5cedc7bfb0ac7f33a894880bd8cf71c3684004c25548434a5b048f2064e690aa6fd9b33db9c3e1db1f2ca666ba0f0f09111164c0e2ea3fbf96ab67a9ec85681088402acfdd24226b5a6513f80bdbe46ae3769725d717d709ccbd79c8d3fc574e49dcf655b5bc22423c11e43d96179bd4c92b71c3d73d0b4863c50158d6e32cb8c9a98f0ff6dde7a4d1b5bb74b3796f3ab40634fc689b0670e1704da724e841dbffe24ced8e0ea8a5b7b37b0018db1d3f62ccaf5cf85f15509cdbd2eb3d4ecf427f0d248d0e3d55e7841fe4468a2a861fd8d670b7aad02bddba313c751ac1f711c3f36ecfa95585df2976fac1d1a4152374a26d16ee926ee4bf44ccf79cd419749e46612f95d26b37ce16274983bb2445f3d05dacb2e55b31f15ca2adfa8780c330ecb1eaccc86f9097d48757cf8fc1e74d57c71fd3339bc7a3498fa0c8d860d790421116c8fe23741de99dd6adfa13d8080e6a80ef989d206da324814b1bce0f2a832a839091a8e28a863c9aed42c61dea24aecf24f629e5953afe941bb63898631d2917caeed6b602ca0cc72c940d5e5f5985d699d183bc699f0bcd47e95be9a9aaed60666ee7aded001a1cedc89ac8bd832a7fa88f1175ec9f5426658c53fb83ca683f1d2dd072f50aac4bd02e36e01be754cce1c35b82b188c801f27ce8b084b5d1cc3ea0c2721349e8048903bd002e55d5c14e5aa30d12b77334c6296aebc961fc9ba5aee191df2d0bc1f6762435ceacd3ba8ac97f008a311793dc340127501298095e8d491cdd3e5b16a6bde1cef59f10c08e6a1659bfc20eff5576ac220cca6b1adaa6b308b8d896f1f444ba352913c1fca946444c0497602bed783c7896797fadb77dbe63f3fc79c73389e6d151c28aacf333607eff31653a45d80fc4b01d237284d9feffd5c6c2d9f52af13d8a946df770cafd0bbf357f442001f0032e26650d800ca172a81597c1d6ffdcfeb3a8ac0c4928fa59919015aac567e84ff9a09affba2d03aad57af86b30a885e6de48a115d94dcb6e3772f51af80022f2570459023f41b680b4bc2bfbd75cc2ef72b7582cbf30ce292b18f1c0d0a986a38f0a4545d4a1ce1c51c855b6b0abbd517a1b84845ca93432f828d5579c7253fe8194c6f5125cc265b6bf686055ec69b652dc21ace691e21c6c0b609a81573f5e80916cce7e33fd6ef2cc84c7edb5b1a3cecc3875b201a4118f644798fc77a820ad121e8b86c233b3b36c33664854537f860333556e53af7dd6187626df8e79cf9c92eeb1e812ba8483cf4ea7b303cfd6c3de93372d43b0b68ae917539f71bfa2000bf317addbb07fe4358f8bd671ad67c4c88e8afb0f6e8904da54610647629d99772ffd3e1a54a0828ec59cb8a8e03818c326199b3434f87e1e0b220e9cfeca3ecea7db7f7f52834659cb70a996f05e59b36251f4987eb7d9d0b8337337d4f1aebe4e24584eef7a7194863e897a12fb75497cdf9700ed982fd6890009140d9812c339721c3119a12ca871c4d75ce907a20b71ef7f908a67108d338dc8abb92205fe56809bd848aa91fa0d4683cae4b486eff0a71a77271a94b4cbea5067872e914cbc30df47ca94bcbc634b317f457126ec8992416ebd05d690a20ccc7ae69e30f05f4c50158a59b62fd8f1135ac97a5aa2c649b6e44031149b240c0200becf2fc24072891ccdb3cbd028ff77ab8b25b39c5c4ce03f9c9558ce7be94f66c96ca6366362463c9159c3464ff9ae2cb340dadde2e69054cdacc7a2107c9787ea8566567c519b2bda9d6e0b38c35a84cf34cd2c15bc35d6e4f2ecf8545df0f1132807626675049e42358a2bb8f8ce20e36c22bc99451124493c5b22efae7bb27033c4c19703de65535cbb94d67ac1c98df5cd5860d8cb9dea926266201a926585651a2550ef61aa1942e1229761590f6ed1d512579c2152981cb370f83870358e29ed8a929c30c1db300702c4be41b5a4c312f2c409ec3022bf340579a6d106fd391945c31fff9e2eb9c16dfca2ad1a0824769a5243d3bb0bd2745703effa8468bd18cdbfdc7fadd29611de5d9a23f8e9834eb19ba6c9986eac9d2e9bdad24cac74d368d2cad8c1ec2ed460185a5d685a8213c1ca1ed60986c7c71c32dce09cb33003a67aaa8adadd271acb0e4f36def85cbb0c9fd981c1cc7d71bcd4c6070f8ab3d43d82cb2c7f249eef7234078bbb50a6c7d1ead2e132cb8a809df6253746b9d4e53bd6d67e3afd9c871dde09c419afac1bb2c56e5cc905f35250705b5c60ff643c07ecc7bb200b5247713840bff430fd9f0f8a514b07d222e1a6779a611ab3b6f903fc37fcd976ff1744324eb92dee86f500a0258052c09117b20c3d17033a303212e0ba408a0ae64d051c60a4ff0347d2ec34f482d2d640d3e53d02a0b083da623116190a11e74ee6b33e8ea03d7781417c79a1ab33a1513177a26ffb9a29c2ca7fb7c2c7a268f3e6631b7295b34bbf4bc2c8ff3c9c388ebb6f7e2e90861ee0c7d9762f20d3ae3267ed450043a93e008fd4871917dd31e318b0e1a7389f3a0aadef41eabb3c8e8fdea9068174b8b1db4eece536d1279d29e0554830cf0237bc615bf24cfabde1f63637fe73268e711ca22db92c05c69299416a3aab455b8289216ab9a5702c5d4753d5e42c65499dcc0f94baa4673af1f976d2fe9a981594f0c54289339eb6073c8acd825f90f0026179eb9d2e87e5eb873c1b22fb48d60bc412623aad5420c14bfc777d2c575d67442865212249cdeee479a27c94a177829a02be159909f9396d815eb89636d403710336be30ca3ae98c8c70c81f61925941c67ad6bcc8f45915a642825838a909e2b2079c1287007573f4e10edfdca9218103630cc652be3918c81e5485864d892e68bfa43253737a18bf80d841d434f22d0f9ccfee00995893a27521b7631fb7927fbee078d2d379323882cb7f0413ca71414e58f44fee1d9263a8fff21501cf39256d2e334eb134155d319ea4c62384ed70c80e2b5fb5c3ce3825329a50413149f098634d0ef7b9d4e1f0a8fa6340ddf2208b73836d7e1083c988850d837e3f6d07215cfa92609783fbac9af58f4901295c0531ad7484cc1185666244d5e74b00ac8a9e531b5b464c4a63bafc59d200a2608aed01750ce909a686112f064df11728c8800d5e8a04f4f1b1b2713deffc9b9c2cdc750f105b561127b275dcbdd43e9d28b846e2d425046519db3bfda6fce3d8a63e4ae372b09ef55588b8745a38df39d29ac3b2250f9ea227bbd063f5c83b7e598a29d1b5ddce3b3f99ff27667c03bc18fb87357ea3f1dd1ec4226e68947b50824d256b9cee73a52807f8c49c1e7130295a415fc07d3260d8f904e8a3a766f6a0680bee233fbb76a6d67ce202ea7fa6776f39bc94d8314144b72111e5e6a19af97748098c099263c03412573a8e4436607297714f07e91edacada66eb418afec0b425f4c8be864ffa16579527eeb5accf39176402fb3a301f95f86279ee699adf5a39ff9af596ccfe00184038f7d40c6133c656ecbe2afa8b7de8a3a53bf2c6931bbd103ca134e4599f496e70deea4ccb73bb677ec62e07c42c42d7652e09b60035fb966252538702277b8d9ad5926ab0d411b4b75c00de7a977a239c96147d04f6284bb8c2f5418942d6d7d172c879e63501fe0a0ae8bb4e2273a0ddedab9e5c56097650548a854c43eb8d581cc95b18952b53ec7c302adf14b86c7b6e218b1e9642d4d4db5fd2c71d861548b99654bc47a0d36f342d381854f45aa54a8b21913aeebced2bc3b6f401238e98651c2ff0d8ac305aa16b2eec9f7450e8e80c826165e9939f2f7497d6ea0b9c1fba6cc2814a8bed139c7de222f9cfc69531989ef7283320bbc0e1184cdee61b3e44d177b574787179834793f5494a11b3deb6de7d1a85e67eb163d43ed67780b9848e14f7f4d22479ea244b5edfce56d94468dff6f724341c3511124881b90102a5b6ddf40d24785f34439b4673a75a35b39a311840ecde8372b0607d878f5b9a04913a6c56402b9adaab505e9ada39a6d2590b0d9e3b3e0c99daa8516728a8cc56d63a53df0e761b9f73697d8e4767752b554faa0ed39c8b259b62db8b8ab17d858e1baf2335ed9b628125c8061947dc98b365705ff09f31678461e7524f7c2d754ca6b154bbef0eeb06e8938e7a8696406688ed4d4ba4e95668bdca8edcbe024f91248a99049dc60f8f3ee5845f025c546f642c7e3149a5314479b78c523848ef28fbba20ab31b0a1463740aa572c7136565e88cebe02efffb7bcc07d7001583c2147ed6279ae0cf5c9c07185ff3ec13e2968a340820576eb06518cd1b95e97cc42f7c76df709dc915b5c701b7d14f923b810da605cafacc030ebc57c91871bb58baefbe585664802977bc3bd728cfbd12808af63f6b54fa22a394cf82b90d0d2a6c3839c6fbfdf96ff65f44495524a88067c42aa83a3d4a8b22669e76216a367e1a783bc3e27b1a76353815c7a3b79ae375c9c256a5f638e604aaea5e523f00904b10aa3f08a8db85f2458010ae7dca799cc62c8c2ff2a28d642d3b8aa264aca9d60e66638039b4d148f9e1aa55ec2175168f8750435ca82e25fe4aa368c063a80fb64781f0b8290d801cee47833bd8687eeb281b3e1cadf0dcb408ac4e7d5417ea585266d54a8c154fd3a757001412cce3b41e30b50f3be805a6a4ef7b7beef928fdc1d57b70e5386da46ae0566755986f5205445025762dc9316e61ff27e6218e977c5a002f2eb5f3257375036628a5a5d19fcf985018962da0a58f3959d2cd5fdb86a9c76d464d49fe2f89eab751118a001efcae3ee993173b0a9c4e1ab1fdf1f94db2aeda80987d991297661e0764306ca18631baad78ba258bafd22ef8c9da6223f33509b3faa183defe70196d0a63213a82c857504acaab4f583434aa255b48f170e439128bde71659c1038e06cf0d007d187c35eb946306c6e01a23124f4b13c3c244c7fe22b549a32056c8138dc1da91566cdb16edec4e89b5312752784440b4ac284f1acd469ded2683d1cc24fc15ad8907da477c8d513fec8496255d15e57144320b81141e4e100189da88c404695fe274ce3d59a44bce268241d44609cc0a944375fa430f01d7d82184a1bf4ebfbd1c8558448a983eaadded4309e3af0ad1aa8a1d697ba40c8dce535de8d74045632bb490719709e170d56d4a8f228a3bf6cf86d53394a04b32bf14c3e6fd6dfc37b2358549ca5950da6a5df24977eed92d633a8a65d8dd9b7b9349e9249077ac9b9d89cf948b66229680057d6a733eb81a79b003e29b4473d4b6d41440fb3cdadeb1ec6dd094bfd40ff79d124dc44d9d2de8850e71dd0a71186e034feeada24f18cb971ebbee6bb86571b182fce7477949d99d4c13f213234104eac89a417e151f8c76701b230b188c5edf3ba6655684ed602fd48688a6ad2911257ddf0a11f4c7a0ed8d7c6cea17d90bfc8db2484724c4e1d3270306de007fd7ff4150bb8566c9fb0d8a339acc97872d6214f1f1bdc430a690691a5d37c0c3ad6175e58908a3f5157a63ef3a00561fbe65209d77c22c86251b63d8ccfc22056bf779e791475653fc00a23cd869ccdbd09017b506a30269d3c45747054fab1b533d5a2405d067dd638486a393d016c0215a0c92b95ee0b5f922be1bfbe1c690a4874f1768848c2834c678fe601bd2c404103fb2d16e517106b24f6f68632ed048a3759d96cb9b5e69f430c4f8d3b8c470b8fce6d89ee359597751afeef9691d873337013905bfb817799346cd79f965b1331ba442ec7725dec09fa79ebcec5dd8b3ecbf86b45173de2e2309af105e61e65c46fefd786e509dbb8e1324b2f2a52b3c81db0b90bb99cec43d7fa14cc346bd5e86791eca286b06606788e5b419f865bdbc003034adcef57ddcc1ebc9e60d785f9e11932dd31ab5f12e7755686bccdceae40f361b192ae4d8a6236329d81ccf08da6c6b576077bb46b18fe7a4e9881dc399db9b067b5f0c352b88b1b18d72375cc7109b1b94e39e534cdb9ffb339d169e8525d089fe24b4ab029f5c8dc6389f7365d8b62bc9a151af2f8624cb49f867347237ec4524ba61b0d4b1b8137e562ba26010c6579a2a6b6d43423374ddc194cb4c4f4417a6629997f939d278cf8b50a70e2ec7ce6611a5a02343b97b20a9e9f95265a11e143206e2b340286086466214a33d3696c905708de1258572ee8c963be41c0ffdd466f487346d70f96dc04c697507f94582953acf757c39c0ad091ade992c928e7af5a04b082226aa94132ddf408f46ce409a89d6222f80f0b992f1a325760971d0d34ba021db74e93e0364311dc8362cf481dea11bb94df28c6040657460ed12414c0ab2b1c4005bb29d50561597edf508f68528d0194f626ba0abac23e8ff4c99be9b5e04830b492f90fbc1f30c23658310ee0631dcf3246391001c080802a2fb90b5ec746aba896b5cacb0877c54cf4eba181820d7a462b75d14069f95ec2073a099168e6c65d3ce45a401e18fe2b297e012a2f570fc9129201f5c60c0764429a9e70fcb5c221c284b78418848e507a13d496613d0fb92a01b1139a87d7000e32f811e63191892275e9db88da31819064740eacf92dc43384b7faf4100e915b60a10274e53525b481343a32a067308a768c8403a24af6236a20b0f714abd5d429d4015cddcde4968adbe03bbd83b24bcac6c1bb84da0ca644a524c1a2c8bf84f6348f6c1b4b8aab3fc090e2cbc19af28c4c910cc957a355fcde16d1fc69adae3f80b3ee27110d7b8f92ee5d57c3f0474d196e4c741a900d978e534fffeaa0148c7e161d861c01267e16f8f8db4668123c1037111db83796ca099bd5c23b6b1b259e728bb45732094084c6e9c39c215698a5ae9d0024f951b2269bbe51535caf0a5a494586d1ec355c39b5e1a6effaf4674fdcb7033f192c02c7be92c76fccd64907150149d392282aca03ee7e18e9aeb2e2a9316f060091336dbfa9732c0938bb60283176bb0443718588cebca75a01018f2ef8f5fe3bad6e0ef1e615d2c54351cfd0e381cb5bee126eafb28b17cec9fd4df71715f78e773cb76659cf7e36f932b2248c39400d03e4597497b4f5fcba8e6465d62ef98bef954a83ac455642dfd2483f849a87e027bd9a0c4499922671f849fcd9965ab26c4e7f91ce0343f1644132fdef6045aedc8788f4a4b86beb12b6fcb226b28631d62ed5b2282a91b28746bdde53fde46404ff7e0d16b10b229eb76e87629a163cce61c79431f6c6125418a31ce8868128899c3ca11a10c3a95d3f626b2ecd9b84656389d99297523ba3a6e3b88e131f62183bb3863c8a6c9613e4e57d15e37e5ef895cfa375a25adb3d2aa9e267f1f108afaeb8bd1181e5dd24ba4cbca85e08640819cbbf80f22b6b0c137683a91baec130c9389e3b70c6196564e6cb6cc220499146566703ca33f02f57e88a0daba4a277396248227caae66578a4c661ab1f076e15750511677a87322f41a130c1488a9771ed842724fd7bb6a7ea88b28fe505b6f9b541d2cf1e1d15df840caaab1ef90e439c86feffac4ab56e1706d4694b02aa9409c8a53a55585e3036429e5162f36894b6456b01c60fb5ac14a3e643dba7f87836db198908c0520d830e044c476bd2a7220d4845d969e029b79844c627b19f19e796ad119615bef1199ca4ad208af303ab0e0a1c3fd6e32af02dd1ea31f70cd9119c50a68d9dfae3ccdbe5cef25965731d88e3cf8c27252a6b0306762f44b3e246d9390991879f9e86aca76e2d6149643e19a7bd2132929e664064e78fcd3289b0a9c9d7bccab51f650439e314773f8bd39a4f1675c170616689b1db98301f60426f538d3931808c7055d573f42cb629cc10a7e1efeb5e27c368bcf85f569e1c226577660faf9950fc67d7670a8669118b0e58049667da96aaeec1a4f45d1831b8c2b573376f7b9c188ebcff5ca36b68cb8e1ab9a923cb22c8daf7ce9e9b72ab75c858d1e8855ba56653775b996cda185f913ab528ad34f79d48f4868ae1e5f3bb7a64e4944731675e1955473fcaa64c9955cf2085ec9ea09bc38a6da4f5682851f4ced52119ad55493a7b1ea4158f81d2310987eeb7b7768e341f70f11e8c76ab466b4f217ec8a2e3425a804566abeb4a50a457f6a7901b8763fc2b7a9985b4276339a69c368cd28cbe60317935c8d08d0050c78d786bea8a5f693de8a6ee45c3112348de1fd844384a5923e5d592d07314253b4168903b5a12ab54fa2c5632ad55df15a25186b3d22a4a071a34ad9a2f9886aa5faea2c1b13fda45bc428ccdb6175204a4d560fc82db6c951914c8c0dc1a6f067182cbe81279c746076832a6da4125625ddd3da6d08dc5f5b8cd55f21b9ee0027740e24c6378ab55a98fff96b845106eb6309c752a82fc14db61735249154d8ffdbd838151bcdfbab51680331f70368c579610359dc10817dd0ba1ffd1ea0b47511a511c530aade67b5b975e17acc4861f382633e86b66e441826b0f9535fadd2461a5bd04744e415be7d4fbf6484b6287b3b3f0b0e7b759bec86256cdcfac27f0e3f0c8c99f271154bfc9f7f30bb99c5b4ab84a689a1bb736ca68357d1efb45debb6ab472ddf70f8a58552689dbbc606a21174bb0ec333d3ba37c5293a0a180841822e7a02ee42a6fe37950b4a6812808dced75fb03a4316b4aa1662c76b9bc7ebc58f73c5e8971bfda96fc4517ad3e70431ad456894d8169fa13216f68063b07aa60f7fdd00ae57ed1eaeb761a3d66e14dab22b0ec84740b3e6be9c9fd8585ab7a046ba7d701fc1b8b962d9826d9788edd3f1e6c66e0b010428bc769d5f44ec9635c4ec3e50a7709560f650b98232646f26f8b071e2c2e5d6d0f211fc3dbae680f098ad31ecfda8c9af63a7fac56286b683cf063f393218e16c43439307a72d0e8ef1c4c1554928fafc17808c0df085e36b1395ca993d8e8a49ec375312aed736669c44a0762e214655b5533579c3b9050b7fd677f36c0b21840271b32d0f73859d5d0442105eb8096bfaaed92cac9fa1a864edbb90e13e02e78525143e16aa9d9dbe6b34c4409ebf381621d9657102aaac57dc99a157a8277cf1bd8b3e877b53df453b386501fe5b153129aac66c33594e0ea4b9b143fff1d15a18b1e825101f3a5ea19144fea60565a8aef0a21806858b1888f9f8970e51f0576035ac6cf5daa6e04827011c130e7c6d2ab9b64d2800bc2f24fd5bfbb549652ce825a07a7172376e9b68a5f6184c38fbdd08bb79f77d9ba5dd6f2ca05cee467a17eaa964a86516120ae17cc5644e031b9d01b71972ac86e2733b90ceb13f44ebf1a31d3da6d32561e6621bb8527306a84ceabec2d4c677088f44eeb0889670aa5957caa560e1285a77b928c08948bf64e99e38a44d5c5e68b41eb8d51416942c392b8a4ee16bc3b55a82add0ba1e542ba89756e6b8dd0459c96ce7c4a3c9f402125e6a5a0891af9d13147d8091414d3e73381c87a9e71882b50d82f1fad299e1308021190a413759ae8906d1866ac037ab268429ded994213ba7ccfdca8e0f64fa7c059229d08a4a6754353edd289c50944f10c2cf23e239501980136299587049547501cb605159be192152f328485c2122db3e95c9cf922c886c56c36a5bb88f3a265427b61112cb701e8939abae234a0ffd8144d75bd7fa1d79646c75a9edbe2ae7182f383a5661236eac4e9c275d9c39d112bf3a740518a879262fd51f10f4f09c92642fb55bf6fe0e969ad459a8c8b441c67c6c0a5310f727d2996fbeaa5afcb358ca90b28b8c16b3231f7564c4f7986807f5817ca39a710a0738de1e6d34c9a2b882be33f3cda92e99be9a5c33d8ca6fe22d1e844fe6c81ca4be143415121a03171c7798dd2edfc756e263b3ec8b54580bc811e192dfbe9dee712be96b21bbf7b021a7db23075399162b853f46b71fea0fbae460ad72541d58e2c8c43ca4b45d44099ed156b408b268657c8540fd50358f6dee29eb90767945dd4b361fc3e33f3d7ba5900e2b121b5f5041f339bd47f85b6631892c8f5b9c008b8892d8ce2baa1bb4271f4b1638a45c9a4fc56d841ca5a4daf09088a07f3a47867462826ef1bb2f08134078ca9586020aa9b09976c720f4eb21f186f3678e850631bd642d8655ddc18252cad4c93d0bba6fda70b89f13594af8c3e62150ae185e3431e5e47d1ab94515401bf16ea1f47f524bd6e57ca27d09f031247732bed1c6e73ca52e9d78ca6f91f6f2df9861c9aa0951aa509c98382b5fca3f9689f2227506da8761f5db19b2f27fff76b89033593a43270c23d3cf9fd5b50c330e22e80cb98a04c4b76548e564432e3ea4cceb1168eec76783473f068bf04b7404e007e34ce22e243b50a27beb65de0888f7b34c46fefcc42c124af8aa735501d1770143535309a38d51d7c9f04a78807311b9e29888d8fa67f6b9cfb677f1140b78dc8f39290c4c85fde57a21f55c32e52d24383c1a5a0008ca6bbb409db3d8f3a24f5e47510f8a5850debe4556553c86408cdd0afd8deae36ba6b4cfbd1e21ce59b976c2988a502b471fc9086a60a4de1b20d9454f999d2feedf108a10b78ee4f512235aef1be4612bfcaf0e207f47a4872a5b78a531c2a4f9b6fd25de80a1826299d29f51d562adbd9ae6574a6403ae42368b28b736c2dc0fc058ddbd0d14ba3a3fbc3fd0b7154801ca206673077d0ff503ac0635ca73aadae3a219d22a2bdaa2bd3042611b000a763069ddd503127c2e111796c40ddc28828047655352b1502b6adf79295b2e834ef98aedf2cc7c3940a367d2dca1750bbde67c806510d4de92a8751e154bc3f66cb9012980dc2a3d08ddb2ec9f64cdb01266771265369629a5fb8951e029796b17aee90c400a45bca5acfc81dfaef0059bf2854512e20206e9d909f777e3051feea592f29734e52346d1cb01f6ca96320f7f1731c53062f02970ad38694ce5d4172aac68c0b71a325aee27cf2ce89e7e83eea5317d8710a8e9484377cbc2fa694437d89995b3a00e5b0561439ca854d1e1d9874798e1b42ba24686736b18078fc0b7aca2a50733c36766cb95f1b348fc5c725de68eb4505d1f20f9048355dc8269249b40bfa2209894c26002f1c6eb4dfc1508b57f8ce97e2678dfbf0e987006d694f1aceae39dd3550bf22298c3d158a6afb5217def62c25729d8e821cee62f6a2c0bf196c983553255095b3b785a6562f70dac5b0e4cbc6c7eb6c33dcd51d5184937c0b43bae77dba97a2d68a54daab3af3d9882d6236c8cad58030a2a6e60ccef1fa4c6c1c47c939ee82ea34d743f83dd959404208c430545f6ab1481424429873190fbf36dd56dc21653804628225d3f2e4433b7e8442bc94d21c2c89e8bf57eefeb099e906ae4eecf329a84d876f8f43fd04d7577647212a7c603407024482df2e1e007e991b4195e4f4148e787e064c0b2a9031d5b802a8607247b204d13a0a880647ac8c8625450d960448fb31945316bb7ff964d7d688fe8ed0435c6009357cf345f9f7e14ca6b0eff3a8c4a2a115216eeb5d47e9b8a430970061f980a57a2f900894e16dd7422bc98d16e731a191d7e4c7f799d4c68befe1a99e0387bf36120539f45c914197cfbcd603721e5de85a36184f3b4e110a5095870580168d67800ca54b5ad1667434246dda18eda4d0042ae720813fd55c4aafc005757e6639be765d28e1664f803ff105fd65438025932992371773da55141946002cffc90544cb539973c7c5328fe46800141a3a6045a01ea1a563597eb7b2f4ff3970604123df1a2fb598ff4126ae4cdcb8c36c4903dd6379cf1c669d9a06d3e3bb6dd3daa45443a85d6673c1065edd75c2152f47f0565d33e5a24528d5e3d60e4363dc580b5136e3e9751d2a106c2d4f0758c5b936cf6da09b9588cef5b82a811b0268ffa4d0d4d7bf1d884ceb5b3bb15c2319a86648dbc31179e3f1aab17b525ccf678c6b3d58c9f300860795f2077dd1ffb7a48818995455b665ff7ce8ee3d8889283b12c7a99d1dd5fb864158ca06599794e159e8ff9de83441061285d4633fdf73f55c8a591c859b2d862c8487690e1ff15c85dad3407bc5b794b62e9824e3cf07c1bda6e8112e0a86f529adb6da3405846773d911ad15859b28b3b6183f032713427e546c9a491f426a124762b285e6f3613bb1988f0ccd9b1f704c33d1bffb6b5e82eae5ff301598ef76c1d1e102714e305a208227e4c930603fbc9b1195890bc2be2be08bedfd7be27ecd3f819b0590686e48b8ec41c1403e035d6cdd0af41ca824f3a45779cd493c3aa634bcdcaa8583fd2d07dc73fb9f6ef37bd71a74dd2810ee7a5c9bd796a4ed5a10412a1d4dc81a1f2f7f8ced00f7f680604c3a0d22c552d3d26a0d7eca77b0b905e8956a718852c7a5ce56b0337ff74213b06eb5f7ce50112f1704300e103c54c4be710b58118bb0f414fc2babb614857f8bcf944fb9d9c0355636811b75f6fb5e084565b970d3936bc38f04c821d95599d712b6ca73b70b61403e41867823c2240967d6ac2ec3ee08e19ad90ae07feecd251c960279e99b57773a6cdc802f207021901a498725506f58fd1817f6fcd5168840d06df0ddcde10a0a0d9efe80f287d30120af3bb9b959ab0e09239fbac4ca8c2e2236f5f8dd2b62bbbd04aad675f3198e22fd4c981a941688ab42b4d1c88ac4603f0273328acad7be00aaaa085c3e8e80128f2a1a353b8a37914fb4cc9e0780d80c118a302c20f0b6766ab0b43f73372f208c8173730fb8726f37a99388b6acd19ca382750da6c927a32df8a55e9b09d12e0f74214c241d97e67df0d6cd4e7e614ac19bb7f95a51c67a0b1e7161d90efbafce0113a35ef9d33312a0bd727569bd112d3c41ffca1f2e6142001bf87cadb4bf0f6454dc8a8e8a63e25189ef9fb7394da850b0e06b4a3987ab41ee3f3ecda718298d8286ef1a971634399a009e8be0dd214aa328377e30508ab0fee9a3ecaf61a3dd8dd760c0ab403d0003d52f8a600062aac25f65110971be839eab781324f66d86ef04a92adc2e84b142eabe05c7520ffad6fb54cf8d941d2686e53fd16bb3aba8133000b338b2b3e40eea7aa985ee328944bfbb31a0a940ef8b825db2aa19d444090b8f0b76adefd47335c837841afe67a888fad8519453997859bea6a9d2832b641f4a2667284b430f4ba3c897c6c66b8ee8879d06cecd4d6ca58fe8ede09365f78a23dd664f4caaf7c13f01203cee7dbaa1686a172f5d6c89194be5d4a99d495cc5554226223a977bc62b4f3242b4a487e2a94d2b86323a533a57eca13283cf5fb7f3071ac8561195681bc249a45260d790cdc3fffd9c10e01026a226a36e0444d48e9baef985c774f79454c10761c247f2009387b0fbb51a5f09fed190fcdc7791086a65ad23637aaf5e6224c9aa9c1290b00b183cc905f09e8a22fd15be782477f67f5e5ee330f602cb7e420b702f2c8ba6e02dc857218031662363df7f76de0cd7dc988b944b3ac3836cc8c2955cc3e3b42771a98ada9926540b6ccd4259b0531004e23dcd00e1974dbec34d4a13956342bd011c10ebfc7d2280388397579a2d91a235d76053d2dfcf1e195910ce03c11b21c9ad8a72be37a0494aa4ff1b9c3013559ce3063b246f3e6eb68cd0e9aa3be7bf4dcade6eeac91a375f9956cee4baf904b24ec03df5cdcf4bed6ffd64125c388ec7190a04d2c2151dd1b9fe3a4f865919105c6e76b6f49ca64e871edcc7313582c97b017f9219a7bf9f72eadcd3436805b7ce472fb74179f2222ff4fb0abdbb505b7ad6583db35de1185d4fb55b88d4f5d06c93e0264ac0b523559cdabb64e717f099f1a5eb652acf376f36321abf23c94b9ee22b0c66acaf3e05165e6fe01e448f0e01af3162a2de28027daab0eaaeaee1c086a11c4762750be177e36ff73ce40dfc3a1205963326937e21ee965f18b4957edb75c0e96181a76384e11aa808f103fe30738ab8efc85489125a162a38e869a93f14a1e9be633db3a3ff838583b45d0d24a686487a492bd8697e30537692518ffc753e580e6976a0d7550d972639cfb26c3c0ab5288dfb4d4f9067a19e6c620bb5183947df72137b908f7aeba17cfae83c5b507d22007e1ab7d3c445c15c2ab7506b30087dee07ad8477e48ddac4d6f847040914298521022df82f2cbbf81b75761e9a6ff1d7aa53296d2343273c8d7ea470f2248e15ed48dc431018aed2ff40b09dceb34f941586722615c5141b7837493daa3a74e478a13d26c321bcf09d7abf8c978859c70555840ca0aac4839a18b5b9f521f7796ba3593bbc5fc324a23c35cc262b3a59c7402cb958064049500eab16e1a2901020ebd2a1e3f37bd66f51a01e3e79545e66bfe322d1f88a484e4c7d58b87dea0f69a54ef9e15f227f32dd0fbaa6d21d8e328314ce6d612bdd785904b9f604979b268ac087f7879579602e8e06a3c9f852cdab5771adc0497dc810d2ae1f5308790ab4f043652b7b5c7b5dcc7fe3bfa0604271ec226993a176e976746f3587eb86e1e21e583562405042f0548907d629a2ab7f1c9ada7717720b830f1c0219b3b3682c25396bb27682c56e4016763e8cf98e0b17e7cee9b25ec716924fca3a4588579dfdefaa208f6ed10d341ec10d60b2dc93451cb79e2be27f307b1a25eb11c463b8ed910d11fe811893bc8e938f3446ab80d5b1505bf0072ae62c4f53b91a0cd3cb1df4724821d85a2f47230dcfe415c3c49a7b4c54faf6c1aa31adbdf843cf2963b51916e72b342af5c443b6127033ce883ba3e206579d167662c7f73275c4aa28033580d156718d419ad60b9e64dc2d8db334481596d134521c352b4d9b8b6c3a3717a1e10495a75230f6583fd2db04e049bcdf2022a0ce500a5b69b4ceb6414b47ea68670d1a2cc13b003216a263e603d0b1cb103ea74d67b553060d1a8039192aa8e038f855465e0930a8c75cc62287a1ebd7c86cf74c5f7716c7fce2c1e6dd8f89df9830820d85d5deebafb0a5dfc2286b87ed1e7d5073766284ac934feff890033426964efbdb7945bca94a40c6907f407c607d6e24dcbba8f488eda47d89ef6decf39d22e58bbc06dc341e01519ab00bc226b58629955d12ef25fe0afaae0cfa6e06f8482bf3fc1b05d3c3fc25fc9f31f96e7bfccb505cc1e0ed534f9a3a79e02935827c14a3a4909e6ba3a531f942569527f96bde4ca96b2f44c94761c6465afccb5058bfd97b972127a92f8f3e477f0f79cd68ee4cd8a6edbea6f749ba99893a2491473282c6cfc8f43e5766549b25737646539252b4b0eab04c9061faeb4dc04bff89271d37f719561acc9f08b36197e84895f120281a05db624dd86dea2916881c591d61144c7b87af816264337c5168c17efa686a97634fa13fcbd37c29f5732f95a6d087f36762bca7cf0b723f41efc9540dfc19fe7e1b438716cb909ba4cfcd89adf8e10fe4a20fc791ffc7dad5f8d10df18638c31460c48afe2d7da303b76944a106a300dd3300d5387ec0f4dd0f1d6c846240c9142beb108d06b75116a45a8c2f630be800dda431fe43600f4fc3b0b44820071647f5880fc1e0be4cea011156290c5a113d2617386442295962821bae64bfc0581ae243730ed41d70dacfc892b8e4560a02bcf095dd1e5312513c81eca72b6fb94234f089a4a2a5c9d199c4d830dae7cb67b4e695d208567b0f1dbf306c2ca8d9b5cf033ac5cbb8462c7649793e28fa22bbb82848284b2ec5ad995a3ab5fb7934461e17fed7a4892fdf0a3cb47236be3c3f696cb2c46a3d82e679470b091a38db2cd823ab5665a848dcd0e673339b7dfb2b0f15bd3b2124f9679eae743638c5f6d5699b6555028d3ac9c98945e53d2bdb0b21ad86f25b7899494ae2431792591326eaa28d44b4569212671b988e8b2d028ee94bbdfc29c88d8b28561c1f4f7075472e2282229ec8843e1ac671f1b4b9486051b7f663fe7d794ee654614945a868dba1798b58d8b306623ce67604f60da45c21ef3a594f26327a54c8c287fa2ab8c4cee6f540c50ed327d061adce57256a9e9f83cf47caee74258675625949c86e577a3a423ef80ab0ee7e52c01597b48ca7edb368faf2c7b7138beea2b5b226bda8d59ae74eb32cc71664b6fad61ff75370c759f799d48eabaeea57e7704cd1c2cb52eb42bc45ce7cce607f28cd0ab329bb10bf78de33a4e7428b1171a19c3f105832e1a26bee2cb5d9ce69c4083231e1607c903af8dd9ad60e39c73ca68adb51986557ae2c9ba8de3c1dd6dca8a7d49c319ae18ab18ce4ea6cf15067448c43c7fce3cff6b29fd618b7cda19d179621ef06853e9dc5d39c968280077f427bc2b5813b70e779c7cbb97f9a552e9721ca8655d520419771f32430d0bd883f3fe03cabdbf9cdf7d471f5af556b6d9b80bb374b789526b4dcd4672ae4316196173e8c5a0279fbb1af4e4d7cb8124f99b16069892e5b70924c997d1006dcb5203d929a5d8463b6b31d30e78371f9b30cb99ecb9bbdd0dd43cb5ce316bd7618bfc7967e68124f99a8d9b4e204942d8f2692d195936a06611b6739ea04e3bc4f988a4bad25a6be460b3dd43d1878ff6311fbe8c51b3d16cda9f68e9e8636a62e868d26c22a9bf104d145586ac5521fae0c860de19a18eb99c705277c95d22e1e071e2b919560aafc8b309d93f6a0fb111873f2b276d13adf0b34a670f7122d36915da69c53a1da7c3e966c967bc237853a552a9e65d65352c1575aa52a9547473395518571baee4d6b94ad5c15efee7d5ff6e7c25940c3f196a3fb88ffdd5ce57a954f701796ad8e38f0896b51543b0b1535c1cfaa79454bacc6c73811e7c38ca94898c592b2463159268a54e4cc16101ab90a1829746279e15d78484a429d87e9ae7c460add68e46ff9e57da91aa59ad562b89bd56d241927c912504b2dbd921412746b10f8d5a0ad97b0549ee321fc2944afdecf613a0299eba0ad96bad118afc85a8883232bd0429d8f8d39bebe2a449a964a60c86c96032988cc424c699df2ddb84868132b63b4a9389281d4f8d1d90fd2395384296494d309ee2a96631067014043b136df003b26851f010fcd1b1060a5e9537d93b452351cc86c1e410db61fc4602a19c91faa80fa58c3e2afed8d2dff425d296a24e117d7414b0a5bf8adc54f40c7e42e8ddaa46350ab2f457929432aec4ee955150a8f61acae84d6736ef4ec413b248cc03b9e17429bdbba9402bf458a0eb32903dcb26f4e4d48ed838272631eadd3d822c5cb0f1db25ce2d366f8cc70d080001e4fe582104027a3c8ac83d83b264f9f2880e894ec66467c4ccd25d9aa063bb9c18ad99b6719decc3409442ee27d81cbb2eaa3af5433b265611539dce0809c240e044114e176160a0883111c57533f144458c34a0d06c42c80dc244c9ca97c993b844ccc43112df23352c27e4af639cc09af9c18004b4d73f9213cb4eede3764cc740962b6cd7712a9ed665597370c0b51d3d1d8d744cf9634580016cf5a566a1e79c190726f4e4c49cb375baa4ff19b46efa31c48f958d0fc411d971404f7e762f24c9af577ee32840feff0764d1e567432b23b9f2dcd74ab13a868d4a894d396586d18965124e778879bfe7de137afe81493b233a1c19271dc106ddd40f7f7353064973661c0042c487c48e2e70e8cdf9d2810dae7cb08f70108b33c030c02d94ac103af1fc773f201e197e08f4f16c18b6862c6190fda310b9fb12fd91b5b5661b08e02e0d1a0ac8183ba03fdbb41a22952aa54aa952aa157c1bdfa8c22b2b5864850c2c52a9f09dfff1f1fd18f713d1e47e189d56abd302b94427f02b462050a7f5a1d48f3ca0942804b9bf2352953a4ea5427943eecf54b9bfaa40a915c67420810da02e144f11268a209ae4eb156166919b9b1b900ab4b09ba72677d5aa2ad624449364551512c8b2062eb8e0a235532090063204b691188dd846f5c98da0daa57340adc8f22912a0cb0f202f9faa608f205e368d9430d034575d805ebf7b01ba4c2dda3bb929002fc44b1e2fdf6fdcd4e32500dcf4c3cb1d2f5d5e4ad34b1ffebb91e543f8ade878f92ad0545b5e7e843d7ce0c82fdfba2907102f31ee537ba83258acb34cbb6431dd39802e590aa0d73f576ee2689cd49caabd2e40174e09d02bcd15b74292fbabcb4d1d1b27350bfeaa0fd8b56d2d1725c78dae9b9b8671527cbd5aee496c6ddd4cb4618da0cb8bc8a6e59a742db784d3bde0c05aa8e245a4320213a59210d140ab854d7bb6e582562a27f50d13931b2727275b006e0422c48d2c27c59a1608c4000d2425d5e974acc7b6dc4f16a5443434687c8d504c080674036a816c402cd0ca49317ae82186f72942b23236a63d1b366c00b931e53391a6636140359dbf6ff38d2b6bbb99a852793c9e0fe8d3723dd9f3f97c4021e9b2f2ce6419d48c199f895eae148dcc092569cbb5b9c80f3f7c90844a422db793a29139a1200bc62f438b15170485422fad1250cb0464235df63959de99fc406e8acc8f9b820a227f96822c4645e4ba01c015d138a9655031279a172f6094601103740362fd7fbed6c6341016e65a98962964422db7fbf13dae2825a211a1443290e58789c9b7a804497b3dfaaf0381725c908d934e4e4e40fd4204e08a7eb8a2168da7d09820c9fd26dd0ba8d59ee4c2a2fc1647113a0724da0010040e1951229b928e88ce229b9689c8862b29791e37c238e162f2c38d27936e26c6c49896bb7db6008d725c51eb26140a897e68b959c6464cdc3431ea84b85a6ecd382e033a9b964b3386225170a0e4b83480b45c0cc4fa94ee05c44ac97153ba99524a7784671fef838f1b218b0f9fa2c24997fd3a2e2eecec7153649cd4cf23c6e5a69c208b85699212b6efe7549b0d87c5ab93a449386ec7d51e6c1387c5051bdfc64d39be3f4506f66801b15a30d971f5ab742f2d57e2b820d64d41390983b46852fd8f5be57ed33d41822467ff752fd1ab354d3bc981453698cb49f7225f742f308a8819c46aafe57a9677e687cf7141405c904d7b3f7cc7a675644710d52ab2e98890790b3fc068b91da3e5c66f99c9f1580e2c42d2a4fedbbde0c0221b914d8ac8a42425044a69791f4a387ecb8590c587ee8505cb1bf713d57c3e051b1606e6eb981af70b9d3e110f72ff0c91cde7c5e0fbf9142eeb7b18f7c5fdfc8afc81589f22b2f9ec172a89402cd10d724fe113814436a7fc896c4e6872bfb5b130a213d697c282dcaf896cf227b2e998fc896c3e2ef7a98db48bfc482bed8e49690df112d6a38b9637ed7262b4661c87db9870d2cbcc124e38a985743a3b06db192003d21d2009968da7fb0cf163f5b921ad5b50178a309cae7b459896178a4093bcf15a536bc45057b0c77cc7b5a6d6f88dbc29c9c3eb0e23c81d61224c84e9566033972ff90a03edba99d14834ea90b5a393285f486a4d87124d106146004db5a626a6e0a521b135af9a97162faee3705bc789a7cf1436b8f2713236f683af7639315a338dbb1a18ec27fbab4ab2b61c715541165694f70049482d029bac04686f001d97547643fcb09b07eb18226ae4aa6a4ffb82dc406b110e5840970420a93fc65891fb834093132d599225595e60c548560c9c709364c1976449566e1b0b925d902c990534c5180986aab22a1528da6a45933c27cd7c7684502854d22aa351494989490c596b32dfa47b9952041daa5455a575a15ab17a715c5555b571329e19941cbac9e218b5802f591616ca8f8d8231fe166f8a1119e208596447660833111939b0c18ff105ff8b2f777dc0bddba3477f837bf4e8def81b12933b3aaabd081a79e28e71f78eb1bd040ea1c31515d94e83cd031b5c8110ba436d933f3f0852d571a36212922aad4d646c6bdb74e5e168e4ff25c743a4010d4cf673a48934803d3a76737cd23c0d64d1e0202169724dc88f52b647e1a1cc61f4e1874698376a6f4ec415b26cbfd58fdbe64486a590f6fa873047b047cf2a0437a1b51f61832b308903b4d75cbbd89921b108901fc4e7381b80d08f5e5b0275591add03c824b40444a04d4b74919df38f8322cc8dec3a4ae091b8e25c25482c928024e260b1220e106144d8963ca8548232aebc7f09cee31d4e771417c9de45a61f21dc22bb1413ae70f86340a60f3dff49b5240e90802c16c962914c71bd71004f524a29ac1092e4679b02c48a0de3af17172cecee88e8b6d0f425613a2d578eef1d115bee685a58f85fa795a3842056910dc21ed88457c4b883c78763cef74c64465fc2139600afd8b1a3547242c69800579e93b041d803c20c9e783963f2664aeb68042be6b223c426d691b9ef044a92052593bfe3ffff5214c106b324edb5a669a1efee25f49095a5cc41e60aac895c718eb4376360b712901f7812a52ca1166f90d2089a6ae871444554cc88d6288cd0131d4e982952d1a4fe92177d4c6927a6a87a297ba51ac91a27b5be9ea25d382fb1f6188e34da8da93958edbf4813a950c9d409c61c7fb68b359ec535f2a68bdcdf11d1ee8583b32a521c76fc8d307ce3260ee5a4ec69f712045e9137d87177a6728e7056cea9e191258e2c4959de2c4fb2f4649965c9a9e1ac343970569c236e5a791831fe39fcfdc59c8c1d3b70a9743defff638c463002df06306799b2bba58c953fa3b5de506c34f0afbeda45fa7db9a963621b91c2690cdc3d468f71bebc8ed12068fc9a45faeed45d888e520635fa12226406159b436c52babb4f29a92fe158ed8ea8989c32dbb810d7711da7d649399d4d06be4561bd636374cc5f12c1a63be6dbab080c1451441130c21b98dcb53427366f47c8447b1da4bdfe49843ffdf7f29c6fdbc47525ef9d60e57f23956faf076031a7e220dd65427e44844039cc0fece1b9a95708132f5bff833741aa19f2176de490fba38d9b7a34b2d62b664bfe1b99fcf7a3ff4aa392c92db92190c438d242fb1bed3eefb9327f68f762576eea5a57d7f3165b6b4f4bca966cc91636e2b3fd8deb085d727a88e746c8c2f9dabdd8df328ec51f11ce24c244bb74df1f4408e7651704dee4dad50ac09b3cb9291f7a73005b8d366b26466d7ea4f298972a50ca12f753229eeeea203b4977927824f66ff1561a5f6662ee0c8687c02b80fc60caf797316221a1aba14bc6221d8b6cd1db9dd24c624ee891c34686d83b029f108f5878459e32fbd8ed799e2733c9d29ee7e5272ce1e61aabe779d0095932213bce9265b6bb3612c4577c499444dddc44d1022d5eaf4d6e2e1bfa6ac1c4dcb0e88d4f0907abfd909466d5fea8937012cd49b092608d2a66aded4ca31b64c9d09b9b8d9b5c9744122cb79e8ee3cc988a5a1eb6c075ce2898810bb6c0bad80fb8faa1326aea93528f052c85d89494560a21a5b28b0dae7cf4e4355ef34de1aaa6d6346d2a6cb05d4e4622930c1fa5244348923204fa786c87d3719b46532936a57744c9f03794141409c5c9c6df6afc66fdb8a0d6ed27903dfd0d1be1a0c8fe57890844fba84403d1ba957020da6fced1ebee4a48209a94522a31816873ce3995c080d08b61188661b5538202d13e2cb01f95b96961a9a679b956aa191361a84465da6f1a7d9fd1b011d9d32f22c33690a500191119fe28c65efeb7aa6b31a0ac95779b166635a4d75d271b534304cdee822cfd5a1ae8ad4eea19186d46ee6a4f43838d4f5bb25d081c06b856f62dfcc65b70fa943654858676a198aa54b95f45553e07da7257741764c982bb68eba6633bec8f79d8e0ca0723957dd220da7319cc0961ecb863074acc2a2e4740cf07d09ecfa8f1e22564d164294f246ff95f18315e7a173985c6c42fe32556f91d2af7875606aba2827f0ca08f20797883624bb99d6ba46846af9dfeb3aae1dce06bf212c1505ab32ab32cd3362de5ce3ce39aa852167582713f35524a94234df2dfb6ad7b91f883457b1f564d129f95935c725c29976618f753c3128944265d34c953b00846e55fe02f8848538395d20d19fb0f6525310ce654c11f1764c9c214c16cddcbd4dc95e24ac13a4a251a3468a408b929d5899f066820263564e0383739e56259c69d5979d826941567c63579714d2818a80de843291a500c8c3fcaca4d25252befff49c11e29ef1cbe1ee7ee2aa3917b3731ca2a84b24259599b82a1ac304ea76339299c9b4f92cec765f2ba31797d5c6e8af1fe262ad8432506367999bc543a1d9b72639671f1e5dc38a9fadf0bfa0b427d5e2e6b33e72469cf41379c9bf61c06feb8502f5eaae00f0439e5e34f4944e78f4b6b7d5c293365e693fb791ee1cf8407d95fc4b9019d402a932964c7227f1b14ab0f24f3990821fb733826afbcdd4fe60f6595fdb5fb81501f1788267392647fece3da11c48f39533d641249a1318ab07da8607f3491185fd4c8343206342ee08fe95242d8a5ee77b40b87fd658c9b40a1970f579c92972f638d5c74c13c2f7f84b99fb8b4717787cb72ee1be736a554665926b95349bec1eeb834b7818a8a7292cc6ff662984571cfc15fe76463dc60b1ff6c4cb650a421d3e7e27bf712b185a23d47cd17703719e39cc3dc09b2b88d691728dac5bebf3df9d6bd74346bfde686ff5652e2b140c9b590454aae224133c7813a22b8acb581ab28cec58e64ada2daebe093013220efee21db9e7b87611cc6e9743a9cebd973b993934eed65d1e958adab282e2caa5da0a33a036440bc4a21d39ebfed5e3ab8a2da7394c763dfd3bd58293b2f39f53f490587e24e4e72ce0887ea60ee94c5a77238cf995b4555d42739ca9d4a3a76445496534a5408061483957443a795c2f103cb67c16a29d9e8c1871592f772da78335efee31b3272d4781a3960461023c36a172e950574e188f09c6adab0f045a9b18257565223cf582a4f9552e16bd2e15bc2059511d429a60a5597c21724837252c7b036867f582d370229e1960b819c3a9d8ef5d88fe8248a41414901dd805aa01ad00aa402a5481724e3a41218304a542c4ce7e6c58b1f3a9d969b6a7c3f8806f6f0bedfaabc1cd1e3f17cf0f5783e9f4f086471dc1498d7c9c9571b96935a8608a294688b0f08040aa952297c3ba718118c89cbe42512fd88a54a516a0528140aad4a5626aa92544ac5f9e1a6c0a0bc583e1b41060362d5f870453d5c918989894b26142aa949755da7d5b969203a2d934eabd3c2325429950adf0ec7f7704527518cc94b0483c35a0f8e191764b302a93e9f2c26f7975aaec846b492c932192b5654954af980452a158b0c554aa55271a44ee76dd4f04c40a994b782efc669b96855e31b4ba4526119f8d62c03cbc017ab714720a4c6a7d0b8716fdc397bb829366ebc8be2822c1c11b894f6bdfdc775b668524da7d55e3710fd1d562aa572d30a0cec81bbe756302895c22d7ca58c0b225d9497931a54459354221bd1ca49ed19ab0616a9549e2aa552a552ede1eb352e88c605a99cd4df61b9cf48b929ef1fba91bb446659bc512a899dcb92c492867221693c9fd0c85d8aae9cad1493341b126c54599f81fdd1bfa96cfc6dc4c176a9323107725239b74efb786c9649e89a67184e4ae5ac5cc7c93c279895f3b569d90bc3a6dc382a67e53a8e639b6f50c3fc0836c326f4b2ec035db6695cb669598589af49398e4929657c613f8083cb895123d852a924adb536abb566b462b314e33b5e429bb587b4609de59cd89473ca1ed222235631c975ae6913d3b49698e4b889715ca772ba17df3a5d013cd71ed2b158e5944a25897d1479816e45b0f13bb5c3380edd324e9db4665b15b3332936e9fc6e7e369f9b73cedfb0f92e29463be0d09b8f754648ceedbc4dcab931d30e38f6148359ce68cf61f43a6c999fcd39e7bb573a9fa09362d8639863aed96836eefe444bcb193722582efae8d280d1494b7e330947863c728c9fb9845d2f6d1ab74cdbb48c624f9d6a2127462be77694d6f76a10c48e1dcec5ffee8c3e552a956ad33ad9aa283fbbbdc0f69adb54aa8de35439b30f8ac669916275db549b6a53d15ae7f683ae0d736273f41edfddb1b90da154338fcb8949b809a1d65a5dbec3ee2bc973becbf7988139e99c316231468f734b599f344e1a27c5fe0a4d63c4300c9bef4e69ad41089263dfc1fa47772937206052fa8ca53bd87e7086cdc54e977362b2c65865ac71627262b03dda4e679c52a26a1362ddc1366707f3008b4fe971cad8365bbbc7021df4649701ee6619e68e372a6c9c149318f5da9366d1cee670dba66538243b886198d3246c73fa9c1d57bc1b3b4627ce83471140d4391d7bd818f60197369b0fb61e6c3ca8d6c62d6c345b14d663810c92a40f8944e490e8f106b3b119e7131b5cf9e2c925cdb08e931e4ec77e3c327ccfb597e3ee3e471db68180ec34a027692800d317025db4318ab59c18ddaab669f54209eb8d2d0a5a67269b58c932ad099591b675c8ce8d6ba2492eeed4724839c7b9bbd7c75625bf417b7f8bf7a391f6f08c90cecec62d3e259ab9867115c7544a26739f72ba74a755b4e733a9cd064784e7657c87cabe7aa93b75a80ec5725397c2198e32b2eec5be6c171b1f7fb3fd37ed92653346cacecbeced6fd98d37b195fd175b5b64237c877821feb33ffe1be5ff1ec87f9e001e42d310570017c8cdf7c715e24afa9e713ed9a6759fef5c993f9bcb4d8d42b9502e57a73bf91d140a85c20ec89c4e277362f7b2d17fcac9baffd1d5c61b1bb37bb118bcb1dd4d87b910cd682a75471dbe20b94467c4cbc0323ab348a9a7c654156d8a472291bcf21f6b26667d3a9c0dd4bad4631b353fc371d55ed7cc3f126b22cb4d72255912b4715a9c56a7f569fd73ba178b332d60f0f80efe4a3d7c04f11bfe4600f80c0740ae6cac389cae73cd68bfe9e07646eecb7659f9f8db063b148fec38b293b2df134ff6ac4bf945dddb9dba5367a44bb9e9e5fb41ff79cfdbef7cf79cef5c6e7ac1100e812124951eba4900184252cb433701c13e3c7453c61092581ebae907bef1d04d42e01eb00d49ffdeeed41969af00321edf88b1dc8ea8df9d3a231d6a055f19538ed8dedf255619b5d792a6dae57e7fa645bbe0f83eb5c966a2e3bf5136d1440f5b645376341a3d6c8fb4d28d32ca282619b829102e5bca49bdb19cd42e5f04000600600401c3078c1e30623c0ffc95328c87d1b97660e37fdd2907feea0fa91a5dca4d9d8d07e1af7ef0676f58fc7d077f5ecb7738c5e9525c8df748ac15566e8e35037f9506feec0e7c721397c2f8abf865e0cf9a526ee24e2ef8ab406ca98f76da5c4e6a1d1a853d59d2316b8a27902011236fdffdd0e5e870745de4892eba12fe76d06fc15fc907fc792cf8fb1b9dab87ce65a373c52da4e05cdbf624fc8d3cfcd9af8139d7144390702c1aac19ac1556912eb8940c8c31884bc12da4e04e1feee4c1dc893b42c48a6d73b95618c0b9171a21b3c4f22fcc313a572ab572046e51648a2d8a947071d52e47da657eccb22cf4f36708af74dddf19ed6b14b6a56852d39669973941fe718f5bef38e7d453cee9def17c4ca651f3bf46b51433054a7d529e944d75525c8aa6382b389bc7a3bda7bbc0cb9671b88ed3f084a249fd364607b6761ad552c8500ceb4ee7454e4ac79048a44a931a224bf41b2e7b9011f6b840ccfe367c9bc24e8c5431ead15aa36634326d86b6ad6c9c0caec31de74a4ee72d8d31e2f8d67a60783e2f3e2095ea440d95a094989c988846a2916874627282528292124a5101a9bcf8bc80e18111c3c6f8ce94f02f87abb8c339b0b03d199c8c956d658636834646a346ade1518f84916c4c1b3dc81e6ef80d9666f1214e09b17f6107cad195f6dadda5949493b53aa60fafcc302ab7f7f8bebdfb16df37ff6e8b33dccb95266dbf79dbb6492a39e72491ee88fadf2e746e9452c7a84fda2e38a1372726bb3bba6212975fdbd1e5a47ee1c04a3cb130e7699ebab98e991dd3314ee3a679f2989a3aa95c7e72f5f78d9b24ab9bc64d92c57a752b6573ea538d536fb98db362625c3165a80112f3344f5734c1e58a37183206d66864ad8760481e523245650a92c106f0244f5734c15d94ba8bbacb856d71f0ed0636c6226c36b0c126b3c96c3690dedede7346cf580012b0bd574e3cd87fd98c05fc087f16eb886121a074ab0186490fc4ae1988025942964f05b2ab452de2a60fa854ed391539543400005000c315000020100a874422c17038d08339d60314001264944682743c1388490c8328850c42860003000100200232333412016f1448531554470ef4771e1f44fce23b4a68bd3af1cc6dc9f62c005e0ccea3e5e0ee12de459cd8aa646605f05b7c1a66a87c52efc7b3443a7428750fa2bd2f524e1ddae7e8b4767d6c66eb69999607f8afb045ad649089b54ef4671540c648c0140a2933f8c0e8a5f0c4f181270156e5cee34f0312e72a62b2afdcd96b1fa5623c488ed7ef2e915bdef53b44364c49f5d89e699d07b20193f4fc2edec35a64a67ba095e555f83e9deadec28c41fa5425c65b6c0fa70cfcd5d97e1e0358b880310d91aa9d176a8d3ede875156edb40e793dd2c3a3b8e4e63f6c200969f622a5d7468ed71e865e056fc52cdf038c9515c494a3531b0af189a324fa002e5e458a464638eeca492376ddc6155eb38d110daf35405bcc0eef20c9e43bc10c953e22ea66c2c4af524639fc1b03ed6224ffbdd75034dadf3570c4aee4e6acb7d23e966a80ab29037b5788084af381266e06539242e074012922589f1940cde73d025d6b77ee8ad59f77753288487813757b4575da40bd550b5aae3e12a8a782bb2be00322755f3f8eb435bd098363b8abe0c20c0e408ac89a30663823d28db9ac5ffbf58257343620f8242f08639ab182ec8a3303820062a20e5bc8625a1eddc3ae18a5531b990019bfb0e930958aa61ac9ab6b8015539613b8c82f9c1e536038668961de655472649e2bdb66f53fab363ba169cccf287b3cd43b50da8dff8c450371026b04288693e8627da9cf59e5e9dfa43eb7f03cb4367ea7c9b0ccf42f6f50774110bf5ada15d6b49d4671a4e4ec4e0948ca96e3e9da9592ec84e8a6966672add17a5432c9359633e4be58b640759fd7757dcfc38f2d4b3e9280d13929f44d665aafa493d49ddcedc00f418b5a83e12a39b444b4e8c608bee00a7b0f7085069d52563897d03827dc19a16f7dbb144cbf5a62f6d683dd03604dc1381ee8c06e3cba44a4c694504f5815deb23f93629aca915da5803c1f16540b5dad67d0f51c9ccd005fe07934444eb5d75077d73ed4984373d93aab2619c30c692cf2e29a0b1f9f4dd81879c6719767fa9f1e62457c71242cccb3c4981d45c8321aaff72b6fce36e2780d7d1ba5141a40b71724ebf0a9321d82c1ff6cc567369b919e473bbfb9546c1b396420f99085f1ae0a74d875c6875f175e490a9c4f3de3de620353885e1fa3ce5f94900a29949992ad5865a1c2170040b255dcaaf52ebed46db40fe0935f0fe5d1dfccd07a50cc14cd4211052e09135fb99b64eb446a09f1fe8f1250e89bfb4ab8f55b73003c67d3a3194483c0056308c650c956e7e04bbb564e8b2eb0d293cf338e250dc64c0859e66d26d9ba86e4af579d1f23441f245be3d07e3bae82c8797ced40b1b257093ea40d885941f5214f6dcd6bdde9b05cf26e609b4dcc13cfc5ea2f7f2d48c0397eb5e29405b9105b6bbd63672f0e034b2015140cb03090fabfd0ed0b196a61d5890074732d40d363d804bf0128f4ea344a9fc918d0086a244f9d9cc6859e4874a9682a53ab9de5b3d064b16181c117a05aebfc30dd706be0d69468d9f25f6dd49ab669332200851f1158ebd168f7de9a8b3d7cb9ca603b939e4fe8f9aa51229cc2a99db6e3d0224fd6659f972f4f5db613588c9f743e77e6a63ea469ff86007fadfb834b7c0953aba2c8b17da4b17456461ad801e150eb830593aee1e4177e0ad9567d61870a4642e4f7a6d523d33a91a3b0958aa78ceb9da7c80292502232ad30696d2bd6cf4b6b1053926e111588c30d3378ce281b270eae1c194d6a28621765b952930556c6f407eb18d63ae9ec64d28146d5c509a887d1de977a691498d396d20169fdc5c156a245ebb17104195a872092323892d91c089dfeacb6e13cd35ba1e018e6fee41dabce45c7d76f2b58cf206fe83b0da2f7d8a3cc97fad3487efc58088e9dc7b55e706f73a1f4c9b3de7d4930d9c6f6d22c9c283e6af100b259553933b60ba0556273d62e29cd0b418337bacdcc0ccab58f579ce4563765568f33ab5664865f20bc5a1a8c8af60625c371b0f40a8636be692ee710358bc275b6e7f4d2acd250bf0d26d2b366d65f241d553c5164394cb16a5d8697733ee7bb0bddcaac6b70b95fbba7b20f1fbe87256f142896d54a993587426bf15b13e83850b5b202a991d5391f1d6086af8f8b28caac1256356217b47e1be1f82653423b07f4936256d17e29d65c025a994364adacaf3f2d64ad45e534364cb0987552bea790cd65ab194a6f868e192d409cf7d42d306b1baf71aafb667ccc2ab3d5187a19f09c09fd7c306eaeedb99d6f5b1551179fb601175b7a05af6190eaca4725e790eea7d9946e616c97ba4593a4c1ccfbf90fbf31ffa783184aa9373697313640c6f0e0b590ab5d1ac5622dd4ddc4a40c8061e810731c3fca1dea0c98150ee89dc7f5615323016fa689d5be7759112e38268872d502d0aae9a0f0f8a6bacc226204d654732e6ba005684071933c8c37bd312375f019fb6f599d6a1e1530458cabe91649ac68357e9e5016e91537084f128eddbe6efe6207183c2aabd972cb3af3a41157dac002db21c3cbd90155d67941085796a6775edf0f1ba28b0d30fd222d7fe70f91dfc70bcfcca3cc534703b494094323d0dd155931750080070af4dea77e2204fd1ab27e1edae8fde71eab0b5a7f21513143ca67b1ebf780aceb000682848f39568e47ee02ca743c09ea880455b5402964bf38ff271600d06275a8f174b146a905f857ac956b398a811a7fc7df6d6762fecbe02a728e7acf7d97471fe0c5f3748e0509b4af89cd9b6c2e956744b26dcb008c6f78ffc2c13cb26a645713c4b13ee16f446376b10c50e53a3ef331c95aaced844b213455af6b7b9803d6b9ccf7ba3544f4f449990c75dea89a656dce641e180d3a1bfefd572522486f29c3b7ae0c1f096718c13bc879c8eddfdf701bfb4857c10b5c903a70bbe62fff869b984205000f92d7f05889982af4535cb314fce558ffc55c9ae31cccb70f759f4bd457b3f4a2fcdae5ec2b9fd8b40883583297edd5407d117674c1da54eaab6f678699298303e78b4236b5455f5d5f881a3ab479896b35cb00af42a1af7a631d39cdcd68048677fafe4869a2a733986d11d1da1cbb14bbec47acfac9ccbf68c8ebcabb62eeea8ebbab52dddb2c46d489532c14b2771f95edcb9b72c9fc95e31ce08a586a2d24607eb743620dd7f8826657d1ff8b79d70fd7cc4ccc677474cfe5cb7674ba5799658a7107fec2bb840da9ef13a6c9f14c0edeada41c4a4338b1833cb51c161ba68d7863206b7bf27d027a0c4126e85ed1eaf702cd9f71d6bc346df259386e1f640acfb4e2514edc3f7a70c410210947970ddef6ed9dd2f286a610569b8b8c5b7bbe9904c7102b96e28248aa594fcb91c42a96933c34d698be95e529f7206487f9bf5561a078587ba6d9900be958ccddf51e2f6463d80d1fdf314c96fa64d3cba5c70ead7c354fde7d733a491efa8dcc6f69e46cf42a532850d99775722a82555127b997c4a00b2f2b0a33b0a031bd040391af916af9337ace29b5d86c8a70bd420f88dcc832f9a7e84e993974f0a3cc9f3b8cdc481de25e1c1d1cb9597587cfcc75c2ecd1de703837151c44ef780191edd03ba5322fc61e66bc3d61194471ce64c601653dacf746922087332f01e315616f81c3181409c9aad15e1cde4c6e806782cf70a03bdd4c95d215b40ca7d9d0cb11d2f467a905828adfabba184edef292f831eeaaa2ea11d1c31a3d031ca52634666c0dbb2fdbad2aeec844649373fec17484aaa868500cf7a3aa11b09784d4507792f9d3d406e642b36f2bb645c6bf1e5595e6ef3d46b25da0def795f39ef0e6515efbcb3fc44f32e744a672038893aa962f731db6f4e32dd0111134f213c281e341c39160901ff72589c566c8852f0920a74673ab0eb6d7ec1368476e9c941b943a15e93bc474f267089d140adb9c355058ca1d651d8b4d78344fe25da77477b74304063abea490422ba7dae7ba5469220edd4c9d6a23098d03b0ffb6ab6326aec239114a04616c15ddb854c3c5a0c9e2041aa55170cf9c894169e1908aec418ab18e87acbcd9dab67a95a57329b08d5701afe34733fbc52b63913c110db8a319c729e515e141cb52154432869e392e244eb852b5184b27d8a249a218dd2082b5918782315baa3ae335df47202d45240dd69886135a3a01a587ab6613bc6fe904b73c77e3a75b77fb884eeec72bafa74ed2a54e826da955af131108e41a659de9d9c982398fe351637c6385ce93535794a565b277c659f752bb3cfc3c6c52aacf3592de61a22772d9be2522858f569ee24c70b00bd66e71935199d2751c43a646d95f3f63966d4c5170f0c4b1183959da99772ab7aa9fed002315124f65eea0980d0b9312d18c56fd64e074bd294799d5e18f24769617afd5fb9043425560482221381c67a6f2b1a2d00b0d72fb5718001d39e57c8916d5bbca04b6e6fd98e998699e30cb90b525887c36211f451d46c48e0f61b6fb3a15ede7b6f84d6f61cd19840fb42efba82c737c0665d2b0b3e59ccad2e25eabda749aa5c6c22c2166fd798fc34d7a62d08d4ff68bc7e244171fd2b578c9567c289ccab45b6fb5e205227d016bb5669a999dd33360cace216826451e6fc0493d36f003f946395af399e74c67935dcc4974f1de3d8aec0417df36720f22b3363e60f97c3e4291459672fcac2bb57f74e5261637d9f23b34a300b1418c80b00fddd46848d0f1cfa764e4b28ab6ff37023e9f856b3793344fef1536c9bb7fcbdc7335c098984e0a88e37f7c3ee1bd9322e1f3f171977b42ffbc3b323d3ff893f86e846d985368500797bb5791445c7e3da8abdb787490ff98d5553379dfa981bed23e031ba41cd98c71847183dfb59252789e7157fb5cbc83ecb2fc96f700d41daa4a619d7970ac428e6296d4fd0db73cd186d896c2cd032df3cbe010482417fbb1085483b19086796626f29af4d413e573dd6503f275d01b042bac8daea77ae155c3cb040d9e5750df027278b0be188a12423cc19aaa001cfa8c6e5ef3d30412d3b17700a53f9b73fe4cc85a3640a4b8f8ade3bdb4346640f6a7858acd0c48cd3a89844b8ffe8f30e4e9c2e0937bb0522771666ae3f807fbf8a4f59c720eb425b82ba468b4852b688841229372e4281c13b29901696af604523d88372a8d85bf0e6d4a92a600303ca5e2da7d06a4c649f8a5155979438b1116d1cd86d378b06785b0ea85f40f93954df4645a8c55b70e08afc600e7ff41ee3b3fb84e81e5889a0ebdb27fba47fd4a45f990bf5bc950572a56ec3a90e37202e1173e1ac836f368ac4393e6f4e7c9868916b468c1065946c7946977781141ca1e78ee53190422516b1ab2c6c8b0836915fcee358dcc2407736f5a83ddb94f573cfdc3e268ffc4bddcc84796807fe1d6db03821104420856aed1e5819c123e42be8620188e45ae837970fd13995e881c2d51040a6b0190296f0bd41355ab4004288da84f0992d06c69b00d27de67e3820a7a982ac2f9919e2b01e5caa76bd6ccfb5a01680802d686d06ffffe4cd66bae36ecb490d22048496119184fc87c7e9d41507d02f7aae0a061cc6bd7f5022d0afbe500eb8c18afd6e5008d1486f8de388b572b3f68d22b647f5a5b52ffe062c92d1811ec24e7a53220e1a2b86f2117c8764b2ad864419b1af96663fb602da82323743112f43a1c0bdf16a7a7f436199ca09d91289f633b78cc4bb3b354c4cdf4570951198984f5a5ef04260d4faa7f19651ee2bf6c3b42f85f465ee700303b054c883d6014697a2bbaa410da5ffc90581f3243c63196824497405429882e7a922f7255567a0928cee9871aad58e97c0baf985c60006bbed296ecaf163d2a1629ba9e2592bed94caac655d536ce4ba4c56737711b679397973808a3b0f0405f485effea1c4c6f418455151744e36ff0882ada6e1f585e6edd6ba7cd72116e12219934466ad70907e21cadca50e81d8457b3f0f8869820f02362321b02c65ccc358f9f6554ba933cb825939acf1e4ecb9af4362b4429ef4f8270640d55555e2fd403253b4ae2460650b87482d27415e1015860f9f1bfde1c24ccdd5c505010d8ca6464849b75b0dd58c57fc3a26d07a8ce62a6a56ef01167ead43d30a0202533a435a9a86ef93e109888200acae8f7913e7073ff16345fb69fae1202c7b55ad2c465001ac7a6e48a8308a37d996f9121ab1ee8f727162b6c8046fb5aaa3e31b5670ed958d1cbec1e41627bbcabccd703132c9cc41b4e9984ae07c90d46e88c1c1f0136a40d47dfa4e32a05a3c04f868681fcae51d16df8b159649f7e97c27296a1e6f3cff1108dd23fe55ccc6ee30223bb3980a9c418caaab2231832d71c63f177484296e74c65c6b7029d05f24a46f3064f1007c861c0a9bbcd30def40c60c7c09ed88d4b059fba13d012d365dc6aeaea94d9a5ebcca2ab2a8c77e6041ba3aa902b0086a436a4c8180af16a07591ab2fcfe29c7d48c04d2d1a86c8a4978005fee91e1a1f338ea33d7e05ba15e2e18ce167a36f8e56b349d9072e0268728a35a600247fd96bdbccee937f1ec099ceb66273b361137bb60b83044141908e7054a0689cb07610d2e18b9364cf25b9c3d847aedab73c02c918ec89dd99c72424666e21e13f2e1c193fc65f632aacfa305afd55c9d1a2c9c6caae370c088f776007a8d33653170e181e8431b91fe51c3d1a3323ca67c1400d51dadf386943326043a577bba860ff2bb62bf8383f8735b3d73c7db0e7f38509af1e092e967a22026ee1096b3db287fe82167ee91a8304229cd1aee85ebed7269d07e38ef6d178ee7c3d9b670e968d3c3af6ed9f04bfe45fb656a90d4cd573335c871456503065135f975969a2ff1313d6843b653d8fb13a53677b8198e357b2e890587aec051209339b482a6601fa984f4b95ad1cc502f1c2f970b06b7c3f16ebbe0281bde168b0b47f6e15cb15f3aa419ce9ae585474d0b1f8c5f8ea1bd0391febc548b99ce136c18fc34266725ec4be127b4b3b5d574e7696cee1dfbb6bd64181b8eefbb0b865ae1bdb85c18a41fce4bdba523d970b62d5c38da74e1452d51ade08d9a2bc2ce981c5a2af0b21d81933b44462f1667836e2fe82d64f45658df1cff77d76f284681c1f0b5d338cbf13d238ad17bb5c2cd72491bc7b506236591a1e910bea79f8ae72b018e211860901fb1abf85a5bdaf288fc28188ee3e350220932e650320ff55e8c11ec47e4ca371f7d7d36fb1b5d18211d54a6f322083aaab7ee66f2dfc32114e05b2bf634d0da280be0c7afaa7e3424600e98554413b9fdae10c92ec6c855a747d67631eac04196fb352f530879a14621e63cfac0bd746dba23f96b48103eb8b7db116de1ed61843c012cabe5413269e46ce555c180b0ea8cc2899d719e974934819b8fa74ed413d8309636bae20ff8bdaff9ca25e1bee08d9faa6290ad75c5a289e972abc1dcd5914b43fd8b257adcee3245338de47b2d259fe3f5ade6bfc33ec1697f560275785182f47da2ed3e68cb265259b298f1b3de1c8a618ce3ab4b7f557203115ed2ca05244e75c4483d99ad486a04dcad1cc91b02b38af2e7eff02b425b80ee80a842df5ee2d848ef80d4e2763c7e412921568ff5745295872204d941357b5bfcc9218ad3642d3c322f09356b4f647cbd8a726844a9c1965e2dd566ccc9d15a4542efa60341a9211ed595ac82b87b2a2d2b3aed64f3de76e01d4bcbafdda3fd16986ca0eb09833a3cc2fdc308c9bcec0aeb69947458930d222be4a9ddb3d7c709a1d4bc0102fdb8a93ee0a1f96c1e11828d7449d332a8318c270c3cf22e8a675ae761bbe23ac62a559383340292bd025c30d7b94b2780e94e748385745eeea00d6469a0a4d447177a18facadda0c46b5dbd688d6a644bd3f32e8499c751d24e6ae084ee0ba98a5f87356b069989359ae63da7b79ed19cfaabca5f677231165d9d62a6ccb4e77ee7bedfe328ceee3b831070dd0ded8a2a462563d8adb70b9ed6ea0efa34c389ebae4b07edcea3e16904340a40e2bc3f0933e03a3e0266cfa85663c1d0c43a4c7fe55956edd7caed2c8d572412ec71f19950d83236917312ffdbdbe1c080b97fe8f6866df5a533777ceb3f7bd3d1bb41ffbee80d682d37f406143097b1c9c705cb2e2b9d1c3d63fab3f22d19dccbd0331417e11cf980795341609d555205841846617d257e6fe8902fa1909e2d22b1d09ca2ed0c5d361d2dd722317822e1f1c4508535cbf07f54d7fb0c1d4ae80b0a678075d18153acc110c3fba4885c7e4aa68c0f35552c8e0deaf37750f802cc0a6d915ba2f6dd66e319915fab17b3987d34ca01cdb23dd831a589cf4c83802b9cd0b0dda2333e871453c329fc62e305966a55d315ad538ba4228ce4bded6b5ed2fa33306ca880c03ed0701f55ca602f84085b2d4b53e8859f7a0265b85f59e623f7075d5a83399d6cec85c3a810c56a339dc8a35b1fe885d4c904b189a0773fabb9506510f8aabd903c1d10a931f8be33012925282883705419b1f8484f4724b44bb15ab1a65f6c5f9387405b6e084001cc5afe650a0e3526c659a5fe607af0dc20905a48b208b1a2bf692641e130ed8bd8b8fdc3a1a1f4c7da244495f433115b9f07d45d06489d69feb5febe9bc23a06258f54702362d4f04af1d9407eec749b7dddf150588abb14d53f114164cbd89a1d39ef41572c489861a7cfca8f502946da9242176d189247186fa453a002033261710509fbfc8b8f8e643cd832e03fdb355adb4f912db9111a24821727b34788e3edd22e49dd23140b2789bca82deb3d3ba61a38d352274f9b627dda5aa7097b0779e1ae3ae10043901e41b457ba27d5f67ab17846dee4be4cccfce3d2b39cdb9017002d1948580bb5059c5b0f2d69cf2dc2e5f671b850c752b608119320708fbeab3fbb6624a1132baf49c4663e9311618e7c0c470a40f819c5a90836c3a847c48b684b3fa162e6604340969bec3fc82f0878d81e909500bc7b2f63461469e11f973aacc00a785bfec7b4d71bb9383797dd8d1c50ed100a2b5bfdb6943ab0fec578a790866d58a6377ebc503f5f24cdef1d7eb0611d08cceff9f229cb1b32eaa26808af93bbb0b3e443586d02f1b0777ea992bf2d631f046d9bdba010bf81b703b57253eb9ba28416a20f393f03c3d3469e26d7cd46108ea0138a2827870631fbce542c94c57dfd4542b664d8b374daf9b448d4db0d9cb1ef7a053fe60053b0fbee6cb95d1f7bd45a4b0836c387379a7d53757ab9d86704df745eac13ef438b8c864fdae10f872e4185a07744e7a6c1eb71beb1f9718b1c558d5e4da70d0460ac1082434444cebb8b35f2bc9661f3b58346448df6b37ec29364e9e914a8a2e4e14d99cef31c6bd2b0b99daff26f61afdcfcfbb1f3584012e97b81615e9d22c177e243f04d98ba02428ab825af0ec5e6027b13a934b68d83f6046e2a559cbb8c9126745a900f86240ca941fb4b5b4a61076ead3e41a56199da79eb7fe8647169931efc599238a7edfcc82b4ca63836cbfb201a1eebba39745c23b2e9df9bcdc9324825b766181ec2cd77844d65ede6d50ecae6a532167d09f02c70d98d55e50ce6e9f911d464ad067ad834f36317ce330c8db48a40244ea4a0cab58186023200b73f34445c212d944c20e9d1e3e101ceb5e3b3435ed8b3dbf0239395a0e66666b07cd4794d1abdf81b51745f75527538a6090e3ecf7407adbaa84821a64af79522c4954309fb16088c51939a27719658f6ae7a8833a2f2887048fdea2dff82a0c4d156bac5fb55d26c2d30d641c8146cbe50eadabae86c141f6e64bab34ec20773467e46cd0e3b5a3bc4f43541377ddf1b019efd1dfc02e2f25bc9be17591b4927bb7066d44b093fd6359631454e93734028fe1787f584fc4c6c8371d14164da3c329aa9a8a01aa1fc655a8a6b25f84e80748237508600482716f70d9745a482ef8de30d46b7fd2983e3272cd2c35164da534137a9da2a327cd5ad82bd31da198f372818e8f241cb4fa5353293e1fae079a664906642a2e2a2bdd12a445e433c5f3b624565ad4b5c7c560c08afb0c9a1d19bb65b45871ff457557008c8ad62913159ded1fb5b85c2c4ae8e2ade2a6249ddee39010af9b7a79d6b18dc56112e325824775cf2f6c5a28be0dba4800ed7b46d866e3a048f1c4382004415c3fbf47a1953978266ad3ec5b20d1a4d14115d458bd6fd0bd9ed5d0441f096714bd0e580e90da44b91d5ab416bee6698ff6f58c5ac2676b593e5dcbb14d8f2ef330732598442e378a022515d8ac13a607988e62cd8464f8058ec2eea8a87d1432335b6b49a223644fbdb1831bb2beb6e151b511acd37aa2b2d495732b11d4a444c56a8dca2652fc93c703dc4f599d832a522f55ba6020574f5c5762c57bc975371a8dae70762b3760558368adbdeea6602a04cc2d4fb093a5ff0b1413543980b61806747e9f60251ae0c30bcd585fcad37782a4ed2e833734acc3052e6ed8654f7dc302b9c7c6147d305d6d76cabd97140e70bf829bc6aaf2c1ff224f02ba6fb60b35756e6a92fca450a18bc99ace3263ab43a079b973dc43cf02bd630a8584d477412a48d3589553ec0dce334227208e02b5bda96b28295171093a0e09fa32835cbbcd18da70d47b771c7a3846665d0abf72e113b520b858604f58eb12282d5d63cf958c0c4ead028e93e2496bfd342c06d05d97c650472b19cf8975409025486ab14bfd65eec73aed7c2942cb32136d778f68e5dac48a3083ef78002667e35250b2585a18e7c5511a7861aa728833922a104e573a130d9b88da7104cab4b6a70af3b993a25301b07986a5049b07d3fd950dd970c63500f9f1e36fc6380f25785f477a312dd9aa70ce90d2126486f718366f58699790334204b6eec68ebcdf971eeaad2c959e9337c5267e17163c2d57bac1451cf395d483d8c5591bc167c439a22de9ef4fca9ddcb4e1aaa97ba680fabd948e8aff9d04640492155f1868442b7ec26e6bd89f0af3b6ec7dba6394473b4e64912819450f1b5044334ab75630d0c0de9c1ddefc33abf39eefc1e343861321e5d0b3b4c40bd0473748ae86c71a361116ed339dd6d99a0d6385d70254360d3bcf8572a89d6b172a3becc7e0644c200b4c9e42a5e82a4e8cb83e39371363866afd942dc9a022a7b0f99b63d59fbb30359f553016a9e2f592a747e95c7b68a02807c95368591d0f6f643c8ec38d265c2d7f0435d3884c09a431ea036a1c6eec564c544ad14aa00478cf39c9b44199f2f15cb9c02314c0138e8f1ca079cd20c0b678a17add03b389c780ff998c0539789eb73d4a1db8635f0ad6cacc2d40e9e01d8421fc1b8aa15c7c93223d4a4610cc127b3b37880f7728d977a20a6a246290708879e8d06d0705e4ebc9012677dc62c645e349abbffe2e90e3de63bfba4b710380d3318e4916a9dcf0459b4061f7b6185261b27f6e96f706962e2e0bed5d2a56d4ce7a6401170c1de828ae3a765a6215b757570bed6828ac6a5d5341ac414cd03d532c1c368cb7a58697abcb44c9771b44fd60dfd923550de2892d95d790674a55be95510815232149f341b49e19a04d565052261d8cbf0c2ba04e9e3420d1cfd95918ee853760a7f1faccfe4c0557677d4cdad92d0e34c48e12c8886f70b8034ae6501f38057500f4418fbddef0c5514cd4f45d5b423639021944bba40bcd8d77196e3e7d6d132d025fc72d0b9a8abf7daa939db0939a2f7dd30440971dba74914a71a81c12d6006e812acc177e50f8080d0eb7c5e58824210088a4265c9fab45ba1181fb3cc9910e02398d0ac4bc371f16748ad61f929e8133c622b14d1c71b5a43b7625304cb4e4c039930e962ffb41fef6aabe4958030b4ef2d220429991b8b4c46df57acbf739e2c30b1bca87a829549b85f46e0435bf390ede5f7092cc5c72b64567c8b339e09a6d11ee40d184333e168c97d7c72b4d4c5e6f839edd71900047ad4641c2178720b8674e4f00e4939b41f548a044c7be8d76ab0e5133e2fa9e818dc0521530c0c06fe135717c3835ae1c0fd293101ead250ffc31fb3691162c0186a4cad23072571507c90ddd80d385e9e69480bd4a814d8335614d1571cf7860faa611b646143bfefbecf8367343c815fdaf827e0d4c4262032eae185821741dac8c34c398107e1dd92759ab8c61a234402c804f19e21a83f8149e64c215d86e4838109fa0e575c002d9e6051ee0b7c4c6df23d08e6eee002c1d690360489918645e06306caa64ad3660ee4ef9f5ed75d8553679bf84e25c5707446c3ecb775b920e6fe72bedc4167e9ffdcb17f2e34bd48f0f7664ae4448a0565c7dd7780709e2f2e2184401e67195ac04fe6afedcaf93193bb1dd3531e0740acebe70fbe3704dc9dc223fb418cae6f57901e76557757da97087aa0c520e9f6fb5ed682d4a3ebb80d4bf7b0511b854de895e454a7941dea7620582d496870ea8d6992e7b6ca795f2556d083bf42478e88ba25aec3628578ebe5b86ed0c58c4ecaf6526b73d36f593927f1b20edfd3c3dded0550aedd294530fbd929120bfd67420261bc07e89a8220f57fcf46969027834b1c3c042c581f004993489e75e04cfaeb9d9b151f7309cb15b160c14a6a43fd120fd66e5193f46c17b76723e90fc8ffb183c2f66da3e88bc38ed0a0339c7a66225c22d6d17f283de92d96e9e263086c7829184cccaf58c288ee0e671cb306d748d2dc13dddfeb22ccc738d8f930eea1b4226f5a72fb493b07acb81f7bb2a89b716f5e3bf497847670b15a0dd15f440995f1fb9fca65fc091672216a9f931aa465b289e4492e7f9466408052ace72cfb68a27dbd268adda8b719bdb68b271600a85f51642ade3ef625d1c8b494405c4d346a777697aa3c866e68602f67cd1c9964261a8f60dd021c7292d6298ced5ca578810004604d00440b1e261676748b4f1a0a78d81894ab42b9a34935434b822dcc991093a4901291d3187742b4b44558c7a4a47700f0715a4218fe41dcaf71f1c346d2b55cf5a6a60c19719e2e24e092dd5ff2544f0a6c46124e0e124c3773ed528a629fd9dcf17a02deda19ae705643444da3f5ccca73e3a326599d3e8dde9521105adfb2224e6ad60efd26e1bcdf411a45b9880e8f4a97f64f3f5e8c2a8ce9131c8d1a7a0b75c539c0eae5c853180fd99972f6bf5bb60677d646012ae004f573669c674f2e404133200681339df575f55bd9110ccc879f8ed951ad44fbb18246641469ba32f8ab0c066c2196b4082353f79fd6c604335f1935c590ceb75bdc74870bd0f5395c4e0f8e712c6f7c0b11bec4320696b18fe25c84fbb7e47f506219a648acd39da4a1d6a49d1c41ae92e4086576fd88eb0dadfb5bb216cef4dc4c52295f2c1434fcdb4dd09a67b184819494a5586eac33f401257933d818e0aaa009f97555a85b184d0ca2f6a422dc13ad9e066555f3d8e23338f653ffbd0b43946a389ed0c4fc89176a686f89a1871976d627d10a7ecadf1ae675bdbe450185bd5a42fdf076f20e91af6e7178bdfe10a1ee5c87d3de6eef4e4dccfe733dd803e4eceec8c8ed39052c9f79cfc912d0c5b5072eec24ca590274e31f4dd8a83a824cf274d8da3909a151ee4b11bd0ea3893aeaedfce888525cc098b90138b1585f33793fa67c7bf2223425358e7027669ac4367bf5835a83abc2964eecfd99560bcf2689f5c0eb8dd3d0fbb4c74bb8bf8b12bbab9540de1a09014a3cded1294ce79769792cd052a025fb564c90f3e1cdef235dc37e681aa5634dac25e8ab7679135b04d5fa9195b8b28c55b2308cd843081992a52192dc999ba1b6376be0cddc5a6a8e16b555c812b43cb84ddaf988d92882758c527ea1ae3cb2e01acc64ced5e9b2037fa76273b8849e28a89a887b73970c505e42ff95c9bb0377cedf8072d8e2d2546d2cdb0b005036940172bf43eb132596eb23355d43eaaa19f387b69e2802961f2b772a609f04107a150a142aa77af5f68f6bbea155280e73e4b75fd41c8bf61b62864a49d1e6c62cef26666b1a7b4352583e45d67880e1a1b146f146a5f35f2ac7d1d7e5756eb7733a244559f518bd3899e23489d0b38cf1bf6d81ecbac0280b27dad408134633de3b5a2cd0ae52c52e4229399141b46888f3cb6d1dfe6b6930c3f9c1472bf6e29098675916f63f7a7e8654fd78135752d5e893710b9bf09b77608c34e01dd3b37e9342cf6a51899b6acae784da5635cc53bbf80d14eaf5377547a1c98dd25332a5e6c54cdc791bfd2e9b406a8434f32575db1ee56188aa5437114e12856dd99e0019fe10c9097799c57c7f3b1e5e332838418a24dc6451f274a0767268a18b2dc1c620cd3e28aae0f4117cc6048d53abe6c7c37fc96a13194bbe93ae04f7ae21dafc11c45cb6149e8f521fad7db9919347a5771faefd8f6535278cc4e6ef732f0d44e27e2b358d4c32b1b75f5eedb2ba6a26c9b407b8fb0c04ae9a13e93b92d4aebcab6665e8a2105ead91ce49b208fcc378191943d8923f631e0e27f601d19992085bbf73159072a20b252d5b87c0487b370c27b192eebcd7868a39283bd1d39c5afb2d19a9d8cfd767000fa32c1aece062f9f3d16b1ba716383ea10a459158e37613af9cf19352a9b85b15ba53f455aab397485d73693759640232bbd429f8b49b604bc2fdd9eefdc2b1c7ea1302cc3f0e543a215b2ac3251adb9cec60e835a3091f9662c31c6cbca70fdb0fd5a1b8458c05aefe87b85c2001b08790b663887f3c52a8c049bdcad5ac06e13360fc981ef204b70d8cf70e81375b486465bfdd9087380e24db440a7f8239344813cd2fb5ee6e6e5e972fae8a8254373bd0b8ce58751c1441fd737968aca2f6ae708e396a60d5e40757ce48116ffea932341905e4d0659c33a73dbe49a6a8ee5d5501f69da298b0e21ac461f80ac903055916419c13980b55ac06c39497090febb865c70b9a836751f47889d150566e4b3fdfc4d0864f345b8ae3979fe88346b81b0317abf1d6e5cc97a84432a473747de2545be1a37bc6d2c0759cca553cf7cb67c4f3b30b7654e2c6893fc7b1387aff145c372c32f074a22cef729dcef995222a72bc5d12a9740faaf62b6a070fea3244335a7d7d2945561d38e088df8fb1a7ce7a7a8fa2163399b4b20d32f8923b2985c172bad3c8d57c2bc35618dfa224f9f0d8bd807c8894f3198f2e4970edc333a0165c124bdd8012fe66e89e8b76f930992cbfdc0a2fe5c389cf3e253fb4ce333ecd830a03b5760298d3fa658cc6e9d8d52d4e91b3ae9790f896941595528a45620918c10a809ac1d74be4c2f95019bce61fa9eba52301b6aa45018a07309b95bd3936ad85f8857c1fb3109bb5dd39540103ef571f5c65bcfcff6549f167bae35f180f8e6a318c52ade95a7d9495009da51b6a6f98a3029ae36c353febf6cc367a092005ce96f57b9c33a2704430c75067531aab73c9bdb86d38e7abfbca6ee140d7a80631165ad59f81aaddbe507f77e5c3a72e69cabdc95fc87000ba52548e65b2fad3fe0c133af8d3df08eba4c0e43320f8f0e043f720f5bcd144f4ded0b2e768cab13b9824056205646110018fd82c2d0e6b15063d8bcdb21395deddacd9ac9da4cc54191aac20d038d8b76d23a21b045f6f5f9f195cd43ef4d92858e791779ad69ff9f713c9c16709674678bdb55273f30a5841b4b4c34aa63b7549e9ede176c3dd8b717ad378c3510b745a6d35a08cc11743a5bb5b4b708a087c7a4ce5ac038c3266b493d5d57df81749b2d5c8693fe9500e431084b3a02a4078c63b3c87aeec3b7b73e65e28fa53dd9462bfbc8504887cf476bb917067d76830fb03e48ee9b0403e049807ee34b5186b61e1147b2dd80f0ba6f201c5a6c60ed4034bb965808f5a8b69794b11ca9cf0b94ff293cdf71e6322c32e5abfb04821c1ac21541156c32e2bb3fc52216b1f0eb246c89a83c6d4b5b13936f105724a1afbb612029980db6b97be9a5d83ca49f1d8a13611b3029af558230a14782b7f8311652bf21a797cdccc49f8eb16d4c2648cfd1b33ae14bbefadd314d51735e3d0b582bb573fcb8a68280cba327ab68c577db85b85e5deeebdd43628f70af0696e5cf973ab9ca319f2954cb0ca2ac4f028627d29cda5145592c1c27e45f667e27652f17e8e845c75a63314f4305ad445e4fab1f3ab3bc7ef2350b794dd752e3b17b1143d6220eeab0e43aab882156123675a8261519c954970e3cf206b272db645486cf92345973e1d1e6e9c87b80f708d49315b222f85eb6752d15006424a4c7e49e982575bb5d09feef2990bcebaddd0cbb8ce98866687b9505897222466e9ba35d5500d01e8456c3154a31257ec09e544e6e6a5a261774450a0cb01e869e7209ed77bc70f3723cc7de781da527cf20e36a5bd2ed0edc89d6ecc1112831910823de85df15e91fe8230913a0d207b20de09aa352eae5834bf10c72faecaa7a65f52f66dd0d88aa44270efff23a4bb3e67c76207e43a4ea1fac905941ba480196f3b3b06a22928f6d83324890248801bb35ca406bf9d2582366594c11a4a258261a56785cd7f0289aba68d12d2e5157a856f2c95f020b5f930c37d12371c8a7c6c37d00406bee5efbc8a948341fbcbbc32548c1a5432d3a5ed338753bc2df04080656b66be586c636facbc0a52b2f90d2a939237a59e6f44a111922f1999ce641c6cac1db04b4579746573acabdd6648d57a39306b65d7046d601370f1034f64288d17bad1196d9dce4d8e25a2ac181b4612ddcf4a15f582ab69630b44947578d583f1d05e2ca81432d209d91879c110c7c7ccc0086f91c181fe9b6e4f2174e97a5f48c22d7e3e4191d0e4d9fecb8f5cad25a4ff07b106f9d23f4d70b21f1b82bf43e8118b40fcf94b40cf633e7c374d829fd19c63ed3bdf6bad410c7623409c0e5a79e9ae6b89bf84f61d140b8bf793df9571271212b6d4418f2c273a0cb48dab1b15faeb418324fc54530d0916e90d2bd77488e20da0cdb6b4829d1cf9fd8a2d30f0f1753e36368d3bed48128f8792f97ed6779ba1bb0c369994e15b84f7c04fe02e0dd65f7c13776fafa0ebd8999e97c74c948f7daae446f5bcb5c2958964644c8ed4532df038bc1d1df385fac0b1c789b1678e85ed7ebe994d0541fa21bf390c9747c7be28859cbbfb4a270ea1d299572f8d105df6814f178c40a3487df14347d08f89d2c4e1e3fce6f5b7b6fb05729434c3df73ad7e1ec5e39a752cb4613ea4584328edbede10abfcd38dfdcc5c93460527cac90485a82e05a70a194e3060fc4147d74ca25195514646a48e6410603ec7611c44c464731fa0a52860b023b35d23bfafa526394087938a8aa05b8585ae61d0a1f532bb00d51ab3ddb399bef9d9549da7c257acf402dac872312419704a5abd9003e6aed806bb51b47e30e0cda5b052c3c1a36f4b72f7ebe3f9a1a60fcd320026c59f81a8226d53ac39cdb70f909fce7f4164ce7207e790b418c0252fbc1890fa12f2c89be0622a10aa518ba634f8887f82c6c0c3e42a2afbb8afee44152df4a76a67f9cdf2b57b8c5ab3e7100a756f2290db353ea2e3fb16fdefa2ec7baa551e1835fbf0531be186398f924f68cac0fb22862ab9014b35ff1eb428003ceea78b1426bb39fa20969232a6392eaa39277d2fbcf46dbac2096401b4a10d5a32fe70dd0b1e314a4e0a616f472a943c769f75cf5a218beb511e3b857c95684c2debea803eca0edc357268c68d4019065c86c68e726e32fdc3ac2486e004b01c068fb4faa355073ddc7afcf93759087b776acebf98a8fbc3a15fbcb984b199c4c89d857f3339ef4d7e93a81dd0f5b97fe5997f485996ec006767b050efa0be47c64aaba85cc1ba9cb5b7abccf02d40cf6e2aa846447bfd8ac255cc7467ddd9552d1190c89d3daf9f1d2e260cd641784feaf121d60c277f207a822543e1b6653307b04e8713be01bfe8f8cc6fc82193ade4fe067f09de1a39e46482dd7ed08ba6921583215e3d41767fe1323957db653eb124ec559b25162ba5c8c90c5305d79ec647032f7439259aab89e1d229a95f0b6ee0277bea8ad326fdc89eeae2c4fb62224e185989a133f59a0630c42eb6b16573d1114a912df1cbaa366afd747527320c9d3b631dd9ceb95919120d17186cd8a50bbc906aa16dc98b1ef92412ac4c95339eebb334fe0cd3652612f878882cd60ab0588948b011f20f554722f9ab0fcea97709bc64aa99259d28794d84106b577e4c00a696236b053f41d29ad868c4eb8928dbbb102f89c476d34fb366a1136a33ad42a4c6e65bc5d49d5ff4d7d78bc8e1243ac3cab0dc125e255f77e1d05c8afa37a073b580a8953ef2088375e6c7fe0c37f61fd2b88e4cfc253abb20712acbae1787c969fde9208504512d9ea69b92bcfda3e06c728e044f5dcc3837453230feba1da078a5113433459767095091fd8a85db3ec1eb001b0208373cdade4d0ace89bf0e006383472bfe3b0e5f0a652d339c6a91f7fd2bc1fc46a97cb6fb345ef47ac09c41504614eceab00cfe7f570b01c4f25a8e5cd0e10d3d55b20dd557affa316a779b8b7e42d6395ece0b5b8cfdbea2c921382a4727403514561947b6e85502975c60e8785ae27e532c7fd95cf1750db969760f7dba8002ede908e5a220ed96664caf06eefa963aad62c3cd6ed3ba20a89b97e9536d074d26b13afedb69564773b8b3b6faf28e9888deaaeefbae7ac8edabfeabe873f4572aa80cf6abd37ca9a40e2fc4103a18b4e66bdf02b43e6ed15088bb2d3905fc6633ac82ad47f7d0c9362f6cea18f43dc3f861264a90ecbae135105afdd8932025fda056790fde8fc3da867947fb1f77d8681c654ff535484d383509f17d5c57f32b66d30f112de8247ec4ec9804ade57d876958e9dc198048d3c89d96a9b70c3f8395963a265e863c50da4ccfe735d16d021edeab78a0efae0f5b0ff8ea3f98954354a1c6928d8bc4446d9b92dd6a6cd9d760bbea0be709d0bdd8eaea632bffe73bc296c6634f5fcadf42ca7230f76a420ab10dda82839420cf71784d7854c37e63f9fcc60ccbcc39eb1d84c0578b526641c5d64313a3274967c53014829af8db67040008fec3512e0b299ad3c5870bebf5b04c012d3ee4c2c44dd23158b3a5d8363c0581b8a4c2804cbdeac4ee8cff27e7d601fd1a8e847587647c3db0fbcded65eb384b2b49507c4b0973925bc794b14ddd8237425e9e428b7aaf8d956243b3c0ee60dc8380b9efcc34210f6518e67e773ae02985457b3a6c070a08d0c733b6334528e2f116d7e2557fa9c3d24b731cf79c40ef7768620e6348a3e778db296f410abd6dfeece86cb5b65e9d4d052f044cce387d1788e4a8ce2598e63ae74b550eb7e1da8221abb3772fdd3aba8812bb2e1244f980a6660e6f1c5d6c553ced3fa5428602f7060183c8946a77e18601265275fdebe8028f8a8cda54af60b1060136f2d8f908b5d825689275de2bbd930ca211520c39a984eac51c3bc3a749abff9d3102259fa9e1d124590066d11b27c42fcf83c26eb8cd9ae7184d31784c190d44c6ed9bf4ed696b1f2c3559687ad34c9cbc49e62db3e0f16622519fe53ace4eba6e5bb4022c42abe6dbc7fe1ad8e53595855bc43a2d34e6840a04d10af48213a095f2092757ad1a1b0eb3020cbeae0e4f73b4f0de5ac17bd6c4ab54b4b41592cefd0ed242bf0c6e272bfb08b43f2d5f63c099134c24bd2abc1b5662ee0a900e720665511f27115ef47c8d04a742af5d6ced5735097b188e67cf85c1f6fa6c712c0c94685cf0aed7e86ceb46f308b6f7f8606bb06846fca7c5e32c5ed4ffe7d612511da491350e6aaae0dc52d70780a22101f783831bc6152e8352e6a215f5437c430aa784bf44f115ac21099e973a5e8df71333fc09ea1593b670a417b51e7bd02a8503fb7113c2b7fd449c20b8b6e7a3f9e12fe3f211f608840d018c95491b2114decbbc7798abe2c165125828d18a829bb056c1f700a6bf8a89b2f4551e4ef3f5206d00b4c667d52a45350582f7c5651ae861d27a724e900121d547f3289db3d93683ea44591bb790e6c5c8f74b23b6ea3619d14ed91abc878ac77cc23aeacf082266986cda4c327bca3033d2cead75475a1ba5635214f5ff44378371374c5cb962f285173f75e18799b55c61f11b0b06f572f89264ddabcdd7a51806e683f43e6bbb36146bbf107e47a5c9a88577530cf8933a7f6745962283cc01cfee0d25d1b713d8915419f6357d8bfde5c7b95dca379fc73d6f0b52c4a55e08787bc6393467f715e16d51e957672c63be7534938ecc20de9604d86dd56a691d74e9d998eaeaba0892dd3649e61535d86c5d915708adfa5fd79fd33863c2f44c862de8a6306c8f7aced3dbf8b5585d4221205430b0ef84651cc52a8c7fffef87ff50d3b619f90d95b8f70ad38ea85213565d28baaf6e9a00af4563c42aa1259a2185d5f339100c085e9772114c2a6a9649ad8c0120fb1be881c3e41a8b562adfd63f1d302b380413594fd4dced99ee68fc70444162d56073abc82fa1eea52ae1c14c5e880c9ace1b4007abbd79427177b4882d5ea0bc9c1d56e9afbed17f2fead0db44aa544e00312de62a10b1c273ba1df477156e10e9b53aaf252c2e63c065782367e7f4831110f5bc0ab95e9b63a447eef5570d946a2a6f830a55de5472063d093dfda94e6576189b93ef383cdbc3d4a954187bfac50a932e44b864a465ecd40590fd0126142cb123102a3be70bf7271da6835e3c62f27f29d1f60a44f0081658a839b432257774c46091bde0b28269f11d835606b15871dacbe3307b0a235fe054b7669b4f493017ca0f057d0eb50fb2c9919ad6d3abf402377de9a816050a7a2e0390ba17c63b7db4eee2e7bb8e2c848792ff450fec54a42850a094e116383f2c340f27c0c433dd6c2c725710a81348055e72cdf208b3a88ff001a6a31b915d19df403d21f61e3db6fc77a6804a8f8b0863d4994504224ebef73e2f3cafbf88091c1ae2f015f2e5dd76f63dfb95f1ffc219e5f11191433e821156fee93df35f9ee1c6f00cc9eb3bc3fea3170fde04a4dc95a12ad2164e3c3a2bed0922e4564976554342fe73531c14c28c8469b3aabd8e19baec36885cf202b2225ffb0b89dc042453eefbfa3b7451c3459cb20df779b9fbb19dda4d242f4a591a52f2c3a4170c3e054cac3bb0bf01b26ac204269e302d70dc1daf2774a890c79a356d7dac857416dde4d3b1649bf1f25448028ce4ed393b7da145d3a20807287c89c17cb8180a5b5c282b1532b09e41b8930ec7684495966cce0a27d64c74640c50c4bcb0ff3f273185338f2177cf90d01e5cf36bcfcea33cde7ed3a7098f389b19f7b87a0d7c0bcab9a934c07875b98d4de690c5d2526a078ce22ecf9d8a34f75e3e77eea922b88e897884b8161fd674e3a8895e4165015208b18a1217686a637de0c8906059456b4cda72ba00debbc7a82f0867f08945b2de319b60f479121e5edd4d0a18e80a1620eda50e0362ef2fe1e58d630b03878d2a51043f9b613d72a4ff7a7318d33cbb5abaf8b607077a5e4a72e9eab3ea01ec0445d6e4a983b24f198f43e0af8e82c33bad35ee8407a7a8d38291fa1f497f528c0a6d43f290d6079103025f87dab7483d46510f6ee61608e0af17caa24e8900532700114659c4f4b450ae2506cacbb1dd51c91c158d706ad02bc04c8c9ef748a2512d66781407b6980ae2395336834eee7e6395aeab73c2b0ea222622e608768798287aa5f460f6fece1c1a88f09f365fdadc6fb5a44abe986f4ee804c14a2d598b46de1548c2b5a9b635be83298b755f4452bb365ba3af95eed82159001647b58c900340fcc87dcdb09deb1553822b67c111e28d8be7e246994b0580fb17ddd6448978724a7c5a70fb8d4b5f27aa8a8ad949715aea11b3288d83257074031b74d3d1f41beab61feaded19e322689fe91316a3aea827ec5d2b1d12564a614784d4a4cb40da7781c3f388dd0be57f939208b9d46495b7ee7121006d4fd7b1ebe347b80ea89c46e1343506695d187a1859ed4345b3dc525a2d7a7b0d2a17a351c160a7c904d50c293857aea73b43b1c9cedbfaaeee591dc26d91df66b9ae081fb29f911e575b9134a450f83c6838df73b6468a2157d7c474dc23242674cab869e477d1e17c2e65dbf2c319c50704d3529860383468de14361f97813372047ea4608b75566100a64efcea12f631ce118a2909ceb4698b72db4e44290d82d620a88b33f3e973c2926d3eff8a36160dcde0bafe054772ce8d11628e3d96882205bca4373ae1c750c032ce8cfee8b43b13dae360d6507ff5b1a8a0280fd11e194b623228f9ce3f47c19cb05e4bdebaad037e1713cb0e431e00ce0fe7ff5e908a4bdb10f17ba2d0df647fbebcdb36f442b836e41807bd7e619a02261e007e370b5e310c4bf8f9fc740d4258c0a1eed554bf937f5fb802dd600d7d45f4bd09bf9d815acbacb2530e23368d6545165248cda4866c0dca03f70db940ea35a53f82a968fa6af1c7da49942c811b5a0d929a170d1ba5103d080e7a58bf64080fede3a9c69e6d82c5508b1dc4ae8ebd0b2639bced0ac60405fb90da989197eeb68f7095de636b28e54056ae285d56f2ecacd824ed4b02146aaebef801257b0065d2a36e3f33a87e92b8cc551eda42809f2efea002f0494f54029d6d6a5e93139822ba1c0aba676897c4ac1d8299307205b308c8ff4670e131c18d5de5406208cbf9923a37e7fe081f05cf880289d9676acab028e50f1a72f9db1f3e87459685488949d0b6ac3885b04475daf5c8aa4a97b8fd978b4232962f1607a32035544b5f86d28e9c04759fe532505ff89f9095e878d220f1415a2587abd7476515e251765c57fca0abdc3379f1cc70f58fab6843a37e014436aef9ed16e997f183d47206247a4242cfbd3cf89e33ad7bbc8b60f65939471f3baa816c1b4a2160394a046507f5b80bb98c163298f79063b8acd69f18cb37547a46156f2b412be35250fb11cc1a9600ab4f50cc1142d0a3136f84774819e9569687a698a7e2af5d1a4ae220a3a651de3d7f0d3acb57f29926c19f795ae6ebf5119e867fe3782c813c3cdea35cc8713fe0c9489cc87e1437434d3ecfe9560b6ff41ffb09cedf80afc8dd01428ac4d2b7e37ad3c77de7b7751e6f4dcbe927b9654020ff89c9406b530e734dae32c318871432185b2a69d460eaca6d91980626c11052dc6339c00bef934dd882bf038f511fb119a6394a2f563096c53ccb33218b29a32159c43da487dc7dc317b07e283d95701360ab0a853e16781963aa69ea606597377878b32ea33166587742b64c81996509d0299197b943a9cbc4c22df2623d21c89e3122525760b3174a6b83adac18df62e185595cbb24946cea8414c4c2911b7d8fc497de79de88c3d90f8cc9d30b1b54046dc11db56fd0eefc7db697be8f6132269be6ed9e7e042acf7c85020c0dc010b8dfe68732d432f0f3406d22f725a0e19944833f5e786921e287aed3ffe22b611b3522e8160c7a69caf6a3e41d81898de4b07f3417e6cde0a64d6803c6907e1cd7800bbdfa770198ee0f11bca5dc65bbb7c9a912a896a4055ea83905105909eac8e9489bcf95773bc834dbc3797548e7721f74a8872f0888e4295801431ef9dda852ac8cf6ced38970ebd79990564e623376c9b315790273aec73349af23bdbd759700c15c98c4bc076d88c224fdc5dc17ee9bdb013c787d01f10f9f4e5a6637be980ba413ad5210456633dc0157d4cdf6c09ba6647fec476f7b9ce6be179ce0adeb9c9452593872a73cd4c785d5b50926d39d89fea73ac6ad27dcc5078beb69394cba4e0715708e4080a4f50d453fc27b7cb7ccb7fbc866bc89ad224b247e3df80cf0573ecad8042bcaeccc420cdb2aa9e553f7e80d73195dade136b243909607a827db0cc900ba1f662bdfe5f0c184e1f7080359cffa39b24098e9c6c6ecf4cacd1bac47df144c992585831aaa53587adf69ae6499441ab06310817b22d8dfa41a344c1faeed80eec4dd8ba9fe8aaf3b7d17fce0600cdffcb7fe387ad255a3703f3d132977600e507aba2c9588ad8553cb82fcee414ab29a9d80e293e58903dc65fb2875400a266d24138e4941af382391b56b375fccc43b2db850dfec18d1c5248bbb17963e40a992bce43c17faf48503dc39203a2ad145641ef9c5efcb1cf2a733b2474c257dd21deb751a7329bc6de6b3f453f7087ccf8511388a9239b47ee194fb39a7f02c56e58512fa9a41f05f203f1800cd97fc6646c6a294bc1658e3257bc11e7050b11965af9c3a5352d3dc0cf119bfc216bf831279a40ebe690b965f5395e24fcccecccb86e4ada5e080fd752049d2f1338d61290a982e12edb62e67ef138b554439117272e3de858fefa969fba0d9ebd1c81fba293ee1f4aee8a2cc47768aba692e0c8b667e62c6c3e41cbd94b01b36a182b67ff555b089fdc5d0c078a83f68e4683f9e18ddfb738f5f5234f08ca25b5f861a3ef0fa0aeaa6f1570927e226d41fcc049a3905539462b82793c02ed83a11eabd834258d39155db81c824ad2ed7536fbaaaef306972000e33b6054f50e9558c3a8f4d86b15bfc5d17ca098be4138545c94bf4f990598eb61a836e105cb73d4d8cef1f50f2dec24bd93dc17c9f12874e6be56b6fc1b538feaef31820c8186070631c460c08427d516dece4a8054c0d108154efa3789a33c3db2122de13818a257b8dd9b37c9272ad5ba2510c8c518d5d0c36427faa4947065c5a27bb47b02e3e6b1a1f4022d82aa3ef332c15120d3fb2728602fe3d57b1b95938f749a2d2845fe5d40c0a0256f35c402ceba3af010415a9005d0ccf09e233fbc188e799eb76308a037d058c58ea02f44df7e1d22e1cf041ad0c23325898fbbec266e5886fe883d5d8f56a55e77a8def3f79d976cd803f6408ff74eeeeba401acbf6749b61d45bf2bc6f3e693d8c4b7e8d823d8ff5959fc0c4147df075506db02c4f1194c41c1afac62c770e8aa1d9864b373be7fd9b824c7d25cd15587deb8bc99510db6f7ebcd5b9daa7f34e262f919f81a0f038d4036dda163152c5db82594c8b3a9ef498c2e9e4d42aefb3c7b84845e03dabd68a8bc2a2ccf50c639f19413fcd2a84a2b9f5d5a8b364ebd0d05ae606572337dbabafcd615da0f8b3c96976f3a38b627f1a13037e08833fb0f05ff8a189e508b29fd4b7b570c94129d584d65865bfcdc63c029eeacb04a90f0ca332ba7e91983ccc909417c4ee081db59376455a538c34b1371ed4a69b4b5b252a3f5d103dfceef3497aa5c52ea0e3611f6c8803d1f46032a0009ddc603c7b6ddb08694f816bea03b7a94c8ba6376cccf7be21913de519659fe741086feb3ecdbc91bef865b5ee454e5bba5df4b0e98059534549c7933bfe42878bac5e99dc19e8d8ae2e0d02c74dbb26587a99cee70395179ccfc80276aa40051a425aee49928ccdc040fa86737eaa963188ed3d301d03c83c4adf030ffd786d5060c0f7e0f8cf62fc3ba295514e2a073174509c52817a5a13ce4b59a0973ea9d203636f5cc7a954ed97519e974afd0db5fdb706e06806df9035109ac480fb0b5673b915118f675b283600d0de5f17d0f388da4448ca8cb8e250f8a1973a4c64f3350bc0b8b13e8b9af1cf910e3afab46fb08e7748273f27acd7508ce25894f7691f1410815460000c53b26125da69769b485ef981abde578c4c1ba2683f57343834daff360f9e99366e6cf8de737c4747f2ca66730dfd0ffbe921e32f1b0049dc6b186803e7bbe1790808504c440c71d2e256948474c34b55612af4bf14cf5afe8b374ba152fcf318b5b3d6501c0f0bad6f475090530eba4431fb868b0e6e5fc212c134e56f19759f1ad8de3f1588f8d7f879dbd689ca27090d7e35392765e47467404e5401e073a5245c131abb0e3500b21e30b82bfddb1bc7abb5001c56632c0c73bcc38c7e89a270754416f11ca0602836afdeebe9434dbceedf329ad61223f0e59876dc442ce15fe5e5ca8001d78ec4bfb4fcbe18103d5401945b9ef19f373c50faa1e74251b7fa00549ee871e18cbad88c6e1c71733fcf7cd7f265a240929748bee3f3e0e76be22f0cf245171151e2c21740e204f6013bc30050333f7d52d9c0a3feb72dcb7fae3a22f19d5a7de3f8bfad4eea9e06b670f7e7c09f89111bd6a041e91a657de007e83995466d98c64692316b98993b5e85464c079cde63b48e869fc97621f9b9a592d24c86b4eb88de5b84921d5d875d79a40ce74655ad2c2d5ccdd978351e81583d21242de3f3a9e1bebd2c639c9a8d12264591ef23e4514e43e13ad63baf232487c2c7a6015135159dda1742c7e5215cc033b552518086f41ca8f2e9a1ffab991b5b3ac194daab5613cc66fc64028710d4790097acd85eafd32e37c40072f70039cb7036001b3fa105d1704d5a133c13227d7cdc5454205534262b0367b60a99db0657c997dae9dd8aad2dd770fb0b7e2bd37f32264b90804306b2bd17fead0772958c4706a5efb1abce45b8bb905ae47e48fb25f7933fa4b8c0b4cfa392f3599ed3cc5d20b9369a9084f654a775ae8996087df86ddbd9f5ec3c45f8072c49416a1412f2f680e2c6a39b4fc5d70f7e145eb94259efb210b08106005935759df6b2be0613ee8243f5514b3eb888caa9fee8a30efebdd8a7def60508eb17409bb90aa6c227e74ace9a31da11d3a115a68a5e1d58097e4f84329e1890b7ab72d987b53d2192ed07940989aa35b2945d7da7863e55c8ddece4f871d17e82c041cd52d7f185945c2c47731f98049e76e0b2d80ea44bae641a93b21f1cc9b158388949b198e79b598916ec3260a48d6993239e34d9cda57e6c7590c73aa9c16bd43ccedb608a032a194b589dc739e937e625bbd18581c88d6bfe3e0b8f0d643e53313365ce271e32313d4ee157849723acf717cd88314c8c09567e33db46301a5bd772fff8bd4cb84b261b117a1663354d62ae81dd8090ff259081f74fccb53a29892ef438e9a0596885db40e9b7246fe8db47f20a910015746ea89ffc6e66dee8d57722bb65eeec66c59638dba9c99d80f89fb625b81501aa99534bc9765b4ee208857f359d80ae41034eee77c44cd71c27a5c3f00920b4130d48c1a3ea8389dfd9cd2f0662d8e5e9bdcccc4c88f4ff3a8ea80f145adaf40468533e6eaf417bb6b904e47418b1629ff44f31b5bb0327f5f4a1090cb1b11bdd80a1fd710653a4ccf298f0c8cbb3d2dbd6b858210bdf14037d0f87270439bd4bebd5bc6213b60618e1b9651b79b32e62bb4bd3d771df3fa2a917db3e197c6291435639385a8934d94145c1daf540a9d78215aebccc805598ca77beddec3e6bd3ef79eec26ed18ce5ec0b38eb8741a41e34a857c4b4f2bc5e8eec18ff65d91460744fcf4bd35e3ede91df4d0a793f5989c719be836d32db30fc1cf73a2b1116874d378aa0b485bcc7a86a9674b830cb99b5a14b98af06c736e2684bc9f77932fac64d54124c2655ef3d05051585040ce0ba9d070ae0815dac62e31c75399043c8766fc17b020fa8776dfe54bdba58442948a8c7cc57618f53c68fda37ba615fc0323271fe6e37a4853280922754008c6fb2c5d3ecf10360d5621c314e3b592e454410bff2006ca1211d5520cda010092b4f3c424abb8f5e472357037d0a0dc96ec93cafac6ba46d20540d7701b4e2b2a77bd2a58ced4c84855bd308b7fb00f8d647a1c232d138d2010873530526875202e797e1749582a03d2b5f6eb57c80f8843dce53a70e461997dc8a3367fe3e1597a58c3f2b7035731e41ee1db647a51ebef72721481042a1922b0e6be828f6e6df7b09fa06034639f4f15ac882af6d1725df1fca8b7546894cad9c73704ad643c5d700347f291919500ace589bfb0b41eb5eb82c3ae0b5a9552fa496916183d4aa6f441ebb8494aa61c24a87e2cec4ce8e301411d2af7db5bbc986b8d3a6488e0cc5efc5bc80d33441b5dd3732e4d3cad409b21a99e31fff14de4302edb51dc3e7daf93244962b37f00513c95c6f5d039a61e2f00ee945489875a2c2a5abf11b89facc94769c54e732d4dac4086f400d8c85d25ffbfea539446861a60250ba435e1f21f7226098014c0a090cbe65a0e04e2d612e02b8879da8dd6dc9adc4a28150618e8bb32d3ed33026ebe773b357483a91784590aa48aae30ab37a29ed831a8a27e230d68ade89b446d734553fcd02481bcf6fd0fbdcec2b9b53c20083f20e6223d007686bce57d9003786f63849d95cdcac54a65a992cd9a31cecc08dd8c02737a29a8343cdf76ca1948beb31550e6907543273743d238774bd3fd4c4097207ef988a02ea2a4d57f0497b0a1a6aae1a8c1d697da36f253e3ca86cb04cb1213ba7f7d6239629111483154e38ed5c9cf328464d66ae3cc1d5d16a27b56ca54dcc23b35769a2b041a71f566e0d3789b06b034e9c7c05878ba6f4549d08f5dcfc809f84d385224e6edc1db07e56cf818f2f2f06bea74337c16e7182fcbd04450ef893338a79d27200257b6bdf1480928dcc651f35f2c21a4123f79c946b50ededffd0e3de6833096d984f295ab70985252b04ef7b0408d8e6ff66a3b2685cf7440ba13e4a70c42149cf114e4861a14bd1ee82061286cfd6876b3bd79d8c770a2d5c2c21b02c70177a828623619e1be871f9a10fa9a0030ea37afa899e8c3594c12913c60a7434d79700c127422fc157560307d9c9dc791112cc1d9cc7fe7543d34b626f1f72dfe203371aa129d8460631816e9f9dca5e3c38798eb7e10d7b04de6d7775a10159b7f7702fb0414a0dda308d5fd175e58dd133fce9558ede011299c2ab8fc96bb5ac843364604ea3548a255aaa8b78560d0f8b2d69b1f566a27d6c8e3585b382c95cb912900bd09e74ec7772e44683e208ebf14cd521acdc5a9eae041ee279e8779c5b187812350cb1b8e63d8874582eb3785a4f2321d8cf04e9a8bd27e366aa5ad3f0823b179890b1124b82d9b2246ec1accc5c2934990d0067010a3f271778a907ff0309bcd960cc8f10f23646d64365a5a2ffd28d5157baaf9148d7a8e0896c550188120dbad394b495ec8c60cce354f0de390974d29dcd2f51a7acf3360afc875810e932e29b5a42eca0b0bff0a841d37f68d1fb2ea1cdf4ee3770a1b6fd3f840843c85b46dff81bc648a06e7e71b7d26f039563a26a71db362b1fa8ad38f011ede190dc29ab610cd959d2b8e879fded34fe4faba6e8415899a58665c0a6fe67413c9268f8f9b20547c8f87aef20fbed0c86ba1c59e4d3424f4a993b785b0fc3aa3107ce4f5c2b096947e0a35162017508831b55596d33eb0983d032fcb33dbe344f89351a4cddff7b526f3364d9c237eafff650e90f62735e11c19db9f05fdef51bc4517be64987adc7823911a654d6661cced9690368926c4dbf88dfd1e115aee47f4ac0682987eb0f4c37e7c2457cd1aae802820b6fbf17a74b0f9057a27f77de03748c8d76d403045d3c660bb3e81977d068edfe71d4289e0d43995ddbf5128cae78f1b82c462ac1acd05e6c607ac638b97ef80a3942f93ad878184b1fd0b0e44fa1322c5d67ef9d9d43cc9b4dfb126925276d9a393949313299ca279c19a9886b0719a3eea84ab921355d0b5c8a5b7fc755f71f3d1d2f2d737b07e8a8157e01a3b2023847e571f7eae666c742bded7b132f335c5c8e68fad88735f307c6d8e3ab415ca197baee3fcda6c263b6a0bef68012f6dc9e7ebe9da19879091ae72df08cbb1d76ada9a0583ccfd811847316aa6864f35eb1b3231e61230680cb6f9ee9d3d9307c2a73f09351add45bc82629891e588caf90f3be2ea68308347b7410d6bba6018aa5091ac93f938c4bf14a1d5a1e7c83e4243acaca824753db27e8046dd31e6da8d4f9f56d7a1971ce8330592348453fb8e4fd2b23f401ce6a2068a0670019ab7936f8f2918a98732edbe58e3c7edae67d1210324fbb98e7d1ad95529c053a8cd9051334193926e33a97fc3855bb248b8c183ecfbe699a5714f0c4c325170476382d510ee8e3b82470b83e0d87770dcb15896a1d1d36735755799326fd820d78da0347ad77dca775dd63a1880aa7f1d91dbc1015b360b3ae129d2f0b0839d5ed0e6d1509ffd7903da3330ff331b8bfedddbe21e5318c5065a81b63651d177aa5be2ce6cd7c280ed059e7e1ee0a0bec001af41d0b43ed80eb95e696d5f7ab9f89d70051d404efa422ea5dd53dac70fb0736606e4fd178ba6539f0a5ff1e66be737d612c7bd3c1cd32a10a8a1c9b966a9388b3352fc30dbd3ae9aa65ef6b355e602cfe639b2d04d776da42187a23435ba60eed66b2c533f114256ccd2ff32c6500796741f020d79a4ee6298289ffd6164e2295e0bffc10d855272b4bb20996dc100dc656c52e20e53b6bb846a0493b8bb26fe5e03c06df6765576b53db1df4d1c186e047d590470f20f6cf8b97b612c3a1902628715a4be05c618054434bfbe371119a671089e4bbc4bbd89a5a37a8ecf95b63fae40f15b712b5b73ebe94d25a57f2170eee8fee6b702cc663885d01e497837f84db8212800374a5a20a207ada101218d44000a36650816722406ba491ec17d12938f9860fb2d89a18f2043317b64d3f0112f6cdc9af135791080e9bf06bdc345fbbc990c71c15736b79e9b90ff2a1bd82db2daafc9c1b320905191356261659e40222ce1f765fd45c6dcbf3bbaaad7fcb2c624620d40328b531a1d3f3794ee5cd9e1e4d5ae67c079001198409e9ea27253aea0595ecbc1273ae1738fea6adb9ad5ee69cb2e2b3588814db1c8c71f818b6de797d74e04d9017c90ffeb71ba2cc76720a423cb9b7061a334fcabe81a0692dd84ff5fdc99a28debb948c8386d20b842b3ece9b9ff599ab669ea1ace194e3bda9cace987101794ca82e08e9b2a21a3c137edd027947dabf3edc89ed78c60dc11fe1ba27aca1b8cdfa692c6c742cfdba7af2f55cd248b1d38fe00436fe0f9999ae447fa8b2b399128db4e4b8f155890dd38b53ddd2171d58134a2d57867cfe3a2e381966d307501c65e914656d5e511742c8fe1415f0a5e9431e3263e916598bb220d7132644ede25e81feaf93a82ac19c3a03f3ab4f195af06450b38ddc9d990cb135d53c8723eb8f37f5dcddae0472b58c4d152d08bd1a1f42c2782c76b49f6681f394fccdb67703d1d642b17beb62df8caf24fa8c4928ccd2862b26b45c24d03537a2fae1b0068d726e19559d50dab6647474ab424473d4f37646d31ff678a9630943a15f132276dee6de00691d64947c0c4245d0d8cf45d7cb211afa29879fa153c6a3829fc355bc0fdfd890f018075a467b70fb226fb4d51e69bf53c073adbb3954bc7565aaea1c57206cb78cfe361ac0b5a84360176a5f7c693ebe873c8b3e4a7f4369838db4cacdc9d381b6434a24cfd4d42da5ec850749a1cf53d7743d8896e9f40d8d58d2ff72a8c6cb3792fbb1f8ea19f53bef2f2f3e515e3588d6b243059c011e4e2c050ff8440e399f4384276e77911fd163435024a3f0d405e5056554d1bc3ae9ce51db01c706d5140a9629ca6567657453fd1e0125657dd3239e28bb00be5d4bafc935df0c2d2ee84c331b30b0000f61603348eb0009598e69579d1f1b82e5fbff3b6bab544a162e9f3f86d6d62d6686577f7ce14b903a90330042f042ea21a84d16a70dc04d053f7b9338638895c6da489b3f5bc2384c9a4db437731897491155b5bd2fbb789e3481c74978cb113b1a14eeb72f7d9c57adaa6e167f0f2631c57dec50e5879ffdfc91049ab23ba96ffe9cd9e62e74be9ea91b2b30f2e96d5324817a97134e44a7635644dad5ff2a7373de9517efb17fde84dfee4e7c97bd4e79aab4bd49974adeda46bed0d85d4cd1063251dc9d495bad9fd76cbe2956ce99a289d94ad9549d7da2351684398a4a46be500818c33b791a7ced4953a95f708f0ecf6d5a65d6fb7c3dce599b106e7f65fb1582cd6ac61a935e18839fe43317aa29baca15daddb5d6a981e7d39044df7c6ddaefed5be9c2a33e68de9bd163d97bb7b96411622079152ced82f6ba409ead35a6badb5d6a7b535e3ad5c3647378d2e844e1badb5107a14daf97508a594d26929a5745a4a299d954e5b2bddaf43fc71fab771fa7f9bd1de7ef4ecdb7aa0cc42164bc71caa8d3ad677dcd32317767bd7aa3b72a5239da07fb7a24e0ed0a26c68dbacbc27ad6f240107811b9b67f70370b83cd1c621195ac3a101bca76df7341749f08a3e248d1cedcce3359751d334784579bfa7d53bc3eea8236b6af4fe544faa4a83b54016c802e1541af545aea2c71f21d772b49c298d91da80945abaebb6b686a7a1a5ada5d1da69ebb531a489288d51a3fb6df0469b6e9286a31ea22e3f0cedac83d6accd94c2e01ea16d43987b7857bb65a9b5d66e1c19c21d8b664ae9b5165fafc61adebb2a33ecbefb7637de7bb9a2dbbef737b1bfb2bcc3963eb2ca0b5ef4e4c78814461d56c6b87a148210892390484449389bb9f3f0e12e972bba5c3647ebe0b88dbcb9596d2979c478c4628c31c638b356eb6ddb7bb562cd9c87bbc86dadd633582b6756c698ebe686c55aadf66e02063ca6c90c83222ed866b8c361c479b88db72c8f9b1b166bb5da7b369b75c07b1c41f07cc7bb6d1a7792fe8ed70b309bcd6647a840c6660800497f2360ed7c39578c00dd07ed9b6eb7d4da77afeeeeb6d33404027a19a4f2ffe98d80cbd3a7794ae77f8cd087fe7fceffa774ceb97170eb53a7f6e39c74d2980f930234d6c5e7bfbbcf774e4a77ff399fd2f828f839ff6da03f3b38210f3aeea741803459335d7baab707c9a039f186570f5a636ff681582f57f12457f2dffd69849b3e49f894beab46b96907b992112d3794e12f57b1478e71baf4017cdd2e2b7743feaec17a32ee3ee90de99ed3288b64a86ad928dd79d02d9647fd083a7a08ef7ab76d8a46fe135fed3c681b038a2dadf4a926595229f268539dd6fa69be0daba77edfc7bd01ddd65f4c0b3c2412a9f4c9641f8f9d96161cf4a9d45bebbd66665aa699273f998c059b1a9a98546aab9040012473176b6d135c6d61bb00638516346de5858b19166c6a68624e9c6069b157b0e038ae0556a75d313215c6b6a9a189817172b2b54081b182052b2525e5f4c20577127432f38142f96862a6f2c9642c7427dfb7828c46339373ae3191c5cccc98929c36167732fb29299125df4c77f27d3232322cae254665b14a25938c7573336d6a686266342dd44234b3426634da2c16ac146d92d5980a575e8666e6b6c02b58e42cf3c7ea4ebe2fe6937d9f4cc66231fab45cf1c93ed927fb662a8b25d39d7c35a6c6509817152ab8ac52b4a050a53a6eb39c5841a9a4a06c272625275389a447a29096f135c9a8c4e13962ea8b1914e1f2f1f101811022788a142992815a6bad95524aa9af5e5844f81da37c29e99c52bae6d1ee73b212397aaac466dd32332a58c0c4ac5c5e5229b815aaaa42c76a41c162b1a27229bb858b403fa99a4a7dda962215c318b6c44c6a2ad56519884ca9974d22ed989b64305c8c11d3c3c170304696d9ca95545450a61fd3ccd4638a99784c3f4c58584c56b46bf473e2c44ccbc9d62c2ec674e548a452a9643a99b40ca7e20a4a49b9df6fdb2749719caddce8c56595824b6d1b8a0a458bb5a92ec72a6bcfc8a860e57c8a8149bdb8ac52702525262a142211abe564341bcd38125499edb24ac1c990482519158a169369140393c2783b7951d1d18f3bd9082dc555a1c0ab1e825a4c5ab854e5f268d6a369299e3a0303baca59afab389f22038d9a4ab5b46c9517142aa8a0325d5629b854ce5a4ad5b5a0c83248715b8a7628d5997eac7c97227555285aba139eca7110c2d40e7ee5bc8533fd4061ad4692aa9cac5caca954d79df054affbcdb282524941d94e4c489ab5a51861f59252a739248e9a839b34347812b28f142a79007062a59715eb2648140ae523946623279b3c69bda144cde61bc01c0b9978e0ee9de509a233101a3560e819b560dd6424f48cdc93816420d377eee1743a9548d4b695949498c4937e77f777eb9f87c82524afd7ebf57abd5eafd7ebf57abd5eafd7ebf57abdf0873ffce10f7ff8c31ffe5ef8c31ffef0873ffce1ef853ffce10f7ff8c3df0b7ff8c31ffef0f7c21ffef087bf17fef087bf17fef0873f5a69a5b9071db7dc73c7d051c7bbbb7f8ec93c446409815d66e31783903862d41c77893b03c9a952da00ced8cd5801771f8207180c0683c16030180c0683c16030180c0683c1601776611776613b3b3b3b3b3b3b4460371381dd4ce46622b167d239eb769933c4fcf9f3211108638410baa5f3fd0493d29f93be68f1a2429da24bbdbbde7aebb535aa36dcac1cbbe1b6263980414b6c47ac006d6aa0584ebb784132480605c1edf1074fee968927770db7893f3a117edfcfa7e3d271e9b8a48e8e8e8e01e28fdb48e9bbb5b74deb1f3a3f747e04fd700219e42e72dba0209917248396f8217ffc803140d46541d839927383968306741cd9a1638fec70fdff9c417f011d3a5a309fe035f8f9e1f92d88085f949343849c431925e4a0a48190888c71669f8918a3944772823e074889b823881d40bc4daea48f28fde71123f65a6b8f009152de8b33c63e485ca0775e043e4876344d7b2438586b6d28e4e3475228c208233d1af5088141101d1e234e30a28426695d7bace6432a91483a062553a9f443823821e8c4833e4646603a994c3b3e4690e073e4064f1af1c0a9e474fa9e77fdb719b14089494909904f111ff8cffaf830c1e4c4c4e4c811663e30994ca69393201b5a2216810425050545f3f1794149488a4a4acafd3cf9a614a8a05454340f162972c48b9a1542841c86080108140ffa10d101d40a2af4803885c8411826768600e1f2dc4d7cf09c891c1f1f0f7844e0b0726265c567891f1d48be679f9a7082e5c489ec412130c811c2938317c2669131218cdc426290c362c287901d7ae0c5adf920f1e3e313b33b58595959d9dba4042c2c2c2c1ce77344c7db388ee3bace67899df7e9610154494181323a2207391b55e6f9c69116aaa4114e015ce41620938031be98b6a2ab628a27c68f31768c25c611e329e8b08120166e4cbb16d2da6b379db5a9e9a0859ec6fc83103c7040881daaac3ef1c5b7720bd8fe6febb4b1db56e9d4de6b2b9533875aef91544698c4b5d5d66c030de5ca56285731e6233cc8ffbbcf7c049dd5adf5caa3f3fe2f33e55036efe44dbc126ff4804a4f5ea61ae54c5ec9cb56a31cc9cb57a39cf6465ed6445ec8cb218d729a97451ae5b297471ae5b0974994bb5e2669349b34ca512f9f728966924fb42daba4a488e2865502944e60d628679dfe4e43e0ee79c80d0030ab5beb32ca579c3737ee3f5fa585aa684b0a4ac6dabd17673c6ad19a34ca396b216d44b9e9b5684d1a8542a15068dbb6d153fa454889e521a8ff7d1f85ea546650dab560b1542a15e5e8a49b86b24c4451984aa651cbe954626262928d4081da2e42d19580e84ac614b9a3b6cd7da451a51da2283a3589442a994a233a8a9144f9062a914a242a517b31c6a7d3a9049e5c2402ca41ac3cea4d46d08da228e8a5a06c272625275389a447a29096f1b5372f70e69c3954267743c60100b47d8467b9bb28f4c24834e2e4bd5734ca398b462138caa2d148241289b210199a48c32119a22bd24ab413fd872e5a28f482e6693a4a8c422277f711a59ad5241249341a8224ca3810652025bb6332994423511ee234daa291a8563f019949d03a3f6e496bd5ff2e81e071adffa428799a3570bd68e095521a1070e7fd7b3de7755df7ca1e5e392ed7bd31e7755d0f6fe4a11561a65d305c5821868b1735362cccd0c4b4c0f156d41b9916582c5a88e169d60c8bf5c9be197c33f882e0f9e103898f249b61c1a686260606ccc909ccd60205c60a168b941499f2b9e0628c17312e623ed98faf8999ca2793a548b13ae59c5ca69f99e98b0179e1797129bd54d03c54a850e1022b269e636deb599680e99c74524ae99cb4d26971c0018728c0ff7faae3c12d733cbb63c70ed7b10c614d74a19dbecbc88139813cb7ef0aa9ffa4ddbbd073ff73393eca1e2094117a3b64286ba447d9595944ce1fa4a3dcf1851e4c0fbae6fefe2f9353c2901c6d1a4af7dd45e94e654e018e9cd6ec41c7ed312801d27f4aba33a41052e8124a9963c658647bd3ddbd6bcdf973d26e3e843a1c84b06b4138a17c086313352f7205ad5bb98227944af323a2b5efbeabbbcc1776bfad6eedae3f77abeefad7ce6bb7db4ecbd5db69a9b5707ed7da50fe4ac86eefdd208cddb4fb1d6f3737de19d3cbb9756c6bbdd28dc8a1e3fd9e5c6b12a1e39e362090f77f735f42b0498042d7d236a49ab6f3c69135665dd8d9c6a4d8eaff0df37fc6f0da0aa9adee72691250888c30b6822ce37332c6edf94b013897e3a3a76007ea00635804a6c186b1d168180fe28b2fc6185f08a3cb2a37ad76ad5a6bad706bb66b6d3270b41b475e6c3b0861249e36e08f87f1cbd58510c2a9e1c65d0be37de3d69b077d439f30c7fc43862af716eeee2cb982d7762d95efeb427fe7dbbabbefbfdde6af3db7fbceddb2f65a5bb56b5de8777fee4f70df6d5bf7da7b2db5a1557be9f60defdca8bae1dd2d77f75867aba3dbe99e74474a69f749f2772363f5ac629b67fba17d440877ec5a93c2980b34524d033ace24374db02691172d5edc350de808b78d763bbe53ea94562b6d6dbd17734c1c515e23f2ef08e54ab7346f6e7aedf51b6bfc39f7cfceb5dc41862f6887db06dae30e79f6d030c61867b28b5ac71bf20fa4b511f631cfe3dc5a0fcc3288c60d655e0c7235654f8f5c390c3168cf5bba237205042d65b227fff498797e71ad2f20f00c1ec49973d7ee86c389f1ee58c3bcc191ab1bcf6f368b852fe48edd0b4e7a0d90fb855c7987e342bf073996a4f18d6fdc6f7445a9fcc5e62dfcc59b49ea93a1ea7f43df316eb9d2170852c538040279d4dd210bf70e403bb6b3ea11b556eb4d7230581abb6eaaed56ddb2838173a1edaebb7634e48aeed8c520579452ba63a0216ba0dc38d2daade5be79216daccbe572c56250d6760ba1bbbb8b3ce835a0a6be510a370d060843f71ca2bf034286df77db8081b831bd168b67edaeb6e61f0d81dcef0f7286a1195c03a4efae35f78de8c91dff0219aa5428cfb66e6a4bb30fb3ef971956b65b41d7e49181000a3246b9a3dc0d8831c618a53b0cb118e11f40861a38bffd7f7b381247ea04e14f97906d9e57e933e7ea4e29f950fa11f67cf5618c94ee3ce9f6990fa8e4ad5dc68e460208021223170000180c0805c421912448c25096e30314001051685478624a94ca83518ee2308aa1208631c420050831c618c20c0d4d1d027218b3afcb510ba79a94fba8561bccfa952986d9976eeffbad853a266fb0a0a91014ade7d007186e55848f3e4ee9d17ad923bd2cc26609568f7b153f261c8924c30018edbf4939d846665ac18b4aee0f47b39b4b87bfcb4c4c79cf52cff24daaf4422ad28b6b6aa5e21e35e1a755615a868a3c583ba7993551eaa93e2a3deaddd485f4caec9a9bba91d81524e99add294b211d7c7d775bea5cf12399b4b93eb3eb685288318e433aef84147528bbb0c4782f39f5036c497268ede55d166f0b60687f4ebea3d9c1806f6db739ed2a976fe3c534b39b34c4d40271aabc1c3bd57ed277f703eda5ccacb7513dc8db73cd52d19fd1cc58f3667114e2707ca2a0d6d1e948bc5a76f0d16c2871faaf3b37f3134110127590aadf7f95e7e21274a68656f1c60038b4d940ff481895dd074e261495ecc16272096cce1a8f3a7c9acb7a3556d9f9f270f816caf95ba427c1c4ccefeafcbcab2308e09f89875d130afd20336039668e8994babf57945811d9101cc05fb1c04eaccbc3a4363d676856568f8b500da640bf12b3d9e934f68ae24b0bc783dbd84d8d39dfb077e19d4c9f54c0b33ad56e2517b6a078e23081d124c3cb3b154f88c61f66bf92f71aa27954932cf1acb1169f03bedeee5db38bb917c0ae3933ad340b33722598d802a745b2aed17d41caaf8fed5dc54428c405edf159f48b11126f454d65718d742ebb4c86be07ce75e21ee65221c0323c312f8b896b1c4a363f9a30a711d79840ebb5dd0cd7e29d4422045eae7d69ada14c93ea19078918a186a97942cba2416d3598ff772ff84c0ba5b36ee0306221c0c6ed72cb5b819d9e33312494629c85574ab1fef5314d3c7188dda196ab3392405a7a1e85019b7f10f32227563a83d225dde21be3c1db2fd090ddc7ff7d8038ecb152aedae5ac0974f34824b03288ccda63d9ed91119cb9a261ed92e678e3041b34d4868e7c6d956c104a41191bcf790c0f483fb5bde14c16a49f540a985de3a63246b10756ef2746811712ea3cb0545e5e0253269d3b53086f949cb5ab032afec9ccfdaeedece0442bc30f998fd5d8d63a0f47be252f60faac04be9468c8bdd1ca8043aff8bb5c1572444dd1be9da20fed4c12516dc210db35d2798d15003679e56e3ea2b35c3d77f8bfa00a8f612a2edfcd6ad8b91c6bc1b8c36d551d3ad309b6c6c16b40e3d0ffb3831115a2ab0e2fb18b397e5a5b78649b3e44ae29ca18156ed5454f89f10586a546c2d26c62a4f2afeb64d2fe88942084470ca0c890ef4d8a4b5c782258e7d04c547682de89814c7d38376528674521b20b8224694ae39c1ec1e6292c29855964d3b510985e52de6c4b7c620a1551ad34fe89099dc15f51037e65c8b931d0d61a5d36c38516354d0a3f067e33b99407b27ea9da47cd0cc8b913f021e490e05fac1304a8a67cdd5a0cee79927416fb0a0ab7ed570521aa5c375a90a7608cbce691648f32f1cc5cbe4be74288cd2ad8216bb7304197b363eef5adae8650b568b361b81b2db0414cd4ddebb6469432eec2d8e933aa79070e07dfc5d9794cbd1df9b60cbf1788d4ab6d08702ee238103d824b15e2fed6bd538c66353ed5021efa99a9289c493903011833a24f032be77b586548992628dd9191fc1ad2cad1da08f0d641a1d345eb25f779decf1e7d80377daf6e86e29efd5e1bb4f25bccc97910cd2ac8a738e11aa927c2c515bee1495afdb590aca5423da57a5522daf0244b268576c9a0549e96023b7becc244bfb5710f04b236b14bc901570292e3cef0ca7c3144ef28d11afc9926d042572890892e8df6244f90fc2ab00238fe68d92b6fc105b51b1c9130ca693cff3322527d4c4727650be32a5e55b698ead62c801d8e58e6b1f32f815443a284736177c617ef0464d0bd136aa1a4ea7782dc42734e136b2305978fd886bc9d113c0992c3f08a97708a3171ebac0e755f191254ac0aecfa29ba579bb31777a7101b3e7d67aa9d2db95d9e8adb3b55c66d4e1b5cef6d4b2eacdafa0ce6a605445d677b46e1e3297c43a530d62fa213015cb437bcbaa723a8a3b0ca10add1b8eb9811c9ddbb8f7abe9aa5ad5d682b8b7c4ad1431e90b573b5b8c37512e10cbab69d8593f3e32c34f8665cf35d0f839eac96230b06bf1cca7445554002af0b5130028d22063323382a5942d7b59062f83faf934537e192a0105cd8a49b0002be3d1e1082e2199b3384b8563ae7308810b2d41596ad10de4ada7f2c582de54ea38915f5d484838810b5ac2b49089a3c84f54a68ae91fcb12d9cbfc3ea075c1de799743996a845cd89047a0573e16c307a5ba40df59fcb7a94040cfcd104cbbab887f4297b5c4d73e1452e6dc78a0e694b24527aa6d5b748ac483702fbd82354cf480ed80bc05cb5220c0984ad41107557396ae539f7b0fd462df51c103c214cdcaff376031bb3c48ced84d7d7a57925a9845f80cc0172b38d3f7597e3e106b1aca40343ef740ff986953ee42570d9bd17b39cc3599f10cd1971376e9be3c1240d11f9ccd74d90a561caaef84883a31177519a82434d10e38378b5349841c4518c607db0de32b133bd8323cd697bd044209b09457571f813b67b32d3e14f644a3c65a4291b146976581f2c20bd15d30168df83c80768d6510273c4e7972001ac01967633926de491ccbd7ca888ccfc719ab1752c091644028229548eeb93553b4e3b9df5f872e779a583a21d20533b3a41db92ad8da552ba0bf069c61d9566ec552a5f0849b6544889d262435777566e73a25eb5a94f26ad3625d2f1b04151a2381e64359944dc6a80bad5978aae48634cc4dbad9ff0f5611b449cd920b595c5ee68016ab4cb6ef7c87a175965294eeb72190aac38b114d0e2e0d9ce2cfbf22d4c9a9302988d41b6e42d2888fe02214348eb15d1f91527d0c1fc0ac3902a108016b4907d765b03cc5420a6cd34882ea83eeb8024662f7f831e2c37851bf930c356941057177a99d7d5e52e7c930ecd3f046a989d4a402f6a53ae6bad0089d495c263cceccd8b164ad5fc0862f2d3cd1279539846a034a14474b1102e7cc0633308d2fcd40ca4ee6832bd70e8c5beaf2bbb836c077ba556d532b3eee601779a5ef8cea37a08f2a3c294b5cfc8a5f3855ac1b2a05ce293acb2f3b451d18ca431df1066f1eae945bc70ff6fa389aed0079ac864e73d73899426acb445428320039d438b3c6dd163fd70d6b4d8eee31acb76e43b3c0e41b8c9eb9ba1f92f27534638869ac76eb122e498ac43e3507df39c7fd66b1fd1a744a38dbffe1e7977995cb9e7c97ca01bf7b5253f1bc6ede041335503b4ade3b900303842ff0a2e55aeb1304eaa234db3827d5be6c3d4d8501554d971050d165ff4270a2b34e63351443014ea50980d2289d79fc832a2931603d333cd2f76c09b707284564f89748663fd8983a86d6ab7e274245f91f61fb709be02839538e2f75af261f36e88bbb40df0d4e431a8da52495fda6b39ad6962230593a3133fa3e380cedabadd258dcb462ef36727d27f3deddf78deeb50189c23eb68c82c31ab0acc136c413515eef35dd02ee312a3f4aa92217c9498fcfb17db66ec996c96016b9c070468d4326ac1dd7c6a716ec8ac7685145ada3829979436715867c17e7ea01c2e1ca8ca81134eafd50964fe4e950c508d87b506f28cd33a0e4633aea1848a0c5d56fee8880fa844261633ebf62e6e8e9a22954b2d3e720acb880cd2f9d2b43ee6a775f9897188832522b3c946d56ebe0bea34908b9cbdec18206a3b9ec26f487b31af358ae7b5bc4406e994034f24dccfbed58ea35d6254b64969722b341d392ab54535dd352c920e764d8b5892a88a4ace5bf892f2f9028b8b94ee2e523b5d13436ee5a4f8375566818bf9cae4a46200c66b918e117311ad98bdb716b5cb8eefc8a9bbe7488d7050cdc3a81f586666db21bef5aed94e7c4fb17bc18d07a02d25db99ea8e5a24137c35b5806db40d4828ce300d602ab0acbf09fd8678cd484e2f60d70be61ebaf8427fe7647ec953e9d9b8c7133199ed1e555b43bb7ac31ce2f19d155715a7230802e02a758bd3e75071e85e0800abeeb862361ed267bf81e11ecbb3b96e9cd448aae4d26509930807725968767d80e8974c323fcdb237c98e23ab84e86534d436a42797ba5260df51f2854beb3c2de35effcfb673cc7454ea985d41560248c693e6aaf92d12b5e97f2b8124d65f5c71055ade217ed5ca94bfeb724c65f245f30d68e0335facad2e95edd2f6bc6b5043fdde1b12af8a33ce0c79eab88e4bb52710c5d745b8ed26a5319cc31a4b2194a868fe47d8e938691a31bf11612ebde8f6a3faf9d4afd28e751c09bc491c212d1804b93e62a9dd24c5c03fa6c11de4be1b4a92defeb158081d4a8e36a63fc8b9828d1884059d4a5813a42dd2c050ab5a4a0a90949c03464669111ca728190ee861a3b450a7d3583e4f99bf1472ffc650b3a8eacb6e29c6fb32763e8ed2591387551c1fe082c51cc5c161a58c503b23298562eb1296611d418cd20c9ab2b4610f491178f2b4db20fc77f18d03af1b57d4a0e23829dae04b844b8271b87b4e46f057566b17850dc45ce1b6c3f6ccac87702ff7feb95d869f745fcd50c4f86187facd1245442e205784cc84eac9b972c3e8ad0737f9d7773d2d6623172255d6347499601dba127605bb1362c7cbc46647d2689fe8534c67794481a91a77a103ba0f914d5b5e9eadd9b27e85b39a27a2d80bfd68988b078982862ed9420aec87d71978e5004502eec3c88cf9eac695046500d2fc78593a2620f210776ef5d53ca67fc55338df4f145e30a33dbcf8ef0545126fc32e2dcb0f3a128b54fba944746a625f248ec12d91d8897424d38c7c0cbd7a89cda21a54e44d4d8a6b2f50b57819052ae549064f9a79ea829a63724a6ae17fdd773c114e87c7a5f2d12a0be163ab2c25d25896b110a503a7f34650bc04e375578a27cbd97f76c45e024cb7287e9493b814a4f67db5a8c4223f5a34eb864be1549d34d82de57cda30ceb7717d2d7aed9601811d83452fc673bd1474e54b605f90fea7850b1846d1c22b5e0ff7f283161d8fd482269dee8a603402c4fa841aceac23962d236e4ab58e212ba76c6827e03b11483c3d00f5874b90f011f87b4aeaac737bf7e977a018f13ef5b65f50101f7d73eb1c3604dccf7360c8b08fb64dcbf036670e02a9eae30b4844f393e391a64fdc0c88fd2835aaecf696d0cbb5bd05f888228fe284419f49496b8bf85795bab7136eb1abe0918054d7d32e8b288b5f780c14e03a232f83aee4f550557b12a7891c5dc064f2d1375c9d6d604bb99853482f4440b63421e9ead284f6597c2bb4db1e70cd8ebae5321237c46f4aba4b5b1b16ce642e6151b2b0c929746310664dc0501b20fd9d64c6ea930296273966dfbd24625f1dd40c52e6e80f14eb45fa56a6c40f81d3de38ddb231a25fc0842097c320b7534fc30470692d7ba09747c370b20787d35f296887d8901502c825bd5c5d43b556b8380a4a1b24d8133d634dab12d3a5d106f32e40d7bba1e1d7b2dd3810c102c0247b528cd0d0e774229f35095495b2d556088e70ec4a079ab46629edc9dfbe98c6bf05b97736935eb0abc402752b16f8b7659a1d63f4015895e6086aa25216a380f0e37e29aab37c40ec5a9afe97126353f5814d14e9d62ab1b84e92f946ea54f42c937add2d8608022381299c8b48fcfb69ad74dfb5c5beefd80ec57f4251f6eda02b2048ea06e388199602ba20f11b1e94cb31d0de8b3150572b0fecaf8203baeb398203b2724f667bfb9bdc99b05ac4760a7c669c0a9de098f5b25aede69d7d19ba2ffaef0e5de78ebdd976e59279c7645404eadf19d9f76b9be69d41f64a31948018211915433181f2ebaab82e2a2c2a03fb65ddc4c9fca3c4c11c435f98ef8eae05778c29f255852b50ec500a6955056714398c694ede82dc0e9f6427779f2777ad102937713f93289873ed7172df6b2128c9a0c74ca31d841c30e3fa2b5000f69684da469888b849acbde2fbc8dc0650a7f8f8d5eb213c7653337d4bce05ab3c6867ac40f424870ef64e03e7739be96b8b40c35c97d893307b86e87fb529790314bcb1416ac5e4b41b33b920c53308dc562264397c2c889f3ed59c14f38bf01c3e261b3967bf7e67ff19a462fbfc357cc6749efca173b47378deb9cf978d9d1f3ffd7e7f1339fcd9db8d5e96be1810cc4a50bc228838f9075f2148092a34257f9582bddb11c8c2fa68313d0fbae40c02b940775aeb028378f202060c5c0241d0388c1725d010b4088e8ce90a27271cb3c98224a6734e99cbe75120085266c72196772bd38b87152bb300c9a476f580421f0588457b7fb3186c08c4e2ed40723c5f707f8640b9b8173333e4586579131510bd6f07e3d46bc5969edc1b113c8b964dda77f5a9105effc2612dce8b596aa6cea9306624ded5001948a77209579ae83f937bf0bba805d3ad12592af4cbca6ecb04e94345e8e7af8be785cd66df222bbcf3eaad7704351034fc3a6d4a0662f1af6796ed5e208cd23124be0e8e6ecfa2bef6c79333f1aaf897359ffc07c91933c971533dac357591bc81c2eed12c0715ce570bd3cb075a23a16d646ac2736206bb6797c3fd17f7c6660f8cc0b2745519ed6f6af2633b87adb05733404f6a18266af374fcbe0c060f0408c33f36ef02590253f6f623876ef75407ebe43d0273bc94a8a30e321ac6da0c1d373f08d84ea065bb9316e413894b2bf1942196472a46afc4d76bd40a67fd9d1c04d32de9cc86fa0702badd284179e588930fc1ca2b3e341176993c30a4a5080e077fcb101c80798243deecfd00ff58918e541552a17a6c7f7d997014035f9d6aed054a024ba2be7892a35f91165569f71ee09fcbaab0d88837b9df84d9fd6c327dc1acc325405ecde3d962302f9d43a5a4203778fccdd5707c36185ed80854e75effee79d65136a14aa08985a86bb681ebd912eb1b617f1491b050a3f436eafdaca22b1db17b28548d25d6df8f1159b05931cb65400f316510a2f15afa142686ff7e26b9e6c986edb91b796a73ad8cc0e4be495bcfef74f273891c34a18e23e2e6a219be8171049a512a8b416eb9ca17bb833ca1b1b9b0c797ff9d43a226bf2726afab70d81239fcbccb401a9799e3038e1a9426af1df3433843035ae318c96fad6f70d569f2a04d3049020e19218d21c631436a49dd4cfb2f68228358c1d9de4b1d476cfcee7bb26a68fc62f107a47b1356a91a64eb049f970658335c7c2034caf1cd84f4cab5635d17929caac8c429b0986a10a83d891ad530d1d4d0c4bd31b0c086420a22ab6d06ab825c20e140939260fdc0c5a1c6e228a3718739661d0034003a6d9e81403c0f4e2e350848dddeef240d5429614a0d2d0d48a69c2ea4f97c2ea57414ff0547ed305e48b536028d86d40c2816aba42a8238881a5ad2c0ea02b7d5221dd4605c3f2bf0407f988f111718bab33e6e769069b849a1c7e9be89cc74d1e9fc2383ee90fad451a0f39406912404c488bcfd1a7666dfac21f11dd3db10d883a8a4b153155d2819b5ce4a68ae0130c409a2b9569a1eb53f1df9527af0778a1887401969e82acefb7e99ad72684983d2c7b312c289c7a2150d3d00170914ab1c69e8064b3b5a07dcff96e89a22a55f2f3a480395217e3caef49ce9f933411ae272eefc0969f6d4154f9b23ef7b0ca8765e1c3c1a045cc61a3ffcfa433070b739b836de454ca4c3762e08ec224a075dcf49ba08b186973a4d512c0f1d859960bea4cc0500117d7cc2635b875c045b0f908c1134bd6e3a1d4c18cc041d2328a4004342643d20df227253439b0e4384232191b812404a618bd5076b61f105c0c5c194261f4712bc058d926c6d7308063e038028a1f5102c4beb0b33e15ef1cb18e3aa46fdfac11d008970d9f90f3c767dfbed558a1371f145d2fcff1e5c4378817372b8c8e0ef042ac25b4887a9d2e6f0a93f0b4c3bc842b65e6acba2a7b2c2dfdac0ee6c6df16d9426fa8e6778f217f267ca12469105ee7aec6efadd678627245c9df6b3fb44c0e197a786918ac0390575062df7b88d3ff00835389d21f49e9e56da0f33dd0fac32cdfc707bc52dabb87392b56048364a8a8acb76eaae92223666a1f2c30238b426ffb0d639b23a12073ab4f7d01727bb0f4519f2830529695aeee2878f460ac1a30efca0757e8ca227152e83d5013c51b91d41c39d2afa50689dc4343603125820eeba21075441efa5d80235ee60eabf4c497b55474caee417cd64de3c18f609104f4448e246b333b10ff2429b631f44971a803dfbdd9752b07a7d24100275cdf8b3bb75100e7d30fc80d06a249392f3a11596d5392ef3a1f9cfef0ec94d70d387161db1037fd9fe5b905ef5c43e14a228af9472567ae8837f503b6fea8e87e6c339c7d5b32aab552fe23e05d27bed3abd5aa9650992453d7653485eff80fbef2709106ef4c8e01d4325a3030ac4953c7c28762946cac0124c046a525e2502502dd4fab1b2a244850f6a93ec268221066a29fa1f1d807bed9e00b3ff7be808a369216432d704a2f27bd009f5763f375d3556a0a5212a02ef07c90905f217821888baf496690933fc18eabd072a0eaeb8247c4e0b5aed6f8bde0348fce9c1aee5de975d3342f0e29b02fcbbc8bbe1086b018a7b10046d42c537788f6e18bc071e1c44194a154115036154314c38cbde4f95383a47a865a3227ff36a797b18c4cca8f282e15ddeec35fd88d634d3a56163f884a8570d58262f3a1d995d4d9743bb2c860fa889b43cf9801f7fb607b24f0b2e525718c2e1247d7b2f9edab7aef580166d564aa8225f6a72463b47eb8de9da430ff1eb17a506505ee783428cafa4d57c18dbbfd1d70799fa563e581679e08afc72b4fe539269d5e44c93d892ec83889744cb1b5762744313373924a217432ffdc83795d06a391a3e10936a0135b91de07a0d1fd0d75922276757f361c3872bafaeea1bfe602152379fef87399b03c2a6ed1ee2088a077532b3a3d34550661019ac8f7b88d27609c90eee7e5c0a71e3f670993230b5aebaf740cd8c9845fdd5f65fd6d99724fcaff57c3304448d760f0be3392f07f669e21eeee505afdf1e72e8f8e7b83d749acff7cac9b6c0d0bc6b08fa0ae7f5a84faae3bc544a4583801a1b73be0330f4b6d743069d672e3b0c27b985c91e789101a1e1ed87dfca9b973d0402629222c15d44f49e50d78756879fc2f3fa640907010ab9fc2af6007f4a89d879a648b46c17260c43e79c5d39e67eb25388bb8826ec016971d6953e72ff7a08bc34ac69247803a018c0fee4eee02a840a1533457eb0fe033ef3d743dcf27e3293c5cdc27559bdefba1e4cd9e4460acda724ebe158105fcfec1ef540bb2fca797b04894b9b86582749ed68654f37d85a7f58e5e1655c1f88fc828c2da0871926bab650f2b780a81991ef80a2ee45e8984c5b92171e3b097e1c7381b0b05fa0d58a0f3d019ffe44b85b641a4162a9726be70f5aec9ad831b5e88ca28f9149669049246e3a22a30480811e38f9e4a9d40a962e9b9abc5802789fb24e10239099a0e19b6d77d69da287ed57a80a8ef7d705c9285108b92ea80be0f685c0b2f7c360f8206c6668e704da58866708974b9b81e8360ecb40e8c8d52c72281ac056068ece44845139033aaf10369b420334035673c0c2582250db1faa42c3f4385610de6bdd5f0aaac35e1d3cd33bde97cc7b48aa222d6007b1422f0eff04cfd4672069f8b7853bd4d33b089e099753ce68ba653b0583ed77896eb41f2c45690de77338e8d9431b8bf0ec81fc6dbb820cc4f925576e843c5438035797985f5956078107b97f4642461da67492eaf35ea38892141da9800c385bfec48234070275ee086a94446d16c30f8d4fb4e91142cdc6b9cc58015d7b709dd153b3cfe838dc922c723bd54b013d35e1598a1ab3a57443c1b9f9cc6d62b7c9af4ef439e2ee34c1ca0609a9df4ba68c1b202a731fe536dd65c56d8187618203bc0869296ab938d346890fe941a002e94c06ccd6a9c8c3ca934a600804374c7649284ec3fca705ed5f8494111b667b7c0a0833457d72f891ad2491851a0c071d141507aa8899ebb524fa1cad20e69051cfbd8a8348845c061e5172dd01435dfcf2758ebe421f0d09609baae7913a24302ae8ff37ca8c7cc0913f483755e581d0e74288074598f9d60aabfa2da25961cdb9386c5e67ee882bf76c03f0bb41793f4852f877751d96476a6c33445e1f57d03e98021b6b8fd7f7c36936f712427ae30dd18b64279c38ce9547d00175952ed97b1242da636155d9e009db75e0dc2d675b0d7c349d174dc19f595e6d2437f33980b6d754a25bb94e76706bda4083a119901ed889750125f99da1f80c4fc39510a2428ccdfbab207a81b4f1e1b2f4ae7ea75a2f30c90fc764540b0a8b229533d5bcd960ef5da444410888bf26965721f02045a0cff67181b32c0396eadf9b72a67bc7a752fdc138d95b4048214e4810564487951320c07beee41327006a1173334782afec1383be4c9b72a1c62ec13b4f98f70ee55a074a1746d6f5ea3586f219f299e9326b29c122ae6e7ce2414eec97155a660dde98c96297b7a557f056d572bf9b4b4d260a74be67f5260994aa1ca4e398bbd58bf69d32323636a84e02a4e10faf1c8fc96c7110b060e2f5710126a2a22411e39008ae0c267dcb0d72bac1affbd3cc904c10d2fb550afb3b0677074b5432b800a017b2410ad00d80a09e873afd7a174d1fe3a4e555c0dfc76b90923119cf17f261d847c49dd2fc0747d9b170e42c2ca7e9ce1a24f3840b8ba6116b10ca7bf47632351c361c4fb08d841d05912eb6329b06ba6561f84bce6f7e245a6a80f21d7c6a9099c0f5f6711462208d47a91e0d8318bf53f144ccaf9fb3fd5b1290c61586824b5a106386b13875ffb27fef5bffeba6464f37b1d11dc9e47a1c048b3d90e813b800abebd7c07bd4f4d5f7666594436f918c80e51761ee63449088906748f5c769a90f073774d6a1bb6f7594de1821844462ec8c1110cf71201a65553fa88711b50eef9a8e6144f260c8f150822e4eed509072f76227c9f222de91d59e46a8b9b1b9b7606915e23486ca951caa448b2047f0ec01927fcdd0729adb6985f5e75b4e02c19eaf003e85d28ee624333c86c70b5234b4aebda799f2859b46349fbfdd45ecb62b0d722aa6d17626039cc58040ed335faeae8b80aa9c08381031339da2f131af08c04dfd3d9443c5ae417289ddfa5b4ba0818d3934c8b13f584bea13eeef09892401d97067f70703d01d08b5f045ecb3d0c0888dd242302f7f639158f50056e43f921a4c54d55bb5a61a35509652d69087edac7669430231f28c229f1f51a2dfb27f7b0ea20616521087bddf08d6a8ba253041fb4c7fb1df4ef44bf67eeb8fcdfff8b643be8e39bddf27c3749d868456711de054565aa1733c9d6f4259c6fa0af66f940de2bd5384e815c9cb6946bc0532cf226c2c848eaf6d99b9f65b322c142697b3e7df9ba0e9f4bdbc01479494ba3266998a7cae7db25044f5df0d14d154a9db060d3fffe20ce4e8152efb0d3871c5e41b4692b850794b95addf7581130f37d9ccaa7e736024f21aa462d6019c28e66306d5b269c0fb275226c76f2f56a0ca82f4157a161f850c6ad6ec2b6db455ebe31c7e2be9962efda6c1a0d5ffd71c914c2c7783e226c47bc341bfa5c0a7673ed1b3e659967042ffc017893d941101a036089989a194ec47e83ea40776625d408974c2a6cf817e57a463e16d94a45ca971895d8aad8b72c07588e063ee310e8072f75cef5c7cb1d7dee37ae80a12ab627e13d4d95b7a4d0179286dcbe44b0734559b8319d801e019f36496e7005ba4e7ca388e169071ba90df713517c386c4480aafa94c33d07a0977fc047d8554fa733aa0e068a255d7007bc3896a36800ec4663a98966736a5030abedde35b85df528c24a8896b358b6b5fa3c633d009ec6a23af83fab69beba08ca0cf446d1dc89935deac8321328bbfb00eae0cec9bb05f285c215f68a229ace139b0b5cda918f5b6e0be0d9e1129aee37fd4794e3976609d12805062071ff99955b003191909980393364f0b54834169a51798e4811ddd1332617d536d4c83c26506266ed278bce338f5fd645314b12893551bec921938003dfaa64d858b96bd9767d2ed448fb90514151b757c4bb2fe56f48468988c84d358d40df47d8a534aa3ef6b93d966c26a69c9e80753999971c47ccff749a9e31597ef923c98e27772a3f3ad693aff94ceb77c68f3498635645de73b0ed553e36943e77bad6384802e722acf77065a08396ce44cc22c624538b9f3df15a3e3302706eccbc27bf31d017d805857273318c1c9ac9258be8b36302c62738f852cdf41cbdc4a4d1fd827af1e1fe7033902a7f5fc97b62dc826af0de414ddd863e053c4078d347ca063d08390514038c5f79939ab0ad691850f9c42e01a45f04129df7173eaf18d3b3bcc15d1b058f87b608f3fdf03194ff790ffb96d8c61f0402aaab9295fc395c3ae74700f7c65f4316d0f107a1eacc90d361cf6bdafdc118d3b977e39c0bfaa8740327870f80f3b88ce157c1f488d3b5fbc998007826f68821541ee64d2ab4b3636a917446c7e077276acc2f863fa0fb1e5070d71ea68fadad28730a85946a31ddb6f11d1bc031e29a785b6c627bc833b339c15df075b295dd1eea0c663cbc3dc2e45450ac11d74d14887cf700fd97fb63bf4f784ceff1d3ba0fce7881dece57b930e7620d02080e0eba094746a3e7f9eb316e0f77b5c07dd66b8192f7a23f1f932b13a10bd6982d5200a3ed43d90711a58869a851a0b89c5ff6047261caf7a4956c2ae435d7ce9173685a374c860bfeb9fbaabffa7e806b69383663f04ebc973fdd84401c8dfd246e57ebd8faae69091a53896b877463213e20d25137f85dc3ec9b0289ef31fa92bf9e8811c049bbc868c806dc2b5c701bc790651fd0ae22d89741c98b624dc07954d4401696686295fa3913beeb4c842cc1540df5fb5f74402dbaf8c99ea363d03e341e92512315f5ad24ca05fd93c65eca8dfd4ccd806542ba157558b2abebcd9f60682db51c62e759b782e0c7521bdddc57e6b97d84870ff3c10130bc214a0d97a2382dbf72f261284f9bbb7b27ddcb157f2493d58ee7da98e0d99565b4d647f02b67c70b1165c8766adfa2740e864ec3cc8c76448be5479e05ab61ff276e11509cb4f78c239b905778c5cc96b222954f6f29554541a1ac63af1ec0ce480d29911040ef04ea684db329ebb4bc19d19d5e57e7a1039736c9a302b8d1674151bcdb21f48a21f1b1aac404521dd47bd53bee339f8bda505969620532dfa15cc710af82bf76c9243c8c1a649396cb847c0f19996a311d543ec8e3dd949e0cf8dbb3e4283f0cb2d0684fdac2566dc386085669d967e94a7646204a0bfb4e36de31404901b024da6ea30a38d1ba96816ddc6712c1b429ba671c4b477a49d87fb694638a24256145808845d69aa1177846e3fd3698aed226a013a472f88eb2bba0b933942814a5cf1be6982c29ffb3f8fe5b93b10afc208ce6eb124e3c2e0fb0bd7166f335e06c7bf30d52494f67c327502f5164d81cf6929f74df1dd465980cedb0fe27a6d57eac41d1be619834b5a16023c775dd32fc664fc077379e11be5c48638db10fa7a31109cd13680a1ec589f01633925dfa6c7266c7b4135e5304e29ad443c9c97a6bb4160ed6d5e53a536b1bb2b1ce34bf2f0cc62f236f5ba04ef307e9843d95544fd639ed054a54a4b5ac17774e13bd227bbb422a89bec407ca8336b1a1384b06b48a2edadc26eba48f39bacfac748c8521b840b0a6942d71413ff52bca6e09911850cba94cf1fa9716ad945a260bc7108f235620ddc49c15f16acc57481e1244df05415aea9946ec7b981683537b8931132baa323ddf89eadc211937821d18874d592f50a433bd2a51723842aa3589ffc52ec2b45530d958d8d6202892c786500dca95f11d969d875e8bfaa07637543d41aa847ac8c6e93564449f6dedee2d20550c44a082a99a72f1294ba92c0d5ddda8df198eb4b2ec7baf6e4bed8c36713eee70360014ce7573a96fed168fb4779fc47fc93971a24127000fd17a00eb07223183c73aadb68a88bd1c762acb41054d75204eee557cecc96802241a3ff1997a8d358b89f1520da52eb09f7366bb6ac6d104487c08a9f9ffb413746742b0467fb836a32d6973b70bfb0e6a9ac3f1777a773127f86caa7614292c3ba8800e80e29145e7affae0140911b462110876765934527bde87f59666db24f57c53d0936e8e299b6dfd9acd4cf33779548900d1378ebe883bda2e989ac2b40ec64cb0aded6f501ec6606c8c305c8cc9be3596a9d84dd8f0281b6b0ef3384552e4e3c5bcb31680fc5dc6712fa6461f3d0008b8f682c27d58384038e91c289c894078453a6f15885b5c1cbff8f728faec7fc50f64ab63f86113957b1bf0eecc582d406f3f82d1c7148650f8d9c886f2ca440a42759a3eb2aa495b6920ba1e48491ae56b42d2ec64b702bbb4acef5b1ae6431d272bc9e39fad4b510fbb539829efbc015fbea418cf24bbd0dfc12598953d473c58c911a4a9f8f561802a9890d99dc763f2087a26576fff82853046526dd7db940ab2291f70875e31b2019caacce59d7c4e0804633548847baecdf5a691b21a62c994fc5ecbe8e3965e4f157698b37f2adc9b21a577ded25e951152f97d31593b46ac2a7975bef896d290e7b9cc099049355a285111ca1ded0e84e543ecaf6eccf73da891855134c41b230e090b2b72519c42ba10b93dfd3ddc7906b86e07d5fb8cd2e21219f2b061a48e4f3651c2125ff07bba21f3bb431422b8043dfd0d13b31e85c3ea26d8406419ba1eba3a328d10c0e47180d943605631ee5b15b72a33747fcb744ca40c02cbf6b1990fcd825d6f41ce2e925beb7ae6ecbc3d34bc0fef65bfbaf56dad852013745bab42973aedd71310b6c9ce1b5ffe0ca2eb4edbebf36b26e15e1545e8998e19e06696a53d24ebcf037e64fa1c8c4a0d106e0b366ed890ecd422f382535b8b2461e42586ad338496bd8b0719ffa40cd649aabff4b04e70225611989705a5853685d53688b79dd473bae8cb876787f6f3f526efcf955b7ded041677b66414d8caa20fd0812d1f12f7ca8ab8720fc62393ddc49dba4308c5e784268fbe6dab9130ab87499610368a93a47d5497becf1703977072414186032a67287a917f71d11b206113432d7c866b031135ca5b55a62bee44a9b2e15e63d927cb6ca61d16cb31e3be456f830617b3df8c739adff71ebd06de11a82d9571d6b4e028423ea4e2fc6b18871f41a82c4fd9c5c5a51a38b3762bd97be53fcba63c12449fda69fcd0c91849534cdb15c824240f6da0a36b62efb26357bc22b32097ab23f7f25631d5a05d282a24ded29152baa79d53796e9a3fad8bebd1a43b5007e016bcfa63322e610c71d3ff47f46d892fa77571b180fe52fc73435c8388697aafbccf435073588b430358f723e4c4a65bb678ede5e0d181afe0f525bc5c65902c1b72381dde568dff127089c00670d2ab8893b6558d8b9b9b304678fcd969b56dd5bf9e6b317e7f3b4f3197248690f200a7f99caaf6b885bf027c7e509806e7a925800c943656408dec180968679a6072a54550c63880fb37455841cb02165b14893e7f6847d29039b662e5c5ba474463fd78700b41d08a9fa615b6134f58b610fd5f9a4cf1a5807abc945184407fd7d5bea858a61e4744d2ea5cd001b9fc65dea6b5fa106fb0f9d840c2fa9e80c824db710a1c5f7f5d71faf9072cc7ff1b9a230d02ec96ac5983b0fba62a04c92f27b88b6801a5b5986d81c861092089ded628182fb8dae391f0606068f70bf5616c0ad76b1606e83c47a3ffa1b09238946830b731852f8dbfe33d444022bbed90b680af17b0a7acaf38a96f63ee75d118d217bb36b00ec01edcd2ad6ec5143b25e615aea1bb6ed5464ca477d29cdfe761e929acddad9f86d6aab43c1e4202aec691467c0978ac5d75fe71974f4826e8bc0d756ed2ce354b2606bb2bfb47b590e3d59b2bc4790361b8b4062b911af6c0a50520d5a7fcd95fa837d728add9f0b81954c1ed2b5b3569626a0835888646658bfccfb4240c2415729168718d3da3b2d9f84b3a6d81008473ad81ac5e240a2da4e7c173c46e159d2e3468d3568966210b58eb28abe2e2f148bb380b9adc1759af8fab198907f19aa593524b9b1ae6d4996059add68807d59b04951b20d2306c02dd614d23d84c3b5135e7196b3a82be5cb676984c03d1ade927a9312e353d9805aa0cddfe809f6787cc31505e71b50ab89217a4039a4cef4d4f2896cd6dd37d910ad569aabe85691cd251b9b8c5392501a308e9ea796db4844809e8c9a981643f78ff95a16942c6275693ca0160312ee354c903b424510527cf0e2d92b927ac461da0a3f4ebb85ec3de145ca949336394ff6d07c8b02bbf2479c35a4f35a11270b9e5fae877b73e47ae28d2c41d0f7b543f64e26440f5972d022a0e7b1300cf93b817bfe776671c62f9b9f475438ab583fe5b30cf5c23ea24c9e159294ef94c3caabbc9c6811c9c805286214fb707055b101b5d73e271b616dd065781de3696eda9d92009823ecc26ea036ba3fd47e6eb1d5118187dcd4113a04ae6053328d10ab63f522d3db5635dd728fd5d71e3c60ca710a79f7b730f61f982a1dd734429f5b8d42168156e70e48ef85f5e1c75fb123ba4561577e91c373d8e788ca97e1ea94a4b22b83b928a6446b9d8d6d123ababee13a4443bfd31240e397c0250f26001b26f61382c7e8449770447041ff6181b543180f6641239916d6029569a6d738b79716508c99e46b189e55ee126767dbc24cfb411fa9f4c61a272c42c30af8740da1bf5f054ef42f86adf73709ebf2309ab9dbcfc0cb01736a233b154a9015b1038a9758bd4064f5e6a23f975f7ece5a06d81809bb9604c1569a8c806eadebef3985e5622f0b6a0972672bce077551056f07884b6ab8f92fa418dc8bd4c32816cf472b936c5d752d02f80bbf821d5fc3b7eb782b9cc26c61aac4af2dabe5902b0446a9c8feb9d8f679415c14581e27110fab6253bf517b174d2ec852e86a5dc8f5dc0a42f391766e46634d50eab9c5f6fd1a5f3af0b6ad8893f2d02aeb1a191571eb5748adfbc08010066ea57bdf31dfcf44ec4ae9c83d3b4f029f56b8e519e297874ff5c579714f67dfee940de72188baf273b9b0d3ed433d3694055559cc00f09ae1724287e91df889e39b7bbcda083c78ac59b370bf694dd060a2a3704d686c814c308d6a0200ec6bec2ae68d25468e3578286cb267aaafa56d9d47af380de0ea22778897a04100536a054ae1404f6efce7542a07b9bbce5d9bd1fdcdd1d1468c3b946cbc4c8969cc698c0484c442b2b19f831bb197631cc89b36947e38fd88124eed08764230ad441f767a4767cbefca81cd30c134717e79068f19ecd581d686334155f6d694027d2b2e2ba765120740331885883d2ade72840f153b089512d6b4161e3570903b474810167e194d832bdc6c9d8e58afe71c954506d2c37a6294ae08bfb92086b669fda6593b5a2dfd0b5af6144b91f2bcde272e8817504cd7c2d13591189be883084a83275914d2568123ad512b6fb413337e1407aa54fe0a6545fd90a37d81cdbd817b782dc0707f8f78189890ee1d0115949d32a08226b7359538bfeaede2c7fdc003db1c33935bae130b7f19fab6997c353f763965343135d0ca4bd1d5f855d571ab4ad367c7f19985606745a2a00ab0d1df05cd884c8f39b4dc2dd7bad490aa5bef6c7ea45bef0a0f63fade725951fa6b262fac7e16dc9d9080f0d56db9f22d631c58efe978636268e97844c8271b30002c93d2b43784e9dd28f4a952083f66ecb118f958adb1a24f00842c4a359b6e15e63ec88d74ff23eb63d8221a5ca558232200bd8155daca6375d1b79424d2b17a5e6e9795d6e04c4e537b15d05ed22a1f3c15444da07a32f217ab47b834ac1261cecd53c1cebf04e7ae4b7eb6d2b879043e9f37518c55fd2effb0c68e4850c13b59d98ae6c99deb06cc0b98bab10af410b923456f69f006aefcde22ae8c7c51a40774b282dba335ff6e64831724fc1d851f8a2e64603fa8b7498f0720c3bd1ed40f4da3c174e3627ec0e49595de4dace69529eb1f93808c5085d488e5bb956bee243bba993346447ad2c43dc94ff4de32da18d527308bfac412bfdde363e419bb1ec5d19430e2ae8af5b215330582b1a6b2c04b84cb6f7fc66fa7147f285308b095c22f3cc3eefe443285a0c0525813fec8579e28b8cf5355eb5b82b68f78814ca17d6eaf5f61cb149a4a851fccf7a272183418fcb5c5cfb76852c79802aeeedb27ce123784131168b819c5147a8d2f759f9f45e78a3d3a3f40a301a22e95c6202ddca44af16fcff3e1646ef952550dfc1977278c221860c32810514888cda3b622b78cedc1e0754f15c2f5f08d1c04979f5a4812f0dc97b53a185feed90960b5e2dc4c0388071230772621e90a2358219631551f3b61201e5e3d4e63ac7c6b4890c82dc6d709478abb1323eda0483edddabc5ca476f63ea749a0dfe6fc9c802dd13b27e1eb04febe7c7360d51fe67866af46c0e8791339e625fc67db344fa5d3ece6df93712a228476f2b889f8fad48d14956217e8d0e8b4bf57d0a9c77f1e8e3295450722c0f9cdfda83ee1a3ad1a0acf698cafd8d7458eed11252dd49dad4740442aad8f21d995a359e17c99428fac6f68079736526208e29085e6944045435c07ae59e0d3472ebd5b54e5212d63caafdfd3565692ab9da67ad838a594c5cc24baa746a49f0ec4f19f98adb3c8af873a48f051b4b534722bf8dedd397102238fe3cb373433ce88e621b3806b17eb9b07243127f650395b97471381c9362675c95df33542f6fc7a237f00e24ead3b006ba05bc30d18f104d88a9a10c49975bd8123c4afdd155ae62a93414c99d0f9d8d8f91b30355d4d53932269f8e11bd4bfe8b5540acc3d13fcc2f3b0b62aa24bd62ab0a2394ee7f3a804355464dc84e1047e70d7a46565d0235ba49f1e2eae7cfa3356b2a24b02a1f7bf91d99d7139ebf0e63c50c212bee17d20a78990e04123753af447872da7e859d2d2ee09c83c11e708c256e6999fcc9aa669c05a541d3d9d945de42f3964b9bc9db818426e991a8bed5ed4d1d34d2887c231d761b124f15997bb3e1086ab93ba1d08199398bb1fc8254d4116cd33e34d520920f305caa8931715d04da61440293895eacc19103f58d80034efa4eb3f412913dd142634e9398702c2b7a6994fae105b39771dcadf41fa33194d357c353e5a9bfffd72c5f06cdaf3bcde28b50e8dcecd0884354c7399f27061224763387e09ca90eab6c42ed44c32e18f1e8b741480943b9486449ba6502b842aa1fdb697126ee2881623bf72c191d26cc4c9424ea6b103303bcbc67350a55aa6d27d8e424305736ea4c3ab4f238c9930fb15950f77a603da073b17608551fac40b603afe68f239094371a6c2879bc3de035e666108d0a2062cd97a2a895654ce7c605862ed647d9ad13d1aec91d7f74d85e715d226ef23ff60bc1603206f7a7f8a8f8a7ac861bb1ca25e2b6439d5e8ec616c66d8e0181e879168704d7622a6afd9db6be20204d6040ad067bb58305e15251db95912b4c5545803c21db0b06a88dd096b40eccc70a1e31969199285b0bc8eb19d0e018081f0c6d7ae0e37751dee15e2f875df36b630b08e1a0533b7e68620bd9971b0ec8bff45bf6d42082184ecbdf7de72ef5d0b530bad0b2d74a5c4e28d378e60650e600a05496001b4eea8e26a3a22d9dec8b5d6abbc1be5fadba894d7bb68d4ca2beefa7a3ddc47451484b228bf2ac490867cc18aebaadbeaf15d64a116a669398b0de5d18269ac5b96c38c876503c6e5f1a4b7bc83e16c68b6f63631eb6061790b674333cb2bcb2d67ff32164c63cfd2833dcb597007730b2ef1e8ccf220172092ed597057e2c1f296b7e00e66165c234f433f4f245b96d7d058afceb2c23580076e013592c9ad7f6dc22ee26c3cd5fa3ed5ade2ce8666faeb59d5915e9e7f5178227730a857c50f90e4be0d990ec666bac3be2646942851b23dc4412ef0700d0dc5d26ab15a4153affdba5e25a4c86b439419eb481821328353672c5c358a7416aefb91594e6a716bef25913a53aea264975f90345d7ec53c63aeaa7a75d8b5cf5f1d76961fb97a673a6094dcd7f61a7ae1202ef93af6e6e6b7575c0dfd1034d849a7c136bad157dfb063df305c73a594b2ec2aa7258ef4975bde8223ed8037b823e1b9fd47de7ec1faadabdf5e7d7235cfd78a7b1b0775d077d5bdea215e73bd23224f1cc425b3bc9bd8c435d7bbca3a76bd3ad6cd6955b88605275162e5d6caca2d6b45746b74fb349fa27223af4ff3f746f276955fc72ed36f46d7d75e1e712a5c0a6744846f3cfdc81aae9fd7b8ec4432a591bf302ea58a7b1d46c95d75ac63c6a33a86bb0b773689f5684d9ba5189050110626391e23b9c8110335dbc4528feab38720305b5c02a2e689314a64a6a0e07a2f317ddcfdc8ef6f469637358a06ded426695f53df1111c425db7794524a29aeb1aff86dc2945c79fa0e0676a67cc187217e6f46f7704d7d0737103f7fd473dd3bb439625c637192f88adfa7f7f75ee654e27a3106ce787131aa7172b93f3256bb5a39ae5fb7bfb0656b9250d8b01b9288c02190c8acc12531ac06b77b424108691494893156da49651079be3307c0fc7027244f8cd1e0762f951f84294bb8f3303b2416177cfc8b0fe25cef057bc195ef00d76bd40b034e9e2d4f6dd7a6014d5de643889c45e41ef3914896b7397690ced5567c2a630fd812a9b0d77075df641a6d442602a10c1883fba8d8c21228f939e1630a1531d20823f7d226885f45d86124c41de97962291f16a38c523eb9de10d6acbf364c5a8734d6e93b17cf948775fa8c8725ed3be3513fa15c62ed109dc8fd1efa145bdcec81c51eda283b6157b212899ef2eb0d617313f803afc8af1ed2d4db8b26e5a237d7a51c8aa4e8198f948b62766cc2549ef308d74d9af92aeba15f9dce57dbdb70e7224fdcc9cbc424da455c92fb374ae6a83d89cf5cec2277af317357ecd9f16c5dd2ac070b8fda145fe1d8736f902dce234ee84091b2e2c789d08482d30412253c748a4675909bad5f1a7decc1d966357d932d7b2ab25092fb35eb11a768938bd8436a53c46470bb98aa1a6331b89d3bdb19663e8664fbd8d3a8f96c5f6518ee1104e66a653eae8f2b4689922bd747642136ec8d7a9d8d1c532f8d8257659d7242d8cb5f364a951a4520b015ae813c3a5ff6d5abaaaaec28eb2139692bae5760ed889127ae8991e7abccb0e6ce746c795e94edb8b3060265f9b2c532ab91b41ccc3d541c6cb138c8cd599dd6214664faabbbd8864cdf2e598ffed582c91d7d93e765bac29394f9e87710b2dc91803c714d02f27cbf095b6a43740e42f37caa51f07dcd9694ecee093306bc8ca1e0cac318631f9680c450a4bbfbfe0310d245caa651cf0860780271b25c42de84018adc41276e9e0f46a05130083fc8300932c6fc37fe727cff8d820d779608093513bd44e3341352480ae589a47184a490753117dc526b9fc0760d17b12402d6b5177171a9b74f40fbf50b1761e152df4f60bb75223313d07e7f71a9b11011b8b7b010fb803773e3a99ea4c979ff6668a9af9dc84cc5957a7b04aa6fef6f58c89216a2dd5ec8f6ea44663a881893bdde6fd77086311dd2852326a24df5b0622e7819c4361892db9984de8ca951fdfa1bf53ccc68147cdde1bd544c038fc09e49c090db7c55555a86f511218a3b9861d90edb59c6378e50a3e45f73d65f702d39eb57e55725061121b5be9790148a7c417fbd9780389ee4eed51730de0b7a7da3f83030c69d7c524abcd57729b1bceffd8ed34bbcb78422a5b45aa665e6a3ebbc5df62d2a4fbb08238c90629aebdb25ad5f50285b1162eb37c6905256fe7a5cdfa46c21f146b1ac40628c0cf718eff9907f6f9c5e824aa19642d27edbaec1e89691e8dd7acb5bd2ea068294c13826bb71671303cb7718969d48f2755dd775d5cdea25200df92e135f70d7a9f6150e7b0a97d9871ba74d12a6c01508e11f5cc15705775784efdbdefcabb5d6cd7aadf395090a04295befe47bcfc234f4f5ef0f777d24cb2336e7bd76d683f53e71c7e1d2fc75791912e9de7a0904a9b299f9baacae7119562f9ff5aee7582417ee6ce66b261ac77272d23cebacb8998034e4df9c73360e131087507e99ecab7ac1048780db7fe2f61f478a2f0a39367069def3018db8c9b81e5b8e18024a6340ec8ea4a5155e62d7feeaccc7c4a37ef31191e37be87a435c2973a4136d9a394fdc2e0209492f44272fbbb0a5f9eee6790861774308d5d00266395c1c663ab68f41688544fa249148b7a457fbd2a8cbc29242c5653909b23cb3642e7eb98e7bca55ba5492e7aa30034e56b98ccbfd6639fe9be5e07e89543898b9cb9d93a132921183cf3d868c5f7114475193f1d7f7d2716f6530545eb82035ce12472e112612a56017a6c2711dcc2f0178d438164ec295d7f3f3d813b7933b797e5efe00e22000a4b123a1e0793abc3c2f731ac57d5e3ad1a83fc63b1b807901301f87a250a3e0e7e393463d229ca1499e27b821c81dc8b38b51f28c6bc8f3af8b6ac8f3dcafb81257a2c6bdb38b520dcc2a0f2273bf66cb8d311c046615dc5d1d2f67799348b6967abc9ce52c2ff18946c9f8c4d75c901ac5f27908a551a5cf169fef228d72f97c00b8e8d3a6f91bb8d8a44df300e0e24f8a95e9e0b85fcdbdfc7a39747910994ba516a552e9f1d585663ee44b3808cc2d70d72fb8d4837be9250ecb74ab601dcc76948248eef1a51a985f1e44e61a289465bc66cb32641cc667e6439ec341604ec15dfb50b90c1c04e617dcf55f5c26de2cc726ca766c98e6de3acd8bdbc0acf26b84714f87fb7739380639fb32b8c81399f4294e117ba2156d9a4ee4edcdc1276d9a87c1c1a136cdab70104a9be65f707dc335896b9c5ea2c4f591162e5ce7340c2ecb499789a408b4699e45c45d16dbf1b2e8dda9ee97ade01fd80b2e147ad2a8799886a7c3e8338fb89a20da47d643beb31ee4fb2a3530a73c08cc292fc0435d9f8781384c90c6fc7c0e4f07013c1ca6c5b0cbc47622cf6b9c50379185a8b98389cf0666f98aaba9519e00e64d10c78b91bbf3f622ba64e12af55ffdcb96551324e624f32f3f24e4851099919fdc06e46be23b8b7f240167aa5748202164489428ae200634ac810d5166e48d109991d8087db4dd8f5cf1103883c48b3283e35293446225e4a7949fcf88c442ac16b86007282841145520997937226f04df787a3732230f815386e082313bbcd38bb9d80c6ef77c7c68d1a8f9d4bc74ce7a7139529670e561da042f6fa4504121058a6488314acc1ba1933e9eace92a616fa4da4a7f4309d28c91798a95b03346ecfbd1618391264e9ed08625334696f4277e6fee51d16d933c15616d9218779ba448be0141186a5409beffa888c2119bbab9910d08c2906c1982d6e16a2176c42c210df81d38bf36c1f7208422e85fddd7d62f460d3e08239186100557fc16e52604f9653e5232c49dd5c028b04647a5434696bf2a7d356a3531cbd70dc9f2e120234bfc1e148dda046f2391089b060f4220950d47301c1c2b9278a215a532672661e4515aa456fb9ea416c8c69e92895853390fc568c485a72fbe2789d8a93e4c48d9236fba230dd177ca93298412890b2f698c71434285222427bf1824e7118b134f6f56d9a7a4d85346292726a59452ca18658c92c618a59452ca3e26d970e1e7ecc08df2bd57e99436eb4155c18eb2626ce4425ad84d604a604ae0082f959f50969131d23eedd3d333c5f56cdc0c28d3775b8ac4ad00789171fa6a9f0cc97867a1543755914c3f05957100bcfe823264fc6539645ca6ab2900326dabaaaa76da4425146daa96149259b89d149aa1afc9b7bfccd1942cace3655c1fc3c5df4b6119550e73f487e3689394e32e468e010377a49cf217b823b9c0a516d805779665856ad96549a05b61f9237d4657b1ac5d69c9ec8b2c69d1e84e75bdabae8aa33b54a7c2d67274c77ee596a33b52ac7cfab4dc08213356dd224beae82ad8657aa5629afaebba7eb9ee4a1ecbb270f60bc30e457557be52dfa8ecd2ca0bcf94c6cd2976240f56f1ec11c31da9e09d36cd545f6fb4b292599935aad6b22c06865b3ffac94a9f36d1af70b289fca1d95a8b3be933aad9679623c3f0ca7c65c7e44f87e15a8bb13665192ed5bfdc05913b7b9b4c36b1f289ccd247fee01daa2385ac775467f424c949cb5e05f016295474f52b9885a34ab2fbc84ec382a912e94375e0885e009c1cc282bce2e1903b9006bd68009f71daa451389c9efe34ea86d3d32b9e0e700ec5137d2b4f4b81a1e2f21ae576d327dfcf9c78a2b7f6debc6daf6db8d9ed5b7ecd9c18337362cc9b99b981ebb21b8e03277744a7330680bbce38daa44df43770f4a74d513b0bee48dcca3c1ec5c09d85f1c205ee48b83bc59d2973d861b683ab4e97697ac5c3814aa03b91e45ce15af85d9abe512b3a5a858eb2a174c32bce74ec869bde5178aa4a4dc15c3d8976da003a5bb8b38936d1674ada14869bc275b40a997e326954379bc874ea38d12895d34f9e4695ee5f66b99d4a481726b1d78a81e1dad7a71fbb5e86cd21ceb2aae56c64ce80a4293dc605f0abc4c5f88d7139c3c2bdbcd90a2b71300ee3a5beacaaaa2a9a6ab32c0cebae67d656d9e7007158bf329677db6bc5190bb6e95c370cb10b7bd565d8a62d16dcc1bc625936f2bdb78795efb36c47cb550e93830dd1abb893448460163b4c3d86ff5259e564ce0e0371d867b873f10ac35c6e2fd339401cd9abcea505eeba728133ac47758b3b582bcbc3befab0afd561200e1b9d8ddce29d8d6c69d98eed15671b9703a461b5c02d685a5cd6aa6439ac0bc3300cc32a5c8f713090c67517eb32b165bbb6dbb7d4cb3efbcb7a64380748a37ec3d9ad5fcf01e2a8bf3a799d856bc1dbadcc0796b1e700716096f55196c3b259c6bd6cadb5364be1eefdbb39401c30df9be5b8185e1b978ddc5dd2b22ccbaabfb66327926d3a6f380748e352f9c5692f3ee25e9c761a75ba6cd48b5798eab489ee6071ab12bad3262abac5272e0607e31817e32f7b816509972e13633c857bf765185c17e35449a3aa4ea32a1a6dc4548900b837f3b21898ea70e16271eb6ca25155e7e950650a0565327dda94e13944b5673aaef6ba698f590eed57c4aa8eea649f48b457ef64ae7037737a3a3184ab7dbbf64b663db4d75fd52deeb27e590c561c66e1ae3e08d46e719a56939c3e9dc89950fa447326923a87a80ea55427d25aeb5cc2edec4bd65fa6efee4b16a63a544914b7c2f4a6e23964c49d4eb4893ec36a768bcbaa0a03baf519c64d286da2b7c892942cc3e80d567d7b0704c661595cecf5f52a97e98abb54b824a7576e42e998d3e9e7d089a34afa348722bd69d4cbf42a19a63a1816ae852792143c73e411f7ba9c0d660f04c675449ec8f5409d55922b119e05fca0c00f36d6be6edb7dbc26b9bea6660c60f7018165cca751177e13ca95e454b31c96a34ada44ed4e1b80de1e71eb2f98f2975d486ca75f103b714596dcea3632578bb3af929c7e55556765755597e959ddcf6cc7a5a9afea2fcefe9a96750bdbc8f7d36b75c2a5ea6f862ae9137d2d5597b9c254c7889b82e90d9e436da2f6e6be3974c4edfa87ea501daa84ee5c310977e3fa099d36058083bf816392610a00dc6bd30bbc0c9f266d6aa263e40e7cd231d2a797c8ddcdf85d37d14e74308b0e3e814275a4904dc74c1f7845132be014108a0e2a814ec026e012dd8d9939363a660e8d3aa67fe2899efe362a3b7d4dacd8c1c60c17ddad37d3db45fa1465d026323cc61c863f8550323c0c7aaa1363e013ef04af2443085fa23a53d01e2ba84f13fa93afa040995e0ac51858e49de097c8b6890b9dc8907efac4180bcc1c7828f0221f2b369c1373329d4331e6a54f3f31465a70d43ffd9301c98810f0c2b3ddd3bf5ac629ac96b1536de28142896cc385ef64247573386e75d256bcd3bb941594a9fb701727ec486197e0d201a9f5cae27854afb0b2ae571ef71dd481e1ed95863b9bb8713127b97edb54ff3ac6f6a9be56fa99bd7bd4721d11d97636dbead8e33bcb91ed63d6c3869364a77f1563d826e65fd6566b511ef0b476b2c21faa395df05e8c369e62a9476e336c57f7eb483bf667774f49b9773df9cc47ec186347283c29adbd97443a0c8cf471d1af0d110805401149ebc4f89ae448a78c398deaac1359e4eedd239970bb78241e21451d2c22c949c1177c8e7c5218a17d304b2933176d7a52c6486a53122ebce949818a0e40e1832c7e50c4c51e6216d7491e97a5c376b62cf6ebfeb23d19debac559f11547637d68bfb06dd3f5783999f9d07085659b2e78f9b8c75d96a3ba3e2ec6dd10edd232fc6ed3b0b230ac03dec28ae3016f310ee64b265633db73f0dda6b31022b0fc72d8e054816c02cf7bf0124a2804cc1de3e96db24c0f8fedc434251ef073e29a8a835c8048a67888799b99271e623e88284f3c04bc4d167185fd05293f9b3094e1654e8677024e86b2bbd29af9909252794a29ee496b8c3ee063673ee0272704cc12dbc01c1b7744e08950187b70f50e0dd339a0e9c2d71eb822f074a81982c833cd983c748ca94ff02f303b34eafadbb84ee6ed3f74dbb7cbb2b2ec17275fc6c1bc71d2caac5f70dbb04defc8b2ec3267b8c423fbf62dbb382c6ed66672cbb84ee6ec3f344aebec9724c32df1b86eddba34ed1b37ba5193da963bc3369db577b6437b4dd4b4cbace1120fedd9336d9b2412f6d22698a18b36c19aee1ccf434d8eec3a60d60e65da547140da0433ce469b60a094b2fe6894962d809319c325e2d62bee6ca553c6be758dcbbe713eb46b3a0c4124bf87437db5ae7134f52f5fd7c334ee870d77daaf5f170744e896786cbf7e6d3641005920e35eda7429dcee0961398818f3a37d9e051a55735f974f87972fedd24eb31df5dab52a2e919c7133da8449e1f61b1e5adced78b9a6e6eb4162beb00d17449b66987e2e116deadb04d1a68ec2a51203c285cf91b3f17080b7620a1632c2f90971d7376515072aff7a685c8ad74188f9da83c52fab99d8a6a6e6794827eefa3535bf5c8a97b871709578c4bfd35ac5e54a3c22a6b17faf55dcf8ea15ee61b1bdc54172ade256ece79ada04ff2e0a37e28650b8e435e7ed8bb13e71ad3015ca5675ce171b4f6badb738d68adf84efd20a08619c73d6396784af33c65823a4908746fdf021c6cc1b327f26911e96b9416a28a4833c8f20840229dc085d4ad3d5cb0fc9d5ac73ce6b225ba9050f2bdc4951754d1369d535117cc655224c5465971087e8198e15acb4ec328d55bfae8b32ed9d066b8aa6a564b8bbde65d730b6996d1f7fc1cae2aed2195b042b1210460821b5f6d2525b6d07d55a35ec95bd34edba2e6b6d66adbdae65d5aaacaaba24aca91426689205909f1526d031414e8622c8cf8a1214c9d7165f6a91a6695a1571341dbdfd10aa69f52251f5aa8db8caea649ed56ba69046c43e8217c18b46227891768ca3d9fe4617629710c7e898866b220df66d749916bdb318d4e84aca8a08fb36c2f222dc5988c3a2908686a5cd7a5cd9c21d7da96f3185342a9629b04ad1c493269c34c1a409253987fcac20c1508c1dbd4de7a83566e321d5e03b28d6441d44b2d5880819f26c72ed273415ab5abd96454dccf0b2d3fefeb4a04c9f43c3346ed426fbeb573677d054dc41ac7657841f4f8d37dcdbebafe856ed29dc7ba75a5dc45d6ee366c6704784524aa29046c472082462a58de2057d044e0bf12ab2e49dfec29c8cd85a34dcf8ea7aefba7067dd8ab2c29d0db532b1ce1a1a8ae34b0c1aa574c34b34dc08284d002ba2540f6784c019edd8dfcc3b0ea5373e40439e1f7ad6e3e9bd72a4369128a52930e439e7841804970ed15a243f203a149364976911508cc96ee2e99d74a70808e29b1843d3f04eefcf88fc3e95c8ef5504f99ddec498971dc9ef2fbe4c0a014916996293095e9ac6591ce5ea6973364b7941acda0c6745faf46c66f34db6447603778090ada1fcb09fbef90b269e4c6d7adf89e276a68a736122bc2053dcd523f9d1a187271eba01755eb63dca8ab4e9cd596ff2bb801865186724a64337b89d0848d24089238690eb45402227af5cec4f0e88519c7959c4194e9b5e762384db653774e8e1f09edde4f78e0e1d813b59c85d9693dd44986a43be71b919b242a487d0ea0029ee4e14657821916e6a03c447296e47243fab1bc2c4b6d1b216d37494c90b903c340f0bd01a77f495d5321688516e6c2b18b904f51ee9ab75fd16bef092ee0b6853ac300f322fcb441e602a901467c8147737727cc4f14e6c3589f134460c1b15a7c472ced930be8804769493565b59179669db15a5a88c56585a482e2d4a2e5ec088710ecb7801006ca2516d8279371cbe7ca585a506f7f24e3764d365fa0600bcc8c0dc63c078e1a2d4c285d4c2b232524911dd4dcbb0cbaa6ca5535a4b8449ca2b379ae285ebe5f7600382f0687426351bae47e9a57df4f23dc6d4a558629410fdecc32104cc3d5e942819f6488095502a39928344678727f50314243474838324e806e748ce0e4faac7e707e806e7480e121d182153d08148cfc70473134e2a1ef949d91f24298b24286583765276e70da5ec1b4ad994b5f0591651445144514451e200a0f405314cde640b6f2db416a75071e5cd7d7559ebbab87b8ba3d9dedb6fbfec7d95f1f02037ede6e45d59085537485a0f078b5f9b3a6f4eb48005cbbdeae2242ad8dee237538762cc9146654dc81cbbfdde9a6176f3a8493aa3c499591287b215fa89a77e503cf583725ec45dc65d397e01477658834628d15b52bec292c2b17cc4d1dcb2f2abb2b0b0e011375b444d6a508c098a3568c4c9cc12af88402b293f31afb4b4b4287342864c18b1ace0242af8875bc1efe130e25eb6720c8a423146e510d7aeb2bd19fdaebc5f599ef27e5dc3d321c8cd198eecf288e81a712b177134a7ac3c3bcbefcaaf6ae5d60acb8a8b298fc0cbbc527f47242e8eb8f77048e98743c6a9d0b82656b9174f778493a8e0fb7b6d156dae433731a65f5935cbc9f272b28936f5ab43314e2cca95472696c9fc2ccbb169daa6596b2da665963bd2c158d6e26cae92d4cb0ccb2373be58723d1b77c7cbf13b5e86cf62512e101faeeea494fd7c68131008a451b061c386f5407c6813057c0002a50f4024fe816fcc1f1f82e27fb0f06591fb0fb77c8459e41b2ac290f35cb4a9bb3f7deebbc4a59b476d2299224ceec9d076e0ca72c83f0e63c38d3dbc27c1f98c2cf5616e3c77ee211226457267ba1d1b56019b9ff5d64a58619218db36c402e627ff4cf05248963025649a7163075a29b536ce0ace6ac2292b2c63f28102f0369e12c73ec43cb429fea05c031ac79f1c7f346cf9e303051a05444a4992403f6ac8f28607b992e0c26c2b92cb84314a39e19c104bc195b983c931478ca336cd49a9a9c25aa5f61e0e108fda242fb114c8cfc3571e5cf90e264b28670a1a4b0ccbb9f24064c679d2a797279771e23b887892f3f224d2bdd77e8796565a6965a5b83365ec0412669946f21331345c197c6306aae38d39e76f406e8709dcd8a151f0489cf002920e0841c2a03b5a9fa7dc55b99a2188647a5f712f574e08fa7a6f39d12f58435fdfc3817236a26a331dd82f87dd9ebeaeb6d6082176c718658c360da18441b8e29fa5b3f6f0d080782262622a024142507284fdb2cc026a0328ad3cb429461e76f861fde0a1a701d68d1daa1b96b5c30d7be3c60e3c34e007a53b60b6b9b083a931a94d170bf7d626c468c346b461233f27366c1c5159f04148036f4158d94ab510638c7df9883536840b1e928ef40c291fa9512fe5639a01bb70bd27f41c420189858290bd24dbd9471b85d4738f724be9e482500a32f4bcc025a4284310f6e2e3f382bd4882eb9d0950409c6ec29094a45b199d90cafd196dc2b090390d310e01b7534d7e72c79926752f21772e725baad51ad45a6bec3e84b452ced4a64823c4d1be1b420ec6042d6e873e457cc389e96d8a8d8ad4a6d4030791f112a34a1a0913200bd6f0524790548a2d0c49b1852fe44829b0c09152cec92305163a99546bb5560a2c9c482c7aa4c0e289145c40024ac1851368af4df605d79fccaf5155d2fc1a65cd57f8656be63cd1a64b3ad126a87365a8e4e1705da62f539baecb2bdcf87e590ff9082beb1857b30feb104f4cb64a0ab7c4b6b591996234d89dafd86b9603c34954305ca3c43e3118392983c02c3fe931aa52c22e33a6c29530fc37f3d2a7eb1817e2b188990ecb43ce785def2813db82c6c51dda04b51e22be71658fd884ef2acc18d7d94ce3a3e44ad87c9bae67dc0b775d46211f50c40b6813fcc5c5fc3a26e5c28a2c9930f3314b7f4272dc365dd7f375a097469578cc1c3f73c42eda74fdba1e1006e47a2482933797874675d6038bd7655adb5e1289ee755dd72594afebba2ea8245f5074b7201ad5bd9f7cfdbacd6581365d40da7461f1ba0f8dc27e9d028d8af8479b2e1e7670fbe260beb00bc344b4e97abce25e3cdecb8569e0d6732aa5fdcdb28eacb5d57e623ab18c51b05b684137ffe89cf4c5860f8312a3adaafa83e6e91f349366923b8b66d24c6080cdedfa7be95ed54c1e10c4167730eb61e569653b585ef330b1a62dfb755508e12b47231f85b0d654ee5adcc2ea720b6f2b1fe2a95d5c0e2f5fbd73b1448458d69bc7ea1ecbd1b84838a3ad892e9fd66367d3efeaab0adbaa82c914dbb4cbab8abb66525515ee80e801ef5259ecf2d9c1647b1f62cca5b5b22db08bc525694ab955f5aab26f1e88a3bac55555b58099e559b6c3bec234d55d8e4d4ba4324bd35ed98e791a8b5bccfb40b12de10e66b6a859e40b4a082184d205573c90466461a9f08b312bef2dc3a618b3825b05a76017c3ec1d102488ed1beb1f401cb1febaf0656fbd03828469ecab5b31f6505d425a75367dddfa49558f6fb1dda2950f9456df7e6476d949f3555dd5655fdd46c760afbe43a366cc9ba9de3f80389a497ed9310efbe4669591515423288061e10239e2d2548f1d910b5adf0127d7c91f72f543eeaad7cbf40f190852a6b87f0069c4988734913a0412b1a6cb1a6c3cdabf7d0cd8dd19edbeacaa290f5fd37736eed4c1c58447a74d10765815f7fdc5e667b39517b93f2f28638cb16504c04c271f00b21192e02411676096040c8ce049b18089192b53a1822759c29c467518129d46512a54d093e30c854f64aa84dc8d72c7981faca5f9072d5c9e9d1f254f346192e7610e74e22237096ed73d334b59c2ed22a5ccc3d301a280c78b812980277a8a03201a644ae10b327df79800731e0e14168941b8110311abe35410e73aa555154fd7ab5f1707713878433f01fbb63710278836d1733fb4895e02f4f06608a7515d3fc945e8d01299f6d0eb27fde4544889dc91728ca25be4a6729ec8f3915bc9503aa68bbcd3fc125934f1a49d8002afe8180b1c32893c8db287f2e449162f0b27195a01a7c8545aee713b5e969163c9a2ce3abf0c776f8a3c9f0483393646ab3a9685cb438c8133a5eb4432fd4b63cfbe838d19308b36d113fd166e7d4c82c5499d1c292d8e346e26e88a12a286884c63133310b3c4dd84b76d823964f783107d63bb1feae963cc725c3f08d13759e21ac9559a1fea3bcb81037d5bda026aadb5316279186cd701b3c8fae4ac534e84ab2b7a4d7df51a0dd00fc9d585a8d86672b592590e5b61c7b28b6a0e6bd3ec83448caba9d9c29df520315bbfa8bd280e1273dfeaa1bb2137990eb9c996f4c215427ee1d657975fb876c6575cdfd69a1a6f32c54432289fb836cb4de0c25ce5ec39e7ac6ae475410be411d77ba9c941af0366dbd824b978a3b4bf5fd67ca6ab3acc1ad50f87ebe240ae4cd7a31412a5cc6083c1860d1b5815aefc91d40c5e116edc7899703a0982be7e1e03f534f23df1bbd5499b226c206a5c824f6715c325da14310c8a4357e25247b9871102c9a6820d1b2dab7c8c32b2e60069c8cf37ed08136394092f8503a099c201509e2af3cd6b27858332cc9f3c63e7e8518f504883b2f7e4fbd9c94f6437f9fd450ac9e52fcbe17299ce4c70b35f6ff196afc85cfa833c5ac7cd3927f7548fcf0f129d1d1e7803142434546bad260bc3436bad11e39818833c40f1c5a865f317cb2b1fd555b8ce2a224a8e43f44114e89d2084300531884188e49de0b17782c7c9b29c0c08ecbf7782dfe0b6dd20c1dcf762fe4ef017dee2ec2fd7511caad3d11e1a941f4e15610efabecce890366266c9e462aa0477be8b293befc2c5297874cc3622431e9e1839888580b99b3db64876e15ece6076c101793800cd9eac8928d4a81a83ba0a73a013402c0f84cc29268ea99e986ad49c02468e0878038f64a8140f734cd2b8147b22500c6a03bc7e4682db452027908ba9d8d306a8de2475454fcee267f66068c846704b3daac3c347ba7dd22d4285ce10949beb9919d601c9d81b7a410fe8a55ecff3793f11c21a2019fb03cada65bafe6534c8cc1aee80640ca3dca3992f619fefb0e824065d08479ce4b61814819c34f6f99e487a78d37066cd40a121882146d0768cdb5a8e6cdc1aab907e6ecf1467d6350efbc575f096cdcc49703e13a3ba6fc6b29a08479e123cc0a2938ee9bf79c108148378e6ce853d8ac84c224cb501de63863caf7a046a949346558fe2c618778450058db760e02545e4cdec29e13967758bc89b9e7ac5fd232dc2eda0ce8410eedc47dcd922395e05432410fa40104502e88894077a46e0235360c4953089001e053c281299766d046c39e452feb28981362253dc151125efb8b823bd256585ab89dfd139e20b5e9b99610a89c3401b91492d5efc7ac1bd9996ace58a6ffae43783f29b50666cf169693122c3bf2e005d117bd1720bb469c70820da881cdfb2c3419d233a4a8cc8ddec89a98a857cbf3d661148e8760f0848c480dc08045be8ab598e963622538c8136224f6c01cc02b140a338e844964313fd6814ea10890f54903b4844bd4596d4222d44237729d831ecdd4a86a41bbcd3cb70a807efa480a1281e8d975b329088e79c13cf1ed39b3e3eb30767604ef82a44f6527cf62ec336334728b3800b6630464c6bc9d1729946c28b813cefb4842b0526e477088417d37f44c8af8afca013f26b1cb368d95d7c929f851c8c10c20821e56a88c82d2dda275753738b100932e9168129301c915360069f756e69895c929b21dc0e106e66e087cc2cc1407c89c73cfcc440c49af580c7002ef58079e530af7ce2aee54310c918b0f2ca653a624e9e4cd71ddc6e36d18cb8f4f01a863c6d823c31f6c429daf42850c58d1c102f19c214a42f49ffcab4185f621781322e02a4b7e0075d64388a2122c2edda8cdc72975f2edc8f0ac56d79f77c227099deb8247d8d4b4204c56f88be085b0435ecd34949c33a3a6bb3a751f006094d28eff447c320f7e6a1923ebd8deb80e4ed7047b334b80375b077504709f64851499b5edea0cece08c3a51e37c8ccdb2f17040ade7e41987d1302cbb2ed6230fb76b30dd30e330dcb36c8e302973044c2f226cc69d3a341d8340ae21fda0464e7c607737c8e3f1ae5f2f7083c2cbb8cb28b0b1797cb8e813ccf7632e48931d38a3ebde36ef674b3a7455e40269e3d3ab8f0ddec21715d843866f124c62ca250de2eee9eb35ff149a3b24d16f109182ebc25149fc89b46915cdc51c7cc9eed1177d82f23dced50daf4bee9b8db79c06f9f3d31065a1b3f391a884bf414f7a840bc6c9fdcb6bd3884839ee983c5149c3e6d80077966cf0d9c346af64c2baa78a79731dcd9981c1f20c23bbdac55317529cbb79e8ee5d7bb2d4017bbc85d047ab5c1b57087e5eb2505366422a44d2fe27737adba2207535c056efc8e1eed1526a24daf9b40f3a79b3e44f2cbe0cbb21c99868178c910bee489858cb2dba6f7865afe2ea4ffa6152d5c091e96621477facc9e363d25f715e10344807f2ff5585830bc2a2a2b1c0f26b8ddec793ad0a743e7379b74cf0792e7a194173be4b24fae72250bcb72c0aba2035351c13673077688319c8199a423e4a1b93e492e484cda70610a3b69d3a3290a538da2f851da337be2e9d114e4793c346234421e988a4112b8dd1beaec7b4a8497746f88884695b087a40899f6c0bfb4e93f14771328bfd91331bd2690365ff697fde28e947dc3ddd5304f8c79dd0d79ba421e8c0d375ef7b90eb96b36c9ef95e3b199b97189499fde057920cffc819309b77b29d38c3699be73bbd933a70f4f1a72ec993dd38a2bf2fb2cd231cf07c9fb6cd2a84784a126f97d3ac9eff01088084359e46e0ae5772149094d2177134a7e74429e46753b402632efd0a8124c9e3df327e26ece9ed718cf9eec060aa982cfebe1be211891ca4f0df90de1668a9c8ac07bc4424a6fc6c6133c4c770372379e20299ee0923a83fb66525ab89e01ee1bc2113e19d5f513d94d56a4518f0b433822f5ea12f9dde526bf5f47a07d8f57ea652198735a9cdd489c861723028aa7a1a7833da98a4009232e028a31d6de4ba2d7e9508cc98c6c398220bfcf263698af548c9924d29512c3bd0ecf4c553f575022bf2b209155f2ab428a27f9e567050874aafca4b0821a722702eab29b7893b26e200f6e97dde8643ed94f7693e2c93bf9929ebbec468898dd644cdc6ee433f2b1d6aa32cc30c30c21cc9d0848450749eeae75932d21435466b66f580ad04f0af6e3a33dc5e7ea817f3346b46ff84ac5d3c34568f8ea89a7f70eb39b9d4be54518b1ac632f4e3ab2e1228c6c9be5f294a7bc252bc248967d6bf1eddbe82c4518c18e847623d8081791b978f6acf495228ca81c09ed42700a3053c24560a563c75ee02254b0916bd73eba50d00c2002bcf839dd0549a8054b0ec669dcc69176463ea49d15a19d15219f9ef878232a2923da91b0701148c02833462edcb935305fa987c33bc40109a7cb6e7e72d7c2c392b393bb1521d24e8c69013a91760840da690122ede4772d40412d40a923194e3cbd5fdb7284d43d43286ea7b20367deccdf0c028c7c588258725684588258529a85939d243a124fef484b8d9ced2c34340d17a17d0517617df49ef519da09f0f7e24900df0ef32bc5928361d1560377ef07067756c30f8800b8bb38e0ee05cdb85203c0dd13cadd4db1e4c4980b2300dcd91b29114b4e7e5f118a31d7562b42a9bb2274a5ded027ee9e4f5f2988bb37d45d298c274bf558d6359f959f1620d25db618fff6f72b28c608d15eb61dc349c09916c75218f612d6e322e51de69392f2172a30de613fa5d2b177efc7858b67ef1ed00b9c049c79f194772f08064e02cec0b8cabb27b4f2d13b9896b3bcbbe1f263924e0c4cba522424248ed4c29172e28994221d21f1c41369289e4842f1440a8aa71e12503ca538d20f47c2e1483bf1d43d9fe773537d959d9f13ee4c1968a7850727bfb70059d9df5b822cec429ba9654813597f27dd58d65f3c55cfb2bf0cabf808b1b04a4f3cbd6b5825154fefd6ef865578b4074008865576e2e99d27c66c58e5c7843b9800e0ce5a372eee6e85bb9722752a3b7fcf74628c90212a3338059869b990ec297fcf70628c10eb2a7fcf8ec41821da477fcf72628c10ec2c7fcf90c41821db57ce069f9922529ec1a8dcba31ba467af75238059821b11c7b4b14a1992256bebd7b3d3ab82fa583d38d7cde100b370a8aa7f7156e24144fef236e04144fef2adce8871bf9c4d37bc68d86e2e91d4b6d5ae613635690c4d3bb905050101050f77e5a8e8c7cf27b0b929d961c9d96233288c113afc6fb6b03c41d40a1031ef4c007496640831a28f901109804410851d860c90d709003d8f37007b76309caef9dca4e7e6719a2d85546d94a0bcb351c6ca6481237664877695172f162bbf57716a1a8c188f114ee37fcbde56606076e167e91244833325e24893b03801749c2cebc1cfb3b4b508c4122468912a54812303337e09b8469e61a7935de8b24f1995be4d578bf376d80f7770070b704afc6fb0b779b7835de31ee92e0d57897c15d13bc1aef98bb277835de37eea2e0d578e7b8db8157e3fddc55e2d5788fc15d0fbc1aef30b8fb8157e35de3ee12afc6fb0beea6e0d57877c15d15bc1aef25ee3af16abcb7e0ee0a5e8d7717eeb2e0d5782771b705afc67b0b77997835de59b80b8257e37d85bb217835de47dc15c1abf1aec2dd11bc1aaf46554354e31e8ae1be54cd4f0a2b94e18a70672fee6e853b52c4dd1b77a6796fe0adf2a3220a457c7237757e5b908d200c37bf2a86d081dc4d9d08c170657e55482124847b0bb3902b9cfc72f2bb91b975e81013b79b3a53275a0b844927e312fc9ba9a750279ede6106adcb340dac6f8c3bf820105a399e61146da0b0e2d7a6b73daa9fa8440d7595494f3245330000004010001314002030140c888462c160389ec981b07d14000c9ba05674509b874110630a19630c101000000180110012240000be33f469c66da900e3fac47aac3cfbc829cd24ccf63251a4300c543e7aec8535b5b1cadf2488b1bafc70505d44f7b160a30aa6fee2990bfa21bfebb584b0c47a75cd40d8370e57ff379c55c729655cd557179c49744ce9d5529299b88bc853448cb82d7072190344cd7a80990aa22adcda1826d685290b37d61f23f94bdf931cb343483d1de5c1f51615bda974052c2d214a7fef4de30e2b42c1156d7af37af08f66bad12fc459b27e6cfd627efd99769a5c578dd920768c2f9279f8cf5c832b598e654fd8c4c39a2c09658f3664c12ad0871a26c8cc47e382e149504049ce600f35983199fc90c553636c33941a34f66c009507270ce9ebce0990adf8aa3b024c30645be145a8fa017b4bb019d84b279ea6bc4ce9f4d1644dfa1415c4ff65ae48ae050dbb8f5170b8b92ed3a67eb7b07119cfff5e2975c803874f1f0823a14c4d27081377c6c31ce9164230ace45d8e4ed12075791c58b931625a92a4f407d8377a6d2fa1f864d29d22be9c03ca490e1f2c61d7f3cdde971388a0ce81c80c94a8d3a47a3fe9bd77688526d2578a01f4f8ea384657212670b61bdc2e5a1ddf6c9f5cd14e013a92e822895f27cdea52c5dd1b2ae7d9ad330a8431742409d4c8a69daab0870573d7cf5f9d63a5eba56ebc5189473d4e5399cc1f66f5dcf82934a55fe167e6966cdcf67db1c70b30c9a810ce998a2784405995720005acd2e4f1ba084c8ff3aedaefd0e154224b45885f1bbe7431f32135e9c22f2350062c53104febb32fca75f5702da497ffc8514d05e586cc641eaad786c18c606fe7164674e32cf755a0b05cd4d2844a41029e954d24191fe480980e6165937e6b47024c6bbe148963cc1869bf1f007a1ad4a767dda84dc840ff99366715f21f5450f53f6ade704d5b5333da8d4dd0a5131f3af801db1738c44282d9551b962f4d1c829adc0d06c1b0f956f1c792ff509bfa8240ab86ba1efd3ddf5b197913e3319be6389e616b26dfe469c04e939ff467394d98f5635c7d27c263d704be585e1381339c0d349337c3c98b7f9b2614e1baaf0d2ca223fcf65dd6fc8915461f46d605e2bb2656d6683f1eced123076c7ed8261a326a0b4c09c5eacfe8f05931c2528ff9fe929c8bcecce99423ea4aa1a0e95da4fec7c7b92efd4eebf71c4128dbc3d1c90df23f9b4714fdc03af167ac8f6eff2f1ca7f02efdbc0977e5a590de9951dd8a6556bb25caf7ae18a1c518679373b342f32fc099c509054737b1686dcd647949a0e6f7a412d37a9197a96466fff0e9b61f673e584eebc90c6eb02ac5613f91882511d381a8d10f5c5072538ff66c775d717056bc4b43cba3aa198ea569c8026b37a1852ca69c5c80f4449a05a14cf6432685ac07f7f8c768c1d9e05232aafe885c1092ba3c8fda0c56580c413eed2b3c449267df4e5123c91ee89b9dfa233952848cfe3cc06c7bbfb25b8ab703e8ea004cf549ee548507d3c31406bf610cc30cf62ecdcbf68fd324af866531ad683b56e20c5289861ce2c81438b485ee1a40e2bb329b3752bb658100824f8994c77d1b258830876d18159a8b84fa4137932b9c7a482593089849c3ccc164c3534cf06fd5bbd6e073291a2868c66c2fe53b8a73ac4e6e455d16a586485bf66ed94e2f91a2f243d5b4cf570cdb29894a7f493e74f2fbd39d84fd21ab2a1948e9622afb185a6b0ae0d68c786279808ecaa8048a36f86f0b723793732a819dd4aaa5a526b24caf6fe400521a9d94a259f64f02ca6e1a50b89b9221150a1bba6cf4fe6fa01481d91728a051ebce5092be9b08716c488bb97985b9a3d7c7f89d1c2d6018c991e15ef6b74e865dbac784d96e8fde37209a4272c923fe904f4beaade7b58c7e5aa138ff3f4f437904572a3a625d68152d57431f490a26e1d7689660a9844e9ef861a5757a7a501bdb82331b100259339f72945b64a2bcc01f4b2f24637cdf257d648abb2230d2046a0c549ca88c80cd585667df948c09a1a31b9d1e48158fd8681fece9447755d626dda2b7b718749be04235c5bbcf5c4e8ac35256888bcd55d56c888bb1486758eb10919fdcb7379a2e1547be7698c339a5b5c661ec150eb0b5b5f2dda2374df294a6416fd4d3a11a9f621c95ccee9f5f4abaf497c86493ebeced9cd718908951ee11dc8e993d30992498e5cb3dac4f6e47e0295a65b52d232197b0b4064b86c5c5951a2d3d9434edd7c4503f201882faa8c7c8ff261908050c47b69f34821a577728e90f72732391a1b439590c27263e389ae0617bc877e0ca2a2ea94e33e75d0c4025631f60ca492519a82efc2256c639365a3b2dddef116da47c2d5e1a32ba530a8fe886617e6b9eb689e312520ed9a495fd0f4c6559ef54b7eda73c7c5eaf29e69367595a1d0b9bf0476e0e66c4be55d89b4e27ad8571455fc0d9fb9b87f674e413102d2451b50103592fb719a9405f6eb355626120e2905f290ff7015356c64517fa3eb91c29173b540adae97bb2aea13f8dc5cc24b0bdc26a80e5e684309059d4443f247b3f6cabe0c5383c2bdd18b05943612b3b6c0a973cb052fd59d77a2b73db913d7a7d9e23d4d9de0b2e799df0709a7caa53e3dea44ba75ad08840937dbec85c26b40b94beaba445f059642c3e140fbfb3145062d3ae745bcd794ed55b0a241611c83168e1b9c2d6aeee96e01f54af83a7b5d849c440ce5b1fda953ecc1827439b840a549857ab6fca66db3e8a2f43161e612afa8c981d163bab608d5589a6da3cae4f873f24ca3409fc02ecdf9cda607d0e1a2c714a6dba04d01297ec7729785b1cdeb43a68842cb2fc2f73414cbbf6438e6066e0cefc2df04497dbff03397125b0e18d9abba5782c48f340c717ebe4468d9243005ad657984449602acdf98ed6371ae4fcdea94e1e0438c51a6b7effb6828dafee85109c96633b5c6735dcc890a202c019cd8ae85aa6d4cf9b709d86628cf7363c19a68811755d791d209be456d896880be022c1ef393426b7ad9cebd287c497d74a92fec2dbe736715f690687c9455ac3fdd0e6c34ca4583927cb37707887744be94a519db6cd88d9472d6ce17edc9b6554434a611aba7907a6fd2d0343d215100280bd0abebf0217caaf919df62adc7561c2a4b00a2f7e81453ca3798ed0af00e7340c1f8c6f9e6ac1c5292a20bc8356ae486ad1b97669a233e646a29a25e94a63177c5847e124bc97d4b184ccd35109417a29ea497c700625838c2c6b01826e6b84b1da1500b41fa6de9db657a15d95726120d59d3907d8254fcd029048edc95e71b1c8930a40826bfcfbeb7d5130bf62d4131f47bafe19b0a5600b9607bc0d4e37e4ed7461a44c9668bfb94f5b6bad1fbf7e8880faf3bf05025bf14f73978b1a473911ddbd231eef10a6db33a619fcdff7ba4147ae66cb1a7ac1d1168bb5256511777ec5946c7f5f9a04ba61ee3918362f82af097e55dd82a9e7dadd3123bf0a33270ad18a8d9ed357dcec260eeabd199f69613ead3594e88e977fcc84c3c6fffffb2383c561c6a92c51de6b28b08a3a436289548e28588bc32150c9ef2721e6f4e081ec984825274c0a98e492b799d9e92e20d61781796a78f595258ab3a634a6c93410ccb672ecda7f9b36845a2cc2406be8ae397e7ade051e2f2657f4aa8cb2046849342cfb08d9d80ccb73f8f1059959f07d8082a5b193a8600e5708b4f009548fee50d71d01f032b8e0d9f9c4875fd0ef39ccaf0c51f2fcc25af455d04c26a19c8c222e7efd7080e518f7823b744550d00dd208759aef08d560239048511aadbc61467daea229b60f4d21c4d912932ca5c5a9dcdd14021cf3799599c191a5e703974003e62559596c7066bb4f05c404452a113ed35ea9fc41fd9e18b4e5b186d29c76ff3d67e288d307a2913ed75b75b8420f7126649897d6e57d2b4f63660ac7d501906bd35e8b4e61b541a9aa3e4e37ee8c2493f5d73a215052577fe5743c69f5c11de2f4a483d3ea22c1dba143d3a8f7ff8c898328c57049369547b26d8da8f4110e0b92610cdcae0de02df11d9a348f00f42c8f269e64a39ebe9212ee8b26887b96b5869bb230ac7af00fe5a153cf7929506bdb04720b58c0419cb95aa5299b524bf94599d9332750c08b044bcc59cfd67a0d889561eb020ed7b2cfa538f3e58305f77116e207f0cf980dea1706b4b74ae7ae057ec36962e0b71b222f17e9b199a23b07b72e5e3aad165fb238a5f610e9091902c56d65dafb9eb9939ccd1ef606f320db5e6dcf50cdb3a5f2d8323ca20095d8c4a24c95293ad0092c217b2673e3fe1d3d359a662779a48f5f1d2a8b877b20d4a373c5e249d88d9750fb97e25e103c9a3ffc2895e8be0fa363468395d95f716479691ff6b415959d14dfb62cf33d6318d14c6bc7b3404113aafba3e35d9ea71f243338c2cbf6a1e7ffd7bbdb97cbe72d3990764c63f8cef247e96cb94ae010de755a9b4c7a16d0c433edf50a10c0351ccdb0978bc0325030bc79b3bc5f6940882f14fe5c670b9b47327e561fc74f8cb4def5d322f990a0867fb874ecfcd60ab80b7ef616ea676d27e35061d1162f4a710ad4a580c6b17cbefd31c9bb75a6a90be7ebbf65f1e37b459b5a33ba6fcb0e55c63ac4aa1f0851f4dd1dd0e3675e3554a72a1df0f750938458758cd9965f4855b0063c939742f131d2e9a928e81943554a3da69c3613596393920cef41bcb83e0c383866f44d2c50e40972250c59731cb265f9f9d9ff9d1ec34e9ae71c4550152571cacd4e1dd23984b0b9428a0a0f0264dfb22750c124de3661cdfd527e54d9add99b5b629441e3dcc297beab44e08d6af59c59ba100cfa519e64a5ba902dcd80271d9949995ac3865a722a3b0e77e66302c000d564da4a6db11e6a1e7fd16e255c51feed98b09b5582595908fccf1f501bf3a15701db621d547697874ec8472c42870bb4ae944f3537300235750e51079868f439b1ed20aeaea24d15783aa5022385ca514ed74830314132c2178429a2a7afc56e51b6101d7949a3ab092461f495dd58384d1b592673a865ab93bc010c5e008c8f1af0654f28cfb32864d73c483b1f170392089736c00239d392a8cffb1659955e8bad856e9a6d481347110a6c02a7c1646ff847b63a083ec5caef4d0c3fa7a0431b9db055837ffac45d61c735a05947b0be79e56efcaa9c1250b8ffa229498b5b4c125000fe432af916bb94997128bdd169935552ae05afc807293d134a3b52c98e6807ac58960044d20e2f11e7ac0b07ebe9bbaf17fc2d1fa05e0d17f05def133273b85cd23e768bb0d4b3244f5a897c119ab48b8b50050392fc36360ebd9fe144def85de8c59e05acb48109d33dd832655006de1c53052f41d04a29d7e75bd2b3a55b448a1bea3126c3573edbc06dd9f88ebeda4304023234762c1888c9efa7214240991ac5f13274e4f4a35cbb22a409e1852bf50eaec01ac280a1523a10a8e20414e65b76dd5c4b8a62e5bd62fb4605ec7c3eba069ff23c036d35d2ad721bd2017be9f5fe850a047396a6cec85a0781230d7caeb6986e8a2a472dacc339b99725e3d46a895e75919aefaf8f927e75d704222b7bb3827ca11e0b5b824c3d2ad59d62b70b2f5e4d01ffe8e8f673b7b333c6ac8fea1041cf36302d60cf2f9656488d07b00d68d917e4ff880675a50ef6aa2a7f9d007be5e3e066191d001fe67eefbaef54ef130ee5f3fab0d4107816e557d33c34d54ca20df467fb24fce4a2e0a1ad1f90ff836a1d28b7a6fe9e7ffd26e21a78583e58f14aed1d3c0a95fc8f7242f8c53b128242e29875ea5becb7fdd7caa9cfcf6a5708b53ea6000418a222f54066cbdfc70ea9dc6522df63f55335a31d45a6b82e827cb06687c5a046d0507ade5550747cee317e1b6b298c28730f0a30e0fd104409ad78962349e40332eec7d2e26df6e0db4740bb6aa75a6f82e6e3d4314678cf880a71008442449441ecaf33ba66608787ad15fd99a57e76fc13669e80cfce89128dd78b037f52ca8e7a87b6d339c86ec13c549cd9e6e6a9f422c76965312f89e27944f740a80b42b11d342c183ccc18e40f3192cfb62807ebbea8d2f9c3a7499089cd4690f07102d9b26a5f510a6a130f0cbceebbeddae9e7fc883711604251c93695a810061968137ac1bac8e84e0c911b7254ced99fafcd5b360a725964fff407fd81c432b01304392d946ac035d9b0af37d8be383504a5dd638e07c884873dcc72f9d86c77a605bac33c752fae7efbc249193f1179a72030db0e25bd0907655a9e8d19004b08891d2b06c721f240c087212a7b88f66edebd3aec99fb757d369e3659d3cc5c62ac65f4b962df10e84be351f38e4c4ae4d8dad1aa12b0f7141b78ea271ba801765f0348736267358254cb60214039a86daa081089ddfa54ac0f0d3eee1f3af5fa48168a0813e5034b4fd7b7a10c78c9b78f0433602a9d46627a09faae1fb3226281e8df06750937cbb90b80efeb06a1107742d40d44f58b3a864f84673483415fdaf8050b7f758139c558498659bcb45e536af9db75150bb72a829f3b8046fe32e3dc78fda47edb2d057dffa5b2d14d520039e732732556d0c24d34f2295a91938654eb69ce2f37f10b99a9c2b18298a4bafa1b195542a13d9a9fc28f194f000cf441ea8a03d1291c5e33c8a320b178482dc062f9c320a1c4cb8185a86ecb045861ea42b02c81820f5e6197160b647df184910c8e023b5c97ad627b2c51fc57565b127cab9bc84a42104108a4239b9520444e4f965a23884aec1f43198d8d506cdd276397858fcdc44228be59fedd73e0d94ef5dd2ccac9f46fef7a4ead921a80dc200d33eec998b1d9a8ca4ac2541a22f2908437c3fd23f760e44aa6f55f5dddb3cceb682e1c0b8c049f894784caae2f39fcb8faed3eea81c063231dc903967b49721d372499d6970f1c5e45df373c88c8618c3cb12efc0698d1e7e403bf4550b549b1426db7b4103e5fb6aa2865c29a07ac442b67803bcef5a550f1ef5a63faae8620848e4a1811249371293fedf98e96ecdc4404637aac4b92de8e453b068fb53094f085756d42c6d140e6f1e7c32a941404107fe5da375bdd6c3a44c9593182483b62bca71507afcc3cee5f8c1ca279a666da19488a6614b391c6d53cf684c123389ffd0216345f8d8a6277e0fd447be35598a8407a86995a01147caa6190acaca849e813e756e6a97ba5a9f6c081d8101e9b2a4fd94b061e6585fbd652df6594b8ddda0ca74d070cd08fad5d2e5fde0424e13f42ab5a5d412c73a6f7ee9a28a7507cbb862e332455061fac8c8895ce67994252b45c4450e5e4ac907e8b6d9d72738fbc612876d8175145b17c73b68204b57f9aa86e7f7af4349dfc6718f63e2fe8e6307c517190e0d0a3851113cf4258440ef6329e0f82be9eb4db2ecc08daf8c33e19ae021f2f52c6b75733a02be3fe5ff3df5e38191d95dab94fd8e4fd14fa2cafd6a4683ad2da2b57dbfff4f02d5ca979dd2cfe4378d970fb0968d54cee4317d100f389502a5e4611a2130000db2c6eca80c324cec7763b41310daee3ce0e4fc17bf21e479bf8d9d45d09b4dc645ae69bd27a36cd56cbfc8d594365033768d5776623688acdfad1eaaba05a9f58fb24bae0b06477c4baca06ae9090dbd9f88150507b1f7d08682274149b643c0d1dd06beb921d19db13657eddd1c3bb0443d130f401fb3474888d7a741f9883837b182b013184ee6c16bd5b015353eca93bebf67fa08d15d98f586f29e298d8776850b31ec5c2b79544e31dae872f4a739f26abedb61688250272a732d30c28d4afde73324a8028c23f8df92be6ef3790dda8c7b9f1d344701218970d27837158717218970d2381e059311870acfda00a4c30904b9714100c79dd853b2761aec0e498c49c9018c92b8533d7ff2acb0c71dd97bb69f4c982b3f88161c085dbf55fd0ebc3c9ff3a7cff371038c93da2adb0f1a4744180d5d897df01bb94520733cc6a02a5484481cd8817e9e0fdd71a22271010b8033fc0c1720c82eae4c426e40312f0f25c5748c384b4eebbf007a64214871c6f884bf95e60bed8544bb53d62fed14f4f210d7f6518b716b6d70c53dbf0702dede49a568456cf9661f4a7b375ba037971a6a00e85264bb10d917e21d887efb6b78580ec8c101672c304423f024a0b73b4950af9e8eb21f03b5f5c17c0bf945317f03fd59dbea0ca75e49d086d6095a1c0584565c96a74f0f93849351917ae00d3a6d74c6b8827302751e622bdb0c8e86c72501749f6d46b147fb6770859bb9a6702daaec579388aeb94ad4dc49c1bcc5de0e4d640af360e8f42082466ae89542cfb5cc8c82e935881116284ab2b4eaaea8b3262bb0c0869d1fed1df32a771910854c4af2a7f4875c08423a96887643cd315015537d0252894ba05e0ef5f33bf4e2455a3318d194aff5bcec6cd406529280026f4e009acb80a5adac96b62fe47db9314df3e2921234997924c0ac184140ce001919bf9216d3b996de331f0c14989df2c3fe85f11ed449cd6ab9cca70d58d9ff9962d99657b7a50d613703692f72b3aa88906860ade78a9d628b71297b20579c83dc1bc1cffa3d5025cc928f000cc21c30fb01121460d110aa81558e9f7891103c4fc50421334e0d922a3a8c8b72c7f43e48aa138d53a449c1c1ee20ccedb76c621d459e633b92db026d6f85908287d12272707955713d8813c04402ae8303714e41059ea97f1daf44f8f844412284d6bcfecbe242ba3cecfc94773977f215bb844ad94cb7f13e24a3789a1e961d956597a87265569582102c2f26a5ba904a1e35bd48b3e5fa65e4e9238c5f92940f25bb956ef1cf9b69a4a81e6b9cbc5ccb62a03bdb23f93be4f5cee324d1de221321a125af053314aba801131eed9dfe0d4f1da792d98c7eaa9f95c01283049a39de1bfd90305f5d7b6ecceff6957bedd0278770c0086cb690e7174c1bd5395af0ac575d5d594026354669541665c1420720cc25095887a1b862d3567569d3d2202727ab94e83692d38bf1c19cd1fc00ea79e7928f5ed7c8e9ecbe09fff4ee41009b60ceb810327ed1756500b1a27bdcd1f3abaf2e3bec27e44ce2d2e65a28ab9042956d8a76c463e930ea4069047fd6cee58597194229a7a24cc9fc0fed80c2eb4d7f7af9ede581ea56750ec9918e406219451ab1507965998db7577e679dd455d2db028d7eeb4c43486177fc69e589ce3c58a4474d53afcc400031fa18e8ffb978f4ae4399ee52c282daa0be054ce7b49e89c1e79046eac0f7cfe0211edc58f37b557c90760a1dab974ef2789d7c66890bdbdef400799f9e1dd432725b353e2aa21142577628ca21d22cc1fdbd121076f33c58fabb06ab482960b728c2801d2bcf86d307bec32c128875e8d28281d086e2535fe53dc3f1bb1c5a18e59309b306b637567c0e5e73055be53ef2884f3165b9f3ac8b8683600f0258264262bb78c739bfa192532c5ac84a7c65d45b84b63f1c73eca39c10fbb2f4f293c536fce16ee1b58367647c246173dca36417da2a13ac627e69fef3c50643489255726eb9f9a8fc56dd81f3104079780539fe616ed95ca62ae3f2688c237f2463d3e8eea9e5e1a87215070544da0b6ca7af5cc90e2800be029c363ef2cd37c4ac4dfa6555fe5a701c9bc8262d9ef837fae2137fbf69529e8eab6dff83bc8a73dbc293b63598c63d50ca3b14a35ef230948bc9d39581686da96432db30465110e51a11ad0dcfef9a01880b01809fc509980d84c043ce80c60ac4c421e6846205646023f143300360301e31890051e18911eb0fc61b929ff3f4a38ee38e3f1e4c82e7340517f2029d66b9c5844ebd0674df62be3b2d2bba11756ff92fdb8a2566865add08a5a412b112da0f23fbaf1625fec15bb62abd82936c546b151ec8a2dbba1e8957e5aa995b4422b6825add08a5aa195d52b910160a33420379a63412b3a4cf253c46d3fd8c9adc64fd0f4f84853c48fffb3b3657a2bf3fff332c37165544f7949537a397df3186124669eaf4b9c0ee26be559ad92b641617c9a0e8af59ea0ec1825cb1783e7e01b8c0444440d742bb70ccece09f3e7ca25a6839ecfca35ad8ed0ef2443cb3d1ce84abde9269a3559db6ccb85869b34a30b35611cec94955a1697227c833fbd860ac96d98e557b7c191c7087c2d3ac4ed423489f137a50948c7b2f831327139a78d7aa485030a8613f2c775ce0f16309db7f69501e815677deec353e48366054b3963784638e319df2233e2605f2acb09d5f3d19326fc14eaa507bbcccc7fff54a581b124c1900d10e0eabf8c247d5308e3018d5293e9b9a2aea03c53f13cd0e611960f20ba4bbd155fc85693c1786bf6abc671afabc47934f291fe9fdf4470ce3261c16cd9b1640e1f1aa7515a4edd4bc2322552708203a071e0b03171f341b082230a46c32060b28b852e744323140e30f1d083366840078c817c3127b4430fdaa001f40c2683ba729b4deda8fadb7a41fa620ae73a8cabe01479d3cf1b8db68f49a8558eba728030c36940c2d904d2e628f0ce9afdc489aaa2c1a4209e1ac483e4373ed490e9fd8f50b0227baf9059d001dc27a43138cee778c0f45df9ad8059c3015c0d6d70988ff8cb21cae9a481031fe1e49bfb3b3049a52298c4d6ae4a32057674b615eea2217051e7ba3bd1104061f3f122501d89b8e47dd140ff918eebee904e1015db579fdb8b676c91a5a92f2a1c17271a0208323bfa2dc20db530de6b78ae0fe9260c24f143051b6bf8a0c371e3b31c2d62ec3c3ba002a5319fc455acc3558f085f5a8005f13d85a1a8bd255c0245eea4398661369d8f15849b04555cec748a67802c69725d09127ad0cc20b8a9a663e20e56ba2365f38d368a6ae8e81f8b3bf2917e210bcc209b9edf84cd160ed20c919b08fec49b12b626ef74540a8c59d987b3dda896005d7ba288a8e19686883a903aeb80564894312d254f594b105a1b40c22ef41c704b5b9ace45b941b0823603e5f49ef3389ea599a76adb3452a6c9488cba10d4556c9639537471cbcb7d13c8a32fd692910e501dce9f06c9896326871fb52695255704cacc0041299d6bd601ac0cb1c7b55edbea2ae8816f3d80a303ddae7ffca428ee881e00f976b82ccc0c7ed63f55d4ee9e45ef038b24ca907c9e6965553e40cd94133ad84fe5583e514bbc3721a535825178185ca0e1f5c5b31bea027eafe60607dea96d13800f0a0155eff29afe5c726d643e4c29000abecf811e85f800e8b79b3eff19c72205a34870bef3a8b95fb5e41ec7a7798ef9841831a1e21047f2fd1a8617ac758f5e8214a52545b4b22e1c42eb25c7003ee7fbf30eac097f7fb120058284dfb302cee2f521cd26d5c6e0c7de19d3f1f200a380c44afe746c7f404f30aaef240c219a08568a1be11d6e5a7f5ff436edc78138ddf9341459509d7b2749816d389a8012c6bb42a8e0e43c7d65bf923bec8b45c236f700f1c056c456a1ce842017a8048438d4121302e168822d48b20ba1f45c8a01d65986e287427dd8e305b1053f8b94a0528a18b8f8a713ca274d518c399edecefef5780b7730526122b0a6c05076304dcf6de1a9f37da142dbe5db87590080c5d307a15a75869d691cad8d58d42e1c9459208b5df2415b8ccbd6f460f8104b25115e057c1e2f2838682192d4fc66f9096bdc553229f8b797fce531124326021a40395a5472ed71c60111d2c3056d16c59bfea95cfdfd92bdccce5799b0386d4529ce919e481f5363c12688bc0e6464712fab0361118cc8299a4f9931e3700ddcccabc50fc917014ff5c7396b5dfe1c58a10d1a53d0855c9e981507cd8ad2c0767ea664d3d90bf56235765f59e19b82e05bbf71368d21951b85b778abe4005655d1972a97026d9d88a471192ab45a0c6296e71b85ee638aff79c14e1d338f0ac6bce1ab2867411f0f78c2a41898de7bb7168b020a6e00745579c41a3f333727a1d326436248d2b05b18e1e471c8d16f4bfa5bb1a40db7f6a83eb11c54ca25a732db01df9a67aaf7b231162c8eecab767000bd5164025e50782468fed0f75214014db7a68fb64d164a0f511242bd764f8b119e65b36d39ed30352bfd79f8a78056291344fe467d6c687c86ec0b2fcf31aea7eb11324f7a6a9ee8d26d2fe6b098cfbb1be4fa5ff871d00c341bb55a331bf3eb29a65b19d3e1ca6308c4c0f16ed8d76e193ca151103c9c05bf74217e92c520ad754fb352282cb5b52f6e1e4dfb15b0ec348a02d94693579081493d72afa9ee6d7515e29e59a391b463aabe9d5bc018e9f2cd8e445cfd32d2333222eaeaf53384b142cc9d154286946fe15f39dd19f12b47d3bd21dc5200ce891984fb2958e4a9ec318f09f47c4d6f94a83d151845388d4a1b72c98074934f7ef04108bb2b97730c9752674499cfd5dfcbf6a7db47485c6d002339f38f3ead30320998cb21d2d2fc62900c8189fb492251aa08b86e909dc07bddaa8801c423b4f73d1fe9cd4108185c7fbe34a610902a30d1f5d7510fffa206cf8d8ae873bad55921ea4df57f3f2e21d511ddafc6effa07db4190607de158649a6844fae874299b6a3cfed1d1956d7365ed5d32db258f5d6ed37c3aee44dd00f38150c04b82995854013ef75d2145c85d9ae746746c622770f88be6cdc2337c0876cc65379d0482125da56f1b9cb97f8ae4721e9ede52b49412c48a27c697a18bde12c263ff16e0e3f0fdf352512b1f0fc6bfe3896741fcca7fdfceffccf86cb42019c734517dcce4dd127f529cc6982f871abdadf6e318a00545b4b2f01012f3a6c834db8fdce90e9da21daf9a0518e8a022fb37ac3ceeb3ae3567f34f0144129e4df24372e55380ca43ab67968e4e806fe3d3656be78aa36abab2836f0b48f2c80d5f1a7857915088903bb35a6c4cd87d11ab247b52e7f8bfd76f89e98618f4ca893bccded42e7468a5ec102ea1371218d1508bfb6da85ee5d99220181fdcaef9555c9f20cee06f50cc4ac9b6bd9bf0f24118e5eead272d9bc5ccc2160bc925ac4b4e4b800184fc9212eb08c789e479f1a9f7d7e61072d4d4d35ae8eef174850057b9d8da94d15632f0e51d201003abb51b3f88591a0cea9d3ac64fd61ac1afc58cc344fc6c6eba8a27689599fd0f895973cd5a9e3f0f98e2849091bf7499a5ab5c0695e1a24c2ccc35349b1dd251a17550e701ff4902b8084ea5ae7321c6b1917af11a8313a819e0f7246b22a411ef10e2895349793faa33b22faa5411294e7c98407ef2c7875bac2b1c7c6a5a9eaa809628852d63ff19877da01386b134b476071d02c00591d3f37fa26894f4325987564d6ad2953f6f083895f20a4f0f1c978f65ec10ab29727be056adb38a1f5d125d584b5ea249eef7d3ee93507808bfb657ecac2cd0be3cdba1ce0c336cf9e182a05b81b02417056622c5b99baee24453b7bb1f7c732728ba5c3467e8211945f6da9e163e26269716d0472dae43df1d2ede20b1e1404e075854a0baee3b0a1cd5a983a5a33aa2bedd61a60cd47fa510771c934e2d554b50b66a66f6e546c914415d073c51226639db9a5aac86fd29bf12657018b4b3b720cba934efb41b80546f8f0d759de722c9eabf3e696ca86b0e93e5c5407902a855586b4b367390e25fda3d5887f9a81f0736d86a1ff89a1587c96b566b2ec2305c3bd50b4ec10986e562afba8db14392de522fdbe9a09ef041a45d27b2e2caf63ea7eb30127e2ad74e739ede3031f516261183f2a745c2be29434c056674a34c6d6a702460a3d76e0aea5b94c3629fff166cfcc2b60af35aa68a4358eb575cc45f93dcd148f8e8b19f626f1533415c4c11f167c5fcc4b892691498f7a025c173542406211dfad8a402e571a9687b117d97b490d6486b2bfb28b416d15b16c04a046abd89ab38e732ca97588956454b98fe551a22e9012ad5aa4f62828fc061f06c27d744b9752ac11da2bef09c7be0695da0fd9533c5bf4ae143b564a320aa7a53180855427737d2e64ed95e88f13de0ef00804045ff94d93405adef9472b9512505d429bd6d4fa97704202c1b3e8e719a6f5d8d69a0c1db2e15b6821912868c71e579ecdba235b0d3f35c09214088b18c606ddad35939f1a3cb9c4043ed854c80ee6979798c246fac44b2e505b4c0d657a7c7401e0930b3e4b77b674a8725671a39e15631309e96d4f0ed474fd457513b209060ce8efe2f6871a0c76879b9e58f8357cbc0268595a3fd6dbde2dc38f445c386f1674852836f3710f0f81cdc9fad29917408cf6b81fe58c8a3f3f66f0125fe8b1d6c4430a47448c8310b7141e710c75ac6e121bb75467648f12dc26d8fa0310653016268a27448725f91c714c498cafdc49a0f698148b360a90407e6356622a481562c4356fd82b719e243eb068e2d904a52241ee9475b7651bfb6fa1880fdddcced9528060b8354f97fb09c524358e8466776d0741fe7029b1db901124bdd139339bdd1590ada66a7e537593063f767b25976e589b3a0e000cec27ecb1e27038cfd87c0d16a83c0832db084e2bc3c7ea32a39522b9c58c3aea6df1605accd9955fb24d16a65ce31ba0c2919ea6042843083199a051938640232810c9783aa64de7d384f1cf93873184a8664ae53a3c682ba73bdff7b63e59bd35fcc332199153d8a1551191ca3bf2b1d3a3e4c19271ef721663fa79873ba546e5795e01a1f6295d864960666ea2e0a8d719744430cc86375a1cd93268822f8c359f4a4e053b09fc6d02b455830282632dc27a2f4ec382bb14a3635e20784202f344c42a9e5177aa4c46c30e999f6f19579813aab5159ac9d1cbac2fc6cf0283cff10994846f3160f2dccc11594a0b0ebdab1e501bb918ee85064d34f0959c16250eabdda64a51e55723af269f35abb7fb0519d854974ae0fdbe9a519ce99fc31187ffa33147f8db4cdfa30a0085b202c0540315f46400071c92c981a7e27fbc9cb1ac376d92cb79d5c692ba33bb9af857226e62ce440aac51838900a64ad37c8d20bfc559d00793b5929f15611c35225a8cf3a473134038d38aa5fd1f35d09def2dc233149f913db8a37107a244496d7eb50aca2375cad8cdbd7132864b60d4d8594d0957274ecce22f9128e8f4ebb0842bbc2dc40e3b187df8cda65bb32484d8484904493bf64dd4e103750fd8404ae4f51e8e726132e9ca367b6ca30c0c3d2c364376bd7b968cfd327be25803f6b9a54eee75ce41d8540d16d975e04216db5d361a22e78fe739ac11bdf7137df158e66a1de8aae36f19e6a0869d2775b65cd26e92161ec7173a19500efdac068147c369b71cd338a324b3a533f81e78bbbc22614d98ce2b2e6989fba95447885300f48a299a68eab79f02756ede0fc521732ae75c2e8e90d50364d85f5da0b749bc5413655d640ac19267e23d6f7fa9e52fcb3dee0afe3d653ef377f2744fb7ae45af8ad443731dfe6dd536a94b831f7ba0cce34816de2b686bdd0a75bdd778286038ab4b18f76d9c2a32655e487f3a12e52844d970688d5b06e9dd48b33c47ec396e57ee7912b3bc5fc699309f2f6b05cdb5ce2f852c196914966c3e31978c1e264204509b9a300a0385bf41e9ac99ebe61342e83bfe8542bb5fbc17853af5992c1e7d949c48e96f2458b48831bb4d9673815c7a81ff7ff7f7b357a5fe3cd369ae481f16d39208ac7b50643827fb68d15f631c562324ebe54ec0895f78c20e04d30d546cd676f562832d3ee4ab37a0b5536fb0e34fd2cfd625fa258a5a30185428a502498337522cf9820faee598392afa9316e135efb1a3489d59aec963ec857e6c2386d6719dffc3d4ee90b18a10dd2481874722ec2ce3cde166b02901af1a03d3a63969fe80910dbd9c9b163e59b95071788b608f50df7f7e2f840d9a9fd3c5d194be04d53c257b57b0512bee9f50f744910e7c1ab5e92cadfff469c54d119562e5b233abfe48c77825180d7381a2b7ebe9f933c53b565d619407c258c2e385cccfe18f6926a7e4ae0ba8c2c1781f86b52721e9bf1901278d16e7ef5a40e7cea6fc05ea931004800b95e2f84da52b42ea6d6604af4d1d4717b3943bb4223fbbcdeb9ba4c6348fed0fa9f9e231368b48a2c69693f6e0f74d7cdf8ecf7b183123c82405dfa69bac6194f88b3d4f40d334d38b270526a8867d23017c91b0f70fee11532af1e5a335701931351266acfc6c253d2569003b1b71b578c714dff4fd68a08df8016e1082881f56aff6a09667a158cb50f28c6c5c50a5f17ddfe43f3b74ebd02a57b059872aa9df1df20e6aac6cef07987f944ae24522bbed69bb571fb20dc44f3f8d20b3a20a74e674cd3bd61ce6f57f0be51cb174f8f0597045977a9f1bb3aa9cefdcfe0007b0ef2bf530dc4f44bdda128b925d4739cab229c290d90dc7efe9f7433a2f29c056ac67d9b28d12b58fb01c97c56db97139ac564e4fd8e4c8f3b7b8fbf416391eb942790c76b645c1155152faac89947f79ca2ef690b67ea44f2a83ad2ad84f1b61857c9dbae958fab000a19e32656b86dd1110fb59722b8b9531472402e3011ff2991aeb38cc17682d848ccabf2bca9982d892218aa74814a3798573a344f9ef7ac4a81bb90457c3f71bbec0bd6344cee5baa4521d25a89b706cc816284617b099c5a622ce80665b3bf94790415faef1ccce5d59f2bc03b0210010c81fd4bd936489242dd27bb998b56113af0177ec7d5992dd08bcfdb521a5441c429b25bf284e4874e209ed7a783e8c5e1a2b2af85872a2a82585992b525179d3860c41082db548a6308a3a2fe2a5895eb391a73ab943ec2235123e825a8849fa4347a045282f4c8516abd041bfafc244a19fbf2e793ea63ffcf5f6cd2ae2cd524940f72bc960cec38162bcf7897aa86ef2fc9630a17ba704a5d3afad102e4bf9f1bc34d3b0cd685f4a50d6a3c0261cc4aef000cdd8301838c952d29605193d0ddd920964b77f6114a7d6265b1b39983e609a2cf74d4f9f7d46607af450f468f441d54bfa3411d507decbc22487721763e28d0e0536dc57ae9c2191b992e62a8d9d8800038ef61bca3bbc1ac8f24ff2e064dcc62ebdc696f667f60afc2484cd203cc3bcef50205ea430378a267db7167a5d8fc6d8455f4a791b0d5f68fe3fd11a557778ec85682e526abc556ca92b10c1dd87f7c83155293598c9f24eb90ec9671daf2754028b68a8831b24cbcb301cc186788d24b75a576a7a4fe3503986e739760db5ecb0074e0f19a5a627cdbe1f741c4cf24fcb58c65621225c231e94069889fdbb581d71702a32b6aa3862c4d84f724bbba3f220f8d56020efe99497e16bea19912078ba1dfab7198ca679af8a7195560616337a971c5ab1e2f6a502d323f9ddc881a45a608f4e93c31c50565498e6cae9f7e8f335eddf07eda207dcf7f8b98377f9fda86e9f488cf7c8083b6e49fdaca1d48316ad05641bf0c77c8030306b710bdd0ba27ffbf217250d126c06cc9b661f20b7a15740c355196355769f192ae44eaec70d12ad41fb5da027c8a3145a5655aef95898b56c0a41eb5f69a24746312bd66930e17d0892bbfd2b5e63f9cbaece22bbe59c85a7a47810800f1bf6cb6619516a4fb3cd8114fa2bb1aaf2ef164439566d2a369223cf14bc7a71e2428684fd318903e043c36ba3382f8626e99bd12fdf39ff9abf2bb5de1dd78d5925522c1b9c13eb54aca0d0687e0afb813d335cc87b3d0ec6849b896453c6ecd768097e5261a14fb87fedecb46dc936ec6f2c9030e727ac42de58d8a5db868126e20218ca37e95c8ac88514431f36de22b5bc411e4d0895b626a452989384df236bd04270297d0e8df761c70f7f3ff322623f368fc76d378077505936183daebc2a130f38d8835ef331ef5c9e2d3bc8aa3d95fc83d69562f910321425076b30d09cb075c221490ca6457aa7f02d3ae91591712d71edd9890e45b6f26b24780818abcc8202fe7d2ea9f0430166e5b5ec6d2dcd6e34b2cdbe5c5c7d349091f004b4f6d61583e57ff0a771896a868503301f32e82b3b59fcd9cf5188c31e847325417236b264125d9d721f842a9b1057a624730e7f04e341bc367609831cd6c16e1342851918955ac83a3feb9e4a2cc898721b6db082fac7b42a2bdad7808cc5c630db63545ed81e14ffaa1e26ceed492c5fdb0ef2efde495afa80000bd4e6288f26fdcf7bb03144886867da577d65d0a1978f987e0029692effa86057014d6f4b29e2dd1dfc590740e742d1cfbff72dff11ab3de85627f0d36261e6a7db5cb78abe83371daa9fa6185a3b5f871ad581780d634b0af35c7254655c3a9ccb81b110937ee27fe4c015985bfd5a7c2063f41079b72cedf620503bd8e118f0532f7175fa14485613c3cd03bfbdbb0758ee4d69486ebb999639d679ebccd720229dd7273e0cba43987cf6dc85f2e00fdc7593955ef6e583c803ecfaeb2b4bebc1b3e50e9eb8ec0adbd83dabbd24a76f2574f8f8b03ccdd5ccbcc70e2e05dc14bfece61a5bed5f9222e1b4386e3670f1875b16cfdecb75e99f47dda6999af02b5f1f02b72dc97cb0388272f0d49a897773831388e4a35c724ae23c47a66df0cbd83626d90fbb7cb16673af3e9c306dd39108bed32a00e2286196304d98f3ca2d62fc56c2b555a2e34a2c478037d6fd5f93079cd3ebb7ab7079e55260c3f0d5b3a8f4d75742f420c394bdf3f18799259023f435f360dc7288c8f95e699fc776590112de3b687fbf65cdcfc35b95049d69b3bbebd0bd82b3ba0da22e9a8630b01ba56e7bc8021be19e81ec13a27c22a92d4c55487623c0cb737e2ae0f3e10e41886c0cbc0b2939e488e109c3e2d5eb65039fa4fd20a0f80d612257521538d56e5129b7a59b4f8d38bdbf0d6e9f801b0bb54a07f94510b515d3d001be5cd34ef60c31bf28a8ddb8e406255ae04ab78a157c1595d488150025689d9dc1fedcab00ded8ba919d05de867d00ea946601ee82eb794456f009a2bf4c4177f62068bde098dcf62cbb57807dc4335cba50d771460a110e54ce5b885f446ca552b2590a772c1233db7f41d9fd3af35982b7834c29ab29e6b3354b70e9ad444ff0d151ae4fc31525d1d5cb970f32a0f2840f1df8555dad43665ca3aed6492063deb3463999092c8f2fcb24479d0452e43c44e1ca551e83c900f7337c83d060c28d3b3601ea8e671a9271e30df92f53430b1a5630fd50ab4fb678c9705cca2d27e826b23418faf6f6936dfd254b39a39015c420e2a0cb364706580a513c3352c972254fcbf1e8e9bd8f155a22b72f1d689ebf21257d73ea0fa49c28fcd6a4a1ab747c44d2b4fd170485dd94538abc61e77e244458b3e99e2c09481ed2325816a593ddd5631acd7a3691499e31a32c2e4c4c23d99a6181ee71d3c277fb2314d450b2e30ff8d2d1d200e1a65b5daf4a75686ce23686f3ac8fdb8833a3f848fa38f6acd8e8569644afc8ab09424dae2f04184a0a097754f40db6c9af80976f381aa7b5d2a556f248250955c00ac85a55b0adb869d0cf8c2846045478a1261ae4edcd9c7eeadcdc034901438ce5e7cd99237516c81217a63e6ef370cb2676fbb8206e8c2898f33f317eea71fd726f826b66faca550b92a9a11210224bfcecdca8b9357a970beff73189852a56b8a0a37ae770e1eedac08b0e1f89da797860cd81003cbcc1b39aa44275ab4e5c8a50534fa80dd811b3fe7a0361a9a41bde1930e97af8d0a6295c566e6d3d53d5611d8af23167e7d7cc90554309942b997dcd7524438f948de12576393d1f54b2b0caaafb511ca5a5755e6de480f1da03d3e895eea5cb3ebc92bce3c4d3d912515098bcc248a4713aa2169bc5384603b80b9d0bbd765427d598454347dced2b54c9b2d84092db48aae9f386181e0bded64a314dcd972a9fac468e232ae094dd48b59fedd67c30d38af0daccab28ae02f243dfbcdde568614caabe631580757fa369fdbb8c6032cc04406e7e92c4128e1c6401ebf09e21a9ed46e621c3cbf7e2a0d796e6bf912ef91bb98056e43a32ef39718296bcff4e7ad1a72292347b30abfe7910740b4cb04c9e34d4b35e23d2e506da7ca1d16bf4cb1b889634a2950356a5497f68112f632c67e009ccd929c2fdf67b8bb8de6094c3e736911310d545145cc6852f07d0a612049d3273226d31e29e2d21a5e6a1e534206f676dbe216877881e1de4b19d6e85334b1666ec75fa397a53a69f00b3b678a796e6d5b0ca59a339822f16b95894cc7ee9ca5d4f7fa9926547eb4f2b30cfb7f93c6f37c1740066e94103faa07e4249bac2c0055bdc0d88903e91e9fb76497e5eaaecde46b393963811dab06548404e9d60b0676532b381b82e100425f87988c18883fcb4a224f8d37a7688be7fb01ce16f8a0ec058b9d0a23996222ec2d981a894a8eff1f35364e38488f7c7dbf5927def71334f11735f84cad673ab4a95085988c713556a027a192f1e731445df81654d0ae8d4e19f7cf7532f1458d8ea5ab64e4053f015073143aa2b1c5580f564a1fd6225b31db3231fbeb305a3628f24a2bffd28cd19ee25c18c3dba46cbbeba6a8f698558d2d0c063dedf07ddb62402c4a5a2f5502b1f12e5ad6ae5871c92afecee9797adef8fea4ba7f65a9b4529aa55248802a5b49107e8f914391e0daea80b38ca8b86b6e9ee4cffd7c6c9cf9bb364b26db8eabe6dd964af819b458f26c37fac73aa69a3536b51b3dfabb96d22c5b076df0ca9ddb3a9be8f899d57572a5c9aeb37cd6bd188b5d92e9c5a8979b2b6f6c144dc7a4bd6883076476596dfcbe52eaa855a979d18204e12b0e9303f6a68f6325170e5a3b7d7889aa234c0a819d30c65edec30b4f20e5ef9f706e0486be8fec62335f40c6d020c7adf20df6737d594ab871fea9755c816fc99388912dc65d66ffcd74ce22021ffafee1b35b7ff3457d5414e68c750a963762d20d94e2ad528d52ca95a930134e3f8ffadb1677d87e574198fbbe45d0e6e90405bdb70380299a7cd7650a2992bbe254cea266d93beb4125ee65a56ae33a510236cf77547203df6976935a2f07fcf7c81533d1a7a238d080e25dafd4deb532430e2542bcfaec6cce432911cb5651ed1f3298b13c726854bd05181038f8914ad933c07a26544f273042ea93d0012a480e62bf5e0160a6e429fac11b416324b11fad91abd5faafe59364d3d18582fb3ef2595b703af3c8580c6413aa9364706e1cf8ad9ef8affbcb6ffa01bc19ca77ec4f69c8a7155aaa38b0a76062c27b559a10b72be1b6490cacdef3e4cdb6de140053549414dc4396f07556d287c8a7c7a1016691b1f416154325d29965113fc3d55dea018bf045254f098f1c6211e146569bc3e83f7017841545587cd9dfc36872b34ce2995becc748ec27e368754401a93b0111bfed060ec74815db19794ee9db989746c2dc1f6271a07cf2c6a12a8560901aa7dce4be6068a3c0d69c629cd3dc5898e15093c6387c57579a0326d7bdbcb3260d1089001bf085d3d040f7173b16d6cfabbabd3c46f5db0494311fa97780e58fbe04c553f1b41ae1aeca6569f3910929a0690961f20022295fbe18e166ffb9438ef88c90a27a5ba4b7b8b9b55d08b025da9ced87848ebea14233b305ac9575575b78e8e9cdcb1790b62b4b07ca95833c1d203a0f3890025053e41b9f81e3a0e0d95daf487d059657111af21623c4a39fea0ac9a3cabdeddea12b4c7931f6a60800fa868e62710af5585875ef4dd152221409e876e4e48db5bb90185c71276c6be28eb4e2ddf377fc17f31698b27d1e84ff5fe80569ead0ba17ba1ddbda9c5fca2586a3275aef877e949daeecd00ab075bbcb858ba3b9f9bf6c31cb8fcba30a7d2f46669927c402597628f4788dc2ed914fc4f275ef85267023fa079513d02348b3852b64c2a822ebcb48c9fc118ceab17ba4797388f830c2d5875c0f88b87fa6ed7a4df45c0ca2a6e01a191d1629d948ca6ce6dcc798d5a87835f4570d49eebe37daed184b1c11d91bb66e787e44843794b1d0efb4c0c6842d5f61a2b0895713c8505918b2d51ce4c8b433563a64b36248db0acf94e459aea897c2c92525443b141b14b9d13bcc1d27e1f9d42c732cf8153b4f4837eb359c051f1e20698fd627a0dc5fd5f2a971f9917729f3f98552fa3e8393c84ab2b0c30c3e7f42080cfe18d80068474b6e056e02ade82c36a11f0e6db41dee0f19cd5e02f730008923c12e41e111d584fa2ea6f887ffc7957b33283421348f46ab516367a6c90e60aa8d808fa8e9f084bbd81a8f939b9820def181770c93a3081576ec85172cc218328163f74b3a0cc1027837793ad064ff1449e4c2bbb57ae85f5ebd331e42d2cc126e6d2ae4c798161fd00dfae488ba002fd79440596ee827d8b273ee1480c7576d09dc090f46c42ce905c51532b9425e2153147a84f76fb6a2b6e749b066837cdcb1b32185933f8bb8cd33ac337ee0ddf5963ca88c5afc8a2d116c8c55a5ff36d8cc04f42bbac1a5de7d97392454d1f3a1c5e965531b5a8a64526a1a3c2f1da3f10b15778071bc637f4389f51159e79d7f927c04a12dbb5d699bfe3cdce952c6c94a403a7ba2689f7cde0ec5a9e4b5b53ced12e020d8e683ae15138a46ecb043a04b7321990363c41681da30d932ea8416a89d675b83dadc135799aa12f449502ecec198797a02858347ca6bf4d713286967911b517363e931f97052bd0edec48d9ae090881cb81b15a92b76a49600ae15840a280f5a65c3977e244dbe24bdff7c4bb31f526b44c3e31e1aef3f44c5b664f3f21b620951434936f2ad8d41d2451a08712ea51db663890148f316ccd37a9c9927ea335ae55e5d23194901674e6dea5d12da3d722650048dcfada2506f233d33adbff0d99f95bd2b0bf09271fd11788ee91cf210a67edc1800151926a30a747e8a51b0089c96be73ca10715e62d0f45a46a379225ec898626d46d47a84894fb226ee238acfa9833d8cb90fbb3f9234bfcead8c563605dcac2cfea48a855750df9a482b60d428e604902c2fa18445f10f6d457eeb69328ab41053900aebe9aba81dc6e7ba31ebf8640eb31d36b952b82975d36a0e0d9267172bca6ae808f1252f861219097e6b90edb1007e47f1a68342c61a20352f18aa84c6318ce91ee8d4eeab8be5aaab67cacfd1110d26025a212f9c8c08591534494187ec8e1d7e51664d92f610947d9c5b08518cad9b34489cb1493e7647a2e835e2ae4bcf3891b6b058b65fc6688008fe48b3ada7e2d93683cfe419e6a928122e20a05ff7e0327b51d901cb2efa17713a191ee84fd726a02b2cd9e6aaaef60c4bce84ad2fe94df51368922b9c4e0d795d6e4dade6c0d22473a5ce49117ddb11b81942201247501625060a8ac17bec89eb19343ced4b44fc137c203b718392f4092c6ec34b738b37462281ea6ff68306f5eca14c49982b16f64ca646aba27fe3db93e1785a289e5162479175fd3987fc48c44c3b54ec2f24ea88cc58e8472dfdbbbc6ddf7c039d744eab6b06fa9441850f8301deb2c6fb64bed5e616c9ea964a624c81aef856abac2ee9dff8fa8b3ac833240666aee9a895e8412216d4632c51ebadb8977eaf323fb73eea328a2ad370f2409a582f3c58ce7aabe15b963c7fbee65b44ba2bb7ddc7da743f46b8287c20b22d2987881f9dd2ed5928490cc96f7d6b2f03c46fbcd49a32009a80bef4578b9b1d08d98b89d0fb7e1fb9d1731e404dd85642ff2c3e7eaea9b43032cd840ded7871acf67fb76775fd80d45b7ab64362440f9b9de13bed451d30e29f423048dcf28a3a9bb2e7d04bd076410cf27bed1f1c2388b1d6fc098a2b7e9a8dc9a21e8c7df99bbf83162da7d4907b713d730432006c7042ae9a6a3a4af022c923af2c6cfb4d74560121763e7d8e1f33805b50ea6f90ccc0462990fab7cb8ec0238befdce19fc8747f24d60d8d2fbdf3e028851eeb3f624b2f7b6995ce736c238e03c3929988e98c137f24b7f21f23586e94a09a5878ebce2ff2a57c0699963fa5ce21bb92fb724201feb4044565b6c13b3f92cfeedc1d912e05cbddbd4763fc03d02e0ca0a805b1b0d537a0b9dc14961b607522529c581f4123e7fd46d88525ef7f7ab286ea24bb34656348e2281b76f067b294652f97c5d84b73cd7c6f263ea11df4d81072aa5bfffca1b273c5036bb996d084c4ec620a9d4d2cadac277ccf39bfb60b4771f68eef3ce9ee252d35c7792a04788f7c16fb94586163bf5f181039ef54deb8c7ecc54e655d2f95aa2c4a490ca2c6a92335d57c94874f13192cbad00c6aa9805674b8fb63d8269bf2dcb7c93a7037fb2b487d91819be7c29754546f6b0b6cf53bdaa4c8d0d1f1ef063778144c97e1e874ec1c43e08416824187698e53ac40cb2d90bd8eb5400c5541a3b56eacc92a6fe71f907b998bf801362c4d69d1271ec28b1ac0e4112449c7896263c54ab9f3ea03d5d46bbb97afe576fb90ee0140f63e55b0f42e9e2a5948d4ee4c1b4a257dd7b69b169401ae9f0cb69041822c45aa6aaa142315b5752e1a66b22855771e0a2e464baea70706131a6c2e4a686a13854282a3a352c492038452c46eaeea11ca780c2a16722ac559104a0d60322906949d525162a302f907b3ec9aa4e87a458292c06f2602afd3811c35b0092f42db7a8e0c11c75a8c650035bf1900d56b4a63b618307a1e2481ee404d21a68baaf87c83163022448a2a1e4d95e44269c0e123aee00269f5f01189d4bc53afa95a2319470592e1af8bf712fcebec758f58652f019e72c5d8235682bff5f8fead1e85f69d63ef51c49bb3883e8a381a9b18f951cc614d69c2f1b65523fa2862a86105bb05610545e7da1fed11215457c9a3e05767a43d6207761c54b967da23563fd9cf5860ec5f893a79dda21a1eef6d9acc41adc316093c1e3ceb8b1dcb6c605bb9e26b1aa2e662ac578ee4e6ac5ea4aa00d317d032df18fe9157a13d62cebb3ca091aaf1bd542b52b022ed0dbc9cd0228f98c18ec57745bd504b049ef37f788d4076a9ef204ef458f8e5c4cc2255d641b8d43b4038c1fb5666956b3e860a88b6e734485118fabc49f81ca7fc963fe51c291a8fa78ca3d06fdb20dd2738c814b0fb67e783cea622c21ed19d621ecb2751a372988089ea80fb398ac2a781bf72c6c77763009cc1cea7621fee1edbe1dba6dc2dd8096183123321a0b5f151b88d6982cbe4a0f8df4ca4c515835f1acedb705ad357fc8a125035c83e66702297264dae6fa54bdb1d7345561de3eae9d8ee7554384f3069cb8d27d49aafafd1c7bc65079bbf61fb6bf3b93738f91fc7700a49ec89b57f669c88d35d1b5307dc1b6213ba04b044af87c61ae109e396193285e89b6b45412ec53cc9e8907ffd37c3e61080cb16d370fe673ae0a99e7c763e2d7be9c72a734f502da30825dc02a7e41e0cc152daa037c512735406756de775186659469cdf9ee2d1f3efc39906a352036b9240ab27a41121de2224f9d56a4345039d211d550ac5065fa1ffcb305aeba9d3dac090be9fe3bc9bdcc0284a82aed906b3d90a14a5592c698501b92969a2987f1832c38730dcc3516465cd911f46af875acc584ff22f158d43ac8063353dfd61e81202d926aff6b58434dab241b2d88c77e48eeea825dd77a81969ea672e6248c1fcac1ab1154c86041287debc2a4dec4e6762329212511fa3bd1833579dbf932606b089c6b43915c5eab6646f3a08dbc5dab56613239c7179f466a1f7a4c3d792447b86ca7306f58cd15406e3b25600d88b19d49b570decb677c1079b7b8f843f3c9e9dcf44c5ddbae8aef6cac9ef4230c1a0655ca4df0b7ec82676588b85ab970a8cdacc6188139294187f031ec0190839a8cab5b47523007de666852a8221a7dbfdb15b4a15f64f80df14d8ab275b520ce46b2fc00fc7799d2639c5505f86622fea8ecb9563079c07f106a5fed4a650700ca4e8aa35baf5849a23a4bb0daa6e09b4f33e545e444e6a9fbc1d80965f93dbc6c21b3fb30aa28e9e1a360e913f684e201054d0e48e1189a60e7f4cd3f018072d8947cd262461778d53b07c26bfad54f39f78027e56ab13392e15757eb8e4b754a64cf185d20bee8e6425e1db1443e77452100c99414af312340198e4deeff03b8394186c83a3d5cb1af7b85c5fdcb4379e56b30ff8d43e9ffe635127d2fa96c8772e75e0436ad92538c000588050fdbd291fa49ebf9e1dba3a200032ba5f3c44d875e26c33683f60067384d3d598bbd9dd8fe29cbf65700413c27b65ca7f07208bf03ec17c80cabd21f5d4b4e8dadbbaac2e485c36742d71d219e3e8d2819b6f5004def4626c3e0ead3400338891f8e778712bcf5ecad536246c78f75afc55d052236e5cc8a92fb0bed3a89bc58782fb19342de067a2d140d94cfeb4087054eddb13c05a612d101a1d1e5466432895544c9a98e47f8271bbee014d82ffe273416946d43e0fe51ad57925c9ea2ba8a6d1ae75f612b8b45cb67cb1959111e7a2c921d29f7411fce8e63f029f36d040ebb024bac304288460a68b537061280ca4ef1e6551566b3c2b8156055bccf9d17e0dff416b20b62b269c3483431d0441d8e5bed023493eaf4b179a64a9d1d3cfa36361f68831c0c11eff51ad6af07731d8e90c062b1a10cf4c8f5c31da334b00df77e64c775d2840ddc487ec34dc2238b8cc8734c61162e59ef1751964c78a803c516fb0bb8199371cbc5866152c63dd4214ab30526ebfedca15affbc72183fdb1ec2cc1e327dff4b58b260f0056ea21573f0ac06984fc65775e642080b5777ea9157a1b8c3f2631e63892e9285334e99fbf08daf96c3ee2d82470d8bf246bb02c9bc7530053249e6aa39a8a9b916675eb084195b4dcdf3b802cdc04c3fe5d30d63dd8acea5ce3cc34a1baed1702a1c67e6c66fd865add55b03313278e8155330de59c20c76a6a5a8dec148d5451c436bcadbd327c2b62bcbb6429081b745941e141cd5d77f760af3a49c588b48c31a4dac38118ab41fde27caa96124b45e995c4a7f54ce786f849f9f4510031937f2ac511329a51f2f60639d5219075c711578857208c139a7e500035d0c999362132fc67c71dfa8a628fbc94253e9f7c0ac2b2970e390bde35440218102b32eea647ba6f124fa7b8bac1ef8debe89c97453b46cd353cb68e43404b351e7a9a495b3eece4212f9a4e713b577495084a81deb939ec68140868964c283ef7dfe03ebb18c762540ced31b6513924384c3a31ba4a43bf0da84fe1e94e870033b672faa528f5d8f520413c0f2003534c56402326446b021ff91179d8378f4aa790f59e562176a2f061a8aaef7608218a17d63e3cd59bbecc31a5c849f194f3f14e8ac98ede038bbd15473e06a52e910638d1e2a36e1fd27eda7b7e59349cc91fd2183d32a7fbf25c35cde536569d2203124f6fdfd93a593eb3406e9ca7892c77b08dac0f737327922e4d700600bcddf8ca73edb3af7ce7837d655b86e426cf6f2e24c5ca2eb9f28696e3dd76286d1273ffdf4d2aef5de66f616e543a60cb676547ca06817558a452d8bdc25606331e5719e6d5eabc0488e93e137884aa07565918943a1c439e79df489a0373199fea004e46729fc010467f881461968d6d13dd93a917b9a97fc26e9d79b8eab616dffe833ef7b7ed90dc12e72cb93c30cb546bb0127a3a6180321bec21bbabc095e5e0933e5ec9ecbbd0cad5de37a5499de9a98bdd4d1146d4a5a353bb733b71307e807645b7287d6d9bcde83ccc943b57ca40b0e099b667153ecd03bb1097ec6f5f55b14a020d8966e8786e26372ca40c3db56c514e06bf9007cd635831d21ded8c110519cc31b6532c33ca8521b0e1740ce435e8c88846bd46769b35664ebf530ea69309a722b67c1b49364ce11f400831e138cb322dc4568f5a9d39212ff9796f8908b28b2587360d461b3b9082a636fec836141ec698b52d628b631c5ba02c9fa5a7c1f9422265fd23580780989d5723a39fa3527851176ad868ca73d3f06190609ea1d2ccd67095775983b6a479b09c247b1cb7b5a4d57ffac3c97b3c8970e9c5f914cefc5573a784385e86a8fbce5a5aa5f988bbe9b89c649fa71c9dd0b52191898e8db77e311e474ca42dd19192d6b8a99dca293921c6a93044766dc8d76c0295f68ca66326c9bb27aa0f362060e59c99cf0856dae8eb480563cb994b5f25f084e8193499a9efde0e5e6b3264d86c69bbb5e742d763a2daf62d929f7824c8ed4e0658ea9b3f28270ed1a3b7e79cc5f3b9e66e449e127571699f42430fe4bce76410bf59c4b493f4637b3b3a003d88665160d58b2a3ac34ddc81c8b07042af28690a4b2c040982e2798a2d9c9909ffb10d3d4674350616e9f16a2ca4f1510efb29cd93845b7dc8478940b729efa7b9b1fe56cd965345731bd860dea8591b4cc1f38edc4a840bff6c239e31b54bf91c9c1bc257ec0ea657b247622c7f85080720ca33fcde19f8901f19ff7f207c785ddbbb5879b6ef96b61f93dfa22b28bde48a48a57c85166759892f32ac2ebe2c61ddbee205e3efb1f054d34a25de3c89384ee404c5a6fba14cb2bb1f2c15684bbcb29e3b09c6e8beeec495384157226efa905c5f351a5a7ad5f0710ab44cb1ffb938cd0c43ba226a7287de33b4f1735c131484412fe40d4ea327cd12092cd79f7d28769dcdc10c86497bcc074a9419a101746140ef164844241dc171ef1ff4ea4a3ed3fb7568030ab1bc29cb99b816f896ba35fad72b2fa9a76b29db03e599fb94b9dc99aba278810c4c118265c4b3cf2cb58966ff4c6a372c7bb6d9c769aec2dbff7a93d3fbd2923b76f59b452eef6c4dda78db1c1c9e577c3b4544c2d00628d8498fd923b9f2b0b8cd39b1e053f8d4df4092040f4d38a45126bfdf06e395f505bcfec7ce36046cf2e1c18eeee3afd9fc8204f8fc17c306cbab059b0496491d8412579880cc382a24b6f7418e03dd2d3f25fce12ac62de50624e62d636d0ad4b677fe37c20c6bb3b5c63effff8048e6df10f7016206f0e716683e35177b1e9db01dd61bcc08579e89f327f9b18148d477ec0c8075f85b1306338291373d5d15c03bef9793e948aad996858ea607bb6d83e23a1b87a4fa819709361cb9096b410cb4ee931be962e0dbfd9478deb80ae84efa3b289e0c7f8e8602a6bb381047c5c1e04a881ab9aff6b106430a98a044ee698dd9dd4e8b77cb8b3f2f34e2461239268dafdca3d0649c9c8dccc64ac661c7a5cdc9b4e4b3598a6e35734bb9703b356ce15ae061bd38f537e1b141c3cfea4e37e6e61f80471ef3b009368173b17732a97ab91db4842d36b108854fad890138746227175a425037d00b0f8548e2408fc58f124e04df6c967cb70efa1eecd538093e2dd2cf207438d4ffd005c39d8ca98fcbd7be51b19034f05e512ac7cde39a283ae50af7514e7db5b26f365cea8d5faef7789e292936ef7a1ae859460d9a3d0d45aeab052c7036125f5ecacfec447fbf94b9006d61ec902a6b6e6adc7ecc46c12867f67cad01c36378b6dc1917a0d7872c425df42ee8088af3530d5733181b39c5ebc40582d3710462341a62e9373134d62944539e16536f83b664c019a6b5649d926fe5990fb381d33adc6a769de4d73ae4f703547f909624f9f9c26acd2a3cee2da54d218727ed3fcefb2a09b8cbfa7bf03b43b02699b3c429b6254eea7a26cd2fdcd49ba46c48b6fcc9fb3d12d6e75d7b55757e62220822484b9c4e42782a4621d25c3cb95f243e448912fce8a41026abd628a2f2942e9f8d8b1380099755f61643386630c6628d4b1dbbdeba5d68f2a3b5789852c63da24040b9e5ee2541452fb11de225926d97d87a35495a5276c651cc0b1280c8e6f6c0186f7f23cc15e2041b7d1c24f538d4f6d7b0aa73e2e30c37329a9c49aeda8a09897807cebbbb213319fcff81b1cfa3df28a4ca6965318a2742b6e7ce9f928f26d6eef19963daa4068917be60b9600f735c6c1e4fcfad979ed154ce3f3a00fec181dbf31cdf896bbf54dbab32b05677a4bb5954e01a11073d9644854acb48200df7ba480f16da35ec3a1b8f1868184c2346af4efff4babc3ca2fda1eece2ffefe27cfcc14fac298e6e8ab30c23dfce65791f49af1c07b1719db5d54976b65d8e39d64e920369873700afedbb7a6f8b37750ba15cc712edd0d74ab879a85d0d97bb056965bf3d0c966336cf8317370648e4e0a6859ec10ff2dd3324a35eee9787d71607889b8941a58e0a2e101702ddbb26dbef0679c9507d0485418e33c11e9e70b0d45ef8e77e8f7d181aa05b2befc6d711558637904bc5d5a6d5c2738f89da4947eff398a325873d1998cd1af96a4d6df2932ff789a4d0af58b4e2116a8e80a8cd5e5df644685bdda71d47e2714bb4a2ba932e921a80a0ed0a8b7a8f129759b7d8454e0dd7cfd46508d552c42f892b386685f1c64071da6c99e0050b0f7563df909cdfd0d415d9db7452c6642e35b008d230b4ca58eb88af712b9f48d4d8a77b5b0243064c9a24531b0bcce691f7293060cf0739dc431104624a281e27c1f449715d9457830500e048aea829bb804f0b8fc25ca488e31f1a3733f98cf6b985fb8156b17e78c083cc80db9ef1e868b679d523361771e90341a5d3cf28f0fe7a0aa618d9df5585907bff499e1232fd7d90d91ccca10eedab57567b788c5276d94029ae0e64d44d221ff89ddf2f57a38a5fc3de3aa30bd335847692ca9222e265421cba09326ade1eb1c79e265a9edd31cad8b9fe20509e66413e9babe129c619932de06bca8deb14cd903dcc80afb582b386c094cdd5e53b323f29d255874ead2200019bd5fdc5f629e6d66d642474c97fd69f3b828a12ac82de16455b69c363082d60b375ef548b13e91bff6e17deb970dbec39c6de1e3eccfb47f4b26ce837d12305e5a2835fea161100b7b14d57042d26b85d8ad4d5835aa8610e939f9b7867676210487181e394658e7264241c988209cea013ead3f5c033e018c7d651d8f9638e7a35c19ee22fcf414fdf7273ee86828cd1e62be99f6d4b43a85442398776da2b84574a7d6eac8601b5265861fbf454f891b8f29b120eccaf366fe297e55a341e0e0b93c5611aff8ec19ab3f6be042fb5341b67f34dad304e90d920c9b8f7e375a3d3a0401b6e7fa66ee41c78115d77283df32f6ea12e799b09c46ed2e02cdcc765e07d212ed4cce522fd728f2fad9f4ad6dce69feb2680a372b10b11a286961f8358993f646d3d0f36c54ff4a97ab9df2765e646aaafaeeb7017c58094d94ea33682324e08462a3cd02e3dbbdb2c3de089925b643777b6955fa085205317bfda3b3beec48259cebfed2bd37603eef6beff8c40ab87d2781660cdb53e813adbd67413cab9fa007e5eaa2fa1cde8c8e9aa3240f6ac57ac780dc988936bb61076279cc965049daad7fa85eafcc9f33a5651c990a03ba66f5caa276665e67489049d97922f1da597a9d2f88e021196e74097dc13e19b5148bc62fd10036ae4d7f23a8324fd07bfcaa05e85a0cc45e4214d8ac57537098f1abec0fa386dc5ba6c5437814a719386a39bf4deefce43d69f5b768bbb4cf9a85f220649525eca3f0f730014eca5f470fa1defcc82dcf3787fee80fac5a772919e21437d3e4ed21e57c0bcaf1d7c6c20bda426cfbeec1976e08fee3b54bee9108bc3b33076eaa5628e9732e24069ab045661a0228d791348c2c4f9c2acb9e430586de4346927330f87411083516ba76c675a9b46e34337a7ba341558257c73f4ed4354db1ba68b688098a9510c48267ff88a3af2d01a771ff9a33e68e0eb4cc7ada4557fe08eb859314062806e86d3beb5d679bd687dd1aea35a14ea715a441029071c0cc1c5932eab8718f1e1dc7d9ba855443c2d03af81ba403e97169ecbf06a7073311f3e3420df519cd14d7a60d828830ae08e45e4d8d4b240a18ee81c6a4fa90a6ebb821a2733f4117e26890a4abf99121cda2ca5e61117ccb7b33b8bc3765dfd58426f4c22cdbeee461afa3ad2f5e185cde03bc4d5b5b78f869fe881b77c6498270adf40df18f46d5fc232c93a075ec91b7e43ea48dbaf871657a641aa8e6f6d5a58085998da705d08206ca565339535dd46a7eb9b06d776cdc17488a7dc8d4a92708a5b3d3aef88ad98c317e5e85be170cd52b884404b3d5134ef51b7604a65ac06743daa8e018045c5ac6709c6609b4f230e09178d444d595e78a451f69fb6485cc2613a876384c1bd9aef7f4fc520b227d998c7b10ec1bffa252c7502961ce2571fcfa66aa27e8c5253913dc8630b20199588c7e1f025cf5af1949dba60698e5c23e9904aceef99a9fc41c5516e2aaf8ac35a9946119fbe75a21aa6f1e6586987742c3d4ff743e8989b0c5d0848317532ff53a15a8cb1d6ec1ccf7f711f9e6ed852df31069f659ac089f052f3faa242fe7695837c0c8dca8ed316e6deb1366781c3518bc4c0046b0af48364ecb30acef5c47c2744235eafb9fe7882fe757952ee49ad07c724af18b4fe84444261d8e9b059d60577b6312c7d35d49cc49ed8f3a8df15236aba79cd5454d1d97e60a7e1c89dafeeaa3cb265e76070429f5a61fd550e61099822852860da21da0eb5e8dbec6c72e5c9519c6bb1b7c6d5ef665015e546e766815c0a3c485e38e1694ab4ab49c381190484659e6e944f094eae379a18a30366a01aadd61b1e3b71d0eb878117f451228327bae9e6ff47ae95116c539e44f6fc1d3e66735b586319df551c30b39c1cba7510875dc58e2a30d694a970307569770ce41b50f6c0bcf5a80c8dbacb3ea0d769cf3420b1191a6b1a36082542db1c883d574fe785b1d90b497ae0f1b1b89c4756a8af8c59a3417f07510ec194b801cfb771366ffc49c93d3c683d06249f846292209b1becd4151e7efca0463f53983bfec7ecd250050048e29b42a9906c5e524ca3f04e90c1f56f13e37d04afa700a806f0dea03741aca5c0a76ce1e0ed3276549216246fbcff45e00ea9e3a8040dbacb853706117eb9d410e903f5c0ef1f1d232a00831794ceaf5d282e31ca7a95cd84d1c33792503db3252f0326978b81938810875749e265ee7eff36104e0c3f3d3611bbeee78260b8337cb1d1f5ebd0fe7326fb36884618809944a898df61ec36f16c29820088a0862006a9a5c40fa9d7ec0795e95ec3a3c4da53068f8e2b15a334d4d272e4e261a59a921d4b2502249c0c9ccbd2f7e0d48b018b4c400dcc606758d4b06ed486b139160bc722fd66ba8d5890c507bf140b0284c8871e30d67a58ea975de5b7460e4501a591cc1723e23a835b4c52867cf05933a2a1164db9863533fbaa8a94b4ca11f9f859e3cc210cd65e0420f9ea4ce1efdf9f3d4f8fcdb71455808de52ba7d1946d701fb833ca5b7396a6c928060b7b049897f6ed43fcc439f5e3298414e57475cfdafc216f4f98e0af75041d49d85d715b1289ce6fbc66f0deeb962a472e8a47e3ed720e4e9978cb509d8f4816750f3f54cc16f97b9b710b89c7e68fe62eef1c73083a0dec89340ac0dd708f1fccaf70661c24e2dd865f6282a872c19ac474b92f8c1d3943ce6aad09c591eacc9c17cf1695665d9b6ca93e9281fa7fe7edb9cda968a58793085720b93f0d340356870620e54fe855ef1084de548658fcf1828110991880e992d49041623b9f5c9a22256bb5c54eb41a03d6fb36bc4584600b9fd311dff10e3a4a7bed4c11c7d643d15633df67c612faf516663d6b45c65df61c8f0e4f48ae1a484f429f41b094303ce4567fd0753b081c3b43fdb2e9b653417febf63c2063e3fa84f62672012a5d4ebd2354c614721d7447cc0d8635832fe51d8dae67fb545d8cb9df76dca89f6826ca75d662c28e45d546f3e91ec7b3efae9cf4f7383939d020cede5bad1486f1afc7b78ceedcb14763557fcd5d0406134ca78142d3a92dda65636a37120c5722b4d7569ea92a2aeea9981484358eeca400ebd604a44a907040761ebd91b2d38c6523290822f7f515d305d1f11db32adcce296b9728186b63427f03c4ae6c9e01df5ab950a95c19ab32be359e27229ec54cbaacf594202b053e15dac56451c66012b6f052aa9a7d51bf6aa97925942ac87694aa0ea085b51dd2a7fe640229d157fb2b6244662890747d65e279f3a198b7e50c682da7467ab6c55d3cd344af1b0abd755eb9705d2af564a4f379489fefb2b6e94dcf8e0d36f9a7b6ea9d8d91119941009dbbebe040d3cf6a6b27b29a8d4b65876c288feef1b5fa9fda0a2fc6b191331df7ef49eaeead71e23eaad545a3e3df8f805bac2695f86756db71970a2ca5d7aac49666180f7dce3c73f34c7bd86de2d8fe2fb0709257a9343d5a7d9a5464ee970731b4cf116419246c1d1fd492a47ff1ccd14f14e9c9cece0445d1898ac44e548676a6257c9e3acd883a3a1b5494a102c237ce785f84f31d56824d36f473b5dc7ee72446c1a9e0ef632e1316ed7f8b5f2b41e2e413daef82faf83d97f000933945a52e4cbff76281ef3460b76c8d27339dde5b2f94bef127bfbca0ebacc077f9c9951d51036d577204b3a46f669a0ad2f3f8ea381f3151a8c12869e3ba70ec622f1e2ca494f1d507e6e854986899b4367de7dd474982be874748e3ba4e4383d800fc35c491f5826989a605fcdee5e9fbd458c8048621be5e6f63cfe3dc6e6c16fbdf4d3df9385386cca2a90d3181f8b50f597526532c883fa48178c9f6b9ac94bf479e3060be0f7dc5089897ec93e8bd3f0bdc3caf34bf6f7e14b5ccf691f7335a8e7452c173a5e9df4691f53b87058a869a06be36bf708a945edc6d8cd201fa9ad6b38990e511f6617136f964ea269eabb3e39906d3c3e06e0670eed7e382cc9caf98851d92983d1e50d22359457523799515ee1ce8afbb346a434f3843c28af507d800222a29bc229b1bfddb097bf4ac6f9b8c7b0be96c06f4f533138d132125062a93116760571330828e15a6a2bca50ea14cc089297e41e0b3c99424bed11232ca47d42d92b011316cb853af11225e5af273d9a5779ede0314909d578c35cf90f44ca58cfe4297f3d537f3fab83581af591618915a8afd40a1f81c43e163a3d43ffc87fb9b32fcce07e6b3170f28949563408f075542fb54f2bb28a2f9155b49758d445c3afc78f19ef798ac8338c2f46561189a4bfa8b11f12c04bc45961db4da83eb63db039d5cc5b57c853ce146f1a9f484a249fe303794efbfc598f7ac6d2db6d20a29081774a790f5f950c4575d78530cc95050ec8d96d94f7d00a90cf9123809cad1765facbc0ede6c8135af086ca8310d401fd8c6dd22e7904448beb40007b089d9bc7b71fa55f41f744141f83f80e411ee0c3a21ae1ca1111f511431da12ff1014952b49e639104b51ef7dd39703e7637a484ea32e1acb31e64cef890cec7966d6b6c9c1557d44def8ce44f0f541c7f45b0bc047d4cfd2ebb78efe2ffa08f917d270a34a7022209906cf47035e69743a05dc12ad5916586501d4aba39b8a302036565e60c0ef08fd1af43b99471b05deb2d259b0ad7463a7922792e4311dd49852e1954b1993b8fd10921c68f55d81d534a8d4e832b1a2b29fd040d387466689a84fa576d60c2365a9aa35a60246c46b55fb75147de6280b2ec6baff42b35c1ccb577f1921edf3c32f3a3d6dc72965bf01ecd27be641fc9baaaa6bc3e163a53870d8b89a1328582321676bbdb80f2900de8b292c98b399f781365d3b6a2a6e6366bfb608661083b33c2240e262d79826e99701108d3a6d44b9e076b50388f53e02c686485979fb88cdc6d77f756418e4b6b8b72533148247d97f48c2631a823b0a9808bc410b511f7ff9a3b599156d7839997ca25eea08ade99d4f76582556342a40351299f250459663b1e8733016793b083ec2cb7d7945bacb8e9760ea79205280912d70596cc4fc01123e9089b72a6e873d1381e2027c879496b4add9b39e7967535bd0547e271cb4d18045d0231fdbf9de95db15d131666256ed2b3a6bc7bc5ca908cff3418c59b6fb12143d579298e5fca9f1b77f55e18bec825b74e5d4bbfc0fa067450defe649fccd7425f8f6c73a6ddc17ceef8dc66cc8255e20592583694e9bdab5135d88ed311bd67032b688d24343fd336c69394e77cb608789b8f412465d36813ba76e94103792c21f5b8d8d462a40587637e004dd76c0405d8b45ebbd69874ea78a6bd4039dffe435018b5c283ec1d405184b609f06863ed5f876019d7931f97159ccfbc68c9622732b80d7345633df6479555014cbb4418d1cffdc0c77978cac43e047a12d5814688601c4dea21c685a025185a29170ffaab0bab749bd29ca95ca4ddc94be67626f23584a3aeeb7fb46cf1fc72041ba8b47406b31c533b2b1d279f83a15e8b95483b5123ca764ed3a7847b9a76403d01583755eb478e96dbbfe14ea337d2d2129d75539c70eb057b434fce3bddca4a8140f9caf168a308815c89103ae155f117c70a06abf5caae57e871b1769bf5f359fbe8bf8441d70e4f495c12fb030971ead89d43f26e04033401a5663470925a5e196f2342e5918613d335847f3dcb0073d587bef142d5309b201813352205f47b268de0749c191a076ea58545002ff18f7129aa2c51dfbd13dcd7872c43ecf21e4da234e2b5b499ca3f97982b6ea5988abe350eba5ec2d2f8dd11a59d9bbcf1a41423e01c4e805e294e00b532c1d261748a5e69a3adcc961273fcba1f461c593aad69cfd68153925a30212139e6bb4ca644eaef3bf262df084f6ccbc1a0402a162fb79ccf6c3bf52f5af26bdd0d3720de224026de142ed3548f0b3dd29b5037ba22b8cf1f70f86c0b419509ea02abe3d147c7391070665e484e612bc3c46da162a32be92dc838cc94aa80201cef3a74bdb3085550d32598d86e90c15d691a31e5d470c043ec2ba916e95e28f08c1053d63f7ac7b7e360ef1a2d34754fab3e1f08bf0bacd53aa4936ad2b8df3721663f9b201d1c69ef0f762f361d1f1e5945ae8fdcc78915317d8e9f032be87f010c993f2d54715a740168183bfe0cd1b903454b816e10955797ca306ed11aa5bdb31dac95a115556ea5a78e2c909d8ea5e9c530520bc3efe8494af811a7122e4fcd8603e743f5fd92a551054692d1ed5b64352856d8533d1e344fdfb28e70b6da3d44be41e45be94167052262138e4ad7d97e9a9442d56f68db3fd936d7ed626a6ed25a89de8876bb9e19bfb3b9142276ffbac8bb29ae843bce3ccae629453c40fc13b2ba014bd44da37d8c504a192a6bac71c975a9906cb939981ed2402d840f74fe93102b5f857bd0b0860dc69b668842a8f94ead9d1535d7a7dbde360a145ffbf1352cabf874cc187487358ee0b849f8e7f8a15e935faea680fcec72a6db39a1e28bcc3f541f5b3f5a62abe4be796c1371685d5a43abc05ca8a20cf5d93a79e55d88b10f3356cca3307c921eccbba565f65527c62f1231b27529ea84cbc4b643da256668358351eff5e9752d47517ed255137cd01f1a47567bdd26b5af0b3a013ca7b114730fbb526691ecb51eae21f93529519a34bb3af40557d8eb6515cad246f0ee6b155ed4f0fbf8811361148191278cb3cda072caa5ee8012ae07325429070fe74a69fbeac9c560e3929bc03bc468c210c11bbe9f280507c0a54d924d92b1aae581cf064b491a9a05c10a4a96040e4a8244c167af950807844200861e3dcec7912c905bd0588d772e68f5402f4e8e53933e3c82d82589eec9036614cfed51cbad7ba86f9b2d90050301d0817eee139895a1b828ffd115e886693f61a0b351a84023506e6dd1bba9748465db2ced7d392b038d79f385185a80e4e7580a71cbdcacf34173680127259c267bc001dcf43ab7e7a4bb4f6caf63990d316b902290e9fd35c36df78711b07fcaa0d192c7e09bce45d243629c0c2afe0c1e26a73d965ceedf9fdcc70ec2bbc85f23d71121cd8994bb267fc7aac078bb504e0aa880374991bc779c512820060d3fd1279e4f8f7bfa532bd70abf51ac7cd752d295875a010e173efdddf7e2c22af0d4f8eb7efe24cc59a850a287924b48e40edf5f31761fcb9d9d20f4127fde627c9f5c15c519445bdceaddbb3d7b641aa4a5c4b38b65adc347164cb41cc38af38ac735eba198f23b9020bf6f9bc37edb31d21c39a3df8e2f5396004943f685b7cf103f4041b8f8e07ec0db858b819d4702dc466198cd886046e0aba6b04e6b3239b0638f00f1a7baf3e54e0c5b1df1ea185d72c2388f28f58fee17d495c28ecaa798844ad17f609944f590b44a53e8a9702784ae4ed205518600a590b7af90d9e229b2ba1373080cc2c38b7b275a699683ed38c15e418a11e17737a80a7026c81b757ed1b9f7367abde9154c418884579622516981c54b24f2ae79d83071971768849c3bca57f78e7193b1b05982eb52e7e2ce8d05167fef3dbbe6e7e623c4a2c7d45db2127d6d11685c9528494ab14a2529d2d838a146d2260d2c66c25b047aa04410096f0c4ad968a8f0e6f81792e77fbd264c5abdced4cace2dd01cc1e179f53f1364d888125a76c1a774324ce3431f83896725c17a29b784a843b538af745560484291adbc0dd7735ffb3d0b20c0b9146569ab237cbe821121506555e9aef80c7db23fc9ca9905ee2a99ff7921e0c563c68438551a5d56e080e40fa6bc9efb5bc9f31a548374afd215751863d091d6ae78c013c71538c630882c2cec4f0c574142f9693cf3bdec34dc655646f9da4dc534a06b7b5099b3c4748695f69e11d8c2515c9bd7038a14ec284edd36cdc380343e5fa17ec688417161fe843b7346f011937ff039fb8f108c25aa1d43dda09b96118cf5e97aee43a97ee4dd106071e9341af4bff2808c0b16346ecfe6c72c75467473957c57b46d3ba9e05ba499557fd8a4fe195ca290ae5630e0f0502e0686087906cf59e0eee9d13e28b948222b4497a4053d1e06626ae4dddce15fd902d90cef596b89327bab92874d413c8ca211c8616b841619d848aa2d7894d156cc65daca8059b83471685f801f34c495b4cb0b0dbbce50731002d201c297e9a28cbe2b0397abf44842acd504af477060cb6d6644690ab8c4f278f479d912f267c4ecccdc20567de85c8ebf231e5fb55f19e720db1df0853ff09deb9a58c9817f48f9abf1698007bc7c050e8e44150e52202015271d59476117bfec8a82496e04f5e99da1259c64d1e567a5f727a10cff4c13bb32cb6008aa460d2c902db64eb0292a5cde5117c76f1576ed42ed8ace5ef40afc9ba1d53e526b84104208217b6f2977430ec50d4e0e32dc4b95a30cf76853a20ceef1bb913282ab3d6a31cae0364b64e6f08f15ad7a15b2c07d4c00c37ee9a677a43e63b8a6ca409583a40ce5ecb704908a261cc761ff620086cd03fe07eb23979e3e95ba1c0753a394d1b4976315ec3a8ea348b6d3cf6ab76316f7f8d0558f8f928e030aea22e84ba75e005d521eefe82ea2c7ebbdc7748d27a5a6463546ead21e4ce3c118a87ba8c91261d61eae66354de34af605fc0b0872424eb8584e4e4e0ec7712f594d03d280388dd2872824db3bae8db40cfdb6358f4c027824e4ba6e07f79b2ea855dda803d2384ffb67e36d94b3dcd3299507847c3a3d3f69d57797a44c1f453b3cf0c115f1a490bed3aa164bc1910d5bde3a2db5773a450f01f03a2d6f1e514aa791aa0bcb31ed54438d5a912475e95b6aea72da637c9c319de3befd485d20df75c9c172ee2cd6c51b72af57671031e30a52e01c39d33a8874475b354f94419b8785b823dc10c540a59bac105e95585c3a76a2599116df0169da1614236643ed9d6520cfb2885acec2401cd4c2adbcb04072a6f4633c4c2f5921bc3259171a1b52869e4e81a607c662da4bd53af6fc20c40c3e82a7bf5466f1910b1eab61ea625c5785cbfdf48123ec2fef5e4095110672359c56b8dcbf7aa3dd471605055b5c8e3bc7dde3de75eda2ce1bc1d3a38d7ee95ebc17d1cb0b77ea75a7934bd5ae4b4b6dee2e18d63cad32d26a267d84863dc5a5ade452da4b2ec5348ed52a1aabe0872854f10d979e8f501796239e770ce338ee23ee1ea669da97a242d26cc8c4fd6cd8691a461a815a78823f5cae76157a0b970f7616973f6a325cbe886fbf85056361e1585858585a2e8e9e50a75317c136b262936c2e1dfd569bd545d073b5799480dbc3e64142ab49b47ab8f6e1e198e5997e53ed2165e8bdba44a75c3d25ebc284078018a8fb94005e2580dcf97ae769236f9657d9496f0cd429ca409d76414c7bc7553ed229da556e24f2b873dc6322dd54a39401535498b8241b76672d01e46838e4025110ec6a6c5dadf6e5eabccd0384cba7e2b2122ef3bd145c3ec62c3e422f6778f531eb368f446936042587b9c41509a40c0da3500ff71385db5d039ba7270a39e176366c907bf3c819ca45212f5ccd4e1f8d02ed523931d6410b62c219757474b07a43fe0162fde4b0807e80c2370aee0d9e1694363de7d4346a3ded4ed60fae81a888b1660fd591334cecf490e604b0fff9f4f4e28763744e634dd3784a1165b4c6724e4a31c6b029622dfcbd5814f1a4613cd80eb61395dcd86263d3d3872f676c9e2257736bda651727cfa9bda753538a4e35f625019c37c48c9c8f6deff97007e3c1a2e854335b8c07c3768cdc3e66a4555aab24b53fe6d5decddaa9b456fff9e1c0ee208532bce10e3d68831697afd5df61054edc80614103386871871eb401a892aed57ae9870363c20dae50c30d0c065bb0829002302c680007a05418afc00310aefc9218f470e0968e63347ba28cfe2f77538d020b10e3b1d8cebc020c9bb5e3f296879a8b6d61b1a186b2a7ccc6c8e5986e439abe9766cfccf9912c99f3f3ef1a2f79c59a28ad8ab3875b57c883ce0dd9f53adc3ebf418bdb64b81d724e15b7df3f9eed9f69fb475a26a4a6c9f7519c0dc1eeeece2c11900e41f74ba60d53d7cb01c602a1e0211453d941a3407e9ec8dc6191ccd1a5edadd7461be9624c98f9c0c41a189fc84a228c66f19c75d81581ec61d43086e1f6d92567e22ac6862820ac8b7bfa1af802c6fec8197a20a16ed156b613623c3095ef8b8ac317e6e1900b639510573cacac070b8211a2ac15a860f41508918782b45aa1412c330868b200bdbe02d385ccd70a4c57c1e8c5e36a05a64bfbc48aa52d93a52e1e3923c4c5fbc7f41727d41f2b78caea61d91044dd633fb7efa2421c5747614177f6b0acf83c31738494e8d0a19f9dd962e15999ac1d660218623c4142d7070b92332d4516d0c0861dc8e08a551f139233f2067c8882c40841b0c2aa99053020c316435b8861d5cf72e40c0d2de8400d5bb0c08a553fd39133fc843dd840070f35c8912f39238457d89bbee75bbe57de973e198b92cc3e8159a9e3872cb01fcc3e41addca12d6a9f9856f2b8a67d425ac962b14fac58d92365bafbe7f60b9817184f94d13f18cfedc3bc8081f98b8af3e20f87dc5b27605e5466258041238ce572524c3b91b7c96ee73aef1399bed29233a01c81292a25d25fde276b5a39a15c4e8405daaae52c77615f2c1669308d3478c622f87d976a8a34f82db51469f0592a29d2e0a3ea4aa4c13fd553a4c15fa9a848836faa2c9106bf54b548834faa59a4c157a95ba4c14fa95ca4c1076b1769f047d58b34f8a2da1269f0bfea1269f0bdfa1269f0bbea22d2e0731526d2e06ff545a4c1d7aa28d2e067f58b34f8581d451a7c5ac148833f6b4aa41169f0a17019c272c50d9da4520065ab5863ada7a56915a35044c83a99a65596a653dc360a6d459a47773796f10c22b2ccce20a2539ddd860274bb79f47f9cb88284a2606c230144b4cc6733834603bdfad59865191232c53d2ec6767b0c262ed636247336d9478a4390ba988d6179876b4da873e121bb51f7212b3993f3e9008cefee6d530db58ac5f2bd772c5535a412ea39802c0f55422cb7d1fc3580470fc28501a68f0e01d347f689243c607cf42720307a10f6091836dac802308c095a22e5a93b325d2302d2c7b86a4c6b062d152b401f3497da70c85c623ef52fc58ab03eb6bdc3260c2233cb66c30128488a5ef1336cf658828793cbc762826284ba087e3683c937822d655825e837f32a2a2fabe224c5058341a4552e98bdd11783b1f3e4f261e8c0e08161a467887855700392cb87712456e10d462e3f66089bad3d6a71f9fd84478f257a3ac932171e9b9020be5921424c1722c485c0b81028342569185a8d0e857c42105aab0d751b2d448502082db2f8598d1e44858267c0822ce4ac468751a1d86eaa500c31062be4ac3615944e719294f79c16bb366457548703ecb300ccde75abd8955acab19ad2a88335449d3f1bd13dec072047832c062013b0e9276dec285166bdcd7e35d454439d1292694fb131b3e1bc2f97a6d8d779b062da0b2a4395b01248416f66d47b9669d4def4593ccdcb4c70670d4b2c6f39cbcb39822a4fe67c29e55cca9b7e3675e52995ef993b1007e274fb989becf3d9b1f6ded90eedf4f3629ecd81696fb902be7b0bc84e2df66eee68eb42dfd75ce8bd539b831e3c684321779e66bf0b9155b9029c16485f6a6fbe7bf6a6f40e330ba48138665b1e53c3794fc73e1d2c3980b02110396d183b75bab513889c9f12dc53de9f126d53de715d732add590a67c32734cffb6ceab1cc862abdb272959595c708b56ac5d64ea9312a3526080e604acc934ef1536ea3ebbbe804c8c2559bea89bcaf1cacd46af546832f57fb8a3d58b373f5d35e5019aa8495400a7ad3eb94765a23ada2d38356eb9426c11df52d07a7bda9d562e05d3c83f957c3125cecf1ce5a35eda267a7df6793e06e2ef88a7efbaebdb837bfced177da9b3e76f9e9603976ecddddb1d73d85e4a016f32af8dfab211439a60d5b0e5a207db196d77a1bb25696abd4795f4320b7e52f6a4882db7298eaa2c604c508a5dc09a47174db209cc374595e9bf4555c9db23142314f549a74114eba0816ad862a4d549aa804b58ab3b87c9527b126aab8325475c13e5d30b659c6403d10ba990b05775e25a41a6a55e4517b0dac1cdccc86a8a09ea369432d0451e8e7c6af8928f413575d5785f0156018fa59098122a62109447256a40b81a2061796f0b3221d8a95323c41c98a54325dc81581221176f931505ae521018fdd052cb5be4fc5a5a58054e599111086149d827104464f8d19aa308c748a67c603b03f6d4c6b49d8dc430cc3309557abb0140cb34b602a2f15970a1395ce6686b95edc36c6d5297e404be5d52ad5e97c9526ad5a51096de7ab825ae5bd9b2e916243ad5360e9b4aea8824441979190acce5726cba34925db6bc899c1ce10b704df7e41a17ea6002367daae8b0912d22d3c48d1079d959c372606cae57f2d0061f048197e18dbc288a255d8638462cdbc7c183c2008de98a028834fad0062019c0f9b5c207d718eb84efcce1fe3ee1815bb11732711b7532e8a090a63ead04fe95240da8f71853377be885843251487e0cf3b4b3d43fa3c11b1065b42caf047a26ef3be1c805ecc92b7cc3ca788a6d6a9b6d146cf89613646195ea8b243185f370281a597970b3e36f630c6055b063b78f02011b1263b08620c74bbaa750ad3ba4dca60360482dd8899a73e53f44e472104c5c5c4670adee954144d0059a253dc744ebe7b60a586b4301414d3d2c2d0ebc6b45a15b52003345cd576bf1b1fd692327c6fcbb298969c51096507434d25d429fe0440ed2d2907c1f35550bccf06ec342da57b8f918d5248121edd6685a4328db7639f078251a41d04bd0f897841170674dfdea3b351f688160b6382606e96d9f00461cb8e79331b0ab93434ddecd4864f84a39b699efd706440dcae63ad45a109eaed3c8e5a86c99989e6a7a8fee0eefd18fbc7bc4d69a40c6fb5b100d27f4b4429d3614c907669133b3e2e16da691f26e44c5cc5211e252f1ee2b9fcb095a066d0dc30ba583d3f2d200ecad161f5a8b8e44c773e934ef1ab536c635a9de298d6ac210c564c2b6649cfcc1c7e0c9318207e8c9358c3977bbebb9b093141d8e7e51fc0773766373be3aa45050b3065e8c6af01bdea2cf6300607604c50acf92ebb648f4dccd7c51ec60c21914404a2420aa68d09ea140c1d8905e8dda8853df8dc3026c825477fbe86dc9856506be10a42c859c52ce9d4b42aae4ea9bcba08deee41010c55545cad9ae7ab30e177d798568c4b09d8d75600ce773dc5418b9c158f89a930e9919d97c8b21e591613141324657a2cc19c619f18c6985579758a555c9d6297ebf29768158f98d6e5b30a4a93d6545d25d4aafed09c73ea9863d011dff6e61d1e847e56f15b2226c835d43e5000c20d61e4dc98a08e099a1941c1a20adc81bef36c1871b59e49d94840ab669cd14a933e25359aa59a6a1a5b2da6f85d7b36be1dbf210740a1d10d81dcbe767184b8cc8904095a1567443bf43c5e9776d42565e69c73ce395f53be5a2daec5b5b816d7e2581c8b63712c8ec5b186868686865c43f1e572b95cae1ed7e521f714e3f6f4f4f4f46c3d5bce96b3e56c395b8ef6bafc2de7f57abd5edacbc7c7c7c747f3d174341d4d47d3d1748080808094682610436d99125e03982931614e40bec9865a124a7c7b66c36cc7b5004b85ae84a541a8242c050229168405691ced22adca88b48a8f4169150e16d42aec49ca4fd8411ba29eddb305b02a292713b6654d7e837570d65a9aca3e6092f9e7e8e4e4e4ac469f0d3d0efb80380838ceea38f738368e73c4710e701c238e831dc789cc75e79db0f981001be228e0415aeeea383f56f737083815ba367e9380d327368ef88dcd69d01107f8cd8d53270730e237384e818cc07e83c469136c0bfa9b1ca73fe6a91fa2dc3048cb165b6871851bfac8b2b8f337f4d30659b90ab061b6c51651ee8d024ea1e8b8019ecdd5a334e288037c5e87026a43c9511b89da4d70d406aa6d533b01b511505b680de05736d45608386613f0694319a5553516e7124aab682cce3c8dcae2ccabce974e5a1584c5990fe22a1667de8891c599af79010af004d8f03316677ee608b038f330beb24218e0f10a71ca599cf9916671e6556eb238f349abacc599379d3fa1b40ab438f3f6fc19a5552916679e7ed37e6da89d2ccefc86337ffa112f9c696f0e60c31bc0889a02d0cca860081104761dbc0585a2069088e3e808b32ceec85297a54c6ee078960a594b9f9c2c0d3259ea64b31447a33758075b0aa5f26535802f1e5217bdd8ef5d1b9d7d36340866718eb8f3f2dae81a35de9a1a6f016abc3435de991aaf2a881aaf106d6bbca71a236dc59a793eeb214698e822b6c41a042882003d44c4b84070b21bc487bcf35d0c722e5f1cbe41e60d70e3a783de528f9ce128532a1da67417db2dbd45c657aa005e440db14b840deb0db9d5a35d969ae40713a0862f4835c48e5cfe006a88b12eff354cd1a861ea863da386de1dc247bddf65bceb3e1b015806a700eabc9be89b480075dee8625da68c3b6dbb8c80409306b93e06885a47ce50978e0eebc899b8dab9ccacb8eaf8b3a15ce95a489f5ca64297e9d0658cc8e54c2b4da6f18aea57b5989a8f32f331412f4014c8a5d4858b6193b41568d02d9484547da7182844dd399b20c235b8c51c85e42b009532a14d68167108a64234888221cae0877cc58b4fb9ea7a0252eefc0e815026ad8ab724811e801a2f0000f00880dbe88eaf2b2e3f723fe6a560fc8df96881d03b4f6d0cc2375a009c6300aaf692322daeb10df110fc5789528ea39c8bc9c439823b52e225cce4f2015063a7e64bb6b6a1790e02e7dc86180095eb6955b454f2666d07ba3cb3af5229964ca57322146541897a38961c381677c426b62bcae0388021d79aad4a44cbb149427ab2a1b66243d064391b52213a9483e91c6915732d3943240989cfb93826ad0ae3492778b12ea3c795cbbba637e83c673511cc1b2d90e99d6ad8c43d95563a6ea3516b4201264e9ba56bd74edd6d1bc76d2bdb4a9d3b4aa58df4538d973f9b0c46a41d7f87f94ae5dbf2957fb1bb7db4e18b7fda1f6ba9bf1d1cc771efe67ca986e0b5adf4ad74ad344b36ce93ae808ece7307e76cb9564def3afe74989ad8114b8fa7df60df7ec2bec514bd5631db4413b7f48904df8edaeed3de742fd99bfa392d90793b3b499731dec5a70dad9d2f5cb4b4b4b4b8d02127e60206e62ebe7fa5c2fcab2e0ef357ab602cdbd0c5bb954a5f95ba5cd48f49a7f83ff69b6ad8c435d9fca59fde75db66430e74dbbbeda56f2df7be5913e7e2747a47e9e9f4963a3b757a7f3bb2cfecf4933e29676f7eec361c72a929886b359e7ba5a867d16a47d5d81755209339ecfde9e863d8ac5ce91d67bfd13e9f699fd738ee86f3b88afd35de26b4df943eaf953e5f8a5f0e7a1a6b2844bc5ce9369afb0d7d3c6755bc00528e966c08056749f1bf0df9da5f11a2864b5cd283a8e1cb25357149a794c280213f24e28561814c1cf13831da207cbbed04aaf3359b748a3f815a556dc8b78a663dcc3b983a5f6f00ebeb6df4ca4b367e524e33619ac9a4999e081111d924d8bb96ab6001628f1af61cd8b57758437163cb9985dc8875906ea921bd27b8f113b3f3cb8199de621af28a8fd3ca17d8ea14476b7a48b978fa49354aab048adce4e68c26aed59d62e45aadda9ef1e00b377b04638c3664ad7c596a5643b04eae356fe9f1bb110f030373ad674487b9fc6c602c83f1e78a2a65d2323caf4a8db75d4815171bc069c37830869c05efa222115997f8b86a262dc307ab4b93eabcbd861897e0a35061bbe40ccd22caf0990c973fb5b8ccf40d97dfae495d5106378b0efd69632a1095884e45ea1259976a43caf0e91480c470a96b0692483fdfcd39e7e439bb583957e55a60f874b8e428953ea46b2f5696127d971c362ccd122d95ba4427906b6e31ee1673b797bbb55c98be79776b89df2cd7e201d7e29670ae4e71cfe8a2b60ba8959d4fb68914ea14dfcc4b279d92d4ca48e72b52ca6485c6f99a4d2494da4cfad5ae38390a83285ef05a71a0ab3b50a441a1c6b1e000462dfc00cae51bd2701bba7c8e6ed0c20f9c5c3e65c25cb8cdedbadc6a451933b6b82539a016eb4a778baee1805bc526d3b31a6b8c37e6ea365aabf25257e9519e5c36faa45521b7b68dba5ead0285e8101fcbc18814a14d28d096cd162fe1d001374b45195c04523137cb6cbf44964812da4d5a35ad7c758a97748a2777e638eea17c71077a8c1cb75d7bb7bd6413f9a2f4258128339fdf4d5a0573fe0b75fe7cb58a7e9658e27ffe6ec4bb387f36e18a6db989ba6a85a9e1bc2d357cc2e7faa0b92e396e44cdd7e5bba83e682ee7cabe524324ee8a4639d37168739ee66e73ce89c49cf3733bc671a5582a954aa8dad5a99d3b0e8d9be190ea82839b1cc7451c347ec695cf03472dcde423b978f795bf1ee6f417b75ccc7694cee1e02d620d696ea491461a2375c9ec0d6dc8a553d3b4a99d1e071d72b57fdce919077a75e5ddcae33c574d371d891dd3ba6c9fa592a681200af5a7529c75d9ec0d171cd8768de3321724384ecbe6b90adc52a6d99029a790e3ece9d4de9c9ed99bea8326e4ac0f9a7bb2b3537facff6e6b382f4cb5b15387f90b3b3b0563df72fe94e8a25db98dee668d2bf4915b7967c327eeca5b56be125dac58176f71711bddaf56b9b021e92db65d9dea576426b65fa45f7bc73938d2b11a2271b14e35aa45a76ebeeb865c17d3ca716c43aee99da9e2e86e3a7f39ba9b90e06bba89a3b9f13f5a0b74a15e078a41df8e8de65bc0e9a69b4c26d371cc9bac357d88a962a795a94bcea04e5f0e634314cb5d5897b7c496192f3356ee5263cbb458961a5b66c5a26a6c99d24fb5547ae9a23a5ba6f4f8e170c9b1dd741c9bc9deedf438361ab78ee937ba598f1e07e9df69245d23598dab9186dab95a22e24e2266cc881123958a8979b9f1e5ceafacd81065aaa8b074e349144fa6afd4d829930d41d14d8f6dc3d2bf6332980d65a98648f8a009c237d3e15dd3865cca715cc5b16d1cc7711cc77143289db52b718703cbc15bdcecb4741c998d432e12d96966a31577527a1c54db482176956f2e38bcc59d77c9517a761ca5d28754171c5929fb7441e20eb9f1bb31add729ee99f572c4cfe388438edcf812fdf721d74673351cb273a30dbf63d6078dc69744ba0d49aade556a08c5eb7e4fa92112f77bbbe208acf366a38c669524085f8f6b758acfb9eeb41cab53ec4406c9976c1229f778f9a22fce4a20ca245aea924ee413eadabc2b5fb28964fec2e54b28b126ca57a4b375394606026269e1520bc653174faec5b938d636d4aa6e821322413187bce8211b14dc60bf84ba1823afdd00a4ef39a72c79e04d197129ead298e86a31683492a673b5e438e8522ad26a17c102d87155b2934e69cd928fb44a6b56e85dce3250944119a8870bdb87878b356c885a44d55cc20d5e60854b1f5540e93f22805cf79cce9f8d8f7a3947745305353a05cdf33c1b789ef735010cf9e77a9e876198cb054670b58a855fade24e7d7a6e713cdf615de5ae2234f442c2b08e6d088e4eb2e1ebed6a8ba6945749917bb8f2e044c1951f757572d18b5dc4581e237f362c54deb3a126874e58d7f576e7c021a1200cc338b0267cf74d01729ce6894014f8ca81dc47dabcf1c371e2a216bb58135e3291db3cf29d166423f23c51e7897a34256ed034cdf3de75e70721d0f33caf0af26016577eb4852b2ff2b8aeebbacfa6fb79b95ade48241269224de3388e25863baaf16a11d4a6d73cacee61bd61a657525cfa39bb8f482a295140be22f0291c7790fb88c330add545cf3bfd6c3cce3e4ce3793b1b414dd3dadbc01f292841088bbea8eb38ee2038ea241064112e1f944ab8fc91a4e2f245222e62f1f30139f0659524c5862f973bc781a27b959b12ab5c0d5f6ec9eb948742691ae778f7c091a886e039a755238d7b9771f3fa78b9a3dbe814d08e348fe31e5b753ac771f75a453a7754abba7336f4f172b1733d5780d8916cc7ecf66dae687c02788535f07052097849dee92df1ebaccbcbe365d1f87a1e77ca5dd4759a0a97c2811ce91de9f2524af9ce9ba44822919e7d362454d7c2f72d2211e744198e7b0af791e823a99cde9d409144c1e5bbe0f2536ca8d1e0b2d4c1e58fbed3e9343a9d3496faf252519aedde9d7e369de7755c45a134cdfb0e845ecee37a344d13d529850aaab8710b375a2105a2e97158e0d1620d34768106b7f948d785bf1e135186e3b883439d8a27bf006a1a4602c1775a5cfe1b2e7f5487cb07f720bf1b36d4b4cf729fcdd73c5213c2c2207c4597e3380e480a71b8180fa75d54b322805e7dcc398ef37971f1f8d97c31009510550c1453f414d3dead81814c2fbdb376ebb86ee48dec8dbe23beb78db87ac948e4b998d04eebb6185c02909033dee313f01901ec1bd25099cd737f3c446febc2a34f4ffb4356e0e82425d264facb914ec52cfb4b96bd7838ffff549a2d2913cfef5e8f7a41bda07e1b0651f252ebb141d3a9f897aab1aa00595763a17a5a15928e901eaf49d12a954714f8d8b7f4d24f3fe9c81998c7ef2425a41f987aca91323fa39fad7ba5f0474d181b058dac18fdac008d8446504651464be2472e39d3ab786cb26b3289975a1fc070f4735b37aea8cc4e3b9d3251ebe95cfe86bb289d8ab61bb21e914e4539f92426724e79125015f12425a41fd2eb493ca92527cb2d7a45a28c518bbb281e112f0763a9f1b244f172ac7c27d4a968493fdd10a98a2e4a17e111e922508fb14689878847ddd3691533b9f1deb6bdc435484ae210f1f1a41e39436d8f9e39bb91154cc839e7e7f9e511244d1bbe1c7bf75299e811b1efb3c1bc1e928951ab53f1a39f1e1568d569e571b6521edf09c94f822ef653d2624df1b2c4d556c32eca8d47d5d08bc18d2b9dd08da41a6f0a483a4224fe742c4535875b917ed2008624255de3aa8ba0ec3e3e4909a90a5210090ac98a16931b493f37925e3746d2931bbf8d35d65cc24d794955b44c2429e954ec8494c44ea8a36cd11482d2aa108a2b3dacb26c8e730a6db655505ac5766445a75ada513f1cfddc788df5d28eb4ea1ec8497243548ff8bab16d9230be484a5c7448695db247faa94592921649094949fbb8800c24252d42370231646a29164022351446231663cc98299d33ca6923dde8563150af9c73ce69436a33fa3895f8bdd1ea9d912fa3a47fe8a20aec5949296587daedc321c3a43ccd2676c9d4b28c5152f98a9199cfc086c80f8832fcf5008c8fe1bc91871d32b979d0d376e1ef3c68c369b5df5ff99e7dac69633de5516c410de40e9433bca12413013233b3fc8400cee04b6a8427638d84a256492610be6d9b095d8c09695852b6cb19a6419491d7410a0857f24e4cea1b02d80f7ffd80870e38893f4028178a083006122f57a5ba892939b7a8f2805014ba4442ca4b32dc44153789297979140a0451a8a955500ab24954912136312fb529292bd9998f818a015da89dcf45c76d8be489ecfd2924c9b42176fa41a09f615c43a9758a1988c341968d62c4300ccbe4a96566ce58e3acdfd072b6d6ddddddddddadc5905e8cee191b73cc347546eaeb49c5a091f5f2fb47d16c96b20defa89fe1a3d68bd9181b0376aaaf3596643676ee44b419b1743999989271e5bb65ae7cd7300231b10879ad3e16219f7563b2a7d491ddbe4bca9943a91514a3d4c5f417dfee32ef3ddb806817a6c5c5edb1b0e3e49a6ec4c2ce92cb4b3ac5374af98a35f112119d56b0894d2cd060e7c62b9828b92175616107caa5ae5853bac6d73221ad664171c58587445d749115e2c2437496b35821a20f59a1ac1056c10e1b76562e10403d75943dc1cb539cd08704e44022f1c74547fc7cb42ea57819a854358f812c11fe51c2a5ed93853b2fc28062ce102e3d8beccb51b66b19bbc9e5c9b538d7acdc9278d94c1e6acd35de5247bef3d559cc349821ceb46b0d97ff1101a459c4199787548b37b89ce5a1867261a12e3923c9106558064d269d9ae05f6a36246522c785de6df9ac3e50334ed14262c59537b690f85c98961795d4ab08d2d2f7c5ef864422ba8d465596cab21271e006ce81248eed78498973ffe9d3265185ac8057d41569f09338aa0ae1156a7522495c340d04b925daea7c7d430051dbb67d6bc596ede60c512f75018f1f031670944be5d5022a5f242e5f407d59692e5c8b5bc2021249623a0bbe5ac089f09d19adee0b7c1065dc17188943c48b7abcf1dfe89a2ab780cab9ba087ef71dd9669323e08d13a853f32504903b7777ea8a35f17c8ed3c55f912ce027d35d30e0e52c77a9a258e9566f883ae9892aaf5c5658aaf45c2aaf5e56564438b2c7fa595ffcab94c90a7d61a9ab53f537a0e8b599f40bf5b05ddad550425017bdcbb2cf265ac6918a325e9fcd2bd6745f5ed2331cab65f85c8ff5bc69b912c7f9405d8eab2040dd696f5a0ee362010c78e204499c05bc4ac2ba802829c347c51db6e452c27247d528291291d5f96a0136b68c0babd51075a36db90dd952edbbfa832f072a91b9811ae32dd5decb807ca06eb4997cf123b752390baf1d0ac447c882185c60b8b3c54b5af503887663cb63ba5299ba3a9ad5529d3135afc51a5daed6922f08a08b02c9381714376e71e6635bdc908643726e380f242b697d3f8368373b906ce5acd3a9221ddf489d5c8e35abe04ae5a6f3ce13b146133c043fc62df010e5608138a3955e815833f3f8124d9ce15ab1155d9a4f8c2b6bcc6f8fd7a217552daa2eebc0ca3a4000b31769826b2c1187d091335a7435b7341f39b3e5581ba240d0aefce80b44bb2e2a7721eaf6519d6fa9aa7715c6b715c4990e43ac34be55027cd61a57d5021c46ad3956f97618e20c0d430ce25b15e2b38efe718f60c45a3a8e85b5b460ad168ed52abe04a89246016aea28a6e66bd03044529499df40ba0d6d515a95fa49a97bfa811aee497b695ae7c899cd75140a0435ad3ba2723f40ddac8d1b51a7bd37406d39006af7ada7a7673bd85a4cc554bc8d1a634b8df1d6788e43c47343600c89e82d751b926cd0e470e3f170e387ba3ad3e4c6732ca66999f818a85694ae685d74702190ec72477cab07f8ac46bca51ae05d05c0e3a783b3489e405df4d843742149a20db9d38f07ca0395b3a1076efcac92e6a21a4dd72af752ddeea24e964a6b16d429f0fa40ddd8a950bb1abdacd3aa2207bd0bce56950e82e758839b39daed34796986655186e90710ed728f1a7d357d7d3f00b7bea986d40c2175124edb2f7a532a65425d204bd6598b90b07c0502bc6291332c67d40cd7922e9f36b41f0bacef445eac94097d7511ddc83bd596af54178fbdea523c937c4d1893d6e2229a36144ac890150b50ef95abc4e7d6e97b37c3bed1b704e59e0c71087ea9d25794d164a552a01aa30cd2f9a3ae1f80a2d787d40524bbf11892170888fe629f70b9c80a61390b503609ce11973b14ab9bf8232e4b15c22b9658919c60054356a2cf8a04654b20b242782584054fa07ec46ac84af41b48508f16c9099e60f913abf82d217a09445648af585c4eaa213543564bb7352cc13c8c5bdcf927620d261287e0cfe8c2c73c3d8c69b8f316883592600f4455fc3c07a20a009f6722aa02f0f90ac49a184b519bd18ab8124d46449aa872d151ff57eb12f3788178bcf3a53893edc419d4e7c1a8fab20b633997e55a3e00e30db996b6ca94c81917fb44ea2ce0d5cbcbf9d98f9cd156fc1ebe0b1b6d125c8389643b4bd49ce212d48a0d519bcd4a966b5ab252feeb01673fae819d691ad67099bae1721f2e9fdee1328dc3438a86cb6231cbb52cb5dd2ad916ab444b764e6ee3b86cbe66f6396789ce796d6a76ce8e9b976ed8b98dbbe23256ba41cf51fae1a0e7ec972308df39815ac51ddb8e494e4a2e13c0376da9f459aa20f02eb5377365d61215747ea800e5c61f254d6e485d3f5478c3a5515a2575a40c5fd36cb0d325b2cb1ebeb8731467da15760d8ec5435419552b9fcfa26a53993ebbcbe639570b2dd18e72c755cec5b5384ef4eef40b1c8b8221d231446a86a832710d8ee5a282308ff104f36ef3326e49cb85a5542bd91074519a9d2abd44e7f9736167a9f417c772f1b0e74db5ab594ccdaf54195333cacc79177626c9e85b6c5767a742efd20be0b30ae03035a469b87cd1a976c2bef85d00efb8cf0603e78d6f6ef3fbf6e1f8222863bad4976c586fe92b35f4eecafcca0a77fa8489145774f9b47f7ea0d0fd5481881338d7118da37135fb272727278ad58c190fc1199fff4ab70389b07c4915401788bc38d9756286a8cf46fb766077326d4db3326eb0134ecc6bb40e71aec64bd9075ca20a37deb0390e96b3c3c98407133684d12d5290f50ab4375838584ba13ce1e4c0d1e12474aac3c9d2277c0728269b074c0f98dd03e5038de2873f58da24a7519059fa524113b1cd826ec11c620d67a910f721d6504b815a27d64cbb057b85c5c2ce25930bb30bb1667a81ba6816f40b940303c7840b03a789411b83f6d2323264653043acc99ac49a202a678835413834c49a207dd3106b7e00c1ee769c236e9052104f8b5813645e35c49a1f38a31b64650db12688c849ac09825d53acf901a4afe938f20641b521d60401dd703a9f8362cde95d010a4c40023d22008107f038ff54a9ab52da24ab14c8491015b21a7806ee0026de8063e00cf805aee316381fe73a91721bf438938273e2d02b00873e070e3d1238f43870e86fd4380ebd8d018e439f001c7a048007380efdea88e3d0dfab1c073c8e771c7b9cd3714cc7d98e931dc709276c7ea80401821e28e459ef893dd9a093e9e4c4b49980b64ca549a68d5edc358efb0d0e7d90951b840d83808243df4cae802a796414724716913a9288cc195a5569e4d68e4245145418a1e2881453b44cbcfd84a16c4aa264445a265e8d8a222d132f4729a594524a6f6cc41f2aaab847d43e409546d41eaa324712a9524716913b320ac91384102315d3c97a208dcf9fb73ffbb547f973e7357456e39a01cebd963471013171f20a6af20448c809942039c43d6915ceb4372976e65c19a5536c0007701289442239d1c7b9c91eaf137c5bc5a5018e4906b4264c989c60803eb900783e8562014ba3546094430121884c20081d09c028d243b5138199282040c3f3003e668407c66a150e5f7a07589c196a0db09e0dc133c0e2cc7baf41ed12d609be3837d8e3ad711dd607cc1e5f53b102548ca66251cc546c072b82e96044b01c1a850e550aa5525ba913da843239d5ad6615a7003f9db500ef4486dd09537693bdc92c4e7621ee8435ddda1b93a9491040294e6004a93c5109b5ca09ef38db9db0f7ec8db5385b6c01a5554ed8e36c338fd789edd6de6c1627fbf66c8b2da27cc6099ab30f88939d1eef7ccd289de2abea8451e7933a9d0851671395946aaa356a8e33731cd571601c2788e308719cd171544e77c2e6474dcdcc8cea372de4a382f19b7e22058c207ed3413d4108f19b76724488d16f1a883552f94d3731a292f29b7ef19c9e72aae2f49b76ed9c6a1aca14cd248a4eedb8c6d1b9c3063338bb88866e74a3db39ced09dc744557fdbb62d7b7f4a64db90bb23779cdccc86dacdde5d0f4b98c2b16de80e8d0289f7af0aa0c88633ba6bdf9132d8314de391475a0603674856a7b02ce585ee84728746417962cd764c07177b5793e0cb69fde9c8ecbcd62919651a6361985c290217e122dd288233623038236a73c4fd3262ce264da61136a0a534a01665f39ca2d82999862eaa26c5b00f73d1d1f1d82100f2e5cff0067bbfabd462cd6c143001e335aec1e1908b75db70de207ca975c901f29bdfdcbb2fe22980618c3bb528e3b361216d23f61e4dbe27d6c47b9652726663744ada24da4a569499efd97ca412eefd1bee5cada2535380dbd989ce9ddd40b49bf25074e6d1c1bd8f7d3a9eb8a2770dfb8aded51ff2da6905c237e6f63bad867c4d3b4bd3be1df5f251536586bf1a886a969499dac491f724ade81bf29e6cb326ca9efe5501a21e4ad60f3e10ed9abe4252e98eaaa7fa3d01c4ce3706a13ed9a753f3f3dda972159d9a474d94e5293a35c1af9886684d54fce5a74849b7cb90a9f8c1ccc2c000b2fc8c2c99373faa2c45a7b86bdf43eeccc3dd1ac1b28f328e87cf6a55db39597502a0888d886cd60f254b8a58a37d4e99e4ceae37f240ea0d9f7bc7d9907be7bdf3fbd51fdc3c1dc5bffaa3b56035cc4fd903073b301f588b2863f61ee67b5e4e1a28e9a12863a7877622913b27f765cb40cd51f070154cc5140c0424817cb889cf122b7c58ad0a19887f580cc442204fc140df1740971bd2bb64c919cf6a1a08a25097ac66e904f593f91e9a5f1660d8addbd32db9811244c9f92f0ae0bbd5aa5ed2aae8ead8d122f1eea4673c5ba419681e0a2b824e3ad571cb239d9a6d27fbdc39055771e73b4aab42f9a158d37dbef7106bf8939f65cccc0f42eb0f96528a3ba9640121d6048167da087209774a28d8e81e9233ac8428334f85ccb953eadcb905b973e73f2a40edf4fc1f3c8fcd4ecd7335895abf2780f3717eb2b4e24ee68dd5aa23adea9e2777bedf7067cf233db7188f41bd80a57976223f53311e837a014bcc32d22abe9341467931b2d099bd35ee99d8a74519f3dd6dfb3394e84b6ec9926a9a0d8dc82c2663ab2f3d2878882665dcd09faa50be1f6a9f176be8e3bb3967cf79293fa4996fd09d310880f4fc89493aa39c2e305e7996fdd3dda18acb6f296ebcfd6ed4e7cf861f836de871530cbb397dc7765a1cbef241f84a7bc3efb78dd129a125773a316256c29b233a83f06d1b43320719b9508adcec1ce5f2e9132c84aab83037622164048b3b18b935376261879c8b9df23bf9edf4dc67b39ddbe846bdfb01a11b7711f7ddcc03e18b3d661f851f53eeb6cafdf3fe7136d6982baad7c06f7fb94050973b9079450fe9bf771d2743e47dab29ffa8cab71a4fabf7aec6dcf8ed8071bd90afbdfb6ef049e7be1bcce190ab92f223c8b421fdc61bdb186b7058e8629f12f4f40e4d2ecfecf431be65db1e661bf77d39987e5700b3475abf1b3162e480112346a7e2e9b11fdb3f1b0eb9a14874fad97cef445f147df7de7d5700f9c60fc8bcddbdfad97f95ded8c5dc185146a4e71dd8b38a7dbe06e10f01d9fb01900e2510696fb0cbcf0ba46fc8e3c82dbab99160d8a4f42894a6d9f99e97f57677fba897add666c89a5966523eccb28cc687d96796d93134d86998a6652c7f66b45c4d342c468bf44e0b46190cc61ac9524a2250cea800b347ce3ce62e9eb9a226e5b3456519565fba8ef2bb2b4acba29479ab98b30ceb97d317f685eb3bed19570104df2aae9575bc748ada5b54a728eacccccca176692a460f0e1011ad98716993b063b055f40a5c00c2a57f69556c8364d4a51b9077d7817d768ac6b34498350520dc2ec5a5a48b16af9765a90c4b5d796932b6c21557b3299a8a42937a5210026f9040115df25d77f9e844d6d518375b39068d9f0ef9ce082eb24ad27545e68db93287049de2c73adcf830bee1c61e910c42846820f8bdbbfcd5f9ea124938e95429cb6c96d9d68932b8c60f20f4d272cfa7a3b3f2f2d3f144f7637bf7af02e1fb75e7b7a85cd1eaba8ef5eda8b71b95d22d29d3e79e4ef9f445dde513d97a71b3872f50dd4ab1dd32d956c7ab442dd44242a6f30de5ce8d42f2b48a3b28c5729389a36b10ed6e5d35559577f547773f4a4888632a258cb9f27d257879f995aec25a84f3e796deb18f041fcacb296ef6ee8a365871bbcb779bd7a3021d4daba29c51693e2a80dd2711349e8f38d31a143046215281382359af978d38c32f29805823e5f233a24ae5f2444415e9f234d188a8325dde0f975fe30c09e4182e3f74d1baf2a238235b57dc6ef1109af77d530043177981b821778fad446733235a8533e4de90278833302cc367981b6a2ab86c52852f577ab126aabecbcba81a5dfe8b339eb43c2238baadeee1e8660f4721fb883272632228eccbd1bf9156b65ad3be1b7dbb734fe6f3cf4a416f590a6ad9470ae0ecee9f14406ec5254c42e9926190f5e63b101e7dbba9de64d9b78f44952fcdb22c1305e1fadb81f50757be5da453b7c1cc94811f3deb40259914a6be2625addaaaf8d9f8b5c9548a46ca98ce46dae317b95da479406ed23a5dc82f254b24f1a40ab9d3f2695528772e9faf7842e4be641471c94e93195e314b96ac022cc9564b0a7d5100bfb05bb78332d4854d832ed23a2d8318c41a11112ed83eb81c811a078d049f9e4256eee1269dea580a69bbc867d33b9d92b6a5b0d18102c83dad5ad2924758b1a6cf97408835ddf9bb3cabe28cba67ff6aef90efba4e7e417e3b53fdc1db8fbe61ebb8a05fc033b206977b071d041cf9879c5bba8d962c3923b3903d231b4a9f2ba9005ba6c474caf4eea38792c5f753027e4f00e5e30dbb2545f7cee2c85b6ab56a899357c85adc982b2d3749c5e899544ccf6554a95568e0991e5f8b8eca033887cb21b721e521ff41258c71437eb1143d03f660bcd33a5a4a8c4e991e4ad6e58b2e59ad3a227bb8464fc1437cb577a2e8148fb69bea123509216ec8426cdbc6dbe8fc2e126b44e79340ce488e43a617c9865ac986208a6ba83c4c5d2fa8542edcef2c150bf73baa7e3fd5ef2b32ee77af7ede39c5b64edf4d36449deaf795fad97088cfbba6a2d1492024d6a468f83db2140a15230d0a9581f12736b9a9ce548d8829f952a5892979522522ce8829f9942a8038840c1965c88bea1765c86b72461465e483b8528359b945ae7c9c71a3a6847c67b3877cbbcf09e0e8373837b153236be34f27e353be1e51467caa55143b7dab281660b85d7adee2f6c801e3c64e854b74b27ef7ea0a1820eb67bf1d99d6221ef7bb09222f1213685505de850c5979ef1a0e91d5ab2bc8c213e4dceefc35c0b3b2afd5b89a29f841afa65dcccacf1a7363d71873c89661479c817d2e86bd318b5dceb818633362a462fee25d4df68835f156a053d8bf1f30d4ee4e50185fad9a475a45df4ce9775ad5679e1b31f8f840acc18387c08edd03b1467bc83a60d0c5301ac9238c64b8fc211716cd70f96114c3c59af4d0628dbcec3385953212c421c19dd4093132c7711cc7711cc76d4c5973ca39e79c73ce3977368d1b6a1ec5982e462923b94ca8555088d4a9d3a9cee954730f670e36ef69db33ad53edc52e62be4117a60539936951c2128be1c6975813fba34cd3a96ed9337ec8b0a3878ebeeb1aa27a8bf1daf92839c3cc1365709f52cde7529af5e4000cb59e4bdf498c6ab45571490c407006147a41cdb0e2312efde4fe6cfa2de71e6abda273e916214c4a1f59057a30d145c46f5180e1e8277bfcc88a518b85b04a97f19372ce597a27bdac96d870317bc38f5748d4c30ed880a3e56e45c090a48401db9c53de90ceb77424f47f7979f6a14cef640dfb621b909dcf4e022041f7e573c7673a9fc4d7840a4ba110d6674b437cbcd4305372c3d27d48a04b3a5720ce9f8d9557f6b0613e673a4b473d3655be4cb46ae591e526694395bfb844ddc5a50dff17f3853fe7b1cfe6d8ecbc3cf652c3eda52b00b500952b80f8cb33eb827de7672ed3e69042584258576e8fc96c34bf48202032ee3c5176722f7d7e3a48e7abc4f02753c7524328ae89599aae239c97d83bcefb4cf3bc7926794d9f980d4f2669b22b3ff5e894a9aefc453dadacd85032d1030ea0e9372a701bdd65efb8fbb6c957ab509797d2be587e7ac752657fe7fac252e5f9fb5eacdc813acf3df13dc9af48b90365816cd66db3464c3e7e32bbfc909055ae00e73cd7f0e531df2a7f395a07e9b29b1e56b330bb134342ae182b0766e3cb61fcab211437e3b961e92fd6877ce9365a76a4bfa8f3c2a8210994dcd2636a2884754bef2167e6ca048465100824e2b51689e8f11305e11ca64ba2b6029817bf92edb103862425337e346a7511f11f11301cfd905cdc7553bee32aa594b2e3ae931ed334dc6cd4f19b8009c542b2a2d29b4c27138ac56482e9863aa14e68729df478ce01b482a464f4230330d458a41f528bb46476429dd0e8675ab181442663018277bb2425d85ff8be7c569e48746a368046cea43c46f0529a144b922d56ce50cbe43302386df44be53b475a60f9637ea4f904748abb2e012e1368798b15c23b88e2041b2d71009e784eacd39156bd3cfed4d32ad3a350ac7909ad6855d7201d8943c48b6eb7d5d1e5684777930188bab607f0abdeeda4f7524955982ae9a78a6ed73c656c2afaeecf8c2e9fd52349310390e443ea4902ce164aced096c7a7220a3ce5c41aec91d505451971cef91972a6e5f3d88fb489d30e209fbbbaacba3907301cfd6095479f5a21fd4e7e38fa620cd856a39f3e80de16205fce9694993e5206abf3355b3da44c94020c6978b64855f831495ce50c4ca9547ac1bd78f1a2c62bfa4a2e3ee2381084a9a71d29d38561d3b8edd58473f151ad5aaf9da8a4ec14b651cf3a44340200004002f313002030140c0785a2e1703ca009935a3b14000d97a85480521aa6399062ca18620c1000000000000000000404002c67845a7c68e91ddf2be554e9630ceecdf56e3f953178d8662103c2459293e263687db3fd50b4384b0c3e486a5ff73c1b5d68b3cb919b562d4cbb9b2c1782ee4f1da15affb6755808deb0b438397496516326fd44cd3105dee1f1722fd23b7673616a40f1b5da83ed2fafd602374004e3fdf1d4b9589492da877eb038d988c31efefe26c451bc14098096cc70ce2af97d81f541686cda7ebab2aa467eacc0e905f9f95fe313d528fa04ad370c2c8891bcda1f639db6975bf94f558f7735bada93e495ee6845b4cb36e9ebd1091084593779a780217aabb706c86dc0ddc9a63cf1e993d04979786c5ac7bf7bc3d65bf7d2a6b7b71a3ff189e4875723d850c797732a3d62f77a284f9b0fa632b21434658b7ebeb3c191934bec84f0ebf576071fa434f868e80c4a8dc02e68ed494432f8f6154a3ad64efeca931c4de88729af6a9a8db6606f3a7f0e1ec429d32abcac09d1ec0cefd449fdafe3e4290f874cd511e9e783d515ffd98785351c32b8efc20f0c3627891a1d3c972a9241e422e235433b761d0b52b74402608b0ce4cbd37918530b9276f8565f00a248906adf116c291051d392b47b1e081e0f3eecc45c9ee0582219584fe5b4f1e7ea81b021c79c8e8b18da978efd1b51cccdedc1e4b339c79ac176225f636489271c8d92544bce28de5eae13ec267fdf9f5758cd305e73f44d940be5d26502a068123bd221085a64cc786b990ae64389a7e00d2c726582490102618453450b8cf55fdc88b0bb5239746ecca7f3f0944a488f24045a2b19acbec0048e5b2586a2662c065effa36ade309ec6a69a3a53b253cf9a7a9bef4c4180ccf3a1f8aa7ca5874bec171ca394a1b3a8e7a4d638e45dafc0daa35037b86063aa06b1aa57bd763b11ae4f69280fcef007ab46e19e5eaf598e749b4dce6f055faefec1563e0d8b017fb56a7af9581ba9063fe77e7c5176f5bc1d00c4d7770b2aa08dfce2a91909c4580e96d957b1ae287b62f6d01a5e7b2c4f8f00d7b687dd735e0362b6bf77caf6e2e3c665059e6c9eb7ff5dda6598262f5a722501e31e6af0f27f97a11a35ef6500a0cc7f648f13049841a42a088c8b51185a589fc8256b05de7e1fe5861d2bf608cf517718c9a86b787c256714a5668ffea229b8e68b7829a7344aab08e1614cf99d294b43e177d679602103e786b0c40aa579ef329acbe50ead1f24b7487493a61407da6034be12b0e3b854c66edf242f73bcd1026b20ca19d7444c7b88eb2ff61d68c5c4fff6823b9e337214b0144eb0c3d80819413b2ad06044de19a5701e98a4b6fbff7d54065643cb8dff9c31b644b5669bc2824813caddc942cb87f888ec3a53551ac88adebd5d7b9db4fb3a63ef9ef66247fadc141062f0cd158c6f51705fc254f45cd4139442a44757893d15b8e866b04641b480c036c40bbd4b341cbe85fd0ad67c1f7e75434fa89d98288fc272c08c9fff8cb36ef960c4800785d2a094e1b55582d6823b177ec52a3f16f4ef059f8630f8b7ac54489619f7bc67218d9b1ad25cb80e6f6b360eb905822f58423f212dd1f16f0ef555d9d72483e953bec283c5db4ab493d862468499b3a25ed39688b291cd44dea07a4e2052aedfcbcbd4999363a71cddc0b2454bc1ca52202e68a15284373df6b371035c8d740fe6d0c345d8b455c6fc8928bda7d00752d881f86d5fa8a92c9c128e39015cf72fe56a5edecf012fb642df6f3e98ea9383ac952076e8fc9430a105d070c181de321273831a1f3b707effb65a669f19b322317b6e1af99e8316c50f64591b89476e6f2b6c6fe52290e68c5949e59a88f7d0ab70125a706b16295f7ba1f1ca6d55a42a3403cd03367050dbd03f4d4a99966ccbf65bb66bd5bb5bf8fdca39178af6c2d22622cfe030f510ed4499e7c8bdb26f4bbcbcd605d0204b59dc2d5c471d10b33cd7aa5a5ff3105284ec2061a3ebc3930f4b03c6b450a19bc67410f7dec2c59275b564d0da166dba3e2a7f76e497527a848c3846164efeed04868bbe24e351560f39620ae63059136b5fe7af9a0d983f306a890a6bb3f0a545c1830375f4f0ae4e3f650e28a6eda0ec6eab4d0054e57f529aac04dab4b68498b47f7bb8f71994b03b1f6f2b87edcc3fc63e7cfc7d1ed6d8c1bf2356598f462947852d3b22604d867cfcb80b2ac0520c45ba39208e1b53d4962a5c7696739ca5073d202d97e4edf94da60ddfbc50468de5c0b8f0b08d45bce2bf1f6ae4c8634cefc4489763751b5c442534f4a265ce5063b6755f1a47025ce8e1731e8b5d861ed4bc4992f4393e02d7b74727e4e75110d6ccca9e4c94b595ad23ba036c8ee8871f62ba894e74ffdadece724ea3db0b400f57ecbbb0ee15374936eefb783bcdd4b6878384b79e77e7a1fa8cc0d6ad52d9c79331c32542a50bacb275c25cd6d5b0150e60c27ee5aa9956001decdf5b45467a6c1e26dfb508e9cf2c8e02e156694555b19d2e441e4ebc9e5c1c9bc80d418c070020bdcc9fcde7a2d5d9318250651c1ab53a7f3da51a2a2bb0c45bd2cc86deec3c65376c19b0e6a6057c3f46deeeb3d3300fc6d707a9406f64e2867435a3df51361f1916ce2ecd4100873c2e1e1a03996307209a322aeee9747685b24f7eef74c219777847c53c0cf966f10b3111ae35a409def734c82df78dc2e26fbb9df4bf4193b04fad988ec3f95e13c3b66940e4920badd10d6544d66823a88cc4181c0e3589d097bf196d2cebd6fbe917468e91a7410ec3c746a7cea3a16aad364eaedcd25f842ec5a2a0208cbd5d3918f3d01ecd22087b987d33f0c7ecf9eba893e798ed0e45b65c32b976920181fe801ef0c7d3de5ad69a6d0dae792620f71b952ecf8bcdf9b24a8a36e26139960ea53a66cafbcf6e23f1ef03298896e41485dd1452860395b7977af282605f779ffe4aaafb52325f54677ef215313213f95e2c72ca0b5362a84128f433bb22cd9786a126c438eae3591e7bc2a877be94a3634dec862814769a0ce71ba7bd83598b93164645d9d59f0ba3c59d63df45c8a5c9dbd308505c3e6204c117c5fd9e5946015441089e33198d270287c8c7a8c4a2dff8a587424ae7a03a59723abf74150fc2720c84973e89719820543196d65171e396e7e899a21136c0771ff945c946dcdcf576dfbb6db49165748e67101ccb5626ec23edb11e21fe4e2e7041cf8575b18f3b0906e5ebad8d16349adf85cc04ac01016a3a32721a280969d81395d9bd1f2d340dc795b4ee2102ff8ab013eacca3500c5551e189277cc4685a49f31fc0d9d632523313bc208b6d654a2b1d72c385feec14541179137aefe59ee6d62641f99d3572e4d223fc8dcd6366723e7411fe2a2d6f130e6376851843bd8442662e3cea843b9e280a35b35de79684977c16d739564c746968402995742bc6bceb00f24fef9c95bc8babbdf68b593778919d191684c4a90c83b0a192a4ea45b08ca53982259404d76584ebad407d75f03e9c07921188226d252689d1dbdee49bd1a16eff02ebd922d0361f9e9cdaf7c9c3f81bf69ba79a5fdca3f6e9792c2ba7a7a38fd6e66d8c44d5c0f017ec56055c32a19b5805572c5cd283bfd8a8b091a7164598a32fd03925a932b056861b495bd1e151398f4f4a6f7f358d2203445541b68f17e6aef3506cce7d5f7eff1459b0bfde638e007d45f985372073e78e25e3ccc380eda93705caef9d8051f36a66bc33766ec4580b609395774d18cc1cfa673c4c9bca262a1cff5f501a034267441ff13a9e8a2bd3753224d7865f5c1f7174f78dc742210e3a7b7e17efe611200e91d57ea17d8ff97b3a4b5569ba1f61ad6cdf9b8395deb85c4caf15b89a63b51407e39023b05cc90569e96c53ecb5c4e3e5285dbb3070e40b5706cfdcd5ee4cc4802bb7bddf2d126981ba0b66aa59426f4f1df681d6c0c08b9845666fae685e5b92310a3048fd2e5ac409956b95d99d33dc8ea8881fea8a673a646bbe9dc3e1887992e657f47d1b7c2acdcd38d6a664ed4f450534d860136c503c264fb3c52d25017c88dc2705001238443baa2374a07698ecbd35d3604beb132818f436f136b66756a24ad28319c2676379f96281e2fa9412c755b5a0c3f07f057ec5b82c60ac6112fa51d0f9779506146d71a0064130788ddd16d8d37d36aa2d63911bbfe3dab6f75b3b8417b1e1eb2467610bfa651cb34eb777c29fa8f11de2e57ad1a88eafd892e6e55d2c09bbd0979f3a76250ddfbe99b724e67f347cc73dcba5c1baef137d14e1e98c9a9b3006ac7ab4536d1551ffd899944076ddad95908437066002d1f1f4dcef7a3f4759ad3d7db7ce69f60a6092033c0a3878d5f89d9d1e78edb99d897bec011d8184208de33b769dd9d53660791d50784e6e9924ae2d8e8cebc840bd0078c136bb724ee672bba6bb2fcf448967f8a799e1f11794cde69a138f25aa5dc2a9ef88dc6c8d904f5e6fa2c7563fcd5ef9fc0d7e8d13c2762aafcbe90dc8d522e64e0ca50855f12a87481b0076e15a7eac5bd33858c56a84b8e88fc817455a1179b512cac8f9e1032b0685e2bc0b3dc4ed75bd1349107a93cc3bc3d9167b9115c21ee8469f771e6f8cd4ae6ced3b4769eab430c02db7bb6302c89cd3bca3935c471eef1332ce82025fb910873312c9fde1bb927538c4d0b25e76415ae464fbc473c389a9b7912f20b3e6bbb5270d2c5cc169ee2ec4b354d5078a02450b579475166b8955a389912725f3f5a729fb52560016d43c988a897d7dcbb8325a0031d5af54c4f0c3cf353e7ba5e25e10be32cddc6a3867801b1183d2dfcd4e08f6c336c1f61a334b37ab6b127cbe30ce6da5bc8695340c1a627f204cd0e0c878ee1388346519035393eafa148cfc9c6a981c34a6e765e447f1e6043988ed2af80855bd1a69af8f7019ebcf77c4ec1d13529d5577dcaf3d4cbc2af6b7447180ee621aceedc5c661097558983ec84ee8bd1b2674a016bba1f77264a0f008ddba0a2e040ad9675f5185b68594a22a6430bafce32b1965dae6184d7186da964c6de3510ba44677a8b611771033e20ab652de2699e6a8dd92ba0a29e7675ab23eb21d2cb392c62a2a70c4dfc837556b5e8b24c6572b64b54322fb7385c296cb9cc8688ccd873503fce96b6f93acbc93815ca8aa58402922a9879fbb445b6cee054c2219b5b1ccd8f5cac845a79684e1b5c844fda18534490138a9347036b42406d484245880601aa70e70103d1017086ee1e90d1444952cc2d2106fceda8c4ee7e198f602cef4f4a4e7f854dcb4862a928a4882759498b5b8723a5d4d964c5df8d42ba59c0ffbb23ec8b6aae68869cb88aeed82f041f58f0c46887f52507d142afc580ca8ba53374b0bd741d733363a013ab08e9ef46cc7f2bfbb0647061df3c0d98ee46f45ba865bb9f3f072375cbb0b3fec5d718b4724672722b2db51f61f10e33acc76765707dfbb20211858bebbbf2600d1c81889b197355db0850aad8b266c936ae79e9e512a77fe342b5041cce887acba1d3627e3bbaa16aa01b7cb04397cdc0273f2d126d7e22d1795ccd4912b6d4717e83840d69a4a90d8dfb19b760f3be3b0de15d716b74b30cbed555a4b6f07d2a3cc03b7b21f6e5fb4b7b123417e3837f0b7650707db87ee28f4c5998f544f2d16848f11618ceb7e369f7bf4f4a10d6644407af820242cc47c889f528a272fa8f5a2a4f241e4f89cf2d4874dd0ac071a6a8a005cfdc3dab1d2aaa957c924fe93ff5ce7cc3c4bc42cc541aeebc63416e0dbfd1309e6490acdfda3dee0c1cbff35c4d7ac0cef800be061c1519e22820b6167ea51a71e9399838fc740234f3c0d8328659f9727465248b385673cfc4d6c600413a71105c07ca5bc7e2f96ec300faabe1a7faa673bd91cde9ec9844e736774b812abfb4f2666d6628eaeab1bfbd793021df179b61d8e9ab1e768bc5d07feecf3fc0323ecf851897462c45b89677891f906788ef6e3052827f2fe99daf04b9d6b7d563ea2a72a0c362b9a344ec3affb543500e69ef7bd2dc02970996c7100cde739b765d1edfa01f5c59f92eae267e383fcc20fe671e9d173e1922750a52fccd3b7cde1ea66599f04c3c005426b18d95df08dd97a85df0cfb94eac9f3026b282bfd6fea17d3ed87cf5e50ac4ce32e3c8658f44ecf4d23e747d50af8f41686508ccea276db4585d8550c60b2b2266271277da92aca012c96867147a2344b59b8aef54a3afd5d73ae97e5730334ceae2aa404d85a855c825097a7f73a14394afd877313a08dc05631b0c18fc9f74cd981c6e0b3ae1726f0f0ca347bcf766179dc3535e763f7d67f7c6b075a7ec7c1454fb38c11035221e9fafe68eb0cbc3c6487c956d9294d1db5f92fcfe3ec48bdda1c4e6186852456fbab4381356f9e24b14626079dd26cad9eee1985ec83c7b71235e973708b3527706c5a9d0a55ae08f17ce4dc3c413acb955d5417118d1b0a1a2970e97a05a32ec2d6b99be14e1a007e0d6692994ee57cb17f61a72394a84020fe68e6059964891a9f3388906210c849a29b69ae7a56622c0c2b2f94f23529381a3f266b6277014650cb12c0f3a897ce42a324d35ba3e7e766620c02484214f0ab55bebd1c725c249f26ecee20aba980142dcc0dedf3a8353aac93b09719bfd5b641923f8046283bbb77bcc20d83c2195c79a7c1d9afa254d011abc4564cb622b177348ac2bbf0dff9b4472b97f8a082f962506d2ad017095ec9bd92faf0f5499380b3c05830ed323a7501fcd66cda0990f075c340d6aa24ffe468de4aa00e7bdb3b5094c203c1cb01bc03054a1cac1bed5c6147e362498472e829705058db17da094d19d039fb5e42a78a9575b606febe583f6183f3a6ce99638b8d3fcebe8b1c8f5ea4fbc86d3f077a990e346d3301d29bbb21eee2268f5e652c76afa7eada864a86e07335b8af2ce25ec0449d3390da7174951cf5bfa4b47f850be39eb6b8a1d2f5951a7e72ef1293b6618a24d1a27bf9538f6c2c85bc2b7ddfadb1b3f0c5add3d9b6d6f47116ab526dbbf5d0fcbbdf1028ed4e9b8ef6511057077a6b093baad931ce0a7fa4e0df9b29a29292d5f7a39da1cd9125b527ff04e531441ea906c90ebc8ac4395087e2063b4ac4b588e41d64a348943f38b6cd26e53ef7fe79fbccd1b040d73994115206e21431ab480e259a734d7de38903f845e41b5edc7633eaa7cc8e8bf0cfc29040a663e9c3f69190f8b3e96f996d68b03ea8797d64675d7b2cd8db2e901e96e5c341cb0fd374f4f1efe7eeda0989d16b093421aee990212300c531bec7d2f4cbc2ea1ca39a39552e3680fb90efcdd75ffdfae02ab5879d47d838dc1e6a8b55050841df817ece31ed3feab680c19bee7a836d70dfc16ad0028b5376fc2fa2aceda74ab0e4ca12f168e87bc112bd0c55058368e179b0a8b480f8af246e8fbadd76a66b6f6b7599ecf65cc834c2eae2a6630487ca5f1c13f63b0d000a957014183f557c8c17003415e49dbd05da76d02db069c32472b63b6f9f98468dfb113e25d7add1fd957fe1eb59c57f797591956eb0d4c17c88abadb804949d0185f28cd8e58a039b74ac988079d893034c4ad2a83c170e518f1a818b538a086d0714f7a26847ae785f9f75656bc6431af2ee81d6c7b942d88dd5917fd93eaf777c4f936aa99993f2c84cc752b08996575de89c05a1e7211e05685ce4976ddf041417b11a11cab8433c4637d0328819e1960a68261bcba46cdc5298a40fda6320577281de02588463f52b866ea80a20236ae82a6444a59d116b13345ace26ac018eddb640172af2c3188e869f390c1c05a1d272f8a07e230721913b3c4c896910ec3a2c48abad00e08db9f7addc1be04d965e88b66d4697504b1db6cd95e02225092b682394229ef99791915a1a2dcbde741c398b9be4f6a987db604bfae8a1bef20d0d20df453a54ca893bc14abe31126125cffd867b3700ebf163d57e40dcccc4107d9018d16b155785895e8ffce0cd127504e4b89423f7777cf95cd274273fff283e9026c2953ea050ee4999bb86337b6d631bc8aa2829ce8c8cfad1654705ade1c46a2735ae033c20ac9a351a03b802f0f8dda4a5a9155e71be0cb0c401457200ce599cb32e19b828ed544c9a31d918c46f97e9ae1e3d8a7984e6ca77397a6d984bf68fc8666a922b49304ceecff9646268011d353017840b32eddb493879f0a94a58fd74f8a2cea06f34e36d7ee4b6b92cd64d41959e0928fdc7d328084acbf2fffd48a906da456bb2576b9e4ff88ec9d30847e93bcd2f8ef143db3c9f55d28fd588d6b6ba877a90ad268247ac3e3f97d6c3bc0ba06c8935e01fadeb887024c89b133687ae0af77484b4171f0f9c13efcfca9c91d3b21933a19f6c1096a4db34f5dc828ad9360f58bd35fdd1c736c0ca1c1339e4df6c1ef094c1fa579b85ffab20e43bc64b588f6bb0821721508dfbc7aef34f1900fc537ec7b1dcc6088bf13c7c2adbcd84fd64495be5a5456326dd7c782288824ec1de1f67a54aa6da8a1b38a4050e7151f6f487846338560cf5a2f99e4ff85e63cf659fe6f79aca16987bd4c8bea4ddde7b97d42030a040e24e4cb4af7471de103bd4af8277d1997294733b132235b18d6808ae674d3844c729fa831505af65d6bea4e8325b951c238b6f33976724c03477864bdd2bcc911e91522ddf08d7c5b125d7b83997235452126fa99f1a2a1e624c4e75fc87de0f5adc21a284a2e58ab92b26b5ba99c8f9cf650d9ab9ecc1e422b82ea1c606232bca86cfd476903a153584665386e20a4e7c6aab9a8df97c0e96162b688f00f63d91581c8f164b75505cd2921af2cda47ac3d69c977a98279efb5c05e7fa8328ecef9c0530982da3fb548ef7e2c02c3ca1897bc98728c07fde2992c86a95d817e25153a0f86b099f10c07674150d41ea6b520f9a9785bfc689478a71447a51435a22c458409c8e92b0fc3f04608a1909367c1ade95f20ac895cb6236f62624b696e8381c8e6dfd95bbf54afb4025dc6c2f9f86b0f591afa92deda7481272d68449f1c2f36fa75a002491a42510852bae952fa72745e88657ecc101886d26a2e19d10c5423fead8b6f4976bac7c571c39443e7b05fe765a61c261df5dc2a2fe209a09b55cc20a634446701147f6680514b8dea71cd057ea4209fd7fb21d1e6e41fa03b7ef95c38f0eed5db03ed3bb8332edf91ad732b52b4873f3755516f665a98fe8237891d073ec23d2ffe157440fd077dc1bce529019665a2b46f521a1fa412d90b1a285faf102e21e9929154b784d97d7192a4b9fb94a38005d353555fbf8234cc3bda26bb5635f8e418befc596b3e470f37c333aa0f0d57c92abdc14ffa93d101f77a8610ddff141a817ff1c57b1df3f9340f4149d9d2869a231d13a9d5226bab405a7caff2f6c1371202342da48929c4919bf5951364cd470e3c18982b8fa4d739eca065e03a95fadcd762ce82ed15babfba74c8eb69ba397b7695ff78ec5fd26eed199671457b95fda321d11a54aa40d1f54d22a02ac4a0a9e1002e2a58384130bb264708b72d748efacc612ea8d49556c4a3d096c1832ab2b036f5a8e2140860161c299c834e95892f69a04b3fa44c2cc843addcbea48480aeb96a7ae6c7429e6485a210cfdb95b18e88f29708feaeb152f59f59d36aa713368e66cdb8460c2e4eea68963c46d49e978c9f589607824091383d106027dffebe52f58d66e6ed739707f6c518a93c508c1485f12bdca72af656d6066c574f938882ca17deb56508a8aa90d603429eb2384e863875dcf7537fb90f665dce370d36310352bbf79b656a6c739de5d5bd4cc13830042c5086b13995715b9add435b3d4a090275472d3b4418c4a4ae5215eb1dac52c3458a5289061c806747a329a0d18b7cb2fe8f680c859fcd08323cdb81c3144f70a24a9e01b49419a2f845254bbfdd3b99de0cee3bf5a35679b625aac9198d37dd705b0ad9a80747bc408a4d90829b4691ca708a67d27e45c465e09a2cc81def065448733340a2c9b76b2798f237d4b88cbe12dfc8061c879e58c7a7179cda80bdc9e51bfe2a53e4dd0b39381085ef00fa1ec58f556690ad853b10591b8cd4b9b1bd17f47ecc5eddee78db1f5df3d2aff786bd2768a27cb50920735c89d2376f3e8209fc97350179b86ab21e7a8a1a057a7292f7b373320e21343c8b00b40a371487141d026e58fa094885f1556d265666eae85600f647b8c1a8318a570c5da53fffd59d1cf968d38e515a26ddf4ad36553e3699df5e4a025d4e4f94bfad4f2637915316d5c0548f2011d359145163b2efa7beec4ea27cc6847afcebd4993367a1955c8cf8bd4a2fd53e7e957b094a7ad4d13648e1a6015a280814fd300433a4ab22454a416bda49ac6d27d9c8d4c940fcf09c0440959a2edb94505b802986c573549abc774cae705ca5c206e0c83a4710d0bda3437826d521cbb27eb5b13c6f1349b3cd6d3ebfd0858f25c920db7bc3e3abd6d0c207a36c0f2234818976949552066c8cddb6c0774aed06733ea08512b560b77771b2c09a81ee9409c7fb4851ca0624d7d08be27c9992cda5bddd0c705d206b456ed7b5f379bfbe1dedce3ed5ae732bae6f9075a8af135a58ca6971473b0d77129c9c47888916218ed34356e866d0fe436e621d863876a255d6ab7c5acca39653a028d94c1a83c5900f5466c2d7d692d43fd2deb66159751bb99dd1561a8292ca50578de4693c0f3c6373840895e5243b93d2ccf90af6ecdfa97cde2f4d9180a32c9758b5ae637f99d62d249310c2c201e0da23f604ba66fcbb87856c31a1904f743649efa0280b4cdd6e0f8e3490210f18655f726fa77447a13aa6ed7d4b702ce1f1a77409efd07c455249bbf1f1271560885a750d4bdad32d6bd9abf9c0a94c6b8f74014e6139ab3ffa8b685583a2fc697cfddcb3c2b52875e5bf4a5d7c7d3329aafbb994cfb5df03c64371e682b6fc3741c22bf025e4073a0688f55b7b1ee0d8c5b5ef2e5bcc3797ddb2bac31f80e9286cae4c3302193fe43167c580a291e28f5a1140c0dbe8e0771fca694f63c53a3622617f6fe492d6281ae6260bdd894b048e98ed60735fb5e7bb44542a938df6f69cde0766dbeeee0d94f52183344533eabba5918b18aad0b99202726f8df5db9815de1ab4bceae4663664adb5c7f8b7703bf0d35fb71c6e939c818d33072b88bb17c66a52f3250aad97690ed6024cd55746ab8cbceb0ca2837a686d347afbf6fd1ed966e372d7118078a1a18b72435c32c5490e08fb41d9bd5fe33ea55bad0b9b825f1b5fc25a733af938ffc3b971cbc5ba829e68e3cf65130e11fc8a36c6f49a6f48e2753bde714352426f02a0996dce3816e26a918ad4ee20c1b6037bac14bfd850c4744ed4682f498b05985ffaed0d6d0021697e49a08d4b38bae6e585e2fa8348f0de8f722e93da8303f4c07b64ff253e00fdcbd8bd00687f18828c9753461afab249f46258c2ba8bb5cd0d60ea5d6cb726f4bf6fb6c7b440b404a06ff0746a2d98503ad75c834e4d5f296c04c4b2e084139ef6c61992afcbbac20ad0081c8f6faa8ba9e1bb70b3214f3c1fde90b15924011e59711a55c3f354992fe684b8ab31d01a2350c41a8d3a4924ca7ee406d5971d5ef87dc3c4a73be78d235ffde3413ddc5f6cdc72e876c6e6c4828bb9a24c9d7a2079de675a9449a340b7949d988c270240a35078b007901786e04607276748e1df721adc2ddae180f10b3d005a2cc948c9f99798cf1545e05955362a0ab73d3835b78e5531308bc4460c65a71747b781dc419938e59214aac88fd0f0cd6bd3a9a45f8b9c87d4d3a1bdf1bc8bfbe79636cd59791b9028bdc6ca0ad15a4efde59b99d68c4c6c5d045ea1cb0019638c321fdbaefa44dc27bda50a48139aba5fa7bdc7d9fbd38a086729f2213ac94499ad81cf6ab3cd3c0b1414a37ea1fcef5c3f6c6a673ffacd88a37ba4f54aab011f54849ce677dbe4cd4e31d54d4bec3f163464d12eb1571d3977b5b5f98925e01a8da979b54d44f7e0875446e61283b599c74b75b579b42f085d9f334443faa1a42e8ba80b409bf1a0ce8f44f991847fc72e9968c1c3186a9470a4d9bca18cf7d334a85660416d6a156ddb5f23a1ad764d35740b19824afbe9d854fcea56d93b905df4edc1e6303d8b70ae0c566a402428b430a8a8dac37492050c6098b95c226d080d9574f62c6a4dbb170e24a79b0371ea9c8bf92035f50555aa41f788d55df98076955656250620a3154365a355ead2890e702ec16211ceec94c18391c758f3cc8b97bdb38aeb425375a2ec89d6aa46f74249efd1d89fdb583d11a032ca202b280d1034f6e55cf9ae2339b034f76e4ab7416ab51e13878ff978d6d0d8aa1639031543f36f83f673e5a52a0995f00eabf91751a6e327170c009b785806f5929a752b54e6f916daf685dbad32c79c6d96ca2065f041927e99836da18f794233a733c04108a28e45faf9398c5e66f1ba829200bce3960b082fc31595d26ee6d7e447209ab54ff8327a0153098cd62a415b040ad3d1fd476e1375927508c924f6b9ac1a2cabe9c43f540194f27d59dbe20180c29fa250f06b811c70ccd591d5380c10a8954bba2e1788c78b480b2ab36a673f0b8fbbb40ec207f6bbfcd10f6265c150083d178bd61e8e1a9722ec79b8d7b3ef4f74f2fbd99f67ad126cb08ac3d25d0ee4fad278c129252869d068427d0d3cf679409390a78ec7d41622e6f693696662857b09356b88dbe83cb8a6a58492994137b544e36f761f5a4a2761f430709a81bb6f92e6ff11f90b47026ce9e3c6d29d4f8f0ca8dfb0f264037c72bea415960c8540089c8cd861f64d64938f9b7b0113853e47db768ff752866e61c413a1469620c6308061073141d1ad8f953313d144057fbd6364567da7c32060a8f0fedee67290364b05441c0d2839b6566d4fd0f0a92567e3fac0f457e03e809c0d4adb454bc9703cc9b983b538df11e0a832cc65858b8badc7cecde86952489b2400710a3951c32a831ec008ffe182affc86e4d6f29040fb8eb31feccf6d8038695b6f28d6941643e5c360336de1f5fde96c6a17a37f511766b785e04fe55b185a7c463ff0c7dccae33b01d02d2f80cadcf88942fb232cd3c3f397dfacd75149d0bba89b1460475c1c144722b436e0c43ccb0aaf166ce09f1a6a6e9ff9c977c5e7103c67b14f0bd96735904852caa87fa9f0abc3941ffc13e5a5969ecaccb6161f5087a29e109ac70cc17282dacc438abb5339a0ca8ac6215cda2f1142913312112948b17cfbe7fe6d3ff0e5abd6852485d4863386a2552b376126e3527d2a381ee03d7c151af628904bb04f4a462218be3a4c2986ae923f33a8125d5c8e4e024fd7407bf39585e9f8868b17fa784e50dab0a47614394c3536802149e1109be143063902884c290667a5ea4f204f430e44bcdae6c0ddf511f54837f619cb46384d807241cea5a0c0c52883a250d8313f63191e8c0a9c76c7f104a3fc1917b6d5b44c3e52340f11e84691f88eb31ce822d4fdf382223d0daf2b1ef3062c4ad44ff236faf0e9546c1ddf841a1a8be04ce45f80d00d86bd8410799122e3d77cd5a82d58e2d09234af517f27c5a0fab7fc2ca85733854f9b508994cf41dc1e3c086002aa83c31f505613c1619a2b895569043cfd85038197281934ec838c9c960f1f509505f63920742cd0a701a4f058fa4beae8f65287bf24f60ae445916ddd3ef395c3de172f6aed5b0378c9721255d60e8f7a906c396d02a8b22cd3b04c1c5c97b76e12abecc8828f3508c9a49a3ae0dd6ad8f48d1438093388cae546047a3f373f390bb40a2d3dabd9c36cf8401c46afc281d7549328a6b3ea470a70c25137e7d6e02c18025d9a9562b1e35e994dfdde7df5f9dfafa1d104adfd70abc6ae9a511c0ac83e2963b6c7da07fa699102cfdb4c9bee09725e07d537c386bee196047b7b80be2a50a066349a39c6a50e3030fb145d0f56d3dff7e5dd662ad1e4451aad5e6c298c83c5e635ae59d91ccb0c1085940bf330a9e911ca303a5cf1a2ed2713a15feafb4275129d5a787db5385af97fc86184e69e529da3ce7ab90bb70f141874721c4d2447963898e83b923d92a759c5d62215b4fbbc43696624fdaf54aed18aca3428edd19c2ee47c0e0264538a26e544956b315ea252e0941f9a46d0ecc561331d3bb016aa72dbbe71ac4141c5ba3760b894fcde54d86ef8cc01c0a48801fa3a29a206df9d89e43c01f6ad866a110e52394197d0c6d204d22f109a10021520080cfff2289e38403a84fc363d40287bc9fae72f8802de6aafd4acc29442f4e3127c7a94a36113dc29d0022487a221331acbea12cad0e77480aa803b6f6b44b51b4c1bd441b76690a40c11cf3246e7228754d21ea7323ba4cdf3884cb68d5689647498c1e0b1201d2c1c7bbff9d8a70ded02bb2f378f1d16f78286ceb7b0daea8b2a7d60d0a3a748ae1847cb573545d3cb24b0e3cb824ca834ab6841c4150fce4c41bb9dd9194254b1c13ce7083bf6961575ceb531b43b7bbe336f8a64f4c6dcc0cd57779b50a3820732bdd69ecbc2cb7816b65a0d8b86766542c573aafd010f49c6e1cf32945dbc4abf397e17049209079089087fc308d5cfa81c607205f67c2f461a23614e08ca654b6c2b10cb91b73c46692920121eb8f0ced05720f379715244a707f448bc7d67506017402205fd3deb7932c720e67d6308c55a171b11dc1873a216778739bde502346b9317a89252cdaea0f27de23dad56f5a218e5b90121836d5ef5692d1eb7fde0c6d82d215402027990d3199bc695fb0cc69c85606784b1e3793fb54f4c0e242248635a20614f5ed8fefcfd43eaec1476203016fb8e61a692a2917333db5888de137a0ca092d792942573dd55c115b345c1c672f37c01e9f244ce400c72618c3251f3beeb793d8cfa388f76c4e7714094ce857436ac90131dac1dda12b46e7251c0c194500e055009d9020a3e3bc00b98302798387da4b80f4f92d13b7e7c3b2c5001a83b9fab08297a6b12a93e7b5b410627274224224896552c11520b6c83006aa26d4b039a6b3f8f6652b831e299b7bd50d895814d4f6c7a118130fb8d127e1628509694b71d199e05682cad2508abd6bd22220759c9e40ed3de05711689bd21864ca77ceaf00ba9763b99318194ab0cd816169537d879889c956fb6809e1001bfbd2965c191acc4eb2f4d555b76939f9128239b4f284bfa63a3ebbbae2842fbbff7be60702ab667a535e892b39e982ab9b3a7ad1fbc4a92b141563d59043f4a7689b43a048df5deb9ab2b6d67788f29417524151e48cacc65297628922c5829ad3f43206188b2e1247175f2c3ff6e712cd01e10ddf47e071d49389786c6b0d86f6dfa15ca443e0302cb7bd3243bc84ca628193e704831fed4ae42f17a17263874640d7ff141fd7f721a16b223c075873858b2b1a3ec80f07472385b9447b891c51e1bf6f646a31be25eaf7cf735f8ca526f0ede0f337606288caa62b92084c15f14c2c0722ab443ab9087c3013aa00bc5b0343d9ce904dd3e58e1059017bfb81ee33250c259e0b57cb0b5f49cb11db0506785edf0a6fff4e32b526ca6ddd70ea7fec14e55dc920f12840c94de4a4bfb4928f7751a9ddcfc0164e7163a5e07f28b83a767d9bdbfa80b8485464b0466d95e44bb7f618621b74d6b889e8b0ebcba4c03d3a539c02e596f682581264fb81980566182800c9fd84127c730fa175ba6eabab033280c37888eb1206a031070047d28f0a058084c9e6cd93f05f648582228fd80c276a48771bab0a72e048487f51402f3a30baa904ce9f4f658593394322e9ff4a6dd3b91c22dc3abbd65e2459bd1e2b328a0b92dab6286b6e8ae643f413c2443d40f1e910a6f9c59890aa54f0c47c45b1daae8f225e7f20122e232469a8f61809b59b3335129ff4fcfb4389fafccdfc978c79ed5ac77eb587355a62f7fc9603e4e921b403f4c485477f0358b660cef7139babac7adfd08824f279ec117ac41abfedeef530ba132f52d5e972bba0f8121555791ef1add111203e909015838cd1b1610403c36dab0146c6d76760c089642215811d2b6e234a8d3366400c89f24b7654abd948d142a51ac993f383078eb86071bb468e739e6c4a9f03130690345b98387919855dcab92ac32fa155387914f1949b802a022e1ec81b3d705688cf7cec0f9016bf72bc92619b24e5caf5bc32b15fa30a026ea0a22c700ae6813d064a6a8d2ac5375832164805a5f8d6028f4cc3f2ca6049b447a3943c80ae0049448e2554a2c23700352c0dce88967bd3160505583010091664f54605ef8f01d015ea20a5a7b36307d0032fb1126887aba9e80fc4b87bebc5b960cc14783bca43604cbbd806506b30153eb388233807a94a058a29dd2501b88aaf1c9d25b0aaf8fc9d8c310901cba6e6a40a4da9a2058df67968d38f80e3891024e4bc6021c84c71c2228f993495c5878181f5b4c7efedba56e080c58eb1e49c0c3e1b9523bc11d631d6f60ddf422d9a8b372c8f6cec4f55745b5cde2b2bb9f5690e8b66b313637831133863d4fe61585a34771aea4793bff8181b9cfca01f20427d5cc965b9e1055381ecb801b05506c836e148bfefa01908a3471e8cd8dfaa4903da0dad2b8ef53a2e73ded14a5153a1bfcacb4a0efede5b5dbf89a356e03f714d17e18f8dabbf743dc8e429243fbf8775454b1f568636cb1fc3a4c27a332696455e2c808a4af252a80406b15f88718f9b4cdb26f7d7c87302e7c520aa6ab296ca9bbf03f38cae5b3344efab0034aaa1afd36c1b50b6286861d6d641f13bc0bb8a2cfc4e7374ca32fd7768ce1d32b0a0e7c79b32e114525794843142e616b465a2319798b8b45c10d23f94b234fbae0ee527c70a29ac4db65ea4004ee5eaa601026be4941bf0bfe758cca11c2084d5bb83d4ebc04221dd2ab6d48bebc8af65e5d03746fa86962ac2cd38af5cf9feb138ac36291ea8228c0c4a4d595f91c796c6511aa8f70c126a7cc9f72744aaf13e3fa029bccfd798a54b415a399677899febe471cd6e733d86c9537f331e9073b0e2fee030838194ce342105200ccdc55367d726dac8ad25ee5aaf3db2ef2573825929017071b12e49603651a73b80824b2e23893c8a18cfd7569d69fd6c90593450ea07d3503430804c5e4cc22959d0d4b05c16ac858ae290f48aa4b9df5c5f5c880a46aa8ae727cc33556ba0dec1eec226a3e3c6785a08713b7a49c0f10be7f0e37d448f00c8fc234527bb6bc5de84adb7ca236698062fd191df7a44556dacd778fa98ffdae73cfc9a89351f0b8222edea4c586d68e0412728c3649fb22d73a0c80b018f8e4977e75df58084154169bd77a5feaca03a60d32b94aec91c2a0a66e9641820099d70901bf6801cff2dbbc3ffd6f3134ec2770977549081c9852639be378cd87bafa3e1334345967afa224e5e0955462745352ee549a82589c7a00a33c7c83234031394544faadb9acf6854575daaf079c4ff5eb2321a852c02470a4d9ff7c0ce6d3f07cb746402761f2d77e61dbf4de7b7f6843aca5ed1c128a38089046ddeab29013427868557ec09b4e0c2e89dc0af7a19b303e0ecec252c6f507afc4f896fe2e76df948ac7bb0b4dc046ed717d321f2c333e086c0cf3a8ac66d6868e6a5847e66baefaf8270a02be93407b4dfb469d48e78ac4d037860b43ffde789c29b4df6eb6b2a4c221c5a6533a07599efde572afe43016e2ba61bd905629c099632b37c1bca7a420f58fe5b6b5bdea3a9505fe5deeb0a77dea0817707e85ca27194a4938026ee93dd96e467934bc9e3a8905dceab96b70a48ae39869b2a6e2d44e509aa20bbd8a160c7d822aff2aa6f0eb3cef9e36b1f6e1309c830183dacc42cf8f263768ca9f858697c5a266e14d4894a83daaa89fb60d743a5873dfce6e1ba32a3371e385d028ef80f926ba065afe82ac32f6070e9c7b2d22ce1a110ae508c31b30d05ecec0903221b5c9137cf1ec48d66d01deeaf24538c22eb44011df399522890eba0dc1c5a0b52c4a1a7015d8e7a1adb63dbfb40c8b1d414062bbcf80162aad4a0ad439d2fdd7958b51ce94616ca8947409ab417a2423e154162d545ef145d63086855772453c80760f3f72834b3fd74e6398bdb091219df2c89cbe60f309b77c0b3dac519b2de41fd5b9db79a6dbc01a9b472c3355b54894ab9cddf9b9a14a7e9d46e5aec61e2dae4f199dca997362539fc7c7c5ab0289f7001de8fa673de807ec1da630f4f6f67321dae445eaad3f00667b7695cd3dca9222b0284dca94608e928d72eee3a7df016d6432b749478a70f55b514a2cd7c4aef472b8c3c6beaf5e372c10ffb7afa303b5f0c77387a01d6c3cf65c95a4290b397ee89670b76ce062290bf85e01c7742508f5b65d92f18382d6ca48928c241a92c00d16893cbb02974186184cab8917ca0471815f5609e75461c80cb76f60b38a88d785d717ea8e99f5257045b6406414bb1644c8822dcc0decf027566b5bd26c5f232d40675406af35850f983e554b3839df0b0b9fabed49d842938a2155305dc8c0db574dcd79481f797630c585286e579458d6f690cf169914267186063e46449c0b5db923d3ca14f5483cf35663968bc1865b34e43a923d29b71d84bb55ae14d4d2266ff0f2b382f922dde8eaa1570ec0dc87914346138580c4baee63b2581f4e22b043d41464eb37ede7ddafa92dcdb9de8c2ef9d9041d807cde78befd69eb545018c9c0e7bc7a08bd291dfba3a45068887303eff695a3eb30efd6132d5dcd66cdd9a03d5052030984088283a4f5110bade028c4b5dd39cf54fcfcd84939e58a92aa2c1d004045fb851f9ee701662330ab6cdf5abbff74c79384593d14557896c9054d43ca4517402b3042b4c2f2293fd1fd953401695eb8bf5213abcad83bd05f5853f10735bcd455d7343c0364a31dd3a0e41f3a5fbcaf8df5b492529fd3c8f959ebe24aa7162200ab92dbab1d377c9d60a698b5fcf8559ac75d9374826bb9e12bde5aaca7216c09e16cfb103c8ab57b9fa0e516ebf84df517260aab86efd53f2607baedba5279cc89ccd7676c9fd4ab6e728c768da0e034f9eb99e5263e85261172ec87dec4cb9617226f52c38443cf9e0f7f6bb81ff8f3dfe0bd92aaca084d298e95a5b74193af99baece3ae0b438bcc70bebfbfc6f73f1620e39d5380cdcfb8c4be020fc2ad4c37a2ef062cc5b5793a111f39df18e0b7d4cb0646e69c650d7309758257c07355594b9829b2f7ad819a5d32641aa0c9c4997e63e8938872749fa8a7f34978d33bfefff85784f92f4668f61180b6bd463212c560dd82f89fa43c481e0709f1449e4c6e7ef2b1ebcf693c4e5b581f5ea705811295ff3bf950b8aacbbd2eaa040271df449e60dc3a55cc1c993f479ffd741d4c33ded1bb6450d90bd2b560a0dd6ba0a2c0b7b34d2c468dba6b531bfe4048899098a4b0a52f03fe529d4e76c93f239df9120131d5c7a1dd0280248e9e0aaa6e49034861ee0e08d2303ef450aa0064a45f37c332d4563c87a5da3471876ad07499baaabc72fe4d29db2d2224aabb851e9f2ddca6f9056ec2db6085d23b1e4be1b577b809442ed2cbdc14c803d5d5c3352f34cf4aa45f863bc958393e7840d163756a5b1c83e636351f914571934fb57fbf6de78d155f2401d2b595e76cb0b86bfc60bb6b09c0d6285da8b53fefa405997a69f01eb7d1a1bf9175f450abf8b7fc8cb3b520c998204000521454a11aa78fa8985b1c3a1a6979ac977e6ed4fd88c936d4ee2c52bca1f6181b8d3befe0f2a94871fb3d5172331cb5b232cd2533fb76c755e7f1c61df6fa364749f11613cbcbe88e72c592ef3f130fc05ded518355f6d0c525ff08e1bd80c21f2feb927ce400bad31958316fd47ca0f740a3447c9c24a2e710ba21f3a206dd92f3c8dbb0effbc3e8326f97dcf0a6e47bae1ffbc24eb0b6ab8654ce4bb20f62884d2cdb8fb997be13240257632860fe799a36e7dce6991c77e6fa326130d690960a2dd331d6c00880def9eb15d010dd6b2d1d75ced0994ab461fb1b7e94a0ce852f1c0a8144d0b65a44ed0f901805a1a2571153f388c73430844a26e8bad3921272a0dd1810021c852b06f59d041e56dda76a89eadd71208ab17c37db00adfef45551aa25a26e5415d94fd8dd56d7f842cfb1cb98cfbfb7fadce5f6fa0db2065bffef028909209c9a105bd861459dc831ee4d24bb1bc162b34ae6307f8b8fca3a77e43c2a66342777d5d27f1fc37624ac70dbf600a537bab5f84d49ff0b5ee47598edf94b8acb603c1ab6eebb23447150dac6d11c65ae4ea7889cda81763f3c195a4a4f62db03c67ace0b13b512092a0e733f271033547ce50d2417206355798ef9cd253cfe70c4d57cd1986ba19ce4b5ce1fdcde2915b2398e24b24fc3001a9f2c63dbcf6ec9fa839f14ad9833b8f948a7a0009e43d3072201c7794defa29a639a4d8fc763a18b23434a5b81de0b3a482c841d01c18717de699d37e4cbb22cdea1030ebbac26855375117a30ba50d876a032ffcb0c88ee33839ea0897d6183897be40b2a243f73572f4132f684e8672e11cc4b8e527975e2c26ec436a04c32eceb441c8639588382c9f14e3272f2e60c8dcd38d09a2aec028e2183bd18f959fdb2f670f9d04bbcafa728ac7cbc53c95ce1803b98f94a71d9fa6fb35874d29e29f334c4a7e3a685f55a2e3fae2d063f54bd315e4aaa6e9b4c5d36e4c9afe3366bb6f6cd71ddfa78fce7920ac15eaf53fbda9db05fd4bdaf4ac0693d33caaf372c79653841b356470aa2786fbdcbbd1ede9a38ffc8daa0ca7d752e04bd0fbe175ad1437ba87d4692d02c660a25390d3014b1845a429c4d2906584f250d16025bf1ec87cfa3cb1e14b7a601bbac5529f81045601ba618a42fd79b8549c43b1f6f5d3483f955812c04c1a01a580391d955fa4498b47da10199a1a558452f001168e37907d539d4844cb89f4aaca3951c75ef7de2257f6297b8362e75398ff3da0814b075448c35a60714ae13f2c6317bed343e498dbec8b52214ab5fab492e6ea85b058a2d3b496849e9a3b479dca289b4ea5d887ba09e925a3b11a98e2241175ea6d62d30ac3e7896cc0d0f4e5d11af4fa851f60d697a46de2c0e6f428c91ecab68646594fcd5c5ddbacd1d6c8a91d82f1e4d10ac607d52f06a1e4df18dbb0529998843663443634b9b3f483e741f7e1c541d22ad11f1ef1fa294927b22141a237b5c25b75aea57f48761135d6d30845711e0f7ed50bf22e7c6c11158736cf90a1306cbbf6847f4f9b37c7d0dbdaf81c777bef9c9b7b5f3054cc0cd77fdf9b2a4e1a457b287249a59ae26c733d226380ea5839129d57e43cc95091d431695d45d7bd185d18308946197844c8f08b0d56d1da31c8c499ecec5de229c97a593a27d0756276fb23e7944ee5897e2a14374cbe7cbde9e9420f59ae1c4b9f059f94d0d5be4a543a697b4d568b97a31cbb6539aac6744168b22bd0f788e61ed04606962ed88ce774ff1694a252c79c50e27c9e86f4eb1ed34628f79b4b3d22d24b096dc25230d861842c2593633304ad35aa8a92851d55ad28274aea14087cd4a5ad40b47b589f8e55888128e70151a45d280a59509413b1d12f5442f6c0e8429363610dc93e98f8e468b5d9e2360dae16df6e15f4cc39f37c4efeee97898be3095105b9f7f807a3770600c27f1ebf9f1323d77bd2ae1b5d6bd7e5f8f4ba99f607c9d05dc301c25f164cf3db74df7c2cc0f74f77d4ec60b2fe26acda30bd6475ab320096a908bcc3398c8d7a4ea4864d67f32137d57cf4a51723831d5f46f2c755706f0a2d76cc898c7aa37db1c04df07d0b037bb36943a822177d609a7b378b0c91cb17ad480db0827717fda52c68a567dcb937401777d62178b16bfc14ddafe83e45f751b4f06789720f346db025539462c341aaf4b498733ad60630ea61299dc20c6dbe71bd68f79182b567fb81bb5bc805c4194e147d78c17d03a55f368fe74d49c311a2e7b36a4b54cf066f5e71ff0e36c3c2a758714205de6f73d3f1fbef079def87fcfb53ce02170f3ae175f0d327db913fb8de90fc1263c101869603170d4aeb3b9dc3813fa98f383a10a2690a6a74f5571f94ee4a8d86a51bd288c0740f1a1d4d77e0794dfd31939918e474c6c74fbb5055430c4c7d7601f3200c0a75a5bb317638cf5f578f73f2929555ba8a5719412bfa1b6cfa3cc7f33b774477214ec93eb41388da6338fa4017bd38a127a686b44ffb763bd9a646d91403ebe534d4be81816a005be52883325226b232a18bb257a3472ad51be05650f064dbb3c10395746460bba9d6c8561b26388b946c4afc3e2c058e489e8a2d9eb1b642d8b427f46ed6e30ea86ed5157d624d98e6236d6cf5e1cb7a77dedb468f542e9d43defab48ebab0c78d1facfcfa632e51d48341f40637f4d2a1973e5b1feb90223b03afc8cac25e0c0783e8754be789e122447fd0a711316e174b8cf4a2f655e45a07bb4922ef246085093555beee6ddec06abf84ec7e01264cd89879d6851c219e0ea9e2ecd53a6254f4ca93aca70c6b5aba720e7a46924fe67332f91ddcbabc6d7bfd454fe51c5751de84610ee3eaad037cf4e667ca8d932d048f23392e7f3f0e052a9008d2c5cdc3cf2c3563def0adad2f1a447621f72a54d3af058166789652093f533d277acb27c3ac96b7f93ad777d21981fe899e465866f7f752938499860c82c9e408a270c81d673c7f90c2ea92fc165cdf4558e041fae8798d4ac5c4df8c4ddcdbbdb47d0124618dd356d9719d8561f33e8fef797c4fe0beff3d2d448f04923a41527e15b30c319193b74a7f63983d7d23e0e9cdc54939ad31ef6bed08fd2c3e80d0b9c88d05739babafd2471a80f1c47e241fb55ee777dc5f454a19863085faf76680a803ea07077344961160060eb92e876b066422a2f35fc5190dd8c4ca7a58af8014d1d9d3d1ce3785f86ef06152d0ddcd455b9dab8362e9e36abe9abb5ddeda1d6f08c42be2949eb475a05850713c447c16fac9a58dac2f262ae42d1c07199da1b36c5fe05799b745482295365a4fe5b851f971b9a3540a66f2d1f943ec2ba6964715db81b822ce70c273bd01b48976a4a626403020145cd7f3bf60ba134b04be876c3f260ec774175c8790f0b19f66f4a16121fbc7ce2e440810c5cbb5fd08f06496e80b4604f73f18761c36b7b020e8e9d1f814080585222653cdcea78121929ef2e18742a1b9581e0f7049187662693f6ae2fa28d811341e0bd49f2f9030abb083124d72b4cbbf8d5ebcbac459de574f37ec42ea2ec068dbd29a3b245ff3990cf2fa4bafe6a85273b201e58638263bba564233c8ac113f21ed56b1a893f15b4ac1e4800e16aa2ed67ecc52c55cdd84a2987fb18e2ecf7d524c4f61aadbf9e029fc6fe7c0c11db73c73249421743729a4f465ff3eac0653d6ba02d1cde55403d2dcbccaad4b31414f92fd9c73713c55d810274b3efc0c45ef791b4e73109daa4852709840cb2f03f3f991e1c6c75803e815e2757c7fafd06a6a58a3c158c48cf04aeaef0b594b6904c42cf3b968fe2ffa41240baf842f8020b58d41dba0a812ef57d0089d7b9496c4659a37381691633cb7eeee9de2e45c655d01d3289ab6832e1fef6010c99b4cb4f0c0aaf226b1e520592c77e094709cd2521dd455b5091fd096d22aac5d647d8ad65d7f4a1e894dd2a662106468cb4f707c258038333fe5f31ee3ab950c76380bd549ab7f0052f9d9ebfce81f1a6f4269609fddb6411ea5e7a5c8f69173ac5fb3377ea9da58197279d628f8011d9d6aba84fb9a9a4585f1e7c6ea3168e1eba3054f28814d3c3a18eb835ff62e58e5c6f671df27813587f9aa2f6dd8cdc121a8b10252b2f056086d5e1fe09ee47033f485230d2f123b2daa428b418a52be52ed882cbdcbabc9265d9d9548f78d968fb8e0563929902c2d5d198780a0913793ea669becc408ef754433d14bf3f76b178211e1a49e4c47ed7655f2b811b11177f7039d2ffafb3849a9285b3c96be6e67e2631ffd96d639e4bd68a5b5cfa104fced91c0149a3fab9b70edfa6000fbea5874b68b9c8c96c18c81b84968ec7c21a1294a55ffd11674b72cc593d2d43bf0d82575542312b82db9f68747a9c184481ff3afbe21ef8704bd2844a1cd9b673243f47e0471fc518c3c3af0e2550ae27fda4bd1bd2d21e5b9fd5724872ffc38043568516481451f6174522041014b1398160e4b5ecb90f24a2a9d0d63419f27907a57dae43cae8b0480cad66f0ef2baee9388a7ce59e30733649a125a546b2be306ab2e50ebc98124311bb09e3fd8ec0f4f5e0650ee42dd00a8a5e0ff83788d45494bb628ff5ad31d6c5d813ee33ab22ba34b076ad7125b11c11326f832a036d979ae0d132b3a715e570e827757b8be69525dbb6b5eacb7b5db0633099dbead81325bc6d694ea8fe5e8b233aa6301c1eddec0d337d7f736f6ca131a57b3f049c9a1bfd3fc393a051c0f3c5627bed36e50150d58a6cd2d3a183ba5466bb689ad9331c260030a774a2c447b5512655c409f50472f34c114218130d2317940228c76ad4c96e82a686044c2cf31de3e0497345c4d7238c50fe0d2848d407174c11dc201c30d8ac10f338928808907e2f61375965e7129b6e5751cfa683bc73e19bd14250d0aac7bd9b0e296bb08f7e49444132595224ca8d2f603ae462b36c0aa7f961a141e14416fc3c26185bd3a7d43d55fec34a5bf0ad212bd4e8b1b38564bdf09977d2d3cae10a2a9c4882f1846f49a0fd6b388d6a1a84e9248d889f840c34ac71011024cfef5456c5ee2babbca3d4e9db7e780136ce86e4501db0a2cc2c10dd6bfc92c350c79a99d72b798fb84b57ac67593dd9b1a8cf71bab00746262f00c3b9ae4e2e7232d29cc831c15198942e0e2f0669692145f2b8ec782f889b62710a923526dfdb3b1e88da9129ccfbba74f208d9836718dbe0b7c46773d9f65ef470027310a2d42920369a0b0a211aa62be10b85e76960f9340fea030e66a1c23d3a582db1c35b7ee86f118041f10de63b4dbcc830e9c7cea5586dcb8fa1bbf422d19d37ce30ca3c5815043ccd50fca572643069723c644edd75aa6e00ad2c7205d5d3b97581cd2ca2386ca9f3e289798ded04d694de8f65110c6ff151417545aa224090275e71bbdf560777153bc80f254e5123e540b15a28848f262e1239cd2f0d8dfccb5e6ae3bc0f23c3f2b726406ff5c64d899845fbd8e7ce38e2b7275c652b456b79bf1e5c67384049717e61a1d172709dfee8dd012444e54e72a30f648566562e0aae529cc5a5853577ae0c88d3968c51cb9ea20a9c8ebac2f0b76a568f561c9ad43aa26663291bc9fae6d4161123739243fa4e2d67e5ea0e36db4922189fcc1bb56bec157f355330ec1d2aa846b250aa451115cbbb713b71f57f1ff96c13822286320678221413959158bdf449925c84aceacec7b9d126f1f06b45137d7c9b9d8078c9737c86313b8610c543b9cd4a778a6e53ceedcada1911664c63a3c96347944a8d27c0e7e7edde5f2266d08b35874edadca64b6c7609aada0abedef3c0ddf7d2dd95be80a1dc805a6cad2e88d0c056b106772fb367bc956027cfb7f50c62bd1dffab46d71cb99c531f8c394e41721f1b38f185e5195b26ab49418bf45599897d89ce83afa297defa747afd7a2854b952beb852c751ba0feadf9bf7cb62b9f1f6569cf06edb50cc6079568de2daec36a4be9424c985d92ac9868248354a42c39db7f218ea152563010da97e87e63fda505a41d7e4d159bb72c0dfcd7ee9c364cf9858875e25bf4a3e493182df162843b4884023dbeba9dd80e577bd7dcbbdf63da9880835c96f0ac9e49c08907f63e52eebc1b63c248b4aee4aaafd9dd7f057041fe4cac4648e5ebfa4e09f73cc272bab0d057b1fffa6ea628952347a4e625bba11d8e514440935d6f5ba41d13399716ee65c562574d8e6a176533a87214657f463ee766b6f32d76aba2b531ddfae1434933bf2a2051069a776701b072c3ce083513de853f7f5edcd52b331c6cbfe8ba8dea86924e042353a08e30149057270662a782c48a6b3e0c16414b84b7ab88e13f9dd8c107de85aa4756e71b1b26c5f6c985a6a49f3bf37073645d345c488139b6a888ce3ad6017b383364fdfe793b17eb45cb6558bf97d51b31857f23254786e1d0c728407aa764d6f7c330b17dc07bcee5c4d2cd3654f19591c1cc9a54b4b80635d235dc105353e531d3852a4515695fbfe324f7b958b9d2de300a1a8d9e0c70147bddac8db64e4affbea53394f955b8e4df311ecd580fd7be413c81c558525a5256678e7c30de5f593585fff66200e16026e7b5fd0fd1c6c4f30fe600e6491db60c9137babab2f68af412548d5d35b25f6fd0f5f250e31095c17af51673d2b2d8491b20a472e673991afe620fad01f9f21c6cbfb3fdf208aa2ea69853ca1719ed5712678262a917a8d613315e290063a9b791d6e15b1ae6b4b53ec78fda00a27f4c87c13f0c7ed3cb079d122be08187a65e853b342369ea25a2c1709f27f12c51e27ca62c4310aae1e40600aac6e2ebe904f529f5f6821260988452646f7c9154ff7e2ab706bad22ab9b251f0446e3182ea523e0cde655cc9ba5970e201ec0cbf0222838eee534e25454b10e405fd4bbf26246b80a3e3e80a97ab16594e0392ac2ba2a8be835a0300221febcfca3dff0166a77edb0661e170cbebcd9370bb58f3567e6b3e835f559fe5cda3ec123a9b40a5c26211bbd58b3209b72448f3b037f104f3f88d72b2bce4b4260b29ef45b9e8f7ff6f63def9ec50fccf405b5d656efbabf8fe27eec9fadb03999e00480c3fad5a8b9c8b87fc28aeb86dc7a8bf54004c4e4b6f7105eece051f63f2682bfa8eb35c41c31354bcc6563121d2dfdd6a44acb05cb1658231ef0a24c55b49d6e801a91132d404fdae567bf52c5754b0b323f15e6d2f4e819346ae04482c2ff81565de24e06f89bb7886f26b5a1b0a4a95744a1e7ab185332c5c99a28764cb80a93997031e796da78abf5ede17372e8bf18e4fb51f509e84cf000adb3bbd763ad69db31c5cc3785b13f3e0d02f5ccaa42f7271416f5996a7de52f357e26b9f0486c669a5a7f0ee58fa19456f5349a557e7e47b58256f05e894b5ee7cce2469e4008b24520e7e43deb3f09eab7642079d640c515bfb1e9804b4c28883613dd94789197770f0245cd0ed775864d6c2747e9baac0f7ef1221ee7e9f624ae6a989e3f0404a504dbb37ab35607765a31b082260c64bd94184cf02766bd0a63eadd92d7cb0b311af2a3936cc4cceca1106349e8b5040dcd278fe55e359a6593b0fe9826c92fc161f5009a8cf56c43bcccf2f3e768211d285e6c669b89f8509e7e18f08a7afc700f7e2bd04fe7a9aa57bee9d0dce8141002f621e81c654a688ceab5127b45114a1ae093f05f7c2a05266226d1c10e3309bff82d916ca9f2c6b4f30cb0eb7c4176c1a913731be8e6744a01c1131d477dc1a412ba8dee4c493e48eec53e296788f37358e837a8d7968a76619ba5987d7aef0f619a60d122b193c50052a363b2d465f57b77f65a70443b594fd50e7379b1ce0b46711dab4b0ba3c517cea2ad2391b82d223625b7193ded9ebfe0443d730bdc0114db22fcf8fbfcf3b3bf789752f0adc5acb78aafa0eba5cc1adb8495e4c13bee8b92bc895eec6330df3fe6dd3c361693d298948690b436908b1760b52f7f9e10115b39a59e13fc064674f5bb134beb4027635f60f79e408936893a3d0af4714f993dc7d71a958ec257340ad64295635c48f4744d766343e0bc7639836b47cf1700fab282deb3be3a46e58e5b32c70c5c0ef13b6601275bdd7c5ba476189e3ad9a6e1e46816d2ef3b478c9db2d00d962f1727a61b5258a665f4f6260cdfbd69e5f4bea51a2719b5062438b18e76e4457cb429b84a989a32d5862c39eda5bc3714a0c44b22e3680101e5be1b6ad8846578e96dcd292d1aba696fcf2656f87b0a3b12caa55eae22b793ef25636d21d548c8d66d1d9b9112d05aa254b6563cc925737fe588ef23dd28a3d5f3b790a5b329bcd961f45d110f52b036f1a785f5ababe90ed5869b769bfce83111e78231ed40c0f23dcecf94ee06478a0884c7510c363d645b4d7d4d4a4a68cbe452ac69155bb2a6b0654a7d20e26492dcd6c89cab22c197783d9ef016eb1bb82c7b9a2870e738d52c891211f8e974a44bbacde2e30b18ec8aa08dfaf7e0632c78d6ba99c83ea319ed1d5529c1c1c50d7d4d40f4015386094f24fb072345247bea0679ce2a9567317f54f479a8257a74cdd4719564a90688810aa6a9e348192b0518bf9be7ea76546fc53569bc23ed4d2195cf6aaec8e9130655ef80b7476c53aa874a9a32c04323b793224a509af25aaf626bcd99abb26bc37716a31ac84a40e92f5c43f7afeb6efb3a5fd40cf4718fa2f5ac6f7374bb13a2ce1676cde41744691d4442950cee538f71294d2fc4c99e038bbd78aee12f3492da8363437f60c05282e0381c85d9004133430470525b303f44a476d062857191bc9002ad1c87257a864083fce5551cbd7d2c8a9a86b34408f2f86f35491cb06399ef24d04ccc39b350221e2ccb09386c88cbbcf6145730ef5a695ac83c35d8f822b67cffc94165a11bbb163111e88e1636b9ca8aa71ae24c4a48272035f3de8234c61c0300c48528256eb269092c5ca3a64455e11d8c8173c72cfd3ae7ce4580f3a5d3902fe31aa1e2d98dd7eddb3e93fa87f393b1f382642f7c36b8fa681824c05687e3d6caa80ae79412d21aa89f03b31cc98312589a090bca85b10478f155a55c4216c311706d17fa30c6375ef3e02c1d2f89d921d3ec348287ec70e5019493b7cb336637e9dbf741e1bc494e2139c21984beaf0d38c36fcda8f3e3ce11661a080c2c53f8bd6e51b9707d7a03e937c40d2ee731ab60f670ca211e1a72689049a0729e87c20c0ac720e1542bf44f8201d21d7032e5f37e785a9d864c46291b2be8ca13018ee1910727188b09bf36f5041f7290d6808dc79ec6dd0cc248cf073914dde697625c096e2132bde9502a66d88342c7e7e7e33fbcd727d5ab6af96f7d552b6049bb407abc5e47baa85cd7df24f73ece0360897554a80a33da506c2875c93f8978fa304c1f91881b053d7e95539061e3e1711d1da2e1838718258c1055b070475ab27f8ee616c1ae95dc2a36e3162b7dd414b7afeaa0870e5e895290adca8642f712df49ea3744e6e2dfbfe10959e487479b4f62446c4215a73e418f80cd46a037e354018277379f4e43097470286648b1714a11dca6ffbe3d1fd8174522b62aafaba572df042d0510d08142b7949f22c063acbbbbff6cb60e62f35ad80d6139e1ad5a37ce6a9420ca775ad4080bbc98f96cfed9be4453ee73088080465c2eebc09b8b4365675e8da66d6077848556f8cac20a3a24242ee3a45efec3242db7497b882132cc2d27cd1d2c86d2f64661d306d2a65498a3ff6076ee23ad79348530aaf84cec37be9bf2b7c5728282bd8446dbb08cf1fe49112557a182390dc1655e1ad02a4812df892885dc027b9adabb71adc1465b4f0203897642c06754a34f179e1012d8907c0aec832e62b050e3c039c129c1385faf5e364590a6b43985582632e8421530731839f17fe80b9446d183fe0e41b5c8745ac81e026ef87ae16f6e2f01237a4b8bdc11ccbabef8c1888b0d572d852960ef7c492617a711e6fa46d933bf844535e3a3e9ab56d812e3f2e786825b2fc7ec022d7db97f11da12ac1860fef5c8d54e7ee2789cb0a908bf5a5196cbf0fc1dfe797b77a9d111bbb6b4566843d0c8981b88a51bf05faa5a7272043da019168c91504f133246b7150ecba8694d1b6c63ec4a7bc7048a815ebf1d4da5efe134b8f0ab36b287753ceed6bd8b89d66923194714d21a1d7da260bfee134759820462caa1efbc3cf02019a8e9e0c1282962fdf14e83f54120df0c9b93d0de14fd13ab19925935616eb177be4606065d5b24a89708df8c726a76506697dfebd88011cd88f48123f3f1341a4c5b822aaf84be6d60373e991a1479565ec0b036b17f90fb0dec5cec8952d8c01e83aba835cf387c277133ab5ef036ddc3e633ad4ea537f92f7ceeb47671d750f8c600116920f5775ca4caadd0272dfef129ed7ff4b9330a689e928c0b27ef22e930d2bb7da68db441f02f1154d85dc9545b0527253e1165cb8e3c7d7756be0ae222e2813c3ab689900ab0c4fd82eccfa7901f5a107742264fcdfd83a9348b4831af273fa692924e29fd88c40233ccf3d96178433d9172409f44042fecc4b9e686bf693099f9d82bd130cc51e6a6f4cebf61038d577d27091086697b70379ff58dab4049dcc9af77f5563b1862c96f85dc5e1b8b803240ff3ccee0c42a2914cfcb872f346284c2da759ec3e3d302e31885de419720073057a72eade2007bbe4faf8bba186c9882228abe1b7032d0e1c7ebd6cb65f94b1aa78c459475c6d935b18316758b7f18dac72aa029a192b267badf4ec8e59b90aed024efdd9501ac148411ceae3d410af97905123643f3064df8ed1edc603d781648aabae122fbfb20d6e98af81de4a0b35568f45feff1b11c6e9fc652c6fe2ff60415923e10cbe6119114666fe606155eb4aa5ef9921b3c761b1d2bfbf67fab5798b1995c2c1dffe69a3692be0fdabf9daea5baceeb0cfe76fe840b0026290e86e0d82409f5eb09b07dd88d11052f3b04457a96e4e95835a2d080f320295e0dc4802f2de4482830a836e1d03ca3e734edfa8f973b0d1675c0cf9f4aaaf2bf28018b60162c3cc527c3c27a02111721c7373cb33083f480232e113a2a1a5ad2f457a2afe3e4e3e3b91c5dee58214ad0aa3a08272ff4dc33d663fbb8538aabe219ca921337e30b16f000a2cf7e69df7e09c72473b5f77ec6377fe8240369a51a529d7a72dffb49237e93e24947e763e1c0cd25572df2fd9dd22cd1763a1979edb666b2e6e3aeb1d5adcddc5cf82ad6eeac831e55d5b15e359c4fcbf529ec526d1754012636698ea8f0aed9262a3f75dda1ad2dacf50f62a9c89c75d32bc7c0d6148d4e14d6848b18b46c5ad27b86f0323e4fff36cd4394b0daf7eadf8c6145c6c39e26d03bcfa57e51392266c3c2494be8749dc810f4692660bcc3ce2addad7a061f1f651a301a425e89d5e5f173e531e321c3df62325ddde62d8b16a0dea7db4294a16874727df703d0ec26e3fc54fb354bd5fd044ccef8bbcdaccba624c58377579ae006b481f5dc78628aa95f39bb6b75685204b2200aeac968357a4329f7634f4f2ac9f40bf1e664a3f2b573797d40528561336bcec76af300a8939e75808239715c85bb1c02fcebaadac6e4908b13b9e5584570c9e4614803b1692bb28217d7a0a5032f276db2fda02c2200dc813f5f7b8322810b13752b55b22d6f4f8f192881397687dbb3d2c279749b2f185e69ee1159a458e4c7b7b93c48801435b83c1caa460455f59a060b3ba4641191acd1275a621692930a79eadee223c163ba02777b9cf3feedd7f29fcc0f9138186f27aee905ccdfa3a621a6896b14bb392c13a520c97a0fe5e1be2c34ceef95c98a20310f4c72d0301cf5c3d453b5c4fdcd3fd5b10443cd38c4242e6ee38f5be02338990f0911a40954f08b578b77dc1d2d57dea3305ba100afcd979ef66f3f9d4a1691fb8677bfc5694f1ffaeb517e348e814e94e9c1d7115f9100aad50ca70a5ef3a0e455675167846d878669d315cdb6e67129a5c6c25fab39668541f1988c701477664fa785449ec98737adac675caaeadf58ca61537af90a1450ca12b90001c3cb3a5cb041b3d2faf4bceaeda3f46fe5e22759670480888dba7c10016d62658a5ff1006162c012a8fa99d7a73499e2cc596fc8b0ac4715ffab7efffe47cc19a80c9efdb1d79004005b0696da15427891727b58fcf58aaa4d50d684294405634e191ab62d21f4eb4fa14c401ddc4698ca82816135e35d1548c82b3535e219e4cc36843ab7c2d62a58ab1ec08d36c34ca4cb06f68f5a1ae273e8d9d1c71725e219c56eeaa4957cb55a651f4d88ec75a9d3f8257d16676bd38ad40925b94c21e98c91527448f57c7688a48a1643f2687a320c260111e1f46f611683add3b301afe048cf26262c40310950962e0cd9fa30104be7c75fde1e134eef1e73afd2338020d191938371b98bac44ed7cfd64a0f1ca4b21c849bb539b211d3c5c4a5229420657a1b5ac08d40e44a8126c8737c5f7e9a0be739e38a789729bba0dc128d82bf30385531cc6aca648e5a5b907e5c4cfa253f25060d72f5619e2d6c0900a8bd0d42fd26b042ea776b8933c1a0b0d1e4dcd974759c84f6395eb09dd7121d75f00bdccc995ce4be0c1574122401f5142f695db3552bd30332c628d0eafb75e641c948a36f83b448d443c2837718eab97c4a9e4c0a917b01f00a60e15221dab94f0c0560cd7a9e1fcd21fb098311350a37411d60823e7faa8ac0a9542c3437a6da942d30289cf48960de4039e8e06bff74be10290d1b89c34a6e3bd88890551c0ecaff0c359b19a4521a819e3151b733e7a1bcf0d4afb197cb65142124d7c13c3a60ab77f009917443c7228bf4deb1013fa3c26d7fbad031688673da44d8ce352469e735bec6139bf266bcc1adcf4d3598855605075ca68b34e93bb723b919942740ce429275eb2d2833abadf93b8871c47f48469ecb557f90f6210893759738f559649eb7fd700d7f2ed91a17c2dfba2c77bc34a3d390e5d03a28cc4db903017ec97a220ba6814cb09050828f1a786841e362303c4e7292a07a428a8ea3758f7423bc0427bbf7213446728f2cc724d92a23e045b74dd7520dfe676204e950346ffd1ba7392a706a28e0d8ac47a0f7c85c47ac315109b2a807850c9d311a7dc01e0ada6a35c91aa45fd1c9bc8a7220cb615417d87e21dc9565ff94b30242e5505b444c2265ccb2185bb599b44e4fa27b887f1c3a955eca70580084b032dd6f6525fd1af9db5b794363cddd40b2ff19eac926668ef01d5fd56f1dada1c8b8df0433619f6f3eacdab1178b9a6e8038c0608a597eed9cd004580af2b411e18162890cd6415feaace3f62e6f303649d7e12aebea6c3ff7f80d8b1145eaa7c95b039d0d7927b2c72faa303fcb38cd9cdf3c6c4557ee5828d12b2dd95e697ff48cd74e69f5a668befb23fef4fb6defd8faceba701317bf483ff813b39dcd1afd87cfd234ff20d34651a346055fed15c8ab15ed4d72a674362157e6f970f35c1309afcfc1d140a4a11aa1c245e4389554733f3f11bb7f5608cf6ded217a9e1427c9afc84fd119ef73579da73605dd1500a7708862b8b37e3ca97b096db898661fdca5aaacb09dd8ea35a23a2ddee231e512ef93a1d79f20b8ea8b66855647ce4a81502d2e7454dd49cba36ed6eba6992c44d6f64feb2629f02c3652d89fc20360274a30737b22e0c47a35c203c9627bea4af0bd1fb853ee08dc3d1508904cea320b2477dd482c5befea03a5de9fe0712c57e64746d9bd351a690df985dfd8260df225d2b78ed149983076e800311e0eba56442fc0eecd91d6f96756a4004f6533f4686901e2ed86e84cef5335971d94084f0ca85806b11fbd13f2c5eacb7b4e2230984a3457aa4cacac4b326144d5812b4d4ef839ee509feebf6cc4ba00d2dd4405423ca396418da2f73ebee23c087e6908242742316f950f613af4ad5305478d9b817817ac5c95832c31daa352ed76633b1fe3b0ee23326b04cc6c44868ea049f60c8fe0b06c22973e62f65394f3c64261be434f7a04cdf77e04dae7490de265fd465114ab86bcb1849e62eaee6bd4def2bd6f78e7e8964d99469f01788e4ebb3c354660e5e801a5049eb22b1a9fcb22eaf54d2cd20c89c072b9cf4867963165f5ccee9f95089260c2c4392670f3b2a458a0c717428f6d8d398144d24c1baa1a424e61b19ac3a97e9d0debbcd26f82a8a383958de96142436e82e9cb1564fd6143d208e2078303f64816d1b6aa8b2c675e705e56e646c52a9580ac011bf97e49baf1bbde4c51da04c6f773bf08d55fee9397130b2fb48c4118111fa6a405827935d25300a58a25bfc12bcf6b2e99f22cb6b7e0ac6a30b7fe930e3cb7146f44493f671c61f7b6c2ac3a8caabcd84e847a252e2861bfe1a78b501e3cc69f44a985fdc57fd56f1aa0fa3468c750b812232b241301f4cc959796a7a69e0290089a2020391518aee7e9e9a49fce90108d5f7474dbd28cf939b6fd8c4f3bb082e8dbb43e6d27e98d915b5f22b13b17fa46fdfdd48f6f09fc08337dd68fd26293fc567f5576eaf2e873ca6ed3db22bf84fd4ca1f42469915fd395e6ccd59d0853ad2a7a92d7dd03820cbf8e17c60be6f7a9db34b670c2cee6fb464a9216f910b16c4548f0a05206444d7c1bb739783ff2a9f731aa83ffe0dfffca8dd40d9eb13500c3e512770451afa009b6677d99c08812b4ca177cf7cd9e06d6fe4784455f20761935499a97bdd543cc4aaf640ca60b8fae7b0638bc3312ad6ab6accd3d849c9188700becd2535bd7441a0de5e75043c2df37962a53fe69eae3fc2a326c55c5837a2d27d2a9e064964828674b615174321c801cbd70c66be97241086c865b8945cc43f18e0dd864e9d4c2559dd249d2c947ab2c3cd7cf1e29c4ee181743552eaa8948eb626fbba3acb5e94099d983f6bc090b4589247ce475ac7f4b5a163236b38936f511aa4571744fe51c2e5e4f832a93dae9a0292956269d2ba8da72c6972015b47b5b3f09eee1a0699cdfb69d5ffaff2066fb68d82401ee2db13a5b0a260d548061f6000c45687331883e1f356618e8d5e0db4c1609bf489576bd5f002aabd828f6d194f0a3d6242e9d347ccd452b158384df1a623c23b0de9938d2d4a8bd3d4c01e4ce47ac480b7521f86ba23106e7ca578aa04fc7c20904545d14389fe86841c036ac731aef9af24df43ba0b648f5011bc7e79a5aac149f850caf9436874eceb4a95d1b0ae40c71d71b96335474c1209b2b91fec2d5bd6ad4ba97e401f693ae12183198ad1123532296848a7021d5016cf6873215af201b55d29d24e8b76b95d64d245522994a9e2a2066b928a4299e7e032d76498bb22b9f0db5506c6e1479f8484b8ee536f954bf0d84bea0f6a01e1d634d58ceadc15e0189e001bf2a09c3aae800a9f78d76340abb3e480eadb375d3a4f1be1ab72d2c24fdda0b8765b808e66d2867de3383e1bd1dd02da9ae4580457b620c51b0cf5ae31d462ea6019ff61a3bfcf491b0de5d7a8220a5d46b2ef2e53bd04a333a40b45c824943cfd45b0497ff214556dab7806b644102000ef1f0176aed3d4ef26a4544491906fbe4d9cff99cc6ca2a9e7f3c1b777a791a30a2036fa2f03848acf29b1082dc9c112f6e02758db14f1f6ada5c625374644394d17327b7bdb62807cfb01b21e922abda6533c782d61f1ce7b8fa8302610358932078b11a90bf4274636980723ea6c82d83bb1cc2a3ac172105f6976c956033b916d25c90ca42270808eb4fe0ae59623d0f73d44c29ab04d33b88c8f547a6d44c46817b5912c5aa3bbf2626614a70922d3aa0b2b74bf1e9aeb8b8d54d571b4a0652a9332eec1a9387960addda804066c9a9642734ccfe4eff4e1bc72479196a1caaa48bd206d854eb35406f0d6a4c440c4f8cfde3ea3ff529d0bb3e0c398f3fcf72fa32ca9b61abdd669b049d139e18e30fe45e579bb72aacb9f1793f2a122fe46044b0a578420d17349602df4e02bcae31b5d6ae075249141e4b90ab018b23ea60abb07b45c265b1e01b46e4262c1e1a78ce142f7e5b78f78a0e44ac621b6bcf8b10712139fd5a3aef02dc086188a624d364dc158cdb6512fb5c6e21aa2a0516876742dccd40fde019328b90c521877e9b2101f8428fab44bae02ad0186c8c3aa34b44040aba3ec384ce5a37de7c4ecf3f9b7f0900a6db69fe309a40d4ede97cae977f1cbb721cc6e03763527ba360687315626b63da6b45ab91770f1905c2812c8465f0daffa97e865f1517953499a4cde58be8937a9dee212e30867dc744dc09644ff191da27d3ac456228dcf2464c9a25c93e7f8f71ca20ca004441612c909d82b6f6ad9ee28edecd39b919722b8b35c2288a79fcfb8038936a16ee11435ce8a156a866324639872baedac56bc8386675270520c3f956ca6c415b863165e0de77e1eae6b9428526c52cd03b32ca98d9097e46dbe539ab433fcbc43c9e21c1bd918fc52dd3efabe45ef2b7c28aec3e9c260cd7d8fcc083b2cfda5358ef72fbca4f0157f406d8e00981aed4a26687e6760e8097ca7a89b48856500c6971f2e2d711e7295d68b22a5d2d2e5d013ec9c01179bc12b4dc2a73286d877692d10c90e1e597c3b2d85e7e2f2a0eee1aa6604f5de913e0d59266d7a5ee74efd6ad82bbb29f489f0e8644dc375597d0c6bf4484ebeddaa30b18636d15d866c467baff8392759cfe554c92acc264a4fb0223a202ec4ec7209f2f02c2297c0d0b9f6f57ce0c1f2467f9e98855f2f7214b6bdcd53b1caf613b35c706153039727da5ab72695335b8fc6993b305c8aa1a005540ad5ce205800881bf4dd93ede279c806cfd7f50b33278fd4b6223a86b55d9778fcc1907ddcc31c44aadec7498fe07d4ca57a6f8e0140bf51f705c32c5c41a5d6cd83b9e3bfd352ce941bf1e488f0ac49229fb15f721d751230ace6d7c5f1a256e222ce192fca8b0b13e929d4f75d7438be748142bb768ec056e3f54a92d7a05ecf8043058f9e8964f940a565e134e580fb4166403b16b442380c59c1d4611791ebc14b586a761007db2ddab172095f783b9a12a0a09dbdf4a779ea3271b809fc24f998be2677f2133fe2b982cf3b2187d34f03cd676ad8bf4fd456e755e7f347659cb44e2e189aa5a1213a68df5db5cd3fc37d84ae18bf0e15787ea8b7a6d4986eab3ab0f258cb6d71674088775b6b38533790ef8cc8f7e868a187880fae5e33f385de01017e227a5760b80bbf45a5500cc72a7c091482b4c2a5d956f3a443c8050183b51f758542040e04dd1c46f354ec635c20ef76729b5cff19089b84b23e2daac27a4f364b82ee72f2b2b9c5f978dd6805d75af043eeacecd9e50e6beb6aa91410bbae45bde800c86ac3ddcdd4d5985f7567135c7cf5e8c9db8227530a6cfaff86076f25dd80580af1e4cc2881fd5af7f0f59b9fa933f6df5f5483e28a4b0f08d4577130b4a89914ca0f9523a0920ab09627d104806a6bfd1808fb3644e9db6a4e8c1512d5c816842e190076ee432e1f2e90270dd6a9d4fe88da8b5f0da9e92ec153e3c5e840504d1698b115ed803df86fc3991c919f8e0e819d93d271bdba907e7e2abb3cbeb46abe4145309bfc4733949e38617cd1907aa50d72c53b5dd20a113a5a3568842b677c29b0c7eecd99914a19fad43fec03e609d5b149b1bf9f3762de88758e9881483463ee18b1a5f356bfa786d4f8a654dfcde454677133979ae969186f7ebae599362156115bcca50981c8f7bbbcabe54eda5bcc509199246cbb34d0a651357bfce0b3d5a64a6ed74bb940c5068682fe361271c4d4c0170bd34c351021310be667c7fb757083a6d06cfaf6064c0bdefebae5f0fe16184b6e9d280e3c47bd0a324397a62fafeaa4eccb4b5675d072b7ce0151165ee33dd616114dbb8cf7b34febf355da7ea85d2e7259c794eaa65582ef446616cebc252c80f4a3fbbf29fc0cacdaa5b852520069a438b0052dd0ceb06af1459b552c3b9028d8721e572abc3b70216ecde963f3029ad184d75cf64eb5c1bb784a133835f8e78959fb3c7d681d98af30957ad43550864569db97eb70e05c0a4d6cb138a27dfd3b21b1f73854863cbf447aac98c9dcdd4d997b53259a0b69a1e9c3c6338fbc8ce19fa04097d64dfada6d7c55c30eefb05463a6c8b0c18a718ca8b04883888dc6f43a1375b4e0e36202396b0b82325cb96bb6e7f575f9b77303299da10b1c7fb41c85ec94833619a6574fdfc542dfc908d4e8234962707f3f4ece71b797c1a24ba254211008cd87b64b4df2418dbdd69dee543dfbb4c3247958f33599b1d71900f49a2027987a8d74a404fdbd14c9413d8db972002eb4a0d56fa527948b7dcfbae74fbeb4690e44dd3c5a386d264c80270726d64ea2e7d0a5565e7d32e4a0daca6f0d8830c4cbc1824bb3867078799c74876d125d114e364a2a6d71835398c0af905644478bbdf8c4d3aea3b8af88c50c4f3ec531cbac7fde8ea930e8856588eb3185fdc8262a198a784f000bc6fc475dd0832097b5e61f4bf7c4c86acdff3b18b7754fb650053341dd83765e9c471077239d81433d53a410073efb23ebad5ec3b93289d9c341dcf4478d07a18a89f72ed6eaded133a71bd7e8a37f9202b2e5f1743b24798068b9ee32f48611046133db420c32d870f675d5e6d1073b8bb673da5c8e8d3507e31d3f89b92e99d60b8bfbb061a8cd681544fff6d77498f772f99650403c8a0ed5797f2685218bf5f131f1fb8145e92ad79fd7fcc52624bd7409cb054414ab25322d428527b026802ba933c8e4aed5734052a853ffe3443edc5fe23d1d170da3ae5f883edd302d458d45af2c87a790720a2b048605d2db6b422c909ae11c7514b8445dd8d9374565062e39dde4a472951d7677c598b30c3edc2efb48c668514acb9044cee7b746572db3631bf948b6f7f5c391a574a7ffad5ecc4ca458b8a7f15ad86c797f53618871ba8a8a413c6a5399512af5c7b934ffc7255e143c571b668c16d72fa16046936e1eb37d61244f124219b1f2394a250524f05968c170c5694ab63612b5073498ed66a1058b427260ac5a6d027aac7ebe0106feee915a089d9abfd49a0abd683ea15972dc7b32f3d9859f50114d68945fb5d0b742f20a3a5c58b66ff3a86440899b8be3ed27d074f6353001ee11c743f266f45d7418af760ca7bdd237524ae7ffa95dc2295ba5ca2ee37cfd84bb801f97c20c48e555fa6a7893cb5563e5b3f48aaf897876c729bde445d4b4896c94a5b3e0bf8ea7dc9c2cf05bad9c91fe41ba80c01ae4ebbd5aa0dd40836e13bc21677c83f4e9343e83a61160ffb1b241e29f274bc1f108e786b0bf02cfb3884d8225b314ac872e16197f7524bcd170dee60901d8133506a09d3f17e7ee91bbd76c4d7907c2c5b35e12504946be2f786137f84f64c3b8c3f2efe09ffa58d79fcd245fb9b55f9c82325548c50f34b77525ce6ae258279296b5f52d0d096e2ce6ee627e767926ac192d05a447c525898cf3ddab2ac0fbcfa64e9645253e8cc20620836743dc732419367839ecf052d9b4ba0455c93c49b9658817326f566474b0907232f98c03c987cb48c88f71847f08c3eff6d2cc184dabb085412a121d019dfbdafee94a371949665a0a311d724fcc397b4a8b9a45ea50a18e7d9998e3088621131e8447c591986fb143416e86e73d39220007be111fea04967b932b83123525d4b3bc9ca8548ec029302172e0e8f4186173901ef018cede9e58df4d2269a586b4e8bda401af681d850b6e551936f4bce9ea04ed946ab77abbb78067954eccaab0980a90452bae47909c22271ac3a9cf357afdbfdf8808bbb19f649f777c6497e5ae8c1a53a707284093fd7ebb800123b3bc2eba217f46e3f197444f23993d732647a9367129fbaa8d8b0f0c362c6682f77b405f2323e190e634926c799946ae44c1e134ca6c621ec171adb31e21064d1142523ef34fed1b5719b77384c8a06130f9273b6ff03ddbed260a49f015dcd06f200cdceef672fcfc924b494c4732fd350796836c75ca33d67f6e188556019a2d78456d30b8da6151a5da3418ba894477b9d49763c67fd1a2af31cd2331f5c3a4c698419508b90b4de8da029e4856eb33a60736cd3fd4e231f3919e92b745fd6269557d6f9fd8b9c1dca7ec279131d25383f13416f408b14c0c20ecb5455f072aa93c8ba83e3ac8d55d516492da2cc6312c80b21bdb6e178d3113395575e45ef63577b9accaf419adb886b2bac3a7f4b30c4d24a8740bc1cb6fce375a5e1872ac5afd8c7642b4f2b97a3601377a7a81dd56133907762d93426b3e5c9f4dd668c23cf115a05017615656fef5e7212e7479e31e816d44b85cdaa0ee260c4643307b56d8c9108a18eca45a152b4a00d62289457153a10311045550f626e75f123d0ba2cb745c6808b13bb96040059758f1df4d85732c58bf9017a13403537ae23314a9e72e6bbf9009f94f5d8cf5c7c5f2531f224e6e772f1680c6ea20b1df13f350996eb29394ed5d90c44f26a776e31a846ca90d679c442ec2116554b82e16452d6f5e2e871b44b1add82f2476736b40628eb1daba0d8da9c4ac4fc2c738a5aebf8c644d908040948ea28b517b6ea62f8c34bd1bb7261dc43f0d7afa13d2e2fd6f53548358867d9809f0833474b74128c028e84593aeb5c4931282fa81a6dd162d466f4294c244e15cc1ceca17639f02d928dd3a7d92396fb492b7a62fb447bcf39b26426e5a91091e10ee8e38d926d842506da0402f1288c843cc94955c15a8a7499008f0a996ba4634e1c2e4f93a562488fca9c6a9360fc496d8487c90035b4c1f1c9756e1503b68fd6655891e5671e494cf496ea440a9674178d6264af6775be2bfa1cfd201cd82c0f001abac73e5dc1ac6eba85c15046c3a7553b301e15245cbb5d3eaa97d947aa27cf723c7cd01a304f058653af7da4277af90206c656c3f99d53fadc708dd7e5444eaf7e47eb0c7fe4f9979b8717ad874e187302fc24d40a764bda9c9e902ed260586a2deef43c0d3c40e4c7753ca713894b23f50a960ef6a8a7e38165f6857ab8a255e5a64d00b4dd0b40cb49c02ff7efd43afa9b2f585e10ae4fcb3e1b71040c7f15abf570ed84d72ab4ad1d73fbb476ebdf2e006952f17c1d30b5e3df408ca2f1f6c3c7187c330be14634ef42b28f720a9d2693a46e67f14dc7e093dbbe628e0933b6dc2c7030d9af428b3eb60ad1ed6bbb68c45aab58fc8aa86fc509f4f6e6ca425f5fd31a85705c4ad6362b502501442cb79caac05516dc3aec5ef1f6eea774c97b48a32e09ec1b7f841a2eaa53fd2bebbef41ee58beafde876aeb9c9075bdc47d3f00f57dd41bdf4a3e29ac18999085031717f7c5bf2e4ce871f9d7d2a98bd9df019bcb73781a1e4fddbf7aca61ff47ec7c87874053506080b8bd3666b45d416607df03f3ff4d08fb289c3b0c6ed6b18529b56caea6aee54d279ae88bf74c9b6b2f6c764c4ac275a8c38a7b08a856d880e3a98614c19d7ef39b64f4fcfb1a4027e335333e6400e5c209c13c443a27253247f68333b4062cad3a06c36cd3e3b3f5ee9f4b9908b82ac3c0268c0f79a101430ebd75560629ec70bc7c50d0952e930f0212d082ddca5fd8b849ba6f69d4c8a278647579c608628e3719ca8001bb75c95040dd958b69122dcd417644e0a59881538afd99da0bd4298ff8f67a9c160c629c8d3d9a1d59ab8d78d03b62ddff710133fc395e8b7aae0082012b01062be30622fcd6d30c4a447dbe53d834f05a80262993fe8060a5092b535afe9bc12c6d3eb5c496ca94b4e284eb2c30b2cd877c119c1d934e977bb3227391cd4c2d0786c2b08de6686e145b76aef12255ef0783d899f5de2016c12e076d5f6ff8cf8c0d8e0c10f300e43c22d617c915f1e28eeeb29b6b9cabd3094aa1809e9ec5df21f5464b02e98b09e2a75a59f1c27ab986d6db5b7dad42863727fb4e0c069286fa59e8e74b333215965c283d51df0daa868165403e1ce51df3165869de528706d72f992da73c93a820b6ac00ead5e6bb34bb13a0b2d0b6e95cb56891ff0addcb597913612fcea5fc8c66e714865484a6cfb984ba78c67537457028dd6b511d946c1b453507aa61774140828578c715211fea370fe7f98a80e0517274c7763ca96e9a1a8629686ecd623feaef39040200bcbeec0bdb9c7d1ddbd88f726cd79fa0d631b18148f8db10b7feb03bd27a93ba609b62a0cccdc46526eb8cce86ebb0fd48606139215fd44ba4d863981ede66062c4ea61a890ee12f66d9dd75254bd24305d75f446a8d9cb1c0f7beb5730916f8b2319af20b171c25a4e12c2cdafdbf786b171f557ffab3446865da0b7ff995abddd81024a294722d3d8bc4593771a5b14b862356774a6e683d115fa55511215918222242a02604db4661ebd2c4a13d5a74d86a4e8f36e51f9bc8333dc54dfad64c2809c65851aadf7ac610e6421c72f4ce5da05a408315994a79a60aa6da8f74c431959dca39e010892670e2c2700d189f5487e5a790b935f89b751db0c4c30e0f615ea871fc993e6a5842f3bb10961b16c8f773a87b8c7e64dac61c49f67c21742d4e54fc187c620f09458a0533b9e97dea0c04603e4241fbb2013eae54cefd9e49d64af380bda9b0a39a66ad350dce45038d156a492e2f3997037f1f4e03d63cb630c6cae2a872852453f8fa6266a0b3240499d4e7ab96a0c2ebdb31e7fc2f5c79fe3b38ec303710428189a45f60745591a39ca008d5bfe91ba19fcac6fc6296fc453a66d7253dc59d8a9192e1fa2d2398d16fe9ff0bba96eeb2a31e5d2a2f83b0d7eb479f5bd7a66d6f1bdd1db9cbba4f0b540ad048a989c2cab06cf58e453ed30bbbbb46fac5f7df0f3d3d1c56d9351b3c8f09f46e9b5147c13dc00d590c5dce72a5435ace3afb9b8bb3e57f602ccc2e9320441bd9f93e50cc00f1d745aae87a138fb2f697cd50344ed6340320972f1513322128e20c732da0b3edb42e7bcbd4755a70552ba06ebfe23c80967654ad8f3876a8b05d3138ece8d9492d58805e7d7b39506d09570b727fb9d746392ff3ba0657d44484674d2ea6b132e17af7e1571b3596ad00931eb7543284ef5181aabbafb8a1bb0ed46dccef053c63ba75d6beea92e8c6ccfe91c0a9587dd8adf745bf8f7c15e5f68ef030c76e08f242bbd48daad06b672cbdba45cf056f29643cf7799a30fa321a508b414dca4bff075a82efcd80e7b9d892d27ba5d5b25bce5d04a43d4d8727701413993c559d5faea0ee3fe4c8e197e9171faddb5ea856b2407bf0872d4ed1581a115db756f1e8ad4f5de4e47fd9add689955a2b663c6a7c865a01d4f869f59af76d589a158f9f6ce8e5db52d49b4f5580445cf50a7b9152d896878051272c0dc76db6f2ff27e020897ceda3c5de69d7cfc17045a725fbc5a304eada20eb83eba1de77ee843b1d486ea41433c0e549436aea9fa15688583c805786c31c06ca4436ab419242d0f2035a180820a23c4781edf9493a5f90d9833cdb38176743615c1c4490f066865a0b37509d94de4de52cab465d90a4b0ba00c2848ecf00dc5e93f3e5e7a8f8d07e6a98d87c1db9d9b37ce7a78d99cbcf5d3bc1501ed70f073691b41de56c03715d8518c6039d8863d49ad8b60757504abcb1db0bab4da5bb72d612d9ce7ceeb9a79ffda44abeacf9a4b8d702d02d7db491fef8bc48ebf3e008311d680eb8ded1d47af5f610fb83e52607cd95bddf024f0d863ceba81777bb5166b05e1dd9d439d579faafc6b07a5d73fabb5189f3bb6ba631b61365bd4b897f3fcd5fe4a8dacb5d9188db327540fa4db163503d25dde36572eb3ed746beba406368eb4796973b9e9ba35d278dad01b2ff5f1f5e2f1d7d9d9cfebaeec9dbd4fcf9e535bf6f80bc8dbd73e5efbda87befce2b0bc4823f26c1188b64be379bbdd6ef976ab413692d7bef695203cc84ba15bedd64939e846bb9da78f8fd8791f37cfd7ebe53daf93760e4f07d1a79fe7799ee7799ee7abe775f29c670fea733a8fd34ed3344dd3344dd3344dd334cd0aa3c08f9090d049f4426df6247a659b996f2689473db027d1abcdb38139ccd45fde48a98d24c1f575cec7c9e0181c973a576764ca396d98f37066599e3498032a061b5ed976e249ad277b7da566407a99e54930df584f3a6a23fdb4153b8938f4f639a56330689f746b74bbad78d27393ee63edc0168d19905eba7cc4cec76cf553b3acc43ad4d516d1c1978e808afb40f39416f3b2ec2fcb32e7f22c4b73fcf6916e8b465adaffb3c10123385a2a8e737e4f9d6514ac21ac6a88be483318057a6c6d8b4e6b6497ac521208a4327d966799e7354c49da677976ee2ebb86005eb01d5b09c6cfe752e36a903da3913a278bb9b5f6c771af466a1ce973d2b245edd3ba4aad78b60ae63c113649eaa45ba3d68dbde6403a993acf2ee95cc79c679190e34f899694223d59db3de8f455b45a62b22a064f10608774777795ae9c73ce39e7ec72b9dc74e59c73cef9f49c73ce39bbbc060bc1956fce668fe9a79f1906c2a9c1f4699bb545b6a868ec8d452ee78d2a3e084681eced40b008640f8245207b7be9b339a7298d160c9a36c693a7699d08e68013cde0f569f586e5f204ea2fcfb0b1d72bcdb22ccbd12cd15bed04d7ebf8256dfc31784b73dac1dbe15553d23bc01e80c15fa07164bdd55a6fbdd4e1b583da72079b4ddbab1c4ba81e481f4bd40c48ebee344f4f10aefeb50fb5160816422ecfb2749d68e9286a6df9f2f082d9f08ecdf2dad7d647ec3c889c73c67df0266d51698f74b6088488ce5d2fdd830f3a677a598e5f96650e82859045b875f9ccc29ca431f7d8b5a7ed9e3e62e74fc7a68fd9344d7f99d6da2a118dfbe0b81436bee9335808a64daddde080111c2d15c739bfa7ce320a5ad9ad8b5443f4e3d3c6e33f962ae5ed8c416b0be2dc69b4340d56a53cabf5a4f37a8b8cf33f3eb00894de5a9dcb4e6ed510b008942e77dd78316f6f9fcd394d69345b8ec160700ca675c7066b92da226bf42a51f436e6beba2a1481cb722c5a3125f2eaf0a77d9d7f5221da061c8c2ae5b5af1c971ae7b00b1b83c2b47db6a8675492d7bef631a0bfdcf0e6ad7682fba58fd8f9f206bbc5ca6640ccdb51589af6fcdc86c42256c790f403f84a1566eb2dac013e3014d6deb39b09c6ef91d96ae33838c757cfed02a68d07e2fbc6ab584259558bc40d88f98f97b006fc78efeca0a6f9729ed3f4113b6fde6af5f08251a0c75fb713b4fbf809a34076f37682b116811f8f79ec2682d24d307ef69f9b087c7a787a6ce995f4b6c1777e4aab685622b4bf720bd16a015e3b16d6bec691fe426a0e24e9bc3a44f24b2094c84e82bd6c3d54a99f260c84d3cfdcb8eba6eddadb63c568797b3d8d823767cd09df9c78d35f443c11358b8695168144da079e4f590209f1d40eac993183f22d504b38664063d2b215f7720db6b29e15f772221b09c6cfe0e523d3abaa5ffef206b8069bf9f2a1216c0e995ac2aba22f7b5abcd3e94befc1e7b57e71df20bf36eca3c541403d416e610fc0e0817c44a2c1561b577393a93766507a69cd3c116c64fa8d4ce8cbcb9f969696d6c83422a91e4a0fb2d56ebcf1e9ec8d1d8c496a06a513dd867a6ef636562da91e4a206f408fe39e20b7b65128e4d8d67e6d7d1b99849e806ebc1e9963180831c764252d4aeb5cd650231a12eab18dc7170c665fc876b6a91e4a07b269699d6e6a06a5c3a91e84332fd3344d619ea6699abadd4ad334d5e0699aa669cdd3344d53224fd3344d873c4dd33415f2344dd3b4c7d3344d53eb699aa6699aa6699aa6699aa6699aa6699aa6a8a7699aa6699a6e4853200ff2d4673010d29d33759e5ba79c67c775faa4af3ce503cbe9a961ca079653b3369535d45217d154d6504bf3d0548d281d2a85a66a44e910d933950e09f5603b950e09f5dc29a11e6ba7847a6c4ff558d4d63d763c4f14c84b1808425ec24000f2b3e69a2d2a1b797ac7baee8969a44f09cbd9859a7de2170cdd79a54fcda1f4b2ec79dd3641afb6ddafd990be740b7cfde4532b8df165e91a6ce7900dc876a6b653d8b832486887426be69cfad2b36827d697e5d904cd970e1ba6bcf3f7eb9ccccb98972fde0f4c2a4dbdc7adf3ce5feb6e0612f13891db39adbbf9778d7e319e68c789dc165b773316915b22b74badbb1949faf444a713b93d6a1dee590ea5671f915ba3ced1ccb40eff7e6d7e737e279ec8c789bc87adc39948e4fdd43998137927b50e67a5c75ac242f244de44debdd6913d221f897cbc6a1d99c1a4669ea89dc847a6d691998888cc484f84a5f4443e123909ad2b73dd227209b4aecc56e915918fa0731a9cc81dd03912904ee4b58520841f6842445e9bc871ad2b851b3a4782a19713f96d5d8965399424087222d7000381e836a657f8f75702e0daee4f6875e7ef27fc097f585677f6cedec5ea599d8985d5fb599d2914fe845667fe7ec22f1d63599dd9b31c4acf394d7b18ab67752e2cac1e560fabf7b33a9750f813fe84bf2f5dbf9ff027fc09bf7412cb969e739a92583dabcb58583dac1e56efcb2cb41c4acf394d85e5cf72283de734cda5f0cbdcbb3d1a2d4d7be586f2f69c87674788c186f366bb9d4e743bd31df4749e73e7243a775cb0d36fbd9db3879e2fac1d17d689553a8c760a775cc2532b2dfde563fe7e26cc65f64e9ad9f3317b66ce5830ac8c4584f5a5bbd052e80313662191f04bcf4dfeeceff7fbd24b8cf3ebe8cbd2c9d176b6894aeff3ac56c642b11a0b63d9c8abbe12a2c2166221797137b135d8faf36fe87573e34a1e9ef1c91c4bb4875eb3137dea17cc2b90ef4b1742fad26bbf2ffdfc799dbf9c7be7efa971a507d946bca0f740b7b3cd2f97af231a2dd5b2b053ab71a5c3a052b2f4b3d7b913a59f39a7a92d83fa5fb6d24b5e366dfdb64de7c6d79765e923b1f4d24724a8972ef7d981f9497b05f9497b5d5b637c1d0863da6d1be940372808a86baf7ad65ea30d93a49fb51769b33d0abf04baf1c627d2816c4d96b8c7eb973e22a921ea977e6a206d35c475921cabae9e1aaeed510346db69bd2fed892f5d66f4a5c78ebef49f185f8e60bef42eddf6f0dc78afd4c6f47396565ffa08f42f4700bc4618796d6391eaa164aa1e4acff7f54b6d09b4586f2f6dd9dd0e03d1b8da41f6711c470b0ba1dbde4034ae7b3cb2bf11f694f2f01146e168ec203b99739a92401e7f9e5a43ec380f5fa5cec35a9ef4cae32acfd246dac8a5c691a85f5be9b64497de75e3b9fc344bd08e6334ee028336679bc63ef63c7c642bfdec3efddada76f2d87838f8a49fa58d0c924b4fba9b361e0924017e12d83872c3c398a42ee79140924c5d14804500631855972b07d2d31ab41d4f029faca48ff491be663aef59be4a1046183e724ab1dbd12f90246b5699fde4e5275d45efbaf1ee5833682f3f94deb7b24fe78d67db4e9769de6e67bb5c5e7a2e6cc630352546858fc88a15368d8572d56050cddffb34e40847c31f8050e185cb921a2c4d57b2d0fc58b8f75ef349c890c3b5a7b5b60245e260a1c2450b8d3a67f06896c118e3d3348344c975fe4e61dbebf57abe7befbd469880499c90216202c63573efbdd775c3189bf7a2e88de772d932530ee625978bc0e5e6cdf45c5d373dcf186f9d4c5887a71f33dea678eb204478f081032420428fb77e811136d0812a6ffd039d33df7a08464002560ef6f649e9cc5b6f41e73af4cae4868a70bcf5d1a873f66d7d7241c75b1f6374ce577f49f509c8d5db9ae56d7d0ac2f0b652bd7d0a52e26d250a2b14d83df1d6954b714e9f5a401300134881362f442951c6451ca71dcc33ccd3220f2b1f06731c0c06732d2e0890fb28575d4d61e6d00a50b071422a6264029632f9d6281b3b5c23932b333710e3ebe5a9d6bf5ebe01675fb4d6e5a0d4141a56a0826aac400519be75219f31c1407899406b5aeb2af2c35524de6b4201a1e1c1c476b4768999b7e6cd2c622817de6c307dbe136351e929284bbfc0086559d6a8f165492c891b7056f7a1d7eb95b02bfd03080fb29e8756969e3d6de14bffe91cec4b3f8b5c34e23cc618932d7e8fbd9ac4ea637aebd717e7edd38c244d336670a221c415406b0754c14b077f65d8f87b657cf93ba4fd8febd756fa48c7a337c95807918296262a0043907091b442470b5a6fda0cc99c576805638c63ccf99b82952b17817361bcc855185250318c9e62103be0dbe3841f35b6d0d049111c63de7b2f8692d623185eb8c02f604879ebb41761deba100a47de56c1f8de2c9f7bef11357f31c6f896f7ba38c1c6dba8b7d69ef0e5adc55656258e97e14f8c6f4dd6ad5ede628cb12dad6d11e5afdfebe4e2c55f29ec1a2201e44b0a42e290b9524686181e1c55e386ab2c5b18411df57a3d15e5ebde7b31c6f896f7ae88225a1146012c7608597cc1a01a157d07464c9c5aa0288778a70891152ed0aeb516b5d6da7befb5d65abb42c6ec563125cc796243d5842a490c346b6d53d4db7befb5a5b52a963c2e3ec6175fd75d40119a2826c61c0992c20dc0bdfec1bdf7e2ebefefbad1d2d2665aa1885380142bfcf9d669429e42c85bdf9082cd5befd03905bcf50f41defa0626bc790bf5b6e8c8dba6b74573de322162e1997bef4501e631c61767a04e991c4b47623485b1d6628c71dea130a180bf9e5108fffaab731b527c27809485aac8529d188a604e6b6dd391b7f7de7b424c0d97bbab1b577e367e98a991cdbbc4cb5b9bf39727a4fc8dfdbdbe26f67a3d143bd2bba88fc074cecc0a818da55e182f563d303bd2c7adce8d5fe63ce97da273e6933e168958ef62125a1d07e004392164a9848fc88ef4f2a48fc4ced5aa15269e2cadce048e278aaa9c1765d28c99a13824b21bbb3ce9e38fcd93fea4a7c0ea4cdf0546e800e921e8dcd0934ec28e27dd049d439f341d6075e696e5303acdeacca20d38d23f581d766122496a889139437624161526e7932ea4a050021515574fbb910b9516af27fd6605e9adf5fc72b212f5f6c9db628cb7556f8b5842b801f49b446215396fdade34bf3c7d0e02ab047997cb9575195871eaed78d65dae5cbab2cff7a35379f265595a5d15e67ab0de5a73cbea72708bca8cc703788c3353e7723033b5d06af57acfb3d72c3acd22ab2b1bb882a3c3bca4bcacb3f96964cb4c9683bdd9db79746f67510d169d47cd25fd7df6599d49f4fd485c63b544ced2132e555b9ade586b2d6905c3cd5eeff57a26687674b272efbde494276fadbcb5e2d1935eb23a898d422172a65872055460a449530270cc142d3d152ac9957124a5f4f84b65fcf57abd15d6daf42ded012e54799366050d3a70763cbf7a1eeeb4d65a1a57dede7bafb5eda4cd9353493078d2d31fa7275e9eb47ad2090a91277d03ce8427bd43e710f0a47f0041143ee9223c8051a73ce9142586272bf19a3f2751f584b53e86588aa64811a15264b3584bbab5d6bef0f6de7bb1b5554070dfb9ea5465e549ffe95cadf2a493931f404ffa25c14306a9146a7ec450021b2c64133153ac30ad6c44f0aa9003138a29cdb08915214c36616d3dbe3dd92405275b821d617614297104486f00b0a89f8db15c22a9a2a0d8a16a55c6ca8699231367b670e0ba51484eb02d1853fd02903af1203e510059514b2ac4c97204ca78e55cc2e62cb2ba1c749c99b02d073d2f358e8947de32d32d071b37e62053e7aa0b37fb8229689aa45c81b1528597a2b7e620d4130ad64d62e3cca2759e493469a4a34ff5be006f16bb0e2d9965550231cb2f068a313b5e5afc50e5088aad16c533c21dcf9fb4f23cdc97cfdbe049ff400410567792a49351348a3c79e38da0161fdfcc62e346378958883fba6591f272b0e847e2d71aa276ae3a0da33ec45b6b9a1bb0fe0c9e442f184994196f4d79b590929002ab23c1ba075697edc53daf0a49b4e04578b1905ad2da1cd56ff5ea73760948f41e3b892518dfb66de3bda0449776c4f8d65e5cb34ee21b5b57c0b75babc1356858c0455194e8cfb35ad22dee276d639dc736de0b4a3cf68af11d317ead3611d49abd454001df7eab3d4001df0af8bed53a7fde57d7ee5a315a4990a32b294cd657aa30585ffd863036ae733bf3c79ea01f2d87d147abe3d0f4d64debf796717f8e6045c0b010f025afeb8ad0b9eb72b9ae795de6ad43e35c12d8706f1dae8fb0edf6629db022a9c538df9c6fdde0d97999975ed3793c9f2f36cd6b9aa6699e6debd038d35d3609346e746be3e4d179a5dfdbb87ee55d7aef889d1fab07d8ed123c72ac9cb4baf5dcb8ac3dc0da3a753edf7823ef3e99ad8cd3def407e63f3f0ea3394c0693fd90083e6ae355226c46b3c17cc7673698d78fc96e3cd88ec76c3c1241f407ffdc5650613a8a6c3958f376fa93d47a7bf5f11ee771eb34ab4bdd7a8f2ddbd26025def4e7961845715eabd380579d7cf5f62b42df6ad5e0c623a1dd036bf248785e892b87b2560ebc14a44fde9bcb5158bf8ea23dfbc90107bc16d403949e79a5e75bad1a943ec21a30ee7204c627f3932dc89e6f3f48bf2406240aeb285214b53954b77d7bc1bd79aae69ca6349ad7b6367bdbe004f75d24decdd0f7a6e8db2dd0f7ed65d6b7dbe277e924c9f4f5eb9f3bb0f6337db9362861bc17fc084b6121dc8cc242b0971cc7be6dd0389cdd7afb680b6182fbb57ab0cefb10822b84d2db4bb7366c82fb3604eb72d3b38dc7c3b33ede44f4c042b0de370f1a676b975f1be9d6f6238c021890e0f6c02870ddfa6dc487cedddb887183ceb5635713d0942dca63dc63573d47fcaab9d1b1a7230c04b2aca3672f4f9e17948a3f3cfee01ad1f54f9f178c2a1dff0035771dbbae1f80c1f74d04a4671f3dfbb5f9c67b49dd1e47bca12dec29bd5eab48f8f0178415ba6c79ccc0926075238d96330f477bdd78b4db2df3f9226dd947e0a804735bbe8d3f98d2f35ef9f57ae1923cf3a8f4d7b4b97eb924c79f0817dfdbdfd543f34673cc414e1f41e8ba03420f94b461b57ae82aa5836fa009fddcd3be4ac727895da4e9a4adf4b3341b9fb6f256e2d35d6e6d76d76966376dd75d99bc89003bbe9de08cd2ed5c8057873183f6ea15dbca8ac36e6d67c56117daa91db0bfbab1f3ee1def883f7cf87b47d34b3faf77f6f2f4eb4d02cc7bdd789d5d2ed3747969ba4acf364cb6df0f59a8c2207dfa6a9ced71cc30a8b4362e57a215e183a5d16e1dc1ebdbab97b36e1840f9d3016ecc80741eced67b1c6db6e272e5909d745c76323bcf9fcccea3ed64dc939dcb39e7256903c6937c75c05e73ed18e310c6113bcee3ed35fac6184d29af7bddb339a769efd5ddb82c2db6f5946ecb3177ffc829413c12c1e78da0123f671fd1ce4bc1df703eb711b5ceaf60ba8f8f8f8f8fcf6d04e97df31b94b4fa75583d61ae0cbbd5da81e7ba95f936a21de6d95d36988de7ca5f612396a516a83b99a78ecafc4cd3ea41cbac8f6d443bafa7c77d7efc070411f0ad04ec2d20b1c37e962346580360cee33b2e8bf98e9f32180c16bb79e360ee418f68e7f938b622e01bf63f2724fdcfcfcf4f9b4b4ca27b2de1df9f1f144c2998a6384d05c1c10289dad0fab911a96050156368a244845413198a523a4855cd50947252c5432dc14aea89955a948202c44a9522a678eb2dc840df8fa89f3e16a5e03cfd02239ce7e9249820f2a79b604e11a5252318dac481b13b3d77ae7dfce9699a3ffda7699dfbf1d385cef3c3e920ce1268fe3cfd2c2a41e7d18cda36b70727cbb08414a174d883f1f3731bd37c02adce2426a163fe3ccf73e8a5e40d8ada9f2a5507c79fe7791ae5f184b7e7799e33a0909a01cb5fa81fdd0767d0ac81e1848a19391a8871f088dd6e3f21463a65827ae3d6e8e31212201e83778787b61efb3c26e20b601f017b0742400299c718888138fd00c2032f5b1efb07a60f634fbb3cc6279aff3c4f5edef0e7d9e58c882ae5c50707e35b9f54171a7f6f116fa149317ebc30e3c48d89362b9433ae70f151c42a21853585661b2343898a1f5451707a3c8fe63b16479a51546a0b942a292e35d0cfe9792fc6185fa5f0d6afb55753de464992d2b265055d62422acb9a9b35fa065cea1f4048f1f87dea1f74aee753bf40e7aea73e429a9e4569ea39f514cca769ea0e483d298d067756a64b6f77c7bcedf0562a2985b7fe1a5f381509f3ab58d6ea6cd3967ba35c5d0b349c88a07183c30d1c1ef846908b948edf5fffb9523b4efcf554775e4cc385b7298aa57244fdcdc4f1450a73a65019a2e54c96db49b74999297f51b44590aa459bb7542e9a9ca84e284101433857b5d6fe62bc456f189fe78a3a542ca668096af0d7694254465dfe42c1598c8b51a856f87801e48c0fdf18ad30bd4348a452a64c151986543a9e87cb3589d54dc72ba3e95a9e6a440953153951a930114b2fd365b277ce1ca7345729c0cce81c358090475238a2c4c910090bda456378b4f6de7b8d50115e3142384337357e55280c7f82bcc5d616e9f1775804cad0080b04f85d343ca214e52812cc92f4ebb911e55c610a0b700702a6805703f09122840f210b356240585ac831630a0cc41970f8586bad8d236f6d0f2802f4d04aadb5d6cef00c20178fc45eafd7c28876c23975185de9c8aa533ace0c77bc2055a776cc79251559255d69984a92610a0f276f35bc9de251e6ab70aa470b415916b516c984ef8a0552092c16476ebc6aa090c384871c40b4a0d65a8bf179e278f34bda22642409aa81ef8694b716870b6f87f5c3098508a9095254b6a1e3afbfee940d3a7f69b55b03068c31a651e54a0d207ffd75a79050fca591586242850b135c804f62da46cdc53dada6ccf0e1c3e742132e8de4011e44ab23252554b9aa31bbf7de19bebf17e319c0b733ac7c38a7689800e5168d76867a05cb948b2139cd474e7a68a5404284852f34cc6ba304c6181b7d696a91c4414e8392c4415904b9189dc0534f23264630a47b558879ebd75abbe28793a91532e45c86229df01745511c8992c248448a2108137a5ba64cd832558404caa94294db210acac95598a91e54763c9ff13c9c4f0d302518b93aa1c296a9136d862a8a1703d0b23a93886a71008485f7bcf762dc7b9a2ad1624389201a4a40096142c570ca44140e2e6a2190460c518895376d8ada171bb19ab7a8b553bda3bfb928e7c71523415440d1e349cb9031f9b2e4e685265688e8801101820506151f3440eb8fbfe8c5f706f9f17618c4cd5bffb143214ade6219e2e3321c0267cb70898a0b7d7c7c7c7c43ebeecec747e893b34f9562def3c6b823c990d950c64555192c3de9f84b8192647e540590f285ce8d1372acb0a455b0d65a6bb3a4705969fefacfd498e15f4f698e47195926a06ebaa4470c6baa8819860080b53052a15418ab18a000804e962254d400c1123e498176e3cb971958a6beb02102834215305959c23001a13b809326366978c89151d4319e87fbb9f75e8c6fdd32870b98b75aa6b09abccbefad6f98ea12e7adec6d3de1ca94972c0d50241e5ba8fcbd9e5fe90f4dd7537110afcc506921f2d75f776acb097fa39686502c74f820d201731bc6bdf73a1df98b31c6b7b8e56dd6db2b516fb17a743085a50b98a92c5052a6ae6450998090354b3e865873921a85d7f8a332b4d242ca94152e528a413c60fc001e2adc5c31416403e7c5cb068b2a49c5a92a73781080adef5c8b1e29f94ba50c0230da421334415f150c45aa6a145c43ca1415151ea3b219a072bcf1d2a372e308c5e713a2157a9e5662ac3532af111918638cf5b74e59fd0841ab5454ce286121cbb0468a3e81676c42bad74e4d81f1d8c9454faca5266aaeb068117a7902801f616404f1913192c4456aa305f4c458c5df7bef940a167fef9414227fb5108b16882df0daaa0c30aec080c38a1537655ab8eebd4c5e0051a9989c99f224ac03b58486d1219e7b9bfc5da2354678854a930b45a714559caeae40c085a296365556e821431bfddc7b8da0f9abc445152a25603c2c79c1c58415a20c314a41a68e8adb2c2e12292355628e0c31c0913044242f002179923b8100aa2449a2087f5e80d1468ac798157ebde2a984bf17cab54c66a28a08a12a02870a0ac400b3e8a0c102c7aa4eeddc7b9350fda57a21eb6d162a224cb2dc40a96050c2a26232c2b23a13280030696acc88d20288928acac44a1008542a8b292f07cfa2d3282f0dd9f4781c25884768c94083468ca3227034c8f5de2275fee251cd51076a9a6059c32383e11a2b29c0e0d6ddea493251c546cc10a948d1f336f81958661ea7247e8c319303c8130e374f744c2768bca1a2a1e5c6479be0832b5ac6ea52e558e2e1a61d409a810e922e67844f296258488a62aa5f0c7faf6035561c36687c408c8c7c39c34b7dec912d6f53a4804595c28d8862f5623494f1d463478b3150b2bbe408e3159cc674c0a8c5d6fa586b2d6a31150aa39a093c920418042a9d7638633854e341abd7eb9930064d9ba317ea8479711bc59dfa0b542a41f4ab328c7af3aa52268a43292c0b00f166300521490c5d6260b561e2d22760b7b20802814a1845c1c110cac85fff09760ed726319450b29293d57bd225bc4c229020d0245add590425756d59b3978b5657a9845c8e7abbd15d5956575d2e24fd5465d5ba977074d755eb807a2e30ae13adabae5ee7fa47cf585657774a4948317e741911d39c251c3e4d310030982df0c8636c393429064db85061469836716f43a00f007d34f6e4efe101fc9e9e1ec7d99e5b4f8fcb2022890854921c0f3a12bbdc833f20b4f2d18832630b9d5d09f49e6672f73c77940005b56368809ae631644e70f12d818122c609ddeb89ba02958e3a8aa040e9b0d2015f22172ee00c619a53c29a3a172f49732f6ab5c11d83bd5e8fc5bd17bdf75e8c5e1b3cde4ad930f3d656281b6ea66e28718283c55beff021ca5bdf008408281c72de3e81fa4d41e5885185c52d1ecf3c9ef2a0cfc3e3b89187c79948e1f1d65acb53641d8742618c318a4631e16f142d7f83fed2a2c0f9eb429d2b80a32f2447304633943a56881aa463ca25446e50b23cbea6921cf7decb048a52171d26c83065868d933633c0aa13d53886189fc8d160055784cce83529ca99810e4e02859f58d980854e4046902162aae808d9cc29e61a8563e8419f2793194e3c76ba35ad6852305992a2c9c5093f394c625214a5a345001715e1a368c790ab2d4b4864e85932037aef9c14de030a93396ea030a1f304847598892223eb480b6796e214a971bb75a0c87902c209531c8c51198a9e3091a10a077cd1a117b6f7de6b514b46038a49bc78b28465c21c21c2de967947145bcb244e93bfc3e18f397155d2e43c6171d2d1477f838021119c58198205cad21316383d486498c0c1612518bc29ee4d539cd95255558292152c5c0e77003df7d230fa8b31c6e94551a3346ffdd616433278a8165ea440b958c2f201a7504536294099095267cd9ba4a62e5fbc84f9d2c38c1b59545186b40313c5a35edb88c7634f510e305071c3c51016b6864cb529a36e9c484f14b398f2d7efbda3cfea4ce0b8e3b97343bfe3a99cdff19fcea5bfb3b3b343e600361020550583b7f6ee78d1065fa4cc910cd04c56243ece138dd2017454076b494a9326747c6cc81cbc7a7bdece220b1555a31c7b3d33074dd3f4114cef40084808a2e34d3781b90167754decf57a29ec4cff6075249458a122c3d58b21327eeccc356fba07566f9aa6d3cc22427404af6cb161a3b4333d77eef5a6a771def49fced1de3c8b4e2e7fef5dcac1b183ee5dcf565777c3e00bd89ad4e8faf51fdf51d393ad476f6307ddfbf3c6cb55ffc2375e7a6bdef2b60e7d8c998224014316e24c19b65055891569a785f40800b6c4864a6c9e60d0e0d6e18fac6a35740149b502a33804520605fe685e2d368cb2a208092303500d0a854de2bda76916abcc114cd9914426c998233cb478747797a4c5cd2c8620cbe5729d2e978f605d2ed7d30b4aef3adfe572b91ce7f20f2e07d1b9a177b9075ddee51f742ebf8be672797679dae35dfed3b99e772d8d79cc04634c249e49c0d3120bbab70618c2f49783bf17831f90614ac4c0413282c5a3c6ae7d27ab731dc3b7ef6c75ae1675ae1ec5487d4ddf9e2275ce7efbce959ab351a2ec5c7dfb4ed58e55b186f8f9b645decef0db777a56b782291d2bb0d99243a5b46bdf29ea5c87f9f61d5fe72ab07335b8b4c344e4db7790a0716ace16b14550d44ce77cbc1d45b76a089f6f47d19fd5891802a1aef410f203eeda5160e71accb7a341ab2301e3cd0c2f2792e07409eeda51a6cef5976f47855657c99890f2e54c9d36549076ede8b073ed856855ec5c3b7a85cea8399b23078af4eda8111a03f5d5103ddf8ef6acceb6458b86c5acce552d1f6d3a07dbf2012b52735685550143f2ed3025d852e7986a089e6f7b04037efb0bcbeaea13253f56d8f2038510ac5dfb2bab73dde5db5f5bf5cc14b089cf4b535471d70e2bea5c631dc580f96c7c3b0ca973576aaed5a8795d7dfbabaa86105a5d6f6d0dbffdd5b33a98d58a1d3288e0b081c2ae9bcbb7bf8eac8e8492551d15aed47cf962c2aefde5eb5c6ff9f6d7cfea9ec90992184ea8704ab26b7f013bd75a824b2fa6ceb5bf909c716aaefb9cf3eda799b3cdb95543ec7cfb896575dd7efeac8e84101e4d4f525cc6906961d77e023bd75775d8b94ab42a76aefdbceadcf9b96e6afab1fd34f2d510e8770f87a6d0ea5e328c64c9a01a13e6c9aedd1c76aeb37cbb59c4b23a0ca4a80247061c3f5f985dbb99d5b9c6a2d5a673b0ad399d2b52736dc48889e4db4d257389a986807dbb89d43ad3d71c463329cbb5651e657dbb19a375e9aedd75a5e63a47e770b95c56c51a4268750d040e8b7c9dabc0ced5e0928ba973ed2e249deb895373ada255cc31d3b91eadad1ae2fceea3a3fcb3ba34eba98a88982c433abbee2bdf2ec0e2140356971259a6ecda3353e7baf8cd8218475ba4a469c1c6c5ae3d0f3bd7568856c5ceb5e7ac464dce469de3f1f69c7d3584f93d6e6dd52d482caa806b56a408b36b2f879deb2adf5e12ad2e04232a56a0fc882334b26b2f8b9d6b2adfeea3448e24ad365a7e599d6b2b2d286db6a0cc298bd4dc78e54a89e4db4ba572a964aa215c563762758ee9489930533c843cd9754f7905a0596af2e3c69a3745bb7672ab732de5dbcb9ed5914082412bcd9826532b30d9b597459deb2847314adff0db4b24f24acd8d4d4de4d5b79355a455e76a0d91bfc721390476ae0697482625df669c9a1b7df898f39d77edb8cd180cb66360372005a5a32a2eb0b0e6cbae9bf85d8956edf8aa73336a6e7c31bec048df8e8d3ab7e3edf808fb6a08f27bf4e1eb254a0c25c4600184ccae1bcab7df2209251f2a848103470618c35dfbcdea5c3fd16ad33953e9dbfcf65ba4e6541047a973a6b7df20ceea5cad473dddf3ed812e3fb6dbaaceb9bcdd12ef77087a032904b132d262899025bb76f24d0213c24c790346c6139b5d577d83e0474778824d16283176ed16d8b96e125cb24c9d6bb7483a97e3d4dc03ead41c339d83698940e286140b463ba4d49091b16b6f60e79aea3b0443a4a4b0d142131a1fbbf666ea5c4ffd881f6054b86111650e8e5d0f89564516dfe5b7f78c9ad34003a46f6fa3cebdbcbd8fdadb978bd03cc920b2300316245976dd5255ab4d6d628289ef2235075471a30321c9298d415b438cdfb63d033537561c92ef7e374931c377477d3b1a39567c256e787153b40b41e71a8a04127189471250858ddeae5d0222b48f5043d4e6a0853a3ea0881cd5d8b2eb271238e6c8d17a02d324c3965d3bad73cde4dbddea3ab872c6a742081a265676edf4ed1f3600d13911e6d6ec361b9acd349078414e5147951b65981c697a5ecae48786186b0410a585143e868879f362c7cbc2e7a5b1b1480a2121578c0c83c6d76a9e61b0f99abf9a6240f91a0d96c60d9b172d0ca9a82cf9a91d0909a130e36b7e6b4d28b8f95a5af3065fbcb2aacd6af1856a330f084f2059c1e38a0dac1d2f55f23c9aa75792866ab57e8124a2361b9a2d49721312123ac1cdd7fcd69a8e9c7ccd5f429568369bcd3898cd6638c408090909dd9bbb240c5f8bf2352d5f6b3ac185af4909d58866b3d9025a5c09a95a630289c58ee73f4bf23c5c29547d06e6673ee4676da8569b1169d0e04247ac369bcd66af59cd67330731f33a1b1a67424d2e7a5fabd5cc11f5b108f514a07e01d43b807a083a377e79d449b07a1425a2c40da87f00e181d1a3281005a228eae99747d1a127ac192f94852a981712226e41f335bfb55aed890b93af4dd16a5886ad5f0fa8a557a58aed679efed084b4c0f9996f986d61f233efd039ff309bcd66684d5765456ed06c31d9e88204455114459af3a8d04da83654ab8de8103ac30e23348a73a850a07de479b447bd5a1d087ac080c30b94ad1e515023a80b45511445510d42e8108af6d355160c88459f905b6f9f25b235b73e66696d6d35bd057aeb63d16a60128ec39138e7ad8f56e3096babacb5d63b603d0424a879eb26b01b705657851f40ec786b8bac85b2c6c45beb271c182fc4c10b0909c119be90ff08396ddd782121212121212122d14d95aff9add56a9eeaf89affd4deb4f99a0b752ebfd76a40a09cd7e05783069f539b177e6868a8e65fab6dad412103a7354d8ffa0fea34178fba10eac426864751b348eb859fcd66fe4ae3fc6ce6a4a6c8cf1c3577288a5aa1b4049d1244aeb0e0b4a3086cc4e1ab09114d22d12a6b6127ad158fa2a8908fd65a1236a0ae60c028d344468c1dcf9be979b8121d675142b56ce6e6d90c8d9a47fd3aa5717a340d0af2f4cd07f97c5050102da8ca5a2a2cbcb541251ea38a70fcac369b459970c60044b42406cd6a905543b4aa592873aed4ca599319560405d55cf8d9106c06865844d11a1414a49ff5fc6c36e380033086d4695ae1850e160c3480697e369ba1a8901921193a72b0ba5025d9f19cc8f370e6acd6940411895642b5da13243f3bc0cf6635ab81244c883e15e8cc91b3e3e5179e97bad029b59b599c413df16d20168140202020202020202038404041404135a0a05a505010105010105050101050501050d0871ca479eedcf9b4a838273c8d46731ccd699d439de642348fda02f3b6e648392db6ac7914a5e5202f4700868c144e70b3b505cb120a6a40910ace60c385d190149dbdf016e866064d2050c9fa10ce666cc23c8aa2160d3a41180df9e10211cb0f8b90e7e1685680822a10d0b8e359a04ca32d09c0cf4615252c7dc95251a6878f1335223eb942676a051382003941d1ac24e5e53f8b1a379e47a751153efde81508880d8d9f61f0b3d94c840936a86815a5aa92823e48ca38cdcf99cd0c9ac099f34ca0d20cc8ae491a40d49a2755b319d059a7d0803e6c6dc96432994c2693c96432994c2693c966b2196d36a3c96432194de6333f6533998c26a3c9663400c88068b319108d2693c968b2d98c2693c98064b419108d2693c964b3994c2693cd6632998c26a3cd642611ebc7582ce6381bf30f203cd0fa987fd039d8c762b158cc53a68fc56231af4c44d479d47f5027278fba101ac5e4c6a33814867009126ba396d0792b1426b16a7a21809809346166916821009da1e859a73c1a6234f26366e4c9ea88efad94a823648a51489c0a109b8121260929f6a45019d3407c6237804ab39b91151e341ae3517151220e94194fd2ec78eec2f370b32b25945634003a8b1d31a184cea28a18f9184a1b4263b3196e26b071238ac6f9181ae3e0888c2a00089e4c57412050298a898706333486a2288aa2288aa2b1a817c0bcd5711545640600e4888241ce0086c39fed38a5a15253e263b1183a8bf53039a2d25a7ad404cac8a0ee8c0d1b51c214be133f7eac0c08b391d65d2e3e948c2c0c5a580183261195c566327476cd7400a348245acd6e50868a2d488ae291628d0eaa27ad84ce64b16b668890d599c098cb501a07332fb1588c76bfccbc76791445514f4b3cea3f68138baa473d86da8cc69454415de6276a3383329b09449d670295d0173e168ba16e39b0d6da99ac69050e19ceb23a93c8cb55982d5a9dbed48925b1791445cda231ab9893310987523264fcf5d16a1c4ff858341e8dbef1d794820b8cd0811090b0f597e7afeffa36e0ec07101ea4a0e3af7fb075b7ee8d11a5e1afd36e2a48f9d96c36c33f9b11a55450f1b22cfb79990c289582f063b1580ce863319f0f8c021e45631429a0cf5cad378b8a64276231d9d5029414b9c950607a144579556881194f3f7a30fd3061a20599d4bd33994c0a851b4157863acd108bc95e9c79144571286ae38d2cf6a2070e5a9d4924e2e08fe33e80f0208a8ffff10f7e7e7e7e7e02a732a8b40bda4973162264230000201000b316000028100a0605837922877914333b140012659650625a481386c21ccc6118a68c418a184308010303224333db20008032b7768ca40293067ee7be08b5c69ab8e5b41656de253368f53d33c1b1157f2b8b552185f153abba4a5984213768f7ad618ecf95407e0e9e59b1056e0fcd10859fbf50b4b1326ffe9627a4b00f379e80adf918894bcc8caff58776dd18dd2bbc25e1b414ff0921983459af9c22e7172f3f89078ef640e3b59a4c9114e8b505f2cfd2d2db444130c1f5440de323f4b91a588548a43226cba31056f782447fd5048abd0ddc7c80484c590a15105532532dd03982ec74b5f1764a395b1e7dc742a80bd0180bab9e5f8c6e4193777790d0b0644b1c9abc298d12e70a859532e0ee9a810a0d8e1f7c6c68e23f8f810f2dd03eb4206af1e53c6a1d9037a288f2b8e2af821264b217c0d8879cff8e9f286e4d69bd61503aa6ad73f5a245eab3a626e3d881309b671bf4c3fc4bd1b325eba75100667423dd920277f5f55b4582f15e62de89e8f7c683025d4c60d1fc443e196d682376c47acb0a097c6e30b9c191b20b3b8b663c217281c5b7c6c51cf62670bab6afc38e4367bef2a39da17ca26d20843ac9b30c7ef5883f17550d5f86d68b0903e0722fb7b687362e3948e820eb83c0739b1fde198aae2ceb667ca837d08925efbec0ef33eaef7b314d5ad0b18a99234c3f28d7ac05c921129db4d06154dd8f8b5116bd7d7361921d5cabe981a8e97cef501b59a6e5810682c32244ce4259cf540a2a4e7751ec7638e25741328a36b384c51b43011c88fcd64bbf193acb11ac447e64f6e870d0c2523a05196b86b3d4859bcab361766c161a8e5299e78f99f8fa084709efb160f4d823a18bef9d4c9ff4c7016d21a4612429f83aa5909d9de4f17a5d7bb2a5db96b6d72ccd34f88900a1c50b5d9904501a1bd08f3918d028ee13b34c50c16d03b09a5984b77394397a6f506ae0508f08f54f76bf38f0960039cae81604fa012fc2fab8d1ddb5a532d062ddb4b88ef576b3430b9120c44e596c3fafa13e937fb731ddf543e0561da260f59d60be456badd044cdb2d6d6c83b8e41bfcb88a17fa067039a2ba532705a1c1b8d7ca2c5ef6f51c1001cc1d549a0a91986e08bd9d91b59a2f9707ab419a31fa69225ce92f4a969497d995ee4383a2c69fa4bd45dbb473acdf5c2d824e854a7f215a700c19ec1a2d1fb99d3b59edac1f6fb6fd806216589f70d26dcaa97b78837a1b4dab21bc3daa49ec1278b05754bc54232b4c937465ccf8017b38559829bdeac9321dfbb7bd9ec578488c46838ce17ebad31c54a9f31bc392a19610b20193e98aff6e8f22c001ba3d757c11caa702067e4cd6786b9693a3381bbb9c029c27ec63e8ad3a6b3f7366716276ec28c132744787ebe9eae322664ca3678565cea509a4a4643d68b606294359bf39fbe3c44141272568f0c446c032d958d1d598ad3863c88c1f244b428ab91fdf66d58a0cfb78c5adf580aa1a00cd27663c4cf351a154b950d7086b9ecdf83a277da2022e4c7e5df9c499d90ff100242ba4732fa3d10930432210aa03480fa6b7e28633707a5ee081ff11b2dea9018dc92d96f3f1e32c48f17588bddb93f10670b5b72e50250d630cc07f2a3d808c4d209a3f18ee63516a2122daa10491f7e55f0087c52c634758a2de09e2035ec2acde899aa385f1de0939e0000d5799438712d92118b14b877e525230f1e487c0798ce4b34514aadaac29549025dcb525730a62381174453abce145f9f269d10eb72f4d5cda80bb8f200c9bcd5507ca810e212f576ab96d7928a99511eac2e8ae3e18c0241f139bf616b447589995521e375340b1ecd5fb7e4a146e236cb12fd4bba8801023366b8addcb2c1287132c4f028179c0d00db0bada2c7232c6ca01ab99f7df36e57b64485ed7b153edf68209a5f47232370d5238628e740c6407bf6f08816f494af13a8ce961ecdb449a5bb55b84b005b93426c1f0e05cba90a5347fa248de011aa42efaa550b0c4425c8ee4c43d1b799461ac6b195c28c07052c8155e44067fbd3f764211fef2265d82297f6ec5e9885866b0376aec0dc7cf25f192c203df9d6253d233cbe842346617b682e6a3a058190a35667ea7fe67da678e531bbc690401e879a81c3e3598e3d48a787e3ba30f13b62c16415930a2eba2e2568605d5e6b2ebe839b13cc62237a966237abb5855dc1f423d66a915b0cd437637e8af47412b60d574e46241622adbbd647aef240345813cb055381ec868f2ce6b335d2862a08dea9413229e1b315a13c159e02d1084d6558e6863adf842e2ea36825ab64c617616f422fc56a73283ea6c9d21a88b86a488e65c3d534ee162ce47ccc1cf72646841b644de6935ad676b420478d3ca903190809a80e16b123eb0097a56fa2892f125d91c57be837d6b318cfc0a6ae6822df84a97fe23ba06bfb0720744b944c5804b4f846be898361010b445229e1998894eecbabefca0560ea062936e64ada2a55e299df83701de63a40c8ab5634d26ff9a4e47230c955db234276efca1033ec5d156ed61cd23230f848519632aa675e7cc9d384cd1cb0219869d7b0a859a9e55b747404c4a86cf062965e2ea913afb11633a4d68cdd2bc86ded0aab1ba2c76a0a4d7913efc5da103df876e9e4be39381f714d6d8a0bc10114bd21ecc8bba1daf91943f47f5d4c6b3f0b94bd26cde2368ad4d0625d28249f6e6e01aa4a330ac643e52f8d8217a7d1377481c4315abbb4986ca9fd4431216316a9c09712673b93a03a37c119c53f8676191fb372f33bd9f4208a241597526921237017618d957d9ed06f11fc0a6dbc08fd06a2e4ca6b886aaaec9980174cf48ac553ba9ba72c402fecbbf0c3cf42bbf1ead751cdab891520f4e8d3e23ef03940aae4358caa6c8f409e64ce861e1d95867f68eb8b9ed05393787c55f94a53a2f12fc9c10880d699479e824a51cd3ecbb8d31deb28658614a67fa104e8efc16395542e4af17d4ec2532c8419a7a26ee1aa5c809f8a4bc4dafa613afec55a78a489f356e2597a02b49129832633d23e41cb8fe481f8b34619753577ed5388fc8b8d078ebf04264632c782040315d2fb94934270a8b76a7ecf3facf5a366dd20aa3cdcfbf1cd474be262c6821dbaa1984ea66c22b76a4b17aa7d9d1c16a0f720d6c6a90a544292e383b59cd6452c0d7947e13873edd8cf2344cb0ef88f0d28b0d533c6a4127a620d870e13fb81ee76ba3735169675f4b3183a8eba01cbd5ffe3c4d23510faf6723d460416b0b5391b48cc0235fbbd7777ce5b6da91ed4d0de6149e5afd80e20fd53a0c51a7654947dbdb39e2da5152fe07ad15bf7a4109f2977b518a395f23481d82bf88d7a91c5ea30a094320041b89570ca8baa48519db63b1a88f2472d93b497b26171ba6e2dc10e0837b73120493d5ae8b908017867a192a883732d597d63caa529fc1a7e0964e4bb78e0631116d331b05a9e17af8b3d24c3e1a8999f4cdd9688b259205c7ad8cde142da13f1bf7b2ad38daf6e9b89a8ed3d7e8cc3bf38890514dd9746e31e0067ce9fc3dcf85fa4e054d43db972db3b7175fceaefc535cfa19fe5ed615b2e60b3c9676be640bc94bd7abd8bd455229b391ccf31a013f35d092d5831cc639c22936816a46648ccd165758305954015127eef48cf08c775bad227e697de7d6f798feba4a958b2c063ba14ed02f5e9dee3818c9fe4e107478352f7fed185acee1d76e1d428970060ab66a2975ca326142e45196256149dc1602b6ad6c5229f715cc65d58a9a591edcf0bd7fe9a77bf0e1ce769687469c86659812a1d13efb9b179f7b8fbd8905b21c5adfb4961ed081d7ba3c83e4dad4719b675b7b6124326b79309b37e8f0d8d0e6ce47fb8f64156e457ba85aa42102b08bfca87a5774db7a2df0156477368d4cc3a5baf95364592d018dfa86f38203623251ff1738bd6cd9b626bc26837da98416c6cd8d7e3a6db082e164c438f2f0eb945c0fccf4a05a4227f06c58109aaf8e2ce441bfa412a4e1da2396d7332416372eaf33a4609298a8718e4965876b1cbebfbd5b5bc53305e4cd2c9eaf20ec72363b2557c5e24e6c0ccb19807aff781f264fbb0a9ea8c525d0e116fd19b84a403e63fcc6a0d9c99bde5cadd107266036c9ef65a569f4e3cfa4899a885429c40cf1d513d9f80fd1e3f7c630b70a9b1f27a4b3e4813d5302c2becc4520632df599a1e9cd3999479c2420d46bd64eb53ed0ecc8d8c8c42876bb78038ade08bbfe0224fc52e423c335c1f3494fd4cc5becbc6ae24d6f1329be4b45c207ed3718358d03047a68eb772af6502c9cf002e890c8b473a5db3ebfda28f26f59faa2e64fec3f6b8a062c36d3f1e1e70863c9349986c208f05e1025212467b3c2bd9d57adbed0004c31b65a660263e76633916cf4667eb1209334b875106302731e244b5079b8358721ee128e2c88c50f721c064ebb8dc50f9805201806524329e4d149cab9c5cb29b8ad9d90724118944f07e7b105594e81217098a8389daf4e5f072f21f0e2f6e5858b43017cc03ea17696a34e94abb241fd58d787740f65de9748b8698dfd8b210226979060cfc6f5795f163f1b58e3a6a4929805fca4d8d2308138fc72e4a1c754877ddca18d291f28fdf7faf3c4a722b479af280ebb275b43a8f4d2038086f3a056ac76b0d1558d1db6f6cbe6fe7d1e779ec81cf544c99ab2aa760bd9a55813765d7f2dcd98ca9a57dc6309cd61059d7165287dcba32f49c2670ae1a90476b29d96e42e63d88b57860eb862bce1d2ce868c9b3f5eded1c09c57f86f06b4031ed93cb158b55b7f5e6297b4e3c6ea382ad269a09f8ba395ca042d978eec4c40697b133b97f3df13e085ebe3fabe00e584e1d4fe942dac4cdbc34413a689f3a302270a08bd171544173163c8ddc99b637f6279a7cf3e6763ca2403a9c614c9c5c582aeeddf87d6caacbb09fa826110ca6578f970514d36441dfaa6c025d6c4659f75afef2a19a31f2d2615c1fa5eeb32e4774f5d7fb0088604244cf63bf72fe8357cd5ee3d40c94477cc23600d128e452ac1629bc4353fc9e98d87e5305cb59596178c11bf45f64dc420441ee45b9a10c25a00eb5bf613d9d67131c33e743dbff319ea632e2c5e0199241cd82eeb98c6c85e2ebafc5807f3ee233119f988c7811eb4cba70d5c99ba1efc0ec65e8ba43f794bf215af33c539bb019110c6146248bde22cda3dd3f301d6a32ed7dc1641213e8e14f25a7d0ce45d6287910f3eb4731537ef812880f96c1518a8803a35dc3c8c584ab583391122847be6fd9726805ddbc1fbf9891f200aaadf2963c5a48c989a9be3cece59e19a62a609d4b22567f980c063abbc34421c0ac8ca13c9de0928fde6a7b696b6fc98dc705a5b109c6b0339ac9a37a0d1c19bc8156808187ae4cd920239c28c21b90ff50b42d458086cc9c84231e355c13c9ca04972c9adb9b9d260d5a8f2efcf82a08222deb2f27568eb6981b8217a6e9335a07a65dd5b070bfe8289067ac9d39f69c9a6a40c9047f77c4f604326799fb22baa4e6681a519cfc007fc087297e35241aa88d3d6baa7d5f005382a62cd1c507430e47394ce304018eec860a5b46a4ea909709f3bc1b62dc5fa1afbb761d880e2294394196ef58b1d33338eed8c2b98a0758620e7ed402410c5aeb855d15dda13653e4c03bc3ae9bde155289f3111337ede3c561a2cf4389703a7fbaf5fce5998bbe24d7111a556e404fcfd13a565daf59978f8921991d9c2b8cf2b38d0e88be10c9cff3fd6af71a00668a04d2cd44122f8b28da489779f830de54661c53da3f3a7954149e099a230e3f6d005a1c9b84c30ddf669486ceb036d64b8974660d5d6bf3dc8e1f4516a8d5cf1d58902c10fd06415a837dfd94bb478e161444aea35241b42f88fa551c0b30e3323406d4c2f3cfb6285d5618572a3bdae233ab8f0dcc7a4044a9ef7f251bc41e0b42650f4ac56450111058c2177ae465fccc75301042708f13911ef5d230e712adb299a410bc868b03853ddd91b47f640e6243460db545a2fc2bac89e19d442dfb6c69c03c21d2ec7ef3ebc2c1f1818b7a354c564d756bd8cc8bea3beadb32b29b146f09f89b8299ebd978fdc9d3c2308164517fa4174d4d07115b047aef3b8a7553c124982fce215ae22a62ce15643b0305f289f564029ea43fc42d05beb4b8148796273be4c638df0406fa48782cb6a9a62d62e2d875d10fb1a519fb14a88afe16f80ff4924d527686714470c6e5044bf48f87d9fd82645eea359637f9500dbfc0d9ebce2658d3bb8131f7ad74108c85e8cb5660edf847968dac34c307633efd1d38d4b200cd80b47e1902e06fbc85dd208b73cf4544aaa9a745cf116d071a6a7d35968183bcf988794e61968bee013ae75a913c0a4a3e4033b6506858622a16d837aed432c68a4cec268f76f0d2da9fc59cd5b640f683d1591c3cbf360fcd37877e2347234fb93b2efbe9379cffcccd624118e0fb10a1fa13839909786e5afacd74d270dd4288a04e6098ba699fc71d989c18322be1a290a0df44f192defc53c1deba24d66fc10ec9a5ce7786421652152663d69f08ba9b25cf0ea9bb18fe0325e2da6b4eb09379b299e2622e3ea858bd6c7b0c87c946684f35be0a5b90902660ee8673180a1ca9215e1c541c10a217d99ac9303cb9583f502eba130064c59121e802dc9a3ba14fead36f7aeb02ed5950b31f49e9fe966b1259cb88467ee3d824d7254110a883e82118e4b2b245a071f89870f42586589494b51803d7e8e57691b7e07fd441db30118421b7347efadf599153f7fa293bca18d7a933e14444251463515e8dbda47edb5450ca51e199e8bba4c71b6b9809329f4528f7a553d6ffe74e629938d5ec072ac4ba8671c7964975348eab88b2cf71ee0c26c1000d5af4fe0750d8409889cf4314230ada41ba759c8371c126691f22d55ff2a8abb51160d81f3e4fd8d2f805eb2d3a71b4fe41ded6914b6be83471865b6180aacf59eeb0d7f7897c9eae3a3b0efc7fff1d15804b4e0dd931934b238e5bb2d8f2d661a0e04d6582e6a78ababba14a85b45358f9b1e9fb00dfb29aeab251c79fb9cca4c9d53f93c764ec86335fff394d8dab0efb756e32edd9260c46cafdede7618a7601da1bf46b005321fc9c48147882f76fa36769d2f80e891ebf7de052f81f98c2c64751cead751acadca417cdfef73c7b63612a9e1defc7877c3fb7980e7f227dd4761fc053041af6ada0c26a75b143820a99ef8d2934d721dedcca5e74c269c64fdd3712862474dca98e39bbabe1f4a32189a78cf6c9cdbcff07b252ef0611b665986bc8ee62257c5cd1fb849c09080b63e02f2d5be1ccbe6c87e360b9e830e6da9252686341a8d477f9ffe947c678115ea28a650c190e12c9ab6558687fa667623d162d3308b80dfd123d50b193e53fd11d99ee817c1173deabed2c0d4cbd85d6fefc49e73b88d84d7a5d66ea55d51fee60442a03959c64695d26d2cc2e6379ff7c016f6b237d47e1886f60220a0cf8c6435d596c75b921bf15ecf2c85139a20e8cc71a8b1bc9e5d82cbf26813135b6ea409eb13662c76c4e88d1d15cb7beb844c60f76828f26e62c7512bccb6b2ff2a3ac9177f1415c27decc965f46760ea12b8c15021801a856e20569423f1238bccb4578a72ca75d3f627ea46408d317809ab7bbb9482061b1073fa778a88c94dbcbdbcb3e75edeca882445e7e240468ffc0a8781ece6cdd2da9d9d09d9097cbf060db3c2c50fc81cd13bf99c791de784a40f9c8ab2a473cbe2d70e466b974454360d68060bba97e5182642868a726596831f162ad2f0eb8267f76774322a78f797f17ab580b02f126900513e3f0dc14f7f61c02dcd2a0b25141d5c8f2a70ab73b5963c074d99472405b89246cdb62a6481cc9ea54f0172a9a4ebe518b592c9cb930c28294af589cc0a4c141a76bbdb46371cf47ca9cc399176a80bda2324e6166bf2bc7c44d69f1dee080f251d1177425c414db435a4631f5e52449e73ee6c4fea0e4f70e423538f4bf8caa5786eca43438d9637b7f94400a91dba23b19e7a628ab5d15baa4a36823fee3da21177caead8a629295e9bbe975b11f3cac825ef932d1d7504d4df9d1c0d4d4bc7720aefa12e41e4f667c53b40e15036d3cabc607c8793b6ee31c512f1709088ec9adb0410eabf02152f18891a0f4e7d6a0e9f2f752d0a3d69bf3cfed7e1735b5993ea6629d147e9f3adda149f671a3f79e30d422936860180c23cfa0cb88528409abb7a5fdbcb0ce5fc85c8f08d5832104717ce0e3011654ac1d8c23b6483d01a6d0cf3a90cf73bf8e88c9c060503c271e3d6cdd586f4b5a2df2e7ba521cd69cfd0fe2102c844bafafa489c1fb74cdc4b2eb77b713a5107cb1ef3d03ea7dc90c2f456b2b40877670bd09532e2913aa002cca5ac503240c14fb08c8528c9ba62c682a558a960ac6a93123d609780e329c49975fc0a3fa9b58481e53cd4805092a33b90054f1281baf175c7a6d3cfe742bff0a0e064eaa8d92abbea72b2a812ff708f3b4cf369d6e344a3d5274a88fbcb933ee2b871074a4952fc4915b97819df0a006673448b272f087534ff1753ea83518b1705dcedd52e560b71faecce685651839131ccedeb90764c159d0f01e6477ac42735ff001918a7ae6a8d889911b5350557febf7d1bd0481c4d4810a3e563a7f7d972c6aca9b8772334d222464d0d5c36e1ba6efb53145c26a7dd96cc2e36efefff514992272eaa92329bb3a4168b8cf294d562ac2254e9cbeea35b5a5bbb436422d5f32b0423c9b093f0300780a5ab226a203c380e36624c00740b6a8aee44028c9b402521ed5a11bcbda75c3419b9f8577090139a295153ea84be60e5ef7f4d32a21f3ac513090245f7c1ef7cd01625fa71f1d867c1ca41ac713951ede94c15d8b2f30761ced66c9b465b72053527c454b679180ea01ea1949faf8ced1b13ceab012655c05c5f8b6e656f58f560a86ecb3605c9c252c40c1507a6bfde2ae87633f0136f5fb50ad877c74de837d9b3eacfa8926d2417505ef18498f25b715f53a9c5420ff0dc0e684e8a32e882e49e28a3ab374d2a1a1059657bcb504f1db32b8543d5e07b57c5f45aeaa8e3079313c4985a1d0a73303c555b542c713a9167476611b7911a2d1100d1b3b6611002f6b5926699a817c173e00010ccad1e1732764cbfd6a20824f1ae4128418cc72761b48c57c9c8c7549428f5aa1dcf264a4afde107fcc814d14b25fcf3ef7b23409fa1b3f8714a0386d18406249e6a6d0ac6bc11c38252c6a9a26134e4f563ca9974a8634c91826b2c2d8c4a6030ca678065f134225a62432ad191c4c10bc76450f3e6af11387c2aff627405d6d733aa5879f9e309462a95722ef1f9534ed39e14c692ddb016a6db5212686efa4d357194cb16fc411f3d8fef15727c8753ee0c3b90b3c5c1da8811b5bc55de6b1f38d83ae801a3ba5d8a33034215deaf8c8ca969e41606b04ffd6049e4e5bcec87b407f7b17296e1a00d085ab7b9474bc8185dce544d6495a69c3ae4ca52c21aabd652369092ce0130c91b1f5ccc5c40b3b8c1c0c5783381cb83318e8a5fc8d014723f6313fd5218e31d857922d41c5dac1d90e3bce8c12205058fbb1f43268e3f80058e8e43a2fe660832668c8b7dd20ca71d2cd3341b03b8926b48a86662761d5b1924bbd123c1387307156f2b1b841bd712180886bb277c802f1baa2047a1d3e57d1ddb789c79fa611db4cea569a26a70568d23085724ea60b03ccafc35bd38e84d09f4084432bf4f2206edd7d1d58db6730fcc82d57e2d6a70374d4f96ce3d90cd3381808ea68e398c565471e0aea43fbfb3813e9c992acd371599d287099963052d3fe55746f247e4852495e88e91df3d46f108e2f1cdee07ca78fc98349e8697d34fd8d9828c4a5217da4c2f9367714cd6e36e9c5307378c842465389cc5b8272b926a5e198c8308acf0747e701da8ca04caad1ae1302b8f93cd535e0a338a71aa5c368e0d83e2626960366c2b6b64a8242bf5016658a030b6659247bd675a0c673f242d905ee9c4aa80052cba8345f8c77504d2f0e7e858140e142aff82018e852174f068ce9d4c2df9d14526d40f375907852edbfe2ecdf3f7c894a97755da362b8786c1c329bfab3dab98df07c19526fd6c67fa0149f9ca051c5006b079776caf8d435b66f2a1c1b815687d5431c9521115f7eea4222c026bc044461b371da704731b673f720c6e8db8c61a7fa96b2163d7f24b57e0a65e39f5043b01220f5d288f3bcf6599f4fb00d7525c7016b4d6880db322f4e00127c71d8ab242700392b2fe410b6fa66f242175e138a3ccac90420c2527b2c09ffa10d35485a491782a7efb6ebf912f89d4cdc1ad4711b248c44d91a3081c04cec41ea576f2820e512db31fa81251e26688a1c7c091884c1611e1374aa6fff8095b3342810abf4723172210139dae6f420d8cf7248fbad116bf7dba60c396f3ad76f859ddf78338543355b2aa5a4233cd90525b0c4925342c177e8101d99984c248090684ca8bc5a9a93cda14072f3307d04e7992dad97f5aae3861c01b43b4f3d48d10166a498213b7d0149d1a038f25982d270e851e51466a35e34f3ad41307d6824681c3f1e4ef5593f3d15a6330316b5f96fc76ee83101611c15e9f0a05d697d71c3237c5a56e46ff6f8e4ea7848a87853ca399948c137cfbb1a66c5969f1b83e701966c1006d1842b5c78847d31a14fb54cfe001c09e80a51c5c8b5354531aecc196e301de8fd7a97a202e1d2c361f359b5acd619d54e2afdcf4313edafc066a37adb9010e75e80d5ba40de489e978b94680b0ea8b01796a8f47e8cbb9c0caece231d25230f02b22a26e2f03f6ff8a5179a799c4314d1df19e57a1e06182c6fc2b1e49250ada9f6f597d7a812e08616f0c4dc2eba2250e39ad65db00746d755855e2bb47669f19d3dc774a1501f09173456fae2dcee8d4193ad19859a32d961eaca19ef827045b4a1b510838b16afd462bd58bca00962ef8f324f9d28be508104f42d6faf13d4a3c93d741318913bc4a5105ddeb4f9f5df51cf6067834182a95376074b2cf43c1e0fafa42229d35713d9f55509dae1e0534a56cb1f3d4f53451ffb07fdb29e534023622a242b0a5bead098ebb93f4e3244c46d7df491884426567fb975978214747c02e6bcce875861f27adc7a54c6c4defb059546719965a22627f3cb1ea4dd402eaa551832ea5d2cf358d3817165423c3bc7cd01f50ea09d433228dae5fb96550189330c2bf6a501c59785874cb4bfba79dc40ff497a07eb2fc8728944582031bbccee2f2cd27cdec74cf5c30e46a08a65449ca801a8b3a1a8ab81651513c5c0947df82f7fe5ea0932d4b5d20a560ec7d58b4f90376c9a85e3d97987ef97c44f4eb6d52b72014728e0dc53480da02c0ff7fe00a4b7b1d848f75aeeed76b79389be595f54742a7b71a14de3d4dd820af4261196dd32f30cdc65ac869c1e036b1200bc61a68afe6da4a30be41f299b9b88c3623f280dcbfeebe511c06d845e5017080bbd61202f995cf726bbab37223b58197927e9e4a7d4a105b785dd4ebad44c1d5cade14477f478f584c9da47b453191d2be6f8c33571786ad9a75dc1deb78ca3b9da041315db3abe66abb95f611420c7238a7326e3d9ff9ff57c457f30b95aa6c6dcac62d9dd14b3d4aea655faf39ea2f631b9ddcf1ca3bb427ae65b6c53696d71d09b38ac50895a15e63058c9b2ca596a2ae911d82f04107d3785e2d2232e49cc57db2b31a38d6ee72032d47b767452de319912e22f2290e1e8715424989e81aef87329e9d3208cd1a2af323feec1853da8202662faf0643a73019f59fd06ee5a9d207acba9fb830ab11f6d028a83234a6fd0d2573000d53973872044ff48cf23c9ec1a302027aa856e09707f02e82407c00b2b2421c320db25df88abc6ae9811c02d5bf8313f76ef15854e9108609509177c33439de45409480a433efb9101a6bf08213349a7766101d0801ca619d7f54ea3051afb2a55368ad0592909aae612981546e82870b09f4160579c214be236c25356670e2abe8caf5cd1862ee6534b976f6f79fc1b329ecddd9cd1d74d7c374d5da358a3af9346531d51aaac8d55e2d9fa1ddd2d52bce2a6d8aa76692106883908ea3d653b6537c76accb0555240bb33719c5cdded6dfba8235612f84c3fd588a24edeab0634f8ea856d3404c9ac40eb8ea1692dd8aee92bd23092057d91dd535dd09e29b16a1aaf04ca59e814985f898cb8ed623d25c785543269ae945c70e60b12a01903f255a793023fa0e3620cb9dac5a6e81778094757b5a6fbea883a6847cf267ce56d31c7b332e4be79ea64de400409f7de484f1ebcecf954126d9365ff829cf97f372b69bdcff4d5ebb356a9db87525c1aa22ce0009bedcb3fe2835b00402385fb5733383ede6efe94a8017d471d097840176a660671d2293f73a0baa09d07dca9a261c263bf6249c014c46624d014e8bfb9985715dc52ce613400005ab0b621eda5325c983aec148ba70fefb44954beffdd201b9fd758c1bf67517c9b09c5dba6fff780788ca17559a2d524d1c9bcdc2943f09aa7f937d7010ab10243461062df560ecb680c9ab86fe70a5e2b6d6de7d104a5741dfdae17c848697c1395fe352c710f412c892f08039e9a83ec71727a15a700f993f7ca3e0a160efc4667762ada6d8a053e37c1ec8a6ca223dcbbcc6c04b914ee9879b1e859969e51866e992a3d40b2129c346fb60c3b85ad1c7f5e12506fe29052c9d4edf29a9a184a629e039fc57234941b68534733d5a45fac8e9a92a30a6168cdbd3624c3fe59d76e081d195b62ef971ed48aa83553f8371278a1a64ad4a02f0f19aaf5ea4a82b8335e3a38d4a728269343305e2a8e77fd1bd89bf89b000e3f383869b6f0496c81c52ed12784f6af1922ca01f34e01adc306b96193247716fae08200b14462c5db602738920307abed0bef0a7144785cdf47a7cff875bb5f08ddeb56e233658584f12053cc3abf1f43c97f0d33a5b2c16ca39a4daa2c04ccad2f6b4789886b6fe6b61cdd43e9da1343c241c5eea5af71451de0e64bead1c678522a62f74e94d0210d17f43c60b727578b35e4205c1791589a0d8b3029b1ce6578079efab340cc9612c28dd273e50cf0c5d2539b6c52388a6cd742f9f90b94bfc5f5cd056a6aad767e72c62725c0a113133c0e30d03a44cba3fa25c91819a42386a0e8be226cb054570383450d881c0fa41fb97f480d518f31f28aa38969c52ac40ba9a2fd38544c2220456d6a0f04144ed906840a4b60b40bff746689f523106c0aee9fa4f01e1f8d0c01bc1a7e194fd9b3e0ae3f3198fa4b117a07425115c601bdd051f18e2f70429b66b97cf0f9d35ba7edd517fc1b5e5cafc86093838af68d0f7824607c38dff865da0bb79b24345303a8f5c70b02d986e3c982184206e4bd60f2f50a87637c3310bf959d9d51672063b69994ba5e939a3d9203e7638a42a36869767a47c0f03f6fdb73a706a90a66e9beb940498c79ecc8e72fc8128b00ab8051aa54791ce1d9a7846628b8e3b8ba639144c0c19822fae2fb4b8559ddade03aad1102128b282d1417645f54bba80dd3c041badeaf34b9e88c9d23e2a36b092ab7d51fb6fe35a0ea8df2b55f73478adf181cac0da9833c186d828166974840a914d94b319c4c96a71770a87bd76842ce13229e3248817b75455ba9701b7a50adf6c955c4c7476a8aa481e356dd0d901f675545f74177cb129e413cfb0baebee7d76d67312b56438ef63a407d7e04ad58623542e4946d9b0591a23316a81745e3d79b379b8d00620887e468737a633a2da2c95444f43aaf3ec2de8c7fdf3b8b7787caf5b4d4a300d2f8af20e073ea1c361acbbd95acabd833b3d4f8ec66a26b5e10de166c4a0d69bd24fb0958faec0b80d47b19a504c68dd8d717f1d6047afd82916c6c0c3033a4db152b4886de6cd34cb315855871573e9cc71006168ae6140839ce85c22ba004bf08b3d67dc5486b09f51875d6fc5eb24bcbc1105d29bb560a9831eef49ef578e4b886692b2c48d42c0392809377c503ecc23beed8f6f023329da3873007abac97528eba20b0d603da4b7b54f409b320fcd9992128fa12a6041630d6d816dbca5bb47d13f7619861a48af404fbf3166dba912ff583234a42a1ae2ca748afbe77e70645d80681c1939681e85ed2a77fdd50d038af660aef7ec1660f0435a74fb4b9ccb64946505b522c180c7d8a7987406996f5f34b0e85b91291fa00188c7e4f061b98f1c06762f8e4c23fe5a695053a1adaf4f492c1d69bac46900f07032fdee8a3da34894838c2166838df0552daf7229d86b9808666a17777847dac80dabc0f12f889faf6ea1198a97a80477edd942295845aadfc40e3c5825142318de9f8e0d1d286733ff12c3334ac23b1a005fd0a2ed83019e18887e59e6cc687983b70cb6f896725e3a4abc11ebecaf4aa56332de2ee72ad26d63619f710829c70621100924a4682b925f471604d73f586e5b0d0ce2f2ff4d3f2292aaa0303a85d30e52dd0b097fb30b8dfdcc9925edb822488235fc7cecae5572daef5dc10e65048b328e0540c6139cbdb0d0df49f2d5a64f7457a775c615a665042186126ef9e1ee11a71048797e27ea1f2eb7b356621907a913107ea39b6586a8f358648dbf2efdbccbc7c4216a61de1b795a5c0aa98a4626189ea5e58a8175ab92e0e2ec4a5d5bb6967008b45c544ea304b1b6d35287093e72ae7f462fad5a76e2366e47df74a43601e92902c290775aee3dc6e61920e27db71e5001a87f82932918e1a1261b090b95ac11d940ea72f7c386c8269e1222e3d137c1a553c304ef1a6b7f80e1da71bac0afb087b8e7d42a6eefe0bd6bd667634b1edb78323de38a44d100e2303bd4193551494bf761d9c4a0d8b335bcefdfed41a163bda1a3b101fe1aef18c9c4266cca980aace80414e37ab7cb3ab2969c7aed4f7824c1a89d53caba4dd4343b4cf17b2af22319411e8c88bb14288aff11ed7d539ea7ea1ec9cfd24e4c66f0fae9ce72ec6392d064bd58770a86e3cec117481b65666dde1f0bf7f1034500e9e38d5d403494c34eecb4605ad9e78b3fb9468aa65862ee626794f3a3acc745052dd1307cd31939f96282492e5ac976709c9dcadc590fe568c9cf03430c5a3f0ca120b77ab0ae5bbaf6ab943651afdbb57e140408ecb12a3c263bf311f36b81b864f2a79a2cf344625e1453a0c4c6adfe10289ad90b32b2a315b01b0deb795ed774c8f23056a57fcc67cdab6d12c4a66e4a4c8e9ab435c5d6e64055452c77ca17cddeb5ab306bad6ea85366bd1aa0c331b7489f8960f37853c67dc4751374e5d030b4e05015eb1ac057210b6368c2062c059d2d220440caa1d3fd18d56af1ffe250b22a410b46766dd31672c017b338551829236f36f1682e205428656f0db114d36220d8f3d654643bc869afa678b7e721e18e2f3d9eba956e18e04d789853701701c5c9bc8b5d1ed81af6b0fec24f963506c9ce542d8409ec924401661c8c83c6b3db149c1f969c17c1eacc38bf0a16a766223e1cc387b0fa78442273397a4ac01594de3658b05bf058573025c367b4c372cef3403c9dfdf1df196db27e8940e019524ff71446ac176b0442e3bd13abeda29287ae2219a59675d245ad19a713ed68e47582cea60e28a7bd64911f2bd191c20ac00ee42e4c00117af9e223e6bc1595da6d687c6325ad3d069982d9e409b853ee996ccccbf4fc6758f0aff94d25a7292a6c3eb5b03e3675c545ace8a291d032ab8118d61abf90dcb0e8c2f6ae106518cba8da391a3a6426e1655ba7220c2f7ea7c3173119420ce93bf0c242a8d403392410b1bf63b8e0019aef70629478c8a242a05e7a645392670eec28d494e747ec08f21bc4787493e491dc9963595e3e8be665658d0ad64a42ccb4aeb60a549ff530892eb7110a49aeee288be540edcf5435a13f399a00bac846666f1cd872d91d4deec9f89ec4f14f17b56ddabdb100cf6cb9d9bfdceaa47678229d6892e89ae3fea8a514584731112a3a130a2695f2cf341006942dea89fed3700fcc103273a7229fcfd058fe7aec308e9d33c5d9662aa7e7e25332891b063fcc0fd0d52bb24165d3872be75da467c760d2cd5e4304d102c026e4dc715ad706c44392919302f95a70aa53ea846971b3bc9cb3b81354b02798a7f04aadd608fd2645bf3d240a60640474ec645befff096a96a5145e18a7ae32c032eb410d9758f106c01accbb2faa90441ef7fe1f4c089cc3410202dff9b54a751e7ce96bba8f0e43ac61865fcccf06c79bfa48a96ee0a9684e7298f62b9cc1d21a88a37231bea3abc15fded26e69262cc710f3209a4af8335bac3b95bce1dc7a8fed17535c14d99cfb44e81235a0bb2240771e49485c882b5d66d0b52eadbe5076bf41344901875b2049497651adc6bd67dda7113aebf4934aed709c8e4b71d14f8232b80eb5e7a75b00d26f0f3b14401d99800f83a8599c046c0ace38517af0df9496d5389bae1bce05cbdaddaf133af950ebc7df0af5c69de7615f2f2420bb4125c681fc2dd88188829663a2273d79db9b41a6a4a99f5fa43ef4936417badaba617cd674fbaf4eabf215b91668e32fd9110ae8642a5fe54c093364974477c2b77d7708e46adf5b7d62139a0dfed1fd13a6bb67c4646c4a060f89bb082c5cf04716b4bd3c4d6eb26ea6a92f12be2262ded7fb12a9af5ee2cc291eae8155d24372fe0b5069bea8d7351502268700de7137d535612778e33a4ef619669e70e917250c52e48a286f436653f7b963bb5f9a101ea110f791f45ff8a2be458f8e60f4275f4c5975f4f8de20606078da07a2556f84ad8b4cff95bc5d7dac13c79e91f33411386681178980bcae9569b2da68ade93d88139c426a7c10ce86226b50d50b7fd1a7005d747be28d5b9a72bbde8398ca2c7acd0d27c44ec69fef13d1a3bb5a58ff6ebe120da3ba22f7c4113d8f413016ac61828cda14b48dc5bb3e87b0323a9c2608d51020c6cfadb39597df162ea2f690867a7a8df451b599433d3fe852f314a26941abea7e0cb66643172e4642650eed18dfaabe8009ba812dd28a35a4a463834a27e9f5011bb33b423951621839a961610d7d56073c589071d990dab879d6f6c2c6d9fb0f2b7cffd90ca1da0549d8e6df695888cc8a5c3f1704e17c78da71e4d367375a782b44002d37a2585c111a01e4db268140268ac3025bd1013d2f1193813a4e82947da387cb86282e3777763519449211acb4faf3700baf12ea67536af0ee36d1ce41c58c880ca34fac390ce902cf2eae18c99664257c601216b6f248d25b810f270f5f8e956c3143a0282f5113aa79e5003bb7fbcd363460b97a7d354e4e6c30966752fc2a3a3265516a347c29bde52fb9886ca0cf2988905e9b1ac715e5da5a7a8027da085c4b97f5b3b207e5cf0054b28c19dbbd4837b0f10704f49cd6fdba5e2f1ce4445b859b74844e34508d046ea2afa80a34473c314a2a0754f1dd28df593f9bafdd07236d92c82c4cee386a4dbdb4a59d1211b815d7181b495319f7abcb191968e42a49f4309d039a2a2762d482db2d59e394a3551aea0da6308559a875fee85dfb0419c263e5f84fb467443832f6483562961ad0cf58509834d2ac71cd86bf50c20f105d77090c6a2fcb62336deed41f48ac01c3b3b574ec0ffdd2e418d99cc9cd7021a8517dfb6911c3712e78ad295e8552d223a297d9ed14ee0dc69ab29a02259213dd5e28c316ba7bc2602e7a4ed5ed087c10750e0fedbaac507e22db4bb2e52b042c7f4caab85374c220e81baa06fc031e6e41e781e90ce616c2b61152af596623f8337d87205a84cc0b863bb8a6d7ed42e6a5711209a66cb54e588400efac29bf1deb90bd6f53081da06cee5bfceed882c1cf653f1465fb997f5efca3b9ef29de688ea83e3fba10f8069ae4362162474838ecbd81cb94d98b4c2ade78db235a5517a1dd9d93e1d8f316eb5f4cab8a8770fbe63f07e4f33692863065321255e77325c6a160a4a8853c9e800af2c823219790d48025eaca42a6a8de074ec760097e0a6f7254337d401cde69ad38bb71e93c9dd38a4684fd5456668600032394d8092847846b1c95c84c2ff70722a34c8b5507e3b82189e52d3776d6db3223030f74bf439da18e061590d18714da8b42d8efa5565f6fe1ff643f628584cbc9f416094bf4820320dfc3702376cd5187cc7120b605fc0401d020cb6cbd9b21394f9d5b212191544749fe86b414e092b2a521db5f64a9288ca27726838190556b56e052fffc16041ef1368a3a9251e6ae91061280efb5ab04448864676edb066c31701b855620d83e0351a019128a961b02ce0f5665d998621f3fbbfb77c746fc03bb1c10a5af155c0979d684d062c1783904b162578835cd7c9b11843ce9387a17447967d2f0d41f2f7eee91e74dc31e4b765174a42bcf244be74c1fec680d76fa9dcc0b403adb34422eec18394017362818b6325304f867a3a6394971df619fc7ef149196cad605b0ca8d305309748ca60f945ca20e2429924fb058588412943921389eb552251738650ba5acf94748aa0547c9788ef846ddc03660b207ef64959109f211f43bc6526a643d45d7718f5eeb71aab3c114f6dbb18e34f36df125a72eb59ae72fcf63a19b3c3326a67a64c39e50ab74585a9468ab4b63f06d2489436cc966418b5eac57c0936e428bc49a61d17118468c9647fac437f3c044095631cb9b9c0f2b7d2a9504fdcf145a935dfa08ea6d4628b51a19b81e3b1d220400e1ef467a1c03de54adb3dff462b743398934b72efe1a01251c2ef1f94c9779dec1a06d167ccb7e12630a8f1a34e89ca7bf85b2393490f0bc449fe231a68240498c18eb2d6be9582080311978d817d726b0d4e930c096b4baada814719062019f021f58ee4ad90c5486603315bbf13d871a552fa3a585f061b7751d207c367a1bdd5a30e161a5c1e119a54d21c6199f14d243463bfc37dbe3b51a9908235973a9eb85e634e1c78369e3802ffc53e7e333110b108ea305760c8b24b0f5530ce928681f8419aad272de3ae395d783fd8faecbd25cdb9b3708d38ef84036e7a2e950c0539ca8578133c916e0bdbdf473392013258ae34fb570a2ffc164c569019c6c24e41dc58d8122cf3d5701560966713f11d78f9a4ff4733193295a019281833119cf12c2da066e437d40fcd4e014e3774a8c16ddd029e2b65f8d03ebef7f5c51804bf0cffcd191e366976d835cc5c736a6f98cc41ad398cf24f201115d1a2fb94d065eed06dff3f84cce883d08f607aa4393bf2fb828b530541ad130b9b8d39aed74805d9cf9d05e71af013a6c38a4a178257a1da02a9a341b754f9e7e1a9c56297643a6d296e2e43b1dc2b2de68683bb56831080adf6f44d29bc6d17e888ec126e06262d8167498c766802ac736389382c190e2d7641df6a5315de872b44b04440344cb94b4938806a11d40e5b120cb515667758bfd7fe58e36de0448d3c8eaf4de2d7234b0abc05d0a648102032f5548e715fbbe5d3ba52000432c3a5026e0c8ff9d9e8750b6e7df393a6e9361c9506d1c1ab97d5dd3ca42049a7071862c01f9abe7ea0b7b6a174f6c819564ae13f3b02145f663cd57d6353a774ab8e24380f85321f91ef48c1048a3bde41816560e9a4d3cc2b9d77479dcc05155ecb8c0f5424388854cd3e2fd13094ab08dd77833b2e0f4b5253de18a99d94d5c0c55e1ee7fa28c243a88b9e1b4b255bd343ad98ba6e4d37cff615828e0fcaee25be5b408eeaf582c1a46832da1e5e1da3aaf1c418e830361043b99fd1e0e38fcbb9f813b353fa88d70a6aaa900c1b6280b43520041ecebf0deddcfbada32af35dd6c012eeba7f85821926dc308ca5016a0204414056f93fcdafd7580fffb3ea41d78e2946c3d4de48ec1b025185afb55350ecdcbf7b21d255ca433be1ea031f15e55a8344dc7d424d641c9fd8ce25c21020160321f7481aecbfd9acce206661c56ab1ed1a828fd321a593eea400eb686e4dbbdb7d5a0a511759505778a8c4a4a1ad7fa4963c0e23b43da3343dd1a84449e3f2d0146d4d896b817746042ec7536fe3716589c944c9d16358f56d4fca02a2f5ab6c1691b2543dfe35818f7f96051560ef97fbdc4651fe99c4765aa3d9044b4bc73707548dbefe737ae4b2a87a78fa1508a4460fe4dbc9531005200b9916008850656ecb29001ddc095a75049f328b674c162f0567779890970bb1d70976bbbc8c3a887d03fb75671173308c7190dee10babf937b7c4ecc2ec9f374dc4b8010e176c818fe29f9e411b3f0c416a1bd1d45c30b6f81f902766f1c1cc92ea1a28b2daa96dc5949c80f09562dea0aba8b11b9f2afb8575ccd457b0261c260a7ee5659ec9d5c99187655b212b20ad16e0955c807b503c124435558178d4911b80f505ad99c3ea588b99d9b06ce06e0b9ed4c4e42c75b2acd2e8b888b174fba367305431da6a08c0a9b27d1bb1fb9c80eecd7af484a13babfece322d4605a65d9c64167d620ff184b9dbc455884ec1a715ca214c22440319d81896690f7d9e5cb6ba77fc0fe99d60482058c8ef90284f326be6dadc82d92f1b490883b22996513c8e5f3b9b1a1050659063a2f5d531cd34eb8e469b1782cb59ffad722b4d680738a5637bc88df5856129c9df3c88049e3e5703385391df2d4578a11a80644f7dd1802c23ffcd79d6a960cb04c2317c09e331913a21fbdf05d79d1b4076b2a09608e55e4042510fb668ab8149c5af8b35e6d4a214a03fdcd6065fe177221b0e0d94e49c58d9f1a4b3e267ba40cef8309da161e55cb13aba5e842a954dae510d204f4bca4532e3ebf46b401fa67f1a0615b3a456239f398c4a122e24232a47db6dd76b00496a4825a44c2f4e2676b771c017092a7890ea123570ee5e787ba36843495ca94c0c3d91263210f5c6368e0a1febb8d4b5b25b01de8305b8c18ff243198d0099ce3756a69e426917dd0c96bc31aef061d9ff10648b6a8a5c34c3ac14c984648cc8f2f142f25c79480410d239bacc9a0c4445a8682455b0ed65d993619cbd4e6063516aa5bd8bea44dae2b6afc5c49f348265b0befeba6f1681b9a9233393a08a5743312033896e12a6b1898fd6de3afb4319184adff3cf24d817b39a5bb58771c96dc20e0bf15c3669ce0d624cdbc8d5be20908829eeb2637d81304f5dc66d8089f2afd894d272d19951b2bed680f7587035b8265709bd5cf3137c13a2a9df44016a0ec10c70f0a731f237bef9b02d5b42a0d484dcf9aca3e5da249cbf0fb146062c829031db4ee51f9bb7be69e7293f84f42b0247ceef420e08d7da820b1ff01afeb4485678b7fbe3f99fa4b056c481c2d02732732216a951560fa40cac68041d65217458f0ed169fc49c7bc483e13a8d1ddf1ba417d86b2cefb98fda9921bfafb1492f30751be0e37b09b83cef6dee46b13c659e5319c5a42d1159a5d99c1cf7981032e1ee2354c08dc8c2bf1e046c8cda158f704016b04098819c2728d011b11baa3e3614506f7c1a115baf5ce3aa06c10e7288b96ab38e050575703d835bcfa09b45cf6c52e6b06b632eec35494b3c85abada923f6aa3451d8b286406f2e70a5c129955a4a23ebd6aa1c94aeb83b88073185d1bb34540a6e0a5dee3fa11aa7aefe910f7e69eb739740611c1fb4eeacd022719c4d7a474bc1b898b1bc49aa1476ddbc0a5155ecc6c99f8e8873fcd5d55e2848b87a34d94aa627abb8c77b52588e1000d210e5f38105a8815ef155fa0b41c8102c9a06faa04dfa4c3784019680b25523c0d826f03d8acaa52541484b432f953a78ddb006d25b9603cbb12c68aee3335757111c556701dc7b8020b4f0946591dc23d86a2c682183f65a3b0bfc20883c90fdba9b48354dc84ac7396e6439f979270195144d75486a4363450c9db67a17ef0fafcdff692d17e7205eff188b72d192c0d0d2f3e3da970f7f689f3a851c34e5a30f15035712776348a4825d9ab8e0d6ae83be142d0537581cdd7123efbb0ccc075c7949fc623e7a98b73048e663c4a73fcd49acf1505140fb00e774025ac22bb9e45b7838441724ab16a2ef06c99388f3811ed1be9299834fb3f6c33e8a839bc80b2990113acb181aa0ae8efdae03e5bdfab90bc7abbe306e2b5568805157baf44b5736755d1902da11b9b8a2fbc3cb31e63f4eaeaab3b848cabcfb742a22e235d8ddf1e92ac2a193825b94baace9a5ee1d3ade1ccea161dfcaec5fc34b5ad2b7e41fe60e7e0653f1d159d6232d84ba15a3730c7203f84e6744ec16a22001697d88819e75d0d858211e234384aecea1074a160ef1f70fe05c2e43119802f116ff9c273d80d1e136c09c9b7e0ad9cc1fa3d0e07c9241426f673e701a7104421e71d71d20c2de36040af8b7bf31561815578ba6977db0f9074bd3ea9e7ee0eb97f135d088edb2db251cac7e800c7b9c519925bbccc159a9d82bbb56ff0ad0ab8ce6a474e54ff94af7c092b24f930f44a174acacd938c5c527f86e5f587fabab6ef9f6c2008f52845201a3002046ed1e64332f3de7e0607342bb162c9f0f0e060b40196c92452ad2850349dad186299914307a5889026af9b723174f9ea1e6dd6f00475d8739a06368204313a0f1e9c92945136128f0089769a2bd3e17c758c9e7b0cad7eacb0eea7740a4b737ca4caffbc946c1f55102f208f3e8e808a8154384ba91d13b9459effd8c5a44a227d56014860ee1f201fd762eca8390f7aa83c9f31896c893c4f68853dcd66ce6df6c912294b5788fd7785180b9b2c393c13d8ebc7c6364fa43cd739e2b9cec1284ac37fb73509c77ee72ea0b769e31a1307cce07278d4b7a71a972a2a706b5102c349868db1c4b9b71138c399cfabc855a56af07ea768b11e85f93aaf8700983e257313000370004d01599e41c50fe21f95c0514bba6a28a5fa3048d2fc3a2a9a0c8bb840ccc89ba461f9f6ee9c9e1adc9392cf8f9afd0834bceb66578d451696ca0d448d963f1c807b6396600ff1c64f0acc6a1452f8d56d8eaa354e536140e0db3e1e0bc10d28907fda202b818ba6b09eaff42e94eefcaa10c4a13782eaefbe7b43d8820fe3769c4e09dcad1f28c04d3ad0d3775ef677564bd69f8f9dccc681f649582c6f140b4cee454708fc457fd10658b65ffc4759779c6156f66818983e7cf15a58716d556ac23435c3b25274175e7f3e6b58017de39ba695cc44f7b9a6d01b21733d6b8c25c31d0c0e333a07d6aa413819b441eed77d26d3eb05cf81202b8f4fc2303047cd02d2851f39734d12fa727439ce45e768707535be3a07340b0fafcbab288bc2399b56d1067ce971edf8c6fd740a388d6cc4f8117a3675187468b462bd7012cea79d145a89e5945835e96eb2ba67322c212986bc47e0df040979d516a42bb5756c836f3524af68519d7ae6d95d20b0d9e716045dcf47a55f3ad8c9c6fa5139d0a0ed05017c06cfa0e8ebcc397849f61ee5340931d4462cb04698edd8e65b0c6e254e18fce9985973f01b55e543ad95f6ffd9af2300835b00c74864bda81f39549f60957a671811e0960bfa4b59551e23425e05843458eb521e187f75cd228b481c659da4b46db05efd23ddf4811828084345c4465cd175a3ca0c70ac17cb1601102562cdeb604cf4b08a925a8a486ddb01a5cd662e545f23a6dc35e5bd3f5d64b892674958332645457c7d6d8a98bb5c06a6363cb0618680663c3d2643f418707750128e72bb918144c56198d9e2387b33f30ca8d3ae26a529b8880b2edbc18ecec9dd5206405edd2acdf3364a014245287cd79552f2b2ff00882056aa471723fc2ad421c8249c9010dc166bbe38e449566e58a52937cae0dde5da3f9ec5f2fc72c5a5a2f51ec89d8724e5ac42dc573252e9783211eb5a01f1913fae78f9c1983bf57f0f5be9fc629fad8cf19ae13f32a77cce059aeb3358dd47a385e58a18f762d6992678a5d23d0058edb9ac3e692db0c588a9910213a53c004a01fb3e1ac81dc8182cb5d477a62c70ab9ae2d1708f8c4f1606893677b14ea5c6c6843b727706b96c25717805c7232c5bc890c92e0bbb4e1061eb9abaea9b4423141311a705ed820f775296581de46d7720b0ba4022d1ef80d59bb2c6d434b83105a3fc830198bc3ad56c96118616b95ef28ed8e4c4d64ae4170b46086fb3d8eaf909344f2a7495b890b5254f260ae77535ea1d2972c3bf3270c8fb7a1a918ee6c6cd05d48cb441d21fc37b41ad26be7ed527151cbd168b81db94f9b444ef4599776342c63e4a7ed32c50486683480c21b0e9d42926d7c9e5c41b153978448536e5a271ee506d48645f03abb43310867f838b996fa265a95e68535248aa1e3b0cd82f89e9f20b526e2d858a9d93f3b5fc4847c1da2e3e054561161d616307bac0b4210436c4fa317442fb9c6b6318c80eb00d72590db1fcc5c66f214c8a13e150378130daa411c3641a9c1e5e3632b568e5152ca92d9852610749b1343766d2b082950403f84315c56007f13f026b4ee573085f383149e060d8e2cb8183849955fff45f38fdb8f26d6f348fe31fe4d283de6ccab183790c82f6883d97c4175d9e024c3ed7d75a4e3cbcb2efaacfefb00c120ced45417b6018e839cae18aac135dbc213c664052c6a339810b010bfac9ec653b68ac5a60ea04a21b7d9f66abd4ec4946cbbab6f899fae2f2373289cf8e5586ab19549cfcad685aa14c7ea692c695149d163ab92b2918a2aceefe158253cb991d2ca2f8266959d9ecc2e8569e7924406503b5a4b643a36c9091317ba2c7a0dcda79110b907c2ea5daa252d2a52691f376376972d6f4ecc2933fe4a9b1542565c1e69eebd7585d3c6676140f3daedce76a1d9ac32993390fbbcd74120dfd31415078557314e59540904b6d265af6d178e8715021964032aa77db326ef0886a3d8e1acdca2249aa12f9c4f86026be3c2b91915c10ab75b7a6ffe0eff4d4fa602d101ac2292c2b31880bc3a2e00d3ee3cd5d72b164e34c2f9facad9c420b9aa300c22acaaaca6bc70545cd5ea43f0c986bf49bd10227dccbe4ac20db5ef7a426fe21a152d1811e8c264d454726a6e9e12b7ce82dc56e2c5e05a789f7cb723a96d48d82621226193257e409ea72cfd74e29804b9ab5a74f6e608e022aa7a6f31ca5829d207626030e805c4b9feacfe22c46810bfcb1559cd7978bb75b191ea29da81a7c412fa539a96d9dd21f7e1efe269bc74976076f16edf79ab6aeb6f8fd4d2f139b20d5bdcc10b5ec0e0e654cc1f21cbbe24b6e46ce0c96c34affd627c40e3e43078881de110b3fc0f78f89944a2e79349ee0cc9ab2e2019ced96375a05483e78fe97de01ba4d8e136ee042ed6981d01fe9c1c8b2802863ebe73533a3cbe0c13087eb0caad239a29314ad3f3a18aac3f93860456f17d61aae46d689da864cae1b84af3d49a662478afb0691f55c0c760ed1ac43c7be039cf4317187b346ac36b798793069eaf5a7fe67788c2743647a57edd475da4480055e19064b8e014d23dbe98230503595618143164df80ecf0cd86113eaa7414c404d5b82de05a8e4a5b7168c1e3f73c6ac2de0d2a4caafcb4d198f15bdc8d89091ddd1d07d4d27777363b19ef6b153ef5883899782788c78248c6b32bc0c785d8ae9da8cc1fb872edc2dc50cb748a16f513de3f10f46e3271043a4c9d57d5ea050d9683be3333087ad992763623a1697e122ef63a32e8e683843e788fe912e00673b1518ee538fc6c30f42977cf396d90e5c0b243f144fb07264c3bea68499ad8abf5c26b5a6d11915b4c2a26f5fd3c8773168d7d93cb8bfaba3d05a9cbf3cad4b5e43223876fbfacd0df5ce4ddda50a1036a5d61a6213547d2fc932bf449ae5d1d382a995319f77746acb561b5eec26531b50821356f2a80c3315beb2159cff848b7717f6fceb4925d4f8409fd4ec52c183bed7ea29ed6675e4a0faa6599e3e7df19a0cc54c2197c69f5b9409906ee2bbda99f36a034ac6d7d7463d5f5d82c84cdcaba8c74f21c764715b8ae828e67dc9ac252155df8e553160a4c0b159bb01796c0706bf6c8a5d250b214edafcd50ec36083a2779570290acae04853360cc4ff0371cae4982861c06458e00192ec7e72b5170a33d1a1394da07deb66fce1b0f361e80c624a35b149d110bbf7be63ca49f78d728782a284695fa492b15c8cc66f8fcc86c1c9cd20907ec1558ca1726fdddad9a80bc0d6838af405b772bfb60a413bdd14d48b694e00b4d6c94bafbc503143f44681a45c600c112224f47b8e4133cf779034f352bc2dc4e47a706d611fffdf2d91e911c954364302b5fd9966af0cd80ed7f9a5171488c75b96c48508500ff1772a1356de55639f7969d4a3e03d9ad3cf78dabdacf7a49833e5569c25e3fb04f558327fcdde7dc9060ffb4ffdcc39978768099aa5083f322482a0981af52d2262bf2f74ccda7fde8334ffcb68a9c6ecf8c0ba00eb6e1bddfe74b52d46c803ce1b33ca33151dc872b7f6084f01c9905321a552cf66d781009e536c803b21ddfcb3f108ab7303be4b00c8e82755a45ab275d17454645ce57517d77b0935ae143d223d6f2ab973d0c8940425c0132865b015d718fa072db1e6bb5e8ffe39d75871000027ae2c2b5f4571250810f19b5112334dd96fc20e727143d7fcda548bdafb8c60a286017ceb2ae4011a7340babc092cef5fa61f2f22c56d7593a02a5c1d9e2c9cdc29c40c9be3b8f479bdc8aced8fc12aa6717a856c867642e4132caf27b3dcc77671e72266e37614a6bc2340ba41d15ed6bd447417b79c011d711b4e5885a80361d3d8d4d05ccda99eb718a6d951357172f2cf4d1312b003b295de91ea20abdb4aa7d4e725e5fbc40a40768ab4b2c356022ed694cba3b6713bd799300544350f09cc6e877328366884d55df4242c492df37a946c2cebef2e04a2b828207744bcd2cd6fd8d6397c0722656e0970dbdc06697b543d9cf680ae75a5855bb5e5ed9aaa576bd5a8c6cda10de10aaac543df865b859d5c5440ba1c2110ccd88a0e828b4070f249c33152b117a4fa4afd4aef43e23a32044349adb96048a36c2af89a6f5dd68d4bbefa310d36bd8b75e704bf4abd5edeadec5ddfaef6db4e5b16b1c3928e10e89a25d31b5ddf929595b3aeb58f71bf9078e0b88643e5faec7257b14cfaa2aec566442b2ad58286a5d327768849ade1ad9d0deb3e1896ebc59415df7efabd51e6ae3f07d65460b88d9b65c322b68f601c51b01b80dfe5cb68199db620fb6e63ab3660c604b785fb68667b5073a6fc979d6fe18e096706ed8069cdd064304d806e750de92fb8c9d5372d69650c919dbc2228f6cfba990d5249741334838107e01bbce4ebf3fd2a6f850a6b811c50bfa3b07342b62f51aa4982c03d0834c5a4002647275110aae9ca5393521f3a36aae64681addd2ca4c33a130b090aa6b02988e6e5925938d10006c5c958b0c8d46595e39530634060652ed4a40e6d12dabc8a4110a9af667f1b0ca4598942e839e3d8272b899adab70538fefca86fe7140f0df97ff269acdded03928b4933df01021030b5c923243b5023f64898afdf609c12ccecb988a50862edd700b93ad52261274a7195b0386923d3f46a4ff4d464606bd5b908d54bca7fe06b832e169b516496b8c81769d8ed1fa101f556dbe6616a99dc8b99e1b60fe27a9979114b07db2bd5ac48a4e41659d7b62c10dcb8afc088538a591a212b271f0302fee5328c7a56f23de43a9d21dff87409128fb2cc0c0ea4303f6099b69ae5a5dfc96705e91e22dadd56ec58edb4ab8c8006ba6151f0194d84725758a075b5066cf0fe78e1da4a7c3f7580ccb10d5855e721b8351a12159234191acf7824deab59020077d78f4b257e374060fc9ae42cc4e097392a2d8d1d39895113d55a7df243d0ca6d18e307fecea8c15a0594f9e9233a4306406a73b965736b51669794fc2604c762089aac07fde77f44ae1c8db1701150146eaef835c350081eb8d2788011392736742d0e9cc329d78045a2f5ea57802a5af865d77e903fa04c23aa025e0bdbb32de99a8c0b09d0057aa7d3b3c02da9d5accc0cd63471fbe07c6d2585a29229ecaf2c213b336e9e104b105ebdfaa3870bd8099714e4f1e214f7976733da8979d5643da9eac585b21178f89e701ec9aa730c663248a385b04b8bb5ec42dbad9942186ad07a67025c80e0d7cc4a9cd59f12884bf9b164ffb7075022934d5df441ea3acd7f536591c06bd9de5e4ed8f2af6dff37a0e8b76656f945d0a964e848c2207ef83c35f169137a8256dd8d9171ea421cfbe2d111f613caa02942341473aba7dba47e3335dd55ee6c428e7cba7e8c0a52e0cca5f5dd775996091fd7290ada84bfb462606d7910eb3b558d2f166ccf7d04eb6854ae3441986e22919cbc12b5bb6abf54a2f83e1c9d265b18f1a60a3913d5a37d2c2c18fc3ef215342e95af2954f9e5c86a21b186d97efb1e1f7f193f833963bb7825927f764b235ce63162216dcd1268498dc1df43f2ab17a36dc84de6c732c00b1c68c7f5d30cb5fd81a69a01ef61e15e92d3712e7686b32846667e81ec57cb1642d5dc32558f7fa1e287bd86f1171af2118f8d74b33890249a5af44b488270d32e8b9c649766979b47d3b1461ea6a2cf139bd926615f58f0d13a91876d3595054049422d7ad03847472f962882d33c56fe85cf9570de6fc7989511ec423c604726da906af242025f2e9e8623bd5d95a895b35d41fa1c8b3969de09ade8676eaef0f897cd07320d5e1cdd82670d0baeaa7e99f2dbebf42dbaf5d044dc96d32d3ae6f42a7819c3747cab515609be4bfd46c5f7c425747964409b55b5a6ac8520a64a7a4748447d6866236079399978fbcac5974cf64d869ca3d673532c80a01fda842bbc205568d5d802b1d2828564712dc8230f5bd40e90625c93d3dfa6569d675af4944cba978bcee9aaa6c69d860daf2cacd15ce6dc5e614ffe6a9cfee079151cf464c465450454d0faf01ab6385dcfc575353cbea73a924e91f0e19a86f5a1dfb5eefed93463ec9ce2793862cf5ae6059b2522cb1c9b66cacf238b5ff6849587d2de080da85a58e7bd62b917b49622781763226f8e916de3395a62f7fcbebf6678f36e8ff9b42a1ad6d8d37e10a8c0310ef8fc2b3c59235f82cd94631344622d05d5c6b54f2432da74ebac70618495af2a5183cd6aa2e0f39dca0727021a6eaaab3ceb3d04fb61c0944a34fbd4d184356b6375b82a15f83162f6efe1ff1aca739199c8f07dc764cc36550341e1901d27f371d9a0c66e56617cdfb232eeadb83119350c00006a56afcb074056b33f2588d9a7cb04d1bdf1cbb039c6eaa29d4589f1cb4e3df3c70a1b6c734e07bb461c340bba5474ed8d2305d10a161b3363c648716bae30d5ad0aac591129d04dffd2e683d1525fa709137dc7d021950b03bc1b4daf74986fce0673dc89d48d29aac12307f76a0451dc74b722627a37c732f9a44c332bef57acb5036101d1f7189aa2b750304f94dec3eac852bf8acf30e0de87c8b1ab849d8fc6c1fba26d8e58f8eab5156eea8c95fabd12ed688beb4755798bd9e8b77e63298bbda5148300ac9e0d2bba71dcaf6a5048b330dfd3a4efbaf736d9f7c033c119ca50616a711c9a4220b877e5c020c35ec5d070840332b6a51efd3a930753443eb8077b37842e0da9c8e1075be8f8d916abc32bfad461d6b70510785df007d55e53ea4c86c00a2d1cb794701f6698be4f6a454b53c312394618a518e17be8a80d049fedc5a479d30219da391d137b29fa75209447d83d70f8500352c7f4242f5635518d36c1a35650ab4559dc3d2150bb21708699e14a7b923a791f128ad8c32a725d868b35b95b1e9a239008fbfa50f53ebc28870cd1c140da3f312c7041904d4cad9befe087579291336278e7c0b8fab09f30a817a2b5183407504f51826ef0d797c90177627f957aa720fa11b807c29ce9b435fd8af2cd86d25cedd93e8baf14f22a5be09b4e308de6f5258a07fb3552cb5758aa2e84ae1d6a3039e6dfa9b4846acf990fea3d8ce2da05d1ca07faaecd70319341289427931098b67e1fa42d31405214bdd3288566a0652a3ec26a2a1f3c010576ced1621d31b32648cce483d70eb526a7c8cebccad874ed5a69755c988cdcc8dde12ef7d4e728e1d4320154d727152b331d1c56e1e02cf08d52d8a7d5afda88ce3387502132b2c2ad433dae25d33d8df52f71d5fb99e670da51815221fbb636d13352fdbe30642499526eef065bb1e087fd0bc3c569f51d2ad885426386910acaecbb9facad418234dd731d53aace644b85cdb5bb242e7f4fc21e7b88f9c07448b021a66ae865930d0605207fa330761000af923cd0f145da60130e4e7383e83b0fb1b84942c4491faf19920c83100a5bce7133b9a35c030106bb89676e8723a9a679ab0712bbaa4bc5e774fd657d0a3080dd561e8fa2d86dd5b4ab9b7945b0621081b08a7081dffcdd08df0667837dc00b38f07f94db0e3ef1db3ef9629bd7945611911db7ef87b48dce661c7df4b665f07948e66652fa4782d7ff87b4adc66141d7f6f997d3d40281d4b6847cb15663ffc3d266ef389662fa847c7dfeb4ddd76c3c1f5a83afede136e313cfe9eb12775375c231d7f2f09fbb8b1d7d4f1f396d967802c59380ce518425cf2c3cf63e2369be8f879cdecab3111442c48454487243ffc3c37dce6a28ebf07ccbe9b2444119572e8e4f3f5c3df0be23697e8f87b42a98ebf57847dfb879f2776db4d46c61bebf8795ebc309ef26ee03179c88e9f07cc3e0f82524eb4845c248a3ffcbc206e33898e9f27ccbe0e806414ab7c30eb4af1c3cf1be2368fe8f879c4eccbc0121332331f692b88fcf0f38ab8cd4263144f2a46c7cfa37abbeddeda8a536b73bb1bee32fb763249ccbe9ea013654c2cba9eb844fcf07f11b75944c7ffc6ecbb5a694da9a822424e5cf9e17f29dc66a28eff8fd977b3aa4ebc9082e3c261e487ff91b8cd219261caa0a68effc7dee8b6dbcaea933afe1ffaa21fde0d0488c3be5c30c3f3bc878e5f0332997d2520215d294e41d171f6c3af41c96c0605db344cdd76ebd83a345075fc1a9e34446990ba1b06d0f16b48c2be35a9a1a9e3cfc0ccd0ccbecb940245e50ca8a8cded873f831b6ef350c7af21a841a8d6f16b28c2be9a1ffe0c62b7dd4b4b19c63afe0c5eb8bdf0f833243328ef060f3afe0cc7ecdbc59d01d9714c528c4d0b298756d80f7f86600661f6f5380963542d61826449961ffe0cc30cc4ec5bc0550734382c38c0a47ef83314719b4118a33248e1167f06aab7db6e101b445cc76f83dfc6c6ed6ee8a0e3b75966df160a991dbf0d31fbee9b0fd3da965097d8f187dfa688db2cd4f1db18b3cf04185f4ae294b2442cf9e1b791c26d0eeaf86d8ed97781047d984ab5248ee00fbf0d12b71944324c89db9b256245c76f33865b5dc76f63745b0d058a4d52c76f33845b99c76f23b419da00b34fbbb91db38f17d7416c6c48e88dc80f7f0db246b9ccbe1ea73717546248052172e387bf8689db0cd46c7313ebf86be2701bd36a312d5653f3845b0b8fbfa646ea6ec8e9f86b88d9a79735c565f6dd242684925a2411e911c5c46d0ebad500b3af07470cacb228ad2920587ef86b82b8cd40c2a29aa18f8ebf2609b7311d3f8dd86d755515cd58c74fe3451346a3bc1b703a7e9a63f6692412d9f1d300b3ef42191204d6846447528f1f7e9a206ef34fc74f23ccbe9e6191151fd2806a3099fdf0d30c719b3f14717b8d513452b8c54f43855bf6edb6dac9294eaded66997dda68c48fa12885db8bc4ed4d8629718b1fc31806a3dbea117a0486a48e1fc31086220cc3bba1d7f16300669f1e0e831dff8563f6f5e4b871e307edcdedebea87ff0212b7d943c77f4189dbcbc4ed6db6b9e116ff85b80b53b74ddfde2e5075fc179e2e4449dd0dbc8eff0231fbb4be50ecf8774c37dcde206eafb0e8c210b7f82f24edc46e9b92a564bbdd2e6ca7bc1bbee3df1db32f6532911dff0e987d22b0a2e30a112f1fc8ab1ffe5d10b7b943c7bf13661f053cd8f00a020794e4e1877f37c46de6d0f1ef88d977994665940c20281b3f7ef87745dc661f63d44e8aa9e3df51e1167dbb6dbab515d7f1cfa8cd34f1cfb8dd0d1a3afe9965f6a533cc8e7b907c78553172a3c205f7c319d8f1cf18b3ef4ae95136052b4ec8c7d70fff8c146e71968e7fe6987d3d339470e85aca025251e3877f06895b8c2519a6c42dfe99b119a3dba656a9d54c52c73f3334533433bc1b3274fc3271d8b716673c74fc32c7ec8b001b94152c49643f517ef86590b8c5573a7e19a5cc32fbae92ac35a48da920289e7ef86598b8956982f8e9f865da64a66e9b3aa54e32541dbfcc136e758f5fc628237537d874fc32c4ec4b8dc662c76f61997d37ec450e24a1aa2695e60fbf05266eb1958edf4233fb6ed246d095a4251b44b71f7e0b6eb8c5701dbf0c30fb7a9adc80b2ae822c2191f8e19709e216bf098b6440f874fc324916c46e9b8e48478c75fc16bc2c242de0b770ccbe14a716901dbf0560f615e0478a181e808c69407ef82d04718b85d9d76362061a0d6293132c86fcf05b18e21657e9f82d10b3ef3e59d2f2a123c88f1f237ef82d14718ba918a32c48b975fc16a870abbedd167d7b8bebf8756aba267e9ddbdd40d3f1eb96d9970281cc8e5f47cc3e9e1225a66c287d1dcdf8e1d715718ba774fc3a63f69d20d862ed88859224ae1f7e9d146e715bc7af3b665fcf8a24af2732ae204564fcf0eb90b8c55292614adce2d78de98c6e8b92912575fcba219d10bf6e783760e8f875c0ec4399cc60c71f73ccbebb74f204ea0c4533d8fce18f41e2164781018fae1a56d07c6e44f9e18f51e21643e9f86396d9d79302ec8687b1241114ac1ffe18266e71b3d9e6163cebf863e262a66e8b6e6df5f39f62a22e74fc31c4ec4393f86196d9d7e3c109d3d823484aa8c50f63b68e1fa6997d3d42185242451232d47cfcf0c3b8e116af75fc31c0ec9b61cbf201ab02e343891ffe98206ef1136151ccd048c71f930423765b74c60c98b18e1fc60b264c0973cc3e548a0706191ce2f616717b8d513052b8c50f4385db0a6fb7458d8ce2d4dadcee869965f6a14422b3e37f21669f0c9e2031ed20236212fbe17f29e216ab75fc2fc6ecbb694b156c5b367e24a1fcf0bf48e1163be9f85f8ed9d7b3f4e3c54f50531219613ffc2f48dce2b4649812b7f85fc65e8c6e8bfaa03e2f491dffcbd04bd1cbf06e90e9f85f80d98706831d3f7bccbe9e27a6f02b884390e6d70f3f8bc42d46ebf8d964f64da06a2d8691255f3446fcf0b34adc6266c7cf2eb38f46461288131c50674c3ffc2c13b7f8ac89d5e68615c74edd36a3a1b1541d3ffbc44649dd0d163a7eb6c92eb3efbe0555c0aef6db55f57442ab8915244a93c48d175120cc28b6088bb23404c70fad91aef58460aa92e284c50a144068f06b846dcba72b68c48da6196c2b8a9c13d75a6b8df562a96b1468ef231b92be7fb7758aa25a423abac372aa82a4976280f614b4a039fc3500cbc281654a872715bfdcfbac737ff4113066cfdf9dffe7e7ecb4ed945ff4a21c4d51fed26fd7158a2ed36fd7955a96ca5ddc9e283fcf5344d7d4b1f3eccecf41a78cfdfc1aecc33f0ffaf91fb07855af073d3fba51181d7d543f8aa6bff62e4753b587d6e09c73f7437bdfdbfd77144551608fe7049c9c10b0e86f97f3996be241b14b0b66e081830fb0775521ba200267a7411fede8474077b49782dc6b810dfaedaac2d447c01713fbf93adcea1da11184792999692151426644cf9b7eaf7ab0f5b5dfab1e666c8ad59eaba7d65e42605debe77f379c5dab3dde0b017bbbcb105a04450db2290e3764746dc5ecda6a4ad769cadbb13887d5a5a90ee79c417d08c61457bc32c4eca7635821b14ab263d9ece33f94d561e8b7cbeaaaebfaedb292d179d8dfa88d0ebc03cc4f47fbedc2e2a0f7cfde2edebc982ccd10b2fc6da8becd3af030e3a2c2c175f5439fae8e24ce9c7eafb0505c6181c06bb93301fc8302b60b871636232f20d18e61fbd929509a5e2867424328281f96417e290c2b6b59d85a98bc74b0097225eca6699aa65b3d4df7a39fdba8d67fea1d6205c738187046518acdde5a8d35aab5dfae35a74ea1dfae35a47546fa23dc01a4fa9eebcd9a277d15ddbd135a521a0f783a07a7977bf73eab539df3d5288ffe14d59fea5e0a52f45d7cb4d6bdf7e67bd39bd39d9bf3b997a627cff9bca3be8be6f447ee44eb40ee66df0b6e7488fb0981c661ed975f741e36275f0eb4a88829451f58bada52089dba7e56ec0c094dbf5d5d2abaeeb7eb4c4853eeb299c5df2f9b714f7a9e534e39ad6974ad7df8951613afd2a2a33b997eafb44274b6df2b1f57d2600ed5e9914701174b0703d0f5b359ac749da215faedc21a7665f1816213b93b01f6765511f6977ebba8147beeb658847e91f77340c02dea437f17153ad5b290725b3854cd53d3f5e56c0b2b195df7d2fd7cebfa3ed6f48dd3b78dd5b1efdfed1ecf093b5df7782f02ece55d57b23afabadda9d6512ba48ebe07a8cef926b02dfd5a5989e8b97eadac3cf4f30667cf99f791abbcca33176c220484ebc9efceac383cbb9aef37a75f0feee7826702b8f1535ed699a7c7c2ebdb2bf09c00420ecd1945d1cde3b9414733daec1acd185d4375ba1f6df69488aa9d1fa48f6ade75a900ba767e907ebe3de5a16813e7a4bf77d6e9aec2ee655e55559e1b74f5762dec18a38fd533787ea0b5aab54a8177768cd1d73cf414f6f3d847c0288f03333885b902bbe39e538873f408b9051be7ce34f71478391e8dfedb5f1ef37844405114451f3ffbb9dd32c35b2b1cb1ecb3b9e2fa3cab5b3fe3b8572e7876cc13a1e7829cb3ec9973c37f7e0ec8f94c8f8765657a6c8fe7d91e4f4ee7e146f6cca128fa59841f14eeadcd9e535b66d0eed58d589e35c98d4bdca2e9dac42d4dfa774dcbfab962e19cf37956de7accbcb5b83e45ad31ebf079eb73a0a79f2ba060f14e661d9d7e75d751dd79f329ef849c7ee3e272ea9b475d1e7073a3ebc1e458dc04acc1fbc1f9e708b0d8b29c89b01272f11be2f6fffc5c930b0fedf76e0872d1cf9bacd1e4fe9c0e9300ced93aff7571c07eadd39ceaac73d699eb7d1401e7ec5e7e9e13b40aee323f003e67c32b40cf3c0014a0dbfccc0c08cfd3d26742781eb6cfe8facc6e26a7cfecf41910fa8c02facccffccc73dc56f8999ff9999ff9991fe16e10c0cf7c2e87007fba10e079ce6ea3c1030f749aeacb820e83bcd3752f05ebd3fcca73f9dcfa298f07e7ec14d29afd3ccfa3f3f14fd3f439aaa27bcbf023cec14226711bc69563b8dd7f2fe87cbccbc3d9f14e9e9dae7beb6bf894b7a3b935efc2e33961a7d7bc86cfad2e0ed8edb2c6f941d5d4fc083846e7833f616ecfedf0ce0e7215780538c055fea00cf0d7c50106f811702ed7d32228e0a6af3ff35470955d7fae85d77ecaa3a1790574f4795a7cfc636a3a8aa37b9e1d103afa8fdb0a8fbe0722dc0d328fe2cce361d7d737e8ea6368c1d955ded977bc0a28627241df9fffbb8579189e7e1fef62980a28fedc79e59120026fc7027700fa2df074147840d057d9752f3dc0a3bc10be85e7ec2d38333c0def0f1042ef644370c17fbbdc40013fa80c1f0208bc03f02ece3100af003d11708ebe7d8777fb073cfd04e05d9c3300dec5391ef02ecea9e1e9ef80c7018fe31cfd3a3c36ebe8cfe17dd6d1af8127001e07ee00f45d06a0b7837396dde6f30878868773a1c7d3c2e3c15976dc3b590c1efa0d4f0539bdd74bc1bffef509d7749eb53803a5104b4d5f504820fdce5f89b8cd2e38707ee69d9023f53daead7c0d8182d62583438be5881d0b77242e59f608e260e1966b00598d132166c41511630bb05c4934153191c4e242c80653084ad2844340b44892e2cbb8a2eb6743e86a21e340661c4176c468a903059d35fadcc8a5d0f7b22115258b5ad80c76f74e9de552df73cee9ab91067b95babad3de54477b1790a16472250b96206b3f0dd3b5e63862b7e5433ec4c1c1c151de0d9749c78f73c438c88e1f07987db7d985242408494850dc0f3f4e10b75945c78f23cc3e113c7c9d0177ac9d28fbe1c719e236a7e8f87188d9d7c301ea0994144d760459fbe1c729e2362719a370a4708b1f870ab7eadb6db993535cc77fa376d3bc71bb1b6e9698d9f1df10b3ef8548dc222aafca983ffc3745dc66a48effc6987d1fc8318545e9939514e587ff460ab7f9a8e3bf3966df6533d1352625c95913e40fff0d12b7d92819a6c42dfe9b1ba3db721fee9314bbaa1d97969d4bf3e169e72ebb65b7f4d2983914888308a1d5a0da5cd0cb519e46dc5a4d5bd7ccea76c6ac73f71ee24e984ed83adffa394753d2f98a9fe3e4a41d3ffb5a9215d4f39e9c3b09e6adea75d5eb9f9fb3520871e44dc70d27309a8a7e1d38b1e2a3a5736e8576ec9cf3d771ce9d2cb3ce5579382e7c88732a4044aa124c4dca1f3fd2f9b3459dff6ea9f3add1a41ea7ea6ad8797e27c7aaad585ac8fdba5f3592f33011a86e67566452225f949f05b3ceed37fb582d2a2930abdb353136916a7264d9ecbb258e98514caa0dd5f77eddef1dc43ab76b3421d6d1daf72b4b669dcb4f56a7ebf7f8a6a2a7fd7a7d80d179d857557441d9f18283da911b56d948cf92d1d91011214e463f54ccc686b3e7efdee6492622dcc9ada79a22e59febb1bb3504ba1dc77befbd57f43d6201455f43381b1f9c94b29289d7900aae39518573efadeebd7754df5b6badb546c273d823a0ae1fe59add4d389fd322d480189388b0280910d74f1739aafa91f3388f93a39ed859ab4165a9abacec2813398251b67b9c631b1523289de777d4962560601d68aaf244a243102aa7df39e4c1a40440f5a1b53ed1435403c89410451a5269390c49df643911465091466274de2f96911653ae14224e404034c9c25444c8082292085b4c05495cc941bab0a09a486bedc5014c15f239caea5a4b43d878a500e2f593cbea02eb69bf595d6f3b6b8a9eadcab154bd513445ffeca12a4fd754d44092ea167cec09128d668ff4485a1ed2f891da46746a26661cc5008266124618eb4db289904145a4f3e04d28c695ae833721282e311df429888f981cb71c846104c40d16079df2f3c2ec45da4bf3e06485097db4dcc189c409170d5132b048fc61334cb9e20206089fd4469766a545955b0dbae6c6424893d3e89e4c696a72a66240d7a230b91971b910858de9470b9d41535b91022bcb30d1966c54650b28f38dc75995a41c4b16484d883f6ee8744d332524694c5a990a29295a5ea090a9e01014b26814252984c10fb90abae65812d1cd85021ae508520c9e7b22765405b65735224643905b551332447b5a351b180a38121cd5a14f7ea008718576bea81ad7892515f742a043d7b44cd4c082eeff1b82ade2a0651571e5b07befbf7b3fd7a93dee64975092f39fc3b28fc335e5a9a3fd561d39e93cbfc327f0764ec91da05e70cd371107461c2f72ae88cafae7f3eb53ffecf1f055d53c28fa3bf7728a5fe886e084aae094b8e6bc45eb02ed4931865212a2df06f286e4cdacea2d4ccdf55bf5a6d42bf45bf5965545eb1fad8da4105281c3aab5d6daa9ebad7f78644cb93db4f7ae31425b60495c16b0266c2a7c924b2c68d51249d7fd562d8ba0412194157961131ccb1358569155477750dd42bf5945c334c803605643d23ed0d821e426c9dd584b5475a5b58848a2ee08a05f2da22b5da65f2da2b38de4278ce10485b2684506b682c8018795b3d222144244d34b0a1f6c3e674c23809c447dfd489283729657091dc54bdc2a1a414070635045aa329c9116dc920a62879228754784114828c1021c401f045a6f5e701c28a0c85decbb4929595e39ace078327af5ceb3cb24407d245eb20fbf05ce7fe9e709d45ac4e3de46aa6ca0fd7ccbd8816d2de2b0f37eb588421c36360cd8bc456bad95ba4e9d60c014b3744d41c96904d3514bbf3e8a5254e4740ca5ac1d694b52cb5d3d2756106d59694e9510c195c4418f0b192c546429193a6bdb6aa7a2c0d9682b125142729ddb42fa76d9c3bd8770594ee068f1c1c491dfd6fa8ab1f5a583ed77eb479c1beab3c9389ffdbec62946f1ed9df7f49d27949c563211d4cca1d48523ae858f64d05652b8fec845bad6da48d72d7befbdb1f4bdebf5bbf535d467fadd02bb412337e5e40a4a1754940f593e1d59665033c25008c9587cb8e2507ad262090b38e48ad97cad6093161c1611ec682a5bb5f0f1d162690f51f51dd3af0f166be91085a44df3410d5e2042c64ef488a8c164c919f14b48adcac50b173b6292aed70a174f2ac284202d8f45a28f628d0a24b051990f175238abdbcdf4eb634594aeebd7870bdee5a283b4762aa212c4fc99a283f8d345841c2dd9ab181fa6ae771accd0043b3c18d3b05869112642d733b6c09aecf5c4938f351c5560a8786a927b14f96852b1d1103cd46cbcb135d9a0f1c60035105c28c24000bd82dc9627c498b2ee90a326aea36208582c3eec3ec7839d9a7eb98e823924ae5bf6de7bd937ca35e74537382a5301c4d545c3ecb779a87119b505a05f2ea31c1d43bf5c46c429b99b7d25506a5995991d719ab1a3264d0a02fa45a6e5f820cae68fe28aa8f3a07ff0b85175b4e3c28ead5d15d20e260c573fac1590cb10003d8cc81c73e824a130c4a3d8a57645a1479619a12bad103a1e6b18d8705c08b1b3da82e9c1812db270646173c4c283eba647138d158a0b475c86c963b0803800acc8384ed517dffdf063d2eb83915fb88ac15b7aecaad6ac6884aa6af01e8f1f9c1d4b66ac6858a88a2283dc5103a689d6b54b1514137d5719c5e538e81749f5d65ffa455231f5018c4d9ac088c29a9e20b1fd768f529149c914e294291eb7eb548ee07bbf500d595163c60e668cdfe6f5bd77cd0f0ecc2a54587cbe7e28d58e4b4dacbbf4cba5e6a533102824ad3015706d525e3a320011510ba2f5c1eced22d9fc6a10b8a92c8d45aa21228671c53553fc740e2f28af1d5a6badf5de7befed55ece94e4cbf575e3f373ea79e3c2deaa94b4ff7a769eea9fe9cd67ad57aebadb5de443dc539bb10e8d2f407879eb6f4344d2faaa6564fa268ce59ddae25f549953dfd5dba63776c9a5e2c3d457172ce9e978b9342bf575e463dd7ef959794cec3beba1ecdb858aab50549b490f23ba738b0d98090092c4341715988b0b29452edfad37bcf53ab7d04dc934f1aa021d8e87020ccdd10b856439c6e646c6e7deb94f33f9f6bce83fbf95ef20155c26b0041f2f584c469882ae3e86815d959477762faad22f3ea14faad22e381320db390d6806f50769ce51b185072650430cb4de9c7466edfab734ed7fcabae9f9fe67877fd117066d79c7f3def89a6bd3f4fd8f5dc6375ce5a1e8401aa97cc09812acbbd39e7405274beb5558d25329a730e4724e241b6ac98d0d201fcf1612db5907cece46a48fcaaf2a450e738e7dc27c9049f2636b93cb162495221a1c60583431e87242e6d60150a8d45792245f915a935115ac22b21506e25b9a631bbb751eb2d207121ce6d02d0a8f554080864595a4995a8c07635d59696d0865cfa4951854896231468c61fcf699d23db9248b636a2542339e7c0022dc10de882442ea10a71ca08eb76538859e7f220254e2ac812a8245964d3cca88429cb03f46bd5038c43d9716951754e0f5f5697969619ca9cd65a6bbdf7d65a6badf7de7acf007a3977349259e7f2ad6e2ea3dbde7b6f1368088b2cf7be408c327c691959cdc892fc80c64543f922f42b1149d770ceb90b26d6b94d6d820bb75d920e210d15c66293ba8c30c800269595b800354caa32dcb1904a21c2c40c533145135146c611ebc8421333c9089d518a8d28a60532c51598166ec2112f4e6e4b486c53b1499b880a308c1d8a283c01abce50085d5628a94ab418856021722f8c2ac688eb9352455c911a8328e426c43872014d31daca6292d6ed6008b18426c8608e30c1d83433614213904b098ec90428668a1626148fc42b26135a0009d0efd58da9e73753d0df453be8d72a471a9b4f263b2e3bd7f294ac51b9cbde43c2868cb568adaafb490da70322d6b945a3d44309392802b562a7c351bea40895c32687eb08552400022043425dd10900985b8c16390050728cf1c5c3d1ed980063b0e5dc8449c94021809e10a50c1e1a7846903290d8fc5228030e83069427512659b2c6a2990cc2cc39e74618176c8a18b1726a9447a31a0dcdd87106500d0622527c0693cd0526c619c70b3bb1e20c310c335fc419526a6474bb659386080b488c349832e8b89a34aa74315b4c1a435e609698c9d268a2f39234d61081813513d6701a400531660d2230148e0c6b30615c50fe43b8f5550d389a9612ca949973cea34cec725ec028a80ceb0f6454978dda558c62d670afa3871dc4ed48a7bf943164d2312c16051b86bd64244db30b58b7334b5ed9c052c339ca4b0863e65cdd38d25042722787822d76ab5c5555555555be4b6822e406e8f74a87d956b38a4d9dcb889102041b5091ca092bcc2c1340594535d5288ba86146f44454c491cf8e56c29c90d634c965af39569853f1de308a3ab7913490a9f871158504944f6ef2c4e109c4aaee38cf7a01a2f3937307bc48ae6b9693db8b0360e85a380c268cb6dde5ec6f1ec112a7764a729e0229c8a999752ea74289765c5ad65c540b6f692102c43a37281c128b0d2062dce117b73457cae6de7b7322ce39bf5a11a2463d51be5e29835ad5aad66a8ce69c2b9358e72a970d5032d7755d6164a000875a53c90356589cd99598504ecee3fc4ecea5784213391feabdb7d6e8135036c2ac1102eb7663c5ac73f971e8c858038e947d790919696a809127225f875a459eabbab13a842d814020d1b119e45e2c20b7ce9b41e68ed5b1ac6ea7033aad60059f3cd73bde864030df4cfc10df90429020347c2ba2086abef5182221e8480288a18f8f2c4ad69568ec4d28c5a88466445186342273fc9ab34805b546727e2c12860997430ed862aa85e02a6665bd091d8064fa0041c2015ccadd857eab7ebe9eab70ab9a1babb075baae2b076bc23af7092cc739e77c5dd755ab5b08040247386909f68b4585d5f9efcd832be79c2b3bdf5aabaa5ac5a14a5755555555f5eb897f45f12f2afe85c5bfbcf857185739e79c73ce39e79cef95828a753b2f2aac73b1bcc2c65412bccaf48eaaaaaaaaaa9c73aeaaaaaaaa2ae73ac8aeea1094d35a6b7d8cc23a970acb2b6cac8c84a39aa652cfb6de5a679d854020d0888c23fbc5da6aea1c9906214f187d381bea8ac12333015bd2b9ba5526080ce560821684c7d0485e5235858452a2f9b1e3d2a2e6a66cbdaa17e79ca83aa4987bc287b8a95b4532b5d7ade45a1f81d15a4c4dac8d85d13f5ae370c1a12591609b51fce94cd63596585cd74688bade7b6badb5d67aefadb5d65aebbdb7d61bc89aee50ae1caa5b1c95ca3a97ab3d5694872df9de1b47df7be322c9ac73f9de7befbd35de4d7d6fce39e72871cbd09c73ce8934b1ce2581881b6735304c55b7ba552c21c54d4211e3da12c49ff3222c30e4d671a22662eb2493f3175684b410e20f8a344833050854b703326c418284a451aa846e07a4d96582842046184b221280207174f43dd8a95ac2f4bc69c765afb92ddd826aad75cb5951e79fd39c73ceb956b56603eb5a3fd75aefb4d6576a635deb8b5bbdd535df5a6badb5e69cebad224131e74c929dffde9a8ceff3aa39d6f9ab3a49dd44201048820d2dbd57cb207b4595915bf16e8a548eb7358bb5b9f2aeda862e9cf3294b2e8273ceafa0c4edbd7786b2ea58c19d5cee0802d547ceb78450de26fc8075bb284cb120914ca80152aa80379eef648eb7f02b2f724b0e868b3d81fd66e14876ced50c82cbccc8881957dcbebcd864e7bf13d2f9ee7256b7ebb7ea4318fb2beac1c3d009ad6a2622e72b34935bd6b9dc438ee1debb2999752eef3a88cfd3165a45728259375655adbe6eb734b654b6a4b6d4d6b273bae86cf2d5b9958cced5555df7b1efcd4f156558e7aaf1365645dccec30f611d5e84757892089dffba8f7befbd3616b3959ab6d2d3568ada4a547b57100e1142391993c2443ba264296e85d0baaaeaaaae304b3f59a29899ed60b124c90a24ab1550472a512d40f69a6b897a5135efbcd76377ebf3b0ba9dd872cdadaa56d3b2727b9351916191799185a9ebe69c73a7ceb9bad5ad6a0ede3aff1d5f7b3969c9162d56447990735ec6a1ec672c972a01a6218e307135f9727142ca524652465456e26c06d5edac983c21f5cad9330d0b5fd57c39e7d76a8cd939df2851af3f14b06e974499756eca3b70ce99b475ae16e99545a286756e1b4712c77ac03a6b92a15f551e8ee6409c735074c5e8e8e48873ae644d815608819295a24993214763654d5d555f1d299803a8944a1cec4ae894b1191000000000c318000004302408a22c4aa2145bda011480104f92424e4e38918703c228240663190641208061000001100463180ca3509853650401c20a02017471a711a91a4bc6a7427e565cb979b2af13e082aba338430cb1c0cceb2217bae338af088b9d36a58908dc57e8e44e1c475e5ff138b15aa0e32fd60ab1bd1fe093f6c18529115f0eb08eabdf3da13ab0ddd8c400471f7192b2d1cb7d800d5ea4746f2b977e55047e22c88148120cbb6bd32d7122c245f4b2864e7248eb53a0017916174d22423ea70fa65d418730c0aea18abcdfbaa87536ff6a408ab9f87dbb6a1785899a9d784b615d551763c52cc1bbcc5b5c80e64820f74b023260f29a6161e293ecc4c00f5786af860962ae452630fe47f9f1900f49a0454a18701c6055c2a932fe60d1bfe709b7ae656ea1c522aaf060beeb9f59ae2be4931e460b1cef75b27cc9cfbb346787c26d8866591f3492eedbd5e9acb5582773bb313fa502b6802c8c59c0e25d1a3416a6bb82ac9f24e5e246cc72eb5622f79d7e0f68fa16a91421ea8cacdd49b997e31232e9c7b5a6222bdbbf6e518db04bb22d0888079a4021c1b9d7285996017be673ccd5e231f03997460aad3192e006973b9a154a7f438c01a58c4f85af831cfbf77a09203ae9077ecb494560cf27df05c9d83c50645eb9205ae911fdc78a08ded59d1dd13c8b60e40869bce968104ce6174afce95193f59c07a14d3e847ff04065cf03a5e2d014113549a81c6b3ec9a913cd9f80924a4e124e9d220ea111918d20f9a4911f7a6e00014535780fcb22927e385c542cc0f1be54aa478b78c1112308c496ed810011d93a455a6a0ffac4204306333581d4e3349161f41321052e5a38f2423249804e5e5014980dec36de065c8da69c46fcda1e4201b986ab90f75ae7d33819f68b3b8503360d2b18a30c8feb1a872066098bc1349b50cc321c8e6bb6ea07bd8b5b2753ef4b067e08819956ab20ed679d571003654a61cbd149839875707b32f02b3a8480bb56ab90f7f38ed33a9b73bfb2c5a92494c05211edc972ccd95710a30cdb38171b785e8d094c8ab9f26c112df5c9e9321ba718a2cdb72c5425b60330e4180b7f36d1a88ca0d64c44290ed9752c238a3c2a4234772111f3fedca578d61f544c9f4f368e74dca58c1ec07172ac5b6ae411f446011ec4f105451aeeeda754182093584754e322a362e117ad5cff42cae01deac4cfa23ac67218a14032af9898b7f0434a50ae4a9160e979bb5ee76cd69ba80e202506a0a414014716dfe8631a8beb9495337242fdd43aae154134072588ed1eb406837b8bbd2d3df8cf577bb1a09434296bc095026a90812524a513a75c524ad92b53d661504c4e93a33cb2b47277134e1e25d1c67b1c9cf881df4bbbc59659aa37939487145f758ac7c7a0be926231cba12b854e219ba6baa02b52718a958a310cc9e6cb110370a34ee0052f3c282792fdba9d2a7d1e38c46e06b8cadccdbab3e09c90c2ae0be69d81ae5150d51af6fa36ec26dac97daee8e195666679a2346d2e26acf3e09c4c63d6924f826261592c5615943f52bb29787eef8226926782496db2f446d666cb481325d55c4df02e4121699aac4c8e00a744ed6fa65897033c72a0991f433937991d6ec19d7f19a3d283af2afe5357b63cf14e1391f97dcca13e4929563ff0422f141425a5994d8e285dbb8b1965e7118212bd1244a21ca048b8515bccc6be44784fd7ad503824a4763dcc3b07b6b2ca094af79a0117adc832251d44f66dee6ae275a1f8b6b2a7dc5ddda64b50569048701eba5faeb0a3888668104a7e9d3a63649ea7235a502b3c8305dae7038ce93b0a7f322465abfda1afc1dbc7fb4bf34db34771dc7e4b3ba42f028fd1a7fd02bb349bb26567a880fcbfdc559933421d440508bd08537d83a298e993b71fd7212206eb3234cbad8fc0e90db9f9a44d8cc65646f8b8a1acf538bca67edea65e11555ebe9e16820f1f1cb7291a79540b4a3561f40d6bb8fc39e810a0e8235adef07ed0b58249f2b26fcd2befac81f78a91b2e892b71acee70590af61e9eb0d1d4ec4c9dbe01e2527ea56424cc391dadcbc0584a768a79f510a8f1e9dd2878a3593ec11d5d4daff3b369a0097acaa75d6034d1f183f7e82aeb1361b91f43efb539e184e2c49302e3828123dd3bb09a99270251b5e4d5e69d69356b283867ac013beab5eeb79a4abb304197d8dc2f2befa0f08bcc27abc4684c2887dd3a07bd00e98f220193efa397c70802fa05226b0251b0df18f220fda729c5c4300bd329dc183ad555b4abfbdd18e850ab67638ccc473d8f100b047b09c84148dda5ab711957840d4bfaa2263228a9b1bd59e11b9121b94bdb313717fa801e5612e3bdf8cee4dbd680932cca41cc729e114e04a21a5ac897e68190c742f19b6437fe635531c54086845ba18cab70cab02a59f25392ed277a31d84f28ec829fa358548eda9196abc58bae2b0620b7acdffc391721d6429a30cf6b1355a46f9d17bfcf352420087a469ceaa9d08e02486a825a4ce631ee3491894edc8fe54878966601094a03e5df8d2495e02c1842eabb310ef13f5957183be1fa8659590303959957e098db6a315f929731ca417425694cd31476b9519dec40d824629574007c82810629dea080d3d2879832683658b5171e94ad1b81b54128226d4e3748bc15ef61eeb8788fccfb63f062464096d4a674737ca5c11d9738aa0edfec9d3b515a73a40afde75d547611d21b82b0cd22977a6e5d2349d177a8b88263b6fbd3fc73018738eb0719b275b63ceb7c207951334dd2bf1a693806d7eae0c177d3a01897b141227eac27d1d3b8f9a64ac5a17f2fdb34d9f002f421505815e4b2bb98334db10684af4b02d19068184702616fd72251898a7c739a6d8d696758218253039be18f42ad7b74dfc94e1f4ade4eba9d7841e9f8be1c0f295a70c812e3a149557e99e6abae2eba3e706a1ed2a2ffa206778a5db38f4bf5b5eab889c1dba717ade009945a722c54c3537952b372aa9638ea94d72ce9a344e1c928aa5e3efc3c85990f1c7cdf4b2bd6c3f0b4fee4cb11a4d38062a9f674f0ad6240617e39a919b4cec272a071a643fd01e9a8d6557f92219e67f2d1445d37f11b33c4683a65692d6aeb095069a785c024226df9bcb415f3e4bea68ed2d0a1f3fa05eab236bb68dd38d78dc9d0fec4a7173ace244034cb184ccd18b720c194123e7949c97fa35a32df9d08981ea97140139824837ace7e56c5e8c69c94f69b48b2a1215314b56c4e9c87508e0c8de47633756342e9196e813894222f437319b04f75a3e4f6619108e16eea8328127fb68883c6c3930c93f0a5c457f5f76ae5fa89ec42613cf38d9fac85b9108813c30a2a8da18fc0ed0fe48782da50f6a00f4a77dc723b98578d7a41c0aef77b2f54e34c4c28e4916f1642f365dbcf3cc0245ed7ca2b3119f6ecb88fca4cfb9a2ab0da100145278620294f6f1d45ecf471c117bd58fb5d881208eb851da8197601f59757f03b365761e941f8266462e0c00161b32584173e32e175f6e3f262acb305b5f6e8d7168613c6067b02bf03671a540551abe92c63cba4ac434429651b3e95e347780b867964d7633c0b818bef8ec0db385d7920e7a834cff6f7a1ac638f4d3756436db5fde755db35bf0379dbec0d79fce127e1968bfcb5906158c530e530a4b68e4b2b0c7e55f0015afa6ae52de9c36a8c186c2b58c7d778d6aab87a98414152d47507ffa2a8116c288adfbcacc4022810e305f8fd73afcc58c76c67ad0ac449eef96e3d37b0014dbc9e3fe87db36aa495529cf78989d10e7d4fe0556e767496ef945592294b7e78de6b86c704fb9f62011ea79033adc9be421d16b046999ff214f2802be02b9e78aa68a7dfff26588085e478dff058b02e8eb864b40481486ee75c94ce260683d887cd283e2e6c4e1a537c2f30957b0b1814ff1cf78b0a85c4a52eb08f929da45cdae0bf7094b9280ca5ce009d7572ff5e70b2319aa12c604ac26c7de2da4b8ae56c68e5180f9f623a79822daaa7c70ffd8c52029e647c2eb78c14e302f8ca87702b5fb85c8a210c504f3dab08b62dce9853409553b08c1560d88610fc1d29ee6232c0fb605b0d3d0e6319dded9a5e1a11dcd6db1620183f306fcd0e9caf5cf58c4b490f90e5955f1bf3e0eb081bf459059d698dd88353b98fefea8f21edaa441b60d48e28d14fac2b2ad552e0a46674cf0f2ab9746846ad8cf7b38fdee17bf594871fda5c403aff8faf0c31b71cf38adcf66b79b67362d0f0f5e04887aea76b23914cc657639d67d2aa737b43e67c28a88d4543a80904ae448862f12a97f3172ace0e1965f820a241a2d154c7916c0ed2243f892f2dd60b6de03f6976502eb395c8f7435e6068ad9438702b1afcd8c217090d627df268c86f41c975d97e31253e7fd18a886f7efa1848bf44f40479de73a40740b5cd4ba9a723bde4aebe646c93de42249f68b6bad14ade96dda1f1515470d07c65c8163f7a0c7f441cc2c8192bd9936379d33e9815495a2d7a93dcbc12b5704344c4a70701abf275c6eac1d8f37b0dbfb04d4d920aafe0487c33022fde0de60614d6c70b78b086c315386108eb93cde66903083804b95d1da00fe5d80f3304d6152cc950f3529067b0429cbf261693cf16521dc2596530e273f7b6ede6a9fda3c76c429530e36cf85f43063a0022ea6dcc4fd5bbe22d57581df2c92a5e335872b7b2a79c1baf2ba451ff5d8de967acfb82cab66f345a5d94155a1f29d81d02834d5d75ee0feb88c6b2e1cd6ee95578c76414e367e306a188ac27bf704071ff2f291983fb3aa5c191375a7ecfaadeb1da76f4838991326482b8932e10450450a8359143a90ab94d2171c9086d66cb906789489b08037c1deceb37282fb2982cf18194669ab0024cff23878f42b6f3741b77598185f424d278be4925975576099b3d2369ce9a60a391a4b769785996a165f8686e7bb4221038799a19c35c7ef3841beea9d2759c6ff9e79b79e0c7dde2ab927a68c5fe6b127a243b3ddbd7603ce5f1247e3e711bf2dc0c5e3f3008164091dadbc71b3a89d0ae61659b7ef0ea8f528e8772a026a442646b30d9407a44d39b90dacdcd43f1d47fc28b478a960a08bba98d10b8cedb9ce9926cc40ae053015691e5969f76d24a67ac78aaf49d7653eddd69965f6fa9202c6673f62c48e1bdf92f91ed371cb61946d3063b90ad5ee7164934197ed18b0327c3e92c303e75273ab1fe563258e18b6a049490b00a012e64609cd55fb8f8d55d8a3b353325f6e1853b2994cd04946846ee9810cb757b595ba3bbda72cd77582ef5b5a85c849e9b64cf999851d8c53e8838362a0d15b8c99b0ed729277a28e88c90f6e7245e2313c3412fe778c9ffbaca8d034d0d294101629f36de688554aecb2fb050f1c80c68481bb656bd69004101c76cafaedf19005feae9329fd590d3d439f204e767a0546b9bd3e133950b63deb092b4235bcf19b3d412761486f827f316869bd98a69f1c8a80a27046c8a3cbe35c359a0facc5335b3b3c481c51f9f37af8be7598eaf0e166c7acd74628100a340e0628cd4bc7143102da0d7ceff3f56fc37bc0c8e6fe9a52b3248e7412c7a2c2da9394e8a8a040f613366800b15124b9a55e07a9183456d907a437b74c05060b23789467c642d12651edf462c24870b5c37ddc5e64f2d582817f6f5af8f0b6bacd49987a439bbf128359669c5da2fb639dae670b47e0bc58459e9a385052e90e635168ae980b392e52b62f77ad9a9686484c81524348466c3199b715bcfb7b677a1b79798023721e15f8bac8d5367ab479e6ebdfb620aab8fd9613e1ebdb39531b2f3ca812188983726cf7ad792d74b15e48952630c058af547e1236db01af426f200f599f971d43382f7d203825bafe8d56f1e5e8231b929d05017da1b269fd1f7b2e1bb94fa8f73fbe459450a370c0cb0d3f3f2c6ec235f1948be526bf4e1f5a9c33c871de0911c353fc29dcd02cc3d6240e46eacdb1c62dffe5ca2c25bd3866e16e89ee8fc99b2503264e1c5c4804804573eb2fb1cf98498f4e423665f6ab84f9748ed65ca28c72ab6d4074574c00e2ba7cfb5332afd19e381d9aed07f3b465fe3f5e8e6c26a2c5e0be917efc57336d6ed6d69b10de4e9d08e14aad82948eaa3fb977ff2aa9aff40c264ea316697905a1adf10e149077e6b1978b50994b47600509170e63073c425f45a811929d01d6e4290d6169564aa22f4b497f7f76c5704df3dcd8db3fe8507edf5c9007e1e4e23e49296a8eab7619e74bf0772a2f934cf3c6feeecf52bd6ffa6894824a4aee4ca7a2f6cc20769b3ab2c8620c1621beb84480672c3cd448a35601789f09d4a99ea6284f03fefd9e6c5d21301499c2f885d207691729a217ba8da1ff5ae85d483d041e7bce563e4bc4f5b09df73111b17f7141328483d1bf3bdee44ff7edd64777b08454cac5af8514db85521313bc92d9e65f6936020b0ecb7cf45706372ca1a03d5c5471b1024c6c599362806fbaa9ea19a2ef0d8a3f9a99d2df1b2e2a438d4e0d45b1b092dfad048a465d392b1c99eedf39c9d2d623b5f47da4df81f9beb7f1c9dd52695c7842301935aed54a2968ea2427b22c77a3479f9a3397a6e5b1b73892d92c2faeccbce35056de764a7880ecad1142913813580c3adf005f5f96f451808622d24dd22cca616b22ebeab422970e242ad6e4d8028a23029210ad08aa4cbed01025cbf4470431807f8d9e3693448184aa45bd437ffe5549aa2941bc12489c0b603e5ef395cb77136c113b150a88274515b57b8f44c2ad9d01390b6b179c02d8c492173afd7e0f499729b661dee50cd710f4b0a04a932c42d8a318f152a471687c8fb9be40dc44eb419909e1822d5308f94117853a3ab65c885af4f749732cab00a4a170d6b18654020e7e43c1b4713c5affb27013434c64e535b37463cfc5ebc33fe6378ce8f96490bcfc3e6550fc0d507ba6206411da1cc88b8f5041c4fbdecb9eac8090d56e6b40e58df03037ac0d3ceb0defe3a6d5291892e832b89339e08ba90cee5c09d7fca352fe488ae3d00ee52c29365a2ff89014cfa29b0bae5e472847732a5e250b40aa2bc86f5890346338249eb1876448337a0c6c08fab2a8c0f37778391be01a3a9a2022ac66ce0a5fa04283193c3bd2843130bd32a0d932b8f2e7e04aa2a8b044195bb8f27f787582a8b0a07c3d9ca7a7f17286a180a05962b813bfa7b68d0b56af2b956dfb08af921990b93b330b01f465a20d902d075e1be6ee58d18a1d50ec3c71814311e0db2306571365e4265c369e488143d8effd09c3ab8932420e2c3b4fccc021d377be0df28d3122d21a79b8f7fa331d9e841451445a5a26fdeec750bd93c720a131dff9fe67d6bf9c29476b2020b01ef3e6874fff27c787574c6b1603d5422c2dd053c33b3cfe07c1faa4fb8c4d726a365cf7914e89fb4157c911c7c6fbba0820ac95a71802c91e14172c18b57b7b76685304162909179b286aa0214f77befdd289d81b6984d2e201a8df162fa050915b7f60285b15c0b3b5a180ead4e30d8ae9f19423558a4fbbee1e4bef71eb894a8aa241ebae920570edc52c27c31a7e570770bbf6966643103cc1389097f050067ceb480e139fd751cd868b01859c9d0911312ac8df8c6b45b70042d8660e4e49c920ea0e806e127ea77ff56ade2d0c75307c02ff545adfec0b85be75cac2795585306ed604ba401bf6162120f73746a6177fc8ebd33635e7c5a3bab392f25edd3e63bd1ed4719121bf973fe3f07096a2e153520cf76e8770a82e19cf8ef4ebd5017f2fc6e86429833fd8d7049b75ed8a8194ac42764eaed70f08d550652a489280c81b21d709451173e588b92bb6f558296cec3a2ce2f30f493c41cbbc46dad3db570bce73a3f1de12d9d2aad1b5ce2c1af24779b392f7277b003a289cb8f6f240704d62faedfcae641b43211f5861f99d7c019d24da43c0fbb62859964c072da2dae2c0f192aa6cb06be1051ad22f214034381b119b1110c0dd66c51e81f2d696b13b49cd1a553491fcac22165574447a172c73a0932174c34b4f1b6fed96d2b551d499c258de4dac3244e6901bd01fea90f24816ecc7074d3240c1833f0c2bbb016bc1f08d37b481c026e54780f19085fde263be4f8a71314ae02ff0532e62e004010ebc9dad74a10101cad86cf30f04bbe48fb5b7ccfab33650431031f53b18255acf598d227dccec2a8fd8c9072999ade6cc54a0dc44c94b9e539bad53a119a39c533a4d1868787bf2f2e16ad4f5db6fbdbc0ca58774b6ea3358685d11efcc79116f2f13daa521557e1dfb45d07b8b05a3d206b8105ea24bf30a57e0dc98b9a03a252158104d8bc4890e2b930eb3958663a3832ffd1fba643a87b46560a7e205aa7720d7edccef230f09c0a32bd8f1054576060d894c5c93946e286198d705ad649de812c564d227e3748df8926f9d844f45521930e65ce71b78e6555283edce67722f89b322fc74a1b4ac84c5f0d1c2a63291d54b411be00696e220fee74982897adcb4c6ff15bb06ca0c512cd0b501ab15d3147a8434b9dc81b13b241ba9cb0cc1bf7fc4ecfdc00fa21f4d9f358a5ebe8305786af7eea25aa290d89daab5dc4eb1248ffa6230f545b15b724c2c60714c8b6988c8c202161b3c76018591cbf412adfd168c4f402fc5dbf16acfc466b279443dab5acdee880bd87c66c0c84b50694d037ab1f721aad7855d0568ac4b7ee5d8a7844ba5c8a78c3ba5e275ca81f5fcea3afd98000d06e1e7dcfcaa13c9a1eb3652b778459725440d11a69d452262e5e75ccdaeef458d2cc45c014a5c0328fe1e82350cab86cfc1475334cf1b68788bd64e23fdc9bb5aec46b8b483929cdcdd97fd0d131341c73cb7d1298b780d3b9da7cdc09cb197ff99e8b1c15947092e38289bd76052d63ce508013326f5e336d271dc13ea3652195ed7c0dd4aedc460bf8ef2a51d95c6f99ae249fdeb313f9a5d96c3309d322736324ee6cb8413e0ec31a9e7844b3beeed50f9eece435090717f5c59bf8ebb742851c308e80f528ed73b60513f810ab1b7ee27485a66b3be76938a65959628d009b1a5a6263d19accf54741965bdbf9a6ae761a526b2f2f67c28c0f912eaf59c87f3afd89d9a56b7912f593e08548d16b2850589f65579280df9f5cd656d9024653063738c92c5db3a60bd852633fc88d97b3e9dccaca6d7de30aafa37d4850b10384bbfff5fec73566046baceb493b1849ec73c1cc2e549d46ce60d02e600199c6660ce969d5fc03075a564ff008eb5fa9b451f7f008a157be54d508fd7bce4efc90976674cb0ea031df9485d601fa0188b1090a96bea8a83b419c982e411ea3342de3190c8301762b04bc6c16126f555efefe7dff8130a51a74d1cd6d31ca21161f0b1142f7a71726ab7898907b910e8042637c9a269ae4c448794dcb1fc882380c4fb0d47d8a4855f97bb53fde368acb74a3e5ef4b6d07f6b22c70a71777b9656d0c42db3fe9030df4081cb47f81dd33e0be4d71597bd8ebd41769639d6786cc7548fd041f3a46c2e13c845fb6557dc2d2755f6a66e366add5950d0589fad8424397f62a239780e111d0596ba216c8e08d4d7a02114df1809235455dcc077ddd8270be92f488fb430e3fdd914ec627e098cca3f331a6ba5009350fc2df7794ef4ed0f03125f67acfaff92a7d8214f555407274d3359c2d05ed9b5761181e33a5b801afcfd5df950e4f8d3ec4344d5e68887428bfc98ba96bb73a62229ba3f321666a8dabdd8bb7f51f785422be6b5f3a10ed484df861ca8e937ffa4471a6de2ac54073d809dc2523520a9323779c5417b3c1b891f8bc36eae23eabbcff8c0cfb74c954e42cf94a9253e537e72e0c6e94554c04d8f7e53532f9c1d2f2ac59ea11585cce8d3ffffef4ab1f03cf2c14b5340b49183d581851afbe7d5826f0984f7d38a5ab37c7cfa1ca35bbc44b067978f10ba5288808a70570100a6e7c578f7a8a388833ecf8f247db5560415d34be9ec9bde7c4430e4f87e6492314a2d0fd8b42cac26cd0fa39ae662aa28e8761ef9bd3f51f4f284e3cf915566dd05afc6483ec2e9ee210b0002ae09cc7f371348357c7c9b8dc55267ed3090e25949c33162b7fbd9b4f34a17e587b870b8372fbe9cb44b3b37ef6aad5d4e136dc9cf305ea3bfa9a2e7de54a8047076ac55d19e23208d7c6dd9abf2eef9b38520c507e4589721581e7a69e5a8834789b67d2a241dc5c79096928af1321df1c33efe29d54ee3f5502d4e1d991f4aa252eb82071bd555fe686fe34f6a9c9833332415237e0b8b5642ecb19ad2d9e3e519dc5a53588c5fba4693e4b72ddc5bf99000d2eec65120c6d194b7c2462beb378c91d0e2f40d48ab50c47597b898b3d55cfcd9bce9a7eb2be9ff8e431a6658b50188628be94332e8548d1361e29e036edc4035cc2f821df6cab40ee864066603eb14d1fef5e2ee000f9962e895d7808a2ec04ad107791095ea2f72a96bb49fae99495bbd8221d9cf77de33b12d97ee872aa5a276bb76419563ce21ce4306049b2df7d423e5568e47b32086418d31b9a4ed895616026cc0648926dc2f38ee64fd6bba7df25b1eae1bd4f6a20e07a3cda0b2522eea9a13585a8dfb1d37e00f03c249cf6b5576192ba374264361d18264611b539b9d5a58070c1e480929e35fdd49815c49c4cb5a5d3fb50dc68b5f8a4da0694798234c7a9b49cef9dfaf7ac2886e3b93dfab747f6d4142fc257814c9e808990cc231f0adaf00cbcec64311a8d2893cb2e92f78417f3ad2b94056f0f6affd1359a8cd3a28cffe50f6ac7c8c6fbd05a25d422943d4ae12f3a575211f3a6cd50652bc2d6a4df0f33e313f3b31ee2a63e21a2b0c76784003ca6ad9a8c6dd56392b6e33b8a5f4c580a371c09260bf71ad7efbd20ae28cc6d725eb2ced6cc95acd7d5d355d976c067969caf9e8c8dd4c6b7eef51121be8cef05ac359c20eed612fb3591e006c0e05256c355280abe216569439755061b687c035982c9f0a2b3d1eb61486764a0deb8c44a78662767128c70ef7818456c804b34f9b523d59ef1bd4cbb398ba4b532564990ca950662c88bf8fd53c163b455f28082c5a0fa932a399424f455c751b007a88740befb021c63719b67d2a2dd4719d026cfbcedb72ee54ed531007598d8650ffbacaa4c711cd9ec1e70a8118dd978aee888306eb9c2003484870951f824b75c082c46782da035d87f717cb946f14110fcf9a8aecc272bad93553cc33086ca2cddc43cf61af146bfcc40f5eae0fe8f9545c3fa2e7edfa4a3055c4f61831abf8202a56bbc3406ae3d31577e043c9ba6734d5617b945a512e03d8a2f385d0dea5aed1a670a08e53b810d5c748f72a149dc9c1be19148a8c5548cb87dfeb98c20e23db6bd1ee89aa553303dfb6b1ff28535094c169d6b7324408449e08ab5894cf210c854cd12b1105d96404c653d194819248a968c4430e84f666281ff1f24cf7907c5d66239353f8248f87eefa5361af39b966db4b4ada0569ab0fb6cdefab790737a977d64507f609ceb50fbb6b051da256778b9406fa81fab3aadd9f463a710ab71b9de9a42c1093057ac84f0b27f4aee1e8f33c7b48fad91a8ac2e9c37385902a2dd0893f48f888cadb7aa2fb385f7504f6516c07f897050aabe80113e06599034dbf350cbf3f31e722667ed7eb119695cc3ad06c8d37a5ee58a20853370ae3034599ecb3c7e16187acdac8dae7ef02be4fbb1cf913d9a94119d64a263b607341d758567ca34ee176c59c3e5620fb99db40b246c5e136af30e8e1c33c22b18bd92abadc7dc3181a0f012b67d6ef030ce552476fe3d169124dfd511aff0bf4a1b38915e44c88d19dc3cd2ba9b9bc39f485ac202d26fa457bae06062faecf6e0383c10fde704bf1fdeafb9cc47354afc3c48a01a2276cb05de1409aa50edd2a235b0c40aeed93a6d6d57f5ab9615c9c9d5aca1a616a9e06691517995366193f8712e08cedc4628940ddc97debb3d34f391c4a820db01fe33efde0fe8a5591ff115069a6036e5c49b7a8dff639121c86106f02483efacf48574e3041c55df34bc67a14fb87c7d9ca130e99f72d30e34cb7ea88bfe6eb86232d091a2944ad38a09323a730dc232a38cc20f4cbc130fa94fdd413ddce1a7e0689a0cfe585120166d7a8cb9be08c0daec008fcc17916374034697d02c39599f8d5082aac320877e141f5fe56983e6e404f1b808872d25eff80ab9978824b61863b803df0a785ea05c6c950cc1e4265e1f9f16463837e5e4a8f60b9db865c8e3c87e666c8f188e555f3a6a6229b2267d34f4b684011707a7a2d30ca57ac735abf2b3c596233b252d51486f38f0533f721aefb16f9c3d499ed316689799ad05d024ef4ee73d9555c90f0e595345a11d022ba77abc3fad251ab256893bb1861a3219f4641a66435cc835676707e020bdbcda1e1cbf59ac7a5e263c3f15bab60829a41fd92932b3010aed6a86bbcc010fc36505714812fdde29c1a3d2aefdbdeb4859c0cee1d3c78a1dbde2b1b959d211df795262274a6147cf5d75ab03545a3c71442f72e17cbad216ed89a65ac49fe4d4f806b809b46b30511cda7d7173dbab8bfcc556d88b1bb50694bd550ae28cfb424237a15b93c4a5eb3d63e05a6f1462c17dbe2cf60e40eb0b95cd437e38578d8e4fb3a786dbe579abad07791e03f04e38a9132e6d6584457edb641c47f812f6bf18e746c5d3370b00eb3d373532b94a5c2b24c6bcb217e16becbe35d42282a14486a4ae4145040d98611c968b1b01c2b9da488ca1121567e655f2bdd65f58c0805318b3a5c5c9ba07b230537bc2c2d8b32964b38dae86d3603d14a3511a03ed467a1a98226d305755d3538a203c4d5ca6dde2dd7d8e72f1cb9511afdb53a9c34d859263bce66970412d07b372c82bb67408e12a336b70e245a533f51566aff4589398a9562733596bb38c472ab68fd5b4d2946ab11b99dac19be88a69eb8b0243f2e31b8d0c29aab6106686377da0dcb5509ad48b730a3420355f01317d210091d8fe58093f404a1032f2acdb33cb6d2c69827446c7d33868911d416991052dd7226a2413b13da8e802c79554cee7b147bafc75e74ab522df53f3029046c970bbadcbf4223977035fc1817996512c4894bfba4e61e8a83139d2b48e6a3834dd4c6c9fa148f31d832785365ab4161d536528454d500515d46f3537c2ae8c2763d890762c012f6432966684feb4da5122effab38174f1d8ed0c13a3f2d75c08960a7fa404108ebffa5300f3f10fe57f23aeb4d1b4aef9915852831be8ab764185916d140555f332d4e5b56e5a8ab20762bf16c596aafca724ab2461750d0bbd26e9345614d411b5b00ba63e8f49868c47d7432e2b366519e9d5defe8b094c21b287936923ed85919df15cded67ad30c0f190a2fdb76c565d78c7dae84426805b964de4afd1cd7c693874337ecc2db83d85ddc1ff058a273a5cdc681da7ef3d2e3ed0276e82404bef70bd0d92df28085080c4397f0c1b3c81cc2cecf8334907da0247374c6cd9ce68de2b22d4edb9832580059abe873d35637a4f872533d55e46597da089bd8db257f2de2b3d580bddf7a4795c407dad48fa0750ca11661ee4a51e671a71eb56b2af29e10fc8916ab7af930974abc0c96e2ab866047a824e1631f200861eb51875705d04b75c750f2657c29c0daeab7fce65111c00d44dd457c03059e4a24a13f5e82f7d9e62bdd7f3cf85b079645a4f4858c93de507d364d9c20b24f425db0f56ac9197e360d3d099ff874fe48f2f536724607e268a45a9281dd13d2717dd8e67d1dacf2cdb1ef19cbd27c4b889b27afc00542beb39af39928c13f44482d38ff5653546af0d01304241263e9331b01acc0fbbee208db259d12bd99ccfd8e64e339de4499ff69b24f4779f0c9d51fb9ed7858491201567d9e442835aeb89d2716f92a005d495c51c1da151d1d558a3dda86893208d39389d9c72cc0cf3e3b505837b33a78ee52f324d869fe92106cbe16c51de8eab020d2b1b15154c1c109f5040c9fd7f5728542ba89c4f5c631db1043df3847869adb06e17dbdbba6987c184a84106a78d3199af8f090ab1e2aa0bcbff8706b229537766d5222480138dfd55c101308384b4dd98e59e5bf63c5ef10f70ca8ff3b07615e876ac3dd51e85469e554b9050478376d59e28ba58ce03b240e7cb204b334a9511c916d4c19e14f842e254678e253995f968e4f4234b50ad3bfd749839b5a3e1c32b6eb88a543538dfd3faefe4687f869dcb3f9402a71f3c15ce6183c654fbd954b33c68e69f7d8656225fb0a74ff867acb831ad6c5d15859efc30d11687b7dc7d39fec634834f352a2290d37b9964b6b5361a9cbb80159eb3b926ed5dfe4393da14349a9aaa5b662adff8e2b6aa83aefe50cc4d3df2e768f8b3f64ba7f70430483c21010799936567d30fae187c237ec4d8bd2a0968a9a3f615a44c2dd32696aaa8707490081146ad5e168ee40d020271ce7c7283d8f4557247b264751d4d17795930c8e0955f5a7f5d343a4cea210d41fa54b71cd29cf833dd9d7e8ea24850b8a0006de87e8ad62273c02929f517d49a4e1725a28405a5062ee42e1b3694b0b3e86479c711c26094e0d32a5642e2701ff862f1835e649cf4d4b715e975e734348fdce80a095be15d74e212fbae6f678250cfadc78ca5d7b7ba405147204c401416269dd736d091a8b882081be0a186ed8379f64401832f2f725f82e4a6618735075aef5ccc6961b6c2cb38b9582afbd32212ae01b9e7a445b292fec5db1b6701db23198ad23426ef89bf2b1c79db4b403e5ebbc59536b54460d3ee9dde1fcf7ff6472e6240c267c54d7e3bd5f2fa104aacb26f41bcc60210535bf857249d63cd0016b6440f796d81d103332ad6bf57ab68f2880ed8880b2db3ab469e5c5572de352bdd8895f1e225fa6b97064aed8599dd28a65096489809451b81f818e360f6fd024d5b6f11d087a81afdfed65724415639913d91d36c01246ca810391d789742c3f1f8f287ac1d1a72643c4833da73186327fed606ff3ac42906cb0fff6d9090a7771d2a29a6755ac61c05ae9a51b9d30f74398d685e2520feecc23d3fd5f3e2aa199bfb8b6ca5823cc6ad1d10b374d4ecaac44663b32176c393cdc9e3ea8054c7d630f0b1536a0fc790b08ac3e648cbd031a884c464ed721e0f2e9c5fbf90b0e14355d030e247e6a9ebf99b5e49be1a8df8b25b4a0f75808409aa3eb9032a0ab9b9ab408fc9114f214420f11dddecc928a207b81699edbe6606018b9e6f38eef7b69a12152645ba23b81001d6cdb944d87380758182a46b491a86aaed4c5f0ef9c079f4a329c226b53ea77a031f7160ead6dc56920558a4d0028fdc431174c65e15b94963ef855065fa58737002ca6a0c1fee4faf0fced288207851bb3a86ae21fb8ae6b242e1c9d742a906759939100103bc485f71b7d3c44ab9111b8170c1d5e34ca1a38365bf9cd4c1249075a6e6e671bbaf1fc1fafc0235c3e4789db363ac71f9656c0c74e75dedde4fd4254b641227be99936987da101a69efd3f54f33cb81407220b600571397acca601075c5665442e504cd55301091874945c642ae09cdaec58ff36677aa3cbb09db9e74b8318ed25931cee4eee08ddbbe221eff5dc50d2a9fe0a6e74e0fdcac12647aad324dff329a6b646594540e5506ba055907a6f1d70f7c2558de3be3192ba9a1403dc15787aecb9af7f2001ee5335fa3ed046f17ff32bb62339005a1fee0011fb44a76cd1d9d1ae605043bd56655a83aef7ba9ba658fc4c9d22bf374838aa3b0c9ff4b2631a9dae8efb08867134210795744ace79f34cb534f5d14e7651c97047366f87e987e2cf3c8a0580b4da1c650f632a60262acb95f7321496b653f8432c99e794c4eac5c2fcd69aacd7678fd561d04b1150258b4c19ae90f75f8afa112dbd368bd391fead712e283f56f62604b85bdb165881d73294249513e9bfcd9712ef9f9b3b14215b2c44b07d818a8de800ef1080c95c8e40ff0529e93aa9e164e802c11fb1d247ac563501ffbc144c0712bd232dc35296ef7aeb5e5d7ce360b58cc4671daae14765d3034709152137e9f4ff34a15602c9649138fbe5fecf3e8ac2a73c74ad505b8d977164e8b21737bebbd1230f3bf8b63d98f544d9afe4125e88fa8c3a894243c64421854985da0de36ba04dff5b588d380ee03c904c274537b63a133a339237d286df2e08d0defb496e2094d3bc50932d10a559a325e5b454a42dd3e172b3aa29892b28f0f8adbe40dcafe82bbeb4ab782137aa9f9d427f0df4f189a7e3fab5f6226f35822ee35f4b0f019647999db71c3af96392acd362d45ce81fd9b31769728393d7b0feb3772bd4c3cb2562bd1876e9c3475125ed38b1a65b06b31d62879242227671edf0f5f8876fbcc4ce97df65eba8c414c40bcec3ffd4e43d93749356151bbc17bcb7f6aa1fda62884c0626114cc6493922ea16640034aa606d0fdb7b1854a8d827edcc78dac732907dd3a84814920fd5af89dbebbb7da22845080c9b6b3bc788c2e439c755e3bd2fd73e0c0ce2486889df2bb010d7bfe6c4a6f215d10fa6070795664219ccd5dce1b305d94d9f7f7cd9012790a4a87c3a4b31d76673dc0d612bf7506795b3f1784041bd80cb832a50b4d159a40c35a59607113473a820861f035bd289b690b96219382266a87c3a4c7ce115b927350e89184d89a0d8f72e0dba98759440b4b759dcb60032c4c831a45d0e8217b7bbec25c12696147209d7c8734661fea8da45b9967c91f56412e81d20032da277c4509c8974bb1ea0b52e30f9ff9ff361c2860d783467da68d0ac8cb23112939fd68c9f90591a640b4df745225c6eaa026738c7e0f46b8ff1d0359650e79748bbcb54a1ad17568d704f3d3fbd05e01d018476815991480e2f8322a5798e28d7a3df8a14250e1607fe7e5ee5079be041d6fbb084c4888d4e66c16b78fb420db58eea8bb67e407b33d0404e396a10a86000a7a1b8a901d5ab0ebd4481972ba8759f1d3ad2a25f06ff6b4e3937fe8e55123a9c034b2636bbfac3e530015bd7e112bcbd34f6b7f099087a03f60771f39bad996def8d94c15da4f64a15b8d8076bf3911e65491d9e83603d819c1344c57588a7dec7e14bbfc87fe64752ef5a0d167e48f06367c10d823b689c99263b579718d90109d340c7b73a474056f7278dedb697d8bc351115d7211f584fa860196ecdb0b56019cda01da74354c5e700cd95507dbfcd00134e9a1356ae0221b80d382f79088453381d43cc52416ddd933d3c8e837c8ce87c837ee86c8ac9c582e344e43095630263ca20612d45f76fa5580b722fdd05171115f774d0d42cca28c3922cf20cdee945252775befc304b9047b04fcff9fc29e99f9bbfb893f47f660828680120830c4b301c0ee04bb51e42e8c30bec859a1116f1676a0702a3dbe2553b90abde3122438b0114130b7149dab1c1c8a0eae44cd4b04f0e6e20912dad4d8a03a47a19d0722d5b8ce18824def683a76eca1e728c2b62b319fdfd5909c1fe355131c0f3c2726373c0f3e38261bf878e0413211f678e8d198e8f0f013f4a2040134f9efe7864d77f71fc51f503fa4d2fd09b1dc537767a292aa9eeededc87f4bcbbbb0fa9eeccddddfcf29bbb7bb2baf3f27ec0031a1b4ca44ec8cc0c61ef16687703a13265a5d50cc8552dc8cd946dc09d2055fbffbffba63bc3909c46e1b1bc5cce68f2d5ee7e84e8c811ba7b02cadf2a725464c8cebebbbbbbbbbbbbcb3b54fc4c064d59499c259dfe999999ff5967cfaa9cbabbbbb9dfb40a9a59fd76f7c65c83f791345e7cd2dd46702c59f9cb4cc8208a27a999b2f2364bb2bbe1fd7d1c138e98db054c43600670c486a3f16e3e201a208b1991a08c19d2e7943384b863849cd990a40ba25fa42325ad7483b9216567ea0098be87a8706ef0c068caca2372e6419273e7b24a26e0300a6a7ddd7d779e8b8e4c59399c1515bb7bdd63f8aabbbbbbbb9093292ba3da083bc690e94c28f9ceb2bbbbbbccbcbbbbccbcbbbbbbcceeb7222075997959cb315834930aaacacccc2e66a6a21c95dbdb64e998cdf5ec68bb98515eee22d7094a0193d74b26e1efcfd7e0ecef575134af0e327f309f8f19570ca3cf841a94e84342f3481b37e2088368b8e03187c62668c3dd664641b8590c5f89deedc83693e10bca997d60b3991d2561a090b64acf367737d28b5bed6edef284ad19c5f262d4d5a493d977d6eeced09495452807b123e5eb3717ec7f32c55762ba29535682d051b5f33a1f61cf337c103c45988d87a0e1c2c7842a60cf09c8a65c146cbb7b07c4d98089171931554f4621aa116c26c082be500c732070c01b36413f722070924c4ba07020724e3db41b9e9c9f0dc50810394705d412e983da2f5ad4ffffbf9d292b7b40424447c30fbf22caaf231bf3eeba08b16e9d4d24444444744434242a124139ff8460180a9ab292e81465fc30747c16215e0e01739690d507a1abda6dd7fbb002e8b78d88dc99999dbbbbfb2844edf71c157325062369ca4a9aed4311ce8d6cec777022c6dddd6db4336565ef8311903bef7207469599999967bcb8aacca50981001c5d7831a272a6a89b9217b39a84eeeeee261eddbb9bd7a12c70334d315179069b4ebb6718f568679ea1146466e625aa25ab97dd6566a0addd5a65775798ecd6c191a8f0c14fa7850898125067468914194e3a4248a00489333e2f217107c89564db09fea047c61d1e253ec9b8d3a4e7411c8f4faf853c9e1724f80324cf8dde2ae1788a6cd002f27ece951852908b1331a272f87c48facde05991f8303cf6e8743ec4f0c96a89f44204062448bf9bca8c9c626de351cfc8097dab8787f341077c49a1fb9033928074021148315cbc60d460dc60ecde33acd4f46a374b2d938a54fce9c34616ec333327c17d12de7b4e464254931917389020e1d04b1cc4e49878e14326083048c3886502adf643372cd823415356129da23e1c31326fa8bf92eb9246ed149650e49086aa2cf0d6d9e58c2252cd29dd4c4555b5d7ffa672c2ba6349ab0fc9ab9af38f05160a51edee1d54f7b457dc634a92eeeeeececceceeeeee3402acb343fc58b2d203a023f462a497f9d3dcff520d1c136470c0a4a0e3f0c9fa5f23527f779b9b6dcfef8f84a15d844c594974342cce5ca0fec5e95d082487cad3ae4c59599b85b8d998bf9a1253ed89d7b7bbdfd10b64f86f3d2ab8c9cc36413427e904181a123ca8ba354932e47da794f5d90df0d631bdc442c8cb740bc26636c85b035e72b0a0bf237d6f22572916edee1ae2acc6097642f7343c173d2e43acf1d3b6e40c6d0979420fc71c637a6bb399d8b5cea6b1646557b9e899dd80553544cc626c55258c98cd048bc4fccc6080343103a8a5f0080ad286edb0bcd651570a529e778bb5e2adb87339eaff54ee0cc2d09495c51610a076bd66fdc7115e7aea2d8b180e8fed482773640892a6276766e18f26179a0695292bad5a685cd56ebb961abd978a0400530c7758b910011e81da2d4195f8141ecbea696ae9c9c86b297ddfa5a124ba7ef7a61f4d4cdb8a41728c63c9cac6ddec92d38f88d6d2ce9495bd6d59028a016d684a332d4c461a382d339c52a06b21462d7980dcb53421592ea8a5d0842569bfa81679bbf0bbbb564553564281b082a18b2c61c1c8d09495451046a08c48b1a02b841f7555f50080efc9ff17312efade5405c20a88223e5d773715096aaa32c182ee4e49cdfba244ccaed35d482a6eb553d457b09902c7e25dde05fe93b3857e4e5bfca9b9bbb337378a5d7777239980a8769f3c96115a8d057d19a1b85e2c483ccaa79bbe326470b2ae7767163abf7fd22288252b0bb06b91fb0dd580e8f4e88afc8a7859e05aa8060e2c9cd004b4a0d1adc60174ace1c0c2c661853149c4f2e2475d450c6bfe3f71d1f71f1588a089b089c0a9ec3098212554545a01d341958f6fa8b6bbbf2f23c16052810feffd6b565c3841be33fdf02e9008da9c6fdbdabb71257045bd1a461cbb8bad1e6d87eeec0159b2b27158a7c9805a26bd2092324af54d1678ebff5f294ac9a8745442c286b8f8efee16ebaeefeeaeb3f3fa361008063e937a494049424944ffac1f10e0521882320ae146090b5974a1c1e2ffdff9938057199c7576d271446aaec4863c18312a9831e178715cb014c4d9e13131914001a05b9ce6dddd1f5cb7ef3623c8663622285cba29d66e3ac4e1128b302154cec90c1c0fceac974c8a814c9be5c5a82b49ca37b30d2953564e5159cd6c5cd56eae45f793a4809df48da3292b91b31b496761921728333fd54c5979dbcd9e7accffffcc7bdb5d1cb4caebebcc82a2ec58a6a8987d76771d413a7e3a803a82e8fff3f3333f7f8af2f3f3eee348a2cc7420bb2f6041d1234c33923438904c4d2e39331c41a4219d45010a774e28478476f77b8f9397bbbb67ca4a2021f777de1fce0b63336525ce030cef1f013a173dffffde1d9870facbd19495480f2fc958b7bb3bbf13e97325868b62c9cafe24cbcb3a5b06c894954244471e6486eeebeb4c9a4da2cdad76eace43307fa2c3e9dc776717023c5045522f6e263872581691ba4bd4f9ea32f3eeeeee32f32e0fe12c33e3184d5979447ac049323333ffffff0d3bba64d719c7ccbb0b0116df9899d7d7b995b2a0088061614af1a6b164bfa89338faffff3f41fcff77b16c82f829527c816e7e2d68804c2880395e25a0458e1f6f9d5d22a843ff3c6163c9ca269270a9c042e14311c44ada84756c25e673fafe2f7f88d44fcf4f57fe63ffefa104ee3f1d648e703abc44498180eb6043bee8a4ad42f328508a3b33bb9272b5ea296a737777f7ee6e777717babbbb2faf7bd02b3118a9250b5cc2ba937a8834dee6ced1be219241dddd4d73df5ddf751e01655b27311cae7acaec7bb151dd9797796f88bbebeeeeeebbebeeeeeebbebece35b9a481a8dc6e367afc480b54cf211eba6ccc0eadeddedeebeddddddebc965a59bc493ac9db222008b716d58892d398a5a67aa9cefee6e920eb0eed1ddddbd85ac77abbb936c56b593bbceee0b5381bc09810491a91b1827cd44074254014349978a20747fc8bf3bf1eeeedafcbfefee3ed5ddff5f6fda07e2e63f06413ff6b7f9ff97519f569f99995bffff1fa4f2a9ffcccc7f7677f709346afff2063660efbbbb9b620a831454ccbeb2bbabe257f76f15807c186770393a3f4d4ca0a8fbffbbbbbbcfcf4e643f6903e2abbb55d81aadc008a8861705b2bb45cd02018b6ead0d8243966650106bd49c08d2810150d2878d3140e1dbe521422a2f062792b018939db4d1db0f6596fbfbfb7007543b459d5ce7470c1126f0a66e7c8c90422fc4b047e3ec6ce4e60f4558d54e797df83a19f6d86aa77e7ce9b4db849b3f1a8da633828216af96c31cae36af3a2f0431329e4af8f09d208389cfd4d0a784a35b057a40291667a0daa9b9618386026c309ab2f2884c5bf8b7cea6893265258db1698eb01812f0576238562d3857b5db8ed719e9b53f633465e511d932936414db5d03fd9bdddff4fe06e86f84fe86e89fd55b1c89771daf3db9f94c5919d472fb91f0dbdd35405356065b6a88bdf21301d3da9c6037cd19bc59d6d939a7dda51cda8dd9a2c3e18c2cef6c30e625dcb1f2e668b09515b0b45bc9cc09ae5bc668d38233ae48fbdc60f98532442c788b797959696ae73697bae9b9bbbbbbdb03aa2e6d77777799f9c2c6ecaef12a0433efeeeeeeee099246a3e1c83c8b9993b55482c22541b06966fd68349a4f0dbf19554b2525b8ca519599b9d9c6274a458e5c2fc7da4d62090a573bbe425b0f6ad26aa9342458d9a49da0c5cccc4a4bac2aa339572228d172b0a01604a10d599763efeeee2e33efeeee2ecd88c267c7d0a24ea0ffaa18d60e01e5659d5dfbf1d3949ad77c41ba6f7777b7075b7fd212e2aac5a5e66eeeb8b73bafc5ccec53798906646666981e0c10bf989959e9ea83ca284b313602a0d8205dfbeefaba8d74bd12a3816ba1fd78d83a3439e692491b230c4d872b240e4e07264e3f39290495426831d32105ded42eed170d16fed141ccf68602a405d8d052022ffde163e6949949a031ef2e33f38f9a0096c69295cdceee1b949062ab2c7cebec291d18ce95d891e8cb48b1eeee06f263c9caeef65d71612576ac1d6fbdacab80ff24c8514b90a1d72c9988aacbccbbbbbbececcb4b3e6a292d406c22982961840d116884ae427076771974a9049fad0db0134e9d4080651eca9341cf4d901484d0e3e7066bc90b0730f6f947dca8512286cb8f926e07875652bb86c3db406e00f8dddd6d72c44d86dca4c84da0b88954cad68c75dfdf515ca4b8a5e33c763640d2432447c36151a8bb2f3b75ff7f2dc8711102b36f62c5cf95188d88f2026477fff6ffff2e5c01d553d8ab83a3fbbbbbfb155a036a3b61c0a72ab0d44286141554430750b4820b755540495d9da2342712582994144d510d281a42f04a3d455d8bba2b3d796100054d5b832b4306a8060b3afd74d174d30a549a601a98f535a834c1346055579a81062c4f61196860a668c0aa68ba69eb3573a52140d34fcf57065cd5e5d29001094ae06907d0576b5fafd7ab51576942e0ec3345530f9cd09c48e0a4a2a96bd3eee6c099a6a41a385132e87a56570668bafeaf0c25a8ae0c655445356055d7704273c200d650b6cad40cb2d8023f28cb3c4d99c9b504a1c6858718b4a3c6725ae652790a853cf548da9082290c504ba4a04bfd5a0a7b18612d73f8328114385efc98616203c8816b78c854de56cb6ef410d232950ed0a2ba400836a9282f095051612aba2c4f24a18daa524ba11106cc3c69f22a0cbbeeeec216537553d4d61381002d1422e2b6669703aba423554156e868382c4ddd9ae1b2f7862a73730b2253561e0d8b50b58514ef77f77603e0eeeef6054d594974aabea8f6eff6591280eeeefeb1fab92251237123b1fb0ab9a25cd1095f7ef61152a19999798868ca4aa728e3b10e219f47f0e5cd9d33402012766eef1c6f77770b5f186ba7deddddad828644d3a3e625c78baad30643e74f1876778543495a2ffb0c5384298c7553f724ca8b929e5d19e08e11d0dddd5d767616fa04cf6e1d12ae8accccec73c60881c105286179b91c55e238a07048e198c24185f6b352901514a620a61f1310c6148ca5b6991e349e46e89960084e99a3c736b7520d0c2f1e351e371e3b1e3d5e5f7e2fbac0eb72229ab2d2a93a45d15c00836a9556bc501d443a8e740c77ff1ce49c863c6e366ac0dc9e6a0fd8e1cdade47bed37f14c59e9ab4d4131de67a5190cebeec21090b553e6eeee661460bd12930a4a11a59ca4a2a48c3aff1e8cdcf81985080145e0f0b5a5fabbfbffffbfbbcd4d82caffff7f8e618e620ea81c5239a6d6d7ffffff77f77fa12cec8d1b37700c87b0968da2292ba1a4a6aa0daaffe77e7ededddde7e7ddddddffdfefffa3e6934865ca4aab4abcaaf9ffee36f7b678b16067d7189ab2b208556b48d9ba47e0a3096867a9ea85120efd528cb13daf8f50615384205356fe80c12a02d15d06f8ddddfdecc39ef3ffffff9f6efcb4e3a79e0c07707eba279b0750431cde85878cfaffff6f53821743316058219980b8e40097995fe110e7dd3d6368caca629d017501171c9410ee30018f8f52c8038805adc00d8e1cd711affb7644cf06b264650b6f486a989959864f46102c048d9f5d9370361de4d9700c228aad419a07302d232290775621cd29c73a9be6c366d60f7e426a4ef8569176476a9899b635860d96760514cf288d461391e4a76e394c215937459deaf9a3d1682756acc478b51c56e178ad154962f4d9c364515864fbdd104a754f9bdd1035524a10617a18d9aa8a32be33841014ea32efeeee3a3baf7777af27515a99f2d56e5a7777b757a0112b98c1f272397aa2023fcb867e8f0ec6e64a0cb8bbbbcbae34f302e33fe94093dcdddd5d666666df9edd3d1142a82e3373b3b3922dc9cccc1d66a2dec65c43abbcbbcdccccb6caebebecdddd35b8da01e8f16c5eebd48d02c78523d2a11d6a3ea69b47daa8f1a026daf8ec179f5167230e7718d18131da721d5c8c223ac4f038c80997f4a8048b3669d54d1804331a00000500180782208b522a6d0014000d248e68a8dc7c64502a9248814038188061208a811006611008e22086a3301e576b057d7e1c64ba4d933a44bd961ac1b902e4b13f574e84d967155597ae76d6b22e94d15bb99e884af44b9ba95bc36659f77e9fde84fcc68425e78b61fe5c86fc50b9d9d8810787d2ecbd3b777c628a62c7fead3d89acb0ef4ee8645d4bf50f46cb62eaf3b0f9007f0ec094ff982574933ea71ec39e502e21828ea9c11b9531a16dabeefc67f92960eded57644ba4770f620ce8062f1d0e7d76bc64fa02d6624883bf20ff040ebaf09f7cc25a1ae92d1ce974c57537e94bca0ce90e1ebacb652092bf0f925ce3c590eceaf077ec1f0b36d9b712f3d86b41588beefd181dbb3630f5f93e2acba1930583933ae94787c643ded0d5ebba8130bb8337e93f9c79ddc5f5acec438d90a86328486e6ee5d4a4bf2805d88340883a5e2b28dd65ff1c65bbd38188770f78c02edc266df737ed7f0f3cd4edf40d746c71cfba1c2a5cba659ca18eae6157eb2fb607aec35e64ee03ec6c3bc6e9c901ae4e27c9375eb1d52a8179b057142e7cbab894e560543cb23072f5b5a4a223f60e15f51649e0c6e6c37704caae4aa35b4da587fe3a094e782df682e1b87e9a362c5397bd03af5209f902f4410b51351d27eb788b362b84968d96da3082534df3413bb427ac49d69b186cce9306a0aaed75b5204c20ccd31bded57efe27bfa422d412066bec76a4ba35054ac5f9ac319ae8c392b8ad9494562cf2009f0b905392a8b274a5ac53d9623dde115f7f5a285394f98f72d4ea693896e259822f1242dcd43d21f7506f2312a3f2553a4bdc366857eaea30f6a4dd88aba18555190cf055b333282e918b468129e8a953a4ecf24a495b725985a5eceb93178afcea26d26804a23148c151f00e2b8e34f3b1b1dd5500413b2987291188c8660cd4c6b5c3098e8a45b59aa0cadefedaa8a93cbfca72147a4c156ec567396ac7507b98c73d6d08af7927ec6bcf2db9b7177804a7ed40d49777d45070247947d42c3d5d21dd179fb2c8a9e470da73897869e042239029df490f04ed5c2220a163f4c2649761bff003846ebdeab9681c04a4574c45a8147c9da6990d1385a41f0be121c6c8d70d65bf9c00fcd8a36aa6ede819bc721b33aaa74ab6e811c81aca56a75b7b6645d64fbe2deedc7f6e4f6fa261836decca51bfb898c8dac9938994783c8f5fcc1c620686bb59938a7f143f09d404c736136929ed8783c8db559af35a11b9cc4f8632fb2c67bfda962d508e77acff4c5ec071e98933bea90e567f43b6dcb9a2b78f509bf6106d8de46e737df13cebf8a03cf38ce2005ec9539272202d2f38fb7883c4136e34c6d4121e4c440c780db7a118d2431bdc64f79e072fe34e99d9f27dafa36b018eeced60dccdd709e1d0682c5cbacb01882f43b370b71360396a5b26825691357f6d0cb63fd173ae8dacae1fd6d89b54f713f7a1bcbf87e8b1e3a384a12466d4bed50ec7ce205e5b9da6bfb18c47dd5f19d4c45a3b4dcdf633fe0c823b57c846ac04466e2772ed2d622b2c477ea54848d7f42c41d762dc3ee8eb82a060fa0905439c416c2c00804138105871c8f05a8a4ded8563b6dd9f9639ca4d4558efcf155bf6aacf84a06597ac6192b3f670e5c9ff619f7376daeb4b048ee97d0aa52523263afffed1d42a295519afa23f7cc0c50a49c76408db9ad6c9db99d87bfbbe9b224684a1958cdeb63fa0c90ff14b74994e626ef0ba91bf9c80440d68ba8c862b4f8cfd397852f4361271a5a55961ac1d0e2ba7abd492943971604a42e25e7cff8b906e343d0cd6eef1aeccb2d6b189341962d0f2ad1f0ed385bbc96e73adb4001198d0a55ff6a1def1f3c5eba8f34f4f6e93a03800921b7d362c58941265152a61f959d0651a02b001ab40328188cd7f55fdbf7c119ebada61c1d3f9c37340bab8c527fd1d86b7aaf4d68f8571c3d9749741f6c11161b0010a7fe1c1831acd7ce3a8a4fdf0856b318a067e02c6f2a4893c3747a50e40a7c9a805a4540a76bef7eb42f49d6f99f7a0beba21d418a46249dae4f6068714f63c29c3816192de80450d65f994c45e8413b830fad9c7fdea24edc64c39c48f48511c938e83d458525506f9193fc84d4b021a2009a9f488ea96c09f29f28de5a292a27664fa00c17c10ec3419af08df7c41f26ac034ee16e814ab93e6daacac6b600116850ab254ba6c2d82ff9638d6e8221f22da94e82079d81cfd89c99d548aecc0a6bebb82423807aa05d8c26b557741659b1717d6ed110155f818c350c8971637c782f0acb005031401d6774bc0cfdf9649550218714eba0908c62d60e2351452e45f83610252a43d0f857c3a6158a52a8ceac73dfe0ecb82416f9142a6b8f53ecb0e94ec8ebad8732b5c5246f196da3c84db95ef434cecf90c9d41910ec7238d796ed0e292022a6679cc40b47e81812fad1e15ef1dce9c36c362ee16d448db1863e427b6832944db31a62f5e0ac6107346bcec9b1802672be68c79df71bc157346d1a330805f0caa87654c333d518b71ebc9105daf17910679b83d4aef2c1625946d2fdb0d6f2ba791a702670642ce774104aac343c106642df3e02997833a832faeec5efa383775ea5b5e2b9ecdb3a446cf2bca3be76baa38185f943fc3876ddd24f65ba5d1807d5fd8d91f99345f918f889a3f4a2d37b087e3a8c52c9a54d0a78ebe6f42c7b951ac02a7335017aabb6ecece28f474cc7245956473cc43d5082c3eecfb10722db5c195aabee948b3f97d7204617d60306ba172e0498a58ff27f6cdb320cdac278c986e3b27c2bdb610e0efcab76e48e939a5f924020078bf7282b0f6392470aa88cf123cbc154c7571ca5b97cb323dc274bc89b9d052480d97a1bd59dd894d97cb76158806ecac4ae4bd84198af7536d3c4efc8f4f245fd8f97f041a65c5f7da302674dae2723fafa1746734772dec1cd2e5f2c2dcfb11473f8f35689f764d8b696be25f4ce54a2122fa5e5721e6a36e74e0ce22581a6cd2852b0877220fe0e927cfacf3450a576da3c52fc1dc0105b18e56b5230ea316121d4f32116b33d2c34d7d2e6141888e20f96a67934c28aa236778264569173e0ac7e56dae2f91f8fc2f5f051064d42be364310995031ce3e21fece8e6a59a451ef6a534fa166543e504e876553640372719c4882f2347de7e45d2ede295c528686b19590eb7486c933a2d3ab28ffb212c6e54f0dd9ccc502c0cd0d4b9b42864e8f1318f2e8cbd58709ab6638c917735e2db31a6d8cf755b80b74a0a2bc00649c0ce56b58bc2b346f2c0d92d4043a6675753885d442e5c438c316eaab825c82a668dd9456ce9af5f071f5b5aac7a521583eedd6fcc3326d9b93ed047bd5382746a8ce755661cf10ba67f1dee3269ddad29b992b1c3f57a3c082f2c55a408a057082259aa6aee98cf171ffb852b0f610ea59cd06125a014bd7106222e65132c843fc028429ef87d2b44e36174a8b21c4822338e5212d04460622f202ddcb21efa2a54f5f10c18c66f88bc10d35e3db39d633f1ea2d00727a58fafa56146260217afca81e4a097e769c970e6ca74e488b95d52297a766199b29b08c36501ae8de2d05f80054f310e88cceeb9fbd6114d5ebba0f174bb10a2f246493749069220d22daee398ce1762de5074596f6936f93c30b6a82c1445b62f9dde307634ae22209b27484a0db6939fa0dd1b59466a26e00baf89446996a4807aa97bfb9586032b2b00928a8a9081601638bd8f356e25e861b30df7a429056a244a7a869015848a82a8b48c1d14da0b81c6398df9d352131f444664e0b0c5593bce5922b52e99d7e572e4286fdb1ea838152796ffb48113a6e5e495bd2e2298ab6dcbe8248f45555cf2b932db916c48d1c020eac3de145b06037ae1f5a5718b92591b741255c0712e681000d37d5066ec47e224b1e3ad56e9df0556f92eed6311596b0f11fbb30e3bf0cc97faba27ba8cb4a2644d709d6231cb344f65d3f432eefcd7c8df8f5631e1661a337243e2dbc98833f858a81e90819f071a0427823f91edd95e111cd79251d418de3266150ea8c37229167b22949f50a12aa83399093c304f3e730e3916012c92ec154ca4c3bb7ef1fa712401d4a3d09c7000fd123715a550272f493d991b9844940d2ec717a874d18a42f3e28fcef739329fc2e97b403f3924a81b3258856c11bbe5287b15cf5e59893a876146a353ad63cebdbf126bc394c088053b58338bc0cb75958b6c55c0b3827b9e276d8cf5e5491cd9d922a6a08be4fcfb23930cc99ba53aae7e0e9b81d4cd0983d410113e68d63d01e47e6182085eb161aa9b0bf4b9e8c6eb2542104df0666f0726d2dcfcb6f6f06550c0fb5b4c5acbc867ee2afed42e91a2d4bb39a465800b756fb6bb7b01b6e17af09728dff341435f16214a8ba272f195ab1021f1dac81ca358257746927d590c94d4f54e10281e7fea8a29f8f70036f598bd255a13c2afba19dfd8654b92105282a1c6707adb9e78d218ca81e9d8fc0e845300df31caee77d70b481283a4a412505534884a2a346b04d439c8db59b796221781a2880ba735dcd7983a5d03490ed23b73df1d6e72c0c053fca0f4e73f231245a02df1d3b1339063f5fad161ce059bd00acf4049778d42a72643b768977f22b7a0e3d8f9d5f92a937933a0dc72f3a22afe6b2c947978fe386861e63ebd67a9af3a0af403bb1585ebbee8c5cb97fe69613b3cbf3807805c226b6aa55fd83a4f1b97822c02da91fb0858e6a105b2f0649c0a08c8352171c8987763dd73d7b782ce0259dad508d304ceb7a78cb291e0b682eb173aba5c08a37008f1a5cb044294e524d03552f289565d5af5a1a0a4fc8bf0d0e84f62dee4d8a4731cf5056a540093e4dde8df53f5a6520de3277971eb992a21bd344820ead9eb549bb4b41228118e86881e8cc7d1bba7f651d5d270a8bb0cb8859e33c10356f84aab6282e3078efab3f0348a977e9f70a219051600fe0464547f826a2575356ee231fee7a80e130877b3448ca966906e1f31266e22a0bb8f3675014c7c71ee263438723c281e79c2412218275bced40f08011d05dcfe4d185329d81c14ffc4ea268d507a6f85cbd9485779b73e3a65d432d1b415eeb6b32b6638af5c56e23709630ab9ec23d1e8c1c53f5c248cc23648a120df4491615f684396abc6f0cf961aecbf763e5b6c815b31f2bc9791d5cda071d56827d9eb140c92ff1b4640e38ea80c4322970a0ce6eec674cfc91545c705ad34963f5557b3285a3db346f08c0bdaf824d733f23648d03792275e7505d7fd9a44c0358451323c1b6c5763816ac588087442e59c88ebcd7cba1e525c4c836043cca831740205d70ec6196f636458282e15e3a60feb6f53b5ab68cbe84b8fd72602d3255c8e06436541d3c070f90a53dd984110192aa1a68786c04853bf6a4da672fc02977672a920d4899da9b21722d75859b912af2d731becc665da4bace8795f2e07dcb297edeac791845c1da652de9b645341e5eb2df957a84ce233fb299900f433d91e47714b1f4ce443d89c36cd24d462bf418c30f6a12cb1e4599eee479025473e582ab2f45a2f26b587c6570ebca7d424c37b636b567431472d94e330b0dc22f39b45c568098ed23e93c6e8a1b2c75109c76d71769ec0d1d0e9d46690213f8a0f8dead785e25e24a2c6269bd288ba589b303964f2affe6e091a9c19df32e6b20c38eb30c80914973f4bd68f9b8242648562f04f5bf039389eab7a39f820902c902080f00a70cdbc2bfaab1e0818cb69849b5414014f0258658c3b89278905d69470cc81d156602860faff5e9fd788a13c95726aba0210943bf1c6a6e2dc9769de80391a936663fd9d6b7cbc6505a3b97ffcc13311d4cf4d67b522c723f2303700e30387140912352fe1ed8795be896de5a75cb346008f9b59433158c816064a4ae71a6a240124314d0df2b1bdc761b051f1c2b010e8d1826f135d672571e1c59775fb669a6c15a8f8467ba5c65bc4a2d5344178d523960400d068559e9b94471ce588fc2aa7b6efb88987d1604808c19b0be7a9bded4ec54a4ea7d3ee77228c697e89b298f1a1a87edf9f5dbbced587bffb4423a949f8d17b05e8eba28a65ac27e8cf20292eee9fde9825792dc4137005ce8cc0722b99e91951b8696905f26bb8e664288f3ac1ce69813fc89892c613293a85e5229e5a6421481961185079570cb58fc7a8b2f14a2a1c441a5f4c63f96da3c016300d26cd6b0bf6bc10321066abaa701add0af88527d356cc11d9b608d531c9eeebd39f315a6bb847c09163c9327ca39e16131955545c3a6d11c9860c47fd333681c6922b5506bd671d3d7397a10ac2cb9a64ef3e2348a33d7a49d8ba7871cc9c870f9b9b500cb1429f6d7d236310b4cb509630c3393c594f047aa8d0689aa52262c287db4354d1cb587d09fcd9cd004da703d4f59203ad76aa45ae65bd3a6ef8655f75ee3480554f37041c3b31d2de4c8677ee0697a977866fd9e92b72293cd709d5898e8c521d9f363126d15bc8d98273160331b01ebde61c8594dd76dd40966350cfc8898bbe0a74b8cb2faad044eb6f54cdefdc2984532d1d3b0595b1a0c651769f9f49018ba2613ca3a1ccdb63bdca74938eaa7c33e12588245746aaab0294d7b5d48ac8801bde8d68effedd42e07564946038d119555e937335dc9547e9c25a2983a4bc22b010959dd4a0ad276d399a414bb20066fbaf03d75cb92dce340a992bc6e5135299a6cf42b23705b0676178891b144a2981ad22a3cf298e77ecc895b61bc8d0635037ffb274e5dffbd42edebb63ae2d8c77749f1b51b631808c83a52053d19a09555b6297ed93580d46fd7e32f3121f26ac58e183dd35bd7d78bc36b513aa0322af1f93d4f81c422eba3c1cf7757e378d8b27b49712239431b16d7b7699a227e2aab7723d7d51cf171fe867d2a19594ea024d607a870bc577d46e9915871f4bef48ce7db77267ed0c2b41e92a7cf275a8c583c291205b1808ff1673dc2e3baa44c5b9b2f7f263993f3eec4641a592daf00808b7d81eff14b92ed542bfc93be78802f15ad3004a8923cbe0bc14e9b7b23192ddecafd2faf00267e28acd718a86b168a86df0c2ec8bf006d7343f0db1ca387616a254f807ae0d6f985b597b6809f87241729f27e720254cab609d90a75c30d3b57e3dd4fc8be66a3c3a51a643e4df301f325fb5bf40478a7dbd8c704a1720411182e98d7289c6a248af3c8db65bbe6a14884157d5ee0903e95e0d024f9cd612f41a4c8ba11345f920c1b8b7c644b6592aec044750fd419c88d7ad648d7788d028104d8d074b8cd15cd63fa056b4f9aebd7d0ac250a7b04bcd38f7d71e0a75f611b946a6c50d2921dd1fa69ad098d13ad291d3e7baa904b89bbee5b1690f712ad69a4ce3b871c3ae2ed0154ef5520a4a5e7fdaba71857c0abd348dd8d9a9ad6193f7411abf867d7b049e3d8b6784dbcb1b8fe44b4f4d710076506886b7a91b1895988f1c9cf3f9d38804890b23c400c1430368e79be819a72606dd9f1805b88e61281e7d8c5f3b596adf1eed18fa07801f01296e041713f3ec43b7c2581583ecf7e13d8cbfa61426f8cbff9e9dc1d40996a161e15683d5aeef9df1567504c4aa1f3f4e6ec9d43eeb2e9981baec9257cea189991f9672480da1a3f8279890f68ca9930dd83d2750b881218ab158d9ac2a04f44b90e4c4f87aa055fdd06b61396fb6387206d94e066fe995e71ab4522aac867d6f41b2607f3f21d9e97a0be9ddca2d5898b3dde20b9933eee461adc035af140d59cc3359d49f152d3f7a3553793020990f434a02dc64be5c89a5964fbec803987f7e6eece3d89f1224ea2023eb198464b0f4a2b9c7229bd16933b9b163ba869432203bb3bfdeaa75fa513ef1e36d24a3f70a40ad5deecaa84b7c6f509b9aeae72c97dd2fdac218cc3983db476f6964d351c1dd8cff2c18ba27d64c805eac046d3579cd4bca94f08c9ca934d65a1643ed323ccc69b415638ebd5658554cba7f7df4478cc6b23d4fe974faaed26833baf145fefe43a2408c58997bc1c81dce3c08fe01d56fc520a9e3df4d0aac4b03c24ad97ceab3ddd1a3213bb58b281784895d8ee33d15982f1091632ebd0c42894a2097f153bb4aae2e54ee0bd5ff92cca4bd2d797c314ce018fb6217b5ad43d8dd69592031b59d06a5be6fe2b5ae851ebefac5e79a6ad3b6b1cf4da5339883a7ceb16ef415285bb83cb03b5f8ad1442a90855d16fb1026e4fd311fab3b9542725459af1f6ffc52aad0295588fe9945bd6763fbb71da5229ae0e8f2a2290cfc5c09b1720d4ddc701b8cba4e211817b6cb2aebf2314746e32ff59299b8b2903db4ed12961bc01d72ab06f139a764bb62e015b2df9167eafe665af9dfe5eb7e08f91d357633b019d9def7253674443dd9cc7f27d72bbd1c166eabafd021f1edcb32cacade0ecd3097739c3774acba693910e62aafc22c3ae1c00c41d53a69bc88eea90ed7a04ab9f551f91772e952b70d2868aaf33aca00ef60484bc945c10119daeb102ac41babb04c1440390a1e2c3c6ed7ad070d6612a1f2ac0ce6a0039172ccd9c880305fef2aeff03d17525b805b9e4e0d65ac2b0994ac33a55bee275376bf7ceed13a34a488302be59c2c43c74381d13c87f586e4c521fb8c408fbfe8c7731f7841fd09f0a151a4eebe614d2b270aab670b05448618401d43314d6d23d0c5547040b3bc2402dd9dc05d4cdc4722e686c6e42255481d487915f1cb76fc712a5ced00ad462b0c0e815627be30a385f314d64314bd1a449df58573f068e142699d2bf996c25782d2fd7e706968b06e14d701b4bf14d14a611cd860254c93ffcf52c6c8ded31fa6a015d1129a48ce94c3c18e88274d91a2d31bb5a95b8c07c23618d2dca20e4f55577e59fdc15eb4c3a45b3ee6b1e4f8ed290d0b5296dcfd9acbc89d7b40bda6442d842efdc79c9b1163ace9ac470465117bafe6c724707247bb004dda38137dafb54f23511d032d83ab344fcf75694c7e10f8701f974736409797e49004b1ab3454779653d93f11427953f8b28bcbcf700045061d073ddc49ac5304192704cc403248e8fe8c88a7eb899978b12093b5411cf4483a0f7d1888474ab5e03d9b71261967c242a83439a534b7c5e6cf9395a8aa60d8c2870eb4b5c25f0c8fa2d81b2964e6d54c404b46e488b9c3074df43a315a9ab3126ad662555773da989281763611f0bb9ce6a3aa4bd191877039e6467eb795065b024293738fad76ed821656c983e4094eb3960f4ddecfbe46fddf03a5d3a62268b63d37db6a7cd55b803618d47c9bed96d5d8811bd37765bd7a1aa6f38ca2998ac811159f084502548c5b8d07b38ea9326c112aea441094564fde82d8a76d59b1078ee625ffa5b0a050f47015a19e832a44119a3fa40d8bd651cc0de75d2061bf0a9a715917a5185482c4926549475e3dd9114b2b8b691a2233e1331d790f37f44c8f40991e7934fbb4e35ae1eaeb7823952725d1d91b87486bdc3acce36e154d8ebd96a9185ec08b853325522b96b2c8b275e4f15c3bc6e10104f9ef0e40505551f3b8811c425e6a2bbe63d52a33307e697c659525f2121b15a65d156f102acc6af8362aa03094c871a7b90a2e9e7c0fd544c0c0517ffadd38a2db4aaed822f54484a6c5af26785f87572ca5d9b03cd574bcdfd24a45f73b178544c3775c3807f31b564f591241517fecb793d22802690eb0445485b834ede3dc69fded4204d19f00b5566230ca56ca69c86cd8a6179d63830568b1c701e3f2039f6173a8c2123c31b56b3671d8ccb62cb90d0102cb582ae56ee59e60cdb24c24408af979e545f8a340bbda752dc45e22561db8281d39530c7b0bef4cd49a5f22d189625411392bc551712e5de55fd365ba8ca4a3a32072a9267bd4de4090d718383c997a5a27fa8f39482e8b605e1a23f01295a8845d7c05217a1fcc388bd2421a18db909522cb23e9e67909e48f3f529fce852a0e93c68118a4e0a8e6e5cf3cb05eead4a43c084b285a8c0666e174685b4b552f0ff65d9368a10f6e952eb2fba3c3e02d7632f5167d179f431e54b7859a3e306c202422fbcb3567efeb9e11c35bc2aa54a1ff84fe2f945871ffac6cccf898fdd6be609554db75602c2441794b969d9284120d282ee28297b730e3d4ceff543187bb9ffb0c07f237990a279cbf85922774bd277a7a2bc28050f5d40afaa292cce1405a1f2d25c93332460fefe3e5906001c1f13a564f83120cc8e38ab204ecd32e3790876b27494b482b687e2e294596ab2f0e7e978c4b9adeb8e314f94297c0884b2c732fba481b3e93a641290a0e5e4ecf5d0c29707142c2b8a418c2f7cc22068f38d319a1eb355c8cf1ce07fd0c333130bd43a5585c0a170acaaff28ce64aa70a48d2bba1174c4119a732aace9935713c5142805a92326c464eef0ae7f56d74b7c7e649f64dc8256e8cce5c234d0adfd3f35f79d7f3afd7066f84abfae402cb611adc4e69bb167cccf1c038c0916eb4b9e89d06e62d9f86d9e9c61178b3707add74af4225fdc31611fda012581298b09fba7ce0acc61cdedbdd7ff5d1a682b581698eb954a4fd0389d6660025cc40f5df24126b1e38c9ee39ca2c84618a75ae8fa3fd0aceca41a4ae22df8af7dc2065c560316a0e9823650bc725452f02f56d31e35f54afd2c4ca437c83d12b10cf1de535cb7ada343b574b2d80b61d4725a2f8dc07d2b5d47ee676b0cd88d4bd8c092117026da5f11a7bc1512ba4ee469b4753c4f58e6758a1d6f89ed017e4ddcd7f56548c60fa5b9ae21544282a3c7190e4c82620e5d42d5755fcec14fbb9054e807ba993e1512ccc59e367f821037a2856f0c6b71fd3bf22a35a39b81818ab2687bc66b255782f79e19b23907f4163549821bb73ec6ba37c1bc6994f0f795dc956e1bca4856d3fa6bf2031ea8031e68878751fd902ebc2eac287891d904936b781696d5d3cc91b40f2b160124fbe7003dd6286351e269c6d33ba13bbbff8e4063eeb4efdd301b9d80872ab801b22cb3315e7324344eeea70166d1ac42dcf0b06dd36026fa865072da53fbc5af9006414bc03b0776e380cb442bda5bc9130141c0ce46be9cb7d25f8b6f06ff3341718a9b8292641cf178a2c1465578cc1bf7ac14bf4faa9982eabc2c03b220c2bff31c1a5b83cf98b224219a6d43efc31a429376c85aaad54b0b0d9100e6b2c221394a756dced0c89d96c0ceaf4e8511c4016cac3e13b1f038375b784a44ae341b7dc7d8fa975446be1175399119c9224d46a900b3e7bc9b27f3ccef1ef960fac7a5fb26c852c4968468779eae45c32732ff72a665649675a30da069105ccc325da79d09409dc2c259b71a34d395b55b49ddf70f76bfb38797d20f7ac3a24351a896ce0797187eba3c6b77f2c523b2e3586d471ff20279d8af217269ecc0ca46748ce9ab7b083c904669d569af01a409c3f8f759277492a579e1493710430713c18ff449aab942f1d5d37c40e042657cc330054cf06f027ebb3021ab0c54a9e7fa142e6f314e46e60059649717a4c1de33d794a8190e297885c330a21d81c08d75408727e82e2a9f5b4be1a244cf2d0ff61d69cb61b98508701caadb87c2c22721ea2041179fe233c1ff3339ec2b872df2fef27b92f6aae34300cf8326e1cd01f92907949159aa30a3ba44929ebe0ca78e7537385fb7e8d2ea13e10fb434549804b9976a07eb223176a0d398560b21ca9dd7125c6ab60ab993973c7a7de7dc0dbdeb642c38fe5ada37f8a30f082d06b9142da9496213b16e3d830f85b2efb76e1330e546f0189edc8ce36796ed0bdea48550c7217f3d60b4f3e2e9db41756a34fa1581a3d8f9cec1d21720d1ce88d1efe1a48cfc43b2401e3d6e244d335b02fa4a0f80ae733292808439d3b55be690760646a55f2eb6eedd055141fc310364bc69f64a6505c6c0b805c89889dd9e31526772da3b1cb057883e24568091dec864a727b5f0dc4e76329306088a4a7999f17a3bf73ffe831ef948e588a322965e50a3a4be2366f12a9ea472256e4db3afd582758e8de625a5b9ff03666ae08acd1da03c7a641f1e2a67adfaaca5ca54fc04fbb33b0a25e30aa31a2c28cd82515f99d2d86da31baf0ece782671008886723e5cacb6f1601a48526ca6825da28dc595b0ae786a0b29a3df34a683f909f9ff93b4a51bea556e0224f0a1e239fd37bc09cb6d2e4ba5745cd15c09cebc5b1aa08fd87c2895ab9c530f776c506ff65eb17f1f3b4b6b9b7bc9db43e2ec1ccd4468de91b573d1747d77260099feafc7b01756530f9f50c972fa175b57bc5ccbc1108fd76cc2e22a83df1a1bd66bd31e208332f369c94a81fa76eded8c5a16db53c14a294a691f0b61a95521b08d7af280bf882e6cb7c950281b96621c2b38498bebba1fc73c911445b7e85e023bf984a1057a6948750f56b43f436cc204c7cab61cf1d5e3d817c8633d33510045ade5fe1726db2c35dbfcb6137c823520c5931104d51c55c11f032e408ce809e91d79f6ad21b3b570b2521c9ff1eb695cec679fb2b638db746f013a07a5a2ec8494450110b5c5299e74cfcc656600b4885d179ed02cfd6008dad6cc914df0184995fdac2b3104ca7136730069154e902d8ac65b21ee79ac6b2b5e77a3374427dc5ce54b65de8ae4bb059ce1f59b350af91b652b37093986a8f747c9fb0644f14cde32c7a4d1554bf197fd1ac53a9ae06f90068b402913a55232e9e5bc332eed01543ef712a310bb54172138a85c0372405492f575686540c03ae164cfbf389d5102ff4c7702075cbe9ab7deb974ef415ddf9563704ab50662b7da2ca1a5b2ae7fdb22c619bb19b69f9070d6b2e322b624752c93314e4d38027696e790eb1e79ac7887d54860ba5b9dd4b046a0eaa546b7f808b0bed87b647b5a66cd0b7942b9249918853a5c60ea5540d613b127a1906c7da8b3f09e84eae7fba11684f2910c58271d322859804d856cc1169f55b4028ecffefd9bfb22b75c26d22cf557b562e0d8cb98018638c11981580763ff452d8a6494f8f8f13eb86c72ee50b34b24b9e9f82b111aa56512621581692e69952a2ffdaa0f1d7cc9958dd914b49eceeca4f296677e5c447519336d4739a477030d59b1a8478472cbf28343b43647873d912575c093ce290ad1de1a0236547398e5a1849abd1f8eb9c79e8226ad5081512f2df92ecd02cbbbf8e4db65c9d43a56bb198b47296505e2a297399da8e0a7ec6fdb97865b93a5fa5d2175c30e260743340b71b3684f9c81e928bec2bf37f2c8bba2585404a6276572e65b13b6b0324e2987f7035da7c1aa18c5ee67c69b3c993e63b980864db3a2721a1879f1c9f7c17b27211eee83c55e8a9c8a4cf91ae5a222c61f93dced5497e30e8364c889a343c3ccca9538bb5b2a1ee50581ef9afb7083069a44888a0841ed9b21da35db0165fd2dfe8209140a568738112ce2810504d3cede0adb1ab8e3442d1498b57d9bec8dc3bc230d4a47c23ae3221540d9ec09619049213e03465a31196a4fb6667e8e8b560ca7e6f88b1b9fe6778ef693c57fda5625a8d444215b31c2ad9eca8f2aee58e473dea6bf75f7eb72eea718bb73e9ef153312dcd85c6084fda49104487382240dfbd85e9d9b02737d039e146dd5de092aed8cb22ced6828c75597a273f961d15c54cc08ad9dd1af456eb2a832b9afe11c5043348803af30a7dff8e7dea6cedb403411365985b48bb0a378a8feb7cdd0269a11a1e9c90992e595e384880ba0296972f6b76f6ba196b1f2b09028a9f1b0091e75f1eb7e5eecf4226d9b54cb060af528308de64dec2a4705baadc458ed896e9412f997c11cecacec2355944df1abd29ae5a911ebb5817a6976ec3b576ccf12d888dce2a370f07bd723e6f0b37ab04b3325b70d2fecae8481aa300a32d51e909c67d76414c05168d053381b6638cd1ad25d9b82e5e24912b94ebb5889874a3910dbc9992a741d274658a3f864ce6a00087fcfd989524916035026db8f0916d424e6904b48166766a8737613a15dd3ac323e86f4e266886e8bc2646b46b5ac491b2de90ea746c564bcf5c24591e7e5f3b6b369b5273335b16b88dc4a569b4f43b0d6794b581e4f8835da09ec8ce737231975e598ed5fef1616c199368c6491d319a973f9ea95b5164bb06bfbfb99196c8891f17453a60469628bba7d200aaba293f37fb2750651944384a8041277157fc4eb6d5a48e2a4ec674cda310a6830031ccd524558996d815a8958a221dc95a4252915422f92fb148c5aaf6632a0fbfdb8b0289ea02be50d0c0be04ad7a89679c15ab146f4e4df1874b3552ee7320fb39fce680d18eacb3ef65294f87e9dfc9aca73df392000dc520450f670c3ab6b89fce0d0de9746d95ca00a5845c16f511c3cf77f1bbf2f5988e853641e59137907f4144ee7093538bc843466ebd2ec152a2690a9d3c266b74b41cb891141f797b15160b1766d39d91390a04a6dc0c61d9046b3044f19657d60c5ec83f87dace6bc129f5a5be08720533b7940cec470515ef478e5a2c680be48e01ba33ad4359400ab1950ec09342b151540c29141b0bed19fe612fc4097a521afa509187274ffb50ba321ecc80ffe7e82b091f683ea0fe3fc334ee15369061f92805a5ac7757596d3e0c175c45b537c150b8a13776237b4bb2a54c526eb977bc0310045304fe395927877c53e410426822347739536724274079686a378962e0bdee730846e4508726f80c39686abe91168c8ee4f9d482d93a9c2fd111e4e73ca975619ace0dfa269a612cc7bfb19b07cdba1451fe88d1fc5c9916ee508ca6dda0299a96cd8ccb103a34342fd4d67e378f3c7df3485e0e6abdd8370ce78e048fa3830386207208d3421322873aa4937bb2e69d0fd3440e152a041d28944441b4cc70cb0ce808f2f3ebcf107e48c3bdf3fe60f8c10c31a89fee6cfd3cdfe343801fd066d2e47d7a61ebef811e705ec3d691af7fb6a323c8df79fda9dd691a86cec1ce9376976f7690cbbfa83e33a06986d7bd9b6205f5c326b182fa3a3a5025090d3b7f4a42c3be3f41d6fdced9032fc83fe2eebc9bfaeb874d2905bb56b0f5a7b96a3425a161973f016abd841f329aea749abcbe339ce0264992fc0c21e93502e2eb5e84f8bad46a28df7f27db4d9e40f924a161efa0d64b88c185bf67affaf478ea06fd3a3caf3f84ba61f7faad970d39af5f43ddd07bfd1dea06fcfa21107ed08518d4d72f81bae1e6f57f503798af9f0275c3f8fa1510bed6bf01e801e7f573007ac0f0fa02cac3a3a3b3dbedfe03ad714ebc4d73d7ae5d5d24714ebbad1e4f124d3fb0c952a7d19d2fcf1b27cf1276eb103768689637e583a5699a6708ec2ed19bd36eed24ce296ef3e6ac3aaa4fad5067dd37237973eebc795e18cf0ef4ec113bef6499b32e492d826508b287c4cf2eab4f46f56bf2ec40cf2ed111fa795e9f3caf799e5737ecfee6fd79feafad1b70ded1b0a6ed763967fb1a541dd7a57ef235799a99ac3ebc5ef5f10ab499f66c47c79d9dd7e70ecf9992e8d13912e704f778864eaa4f7df30cd7ce30adfad4dfa1d51b75c3ced79daf17aa8eba011cb3b6620dc1acc3414df082fa18ce1d7841fd9d93577dea5f38adec93a7456fee34bfb74b736badf56b1b18662d4b5d795f9f3c93444f8f9ab701b8355ac2ee300477a703aa4ffd1e50de3967fae499f3a5082248814410731cb4bb4c569f94b73b3345517cad2b2d90e2498ee48f9f33697e98cb08e476894b11378fc1fbe150922e43689dfdcc5f86c8259ada5d7e0e4804a5ce3f1c2adf4319e5998adbea5a6c1de7e93ef71ac77f97f3e583a5073c34074d6ba975d034a7cb4fcb5ca9d391a97edd97676a6e20110c69321d411aca18b17b12b62ebf74bb73f93a5403b1eed235a865e9415af7eecbcfaf353a6a1d5a024d47547f9a434bd45d660bfebbd79fe6344cda59eff29316bedce9440cb9273f77c041f9da83920c3fe8d7a1a4d6399f86499b2c45e85ea323f4ef3e5792b9cc413359e69c7f2c4594e4e7b2247f0c9e8b467035110112c68a12190f555f5565e489261805d5172a30d228f4e97c526c889e803c8d9535ca250e7890a992260e2be8aae9290dcbd38d8df5b8c1b0a7175b37bf117049bb6a82a242d3140c1954d8ca07c80c166f279aca94bcf88511397d098bd1655bfbef63625bd0e985cedc60580c29fbc206c3628035e9d4ac20e4a50f5d585600fba1e6838b8bacacac1faea28aabaa2b83552896d514e401af33273f90407d39635ba8bd30532375e34aa80984ede2aecd8484c0ac42344ca1561df1cd2d5d0f35c67845188c9defbdf78685f96c8cb40debbaf2ef0113b3751b0c03b3b2d3ff1981806fdb33949cbbfb5895eda5183c644a23f11fed37cc8d4d467d6f6ef421201f1326646e66595f6c4c2682d04611b44302f889d5447957c882115fbf476b8284f1e5b0eaa255c52e0dc15e51a28cbd678021e4cff74c9131256948f3c88e31c61867cf4a4118b082b67d5e0f5fbdcdd0e296105a9482589213272e315609eb0c6b2daf98c0095a64cc9829d2640a062c2260583d8c3498ddb48e419b156f57dec6e4eed1bd37e90dc9db137777f7b71ddb6683bfb7a96b7f651819e44a9ad814e11531175e3f30141905c67ead56138f3285acee3628e642079916406a5610ac89af136c4669615aa2e424201827b0602a2aeb9a41c3b2b816b43f2f1f5e68ee3e65fb0927a302a3f0e506667b60d6634d8f2d6f5a4340d8152874c9205ce3d225d0b00c51d15abfd6d074344c4994b8e18bcf537dc0d76059d13484dfa1b5e259e2eefa60cfd6b65a1b8257d7032f00df92a635ebd081e4013de40d9a3599b0197c93d7e3c9007ab0f02098f6a43e04f8d9a23d6fcaccb00c716d095184189e3a9f389fbe4791cce7dd16ce0b97d4a739be1ecb10e378da9d1373a2ddd792f914f79896cfba479d497d9a680a94f6f07276226ae2a038af5febca101a0d6dc4fb36a5887b459c13ac3e3b24bc6de1cc7f637e399617b5da7db933477324b3c93b7b4844dd912d8a0077fe547cf1b1cd8ba2cdbd156d6c6c6c723765a6289e768b285f84b02c7376e76c9851511c45c03b93b02fb66fb50c61c52bfaef8719b85db4606a58c37f1bb13c72b1a7b0c0927d552e27375d165a11176757d62cb1483fb1a27184155bc2baac206182618f8c90915d23644efb668346c886c0b4f87a246d9eccd47c40de2078812e67eb52479ab9072bc8a15983385b5b124453ded63a34e579124d7bb636b74653fd249afed665599279d8f9143cc24182d7a5a369584620b749fd632902e7cbefd50d17debe851fc07dc17ad1175e7f2d43e832e7ec67cebd599b4230600e4d75761a36394aa23c40740824e7eeb973c408eedc73b9099edc8db92f5f836abd841f784f8e3a37fe8efca960eb1b9337f27478e808de6b7db34d936341fb664b0f745fe6a475e780d999821f13042f801ccc9e46734837a143a2230229ce305d13a3ee6ed2b018c7ef759ef5ddcff75a8ca2cbd1c5be1e167c5f493729b056eca48ecc22ad229b2220443aa2b717a50b1245dc92f619b1c8f9acb81851a48094bd58e028222f4a73ba40942c26db17a7a8b22fd2be174def7d7baf591197c760265b1618779d61fa90e58b8d164a9c92f438e1280b6fa7ff932f94157f1ce35c8faf302b4adad6b191099b0af6b6c52d80b6968468c59d09aab2c60e81da167b100ab7d75adb838d804a50d3724b636a4bdb61bb868e7c50f048f1df9377fa3fd9ea45190b262f6ad4d0f2b46585949de1b0e206cd542009b38931c698aac7c618638cb118550af147ae86a2ed81efbd97877dd6da5ecf1462ad45f106cd8ae2b6dea9f9164a57a45a47573a1b5366acacad4a85094040d2ae8ae2969ade9c8268008b1a1a6f64585dae809c699b379b284f6a58ab6fec7ac5d9fd08a84a46519227626565b240e01f42fc1ed5b02b255694b6bea4b88e72ec3668764403cfb0201a256f433cdea8a420c6faf819af0d73d5479bb34a18636cb4b1ad4aa61a232d4782c8e4d0ea7126678366465676fa3fb786154fe0d36fe5da6db0ec6d8c5a765f8671836050d65811045d7e9cb941b455968447e825889a3063665dbc76e0a00b8c0529e52043c497c36ee59d1284aaa010f311060b84d591c3b4b8b5f6da8bda315f300cb4d062820f3129a1b41c4c4fd7c1c636d02e192d099a51761455e4cb6a3111993c2bd54625ce0491272a9a2c8ea52c5acc32c606ae00d14aaad2e28b187b63096d296b061491a1205f41336cd6d2560fb9c1df528d9dfecf9406b9706cd901d8a0180eb01c159c49777717db5ab2ddfa90ed2c62684569695950ca406b4c2b6927b6a5b5336c506c4ba9877971b69ec2dddd784b6bd6b0c064b16145d6c46249ed9012f334212641444586beb67680707bb53daa8abbbb3b36c218630cb566f3b6fd9e9d5aea894561f12cb0506e713f720e106ccad89a891e3dd6bc28411c97dcdddd75482daa9eaaae1c07618c838e422a15f6cd06c1a8ac983783a61bb9fb0a522cbc4903b8603933e5a50b132cd62a4a0a2caa048c31c660524e1b3b58548acddb201814189dd516ac2d3574374cf0417c24a356a49c5154d510b439a415ae7684ed580b22c4c586919951122410a4b89a5899a9128589ad2a3bd264c54d6eb06c6c0533aa1b5d4d6a9cd0b29819a34242fac1b9318de7eaeeb9111bdd3c66b8f1fabdd77d198fc57951f1e69b1b1c8beb4ac176e015a7a54c095dae30b1530e8254970931dea4546d21491dd91655566e3678a4ca4c769185055658d9333e62a3481fa932db391b3c6243491cf34195b72c6a5158fcb86cd4d2129aa4256788d2a000658186bec4385323482d8c195b8345e9fbd285f1ae469a1f674ba05468a181b334ae885ca5515540ecc59030a6362a3b40e01969c4b0545c7589573aa48054ace00a83c6c4843523194e82ac513142336363ca3e591109c34171526306851335ebe4eeee9ec7aa2b398f4a6c654fbc240d915a4a03c26d8ced6b645ba6524182141950ed8ee6a3e9efbde088d190b4e780d7e23536382651ce28cad06e609f9c73fe0cf43c1332e7ccebe59c73ce193b762f02e221c4852b4794321d35c27e674eb8392e23ddddddddddddefbdeeeeee7eef757777ff9960ee78bddf94cebdf7de7befbd17dfdf8b9c73ce19ffe0acd911f6b29fcf82bbbbbbbbbbbbfbbdd7ddddddefbdeeeeee7eef75bf6565c892d7d343b93318495e655a7c213263053827604443f70c8b262d988919f1d993d235efba20e10c4d0b245f3cb228d16026e50ced2fc63f7add8c3f8e4eeebdf7de31e79c7fec8c9d4ccbc2cdbc8cc7ebe20206cd6cf3bdf7deeb3bc99032af672fd3bd1dc05da161c4a4820a1510d7c8bebe9c289f220484094bd2a1c34bac8bfd7aa122cc8de3dd2b74efbdf7ba5ba47bef75fc56dadcb533c653eebdf7e6aeefde7bf1d0bdf7deebee370b9515b95539bc8bbdcc2c09e7c88e32e7dc2b3b336281b50cc0ac8ae0b49aac8d7955b0276a408306a87293467081a68c0cb02c5f67457e5c8cd830509114a92c3ed0cc54c4a0604bdc9635bca465c84dca538b271748447e5bb26c29dbd215ee1142e0c0072068b041f511bf7efeb1625454f8397cf327fc0ee16b10fe06e17f103e08e187103e07c2ff40f8238421096198c7703c35fcfc5028dae24e7f36f63577855db378fabc885d14af14326b4c9f37356d69a0a04972e6481c11335c6570a84045e669cc129c142231524c842903c6cb972b5ea274517b2b73f3e202644b0e2d36b2ccc0d2e24a14232b5150b4c5550143254b0a284c598282991423514c60db8252c2931a4e5e34614362c29662099a35316a5b94a490a4491a1a9230b4ae331e6658bfa8b22632282c8e40091a53233626cc0dac8a91275f695e63454e20e2e3841b43a6ba9c843c5132e1c950901580a8f0a30b97151f6c3d94f020db5164eb870ead1c555a327030dd705294e5e4049699ab2f2560b1926263adea47f53515444a479415148d1a2e6834399ad1c427e3cc5318272d31a634318171f602cc8590163b98ae96a09460243159c182898a156990e08eb818512972428464484c6848500f155929a47c31502c490a4f2c110a4dac5981cc9a37356d69a0a04972e6481c11335c6570a84045e669cc12dc1a9198351361ca80f1f2e58a97285dd4decadcbcb800d992438b8d2c33b0b4b8a266345a51f3b5a1a90247c52d85b6296c28a849f94531c226040a8f27594ea69a3c31615aa2c4684d894f0d8d12b8246e696d48d8d0d4ce7e66467e42ca7890651d991a7b12630a4b620496c46704cd179c579a5b068bb435808d016a0bf829c0c807211e782420abc31487a70d4c19a4196948f32100cd01e00ce0f6d386015b01d42ef811c0c8008458c0a3822c9f290a9e04c0140024463d487c004083c29d6edf36019b046a197e3c463008d9e17121ab37a5f394c3848366c443f359407303b77333db6cd8746ae58f34a285e45c8f1147b6816b78d355b26745a279e6abe6f74c5e879a66d7b7b97eadb56ab8b57eaeb57610d19f0ee04fadf5673666d75aebff883f22070b022c92ab48e68c75ec8bbad6e724d41bb34fc98dd519b307b90d8f91a8b42a9f693ac610e04c000134007318000083301c06a224c9611489647b14800b4e82385060228c0623c2280c0606048140180c04890c0008c00010c37010846128a6f4031591189bc52993404871cdc69020bd4fbc283fee81a0ad4b3cd06a4723a0db2c8e222e8fc83128aa8d6c92fe41e22df0338c202bc872bf6c5ad1d3dbaf0be36af87483276be390a717fb608a7114ed60a07c268786fbc842133dac2924e97c83e441068db82478446068495388a3f66dc9fd44fffb504e5642d06c6356d4fdf85afe6f1bc4c789089f4d64a2cdff6951558fc904ce9e7136559c6820000a0634c1212e7347fcebd8cb3ad10f825660ba061f7f44b7840cfa5db69d3a004fe73f304a8861cb31245836383c8a0802f865f39a1dd3ec7400269c81ec80f771ab1cec92a312eb91d840635483ebe4639b459fffda33a6be085cec96684082b76ad6db8897035bdea591523e5d666f316bf2ed2e76ad87973bec5bf01162e8489e0f44cca490a306980d1c5b36d2005943a896a7aa29af743dd0f9bd4055a9ea6e5801e806f064f802393a08df511c57257c093027de78117c62a333adbb915fcbf87736fe95ef00c9b54e9799b8f5bd31d7e71e6e55790c6b29ade238746ab10b28ec346877db6c52bf10dcf6e5fa673130946487f4c9cade7cdfe9baa30343b18ce51f754b309f62010656a6079b3db8855054738732326610d604a6d4b497578c918edde382a8addb0b11643f91c41e8e2886bec1de45ba8abb5d0d87038c5996b20c30aecda4476a88bc07c43289d99c14044d8c750b4c6dd76dd0ed4cd0746e6291ac17d7306960d123305a95515302bf8d9009f9a3a885e70859078262a907671f19d839d254a30ab605f230d0640b541b692314c777631442475f3df419882c7a24ad9aaa3ef0acdc392e8e001434e685f1e3228af8bc9330e49b63434ed41439716493fcbd00842dfbb062fcc40d0b44bd33d39429e99404aaa50f05c34d53d4e46120e23f4ca6671296cfc6726fed108de0402aad901f0ca224edfffdaa7f843c420fe2a3d9aa3b9ee3b9937d3dd1d7989c2902ae5a12e237a6e2777c88633799bac25474489c11700ec9962f5822d58e4ff4045a52b40ff7ceb88f4d660849cdf98062ca7559fbe0c9e5c38ab0fc037f2db0a85e6a325420fdb8104b321880f4cb21d006bf5e69e1e1522131070c124a65d63528760cee2b274ce0e7d87267dbdf255186f32107069d9dd9a1ed718e52c1ca1a86c370a0605d2393ca19a76d6d54a1d961cc889f0670a24a7eef0134f28d3790dac9dc09c38300f9ff89c64a73023baa908b19d0bb98e699ccf63f1e16acb1662aa771d2103803e481989f4659659dd0afed6e338869223c6ee94d1b8d9d8748416561a540485d6d4945df64411a9ed7a3171ca908e4a9482a5e8420813cd94c5c0387e01489c33065a77770ec07e06f03f169c41eea6750b8996d1024e1b6c287af75170679e0bbf2403e7c92467900d32d823417822f7de9557c3391251021487c98d15f519c5f5d0258195a60e92cd03ffa4bd311540833d935326a4eb393b10aec99852961e97392ab06f61afb3a8f52d03a7e8d061682b1625c9e8b0cde76eabc5b9d14bb4595960ba961757894a2db07d0f5666bd29102d99edc1e88cf50b82917c8cb6ec375bb7bb691e151646dd22668ec52983928d17003c46a6dc09d5c63e85ed2b6ef07fc9a3d6569363ddbcecb9ecffc3a5079697ec7bb720e02aacee272d685c44f778f107641403671b8dd5fe8e7506c6aa870f194ad479d5c3ee8bbdb73412dfb6973556b0d6da168219396f3b45aab3561dab868e352d91f5456f7b599a2b5276da16a21b396f3b45aab35716d54b57159fb435acdd3668ab3f678b650b59059cbf95aadd51a9836aedab8acfde15addd3668ad61ada42d5426764795f59bdd19a9836aadab8acfd21adee6b33456b0d6da168219396f3b5ba466b6264a3ba6c4cd2feb056f7b5994a6b4f6db168a1b396f7b47aab35316d5cb47149fb43cf6afeb2b9a2b5a6b658b59049cb795aadd11a9836aada3849fb435addd3668ad69eda624916322fcbf95aadd11a9836aedab8a4fd21adee6973556b4f6db16aa1b396ef6bf586ac812f1b156d5cd6feb056f36973556b0f6db16aa19396f7b57aa335316d5cb471e9d90f5e56f7b499aab5a7b650b49049cb795aadd11ab83656b47149fb435acdd3e62ab3f65d67d73068f940cb785a6cd15a865628daa84cdbf95a8dd51e9856a4daf8acf562adee3f8badcfdaa6562cdaa8aced3dadce6a4f5c2b126d6cd27a9156f3b5b8456b1b30f1d97e5cb21b3dffacd26b6d4cbb5eed58d2feb056f7b4b9a2b587b658b49059cbfb5abdd59a716d54b43109d90f2eabfbda4cd5da86b658b4d049cb795abdd59a9836aedab8acfd20ade66933456b4d6d51210b9997e5f41796af717cfe4060c1344e31fdea874172ec70aaf68abdd446576d8eab5517b51c543b8b6a699d7629d2ba15ad0ca2a5ed699560b2b7faec2ca2ade1b4cab0f69d6a65696d6da7558ab46e442b936a69796d29d6be51ed0caaa5e5b5cb70b26eb2ec4caaa5e9b54ab0d6ad686550adb6d72ec3b5ef442b8b6a6b78ad32d2be57ad6ca2a5e5b4ca51b26ef4d94caaade5b5cb90d69d6867112dadd72ec75af71a26a34123d3221ba6cd79b5eaa396836a65522d0daf2d45cbbef9faba9f2927f3494ffabca9fa1f5cc708bd23dd79e97b3c540d813573de9a9431bac44c753a4c6a30ce1b84b86631658ff44555f1fa68755e6da144b10e090bce7447cbc7e6f0d5ec658cb7287c655935d04753222005fa5c3e42ec683aed06731b7b9b47a150f968579535dc9e4e57e91d02b79a30417ac5c91d62f3917520881c636d4966a9c28685147038478cbf331eccd374f9f78830d608a86b4c2a3f1b30ad242ead045475f59edae679cbf1da0242035749dcfbf2e89c0cb5a8aeb8eac705ff9fe217ac51ad1b5422bcea951238edd368238780992986b471e4a4f5078a86f7a798db9ce51e86c84c176e267c2d2fe40f541127e495af99d9887feb6cb2228994ddd4430a4f045ab92de9a9c921b3150fd7afb69f78a4035a1218d574ad26474c523e6eafca76ea110543065a398dd49e1f3143f3f0facb7e6a9fea819282cb61814ba6534b9ed797a90331026869a3fa5851607e255e8d151e2dd28e9cea2f4e1e63247553eb670055b65740ebd1e0c93d3da2d79d2c7914cfee6ca38315e4365f61409191ef4e6826c1bb7a62226b5e9b8bb4ce7398c8d65cecdd02c242ca43a08459457f5d20a8f9f8fdba0a198409e0707f18565499d1b2bc7083161c73dd1f0c8bffe1686e3ffb3eb67f203191f0c0beba8ac21ed3bc6d5a5814608b3eadbf5b1a470597e7f925e0467fb78effbcc25db5d433cc9ae849492b716023278fdac0406e2a553573e761de600d8fc4246941d69d09d770f52d4ef54376d963c2597fa48afa066dfcccae295757c4ada4bd85be0175f0ae45105dea4f6ac924a8b1b0d2f8a04440dd00b951b9cbe993c5f13f126c4ae5087a64791d6140f07e8f7bf01e0521f32162b0cb1346fe273e8f51a5dae62c45d2f9d68a30d5e3407aacf0bf8e3a38f0eed6fedca3d8ea1364b798b5002430bc2240d3ab6eb1b16e0d314411e91804c78d18a773e192ee384dcb333084572f381cc6394dbca6ffacd0e29446b9dfa150208f3b51748bd3fae55904f2d82dd8268d534e53fe1b693cc8b7584d1e8e37e9a4312817b4ae7ba76fda85f312bda527cb9a9838920c1615f3a503696af99b984012907a96a586b101d3ac40cadf390d71fededf33bb4f99f595bba98feaf699efa0107dd299294d731bf52a071a6cba7d76ead7a47bdb4f6fc71268c945c160e42c8beab064b5c4fdbb24f0d6cb0e8b1cd0da2016b0d5f974c92c75cdb36fddb675cc415347c0b32b59950e625d71637f31ffec6de43e00e29003dddaf0a04f7eb717bf967f31acabfa6968e4957711274a5a7fd7472ec04ffa4cd38c0c04b757f0d329db1adaabefaa7669dd18a146f3f932573e4e72e3735a01392dfabb827e3a36b90ea008b09705c977351b9af2d85b7c53fc1a569561196fc8f7da33aa345a6b2d7734ea0ba817ae527a060ffa7ea8d974f1061368a6893d1b9195f790985368400800bae48dd8b4d8d2994a0c3c527ec89787653552cf76f7b37b756b03f6f89171bcda45388216d982b8a45d2492f3734cc5bbe804edcd033080ee8a0bb99a4594c8da028d60a1d6ff88f6cef86f37e0966f2a9726e7821f991b050669cdc86b98963c7bddef45e0ab8f7205f0d94801bb99090adbfa9e033f55514263b9b7a6507f30473e23d6469ee86b4c60dffd6c57177283fdf5175dbc9e583b927ca28cb64b43bb247603343cb8ee7107240bb3e756f7d254c147d268bb64582cac9a88c4fd114306d2ce9d53a7dcaea5f5a1d7bf2b7b6eaa874158745fb5d51084f452c8f12bb2f26b343080b7a560f40e9ea9505b8f2a1f1ed3bee34109b2a86e2330eed60c783dfd2b72a3fc16385f3a30569a91a3aec71bcad6d3516c95c15beaed3e769914b8dcb9e4e704326208bd8b581032cf707c5b12599c5ee6b9e07ceb1580cd05907614e7a2f7d70d9d3441e2bffe9289dee5888d4adad1a97666ee668bb5eef900353039e1959a06e9f27c240149f139d241f08b9a014483dfd292f7f061df48a42a3343cb5b3598daad9484a27aa6ade1940d1aff99ea1684bfd1328fb2b8db0ef476fa1e79f4937a18c11e40085be1395aba3cf5eedea46258c4b2d81539d0819436acea2b211c48a0b3753d864f26d8857db3be6f9584942002a120414952860ed5884369c2b14315abb26a306f0c566187629328949a080ffa60f4bb0bee7388f1a48d7d2e8926981203644dd325671753efbf51a857ac8e8d9a9e9c19e7042a6d5f1d61d47390e011ba61e07b650efb1466a27a361b86939a75754f0cea4931c04e59399bebae17d4a89de197effdea5d745d3ce4866a6806f857d67927e5eb4aa8e1fafc2a18608ac31b9c70ac292062dbfd65755c59e6d610bddeb28acfdd5f4b561b6ccb4c855587efa6600fb9c90fd5b5e4e2a62736a09fb6c3dd01b1c59742c5d06d67ee3fb8bf853b214687b28cbd74e9347eb2f7b036e0d69f9d7d7d0a04f24069be8fdb2524a71d8ec046bd8325af5fa4304cd47e223842bd3cb0e260081aaa0afe03823a1929cf112e5255ab9801dc15a25f0539ebdb9d0b2b034e2792576a7c940282e5e811d02e623e7aa26f0d578e47d0704d05c626609d5a67dd52b62c255495f7b3176d7b5b62afac5d4be1eb18c00fb7e801feac8eaba580cc630d3acd7f768b50b91ac93201c139b54d16ac49bb11010a798a1bf42802aa6338bdf9579a9288f5764be7aed93485643cf53528ad86868d00d835399c005aab083bf60dfdd656495380f958c7a8b5fd2f02c8ae1e2757ef84285d7ae200aeba86ab1fba08a9a717a0c8b4cb4cfccae354a44d9df583e8e7c38bf2917d4086c37278d831848f391e60e045f65035fe322d1691a7bae7e2779fc3118797e9855aeff3b8c959e82e15de95d16cc699feac7bde9fb68505148f808fd76cc19a1b1ec198f4d2864ee64ef4a3c267d677f6d53b57567047d691b3c3a88c60b989fe4eddc581222dd7e713a495c3cab86ae591e60e920443a048f04a1788b36726135ed45a886dbdb3d541bf79e85be2dcfb82a655a5084b09de6c9c8d24fe3227d3e68275aed448191d77960179632a71490ba67afe641bd768568112b19553f4b41944e4fdea4d2b806dd5f6188611ba04083733addb6ad7459cc94f9bd25635c0a8397718153afab664e3d6126fa3a2aa635068b58c2008d1a26fc635bf5f397a370a2c90a83b03d2b7a57f417e1401eebff69c3143e810548b85679601edc4e1bccdd4ce83a8fda890b6839aaaf57bb511cea42f72e36bcbd6f971c1477ae002cf8abc7ea826ffa9f28ad351d49a1af51e7b7b2b2ff5b3fd2faabc08d529920dceb223c211de73d1b8922187021d7c10bd2d1c9e1006709b06c43cfcd45fe0753702521ecd160f6c496ef50c3910de46e0ac27e7e73787fd0b8463a973723e2a9e6ed0e5988623b75241cf15b7ca72c2f7571bda49c7801df0ccf14ebd942b33a43ea6b39b0a5809b20083794ea43cff5e4198fe5d21e3d6cf2c47c442dc1ea34f16617e86d86406c40b14f4f76f1b5b6290171855e59f5a0773ed2afad0be6c31809d5fc851782ec336c4b324b680b26b52cacfd7f654f1c6012a2173f4e7f40feb095480eb6d7401dd48102fdc021b3f291bf6b8190f2debe4f8b8a3491b613281e7ceeacf298340e5de8c74592a81e7045fb93e046d1bfa45b390537771f5bfc0a22dcf0dec70014636431cc99d971293a037d388913a895df9b62d9ff5397e4dc22bef021e39c499707e74a00fee16dfb0338e0ea81e3ad0b6ac8dff8dfd483b2eb0126d83c750478499cbb6ea0c98fc4d81436113af77a58c1c990a2fae487fdf649df92b00cb59802a8c7780ac182db16c644658247640e28c7fc95af3f6cd90aa22eae50a769a8385013151d642f0e92a6dc75119f13fb0f0dea8f3e091a73f289cbb0c1a52f8f080de7bbf600be8dd819039942b088087cc82914314112739ac10d018dd4393803e6682fcdacd28a685493fe09bb89ad26d4deafec4f48f26816d794fc4b7075dd47681b7290b4de878de0443a3aa11f2d3eefa22db5f2a231210d0d6bf960bdc97171330565d495653566b8f41f918b6c139ec1b11f17ace992d21282feebb8066b0886b90d9206ab0584e776f7c864dcad995e75bb410247475d1ff7def9f7b277f50a7dc210f9aeade0e8081d664a6ed0e0f191a2ff8620060c3d242cf3cc09321fe6042b436a3324f35f003152d31cc5e188bdbc38dace517ad03ff1a11336c73178b9e2f18aa4a8426de1cd367e621c221cad35f7f6c6c2a6d5fcabb3386911456415fc478fa0f611070670588ffdca5b9dfa278fa995a75cc0b4800cf23cd6f5fe6299c850124e335a17cb9631c91056ca19b6b23673cb70ea83667a488759522275e6828967d4424cbad4a0567d7ab8657b7712980ab9e1a9612517c808b4c1cc6ea470f2f27a7fc9325a5cdc7f04e82d7fab19ea68fb5b57e74760e54b8f6bd7f8b598b50c7af8c31dbd3c533bea93e5ccbf940081ad3d84d263e705d28040b04dcbc40843a662f05795031cf336f95114c8ae3fcec272b6921685a826d0879eceee675dc31faf9d07762d53ca839dde72fad1dd4352f1b93743e3a68ffffb556e2e199aa3345cb8c3f4d15f052b364d206e42825d4eab39e2b3847a550ca94689b6f244cadbe0d92661127332425dc124f9cf146f68235cbc436f1fc9191f11731bc5a578925c84f3e50b9886ed4c5ccfc1aa84ee566755ed07f21f0cb2ad91f052e098f81dbf31cae9756d9681f37a0909cc6c60368568acb9f8203c49bac2c2d6aeeb123cb8d906fa0d76d2b523f7b5ee027f725e234e3dd4b8a51a4f250dec565f0cd348d087efb05c94f55ec48e9910e601eb07086ac647e2c7f09a3c1cc481b3b56a20ce0a4be67af02831db426b93044794fe102694660abd73fad7d052e7c51c220c6e3577fd8f836d78cda29f7e81e5c7c0133f2019560241409f91c694e0a874c4ac47216722d51ac6503276e54eb322aa2b1ca2b3aab68afec584cf3df42a0a2abf3eb40886ef018c0d3596e66817e876b2554a0cbb750b2907a2f7aa6c10d4f047eaf50f24807065360dbe1d75b6ef2fcc01d7f55faa547873320f858967e0f6715962b7d3f6bf6bfab4a2b82ee4a6cafcdf6a8d661bf6adbc43971a15b8973f592c67e0129f26e992bb6dee1d122a5319abc18139c789a60bb05f0b932c1ce057ee157fbbd42cc87fb19f447a5334538cec921e843270cf4d0bd4a20c40a35aeb6ee00541507c83d87cef018c2044694714c088c080efaab43dd5a248391054ee7183e917aea7a58bc68a892d7b470efcc8088984bbceb8492e009f9a95c3780f4a2000fb9916156df390f3c6792d073637a6e53d7629b6b4fa1f4001152ea963df839c39668d39e439349b49f71044188d92f413844451efe99d70c2c561adc97ceeaa275fbc785c3a58c20acd810f510f6a5b3c2cdea2cb6c663e0c540812a380580a2ff348036b7449f6a1096d69b7a00e30c78b2722ea74229190257ab9c1c5b2b034e6e7616a7cdb9c13b160684152279f10db2ab1beb85f209576613b31f018fdfb1beb5a6489c68fefec270d57763b58a0ff4bab39a0370c29e38e794bfb3c6986ecf35daa76b8c87d426389a12ec570544ea4ab0f5197277fe1be2beb5804a2cd19db53202d9634233d5100686fb324068fb9f8d3efb436a242b1fad68dd768c08ba5a3dd57abd67c1b5985880922bcb58c990a2c54a1e6b48a6c3e0a851440b52f7ffdaabe10d40b534c8f08b6ebd846d118303aa36b31b54843c805f48fa7ac8a5f967ceb1bf990a57a8a73f4eb2c857b73fe7c55a6d6dd5106b7d19c79f7d0a35c4bca23743037cd77f0735704b122852ead2a8e2cb49dbfc6e3968f9154880ac404a9fdab28d6e399bf6d7be56b68a018f72497681946d5731f59ad4f18aa77c2e32cb8cff730b4e6ddbdf360c6e4e2b906e558f5bf895e082b496a77bee60c0fe5a0d3b404a8b8a4d77ad704c54f22c6c85fb68b60cbf36e98be2660937de3a66cdfe1fff806c8dfb6365bcbb474e9f34c30a27e198419f928582d58c31c9a4f0b9f688a46d8458b2775fb507b66fded1948722c3222583c7b82c570c0011e393ec2978a9b557f2db38303836734b1892713f8d8514be3a2ea889e555f5657fbaac8bb223fe0099fd4ba38ef369f2aa095f4cfba1eae5d4e9a68c808b49354c073c9d1fd64880588b8739138d78773eb9281c5e39757d219493dc376beb054402000538d29376a959fd38e5c16b78abec2359a9235f172d907c9f9eb1f767592f78f16f172976257e0a270d87f00efee000ce5ffae08f7c40faaefbf2e255a892e4a2e10761ded379470f4267db5d1d6596ae509b86957104cde9e422c531c071562fc888f5d08c2bca1a723e1b0d2d048e39e1e740060b1eaa2ae75d6f9d83abe386cf161ba6c907395cacfeca868ec6410b230a12935385c88b10634feaeed2ff2bc26fa1777740449b67ece170a0521ec47b61f2ad0130b082853e6bc38f83411b2c30df4f7ea6dd1d1f2466a57ba8455e9bef50093fdba4638721d487afc1e3a18b6d70f719393e0617e0fcc6a59fc31869f3d92301eef8e73104acc64e2c1d467d2e5ec1df51a953bf741582ac2599f235e01bde8d05eb445fb912b568f0f30909d44fba449b573e2682e0d5b2821810db2db5c2ff8387743cfb75a18fb30cd2b8823cf1f3c61009b6fa3900be7e683553a247119325f9412e2cbe7177087240ced3baf0ae8a2c97f71ee51c2bfee05f5895b4f25c38bf88cbc28f74a3b7117b3aae61d250e84dfc30a41fe08d40c64847610df6ac1f91c67ffb66467a0e47a4d0e41e263f6a1fe9e689e52c24c00885596fd0a284f86fa00d3194d98e152547ab3a01b049544d1f0059aec2d8f99d8ad17d547d7c12f57196412e473c753bc7b84966e929664baafe05d55327078f72ea679a294db766184efc65b5522c310b630603798b09b29d50ead1bb82eeb03102bd8f53beeb3f6254e22a400dc26a186c1d3126d1f7dc936615b85f42ef3d303b3a5a9bd85f1e58eb03f0420d296f4920bca08c1041c61de58a252eadf9ae56ba7205a25e884f7cad3906f4747d2c25735efd6f3b2c3699149a105c76527c8787b242025c6c739bdf7bf2f222aa01779970b829210ee805ae1b1a41c30f2298703c048ed6217cb0feca05fe458a6a586d42f4866fba853dff4fe53f28708ac5de6f3b8adafdeb5f4f83b5dcf263fb1332e0fe91e2e09b23374605c42d4a632a801e9d4f97d5c140b8f06d0b37ee2b85fdd507d56f0fa646c58892ebeee3a76106853cbc0ef6adf195080ee39c5eed1e1a709b1df0a03f3715c01f10761b85fd12bfeaa0fb702e5fc7bd5b360b971ac3cbba1331b0fe7569afa5c722c0832772938ecc96ab71be5b000e96d68ebaf5afeea8eda2c43582ab72d0b2490ded174c24d91398cf23ea60929ce25a49c7b712f44a5ea38cc2e443193fb6af55293d2812049f3d2681612b029d8131df9e024aff2fdab2059fc138452809acbf1d7e1a27bc01d94ca750f5968bf94b0b89de456d27510b71076f40d5f506e816c60be4b9f4c6a95ab3a85b60fe9a20bdd739083423b3c1ca1e2ec83c31694c0b81d65052e24dc066830c1cf4395115c47941ff4ec47fe5442c5d1723d1a7313dd9bc536d18f0dfb11797ad4d6bec09bc0fb7969d8393131ab7f47e15a982d91f8cccfb4760af24a06ec4a899569b03521d20d001c58406b1f475287c3c3ea63395b7eb920728534713dff2d8f2860a9e904c458f71b470fd649f6d43aebf6b0f02380e3e1dd87640b6e0cfbbacbf99aaefdb8b69b05fbf86e8cf09c2c4093a8bd4ab6070677815a1e16e193820e7118147a7e972446dd002fdb57264d8e1caabf5e6cea6dde515c1bfbbc56fb44d6101efede54f58b7c3b94bb1d6f264aef86443e855d04b1234ae066ad9a00a202766b300b5ef7308278464ea9746cab5f566a983df8f9e3ea161555157877e7d9613c6642a353365088eb92f7d496597351821cc3383f1d1929abaf9296c55db64ed5bb5cffd068cfd7eccba74ce1203d0fa2b843bb816c1dc38608c273183ff484c5b57da4f2ca0417bb785d4bf28f81000ee1178373bd2d628776aae5866fabbf523ff47824eea2054360cd67f32d62fa4626075afbeb582abb0837af8aab9fd06508aec63c7d98f2f956b3eac6a948d7419ce18b5ee537a9d5e87e112f7e4997d8eb4de9f21befde9e6acc26e7d43b9cd7f286af187d53eaf43b8f543a1b832b547cc3ec9f81a2c1c13c462204933ca3c28987edbb40a2de0594d7cb955b52a6db619e5fd6f848255c7ef72f7d38f93664014b2e451f6968f19be375ef63131235cc11ae15858b1fa9dab1deabdf381ed2e9cffaa0cf9119d6c1b313ef73e3397d6fded088fca66869b7550d4e55beb1818a53289e2c57876ac0371955db90edf7ef063bb2d47d7232f663f3202aafeb420fec31e5d32749e6d2df362fdfc171f58d769e31017a8ae33276b6bd5208d664da004f75c81add659cec40c40ca78368380f55ee6c6a99ea9aab3ade7e9bf8b0ae3a6bb8a3de4c476ddce58bfb2c49686d53b6c282e664613544b340c014b828f9c334f4307e184b84b28541099a7c33acc54a9d6fb719d82860464ac8302090f3a54dd0bb5ffc406aee1e043885946a412fb7a0c4ea1a79009e217979c5f2d361af6ea55f3f88fd50987e59a176f3679c28b3755a49d29a464ac2c467b4ef57293f511e7f17a947636b01e2e65fd2d67da7c34a6d96c6252b6312d335e132a01ec24804cb449df7736caf35d000db792fce1abd90a2479e5db6bc2bc363aeb8b79f357307f3b45c779c8e15d1fc17ffb769d8576b9396568bc7a52a3fe977495fd282c6d52257df34e1b7f0b783ef37201d1aafcfcbb2c3c9813244b0a70e045444ab1275367620dc68cf92eb2dc0f92fb2fb204355c80fcf7e94e801797454b2d9c615d0b9bc976bbdb065774a25d20d1e03ca673f14baa042bfd61925dbc95bd527cac3c05feeb0df1bc519f7b411e502f061db8f02a42489e819fcacbe2a502ecdb6019cdf4e0ba82d657efe8469e01e51bef2cc91a58ddb92453d9608dc78598e287951025d3bddd91d1fbbde51b9412c5c333bfaf40295c085b1ce41154a7b9872a11546002dc71021af9c5655b400ec29236ba3bc8dd1deec591f59f9dd958ffe5e8d6efe1527f49f4480c679fe6b0d32eb7320b0959ccbd68ca9345510830c209ba2758586c3ed00fe901396c80e2122f1b0346d119b3bdbc093f357a5257667b69657777f7921de5063406ec054e3abdefc88913214186a060891151505949d20236671541774a2cb358a494573a3dc980c38b2a8718bebca6b822050649913ca14418000560a24c218224963829aa5264c1dd5949a242902c4990177e20f34412219400c25444a38841f0eac80c34748144040b4ffcf044d12cd3a7151150221a2c29b9404396114041244261458895a42a55dd891d6c8fa198e5b1ba6ba261076c8a072b5e42c0c5113e56d0830c86dd80059030555d40f192447ce2280a1263c298a1a249151da6eacc8e203d9942c2e9eeca132fb4be602284e625812941cc387142c3102f4573054cc43029535da4955a254f98ac74f131a5882196442798ecc04488254dd03ae79c73d61499519e88524557a0f48818e5080a7f88222688a7bb2b51a8f49aeeae4481a2a79c2224ca48192f3f7cf4785241152e70081282a80ff4008238e6014a681d526bad5452f9bc74e05ec9de277797c50b90be7d90ed024b9165418498ea72775b7490d2218c9675524a29a575560c0996d74305294b8d50fa812b9628010b82482102178a681349483c50d39d952353291c792209a51c947cc0c0848ed2cd39b758a9e20a0b3064f6ce30644c141e9e76700a93252e81040a8954cd2af0e024a32a50ca01921100c17ece4881d28225292a7891c276f83085430d3c540175c57d52475ad06777569038cd1f5a5657690f9d6661c4d3930d220b1bb2b09366d788677d5cb2ced094a7d63ad2029d534af9a2b4d65a8f48f9030bdaedee8ad212768b7c55b6a0638a2521b6acc082284d8aaa504aab9118514d6c00024818293bfc90c1c1480e3444a1421044b0a8c2c4a5804c0d570b99186288d8162b4b58990a9ad5894edfacb2cab9454ad24a6ba572ca39a7b4d8fb68f15562baa5e9792d93599da453b394524a794beb16a5748826193aa574b6b4219a90baed6e082c5df44d3f54b624ab10d2824aa68b256c0d98125037e79c73522194524ae99456461685093aee4e88289c2811311ca9d46841830328a52d58e4471499570c4784d96286146c2c68a594da59644e10b6b0c24b96312c4851a4688ae9b3d24a69a595525a69a54fb36ac173d65a6bad94525a79d0526badcae426664869a43e58cfd522b5d65aeb9c524a396badb55649a594524a292b96524a29e50f5a9eb0bb2ada232c1eadac721f122cabb56a0b3e80608207114c5a604154424a8f247246a165dcf28794524af959a491c6f8288f2d6ca8d6e40bf34929650d36526bd2499c3db022e5d4e74929a59432ba54f052042ad1a55661ca876e694d4a29df878b0a57e488c976385343961640e9f204c5062a8484b998e22251484b80600119269814cd24faec32439f5bb8e893529a99a0544a2969dc3205a5524a49ab9472522d78524a29a5744a5a29a594524a694b4a29a59454de4c4a29a594524a29adb2564a29a5544a29a594945629a594b25629a59452564aa594524a59258b3e4aa594924e4ae99c73ce3929a554e289c9596badb54a29a59492bef0237601d265775ab48ce9db07591f1bea471e6aad9652213c3c00ea052db2b8a28a8b164a8020c1458da51794f002660426d0010534524ae79029e36b6a09314e985942040c51355bf00085892096708108991c8e80828282828282828282828282828282828282822aa2c813921d9c8828c205940f971e3a74215f2d2667b4d5c89c3f68fae10b473fae0803448a132a78a06284db92830f5c9c8122cbd297f89404043237581933022044b08222c0d868ad2f30be9c0088129209c03cb132c597209c10e0b40216266292fcf0256b2d2f2c2f73032ebcf0c4892a284b515e822c90923a25a594563975757529abac52ca9a5d2594124129d5e42c3267175a2ba594d25a2945d2a1da3cadd5030c2c9fe0852710942962072b5d7a604148d08c1feccd5244766b554229e5d2a996a64e6595b5425a655dd93967ad73ce39e79c734a4929a594525aa5a494524aa99cb4ce39e79c73d6eaf3ae4929ad756aad39a7cfbb6c7c4c4a29a594d2aac9227366b982d63a29a5b34cd45a94a620434a29a5945230f969ad5527102c89d59c64e48915568a682149aa4811dd92454c1615c839e53442a9f4019241472a1d1c5245920e2cc9628a215065a29615aa9088324af9566832c6033cb40ca9a10442b2f4c9d4a78c2e6a097940422216712950b202284b7e6ce104a5894b9c485495d21e74775c8420cd702b7dd032a99406aab59cbc196b0f28526a2d197bd8f0e29c73ce29a59c73ce39a59473ce39a79432f6b8e1c1186394524a19638c51ca113c577b90e021f980218a182f3f347982c50a21533e5c8450e9b63b2e4288e8db07d5202ae80a58aa3a755ab0a8004bd4173a8178f121231030429248822208102dfaed9b7ed9e3068722968841062a905812aff4f8c22588999e75c7058948109518972d1dd0a13e5c4ea0735c76d65a6ba572ca49238ed3d18794442cb9ad561fe3338b836ad5bad5facf9fd97deffd5a5dad5c83f3b15cb98e8decebd7c8be426d67cce46ec568dd19af7dba17a03fab0cc0ba7efc96e7fff9b7f6b5d5b3567f3f9b38effb75dfdcb879fc70e35ab56eb5accbdacf2afcbbb323ece2d7af11bffe51cf207ef55b5fa3f2d8c28fd17798ccb06c7e1ca1dfa7bbe2fa5bc5e4acf52fb0fae14d8ea09f8f5904fd96e3d09f711cda5bcc730475cde373e97cd6dee663ec2df6170ff38d7f0be3ed8b173c04d6b37ef5446ff5fb6e2cabd8e6d5dfb79cc537146ab611c2e51b8cd701fbea5d363aea2b8ef3301e661bafe3bc957a4238aebf7ff9a60376fb30b88db2db4a91d1f6371b55c3722be5da19966ddc8edfee11fa91b6a231b6613f6f17b81e6f1cae1bffd6f5996be3c09ff3bb3ecb60cdde65d0efdb0c5c2e1f9fefd7c6e8b6d5b2f7beb55aeeb8697e666fc3b7fa3623f4ba730475970dd78d7fd767d786cf001f3921c6737b1cb72b03fc9bcb85f1ceefdaaee7b77b1ba11ff5983f887c83e77a311b49091ffb1a50becbf383e06f412dbee9fe70cfdd41dc08c038fcad03ca37c7646b54b7d8ee0d83cf2276bd4ce38801ce3ef6352c578091cd1fb8deb25cc7c6fcf847fd654b44f7a6bbc59fd5b9a520f707cff51edb203cd77bea838ebfb926ed80ec7fc6b70a2b5572599bdc5dae2782aefd8fc1de52a0ea367f818d8256ea8763dae75d36f279a2f7b363973edc09cd4b1a9e42d0ffcb3660f4774c34ff6615ff8df2e8f98d2225e5acb6f49e1df98e510fe87dcd8e4e0fe83dcd8e4d0fe83dfd214ec1a1880481dee38f4c2f053a88dee2527fd9c6a958264a7942912a4e3d219d111af05c5d38616e2fa74d2ea74af4c9e3e03da54f38a0f75420452ca40a11e9d5a3d2d477baa4b4b5a812bdb7e67885298b29fd510c6bb654e989125d7a429b8db2514fe8add21382ef63d313da790c820f448f2a41243864a32491fe7effe6d9350abf633ac1946e7530bfaf3b218098d2dfcb579337e4ac5099c1224a2995c4aafee48ffe1edb0d820f543280804a628c4d5830cd89614afabdf7ca7ef5bff8faee33bdeb733d97d69acd63d66518d75aa5e77ab6c973393883ae80a3ea38f2cfcfacffaae5d0bac50f73988d6236b2368716cd3cd76bd2b4b79a34d65b9f3d2c9bb4ecadcf20964d3af6d6ed32d7b81dc6db273ab7041db2eb7c8ccf74768c6d95745ee7895e4c7a8e2a87a3ea303ee7b39cadbdcdd67844da3109c61379aef7309ee8412525d00c73f8824a8f83f7973b2af8822f25aa841dc0f5f799c4b2494f138cecade13afc7b7fb3bff2a23f021d3eb63b06b74a3a64d7e1f649b661575ef4779cb7619eeb056bd51abee0902baa1abe4a803e682bc5ad8dea96ebc0771dffd5e1b4fd87f46ce4253cd7fb205fa481c701559103f08680b3590996f23855e609d57f9647eb7ace8edd66c7aefd705212679b10fb46954cc0f65bbdcd8e7db33c87a3eaf9579f59253844adcb32fa845e79e7bd9c2a81d1f137aad41f6df25cef2395f7c2b969601ce314047a8fb3c72056d443c530e338f5ec4b6eedc738f53a76336cf6d555e9f6b3e8c425363dd77b79456fb1a9bf88048762512cb3dd73f138f55cefaf0f7aa34af63d842fa5d4f20455b4d9dd4711ea9050f3345fc375eedf5029da7143a5a8e669ec53000ebd22fbd8eb09bd6ef996032669aeabe8bb23f05ccf49550595e99be4d15f9c7a493700b9e7c29fb910b463b242a9bbba63aa22aa335991d49d9622a6decfe88e898a1e7a9c721e3ce18682a8bc448025061cc09829a2dd3d57868db91f5f175de703d7f3afbce89adf315131a51f75bbb7bae18e33fa35bbfb0876ca89e0dc923bec2ac914ded12a85778427f6a3479d31465be50740d00120358c0c1f70020899841218b450a1484424475cc04173c185237186224956200940d39204a54c8c19354022493e8a64a06931a20520d6c082911772d03e33002952450c3d8a1c917942d0c50e524644924591265531340fb4a0c810aaaa135f66ac5881cdd164a0a285272470221329488025de683240d14207a00d9229225b48160c4d107122ebd8440c11216aa614456489971b8d20d20292076648550e95d298c469081332701932040c419621344c25430c1112540fc00466a409a94815a5e8932a9c1046a86ca1414c172e5354d18496b4ba39830c8283541143bed8a0048b26a8489224490c3549913e69a5d8474d128fabee133db963acca1a606c84f3c69f411e3d7f766fbef9e69b6fbe55aae74761697b6136e9a4a3674139db3970bf9f6177b334be8dd0318b631b3a3dd78bbdb51d9c0fa9c4577cc5577ce9cfe48654365c9253e2abd62a1a84be4f63f372bb9bcf30976f387cd96c98c4a4f36fd9cb8d23739dfbf937ac4b4e03ebaee78a552e8d5575b7fc27c8d7366beba772636b7e9c349866fea4a189980683b12b10d4efc5fcca2a2b10d433c761e5de826ad5bad5fa67228240ef154081d0bfc5aa78e609e167fd0b7df3656d23bc7dcfff626f2ddd33df70e73982ba24a1e6e7671bee37cbb21d3d33719d064c1b041225968a76ccc7087065fa3d2a2282799fe9f9336c6249fd5a20a863fa77d3b79b7eddf0889339797d40187cc14da5930276946147d16251556a344d74c5283ffea659bfb5567c23fa408b9acd0cc0f4c3afa11f3e5a2b764e2340167fc1b7f84470ff733d983d7cf6ddab350ff943beb95c199661fd1a906bcff5b06c2419e0ba835cc7c67df835eec33fead0eae772ef9cb3bb55778cff7f2ea70f7a2e47f42cac40bcf75e851fffc1240893aadc27e43e4e611653c29a584c8ac5a6746badc5ddde7777d77b637418120c9a661d39b2069eeb61317848e9ef9d449a4bf85a1b857581b6a5bf055fb029676e1d3b30248c08862fd985c6e0eb09652f7f6c3ff46c54d5e2d498327c7366ba99a01ca7e4b79e34974d56a94db494fee494fef8e69e9ef8b6c1069bd6b17e586c0bed63e768f2c3a023f8d5aab5a5416030677f770e8a64b11a35164df9e6cee8261db9134cc71b02faf7253c21a42774f3ef251de9ef77bca157958d307ce3d273bd38a502411dc7cde387af9aebad4050bf1c877d2c1b65bc6ffee6edbe7997f5dbbff9ec39314c679e5c1ece01ad9e9e7f3d211cf2e93f9a632be1684ab74fd52985d0c2277a525e7ba185f099e9f0b71ccf4cbcf36dbcf969ae78b6b6ebd98e1d07e781f68f9aa7a9d941bee8061cf25b4f23378efaad773b36ec7338a7de7a0c1c3d3cad843867a545cbcf8f3d966be4af75c79ff9b1a7d1fafcf2e62b5b313e11c4dee5e8b2b85db74acff570ecd9ae2873fdbe95b252362afefdac629a6b7e6a95627cfd7bdee1bd6535bbf7ebcd7ebec013bfc419d7b9712f86f37ea99c5f8f7deed833f74437e9d6639fb1b5d8565c2db6f18960bedbf5eda85ff99866f3ccb251586e8222a9d7c7590b94999efd76d4318e8d06435ea37efebb71deec9f8075fcd97ceb68367f2bf5a49e147a4e126a9ef3e75b8e9b43c0bc7e866f86416f56c9861942e398c0fcefaecfcff8eac58bbcfabc579f753c0bb308d9e77f5984ec21cf385b7d8dd6c3bfdb2a156119be15413e7e984590f08bbebfc3febdb73ed163edd8ed763dcb627fb1331bf56796652e7b1af9f18e6ee19c585f6d1d4f84fa2cd6e76cc4a281df3d57b40f33e6b3b5b7cc2bb74fb0e8cd26d570147a9e3fce765dc6bbf35b2988e1b65136cc73d92821b4ac61c3dc7c1fdfc76acd463573d908efcbb767a6e3cf18cb34ec577b01d8da4e6a3edb1beed934ef3209fc69b84e037a7a780af5690b0d4b45351ce98b805020f2ccf490e399d9913975fb34dbd2709d06d07ccdd7589aa711a186e916f6cbcd74cb3714886c273d8f778e67a6d3e75b87048e42cd731e9920d07b5744b35d914d82433ddcf248d2a275866118da65a3112cd1b353fa7b202afdfd0d537f0fc356e9efb575eaef2d0f38649f5cd1f787942348af2724b4c1d756abfafbad9ee9efdf1699faa37a425b9cea669ed0169ff4f732fed92408247589f47793fae6facd8ee9ef37cdd259e6345ecf36ea223d21f762c98e09d37f44a7edf2e8ef6d9827e48618624c7f56aabfaa3c04d30b7dbb44ec9435d3df677cf18fb7540222ba8d7a42f906c645b71c6bd2497008229d7942b5a9563da1caa5cbc69f6164b46bd2224c7fea4b744a7f34f07ffeaf3a30d0f3efb92da0ddb3f9aed9ee01d1d86af3eeb92c666dde65afade8cbb723a5bed97c8ea0fe8f65a3eda8ffff3c968d7c60d49a8df6d76cb4adb556c6e39d972161d0363cefb2118fcdd8dafcdd3982ecd342db27821736e90f2ac1a2c5ebda10b06ce4b2d91559bf7aa13f27f7de8b41bef9e2bf187e0cb6eb594eb6b72bf418dccfd9aec78c3fefd7e4b932be612d58df12eb2f7f4ff6537a2e309af5db537a4d5e857cd3da12c68ad1018ff144efde378007ff448fc53fc6bd9cf5bfe17bb0e31b606b1f63ef3cdf38dfc1bef1f98fdb83d7b6017036ff9bdd8116a334ed595063693b37383b2ca70b9e7e5c183cd163395de0e21b07facfbfc7604737e302e87401df76f49f1f0e9f9ecbc97c1c1c1c9c9d9dbfb9c1f91d9c9d0d3ab16e1e3ae13cdde0fc7c16250b07e7a113ced3ce0f8be584f3b4f3c3bab96139fdf0f72c9c1dd6dfb0587fa3699aa63dc7a1fd8ef6381c3aed70f8a4694ddb389ac6fa9dcf58acc7da61b158dc042db276589ad3136b47d3de69e7bde6f48430cb8775ef947b87fe31ebb5214ed472b2794e93cbd8f9fb8e75773ec817dda0bdd3f79ddb5a3220dfe2eff0f88a3b2af1a8a44406dfea0ddf340edf5afdca6c7423177a8b2f25cd81de401740c3a4173a68eb4083df8266649003f05b0b00bfe9adf62508f47ee50481dea6bbeb63d58fee393939adbe65ecdaf7bbb77bde3ddd7b9e122d44f5a3df27d2ef73c0b77aa4dfdf806f5a49bf5f003ea6df2fd3ef13806fd54cbf3f00bee9fb413ce9a9dfd7806f4102e05b075cfafd197c7355e9f733e0dbdfbfcf92723f007c6bdd0700df74bf0fc4b7daa1d3987eff4cbfefe25beb3e064efd02bed5a82aff73dfc7dd6fd9f0ad6ed0efcbe09b4640bf7f135f78e7beee3321fae4eccd55d9b01cabde8f9e418c02919e3dd1bbac8bafbcaffbaa4c1b78f50cbbce39c7f3748ccebf39a60dbc7a8efd2e2cb7447233e48fbd37acef4f525aedc89f7372c638e39cbd7a9771ce594a29258b6f1826595ceefc4ee6ccda397c3bcaf96736ca19de3d7cc37acf677b9593b35ae5fcea69365ae5609cf9a6434eec003df3175ac3fac434c8a8f243cba9200fdaa003da45e77ccf674ec733f8e16ca4f3353adb39a0fc357b63d6e7277af165395ff14d6b9c0fdd4b2479667d96f2895eb673bec7ddbd4921f966d67b89e43c78393fb103b89ef32f1be5502ebaf5b9f5f7a394cd5619ceaab2d6c7a8d66f312a0cd1bb3b56bd7dfd37fb95d6c37a1a58d770e0cf5cbe8051ced3c0fa0bba45b35e7bbcb3c78ff909b0b3def5157cb1e1e7ecf87bdbd7367fd6e6f99ebd13c3eefd7c6bcfb359bfb37b2cdce06abf8ee99754920299245284d6e9096afe2f5fc088e769609d7f266dffc900069f616e3e9a0b7e30e01b072ed8d1cdf8f9d976749f7fef76b693f93c3c3c5cc7ec3c9f41ec347f988d9ccccfb02c02ff9d7fd96887e7390f8f469cc7aa29fd52d8d9989bc1a3054bd3cb3e9f45b97acc69c0f370896747e7ff7c3e9319e5a13e4f573bbfc32f00fbea7df876d4f9bf5f6de766f07ccc46fce3d6b9b1fa9d8faf03ae7e879f007be43a66b79f4d4cb391fddfecc36eedf3e0b0cfb568fb3c1c2e71bedaa2edbb0e7f85fdb3ab3f01f6d5f3cf56abc7e0733330b6fa973f883c78f41537c13eecf831a701feb8e3651bb0f313ded213dae4c681befac72dfc0bc0cec337ac73fe6660bce25129c68e4a9eebe12cbe308755d986548e89c886cbe07fc3b7d7383cfbddaa11d4b3a818e6692c9c1fe31cf30dde902b7a9f6530d32c3a7facc2194bbdb78cd3ab802c566559d5992772ca1b725e96e48fa7fede1da97a2949c9f2852f68e65dc7f422a258f4165f4a4f08467c058dd073ad5ab75a34089dfd16b351a62f370c1830ee1bdd0b210c1bfc2433992d3dd71448c5691c48456aacacd56394b63ae7b3ecb95ef693e7af158c432a9be88306d0dca039085132fec98892f1ac1825e3318feaaf468cdfbc8787fcf18472feb956bffa77f657bff716fbfeecdecfdc54c7af2e3f678b5599decedd7f614450977edfca27a0c58176433f0ee856c1a1f88240afd6d53ba86dd89fb6b11e5fb5c248a35fa311bbe6d1cdb82c56cfe3fb32cb6c4e4f0ebfbff32e87b09f676f9c7fb1b70e7ae6bfb7da577c078756d1dae3e47c2673fe7ecdbfd77ef599b6258f58a5fd16abe2194de76b6abe661e1541d6cb6cd4daf18ca63d0e8f55cff51e9e9b8ea7b37548a84181e66bde156577e7fcdd3734ecde8dfcf25fbe01bfe817d95e5d67b4ba5ce746cedfcff9aa78467bb9e399e77a9946963c9e9076b39754a8644c5a6972102a642308004000b3160000200c08868462b13ccd411852cb0714800e6790506a60300d87c2c11485402004410c03180600000840c4288418738c4a00027d25c41ef83f043f0fe86d125611cfae1647565c6de2258c691c0f6885ee86c311c2eb1c2e1c2383d6611f21cc7b6e33a0faf143b0edc723cd0562a39dda3f3eb2f916ed9d54d118efb2ba528c30a7a7c2c1b0f6413e33732cc0d2170af21f655117111b7c2d2c91293dabdadd4e2cd87f6d223a5a16584cc1ab5c0418cacaaca8caaec87a70f43fbe8b9ed4c22ad6d824f007412cf3d2057c458e9c892367a7851511963debcc283f4825fb148d179089f6e70027870ef11e0bab09836ee81d2facbfbf63272f1f762e556d67ee897a88dd95314ca09a091dbe66ed24ac2319823a1c2ecd04381b9e7f612d13d003eb53187252713ad2c0952165b4590aebc1ce4dcccefd56f85630dec105f4525814f427feddf577b6b85fd73790fbc2bafdfe3eb95e44b34a1555bf17d63faea10c0192109d764ce859af4999bc41eda293864d8d598a55407a61355542db5fc05089341754a1c2c29fa989d1fdfdb50eaf8f2f76b5264184bfa98ac2a2d6d6cc441ee256c30470ff3da5aa82b7617249c3d871154ac0efd071ed06bbffb6a970bc1f476e1553765a333b145efd309fe31735a631bcb95cefc4037b46f78caa41161cbe53997736084739df81411f975826258b83156fda28062410cd9978384d46738b66f4992a036d0d76a3e28c099f7aa82891615cd871e660cd0eea38d2f3d89117bdcd3947494c865551bf3458a3375e30a423579657077f0d7c7ea92e407c9601d1d2d567d481d09f69d9a8f68dcd5fd8e76082741a84100df20f17f5b07798f11348abdf9dc1806cf1a5bec2fe219393a792d179b4e4118e7dc40b8832a33b8d90da050f15c23f09a87c46526d9d533e8603ca02a7d2af7b77b1400e9586f666bbe66daf04ca3dd1fa6683c1c09db8e1e45796a198ed4acb9f75862b725126cac0effd649c13035a7de25430ad05663abcc5165e61ed1566f87ac07151d2c7419a014860ba70279070fb97e2bc817548aaefd1f809161ae14a061a11884456b1aa84d8a6bf4ba7a435a857c01406dd1484893a470a9a07f6ce6879a2729814aa31b1ddd64b3af84f9049f6ddf9d3c08cc3dd8129cc2f3b5395ba26d7cbb03168c7fe5de8315c2df414ca66008e941a4bb366e0f14f273a236a3ad1bff31ad811de32ced1604b317d8416dcb2992ea1894b4e5a880816497d62e0a9b4b521a74665b11b770e29dff0c3574bca84335dad6e6b6f9bb5abf916900b258ece0f5d53844ef5c9ba1bad3bcac8053b08c253bb8f8666c34739f70d7bc29eb2a3c62ad52959c3df0c70735a7a3e15d0717850148b5724e424c6023dc9bfeab788773e5ccf1f37adc215047ddfccbfe6262e0a6ed980eff707e4ac476467398ba6b89cccb901838830f0b062993855388f78e7b6dd0f5c6a4eef40d0817695e74089a709366d34409fdb495019860931531dd5dee01c8096421e046a938f2ab5c091cab2cc7d622bb09d19f1f298e5091e448051e3c3e646a087c4cb27bab081b3f08996c890ec73fbfefbf5a0202371a2b04a1e74215442e91838caadc952c715f58407a27f39daaaaa0737c0eb45f7fa0c50eef001d594440861fa9ba1fbec2cc87d2cf2e423c9cf7c8db1ee19608caf7140ba9dd41839af4ca15f079bba7e97e23b7181602e08b5b7df53a09ddee0a22fa563a98d3d4df4bd708f0dee37f4604197a03efd51cf116d75dfc63722ac139abfba2f871cac80a3dee172c3fd41e116260abfbd3bc276e15eede90837f004d49b0c22d4e7f9ce15bac8c9a9449a848068e0625e0a90e485c4a0049b28f1fd32552dba7afeb4938f1888775f5400830c69d1ad20db77f405594118c4205c2bc2e8865752ab2d2d76da48600940155a83145b8cca0d0ae898de8af4c47d898a1eee872f7208a49234960c137c027230e0b130195ad6e5d446bff5445db26550ca4274b7f4168c8ae7c7335c803583b901b6ee36e63d3a57870e3642dd0da47753ff19abb00b0f8e557f508932dc2d07450d94de76202b78d77d5ec4489c4a6afa6f025dc275462bb539412cbe824d03abce88c09170ade9e1a62cd71220f374b2e17fd14c9fef30cab8469a3729c0bc493f58e799b628b43c7b20574f8740aefa19da6045469637bf1ccb2014a2401669bf3ccd0f87eba261f3575ebb30f7aa90170a727885a7005439cbe1892e21c9129628e9ff0a991907e8ab720077261a8df4a94db165bcbe8b87e3bd6b7ae81d511532f2f4b21ca4dd75184850565f88f56e1e22562baba3855cd487b27383cc8f4da5247c3e91eb8f044108d225e7852945b6f18b1908eda8160c229bb86e87a0d1e3654c03255b2e5e2256a12cca02840dcdcc3a4267dbaef141c2c3b1c794644e60ed5ec8a59f3fcadcfefe72e6abb708a927b52300925d9ac45466e4ca3fb441ec67e5e0a2c28c806101d7a413442cefaf1a8eb6019dc4efe956a6c74af6214b59b37a5470620fae2cc6603a38aaa98be47d5574428a0c132c4561b931fe29b493664f3983f99b4803492a3494ad29fa425ada89a4656a846625d558acfca7191385c7c45fd8ce6ea470c96f5aa757d09c120de10abacca881026599678ba71b91d2269413d5c985c58676beadf447b8bff6f536babf140291c01e1514a2140b9c0b8d1196e0727eb3e88096bd7a4b9bb17bc3be356c0cbdaad5b2d2a69185a2488c9a833f1c069c8338e94c1006c4a7d6c92d0e20c7fc0c9bdf8ddae2f5d077c59de6ed87e13124c30706ee7a1883867a167c24a85c8f51655dfbac7dd3f9eddc27a559e5645f77859b85a0c830c0693af3148c9c384aed33fe78160c05ee04a461929902826ba4ec832218cc1e57cab44ceb50dee33230c3f763ea7d81e7088ff8f31cdabfa02a7162535330ccfacb261f32480689e5a6b6634d57839b6ad4f0cb4a6d2d40664c7236576c2fa1fe625506113296e2eca3ec5454e5f6139fdb05bd0f0b93d42749b979474fb71dc449cce15d3bd113561ec83371e4739a183d85c07491d4e21e2edc66850ccf3eccca95ba943e5434eeb10f544bcdc73fb12f582be615962dbc7214bd103cb779e3e2f918959f9f8e507ab5e4dd20f38a07008047bd0fc5e03e8f024a7ad25bd57216d9f4288460cd2c245b9ac8b08f0b2043b515beba0d0ea312b76bc7013a6a54f532a7c0ebe76cded3f53252d792c1973b1ede4a3ca69034b4ef6eabb6fbe4f1208928f7cbea53d6340fecef5889bd3cf693d560a02516146c193dc21900b2689c44f7e8b36105ffee31bd65c49c80c693451557a35d69fd2caa23c763101d3dd393eca035e73acbe0a410b112cabc5dfd753f48badc0d31b322ef1bcd9bd98011a82a23422428a9d3cafa734321586a88ced050cea588fc6237dbf869d5547797af5bb6fadccb2b36ab4a4d41bf08cd55aa5087216c4f316ae9da8ce3ca1c14586766d9ec23326821fbd6bf5fdb9d09ac29b86a13b4b7ef6038f3f5d14130fb636728bb7127d0f56ca4f06e97f795642ee48d31f32c81d77f6c8ab09e1dea01c91363868c7899252c096d9b5d6f6783d70b392c207ac082026a3f7f2873c1def61d240b143e45750fd146b6a083f12a03a2642036e3f8e52ad58e6d385676d85d13983d4978f2fcdcf3e1e6a62396b31fd060eeb42ddb58486da6d2e1b1f88ea0ce4cb1859614c248c09a602e8e1977a460b94d1c76daaec64ff70290c6dcc41401bdf4b46a31d1199e57f0ae5dd46f2e9d4d607744090b67fe43d2bef6803b03f5a2e83adfcbd138d5d2a02f1036a4cc8f5bb40674ff839c5ae18abb0bdf2db1bdd6c377354c9b58f2626c086d4b5f0b418c6b345a4db113b9dda9dc7a00b317caa995d9f6da892658b1d4fec1539bd9d3f3356edf5f6fd0c0920cb5f21f3b5fe700f09488b3c00e8ce05b436460f26edb880d931f03993f1e30c72f4b07151856a8571881b4109c6777585dce6006ae5958657fdb72cb36606acbbdce4eabea4eea2a24bb7c985e94d555a9e6f54e2639237fd691c83c46521c6e545330055e21c824a69ed12cb08043e3f095730f3a7d4e5294ed2b6395eedac57220a41e106082818a2e7226b6efd65c140735007285a9c728a1ee06511054591a0b5cbb1ee1068f280afa485197b95c1d0bc2d3290d9bc9992b47ee8a4e51ae41944f5ee2778d27e112229250a7be5c1f47773d68744408030e6e82509a5f0b19bcd34eb3e0bc0a4811d27c93e80f96f2617461a7ed160533be2954bff976c0719c8f04d418a94e65a3ea0253837fe1b0a595220bee79d6c4267d6ff7e4dcc8d127595e64b915a9d4b75d9ffea2592057e58d7e67c07fd5b5fb7a2cd6557ed3a8a31b2a04750150cb8cdec1a705d27036a3aef83ea3c3686d6222c70d8698ebc1308eb3915b7cece73e86839db1d8aaeb1ce3eafaa31dcef84fbd999459e52e88f9565cf35a10b51c93614f3ea838537d4c87e389fa8f739a4b22a681c55268cb4cc61c3902e8573353e8bdac80c0d61ef11075308ca7d28531d1f5fa1537fb32040f798de2cdd3f0e2e3be031058414eb8ffe53f686920099f6b09ea78419418e252941c2d22d1af919444abba3e62605144600abd72784a36d82c79060859ad22703cf279dd706d5eeb1f5c410616420ec8476f38246564bab55fab8c64f8d46819bace5c07f7571121c2ac375286186c0ae3bd70d3759a9d6f654490049f2775b83cfd6f333f940e3f507f03c056dabf82d74fcfd714c44861255dd38bda9ed014313e66c5de3d93191732b0d20cbd25616d1a292e24d94f92334479f36071367633118f9f63af25ba18f157c91e28faf4bf98a2c669a8a789e89f24a49e45471e5a61f83d62b8f57a7edfa88b5a1d37f9a38b8be8b6e0b3d882ffe40e1760c049b12f7568de649c624d3ecce9a4d7103cc90badbcb42d900482cfa4f44c2ca32c73f667a1d767793ca1193e77785270aff4e93080ededc614ae8543f25968ce0b742d9384ae39361d940e28551b995127c378d89e0346bee24ef5ccf840d74b00ad04ed78b54998984ddaec188c852ec723dd5ce145fd85d28b1ddd93a62d70e18ced938108c0276193f5a2011e07ebc4c1da4aac88b705e026a11743f5762cb57d0e7d18ff3a2dd63e76f17375396ec1f6e8d1df5c87f581f34848edde5e299cd9aa04478ed4de77f1632b444742f358255bb398cc920f590db11550ac41059574e2f80a53069a311102679a6f3e1c718e01174e85aef3fb2a2013d819cbe6b67d2fdaeb4c90dc8cce88cdf473e6d972d38e246a64d367b4193db094f067fc7585ebd21174c8a5a4d42724e2a25be6d31feafc7152324fbf9c00dd35a18d6ef2009df7fc0c3a512574a4c10b0c3aadffdeed12fedd866c3b3eaab5b3941b31b52a48b564b94faeef18791923de8bdde118308eb4d217d5f92156d2f9f95a5558b0982dc17362a92f873edb9b368c58735e76aa0e81f2c8fce5ca2bdf248b834228965daf1991399a22d9653e826b530599159c71357dd7996dc6f4e2c72a9bc8e284242f3436789bda75d3ebb15d896661efe5383ffccada266177ea71247ba898fa0222e29a467b737b7191804145a81860c7d737fa3d80de8c0d58e279f1b5743a740c84be22cd4bb2835271d9817f9cf8e67a7ca69f00698ce27b28d384df425acce3eb4b79530788123669a47ab74eb3470e91826155b6d2530478543668a0bd06f7084f9c54957f8f8d1673ecfe8d76a83cfcf957b8d21af74ad84d226902cce1e6293e76d41b11715b35096e264ca56a8cca159971df1701d7e84f4dc1e49d3c9e37dfe24bbcc1b92e9622500a916575b9b1227c32702a00553a0d97b43a249ad48c99c7361d5c60a74be45a3ee628987ac81af07a28ceaf3e7b94519cf97ad7b0ef9f5047aac200cbe1f02b89e4ec3efe969058ca6702bc0d599570732bfcc8da4c06ea098f5ab6a023230abcde0d27718e541cbd3d49595cdfe8015d8b4c0ccc82b2a0f2caeb9d2883cfcd072bab35a446c3bdcf83704a4e03d0022a74ee2130bbfdc4739493e7e194ab400aacabc527f3ad4aceaf81f41d6b8eaadf7056b9423a3250d0056adf4f6039aabee1a079cb374f6b6f1de12f51bd6e4f39a9b01decd9d4a634a9b676d61e72acd24ec46284e50318eebc2eeabf24bed0bee18dad15fdb3756cb886447734630f608fe2eabffbdc4ff706cd1b1a40129496dd4dbfda1e6de8c7fdfaca0809eed0e9567d75c076c94046f2de10d7a312678b04e43494b928333dddce42c073c850cd1f465e2cbd6a2056926e33928a0c5b02ad0dbda452bb49995f28737e0598d26417035c9e99c93fec4b2aebb2a0052062efd9112e4bc8978aea9fda9fdc058ac7d19fb4de9631010c9a97802c1da3fe3b87dba6fcffb99d0375cc7c7463da01fc55e1bda1a39702121d6419794318b9f98998a544ae8e85a27e60c86121225d4e4e35d279f69ac1634bfb43a83fa2591e32432c812e261d1c6eced5370a171844bab5f0206b470beb089222d94560232c5d37c24d38b09874a488187e06dbbda5ff3879c2272dbada688b522c83ba47ea9990fb2327364ac18b763a575a58d5275301d890d71640cad0dc0c4f4c405294ab0aa81f3a766fab2f50447a0bed5c328761919e3d249144f3474a12cd69c926e3b7c4c65b0d30d1a547068ed18edc996696c3b09156e5ed716d6e2a530ada0515ed9bd182b19871890eee21983a55b7d3de96fff4569b2592663e23c3affa7ec3fe9089e84c2a1c891df9bf3803e3d4758c1b0d12bcfb936087c76dfb5c8875b8436c9c733e4daec5649358506e9e8d8769f0252ef1d348a6e040a743d53fa3d8d381304302b5daf3ecd0d17adbab13ea1718bb04fe833baddb1f8ba039b6b56c8863c3d1dd88849dedf86c501348b2b964dbd1a4ffac0fdf7a126b51142a3968a78f956e3c7a0b7bf8b0b0a9c72c80c8eb9af6924d13a3ec75a96ac2c2e9359fd5c96d181d9b1975ddb0d374d58f639bcca6edb32ed827c3d44014d969881887a64daa7e808941f92d2f0183653bf9b686ec7809b72dc8261788cad76de6cd1573b69676dd119706d6e4c84956c3992259c2e80799cb7e70ec37ab6277501f4d406f32d7a249a14b08ac2615033f1a87640bb92217b5a02d7634bd8af328a9171019a3a3a664ba28b1c753c1c76b08b290fbd0b3fe0453d32dd98128c295ac8a5af99b9e190cfcd831ba11922d666b17c9669e7b1f096b19aa8a6d9fa97433ad0959caff89b3f1bb27f141ea1a220cb3066a480b3b368dc0c539361dd10ed325aa537d192ffee5110f416439a0b74b2be93bc06c944897eb104492cf6f6694e5f4008ebea4a9b819555912735f968d29e9a720399374547903abcfb634f0f066b1472c1ddf80168277f1c579ca0724c8436fbef3840d6e8ad5894d74b53e70e4af560fb1af4f3d076c8de513687b4a6dc64e00186d0176c8d08fd88fa808d12fee0a50862e83e44b576c96c2168a920f200e01ed4d488b796e22eaef467ac1e576fa53773aacbb9f4b371f3e4f7a30e2a385666e51306af7f7ef133a0ca612cdeb68ae2f64d9991303adb29726f9bf12d4c2967b3989d2972af9a748f372d5a159e8a84e9689176251de6010e577a2c273612c9fe8c87bdc053a34adf5b444a5653bda9624fa660e61e7e09c875978385d89be60e79783555d1d469ce241a0235b4e3b15d04e894d733801ccb2554e0303b4456a303bd4ca4aa8bf8d170820b1219d814bfcb86e4e1a208efa49c15943aaf44efa01bb76539c5bfb40d9ca208bd83e0d31206a362c894122d153d4a0a16138cc2a40f7a2a296494b750a243fffb9a07df34151d2093583cb331327bffa22027e692b6693c68c26526e66a27d7d2aa5f8b802e884822422d65e47bae80162a41d25e63ed5dcbd0f89bc83e32cbaf7c70ba0eda26035b52bfe49066e9f2ad4ecd370ad8c6808ef5becb99d7e40d6c2c59a1a86501be05a1479d6b7fde60f1ae25cfc03ca60be032637a9fa308e5d15d71b1a22b2adbff4901c83ed648cf77575ec2718fb47133810cafe67863c236b13066ba8238b0de3368243d66ac79e3bf93486cb6e02e3d06c45922c6a4cdec949a05afabe13db27c38e11a9174f51ddec429a5e908eb75ba7c6617f63db81a97270eb25752b3a4f7cbcb1c93d331a41cd3f25fd5e8d8630d42547d1b40befc0a5cd0ad11e4a783a6e943db48f1034a6a0d29ade4975ced3b6b28b4997e63d6887b52fbe8e87fad3cdd1b013ac4ee9adcb9ba015bec63828341d349e2921944bf6b9d2809253c7ca7e47e1c7268941a15f124bd8341b2e9031249811fc313b189c5330c2797b6a4f28a0d0fce7d4705885d464ec01be744ab0589a926be40f1fec2fb50fd479a39f2e7ad2743045345d1fa190e5382fbdb2973c19ff931f6b84eec5e7b4584a1d590a5f35ade4469da5ad3214bfa236f8dcb477eef791b2aa26936b99578207486e8ed5494363e60630db9d6b2e9fbb8acc0b0477530fd3f3616d6d8332cd99991a70e9d0da11fb92081da608400cc07f8629c688f964ac4ad52b112e28000a13a91427ccb114f40b16ae04963543ec76036a3d434eacb16acc6a859488a2587d38d8506ee1974e30eadd46820695291743917d6fd25b61d403a93e21ab0fd1e4ee43b2c72a3530d7eb9238c2e78d625f99070748eacd829e5dbb6f77ca1173f56651f1d293c30b5cbd5936ad1bfbf61043013e239a1ecf08392c24af30f32d57314e2732bbc61dff1c6d3a91c9497937ecb3ab6969e8d32090beee821cf94ac92e75bfa6c82ecfa98917db485f3c7a32a4f5c1fd002589516b0d892eec863a9c6e6c170d7826245a4d1ab870908c4159e6d1e8601b1360f0cbb214d60ce33156a99640b64ad96964bcb4aa072dfa5f4e9a2f89b3e1329c013ad1879e504d97ad2de39b7e0f68f328c92cee8c27275c8b9c6e38be3fc8b4cb495ab856b177fc9e116b909446b5e023840ca6794f4ad3b73557afe87cc3d9e9d39547c700726f57e6b5623be00984f69301a953eb018fc8527cc5a686bdce65e6b175425d6af7e593861ef09380eecdfb1de01b97df4aee85ba2c9634c716f1158c6f90c7024262e086d8abd9b0041bcf0b20f8de460217b5672704b9d5bab57c2275b070026ff76c115f120ca077f95029a07be6567f0a2511eb20f210e30cfd3b6b399fa5b6ac24aa01a245bca331492cf6ee5cb79dd3e4d041908ba5bd3c36a6ccc4491a895f62fecdf18adde121a2b0d54ab21dbfcc41b99a0a248d95155ef50c4493d799ecaca0a652193a7d8edd8eab05cd7526f49ef29cc4fc48ce9a3444899320dc134d63e0dc704b4915f94ac1ea6cb322a3a90e203acca733dc99eb1f09207da8087996f37f0a7420480848efe0dff1d7712508fa1b8d178eda4b05034e46a7328bb7debb9372f92cf4ea1a9dc7498221d181160e0f7dfb6243eb1f6d166356962024becfeee0f92eaca2f71b3e679bd1d955b83e255e4e7fff9e3cf382424f1a9eaec82fd45849743dd4cc99153e3a78111c49ea7ef69168e5aea01e2d50a753d6e3b334bb6ca43a9d404dbc461053211f0b4f35d6af4f18b1b8f2390f6276c36211b2c1e28feb6ccdf59a29c3f067df4ccb35e1c08024d2032df90f8a289cc469e9b1979ec398a62e9e5bce0c57f956f149b87c243b1309c2f69be50b15e58476472214a0c6fd40445f8d844d4e2193ec1b93a4c2fdf02d4073323d656b16a0ce120deea24acd70175d5b224ee9fc6f5de4785931fc3eb90940446442d21b004767f3658870137cd827bf519f13d80c8980b3a5cb66b6af93e1e133bd39b373b566059c0fee45293a4a7c9beaf2e9fc842b76338c641fbd36ca70e6653c1c75f2c12dd4d3733d4bf1ccf9479a82c73078a204f9f4f856f7d9f1e33b4c015d502411cf867e5911ca6d4a7666b1878d8c092daff07161f1f963073e626b52d4a4fe9034205f3d6fcd0f64d34c05b4a844567791ce1fab04ae738f268281e86e047372dfecb1e471cb950fdbff50926a1d6bbdc620626e1e6114b677c0c7cd899cce8ba7910e666bbe4c07692f16d9508f728dfcb2faf936c8e871ce695e03d604fb74b6c85ef0fe1f30bb0394c5c8190044bebd2bb918e53f5bb3e1fd4fb7653f40b2f148cb2b0909fb8407f77a797c3d9b28a1a470066270a6b8aaf836ad3c8e9a1d6ba01a97229da37d6b65b104b7fed96e675632652317f664312a7530fa89a3f0b30fe6aec3b3b61bfa04f28b91fad0f8cf3ef43c9a608cdfb12e488a4c23f990ca8248f76f9dff7c56906b197fdfeb76a8470b42cb022d3a254b01b4380a0a732ae0542a6f877cc6f6e439c80f2b8862e1f637dc243e3fbf8042b78dd74e0dfd504c4f8031577e2934e54b520d1c1bd18313957939ab2b62eeaf33361abd8eb87170e769902c78d9d2c0988b693502f70f94944e9d3f94c2c7777e6409986932a194c71570fa0e817ed2e7191f61ca4a8af3a5238b91f5ca0fff60335c80e182912048dc6139d5de95f86f89340e2aab23731c590d183290bce68b55fe7bdae3055d1c9373682a3e9cf7ef924b58fef251e1e82c1d04dd0127c312bee5e04fbd2470fa5e836189a58455197678435c6d1d2e3b28464a73d29da4b937ed26fa9c2961911c5771f0815d26ac039e5e633884911f7b182c37057c37058fce2e7c542cae32b8c2e358f76a440f1db4bdcd4b46899363373f56e212ee0d19ca01933d96db96480438d1be4111e315104e23507bcc0a62a8971911d43ffcce848f99c745a116238c21f708e57887025df3ab1e9e9b62dfcbaaaf42679d49b6aed875981c3c719dbef17ccd4620bd3f04484f8266afbda53cbfc8db5c4c54ef2d15d060a55eb8254fc3d6bbaa929b0552ae84bfaae40dc0bc63a27f1bc13c06bbbc0fc2cb50488b0e42ff182e3ef4d85e0725c4fe258e1a48ad6b7cf458e51841926787c9325bf4af7411abc5d15fc45ed77df0b0bfff12e20a5157d2785e79205203fd53f8c4a7e45df7d216e1ae33fbcf42c68c7a4538ff4c5f4558e545e4b11f6e081b7bc71af44e5324447f7f07535b1f50a0553b6dccfb85d491d07dede644b2821e9b84bb59ed9f7cb4eb003d5d350fadbe47955423c6a2f3a25fcfb75fa781f55068c19d38bdfaf5c9f03781de4cdba11ba01fb1b05cb973ac4d4a32fde9542bb57c7d09e64feb1cdf9c74c799e16da223d05980d8515fab45de650a4bc8e302aee02d73690786ab96173d7050d895dc3da8d96d72e6e7e889b36b98e1d6f3b47c7ce3de3f550ba350530255e9652b77ddac631cce1b602e54dcd54d50aabce83ced113412a282954c6c3ac526b9dfd4aaa3aac7f46c8ff93e1c01eb456ac36f222b5cd8c36d276ec4978e4b0730ae38cc3aa610861597536530737cfe4f2ed6c13f590639a763832d790810865194278a2abb25972e6e6d59f0b7a5bfde56b78cb998fc3374ee1835d5246217148d8f6be4c5d28c3f790360f08749725380671451422666cc365deabf8cd98acd942d8cd1aecb1866a7c0fe4ff5a0b31771dfd1a1281b9b4b59cbd40b0d50a40dc4b85bac68886458c95ab1f2d42356dcf0e45848f8ccfab69346b8f6dab3550de6c40d61f73f77bcdc5cf8aaf2e88fa439c267a8c3928bbdfb30976be158d343b1dd19793d802fbacdea4f548f5c8eb520c5de28321180add00283504ca89aedea864e51a9ccd90b3808f213a90e5be915082cd7acc3dc1287da79fba82a93d14e2c0157cdc8b7b851e60754c117bdae70c7de2decbb9a8698e4dab9eb45048bdbd66a771a84509857557ec7d862b9fbfccbebcbfa7b68eefa7b5caac42ff42610c3bc867027572f8a203186b3b8f0b049a2f9ba26733e0a69d69fef82c1ed32ec4b3a49afe23f419d800e8e927832250e966ce7bc7470adfb77a70e32bc74c547b27be7dc89194b5f69e0f23470dfec3efa129861d5cfefda07c4079c0ac0adccac701ce406e5e73c49bfadc8a4c25964756009bc313b97418180be2dd423e4f7808e8ad5cf02ad04f6b997c1d6576f67c12ef67a00cd0567ee34cc81671cc86150a090b70d8e89fda1f649f213f121f81f23730a1462da6d90064a5b73c85371e25326676eab3b73ad31c9b452574d48dd337f0dd40ae13688056a8f286331e5d3bf7ed76b80ba377f16a8d5bb6db04a83ce439226c43184f2f6a35377936ea75917ee558e53035fffcc1ee3c48f302bc2fda924413e4e2ca0bfebe9ba04c29dfb6b80d6017197891e7c3f64b521f88e91390c147e86dbdc89bba32df5dd0e1cefc8df02b5f6841baebef9214f1d2f04ff7132b74021dbe096d757763285a77260dce1b75971e01e10db14cc33e56569ebb5542b7b4041ca6540a14cb8cdceb13b180716d0ef5a57c10d736470dbed3f1a1ec75650cf4a17c1ad32c2b8d5313d7bc41d14f9cc3821e88e233906081395bbd1d1de236fa18bcbf7a274cae0e9bed97d34c7476ae1fa0eb4ea528193f5a57ba8ffc8d3de42af8ad2273fa4fb081327bb9f69c2bd7fd500ee92884ab5697043bf25f01794199b6e855c6b25c594557bdd60753e087d0bf5c1aa459e06744eb86483ebbeb5f9474af1a1d66e219ee67a004b05b16ff754c6d714f1a1c8ecb496901d2af35a726621ffd6f827386681a115dbed3070816dcb128501337317d21778cc8f226a2f941bac31027840e95d66e74a068e0f8aa49ed5d002cdd113c8830222ac6e58fc77754fc23890c1c9a19211325d59291eb353a059d589ff7a64819f70d91b44051d92baa647a548b64a8902e32d4be124d60a241b02846cc7c01dc9fc23d13cf4a748b449ab862b4529048365cc7b6d1484d2ecb2e6c85a1953c3fbd3103dddd1c1c050b12fa3b90e066e7b996da216ca2af99d8e0331355bf839f36630784ad4b753a4e888177c65819b6ac8e899bc648bdcc0bd3fb19848455e24233897b3e393a390e76f55ce569944a1e1bceefb0a732822e430565ebb0638536eb3a09a9b38fd70fa11d0bc2e2c9a29d0142d7c40e2f094cfed85828b868e1bc217d3b07039888961a0ab261e83ab0ddb09dc2b39fa452aeb73d26af4654470c83ae4ab500c93a8c9b773a3df4ae7805a304f664805a194f1686b4ec0f97a44aedc5f8654931f046d2c5d14d3b373607f4c7edabafd8e5ec48de20f3a9e01dd56b21a6c664be357816d3c6bd1df1b06c7c7f5eb6b9761adbf5ead20f36e13b8c7339b970a01fe603da5953076c424c617fbd59c2a6d48cb9849f246175809c8ed0afaa060d783f57b574160e68ee07ceb27264002d2d4555d81fc5abc9814b45c839021d7c128ed79c9fa1cf30f322a6a70860a7ce2879071480c2ff148b66e4182d5332280eaf03357f8ec92ba210c541de31c5153f87c5091750eb14f392250c09d1a60f664209d8afebdf65eadf50be9cca0216c51c32bcc9db5efc58ecef22c6b0b549741382f7dfe95223518f67b5f273cb36af53f8daa7b7ff1cba409225cdbae0c5c2f7d4aa83b8180eea038449e1649f81ceab1d1dbd50c942c6196e2280eaac71ae5f8ffb117dc9891678484578eeeb4272f3ac2b9d10d82a200849effee099fcebd58f0a28b049803ac5e8cc64ab1a18ed311ab24bd2c0c34453242effb9e715d34327637a9ac4756d0c7465d1360f98cf0697873442ba9b1f81c20c5b14689034fbcad17c6ec5f9ee2e4390d0171060947d2ac9b518ddfc9c0a7060464225f78deac9688bb59ffa1916c64b959954f536bc4af3e9d81756b84d0aa78e118d70f8c7a8391a3510e2ce5016a49f7438d3a1367724a337a6a9aa4c4abfdbabbaefb804ed8a24b7b47a5f57f4ce76b608f0c42cb48385a59b47c39c3755bef052ceb3dec426b6ad6ec86e94fcfaaac1925de2342cd47fd488e663872ddf82d685c235fa9c1ca7ad3ab13d10becae45a6dc40823edb0d980d9d0d3bb077415f9862f538702cd60f3ad6f13f065c09bb0f35055a33dadb93feaa754df2efca0de21c9b81bcae7f13ce3bff03c3d4d3a4f42b86d80124c415c397ece04887e91c830555c7847b8865249e61aa7b90e886645994374f23e5da1bb3d220db5cef3548fbd3778871a2ac2415afc007c0270363f782d98bba4ca7ae154d791ab21c922fe8593e6d6ad09bc8eb5b70c8fcd978ec07ec0f4b1b31fd79a05f6cf19127a67510a775d8eb3817e8661ddf0191f495910fd8f0bf3a58019d1e055c54d7eff5e48709d6fa8b8be697f0d2548d74467d07dd018b29706f0ade8e970ab41c981dee5251b2aa40aa78770de619d05f432906dfc0780f1bd29462da22a1424c34965a5f7cd3d34b693cdaa60cc9b75743c2f8315e6aadf802a99fd318f679774bd62e67e1621f71e92e0553cb5c97a7af82fd5adba3d12c12c5f6c5969a32ac561d2399acb326d481abca76f4203f50895cb788ab4ad152ac9e8c301e79ef02d0e0232390329d951fe282c8359578413eb97ae966a8e9677b2b226bf376003c7ad534f954dd5e88aac0d52fb8bebd285403268e49f68ed79b865f85b088841c432c0018922208d3022740ebcea29a0ceb50b9479f12227d53a517583851f335fc3dcd22e56bef60677e04193238c40eb7d9a4073d4acfd15c97579542b8c3a6c02605f6bf664b1f7fcb790ccdb4e5cf820f754a79243713352f069e811fa0af6bc5bef6d2d3d17527108d08e5958532c5bc58f441a5d5737207692cced868a2bafe87fef1c34053cd4d881915d1179a1dce797e37d9f0884ec9ccc4ddfdd3f501de738e257ee8fa2168ae4ca2525dc3f4e8eb1ad2d81adbf0c20a84b0a144c0a79d3fde29727ef912745e71b1d4f46085355751d54e632f12f24f945fb08f47d86dc26fd67bd368334c39e9cef613a040560f7c5747356810b7c35085274ebfff6bee1533964a2127758402d88e4ba7095b4f205c3a8d9db2fbab70231c5d91a15dbb29a59f49fa111daea5c59e69961eb008773d4c65ceeea86717d3e1f08694dcd446d2ae873f09ff6835d563694d4c81ae8232f5c364924dc03615288bc31ae527d0bed01f403481eac0068ee21d551069979d66062f01ca39df0fee1b7e2c631637a3084575978aebbb1cde2669aa623555d4da975da857e74c1985ea29d0c094ef21f88d9a90e0cf8d9b37bcb711dce6557587bd1ee12ccc2070144d7200725ebd162e78bb81cf624d8b0a25f4d0b5f640c0447da02166cd257d447e1729f26573d02b2e602a49c59f17e2e410c4b2d0cd4c9e8233e8e15e330fae71a5161d10d3511c995af42245a5936838dea44b139f514f52e40ca2bd19ae5f88bfed4609e2c84af1607c987a7fe1a1b35359eb6ee025c89480ad73cdc50a0f42cac0d034bbe1d89c9ab36644116175909d55bf1b6b1f22927a510b4f00b5349dd10ecf3a7455fa456d276199aa92664a3f3c1e109f25e462636391fc283d2ba8ac4b74591f260e4a4ec1c7c291825204a3631ab1257ab3ab9f07ffc4cb0b836f0b7bfebfaf61712f4f4ea11e0c53cf1ab5fafef80efbcc912a4f98175d0816280000b321714a3d429bff540bcd446945a91aced2401dec34920af027d1e2614012faf0aab229b7572388bf4d0dbf26b4587a9ac9ded6528f24b369181d1a54a3810790570f565cadd2d2c9bf4841e57bce0094c6088dcee640a62e106a124e515e9dd4512a3fa1c30c03289fff8f887ce9b40f6609adae85d6b22742ec68d70772c2246cb8a5a54a8200c3dfc30fad147534f800ee24783ee4403e3a1b5945a1c942c33d8ad6fd33b9c63d8808df2b87e692fc5d7ea8a70e941f5277a80c3f82ddbbfc103cd9fc5f0dc5685dca3bd172315ac1d86f746042ba5aa54d101e3cb8eafb1bc6fbdfc1f4e4898aff501301af5d071147be0fc1803c81e8e12302ce77afc073760775c1f799502f4d7fcfe7de2bd0a3ee961b9517979baae50955b3c78159f151e4f404428f7aaf537c3c53ee948376809176f3a8210ad96a320385eccb881956c5449b5290b81be52c7cec5e0cca5d5ad94f04a3cfbf2003bc9a6f7a528aa9c4bf6530b6e6b8f3493fc4a5ce0285d49a78722de2d4583c8dfab644d5df9c9861ca61004c215a0a624224c024ed02de1b1a1901257d60e6ae3b070c385447398f83147938f500c2a92f2a2407662d8e5a892272a148927170aee7a78f42d46b2f1f790b04a5895114456b0ae5dce3a5cf2c910ac2552222191d5559ccb25982c54de0f202f82ec9ff66412ccc359babf60b8f50ba8e304189c5c91668fc15e20913890e18503be7f7a6b2c77b32cf5a216f8fa7bd10c0c23ae2ad13c3df22b5549a86fcc3b7c71ba26ac2240ed621ae647dff4671f03aa338902d95be0732f42ed37cb6ad80e454bf5c9c7bbc15ebeba9124013bc119b062890a6d7543a50301f00f7129c53b43206e805c8250bbfab52b6314523ba2f538f97fca1215065f525a8427c331b348907789012eb73d3bba54c390500e615236a779cb3c37025d4a0c80662fcba835794717966e4d700ddd61b218c41df27290df68ad56f8b5b7745ee258a8200a4fc2a2a25d8db1545704a4690d43e2de486536ba2dd65d56856a9bdb41b01570738387ecb3c57f5d30dcf0ab4d0f1552cb473a2dd4f23061f4e2e828d7b48c75a116f84ef796d22de4b20a30556cda98ecb940f1dbc01b887ccc72c1d963fbcfecb96a82648ac772a0f491fd3bb2dbe70da579e224d8aa4de901fba9c59ae2d6913fa3b2a78c223f10d791e9a39d3af2d882668ef187ee116ed1bd8c3a37c96aee50f57ff4b3f6d1af9ebf1885f993fda5273177e37f4ebcce21f9b257a3d7cf408c4afa1360a4e3ac1756190e14eee19efb05f8a92631f510927b7bd75f691d0655ce227b5d58bd53f135781fd09bc872d68c46542874496a92bb36e662c74df10975d1148d7170aa846f986aff617abe089610723a4f9b763ee505f22ed64686223507bd3d1da37f0bfb5e2ae6ad55bcea3c0e9165828d041917c47e29afb65b13133952e7e2f93ada811784acecd293a45504986b155859b9412cbec26a3fc4f4ab7f4cfe42b55d001a0061a447b2559fad6b0f3f125c4063f2d87ad0011086cc7ffa994a64ec905b1a5bb959fb9cc7e7cc1c62efbfda9ec8bdfc65d9a50237e0a5b04c25942b6ac1d360a5a66942555cfbb6795340176e1e488541a4cc2757b484dd96738f808c336f09c778fc8b710d596341668d2cc59f76e5b0b7e09e145b694a39b4786cf639740ef84bd9879511a518c12e3e9ca2bf3943a63b539e87e6b654556540208cc1d3db75860192f84989be4acd777524a0f23c788cd36ea23c82d051c48847902a6f42a6cfaac53a4831419109a89624c2f88535271d4ee745c97177b369dd1f2537da235a51d65e06ca91cb9474fa416948a48350854a7e9dffa4ae97ffc7485dcb14f8a94a82e688c0f999352de765e932bb2b55546a6fab69e92ef9a1e0a2324dd5cf78a9805b55b212d5ed327c79394561eda9552a16b2421eea74192497050a484f1db607371e798626e919c83580c153412480ee0cfedb2f81cc0db8620e4ee1640a4e601f646a99b3752934a220f117d1135107c59d111d9187919ee88fe5569d7b229ada005eb89518aedc2f963b1a0d5d13c98b7d2179653544f43e47a2e3bbc0688e817256686d7b092eedbd81f013c30191982ca5dd50a4b0051164f556d521d631416a61b02202372e8171b82be9ff49a8380160a78c6e90189bec8c4fe145d93bbeb43a9d29fb1334557bd6ce874edce867efd9321553ab18f0069c0f8b0ae403d98439eccfec43346f9d49ab21c0f03fefed20febcafe8802ab592c39e3a5f00eebb3e8bd6e7d34e5252898d39cfb6331d5cb47dd9f689de3438ba91e642fd03027400d23ced1862d80daa012cde4246a86ba5aca3e266680a0b5b47f20d518f478bee2e76053bb3444ac28cdd61a519d08c97aca2a3dbb156f74655a5c18a2d4e72bbfd1dda6262127a5eaf00c10a1750824ace1af9bc5d2143cf1a98e0103a96c8edfddd4896117a36b12470abc9e8517f9ca1b27fa54874b6f7e5124a2a6e5e64a14275cd35bb440ed3c7efb978dda422dd627d556ab2489000ace53ee85fe989cea2362dbb71aa51a4853237746be4441b4818fec916d50a3a275609811d70e7c7f58b0aa0893f305029b9f341df703f0be01b38210274f333408e02ddd286f4cebab6b7aa3c205bfb5bc881fe3a84c40025d385dd3fb054b691f7e496b67e10d6bd9d52d0098f6ea9d5cc2b598410800348a7374540d596ca025302885f166fc0d74e5d84f842c3b9e6f6c5c61f6702f1ea6bbe3c96fd7932dde4ebc59b37721311bf4a1b5692bd0357604180d4e379c33568b300e2a5e27b5995b538697a2658acec19cb44d6d2d33a0ee679814a5fd9d7dfa6eda62e22137124c7ca3d6f9ebb4010c41742a4988ddc3f99799bd712ba82b70136f44083eef0af0e81df4f9735b9da339de8ca59124b705a57c9988a96c25a6a157bdd4fd1e6d8be6f9e29a87ad936a5bc70f3d532d98792a3b511d3dac70c0e0a0659653566d84f11a46481d0776fa75bad8fdb0fac402b38cc02a0244a44523c2dd540643b28f81ffd0a07a28e502c7b50831058ed4d087049e7471f1cfcf8aea2c3b74f6776bdfa80d8c621a9b8f63fab54c126ef9380ebe622d011c1b0e3c52bce44aede5311d9b5ffe7f2075ac6f56e91d2f79e1f1fa55f4cc46af7f9a0f29f0023270cb9d89c4b0737c103596b626c72909e2daf8b28923a4cef8e7d7a9da6cc51173d7611090152d3b5019da94998221b73fe996483871699c87ab163e00bf14c829cf6604013c28bfc2735083732abd2370e4f6d11a5f096e0d4e02ebae75c922dda2feda2b13acdb85530f8be229bdd3415ba0f9db5226d3c5346e4804793f0d11059bbccf37691e0526555c3ded36d565e99388fef8b207b62c835e700a5306e665c91d0f37da3f69555eb2684278a9ab8851942e8ff00449d09cdc73c5b4528a79096cae05fe2ec551105210785535e940a6338c38c61562f61c93617df133a3b7f9780c3bc61562747a387a8bdf652c231ac2e0bb3082271c280477085e401b266a8afe15f872f90d6a7b393f6cf2f5cdac575b4288344208d95bee1dae0f3c11d10f605f8b8f1aa92db1ec361cb6bf9dd2217a8d4e8dd651cb7d317c5f87c73b77ec8e11cf931226f338f33ed29977bad3224fc3bc5209531e3aa333cac3e52d539fd24cc6343da2afb65ab0e346073bd2994f6e59bffa48a32179c63a610817998e7209e522f761239ded344c96c109438ee458956d3e5448ee32e451f5863c52f0fb4aa5effb6e7d588b986e11cb73998947333181866d2648c144a22f167432b03858f5404e2421641f24e4ee19b0deb40624c87dfa3371f415f38736eabee206b91b8b89446354c68ce278a41eba62e2e8272a3cc6a4f028d291ce2a06f1d759daef3d44639b4f3f9938b625f3877ec7882b3c8a5fc1e3572b9b8247ab1aca4f72ff03ab14bfef9b0f8d81db12f07d296f3861666886104cd0076e4b728f3a72b649ca980f17b19fe14d0a6317bb63a4742a64acc87d7b5ba86df44bb7839cd87e07350a3340c9122df69368b18b8695de45782eb36762ea4bcbdd74b721fdea8d49ee0eebbfbafd741d1e73c0fcddedc7e7dbb10da13bfdeaf0d43b0d6f3cdc63f86d3e20a63319def86c43b69f5a6bebc34e80b991805d063bf650118be90e9d65c10e71ef70c7c452c670ef215cc484e47bb7d86d88f70ee9adb5c33c2d762dbb63e46b752897d962c16e3e2d32b10d69f1fb18fe863c26d062e30e71134cb4d8d2a88991e60d5729865004c920b8fde4de7c581605cb3c6e3e79c786e14710531e256ccdaded269ccd663290f5e9ac61e1cd90104851e671c50beb06f992f9460668902f99c37adb30efdf4bb787f775600d433c6d2b7321f8c46e49346c7b7f0906c87428d7d2d809632b4dd8ce30fc774ba5d23b994b977bbd74d675d6aababc1981b595d4f65dc36aa5b5cb30942b38a3311dd968e7b8a24f222cc09475f4a5dda67924fd821d3b1e49f8c93f3a6f60957fac72bf85a39d5eab7535aef2d8e5dad1aacd21dab3bd6edbd6ab151e378cbbca28ae79520135bf77ff6ad5641a8fe0b59087973bed5f2773f73aab984d1ad6dd68b7b6284b280f4ddff77d3f6e3a7d9fe94399ce5d8647a0301e3b9b6ed3dde77db466ed5d9d756a739c483db84f91b53bd23cbfcf4ce73b3aebc7cd2a268efa1f789c4d4cddbca675b887e9dc353c6a4d32d5f04839cea471136bdfeb51fe7d1a1e71e6b56be79938b477b8764d7235e11055b5d4ecc070c77c0fd4bff00830cf2e853d6d6a47b515f93369f9db4c2693c9f47193870b77cc974eaf76baf5db05352c3bc4a7afb628b80b270e4d601575cc0127feb010dac9d0fe38dce116f77afad3984cd781f9fb980366d3c38f7e9c424c9dccdb84c3f1079d5578b87465a7695a77b5dbb5d8c5eceb356d36c9cd4d9daaa9d0e173120429d3fb8cb4274b3971e7d09e3c2f93b27ca245793a9b049fbcecc06ddb428edb368edb361ff5eb3a367f7c74597bb7866fbe95e47ecb97acda953b0993a2d9824f5ec2cc59ec7ac0f6a097799c33334821cf232608b2c4e39c657a7981541e28a3ce58dfc2f172c550a0647999850aca0bc4cecbb724264227cb0799b22b34a093e58d482c5b9ce1944ee52ba55d875b3cbc77dfe1bdebae934b73bea3739b5727d3772d4daa93e594afe7dee970d80197ce210b355831b7888334c2ca245e10d205a4fca1d03711f771f4f4ce1b5899840a44f278790f048af9458cf6be16de4c8ab74b4aa1e032c5a3fcc65d294f60122f14c9dfcc72e8044179d5626739740220e4558b354b1943f1102d763dbd33d70bc5fc221b2163ba8821b9cb7388bd4fa65ce0c9230d1776323d8dac9143ac4cb2052739cb245b40ca3643146144964a4e00003b4aa2dc367d99640b45b12a93446f1a9999a4680db92f44a3a0412f0cc93daa1ad6e2417b480c0597eb294ee2851a588128cbe650f07d5e49e7afccb5ca50ce26f975a397576bc9cf26b9adc836fdcdcbd33bbfdd2aa6c4f37eb389a45252cdc82761b6dbe6051b46444323664dca9905dbe7eed865bacdfa19e2964554a8ffc6ae851a56e3c850c3682069580d11cd1bc761873d00dda46137deb1c7de396cc7cce81e9a079afc5146f651cca0003e3e83427c5c65d0826068bbdc63eab2c9665367f371f58b7289e26273ab9e584e00f8d8e5930666c16eefa3cfedab193ceae499cf79296fe38e3a4bc8366edc7c0442c7c7d78e8f77888f2c381f4f44f090e771a77ccd137171eefc1057cad78e2be54bc79dbfb9f3da8d1b1bb7a1333776796fdcc6cd9159e4d8697873e3df8d3bed8d8dcb503617b888f61adac0320b9991d8657813c3dd84f6d09806c47fc063e703ee89d1b4193de0d1ce380fb8870771495f78b442e07125003c5e864731e35126cbc0234d1e69d1b6ed80c7958dd1937b058383f02f1ebbe3d1dae000dc5ed2e27618b79920d118d7435f3da3310ae32e2d18a9855b6761160c8020700e1c1795c4c24e61b0cbf0068667be7167de683e5f5383a7a5b94653438391d4f4911637181e7532ecf3cedcf1893c73d9309ac7a47ceca29258f9d86fdcc61d6db6f14f0b6f6ee069a5bc71a78d5fd9a28dc76e6dd1c66d28ecd2f8bc35fed5f0a6069e7666c6c6364383068d1a34700b815e58d9e248b7ed40e0ed325ad0f61f8272cf26f2b56df7016f8fd18ab6cfe86b48343689c8d7f6ed3d60a4ed3c60a4ed2fbc5d657bca76d516b47dbbb87d073cdaed32f0b8ea6f45343601f9da2e847c6ddb636cdb61b6ed2e5cb45d8c849136987e6daff2b53d47de0e038fab6d7b0bdedee282b6b382587050f70dcfafaebc0d95f42a777c1e35a451cca38634cae45143a2c9a376ea66e43ecaed02ec2e720bc97d05e5b4b746433a05a7138029a60ead2b62f824ccc84dc1d2b4d89f69b187d71ba99dcc9829d2fa944999981f3eaeb23cd7a5d098e964b0d5880bf0de05b54f63cd14f81d6ed31e2a890d95d8107b3a79d4c93b3c35aafc47e71e39b20b793c9de539b20b79658717581ffa4996bfdc99eb4fc3585afe22e3ab15188f01f315eba5b3eea23f7d3f9d858f08ef9d75d7877142ec61d64f77ddcbba779e52de27113006e0615412d1f3bef2f2969787ff34d0754f675d8c5ffa0c8f38e196f7d3ef5d2fdd96f7f952cbc338f3f794a6502894a67d5f8af5b1b4abb2d6aa582cd54dfd2bfdde510a21a9ea95704e3b115fc32360dcc33d60fcc33d56c61c959fee18c2b86be52a3bdc93817f0f8f317085c13f686e31a2e52f2f2d2f2f1a077a2f2d789462035f5efee2bd6096bffabc5c96afee596ed3f5e7e5edbdbefcff5e6efda93e2f1fabcfefea32d4f1729b76d9e1f5df2c5d755d5ec31b977f1e3e0cd6f1bd67b93e4a2124bb3eadb5dac1efd00e82e049a53a3d75a98b7559b7a1acdb19df99f19d19c6bd6735eb88d17b0a0bd5e98e3ab94110eff80e86575dd4ad4e0e7f74466107cc1f54b7a157b188a45293562d05a6264e5d7a31ebba5ca5c5e5d5a5e5b64a354710fce77dde41e93d751bead92b73ea8277fc0ec44faad777c86387d7d77f4d3ffca3738eec42aee7e15f054bb7f628bdfef3bc87d72ab163e99f771efedd1ef59d656895d8d1033e7954b957aff25127d7995d5c6e435dee0e5fdd9a79b82307886495037147298464952a3efc4b7823e2693dafe639db89ccc80ea7214e4ade01f738bdf42e6a58497552a94e27954a157e94c5425d95caa65d1665efe9ce8c4261d50d6f542d1edfb5eff8aee1aa8136d5d96207cc1f40d6c17bfa478bb2875157b90d453169b12b17b607cb57b831d8ca64ae5adeffe98e51e493aa73ea1ad60ea64ed7aeb4aa1ee1552ad53ccdffa0390c7166b27719a197f404ac5c84aed2e9ded566a5c378757978c4afda3fcf0baf81d73e7bc7d4e75120f8fddab5b70fafdd318aac7d864778b8a5ba17866014d9bb96bacb1033a3c6f016d35ff6405d857bb81ea6ae4733caf5161c178681590ff1f8822bc63f682e1951fae9344e914fe1bd7fde0dbdd3774ffbe781e0c908af8447294ae089563cb2fee3e251279ff03deb948637f4a77b5f2feb5e3cce7caaa7b3fe9dae36ab49a7b374d427b4e5e0bf493fd43f7bbdd05eef9f0a8f51e4b0848b6cb72da2ee5d8647c8165178d4700f7a90e25127c6bf2b8d287997e117be7e781cefe7437b9606de2bfdbbaa3b3e91551f7fa09ed8008002009ecb50b0ec570a8f4172f842e1318a796fa1e0bef8e28b3a009959bbb7710f8f47cb415066f01af0521fa3c0d12e4847d561fe4466e1711efca42d30776c22cfc7b82e778c22cfd7246dd6c7d3cac03ffab7e60e71ba9eece1b188dc63c6bfb7602766f258c4573487ace4510e4b7059f83924a7ae7dc66766dcbb93cee4141e8bc820ce99c9ab6b3fe814ec0e67bd7ec66ddd5bfcb150496c0f96dbabfc9b60ea5fa7bcd46d9ae58e33b37861ca4ba53a54eaa86ea24aa57aad894de13147c55e142af4422ffcbcd0f33ed41d29c87265fe569ebaa1131b7a966b623d951d2b473d75516759c9983eb8058b7aea5d47917efae9a31d571c50c35057bb4aa5fabeef3b64fe306a0af6d3c9deb55bcfe26dfea0dd86dab48a75ae8945e1d4552e592b329feeb835b997b2ed1cd04ec768d0d6a43726cd09517ddc9ea43e6e4ec6ad8bdc1b173b7cdc8c721b2589bf452a3cae5645434219100bd1220d12a25ffd7b6dc4603d4fab499e57f49d0b830d71eb303e56b4286a3c1a1e57965a0e0c9633b249f73087052b1fde12591f1e33a3459b16e7f7c39579fe707fe0e1365df327c52bd3e2511f6a8587694fccfde1fa20f2f0612fc4dec5802c62f9e75d1696ebba8e99ef6d9ae533dcc172ef3e5c99636ea8ed68b335f0e4ceb3dc17a29148220c5730316474f8da30d7c3770dc30f0f36ece521febeefc39dd4490debd3782385b793ae60c38f8de4a46bd2123bfed0f2cb7f28c24688216832103219083103f10c440c206400b1020410976107c9989e4f90d290548b82668e713275cc1cb6174169b8a2dd9083a81c8cba402aeab04f4fa1a659116a5a78ad45b520223424d5e187480d4aa8acaf7d61072131e3dd83dc2f0247a321ce8cbffce531f7e1334cb5d8b7e92f75a70e7bd5b5d3b58377046f4b475dbbea5634581ff6aa830f4f782ce113ea74faf30903a1397cf8effa8082cb293c5a0c05074514b9870affa039855b38cfa93fa730109a3f9c2ef5dd1fbc30ae69e0982ea156c0b8b4880d569bb5288a2da71f6b92ebb78b30109a5dd7b32b975486cc69648868aeebd616bde3dbb5e8fde5822d7ae27db833af5c202e8da4063f10d4665251174ab49904b5afc5cfd03b8b788ad430b0a34f72f7772034b734523b496a986cad8bbaa861df67dcaec530c436624b8b135ff1cab438f37156b0634d62799ee7596bcf55c1f6b080b5ef41e6d69f16a34802069b211a36caa1991bf5be100dab498c7e82d03e7e40c1e5f033a7f0b8019a433caa1e1a111ebc4d572e1a065ef67014132034b75c75a1e072cb0f9aed7d5a2cb2273ca3c599faac4693a345666625ce501dc6ae5a541e98bdf0fbb4d7539e0d4dddbb3d5c861f8682cbafabf0487be8a1bdd73bdcf17afd9b600fb7667b6596e10b6b3330490a7694f176d8c1bbe7799ee779d7e5797dc485379ee7d5ba799ee7799e775d9eeb56cf0bc330f442cff33ccf0bc330f4bc0e322cecbc89858595bd31745d57e240ed86b5d45e076a17cc294c1a86abe77d2550bb5fee135c7c8491e80ba7a4c0b84b2e93cbc535ba4d5e5e9cbc20bd1cbd30217a316a25d117fd89341d5c57e429076ccf4080d251a3e0760a2e9531f5dd73eb937bf2e2b2cc017fb9360c74fd68b714be10750bef601e2c04f7602b5a4ee43ff77969f262f4c2e4a5e83c2f492f47eff9ec05c9c5c545bb5dc9049eac85603348eaea61ddd426ed72282828daddacb5dad55a26e0c555a9729e5c103c9dbc93762bf82305f7fb36d028b89ed765edd21fa0202c5a14a22ffa54a8a366d7cf153c20adddce2b31b8886114a3498ca3185dac5c4f5c492e24d71197508b4fae0bc865e42a720db98e5c4c5c442c2c2c5abd52bec210a773fd501947acab5c1512a024bb815f88c0aa06fb42046a77767d82fb3224e4be1099e0be14d1d72ca33eb25471615c51820b2388e7c2c082041786101517c6911669ea3d82dba264e7b688e0b60cd1578b90165b785a6c9985e0b60481e0b6f4ecb6f47c215407a04c3fe9d0e2a3ba870502948ee693d3bf0cd194a7840428c9e693924fa73cf1620e7248e1a255420250d90dbce295ac097f893bdbf0e9e422e0d30d5789d7b8ad17221e76745d87c3464db7c415309d7cbaa166c6e1130e9f6d986ff84cb2712a4459cd5f8868ccf5d3e15b0a757cb90c33e9528008f9aadf710f10873be170df70a71b2e0f4e6c944aa51a57014b944a3bee01bab0a40a66c8f51420e20c2e8801c246103cccb899d12209119440c0b551e321e04e2757e24e37ecb8465c61876725d3712a44d90e1556a6a4c66c431b5e63a3c66766bee35488321d58265f15478efb8ad5b83b66f0b551f3815c7893e3ce321cc79d47afb9330dbf71a7181ebb730c87dd4986ebb8530ddf71e71a3e9bdc255ee3b2b28dbb837423930dbf67f8cc44c377a810cd702a6464466617f8fb6adc082fc4a9398797c3881a346a6e7821ce3d0a0523b0e10a408adfcdf7b1e1de205d9c355c23d470eb979060b0519bd008030d8eca408631d0b841481b9546cd8d83da05d265fc99861a2720a18b2b0034c40efb3c038de37818e274be0f431e9da7199a9084ac5dd95119c830861a3960b18bc5808346cd8d30a4b9330c77dd09862f7167936b777ee1623012c3bf190630187d0105db8b3513eec29b1b7732b9eb4e2d9ce6ce2dbcc665c934b090857f730b777ae1530b7776e1330b7772e19309174cfe4d2f74810b2e7c5800b140b314edfa37bf9e5bd0c2750131b9ae2bb2808583a10e2f6f58b80d7e614f3abb54e3aeb2171eb165dc5e7893e34ea2d7dcb9c563773ee1b03ba1701b7746e1337726798dbb92eff581e3fad042c9bf7ab7cc831244578614b5b8588a35383583f30a4baaf07a352b5c618915aa604209c39b7012dd49854f28dc59f4a9e44e29bcde9ae713ee9cc213f0fd26158aa67065db985240d1c24e2dae97695c3770c46a4c268a32b7b83b406c318d1881e3393e93dc1d9b598d2a6dd4e3538853f354329518713ad588f18aa9cf71310e98202ebe330a77c7488e5371998d4f255a7c6e51f3d8a91065466612d86766922444b07175481bf5538bfb22ba3150b8403ce1d6e3b832666e9636ea614ec815c7138e204301588a34ae1b386235a810a7e23cf581df50164a58421390bcc65549c21126380125094c58c211272841095924e1c8d010922528210b6b9b6099606d128e9c4ea7241c41a1504938924aa5b248c2d0119512542a956a0929294a4849424a4a128ea8a8a8ac80618e3b89701c7716e135776271d79d4378ec4e237ce6ce23bcc64db92184201c76778c4c2124fceb6c49084243a0c148c0e2eeb882da06c582cbae1f1963cbf015e1ebf64184e30d0752a41f693ed5e838c2a5215fae9fcf215c16172c6e8c22dc1829d6e30b84115c76dd85838c0770c22e239c844e27aaa150a88a4aa5521a55a95445b845684e049acf203476008b5501947c75a89494eda64c5605867055544694142bca092c54a6105454429c3a85108486b9e44a88d37940b6bbea4a26fcd014fae0074140788dab3a0121e8073e40a152a61c77f2e038eeecc16beebce237ee34f21a379569dc17a297cf755f96b428c117225943b3912bae2b88f6e0ba8478705d475aa477353ec5aea01665b0b5eba588be10bd6821b7d476f11bc504de3b2d0a2ad39cc21b1ad8f513049445016beeccc16fdc3983d7b8a77caf0fed3e7ed83c89fcc7a4c1695c1f50cc2f72fd68eedc01900eaedd2eb203a0223a48a9face1bdc75a70d3e6770e7cfeb9d38b806a4cb13079f39b83b2208c017b3063307ff260deecc93c8a5f287fa8983abddc0063f37a506b786ea4b91b34d9306540a1adca6b973c85d77cae0f84e18cc19dc1d23330633f837874c195cd7153180414aa8c3cb55a552293aa5a7a4270b5a1aa8538d6b69a454a81c77aee038ee7cc16bee64c16fdc69c55d77b6e0352ecaf4398deba3bae05ff579c10bee12a23100c857cdf11df809b97e740d652a852064ed13966becfae00200c8b2f6697d28408ecb030f4ac828b5e09eacb8292c50853855b502d58eeb1aa22f9529db849f428139ee24c171dc5982d7dcb9f31b778ee0ae3ba978ecce2a0ebbf304af714d99c6f5e1e2f90e15a2ccc834c1a9f814f2cf754b79c3293bb26d5471d7edb26bf2dcab8437960c325c17ab6015d7e5f28657a8b853059f23b8b3e7d30477a2e0aebbe5b973778ccc145c044fcc9d7f5305d745a4e7ba8052705d412870e140c6d0bb6c207fa06711825d3f2c39db742fe47a99eb40d62e5eb9ae8659582ed7a5b8e5badd42c3d5e2ba739ee0ca1062825b844794ddf8ac6296a0043c24b858a36204f7b443c3e5ba727b51a5c01c778ae038ee0cc16baece5d778ad7b8619eb121c52708fe7dde8a6bcb7805765d3f5423d230dc301ca70780ac468ab18f2ea04cf3d105821a1d598349b13e7665c8573dcd8511616528004bb1aeeead3ec88011513aa5b8c4b03258444031c658678280c5d2b014330433047701d158ecf4ae201aa3e1faa131d80481a531006d8a1bce745ad7b6cd34051029eeb679a061a4a8401c9703afb951fcc6f5c05df703a7b9415ee3821d08f2010f74208a2856429ce78d032b5306f980073a1045143214c00116964a0a587381fcc6f571d7d5c069ee8fd7b85fdec0b6faa1011f1b00028465b6b0c21b5688730ae4eedcb8cd0cc837f0ddb8ff5ce46c13be71a5ccd5002c637e68c0c74db9c1d8012d2b2aa0eb42f11ad7cbf8091cafaee3b8a6ecba3ef2772fcd4fb02a0d168eeb65d70592af94e27deb621a4fb478b8a505c74565d775028a2ba5e832f978e27a1e904d8a345c60e0af56c01c3703c7712df09a7b81dfb8e36337e7b0ebc46ddc1e9fb918788d5bca34b795d4326b91be897ff86eb9f5a463374ec7ebe1e31bb7e5ab9e15e274f96a30227c68f9500019292e31b656e924430119688538b565d630d7e95b490dbba76f3d69188d53938fac79aee35b3d20dbd612e2540b5c1f345c3f399707d75d429c8e07259c182f40c3650497f15d3f2ef87676e262e0ba72aea4af1e2ea14c5f88de047e3d8c90005466c760c70b58e085687c218281efc40ef87881262c6081b792688c86b97e6c99657afc8bcf12dedc7f2b10c79dc06b2e057ee346e0ae2b81d3dc1d234c54e010788ddbe5af5eaed50a71beb5b48438d73213b7c88d57e0c6295043810948200210a8b93437c4a94cdc6da3512f7d09716abd4de3db0d716abd326f345cf82c16b0019701af71b9fc805b4401778002525249993e6588c65298d0177d3774a58b4b830cb80df8bdadb9c0fc2e2e4d9fc284c66424d1174d6192c224d3ca805ba558278c96d50a068c1750da04fc25bc29a2807f34e441330eb20005dc04a8ac25ca3292688c2588bee86935d58a3f5a194999cefa5c59281f5941999e068debba825aa4bf715d58f48bbee6ba705c179216e9735c17d112d785800bb3d322bd121786a7457ad875cd5c1717fda2df715d5df48b3eb624d3db6892e9755cd9afd1e524d3b304598c472b3596a0dae4b8c50269dc03bce622f11bb700775d039ce626f11a77cb9700fff0ed9cc47d51d22f7a97f0e600f8a5885ecda5d1d0b403fcabf7e500f785280db67e7c21ca2f4a5c3fda69e071452f3e28ed01fe873707f8c39b895f941cf1acd9f40b51c30e70fa17252f45aef0e600f80077e2d7570c44c3187409bb1629be321f20090314800048b8481b1509182ff7b7a5056217917ed1df2bb34b7873040d028c958ba426238e38cd1dc0ef9db9c6d5721be1d2026e17468d5b330c182e608d4b330d9abbe3026a1bd8f573645fc232d0dc9636364fbe2aca899710c7e6fb9710ff050698e3de1cc715c08bb83acee3ee381177e6357cdcffe832be8d2bc410a7a29389607e213382f34fc72de23b2e8f7f3397887ff7965cae09dedb59182e06be5bcef11a32706ae4b8326468f9de1d76d0401a346a16450ebc97e6994b43beea716e119e4e26c487b83c5656f3a23180d7abf38e2b93af7a1d37098effe872157c70039b890971f1f5f1c3e67b1ae721c4b119eb2801c7a571efe521c4390f1d78efeca1871278afccb08b633ce47a015c1f504c31cb02f83d8d01d0b86ed4dc7b67843876464ca9e33c13fe5f401c37bfe6ca7ee302e0ae1b80d35c9bd7b833dfeba3fe479783f8576f671ab714a604b1c91fea657767878acba404628c91ebafb4517188f32de3cd03346e4bb1e62bbb3b2278b9ecc6692e022666b24ce36a36b714807b92623d006e8a7cd50741735da48dfa1b574a20c69beb61429c7affc5c06f7c0fe6b83c1cc7ede13577c66f5c1977dd1d4e735f8fdd1f0ebb40dcc6f5e13357e635aecc34ae0ffc1f5d8ef987af9679b831a4580fc47dc957bdccbd215ff53ffce8324caec7f7e1ee4809c428b3c8f522986226f3414709f85e19e30a719e31c6ae09e25b334c83f8d2fcdae18652ac97714ff2553fe3b2c8577d4ccb1fea7bb83eae8ca987628a59ee214688f3ecfa47417c679e715d3f2ea016e979b8ae2b5ed7f5735d4057f48b5e46a8c3cbae9f262fbc239e8acb5c3f6d831ebb88b4482fe3ba80e88b7e871dc8187a2b063b3fbac44a5b9b7233ddd7ceb5612e3c4e71ef9431f538bcb9ff5c2dae168bc5b55a71a9a4a8522e94cbe53a59178a29043f975772b93a978b73b95cae4dab2eea72f574b9e4044cf8f56af51206e6caac7d20069e2da9c9853f0f7367ae0dd33eefba52c6605c7fc797a44cff72c70bc9f430ee788fb2346ab9a374d2ba6317b1eed8b1dc511aadee289dacdcb18b545c3f63a7ba634b51a64fb592323dea8e308632fde9fad0ece882f9c9f4a63b1e2953a45cdac9d46874cd6c1e5d3f2fe39794a9384366879e2c5d3ab4a4d35354aa33351dda758a395b87ab53b40e9da2757ae3e89c824e4ea7a7a83ad3b581c9861aa0ccae5aad9b4cddb419bac3dd8876b13bfd8c866d33265e5955ed91f34b346c92a068369b8140269380a00b27b9192004e7511a25694159a04109799c42e49448340c0ed98241be22b1a38c0c8d95e4ab693a19d3b3f1122d7ac1ce8f92c90f113e09d375d6ae561765626291ef362d7b966b13999372b3e2eeee6018ac8c75e28c8e7def20e0059b48bffa1d8df50c9770b8e1fee931d82ae6de3a3beba059d3f04998110c4a811de5e947f0a7a70ffe543c0ff61c017bb8e89c74ecc92ccf712be2c9f35b518f153e43f2fc2192a78fba1551a02324a38cb9984b66ee4bad68b3a2631d6ea46d489edb15796e58cc0d491e299044a2310a445ff39d5d5d1c45a051665e360582826df98412162d4eac1539c1525c12c2a5a016e73c88c4ca8fa52030886bae053266bb56951d8771114d8bd92ccb24566092474bf44551fe66c8e325776865eec016e7673716b66fc2d0cbae93dd3bf9ea2e2fc3ce3933f23c27b698b97b34580e97b652777bd09fc1c2dcae6425fa244c11ad61929b8155b266db46972c4f3fa680f29a9cf48e33b2c87d8e33f7a09f2b4bcf60477bdaa297b2daaf6ed1d74cb11483fd7f46d1d21af4cd930169fab4102d03135986272b7128f75b6680e006ce0b003baee65117b9df22eb15fa9377669944c53ed81d23d4045e964ec881908ced6ca7e2b2eddf768dd4cb1ef594c3a82d6cbdccdaa50c6667a83d22b79a3f97f27eb5e30d93f6a3c55fadac165b13f9e9594622d4b079ab508b4135a812c93ad47528632184ab100ad7a01a5485647c86748105319c808b37c8fa6135f2d344c25bafa846648c0f1d609eff1a3c0d797899482e8ddfbc9f06a2dcfa5389dc0aa480f0a9d72b648d115933719194f72d15ecd80d34b7a8a20867b94515469ff38edd7c13016ad8c41d1640ca523e6f03f54fff8c15f59e32d495d96a612b10911f14aac39bd3bf1aee985f50dcda2133c5530845994ca8dbd0d3ad3f2da264f3871269b16faa91ce33bca946644c2b1126113e8583cc3304c9526fc916bb53c2f7fd80293a6b03d1fc993fd306d4246f3ac77128140a859a57de7166f993bc28bf3d617975f2a419c5741bcaddeda6fb435fa5aec3d3a700a5dbd0ef8e3368cc29e1c9d3e224d2f58a8963e6a6f3675a41e40ad9e22c8fab223baee46c2b3a56fb8a2799f5337fa82db275e8491ee90f913a942b12ead5953254958a095f2e71560bcbbd748382b74b4f412da93aa148ddc5ccdbb6e1d944e5db57f08fce2bdfb016ea981965a57acac7965f2cc36a5d86e2c6630e88572bdcfaf6158df557ab6b6761ef07cdab834fb9a824568573c0cc62b91795c4b6e01f34b3580eaafc7e863b7a985e330bf760613d65e52998854262efca2f1ea7102dd315eeb172164ba585479d15dcc3742dd3f0082d9b50aecbb75b72d94c948239aa6cc2806ac571263c06c9a66f97e2945985c9445997a1e9364d5554bebd542a95bea98c477cb9a452ba94dad0121e752865dd745d582f7df2cc2a58a756e492c934ab983f6c95d26f989aeefc32b5e922de5bf71fcb5db1bcf1572ecab772513cd7f1677883825d57de157db5e95bb95d8b2cc7a7d7744730b3ac2ec31d2b94e3eb3abd2c97e1b8caa5b35cd065b51d2c95beed6a269615c5a794d2bcf2120a2db1ac545454f0984351e8b5a1a631478582d3339f36999916534ed372eeceec724e75c9facb291e615c657ae9335ded7277e14e79acac1ce58e391905b74ca767f9d6327df5920a8aca479b935b26cc825778ccc9a5974e8f32aa1cf56f03e9c559395539bd9b098f392a959b465546d95054b0e9f4a6d36f2a07595f61bd744793e9db4fa6bb3280995963e92b384775ba0c8f601d05f7607d05f7b82fe5a84613ce516516deaef6d23bc4b9f8ad97f0f8822b0c97b73e43235cceb9b870dbc6954c5ce9dba90b1ea5d8408edb7035e1b17519deb4a86ecb55b7d582c799b994d357dcfac75d9a2bc3a568f4a6bc8637292c4b4d5ffdfbe6dd2e7bb41b1e5599aedc945734e66da62eaf5667c1a35dadbec2638e2aa71c3cc52957495141b93285aa9ca2dc519551ce62b3b76d2b07cff262b1a12b77ccc92b47b92b7a15ed2af42a39dba6f2942b738fd255fec990089d1cd414ac2a53d3ca539d6597c725728e2aab7ccc51657ab024b3ca4dc9aa51880c1e75c79c0c5e86c6aaecdbc29b139ed69e6ecd1617f1bc94ac5dd9dbc71f990669703b9dc0d28f323b66b4d054258a09c584ebf3763b873ce6cc32332078b063df41f0b6f4abc30dafe8abb4e1daa2cc1c8f6eab2a0b034bb11c5299a275ba0a9385ed12469bdf76778c945eabf6ed72dcc4a3fc7cf771be846568e45be2cf558b543b77ebe78e4cdbe899c50c8d766595b8b34db0e3aae5ab2c2343079fdc9f59b5e4d082b65c889599d15ed0659994a37892fb41ba96edb4ec18d1368ee3c028666d23290a3a670d939907b625eb6acef1f3dda498eec0ca707ef6b0e0930debefe89e924e2f7f14ecaf82f4d3c01aead0ce691cb869f9eb40aea3f9f3c0d2f7811e087ea10eed9f895e6a9dd44a80520ada7eb6ef5402cb8215c8983e55818ce93bb19f3e2ad0fcf67337a0b911995ea6566c400d9bdb4fc3eaa7c4b427cf6cd3fdc48e5de6a131fa06fae968cfe6b3d1ed6723b2614181b2153e3db545fabebc138f12a967fbe9c9544631c733763fa0aca5a02c5d55bbc2b763649bd78aea6bd63e6adf5ab56a9886fbdb3ba924f7ab95815d330d79d02fbef8e28bd59469b2e647e71900abda26ee866ca8053bdadc29f8a64caa545ed8715e665bd430ed3079231b85447ae248eeff68189d4b54a7549e1e2c6232da4ed5814d89b6ae89269ea03194839f652967cf16aac8fdc9337fe8777226f964e963dfe2517bd4fba89d4bb8ce9660b730630a9995da63427f16f5cefc011795763e26e4b1ce7676260e4d0ef2879e479b1024cd0b2abadb4d709f33e45a560a403988a768293165e0a70cc43ca00ce53c55b6039e8a4e667a77a76c864954190aa642042832f02d930d2b99ee94407c3219de20019670e9e0951288cf2bd5d9d7032b5bd49e6c331d5aa6584bd2925a26c32274a0905f648e6edd048d51d9658bfdad3303553d4795bbb717b6bb0ded7254b5d4e5b4d81a289d18e5f4abf47921879f48cafd26680cbc875148ac3cca29952c92efa34cfa3850863b3a3c729e57da9a28009581b81ed1d708ea2c370d79744de434ac7be7f6680eedc95da9c32d1edcbb77d809da936b8bb2d650764f9db5b8c3f578ad3d01b2024808932294299330e33694dba7ade8216d458b724a9e9cf6c2ce1c151542775053b01fe96cde95dd99465ec8128f323d457cf2b8f914e9d9808094206182954874c02423c9819329dbb62b62603bfa8281f5f1c3e64d0632a6bfc140fed0b33cd2195092dc3077bf6ddb28c7755dd3f0a6446bb8434a29a594524a49b1b85b508b2de484a08f5e9ab7210d6bbafd74441a06a378654b52d23967e7ee708714c7d934444dc1d2d71d34dc41e56c5a4df452c6484c71dde9212f74d156ecb4b84d3c768f1166bea53cb0dde90eec276de5a4941203b4274fdc437efb2737293fe76bb8f9c8987e3ff9c9b4f41901a8ac842f91bac6afb3c722d9819271f3e98a640748e6dc7c3eda130429cffbd8ae81993becc3878ecedd7568b9bb0e307759d67357276f39b4276bcd837bd662770f8d5110c857bf043e40b97b684ccada2777d3d9f6336fe260c7d9e384b256e36af6e47e922744e82cd6326a459eb6c88eb347d54367cf0cd39dd38e1d57abd8fbb661ada93a85c00ead8c7c12a688243c69d8bcdc82c827cb2db4709267b2dce20970c832c4d9f2c450cc2fb20c6bd35f7721731149f0425096b9882438695811497092258c9c33f876a8b88cbe7e88b6d1a71789b6d10fc560fbb89fece43e1292c88b2730ea4593dcb28e431ee5923e85c0f6dc8114e8bfceaec6836036f4d3c3b31302999487b134a65d7a186c9152dae1390319433fcea019d4b0790e6f57d522b51f911683ec9c787646ec38e70f8df5e9a7d0250c9d5a7ff13d61e7658a1d32c3114c965bc825c0c2ec0a4816a64da0e5c85019191919191dc8682ddb06159ff3b3aaa1cb91c9b46a9acd91c9f5393258bc3bbce9be6d631479cc91c91890c9d30999314746ce5bea7ad4d3ae619f4cfeb8e12a694cf56e9c91b58f30596b093f8219f5f1c391fa58ca9aa6c259c3e376ef07d497e7cbde79946bbaf24e10cfcd93d53af16d9a08349a337b32f731e763ceece138dc637b5fd3364d2b72f322154f317b64462ca56d84c950e7e0c3809d971f8a8419e98ccb9ad67d9206b67ebeced98c6a94f3cef24ada7f70b9fa987386754a9376a19ef66b1d7fd44cdfe51f95cada36e8398db2f00252923020512a7c92c6a44c4a99862c47d9852cb9582d9139b8abe4374a36642d0599962e41ac8131401c91690cf9d26a8c0132bd56a71435ed0331da946d53cc4ad9f04918b0c57ead44bafa97572bf05b496ab1a2b10944674c1cf3c8fca1df334a5fc8e304439e444aa611506e26413748cc2136d87155647ed532f1ce7c5f29ab7766eece3c81b4f7e791efe314caddafb7ca4e8adab70b4a51bbe30372e9ed5d23db6d1a366e2ff5d80ebe4b750e11de6cb86221c2325893b411a2611e2ee1eeceb4d84dc56dd7696f98863b6f971bee409ab51e6387226b94dc5da16d9aa6695f05c31b6eceae539bdab4b2bbe251764cb0a56fb5ebe8101cd781a82494a3aa3e0d79d4832d6e98bb30da2b77d2346dd3346ddbb6a10dc9a6b2da666f3e94493ea261a04c2817d48852ea246f47ad8f73ced9dd734e38e4cda5c50586855916d631eb1b8bf58df512eb1debb4b2824ad279e57905c64f7774fdf4d41d5357b58b4bbd4bf518d6f55378837f42a9eecc2e1776c550a5c488c1dc856f8c7f3485a650538cd3a7e3f4efa6ab5ebe7d3a497ad2b3de699e0f054afb3a2abc118f0a6f5eff522ad74b7ca5a8f476bb068bdabebd1e61e29051832a169beb1bfe76b7d7266e3b6ca74ee6b7d32e96e44d5bb1c09aa08a206fd48bbcd138e4ed72a47050a12ad4e47ac350812a3c9e2ee3accb70878cf757563aaec543c65967c9c03d5e54431a16e3dbe90f8dc11c0506ebdbca37976f2ddfb6bf2e152f55b2fd4bb95c3264b40ea466179716171797d373adcda5c586b678b8ee721717eef1a2fa54a03d2a152386eb54468c43819263602963c618ff35577884ea3130909965e0919ec29b8c0a7758dce3f4ef3d5efe6366d5bf145005bcb2e674d4e94e33c8982dc6a5309762d1afedae4bf1a577b37d67172d6eff9d482d6e57dde964264dd6ed59bbdce669717bcb6d212d6e6fddee6971bb0ce7918cd9be72d655ce224571c5361e3b8e09b67be52aef7fdacaca0aeae0ea16d1e2f6958b448b1beadb26d2d736448bdb28e66d1e35ac8bed1349d6a8be7db241d6a47cfba7ba33a7a452ef41c2c0f3206bb08cd94a5d989219e56e37ddb185f8e0c04ba5d8aff72e14dc17b8dfdf5e56796b94ad0ec1a02d257c12464a393550da225a78a3e12aa5d6b508da6fce1c99dc17033259c33dfaa67ff39aded7f44f861b1e91c89b8c4c6e6d893ce993c813fcbc5fc974c71976ff36f0d63cc3eeab5d88f3accd0de4c21b8d9ba1864bb3549ad566939707cd1ded66e4da188686371453dca23635ad9aa48c690cd362fdad1a6cfd101bb6f96873adb7aa3c761884811dfffa318734cab2a8d4a4b9682e506a1b0a2075e674f5dcbecd256de9cb0ada671e7779f96e0aadd434e6d16e933667173e0933d2924c931d7df9d83969d19c23f8bc6cb16df2e51cf4ec8e7ecdf2c650ff550decb4cb976452524dab94d6ee2d7ca5d9b5c7e589a78ca99be6d12c5f6b684bb1fbb365cda469f84ab2a63f2fdfc91aeef2dfc42519a3693c3a73b893319a562beddb39e89330e30e3d998633f0c815e5c90de55991d027d8f0a2b85d66e488b246734ea86130d7ce1d69588c6b58e67045b95e6c9186c1d68fe20c19a14c4393e9b72d9c58a645faf03ec18eddacc6e93b10743b1d4f27a46334a7eface87c68f7436335a7ef8072702738fd7744632de4f41f128db509fedd53d2b0049cde2b6ad8034e1d707a8f49c31670ca80834b9cbe3b6a18024edf75d130254edf05d118ecf4dd108dcd9cbe2ba2b11def846c7cec88b28e8f1d934cc37f5f8e3be5701c77cee135777af11b773e79ec4e3a1c767b761d777ef11db743701b77d6e133b741f004dcaee20fb85d823be036cf17709b0467c06d2abec46d111c01b777aec4ed11bcc66dc9343a14dcc78f55ee9effb039054711ca230b2a295356500a9314a316e953868668fd368b067b51729fe0ba7ce88bbee5c67d21a22f171717214cb890001d569edb76723331314d9a139857fc821d65515f1c678c32323436c14e6567917c95aff9d9cd21af8b4fc2eca44659cecb44132db6346a823231019bfe86c6ae4392fb20132d73d257668aadc84226683b69346911ed60c7344c97f4abcfa46774cb31d8792fd8799a696c02fdea7741e4e409135d90a2c4931ad1e6c2f04cc34ed1e44bbe71a5736a5593dad874c3135719b34dfa854fce58fa22dc8e11d4e98b72dd36f0a8bb15cd3927ea7d572c36c4230a859a2f9ab50ed6a2ce15856f944b69f11886972b0ac35bd4c3cb152969118542d5990a0b8ffac81185a716a0ce11b5c815a176a0305744b71d8ea86d7451db688e68888611714a38d40ccadb5575b7693a5891b7cfa03a7491c56fff6228d3c892a80e4ff24cae97b20675f364c9b396644c3b9a33b7301e7368509ea7fb2d34627e43c138c41c11ea1f0a854ba8221473a18ece286c43eb55dd9b577d0b6f3ad56d95f09cd8b5c3b90be3f2108f337218a4d11e8dfafc681488082909a88b809a099011d0514fe7637f564041da91d06c2222a4a419d17654c4c4681e05754276888768059427d004e280e8ab076936c97394475fb252622512a11c8759b55855070acd704673fe6b5d99b59f1fed4723d28068ac8dda08a88d8038226b477123a2313a9b11cd8856dbd14fd7594b8de8ab6bd759db59eb097946ff6a656d9050d759bb5a7d2a6b8b3a4ef5510b8f10bfb5b8b75e84b8b98e995f7076dc7bebb6700ee39e8e168d7d3c7dcfc828c828c828c888098d7942f4d5ef3aeb0955269e903676b2a1ac1175a345c9f19a8fbf714bf35186268f1cd14f7f8bc13eda999f9fa1a1fea1b13e35a2318e870332323252e91f95fe51d9717b0cf11dc7b93c60dce381d3e2817574e67122ce3569d84f66c97dee8843a2b19dada70e46c87d2e897bd2b19d8de80917b9dfed74ece396344c12d5c127f7392694071138a73e9d2eb8e38ea9eff810f78995c7388cdbe38995cbf80f56c1a27efad8716f7dfcb8301a51df81e79216576eb960b7fe66e3eafbcc135272a2e396924a37d713e27a3b402929170050ca654029cf4434d6d78e6c880240c4720060a220f0d8e5c0a3c581c7550d1e7f038f228d7644b3016d44db11eba6c7f0b882e1d19a6e0368068fab1a78b44d03b30e04eb32473f6c471c11a784a7cf01d1fb80c7957d0c1eed0c9edc28ef8103e281037ae1162e21b5d85db4d81a1288c48eda91d72deec2640f7fde978ec49e2c8f7880e651f3a8683bc05cc66df1f8fcb1cc316e8b47aac7443d75e90273fcafb4723b25b344836446604018ecba395aece34bd32247d4d2e26ae48c885adc6b8bfba494333223df0ccfc86b52e76790aa081b3c23cf085cc2c444233392f2f930a9c30fa784e3227b432c76669c91670c97943cc33c6b5a509526b3b05c6fc813b28265f9e8097947b423faeaafac76f49247aee5ceac1d7d35da957667b4d8445f832e2d57e6ed094cb2f44296499c7094670856c1a65e3f8a9c120ea9458e88c88ef52b1f3d8e4807ea74ebe17188ec1dac460d1b65504e2cb99e3822faaab5f50abee2316726d757262015ecf6313cea1bae46449d92e74b2e79fe8b91e74f31791e25bc5547e7569ea6a32e57c47146dc11b786dc07736832cb6b78c372d3f584bc237986207847d43f943bb6e667b2cc2847dd1da5a31cbcad8975948e12dad687fabc278c1a670d3f6f4353deba0dfdaecc5666d6ad99a5870a7ece4c78c79c19b90ad5204fc81b52a56eabf499e7a54cfb27ade5946ca88aaaf6dbe91673451c51d2e81915a137dd223c5c34355526d528c4da112706cb319973db34f06a4762d08e3622fa798a06cb59c1725c51c3240706ebdd19992fb68d68dbe669148ae82138228e496bb8e29133cacd1135c59323ca34029862ea34a7802fdca60e3b323312c9a6f57ce0f4645ad4344dd3ba7f325daa33986606cc75cecbb45865e68fce738e60de26debe99c5bf374fc3bc7b78bea7d4baeb9e39e969921d572a2b53f1288964647ab827e26a45872e72bf05466b61a2dbb66dc3f2999ed2db49ba4d8adfe24a26065a2ca940354863a2c59652bb9c408bcd8016b72b5a6c29e5cd51c93e691f27516bac3e5a0bebe8dcd23e89a612d4d1447ad2ef9d8ec92c8a9600b5585af5a93f75088c07adacdb41494f8e9a28293a22247f5a9c425a94dda6168b263d611d3561e516962d6fa199226ad2a276593e89a8900637497902c0c2b4a8454a8534dc5dc17e1f3b96eba3de910ad126b95be868a448234d1aeb6cac3cf33b5d929b2ac94d91b4117df5116a85f61797d648afc83488623189fad5a73cfdeabbf0f8d5c5e3cabe855aa8b330f0685d5a8c5a2c3c3e37e923a396e93287ff5893657e734a3cb7d902c11666b1ac40fb43dbeee929d24aa909e53e156282911356c0452632d21e0a341bc1916f68c88b2ee4911ec94db1c85d93a0c1e866c5fa597766d6c72ee36318addfbbb66bdfa6697f61bd85f599c22df0f32c97dfb5168859f0c8041359a3bf8a4c7d829f178a6720acac019d0c4a0962d414ecb7a7ee08deb69e6a5dbb23fd8651492cbd7cca3f6e86039879fbd781db4db56ed35a0affd0f2f6f994cbf088d637dca3f514eef1724dc3b5457c89ed5da7172c5bc4d760fce2da220c3cbab026eb9b218e949335298b75977f1bc8ba9d8d90b8523cbafc07cdace3df05a759f778ac78fc41cfb03a1dfc37b7d4ea9f9496058ff3ca399f53d7ee942ddf29cff716dcc263c782ed27de708fd5c11506e9954694342d75c7e7147dc9f205060c17979696568bc5626159ad56565454525254aa540a853a9dac45413199c21004bfcff34a5996f26cb530cb5998f591ab81f1978f5a9e2d2f78dcb2bccb615c29635cf0b8e579d6cdf3b205b3625897e5128ff4f6f32c574a71e23175fb436322a7fe75c8e3741094f2abe076411912c1449ed7a68ebc1a535f39b5c9a37d0affd03278abad56b7a1ab7bfa8abdca1d99c8f6d3aa74a85497780b7152f2e9b2b31d37ca5b5cf3b5a72728683ee1a36e118ebb5389d561226b134b504a5b344ea21692293cae700b496b1f86e18d7d7844b345734e395b3ca89635dc4754b6853e5c849b9f18c68ed527fb6854b0631bdd961651aecc6d945b5a9e18a68d72ff79a4464d7c86d690351e23f2a62bce10877a785a221165896568c41341ec0c61279c004fdfc2c941ec0ce5a9a48d1a3631e5e9bbec0cb5cb5b84fbbc40666e25710e4fc19dfbd19947103b431916c4ce5096b8c82c889d21d9141c36226f447b1b9133d390073d885b336f78dc21f313a7f9f3c0ef88ed043f595ec60c5f64898bcc8c38213f3f45103b4332234e485cc47b915612ddb97738c894b594e85e7a094b517ad75dca94e0ee799f320f0731e244103b4379dec80e999f08626708b778c88c4cccedc0966e4802db9291d1c86897a7d7668825d891f2501fda78470ed5214b5cc31d3363db5834acdee3bacedad54ace3b898ab2b0752ae1296a1b3d8926515158a96acac1ca6fff9a7b73942ec100c9641231e1b34493dc67008f103aa4c99ced85d5244da2c54994298f64c2935b16310089248258a6a83a1a0d40155c2b09ede1431ca45ebb8eaca544187ea3f2627777c82cca989631b3030ff3b58030b825cfaf1ad671b7a52eacf71e2beedad6999566e15bcd766a52dbd0666da37f2a819d539b35b8dd1dab9a497568628a9f24c957fc23f1112c721fcc335a935a9cd1f7a01807e52b93f25893469d5c9fc8fc9d8c7042828ce99aa4ea3a6b57ab200d574c7117a72327f9242463aab6cd4cb3ca752522a0a4cc9225134460949534c92c596e9124287f21387b3a207442903161830085052b45d58bef03bf2fbc513997fb2724c89a94f73f13282dbd49054975d2625fe5366db579129a294f79277556a65252a652d22eb141a9cb9e9e86a550ef4bc992f5535096e5e5b10be2a1af4ea552d2089099e5d160868cca283c6a57c8d0879450fc8082cba8cf0dd08cc2a33c145ccaa5f240682ee1994f5ae733249f844e479035359f841a6687cc4030714deab068710cb6130a6a6253789451c8f3f43b462a564152496a1bd8d1f2a80c81f4aa0cb5d80d998120ab10b5d8a7c28e2a43d90ac97d2fe4412f5f0a7128c69647ca24296bd2462463320a92dc3c764441626b52f5a20baa5fd4a46ea85bd229e996744abaa26e49d53a236d874e0ba9f046c3d3ee906b52c34c158ba1094b114ccaaba3699467357243aa6b826ac2165bb08ac0a1266c9185a02624394aa54860471425444882da0cb98520c53e11e5d3514d2a82e4ba208d87be8c725f1b125bf9b1a2456d488be6a30d5141a2b1e74681a5af59d871e54705a96114cbd7ab01fdac10e9588bac6d3085273322af6ac91d50ee7738f1d83109f13c02b1fc903adb3326e4d6a1b8bbdc0eec97a29352d943563f593cb122a43d593cd90138cb620e469a15727e2af064048943059e90206b80d89311240e4ca9b0230a5692bb0b77a010514dd3b49e9aa6699a0c4da34e46196ab1ef43632a25fdea7fb4dac72b69991922cca8226a30079552542ab3e77444f4ded3d373121a4f422d9e08b3cd485d28660642b30c6b521192919191919191514a504a492528a5b3a514d52cf75566e30a8fcf5276324ac12a8cd2b2d542c2bbcc05d0916dd711a2311d594794bbe8bb8eccf3be7d7edbfee120ad79717b90efe00b20650fb2c2d7919d86befa3ab2897d24013eec87384837ae349994851fbbd9925f82be5a621f496cf75e00294302071902ebc8be5d4786a2824d021b71a2488b87cc8826eba1d94c369166b3dc43b359f6f0ec6b49dc5200f8edf328e0371c64cac09bae231b251101a4ecc32d25bc961253b67dcab67bad397d68ac35718b00df57ae04ca3d2c857794af60298c24e11d65e552a0fcc3dfa56caedc27ee1636cc5d965b906005579b517a022b730b891dd3c1f0ab23b1b3e31de53bdf575af3abebc8c21b869f0f5738c80ad6be0741c1423ab2efbbde6dcd87d79105f1b0f7ef4978ff3eff7d0f71102d888775643ab26f82de95b2af265121b6fb0e59ba0945082588be568aba69e58aae1479e23ce1d08257a2823dac019d84a60a248e6d264f406c9e9fafd60a567bf70d35cb2a221a5bf9a1af7ed759bb5a5d45f4d30975430dab4a1ac604c9aa7e13acb20a76ac49b5c12cdf4222d32aecf4993d2dd2125814a0165590acca4a050985945b4a78527cf72e65de952204dec10701714b0929c07f97b220de411312121e46f1099140e931d29ab3b9a3f148392fad9432353434a4d2a3d2a3d263d4a9d81495516e49633a32593353ba55caa9c78e2721a294a00e8b14fe8ec2a3f8f0278b828f641396f435f1b842921b4bfa9278bc12505c921b7301521fcb9deed8d9a30289a3ca41fec0025953bd781215811d4d482a2255118de9c8faded591a998a89064cd4a45a452014a0f7db5aabbaa9e10580e8f282a9edc67a192d826ca6377a4ab837da27d43e108ec58936696425ae4e159d524531135998ac0a0bcfd24445fdd5926dfd049e82484c7ae04abf9f11b4aaa496317f40de5a186c924745092fb1f9286d14fc9d6539f68b39ab44d252df635a38ea70452762ac80d031be4fe4cca26a46dec824e42251ffa3221553c7613cb1251ee775874425d50c987befa79628a34d405814023b023fd8666374ce2a96435db36068ca1ad84e98e72ba7cc350f8a88ff216af5a6c1ce30adb376c9c5fb5d88d6ff128add5b1765a8b4d2614eaf255cc1fe451f451e4496d931675a0e0e851d7342fca4f973bbdddea1daeb3a874ab1506ba9e854acd8c000000004314002028140e088582e1784422281ae77e14000c93b25872501b674990520821630c2106000000008c00a0010000a0f86be9ea235ae4fca26828d9af3de15226a12d575a4b24d945c8338ba71ba401eca12d29f2eca52907b9bd56ac34b132ecbcc7efe3f90b964a90e5b17158a631ebe7d8798472d66f6fd3bd50d9b87950aa5f3033eb578357dd586ace7f574a263e480b00bd5532765a319bc4dd0c5fd4bffd11036ec55380ecc7e3dd432f61fc72be4d7e39065e47464290755ad4c1d44f465af534a75cc750b9d2575b919c5c8fa6dc56d23baed211509bae52cdfc70f41a15cdaba023a6c22e71e53564543c3af2516326c437b1d1db835f2e9445ece61f86f4037184ab04a05715a0aefa8637c95146a2d0ef4bf4795751fc161255fdf834713e589bd04a2ba70b10deb2560068e523dbe552f82a48ebfe19928fdc3d6bb0673441c7773c48b2259f00f5081174995594ddc23ac7e13a0c8bc9b25de31cfcfa9fbf7ff035de97cf5b632f3b281f26d5af9bd1ca0d1c141f92ce75bbef8f8f780fdc88605051190c37ab8f19c228ec782394e5f7fa25f662573aa16a89503499ef2bc42dd301c0406a31304717c6a0b2011e7c450ea24c28241cd50da514023279fafd3afe122aba0de280be1c582eeb920498004f8fd04cbea2c55da75bb798b17754228379f5fe52fe050a55f3c36e6043be62b906141113c494cee8931d0de8406b07ec5f4bb3889a363773fe549b010a038100db5ef97fe349009fd100e4294445fb07ab53a692d969c1a35d8e5f71b523857ea09f5c3f76d952515d8254af2708bdd3eb56e019129281a7908d4d9610c79868421ec7aafd6994b27f97deebc82627866e527df26b3508e3bad400bf2d45725224506e6df6ee6875387d86df9daf248da3a0f8fa66c47b46bcdb6ac7f6dfc8707680b82b9511907d8dab3de72219d4d61a2c6bf3425fa0f3cc149ea4e65d12f0f9edbae3bd695f17a77b6d95fe01d830e1df19b28779e21777f79083d732d66278e179dce79beeefc1c386e8d5db66e63f18c8ae1a0faaa0be1ede213bbebc8a3045eadace142aa00db927b034ba9d61cfe217a38f3fda6e3d316fa6344cee18079608878ddf896a91036678f1faf7fc8cd52748c1098bcf59b531aed63d446726adb3933e730bcdf5e33dbe5108c1bd024d5240f7d59f7a35729db322d0db4802d509929a0d4d2ef1c4dc9ab9afd76c902f66961445ac5a0b75c04e6ddca551a7121b7cbda6b0be2418feeb8b6f26e0bd0f06161d5dbc90891553590ba7a170ea3f57e07e496a55a819a5ab5303d91d8deb5d7018e0af98efd4b44ad348c95364182b9b97d286c011593e6bcb73f3496ad602634c8046c9e8b4e8a6df7e132d6e2775fede1944419d5f2621d01b215f8983c2869afe2d1ed238c0a716432d4371bd5afae0c168bc9a2f9206d2fc3db2f42e62fbea232a35473b03092de013c76fb89382a1911d99c122e14be8ab493702971061b335b56314eb7dfa21ec635d02d26845766d809acae12a01bdc09d487b989588ff8444c0862d663f6be8f914944745291452e12048d3dbfb7188d3b4e84919e344af46e07d2bc6411acae818a3848e0ea78b836b4b93047dc278aa0503b34fcc1dcccb39b1e1ccd72db0ff5b6fbbc3a1428fe88503be6f120e3da19fd2f2047b65aef92bce4a88960df96a9e46bcad3f783119122372685434ef3cd64948e48220336f0079e8d8e4c94a4b5b790ede1ae338d1f811a1d8870de41b487e72963f903490cb6f52beea9c8b7be65ce66501152b1572218662930f9cae8acd27366ad4fabc7a8682e57a9368eabe13955435855bd2a3c32935a56024109d2fb4da5be3766cbfd02f1df2ec75037167ac71e4cc45ce1a742931205927562381371dadbe59fc2debc35e56c8cb00c06e18bd4d98aad0b8e7aedbd529743089b4f797986cba93d91095d42772c1e391c68ff3470d8192b0da66566e2cb8c46b482db686ef0152c3e148702e04805b12424674f43f1c3f8295da26a8f9a0973944ef1de4a7b7b9791fb6ac167562134af7b9577ff91fe8a3aee20111343b591479a74434c30c6c3a1a1c2f1418e7d861ded2d100a04f6776f19f9be46ba3f63bded05eb9dd798aaef0e308e486e53b67b6ac658315df4c08968fc989fe0338d7661354325920935977f62dfb342668b055e76b3603ef3d34d41eddd82434912e535fb11b55fba9dd0404ed0175ee28bb46c2793e55f4d2068b7a98db7213cf2b67e8ca1e789b811399cd04923e79b24dc576f2a4c1edfa83cd9cfb7629d3dcab9af942d52c15e355398d7b3bb15469152f7387f4f86f41bb63e6f6e840d0e831f8aa71a9b49e38503e7435902bdb386773e2045660208df4480eb38b5f1dfbe7227830b2fffe9bfc2b009c3aae029c2924e7f63934eb5d67153c0a6af33735238dcffb9bcccffd9baa330df465384f57eca810ce65a0a1fc119c43d34e9cc703c88ca1293cb31db2c7feae48575c0320cbdf9313d5662c329e730e0c719b207c13efe90ef7f14fbe9c1368cf03cbd808a79d7ecea35755c06fd06577504e789767e50b59879db87aef5ce7a212200b847f372317757cd9d13fca391e8febeb4c701900f9a3e2d400dde98a5abc73ac2c401d2fb1314f8166eea5f1c3b483d73a0fbe7a7deb09d18c2cd01c43db38e9a3f66d67f45980d4addd2bc99c5c8cb74d73bbf841052dee7cbff07aca836b4638c2b25351a0df60c44120dded7c743a9850b3c66b06f36b04c86243b5980e202692d006c3789046b063d18d94943ff4279cb360a74127a55ea164ce4cf707d1c5cd9c90f1256de095a7726b439433ff29655cd580f98b27943ce474532bb17f3cfa38761095caa915c2420d29e3ed8f772d2e69ba6826bdfcbf30d68ee09cfa7bd8336f8ae152980802cc608ee6417e155be2921746022214fdadc235a26bae967d1a3ceb7b4329050047914f6f26c5ae8941cc89f99fe19e5301b8415d1afd8671351da080587bc71d432f2f70ba27c2dfbf92895bd57aa21335dcc40eac4dcbe41c85800e68173fd23af3fa7b6583076c880e21403e662be5f94e34a93664da6ed25665273b38cf8336ddc4b92c6d1b056b5135f43b8349ed25aabdee2698c74a6bb4308e2ab9f9a0c1a9f0a7047c2870e0c3d70a450a716e727220d069b4c6131b6a3c2eee132ece2bcb88335b7d45a11abf0d276e350cb8dab24e13afb6fd3fd95d8a2b423154b16eddc07c264fa2447aedf91bec3fc67ba7ab3f47694433cf28af86cc565477f3ca7c44f8e473ad70d00f7d5c6e4c5b0faadd867cb1f843eb11e378984091667545e23951d158853b70e442c12bdc32971b1bf69262120cc8ea92f39be50421210d8864845361896db7313ee39e9f20f42ba86fb945908465460c405564ee3073a7b4ba21cc83371a6430193e23d7761531c35b77a28ca0766d55e5b131db75d154c551d3d4d0e36cc35072bab9143c2aa99a29e224e1e2ef0036c657e3a307e73e3fca26813e1356f87b46646965cacc3b7cdb481b0aab1fd1ec6037f8124336f6d3d7b9cb7c082427506178db0232554def6ed03d93871b06423fb003cc9b11e42afea76f352da92551979dff03381985d6fbb1081a75e6be020c6f5d59ca8f9dcec666733c7133fc18b655e7213d61080cf542c8368fc72fbcedf4a1301614f4c475acdfa672b27c594c9e72a369f2f09be2ebe2b23ed13c43a0c58d3c172443d984a5791158de6915314fff176611065f9935e8325f808d911a605d6fe168d85d843f76888f5f475e09279c5c568436971e2e9cba947c61cd680ee3e3ed191e4b3b179eb2027099e11acc4d4345d47fb1ad91b3f2ebe911950f9e3c52ce603fde077e163e1123df519be6e2f7d6a7b1da7caa66298f73bbb2931ecb5775414a749196c2b0182aeb4c36788125d84ee52c7be8c85879a5b36190fb471331eceb9fc409fbe14783e5a69f2fadbb6e328d3dd2ded9cd9372fc68242aa3857d59c6ccccd6d45a4812cf2c3bb416d91785a2682546f9e2f8d54862d91e9ade206680f20850981661500bec924367037d64a476f2f382d0f9916532920a4132512d36402363acf8e2953a316ef4bbaa40257a54dddaff052f12afd1511d8b416cdd94fe0f34b9810c932c941cfcbfb70ba0cfeeb74dc0aa1e416dc16f1ebded2f2b5509894e851c666b17376abd0b6f8febc4b1360575708218353b0545bbe9b480be27a51e2ed2be1f287964a92b0e8abf5638edfc5b43b96c7611ad08159ad4f3a05e70116bc281cf8701825f80332d7b3cbb22e43edf7f85af7783d6283430db1ff418d976e87a48d90479fe404b219b1b3827acb67f3f1eda025f764804de4ea7f8966943b5911825be7be3e7396205e9114029449530cb6e68ffbf9ae9307c474bc27915b456505ed4afc650f39bb693fcee38ede9a813ec74d1af06109867ed96bf19ed83a65a37e9e84bdbe3178c8902144ba60868f8d72d1e4bca79205fa5e6248034f8d820c546d5e944475c2ce60ea861f93e8f04747c2c6c8cb00b9c349154e104a52bc163e664b098c5c1240849e62192f421893617349748b2b9b193a74892dd194b62cc6b2d83199d39958f60f62ad908d272784272bd0edcc0000566f5f8b39cd9e076eecf0403a1fb98eadef33306fd7d5113671c26eddec5ac764e4f2c470b21da753c42d5e2b569fd7df0e7dbbb3243e09f9a1769ba5f0e5ed50234f16774cac4217eac2d792c317dc48b2bb1fa0f9e88249d722eb6ee6d2c03b865e775bcbbee7b9fad346ee71cf98ac3c12413bbe64fb31d3984c57fa173b38526d4fba7dba6f0037843f630a8c32e819a3e3a45a8a58a04088a68e0a52897c3068c93d6dd2330e08b760700472fc170510016712a41c17873137c4342f2dad36ac4c16f5905cf895a45d7a6d7e88aa8389f19cfb1b6abf6bdc15c2f2b5e5d1eceb21120bc15b3c6bf107fb8becd88b1de76cc9992e81d869ae19d7a927d8c2def3ddc2ede89ce80688856a5536c650a555b5c4e7397db26a3f2f03b61ce0ab1be7ae840df7e5035c983d1d10bd40cdbe10017d272e3e3841080da353df35f4687c9dd2d5751544bc56addcbeee428e39f4e8164d0f2f853b1803c5c7cc388f23f58c99480eff8b422b72932115ee9164bf114636fa3bb211a7f8500aafec232b30ac91223ae772aec14d97f4ae242bf946998638a6c4763608184c2bd2b4fecda890d041d2ce844d7301c35a21c95a455b9e43450931a06aa1152813a4dc36f2b9ca71d30118e1e81f5a146f472969e769fd2995fd6b9a83e95ec3e161f87391b5f6cd38fd5149fc96ab86366afe3af855fe9c52a45060943e98d8bfa30f815eb37e4783453c19c1ee704470771c3233efb5b16a482f5affcbcb6afe381b7fde1e7de1ff390ee48cfe4df15a10378787048329b2fe8f5006040e7275dce7419e896e100df8351d46d432ea8e4b9573deb490fe074b186402b299c989e533b3cfbdaf1c9ac3d43d0c5ca8b6005426184ccd09390c96c5fd76ef87989c6d65064617d27c3eabf58ae0b3b73166e64aa9baa9d4ecb429a133d8350aa01c27cb3efc024ee2320ff0e7e3052cfe03e995d9e78448243ad0c8d77bafd9304257716c5470d0765564a2bf96e0bebdc097cf0342fd84d1c042cb3ea5b02d733c4d79750a7921e85c3e5275e8e22dd5ee03c631dee17048be54a143ac441fcdbc7a637705c0796c3470b83c4b4adb3756e34abe4a0172cba0168415308e531c7503afff5bc2de0b6751aa2d0831120808692684871e3c52f17bd1b9eacea7bb99532a0b8fd28bf096564979e06f299667d41a6951f7943ecfe83269533dbb03a2e69ea1865457f6a77223be5d4efbbe275d296b353597f8e3ad7db92835ff175c3329a70b40d28d95c33190d13ed4a3719758956e66ab216e2cbe7eb2e35350063380a8edaf6d81fa9ffce3c0ca61473896705dd6a00222bc32bc6f1705a825a8883b29803382fdb1cc7fdd68ddc2193021bce70f263a62f27499481382877679b294d472f0a7f7b3f7f77b841487921569c9d90cebae86cc39ce0889afb72219ef9bb008f05220fa7cb8e8ca23044d477dbb3ad994ed72e3055910c982c565289d3dd6b7f6eef11bcad3d4bfff036a7e63215ab3172bd342cd309a7ac2e77a8e6c341f13af24a10b37a7432dc7275ee77f1817b4961c6339e369a27f667a3958092d6862b99e1304f1446c7228255e95d295b992fb9bce526f260225382b7f8c22f2daa6975a5eb4808f495a5c6f99659d0a55760033bc36fcc5567a965cdf608cfdfda9a4da252a31ad66c1f3c7e7aa032414fd005a5f5294793015a57a8f1bbe1713789afd9aa2a64af958ece8ea89fcd1f47edde9f336e1aab0e69b9f1992bc8d9e3ad6f325bc59c3cb0f5e6675036e787b7a0e1ec4a73f070cb9b9955e11c1fd06af31995cce1e3ad69387be539ce299a8a1343a860e81179e3ee7d5e5a480e05b02638ede4917d2a1665ad63bfab1da641b3d7cae0625b268ee8346ef60c5a3c0b21930a7b6b98090603172b24c5083b1bbc83f0a04fe6affb225abaaed17ed14af34068cf5a035e8d6bb9658e462361e398db11ed437253b7d5d911236997273771ec8830ebc55f7918ef1214b8b76aa4ece702316be6908ec3bd905b23f3d632dbdce8a782ae8a607af894b42531a2f9390f1ecce6ece8c29df8707a20a52b049313e09d33085b7fc7a2b3c123026f60720379d493338fe92d6d7f75179e284ffebfd19debc6cdcdd051687d48e2d2155b7d8b99d364d82b2861deb0e38b7fd9d69c7fb847334a54a6c16a4c8f3621d81e46822212144459578ccb6c424ee84ce0e8756cca2fc8aa2e690778f718f1cdffb7778dfdbabfbb22c7332526145956313e06b5c32836c2be9e9b2454bf14b854b09ac2615e55c568c8a2685790a90849392dc6cdcf8b933bbc09a233156e5101274fb3db2e425bff1d1387e8e88604485c68c31d8adba2059d7d2a17d00ac95a5e77d3b6e4e99b81de1d5b64c7f3b423db5bef8dd44d44b765e6910adf8b20153dfb7c29f453f048ac092f62d7663e239fc0f5de2615edce01d4f4be50298abf2e170d8fa365662c1eda3178c2feeb45825965a5f2c79fc36c267f1a264c3e7d40d5f81a521f047c8ff69b480d3e99c630ff5e45b8002c13d81edd7cf116476c94233c7a92c6dfeee19c1d1f86a49efb5a6dc8f0e3750e2ec6512afdb1e6dd5df99f4574f9e48182e05948269b516e554438195226b9b5179da2e2c3ab470403b742be5ffb0ee695c70fb551a75368ef86c58dd2fc271bbfe6f8186f5e3492808f51476ab04a02ad5a6c20b46e87137861af9f3292325f53c9c9ce4a5f465171079a7c2b9d5d0f8cbbc5a4c823ee45ee4f14069b597cd098e68ece14428929db132e2d2c4cfd1b29635d2eefbd6d3970f54a49137a0d664eecb63c81bce945b735b6d62284991cafdc1b23de75a7b9013a2a6f1dc1ee43274a8a762d9d1b6485653b8b7aca9b2988a511c0a77762c6523518d55c891b51c59b1374d0f81cff2cc3c50f4533d4503058e3bc665b6b273e91231ec05a45e0807f00f965035ee1c314a5ac9e126360420c8dfe08bbcfa62ae4379622fdc7d00f3b2764e2b5218c7b8ed9da015ac024434ebf20122b27eca72c3ef89f80f6198dc9a471e498f599c8ecc486cae9f6b3a8f0712ad4d961873d84e7080b5acca8bcdc4550cecabc4f8d1363fb6210f83b8a65c7fdf476879b13f79435cc011c20538956a9121c4e4b605e9703921703e98776314e201a0f47155e4b9b33a5c94e74ac113658a43afbdd65fec1aab8a4d7da8b6e3e3f4f22bc7e6f8e1f55b72e417987df59dbb85ea19898ff7745a6394756ad4c8ac13ff384279e352c4ab28225e81fa26c2b0b02f4a1f9bdfbd068d009563388380180f4d7b60112191c8c8cafa97cfa0b61176c8a534c3f817ec3008c992093623b1b5307e81bd53ebabe3d3096bfdd8e4dcb531de37f29c1036cd4cb26b633e67ba80e33c7445e730fad2b65e6d06072bb57805843860af4316f63f910ae6f14d4492cc9fc558b26f40a9e5c6bb93383215c3e38d15bd6ce4b1b28820ddc058834449941a0bf82901c66e73ca0efe504d4a814ac8048e49af4a141ff4763b1a7f7bc0ced2ecd0aa58ee81c8c21354aee9b19f6322607399f6bc3886533688e35bfd403c9a7808cdaf605457d0465c6140b9a544a7708d301a1787830d7349446a12264221964995eb67bbe176765d9ef93c7e909cc185629cb4eb6c5608d2f2d2b491564d5c414bdfe953069b04407f6ef879ec5d29989e43387329c81e0c38509a5f14b0572747b15c44fd69c88fd275279daaf07204dcdbde8690a76405e9ee9ba21ca3f98d05e367b3a1aaabab3c4a4807d5580fee27a59d1903d00181738f824cca80f74584222c0b1025512d9260a13864df08d4340f84ae2eb5db737d54be4a0908a8a7516dcd2f321c07311bc29720dbb3870285ed96100c0b448f80854892efc1eb209d046c4e15648ddb37ee691005a13f286a4d44972e89eb88fdcd323d1eb49aa3a6472348b688941a9b23acbbfa2c2ab444cdb5829aab33d05fd2c79e95a530fd798098def1cce90971f4f4b045cb2b29e3be1f82ea154118877e8d3de5f2894cbed23740c60ea6aa036080a5a7521716c6f6d15d091ee3beb818938a4b848228b1682947461a3d6f4e655bd15b8c10c0f8f83231b348ffcddff9195ffa939dc57623b2a66b064c1f9e3ed391912a4631c496d0c118e79528712b07f173ce043cb82f559d05b3cb0bff409e3a0819d4804475a2ce6434ab4918f3e11a46f02e2429f5845481fcbaa9f1529795e808888338eac8cd9741d107c804f48a1c684ff35f3c5c4940d72bb3a043c81b532c41b8772e5115be8f1e63bb75055f30a91f0f221567d9a5cb427ef8d25838853e22f00d122cfc55287e2aa1cd2b882382ef1d61efb0dd4554e9096bca8ba91a6725d7aa6e1173c979251742a009e2f94c6306493dd50d3d21b16280133601997a878b35628fb2a1350751840e94d511586c958ad7369394a226709003e52cbc2f49c11f0f51e13603a64368b25ec69057a018b76246209b9e115e24d8e0913a3a73d793ee8631849bab702d4e19d62162beaf9a16a9115728f16345d38f724d0e404aa08125a5a97ef32e48a9e8f35c480cb7e41ec2c0826743909215da3843965da66a8bf5d817fb26a93ff2e0d90b203425a0843ccb1ff6c5d4dff963ca3e046efc03ae861af94cf263fb6cc5ec9603b8f55b01ccc1728665e4e22fb2b2ccf47a963ee6b498f8715b9285a88e78cd046fcf4eaca347a34035bb0dd3d9be080e362bd235fb324849ad7458422047d69e414c735386d0496f29bc0d30b358e111a4fcabef7ae21bd836f971e887490522140ab4e67ad6c435ba96472c40dce08f49b3a49e72a79f0fed62fba5af16923231ffb0ff5dc5568a015b260d3a50884efab976746ba6d820a3a27b8aa8fd1193d62ca76feebc0e58915860a4bf227f38a0e79ee1fe077422344374a12e6f07bcacff18fb4664314ee9ba15fcf0e702f0e8168d41106257bc6439ebed76a4c0e7e64a804cfa2a4f69d02cf67445f0cd21bba87bfb71ee5c4b754fb8f4061deb051219f228b3bd7c137bd21a4531749f55226bf07b117db499c850ddace359366151c3671f197d00555082d312dbc2b58a4044a03c0e4ff8440dc8924f289d2d8e08032c9862d49ecdbacb725779d6b98949159b48f9ae339a5581e554a0f5ccba85fea1ef15bb820b673ee489cf1aaa1488b9c1cbada1ee7b8c9f8f6202b8a785495a41761d20cb41f255021318d9145f624c56a12bfa28a35299d014cd5863d9b18d88361522cb97651051d028ba743dd01857454161b58f8342f60bd8888e3c0d229f1a2eb5921d2acf75d5889ecf451c88c6b978619f9ee2d85265951979e75112a993fe48bd736739de8fccb4007713870b90610dfb2f311466379c0cdb1ecb60e0f0dd4f5921ffe87d169e15f0cce8eba5e7bfddf422df0fe2242315baa15ec28c0f9d7d774d39b6092fd402c6a1893a4326a188ed662cb83f40aec6c76fa2a86b8615a4d16623f7e02fa9b7d6dc2a504779ff9a5c59a53cb8eb84068395065cd83b0bab4f4095c7dba2bb8d67f0be9cf525ae04ba84399dbf6c388f68741064ef40fa18d41dc0db17b82683a0257a8bb53a887f3d087a791a24afd11415f61602a9563da62db2b15673e7698e70a8e7c0c6717dc7a2d5d1942119a7a3d32456ead741dd828be388c202263f01a70b2ed3b5108e2bbef2d7be86806ed73736e422631fa03bde150753d1a21ef8693a65732d8a9e1a88366922beb9060364978ec7a25a6f4034f575320a327b4462f69c559d111f5ce2490bff6302def20a1fe031cf1650b08d80bfa7c31ce0ceed9d63c7a726f4353985027585c1bf361e01fcbda74b5d09b711eb1909afef17cc68b4f76dce44478e6fda2c6a1d7ee81847ee196fcb662c2d03ad5c328701b84f6ad579921e9d99ca20fc01833e0c7bd223298d3d00ff3a76da2965b8d5360682f9cad2edf52c6f352aabe49bb677d43a5a112fa5bb94bd440a1224140909d5ac6b91a8679afc43e09215d7d333022e229d2873b7b38459bcd91fdd27e7d3f92f2fd49fe2cb06b12bd938437a645e84457c0b409abc45afb09ed177d1c30757fe1da7acc87f5e4666d292aeab9fa8cb3d5b1df0f2ac03f65f34a2d66bef14d5c3336d4fa09d98d5ec9e64d08ad35bbae80cd7aa7f497336b31f24f7069de4c71e75b9f1ac7ce2837cac06271b48c9184d91cc96372e53c37632b43bd018d054ff04b63aa57d332369e56a68e98566efa734314174979cfb6d4084343607fd2e09b10f55b6a6886afeba22426c19cf26989d02da3c0440e02f521602564104c978e18c56a456897d11bada3bc0b0476cab75b48b3463854706dca3d22f33f7f9a089e82f80ac8a27f9d0beac3794e2b37c190e653252092ab923e56dc74448305ec669c1a320080ec5adf60b760be375fc4cc500d17edd5c1a059bb90399ea66768efb2ee4dbe64a406a0a099578dc317a147046eaa8cbe2436d97cd9e5a36512b98cb236a3bb0932a0cbeb843f8c9d0bff6350d63ff0f65d4efec5e0b0e02f063bfe56803a1658f8ee23c9e21330c7a623186873d60cfd58bb101b2945fa6596a3a5e3f5e18ded917fe5530509f22899acf583b460b24f0705b94117c70ea387849940f838376d71647990ae8c0c000565792df0f2cb3bc53377f9d25ba34d2124fae3efa91a44ce747bf23001139ceba960a31d856ff6ed3a753c866cc472af7f3b2f5ce22f4c39ecfdc44683926ecbb693b2bec648ce27dc95c5fbd290280e8981e9e1b44ca8abe2a15689bded8efe3929199f84ab51d08bb06743fd68f56070897b3b1fa516e22e66f26af3a46ab96f30905096a46dfb59fe5a082a95b4370ff725a2073ceb83f512b9dab98178cc75010112069d8b0b672f6c7a305d5bbc110d79470a9451b045e6819e9d1423783da61862386ae13b828ec3c3faf161b01ee35080f6187e007014c316f044d5ab582261307c4c134a07d19e6a40df1235bd1df43a2e818e0fb79a71c9c91a5918e327a8cd58d266b1e4f574e2e14b0d2ef728a57c876c2ff0c7cb24ed4f0ba9bf14946f7dedda13397bc46d4340a71887eaee889d9437c063e64b670c855b107b2c4f895794c2d105e41eb32e35070f1b54df42214095e63b1d9f1f0b872491b7733c24f04341efde1ace292b1f1629fd636a0470f84580c2d88bf0fb7989ea16e95b9708250336d3c041d4ffdd494bee457d28e5baeb8f7b97bbaf477cb3cb23806532440b8f5a9110e4cd77e02bd9b8951443969da62df96018ef1aa4912d0177c7679ba64077684608d1a169b896d0ea584bca858f8aa83c4568cd7fcf59e6178a12b2861cbf256d0cc0f8650deaae02b00af0434ffce8d424298696bd2dc582b4974eaa9d5a0e8ba2d9e4606763a85af6311730ac8b4be2657655a81777f2660017eb00e4254637f298c88411c67a3709f9cdc6db7ec7131d0382236b230382a813729a6c76a4133b27375f2a5917e398bcac644262073c81c92e281c5e41d2542c298f62ffc4539c8a0f21c4afa8045adf48586a58b0c4f857436ee2a97f944d6f0b41a345fab888358a293c01a058a94ad5937c9957002d65a932df48654bcb4c7290bf2eddb8ea4bb3703ef63b4cc6d4dc64417caefb0495ac6fc6bc3b67ce04631de6f289a5351a8aef8c8a9405086b6058b0f9c06cfbb450a035f2d55dc155d2894dd5bcef8fba336ab65cc78f9006aa78e4b77a9138277393e3770848e67032ca5c17d4f5f6a6696cc422b746488feb9c608e8685d00da0196846367853af1884b312d620701dd667fd322423deea71daf34568d912bf1d825f8aef2b5729442766a22efe829276266592eeeb1347c557717e9c6dc0489eb770cebfb6fdf0b7d62a74c4726b9d73b2bf20633cb4180a4809d82d3e09f8fc543fec068d946d0f67f602fb72835305b264991ef4b9cf44e0ce920e0858e0f5bfc2d13d054fc7b2ff104c3c3cb5978f7d7b61d18d6222df4a3b5bc0dee1582cd1a38fe7c06e58ee86689beb5b4f3f9dde92fa5cfa824738f606a44999441fdd7a0281e313687f2b22188adafd52096bf39827fff0420d1f7d191173f1ea209fc1984f48e2e77ac830661cd7d83d034d42596c22caf75026188927b593cd94dfe22eabe9cda30ae3c67b0c4ccf7370294999f0b1cf0bd6b364c68a522690d2159e8f348abe99cd07cbf08f84d813134db98a66be6545b13ab0b7c26ad8802ce95a8fb2e61133c60e0682aa185367604c774cc4f98828fb013e0729bc0ca09269133697957a117b715f618ac03578372aefeb148ae647555cfb6ccd4efceb3e9e127720f49fdec3504896e62a5d16188c540ac8d97ebeb5726d917a445246b764f3399165a22c638d890864a4ae12a4cf7f0f4f0cb0d69711c40fb99816f2815496983598840a8bcf0a857ff5953a6d7f69cdb682cd1d2a706dcc4cf438e9d2c0e39259e456cce93066a0e5b9aa14b3fe52eaf07ddb19056ad2b15049bf0a8a940bbea430633cdc0ddf385ea65d53c202716ae273cdfc4630eab6dedc6392df6be4219eb0668b2ca9f0251e3c8d628f829ab32476c46153850653e9264dd2e50a50289270b768fa92e72ffb38723768cc673554c4524b023d0b5b1274268b900190368dd07edc057abf873301f6272f9b05180d9208c79a0e141091db17e512e70b968db88ae7e20bf47f3e53f9cc736f404bbed5960963cc53b3681da741663d9792a18083a6cdac1a99e11e410ea655f8ac0ea426ba64b583feae08ba1d4fadd91183f37c68f6082cd103499a832d773222239bb73068d31ffd186e0bf344176719c1d2e457c47c110d83beb2f601f0ae445582b4c9a602c279512060b4181b0c8af1ff2480488176ff6c08504424b2eda0c78392336dd500f458b203e01c42630b1b08659d8c09afefe05cd4d022873c3521055a3110a193464811da452485233dcc762220c8b99b349591157877a9666c55002233ca53734f9cc5e2f3fb05f8a00839be1b7096aa612ea49d97e1a347b273f4386e121539c3bc4102511d705a1d394e06098bce716ace4b79a2d29926e64b7a98c30a893d2e45097c07349bee41749d3386082ca21ecc400662bd9d5d369eeca9029a84cf1ff26e49066e5adf2e0037627a7b0e2655d1d184c5b8f0348b8a33a10cdda20846e305bf4153616301be405460484e55153dbf5364d633f52ab910bd7ac90b573fa7a1b7eb19bb6c643ad647ad8991eda61a6c5a3deb2395721b8cce16feb4d19b57e3509bc18a2c056e53509d881638ca4a95d38cbab3a7f394d769d163dcec54f3fcd945b1717a71b5c2e50848ef581465db7c1399526a03b6aea3d32f67cc5427c2cb3dc07838d1e2f78620317b3f7b31701d6b068d4ebb35a6759112bdd922567aeb59c09138044a86053a6b393f0740e34e603f6a50697060c6749c97f38eb09c4036092b2f509c7da96c54af6e14ef9620649780ea27b117d36744a5d80d6b04c0290abb45e61e51f1a9b71c26b852813d7092c09851a9833e026792d5da3e8e1bc951d5447a3731696df9e418e8617b0eccad51dcb880d1f46b5cf56fc323d6b81b9dfbc8d1b922dca2514c5b8fee64ca91dd16ae304fce499663bd673ae1d7b9cf5d4ddfe1850044f7561a23087eba5b32dfa1453505fd246fab3175e570ce1c9d54c57254d5780d64c17a9af3d32d43b8274bce7812434c6089a14474363d3771dfed35f654dabb0c05fed057f49c1f7b69d4aa65abaefa3119aecc344a29e08b65a5732ff0e7d18827dc207c75344432252e465e54c07201282cc921d3658fba672bbc53c0db40f81bd341ba3e97e79f65b86e705ce28d3ea7901d2422cd562eaf67c3664d9f09962a47049a489dc34996736eb940736b4dadd14baffc659e3873d46c4e4273c28120b4b8dc6cb06040670b3262a553ee0d0ef7992f3fe63df3212667bdbeac874bc553aa53f57a07059ee913a8a97ba98405d004209c0e5d6cf4d6655f43b59c79eea2b93a780e0645c865eb9d99cf031ccaab5d6a32b0cf97ca4b4072a65fee2b046dc284355185a71619d1132429f95b973d3a7c9852c7c4b153497c870dd40eae88eadd6ae789daa5446729efa19bc1e7ae49368da08b78d906617c5369a3d48abc29953c1788af21bce5b904a5649751d6fc502b83a01943133c4034f2e61b20beff06aee594fe969340408360658f70c776598895957a843340b63086010415c6d27672e0d656782ec7f93712b2e8740058aeadaabc043f1a189c284e3acb43529d8443175186cbc70ef2ab51c4f3b61e98cbdcd14528b6552d42e42773a1ebcb0980e076a3d2f220a9020dcabf09039c55f638e4d4db1e37a6aaff72d22ed2883a6567a0bd64ed70ba07eb9c3b1269e6a0c5b57422114347df8f341f1f350b8b9810d2673d8b7d718d38b1ac33aebf4c3795fa5dd4e75f4a684920ff42d5a6c5495724e126d4e594de33f11640761d4639164e3eed93a928ab97ed0699a8c3c018530a049a9ca43688e7b2199cdb63b85d5976c8468aa3c57ffb9ba3819da8e47b28a87317dddf4d112048b1e3f0c66d040a712baecb4dcc4f916984ea95805e59dc0fd1b95d1e27e2f2b324945e45eaf6b4d09b43795f187980f50a5ad7a4935a9841680b5563a6518991e9bc48409a920a85940a0cfdcd1e28d500542c92299d7f2a9b090e1e13cbe4c12d346e09260f70d65e8b14535779e8a1e64554c2bf39a5e8c1b88866a30319074e4f3817e7d1dcde4d89d0dd96c4e7b25bf5a3dfd0d4ec066d9f114cd3d096bb0909ab702e07640d694d70c4ae6f8c15d60f20c3053e781ea6f3a1961f470cfbc108c68657b1782d283a163d928b0038d5dacb11a32917942c40a73cbc2e4e9972cd6eda602949ce4dc0587773a41b565fec3753f1cd6dd2233e9ffeb5c1dfcd9a574830a59f70b55bd56bb7ded64743f16ff39a45da7f44c97b99281368785423da14dbcfd6f3853e0de8b6125a6583b46246d468464cfceaf3111d32e33b705caf0e517d16e00844ee0780a19407ba5b9e18301c46183c31c5cb5393300f5f8f69cbfc262fab05521f1cbd3793c7558295b833c3408cadaffd2822ca635ae2342bfd571616df9e021debe19a9ccad2ed8198f9f22ad7fb444eca6634ab0877de1c8ae3a222465f79c0f0dbbef37928cb8057b049917c902d84c61f7a3f7dacb7c9075ed187ed6e0a5232572752d08b2ab870c86d7d4cd3b9fd8c26c6a265c84e975df626d33f2adf5e6b480cfa9c456d30f521e3ef3d0fc36da1728e3dd75a6ae37cf2589bebadc7a099f486254b6ab52c0307fd0a387c90a48399319ff61b0ccf7f63980dc35658766fd68645d5d5c43df50ebc0ca0c42644af1a7f6d948889d7db7779498183bbecf271042b3fc869b903a5d9550d968108c39f78b8d33e612d8faa20463caa42fc72b82588bdbca2ec5b9ed1e3574ee26ac41787a67c3dbbd8aba4e21bd79ec9e55eb1b1805bf1bd827a8ca340b448ddb96495721c7d898a2f0decb0402e7bc3277bbf4b0a3e0d302412e870c376f1e43fd41fd243985d368b00af026faa3011311c641788ec071723f659a0653813c95dd8d5bbcdca694a8ad79b40e8003cff1ca7b22cb121eb4e28ac17f0f18df74e45e27f4d759d1a2bca73c4bedf857071ef74e01bc4874ecd1f0b1f2c568aa8ffb88f384819fb0617098e445b1009b72de93ecfde49c5791a7ae41607720917d1e51e412ea28e18a1e6c763b656297a42c61b93369bd5b392d06d2b3cc30e8ea51a7d0ca7ff4116cda9b77386b6c65cc3521d444d5fadd692c1becea2bd4ac418b51c2eea8310b65f196d3c7c4853539a815d2edf0977bf4cec9e2298ca8b961fa2c797d67135aa8044dafecc1639f37ef390845a69aef314e241b3a6ac9d3b62e97902c9e419cbf870c2666c4abb727e8f1df631c5fa31c9f02173552f1171854c1a0d8ba558b842ef17aec245d787a0f283f39975804a5d4c4d1243b1c89c0c348c5b987caea0267b184dd30eb4696d1f3121b26fc02494592834bb3dcd25043778df425b993d62b9df6b215879f510129e94b0408d2f74521a12ef49bfb807da19e55dfe4d560d1c8728e4d97608cf6f8b010edc0fee07ed681201435bb82214a1f9b80e5c5f39f6069e7bc624e22c2008d0b974fbd5a152c08215a6cf18f324dacc83e52d818bb8e30f0894a28eb0225f144e0d55534a720515a578a9e76fcaf42a9c5b3a46afae952acf85b30f9560aaac9bf40b9a8ed1cb8095c8db60c8a9193e58e9849a89ca34bd3520981251788525436b9cee0a5a5042432dbb958fd8fa76c0006fb81a6a7a0f7e808594f781326c7469ff4c9cd5ccc80294a291647e69c08516cbec70740078729cc206868354cd07407adfdb506d07e955b7aad4649118d744352bef2c6ee4f326fe0a103ad117508bc36caf99cb111c3f1d55f2b5984b3f8c982a86ff906d6fab2f4a471897b09251f75f3076077af7a017e9c33fcf0b4f17de4fd6e65f094a4b160c835f4b817d17c4da00b3f170948e04e2e805a60d27b6068d22009a6ba974c69671faf5e8274bb165747045b3e4e0d8f73a2eee73781ee1ee9b434f94da45c14676569bd90815c114180e3e00e3c9216d27a675cb16982d3a958dcb8ec9ebe61f8693d6b48cbde183f0ed351a91d48b9eaaff0439b0ae95c7e81c87238180e13a9c774246057d1aab62977b0d45863e949ee52c3544bdad98325f9075dadbe328a6cea8aa017bcac8145c693ba673c5c0eac557bcd427411bb455132838f2109c28f6cd3d15f48adaf857b93c4bbb20624c3cc55cf1427be9fa5e668fe2c8e7fc25fda696408ae319f1d17b2ac0bd0c8dab5f05de608548547ed497f2cfc453f343473b727e2b9c1ea474dccc4a6b995c9c5a7a0ddc776e3b84f806ceabd1511807f5bb1ce71cbe4e061435996d245adec11414bb6f30bfd4c0c23e87b91efc113e64f7cb78501457c6cf27facdff24c0673bfdf907d7aad6eb6368da429c8adf6daba4154a8dfa261cf880a4009af8c5b282869d17656c70e8294c4b2d84ebaf48754f3178ad5abe5f685a32dd1e4ff1a715b871f3ba6b32a6958ec5b46e6e68627d98396ec5945a11cc6d9cb82f63d3cb96b1da20fba5353ab04eebfdc571062544b27e13f2e71d4c6d47ea12a61e13c45358455005b65a0de9a32565b3ad92bef5506bfe2c66e0a9a602b0c6d6f6b18a1431e897c1cbfe8db16eed2f6a08c39af155ea81206ac5db019c37ceba45dba404d29b63efe077a8d336dcc604cda762fdae541a8afb98820820c3c9d9c5e7b819354207458074886b0de452936167b931631d741845b683248069667f90078e984b5598f9a91e1e360f9e0eeae35cc553b4e7560973a3e38437dd1dc947ae423d7735d8ae036ef70c7f2a4901e5fedf3b8e116bd12ce17c34fbd2ceb72c87f5586f7b799d471b9b4878a8d2d03d3d772ec67bb44d14e6db2d09fc408115de7c1d99b8a2abf232e05d214d703a3e95b34e954247bde80cee4ab8f9c65b5d4fbf214a58876e3cf5741e588a5743c7fc0e81a35d8c03be38066ddfaccb4e29d1f9020035529845b0ff70fcabb4cf3d8553400c330a1c43514ef1164a2b232ccfe72f93823680a5cb6d06b741baeaa987264734a9995b6c2eff0c4033210db55c3fee1b541c93ea4658b65c43874660669c0b62cd0fac26ee5873cf4603972c9b2e396c55a49a84981d4968cb8ca5120c7016ab5d33119652791435e8b15616e0688615d52dc59ec1be3115986b04c55caaf8493296ca5ca45e30769fa9238fd37ac51576c80681134581a40d996293ecd5f4c321a91c9ca2c9ed298a6cc4e2a9eb61b78974401203b39b9af127e47159e2616b7451284967cf89d7b8dd19cf8b4d3a3c625352e23996f5280c2b7936b85352d2b3137c7d6ab376bcee3fc4d46ce381daca60249fa70cbe672e66f268d5348142a895d86910dc0b95abcd80672ff58303de0fa5528895be90b5cae4d54451095ab2b01aad0404db9e52b066f8df358d3a6da27f3b8a6a09fe5a89945929f5ba850c0125f78b70a6b4a4858d9a7ae47e25f1398559445f853f535aa050a1229e22de080c4ce70139a610628e420780ef44f9e26dae743797ae015b225f36cc35b86df7a3c277ce7fd6ce1ac045cd6b167925b90bc4c1b1d769750473af12013daa8d5256024d700e9f214944c3ae453b99b339290d958c256ae5cf95f2eb08f52ff70a05bb4d4fd3e3b612c5ade65e2bd871d0f07c6bc953543e5a95925f8e0ed0594b6c9b776cf54c516cfb5f34a4d4ae41387bae2f25c3663d85d6a740b9b5c68feb2f5674add23d1436510198b7b7b798695896557461d8908179c93f420b2d0ab3c18c3b7cca1e70465930cfbcbf25d0fe22ccdbafd246c459651fcccb0537c1781309f66d228e0796e82913527ab847db2f40a53b39ebb004775a0f4d1123d28fa53e472000167803b15c9d102ca1f69de0fb93dbae68e8e89ce6729d529792d66ba7f2b607907cb70dc589d6478bb43c5c4abf3b2e92693f2ad5943084439c4a3a243ea2083a7b3338b9ddca17728c7f1a3a77447c8fa5cb4559bb387abe214f97c5636900f2748888a7b8318a3beeae6d0a619a1ce2bb63ce7e70b357ce7084b38165a7c3830524bcc8a95df0946914f2808151fd5bbede5f4f4377b5e23b489291da4b74fcd90dc2c38bbbfc3a8cc680c11be31230a5e30cd2859f16b3bc90930e7e659090fbf8a0f449cd4a22979ccbf607b2c7ddc7155deafc969c0c73d82176f7994544ba2ef154e7d231b36b5be52f888bc9a1204ebbdf46651b4484d45a872565afbb1f06216c0e1daa4ec2a6dfb66720f4b71facb2cc78884ebd6207fb408d7b597091e5f711b24950c2e1d419aef0d5c43dfbab0e1b64e5417c9601def562167fefa84d72206c679d77f29e58b78bf7002f87d7129a256b72e20876da0c0694251e9544fcc299a5e2cbcf48dd5f60175ba35b262c36dac54c34ab231b6e1bf4c56ff562e28ee31730d5a3f75873095d9ee02f93844e7c2ff9a04f09e8d0a1a69c61c2dc26ba9a93899c4b74317b5819782ef6c4276350f2a69c307c33df40578c89979e88d097a74d6607ebb41ca673806d95f8b545056711a6bb71e434d6f148fd5fda4a423d273d74b6cbda16601a1f75f78357195efd76833c44eacab35401d3a22dde139ee98ee8b981fca673a4d0a6ab362bd2d598835b433d729d0d75561ede78f0113434f324cd50ed3dd1f0143f25b685501573e5b0a2b12f1477df1ea606611c0da2c9d67c2a32835809f8a6c2c24c02fe5b16ac25d53f81cb220b6db8b6e747991b1ed06741469f766f663365e7cf3cd93eb6d907adda9d0880903c709f000672551b00c52b297de6a76a4a50880be169b8022ab9eee7f0d97d7dd3008bfc601050388d75a2f5afd0423f1fe75dfa80e39af50e712b717846b8f3c7f45bde729f1fb112ea13c4442cc669559998eb89164450464287d10f474e76079b1daf8819f01e29b70fcef616a17d4e8f25c20890426c91faf28b89aee6ac3c528e37deb18af653ec28d1e231a5847fce369664599d9c46cc146411dccf59e4dea19f12ce1791416517047c337a7b4e82a04c91df5a486ce38fa58052be578dd4ab35fd9acdddba8eedb1a37f402417736a68f90362f03eac453f830b794ffce7b03d87cc3c68a3e696afa882692df60a85e93b0b2579a5e178c9a26e6d09d52a804c34b483b45253d16c323f136262cddabaf34252301e6ae663aab6584fec44dbf34ddec806fded03f4c454cbe5bcf0b486715c70b6f0586b3e086463019acfa6caf1d2694f928ba2752f5a5ddb8b1a5c5e9bec36f5703ba5f1bd48f82d0df04fcfc950f08da720dee4cbabd93b210d9e38a496db18fbbbac30e15a1e29588cc19a2caadfc01b6f559c0d0eabd4a67d3d3756973b4266e09f94725a36536d3b52b187e4d316d73aa5c0da36c8cd5d0fffa696e926a2b15adf5a97ff038ab14f8eb2beec91eefdc613850868ebedb2a3d3eeb636d84c5d63afce293fa8864593d1e12fcbf4bf6e770585751851b2aa9a79d6c5dbba7168d2e6659bbcfbaf5105b8dd596eef0798cd2fc42bfbc030ae023ef02a99589fc0de3239c1ad9925b9655e3a37772a132a05c5c7c5d62ba909769d42df4229628a0a96e0fe44c192d0617b52dd8c1eb580346360ef897dde52a471993b82aea947ace926bad636ed6946511e32e713b4626d97ddd523a69b346b105b7bc2c4c3d604a996874ac9e379c6e347115ad3948760581cee6eb3698022e7fce2a8098b54d5d0d449ed13544028d6b34293ce1265eea5a6861d479ca46b12c42a118b73e0425e8ff0cbeab6b5979cdbf5efdec08c961a6495e52c8f488d3c221f1013bbdb3ef8de50d6d753515e5c585e6ea5780d715cd5df695cb8c50ea9702a0ee9972bf3c644bd31ce49143af48d7accab2bdd1b12a5fc5166dfa4bb1dcd2ed7ad820a7bf9c94bbddad58f0abeffc60ee5d6f5a5f370060567ef6ad3929f4a3862197a23cf29b6e6db93d6be5309ea6ef3a9d742b9e75969b1ca6c25ea490b060fa963d0852b1040779b64359ee965b75c60edf6bf53d6d5e64215848ca7c246fabcd740777b8b947ad3a68a2df141dc3660c41e57d2da7784489bc93c02515407708b816140a4b58885bbd386d92f79af64c4c49b6f646fe0150f018d861775b0d89cfba2e4c6501141a901032c69d7dab489bb039cbb7d0d89218f71a4a3bb9754a40e700f76a3f32549457408f6f172252d1907408741b5de0e1b702571db87be0ae9e30db17ac31264ddb629755f35f18c2eb2e6e3bdf529832892343175878d261be66edf67e18b8b47a221d0c8e6788bb7dbd81846b739f34865e5864ae66e4393803da97899bb0d9105eba287521f226a15c20b9baabfdd9d6f7712c146a8625922ea8ffc2ea58e07a82cbb47c2dbb6144eafee1f7837807ac4e85c6dab3d40a0075e39cd417747968fc2247921b5b9dbc4d730d445fe93d0a062b19dc6ce2805cbfc113e6db1697acb9f73cab689f3053119d0b1550a5dd5825d94e2b79db7cf8d8cae97212c111ca46888fd71bce22ce8860259cc1e598d868785660579627f74827678d501d37c0181d24ea763ceb25d988b3315ea5a0aaac2f0b7c2099ccf878175719bbfba293b8ae50dabad3db7a14e476091dcfe0b457dd5ba3fce43c8b492e832626df79edb8bddf6a31cd8e9be453f4d06937b6eaf5d68a09b36f82b5d6e50a127216c2863f295d27974921155be23442a7e2d82ca67853bab2e6e2ca42167dc8c2d182e864ce8d358b055145841dbcec81586634181ad47c9cc6d6c830c2aed129afede07c57d9fa0a3e0c6c7a70077c09d4f060a05155b332709892aee111085eb101bfff9061f6f89b1203c1e3891c4bd4cab4b976947cc13060488346191fd3eb3440c7c9a920d23a190c121f6ae948d9f0bbe93c3edd7a2f70826d5cb8bb3864052a64a9d9634c814f6df9009595c5a3bd7dbd7729be5645133c75e5873b4442f933775259dcfa762f7b423f20c71b9e1e48dfe3e25e908438355a7dc3b52ba0413f6938f9f6c30360101c1aae083960843d3692b7db4772376cc05ce8e852ea311b2d8b57113be6f3a7c4f604998ce6b7c567016fa0748292fe8695770bf8ad88b757d9d16d47226d310a44f57e1eb323f6242b927a08fdfbb35c41ce3b0857cc67b52cff9a73a69e0a155b2644e28dc2d081d2c6f6112e9a2549c2bda39bf878b69b644e4234a5cf532f95cf5c88c6f17c93ead23aeb09ddbd07661fdfe425f0ebc67ee966a3fc14c7e4b83b9555b3c2d8bb463447c4fa3b36c90b484bb8df2c9b79e2aa21d8cc9aa23566c4359c6d278ce09ea58b4c15d21db55aaf0d2243a6342c5b4a58a43105dc61fa4676612663947de60e20028447346c832be0641ba7e0ba15b180e092ad373d025b461ae48f56d605d7d3ac00eb7d8c027da302c611d26834e218a4a69e1587be9ed94a2e1d65570cb4d5da7bbf3855280831e03ad774bdd629b95ed1620ab186458c62c758bfbf3273e16579f3e184e7f8d85272c8fe334ab93d90a446fd6067b051748722fabfac340bf8c508dd4ed15d202f93559aab061cdfe174580431c69115531efb0ac1179c5d55d6037da291bcf904f151ed2eff10aa92ae30db6b9ea364b78fe3bdee7a36a19df26f5f8453ac18d881850beb1dd740f7801aad32b5262d7510fe93088e82031b41578f9e5e452dd140cbab9e0bc07ce031f41323b3ceb701ad02ad5e5a289ade7a54b43a053f178ec98b59f60529d109bccb5d2c88ccab83905513041c6e347aae5c798530bd64d901addd1ba3be1f32eeb83e00e6c294250de963dea8cc3747f47684f6d44364e20d47f7d31ede69d3afa412301f55a140ef76f794ef5410d264607648895a316d566201f0026285f673fbcd48110439658bc0617a22664b39a38e2c1a4c88afbd3201c036226918b8e8590c1c75b5c45aa1b9081ab43cc2590694790057afeb2221ed3ccf3f728e661ab00fa013d297269e2e27c88fe3c000794ccaad8b7174e4644fcda92077378496023479922168a647c27f1ef46fb4da90ae8c0cfc105b9ad234301714824f96d39c35a16dc7ab62a1791faea9f00cbe858b102b299c9f133326a0f5f6a221e3fa31bdbbeadd605d7a5e980252278af026d125eb25b786c86eda16a504b9908afaf48dee28134be914adcfa683dbc28cd22130a81832f53163ef2122366933ee1f85aaa159630c74122843de12a63e7bb9d8e3b073d2cad42b056416dc55fcfe191f607e79ec7487f143faa6eab71f9976ec11d838db9705a2db8b3df1e0be51f580fa33df6acfbbfd117a21d7dc0f5d0016e44929802a2f72a3ddb2cdc01a982c7661d05d94dff3c08be91b3372cb0960352501b6dc30b310779a7f3f128796dc2199a69d6930971f8c0b6f40269178ccf867019c0fe54f73086b6030038a53746e3ef5a6d482c1854c661644a829a5f5a26315ba7d6805fa3892484cee91f28f57f85acf0a2fa8938e1355c4f03ad01bca2c9ae31e56548f12011a3e615b053cb74df2ebd434f0985570ba277f7216a5023a33b6949a3275e91551e9c24e2ef09b42374f4e102e0e0eb766335c5729cc0f6abe8ddccb38e7d8f82479e4df230afc6853e948d50e92cb83e329d97eb68fb52a635fa25641fb75374b611a4fa0ebbe576194a40121cc27edcaf80a5e0d386e7e5b88b2a1647a07adc924d028ec270b04391396d76b6bab98c46cf7b580a6637d0d9032ecffc20204b9bd373242500eda2090cf7c3b074f7ad736ec11fe24d7ffa7acfdc48be7c3f43ca66a3707bb80e7f0480ce2bb693a96ee8fe6cc8861b54b63afa8e849be10f0648ea527c9976f317615e7c2c262ad25432f888c4e861187db10a3189cb48aa416d43e22880ac1c8e10325ed36bf9f53eec82f7c7aa08502cef0c2d424b8debfb8f8d6db6e2808ce858be476124a698474242ad72d8642d1634bd9daefb8bcefc28345807b7217c20c6a7cfff4c0cd79ce186647460f3f888bc5b1906bb7600898dd2b8f60dd79d6b56206c2444fc54cc3392fabf4f003f00d338ff3dbf399f45e85be192960c56630ad242773992d2a6d857db679fcaaeb73eea03b1599199c43c7c584656c7a849ec1dbfbf27fb3bac6eb53f83995feff76c84f1b464037755c7481931cb1f09ebebd3aee798d24918d191947f78927766fc27da24b6fe68390f6973e333a56b4f3c01c5d82b3d0d635809ead08dd173bd01a8626acb05df09b72649732977b6544694d774fd00c72a93d4b240b269ef5c50616312b4c719746d162c9b80d3ffeb188ec28fb1e737805c1097b4ed5f19f1013a28dcb916b5166d5c27fd4fc19d21b615e19a81c410d7bb2ba2852783be1420bab3a0e3f7479c026fc96308b9b83c01ab614077c0d36b05d0efc5c6e53473af33fee73b1559dfdfce11b88fbc94322ccffd153b3a3f7ae5827a542dfac3ca1d709ccc5d5d989d04fad9cd8e803000d6954b18e21441b0b28fc9bb0d101fafc7cee41c4fb78ed34613f79271818ee881ba3bc0f980f4035c317bc1aa17bcbcddf6dd7e2856172fd7dd93db2aa89a2c4a859c6bca90edd71ac895ffb4ce0243fa1e58caacfaf92ace6c9378c09f1af898c47dd8f36733c121d3ccc2a0070d017ba8b8999b0ee577e85e523b5450cf2b7b2275a59765c1b4cbafc390938a2e3ac0077d977e3a49a3248f1489195036334086703c330adbbed90dfb761b11c06bdd5a515b7542c5e466f59cc541b7fd8b54b868d58653088a84fabdc58f67a5e48f12318d635297032ddfd7b0ccb02e5ab929f2d2a8368eb5d5d456dd075a3f9d6f905f8d22fb66914613ec2f186b6442f99dcaaf5d4726bbf8fabb07d9065f6899f1d71e17f3c669f36ed8746f70f8c869420600d09ee37e3bc7c4af6b71ef203c94ba5a77b21d541a99a1d3af9dc8e2d5cabe30d4997f08f5a8d6b75a6c35ebf0e6a81fb20a12dcd331cee710745c1f9775efd18e0384ae0329fc332b281a14ab5c0686df496c929945d674fe462e73109ad43ea8b2874e1fb72426fe8bce096355849b3abf865dc109de7eeeb475a4b098c576f1160efbf8cf36986d60238a2599d22b01ee68cf90accb09287254fe93bcb568bb3c49b75eaee1c001a294b2f15f28f59e7627a47d9a888a33e0f8b6490235792994c5e86c927455813419ef1d0fe5f5460730d4e18662e6dc6be9843c829a81b38d3e91fe5d8cee725f5b26fcef3152af28f3c61ba67021311aa57dd08f30a427295a6ede923115fcffda7c5df489584ebd03a4df67354267d996baf3b5eb66ab37ad516712e8a311355fd5dee49994f78a19b2440b22bfc9ae978338d914b5418e327292ffa46ccee2d0fbdaa79cfdbddc5eb4ecd1f9153df1204a8f590230dd2939ba9b829e09419c4a1e6229d8f57a034e3d6b935805d81541fa2781994648409f47101cc1c6c03ea8720914a16c72ca505deae47a169cf5503501ecf1e59c927b419fecca0b6bcbe9a6f2855741881b11de22031b18389fa67a75c55e56f8abe3a5d403331f086da073e2fb61e1883052b7c5065a0671e341e1c819b83488a4b8e4c30030dd803f88bd83e0dece1d808e60a7bdc2cdaba662f5cc936b238ff488fc8747a893dc6e890168708e2dbb31a0306c9bc2a4e30aa2de77485e12d764e51a9e36827ac2770f81f5b9aa237b59ef2d446f766704df5e7443472ef8ef05b7e8cc053fbde8b65e549efb3ebd4af66637e136dd6ea88eb199f736a477762682df5eba4d97bfe042e59a0cae2a4730baab6590f3c1f025acddb9e26525bd7e3c19ddc0d4b3efc5096cbabee540b41fb2606b95b9c1ac5341528d9475bcc0ce8a086e078e4a0a4e3ad2bcc1b777eea1e0cb3c5489c84598ec1c6e135ce0cfb2ad0c342d89ca5e8f573a60f5125aba59bbd7d25dc8eec08ca0dea32815fc14a5a8748711072dc4ffdfdd0bc55bfcbf48fd5d94b5dc74e38518fdf57989a15ba7770cff5200085aea3c5aae1b84e20d9cbfd47fe9d10da55358597e769fdbe730a93702f8b9e8a05666575b23546512b75729b25ea6d832cfd6329bb34cd099006a5b4ef507d2639a197f2003a7832b21b5e1a4e1a219aa173dc4d4dbdb20de6a1b3a3c7964a7bd463e82dfd4db90b6e919f89c1096419fb4a67f5d0b9aa539ba1278dc7e9c0d13a646f86a8743ac20d26b27e8771cd82ef1ca0f66ef5c51b4e9c13c163e836562f34d170e0feadd6035a00fc62ab160375203e73e3b25754ef05a5060416228747a18998619f2c6fdd2c8bd1a667c8a2f25407d01f932e72d55fd69ec56acdcf6d1c0fe6cba03928c126e70d62bba8380d6960fc3677b353e95043393ec1e55fa6c70b5654fe930d10b7e542ac6982a01deaa67e674c409ed3eaa146fb392551830810899d83f7ed05dc86d75be483fb452e231dda55de73283c0ed0a1edb3dbaa44f790b6492a9c4be4be2a87f5c0ad699a0d5e143544151e6430e59dc0fc53909ea0010711b5ada678841c7577851afbb7c57cbd25f7e95d8b5b32df6e058471c4cd6a02d1cbe63fb6530a7b6c6807d474c458db36f9baddaeacf13ae04d0950517f2ca294fff563e863569784538219882930a8d94cdd99d1300e44c9978c0d086ba08590f12339c85b87fd00f00a8f094e57a1262608cd2ad22f0ce93cc2052d8090b6e1802d19de42256f3d24034b389c027e5ccfdeac0fcf91f9301729769162e6e849785d37b77af439fcd4c7405821fe26080eca3d0a02d40dea095776e35865f181a2aaab4aab6551094e638c496b29f6a71cb2567e741bca2e20932dc96a77b1aace399ab78f599ad5a9121e8261807692a40dcd940adba85aaf8096c3b33ee9857518c8669aab34a3bfc884a940f7b79c6116eadb2a2156a5c8b29f924a9b9909e722286abc2da01eaa3408f084c707473dfefe8f2c5455a5382a01d74192c2ddcffd53f3a17d921535e9a93a862cb575462e85c1dc40529f89acfd6608ea5c0eb846b4c9e07330dcc967cbafbbce5650f03f24cbd55d2d89b32277e4aac645491973100d2bb196d7444fae3d147a35cd4932715142f32d4df4945d277bd73c0ee3f605a6da291b7e024014c1f154e87af48c9996fb1fa6c907dc6638ccfce9b69fc731a9847ad72f6b4e16330968fe1137bdbae07ca3ade66d9210442f6432c3f46eefd4fef16b25b00ac584bc4d6b39077d6eef4ed7647a7960aca3caa2b17122af8d80be4bbb1946e5b1f097a0e1520ca6301e33310215e1051a0f71ef78e58fb575f5b8a49635823df86ca3b034c62df7f740c24b57cbec57ce82c1a47d004d8edb0c4d9e35b1ad89baec422cec8b142e8a768724e1451f8c15917cc698baa6bcd59d251188443fc7bacfeaf0231872cf9a3f3cdd0b808520970ea65a234f8a30c0ad1c9aba88c30a293750529b23a529ca225368365fce25099ad7791df2475ee48253a3000680d2e56ab85be576da43ff930f5fafe6bad3fffe4a1e1211343a701c625ff4e5fa32dc2fd73ea4a136a9858a1d82f30ef3854e1732a4ff910a4cf23885ed66729699fd2c33d2700b68050e862b3962f50ed0e9dd7aa6dcfde2e4a836f94f869b477be9759d2541c7044e7e6c84fd046a79161603c9a4298d1c7286bb0f96ed8a4221a670de612b8e52dcaabac196fc2e788b832211f28efcd2cd2ce5da8c75fe79c2940121c2d90787328935b9cb4e444be12401b5bd57ce6e217e258ef36a9733b63f9f269000a77a9c925b49f2288efd805afb98b4e50036a588b42d0156aca595bc123be08a4aa1df982021baf8556ac8fd8aae9492506dffb8610146484d4511d6d8a51b73f83c5a83264915632c2483810e70113db3537d1ba638417e98f81dab17fb17a00ff53047b30bc78004634ab33ae835d5108bb67443780efef4c742de34703f0fecebe2bd3b59b3addfa733a1442c9b818c14e8b9acc12cbe85e2b2d9e261eb08df8e01fb4cdbbdb4c47890748c6a1e706b06b6567206f3c96475da9820d310f8feaf03c8ed3df22cdf4007e0e0590062610bb87c5e373f4b3654c89c202e4ffc46be85f86a946d07adae8b36cbbaba98b557168909178fa499a4cb4c4e1776428553e5427ecea9544c15eef71d3112cf12d73fafd57f99e50fdcd14da63c4cfbca899338d164215cd4c003d9217c2d0a74cd464be033b0a6b5b44da04ea26a0c1a5165aee67f9a9f75fed7b94117e40cf20efe0bc595cd548b4288e629a4125d8d22785b570f25b0db90a30298c784adc1344f98f59b43b4c26a0bf59849bfe59e8ddbdb280423f640d37bda01715a0b4105b9a802907bd3c579a222a8198df000c7ed12dba55597ef2f60affe3e9095ea4538d804a848c0c4439975f11104d5605f88e5d947f9dfdcb199a467a98b07c09b4a9d4c3d4e44f4e029e0a57aeb26cd8ef1bfb807bfdb2b00f9131f4f430eecc809461b0875296e00856d8161d30e681e83c65a240844c972c29801410b116a8a0b04781dacccb97508d2fbbf439b5697c65cff8f1b92c08302d03d9434080f4fc161a3ddcd00f75d60ea2c93608af577ec6cb1fb2dc43e055d8583c010385fad90873343d5104a17955da453d466611f635794a68694375714dd36649ec060772c1603410fb0c8de47d9950a321a992fd32f86d30d0e10a26e5933fd03e7180664dea27a0927b4351b811ac2389d0cb857dc599633b246cada744090a031a7c659ba8bf37f423dbeb58acbc624420c2f796301c4131161c3482460f435b74269f1d56ebe9d798ad0d40b56f6f3d8fd16cd28e48c8d2525c0ab7b8731bd8b1fb6f9e692fd1e9be6640c01d941c9ee89de0fc3f8e9b9056dadb94c2dd7f24a7cfc35955b8381fe9cdcf323ea9d8039d4d7e2bdfc0a7b8c84417f8e7f37d9febb69f5e861ef1d12779f2574760bcf95a80280e6d95d5cc2044d2a1f801f04e87053f7aa097e4ec3533b2383c797e818b3449316ab54d86ef749e529898d7869547d7932546fb781b47a30b10581ffb62343146e631d8f6810b10e2be728b3b1f88dd3b12ba3463e6476a8ad6bc1e3bf3a26d8c447f3412b2d37a9c29554b17088a41679cead34fbf76300972d7d713eeffcff5ed0288d308d45d616e04d7477333274f8e2424cd99d159a251ce92632970a70ac014b4b1c655d5652d93c33c25886a8dc47c03f674b1a591a431e92cba547ccc305503ea912bca8c05f987e32cfab63959ad0ad77e91d31d3df16abb6a6b9b9cde6104f7379872566f448454c9aa62bea2dc6819477f1fcd8b06194b9753fccf0bc7f4da0f51d011565135da1e2cc40b29dae9c40358fc068cf215089490a6ef204cdfc635a40ecb8edc51da44008c5412b62e5857f1548c4e47c836d9573cb53975fcb7e17e5e08891d830fc57e155c8b0c860091c240bfe98ff0dbc91ad5661bfaf1f3c3962ce940f3f2c1a689fad72f5feab101abe008c81486363e4da83f1390367bbbb63b9ae3047b73db6ebd54566558aaece0f9e77da1a3d94177c1916570de2ecf3efcd7576c2c4dce510b38acf54b733303092cfb9e4b2d149ecdab863c84fb4d446e985eae7eaa455f875527fa941288fa8af3e30069aae6fa5e50bb2e6c9364a784eeed5eae500132426fc4fe78e189d70061a6b31d510881454b292db7fed7a10b593209634330aaaa3dd5ba4a6ac8781c09aefeb2ac0db44ffacb12e649dd9b9722f81e13c9bf69d7e9631352700f6c86f865092ccaec5115594aa44cce1c58d66ea7a4fcccaed8fe0c5654442974e131735287f1524e95a93d021365a07ea3eadc1a47146bc03b24a84c01bd06072720290441c86a80ac829114e2e74a017f0983867363d9280783a05c8299ff657047d01e6c553956587bd087715a10ff9c24baa07aae76acf8684ce913892ccfdf45e19a28a381a8d81dd4c42a23407036adbc37af3246a7954a316203a2174eff2253b8f8c2ce054f0ea122ec488d50d897357b2853815705906fb1fb48b7115609c985fce7be008571845bb09c3ccaf23f48951e3e311b9517e78bb2124ca09c2fea8856d2f7074a67b04aca7c41406a42696708401b9f130d0c3fd45a3b6c844f752780f7f1173582a3472ecd3f01495e2ad74892a119cbce4013f49a6b052a2eb31ba039810c214d7591403808d2c64bd596f791fe67399051e27a8fb98ca094ad5049a15065b943267ac82001c444a4472e77de015784a7a4186cac0dc0be9144195912418662aeda144ba30b229a78038486c01f10959879d8184fe1d4bc8e6724d449eca7383dc582f6d61ab6e7f12a86959e8f755219caffb2685cc7b48102c3ca963959a22a03e9b92207ac4625805500822c1ba37209596e9c95b0033d5b3e54addb0c13ce81ac7dbdf3e2d342828862732bcbfb7fbaec0b86d887a1008d8bca993006e7ef9e402701dd93eb229f7a7cd7dfc3f7e9731c86e8581dc6eefe1679b11175e7610779df21d70a768e7e1f9c97005d7e0ded584c0181066a29f41b581a4e3f3c268fb2717c880af6b0065c224ffbf669298135f85df4766c2185b338d653de91fb98d9a13e29119557440b4945de23478b89b92c842323dd9bbee79c85c9887f450244a0a26543d1d064606bc1fa0f4f7648679a146ef0d47c67d328776fe00335a265ef2f244564cf9b78acc104268145d9f5b8631cf02562314c8e8d1786045402c1b5f193fd2033d9cbb5dc9395816b4834e217f5e9defc3bcdcc01c3a0b148348539c22b1dada035a4e9dd4795223d7fb8c243c55130abba287cc0536d937dc8071d45151f5c950314aab1eca5df5ab00023e25073be9d26c4b4953123c3222bc424d4e7a1b873dac3ebb48576edfb853c9516917335918ec78a4115892b8f39c1fa1a63dcc645425175301ae04d1a8d14324e0b09d2dd832bbb55dc32aaaa0d0d42f2bf81eb2b994c9fb70a140ae06b114fdb3e64aa3590028faa427e64a24fba88ecfb3d211387b3c59491d0ace391120dc5f400be22352a05fc79f2a581f74d4c346f8c8997707b6ac830acabb9a33446daafe2c03fc90152479dfb5b1352daa09701a17c8703477e6cc16cbcec8493c3a78e74ccc84e45fa30114bfe5d2d2443e9b0a299f4a6163894497f5e43f9b7566414550570e52e4efb524b8e027bb84905022c945a65753b0e6b5b897d3572cb4296bb41ce2f355eae8da84213eb2934160d6b1ff1d5d630e9fbd0cb9f6acaa45bc784dd07171c2145b908b8dcb1b15ff089756b63237d48a8a5d483199d40a99a2edc09230e21c7e6aec39d8b33e0b3bccd5beba6eab6b8cdee530f4111c0b28cdeceac80e45f65274ba635bebd2e860c99ec9747f280d680c247d03e94f428718142aa641e66e7d51fc0080ae4de5514b84ddbc40dad028e51cde889cbc0c5711280a625d0dc867536d3700ce035017b2e89e08301819bac3a2de637ab619bc0a1d307c4a97de7a84751bf7ec80c60168e6dac0b2493e674d12860a1db4fb25b69d00e5f4e83cc502770ad946b97828af4c01ff95e08dd788d7a7d7ec01a155ad382243ce49bb669e94761ebb8eaef91736d76373e93708c8af2caf2d85af3cd85787cd7572aaabba4bc7b447c4f85cc4637fd633e747eee41e06128b316ed1a3048cf96cf9abccba86c6f5d6b3a6689f8aa054dede32b69214ea6a107027f2caeee40d494a4e23a77e8d16f2f40935d5e799200c14b7a9729705c67e1844c5640e8e59207be2b9999fcdb27f3b2e9d9de1d5ce4e2822cd22721047ccd88d527bbd2120d5878190739a6be2b597b5e2a26270ebe74296611f67eb1e2a828455c9a3c9caa2edf63bb8090f7850cbd426a4a164b74a35829ec3669bb43c3c62c930337c66ee2c7c1894b7efb11ed70428cea4d14b03181bbda01da62674ce90a649b258e38e69f02d46a0008a70fa54234ddbb6ccd8d588e87441bf619689b120966f1ca0d34f303235cdc0f8a5c885fbce24bdf04d9468f259b45c5b06474f9369766bdffccad2f9a3ea5d4d9e62ad10fa4c85cddbcc204cc152b45d6e0dbe65599e288cb05ad5ca17c7f4b1061e3ef8b21ed762eb1ce8d635b12ed7c37b85d9f27f50a84ca643973322928d9f0a6f9f7dc556587830d6dcbc58ac6a2a21b1fdd290f3a4c16efc789075fde707726f6b3cec42291c7c8848539201fc5c2ce1d3a0e220507666f03bd51cf0fbf6391f8cae220278e8372a73007a3bf64087aedd394a47687114105550d76409a10160fe049e7d3bf0e38878a12d2fb3d204b48d440985d51a28784b45e20a4755da280453d5842b1cac1e1053f0f56d1591862341462d35133b75234684b442b2d399f81a44d8d11f7640cc412824b66ec460c42fca0018f7a63d7e9184f6377a8cc2618b9e5f02df25dc14b651a43b1b7243cc3898a941ac3b7967c32431f6d16d488bb9b5d758ccc74c6d790cad5a48186e30be37859759679de080509b5ed48991751b2e1e0783c2c4e6d1cc2681109d668ad84c99c522204c4c0cb79ea6e4a4f2b90667152953ee1f590c2e77688b2ca70c249b35ffff895aeff3c56ec73f821e8f91d8efa9ca0ceeda5e70517c5a094005a77b1b8d77d74852fe8a4d448a47810610741d9b380fa176b839f8eee3894bf8e625713158f5b9097ab5ec28c530cc0f18538dd72385a9d354b40bca3ecb8fc48f49c3656849fce65af8c04254080f5ea5ba9a9d81cb0a2685424d7bce4d6ab4a784276f00edb05528e6f038fd0a870f0ba0f4daa86a59324ea5573564050d820705f50f08c1199ec1035430c0607fb46cb3d801e591ca799e0a5e9166604f9f2a622a56c2768d0d441fa2ecfd1740aaf2f092b79928c7a8856a16f87fa6fd39a25b4b5023556febe42e571091fe4986a27a40e32d4ce639f3e24bd21f2cfd900328a62fa033d4d9d98da3411ac890bc5d7a2eff47043cf91c65013df3c09e322712b790a38f5ad90c1265eeb091c24990c66f2ad0106c06f2812bdd7b0912fc15f92f57b3f3103b313ab21f116d594f023a41c3f0f66ab265c763d0876203cbb61cf09546068d018943a7cc1c2f2fbe35f7fa3d64615ea3aa123749c36c347dfde9e1286382507a19b93bbdcb3b27f029cefca817a0d7109ebd61c300a12c8b845c9311d5f4740e2f1345f8c30b89b2c484c0e04386b81b2732615c4d0d00a1bbcc9fe75946527585136060e75e3cbef8f0cb89521a83920879629c6036e50d5cd1a7759e63dc26f8370dbc14b44ddad575dd3c1e9eaa2d1b5a4a789866330f3c529a7c1785aa2a54a5af8106d92027825c99b67da31b6084ab1968901863ad404ab347b7c1c40e6ab0810160beb01f0a0e5f0dafdd9431d1057e391a06fb21d5ad48dc3c1b95fb7ad70926a95e07efb741afd53445d7805a15e56c00c2df6940fa5cf234c02c787878a2decabd31d4bc4aab14db082940b9b362531a7f8502a2f96708737f053d9867cf608a04e5a55649781cd2cebeb0970c24994d147f101c1154a6e54a0f13758ad81a03dbdaf9ca9cb31e44cdb417d452342f7c9891564910090dd922b38d24f3529eaf6a3244a655be116674b2339f9d54d1069503cc695d9d3d19dfa040464aff7be0b83d03e358da4f26663a22d4c0737a7dd407ee88082b045bef5dd581381fc602598a687b51b836cef59ad2966bc648bf59511e5794915efb624f8b8f508d83af323b81b7b5492095a34e20ec6d4f5b10e55fa21d243d12fd449e51c695d4698ac950a4c530d21313ddd39b443ae8d9dafb0868bac2c49f6ad201cdc1b85e0e426f7829221804c3d3508830bd24b79e9a24316bfbd4ee72bf262aa3d821586b1291a67e1c8929741bc9aa8f57e5fcddeb44a3d829a51c37cbc8d727cbae727dfe0b1d3f954c09ac62fa30517500b7ffb69c789f9b5fcde086ba61addbe6d137dadcccd4c374a2e2dc3fa88c0d18b93b35f45d5bc7f01e3d7a00dfdc52728a67fc28125e9237cb6b1492fd676e220f1833c6db9812a94b46dd4660210fb59457dd269064e55410d1a87b05f37e19562c63a24a0a8593cf75fe6fe25a46a9d27852c57427996a51057d363d2d8dc34aa3db7aa25cf280b3c1943390fe1134341daedcce66e619ed3c1b491287aeb06a352e4b91042b2c70df7c12d9e0c17e3b516acb1c035dddb139ccfcb1d8ab8d09edaeca7125658cd49697c52da2944f30c642073135813c7b0c5cc4399ad5b91cdf249b48de6ee24c5b2286df01f5c8d407843926cbaaf9c2eb1f40a610fb20e19559917b944bee2b27940b8b4496a3bc51f641aefb2bedc7519be601aa01541892910fdc0b586151c54525903ad59b1120b31076785f22dd3a068df371b87e28b372bfd8b4e955d5db75cf6966e7d6541bc8a1525f34945de424df90465c1cd534d562d327112b8855924af13e1b5a86432bca06b7da982a726a8287c0779bc142c1788cef0116079da403f068c812eb85fa8a17e6d233ab572e7840a57100c988960334e498f0f33a931724fa1c3ad92434645db16831594a19681301ef0e57c0831f1b1712e09d36a80b730a8f34d0dc130200b1a0bf0643cc3a51e8cfdf2a645c65bc5aceec19c246f87bffc1853d5088d3309cef6ecbb07cbcba42e35a360684a2b38088ead13c329819f794587dc6093903f5d456b42499bdb2b824887c6243ad170576809159c8ef0abe8679b95e3847808bdd2c84ec9d45a44851b1d2b89997a72bc919a5d2e626e84c95abbd1c742664f60e10d01d2dff5ac87147588a8bf4dfed20d6251fbcc736b291c5f90cd47c514646ea3a05c6b26ad312f017de5da2db6c7035adeecc535b4cee510fab739bcfb861c38c583af694f4b5f14e2b695396451381c097f69787c4407a35ec9e9143538badd59dce7dccd28ffb904a3da6f64284f0c727c0973dc6a8bc86ef1bd35db106ad2056781884912a00cf49f081446598264a44269856837a1e8fa47b3d9fdafdf6c7e95e10ce421d187cfc9a2ba8f8308ee3e7e5ea3f5e3cce5597f209b20a71ea587d288a70047021a72c18e30fe28e83eb2b18af8fe0709da0ce8110d4ccb3de655a744dd67a3dfde6c407a6622774ecf4350585a1afa2c36a5428b5981c256eaa3cb257d63a562366fce70648850c6ae214251f2ca39e972f62f3dcccbacd1827e1516e5ab0ba8e2068e43d5415ad041637125a4989ffe92ee19191d8df7d214e70fb1a044553debe6c965e453ea9c8f3e515d8095a7553ff3315771396cd9077b8e6d3aa0706937d18b1c3b3a49f53ea019705e3f6609e75bf8701ce85798b541f33efa5c71659fb95ee6d5e47323f72c11b85f1b3c29cc3d1e6ec1a64b22b652bf072efbc21781758b3829418f7403a74a16601232554294f08d28f457fa6f7944ea7a02bd4abd0366524b60491958796eaa13726b428e2b5384cba838f1d9b7d5d295c7a948b23ace20f830ea0be80d0db2dcb5a7eed652399617c17a7026766f4124af87b03910b35f108be38af9e1c4e128422f65598705935110e5ea7180fbf90d7937236fec79a6b47b01d71c32fc1a1d7cd37f779a6386d2fe3c2477700d5c0b25b46d33563e10352190b3c397cdd66b4022782009da56b4ce2436d1591cab52e917566b60b77f03a5481dd0834710e556a1e9aca03ca4ae146956cd9d3a00c4d232e05689da16866ccb07a67761a004c2e34446848e4a83d9c5457141a926b4e0f19fedda76f4aeadb9cae1dba5e2d1cf89b6a78afab6d0e0cb758e906e65f8b563af220d90084efa380d13a11a769c941acd3646708e408656721336b7a25cffeb5f6d8f69300ec9f8d8a495042801e3aab28908090af92be9b30a6604996012f2bb1509d4cc2ac8ecc79f4050075610c8335c81501c9c127d6aeb18e3bf788148145e71b94d1bdef24848c29a75d086e458423f975e62fa9003f056caedc3b89cb81e4d0ef85d03829482d297f0772c6daaaad24c5026fec2d1b44aec8d463ec64d69a2fc972785a001056d373d105b5c75b28372813ba4553d0afd0419be2efb22cd159f13184feebcd962d86804246af0623a0e077573416d6c7eb1d8405b42314033d53da26009894207078104e1d0ebbdaff56f0b0a4d21c78d5cbf461d81558ba0a0e24c384e435ece0c8ec32172fcf11fcc82265b87291415406730f0784398d62814fc4d4103886cb0da6c1c540a0996b9fe98ef691c33e5ae821f831cdb1a7e3cdfb9e266af223ca274fdf91a2ae07c3dc97b687d4c044e2bd9fe0d92c0f4292cec563ee15eb3652ac8abaf93539069c15a0af3972aa62c07d1506394820bd23a90c03cfbd2cd92e58c6573c58be00bae61f87d286e9e8256e1f848340eae4b00dc65dc4222804e4eb2e0320b8a6ec1733c6169bcae817ac1422776caf4362cdccdbbe89009678e4ae8654a38e00bad5313c57ff45343c78abedbf89d34ae552c571087b7dfabe0194663d492e8ce07079afb95d055b8b5212bdb5b0594f4f6803336ad002f2716f7ae4e8d1cc5506d03b0aede789261d46afeb13d29a17b6d3c357c3965cc20aa041deeaee3ff448196bc7d8fb13737f455c1d55611aadc36b331f7a6eaeacfbf9cfc79ad4271bd8b776c77d64da6c413254431ffbbd13bfaaf4c90044d522cf464e112a8802a6224787cdded20a0cc4be8988110caca2e035a6eef292e03588667748ed51109e414e0500cd03fea5ed86bd3d7f04405eacf06d5aabc668bbf621ea3805b9e3a348b4704ff607d1561d8ae79eb3d64cd1104f3278b45602d298bb4b20d3f9aa2be6279132dcbb9d9dc041f1adb02bd1eb989e2d1d1af0a2a97725fc2987e4324b7e29a2e1ecdc00ddef09684ab16641b7e86f4acb22898e9c727ad8c380e95a0cff16a569f44101a1bfc11da743989bc9562eb8014428d25d288408a3191dccb96884b2df8aeb25a24b18f6650d7a4479c851caa068d112b17fc95169888b799434eef0d6220106298dde0ea1faf1c783b528351c0fd4558527e462462de6d615047f190876e75eca6fdb8c831ee0223aa47209a4de17ad5c62d0f703143a415175246de0e5314a2603ca61609e820144c986045ff4958e0226d934167441caf2c2829f2888fd6c249698c183140e665098abd992b3d408ae6d8f682d75b2ab5dd29356c6f8704950c40c3d28755f8b88172c5033602fd20cb7213f6b59f66c2dca0679ace056c97c43d1d0bfde34b3834ae9c2ce08e7e002a04b50415a31c48922550f8ae51d3ce07cabae6299570e0c25c75a0035645eac466482aae4d2e9870f6134ea4bfc9a1dbe69ed53c41f18ce99708ac86a93a65645afb266ce8943542a1614b400ba4bd1204dc8d0daaeee17217525e99a4e1dd77b7828024b7d68c175f395a38428238cc69b397074ec4496e77eded707761474fc7053528e88220be59be98e06a5d3461cab3eb8993d0c2ad7af8b32f8477e013f60751921aec08791ea002be6988e1c70b3b859ba8b217c80fefd8b405b9ed34163296fed2e4d8290820b5ca897e0ab924cb9e96d3021b718027a07147bef735a8c730fce123ba7c0313c419142052bd876d000e0d5a023ffe000d063ffd0720e2bd89dfa5a8bdfbf487056b8f740d27ab0d249c3f07639e0b6b9f16419097c310c67f814e91e1b3aa9313796706018f4b2b8c9817d570c179c020d1b39e8f31e30e4e85d6ad30c3f35347e2b4cb571b80419c00d5c235d7006d213c3e7a5ba3b756029d12c826488542973b80486eeb332580031d48bd4a1c58d1a5509abdf05d688960726d308e3d60841cf7462a5e1a3bec5e43126e6d2669ab5ee0f5db4deba6f20442105f4ceb10b8d4c0579e76e1e6b6892b94f0ee061037c22cbda418712f28a0bb18c227434c193d3eb3b6f920e5064a286627ff1efe179e95b9349acfc3b1b6ca75b4edf1860f0dbc7fa6e2d36e61efed198e9698dccb04c86264f2c151fb711f042a7adf7183e52fac72b7bbb11a0652432242e01bebd515aa1de22a855e12634af6c35f7ba8ec3a6e76d1e36a0a721081ecddd69de1de57bc53fa132afb3e40b51ef21b602ef19fa761a10b31417dc180adb6162bed736847f28168bbd88c62d848114f60261cb0685ec2cc7429225c6eb344eac657725e3a20096eab3e97699d8d502d98e0ae3e1fb82021f40f7b5f66ba17584eaed752e9385f39a2574eac35be5cefea0f0e5715785ef66b843fd92b92d8933409fa56ad8a0cf4b86469a69656c760be3942c7715e525ec415b62509d233ed8065d95ada59c29fa611f4405145d09c1afc938decb337f1ff69d5e32b3737de803bae45089c4a67d8e774b52f36cedcb5a350b03d6056d8a3bee4c6f080e8bcee2428fc7071410af8f48461aa0b0d703d6f81e5651f2734c6dbaa832be8b93edb759b75c2baa515587e85e4226da512c8c985edde1ad80df80a4e2ae06f64f4dd1f6b74294e8dfe7a9d0418e94c563a069171c878f20a229074fff937e8c23caea2eca678628bcb6305c93dc7d13a53509ab9e311e8680d30c7044e9e1b8ce3130d0ee2f8fd17903972cada6b2bc4ce38c71c5b523ad33b2be7081ee5d7e135255ad0df0999c344ed48ff936db3c0dfb456934c1d5a6e29d75b42aa41a31014d27a96478b86c7b61ce57ce96c8c7b7f56c7a51b4d8c12de3757e3d0a0a0a06d035dc7ae85d70568609d41a106bf7c3c39f7625fec5649bb6cf2c5cbeb28a3e4003b1f0f7a52d010a67861e6f0109f15ac6000ee2c9c1829c4d154a2940e904cd47d6d9ef785673d66998b3169e4b3368eeaac2165e14ebaa39e09277420c675afeddc48a9cfc4467598c04b018ac1b495a2a663ff77bef69fe5b26ca4124b79fbaff4a0fb343652ad7a074de3f3087b0a16be118d54077970bda2f65fabbd3b858daa7423cb8cf10931ba772d91f0fef2446f06ef96e956ee10d8bb56719a2bb17fc43881187bc121c5704455e9d69f9ed450096f224b49fa47572db647bf9334e67e02a672e0e95d75b83cfe41e33a0ded5840f7281a979c09fd7b014c120967df5dce2fd9f89ead00cd560edeb9ed7560799316ef8dd834bf1e9b1ca9e07a63d0ff102776da5b4710e64bb58e86c1d770acb5e01f366fc7acf8dbb833c9f5886af5afa05e8b86b7830132bb9a60a8391d4a153952a6a29bc919d4437d68ddfc87fac61b0a0617643bf34a81f1f69f70c7a069d848d7d14dbe8db56c90bac42455a59b760d2be4c51e78e03accdfe6564e7a52baf57e380d42a9fa2ff3690707217c902dcb1b7290e249fe9356e6bf8c7f1b4dfe129cfe06fe2101025086270e0848cab2ac6c157b17422f67b10c35f4085cafe22c321192b13459d9c9a77d6452f3c3e02dfa79f7bfc55576534bc140acf0a9f7ac5f9e1526991340c4c2718951a7e8fd164cc942ad13f8baeb5f3e22ac3543c82a7795154e5f82f947c6b0de6222f91c753e98c58bb70bdf2efb4b9b417a9806a805052cc19887a37fa16b35022fae35612c5ac1491248e822450c600ccab19d66ece94007061f54a9ca2a7583e5ace22f72b7210965267c65ebbe4bc793fd1d8b2601b51aa55bf4330248aed83ec14b4d1ef372be7ffb3a5ec64a092b84d75f20e13c47ffbb4c6e803fab2a8c6be362f641f12d67f2a0259f97269f914de1b9ef3fd6c16e69b61ec74e53e5073fe979530c20e1caf34f103dd9440ec6712141f63d9145a77e4ab5094b9cc0aa7e5828f3b27886197cdc3b9d0d06b2a61cfcc0783d7667568165b3a0e4f0dcfbfabae2f55d6570e18859d5adecc49cdf6ba180bf42a718b0bf454adad5d636e74e4f3a9627a313b2ac638bc1cfc3371241a57d2808df41b8a8ae89ca3706f7e7092f7c7b759433baab573c52657577d38c2bd31e1b0dfa0389febff1a3529b00be3c5385512367345f6b270b267b8fda77d1d381dfe2bbb082f08f09df6bd4be0f8c7127b057b7e75fce9333016d204f3af907062948686d05a70263a55dfbf3ad709334e2b37bf253e3cb4dc0e05c49065615138ac9b9da2d652055fe0e5b88670b440cdb6003dd5109343828cb3f82fc47b2a8b72b635477e4663ade3afe287f6faeaf91bd6947db5c76d494997170cc44a51e211f57426b19813032846ebd672dcbf501a3a3421f0773df0caf7a142e215dc91e600cec48903a9742e6ca038b5aeba21b0715eff7900c0be6a6399412d252d83643b955b0b2821a209c16f7e5aa735b60de1dfd3e0c86d726d16759fbac4ee26b015b69d7ce9f9687b52b1f4aea6d5bef6ad3f3c8e4925ccea84105fe48be87e21e890244495d1c24fe3f8124f27ee093811dd0189890f383252f59221a2ce64b12c204cf63380e05499123d66e01b55320f7ee5e77a1efc5e87a662f6fa9bf476677897d4233f745856b94b6f3d0435f2cb013ebca3feaf33095ccc101479cfd6a6743ce1c7cc0a09e76eac97885d3cb8d14150d3c7f5d248ee17f5020e8f249bb795dfdb1da17c5fdbf9d7bd2a4b1c55f0691fae3f113552e106440d3f1f249bfbd452f9022e396438812f52726d885a7a1b35b5130d3a97554863c01af05c123ea806a11100be798ae28e0a0580d09be36dec2c827f7f74a3fc733c7ea5449750d64be3811eb11662a768a6ddacd2ce29be9c2b493bcf5bbc4c6df254c799546770970893f945e4a779988a751d1128019a7255265676177a0eebcd3e6a133a14ba7d32b566d7bac58d58963d575492b1c9787741f3ce5de6ac1a898791516f44ff1a486edd1340dba825b43b71772afb34258330a38645db3f9f66a939043811bb9e895ffbb781a540ee7ae28125b0226bfe9cfd2e42a7646d727987a329b4ddd53a426218a87a287b4955989d51983c3ece278c98d292b7e584a08205c8116befad7adf8f58b459c666f10b0223ee2c743db325a0c7fa422cc9ae732d932a8978cf479a460f38fd7976978c5cf09f20d815a2c2f53b1ac0233e691b338a4419a61f3959deef6c050709753f543c5838d43157c8efc44747b0055e2d1571a3e67145d8f48aa33c0cb4fdf0bc936a3daf096edd3f818bc13b7d1466df4f2f74f4b2453fb15a8d3ad5a6747c51d5869edce34f57ef9f2de5a2866b6a23d20db2c6364f2f3d66aeef381fa8edf4a84cb36d25a6c0edd6260074c791c69f2268ac82b23614ef157734f7fb58e93b48acf3246f67257cb1abe4c9392d3977a3eef903ee24c14f395aa67469c88c4d43863bd67b9b713b1a46476002059b8dbf2775cc8a533fefc4e56f3992bba84e2dbaaef3ac569739fe1b7c3d578a195297d0526d4c494c8924c69150f4f452829a4cb29be2c8934e84ea1877c9b30fa4a20990cf03c712dd81595a2ea8a831bac924d75deacad4770a57c06a10dffba4312d00f210b00f33d9686a25581f9fa413bda4f6d424f6e5b92cf3af6d23e6cc1a0f2e3d3dc3412d83cdbc227e3b72746956deba61f0e6e07580c10c87b193e484bbb5a3fc40032f1db8c894943673150ce6a9a534006a283e7e26f2f19e17a49011c2bc8719f97d4323e69edf86e76eb924078ff9f4b3b139b310b0301128d443294e61a19fabbb620f4a28e9fae1c8108697a299780a195e89436c8268c6160135eb443f949e57f47126f1356af4543a6c4af1c7d003e09215082a69fe7efd2fd7ebacd73ae29d6ef491765707402c6c596ecda3bb0f507043fbc58f779a4e130740ce21ebed33fb999f74fe43f796ff91fb5cec3b204c0c476419824ee93881504ef7f0241f24ff3d62231cfa16df2064a869a047e5f276a65ac2fb6062a5d2bbc85de6c660522b03395ed248cbbd21d8c8b91927519379ed2c2980ada70da1103e39ade95eebb0bd7b705fc797ac3ff84f7e12d97c4057790e30c4cc816cb644364da881a3aebf7f38721ab97c78617fb03c2bc837a92b82206a86898ec688a19bcc6a6d5002a7dec897b093b040f6c7e1e38314e195670cc68049a5247a5532020554d070f9917d3b0900d3a38dcf434f82a56650c6ec2cb7a05bfc2ab588d8ee6719d50a0ecc3d0595c806442150d4500455b04e563eabf2cc138c27beb47704bce05963aac9b9088edde64cbbdb74c29a50c0a270a2a0ae01d261fe1b1c8dfbabdd7a9ee4f70a4f6bf88695511d3b73753faef54f78524d37f8faa62929ef44c4d1fa97b333c4b3748cf1fbfe8e120919ebd195273945fcc5ce86df47b5e12353e8f7864e2d12ed21654f46644df89284fbed1bd67dd671da33c8655ddf7a25fb80f743b8051f46a1e30c41881762a3fbf62f42f64983fb7dcf9eb96cbccc51c76fd143312973dc6c8404e70fcc7f4971bf1e5d929226c6cb90f5f798e03cd56f19030c68060f115c622b56db267d4fc9cda401e3357e42b56f7b90fc7e1be8366033d6f1007794cfb788ec60a62c226a49dbaaeebba6edb847071b5415304f5cb9745973ef9c3c95f3b4bcb80ccb0811aa8a990a2d6e6265ec02902852549eac2a12e14ae70439dae9e6fb55ea0884424d42de12fd363b6974438ef81601836452b49eb48eded96f018cec9015ac263a4c633639fbd336b0229210973cb6348def257f566ebc5b056968db468323271d133f53c59dd3591d77d1c44aa42a1f99c3547b7204c49bd14ccedd94342fbedb36195f6fdec8f7d5a7647ba1e1ccfe019fcde1126ff2e8c1044828aa124a273ff6da32b3796524a96ee22df6770e5e4b8557ba2db04cc8d42097cea1225956140dcf388ccf045136816ee57254344baefd721e3318ca2622a69968c79e59511703af68567651b2b63d7c6aedebe905fb599d5db36a3369a232d6ed47ba6eeb27647cf6320fd22451fb3b620cc10f552a0929f7d9ca88769edfb4299dadff139e61d0a0de1043d5cb20e7e7f607ede658850c710fd06b97f146a4ece24147ab053a110c771dcf70d822e9f4b8882265b88820d6ebf45567d832e0dc6005285928867dadbe8d5d129c263e8bef4777fa8bf880eadf7d1090f819692ca7de1fa14b13a600d3dd310ac2c43ce318d51d66e89809675cb3894f9cde3d6016d5fbb36daafedc3766d5fbf86ecf26e7581204fed7fe11a62a42e7dd12f0d36b8656ba3332ac4bf93c30c4116edb761a0c3bc34143304b78f5d6e98212865bb24832d1bfc5f09bb674a9cb01ba73d18ccd05f0da3e167d958b800feb1f007bee89757ab478dbfaf650d8b5f8872314b94fc98878830d7c54f787a907491adb74d6b948e82c8aa7677ac7bd336cb32ef6edfac59aa6f9702c75f3c36b38de331994bdb7601093181b50560cdce60b54d30a4f69f584086d496daaf0989df2c8f8940356c57b3fc2573491bccaf5b5d0f6628398bf90d3b27846e535347868adadf02be70218271785884c45f953f472ae9ec6e9e6e65a08a08875e46cac0c070dedb0723c3d12160b2e7be2162883fc2c834c8bf655cc4d6ece311ab1260fd58b297bfaa4859b2df5e561ba72e14e23a44124a1021c3d3334588db50de26251da25f1ac60833fcda9f8865f58e6121055848413de1c48d0c605df00511a2ac5567cce83759753b854f9246d23c512ec82f9a3061c031802d77430936ba9c9e7855745ec37c54836760264c76958055fb452c204398550525af5a63b80d40413ab55640418fdabf456a730b169382975d9d622270bf8070ab7138ba228e9760bdfaa1b76c50db61a082dadf48d8981459c32ec27de838281f76134ebabb0ba50f5b0c61a3a176bba1a67ccc8445f9764fbedd976e4ddfd7d2b7fb6222f76524eb7ced0b6596f01866ed4b7ff6012d2afec6ce504366311376891e503e87dadc86da67a81d86dacf5ca8bd13bed49502dd19fb92feb033f60b1f50f99740b906144a20ac40e5f066bbd94263e8363541908adaff628819ca0ac2f40c104604bed8bec04149622dbe2d9a0d6a289821aa36cabff207e936354d0b54fb99b273c7a21d62762b9ab1739f329376fca7ddd089eadbe9f9d475bfb1cc6758e59f6aa3bb6d3ed36ddbba6d7b53a76f6f8a23d2fbc7a6e5dd988abe5da3697870dd254b96ca06d7c44d5f57235317a69ad6ddc46caa2758e814eaa0e83aca452214dde9449d610d9ebc3b7d4743f34754fb13d5b4cd6a62d5321655df5f1f23de0d193a4d77ca1dd38e9ee81772e593ff49a66ebf7d5fc8937a220f87e8e7c6b04e6d33eccd6c3a4c5dd775a64de93a93c9480d573e05657a2731ea53f9c2763699ba9ae60f4d349c754d6e6c9c60a2ae09bf2f1fa921afe96918bb35f993e9a3e9a277c4fa9bfca9f45f8c0e5979f4fc752ba523b3f4d5741d7d34dd934c1fac9abc09e964f2ae83fdf7631aae7ca68fc59484c7a04e72ecf311fb27aec1efdf89554e230f8793dec43b624f2b2a9f7baef2225ff9462aa79fda752613ddda755dd799481f176119268fa2a54fa1a7b7e12291890e8f41f192f018940f75f2f1ee7abfbf9fbfe9f7c31a28b886c9e93fffd2b349e9c3385ae78f85f4a737d13e86624d7faae9ca7938f6694c5fc8d23b425417a6149aec177ee074fa923773ea3cd3dc6325959e6b28f3db33145c83ebf6dbef5c9109ac8626edcd8cbe8ba7d3e971747f4a4254f7444b262e7d0c05cb3079120d5dc217d564be09ddbe2389d88355189850c261f267a2b5d1996f9fc157f001919ce09bce5eba80fa51fb5ba22f51f7799335b1b234c1e4ef59f8290b7fa896124c9c19825993a1dbd49c3b3838b5dfc6f130fb9932e156b03361c37e87b90bf60952565da43d88c88fccaf71675fd6262ce98847a39da46a3d9d0a63e566a6dc136b36e219f5742afbb20f7d28a5ccbe10a5c30c473ca39e2cfb11cfa80749186d748f114fcfe89e9e31e2192119f574deb176ad4e852939231fc95252fb258f0c524753743ffa96a2323792cabdec24753495cc118ed3dbe8235d0c37190a49132d0129b54a41b82943db111cdb4fba854cbcaa121bcfa9753ae63d6ff49ec97b5908a8bec7344ca571345ddbb22dd39eb5eca3e93efbd026bd7a1425135a1ad220cf0849835b1df1b056581add06c3510f7521f13b1a86b8286bf4118f9423241367fa182581192919f58c804641b307cb4da3ed74eb0849bf348f19a6a8c18c872743e23d1aec55e13015a60c254bb25c3af52e5e1f24d450be58ccaafdcebf1aa9a0a0dbd4445253de45fac886c425e480e813af921f5f30f72565bae9d061869b4e4452fb5932c71e8f91df1f91642d8f91df96e5643831288c40f127fa8890b8ba24afd014304e496ca3e2e3a98d64f7db7460fd8a62ee87fd0ab2e9642d57129f2994d4feedd9a4d878369d06bf5d10a8ae0f4e64375a6b4ff08f74a59cbb34b69d93d0451c4c397d3c674823692974fa08c71aecf7e9b3f21f749b9a53ca25416abf686331a2406698ca8caacdea7acc1b5bdd5f97c79e4e6dcc820167ad50e4e5ab233ad1c70a3658420d9d27f424cebeea54e8413a288803e9a0a0fddaa7c1f67430d7ec192736c82b66c6c93204741143987ce10b17f961cb6975bae73e9c329c214c7597c7745f484a6e4ef96dbbda5d20cc6badb0a447edf7219d72eec13fe20b668f4eed8bba257417ce103574d7907e69171066b83afd2e3b15c6d0a6f2771108d80f48bb891e3a43b7a919ae0fb3ae00126439a3e1cc36fffd98d560ebe35683e0766f6fbfd62233cc90593c9b2db38030334fa78a0024083f2a0f7cc83951a877906db03df687590b0309f7304f83fb217752ce8962960f08fa641e336d0b28293f69f7265ae24227822a4dca9fbe237933a55228e4751d57a2b276271a2ac13995fb14cd85a2831bf829b031dc6a024b4388e71e182d8055f885026a0013003c837de90f555ed08de95efed2317205e379f4fcccbdd6d2b8d7827c9a0b063df9190259b957f742fd83204c4c4c6d791ed5960f47358c722567b0319a15fbb2e256dc0a0d35855b69d3512c58b0f8ca22e559bc10f4020b23e5d70bf298b8c2c0bea47c36b5202b5074a829ff72434df950dae89794ef8fab944ff994cfbe109592f2fcf5a0529ea7a55f529ea3b2c1943fa1a20653527e44510da6fc7a0b48896dc21da119fddc5e1705b15fe844500d471f83a034fb28df71c7d1d2334fe650ce93f96529252e854e04d551fc142a2b0701ed998ebe9073eac7a5289fe570f3512697f241d0ad994909cea9282ff28ad88af2eecda03cf7edfb4dd5e80b0d65ddefe5334a83f236fc85aaa050ae20e5c12e280f0622f443c825e4030d4f1f0d6568f73af5c0adc215431452fb5b68186a42ed67a1a10a898a7e856a3fb45583dc6fcdd6c99a0dc7fe8ed1aec692158572d5569e8e6ddb5ed2d81a7f97ac6c75e39c0ac481702b204c7d4543af06d945ccb9e07933aba5112ad2291e35b2927e72a1d7865e1d89f2884ffaee46d7cc3a43afd0ab53d993be3f04ebd4e8491989f45946b776af8c72ada4f9a4b07b4d1a990221a9bad309b75a18dc8ae3569d8a518a8e018122903824b2e22bc2e211eed52958f7e256a157a7160a2a98a2f6878a744aa676acefac987de835c68f9be23ebecc3e8e7cc58339fa1fa7e72fa33c6a506296f2dd9665a48803a619e94ffae4249e707fb27f12ffe424f4229932d2330de58f4e3eec5ed1062b03e579d4c83a69fcd162e1a0f6471bac8ce6c88a2ba0597a141a461cc420a4afc49af1475c4dff30ae22d72642fca7d32648b0fd13acdabeeb0c30fa6d9cca6c0386810a4ad0a4f9cb91b8ca71b5227d7135bfb8e26214a954d1875c153d6f8cc98b44af859e7718c0c45de7e108c9dad1655100abb6a71122021b56e588c0ff46b5b1ca95bd08b0c806fdb3b9516db1155d71c571abee55c3d00be4be38e330435fc5d50f49e3ca5f58d1b50a43afeed5bd8e1459fd88418cd48e41ea2e6186dd2bc6968812bd9cc86e5c9ce89be884dfb4137cc35c0678d02def33476fae3796d90ea21ef13387f58cfe8cba4e8b1769b095b7d12a1fee6f1f7537e2308fad7c6ec4619cb33d1ce631d80c1de6316f056664c56346b61e69dab1061de654748c8b981fe11c47e231ef711f5792d331f631d3afa5e1b58f744c0f95eff184549d605bb264898ac826f7632bbc42b9aaa8709d0d72ce7442cd565bd090abca2f5581c160b0ce615e39d2c63e1a6c87756f1fe7f00ae5f960869ca3229fa9a8c5ca17d66cf2b59aac8666b784fc084152bb2d6246d922e4fb516e4af4dbefe7ea16f3b6adb8145288f5a4628a422f0a6bb66e752baba675ab532a2ff266543e9efbd56c55f4d2c321fa1da3254b9654510761d187de468b3e141abd8d36791b0de39c57ed671f0e73232e45b71646bf0a8bca77a3ab4aac8ff8d4fe06ea2a3a0604da28bcc0f34aa2e3d33c517841490dfbc7e415c5174a50c3a6a2975b43b8430d45d19ba99931f96ea3bb946b7763e2c8ea7ed727f46452f9d02b33b3cab3e94fdf9968bb4eb45b26930abfcaaaec7aa86e61f181c9dfb5b060c1e27977ec872b2abfd252a4597c6d640e336c9a1dcb62e3aa42bb6e741d0a2b63e5db4302f5d967c312faec59f5df7dffca330a35a17c7fc75ca5c5ffa2fcc97727f4f4758bb64b0713e571a050d17ba3ab0ae943ce7128ac8c7e15eab185d1df82ba4ee9db7318d08c0a587f096b62143dcdcab30d4be833627b9a7d03d426b2ef09223b0c50b76f15ab5e25cb3e11645148fcfd8490a089ff2654ebe9c844907d36adfadf72ac3c8bcfbc23569ebf85360cf5ff2dffead4cab743f4853795c5876fc3b7b7d12cefde0cddd1abfc0d26aae899ee0885be6e69e85950f9dbe2c316dfb1e85b6c1f4df7a16fd17d34db6f4984e26d83fdead4f6296e2339b6e76f415b3e37e2f5f02d1cd603ad89755b6c27e587688dfcd0bea42c3e9ad0ef4bf68ee85e7e2c21d04078137af9852c39e4772f3f107815fd4d0d7d21d71da1a7d99e778468b615965fcae25bd096aff1badf995a46cce2471e0e162c9ec517020d7c21f0ca7f536d740b95b56b4f01a85f8fbf90896e446956bec69fc3a162fa9157c45615fef55468547ef4ece550f9d177eb4100f52b5f285b341aad3cf72c7fe2cdb07c3c57be1aafa32779456c1d7db78946a3bfa9a1ca6f2a4c54144da129bf519ad16fb5e1363a857aa3ad2754d61395251aba1426ab7f489a19a3a7230b2d8055f16b8204da3fc12a2d7bee396f86a3b24e117b46b4964696d51cd86a61b0f0049ad96783821bd508b26f8204d93fc1aaecb36195bf0e87ce036386bd4859f9b778c31a68a4072b7ea4f1935b056068f5df50a80761fc43d0ff05f74e61b687d9603816219c90a8c96c19b8314501992128f3851b0379fcf34c9bc116e58c19abc115ab53f1b90fe3675faf1a6cd68f5ec5af599ca4614dacfb5baf1a64ad5859dc9ac5b27db3f2c86a4dacfb752b1c1c1c1e788ffbf80fd0f3d01d18b00116d37939abe5f25590e300f5f8fcf0c0264afba8bd48fb621a669681d363a26a86200fae61af3ab55a18fd33f4a0a04e7115deea81b3fa11a4ba08f1af7ff44bafe4bb8c6ae05aa6b97377777f2ed8dd3dbef6a1f4d72216a2c899793fd0f7a717a67f7fa4720baed3a9d05b3b279822dc8f38ae841fd5e0a31ee53154cb6ffe853fd4ed6d348f19ed395ab7ddfd8dd66ddb3629a5dcb867dbb6cdb76d0b7da13fc3dcdd99b56ddb16d4a150e80b65b83d95caaf4352f4399012ffd91ee9337f620c6302c533755a31d4ab25717c2020237de64f0c08c51392feaca4c1b9ef312977bf1fe6fa0b4be8f39f06fb678ae985c92f3ff49fd4722dcfc35e9152eec0800d65a8a1b772908632d4d0715850852800d5b07dc28e918accd063dde223ccd063b14eeda7f8754a56981b3d06ac2acbb83ae51a85645f4bbf444f9acccf3f9c0dc508dd0e31b96e655d12ec8a3146eee3968b83b41a7435d8dcf26767efeb3efa4f9ac447cad5a3e10d8a23c9ad8beeee9d4713496622aeeb54fc85877a984e914894c3256a0da9c58ae9597c0fdc73cfd4637c9612c7e7a8f61e0d93a85ee43ccee33c2e935f9844e5dfbef8fc5ee65ae65ce69e7beeb99771fc9e995efbcc2bc27bee2b59e184a31ac751cd145f8b9ce9b98fc6146b32d3bbe87ba0ee19d17dfcf672b07cdb608b8f5fc8e28b0dae7c2aa527914a247752e492ca775a54696979959616f005ea3ffb8e518f329124b7bc67eaebb1fa7ee9b9b5c58ff4f927b9b5a15ef4cc6599473772317a0f2d5ab060d1d2c2c2b2b2a2a28242a5a4a0a09c9c9c4e2653a94422cd391a9998789e48d475a110579dab6c924fa292f4e1565d9abec4e2aff22b2aa4d2478241fadcfd0bb5173dbff45e94c4163feb3e8b9fb9c718a3c6d12cd230f3e73c46777fcfb54f792f13bd96c5177de10d9775a247a1204cbbbb7b394ede7b3ed2a9ad4fa97f7ca4c17e9aee5bd8c806d5303394f1a67b0bb9b53e49a0c0a7f65f4009bf7468bfbf95a5bfac60720fe6f75f97ae065bebde8c47af88966b3fc669b00133e45538f99f5b31098ee2064a604ec2677e3eb1b53c608184d3dd7e21b83438ec77fee8523746f359fbfb63834c636a8bfeadd1fefae317bbdb9fd73bc624cd53c14f482cd260fc64fca51f02f16362098f7116c6fc42fe616bf00f96d1efa2f287a8cadef3c7e777591a1958e7cb1861ce0f652a116fa3f907d76016cbe847a1a78f218f320c8532cbc48433200bc0c1d97d2d16c1bf335a8ccf2a474083ab53c42bacf168dc9745804d0d7db72637ed594a4f7a9682a5f4dde85ad2264fd1cf4a7690a0e3259246b736acf68be94f34d4def4ede598256a1a7933bb914c2413c944229948a48f5ae94da56f87674fc31b1d0d22a0c12296f763d7f3ab7b9e94eb880af1de4633904e71ef1f2a7eeb2f19f73244741fba70e9b234f845ffc3d66818cbe817bda8615ca36345c460ff6d9ffc4851609828368162ebc474b8081fa9c28655ce35b80b2ba3fff58528d47ed4eba580f8ee3191eb02fcb3e18f912c991188ef0e68f9f7f7c380277e1af785bf534d68c3a3b176f281cb635ab52ee2d6afe837d64e89e63af72b915522cafbb27d47b72779a06acf955b157fe10d8c4de321dd84d7e4185bb617a1811a08054d850bbf7a066c07443ec0953fe49791067b36900cc20cf9d540af560df9557bfc253643294519c0909a3daae0384967cfe817edcc184309c4ffc46a1f4cc8eceb9c55cfe88f5fe7744eaf803a26aa4e35445567209a19b4384c26fca53f8815c484c7b00ddc8398f0985555ce0962669e2930a106524661e401919830b9771cdeeec1435d1d29303c303c309c89642a752794eb76cfc2d876db18043aa2c393644382a77b5c93f138a28d259980cbba549f4c74d26d1be4ae4ef1d0643cb75cde8289f1a117d99a5b1cbbb897c13d0cf731380e4757ed6b9f939347a2410834d8edd33dddd3499647c7d238c9b22c3b59185fe884e32c0d961ff6503777d76fde0dd77e4f4c770235e45e09977ad2430dddb53c27bc46b66d63ccf96bb7507b6be86019bdb9cb6374708d7d7f9d9c8a780b1d37e28d97933488d21edb9497de8cbca13265fc7a3332fce473d7c6e01e9f9e243e30bf51197fc24131fe24c6cbf8edbb2ec693626c313cc8637a15b49a1af5da434ebeee24edd33d0ba387746a07c71e4abe10c9ec3dca0bc4102068bf38175f17c9c30cdbe582e5b7ceecc32fe5aa511914090a8109b0b0b020d13d8e8387eeb161d9ff4d0443e5cba0d9cf3bccb05ddd33c56aa5575c4fa716dfb9c807bad57bf8e9fb7da0252bccd3fbf02f2f1fcfd3cbc987f5388a1c6769f8f0dda2458b163d7c7f7261f0875c4f4ed62b7b3850fec4362cfb36372aef9bf09e55937b9a134ffb562d3542f39ea910934f049e8967f23b3d11789f4dabe6ec249dca5e2e0d7fe920bab2f8ed1acde235faa21b09d7e0efff76b878d92f92ce465281b8b1fd09fde1d79bf9817f97e376992a0153690760ea7e344cbf67fa3dca773b95d0f77df766e8bb12ca3f0dbad453c63e643c6aa6bb4cbeb92fa7efef74e29571fa8dc6054f9f51b9e0e97da0a2054fa7d1f6236f665b1a1b3cfdc9e69d4e5f08b23b4b6855981bc9bc1bdfefa7d18d73a9cca7caff62be04e1c3875d0dc7e164f6e1944ba3e3a810ef8286db7320f81d8b5c7cc83d78f2d1b878211e7c8e2a01534f7ebd1c2e3e9a93e71e252a7927bf7d2704e50729101f129e0e180fbe10ff020605b9175488c90b918313c205f7cc3d0bf12c04334b0e7e215e880ec0d450fbef6f2ab783694ede85d3417cebeaeabe0f5fd8525417f442987675eae48170f12e1ea440fc09cdbe8eda8dbc1920803839f15cb80082cabaace4a31fff6c5ef6ec33e9d6d0b13eb84817cd87df3d79cea7410a700f27f181fa6b7473a12170494d85b5ec930d52ca943e0779cc3a059ab443984a7f3d058c7efd857efcd360f3c734fbdb6aa387099aa1bbdce5437639f6ff4c431d55fb18e64f53fe444d3dd0b087dae2e3c135749c9e9e9e30e5bb16754fa7b86da91d339f8b1de3bdf072cffc859c4735976a42519682b24e0f27e914ef56141a2ae1d2496f8633d94cf69927569a69f221ebe8f0dee46b8204a27f8255a28719e998e97d1324f0fe0956799f0dab449b3a6d4a48ce322182dd205601c3a0dbd8ead425c00c183fb8f809ccfab6ed899f7cdcf769347c976af24c26a69169bec9a4fd88be0935fd46bbde6d3717151152ac25d22724f430303030757ecfcfbd4f44fd45dde52ffec27d1080e998a2f623e11ae24692d4969911f9650eeb1e21f1f321ee3a7a92bc13db4de604df74764306fd4e8249ee7efe68826ec6b97fea985367de4c87ea4ee4a166bb61c6f75ef435894d14e9a9c1f6e819f1f3840a7dd1dbabc98cd8b6cc9790eee59075934cd4f8fee2d2398b66e8fc494c98fcdde42ba4d47ed6bcdddf290a858a84602166c3dc28be40458d1d176ad0601ecc83eb8c18560ca7d39c0b7096bf844e040e1cbe7a203cb8af46d6adf1349eb91f1c270252f96bd0b8203f0d2a1764223e8ec5b5b9cb44bb33aee6ca09d2a2b7cfb13816b7e2563fbc66e39ca8bbe443afa5c171619cfc351b29d4bd96d5a9fdd1292ec8ee8b0e2f37506063422f9fc0d298bfabd392e264b060bf4ce7598a5b2d7fa4ac7b7548e064b0a94ef182a4efb8f218997d2191b8ddee15e23694cd160a89a2be431982e55f1e8506f1d29b91decc4aa9e3becb9693d9ddadf11c652208f05c0f223406f01a0ab73cb3d109112f8fd958acd7b6c1361f7fe947cdc9c37dbef96841bcbcf28ce878254747dc277b7c12a7c167d9a3d4a3c1ceba4ffab0c30c25ce560250918f85d14f29a5ddab2bd2c13a235decf3e1fbbecf071f7c40427baf0733e4563d9861e865c3c2af23a4e52202504ec9c2d858bf2d58db82b52d58b59f08caad2847837203a09c0ce55ab0efdf7cfe1f357b80a15073fee6534f384972a1e282f42ebe7311899ef8581a1beb14ca0ff2875f8f11c087a8fac3d71f86f850bafc6e4cea43547571f9182ae32fa44fd1dd971974f76508bafb62a202a0eb26d43714202610bf1d03c49b782e7be2a29377f1fdc98571f221d7399f93de11f3bbdfbe44654e83a83ef94a6fc3c26f73a3f26fc29f55327b9af9dce85bc5d488d1d3f01ba03efb2702df7c7b96fe22f0cfa655f2dd5380f6127c6eb534f6fb479473a45c18fc92965ee2746a7e3bb26ec4fde8b56e13a1d020de09ce5111d9ef7c832da9fc4d6c8d0db632fa399b24ae2f383a1724bd66c5927e5f48bc3248304859c63df727134f833164fa85f4b14a223d00be70925ec647fa189f1674fa4269e2b4977fe18aa1925048ff227d467aee3bf9c275c31c7da40f517436487a8d927ea3a417629354d293bc257dc741d0adde0dd4934e9ea33b38676569a07cf685dda431bea3d977f3b9f9a6ef58d47d38dff4a112bc8af1a69f54095ed5d1e8e773ef7933fd1247f6e814f7fd32a753a5ef46cf7d1783666fa2a5af2bd2bd60def4315ec6871d0c15324d530615b27d8c6dfe9c9fd1eed7cb3e9af9d9fc2cc66731b26c7ef6852c39b28ff131be0e704e3df99b3ab3df917d3423cdbbd1353160bc1002e6057401c40f303e7cf47b8061d1c2b2a2928272723291be10668e4c44ee5191e7799ef7de7b5fc855761d982cc3c970329c0c27c371cd35d75c73cd611cc8811cc8815cca3951a87f18ee4318e79c73ce39e7421ef290873ce421ae8aa8a4a18c05bd7e5a3d00889104cd0b5524e96ef79d2aaa8872e8a1058b16961515540acac969fb82a9449a23134fd4853899c960d7d9d77d30f963344214b2c556b8d88a236c5618893166991553d8b64dca2aa60889985a61854d075de90b6c451cda0a2595995ab186da1faf3081ffc86070c50a321a6c40f28a233b57c44e57bc7c50510d32bd024977bb57a12486c49079335996699a1da8b8420d524ac985ec70e48a39b8bceece92202851094c827a308aa3098c979720a9bb73c590ea2f5af263490baacb9228462213131393d128e8c7922976a4047987cca7874707862373e60ac562b9608240a0ff41f9cc1ec923512a56edeeeeca44aaa99678e1e4ac58ae48a38a7d6238392b56cbe531296a1e1e9ee6e1e9d63269927d4222cb20e9d685880fe5a4113e5863be7be48caf1a0880efd6d210c1cced41219e7f9686f7fc830442ba90a07c9141c8d7caa81cf8954355cee5e7f9b5344c9e9f89a53152f950460d3daa45b77e37940156120ac949245949a4b7b134e647d3f3cb8d71c94d124a657d45e344ce1a5f385134be1035802f94f962644c94a92f9473c6174ed40be0db58006200884598bff44b982f9432626c108c0d7ab141427ca10ca0205e2f2ff0e5e205c4eb879774f942f9f10fe51f17ffb864d4907f6a26e5ec164bb7321f30f391d1230304b547cda9bdaf4abe2af9aae4ab92af4a1fcad854251a3a0c2abfeb4839270ae5ff2158bb2fd14cd3344dd3342dc2b62dc2b608db226c8bb02dc2b60f6554ef4b748b40deef3202c9082423908c403202d593cc5c2ee59c28d4bf8320f7a10c2ef391210304ffb3d74a34a4b148a427692c92c622692c92c622692c7fae9ea8a94449df1c99bc7eeac2e8684fd4786464ac610b82bc03338b212868bfe33823b73d1c5cd77dbff8a26ee6cdec977938b86a51d3bc594bd2c9616eaa7596b7dce52ee32ffd2303241324e33839a1af966857bf60311d9e05ea71f90b90e4a08983caf915c8f2f117988c4d1d14cff7803e3f302fd0f52d146bae5c47f2cc1e94cfff8040cd130403ca3c8ce778cc3ccbda3bef31fb572c56abe572bd5e30e7ddddc5c1c9f11c5fb55caed70b068bc574ea2e4ffd01aabb38383939ab15ab6eb760b1babbbbbcbbbbbbbbb14caa647ca44ccb043d8e4cf55066532dd1adb8409a8a5d1e032483260e2ae757202b73652af681c9d8d441f13cb38fc63e51d52c1c99335728d6b740766da28c86cd7255f378ccbabfe7788cf4177e20981fd0e77b503c3ccd33256a3e0a7c1870fb84689fe754ff4859b52efed1788c01f082e56a6cfe4e661f659422cf1606ff7e2491502defe25c8ceed1b9d09471eb8b0ac3ecde7945c48fc3185a24b0bc2006464043112b6a00c50aea9095606ed46cac4e04aba6a9b42cca0124f1c28f2d7841481674a0729c37b09c088f20faa7c75605151c90ca062ad890873dc06f1a5351e39665191bf250638c318ba5ba3b6d48410de7d360c62d5b1fd8810d5a8859ccb6cc056ab0c2146750e2c3057d831ba8600dab36e8b040e3c2136040838f36c4616b8315394a509082795ac3131b50d7e9685c00031a76da10879d3658a1040515d520a3a153e2030523aeee8e921b34b81cf098ddf86d8cbedb35007450ecedaedce9f16d0f9858d9610c447070852ac061c95aa0dbbaa2a5c15f6335049ae7d5f3a9211099c4ea894c42a0d5a5c183816a084a7569f0609cbac3009571188a2efecaeeae02fa65f6903da3fb25bca95b80b963052950639082e5f7b7c8c9cc4be8b86e84c9224fd564b66daf713b6e7041a66d9aa66932dba488d909954529703166515342286a530bc206318b590683ae6adacece1aaa96c57709d5ddd9f951c387d9bc23749203ddd2154ce1609d22f6aeb8817de1053039cc400d53b040b51c49d460016608d69789b10048ed7f414415452be4f21763818f1a3f5483fe82ee65f620e23b78495ddab9efc685b16959f4fec13df8d19d85ae658354143373bba85347f6338122c6e8ade75f14486aa9ee4e1453545434c2280a1ed3809d27a4608312e401097850c52a6a381b02290842b48a3dd1821630a1053c4148c20f78640c130b55abbb3305253544b905726e5610873ac47640842270210f47a230a9bb73e4453f6a9b1670104f4572b02305978f7912d5dd89021d6a383f8b3ea4ac4249dd1d265051c3ba3b4c50420dfd2669821475778cf4901e63d375747b46e8ed11fdda47b30d6e3637aaeefbd7f7e3e1801ef29f7895f497f84e6ccf086bba72dd3ba0f3d03769c26df0d4606def08ed69368db7c1f8c523b6f6235db793b7dfd0a6466d8fd87e35f694bff771d4a60b307dd4edb51cdbf65d833695f41a0d6f6ceacedf2ec0fc6cb667ecdbcc7782c8e8b7679036d16b948b5455d335f4ffc08d57d3b5fbe28738f766fcb74dd3346ddb36ff8ce30a9a00a46abfda6a7b448bb8aea910ef3d9af32aef978637a14d01bccf8688c9db10e9de7bd14793d1e84726a35167f29d49e7d15535dd2a62cf38d1735b731bb3f670f417f2529bda75ffa117fdc6bde8a3e92db47d84f69b517f7f23e2739fd4ba95d28ee4b9c9edb7a6aba6c5f78f9f875c9ec02676d72cd6348eec3bb7a91db7c1a6357d458763816244be10be8811f18999c104f504eed5dd51821d986a3dbc19778f51ee2c61b5841554144b0eaf5bc39bea1f1ebcf3532abe48147198bc8b4294a372fbc2ac7af7fe8d885b0d218eb3a86da73aff6ea3e1772ddbb6bda853a8d26f618d57ed4bbfde8ccc4aafd954950f6fb41d5e553e21a4b7d1288a6a19d560f63c7d3fd8fdc23f6a31f1fc641cd15086b37adf0c719bdc362d7e30da28cb92d0eedd2dbbc69bd0f1ef403164abbba38432b893eaee288167547747093f3eba538eef3c2abfa55352fb53a7361fd59fc508f9db8fde691892b4444d3494db90ea6ffa2400e93a51cb8c76dabe337dffc777ef087fd3176eff7526a2f666b43f754a7e89fb1265d1defbad73c46244f6a3cf7ef4b168cf6284f7dc7bcfe93801ab72760160d242d37df3931f66bf7da7cd5d0cdd8e197e6d4705be434dfd0b99bfd3e81372ac84373b2043d5baf678f745e6225e30ccfa0b7f8fc8be8fa53fd6f8ed82fbcedf1fcdfe0e1b96c18ca375f1183ffef639bc1bf137187c001b0daec9d2e0ca2db58c493b73abfcec9b6588f840ec947f2c3962ac8e53e56f391847bbb1477070aae4b1638170706a4da986de6b4435b444953c7618a0f6c2d8be46ab1c0fee6bb42392a8f26d7488eee8a1caca0b6393dfee8b7823e41561a3eebe085db430b2cca4f2c7991c9914ddbe8d8e34ee4001a48aa213b667c3d9c0131098c08f121b1ca7654033b47dc8815c49833f3fdce74aa63f8c03716507fafc87e50f10d00f8f8fb9e52c8cde54b0e18452dae031c1e4afe7e7e787470712da0dfb86d3ad4b2872ef85e1ceaabe018fd9dedf57be40d5bf6d63f9cb2bda809ba6699bd6e262af908b8bd57e1e209d0a3598a6539b8adaaf49a1217171ff42fed9cceef29607d9b7d1fcb9cb5b2ed6e420ae56ccd1e8a6bd4dce8daad368468158fcb7bf5105b1f8c7a280ecb54722d33e1b22fef9683c99d6537b3d1d2af731f7716cd5a0a05a557cff50d35955c7a255c51cd760fe12e32f8c300d369d86de8a395104a898a8246d1686490b158d080000007314000028100a060462d16048a80c83e50e14000e8d9c4e76589ac95992831052061920c600000000000082004800568e6e088755c770e14657c13ff4a0073ae804ad08cc879bae7e3fe8463ff460185a1d840d37bafa3ed08b0ee8473bb43a84611b561b761fe8473ff4d1f44c42900df42b7292510d0f16b1400ffdd187323650cc0fcda1f5ccf3e90a9b96f471565f1f01263cc377086ab759b76bf44b503e522982ca3a1fd4f58196a58fe372a051ad0ff632505fede3902dd0b0e28381c59063abcf583fa069284a6024e8119c18560ea837c6ca5646305e2813da80e6fc28aa0304494511ddedb9d8134779b771ee0d5b922dc0029a84e632a2893147a16e598024605b61cea6b6bb0268cac61d609537501dd9cf6a6d37b96e44b331a331586abbdfb7ecf215591aeda2ab173f13ad054dea24e1ef2e1df021bc6534b7210dd219fac9c982ca0573e99e183212fa1f46f753055bba051bd7431a9caa353ac6407c197a74af07e5fa94e62406db379cf3749cd2b05d7f0b3c80c7dd2faf8633e63046fda9066f0da8029b08929971b7c9dcf7c251c229d82e64160b7c4c7057aa4de32400edbb91dec055b26d004e3031c0d6a06f4b50b07580bb373a8158c73e966211cbb18b6dac632df1fb1a305700c9512b80bb609af6e1667bb3138e5d6c633316b11ebbd8c73a9662133722d5e5e4959c464c7d39b9327ef611ad929c2f968217fd50e21ef8a2a2fe3ebd9ef28be9abb1977db53cbee3923e2fe81d46288587f6a82b3beb6052921aec6ad7ec80aa38e6d4ac868d0c87ce638793c2f1fbb02be5bdc552c0ceb02e3bfa82e2811e9ec06fac2f08b57bc255716b19978fff53d298e34185c2fa3273a9b09571bce243427822bb4470d6f9ce481720150164fe6b0a0b1e2a24d7db35e6e1a58d94746b7a7936a1bff65c13f3d9bdc6b3d1af1a7588aa29fd8a9735639bd70fa95f433f4ff6db38eb6c31227e5fa2de71e7c9837d2a63737daf521d4a90f78e5edcb38144ded8ace78f2c3cbd70ba5a66a94b050b569f2016b60790e58f6d0529a527bc796d6518b8bda285dd6997ca5a8f7d663400b56cee8726f8a46e382f9b31ba7ff7ced87ddc9f317591364c32953a4b9a88ad20d4245c28d5bdb8fa8d032cd62821dd85a9bb4421bc9283379d3f87a4cfe1ee7c6d34246b455ce841cb42c0ceff23f97389eee6d048a850fe2c758d1f9a74bb5189484c6ce778063f9710e77b2b1cfa0982f65caca67b7f699f0369670a5a31267284a2c0470bf7e2dd53b27a75430a6f5f08c3b9fff54141df21717ecdf7bcaa507315e4f4b553d7d0ee8872bb1c618e62ea691f3c6515a087c3d062e8b318ccf07adde7ee61ec4d4c7c9d749d21008fa19fb7c423a1d2b984f49abe2f8a6511a8d34a7168f5eee5d120a7c5c9465565cd5957399d5dc2674891603fb28a02c72ee08bd9708d84b6cd4e959ddf76d306679376ed9d3638ddcdae0cb2a46b32ed049e894962d751cd06377edac9d8e08e35b04f6cb0f78a97d33486849d2eff79faebf2e993f9d334b68bb835ff24ae0826cabcca4e6e6d067d04f509bd54d41ca4f6d34cb56c9a261c5b9a555d92a6fab14793bd5adb20b01c7a6d7799370be0ea0504faafdcf3fb77aa4e1cfaa007e297b51c27dd4aab235b4af203d7f626611a496e968be8b6fba5c9c52241bb82092ad27645b10d2db6a34ee4ac4f0c1aa00f5d4321aec991d7e9de28f3655d332bd5bf266c0d11d346415892869f4e6a543391941e67479c0eda0d943c44f51c932720406451a61d8220b9b7776198ea7b2f8d8cd4ad61e5eebbfd0443a60533f5f4b4fcb4402c7a435dcf9be1fe9ae29c31bcfc9107304a41a8d7c9e069c0bacba778bde0d33664fb8ce9124cb533f0d0314c2d77cb862147957a2f5b12a08432aeec60769d0e6d0880d9a597cee60c88928d00f706297f3158cdf61e1038342fd66c76beb8261903f241b11d7e6cb402fc733e8f11f9bec05a9d737d9e3a5760da51bb973bdb86a0dfe93bb45924cf6666b7e3bf401a9411b3aeb8371bb8d3fe7c3a0e1219c2cbaa8151f1203702fde9c5d4ca9e375bf308b87a6d2d30b2c3a09db946952cc68f2edfc5d79fcc1d4762fd82c5343dfc5e97049e9c18df67a39a9ca22ca7c76d713e020eaf0d2d2b57d6a2a21770e2bcb6fccf1f912dd9e594cafe85e7fb29e1b02d8a43c4151c1008aece24d9a58e12994da206827b33ebefee3eb1e8b1bc697d0d166427d0ba606e8b24085ce78dd6116219186d80c6601489d99b58381136a8733d1073402027aaa703266091bbda8a6d7b0fb4009f219beb07c101ee551c6beb4b82abf4d075b9cace24ea600555c106305181b2c6710a007795595b4aa840d582af703052cb280be49554c0462a39a451a30400c63a4932ecf209aad509ceeefb319de86395b88681621fcdf8dcc134b7c9686083b8c682533ad5ea1d9ae02bdef3e7ad38aeb8db70e19c6e98f1a50e6c8bdd95764196c8ea00c617b7ab4688d7c7d6ff6b5b0076e068f1af690a5f50f2372dcad7a5ecc37445532ed58f9a4583117b691665637471f2a041d9c2209db62bde78b46b164d6edbc5a6dac8fb103a6187262cec959e9baf06376501642eedb17fc6068c9eadf85e466cd6e5a0444fccca5b84ad3a5fd43ce384820649074816c187f95c57aac91bbed46e32bbb1b2f6bb472eb1a4d0e289e6871d7ef081f2a42ddb8dd43014b8e79ff676a4f346fdeb173762402684da01cf43dc5752b8c479c1acea6ead8407d08b6bfbf41a5846ea5ff84d3fe940cb4983411392db091a0869cd3ab5b6f6878b01a743c32bd0d5acb7494eadce3e4e5f35168297809ef854a38ae0f254ef156ac9db1c857677c9aaea04308a5e8720eec9f9c6ae26062bbed110656d5b664f543cb1a9fa90331337bb8187bc60447b9252cc2a3aaed167cdca057f21a62a107c88ffbf7183e0824cd889c827bbe58761365ea431a42462333add2f21fd9cd662941f8792a6e8f934e954e7b0bdcbe88d048531806bf99da927008b29e95e9dda5cea4018802300dd0d99e84e773d8e4def750a4aef96dd8dd91d6cc6d9575389d14b2ea7c5a3dc26b0cf5e5b37985fb2af3c058e2388f97bfda4437d410dc379978e60260e5197a721acb0a1d2c038663e015073f3c2a882b4d1b0d5a4c0522fd0d63702a6c9922c58edfbd9fa901e9c81124efa626b477d3d2aa7cbe11327921992bb72d7fe1a3726e3e960db8628e9dd4f80dcab24fae2b132c0f39be80f8d646809b49d72609595ece0765807cd93332f15ebfc0890a2de617c84c0e2565fe035c380ab33c3eac2d42795906a7001d89b14a364945b973de22ed8c70ae03087b000d9372260d1b6f2bcff900061ad872abbb9f4e45d93a24ba1f2c780f9e361842571a70fb04018031f8714a7d2c4ab4eb1de2d41cbc24f0d13f19e5b9d85f8eab2d3d72f0486144f0b2cab6e37d60c91c83a143a168e49fcd1a40efb6d454918aad83b27404d50e82c73eaa96170988480364b8d250d9a2d98215f28c0eb0638fda0f2b94291c5c33d84aa371417906341afd33e8c752a17cf31f3fb4c9c2b176d79a559a3791871a81e7b4cda48eb3420fa6fb06787aaecffb9b49cea94faffc30290641a6e77bb28db6c0169a3df703bbb35f00bdcbb59d40272d529b46498d3d9896fd5e0d90fbf6b5bd24930acc28737a87cc0484d5a2b796b46eda2606067b43cde10b0b0bf6a4d8ddce3b475083620870b71fc1358669d2030037bfd2a277ae08ab725d89614392ee80d99b0dfa2bbbd33929a3bcb5e957e1eb4560085f48df6d18424ed4c2b5e00da4f5edc4a967bd2d2c562ed02d2d22b00dd7dc789faacfb59c4246ddc2d144e3046bcf5cd04b3a2b7ecc06ce8de9c6c692f8fd9aa70ca29a070661ffcec86f4ed297863b01f22496fa5bfe9e25bededcd9af2fb7bfb038bceb63f0169697e6cb98a31364fba4b79deb6bb3f04a3e6a921990bb8e4c3526bb8ec57abb45cbb19a81849ed41d750afc516aad76bd750ea7d9942f692f13fe69a52f55fd5d484c3607374074bb4ca0aded33799821897752d34db34b8848a56089c6c364a5e7f0a3c99172f1b0581796c6b3b19e218e5d12681b6c031c7288e59f2d06cbf0a5da1bf9d166f58c22615a26f1b18a091d3f20c9285a679c84338de3ff2549bc572dcb9f35ee374889288cb8712f6d036ddf6c0b14fe55144d1a8251e71c5858308522cc9cfcd0fcf62fda287b7d4b11be8b0b0b66a9f2a905b4b124dc097859ef1d5af78902f85067d251496f65b7b4135d8838a5ab339047cd2fd6ca8d34977b5c4581eba5eccce82e4da0dfa3918d49a6cb91bbf53c7de85496fdb1974e4d8a61462bc814c2b4e076859f7da546cc0ccfcb26b00ee431ea190f31873b1f0512475a27a41637e046d01ad3471c3d5631ccb48efcf0433e91fdefacf9ca8b0f5ce809961437a7ac6dbed2741c92811d08abc703e43f623b66e4e4109cb3fce36178a2dc733947b0a3b4e82d40a8732ff813565ccbb1ff6662892d5bfb35757048e0fbe6a007c51f79b75d99bfb6a2db86ae89627c6e7da72d7cd62d413ff6328d4745176e2dc9caad35c3b70ec183269db23f88ee3c0cf0801ba7d699a0398708b550df4e633fcbc68b738d84f19fe5545dff0f2d25cef833a074532357d86730b3dbbcc3e2ce30320d4a7ed6c9f02815644b1de5258c63cc74f7ccae81200b18f6661d276f33e5e85821baa46a4bceb9287764453a3ec7470dc4217f7689c7ca940d8535a261fabfddab2bd1b7a852e59d70bfd3c64c2b6368ce1aa061de567d548578b6587e451c230c885d8619113717b69f0ca80650af170a3295ac05ed0ea478ab7e1e6c480e264e9934d991bc3b841316ec937940f37b2394943c13ceb87a86803088e4dbbfefd33bab70feb28b1651e819261cf7dd64f9add4fc95986c580f1df1ddc94080d8126d243f0331df21fcfc510a1c67cc1d96ecee7a8098a9565359d6083f2646d04b72a1c9ea054ae3ec8d9aa95609231b837bb87c032d140666243d3fecb78f803aadef2706532b883b76153a78efacefdb446804e686c7f563765b50eb1adafff18c66151c052eaa037b5a73be411bdac4f5734876f79989c0bfc7c99d7af1418b5e0c3e69f8753d50c7cae0ddbe5a468e146272cec972ede849a4651323480385f8cfc9ab90879591d66916ff9622243c22f0800b4ff5fbd2539add41d25a6e8753021685f0ed9eb751b065726691c6f21d563d0e9e1dacf36b1e74777cf076fd7884b22508cdb979466463869162c1c7e7f0e4fed93930558cc23a25ead84b3142517d54a50a3ea58884038d8452d2e6935bb8948f0703896c478f9678e1aa618638b4ee5ea47e827c665001bf33ce4d7580a239a3777439b383c326d8605dcc5056376649bda1851ba5eaccef7d94820b440233ef3844ef4428803b4486c0920feb32847011d50d7a5c39294592ce10679b6c61da0314b7300ad0a37b57198e1115c984f178e35a9228fe00257bcbd40e3a00ee47e11351d67664c026d4f68ce6af37a8e1eae3d8d2f105502849d9022ac20e878e9ccde48697a7060a9927a61eda7a0dd8d354069d5801734db39130c877dacd6275049b7a1d3c089ea06355f106b1ebb131b1adcae9b9d0484e3745c1ff63f852f1192d1215fd1a85ad65b9f8d2b4c894a55ca33cbf898481b8b3179d8564ec2aaf8ce304a680b4a6c0fddb80a13859e820208217085a4668b5e0c5c5cd9759df37103fcbe3604d848d4048f31b416215711511b3d556bb20087d51d6161951e44c2374bbf244ef1af54716603d142f763115d52e8c616729b08e8841eff22437a8b86ee71a57617d5a13382cfc40dfaed5cfa3da3e4ada2d98430d50d1adddd38de220b35da2b515af6fcdcbb998570b292b6dea91f2bf2c2cc921d66f6506d939470577ba1380c372159226f0851f78e9dba0a1b714499ecb7828c222640334d9a5cc6e2964577991b060388729d61a17bf3c13132e2d935c559519f6ffb24e9a4bb81705ad18b59958fc05c29308f3452c5a2ab12f2115cdb3074beb3684956ccd6425aab024cb998f7889848bc11606486676742142a7033db388b72c24a4e6dc7e14d84482438e36fa17d282aa2dacfe9efa88eb45b059fdbe8f148767932aa9d1b68402aeedd56b97720d05df71a93cb02a66af461a491f93210f4f0fab9b8e5a4aba89c2be2c2f5bf765942ef02f8d9246f40b9cbe1f1cced89c476ac621d6b0a1d3fc5592af1d403b3aa040764681387528d7b200eb90c6b3f9b59ceff632dbd31b0bc22fed6d0bd6369736055c9392ad8b897ac4763f354a206cf22ff98a2480ff55286b762db24076b76e2bb081d07b303624e12d328e908ca4ea6273b9cb065496c1ab2b47e1c4642e04be02b5ab1f5187fa0de9a2164bd72736b2fad06a0e84532c400fc1fca8e8b9379efef43823d06f1b547cc6ae2be00bb747ef784fa85a7ba11a1b5641128d7981a4ef87dc18604d6a9ad90dbaf468293638595c87a6ddcd40e5f74e7e703c15ea905a65fcfdcdd70a982fdbbf87b292f2232050f03da9aa7a8e2b39ea0fa878fd8a37ed3d5c74d0e7b528ea1be39e7b16602636300745004176d82b8a9a1b8f5fa84fc2e5e23ee2afda27739f100f399ba8e467aef4df952c5bc2fff51a4bde1d30f666a112cc64e23e2e6c3408c56ef8f404ba12d5ea4f6d99043bf706f47bf351b1f3e8beaeda55c59ff47278765221425e9ca0d292a5d3406886864247c14792451845e6df883328987adfc354cdd787de4e825d0523ee6c700e61860a4ebcbbb737faac355116da7318c31ded1b17e3bc46b583eee41c37bfbdb12741c64c5cdcf5e442266fdbaeab9127447bd8d4e83f73955faad80e0e2249129259c6c39141e5ba89adef08dfe2ae454eb9526457e6bc04291519d4f33eaf92831305da3e8d6350739c7c59ccad1258ff25f75b2e1f51f3aba693d52105a95f2e005993c05de56e05b3d129e8ad8fbbecf9174750ec85084a20f1fc040dadc6f2d88f45e54050cbf8ad2a19873af941311382d5859efdc0a04d1a14b1a54c7db2c4d9a7a5ed3299c2c0a57b513fd42164c988007a94d51fd9f1af4c74339fc7f9c3587a429608559978400525b030af2ad3a0ef9688bbbb7131bfe7b1a42882e9ef0838f23b59666ad2a26d3579cab99ca51aacd0549837e25d318a8e5248880218f517a6526fb8cbc61a4b3acce85c72047f63e94e9a1e7f95a65436ec0e4d744c7580fb2ee0312ef81233ac0aaa08acef3f989daf771e9d66b41065ab28350cac1689bdc12668b1e816804d5cca033c29f8c1132aace9e48b153d93918f4f1a2e5777c1611dfd63638fa5b2070dc8f0296c7831ed8fc6c53da265d21091e65f9bf688adec48e44ccdb6e0d028b29faa032674b841c64601519e2a7a8788d5acb724e53af6e3e1ccc95172fdb174ce45fabb6d580061e15015241d579c19650dccf10768b7a8b48cadffe7546d3248d29c3aebe5de45ac2966025c6cd65cefe9692456ab73b604165ce21d895cdec9e77e78afe6b314aa6a384e6b4e6354b1ca97d7e940f31c5a797694747eef40d8f5191cb718de5762d5d8c3032d414a17e749b06fa73708319fe3b300e728e632f824a1a4053345d2d2011e1d1e6d059babad5dcf80f2bf0072cfb67fe039707c0404ef95509091b6cfedfe81a5a9ab29e22a9c8458b26a5ae088408c0e03bfdc5f255fdab8149e5b960ed14d07733e9f722c5d5323cdec391a08830ba56ef679241b4d70f207952f79e075b4c3cbc38da59ce7b530e83a3e7011279ae3a3a3f02d302911361a3f820bfd6bf33865a5487f36e6c4742884e7903211963f54d22b6e3faf321f742b1eca988ff9dbade870b26e45940516a145fd53bb5a4d017daa0de7e1217e282b686896c57e175aefc0514320ee1ebdea0fe3bce192dbbed86a4f6011b216549fb9757818830f91b902c24bb2ea4615003db4033070e328112d2dd6101e9624900d25f0012f94f5cfb8fd1d841fb17664cefa383712702467b5487a23b4be64e0c92c95f0659e4aff30e3cc5c94ce3c829e4696671460784e54db42414328bae5105d4798a0fd803da1b1feb2d22c475299732b4a96d540af55c12393fab93d14943997970064b99114b6aa3b818a5e1f2eb3f7d092c3bc660b60177c7dfd0b93bc3c08569c235f591bbde00b7a62120a6b88cba4f9a2fb5169976c0ebd2818aa145051473430bca06329bf4deea80d9984a297695940b413f85f6799f2fb9508d315f92805eded9bd50b9bcd37a86532fb06df8cc6563cc98d95e047bfd4fbefcd1ee42caefe87d66cdf015459b99485fb64e1d783c82867229b41ed9101430bca8de7083a2dbb5765f2b1d647d2be4cb5b8062435543c37ba3c334d5354e2cde528925a1468da455f10f30b5e5b9ce7196c3f69c3142b620966446780e55aa183d58f7c29dec675030bef701d1a080e83789ce56034707e89746d4136330cf6fc87ef618d8c2babc7e9bd61a57c68c5c8bed205b98f4304250fd780cf88d2f2f49764648036db75af4aaf1fdf185ce5c40c018eae21e1f2a22380fa3539a136cce52c7f8013df902b7530f3d7206288e749560838f2fe8710a29ba05664fcdce43231ce33b8c458bee7b1c0fcec4056f60ebdd300be01212864a15b9f9d11812261bedb016c4e88ba2a0dcc696277fee834e3128412d7092d4f451d5ccc658acce85868afe5cb779a9b8510a07b1304ee20d6bfd149eb9cc44d289a53041424c33e755e4ac6b5da995d0f0d0337dd759f921471d7afd35cdc8c6a54b6c35179331aebd20c96417b4b3c052c5a9b5abc2b2d4824d45123af553a7447903bcf57819d88a6ec2c412f0552f2ec8af430c3b215d2da0efc750d3f6ca4387e43cdbc6a857ebccfbad377fe1055ac379f35766e855fda08bdb73fd79744d523c1630f372c5ba949340766d187c931cbc237f66bdeb4df862024fb54c8fabd66e21283e5f056328c59173a93c5a2eb919a810aa4c19b23602fe25f29ef04b4937f94884049ac77754e3d775bcfbe6abea8313945dfc4f0bf24c7f2f844a36275cdb9e7134e8c2bededb86e763ae59751e3691949880b12553f5e7efdea38222b370ac5a10c3c43930899f9fc24e29c39311085f0ee32ab8e9066d09db63f168b150155eaafbab4b7773e063d53d87b733d8789743835da93d1a1edb73618e78b234a125757026a87366c3180b3c416711520b6bff889a3c143600623a579c55f82895a4ba1969c4e91d9949cf4a6538cf92b48230f8f15e1aa73430d3327084d957e4025dcc92dd630c4a4d7e6094ea381518f54a945eb6eddac51d5f7fa882e58e2d964f1eaead9a01029ea91a9cb0333134e85336b858e263e0ede836f6dec65a1f6744f1c1756bcf4c5806f7a9828391523ad5679da07b192b526c86ac353e5b69b0727b9f68a49e02260be821ea54ab39fd86c3785b8abf52ebdb8a28011cf380db46c838074f37e0c5c8dd803b214359fb1c5658b68ae5fb4872ab1b1c0e3c433403bd0b0691af5a076488bb78374d345a9e8d96a1992c7a586b6f7b55a8c38a93ac5818f3412c4f75906f1de2088ab640b761ae2380b4c2ca499d7a8c6bc54412fa2e9dfd5dc7b3b9f99e5f5a22c6c89ceb01c64ae6d6c1d1f21a98edc8cc2d608a4bc353f83588f05d41010bad80d807f4c366b46a03c96727c47115294290dcbb97dc0a8b9b682d02a61e2b67bb51a68b1e686c18b83e616dd3dc6234f943ec9725fb7b0d0b8452390fc9daf3f8c69dca6fd6525919e35d086cfe8dd759712de5a22f20aae3177d2101f6c6046ac519c15c52af17a093b810959081d3959d50389083c14899c5ec424804cb5e785bb0056a13772dee8dc5abf513efa617c1cfe68030ec9660669ce80d2860c3442103b23c840a0bd5c2db673018770828d478ffa93c8505c17bfd1e5ac76e0431bf453f45efe950b945a64f795c6cacc3ad562db4f0dce6f406af419d140073e8a5964f4de9a41a1e1e654aa7335feaec3f2c0632484b425c8e0adaed76cad040bb1aa3dd283708e44fa40522410c02e329b1da6529ff90d9f0fea3f9799d1f7c420f3cc2939f3470bc00372ba6f40c4322b0165566f7c6e8d6f0c2a6fd4ac9a41697a01e86b53eab8a655470c2a8ca1b2b58acba02d3b3cdc2f71e861d52ca8076abce1d5b4e0b1bb5c49a97ec06e3eda940e5c808cd1b040c06ea6f3f47ef920861544fac9cfdd53ec32a5414398f885b6504e0fea94927ec703813bda8f9fa558866992d7db51d4721d1585d6fdcc0f4633bded5149044fee5d648e489534a82ff02acff00a3c62ef3b9b2a58f217a9ed4a28821d05e7c087a7f04f3eb48230b419d576ac6d441b87d2a540ae952577ad46295d7fdedacf99c1bf5736e30fb724afb4826faf3eed90cf98ecf5537acf79843cfd1232b08566ce300a968be49e2902545c2a177035e12806f6c9b2c1740277d3b7da8ab06bdd93c5ff5b437441743af767bd36197f8704a65a85c928ba188eb68a141fde761a3f065546050e5dcf4be0f864fc5687922fc398e377a7ede5b67f9b89579eccabcb1c369d462d24b48986a1554679e9ea6a7cb510b1368519f6eda0099d12c7ce7e11dcab42cd5bff0a0500eada9e632c6ae16ee25eb341139614d17663c47121e495cecb4be0c6e041a4ddb2b099ee6f3d95a612194ac8ba1270d7f205b8d4810c6150a8b61c31d2caa356df9b0d65509c678ff87943d03d6163e8a7c112e28f2a7d4ea2ace6395e4fb8a0f06e705c3da868481b1fa4cdbaf6d51c582d17b6792eb4f059ae49de8536a8988f742616661d8c8a980f989c60a25621f5592f38bf07fc5f943ac6f3feb306e685f62395ed4fa0eb998cbc883e7bc28ccb82bed2bdf3341693f77d109d46e9a160557d7a7274b10a55fb1d6ffa5dffbcec27ceb1ab3681069770abbda13790097babc5f061099286d62fb4bc8fbb550143939b6fdde9999ebb1438892937fc82de40210de6fda659e0462153a84d55d659ebfd9a9d1fd1ca160734b8bb9b6e52e19715699ba96b4726ed48766fd9b93e4543a309b0fbd1d1f15ebbf1003698b295c2a27275a75c0c651d690922f94a266c92d5b1ffaf13f7a5a2f02998b2c3ea28373cf8d7b5b7554135ef8668ca11a3b1f3358ca44150f8816fc9ca1742f2d2227f054726ac3f6a1890af8088b7f5107029a1ad3db18a5a992f9378cce091db3ddb176828a3e74b4a63d6536687f22e9d7d79241eed62360b85c4913eac15fa9da13ba8bdf1eb51caa6f05604f7e57594915bd497bf26d504e5280fa5eebe983adde0b82e7f61f8b65175dc8dfc386b1d12b5e4c57eb119ee8d5b8bd481531f4b13599ce30f8d229a66bca80cf87e5408578a685eace648913d349c310a70b96aba171bb632c0c4821e717c88b54a9223fa8edb27f735a92c0f57c13981681806d4ef7c5b9ffee6d86d6c6b48bca074452b8a6b54d71930c3fdb6577eeca451efcf90aa012d5d2c78f0343256b12703696915e471eac8ace31c81140ecf2656643b34e7bbd2047804809cd38cb7f04b94d7524ad5f31196faddd18c81006cb363d579d6e5e0affb80569aa35afb282cabfd9147924531bc9946226a992307eb698d3e08c558d994ab4c1a3b42eca5b56aa1b4e3fbfa05ed9854661cfd514470a5f1decca4e08af4670bca005015d3b26f39d3e6e560926a3f88c2b9787fff4ed257623d9351eafbaeacf391ed29515354c02710b5fc13177921570f9da86e261ec0df420ae578e87ab82967c6c6e2b84ccba7c8256cf0cc481637c11f3be461992a3f8b368fe505af3592ed72d8b103dac293b3dad55790d2be899bbb489676b9fa53c3831d4befaad532079cf84e1328b188a56308402e8fdea2eb00dae232f268690f2340e433abbfb5a9dcb3ce0b80d98150055973ebee170e306e4f0a27040601ac0780aef7384f206047ba1fb439d95095aa9804f2820d88b30927edd27f284df3b0238f684a0ee191a25f190cf94a28c62be36e3dc4982adb1538a42ddf44160b78d3e6b5f18536e43e38dd6b850e817a6df0af577d814ddedaae2712900fc035c4331773527c8a06b6eb093da97a4dcdf71e999fe98bbc156e640e12382da73818a0a9bf0ffe884a60440f9f1b925aea9604a8f618d01018b0f5af4ae38df0e0c20f3c621bf4b451cec6eddf86d59162df389f936a2b1dc108b58ed4f7782c2d91982f346cbbc259d0b30bef3b5fac0f9becf383c0d0811ecfe47d1ff0ca463e61f8ca278e097258479318c117e9d2632a87669241f4dfe028b53d129bde0aa1d171f42b374afb8070ee37763afd75321db8b2ec9839080647429a873115fe99b5f8c200956d02813f0e5a252e10248991c1f7df7a8daa681d60852786a30f609d431689072965309a7e1edbf7c6e7d6cf33097a68f33c0452034745cca42a8a586fbcb95db2907e943aba3e0bba3db3df8b5d88ee84cf128aecee9ea513551f6528533f42c3e8b85efd31882ef1c05be68e1dd7b4c5cf49755fbbaac34700e4eaf3001c873210ebe25c5bbf7c9eb58ec458b84c762ef6ff0e1fa1de06de94c3f756a721318d8a79b57083906348b06739efa1e54145375a2c785017e2e4b1984710d84d26761e40a36ac7703a2747ae1f0023d5f6c85dccae1010c420d94cbb9f8c85dfc4f35c240019bb8b486b59615239e5d533408ddf483200625f2392dfa37cc9567acbeafe78c2f2c0dd5806db22de220ac6c8891de36589a4da6dce2bdf2f8cb12ed7c84f40a48023d69dd8c04b9605f6265edf9559541054fe10ad3e5ec7b5ff242f1dfd8b23aa649413a11a78c19bf02814cf2ca52772dbf91c43bd017630fc50808dfc16452e54fb390bf22bb3cfd78a19ab23daf74304eb4b162cb6952b0b003b0202a64c95873204d134afc50acc3644805551c2ee06fd6f5b36c7b3ead4a927f1435ce06b81870e3b54a485871e38b9d3a331b5f56094e52e98f9cf728679f5342bdb30c827f04f5f19b3e431daf2728507340b759f13ffa1ab4533518447c48f0184c2b2ca6a5076caf6364c972184e46109a453da927c7a0ef02e189c22aadf75032b19e5c8cad7aa638229955e9acd9f2d1da07f82cad3a96912fbcb76f800bb6db3cbd795b10de21a2629a03143b268e7036192bd8c2dc3de47d5cf4b0560d191e2b9856f7f9b4dc110dc0d726d63bad29453ccf0a6818f5b0e906a5632b479bac1533626fe9785c0c97f043659c1d0abaa26e532bdbcb09ae52275961444e58701a3b2b06335460000d3cf0d46eabe1c9707c05e7cb0a8c1c31ca6e65f575a3cf09293e9f5fac619ef094680bfe39660c1a8152001b7e33d272456ee02bcd18f687cf4ab1605f2f3603a7bdf1591ba81128d6585538373627cf239bb800a633bead3c1e1fcf5bde9140849a32a8fc2c7a53a858478de2cd083e3ccf386f56d08221485fb8a8361463b9b9682e2214a48d5a692c134d3eebd9d22f2e9567dcb991ebd13bd6a3587e6ece605ffd2c86b1875656e3afe4daead0231cfc733831aa29fd9844448567549c17772c220fc9599c2b379387a6573ca5e9dfc4c5e728b0f08255a24539ed71c556ee0d418f7c04ae98afd043949195ef65b75d2f854c761f6a9e72a51d9d6c2b52c013832c65bf0fdf575b1c4c50eadb004acc40f81bbddb701b235845f66db8811c8569435880e06407c612322c61946015afb1438d40251dac18c2a68293a05cce08bebf167c6c6b5604193e57a8e3644f4452a363cb14f9de4ff430c05bacee9eca85b48b98b234e84ae5b1a6f1d29c8ac98ca5cc280ff5eeb98da06bd06d20d2e8e687f216cb544ea9c7499edbc65df403a61df06fe2c1650fdaffcfd830964930e0b7dc6cdd81f1e873a517abc7bb76471f6ddcb48f16040bf9988eb57511ebe1713255870e7f704e1f53bd6905aad5f2d8484542f539e421b6074f8d7091c5a3b5e59be5908b307ad072f45aa2925f7a17d38f8cd3dad6487de34c9119b45d973c2581b67d01006de37eb5f2fd465c69a331831eb61b697bd58245557f294770a0a2fefbdeada1a344655e528809be88996824cedbaae5862be86518c8d01074c9e0c1a35165c625f8d634dc617fa3819ef45e59d7086f56ff4088d2bf10144a67246d710cb9982217da001e8eb76886dfdc522293a30edeef84f21e5aed98e825c1ec0ffee17e026525fc847bdf4936fb3ea5c21c8b1c1381a7bafe10be9c7c179da728b09fbf0cee431510aa8521cea86cb59f8cc0bf6a27d9b88350d947ac673ab525c3215dea5dc57ba41e423f454acb2b21f45a4356acd677f9c6e05961aa9b90856cc1670c6490930484725e757ee232d88ceb4064526ad08b6e51969adb41abcf4a5a6866eb48e4327406649135ff40e315cf05d7888c457b47d33223834e10a4393419e0f8677dbf9b8a04cb489b09954c3112e77337f02f223ab3d38e6f6d242f51533b4d07b085e9b73880858fead254b0bb971884b75b804590984f311cbdf575554c37f5aa6f70694d6bee2d58944341e6c580f4217dbb896cafb306412309f466fb0a5adc5d07cef6f8f0b49110c44689be7f15fd656ff9c13c88682cc3c90677567c0d96ae43da313d6e88f1230f48417536602fbd5d5840aa4ec9d5e181745aa8fcc0ccafed144f084c116538ca0e584054e451a6129231519295caf9d77ea75a6bf4842ae83d166fae9b2e1b2f6c31da40aba440e14d0ffe3c69f3795eb4716f575c0a3a10f7e4d14fe5333d2d8bff8d5377cbfca91e556b7c87f92638c57484e1f5f190d40844467e730d45c929d484fe91b4063ea84c41f14f3d7921704e6427111db9e94a72673cd9613882b995e26ece8855e9bfff947de8d3eda46bca40bb5ea97d9153dc18d1fbb4a3f04521879bc3052ba1e1fba1bd0082d8dfe40ff2ec5af3fd1af9d6e59bc5aea1996cf4e2aed378e1552d6c08c78e35cf78f628e6aa967c19ce90d7e4e92c2716b84111f94a59a51b72ecb61baa1ee8603bef73a6e29c021c1df1416a30b06de21db8fa4385947d820a13eebbd3313e17e6eb94005a5054d745279234fbd2a821ce06188b3aa0debe6a8f6e9aecd18bea1b139d9999e6773479efbbe0a706a74d0fafaafdcb6255bc75236a14f84f3965304f5f41d2f9ae655287d98520cd81bc15ad3632ec618d1589b0b7d88b604981b6398412e18ac1116702b0299b828ef8fe3dd690555f0970bede5505b11f5ada8cddee1680e6de4bc1aacccdde596c250ef920ab4da033f374eece595fac3a3ac570ac759e3e25e484838306e64852ca4ab35b442094d9abe2ecd30cffc9092ef35f6b519a61ec9a2927b9c8fc810b73ee29bfd6259f7f49afa437c2d011607e6efec9beb064394951f427239922c51882ca24055cca0d5d86e4e9bba1c90da07a228a4c58f6504d1bc4e5f6fc972adcf58484a56ca4aed82dc0656f0a2b1b71af44dc083c070854d179f9cf7682b66ba1444358d66af69617408256b34fea3ebb80c6560b83a1a562f20e56c8ac5600ba2fd5bbd327a218a5fb595fb5f1780c5ed2a8ca6de6682c02d815ffc2a3c1d4e037b5e0bd826f0a738ec73d8118a65b20278a8a402b958717c59413ef50f5186bc7567b7bbde01e4c193323d5a36efc9726583668be2d16d630f253335c7b175269dc6a38a6341e25b2880cf2517baa70f29968beca59364a4d31c6e5776448818d5bcf0ed117f7ac7f9d7b201269d3db3b13b5938b4133460e9d0d559bda55040743bc1d9e96ef702227c7c8ab04c7cef653397819e1dd16096f5e4995ffc271b008bc962c82425778b0d10134765fbbab7d2650ab24dc6f6a2baf34bd1258da20673fef25c8fb6c590476ed9fba6eb1ba0d63f66ec8c6a4be27a8e615b5f43f92df8e085ed419d783436759d22c2e33cb43464295f0e3a2ce222219220a501e1f9f40c7f43306a874cf65cc408d80cac81353c18826659d9f608176c934b39400c42f2c743283937fd2afcb2b0f1f16759397500a0930a366d63021783cb61d8893256dcd817513214d3930171d442c100a8e9a786aac5e0d73ee17eb33bf425113beaf2469a7b58f2a2441cc75a5e6a1c24488d2f7a1758a87ef4ec10a3fb8e3d8091913e662ab9626197ff75f8ae1bd9602e15297ec5876443aa4118b3cf2fd54562b26734aa0626343db7a31a0fd5a70f12f6a133715644e854c26ad8876e76d27617a445c5f73433e9c7dfcb9cf5de5186c4260f5ae6bf4d0e55a2472d0e698c0b210aae59e02cdd188a2c28a878e7f40b731215a13ea0440464fc12f5ece994a85251c6638b487c05f72a6d843d6ec050f86a7a008c74c5b1377a99ba76f154535dc79b301bd28b50777aa9e123c8c98b72754fc9eb02e783b072625ee0b85853c5ea665af611c3109c18fbb51b7099c1941b48997e8d1c2600823696b42d2a62ac293f7c2534771bb4c4af8c5d3ef11b62288722a181c5971c86a5526f00190bb2100a12939edf931ac320a22eff6ed6905d233cc9bab8120f88e07aebdcb8108c6fd64b88f2cc2139f4d626c863a45b47473c62a812b635613e23b0d4e397563ebe982163d041ccadd9a96260d8cc71a8427ae5404fb957ceaf60d49e54a4138d4de98fcaea5e34d59b4e8a309ff3fcfd5082e6b9c38dd3cbe69a3af6fd801fc703306d47285419b6b84742649f88d6106467ec009db859ea3a0e196712268704c965180ed16abe8c282858096c60a321142ec4fa98509b058ecd6d392e5eca014959ef43960cd6fbfef8a003840195e7d8c980a9ff796abf42fe6e0694a64087e4ba07fa750d85a06559864f05b200f55137b07990e8cdf728245460df910d956ae8bc761f9a4a5891e7500858026e737aad2d9df0adece760b47308feec1d063dd7f225e6a1b157aa4a164c75ee46c4d5103d5edf8967eddec803cee1e9050a985d198284203d599d6c08ed769f4152ba2172bea3f90ec5397745615138b7db9165aae246989fa96b6d5cc22c96f4ab21d601954e0be6665b26f968ebf15487af8e097078371bb77bc6a5eb85629a9faac54c827db9c08080e2bbb458c7a15fc897b20fda617852e4c4458128c773f4659f7bd3086429767ca21db170cab0c1ed6fa0b4304c45811c0214f092e81c148a05fd32256204deeead705d01d33b855bb55b2789b259f9120a25d5ba24522da8dd9cc30e205c6d67c75b42cbb4c0009b501cdd3fdc07caf47679c56e85e90efbfc83855aec35432357644a71b1ba3752dad190ec70490e4d0e2c5f3cc2217c75dbb11026610e08413da7a0b445c9f983f9c531f5f92c873a1fad4225e95fd60829438e74318c380d70f60db35a35fe88cfd8b4bf0e66381ba594ab62a558e5b53cf290053a746e55b0f5563d22c355626b90186b98a0a56d242395256be2eec2ea9c0e7221b732f29e006f0eda50491dbb43637906416e0f06a107c8d12e9bae13d18cc27ccb86500b1334160532a44169c6823331c5c565606c4512b4270a7dd79fef2f90c688a4d6eb633a729a0b69d2bf2a523db5c0a8b6777fdd73a96d6510c98b32ad1c292e85645c077f9436f7ddc9bb8861b6f5003ee87abbd5a310b33302edb08ef7218f85641678816e3a590f4aae490194ddf0f8f619ecf8122cc6fa5bfe74569f2ab7b99bc8870518395641f0637b741147756f3a1f4ae1124ed80a4369862d0682509e70906f81015545f131c42a9f6f790d4aab1ad7c314b2a653c7b0b4c3ad9441d300e709c219cae0ea279e765f7e6fe53760886644a42ea6d262b66aebd72bf634cf55ff05f155183cb538558a6f7bb76e7fac1fec63e9f9ba7a555e6544f04790b937145c372d40b1da1d289d43dae39d105f31934260d70a9cc02c4e79dda85b764f09feb4bb084916eaa7118d3b0d0adce12745e6afc920adaad8ac0c36d2d6759f75e9daa6e5b71bb05a033dd39a4c401141d129c18964a2a71f96cc2006f5af952389a2c6fb61d2a12a7af4e7f1d26c6677ea83f9c704e2e14fe5bfdc227cf2024367d671bbbbb53f9b449fe520eb5b7ff474ad36014d229c84313b92fa07d8f4e11b3a08cb0bb3e257d45f92a280cced0b10578f7a5da52247b4f1f73cc8c2ebb4b1b7deb3495509d13a0b0199bcc195e7d6ba2d6e4bed616c80bf6db6e0c10d51f2cbee8274c8a8ea383853107c1339cc61e148b0ae9821ec9af491f7d735641bcd34a51356dbf5b284a74535f80b74c70f5369fe2eb25f61b63d521bf612067616a8f1ed0449f27ed3f67f4706f0f9164d5f99a24ec0515f37fce4d2fe9359d1e70cd3bdeb1a804586bf1962c7cf43d5603b6b05ab8e78e2239ab7b240c7525bc37d4f4a67244faa24c34e0939d2e24c7c93da2489600d752464ab7c3f94347455f99080c1b7704b1deaaaaebd0035659b4bd2d86ace3c5627ac2bd0e41abde10c153bc265c5b214a27a931cf15c51b46155a28d5368b5c839ca43244551d17e9543d969a02e7ac567029561ccbf4afd63ebd1d78f975d274330110b11251f5772db6d39328b430050b6b9e38c4ffb2767b57c62c19c6c75ed55af04262b649fa54f2d90de9587aabaee5a2499da7e51b72ec04a2937989f3955c17664ae4a5b11fec0cd630da31f5098ee9e26fa3b268e01c687b9220114330892518cbca1f882bf21446b74c6c4985174f6e67076720f7b3ac20402e63b53fd1288e65bfdcd627b36c6db89c6d3b836ee478b2055d2174acf0b80c16950eebd2e19468f33284c209226235f45a9231a1ad235e18f53231b1254295ee57f3c1e47bd577b186f2a4cd549f182c888457c6d4e8faaa9f03b3357349465781e2389d348bcf635369004ce8fc29e407c44b4494132a143d46be998d1fdd181ecbd09d49386dd39ac91dd6cf0ab554958233155c58ca9482fc2124b3a191fac72f84ce438bb58c3c6688b2c31099343f1f9b7b0a1680687b5e857354bc26f81ba37be97f0c90e7c9a8499cc70be1e2562c043a81cbc4eed83ca685ded0582d43d442a48eaa9dc1eabfde5da270a59fba734d4830a1a2447c2c2f218f9aa59111a0450c94a442bf6bef4ee4dd913ead52cd294fed29b14bd342d5ba7106d45e68a246728813fcf09d476ac909ff2d25dc94b8cdeb28f3eed24a8e3cefca13d4bce0cad34dab528a14aa3562a3fad5c42b9db2c9faddaac5d83ea9a407ec5dce32df8637b16b47855055c209a2c48c909822501e59a7ba37296e574cc7b72c452005c97fae5fa112fb295e6975103f330b768250bc94b546ff8d6ecbb1fc7946d78637e68a045c87ca6ebf56bc3d294dc8655bcbdcabbb3c15ce3af59770c126c4d2f6a320281758429bfb7640ec4dd9c58ec82f2710ac0a588c2cd97fdd5f142fe0e4589e7ddf1b44e8635d925293cc9bdcb6531e564126a92854635780efce80d9086d653899b1bd79ce0ebd4f55f452451b853a083d9d4d2ccce6135980c535cf4f4d769495eb1087ba4029ca86bf5744defbd03340b4fa9cc3b49f04bb70a3323a1d424838f3a45e7049b1a6c92acad11f9ad6161c9f9d4e2dfa8d60a004f5a582fddcca96e11cc1717241f4d3dd385a9738f409a117a517e80cb3b5da42bfb562b5440bbf815e41a8f2257c91bacf2ed7a390cfa1ccd2bad9be370e24a2507d091dc95be4534521f865c2b3cb9f95457dbf87a016d7f94af3b2679d75e725de599c75a99dd5c316713a12db7d96e17677a3a07a3089a800905c2572df574aa745514422548477de7bedc1d70f3361f56e9d1e498d96e615f9436c8ba503bd1e4592c4f76025855e62069c24cdb8ea3d9d78203540e6d08d2315c02a084b4ae918106532f19582cd9236d5d453dcc27fb3e99ddfc36a0526857cf1e3e4544b6cc9e4d9b958d996ff0a55e93089d10d10024be6ce1cccbb435ef519f22d776047ee0c177f7f4748c010cb81f49212be00e14cc02d23a8dc5bec195543c175c9cb35c4e60a913d0b82304aa7a3df4e9ea1bf190e6bb9f47a93af2146200399307f38e4bcd877d9c748799d63a5a9b2647c81e660b84d9196d0e8bdb33b52b2dc5ca6ac400c1a656b895efba11206ac0995b02be0e26547fb6b10d8c7e999d8add44f604a282a617d8400e902326f68337a929a31655ab4193b773b50d00f25848158ca9a1b51c89c365c79cd345a4e7aa45000428902504c7ec9126d0e8099b982cc4525ac1848073517712344f0580119da23c4ebea02d063b87ebd58c5ef66c98ff6a84acb2386b180e6ce52e4564bd879c61969a6b22179a5af467f9e760e004ba6cc99e98fb73cb19f7a3f384c6b681e2f5d7e28fe0c748447b79e16f0f8e85b03a71d8e2d6f49d4c41c5c9e8d892e4c717696e6122fef8d152edd0e19b391201d10436490ad1795232f982ab5a21c776d9a22b5416fa065db4b580e5d51efbd1def3917df657f4495eb3a5741d645ed625d3127a80a05c72802cd58f332765773e40e66ab4c6e8bc472604a4eae8e964dd4c14ab814638bec117aaa820d0e6a6cfe96d2ae9bc32477b0d6ed2777a4fa40dabf01fb9030982ed15de2027d7e177b47c2c486fac0fa40c560c6f9eae08de2708f4db36ee76da373802229eafc679bf3abd3cd497aa0d5a978d75ceb3b91dee17fcdf54e3700c9b7371cfeba0f4e6f80c03bae90517cca84770cc5569748f218b420589faae200f264e0a0c2c6f0959d3c6684d02517a7a269ff5a022a43857db413fe162f0b438d7e06279247bcbe456df6931fb186df537049cfbffee3b21f78f11d57fac05f57226bff1025c417ee560a8ebecb73ae4b8dbfd07226d731c3a8da00eb19ca53357a5a79b097d70f5ff46342072a86b5d6d01cb8f4e42c8c269fd0390675160842293180ad58c25bf8d3465cf188c5ccef3cab16736e7e8673430239567371ad5804c2ed4adf533f690cdd71291910c067aa5a7db1b7c4b8549389b9494a2bf5cf3923899c91cb4c484ef9789c2469b32b286383970fc6a674d82a22d86b111af149393169b8fb403d7b8dc8c187fd9046c0418c28828be81923aae5170acd8096e4bbd2d3b06505a2618a4495302ab82ccab71d647c9cd2f61051b64a6ad5ca1db0de5cefbd31472ba2f2c6ee62f0374d954b7fb0f737b5d0133fbb06cd18cf31c521ac371f48a51d131424ff7d94d25c1daeb938156a3d93b01b0ea0684ec8981cd532d390330e1eb59574b672249ae7d5ba5f43e7a534c42f9d9823d1b65c782af9086f14e59093ff073eed652227d513de07afed845d979ba5829b6ddd27b2e5625645d2c3dfdc5f25930bea10f2e5d2dc46e5e68159d49f1c9cfefe1e93f783fee7261f902952278d0c0c773844bbd127883f8580674d28609ab36eee906e3a36a095641d91c2ff1a9a68d260a4ec2632c3747d139564b31552e98f3e4749dbea429bd7c185edb8840844fbb7405a2b2dea712328a9fc08f57e3c8bc57b66ac4b6be3029de82e6ae8e9a7ad2f0b38e7e946dea6d9b77818cd67e492d469a54a88cb960c65853adfc72d3e6eae9e27bc48d86879965706b4a54781abee8703cb63f32e03fe31e161df27a7ede5d22c98e78bdb4292a223df7ff7315da44c353ecdd09359ae70d1e30568817d491f59ab447f46a846878dc4ffbd0edab8108301cd9407896aac1054948290d5b170c2fe885f93bf2f5ad421579ee08c8751fd06451970325d4ba67905e6a533d4decbe681152efcc0770b0b86085a1fac6d18e2c2229aba5b7d91cd60f97b4f3084fff7ea3af596eaa5281ef43447bdf64434169fe4603af25d3cd3f84ab242c211c218c102eac21e86c25075275f9b8c9e4b513fac09fc1f67d8d0519743c7c09c37334c4baf072053c836e66f00d0ae3139d74b12bd9b153a0cf4c84e89de15dbaa1ebfc491506d7dcd32575ec3821fcebcbc1957af8960b284f2f1ce147abb7a381c5b6ff47897f37fb1853dd9ed7ec8f8b070288a6cf081c83266954b7e0739b6727e3939ceb03b799a88d02a68349cab16ed622b7b1473804f3322b48e6c6c472bb25e8b4f0c4120992cbe720eeb47ca1840fcab4f61c0cec61c338fd7817074c5a48780406baaf7d4fbabeb4c30079bf76028b41d681e830b58c0abd7c179f23fe6919326e7835a197fcbfe470db305f951d1d8864cd9d8c5e43f683d05d9da67fcf271feb3723092d7439e6b0bbabb7474449e2b95330e2af17d072a1104133e66e0ec6f232e0c64a464c61998949108dd8188bca0db5ae30e9ca7bbe0f6773183f38307885442372c56c0c93ed65cf77cbd18197ae8a3fddd98b7fcc0188ba30e1cd97ff3b7101a0de780fb1f1bb005f04bc504423d4464adaa164a2f62012cdfd39722959eebdda7d0d33c6431b1bac172d4f625e29ced489ec84b857b0076205ce3cb5ab21e5bb75bb7e940fd8f147ecc9b072481bbefc0bf08f8a54dd560e7cc82f9d6511f2e3497c37d058ca91b815bd5e1837cfecf101604bb24ac13d0587eab5e4b015991e6d70247ee6060322fd3616496e10efd58b80b1386d68e57e25b95c8130dc9a8ac8003aa5fb4daef14f934bf252e07f7622af94472b2d1b10798d13671078c8128ef7d997919262c6050b8545c790e104a83b643357b380a9dc67a13cc80e087d9d6bacf2e246ecf2c4d79c178b59764ff5a25ed8e1be2ed577588d1d3baadabe51db85f55c3664133c8f274739f97a3e1b36bd934b922b3e0312037a9b8e25f4dcb1481183ba79cb8e75491f72fa73b7c04300ad02732a8405ce46b2e4d89cbb5b9958e928a39d63115fe2b32ca458d6bdc69b8d9323e677390355fd3e254bdcaea9dc89d5afc7a5a05f27c9a5ad49c7dd0046dfc4c332e8f46cf2762316c36856c1474ed53866314abc1b379ba16d9e8d5739614fafab4ae4af3f1603eaa10a2d07fc7dc77b86235996e95fd5e443bc89994c63a11e078252cbc7906ba984f19d94b0fb6c4a2617959634bdb714bf1ba74a1896c301b4881014edf623f418d1e66b79240645ddb2feb09dbe052a646b1ad9288c2b239eae0b590ef49a833fc4f15fac454212fa93d0c575e4b7dac00da3cdfb2b366e8f1252ff9c03b05d7ecacc326546d6b26a5409f1e14dbce08fd9ccfb3a1754f37e78864b05ea4acda03151d936a331d0829c41a63e9fd6d8299cffc4d955d08a2d12b0ae117cbf6a38a9c2554998aa2c854289098c665d4786b79561d17abb459442377e41df048cd4a4b27cc6968296979fdb6d55ff9fe377eef00b3b0d1a201513f8c205d80a84fcc852fa8a694ee99080815e690f2d3959f13e15a4a007828e11cb94b43ac9b428cc8ac1210850cd3c70b88361b42ca5f628b7b75e6402398e26fa488c2555d7d7a279a6bb21dd9b1b71ebddf92906e5778908bf6f47fdf7703ebd35590d0bb71ec72036b9384085454ef98bdf514ed940259ee8634651de76f61455a054c67b0705c50562a1ed1eb8419571845264daa1e69459452e0e1a3e5c8a0580d466f0baa7726dbe2d2a1a3e1b3a2fefda4e13a2a6e9453d2e385fb80dd1ef5cb1c197e8c58cc35b0340a6b2fdcd60bb3002b9f90635ce0ee649b12757d210eb4f08da1e45ef203c6d24b75293a2eda89c37f812cf08ad388aa70b0a6d00e26a5672687061abd72f3c9a275a9c50b44eba3a6837bf2cc17b3d696e16521bf1c6f53faa3ab5c33a1cf9cc9cf5170cda80063cc7ebb305cddf4bf497caa7942d6c0374da6f37265244c54eec9742429a3d84fe528aafea7e9bd78297ac6d0cc402025d41af8d7d677c956a08ea624eff4d766e63964020e1a2824103ff397407864d03016355a6f054e1d02db8e37ca07d2c4805e8d60b70882f03526320b8c5dbb4513aa557e258fd00ec9e9fea694c82fce51dc83c834121bd41b485d30c57f8dfab4255111b81d50bbbcfbc9710f9ea4f9b7dcbfaad1010c9cc82a1d85cbf00e4e9a661dbcf6fb93966032fca0147f4c0ad4d2fecf35569de8bca5c90188dfb1b033f6bad82457b4305e688b2e80013e231ac6d7107c4e382883e7322f28257410d94a78663de0671dd4693eeda808754f0cfeaef21a0d26219cefbe8ebd2975210d18323950d31e3cf3500b5504425de19ce7711378047028c13815b62b39035d5517155a7bba4364d6e89877b58b14cc0ce9902be3c36377ec2b14b7159c9bc459074238a655ed08a0cfe6cd6b9d1f8ab7ff838312870d5e1e7a01b4b34e972916ee48cc51980e3ef092b3cc008b3d94dc307e65a237d2bbfd1798e0bb010ca3395b67fb46c356c22ddcc14aa390df3d508ae655daedde87b59b3ba6cee42b939bc00126816912d13d730a1608b2848953f05967246c3a2637cea76b78593b5a1b88109797c87b73c279be82f2e584d439b890a1ed61e7f6a4ce30638c024fcd76cfb0a5a42a6fb8ccf11061bcbfefd04aa313165abcef8c3fcca9f19e154e1d66947e2b07f8f2b78ed75d5e7c2543a89a519bcf6f71167f292742b64dfa95f2b4a968bb45b3c96df13f3bc1bf10ffb26e1a6a885d69f3628969ee444d25a98f2f1507b25caa146cdd8c27f027af50d9d37527ee48cfbfd4f958da91624a3d218e677cb3ee16f238cb399e2c00a9a17461b25e88580ebecef484bfaf8a11f5ac922f1eaef70f34fc105e47a56b9fac8933131c8e3f0f4cef7b175806377045b44f4bda3cb481ced02986a81607a626b45192eb28dcfe5b466dfc2be2ba56be4c7c63eeecd6f9caaa6d312cb64c2486846ef549521d9cac999dca60b3161e9e46fd572555e6ff49d2973507f48448652d7b40d008980dde15e8a07102d591db3fd04330e0de44a966bdfcfdd7331f20841fccce01e9698326cf2a3380e62fa9951df2b800b57e4eec9d3d94a0d1ea18dc319e27f20f172b05c3e6fbf7519756cc5640ab05564ceab2401e0f1a10559088ef1f3f922139a29c314924fdb194c75441914164f1eb00aa6098b31b087ec8e8edf50e25e3b12717b3e79f6a78bc73a88243c4dc6296b80294e8be43acff6846919640e0dad59d3192f10024433fde05a534a2276b0fa8a20e33c57d8596c9da3e125d66e03dd1f4840eda18bde40c0a50a73563e7c2c9732974d3135e74378b7650998f455e4f18121672eb097bef4a257c01b78cdf4ee194d0135e37886420fc15f9242240c33b8e2f5383f8fe9d98907c941b8577a034c4b06552c3eb0949eb8498fd2fddaf9a783df7a79a15ceb800bb3f2dc426e63707045151982938f85ced9862d8e0bb9aea7030f6ef7a429856266c78022a9d3a8164f07a4547eaa87ecaa408ab4da4536cbd5e99ac9e70491391a027f4d5bd835fcb0a5eab9ff01dfafeb75bd189d884dd6fd96f274f500e3759c6d67d85a437762ca46d0f932af39c06742f79479345f83df3f28d55b0fe66d5d16a099937e25b6e3e2fbab69be6ecdd8d51fb8b79d2615a797507b7b14518a271a027c0c3438c28b2e88cf570aa40c1ec4a990f894d7903f9776f18ac582699798a26143cc1139fec9d0e397740bef54f8888c77aaf1c00933b74ed022201f8131e3b64e2543ded9fd0a54dec48281b14d828379968377eb9847d60c1fd09d75ce1599b6a793c2742c83e949378f24ee44e18d9f3391141fea35c8993ef24c7c4c83dce1911f21fe5489c5c27b92746ee798e4506df25b4568185608bdf094eada5321ee19450a6334e7172c838f427a40a6a142397f8828c20fe84d8028e0184d37f420fb0d0efa066646c2a6769e8d5ab3c0e9c71920a3ab0a0df2f9ba85751bdc7c0521dd3a6fc7fc24352e424e5e7c4e1459ffe84afe7dbd51e2931982297b98902855cc72525290194f185e618ab2cfa708c6f1e6e8f320527c9ed45c02ca010f2b561b022d9181112f2d49e12d6f31f153541e556d33019c316b5d3ff3a2d96044cdf7bc31b62f0605ce81424f90caef3e72a9c07a72f1372be0242068600e7cca2c325bcb1a84f70f633e666ee7fe3653da97e4300a573cd19f553d5cc82668179697e426eab2d191ce7d8906323eb090cffd46f44a07fc1f757c30c1a20f5746a9e67a444831d244dc2b0eeae95ccf9d0f4067e00ed165e5d3a3b4825fcc579572141fff07446d0282828e33bb74b3d082a94ef6a50e2b7c4ef0718a70573be464d4775df6b799b326f65531add8da70c7352329d0c9a9b6bf70aea2e6064ec309a7903b18820f6712987c751d9bf927ece9b6b09767172160ff67353449a5513bf3cd68061515941c6f80db6f6f2ea5f64cedd110f9260b6297f21bfe3fb48ef8b5e3c0723f7db0abeb00fe4afbdc3c0891605bd864efcda20a261915296d23a970cafa0e73161d67a5f38239308e6b0f6aec65b47563204f2f15046f29692196c2dc55a6fe6f91a7ee3add7cfaf44dd91a8c18f2a7f697d1c3bc9da9b36a0641bd68ef40dae63837801ed57f6bd840c007269035dfa7b4151671ea0161c9c149623c275ded8688643c672c79a01b146ccb500cae5f29767dd06b02d1b89b1a0189fb40bffef132446df94f74d4ce1e2c4da0b09bf189dfdec0c03550f55832b39d72c141064b00408ce23126f9a482cd5eec20d0569b4078884df4b8a6e6a31ecb9a00a14205fa2a9b6a1aa27899fa6cb9b813a25c707729baabaa2b1218c62a69fe13005708873e1472b80b920f15dc99254c8a5223e2d97af60aa903a21b39ddd07db0fe542bf8374b0d4c3d90be188e58858082534f8d9638c2099be2045bcee455aa6b361e6142f5fd64f941fa5e8560e1ade7329b647817e4ac6743f21e41e480a8e5cfefac6d978208f77341274e37b9bb58f7dadbf77293b7a84f2ba9d31cb4fe91900c598dd272a1cf014029115e9971589ff64c0aa8e6a805971a22b2de57fcad6f4ba68efd0f87f58566676fd0434366a7fdcc2e9a0b7245688a84484c53cf1f84fb1297567cfb9e7640ba35d989f4572f061c5b0381c63705ac81305c446f3c8e3c0d88d64b886161090d7b844ffa448465b5f942785d67f4213db42aa09638444ae1be913562baa2013db17a1f1e80c433d8deb67f73844371e24210ab07604a617414a43eb53f92655d68112510d93c44ba765085a571be3cae0d3f62c216876d148411ff2ca5d6ecf77b83c3c595d9e3d740725f1fad52920b40d49d5c020a285e4d1e1b8473d7ac27e5e20c92551f1634c2ee95d6892b31d4de8f61ae8653ae26aecf25e444aaea25e812a8c20dd39b9f5fe5629e9ef14afce4653d5f2faecfac828b01246bb672144ef0523cf696bf62062d7c7781007dc8dc6d464eaa0b52770ba2f84916237e0b825bc00f19995de0f42066705074b66b1ff08a3999e552cc09d2d290048e4211e9fb137255da0f4b2412c758f5dab9cd50a0eb6dc65fa1cda515a1baabb2e756022183a183ccd7dd541bad36b8ba819c4caeefdc6284a9ab1d3044a76f3d98de219442d76af74e9c7f7adac09d8a799eeed3ce730663dbfded80b196da09cddaa9af8cf19e2363121c12f7c0b9fd5d2d13624f684ea5ff36c973ad52839cc6ad311d28be0d70378f92527c2215ac1020c6134ba8044cd0ee6bdf3c4a43e39ef79904983e4f7829f64aeca8c9b95b294a3549fecf00afb8d013a4e0854a0005f6f010bfd1c942ea4e3cea5213e591ef69e28f483509065bca3488d590613445090a19a0093fc18aaa36367fb8d2cc3b574a8a53ea7dacf9f2648958cfa841077f405264c92478ad595623518fbc8d11c92d8190c4746d47968c7518417463436a218e2c72b3d2a73ed814fcb624c8c088dbb76e0b254bef2c8bec133b27292b4fc03705ddce0ccc8a0a598d6526346346f524786dd40828553d3fd7463c896faf29e57f1a0872d66622f41f8bda955d0ee1623ff62f1357016a56d051556425de4a4e764c8e72e64a7eb1de720921daa4d5ea77798dfcf487608b5f4ef18c8eca610b3fd6861e1ee019925f6cfbef530e2275838c36168bee796f1c40299eb877e4b5f0d6575e9dadcd6481e69220c59f5f9192d7fc369c799fcad4bd79b841b10f5359f63dea3dd38fc6941145c476c4dff9a230ab58e0c7d9c1ee4371cd3409f1a2061b7e3b77967adec5b8c347e8d5441dc29f766011bb9996e43fa8773a71c428dbc89fec266eb7afb80abfb15f3449f9e29873c374e5b7a4a1e2e1c1fd69da8825ef23557e213857d995408f64917981e98c01afefffd52accf58b1ee01e05f0256dc17f8d5b56d2dda98cbaace6d0a903006e901ef8c5650e3c44a588ed1443f92a2c5800d1d65fe656f9668a4fa3a585e1cdb074efed4d0995ff1f47e1192dc32ed3007cf1685d1eaa9fd3083530a0710993a537fbf206e3f3a5ea1699ce7864298e0c652b8db3222f3787f26d334a76f6aaed0576ad1d6376eb4e77d3d1f2ca8e9c4c31e8a08ca006310944f53fe7884434dceabd3ef052db6b783559e68bbdbb979233b8ec3a8143f35f779884b90531a9e94475aadc7aea80427868c52e718d454746e102a691b145d6b62cde4c6e52ff62f5d81385b49f4590870d514dcf70970e8276c31c3f05a62b1dcb5b649e2abc6392f39b4828cb79357912f93a7764d37a88881b1b9a09c04064db438c0cdca40e8239ba09666a194edf93323c571930c4877be803befbc83cfde4db38bb693355c806a6fa18c54db6c62c45c296fd91958750eac00857cb2168fea665c38e6d1ed80fbddb586a72011e171b143bd0baddda7ae1669d1d741f51616ea3c2347efaf8a24d2d08494017bda37421aec0da7544625f43a7bc4c3d294c1a80e0640430088228d786430778ff43246c4d94aed8a00471d4549174ea3ddb7be00d6ceda1853399113541c9ee96805404dc418680f8a7c8b9cd6a66c179f2e0cb895034b64868b7432432e9ba907a053af5b44cf7b3584d6f3b4746979b70b13141235ae865f52b4c574d4f29fa3db6731e7781d3eb48d7acda13091c63397d143f58c8d8aa7b5fe5dcbc95101812dba5aab1cdf0ff173a1e684b75b4dd6933f9855f0e72ba74ac897598c3cf3fcb058466fd0fa83fd57c45625c4fbd1e3d83eda4730f56d8b20f95aff8581c25c1532ab5047d4db0688b95b60521b95f6050b42e8de3e3f97fdabb23342c98eb15a05b2faa0312551e2f98638183c21a72c63d90e333aaf3fcd2291291710f44175a098eada1d09a8fe62c9bce955810250988b7ac5b8947ba2af53bc9b2f2b83fd9b45e5e4a74dd86a07f090e524250ff34a1bd01756f5ea9869f7e38860061555f211e7fff5b661b9d3e8565b1b4a7ee73d44f31bbc504689ef76829d65214ba12f38df195f37658d7728f6e31fad114c78cd6b0fce83b39b51446c49bc59c97f8773ad4681c76195bbd22160b8d894fb615ce58db1dc9a1a86a3286d55360452f180b65fc9f744e4e240afcb565e299808bd4f1514a80ddeecfa88fa6c1b500210377d4eb621b9844deb62c89be2845eca38fe77035182613d14caf18c484693387c0a4ff7a68a468bb3be157a5cc1a1248e8ca3e1eac12aa1df5fe4a70a6a5760a4974171d8ab8cedf14e03a3dd9abc6d9428c5be055de3c29e1f5b5fb599326f1c183ce66d73dc871c9bd71f39fe4d11c7e56c76c9dcb7336fb9160c1a6e80584f5436a2cf8b7c3172174eef58c1375fc154305dc007c3d9e01eacc5b4ac932fbd1c587b35e5de9ef2a3fa0333f93ae82da4d435b086181066ed35a4c5a002b16d3b3363d72e2a5381408b9125aeec9124a1e23ae1d144eb36cc3e592f42005ab34de04bcc9bc88b591fe658ee25fc1a410d6bd3ab9d7b745debdf252ea53db619a602ed8637aa3cdd4a14bee883b80266386e25f32a914f2c290cf7f97de45bdf1f39db2badeaddb2757b64f22bf5a709bdb7057a0b186958528e88c478673351779857720e472580955c96f1028e8e8ddd4e1bbd06f56d61bd2503d09079820ba97a6d12e6fbffff8b916b72e4b20189e1c878857aee4386945cbe9fa7a941d5f10b5c33aeff19649d8adf9acfa99ac3015c5f7be0d93488ce9e9284256b1b826f1f7e9d9a7eb9c1618a109dfc37bc23c7dabab2a341d0d0bcd8d86d4c450c1a50bf195d7bc47b97b6a9fc3312d318c2df42160840bfcaaa712557db9efea4d4ff7b48e47cf015f9a49807e208c6ba072cbbd82062aeafa99d8e533eb49314d6c040ba6fe4c227fa19c8442f07cbd814211025468bace3918df3def021de62c147a7a77d8cd8a25aad9f99cc79b76e89b715df2bdb1ab8c7298a3b0e09a485270916b613c0f94a3024fe8db563d3725311295a28520e2b74104d95d2578d0e6b053f241b8d5881edde20175c7a9fd35f1a27163e379a952fcd4c0c02afaf73d7739c3a7f22f550fca50b555751e63c0c3498409a7f9bac47bbac894187b29e15967d9c33ce616b5920517bb79ef92b9da2eafe6f83f7ee7bc16e442f5918d7c1f35ad14486444ddc21f14728fb324ec80ebb4c10daeb8e8aa852c0b91786e1fa4781b879df1e151de7904c61af3bec8805fdcc44027e45d7f291904dcacab3017787b390205e31dcc5ddc595951705ee2b08bd8c3e2d82bc3cdb0429abc77b6cd22ac52646231956037106799e8b3ecaa77ff95633ad63c53997e03db199bb3513347c90fc80b7a014436f43d1e3f6e975674f08c127cdf09c8137d041ce15e80ce4c472ce1090acdcaef38455ae624020548220d40b4964e68230e7f02149ec805ca3dc60efd5fd1bb2e753e64559b82022b90ae5c492e7aed9e613bbbabd7a974ec51fd2677319a82766dcb6e761baef4d7551e8ce21fa6acb48e9392a17a9c4c2d4b2531ba6703d200fed808cb738ac02008df1fa8b0d1029c6bf21e81ac71ec61787ce390ff8af21a6704ea88af707c3993e0e2dbd12f8ae768604a4ddcc1ea0a25c777c65c8042ad884314fe7c50410f383a2a38ed8639029834785b8cc8dd128535c7f51c7d919dd14116dbec0bf488700c365ab87fbf7ae248fadd060e90e1534c03dc3c0e7cedfc06798f0325c020d97c48523d79376a48d1bf690c8c221053b97f8e38ab711168d6621c079c0777c0729589b211895541d38ca8ee2c824bd0d515d84a1ab180ed9882af58d91c2abfeb2be1cc29cb0b33170b89caa9c88d18b4263e1000f2b38cd6bdb649c27129313825110aa4601e8806e92fdddda95b2c04df25caec2f53564f940dfa705cc46995951a9fde27d48af93b3e6f11e8bc29211e713f20d524f20c93d9ebd2eb1b6fd9c889f65d1843a463120d29066d66a942f5d051a8e0d09cca2d0808f3897805c5d7f529ee5488e5409a7cacc956599e850230dbfe54ad79fd20dc8963527d814aace451e77c68cc97515cfb64fb427f235b907fd94d5188d279e62d5f9210706b34ca98841c72bdb20688e0ec7002ed0136a071d0f75f73b2b64223ce3155206ef38415cfa0cafdcda869e00f88474f4eba03e6d3eec1daefaefba05d2c190c724842ea7924f8bc4ee16928c8ffe5d60632d1ae7d8a5a5a0a3b256640a986a6cb21a3b2c77de52f7fbbf3ece88c1039767e0bfff8e4a3f6d3749d1ee8046d8a06041c6c5f0f80ac9839d65f363ac8d35e76e9621a63766913479fe401b00a302b60ca93b09d8e63514ea7aab06811d6b805470dd0db0557a8b4409bd629ec86c95c2fb1586864daf96a53d0459978a2c74060ae0f3be2453ee9748d0fb55dd500ed51afb388797cac90afe5387c9adde4fe3514d02ffc1066835f87fbc00b76191c1e408b1fecf837f58544793f99c59411998dc4100e865b8c8506cc55f519059057a222f666b594adec0ecabe8083c1103e520b3b85b7cb931ba19df66fceb878cc264e62581405f6563e8b428d9596a541138c8da7f01812e5cc7495b08b3448388b25425910c87339e38eae1deb9aa0bf99d2da3473984e5dbb575568cb463723c3ec309740b758286a0578233bddff1620c9b48a2366cadb4e3f5f30ffecc50b3ac655ab61d4d2bd27074a36de5502ebf82a52662198f383f6beb8d842ea921c2355fe535ba8267df5a072db47395ab4718c6fca00ca79771cf192ec300a6756cd1fd7db731e21cda0bbc2e8f0f912c6383c7cc596e63018cc525baf6284090f4289071a26de1590946188b41fdbe82784c5befab86491faa065da737223408cdc29720832d89d1e38fe4b4417c442a1d7410fa9f139efc00b1891971050734c6e6146b8e3c42b1a6ba5968f7c2ff0505344beebaa80d6ec7eab73b66c48a83b02b4eba57a2d004ac7bedc1a0530ca5b961aed5f912992eb30788c0e288549bb511835aa8d26af85f7f5d231a701820eb49046f75771a4f31509afcb605d9bf451d2a0d7e2deb38ebc66b72c5dc3f87078555cb00c646bf331700e4fbe29fc0ed1eff550bb1b5700a6cc1ff43d18612814f0adb5eb8220d728a146637c6b5e53092580bb0e13ebf5148900f85d55ff87c9647b910d62ad17cbcb2c60bbaa15daf69a5b93f187d3f8d5fd3d587411ef763f0df1bfe3803f1545a6613bd444544a089aae8189bd1e52425370be6452dd7215f127c01fcf2df142fdd71295c0be2a8ade7133cfa3ceb2e8877cd14fae6a22d997c4ee16d3b16895b464c749d2e75bbfdda319994c0dadcb84b2358ff027f9cdb99558fa906d78067165f441162f8fe7b4f65f3ec59846d05f4a0d8a38f5055b67b6c4bb0a4de2e00dcde97e66e7a076e4e43c10962ba63a704641949c389308002aa7d3f3d5115e55d7f9d7d43f862d3456e3c75109bda8c22fb3509a4d5fa4a65fd28c6a95ea6dfc4bed9d4acc37b51c54752dc3004e39b1e3dbfca4e07e08bc128c930f92e24e87173651165fa5809eee1a1519b003d017541d1cf223f03b698188fad0916e31753d211958b114d8442a18544545f41d913bd09207094d50194ed8adc038eefa242f5d4b4280194bf7a8b7ede998f5dcc23244bba7d1c09a376c51dac7676e98ec8f084df22b0eefd526d4bbeeb154e1ecb01b6551bb73cadf42168db1b368ab342a0575c219f9340308d0de223d61afef5f36600b437d055a66df73dc050286592418ce1207e81ff61636ba22f249270e5dcc351e719fe2fdee3eef78aa14c954b6382636874a253a4504577b3ea2c3def51f0a71d61b9a00f89ff030e2c45b9a712a0e2feac99af55d95be64f59beea95e11f145c5bcd74da889dbc5cfaedd52bf8346143f6ee5c25eb75e4c756ebb971cf0be9c1dba44beeef5cd85b6a480c241ddbed3f43f13c4b44410c847d42cd1b3bead91ab9cc07853d5fabc9a4ef63e9730040c0d15716ea92e54f848adf1992aa8ffdc551d0a3e4f985ac638f68973d49856756554a96a745326d3d011996c90b58fa3765641c290031cfa3faadbe43c23e8c155d21fec2e180ac934afa495d5cee1eac4f64b9cd15e2f961f12eeec0d21b3ffb4c3294db701620b8d98a964dffd27952836b48011325b1e342b8fc2e696b1c7480d0babb923354a34f8a500307c54051e89857b27703c773d126fd044b0d3d94bdf8374414f7752a6eba19e01880e0fc8857e1ccf271259894111daa5ebd60fe7bdb84bf55fe72f376d0f6bad5ca59733609b4c0a5facdeabcaa3b3e5f281a20c4c413266d752ad07e8e468ff9474ec929d3de8b454e59b5c79c53d17f43a80b9cf950fd9869779bd8e6470ef2acb66e749386995a91cbfc8ad17b7b2e9e07ff5fcce4333f55d55bd30d4f15cd151c8bf59e6cefd6e5f4e2088accce143aaef2167be284faaed6b13122132ae257db1414b0f6b2b16b2d345f1a79813055c7b8fb6f81ce9609305641044f2e79163480bbe53c0460c872a67624b51e41c4f1424ea685a9762298180333783c66b18e99c5f8467e34871e34cc8cf15cfa78a5f3d16d798194ebe966d29983770b2e830811b96202f531395262bf9f0bbbd313c9be746d65bfc889608c43a85f0ec4ef748b2052c9f92744501cb5e25a731e7f2cf412d3c1425800f60691f194311c19733d368237f880964a005a5446e5fc254d67fabcc6ac40b2c4732220518f517db86cc965f1536ecb1c880455e276a3efa95e8f64b1bc13d2597d7bc616d5e797f65a540d819823d942a029d956ba902c931e96fdca3ad60e51ca66a1a2dd34741b4096c5c0cf3881e668f805d418ac7eb6f0d62a4ff9b854d247567081d16389317b30d99513a2b9d7fa9df70984a7b608244b5168916be52fce36bd2b44c22bea392284e608725265fbf68eaebcc6896721019cdd0e122f4cd05facd00707ca36d294a21a8e1de4a919102b03a90ff9adfa90a995f65f29eaf5bc6f742107aa8833a7883c7de87bc93a173b7d28b7fd70bdf82693c47ad5af49ddc8a7559d67e3ab0ada4ee9c1e955cbd04beee204e022f6997447b526494377bdd31e469a3d4c52bfc1d41191983c38c298f5bae11c900411712b2813f10bc4e45396c5ef613d7af5a246858a17810f1b05c8c1bfbeb8ab0400d9a8515efaebf126d197b242a45d5b36e81771e1f87916d82cdb3725c017d8ec8c50486ed988e47309b7bcd819829b339181a14ac9083014c3135359013de354110895bd8d0fdf6ddbaf9e2160dd3d3af70cb56884a4ebf0556eb7f5dc6f43f137fbbf54b3fe09783b73b5170d9f03dfb8e6767b38f84d90960b6ec9352201d6fa4219bba46460cbe9933a58288582522896ccc2f1cfddb56d32bb0fb958355690245696e083c4b3b049c259f0e0aef4f4794e10b5bea6765293b87a4fa9ecb1637e917ae1188e5e58055b392f45db7469d5f4b16cdf828db6306f59b71f5f4359217475f50c9e0ffb958c728113e12e2b8639de13ba2817afc7ced8c1461107aed273b880eca79a810b3cde67147814050fa3b1bff8574a12cfc34a67a53c78013d550c5bb1d7e025b3ee0955cb946d549b628cc35bb88e58fdf79b4d7ede7f03e0f47ddcbc95adb7c2bdbb4180de3dfec0344fdab464f49e73077506399d14a3ee9c090ef5ca3f33a506a4d10810bd5c9a042fd24d54a43ea7e8279f25ae03b426301d3ba0b407c7099c5799c16437356ee1a388a5d6aa4631f2250183be6265944f88a38d019dc5294807f621ea225124e195fdc1b885d95c1deb2e1096d9de9bfdb4e04f0cf1249cdf4f5f0fab6727ba03e4a663b2d7024cd273f0b40af4c24816d68a380353f02e2316831c843024f143a8b3b6bf30a0261544af8c89f684e1cfd3f0e9f79c85c9c12dc86e5657d872a5d51473305e97b6f7cc58217bae70487044cbcca1629f75131706cecc7ba15b5db90b1bd80d38bcb3a5ef8e72121cb8cd9eddabaaa40cbbf220e67297c8ae50f1ab927c97feb2477dd1321c572691d7f48ef1a62c843a96fdace100a99e409b04183baee929a2636349ebd281c2f4d05700b8d9991f2dc355d1c70072a53709b3d04a62342d5b175beb76c73d9dea836c5b0fc11ede5010f22f8032ea22d6f2ee4a1a860f56deea127bb3f0e3c9c2a1e5c2aed3e98d567dec5695053c9c241a58aa0c443fd836312f599c9ec74d2e22ffed3ad1f20ec8d5f63aa16e9f1b5045a80e127ba07aee815b609ea26e909031bc44e8b93c1a0ec39aa3db0693ec4ec70187273f780d9984378682a53d3d1c908d0a7d092e41058cef04c8a4ace673082671bae406024ecc2f70bc7108c7c2f52fb8c5e9dcaaf6df02c4ab73c164579df28da664c6743a72084ecce8168e7a9579264ac717e1c3348eaa34b990727540c65551ee9cc9e414e78471bfc8a78acebd87eb65220d15fca18d92d410d9c299f4da915e55dc017ff17875bd7eb7bd7be5c1e1d2e12a87d087906185f0701da0272f24146362e0b14fcbeb20c077ecc30dc61821a1dfd700206235a8a2c35d81ac7cbbe27112afe615e6e383cd38ba2f0b631500d594adeef9a41d2fcc9e1702efa6bb305578d79e0e62127f5e34f4b78493d620a9083815400550b7bfdd9e6f2831943b8de0b0bfcf51bc1c45d1ad62e1a80373660cd070cdf2c499a60103c45af9c236d7270cd6df05f8fe15c6963d7867ccc628855015bdc77b175b38fc7b159b823302fc5a6f5df143e70161d89407ee91f147bc88c3a98cc8492caf35446f057e3e457a1155106058b539ea1214a6e85298a2ebd4e72e3204a12c5484c1a2db5945d7d12ad6ef798eea2d25758b6cffc5ace51293a9eebf6d20907e5b9f777ca697cfeb34eff8acec656b1aaaa0acff2cc7159f57b335dbdd5b06de12b311ea0f30a769a0b1841f8481033066d0c5391352c0133b383df000045f2944414647cae5f40d21c48f4f1a37d8410e7048c0cc1408f8208122f8e00b19b0800458684006dce101e74e80ce5798421942e0c10e602002259228c289104d7e7c8c14c1e106196248010a94c0c203492001b3a1067c71a85104223c2993d240230b587032840c31a87c208318b480052418c10712800027604504c1e4c787e78b1bc4c0062a9872240840f8e2063280010b5690012a0a3000014ca10c1ff080052b480108a024fdc8b3a36a292309631461063040c109b4d880020ef023ac08274330e1d919e262a95abeb8c10ca0988002a0fc58c40f3c457686b86ab4783409637c71031ac4000527d0e2031b580002a010f1030f0f435c407cd0b06ca83c9a4612c620020d66100318a0e0041fd8c002148080034039028c08273dc8806770210912971a43a8e1090314a0099399290e50801ad215a8343a34b82e94b8c06de1d4018f03dc06380d6c351c4d37b3812b311d8fce63c081ab61cbf1d1d0cdb0e1f064d86240bd60c34697f25c5a6aa45a68609961a5061515ea3b993ece642a95ba8d524a434ac5a494ea0c3e19abfbda6ccafc88457b4f254c34a55243293dd194ca0e4ae90e34a5e2b15cffaec556ee3f5a7dad6bebdbfa905aaeb9d244afd629a531945224300a0494528fa6501ea094d6a029541494863ebbf66947ce721e88f88a07224e2945514a8b503e50304ae90a4da18628a5a1cbb06bebbb16230204c121f2d63c68ea34859310aeddfa477c9db572923a79e034858ef77775ed3c299a3ad1c6fbd407a514079a3a05a13a8332303475327d5670da9edd275d86fd454b6acf5896ebd6feb35b33a59c0328e51a4029c7802d0994d21c34659a01a54268fcc6733ec51d428404110244888d901f427c08e921a446088d901921428204090224884d901f417c04e911a426084d909920428004010204880d901f407c00e901a406080d901920426c82d800b1b1b1f961e3c3a6874d8d0d8dcd8c8d901f417e00f961f3e3c70f1f3f7afca8f941f363e687101f417c00f161e3e3870f1f3e7af8a8f141e363c687901e417a00e961d3e3470f1f3d7af4a8e941d363a687909a2035406a6c6a7ed4f8a8e951535343533353238426080d101a1b9a1f343e687ad0d4d0d0d0ccd0089909320364c666e6c78c8f991e33353334333333b1199dc1f2bc32bb947dc6221194720b5069ad54564838121e005769a904c0dddd29e5144029f704a55c02582847537b878b884908a59485a64c31a61c94d21968cac4b92b0cdda5d20a43776dd993ee2a216bd36636bb6fd993abd05d325d79e081520e01252f28a54e53252b28756df71973d7d6ef932eed32ecfbc48ef4634753a5084cf1960e1dbeab8f5f24da5b4d4ab90394ea0ba62a2875edb3e708e78c715411e851d154a9064ae92abf95d97d7fe4d9e213c57e404a290028a53d28a54a68cad380cea01673a50181803331a3c5315b5f2ccaf4a80922be90d82844488d8d283e4d4c89453076d2b69dd5f2d676f65906cf721565c82a625226eb53a6b6cd72e7fe6c8c83f61bd9f7b7b6fa62f1f250ca1920e39c773ee32d34fe36cf9c718e7ea3fa49464b56a3cb9331d07d23b56d96efdafa9f643572b29e5bac4e13772d7debb8faf1e8eee3e74a8aaf33bb566b5bbab62ec3389bfeb4ed25ce32afbb8efeb7928efd472cfee878fbf8a4ad45f6cf721ddaaf6b2b2de7c57c62a1fd72b9beb4fb9e1966c6f63db128d698f19eb2985df3df9f19d9173fc3b6fe5dc9172fbeb0f1ef99cd7bd65d75fed62430b26ebc6b5bff4862d8b5305deab779df87e5af55f2336cfc31d7a3cff7147fc9b638413a7a93a7fe0ca389bb9ada8ed7ce3e567b24fa6755ebef19ef8963fbfc995dbbc527faa0fd42b56d33a6edf385b759cba2cba5dfc86e5bda6cc26ab2ffd8370118688aa3745bd2d41eee1adaa0a96d079492f525034d6d0da094dea0a92d89f2905f5f4b296da1b484631bd2191c712923be51aae6c40e94d218686a4bdd279d887fcc47f2c434ed2cd776e5483f5eeb6f84cbcf30b31e69ca29a194e2a029ba04aa33b84b59c639bfdfeae3df7ceecf7eb1dd75df2f9f344bebdbd6bc7d76eddeb5cc58e695525aa29433514a6ba0292a4567507c23d851cd3262d6322226c92a53cb35c72c492957004ae946b92628e5084029e704a59c14ea51ca35d103141e8840044650326c61058b0433380268082b18927de183092ce4ceea450941c078e1e8046e61ca137c4827a8400581615980068c17662000d8995a47871e88a40ce002271db0a8e0092b748ba4a417ed58563081952392e0bcf32436f7fc882b863e37f91150a4384e6908e5254fe2e42a6e8239228ae394608e48c2e42a30521ca773144c122718298eb325618229c1744e3d09d3764f34d5016179e17c655be95890488273134c12e7dbca8a9f3e94e72896170e8a87c4c937eec482b3f2a2c4e9254a0f389da35ea048d9703a8fd2038ee794858565a3382c2c8e5271291b0eca3737bd4059711598240eca8ab3f8f68204cab7130c12570ca17c7324549cf3178a83527961c9f1790fafa2ce3550e3dcc40245c5a5380eca4d2f5058361698a4ce37df9048a273144c52e72847c14091e2382cdeb50891ea9ce50589243a578149ea9cf3a1ceb917291b0eca4f2f52369c93abbc4089d2030ecaa56c382abec2bdb0f8f6b2e25dcb4e0e203c6771213a5f71d30b94939b9cb63051028765732450ce21a1a2827ad9706cd8200553a4811ae71aa879a5961c4078cef9500b500b90574aa2b4792611acd898c18976513c2852a29c3a209cd3ed450a27c58322c583b9e2490f51ae78d2c3aba8dbe816af2e896d63b262a30b1b31282ab967a4e4753e704a74db0f2b7465a5449ea030b1c4c639e7759ed76d2258a125dfb66ddbdcf3d393ee85dae11ce5dfc9fb505ef77da80f758229ea3ccff3ba8eae70476c2d3f28d1b1d016249e9b8e30e276e74357ea4a479c4a30bbfb4189d77782213a7dde4b5109e6c9112f144cd1e79cc94b251f3a22ceb722cfe9cbf4f2e4889747c471be95b258a1dbb675dcc9bbceb7e72623efe5098e970acc93239ee078996076f742f9090543e4f9e6304f8e787d30459e735e2a99ba8e6b41c9a99f5e521dabe436c0486d5e72aa4389c88a0d19a438df1c9503aeebbacea5546a29790b8bc905e52d286f6971d6192d35585866b8ec80d202f3a4abc1d2e2e20243b42369d5854b0d95d77069711757b9b8c0d43095bc6b6161812122bb305868b0d060a1c14283abc17d18f0522e2e2ece3ac3658701522e2e5fca6547120b0d161a36dc25957271961929679d9172d9610017a72e2c1b2e6e630794944bca868d6dd5c5ab84721b2fdc70150c918d2fe5f242bb175e68c7b2c1e2aa8decc2f8fc4bb9b0380b0d161a2c3458687462b8701f12be2c5e35baa453e726ba51df91443d4f89235866b0cea03b0cb051ca32837506d10e28f474da91743a9d4e7e72d38b0d2e522727da29373911d98541b95517af2e0ccfbb156f7901e3b552a3c60a0cd1f668b0c1450a86ecc2707181213ac17461b0bcacc010a9c06cef858231390b0d161a38be2c4e535abaae63f938aee33e53a782826151e2881a28af51b4e2f48572a901c3712c2c2d03a05c5e88925871ae068b13b1984adeb5d45861f116e74ead28a6578dcd3482d4a6c4111b8bb79236f758dc878ee553bd141199fcc4626261f9583edfdcebe4b198503dad282c302e2cae52a9585cb5f94b510da72f16cf8613792f96cd5d3c77d96cb0788d1aeea95c585a52502f9397be947f2a18a21a302e9b7b2afe798d9756944d66f3925c3693154ebed275dd0a91c7b1106daf53e79bc9a34fbad70643b4155921a230441ef7429452e2888deb38a256038a4a4e5f946b25b5a06c4338f75a065051f15a76547c47c5690b0b75d3cba7e226ce08eac4850acc469d608836ea83296a45d98694bcc3916432c34bdaa0bcb66f835131008bafbcb0acb02045e44d3955d1b13a3f9daaf0a6a8e05485cae9a40567633aa5e0b40567b3d245175eacc0b4a0a8b4925a514e14384d3945719ac2d9785eda564aa728540c4085155e1559a8a8ac20e54db1a28a2c5490da5ede140a7851785458514516ad28a729a71278533c0a5471a2c0a98a9315de945315ad289b8ca90505d54a9ad28a827a6dd40be54d69450163058ca457e7754f786dde85b175626c3037522995266a784b192d2f3560889478b5f8698361b1e182d4773aa5bacec616a92294975e445f182d8efa84f089f18dc1d998be277c6570362d27efdc0c33ce38b5c0b0ced8644ca70d89f742c1b80f9d896506b72ac17c5e70ab2e5e3e30be2e381bcf4bde7dbeb5943e30381b16ef5ca50994b79458686c322d30261b2d487d4ebf2eb6486daf937766746770365d52f722da5e442c3436996d07949769eb828cce3befca30e3d57967050e4852e75fe75f189f1038201b4eb77d61b0d0d8644c2818d6199c098665c6ab2bc37b9d58502a3044db7badbae022451269253e1818ef94f4a2397c1dcb04bc80420b282e3006b7a22d40d429111796283cef2bc384c2426a65c5cf682551981691f72a9d4edc8a66ef85d492c2adbe9694951503bc883cdfdc8b05b5c212058bafbc78cef2d282d24a5a59394d393dc1ad38cff35e60561c8668f3dc876e85e5844a418ac8258a1315a72a381b17eaa2525e449b7be94e444abc9e6c697849af156779415d21b5e29b7ba8cfbd56941614a2eec5b2b29d3cc09d2430e58955172fb20bc374f23c2f89970763eabace4b2fac3336198e65060b8d2c368fe34a5ed7719c6f9c732b25becdc3c069032b5407a2d3139e9417d1a913a323a30372f2275ea5ed093b65985e1d19409d181debf4e2ba6f0c8ec57d67bcb8139417d79df1ea60883c988d7a79531aa0e2448a4887275e3a70382b1b0a0b291fa4522c3e486d9d1825ce5301fd8197830a9c08c3061f2880008a80d345a162015ad0f03a494981175248b004195a38caf49da490c0643a9dbc0478de0f1e20c5035498c110a6a000c72b0de0e5791e0e53e986e7799ee779385227cf4ba56ed478512fa478f1224a39172b0590e2f2a25e48a9c2834100ccd0c293e249799d6ab06d2728b66de3b826b2e030d0036edbbc48d2c28b2664b06d1bc7754de4a00342133258f9be21e4600508524071427927cfd404064e3d52df8bc8672ab062a309ca79a6930acbb66d1bed9eb8c0b66d1c1786e779a552141af8beef742263032a2a2a2b2b5b161d686969a951c38c2b52a9544aa5c2e285969ded85175eb8d1b239bd41bd70220cee85e3c509326e5061c5c6142c5e38618197174e4c79715d38016546e564fa4a2693c9f47ddff77ddff77da6d2f77ddff7b9e779dfe77ddff799bceffbbeeff34aa6d2e77ddff77da652e9fbbe92672a7ddec9542a7d25cffbbeeffb4edff77ddff77ddf672a79df57e3fbbeef3399beeffbbeeffbbeeffb4c9e69e5fb3ed30e25cf2b79dff77ddf874a7911e509194a602a9da430a9944a271306bed20e567c9e2785e5002eba1b391010450826ce6bc2f3bc269af84ca52d3580299c701d5a5e443e73aac1811515d4e933953c4f03a69327c5b66d5c8701cff34a262da258f17ddf09e505172a2a2a2b2c5e4419c38b284268696969a951e394f2620053acbc008d0ba03cef3b7da7eff3a46060ca0eb670802f4a30c50550b64063025c142522e0021c84600b170861091cc011c00dd0d8c129854263082a5f0a552a9996c0624a799ee721e189cf8446156a944aa91b9e0e4cb0984aa5349660f1e809a6f318404594344a50e3060eaf94460c56707052d2e0c2e739e17910b8c20f3c0005294e5081e33191c601ce48238d31506940214a1a55c0b185cae9b329a1a867e3e57da82e4c41d5ddc0d131e13395d060e2e4a5baf084effbbeae0b4c20c0e7ddf014b003341e308009bc887ce6540302335fc9e4795d88e2e5799ef7555180522a049e67ba9102cf735fb90e7e824189fac9f33caf74e3fb3ccfab411768e0b9ebd0851ba82ca0e4994c26d367329952a6314a26132d956e9c4ea7140e93a90493bad1052967a4f1224ab9890094bbe1ba8e8814c7e19ce886df7444386e6ea4388e37e47322ce44c4e36c4cdfcb6b7393c7bd28d125e1715e0556bc6de3b6ae739693165244299402529befe095bdd72b022b1bc7b9919273dde6463cdf6a1ce99cfa4685733333abd5167482a15d974a9d4e46381b5fa46ebc88b615cfc58773231466db680cf55e9c9ffcf3a1937f279801984a2d464a398c6c5ec439e55c6c2c2055038e530be7dd8b11fae238981c9e17c1d8f82205f362c473ce555a783c98972d8d179112af133da16a70de39d7c170301df77161654be3b5e25246199e129e11ee64a44bb518f16c7ce1b51829bd4cbee292c348c98ba86f5e5a29f172c9c153725307930308ce3b1f3ab9e7411407ca00b8cd0770dadc83e1bc04a301af0ba30ba36319a1af1c9f7f3036be48993c8e2b71385d17d4e1789e17e4e174a552a91454c231994c26539009e7fbbeeffb823e9c52a9542a954a30361490224a059d703a5f512999be530d0d74309bc94b6ea404a3c48bb6e4e031996028104e10c5e9684b10e5b8178ad325d1792c56e8ba1f9d8fae4757d3d174321dd8c574add5cb34b303d16ae694ea5ebcc381764427148e8e8699176aa67ba1bbd1c1d0c5d0c9d0cda43a97953058d0f2c3478f1a9a19190fee09288114a290c011dec8ee6a64f38f305d49b2c674858d81842d8c3f5aa3adcf92526a8352aa85204ca094eef1bd463eed5a37cbbaf5977668c6ac5b9776ebfdfa67f9344b5b49f13fcbf2cb602f662c7b23feb3ac9ae3ad79764f98888decf9e461e39364dd1af61b5f1d136b401ab0474ccc9355d431b56d7335750663e3586b160967539fb8ac5d7cebeffbe5f8e23df1bd155643c29924ad4cffac9a30b33e0db65f6bd83e316ddba39df1d64856f6d98491a42d82d1b63d8215e55a7efeb1a219483ac289ea376b1be6e3064833d7ce6cfef15180948f2894d2209af2e18312e16408273b68aa870f7a7ca087131f68aa470d94863ebe3f6d3f19ab2186e9f0f41a49d6f3d6d2f3ef4afac7fc561124eb395a233b5eeb77ff6c3c633554a8d182524a8493566b082760cc49d21ef978ab975888526a034dd544a194ba68aa260925c2898f9fedf9e4b3b7c6a789f5b3eb7a34de4a73da500d0f9a338870e2add1fa104ec02fb1b84f4ca3022ac36ee427cfd7a01900057b729ab8688df20bdd9dfc463f41faac34a41d264ac61d7d9514411a2dcc3c719e8dd7167dc639e3b548601be9ef0d11f197ecd73219867dc6622defbb938198f1b28c1028a53a34253385520afec6463ebb36e6b3f9b4edba1ec9943238c2118ba1833f62d18b2c01f21ab359d4b1537bf6fcb46d7f88524a84a64030b4e9bf4ff191def1f69aabe92f70cac6f7e82f109a029be8f305e218ebd362c208470babb99aa183355720afa7bf76ae5b486604c46bfc8d7dc6fa47c8737c9a2834d63f32feaea3a9e4479c932b8ec9643ff708ebccae7d52ac892fb3496aae40e3cd98dfe68c9f5f263b71f67d6b5af1f30d4dd723637d1a4c7c52c260335d9a653ef246580d83e51fefeb9f55d8f865defacf271f9473dffc31cb7ce4372e3f88ac224ea247974bcbd0148f2778f00842f3cf7225dd9146ebb91e99e70e31cadfb6084ded4842aaa5aea6df239c67fe4695f6e79f4fdc2ccf174a694f10b848ed58514a573eb3b28b45afc5b62df39b7e2b6d675cf24053ac3028a5dade73a55928604da194dec420bd5f7cbdded7aeadb37052acd5aa3c4b8b544b3cfb9b5aede08db0da6b5128a53434b5626215d2957b6d5bb19a5574f2eff8bbda6d67f8ef8b487f541da827e8883f6dbcaf29a53634b5724a675c5b207a74746481527a034de9f881d7c80b7b528ece838fb91edd233cc2c6d7fa459c4d9cdf089761cf585b233b7acd3f3edebecdf2f7aef48df2eb0f1a5fd74f32fe78776a63fd4cbe36d2fb9c7a9b2f8a557fc622ecde10117fc9cdc87333f2e8d46a5f04abe537c2a2b6e3f8af61251e6fcd372fdaf15ad81bd92d562cbb3c258ffebd5fb56d6f589fcf5defcc0a2df1d68a88f84bb4a6e94a83fdaea31d6f15f70b3d2d87ac46389be66bfcf162f18566d7168915675bd19226d2ce782d124bd625fb34b5d5d919c75e637dda0b1bd9f7f567209bb7fea0f1ad798ae2cf679cf3b9b495cc19eb67daaeb902996685edfbe59d59adab695658c6bb9224165dae1a23ed725d5b6962cdd5846d3cd622129be28f38e7e626c84944fc2523f933de97ae69ecf3e30bfdcfea169ad99e8badcebf84520a030ce890d2f5c849b28a46682a872d2acdab5f5bfeb6fee4ec5aed2f4a690d4de59084ef980311399c2848927fa4abb766d76e9dadcc6598c7c11a499e3217473bba7e9761d7aff1cbdf3ce3ef27cd12e7fcbe3c3471579c7ddf8af745b344bfae4f7e104c144aa90f4dc104a194825bff6c766adfb4992dfdcddaae7efd69bbf5b45d9eb35c69dbdf8fde47e8e87d362685ce27d5fc19af4542297d81a65ec8a094f6d0d4cb045e8c509008271b93ba355e5b348413503f4d5752fbef2a5ad23cc7f1c77ddfe85d5bda90831b93dabfb4db59a29559f14d1d335e5bb41a6ff51076b1d5fa75f8a659691e8ed716857edfc8ce64d8c7df199b9f1dfbadf969432fde97c97e5e76a06fd6b6eb7ddf6807669ad5e51242f3e3474dd62ed75f4b5e0c2b2da554074d391814cc0e853eabb9efe77ce6ecd7304a690e34e530707c4b9a66f5fb1f735d69be5f7bf5a3f719bf3cf507e9b747ef93cb1206db4f92d5748fbed41e8968c9d809e44114d9d9c1d982520a044de1306556b75b9dc17d2d366bc099181af1359d81cdc06a96ccc06660344b446d7bccd731251e1590c20107a5dad2b6d3444b3bf2d6d0f8fa94e2793748718314ea78bb9e5552e6e3cf6ea58926f63fafdd178b366f3f7110941e41831561831894d68033208dd10ece4fd09050b8d1ad8a4d67f063386f3d03d6c45c4be62f214005a5dc0528e5a6a0291baa483a6d49494b24a924519a9444b924da2551279268010a40a90a45514aa5504a80248a4a4a5a22a90049942625112089894d0a4aa9c735a1b758cd12e7b85ce28f58c4b2cbf363cd3353c9d63589ddf6f21861c97a6d919d1a699aaf1bad2b29c2f29b48b52c1231198321d5f286c8c5769b3f48b514adbe366fa487bdaeb1fc40faa6a6c749243f10522d5dae8d03341cb1c5cf198bbef1d547ee32eb4f1bf221212c63d848da33168e4fd3f65a99e71f497be2e80cea6d4b4b96bf758d522e0a4ae9c635f1dbe6a3b17edeb4997d26319da07f194cd7aa59cb78d7f1d61eb2e6377fc85a66eca37525736a158852ce02ffb988a86de972e9fb4578bb5c5a9fbb6ea1176f252b8efe20b04f6a864a29054150c77eb2b5ebe7996fece3a076b256f214c92a3a6ddb239f5d7b844959fef19efeb9fa3371916ff424ec62bbc5aa6fcddba53348d3952623f33f7a00f101844686a6a6ce00e921fa187bf4f01164e681c4fcae79ebd8a965f43e7191f8345166db194d579acbb53336cd53c3beac5986230b4a77c634ed186f9aae3477bdce6ff4d9e9104de148a23338dedf480f13dfd432e21bc9fc107bccd8d0bc6c9409e921fb6a33f3c3c7d7fa0388685333f363668c8da38fd80f1f405e46dcfacc329472100001a5344655487a504ac77fe243c6fbe7b5a5dff8789f56f38e9d9a520ac693b0fb242c0959457bf1ade2c53ee39719cbc8da33da1f4ab90a8c168ff667766dfe31ffec17ca6ff4f323ee99d5a18f95a7cfac0e51ca4131fe16df44fadfb5d83dc2b7e82a99d5a1d9b5d7d6f2f35877d5995d4bda9a8728e5281044b695fc49d62594721390c0c5765b8dcd2fedd0efaa33ab9b52da51a7f444298da1a44833ab591df279ed24f9f9c109da31b233e4c3c38363c487276848c8877686727e922451e213b4c3538467c8674787c78772767ec0f9d1d9197a05edf428f1d909526448c94e8ecf8e12207684867684449bbf3c7d807ebc78beb44339434abeb443e31b6149234fc6acb64b66d7e62d04d48303030528a543b8cf0fcfd02b87270910d00b0693d2213c87a7084fce0e9050cc50939d219f9f1c189424197f8b6786812605c36ae5440ce13b43af253c414094721198c241a03362400e2a94c007f5967c1548629c423f1f18c1c20a8c82d04d0058050258e4807e5888822700600e5a7a40018060217301dd3c03d7426003942b8760f1436d454b0fe85ed063871fb424040774a0d0e394b2be1d05e071436991173450128522d0ed054a3c01021314facdd081184871c60ff5502d6800ac0546f48bd2c5134eb690063501b15279e8220d4abfcaed1434a19c138e804c742084d22e702089081f9a40b912d41cf1ceb0817e03704006929254807e522882022a600929e50106ce48000e28a829878e1f6a449105e57c28a180419906356903c8c087da11edbed0d9a24b0aa21d1090d18e2118414d1368c00e20984210b4e4363738c208d2a09f901888511041012d2d618a70db8245b72a564360b82aa05d0f0d5e0802e90294969114d2affca8c7c3463f5a526d1f75d94a316c35b6538d0784760df06ef8b8d3a9e475db4665e040cad10d08af878d7e434a94a3dbb675dc916dfb366edb3a9311dcc66d1f1743d0b699b68f725b0bd87126d34ac5378fe3bc27366fdb3895ed0adc86a2a5cde3badf36226edbb893122e07b771268fdb9cc06d9b89db80d864d8b68e3bbda0d47d35b618b66ddb38211c0ca76e8b623371dbc675b08df354503e3896ede6b49574e878d83e8ef3683a158edb582e365b003c9a950870d4a31c0636af5b79256eeb68c901db1136cad1542a4537ba791bb745613b713bb68d2b715cb76d3d3699edb4b1701cc79972361d1ce771db4c07aecc70da616bb141030781adc4cdb0795bb7510e887395cda39c35510fb70374f4e5051bf521065cb79936efdb5ab66e0ac79d5cdd16a4db38ce738e05b5da4adbf6cd783438cc6c9c8ae9c46ddbb67ddbe6da382e089d6943715e67b4c170e7b675311b6a85db4edfc6f9c0ddc0ddc0d9d0d18e6e2e9b89e3b6162fd579dc0c1cc76da6cd936d281db69512b795b61a40b66ddbb61cdc0fa61514b7c54e2c1fb701b19db6ade3366f3bb2d9c009e16ae056b88f2b6dddc66ddce6da6ce056b8cfdbba52b76d40b66e5b6da88d65dbb621db0d9c4af76d276fe3b6cdb56da618b81b9bc76d256f13c2ad6c1d77c3d6751ce771de2684e3361a38950db59d3c6edb36d76603a7f2759b77f2b66d03e21b8e1d27221d8fd2d66da8cdc3b1a150ae952172dcb0e5e06d1c67e2bedf5230ccac1cd9366ee3b66d8ba11f35299334b632985cea4b8c4006184ba4388207945423cc0819410c1af402040a8414387820ea1714488a144001f4827f7e8c40544692971baa60c40835cc089102878c905aa303408cd0a203901795cdc6085b176cc2342a60e3685030e4c20d3161155c4b8c0ce096cfece011454b0a3884ce8283cb608346f10211342c2980ba27004a3b4a29f780fb240c6f9879c282c8b6124ae90da5348852269422a194ae682aa5aabb8e3013141500d42009f59d4e2615155369a5b301f575a50e0696a1257c604e2b93ca2988c7e2b2792c5f102cbb6be952a53004208124530dee4379ad161b827820496509cbe8b56a2cc1f9c85152e26d26222e48e221898e4a009ca7e225616521490c285bc9a5c2c18725388f862e8607493c8c9084031014185c7006d01959a289a419504c586e4820a9080ce649ab602189c84619091790fa505d4ba9c873c2004b9c3c5517d36389254c81dad1032827332050835b29f9a0fa8478487e882c9878a1b45229a2b283c989b7e313c28409a430c2040e122003a5454c42002e92564ed90404d052e3b2912069069b25543e212695538d0e088f91ce069522df123c2d42a72339768aa8a08eb0088d444c902483d7b25131b95e6831a9acecc01491812495d3911b6205482a75a9d26602c2a4521a62daf1ea61e544e9381d31a97c33b4e8a074f07c5032dca861071a62d8715af904edb084ca09fc7ab4f400c203f4b1781f0d2557678362f174b80f1fea53f1644a48bc203e6ca51cdd4b298619d449ec84ec0cc1715289010564891c9f151fa795a783a7838903493b6a783a251ea51b503a7835b8d07436309104ca6c9dac8bf1ba5200608a6000be5878008c2db2c082035410400924907491ecc5b00827423459a2440828c90f475c417aac7600400eeec500066948e1094be8e106003034ccf04561032f34900120767a70d90003cb8a898b149ce08a2a3440c505a488020a252b1d32e0042490c619568809218528b000861790002bbb19a2f255a1802780a07e10c606aa7009b191e1c68acae9ab21070946e0e4c71f9f1f788aec5400014e3461438c1f2ac0c2031c5082c9122036386e783800a30a4b6e78b0417da60f44390108a67800030a10000b54a00209f8f1b919a28365e302b705ce0caf0c8f024786b704ce0825313620703ee07a80e201cb0e381c705f7029e8b0e08a3ca24d87930da51a5a66e064e060d86ea85e28d9e0545bcaabc1ad945438d4e9c47d5f89f3b66edb4cb4c5a5cbd1ad20c93b409297c4b4c3b7ef0a4ba43290542ab17c3b0061094f0a1a4f06162a3a60224092970415834a0d380490840ac213a2bb61659b584e454e414c2add101c2aa51a249d4a9074c3c91228201d145460294252298da4120b0d3d4862d9302b4842e1a8c17d434a32a50648816165060830e11920c9e5c5e5a58b51c99c70a8d260a2c4e314e423d2b974444e5424753d34322615931549dd8a8906afb542d36d1e8bd7522952e2f10561a2c1a4622262b9c17203850315c31744d705264c3474593051ea220900445ee93000d8e0b9585c4c2a6feb62ba1c0fa8250613f731f9727c3e25186a6ca695aee4b1745dc7755f77ea502a3578dda7e4b3e102a4a2fa4cdfd67d9e0f4fc6db4e3374399640e150ea40520d2b965099bc1c271d26bc223001135f94bfa8f658118592a4450214e487901098dfcaaa6f7be258d5f5831cacedfc26cea6c3ec5a665c24c80fad61fc471021211fff471d6fc4c12fc24662acee3ad2743db272f3bfa8f41e67e2d23bb8837eb1a585fabacc3a6be5afc95ac4c1106b1fcf3cf465bda1835b63f2c47adff0c86521abe5720dad429afe2cc32f93612fb5f5d9b56fb325c5984d9b59528bd67c11a9345d8fb85c432bf75a7b1cdcda921ede0c1109c7fa79bcbfafb57f7a8d74106bb27a6beb9f591d07c30fbd16f3fd42ced23ab459cb956b07f59bb56786b7efd3242bcbaf25ebc6430eeaf0c848f29499f569ae2fab8ff8a6d0f3e0213dfefbece0a112e75cec439235872b956e6865d58e7d2e80e302dc145598620a530c610a30a698c1145b4c3182294440a98957ee2e97711600bc05007799d85b00f0bb72771131c48f5874515a72c114494c31b256750a1d28a541684a8a31ea8f947a49444020858b140438c7cf7eadbbcbce7012d7eb4a037a5d69e6cd90684dbc8374dd75d479df13e7c83e48e72f4f7db15877d5c1b20bc3f98d805d7cc53735d22e5dae2158ccc5565b6008f11c7136bde67a76adce60055e30da6a5e253f9af54817899884fdf9e44798f84632fa629a030496008513a0108352285480f348b688cee0f8b9d2b4cba5cbfca659fede98d4b07b524a2df064044fa478d2000a3c29712ea28f3049be609996692e97cee0799ae598c15c336c7c5851fda3118bb0fd477f61798f581c5f9ff7847d113661322313e672fd784fd9e73722b1d676dc767cfc45d824c90afb7dc66cde178bf65af2ef9bf83526615bc3ee9b1866969976f477b4b11b976b28ff48620834a1141c2d6947120fa96debe3d3c46d8f34114ef2e3f1d44338f1a70d418045e9104e1c2cc278bffe621dfdc2e329547b24a31d4fa10790411f00034a31edc8e5ba11edaedb3c8b304ee2720d1139fa8b847148b28a0ee08203bea09422a129074001f393641563c09a3e5b24598f1a3006a514dc180735408806e434a00703c4a0e0cccc4c6b86c679842459c5d099780cc85af96f9b8f4a9cc3b0ba7e0630c180cc00211820c4001e06c4c0001b0b4001a5548688e780a3e37f7f3c06d463fd3cbec7802c9ad58fc7dc10f11c4098104cdbda171dfd6585477fc3958ffa7715edbe4fdbe74b57181e4fd8f8f784e1f1d4783c3558fb22c7e3a9433c9e425b89889105d0574a0155d497028628d5f6e6c6e51a22420409e3b85c43b52f7a02064fe0277224800b4ac1fd35bf5f69beebf8f756d2fcac9f34c18b4358e8785fec63c6e2ad2450028448000c94d21d9a4200180740c01208b839401728a5383475001450505ba789a766854a3e5cf9b635f2e2f15692b447b48d639eb7beb6ce2af6da17dd2ab3f98d306d7fc6d6a8d23ea66d295383cd6e254dfd16a9f6e8b7328c547bfc4b3b542462120764c5b4f9d943d1639c265c792886aec7d73576e4f99c599935b2798b766b4b5afd59f48fede0bc706635bf51d501c722d1e618d68ec797bf6cac915b57b2f5a5ddacd755ac1f868e6324596527aeadbcf5312107717e236afbc4da8217fbad4f8aae6dd5d6f5b6b9da237cc4416d9efed792a569da227dadec472107593ac7b0e3ede323599989f3be24c666fd3163bfb648ac79fb337130f4099d26c627f41af9e3addadfb6c290b54f739fd88b042df1ade3e271d4d756d2f45aaefa9e3ebbf61cc9d3c4a67f8c7c2bcb58a62b2dbfe932ebe197582864c956b55c3336cb1f72b0568bf0ecf7b5f58642614c931f264332ecb36b6f3813fec576f631ff236ffd38181e1932e2b3930436e4b3d363644708e6f3c33394a3246848c8e7270716b4a3e3a32494e172f631cfc4c1ad2de963fd3fda1f73990cc7fc58f3f6ea5f544b7f261ee4e3e07dd716c9413d1b9f3cc2b728e65a2cc654a789a776fd1a9bf93473d5f98dc6eaf7bec634b11e3d699615e93de3220e9a2cecafc9dfb5fc46bf726d3f57d7deca6ff44798e62d4d62116f9c4d172dcdac79766d10af1edf3c0e96f9b78b96acc54e5276ad9d5d4bc6ca3af38c65311ffaf1f12121253db56df329be90e7e0e08e1dfa2f69f73d7dc6b5ad91bb22fd3dfaa93d921f2d6a317f4a3b1c944bd97bd276fdd15ff631f76153448dd3c4aa5fb41c17a9254a4965807a09f7c33da14928e570918849d149b21e39de5fe2a75c6c5b0f49d216857fe4436634119b3b945b02d6f6cbaaa6e99a451f36a7cbac0ff98bef97b57a44561f36274dc4e66f7d128df59cbd1cd4b36b6fae4cba9e21469208a294861b9342e1c6a4def958c589d518125b8031d7ca5877ff588de9d7816d5dc99b1b224a88fcf9e475469e20a08ac95a35ff65ff45b419abbbea80623e953859fd08931f7b1910f8b792e0be95a40dc148b25e0ccb3f9bd9bc6130b28a36e3ad2d2d2687a66a54d0ad2b497eae4663ad09a52cbff195c7d42a595ddb5a0c358e52af4efad6718f6ae22d8283cc13672338bf1038bf1038bf107a6352e808d384b00fce2fc41b61f58f3867ac4f43aa3d46d82c6d9231d723461808a9f698b00a2b476cf303bd866ea50d69fd49cab3b4d7f6d42af9230c768493603ca4796a957c9da76020d5f28db042e3efe8cb6396f90852edb91593e311ce62cc6fbce43390cc08a8e66a82faac94d227504a4b9ada5b9c423a945297eb8c7157ade2e80cea8badf66a60d1d43629a5beab7f91d7be88526f87d6c02642e946b9cb7765fd59fba255dd5567ac7fa4fc0cf4b35c93603cf423ce397a1f4ab90de80051ca55c169a028d732ffae4ccc321fa194cb8059e6233fe21236bbf9f7973557d8cb60ba7e16afb5e48f309dc18d495d96583482c930ce26acb665b06dcbd8a9f3df230cdbafc91a538a4832a588941f568a483abfcdb9c69ed427424f5c94ba4b84b5dcb5edf8f98bea50ed8b6a79df777cf38f37f9f38ff9835c2e0d33b5266dddaff3636efd333beed3a4e97a64639c619ae6728936fffd59feb1fe116df5df37927fbc2f84f30b21be290434f4b38c34c4a4b62d5977c63d2f5eec335353d3e3a8068d3c483fdeaaf5e7717ced13c7c8b2d1b531b26c542468094dd723458296e4bc53f4b3538a4d6c7ed41cb9b961ad889462931f97eb2a6186a6ee082e4db4bb96789ff58e2d9aba36ca2c945394492825c249eb62f3f4f1b718c3bb956b49438a7c02114e5a4338016f15222b401e29b202054396b7469ed0a8d2fc9eb2734848923527f47acf22131419e0e82fde453c4456a0204956b1120d40084d1125b167582a28114ebcd5dae4a9b51dc9138b766681a8ae472fbb421b012da4e03eb18f5fdabd33f656b5db7a2bbfd1df1a4ddcb5ac9516331b6393ad219c80f735c362968059108a2fec8bea0e8beaf6b1ca7c20034366844cc7fbe0a1fc4ccb6b64acc6ee1be5dfb7defc4678e63d0ed6c898d51aeb13e79fdd3ab2f0f6b17ef65559234db192a6ef8c42a8e3080c406578673c32ded005a54438f196aeb4f18db44b11adf80225c289b77478bcd61ac209de38571f2bed45da5a64e87e511d7a1d3462f16b6f6b637d1db4ef0bbd28a5329aaa50d46228144ae57d087fda100a8552a1941ea1a97a041c7f7f36c958e83f546ba03414239442694caca67619f622b1925eb55969f9811cf46b9d8547c71b7cd0aefc4fad2dfe1cfa406d189e2838de13cb5ebc9f5f96826541290535de319f7328a538680a2685520a4453b020202b9ba26f0bcec05fc14e1494150106bdb6ccbf7fd43a868a7882525abbb5748c878a382ac229a5b36bf789b3cbb0d7ea91e3ebfaac624bd7234d0418faacd5b7f517afd54454912b113f5028940ae8daa2502815968e196f8dd13259a687910cb620a8453ccac8b8b4b9376d45841ec24bbcf5998342a1546e8820619c526c7273c35a6dfde3cd0d49d61c97eb2647d7845c571f2242a4149bdcdc2c2182847186e0c0103f43b8841883523a044d09e1840a4d09a18410ad541066504a41ec3bbec47ac7908b2dde35b2b663e3bbc3b5a591a74ceb17c553fbcb5d3b433f3ee08fb5bcd8debaebd3b6c6d6af0d6148b5c43e608d246bc65e2367ba0c9f76745fa0b7bc45560fa26b6283549315342129a87b729a841e03fec75cdb7ccfb2c4248937d20e132728a53f34c5c4c564c7923028f8d9ea1f758ddcb9f6e434f1daadb38b49c7b792a76877aea6d720255750b20425519424a1643504c65007869a500abeae34319f664f4e93564c8e194f52bc56db226db3effa31afd592b455862d2cf48c65b4d989cdd35b3563990cbbdf99fdfc467848e8079452219a128a22244b057121e808a9a0a4a01d945291a6809001a5f4079a020209208028a54d680ac80c202a8042d06bd5c4fb5a570cf8b15aed71f05f56c3bb26c6cadf36060c6b7a8c3cafd06ff5990cfbcb5d612d572b5ad9df8f851e03ae689ae0ed2c1608ae5afb7eae40ab9a26a17f4cb4666d3b495a260e6ea477855bff187accecdaf1d6a39a471936abf87f5d57bf5f543749d6d63d4fdad6ffb2b0fc6d61ffb2708b6fe4a10ec75abab617d7aae9ff4540bc9dac2226f5fe126b1ffa690205c03fc2dbade3edb55b7dbc35dba76d9f7d767d7a0d6faf5ea45f3f3afcacf8108152ba84a67ca450aa6dc6de7285a1c7801be3a01e7785a1c780ac6a7b729a3c6daf64f585c65244d230f2f7785fa77a30588bb968fabef52fce21c99af3fa8615e4f456907355837dac564b12e3184cdbfce3c5a6febc4ffca5ddbbd6c6fa4140452226716af94f204a110936ded7496290648b96bbb6fe11f6430428a5eeca5806d66e7599f5d6cfead6ae756c9bb1cda657d755dbf1c7fbdaabef9a3face971b6c63fc22459751cc4dbbfc892470ecab0974fdb7eadff91ebbb352e5d576fe97ce2cf759738cb6e26c997839accd5c88ff02df23ff29de4f4f1331635a61db90eff629fd0653c0e9eae6d4f4e13dfe45965afe3208b24ebb62eb34ee35b9f44fa5cf9f8a659f3ceb69a0e665b4d67857693674fe8e3b7f0ca65d8e6478dd77c512563d66b8fc4416dd6bc7dbfd6d567d7eab7b36bf1ec62b096ff7c42da6a54fdc958bd4a3e9fa4ad45c6bb495b848cd5abe4c998ddf98d2ecfc63e3a19d3c45b3f68e37b6b8edeaff5ab766b0fc6431527c95871b08fd01b6135de4ed6f3c9fbc78cb0fab36beb9452174ae9182997140ae2e8c8643fe367bcf53db3c91a6f5de5bfd7b674517d5363f162d776c4f78883ac9507f5f43848c338c8837a7a7cebdf3589e7b20475f93b63d76f542b0d1cda18e78b636462e838d65cfb22d897369bb93e29c2f6ebff8d8d5e635224abc626cea6b6a3a56951db52463f798eb894d13f1b6d8ee5b28cd130234b5698f95f44921596efa9b24af520a5b62d69f7098bb9b6ee7be232e6c9a2fc652e4b180104408af7cca035abcc0c3803d2c4886fb46dac07590f21a5ee2aa287937e72ac4f3adeaeb78db995c94eede36f99a569ba31a194569ab241bab962a6471135fac9daadaebfccfac4d6e833d07e6d5a9ace1f2bbf8c296dfdd8cef5694f9258c4e3a9f1786ad8cc6a1ad848629afe4cdbb0af76936709d31546be78abf8b11afb581d7283528aaf0f800247a096521a044db93640cf32d6a3069c89898d316ff3169162644a114946cbb85ca58814e3ba8152faa2292143a0947e3425a40794d230145d1b79187accfd7190b563c7ca75e964bdf9f7b5aec7f9dfbcb91922f2a4790e11117fc968614ab200c3912754d244498e6dcb125f6fddff1f8c8d90e46b280c18a86a480b4a5dae1bd1345f3c439b901384a010ca4240423404b920746f85ba1586dab523b3832474852c24ab9f1086f4e0ce7d1206aedc91ec380f477293b72652db3663d9d6d87c3938f28437449884a1cb70adf9b7ec157eec77a8f5e719ce667e13ef9f39deb56afde25f6fbd788e38db7ae45e7fb420398eb6ac91b4d98965a7fd239a585f58098e093c0c21c91082a87c409f1a3ea695bbcb67d73a11ee1a422646e63e09d330da3e5f476e6e54bc75e3ad202711fd7767e4c9ff403eb52faa343084854f13ab5865d89dc6ccf27b9c07b85fc3f26f6cf483069c89896109796bc96ac9cdcdc8e32d216f65a01b1f6f1d21627e06cabf6b16ef931be3a09e5c96fb8590dea726fbc7e11123bf790af1644147d2d272b0e021a98ae78718a88a27658b848e88418f7071240aeaae96d7ce98cba5f7fd3bbb562ba114051ed4d35382940f4590b6ca827a7a7406614646e0a35f353d82b08845cce467a3cd38607e8db5effb252e43d7b696e7dd2992e19783b52f729d4712d34a9bcd6b49990cbb66d7ceaeddf181eea4a88e182f1d2d2878cf59ced1fbe800513063afd189f9d6717d28070c0a6ad6675caebc762b12a539beaf1dfda5c221831ebd4c85332556cb7fe42a9c26ba1ee1acc0baeb4b0c7c5f2f1a055f333e08a11ed5bce5d8e766880849d61c22372311f197f44073f3841b306eb0b851c08d4b7583e2410b1a74718d8cb9d85b392a22dc098658600813d5909c212c2e12b8aaca9543c80e8454c10a4397d995eb9606c3fb640cd216420892accec3c356c656db8b7f1c0c6942af91d6732be4091206a909920242032047408400f16c786003c5e6870da7faa105d50f2b543f6a3f747c94e143023e9450f990e90104550f1bf44882528a84aa7af450d55ca1260a4ac42b67086fb93c2626c677f090e19759d2f5b6de2a7f5b570cf846b87c1ad78f0c8f90f370a11926573fe1ca657807b26233f45a4c043d140a5b2dadab9963844e5c1b6f5db9ddf8bac2ad6daea27591aec58b3dd4a13e49d35b341e13ba0c5799ad352b2a9a2dd00481c60134339a1d9ad2cc0866629452d72709e4317fb14f8e8fb70ae13c5c88d50fb8c9f3c96a6441d3664c3b72d60a1653c72f4b1ea4da03ea6defc91a795aadd54a8679b88fd0c1fadaef9b78e87d34f639fa22180fc97ef6f9a3df667c79b0cfece2cce40827c1196fea81213fa03744f6b5d87cdad10d11f197648c7789b3ec3fcb342c04ad70bc5854b59cf20803ef9347097824510af2f851f1d01a93be4fdcda676c47161464e9ff1d3490e519cb543b7ca094d2fd52b1cef8cfb2553d121a9fa62b29c464dcd5fca0fd1a27d9fad419ff088f77878584c30a4267d75f2b332825ab6a05065d454129c65bb592e14155ab20aed22185234cfe6719ece8afcb35043bfaabd2214587130a0efdfc04dd9a03be18bb4a763843b5c30d543bec40823990e5a681e016cfbcb5bb4abb0120440811e110feb41d6a98810a002c000049c15a25f31b61dff8ee2a446eb122ede850840e3ce860c2228726aa1c00a08209028c14158c510daa82a1c1d4f09285170ba85e8450bd80de04df806f4ac11247c7f1ad655c7ee9d77a51a8abc3c2f19e64ddfad471b986c2a08b5daefbe31ee30e8a676c0c61b78ab0d063dc5d41a0235d72fcea9ac763c07fa17d9ad7b6c82ada6db3d6f11830e3306ce9c8e355f9a7c2a10b150e02c001c80d65a86ef08282e1c63887ae2d2b5cf9e7d6f87ef417b4d97456c813ae4ead2d38fee7226155dd60630319368cc086d086961a485043025435c05435fce44023870672fca868d0828a8612509a833bb875b65a4776d69f79afaa3bdefea4ef8ac47a4d56d9aaa52bcd49b2c242af4f621c0382a0b8df5b7a56f3d76eadc572353f9b27aeb58abc9239d662857e3559ad51fe5b77a56d0d7b3256619eedbecf83547b6e12a4da03daaddf7d639f377151c647fbaf1ffd9d0167c01a23c765f57170bcad9810762741abc3d04f9debae63a85fb7b44c867facf94b1c0fc3203c0c4347c2fde68648dd55c75bd95b374464e40b11292d4dc8ac3d3fab3cb8bb07c0dd9fb46689457cc330dcf11c5c6f7b4f0faa6d3bdaf389e579234bbecc7f24b3253bf57574edd69e1fd8fc806a9d8b449ca448c449446d4bd8bfaceeaa03a508d58d277c490d5475c389036dfb860eb4092f90018e3646c60b5560a1ed082fd0743620504a9d50958d336cb48082a3f61979f60b8d56db245b5b1236fe262b0da6edcd11224818e70811945227542a1ce8f84f863479f5b85c3e6c74fc91eb93b6876c6c245e2cba8931e9323c64bf50fe8d977c2d16e3463849925729a3c77be27c23fe1298fe8d8d6e469e5a4ba8a6d2f216919c6dcb128b442e172cbf19d3e70f94fea0aa140e2a172eb890a133f82e5550ea5a579352aa552e41287597bf5c6c1f87527aa22a9795bb543592a0aa5102d05d372f354c77bd9c4c54357c7097aa060e940edd6820976b880812c6d155fc25aa161e2c658cb7e24c62da51f9b45de25d552c48585a2b61ac24514a81a0aa1519d50a55e9804a658361ecd4b0f16b588f5a35343b804296be95344d9d7ddf7ae4639158f1f62d9eb876316d766dcc3df53d71cd653c7e2bf8b9ac5d3c9eaf4d1f1f050454152b5d613c2ed790ead405d58903aa93124a6912aa3aa1549f16aa6fab3e1c27a84c50a84c4554a695ca840a4327c9ffb196d55b61686ff5d69083ba3cc56c8b7e42cf61e5ac7e2a8ecbe572e91f570e6a2be3a9fb4b5f7918ba6bdf5abb35f6423018a8c7cfa112f0810a35766a5509e98b54a52314c44155a515e895e1a3f2a2a0142cad6b1ddbbe9125f72351795bd5f1a0bba2cb94d21da8aa4ba2ea4e2a6e0746a88a3b808a1ba22d97615d62f163fb3518eada1709a9b60fa83627549b8f6a03808ada4045ab50d1a134ba9046156920a55184d2d035c6743c266c85baf64836d2fb84de0a653f2ed75018d3f11870a5470bab7d91cba5b7c6a2bf1cd46fd65834391e03d274dd5a87c7ddb2c87aeb972bd7e1f18f81f9597a55fba2da17f1f070e479b336547b24615108bb38ccfb673431d7d75ecbf5da9835bfe88d405dfb22ade35f337170fcd3d23e63cdb3e4857d6a8f64d4b547827db00fc7238810949ef1a2747659ad211cfc8cb79661cf311f53cbdb9d0b01a51c08dee64d29f7014ab92c28e5b0a094f300a5dc1534b5052ba4b640066705a55c07424a390e6c618b2d20e9f06cc1c55ab979faebbe11f873112d8441c92a7eaeb70e69a10a2d98946ae1c89116562838ca8c1fd366e49005276421075970220b4364c1f398cf32d9bbb6fe58c87105225c210757d0e20ae3155aac3086154260859a1574a094b25acee32e1de33e7e6ee12db3ee0a438f01b535718ccb634056cce7156c631ca4f3192b6ded56bfe4d3aa605485a12ab0aa50830a25a04216540829bd5889c714b16f04ceb2988b6f9d59acfd8d98821553b053b851860aca984229fd5ce4639f65f785ebe7224890021852e0420a5648218a149090421052b0210a4a88c21694a599c88cf5839cc65d383a1ef3437396a1eb6dcb1d30741788f4e3ad0e227dc6af8d7d945c9e8d7df6fd5bcbfc403044010a4fa094b6a1a005144c90f546961ca1e0e362ac1deb2770e109270059e3ea8dacbdb9f1164d57d8f846e88fa59c70052790c00946382108a54fdbde04322cd084254db0c1841a3081092610a114dc1867afc5ee0fa8ab8f9febd63affc6467a666686669671cc48db5e9ee4cbaaa6cd2cad56c9306cbd765d6975e6fe02d2f1790519797dbe05491c8e3c3bff91eb9db16cc70e7fdab63a3cbe5ffbcbc18c5d861d66bf8661e9b7a22df1c5e293b75ebb3af30e1dfcd93d3a0259de22eb9d59bd72d77eed35c742180fb1504a85a0292098c25c331b738c5f9f15e88d6c92df750bddf854d87843646b9ba4e6331a99c9aacea08c1e830963dc60bcb6c85b2e2c8edfc4182c4af53dc217c9c638e8a8067d9efd28d62c83c9648fc5d9dfc739ff45f0101324b446d2d23c83236969e211a8a0943e4945c08c23c8e00a8f201ea1074a29a83ffb9b58d47e6d517d2664756d44d094184a80db9656873592acd8bcd567559ffebbceecd66f74ed896bf9c4352f12ebde158542a9e02fb10e512894cad15f27abce2059855c2ef197e0b860309f1f1ea1a09d25b01d23afa09f212118cc453b33ba28c4fc8daccea7f84743c68fc93afea86b420e175467f0080044a800118e78a1c50a2fb4844184d05dbae61041064a81c837fa24261ec23259fe7ddf3c7f2c45a4baf5eb0cc2ee111e498cc5fbfb33cce6fd5906cbb0fd1ab65f17614cc266d7628c54cb176fc566594d0d43aae53e31ec4bbb61b5180c8bb0234cd3307c61fb356d8ff608f63491b6717e23aa8661f21c7109936523186cbf46aa25cc2c4f180ca996f68db05ac34c58795e18522d616679c2f66b18b9376c76edc646fb754d84695dcd5a0cb65ff760a5072a65f0800c0acb0f6bc9b86b7c197d92663ebd45295d020f1a4029a5940e8107413c28c28316a534635829225d0b2b452497ab149178b0ed400830b2baeb3386ede0891d34a1608ddce20e82505d5f3ab002a594ea7af4d2c10a74008552701ffd1dc7d738e6bc72a07ff6a435b2d974bdaba83f270760502a235ffb3856cf4115360749945270e3eb39f0a18684857240f7c578b748328b8cf7100e8aa054ebb8f6c6e51ab2a1396f86881c21c99a03460e5f34e10b2ebe30bf08bf40dd40043780c00d746c50860d78608307d8e008a5343ebbb6c75d3f3a3f43d7b65adabe3eb73e894e5cf3cf3a4e5c53e2202b2cab2e5b2f8bf4a4ec8dc8fa46e323e12119a66d6d8f7edf9aeb39a3e9cf32af7e8faa29e4c509bc18bd384229f85e83296ad05383f12f1e5d66bd16c324498310d020a4c1cb0c8630030378c5455d64418d90010e9490414c0c8810830ac400090ccc80c10d608004832218ccc0c51328a53b0c8b5847fad063428f09674220077535eb39b3b1b26a1b7a0c88770ec35a5d834fc6ecb5d7cabc765fbe63c76bc70e7719f1e1f1097a3101ef513535173cbc20092f40c10bb07881134ae9786b6d8b15e985f46adf2f351886dad6d0051c7041e9021d5ae0450ba2a094825f8fbcc60ac395cef662678dab1e30680b30b6e0c0160bd8a2670b1516b4800501608190155c610556ac40c90a6e80401e03ba5e1ee38a0165d86564a57dcc2f2ec9fa397419d6f8665d71c2bf78571d9a96a62fb656c45a57cf587f3ef729fb588c5681112ad8910223a4a00729b082520ab28056b46dc131564d30cc1f7a8c4b0381e25542370f9458c8f5cc127df621337ee343c6a7e9d3f4adcf1f82d884345d8f84de0a41960dcdcac70fbd9298e6e56f5befe71af3a5dd4048b547867d759f0459ab079d87d7f4083dcc788bb5c8fd9336e4600d4397e1adef499a5ed3631cc7ea35a4375f571d70ac7d51c85ac9f01b6175e8dad671ac7eab51c6b52f5a39f9b4d6e7eabad25e8ff7c44536f6d9d8e7c958bd4a2ece0f847dae1219f942d8e7071ba794c2603058cd24475cbe59dbb0df75f6e48f6fd6862e96bd4e0d09672092469255ac21e1fcf271bf762cbb3c58762d4d575ac6393f8c52aa034d89a00494522a82275e267d89e008a594de1f11ac68188a0045c1f1cdd7f8414f9216c9d1fb9c425a4c01b5d029ab161e023042f004ed81a64270848262ccc5d775a58d56b4a710089c008230c462c6392159c51df041d084cef2791fe73722e6826086523a62f1a6f6488888bfe4a6f6486a8fe40312f8c0ce0760b21082e784ba487cdae8fbc459106551031661504ac1ff5df3298a47baf645b1539f5e2377ecd8b103d4b52fd22459b190227b6111caf07e212c6e98f569ae75e06c8d62e56bfd8a3d130f1cc1035d501ab2683c20e40a255c21842bbcb8a2035754e08a9e2b362bc8a0a0b69f772dbf91054356ceea2714693c0664bd91d53774b9b085993a5c79c8125afd84eea2f1981076ab18228542321ce684214bc87978ceea27f418f0e8af9015596c5b06a966a814f08be6a99e744c219a111000020000731200303824188c464442b9709e44e30e14800477be5e90509989c32c8829849041c41011108101001011481b003d5ae49161de31ce379e668701cc2e332f29c345b916b387b81a621c08f0eea419e060153114d3edd70e8f2eb665c0beebb791f5b4eacf4368e324e80fa288c51efa52668300ab6330e4035d1f206ce45ffa2640392cb7b0a6a3e7443f0f7d7720c93b158ba298a4f4215c2c6f7bd8e0e6ec838a3dbe4bd074d5acc0dac947cf7ae3c475be48e7f23386fa9d38603478161e6d7f6a6460e9503e419b13eab3e148fbb23459f3bfca5d670cfa3e2386def5ede69d8e99af206435bfaee23df421bd5308b456158b5447e2494b4fd06cc5c34dd760f929836bcd1f827cec56daa5b4d4db9c029596e13d8b29cfb73214200b1932e3399f54539cde57b0afbb3a147ec1e86fef4562662f9eba99ec7dda765b321333ac53871756d3a23ee4b9a46bab499601bbb660bb455a1cfc2d6d8a0c8a419c1aac8072855e5ddf5adb1c0378430372d2a766b06e2eb6a8b61e440983b88375e4e499b160de65e0e764760743296fd62af75f6f28c9dffc350501130992ac50edfc32ece848e928ea2e0aaa5c83149d7d9848f74ab2c54c0cc09e337df0d2c5055fa8fb6736900cc948ae05685b023d53630e498bcfcda1df55bb9cb210fd0a50110f546febdd5dec31ec4bc9b620f5ef4afdf2089dc95c60f9a106601fdd86ba03a58dd6fba79a2cf64e7c9b3f35886060cee43a015e673a511088391edd41f88fa036e28ac664d24dc75e3e6976fc4f6f7ba4f3aa8e1abb4a5b5e22a009dde24d23688139316b1cc6ff490d7514388ce9b840a123730fca8892e0269df1293fe1a3421255bd3d4cb5967ba99f1caa02ca2f240ac5423689335accc77cf2e70a1f21fec8b48a577f86e4f907df3ec2e5956996db8fab87ff2fa582a720e339ba7acbdcdba2dc311473bc42cb99f15ca42a22a3a5ea8e849ef473caf5e3797fc184a916becc45b22e7ea0320c66edb76932bb99e40a58d67aac611dcd2b14c6e966ae7bb29ac5b77ae60192281483e569c9dcfd4f4bd1343176e5a60430d9f97e8cfe707951bc22c011d31ae7e1d262e1328994305bd339a07f94b0cad91221d28112ae02bf72652e66fe932dd1852595d7197a0060aea580c8437f6c081a17675ab6cc07c0caaa6ea029c052ed65b90b7a0f644d50e7ba00683a38ee9b40e8c8351cbeecd608e74cc75fa13ca7faffc714252971666823e3146dc7e02a4e515106a89da706b03b5b8bb1052594a5f3084866c3f4e227f02360ff4c504b037f04c3eddd389b2303a98bb4aba4182cccbb996c9f79fb308cb515f4ed0cda9d959b2ad3131061b08364cf1411156517ece4c6d94705781710edefa48b069ecd8bc0c66f069afccd7eeeb209a485267e882a989ea386422f7fc7a1f15d2eca27da1582cf422a7b880db8e4bba42faf2794f7a865c00571ac411df75320be6712e2908ed32fb409d4b5c0140d70694d385598aa3ba7981523d37351d6ee68f262f6f0e3753724629605f02fca4a441d478fca230ece5fa7d5591241e167034ce3af6266af8ee04d07180bfef78691ab4db7624f03d771196012c9fb7923dedbded529f40b2094244a9105402373b93723a87856734c1efb9178aa773faa2b208feaa9c3f08512a7410213c6141a22a097449180e236093cb2e6dd2061e3d0d32f950a0efab0c740ca1041a5c3c2d06a8e6254ad92960f6fba79eb96a87eb21dcacc8657c7110b3d08c9883e16d022fefeb23beeccf3be362682411a931698a209338a1429b513652a32a4d9f1a9e4997857673161b4452ee80b27102f34c48ea1b283ed58278fb0dee0b2af05c030c24ca02b8e45adbe4b893d5a9ca643190599359ea61809c87b085fdff65382ab6ca1d1452f998ccc4d6bd01731c523f6b1463e8915efdbae2695dd2426e3e7fb546b9c1a1af7ee2c6c5aa56dfbc84c6266fc8bf712e37e8dfc4e18cd0b537093ad3e5a0cfbca1be2ba509b50d6ddf40f061c13b794212e722e42a4d5cb1e42951a20bc38096a673094961d7a1a4196d43158bc9085278375e1c69f4dbf43e49a966efd2c7e16e79e4483dd4b5514fdad2bc9d995d3ac6630c7de4fbc8109acf9443376e02157e6fdbb84b2dc10a501c5e8e1b5ee2efda2cc59d63ef2ed819a8631c714c0a2d1c137e111c1576e178130699449db03bf124e0f94ea8d856e0f17f0cf95f5982ccdf97be9d8e2d537b3904ddcf8546a83bcf3127be86136b2a3b532183c2af6a756ffda5e471d6974bdff2adca836c759bd7eb577d80396a8f29fcece9745b987a4ad772aa3491f38b53a44310b308062125bd26cad66fd44484589eb2ca20518ecbce3e7e48ad3253c09474489c93c98e3246c2691d219d7982eec2dc647faf25f71ce6350a00d4eb379aa4217f71b25240607cd58c2335cdda919303743a069172be99d9462c27d1d6c6c0704724898fd8f79f9f93aa69f07c2fbb139846ebc20d10331e8d0a2ea3d32e550b2ac9fbfd7304105bf23f463245a692bc0caa94881e34e4460d7df5d6ccc8d81383c2d45a3b73ca6688f28b272ada7a917de7013bb2924b65ca59fa5040b3a6fcfd6c8f843d356156399efe98e16eb48784f2c6b00bc9431535216a6b244292282d67bb369eb3bed410b224d7c82b91f5e99cfa90c4d4f369f1fd949aa0081a4c5be6d0eb9cc178cac17a25455c91530309cb3a2d539102f5336c5ddb47b610f2de533b39c0af2ccac65e0d987f47c0244b31c68ab9865507f6b24934acce953a56757e07b3e52b48e9534bfe8846d571f29bd3761c650d6a045d83685e349d8623927f8f734b8667fed534b0cb70d115bfeabd6046c073607f6b4256003b831fc32473a31101dc249593c0142f85686911276681b7a0c09dfab4ac2aefb77ae33bda31b54703167834ecd8e8c0f3d35715993af0327bb0697c0f2ac87a5c0115b7081bc274ee07dd4138aee6af7208ae374651840161177755a323f64544aa9dd7e320d50ae2e14dda1ae0ef47ec44800d4e662d3ae85e2eabd2dbc629b795bb9e78c29649f19969a583c0a3bc29f318faafa9d4ed8f499b03bb29c22f21f2d63409512896dc84b2d7b834a18bfaf5c1ab6e457100cbf7331ed3b2b859f89a555100bc2a5f2a4d2f6df235f910daeb69acb07037ea74846ef0cb18851b75de51bf3ac8f45b71dafd0741106a94c7d2d63937f4291e04b8e73cc682b6c18e02f836bb0706424c36a0db252383cd9dfc30b3b14768a7263323e9c6b7e9a0e28d16b458ce233883a44cc1e2941484bfc59dddda2b228cc6749ac2198302e2071dcb92850048fa991de3961ca5cdb3e4ef4cae96c46dc932538db9fc4b5102260970298989269370948b50bf1e8959677c388fe1af9b4ed3aa189c9963ca163ff588a91e02c16185dc6b46106ba54721e9ae958d194a36d767c746a08cb26b4dd9c43dee07923af43bca88c7ba8c46f0d85bd70f3dc1980effd11847b4fccf0fab9d7b0d07a76a8759a425785d337725dc62254a1382a821e1f0e16ff77c7a01790dbab3145c168e4ac3293ff25eb619610a09e47467b948de1157a63ff12523f82669d1fea15159154843b30671d779e900d8527d655b484fabca6d38b09c2735b2fed84ca6c950aedeba6bb371b2bcc7a40a09b5c42ba0c6cb69778cfef56a03afe0ac0296993a6ea4df265e365519f64c933f8b139ecdc1288cd27dce3b3305ded3080244c6f0528f6db646d55ab179d6c8809c3d9d36ce7dbed6835827d9f6d27cf9faa5fe79a04847900f28de7594268966631cfca3a8ef31bddf610578d63c110590c1739f7c49270db1dd1f915d62fd80ef05de7c4ca81e9967871aecb2279a15a833015844682dd38d80326f0c0f206b8929b09723e857f900e47acee42bb002b7699d240832d881f0e33660b911b060c6d54cc539510c8f78c92a0ad2fd4172c6c2ae66a31b11092af730d5f6f678de5bb5d3094e1992121cc90dbe96f05e7de6856835d5cb9418a6f6cbcb16b0eee855e1d20d20c1cdc9cfecf6982f21c7e520907146ff827a8a2bd66164c39bc4ec978c52e1ad606048d420daae8d78af3564d25a3a0ca9406efd99afb9b08697796930d854854cc61ff6d00b3957353cb6d7681552f881f175afafaa67760299d654e67d1f999fbe838bdd59dafc21e8a4d23cbc452ac9ff5a6ad4e0223f17493abbdf50f7332b74dfb9176cd29b716a7ff09510dbe75f45f110c54918b98094045cad7f96a5007fda8e31b292f6328ca8f572bc6d2395aa02d4e5962943a7c5c9ad7d8c5ab93c42b8e675ad1bbe90f1962392c830e15fa0db2f6634459461eb09753ea6b19f85fd5e6f85a2f91bac38a1b53af8879ac776f8ac77dd452e9ce258b9c3087a1e8ea20b16b27c8ade881256d9595da20b0a880345e3a4b348e94b82433048dfb014ccbfc2e017de0bed93d111aa59d06d83aa113aaf36644cf8d4bec57d342ba03992990a0550194dbc22bc6acfdd438774ca95aac54cd1f9265bab45812ee7b24d9f2a4cac0449759e0c55a60c7d3c742bbc19102765a6cd4de3773d544bab008740902db491e38bbbbbafaffddc59455fd18f0412e16cc712674c1219a63649f3df898b0169518e3786e40204c94cdd3be8a3a72f10f7a1da3bdaeb66d897d8c20f4237ae6a0f6733b8fd7347915356719b22e2e983439fe36ca6e878ed18f808c39d12b577c43b466389a362c03b9e34f2a1c35af062e1915ba1774a317fd8f865ea62cd25d0611dc823c5df2704dd0d9606b6b02864fbda3d72f486da488a62e6b28880667697845037d1e6bf4b2f5b6d4e718ff7fb02c31cc8e58e21c05e4c85f8474e12ca92b66225348ae45efaf861edab403934476fdc206ac45083fa44d36f0fc6c03dc5c2710bd00819ec52c93d3557c61da11d0f34c5005b26a6f2de39609a82c77b746ebbfc7eb6b688492d6e714553bac5724b809374073a5b98ee2b9b01ee77731cd182504fe521419b05a074f84c0d676b4d76ca61e8308b51c12829c45fd1ff5cfb91a3152ea0e1c584e82453eac619dd12c1bdf14b91f90f2805cb2bdb8655fd71e5f2d6fd393478c934e0eec12ffa9255118538f73725a0ae156cccf7f1d7fb9e8df529e028ae301faf0eeb5766c65c60bf0a7f777203dc337b75ac62db25213fc7a805cea9bd48b1c1eedb15a4a7da22db509088ebe62a3d279981a960b495618f32e4079018304994b1daafbb367ce929782554a6c5c140bf006cca292e4282e03ce803346b7a91dcbdfa7efcf61eb8d29a50526fcc3bbccb77fd8c100d4619118dee883da87f2b5287fac651a6544e9ae11e76f54bf29b44f638cf59ce2fdd47d7c265b69a92c8a575b03d1617bd58abf2e140034e8cc70744cc5978058de61c0d3bfcce515338f17539e9fc1fa55af94e81b9f876ab93c7ca033d0b84c98565f20602c8388c1b4963f5a952dbf4179701748021a5fe6b3b6892bb94c3428caf1c00c1c5b8c6700a12713244fdc394a532ca73751bdf47c2732e9c4ddb6acbcb7e50e971244f970ccc845d307a3cce0cb6990b9ae17321062cf80a876992383f8fe6668c0f146b8cd0a301e42893e001d9ae383e5ade431470d213ddd7969320739d0eec87208f86e9806c7931c0a8a309784b09d36bd1ae12607c60f77b1d2151ce61139ae3c80fbe7b2a5e7a2b12e7d4e7140cb3c131b1105ba17363fcc3796809f5ad042d57e2607ea70ecaf38fd2aefbe5d0bc036433078c1453461dffb4c3ae718c7c5ced7b5b68e7c2f41794eb3499213a772f1a45a9641e5e69f7e62da95ca2e4f0dbf63a8a1e3f7d65aec115425ed2e77f05038f916d048f79b93b86af4f79d2d7e804cdaae20ddcf114da9f7bc208d376e031c278221ec1e8a9f80cd62b5213d06c47878b99b1c421f90a9747e64ce57238d1bce81c8ec6aef7921c251b4c8fafa37bf2e5f99113d6d86552d6309f6d2e226ded339e46cae1d429f6c3d4a6ba0c1b621b0d27174973894703d36be641c81c334c1891c0c99bc91569e7446eb8ab50af194056a29d239ca5cf1a24f0b29a031c8c81212ffa00018db0540641d730c1eac2019ce9af0c2f1ab0274ee827ff9c636cc81dc2fb4d24669b26f7c58c2a4e58e0af097b5d7d18c93040ac5da58dabe13abab9a62136e403208891b5a9590c641d7fe42d1ad6535c4573fe06e94b1532d2ad88773b2866ff12536d20f6aa01df320d09cc25a55f61b6210c1d700d73fe4b073932b654a818ad297841c4f169399ed5e48010c628bee0f50f6d6eb1105e534645f6d3a4d240cf9374406ce16d87dbdaacde13f77122c0392046a7abbf6da99e1f075fc98ba56641d3df92fc1b49ff8c3565a2bf8f7d43124fa491aed2bde6c07c714c64c958a12528fa41ad80f2a5c860bc02bf8aa12e40810c34c3ddad03de247d6a799cd1293bda628fdb0aafbff67ea0616ef344281d64afc13e951cefc492ec66b2c37ceb365f3dbb286d481a67ab2da950db6ec4ab8cd2b028fc6724dddd19a221343e670195e3145a1b9f8b67f9380d9772924f91b90cd29237d249e5cac0186244c2108169487b8ac7d841615bc8e71988e62815a0971e87c847441d29b2da5a86bce51dfbb7a48f6ad582b6a71df219d98d4c0d3aa08cf46d897c049d4bacf45c205f7fc62203f8d296b1aeff7bf5aefab9a1bce735eac81181b88a6ae0220527acb8030f3e4227cfd1fb99528ab497b5dc5fd6108e7aad6aa77de45345e79de2cb9fbc318b8aa08f38e783db293ef42d3469e34e4e5604b93ce838c5592465669d10ee24c3fd959db8b0531f62619281b29c5acbb0e0ff07aabc4d5e4ce2fda6396af07921ad212c4eccb7e60406b1dc3131a57ad179c4c40672fd8162d449c03f765a4b0d08d6347122fcd508a0bdb1ff6a8438176f705bc46bda17ada79b8f3ba4920492b24675fac365998d24bd87e2158adb99cb5acc65a0abdf12a6dc74edf24a6abdb7c479c08c3e2a6db2dfeaf3cc64b65f8bfa4ddc24acf735c423d5358ecd65f24ed610b3de3d2c79768479e0d4dd3548e9a6b9ca30a3a52079d5b39012ca9df22c091a4f97d98c38c3e9087320b5f87304917db8d5001e11bc6f7fbb99596d49dd9f842ce6d70fdbdab2fb0fd6d156296c57321137f4c4ace3f81e974921b0ddf47d421298f145bf7f89391b6a8d391029f928f1677ce6da964e9f236a20fb21ba9b38c86104adc25620be060124143114a05893dc5d96c66d79b2d97473750c9cfe44dd6b279b461ced81f1e42787df7ee01ff45ae8c193c37010ed6582f7f641b1bc4a50bd6bab20f9472797e772483bc2787044727d193215d08cc76427e76489bef61ba8f83fffc087a094c9a08b3a0b152b97e172308737a351e8db0c27f41969a8ea2494d2b0e417cd0bfe80071936c8c1f6ba0d9a712b0291ed799472c9f20003ca1ad7c7f2b48c6770a4ce419f6122abed3ee1de6f928b3e672da04822036fc0722dd36277775287b5d15410ced89040f493f21ead48156a4e230c1e59f4d55ccf25545c7f5fde7caa061c083ccb3b1291f0fc5ae43cc5e6a75c8bad6ea605dc42a125ef5ee7e58a75b1edb230b2659ae392b2c3e3638870574a5ca907084155f29c3ab2875e74dc2f71bf54d186987da05b42a95c16b9ea69901fe62961d2c22523d7d11f257d6b53026c83000b74aa38ff806db8d5ae76446d7538cb1b3928525b29c3be8bc8933d1668b3a98945f959822397db0f331ef8ad9d2e39089704b21200130db0c0437f04939d0bd4e0bd3ee0f5246c6f342566672931c1430f5590a31182a842c64033e8275bf91360861da58ef518315214320b42dda91b44ad99c111740396de7a4c8076afe501d0fc6043b288c8f131c7f644035130b146d0db31cfe834fb02ee558bf036b417efe9ff8953e0c47c15fe28a03ca0d9a7cc7913ed4cc012ff0e25e981775e6a38746471c5eab7b21b6b2e80690d98fa3f10e38e77ce0bcdfd5cd8ee1edef4aaabfe330e7b26273b3bd2d71b6fd72ec73a3db28b329df1141785e20023709e0a79ffed74fcd4a4bcb2dcac2dbbb9f68bf80b61118923749c79d813f12e6c16e2ac1d41d2cbfe58738eae82053ded64dc5133a0d4b2ddebfae368e76e538244fb5aa413e106b07a611aea9b9268891aedad44ec57f389e60f873a45d7ef04588fb12224a4afddcab2cb968040d74a42355aaadfb822e0c4aa288e950edf2ec028139471f155f8ae7854ff3db2f708b00b29e3318bed6ce0ca4d8cef4edb803fd60efd4782371be311d765211c03ddb6a8ba39d7b6687cd749d7bd636d601981c6ce308a5465057e3bdc9d7fc4b27dd6a67edf268e5e373a283208c8a1512d8ca7e1a16f64523cc5202ff449dd31d33cad867f38e484bc2009a60ab0bc4cf07d90924f9d0ac8806d4a63b3e17362f7033d3fd2af51206140c702463b953b382427edc1f581d527ee0a12e9db0ea6502b09b001057869b3836ac005a2343ed774e05dbb7ed99ccf6384a221913f486f884b202803fc39b5d5bc8b62247a29a45dfcdb5489bd751d3608e15ac00036fb3554a63c10d98583823e9304da3f7d1af3f3b3a0a51c1175ffc21b6315ca45deb6b75682c2802a2c0da2c1f0c1f6e0b4e5b0a0c29e7e5f2b56f4a1c57aac698323e03b8e752d446068072084fdeef2220da7369f9d1e23c51511e31c35e02f00b3f2fdc5f649e4388e38ad4a4099f25c6153eb03202b9fad34d544ba88327c020fbd97a4939aa70d9c5b9a5916367d9a88eab32c1a7496501995d2d789fc2b580b1cf86a8a2b33ebe9b12733d8c4b84a0c246ba52a51bb5db39f8d8cde14665b9cf9e3fb4a7b75402da1f25c3b4174a4124e85e1127cdcab416f27d13dee7db22305537d195da098418a4f7bbfd40426ec9e5385f975ffb3ef506b301d6cfaa574f98c3998507a6dbe16a700b9c3240f534045ab9f018b722f03c956afaca8d69cafc065d653e0d8a5d78d2683cd628fe3674577bca78265f1a62a07ac1b0373900defc61ca0aa232ef73048642fd6f6deb4d43a93c194be09729b78a2d7b25cb5686c1a3a1fa28b93ff0f937fe6c096a16b9001b3d6e8610f21a57c1435af76504b6c6167d11cb17e011c6bb4120686835702ac45646cb307b34840c17422b64e3cdb2ce84a3b912cb6b1e6ead4db9704c91e82be1ca3f5e8c76dd822c6a2182168c78dcf9cefff3ff034da1d74a01e86a2c2399b38c13613efbd215c1e5817940a24a7201df06aa3899feaea0175c8d185fb6f82fdffdc47575dc4d8d21a6b76a1d108b5f0de76b33cd9e748e58ad5f4547b634ea4de42115ac5cdf79fe79b66e80d76fdaf0536ef7087b246db57f28700e643345fbe64e5faa610a44c7bedea1ac67dc93b050799ca452c8bd3cd76deab8e94e9cb1cc2b78c1e2c44d47d46c6f97da4d014d0570e89f40a73b253b2b180cf9eea34933f1a42f729d5ca166d5b4624224ef788097797d8ecb70c64fb858ec050bb51f04a200f4394ec81015dab6eab37fc586a5ae178eb7b328677cdfb1676878ac223d08fd8d42d74875d3a0f6fef26c3f5db09d3dc2d819822617831fe0d2ef67b5e972dd32f9b85d6dc9a33d481420b011a4b9b5f40afdc778f0b2a42a54d463b4a57902674db36afd270854b2d8587eb842aae0f34c0801fb217523a0399a56fa786be05c5d7298f4905d0d9ef8604d0bf6d807d7050b83d4366404f80b059a19a2dbfd9c7347935dbee924dec3764128de1f0107888ebe92a010a5b3ea8419f694206139ee33a359bb58fe918ec630c36cc13860af59e39b35345e4dc7c7ae0d401e1d173c1c0a8fa1437a325d7639c2c611c2914a72d8247b2de95d7d79e54cd57a023a7c61f01d6b6be2174b6d207f46b208bbc75f7b068786cfed52d960caf6d1d9e964b7300a83e639d0adb4615bced06496355291d34fdfa51f5fb96c7a1ff6d2f232cc71dda32fb695eb936b983be0e3375f7799fa04ec76aca21bafea3b600714b470947481e8ed7292191ffddaa581b0ca3f32d8f7b81f627f092e4448694273cee8be594b8b962cfd45577f2c28ef1bc2e93bf1f99a44c99aeb1af7f537af72283f0ac3b7a8439bca5365baa2dbe390327899950c5cce3fcb602333a1ec10d799c43fec7f52e35a95ded7f9e66e2815ece85f265051a54c9923fb54b6d8cf76bb14a8e4d1bf6bbbb15113eda433f0bac11b9075341590c7435548dd449fe090246be7253f199ddc65aca256d0f5cc73be221e650f7f49d2b3b185c8ee9a41e238df4c2dad9fbf339ff0888a26e9d42394a1585e49635ebe7c839b6e242be666333518f2f304a060d80c2f4206f017fe92bb0e08bbc778aae7db3ef1e4a2f66f06db8a2ae77c3457bf75fd8a79a037f7362d140ce21a2c0b86c3490851027045c866c7946dd9c8df5a1a090d287b57c34692c784df2154f5f4343432ca2c0c3790227210c08bf4b9e12b9c47dad1fd6da8fdfa674058ff56e0b8ff59e2fe42f0775000ad9d3847c64ca1dbdf3773c90ddd5264340c03bc5343fc2d6c8e92ae4bc5bff20ff4837138453ae97e9631a4fe060190a7b6615fdbb68217b1fa39212f510a69048cee38eb0cccdc691cbefe5f21a930100d3cf1a38e37f5fb6cd1ef51a5be5630a3f7c80dde57fbd3960a3115f5868173990f29e902dc50a79f8619df428d0e2272d83c44ef24903a0e2c050e62c0a4c0a202eaeceb7188abce3fad93c61dc6f1a705222f5164ba5ef6649f8ff616e3c415c57e0d2bd3ad8c6429cd2cf6cd8180bfd6be9ef1103cda5becb4d3eeea4465cfd230cd7953d7fb4807c80ae08345766a66b5851649708ba30b4a06df6180d34b8b0d071c97df426df0f9935c0b7346acbe293ab58049c829d31c01577cf381a7b5f566b03dd6d0715d6831f4e4e5f406e0fbba22d9d89ddb4becb8bde8d5a27f4d842d2ed90c5a85c20db9a4f58c5e5c434182024e5a54aee961a433b6b8f66cd7e225b47cf1b5787930f91ac6fb5a365083d4a5b526e013c7333c45505a667189f2159360fa954a219cd3748905994b40d4cd80c8f8e40e08f4f9341bb308af1cf17864b58a39a7b35ea65ceb6c3c8ff594cba05ec20d00d9f8c72b2c290138ff04637f0759eee2a5fdfacc0d065dbbeefa0257df104f075cfe4426244412503cf6c59ebd73a1801dbc48068b53934835c18d09cb2786f0979cf373f11b8d424c8362b3e1d3ab7b85db131311bc8660cb2c9109794eb2217ce5f1fc1443b554b490b4a0e72e77b8872930ff81dce21fb1a674216903d4b371622e6442a13409c0bd11bd92d33e290884a76d3839e559ff03f911f0e4896ee4f0a89cdb3190b66d33ff1f1c1e47cfe83c0036694b341281cf9d511c9b03328911378c0d97973d8ba454e0edfd4d0b43aa84e17ca6a588a24844141a81619fd81fbd604119b07e9ea0403aa4eef7d0c063078ccb8973509a40024980a6d1ca75a0cfe823a319048789e7665e87564efb2ae445890b21f15cb70b3377f808c03f4c8b89c1839dba0ea7002ddd0c475a743001e8a37da1e1afc965d8bd9f1f471119026c376cf19ab47233f869591a952a17ff73d21da7afe8ea000d5c6d0a144daf71103af1296f2b87cd0b22a5d0e8130c31c6fcc18d31372a60cb95e14bf2012098b5b67957529bd8a2b1d1a4d40b8db5c2c6bbb29b2afc3b76fc9016a2f6e87074e8eff07e9b4c08d57eaadeabb93d732b89da48a7b252472fb2f1789a5e9930f716ae91036ccdfcac1df1920ca6197aa28e2973f31db4af6a1ccd83e101eeb1d8d79988a93848b6344e827a14d25e7ebce216dc2ec1ade38b9159c8e69d3d6a13db3b1df55573714f0eae6dc463fb958dcc4b02d5ac279c89d186188b7c9c99309d0a8c9eafb8af5eb2f6af9a325fbfb7c60e97484be9521577a4676be05c0d79ce44a9d8ed0c2bdac3da2f641fedb2f19229400642ba4495247a3e789786420ead4866ef95fef986060b3fc4b143af898672f304ac2813389fa3554a1a893645a5a2f1362d222a2ea54603da34763328b29419a96f44d51684a494b6c55f87fc59b84854937d0967cf11f05c1828ad619d484bb1ff48bc2e74c87e312e61d808dcb87f83719a2e06c9cca82b1628538f32c052807aaa25b43e7b576db7d81cf0581ae135610f2f3afb5efea13430c15f6e609dd63f6da2300fb4c638b06d99ed6e08993760d5f3ecdff95d4daf46b5da5a15e4c3c75d7a2c45b5b283a21846b362ae30530303555f23230db6c8e52630ce9bbfa3b36c83fb522a4e39149e7c7436c5fbc187c5afbe210fbd6816037efc7b7842ac98a1c85a0dbc00c0953321cfe09cff0614a704ec178f1d5657fbcc756e2fe8b15afb1ef5799d4caa9fe8d607e0e053fa1f7639326639171912010ac043a272f01efa37adc6793f2ab99aa8a100a87537917e1e26aecaf520c72973c7dd979357a11adae0557f1ad32166d02f4c3cb60540115a2facc1706d08c259506f409edf75166fae058c6028ba4e2082fe65f58dc1c61f4623a44519d45a643e903a60cafb43eb732cdc3cef52467c41cb6d2b7c0441b2006f0583cea2ebae8faacc9017018ceaa16908bbd3c226805aa07271cee2b06a438ccd47ddf171fc5addded72be01916ecb2a3c97189265f81a77c01317469a1862667eca58194c896647d53415e3ff081915f87d015d63510d68b7da35b3b94eef58ad5add2caca0edbce947da71e294ac5fdb760baa7f868e2a48b6440e1e20f202a1eae28e58dc8d6b4c92012605c7aef6c53e74cb3250bd6a3b89c33f1e1e8e3e3a567c0ce30d87868a2be2b57a4793764fa307cc851a6959eb297028640fbfbccd9bc4720c17f47d727e9f178d23f536730c2cd7311bab54cb2c85b4195452f6ba6cc30ec259cd4effde1ef6392e17488b80ae91d37b5361650dd99e5128da9cbe5e9f04549f415f7bb6add56fce976cd6e66cfb61bf8df70270d063a022961ec771f6670a918ef1466d118c280c5b3499c3517c2f27e4b5430da83013234c1ac70a2f7850cf92139208688aacb214d98e2c22d1f6892f00fb3701d407cf7cf14cd224d9c035015d176a81c1677611efb5bf103249b99304efa409cb8f3b8bf481515f1f0cdb6fca91b97fb42cd5bc9e10890be11ec26af314536503e5f71c99f79a85ff502725bd714dca94e7a2141d83cddf7b967f16e26a6abf91f388c154b1066361e510aeb97b8a604e3e47463a5c6996dc09490d8f1f04d9b62d98612cdc76ccbca9da372a68baeda469f16744bd25701f9e3ca9df8823c94b830ea37f49e2d2c4708311cc7e4472770ca022d28a15a0243c4d92436277099aa9bee1a741a2846c342d2c3db421bfb3ff5fe250163bac3d039eccd48e158e7915180c769d1e08b4f5f87fd7e707621f77a4098765225aff4a7045f7db2dd143035499e9641e7390657337233a5c24091c1f060f3482c79d7ba0984d12ae6e66100071b8ff20873bb3a5190e617f33aa4e64490c67a00c45544aea12f93f53a1fb649bbd63d6ae2ccfb61efb1ce675bca018360b7b1d35ed377c4f90b90ecd9fef845f3b5466730f665ccafbda6f7708a95187ba3effd497fdd4083ad19e4cdde78edfca483db8568b64178d5f410760b81324bad51f10ee01d7a253951aebc8d8278dd8b44b192478a7065e70090801d34477cdfa65cb646eac4a55433ec1f016341784e4b1fdd59541f9ae7884a691b8b130a230a5986d69f521d2cbf91071f150e934bede9fcf354d9ac8829fc00d85fb88e16ffa8cc5bef5227a41088427380d6134e35db58840713fcc41d88b10aeb638280979acc08bad02db76b4bf9d7abc0e31c78fc7f8a3efce85764ecc6e1b3227cda783851e2064bd9a0bec6a4524f57b5080b7d426ed2979c43104bb08d3d9d0311cfb0ea188e0d0e221618162173fc92290d2acb1e4bb2ac9c34ff27918a39cc7015896ee65bf68bc0af5a2af2cb60f730a62592019f665e27b3d80fce6ba1b5bbcb8afe7122c3bcc26b0011adc1c83241d35dfa81996826b146a79f9036c900698222481f5fa46ca931d120cb1072296b6c148cf17c5c8aab8f2a1ba5a1048b78b4a28fa809dc8f8d95fccd45d792b25b6f337a5ec7ca6875f0b265ddb1ff27ed28964f515f7809dc7804a418f319b5f862f79a8952d9210347fafcea8e0afef4fee2c8ec55652206e3f54c8a6ab48710b7d104121b207a0860b4add32fc641e7bdb501393e12404e7ce76541b6b6819a702c4b92572847a44e24cf5f7a501c2d2e0a7dbfed2370b659bfc7a8472d7f260f7c57409cc6bce8050eb70ff807df73dccd2535102f827b6917b2c39531a1e1e2837135df20f5570eefae0486e4ab8c3d86b2e96d86c6b3714685b2fd5b209caa532a9204c28638ba3b07f787b5f1c8249f5f067299bfa9a4db43b7807e0ccabc872cc2f9cbc9dbd4e03d38812b31c0a7ce41305c41c449358c3e2c6c5d637b6a25b6668a29065415e3cbd7e8eb12d3b18e02d2807e05fa6b933fbf6058ec710c4e83b16f1f40d90d5808602ae1863c9a5ff01ecd9924730c638934421dcbcb70b96ded192744c4a1105e99aafd9223ccd380797b16d13fc6491895b35c46cbd606dfe5b619c9290868c9f9d4f06f2bffa56a2db8239fdb3c4bc2be344a8817141d63669300ab13d63c169fb8ef6f4c740a24470d6882009b4045b101069ee041c0a2c37132f4cef96e3fb80c2e49d7acfa7e42a9fa17cce7c36bdd982b85c01a9f1dd1bf272b19823f0eb063f761cc585251a6eb8c1a6e209e47c1ece886da07fdfe2a3083dd93202eb4814f6423596d2aedf5ab8d88a128e8224345b191a7987614ceae57b052407ab0a7e3879e865cc5e63450b2be92597e8eef43fa7a1466a63a76416529ae936edb2d74a9da159d49409de301d5f2496d9523684a75daf97ebdcedfe5ea5def22b0b5ec34cf29c07e079ade786d52b587a6cd31e905005591c38213705b1ed561b9ed7dcfcd0c01602b54dd383037b41591e7b068c24d28613e876b73f3f3ff61d687b90e1be028e25e9e48594fe48662e16610261b22100a9826b49c28285633ee3aed4a38f7fb58cbdc07326446822abe8d8950d91fc5ab448e8b2adf956fd653e3c7781717550d39cbf048c61686b168e2fa4e2b4fa761b58e6be0e569a0e440b893746fa38ec687201ba6b6bd20082b644c5654ad770692e68de46858cd2cd8c92d148cc3ec563bb559c51dafa1f24b656b32e371cdadf613cf0af119a579020fc06c953705e8f24985c417469e62df893a0f89c21ad3e4b9f306c525a4f252b79f68e1cea9073d7efb385d2d6bf7b27d9199c30a5ac17a2c1e76f0884241f11f6d0736d570001d014ed25812ee7eb2f08522148d621daf9b1de6908bc747b239b4a83974aa34b4e9419074c523bebbe55025b9bcdcf17c6920f9cb2d97664f9cb869fcbcf876b3305d80e43bbcfb9ffb30ca590f43b61779156540008d28a9bed439dafeedfe11066c38d722fe32192447cfc1222ed900fde72c591d574b7e3db9ef948d7fb946cedda93792895c9ec6102fe60756ba1172737c3a965dcd94dc8d9e8dbe104c1c9c4027ae62cc628a4279c2549206614e79cf9e55670b2bd98ccf16dd53b3252f3e311bfc03a66ab6b8f1f91b01bb59a1442c8589d931887126b090024174b8b93875667f02196b43543c2a6d5e072592ee220540db2d1342c97e20cce002b57709ddcca03b2d5193e149d2f57a1f8295258437b23fddc7b13c3944873f63e3d5d602bd7b01a0530748c5cebd7100f2b045d975eb136b5aba83db7383cb886fdfb15a2c5de640041441cddffd7a09037839d1c1c17fa8755dc94142da1758b41c381cf66fbf5f1a82b02f6201b4c133965c00411b6a474bb2243dc1d330b4604553e103b4d4da3f1eb1a845030bcdcf7bec681e3a17c084fc5d89a00c9abdd2e05ff32b61c0fdc542fb47ea779c6079a85e48d8d90367906dbbce5ba8ae806b7c8e08a8e177305260c6bbbe8a9e65f9ee9d64abe3d17cf5f44124fc00566611e581ed52d1fd7848561f94f6467da26915a2cd989b1520b26c94bf5d658b488fc30f11e13ae8d4880bc19afef6b043e52dc981ac673d03ad7e07df7626b49acf30e482386ff0d69a1622c78a824aac74dbe6cf92d484a10b5e71f4111a08fa72eea28c223c897e3739405dda82aa95407240d70d64afc2dcede20518c4df04b9d52564ae94271adcb9df36f09d20312a710d300fac4a03cf9cf6c640cb3d57b8239ccda8c996094009020186c477b37cc91ae826f1c86d6e508221047b97547422f340abd854298a803bd778abb4adedda4afd5ccd64fc6638dd2846f57b537dfe5021f4987b060535049d50dc5621a84beeb2bd591f1784a435ce0afca44daece6add18ed035bec7525f4e9d33d7d730f3bddd6458ccf9b9b1ccafc66f98a9c39c3dece0d188bec87d07f409c660a88e4181f804f81ceceef055cf04a4cbee340bb2efa8435f4de78d8fe272e8f427af7499303d5dbf13b46eb9664d90d45d06fe3c4976bf4a82883a05bda4a0e8a50732cf97e7c4ede47520fd52fdb8050e376cb29c219f0e0a732000574b82f0d37607edf1547345559edcc8e20bb9ad7a6f495843cb173b69055258ff42fa0f52080d2f7b1b6978f32db0fd8c52629a97370301f2cd67fff8ce3114b0de9304d8060579f634a38941952a6d76cfb66a9b62750c2c09894222c03140412086261ef8d292e8cc123abfed8cdefa0a535755a04a82bf46f33883800705baa233ea20df43be3ddb6d5cca999f242044e0244337e2639259fed971979017f668bbb0af32b8247913e5501346b82f254ab187b05e995705bc2bc828b3fad4c9310cc31620ed9982e8cf3132936e5165ab362b89a585e79adff75b90a51ae304a734c64c141d57062dd5a6f0ca152f85184f034c0477ee00c8296efc084e6de61a5b448c33cf220c783fe7d35e4c7826a316d005af6e5c1caf507949f637f4103a82479a6cf34ee6a7995af9834d84a3a1c53a740115b048f70050651d579a4dfd570de1f962e3caece822e82ce422c0f7da08a0f4afd60deb2af512f76813769fd504c67aee4aefcf0c912df44868893b871e67495dda5326e1eae0e76dbe47212b3690e84bebd63f744a2b5d5a4d0cd3143e1507696173654fdea69750f4fba050daaf1c8fa4ee320862f17b5f438231c80a6fdbdfef74d1186c0a24328bbbe4627d10b897f7f14d83ecff31257c26c12dc3a9a21719a0d73881e5fa292036a4f4a8fb9524d4fde37d537fe84df899002ca835c20f9916f71a1d1680c9a2d3c67c82e58e726e51d098f35a1df21aff836c79d22e9be65fabc12212f097640041e428bc8ce4a82e7a69f7b53ff26e4b1580ad53b8aa2f5b4329ebd9887467d6b9a21036e8dd77d9a9acadeca2869db078beb361666c722aa49dd9ecc67a005409ecff63cfb7f4e6340690f8b371e3f38b9ffe075767c77dabfee872b293c510964f03e3422940e8c852503c317213a71db1b221d624c945e867fe68b2603e0575f2daba3cd47007f532fa9800bd401dc077bd7d03201febfcc36779847809a7b562944b5062b2ec6ce0b04ac9c80dabafa5b0036250853161bedaaa15fd492272c7ab2207910c5c097e8b8e0c3fe3e2fa3ccc5f0751abff7ee6ba9b8fe9c60d20e8fd933344a77bf26cb57b2880cc51808bc9f88f205788286891dbe105e8d537cdeac91be939bf12b19a1a3db727b3577541e938797c64bf40347a8e964612f80f26faf46617247f5c54cfeeb583dc016b9553910c5cc04b82783052206e71b565f6658f424824fecc121f81b0f11d52dfbe3f444d8700cf999c35f0296c881346b5c1e0872cf1b7c8136f4c9ec07a03b93cdeb4ffca0db077d159b4c4b839e39d9c2f30fb3c958cfc25866cacb125c2f73ad1caa7a1a3d4685ea0a8b838023055ed21947163254b7568138abf2d020ea42fe21d1c9d0e359b08b5553d9db4d3c910149e3666475ba60f0ecc166ac31b778a8684d57199b2c06ff91fbe5b1fafa934ae0e6df8372deb298ed222965be7f603edeac81b2ba8b20f62ab6c1d0d2b47275a9d57073e5bd206c1663522bfa69e9a0951ca8a21d79a9321ae6bb5ca45cec291bc1aea46d599ab02af85a8da39cb8544f07ca1c31e475d96dc0b997cd4d24ebf95e04247b9c5f26fe34ed8aad83b5f465ab3fbdbd2dcc7ad1e7702870d8d2b40876e8ce9c2d20e304f103c8449f658d5a3fafb5eb5ab8aa31131e0ce79995eaa863d21de9d13ebdbe5b727915dd3287df9ae7dd884270a29fa888f7b0b8a061fc32b7bc2eb5495959774f5c30b290664da1e365558551e3c0c2a74209ea3978cf32674575c9acc84f84b6141e651a66eef69b6543947ef650e3c6ba0efab0261527b3ed8c304caee1bc7ac1dfee837c9aa91b44a71f8c0d42deb57b408da8b99caed568bc498efc2e9376de2481203a50108578d05184fa7921c8feefacc7b46f64ed8ca632589daa7cbe110071f094d92668c3232c02552006f41af5e81c0d35c17833cb93a6bbf07ab652923a0270c9947ed8253a567c57d6001e991a30762a505d8ae0cf6771242ead78f189d960bcbb2a3505cdd42e43f9559590b86cc6f5e99260efddbcaddd9a18f39914436057e0e9d5cfcf2890784f9ab6202c24ff5980e9693018176bc5ab170b871096188bf72640f6e2c551c09af6269057b1ef51fb7800fe014161e1a582572555b546b9e5ef6213cb4e706d9ca8e1cbf20f224fde1ca840ff99335397b84c94579a66c23c99c190a826901bc9d878f9c94112a3e7188a1d33f29d529d17d6a20960ddcef2fc308b32ac94c8894995864a68b63f86014469b509024f4e723a64965a6ecbbd9a0021212b40f8b382912719e3af11191e6d65a2d371c14f43bf8db83270a3958f56b0312465c80e4ca27fe56c85c905c53eed10843e8c5c4178ea130fd9cd4f3a277e027dcf204056f3e1c958729d56fca40cdfa2b3849224fd51cf660d67a3c03dbdfcf5efd74e25d400e6b6afc93302a76350898a88b5758b8653484d59bb319e735c1e8912f31f7946c960b35f09559f796f6f37fd077b8b69d6a0fef772cdb79044dc51e9c9762b4f16d4f7f48be23dca33a49eb5368b03d9e2c382ca9f10a92dca14a3e7dcd059dad84bcdaa129266c0b100ef1ce51f8d4482d5656a78f045fe5ded5f4a56656b9c33ae2eff3f8f6eed20e6c624a5269fedcaf62f03c8e060c4a35051caea1100975a374577637870ab150e62dba01b0590b4dcd5bd96968d0d23fd4e3bf2000c908d9a8ec69f0fd2435afdafb9e4e85ef8adc399f3ad0d28363778f403fc95414aaff0a83acd3fa4715fd053c000d39ebf11beaf67c2167414d8cd1bdfef372aadb828badab02f77288035e742ad14580265483049dd210f59d225ac0d059ae09468142ff51e35af259a6de8403e7c805af66513e2877996652b9276921684f6d51f781af3a248b5dc9dc2a61e67fdfee89e6c04c6814986682a260ad415f79e84089e09a662fb148ec6d08faae45bfd3ccc95997550ecdb505642f8d956840a4c4f546078357d56f3ebd03cffe78cc536c41e5638054b986c59424e838d09905c39ee888284b045aaaf5f92c9c4118d2ba34c74ca0b38336c51c0d3f7d1c9ce0316d01320fd8499247094f753e30bb88c418c6d4c9c0a403cc7971fc181b8eda44a5b9b2acd907b1c499ec1f26b8fad564b9b91cb219ce92c29fff78b643892c59a43a48096a8cf396a061d4b4a870ef7601fd01348e7865fce9c12ded0b9adf35c0c430990b9487fd39f79f7c95e23d666cab373cba680e21b303ffad70ef1037205ea6113744d6ae806f06027db1a69c0f86e26526ba3e23c3400a0f5f5387a1abcf410010b5382de1abcdcaf23b6c4f218c4f0f2a73da7a2a21d369038ba6bd0204c31d015766af1b3172d06cfa2db5eadcf23136141ed0b1cfe3054625d41224c038db44d9926242effbdc7c644af97f120b01d77c5919752b5aa2f9c0060cd6ca6da4f843c0ab870f0c21623d9198370a49bd4f254655547baf6f3a67434145715acd2dea9b529a6f94381650988a696279f00693293d42c212f1f849ca3c40c04587cedb3cf43e8d4bef1a78b2e3c14d8bfa07e73ae30a69881ee5c7f408548ab4a3ae0475d217115d6010bc10a36a4010064caa6e283ff3421c9dd0ab8603c222d307aa0639423f151710276e9fb46aaacc5895dec8d23ae51089379ed0fa6731cc931051c96da1774947d3b40caf09da474f7b838a4e8cc8edafaadbcc2569149db80def063bd7fd9fb187572d8ed85df029970423885aa8a5e0b72fe802425921130713108c93ed7c1fbbe3affd3e26cd0e17cee19dcf68fcb1f813902cbe8b877a73e4dfa9adccc028840d273084f4c670b3a878e3f00a253da0b843139e06b1bec76c837e37859c295ee53eb5b14e95545f5ccbae10bbd5067bb848119786f8a1e409dfde2166dc600bc169e2b7850fadecb4ffa4536ae771d5cef7f3f20bb67c1176c68704df0373b091a2188ac9a075c7cecd41c2e888ccac1ec801df94d49db7c11a75113df43bded14da8497d3ad4149e6ecc64e9960a9f8608a0b251b0f9067cfcade1a762477f2122d6ec81fb732e76ae957ffacf428b17f1f19411a0ba92ac10681241f023a4e11d1ac9b1083fe00e1398e7e1d743800da0036e9134596f9db6c0410348276c3705aa0dc9e224da9bdea2a25a7525e73401259d36ad7a2fc582abd014b7af8328986d8c2e4a2ec824b20fabea2282dc99b2a2396ea4e481e785a856e042c87d2717c26d43df3c1777970151caec9506774d09381318bbf071a867f6fbd898065c4ce9e7229ac1812de3d430adb46e7febcbf017e58c53051c1c0826a03efd25726fb2f306f21d8001c97ba0e5002a6d53c8192861dd5a5ea98f1dcc3bef46f54cbdd1d27ac40a6cdb3f63997710074ccd81ced18f984c9345dfbb9108034fd9c98965ac9e648be99dceba1a62c30c4fe8083c361fb704b27283c955e070c2eb805aae6f24cc2025b2622475c1b4b3987467cfff5aeabf58682fbbc734ad1978d4888010cb14edebf54b22df74f5d8eecb5f9d5824cc2fc69c5579caf292a91a55098f1a296fc818b47fc02dfc7f382e5128ca081f5af2ef145068cb8ae5a3c3ea14184e3c09b916cbfd51f29884568c96c920b068f476f309e49a6d25253c31de41300dcffddea796b1ace0ee2557641002a15cdd0247e40567fb6f15e9acbc7e135321c6dcfdc352bac96f38d8d3481cc94fb3b48688db46afd366760723cf1528c52febb5dd91bd53722762dbb67cb8c6e74592cc544f9c32ef57c5aeaaf1b56deec51ba1f550e9b104faec25a8d13a65b881c19fafccbda1691611f04f0980cae9b22c60cbabbc1fb2653010a71fc00aeba0e69ca5dc9f84f9f540021965107069a1c4e4e945a5dc485a83d3b08bac7f708beccb4082e724674bc7c1fc8ada39c5d55eab06a4b50cb5201b59ecc7fc9a66748c19f72ff1b90a6c3dfb6af42e9d9312ee3ecf7b968da406b438e8bb2b0b806866a3787727012b2a8b1820ae69f6f71282648a6bc71c198c431ad10fd511a2326a32f3768b1680a0f0286173430597f90a4f8b2f1181d378166a942a373ebdb8f00bf6086b00c95991ac04001c949407ed202334505a44130fbca181d82e1b1447903f753403e7bb8567daa15515d22690146d9901f337cddba6e9a28d29bf97e4a38166cbf5673296fe27a793424c8c9fdd67006ac3cfcef495a510a5de0cb27309fba209c9ad96b960ff9d43e36f23e8eeb925f3befc264afa1e2e8465068f904941ad9cb5d6e2a86c011076ec5e9d3252f1fdd7b469b1b43441b9e69d8cd16dad6e4894b7a1cc273737c60a9278d217e87668774e69a80a8842c1443ecc99dc5b5e1fc9bae4412481b9e37d3ce9c3b1ef8a7adac77ddf92d70b9c63b2b19042e99f95ac7f7c31a4d76ee7a3af7d8fe0209f4b385555af1dbfadfdaa6fdf5d1f8b06fb430bf2ddd961dac63ffd926f8a7af73ad2c12ceb7b8b467318325d31b1ada0bc99461845e07a4a087216862e12e3b064a7516c546a9ca3fadcaf5ce1b405036ae3bb26024f51b15a89da0f56ecf3529ebdb30eafe1d0d2dfea9e2332cb9845d9e4df8c1a996a4b0c09c2ce79b8bc5828f615314bf4f99fb1c40011a978f693642aefc6f977233362c0a016022d0663d56c7d386ecd6a5bdb9412da4d0f765a502c93991b65a3a27552dc4999033b314bd7a2e9a67467e7762008b97d33271a46e9ec87bfc2209c70d8f160e012bf6bf2d1fd89db475d0ba61b5971bc962173dec0ff60c4b3fa6fc03b5dbffd35e3d878b25df068e6e7a9a93a51717dd909c181fbbd1a2d7da0c2a8ce3da43b7f0559294733f0030cc333ce90678384de7d9ccc48edf2e81c5b85fa41c840e36a940adafd082c79236e1a638b4860ec2042b034c0c14f19273c51be5701f80cf7eacb837289d2f060c4b5cdcae77e75fae91f158007d4c3ab8268a9f05a1c7d04ea30281c6d48bbb7c661a58cec4fd21bdf176f2b144fc0e90c568419ece3d919324e0704a5840e7edc3f94716344143672bca6f4efa1c2b102178c471b6f0a70716c13f6a8332c4c5ce39adc40eca9b896f7c53b44ccf453d6fa9d886f30286146d85115d05ce3fb75c46515988741da0de2cf37072343e4e1d022456ba934be0cc9f7372055a4b03e3d564dd0383422acba50c181194700e9bcb1ddea231ad94c5f24eb2aa2785ba5da791cde892af840f3a5ac49e09ca23fd444cc5b54fe33497c471d0f2d44ba3270221a0c89dd49d62f7d8fa0b8932e07bca1c9ce6c6713951d007c00194c6928ead4f5f0ab9b19c61e207504c5d0efd039c6776e40c21eafd831fba87111e2475ca5d7cd6c05b5f711d6b8082d871ead47889b3277810b2bf132b1c9ca8b10651f106d32162c3b775c11ecbf70ce651a35fee01bd661e92eea6b8ebd69ce8dd65571e008be0602c11b21c2d06ad4a453a8302c2494afde644a87f02fa76e521119e84f07b068e70a0628b69cdddb43ee189b287e1279034389815781ccc409029afcd604404a3503afc643e25063a35ecf633c35341a2e749d8fffb5d7276bbe1bf0880e690b0aafd51023a3d2674e19853ea5469ea940eff772eca72a9fd0fd97e1fa347a7dc1c6e2e7484c8f429ade2e2fa2860f2f2bc96a90a63db464fb15643a26ae715a668c9b3bacfb250389e79443123a9b87682640f9382ce02ebdf0f9e2f02e5397ea8887176b0b09263d07f5ef0fba2812e32966d231983011c0c30b3d34d7f79a27dac6381cd3bb7149ee4046b705a0015fdba5a6e571a24bae973b5843c9d1409119b75727036f817217b90245b44dfc7b00d7f407badb370a14a37a0bd7c33ca581bc2399896c57bdc4f484b7beca513d4b045027fc81f9da42d82adaf1797a040f229d4d802aa7a6225b758ef094f750f0b2ae5c11219a5b69cf0a7da9ebd7a94d8976b2febcd92581740b8587f19c21bb6110fc0ca89a5944c2d8d7e7fc3feaf9242a2556d20a016ce594e7707f9ac69ec64378b132af8f27f3b86cdc8007ff478cc4c094ab3812b9c5ce8749253ad0ed192d005b0e8adba1ae206ac7d3cb6f466a1d9f29e20340ab2496948eeae3a8fc5a7db389c3813c1df1482d085e5bf73c6d0ca261b7adb4c26ee0e8a631c8448876ab88a646aea9a603dca7179d1d174630fbf1462dd48f299a9ae66fd348a8fa523e88750a1968399a4d66f6d33eb3d02ae01c02142ccec9db1d711396278f53e56ef50325d1bdcde5d69be0a9940b07fb6845cdddebebdbcfcd9b76acd3a8417e02c05436f4f6fc3075764e4c6f6bc4212dc2b18c67568693970bc151e93754615fe033ac13d8def2fa45e533b06d7cd21275e9cf5373c55804c2a87989c9fd9493c4c9ba3694073ed471c4369fb0d0fbb3e2d172530021d95cb33ce0014fc2e3aa9058a03788ff41f09d2e4d4517391622332646ee512260ca040e709d1bfe3fc2e0a68d3a8e737338fb905524016515407f467be469b0aa51781988de5bf4032e42edc8ff996ca4591442a42b0e40d58da1a56a4a8a9ace3548874d7b49165e942589bb06d6d7b26f567ac4210559deb8308af2a7b3022c9c8a195884e49528143f9212701235cf988942785e855a8e41492e073fba43585506d0e4d7f554542f86bccd76ae56b5fb3c9ddbaf6892bce9abb66f3a568724749dcec41e1806829751ceebade531c354062ada745f24ed5fd0b13eb8626e8491e8078ba60f35dd0ff67865cfbb2e460084407840310c14a898ff0f36a25e43af5c2c4e46f03013a27ce099161b750535c93cc68aa4c12e46996aa581d8cacb45e870252e15b0c8e527f1fb5ae3420bdf29ede84066c002772652990bc9f071affb32c0a02bb40a28a8407b8b7ecff03ab215b57b0c57d0d59a40d23bb5a294ffe74478b85d3fa680d88568efc0654226003b117b901cec99bac91988e6dd65b7468d56ad3338a6a38cd1a03324ab51e935fd8bc40384549078caa5db831cb5ce71c32e9c764b07f28626214ad32d7650f481fa47e80e5027625334192ce90d5a1501eec9edda4f29bc9b3a54cced33eb23887e5bf1d44472968ef897f4a29d8bc211f22db6bd7283768228b2eb5f3b586db4172fec0fafb76dcccf3f44c91fe388bb46bfe10c0c7e4ca91c76e11133778bdede37ce15941d86b3e666626d75494bb4518a70e702c2942157056187756115f74c49006d2c932c50b0aebc0b5c80aa56b94095b910ddfa89906ed8f39c244b18b2b2be469f2b27be0c92ea5325e32c24d6a5e85be2a6f260989a55973a90514a6be849e7e55c09909dbcf345ce6b4031d968136da18888db1edd66850f4fa6188c5e87cc1c26be5252daa4c240ff5466b03d0cff5159ab630cf66789c982bf14cfdac499f1d60d25a827316c24d5e215664d22f5742d4ea325fe2109ac17efc93dad8f8c79d09d72bc53f1e855912df7af141b53998bac7d482617a0e88b7d7dbf9a681497cb6290bfff025d81371cd9ae807bb18968319eca667947f61ce9b39fddf07bd5cfb5becaadd40f2b63b59b9a902056c1a92aa891ab742970ddf74d910e445989efba219231dab884dd5915748b8584b612415ca9eaa9fb899b516658afbced1ddb1770d06ad01f4cbd959882859b0b610439c7b7d4d649e31ff5ae33d6b23f69dfdd7edc074fecb4d1763e358b5876511d61a2d4f452cc71c995eb20064d8a5b34d11ec134257ee48b0a15e4de74786c593eda261bc2237a7504b3eda5548c4c207664f4a9f52a4d4470a572ef83ae92b80eef5d012aca5061c492e358c08f2a19db7414efd8c45cc7d3f3f0b24dfdde9d6218951c077de9bfb0c2e31c7818b26e5e41f61eb70f7d48dede945ae5cf826b8f3646eda8bb6a8bbd5f808ed61a02e3742927aea9d25be97fb54e9e2d8f7b6550ff7b809c0d941a4cbf42df8bb53a104715972a9da4193ed9175fe717e49db7e43160f931e20fe2316a55aeafb0193bca096e9456c9bc78d809c06837c1b4520d002e1a9690b310206a40238d25e06e11d81d7b04e06371ced05a0e32667d359812630cbd7e3757b2da8ad66119a1c28ff2cb16c10c38037244abe64c3bf7aa0be6bef4e299969ba85c975c32acd7b3a0ad3f6b22038c895f4b2523400e6dbb9de42749e37434b401a8b122e0e6fd773e5577338d07ee072bbb2039d8134deb74439a1eb3bd1bb0ea9944b18f0b6609fd8c98465e52ee01f0fadf3019eafa649efe181c446c9150e3e886fb82911f7bc636c0fbc10b8d75ba06b081a1c4feee51c4b26f217e083d64a01af37e9cdf8a084f7ee3885871bda0a79b9fb694eb82ccc53e00f7e67b1019e3822b2b4f511c921dc1677c9bd029db87f269046162c6936c256710cce67312420a4e5e239c56d697b797e983219549cf1b8d065be26d2fbf628ec479270e3cdb12b764fa1dcb786e92f50460f93456581d749905bb6c2dc06f6052636107bcf66ebafc6ef50ccd4b2c842ea212517e06fabf9fe15877cfb69bdb2f858837bdcf490bd10df90d641df20987b754df57faea66b4d0ce4834360fdfb432872f1749d9cfd819be7460c2baa67db02f6e354fb286733330e6359577d367040aeca44d467504edd1cd80850229991692c4017fda8b15dc0dafb569368223d5b3c9be4cad9c6f0e53bc12a78f6d8696c5913f35129962f8a70f9c585dea520f0483cb1a8b62cca4f36adc6a1308d72298feb2abaa742ac7834a207dd01df8182fef6734dd7abb83cca48f46aace5ad3c57848e53174d254578c8a05f11cd037385e9bdfa5bac4db2ac7490429e8b6e25a09239c82998f60731f618224c33cf2966072f72e13989bf5fd4b550cd1a7ea60699f427562d3c2d0a5a79918dc3fc8521f7853e0d765ea4fb55f73dee9937ec020f92d6d8a77787659dae814c854240e44811450490526c9dabc781e0f12f6d9f37bd303cd50689c6847e3679d5427542bd3f6a55a8b6b15c84987aac0bde6677ad1662b59d9cd6d4ffe9fe10023738a7b4d7d244bf07e577b0b05d9cb85200fa27495c160dd8baa3771d1ac9fd628160bda419cd9ed7a631ffb121aa6c5de816c3cc8753207f075ffef1bb317b09bf4fa51fc4d66df1d2def8ea15f97d2563719881e6f2167601fda3bde2e2a55e1b361ba0de3b169b98355b8a81ce07f2e59a4a45138e304c48c89f257666fafd60e150c1e27d61d96f5f58b9b00bafb161e8e5ce1c6990de25dfceab8df67372dfc5938dfe59d4dde3cea7d7d10b1220bbc53241c7355c335883a9de215072f8c321dee2fd81efe91aac119b7732551d1eeff8bbc8e47959f03d3707c8cc7b9fa56ef70011d79885ee1d8fa7b149f95d5b651a14bf4d2a2b6b186b78bc2ec4a2645d151a4f3f6a295661a72fd627594d669f8c0753701af8d96c7b17a3b24713395b2a09101f68f1e8b3ed23a99cc9c8e4d6ddb42f1eb9c018893e6e04b208472f7913faab04fbff3bd0b0ba8fb392ccc9d78ffdf3b0b09091b0de4de81e4ee413f4384091f10227c3105581c515ff276afc374d888d0a8b62d49edf0806ef0bddef2f648b1e0c900f5a9f9ba9e6835a78c49d422009fb34df33b45fa18e10e45cedf51e0d75cbc0816954622aac39f90102edc5732ce80d3a7fd9ee46e8b2425c3fe0d8879077108dfb740296e515fa4384fb577878c205fc5b89fc88fb833fc23fb797e6e2f7aaf4d30218b2526fad73131348beaf463cb3f8fca9ee0028619417a7e4bacded3f17c01e72fec15e55943748f5ab64bd5faa623f80f22fbd70b2ef6084b20f93ee5967c1c2d09b4a1897b8580e66e29ecdc6b989ca6962ac45dd7e3d480ba02fa811887e274c062d62f37859acfff08cd8eb3fc8211b7f2376cf622913ca4f5a1f27cbd5a7e9aba4e732d28760730ce2b1f8e27858470e6daffcd28d87972afe97bae98dc23e58b86e2eec602771a684b377c9d689a38ba1b5a3c4a37c0c4e9cb0bee5b2ad7d5802c1eecc2da72a0685ed34433d8c255d9a590ed09ebb19d5b9456362698c87df6927f9f8562647fed457dba24f035ebe20c6d2974d5f58b2f163a02c1b592e33eb834f57afe88e11432be4cd7bb08101969d20949fa51812a212a0bc3045e0d9ec41455d392390e83b6d1d84b5c88063ba3f2a5b7fa7ac6d1f2fffcd37ff5db0e8b7a036f0bc0d70fe40c8f4720c8b65bb7b2109c76d28a34013866225a5f2a28538a9cad78b4ac97ff0e9df4e8c086ae7d6718f017a2de7c16804fe7d07d0272a48c2d36a7cead56b9121cadf6ebb9281b897b41f3a094511afcb71cebbe5ab79bcf7df30f44f9e832f3a65926892464f8c7e67b9f83f45bdeef3cf7fffe5f47fb4e6e795abdd0b751a66e6e712ef5450701b7a61105a0b65a7db725e5cb5d8ecc36a81c694e3a13c30a564e792c2b276220cc0b26e8f565357acff2fc235d94b76d6c03369ec6bc65969f40d20022927595dc5a1e323e654eb3ec5ffdfd3e94e209873d0bdc1c78f8bc68939a4819231a90470141744f3e43615bd82114bd3781b768cfb5e96f9b99377ba7146b548e8fa44214888099749ebe509cd1c8794883274eab1a5b0dc9307a87accadfe9f4590b6d4ee64eb475e5e5d3467952ae13ede806f51e407093ffc3173515e779ad450f2ea8c962a6617d7192b706340ac0808b6acfda12970516193cae60bc69b4fbf0e5d7bd4405611fc2a16544300200c123973ff1fe2b7b24532f2b82e15f8ee28a3862e21b7276d931e52debca746c74dabd689a43ad8ca86818d8a01fa94b3df09add16f795a6b8d94ad0295dd53f3875abe60c521a0ac96a3a5af65056779b449479ea19e7cc6639290f35297dd8b8ead09fe7abfba14022600c3010ca7f650fd2151eb93d55337adaa5485ce89a23d7cfc52928a2e2d8f996aa68d4309715435890e9aee77945b502c26c9a9bdae051991d10a7fa7064d9d1fcb6a3f20b136869f6bdd68a8da93c1fed3b58aa3b33cc217fb055116b8421c70c8090fa8a06c9f399d20eef148969bfd383bacbc6cd0af67a600f87748c280901e5a13f5e96c068c2a487399e8365ae53595a698e1edf026220559bdc1c185b0f2f0b2c8a8b3d30346828a19c08e305152877373de8910e8568e76b282a42bbe102d253b31880b3182985386338fa2af8f65dd4878ae569ddd6632ef4c4be76388ab2ee0f793a61d61f93ac2728b3e7619a17bf6d5c795ee502ee62c8fa73647b3e6aae3c6ba7d55fe29b662c38e931bbbe3a373a4cf7155a8e65cf3c9ec0d0b6b219bac830b259688473e83b047f830c3c7edaf05c57707d834b26444df882b8b6dde284e2d52f855318b552004c63538fdc39ae3b6cccfd465d239d063c94b0705398c79bcbde42e35f3ae431339279e7106f7d4bd820ccf6d2e020654481505982258de82dd274b331da24d9dd71a9a2a110257a6998b87ab3e3070495db46ffa72f2d89fba555477d1f9b719809bf9c429dc889e2635d6a76ec7c1ffcd5f004bdd4e688e6f952bfdeca7f15a5e4594618b0ae7ff44eec37c73c6afd3d4e9696110a569d870ef69ce1538653a3ad3efe26cab3cb6228daeccc86e85d0ac6f3f83c9b3c5d7327ab6e5931f9d7425958c831c78e041c4018853fb0d3b4159ad9b995a9673bd167d3c732812053085c37c8f3eb3076e6748b1c937dc24c1b90e48e00a8db50ff9b72da7ef793abb13cf72343bd7f2f881c03abb3d1f081d3285e1046174767d70820218d9d9805a3cf1ffb4659d35d0963d862f5a7c869a50dd2f9550d7ae901954d01ed7bd7435078d8320da3b33e69c53a17bce292d2c177c062d61cfb2d742d3f2e5fe36be79faa7c3c98a3e21a10340047b5bc8d40e305cc33bcd3a802f0a62195dcb0a8ac99a08a6639ac158d625216c9a8a2ac39c218f2c4b2eacb7216536653dab912739c065b138a19c8c72dcb2c679555963a11d21a18d958fa9e91b38d148c16f6a85c8afca35aeb4772075dd0d5846c8e55d2180de1b8ce22c2bbd87e64d8b0a86407371590948c3e97a328d695ed97444cd6062ab7516e13d7f13a654b8da55107ee4353294a8d80f4ec94017b99b7112b55ba65fc5035a24fed748bb786610ca55c7a88a87ad48d0943df832699c8246f6f37f2b6c58ee5c49869051e59ab0e064022ffb2b90533b2c8bb918c106af1b67de4e342278d70668211d9944a39ab228660410dd9ab2a01701e47153e6ac939b38a3b08f0e79e9691b1b04900fd430e06086fe85603d439b20cc4b6a762080aca7a60e3ed5a4396ab2ae65e11386129510e3964d7bab69efdbe401482f3b172492a22244f67a0fc54f4bd423fe816496a50be4f791ce853f888a1b52fd47c3111fe5d7157141964551240887c0c92a8dc9a58da216ba8b46562551b211f56e21abed8705e3dc5505b4461404b2fd2da7593e5ba42993ed6d86bd353780d47230aee676bbb6d183807c433ae02ec241205a93d03fbbba4120d7ee94ad60833581b6e80b3c69b1e6c737fdc3534baa0101083decadca1d00134b036f84fa08555483c42c289a2149a468037984d0b0958fe912412097b6a1f06dd03574e981b3952260967644619d476bcdab79589c31858910c0f76605a3547ea2f64857866e52b79c8f0f5a2ff3dc017fe81e8ea0ae94d90aa8abe16a564cdbef16e3257c6e49902e678a9abac97cbb050472178e296d9d69e5bdc60119484a89aece14fdd1316870d3a7370fb3c98e33ba40a625b397c5a30e47c5e6a453f9fd0ad58cf9995e6c04a293b6d0dd52c4a9c8e53f776da9fee820a987cd8a14e0a411c87f85746d0886284be57b3e0109b89baad717be528d80ce5d87c044fe376271264732ade45642c019261bcb7dedc54baba26acf1781b4fd1168e2924ba9789ae8a0103a13cfc7b8d8fd3622d6ab304e3467ea22904ea89b76be6fa62ba130c498a56965ba6be38a40faefc64d2169183c78ab78ffe5424cfe112d16d014a59af4028984a5f43d38acc5072c10d846fd2c5504d2391bcf29c860648396004ac646ca48cba0b196738956fec39f567726de71f68ecb9c9613f945b20f443c949ddb14225a469204f8525fa15b50e00a8d956fdea2e5cbcd2879266a00a1da186792f0ba3fba4dc2c4ab263d5d21e854e8df20bcf769cdb5cb7dc4c1b5a66e374a1f53e8b1e658075cc14bbe036228e06afdac0dd5f3e8118901dc10c5c26e93822b3f7a3f96fd23dab5a2029c7ad65ae1a909f4008a9f32c6e2da19d76809ef32d709615b3ef28870ca7ee111a7ecef4758e7cb8878dc259b6ee08b28e0b869f450719fde3d80d63691e67a9f517435316259eaeaad3014c8e7de0af3a0f3d8716888f4df1f7a18555b6c68e86d98a027aa59a4d13bfa193de7a4f74043d0e3715fa21221b52258ffc4a16d9a1008c86ba34752b6d4001827fab23adc64f418105859b7ba3faad023e5522d2d96f6d3dcfe1752cd73eb3d412f11451441ff99ab4caae3a6e6563da7cfc2790e9967424ad6c45628b95ca06a9fcdac42d2d90b623ff4b10c9a6ed5718649a545d501e9833e5a7ae704835de97221fcc5180557eaa8b03871d163af7bc63f0a44201a24e8f7c5f30898b95328245eab7a92859886626fd6ce4060a11fd2cc107752c24052af2a119270a511621c896572c29c6f363aa80944d4b829046276bfe0b91e3d87c72b9b003034203bf18ca86c6473b734f18c224c8f8e97673865e338907bc35022122dc272a45d878e1897ae2baab2993d4ef2cf8db8d75a227f52e5a383590c39ef43eb1365d143aced471828a5c2853a69e996441badaee6106a4ac1b25c94486dc7e0a22f113a915b70be2d12bba840a5af5879561d01dc818e000577f5041e4c772653746912214bdfbb74169b5e6f7f4aebdba83bd454a03f4c1102139162a4943fe395e16c3034efe136a12b7e4a5fad67c012d668b8baed1a56acdb74387dcea6c52438baf9bd01abf4245294c634ee0db77d19bf7f7b81da12ad4118a174807a4bf9315a2500b874dd6e42e9595470b16f0ed3e70361090c71ebe2583b24ca923182e09a6cd50cee039490017f1d687db7ad0fdbd9bf79555cd26419c91f35ebe3c1097f4cac70f892d87a79c226ceb1f67f9ead1e813cb39c4284d8c23ff49d475388ea0a9109f03c17df8bc9d44960fcb6277220abf3167f7b24ce4d29f930289e74b340eec65b1c13d0b4983339988a214136e2e1980b7f53c2f9187a8b0fee6023309d5bd62ff898f8dfa4899fa0cc75d3fd8aab58693dcc8951a9508feb51ae26cacc56911b05aa75a46bc0a51066198b5b9faa97e244def676c1ca16e8cbef866849274635c9381ffd113807c007bc94e5c3c0b1dc01e5b6d13b87d8dd4da1c36baa2cf6f93124069ddb02bd52664229d4887b665009418aab3b115bf768d3029d9c997c8eebd1eb5a6f3ba52730c0252762d310e9e564cdfe416bd0b632fb947d93305a2cc5648734064ef60fee15d0c69ae05eae23debe5a762c3eddcfcb80a62bac5f21d560864304d0f4365168120b72b03c43fca429643dd0a20d2175ea9f050a7c6b07f8fca049c4767f53454204fdba7518d09fb6847b3c83a0a24881a529f503a46b3d30f51bfe7746b66ca67938f0e88a24dc345a24c941c24d65a2f4d9f7b200e7f2d8b78d138d9490d384849b75335e79bb087ce4a68ad4358a9c90ae681844447a7ddb62313116596e14c5c92ed0b972db658d2d646c94dfc89f573d13b42cacbc42ee4172200f20c5c9159292d221246336692b007bba8e10918b0c4032a3178a0a2652201fa4c59fffffbb410111b1f893154f6fd7f4af4f3011238b89d47157e970027761de9dd214eb21bfa2fc6f9776a0e5ae73ced9b5bebe2f1c35376ed0b4cd9eb010770ac490746daba773f38067817739a5a5e1e3c43bdb4719d56a8ad0d234bc86f6e14aad90848c1293a165cbb759d2ea759b970204bef01382f31194dc0fa994d52f90c20615f7279beee5cd8eb0d5100bf6928159f8309d84e4c308638728a307abd7fdff452b69874356b1b5cdf3ef321b0dac9e56398c3b88b0f851394ed955e70d4746ed618810639bf5b5f8b93d98d5e7e7dcf3929f2ac9addb64f5747f06b78e13cf6212b646a496cd0b21600f0582fc1d2924ec2274f7d884aa6704f8ab4af0c3380e5a80f6f1673d75d87eb1f57830d2f220fd7e77907ae3c915480a45e83e7c86ee7aeabb3f72570ee16743a1c15d3a9d3603d52a371196db74bac944ee0e2b4efc7c17cafec460044548f793495f4496df63db817b52f82b46769359e156173720ed1db9ed4289d53e3e75455bd33ae8a1185e9b6131b0a38a295562adb183946a7c11c46095d71a9f14af1adb00090ad5f450ac61c272a208822590735f55eac7dd085b6706a20d1291a8f5c3cbc0a77c1248abb47c38372f70d84a3f4394d7af41561f9741bc8f02a0ae054f1bd1d5e9a3cf970dfa4525b591c0758e6422b563d753e3f565e2c419ae202f95870924c9cb1f9a3bd9d118f94e4081cf349adfb481f9197b6e25d5be8f1497e432a95b15ad401a2b7723f933eff9c1a2bedc2e255668adcc376054e01003c1544241445b0f5f12f9c304c5768f13544e9b0cd02fa36502bb2125bf7bf691afabf0969768d830899737acd5a9f465d7cfbf7fbca2ec54fe7b662bb62b28c3d4c05e36a7206b25cd9d264820b0406ff50c98df296de50fadc99c73eeb7632958d9f3d10fa9d72e0fed8f1f0ec6704e4f1f1c70f6b27a7073c7f2cd9b603070602177c8e31b52444f27a6d84d7a3ff4a32807e62bd7c59f7d8552834da092b61edfd84b8d1386e196265e18bae047d135b0308d791b789c0a26a1b842ead43ab816867e387cfe29e4d4a8d30a8ffa3e8f7d641985d919e4627204a16ac5d4346be8f7e879f4147d16bd3d7a9d12025cbe50506151d10541b5f56b9f05a7a3f9d1a1e70974e11a76bd42f1966ebc2153e4f1a02b5be52cbfbda5648ebf7b04c697e371af78ad59e7a0a294800489b14a7cdf049de29fc35ffbaab3b2ac924f5644a1f719a0a9713bd825aedf74ccbbd14158d88e9f7a9b5516983af3ef284aea870680fd9dbede4f6edf039be872c03a1cfab52bcbacd47a503a2329286910cc5ec8d5b581185a593ccb671fb0388d5ebb946679fe0eed6edb2c995ca65aced2d1eb0d3fed8112ae85ffab8de4b2515148f787e2e8f6d910886a2a52495e63f4e1e90980407ccdf24c5a3d112a0bbbdf1342d0fa18fbe8d509e70ff05afdfb66a207c62e2af25b83fa047a15dee2ce0cf18cf7f2d8092248c1c8aa9ab929bf3f8526490f3e4f71eb74f538997d762ac8b274dab070b49ef3966dacc7a290a6dc37f47d95c0f6c564c700c23ec488dff7b019f501b64a2d570c712b44c08dce563ccada06aabe82b4f2ac2d7b58073ad4ce9dbe53887b816f4daee529e6f49abbbcc4ca3390548c1b1bd2fa350116353bd0cc7708777f05cf120d12f13c59e26e5ca5a53c7a42ad57760d3798435de0d56d6cdcf887c2abc27963c382aceaf4cdf0a9fa25b9bf5b1b8dc2435f82f9bf0ad18a0628678436d870e433e1d613bf7d9c166b00ece7eadbb499c7b6b474b2ed669d67ae8e4329d9e5d93f40f473e3426d327405d9f7ae3d08a52911cfca5211718cd95608200be20c031d1f0714a6e0dd4c079990a89221acc37fb27f798d896eef713e488f0e34c74003b2122dd0fd60e3d6897e82cb23c9a80b4581e6b4e22861af6cfdf097e113fba925ebd245355b0da01821e01765ab3beb0728bfb7a407139f3c06195abe51dcbaa3abf6fc7e8b353f835fdcdf9ff59e34a2f2a90efbab3303bed142d9177ce27a754ac73038ca87fb37d44272dfae357ca2b19a40a06ece0fc755c249291eb014ec1194ce6a8141ab06e1012f6a2ee0cce359987de844eebdaaa287c983eb8fcbf0a850971c9f35bd5141decdda3d8ab50de206ed2f94a5187a82d15052b820093e89a9e0fc4d43af6b54c474f737665c58a1b51ea737b43a4647eec6ed6ea5a5fd4cbf9a899372dba6cdf6d5dd5ee0c0959b04ef391228a5ba4c60e24c4c27e68935d19b282727bc75b72bc950c78a3c9a1922e9462741a31b64d7abd197d1038b2da61b7cab219803c4e949cced76bed93778bd82d6e89fa84c6c02ec16f24c87f0eb084c3aa570f7328ea20587be1aed1af75d2099eee8431bb7e126f81902c71e1df8a2652e6499ed9e919a7ac4d9397d1cff8aab2ec2d646d889b9f141c3f5be8cb401858b41afbd36b3585b3948114b1da5bd86f7706ce3f21aea46025bcc7d082dc2f48d0f9a6a54ccae3f454c60bb52300b433428c8f07e8e572ac2ba5806d3f0158d08461b19100455976f2c7898e89f03f6f77468e1f54ae87e1d329987f6beb462b323d6b78bbe61813264820e5c33bf66420abb842f04f4e7811258d125596a2a24a24abb0d34f52413738aa66d7b855b88df426fd2a3d927705cc9ade99402216735ed7738e89169b8b80a82d084391841c8b148a3c38dbe02f10d770d289ffa163d59d7aefa0d7b00afb9241b74faf25d6bd2ac3d287fdf73ec2d0f4b1d55de9b29070b4accd00ba9c544be645c464eb73da3a8556d8bcc22b753fafb75984b2defdb72f599cf7b7ac21231f4071a09137fb97308ababc57ad102ed469f114ec4e51af67042dc7e2fc5ba719d392eba54f43ea93820d31a6b3a2c7e38f5ca5bba7910ccfd6a1c7f74ca313bcb471c2bba6cb11736ad00a39f3a7397c406442c146fbb160097ba9d01b4787cd18ddbc2528d5dcff7260dcdd4b62753dc2c39e0310481092c915e3de3fd6b75cb55e2be81dad9c0b8b93b4912faf977738dc8abd50ee656dbfcca2a8075e6f1e4b8be36dc290f5abba8faaeb11f65c7de3a4975a23a427144ce8b38d40c484497de7babce2ffc45917a7befa5731ef88ab5a93d552a1b31bbfac420d1425acd248057e571f125207062d700011aee7eb185e8c7363ea10be8dca51f7430640871a903cad6505d30421f1209cf9c0d7be7a194af60f1180a46ed4c0494ff7c6e0668164c5d05c63f9b8b0c62f50fae921c448fa8800daa41a089b3894c73079e8e7d8e4ac906b830e68e928e35d62ee4fc666af6f4d51074a6334957d4c9edc89675f4828d35323e2592b92c00793536a32c5c70350f77c211e14399036c75877fce5b67599043932e7bb06d248e2d0176114300c99085d17e5bb57dc4ed15f936765978fd2223c28e928e3b622e6ac143c9e866012fb78daf45ce0f7aab6932c2cec99872e47d1ac49c3fff5bad42404540e9d1d3709260b5ffa715b000d451b684420fc7216c53e4e464fd708b391d8407655a593e9069893ed28a0a24a6f7647133d76272fea9988a0e14677cd99d26a0086423dad83cfd133f153f87093f84e204f50bccbf25c9f48a5d075b866330269aa53e183c257ca892125b5ca4a04dcd4701339e800cde6e7b670bdb75a5fc98f57f5c5fd55d22ab44a2c39ea858e0961c94d642875e690b30783614d7d01d21c35c2dd856cb8f488b3e5d6ea8ece16d68973fd3b521bd861ab108bb05a33f818865d6fd7e3f5dad0f2a587a42aeda3fa168210eb0577a9e05d6b487ec4df51c7252b5a44e47e03a985774041eccae815c0b9d9ee9c80ca49d3fa4428f0a94c99616eaa5302dd055201930c71fc407320a3fd5d40a34386706a0223e3b2b95c0b9484b73ef7ff20b240e3307ccb0a08f96225762a3ab875739f887f686ca96e3042409d64147c72042893e178bf4be065aa450acc6d3c4858ef5bf8effd00eaae10e24be9eafb13a7cbf9c97a709b3e514f98fc37500bc5f93810a3a7f081c85856b68b4e617e555663dd3b3e499108af3760932fa5cb682a492c8cca2f6eb75b75f3ff5243137eca5ce986d484a5c810207d55727362c82729dafe04beb48787f348536b392f7c56c95fdf75b070a8ef22630c54fb72556212c415bbbeb324abdb72974cd4b3d3a082485403b85dc25dd16913d740488725fbcec424a05d1b5380eab89e324605830abee34dc149238a3698df7ef444abd9c45e299dcb0a093ef0a1a7bf93fd88df61ed02c5d53001a6c469a7a1d93fd1675675d972a7e5decd0b61a51d2ea2889439afdebd957c07968a82a78525a44c925de87ae7bd35ab1f7acf13807a86097a9f261340a65bfb4959cc0a4142581100ff9835e27c369a987d98ff0eee2885b559368f8409d0df5bbbca961783a4a1015c09df370617099e057091993f1b492b2a45f4974a178274d7138dd61ccfdedc82d628aea34422367b9cad2e9ca28daa804f588ff8b1f5da5f716a520e34d5be396bf4b37f0e18424e254ee473d8b2fec67da80424749c79bfb731ab194e532d30dc499d8623cfbed3b4ccb9eb5a5ad24a6d5e67b6bcece7ccfa53c0fbe02cb4172446c5300dfb5c9993c20742f3e52f783620eead3897157e8fb0a7609d03315d87c63c40f6f7b5c8bc1b69a6981d2e7899040d37ebbb30de168c8893e460403bf6f42dcdb36ca9cbc88dac27b15e87c20910722f8ca605bc3a56f4ad89ad3f975f308dc4119d31439fd7e1ec6e489d42c33b04cc17407fad36955ed9895320aba4ab25fbb1232d3a2fbbdb3753a2bab1ddd808c9e7a62c82aeac9034525b6d6a3ba10cec3953365eed0a2e4cbc9c3f5973156adbb98a0d0e71bb1234178684a2fa34edd44b6e7d5c4404641ae61fb33aa57c5cc6877718223de3861b97f719a19a0af38a1a54500ce7315ecfedb4c3d9b5e528d08510eb74429ad97f64e0d234db31809e181b77b9a49dbe07dcdbcd68010c925951a656c433dbcc83c63608f3473ea79b8c826c2fc6f111e63ddfc62c5d3cbbc773edc9ad0170bb06090320b0724f81bd2d6808502e6d0f062836bd9c899834087b191e0ecbbbc3d105402ba25fe7c84de35f128e2718329d83cc96a501771b686bace98e429cf94b8ba05ec042ecb8c4a5dc92a59f1943aeb0970e347f1b1461a2e022c7c05ce2544ca0d531050aba83ac4af6059c62b7e87af41a3f27388d37fce2429c7ba295768c117d74b7853b5b06fa9d69574d5882112d994790b2b8b989d01474d08f1603d8a5ab2dd255beeabc3701e17b8ae8fba9083f674b429cd0d700d900e3bfb96d09d1edd93f2a952850e1d284fc623bc7184111ce187230019a1902c4925e16c7a325e7bc8556f9aeaabae43bf73ce9542f3aac246b8821a2103da0832f8b5ed562d09efd8adde3f6d8a108251119828c28cbb2bc04744a0830855e8159a225ffd137acb4d63af0d44841c22c4309aa30b51041ab35e4f34a39fa6faaac635a54de35a3eea73ad486bf59a83fe3cb34e2f2906d5b9bca67df4b18af14d6356f3cf9d77587fb583fd12d5a57a4df5855eec679875e713bd7bab37c75e76675d6698d5cb0e42b3cfaa7bae7a4b4c0871170db9fb10775173e4d8e24a537254b9e400924304820ff28da541954e445107a93457bd2520e8f80feef881173f187f60ddaf71d4192d7aaffd52d539597c2086bbfb40e5ee3ff8c8070718c57187fb355e41e34fc97bd5288f8d136befd5031cdcfdaab764b3a2f8f1c75172bfea4de37051817a30470fb0f01e0cf985777ae0e27efd4ea13a67f4a2e6e0010f8e70771e3871d7e88807a05f3f25f3e0c70eaedd36f6b4452c4ad5a6fae90e9a70bf2ed6364c4c334032a68f0e76a0030e5cd779927450430e5c9083217290030edac081d008071e0efc22c1bc3a64f5a7559b68b63af6bae1067b5e54a3d45f6382507d5af49656ef34bd2b5593d28bb29b5c4936d516bde6f97bcdeaa8b5929f1b58b941941bbcb8abdaaaf499aa2338a0c031c3027c640330463668327ae38e37ac78e3884b9b373ba62ea2eaf26b2cb964bcb4ead13758a8c11935b0400d8250efcd8ec5302c8b2153db92dce8c20d12b89172f7f7911b2e6e380dc0a0818a06a419e031832c334081bb5f7ac40187cbaecebbff738a6c1c70b0a38db98a98461b7315b9d9c9a38db9682c0e385c78c75ef596eeafab1af54bebbd5957a8ce5b972935df741c612ebdad26d1bcd821284a9b373bd65e1bffcdaa51ad7b1e6b9bf4aa7e568da20e010da0dcb589ee5c75c40206c4e00631d8c26a73c83d0635f8dbc8d2c6956ba3346d60e16db4c1c3755adbf8e13060c37d55b535c1a074c14088aa976c41b22183fb35aece3c8ae29aadaacded2eca798117ee6e53d4af57fdd2a57e7a91a86baffb8aa6b8e420092dd0817b0bc268c106acbdd60bc65e6ab6fbf5cd556f49f7bc3e7f7c862e0f0874700077d38c8cfa97bc6bdcb1d7b8e25e5a2315ca7b8d1f6ac0a186aa86f52bdf9dd3b8e2695071f72b0d05a4e1728de39f560bb4022cbe823406e6dfb47a5d818b5f308fdef3bceb355fd63c8ed030e3da6820e1d78a7cac797c4cffa609a3d7647af49eff3940ffa6c9645aaf0967d33e030733b0986105a3d76a9688b8b3191730a3e47e1531c396ca90c3cbd0650c800c179031c56537ba5a8dbe58f5d77b5a6becf5e83d77109a5572a3998cd3ad6804191f196e1fbd162608cd2d4cc620c2c6bd251cc3660c1f760b592bb6d888d101b762f942765bbb73e16c7bb06210410574a820082a60c38a47703e228abc5001055450840a808e908e60548baa7099220315b4a4c08e23e2a7400529a862ffcd75087a4bab8a7e8ce014f47077abd74bcacc118bb34649e779a1ac563f3f7a93ac6a3ee70484eeec15fd9ff57f5875cf56350f4ad5404018700a80c1a12935c58f52f75581c100304eb74ab67aed5514bf28c2176eb85b6bd5efc1e48bd3fe7f216345f5bf008287bb157b38e1c5175e64e10507a6e46d2ffbe875ef917a71f2a2e4de8dbcd0ba90c31eb136c6da15fd749797f4114520d307ef7451f2abc7762143132e5ec00515bfb84872a6b810a1c08afb85d1ab55ab5df74d527eba51f0040a4a7e5f45c1aa3c0118eb3d0199cef3da9ce7b541b2c5145b64608b0a6cb1dacb8af6baf0bb8b707ab86ce1b2b328d322065a70409b371511400bcc0726c0c3dddda370c5dd936082950992b85bf1ba8b5a4c20c48aee8e258b2b6e5d8c2c1e9005b6ab0eb2246b2f94b5a2bb5731e58a2cb02c84b8c794a00725b08168f746b5cd2e01c94532eea21e462440820427094615a5a25024e0e1a1b88b2a30023b4690650458dc8aaf5a1bac5eadbb088c1120614551fdd4a47a746666c79280646486748d4904a8080680c50ab0b8020b203caab8d09c57f4def5aecef2aae9a5d26894f57726d56b57e8c57a45efad09010e0190d1155f5c615e4143ca34772e8cead55eaa2ecb6b66f59958a10377bf1e955acfab63c504ac185a91a3b502ac028e1f7b55f184bb5f18cdaa2a469a2a84b85f54cc715141c5e253db9da97032a282e47e81800d100cb9fbb561d48bd1bb6e559b4010e22310c8981af7e00352b03fe93f120d74ed7d2a5328bb57678aca3be67f753ed66a907a9df7246ff679bc2d2045901425775f89400aeb812cee6ec3ea3c53e6feb24c35e10111b8af3d5cd9923ea5c28c1bd5e73d8d41f734edebd5a252581457e5554b8d7a6cf1ba8bd835db7dded3b597faa8eabc76dd4fa6575df7aa35b9ae486bc7a1cb73b2e3b8ae59556d77bfa38af5c7dd9ba001ecd7767717a4a210c5a8011f6ed3539bf6f7e9b364c9aa57ad954411ba5f5664525301c7e89bf6bf697d3210ba73daf784f1cea337c9a3f7545d253aa2b8c228ade664a08a5ff8d79f0c04597106d5793599d27dde57228aa4faf8fecc8c921b1d1999f299904a6e74ee7a6fb0aa4dd39e99c13b32294ad591299f09aaa764559ff6cccc636da37a74fd9f19176066602ce945a67c2641688e525e127f7ad5f207df3fe11d9bbb5eac7e2aa4539c4df7aabf57f451333a3237aa5ed319d36acd333a326bbace60e44e228aa2a80989a20dfe28e5adf9cff9374d332e902c49466b25a772bde7796deefa3cfbaef70675d39f6dbe92bdd3ab02edc7bac7f4c1682a67efabded2de36e9e5d9a77d755294aab3694efbeaa4727e4afe4177f6a337c9927daa9f520010beaf935ed5cfaae6f1aa66ef8c42a1b9c9de9f87f67e35082745a93a4c0cd935a599007277263626883001440e771f2d018325c2b0a23ea92c69ab97fa6b7af135adcad1124796782165137a4bbfc2812312e0813bfe6caeb946fdad6613672401179817f4cf233229bbef9ac9085c71778f4095213e1170e27e6dad028ac08f95ca95eb7f5b23232a5238698542a56e56d5cfc68f310d151d779a1115d2c6f842200b084881808c5e571fe501317840081e30e47eade85d877ec4788755a33b94d2abfa1931bee368d1f4aa7e1e00bafbe5803a1c80e51dd0840352778c69d6dffaa41aad038a38c0ef480930464a7440099d6b5c7fbf1251041a579727e6d51435dabdadcdb549e533c1693e69409464266c00150d78a201420db017942716efbc7fa5d112b827218124408779b1f891b8c3dd1d09332e245223480049537bcdd9d21ce1c511abfb052394f7fed5cb6a6f109a492b12e645a32c0dc64cf01b91c5c76dea5b1a81c5b53ad5fb40469c2c90113aee41465837a208386c28c24a114345407177d4ce3ca77d4f3333333b320cf041440d8800011199888d08158658c110510c0165086c8a12a67431a501539c4cb159d5315acd607501af317d6494f8ac4825383a403b38e267ab8f62daa2b8f3a8d92333da2661d294aa6146cdcad817bb2fbdda150b435118ba628888211e6a6e2c91d106a1792c952c11eb330a1141a88a10142125a93c52704c913aa5805244d637dcfdf2d18ac5aa64b4eaacbe4bb0a1d80dd8312a13d42a46aa128f6aab7a149ffacfc799c93396f60853b2f6d7acbef88c963496548fdab127069fda8e3c3d96882df1045df4a24a74b5d70f3a53e6abb71c47bb42692e28e313fba7d59e41171d6346fb27208bc395f7d0e5196fd425267ce62f336abfc6a2693e0d91720429389082454a14529448c156f091941d5237dcf421d91df60e7be8a24aa5179f6b87eb3235295b12e9bc5bdf8cf40a34131a094d049d032d039d00ca043d002a4275810a02f51385d159c5996474f638419424a2602321723012828aef2d0666cc4ae38b1d4f54e3157ab5d28bcf686d8de9f362f766632ccc08938d9664c517cdc668a50fbaa8fc6a6ac7acf466cc8b1d6b46ad6489d8ac6489581e4bc4d6a8a991b3478e5898175134b569c4f75551fca07bb3904d9a1a2d910b13c16fde5da636aa37aac96bee5c5b9f7685da7d4faa265d2b040bf906d904eeae828fb2084639282f609481c82b8c4e5d9c28303a2d0942f3aa998c30230ccfb8c79a1b1b031313f35897319b67e4c10187ebdfbcf683d47b2ac9d48fbd56e85fd57557175d5d4c736df25a53eff4fcd35f302b215ed46b5abdedd6765fa77d4f661da695972d64edaa7b787ed54c56a77a71b406da2bf4f288c2232a778cfeeaeed545517a45efa964e279a1d17fe0f78f7ec1bc589817abfa9ec7dcfd855c1b6719612cee3ec2559e1c82e2348fb0ce8cea51fcc2be469546c731b344c634e6bc8fed79e628e5ddf99b6cfbfb149475b406c28ff1e9d3027787e22e3641ee3ea3b393e6d346fdba73d59b923bb87b929b99fcec5f35139ffd6a5e5f09c6341ae8cf34ab40416846536a69df12fa49ce93667fc63bafeecffbeaac3b27f9559b42a5559f3fdb46db966820bcf1ffcd5e3d1295ee8952eab3e6cdfbf3b3d3251be751592d993e1f845e25fafc5987bee7b4e626184d6925ebd0f7ec34a5d51eccbbd1257bf53feae733fd7fac79f6abda6667fd6daa4c54bd7a2434a54d0d465339ebd0f7e4acfb6b7469a376f6e753bd38ebce49f66f7d96d67d936813dda1d9bff355a2fa1e9dbd8377f67ef4d79b64ff59a24b6ed6a1efd9a5fd59c95e3d127cda57e7b4af0e8f2802a934faa4ca132a4f3020e4d002082980f00182003fa831fa417d8b6651cc2f166684c9c871fd1fd467b4a67eb1e3ce388e2bd292f764f73da52986c10f3aee3b25e5f78ccc0b9c48c1fdda3aa734e9aa291aabea1c7be58dfeb6d77e1455ab543bb5d1ffad7fb0d7dea9f4da1d76b8aaaf49c0fa41380da6de31ebeaccfae2d80bc33a7bc4629dddc1e6d1b433d62baa332adf93c65e51b0ccae572caf6957f4a219a531866596b43ac93bf45bb4572ec5d871bfaaafed845b1a28790236a94457bb05176c307ac52d8aa2ab011f3e5a6f31dd5b0410c505a290e2eef68649c9ce9cf65dd32884789538aa8860846249a3a5a9c2837b1521ce4497a0c8e2ee171457ae0d0515f70b0a1d285edc3390c5531998e2a5260363067eb8bbaf39dd8f2d0cc471a618b022c42d0c54f1c100486abb22f79fa98501b72ec0067a01135817d071bfec0874811b0bbc61010b1c71b526bd4a6381520caad1176b811f3057b93ee9922f1530a302674acdb80258057e5c2bfa14d8c2dd5da5c0e8d7b5a8a6a1408cfba543b2d79ab35e7f4afed9270dba44f5f94197fcab3957bd256cb3ea9ed3be4168de4168de9907dfd751b58d921bf4984210132998401ceed604c6b02690c504a4b81547bbb78a6693e9556df3aa2ed76bea1185eb3d9620a4c98be625a058028fda5ca245026848c0084b023c98ebb511b0c31d4a10f64910f68a000b223081114a10a77d4f4f82182f542b59533ef851192802985f54b250b1e254a850e181ca5b089c914ad7dfbfd7bc73137ba13f25dbd33a243f9a57f44e5991a3eacd15cda7f27ecc0ba179ef157d14eaa63ff871fef9198214d94846b1d76eadde349f2f94559d4410ee563485d22484b80debce494a74b5ed9f809070c3dd4f248dbd4854f13465d38db58d85848ebb89040dee7e3ac20e9e234ae06e4ffb88268e00dd2f23e630c28abbab2923a8b836a2848df861ea1c26a522cc28828afb5d7711a5225c7c33008e7d4f0cb042f5a8ea51d4ba19f0b2bae7be44c4e14e04134410a1c31073a8a8d63b0f6972a54a434c31c4912973ac59d542a4b6d0e7d36a6e8c5e12b6a670614d29a7c060add258d1c738b51feb92b43e89d99d4d33af0430b4022186462a3254a6cab2847020a48425f4e6a9baaad5ab1dcd7547b97feef583565b4531f2b12ed1d549632f4ce3dee2030e04b18430f79d3a82eb7c8d4fa08c4f2c09caf8649fd6bc5e685e5dd5dd51efcef6ba18bd3ba5e6fb2a0bf3725168a6b11779d537b556537bb390dd240e904f8ffe1469ef21ea8e523ebe313ac85e3b8ef6c88cbdd9c98fed855fddeaa716bffa42e7b52415c63a4dcb7c5275b6fbaaf9558d5aa1b7b4a64a9c49a70b651c9f087d56499b187cff74b363d1f3bc796566ac5150c6fd04e771b47aa5b1d73d4f1a7bdef5e7676334a56b4c9f35e5f3ab6672f3330551005264f8cc4eddd2946b4c3be8aed7847fa7aecd7a4deb35a53d32fb514a64ca6772d55b32d170bff29a3af39a3231ff1d456b206fa963fd9625f89881f540ee3eaae03b54b0380c5c02f714a59e52947ac2e91093280ec198dbd20e5fa324c27d8482b389b4229f8cd76a556f2a94df2a712859701fa158d293f122abf845a6eefe16c983b5ee1c6e5d2beef709bf7606ba98bb5fab75fdc2462c5a55d99dad354ee1d658f26b5ba310bf2c131c97651a7214b52bf2fcd232dd05c4b1002caef392fa0cb2167072173a7fa3feb48019dcafbd83b3090a90054588bb5f41b0c00ae2034124b137a3a92775584fa4b09e3c79e202440a80d0028820dc2fbd51aa2e5f881d6347d3fa830e7ed080f543ea5b9fa51325584ec870c200cb09d0d63b5bd2b59db0d0e4045693299aec34e9c1a40417cc0874adfb7febf57e89961613cb5a9287b5848c25424b3095ddd7aab51235a5579b44a942f7a4aed6fe69557f4de919997d4f4dac88eaacdae8bd76e7cb63af0bcd41e8c5389654c2b946989225edbc8c76dc19d5182b6e0b43bed80bcd16e6bed8ebaf9dad57fb456e9acbbcbeec2c8adbdc79bdb834da187b016d7de65769ec38c238b124d3cba872328e30264b72f232da7d4fe356e993ddbbcc42685e337a53d4ba816c7e4afe511f88d5554d4197a09ffaecfde89a9b04a15ab536b08216038ce3782ad1bb7e909128ff69d0468da671e764a2d68e11779d104ca1b344e7003a02b07ac0d243067a30ad1e8cb85f3e561caf9d1a6dcc656a711c6d8cb8afd545018d17ccab2a7d8ea345f399d73d7451e30873d59bbe3c4affc4d8cba23ab56ef583d60ffa29f9679fd6f55a8df7adb8a2e88ebd52fad4a516ba7baf57eb734afe75a5de7ce6a1bd96e3fe53796decb52f9f9c9d1c8be62be8c2b117aab7fa423e00d80000dc61785e74707a63ae47556d4fe2481a6160785e742ca9c692845e4d5f462ba2a2a0f9b4a7f2e2d8cb46013c1be3eb0e46ba5aa9b89ff7e49e352151d4844431a73766756ba60a55d5a587c09a09c235a122678acaa69cde196c1fb9c3af0f52efba75c9bda574640a47f35dd7df47927879c4064be60e77fb44e68a63a88c12ee0ab0643c991c2c991f6e49563c62a1988c60f16d040b4b631971e2da3272449ce312ba96888528c5afd00916c5b9ec7e75ef946886e0f0d028c9b9595daf6a68afe86fd567c9fec01430ee2a58ee638a8f958f15ba3ba4e8c2fab0fb87f3093932632daf0e4f0c2b635f6cb0e2baef897a54acb8a1b8bb0fb7bc289607648fd860f1252d140f07f7bd66d274c4066bc2620f4b6a3a33dca394faac8941f5ef18fcbf637af060ca8444b188287223e7e26e77dcdac470f72034e3fff2d4e847d12a6977563d6a6d42ee56dc84b8bb0d351a1c9656056ba3a36eba3521ba4483726645fd8c8a95617ea5528b6141b58dbd70b0210b13e27ea13aabbf66b5b476e4c951c264d4d82a72a5c8c9ad2225ebbae3fa54a75f96a6b6327451d7905f0870ebd271f76be8a262b2acc81a58103385fbb555684c694d9148594876dd3afdc12d928ebb45e40e7b2d2253e474e8edbad14f357a89f0707790c3d4dbda61053ba4bf975cd6a6d475071e60e28039227d181edcaf9719582f63bc9c2ed5a3f9a64a8dedcff5025a6bbda4ec9029f49aad21239aa730f129d9a18b1af2e2ee970e58bcb4d6d2a18a0e3a79eb606d0c02b670bfd654ba664bb21030b42f0274dc5a9b43969f1c52702a4dbd966f9aebb5aa7abf7a1fa5febafefe3de251dcda7af53e69ec4596fbeefca77b774abcc101a2b1c15152c2b9b1302bf45a33bf58d5f7bcb10128fe53f29ed1b6d4959536ebd63ad7e7d5350e3d3e725da345b5fa63afbc3f9feafd91b492298d2d9a873caa6356648c69ea215a5df37a85f24e8986862734b06015200cbff093fb3c2f991fcd41e8ef5cfbf5bd564d95a5de41f8c7f2998cf66ed4af99c65ee7db07b2d7b5d79fe4cdea15da3ba7f60ccccb68b7896214b57ed0785af5fa7bdc3f25a3f29aaa3968cea4cff9944feba93539da8b5ed4ffd87dfde75c4259cd288dae4e7ded34e73345dd578d292a45ea1f7ba579d5fb7c95350243c41ab13b5822f6df3c62d3bc9ad63f8dc0a4797d29cf5b9a8ed8d5fa67912296b4ee943a8ea3bd484b8249f3fa626356a77acf8cca3b6645b56a8ea3bd76ddb1f74c05a579ddd7a2f9aea4fe374de3b85ab3aad5acf50d695ed52c7483fd319fe99acf148ac67a4b124242dcfdba568fc48a98102de1fe827d52832e49de54a722d1ddb15b414277146abbb09818324a19b451eb16c5f2854411afdb946eabb484ace69f232cee7e997af484463d8ac61a95dcaf35faf1579f2e575caab87b8e8b13cbe587bbbbbd54fd2f6e01e00d774ba381f49a310ece353af83c69f097548f3100b06b7d2b869dad18b670f71c254c7a6248356ac5f043d5257be16bc160657bd282a18afb85c2c0c3de802c20598060e1eea325ad576501a1620141b3f5c21d6fbdb0451277d7dc7a2175bfac1774fc72218bab17bda4f55734960b66b8bbe5421520cb051ed65f653bc472e10790d5c21c6eb59002f70bf5a8991664ac1f70b8fb905b3f468cfe79b755ad1f77006eb1a086c5026ab120833b4907e59ba26e6983d06cad7063adf0c35a4164a970850a4f2c1548ee0e835b2ad460f960c3f26185bbcfb8e523c8ea81071bee776b34e6daeb4677ae710fc168ca54b5353262f44723af9a26fba7159b3ac6488cf83ba07987157d946a49dadd31b77aa8560febee3a6eb5582d538ce34e59bddad525dd5c559f17895b2d46ac1677d719f5286d514bd445c6389688b44438ee7efd8ca3d56b145d5a3d924fd1cc738d63beabfae57d12e6068ca6ccb2c82abd81dce105a5b1782765aa1fa5bc2a909a57f433a9ea35a3369a3acf1a1407dd516f0ece795ed48fd640e9b5515fc887c607e79a55f7e89e1b0db4c2574d69d4f3982a13dd2344a808f7dff9aa336a7a4b6daa25f585be47e724de22047e299925628518ad91315b192bc4e82d78fc29959258199b473c6a88c2134651e040ceaaf5270a4fa2100028a4e13e4221a52915df9414fbdb5e50b0001440f7118a255de94d2fea0945784215b7d71392f893d15ee74963699ee0c21d70b8fb08c59248faa47a325eaa4cdee100b7a427a3bd70aec1bfde72eb13ffe88e17bfeef8e1ee842bbe3a010b77271ce1a8134a4eb8c133d0d0e326c030c1064c80001370eca8c38e1bd8f180911d42d831431d6bd491d661d621835f2a8b33f9a775b431774d9d7a93f74fab3ef7385a53a35aafa38d813157648ad2259a49373b31646a93a93dda980bbfba71aeb117ccd0ab37bd27cef7a2ee4ee947ef7aa65079eb337dfc92c9256460093c4a788212e4b8f08fe3689fcc4350d446092250c2121e83668baefafc51bfb45734a56d3e08bd4a567dfe6c6b6a8bc3113b16b1e3682fbd5eadaeaf4ec93f161b92da8d6538933031646abfa8d4c73893a825dd806fd8299d0aca2baacf34b566d2ba5342033eb2e2e3232b281f5979808fac80c04756bef0919518f8c80a117c14c60a3e8a4202417eb8301a992f3e328df8c8ecf191b90073c847a6037c643ae123d3033e32b568c1058c1cdc058c22ee0286e82e60e4b80b183eee0206102e6008e1ee30c4f02388358aa9e2a3182b7c14d3858f6258e0a3981a8041fa28260e1fc5d4e1a3eb878f2e02f8e822e2a34bc64717921854b0729ab84bcec95d7284dc250709979c2aee926385bbe470e12e3956dc25078bbbe4fcc05d728ae02e394c20c012b6706b092d70ab0eafc306b796e0e3d61284dc5ac213df0c432c015a50f9280a09f8c8347d14c5133e8ac2033e8ac28a8fa250c34751b4e1a32876e0a328b2b8fb00acd1951f3eba62838fae883eba92c447579e5c91000066186179228e353c480b101fc5e1868fae403102800b107f4106008ca460858fa400868fa470c5475270c3475290c3475268828ff250c147798c7c94870d394bf8280f928ff2a8f1511e3c3eca03080fd2a2011fe581fa280f237c9447133ecae30a1fe571868ff2c0810b7450f1111d557c4447153ea2c3043ea2a30c1fd181c54774f8c0dd5d80c10508901116273ec242fa084b141f6111f2d115066039c2475724e0232c4fb8cb86c247583830c282858fb08451830d0538000d35e88083d7e083126ef9f0845b3e68e1960f2d70cb8722b885a405b790e4e016121edc42b200b79018e116920db885040cb790bce1169225b89544885b493cb792fce05692d5ad241608801018603895dc3a8d6e9d84dc3a5171eb34855ba733dc3ac1e1a32ba88fae30c0ad1312dc3ae1e1232c61b85b1e046c710b1ce21618ba052a710bfc15f060c25df0c080bbe0b101191c88cb88b4e223d20c1f916ef8888cc347e4117c443ec147650b2ffc40020fee82841d77410290bb20e1077741c2757720410840c51577a1c20d77a10208ee424513dca58a20ee52458cbbbfd042901986f0d10c0ff0d10c1df0d10c57f868062b3e9ae105256fe30ab1da38311f4fac18eaaa20828f9f00b8f8e042c995161a34b9e2e30932c0c2dd5948420e7ea032843174464b024065e84701e808cd31f201157e854a883800800422567a6411c38bbb038004180901d84089510c827eb0b07fe081871318b1c10756b078a347c7dd5b3c222c19810002e82e9281087cb01e840d40203e274e6c700508104ab6b031ef68210729c01bfce0e472c54a961f5344db42122b70b8a00e273904008b154c521f400ee0a1e50256f80b4640c35560820f6894b0e396124e6e294104aea4061d5c0061128e702b0950b8950422b8952507b7b2d8b89505e556160bb89505056e6569815b59b2b8a50418776ff9e12bf8f01635dc5be8303916fd0211b5af4ac6dd6d081243e8ee443c480c31140902431a22fe5507ad4469101874d6bb4de7ddeab5ef70b781bb03e14180b0e123023ea80cc0dd87113e8a080284872986b8bb959601b8680a09d8ea257445261f75a81e552164001a04897444c60e6198219c5f56f393884a549fd5fc24d65a8b0631841dc2d9f441f84d3608c1152a40713a3263fea942d011192216fdd364c2a7ee21c50a5fac1bdb23476ca96276a606771f6504f981fdb1466d901f98bb1545258ec86ccc117b7d10fe96edee4f3c080b2bd6e80f403b3634251a1b2b63877056409015e4d8ea5524bda822ffea4a16d9a8eed1e3877b8f161f615ed2abaad094288e367b46cb8430218d49268a98104e1e3c38c62463822ec13f0343d2b6d48b4c0f91a6ea54abe892f4aa40afbe8e7b0f5f634fe1c6bd258f33379182e9739e34f8cc4ddc5bf0d8ee2d514053a67b0b14f0cefa2d4f80e26520e7de7207e7047075d5267899b6adaeaad290faacd96846822a9dfc8a2e51e9d35c822e39cf54cedf1af7961fecff9c2034f7fc49de55f7e053eba443383332e533419543e799eac99c684e36279c93ce89e7e473023ad99be63c69d69286097f9239084de5a0bae7d7574b54db805a96025350308df35250b4cd87163bb48df3ea587d14f7962560daea578fa44509ab9a454d9da555bda515d6355f66cd44cd5969501a7d8cd2e83d017d0aefacb0ae5933ba04e7543ed0ce419fe4bcb9cc38e503de59a134ee2d49b8a8bb534844353f3d3e3b40363d4b7c3039a1e1d1a8496449618d8c0778dc387e29d988ead1fb42d89e98479dafb2d73c7f8f26ac050974b81a561cc1dd7fb418a108308fea1ea031a2106ef55a6b48000474a829c2a9c0e046ec4081d4e31de0c0c85d031b8613cd1344239a458045ffc4ec111b2cfaa7fb0f3c0aeb0e22fc4f92cc688f21666c7a4b93ea5115b010614eb8c21d3ccf8b5aef5a3e939d539a9dd31b843eeaa2a63345e5add236de4389359ad555ab7a064c991ea7a5255a7d205635bae7f30d3e53ba098f4a9f5f6383fe14ade6b8b710610e25ab9b44f740c10162e7c7748373e363d3836352e2a344098e0927c9921b1f1e93131a1e55fdbb7189f383e3759a56017d947bd628691942140de4de22041af79620cc04e9d30695527b501a9a2c946f723e63345ba035455a1a1406ddc9f6b4aae8bea7f242af3d53fb3e794f9a6bbf91157ade94945b23877b0b10dc4a420e57fdabe2745dd7755dc7711cc7711cc771dbb66ddbb66ddba6699aa6699aa66959966559966559866998866998866998866998866998168661188661188620088220088220f87ddff77ddff77d9ee7799ee7799ed7755dd7755dd7751cc7711cc7711cb76ddbb66ddbb66d9aa6699aa6699a9665599665598661188661188661591886611886611882200882200882e0f77ddff77ddff7799ee7799ee7795ed7755dd7755dd7711cc7711cc771dcb66ddbb66ddbb6699aa6699aa6695a966559966559866521f8791db769190f6ac77f080214d42f52e622a5ba777070cefb3f366a09f5eb4ecb0f7c10877b4b0fdc5b78f0560b778f811ca7334565919f5b84051046e05bbd5664794df55734c764b5dc195b540a7dd4be2aab75ee7a6fdc5b76a0832034e33fef7a7370d64c6678b249fd4fa17061d6751a86d27950b6cd1a01534feec6e5bffae4adc951c204cdf72cfd6094a694a677c3705eca92382ff5526ed1644af7d0f7a47cd09d1c254c9ebc3538353435a6749f6726d52f815ab62407ee2e845b3d4082bb289ad21d8713dfea6502b52c056a592a9ba8d50320a55046bdbad56bcd24a865a6ad7e7afe698b54214459344414101042c20319dc53419944e13762ede00535a9bf66134aaba6139ee0de92830cdd362b1d3c11a40304dcb4c86ad5269ad79d52624fab2862e4e6c1c89dc4fd02415e78c2bd050736c8e0ae42155781891cc8a8bfae372da2ae50d060e100090ee2c001161ca0c0dded7affb4ef094d2969a271ea47d55972b37f9ebc359624a36a1b51740167cd44141fa38f713ea57bbfd08c0bd9973ba2b85354ca248aaa56d5f712a04a274b786c94345179ccfb4954148f8ae2d138f563b3d5bb2445dda857bda59f7dd55bda3e34e4ad716fb9810d6ee0de02877b8b0dde706fa9811b34706f99810cd0c0c3fd4d34e670d7268ac5ddd1b0e2fbcc777d8c8612eea73b1a49dcf7fed38406b832b3fa42685877347eb8fbfafb0867ac3eca19567c7f3ea38aa1479970f733523fc389bb9fc1a5f9b44d66e0e1ee72b8e36cc6950a1461c614eefe6a6adaa6506a0611ee666077549b71e32bd20c1adcb7c98c1f2629285c861dda2c4307db2aa30b77d30ea430e1f8cca7d2a46ad354c65946122fe3c5ddcb00e2be4d76ec3074e086ab1f45d52a9326c3ca146428e19b8cd39d0c2027e3860c121932b8bb0f9f14e031ec18638d3595d6ac86b45aaae28e83102c319410a30877772c4020825210155cf9125081273e4f44a003620481bcc04e1a4940f1c58f2bb014a9c01a547c80c811ac2861c11841707791005a7059c348020519b8bbc8490c66b085901ed48002ee2eda028804800aa0451176dc5db484116a805155902181bb8bd0e861040d7c7063cac9dd5b2080830c520001012e7881bbf760021d0b404109d488820e776f39829a0101142d242ddcbd25094e0282b0c490259ce0ee3d6670020b12a0a822c60cdc7d050d60e00e911b621e3cb8bb480e265080083ca000c2e7ee3e3630b210c5e90542f4c01dbb34a1981819196daa2f23736b644a1a2807bbafcc5e3d12f39fcc3875d1a07daf7a5354a3f2939744af1a940215c210c2e3301e60857172f74bb3447e634c1386916bfd19bc6385093d177eacb7aab76ad2a52eb53a85118c1b77d555b5ecc262509556c9d3be2730ac0f6a07872eeef8c201eebe8b9cca5fed9a5a23f8d594f9d8def41f49b933aa06523aa003ab0920f0228b5fe5467b78e8f269bd5b2d2f8fbd862e2a072b6361862e2a8722525ecefca52d62a56cf5daa62034ab18b6820f5617eb36a99f96797d94d545e95a690dd4850e5d0071bf9ad8cbae978b2270110717667031857b79b91872772e805a7c38c1470ccc8b69e76bf5514c364461a1400c349f6846511d5c44c35928e87cab17befa44810d7e99d2abaa4e60865b31bdaacaeab5054b0c5c04661b306839c0096440f559e62daad05888446ac951218e2d306b8b18dc7d05b7b6f8a1051beebe77cc9ac955aacb266871f2ad5e5ac86851448b215abc38aa3319533e9336b630011577f71b8c6302b288a37ca11aa6308529645102772bc678cb5e33e9dec206be7f726f79818af1b5b248626581240b1d9fb1249935d7b8b7b8a0052d5758b0c6172d6aa4e12fc06205680ce12c717753837186196dfc5043b33bd8f4a6b76cb9dc7d01eee2011adc5bca706f21234a1a8342634c55a88704d6a5fc1e438c16153c600414d8ea1584aadd055e580c46afeaee6a38162b9c04a214b48461e5c7b5e2de02460bd883bc4500a2245cc1dc5d8d1b788f00788f15dca530028b211c91b138a3dc5bbef0a28b9947758f8c5d916ff6b45c51144270c469cdea2db2535d4413f2f5a394791dca34fff3f337eafdd36666276fd3d045a55af7644317a5ea8c2e21f10be17fa11cf4e64a3e4657a91a9d211c4c68466648d78822fe214d8a22ce2655af5ba34ceb357dba5a4d3333302f3328ade6e0b7413ff5b1517d4f8a5275d43737aabe79a3614232a8d289286642d8847f081543bed52b85d2e585c54c59a95a6cec70d1105ab0223b259afb29f1c998d5a922ade879615e2c46cf28257a7fbc46bb83b556dc3b7084dff68565f79a199259764d254436c0340e93e596959ff6751cd70d89de284b6cbeb669e1d6915b87793a03896a4062988795db67f8b5ecd342911b8f3d077265c6dd6efb34d30b12d1a0c4df466ad8f5ca0f31ecc9234433c019a7955ff67de46f1b8679da4477182092c1469259f77521d634cde3b8ad0811964b626089b3d2cc328eeccc6d754b29510c3c0f83dc076ae1ddaee7912414511be4f6e6869919de3813bbe00783f0bba5e97d1b4776e1c769e169a7d6bb8aaa88d8e8321234cdf09a5979b792fb5e906d77d3bc727bfc5ec861ed34936af5461453ad62f5a67a38ef2972c1f7851f725a77bb92e4c8ce6b01ce3eb2e4382df330cc659f9d44f1bc3ea22b24b665d7fc70f9590886dd7712c56c9a334056d5e64e4e0e4aab39a228aa442cb85aa779a486856499ddee2b4fa2a8baaa69fda050b486b6755b499ae4053b1c7ef79e44f13c731451f4446a9058dbb28edcee7df0db4c5094c60db190fccc4ce32e4966e09f66747ed65ba2da86f386b40a488614ade05e0f3f873d0c7ccc7166e644264784c6976087811ea665e1e7991a6812c599375f49699291223ae37e18477a187737d4b62cdc64f48aee8862894706159991698f65bf71db7f5d089a9f288a62d05d659088cae8b0f23b0dc4a16796a199996498f723370f67f739d3bb261ea3c498f6811f36312ef338ef13a30c31ac6999e6955dd85dd3530136b910bc18666a66d7e1ff147099f9d967e20de4b832fcca30beece24e033b8ecc3008feb5b291f76ed87f1867dec5400c8cfb819a8699f766f8db3ef04fa228e54d6b298a3352701e95816c64aee88b2ff33210243990bbf8b94fe89ea629289fe78be28a665d52228a7a5d5f5d7756bd78cec359b76d19b691d9cd26d3aa4ad9a2385384a88b7fafc44caec4e4f77d77b593289e299428cecc9cd6ac5e1d6444271071919920489addc791e46f61a6a974da448482ef38ef4b8fdcb2cd33bbc77a15c5acc3c1e7e71c5114458c7e94f29240884eb07519978124e6be30ebbe214d9aa294f72445f1cf954ced1c445b605cf9dd52d31e97f872d93d89e28f28aaf7bce516c5287f5efc426aaadc1169a181dcc661e59b8f43f39699094ad2fc362c2c43eebe8771dd8c288bafdc32b3db3cb223c16dcbb25c82f066d72c2f09861f489a2159d3838804f733c3ab65a5c79938ccb86f04d8e5c090343d53fbced3c02b0230ccca6d036f1786a0196edb098bf203c1eb5d8dd44acf0ccb3cf43aeaab74921d5108f0d7e1ac7bef7aa197659fc623bae22bc3ad33333224cd30c4bacd84fe298aab5497a2380305e8498fc80acfc324f61ef3b6ff3a4f2b4fa2a857349b382f65faaddeb40acec34cb3bb181786de2d3113d4321f44549864c7997f3550d33c2d34cd9328aed4157d515c1f044f861e87b1499658975d8efc40b7755818622488b30fdc2e289a82334b30c4c8df6ef6d847e293488aacdcc07033b18bb1df6e989d3c6062e42d390dccc0f73890fc93a80319487625c6be2bf1f619d9fd88220e64dc6682af3deeb28cbcdf9d4451136d20d4aef086e073f77265f77d188653e427116900fc346ee3c8efb9ed2bbf0e3405a5c8c7a64f6fb95f1467d47b2a714451845fb85df2625e784b93d4b08c26aaf281d966766477412dcceea6cd0ce11d191f445074d9931863a1c69118c7793803e0d5c82f2f8631cc0b71c66100241ff4b2acc39fb981f7d32e00925e17deffe7bc6f233150648192331f0bbf0fec3edc71ddd3e05bfa1155e0bb5da79959f9e0c5d9869114d8bad7b8db6998676a9b87652751c499e8090ce4b2b2c361f8ddcf304d1339e1699af79c87912679bdae0c75444d80e0f79a09661cb88126178ae2797e89239a00d8fdf76518fedf3a2cec4a1e444ce04dfbfb5bf9651e9899dbb684f78119e8e18ebb0f621c9a12f8c2cff4dee432d2cb4832cb8e8822f06df8ebca2ffb30fb32f2823237222ae64672a5569a24fe3eb2e43011042ec66160987d5bf6e4dd384ef480bf1988b752c3a54796dfc54ea2f8891ce085d7c4ba6dc32099995ac89d441146a404be98f926d64052c3e05666275124891a60625cc9919c866ff895da056b444968e45ff3cbc8af7cce34b1264242234b73fb0cc3ca8eecb22f131db18524579a198637cedb3cee33dd181172d9a69158d8755889bdf28bd82e096219feb8adbc1c3649066cf731486e5d098297bc99464304d6ca8fc34290fbc2edc3b47b12459b213c7c6f793d8cf3488c651e7612c5f3aa41f8a639dd94ab6164c6911a18e22f3b6c3b89225ea134a2b842af4cb6fade0bbf0c04c36c7baec3b49328cea8bfeec8d88822fe9cea206342b329d52a1645754df51046b30a4d99462aee233f8c034bace1ccfc0e9f4491f352a615651611fab410cb3aafc43a327caffc14697638d44caf23b95b625fa8ad5979b9f233b76cc3fe39f44fd39b443101fb03b5cd2bbf33b592bba5a79d44717b2a6696a6569a9cf6e5d769df9f44711d7a54146776a9d288e22ed52b8a386b1920a43c79efe5b42735f337bc5d75dd32594a9adef7759b477a19900e3298f6364cfbbed2dbcaafdc3e8f3b89a2286ef54394dbb86ed3b46ecbc00e6bd713459925286fdbca0ee3b4db91a14786dfb99521b769f7bb7b4d2ddbbc93288aa209cdd76422a394098862721bd6691ece4cedbb1a49cafc2084a6e152c3c8efcb8cc818fbdbe1f26661467e21cea623a7ec9a77c37733316ec325f69d445114457127092a3f2c31d004b14f2b3b9c85275114c519518c9293985252e6cded6a18a761da8643ae04372fca637cb10dd3bc0cebcaf0b34fc560863f8cc43e9233ef839f61e4e6114554896597c41bf685f8bf6b6253257febee669a5e586a59497ae0793fee7260867ddc97fdff4782a99f11c4cc6dfbb4d27c0d63dca741e9b146809e34316d66c7711dbe9f1796186fff0bd04a6de3b810c43c0dd43c0d83527a9e19e2cebb1ec8dd320b4f417458487ae5c5dcc5b0ffb04e46e7c99691182cc992ccc807414d03e25fdbc2ce34b992d4c0f25f1467667c4840323efca0fd478238fcc80e632ffbde73f2755d893532f3b807376cc39a6878d3380f93d973e056961893eb65e407de72c34af0fb323c89e28e28aa7abdeaafb966499875179b970b35ee6e1ca95d140714629e466e1f6210ecbcd0ec4ea2b8fa28a6bdfa28a6f0e7233130dc4ad3fcec0bff663035249a17264ac22cc4b6ff4b7a9de971dac7792920056020486298c49c77c1ac0cc199b2a4996648861fd785a51992e4a67d30eeb6cd7b33bc26eec06e0b4a917fb3fe8f0c921e2dc4f0f758186edc35bb72bb783e2e243d8fe46e187a6057062501c98ec31e6662d956729f6148340f7b532b338cf34af043ef248aaa474ba2785a57cd872fdbcc0d6f9ab771dfe661e4295dada238a34d54144d26511c62e741cee4420cbbdc9ba636d1e89065d8799f1762732b43cfec41cb4af082a6f675e14c0e77432fc31fe99137cc36cc3ccd685b6a75cf74e79b33456519514c5159145129b407c77bd2c4c26b6e7f3def13459b1b2cec4a0c9b1e199add2d3b7cb2c1c80cf348f323b70fe3b0b69d44f1b453290f35a587c30e6319c8811a4782df4914d57b2a8dd0905888958fbfd2033dcccbbc9328aaeb36cd346962d7144a07199107cde3b8ffd2e3beb2cb2ef627d17425a0d34ccdf330d6be0cbb65089e44f1d7acaa7098e1322febc28b370ff4be6dbb27515c2f4ad526028e7821fe36b3cb384dfb9ba9b41a74c97ca869d72b3913c4362c34b3932862f5455114676848aaaba4c7084aeb1fe26766df7b21f665e4d669ab7a24e4b22e2c33eec94dfb3ed2244f5a14bf447dd01c5114c59dea1034392d2c31783b4dc35ec6992751349d57e84da28866efebfe765a89dfe334f071b79d4471f3b83023c90d77e1f679a5697e27515c51a629a60bc9f2bef638d3b6aed3c2ec248a265114458e2bb3aecb409233c137b38fcb4ea2881fdd3810bcd704bfee76190966dc491437fedfa6f5834471c6ee6b7f6e56513ced7bba325b43696d0a524da61f1901b0c7a675a75493298622305776430c899411808896cddf2133e9730030087841c090ccf4427feab3061d7040400e37e0704366fa130d36bcd82135bc1c000dcadb06036439d0c015e085007600e69a32194048868300b414a54b93fa42ba7cd564caa2789d9696ff05e065861d6458d5bb0e0932c4d24c261c4634b81c0000d9a5210602c0a0e1df0148945b961fc5beb007e042015a18c08ff58386b0a0e2339f4a981538cf002a789d667d0c69d57a801ea09699b48f724fd21484e6a1b72d99097500516652f57a4debd0d3e0d60c62c84202d1a32eea23862c5d6c20a2200079c1d918c30e1a77170374e14156c0e2c70bcec61847a071eb2af8e8d1a2824b1240921085b09004107749427497246e70972190dc65089b358006a4e15603de70ab0140f09114dc50220697190810a4003204b1425c66d0a109eb561346dc6a02895b4d60b79a50b9d584136e3551855b4da4e156133c70ab8924b8d58414dc72c2c52d276c7097bdbacb6e80e5848c5b4ef8b8e544106e3941845b4e3ce1560398e0961358b8e5441a6e39e1865b4e04c12d27a0e0d6130670eb099b210390810007c0c3475670f091152fae55a8643328c64deb143223000043020000d310002030281a0dc70322a9603aa6f71400025eae5cae66a14ae428c931658c31060110000000000000800193871d18736e1c52e850ed4bbea45651fcc66595e89cb1cbfab81b79da605983b01a8b33bf149df7aa273eaea7b403745bdd3515416b6fe2fb83ba1cc2854627bd8e6fe889e2101ec0ab704a071395f208a7f5587e00e7555ee79cfbefea3e87453db94eb2220a55a3ef622f837ecd6e66b0d6c330279e540bce314e4f5f2f55d4e2a1897541e17d2857df82c2acd39b37ca86682e00dab81ac584cc44ab15f50db89db986b3d51d3785d360a59dc3536b6b8b047d4337f2f88a1753090d61cd4d9d6220976c2021ed94b9b617ebc07c414c8e4c1963f5bd2a8bafbe86fa9863d8aecdfcf0d251d708a44b7dc55554bdbcf3ff4f9493030cccda43160f33218f44d3dd7b021bc53c73c4bd8619f48eef803a7de2b90199baf834e0d2851f7089b43a2689f4cc31b1f325b0d75ae41c0658442184a6eb4ee997cc9184d44ea46ac405ad919e9f9825a0c7f066df1a2d9d07c33527e89a57e66aed7b1f488b7b17a0b6ef16efbbf5fb6ef77db771dfadb9efd6e67d37ba5a0f9144dc483140f16a82aa842d1d56ec424a0d05a3f67f93d2fff00ddf0a81d945d96b1c9d7c80dbfa5c596b675a671ae5a60b76038d7036b22963cf05cefb7cff8a9c203c7d30718ac687500f1f39594e30c0313eda909b7bbb0541de830c13b1ae83d818d50d3ca3b8e89790fbf5fe17a14f5ebec3f362cc3c8c407c7610a869f0fda4ba1d77d3ee7db75290ab2ebccbd63ec7c472c163faa1d1cdf90c3b53cd1d021b36f15431041c54a01757d42249b2a2b0b2a12b97e2d424ae50908ce27c4d16bb6b307a9cb79621acec77576edd10de6b7355ec96d1c03ed477ef424586b02d785ba9aaa64df50a3481f2608240a2c92394a024d3a555d1a9b4ab0254388ec3611367fa1f5b6a677ad4e68f53f799a46a90a8326efd8a27458abd092024a2f277e9394b3e68f97d520314ba161236642adb3e6b93b73b4071f69889b61d305441d4063641a94991f8f385b7a5fc05d10aa35b4cbedb436e107ff88c9c5a98e9199d7b17716a61bf32aefdb70656d103a85eddb81ba97b1527da7bea21656781db438dcd7964b073ad172c9bacc7cd8a5c2a9275a2100bb5fc283eeea4dd0efff431f96e07218268d0a13ebec4ce96b1fc387966ace525f35ed357a91ff8ed5105b4af3757c09c80a6e7e827da9eefef5783966d606fe5fb9ad453edc4446cfb67fdd3c566f3f5e8057e8124d98a39d7e4d3fff96e514fa73298da50f51eb890ca1ec93bb31a3c02e22cd2ae36ebd6ceae5963870ae0d6c17d03c65969e2ec730226ae2c684313e6c88f0216fb3a01b632c88a9c0ffffb51fdf34d066ba0ccf9ab9073357bb36ecc90206c6b486dd2236818226a21b4b49462025bce8206b675cad4475335f4be7926f620357065977c0a456cfcb10152bb6133fff398974b2330a8378907599ca93c85343115a5aa1f4cd709f5ba8a26435bf53037f4b233976df2dac5304914ebf2260c6da37b3e81d618171a678e9130299d26e6f0299c7cd2733fde7bc3f4ba3940deeb7e1c64601eabc4f8b62498fd498b8416089998efab2b463d461e5ef17a8537ea426f94bd54ebeb351cc16e3f4cc9feb861983576f9f4c55faa544784071168eb1bb84e27405a0afe30b34a2eece089f2b049bcee1c682c9e25396d042554f1bdcdbcb5b99eba274e92a9c07979cdb4c47c515b4fffad2c52bc3a5065a0a30f99c45463a0d5290806bdc4de7576437c73795d37aa2aed384b2c722e611eef82bcf03d7df32d26ebae3d5fbf496820e7ba8731329823aff38d48a11213d2170d0a77abb384010c172e68f222ff99e8a6d055130e5488d9651ccf4628385be1e6e8778360cbd74a3c1f96d4781bafeea7c881ca5df9d47ceb8e1ba899e55c17c8c41554b93e20cd429abe49179659acb3b95eb1c544ed4a28de678851a15c46523af4a7042b6a978f6abd2b3c36fa1356babe8f947a5eeac90e8e44916639ca73f8505d72ed625faa9676763b04e433ac8a8fbd51451ed943d4be2cdd2876eadbef2aefb4fed30164c5c6164deb854e5c9c473e5a06d8bac4931722178f11154ba5239dae52390a198e9a0eb08e4c980927f3c8f3ba182835f65130f4a4894f21f851baf1a76046c01847e5fafd40130619388014f391c0816ff5b3926dbcb05e85e264eaef2fa6558df039b63597f1580ae3dcc2860792bf5489d0527ae82ebb49ed4326129d50ad6702a74e235de4f9e8bc6bae8cf46bb59615a8c00dd32c3c4d17ccb0b82288c3c013aec24e13dd11d1a8a503ced0c47dfb78f916dd9e5507b81a1e9fbd372ce0450d896061a8469910eb9658d4ed6d2430269b0f0055b0d549424b867f10f7795422489d059eea8b8d21a01f2f5e1ed43f1d2a0e2409241988557e70779f0d05d73f60e2c80e9000a78e7483de8bb9366fdd7f248de66dcbd88c381986818de07b69bd7dc44cb0ed6439dd6e52843edca2570000b0bfd4e1e5714303a0f268548e6186651ad19c651207455602cb46e0510bd871a771e60978606d4b52230e839eafa0e835e3f30c01177f8b3c0c31b7136052fd7988d74acd1e422eaa49b0726873d09c7009fb846f0350111587fbf9459d462001b60c0aceca0444c3af2f704d6f6f43d6c7f813e3c3372c582179f60d576ac0253cdd0cbb963a28abc81f84485226e2419060006136d62fc7e800e4c00bb080093f4bdc0e17efb191b8b50463933f76eb412322126073771c98b55d3d2b7715680c4b7f005dcbb247229968020c2fa8626596340d6deb00905d88e6e8007e4d0684ee16145d2f0c61cc56b7c6734fd1d6a9f0eefe8932409af6e891e0f03d2a20965691ab8073ddd0d20bf2b18d6de5490652a819d10f02c5d063b2600550c2e7f85e10d1397feb74434bd3d0c480cc1e8fd2882239c77787a9a5605cea3e66f5d38a38c86486c05f31c3c1d81893c130f354eba25876c15fbd406180715d1c7f616cf8b423a3bf67dcecd44b82dd43625cd708da3f7ac7d6eedfe8e9b61afc2c4eb46d3f2ffa93ff9189360c42b8c6e6312577ca0d7b4a88c99f4bc8d75e0f5eb76029092e2e2610708f08fb05168b521ca260bdc142970f428f1cb33f8fce683a23621f18255bd403b755fcd8f89f85ba309ca39e8d99bec1cb3554008c7d3e3ce14a6e24bf79d407be26e30dd1f68e2adc6fc73128d2277c093f20724ab47da6f081d10dbf5b7776a55ed3fcdb5b1a4b66de25fdd3b6622781fe3f331d6343b2e63a17f00bfd3f7ad46017e99ce6236952b2a727f563fdf221da7e14d8fb0d1adf4cf991fc1be15ce1a0b0d1330e9d8b330843597524c1aad52f55cb5389a6373dae5fdf6742d68f7d9abb9e0ee1f6e27ca18e416c826c13bf8f6bff81913f353d3bb2fc5ee903d43541d86736cf2dfdab37ec6151370b0afae7cf860a775ee16503d9e2a874a1541e09b7b469f53893a7ac87b7b236bd7b0bce0dc298a2be644460bdfe140695bc2b61f797626dfedc85a5eafb292d66004677e73274ff52755daea4b11f009aacb4b8a3a4776329d8782180a9544bef259cabbe76f1a1737acf2016d93f44844d73c6e730788c5184f2ce315be4d9867c00501842dafe08ced077f89c0b7e99316ca2a38ebc69d79b0ceb8778015a24f76733812b711834765761091cf1e9d20259cdcfcd020e5e8cdc3ede1c8f4d0ab1137a5a0cd04c037133dd091a78d58db0726c2c08861a73d7006218668cac1cfed81433c07168cebd8641042c3f9a2dcecbedd1e529f4de960cbfaaa9cf8b7502f0877f6a4e4ae3352000d8398e87fecc8c80b16817b9f3e510fd165cfee35bbc5946391643fa1942fc3b7c47dec57d8883b041f4b174ef66adc73da6a64ef6ecde4c0e2f3d0b1a899c11eca5e4bb4df48707f64f5f1ca4d67a78d21c59223df073e0b6f097a5e75ed075ef0549439299cd146f7510dc61712bdaa9a7d1cb97cf5b413fb3d089ae3792ec9568fc6b56c3317d036cf23863f36036050aaf16ce7098df69da9df70036d051d673fdf5b552f9540ee4d1d5e11ce4417a1a20d731fc95aaf875a2f0cfea7106e5337b34dc8c72e05f6e60e2e9d2b54fa037912a622bf920165f3ce3b3d67f12fd92f32e9e9a641871cf0b722104237c9af62ee06960c0ad4e244a9642e72982a878594280e23ff6cd5cbca7ff218ed83e621eb4c2f9c1abcd5a31473cc736e48a2799ecbd7379c06a50df101ea2d8110503cbeb3cf22f8b32dae83ea88d84b76b057da835d7990cf6826a0181fd6fbfc846b037797927eddd3a431ab99a3d03d62d5f3255bdf6ab6f5c7988dd5f2b0822a088943fe11b329d6939d08684049b936fff123dcf3e48df063d5dbd754a4cac7dd2bb76956abad1873fe09e725f3d5356fca6b8ba3ae09b6a5f4abc55de26306b0d9ce10810be2d1d5a88c58c554b4e972db7f0d25904ccf7e00e7375c0ca091e48891d0b3c1079ffcedf874ed36c411b7ab8fd7511e5e6863612aa008d6f798f61bff7bf644d3820ed5eafca7cabfa71480e0006854cd1e9abb4b1f5dd189ccd613ba2fc53ee3a4c29786b9be9cd56886aab87cddfbc7a34c81c071faa5dbe87f0deac0ec68f8f38b00005752844c6eaf9e9e33fcce79ecdd829c02b3b1487741e89d39033aecc3a7f3c7591227450b2f577b9cc48ebe109f8fcbdde70e0562a5170e1828dc85e0a05c23c8a500872e227fc49efb6603e5038732fbdf39b47112e22e5c83933ede118b11d3bdaaf5c2dd935bf8b8fb4a011fb8d1b4ecd493295c82b9665cd8a3f28e11d656f8e834a3417b3801d197ab1685b616ce14287b9b51942be4c72e1252bab5c64d6ff5d9f8476b4ed306c9722c72d846be15f4172315971c7486a158cfad4433592270835276626334f67963ba61cc6cbe4c3e97b8bf85c41596b8d5d719c8192db0d74bfa5bfd6c80d8af42ed572aa696c1a16ca7b38beaae5ba3e4f99b80e3c678ff90b62a5ce03527afe2a2bd1ce9098b35f94524431013f66ce4387cea8963a44730c2f7217e64d6d958301e3fcef4d9bc2dacc5a0f054b7ceab2c6bb8681fe543805178119bd54b241719b171dc222589774c374e25eed15dfbbf5fd33e9dce6bba7bf7357dd218d0e2518518738418029b34ae4d7d0d3409ee94134c44714d6b1b8e5defab48e9ba328724e88b5ba8eba502592a98cd85833daf2f328a716c3680e262b7b065c823e923d5d06a9e633c7111bc3eac9ff34e8b37e440212f68f2c1aa9855d03b249818cc943bf93682663de55dd71c31e1faf0aa9657494f6e0a0e71e4bb82a114d309366b1218cf0e1cdb271781976ad4aae4c8bfaac9f4732544bd030eda312d259172bfd45e4b05ea90fd24fc5da73f69c489ee70553782bc7991994adc5eb43791d1a99861c60dd38a5ccf100901884f81b2d0be941f47683fd59f983ae376ef06396ba1ef46e7f37feb0764a0be71f246e34bcd9da617bbd78caedc00e180cc09b2ad330b40348ef773ab128ded1835adb918dc979bca29afe0c3014e54c23fe3eecaa7c62179c93fafd4bff49785f9ef663b32fee2df08ab2004f73e9aed595ad0e86d337b75cb0d27d51976df10983919f4b9c37599020afa2461bb402cf2469166af38628bef3745a749afa08a2b4511e792156f08afd4a4698e85981cf9eb227e23ed95ee1df6474989f97f6ea144467270510efda2175f1404434e0dd7563e38a115c3f22e1bab983b21225722a2fa40216f6252d850328f15b54745a9dd552f0da10c33741aaa280a12110b9fe6ddd6fe084235a05a02e4b729778a03d428e1b8bb9a9f9f7fbf0a96759c1b1ce808beb7562f7183a1ccf7a750eab8734bc42d40f6ab47c114d132778016de9bd173f1b61239d2a119b510e63d36e87bcce7fbbe1be5bb828e20d2865919652e1262074d0e36b0e5e19f7acc95e345e4d5e62cb8991a84e488be634e76a51a626d4a7851506cab593e25ce669da0125e248d58dc281a0a2bc651e46439489fe38f034d30ddde524622e9af8e986e054bfeb16a1b6c3a27b35845fc75dfdd5e9b6fae10dfaf8285678bff01d784f87c1f0b067a6d9ab3144053dd99987e0d33ff779a32f93cf2fcec18abb274b7bba52c682a5945b52d6b02eb90d783fdbba3025ed369d96d10318eea2eece1b1e6382fa628a3d5868f3965cff446a2db8e0f6230899c07a3ecae12e985e4626b7b373145faab58f7a227d96f4385ebddae450f285e323d94b55af4f00cb056569d5566a61f83f1d0348d766e54cea99f8b9394e6580693414e1ceb345401b3586a4d3b23b26453f2de28193d48a82e63f4e28a9c1279d2f6929944dcece01af7fc8affe85287950989554081d33b2d26e13e98c171332aa14ed9e48961963c324c46ad036994170cf3aa618ff4a8b54109dce6b9147cb0125604984efb2a3839402b834b85858237399b41d66848824d79c53cc7dc76860e1640565c0242d5ed67802ec0c2ebcd920aa205d550a573eb583e081e3e9b368e7f061241026088befe35a2f6ffbb450770330933ba9e7eda95b98d9d360db61ae4bf7205c1db1bcb94f5f3dfea2e9f6139067e4eaf52db62488d6b32dc33537ce584d0f31aedd03466b78f8c1da1e7f5083078fd6f0f083b0318e00060c108581610461631c010c18200a03c308c2c6388bccfa431516d30d53086634a4f0cd0e38be05638461c30031181840002b0608c38831e230308000560c10861163c461600001ac18200c23c688c3c0000258314018468c1187810104b06280308c18230e03030860c500611831461c060610c08a01c230628c380c0c208015038461c41871181840002b060877c95d12d8521eb7706e33aacdb16c05b14d7b4d98b5605633969a8ffeda41784c1a8750ec34b4b898346ea1d86968713469dc42b4d3d0e268d2b88568d7a1c5d1d4710bd1ae438ea3a9e31ca25d871c7753c73974bb0e39eea68e73e87618421c4c188710ec30843898300e21d861087130611c42b0c310e260c23884608721c4c1847108c10e4398f4208110d10314c2f30ece084d1e18232c7a0ca06588d6b53d03b537c08055242718d1e080114d5f528bae765ead5823321b42ca5c64e9ab48078a56323994e6e97b20aeaedcb4d10764e980c4084d094619e1830024be48874ec39c25d9583d419605214f8d89e736e94aac8765c4707b167626700b51f0ece4625dfeb0b57e06d3a75ae357bc46e73fdb0182929f29e3616095b4522359cc12f0d326e8130506357bafcf50aa39ece9367072418d7254099caabfd90ae85bf28efd7ba7dcbb024ea9b3dc87179730204d7bb1e9deb854616b441d532df1e3f7c059dcdfd16d9a77c0c3aea64602a0b4072adf607edcad62603231c77f4e673903f658f71c88a018f31172251e76ec69f2d1b392d559751e4a296ae4ed4bc0784cd2df6829985aa7332a71f488611899048269db7606906e570fee44acf5f466f8f4bc7d818d70865ef75e81d0e16593017e476701d8cd38edcda0154f59a72cc48f6c4b03fa36baef423b25195ef1739d231bd5bf1acdc93776e45fdf2f861f73ca0bd195f8bb362cf224c5ab9fe1569f84f57d84bbd84f48a1d630fc20e8a3184096ab1ac73f29dc7997c26a1c69ac6800a8c12ca07d7da8319da21d13138af4ce4bf69c63c6348b2054f9639cb9df9e7fe9d5b58198c2bd1c5dad0f71570e480d86984285a3ecf754a7ee8e50a4f4b5178ca6f67fe67eeff744fb8ae06c29ab679ccc51c43f333ce23bbc45f051a28b9c2d697f1e85166e43f8fdb3dfc49ec167903c9dd014e93c835a6d3cfbc758edef50b3e737ba99a06107024412dba764c51bf2de04d4ee8009383452a049e01776d7221927e54d4b8324265fcb524beda4c849e7c0f655dd2180069446c32390bb5659c30a39cba69b0cdd2307f917e85bb73117429ae975f144f50a5f3f5e7e1a2c29cec5488ff52e58ff25f143d1a691c1f9c5f253a19eb60914c9a39aaccc33c4b7a30c9735f19e5bb502522b6c7649f80cd43b4edf93ca127054a3452489962b21b05bbc53c073e184bcb635f79658b3dbcbbd55fcf472f468101154d1a0a917edea2d177382c0a5d710d344b4ea2bcc5d2b58d123ead7d17f15054efdc18f34d1867a3cc688f82ad7a62660122a0f49228ebe37d488fa748ab58a1196f696acd13b7299f712b3f505f4118896f51a5a7a68d100d5d7a294d5cc9c7a9e2e95a8bf53e8b00898e44d5eb2c8868148036f743a642509999a15e3b680a3b2100cc57ba59f4a13f1e8c71f4709167aa14b0d5462a258d059b89781be55e218d1db635ec3892362f9c25f6206ffb28a490a3adeb27ebce5402c1cf0b60cdbcdb1bd25352288d402626d3f3857f814692aca1e2694f57ce13e6481411b9454140bd42bd0aa90673e2c265e1844d883ae70684a3836b580972609fa7316d68cb53547934eda642d6b02781e740405d2c2538428976c0f9b7c5bf0edad268bb6c5ae2258607d5ce3f03a4ab63b0de7032f1abaae8474a45b61a5271654d1c0a2c070cb1997aee2a617677b37deb0f41d678f6e0eb976090f639cc1c2a9566042095e6523174c143e084912dd70d147157ccb65b18c572ced2aaacf8b790bc0ccc9a48a9d7f442f22d00632a739484516f7d36678125bc4278d456872090fe49b52e7ffdb900f03c1bce80fcc67dfb79b06d23ce9132b12bc597efb2818ee566dc4a7e54ff5e9e1c307239405f0ede28b56a3a239a517e5982128e1f574e583312401c4f2fd9a182e383f2c7d9d9ea1899b42085d45c3a36603833e0b22a3e4aaa6474037eb6a01bac570ca01f19ef2261c3ca4c8a44d8d5cf1006a8bdcebe46727b3bb2ce5c2fcb7bc2c4b997fe6db27188ca5f14f7abe9371a477b5e7bb849a2b624b5a537a6758bfbee1875447b201d489c8281c3fe9f119fcbf9aa3bc1a426683e9149871e0c9e9fd32bc219aabd73c5b72b1c4ff359ce69d418320fecbdacf43494e70734c6702601ca763291a1ed89bf9a734ab857a2e0323c6bdf3c4dd3dda8f4e807aa17a4a5472480443515c7ce9637590a5adc689a8af6a229aa041fbea0494c802b2235d3e9cbd78ee24239317441f05d2e1eafb1603f5d009574801665f91990dd4fd55b19f4890c25b40585421c23a5e626983c7d2184e719067e882a73febe9aabeb3cb54459543f3df1bdaf36c8f9cef4ce25b4cc8dd51a884413a7cdc6e3f831048f306c727bb7704dfa92c1e37009b1d250577c872ff7c56da1eafe1002f976984e0f897799159b82e47c7336707cd082b0ed3e15c4a2dc2f3d018904f32095ee27c8bc918847a3f30832ed290f68f75441615f351f4bc3b4c66b7b08e5419d7ca1c00efd911a7edccd1a13cc1d8c79cbf5b876d98e336e861570163b703f53f150fe5aaba5a523cba620a5bf37dc6e03f580371224e0b70ddd7b8aae6e1e290d501dc6dc8c4a0af0e1fe1b2b462358a3c6df9672b76c8bdd6ab2210bff66501e6f820b6e553a4f71c885897fe7466642d505b9b2ccc11c1b725bef53d8c8257365020a249cb8e7af1000faada465b0f6696a08ef1128423e9251d8a26c1a51b3c4f73caa1eceba34929fa7f7a06d7fec3956b71a65d296c50ef4908228296bd1cf434a604f878d3d9be2a69ff78ef8f6bd889afcb766e89da09a9216865df820872cc25957ca0bb91e0bf483a9fcc4988a76275285feb960bf5dae711ac510df9c6bcc41f5f64b02e3898c4521e035bcd56db23ce6fd2412d778f3bf8046109d24e6358b9d250b4d3ac3d3cb9f76d783367e5bcb634b4a2616c162cda372c1bc92cb8d7e91758de4aba62d4ff1654f900b0d10d41e632ae2368694975b606fcc9d929441cf871b41060bc818d027220ed7c4d232453990f401af23c7383bb24101be1c493c097eb96fd6c2680f0ee54d86449ac42d6a201b32cf2505aa77d15ff6fd5c93c05cd426b4dd077fcc8db5347e04ca44cff5fb95134e17c9d4a655cb03d990b4c971b64b3cb64038f9705f17d18977d201228028628b5c37b1d58183da75cfbe7ffe6e7fdec57e90709f1ff8fa38f986b1a61f51ce32568142cde0ddf7d5ba07e03057ee5a431ac142ca49fb23e769273f53fafbec369aaa9fc68ff1cf90efd9fa1d7e8bb29596679bfe593f34616f8cec970870e41f9b5771568207470cd93c6739c6b66e2bca49322628b0b573c64156c20dde187680ba64dc98980d1a72fe4595c016865c8b9aea82dd070ec1d40217c9b8233ce354faaf662a03cb5e6a9f1a03ec1fcff2a3526bce7616238ba9ae91395ffafb9406e9571171778d5badee2206ad41b58ff4d729b771e3ecb5eee8ca1288801b2c73b0add113c88088cff31dc3cd100cd9d33d414ef90afd5c7a6e024d7da8e915b539d9c771fb38b605141e532bfc897ed32e7cc3d51655eaaa58b7e7678ce3d776144b344d3633552ae38f1d01af85e421f8b9fb0641b3cc651475e8a9771979a6e8da3523c37783c305caeb7aeebff80a5a9055447bad95e6bac7fea56392b8ff3aed4666d040bbbdf592c31c40168061cc3fd9a543e9c38daa7c0836934cc0d6f593c58920e6741800d6af6e5f4595047ef2e6c9efbd49c18f0a6dfdd5535a61544f548d668cc416ee16d66a1ce39c9f525c6a53d93bedef957f34f33b6dc74e075a9832b15c17e7f60d3497891b8b37376700ac02e9f95f931e996bd5b3690fe9ec02ded94253bfa8d0eacc5701a8ecd7dc08e888caa99cb7dc1665c968db1e69efc02ab19603bcc0fdd39f656d947f52a65a0f3e8748caed64de8e14605f561d54be58ba22d64d4f78858d1ed9847664db403d1af5cff524538cfeb1df067d197ec65d150a37bebb7ab107a2b639ed8316e63cd6d74017fcf3181cb487aebe7476731ed0a90fe8f6381d3a508a6f79fb569fc0c3748f369ddf1d57c1bd5e73d98d3b1541def7cd4fb53f01e8e77fb01efd8dbf99a75f26340e4f8b488c8804b71503ec5e59c7eeccdcac6248c62a54149ad67a8b3826322eb2205d65c9f95475200a23e275d535784ae3b17e3705ccd16039a154819f69c963bfa622002644ad6f90443223d8461c05ce55d4a99bbc1f3c1e3677cecb0b469eea1996d0b7786e02775dcfb74a5e6cda30bc531eef2ca8ca266532e032aae487b0c7ac7f4a1a54d47562336e58c4670b9e44e95934d38202a2810dd785d28936428d3ab814247033e903e9ca6daaf17649a97ef0590c10cf434c63df8a89d45c3fd3e1c751b379c1507f969617b1c2b1d1207ea073941079bda6b231c333e078a98205e458fef45fb1ab9a7bf970e0fe236270aada8fee8c637b7480183b9c9470cb41c0d8b7833f47646836d65429e0839acdacfd50b929e312b9ddabe8b995d0f8b8b4914442a1f0c8b44ed42f9a3f4557046646b6714b427e7246b5ca9d850cac17669832bdf16b4080240dc3ba3796100488af39987f3028cfb9dd64f697b3d58e9e4e0cbcf8a024c03bd8a34021a72b0234386805840d167b49d244b3e6d80266c2bb36bcffdffa6c2b5242b681d2cb3b91004c14397a5989d3fc318ecf9bc6bf35a4906a72bf444c9aa5dd54f60856e05c07b7d69d65e3dd8448a353c971568ca0926b8ae761e1d79eac2ee5c1f30918090fcc5f7c9440fadcdcf7d4a9d197cb061cb4312cf2cf316de94cab01cd5b5c33881f351a99f5fe646466d5b480c601b298a9acebd01ebcea4fa9af0c2845b642ae64c57f396554f30accd33eb3960e9c9a794bd79301cc4b0b93b4e56e5e337c2e7dc2507adf479bb8f0c740451bfce0ba69b657117d4acdc009464f5ca00a166849dc36bdb9a0d2f4066c9b02c9703005931881fe8f7406bf122ee5053e0f745425524a9c0c39c1abac7ca129f0007c141fd07e99df24a6b24dcbf470f23e34e399379c582be28e2fa4171bb6f179afc63b491a69fea1bd12e5b28e5fdd2774103f2a1796857743694ae8683707818462a030f6b1b07310b9b0997b33d494c6fe9f93ee9a4ea3bad94878605b2f8a2e49edb44b5125fed41662f6c4e9373d2ba86aec2246617c0e72ab552e92974099b176cb457e0f96cc93505d486b54de00db27f79fa4f2450a6767853f0fa0fbe0fafd01c5c0b98f7935a4623f0c4a5103c1609575c3e4b03f906117e17d87a13ebf716796440a07805c1ca2d4a93a345a170ced648e582bce2aa29933f2c49cb1d8f7f3bcda6cc2c05ae04855de509c205b11994942b267a4af61d6660c8ae3635fce8e5ac9a884d7e0f8bac61e1a27aa469b1e0e9485c6e845facf11aba897d41790226a3dc8a43aba56a7c40d32c36e19be6ed6856e158fdac979e11b123328eb41d0a0705b6366a11bafc6c2bc88afda6ebe6f2362d1aad22249c2777d714928726f0829aab47cd17b2a18ab42042b91b330c7817593983ff1185e9438051d1bfe6c6b3d0106cd2edb47028aa26d96b487f285bbefadd9c250d9fe318ed71a2e4475ab12dc964688efc73c6f984415723c48deab08bafc0ca478fe7c69c7cd807f01d9e96b76a713505a1436c6ca9df6683820f00ccda6496b2b0251acc705f57255901fa90d8d57edfc663c3689476d39e2caf9fa045b1067ef3857719894a7e933910badaf3b803d0a25016ff8ace85ea1fcd07e37d38c0cacead5604d4a0d44bda2691728ccb76e23f38a2348a3ba255c351c1c2b0fe029c951ad197ff574b2e89d2f0d87a2398cf884edc86adde45664a36aa1d658db8c5ae8691b1f0e147c4de3c88fe72fd79a2f22c81b2102a05552bdb618dedb367c52a27f8ed15d67afda5a49e82901c6774d3ea464ac0ac873e5c29854bdcc14de59cca2e2ff26df3a6a91835a56ff544dc5d263a3b50660c360033135b83ac459b886f40fe628e200276cbb16b475c7a90365e71b6cdcac00d34fcdf18b12736271a51cf18a5493341c1210bb5d19f5fa35058bed353aafb1b13c82bbb6aeabeaf99c0ed816cd5766bdb9224f7611565cff27cbbf21e3ecfd8722ba30be09bc3381fb28db1f760bb8990f9e91e9e7eec12a0ce56b224e405065a939ce7ea3f36f0473790d6338e44370f5ae4159b4e6543f3a829f5cb7cc0820806c72cc6cacd5a685a0a077e693d1f9b09a13ca2f2dacd94d32c0fb0cbd34955479b69c3af8a1500ed84cd98a210dcf92913ed2139e2e049b623e0477497cfff5b634baf880721c34792b91d3249391b2ef3da7cf968f70ab4193a7cda318c840a6954c7fbecc313c7bd4b4c48977a6aea5c9ed8eb83a6a3ef6cd4962373986a576d4d5dde9825515b851d1d171f1d4bfdfd70802d8757613fdb0bdea23694068c223418492eef8bc89874b2ad69b2f684b7d647f09e96ca7603afb75d7432394c428e7a5b3643309cb756dd9359b9c5594be8a90174bbc7ba4505233fc9e0878559a7cf89fc2a3c5e3cea39520a746bbf0b8da0083c3a5def558a9cc033c083257e9b96046b4bb22603a9c624b4021e5a03b64cab1f88ea5723d24aa79c0d8d581b2a8250737518fca3a656faf79d5df4e11888ba6992b4d02dfc70041d0cb967697e892d38131b2985412f0488a02c3a58eace7a2887baba19420bac19290f7f6f3482532b1221f8166a3919fa625eab30fee90c771a4d7757513d3c2556946919ebcb6d68a8ddb5b88fac4d622ef9de23add373cfc0c24e0b9423a3c653de3f3159b151cefa04f1e9debeb1188dc6c667efc17423f4f48a026e60474eed3e4f6b2857b231d92301f77659a4e3ce4b5ac09709d8a99cf915d225893ab92a3d6e414bbb626a2e92bbcb669ef023fd1eae849aeb4d675c90bf9fb9f508dea746abb145f45a7ffac77b996fd3e835f3f49ae5e93452d4194c57a2abb78d11be4c340c02136af8a07fb9036e5698027f3c315708e17b8884c5e65389f7b0c7bda650b2a16f5e043da73c7b942b9e3b7bf4d42495eef4f7bf517e3ec6e82ccccff5b093befb9cdbceff75b546be4413d1b8205f9a83cd090faae334f0bf7354d137f8c00dd56b59018aea2be43408f579867203cc0e84110fc436dd209f16f5127464f7835d2acf23ce180c7fd37043e8c283f8f9b228d475d3b1cc5cad20683a1082808f0bf20d65a8b76dc33438c3e07aaecb574183e64d7c4bc8e6cad483612088f32649431e6dad88324a61a23067508b963a8ba66cd3ecab1f3d99f31cc9b99b76fc33430072c2aaa35ff5ace9f6c835d6524bfdef562448f5c71256760f2fe5469f15c8d3896c1fa79f1fbb32dd4cdf1e6da84a67c47ff790289133900641e4f468e8af1502d3d027a5105d9a87492acee0956b98b798ae5e74db7cdee47cfb8d86e812e97acef373029e9b25b09024d4df70e05e39c213472578b3b8c24361bb2b89f91f8a1e06f023ab125a4832239bab93a6b9222ef4bf1d13ab4b2726883bdb6c0c404c82a5895bb6f1b6f5c18e7a5521e59c2e5b9f914945075e41505eaf2623ce1d773ce5b52054df5e91455b97e287d149977d4d884ce9df1d89351159a58a1e8eee53c80b01ff350119337656f334e8d570f5d40f55a632075256cc52b2c3aba3091843ba63a53d2ab622a4d228e9a2d9f471d5bbb9be59d74d8237812754872fe4a1d69598340d5c2c19dc48accf4c75b3e510a3aef51ad4824420ae16ef3cbaa32d429f4e8ecb1f8b84f03022cd3e777e060cf9348b3c4eb3d595b40f5e0f4a5edc79a0be145aa8bb066440badea4f371fddbb539c7c9ed88ef39607093c913d7e2835ff896bedf1c85a1a2a0767ecc5e242fc37ff1e461c936bad015772bc05b51dcbad161209952ae4b832621de9ab118baee0306fe798d579304b9ec6ea501694e50e2a47fa83c0fccc314684ef82cc338a3d84035a93308186f24c05f0c699b07634671ebd319f13e2cb1b6e1f461b0e3af2131578985b0295fe9a1f1909ca3702283cc7f154101e7efd64f3dc7dba5154a1b9a8fdd57fa2d23281b25632aa3f3e3c800a4f51823ddeecd2507e4f4ff4d3d13c4660be1c6afdbab7e1f936bc0d2f3ac2f4e54e2f45a803e2b8671a9edfd07ad1731c033ba02d1270e7a6ef6d0c915bd0aa58725dbe3b0fc73c71e8234ab0b3a6d111468b8f47b3e2c5fc4bb6c53685f96b4498501c15686a796d388db6e2b791e2b3317e5c89c66edb124397b78cdb88d2fa6827d3f60b66e6a2ebdad5f15de7c1f29069f2aeeb9cff5a2cf2c10d1da89f9e89beab11f4f1e1bcdd9dede61731bfa84319f03717c957dd8b39d61ffbad466a4b0e8c525de60e52c5ba0868ae6f88bc6398a94071d20c08ba14d544d069924369b6992315dd9e0011cd2f1a12bf3ae75420c70048da3edd49b5350c785966ddbeceba410136f8c62410bfb317369414047631a5601ebbbe438b903e6ce8419b4d8395db8a9159384c480e63a9e11e397a741b5b2e972676d8664becce8e309d0d28116450b380099879137e166a9d17226419814aa238fb9ed752e1d17df8a39791cfdd7f6cf0ccc53e7dcaabe51e19b729d7cfb8841d637315f79ab84c89652b02c506830c52c3075d1f355a4971709a08e80d23fa3ec6217886135946cf5906e412ff87febdaaf769f73a583cedb19fce132240dd0d3be6eb76d209056e469be7f38539b584fb59dc5f70afbf1b05a457fa3cef64fc121c0ed0757fffb41619d5dc7abc21d149971d8d2d864d40c9afea98116c73521508565333b417fe27fd9e488df9c453fab2228c56f15287c85fe2e04e70cf986bd7c3d28e01a67cf2c1cb46b5bc98ff3b483bfc8e41eeda8767cef9970361bc18d32fa5247d3f587da5677f58edc5ea7f51b1840375f732c97c43f63824c365087a5916f73ddbb6bfec8f2a1f8dbcef34b0a3fa0c56994310227f95a4f9819155566eedc1d37864f84bfabf29d2748afdebbdc905b58ce0ff86aa135a7eb839ea14ef2bb345e6336326a14567dec0e1f845cdcb69e653ce1e228d4d32573f82374b21669f749b8f43e87c3f0864840404b509465d19945413179666ed4adacb95da43bd70a6acf9018dc4c24e08c07ae2ce72795349f0e55989fc1d9ab590532780caed3a4f94384429eb7f91a3491134ae1259bc786576f75753f937a1824014aba3b44d30913cd6f17fb4f9469cbcf3a3d1495d2f0864478b750dd2d6648ed9792e8e4f5a109827bf3a68c33e3dfcf87fcccb92e9397df74bd708845b22df6c5373aa8c133213ae253d530b5de893b3df58264b814a0bf96f7237abe3f567265000868d709e888646e764b3d35ce1d13df63c1fbe7c4ebf809648e07862b22de094d9c91cbcb440fe91aa15d06f1fd9a3d23ad0685c61e5f8fd81dba11d0f3e0a95d0b25e3ffa15649c22079da4164607f55c3705bb4a23fd18a9df272985bc75af902bada3486d4aa4bb9a3ef2b1034cd35314cc129930c7b0cd2993c09e1f2a3520b51c18ae542af0f62c53ecb91c34b5ecb466d6e7151394a85ea809dad27586156bcc1834c2e906ad557a8a6e0c2dd5a4dad7dc01cca83749b224be1e02944c7f1f07f66c2039c020fd9a71346bf333c4c03a918994565324918b2b2898c539852f3895c6b6421dad265331cbc263676dd9d8af98c46eac346bb5b1d661026b7efef69362e7d2605b03df4d48d907183a5ce2a478332173a31e7ef72c7b3a96940da0436717adb0f049f2b3c2c99a85c6d5687c25c7fe3b5916eed48a12f565a3778b15c88feb31fa6cef5dc4661478fed77f68326abf1740c7763268cb6f6131dc378ebe8279f45cffb1b71880199e2802b743f3919564790b3261bf8429d4df0773db0c15f033efe3d8b03ca8e1d196d5e82b0daa5c0410259b8804ad730f5da04cbc003c1e4ac403ad8d498fd01284e7ed1f3dff318b35724311948297fc905c97804be0abf142b2d597c2cc1960cfe2f26226a5d8c4edfaa97c59ee169c4ee4e9a39248cbed804e7ddcd16deb1a8a9f2874f3f69c6b8581839440fb722ec16a167750650d067edee624a26ec8fa3f092ced39ad081f69fd453a592c72fdc72790994a2573c76a298347070a97de253711db295c2de8b3e59c1f9674eac47f299a76433aca8ca38e15f48451ece03f608c594076d5f0d9568ea34d1dae4974ed00b32dfbd0f4b4a49f4c007f0d670ed6872ba8157bf46608691f5450b7ed6f3a4d4e7b25746ad9ce65884a41e93093f2cb93782583ff306136b7e940920165f08ed756cba78b3164899746e9c4eccdd5030876c1c630a5da9f964d41325110bb695a145cfe6342416d1014a86f03963da532f1ab10bb0960cd9e76347d5e39e9e7c581f588062bbe6e92007abe9917cdc606b1906fb44d313eb3397fa10e07193ede283c393d6e16a5e7342d454e1fe1ad0027390ca70b5524662581cdffc4a0b3672ebddd975907fbf75b1e3784f7e74bb626d91610884405205d4cce063358fdc5d6f08ab2026db4a6a313d5f823bf36817fca40fc408be42711996855ef48070833963f904f4e77a3f94047ac7237420f2ad35979aa246e30d2472bfff954cb32e86bfea525a98b80f72490002e1e66785f97521c43f169f5bc14cea644c6457d577b66a4f721c4a03a19643d5d2b03290ac48694119fa64058645dfaa4c0771ad84b1d79bc8c134051972c87caa06bd169094511013e01c7fdb981ac7f5e509032b0a392da99f1e6ae24b586b7b0669ce190c202397ac9063576b36fc006c7b054a23c3b4b586d0f41345dbf663ff5bcc0d9f4019d7b232e29981eebbe0bd59466f5476ab855792efcea47a7da0e0fc8198b3e70cc89f819362cc4e83831b9206f01694ac20bd2fc7b49cd8f15437c3b082d07d9f8202fd78df855e786a3db07f27c8ad45794f3f7b30214cd26ff3c142f614638ce91991576d4054b887ee1e600ec076587fe099e1282a25c2b0f03a99e22c245acce930dc7b5108b0a3f1e406de6aafa51ad9b8880e894e330f35ad15445185ab00b277f65fe8fe8763540b4724cb545d8f329eaa3b2ce76b32f391f29d51317522f0e314797ed7f00c1c710776c0e99b551b2ebd202a73df89190b279642d4008c8beacea81bbf3ef358ecc1303808940b967ce8199ae6635ded7ad94d7712740d57412bcdd94545deeab5462ceb4a2aa3615eb224c68255d68df540df6292b2282ba2a27de924bb323d56598c39a44ff1fdb09065dbe3094275d53e33e225538262f3d4614fcd53367e7a2fed348712757c3074a90079cbd29afbc0b9934fcd78dce137edb542124f0088b79bfa7e245e3a5b1dfe3471459270f57ac26d70a643ed7fb848bfc691fafa880bd8be1049e4f653434fea428a1bddfe59e3ca6f0fd814f551062c91ede61983a6e092f646238c8a6209889ad90a5c5888434c55b095955d9281935cbeca7adab8d56f40d01f429faecc6eff0bac2cc264868c0c177a3faaffb85dd318e996bac609c8185c20cf79e9b7da494359ff1794ffbaf018fa40f40e36e70b161c5626152bff0436240dc4ef7c4f4a49e170ae0a6f8abf687da8f620e77e02ea757073b7dec2365d58d25c75afc7373406677bbfd9e01100e63f604b2049918f8293500a401ea68d1680da88b8c49b9de9554860aaf508f16a27d99d27e6db1d3f0588e66b5a9a2260934f087edac4b8321d77bde15b20da9568617c42ebb118c8304db0e0fee0ab7ae902a7d5e49ca98ff31d1d51f28631397748973d5c9b49c399f2dc58f5b9fe31f11a70eaa17353332294660475b25d44f30c2199cce786755b77cc60d8f2bd7875799143fefd769786c50f7284700f174e8573b2678c8e9caec72c5836e2b183739cf9ec21090a60a43cfa1be4a76bf471f0780ff0777765857063ba4a05e91b1dcad20f6e661c4e4e819834d1e6fb5e580741e31b22cf42493b2ba71a628be19a215cdc3b337df529434679490676d88c784d565c4cdae4899a84fb785393cdd1d05b70376b3042d2f509930b3670023fd01157f59c40bbc63a285b29f1c22de755046eb0f463c964a60c50a4f2b204f63c5d45a6bbcba65775bb91701ea90469cd1c9fb1d41c615909fd36a2988bdd574380e5ea0549e520373879a61e4cbdbed042390edd9a23793f4aa0d2c126c40233d8aba0c8abc3d51d6d4b52fbdc53c5cbd7e3cde80ca725081f621855bc7cde50161c34bdb31f0548448091ff7b48b21f97ff825b92301a2482527a94785a4de140e25b81ea25e023dac486c0e72ee725fa293e9df900c4ed9eae3aa469024fe5d2597c186c724d599976787b2e4bfd9be3338aa30ef710e6c6b811de1f2f53e364f673bec54e4a8fe2290e61e640495f8a984175f0e8e5be3721a1663554bca27c940ca4a1b87e9e7f49426fdbad75585b956cb942ab93df3bee489b29a24aa38699df76ebd553e0228d33833ce0f9330a4d344553da401b97037200a1cb3761b165d2a51ecc2e88c388c86e7cd64a5ed963f208718d0d52753a9acd08618519d739ce3e060ff2aa9d018e23041ef3277a60b4ceaf49ebd2e67128cfbf702cf869f63f9578d6b60de1ba16850851a781ff36801e1026fa154bbecd60853f5f11bef252717b8c4fba1a55311bcdd0f2128a3a0b0ab73154951a20808cbebb65b443f07dbfccd6ce1998d20f2a59d0605a63efb5b8d0e1960a7642597a6a11205ec5f07344c35e7ee138a37b2e8795fd7c19374cdb19d294c564f0151512dfdef23ac62ddd3b436570e4ad614ebb59a2b266fc01a813f9a11ffb859514315e10a54d54c667bf89973c09e4529ff32809de61e8a7484b7eb8b8b0c8676be0c2ebfb8fe27236ccda39a215c5e1aab02dc5920f81e5e32c60cb792e70a030452489f5e5c4a82492380980dd3bdfc79817f30e5de41c42cf55cfc451c4198e39ee8fce66b43d8f2af564c8b6a1977121994231203031ca342578d74eb2a0647f32a8e547e06fbf7accc399bbd2e334c48076efb02bb52c85e207da77494e2d4938d0108cbf15bef898984996957954e1ad6bec745fc741453810f601e404a46e9c8453287863951eec893416be9b07564a45a0cfb5ac3fbdb5c185424e0973fa53bdb092f8509d92e00d8bc85a994b9c06b192b7caee8a25c38b8af947427662fea773c678efad037c82bea91f078ba209944d456d3d2ddd925d7d47ea19b10bc7ac17d99e8f3fe58f96d6421d5f1d942130115859b8401a61eb4c350af70ece773cb86e164ce0c0bfe1882baff45747eb9f842e9b14099c02077cdfc15a104de58927a603e5d37d9d57999c0a09131e15c7ee189094bfe029d45448c2f5dca31d060ac8063b4421a32df1a0f329128bd97981f3ec730e33da757c04b0338ae91c848d1ccf40d515b0b91d3c1bc430236438106716047d5cb5a2e07fd7fde56478a1ea16161c0c752ea09cd264800e9af5eb9a8ff988922971aa363b33ac9153fee65a7d04255d79f4b9b163bc4de1b2772f4f208a4b1aa198907bc7f320653fbe4bc6f154dc0847b7d74abd2a3c873c558d63a27c2336d957094ea97c9ea07b891b5c21b08b4d4ccf4094333c4b6e25e7dea814c26d31c0d7cb4bb11dd4736cc027bc47132e69b53884e1c7622b7d1101bb2471d70592949043820b2a8f26909648b8aaa77bc77cf2d6e7406d817a75d3e9fd7d8df74bb4d7efbc664deffd47c6effad1483259631ea863619fe288228687e4c60495c5292d483234a289e2e29ef5e9914a20c72f5c58bf90560b82c91fc957a22ba622d0101ffa062b114baad808537e842bb88150dc568d6d14b0a6f9a85516f24142c1a137eaffce59e2d3d5f112a578b0ee0c9bcfe7edd804b2ad0350132081b6fe18eeb891158ec913a9805fc9ee82454da8040f24fa3a0e63fa718288b3acb0c88c6f0dc2c634b7da6a27c60384d2aeb9cf904e07f41cc1a1867a3c09e3720dda6d4a33a238e089823420e8a9058e0a3098058898dbe2377129cd01441a95d00833b02e02db959ed533e38b5f7656cb9cb0c884da1e8251e4d549edaa35908dad41467d207f0adce666b22754d5a34507346c9a75f11d0948fd4cae5409fede8692e5f44c0adc03ca940abf1e6068cc47f4eae9c2dc804189bf9932d6002bab17b0e719e72af712d2f227180ce941c795e6b60aee3e8dc79920c16f9fe9c94900ed2ce276b0c93f664fe7fbe47962134ddd01282020b24ab74b173d976e785d5b2a095b74a335f8d24bc86af4283c1ac8f85fa77520ae787769e3263f5dc8175f15d3b56496f06a0a87b93cfe9b0af055ffecf7dd57100dde04cb5c00cfcef86e220de238a37978843698e71cfd0bd9fa5d0489af248caab8b95d6eed111e0e62a5e125842b8d8c34426dcbf68dd0b64afa196279a452695bddbba58edcc42348156a563f139a0cf3b3ec81cf88904752fb2dcc5edf50c65c7a2af75d2af88896116032281a626c599ba8e99849e9a3b8cf5ccf3bd9a1580929fc65e47fefc02bae8cce301ae40ab3b8615502be62e976c8a2eb7cedb8c802bd62eac13d25c4aea4cc7b510564c94e110130603d40595aeac5c730c55bffd11197cd7956a5967b2674e5bff6d5d1f339ef0e1cd6e46249f8d6fad11445b0f134443f14d12947ef4df954185f393046682afc7baab27bf0f4cfe4c5ad9b5e48a300597a45e52e91ce63f17d33c53005afe7a7fc74315b9dee28e4ae6ae73b3197b18a17406195d3b1c330b4c4977ca9c6453b63fe94c6d0ad43a2b627e2b784950d1d34d11db1435d8a2609ebff8c0b6513ba7ca9a86883f32edc88a5da0f549dc9bf648a65e41519152e2298d25cce820a4fc5fbc9c79762519992db72d52270737f02f8af6ddbec572d73702707dca4f52e9736077fe4ea2c0204e4ee041e04b86922c9ee3880dc4e52e9fd0f1c5d22825c77a114f37b645e57fab84da09c29324cff09a37550cd8eb1c7b8248773dd841a383d0decbdba24326baf77bf4d1a657fe334f29af8430bcf787541ba26af1846821e10fd0e785a313e919b5657bfd6a72c9f84b9edb7bb4b1c6faa5d23c2fd1f326e241b5d34237a6b1b51fbd4535f18649dd30d72e06dc87e9f79313178326f347f441796197a2d2360f6eaaf6a7a2611b4f834bab17f5a92666cca566fd40436eee6160efaf50a09dd84a38daad989da0e07fbdbd40ef027235bb4132cc0b21e1fae87e4795bd7d055d6d5f8561afb5a3926cffe17d575184323f6e9bd9f431c99df1cfe3db9f6992c18d4c13fec561913fe2ffa57fe637272a105ef26218d50649cee8750f233b238ba4e8206cc18f8092b0654c3e284cc101b1616cbaeeea519869b44d0dabdb5c15742a31ba72e9eaf1c582825c360b8fa6c5cf0db53051db6269a5636f56e2343b0ae6434e3015428f7d29d6ecdb122e83e81c1f38da095f9fe1734928ddafcbb4b275c78195adb63af113950fa5599f0d7e016b6ac7ecbe15da147e83cd8a77608a3f3c4ac0672d9085778dd336205a5bdddc03a6692a58474f7cc17a771c62f74eee76f9507a7047add13752f1b448e03585592ba6c28637f5199f065d35258deefd92d71e8d00e97bd52c231babca0c296d8a030e0be9ee43ce4ccec5f52e234c161eab06da7fbba76964db2bc97640c357d4b18987e25794b945326105bcb93565b2e3014c810665d49dd5ac65fd92a07009b285577c4d259bb77302cf3584c3b6843b5e69c7ea8195f01436204775544eaaca997ad312e429c35c3870238357c8dbfef0e47d80197c95429188a0f44933cadd68538dc1309e855a4dbd9a6c137a2b4b5dd412a4fd02cb3fbc57f2e689e043e20881152ba9aa575ebaf2c2372542c5fa8aae218c1ff491fd3d9996b7e68c46e6e54ac3c2a66efad58de987fb6f6ba9f0161eeb510d56f29e10d1ea84af07eff47656a80dfee0aacb322d012c1d7f8391283837a08db607e9ee3a2aa2be3f7d0e141ab3ad8b7dccb33b253b702d4bf93d3cb6d721caebba238d7557e646c15102308b49bc2cec8d276c2a3c59727851b08e0fa20c9cbc9599f507378483c24216b5f5437856876e1506aa193eecf4c8660716b26b21010be8ef62d859ecd3c8bc4dc9aa174300303711fcc7f8372a5f2c82af74118508729f600978659caf67b4ce74a6c5fdac1576c008d274efd37d4b6d7d27075430c6d9afd158cd5a6e6d006755367072ccfdcc4cc9ab1a1c9ec566042e85ea72f57ee96ff4579f8ab8d96532de50fad5eebfe9f2bb7ae3564b27b040c209356837d9f75b2815365a081bd807592b89b273ec4332a3e38223f054e24f7aa2274873ef9c4528d2c1d2ac2a332efda38a98fde70309cab099f065015beb400a7bb2138c9e2ee96871fa5b1be2911217bbc645202ad0d3c020bac2b40067129fe15379eaf365a377f05d170f9a439e50091d35cf319ef7c913f76c665e0338c1fe4745721b6b1d17bb557bbb143a36ca010de13e7c77f3efa9b05ff3690b2f56944e26667bdcc12da45256a27a9e615746125e114bd274b4a837ed30eb0dc20c845b70777946753e59ec27db0422562706a71fa88f38868904420383046922eba8b13b72573eb7fd46d15820d011af8169c750ee01af7d1139676be981ec1db42f67072f6ce475d76eabdb79e260306a91ce2b44d98944d5849b7b71c13272a8fe37fc2164e30df6fefb8005f060afc3d2ae665e4379b21bbac196ab54852c569b860e372f9d6f0b428877f9b179a2f4afe2fc31b8a16927bc7b6b7f4fe974b564c33426c0a2aac15279238bd115d6a1d9f38989d1ee3b693dd338be494cc79ce73ac354d5ad4015288cdc78836f747109dd5b9774180cbdbe8395fc7f7afe224d609b8b72caa234ace8be732eb71dff96e7f6991dfd6195c3932f74c570c534ae0a2eef934dfff3db9d91ce0f4d449f759a611eb53444aa3888a0b190fb030fb3b1b955ced086af2e9af3a844bcf228242e5cdd8d4a09ad3bbb93a8ed7e65e33730c1275cd4445926d8172a97537e90fba2e3e3ce99c17111f4ac0ed5608ba4749827c7637576c097b79745afa3289f84ddf5e744bff7d4f2c00cb90d572a2cc25e875ee0b7e22a32dd37edf861dc273abe881ff987330bbdb88d914d3d7ff56be57e21b43d8ebe5a3687001ec7a520a14d020093ced301fb1bc2c816580fd1e969c530cc9fd77942cd3805396272cb8d1f3146b8604ac244172da5f7cd41983346702d52b49346fa69a2d1c6611e54ad2af68e0e8f4c8f42f49eea11019fa63534c7e709c13f2d16255a324e3783f45fc6723e4081b0d63d78e8591d49d33c26c6dab1fa544c677b974567a3a723e11bd6aa89f88aedc1d58459d983d1af9eb0747044f226dbec60e2eeaf72e48baafd328fdf2171d90f25d3339f245f44d16a5a1f67852f974d85da5b74df1c96c8b7558545a8de084a2fcf021174f63a4c4d5a54a48f7ca67ec4d8f88c06c3973d846c1093b2d23b6a159fef8ffb399ee29c212bceaf2c23378421b54aaad06229b278dc9ec011fb56a88c8ae959c1d65e820a1881f9d21253649b7b454fa4f24bccd73238475453d843900403d7877b3d489ee543e52f27b66a96f41c2e0a04b66bc979efa7bbe731316e4da34f26f6c1dc990f7191c809348be3690e0f1eb14cefa3a98df3da2e863ebbaa36d3898c65095c93cb3415e0eec865b9ad5339adf87b152c1669dc90fbaa72aa0ad9eb620eed51b57b19db9015d7d55896b516957e3a61fa3a36280502ddffd79be823c088f5c579de2ce4e76ba5c93d846d92874c0c6ad81e14442665b35327d2792f3d70712633cbbfec9006a5514830229410c4bdc883bf1aab3aa31bdf7bc1036c46007de0454873f64f477484e833ff6d068926db8dfa8ee630be65777a26f9ce4efcba917069163cf53c55d6a8fb05f916209d2544d2cbe590e77e7a932c8b20661ca1ae211b573d4d35e02c3772b72ee4512ab91f72d9932a52eec92d3f15459b439d004922585fbd573acc133721831d7b9320d8411865ac010ac0fb3aef6a3d39c3c7606d663b26ba23c0f32455c39b504d94e8a6036669d807cb67933d637cbc6d157f0e29884201189de521a03ac948ffb14bf0377ace4c1c4f3e085b11a49150587fedb7f76fc454c7ad9b783fdf7212414019d7fa2e5927a6677fcb0e857df2014b84d21d3ff18705b5b4e55ff5df5652ac4fcc06de03eb5960eba688ba36eb01a9daf895ad6746191b8660cf8f20b6b23b93199a22d358c2f2508450d2c304c49c6827398d8a9d0b24a32f0763e4b25ea10241dbbc9e0989eb68fe71dfd1df81322e3c32905cd2638aacc8655e6c571665932295aac61eb2b222e96322b8b142b8bdaf0038b0dcf4374712db8730e12db89b93d29d49e1b8d7f28f7fa41827ea7efbfb44ac8d719f38e5bdc3959491c3ae6fb6ea91b456dd7f859c506784ab0a644778966de81c0f4be7224eb1de63ace376a7a3e3c9d60edb93c2d3f9dab968706f06fa2b9e065ee3295d8d3dc242037973233ec5658a80ce4c023abb6f31df6bda79dad7a7c09e56f563be2a85b21067a0112fd39924149a7fb6fa28a70607dea60f76efe615362309c77c9913baef2f80db7b37146975192eeede2b0ac0eaff346a9d53df0df6c17f24d276b3994c2037896be99a1c4f8e860657d4c07c80c5d926b3ad0dd5ea424874a237c52b51ef2ecb769f4d18dbf4f4ca96e2e062d86ca6da520105aea6df2718817cc159cc7999bab15bb45228d2404f14e5406f91b90d5b13f65ae59e081c0014cdaa61ccd5c53dc73f54384f8747a30ec1c387b980b7558c97560a65ee2f7e720a48d0f875cf5ce067d2cb3675a2c0d6acbc52e0336beaf90e33174605ba59e1a50371b4780bb51ad2f34b146602b87d9fe23ff003507d74fdb35dd5011870265346fc3a0aa83c82c0db3c6e13222cf5985b0a6a8ce80c4f1b4f615a1b2ab262b730d923990848160f29fb2d874ea9c22ec56182c8ea6e9d65f85753497f8a06b367e88d9bb92a064c5679687a35fa1298713b7fd0d273abc29e9f43db765d50c4a8b3056a3d7b22dafd2a4f8f61e3300970215c48a8da0aa5d955cb302d37ec288896ecc17a713e5a4ff0418a57a98528b0af6b32509f7cf63c1c5bcc6ae4f92e417b03d0bf949c05f3fc94a0cfa8eb466774824ae0a31e0ab0650a3a11b33323ca67051ce16ea6093f09dbc301b38002393bcd4b5fb2800ed1598194e6c094cb59ef54869150608fc08f1197099b67cfde4b450e49462c9aa9e2c41cf357acc7d9e444e23f3419af261fd6b3565fa9ae08e16d70d54f98500750a0d7bdff2d997f1c3ab42553ba37cb93eea2fcef6e0935b0dcbc8d1ff4d112020a5fcae69734963006ba9f1d4d3ad2d5aba268d551c760b1d87e2f3c57b582c552fc8db93922f46ecee20883fe1a5b5be3bbc9983bd0eb0037ed77660a85ffb1dcf1f8dfeeb2690490dcb9a7be272e5dc19240b25dad4046ac9f45f53961abb663beb67a2c58fba2fdf60a56b7b810cdbcb1dbcedf72107cdd5305b1bf8b0db4118367175d270a15971b2a973b9db0ed7ab18ffe0625ffe1c8ab84540f6b921fc11c4b32eabad89a096f7faf1e347cbbb8f5026b2c021d6b62343c1c9859ae7fee1bcb6c870bfb4fd98cf0adb5aac579f7a3325f344a0db597a3c5c7f2eeeb99d86081f61c28c7370e7c0a8f1f350ee9d6cc3a8dc764dc0d92e0bd65bd43c78c6a148bef2bb90da966d9f78d5136311912c3d541bba25fd66c5fd8f804ce728fc900024986d869d514e3aeaeb6e017c8fbd47d1d7fb1c144fef007a25fccc1f3fd4278400142580751cab9ab66bf38db87d4894e97d45bd75e8f4a01af4222e03369a921b8d9c606cb8ffab4ea387ba82f5f3f6ccd6652a5f928a8167944620615f41e92f3a9fa20fa8344e362d8a04d041a7fa1333b4c54ae213ef5dd224075ee0da8d95a56d148df872967493964e7d0e37cbb8d79721d8e252f389c6c90ac972c30b15c657c4ac8e769c7a5d18963130d6d75584ab9c9153bb3fee1eec925a1e3cf5ac7114c6a347db77baffe1f220f8ba53472c34861caee14e9c811908772c0f30e266396ac51b5dc8511acc872ac3e1d314ed933d724c8ab5ad274ac3f4b173b5f2d78316c32113b72c164eb46bbad85730d9e2efcabf63572b7193c024ef7f00879cee57b9e90782e349e720df916f691e0f9fd41d74e3175b8c4d7e0d863805b7e648e911277ced809c0321f16e9953486862049214ec37c0c756487e9498b42544cb1cce893b3485a3d02ae6172589efb94d26739dbf2a30d0ba9110070c7dc19ef2318bfaa64d151aa2481febea424f65f070deb9161d8af6a9616a367dde57dfe4d167eee3d133751d8895d71f09273776ef5f759191bd695666761e919f7e15dacbb75729cc83e380b5c2e98b222536072f942be3aea1550cbfb6601db1ce6fbab40919884f982a8a08020d411ba0cd06bb21f4c1ea7a4b279399b13ed4498cd2b69dea9136ab2c240a2ca8555c12b1ba6b97c29181b178850af1c7d6c2f2a92ae92ddda6d64b2e9b9481e1803de6bee30ecf265036ced7aeb839ab9ae56018459316644f752920ffec76867a2de13b9fe4f0fb07002c136d1f401793d20645b62202e1f323148b5b308db808dae7dd3877d3fc534aab885cd7a7473d027db08337078bd0cb208c6548eb3b365a8dedd84239a74796a4f5b96db1cc3018babe8ed6bc4fcb7830c785d4bc2a623633fab94c34d3cfd4a7f2255171ec87511169b7d15d1b6beb98856029fcf6de9a4de02da5e859644018097ac219c124eeb7fc31b9a97d35b962292679ee12a31cccb790a3c00bf44a2fb187d76847fbe714053e0298d3d4042faf2964ae93b75284b6f460260bf6cab788cf7c19f2becf723a37e0d407f01264226dc0c760998ff868ddfda1d2507aaf1baac6e36355b0fffa1e02dd7b11173b4d872ab5bd79012ea515ca8180150da510c102c3bb06b0ba1e44ef15ebacf6c0e457a3ff21f111f2ffc4da5e23703a3ee8dff2063073fe0d370d48b453b364c698c594475e0756ee90955120d5a57a609b9f291f2f4a0ee5a3b1909278d30555de621ce5a37e2fba8a1d39e4c6ad6d7186ee2eb767f2d24b396cbb6a302c991ca81f9b8dcdf87d9ce2771b9ad641d765c1f0f59d6840d24e8b8fc977c7f047ae7ee0030926e9a549e4841ff7cc7f24bca025738a200e2d03207fe3129e78829fbe51d4f2dc5f340cc9d47cc23ccfe42267ebfe4b2291e7defe7a200f30f318cec9c46fea748036b859d215d78aa76332cfeefb39bb3e1dfb71f0918a0e97faacac015e4e6b8da27037a5759ab6cbb2df4a1076d2b5e157511db195341ab3d48b5d62654f415c1d5621c474bc5a14bd9c92f634674f6b420ab14b775e284589b6fd54b64d7fa4d8d3006460496367de5a276abce4ffce22ab58cbb0d5e6d9bb26786ec6131c6a2edee447d1fe7a97f161e05156b5f4e81153a13e9a790e68cba766b01e326a4f4f6afc5d608ade645f12774bb1e0fa7fec20e1e56853ba3613cd550ff5b61174e06a3cb539dbdb06a329ee6649fca990a67189c7215d83f2a790df9b4e4e30262c52ba65d7d64fbce6596cb5a563bc45cf5aa7550a9e6d09738827a2a65173d30abcba79dcfee322a02722781ae1518f215fb10d0dbc9c3e7aa7c022da1495f24ec56c50adb2d16acaf45fe2948289fafaa4a20c380f07eb92da477e3ef7d0a0b7eef90fdcf7c721a4afe11d16642d16315ae94646675946767dcf7ebca2031bb8bfd0dfc3b884f9ab8e497b5682dbeaa75a4a61bfa93353c0b9e1ce16c33614625b29d3f60be53654d00400f036e085f45275964d120cfa69ff167a6b7000100c86d795822fb0272081f90afe0af4bbad756f9b91ddb2af66076902bca9ffb5cf05b394a52a93335935192721a81baa9bc53aa6eb5e2e44140c495ec6b620a28a2cb437c4c5a4a7393ea82f5c72245d08e7e20963bcd6fcc655324e65820781d4725efae89c0326487079dc47fd3eaa5db1f9aae88cd267a2c74438ea9df518428d0c0135d95c20f134c445a46eeeabfe71e5545dc8b5a132de94c55d9473dde2f33cb682a4837cbce3ba8d1a6d4ab3b9183dd92ed6451dd015408fc80fcdd93c2e10703583fe424cf3c3f7123c463b25abbf891d91d1066058e538fe1d30a62e431263960c071963e1aca694dedf4d337798855479b38568f0e6b37fdbbc88ed9d67af61471d01ebd06074e4ca0560aa48de4757e232039e270ad46e6d8b81a9180453a2af592064a59c10d4340e42dfd87ca0523c4bf1e074438c372ddb7c510d7f72fd6d184975d8f70878fc4710ce802e3ccbfdabec2071627cf1d3cbb589417cc89b06b5a9e8cc86989409780714b08a07a54d46b5d652bfa853f6fc47f1054c9f2aa5df1997cb5d71aad7268e7331c0ccf4daff06c232cd95b79ab2e02893ffc14910af7c00c479438ec335858c8a113079cf61164ec8c9d8456e84e155f903421f1a201cb48cf8365a945c531e3d09d26c55875ffe00fddcd8c60e69848d9abfca8041a585a6c3441d7c3f61a8f74f139a2d01744a9bc46a6484784d5d5454acfd55eae086c332daec2c29b740f7c57a7ab54f70450dd57a38b441aed5e07bc29fda4e900e0089057ed3b958aff47f10871d50d2f29b8681055b02c3f4f171493345528089a3b79cbe20605ec6b2d0e358a9e301573d7196b148e43ccceeb7138a46897179ab979b6f00e57b69680836262ddc0d293741b6a088c43adc8f111992c1322082f56fda144038851665c4710342e8ee8c2caccb09d72542ba3f983c5aa9a4fc25288a4139573fcff7590d54b66b8205662520e9a9098b6ed34b324193098d23679339053755fc5d16fb04e42834adee2de84c927c21272f72961b7cca4e9e27a794a609fa45ee789c397bfba5ce0f5817dfad7e91fd02089b4f30a9d5a90138d393518be943623fc26cb9e98a515a301079a0aa3c3247743072d3b6e451cad5f45e576002b11196654a13f33e0c81fbdf6b9de6d18710fbddb129e4df6926551b2d2cc28865ba31c6ca2eba3ccb00231f307fefbdb356f426a5b9812d4d70285cdfd0cc614b2b321dab10573bc0c7d167fb83e0a636e7e19284430d14bab83ace4b88e6ebee9193248e25f417f67d0823a73182b569a1006167d369767ca7edb1cc6e7db069c2486891472216bbc3dd0f84e48f88bc5dbd850912a2ecb1a14f6682b69ac1e3583f78a843f97d9f14845ceeac293aa50ff947d657d6d332451e4bc48a42cbf143e8d15dd12d122e0d9f2ae7f160e84b25b4e3d5675f46623c142d3894dabc4272ed1222b704e1d41d3a49be3bbaeb6c6440fc39d287d95cfe4dea5a9ed7b93e86a7e710b7fc2e885099216aa72a851a305b8b18260497e57415340335771d7905f82ee5ee780b41d183adae00db087e85889df39e88a4c5d97cb5bf72cfa349768d94a4c9d179b8cbf43d5ecff66f97e7604a127467e0afa3008a83afc689dd3f035f0010c8ca08fc4d089016dc8ee1042e73022842e470973623789b009690ed5da2526d3316428fa620634ade52927c3a902565dbee7a1b987b02938e6904b44fdd65dde331a6a6c4b251c7887c5eb7a709a4376477f23dfbf42a127e357506f8eac25df2845d060db518cf369d38c2523f63a301a628781b408382f6cabd06384af32fd471db7e7d40da5e3bd46be29c118df780e5744d923fc7e1c3977c866536f593954f5b163d29a82fd1372c02fe09c8ecd758343b586a367f56b5dd818610f7add480e3e438db12084baa32b4db725616b00a01038eee3b717270da27cfd3ed01961374d82e0e71ecd589f36117fb8fa5625c247de9bf55ec3708e0ca3670e6983afb219ebcdc4ffec7e4beef0325f499ee79f18d991d41aa8cca35110829da141dbdc26901a1fe24c8f10da78b682683e17ee7fdd774bd5d878b444aebd4a569aa5e53a8b395855969a2945ec53080fa7e77ecb15f851b97c2fc61d8ae17eba1cc0e3d4408dbb40160068cd4d05fcda94a653a9bbc070c1860c548ff022c896a9d6b0455138448a03825e4ca23d429befc491a1eaff85ed88ea566cceb6405bf6dc4b4353f46e72c4d51e656fd48c1536c0c323293113a9aec1b73d6afe9498fd05105db88f0dd93fb73a86b58d3410f871a8edb0eb24d2c4cad26aac6864761193463d373da930598cbd64d32b308cebcec23f765eae6bb04fa11858919d92ffad76dd0f1af670f0e1d234a2032df919b252735c2b3dfc7acbb01bd748a31adfa535009ceeff725f95bd30e1b7d86cf67e871c970dd94b913de1b3f2b9eef6a7ba7ebc3dff9db5bd9cf8f27d8720bcf460528eb75efbcea50cb2907928af11fa5d222f041af974ffe70833060e3e4c52ad86387c0112015d27bbe8859c2e73d863cd201a882833bac4d838ba6ee10d36d206d353fb2d68193c16766a95a1d11b28db0ac29c13ba365410b6c22139513b5ce544619c3e2d8846faaf6633322b0b4a856854496b1e98d60c772a2064898b39cc49e4979fb29cc1011df54e6fdd6bae421c87510412db344459017d6cc05779242e0112fd56339f2404e445965a570eec66ca3efe9aa4a604cb2bb9ba3250416081d5b3b9780e5e02403c4fd1dcaa78fbec917ca96d7a5609f9198bf3b7947200bdf17d6d52d0d3080bef175c2a8ba98d1a48079f276c472b91631e9590de84afb5ed16d094d290b17cc9034a8aa9f251f75c09c0f9a5ccc198981e0f0803b892f2e2951139788177044be8cfc8b41f8a7d787cd5a6ab2270f810aaa566d25414c1117c2642d3e28b0b0dbfe3a0d77602a67810759823db93dd371bb838be3dcb11ca7cf99381be8b643c5a01f7413b03ffcd528a84b5d823343d5cdf257fa47ff0359e18220c7f201250e354d31b2a27a098be2ac590fea7b9ca5888e9f7f3ad6f888d2709490840006b8ea340ab6178c0491d4f5e4e7191e587b4c82e35e3afde42829a80f73e8e205c55f3d17720977228908f3c057e457ad182ea7dd3fa0fac81e8f19c2cc695a8381e6eb436b96e29aa0cd62663530cf137e480da5b557b0a1c2385f134bf1ff21a32f3c86605421dd6c92d652f80a4c20c1e1c828e179b3a15c94ae428ddf2620b6f998e653f76135b06c5493802b9bd87b9265dd2982283c2dbbc81cbb983c81fbbfb632ccdf3cfe275e1f505e83de3e653bc6bb46bc51b7068154f299ecf45f7297080eec367b98dfcccee76e3eeaa90e946b291b7f923ac04d36da44a7312ea02354e59ac9d3cfe99fefa17b4044388a250a74ce857638002d923f83623761acab3ed3cf0b90925303531fb5273e5251c046c5af7086b8b9edb473369d4b8dd5f2d0736cff2abeeb2e09291f44ac4db357e30985239ac4f538bb1e8650d4b4906a0534985433710e7bc2828b8331a3fd9f88e98f8e13c768cd82fe7fe39e60540f001951b37c402b4503ea8f6670c4aa112859ff13d3ef5f3c948553b14daf4842a7b7ea35540ba51c8a47b266e4f603ba2128929dc20d32aa7f9d45d476ca0657703e08ae0f963e7df497f524964b97d1c567b65487e2e73f1092315875148184493ea91955971a99bf3970632650a14f9b6237972157306bd7a76fb4e94e3d4e3a969a0a8b39c67de68bb0909b08899e4b04a98d178e70f4060d2c65004f599a93571d20d0552fa163c326619cddd7dd7bbfa87e7230d67885b3bec1d652b49155962eff061b9e9964f61185ef2c5ca6245f38a59fa370304b2859f7c91d46bdc3b95bf76520e78200cb23187fa1223c9b076957bc67d2c988bf4b6f3eaf204aafc7cc8ae8977759f1d6a24cb659eb6823c816b60eea279f354d4d5043c7226b4c05a99da831c764e65d518dd003df5429f48f02cf652ce3c962b082175d85c61ca8c29a53ae524c4b2efc4bb99d9458ebba5b1c8b5c9b3a4de075a8c6cf72cf53eaddeeb61c35d97c103dbfe6b58def477c56444628678101cfbcdf61385dab4b75cc59fb554e888d28d025edcde0258753bc185021a99e44c61deb7524975496573819784a7488296abe20b70d3c65dd336a59fea5d990987e7c2ceead782a3a2812393fae2ec0f4bf1f74c12374d1cec5855dc3f649d42e0195558f544e1cdc43376bc414d8dea9004a587177d567d18b29a79c95751985b4c30d53f5147076cbac5659e35bbcf0998330739d4641b0763d4b7f03b371770fa147a54e8c5defb6cb409d5b9e9b41ba4fa593cf3f14527b3d53cbe7891cd775ab70e8d5d02de0719ca82bf7115d206b40ff86a55e8cb555b515dbf37c4c3c1afeda8c3b0bc1078a3f75ee856fe705e72166ec3688b618d0583c8b9d595882ded46b355ee540e85620cd959c04c6df7b2c166f00e9f9248a3ae65f2132db68b9f92762c47121dcb324576dc66dc1d9fd4946078fe071e6c21461fc4db958d4413c23c039ceb3d7d0969a65e09efc6822b63241e00135096470a68b02171652f58b3a6954bd26de689c03b21c800fe6749a67b4b93bf92d10a6285a28994573223422579d0a4dd38276c0ffe8facc287c26883709642c0db5abf56a52c28f351f033c495417a42376d8e9ac7c4fc34087d5760ac50ad9cfeff4df5fb403ec8398aeb830d45e7c4ed6e643212bae5a478c179fb516cce4d1b0c3cd1926ac130e55429b0fdafa9437187ce718e5d7b24740e64b772a997b4012edbcb8d9b3b45825d9df011ab8a451805f81fd28513d6510e1ea111c2f02353c110a23f887f990346cd03904468dfa0d3ecc0d4a05e6c09d3222db5070963ec97943de90fb66be8777fb82a337b77ecd14d4f0d66a43781174bc6fa489c3ba2e1169cafa0b77c2c1cbd1510d1d6e0204fb25de6a8d85ddd975417382860cb33d633be26057cf77617a7832da3b5f0b5961e8d21a739e8ad7a58c3286249cfa0132e552c17fddeba29177d068a6a4c465a06510e03b4e98b96fcf472401fe2677545dcb1c2df4fb79d6033fe632232b42f937c275a5abdb21dc9f7da0fcefd744d6f8c0d592b706869bcbf8962b2e436e805e60f8738ff680ad208ec8368340fd6d6df9e02e0b3e7de1acfe88a8129dbb120a19c7d6b3a77fbaaf98533937ce63e64e03ed022102d6f304966fce5607dcb9d92259d78ad8b8842a53f3a3871fae4fffa5b585f40c83f038084b0768d7da819708268d12101e0b5ce1538911d5cc49826c3d6031a9a17a1a60761d836756571f05cf32dee1f0cc5f799ac390fd65a70ae5e346508abd80a625fc7aad1d1bd6e21ff29890a287c51e2852b9dcee5ef6eea68cdb1d246e0a0b5486b9195bf7b205c0b15707bc613a86f6065d93eb73979d72525552b003d17fc5d24de5d4cb6df64f2066b9891bc79470dbfad6dc6e30be7499f4dbcaf3b9052b38c0f5eb85a384e1a03753d09f31a21179615de0cf5f5db1d304fdbcb44c8b35b76dcea64ae9180c13d0d6f516be14f3f6f99ed3ee05f4914367289505e7481c4989ba738f6f3d07ace11ea5f2fe209a83b8dcf23d9a0b909d73c8f8ad284c315f37c778cedc34f7161de35ac3e326c3b67ab2c205ca7aedce031c251cd8c51347f96438fd19956618ca1b08c597cacb98aef61d9837f9c9a94421bb603b60b5464df348d3d1cd846953906b2f5ea2248c1b873fbc60e5b50a92a486bf18deb35bde2283b23179165a058c871dc69427032c47eac6f29079939f8eb35150027134fbce3bf8098076fdb869829b614844f34ab8a2ec54a472fc348b4eb33271e8fe75a8b9b010339e9eb853a4cfa30952d17ad79b326029d38ba379d9745821b93200bc1004880157fdad08a46c2ac3366290d94754d4bb5c1894319789f1aab8169f3f301b3032c173803164e0154961cf9ab76f1273e6689d9166edf410381b9271638ad71baedad45ab0c524ce6dc8fdb7a7a9c9393c85a42cb6712ec9cb48577b720f86516e236d33661e6a6401d08a80100978e6d3e1e35eed3be199bde95d25e0c0bbf2ba874cef34a241ac41cb67904b77189b10e19db3936bec37ac8915ef5b178ba12eec5366d3687eed7052265ddf3286eb3693c23d7fdfd90b4ddf337b76ef746634877818a9139e4e5f7e157d837ac9dcbca70b3944474e9c07bd7678b411831a4398da9c985d3384177c8df565a2f3bad2573ba46185d9736cd6365a93cf8ab4927141415f4d95db79374ccd7cd0b583eaefe047ac7988c62003dcfd91f2530515a67def100b529ad4263daf73c1381af0ffae315dba7d6fcb6f949766d8150c3fb60caa769b308d31d987738011fb44b702869ed4b2e2d1190c9072194f03b621f8e3325768bef5fe5ed2cb6c6b16fd5ace313fd7f0df7d74e4c66c32650efc117274c0b48ab4c010c41c5daa56e50d9823ad261ca540fd083ba9439b14938b2c4ad9de776c74f2071fad7e8eafa8af5afde52f346b2e72c5bfac1f823fcc338eb077f41894883e3115ce34c8266b2c95c436094f17ba8f67588ff97c1810d01bc3f706016abf2170a065453103bbd2bf061eea058b1d212ed25404a47e74f2ed48ae1c1f822db700fa0b4bafcf46623f1dc0ffc81bac54b2f6684df0b4b40265683424801a23889c006edaccdbd5b8bf8cf969a9cb64b32e215bbd30b4dd132297b08e4c4b19fbc621c2519971d71738a903a89a94db3ab9db986f6d80d33ba1fa21556e006fad2c6399998b436b056f230893a52d9f0d538a1d5e5c2e71bb1b1188658ac173197c98ed84e8cc82643d28719de648399b4f38ed60c2e32d469f40d0cd72c446ad13ae22ea0464e630c87a2c240625307b0e6b5f99fcddfda5f5a9d2114604641bd17226070bd0ff2f54733c2dd3aadf85a377b08a7ea8f838c39415677a4c4ea8d9c4d85cdb2d5de09e6df93da9c812b0f03852dd229ebf5220551c94888a635b9c636f10c56370cebfbca42280792238ca009e06e4a3488f318e531fbaabc889c9507602c71fb0d3ab1043bad9f3f3fe010395ba912d6ef3188ee186f8cd1ecdd2bd66f9ddd8585bd3e0bc24b2ef30403cfdcb8ece12dd608c3274dc9bdced119959daac4260b0762d7fd1f9873317ecf1254fe639b68eacf14d778621aad19f60cf6de3af2ad0aa92de0509a00eb1f69beb00e98acd62c3010f2f21e08c542949ebac783d49ac90cc178a013575b722f326966ab48b16d66555e891de79d02d88bef4febb748056865c6f9155ed59c07b8fc2c733f5341c0a5148c06754ef7e34ae019d6449a554c74f36cb46502a9e51caa6b059ed36598e36fa661aacdee0c200435e19fe16b948afb397f31ebe1caeb53122a5ad8db55b1b36de7baba378e3f3b80de71d3abcc809051796612d9e0fc671c5500651aeb39aa031bdad5f570b566f070f38bb072d1ce4bcc08b061bc22c81b1c7f757a33c8119474c0db5d24f807ec41882f257192b6a68b43389e7e089a52ac4125c7150e1c71ae450badb90f837def0efa458fdcf6e1acb19709a469fa6de047c07e46b43069f50023c18c2d05d8f131699a7727176b0ed8adfbc3e46dd20b89c197efd27be068d96086950af627074a4eee0a847c4783d65d4ff3b87d8048f2074be2b1b315e3f813891ac131853151603837980b821f30929fad8be80fba3d7f5e0860bf530360a7d2e3f04c99c29f3335a11b23cdbccc477f242f6d317169729958d4d028c9bc998e48e40eb0a860fd93b8d6f5fa7972f08762669f2d1406177827f1d0cb232f489701fca9e52e465f0038effe73764f7714b2f0530edbd7dc9f65cf45bd43225aeec74654324ad2642d8fa1f56dd690fe0075450c9db7e740f6918e7df1bee6d66db103a6e888ba6f3643ecf58174fe47ee267eee9404778e1b6aa8af3553465f2f99915f35068c3f6e2b83864c7cbb3d2f398d510b5b0999374c944afcb27d209e6a13b2a0b48df38e2d4d6150216bcd9b1b2bbd85dc4124af0a858dd84819760285a094ed78c756794adf26d49903bfbff4e725ac3c3a4c7fc34fcf46b12dc161c34e1251465bfaa970d01d9c34c7da027b105e560000cfbc14710c70e56f1a10e183a0a4c12dfb6bd067f5c3ad33dcf136a8876ce21e942fefa2692be86eb754aa2d2d0291079aadb4aad61f0309ce3c71411f5f535b16909ba972a087a76552d118d91201086f99a71c8f64c96f43f85691fca07900e87ae87cb673f86fd10e619f6dbb5b94f4f33abc3887010acfbb2c180af6880e8ca1a204c9d731b194cdcaadbdee3dd2a5a8813eebddc4a486b6d555a6014405b7d0733f9d267f598325f0879ab28cb3789a9bfb995a09d4e7c83d23bfcab6e3eef44a0f22f593f16579b85741bb980fbb50cc057287f4f320d12f6b8c1701afcc859bfa15fabb378efee2f11f15036da570c47262272ee35e32e66ea1a0aee3b002f75328b7314619463223215266f7ca10c631d55ef49ce9086a253139785b5a1324b3ef735dbac828bd87a1053feca8dcbe1ba1c8352cc0df6edc2977dd98006841d2fe1df3494c0c0f9d29c98e1183640b71cedbcf1e30c83fecdb39275c585335708dbcc602edffec5290f143fc11990de7528e470927c3de9a82b9d423f238312a33f1c47125e1c4cc7d31c4e38173d1e4a0107cfa016aa4d7c93429ed443c81b6540b969c5b62a4c70fe31abc51825c8d6dbe8dc0ed032c1da5a1b98e2c47886aae00993fbfa2c0de580875501c2aa344435fe904479846065d385afeedd25be02d999afa0fa29b9d685d97dadeef76410c897f680826eb81c00a91e24e4ce05f52d8b22c53ddb2156cedc17d1a1533067732789dc0869905ce0c4fcbbed66620b4544cee03c79114335baf2af8836d46fba990dfadc639b94d9446623537b662f8e570679c2131b3872a0d043e21d6d0cca2d07535262ecd9b6173f623ce5959353c187e8bd1a2d1863feb11b01d27bbf213fd17e0d93161ccbdd6d29dbfc530be9e1549b0474ed918323e1665bada51c659fda084c8e11adb98c9445bd91b0caad5975359a79d42946e0ca3b9a5951a363e02f4f8043a1ecabe2e9c491daf5ba89c6c19e945bc1fb0f9a3dbe7b12740ce41ec1e4314218004d95693bacb03d862c130e9fbd7bf0c3eb2b5f60a92d87b8103a58342e0f37b4e70965353448362703fc78633d33ac307ef5d8c1599d6f17a65c572b8b83473934d8d3f2f902995d031370c85dffd3663085553b8090444347024cbed7b4e3a8615775d969a2fb3d2021472ea4030bd44c0fca083b71ef28a7a8f9dce7e05e83d3ce7c53a4dd0d5e86af801e26b6bf1cde595491708416233a4c04fd60d2a9466f00d3a9671e794e93146ec451448c4882b912195be6d1d8da465a4a54a300bb54866931982aedac559273883ec3855100f7a617b3bec2e72ddffb01f656c71b84c2dcfd38f5f619981dd38acaf004d86e4360c3a275957c467543d8c6686b7e6fea623b7c8c524c9f390bf9f7b4fd7b7949381c64d4ad72e6729f0b101d1d93d5cd2b6040a32b38946d78f1c53f246771a4d116b0899534333af23b947ff6dd7b231b43c7eb08b7eea2013ccc054ec9d707bb55f89c2761e65f12b7e5fbd85bd0342d663b37cef468226ec8053a5cd2af40b9812f3ceeaf4c974df87ce82d84fe52cea3b116d2463edbeedb91091d493a79a29bed845fd6efb0c81cdcd0db1336f7c379ad702f89572ce3f2fc461ed9af7d2058afb74b1613327c144e716de9a0728446804eec789b53e37f707f80cd775eee4e08d674e0d598aa8cb26ff9fb20b61de3957250e3111fb687234f8f29331c46b189504f189f67ca13c96ecaad29188bf8fe6d8bd2acd1d8e89e845cdfec8b7b3969f0a8f53b93d5a57f363c0668c5e8e05d2149ce84fcaff8a815002232a6663221b27d0afcbb257ba423ca9bfedd5608e83eeefbaea15622b920c030cb368f07569bb282dd084f853412a1dda26bb865043aaffe668230056ed6874c479a4d44dc8b67e1019383abf33a8e9db4c17635fbe8c2f5fc8d365a6c6ba6272b6b88b60aaf0d20aba65713bf766a94db94f6e85ce30e6b0f90d6f8132c6e174c38570496733e46f2296f12f59b84ee1be09f58f97b22b48382a6936cccf3622ec51600fa7fc1ad04765f208a5de2896f65beb765734cbe6ac28f63ddee9ef2e31979dbd65622f50b8a1bd8ecf9af6ed25e6ef68b47f34c3a8eb112b3f9c50156c975a2fbf0cb91bdf56d572eac4be304a7e96721f5a96760d119eaf8db9fc6a6ec92033099d331610810b7486e6920c5c258fb1562ee17d12c59541aa7ebb541dd44a49da332ba1c1f08b0e7baa7f78416b53c98a16307406f88e8832aae90e3fdaf39eb1e6513e7ff1f29cc2289542526ccecd3988ca4b00fe29c5c9edcaf3fbdfbee257b6ecbecaa20a928aa008b27ca43a9161b726b5a7d719c7b1b676cecb309550cb53d36a6c3086534040ad4af095c20f83cf1614534c1ab07176a03fd7a538c479d93d25218ac4187b504f87fb7ff8d2cf18b0523f011312949869361b0d33e9c5f8130bbbca5891e1e7a6c3867730d8c74896344632f081fb916f19c0747bb02c83acedb11f285446775761dd7021c7a1677d49041372ee9e363a54e2f9402e0c83ce08d88ef9c7e83e6aad43c42c52cdaa73dca5e9217e247eda2ff38ac2c741b1f6dfc4241fdca7c8771b622a35b618bc9307578de47aea427a691ac014fab0f4bf77c1e824fb42bd5ac56a6b4bcfa085f8898c66192aae34bcc02001278de9d4d1057eac9962faf0fb2ea25259694d09e08eac8f22061a8117ec2e54a1183f261ec2f767829bfa846fc1ab857d7c5b22fa1c0a9106670ea0b0f5a41569e230dc2d5472b01556d6046b05c6deb7012be2e9b015fdd72de75981cd82fa6a931e88a5d7d216d1971065b3be954bdb5f9e6bb619e93c9bcc0f9fb65371c553b016827165c658f30c4858c70720073c50aba585eaf0a381bc985858171daec4b2e07a71749991b86e3712ba340cf64dd3508d0d44bb3f1f785d814e74d57de118d28bb743c53cd553b0918fc3dd5b1a1fdd7e2eebfb58c5bd0ad5991429f08ca600b6a859a41d2112a1c86705400368c29662f2048e49d3464e136d4953cbd99fba61ee3b30a0d088d996dd456d2178716cb04ef016f326baac279603e4aee2f16b0ef12ed3e4417aa40f6c3644e1651fca672a94a3a68d65738102907a1b9b9e3284246160a2d7a78b09fe66f56fbe1954a87b9c96fec8cff729c8a0a6580b67565ded0c1b1610742d69bc4ab44311f84639e55fa040ba61ca31f8aeab8d07f951ab49573e3a51cfd63abb9e052c2ebd8231485f5b6a144d0f8dbde077066dbd9488078b62a8bfdb75d779e35e4c8bad960807437e9b0a551ff9b2d72df3b9d1cf9d58d677aa1ba4c55625a5d3bc8475a97a7e6fa76a305dfef71f750c8639dc8f2b4e04295447910340e25859de895205de9c2234d8a40202a24e22c00c6786ecc70ef47585bd05beeebd14896ff450bd703a0212b40a96d3075a2a28216d58eb98426febf2d718aff38e3127030ab9adf9fb5454d7f252b9bde582d6c48f9e906815b542a99904393da2425144d8907e5920f3d25f0567984ab63f14adbd72a7e9eb687c4b2b77236070cf3b9b2df492d5052bfd5978e50b4610426a550e7084e07881e04a0793931de39c26264cd166bedab20cefdb0e09b2db30d0b8b475d304c34637f70eb7485f0e18caeae1a208923aca606fccfe9a2169778634e26f6fd127075c8eba45d86946f94cfe8da145e4f3a1bf065717f52d5635422ee15a2c86060792a42297996768b0ac5311eba24f43871912257a58886d7032849b337fb23a88b15b846eeff43bfa5240bc9a611c6ae51e903fe4e70ee23c23fa5cabb55cbef410ed6b5eb6ec291c911013ec8e01549b1f8777ffff76e4f1f44f298a8cfc676ce7743afa6e394c83e3e05be7f9c95044590b1f671107cc22142548d7377683b2a3aca15c2828d7a13b1d639bf60d1421753015c2946f67bae47fbe235f167760af7c5fc1fe37db79aba58a99f3b664746c5e141f2a1eaede7967649f4dca7ee887df2bfdf4f453d78c1ccc29faf71c7e366f2bed740bf113ca521f7ad0298c5b576c47421e8630c039dbe2995c9e7f041ea275b23669c08b4a945740aa163eacf3a1fd40ff038f964ea327bed16b615d5485520105863d5c442b111d51955e885e5126ca1abdde748262c1ac032dfcc1a1c6ed672e8170c5e91ce019fbd0a285886d53d47736ce414e22d675464514beabfe0ad84a31985a9a67c0e4e4243ee8d2fe3974a9cec6d1f31d2dcb0f73ed9902539904d1860495d8872f052d081a771862bc5962027b280b58516483c6f1d4bcbc89659acefa769e034e444586c0864a3bb1e13af1615976b75e4dde508635313a1b69ab8335a57942d67160ab33ebe4e86f81b27ee32e0822e90a9192bf982454a3cee5bf0ddb3f15290e0b030e0f381161c489d00959ec83a3e9e88d4d4b485a429c9a793ca1acdbaf61e15bd416e32314c5f96e4a283398b050726f34d80c4e20215bd1253d9096c46dc7deb790eb74374cf17e1e13a527ff1efcdf864b9920ac7aa767d8e1fa6384a4dec588a55bb6304951303ea5e8b714edd56cccbdd12bc4351c76c48b3185f4c2f8c2c868e723e242722d8f4bd84532f463f77227bd057e09cfa94a37b8174872f4086795839985de2426fda629aa4a1f16d4d37f5b3512700c8ed65dbd3a4021d8aa944c9cd31634d994d9d450e0a274dced341499e2ad1f3058d810ae34ca2d315cf94f3a9f879ad0757341c23de6edd0e97d741bff18aafc32236153492f6be332f1767d8d0326f4b3b86b100975e37cded38a9f2981b93e772164197e9da91a19b249098258668a52158ae761f2f469c1cc2ff2f3e848897d33e786895cc2a56ea6dea75b2ad40bd774f9bc660c18681f95aaa204226c5c44443c16c6bae6f480cd8941cc39a4c39e31f330b1540d22aafd21175508a4c3b99068f365565594c1efdddd314332b46b2e77e986dc8c7f11b380a03e9a058ce46717b6d81db75aa3b19fe0367985bd3cfb72eb5dc83a1f400e068f1df65dff9a276c47bc8c1be8df8fc601fe13a0b2616d0f2fc62d5d87131ab86a726b6054ae44be92308ac02a76639b50afc2ef286ad79ec855e7e2b99a9c298798e510f56e79de612c683f6362f1754fdaae9c28e325267cab3e19ae5a061cd5549c0d074c56c0fbca977d46093d06d05c445880a207ddd34241ff64d45626de791bb2ef509eb8ec56fff28cd1052f3e16e4084c4b91c00912485afed89f8b5e09e25f0197d8421d6554b5d6910067dc6514b5082cdce85b42ea516183589c09a0213d948f3e6a419e9c007d5b267241374ea540581b37114ad568d57234ffa9c1628a120828c15b364a46a0d8233fb4d239561ce142260a25d97797822b194ead036ea18d35ef42ee11dedb51c0909d1cc2fa52e0b69c3dc4bccbd87eeb75dea4a8c49ecc57929f760a89a5df3f486f54102fc936d30d6bf022a2ee870553c612282c45a04cd74d9c264c525947a65d04eb7f8cc4e09a08445938f15bf61130df692bf5ed9e22ac0e1480f02e6e2c2587ee3a63c358325802853123a46f515f785483c1153662ac00980ded7410a14390f6ab1d5a0ea944bc5174e3227eaaed6defdc59008a5d586f93815f45beeaae5394c9846538051f83619448faa73ce9b21476b51e10432d84065ac15279f679406266ca95dc8edbfc6b004816a5866198749d36497baeed0629ee38a0124569557b1c63e9b1c8585ba26156b408ea49d5bc2aae1481246ad1b65c74d2d85430bba5c93dc685ee9cd012c5d6cde457fc1ec919e0ae14d7c0aecf4c7e40e0b6f8b8d396789f0225059751782f3c5367f76db234f1612dbe17e946147c6c49b12e39ce5b15745f2d096796390a4f935994530c38072778d1c7e4b8cd10e334580afca43667f1d1c225f06cb77ca0c895c2159a3283069944ddc18c6308e2803c9a49cb2bb439a36d812022930f3d5e40516ef4fb585b72bbd05e2014f8cbb9f4c75fb143c9fbf8d8d5daf037879b9cc256eb496517decac3646403aba95af71d976ffd8282a0c72ab32dc7c9d90178f634594528a01e175943117c93921665b94052e5891634112d193ef6a9c694ed53580d812ea3cfef65d3fce3594fc2d495e9203514d6d3550645435478d59d564bf1af19a568bc0448342288a8f3dd2034f1fa9cd9245365cc6068f0c0349f6fe52db41ed187da537c9878f1dd3c2ac840c3fec92812dc3ae5629cc60cfd017e05c408e62c3b9ec51b3f7c5e95c6b23bf86fc533e68a2c207092f2da040a6beebcd4cfe380b8463e2e1e677d2543332bfc4a33c9bf2bdae5a3d0f868a483872fc65b9d27fe02019f833e3b3305c6f6286c8bcfc8ef952b0a709b69df9964d8a844e386ccacf02cf3664f50ea36d6edcb839cb80d15e330a264e4f24166d2cf1521233656e06d237384d95d16c4bd8ec11fccdeb1b094f82620562cb36a6d53d204f0d3fd598b02aceffdd61c13da93672f81dff9db0b8589f23f23235e13db6b56b2ddc63039e9585ab0e3950b026c301f3ffffffffffffffffff18f61babdf2c5076ff94524aa158152bf786769229252925a793c24070180500000000884dddddadd940ed0e670ebe0efd58fc133620870364a4a2ca2bb6ab964e2f6565a0021d4dd98c8ad153a4a662e9d18a31f7668ad4ad6f35e5e5aafc7121a530f67c0c9fe3a66c972485aff936d46be7791247615adfdc0b22d3d32a5194fa2c97aeb4f81e93a140c44bb7e2936e981814fc8e6e19998376d5d127d29e4c7bf3e8b89de31389448627764fe2594b86c798d489f308f9769dbe77b54e249219cc200631f0a1cbc383482432385185cf61deebbd44e64df0593fbccc05d98c9b26fcd3e0d194ea4b37da4c582a3ac513f53181ae18e235ddd77ba89778fd83667608d1eefee861894f97cbb885265929fe424625fa20c4856fb996cf394a2ceb1d7d44ed58c5389148de83f09031093bb9c7ccb9ed4f3d24092b0891593fc85b8c2b125a3aa119b487bfd33148985496b78b77b3a9ff23d674d56725fbd425d38406321c91a7f73c3a59feb4be271249b74a243bb8d09101198dd04ed355ec4b66d019166430023529e24cbc27f1ea1661b2ecd50e62356f9b901728067284e116c81103198a7894294bfe1ada54362522b53147e9ba910c44985756ebaaf462f59b4824de8544c2020d3200198740a911ca2d36c7a0196388ba5f6d2f5e5c529dd5838c42949d61f66e1eae63228429ca57909673ce7ddf20befa958f5944a67882e0a3ca6dd0547271205d34e08706bc001244024284f88f4ac8080467973a06539647bd0e885bad56cdab3bac877f583d264b51322f8d529f808b12e8d842861f90a964f8587df71e6464f461b77851f1e4680f334f1c20830f69d094f7997b9a463b9148de3be043c61eaca4d495098f9f7535197a287fc6f0d4613376d2630441461eea581af22bd3544c3a78b0dad2452bcb527ee80edb7d7cb34c59d39a7a800c3b64662147fcbd2a79a60ea8bf1d8b2ada49890d1d18b1d2aa1f672ae5d11cfccf31b4fb480bfb141972683b76cc5b79ab947c7140e84c3a9ce5470b220ef9e11cc43720914040061c1032e5e0f9b446fb8b4d24120ec878031f94599dac85d1519b48242ef01f41bc870c3720abc24488e879b6de868228cda0df343f3b63c37d41c8efd794fdf55cc3155cc4692d9da3a74c0d7e8e0f9a836f8f7a2e021969d02b9c1e95636e88db65a0016595a67f3225bd319f84b13cc2f0f18504649c01d99bdd17f318ffac19ce7cf920ae5b366bb20c9eda7c7a9426919b6364f8439e58d694e3c5af8c21b15d77e9a147779a2c430cc94f7b4ae58e2654c547f7e0f1038844e2a329f04303128990150001322940c95104d0f1858c309c82874f524c856f0540804c7c740f25c800039b3e86782dad0de9994824427c08901f2ae30b25195fe445d6e69cf3024a6cfa583d6d4aaac90432bac0edc6d4343179a66612c8e0029e3ffdda091d36e8941d31a020630b7fdc900bf1d8defa2612091732b4909067b264fe13bd1f2c00017298a3438810f762888c2cd83a9b313327713aef800c2cf829f5e5abe74b7fc7094ae0021957a872890ebda77773e3138964478e1d39cc014347107f2040826c20461c6458a12073cac9f256af9a5c46151227efa6d365e698611732a8605b2625f21a3a3ede0fc898c221ef69197b6237172123902105a496bba7c65a02195168552b3489c613ba3532a0d05a2ce91a94deacf1fdc0c9784226a6a4564af330423891481a20c3095a3cd149f3a78f9d618efed1c3023972a840461312a17aed5baccad467070a643021613940a683dc4bff4d9ebf05642cc115dd0fa75e53d0792921f1b6b2f14bfbe59549c0b3af5a5c9a93f594183890810474d4b0e9639e4fdba12324eb4a77ee2c87e6a40c23e4794bbc9657c53ca68c22fce9c2c7effe6c17f9c4c76a086410e118255dc572ccbd2c2712490e1d6170185c071943c06d6bfbcee2a998f710194248cce94e3a6c4ebf5b1389444610fc144e7b74f4f6944320182dc86032ebc4693ff04c5eccf964fcd15727128910193e485ffc44f6ae78c94a0364f4c04d1593794629e99d9e48243b64f0e01473f2d2203ffcd63409f2050f204d02193ba86428d3b4389e46533c64e8e01953aac4f9dead694704620841460ede54192d8f742d112a5df804ba908183ec4b2b9b10327e901b30be907183d374ca29261be3fc22c3067806fdbecba12d33ab85d99962cce147069d9476ecd0e13e56ab20428b2f494b6157b935574f24120d32e40511c891c3870f7d408e06e890486248416416e5142d7f780fb1b0b1894432041159984c05d9ee633278fe132e4462c167f0ee242c5de5ec8185daf7955f849d2e594d76f80f203e1e2091f80f203e780422af283b457d8d791f6a12445c61290bfa151f3ea31d3f34f080c9901e2110e2c3470372e4c821911041a41595860a9a45ba7838151588b062db30a6f739f66b6a316e20b28a4a08adf8617116c22491b840441526f1a09599311f558f81482a8e799a2973908da5723e4450614aeb39ea965b44356e011d251039c5172f9a6e76a8147405022d1031454a5b5e54c5d7dd4489848717fc02068894e2fe4c9fb269acd85b4861e968ba2e6e29192fa350d36e63abec83d5cfc361d0c387af20881f115154ee1d37554f454526811c14d0f1856240c74424148792223b6dfd9bfa4b0414c6cbe769722f8ae5bcc8272cbd4ca3f29f77ce2c0ff616f06880882712df59f44faaccc82b10e9c41ec3fdbfbcb9ceb82610e1c44153c7cbf982a59cdd4422e14287074436a1c6d8b935fe59a9139a784b243b3481973cd3faa4dd56839248268c9e29259933c8e978031210c1c45539c5d8a07ab942287209554f7e924f3a99d279c704b8d0e160f8d0168858a25417aa735d08214522956063a9ce4d37b5bbd04422e9e2478f305a22d901821c16d011c48750e00bf5422291482e204209737f89346fb950914e36203289529231db7d2a36664612058da3548a57ef21e467660b1d0f1089446db11553eaf36c6e81c496c6f593fe4d3a05a940e41166ca3bd27bc553ecd711c9383a08254ead46c91a71d688d2299b7543eb0630a2d7ec22b5f74ccff545f8e3e7b79d255e5dde828822b2aa5f4f426eae7f790591441cd4958ac94da6fcf84144974486959776c70e1d02dd911bd5a2590a7e3241c410e7d30cf1a557632a4f1030881442df1995c9c62f5b75429c62c89e909d4282c8207acb9a642cf9a6d6a320b2fa3d19a15f9d423f99824820f41883f7eac5c577490a22803076b4c893f65241e40f55f2d09ea429efb3e48af821911974eaaf0e9eae14e9434a96b6a8de5f69e18d40840fc8fcdeef5daadad43491488600f121640f5acf68a832ade5597741440f668fe97694a9541e261f4080ec0744f270dffead67f037a14f1d88e061f36c23c64f95bb6eeea0e96ccd4cdac4c2ca7638e7a8bb721e1b7465ea605e7aabcfa4f7492e3af4dd9b4126f3942957211099434a2d7e6add9c463c39fce63f5a3cc70be2561a88c4a1dabfee9e39b95c6a3894a983494f336eb9d40fc8e1801c0d20800844de906edfcda75352ad2945c40de59c5dc582c6199d527820d2862ac81c36559056b1251bcee097f99f4174d92d04913524a24d75fcf35079a36ad0f37692bf177627426948caea6ad4b4a6c2e83b10414349bce26fd2ff513635103943e3c173aef8a4d539c70ce6a037c74497b4dcbe173dd4c703365006d7f43f3756c3c77067204286cc83c7182de2634ca90c44c6d078a65ad7b01b9e471131d461db948f509b72281bd0039130943bb564091569e96bf5091878b58ca793dfc8b8682291a0c817bc77b760b274aee63d24921d1ac8c1450e0ce880804422e285ebfa744a9a1f4ac9f804912e9cc5e496a5f8f7870a086e20c2054df885fc3042bde7070a225b3859182d162a0869b93741440b7c5611a5fb84f8b6cf092259485a4ef7acdd529ef3175f280f5e82081690afdece0a4246633e03225748e5a42dc773a8b8e9011810b14221d2d2e593f749687a2291f0e8e2478f0f8854a10ff596f9aa7515fe89442291ece802c805bc001244025510a1826d157bab5f6695442e74f8109902bafdda95474bfb47d3028944880444a460c768113aca6e0ed51241240ad8c5e0a236e5fc5c520e44a090c959109bd33691488620f20493b5e5786e1933dd9704112754f1d2c8b9d2144bfb451069c249b87a8a267f25cbfe810813cef2269436e92a3a9e8ec812ba1a39d94babae74d2b1224a28fbd47ac5c7aedebd813c60022249b83743d9cd6a26e9e799d9a20b11242832dcfabffa68b64b0c1c881c2111994d068f22935f28032246e8b48ef5ad98296d321b102982ea5f32bac935cbd6261209172244e06b746d4cf7eb41771a880c41dbf11da17fab25f3404484709e9e9219b5329396139120142a7fb48f416ed89c69200284e306f994b1fd335af0077cc9118d1f2a4b6a5a447cf0a667de283a8e12efd50c447a90b2d1cda52d873b992203111e7499576f6a9fd7ee2a3bf87bf546f9057de99648b610d14139fd28b524629a628d1104911c2054cb25b9d1aa437c1389e402124910111cac5ed92acf846a4d7a01082072035634a6c811d972f9462007173a542062037f3305ddcb7f950ffa18b53898aaa049a855f90cd2c2bbb6f7bfae2e99f90d62cc8251f93e69d55cdaefc80221bacbb4a96eedb9c4c27071da4a9ca928b1c1e2754bea42e6d20821f48218af482ce8afdce9d7d5a61f315c91d45c4f0f1f2717361462b4420fba83ca19155b215b410c565817dbc272daa6b35c8c26c458c5a9c77249d1a527e48da18ac452f9c90b9ae7656f418c54a815df63e8acb59f390ff0a11289ff501f3a80c44085591ab3653b5a418c536cd152fe6b90e5416715c43085a983bc8b0b3242d8e85dfc701f3e74c20e88518a83caa80bada26a259e481a108314ed9fecd3f5d933a3c68544320a35bfa48730e555c1230a64d3d756ac69d2319f48245f00914892291e904824928b118a35a87f778e1dcc5467c28347016280c2f81896a9f35dcc353efe627cc2fce1ff9984aca0f54f500c4f2ca2f9de5416a9bac18944d205900b74d105900b7c012403124917407ce848313a714a5f699d96de2a88271249d595974802108313de6e663dd5fe5b8b4f24924d58b2712f8eb85ee88328182c102291488001313451d765903168d350cb6b2046265afd6dfd9c74e7f09c8944928218984866d0108d4f31f805831e675e50858744726656f0811897d0c3ab2f993e0dcd1e0f08d1a1312c71e69fd7bc769da4a62f885189c30821b744266350a2d33125f5a24467a9bf3126915c5a6e4ca5346e5e4920934cba316f4c2a28a5306244c24feb56d9ae84ba98328901893bfa7e7ed3e1bbc32783188fe0535fac853059a5a2180127f11317b8ea1ea12aec2d78399ed77fe9069d3a35b49067d0eea1bebdc7b32cb825932a8d7df1953f5fa80b3cf043035f030b8d7fe82f69b7f9dd5e21213775064f6ae11b7581101e3f7afc78420d2b18ebbb4dcaeece755b871a55383ca5a6361de1a52e150c5ae63ce752ca4c09c68f08d49842f2d6d293d2a73e8f204078d490c261c48e26cdb57cde4d24921a5148e5c553763c1d944c0d282475f45b6dca1d93a7ce50e309f685085d9d5be47edfed84e3cd32075d594cd756418d269c4a8b7c0e5d263c26273598b05bfa24b61e5a93a6263596a0790ccf97f3329e522712c9163594f0a58f0a3ab9e8f405e1b1230239dcc7f6f0e143ff070584780778841164888e184ca89104acf3079db378c8793d9148bef0e2033b1e902308102f58043a56f0a38707bc6011c440420d24acee41a59c4a15408d23f89de5e2dade2ec6de080995bcc2cae6bda4c249043450a308dd8b67a814cb76f79e48240ca84184a3e7c9ed11da09185e7851630895756baa78294891fd4408eeadbb9e4e4a774e022308103058c03582f0fed5564ef6629dd21354030849ab124bffa334d4f8811a2fc6bed0bb2812a213afe1833b4768fe98738d1e9c4e7e18cd6e69abdbc4259214d4e081f1f3a7a37bc8dc7eaab183e388d2986316f394ec8944524307db6b2a3fd3a6ad2c9d4824357280e55419ec4f5b968626128937106ae0a0bc5e1ad464de97cca97183ccebc6ca5edecddd1a36487bc9da7f3d8d29f6138984462d2ecf1554fefc9da53c2140363019d2230427a0410b56642d893967a1ece935b92bfe4978b2a8eb4f684d6d7e2b3ab1d8b7949a10e9731d5d586c716929b23cc68afc159ec99cac6fef0aae37735756fb5f745bb1c6496db3fbdab48c155c2ee141d3ff34c36915b70699b7d69498cfb22af6d4f3b0734d751d4a0572b33f6325d4bd875151c5ef3c8f93aee19ec2ba72d79ce43276f84ca1d68dd2b4cd41ef544a61a52f7d4af9c67eaca4d8f2cbc9b496a3b9cfa3e0e4a85a5132795cfb45e17998fc9bb0526a77283eb11e545bd0e8da22281a4dff2332e5a44fb89f483f5cf5f8aafd7ddc1389ffcfe9838d86f17c27d8b07bb56d532ac61c4e20b3e8f3ec3d8b8ba64d981753f46fd99a68e6c435678f8b65d14c94c14c0553b7615a61828b51d52e5c3b83ee2fc1a56876aa3a885a1959c28edb9ffb3dc8ef5a2a810a51cdf46937e4ba94305d3d575f2ee93a7912c75afda09a34496c32e9379543790aea8e844144d7b674deea7348a47d2c7c8c5769b3531e610a4fc2d4ccc2dff68e289ddefa333d35a252fabf398bcbc7888cb066eb2d63d44528de26aecf53f6784d1106cb7573f2f7f5b33b91f0f8220a3412a1eb66bf66faced820e2cf194be667fe26ef0fc145f5791f6d63edd617340cf16fd4d3a3f2c2f76b6814c219bf4ee51e83c81c320d42a436fc6b6896f5fc78108fad59fe975e107f12c2ece3572659371028932eb2b2fa74570544a9553c4c4745c84633a0230a34fec008d94cbb20ae39a6ea0744b493ac25cf1a1969f4e138539f2eefb5e99969f0e1ec232d9eb29429733f914868ecc170a936647f56558fe9c1d8cef314cf69ca748240230fcea6efb52b1ded47a9081a78b0639d92ad79ad529b3bf0a536ac4ac5729c69021a764854858e49ca9b90ddd501bb4c67713c678771e9607f101a33f9882cdd4281c61cde3e35f6512e64993ff921073c6ed694fbb36704d2be27a011073d6e9b4aee1f96aa24916cf39808c1000d38a05d74f4b3d408dfd3442239008d3778a79e73ec91a3e3522612897b80003a1440c30d89ed20940a2ab7fb34dab075769d534288d805a0c106cd9209cf69d345137b2291f4a0b1062ef75ec95cda7e19204082e4a0a1863e95d0bf1754acb4c104060368a4015342a93c2aaff14786061a105294aacb1d2c9b2c49a0032090487cf80a820401f2e383b440c784c6192eb131344f739217e334cc50def294c6d37dcce83cc806620881461930954bc6f4b57da04106eb5e43883f793a33021a6340b4e2491d0f3d2b96c9077e684022a12186a22991a73e9605b117a08710201bc841812e3c035ef4c8418052d00883318bb2ac666fc9779d000d30184fdcaa68309d4adf031a5f503ea6983667cc8f0fc880861750b9a4df660ceaf274263e840ce9a141b8e841a30bc5b6ce9eaf116d622e020d2ee4e5fbee296e97987a22910082c616b4aff9acab41b64cfc41430b7cdefd127242a3ed68229174f1a38710302a40230be8944fad9ff2864f97891740824880fd0b0f48244c030b8b08513d174655fd88078d2b202653b37b87f30d268964c80b22c0a369588111da6d694b2df33bc2f81e411c041fa0510537750edaf2d5f86d3e080d2aa8731f4d7acc98430715a03a90a33890a33690a33490a33290a33090a32e90a32c40001e47a03185ddc2a6ca55cb5b1ebfc0fb470e2ed090c29ef46bcf7390173b2f51e8724851712d31a3798102eae6c154dea0df7a91008d279464e998da46eeadaa1289086838e1572bd3b17d9a525e4fa3098ebc5dc79436ebb9294c586d47c995baa994dad2008d25983b47ef744fc9c73d043494608cb1949199e63dbf9204c45e74a52053c837e9442251000d24a0f99d5db4753bc9fc118a7b16222ad23042b1aa25b7bb3b6d558aa0b5ee650f4dda94d934888016f10b91d7d0962a348670dc4ef59d22ed83dc08e11c9944c8d3e29e8296461096b3caadb159c37e060806396f7a973cedab30a0f183f2bc7a909a6e5f3459e583634cb59e90fe1d551ea5031a3d5894d8bc15eac38b8cee80060fb2d860e1a3332e4a3625088d1d20af54f3bceda99cf41ad0d08127e3e859affeee20fa80460e2e31da349caccd9623743470700aa245f595859c587240e3067ae79141eba37ad0120d1ba865f5efb145283996c9901efb8019b54896b9a6204537eecfb4c036e5ed836c0717538c21cc988516fa467ada131833649150214d7a2afb0ee199110b2fd54644e96b3203167e8eec4fe6da9e620c901f3c66bca24aad9aee43b507eb7a30c315095d61fa377ed6c6c298d10a4b7f59caa8a1e74977c10c569451355ca857c9697b155f88fcfb545b492b3b43157c7ffc9ed8a452990a1066a4a2ccb6d2f183aa349e9a48241e98810a774678c58586e93130e314e8f0b1941c91a16325444f30c3146d5b2ebbced1c2541d414c04669402b1e3a782ba60066690e21d4bfd21b4848519a348f6e3bb32960c7be6086688a2912384ac8a39c7549756203e3c3023149abcf394f2695afef8e0e13bda87f79080730f1f1e18d2c3013ab898010ac49cb06449df0551aa0af4139c25f565ea41a892cb8f1e5eccf08463d6221ee22c8953994824fa8510c98c4ee0b77d41c9a78530cd0c4e24da435c8cd3bd91f94d201b635d0e6efeafe2163a6668820bca534484e6fa0bd26182199978e52a453da90d4be1199830fa75d77848d7fcec12763a53f29d32b38996b074ff5cf631fdbd6725fecca42dce9cd613254a6c154dcb09b51bec2f93e8e693dab3af52293b9248ff73f44b39c78d12c98eff4181184d9811095356b5dc33ff206407073320819acd7cf81c349148663cc24e363aebfd8ec8798ec874b44e2d836789bd11e78abe511dc4aa86652291ec08e242c080c0ce60c416727f796bbbda53de8b6053de8aecfcb01c1efca307086628c2aaa034e9f0dac9f24c44a151ee6ef563d0fecd40049b82ca8dab09171d93630b1d72987188ee6426aff0d9ac58d991011d4a986108544753daf4ae8266bb10a64f31749f7bde12ea0c42f09f69c7b78462d860c620349d8368b38b2be2ad19cc1044bb7ed16f535e5d8781485eaed19462fc943e20cafd1ebbeb44ef7bfbc359d49b85c97aab5ffda0950e272c2f5c3ab50fc6744aa92cfaf43c69f850b81142ce892f613969c61e0c3a4c97a8392d35a71e12939e1b6325391ddd1979a82ed668ddd53e959a81072b768e79ebf894cb1977d84d287d5aa72dc97fee30c30e57bcbca6748c29c455ea80c5115523fc7409abe990ec96a6e7295542e6e660d83832a72f623d75391877b744a5b2f0b74e1c1015f39fd1b1c24a70482e8550cd7daf29f6062d349b123ab6f194dce0cf87936efeffa6b136b4ddeb1b4c6e9c528f0d99b81cb3df5fd466b906d53279566f12d2d2a606d5f382ee74b1bd9d4903f7a36ad3e818ec346838a866d1d3f944e868cfb0cf66ae2de1bf29c80c997cce3ba7621952e9e3b7b55dc367c990a9d452e2f4499b6dc760e7fc1e4b2f74fbe588c1900d95d5f4e5e9df8421a5a2429dfe7839238221d569d7e92e32860a7da1101bd52ea911175af3c2db1ec3e7b2debe5c5d487c4537bade59b5890b5ce84c4ada9f92f13b5bc8765de485bd246367b5f0ed78f252f9bd262b5948d7c2559fe7cd591c0b5968cda14d26151baa2b984e659039ca07a152d80aefe76ccbebaf9be35f05cf4d7b504b5bb1e5510195b4274d2fe6f79d9d82fd95b35519748bce4821d5ab4af1233fd5de5130291d9e33dc0d0536cbe50ea246c4dff78445bca9979b85558a4e706346a8cc2753ca29a5098bb4b9f471756bc766c25556e9a23ac61f692e01692a96cec61ea544a584ec572f94b258f91b4b42ed9a3c85b7e5cf4d21c1d38a97ad9c3573361d214bad1b235b9e93486718a15aadcf397eb22fbf138964c7036614c10a29eeef7b7a614a338860d69bae52ba36bbf989442264c6108aa3e46330978b395621207408579f2d39d39b2003981104d57bdff4758b67f980708aa7b32b93da109f9c00e96208184078f098f18384fd5dceb5ebb77e80d13ec307e714379594d914cfc72a2366f4a0d1d4e91b3a88fb8e9948245bcce041a9b72baa34fd830ca6193b305c5584e8b8b9925c7560740ddfb7e495f4a654302307a8a084ddb7a78aeb691c7c17cf45a7c9a7dbf30688fb57a80bab78f7cfb0c1ebd1349f387d39f55c0b35c9209eb4d2da45800c5a545d4966a76b8fa9661064cca2bb2464d62dc9fe13cb220be2b446f12e5517148b3ded49f78a7e21969c7040062cf81af751fa3dfd666c888c57e0979230b5a39268ba5da1e72acdbca28408b1b422997784ded1a9f458cc0a7d94f40d2317ea64ed437f682007173a5e20631525997ac7772ffcdb528516e76eb3081d527f3b49b88108de74537d48d327f31e02b7de989f5c5fffb386c0b23d6f8b9812213e85282957edadf2242dac84502b7eeee031c82c1f3308e45636dc9dee69500ba250d9f1729485537103a1c51c63faf47aa7f5054429e78d1b2fc8944fe381851b7ff884dec9cf0ab5b5791f6008f1203c86b00619f202bfe107af94ae3816739cf9981adce8c3996583ecb7ec6135290237f8c08b3e955c83188109dcd8c361795a467b8e49d7b3c50d3d245f994be376f27087ade49b5cf4eec71d61e80d3cf09df39e5deafb17b16edc01791a634bcc979cca94c2458e2a5c104007deb083e6b2fb9d8449950f81dca8433274bafc9d3febe28f841b7448a68e16bd2fde5786c7101772841b73f0cd5cc4eb754f9b77430ea570516debf731fa4b243bfc87fae031841b7140c6ec2535451ffdd96ec0c1131e6faefc647aaa76e4c811c4fd875ea0bd0540826c200701446871e30dc5927231c5d6d4ae71c00d37a0c45394b70dd1a2466dc84fe58d57e242893f0cb7c044886e91c30110082308102f1c035fb8c186cfcb4fc6961bfb94dfc08d3598e25dafd26ba638da1d098c1b6ac8c6c3f24ae5412870230da83ff97193121d6365be10a2e3061aeee8e92eaaf805a59b335825ad74ae7c1ecf4166b8c3c7f18c31a674dbcaf0c914f1a43fa691274306feea3744dce5a7bf8c81cbe12f074d1944348b51881b623879d0ce9636b8c58d307c9dc355fe61e80e1dfda301ee1218e213c891830239b8d0216403436484e10618ac3057b23e7d3b4f4522b9f105756f7fb3e3c90bee254f3a594c499e8abbc066a9ec503a85f29473830b67f859f2e03933e53709438304d11b5bf8c7f287fec898b79a1b5a387507fd298ae98f2767c113a1a7ce3c85053d7d949cb194a2a6be7105ce84d0c17b93450b422b786541c6b69056015bef199944dbd77c5478dd7ee4bf42ae0f6488036e4c01eb51f99ab45b933ec81021ce3f1aa0851b52303dc934755e55b116ac80c7abfbe0b16307082c9063c71030302002861b51c874a96d5bf3d2a32f144ab252126a2e67db929d70e3096a0efbdf31279db3e51b4ed0f227dd3d9ff7dfea1b4d38ac78eb29b92ce1df206e30c13b9572e84be21b4bd883696c7255d7cea3129e151926e38c0c7fa71b49c0337b734ab2dde206120ccbcdbdf47561cebd7184ce4f592ccd56316b95811b46e03388cc6429e469c56e14e1ce9ced2963ace776211249086e10c1dd7c26d39ccc99c2786308a7fe9fed65ec1ce36078033271430869ff24d34458a64b6f10f6cc26466db29cf6b4021d720308e90af25c647990ef413b6efce09cb7498ace9db693f4860f90c93264f0acf7e0dad29c425ab218cc9f4c1a71830797dc5de89c561f7dded881a17379524746279dd5011ea7dd63dc6d4b329f2347ebf8c38d1c58fb9dfc622ce4aa7303072659429bbe1cf3319c376ec087598a7a49e7fbbd618373879141cefa94c7ab1687f991494bc58b415e264274826cd0e2f03b73aaccc367934a99c569c654b84c222d47d3c3862c4cab66ebffe3717e73808d587439de33e6d6fd37a11778d980c55f3ee329d79e84c65f619ff7fdda287d32c81557f99a9edba432674d2b8c8f4985f9f7bc793b91487808e9c18a8205ef3d719f17de5f85fa6d6f21e4c88c3157453a25953f68337931fd4422e1e10110a201d0a12386146ca4c22cf297d9521257e9d6e1011ba8d8ba42799a488ff12a1d0cb0718a4ae500ef8f9a8e1972fbd2b2610ab4a5fa6cead56df58611840b20364a51ba24bdf2cdb87cdcbab0418a3748abb29dff1f088f15708f158cc258428feeef2a61418f830d516c2a3c3d4d93585f58602314ede84a3f363f5e1530c030820d50ac2dc24bab59cea8958944f289bd42a6577f525f952e8f205dd8f08441534a2a54674aab8b60a313efd899098b15f3efccd11490820d4e94fddfbe3dd68944b2021f60ac4472021b9b502e5eb6d06143138aaddedf89a8a0bd9289f3aeaa29616b5dba9c482498c02cf5658c7929994ba4cc4a876c75d39d62362c7196cba7534fa2526c54e24cbaf488f2db9cb7a4c496f38758efb2247aa15f089944e92e5bacbe6496ac93846d7227ee92a5145c8cc4f125ea31a527efec4222b149a6a4a64e79920b136c3ce2ac94ce7450495c46b7e10844c634da87de4623161937452f4d62bbc1760ff23c86781762b0c18882b0f0295aaebb936711d5693219846ebebd3c9148c208324422d99163033a14716ecbdaa51d9e482436125176fd5016530aface4284a2b1f4de57d46ed46c1c62b952cf94f73c5454ffc2834824c78621d2a35a3e6f7ad2985bc710f7807b102e1c60a3109c0c712adedde4a7ecb041084b3c6cac78de955ce4e30b1e0f84c7eed8e1437f04d1c0ab5f20070872582047fb0f1768402209e22b08a25ebc77c01b48067ebca0c7c718858d419863aa54fc0b19d18f205059d4b3be56e87dd20f203c12602310d567cc4d26c3a8b6c7062032fbcf269696e2ebc1431036fe8032d1495f082ba95f4b2427b0e107445dcc13f76a29c56a1236fa704c19ee2dd75a4ab2c287747f93a9a4f7634db587931a3d59fb20468f69430f65516b4f669617f42060b00731808d3c744935a6a6da79e710036ce041dff8178ba396a67214d8b843c24f4dc918a467d26c626cd8e1dc9fa2e9594f3c1da2cd831036ea8092d1a4c5f02533729c48241ab041072ecfe5b895f294c93cf9838d39202e6c9a107edf977336e4803e952a87669a7c8abdc0461c0aa52bb73b539f6c06075b2c887fef948d3760b19a4da48d8c7ad80d8f4aa3c36b836d976fc33ba9da6d6cb07bbf2d88cda160630da5d0e1fa74642efa490df5778e49e74dcdb5540c6ca4c14a234e47cb5f75f0d840c35df2beb4e9607ab43dc3d136c6fb73aff2069961cf289be5a2db28c3e9826eb5a0a9f2a96ec2700be43041bc84e116c8519a60830c9ae950e1b4df36c650921b64b08a1db25426867c3dece7e4f94c6d36914880f8f08044e2021b61f83b5676534109b9a34d249202402007017404c20618928bff4c3557b9724cc80f0a48244286fcd02118b0f185a267ecfcb4cfefb22d60c30b8f52dff3b1dfe2de3ce1b1ba0fd0818d2ea47673d2f4167dbcee8944c202f7a13d8604d10d48245f78c124b0c1853bdc96bd5cd01fdb62630ba8144e460f135b6a2a607861430bddc5599ae8ac1bcacbc231555b358af05e4ba70d2c5ca7593e2fcb5236151b57583b5d7aeaa4a3fb661eddc30a8edbd7c8cefe972855a1d8f6a1ba46c6286ee2810d2a18167ea731be870cf2f801a4878d291462f162cde718ea2a1dd89002371bbbe3b1c3885aa290bef914bda8fe7193a0f0c7dbcd75101a33db78c261f7927e6cf6bc5f9cf0b5a5d2f81f46c9cc9bb057f2b06134e791758ec006131435b22366534b585458c7b9f02937db1389e481f050027e25d49c8c31cce23a91486c2421a9f146df9ef88d9c6c2001b5a057c53da54c6207e060e3086795975c7dabf9786d180171ffb3f8ea93177f1b45b094ec3d2db161a29530d820021b4e9b8a99dbd663011b43f8d287b7f978ec6a6b0f3684f08e07d5adb6135bfb4422b1118447b7eb4ff32aa5de8170f4945d7dbd37f3b6f1837b634c277cc3465ea56cf8e0f0cfd92925cd6423e33164878d1e9882cca442a71cdbd33f9148785cc0060f50a673345b529a92a5271209086cec40fffd142f7597c36b5bd8d001fa3eb667cb36faabf6c2460e0acde1947ae51c77833c54053670601017725d3378b6eabab07103f3c55f9131f34be6ce1c6cd8601b6d3a4f69d0ba96520b65bef3cdc48813ffd3a24fbd75d9abdc3e45d4988549b33e98ee773d51cb02cdf1c7638cd53b0f0f8964c78e20421e5123166aee4e2583c74f67262c90fa7942254d53f997579c83708b76d184caf103a4c1708519bbc2ccba3e914824355ad145d950679e7e358c2612c9163558c1d58aca21f252e4aeab584d7550593b66e4ac8a3a861035fe6a76964ac5b7c9f2bca6ac79d4878aea7244a74d7273a7d829de6062293e590a2e7a53a42d7a3b962ae5248315a8518aced4968d06ed509ae6a206291a5342ab7774146617b5366e2affa7df420435445165b8d6b0990501c22314a7dd3a996f1f7e264f24921d61a8018a3aef8bcc1c76a3a8c1a8f109b7c62ec6d3a03c673ee1e189734e221ac2663396be13bc75fa73cfb631a5d24422e1114690219c488893efa1772f56524d784ca0c626be14b5be283a55a67548241249036a68a21c9d3a77335ace8a99d84aa694526aba303563023315a7c2327c8963cb28395fa56abe46a186258c356fc2c38f78782a81e894a308a1afc2081d25d6522943ecd4733d651265ce2763b4bb94f54a92488c384b1746530aea14093cc8139775e7744c3624527a696359ec0ea77f444a573eb4b234914878d470442bfa474d54f4db20a8d108f382c9dd6f0c99d39f8b1a8cf8739229673642ec6f2612c922caa9163e7366b611d6442209410d451443bd6711eaecfc2b5ef04844657954aa5129bff752a00622ecdf7c31658f8f2919a87188d2698f6629dca26f882e73ba6b8d85fece14c2d25c622e2150ed9e1993f7c6b73f085dbc55b367b0b40ba2cfcca38410bd44c2458d40e0bd7b4adb7d8040890efac7c334f92985d4f88339a329bb9c1372fb23a4d4f0439ad3dc65ce2cd56e2641bef0220535fa6066bd712d352a7b3c24122f5a20881a7c30eb88bad9e02154fd3dfc7f29f9c9a46d6e6e3d9cc4aae654a54c5be5442211a23c6ae421911a734ecd417c27b5f2c00316664e339687f8482712c91d6cf5a0b45209a86187f2be36bee70cd7741dac9c2b65bbccfeb8ec4422a1c3d1477d744f32c720ee8917732895d9e9b835e4b0e79b8dd1324ca5bf2612491c5e1935e2993ba2c241db3215bb4696d9e93d1c50e30de5b2d4ee31e531bc9a30a0861bbe79574be949e6ad801a6d48eefa5f0a7a39e38a266cc862d21a9b82ac6e2550630dfc8f68d3e6673a29d9442299400d35a452b79bf4519b4f262712c9026aa481d1a544f45e36dd619a482412091ab4cb55d2ffc63e7d0346076a9c2121f533c8e577373750c30cc7e518c4d79d7ebdd70235cad08a6ed54dadf192bce0173ca00619acf2b9a8adede9e699482459630ca7526abc3b3eee2a67229108e171811a62585367b6eff83795471389044843a046186a0ff295bff383ec7822e46a802169969fa2e9941a1eacf10533884a6b1a936a78c1e4b963e474de1c6e6e8d2edca55c2dc99a03e7a9cf0ecaaa94260140088777d7b99223d7e9038020d8a2716e77767d7a010010d21a3ae36b50f1a23e00fca0b41a5d2b45f5491301c007fda6785f54efbe4a01a00727b11984cecd3e214e00f0c028ff19457e1c003b70367e48516f5a3da7004007d9d588f1f053a67e03400e30dfcf9e5463b8785a00e020216adb9762caee3903e00625bbe43d1a636d8f050036f82ab35807259b64666b51d4bc4f233e976a74b438fec8749e4c26a1943d8b7308abf68acaa293cf33fea1c5020f4a08d55ee945a9c0e2e8a21de23d744cd7f58af57d739595f00a1d5720b3ed49ba58a8536d2b1ef5711f5308b1e2f03a6b4966ed57a5ab4073cb59daaef065be2aae7c694f93c74a6f31159f5daa66ca4b22f4cb030e549855b3fabac7d42e790aff34f4b37c66eeb79822215c537d6799b9582945ba76ed6412428c680f293aaf4c41563e95ee62f4d59cf1a5eed70d7088c24b3a1a4e79d21cdd42e1a87a34f5dd82e27b95edd11c7141359f38fb0871f2af2334f3030c1e1fc0e1897bc3ac5c6b8d031c9db0f655c5e72ae3774806383861bd55d0367e73b14941706ca2ce493e9eaef8acbd85700087261a6dda33567838cfa74c24d5e394baa4a4580c61c27c15d53327d9bbd7705ce2f91837c74c7ce5862c919ff66a15a19e47fc95382e29f5961b745d644ad41b54a75d4ce7a617c731896cd7da378f86cafa4ba254d1d4cefd866b6622e16ab04d6f49ee8592c7d8010e48b4b9357cca7d8f707c3c7ad676a000872370cfb9e2d6bb7fd894469cf3f7b4937e9f37cf184668395cb5621a4b59049a748c56669732f35da58843fd55c7f7a8d99e7024a29159a6fbe31b8388476eaf8bee381b94aa944370e949e306a5b3641e872118b5fb31fe31e78f7221ac0fe5a2742391b0901e5e08c14188ba368c29a53f76fa3e884b732a2183878228647f0a472090e1b57374931f27e6227000e22497a5a6b3ba848f40c0f10776b3b77a76d0397a1a631038fcd07a4a539d29c7839c0481a30f8690c15407b114dca414c0010e3edc99d352d76aeda8788c2ee0d843e16e84763a391dbcd2c3df7b232b6d281584120b70e4e1b0a2abc252ab8a1ce1c1df1a798f957761f338ee801c9b7b7153fd2b0d871d4aca7412efd2ee31b60e40600b1d38ea60a58ae9f4a5f06ad1e9606b69cd5073f3682b8e39382e22c22ad535bbca020e3994438656d5ac656625088e38f81ae35bc7cb56681f80030ea98cf4244e4f38dee09b87cba46309031c6ec07383f2d24d255310ea00471b32ffcb38d257b35b0a071b584f699b93ce2966d1aca14c22f36f052d3255921ada20e4c6f9186d37bb40c091864f93523233a734631625e040c349aae50c6fb3d9cc83041c67c0336d8e7996355d5d627801871934659ff28d96b34bbd0c8655f691353235e020832754bac650e53ed9eeec0c0f2516708821b5d1ccff2c969caec3709e52d6f1d3636473c0906dcc5e7e85bf90ce7d67af29b5d6a1177078c18aa25974b2d7aa8e71014717d6ae645fb321655365030e2e9862494fa6ad8465b8706ca196efa063a7560e38b470f0943cdaa51a1b91e2c842d66d72747b909e298585e7d4b4daed5d18e9b982ada234b52a9dce555bc18ff9f4d7ccf2018e2a243fcf3f7395f69b4d85734eb79eda4d5b8f050738a6609e7edcaadceb9c940738a4d0fe08cb4afdd32d970c7044e11d7deb3d5642055d82c21aa33afd6c4cdb980b8e272ceba9794c8456131e1c4ee8a4e708df583a3cfd389ac0752ee5417433c50dc2c104fcaa6d2dcaa99a3105192244008c6309958c9b6a2133b5efd3001c4a282c8e1821633a20470374b00047121ed3a274fd77d44c1f1292325a2e75e47184ace4d229cd6b3d2b71186119fdd7a52be8ad2ee128829935b8e78d102696c741044484b264b1992e9c7608a68c8b6df716ba3f1742299c38cbaf943265078e205c41e3c6754ce300424a97cc49df54d5c71c8e1f305a6acfb7837c51693070f8201546988593e34105d94422f1a13e44080970f4a00d9b0b9673fa205fc5c103449e7dda12d2b4ef1bf2435941d0011c3b3876c6e0e12b7ad484f13d74e067d9a0d725e441be90008e1c6c1edf9737cda64ab11e3870e075ded8f05015ab4e3738a8acd1ac3f85c306a50c13ee4976ae6768466a71ec15397fb246cc43b428a6990baaefdc633b0c189905df9dacf2f35e7a8b6f31220b3d4467d93855e527732181915814c47c8a5a5284c5961753a794e2cc7ff6158c7e986e8a225798d485f3b4bf1964c709184278fc1869c51d4e36e9fcb13c9d3f6145f24d76a97c12e3493b81c0c82a8c1b0bba22b60c8ca822cfea5fa664ea9c7d273b3a8806b61849c5f515a2fd9eaac3694346506174ef12299ebdf4ef491030464eb15f45f3f46eb22e89bde8a142464ca15eb95890b92d60a414ece6cb568d921f9e4d24921d41bc3508173972e8f0c208290c15748b7e65b1bc9f8944122488f3f842bd90486c6414fd9de8ac290633fdd88e178c88829141c9b92565da923e91481c30120a63fd5652ed57e67282a2d7ff1067329527ddfb61e4138eb8cf962c671b99b6c90e8924c888272a99e292558c1fcfe3914ed4debe163448d15973f2430312c90f205f8c70c22043cc7acd3dcb2ec1c8261e0be23b44c3f62f4413088b39eb6f86f6aa2018c9447749e79bf0cd041356acaef5ff104760e41258ec24c48b6ef94aff700ff488254eee9595c1de8944d2398604f1090f510ce468401f462a61e7a04b4b5e87a86c0ac9d132ec304209f773258ddbdaa1e774408e064c22f1ada4f156f40a189144e3b1637ac5dab5e84e2492914874b1a7b52a5dca9b3fe13164c70e0de838a6c450c208245266ead729da3cb890482430f2883473723b114d96325d801c4d01024461c411a6d1ba249406471a9158bcf670cd0b30842c1842249234c208ccf57b75c465b0fb7c641169653c91c1c62d962564471451fe9e8add59233dbb238940c6b739d99b53ebeb101841846b67f52694aead914e28307208e42ce64a662987eb0c9106b5f669d959f47d84c410c2482152962a8b6dce65ae56054608517cb9ec7b7bafa29b89440281914134aa7f317ce7ce887d44106a4af98dd11dcfa5c04820bc9449995bd29a43894600612e7baf542aad66fe47fea0ed85c6668a2362d9442219c1881fca8beda2ae3ffdccee037a33e65dbe3e4b96151f0cca42ef8d1eff98973d9cf1f2ed060bb9714c3db829c798d2dbb92c4b528ce4e1b078d5dbd4ba16251eee374bc2e363ce5cfb0e2561fdff6bf142e8ec6030b7d0b2d219c4ca7530343b5c7af58ce2321d2c0d9e2e2d2be8d0e2e4012373f867776e3df7b389d2881c585321eadf979138d4392f5e0a699b221a3868a5b552df9e9c5166d51b5cf92473663a8352b98f1137e839c4d4d9e55d5b6ca40df6a665c91355da2c580a1bee8ba91d634e18236b7873df7857decfbe5730a286f3c50b4fa1c4cc5db8d290c78e6fe80ad3ae1f0dc8870b2eb2e3c57bd21846ceb0fb9e6acb397fc5e698c19339fc5db63315635019acaa24f6534acb2573322c624573f66f528db5c6d0c77c9bf4c85ce8696270a4a70afe39588739151e35120653ccd72c5d3cc6c777142f8c808153a52f737f27bfd9c060e40bce98b2f0624ac6acd50ba54c26f34e737d69fe08235d28f3f87ca853f162295c38e8d367df7ed577d2912d60d749a70cbafb2eea03c8f30823c8102d7cf1fe41792e25c3833a3a9003c8901f1498a184912c9429a5ddb85ff236e61dc841011d437e8031f100f7f031820594ce4c4d59ae767621ce43d0c815bedc8e9e72b84c4faf157097b11099ff2a7dee050f1f3e9425922160600047aaf099c9d21e44a6cc1a9f1480002354b8fd62b01436275b1933b0e38b91299434a5aa17fdda9ec72a5240e5bda76a9507535e14d6adbc3ccb6d512c1d818231a3540e3aa39ad9cf63e409a88f75a153ed497dab941127e4a12dae494f279a3310469a50a7991d296a33b633019527561fb31c598276fba336a845cf628e28c1b8f1245646fac9118e240129a32d167f9a63902f308204846d6ad12963f9091108468ee0c59ad8928d16679911239c6448b90d9f6360a408beba6e95e66b9fcb6e314204b42c06a95b298fd2e0c8103cafe0fd97eae2cc234230c5cc792d63efee974682b0c6160f1af3a58b69331122e4022340d0d26c5cefd9dc0a1f0d8cfca05babb852593be99e273b763c400706723c2007173a74c460c407bcc512fa82cca58573a4078d4e9fe2b2a7d35b7430c2833b7466cc7096a2ee144422d931b203b48e182163c98e8610074674c079a655ce49058b8f0b61240798ec529bf2b955d9e1058ba07fb8070a6081111cac9a84ac9b7c3748acc2ac5f675e65cb880dacca9b31987f32ff522dbaed3cd3f7dfc9727e74e0062d16bd61af926d7dd8cf64073b088604f116ac8075c2801bb3a83d841499844c4d8511840b05dc90c5e3bf62399fc1f37c317870231689d09933661326f7770e6ec002216352cb6f6336c66fbc42d16e3193bcac2fe2de70859d3769c94e7f5a74a315cdc6de185b5438b5d6e4062b50377abeb336a6fd7c136eac222d53496cc56b1bf10d5554f2b42d0619aebbf9106ea4222d324acf858fc8893750d1c9d1a93a543637ddf0e81f7ae314a5b7e0be9a6b53983c87d95817117d5d29d8d49a3f25b356f595145e7656544f723da74c821ba3f874d6383262314b8a44f1a7b0164bf77bbef885c2a05fe7f584e764958122bf8a23f386e70d727ea2b1ca71518454b994efc10d4fb0597f9ea2668ff194dd7aa31375d7e6a798f33dfbf9c303373871b0cd3e7bf51c5fab4d20b656ed35b386a659135bd0539562ce9f37ae1b99c0f3535edff7a951421389e4062652224a9c68707900e9c98d4bb85e9f15fee9bb49fce38625f0eb204dab3a66dd180f207da31295ca20d7e28b65985c20e00625fc4e2f76a1cc63d0e88d49a05489d33d5ef1d5441f02040446b821093f48d5d2d531bc9e68801b91d04c88cc3988d8a41f24cced29ae63768f50e4fbfcaca8af3aa123d81cd747c798694462f274471b112a5746543a6bf6938692b5d787de5884f1ccb30895945595ae0537146186ee9bc88968c57823119eb8e839019169a82453d350200c8642813018000480016cb70e024311083038402210486412b98438dc03140000473e2864442c2a281a1891c802a140200c8643e2501808a2200c022986e36018f55a3a22b82f43ae5dbca71268b9cc2a15d6a34abc8c19ac83b95506b158cd0d2976af9a5562ac8a642de6656cbdf5352db24d31261d3b12273c345cf9c1ccd6314ff7b47bc58a3130dd66de9e9f39e6135c31317d4fdf3158f7a5cba86d7b91e12ac1cb5c598c74ff4f4936d07167d28fa17b0c3780ea0d01d8e7f77f51bbccd9d5b7bd982fdec4fab67d7e47316f6f448c8787f60128d530f8691b520bbf11c168ed691ca7c74c03f1e17ed8ff1590c54c191b68141141c287f1f193b847ec4fc6cc664d1b4b145dafdcf7bc9cb40a3d9080cd24c1caaa47153d6e7302c8adb1b75b026a2ba42069038e352e2ac4c1c6cabb09d05b1784452d07e50f31dad791507b0571a6897bc362dc359c428a7ee17fed45f533efdfa14c6103e0b9229c8447b97008f148dc81ddaef52ee920732ec76c287d7cdd877245f03fda5442fdb045b3b4977fcb9abb1cf3b44f0c7c2333b7b62893f270b2d558de54029c7426d3bc7b89a6c347da55dca66822dfac2a1b868081542e5bfd6a22deaee2f6e52cf9ae99192592e440074fa97fbe1b1571b7c3be3ae4ce084d8fe0a94429b2b6c1240d9198c8b668b18f5f0fb491daedf5c0fbe6c3c38b326d740f318045ec911a8ae4a9dbb2849c01301dbac371f38edc8131fb215b3266d16fc33d1ab5e2c8b47438738ff3986aeec5f8f2157f1bfabb953ea05831df8c85eb895a42a5c42a44d1f6676b93f8e619461593ea85be5a256605eea3067207fdc74e66c98f5f71a423ce6bd7597cb3989519a2ffab9794b4a7d55731de31e080fb31b85d8f81101a4a297ab56ccabbb43fa4a50dedffff509ebc72be295e97d5f770de337ad22823fa6dfc1ab94bc8194f5e9c59dc7da4f1e6d0cb608146fe0e5fc04e011bba8c90224279e91523d4ae2ad9b1221c238bf7b048dc23981b52f43862fcccd04a34747cd06d3452aa40be622b53f3dc1d7cf4350cb8978ded2892d9dc0ebbf8a1feecc9d7ad32261dd0283704003c9a9434853a25f72fb298fc220c2d39c54826545012412ce4c80c3ab0aebe8517bb797ea5252b29a032a8f6fc0bd88d6886dc310a714310a157a36e969e5adeff60a171c91b6ce2ef9c19fed218bf5f19acaaa9d863512b4112e0bfe1922662deeb6d3afa92e6d1543244fce7e7d04b683cf18f1525a5ab773409ac74af7684073bfa8dfa3587af11b84d6b484533785d49595b8d61f13b152b5b9743660081d61d314a91a8e9a55a75e262d07918312a78da14ac96b9d14d0a0d5efc84bc5ef4ebd42b5b29ebf82fa7c6358d3fdcb21edec31cb291da30bb6ff127710dc00987bc28d7e99aae2e585a28709c5bd470eacd5add88015436da1ef14965f756c02b23bab2811d22bb154b8e5a42d7417f1c235bd169333288060e0ee73fe5b370f0cc6874514028da39a82d338f456ce2d68aa9d96f8a2aac310d95b41a6a63f2db42e16720145c02f4e49566ac15c785b5263c529f82d2207c39d0994f0961f317ca084163e82c2e31fc4fdd06570e3fd5aa7a01dac5b6933885a7a0c127b495904239630b614b02ba3ba1c6f14cb743c0731de6d91d6ee322805801cfc78e1c1446d7713a9ea95821b93c815df9386ee691f7c141ec9209609ee1f2aab20d5e855b260924f54e00f854038d40a43ec0c8134cfd12133a31c991d9dca535e6761d97ec0969ca034718eecaabca40c9c4d4e8ed042c87d6aa9345d7c4ab4bed01be928c2ff628284b4dac36db1c841654d7ce892376ac43373bb7b7c2ae162ba2f5ed5013732b08efb32f394d85d395e3ef94b9272f20b64399c5770b29fd38f68165dd538c26de40ebd3b62c0b2acc8b34514053a64a96769eabcb600aa3be87dcc74507010187502206a2516d62fc6cf060c4f5f2e5f31270daeb20bd13ce536cf989fd3f2a2da60852c701688a22503f4465af6072970f2e2c5578bfcefcfefa6e57f72748c59b1d0ee5569614f6df95b09cd42584d94a14b55975d44d668a68f7bd36a44e46733aff137ae0a807f07049ac44ee016636ab0b396d2b0d211468725b6933c62f5b62aa5f4d4738345b4426005fcc5041d1dab64b5295c58c2261189ecf8d2ddacf192351c5558ad98208b47880fd17600df70d40969e61d273b71ed119089f9fe9d44a57648b63658f9011839686fb1a485aca8c244a0d0c0b4a15c8955e6cf2bb1b78c7058fe3a01a4b830abdfeaa651d8886e9ca772867ea0400fe781fed0635c7df830dc95154a46f396e3ab92b06a2f1425a4c83dda2ef23303dce6766a27176cebadcdbfade798eeb9209989941936b447d57cb1036199d04151b93e3dbf98feed4623d5235983b2509b4b5202a9629fc26b0e3864535f58f17b9a4cb5e4876bedad4aaef3454e89cf0caf4e51a88d3b9553619c2c86544444d00b29a0143a3b3b6d10350f3688461d856b141d69514bbbc2da3654e3f0681eb899c2f82c3d6f440078889e991669019d6501425714f8dd10ba2be09cea3a917b986fee27f0830e6a5a7bf0e2d1a6128e1354a47ec9bce3003851ad4397b0fe6af908e8410bd7a3c466392a75809008e9d94c2a14feb6224c16732748c4b3bf20ef766567e2b2cdc2647f8c6d48f6d386222e24fd52e11de77736e36d8d81aea87ca5fb034d92db199709845353574fd48adc095f36cdce4171212ea8f0ad3f8c6d1083f2de90e1724ed6ba4dcf4d607c6b3f16f2e5bec8c11ee57adf2a6a03c09226fa9da2c62627ee85deac4391d8fd757ea385d3d5f1f6ff1171ee51c2dbfc059c7b7e3488b291cb8919cdcb6050c47f29b8c2827e83dd0f0a1ad8680daeba0220a4650bb1ac6071c0632a002e29e0662379e74d27da3c7fd9ddbb8302a30a0d59dd5267a990231ff4ae81bea8c6f0c35f6dbdafa7eaab36d9afdeb193f5e6a26f6dbb9fc076c684bdb5c5abece7c164e60a2e982b6e500fc188832585f00282b1c0eded5e8eccadd01eecdbfa415f81f867d8d8000e6ce7587cef5e9cb07f5a0514d18e22d0dfdf79830eb4d590608d3ae60be56d0ecc09fe72cc3973aa4c532b91242b4b08f82842173feff9333da9abbd8aa06a26ae8cbcd9c8099235333052d498e91ab65f798827e80485d4a5d57bfe27faf162e569cde3f12d129e6387707764f76a5070382721301389f501a102688699307840e8328beb89f00097c961d586c06471778e3950c4091bc19d654b4ded3fbeecd1152be1a83ef3491284773dac50d7c420d81932986c1301a7f73b07f91ddb7c11ee49073b5bbbc13d870ec6df847eef4eff806f6f8b56cc69807d1f06fcffac1a5d2b3fd1fa76856218b9a7672bf5707104d2e69ea7d79fcdb69b251091e30554cf378d40e2e456e0ecf0761c2514392ad1e2e466d6b2d0b765f30ae11085b42f53bdf23e7ba81c968659a2c76372bfe0912b7a74b0106af1c3f97c79250d2a66077847a77ac904e966177928db194d3ea09f7da48943a881b3369887e86490132be1b0d88bc0aa1ae8a5bd4915d0a6766b23761c21a4235b3f210e4b48a8200cd1654ca769fa693b1c1c9494c956000b4b193a4d2967b8f0b4cb1380cabe1192e76d2ad9ab5a31950c64cac6b825179bd754647a349f98a2172f7afc29750a2fbb3912be9addfa2da9146bc6da9dbbcdf625fcd24521a2402648ee7fa457b19347195c31fb80c7b380f5528b1431d4900277edca969ea285f388ac83ae00fce4fe365b809546a8bdfe56456dccf71eaad0d8e346605cd6c104ac36c860f50e12c3d5a1c8464815899ab657800ac66f049ee534707bec0ad8abc43587c8b41b7543365846f038f5f0aa20c2c216305505b61bcafe0107e757ece96b0e3d215ca80ab07d30c56670d01b33fc4f9b607bc1c36788ba3a795bef4a0e7f44b52d381a4b14e320c74f15cd742911d475e92219211ae4d8bdf48749f2acd7f90874ade6c1ce17b0b85ff219ad5aa3556f13191f74d6a3951ecbefc2dc2b0955d60e194d869a53e429791a057df7dc29df2a715829d670394d884c6ba889d89574674daab99089405703ab341031331a25a3a743cae0b2bab86287a955e300614c662cb118433e7851314e094b0e32bbe0ba51fe5f8b81ac249cbb03c189c234047d09034e6eda6c1b156928c19d037ce9aa06592a9629452ce7ed26a84d5057fb48129517869f61aef17624ef6140e7e5b5c44127d34055d24227f0267270d99a64ee321ae9a1166974b269ee051971a4a1de8ff3875ba8437ebc4f17fcd411d419fd60ab7407a9d65e8d1bfefc122f5ed71377a1a3f0c64576466694b4a2ec4104f082db448fe7401886804858035553a56db88b723d705704005ada7677db66996ed2017bb071c7b155036f5b7dd02b77aeb1bbd2772104cc3ea0e654a4aa574345e18ed649614a9b6f9164f60f7f6123afe3ce6db5dde8ca623f6891e015b47511fa755249799cf5111c3a9ab48309800572690bd0f8fab7facbb4c3b7666fea9fbc36b3e60196ed3e6772bf163a9a3586b588efe51d964868db3c3a9dc5ff985bfa730035ff9d1bf80e3788fe1aff81c3424ebc537e4a742f5a7ea764382dff8530f8a0d7809bd93b4647c6be9d05f5544efc50197b407aa98ffc5f0cfee6119fd8181fecc962dea0adf6e58ad090a31120cbb23b397d2ee03404e0ff5b6190fd3b3ee66e4ab9c8667ea1883f327eed3fae81f04def75442fb95d6617aa293c273dbceade4b3d8e9eb0fda3c94a61423828de86c51cb41b769680826a0c7cd248bd7084ed33e52976a9c232585d742e7f449829de0387438e896275ba6309710ebc37e993d110f9f8ae24ec54f30103f3c7cd1edf2f5ba5028e1d50c5afe8596f4eefc1af0cceeefdbd9cf97e6560437a500fdba6794ed21fa333d74f5edc8ecf3becb305eecbed5dad5c4ccd358b2942c345e904be26ac6763a2ad1396984c88698f571620ab9aa6a27bc4e7630ce196d450a1739c006bbb106dfe3c01e902742f44cc229b6b070354a7c727de94125ad2eb6ac67271ade35d2e13d984453fcea56336f58c7c67b1d63b2865d05e604e2418ef48896b0c0ae10541f08622f292f37b4e9a38587e471fbd532003da29d32169a4098a0957cd15421035cd513a45108853f6253504899db865ad2486e537b2264f2e18079acf6c2a851da91decb5942ead463f363cdd2592916f67c829dd8aba2f32b2efcc5fe1487fb95e7506079f7fb50d96c7596167468e3916d05c5032a7863936cdc08690cdbf2c5dd386380e8cbce63fa4d46b9953d4c8d3a23561ef1b10d82810c8a73091e4a9f5f13405fed85067b16d2a5c736c86efc66a3fefce9a31785432a433e5e7de0d4ae5f5c644b120e491ce337e717462a13ad3d573c4fd2f7069540c4327ee841f4441735154fdd3236c8848169e7c02acc59f494da3a10a472192f209c7258abbfb41f3b49be311f0e9e596a74cec0f2bc1538ce73ff7d79da816581dd4d7bb23bbd43daad333416b20089f39ca812cb35a1bdf2520f00a20b073cc1830e472b7fcb7d34451f6abb608e58902b981e69c0a12f5c2ac4cda77e56991097e24c237f27bc7fe4b24ddaf3dc499878eac221e4ac014679879cb660e365a7d0ea295eae3f8393a55447fb3cb29a4d77c7b1ed6cb7b2c5ca1e83e058211bead3388afc0e250391d8e991f0a8ceda3048eb7d8235ffbd3076d07bf5b29718897c9e696c643d3bb9f705f7364cf5b25062ddb0d8460dd890d4d6cf53551c3f6775231e5d0d077b9babc91996ef6342a3f38c35d906aa65b468c52b30ce6efd7defe934ce0b7e55c147f75c7e00ec64e62e625ad8dd39ad9a871138a849a208269b1eb911fd7ab5ab2941a9508a576a391a1f5845bc5077ff59460ea5550e0824344c879009261a16f2ad63b2e918387b9ceb033818e38eb0fe1a89e708bd533f5d0267f8de57b216d9f11f90877c1ab1caf238a21b3a93ff3e4ae941c969077c2c74a9113e4766928bb9541b93c22c15906a2c6e2df0e8e19f3f9bb3bfd9313a081c6c1d72685ef8188b4871036c52fb881dcc73cf0712992a919e0343c7c14432be73c04cd829e01f36011c16e7a05772d516c745949e4096baa7e847db0906440757b07b9c9e1a118c4fb6cfe111aea6cff111934866e90487a0d53ea95489429fd995d05001239296dd5db381973317292ed575c5e83d148d38ff3cf4dd880948a182acff413fc9003944721d0eeba348b7575b869b7d71adb86dc1e71894e0a303bf7a9b2551d22973a8ec306173a14691b5646c69817883836218beff2bf883919c84f3ed1be6b27c33a08d102f0f22a827b540f3138d6ac3a5aba8fcf15f5741cd717e7153c68a6e18e2d6ea0861419a97272b250d1897f6bfbed5190155a0ad8252606a533c278a313f2f5b44500484bea18f942ddba59cb4049fb723ca9d36fe829fce0893cf0cd0376553284b5c19850c9e70a03eb6a1ced860371329299c5fbf5cbc830cde709545e6f3254689456628cbd21f6ede4d83b6500711fdb1c8c6b9e6c0b48425e7c458ced45b5ac6248a2c04619c7acb2f12dfb232ef9e278d819a8fb6cdfb2ac0e430bb3f933a3623b1a040c0c00719763107a6a3d98e4964eeab71957fb66cb93064e0a9faf2057f2e1b8a83408cb4dcfe6e8baaf8f3009783b71b9aa7de947db926daa21347e4c9079d0a4dd34c4d9c6448dddf7445e908d8874199a16787c06aa3c4a46910a5c100927d44e671f4220e0c55b6ce2f170c00cfac029c769c52a1f7df00312a8784f1cfa181d8420a237147737fa138c5882b42438f4811943728574777f8a30615832502aafaa821cf946ffc6cb9e4898ff0c635d9ad334ddffaeb7ab0efa60f6f3ab3f5ff5a33c570a0b40c048c32b8007affa7c6504016f7084245c1710b2c98e900141e4fab3cd24687239a1d37e17cb8f1a5eb74e8f48fe4459643ac3c689e7d417872c024bfe0131f33a08608bf9c1bc501fac9b87b429fbd311b1644ad82dfc51ff0fa58c17fbaba745ddb9d484ed4b83586e6e12603eef5d992d5f8fa568d19073b57e0439f4f17baaabd0fc5d32f01c53e9d91567ffb7b356f8db253ab3d17a771f04a1db8019c47eab09bfb772c71719f8c55e55eb19a96dee67cde2e03ae68d44c8cda89c74b955f50959bfb154696a6ecc7e980ab2e71ee2c1f81eb961badbe8f1ad111717ade6204b1a05f3da310358b07de28861bc20485fc0448907b93865a78cf60d71872322606794bb3f510d71e8615067c7ab10f1081ebaa532536084c1f28bb59f21f6540ca111d60186ff3cfa074027ae0455666a6c8a7db1d2e13dacb66fc34e44fcd9b88b6cfedd5c0f40eee292c6dc5750e339e6951107aaf7d088a4db46efda554cdda905945904277e847b21c61ad58d23016b2cffae37c71d73e0fc225ea83892a0b85b26e3e03622731c6f6ac1edd104ed9d21fb1e165cb79c99844621777e5b4abd674c5d49a718ef497811104974ae50f6edfe8f69633712187f665b73cfc923974238345737958de68267b402cac8b84bde75c37da368e0ed16f2f3385cbc7ef9bb0c16d33a54dc084daf4ab0629621dbcf0af1fbf7559fbc38fd7be85d9c6edb840ebaf11e6092d140226be5a0e469e7904f34c5f906bbd8b7907eb4fae2c5d691a602d6be74e86e51cceb9153e13bfa31ef4b7a1ee498dc0a8829c6ca3df32194b5a3126492755520f3ecce0eab42987157d4f7d425f57627c6fe85e8bed6f012eb7bba74a5b3dc8d668f0f38d3b56f418062e7143b3e38168e859003c352bc31294a2f1c4fc3ac0985ae9c3f9d245c4edaa500c0cb4d021a720e66a07479632cf8869b74753e9a7bf6fa9515f409a1d1835a02b3efb3c9b32210a636544b24489974558d27b1e81d333fa774c0f2720fb5f94cd6012a4c15fb15e16fb6bdebc07fb490d65a5fbf936a5102a895c65a5b26a0175bd2d656dbc953fcca0138c81515f251b9fa81332311309d6f85d81d21e1727531b52f4fde3ab97cc173f27f38db5663f980e3298300aea043a8b280ad4b67d954b082da0157f44db4648c94f9ae8e54446f6aeed12caca2837192bc1de789ce164692be38bce4eb79ddf8dba56333419ee4c0a716e053f2f00a18015513c85329f1a0b02b5ab488d9f336ab095819e03fed8cad9e8c13fd1f0bcff4b68cfb774008843f6afbd91315c151e92022ae1e3c9363878cfad9c96d54d35ac7b9382117d159546b14071f8454ff106b69462cade938a725802ccf566eae1c75020e9480295288c0450aac00a0d129e6b106b5c8a6d3456d78c594fd225711bbdc68615f59d845b44d412b95482976fa2298b070d5520d2fdcd09571d28d316f12df5a325507ec032989d9e4af2484bad7112abd13c79a3eb40197000d357f9341d3e4c3db4a73fe93f47fddc617e44ea3a769aa57046fbe1771a9a7ee11ccb7c2562163a8a1d5ce2ef672e76bf1c86b1e88f064f65591e7a4aea92ee52b2f6be6e633cc0c114a7bf9b15a44838f1a1da333a47eba09cdaf4baae0db433cfa0b939d8483477df9ebebddf43896d5b1336632c89e90b3c9842f59c0247c5b21b0a9d713e0427e381f5ccf0a966bdbb272fca346f32a817e55682cdd486bdc43ae88a62ea7a603b5f14164000fd67c584f9a8a1410507441db55b7f94512d0d432d0b12ce0d2dfc44a7f5d9151e2b2f7223dd0bd8300e694a054579e057de499016483324348a8a9078f26acc666373a279d787036ebdd99eb89d3070049869af47501bdd5dad4f6cc75b47d966318850eaeb40e0fc275db2d8471fc9e4f32892d1140173faac64143cd7150f53d052c0c33119a860d45afdcde02712fa3c817d225cdf6aa6fd2ce39178c90359dd32d008a1568043ab9cea0decb071b9568776e9d8fffdb638ba6ba40faca60ceb36920c9aa31b82974a8959929e712dec327e1460df9c16943ea074c4a13993c011f3e50b4d2720cc2bda1f6715054e36e75710628bae06356855fc6ced18771b9f051c4af12dbb4f386518942a91abccbd5fc8cef9c59c1bd5b361d013e33d00de3e7d4c148639d98ee5085836d24f99c880437aa7ab200e3ac4ce4347db58a2d660cc6b2105d4addd16a7a65823d625e398c4049aa3a2ba0bfec075046982d28e910987f844a1386ea2f90f904565cb6f1bbab21cdb599aee40557cebe1a1a1cba28e93e0f1c060f771c2d263447c4428ec7831badaa519bfe1facc3a8b6eb0a0d1151ef839bb3c43197c197dc3667fd443e62b376fd625b771188bd42532f41b90b885a8cc786e1bdcb8ec328d39c6e56e00ba59b998e838ecbf2557e0061101d29a035778e149b79d680b010789981c52fef99e35080d0700fbd4ebc803e6838f29eb4e78754d78a7220d9dfa0cdb676013093a37072ed8305f56dc0509da371a5a9f977292204f4c10b28bbc90abb6d5def5a054d8c3189b3467e1d36f8cd0850dc4920701a65d72c5eb528b459351957127cf0c9a4985a477c0ac25fa1251e61bc22fa1cddc5b2116908112ac2701d697526fa0c7dd863aec6da0359d82765a11cbe240a5bc30da726c6c9df916b03d419fffdabf47a23ea0b07a7d40fbce3ae92b601fefd147ab9732a464c3c7a1a324604a1360c436fc43079787a89496a7996745a9c82696c4312546e98301fd0be3b535b5d0bc977a9f339de5673013d7ead5e0169ba118327e9174bf4a339226c3330837e277548d4876166afd38b22ac25e445bd4e038ec1863a7fce351d99668ffc96119461e12dedd747f59956be7d90551599cb849486875ddf9a2f69b9b4d3806209f2778ddd369d383166309b579dfb308a67d412506896fcd8cb6ad9e0e8887572da10c1b03272271bef86440aa7f162e19dd08afb03f80b2aa93c95717de75a444c4d2928e7969f07cda9780e713038e4c84003b66f5280a4e74198d34cf741906eac3d30e1ceb360ffbdeb2f60e9d3fb17c045b12e0541dfe18522ac08392e62acb6d80855df53591795a798490648993396f2e6c6452455618b0492f867d5abe79a6ea06d14e474c5ae45287bbdd0c0bfa8af29f5c129e06bf3c9ea9749689f13585fdcbfee8344ea4bf0f907aee93a8d795b4cbfd9f0472771360da3b9f459c6e36650b115d7a9b7bb7c8bcb321639e92b59d7d1543a865f3cf9d89ff7a2d6234b180ad67006f81102c81dc223190623504dab2867a867cc4317053a2059765ddf8acdd07d56fb426e864ab2c251157279925840886053991525d2d879e9412464505604bd0b06d49323d2c61559b6a0ec566288678e5e372d7272e367161f34ce3a2b38d7415c6d026e3afd485d45f91498d1e8998039efbf299c7a48fcd40a8147b9781009b3a323a8d9d48c9251dee5a0705ccaab123b6fe95b1b746aae00bdb6f08c665ce52da089fc51696eb95a9967cc4551268daa4c25515fc0be8baa0585ff8ad0bb890c51ba75cf4bbff2fdedb85d2bae8152e4cd74562b8a0bb2ddc5506fabe185a17bcc285e9ba480c1774f785bbba40df1743eb8257b8305d1711435eec8383092ca017eccac27ac808ad0b5a71e17a5f20a68bb9db161ec177fa76f02fd4f58bee7561342e626d1641d558c56af71749275d04393d91f30d171bcb85082f7bcfebcf3d9ea8306673ed9e495b89db752614d2573bb764dad88a2542344204239268cf437608e9bc9a2014435069fe15879d114001b37196492111303e6d5d4417604644cafad3eaeb3e75e4fba6601b21f8e8b652df4e38fb15ae39b0548c86993cf82f254e15805cf8c41b9975798f8dc8fdb9eea3136496d048033c847ed9d5bf212fb8a7d6c3c328d1de6c1625675332a28c3c2fb0a55136cf5d2b76da4b6bf63ff350c14d3e44f707326175495637b745c01a5c57ac51aebb52997da78f414d8874d5ea1e9bbd0a3e4f1a36df0e3872fc85654ee6e0cfdf002c1b75d883c409c9e85aeb44e549b5249f2287fb82539e3243025b9f70c51bf7a9baf93c3909a8a4e02987019a220d54a79fd2a457a46ae595720baee444d7e2ed5ac8345f3a808f913724f83c424d9b49c5a95d6874bcb7af00349f0dbf4e873b3eef330b47f84fc686c117846401216bd9b661f5ec8de7d5fe3f9341a3413d2416f9845a8840ce597cc533710fc998556c50d86245807b25eaa6d7ee46572a2141c6b8ae521aff302dc48bbdff0098791b4fe033e615ae22f663cec678ac16496b61023152cc3c0a46e619cf153a2b4b0c1b0d1f44111c8529c5dac42c360dc5d0c0e4c77625138ba858ae7fbb79d5aa9cbb33f3f630056a809d9ad6005ad3657549b4c4247997ef3d72b5c45704ef1713d09d7c85ed3b9ee5c3044868f9b4618791ba4c6b6ca0a5f65ece7a95dfebbd257641e5ec3971f320e4acb4ee12dfc01a1aa4cb77e5b050a7d6200cd87425398874041706c14e7b630e3aee60db939f2b355004afa8c53ae1551896df666efbe0b9cbe6c3dda3061a474ab133a8a2a1ac83526f7cbd4a3770c345106d2889b895e4525f2c004b2c68c656e29f5fbfb833acfe543591be6a33ef7ff2fdb9ead4a6bd4c9d2a7cb131d9016f9f46f979f2085e965883252f6966a5e6a4fa41aa8f23002e63906c14fd5286a186aaa6a642a2b819dd71973e4ec0de17795e85f73b45ff091c44f6adeeda66e0fbbe01329ddf45587db0ddb7061c7d670ec13f133061d4cd8808d3b0902a7bc891da82faa4a511ededc156ffac15811257b77f86f9e29462e59b6fae231d6b5b511772b9e6ba65c11e969584c3783bcc7ddeff2cc7e6f06553ce6530da90048b16b6e615ed08ba3ee85637355d1138021496bbd946581dc092350a79d7087461744f8eab463c8c9ba7a034d13fd5a1a42405ae5404ac8101cf3c8a80c0bb3468e53e7db3f072ea836240033b03dd7886914de378cc4d6d1669dcb35f8a215b79ffd2b1dcc3c29a430291680517b5a1f73b3040530cfee4b650095037c8e5f1d4f10de3257df082968282afee37a4f006a28d0fa9624ca8253d7e083a9d7876c22c429c0e652e88d9c86a5d94a1f54ea9f49ba08bf95004dd80e6f1afe086d5231794e022fdd18e3f3c1155765965e6fd99de72f68d7469caa3620d3605e06c0512cf60d1ed8b2b30ba22bee647d93174adbbb84e967dcc414b0c94d08a99a8ffc04a4c44f3651cf4fece613cbb326a1ffd04db6c000615a1f800b3ac81d058096246ad4a211881bd11a15ca8c9e0c781be74cd4020f4081e1305b105f16346d6ca95cfeca8e8a63ba80705470a492139ca90c3005b8c8a6e2c0c5218a61682e443c1564ae0c7b17eefbcb1b4a82c52ede363cbcd2cc287550970833bcd597a510b3007236a0f3582923531f29cad75ce01045854b7aeba54adb8ca2745777d5056fea59b53023f36a771514bc2518e3a8f7cc6b3d23359644db8d11af8aec639f731808e0fca73d9e0829d1696f2a5c9fbb19701d76bfb9c7682e95b0d469123586288b1842c83823b2478509223930203c70b7c5b704d551e66fdea6ddd096e091b630874b3387c83f736b2518484be0f4df82d32c2a4c71abd0361070043c15c6120d84ef54e8f89470abc5c1110bb27d781c4f16b42a090307e601d00ad6a3012b87c5cdec65c3974eb64752f996f1e9c789d5d7c64c4c0ea2610605602245b21518a565b8d0d800979a35eb9342818d0bcf17c2bc0ea9b792d47c2ef40f48a63ce7b1b3a8a31c9c47a46b701121e5244d297d4746849e02fb7ba57c099a7ffc41eaea70d1e5f4bc40f70b70e97cf5a5dcfe1a3d67055e8d354dae42068dff0c8f459077e8b6e31aebeed69b38e3ebafd75596151d9165c7cabc48cd8b0c93f2c379409086d612be43290cf6d2c823cce0e5dff533d106e98deb8dc666b8bbd40461eb6e4abee130a2ed7a3b207e1907199fb56ae11fd2ce3ae58ab2b6bda6a47b59e475ec71804c1bc46f2c4c0b0d0c02dea7baa5d05b3a611657a5fbff7269ecd9bf54fd6cf794f0401e70280db60783e43feaded27f04f55de150410db8faf805cbc1ad787b4f6dd2cb0821f9c3f557c57eac3ebcffecf2fbfb5fc04fba9e6bbe21f7e7fb67f7ef5ade127e84f55df95fee8851f48460306c2f607df4f35df15fff0fbb3fdf3ab6f0d3f417faafa762b6dae66ea19e37b2e54a02b9c5bed80d240dc751641c09d9783136485a500a22864c8206867f178e211318730da5ba1bcaf775e460c9db596582d6bb6f046f200a74cac9712f29cdba6504e4d52349e2071f5da422b14f1d481b5d10f01bd42046bc5c058fe9a6840771d906424bbb363931b5d8f98bcaf4144f7c6e2378f933719bf616e0d48784e6ac59f7aa790146337878499f48014533a29da2639260e3dcb13f9a2deaf2798d7c5d44351f068f66fe85c51a914b4f33a5d3a4bed81b5f174ffeda4ac01f22472cc7853c82299bac792f7948cd5525d8190617d30c4db126b495036d3fc4fa5446873994c0bbebf446eb6222b777b7e2bf1d8edb2416738983d213af99a4d9b96118d8c418892338c938dedd5b5a0da5af2abcd4708e11d74e73687f6d140c1507cee90ede986852f674b500c4d05f9ff9e3c6aa323d7fa4a6d727e2c69c5b235ad5ad8d21637cf5292d32c88d056ea71d240ae416bff6a1c97b82b2d3d090d92401f5d290e2141958a2648175827906473aa404428acedfed02e2b4ec392954819d4bf45ae13cb41d3dfbf88dcc55c83df699b95a2e74f343c63f3422632bb8c552d62cd5e4c0db302cb7fb7cd593fde94141030e4dc31093e775fec2aaa2bce82d5ae9e9ba0a9d75a6c314b0c8f8a605affeafce1b3024e9bcd0314d3cfa5e7f115b39fb4f677d57ac171ef68b59e4be3f2cb67cc602e4c9c4d872590eaec7717dbcaecccac3b88bcba497a38a1bb18933f682ef5b9d37be821f04e1096a628e9e4ce0b023096ec61ebcb79786acbba2afee0002ac1a180148aa0e9193efe2304cf5e58710cd1b47d51e5b6973d9ed1a8266764b3e443c846d75c9dd61197c7afc36573e2fe69db4b0003a77069bb9dd4ba41ffd56349370646881cf75a5d9e8fe783ce940f9503011d7d278850a148e88360558164157ad8b40c0de09e397300f86749b49fc340d552de6a1ade937867ef9441b9b7cc5fd737dae48c6a720d7111818f865166c679f21bb4a31fad8f0049e8f568165257e34f89505f63b20b38c1967a10f1d35667b78a35b6de731ed74cab942789c5c416c079dc1bdf966908e54aad0de606b1974066bf0e56a3734478281e7d5d8f30daa0e801e55ef984c03cb69b27cd2af0f397255f3063199d63279a85bf9f37726c1e7120bc555e8105b410a42c8dbd600b901377d04613f797faff7ea8e12d348f70c19211cdf51d43d5cb0147e9940abec0c9408ca893ac68014adcaec54de740919775412f22c136c3454061b1d20b725e5515cc0707fa2210cb6069eff7f8e3133ff10b7143f642d10118e7b7840ffbd5c356828c7dec7943e82c89af4f828bfbc3ee487a36fa859c938af6899438daf8e8a4c7578fcb41797fa026ebbca4b5bffa9fcd0f9ca965df1cb4bacf60d1ec4024ce8293cc34b0a675cf4ec44a1b08de6d16155143064041c33dee2310156b45776cf0af818092cc67de9ddafcab8f997ade22d2e54c8b5de20f989be9ecdbc22ab7207dd98cc604da26ac77a4406c4a53816cb6384fbe414333dc6c16c84ce33cf46b4fc9002b75550bbfc638c1716012bd571801e5daa5f99decceaea4c44ccbbd2f997c10e0ae1fd46aca669a255b0001cf750434ae733085c11d9e5e7401f2ec308b47d8820facefceeac2a9e6cd4257b81f8b1af906e914bafc62a8c96c084cce44ee62a06c9235f85fa0b48b3e419094d7d62ffe01de7e2f7d0bb0a0940185c7045d9b12be452c53174076668c1a02a468ee454d911798bba0db597343880557511d9dbe9d8698fb5cd70ef91275e9e8f9cdbd1b1fc19c10fb8cd4f26b062aa4d61b6d30662566ddfde1775bc1ede7781da3a3d271c015d1629f23b1449013b9b11a0cc1f5ff453ca569738429a47fac910394c6bd1ad8362f1728df2689a457140127b7036beaa58f4530cd9bd330e72575c2f112c17a071e375f72bc81036c185b19a6ffd6eca105ac447959caeaf1e5d14859d1ce1d2f7ffe820b287f25a45346054aa7a96e136885062ca5a39865317d34858c1bfe873715552280a0f1f0d9bde0d467df5fdc2ec65338a9f31d1b0c395a64ee27a5e3314449a0c210353d9a7273ad6e1aa16607a15a3ee632b85fa407d62d01d7fdef45ee285ec02b0952c41ba4126e3c21d63eb16096307d95473f214b8f0b405761228f2b75992b59a9a53ebf7502533006eae2b72c0a2e3e645de135f8a77724672c5798a52139fdcc28479b5fb486deb82d0897578eec212b50adb2deb7f6a202f147359c70f5af9f5bc141a54f69bda01436c240dd6d666007c4f47d38ff912b6af3bfa087e494abdc461601a440b5fb154c2b3eccd38eb8b1d2fcc408be04d855e685f40e1afd53e137deb8c4bcbcfaa71541f7452fc596b595c6c576b43ccf09121737d3ea54a7f138113d1ba317677a8f1df6a91b38d81d82ffa3f9fddf42f980298c930c0894666f9e73ef89b6c503d46f39df5944baa4224aa498269d1b31dce11302b5dd7119c2b9817bd86e4a018f036c8d6cf4a75ddb4bfad3afae021c71344b99e1c74441c4377950c7061e601d4efdc60cdfae67461a578fdb29221df53215e9d5427c6efd3b588a8564f114cbb26f7bfdd434cbf1de30dce21686da15df2910244d96be42cf9002b4b0f28e4d295a9543d47487cf27111c6014eeafca61956d1c6167170851db69b7af7a6b581f27ec50d65f5ca8a2f2e969ebf906591b3165f5150b4ae32adb3d1a255d40801ac30008f8efb0559d516f56800f1c4fa080da66ba9ec35a0b57eaf39c1297efb117ab58bb5e24a5a913e5ab7a457e9c48106ebd46d8b1e1ae3c4cfcf9aa35befb50437b327938bf8025e156d20d82f92d7cc5dacf12a8bc4c3d8aa54376821a5e60228e44df0724b253a642addb17d14e9b37f7574a80e12a767558503c868ae3d6315d1b516f8f7c4a4a13002eb4dcd9ec646addaf6f4bc5d6dbf1ed206420cc17aa3ed63c1ffa57788883029224120ce80822386690147d4999ffaa46561b028d296b69cd9b8191b723d543c7e00eeba2763f42a503607bd33f6983e4591e3f7c6d2ac4c3859ab84c8319aa88821c1cec2631da0d1a5d2df4914021dc92d94656ca4fd68e8f11729231cd334589500f3239b862d66edb119cfd98a78a85deced761767122946346ccb6d14f370e4ccea701c56c9e16265d0c5249b341192ac0e118a811b0f34c8fc59c208bd1ee713de7f79f59254772ba5a1bca2efb7e68d1d8d24b78bb6a54d093acbc58e2ad5090cc48da8374cfb9db8458ff5709b180a21870a1c5b7d7bea24b841823ae9a88f5749fb68c1f5fb3cf4612394721988d5533361ea9029ec640681d242fb17051d4a35380a8de7c8dd84d76b04eb106874320c73d4dc8aeb4014e84018b84f273d778b06e9ce3fe88f0508f0bf483ec8ff1b1982f618913d1191b4df06e937a2108b8b3fbd6787f35d69d96a756c3353812b33045b51de6199c86524bc63dd6854022f0ff244f598d6841cd93caddc650a7c1662be7d0600f40aa1f01f62439e93821ba4ba699136b4583fead85397009f43f2da1e4e457d0272c3ee57fbe11392e858dadef7dfd325adffd8a603c8dd274c78b575668415f2dfcc79886497202dfa694f549ae599f9120eb4da9435d9d74632c8879b8bfe9e41184de3dd27f16e4579d4e19125a075d33d4fbc0f00275b32c94f2746466820b145b42f02107dd95e6b1708a64782beccb7e566915de8fd8754b2913b6fd2e2c0b31dcfe258094a82bf6d6d65ef1447827973eb2d807b40c6ff698d4085cc3797bb7906ff481da3bcbd7571fe7809a5d22cdd54212785b25e98defedeba85241fdd18d75b384e776d3ec30eadbfd2b29685023589264cc1a3e9a84b8d683288d606813b672f37db4053345ac02a7d303bb732ba53e9bf9bded254435ea6927f46dda268b6c2158bdfdece5f70e0a46491efb3b1230162d2a3d67542c65a27f80a60edd07b4d342123c3afd983e96ea872c500264fa7f2f4cbd0bef2c3aaf0806808f05e3316e550e6cc9ba51c288a225a38d66aaed65593025827e616f15f3cf3924923e2d296eb1419948983275ec85c0888d92c0876f6076adaee6add28659e93064c88057f201bd6f7151901cb8087892a1af683be0472489350cbfab18c3cca376efda37714e6f40ae4bdb43d01d76b194b52ad31cd91babfaa374ef36dfae10066b509c6215a4b51813825f86f418bb67ea3b424680663f0f76925b3a105c1da5883a64d04f8c5f77c907a30aeb834edd3ca20d6eb46b6b1062be85eccff8e515f0f61d19a061f34c422fd653186ce29257afff671688ba7fc749dfe6e6918826454c6806e947e8321ecbed087cb2055eb6ecf296ddb8c1c63f45d420081edbf67fabbecdfb90c54ae28b508bb5e35bd0c2e3232a2bd38fcaa880b5a9e15e63395e957d1fff0fa6cbf1e0cc4458ad933c71ae0e120528e9450adbb0f393499bf989cae2f9c92d0b574e50f312d0915643cf4606a1969626ba63c15f09e897eaf2992a46501021f8deb7be45f33ea684010aeee3734b5a87ffb30ac130769fd894d4a62753d92e3b9651cd5b265be4815f778a9a25d370c70410d4f260a95d4cfadb587c19e62d7358cd891bc25c41469b25ea8a63239470133aba6c4818e650dda428e186f715a7ad6c7ddd4261c1bb0b9a3f6d81779cf0e52f5d5c3f80a529922cd37e030e3a74db4111459e5d387a4f69e90acd92912e9b0ce805686ddce97cbb7a5a4f7095a9c7133894072b72a54d7702ce0d44b90a3120b4a4d001c0300cc3300cac326c234ddbd6e8d188952949c93ee038ebc46de324a52d534a696d63c6e036420821e4a378700a950a490a6aacd163871b3e7ec440c4177f163dc7bcd9cdd9f65e1c9a4b3dee4495cb252f761b9d3f7bd3b36c6215ef61061b22bb488f8b39ac6f958ca2e9424d515af4945424170b56253f9d8b2da6a57191a6d55151bfd17365b7e8afd2734c1adae2d86296c44c89f89c656b51092dcd0b5a2e25bf545ad852fc5b6cb6a8c8cd2c6a2f8fb34128d5520bcb023d2166bdd372468c0597f93193ccd43108171668c5cba9d66517c647afa8fa54bee8ba2c96f73f5260868e2022ae48c91fa127c534cd3c445a81786b9ac6bfba2c1c0311569c6cc7c5f9d494f2f92a503a5dc7474d5574d2c50b6d326886a75271abc9765f17e5e5fe201f440622a840feb45d764ddb7496532432c7ed53bda645990d22a6f8f46c8b59b23e1f83444a9107e57144c8e64d23aba0a0a4a80104f42a2760438414751032bc68cbdfb11b0639d4d001e47bc0600d91512c5678ceffed85ba5165c75199818e1f3058d961021494951de70722a250ff7fa458c57fd2a5ca8b84227d4288bfc82ccbc146502ce7ee0b97e1ece4693e819ecc353a3dc6634e40443c91f61c3acb66b113c81bd35c6a7b838adfc74a4a1b417cfc58438413f5ef9eb65b5f64138fd07c61a2839a30e78f25343e66cc26cec4d2e6caf8cba24bef59306196cac9a464b71c8b5c42dbf6b1f76cdbb298882514793a8a8bd9bb6fb6248854e2b872eeb2c8b059d347094f4f33bfe81ee2ef491ca6b6f647a9da116a4920466831f4e8244b581689c4c591497bfa20d1bab7ca8858be2cc91f710eb23f0b32f38e684de3fb3f9e8a57488748234cfeea5934be5eda83106144b7ffbad14ea498ac5450504416a1cbae7f1b7be503240508fd3f4e8a28023519f466697551e35469a35f4524118e8f4adde0b2a454933adef8d13c7804494304116de8f822b71f6af7211232fac971cff1d49b8821167490ddeff4774fa7359a0d15d840a4100713bb55f5926d9ed6e1021142a8f3a3756c94381b7510ccf6ba3c2e469917d482c8348cd0d51736323e100944993989bb8ec7542f4500c1f967d6a47eb6ba5cc37f8d1fcfc345fee0bde4223d66df24a303113fb83fa7c58fb6aa9daf3e6cdafaf3e78afdbfcb07ed374fdcf685292514d9c3619ba458c849eb38d203e2b13e73e66c2db946240f6ecc17d37fcf7099c543b5a6e4e7f0280e44ee5096ecb5708b6fb13495ffc1c6693584d03340411142ff2881881d16ae46dfe81c6a456f1288d461d96350ef0fb50a8a081d7c7bed8c499bae0b8f4f43640ecb212fc707b1163e451b88c8217d293c898a77cd12a79f411c1223dd5a92f78bc0a197e3872dfff8f3e059d9610223f20683d078d3d5116e1f97418e33742c226ee8dc73d29bc15bcefd042cd286f45e6acea0b408312d0c44d8e0cf8f8c722f88a6bd5450506020b2864bd88b30999e881a8ef5b278f2ea4577da32104983db5fa583bcba66ea55527ef88881081a3c31a127e4b5e53aa58e17889cc174c9fae55f903164ce0c6da7d590dd9299f40b881b2265b852fb3f95163550508e6740840cc8cd82ce92aa94d7f7d2c8b12263e05a5e2c070b749800056ae450810b72b040c70c44c4b0e7962c3d29a5e605934a1969f0f0e13d7a063710090322cd5afaacbf679a45040ca98d513e75ab291b2d5f28fb83ce1b19553a965ee04ae3e6d7d3d362ce0d43a40b5cfab96c4263c7a033225c685c4cbdfe7a27d39a0a0a8ac81696ad35cbe3626879d2f3d8a10204046e14a1082c10d1c2a785d5bd0c1d19c4ae52c62e44b2b0698d50e66bbae3898532c9a917a408cdaeb0b7fbe6bf8b5640dcc86b0c26caaf3a225558644b7dee0d26f4c9bc00092254d075b4a8d579bfff4c9129a45df46bab9aaf4b9388143a0d6a839c91d32fbd48147e31f35ce924eed24b4241040ad9bc2ce78a58092bd10d9127a01935c3856d7931bb38213f213a6f3099e1924c08224d3057c8742a5eecef4f112654f655253ef62598c3c9f0e8b2945eba1551c2f19470c946464910928cbc4d684ebf15324cd1c1a596f63cc69268bf58ba285a37268a1063a06561c38b966aaeb7d4444831b0d8b3eca89e278410a38c9e4c962edd98f345879061ac7ba2c74e6c3885a1f967134f61df9b6321c1d046cd7438fda52f6601c6b2fc6b1459a641e86018427ec16ba6d816b6745b67437cc107d971346ef567325510d28b841ce5c25c0bc24fbc2021bc68839d9ad0b1b32f864310b28b54e4c70effca78cd87e8e26e49783cb32a17e8bef4b2072584f6e8577e8d105c2c0b4a0b5ef79d840755c82df494724af6ae494d882dd8175f90e1f9927932555050bc47a784d402258488c6f10ad5a71c0ea1453aa716e793946dd99059203fd67a93cce13de87610228b6554e8e082cecb2fe684c402d9e93f474368d9c92a360881456ff7b5310b7a8368f715b88a168d3f9764c79c2bee585ae2267a764c6d05172ee2f344c966b16485a9af57b6258dd14dafc21a17f7fe36c84e9fa90233f5fcd2b0e26b4aa978d4280dcfcdae97172a966ab3187a93f4963b778a4d88fb607795f531a6f05c7a69afdfb447af434a81281db7aabfc283ce4348d1950ce639f6fb7fd2d22364149ea68a51a61d51244e9be89fcc51e583a1586af164182d48516a6b0828d86add2c32b4185ad4423ed1ace6effa967576174f98a9df7b944b48273269e992121e2c4bcf219c787ddeff6f7e6426396413e5d9f96691962ec8708826165d5042f5fafcd6e44c209396dc4645cb1d26fedaf8422ef16edc543a29ad2fd5176289d3ed6bb3bad479ba135289478b673153efbb9c5a28a1668d59f1d2d9a952864c2297ee6e55466d9c4b25a1e81075b359ccdb7a47a24da5e9bb3ba8164da80a12b9db95aed7d8300f570921e4117dbc53eba351f773fd468823f8b4b9ecb3d46be592778d383f752a193c3553653346a0fb93ae6e49778dad558b387facb7fffdd47c50882296e645d9645e17dfa544b0417b7c8c527af3e8218848f39bda52da7c2fe69043b46df539fdb370e3a510432ca92f0f42b39c904228e25eaa0db7a7254d4308b12c568c7510d25fac6e107670696414adf8e4e110412423eb3db3684d1fa19040d8f29bfa837e395b1a01d165b795c54b5a2eae3f1cefc35fbffcf9d244217e58c6e3addbe6217d38db523b34ef495167081ff4ca7b93221a5dec33640f8817b378a63accbac5217a582eb324947bbee0f685e4a156f3f07a2bf9a3da103cac66ee79eba93bb0693dbfb32c3e9b8442ecb0c7855d5668b9538842eac05d6c1cfdf51deec584d021aff1dba0592af5d70999831d5e4a76dc370b4d881c1aa99dd2ce747c939f9038e867ba76445653cfc70b2170b87d5bca709a3b29a987bc218f71326cf00d7111d9f0e1e3e85041881b92de415cbd180f69c3e27d8c7e2d47172d5b851036a47e42951ced396d660db92064b5c7fca76a5d881a5e91df51aa0949832ba7fbe782e6a063060db99c125a4cefc6b543ce70122de9f0e12263d2beb720471642cc806fcecd255eee4b8642cab0ac28ab3af93999b61032d8da314b2ebb2c6b4a17320643af3ce32875cf1f1322063ccfbd864bf74197191286c5d1825cc8ec16d46442c09012b5bfdcf4151fcb902ff8321bc7fb5c36971fe2855e2c5535cf0ffbab8674c1b41a4447f72aad4915c205c63bebcb39fee3694cc816165cfc2066dcc3da16a2854aa919e9a2dd07f543b25009f1593ef5e7ff2885606149c65fb2cff792563de40a188b97e2ceb5755a73270dea49030929b8974b99b672c1adda204146e18712f23454c6a89b82908822e963a2bd7e0d0567e2a2c9d5913bbf9180e217c46f33f3af06924fa86366e7af1e8927166478166f45d5892d83c6203c74fa40c2893b8597965b0e61a3637220d984dd5275caeace2a696a02d5a47a572f274f697320c9c49b94cb27f2b3974a8f0d2498d8f3efb4a938a144967a20b944a6a136a75fa81933492cc1ba7f70f5eb1d757925ce99c49ab21056522c4a543fa75c6ced49185a383fefec4a22fd2ced9e507e24b4fffc2ffaaf680a31245aed7171b1f4ba77f488d7ff05996531cb2a4a890412472022ee64ccd0f2189d2490340219fdf3bc582f8cf8c577cde9c38c46db16f1a64c9be52c9da1ca3c028922fef97c3aefce4ba6c221902442f58d919ad54ae9871161d24efbf2dac9a0bfbf417208eeaad38bf9b2e5fb213144a5a3b9bc985f98b640480ad1c8ed8db3791d0fe20f12429cdf844e23f3bc4232884395b230717f2fd7aef478370471c998963e772e57459240fcaa61b45f5e989612207c0b9163327d7e062d7ff8e3bc3a79d77ea836c306d5ba91deb26990f4c1ebe89abe21736a417f03123ee0b5bafedba646cab707bbff6f456b467cf648f4e0f769d90f427ef49a07ac63bad80f110fbdf499cc7bcfbbb3e606c91d0ea39fe578a2cd5a944f6207e56647a6e72456749ca40e978dc7c96df9a9125f053a7aa549e8a09fa9fecdc16574bae7808e39981af5cce1352708891c0c5acea5dc5f1735db58208903b225fdb259d113af6981040ee812a6c45629195dab37f872c256b32c68e12d5504891bf69cd7ee9e611bceb9937f98119da61d123698f6c5cc6721b3c53cda80640d9f4ba2fd5c35b3bd2c6a28a36750d5a2f139b634dc41458b8dcad090a670795dd74be4ee2a2467f8aab41c6bab41e65c9941dd54425c7dd298e327290372dfe4c65c1e19725978f1838bf11890b97fb54c4f6258ccfca325179d34845018cc58fab27f3481e1aa9e7bb1aadee4f40546e637e962b855cda917ea4f7d376bb2e7daa50bafb6b9b5e89d5b8c9370e1d272bf795521cf3d5bb0e3cf8dee150fe792245af8df423d5d12553a6716caa4f47907122c74277378b67a5134cd2b9c4e0853afb1bd7309ad50d8e9526f2d68ecb8552856d45ef0ddf4a4e429905061315c9c89ce49b64749059229bcbedbf362b8dbfe121f48a4a07696dacfb9eeb2e8cd000f245148cba94c96d2fc23fe238102df75a14de7b092917d82e409c9d5129b315764a93810244e60a376ee0f1faf378a9a60f2b574e9d7e475529130614936af67a9c8783ad2f1244be8dd3e8d9968101ac4244ab832b4942dd867f34e5ad9c163c719395ea0e30823c9d0ca3c891ae9f1e3db116418935b6ecaf4f975b763a4d46712f2828c9196ed24ca42e9b59816e3fba4b67d55629c44b7be2c6f996cd70c435d7d0ddf37635a1f61a47d1bd3bfb8275235c1e893ee6c31cd874a7301c6495f525a525a5e2a0d7fbce7f8f13a467eb177d0a26e9b599a10fb82cda62f73a5f72275ab2e06d36db39d608417c7fc55eae57cf9ae0160c2c82ece78ba65f1b42e505a4dc7abf89eaf970b83bc72594ea1eb438e8430828b4367d0a9feb65c72d10d466e51697cced0fe53ebf20823b628b3a4e5cd9f54932ead0623b540bdbee50ab15119a185ee3f2ffd9796a6a6466651e6dbfdb4329e5ccaaf30220b843ab1f9ecf386168dc7482ccc632ebea0b3a0d9fb4f23871a721881852a7342798796ccaa16448d91571862ee1ed6af2afa5b63c4158eb518740c2ed88a744b7938ebba1aa10432851156a4450fd12643ba8a36c5a6c7df10f9e235a20a7407fdd1a385bdee720923a9284e745d5479e9930c1566cb32275c7e111bd7c82956b1f537f9f2882916f67e3d77ec9599b48c5e6914e8f0917a8c94a22aa545d574ca73cc22529c357d756597dae4bfca0c726414aaa80819d5252bf198198c88c2cef4ccfe49093da5ab31128a36e67f7aef760723a0c8c47eb44794f8ed5d2505480331e306239f40bfcfbcdede5ff6d4bb8f178c78c2b6d1c1e476cc45e9473ab1f4b2b7a4b3539ebe244ef039ebf9e8cc8772c1178c6ce2a8e32fa88ebff9eb1fd1c4ba758e6462b330a139897017df5261c108268cb164de5fbfd221373f728942e7cd79293b780e0d1b3e521e351b6dfc0f158c58025d4aaf5885cccd9f83c64825f8cf2fbfa80b1d7493c60b52462871d0e749bae4e175af348963ba6ed277e339676e4412899dceb9c3c7a4f18232786030070774f8580980184622c1a906313aa3e23a2e95168c402237fbd4a4436db67ef8487984a9a50c7ac42a3574ac7c1a2a409a053ce20874e98c9fccb3faa5a7a2037d0d50506ca411c9ff978466da53a23b2a28286d00e9b12305238c40da95eedaaad9f51895334616818edb20264c8cb7d829658c284213b50f39abf6d1d444301af679f7f182374610914c6aff59d2d5381a83829143a06ab773b89c61c68821743193f88fe341bf34a2a09491c60b7c30520853866b74e142e98f5b0505a50c3442884ddcc5fa844e1fed45050565072383c8c6d3c5a4b4fffd8e407ae8604410c760c2cbedfe73b64525e5053f460261b0cf29669d4167f14ac10820787173c6f9244b0b1eff433a4bfba2efdcc4e2f543bea6e2eaee691f73a830d2876ed346ebccda82ea181ffce07ffab288ebbefc0e46f6601242b6984a88bcbf558395203edee8339030a2072b458957db1d5f93ff8e1f6ae8580982860950f03b7ea87174a8319287bf63f8d82feaf3ec88075e90ebfe31cc5ae43c7207f4e4e65497eafcb9237630d49c4b1f6b3bbba4d7a1f90da125b559da7f3c17e43017acb4e00b237448bcad7ab78cefb873b8b494b9343fff96b11cd8d3a383923109b9218fc339aacfa9e696e5fd1c0eb67eeab2b49737e09ee1f1cb4a7a69f7c7abacec48c1881beedbb5149dc551fef2236d68e5a49787cf7c49c7a894f16bfc78345050cec8c1021d68840da8e8133fa7e48389780d8b69f69e557435a4f3627ee15c56d5d8aaa0a0f078363e25078f6723053a54d04a9b600668a0b10224e5070f1e36184983dbb759901f3668c03ceb5568142b5b5bc7caa7f14600ce3072064bf5ff6bdcb419ae9356264d2bc39268f9e8e6286a3b880ccb31f6c75cbd5f873e8643c3fefec6519f94500cffbe87d2d9fcacf1c3607f9c66cde89a5edc7af83043c78f0e18cd3c8c80a16b29b47f645232f582912f94229447d3cbd36ff18817eadecc72164faa939847bab0073d7573f9f49d908e70e1f3aca63d8b7b1ad9c25ba5acbab4f6456919d18267ffc145fb8de262970533aeee68f54aef55567c9800480a46b08086cd26dfcfa57a5153414119b942ab29a34ec960a17368c40a6b964da98c2821846f84912ad4a2edf448efe062d7235430a5c97573c945fb7047a660162d8bc1c5322d6975302205f4be986537db6b1ea10a0aca48141e7d49baa0fd1d81022e8569dfbca0a534469ed0b654a1ff378f386131d48b313b6da91869c2c2ccc7163cb9062d6829271861c2f721b21eb55404c2c8124e7a54632973115a8e990d4694f0fc6f985352e39aaa37104906babe9b639ce50211645c1dedccbce518ad2104e9941e881ce3525ad533c62c9dbb9c0a901d22c6c04dbeaae3e6242f765420528c3c28b5d92c59c4303e77e79edc076d890c6399af4da5a26553fa1511061fb56fc3baf8c6530ac62db630de75aac3d51301c6a1fbcdb216f9c51adf72cf7ace72a6ee3e7ae8f81d3f02a8dd2e1d57932691785e90f262e59ba8700e2690384be29a25b391399dc3e411d865b67997c5963fed268e6074c4ef6c53dc654141296365082900d2140062d208fdc593eb47f951fb27134664db694d936a0a35da22fa646eb2a255c4b174c698839223641226e2186a94b518ef8367b1209820e23ff958ab9e4f3bf52138931fb245994b0f2d35c8e12d78c3c410b5d8ab9dca2c9bb5bc114c0a71d2571ab37ca11f7627c4414d7b46d5d895b50d02a1a4b9766c68b97f3111c4a53bc9890de2e2f8e60d93409c3d9cdc9c4dc90410fb6729694ab9a459f21f105ad08df9d7255cd4f801f92ee93cb972ff7d1fd48dffa26841fd0b2ecf87f3e36c5a6d526f6b9aec6159635acdd86c3a77fe04133df852fdaf4be25a64dc4df2a07b2e79775ff5168487c52ca7099dd6a6e75277b0c50c4ff2faa50d2676507cbda5df99affa18933aa0d363123d4a5df55b67f030a183294e74e84f5aebef1b98cc01ddefcf94f57c3ac6e46006132dcc5f0dc4240e5ccb7f163cd8e71c3413381c62a2d24ece6fb05d439aaa8f5e8f8604133720967bb1de72586de936285f69b39ff4b3e939d2c8f1821c414cd8f02811eedf92cc9db51582c91a0cbbac0f9d19cdc43c081335a0ec3af53f6cd02dbefc40c34dd290be20326eef67a98b76f8a8810d4cd080d0e22dc82c066dca42933374dfd5a94b3c4b233c5130318319b438ba5545eb89ac0ce6e7d9b8419f7667d8840c9b1026ee46e6517dcb640ccb29d6c13ce527a1f3de82951ecfe309266240b9e6a793314f9c683109c3257d3badaf078654bb9a167c7fc6d5e50ba819d92c6659dc1f99f7822ec5ba7fcff98816d385ce5dceb6236adeb4a42a2eec317b29f5dc9ab3c88460b205bf47e9a7f5242d184f2853b69e46b57859d8e6a3766b0ee7e925b18078526f21b4872b17bec22ec6a9f10e23364cacf066cdfa1ec74c7e89ce4daa80fa1c35d5944bea6752a193a6254e5c72134d41dfd196bfd32385c54f5a4c97446d97cc9b4521314268916b1b1eff86c2ebe6828d361d76b1c913ce2f29f35ad1f6ecd709e810191e2fce07192a259834413dabfbfd2bcf22a60e4c98900b2344bd6fcc1278c9d2b6428850976313255c325fe754f2823eb5dd25430bd957fe6a9b1d6633646c5aa5a64d4c6387aaea1869b213696a53599769660c77de33d5bcd6ccec62b06739fb996551fb354809316ac942c552beff4b3c0c337952b557f62faa890825c260f432897bcb27b374114a82b19b76f9be3e2d1e9400c32c274f5532e74917cf8d925fd419e755326feac5d34b7c616ad768416cd6245bf5c2b996abb367919b466683125ed4529badc9e421b39a76718993b7f2ed3c1fde1a25baf0a551f5c25e4be6d7b220c70a72a820470a72a020c729c9055adece8c95d59a3bd33f528082d23fbe0417bf18bbbecb4ae79155c92df4fbf83daf724a892ddefad310bb8e9bc5ba16c72acd5f8b570725b4f82ede3c48512ad376b3c0da731c19ddd37c9465a199106b6b4aa97d6fa050128b5e5693f29e65ef371758f82f5d6ef04e5a7431756ef4a0e415acb9b9edc7397f3175c572d00e4da56a2bd4dcb13b2e97d80d9b15dd65698fd1cf45465e855a67b32144ad0a4b6629633e5e72d137a9f8ec3ceb6395cc1ade0e4a50817be9946fee9f6936a7b0366c5f746ad271465d620a3c097dcd1d5c6ed32da570c76333e76a6953eb3b4a48c18996cbb4e61a051f5f0cc2dc4a3bf32f8abca4bf245f2f93cb1b8a2f7458cb2d5a028af37d4ca193f8ffd1fb27ea9694b8ec997bc274e2524ba5b526c2a512259d60fee543c938a74fc68d28e104ba949ec6e94c0e46946c62b17cd4a8760c772317a144138d10dbf7992e9de69d09f4a70bfa7e3b88a87108259848ad53082de770f1129fa1e412bc657b9a76614b2c8db92c76105752365b29a9c4254779309ddbadc9a6449e5a521df6b3b82c589338ee64cb73a13d09af24f197d4d4928ff8d08c23e1b9dc7a68712f81443ab74bf19dd4c8b3f011b9244a752e3dd162524798f6c3bcc799c839bf11fe68d0e39d35c9ca8c11ccb8a85f0b2a59045284ec876f79e7b52386124568561d6b731663dc74229229c2748c69b55bd488c8fbf395b8542f2adf21d070c9ca5e8cf1362c31046294eecc2e961644db42e4359f3a5755da7e08718e9f7d9b794568c92583a87390e1736bd02fb78b200a75c9d3b3e779ff969240783ee3b5fbb2b7d980c03ac62072947cb2fdff60921bc48cec0e5a343423470e1d8328f1c36bd931bc9ddacd92be0fbe7fe8d7fb0e5a6c990fbb247c3dc65135cbec81cd3dfd9e2e06a5d563a3440fa8973c85c669cbf862f2d0a7fbb2111d1ef8b812fb62566917e33b1c3feb83ce1927ff3339b05062875754082daefe49bbd742491d5e0f33f54d19d692890e5edcc8163435869239ac3e3a09fdd6b6e9a5e4f0958adf8bda2563d0d1511207dc52673f68ed2c8907874689a6176bb30001f92879c3f20b42a8e7b73ea52e256eb08468be988c1f3eab94b4e11f1d4b089d6ae5cafe1236545a7efb38a7b4246aaea1d8cd902d9507f7dcd4807cb96f09cd5b597d491a907145096fd183aceb4ad0f0b709a9d93b6651d622a1e40cb666f9b436834c2fa972a440078f12332c423c9c92a376791965f0f8e143053f7cc400e58d952e29c3a194f818339daf9c2564d8e3087361ec0599c4583286454db50d2dcbe296ce5c2811c327f5b41c93657e758d0a0aca8fff31031494374a5012064473649e94973f2f951230d4b7a54a946e4abe90d0224b6bfeb8b2724a438917d0cd9f9409b9f1398d1ef9e86186922e1c3ebd4b654b7a6365871c4ab8d0b9b5b7641bc3865b57c086922db0225dde0ee256bf4f2b7428d182a332a9932f67f78da787922cd4253bfdbe3cad6749102558384507b3123db55172853e53a754ab0efd941538993b54f36b14d1c9209454e1db136133ae395e8a885042853bb66f1a1d2db76cd6148e9b36e385d9f42436452891822642bebe5842cb5bb0240aacdca731d51a28e02fc812fb234e4b9d0b52f2845eb4da0aab0b8fd50ca1c409e8db8ef9ee5c56d16c49137a59b765414cad84129530c120fc84670c7e72e42e5942a379fb2d676af1c57909254ad8db4de8658734cd51259024830d6277774d46fdd220e318b3df1511a25ace8f71ca6ed52f99638c5a1693a6174f267b0d1663512e2ae3f7ed525fc4b0be4369107dc1469624c3387aee98f7a5d364e59208e34a5dcffc77561bbc29900423bb38fb9cb4eb5b90a18104185df8c8f7a0fa84ae310d24bf5873146dd91daa76ff1be97f85c417da26dfd2223537cdda8b44bac7cbc95d54cb362f92afa265b9c53f6dcc2e102fc5e9d9a7a89d870e24ba783b86f2cc1cdfebc35c98f3aa05f9a6259d6c24c1c5c266931d6bcb5ba0a571d7acd1b2eb6cb12c666ef7a4c2564f2506925ad49a33475f9239c98c69818cb767f88af3d29f3190ccc296633611ff52e73e5d1669d5d4532e7fb2dc4f2c0eddb6911f74589caecf3c73ac91b6d62bccf925bb49082df7a95db1acfea1b7336dc562856ce99ca5d89c9b15e8dde0e2fefe7b2e791579ca603a32d3e61ea52aaaec984e5a6b965bb2e140928a4a679dbe98cb32660d15cbf69cacab8f794e14079253dc827c59f52cb5a4da41038929f0ccf24be2930c2f031d58ea03591fb8aba3000728f0061b2b2a6bece8f18102c119105806d00a90203f08108037ce074400b00224c80c0610805fa383acd1a3d938800080fc40000d00802907c0b18964fecf0b5695ca9e054141e1f13f52dcd8e1298ebe0d2067e0d0441b3c502670c78a1b3b1c13b863850d15209d9282001c97c01d2b3f5480b0919282001c965879209528000e4aa07e4da6cc2e774abe4964b2ea729610e639aa8a243439bd9f2d548d7ab9c31189c5527dcdbeaef3a46c03f1781e28283c7aec58f9613820813b56dc078f20292908c0f18877c3070f1ecfc300381c91d8676fd25be72557234e5142e385d612254a8c386e4cebce395ac7fe178196c7d3bc33c33f6a14917c915617daf6018e442c0b22fd376630df18c58188ef4f6d500d2274a7380ef1a9157f29a46588ba3aac9ea6171c854898cc9944fd3cecf368e020c4e6b218a3a85caabc98ca03a1d5c031083b9f674fa6a5ed328d43107966f0fcd15a54700402b9a132e37429081a3f7ea50541c0010854d7bf66496875b1d438fe70d87117356733655b70f8e1dbdab48f59c4cfb9d400471f7c597e3edde5cc3e2d38f89094133a2813f11e92c94a269dce059965d783e3d539ffe133bfc87940bf3c2263e6b0b372e121b967164a0b9b9f5fc371073e9e6c49e6e776382f94edfca670d4211b15edc2ace7b0d5c14187e6e4b459e679974e9d8399d493b7183970a69d4cf48868d81807ff7c4bbad8295f730587654955687649de5ce938de509b8e8ef5b89cf1b71f38dcf0decf5507cd5b72fb3620dbffb65f7ccfce83010e366cfff531464b327df6d6708cd0252ea489190dab01ebbb723921af5a4c99a541b5ced2de21d3dae88680030d6a7e7ff76651f309d919964444ddf67ece7d32c33f42937c41b3dd7eca90504a4e9dde86f2d1428635ace61c4234598f3d8674bfbcd71b77ab6428063e7088c171c1aab5d6b4b398f3c01186c3df084fa53e4bee2d6de000c37bf2ef3c3d8611bdbe8056d38256798f294683c30bbc56e5b5a8164d4d293d7cf44801b20305e50438ba80d226ab39dbafc8182a2ea0d24d96cbd2b564a959018e2da4aeb478eb727af524e4021c5ae8bf538ea76f4c5a097064e10fa54326993908173d2ce82d49cd519be73ac357f85e4b85c98e8c9c8f159a17775b7cdf6ab5b10a478dade133c74f9a3654d073bbaebff0671bdc29142a575fa5f3b2c88e430a07f5b2604aad7e66df5b80230aa69d9807a5d54ffb4b0f1f3fd20a7040c19ad3a55cf3cb3967ae8282f24020018e27589681008713d29e3ad3c46a874b251c4d48a7e65c1ae352fcf63898801a8f9bb3705abab20c1c4b58ccaca36d5434cea7fe2ac0a1047489d2265c6a3949c6396596cfc26eccbf2ec8303bf48a8b76a94c2d6ae8408d93636ce392bbec7bd8529e107c9c0005259d18633161a7c46327c5d8c499cff7eb8ffe283172198fd1c6dc5e6e338cfdd4674ecce596b213c62593d8cd22c4d6a8c64607e3dfcdbd12ea464997f613601cdcfe44a6ac527b975fa86974cca5f94ce9b92a27bec03ca7906fa2a3935e94195a64bcb24599c50bb7b418a7d326e52fa977918b2f9b7bccb2fe964a1798d0a905b5d9af359f5c7cead3a869414b8d96c585f91e73ce8cb16577f95bb4973bd25fd277a53327b6e0aee5d998745d46d79cd4e2d83fa57953f9a9f627b4c8334f4ee3090627b34059d9660e229b5fdca471220bb7830a17cde534c2f32927b15844b68f14ad932f292c3ccfdddc361edbe3e84e5ef1e6d1d7410b9aa7da0301e24325a5c70f139cb86271ebf59225b21ee25618e2742931e2928bcc8ac3bf20c34e8392cdbe1927ab488985f7c83e61bb27374e54e1798b2d9d0bdeb2f8cb492afa6dc133faea2927a8f0fcf35d3496c6583ac5dee29f2c37cd8929963b84bd1ce306c249298ebf499f6a6d3bed96148c1633d6667c9e6ff70727a348f8f986d9fe4e44c169e6cc6910a65d75289c9341073daa3e0145da4ce6ec6292ae23223776f8c927166fb544fbc94fdf391e9ee057eb36f4538eba782f279d503ed6ac6293fe98ae8282c2060aca4a8f1d34586387095050504e388165ca0be29270c136bb89053173ba5355861e888e129c68c20f79b7a26ba395269d64c2fced2f311bd264d64e30f15dcb592a4e6889fc4e2e91d02ddae9601fce4f45e3c41265cca4d7c3e93f5e05fde84fe38db6810f21a881822282934a309ede7134072d6dbca8a0a0ec00b263c74a903da18479c23b8fb4fbd4238d818e951d6cb491060aca8f951e9c4c822f973a6d98b78fd62792d8c049241e990b1ddbb6e4a90c12293bdaa0c0c923500f1f113871840d7ca8b18193469825b12dbf9afbd96518b181934598d32fbf7c3754c84625850d36ba8d7774a2881e7d860f354c7092081b50e00411293bda3043053e900fe4630614383944044e0ce176aae50977ddfab8109f29d38c17dba7bfe58410093819442af75ecad1b6b1dc3c1144f2e1e3070f3414701288950792b2a30d3316700288099cfce1fc134addfb3d4817433bd838416210002e9cf8c1ef18b5c2cd3f4b6847b791d286104efa00e48d0742054ef8b0a30d332a70b2073dd103064ef280e3040fcc7d16bb831d52561e705287941d6d98f1a74da080133a6ce0640e297b2207df91b2f2401a70120720bf63471b123881830a9056b1c0c91b2e70e2060e9cb40102276c58831ad2e02339e0040d67c871620637be4f638c0e61f149e9915278006921a4a4f85819c14919227042863168e0440c193809c3064ec060ee1cdb9d054fbe008402275e90c0491780fcf0b1d23e58c080132ea4ec68c30c1b54e0640b857f5e6d9056d572fc7bec383c7c201494344eb4b0c61aad86074eb28005e3fc736a3186b52ccd2757387d960c3676dabb2790132b50e0a40a0f38a1023ab98d2ce1e91e3e76d0e1640a292680c08914524e4ea2a0801328a4ddaac3ad54f9fb65869327a0749469d920194e9c80e3a4099979782b613a2735fd1a6bf860230504274c10395942a5f6a2a667d4d3f93d51429ab23cff64b6814932f0add85ca73264e4a6e57891cd8f61b68f1fcce4323106324bdea3c4d78eac96629c34d8a56e52234a6e26c4f834f746bf3c8741729491facf307a2e6084c9304e721d2363844e5a744c84f1e7781f79ffbb7ac960d4327ea37f738be7123096d44b661ea46d5c954d7e816cd3b63b250444e547ca1a69e44023871a3a6680061a28286798f882f14f1e3a9ff033ed62d28b53fffe34741cebd199f0c270613a4b4a646e69380e26bb48693d33f5561d53c432cec8c1021520cd821f30e89546410b72a891231826bad03a3cb87c7c39cb2ec82417a6138b1d5df99268d132ced061828be635264d3ffe1e3c377cfc68c3e41666eb9b8896d0c4169fe66c1fe4651076a60a0b4c6ae1cfcb2aca5ada9873b5c384166cc70e26f3d37950229359e0bbd779bb7ce47626b2d0a52e138fe14ba56f7460128bf3abdb47bdd25b5ec2e2cb73551d9db2b3ba159357243e426971e1364c5ce18a2cfbd231286885419fbc889e8d7a1b6960c20ab3f0f1b4a6859645644c56a1a829bf97973e66178f892aaccfa55a122f796d0699a402f99214211a1bfea551414179f4c3479282092abe93e69ba368d1fc722a2828292b39303905d62d9829f53997aa900a0a8a89291667d45c76cd9b41e923a58d205b302985794276d4070b75afdfc08414ed884ca574cc7bd3988c62319bdc24c3e9b4e7e22a26a240c764aabfdad2bc6326a1309697ea99684167fdf858e9d102219880c2d36de2392372cb3e934f98fef774f3c7389d2f134c3c7128b1f14266bd538d1a9874e28ed91c746e8af0d04c38811226ede5d1b3d25f9a6c42516762612a9372517320071a390cb00a134d98b14dab081d7f5ba314986442db8e9e85cfdef8d13d769860850711de10820e14986002d74090e675594ca757a1eb9b5ce217b64ea6ffcc92d0926f9c94951f3e80986162894ab587d6bce0b267d3a4127db7af690fb777aa45a54d28719ff83ebd70399bcef3607f984c626df334a536d878ce4ac2e0570a8c6ea874d29288240e8982e150201000806066af410083110830504c22934763b18848da961f14000142281e564626223a20181e1e0a06225158240e864281302810060608421408a23c0955d3008b007bdfe75a493f634cc47435f840b8b7f6559974034bd2370ad40e9886fdb287d08628d890f387f21c1eeb538babd9aa472cab19806dbcf70e5120839b6e9d61730883c60c38bdb67010f2c5fd80e2bae23b7d4941300eeac21cc3dd3816ef6cea91332c9809716c8d983fa1d2bb9e32443ad0df3eca71c9a4918a584033b9dd0aab616fe998283b780b9feae2505e9aa6738ae6ae2de707b3ef9b294b377afa573c28418cae6a545894f914ab89365f690e99e16ed2a3ddcce330bc1dd7fdf5c2ce2bfd8b6d2c06651c71789fad630c0fc3578959b321030bf9206f28bf1dc5e526f450b6b0f8f162b84adb0ae02753ad3a56f5c2d3cf60a6e94d2e4bc5ea7861267672b02ed43c0578f5a038e09dfae9c3c7dfc3cfcaa8694f8be7244d40593fb208f06f57c5e1711e846a02266b1437a99745dbb0f03e55de5d0682c6f4f95d60ac2a88bd101a3132309788546c1bac2e3d932f40890f9f7882f3f957ab7d95a0159c3be77bd594b2b2fdeee05df648eade3a1058353eaa6d93bce6e91c1bd0a599829b4f2433759c3dfccce4e4b520357a22eae414b6b98266acb015b9cdb9a16245703ba3696544c8b1df1f6a315bbd9fa240ce73a3e4dfbc832de0da539ceffd5aad86cb36161e8695d161216bbe041151b6896a510f0708054897aa5f9afe11a00a57669fb15714ccd95c40d590d369e7a072c7d0dacc7a9fa8d3692669a1a24da2def443083fd995fd0d436bac563409c601e9caac16d90144081bb6910860aa4ce294e32d5d5e54858a07d459cda25f2c6df7fb542f4749d45afa79649bc6c1e5748eb7e4e9c2ac68c82dcd83db20f3dd705306da7834c8aa431ef4b8857fc8a34111768d7919878f9fe6da9f28ab74ca048c6b381c1c4c3d7b5df220e60435c609adf5b70dc579e90f8b7800ed80623ed72b5215cae3ee999d150565ab8b128ee413f5c194dd592e3a3ecc978b283dfbf74c4bb9a9ca583c355293bb93d073566b8a5277de5cd0928e856d02fd46c85b70b5c14b2c841b771bf5184f3fc63de2b6b6a51bc31b67f5b28e40f832619fd01bc22f9f10847f1523dd0e14cf05047703baf4f65b013ca24d8c49cfeb7fbb0d9409c334f8acecd27f6e28653a964c6de71bdf865b334a3959904479a270009d519b89d078168a3b4a3a623e21a1e32ebe5b6c8de15a9278f403bed5b95701b232dfb2b1d1e9ccae8c4bd0b46599ec57db4407b203ba6a525ed58d005e8f3eb4690bd29376b1ad7b123519acbd9165a64f0c9006a2858ae7a911671123cf4433d13a2d678452c0dfae4e210d5c1720afdd2509c305a602a8f50e366380d8caf42678cae23b8c0f5fc0c72a46a70930e98acb0e0ad7577283050b28f4245d517db42463e00990b1aa50dfd9949e599c12ff4ff0cb3957179df58ca7f6d13a8c1c066f1a3f0a93e94bae6a7c28b8ba9f5bc8c8735fa3f9aa5050615caec34afdb62b245914d441bfd7fd170fb989741b69bfaf256f4613774147df6c198f3874a35f14c34c2b853f5591bb0a8091a1625ebc04cfd862a54730813e938252a41bc048a6d8c73486e0db66155fd3fc45a35448d1ab6bca7d4644e3cc789e776faecce4cf1f7a64bcdc2c602e50dafea779a22fe2c09c4731d22c7a9c5a1d322443a83ae2879b29139e09a5cb4c279503755fae9aa80d009c80804f9ee2ab87413c12aa9c0bec07062eaf28fa421e0ed04c41604102f3407d0bff8b14fe4b1ecc32a990059a321b42efed44dccee0c585db58e748f45b5ed6530d8df835eededcfad4cecdb0a073b394687fb9844a162391c1862df36b8838d250f1e26f062529cf93e5db26dd438ce57b80a2282cff1b6e40507c9dfbca8bccc13f896ed895f73817ab82259ec11a036de5cbd880f6ade98750da2aef86f4f8b1dbf9d9a06e09c00f8ff8ad54e71061b588d29d1de9cdbf0b79bfd1c3bbcce9c9478a232257c5a7ec5422d6c9734096de66c350b079e8269fe95e50d2f81098427aaf31264b6a59fbcbac052c4cf0ba91e71647476404122a6f76c536457efdde37a10622afbf3e1aea4d8c90ed056e74b4ade1c7b7277ae14adee93110ad117d8f4fbcd8ed07aa6a78362fc4061908b77ca5b5cbc55b6b235f3400008e36042901d00577976ee8ddf7ec2366ed92bacbd01108397fbaf420851de71d5d95922de9013619568b01c669b312ef7ca62e83abe0cbdd96d5762f355c162bca43c8569c664a28f8acee7623aa8ee900ebbfde81550ba46203725a7af9ef60ab93120af32acc4de704478859305cbf2cc345b5d873de93bd49904a3155af9be3eb75c2ad6e06eafdf498364e9302381e54f86d0c5da2ced795ac770372a0e573386e55758622db719cd37126699fe6605bb7e42d51434c2bd113a016fce9923fc67da1ef42981942b3c5de8bd6c75f001f3da19a48c351b1aaaf7b54aa46d506b9eec3756cf64f806368296c07b0a1d8cecd45eac502ddfa041d2d52f6e2ed143a0615cbe4ca625a88e8aaa49f3c792c75df0489f4d163547d97b4505e5a5d16e40a7988bdce1a0e5fb6bf3be19f8de255bd7586aee5c8a5fd78ef3760fd63941105da11da75a15596f5ed46ed3ad0700998565f0c59dc46ac5bdbb49c265c0ff0f5d9580ee5b39a320bddb3855efaafa387fcdde62dea530efa7167b6cb9aafa530ff7efe1ae86310673a25fab9da7e9dcf9b4f8506b33ba086cae32428d55dfa70a383931748b254fe78373d743be3d16deadcb7d62f769ebcaee716542add2001fb66ef5621dbe6bd51749cb649f4574e6d9df7b4018d0192cff0dda1af273f05611f2e5a892c7697a9ccb026ea27bb83d3bfcf4380da835a074da39cba52272b1504ccb009515834517b6ab44f3307b21859bbcf2f7566a62fc266d58e1e790b3f60defe2a4e9d665c8c51a7021b7d2492d7f75308e383a89a8a14143150ad59583a2fbead99c2ec9017f1776f2b2df97462f89679502038ea7bfb714a3e6428ab2a9efd8092273a1f2d6bda353b963fa425933fec6a4539d8e0bb8e304fdc1beb530117e6125f360c8020494fa567ec8d9989190cc3af87a0af91381b7df6fea7fc20dbb038daf1334da8e487a3583ce605ae5b51f1dfb094a5302868b1c6e32a5057571a35e81c23bef2ae520782178a25869dd0fc2cfa6c0dd3b46581252e2c17c07d1d73f09aa32d40a820e9be285a62f5f9c099a29a18c3dc6f1b7486f76eca0746ec82423eea93dd01a122106ca4d939843fc3e885b7f92e0553c78ab11547e58eac183b738e25769536aafcc0b0f4020e8ccdced0ea09522440b5725716c0360d0a04a93ff8a9205d80ada78ca52259d0086446fc2bbfb37692d2f606a08d2a6df20c70fd669784a35892c89e5af3649bbfacb7f76176dee32dd0156acbe6aa97cbb8d2a072b3ee3e4ddcfcbae3dae6a3f5372e6eee75198f988fd15c7cd9bbd8514d55c54658e299fddab0a9a11a3c82bdad31e7bb80eca3810d1d68b8f19a33366c7837c2c4a4409a9aa9c7e6ae7191c9dac98bd178287f4d43416cf53b899399822b38f190d48846682c2e1669867280c64dd4828ead646356d9ed755460f49f78e99550f02cbf7dfc5f2e1214e4689c7cc05a7ea4dc0f17f1936d65310907625eace748e6edb1586edf28f945ce64c58b6e32ef382bf510733d684b0f0b5301b942478548555615ba02cdd9c15869478426d3ceba590506990fce8d7d336bef9eb69481d38e6f5bb40166dd897e20bb592f4cfa74ad3689c142724c8e2779e8b6b17ae01721f9c9ee3dc0fc2b9bf0a44ba02cbf5b768283dd0837b811d8df1305954d97419d297bc29698e49d23b856e930f175160ed56dabd3943f941379bc56d233fa38d8e70a40c601a2da809d7655886dca927249122842de44f31c81a5e0bfe0a03a1c04a5b7ae6af5f5b2775ad4ef89f1e66821fdbb62c7f2975bc89f79423cc8368e1be7adde46d625ef16c1e14645e3d153566995b200eb33090dc536bed66dea8313175a51472d12040988ed41f76a47879d54900167777418e9b2b933ae8b7e0226c3ef8edb390aa8636e7b0715f4ebc8a58d204caa502b8d63b4c9c7a377cc0834d858f601054d7adbf873f1f57550e9a6777d8e47b9f5662ad523f6b04810e73b7dddd0b7df409a33674385eac3f91c1cf0baf6edbb93535d813cfe5ccc9720a73c825157a6258c44a718045a793bfce5c4af70fd042ebbc1245ecab82b6d5a9629a561e1738158791744725ea0df77cfab367ec116e583e82dd0d81b8c15500dbbcd92d912ab1c4f803ca21c0b4266e9b49f016748b4ee88bea6962c1163ccc8ccba05e8040fd0ee10716be976d1e908fd882a3b69e20b7749dfb8c8e95887041d8a735becb931235d8df3d1c52d66bfc12a76da1a6ffee21150f1afaa58cd64fe8bc46d3c845548834aea8d6d1fea2fe005d727fde5be77e141e8a1da595f452b6bfc9011a6b6ffbb0f20c4bb4f584d8060a8a1463aa9d3c1f3f9f1165518eca4ff1a58cd2bdab833889bee388b41b55c5dbdd567fee530702a4a2170a7ec2e3ddd41b24aef971c1f4a02afd23f8fca67117e16faff85c9b885ba0ebfe1b34f5604a744b0d7e7c0f9129d2c673664353eb0b06cac30f903384ffcfef1c61aa65c2c8746d9b314706eb227023bb32719e6dcb5e44adcdbbecb530f22ceedc274715abf068e5fb3cbe78a81b9706167e39189fa62acf68b450d12860147b76efcd202a12c5f0f32fdcb2f3434add17692ffd33da4556425a9b853f467fc14a9f469cdd84233ebeac54aaa633e29813ed648959e88132d6a21427e3e3b87fde459196825d8e30bf466bf19c15d568c71879ea3d94b99b287b95c626c7e24887a2a4faa68384588a7d69534f3120c1ad10dc94446a89fd8624906a4a0f5c97c9ebb93823c544c8fa7abc4e2690c11632f0fd419ad6ec350e4323b04390d64e5434ef12d4102d43a821d7a0dcc3d08c854d8d19c906a407fdd0b167450baddbc17e9e6803efcb0ad79ff720ae483acb07cb3251670b00f9131f0478ca52cd6d4987ee156962b598af173a7cc61a864b224de89a19ec10600e5d50b0944a0b7aacf5d32ad3827b14a063d97a63d0cc0801c7c6a412192a027229b1801eaa6c113d937df458d1d5e89f510bef4dff56810d6dfb16eb5ca4bd6ec8813b98972d40d97e063d8587220cde87584e794803ad81d2404b4043f582bef2788b16bd1866f2bc083a4e2e44eb87c1455fe50b0414d2a2e81244f8ea43c7da8576384127a5f14a148c73a08f17ed11ec109cdd05c038c14bcdbe309f5e5ef130ead749ef6e80238ac3e64f728cbf18899da4df77437571e2dbbc795318ca4752cada54654409533232374504b10061992ac7fd261f5a7a12c6ba06dbede0db71da832d3baeb86a5b8acb42c462959edb6a7a07aeace2d48ac0b74ad00098cb5e24d48b7b56ba8d3243a8fc752a410761d89abd81e6174079fb424b32cf2bd387a8f3b201ae435fafc5fcc9001bc5be6a5c4c080978bb05792b13bae03a0973fc7c5d4ff23404a0ea7f42b32fed731233110f42a876678a34980491d4727692221f6b47853266ed7b885baaab1749ca069f4954ed8ef84d074c4b7aef4926aa108e91521ef8d111982b1148cdd632d0740147115e38538f559d621be5688f3cbe225de88496fa745d025aa52e013fce81ddb740686f00e5b0ff375eb2b9e4e0996284abda31a22bb97a9fa52357921d92de2dfd6eb4a086da09b326899215c3f902afc0d0c003016110b9fbeaa343ac04bce0359fd767027c9ff842215512090a621412487ba4a0a70112c60cae9ce8d94141ac59ce91f62f2952a7847f77cc5c6d84f3cd0697153748c01d12b314cb8f7c59ea9b4a9c509b514ab2bf74ee6c5b631a5ef0de4154d67d370195dff441d3ebd18d0da0ce73f22226aa50033f445cec5c0850d6fc084fb30710dde958a0971d61fd98d23bc51059484152bfe4c5119b5545b24c9df1329675cc4671d64b81777e4d32b203c4a17d13a62bd2597731ad663a93e82af8d4e6168ede094021e8453d27f8991e2639bf20909b0dd5f3fac7d217876e5122d6445d2a550fcc84bdff76cb7f0cb53841050d33b9e4baa5ded8eba9415571502ebec614d5a6903b4b6d4cfbf02339a74c936983c050cc88c967c001c892cc00c751c53f5dec28a0922a3ed8986d231113d4ee35e600d368cd3354ea37c4510d6473148c98bf1752ac584db8d7d7d8f21e0da63593c58d84587c44b3df4bde501a9e3297c7997a8bb764e12e818842829a4565c06b1bf819b3083abf2485a3efeedef48a34805676bea5712105bf17f7ea5d52e741eea74f9317dedf7f274a926fade546bd7458aaba236826967f2c7b9f1d8d5cb6099b1d6cdab416a1e0c097dc5ed572ba71664af43e3654b0172eaf349fa02938caad7d3c187c315245d658c8d0630789884f95f6b6585f94889d23f5fc6f0307df6a15986e30f9f732728dce9f435390724937f730df7e3f807de840bfa24e3bcefa1de6cd403fc7fdaf68f8a8e02fa851752284cb4bf4bc6baad2681cb776544f6d766fee6ee6c9ad78725450e3402a902164300f1ea2fded66aa5407e0d842522d880def7e081b6fa4003f704405c76984f8c02f01dfc1f6f37a7910c6832c04abdbc5f2d0cb87a9b07847225df39aa112eeb7ec803c2b230a68cade4b95b9f4dc831da0252268b5eb1b10b482dc3ad71d52311df98d63bbe39b264bd2e7ac6ad48830c952d375afe910f4f35102f66b7ae12479b3dd9f5d5a49a64ae6518602254ef3c2eca8f7e65e22992621914efe565386cdd06f47a892a0c35089d660bf8ab6ff2c3836876d9c95cb8e46ba6b1983e8e7655c1227f3abc4a5013cea1ed680eae4dd1bbdebd810d9f0475320026baf544de012c6e0a0659018dac182e550342ea5751ea66c9ae86a10f855b976c7dd9f844264352fe89cd46dcb9c62d7d966176411259334e2c39212b711b04beed12245b068c74ecf539bce99e18de067e4331a6d6ffa3ffdc0023d39f68edf9eda2e122a0b177d598acd0f2f43c87c1a3e28676bc4c6816355def546377d599acd052bef606b068df5b870ea407f22d4a21b2550832820641bb0f4e4fb2f7113ab58292bfae2b7679016df0372c5af9f57689c6070469e0e460337ad260cc2b7307ec5adb27d3df6e9bffaf2537cb287feefcb4d087085030b956c282c483d6ef581649a46bdfd9b439abdbc839303c93743082d607a2e834f1fb5462f0c15fc44a5ed48356e8958b8689beaf6b86d7fe7e405fe78e8e7f408239769c51d3eae05ad1cbf7f378be4c075dedf53f4f552747ca3b1dedae442062ec9adc65bc13bd18ca81cc84ca0380bca7e4e564a8eca1dfa83a6ba630624f78151af976ebb569331f53ecb39c89bcc6319284cca83589df8a9904a0b018769af6865b8d5acae568632bb6e98aa98229d9a47298a52831ec34a6207b9cfbf95e6223b6c87f1c85dd4c96c8282ea7257463221066e5d2966b05811afd709621f532cced6f008957361bf5bae59df642b2656c9d44043b07e8f6a463e47368bd308d76211aa96cd6b6613d2b1784ad74b8f4a54f12ac2294c135537a8b9c5948c522fb1f6d18c378842aaed492b5fc7269d31f12497b5282390eb2652c09673d4c063b9d42b65ca8a30c37d3e90fbc775a3cd95c14b4b48c752dc90a14beae9a5ab7f4a6153833494f8dc13538282937a08cf9a738fac314a5e728efb931244cc70d259d6024d4c75539b2229e666539ba7d454ecdd0acab01b39cc5cb0e16c02027c51b277631106da55ee0ba88ae453c382dfab8a02f22f506b56481b692eebdb03b0529b1c9d4998af6c8bda50f481bb6d80ec728a7eaff7faa1acff4017a023cf6026219d6768554dbf345ca03d138351ac6305f0999fe70155aa4084ba0e43af13f96f49c13d087e933b65b343ae8fac05e45445e480091c5c985767a0ee95f0c5cee460bc2e2c27432a7c98f672dc86496270ada5601f4f995a5579cefd2ba8ce941538ad8a6412b5a6f3d778735c97ad2201633ea4fb8d5f07535c37d2b56232367480f0e6035b74db8f03f8f005bd21ada4ebdf9684deb8f4f865adc7656626e5ff223595dcae196409175e0231eae1bf56651aa9d4bb89eec246786928e685749c97081c39b2568fe0fff5abe0957de3f3d0ac272da16f25fdb407f058dbe66da822fcc0a3a63cec00bdb2fd031dd4744a1a7f658ee300632bbdf90f8225e84ebb89806a85e8a521d472465d2de82978514193ec5dd7cdcd05a88d48e9c145caab6192c22eacd287e1a82329116fe2706d55edae31a538ab0eefb87465fe4bcc606ff440c3fe8db4413bc1541ab7894e163848f4431f2d4aaf8fcac145399491a39f7501616194277fe8f0bdf009f5e1a691e211f762b1b4f629fe3328e000c6393462d21644d91478fb58954928f98a341469cceb79a1f3b880cc3b7e05d6f5f5d4d3fc16447af01f83b01d2d9b24d662905d9e56ac6f6fc87a46149390b712ad6d53d9024fc424490b0d619f1a4d2823c5184f4a49bd27d8db854c401f49eddfaba8f70652949c636ff88b8d7fbbfc53f8e2a834b8bc4fcafa55d2a3c8b9d93b212f091d361e6de6ae3188f910f5ef0591a55c1ef6c81e461416354167147b242b40a45ee565496576be743447cbcb392c0d243038088c7e3d081ecb633103d277403898085e59ad05aad359ebc3f392edb20494afbac0c2d390d6845f869c201a9df798c2df119d0c5379040f7dcbb6e55e67e19c24fda46f03a3177254f756a82bf826b851ae78cd75c547d5cac404ed4859c9984003f9233f12cc40882f6e605235404de74e0ac445e130602044d2d94fabb074b827f431208e567f13994f2c9d1d1c190a0df5e9891762a9b502cc70dc7e5e53032adf4f272a86402c99908a31053c1e031b6c6676ddc17a95ec86ffb0e6b875fd02a2891709d63aac32968fb8d6ef42f143b647070686a105d23980ef685eb9aeaee939a2fefe719235dd6b29e2a6fc60e064ae90d69ef10c2a969e75c322ca8f7e9777b934d9b995f41a8b8482b8a1cc1dc0e48c741ccfd6b10ce9c8acd0d0b6dc63b9ad44c7aa7871a16a91f5b5309af043d4b45cc8091a7882147c12ed345f16721b73a03437e088774d3b2794a31d4e807fd74bc42f9689f49ad79847fee30502855bc2c9dcb8b6f3f5bfcae591759323c297a478082a71c4e17ab3a19cc2e334ab450de908f36ff320e515f8780ca6bec4a72d9b1b46828f54c7a7f01c40a0bacbf8209efe6774b2a60ace40e13766766925142762ac6e39cc3a9f85c406528a16dd55c9c3ea0d21b36c10c9a306427b1aa647564701bd9ac82ae47c3ba8fe000a1f4c47efeb80d9539719df29cd30737233c15a4bbb415f1a3f16c8e7f3bb7726351680f73e84da4659ef0ec094b6650ae38069b7b9e28d3850e8c92cf176fe6274b81f1144dd85f0c5bd1ca869fb4528ff2ca4551ef2ea80a787c43c11521e4aa817c82dde954ba4aeb5ccd3c553c9d38593d847031abd820f4c2ed059144e1a5759a915d4c4bb192f95156514079c960910a6839be9583dc741e8e5f08a099862f2bd320e778ae6e5d3c319c7ee79dcb3e12897a822ed771b35e04013296dd76e86efc2fce4ed8671abfd7008b1b2841a3ed2ab0bdc08c49b9c7f32e868a46fe3f1fdda50b155f7dbc1ccd584404f640b50a5da02be33ed24ca5b8a75e88890c1abfb6b7792912d1eff40158bc130e65ff3484e16834984ac85193ce5ebc6229cfc81be0615c62e3fd2cb17f3dfc340440ac19a261f29a3c338c6a6b789889099e615275f672d028231ca4c836180a61a28ae6353996294c5bebd3b03038f48f3d001dcbe3b12b53e70283a76007aba90b4466490ac1e928a3e7a4c98f83310bccd1a80c0d6fdfab8ed64b67d121862f5a8d50bb0cc49b7309375bdfc3475a30328b2b5d41c19d1ad148744a2f1c53b989bef1f696bcce3ea48d68be49d0b45094336f2e65f30821ef1f3989ebbd09367a55f87b0ee2106a3e5a7244c11f6d7566186d85e686c843e3c259241c78b90c46fe81d28c0688be1dbf1d0815076e192baa76fe28fb7ef6437e339f8d26fcadd82b76d0bd7d241a5ebc5aefb92c042832731329ab22354384550f16d0b3daec3ed25ab7bb39772a5c040e3588945b6231c406708d5b956c79bb4e3e0bb516f685b56f1375cae1ef67d848d866f794844dfdc5ec800c631829a94fcceb23bf363f6adabcb2327119da7a0b00fc6e3d3df36bf1fa249144837c2406cc7d8b3e1e849da530d65949c6671d7e91d48f021e44d1120442bf04c92805fbc6c5a6d0a434d8e474a984c4dfa0cfd90cef1a7b9a0f8e363d49abb34b20233184b0b8a2fd7d9b07cd39b2d0277012363e45780af1374d9b2b3dc90bf5096c875da08aa357c444a19601397df2ef828fd4253983ee566e13928a5c60a60a56097ca2ab014290aca970713a6ce005853eaef4bd08beffc4262b76fb25015b96c108c221ef1acdb9b6da62a09a388b1bd55557cbed09063e3b758bac3db9a9091fb5b0ced6fc2428beb54d9a3599bb8b1b39dc17d923c2766b4d279ad97c53fb77cf0358072718fa3795dbec6670b74e741b1eb06053d59f1b5a4de1a54a68c61ed24f230ff4f8a3db7143b53c2e72feee8fa140f4978d5f6142794d742a4022104d63efaf0eb55f9f693f9193421aa07f49e492df47d8164170012c7b8ffc40f46e2670718acfd46f017dd3dfcc6ef466f05ad0c287fa3ac0b7ddc893a8a5418c65b3dc30f035f566c045799505af7474dcd6c131faa1aa0962a9d6d1dfcb82460236524b14586ebfa000d8032088354b0557e9497b904f723b3ff8b3197ee59dd865d3c4ced8957cc3fab7b3320e6daeccfbf72b3baafdda80bcb7255a6306f15f561a283a9dd1d504e0fd2718ca9c35a2510d07b2e2df44aa033fbba17624e306b5e3d9bf7fa2523d8ce31c1963893cd8ea01c446afd440688436b704027f03c215b55d849c492418aed911b4930592da7b0133fc2c66ca6a3b1032590ebf3009cfc089e074c76a62bf42e9c464b30f35a59d3e6e6b810cecfe3c9f58a3f6d5cc4662cdf803243bfb153367dbf39f556734fd12c9472b6d09a2c51502d6f8c244b2340a48f936096ed4c52b771094a62069a1d98052fbce50be3e97d3d2767936988f3f0bb78fbf242f7d7eb9feb09e4b89e2e174fd3c81d446279f4c5e23e9426d648888dae6519b27e95a80e0aa9517b83201166502018be0eefea51e173df21375a9fdb29276a5dc12f87430ee75785f108433fee00e183830295772876dd721c3e456bf83c5a160b823e8ff580e8b62a2fffe1f48aa85e02b815909c73c7daa6e6947a92a45c61029f261fe2d2853fbc306641211f3f4722e374aa9fd84d47a5ebd2e2291fded2efb5f42c01c37fa51129a6f817d9405c23f6fd5a971f8861953f8dc64077e9888a926e48d37da1d0ee114400eb9ec8d9f9a32761cc483d40d302279e2eb03dade2d0d84bfc9769bae09fba1518f5c9487da53453be3bb8370125e11ff52f3ec65e9e644eb355d03e55484f06c71c23aafeb53c435db9ac2d19c3fd8e5235e0064010838c5d86c75fd5d9061123cfb852b15c710c5a831854f595469f4660d43ca093ee5259561c32ed58c91b323dfddafacdba30af57aa417d3e6d5f48e97a7b91a677d014e3ee6378172263e1b6cdf67dee62463a183d40723ae8144a3adda3fa47f6c43ac03d43eb358bfc8cf46e947a29f25e5677bc3636692491f288877767c1c94c588cf705bb3ec0b4064e6a6305c92b212a362ccc46113d409ae331863af6c23dafd24ee1e98cd95e26a82b2541601abfab5438d97bba7dbf5f1fd5321058032a5a11ce95949a2f62badf7bc0ce92db7393079bc76bb3c1ce0914e465afdd826e01556f278ae21c4dab0227eb963d098e76f1bd8235c99211a71ed976eb0eb116e20eb3edd99968c107a3962ae4837c7e6c035d92dc7dc35bbdff881c9ac032b01e5f9dd4566d18145cdeea239a600d40b87bd9e47a5a5c5cdb03762cb193984642c3bd7f96cb4115e35b4bcec77d6556d9580cdb87e811f613dd2e49682ef0aa2173e64cccaee2b7de3aa20c25d11633d02b9448cc8cec0febf2d440189ef324e0ec90d2b9b01c010ed81c6f86cc0835f5a39f6e266fd4d5785c8021ff4439228c244c7fd7e31e8c7c5fb68e67ff08d6e43ac4a39debce82d94e7390cc7b176823a6e945fd01f507b9cd66e54f7fe3202ce849ad82737f0dc2e54ba22d6f38e7c283a2911be610604ff5456b63183cd92cbaa20c495d6e73b86ba75f8ec8fdb006d12da05945ea9014c31b1fe4b52a06363061dc8bffe1a95311fbae4a6ed16e333e528e95afbd23de78f945bc41c6032e78ed1a3e4582ce64b2613ec22f8146fa706f5f140e40064174cdd040f71c20351d719fc07b6e8080840ab773d4573f07aa7f9ac2ded033f9ae22ba18d4aaf98d85b5e381cc7177c99c27a306f6511d0def1fc262cb27bd6a24c9051f01520b088c449057a48b1916d9398a4cc4d9f0e02b99f10c50c03d6b8121b11482834c4158c2d325575516e6162070ca3fc7c6bf67f855808d9131edfb28b2ed1d102cb441c63c9d36a70960a9770ac8fd5d9f64df406bcd07b709881e1429bf334ee58c0500dcc45527a9ff59fac44a4bfb152192ef732d562a56bb49c8a79c4324ae3636e58d7e1781a5d500e8bc190f0815eb18c1d40326750d3ac9404afea2c35243d0ee2c8a24a13144696f0dc4e293f0690aa81baaa65c84938791bd0664dd051a84149f23aaaa620373f5f3f60860d354b05c41fccb8c05c421c0e3256c82386017a3860b762a0df327a46431fab1b30fc02", + "0x3a65787472696e7369635f696e646578": "0x00000000", + "0x3a6772616e6470615f617574686f726974696573": "0x01200e6d7d1afbcc6547b92995a394ba0daed07a2420be08220a5a1336c6731f0bfa0100000000000000fcd5f87a6fd5707a25122a01b4dac0a8482259df7d42a9a096606df1320df08d0100000000000000e1b68fbd84333e31486c08e6153d9a1415b2e7e71b413702b7d64e9b631184a1010000000000000036be9069cdb4a8a07ecd51f257875150f0a8a1be44a10d9d98dabf10a030aef401000000000000006c878e33b83c20324238d22240f735457b6fba544b383e70bb62a27b57380c810100000000000000d9c056c98ca0e6b4eb7f5c58c007c1db7be0fe1f3776108f797dd4990d1ccc3301000000000000004bea0b37e0cce9bddd80835fa2bfd5606f5dcfb8388bbb10b10c483f0856cf1401000000000000004ee66173993dd0db5d628c4c9cb61a27b76611ad3c3925947f0d0011ee2c5dcc0100000000000000", + "0x3d9cad2baf702e20b136f4c8900cd8024e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x3f1467a096bcd71a5b6a0c8155e20810308ce9615de0775a82f8a94dc3d285a1": "0x01", + "0x3f1467a096bcd71a5b6a0c8155e208104e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x3fba98689ebed1138735e0e7a5a790ab4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x3fba98689ebed1138735e0e7a5a790abee99a84ccbfb4b82e714617e5e06f6f7": "0xd0070000", + "0x42b50b77ef717947e7043bb52127d6654e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x4da2c41eaffa8e1a791c5d65beeefd1f028685274e698e781f7f2766cba0cc8300000000": "0x200500000003000000040000000200000001000000060000000000000007000000abc3f086f5ac20eaab792c75933b2e196307835a61a955be82aa63bc0ff9617a06000000201efc23c0b51ad609ab670ecf45807e31acbd8e7e5cb7c07cf49ee42992d2867c882d72965e642677583b333b2d173ac94b5fd6c405c76184bb14293be748a13b6a8570b9c6408e54bacf123cc2bb1b0f087f9c149147d0005badba63a5a4ac01a8e61ffacafaf546283dc92d14d7cc70ea0151a5dd81fdf73ff5a2951f2b6037669a10892119453e9feb4e3f1ee8e028916cc3240022920ad643846fbdbee816042f07fc5268f13c026bbe199d63e6ac77a0c2a780f71cda05cee5a6f1b3f11f0e07a51d3213842f8e9363ce8e444255990a225f87e80a3d651db7841e1a0205d822d4088b20dca29a580a577a97d6f024bb24c9550bebdfd7d2d18e946a1c7d000000000000000000000000000000000000000100000000000000", + "0x4da2c41eaffa8e1a791c5d65beeefd1f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0x4da2c41eaffa8e1a791c5d65beeefd1fff4a51b74593c3708682038efe5323b5": "0x00000000", + "0x50e709b04947c0cd2f04727ef76e88f64e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x5c0d1176a568c1f92944340dbfed9e9c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b": "0x52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649", + "0x5f9cc45b7a00c5899361e1c6099678dc4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", + "0x5f9cc45b7a00c5899361e1c6099678dc8a2d09463effcc78a22d75b9cb87dffc": "0x0000000000000000", + "0x5f9cc45b7a00c5899361e1c6099678dcd47cb8f5328af743ddfb361e7180e7fcbb1bdbcacd6ac9340000000000000000": "0x00000000", + "0x63f78c98723ddc9073523ef3beefda0c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x6a0da05ca59913bc38a8630590f2627c2a351b6a99a5b21324516e668bb86a57": "0x00", + "0x6a0da05ca59913bc38a8630590f2627c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x6ac983d82528bf1595ab26438ae5b2cf4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x6cf4040bbce30824850f1a4823d8c65f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x70f943199f1a2dde80afdaf3f447db834e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x7474449cca95dc5d0c00e71735a6d17d4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x94eadf0156a8ad5156507773d0471e4a16973e1142f5bd30d9464076794007db": "0x00", + "0x94eadf0156a8ad5156507773d0471e4a1e8de4295679f32032acb318db364135": "0x00", + "0x94eadf0156a8ad5156507773d0471e4a4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x94eadf0156a8ad5156507773d0471e4a64fb6e378f53d72f7859ad0e6b6d8810": "0x0000000000", + "0x94eadf0156a8ad5156507773d0471e4a9ce0310edffce7a01a96c2039f92dd10": "0x01000000", + "0x94eadf0156a8ad5156507773d0471e4ab8ebad86f546c7e0b135a4212aace339": "0x00", + "0x9ba1b78972885c5d3fc221d6771e8ba24e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x9ba1b78972885c5d3fc221d6771e8ba29611a984bbd04e2fd39f97bbc006115f": "0x01", + "0x9ba1b78972885c5d3fc221d6771e8ba2fe6d4a58cccf03d052c50ccbfa0311c7": "0x52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649", + "0xa8c65209d47ee80f56b0011e8fd91f504e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xb341e3a63e58a188839b242d17f8c9f82586833f834350b4d435d5fd269ecc8b": "0x200500000003000000040000000200000001000000060000000000000007000000", + "0xb341e3a63e58a188839b242d17f8c9f84e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xb341e3a63e58a188839b242d17f8c9f87a50c904b368210021127f9238883a6e": "0x201efc23c0b51ad609ab670ecf45807e31acbd8e7e5cb7c07cf49ee42992d2867c882d72965e642677583b333b2d173ac94b5fd6c405c76184bb14293be748a13b6a8570b9c6408e54bacf123cc2bb1b0f087f9c149147d0005badba63a5a4ac01a8e61ffacafaf546283dc92d14d7cc70ea0151a5dd81fdf73ff5a2951f2b6037669a10892119453e9feb4e3f1ee8e028916cc3240022920ad643846fbdbee816042f07fc5268f13c026bbe199d63e6ac77a0c2a780f71cda05cee5a6f1b3f11f0e07a51d3213842f8e9363ce8e444255990a225f87e80a3d651db7841e1a0205d822d4088b20dca29a580a577a97d6f024bb24c9550bebdfd7d2d18e946a1c7d", + "0xb341e3a63e58a188839b242d17f8c9f8b5cab3380174032968897a4c3ce57c0a": "0x00000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f308ce9615de0775a82f8a94dc3d285a1": "0x01", + "0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x0000362b4c8ee30d0000000000000000", + "0xca32a41f4b3ed515863dc0a38697f84e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xcd710b30bd2eab0352ddcc26417aa1944e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xcd710b30bd2eab0352ddcc26417aa1949f4993f016e2d2f8e5f43be7bb259486": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb319b9aeb2f5add22992ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f": "0xe1b68fbd84333e31486c08e6153d9a1415b2e7e71b413702b7d64e9b631184a1d2644c1ab2c63a3ad8d40ad70d4b260969e3abfe6d7e6665f50dc9f6365c9d2aee93e26259decb89afcf17ef2aa0fa2db2e1042fb8f56ecfb24d19eae8629878a8e61ffacafaf546283dc92d14d7cc70ea0151a5dd81fdf73ff5a2951f2b6037244f3421b310c68646e99cdbf4963e02067601f57756b072a4b19431448c186e2c57f81fd311c1ab53813c6817fe67f8947f8d39258252663b3384ab4195494d039d065fe4f9234f0a4f13cc3ae585f2691e9c25afa469618abb6645111f607a53", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3328718e032416872520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a": "0xfcd5f87a6fd5707a25122a01b4dac0a8482259df7d42a9a096606df1320df08d38757d0de00a0c739e7d7984ef4bc01161bd61e198b7c01b618425c16bb5bd5f48a910c0af90898f11bd57d37ceaea53c78994f8e1833a7ade483c9a84bde055669a10892119453e9feb4e3f1ee8e028916cc3240022920ad643846fbdbee81668bf52c482630a8d1511f2edd14f34127a7d7082219cccf7fd4c6ecdb535f80df6f8fe475130d21165446a02fb1dbce3a7bf36412e5d98f4f0473aed9252f34903a90c2bb6d3b7000020f6152fe2e5002fa970fd1f42aafb6c8edda8dacc2ea77e", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb33bb8d7990ae3975438f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404": "0x36be9069cdb4a8a07ecd51f257875150f0a8a1be44a10d9d98dabf10a030aef4764186bc30fd5a02477f19948dc723d6d57ab174debd4f80ed6038ec960bfe218e95b9b5b4dc69790b67b566567ca8bf8cdef3a3a8bb65393c0d1d1c87cd2d2c882d72965e642677583b333b2d173ac94b5fd6c405c76184bb14293be748a13b821271c99c958b9220f1771d9f5e29af969edfa865631dba31e1ab7bc0582b752496f28d887d84705c6dae98aee8bf90fc5ad10bb5545eca1de6b68425b70f7c0307d29bbf6a5c4061c2157b44fda33b7bb4ec52a5a0305668c74688cedf288d58", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb393c0875f4080dabc8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47": "0x4ee66173993dd0db5d628c4c9cb61a27b76611ad3c3925947f0d0011ee2c5dccda6b2df18f0f9001a6dcf1d301b92534fe9b1f3ccfa10c49449fee93adaa834992156f54a114ee191415898f2da013d9db6a5362d6b36330d5fc23e27360ab66d822d4088b20dca29a580a577a97d6f024bb24c9550bebdfd7d2d18e946a1c7d481538f8c2c011a76d7d57db11c2789a5e83b0f9680dc6d26211d2f9c021ae4c4e262811acdfe94528bfc3c65036080426a0e1301b9ada8d687a70ffcae99c26025e84e95ed043e387ddb8668176b42f8e2773ddd84f7f58a6d9bf436a4b527986", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3c25dd840975e8979fa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00": "0x4bea0b37e0cce9bddd80835fa2bfd5606f5dcfb8388bbb10b10c483f0856cf14720537e2c1c554654d73b3889c3ef4c3c2f95a65dd3f7c185ebe4afebed78372560d90ca51e9c9481b8a9810060e04d0708d246714960439f804e5c6f40ca651042f07fc5268f13c026bbe199d63e6ac77a0c2a780f71cda05cee5a6f1b3f11ffab485e87ed1537d089df521edf983a777c57065a702d7ed2b6a2926f31da74f64d59feddb3d00316a55906953fb3db8985797472bd2e6c7ea1ab730cc339d7f033f1a6d47fe86f88934e4b83b9fae903b92b5dcf4fec97d5e3e8bf4f39df03685", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3d560e0b6940e074462475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a": "0x0e6d7d1afbcc6547b92995a394ba0daed07a2420be08220a5a1336c6731f0bfaa076ef1280d768051f21d060623da3ab5b56944d681d303ed2d4bf658c5bed3586975a37211f8704e947a365b720f7a3e2757988eaa7d0f197e83dba355ef7430e07a51d3213842f8e9363ce8e444255990a225f87e80a3d651db7841e1a0205ec60e71fe4a567ef9fef99d4bbf37ffae70564b41aa6f94ef0317c13e0a5477bf49eae66a0ac9f610316906ec8f1a0928e20d7059d76a5ca53cbcb5a9b50dd3c034f68c5661a41930c82f26a662276bf89f33467e1c850f2fb8ef687fe43d62276", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3dc18ebe8d771cfa002ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864": "0xd9c056c98ca0e6b4eb7f5c58c007c1db7be0fe1f3776108f797dd4990d1ccc33bab3cccdcc34401e9b3971b96a662686cf755aa869a5c4b762199ce531b12c5bc4a980da30939d5bb9e4a734d12bf81259ae286aa21fa4b65405347fa40eff351efc23c0b51ad609ab670ecf45807e31acbd8e7e5cb7c07cf49ee42992d2867c4c64d3f06d28adeb36a892fdaccecace150bec891f04694448a60b74fa469c22160ea09c5717270e958a3da42673fa011613a9539b2e4ebcad8626bc117ca04a020019a8bb188f8145d02fa855e9c36e9914457d37c500e03634b5223aa5702474", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3df32aff68041374f02a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16": "0x6c878e33b83c20324238d22240f735457b6fba544b383e70bb62a27b57380c817c94715e5dd8ab54221b1b6b2bfa5666f593f28a92a18e28052531de1bd80813d2f9d537ffa59919a4028afdb627c14c14c97a1547e13e8e82203d2049b15b1a6a8570b9c6408e54bacf123cc2bb1b0f087f9c149147d0005badba63a5a4ac0116c69ea8d595e80b6736f44be1eaeeef2ac9c04a803cc4fd944364cb0d617a33306ac5c772fe858942f92b6e28bd82fb7dd8cdd25f9a4626c1b0eee075fcb53102fb0330356e63a35dd930bc74525edf28b3bf5eb44aab9e9e4962c8309aaba6a6", + "0xcec5070d609dd3497f72bde07fc96ba04e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950091b1bd4e8d4c12061756469802496f28d887d84705c6dae98aee8bf90fc5ad10bb5545eca1de6b68425b70f7c": "0x38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195009ab51029a10e53570617261800e07a51d3213842f8e9363ce8e444255990a225f87e80a3d651db7841e1a0205": "0x62475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19500a3d203cf823b13d6173676e80821271c99c958b9220f1771d9f5e29af969edfa865631dba31e1ab7bc0582b75": "0x38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19500d1064d79ff558056772616e800e6d7d1afbcc6547b92995a394ba0daed07a2420be08220a5a1336c6731f0bfa": "0x62475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195012b62e212b6a7a9c696d6f6e808e95b9b5b4dc69790b67b566567ca8bf8cdef3a3a8bb65393c0d1d1c87cd2d2c": "0x38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195012fefbc5e5cee2846173676e80fab485e87ed1537d089df521edf983a777c57065a702d7ed2b6a2926f31da74f": "0xfa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950149cf457032f53e57061726180d822d4088b20dca29a580a577a97d6f024bb24c9550bebdfd7d2d18e946a1c7d": "0x8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19501b1525326b5d47776772616e80fcd5f87a6fd5707a25122a01b4dac0a8482259df7d42a9a096606df1320df08d": "0x520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19501e69501baac264d4696d6f6e80ee93e26259decb89afcf17ef2aa0fa2db2e1042fb8f56ecfb24d19eae8629878": "0x92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195021e85cbadb3ce9a26772616e806c878e33b83c20324238d22240f735457b6fba544b383e70bb62a27b57380c81": "0x02a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19502d2937d2d9650f057061726180a8e61ffacafaf546283dc92d14d7cc70ea0151a5dd81fdf73ff5a2951f2b6037": "0x92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19502e5e3ed1cdc323ab626565668402fb0330356e63a35dd930bc74525edf28b3bf5eb44aab9e9e4962c8309aaba6a6": "0x02a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19503639d22ceafce3266265656684020019a8bb188f8145d02fa855e9c36e9914457d37c500e03634b5223aa5702474": "0x02ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19503c0791148c7780b8626162658038757d0de00a0c739e7d7984ef4bc01161bd61e198b7c01b618425c16bb5bd5f": "0x520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19503c75eb9438a505fc6261626580a076ef1280d768051f21d060623da3ab5b56944d681d303ed2d4bf658c5bed35": "0x62475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19503d7dc9205a149f6a6175646980306ac5c772fe858942f92b6e28bd82fb7dd8cdd25f9a4626c1b0eee075fcb531": "0x02a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19503eaa3e59477bc9506261626580720537e2c1c554654d73b3889c3ef4c3c2f95a65dd3f7c185ebe4afebed78372": "0xfa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950417ebe2c60c84ed5626565668403a90c2bb6d3b7000020f6152fe2e5002fa970fd1f42aafb6c8edda8dacc2ea77e": "0x520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950438ac98f6d864839696d6f6e80d2f9d537ffa59919a4028afdb627c14c14c97a1547e13e8e82203d2049b15b1a": "0x02a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195043d506aedab0d2ce696d6f6e8048a910c0af90898f11bd57d37ceaea53c78994f8e1833a7ade483c9a84bde055": "0x520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195043f25e7a03a30387696d6f6e8092156f54a114ee191415898f2da013d9db6a5362d6b36330d5fc23e27360ab66": "0x8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195054435a901133fb946173676e8016c69ea8d595e80b6736f44be1eaeeef2ac9c04a803cc4fd944364cb0d617a33": "0x02a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950585cf1f6f8e46326696d6f6e8086975a37211f8704e947a365b720f7a3e2757988eaa7d0f197e83dba355ef743": "0x62475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950636f684eb09a15046772616e80d9c056c98ca0e6b4eb7f5c58c007c1db7be0fe1f3776108f797dd4990d1ccc33": "0x02ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195068dec3fce5ade0966261626580da6b2df18f0f9001a6dcf1d301b92534fe9b1f3ccfa10c49449fee93adaa8349": "0x8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195075a33a2ed5ac2cdc6265656684034f68c5661a41930c82f26a662276bf89f33467e1c850f2fb8ef687fe43d62276": "0x62475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950776743a4ae520892617564698064d59feddb3d00316a55906953fb3db8985797472bd2e6c7ea1ab730cc339d7f": "0xfa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19507acca078b878d43a70617261801efc23c0b51ad609ab670ecf45807e31acbd8e7e5cb7c07cf49ee42992d2867c": "0x02ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19507d9c46786caf74af6261626580d2644c1ab2c63a3ad8d40ad70d4b260969e3abfe6d7e6665f50dc9f6365c9d2a": "0x92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19507f532159f03d44eb6175646980f49eae66a0ac9f610316906ec8f1a0928e20d7059d76a5ca53cbcb5a9b50dd3c": "0x62475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19508248d97b4996007070617261806a8570b9c6408e54bacf123cc2bb1b0f087f9c149147d0005badba63a5a4ac01": "0x02a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195097e3e605d1b3579b6173676e804c64d3f06d28adeb36a892fdaccecace150bec891f04694448a60b74fa469c22": "0x02ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509df5f4072c4244956261626580764186bc30fd5a02477f19948dc723d6d57ab174debd4f80ed6038ec960bfe21": "0x38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950a00d3cb0425699a66772616e804bea0b37e0cce9bddd80835fa2bfd5606f5dcfb8388bbb10b10c483f0856cf14": "0xfa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950a068f246c1094c1462656566840307d29bbf6a5c4061c2157b44fda33b7bb4ec52a5a0305668c74688cedf288d58": "0x38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950a31727416d0095b96772616e80e1b68fbd84333e31486c08e6153d9a1415b2e7e71b413702b7d64e9b631184a1": "0x92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950a9e62b8a5c8760f06265656684033f1a6d47fe86f88934e4b83b9fae903b92b5dcf4fec97d5e3e8bf4f39df03685": "0xfa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950ab7b30d24546522861756469804e262811acdfe94528bfc3c65036080426a0e1301b9ada8d687a70ffcae99c26": "0x8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950bad35ce880ec90d4696d6f6e80c4a980da30939d5bb9e4a734d12bf81259ae286aa21fa4b65405347fa40eff35": "0x02ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d1e1b030b162ca447061726180042f07fc5268f13c026bbe199d63e6ac77a0c2a780f71cda05cee5a6f1b3f11f": "0xfa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d31ed6cbd51d9f636265656684039d065fe4f9234f0a4f13cc3ae585f2691e9c25afa469618abb6645111f607a53": "0x92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d46d2cb2a4d496b46265656684025e84e95ed043e387ddb8668176b42f8e2773ddd84f7f58a6d9bf436a4b527986": "0x8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d7ce35a3ce71c3d76175646980160ea09c5717270e958a3da42673fa011613a9539b2e4ebcad8626bc117ca04a": "0x02ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950deeb3985cefbdfa47061726180882d72965e642677583b333b2d173ac94b5fd6c405c76184bb14293be748a13b": "0x38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950e193783dd6b845ea6173676e80ec60e71fe4a567ef9fef99d4bbf37ffae70564b41aa6f94ef0317c13e0a5477b": "0x62475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950e592f5ef74f560666173676e8068bf52c482630a8d1511f2edd14f34127a7d7082219cccf7fd4c6ecdb535f80d": "0x520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950e7240ce913e160eb6261626580bab3cccdcc34401e9b3971b96a662686cf755aa869a5c4b762199ce531b12c5b": "0x02ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950e887ec3d30b64e896173676e80481538f8c2c011a76d7d57db11c2789a5e83b0f9680dc6d26211d2f9c021ae4c": "0x8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950ed0b865484219eb06173676e80244f3421b310c68646e99cdbf4963e02067601f57756b072a4b19431448c186e": "0x92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950ee41af0530f856db6772616e8036be9069cdb4a8a07ecd51f257875150f0a8a1be44a10d9d98dabf10a030aef4": "0x38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950ef9482dba3e5b0d862616265807c94715e5dd8ab54221b1b6b2bfa5666f593f28a92a18e28052531de1bd80813": "0x02a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f5bc812467e867ac7061726180669a10892119453e9feb4e3f1ee8e028916cc3240022920ad643846fbdbee816": "0x520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f6584bfaf470c1b26175646980f6f8fe475130d21165446a02fb1dbce3a7bf36412e5d98f4f0473aed9252f349": "0x520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f7aec8a47707294b61756469802c57f81fd311c1ab53813c6817fe67f8947f8d39258252663b3384ab4195494d": "0x92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f8df002813b43b80696d6f6e80560d90ca51e9c9481b8a9810060e04d0708d246714960439f804e5c6f40ca651": "0xfa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950feca8028a77ba7626772616e804ee66173993dd0db5d628c4c9cb61a27b76611ad3c3925947f0d0011ee2c5dcc": "0x8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47", + "0xcec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903": "0x2062475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a040402a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b1602ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864fa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a008062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47", + "0xcec5070d609dd3497f72bde07fc96ba0e0cdd062e6eaf24295ad4ccfc41d4609": "0x2062475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a0e6d7d1afbcc6547b92995a394ba0daed07a2420be08220a5a1336c6731f0bfaa076ef1280d768051f21d060623da3ab5b56944d681d303ed2d4bf658c5bed3586975a37211f8704e947a365b720f7a3e2757988eaa7d0f197e83dba355ef7430e07a51d3213842f8e9363ce8e444255990a225f87e80a3d651db7841e1a0205ec60e71fe4a567ef9fef99d4bbf37ffae70564b41aa6f94ef0317c13e0a5477bf49eae66a0ac9f610316906ec8f1a0928e20d7059d76a5ca53cbcb5a9b50dd3c034f68c5661a41930c82f26a662276bf89f33467e1c850f2fb8ef687fe43d62276520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022afcd5f87a6fd5707a25122a01b4dac0a8482259df7d42a9a096606df1320df08d38757d0de00a0c739e7d7984ef4bc01161bd61e198b7c01b618425c16bb5bd5f48a910c0af90898f11bd57d37ceaea53c78994f8e1833a7ade483c9a84bde055669a10892119453e9feb4e3f1ee8e028916cc3240022920ad643846fbdbee81668bf52c482630a8d1511f2edd14f34127a7d7082219cccf7fd4c6ecdb535f80df6f8fe475130d21165446a02fb1dbce3a7bf36412e5d98f4f0473aed9252f34903a90c2bb6d3b7000020f6152fe2e5002fa970fd1f42aafb6c8edda8dacc2ea77e92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6fe1b68fbd84333e31486c08e6153d9a1415b2e7e71b413702b7d64e9b631184a1d2644c1ab2c63a3ad8d40ad70d4b260969e3abfe6d7e6665f50dc9f6365c9d2aee93e26259decb89afcf17ef2aa0fa2db2e1042fb8f56ecfb24d19eae8629878a8e61ffacafaf546283dc92d14d7cc70ea0151a5dd81fdf73ff5a2951f2b6037244f3421b310c68646e99cdbf4963e02067601f57756b072a4b19431448c186e2c57f81fd311c1ab53813c6817fe67f8947f8d39258252663b3384ab4195494d039d065fe4f9234f0a4f13cc3ae585f2691e9c25afa469618abb6645111f607a5338f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a040436be9069cdb4a8a07ecd51f257875150f0a8a1be44a10d9d98dabf10a030aef4764186bc30fd5a02477f19948dc723d6d57ab174debd4f80ed6038ec960bfe218e95b9b5b4dc69790b67b566567ca8bf8cdef3a3a8bb65393c0d1d1c87cd2d2c882d72965e642677583b333b2d173ac94b5fd6c405c76184bb14293be748a13b821271c99c958b9220f1771d9f5e29af969edfa865631dba31e1ab7bc0582b752496f28d887d84705c6dae98aee8bf90fc5ad10bb5545eca1de6b68425b70f7c0307d29bbf6a5c4061c2157b44fda33b7bb4ec52a5a0305668c74688cedf288d5802a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b166c878e33b83c20324238d22240f735457b6fba544b383e70bb62a27b57380c817c94715e5dd8ab54221b1b6b2bfa5666f593f28a92a18e28052531de1bd80813d2f9d537ffa59919a4028afdb627c14c14c97a1547e13e8e82203d2049b15b1a6a8570b9c6408e54bacf123cc2bb1b0f087f9c149147d0005badba63a5a4ac0116c69ea8d595e80b6736f44be1eaeeef2ac9c04a803cc4fd944364cb0d617a33306ac5c772fe858942f92b6e28bd82fb7dd8cdd25f9a4626c1b0eee075fcb53102fb0330356e63a35dd930bc74525edf28b3bf5eb44aab9e9e4962c8309aaba6a602ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864d9c056c98ca0e6b4eb7f5c58c007c1db7be0fe1f3776108f797dd4990d1ccc33bab3cccdcc34401e9b3971b96a662686cf755aa869a5c4b762199ce531b12c5bc4a980da30939d5bb9e4a734d12bf81259ae286aa21fa4b65405347fa40eff351efc23c0b51ad609ab670ecf45807e31acbd8e7e5cb7c07cf49ee42992d2867c4c64d3f06d28adeb36a892fdaccecace150bec891f04694448a60b74fa469c22160ea09c5717270e958a3da42673fa011613a9539b2e4ebcad8626bc117ca04a020019a8bb188f8145d02fa855e9c36e9914457d37c500e03634b5223aa5702474fa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a004bea0b37e0cce9bddd80835fa2bfd5606f5dcfb8388bbb10b10c483f0856cf14720537e2c1c554654d73b3889c3ef4c3c2f95a65dd3f7c185ebe4afebed78372560d90ca51e9c9481b8a9810060e04d0708d246714960439f804e5c6f40ca651042f07fc5268f13c026bbe199d63e6ac77a0c2a780f71cda05cee5a6f1b3f11ffab485e87ed1537d089df521edf983a777c57065a702d7ed2b6a2926f31da74f64d59feddb3d00316a55906953fb3db8985797472bd2e6c7ea1ab730cc339d7f033f1a6d47fe86f88934e4b83b9fae903b92b5dcf4fec97d5e3e8bf4f39df036858062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab474ee66173993dd0db5d628c4c9cb61a27b76611ad3c3925947f0d0011ee2c5dccda6b2df18f0f9001a6dcf1d301b92534fe9b1f3ccfa10c49449fee93adaa834992156f54a114ee191415898f2da013d9db6a5362d6b36330d5fc23e27360ab66d822d4088b20dca29a580a577a97d6f024bb24c9550bebdfd7d2d18e946a1c7d481538f8c2c011a76d7d57db11c2789a5e83b0f9680dc6d26211d2f9c021ae4c4e262811acdfe94528bfc3c65036080426a0e1301b9ada8d687a70ffcae99c26025e84e95ed043e387ddb8668176b42f8e2773ddd84f7f58a6d9bf436a4b527986", + "0xd57bce545fb382c34570e5dfbf338f5e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xd5c41b52a371aa36c9254ce34324f2a54e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xd5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xd8bbe27baf3aa64bb483afabc240f68e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xd979a2ce97f43b91540066af95e5c2cd4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xda7d4185f8093e80caceb64da45219e34e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xe81713b6b40972bbcd298d67597a495f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xe81713b6b40972bbcd298d67597a495f9611a984bbd04e2fd39f97bbc006115f": "0x01", + "0xe81713b6b40972bbcd298d67597a495ffe6d4a58cccf03d052c50ccbfa0311c7": "0x52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649", + "0xf0c365c3cf59d671eb72da0e7a4113c44e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xf5207f03cfdce586301014700e2c25934e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xf9922c78cfa3c316d27a3eb48145ab1b4e7b9012096b41c4eb3aaf947f6ea429": "0x0400" + }, + "childrenDefault": {} + } + } +} diff --git a/polkadot/node/service/chain-specs/westend.json b/polkadot/node/service/chain-specs/westend.json new file mode 100644 index 0000000000000000000000000000000000000000..629dfc86ae11576882819a10d0d2d8c2bfc1408f --- /dev/null +++ b/polkadot/node/service/chain-specs/westend.json @@ -0,0 +1,156 @@ +{ + "name": "Westend", + "id": "westend2", + "bootNodes": [ + "/dns/0.westend.paritytech.net/tcp/30333/p2p/12D3KooWKer94o1REDPtAhjtYR4SdLehnSrN8PEhBnZm5NBoCrMC", + "/dns/0.westend.paritytech.net/tcp/30334/ws/p2p/12D3KooWKer94o1REDPtAhjtYR4SdLehnSrN8PEhBnZm5NBoCrMC", + "/dns/1.westend.paritytech.net/tcp/30333/p2p/12D3KooWPVPzs42GvRBShdUMtFsk4SvnByrSdWqb6aeAAHvLMSLS", + "/dns/1.westend.paritytech.net/tcp/30334/ws/p2p/12D3KooWPVPzs42GvRBShdUMtFsk4SvnByrSdWqb6aeAAHvLMSLS", + "/dns/2.westend.paritytech.net/tcp/30333/p2p/12D3KooWByVpK92hMi9CzTjyFg9cPHDU5ariTM3EPMq9vdh5S5Po", + "/dns/2.westend.paritytech.net/tcp/30334/ws/p2p/12D3KooWByVpK92hMi9CzTjyFg9cPHDU5ariTM3EPMq9vdh5S5Po", + "/dns/3.westend.paritytech.net/tcp/30333/p2p/12D3KooWGi1tCpKXLMYED9y28QXLnwgD4neYb1Arqq4QpeV1Sv3K", + "/dns/3.westend.paritytech.net/tcp/30334/ws/p2p/12D3KooWGi1tCpKXLMYED9y28QXLnwgD4neYb1Arqq4QpeV1Sv3K", + "/dns/westend-connect-0.polkadot.io/tcp/443/wss/p2p/12D3KooWNg8iUqhux7X7voNU9Nty5pzehrFJwkQwg1CJnqN3CTzE", + "/dns/westend-connect-1.polkadot.io/tcp/443/wss/p2p/12D3KooWAq2A7UNFS6725XFatD5QW7iYBezTLdAUx1SmRkxN79Ne", + "/dns/boot.stake.plus/tcp/32333/p2p/12D3KooWK8fjVoSvMq5copQYMsdYreSGPGgcMbGMgbMDPfpf3sm7", + "/dns/boot.stake.plus/tcp/32334/wss/p2p/12D3KooWK8fjVoSvMq5copQYMsdYreSGPGgcMbGMgbMDPfpf3sm7", + "/dns/boot-node.helikon.io/tcp/7080/p2p/12D3KooWRFDPyT8vA8mLzh6dJoyujn4QNjeqi6Ch79eSMz9beKXC", + "/dns/boot-node.helikon.io/tcp/7082/wss/p2p/12D3KooWRFDPyT8vA8mLzh6dJoyujn4QNjeqi6Ch79eSMz9beKXC", + "/dns/westend.bootnode.amforc.com/tcp/30333/p2p/12D3KooWJ5y9ZgVepBQNW4aabrxgmnrApdVnscqgKWiUu4BNJbC8", + "/dns/westend.bootnode.amforc.com/tcp/30334/wss/p2p/12D3KooWJ5y9ZgVepBQNW4aabrxgmnrApdVnscqgKWiUu4BNJbC8", + "/dns/westend-bootnode.polkadotters.com/tcp/30333/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5", + "/dns/westend-bootnode.polkadotters.com/tcp/30334/wss/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5", + "/dns/boot-cr.gatotech.network/tcp/33300/p2p/12D3KooWQGR1vUhoy6mvQorFp3bZFn6NNezhQZ6NWnVV7tpFgoPd", + "/dns/boot-cr.gatotech.network/tcp/35300/wss/p2p/12D3KooWQGR1vUhoy6mvQorFp3bZFn6NNezhQZ6NWnVV7tpFgoPd", + "/dns/boot-westend.metaspan.io/tcp/33012/p2p/12D3KooWNTau7iG4G9cUJSwwt2QJP1W88pUf2SgqsHjRU2RL8pfa", + "/dns/boot-westend.metaspan.io/tcp/33015/ws/p2p/12D3KooWNTau7iG4G9cUJSwwt2QJP1W88pUf2SgqsHjRU2RL8pfa", + "/dns/boot-westend.metaspan.io/tcp/33016/wss/p2p/12D3KooWNTau7iG4G9cUJSwwt2QJP1W88pUf2SgqsHjRU2RL8pfa", + "/dns/westend-bootnode.turboflakes.io/tcp/30310/p2p/12D3KooWJvPDCZmReU46ghpCMJCPVUvUCav4WQdKtXQhZgJdH6tZ", + "/dns/westend-bootnode.turboflakes.io/tcp/30410/wss/p2p/12D3KooWJvPDCZmReU46ghpCMJCPVUvUCav4WQdKtXQhZgJdH6tZ", + "/dns/westend-boot-ng.dwellir.com/tcp/443/wss/p2p/12D3KooWJifoDhCL3swAKt7MWhFb7wLRFD9oG33AL3nAathmU24x", + "/dns/westend-boot-ng.dwellir.com/tcp/30335/p2p/12D3KooWJifoDhCL3swAKt7MWhFb7wLRFD9oG33AL3nAathmU24x", + "/dns/westend-bootnode.radiumblock.com/tcp/30335/wss/p2p/12D3KooWJBowJuX1TaWNWHt8Dz8z44BoCZunLCfFqxA2rLTn6TBD", + "/dns/westend-bootnode.radiumblock.com/tcp/30333/p2p/12D3KooWJBowJuX1TaWNWHt8Dz8z44BoCZunLCfFqxA2rLTn6TBD", + "/dns/wnd-bootnode.stakeworld.io/tcp/30320/p2p/12D3KooWBYdKipcNbrV5rCbgT5hco8HMLME7cE9hHC3ckqCKDuzP", + "/dns/wnd-bootnode.stakeworld.io/tcp/30321/ws/p2p/12D3KooWBYdKipcNbrV5rCbgT5hco8HMLME7cE9hHC3ckqCKDuzP", + "/dns/wnd-bootnode.stakeworld.io/tcp/30322/wss/p2p/12D3KooWBYdKipcNbrV5rCbgT5hco8HMLME7cE9hHC3ckqCKDuzP" + ], + "telemetryEndpoints": [ + [ + "wss://telemetry.polkadot.io/submit/", + 0 + ] + ], + "protocolId": "wnd2", + "properties": { + "ss58Format": 42, + "tokenDecimals": 12, + "tokenSymbol": "WND" + }, + "forkBlocks": null, + "badBlocks": [ + "0x53849a2121fe81fde85859dcebe8cc9c37791c01a9702ce65615b1dcb8ac53e5", + "0x66535350bf0d031dc15a0b6ee20165c0cd7ea49fec85685915f732e24d69e141" + ], + "consensusEngine": null, + "genesis": { + "raw": { + "top": { + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc69406b1b580f3fd70373207c005e38adff268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836": "0x047374616b696e672000407a10f35a0000000000000000000002", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950df2ec3df1d2fc39f6772616e80959cebf18fecb305b96fd998c95f850145f52cbbb64b3ef937c0575cc7ebd652": "0x9ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da90566b5cb12e1bb0dd3301e8ab40c6d0508264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d": "0x000000000300407a10f35a000000000000000000000000000000000000000000000000000000407a10f35a0000000000000000000000407a10f35a00000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a00000000ce6a96a3775ab416f268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade9803adc196911e491e08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d": "0x00", + "0x5f3e4907f716ac89b6347d15ececedcaea07de2b8f010516dca3f7ef52f7ac5a": "0x040000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6afdf816f281ad669fe59fe0f725f72759ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d": "0x047374616b696e672000407a10f35a0000000000000000000002", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9bb08f275d00049b315666c2c44130a106648d7f3382690650c681aba1b993cd11e54deb4df21a3a18c3e2177de9f7342": "0x0000000000000064a7b3b6e00d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000", + "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x041c77657374656e64", + "0x2b06af9719ac64d755623cda8ddd9b949f99a2ce711f3a31b2fc05604c93f179": "0x10a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a72bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e300174bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e", + "0x5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1": "0x32000000", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a0000000003adc196911e491e08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d": "0x0b00407a10f35a0b00407a10f35a00", + "0x2371e21684d2fae99bcb4d579242f74a8a2d09463effcc78a22d75b9cb87dffc": "0x0000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb35c69b53821debaa39ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d": "0x959cebf18fecb305b96fd998c95f850145f52cbbb64b3ef937c0575cc7ebd65272bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e300172bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e300172bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e300172bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e3001", + "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a00000000ce6a96a3775ab416f268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195024a1470c7a02f07e696d6f6e807ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a": "0xaebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934", + "0x3a636f6465": "0x0061736d0100000001ae022c60037f7f7f017f60027f7f017f60027f7f0060017f017e60017f0060047f7f7f7f0060037f7e7e0060017e017f6000017e60017e017e60017f017f60037e7e7f017e60027f7f017e60037f7f7e017e60017e0060027e7e0060037f7e7f017f60027f7e017e60047f7e7e7e017f6000017f60027f7e017f60000060037f7f7f0060057f7f7f7f7f0060027e7f017f60057f7f7f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60087e7e7e7e7e7e7e7e017f60077f7e7e7e7e7e7e0060027f7e0060067f7f7f7f7f7f0060057f7e7e7f7f0060057f7f7f7e7e0060057f7f7e7e7f0060047e7e7e7e017f60047f7f7e7e0060067f7e7e7f7f7f0060067f7f7f7e7e7f0060027e7f0060067f7f7f7f7e7e0060047f7e7e7f0060057f7e7e7e7e0060067f7e7e7e7e7f0002cc0a2203656e76066d656d6f727902001203656e76196578745f6c6f6767696e675f6c6f675f76657273696f6e5f31000603656e762a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f31000703656e76246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f31000803656e76296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f31000903656e761e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f31000a03656e761c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f31000403656e761a6578745f73746f726167655f726561645f76657273696f6e5f31000b03656e76376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f31000c03656e76286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f31000303656e76216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f31000d03656e761d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f31000e03656e761c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f31000e03656e761e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f31000703656e761d6578745f68617368696e675f74776f785f36345f76657273696f6e5f31000703656e76196578745f73746f726167655f7365745f76657273696f6e5f31000f03656e76206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f31000703656e76196578745f73746f726167655f6765745f76657273696f6e5f31000903656e761b6578745f73746f726167655f636c6561725f76657273696f6e5f31000e03656e76226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f31000e03656e76236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f32001003656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f31001103656e76346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f31001203656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f31000603656e76226578745f6d6973635f72756e74696d655f76657273696f6e5f76657273696f6e5f31000903656e76206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f31000703656e761e6578745f73746f726167655f6e6578745f6b65795f76657273696f6e5f31000903656e761a6578745f73746f726167655f726f6f745f76657273696f6e5f31000803656e76226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f31000903656e76236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f31001003656e761c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f31000e03656e76236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f31001303656e76256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f31001403656e76256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f310014038b0589050a0a040400000a0a0c1515151616021600151517000101020102020201180403191a161600170101010a1b0101011601010005010100010100000100040101020216021602000101160102010102040202010216051602041616160a0101021c011d01010202040200171e1f160217020104011616161616161616161616161616161616161616161616160216161616160216161616160204021601020416160202020202020202160202021604020201020202160216170216020516161604161604021602021620060f020204150a0402020216020202020202020402020202020405020219021602160a2102021616020216020402162202021602232419040505160204040001010201021602020101020401010201010404040204020204170a020502021602130125020216040404161616040202020404160204010202020202020404040404040404040404040404041502021602020216162605260a02020204021602161702020201020202021616160416020202020202040202020402020104041604040402020404040416051602021602160202021616161902040202160216160202020402000604040202021a02040402020202020202020202021504040404041508020217020216020404021604040204040202040202020202020202020216020216020404020204042717160202021604010216020201020201160202161616010404020402020216051f28020404010201040402020202150416160404040202040501000402040204020202040416160404020402020202161616040404040404040c0c0c0c0c0c0c040c0c0c0c150c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0204040204020402160202160423160404040402040000000029292a2a2a2b0407017001ad01ad010619037f01418080c0000b7f0041a0abc7000b7f0041a0abc7000b07a2071f195f5f696e6469726563745f66756e6374696f6e5f7461626c65010009686173685f7465737400290c436f72655f76657273696f6e00ee0412436f72655f657865637574655f626c6f636b00ef0415436f72655f696e697469616c697a655f626c6f636b00f004114d657461646174615f6d6574616461746100f1041c426c6f636b4275696c6465725f6170706c795f65787472696e73696300f2041b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b00f30420426c6f636b4275696c6465725f696e686572656e745f65787472696e7369637300f4041c426c6f636b4275696c6465725f636865636b5f696e686572656e747300f60418426c6f636b4275696c6465725f72616e646f6d5f7365656400f7042b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e00f804214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b657200f9041850617261636861696e486f73745f76616c696461746f727300fb041950617261636861696e486f73745f647574795f726f7374657200fc041f50617261636861696e486f73745f6163746976655f70617261636861696e7300fd042850617261636861696e486f73745f676c6f62616c5f76616c69646174696f6e5f7363686564756c6500fe042350617261636861696e486f73745f6c6f63616c5f76616c69646174696f6e5f6461746100ff041c50617261636861696e486f73745f70617261636861696e5f636f64650080051750617261636861696e486f73745f6765745f68656164730081051d50617261636861696e486f73745f7369676e696e675f636f6e746578740082051e4772616e6470614170695f6772616e6470615f617574686f72697469657300830515426162654170695f636f6e66696775726174696f6e0084051b426162654170695f63757272656e745f65706f63685f737461727400850521417574686f72697479446973636f766572794170695f617574686f7269746965730086052153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b6579730087051f53657373696f6e4b6579735f6465636f64655f73657373696f6e5f6b6579730088051d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e6365008905205472616e73616374696f6e5061796d656e744170695f71756572795f696e666f008a050a5f5f646174615f656e6403010b5f5f686561705f62617365030209bf02010041010bac01393d5047840148496c51d1015ba503b602b102b202b802df02ab04a4045eb502d0043536375f405254555657586667686a6b6f6d6e4d4e7efc01f503fb01fa01f301bf04f901f801f701f601f401f201ff01fe01a802a902aa02b902bd029301be04bd04e602a603cc04b003d204d4049c059b059d05ea04e904e702dd04dc04e802df04e804c804c904ec04eb04ed04f101ee01e902fd01a702c704ea02f403f303eb02fe03aa03a903ab03b1038f048e04ec02ac04d202d002ed02db02d803d703cc03af03ae03a703fb03fa03ee02e603d904d804ef02e7048d058c05f002970593049204f102ad04bb02ba02f202bc02da029b04f302d103d003f402e5039c04ac03fd038301fc03da03d90391049004990498049a04c204c104c004e004ca04d304d604d504de048e059a05cd04cf049e059f0591010acdd13889050600200010220b0600200010040b0600200010240b0600200010050b0a0020002001200210260b2801017f0240200210042203450d002003200020022001200120024b1b10a1051a200010050b20030b0600200010280b1c01017f0240200010042201450d0020014100200010a0051a0b20010bff0202017f037e230041206b220224002001ad42adfed5e4d485fda8d8007e42b9e0007c210302400240024002400240200141084b0d00200141014b0d0120010d02420021040c030b0240200141104b0d00200241106a2000290000200385420042adfed5e4d485fda8d800420010a605200241186a29030020022903107c200120006a41786a2900008521040c040b200120006a41786a2900002105200321040340200029000020048542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e2003852103200041086a2100200442cf829ebbefefde82147c2104200141786a220141084b0d000b200320058521040c030b0240200141034b0d00200120006a417e6a33000042108620003300008420038521040c030b200120006a417c6a35000042208620003500008420038521040c020b200031000021040b200420038521040b20022004420042adfed5e4d485fda8d800420010a605200241086a290300210420022903002103200241206a2400200420037c42c300850b0500102b000b2400410041d4b3c000ad4280808080f0008441dbb3c000ad4280808080a00484100000000b1100419080c000411141a480c000102d000b4701017f230041206b22032400200341146a41003602002003419ca8c700360210200342013702042003200136021c200320003602182003200341186a36020020032002103a000bdd0101047f0240024002400240200041046a2802002203200041086a28020022046b200220016b2202490d00200028020021050c010b200420026a22052004490d01200341017422062005200620054b1b22064100480d010240024002402003450d00200028020022050d010b024020060d00410121050c020b2006102122050d010c040b024020032006460d00200520032006102521050b2005450d03200041086a28020021040b20002005360200200041046a20063602000b200520046a2001200210a1051a200041086a200420026a3602000f0b102c000b102a000b8b0301067f230041306b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240024002400240200141146a2802000d00200621070c010b024020040d004100410041cc80c0001030000b024002402006410f4b0d00200341046a280200450d010b200620066a220720064f0d010b4100210741012105200241086a21060c010b2007417f4c0d01200241086a2106024020070d0041002107410121050c010b200710212205450d020b20024100360210200220053602082002200736020c2002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241146a41dc80c000200241186a10310d0220002006290200370200200041086a200641086a280200360200200241306a24000f0b1032000b1033000b41f480c0004133200241186a41a881c00041b881c0001034000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c2003419884c000360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a2002103a000bba06010a7f230041306b22032400200341246a2001360200200341033a002820034280808080800437030820032000360220410021042003410036021820034100360210024002400240024020022802082205450d0020022802002106200228020422072002410c6a2802002208200820074b1b2209450d01200241146a280200210a2002280210210b41012108200020062802002006280204200128020c1100000d03200541106a2102200641086a2100410121040240024003402003200241746a28020036020c20032002410c6a2d00003a00282003200241786a280200360208200241086a28020021084100210541002101024002400240200241046a2802000e03010002010b2008200a4f0d032008410374210c41002101200b200c6a220c2802044102470d01200c28020028020021080b410121010b2003200836021420032001360210200228020021080240024002402002417c6a2802000e03010002010b2008200a4f0d0420084103742101200b20016a22012802044102470d01200128020028020021080b410121050b2003200836021c200320053602180240200241706a2802002208200a4f0d00200b20084103746a2208280200200341086a20082802041101000d06200420094f0d05200041046a210120002802002105200241206a2102200041086a210041012108200441016a2104200328022020052001280200200328022428020c110000450d010c070b0b2008200a41f088c0001030000b2008200a41e088c0001030000b2008200a41e088c0001030000b2002280200210620022802042207200241146a2802002208200820074b1b220a450d002002280210210241012108200020062802002006280204200128020c1100000d02200641086a21004101210403402002280200200341086a200241046a2802001101000d022004200a4f0d01200041046a210120002802002105200241086a2102200041086a210041012108200441016a2104200328022020052001280200200328022428020c110000450d000c030b0b0240200720044d0d00410121082003280220200620044103746a22022802002002280204200328022428020c1100000d020b410021080c010b410121080b200341306a240020080b0500102c000b0500102a000b7e01017f230041c0006b220524002005200136020c2005200036020820052003360214200520023602102005412c6a41023602002005413c6a41033602002005420237021c200541b0fcc200360218200541043602342005200541306a3602282005200541106a3602382005200541086a360230200541186a2004103a000b120020002802002001200120026a102e41000bcb0301047f230041106b22022400200028020021000240024002400240024002402001418001490d002002410036020c2001418010490d012002410c6a210302402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c050b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c040b0240024020002802082203200041046a280200460d00200028020021040c010b200341016a22042003490d02200341017422052004200520044b1b22054100480d020240024002402003450d00200028020022040d010b024020050d00410121040c020b2005102122040d010c050b024020032005460d00200420032005102521040b2004450d04200028020821030b20002004360200200041046a20053602000b200420036a20013a00002000200028020841016a3602080c040b20022001413f71418001723a000d20022001410676411f7141c001723a000c2002410c6a2103410221010c020b102c000b102a000b20002003200320016a102e0b200241106a240041000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41dc80c000200241086a10312101200241206a240020010b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241cc82c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41e482c000103a000b0b0020003502002001103e0b3401017f230041106b220224002002200136020c20022000360208200241a884c0003602042002419ca8c7003602002002103f000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241a083c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41b883c000103a000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241dc83c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41f483c000103a000b0d0020002802001a037f0c000b0bd20203027f017e037f230041306b22022400412721030240024020004290ce005a0d00200021040c010b412721030340200241096a20036a2205417c6a200020004290ce0080220442f0b17f7e7ca7220641ffff037141e4006e220741017441ea84c0006a2f00003b00002005417e6a2007419c7f6c20066a41ffff037141017441ea84c0006a2f00003b00002003417c6a2103200042ffc1d72f5621052004210020050d000b0b02402004a7220541e3004c0d00200241096a2003417e6a22036a2004a7220641ffff037141e4006e2205419c7f6c20066a41ffff037141017441ea84c0006a2f00003b00000b024002402005410a480d00200241096a2003417e6a22036a200541017441ea84c0006a2f00003b00000c010b200241096a2003417f6a22036a200541306a3a00000b2001419ca8c7004100200241096a20036a412720036b10412103200241306a240020030b6f01017f230041c0006b220124002001200036020c200141346a410136020020014201370224200141ccb3c0003602202001410536023c2001200141386a36023020012001410c6a360238200141106a200141206a102f410141d4b3c000410720012802102001280218108a0100000b0c00429ef392e9c28bc0b1400be80501067f20002802002205410171220620046a21070240024020054104710d00410021010c010b4100210802402002450d00200221092001210a03402008200a2d000041c00171418001466a2108200a41016a210a2009417f6a22090d000b0b200720026a20086b21070b412b418080c40020061b21080240024020002802084101460d004101210a200020082001200210420d012000280218200320042000411c6a28020028020c110000210a0c010b02402000410c6a280200220920074b0d004101210a200020082001200210420d012000280218200320042000411c6a28020028020c1100000f0b0240024020054108710d004100210a200920076b22092105024002400240410120002d0020220720074103461b0e0402010001020b2009410176210a200941016a41017621050c010b410021052009210a0b200a41016a210a0340200a417f6a220a450d0220002802182000280204200028021c280210110100450d000b41010f0b200028020421052000413036020420002d002021064101210a200041013a0020200020082001200210420d014100210a200920076b22092102024002400240410120002d0020220820084103461b0e0402010001020b2009410176210a200941016a41017621020c010b410021022009210a0b200a41016a210a02400340200a417f6a220a450d0120002802182000280204200028021c280210110100450d000b41010f0b200028020421094101210a200028021820032004200028021c28020c1100000d01200241016a2108200028021c210220002802182101024003402008417f6a2208450d014101210a2001200920022802101101000d030c000b0b200020063a00202000200536020441000f0b200028020421094101210a200020082001200210420d00200028021820032004200028021c28020c1100000d00200541016a2108200028021c210220002802182100034002402008417f6a22080d0041000f0b4101210a200020092002280210110100450d000b0b200a0b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101101000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11000021040b20040b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341b486c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002103a000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341ec86c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002103a000b9307010c7f200041106a28020021030240024002400240200041086a28020022044101460d0020034101460d012000280218200120022000411c6a28020028020c11000021030c030b20034101470d010b0240024020020d00410021020c010b200120026a2105200041146a28020041016a21064100210720012103200121080340200341016a210902400240024020032c0000220a417f4a0d000240024020092005470d004100210b200521030c010b20032d0001413f71210b200341026a220921030b200a411f71210c0240200a41ff0171220a41df014b0d00200b200c41067472210a0c020b0240024020032005470d004100210d2005210e0c010b20032d0000413f71210d200341016a2209210e0b200d200b41067472210b0240200a41f0014f0d00200b200c410c7472210a0c020b02400240200e2005470d004100210a200921030c010b200e41016a2103200e2d0000413f71210a0b200b410674200c411274418080f0007172200a72220a418080c400470d020c040b200a41ff0171210a0b200921030b02402006417f6a2206450d00200720086b20036a21072003210820052003470d010c020b0b200a418080c400460d00024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20044101460d002000280218200120022000411c6a28020028020c1100000f0b4100210902402002450d002002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b0240200220096b200028020c2206490d002000280218200120022000411c6a28020028020c1100000f0b410021074100210902402002450d00410021092002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b200920026b20066a2209210a024002400240410020002d0020220320034103461b0e0402010001020b20094101762107200941016a410176210a0c010b4100210a200921070b200741016a2103024003402003417f6a2203450d0120002802182000280204200028021c280210110100450d000b41010f0b2000280204210941012103200028021820012002200028021c28020c1100000d00200a41016a2103200028021c210a20002802182100034002402003417f6a22030d0041000f0b20002009200a280210110100450d000b41010f0b20030bc80801067f230041f0006b220524002005200336020c20052002360208410121062001210702402001418102490d00410020016b2108418002210903400240200920014f0d00200020096a2c000041bf7f4c0d0041002106200921070c020b2009417f6a21074100210620094101460d01200820096a210a20072109200a4101470d000b0b200520073602142005200036021020054100410520061b36021c2005419ca8c70041b087c00020061b3602180240024002400240200220014b22090d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200520023602202002450d0220022001460d02200141016a210a03400240200220014f0d00200020026a2c000041404e0d040b2002417f6a210920024101460d04200a2002462107200921022007450d000c040b0b20052002200320091b360228200541306a41146a4103360200200541c8006a41146a4104360200200541d4006a410436020020054203370234200541b887c0003602302005410136024c2005200541c8006a3602402005200541186a3602582005200541106a3602502005200541286a360248200541306a2004103a000b200541e4006a4104360200200541c8006a41146a4104360200200541d4006a4101360200200541306a41146a410436020020054204370234200541d087c0003602302005410136024c2005200541c8006a3602402005200541186a3602602005200541106a36025820052005410c6a3602502005200541086a360248200541306a2004103a000b200221090b024020092001460d00410121070240024002400240200020096a220a2c00002202417f4a0d0041002106200020016a220721010240200a41016a2007460d00200a41026a2101200a2d0001413f7121060b2002411f71210a200241ff017141df014b0d012006200a4106747221010c020b2005200241ff0171360224200541286a21020c020b4100210020072108024020012007460d00200141016a210820012d0000413f7121000b200020064106747221010240200241ff017141f0014f0d002001200a410c747221010c010b41002102024020082007460d0020082d0000413f7121020b2001410674200a411274418080f00071722002722201418080c400460d020b2005200136022441012107200541286a21022001418001490d00410221072001418010490d0041034104200141808004491b21070b200520093602282005200720096a36022c200541306a41146a4105360200200541ec006a4104360200200541e4006a4104360200200541c8006a41146a4106360200200541d4006a410736020020054205370234200541f087c000360230200520023602582005410136024c2005200541c8006a3602402005200541186a3602682005200541106a3602602005200541246a3602502005200541206a360248200541306a2004103a000b41d095c700412b2004102d000b100020012000280200200028020410450b800101037f230041206b220224000240024020002802002001104c0d002001411c6a2802002103200128021821042002411c6a41003602002002419ca8c7003602182002420137020c200241d888c00036020820042003200241086a1031450d010b200241206a240041010f0b20002802042001104c2101200241206a240020010bdd0502047f017e410121020240200128021841272001411c6a2802002802101101000d0041022103024002400240024002402000280200220041776a2204411e4d0d00200041dc00470d010c020b41f40021050240024020040e1f05010202000202020202020202020202020202020202020202030202020203050b41f20021050c040b41ee0021050c030b0240024002402000104a0d00024002400240200041808004490d00200041808008490d0120004190fc476a4190fc0b490d02200041b5d9736a41b5db2b490d02200041e28b746a41e20b490d022000419fa8746a419f18490d02200041dee2746a410e490d02200041feffff0071419ef00a460d02200041a2b2756a4122490d02200041cb91756a410a4b0d050c020b200041c089c000412941928ac00041a20241b48cc00041b502104b450d010c040b200041e98ec000412641b58fc00041af0141e490c00041a303104b0d030b200041017267410276410773ad4280808080d0008421060c010b200041017267410276410773ad4280808080d0008421060b410321030c020b410121030c010b0b200021050b03402003210441dc002100410121024101210302400240024002400240024020040e0402010500020b02400240024002402006422088a741ff01710e06050302010006050b200642ffffffff8f608342808080803084210641f50021000c060b200642ffffffff8f608342808080802084210641fb0021000c050b20052006a72204410274411c7176410f712203413072200341d7006a2003410a491b210002402004450d002006427f7c42ffffffff0f832006428080808070838421060c050b200642ffffffff8f60834280808080108421060c040b200642ffffffff8f6083210641fd0021000c030b41002103200521000c030b20012802184127200128021c2802101101000f0b200642ffffffff8f60834280808080c0008421060b410321030b20012802182000200128021c280210110100450d000b0b20020b9d0301057f0240024002404100410f200041a49a04491b2201200141086a2201200141027441c894c0006a280200410b742000410b7422014b1b2202200241046a2202200241027441c894c0006a280200410b7420014b1b2202200241026a2202200241027441c894c0006a280200410b7420014b1b2202200241016a2202200241027441c894c0006a280200410b7420014b1b220241027441c894c0006a280200410b74220320014620032001496a20026a2201411e4b0d002001410274210241b105210302402001411e460d00200241cc94c0006a2204450d00200428020041157621030b4100210402402001417f6a220520014b0d002005411f4f0d03200541027441c894c0006a28020041ffffff007121040b02402003200241c894c0006a280200411576220141016a460d00200020046b21022003417f6a2103410021000340200141b0054b0d032000200141d495c0006a2d00006a220020024b0d012003200141016a2201470d000b0b20014101710f0b2001411f41889bc0001030000b200141b10541989bc0001030000b2005411f41c495c0001030000bea0201067f200120024101746a210720004180fe0371410876210841002109200041ff0171210a0240024002400340200141026a210b200920012d000122026a210c024020012d000022012008460d00200120084b0d03200c2109200b2101200b2007470d010c030b0240200c2009490d00200c20044b0d02200320096a2101024003402002450d012002417f6a210220012d00002109200141016a21012009200a470d000b410021020c050b200c2109200b2101200b2007470d010c030b0b2009200c418894c0001044000b200c2004418894c0001043000b200041ffff03712109200520066a210c4101210202400340200541016a210a0240024020052d00002201411874411875220b4100480d00200a21050c010b200a200c460d02200b41ff007141087420052d0001722101200541026a21050b200920016b22094100480d02200241017321022005200c470d000c020b0b41d095c700412b419894c000102d000b20024101710ba50201037f23004180016b2202240002400240024002400240200128020022034110710d0020034120710d012000ad2001103e21000c020b410021030340200220036a41ff006a2000410f712204413072200441d7006a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d02200141a889c0004102200220036a4180016a410020036b104121000c010b410021030340200220036a41ff006a2000410f712204413072200441376a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d02200141a889c0004102200220036a4180016a410020036b104121000b20024180016a240020000f0b2000418001419889c0001044000b2000418001419889c0001044000b1c00200128021841999cc000410b2001411c6a28020028020c1100000b1c00200128021841a49cc000410e2001411c6a28020028020c1100000b5b01017f230041306b220324002003200136020c20032000360208200341246a410136020020034201370214200341ccb3c0003602102003410436022c2003200341286a3602202003200341086a360228200341106a2002103a000b140020002802002001200028020428020c1101000b1500200120002802002200280200200028020410450bb10401077f230041306b220324000240024020020d00410021040c010b200341286a210502400240024002400340024020002802082d0000450d00200028020041ed9cc0004104200028020428020c1100000d050b2003410a3602282003428a808080103703202003200236021c200341003602182003200236021420032001360210200341086a410a200120021053024002400240024020032802084101470d00200328020c210403402003200420032802186a41016a2204360218024002402004200328022422064f0d00200328021421070c010b200328021422072004490d00200641054f0d072003280210200420066b22086a22092005460d0420092005200610a305450d040b200328021c22092004490d0220072009490d0220032006200341106a6a41176a2d0000200328021020046a200920046b10532003280204210420032802004101460d000b0b2003200328021c3602180b200028020841003a0000200221040c010b200028020841013a0000200841016a21040b2000280204210920002802002106024020044520022004467222070d00200220044d0d03200120046a2c000041bf7f4c0d030b200620012004200928020c1100000d04024020070d00200220044d0d04200120046a2c000041bf7f4c0d040b200120046a2101200220046b22020d000b410021040c040b2006410441f49cc0001043000b200120024100200441849dc0001046000b200120022004200241a087c0001046000b410121040b200341306a240020040bf80201067f410021040240024020024103712205450d00410420056b2205450d0020032005200520034b1b210441002105200141ff01712106034020042005460d01200220056a2107200541016a210520072d000022072006470d000b410121032007200141ff01714641016a41017120056a417f6a21050c010b200141ff017121060240024020034108490d002004200341786a22084b0d00200641818284086c210502400340200220046a220741046a2802002005732209417f73200941fffdfb776a7120072802002005732207417f73200741fffdfb776a7172418081828478710d01200441086a220420084d0d000b0b200420034b0d010b200220046a2109200320046b210241002103410021050240034020022005460d01200920056a2107200541016a210520072d000022072006470d000b410121032007200141ff01714641016a41017120056a417f6a21050b200520046a21050c010b2004200341b09dc0001044000b20002005360204200020033602000b8b0201027f230041106b220224002002410036020c02400240024002402001418001490d002001418010490d012002410c6a21032001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c2002410c6a2103410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c2002410c6a2103410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b20002003200110522101200241106a240020010b6001017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41fc9dc000200241086a10312101200241206a240020010b0d0020002802002001200210520b0b002000280200200110540b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41fc9dc000200241086a10312101200241206a240020010bd30202047f027e230041c0006b2203240041012104024020002d00080d00200028020421050240200028020022062d00004104710d0041012104200628021841db9dc00041949ec00020051b4102410120051b2006411c6a28020028020c1100000d0120012000280200200228020c11010021040c010b024020050d0041012104200628021841959ec00041022006411c6a28020028020c1100000d01200028020021060b41012104200341013a0017200341346a41e09dc000360200200320062902183703082003200341176a3602102006290208210720062902102108200320062d00203a00382003200837032820032007370320200320062902003703182003200341086a3602302001200341186a200228020c1101000d00200328023041f89dc0004102200328023428020c11000021040b200020043a00082000200028020441016a360204200341c0006a240020000bd40202037f027e230041c0006b2203240041012104024020002d00040d0020002d000521040240200028020022052d00004104710d000240200441ff0171450d0041012104200528021841db9dc00041022005411c6a28020028020c1100000d02200028020021050b20012005200228020c11010021040c010b0240200441ff01710d0041012104200528021841999ec00041012005411c6a28020028020c1100000d01200028020021050b41012104200341013a0017200341346a41e09dc000360200200320052902183703082003200341176a3602102005290208210620052902102107200320052d00203a00382003200737032820032006370320200320052902003703182003200341086a3602302001200341186a200228020c1101000d00200328023041f89dc0004102200328023428020c11000021040b200041013a0005200020043a0004200341c0006a240020000b6401027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a10312100200241206a240020000bd70a020c7f017e230041206b220324004101210402400240200228021841222002411c6a2802002802101101000d000240024020010d00410021050c010b200020016a21064100210520002107410021080240034020072109200741016a210a02400240024020072c0000220b417f4a0d0002400240200a2006470d004100210c200621070c010b20072d0001413f71210c200741026a220a21070b200b411f7121040240200b41ff0171220b41df014b0d00200c200441067472210c0c020b0240024020072006470d004100210d2006210e0c010b20072d0000413f71210d200741016a220a210e0b200d200c41067472210c0240200b41f0014f0d00200c2004410c7472210c0c020b02400240200e2006470d004100210b200a21070c010b200e41016a2107200e2d0000413f71210b0b200c4106742004411274418080f0007172200b72220c418080c400470d020c040b200b41ff0171210c0b200a21070b4102210a024002400240024002400240200c41776a220b411e4d0d00200c41dc00470d010c020b41f400210e02400240200b0e1f05010202000202020202020202020202020202020202020202030202020203050b41f200210e0c040b41ee00210e0c030b0240200c104a0d0002400240200c41808004490d00200c41808008490d01200c4190fc476a4190fc0b490d02200c41b5d9736a41b5db2b490d02200c41e28b746a41e20b490d02200c419fa8746a419f18490d02200c41dee2746a410e490d02200c41feffff0071419ef00a460d02200c41a2b2756a4122490d02200c41cb91756a410a4d0d020c060b200c41c089c000412941928ac00041a20241b48cc00041b502104b450d010c050b200c41e98ec000412641b58fc00041af0141e490c00041a303104b0d040b200c41017267410276410773ad4280808080d00084210f4103210a0c010b0b200c210e0b2003200136020420032000360200200320053602082003200836020c0240024020082005490d0002402005450d0020052001460d00200520014f0d01200020056a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020056a200820056b200228021c28020c110000450d01410121040c060b20032003410c6a3602182003200341086a36021420032003360210200341106a105d000b0340200a210b4101210441dc0021054101210a024002400240024002400240200b0e0402010500020b0240024002400240200f422088a741ff01710e06050302010006050b200f42ffffffff8f608342808080803084210f4103210a41f50021050c070b200f42ffffffff8f608342808080802084210f4103210a41fb0021050c060b200e200fa7220b410274411c7176410f71220a413072200a41d7006a200a410a491b21050240200b450d00200f427f7c42ffffffff0f83200f4280808080708384210f0c050b200f42ffffffff8f608342808080801084210f0c040b200f42ffffffff8f6083210f4103210a41fd0021050c040b4100210a200e21050c030b4101210a0240200c418001490d004102210a200c418010490d0041034104200c41808004491b210a0b200a20086a21050c040b200f42ffffffff8f60834280808080c00084210f0b4103210a0b20022802182005200228021c280210110100450d000c050b0b200820096b20076a210820062007470d000b0b2005450d0020052001460d00200520014f0d02200020056a2c000041bf7f4c0d020b410121042002280218200020056a200120056b200228021c28020c1100000d0020022802184122200228021c28021011010021040b200341206a240020040f0b200020012005200141a087c0001046000b2b01017f20002802002201280200200128020420002802042802002000280208280200419c9ec0001046000b900101037f23004180016b2202240020002802002103410021000340200220006a41ff006a2003410f712204413072200441376a2004410a491b3a00002000417f6a2100200341047622030d000b024020004180016a2203418101490d002003418001419889c0001044000b200141a889c0004102200220006a4180016a410020006b1041210020024180016a240020000b1c00200128021841fea9c00041052001411c6a28020028020c1100000bb30101037f200028020421020240024020002802004101470d002000410c6a28020022002001106120004103742200450d01200220006a2103034020022802002100200241046a2802002204200110612001200020041062200241086a22022003470d000c020b0b200041086a28020022002001106120004103742200450d00200220006a2103034020022802002100200241046a2802002204200110612001200020041062200241086a22022003470d000b0b0bab0101017f230041106b220224000240024002400240200041c000490d00200041808001490d012000418080808004490d02200241033a00032001200241036a41011062200220003602042001200241046a410410620c030b200220004102743a00032001200241036a410110620c020b200220004102744101723b010a20012002410a6a410210620c010b2002200041027441027236020c20012002410c6a410410620b200241106a24000bcd0101047f0240024002400240200041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422062005200620054b1b22064100480d010240024020030d00024020060d00410121050c020b2006102122050d010c040b2000280200210520032006460d0020052003200610252205450d03200041086a28020021040b20002005360200200041046a20063602000b200520046a2001200210a1051a200041086a200420026a3602000f0b102c000b102a000bff0101037f200028020421020240024020002802004101470d002000410c6a2802002200200110612000450d01200041186c2103200241146a21000340200041706a2802002102200041746a28020022042001106120012002200410622000417c6a280200210220002802002204200110612001200220041062200041186a2100200341686a22030d000c020b0b200041086a2802002200200110612000450d00200041186c2103200241146a21000340200041706a2802002102200041746a28020022042001106120012002200410622000417c6a280200210220002802002204200110612001200220041062200041186a2100200341686a22030d000b0b0ba90701057f230041206b2203240020012002106102402001450d00200141d8006c2104410021050340200020056a220141046a2802002106200141086a28020022072002106120022006200710622003200141d4006a2d00003a000d20022003410d6a4101106202402001410c6a2d0000220641024b0d0002400240024020060e03000102000b200341003a000e20022003410e6a41011062200141146a2802002106200141186a28020022072002106120022006200710620c020b200341013a000e20022003410e6a4101106202402001410d6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110620b200141146a2802002106200141186a2802002207200210612002200620071062200141206a2802002106200141246a280200220720021061200220062007106220032001410e6a2d00003a000e20022003410e6a410110620c010b200341023a000e20022003410e6a4101106202402001410d6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110620b200141146a2802002106200141186a2802002207200210612002200620071062200141206a2802002106200141246a28020022072002106120022006200710622001412c6a2802002106200141306a28020022072002106120022006200710622001410e6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110620b02400240200141346a2802004101470d00200141386a2802002106200141c0006a28020022072002106120022006200710620c010b200341106a200141386a2802002001413c6a28020028020c11020020032802102106200328021822072002106120022006200710622003280214450d00200610230b200141c4006a200210602004200541d8006a2205470d000b0b200341206a24000be405010b7f2001410c6a28020021022001280208210320012802042104200128020021050240024002400240024002400240024020012d001022060e03010002010b200420056b21070c020b200420056b2201200220036b6a220720014f0d010240024020052004460d00200541016a2108410021060c010b024020032002470d004101210941002104410021070c060b410221062003210120052108200341016a2103200121050b41002101410021074101210903402001410174210a200420086b210b034020052d00002105024020012007470d00200b2107024002400240200641ff01710e03010200010b200220036b21070c010b417f200b200220036b6a22072007200b491b21070b2001417f200741016a220c200c2007491b6a22072001490d05200a2007200a20074b1b22074100480d05024020010d00024020070d00410121090c020b2007102122090d010c090b20012007460d0020092001200710252209450d080b200920016a20053a0000024002400240024002400240200641ff01710e03010300010b20022003460d010c040b024020082004460d00410021060c030b20022003470d030b200141016a21040c090b4101210620082004470d00200141016a21040c080b200141016a210120082105200841016a21080c020b200141016a210141022106200a41026a210a2003220541016a21030c000b0b0b200220036b21070b4101210902402007450d0020074100480d01200710212209450d040b0240200641014d0d0041002104200921010c020b0240024020052004470d0041002104200921010c010b200921012005210a03402001200a2d00003a0000200141016a21012004200a41016a220a470d000b200420056b21040b200641024b0d0220060e03010201010b102c000b20032002460d002003210a03402001200a2d00003a0000200141016a21012002200a41016a220a470d000b2002200420036b6a21040b2000200436020820002007360204200020093602000f0b102a000bd40101037f02400240024002402000280200220041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004102122050d010c040b2000280200210520032004460d0020052003200410252205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a2001200210a1051a200041086a200420026a36020041000f0b102c000b102a000bbf0301047f230041106b22022400200028020021002002410036020c02400240024002402001418001490d002001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b0240024002400240200041046a2802002203200041086a28020022046b2001490d00200028020021050c010b200420016a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004102122050d010c040b2000280200210520032004460d0020052003200410252205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a2002410c6a200110a1051a200041086a200420016a360200200241106a240041000f0b102c000b102a000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41cc9fc000200241086a10312101200241206a240020010bcd0101037f0240024002400240200041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004102122050d010c040b2000280200210520032004460d0020052003200410252205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a2001200210a1051a200041086a200420026a3602000f0b102c000b102a000b040041010bb60101017f230041c0006b2202240020024100360210200242013703082002410836021c20022001410c6a3602202002200241206a3602182002200241086a3602242002413c6a41013602002002420137022c200241ccb3c0003602282002200241186a360238200241246a41cc9fc000200241286a10311a20012d0000417f6a41ff0171200141046a290200200235021042208620023502088410000240200228020c450d00200228020810230b200241c0006a24000b6901037f230041206b220224002001411c6a280200210320012802182104200241086a41106a2000280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a10312101200241206a240020010b040041000b02000b02000bcd0201047f230041106b2202240002400240024002400240024002400240024020012d00000e06010203040500010b200241003a000a20024181ca003b01082002200141216a3602042002200141016a3602000c050b410110272201450d062000428180808010370204200020013602000c050b2001410c6a2802002203412020034120491b220441016a220310212205450d0520052003200310a005220541016a200141046a280200200410a1051a2000200336020820002003360204200020053602000c040b200241003a000a20024181c4003b01082002200141216a3602042002200141016a3602000c020b200241003a000a20024181c6003b01082002200141216a3602042002200141016a3602000c010b200241003a000a20024181c8003b01082002200141216a3602042002200141016a3602000b2000200210710b200241106a24000f0b1033000be105010a7f200141096a2d0000210220012d000821032001280204210420012802002105024002400240024002400240024002400240024020012d000a22060e03010002010b200341ff017141014621070c020b200341ff01714101462201200420056b6a220720014f0d01410021084100210141002107410121090240410041ff01710e03030400030b410021060c040b200420056b21070b0240024020070d00410121090c010b20074100480d04200710212209450d060b4100210102400240200341ff01710d00200921080c010b20092108200641014b0d00200920023a0000200941016a2108410121010b200641024b0d04024020060e03000500000b20052004460d04200120056b21010340200820052d00003a0000200841016a21082004200541016a2205470d000b200420016a21010c040b410121060c010b410221060b0340024002400240024020060e03000102020b20052004460d0520052d0000210a41022106200541016a21052002210b200a21020c020b200341017121064100210302402006450d00410021064100210b0c020b20052004460d0420052d0000210241022106200541016a21054100210b0c010b410121062003410171210a410021034100210b200a450d030b024020012007470d00024002400240024020060e03010200010b200420056b21070c020b417f200341ff01714101462207200420056b6a220a200a2007491b21070c010b200341ff017141014621070b2001417f200741016a220a200a2007491b6a22072001490d0220082007200820074b1b22074100480d02024020010d00024020070d00410121090c020b2007102122090d010c050b20012007460d0020092001200710252209450d040b200920016a20023a0000200841026a2108200141016a2101200b2102024002400240200641ff01710e03000102000b410121060c020b410221060c010b410021060c000b0b102c000b2000200136020820002007360204200020093602000f0b102a000ba00201067f410021020240200141016a2203200028020422044d0d000240200041146a22052802002201200041106a280200470d000240024002400240200141016a22022001490d00200141017422062002200620024b1b220241ffffffff03712002470d00200241027422024100480d00024020010d0020020d02410421060c040b200028020c2106200141027422072002460d03024020070d0020020d02410421060c040b20062007200210252206450d020c030b102c000b2002102122060d010b102a000b2000200636020c200041106a20024102763602000b200028020c220241046a2002200141027410a2051a2002200320046b36020020002003360204410121022005200141016a3602002000200028020041016a3602000b20020b8c0201067f02400240024020012802002202450d00200128020421030340200241086a210420022f010622054103742101410021060240024003402001450d0141b2a8c0002004410810a3052207450d02200141786a2101200641016a2106200441086a21042007417f4a0d000b2006417f6a21050b2003450d022003417f6a2103200220054102746a41e4016a28020021020c010b0b200241e0006a2006410c6c6a22012802084108490d01200041086a2001280200290000370300200041003602000f0b200041003602042000410c6a4128360200200041086a41baa8c0003602000c010b200041003602042000410c6a4129360200200041086a41e2a8c0003602000b200041013602000bed0301057f024002400240200241046a2203417f4c0d0002400240024002400240024002400240024002402003450d00200310212204450d0b200241c000490d04200241808001490d052002418080808004490d06200441033a00002003417f6a41034d0d01200321050c030b41012103410110212204450d07200441033a0000410521050c010b200341017422064105200641054b1b22054100480d0720032005460d010b20042003200510252204450d050b20042002360001410521060c030b200420024102743a000041012106200321050c020b02400240200341014d0d00200321050c010b2003200341017422064102200641024b1b2205460d0020042003200510252204450d030b41022106200420024102744101723b00000c010b02400240200341034d0d00200321050c010b200341017422064104200641044b1b22054100480d0320032005460d0020042003200510252204450d020b20042002410274410272360000410421060b0240200520066b2002490d00200521030c050b200620026a22032006490d01200541017422072003200720034b1b22034100480d0120052003460d04200420052003102522040d040b102a000b102c000b1032000b1033000b200420066a2001200210a1051a2000200620026a36020820002003360204200020043602000bd60201027f024002402002450d002002417f6a21040240024020012d0000220241037122054103460d0002400240024020050e03000102000b200241027621020c030b2004450d0320012d0001410874200272220241ffff0371418002490d03200241fcff037141027621020c020b20044103490d0220012f0001200141036a2d000041107472410874200272220241808004490d02200241027621020c010b200241034b0d0120044104490d0120012800012202418080808004490d010b200220036a22012002490d0141012103410121050240200241c000490d0041022105200241808001490d00410441052002418080808004491b21050b0240200141c000490d0041022103200141808001490d00410441052001418080808004491b21030b20002001360204200041003602002000410c6a2003360200200041086a20053602000f0b200041013602000f0b200041013602000be60601067f0240024002400240024020012d0000220341024d0d0041012101410021040c010b02400240024020030e03000102000b410110212205450d03200541013a0000412010212203450d0420032001290001370000200341186a2206200141196a290000370000200341106a2207200141116a290000370000200341086a2208200141096a2900003700004121210420054101412110252201450d0320012003290000370001200141196a2006290000370000200141116a2007290000370000200141096a2008290000370000200310230c020b410110212205450d02200541023a0000412010212203450d0320032001290001370000200341186a2206200141196a290000370000200341106a2207200141116a290000370000200341086a2208200141096a2900003700004121210420054101412110252201450d0220012003290000370001200141196a2006290000370000200141116a2007290000370000200141096a2008290000370000200310230c010b410110212205450d01200541033a0000412010212203450d0220032001290001370000200341186a2206200141196a290000370000200341106a2207200141116a290000370000200341086a2208200141096a2900003700004121210420054101412110252201450d0120012003290000370001200141196a2006290000370000200141116a2007290000370000200141096a2008290000370000200310230b20022802002103410410212205450d0020052003360000412010212203450d0120032002290004370000200341186a22062002411c6a290000370000200341106a2207200241146a290000370000200341086a22082002410c6a29000037000020054104412410252202450d00200220032900003700042002411c6a2006290000370000200241146a20072900003700002002410c6a20082900003700002003102320044101742203200441246a2206200320064b1b2105024020040d00200510212201450d010c030b20042005460d02200120042005102522010d020b102a000b1033000b200120046a22032002290000370000200341206a200241206a280000360000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a290000370000200210232000200636020820002005360204200020013602000b5f01017f02404120102122020d001033000b200042a080808080043702042000200236020020022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a2900003700000b8803010a7f230041206b220124000240024002400240200041086a2802002202450d00410020024102746b2103417f210420002802002205210603402003450d01200441016a2104200341046a210320062802002107200641046a21062007450d000b4100200741004741016a41017122066b2004460d002002200620046a2208490d012002200741004741016a4101716b20046b220641ffffffff03712006470d0220064102742209417f4c0d024104210a02402009450d0020091021220a450d040b200141003602182001200a36021020012009410276360214200141106a4100200610792001280210200128021822064102746a200520084102746a4104200741004741016a410171220741027420036a6b10a1051a200141086a22032002200620076b6a20046b360200200120012903103703000240200041046a28020041ffffffff0371450d00200028020010230b20002001290300370200200041086a20032802003602000b200141206a24000f0b2008200241fcadc0001044000b1032000b1033000bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff03712001470d00200141027422014100480d00024020030d0020010d02410421020c040b20002802002102200341027422032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a20014102763602000b0bb90403077f017e097f02400240024002400240200141086a2802002203200241086a2802002204200320044b1b220541016a22064101200641014b1b220741ffffffff03712007470d0020074102742208417f4c0d00200810272209450d01024020050d004200210a0c040b2004417f6a220b20044b210c2002280200210d2003417f6a220e20034b0d022001280200210f2007417f6a2102200820096a417c6a2110410021064200210a03404100211102402003200e20066b22124d0d00410021112012200e4b0d00200f20124102746a28020021110b410021120240200c0d002004200b20066b22134d0d002013200b4b0d00200d20134102746a28020021120b200720024d0d052010200a2011ad7c2012ad7c220a3e02002010417c6a21102002417f6a2102200a422088210a200641016a22062005490d000c040b0b1032000b1033000b2007417f6a2102200820096a417c6a2111410021104200210a0340410021060240200c0d00410021062004200b20106b22124d0d00410021062012200b4b0d00200d20124102746a28020021060b200720024d0d022011200a2006ad7c220a3e02002011417c6a21112002417f6a2102200a422088210a201041016a22102005490d000b0b024020072005417f736a220220074f0d00200020073602082000200841027636020420002009360200200920024102746a200a3e02000240200141046a28020041ffffffff0371450d00200128020010230b0f0b2002200741ecadc0001030000b2002200741ecadc0001030000bb404030e7f017e017f02400240200241086a2802002203200141086a28020022046a22054101200541014b1b220641ffffffff03712006470d0020064102742207417f4c0d000240200710272208450d002004450d022001280200210902400240024020030d002006417f6a2105200720086a417c6a210a20092004417f6a22024102746a21030340200420024d0d0302402003280200450d00200620054d0d03200a41003602000b2003417c6a2103200a417c6a210a2005417f6a21052002417f6a2202417f470d000c060b0b200720086a417c6a210b200341027420022802006a417c6a210c4100210d2006210e03402004200d417f736a220220044f0d020240200920024102746a220f2802002210450d0042002111417f2102200b2105200c210a024003402006200e20026a22124d0d012005200a3502002010ad7e20117c20053502007c22113e0200201142208821110240200320026a0d002006200d20036a417f736a220520064f0d05200820054102746a20113e02000c030b2005417c6a2105200a417c6a210a200f280200211020032002417f6a22026a22122003490d000b2012200341dcadc0001030000b2012200641dcadc0001030000b200b417c6a210b200e417f6a210e200d41016a220d2004460d050c000b0b2005200641ecadc0001030000b2002200441dcadc0001030000b1033000b1032000b2000200636020820002007410276360204200020083602000240200141046a28020041ffffffff0371450d00200128020010230b0bca0302097f017e230041106b2201240002400240024002400240024002402000280200220228020041016a41004c0d002000280204220328020041016a41004c0d012000280208220441086a28020022054101200028020c22062802006b22076a220820054f0d02200720002802142802006b22052000280210220741086a28020022006a220920054f0d03024002402002290308220a42ffffffff0f560d0041002100200a200428020020084102746a3502007e2003290308422086200728020020094102746a35020084580d010b20022802000d052002410036020020022002290308427f7c370308200441086a2802002200200020062802006b22024d0d0620032802000d07200428020020024102746a350200210a200341003602002003200a20032903087c370308410121000b200141106a240020000f0b41a795c7004118200141086a41dcaec00041c095c7001034000b41a795c7004118200141086a41dcaec00041c095c7001034000b2008200541dcadc0001030000b2009200041dcadc0001030000b41c394c7004110200141086a41ecaec00041d494c7001034000b2002200041dcadc0001030000b41c394c7004110200141086a41ecaec00041d494c7001034000ba80301087f200028020822024102742103410021042000280200220521000240024003402003450d012004417f6a21042003417c6a210320002802002106200041046a21002006450d000b410121072004417f73200641004741016a4101716a21080c010b41002107410020046b21080b200128020822094102742103410021042001280200220121000240024003402003450d012004417f6a21042003417c6a210320002802002106200041046a21002006450d000b410021032004417f73200641004741016a4101716a21000c010b410020046b2100410121030b024020070d00410020034101736b0f0b4101210402400240024020030d0020022008490d0120092000490d02417f200220086b2203200920006b22064720032006491b22040d0020062003200320064b1b2107200120004102746a2103200520084102746a2100417f210103400240200141016a22012007490d0041000f0b2003280200210420002802002106200341046a2103200041046a2100417f200620044720062004491b2204450d000b0b20040f0b20082002418caec0001044000b20002009419caec0001044000b1000200028020020002802042001105c0bcb04010a7f230041106b220224002002410036020820024204370300200128000c2103410021040240024002400240024002400240024020012802042205200128020022064920012d00084100477222010d004100200520066b2204200420054b1b220741016a220420074f0d00200341086a21084100210441042109410021010340200828020022072005417f736a220a20074f0d02200620054f2107200520062005496b21052003280200200a4102746a280200210a024020012002280204470d0020022001417f41004100417f4100200520066b2209200920054b1b220941016a220b200b2009491b20071b20052006491b220941016a220b200b2009491b1079200228020021090b200920046a200a3602002002200141016a2201360208200441046a21042005200649200772450d000c070b0b20024100200410792002280208210b20010d042002280200200b4102746a2104200520064d0d012005417f732101200341086a21092005210703402001200928020022086a220a20014f0d0320042003280200200a4102746a280200360200200141016a2101200441046a210420062007417f6a2207490d000b200520066b200b6a210b0c030b200a200741dcadc0001030000b20052006460d010c020b200a200841dcadc0001030000b200341086a28020022052006417f736a220620054f0d022004200328020020064102746a280200360200200b41016a210b0b2002200b3602080b20002002290300370200200041086a200241086a280200360200200241106a24000f0b2006200541dcadc0001030000bfc0601047f230041d0006b2208240002400240024002402002200685200320078584500d00200220038450450d01410121090c020b417f20002004852001200585844200522000200454200120055420012005511b1b21090c010b0240200620078450450d0041ff0121090c010b411010212209450d012008420437024420082009360240200841c0006a410041041079200841306a41086a22092008280248220a41046a3602002008280240200a4102746a220a20003e020c200a20004220883e0208200a20013e0204200a20014220883e020020082008290340370330200841306a1078200841106a41086a220b20092802003602002008200829033037031041101021220a450d01200842043702442008200a360240200841c0006a41004104107920092008280248220a41046a3602002008280240200a4102746a220a20063e020c200a20064220883e0208200a20073e0204200a20074220883e020020082008290340370330200841306a1078200841206a41086a200928020036020020082008290330370320200841c0006a41086a200b280200360200200820082903103703402008200841c0006a200841206a107b0240200828022441ffffffff0371450d00200828022010230b411010212209450d012008420437024420082009360240200841c0006a410041041079200841306a41086a22092008280248220a41046a3602002008280240200a4102746a220a20043e020c200a20044220883e0208200a20053e0204200a20054220883e020020082008290340370330200841306a1078200841106a41086a220b20092802003602002008200829033037031041101021220a450d01200842043702442008200a360240200841c0006a41004104107920092008280248220a41046a3602002008280240200a4102746a220a20023e020c200a20024220883e0208200a20033e0204200a20034220883e020020082008290340370330200841306a1078200841206a41086a200928020036020020082008290330370320200841c0006a41086a200b28020036020020082008290310370340200841306a200841c0006a200841206a107b0240200828022441ffffffff0371450d00200828022010230b2008200841306a107d21090240200828023441ffffffff0371450d00200828023010230b200828020441ffffffff0371450d00200828020010230b200841d0006a240020090f0b1033000bb00703017f067e017f230041d0006b22022400024002400240200029031022032001290310220485200041186a2903002205200141186a29030022068584500d00200041086a290300210720002903002108411010212200450d022002420437024420022000360240200241c0006a410041041079200241306a41086a22092002280248220041046a360200200228024020004102746a220020083e020c200020084220883e0208200020073e0204200020074220883e020020022002290340370330200241306a1078200241106a41086a200928020036020020022002290330370310411010212200450d022002420437024420022000360240200241c0006a410041041079200241306a41086a22092002280248220041046a360200200228024020004102746a220020043e020c200020044220883e0208200020063e0204200020064220883e020020022002290340370330200241306a1078200241206a41086a200928020036020020022002290330370320200241c0006a41086a200241106a41086a280200360200200220022903103703402002200241c0006a200241206a107b0240200228022441ffffffff0371450d00200228022010230b200141086a290300210420012903002106411010212200450d022002420437024420022000360240200241c0006a410041041079200241306a41086a22002002280248220141046a360200200228024020014102746a220120063e020c200120064220883e0208200120043e0204200120044220883e020020022002290340370330200241306a1078200241106a41086a2209200028020036020020022002290330370310411010212201450d022002420437024420022001360240200241c0006a41004104107920002002280248220141046a360200200228024020014102746a220120033e020c200120034220883e0208200120053e0204200120054220883e020020022002290340370330200241306a1078200241206a41086a200028020036020020022002290330370320200241c0006a41086a200928020036020020022002290310370340200241306a200241c0006a200241206a107b0240200228022441ffffffff0371450d00200228022010230b2002200241306a107d21000240200228023441ffffffff0371450d00200228023010230b200041ff017121000240200228020441ffffffff0371450d00200228020010230b20004521000c010b2000290300200129030085200041086a290300200141086a29030085845021000b200241d0006a240020000f0b1033000bd33007017f017e017f027e017f027e1c7f23004180036b2207240002400240024002402001200284500d002003200484500d004201210820074198016a200320012003200156200420025620042002511b22091b220a2004200220091b220b20054201200542015620064200522006501b220c1b220520064200200c1b220610a70520074188016a200729039801220d20074198016a41086a290300220e2005200610a6052002200420091b21022001200320091b2104200a20072903880185200b20074188016a41086a290300858450450d01200d210a200e210b420021060c020b20004100360200200041106a4200370300200041086a42003703000c020b200741f8006a200420022005200610a705200741e8006a20072903782201200741f8006a41086a29030022032005200610a6054200200620042007290368852002200741e8006a41086a29030085845022091b21064201200520091b21082003200220091b21022001200420091b21040b200741386a200b42002004420010a605200741c8006a20024200200a420010a605200741d8006a200a42002004420010a6050240024002400240024002400240024002400240024002400240024002400240200b420052200242005271200729034042005272200729035042005272200741d8006a41086a2903002201200729033820072903487c7c2203200154724101470d00411010212209450d0d2007420437029c02200720093602980220074198026a410041041079200741f0026a41086a220920072802a002220c41046a360200200728029802200c4102746a220c200a3e020c200c200a4220883e0208200c200b3e0204200c200b4220883e020020072007290398023703f002200741f0026a1078200741a8016a41086a2009280200360200200720072903f0023703a80141101021220c450d0d2007420437029c022007200c3602980220074198026a410041041079200920072802a002220c41046a360200200728029802200c4102746a220c20043e020c200c20044220883e0208200c20023e0204200c20024220883e020020072007290398023703f002200741f0026a1078200741b8016a41086a2009280200360200200720072903f0023703b801411010212209450d0d2007420437029c02200720093602980220074198026a410041041079200741f0026a41086a220c20072802a002220941046a36020020072802980220094102746a22092008a7220f36020c200920084220883e0208200920063e0204200920064220883e020020072007290398023703f002200741f0026a1078200c280200211020072802f402211120072802f0022112200c200741b8016a41086a280200360200200720072903b8013703f00220074198026a41086a200741a8016a41086a280200360200200720072903a80137039802200741c8016a20074198026a200741f0026a107b024020072802f40241ffffffff0371450d0020072802f00210230b200741c8016a107820104101460d0120072802cc01211320072802c80121142010450d0a2012280200450d0a024020072802d0012215450d002014280200450d0b201520104d0d0b200720103602d401201520106b221641016a22174101201741014b1b221841ffffffff03712018470d0320184102742219417f4c0d0320191027221a450d0e201041ffffffff03712010470d032010410274221b417f4c0d03201b1027221c450d0e4101210f410221092012280200220c67221d211e0240200c41ffffffff034b0d0041022109201d210c4101210f034020094101200c4101711b200f6c210f200c41034b211f200920096c2109200c410176221e210c201f0d000b0b200720153602f802200720133602f402200720143602f0024104211f41041021220c450d0f200c20094101201e4101461b200f6c220f360200200742818080801037029c022007200c36029802200741d8016a200741f0026a20074198026a107b200c10230240201b450d00201b1021221f450d0f0b200741003602a0022007201b410276222036029c022007201f3602980220074198026a41002010107920072802980220072802a00222094102746a2012201041027410a1051a200741f8026a200920106a36020020072007290398023703f002410410212209450d0f2009200f360200200742818080801037029c022007200936029802200741e8016a200741f0026a20074198026a107b20091023024020072802d40120176a220920072802e001220c4d0d00200741003602a002200742043703980220074198026a41002009200c6b220c107920072802a00221090240200c450d0020072802980220094102746a4100200c41027410a0051a2009200c6a21090b200741f0026a41086a220c200936020020072007290398023703f00220072802d801211f200741f0026a200920072802e001220f107920072802f002200c28020022094102746a201f200f41027410a1051a200c2009200f6a220936020020074198026a41086a220c2009360200200720072903f00237039802024020072802dc0141ffffffff0371450d0020072802d80110230b200741d8016a41086a200c28020036020020072007290398023703d8010b20194102762121200741e8016a1078024002400240024002400240024002400240024003402007201622223602f401024020072802e001220920072802d401220c20226a220f417f736a221f2009490d00201f200941dcadc0001030000b0240024002400240024002400240024002400240024002400240024020092009200f6b220f4d0d0020072802f00122092009200c6b220c4d0d0120072802e801200c4102746a35020022024200510d02202220224100476b211620072802d8012209201f4102746a35020021012009200f4102746a3502002104200741003602f80120072004200142208684200280220137038002200741003602880220072004200120027e7d42ffffffff0f83370390022007200741f4016a3602ac022007200741d8016a3602a8022007200741d4016a3602a4022007200741e8016a3602a002200720074188026a36029c022007200741f8016a3602980220074198026a107c1a034020072802880241016a41004c0d04024020072903900242ffffffff0f560d0020074198026a107c0d010b0b200729038002210220072802f401210920072802d401210c200741003a00f8022007200c20096a3602f402200720093602f0022007200741d8016a3602fc02200741b0026a200741f0026a107f20072802f001220941ffffffff03712009470d1c2009410274220c417f4c0d1c20072802e801210f02400240200c0d004104211f0c010b200c1021221f450d280b200741003602f8022007201f3602f0022007200c4102763602f402200741f0026a41002009107920072802f00220072802f802221f4102746a200f200c10a1051a200741e0026a41086a2223201f20096a360200200720072903f0023703e002410810212209450d2820092002a72224360204200920024220883e020020074282808080203702f402200720093602f002200741c0026a200741e0026a200741f0026a107b2009102320072802b802221920072802c8022225201920254b1b22144101201441014b1b220c41ffffffff0371200c470d1c200c4102742226417f4c0d1c20072802b402212720072802b00221280240024020260d00410421290c010b202610272229450d280b2014450d062025417f6a221b20254b211520072802c002212a2019417f6a221720194b0d04200c417f6a2109202920266a417c6a211e4100210f4200210203404100211f024020192017200f6b22134d0d004100211f201320174b0d00202820134102746a280200211f0b201fad21044100211f024020150d002025201b200f6b22134d0d002013201b4b0d00202a20134102746a280200211f0b024002402004201fad22037d22012004560d00200120027d220a2001560d00200a42ffffffff0f832104420021020c010b20044280808080108420027d20037d2104420121020b200c20094d0d09201e20043e0200201e417c6a211e2009417f6a2109200f41016a220f2014490d000c060b0b200f200941dcadc0001030000b200c200941dcadc0001030000b41c0adc000411941bcacc000102d000b41a795c7004118200741f0026a41dcaec00041c095c7001034000b200c417f6a2109202920266a417c6a211f4100211e4200210203404100210f024020150d004100210f2025201b201e6b22134d0d004100210f2013201b4b0d00202a20134102746a280200210f0b024002404200200fad22017d22044200520d00200420027d22032004560d00200342ffffffff0f832104420021020c010b428080808010200220017c7d2104420121020b200c20094d0d04201f20043e0200201f417c6a211f2009417f6a2109201e41016a221e2014490d000b0b41012113200250450d010b410021130b0240202741ffffffff0371450d00202810230b20072802d401221f20072802f401220f6a2215201f490d05200f20154f0d01200f417f7321090340200c200c200f6a20096a221e4d0d03200920072802e00122146a220f20094f0d0420072802d801200f4102746a2029201e4102746a2802003602002009417f6a210920072802f401210f201f417f6a221f0d000c050b0b2009200c41ecadc0001030000b201f450d020c030b20252019202520194b1b22074101200741014b1b200f6a20096a200c41dcadc0001030000b200f201441ecadc0001030000b200c200c2015417f7322096a200f6a220f4d0d0220072802e001220c20096a2209200c4f0d0320072802d80120094102746a2029200f4102746a28020036020020072802f401210f0b2018200f417f736a220920184f0d03201a20094102746a202436020002402013450d00201820072802f401417f736a220920184f0d05201a20094102746a22092009280200417f6a36020020072802f401210920072802d401210c200741003a00f8022007200c20096a3602f402200720093602f0022007200741d8016a3602fc02200741d0026a200741f0026a107f20072802f001220941ffffffff03712009470d0f2009410274220c417f4c0d0f20072802e801210f02400240200c0d004104211f0c010b200c1021221f450d1b0b200741003602f8022007201f3602f0022007200c4102763602f402200741f0026a41002009107920072802f00220072802f802221f4102746a200f200c10a1051a2023201f20096a360200200720072903f0023703e002200741f0026a200741e0026a200741d0026a107a024020072802d401220920072802f40122146a220c2009490d00024002402014200c4f0d00200c417f73210920072802f002211320072802f802210f2014211f0340200f200f201f6a20096a221f4d0d0a200920072802e00122156a221e20094f0d0b20072802d801201e4102746a2013201f4102746a280200360200200941016a210920072802f401211f2014200c417f6a220c490d000c020b0b20090d0120072802f802210f2014211f0b201f2014417f7322096a220c200f6a221f200c4f0d0920072802e001220c20096a2209200c4f0d0a20072802d80120094102746a20072802f002201f4102746a2802003602000b024020072802f40241ffffffff0371450d0020072802f00210230b20072802d40241ffffffff0371450d0020072802d00210230b02402026450d00202910230b024020072802c40241ffffffff0371450d0020072802c00210230b20220d000b0240201d0d0020072802e001211020072802dc01212020072802d801210f201c1023410021090c130b4101210920072802d401220c4101460d114100200c6b2114201d411f7121134100201d6b411f7121152010410274201c6a417c6a210c417f210903400240200920072802e001221f6a220f2009490d00200f201f41dcadc0001030000b201f200f417f6a221e4d0d09201020096a221f20104f0d0a200c20072802d801221f201e4102746a280200201574201f200f4102746a28020020137672360200200c417c6a210c20142009417f6a2209460d110c000b0b200f200c41dcadc0001030000b2009200c41ecadc0001030000b2009201841ecadc0001030000b2009201841dcadc0001030000b201f200f41dcadc0001030000b201e201541ecadc0001030000b201f200f41dcadc0001030000b2009200c41ecadc0001030000b200f417f6a201f41dcadc0001030000b201f201041ecadc0001030000b4100410041ccaec0001030000b200741286a200729035820032008200610a70520004100360200200041106a200741286a41086a290300370300200041086a20072903283703000c0f0b20074198026a41086a200741c8016a41086a280200221f360200200720072903c80137039802201f4101201f41014b1b221e41ffffffff0371201e470d00201e410274221b417f4c0d0002400240201b0d00410421170c010b201b10272217450d0c0b201f450d022017201e410274201f4102746b6a210c201f417f6a2114201e201f6b2113200f4101200f41014b1bad21024200210441002109200728029802210f0340201e201320096a22154d0d02200c2004422086200f35020084220420028022013e020020142009460d03200c41046a210c200f41046a210f2004200120027e7d2104201f200941016a22094b0d000b2009201f41dcadc0001030000b1032000b2015201e41ecadc0001030000b2007201e3602f8022007201b4102763602f402200720173602f002200728029c0241ffffffff0371450d0720072802980210230c070b20072802d40121090b20072802e001220c200c20096b220f4d0d012010201020096b22094d0d02201c20094102746a20072802d801200f4102746a280200201d411f717636020041012109201c210f0b024020072802ec0141ffffffff0371450d0020072802e80110230b2009450d0320072802dc0141ffffffff0371450d0320072802d80110230c030b200f200c41dcadc0001030000b2009201041ecadc0001030000b4100211a0240201341ffffffff0371450d00201410230b0b410410212209450d022009410036020041041021220c450d02200c41003602004101211e02400240201a0d002009211a4101212141012118200c210f41012120410121100c010b20091023200c10230b2007201836028002200720213602fc012007201a3602f801200720103602a0022007202036029c022007200f3602980220074198026a1078420021020240024020072802a00222094105744180014d0d00421d21040c010b4100211e024020090d00420021040c010b200728029802220c200941027422096a417c6a220f280200211f0240200c200f470d00201fad21040c010b200c41786a210f201fad2104200741206a211f4120210c420021020340200741186a200f20096a3502004200200c41e0007110a405201f29030020027c2007290318220220047c2204200254ad7c2102200c41206a210c2009417c6a22094104470d000b0b0240200728029c0241ffffffff0371450d0020072802980210230b201e0d030240200420084201882006423f8684562002200642018822045620022004511b450d0020074188026a41086a200741f8016a41086a280200360200200720072903f80137038802411010212209450d022007420437029c02200720093602980220074198026a410041041079200741f0026a41086a220920072802a002220c41046a360200200728029802200c4102746a220c428080808010370208200c420037020020072007290398023703f002200741f0026a107820074198026a41086a2009280200360200200720072903f00237039802200741f8016a20074188026a20074198026a107a200728029c0241ffffffff0371450d0020072802980210230b200741f0026a41086a200741f8016a41086a280200360200200720072903f8013703f0020b200741f0026a107820074198026a41086a2209200741f0026a41086a280200360200200720072903f0023703980220074198026a10784200210202400240200928020022094105744180014d0d00421d21044101211e0c010b4100211e024020090d00420021040c010b200728029802220c200941027422096a417c6a220f280200211f0240200c200f470d00201fad21040c010b200c41786a210f201fad2104200741106a211f4120210c420021020340200741086a200f20096a3502004200200c41e0007110a405201f29030020027c2007290308220220047c2204200254ad7c2102200c41206a210c2009417c6a22094104470d000b0b0240200728029c0241ffffffff0371450d0020072802980210230b02400240201e450d00200041ccafc000360204200041086a4119360200410121090c010b200041106a2002370300200041086a2004370300410021090b20002009360200201141ffffffff0371450d03201210230c030b1033000b102a000b200720043e029c02200741acaec0003602980241fcaec000412f20074198026a41acafc00041bcafc0001034000b20074180036a24000b1c00200128021841e4aac200410f2001411c6a28020028020c1100000bb00301047f230041c0006b2202240020002802002103410121000240200128021841b29cc000410c2001411c6a28020028020c1100000d0002400240200328020822000d0020032802002200200328020428020c11030042e4aec285979ba58811520d012002200036020c2002410936021420022002410c6a36021020012802182104200128021c2105410121002002413c6a41013602002002420237022c200241c09cc0003602282002200241106a36023820042005200241286a10310d020c010b2002200036020c2002410836021420022002410c6a36021020012802182104200128021c2105410121002002413c6a41013602002002420237022c200241c09cc0003602282002200241106a36023820042005200241286a10310d010b200328020c2100200241106a41146a4101360200200241106a410c6a410136020020022000410c6a3602202002200041086a360218200241043602142002200036021020012802182100200128021c2101200241286a41146a41033602002002420337022c200241d09cc0003602282002200241106a36023820002001200241286a103121000b200241c0006a240020000bed04020b7f037e230041206b22022400024002400240024020012802082203410c6c41046a2204417f4c0d00200128020021050240024020040d00410121060c010b200410212206450d020b2002410036020820022004360204200220063602002003200210610240024020030d002002280208210420022802042107200228020021080c010b20052003410c6c6a21092005210603402006280200210a200641086a280200220420021061024002402002280204220b2002280208220c6b2004490d0020022802002108200b21070c010b200c20046a2208200c490d05200b41017422072008200720084b1b22074100480d0502400240200b0d00024020070d00410121080c020b2007102122080d010c080b20022802002108200b2007460d002008200b200710252208450d070b20022007360204200220083602000b2008200c6a200a200410a1051a2002200c20046a22043602082006410c6a22062009470d000b0b2004ad4220862008ad8410012204290000210d200441086a290000210e200441106a290000210f200241186a2206200441186a290000370300200241106a220c200f370300200241086a220b200e3703002002200d37030020041023200041186a2006290300370000200041106a200c290300370000200041086a200b2903003700002000200229030037000002402007450d00200810230b02402003450d002003410c6c21062005210403400240200441046a280200450d00200428020010230b2004410c6a2104200641746a22060d000b0b0240200141046a2802002204450d002004410c6c450d00200510230b200241206a24000f0b1032000b1033000b102c000b102a000b910301067f230041106b2202240002400240024002400240024002400240200128020022030d00410121040c010b0240200141086a28020041056a2204417f4c0d0020040d0120024100360208200242013703000c020b1032000b200410212205450d03200241003602082002200436020420022005360200024020030d00200541003a0000410121040c030b20040d010b410110212205450d0420024101360204200220053602000b200541013a000020024101360208200141086a2802002204200210610240024020022802042206200228020822056b2004490d00200228020021010c010b200520046a22012005490d03200641017422072001200720014b1b22074100480d030240024020060d00024020070d00410121010c020b2007102122010d010c060b2002280200210120062007460d0020012006200710252201450d050b20022007360204200220013602000b200120056a2003200410a1051a200520046a21040b20002002290300370200200041086a2004360200200241106a24000f0b1033000b102c000b102a000b900706017f017e067f017e057f017e230041306b220124000240024010022202422088a722030d00410121040c010b2002a721040b2001200336022420012004360220024002400240024002402003450d0020042d0000210520012003417f6a3602242001200441016a360220200541014b0d00024020050e020004000b200141186a200141206a10880120012802180d0020012802242206200128021c2205490d002005417f4c0d020240024020050d00410121070c010b200510272207450d02200720012802202208200510a1051a2001200620056b3602242001200820056a3602200b2007450d00200141106a200141206a1088012005ad22024220862002842209a7210a024020012802100d002001280214220b2001280224410c6e22052005200b4b1bad420c7e2202422088a70d032002a72205417f4c0d030240024020050d004104210c0c010b20051021220c450d030b2005410c6ead21020240200b450d00410021050340200141086a200141206a10880102400240024020012802080d002001280224220d200128020c2206490d002006417f4c0d080240024020060d00410121080c010b200610272208450d0820082001280220220e200610a1051a2001200d20066b3602242001200e20066a3602200b20052002a7470d02024002400240200541016a220d2005490d002005410174220e200d200e200d4b1bad420c7e220f422088a70d00200fa7220d4100480d00024020050d00200d0d024104210c0c050b2005410c6c2205200d460d04024020050d00200d0d024104210c0c050b200c2005200d1025220c450d020c040b102c000b200d1021220c0d020b102a000b02402005450d002005410c6c2106200c210503400240200541046a280200450d00200528020010230b2005410c6a2105200641746a22060d000b0b2002a72205450d042005410c6c450d04200c10230c040b2002422088a72105200d410c6ead21020b200c2005410c6c6a220d2006ad220f422086200f84370204200d2008360200200242ffffffff0f83200541016a2205ad422086842102200b417f6a220b0d000b0b200c450d002007450d012009422088a721050c050b200a450d00200710230b418cb2c000412e200141286a41bcb3c00041bcb2c0001034000b1033000b1032000b410021070b2000200a36020420002007360200200041106a20023702002000410c6a200c360200200041086a200536020002402003450d00200410230b200141306a24000bcf0201067f0240024020012802042202450d00200128020022032d0000210420012002417f6a2205360204410121062001200341016a3602000240200441037122074103460d0002400240024020070e03000102000b20044102762107410021060c040b41012106024020050d000c040b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d03200141fcff03714102762107410021060c030b20054103490d01200341036a2d0000210620032f0001210720012002417c6a3602042001200341046a3602002007200641107472410874200472220141808004492106200141027621070c020b0240200441034d0d000c020b20054104490d012003280001210720012002417b6a3602042001200341056a36020020074180808080044921060c010b410121060b20002007360204200020063602000b810103017f017e027f230041106b220324000240024002402002ad4220862000ad8410032204428080808010540d00410121022004a722052d0000220641014b0d0020060e020102010b418cb2c000412e200341086a41bcb3c00041bcb2c0001034000b410021020b2005102302402001450d00200010230b200341106a240020020b21002000417f6a41ff01712002ad4220862001ad842004ad4220862003ad8410000baa0201067f230041206b22022400024002402001422088a722030d00410121040c010b2001a721040b200220033602142002200436021002402003450d0020042d0000210520022003417f6a3602142002200441016a360210200541014b0d0041002103024002400240024020050e020100010b200241086a200241106a10880120022802080d0320022802142206200228020c2205490d032005417f4c0d010240024020050d00410121030c010b200510272203450d03200320022802102207200510a1051a2002200620056b3602142002200720056a3602100b2003450d032005ad220142208620018421010b200020013702042000200336020020041023200241206a24000f0b1032000b1033000b418cb2c000412e200241186a41bcb3c00041bcb2c0001034000b9d0102017f017e230041106b2206240002402002ad4220862001ad842004ad4220862003ad84200510062207422088a72204450d002007a722052d0000220341014b0d00410021010240024020030e020100010b2004417f6a4104490d0120052800012102410121010b200510232000200236020420002001360200200641106a24000f0b418cb2c000412e200641086a41bcb3c00041bcb2c0001034000bcf0303017f017e037f230041d0006b2203240002402001200210072204422088a72201450d002004a722052d0000220241014b0d002001417f6a210602400240024020020e020001000b41002101200341003a0049200541016a21070240034020062001460d01200341286a20016a200720016a2d00003a00002003200141016a22023a00492002210120024121470d000b200341106a200341316a290000370300200341186a200341396a290000370300200341206a200341c1006a2900003703002003200329002937030820032d0028210241002106200341086a21010c020b200141ff0171450d02200341003a00490c020b2006450d0120052d0001220241034f0d01200341086a41186a200341286a41186a290000370300200341086a41106a200341286a41106a290000370300200341086a41086a200341286a41086a2900003703002003200329002837030841012106200341086a21010b200020023a0001200020063a0000200041026a20012900003700002000410a6a200141086a290000370000200041126a200141106a2900003700002000411a6a200141186a29000037000020051023200341d0006a24000f0b418cb2c000412e200341286a41bcb3c00041bcb2c0001034000be90503017f017e0b7f230041e0006b220224002002200136020c02400240024002402002410c6a10082203422088a722010d0020004100360208200042013702000c010b2002200136021420022003a722043602102002200241106a1088010240024020022802000d0020022802042205200228021422064105762201200120054b1b22014105742207417f4c0d040240024020010d00410121080c010b200710212208450d040b2001ad210302402005450d00410021094100210a03402006210b200241003a0058200a41016a210a410021010240024002400340200b2001460d01200241386a20016a200228021022072d00003a00002002200741016a3602102002200141016a22073a00582007210120074120470d000b200241186a41186a220c200241386a41186a290300370300200241186a41106a220d200241386a41106a290300370300200241186a41086a220e200241386a41086a2903003703002002200229033837031820092003a7470d020240200941016a22012009490d00200941017422062001200620014b1b220141ffffff3f712001470d002001410574220141004e0d020b102c000b200241003602140240200141ff0171450d00200241003a00580b200342ffffff3f83500d04200810230c040b024002400240024020090d0020010d01410121080c030b200941057422092001460d02024020090d0020010d01410121080c030b20082009200110252208450d010c020b2001102122080d010b102a000b2003422088a721092001410576ad21030b200b20076b2106200820094105746a22012002290318370000200141186a200c290300370000200141106a200d290300370000200141086a200e290300370000200342ffffffff0f83200941016a2209ad422086842103200a2005470d000b2002200b20076b3602140b20080d010b418cb2c000412e200241386a41fcb1c00041fcb0c0001034000b2000200337020420002008360200200410230b200241e0006a24000f0b1033000b1032000b970403017f017e017f23004190016b22052400200520013602040240200541046a20022004ad4220862003ad8410092206422088a72201450d002006a722072d0000220341014b0d004100210202400240024020030e020100010b41002102200541003a008801200741016a21042001417f6a2101034020012002460d02200541c8006a20026a200420026a2d00003a00002005200241016a22033a00880120032102200341c000470d000b200541086a41386a200541c8006a41386a290300370300200541086a41306a200541c8006a41306a290300370300200541086a41286a200541c8006a41286a290300370300200541086a41206a200541c8006a41206a290300370300200541086a41186a200541c8006a41186a290300370300200541086a41106a200541c8006a41106a290300370300200541086a41086a200541c8006a41086a29030037030020052005290348370308410121020b200020023a000020002005290308370001200041096a200541106a290300370000200041116a200541186a290300370000200041196a200541206a290300370000200041216a200541286a290300370000200041296a200541306a290300370000200041316a200541386a290300370000200041396a200541c0006a2903003700002007102320054190016a24000f0b200241ff0171450d00200541003a0088010b418cb2c000412e200541c8006a41bcb3c00041bcb2c0001034000b980401067f20012802042102024002400240024020012802004101470d002001410c6a280200220141046a2203417f4c0d0102400240024002400240024002400240024002402003450d00200310212204450d0c200141c000490d04200141808001490d052001418080808004490d06200441033a00002003417f6a41034d0d01200321050c030b41012103410110212204450d07200441033a0000410521050c010b200341017422064105200641054b1b22054100480d0720032005460d010b20042003200510252204450d050b20042001360001410521060c030b200420014102743a000041012106200321050c020b02400240200341014d0d00200321050c010b2003200341017422064102200641024b1b2205460d0020042003200510252204450d030b41022106200420014102744101723b00000c010b02400240200341034d0d00200321050c010b200341017422064104200641044b1b22054100480d0320032005460d0020042003200510252204450d020b20042001410274410272360000410421060b0240200520066b2001490d00200521030c060b200620016a22032006490d01200541017422072003200720034b1b22034100480d0120052003460d05200420052003102522040d050b102a000b102c000b20002002200141086a28020010740f0b1032000b1033000b200420066a2002200110a1051a2000200620016a36020820002003360204200020043602000b1c00200128021841e4aac200410f2001411c6a28020028020c1100000b8b0101017f4197acc500ad4280808080d00184100a024002400240024020002d00000e0400010203000b200041046a290200100a0f0b41a3b6c000ad4280808080e00184100a0f0b4199b6c000ad4280808080a00184100a0f0b2000310001100b200041026a310000100b0240200041046a2802002201450d00200041086a3502004220862001ad84100a0b0b1c00200128021841e4aac200410f2001411c6a28020028020c1100000bc10304017f027e067f017e230041206b22032400200229030021042001290300210520022802102106200141106a200141186a2207280200200241186a2208280200220910950120012802102007280200220a410c6c6a20062009410c6c10a1051a200841003602002007200a20096a2209360200200341086a200936020020032001290210370300200228021c21082001411c6a200141246a2207280200200241246a220a2802002209109501200128021c2007280200220b410c6c6a20082009410c6c10a1051a200a41003602002007200b20096a2209360200200341106a41086a20093602002003200129021c370310427f200520047c220420042005541b2105200229030822042001290308220c200c2004561b21040240024020012d0028450d004101210120022d00280d010b410021010b20002005370300200020032903003702102000200329031037021c200020013a002820002004370308200041186a200341086a280200360200200041246a200341106a41086a2802003602000240200241146a2802002201450d002001410c6c450d00200610230b0240200241206a2802002201450d002001410c6c450d00200810230b200341206a24000bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad420c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003410c6c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a2001410c6e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42e0007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341e0006c22032001460d03024020030d0020010d02410821020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141e0006e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff3f712001470d00200141057422014100480d00024020030d0020010d02410821020c040b20002802002102200341057422032001460d03024020030d0020010d02410821020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a20014105763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42287e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341286c22032001460d03024020030d0020010d02410821020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141286e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad4288027e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b2000280200210220034188026c22032001460d03024020030d0020010d02410821020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a20014188026e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff3f712001470d00200141057422014100480d00024020030d0020010d02410121020c040b20002802002102200341057422032001460d03024020030d0020010d02410121020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a20014105763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42c4007e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341c4006c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141c4006e3602000b0bb40101027f0240200041046a280200220320016b20024f0d000240024002400240200120026a22042001490d00200341017422022004200220044b1b220420046a22012004490d0020014100480d00024020030d0020010d02410221030c040b2000280200210320022001460d03024020020d0020010d02410221030c040b20032002200110252203450d020c030b102c000b2001102122030d010b102a000b20002003360200200041046a20014101763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42c1007e2204422088a70d002004a722014100480d00024020030d0020010d02410121020c040b20002802002102200341c1006c22032001460d03024020030d0020010d02410121020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141c1006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42147e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341146c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141146e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff1f712001470d00200141067422014100480d00024020030d0020010d02410821020c040b20002802002102200341067422032001460d03024020030d0020010d02410821020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a20014106763602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff00712001470d00200141047422014100480d00024020030d0020010d02410421020c040b20002802002102200341047422032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a20014104763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42c8007e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341c8006c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141c8006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42247e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341246c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141246e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad421c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003411c6c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a2001411c6e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42307e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341306c22032001460d03024020030d0020010d02410821020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141306e3602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff01712001470d00200141037422014100480d00024020030d0020010d02410421020c040b20002802002102200341037422032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a20014103763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad422c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003412c6c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a2001412c6e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42347e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341346c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141346e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff3f712001470d00200141057422014100480d00024020030d0020010d02410421020c040b20002802002102200341057422032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a20014105763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d8007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d8006c22032001460d03024020030d0020010d02410821020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141d8006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42287e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341286c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141286e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d0027e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d0026c22032001460d03024020030d0020010d02410821020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141d0026e3602000b0bbc0102027f017e0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1bad42c8037e2204422088a70d002004a722024100480d00024020010d0020020d02410821030c040b20002802002103200141c8036c22012002460d03024020010d0020020d02410821030c040b20032001200210252203450d020c030b102c000b2002102122030d010b102a000b20002003360200200041046a200241c8036e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42b0027e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341b0026c22032001460d03024020030d0020010d02410821020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141b0026e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42387e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341386c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141386e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42227e2204422088a70d002004a722014100480d00024020030d0020010d02410221020c040b20002802002102200341226c22032001460d03024020030d0020010d02410221020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141226e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42187e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341186c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141186e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42c0017e2204422088a70d002004a722014100480d00024020030d0020010d02410121020c040b20002802002102200341c0016c22032001460d03024020030d0020010d02410121020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141c0016e3602000b0bb90102027f017e0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1bad42187e2204422088a70d002004a722024100480d00024020010d0020020d02410821030c040b20002802002103200141186c22012002460d03024020010d0020020d02410821030c040b20032001200210252203450d020c030b102c000b2002102122030d010b102a000b20002003360200200041046a200241186e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff1f712001470d00200141067422014100480d00024020030d0020010d02410421020c040b20002802002102200341067422032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a20014106763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d0007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d0006c22032001460d03024020030d0020010d02410821020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141d0006e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42f0007e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341f0006c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141f0006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42307e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341306c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a200141306e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad423c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003413c6c22032001460d03024020030d0020010d02410421020c040b20022003200110252202450d020c030b102c000b2001102122020d010b102a000b20002002360200200041046a2001413c6e3602000b0bf90403027f017e057f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a200341086a290000370300200220043703002003102341eecec000ad4280808080800284100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000b8b0b04047f017e127f037e230041d0036b22012400200141f0006a41186a4200370300200141f0006a41106a22024200370300200141f0006a41086a2203420037030020014200370370418fcdc200ad4280808080f00084100c220429000021052003200441086a290000370300200120053703702004102341b8dbc100ad4280808080900184100c22042900002105200141206a41086a2206200441086a2900003703002001200537032020041023200220012903202205370300200141c0006a41086a22042003290300370300200141c0006a41106a2005370300200141c0006a41186a200629030037030020012001290370370340200141f0006a200141c0006a10ba0102400240024020012903704202510d002000280208210320002802042107200028020021082001200228020010b801200141f0006a200128020022092001280208220a10bb012004200141f0006a410c6a290200370300200120012902743703400240024020012802704101460d00200141106a410c6a4100360200200142003703100c010b200141106a41086a200141c0006a41086a290300370300200120012903403703100b02402003450d002008200341246c6a210b20014184016a210c2001411c6a210d200141106a410472210e200141e8006a210f200141c0006a41206a211020082111034020112802202112200141206a41186a2213201141186a290000370300200141206a41106a2214201141106a290000370300200141206a41086a2215201141086a290000370300200120112900003703200240024020012802142206450d00200128021821160c010b200141f0006a410041e00210a0051a200f410036020020104200370300200141c0006a41186a22004200370300200141c0006a41106a22034200370300200141c0006a41086a220442003703002001420037034041940310212206450d0541002116200641003b010620064100360200200641086a200141f0006a41e00210a1051a20064190036a200f28020036020020064188036a201029030037020020064180036a2000290300370200200641f8026a2003290300370200200641f0026a2004290300370200200620012903403702e80220014100360218200120063602140b201141246a2111024002400340200641086a210320062f01062217410574210041002104024003402000450d01200141206a2003412010a3052202450d03200041606a2100200441016a2104200341206a21032002417f4a0d000b2004417f6a21170b02402016450d002016417f6a2116200620174102746a4194036a28020021060c010b0b200141c0006a41186a20132903002205370300200141c0006a41106a20142903002218370300200141c0006a41086a2015290300221937030020012001290320221a370340200c201a370200200c41086a2019370200200c41106a2018370200200c41186a20053702002001200d360280012001201736027c2001200e3602782001200636027420014100360270200141f0006a410010bc0121000c010b200620044102746a41e8026a21000b2000200028020020126a3602002001200128021020126a3602102011200b470d000b0b02402007450d00200741246c450d00200810230b200141fc006a200141106a41086a290300370200200120012903102205370274200141013602702001410036024820014201370340410410212200450d0220002005a73600002001200036024020014284808080c000370244200141f0006a41086a2203200141c0006a10bd0120012802442100200aad4220862009ad84200135024842208620012802402204ad84100e02402000450d00200410230b02402001280270450d00200310be010b2001280204450d01200910230c010b200041046a2802002203450d00200341246c450d00200028020010230b200141d0036a24000f0b102a000bd60202057f027e230041d0006b220224002002412036020420022001360200200241086a2001ad42808080808004841010108b0102400240200228020822010d00200042023703000c010b200228020c210302400240200241106a28020022044104490d0020044104460d0020012d0004220541014b0d0020012800002106420021070240024020050e020100010b2004417b6a4108490d0120012900052108420121070b20002008370308200041106a20063602000c010b20024100360220200242013703182002410a36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c20024180c5c6003602382002200241286a360248200241346a4184a5c200200241386a10311a2002350220422086200235021884100a0240200228021c450d00200228021810230b420221070b200020073703002003450d00200110230b200241d0006a24000bcd0b030e7f047e087f230041a0046b220324002003200236021420032001360210200341186a2002ad4220862001ad841010108b0102400240200328021822040d00200041003602000c010b200328021c21052003200341206a280200220136022c2003200436022802400240024020014104490d0020032001417c6a36022c2003200441046a36022820042800002106200341086a200341286a10880120032802080d00200328020c21072003410036024820034100360240200341c0006a41086a210802400240024002402007450d00200341d4016a2109200328022c210a200341b8016a210b4100210c034041002101200341003a00e001200c41016a210c024002400340200a2001460d01200341c0016a20016a2003280228220d2d00003a00002003200d41016a3602282003200141016a22023a00e0012002210120024120470d000b20034190016a41086a220e200341c0016a41086a29030037030020034190016a41106a220f200341c0016a41106a29030037030020034190016a41186a2210200341c0016a41186a290300370300200320032903c001370390012003200a20026b220136022c200141044f0d010c050b2003410036022c200141ff0171450d04200341003a00e001410021010c050b200341d0006a41086a200e2903002211370300200341d0006a41106a200f2903002212370300200341d0006a41186a20102903002213370300200320032903900122143703502003200d41056a36022820032001417c6a220a36022c200d2800012115200341f0006a41186a22162013370300200341f0006a41106a22172012370300200341f0006a41086a22182011370300200320143703700240024020032802402219450d002003280244211a0c010b200341c0016a410041e00210a0051a200b410036020020034190016a41206a2201420037030020104200370300200f4200370300200e4200370300200342003703900141940310212219450d034100211a201941003b010620194100360200201941086a200341c0016a41e00210a1051a20194190036a200b28020036020020194188036a200129030037020020194180036a2010290300370200201941f8026a200f290300370200201941f0026a200e29030037020020192003290390013702e80220034100360244200320193602400b024002400340201941086a210220192f0106221b41057421014100210d024003402001450d01200341f0006a2002412010a305221c450d03200141606a2101200d41016a210d200241206a2102201c417f4a0d000b200d417f6a211b0b0240201a450d00201a417f6a211a2019201b4102746a4194036a28020021190c010b0b201020162903002211370300200f20172903002212370300200e201829030022133703002003200329037022143703900120092014370200200941086a2013370200200941106a2012370200200941186a2011370200200320083602d0012003201b3602cc01200320193602c401200341003602c0012003200341c0006a3602c801200341c0016a201510bc011a0c010b2019200d4102746a41e8026a20153602000b200c2007470d000b0b410121010c020b102a000b410021010b200341306a41086a20082802002202360200200320032903402211370330200341c0016a41086a2002360200200320113703c00120010d01200341c0016a10be010b41002101200341003602980120034201370390012003410a3602742003200341106a360270200320034190016a360250200341d4016a4101360200200342013702c40120034180c5c6003602c0012003200341f0006a3602d001200341d0006a4184a5c200200341c0016a10311a20033502980142208620033502900184100a200328029401450d0120032802900110230c010b20034190016a41086a200341c0016a41086a2802002201360200200320032903c00122113703900120002006360204200041086a2011370200200041106a2001360200410121010b200020013602002005450d00200410230b200341a0046a24000bed0701087f23004190046b2202240020002802102203200328020041016a360200200241086a2203200041086a29020037030020022000290200370300200241306a41186a2000412c6a290000370300200241306a41106a200041246a290000370300200241306a41086a2000411c6a29000037030020022000290014370330200241d0006a2002200241306a200110b40402400240024020022d00504101470d002003200241d9006a290000370300200241106a200241e1006a290000370300200241186a200241e9006a29000037030020022002290051370300200241d0006a412c6a280200210120024188016a280200210420024184016a280200210320024180016a2802002105200228028c012106200241f8006a28020022002802002207450d0120002f01042108200241f4006a2802002109200241d0006a410172210003402002200841ffff037136022c20022001360228200220073602242002200941016a360220200241306a41186a200241186a2201290300370300200241306a41106a200241106a2207290300370300200241306a41086a200241086a220829030037030020022002290300370330200241d0006a200241206a200241306a20052003200410b50420022d00504101470d032008200041086a2900003703002007200041106a2900003703002001200041186a29000037030020022000290000370300200228027c2101200228028801210420022802840121032002280280012105200228027822082802002207450d0220082f01042108200228027421090c000b0b200241d0006a41086a280200200241d0006a41106a2802004102746a41e8026a21060c010b200241d0006a410272410041be0310a0051a02400240024041c40310212200450d0020004100360200200041046a200241d0006a41c00310a1051a200020012802002207360294032001200036020020012001280204220841016a360204200741003b010420072000360200200241d0006a41186a200241186a290300370300200241d0006a41106a200241106a290300370300200241d0006a41086a200241086a2903003703002002200229030037035020082004470d0120002f01062201410a4b0d02200020014105746a220441206a200241d0006a41186a290300370000200441186a200241d0006a41106a290300370000200441106a200241d0006a41086a290300370000200441086a2002290350370000200020014102746a41e8026a20053602002000200141016a22014102746a4194036a2003360200200020013b0106200320013b0104200320003602000c030b102a000b4183dac4004130418c94c700102d000b41dcd9c4004127418c94c700102d000b20024190046a240020060bf90403067f027e017f230041c0006b22022400200041086a28020022032001106102400240024020002802002204450d00024020002802042205450d002005210620042107034020072802940321072006417f6a22060d000b200421060340200620062f01064102746a4194036a28020021062005417f6a22050d000b200241186a2105200721040c020b200241186a2105200421060c010b410021042002410036021c200241186a21050c010b2002200636021c200241246a20062f010636020020022000360220200241003602180b200241086a41086a200541086a2902002208370300200220052902002209370308200241246a4100360200200241306a2008370300200220003602202002200436021c20024100360218200220093703282002200336023802402003450d00034020022003417f6a360238200241186a410020041b2207280200210620072802082100024002400240200728020c2205200728020422032f01064f0d00200321040c010b0240034020032802002204450d01200641016a210620032f0104210520042103200520042f0106490d020c000b0b2000ad2108410021040c010b2005ad4220862000ad8421080b2008422088a7220041016a21052008a7210a0240024020060d00200421030c010b200420054102746a4194036a2802002103410021052006417f6a2206450d00034020032802940321032006417f6a22060d000b0b2007200536020c2007200a36020820072003360204200741003602002001200420004105746a41086a412010622002200420004102746a41e8026a28020036023c20012002413c6a4104106220022802382203450d01200228021c21040c000b0b200241c0006a24000bb50201047f024020002802002201450d0020002802082102024020002802042200450d00034020012802940321012000417f6a22000d000b0b02402002450d004100210303400240024002402001450d002002417f6a2102200320012f0106490d0141002104034002400240200128020022000d0041002103410021000c010b200441016a210420012f010421030b2001102320002101200320002f01064f0d000b200341016a2103024020040d00200021010c030b200020034102746a4194036a2802002101410021032004417f6a2200450d02034020012802940321012000417f6a22000d000c030b0b41d095c700412b41c491c700102d000b200341016a21030b20020d000b0b2001450d0020012802002100200110232000450d00034020002802002101200010232001210020010d000b0b0baa0703027f017e067f230041e0006b22032400418fcdc200ad4280808080f00084100c22042900002105200341086a200441086a290000370300200320053703002004102341ecc4c000ad4280808080b00284100c22042900002105200341106a41086a200441086a2900003703002003200537031020041023200320013602302003200341306aad4280808080c00084100d220429000037034020041023200341d4006a2201200341346a360200200341003a00582003200341c0006a41086a220636024c2003200341306a3602502003200341c0006a360248200341206a200341c8006a1065024002400240024002400240412010212204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad4280808080800484100d2202290000370340200210232001200441206a360200200341003a0058200320043602502003200636024c2003200341c0006a360248200341306a200341c8006a1065200410232003280228220741206a2201200328023822086a2202417f4c0d01200328023021092003280220210a024002402002450d00200210212204450d022002410f4d0d01200221060c050b200241017422044110200441104b1b2206102122040d040c060b200241017422064110200641104b1b220641004e0d020c040b1033000b1032000b20022006460d0020042002200610252204450d020b20042003290300370000200441086a200341086a2903003700000240024020064170714110460d002006210b0c010b2006410174220b4120200b41204b1b220b4100480d012006200b460d0020042006200b10252204450d020b20042003290310370010200441186a200341106a41086a29030037000002400240200b41606a2007490d00200b21060c010b2007415f4b0d01200b41017422062001200620014b1b22064100480d01200b2006460d002004200b200610252204450d020b200441206a200a200710a1051a02400240200620016b2008490d002006210b0c010b200120086a2001490d012006410174220b2002200b20024b1b220b4100480d01024020060d000240200b0d00410121040c020b200b10212204450d030c010b2006200b460d0020042006200b10252204450d020b200420016a2009200810a1051a200020023602082000200b3602042000200436020002402003280234450d00200910230b02402003280224450d00200a10230b200341e0006a24000f0b102c000b102a000baa0703027f017e067f230041e0006b22032400418fcdc200ad4280808080f00084100c22042900002105200341086a200441086a290000370300200320053703002004102341ffc4c000ad4280808080b00284100c22042900002105200341106a41086a200441086a2900003703002003200537031020041023200320013602302003200341306aad4280808080c00084100d220429000037034020041023200341d4006a2201200341346a360200200341003a00582003200341c0006a41086a220636024c2003200341306a3602502003200341c0006a360248200341206a200341c8006a1065024002400240024002400240412010212204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad4280808080800484100d2202290000370340200210232001200441206a360200200341003a0058200320043602502003200636024c2003200341c0006a360248200341306a200341c8006a1065200410232003280228220741206a2201200328023822086a2202417f4c0d01200328023021092003280220210a024002402002450d00200210212204450d022002410f4d0d01200221060c050b200241017422044110200441104b1b2206102122040d040c060b200241017422064110200641104b1b220641004e0d020c040b1033000b1032000b20022006460d0020042002200610252204450d020b20042003290300370000200441086a200341086a2903003700000240024020064170714110460d002006210b0c010b2006410174220b4120200b41204b1b220b4100480d012006200b460d0020042006200b10252204450d020b20042003290310370010200441186a200341106a41086a29030037000002400240200b41606a2007490d00200b21060c010b2007415f4b0d01200b41017422062001200620014b1b22064100480d01200b2006460d002004200b200610252204450d020b200441206a200a200710a1051a02400240200620016b2008490d002006210b0c010b200120086a2001490d012006410174220b2002200b20024b1b220b4100480d01024020060d000240200b0d00410121040c020b200b10212204450d030c010b2006200b460d0020042006200b10252204450d020b200420016a2009200810a1051a200020023602082000200b3602042000200436020002402003280234450d00200910230b02402003280224450d00200a10230b200341e0006a24000f0b102c000b102a000bae0503027f017e047f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a200341086a29000037030020022004370300200310234192c5c000ad4280808080d00184100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad4280808080800484100d220129000037033020011023200241c4006a200341206a360200200241003a0048200220033602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200310232002280228220541206a2201417f4c0d0120022802202106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bf90403027f017e057f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a200341086a29000037030020022004370300200310234180dcc100ad4280808080d00284100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bae0503027f017e047f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a200341086a290000370300200220043703002003102341bbacc300ad4280808080a00184100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad4280808080800484100d220129000037033020011023200241c4006a200341206a360200200241003a0048200220033602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200310232002280228220541206a2201417f4c0d0120022802202106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bd70503027f017e047f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a200341086a2900003703002002200437030020031023419fc5c000ad4280808080900184100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240410410212203450d0020034104412010252203450d0520032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200128022021052003412041c00010252201450d052001200536002020022001ad4280808080c00484100d220329000037033020031023200241c4006a200141246a360200200241003a0048200220013602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200110232002280228220641206a2203417f4c0d0120022802202107024002402003450d00200310212201450d022003410f4d0d01200321080c050b200341017422014110200141104b1b2208102122010d040c060b200341017422054110200541104b1b220841004e0d020c040b1033000b1032000b20032008460d0020012003200810252201450d020b20012002290300370000200141086a200241086a2903003700000240024020084170714110460d00200821050c010b200841017422054120200541204b1b22054100480d0120082005460d0020012008200510252201450d020b20012002290310370010200141186a200241106a41086a29030037000002400240200541606a2006490d00200521080c010b2006415f4b0d01200541017422082003200820034b1b22084100480d0120052008460d0020012005200810252201450d020b200141206a2007200610a1051a20002003360208200020083602042000200136020002402002280224450d00200710230b200241d0006a24000f0b102c000b102a000bae0503027f017e047f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a200341086a290000370300200220043703002003102341e2c4c000ad4280808080a00184100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad4280808080800484100d220129000037033020011023200241c4006a200341206a360200200241003a0048200220033602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200310232002280228220541206a2201417f4c0d0120022802202106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bcc0503027f017e047f230041e0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a41086a200341086a290000370300200220043703082003102341dcc4c000ad4280808080e00084100c22032900002104200241186a41086a200341086a2900003703002002200437031820031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100f22012900002104200241386a41086a200141086a2900003703002002200437033820011023200241d4006a200341206a360200200241003a0058200220033602502002200241386a41106a36024c2002200241386a360248200241286a200241c8006a1065200310232002280230220541206a2201417f4c0d0120022802282106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290308370000200341086a200241086a41086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290318370010200341186a200241186a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a2000200136020820002007360204200020033602000240200228022c450d00200610230b200241e0006a24000f0b102c000b102a000bae0503027f017e047f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a200341086a290000370300200220043703002003102341d6c4c000ad4280808080e00084100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad4280808080800484100d220129000037033020011023200241c4006a200341206a360200200241003a0048200220033602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200310232002280228220541206a2201417f4c0d0120022802202106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bfc0503027f017e047f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241186a41086a200341086a29000037030020022004370318200310234192c5c000ad4280808080d00184100c22032900002104200241286a41086a200341086a290000370300200220043703282003102320012802002101024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad4280808080800484100d2201290000370348200110232002410c6a200341206a360200200241003a0010200220033602082002200241c8006a41086a3602042002200241c8006a360200200241386a20021065200310232002280240220541206a2201417f4c0d0120022802382106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422074110200741104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290318370000200341086a200241186a41086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290328370010200341186a200241286a41086a2903003700000240200841606a20054f0d002005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a0240200228023c450d00200610230b20022003200110c901200241286a41086a2207200241086a280200360200200220022903003703280240200228020c2201450d002000200229032837020020002002290310370210200041086a20072802003602000b2000200136020c20031023200241d0006a24000f0b102c000b102a000b990502087f017e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841010108b0102400240200328021022010d002000410036020c0c010b200328021421042003200341186a2802002202360224200320013602200240024020024104490d002003200141046a36022020032002417c6a220536022420054104490d00200128000021062003200141086a3602202003200241786a220536022420054104490d00200128000421052003200241746a36022420032001410c6a360220200128000821072003200341206a10880120032802000d002003280224220820032802044102742202490d0002400240024002402002417f4c0d000240024020020d00410121090c010b200210272209450d0220092003280220220a200210a1051a2003200820026b3602242003200a20026a3602200b2009450d0402402002ad220b422086200b84220b422088a722020d00200ba721020c030b024020092002724103710d00200ba722024103710d0020024102762208450d03200b422288a7210a0c040b200ba7450d04200910230c040b1032000b1033000b4100210a02402002450d00200910230b41002108410421090b41000d002009450d00200020083602102000200936020c200020073602082000200536020420002006360200200041146a200a3602000c010b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034180c5c6003602482003200341386a360258200341c4006a4184a5c200200341c8006a10311a2003350230422086200335022884100a0240200328022c450d00200328022810230b2000410036020c0b2004450d00200110230b200341e0006a24000bf90403027f017e057f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a200341086a29000037030020022004370300200310234191cfc000ad4280808080e00184100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bf90403027f017e057f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a200341086a290000370300200220043703002003102341fecec000ad4280808080b00284100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bfa810112047f017e017f017e027f017e057f027e017f017e037f017e097f047e087f017e077f037e230041d0056b22022400200241d8016a41186a22034200370300200241d8016a41106a22044200370300200241d8016a41086a22054200370300200242003703d801418fcdc200ad4280808080f000842206100c22072900002108200241b0036a41086a2209200741086a290000370300200220083703b0032007102320052009290300370300200220022903b0033703d801418cdbc100ad4280808080a001842208100c220a290000210b200241f0036a41086a2207200a41086a2900003703002002200b3703f003200a1023200420022903f003220b370300200241d0046a41086a220a2005290300370300200241d0046a41106a220c200b370300200241d0046a41186a220d2007290300370300200220022903d8013703d004200241d0016a200241d0046a412010cd0120022802d001210e20022802d401210f200342003703002004420037030020054200370300200242003703d8012006100c2203290000210b2009200341086a2900003703002002200b3703b0032003102320052009290300370300200220022903b0033703d8012008100c220329000021082007200341086a290000370300200220083703f00320031023200420022903f0032208370300200a2005290300370300200c2008370300200d2007290300370300200220022903d8013703d0042002200f41016a4100200e1b22103602d801200241d0046aad42808080808004842211200241d8016aad22124280808080c00084100e2006100c220529000021062009200541086a290000370300200220063703b003200510234180dcc100ad4280808080d00284100c220529000021062007200541086a290000370300200220063703f00320051023200220103602a0052002200241a0056aad22064280808080c00084100d22052900003703d00420051023200241e4016a200241a4056a360200200241003a00e8012002200a3602dc012002200241a0056a3602e0012002200241d0046a3602d801200241f0026a200241d8016a106502400240024002400240024002400240024020022802f802220a41206a2209417f4c0d0020022802f002210c0240024002402009450d00200910212205450d062009410f4d0d01200921070c020b200941017422054110200541104b1b2207102122050d010c0a0b200941017422074110200741104b1b22074100480d0820092007460d0020052009200710252205450d090b200520022903b003370000200541086a200241b0036a41086a2903003700000240024020074170714110460d00200721030c010b200741017422034120200341204b1b22034100480d0820072003460d0020052007200310252205450d090b200520022903f003370010200541186a200241f0036a41086a2903003700000240200341606a200a4f0d00200a41206a2207200a490d082003410174220d2007200d20074b1b22074100480d0820032007460d0020052003200710252205450d090b200541206a200c200a10a1051a024020022802f402450d00200c10230b200220013602d8012009ad4220862005ad8420124280808080c00084100e20051023200241d8016a41186a220a4200370300200241d8016a41106a22134200370300200241d8016a41086a22054200370300200242003703d801418fcdc200ad4280808080f000842208100c2207290000210b200241b0036a41086a2209200741086a2900003703002002200b3703b0032007102320052009290300370300200220022903b0033703d8014190d8c100ad4280808080c00184100c2203290000210b200241f0036a41086a2207200341086a2900003703002002200b3703f00320031023200420022903f003370000200441086a2007290300370000200241d0046a41086a2005290300370300200241d0046a41106a2013290300370300200241d0046a41186a200a290300370300200220022903d8013703d004200241c8016a200241d0046a412010cd010240201020022802cc0141016a41d50020022802c8011b6b220320104b0d00200310ce010b200a42003703002013420037030020054200370300200242003703d8012008100c220a29000021082009200a41086a290000370300200220083703b003200a102320052009290300370300200220022903b0033703d80141d5cfc000ad4280808080d00184100c220929000021082007200941086a290000370300200220083703f00320091023201320022903f0032208370300200241a0056a41086a2005290300370300200241a0056a41106a2008370300200241a0056a41186a2007290300370300200220022903d8013703a005200241203602c4022002200241a0056a3602c002200241c8026a2006428080808080048422141010108b01024020022802c8022215450d0020022802cc0221162002200241c8026a41086a2802003602dc02200220153602d802200241d8016a200241d8026a10cf010240024020022802d8012217450d00200241d8016a41086a350200211820022802dc012119200241c0016a200241d8026a1088010240024020022802c0010d0020022802c401221a20022802dc02220741d0006e22052005201a4b1bad42d0007e2206422088a70d052006a72205417f4c0d050240024020050d004108211b0c010b20051021221b450d090b4100210a200241003602e8022002201b3602e0022002200541d0006e221c3602e4020240201a450d00200241f4046a211d200241d8016a41206a211e4100210a4100210302400340200241003a009004200341016a210341002105024002400240034020072005460d01200241f0036a20056a20022802d80222092d00003a00002002200941016a3602d8022002200541016a22093a0090042009210520094120470d000b200241b0046a41086a2205200241f0036a41086a220c290300370300200241b0046a41106a2201200241f0036a41106a220d290300370300200241b0046a41186a220e200241f0036a41186a220f290300370300200220022903f0033703b0042002200720096b3602dc02200241d0046a200241d8026a10d00120022802f00422090d01410021090c020b200241003602dc020240200541ff0171450d00200241003a0090040b410021090c010b201e20022903d004370300200241d8016a41186a2207200e290300370300200241d8016a41106a220e2001290300370300200241d8016a41086a22012005290300370300201e41086a200241d0046a41086a290300370300201e41106a200241d0046a41106a290300370300201e41186a200241d0046a41186a290300370300200241c0056a41086a201d41086a280200360200200220022903b0043703d8012002201d2902003703c005200241f0036a41386a200241d8016a41386a290300370300200241f0036a41306a200241d8016a41306a290300370300200241f0036a41286a200241d8016a41286a290300370300200241f0036a41206a201e290300370300200f2007290300370300200d200e290300370300200c2001290300370300200220022903d8013703f0030b200241b0036a41386a2205200241f0036a41386a290300370300200241b0036a41306a2207200241f0036a41306a290300370300200241b0036a41286a220c200241f0036a41286a290300370300200241b0036a41206a2201200241f0036a41206a290300370300200241b0036a41186a220d200241f0036a41186a290300370300200241b0036a41106a220e200241f0036a41106a290300370300200241b0036a41086a220f200241f0036a41086a29030037030020024190056a41086a221f200241c0056a41086a280200360200200220022903f0033703b003200220022903c0053703900502402009450d00200241f0026a41386a22202005290300370300200241f0026a41306a22212007290300370300200241f0026a41286a2207200c290300370300200241f0026a41206a220c2001290300370300200241f0026a41186a2201200d290300370300200241f0026a41106a220d200e290300370300200241f0026a41086a220e200f29030037030020024180056a41086a220f201f280200360200200220022903b0033703f0022002200229039005370380050240200a20022802e402470d00200241e0026a200a410110b40120022802e002211b20022802e802210a0b201b200a41d0006c6a220520022903f002370300200d290300210620012903002108200c290300210b200729030021222021290300212320202903002124200e290300212520052009360240200541086a20253703002005200229038005370244200541cc006a200f280200360200200541386a2024370300200541306a2023370300200541286a2022370300200541206a200b370300200541186a2008370300200541106a20063703002002200a41016a220a3602e8022003201a460d0220022802dc0221070c010b0b0240200a450d00200a41d0006c2109201b41c4006a21050340024020052802002207450d00200741306c450d002005417c6a28020010230b200541d0006a2105200941b07f6a22090d000b0b20022802e4022205450d02200541d0006c450d02201b10230c020b20022802e402211c0b201b450d000240024020022802dc022205450d0020022005417f6a3602dc02200220022802d802220541016a3602d80220052d000022264103490d010b0240200a450d00200a41d0006c2109201b41c4006a21050340024020052802002207450d00200741306c450d002005417c6a28020010230b200541d0006a2105200941b07f6a22090d000b0b0240201c450d00201c41d0006c450d00201b10230b201941ffffff3f71450d030c020b20184220862019ad8421240c030b201941ffffff3f71450d010b201710230b200241003602f803200242013703f0032002410a3602b4032002200241c0026a3602b0032002200241f0036a3602f002200241ec016a4101360200200242013702dc0120024180c5c6003602d8012002200241b0036a3602e801200241f0026a4184a5c200200241d8016a10311a20023502f80342208620023502f00384100a024020022802f403450d0020022802f00310230b410321260b02402016450d00201510230b20264103460d00201410110c070b200241003602d002200242083703c802200241003602e802200242013703e002418fcdc200ad4280808080f00084100c22052900002106200241b0036a41086a2209200541086a290000370300200220063703b0032005102341bbacc300ad4280808080a00184100c22052900002106200241f0036a41086a2207200541086a290000370300200220063703f00320051023412010212205450d03200520022903b003370000200520022903f003370010200541086a2009290300370000200541186a220a2007290300370000412010212209450d0320092005290000370000200941186a200a290000370000200941106a200541106a290000370000200941086a200541086a290000370000200241b0046a41026a220a200241d8016a41026a2d00003a0000200220022f00d8013b01b004200241a0056a41106a42a0808080800437030041002107200241003a00b805200220053602ac05200242a080808080043702a405200220093602a005200241bb056a200a2d00003a0000200220022f01b0043b00b905200241d8016a200241a0056a10d20141012115024020022802d8014101470d00200241d8016a410472210a41002107410121154108211a410021030340200241f0036a41206a200a41206a280200360200200241f0036a41186a2205200a41186a2902002206370300200241f0036a41106a2209200a41106a2902002208370300200241f0036a41086a2220200a41086a290200220b3703002002200a29020022223703f003200241f0026a41186a220e2006370300200241f0026a41106a220f2008370300200241f0026a41086a221f200b370300200220223703f002200241d8016a41186a220c2005290300370300200241d8016a41106a22012009290300370300200241d8016a41086a220d2020290300370300200220022903f0033703d801200241b0016a200241f0026a10d301200241b0016a41086a290300210620022903b0012108412010212209450d0a200920022903f002370000200941186a200e290300370000200941106a200f290300370000200941086a201f290300370000200241b0036a41086a200d290300220b370300200241b0036a41106a20012903002222370300200241b0036a41186a200c2903002223370300200220022903d80122243703b003200241d0046a41186a22202023370300200241d0046a41106a22212022370300200241d0046a41086a221e200b370300200220243703d0040240200320022802cc02470d00200241c8026a20034101109f0120022802c802211a20022802d00221030b201a20034106746a2205200637030820052008370300201e2903002106202129030021082020290300210b20022903d0042122200541346a4281808080103702002005200936023020052022370310200541286a200b370300200541206a2008370300200541186a20063703002002200341016a22033602d002200c200e2903003703002001200f290300370300200d201f290300370300200220022903f0023703d8010240200720022802e402470d00200241e0026a20074101109a0120022802e002211520022802e80221070b201520074105746a220520022903d801370000200541186a200c290300370000200541106a2001290300370000200541086a200d2903003700002002200741016a22073602e802200241d8016a200241a0056a10d20120022802d8014101460d000b0b024020022802a405450d0020022802a00510230b024020022802b005450d0020022802ac0510230b418fcdc200ad4280808080f00084100c22052900002106200241b0036a41086a2209200541086a290000370300200220063703b0032005102341e2c4c000ad4280808080a00184100c22052900002106200241f0036a41086a220a200541086a290000370300200220063703f00320051023412010212205450d03200520022903b003370000200520022903f003370010200541086a2009290300370000200541186a2203200a290300370000412010212209450d0320092005290000370000200941186a2003290000370000200941106a200541106a290000370000200941086a200541086a290000370000200241d8026a41026a2203200241d8016a41026a2d00003a0000200220022f00d8013b01d802200241d8016a41106a220a42a08080808004370300200241003a00f001200220053602e401200242a080808080043702dc01200220093602d801200241f3016a20032d00003a0000200220022f01d8023b00f101200241c8026a200241d8016a10d401200241d8016a41186a22094200370300200a4200370300200241d8016a41086a22054200370300200242003703d801418fcdc200ad4280808080f000842206100c220c2900002108200241b0036a41086a2203200c41086a290000370300200220083703b003200c102320052003290300370300200220022903b0033703d80141e4d8c100ad4280808080e00184100c22012900002108200241f0036a41086a220c200141086a290000370300200220083703f00320011023201320022903f003370000201341086a220d200c290300370000200241a0056a41086a220e2005290300370300200241a0056a41106a220f200a290300370300200241a0056a41186a221f2009290300370300200220022903d8013703a005200241a8016a200241a0056a412010cd0120022802ac01212720022802a801212820094200370300200a420037030020054200370300200242003703d8012006100c220129000021062003200141086a290000370300200220063703b0032001102320052003290300370300200220022903b0033703d801418cd9c100ad4280808080d00284100c22032900002106200c200341086a290000370300200220063703f00320031023201320022903f003370000200d200c290300370000200e2005290300370300200f200a290300370300201f2009290300370300200220022903d8013703a005200241a0016a200241a0056a412010cd0120022802a401210a20022802a001210320022802e402211620022802c802211a20022802cc02211d20022802d002211e200241003602c805200241003602c005201e20076aad42e0007e2206422088a70d002006a72205417f4c0d004108210902402005450d00200510212209450d040b200a410420031b221941014b2129200241003602a805200220093602a0052002200541e0006e3602a405200241003602b803200242083703b003200241b0036a41002007410574220a41057510a90120022802b803212102402007450d00200a41606a410576212a20022802b003202141d8006c6a210320024188026a210920024180026a212041002107201521050340200241b0046a41186a220c200541186a2201290000370300200241b0046a41106a220d200541106a220e290000370300200241b0046a41086a220f200541086a221f290000370300200220052900003703b004200241f0036a41186a2001290000370300200241f0036a41106a200e290000370300200241f0036a41086a201f290000370300200220052900003703f003200241c0056a200241f0036a200710d501200241d8016a41086a4200370300200241d8016a41106a4200370300200241d8016a41186a4200370300200241d8016a41206a420037030020204200370300200941186a200c290300370000200941106a200d290300370000200941086a200f290300370000200920022903b004370000200242003703d8012003200241d8016a41d00010a105220341d0006a41003a0000200341d8006a2103200541206a2105200741016a2107200a41606a220a0d000b2021202a6a41016a21210b2019410120291b2105200220213602b8030240201641ffffff3f71450d00201510230b200241d0046a41086a200241b0036a41086a2802002209360200200220022903b0033703d0040240024020092005490d00200241a0056a20022802a805201e410674220941067510960120022802a005210720022802a8052105200241f0016a200241c0026a360200200241ec016a200241d0046a3602002002201a20096a3602e4012002201a3602e0012002201d3602dc012002201a3602d8012002200241c0056a3602e801200241f0036a41086a20053602002002200241a8056a3602f40320022007200541e0006c6a3602f003200241d8016a200241f0036a10d6012027410020281b222bad42307e2206422088a70d022006a72209417f4c0d0220022802d80421050240024020090d00410821200c010b200910212220450d060b200241003602880520022020360280052002200941306e36028405202b412c6c2209417f4c0d020240024020090d004104212c0c010b20091021222c450d060b4100211a20024100360298052002202b360294052002202c36029005410021282005202b2005202b491b22290d010c030b024020022802d4042205450d00200541d8006c450d0020022802d00410230b024020022802a8052205450d00200541e0006c210920022802a00541346a21050340024020052802002207450d00200741c8006c450d002005417c6a28020010230b200541e0006a2105200941a07f6a22090d000b0b024020022802a4052205450d00200541e0006c450d0020022802a00510230b200241c0056a10be010240201e450d00201e4106742109201a41346a210503400240200528020041ffffff3f71450d002005417c6a28020010230b200541c0006a2105200941406a22090d000b0b410021200240201d41ffffff1f710d000c040b201a10230c030b200241f0026a41186a2116200241f0026a41106a211d200241f0026a41086a211941002115034020022802d004210702402005450d00200541d8006c21092007210503400240200541d0006a2d00000d0002400240200541206a2903002208200541286a290300220b8450450d0042002106427f2108427f210b0c010b427f210620024190016a427f427f2008200b10a70520024190016a41086a290300210b20022903900121080b200520083703002005200b370308200541106a2006370300200541186a20063703000b200541d8006a2105200941a87f6a22090d000b0b0240024020022802a8052205450d0020022802a005220a200541e0006c6a210d03400240200a2802382205450d00200541c8006c2107200a28023041206a2105034020022802d8042203200528020022094d0d04024020022802d004200941d8006c6a22092d00500d0020092903202206200941286a290300220884500d00200241d8016a200a290310200a41186a290300200a290300200a41086a29030020062008108201200920092903002206427f2006427f20022903e00120022802d80141014622031b220b7c22082008200654220c200941086a22012903002206427f200241d8016a41106a29030020031b22227c200cad7c220820065420082006511b22031b200b20228450220c1b37030020012006427f200820031b200c1b3703000b200541c8006a2105200741b87f6a22070d000b0b200a41e0006a220a200d470d000b20022802d00421070b201541016a211520022802d80441d8006c2105200741a87f6a210903402005450d04200541a87f6a2105200941d8006a2109200741d0006a210a200741d8006a22032107200a2d00000d000b02402005450d00200941186a2903002106200941106a2903002108200941086a290300210b200929030021224100210703400240200320076a220a41d0006a2d00000d00200a41086a2903002223200b2022200b20082006200a29030022242023200a41106a2903002225200a41186a290300221810800141ff0171410146220c1b210b20242022200c1b212220182006200c1b210620252008200c1b2108200a2009200c1b21090b2005200741d8006a2207470d000b0b2009450d03200941013a0050024020022802a8052205450d0020022802a0052207200541e0006c6a211e2009410c6a210f200941306a211f0340200741e0006a212102402007280238220a450d0020072802302105200a41c8006c210a034002400240200f2005460d00200541246a201f412010a3050d010b200741186a22032903002122200941086a220c29030021062007290310210b2009290300210820092903102123200541186a200941186a2201290300370300200541106a2023370300200520064200200620227d2008200b54ad7d22232008200b7d2224200856202320065620232006511b220d1b200b20228450220e1b3703082005200842002024200d1b200e1b370300200c2903002106200129030021082009290300210b20072009290310370320200741286a20083703002007200b370310200320063703000b200541c8006a2105200a41b87f6a220a0d000b0b202121072021201e470d000b0b2016200941c8006a290000370300201d200941c0006a2900003703002019200941386a290000370300200220092900303703f002200941286a29030021062009290320210802402028200228028405470d0020024180056a2028410110a401200228028005212020022802880521280b2020202841306c6a220520022903f0023703002019290300210b201d29030021222016290300212320052008370320200541286a2006370300200541186a2023370300200541106a2022370300200541086a200b3703002002202841016a222836028805201520294f0d0320022802d80421050c010b0b2009200341a4e4c4001030000b1032000b024020022802a8052205450d0020022802a0052215200541e0006c6a211d202841306c211e200241fc036a221641186a2119201641106a2129201641086a21274100211a034020162015221f29003c3700002019201f41d4006a2900003700002029201f41cc006a2900003700002027201f41c4006a290000370000200241003602f803200242043703f003201f41e0006a21150240201f2802382205450d00201f280230220d200541c8006c6a210f201f41106a2121410021014104210e0340200d220c41246a2107200c41c8006a210d4100210a201e210920202105024003402009450d01024020072005460d0020052007412010a3052103200a41016a210a200941506a2109200541306a210520030d010b0b418094ebdc03210902402021200c1081010d00410021050240200c290310201f29032085200c41186a290300201f41286a29030085844200520d00200241d8016a428094ebdc034200200c290300200c41086a2903002021290300202141086a290300108201427f20022903e00120022802d80141014622051b220842ffffffff0f56427f200241d8016a41106a29030020051b22064200522006501b0d012008a7220541ff93ebdc034b0d010b200521090b200241b0036a41186a2207200c413c6a290000370300200241b0036a41106a220a200c41346a290000370300200241b0036a41086a2203200c412c6a2900003703002002200c2900243703b0030240200120022802f403470d00200241f0036a2001410110a20120022802f003210e20022802f80321010b200e200141246c6a220520022903b00337020020032903002106200a29030021082007290300210b20052009360220200541186a200b370200200541106a2008370200200541086a20063702002002200141016a22013602f8030b200d200f470d000b02402001450d0002400240200141246c22070d00410021050c010b200e41206a2109410021050340417f200520092802006a220a200a2005491b2105200941246a21092007415c6a22070d000b0b02404100418094ebdc0320056b22052005418094ebdc034b1b220c20016e2205418094ebdc032005418094ebdc03491b2203450d004100210503402002417f200e200520017041246c6a2209280220220720036a220a200a2007491b22073602d8012002418094ebdc033602dc012009200241d8016a2007418094ebdc034b4102746a280200360220200541016a22052001490d000b0b0240200c200320016c6b2203450d004100210503402002417f200e200520017041246c6a2209280220220741016a220a200a2007491b22073602d8012002418094ebdc033602dc012009200241d8016a2007418094ebdc034b4102746a280200360220200541016a22052003490d000b0b200241d8016a41286a2209200241f0036a41286a280200360200200241d8016a41206a2207200241f0036a41206a290300370300200241d8016a41186a220a200241f0036a41186a290300370300200241d8016a41106a2203200241f0036a41106a290300370300200241d8016a41086a220c200241f0036a41086a290300370300200220022903f0033703d8010240201a200228029405470d0020024190056a201a410110a601200228029005212c200228029805211a0b202c201a412c6c6a220520022903d801370200200541286a2009280200360200200541206a2007290300370200200541186a200a290300370200200541106a2003290300370200200541086a200c2903003702002002201a41016a221a360298050c010b20022802f4032205450d00200541246c450d00200e10230b2015201d470d000b200228029405212b0b200228028405212d024020022802d4042205450d00200541d8006c450d0020022802d00410230b024020022802a8052205450d00200541e0006c210920022802a00541346a21050340024020052802002207450d00200741c8006c450d002005417c6a28020010230b200541e0006a2105200941a07f6a22090d000b0b024020022802a4052205450d00200541e0006c450d0020022802a00510230b200241c0056a10be010b024020200d00410321260c040b200241003602e001200242013703d801200241d8016a4100202841306c220741306e109a0120022802e00121210240024020070d0020022802d80121170c010b20022802d801221720214105746a210520202109034020052009290000370000200541186a200941186a290000370000200541106a200941106a290000370000200541086a200941086a290000370000202141016a2121200541206a2105200941306a2109200741506a22070d000b0b20023502dc01212e2002410036029805200242043703900520024190056a4100201a412c6c2205412c6d10a601202c20056a212a2002280298052128200228029005212f0240201a0d00202c21010c020b200241d8016a410c6a210f202f2028412c6c6a210d200241f0026a41106a211a200241d8016a410472211f200241f0036a41206a211b200241f0036a41186a2126200241f0036a41086a211c202c210103402001280200211e201b200141246a29020037030020262001411c6a290200370300200241f0036a41106a2205200141146a290200370300201c2001410c6a290200370300200220012902043703f0032001412c6a2101201e450d02201f20022903f003370200201f41086a201c290300370200201f41106a2005290300370200201f41186a2026290300370200201f41206a201b2903003702002002201e3602d80120024180016a200f10d30120024180016a41086a2903002108200229038001210b200241f0026a41186a22304200370300201a4200370300200241f0026a41086a22294200370300200242003703f00241bdadc500ad4280808080800184100c220529000021062029200541086a290000370300200220063703f0022005102341c5adc500ad4280808080d00184100c22052900002106200241d0046a41086a2215200541086a290000370300200220063703d00420051023201a20022903d004370000201a41086a2015290300370000200241b0036a41086a22162029290300370300200241b0036a41106a221d201a290300370300200241b0036a41186a22192030290300370300200220022903f0023703b003200241e8006a200241b0036a412010d701200241d8006a2002290370200241e8006a41106a290300427f420010a705200241c8006a200b200820022903584200200228026822051b220642012006420156200241d8006a41086a290300420020051b22064200522006501b22051b2006420020051b10a705200241a0056a41086a2231200f41086a290200370300200241a0056a41106a2232200f41106a290200370300200241a0056a41186a2233200f41186a2902003703002002200f2902003703a00520022802dc0121272002290348210802400240024020022802e00141246c2234450d0020342107201e21050340200541206a2802002109200241b0046a41186a220a200541186a290000370300200241b0046a41106a2203200541106a290000370300200241b0046a41086a220c200541086a290000370300200220052900003703b00420090d02200541246a21052007415c6a22070d000b0b42002106410021054108210e02402027450d00202741246c450d00201e1023420021060b4200210b410021150c010b200241386a20084200428094ebdc03420010a705200241286a20022903382223200241386a41086a29030022244280ec94a37c427f10a605200241186a202320242009ad2206420010a6052015200c290300370300200241d0046a41106a22092003290300370300200241d0046a41186a2235200a290300370300200220022903b004220b3703f0022002200b3703d0042006200820022903287c22187e2206428094ebdc0380210b20022903182122200241186a41086a290300212541301021220e450d02200e2022200ba7417f2006428080808080c0b2cd3b541b2006200b4280ec94a37c7e7c4280cab5ee01566aad7c2206370320200e20022903d004370300200e41286a20252006202254ad7c220b370300200e41186a2035290300370300200e41106a2009290300370300200e41086a201529030037030020024281808080103702c4052002200e3602c0050240024020074124470d00410121150c010b200541246a2135201e20346a2207415c6a21344101211503402035210502400340200541206a2802002109200a200541186a2900003703002003200541106a290000370300200c200541086a290000370300200220052900003703b00420090d012007200541246a2205470d000c030b0b200241086a202320242009ad2222420010a6052029200c2903002225370300201a200329030022363703002030200a2903002237370300200220022903b00422383703f00220192037370300201d203637030020162025370300200220383703b003200620022903082225202220187e2222428094ebdc03802236a7417f2022428080808080c0b2cd3b541b202220364280ec94a37c7e7c4280cab5ee01566aad7c22227c22362006542209200b200241086a41086a2903002022202554ad7c22257c2009ad7c2206200b542006200b511b21090240201520022802c405470d00200241c0056a2015410110a40120022802c005210e0b427f200620091b210b427f203620091b2106200541246a2135200e201541306c6a220920022903b00337030020162903002136201d29030021372019290300213820092022370320200941286a2025370300200941186a2038370300200941106a2037370300200941086a20363703002002201541016a22153602c80520342005470d000b0b02402027450d00202741246c450d00201e10230b20022802c40521050b02400240200820067d22232008564200200b2008200654ad7c7d22224200522022501b4101470d00200620087d2222200656200b2006200854ad7d2223200b56200620085a1b0d012015450d01201541306c200e6a41706a220942002009290300220620227d22082008200656200941086a2209290300220820237d2006202254ad7d220620085620062008511b22071b37030020094200200620071b3703000c010b2015450d00201541306c200e6a41706a2209427f2009290300220620237c220820082006542207200941086a2209290300220620227c2007ad7c220820065420082006511b22071b3703002009427f200820071b3703000b20192033290300370300201d203229030037030020162031290300370300200220022903a0053703b003200d2005360204200d2015360208200d200e360200200d20022903b00337020c200d41146a2016290300370200200d411c6a201d290300370200200d41246a2019290300370200202841016a2128200d412c6a210d2001202a470d000b20022028360298050c020b1033000b20022028360298052001202a460d00034020012205412c6a21010240200541046a2802002209450d00200941246c450d00200528020010230b202a2001470d000b0b0240202b450d00202b412c6c450d00202c10230b2002280294052103200241d8016a20172021202f202810d8010240024020022802d801220a0d00410021054100210a4100210c0c010b20022802e001210c0240024020022802dc0122090d00200a21050c010b20092105200a2107034020072802c80521072005417f6a22050d000b200a21050340200520052f01064102746a41c8056a28020021052009417f6a22090d000b2007210a0b20052f010621090b200241f4016a2009360200200241f0016a4100360200200241ec016a20053602002002200c3602f801200241003602e801200242003703e0012002200a3602dc01200241003602d8012021ad21062002200241c0026a3602fc01200241f0036a200241d8016a10d90120022802f003211b20022802f403211c20022802f803210a02402028450d002028412c6c2109202f210503400240200541046a2802002207450d00200741306c450d00200528020010230b2005412c6a2105200941546a22090d000b0b2006422086210602402003450d002003412c6c450d00202f10230b2006202e84212441002126202d450d00202d41306c450d00202010230b200241d8016a41186a22094200370300200241d8016a41106a22074200370300200241d8016a41086a22054200370300200242003703d801418fcdc200ad4280808080f000842208100c220c2900002106200241b0036a41086a2203200c41086a290000370300200220063703b003200c102320052003290300370300200220022903b0033703d80141b0e4c100ad4280808080b00184100c22012900002106200241f0036a41086a220c200141086a290000370300200220063703f00320011023201320022903f003370000201341086a200c290300370000200241a0056a41086a2005290300370300200241a0056a41106a2007290300370300200241a0056a41186a2009290300370300200220022903d8013703a0052014101141002101024020264103460d00200942003703002007420037030020054200370300200242003703d8012008100c220129000021062003200141086a290000370300200220063703b0032001102320052003290300370300200220022903b0033703d80141ccc5c000ad4280808080900284100c22032900002106200c200341086a290000370300200220063703f00320031023200420022903f003370000200441086a200c290300370000200241d0046a41086a2005290300370300200241d0046a41106a2007290300370300200241d0046a41186a2009290300370300200220022903d8013703d004410110212205450d02200541003a000020112005ad42808080801084100e2005102342002108200241d8016a41186a22284200370300200241d8016a41106a222a4200370300200241d8016a41086a22274200370300200242003703d801418fcdc200ad4280808080f000842206100c2205290000210b200241b0036a41086a2230200541086a2900003703002002200b3703b0032005102320272030290300370300200220022903b0033703d80141a8c5c000ad4280808080a00284100c2205290000210b200241f0036a41086a220e200541086a2900003703002002200b3703f00320051023200420022903f003370000200441086a2209200e290300370000200241d0046a41086a22212027290300370300200241d0046a41106a221e202a290300370300200241d0046a41186a22152028290300370300200220022903d8013703d0042011101120284200370300202a420037030020274200370300200242003703d8012006100c220529000021062030200541086a290000370300200220063703b0032005102320272030290300370300200220022903b0033703d80141bac5c000ad4280808080a00284100c22052900002106200e200541086a290000370300200220063703f00320051023200420022903f0033700002009200e29030037000020212027290300370300201e202a29030037030020152028290300370300200220022903d8013703d00420111011201b200a41d0006c6a2120024002400240200a0d00201b2101420021060c010b200241b0036a41106a211a200241f0026a41106a210f20024194036a2116200241d8016a41206a210d4200210842002106201b21010340200241f0036a41386a220a2001220541386a290300370300200241f0036a41306a2203200541306a290300370300200241f0036a41286a220c200541286a290300370300200241f0036a41206a221f200541206a290300370300200241f0036a41186a2209200541186a290300370300200241f0036a41106a2207200541106a290300370300200e200541086a2903003703002005290300210b20024190056a41086a221d200541cc006a2802003602002002200b3703f0032002200541c4006a29020037039005200541d0006a2101200541c0006a2802002205450d01200241d8016a41386a200a290300370300200241d8016a41306a2003290300370300200241d8016a41286a200c290300370300200d201f29030037030020282009290300370300202a20072903003703002027200e290300370300200220022903f0033703d801200241a0056a41186a2009290300370300200241a0056a41106a2007290300370300200241a0056a41086a200e290300370300200220022903f0033703a005200241f0026a41186a2219200d41186a290300370300200f200d41106a290300370300200241f0026a41086a2229200d41086a290300220b37030020022005360290032002200d29030022223703f0022016200229039005370200201641086a201d280200360200200241d0046a2010200241a0056a10da0120023502d804212320022802d004211f200241003602b803200242013703b0032002200241f0026a3602b004200241b0046a200241b0036a10db012002200f3602b004200241b0046a200241b0036a10db0120022802900321052002280298032209200241b0036a106102402009450d00200941306c210303400240024020022802b403220a20022802b80322096b4120490d0020022802b00321070c010b200941206a22072009490d07200a410174220c2007200c20074b1b220c4100480d0702400240200a0d000240200c0d00410121070c020b200c10212207450d0a0c010b20022802b0032107200a200c460d002007200a200c10252207450d090b2002200c3602b403200220073602b0030b200720096a2207200541106a290000370000200741186a200541286a290000370000200741106a200541206a290000370000200741086a200541186a2900003700002002200941206a3602b803200220053602b004200241b0046a200241b0036a10db01200541306a2105200341506a22030d000b0b20022802b40321052023422086201fad8420023502b80342208620022802b0032209ad84100e02402005450d00200910230b024020022802d404450d00201f10230b20152019290300370300201e200f29030037030020212029290300370300200220022903f0023703d004200228029c032107200228029403210a20022802900321090240200228029803220541c100490d0020092005410041202005676b10dc0141c00021050b200241b0036a41186a2015290300370300201a201e29030037030020302021290300370300200220022903d0043703b003200220073602dc03200220053602d8032002200a3602d403200220093602d003200241c0056a2010200241a0056a10dd0120023502c805212320022802c005211f200241003602b804200242013703b0042002200241b0036a3602800520024180056a200241b0046a10db012002201a3602800520024180056a200241b0046a10db0120022802d003210520022802d8032209200241b0046a106102402009450d00200941306c210303400240024020022802b404220a20022802b80422096b4120490d0020022802b00421070c010b200941206a22072009490d07200a410174220c2007200c20074b1b220c4100480d0702400240200a0d000240200c0d00410121070c020b200c10212207450d0a0c010b20022802b0042107200a200c460d002007200a200c10252207450d090b2002200c3602b404200220073602b0040b200720096a2207200541106a290000370000200741186a200541286a290000370000200741106a200541206a290000370000200741086a200541186a2900003700002002200941206a3602b804200220053602800520024180056a200241b0046a10db01200541306a2105200341506a22030d000b0b2006200b7c200820227c220b2008542205ad7c210820022802b40421092023422086201fad8420023502b80442208620022802b0042207ad84100e02402009450d00200710230b2008200651210920082006542107024020022802c405450d00201f10230b2005200720091b2105024020022802d4032209450d00200941306c450d0020022802d00310230b427f200820051b2106427f200b20051b210820012020470d000c020b0b20202001460d0003402001220541d0006a21010240200541c4006a2802002209450d00200941306c450d00200541c0006a28020010230b20202001470d000b0b0240201c450d00201c41d0006c450d00201b10230b200241f0036a201010ca0120022802f003210520023502f803210b200220063703e001200220083703d801200b4220862005ad8420124280808080800284100e024020022802f403450d00200510230b02402024422088a7410574220a450d00200241f0036aad210b201721050340200241d8016a200510c301200220022802d801220720022802e00110de012002280204410020022802001b2109024020022802dc01450d00200710230b200241d8016a2010200510df0120023502e001210620022802d8012107200241003a00f5030240024002400240200941c000490d00200941808001490d012009418080808004490d02200241053a00f503200241033a00f003200220093600f1034280808080d00021080c030b200241013a00f503200220094102743a00f00342808080801021080c020b200241023a00f503200220094102744101723b01f00342808080802021080c010b200241043a00f503200220094102744102723602f0034280808080c00021080b20064220862007ad842008200b84100e024020022d00f503450d00200241003a00f5030b024020022802dc01450d00200710230b200541206a2105200a41606a220a0d000b0b200241e1016a20263a0000200241e0016a41033a0000200241033a00d801200241d8016a10e001201721010b2000202437020420002001360200200241d0056a24000f0b102c000b102a000b8f0201037f230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad841010108b0102400240200328020822040d00410021010c010b200328020c210502400240200341106a2802004104490d0020042800002102410121010c010b4100210120034100360220200342013703182003410a36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c20034180c5c6003602382003200341286a360248200341346a4184a5c200200341386a10311a2003350220422086200335021884100a0240200328021c450d00200328021810230b0b2005450d00200410230b2000200236020420002001360200200341d0006a24000bd81604027f017e077f017e230041d0006b22012400418fcdc200ad4280808080f00084100c22022900002103200141086a200241086a29000037030020012003370300200210234186d0c000ad4280808080b00184100c22022900002103200141106a41086a200241086a29000037030020012003370310200210232001200036022c20012001412c6aad22034280808080c00084100d220229000037033020021023200141c4006a200141306a360200200141003a00482001200141306a41086a220436023c20012001412c6a3602402001200141306a360238200141206a200141386a106502400240024002402001280228220541206a2206417f4c0d00200128022021070240024002402006450d00200610212202450d042006410f4d0d01200621080c020b200641017422024110200241104b1b2208102122020d010c050b200641017422084110200841104b1b22084100480d0320062008460d0020022006200810252202450d040b20022001290300370000200241086a200141086a2903003700000240024020084170714110460d00200821090c010b200841017422094120200941204b1b22094100480d0320082009460d0020022008200910252202450d040b20022001290310370010200241186a200141106a41086a2903003700000240200941606a20054f0d00200541206a22082005490d032009410174220a2008200a20084b1b22084100480d0320092008460d0020022009200810252202450d040b200241206a2007200510a1051a02402001280224450d00200710230b2006ad4220862002ad84101220021023418fcdc200ad4280808080f00084100c2202290000210b200141086a200241086a2900003703002001200b3703002002102341f4cfc000ad4280808080a00284100c2202290000210b200141106a41086a200241086a2900003703002001200b370310200210232001200036022c200120034280808080c00084100d220229000037033020021023200141c4006a200141306a360200200141003a00482001200436023c20012001412c6a3602402001200141306a360238200141206a200141386a10652001280228220941206a2206417f4c0d00200128022021070240024002402006450d00200610212202450d042006410f4d0d01200621080c020b200641017422024110200241104b1b220810212202450d050c010b200641017422084110200841104b1b22084100480d0320062008460d0020022006200810252202450d040b20022001290300370000200241086a200141086a2903003700000240024020084170714110460d00200821050c010b200841017422054120200541204b1b22054100480d0320082005460d0020022008200510252202450d040b20022001290310370010200241186a200141106a41086a2903003700000240200541606a20094f0d002009415f4b0d03200541017422082006200820064b1b22084100480d0320052008460d0020022005200810252202450d040b200241206a2007200910a1051a02402001280224450d00200710230b2006ad4220862002ad84101220021023418fcdc200ad4280808080f00084100c2202290000210b200141086a200241086a2900003703002001200b3703002002102341e2cfc000ad4280808080a00284100c2202290000210b200141106a41086a200241086a2900003703002001200b370310200210232001200036022c200120034280808080c00084100d220229000037033020021023200141c4006a200141306a360200200141003a00482001200436023c20012001412c6a3602402001200141306a360238200141206a200141386a10652001280228220941206a2206417f4c0d00200128022021070240024002402006450d00200610212202450d042006410f4d0d01200621080c020b200641017422024110200241104b1b220810212202450d050c010b200641017422084110200841104b1b22084100480d0320062008460d0020022006200810252202450d040b20022001290300370000200241086a200141086a2903003700000240024020084170714110460d00200821050c010b200841017422054120200541204b1b22054100480d0320082005460d0020022008200510252202450d040b20022001290310370010200241186a200141106a41086a2903003700000240200541606a20094f0d002009415f4b0d03200541017422082006200820064b1b22084100480d0320052008460d0020022005200810252202450d040b200241206a2007200910a1051a02402001280224450d00200710230b2006ad4220862002ad84101220021023418fcdc200ad4280808080f00084100c2202290000210b200141086a200241086a2900003703002001200b3703002002102341fecec000ad4280808080b00284100c2202290000210b200141106a41086a200241086a2900003703002001200b370310200210232001200036022c200120034280808080c00084100d220229000037033020021023200141c4006a200141306a360200200141003a00482001200436023c20012001412c6a3602402001200141306a360238200141206a200141386a10652001280228220941206a2206417f4c0d00200128022021070240024002402006450d00200610212202450d042006410f4d0d01200621080c020b200641017422024110200241104b1b220810212202450d050c010b200641017422084110200841104b1b22084100480d0320062008460d0020022006200810252202450d040b20022001290300370000200241086a200141086a2903003700000240024020084170714110460d00200821050c010b200841017422054120200541204b1b22054100480d0320082005460d0020022008200510252202450d040b20022001290310370010200241186a200141106a41086a2903003700000240200541606a20094f0d002009415f4b0d03200541017422082006200820064b1b22084100480d0320052008460d0020022005200810252202450d040b200241206a2007200910a1051a02402001280224450d00200710230b2006ad4220862002ad84101120021023200141386a200010b801200135024042208620012802382202ad8410110240200128023c450d00200210230b418fcdc200ad4280808080f00084100c2202290000210b200141086a200241086a2900003703002001200b370300200210234191cfc000ad4280808080e00184100c2202290000210b200141106a41086a200241086a2900003703002001200b370310200210232001200036022c200120034280808080c00084100d220229000037033020021023200141c4006a200141306a360200200141003a00482001200436023c20012001412c6a3602402001200141306a360238200141206a200141386a10652001280228220541206a2206417f4c0d00200128022021090240024002402006450d00200610212202450d042006410f4d0d01200621040c020b200641017422024110200241104b1b220410212202450d050c010b200641017422044110200441104b1b22044100480d0320062004460d0020022006200410252202450d040b20022001290300370000200241086a200141086a2903003700000240024020044170714110460d00200421080c010b200441017422084120200841204b1b22084100480d0320042008460d0020022004200810252202450d040b20022001290310370010200241186a200141106a41086a2903003700000240200841606a20054f0d002005415f4b0d03200841017422042006200420064b1b22044100480d0320082004460d0020022008200410252202450d040b200241206a2009200510a1051a02402001280224450d00200910230b2006ad4220862002ad84101120021023200141386a200010c201200135024042208620012802382202ad8410110240200128023c450d00200210230b200141d0006a24000f0b1032000b1033000b102c000b102a000ba20401097f230041e0006b220224002002200110880102400240024002402002280200450d00200041003602000c010b2002280204220320012802044105762204200420034b1b22044105742205417f4c0d010240024020040d00410121060c010b200510212206450d030b41002107200241003602102002200436020c20022006360208024002402003450d0041002108034041002105200241003a0058200841016a21082001280204417f6a210403402004417f460d03200241386a20056a200128020022092d00003a0000200120043602042001200941016a3602002002200541016a22093a00582004417f6a21042009210520094120470d000b200241186a41186a2205200241386a41186a290300370300200241186a41106a2209200241386a41106a290300370300200241186a41086a220a200241386a41086a2903003703002002200229033837031802402007200228020c470d00200241086a20074101109a0120022802082106200228021021070b200620074105746a22042002290318370000200441186a2005290300370000200441106a2009290300370000200441086a200a2903003700002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c010b0240200541ff0171450d00200241003a00580b20004100360200200228020c41ffffff3f71450d00200610230b200241e0006a24000f0b1032000b1033000b990707017f047e027f017e057f047e017f23004190026b22022400200241c0006a200110800202400240024002400240024002402002290340a70d00200241c0006a41106a290300210320022903482104200241286a20011080022002290328a70d03200241286a41106a290300210520022903302106200241206a200110880120022802200d0220022802242207200128020441306e2208200820074b1bad42307e2209422088a7450d010c060b200041003602200c040b2009a72208417f4c0d040240024020080d004108210a0c010b20081021220a450d030b4100210b200241003602602002200a3602582002200841306e36025c0240024002402007450d004100210c03404100210d200241003a008802200c41016a210c2001280204417f6a210803402008417f460d03200241e8016a200d6a2001280200220e2d00003a0000200120083602042001200e41016a3602002002200d41016a220e3a0088022008417f6a2108200e210d200e4120470d000b200241c8016a41186a2208200241e8016a41186a290300370300200241c8016a41106a220d200241e8016a41106a290300370300200241c8016a41086a220e200241e8016a41086a290300370300200220022903e8013703c801200241086a20011080022002290308a70d03200241086a41106a29030021092002290310210f20024188016a41086a200e290300221037030020024188016a41106a200d290300221137030020024188016a41186a20082903002212370300200241e8006a41086a220d2010370300200241e8006a41106a220e2011370300200241e8006a41186a22132012370300200220022903c801221037038801200220103703680240200b200228025c470d00200241d8006a200b410110a4012002280258210a2002280260210b0b200a200b41306c6a220820093703082008200f37030020082002290368370310200841186a200d290300370300200841206a200e290300370300200841286a20132903003703002002200b41016a220b360260200c2007470d000b0b200a450d02200229025c210920002004370300200020093702242000200a3602202000200637031020002003370308200041186a20053703000c050b200d41ff0171450d00200241003a0088020b20024188016a41086a200241a8016a41086a290300370300200228025c2201450d00200141306c450d00200a10230b200041003602200c020b200041003602200c010b1033000b20024190026a24000f0b1032000bbd0101047f230041106b220224002000280204210320002802002100410121042001280218419b9ec00041012001411c6a28020028020c1100002105200241003a0005200220053a00042002200136020002402003450d0003402002200036020c20022002410c6a41e0e4c200105a1a200041016a21002003417f6a22030d000b20022d000421050b0240200541ff01710d0020022802002200280218419a9ec00041012000411c6a28020028020c11000021040b200241106a240020040b8a0604057f017e047f037e230041f0006b22022400200241286a200141146a350200422086200135020c841019108b010240024020022802282203450d00200141086a2104200141106a210503400240024020042802002206200229022c2207422088a722084b0d00200128020022092003460d0120092003200610a305450d010b2007a7450d02200310230c020b02402005280200450d00200128020c10230b2001200336020c2005200737020020022003200810de01024002402002280200450d002002280204210a024020012d0018450d002001350214422086200135020c8410110b2001280214220820042802002203490d0102400240200820036b22084108490d00200841786a2106200128020c20036a41086a21090c010b4100210602404100280298ab470d00419ca8c70021090c010b41002106410028028880402103410028028480402108410028029cab47210b200241e000360268200242de80808010370360200241c79ec00036025c20024213370254200241b49ec00036025020024200370348419ca8c70021092002419ca8c70036024420024201370338200241ac9ec00036023420024113360230200241b49ec00036022c20024101360228200841a0a1c000200b410246220b1b200241286a200341b8a1c000200b1b2802101102000b41002103200241003a00480240034020062003460d01200241286a20036a200920036a2d00003a00002002200341016a22083a00482008210320084120470d000b200241086a41186a200241286a41186a2903002207370300200241086a41106a200241286a41106a290300220c370300200241086a41086a200241286a41086a290300220d37030020022002290328220e3703082000411c6a2007370000200041146a200c3700002000410c6a200d3700002000200e370004200041246a200a360200200041013602000c050b200341ff0171450d00200241003a00480b200241286a2001350214422086200135020c841019108b01200228022822030d010c020b0b2003200841dc96c7001044000b200041003602000b200241f0006a24000bf10804047f017e027f017e230041e0016b22022400200241d0016a200110c701200241c8006a20022802d001220120022802d80110e101200241286a41086a2203200241d1006a290000370300200241286a41106a2204200241d9006a290000370300200241286a41186a2205200241e1006a29000037030020022002290049370328024002400240024002400240024002400240024020022d00484101470d00200241086a41186a2005290300370300200241086a41106a2004290300370300200241086a41086a200329030037030020022002290328370308024020022802d401450d00200110230b200241c8006a41186a2203200241086a41186a290300370300200241c8006a41106a2204200241086a41106a290300370300200241c8006a41086a2205200241086a41086a29030037030020022002290308370348418fcdc200ad4280808080f00084100c22012900002106200241a0016a41086a200141086a290000370300200220063703a0012001102341dcc4c000ad4280808080e00084100c22012900002106200241b0016a41086a200141086a290000370300200220063703b00120011023412010212201450d0120012002290348370000200141186a2003290300370000200141106a2004290300370000200141086a20052903003700002001ad4280808080800484100f22032900002106200241d0016a41086a200341086a290000370300200220063703d00120031023200241346a200141206a360200200241003a0038200220013602302002200241d0016a41106a36022c2002200241d0016a360228200241c0016a200241286a10652001102320022802c801220741206a2203417f4c0d0220022802c0012108024002402003450d00200310212201450d032003410f4d0d01200321040c060b200341017422014110200141104b1b2204102122010d050c0a0b200341017422044110200441104b1b220441004e0d030c080b20022802d401450d04200110230c040b1033000b1032000b20032004460d0020012003200410252201450d050b200120022903a001370000200141086a200241a0016a41086a2903003700000240024020044170714110460d00200421050c010b200441017422054120200541204b1b22054100480d0420042005460d0020012004200510252201450d050b200120022903b001370010200141186a200241b0016a41086a2903003700000240200541606a20074f0d002007415f4b0d04200541017422042003200420034b1b22044100480d0420052004460d0020012005200410252201450d050b200141206a2008200710a1051a024020022802c401450d00200810230b200241c8006a2001200310e201200241c8006a41186a2903002106200241f8006a2802002105200241f4006a280200210720022903582109200228026c2104200228026821032001102320030d010b42002109420021060c010b02402004450d00200441186c450d00200310230b200541ffffffff0371450d00200710230b2000200937030020002006370308200241e0016a24000f0b102c000b102a000b860908097f017e0c7f017e017f017e017f047e23004180026b22022400200241186a41186a200141186a280200360200200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241f8006a200241186a10f203024020022d00a8014102460d00200041046a21030340200241b0016a41286a200241f8006a41286a280200360200200241b0016a41206a200241f8006a41206a2201290300370300200241b0016a41186a2204200241f8006a41186a2205290300370300200241b0016a41106a2206200241f8006a41106a2207290300370300200241b0016a41086a2208200241f8006a41086a2209290300370300200220022903783703b0012001280200210a0240200229029c01220b422088a7220c450d0020022802a401210d4100210e200a21014100210f024002400340200220013602dc01200241e0016a200241dc016a10c801024002400240024020022802ec012210450d0020022802e8012111024020022802f00141ffffffff0371450d00201010230b2011200d4b0d010b200e0d014100210e0c020b200e41016a210e0c010b200f200e6b2210200c4f0d02200241e0016a41186a22112001200e4105746b221041186a2212290000370300200241e0016a41106a2213201041106a2214290000370300200241e0016a41086a2215201041086a2216290000370300200220102900003703e001200141086a22172900002118200141106a2219290000211a200141186a221b290000211c201020012900003700002012201c3700002014201a37000020162018370000201b20112903003700002019201329030037000020172015290300370000200120022903e0013700000b200141206a2101200c200f41016a220f460d020c000b0b2010200c4184d9c4001030000b200e417f6a200c4f0d00200b42ffffffff0f83200c200e6bad42208684210b0b200241d8006a41186a22012004290300370300200241d8006a41106a220e2006290300370300200241d8006a41086a220f2008290300370300200220022903b001370358200a450d01200520012903003703002007200e2903003703002009200f29030037030020022002290358370378200241086a200241f8006a10d301200241386a41186a20012903002218370300200241386a41106a200e290300221a370300200241386a41086a200f290300221c37030020022002290358221d370338200241086a41086a290300211e2002290308211f200520183703002007201a3703002009201c3703002002201d3703780240200041086a220f280200220e2003280200470d002000200e4101109f010b2000280200200e4106746a2201201e3703082001201f370300200120022903783703102001200a360230200141186a2009290300370300200141206a2007290300370300200141286a2005290300370300200141346a200b370200200f200e41016a360200200241f8006a200241186a10f20320022d00a8014102470d000b0b0240200228021c450d00200228021810230b0240200241286a280200450d00200228022410230b20024180026a24000bf70c01087f230041c0046b22032400200341206a41186a200141186a290000370300200341206a41106a200141106a290000370300200341206a41086a200141086a290000370300200320012900003703200240024002400240024020002802002204450d00200028020421050c010b4100210520034180016a410041e00210a0051a200341f8006a22014100360200200341f0006a22064200370300200341d0006a41186a4200370300200341d0006a41106a4200370300200341d0006a41086a42003703002003420037035041940310212204450d01200441003b010620044100360200200441086a20034180016a41e00210a1051a20044190036a200128020036020020044188036a200629030037020020044180036a200341e8006a290300370200200441f8026a200341e0006a290300370200200441f0026a200341d0006a41086a290300370200200420032903503702e80220004100360204200020043602000b2003200036025820032004360254200320053602500240034020042f01062207410574210841002101410021060240024002400240034020082001460d010240200341206a200420016a41086a412010a30522090d0041002101200521090c030b200141206a2101200641016a21062009417f4a0d000b2006417f6a21070b20050d014101210141002109200721060b20034180016a41106a20063602002003418c016a200036020020034180016a41086a20043602002003200036025820032004360254200320053602502003200936028401200320013602800102402001450d00200341186a2201200341206a41186a2207290300370300200341106a2208200341206a41106a290300370300200341086a2205200341206a41086a290300370300200320032903203703002000200028020841016a3602082003200636024c200320003602482003200436024420032009360240200341d0006a41186a2001290300370300200341d0006a41106a2008290300370300200341d0006a41086a20052903003703002003200329030037035020034180016a200341c0006a200341d0006a200210b40420032d0080014101470d04200341206a41086a220520034189016a290000370300200341206a41106a220020034191016a290000370300200720034199016a2900003703002003200329008101370320200341ac016a2802002106200341b8016a2802002108200341b4016a2802002109200341b0016a2802002104200341a8016a28020022012802002207450d0220012f01042102200341a4016a280200210a20034180016a410172210103402003200241ffff037136024c20032006360248200320073602442003200a41016a360240200341d0006a41186a200341206a41186a2206290300370300200341d0006a41106a2000290300370300200341d0006a41086a20052903003703002003200329032037035020034180016a200341c0006a200341d0006a20042009200810b50420032d0080014101470d052005200141086a2900003703002000200141106a2900003703002006200141186a2900003703002003200129000037032020032802ac01210620032802b801210820032802b401210920032802b001210420032802a80122022802002207450d0320022f0104210220032802a401210a0c000b0b200420064102746a41e8026a20023602000c030b2005417f6a2105200420074102746a4194036a28020021040c010b0b20034180016a410272410041be0310a0051a41c40310212201450d0120014100360200200141046a20034180016a41c00310a1051a200120062802002205360294032006200136020020062006280204220041016a360204200541003b01042005200136020020034180016a41186a200341206a41186a29030037030020034180016a41106a200341206a41106a29030037030020034180016a41086a200341206a41086a290300370300200320032903203703800120002008470d0220012f01062206410a4b0d03200120064105746a220841206a20034180016a41186a290300370000200841186a20034180016a41106a290300370000200841106a20034180016a41086a290300370000200841086a200329038001370000200120064102746a41e8026a20043602002001200641016a22064102746a4194036a2009360200200120063b0106200920063b0104200920013602000b200341c0046a24000f0b102a000b4183dac4004130418c94c700102d000b41dcd9c4004127418c94c700102d000b9711080f7f027e047f017e057f027e057f017e230041a0026b22022400200141086a280200210320012802042104200028020421052000280200210602400240024020002802082207200028020c2208460d00200041146a28020021092001280200210a2000280210210b200241f0016a41106a210c0340200241f0006a41086a2201200741186a290300370300200241f0006a41106a220d200741206a290300370300200241f0006a41186a220e200741286a29030037030020022007290310370370200741c0006a210f0240200728023022100d00200f21070c020b200741086a2903002111200741386a280200210020072903002112200741346a280200211320024190016a41186a2214200e29030037030020024190016a41106a2215200d29030037030020024190016a41086a2216200129030037030020022002290370370390012000ad42c8007e2217422088a70d032017a72207417f4c0d030240024020070d00410821180c010b200710212218450d030b200741c8006e21190240024020000d004100211a0c010b201020004105746a211b4100211a2010211c0340201c41086a2900002117201c41106a290000211d201c290000211e200241b0016a41186a221f201c41186a290000370300200241b0016a41106a2220201d370300200241b0016a41086a222120173703002002201e3703b0010240200b280200220e450d00200b28020421220340200e41086a2100200e2f010622234105742107410021010240024003402007450d01200241b0016a2000412010a305220d450d02200741606a2107200141016a2101200041206a2100200d417f4a0d000b2001417f6a21230b2022450d022022417f6a2122200e20234102746a4194036a280200210e0c010b0b02400240024002402009280208220d200e20014102746a41e8026a220728020022004d0d002009280200200041d8006c6a22002903202117200041286a290300211d200241f0016a41186a22014200370300200c4200370300200241f0016a41086a22004200370300200242003703f00141bdadc500ad4280808080800184100c220d290000211e2000200d41086a2900003703002002201e3703f001200d102341c5adc500ad4280808080d00184100c220d290000211e20024190026a41086a220e200d41086a2900003703002002201e37039002200d1023200c200229039002370000200c41086a200e290300370000200241d0016a41086a2000290300370300200241d0016a41106a200c290300370300200241d0016a41186a2001290300370300200220022903f0013703d001200241d8006a200241d0016a412010d701200241c8006a2002290360200241d8006a41106a290300427f420010a7052009280208220e2007280200220d4d0d01200241386a20122011200229034842002002280258220e1b221e4201201e420156200241c8006a41086a2903004200200e1b221e420052201e501b220e1b201e4200200e1b10a7052009280200200d41d8006c6a220d41286a427f201d201720022903387c221e201754220ead7c2224200e2024201d54201e20175a1b220e1b370300200d427f201e200e1b3703202001201f290300370300200c202029030037030020002021290300370300200220022903b0013703f0012007280200210d201a2019470d03024002400240201a41016a2207201a490d00201a410174220e2007200e20074b1bad42c8007e2217422088a70d002017a722074100480d000240201a0d0020070d02410821180c060b201a41c8006c220e2007460d050240200e0d0020070d02410821180c060b2018200e200710252218450d020c050b102c000b2007102122180d030b102a000b2000200d41e4d8c4001030000b200d200e41f4d8c4001030000b200741c8006e21190b2018201a41c8006c6a220742003703002007200d360220200741186a4200370300200741106a4200370300200741086a4200370300200720022903f0013702242007412c6a2000290300370200200741346a200c2903003702002007413c6a2001290300370200201a41016a211a0b201c41206a221c201b470d000b0b0240201341ffffff3f71450d00201010230b200241f0016a41186a22074200370300200c4200370300200241f0016a41086a22004200370300200242003703f00141bdadc500ad4280808080800184100c220129000021172000200141086a290000370300200220173703f0012001102341c5adc500ad4280808080d00184100c2201290000211720024190026a41086a220d200141086a290000370300200220173703900220011023200c200229039002370000200c41086a200d290300370000200241d0016a41086a2000290300370300200241d0016a41106a200c290300370300200241d0016a41186a2007290300370300200220022903f0013703d001200241206a200241d0016a412010d701200241106a2002290328200241206a41106a290300427f420010a70520022012201120022903104200200228022022011b221742012017420156200241106a41086a290300420020011b22174200522017501b22011b2017420020011b10a705200020162903002217370300200c2015290300370300200720142903003703002002200229039001221d3703f001200a4200370310200a41186a4200370300200a4200370308200a41286a4200370300200a4201370320200a201a360238200a2019360234200a2018360230200a201d37023c200a41c4006a2017370200200a41cc006a200c290300370200200a41d4006a2007290300370200200a2002290300370300200341016a2103200a41e0006a210a200f2107200f2008470d000b200821070b200420033602000240200820076b2200450d0020004106754106742100200741346a210703400240200728020041ffffff3f71450d002007417c6a28020010230b200741c0006a2107200041406a22000d000b0b0240200541ffffff1f71450d00200610230b200241a0026a24000f0b1033000b1032000ba80202017f037e230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad841010108b0102400240200328020822010d00420021040c010b200328020c210202400240200341086a41086a2802004110490d00200141086a290000210520012900002106420121040c010b20034100360220200342013703182003410a36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c20034180c5c6003602382003200341286a360248200341346a4184a5c200200341386a10311a2003350220422086200335021884100a0240200328021c450d00200328021810230b420021040b2002450d00200110230b2000200637030820002004370300200041106a2005370300200341d0006a24000ba628030d7f047e1d7f230022052106200541e00b6b41607122072400200741003602182007410036021002400240024002402002450d00200120024105746a2108200741e0056a41027221094100210a034020074200370348200742003703402007410036025820074208370350200741a8026a41186a220b200141186a290000370300200741a8026a41106a220c200141106a290000370300200741a8026a41086a220d200141086a290000370300200720012900003703a80202400240200a450d002007280214210e0c010b200741e0056a410041e00210a0051a200741f8026a410041e00210a0051a41c8051021220a450d054100210e200a41003b0106200a4100360200200a41086a200741e0056a41e00210a1051a200a41e8026a200741f8026a41e00210a1051a200741003602142007200a3602100b200141206a21010240024002400240024002400340200a41086a2105200a2f0106220f410574210241002110024003402002450d01200741a8026a2005412010a3052211450d03200241606a2102201041016a2110200541206a21052011417f4a0d000b2010417f6a210f0b0240200e450d00200e417f6a210e200a200f4102746a41c8056a280200210a0c010b0b200741f0006a41186a2202200b290300370300200741f0006a41106a200c2903002212370300200741f0006a41086a200d2903002213370300200720072903a80222143703702007200728021841016a360218200c2012370300200d2013370300200b2002290300370300200720143703a80220072903582112200729035021132007290348211420072903402115200a2f01062205410b490d01200741e0056a410041e00210a0051a200741f8026a410041e00210a0051a41c80510212216450d0a201641003b010620164100360200201641086a200741e0056a41e00210a1052105201641e8026a200741f8026a41e00210a1052110200741e0056a41086a2217200a41b0046a290300370300200741e0056a41106a2218200a41b8046a290300370300200741e0056a41186a2219200a41c0046a2903003703002007200a41db016a2900003703e0022007200a41e0016a2900003700e5022007200a41a8046a2903003703e0052007200a41c8016a2f00003b01f4022007200a41ca016a2d00003a00f602200a41cb016a280000211a200a41cf016a280000211b200a41d3016a280000211c200a41d7016a280000211d2005200a41e8016a200a2f010641796a2202410574221110a10521052010200a41c8046a201110a1052110200a41063b0106201620023b0106200720072f01f4023b01dc02200720072d00f6023a00de02200720072903e0023703c802200720072900e5023700cd02200741f8026a41186a221e2019290300370300200741f8026a41106a221f2018290300370300200741f8026a41086a22202017290300370300200720072903e0053703f80202400240200f4107490d002005200f41057441c07e6a220e6a2005200f41796a2211410574220f6a2205200241ffff037120116b41057410a2051a200541186a200b290300370000200541106a200c290300370000200541086a200d290300370000200520072903a8023700002010200e6a2010200f6a2205201641066a22022f010020116b41057410a2051a200541186a20123703002005201337031020052014370308200520153703000c010b200a41086a2202200f410574221041206a22116a200220106a2205200a41066a22022f0100200f6b41057410a2051a200541186a200b290300370000200541106a200c290300370000200541086a200d290300370000200520072903a802370000200a41e8026a220520116a200520106a220520022f0100200f6b41057410a2051a200541186a20123703002005201337031020052014370308200520153703000b200220022f010041016a3b010020074190026a41026a220220072d00de023a0000200741d8016a41086a22212020290300370300200741d8016a41106a2222201f290300370300200741d8016a41186a2223201e290300370300200720072f01dc023b019002200720072903c8023703c801200720072900cd023700cd01200720072903f8023703d801200741a4016a41026a222420022d00003a0000200720072f0190023b01a401200720072900cd0137009501200720072903c80137039001200741a8016a41186a22252023290300370300200741a8016a41106a22262022290300370300200741a8016a41086a22272021290300370300200720072903d8013703a8010240200a280200220e0d0041002128200741106a21020c040b200a2f01042129410021280340200741a4026a41026a222a20242d00003a0000200720072f01a4013b01a402200720072903900137039002200720072900950137009502200b2025290300370300200c2026290300370300200d2027290300370300200720072903a8013703a80241000d03202941ffff0371210a024002400240200e2f01062202410b490d002009410041f20510a0051a41f80510212211450d0e20114100360200201141046a200741e0056a41f40510a1051a2007200e2f00c8013b01f4022007200e41ca016a2d00003a00f6022007200e41db016a2900003703e0022007200e41e0016a2900003700e502200e41cb016a280000212b200e41cf016a280000212c200e41d3016a280000212d200e41d7016a280000212e2019200e41c0046a2903003703002018200e41b8046a2903003703002017200e41b0046a2903003703002007200e2903a8043703e005201141086a200e41e8016a200e2f0106220241796a2205410574221010a105212f201141e8026a200e41c8046a201010a1052130201141c8056a200e41e4056a2002417a6a220f41027410a1052131200e41063b0106201120053b01060240200f450d00410021022031210503402005280200221020023b010420102011360200200541046a2105200f200241016a2202470d000b0b201e2019290300370300201f201829030037030020202017290300370300200720072903e0053703f802200720072f01f4023b01dc02200720072d00f6023a00de02200720072903e0023703c802200720072900e5023700cd02200741dc056a41026a220f20072d00de023a0000200720072f01dc023b01dc05200720072903c8023703c801200720072900cd023700cd012019201e2903003703002018201f29030037030020172020290300370300200720072903f8023703e005202941ffff037122054107490d01202f200a417a6a221041057422296a202f200a41796a220241057422326a220520112f010620026b41057410a2051a200541186a2007290095023700002005201d36000f2005201c36000b2005201b3600072005201a360003200541026a202a2d00003a0000200520072f01a4023b00002005200729039002370013203020296a203020326a220520112f0106222920026b41057410a2051a200541186a200b290300370300200541106a200c290300370300200541086a200d290300370300200520072903a8023703002011202941016a22053b0106200a410274221a20316a416c6a203120104102746a2229200541ffff0371220a20106b41027410a2051a20292016360200200a2010490d022011201a6a41b0056a2105034020052802002210200241016a22023b010420102011360200200541046a21052002200a490d000c030b0b200e41086a2205200a41016a221041057422116a2005200a410574220f6a22052002200a6b410574221710a2051a2005201d36000f2005201c36000b2005201b3600072005201a360003200541026a202a2d00003a0000200520072f01a4023b00002005200729039002370013200541186a200729009502370000200e41e8026a220520116a2005200f6a2205201710a2051a200541186a200b290300370300200541106a200c290300370300200541086a200d290300370300200520072903a802370300200e200241016a22023b0106200a410274200e41c8056a22056a41086a200520104102746a2205200241ffff037120106b41027410a2051a20052016360200200a200e2f010622024f0d07201620103b01042016200e360200201020024f0d072002417f6a2111200e2010417f6a22024102746a41d0056a2105034020052802002210200241026a3b01042010200e360200200541046a21052011200241016a2202470d000c080b0b200e41086a2202200a41016a221041057422296a2002200a41057422316a2202200e2f0106222f200a6b410574223010a2051a2002201d36000f2002201c36000b2002201b3600072002201a360003200241026a202a2d00003a0000200220072f01a4023b00002002200729039002370013200241186a200729009502370000200e41e8026a220220296a200220316a2202203010a2051a200241186a200b290300370300200241106a200c290300370300200241086a200d290300370300200220072903a802370300200e202f41016a22023b0106200a4102742231200e41c8056a22296a41086a202920104102746a2229200241ffff037120106b41027410a2051a202920163602002005200e2f010622104f0d00200e20316a41cc056a2102034020022802002205200a41016a220a3b01042005200e360200200241046a21022010200a470d000b0b202841016a21282007418c026a41026a2202200f2d00003a0000202120172903003703002022201829030037030020232019290300370300200720072f01dc053b018c02200720072903c8013703f801200720072900cd013700fd01200720072903e0053703d801202420022d00003a0000200720072f018c023b01a401200720072900fd0137009501200720072903f80137039001202520232903003703002026202229030037030020272021290300370300200720072903d8013703a8010240200e28020022020d00200741106a2102202b211a202e211d202d211c202c211b201121160c050b200e2f01042129202b211a202e211d202d211c202c211b2002210e201121160c000b0b200a20104105746a22024180036a2205290300211320052007290358370300200241f8026a2205290300211220052007290350370300200241f0026a2205290300211420052007290348370300200241e8026a2202290300211520022007290340370300200720133703f805200720123703f005200720143703e805200720153703e0052012a72202450d0420072802f4052205450d04200541306c450d04200210230c040b200a41086a2202200f410574221041206a22116a200220106a22022005200f6b41057410a2051a200241186a200b290300370000200241106a200c290300370000200241086a200d290300370000200220072903a802370000200a41e8026a220220116a200220106a2202200a2f0106200f6b41057410a2051a200241186a2012370300200220133703102002201437030820022015370300200a200a2f010641016a3b0106200741003602f0050c030b41ecdbc4004135418c94c700102d000b2009410041f20510a0051a41f80510212205450d0620054100360200200541046a200741e0056a41f40510a1051a2005200228020022103602c8052002200536020020022002280204221141016a360204201041003b010420102005360200200741a8026a41026a220a20242d00003a0000200720072f01a4013b01a80220072007290390013703f80220072007290095013700fd02201920252903003703002018202629030037030020172027290300370300200720072903a8013703e00520112028470d0520052f01062210410a4b0d04200520104105746a2202410a6a200a2d00003a0000200241086a20072f01a8023b0000200241176a201d360000200241136a201c3600002002410f6a201b3600002002410b6a201a3600002002411b6a20072903f802370000200241206a20072900fd02370000200241e8026a20072903e005370300200241f0026a2017290300370300200241f8026a201829030037030020024180036a20192903003703002005201041016a22024102746a41c8056a2016360200200520023b0106201620023b0104201620053602000b200741003602f0050b20012008460d012007280210210a0c000b0b0240024020040d004100210d0c010b20032004412c6c6a21184100210d034020032202412c6a21030240200228020841306c2205450d002002280200220a20056a21172002410c6a210c0340200a41306a210b0240024002402007280210220e450d00200728021421010340200e41086a2105200e2f0106220f410574210241002110024003402002450d01200a2005412010a3052211450d04200241606a2102201041016a2110200541206a21052011417f4a0d000b2010417f6a210f0b2001450d012001417f6a2101200e200f4102746a41c8056a280200210e0c000b0b417f200d41016a22022002200d491b210d0c010b200e20104105746a220241e8026a2205427f20052903002212200a2903207c221320132012542205200241f0026a22102903002212200a41286a22112903007c2005ad7c221320125420132012511b22051b3703002010427f201320051b370300200c2900002112200741e0056a41086a220e200c41086a290000370300200741e0056a41106a2201200c41106a290000370300200741e0056a41186a220f200c41186a290000370300200720123703e00520112903002112200a2903202113200241f8026a2111024020024180036a22052802002210200241fc026a280200470d0020112010410110a401200528020021100b2011280200201041306c6a220220072903e00537030020022013370320200241186a200f290300370300200241106a2001290300370300200241086a200e290300370300200241286a20123703002005200528020041016a3602000b200b210a200b2017470d000b0b20032018470d000b0b200020072903103702002000200d36020c200041086a200741106a41086a280200360200200624000f0b41dcd9c4004127418c94c700102d000b4183dac4004130418c94c700102d000b102a000b841205077f017e057f017e087f230041a0026b2202240002400240024002400240024002400240024020012802202203450d0020012003417f6a220436022020012802042205450d022001280208210620012802002107024002402001410c6a280200220820052f01064f0d00200521030c010b034002400240200528020022030d002006ad2109410021030c010b200741016a210720053301044220862006ad8421090b200510232009a72106200321052009422088a7220820032f01064f0d000b0b20024190016a41186a220a200320084105746a220541206a29000037030020024190016a41106a220b200541186a29000037030020024190016a41086a220c200541106a2900003703002002200541086a29000037039001200541f8026a280200210d200241f0016a41086a220e20054184036a2802003602002002200541fc026a2902003703f001200841016a2108200541f0026a2903002109200541e8026a290300210f02402007450d00200320084102746a41c8056a2802002103410021082007417f6a2205450d00034020032802c80521032005417f6a22050d000b0b200241186a41186a200a290300370300200241186a41106a200b290300370300200241186a41086a200c29030037030020024190026a41086a200e2802003602002002200229039001370318200220022903f001370390022001200836020c200120063602082001200336020420014100360200200d0d010b20024180016a41003602000c060b200241b8016a2009370300200241c0016a200d360200200241c4016a20022903900237020020024190016a41186a200241186a41186a29030037030020024190016a41106a200241186a41106a29030037030020024190016a41086a200241186a41086a290300370300200241cc016a20024190026a41086a2802003602002002200f3703b0012002200229031837039001200241c0006a200141246a20024190016a10910220024180016a280200450d0520024190016a200241c0006a41d00010a1051a417f200441016a220320032004491bad42d0007e2209422088a70d012009a72203417f4c0d01200310212210450d02201020024190016a41d00010a1052105200241013602102002200341d0006e36020c20022005360208200241186a41206a200141206a2902002209370300200241186a41186a200141186a290200370300200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318024002402009a72203450d0020022003417f6a220d360238200228021c2205450d05200228022021062002280218210702400240200241246a280200220820052f01064f0d00200521030c010b034002400240200528020022030d002006ad2109410021030c010b200741016a210720053301044220862006ad8421090b200510232009a72106200321052009422088a7220820032f01064f0d000b0b20024190016a41186a2201200320084105746a220541206a29000037030020024190016a41106a220b200541186a29000037030020024190016a41086a220c200541106a2900003703002002200541086a29000037039001200541f8026a280200210a20024190026a41086a220e20054184036a2802003602002002200541fc026a29020037039002200841016a2108200541f0026a2903002109200541e8026a290300210f02402007450d00200320084102746a41c8056a2802002103410021082007417f6a2205450d00034020032802c80521032005417f6a22050d000b0b200241f0016a41186a2001290300370300200241f0016a41106a200b290300370300200241f0016a41086a200c290300370300200241e0016a41086a200e28020036020020022002290390013703f00120022002290390023703e00120022008360224200220063602202002200336021c20024100360218200a450d002002413c6a2111200241c4016a2104200241b8016a2112410121010340200420022903e0013702002012200937030020024190016a41186a220b200241f0016a41186a221329030037030020024190016a41106a220c200241f0016a41106a221429030037030020024190016a41086a220e200241f0016a41086a2215290300370300200441086a200241e0016a41086a22162802003602002002200f3703b001200220022903f001370390012002200a3602c001200241c0006a201120024190016a109102200228028001450d0220024190016a200241c0006a41d00010a1051a02402001200228020c470d00200241086a2001417f200d41016a22052005200d491b10b401200228020821100b2010200141d0006c6a20024190016a41d00010a1051a2002200141016a2201360210200d450d012002200d417f6a220d3602382003450d074100210702400240200820032f01064f0d00200321050c010b41002107034002400240200328020022050d002006ad2109410021050c010b200741016a210720033301044220862006ad8421090b200310232009a72106200521032009422088a7220820052f01064f0d000b0b200b200520084105746a220341206a290000370300200c200341186a290000370300200e200341106a2900003703002002200341086a29000037039001200341f8026a280200210a20024190026a41086a221720034184036a2802003602002002200341fc026a29020037039002200841016a2108200341f0026a2903002109200341e8026a290300210f0240024020070d00200521030c010b200520084102746a41c8056a2802002103410021082007417f6a2205450d00034020032802c80521032005417f6a22050d000b0b2013200b2903003703002014200c2903003703002015200e2903003703002016201728020036020020022002290390013703f00120022002290390023703e00120022008360224200220063602202002200336021c20024100360218200a0d000b0b20024100360280010b200241186a10a602200041086a200241086a41086a280200360200200020022903083702000c060b41d095c700412b41c491c700102d000b1032000b1033000b41d095c700412b41c491c700102d000b41d095c700412b41c491c700102d000b2000410036020820004208370200200110a6020b200241a0026a24000baa0703027f017e067f230041e0006b22032400418fcdc200ad4280808080f00084100c22042900002105200341086a200441086a29000037030020032005370300200410234186d0c000ad4280808080b00184100c22042900002105200341106a41086a200441086a2900003703002003200537031020041023200320013602302003200341306aad4280808080c00084100d220429000037034020041023200341d4006a2201200341346a360200200341003a00582003200341c0006a41086a220636024c2003200341306a3602502003200341c0006a360248200341206a200341c8006a1065024002400240024002400240412010212204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad4280808080800484100d2202290000370340200210232001200441206a360200200341003a0058200320043602502003200636024c2003200341c0006a360248200341306a200341c8006a1065200410232003280228220741206a2201200328023822086a2202417f4c0d01200328023021092003280220210a024002402002450d00200210212204450d022002410f4d0d01200221060c050b200241017422044110200441104b1b2206102122040d040c060b200241017422064110200641104b1b220641004e0d020c040b1033000b1032000b20022006460d0020042002200610252204450d020b20042003290300370000200441086a200341086a2903003700000240024020064170714110460d002006210b0c010b2006410174220b4120200b41204b1b220b4100480d012006200b460d0020042006200b10252204450d020b20042003290310370010200441186a200341106a41086a29030037000002400240200b41606a2007490d00200b21060c010b2007415f4b0d01200b41017422062001200620014b1b22064100480d01200b2006460d002004200b200610252204450d020b200441206a200a200710a1051a02400240200620016b2008490d002006210b0c010b200120086a2001490d012006410174220b2002200b20024b1b220b4100480d01024020060d000240200b0d00410121040c020b200b10212204450d030c010b2006200b460d0020042006200b10252204450d020b200420016a2009200810a1051a200020023602082000200b3602042000200436020002402003280234450d00200910230b02402003280224450d00200a10230b200341e0006a24000f0b102c000b102a000ba50403017f027e027f230041e0006b220224000240024020002802002200290300220342c000544100200041086a29030022045022051b0d0002400240024020034280800154410020051b0d00200342808080800454410020051b0d01411020047920037942c0007c20044200521ba741037622056b4104490d022002413320054102746b3a00482001200241c8006a41011062200029030021032002200041086a290300220437030820022003370300200541706a21000340200220033c00482001200241c8006a410110622003420888200442388684210320044208882104200041016a22052000492106200521002006450d000b20022003370300200220043703082003200484500d04200241286a41146a410b360200200241346a410c360200200241106a41146a410336020020022002360240200241f8e5c200360244200241c8006a41146a4100360200200242033702142002418ca7c7003602102002410c36022c2002419ca8c7003602582002420137024c200241b0e5c2003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a419ca8c700103a000b20022003a74102744101723b01482001200241c8006a410210620c030b20022003a74102744102723602482001200241c8006a410410620c020b41f0e4c2004136418c94c700102d000b20022003a74102743a00482001200241c8006a410110620b200241e0006a24000bf12c080a7f017e017f047e147f017e017f017e230041d0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d0020002001109f042003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00410241012000200a41306c6a220d290300220e200d41506a220f290300221056200d41086a2903002211200f41086a29030022125620112012511b220f1b200f200d41306a29030022132010200e200f1b221056200d41386a290300220e20122011200f1b221156200e2011511b22141b2013201020141b2000200a200a417f6a2215200f1b221641306c6a220d29030056200e201120141b2211200d41086a29030022125620112012511b22176a2000200c41306c6a220d290300220e200d41506a2218290300221056200d41086a2903002211201841086a29030022125620112012511b22186a2000200c410172221941306c6a220d29030022132010200e20181b221056200d41086a290300220e2012201120181b221156200e2011511b221a6a20132010201a1b2000200c200c417f6a221b20181b221c41306c6a220d29030056200e2011201a1b2211200d41086a29030022125620112012511b221d6a2000200b41306c6a220d290300220e200d41506a221e290300221056200d41086a2903002211201e41086a29030022125620112012511b221e6a200d41306a29030022132010200e201e1b221056200d41386a290300220e20122011201e1b221156200e2011511b221f6a20132010201f1b2000200b200b417f6a2220201e1b222141306c6a220d29030056200e2011201f1b2211200d41086a29030022125620112012511b22066a210d2021200b41016a2020200b201e1b201f1b20061b210b201c2019201b200c20181b201a1b201d1b210c2016200a41016a2015200a200f1b20141b20171b210a0b200d2000200c41306c6a220f290300220e2000200a41306c6a2218290300221056200f41086a2903002211201841086a29030022125620112012511b220f6a2000200b41306c6a220d29030022132010200e200f1b221056200d41086a290300220e20122011200f1b221156200e2011511b220d6a211820132010200d1b2000200c200a200f1b222141306c6a221e29030058200e2011200d1b2211201e41086a29030022125820112012511b450d01200b200a200c200f1b200d1b21210c020b2000200110a0040c0f0b201841016a2218410c490d0002402001410176220b450d002000200141306c6a41506a210a2000210c0340200441a0026a41286a220f200c41286a220d290300370300200441a0026a41206a2218200c41206a221e290300370300200441a0026a41186a2214200c41186a221a290300370300200441a0026a41106a221f200c41106a2215290300370300200441a0026a41086a2216200c41086a22172903003703002004200c2903003703a002200a41086a22192903002111200a41106a221b2903002112200a41186a221c290300210e200a41206a221d2903002110200a41286a22202903002113200c200a290300370300200d2013370300201e2010370300201a200e37030020152012370300201720113703002020200f290300370300201d2018290300370300201c2014290300370300201b201f29030037030020192016290300370300200a20042903a002370300200c41306a210c200a41506a210a200b417f6a220b0d000b0b20012021417f736a21214101210a0c010b201845210a0b0240200a452009724101710d002000200110a1040d0d0b2002450d02202120014f0d01024020022903002000202141306c6a220a29030056200241086a2903002211200a41086a220c29030022125620112012511b450d0020002108200121070c040b200441a0026a41286a221a200041286a2218290300370300200441a0026a41206a221f200041206a221e290300370300200441a0026a41186a2215200041186a2214290300370300200441a0026a41106a2216200041106a220b290300370300200441a0026a41086a2217200041086a220f290300370300200420002903003703a002200c2903002111200a41106a220d2903002112200a41186a2219290300210e200a41206a221b2903002110200a41286a221c29030021132000200a29030037030020182013370300201e20103703002014200e370300200b2012370300200f2011370300201c201a290300370300201b201f29030037030020192015290300370300200d2016290300370300200c2017290300370300200a20042903a002370300200f29030021112000290300210e200441186a221c2018290300370300200441106a221d201e290300370300200441086a222020142903003703002004200b290300370300200041506a2119200041306a211b4100210c2001210b03400240200c200b417f6a220f4f0d00201b200c41306c6a210a0340200e200a290300582011200a41086a29030022125820112012511b450d01200a41306a210a200f200c41016a220c470d000b200f210c0b2019200b41306c6a210a02400340200c200b417f6a220b4f0d01200a2903002112200a41086a210f200a41506a220d210a200e2012562011200f29030022125620112012511b0d000b201a201b200c41306c6a220a41286a220f290300370300201f200a41206a22212903003703002015200a41186a22062903003703002016200a41106a22222903003703002017200a41086a22232903003703002004200a2903003703a002200d41386a22242903002112200d41c0006a22252903002110200d41c8006a22262903002113200d41d0006a22272903002128200d41d8006a2229290300212a200a200d41306a220d290300370300200f202a370300202120283703002006201337030020222010370300202320123703002029201a2903003703002027201f290300370300202620152903003703002025201629030037030020242017290300370300200d20042903a002370300200c41016a210c0c010b0b2000200e370300200020113703082000200429030037031020142020290300370300201e201d2903003703002018201c29030037030002402001200c41016a220a490d002000200a41306c6a21002001200a6b220141154f0d010c0c0b0b200a200141e8c5c4001044000b2021200141ccc6c4001030000b2007450d010b202120074f0d01200441a0026a41286a2217200841286a2222290300370300200441a0026a41206a2219200841206a2223290300370300200441a0026a41186a221b200841186a2224290300370300200441a0026a41106a221c200841106a2225290300370300200441a0026a41086a221d200841086a2226290300370300200420082903003703a0022008202141306c6a220a41086a220c2903002111200a41106a220b2903002112200a41186a220f290300210e200a41206a220d2903002110200a41286a220029030021132008200a29030037030020222013370300202320103703002024200e370300202520123703002026201137030020002017290300370300200d2019290300370300200f201b290300370300200b201c290300370300200c201d290300370300200a20042903a0023703002026290300211120082903002112200441186a22272022290300370300200441106a22292023290300370300200441086a2205202429030037030020042025290300370300200841306a2101410021212007417f6a220f450d022001210a0340200a290300201256200a41086a290300220e201156200e2011511b450d03200a41306a210a200f202141016a2221470d000b200f21210c020b410041004184d9c4001030000b2021200741f8c5c4001030000b2008200741306c6a210a200f210b02400340200a2100200b220c20214d22060d01200c417f6a210b200041506a220a290300201258200a41086a290300220e201158200e2011511b0d000b0b0240200c2021490d00200f200c490d0241800121154100210d4100211a4100210f4100211441800121162001202141306c6a220921010340200020016b220a41306e210c0240200a41afe0004b22200d00200c41807f6a200c201a200d492014200f49220b7222181b210a02402018450d002016200a200b1b2116200a2015200b1b21150c010b200a200a41017622166b21150b02402014200f470d00024020160d00200441206a220f21140c010b4100210c200441206a2214210f2001210a0340200f200c3a0000200f410041014102200a2903002210201285200a41086a290300220e20118584501b2010201254200e201154200e2011511b1b4102744198c6c4006a2802006a210f200a41306a210a2016200c41016a220c470d000b0b0240201a200d470d00024020150d00200441a0016a220d211a0c010b200041506a210a4100210c200441a0016a221a210d0340200d200c3a0000200d410041014102200a2903002210201285200a41086a290300220e20118584501b2010201254200e201154200e2011511b1b41027441a4c6c4006a2802006a210d200a41506a210a2015200c41016a220c470d000b0b0240200d201a6b220a200f20146b220c200c200a4b1b221f450d002017200120142d000041306c6a220a41286a2903003703002019200a41206a290300370300201b200a41186a290300370300201c200a41106a290300370300201d200a41086a2903003703002004200a2903003703a002200120142d000041306c6a220a2000201a2d0000417f7341306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a2903003703000240201f4101460d004100210b03402000201a200b6a22182d0000417f7341306c6a220a20012014200b6a41016a221e2d000041306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a2903003703002001201e2d000041306c6a220a2000201841016a2d0000417f7341306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a290300370300200b41026a210a200b41016a220c210b200a201f490d000b201a200c6a211a2014200c6a21140b2000201a2d0000417f7341306c6a220a20042903a002370300200a41286a2017290300370300200a41206a2019290300370300200a41186a201b290300370300200a41106a201c290300370300200a41086a201d290300370300201a41016a211a201441016a21140b2001201641306c6a20012014200f461b21012000410020156b41306c6a2000201a200d461b210020200d000b024002402014200f4f0d002000210a034020172001200f417f6a220f2d000041306c6a220c41286a220b2903003703002019200c41206a220d290300370300201b200c41186a2200290300370300201c200c41106a2218290300370300201d200c41086a221e2903003703002004200c2903003703a002200a41506a220a41086a221a290300210e200a41106a221f2903002110200a41186a22152903002113200a41206a22162903002128200a41286a2220290300212a200c200a290300370300200b202a370300200d20283703002000201337030020182010370300201e200e37030020202017290300370300201620192903003703002015201b290300370300201f201c290300370300201a201d290300370300200a20042903a0023703002014200f490d000c020b0b2001210a201a200d4f0d000340200d417f6a220d2d0000210c2017200a41286a220b2903003703002019200a41206a220f290300370300201b200a41186a2201290300370300201c200a41106a2218290300370300201d200a41086a221e2903003703002004200a2903003703a0022000200c417f7341306c6a220c41086a2214290300210e200c41106a221f2903002110200c41186a22152903002113200c41206a22162903002128200c41286a2220290300212a200a200c290300370300200b202a370300200f20283703002001201337030020182010370300201e200e37030020202017290300370300201620192903003703002015201b290300370300201f201c2903003703002014201d290300370300200c20042903a002370300200a41306a210a201a200d490d000b0b2008201137030820082012370300200820042903003703102024200529030037030020232029290300370300202220272903003703002007200a20096b41306e20216a22014d0d032017202229030037030020192023290300370300201b2024290300370300201c2025290300370300201d2026290300370300200420082903003703a0022008200141306c6a220a41086a220c2903002111200a41106a220b2903002112200a41186a220f290300210e200a41206a220d2903002110200a41286a220029030021132008200a29030037030020222013370300202320103703002024200e370300202520123703002026201137030020002017290300370300200d2019290300370300200f201b290300370300200b201c290300370300200c201d290300370300200a20042903a002370300200720016b220c450d04200c20012001200c4b1b210b2007410376210f200a41306a2100024002402001200c417f6a220c490d002000200c200a200310dc01200821000c010b200820012002200310dc01200a2102200c21010b200b200f4f2105200141154f0d010c050b0b2021200c4188c6c4001044000b200c200f4188c6c4001043000b2001200741f8c5c4001030000b41b0c6c400411c418c94c700102d000b20014102490d00200041a07f6a210d410021184101210c0340200c41016a210f02402000200c41306c6a220b290300220e200b41506a220a29030058200b41086a221e2903002211200a41086a221429030022125820112012511b0d00200441186a221a200b41286a221f290300370300200441106a2215200b41206a2216290300370300200441086a2217200b41186a22192903003703002004200b290310370300200b200a290300370300201e2014290300370300200b41106a200a41106a2903003703002019200a41186a2903003703002016200a41206a290300370300201f200a41286a2903003703002000200c417f6a221e41306c6a211402400240201e0d004100211e0c010b2018210c200d210a200e200b41a07f6a220b290300582011200b41086a29030022125820112012511b0d00024002400340200a4188016a200a41d8006a290300370300200a4180016a200a41d0006a290300370300200a41f8006a200a41c8006a290300370300200a41f0006a200a41c0006a290300370300200a41e8006a200a41386a290300370300200a41e0006a200a41306a290300370300200c4101460d01200a2903002112200a41086a210b200c417f6a210c200a41506a210a200e2012562011200b29030022125620112012511b0d000c020b0b4100210c0b2000200c41306c6a2114200c211e0b2014200e370300201420113703082000201e41306c6a220a41286a201a290300370300200a41206a2015290300370300200a41186a2017290300370300200a20042903003703100b201841016a2118200d41306a210d200f210c200f2001470d000b0b200441d0026a24000baa0703027f017e067f230041e0006b22032400418fcdc200ad4280808080f00084100c22042900002105200341086a200441086a290000370300200320053703002004102341f4cfc000ad4280808080a00284100c22042900002105200341106a41086a200441086a2900003703002003200537031020041023200320013602302003200341306aad4280808080c00084100d220429000037034020041023200341d4006a2201200341346a360200200341003a00582003200341c0006a41086a220636024c2003200341306a3602502003200341c0006a360248200341206a200341c8006a1065024002400240024002400240412010212204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad4280808080800484100d2202290000370340200210232001200441206a360200200341003a0058200320043602502003200636024c2003200341c0006a360248200341306a200341c8006a1065200410232003280228220741206a2201200328023822086a2202417f4c0d01200328023021092003280220210a024002402002450d00200210212204450d022002410f4d0d01200221060c050b200241017422044110200441104b1b2206102122040d040c060b200241017422064110200641104b1b220641004e0d020c040b1033000b1032000b20022006460d0020042002200610252204450d020b20042003290300370000200441086a200341086a2903003700000240024020064170714110460d002006210b0c010b2006410174220b4120200b41204b1b220b4100480d012006200b460d0020042006200b10252204450d020b20042003290310370010200441186a200341106a41086a29030037000002400240200b41606a2007490d00200b21060c010b2007415f4b0d01200b41017422062001200620014b1b22064100480d01200b2006460d002004200b200610252204450d020b200441206a200a200710a1051a02400240200620016b2008490d002006210b0c010b200120086a2001490d012006410174220b2002200b20024b1b220b4100480d01024020060d000240200b0d00410121040c020b200b10212204450d030c010b2006200b460d0020042006200b10252204450d020b200420016a2009200810a1051a200020023602082000200b3602042000200436020002402003280234450d00200910230b02402003280224450d00200a10230b200341e0006a24000f0b102c000b102a000bac0201037f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841010108b0102400240200328021022010d00410021020c010b200328021421042003200341186a280200360224200320013602202003200341206a1088010240024020032802000d0020032802042105410121020c010b4100210220034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034180c5c6003602482003200341386a360258200341c4006a4184a5c200200341c8006a10311a2003350230422086200335022884100a0240200328022c450d00200328022810230b0b2004450d00200110230b2000200536020420002002360200200341e0006a24000baa0703027f017e067f230041e0006b22032400418fcdc200ad4280808080f00084100c22042900002105200341086a200441086a290000370300200320053703002004102341e2cfc000ad4280808080a00284100c22042900002105200341106a41086a200441086a2900003703002003200537031020041023200320013602302003200341306aad4280808080c00084100d220429000037034020041023200341d4006a2201200341346a360200200341003a00582003200341c0006a41086a220636024c2003200341306a3602502003200341c0006a360248200341206a200341c8006a1065024002400240024002400240412010212204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad4280808080800484100d2202290000370340200210232001200441206a360200200341003a0058200320043602502003200636024c2003200341c0006a360248200341306a200341c8006a1065200410232003280228220741206a2201200328023822086a2202417f4c0d01200328023021092003280220210a024002402002450d00200210212204450d022002410f4d0d01200221060c050b200241017422044110200441104b1b2206102122040d040c060b200241017422064110200641104b1b220641004e0d020c040b1033000b1032000b20022006460d0020042002200610252204450d020b20042003290300370000200441086a200341086a2903003700000240024020064170714110460d002006210b0c010b2006410174220b4120200b41204b1b220b4100480d012006200b460d0020042006200b10252204450d020b20042003290310370010200441186a200341106a41086a29030037000002400240200b41606a2007490d00200b21060c010b2007415f4b0d01200b41017422062001200620014b1b22064100480d01200b2006460d002004200b200610252204450d020b200441206a200a200710a1051a02400240200620016b2008490d002006210b0c010b200120086a2001490d012006410174220b2002200b20024b1b220b4100480d01024020060d000240200b0d00410121040c020b200b10212204450d030c010b2006200b460d0020042006200b10252204450d020b200420016a2009200810a1051a200020023602082000200b3602042000200436020002402003280234450d00200910230b02402003280224450d00200a10230b200341e0006a24000f0b102c000b102a000b8b1606047f017e027f017e0a7f027e230041c0036b22012400200141b0026a41186a4200370300200141b0026a41106a22024200370300200141b0026a41086a22034200370300200142003703b00241e4dec400ad4280808080e00084100c22042900002105200141a0036a41086a2206200441086a290000370300200120053703a0032004102320032006290300370300200120012903a0033703b00241f3dec400ad4280808080e00084100c220429000021052006200441086a290000370300200120053703a00320041023200220012903a003220537030020014190026a41086a200329030037030020014190026a41106a200537030020014190026a41186a2006290300370300200120012903b00237039002200141086a20014190026a412010cd010240024002400240024002400240024002400240024002402001280208450d00200128020c450d00200141b0026a41186a22044200370300200141b0026a41106a22074200370300200141b0026a41086a22034200370300200142003703b00241e4dec400ad4280808080e000842208100c22092900002105200141a0036a41086a2206200941086a290000370300200120053703a0032009102320032006290300370300200120012903a0033703b00241d483c500ad4280808080e00184100c220929000021052006200941086a290000370300200120053703a00320091023200220012903a003370000200241086a220a200629030037000020014190026a41086a220b200329030037030020014190026a41106a220c200729030037030020014190026a41186a220d2004290300370300200120012903b002370390022001412036028c03200120014190026a36028803200141b0026a20014190026aad428080808080048422051010108b010240024020012802b002220e0d00410321090c010b20012802b402210f02400240024020032802002210450d00200e2d0000221141024b0d00410121090240024020110e03000401000b2010417f6a4104490d01200e2800012112410021090c030b410221090c010b20014100360218200142013703102001410a3602a403200120014188036a3602a0032001200141106a3602f002200141a4016a4101360200200142013702940120014180c5c600360290012001200141a0036a3602a001200141f0026a4184a5c20020014190016a10311a2001350218422086200135021084100a02402001280214450d00200128021010230b410321090b0b200f450d00200e10230b200141106a200041e80010a1051a2001410036029801200142013703900120014190016a41004100109a0120032001280298012200360200200141fc006a201236020020014188016a2000360200200120012903900122133703b00220014102200920094103461b3602782001201337038001200442003703002007420037030020034200370300200142003703b0022008100c220029000021082006200041086a290000370300200120083703a0032000102320032006290300370300200120012903a0033703b00241e481c500ad4280808080a001842213100c220029000021082006200041086a290000370300200120083703a00320001023200220012903a003370000200a2006290300370000200b2003290300370300200c2007290300370300200d2004290300370300200120012903b00237039002200120014190026a412010cd012001280204410020012802001b220641016a22072006490d01200141b0026a41186a22044200370300200141b0026a41106a22004200370300200141b0026a41086a22034200370300200142003703b00241e4dec400ad4280808080e000842208100c22092900002114200141a0036a41086a2206200941086a290000370300200120143703a0032009102320032006290300370300200120012903a0033703b0022013100c220929000021132006200941086a290000370300200120133703a00320091023200220012903a003370000200241086a2209200629030037000020014190026a41086a2212200329030037030020014190026a41106a220a200029030037030020014190026a41186a220b2004290300370300200120012903b002370390022001200736029001200520014190016aad4280808080c00084100e20014190016a200141106a41800110a1051a200442003703002000420037030020034200370300200142003703b0022008100c220729000021082006200741086a290000370300200120083703a0032007102320032006290300370300200120012903a0033703b00241c0e3c400ad4280808080e00084100c220729000021082006200741086a290000370300200120083703a00320071023200220012903a0033700002009200629030037000020122003290300370300200a2000290300370300200b2004290300370300200120012903b0023703900220014188036a20051010108b01024002402001280288030d00200142003702a403200141083602a003410410212202450d04200142043702b402200120023602b0024100200141b0026a1061200141d8026a20012802b802360200200120012903b0023703d002200141a0036a10af040c010b200141d0026a41086a20014188036a41086a28020036020020012001290388033703d0020b200141e0026a41086a200141d0026a41086a2802002202360200200120012903d0023703e002024002402002450d00200141b0026a20012802e00220024101107520012802b0024101470d0120012802e402450d0c20012802e00210230c0c0b4101200141e0026a106120014190016a200141e0026a10b7040c090b20012802b40221040240200141bc026a2802002202200141b0026a41086a2802002206460d0020012802e802200220066b6a220341046a2200417f4c0d040240024020000d00410121070c010b200010212207450d040b200120003602f402200120073602f002200120033602f8022001200141f0026a3602b0022004200141b0026a200210b20320032002490d0520012802f80222042003490d0620012802e80222042006490d0720012802f002210020012802e00221072001200320026b2203360280032001200420066b22043602840320032004470d08200020026a200720066a200310a1051a20014190016a200141f0026a10b70420012802f802210620012802f402210320012802f002210220012802e402450d0a20012802e00210230c0a0b2001200141e0026a3602b0022004200141b0026a200610b20320014190016a200141e0026a10b7040c080b200010b8040c0a0b200141106a10b80420014184016a28020041ffffff3f71450d0920012802800110230c090b1033000b1032000b2002200341c494c6001044000b2003200441c494c6001043000b2006200441d494c6001044000b200141a0036a41146a410b360200200141ac036a410d36020020014188036a41146a4103360200200120014180036a3602b803200120014184036a3602bc03200141b0026a41146a41003602002001420337028c032001418ca7c700360288032001410d3602a4032001419ca8c7003602c002200142013702b402200141e0a7c7003602b0022001200141a0036a360298032001200141b0026a3602b0032001200141bc036a3602a8032001200141b8036a3602a00320014188036a419ca8c700103a000b20012802e802210620012802e402210320012802e00221020b2002450d0020052006ad4220862002ad84100e02402003450d00200210230b20014190016a10b80420014184026a28020041ffffff3f71450d0120012802800210230c010b20014190016a10b80420014184026a28020041ffffff3f71450d0020012802800210230b200141c0036a24000bd50302047f047e230041f0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841010108b0102400240200328021022040d00200041003a00000c010b200341186a28020021052003280214210641002101200341003a006802400240034020052001460d01200341c8006a20016a200420016a2d00003a00002003200141016a22023a00682002210120024120470d000b200341206a41186a200341c8006a41186a2903002207370300200341206a41106a200341c8006a41106a2903002208370300200341206a41086a200341c8006a41086a290300220937030020032003290348220a370320200041196a2007370000200041116a2008370000200041096a20093700002000200a370001410121010c010b0240200141ff0171450d00200341003a00680b4100210120034100360228200342013703202003410a3602442003200341086a3602402003200341206a36026c200341dc006a41013602002003420137024c20034180c5c6003602482003200341c0006a360258200341ec006a4184a5c200200341c8006a10311a2003350228422086200335022084100a2003280224450d00200328022010230b200020013a00002006450d00200410230b200341f0006a24000bd20804047f047e047f047e230041d0016b220324002003200236024420032001360240200341c8006a2002ad4220862001ad841010108b0102400240200328024822040d00200041003602200c010b200328024c21052003200341d0006a280200220636027c2003200436027841002101200341003a00c8010240024002400240024002400240024002400240034020062001460d01200341a8016a20016a200420016a22022d00003a00002003200241016a3602782003200141016a22023a00c8012002210120024120470d000b20034188016a41086a200341a8016a41086a29030037030020034188016a41106a200341a8016a41106a29030037030020034188016a41186a200341a8016a41186a290300370300200320032903a801370388012003200620026b36027c200341286a200341f8006a1080022003290328a70d08200341286a41106a290300210720032903302108200341106a200341f8006a1080022003290310a70d08200341106a41106a29030021092003290318210a200341a8016a200341f8006a10b20420032802a8012202450d08200341b0016a280200210b20032802ac012101200341086a200341f8006a10880120032802080d07200328027c220c200328020c4102742206490d072006417f4c0d0320060d014101210d0c020b2003410036027c200141ff0171450d07200341003a00c8010c070b20061027220d450d02200d2003280278220e200610a1051a2003200c20066b36027c2003200e20066a3602780b200d450d0402402006ad220f422086200f84220f422088a722060d00200fa721060c030b0240200d2006724103710d00200fa722064103710d002006410276220c450d03200f422288a7210e0c040b200fa7450d04200d10230c040b1032000b1033000b4100210e02402006450d00200d10230b4100210c4104210d0b41000d00200d450d00200341d8006a41186a20034188016a41186a290300220f370300200341d8006a41106a20034188016a41106a2903002210370300200341d8006a41086a20034188016a41086a290300221137030020032003290388012212370358200041186a20093703002000200a3703102000200737030820002008370300200041346a200e360200200041306a200c3602002000412c6a200d360200200041286a200b3602002000200136022420002002360220200041386a2012370300200041c0006a2011370300200041c8006a2010370300200041d0006a200f3703000c020b2001450d00200141186c450d00200210230b200341003602900120034201370388012003410a36025c2003200341c0006a360258200320034188016a36028401200341bc016a4101360200200342013702ac0120034180c5c6003602a8012003200341d8006a3602b80120034184016a4184a5c200200341a8016a10311a20033502900142208620033502880184100a0240200328028c01450d0020032802880110230b200041003602200b2005450d00200410230b200341d0016a24000b883510047f017e017f017e017f017e057f017e097f017e037f017e017f017e0a7f077e23004190026b22012400200141a0016a41186a22024200370300200141a0016a41106a22034200370300200141a0016a41086a22044200370300200142003703a001418fcdc200ad4280808080f000842205100c2206290000210720014180016a41086a2208200641086a2900003703002001200737038001200610232004200829030037030020012001290380013703a00141b8dbc100ad42808080809001842207100c220629000021092008200641086a29000037030020012009370380012006102320032001290380012209370300200141286a41086a220a2004290300370300200141286a41106a220b2009370300200141286a41186a220c2008290300370300200120012903a001370328200141a0016a200141286a10ba012003280200210d20012903a0012109200242003703002003420037030020044200370300200142003703a0012005100c220629000021052008200641086a2900003703002001200537038001200610232004200829030037030020012001290380013703a0012007100c220629000021052008200641086a29000037030020012005370380012006102320032001290380012205370300200a2004290300370300200b2005370300200c2008290300370300200120012903a00137032802400240410410212208450d0020084100200d41016a20094202511b220e36000020084104410810252208450d0041002102200841003a0004200141286aad220f42808080808004842008ad4280808080d00084100e20081023200141a0016a41186a220a4200370300200141a0016a41106a220b4200370300200141a0016a41086a22044200370300200142003703a001418fcdc200ad4280808080f00084100c2206290000210520014180016a41086a2208200641086a2900003703002001200537038001200610232004200829030037030020012001290380013703a00141dce0c100ad4280808080a00184100c220629000021052008200641086a2900003703002001200537038001200610232003200129038001370000200341086a2008290300370000200141286a41086a2004290300370300200141286a41106a200b290300370300200141286a41186a200a290300370300200120012903a001370328200141e0006a200141286a10e401024002400240200128026022100d0020014100360220200142043703180c010b20012902642105200120103602182001200537021c2005422088a722082005a72202470d010b200141186a2002410110a50120012802182110200128022021080b201020084103746a220420003602042004200e3602002001200841016a22113602200240024002400240200e411d4f0d00201121120c010b024020110d0041002112200141003602200c010b200e41646a2104200841ffffffff017141016a2106410021132010210802400340200828020020044f0d01200841086a21082006201341016a2213470d000b0b0240024020112013490d0041002112200141003602202013450d0120134103742114200141fc016aad4280808080c00084210520014180026a211520014180026a41086a21162010210c0340200c280200210d418fcdc200ad4280808080f000842207100c22082900002109200141e0006a41086a2202200841086a290000370300200120093703602008102341ecc4c000ad4280808080b00284100c2208290000210920014180016a41086a2200200841086a2900003703002001200937038001200810232001200d3602fc0120012005100d22082900003703800220081023200141003a00b001200120153602ac01200120163602a4012001200141fc016a3602a801200120014180026a3602a001200141286a200141a0016a10652001280230220a41206a2204417f4c0d07200128022821170240024002402004450d00200410212208450d072004410f4d0d01200421060c020b200441017422084110200841104b1b2206102122080d010c080b200441017422064110200641104b1b22064100480d0620042006460d0020082004200610252208450d070b20082001290360370000200841086a20022903003700000240024020064170714110460d002006210b0c010b2006410174220b4120200b41204b1b220b4100480d062006200b460d0020082006200b10252208450d070b2008200129038001370010200841186a20002903003700000240200b41606a200a4f0d00200a41206a2206200a490d06200b41017422182006201820064b1b22064100480d06200b2006460d002008200b200610252208450d070b200841206a2017200a10a1051a0240200128022c450d00201710230b2004ad4220862008ad841012200810232007100c220829000021072002200841086a290000370300200120073703602008102341ffc4c000ad4280808080b00284100c220829000021072000200841086a2900003703002001200737038001200810232001200d3602fc0120012005100d22082900003703800220081023200141003a00b001200120153602ac01200120163602a4012001200141fc016a3602a801200120014180026a3602a001200141286a200141a0016a10652001280230220a41206a2204417f4c0d072001280228210b0240024002402004450d00200410212208450d072004410f4d0d01200421060c020b200441017422084110200841104b1b220610212208450d080c010b200441017422064110200641104b1b22064100480d0620042006460d0020082004200610252208450d070b20082001290360370000200841086a20022903003700000240024020064170714110460d00200621020c010b200641017422024120200241204b1b22024100480d0620062002460d0020082006200210252208450d070b2008200129038001370010200841186a20002903003700000240200241606a200a4f0d00200a415f4b0d06200241017422062004200620044b1b22064100480d0620022006460d0020082002200610252208450d070b200841206a200b200a10a1051a0240200128022c450d00200b10230b200c41086a210c2004ad4220862008ad84101220081023201441786a22140d000c020b0b20132011103c000b201120136b2217450d0002402013450d002010201020134103746a201741037410a2051a0b2001201736022020102802042113200141a0016a41186a4200370300200141a0016a41106a22164200370300200141a0016a41086a22084200370300200142003703a00141db97c700ad4280808080f00084100c22042900002105200141e0006a41086a2206200441086a290000370300200120053703602004102320082006290300370300200120012903603703a00141a7a8c000ad4280808080b00184100c2204290000210520014180016a41086a2206200441086a29000037030020012005370380012004102320162001290380012205370300200141286a41086a2008290300370300200141286a41106a2005370300200141286a41186a2006290300370300200120012903a001370328200141a0016a200141286a412010e5014101210820012902a40121190240024020012802a00122044101460d00200441014621080c010b2019422088a722182013201320184b1b220d2019a72202490d000240200d20024d0d00200141fc016aad4280808080c00084210720014180026a211420014180026a41086a211541db97c700ad4280808080f00084210903402009100c22082900002105200141e0006a41086a2200200841086a290000370300200120053703602008102341e297c700ad4280808080a00284100c2208290000210520014180016a41086a220c200841086a290000370300200120053703800120081023200120023602fc0120012007100d22082900003703800220081023200141003a00b001200120143602ac01200120153602a4012001200141fc016a3602a801200120014180026a3602a001200141286a200141a0016a10652001280230220a41206a2204417f4c0d072001280228210b0240024002402004450d00200410212208450d072004410f4d0d01200421060c020b41102106411010212208450d080c010b200441017422064110200641104b1b22064100480d06024020042006470d00200421060c010b20082004200610252208450d070b20082001290360370000200841086a20002903003700000240024020064170714110460d00200621000c010b200641017422004120200041204b1b22004100480d0620062000460d0020082006200010252208450d070b2008200129038001370010200841186a200c2903003700000240200041606a200a4f0d00200a415f4b0d06200041017422062004200620044b1b22064100480d0620002006460d0020082000200610252208450d070b200241016a2102200841206a200b200a10a1051a0240200128022c450d00200b10230b2004ad4220862008ad84101120081023200d2002470d000b0b20132018492108201942808080807083200dad8421190b200120193702840220012008360280020240024020080d00200141a0016a41186a22064200370300200141a0016a41106a22024200370300200141a0016a41086a22084200370300200142003703a00141db97c700ad4280808080f00084100c22042900002105200141e0006a41086a2200200441086a290000370300200120053703602004102320082000290300370300200120012903603703a00141a7a8c000ad4280808080b00184100c2204290000210520014180016a41086a2200200441086a2900003703002001200537038001200410232016200129038001370000201641086a2000290300370000200141286a41086a2008290300370300200141286a41106a2002290300370300200141286a41186a2006290300370300200120012903a001370328200f428080808080048410110c010b200141a0016a41186a22064200370300200141a0016a41106a22024200370300200141a0016a41086a22084200370300200142003703a00141db97c700ad4280808080f00084100c22042900002105200141e0006a41086a2200200441086a290000370300200120053703602004102320082000290300370300200120012903603703a00141a7a8c000ad4280808080b00184100c2204290000210520014180016a41086a2200200441086a2900003703002001200537038001200410232016200129038001370000201641086a2000290300370000200141286a41086a2008290300370300200141286a41106a2002290300370300200141286a41186a2006290300370300200120012903a001370328200141203602a4012001200141286a3602a00120014180026a410472200141a0016a10e6010b201721120b200128021c2115200141a0016a41186a22024200370300200141a0016a41106a22004200370300200141a0016a41086a22044200370300200142003703a001418fcdc200ad4280808080f00084100c2206290000210520014180016a41086a2208200641086a2900003703002001200537038001200610232004200829030037030020012001290380013703a00141dce0c100ad4280808080a00184100c220629000021052008200641086a2900003703002001200537038001200610232003200129038001370000200341086a2008290300370000200141286a41086a2004290300370300200141286a41106a2000290300370300200141286a41186a2002290300370300200120012903a0013703280240024020100d00200f428080808080048410110c010b20124103744104722208417f4c0d04200810212204450d01200141003602a801200120083602a401200120043602a0012012200141a0016a10610240024020120d0020012802a801210820012802a00121020c010b201020124103746a2114410020012802a801220b6b210020012802a4012104410021080340200b20086a210a201020086a220c280200210d02400240200420006a4104490d0020012802a0012102200421060c010b200a41046a2206200a490d05200441017422022006200220064b1b22064100480d050240024020040d00024020060d00410121020c020b200610212202450d080c010b20012802a001210220042006460d0020022004200610252202450d070b200120063602a401200120023602a0010b2002200b6a20086a200d3600002001200a41046a22043602a801200c41046a280200210d02400240200620006a417c6a41034d0d00200621040c010b200441046a22172004490d05200641017422042017200420174b1b22044100480d050240024020060d00024020040d00410121020c020b200410212202450d080c010b20062004460d0020022006200410252202450d070b200120043602a401200120023602a0010b2002200b6a20086a41046a200d3600002001200a41086a3602a801200041786a2100200841086a2108200c41086a2014470d000b200b20086a21080b20012802a4012104200f42808080808004842008ad4220862002ad84100e02402004450d00200210230b201541ffffffff0171450d00201010230b200141a0016a41186a221a4200370300200141a0016a41106a221b4200370300200141a0016a41086a221c4200370300200142003703a001418fcdc200ad4280808080f00084221d100c2208290000210520014180016a41086a221e200841086a290000370300200120053703800120081023201c201e29030037030020012001290380013703a001419ce3c100ad4280808080e00284221f100c22082900002105201e200841086a2900003703002001200537038001200810232003200129038001370000200341086a2220201e290300370000200141286a41086a2221201c290300370300200141286a41106a2222201b290300370300200141286a41186a2223201a290300370300200120012903a001370328200141106a200141286a412010cd01200128021421240240200128021022254101470d00024020244100200e41646a22082008200e4b1b22264f0d00200141d8016a2127200141a0016a41246a2100200141a0016a41286a2117202421280340200141286a202810e701200141a0016a200128022822082001280230220410e8010240024020012802a00122290d004200212a410821290c010b2004ad4220862008ad84101120012902a401212a0b0240200128022c450d00200810230b2029202a422088a7220841d8006c6a210b2029210202402008450d00034020014180016a41186a220d200241186a29030037030020014180016a41106a2210200241106a29030037030020014180016a41086a220c200241086a2903003703002002280220210a20022903002105200141a0016a41206a2214200241c4006a2902003703002017200241cc006a290200370300200141a0016a41306a2215200241d4006a280200360200200141a0016a41086a22082002412c6a290200370300200141a0016a41106a2204200241346a290200370300200141a0016a41186a22062002413c6a29020037030020012005370380012001200241246a2902003703a001200241d8006a2102200a450d01200141e0006a41186a2216200d290300370300200141e0006a41106a220d2010290300370300200141e0006a41086a2210200c290300370300200141286a41086a22132008290300370300200141286a41106a22182004290300370300200141286a41186a220e2006290300370300200141286a41206a22122014290300370300200141286a41286a22142017290300370300200141286a41306a221120152802003602002001200129038001370360200120012903a001370328200620162903003703002004200d2903003703002008201029030037030020002001290328370200200041086a2013290300370200200041106a2018290300370200200041186a200e290300370200200041206a2012290300370200200041286a2014290300370200200041306a2011280200360200200120012903603703a0012001200a3602c0012001420037038802200142003703800220012006290300370388012001200429030037038001202720012903a001200829030020014180016a20014180026a10e901024020012802c8012208450d00200841306c2104200a210803402008200841206a290300200841286a29030020014180016a20014180026a10e901200841306a2108200441506a22040d000b0b20014180026a41086a290300212b200129038002212c20012802cc01210d02402001290380012207200c290300220584500d0020012802d4012208450d002001202c2007202c200754202b200554202b2005511b22041b222d202b200520041b222e2008ad420010a70520084105742104200141086a29030021092001290300212f202d2105202e2107200d210803402008202f20052005202f56200720095620072009511b22061b22192009200720061b223010ea01200720307d2005201954ad7d2107200520197d2105200841206a2108200441606a22040d000b427f202b202e7d202c202d54ad7d220920077c202c202d7d220720057c22192007542208ad7c22052008200520095420052009511b22081b212b427f201920081b212c0b202c202b10eb01024020012802c4012208450d00200841306c450d00200a10230b024020012802d00141ffffff3f71450d00200d10230b2002200b470d000b200b21020b202aa721040240200b2002460d0003400240200241246a2802002208450d00200841306c450d00200241206a28020010230b200241d8006a21080240200241306a28020041ffffff3f71450d002002412c6a28020010230b20082102200b2008470d000b0b202841016a212802402004450d00200441d8006c450d00202910230b20282026470d000b0b20242026202420264b1b21240b201a4200370300201b4200370300201c4200370300200142003703a001201d100c22082900002105201e200841086a290000370300200120053703800120081023201c201e29030037030020012001290380013703a001201f100c22082900002105201e200841086a29000037030020012005370380012008102320032001290380013700002020201e2903003700002021201c2903003703002022201b2903003703002023201a290300370300200120012903a0013703280240024020250d00200f428080808080048410110c010b200120243602a001200f4280808080800484200141a0016aad4280808080c00084100e0b20014190026a24000f0b1033000b102c000b102a000b1032000be30401097f230041e0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841010108b010240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a1088010240024020022802000d0020022802042205200228022422064103762201200120054b1b22014103742207417f4c0d030240024020010d00410421080c010b200710212208450d050b200241003602502002200136024c20022008360248024002402005450d004100210103402002410036022820064104490d0220022006417c6a220636022420022002280220220741046a360220200728000021092002410036022820064104490d0220022006417c6a22063602242002200741086a3602202007280004210702402001200228024c470d00200241c8006a2001410110a50120022802482108200228025021010b200820014103746a220a2007360204200a20093602002002200141016a22013602502005417f6a22050d000b0b2008450d012000200229024c370204200020083602000c020b200228024c41ffffffff0171450d00200810230b20024100360230200242013703282002410a36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c20024180c5c6003602482002200241386a360258200241c4006a4184a5c200200241c8006a10311a2002350230422086200235022884100a0240200228022c450d00200228022810230b200041003602000b2004450d00200310230b200241e0006a24000f0b1032000b1033000bba0201037f230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad841010108b0102400240200328020822010d00200041003602000c010b200341106a2802002102200328020c2104200341003602380240024020024104490d0020012800002105200341003602382002417c714104460d00200041086a200128000436020020002005360204200041013602000c010b20034100360220200342013703182003410a36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c20034180c5c6003602382003200341286a360248200341346a4184a5c200200341386a10311a2003350220422086200335021884100a0240200328021c450d00200328021810230b200041003602000b2004450d00200110230b200341d0006a24000b3c01017f02404108102122020d001033000b200220002802003600002002200028020436000420012902002002ad4280808080800184100e200210230bf90403027f017e057f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a200341086a29000037030020022004370300200310234191d0c000ad4280808080800284100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bfd0f06057f017e0b7f027e067f047e230041c0026b220324002003200236021c20032001360218200341206a2002ad4220862001ad841010108b0102400240200328022022040d00200041003602000c010b200328022421052003200341286a28020036023420032004360230200341106a200341306a1088010240024020032802100d00024002400240200328021422062003280234220741d8006e2201200120064b1bad42d8007e2208422088a70d002008a72201417f4c0d000240024020010d00410821090c010b200110212209450d020b4100210a20034100360240200320093602382003200141d8006e36023c02402006450d004100210b034041002101200341003a00b802200b41016a210b417f210202400240034020072001460d0120034198026a20016a2003280230220c2d00003a00002003200720026a3602342003200c41016a3602302003200141016a220d3a00b8022002417f6a2102200d2101200d4120470d000b200341a8016a41186a220e20034198026a41186a220f290300370300200341a8016a41106a221020034198026a41106a2211290300370300200341a8016a41086a221220034198026a41086a221329030037030020032003290398023703a8012007200d6b22014110490d062003200c41116a3602302003200141706a360234200c41096a2900002114200c2900012115200341086a200341306a1088012003280208450d010c060b200141ff0171450d05200341003a00b8020c050b200328020c22162003280234220741306e2201200120164b1bad42307e2208422088a70d022008a72201417f4c0d020240024020010d00410821170c010b200110212217450d040b41002118200341003602d001200320173602c8012003200141306e22023602cc01024002400240024002402016450d0041002118410021190340200341003a00b802201941016a2119417f210241002101034020072001460d0320034198026a20016a2003280230220c2d00003a00002003200720026a3602342003200c41016a3602302003200141016a220d3a00b8022002417f6a2102200d2101200d4120470d000b200341f8016a41186a2201200f290300370300200341f8016a41106a22022011290300370300200341f8016a41086a221a201329030037030020032003290398023703f8012007200d6b220d4110490d03200341d8016a41086a221b201a290300370300200341d8016a41106a221a2002290300370300200341d8016a41186a22022001290300370300200320032903f8013703d8012003200c41116a3602302003200d41706a2207360234200c41096a2900002108200c290001211c0240201820032802cc01470d00200341c8016a2018410110a40120032802c801211720032802d00121180b2017201841306c6a220120032903d801370300201b290300211d201a290300211e2002290300211f2001201c370320200141286a2008370300200141186a201f370300200141106a201e370300200141086a201d3703002003201841016a22183602d00120192016470d000b20032802cc0121020b2017450d0820034198026a200341306a10cf01200328029802220d450d02200328029c02210720032802342201410f4b0d030240200741ffffff3f71450d00200d10230b2002450d08200241306c450d08201710230c080b200141ff0171450d00200341003a00b8020b20032802cc012201450d06200141306c450d06201710230c060b2002450d05200241306c450d05201710230c050b20032802a002210c200341e8006a41086a20122903002208370300200341e8006a41106a2010290300221c370300200341e8006a41186a200e290300221d370300200341c8006a41186a2216201d370300200341c8006a41106a2219201c370300200341c8006a41086a220f20083703002003200141706a36023420032003280230220141106a360230200320032903a801220837036820032008370348200141086a29000021082001290000211c0240200a200328023c470d00200341386a200a410110a901200328023821092003280240210a0b2009200a41d8006c6a2201201c370310200120143703082001201537030020012017360220200141186a2008370300200141346a200c360200200141306a20073602002001412c6a200d360200200141286a2018360200200141246a2002360200200141386a2003290348370200200141c0006a200f290300370200200141c8006a2019290300370200200141d0006a20162903003702002003200a41016a220a360240200b2006460d01200328023421070c000b0b2009450d032000200329023c370204200020093602000c040b1032000b1033000b200341e8006a41086a20034188016a41086a2903003703000240200a450d00200a41d8006c2102200941306a210103400240200141746a280200220d450d00200d41306c450d00200141706a28020010230b0240200128020041ffffff3f71450d002001417c6a28020010230b200141d8006a2101200241a87f6a22020d000b0b200328023c2201450d00200141d8006c450d00200910230b2003410036028002200342013703f8012003410a3602dc012003200341186a3602d8012003200341f8016a3602a801200341ac026a41013602002003420137029c0220034180c5c600360298022003200341d8016a3602a802200341a8016a4184a5c20020034198026a10311a20033502800242208620033502f80184100a024020032802fc01450d0020032802f80110230b200041003602000b2005450d00200410230b200341c0026a24000b961d020f7f137e23004180056b22052400200541206a200010c70120054198046a20052802202206200528022810e101200541b0036a41086a2207200541a1046a290000370300200541b0036a41106a2208200541a9046a290000370300200541b0036a41186a2209200541b1046a29000037030020052005290099043703b0034100210a024020052d0098044101470d00200541c8026a41186a2009290300370300200541c8026a41106a2008290300370300200541c8026a41086a2007290300370300200520052903b0033703c8024101210a0b02402005280224450d00200610230b02400240200a450d00200541186a200541c8026a41186a2206290300370300200541106a200541c8026a41106a2207290300370300200541086a200541c8026a41086a2208290300370300200520052903c802370300200541d8016a200510c60120054198046a20052802d801220920052802e00110e20120054188016a41086a220b20054198046a41086a29030037030020054188016a41106a220c20054198046a41106a29030037030020054188016a41186a220d20054198046a41186a290300370300200541b0036a41086a220e200541c4046a290200370300200541b0036a41106a220f200541cc046a290200370300200541b0036a41186a2210200541d4046a290200370300200541b0036a41206a2211200541dc046a290200370300200541b0036a41286a2212200541e4046a290200370300200541b0036a41306a2213200541ec046a280200360200200520052903980437038801200520052902bc043703b003024020052802b804220a450d0020054190026a41186a200d29030037030020054190026a41106a200c29030037030020054190026a41086a200b2903003703002008200e2903003703002007200f29030037030020062010290300370300200541c8026a41206a2011290300370300200541c8026a41286a2012290300370300200541c8026a41306a2013280200360200200520052903880137039002200520052903b0033703c8020b024020052802dc01450d00200910230b200a450d00200541c4006a20052903c802370200200541206a41186a220620054190026a41186a290300370300200541206a41106a220720054190026a41106a290300370300200541206a41086a220820054190026a41086a290300370300200541cc006a200541c8026a41086a290300370200200541d4006a200541c8026a41106a290300370200200541dc006a200541c8026a41186a290300370200200541e4006a200541e8026a290300370200200541ec006a200541c8026a41286a290300370200200541f4006a200541f8026a28020036020020052005290390023703202005200a36024020082903002114200529032021150240024020072903002216200120162001542006290300221720025420172002511b22071b22182017200220071b22198450450d002015211a2014211b0c010b2006201720197d2016201854ad7d221c3703002005201620187d221a37033002400240201a4280c8afa02556201c420052201c501b450d0020182116201921170c010b200541386a420037030020054200370330201c20027c201a20017c2201201a54ad7c21020b20054200201420177d2015201654ad7d2218201520167d221c201556201820145620182014511b22061b221b37032820054200201c20061b221a370320200220177d2001201654ad7d2102200120167d21010b02400240200541206a41286a28020022060d004100210a410021060c010b200641186c21084100210603400240200a2903002216200120012016562002200a41086a220929030022175620022017511b22071b22182017200220071b221984500d00200a201620187d221a370300200a201720197d2016201854ad7d221c37030802400240201a4280c8afa02556201c420052201c501b450d002001211c20182116201921170c010b200a4200370308200a42003703002002201c7c2001201a7c221c200154ad7c21020b200541206a41086a220742002007290300220120177d20052903202218201654ad7d2219201820167d221a201856201920015620192001511b22071b221b37030020054200201a20071b221a370320200220177d201c201654ad7d2102201c20167d210120092903002117200a29030021160b024020162017844200520d00200a41186a210a200641016a2106200841686a22080d010b0b2005280248220a2006490d020b200541003602480240200a20066b220a450d0002402006450d00200528024022072007200641186c6a200a41186c10a2051a0b2005200a3602480b024042002015201a7d221620162015562014201b7d2015201a54ad7d221620145620162014511b220a1b220242002016200a1b220184500d00200541f8006a200010970220054188016a200528027822062005280280012207109802200529038801211b2005420037038801200541d0016a280200210820052d00d401210902400240201b4201510d004200211c200541d8016a41306a4200370300200541d8016a41286a4200370300200541d8016a41206a4200370300200541d8016a41186a4200370300200541e8016a4200370300200541e0016a4200370300200542003703d8014200211942002117420021164200211d0c010b200541c0016a290300211820054188016a41306a290300211a20054188016a41206a290300211920054188016a41186a290300211c200541c8016a290300211d20052903980121162005290390012117200541d8016a41206a20054188016a41286a290300370300200541d8016a41286a201a370300200541d8016a41306a2018370300200541e8016a201c370300200520193703f001200520173703d801200520163703e0010b20052017200220172017200256201620015620162001511b220a1b221a7d22143703d8012005201620012016200a1b221e7d2017201a54ad7d22183703e001201620197c211f2017201c7c2220201754220bad2121200541d8016a41106a210a024002402002201a7d22152001201e7d2002201a54ad7d22228450450d004200211c420021222002211e200121230c010b200541f0016a201920222019201c201556201920225620192022511b220c1b22237d201c2015201c200c1b221754ad7d3703002005201c20177d3703e801202220237d2015201754ad7d21222023201e7c2017201a7c221e201754ad7c2123201520177d211c0b201f20217c211720054190026a41186a200a41086a290300221937030020054190026a41206a220c200a41106a290300370300200541b8026a220d200a41186a290300370300200541c0026a220e200a41206a2903003703002005200a290300221a3703a0022005201437039002200520183703980202400240427f2014201a7c221a201a201454220a201820197c200aad7c221920185420192018511b220a1b221a4280c8afa025544100427f2019200a1b2215501b0d00200541a0026a290300211a200e2903002115200d290300211f200c2903002121200529039802212420052903900221254201211920052903a80221260c010b420021190240201a201584500d00201a201510eb01200541d0046a2015370300200541c8046a201a37030020054198046a41086a41013a0000200541a1046a2000290000370000200541a9046a200041086a290000370000200541b1046a200041106a290000370000200541b9046a200041186a290000370000200541023a00980420054198046a10e0010b0b2017201651210a2017201654210c200541b0016a2021370300200541b8016a201f37030020054198016a2024370300200541c0016a2015370300200541a0016a201a370300200520263703a8012005201d3703c8012005202537039001200520094100201b420151220d1b3a00d401200520084100200d1b3602d001200520194201512208ad370388010240024020080d002007ad4220862006ad8410110c010b2005200736029c04200520063602980420054190016a20054198046a1098030b200b200c200a1b210a0240200528027c450d00200610230b427f2017200a1b2116427f2020200a1b21172019420152210a024002400240201b4201510d00200a0d0041032106200541b0036a210a0c010b201b420152200a410173720d0141042106200541c8026a210a0b200a41046a20063a0000200a41003a0000200a41056a2000290000370000200a410d6a200041086a290000370000200a41156a200041106a290000370000200a411d6a200041186a290000370000200a10e0010b024020172016844200520d00200541d0046a2018370300200541c8046a201437030020054198046a41086a41003a0000200541a1046a2000290000370000200541a9046a200041086a290000370000200541b1046a200041106a290000370000200541b9046a200041186a290000370000200541023a00980420054198046a10e0010b2004427f20042903002216201e7c22172017201654220a200441086a2206290300221620237c200aad7c221720165420172016511b220a1b3703002006427f2017200a1b3703000240201c202284500d002003420020032903002216201c7d22172017201656200341086a220a290300221720227d2016201c54ad7d221620175620162017511b22061b370300200a4200201620061b3703000b200542f3e885db96cddbb3203703c802200541c8026a200541206a41386a2005290320200541206a41086a290300411f10990220054198046a200510c601200528029804210a200520052802a0043602b4032005200a3602b003200541206a200541b0036a10ec010240200528029c04450d00200a10230b20054198046a41386a2001370300200541c8046a200237030020054198046a41086a41013a0000200541a1046a2000290000370000200541a9046a200041086a290000370000200541b1046a200041106a290000370000200541b9046a200041186a290000370000200541033a00980420054198046a10e0010b02402005280244220a450d00200a41186c450d00200528024010230b200541d0006a28020041ffffffff0371450d00200528024c10230b20054180056a24000f0b2006200a103c000bbb180e017f027e027f027e037f047e017f017e047f027e027f017e017f027e230041d0046b2203240002400240200120028450450d0042002104420021050c010b200341386a2000109702200341c8006a200328023822062003280240220710980220032903482108420021092003420037034820034190016a280200210a20032d009401210b024002402008420151220c0d0020034198016a41306a420037030020034198016a41286a420037030020034198016a41206a420037030020034198016a41186a4200370300200341a8016a4200370300200341a0016a420037030020034200370398014200210d42002105420021044200210e0c010b20034180016a290300210f200341c8006a41306a2903002110200341c8006a41206a290300210d200341c8006a41186a290300210920034188016a290300210e200329035821042003290350210520034198016a41206a200341c8006a41286a29030037030020034198016a41286a201037030020034198016a41306a200f370300200341a8016a20093703002003200d3703b0012003200537039801200320043703a0010b427f2004200d7c200520097c220d2005542211ad7c22092011200920045420092004511b22111b2110427f200d20111b21124200210902400240200142ffc7afa0255620024200522002501b0d00201220108450450d004100210c4100211342002104410121110c010b4200200420027c200520017c220d2005542211ad7c22052011200520045420052004511b22111b21044200200d20111b210f024020114101470d00200f421088200442308684210920044210882104200f420888a72113200fa7210c410121110c010b200341d8036a41186a22144200370300200341d8036a41106a22154200370300200341d8036a41086a22134200370300200342003703d80341bdadc500ad42808080808001842209100c22162900002117200341c0046a41086a2211201641086a290000370300200320173703c0042016102320132011290300370300200320032903c0043703d80341c5adc500ad4280808080d001842217100c221629000021182011201641086a290000370300200320183703c00420161023201520032903c0042218370300200341d0016a41086a22192013290300370300200341d0016a41106a221a2018370300200341d0016a41186a22162011290300370300200320032903d8033703d001200341206a200341d0016a412010d701200341206a41106a29030021182003290328211b2003280220211c201442003703002015420037030020134200370300200342003703d8032009100c221429000021092011201441086a290000370300200320093703c0042014102320132011290300370300200320032903c0043703d8032017100c221429000021092011201441086a290000370300200320093703c00420141023201520032903c004220937030020192013290300370300201a200937030020162011290300370300200320032903d8033703d001200320184200201c1b3703e0032003201b4200201c1b3703d803200341d0016aad4280808080800484200341d8036aad4280808080800284100e200320043703a0012003200f370398012016200341a8016a221141086a2903002209370300200341d0016a41206a2213201141106a290300370300200341f8016a2215201141186a29030037030020034180026a2216201141206a290300370300200320043703d8012003200f3703d0012003201129030022173703e00102400240427f200f20177c22172017200f542211200420097c2011ad7c220920045420092004511b22111b22044280c8afa025544100427f200920111b2209501b0d00201a2903002104201629030021092015290300210f2013290300211720032903d801211820032903d001211b4201211d20032903e801211e0c010b4200211d02402004200984500d002004200910eb0120034190046a200937030020034188046a2004370300200341d8036a41086a41013a0000200341e1036a2000290000370000200341e9036a200041086a290000370000200341f1036a200041106a290000370000200341f9036a200041186a290000370000200341023a00d803200341d8036a10e0010b0b200341f0006a2017370300200341f8006a200f370300200341d8006a201837030020034180016a2009370300200341e0006a20043703002003201e3703682003200e370388012003201b370350410021112003200b4100200842015122131b3a0094012003200a410020131b360290012003201d4201512213ad370348201220108450ad423086210942002104024020130d002007ad4220862006ad841011410021130c010b200320073602dc03200320063602d803200341d0006a200341d8036a10980341012113410021110b0240200328023c450d00200610230b024020110d0020094230882004421086842109024002400240200c41ff0171220c0d00201341ff0171450d0041032111200341f0026a210c0c010b200c450d01201341ff01710d014104211120034188026a210c0b200c41046a20113a0000200c41003a0000200c41056a2000290000370000200c410d6a200041086a290000370000200c41156a200041106a290000370000200c411d6a200041186a290000370000200c10e0010b200341c8006a41106a220c20053703002003200d37035020032009370348200121042002210520094201520d012003290350210420034190046a200c29030037030020034188046a2004370300200341d8036a41086a41003a0000200341e1036a2000290000370000200341e9036a200041086a290000370000200341f1036a200041106a290000370000200341f9036a200041186a290000370000200341023a00d803200341d8036a10e00120012104200221050c010b20032004421086200942308884220537035020032013ad42ff0183420886200cad42ff01838420094210868422043703480b200341d8036a41186a22064200370300200341d8036a41106a22114200370300200341d8036a41086a220c4200370300200342003703d80341bdadc500ad4280808080800184220f100c2213290000210920034188026a41086a2200201341086a290000370300200320093703880220131023200c200029030037030020032003290388023703d80341c5adc500ad4280808080d001842210100c221329000021092000201341086a29000037030020032009370388022013102320112003290388022209370300200341f0026a41086a220b200c290300370300200341f0026a41106a22072009370300200341f0026a41186a22152000290300370300200320032903d8033703f002200341086a200341f0026a412010d701200220057d2001200454ad7d200520027d2004200154ad7d20042001582005200258200520025122131b220a1b2112200120047d200420017d200a1b2108200341086a41106a29030042002003280208220a1b210920032903104200200a1b210d024002402004200156200520025620131b0d002006420037030020114200370300200c4200370300200342003703d803200f100c221329000021012000201341086a290000370300200320013703880220131023200c200029030037030020032003290388023703d8032010100c221329000021012000201341086a2900003703002003200137038802201310232011200329038802370000201141086a2000290300370000200b200c2903003703002007201129030037030020152006290300370300200320032903d8033703f00220034200200920127d200d200854ad7d2201200d20087d2202200d56200120095620012009511b22001b3703e00320034200200220001b3703d803200341d8036a21000c010b2006420037030020114200370300200c4200370300200342003703d803200f100c221329000021012000201341086a290000370300200320013703880220131023200c200029030037030020032003290388023703d8032010100c221329000021012000201341086a2900003703002003200137038802201310232011200329038802370000201141086a2000290300370000200b200c2903003703002007201129030037030020152006290300370300200320032903d8033703f0022003427f200920127c200d20087c2202200d542200ad7c22012000200120095420012009511b22001b3703e0032003427f200220001b3703d803200341d8036a21000b200341f0026aad42808080808004842000ad4280808080800284100e200341d0046a24000b800508017f017e047f017e017f017e037f017e23004180016b22022400200241186a2000200110cf0302402002290318a7450d00200241186a41106a290300210320022903202100200241d0006a41186a22044200370300200241d0006a41106a22054200370300200241d0006a41086a220642003703002002420037035041bdadc500ad42808080808001842201100c22072900002108200241f0006a41086a2209200741086a2900003703002002200837037020071023200620092903003703002002200229037037035041c5adc500ad4280808080d001842208100c2207290000210a2009200741086a2900003703002002200a3703702007102320052002290370220a370300200241306a41086a220b2006290300370300200241306a41106a220c200a370300200241306a41186a220d2009290300370300200220022903503703302002200241306a412010d701200241106a290300210a2002290308210e20022802002107200442003703002005420037030020064200370300200242003703502001100c220429000021012009200441086a290000370300200220013703702004102320062009290300370300200220022903703703502008100c220429000021012009200441086a2900003703002002200137037020041023200520022903702201370300200b2006290300370300200c2001370300200d20092903003703002002200229035037033020024200200a420020071b220120037d200e420020071b2203200054ad7d2208200320007d2200200356200820015620082001511b22091b37035820024200200020091b370350200241306aad4280808080800484200241d0006aad4280808080800284100e0b20024180016a24000bd80301067f230041106b2202240020024100360208200242013703000240412010212203450d0020032000290038370000200341086a200041c0006a290000370000200341106a200041c8006a290000370000200341186a200041d0006a29000037000020022003360200200242a080808080043702042002200036020c2002410c6a200210db012002200041106a36020c2002410c6a200210db0120002802202103200041286a28020022042002106102402004450d002003200441186c6a210403402002200336020c2002410c6a200210db01200341106a200210ed012004200341186a2203470d000b0b200028022c2105200041346a28020022032002106102400240024020022802042206200228020822046b20034102742200490d0020022802002103200621070c010b200420006a22032004490d01200641017422072003200720034b1b22074100480d010240024020060d00024020070d00410121030c020b2007102122030d010c040b2002280200210320062007460d0020032006200710252203450d030b20022007360204200220033602000b200320046a2005200010a1051a2001290200200420006aad4220862003ad84100e02402007450d00200310230b200241106a24000f0b102c000b102a000bb30101027f230041106b2202240002400240024002402000280200220341c000490d00200341808001490d012003418080808004490d02200241033a00032001200241036a41011062200220002802003602042001200241046a410410620c030b200220034102743a00032001200241036a410110620c020b200220034102744101723b010a20012002410a6a410210620c010b2002200341027441027236020c20012002410c6a410410620b200241106a24000b130020004118360204200041a4d0c0003602000bab0407047f017e017f017e017f017e037f230041d0006b22002400200041206a41186a22014200370300200041206a41106a22024200370300200041206a41086a2203420037030020004200370320418fcdc200ad4280808080f000842204100c22052900002106200041c0006a41086a2207200541086a2900003703002000200637034020051023200320072903003703002000200029034037032041fcdec100ad42808080808001842208100c220529000021062007200541086a2900003703002000200637034020051023200220002903402206370300200041086a22092003290300370300200041106a220a2006370300200041186a220b2007290300370300200020002903203703000240024002404100200010f0012205200541ff01714104461b41ff0171417f6a220541024b0d0020050e03010001010b200142003703002002420037030020034200370300200042003703202004100c220529000021062007200541086a290000370300200020063703402005102320032007290300370300200020002903403703202008100c220529000021062007200541086a290000370300200020063703402005102320022000290340370000200241086a200729030037000020092003290300370300200a2002290300370300200b200129030037030020002000290320370300410110212207450d01200741013a00002000ad42808080808004842007ad42808080801084100e200710230b200041d0006a24000f0b102a000b810201037f230041d0006b220124002001412036020420012000360200200141086a2000ad42808080808004841010108b0102400240200128020822020d00410421000c010b200128020c210302400240200141106a280200450d0020022d000022004104490d010b20014100360220200142013703182001410a36022c200120013602282001200141186a360234200141cc006a41013602002001420137023c20014180c5c6003602382001200141286a360248200141346a4184a5c200200141386a10311a2001350220422086200135021884100a0240200128021c450d00200128021810230b410421000b2003450d00200210230b200141d0006a240020000b34002000418fcdc20036020420004100360200200041146a4124360200200041106a41b0bfc100360200200041086a42073702000b2b01017f02404101102122020d00102a000b200042818080801037020420002002360200200241023a00000b2b01017f02404101102122020d00102a000b200042818080801037020420002002360200200241003a00000b5301017f0240411010212202450d00200242003700082002420037000020024110412010252202450d0020024200370010200042a0808080800437020420002002360200200241186a42003700000f0b102a000b940302047f017e230041206b2203240002400240200241d8006c4104722204417f4c0d00200410212205450d0120034100360208200320043602042003200536020020022003106102402002450d002001200241d8006c6a210603402003200141386a41201062200129030021072003200141086a290300370318200320073703102003200341106a4110106220012802202102200128022822042003106102402004450d002002200441306c6a210403402003200241201062200241206a29030021072003200241286a290300370318200320073703102003200341106a411010622004200241306a2202470d000b0b200141d8006a2105200128022c2102200141346a28020022042003106102402004450d002004410574210403402003200241201062200241206a2102200441606a22040d000b0b200129031021072003200141186a290300370318200320073703102003200341106a411010622005210120052006470d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1032000b1033000b3301017f02404110102122020d001033000b2002420037000820024200370000200042908080808002370204200020023602000b860101027f230041206b220224002002410c6a410036020020024200370300200241003602182002420137031002404104102122030d00102a000b200341003600002002200336021020024284808080c00037021420024104722203200241106a10bd01200041086a200228021836020020002002290310370200200310be01200241206a24000be90101047f230041106b220224002002410036020c02400240410110212203450d000240024002400240200228020c220441c000490d00200441808001490d012004418080808004490d02200341033a0000200228020c21044105210520034101410510252203450d05200320043600010c030b200320044102743a0000410121050c020b4102210520034101410210252203450d03200320044102744101723b00000c010b4104210520034101410410252203450d02200320044102744102723600000b200020053602082000200536020420002003360200200241106a24000f0b1033000b102a000bf60301087f230041c0006b22022400200241186a4200370300200241106a22034200370300200241086a4200370300200241286a22044100360200200242003703002002420837032020024100360238200242013703302002200236023c2002413c6a200241306a10db012002200336023c2002413c6a200241306a10db012002280220210320042802002204200241306a10610240024002402004450d00200441306c210503400240024020022802342206200228023822046b4120490d00200441206a2107200228023021080c010b200441206a22072004490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009102122080d010c060b2002280230210820062009460d0020082006200910252208450d050b20022009360234200220083602300b200820046a2204200341106a290000370000200441186a200341286a290000370000200441106a200341206a290000370000200441086a200341186a290000370000200220073602382002200336023c2002413c6a200241306a10db01200341306a2103200541506a22050d000b0b20002002290330370200200041086a200241306a41086a280200360200024020022802242203450d00200341306c450d00200228022010230b200241c0006a24000f0b102c000b102a000b4d01027f230041106b2202240002404104102122030d001033000b2002420437020420022003360200410020021061200041086a200228020836020020002002290300370200200241106a24000b2c01017f02404104102122020d001033000b20004284808080c00037020420002002360200200241043600000b2d01017f02404104102122020d001033000b20004284808080c00037020420002002360200200241d4003600000b130020004102360204200041ec86c2003602000b2c01017f02404104102122020d001033000b20004284808080c000370204200020023602002002411c3600000b2c01017f02404104102122020d001033000b20004284808080c00037020420002002360200200241063600000bde0506067f017e017f017e017f017e230041206b220224000240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200024002400240200541037122074103460d0002400240024020070e03000102000b2005410276ad21080c040b410121072006450d0220042d0001210620012003417e6a3602042001200441026a3602002006410874200572220141ffff0371418002490d02200141fcff0371410276ad21080c030b4101210720064103490d01200441036a2d0000210620042f0001210920012003417c6a3602042001200441046a3602002009200641107472410874200572220141808004490d012001410276ad21080c020b024020054102762209410c4b0d0002400240024020090e0d00030303010303030303030302000b20064104490d052004350001210820012003417b6a3602042001200441056a36020020084280808080045421074200210a0c060b20064108490d04200429000121082001200341776a3602042001200441096a3602002008428080808080808080015421074200210a0c050b20064110490d03200441096a290000210a2004290001210820012003416f6a3602042001200441116a360200200a428080808080808080015421070c040b200941046a220641104b0d022003417e6a2103200441026a21044100210541012107200241186a210b420021084200210a03402003417f460d01200241106a2004417f6a3100004200200541037441f8007110a40520012003360204200120043602002003417f6a2103200441016a2104200b290300200a84210a20022903102008842108200541016a220541ff01712006490d000b2002427f427f41e80020094103746b41f8007110a5052008200229030058200a200241086a290300220c58200a200c511b21070c030b0c020b4200210a410021070c010b410121070b20002008370308200041106a200a37030020002007ad370300200241206a24000bd53901037f230041106b2202240020002802002103200028020822042001106102402004450d00200320044103746a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a41021062200341086a22032004470d000b0b200028020c2103200041146a28020022042001106102402004450d0020032004410c6c6a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a410210622003410c6a22032004470d000b0b20002802182103200041206a28020022042001106102402004450d00200320044104746a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a41021062200341106a22032004470d000b0b200028022421032000412c6a28020022042001106102402004450d002003200441146c6a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a41021062200341146a22032004470d000b0b20002802302103200041386a28020022042001106102402004450d002003200441186c6a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a41021062200341186a22032004470d000b0b200028023c2103200041c4006a28020022042001106102402004450d0020032004411c6c6a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a410210622002200341166a2f01003b010c20012002410c6a410210622002200341186a2f01003b010c20012002410c6a410210622003411c6a22032004470d000b0b20002802482103200041d0006a28020022042001106102402004450d00200320044105746a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a410210622002200341166a2f01003b010c20012002410c6a410210622002200341186a2f01003b010c20012002410c6a4102106220022003411a6a2f01003b010c20012002410c6a4102106220022003411c6a2f01003b010c20012002410c6a41021062200341206a22032004470d000b0b20002802542103200041dc006a28020022042001106102402004450d002003200441246c6a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a410210622002200341166a2f01003b010c20012002410c6a410210622002200341186a2f01003b010c20012002410c6a4102106220022003411a6a2f01003b010c20012002410c6a4102106220022003411c6a2f01003b010c20012002410c6a4102106220022003411e6a2f01003b010c20012002410c6a410210622002200341206a2f01003b010c20012002410c6a41021062200341246a22032004470d000b0b20002802602103200041e8006a28020022042001106102402004450d002003200441286c6a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a410210622002200341166a2f01003b010c20012002410c6a410210622002200341186a2f01003b010c20012002410c6a4102106220022003411a6a2f01003b010c20012002410c6a4102106220022003411c6a2f01003b010c20012002410c6a4102106220022003411e6a2f01003b010c20012002410c6a410210622002200341206a2f01003b010c20012002410c6a410210622002200341226a2f01003b010c20012002410c6a410210622002200341246a2f01003b010c20012002410c6a41021062200341286a22032004470d000b0b200028026c2103200041f4006a28020022042001106102402004450d0020032004412c6c6a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a410210622002200341166a2f01003b010c20012002410c6a410210622002200341186a2f01003b010c20012002410c6a4102106220022003411a6a2f01003b010c20012002410c6a4102106220022003411c6a2f01003b010c20012002410c6a4102106220022003411e6a2f01003b010c20012002410c6a410210622002200341206a2f01003b010c20012002410c6a410210622002200341226a2f01003b010c20012002410c6a410210622002200341246a2f01003b010c20012002410c6a410210622002200341266a2f01003b010c20012002410c6a410210622002200341286a2f01003b010c20012002410c6a410210622003412c6a22032004470d000b0b2000280278210320004180016a28020022042001106102402004450d002003200441306c6a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a410210622002200341166a2f01003b010c20012002410c6a410210622002200341186a2f01003b010c20012002410c6a4102106220022003411a6a2f01003b010c20012002410c6a4102106220022003411c6a2f01003b010c20012002410c6a4102106220022003411e6a2f01003b010c20012002410c6a410210622002200341206a2f01003b010c20012002410c6a410210622002200341226a2f01003b010c20012002410c6a410210622002200341246a2f01003b010c20012002410c6a410210622002200341266a2f01003b010c20012002410c6a410210622002200341286a2f01003b010c20012002410c6a4102106220022003412a6a2f01003b010c20012002410c6a4102106220022003412c6a2f01003b010c20012002410c6a41021062200341306a22032004470d000b0b20002802840121032000418c016a28020022042001106102402004450d002003200441346c6a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a410210622002200341166a2f01003b010c20012002410c6a410210622002200341186a2f01003b010c20012002410c6a4102106220022003411a6a2f01003b010c20012002410c6a4102106220022003411c6a2f01003b010c20012002410c6a4102106220022003411e6a2f01003b010c20012002410c6a410210622002200341206a2f01003b010c20012002410c6a410210622002200341226a2f01003b010c20012002410c6a410210622002200341246a2f01003b010c20012002410c6a410210622002200341266a2f01003b010c20012002410c6a410210622002200341286a2f01003b010c20012002410c6a4102106220022003412a6a2f01003b010c20012002410c6a4102106220022003412c6a2f01003b010c20012002410c6a4102106220022003412e6a2f01003b010c20012002410c6a410210622002200341306a2f01003b010c20012002410c6a41021062200341346a22032004470d000b0b200028029001210320004198016a28020022042001106102402004450d002003200441386c6a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a410210622002200341166a2f01003b010c20012002410c6a410210622002200341186a2f01003b010c20012002410c6a4102106220022003411a6a2f01003b010c20012002410c6a4102106220022003411c6a2f01003b010c20012002410c6a4102106220022003411e6a2f01003b010c20012002410c6a410210622002200341206a2f01003b010c20012002410c6a410210622002200341226a2f01003b010c20012002410c6a410210622002200341246a2f01003b010c20012002410c6a410210622002200341266a2f01003b010c20012002410c6a410210622002200341286a2f01003b010c20012002410c6a4102106220022003412a6a2f01003b010c20012002410c6a4102106220022003412c6a2f01003b010c20012002410c6a4102106220022003412e6a2f01003b010c20012002410c6a410210622002200341306a2f01003b010c20012002410c6a410210622002200341326a2f01003b010c20012002410c6a410210622002200341346a2f01003b010c20012002410c6a41021062200341386a22032004470d000b0b200028029c012103200041a4016a28020022042001106102402004450d0020032004413c6c6a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a410210622002200341166a2f01003b010c20012002410c6a410210622002200341186a2f01003b010c20012002410c6a4102106220022003411a6a2f01003b010c20012002410c6a4102106220022003411c6a2f01003b010c20012002410c6a4102106220022003411e6a2f01003b010c20012002410c6a410210622002200341206a2f01003b010c20012002410c6a410210622002200341226a2f01003b010c20012002410c6a410210622002200341246a2f01003b010c20012002410c6a410210622002200341266a2f01003b010c20012002410c6a410210622002200341286a2f01003b010c20012002410c6a4102106220022003412a6a2f01003b010c20012002410c6a4102106220022003412c6a2f01003b010c20012002410c6a4102106220022003412e6a2f01003b010c20012002410c6a410210622002200341306a2f01003b010c20012002410c6a410210622002200341326a2f01003b010c20012002410c6a410210622002200341346a2f01003b010c20012002410c6a410210622002200341366a2f01003b010c20012002410c6a410210622002200341386a2f01003b010c20012002410c6a410210622003413c6a22032004470d000b0b20002802a8012103200041b0016a28020022042001106102402004450d00200320044106746a210403402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a410210622002200341166a2f01003b010c20012002410c6a410210622002200341186a2f01003b010c20012002410c6a4102106220022003411a6a2f01003b010c20012002410c6a4102106220022003411c6a2f01003b010c20012002410c6a4102106220022003411e6a2f01003b010c20012002410c6a410210622002200341206a2f01003b010c20012002410c6a410210622002200341226a2f01003b010c20012002410c6a410210622002200341246a2f01003b010c20012002410c6a410210622002200341266a2f01003b010c20012002410c6a410210622002200341286a2f01003b010c20012002410c6a4102106220022003412a6a2f01003b010c20012002410c6a4102106220022003412c6a2f01003b010c20012002410c6a4102106220022003412e6a2f01003b010c20012002410c6a410210622002200341306a2f01003b010c20012002410c6a410210622002200341326a2f01003b010c20012002410c6a410210622002200341346a2f01003b010c20012002410c6a410210622002200341366a2f01003b010c20012002410c6a410210622002200341386a2f01003b010c20012002410c6a4102106220022003413a6a2f01003b010c20012002410c6a4102106220022003413c6a2f01003b010c20012002410c6a41021062200341c0006a22032004470d000b0b20002802b4012103200041bc016a28020022002001106102402000450d002003200041c4006c6a210003402002200328020036020c20012002410c6a410410622002200341046a2f01003b010c20012002410c6a410210622002200341066a2f01003b010c20012002410c6a410210622002200341086a2f01003b010c20012002410c6a4102106220022003410a6a2f01003b010c20012002410c6a4102106220022003410c6a2f01003b010c20012002410c6a4102106220022003410e6a2f01003b010c20012002410c6a410210622002200341106a2f01003b010c20012002410c6a410210622002200341126a2f01003b010c20012002410c6a410210622002200341146a2f01003b010c20012002410c6a410210622002200341166a2f01003b010c20012002410c6a410210622002200341186a2f01003b010c20012002410c6a4102106220022003411a6a2f01003b010c20012002410c6a4102106220022003411c6a2f01003b010c20012002410c6a4102106220022003411e6a2f01003b010c20012002410c6a410210622002200341206a2f01003b010c20012002410c6a410210622002200341226a2f01003b010c20012002410c6a410210622002200341246a2f01003b010c20012002410c6a410210622002200341266a2f01003b010c20012002410c6a410210622002200341286a2f01003b010c20012002410c6a4102106220022003412a6a2f01003b010c20012002410c6a4102106220022003412c6a2f01003b010c20012002410c6a4102106220022003412e6a2f01003b010c20012002410c6a410210622002200341306a2f01003b010c20012002410c6a410210622002200341326a2f01003b010c20012002410c6a410210622002200341346a2f01003b010c20012002410c6a410210622002200341366a2f01003b010c20012002410c6a410210622002200341386a2f01003b010c20012002410c6a4102106220022003413a6a2f01003b010c20012002410c6a4102106220022003413c6a2f01003b010c20012002410c6a4102106220022003413e6a2f01003b010c20012002410c6a410210622002200341c0006a2f01003b010c20012002410c6a41021062200341c4006a22032000470d000b0b200241106a24000bd2ae0109097f017e067f037e217f027e0b7f017e047f23004190046b22022400200241f8006a20011088010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022802780d00200228027c220320012802044103762204200420034b1b22054103742204417f4c0d020240024020050d00410421060c010b200410212206450d040b41002104200241003602980320022005360294032002200636029003024002402003450d00410021040340200128020422054104490d0220012802002207280000210820012005417c6a22093602042001200741046a220736020020094102490d0220072f0000210920012005417a6a3602042001200741026a36020002402004200228029403470d0020024190036a2004410110a501200228029003210620022802980321040b200620044103746a220520093b0104200520083602002002200441016a2204360298032003417f6a22030d000b20022802940321050b2006450d01200241f0006a20011088012002280270450d020c180b20022802940341ffffffff0171450d00200610230b200041003602000c180b2002280274220a2001280204410c6e22072007200a4b1bad420c7e220b422088a70d00200ba72203417f4c0d000240024020030d004104210c0c010b20031021220c450d020b4100210720024100360298032002200c3602900320022003410c6e220d36029403024002400240200a450d00410021070340200128020422034104490d0220012802002209280000210e20012003417c6a220d3602042001200941046a2208360200200d4102490d0220082f0000210f20012003417a6a220d3602042001200841026a360200200d4102490d0220092f0006210d2001200341786a22083602042001200941086a220936020020084102490d0220092f000021082001200341766a3602042001200941026a36020002402007200228029403470d0020024190036a20074101109501200228029003210c20022802980321070b200c2007410c6c6a220320083b01082003200f3b01042003200e360200200341066a200d3b01002002200741016a220736029803200a417f6a220a0d000b200228029403210d0b200c450d17200241e8006a20011088012002280268450d010c160b2002280294032201450d162001410c6c450d16200c10230c160b4104210f200228026c220e200128020441047622032003200e4b1b22034104742209417f4c0d0002402003450d0020091021220f450d020b41002108200241003602980320022003360294032002200f36029003024002400240200e450d00410021080340200128020422034104490d0220012802002209280000211020012003417c6a22113602042001200941046a220a36020020114102490d02200a330000210b20012003417a6a22113602042001200a41026a36020020114102490d02200933000621122001200341786a22113602042001200941086a220a36020020114102490d02200a33000021132001200341766a22113602042001200a41026a36020020114102490d02200933000a21142001200341746a220a36020420012009410c6a2209360200200a4102490d0220092f0000210a2001200341726a3602042001200941026a3602002014423086201342208684201242108684200b84210b02402008200228029403470d0020024190036a2008410110a001200228029003210f20022802980321080b200f20084104746a2203200a3b010c2003200b370204200320103602002002200841016a220836029803200e417f6a220e0d000b20022802940321030b200f450d16200241e0006a20011088012002280260450d010c150b20022802940341ffffffff0071450d15200f10230c150b20022802642210200128020441146e2209200920104b1bad42147e220b422088a70d00200ba72209417f4c0d000240024020090d00410421150c010b200910212215450d020b4100210e200241003602980320022015360290032002200941146e2211360294030240024002402010450d004100210e0340200128020422094104490d022001280200220a280000211620012009417c6a22173602042001200a41046a221136020020174102490d0220112f0000211820012009417a6a22173602042001201141026a36020020174102490d02200a2f000621192001200941786a22173602042001200a41086a221136020020174102490d0220112f0000211a2001200941766a22173602042001201141026a36020020174102490d02200a2f000a211b2001200941746a22173602042001200a410c6a221136020020174102490d0220112f0000211c2001200941726a22173602042001201141026a36020020174102490d02200a2f000e21172001200941706a22113602042001200a41106a220a36020020114102490d02200a2f0000211120012009416e6a3602042001200a41026a3602000240200e200228029403470d0020024190036a200e4101109e012002280290032115200228029803210e0b2015200e41146c6a220920113b0110200920183b0104200920163602002009410e6a20173b01002009410c6a201c3b01002009410a6a201b3b0100200941086a201a3b0100200941066a20193b01002002200e41016a220e360298032010417f6a22100d000b20022802940321110b2015450d15200241d8006a20011088012002280258450d010c140b2002280294032201450d14200141146c450d14201510230c140b200228025c2217200128020441186e2209200920174b1bad42187e220b422088a70d00200ba72209417f4c0d000240024020090d00410421180c010b200910212218450d020b41002110200241003602980320022018360290032002200941186e2216360294030240024002402017450d00410021100340200128020422094104490d022001280200220a280000211a20012009417c6a22193602042001200a41046a221636020020194102490d0220162f0000211b20012009417a6a22193602042001201641026a36020020194102490d02200a2f0006211c2001200941786a22193602042001200a41086a221636020020194102490d0220162f0000211d2001200941766a22193602042001201641026a36020020194102490d02200a2f000a211e2001200941746a22193602042001200a410c6a221636020020194102490d0220162f0000211f2001200941726a22193602042001201641026a36020020194102490d02200a2f000e21202001200941706a22193602042001200a41106a221636020020194102490d0220162f0000212120012009416e6a22193602042001201641026a36020020194102490d02200a2f0012211920012009416c6a22163602042001200a41146a220a36020020164102490d02200a2f0000211620012009416a6a3602042001200a41026a36020002402010200228029403470d0020024190036a2010410110b001200228029003211820022802980321100b2018201041186c6a220920163b01142009201b3b01042009201a360200200941126a20193b0100200941106a20213b01002009410e6a20203b01002009410c6a201f3b01002009410a6a201e3b0100200941086a201d3b0100200941066a201c3b01002002201041016a2210360298032017417f6a22170d000b20022802940321160b2018450d14200241d0006a20011088012002280250450d010c130b2002280294032201450d13200141186c450d13201810230c130b200228025422192001280204411c6e2209200920194b1bad421c7e220b422088a70d00200ba72209417f4c0d000240024020090d004104211b0c010b20091021221b450d020b4100211720024100360298032002201b3602900320022009411c6e221a360294030240024002402019450d00410021170340200128020422094104490d022001280200220a280000211d20012009417c6a221c3602042001200a41046a221a360200201c4102490d02201a2f0000211e20012009417a6a221c3602042001201a41026a360200201c4102490d02200a2f0006211f2001200941786a221c3602042001200a41086a221a360200201c4102490d02201a2f000021202001200941766a221c3602042001201a41026a360200201c4102490d02200a2f000a21212001200941746a221c3602042001200a410c6a221a360200201c4102490d02201a2f000021222001200941726a221c3602042001201a41026a360200201c4102490d02200a2f000e21232001200941706a221c3602042001200a41106a221a360200201c4102490d02201a2f0000212420012009416e6a221c3602042001201a41026a360200201c4102490d02200a2f0012212520012009416c6a221c3602042001200a41146a221a360200201c4102490d02201a2f0000212620012009416a6a221c3602042001201a41026a360200201c4102490d02200a2f0016211c2001200941686a221a3602042001200a41186a220a360200201a4102490d02200a2f0000211a2001200941666a3602042001200a41026a36020002402017200228029403470d0020024190036a2017410110a301200228029003211b20022802980321170b201b2017411c6c6a2209201a3b01182009201e3b01042009201d360200200941166a201c3b0100200941146a20263b0100200941126a20253b0100200941106a20243b01002009410e6a20233b01002009410c6a20223b01002009410a6a20213b0100200941086a20203b0100200941066a201f3b01002002201741016a2217360298032019417f6a22190d000b200228029403211a0b201b450d13200241c8006a20011088012002280248450d010c120b2002280294032201450d122001411c6c450d12201b10230c120b200228024c221c200128020441057622092009201c4b1b2209410574220a417f4c0d000240024020090d004104211e0c010b200a1021221e450d020b41002119200241003602980320022009360294032002201e36029003024002400240201c450d00410021190340200128020422094104490d022001280200220a280000212020012009417c6a221f3602042001200a41046a221d360200201f4102490d02201d2f0000212120012009417a6a221f3602042001201d41026a360200201f4102490d02200a2f000621222001200941786a221f3602042001200a41086a221d360200201f4102490d02201d2f000021232001200941766a221f3602042001201d41026a360200201f4102490d02200a2f000a21242001200941746a221f3602042001200a410c6a221d360200201f4102490d02201d2f000021252001200941726a221f3602042001201d41026a360200201f4102490d02200a2f000e21262001200941706a221f3602042001200a41106a221d360200201f4102490d02201d2f0000212720012009416e6a221f3602042001201d41026a360200201f4102490d02200a2f0012212820012009416c6a221f3602042001200a41146a221d360200201f4102490d02201d2f0000212920012009416a6a221f3602042001201d41026a360200201f4102490d02200a2f0016212a2001200941686a221f3602042001200a41186a221d360200201f4102490d02201d2f0000212b2001200941666a221f3602042001201d41026a360200201f4102490d02200a2f001a211f2001200941646a221d3602042001200a411c6a220a360200201d4102490d02200a2f0000211d2001200941626a3602042001200a41026a36020002402019200228029403470d0020024190036a2019410110a801200228029003211e20022802980321190b201e20194105746a2209201d3b011c200920213b0104200920203602002009411a6a201f3b0100200941186a202b3b0100200941166a202a3b0100200941146a20293b0100200941126a20283b0100200941106a20273b01002009410e6a20263b01002009410c6a20253b01002009410a6a20243b0100200941086a20233b0100200941066a20223b01002002201941016a221936029803201c417f6a221c0d000b20022802940321090b201e450d12200241c0006a20011088012002280240450d010c110b20022802940341ffffff3f71450d11201e10230c110b2002280244221f200128020441246e220a200a201f4b1bad42247e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421210c010b200a10212221450d020b4100211d200241003602980320022021360290032002200a41246e222036029403024002400240201f450d004100211d03402001280204220a4104490d022001280200221c28000021232001200a417c6a22223602042001201c41046a222036020020224102490d0220202f000021242001200a417a6a22223602042001202041026a36020020224102490d02201c2f000621252001200a41786a22223602042001201c41086a222036020020224102490d0220202f000021262001200a41766a22223602042001202041026a36020020224102490d02201c2f000a21272001200a41746a22223602042001201c410c6a222036020020224102490d0220202f000021282001200a41726a22223602042001202041026a36020020224102490d02201c2f000e21292001200a41706a22223602042001201c41106a222036020020224102490d0220202f0000212a2001200a416e6a22223602042001202041026a36020020224102490d02201c2f0012212b2001200a416c6a22223602042001201c41146a222036020020224102490d0220202f0000212c2001200a416a6a22223602042001202041026a36020020224102490d02201c2f0016212d2001200a41686a22223602042001201c41186a222036020020224102490d0220202f0000212e2001200a41666a22223602042001202041026a36020020224102490d02201c2f001a212f2001200a41646a22223602042001201c411c6a222036020020224102490d0220202f000021302001200a41626a22223602042001202041026a36020020224102490d02201c2f001e21222001200a41606a22203602042001201c41206a221c36020020204102490d02201c2f000021202001200a415e6a3602042001201c41026a3602000240201d200228029403470d0020024190036a201d410110a2012002280290032121200228029803211d0b2021201d41246c6a220a20203b0120200a20243b0104200a2023360200200a411e6a20223b0100200a411c6a20303b0100200a411a6a202f3b0100200a41186a202e3b0100200a41166a202d3b0100200a41146a202c3b0100200a41126a202b3b0100200a41106a202a3b0100200a410e6a20293b0100200a410c6a20283b0100200a410a6a20273b0100200a41086a20263b0100200a41066a20253b01002002201d41016a221d36029803201f417f6a221f0d000b20022802940321200b2021450d11200241386a20011088012002280238450d010c100b2002280294032201450d10200141246c450d10202110230c100b200228023c2222200128020441286e220a200a20224b1bad42287e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421230c010b200a10212223450d020b4100211f200241003602980320022023360290032002200a41286e2224360294030240024002402022450d004100211f03402001280204220a4104490d022001280200221c28000021262001200a417c6a22253602042001201c41046a222436020020254102490d0220242f000021272001200a417a6a22253602042001202441026a36020020254102490d02201c2f000621282001200a41786a22253602042001201c41086a222436020020254102490d0220242f000021292001200a41766a22253602042001202441026a36020020254102490d02201c2f000a212a2001200a41746a22253602042001201c410c6a222436020020254102490d0220242f0000212b2001200a41726a22253602042001202441026a36020020254102490d02201c2f000e212c2001200a41706a22253602042001201c41106a222436020020254102490d0220242f0000212d2001200a416e6a22253602042001202441026a36020020254102490d02201c2f0012212e2001200a416c6a22253602042001201c41146a222436020020254102490d0220242f0000212f2001200a416a6a22253602042001202441026a36020020254102490d02201c2f001621302001200a41686a22253602042001201c41186a222436020020254102490d0220242f000021312001200a41666a22253602042001202441026a36020020254102490d02201c2f001a21322001200a41646a22253602042001201c411c6a222436020020254102490d0220242f000021332001200a41626a22253602042001202441026a36020020254102490d02201c2f001e21342001200a41606a22253602042001201c41206a222436020020254102490d0220242f000021352001200a415e6a22253602042001202441026a36020020254102490d02201c2f002221252001200a415c6a22243602042001201c41246a221c36020020244102490d02201c2f000021242001200a415a6a3602042001201c41026a3602000240201f200228029403470d0020024190036a201f410110aa012002280290032123200228029803211f0b2023201f41286c6a220a20243b0124200a20273b0104200a2026360200200a41226a20253b0100200a41206a20353b0100200a411e6a20343b0100200a411c6a20333b0100200a411a6a20323b0100200a41186a20313b0100200a41166a20303b0100200a41146a202f3b0100200a41126a202e3b0100200a41106a202d3b0100200a410e6a202c3b0100200a410c6a202b3b0100200a410a6a202a3b0100200a41086a20293b0100200a41066a20283b01002002201f41016a221f360298032022417f6a22220d000b20022802940321240b2023450d10200241306a20011088012002280230450d010c0f0b2002280294032201450d0f200141286c450d0f202310230c0f0b200228023422252001280204412c6e220a200a20254b1bad422c7e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421260c010b200a10212226450d020b41002122200241003602880120022026360280012002200a412c6e22273602840102402025450d004100212203402001280204220a4104490d0e2001280200221c280000212b2001200a417c6a22283602042001201c41046a2227360200200241003a00b403200241003b01d00320284102490d0e20272f000021292001200a417a6a22283602042001202741026a360200200241003b01d00320284102490d0e201c2f000621282001200a41786a222a3602042001201c41086a2227360200200220293b019003200241013a00b403200220283b019203200241003b01d003202a4102490d0d20272f000021292001200a41766a22283602042001202741026a360200200241003b01d003202841014d0d0d201c2f000a21282001200a41746a222a3602042001201c410c6a2227360200200220293b019403200220283b019603200241023a00b403200241003b01d003202a4102490d0d20272f000021292001200a41726a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f000e21282001200a41706a222a3602042001201c41106a2227360200200220293b019803200241033a00b403200220283b019a03200241003b01d003202a4102490d0d20272f000021292001200a416e6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001221282001200a416c6a222a3602042001201c41146a2227360200200220293b019c03200241043a00b403200220283b019e03200241003b01d003202a4102490d0d20272f000021292001200a416a6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001621282001200a41686a222a3602042001201c41186a2227360200200220293b01a003200241053a00b403200220283b01a203200241003b01d003202a4102490d0d20272f000021292001200a41666a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001a21282001200a41646a222a3602042001201c411c6a2227360200200220293b01a403200241063a00b403200220283b01a603200241003b01d003202a4102490d0d20272f000021292001200a41626a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001e21282001200a41606a222a3602042001201c41206a2227360200200220293b01a803200241073a00b403200220283b01aa03200241003b01d003202a4102490d0d20272f000021292001200a415e6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f002221282001200a415c6a222a3602042001201c41246a2227360200200220293b01ac03200241083a00b403200220283b01ae03200241003b01d003202a4102490d0d20272f000021292001200a415a6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f002621272001200a41586a22283602042001201c41286a221c360200200220293b01b003200241093a00b403200220273b01b203200241d0036a41206a20022802b0032227360200200241d0036a41186a20024190036a41186a290300220b370300200241d0036a41106a20024190036a41106a2903002212370300200241d0036a41086a20024190036a41086a2903002213370300200220022903900322143703d003200241d0026a41206a22292027360200200241d0026a41186a2227200b370300200241d0026a41106a222a2012370300200241d0026a41086a222c2013370300200220143703d00220284102490d0e201c2f000021282001200a41566a3602042001201c41026a36020020024190026a41106a202a290300220b370300200241d0016a41086a202c2903002212370300200241d0016a41106a200b370300200241d0016a41186a20272903002213370300200241d0016a41206a2029280200220a360200200220022903d00222143703d00120024190016a41206a221c200a36020020024190016a41186a2227201337030020024190016a41106a2229200b37030020024190016a41086a222a2012370300200220143703900102402022200228028401470d0020024180016a2022410110a601200228028001212620022802880121220b20262022412c6c6a220a202b360200200a200229039001370204201c280200211c2027290300210b20292903002112202a2903002113200a20283b0128200a410c6a2013370200200a41146a2012370200200a411c6a200b370200200a41246a201c3602002002202241016a2222360288012025417f6a22250d000b20022802840121270b2026450d0d200241286a200110880120022802280d0a200228022c2228200128020441306e220a200a20284b1bad42307e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421290c010b200a10212229450d020b41002125200241003602880120022029360280012002200a41306e222a3602840102402028450d004100212503402001280204220a4104490d0b2001280200221c280000212e2001200a417c6a222b3602042001201c41046a222a360200200241003a00b803200241003b01d003202b4102490d0b202a2f0000212c2001200a417a6a222b3602042001202a41026a360200200241003b01d003202b4102490d0b201c2f0006212b2001200a41786a222d3602042001201c41086a222a3602002002202c3b019003200241013a00b8032002202b3b019203200241003b01d003202d4102490d0a202a2f0000212c2001200a41766a222b3602042001202a41026a360200200241003b01d003202b41014d0d0a201c2f000a212b2001200a41746a222d3602042001201c410c6a222a3602002002202c3b0194032002202b3b019603200241023a00b803200241003b01d003202d4102490d0a202a2f0000212c2001200a41726a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f000e212b2001200a41706a222d3602042001201c41106a222a3602002002202c3b019803200241033a00b8032002202b3b019a03200241003b01d003202d4102490d0a202a2f0000212c2001200a416e6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0012212b2001200a416c6a222d3602042001201c41146a222a3602002002202c3b019c03200241043a00b8032002202b3b019e03200241003b01d003202d4102490d0a202a2f0000212c2001200a416a6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0016212b2001200a41686a222d3602042001201c41186a222a3602002002202c3b01a003200241053a00b8032002202b3b01a203200241003b01d003202d4102490d0a202a2f0000212c2001200a41666a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f001a212b2001200a41646a222d3602042001201c411c6a222a3602002002202c3b01a403200241063a00b8032002202b3b01a603200241003b01d003202d4102490d0a202a2f0000212c2001200a41626a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f001e212b2001200a41606a222d3602042001201c41206a222a3602002002202c3b01a803200241073a00b8032002202b3b01aa03200241003b01d003202d4102490d0a202a2f0000212c2001200a415e6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0022212b2001200a415c6a222d3602042001201c41246a222a3602002002202c3b01ac03200241083a00b8032002202b3b01ae03200241003b01d003202d4102490d0a202a2f0000212c2001200a415a6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0026212b2001200a41586a222d3602042001201c41286a222a3602002002202c3b01b003200241093a00b8032002202b3b01b203200241003b01d003202d4102490d0a202a2f0000212c2001200a41566a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f002a212a2001200a41546a222b3602042001201c412c6a221c3602002002202c3b01b4032002410a3a00b8032002202a3b01b603200241d0036a41206a20024190036a41206a290300220b370300200241d0036a41186a20024190036a41186a2903002212370300200241d0036a41106a20024190036a41106a2903002213370300200241d0036a41086a20024190036a41086a2903002214370300200220022903900322363703d003200241d0026a41206a222a200b370300200241d0026a41186a222c2012370300200241d0026a41106a222d2013370300200241d0026a41086a222f2014370300200220363703d002202b4102490d0b201c2f0000212b2001200a41526a3602042001201c41026a36020020024190026a41106a202d290300220b370300200241d0016a41086a202f2903002212370300200241d0016a41106a200b370300200241d0016a41186a202c2903002213370300200241d0016a41206a202a2903002214370300200220022903d00222363703d00120024190016a41206a221c201437030020024190016a41186a222a201337030020024190016a41106a222c200b37030020024190016a41086a222d2012370300200220363703900102402025200228028401470d0020024180016a2025410110b601200228028001212920022802880121250b2029202541306c6a220a202e360200200a200229039001370204201c290300210b202a2903002112202c2903002113202d2903002114200a202b3b012c200a410c6a2014370200200a41146a2013370200200a411c6a2012370200200a41246a200b3702002002202541016a2225360288012028417f6a22280d000b200228028401212a0b2029450d0a200241206a200110880120022802200d072002280224222b200128020441346e220a200a202b4b1bad42347e220b422088a70d00200ba7220a417f4c0d0002400240200a0d004104212c0c010b200a1021222c450d020b4100212820024100360288012002202c360280012002200a41346e222d360284010240202b450d004100212803402001280204220a4104490d082001280200221c28000021312001200a417c6a222e3602042001201c41046a222d360200200241003a00bc03200241003b01d003202e4102490d08202d2f0000212f2001200a417a6a222e3602042001202d41026a360200200241003b01d003202e4102490d08201c2f0006212e2001200a41786a22303602042001201c41086a222d3602002002202f3b019003200241013a00bc032002202e3b019203200241003b01d00320304102490d07202d2f0000212f2001200a41766a222e3602042001202d41026a360200200241003b01d003202e41014d0d07201c2f000a212e2001200a41746a22303602042001201c410c6a222d3602002002202f3b0194032002202e3b019603200241023a00bc03200241003b01d00320304102490d07202d2f0000212f2001200a41726a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f000e212e2001200a41706a22303602042001201c41106a222d3602002002202f3b019803200241033a00bc032002202e3b019a03200241003b01d00320304102490d07202d2f0000212f2001200a416e6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0012212e2001200a416c6a22303602042001201c41146a222d3602002002202f3b019c03200241043a00bc032002202e3b019e03200241003b01d00320304102490d07202d2f0000212f2001200a416a6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0016212e2001200a41686a22303602042001201c41186a222d3602002002202f3b01a003200241053a00bc032002202e3b01a203200241003b01d00320304102490d07202d2f0000212f2001200a41666a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f001a212e2001200a41646a22303602042001201c411c6a222d3602002002202f3b01a403200241063a00bc032002202e3b01a603200241003b01d00320304102490d07202d2f0000212f2001200a41626a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f001e212e2001200a41606a22303602042001201c41206a222d3602002002202f3b01a803200241073a00bc032002202e3b01aa03200241003b01d00320304102490d07202d2f0000212f2001200a415e6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0022212e2001200a415c6a22303602042001201c41246a222d3602002002202f3b01ac03200241083a00bc032002202e3b01ae03200241003b01d00320304102490d07202d2f0000212f2001200a415a6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0026212e2001200a41586a22303602042001201c41286a222d3602002002202f3b01b003200241093a00bc032002202e3b01b203200241003b01d00320304102490d07202d2f0000212f2001200a41566a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f002a212e2001200a41546a22303602042001201c412c6a222d3602002002202f3b01b4032002410a3a00bc032002202e3b01b603200241003b01d00320304102490d07202d2f0000212f2001200a41526a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f002e212d2001200a41506a222e3602042001201c41306a221c3602002002202f3b01b8032002410b3a00bc032002202d3b01ba03200241d0036a41286a20022802b803222d360200200241d0036a41206a20024190036a41206a290300220b370300200241d0036a41186a20024190036a41186a2903002212370300200241d0036a41106a20024190036a41106a2903002213370300200241d0036a41086a20024190036a41086a2903002214370300200220022903900322363703d003200241d0026a41286a222f202d360200200241d0026a41206a222d200b370300200241d0026a41186a22302012370300200241d0026a41106a22322013370300200241d0026a41086a22332014370300200220363703d002202e4102490d08201c2f0000212e2001200a414e6a3602042001201c41026a36020020024190026a41106a2032290300220b37030020024190026a41186a20302903002212370300200241d0016a41086a220a2033290300370300200241d0016a41106a221c200b370300200241d0016a41186a22302012370300200241d0016a41206a2232202d290300370300200241d0016a41286a222d202f280200360200200220022903d0023703d00120024190016a41286a222f202d28020036020020024190016a41206a222d203229030037030020024190016a41186a2232203029030037030020024190016a41106a2230201c29030037030020024190016a41086a221c200a290300370300200220022903d0013703900102402028200228028401470d0020024180016a2028410110a701200228028001212c20022802880121280b202c202841346c6a220a2031360200200a200229039001370204202f280200212f202d290300210b2032290300211220302903002113201c2903002114200a202e3b0130200a410c6a2014370200200a41146a2013370200200a411c6a2012370200200a41246a200b370200200a412c6a202f3602002002202841016a222836028801202b417f6a222b0d000b200228028401212d0b202c450d07200241186a200110880120022802180d04200228021c222e200128020441386e220a200a202e4b1bad42387e220b422088a70d00200ba7220a417f4c0d0002400240200a0d004104212f0c010b200a1021222f450d020b4100212b20024100360288012002202f360280012002200a41386e2234360284010240202e450d004100212b03402001280204220a4104490d052001280200221c28000021342001200a417c6a22313602042001201c41046a2230360200200241003a00c003200241003b01d00320314102490d0520302f000021322001200a417a6a22313602042001203041026a360200200241003b01d00320314102490d05201c2f000621312001200a41786a22333602042001201c41086a2230360200200220323b019003200241013a00c003200220313b019203200241003b01d00320334102490d0420302f000021322001200a41766a22313602042001203041026a360200200241003b01d003203141014d0d04201c2f000a21312001200a41746a22333602042001201c410c6a2230360200200220323b019403200220313b019603200241023a00c003200241003b01d00320334102490d0420302f000021322001200a41726a22313602042001203041026a360200200241003b01d00320314102490d04201c2f000e21312001200a41706a22333602042001201c41106a2230360200200220323b019803200241033a00c003200220313b019a03200241003b01d00320334102490d0420302f000021322001200a416e6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001221312001200a416c6a22333602042001201c41146a2230360200200220323b019c03200241043a00c003200220313b019e03200241003b01d00320334102490d0420302f000021322001200a416a6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001621312001200a41686a22333602042001201c41186a2230360200200220323b01a003200241053a00c003200220313b01a203200241003b01d00320334102490d0420302f000021322001200a41666a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001a21312001200a41646a22333602042001201c411c6a2230360200200220323b01a403200241063a00c003200220313b01a603200241003b01d00320334102490d0420302f000021322001200a41626a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001e21312001200a41606a22333602042001201c41206a2230360200200220323b01a803200241073a00c003200220313b01aa03200241003b01d00320334102490d0420302f000021322001200a415e6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002221312001200a415c6a22333602042001201c41246a2230360200200220323b01ac03200241083a00c003200220313b01ae03200241003b01d00320334102490d0420302f000021322001200a415a6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002621312001200a41586a22333602042001201c41286a2230360200200220323b01b003200241093a00c003200220313b01b203200241003b01d00320334102490d0420302f000021322001200a41566a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002a21312001200a41546a22333602042001201c412c6a2230360200200220323b01b4032002410a3a00c003200220313b01b603200241003b01d00320334102490d0420302f000021322001200a41526a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002e21312001200a41506a22333602042001201c41306a2230360200200220323b01b8032002410b3a00c003200220313b01ba03200241003b01d00320334102490d0420302f000021322001200a414e6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f003221302001200a414c6a22313602042001201c41346a221c360200200220323b01bc032002410c3a00c003200220303b01be03200241d0036a41286a20024190036a41286a290300220b370300200241d0036a41206a20024190036a41206a2903002212370300200241d0036a41186a20024190036a41186a2903002213370300200241d0036a41106a20024190036a41106a2903002214370300200241d0036a41086a20024190036a41086a2903002236370300200220022903900322373703d003200241d0026a41286a2230200b370300200241d0026a41206a22322012370300200241d0026a41186a22332013370300200241d0026a41106a22352014370300200241d0026a41086a22382036370300200220373703d00220314102490d05201c2f000021312001200a414a6a3602042001201c41026a36020020024190026a41106a2035290300220b37030020024190026a41186a20332903002212370300200241d0016a41086a220a2038290300370300200241d0016a41106a221c200b370300200241d0016a41186a22332012370300200241d0016a41206a22352032290300370300200241d0016a41286a22322030290300370300200220022903d0023703d00120024190016a41286a2230203229030037030020024190016a41206a2232203529030037030020024190016a41186a2235203329030037030020024190016a41106a2233201c29030037030020024190016a41086a221c200a290300370300200220022903d001370390010240202b200228028401470d0020024180016a202b410110ae01200228028001212f200228028801212b0b202f202b41386c6a220a2034360200200a2002290390013702042030290300210b203229030021122035290300211320332903002114201c2903002136200a20313b0134200a410c6a2036370200200a41146a2014370200200a411c6a2013370200200a41246a2012370200200a412c6a200b3702002002202b41016a222b36028801202e417f6a222e0d000b20022802840121340b202f450d04200241106a2001108801024002400240024002400240024020022802100d00200228021422392001280204413c6e220a200a20394b1bad423c7e220b422088a70d07200ba7220a417f4c0d0702400240200a0d004104213a0c010b200a1021223a450d090b4100213b20024100360288012002203a360280012002200a413c6e2235360284010240024002402039450d004100213b4100213c0340200128020422354104490d03203c41016a213c417c211c20012802002238280000213d20012035417c6a3602042001203841046a3602004100210a200241003a00c403410021310340200241003b01d0032035201c6a222e4102490d032038200a6a223041046a2f000021322001202e417e6a222e3602042001203041066a2230360200200241003b01d003202e4102490d0320024190036a200a6a223320323b0100203341026a20302f00003b01002001202e417e6a3602042001203041026a3602002002203141016a22313a00c403201c417c6a211c200a41046a220a4134470d000b200241d0036a41306a222e20024190036a41306a280200360200200241d0036a41286a223020024190036a41286a290300370300200241d0036a41206a223220024190036a41206a290300370300200241d0036a41186a223320024190036a41186a290300370300200241d0036a41106a223e20024190036a41106a290300370300200241d0036a41086a223f20024190036a41086a29030037030020022002290390033703d003203141ff0171410d490d03200241d0026a41306a2231202e280200360200200241d0026a41286a222e2030290300370300200241d0026a41206a22302032290300370300200241d0026a41186a22322033290300370300200241d0026a41106a2233203e290300370300200241d0026a41086a223e203f290300370300200220022903d0033703d0022035201c6a41014d0d032038200a6a221c41046a2f0000213820012035200a6b417a6a3602042001201c41066a36020020024190026a41086a203e290300220b37030020024190026a41106a2033290300221237030020024190026a41186a2032290300221337030020024190026a41206a2030290300221437030020024190026a41286a202e290300223637030020024190026a41306a2031280200220a360200200220022903d002223737039002200241d0016a41306a221c200a360200200241d0016a41286a220a2036370300200241d0016a41206a222e2014370300200241d0016a41186a22302013370300200241d0016a41106a22312012370300200241d0016a41086a2232200b370300200220373703d00120024190016a41306a2233201c28020036020020024190016a41286a221c200a29030037030020024190016a41206a2235202e29030037030020024190016a41186a222e203029030037030020024190016a41106a2230203129030037030020024190016a41086a22312032290300370300200220022903d001370390010240203b200228028401470d0020024180016a203b410110b701200228028001213a200228028801213b0b203a203b413c6c6a220a203d360200200a20022903900137020420332802002132201c290300210b20352903002112202e29030021132030290300211420312903002136200a20383b0138200a410c6a2036370200200a41146a2014370200200a411c6a2013370200200a41246a2012370200200a412c6a200b370200200a41346a20323602002002203b41016a223b36028801203c2039470d000b20022802840121350b203a450d02200241086a200110880120022802080d05200228020c223d2001280204410676220a200a203d4b1b221c410674220a417f4c0d09201c0d034104213c0c040b203141ff0171450d00200241003a00c4030b200241d0016a41306a20024190026a41306a280200360200200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d002001413c6c450d00203a10230b2000410036020002402034450d00203441386c450d00202f10230b0240202d450d00202d41346c450d00202c10230b0240202a450d00202a41306c450d00202910230b02402027450d002027412c6c450d00202610230b02402024450d00202441286c450d00202310230b02402020450d00202041246c450d00202110230b0240200941ffffff3f71450d00201e10230b0240201a450d00201a411c6c450d00201b10230b02402016450d00201641186c450d00201810230b02402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d1c0c1d0b200a1021223c450d060b4100213e20024100360288012002201c360284012002203c36028001024002400240203d450d004100213e4100213f0340200128020422384104490d03203f41016a213f417c211c20012802002239280000214020012038417c6a3602042001203941046a3602004100210a200241003a00c803410021310340200241003b01d0032038201c6a222e4102490d032039200a6a223041046a2f000021322001202e417e6a222e3602042001203041066a2230360200200241003b01d003202e4102490d0320024190036a200a6a223320323b0100203341026a20302f00003b01002001202e417e6a3602042001203041026a3602002002203141016a22313a00c803201c417c6a211c200a41046a220a4138470d000b200241d0036a41306a222e20024190036a41306a290300370300200241d0036a41286a223020024190036a41286a290300370300200241d0036a41206a223220024190036a41206a290300370300200241d0036a41186a223320024190036a41186a290300370300200241d0036a41106a224120024190036a41106a290300370300200241d0036a41086a224220024190036a41086a29030037030020022002290390033703d003203141ff0171410e490d03200241d0026a41306a2231202e290300370300200241d0026a41286a222e2030290300370300200241d0026a41206a22302032290300370300200241d0026a41186a22322033290300370300200241d0026a41106a22332041290300370300200241d0026a41086a22412042290300370300200220022903d0033703d0022038201c6a41014d0d032039200a6a221c41046a2f0000213920012038200a6b417a6a3602042001201c41066a36020020024190026a41086a2041290300220b37030020024190026a41106a2033290300221237030020024190026a41186a2032290300221337030020024190026a41206a2030290300221437030020024190026a41286a202e290300223637030020024190026a41306a20312903002237370300200220022903d002224337039002200241d0016a41306a220a2037370300200241d0016a41286a221c2036370300200241d0016a41206a222e2014370300200241d0016a41186a22302013370300200241d0016a41106a22312012370300200241d0016a41086a2232200b370300200220433703d00120024190016a41306a2233200a29030037030020024190016a41286a2238201c29030037030020024190016a41206a221c202e29030037030020024190016a41186a222e203029030037030020024190016a41106a2230203129030037030020024190016a41086a22312032290300370300200220022903d001370390010240203e200228028401470d0020024180016a203e410110b301200228028001213c200228028801213e0b203c203e4106746a220a2040360200200a2002290390013702042033290300210b20382903002112201c2903002113202e29030021142030290300213620312903002137200a20393b013c200a410c6a2037370200200a41146a2036370200200a411c6a2014370200200a41246a2013370200200a412c6a2012370200200a41346a200b3702002002203e41016a223e36028801203f203d470d000b200228028401211c0b203c450d022002200110880120022802000d0520022802042240200128020441c4006e220a200a20404b1bad42c4007e220b422088a70d06200ba7220a417f4c0d06200a0d034104213f0c040b203141ff0171450d00200241003a00c8030b200241d0016a41306a20024190026a41306a290300370300200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a29030037030020022802840141ffffff1f71450d00203c10230b2000410036020002402035450d002035413c6c450d00203a10230b02402034450d00203441386c450d00202f10230b0240202d450d00202d41346c450d00202c10230b0240202a450d00202a41306c450d00202910230b02402027450d002027412c6c450d00202610230b02402024450d00202441286c450d00202310230b02402020450d00202041246c450d00202110230b0240200941ffffff3f71450d00201e10230b0240201a450d00201a411c6c450d00201b10230b02402016450d00201641186c450d00201810230b02402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d190c1a0b200a1021223f450d030b20024100360288012002203f360280012002200a41c4006e360284010240024002402040450d0041002142410021410340200128020422394104490d03204141016a2141417c212e2001280200223d280000214420012039417c6a3602042001203d41046a3602004100210a200241003a00cc03410021320340200241003b01d0032039202e6a22304102490d03203d200a6a223141046a2f0000213320012030417e6a22303602042001203141066a2231360200200241003b01d00320304102490d0320024190036a200a6a223820333b0100203841026a20312f00003b010020012030417e6a3602042001203141026a3602002002203241016a22323a00cc03202e417c6a212e200a41046a220a413c470d000b200241d0036a41386a223020024190036a41386a280200360200200241d0036a41306a223120024190036a41306a290300370300200241d0036a41286a223320024190036a41286a290300370300200241d0036a41206a223820024190036a41206a290300370300200241d0036a41186a224520024190036a41186a290300370300200241d0036a41106a224620024190036a41106a290300370300200241d0036a41086a224720024190036a41086a29030037030020022002290390033703d003203241ff0171410f490d03200241d0026a41386a22322030280200360200200241d0026a41306a22302031290300370300200241d0026a41286a22312033290300370300200241d0026a41206a22332038290300370300200241d0026a41186a22382045290300370300200241d0026a41106a22452046290300370300200241d0026a41086a22462047290300370300200220022903d0033703d0022039202e6a41014d0d03203d200a6a222e41046a2f0000213d20012039200a6b417a6a3602042001202e41066a36020020024190026a41086a220a204629030037030020024190026a41106a222e204529030037030020024190026a41186a2239203829030037030020024190026a41206a2238203329030037030020024190026a41286a2233203129030037030020024190026a41306a2231203029030037030020024190026a41386a22302032280200360200200220022903d00237039002200241d0016a41086a200a290300220b370300200241d0016a41106a202e2903002212370300200241d0016a41186a20392903002213370300200241d0016a41206a20382903002214370300200241d0016a41286a20332903002236370300200241d0016a41306a20312903002237370300200241d0016a41386a2030280200220a36020020024190016a41086a222e200b37030020024190016a41106a2230201237030020024190016a41186a2231201337030020024190016a41206a2232201437030020024190016a41286a2233203637030020024190016a41306a2238203737030020024190016a41386a2239200a3602002002200229039002220b3703d0012002200b3703900102402042200228028401470d0020024180016a20424101109b01200228028001213f20022802880121420b203f204241c4006c6a220a2044360200200a200229039001370204203928020021392038290300210b20332903002112203229030021132031290300211420302903002136202e2903002137200a203d3b0140200a410c6a2037370200200a41146a2036370200200a411c6a2014370200200a41246a2013370200200a412c6a2012370200200a41346a200b370200200a413c6a20393602002002204241016a22423602880120412040470d000b0b203f450d02200229028401210b2000200536020420002006360200200041b8016a200b370200200041b4016a203f360200200041b0016a203e360200200041ac016a201c360200200041a8016a203c360200200041a4016a203b360200200041a0016a20353602002000419c016a203a36020020004198016a202b36020020004194016a203436020020004190016a202f3602002000418c016a202836020020004188016a202d36020020004184016a202c36020020004180016a2025360200200041fc006a202a360200200041f8006a2029360200200041f4006a2022360200200041f0006a2027360200200041ec006a2026360200200041e8006a201f360200200041e4006a2024360200200041e0006a2023360200200041dc006a201d360200200041d8006a2020360200200041d4006a2021360200200041d0006a2019360200200041cc006a2009360200200041c8006a201e360200200041c4006a2017360200200041c0006a201a3602002000413c6a201b360200200041386a2010360200200041346a2016360200200041306a20183602002000412c6a200e360200200041286a2011360200200041246a2015360200200041206a20083602002000411c6a2003360200200041186a200f360200200041146a2007360200200041106a200d3602002000410c6a200c360200200041086a20043602000c1a0b203241ff0171450d00200241003a00cc030b200241d0016a41386a20024190026a41386a280200360200200241d0016a41306a20024190026a41306a290300370300200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141c4006c450d00203f10230b200041003602000240201c41ffffff1f71450d00203c10230b02402035450d002035413c6c450d00203a10230b02402034450d00203441386c450d00202f10230b0240202d450d00202d41346c450d00202c10230b0240202a450d00202a41306c450d00202910230b02402027450d002027412c6c450d00202610230b02402024450d00202441286c450d00202310230b02402020450d00202041246c450d00202110230b0240200941ffffff3f71450d00201e10230b0240201a450d00201a411c6c450d00201b10230b02402016450d00201641186c450d00201810230b02402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff0171450d170c160b1032000b1033000b200241003a00c0030b200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141386c450d00202f10230b200041003602000240202d450d00202d41346c450d00202c10230b0240202a450d00202a41306c450d00202910230b02402027450d002027412c6c450d00202610230b02402024450d00202441286c450d00202310230b02402020450d00202041246c450d00202110230b0240200941ffffff3f71450d00201e10230b0240201a450d00201a411c6c450d00201b10230b02402016450d00201641186c450d00201810230b02402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d110c120b200241003a00bc030b200241d0016a41286a20024190026a41286a280200360200200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141346c450d00202c10230b200041003602000240202a450d00202a41306c450d00202910230b02402027450d002027412c6c450d00202610230b02402024450d00202441286c450d00202310230b02402020450d00202041246c450d00202110230b0240200941ffffff3f71450d00201e10230b0240201a450d00201a411c6c450d00201b10230b02402016450d00201641186c450d00201810230b02402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d0e0c0f0b200241003a00b8030b200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141306c450d00202910230b2000410036020002402027450d002027412c6c450d00202610230b02402024450d00202441286c450d00202310230b02402020450d00202041246c450d00202110230b0240200941ffffff3f71450d00201e10230b0240201a450d00201a411c6c450d00201b10230b02402016450d00201641186c450d00201810230b02402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d0b0c0c0b200241003a00b4030b200241d0016a41206a20024190026a41206a280200360200200241d0016a41186a20024190026a41186a2903003703002002280284012201450d002001412c6c450d00202610230b2000410036020002402024450d00202441286c450d00202310230b02402020450d00202041246c450d00202110230b0240200941ffffff3f71450d00201e10230b0240201a450d00201a411c6c450d00201b10230b02402016450d00201641186c450d00201810230b02402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d080c090b2000410036020002402020450d00202041246c450d00202110230b0240200941ffffff3f71450d00201e10230b0240201a450d00201a411c6c450d00201b10230b02402016450d00201641186c450d00201810230b02402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d070c080b200041003602000240200941ffffff3f71450d00201e10230b0240201a450d00201a411c6c450d00201b10230b02402016450d00201641186c450d00201810230b02402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d060c070b200041003602000240201a450d00201a411c6c450d00201b10230b02402016450d00201641186c450d00201810230b02402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d050c060b2000410036020002402016450d00201641186c450d00201810230b02402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d040c050b2000410036020002402011450d00201141146c450d00201510230b0240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d030c040b200041003602000240200341ffffffff0071450d00200f10230b0240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d020c030b200041003602000240200d450d00200d410c6c450d00200c10230b200541ffffffff01710d010c020b20004100360200200541ffffffff0171450d010b200610230b20024190046a24000bf70301017f0240200041046a28020041ffffffff0171450d00200028020010230b0240200041106a2802002201450d002001410c6c450d00200028020c10230b02402000411c6a28020041ffffffff0071450d00200028021810230b0240200041286a2802002201450d00200141146c450d00200028022410230b0240200041346a2802002201450d00200141186c450d00200028023010230b0240200041c0006a2802002201450d002001411c6c450d00200028023c10230b0240200041cc006a28020041ffffff3f71450d00200028024810230b0240200041d8006a2802002201450d00200141246c450d00200028025410230b0240200041e4006a2802002201450d00200141286c450d00200028026010230b0240200041f0006a2802002201450d002001412c6c450d00200028026c10230b0240200041fc006a2802002201450d00200141306c450d00200028027810230b024020004188016a2802002201450d00200141346c450d0020002802840110230b024020004194016a2802002201450d00200141386c450d0020002802900110230b0240200041a0016a2802002201450d002001413c6c450d00200028029c0110230b0240200041ac016a28020041ffffff1f71450d0020002802a80110230b0240200041b8016a2802002201450d00200141c4006c450d0020002802b40110230b0be49301032a7f047e247f23004180026b22042400200441b8016a4200370300200441b0016a22054280808080c000370300200441a0016a420037030020044198016a22064280808080c00037030020044188016a420037030020044180016a22074280808080c000370300200441f0006a4200370300200441e8006a22084280808080c000370300200441d8006a4200370300200441d0006a22094280808080c000370300200441c0006a4200370300200441386a220a4280808080c000370300200441286a4200370300200441206a220b4280808080c000370300200441106a4200370300200442043703a8012004420437039001200442043703782004420437036020044204370348200442043703302004420437031820044280808080c000370308200442043703002001280200220c2001280208220d412c6c220e6a210f20012802042110200c2101024002400240200d450d00200441bc016a2111200441b4016a2112200441a8016a2113200441a4016a21142004419c016a211520044190016a21162004418c016a211720044184016a2118200441f8006a2119200441f4006a211a200441ec006a211b200441e0006a211c200441dc006a211d200441d4006a211e200441c8006a211f200441c4006a21202004413c6a2121200441306a21222004412c6a2123200441246a2124200441186a2125200441146a21262004410c6a2127200441086a2128200e41546a210d200441e0016a41086a2129200441e0016a41106a212a200441e0016a41186a212b200c210e0340200e280208212c200e280204212d2029200e41146a290200370300202a200e411c6a290200370300202b200e41246a2902003703002004200e29020c3703e001200e412c6a2101200e280200220e450d01200441c0016a41186a202b290300222e370300200441c0016a41106a202a290300222f370300200441c0016a41086a20292903002230370300200420042903e00122313703c001202b202e370300202a202f37030020292030370300200420313703e001024002400240202c41104d0d00410121320c010b024002400240024002400240024002400240024002400240024002400240024002400240202c0e11000102030405060708090a0b0c0d0e0f10000b0240202d450d00202d41226c450d00200e10230b2001200f460d150c120b4102213220022802082233450d102002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a22340d000c120b0b20032802082234450d102003280200212c203441057421354100213402400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a22350d000c120b0b2034418080044f0d1002402004280208222c2004280204470d002004202c410110a5012004280208212c0b2004280200202c4103746a222c20343b0104202c20333602002028212c0c0f0b4102213220022802082233450d0f2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a22340d000c110b0b2003280208222c450d0f41002135202c4105742237213620032802002234212c02400340200e202c460d012035202c200e412010a30522384100476a21352038450d01202c41206a212c203641606a22360d000c110b0b203541ffff034b0d0f200e41226a2136200e2f012021394100212c0240034020362034460d01202c20342036412010a30522384100476a212c2038450d01203441206a2134203741606a22370d000c110b0b202c41ffff034b0d0f0240200428021422322004280210470d00202720324101109501200428021421320b200428020c2032410c6c6a2232202c3b0108203220353b010420322033360200203241066a20393b01002026212c0c0e0b4102213220022802082233450d0e2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a22340d000c100b0b2003280208222c450d0e41002134202c410574223a213520032802002238212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a22350d000c100b0b203441ffff034b0d0e200e41226a2136200e2f0120213b41002135203a21372038212c024003402036202c460d012035202c2036412010a30522394100476a21352039450d01202c41206a212c203741606a22370d000c100b0b203541ffff034b0d0e200e41c4006a2136200e41c2006a2f010021394100212c0240034020362038460d01202c20382036412010a30522374100476a212c2037450d01203841206a2138203a41606a223a0d000c100b0b202c41ffff034b0d0e024020042802202232200428021c470d0020252032410110a001200428022021320b200428021820324104746a2232202c3b010c203220343b0104203220333602002032410a6a20393b0100203241086a20353b0100203241066a203b3b0100200b212c0c0d0b4102213220022802082233450d0d2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a22340d000c0f0b0b2003280208222c450d0d41002134202c410574223b213520032802002237212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a22350d000c0f0b0b203441ffff034b0d0d200e41226a2136200e2f0120213c41002135203b21382037212c024003402036202c460d012035202c2036412010a30522394100476a21352039450d01202c41206a212c203841606a22380d000c0f0b0b203541ffff034b0d0d200e41c4006a2138200e41c2006a2f0100213d41002136203b21392037212c024003402038202c460d012036202c2038412010a305223a4100476a2136203a450d01202c41206a212c203941606a22390d000c0f0b0b203641ffff034b0d0d200e41e6006a2138200e41e4006a2f0100213a4100212c0240034020382037460d01202c20372038412010a30522394100476a212c2039450d01203741206a2137203b41606a223b0d000c0f0b0b202c41ffff034b0d0d0240200428022c22322004280228470d00202420324101109e01200428022c21320b2004280224203241146c6a2232202c3b0110203220343b0104203220333602002032410e6a203a3b01002032410c6a20363b01002032410a6a203d3b0100203241086a20353b0100203241066a203c3b01002023212c0c0c0b4102213220022802082233450d0c2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a22340d000c0e0b0b2003280208222c450d0c41002134202c410574223b213520032802002239212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a22350d000c0e0b0b203441ffff034b0d0c200e41226a2136200e2f0120213d41002135203b21382039212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a22380d000c0e0b0b203541ffff034b0d0c200e41c4006a2138200e41c2006a2f0100213e41002136203b21372039212c024003402038202c460d012036202c2038412010a305223a4100476a2136203a450d01202c41206a212c203741606a22370d000c0e0b0b203641ffff034b0d0c200e41e6006a2137200e41e4006a2f0100213f41002138203b213a2039212c024003402037202c460d012038202c2037412010a305223c4100476a2138203c450d01202c41206a212c203a41606a223a0d000c0e0b0b203841ffff034b0d0c200e4188016a2137200e4186016a2f0100213c4100212c0240034020372039460d01202c20392037412010a305223a4100476a212c203a450d01203941206a2139203b41606a223b0d000c0e0b0b202c41ffff034b0d0c0240200428023822322004280234470d0020222032410110b001200428023821320b2004280230203241186c6a2232202c3b0114203220343b010420322033360200203241126a203c3b0100203241106a20383b01002032410e6a203f3b01002032410c6a20363b01002032410a6a203e3b0100203241086a20353b0100203241066a203d3b0100200a212c0c0b0b4102213220022802082233450d0b2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a22340d000c0d0b0b2003280208222c450d0b41002134202c410574223c21352003280200223a212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a22350d000c0d0b0b203441ffff034b0d0b200e41226a2136200e2f0120213e41002135203c2138203a212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a22380d000c0d0b0b203541ffff034b0d0b200e41c4006a2138200e41c2006a2f0100213f41002136203c2137203a212c024003402038202c460d012036202c2038412010a30522394100476a21362039450d01202c41206a212c203741606a22370d000c0d0b0b203641ffff034b0d0b200e41e6006a2137200e41e4006a2f0100214041002138203c2139203a212c024003402037202c460d012038202c2037412010a305223b4100476a2138203b450d01202c41206a212c203941606a22390d000c0d0b0b203841ffff034b0d0b200e4188016a2139200e4186016a2f0100214141002137203c213b203a212c024003402039202c460d012037202c2039412010a305223d4100476a2137203d450d01202c41206a212c203b41606a223b0d000c0d0b0b203741ffff034b0d0b200e41aa016a2139200e41a8016a2f0100213d4100212c024003402039203a460d01202c203a2039412010a305223b4100476a212c203b450d01203a41206a213a203c41606a223c0d000c0d0b0b202c41ffff034b0d0b0240200428024422322004280240470d0020212032410110a301200428024421320b200428023c2032411c6c6a2232202c3b0118203220343b010420322033360200203241166a203d3b0100203241146a20373b0100203241126a20413b0100203241106a20383b01002032410e6a20403b01002032410c6a20363b01002032410a6a203f3b0100203241086a20353b0100203241066a203e3b01002020212c0c0a0b4102213220022802082233450d0a2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a22340d000c0c0b0b2003280208222c450d0a41002134202c410574223c21352003280200223a212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a22350d000c0c0b0b203441ffff034b0d0a200e41226a2136200e2f0120213f41002135203c2138203a212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a22380d000c0c0b0b203541ffff034b0d0a200e41c4006a2138200e41c2006a2f0100214041002136203c2137203a212c024003402038202c460d012036202c2038412010a30522394100476a21362039450d01202c41206a212c203741606a22370d000c0c0b0b203641ffff034b0d0a200e41e6006a2137200e41e4006a2f0100214141002138203c2139203a212c024003402037202c460d012038202c2037412010a305223b4100476a2138203b450d01202c41206a212c203941606a22390d000c0c0b0b203841ffff034b0d0a200e4188016a2139200e4186016a2f0100214241002137203c213b203a212c024003402039202c460d012037202c2039412010a305223d4100476a2137203d450d01202c41206a212c203b41606a223b0d000c0c0b0b203741ffff034b0d0a200e41aa016a213b200e41a8016a2f0100214341002139203c213d203a212c02400340203b202c460d012039202c203b412010a305223e4100476a2139203e450d01202c41206a212c203d41606a223d0d000c0c0b0b203941ffff034b0d0a200e41cc016a213b200e41ca016a2f0100213e4100212c02400340203b203a460d01202c203a203b412010a305223d4100476a212c203d450d01203a41206a213a203c41606a223c0d000c0c0b0b202c41ffff034b0d0a024020042802502232200428024c470d00201f2032410110a801200428025021320b200428024820324105746a2232202c3b011c203220343b0104203220333602002032411a6a203e3b0100203241186a20393b0100203241166a20433b0100203241146a20373b0100203241126a20423b0100203241106a20383b01002032410e6a20413b01002032410c6a20363b01002032410a6a20403b0100203241086a20353b0100203241066a203f3b01002009212c0c090b4102213220022802082233450d092002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a22340d000c0b0b0b2003280208222c450d0941002134202c410574223d21352003280200223b212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a22350d000c0b0b0b203441ffff034b0d09200e41226a2136200e2f0120214041002135203d2138203b212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a22380d000c0b0b0b203541ffff034b0d09200e41c4006a2138200e41c2006a2f0100214141002136203d2137203b212c024003402038202c460d012036202c2038412010a30522394100476a21362039450d01202c41206a212c203741606a22370d000c0b0b0b203641ffff034b0d09200e41e6006a2137200e41e4006a2f0100214241002138203d2139203b212c024003402037202c460d012038202c2037412010a305223a4100476a2138203a450d01202c41206a212c203941606a22390d000c0b0b0b203841ffff034b0d09200e4188016a2139200e4186016a2f0100214341002137203d213a203b212c024003402039202c460d012037202c2039412010a305223c4100476a2137203c450d01202c41206a212c203a41606a223a0d000c0b0b0b203741ffff034b0d09200e41aa016a213a200e41a8016a2f0100214441002139203d213c203b212c02400340203a202c460d012039202c203a412010a305223e4100476a2139203e450d01202c41206a212c203c41606a223c0d000c0b0b0b203941ffff034b0d09200e41cc016a213c200e41ca016a2f010021454100213a203d213e203b212c02400340203c202c460d01203a202c203c412010a305223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c0b0b0b203a41ffff034b0d09200e41ee016a213c200e41ec016a2f0100213f4100212c02400340203c203b460d01202c203b203c412010a305223e4100476a212c203e450d01203b41206a213b203d41606a223d0d000c0b0b0b202c41ffff034b0d090240200428025c22322004280258470d00201e2032410110a201200428025c21320b2004280254203241246c6a2232202c3b0120203220343b0104203220333602002032411e6a203f3b01002032411c6a203a3b01002032411a6a20453b0100203241186a20393b0100203241166a20443b0100203241146a20373b0100203241126a20433b0100203241106a20383b01002032410e6a20423b01002032410c6a20363b01002032410a6a20413b0100203241086a20353b0100203241066a20403b0100201d212c0c080b4102213220022802082233450d082002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a22340d000c0a0b0b2003280208222c450d0841002134202c410574223d21352003280200223b212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a22350d000c0a0b0b203441ffff034b0d08200e41226a2136200e2f0120214141002135203d2138203b212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a22380d000c0a0b0b203541ffff034b0d08200e41c4006a2138200e41c2006a2f0100214241002136203d2137203b212c024003402038202c460d012036202c2038412010a30522394100476a21362039450d01202c41206a212c203741606a22370d000c0a0b0b203641ffff034b0d08200e41e6006a2137200e41e4006a2f0100214341002138203d2139203b212c024003402037202c460d012038202c2037412010a305223a4100476a2138203a450d01202c41206a212c203941606a22390d000c0a0b0b203841ffff034b0d08200e4188016a2139200e4186016a2f0100214441002137203d213a203b212c024003402039202c460d012037202c2039412010a305223c4100476a2137203c450d01202c41206a212c203a41606a223a0d000c0a0b0b203741ffff034b0d08200e41aa016a213a200e41a8016a2f0100214541002139203d213c203b212c02400340203a202c460d012039202c203a412010a305223e4100476a2139203e450d01202c41206a212c203c41606a223c0d000c0a0b0b203941ffff034b0d08200e41cc016a213c200e41ca016a2f010021464100213a203d213e203b212c02400340203c202c460d01203a202c203c412010a305223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c0a0b0b203a41ffff034b0d08200e41ee016a213e200e41ec016a2f010021474100213c203d213f203b212c02400340203e202c460d01203c202c203e412010a30522404100476a213c2040450d01202c41206a212c203f41606a223f0d000c0a0b0b203c41ffff034b0d08200e4190026a213e200e418e026a2f010021404100212c02400340203e203b460d01202c203b203e412010a305223f4100476a212c203f450d01203b41206a213b203d41606a223d0d000c0a0b0b202c41ffff034b0d080240200428026822322004280264470d00201c2032410110aa01200428026821320b2004280260203241286c6a2232202c3b0124203220343b010420322033360200203241226a20403b0100203241206a203c3b01002032411e6a20473b01002032411c6a203a3b01002032411a6a20463b0100203241186a20393b0100203241166a20453b0100203241146a20373b0100203241126a20443b0100203241106a20383b01002032410e6a20433b01002032410c6a20363b01002032410a6a20423b0100203241086a20353b0100203241066a20413b01002008212c0c070b4102213220022802082233450d072002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a22340d000c090b0b2003280208222c450d0741002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a22350d000c090b0b203441ffff034b0d07200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a22380d000c090b0b203541ffff034b0d07200e41c4006a2138200e41c2006a2f0100214341002136203d2137203c212c024003402038202c460d012036202c2038412010a30522394100476a21362039450d01202c41206a212c203741606a22370d000c090b0b203641ffff034b0d07200e41e6006a2137200e41e4006a2f0100214441002138203d2139203c212c024003402037202c460d012038202c2037412010a305223a4100476a2138203a450d01202c41206a212c203941606a22390d000c090b0b203841ffff034b0d07200e4188016a2139200e4186016a2f0100214541002137203d213a203c212c024003402039202c460d012037202c2039412010a305223b4100476a2137203b450d01202c41206a212c203a41606a223a0d000c090b0b203741ffff034b0d07200e41aa016a213a200e41a8016a2f0100214641002139203d213b203c212c02400340203a202c460d012039202c203a412010a305223e4100476a2139203e450d01202c41206a212c203b41606a223b0d000c090b0b203941ffff034b0d07200e41cc016a213b200e41ca016a2f010021474100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a305223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c090b0b203a41ffff034b0d07200e41ee016a213e200e41ec016a2f010021484100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a30522404100476a213b2040450d01202c41206a212c203f41606a223f0d000c090b0b203b41ffff034b0d07200e4190026a213f200e418e026a2f010021494100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a30522414100476a213e2041450d01202c41206a212c204041606a22400d000c090b0b203e41ffff034b0d07200e41b2026a213f200e41b0026a2f010021414100212c02400340203f203c460d01202c203c203f412010a30522404100476a212c2040450d01203c41206a213c203d41606a223d0d000c090b0b202c41ffff034b0d070240200428027422322004280270470d00201b2032410110a601200428027421320b200428026c2032412c6c6a2232202c3b0128203220343b010420322033360200203241266a20413b0100203241246a203e3b0100203241226a20493b0100203241206a203b3b01002032411e6a20483b01002032411c6a203a3b01002032411a6a20473b0100203241186a20393b0100203241166a20463b0100203241146a20373b0100203241126a20453b0100203241106a20383b01002032410e6a20443b01002032410c6a20363b01002032410a6a20433b0100203241086a20353b0100203241066a20423b0100201a212c0c060b4102213220022802082233450d062002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a22340d000c080b0b2003280208222c450d0641002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a22350d000c080b0b203441ffff034b0d06200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a22380d000c080b0b203541ffff034b0d06200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a30522394100476a21362039450d01202c41206a212c203741606a22370d000c080b0b203641ffff034b0d06200e41e6006a2137200e41e4006a2f0100214541002138203d2139203c212c024003402037202c460d012038202c2037412010a305223a4100476a2138203a450d01202c41206a212c203941606a22390d000c080b0b203841ffff034b0d06200e4188016a2139200e4186016a2f0100214641002137203d213a203c212c024003402039202c460d012037202c2039412010a305223b4100476a2137203b450d01202c41206a212c203a41606a223a0d000c080b0b203741ffff034b0d06200e41aa016a213a200e41a8016a2f0100214741002139203d213b203c212c02400340203a202c460d012039202c203a412010a305223e4100476a2139203e450d01202c41206a212c203b41606a223b0d000c080b0b203941ffff034b0d06200e41cc016a213b200e41ca016a2f010021484100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a305223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c080b0b203a41ffff034b0d06200e41ee016a213e200e41ec016a2f010021494100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a30522404100476a213b2040450d01202c41206a212c203f41606a223f0d000c080b0b203b41ffff034b0d06200e4190026a213f200e418e026a2f0100214a4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a30522414100476a213e2041450d01202c41206a212c204041606a22400d000c080b0b203e41ffff034b0d06200e41b2026a2140200e41b0026a2f0100214b4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a30522434100476a213f2043450d01202c41206a212c204141606a2241450d080c000b0b203f41ffff034b0d06200e41d4026a2140200e41d2026a2f010021434100212c024003402040203c460d01202c203c2040412010a30522414100476a212c2041450d01203c41206a213c203d41606a223d450d080c000b0b202c41ffff034b0d0602402004280280012232200428027c470d0020192032410110b60120042802800121320b2004280278203241306c6a2232202c3b012c203220343b0104203220333602002032412a6a20433b0100203241286a203f3b0100203241266a204b3b0100203241246a203e3b0100203241226a204a3b0100203241206a203b3b01002032411e6a20493b01002032411c6a203a3b01002032411a6a20483b0100203241186a20393b0100203241166a20473b0100203241146a20373b0100203241126a20463b0100203241106a20383b01002032410e6a20453b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002007212c0c050b4102213220022802082233450d052002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a2234450d070c000b0b2003280208222c450d0541002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a2235450d070c000b0b203441ffff034b0d05200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a2238450d070c000b0b203541ffff034b0d05200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a30522394100476a21362039450d01202c41206a212c203741606a2237450d070c000b0b203641ffff034b0d05200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a305223a4100476a2138203a450d01202c41206a212c203941606a2239450d070c000b0b203841ffff034b0d05200e4188016a2139200e4186016a2f0100214741002137203d213a203c212c024003402039202c460d012037202c2039412010a305223b4100476a2137203b450d01202c41206a212c203a41606a223a450d070c000b0b203741ffff034b0d05200e41aa016a213a200e41a8016a2f0100214841002139203d213b203c212c02400340203a202c460d012039202c203a412010a305223e4100476a2139203e450d01202c41206a212c203b41606a223b450d070c000b0b203941ffff034b0d05200e41cc016a213b200e41ca016a2f010021494100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a305223f4100476a213a203f450d01202c41206a212c203e41606a223e450d070c000b0b203a41ffff034b0d05200e41ee016a213e200e41ec016a2f0100214a4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a30522404100476a213b2040450d01202c41206a212c203f41606a223f450d070c000b0b203b41ffff034b0d05200e4190026a213f200e418e026a2f0100214b4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a30522414100476a213e2041450d01202c41206a212c204041606a2240450d070c000b0b203e41ffff034b0d05200e41b2026a2140200e41b0026a2f0100214c4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a30522434100476a213f2043450d01202c41206a212c204141606a2241450d070c000b0b203f41ffff034b0d05200e41d4026a2141200e41d2026a2f0100214d41002140203d2143203c212c024003402041202c460d012040202c2041412010a30522454100476a21402045450d01202c41206a212c204341606a2243450d070c000b0b204041ffff034b0d05200e41f6026a2141200e41f4026a2f010021454100212c024003402041203c460d01202c203c2041412010a30522434100476a212c2043450d01203c41206a213c203d41606a223d450d070c000b0b202c41ffff034b0d050240200428028c012232200428028801470d0020182032410110a701200428028c0121320b200428028401203241346c6a2232202c3b0130203220343b0104203220333602002032412e6a20453b01002032412c6a20403b01002032412a6a204d3b0100203241286a203f3b0100203241266a204c3b0100203241246a203e3b0100203241226a204b3b0100203241206a203b3b01002032411e6a204a3b01002032411c6a203a3b01002032411a6a20493b0100203241186a20393b0100203241166a20483b0100203241146a20373b0100203241126a20473b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002017212c0c040b4102213220022802082233450d042002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a2234450d060c000b0b2003280208222c450d0441002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a2235450d060c000b0b203441ffff034b0d04200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a2238450d060c000b0b203541ffff034b0d04200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a30522394100476a21362039450d01202c41206a212c203741606a2237450d060c000b0b203641ffff034b0d04200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a305223a4100476a2138203a450d01202c41206a212c203941606a2239450d060c000b0b203841ffff034b0d04200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a305223b4100476a2137203b450d01202c41206a212c203a41606a223a450d060c000b0b203741ffff034b0d04200e41aa016a213a200e41a8016a2f0100214941002139203d213b203c212c02400340203a202c460d012039202c203a412010a305223e4100476a2139203e450d01202c41206a212c203b41606a223b450d060c000b0b203941ffff034b0d04200e41cc016a213b200e41ca016a2f0100214a4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a305223f4100476a213a203f450d01202c41206a212c203e41606a223e450d060c000b0b203a41ffff034b0d04200e41ee016a213e200e41ec016a2f0100214b4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a30522404100476a213b2040450d01202c41206a212c203f41606a223f450d060c000b0b203b41ffff034b0d04200e4190026a213f200e418e026a2f0100214c4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a30522414100476a213e2041450d01202c41206a212c204041606a2240450d060c000b0b203e41ffff034b0d04200e41b2026a2140200e41b0026a2f0100214d4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a30522434100476a213f2043450d01202c41206a212c204141606a2241450d060c000b0b203f41ffff034b0d04200e41d4026a2141200e41d2026a2f0100214e41002140203d2143203c212c024003402041202c460d012040202c2041412010a30522454100476a21402045450d01202c41206a212c204341606a2243450d060c000b0b204041ffff034b0d04200e41f6026a2143200e41f4026a2f0100214f41002141203d2145203c212c024003402043202c460d012041202c2043412010a30522474100476a21412047450d01202c41206a212c204541606a2245450d060c000b0b204141ffff034b0d04200e4198036a2143200e4196036a2f010021474100212c024003402043203c460d01202c203c2043412010a30522454100476a212c2045450d01203c41206a213c203d41606a223d450d060c000b0b202c41ffff034b0d0402402004280298012232200428029401470d0020162032410110ae0120042802980121320b200428029001203241386c6a2232202c3b0134203220343b010420322033360200203241326a20473b0100203241306a20413b01002032412e6a204f3b01002032412c6a20403b01002032412a6a204e3b0100203241286a203f3b0100203241266a204d3b0100203241246a203e3b0100203241226a204c3b0100203241206a203b3b01002032411e6a204b3b01002032411c6a203a3b01002032411a6a204a3b0100203241186a20393b0100203241166a20493b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002006212c0c030b4102213220022802082233450d032002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a2234450d050c000b0b2003280208222c450d0341002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a2235450d050c000b0b203441ffff034b0d03200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a2238450d050c000b0b203541ffff034b0d03200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a30522394100476a21362039450d01202c41206a212c203741606a2237450d050c000b0b203641ffff034b0d03200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a305223a4100476a2138203a450d01202c41206a212c203941606a2239450d050c000b0b203841ffff034b0d03200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a305223b4100476a2137203b450d01202c41206a212c203a41606a223a450d050c000b0b203741ffff034b0d03200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010a305223e4100476a2139203e450d01202c41206a212c203b41606a223b450d050c000b0b203941ffff034b0d03200e41cc016a213b200e41ca016a2f0100214b4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a305223f4100476a213a203f450d01202c41206a212c203e41606a223e450d050c000b0b203a41ffff034b0d03200e41ee016a213e200e41ec016a2f0100214c4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a30522404100476a213b2040450d01202c41206a212c203f41606a223f450d050c000b0b203b41ffff034b0d03200e4190026a213f200e418e026a2f0100214d4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a30522414100476a213e2041450d01202c41206a212c204041606a2240450d050c000b0b203e41ffff034b0d03200e41b2026a2140200e41b0026a2f0100214e4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a30522434100476a213f2043450d01202c41206a212c204141606a2241450d050c000b0b203f41ffff034b0d03200e41d4026a2141200e41d2026a2f0100214f41002140203d2143203c212c024003402041202c460d012040202c2041412010a30522454100476a21402045450d01202c41206a212c204341606a2243450d050c000b0b204041ffff034b0d03200e41f6026a2143200e41f4026a2f0100215041002141203d2145203c212c024003402043202c460d012041202c2043412010a30522474100476a21412047450d01202c41206a212c204541606a2245450d050c000b0b204141ffff034b0d03200e4198036a2145200e4196036a2f0100215141002143203d2147203c212c024003402045202c460d012043202c2045412010a30522494100476a21432049450d01202c41206a212c204741606a2247450d050c000b0b204341ffff034b0d03200e41ba036a2145200e41b8036a2f010021494100212c024003402045203c460d01202c203c2045412010a30522474100476a212c2047450d01203c41206a213c203d41606a223d450d050c000b0b202c41ffff034b0d03024020042802a401223220042802a001470d0020152032410110b70120042802a40121320b200428029c012032413c6c6a2232202c3b0138203220343b010420322033360200203241366a20493b0100203241346a20433b0100203241326a20513b0100203241306a20413b01002032412e6a20503b01002032412c6a20403b01002032412a6a204f3b0100203241286a203f3b0100203241266a204e3b0100203241246a203e3b0100203241226a204d3b0100203241206a203b3b01002032411e6a204c3b01002032411c6a203a3b01002032411a6a204b3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002014212c0c020b4102213220022802082233450d022002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a2234450d040c000b0b2003280208222c450d0241002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a2235450d040c000b0b203441ffff034b0d02200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a2238450d040c000b0b203541ffff034b0d02200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a30522394100476a21362039450d01202c41206a212c203741606a2237450d040c000b0b203641ffff034b0d02200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a305223a4100476a2138203a450d01202c41206a212c203941606a2239450d040c000b0b203841ffff034b0d02200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a305223b4100476a2137203b450d01202c41206a212c203a41606a223a450d040c000b0b203741ffff034b0d02200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010a305223e4100476a2139203e450d01202c41206a212c203b41606a223b450d040c000b0b203941ffff034b0d02200e41cc016a213b200e41ca016a2f0100214c4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a305223f4100476a213a203f450d01202c41206a212c203e41606a223e450d040c000b0b203a41ffff034b0d02200e41ee016a213e200e41ec016a2f0100214d4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a30522404100476a213b2040450d01202c41206a212c203f41606a223f450d040c000b0b203b41ffff034b0d02200e4190026a213f200e418e026a2f0100214e4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a30522414100476a213e2041450d01202c41206a212c204041606a2240450d040c000b0b203e41ffff034b0d02200e41b2026a2140200e41b0026a2f0100214f4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a30522434100476a213f2043450d01202c41206a212c204141606a2241450d040c000b0b203f41ffff034b0d02200e41d4026a2141200e41d2026a2f0100215041002140203d2143203c212c024003402041202c460d012040202c2041412010a30522454100476a21402045450d01202c41206a212c204341606a2243450d040c000b0b204041ffff034b0d02200e41f6026a2143200e41f4026a2f0100215141002141203d2145203c212c024003402043202c460d012041202c2043412010a30522474100476a21412047450d01202c41206a212c204541606a2245450d040c000b0b204141ffff034b0d02200e4198036a2145200e4196036a2f0100215241002143203d2147203c212c024003402045202c460d012043202c2045412010a30522494100476a21432049450d01202c41206a212c204741606a2247450d040c000b0b204341ffff034b0d02200e41ba036a2147200e41b8036a2f0100215341002145203d2149203c212c024003402047202c460d012045202c2047412010a305224b4100476a2145204b450d01202c41206a212c204941606a2249450d040c000b0b204541ffff034b0d02200e41dc036a2147200e41da036a2f0100214b4100212c024003402047203c460d01202c203c2047412010a30522494100476a212c2049450d01203c41206a213c203d41606a223d450d040c000b0b202c41ffff034b0d02024020042802b001223220042802ac01470d0020132032410110b30120042802b00121320b20042802a80120324106746a2232202c3b013c203220343b0104203220333602002032413a6a204b3b0100203241386a20453b0100203241366a20533b0100203241346a20433b0100203241326a20523b0100203241306a20413b01002032412e6a20513b01002032412c6a20403b01002032412a6a20503b0100203241286a203f3b0100203241266a204f3b0100203241246a203e3b0100203241226a204e3b0100203241206a203b3b01002032411e6a204d3b01002032411c6a203a3b01002032411a6a204c3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002005212c0c010b4102213220022802082233450d012002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a30522354100476a21332035450d01202c41206a212c203441606a2234450d030c000b0b2003280208222c450d0141002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a30522364100476a21342036450d01202c41206a212c203541606a2235450d030c000b0b203441ffff034b0d01200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a30522374100476a21352037450d01202c41206a212c203841606a2238450d030c000b0b203541ffff034b0d01200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a30522394100476a21362039450d01202c41206a212c203741606a2237450d030c000b0b203641ffff034b0d01200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a305223a4100476a2138203a450d01202c41206a212c203941606a2239450d030c000b0b203841ffff034b0d01200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a305223b4100476a2137203b450d01202c41206a212c203a41606a223a450d030c000b0b203741ffff034b0d01200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010a305223e4100476a2139203e450d01202c41206a212c203b41606a223b450d030c000b0b203941ffff034b0d01200e41cc016a213b200e41ca016a2f0100214c4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a305223f4100476a213a203f450d01202c41206a212c203e41606a223e450d030c000b0b203a41ffff034b0d01200e41ee016a213e200e41ec016a2f0100214e4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a30522404100476a213b2040450d01202c41206a212c203f41606a223f450d030c000b0b203b41ffff034b0d01200e4190026a213f200e418e026a2f0100214f4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a30522414100476a213e2041450d01202c41206a212c204041606a2240450d030c000b0b203e41ffff034b0d01200e41b2026a2140200e41b0026a2f010021504100213f203d2141203c212c024003402040202c460d01203f202c2040412010a30522434100476a213f2043450d01202c41206a212c204141606a2241450d030c000b0b203f41ffff034b0d01200e41d4026a2141200e41d2026a2f0100215141002140203d2143203c212c024003402041202c460d012040202c2041412010a30522454100476a21402045450d01202c41206a212c204341606a2243450d030c000b0b204041ffff034b0d01200e41f6026a2143200e41f4026a2f0100215241002141203d2145203c212c024003402043202c460d012041202c2043412010a30522474100476a21412047450d01202c41206a212c204541606a2245450d030c000b0b204141ffff034b0d01200e4198036a2145200e4196036a2f0100215341002143203d2147203c212c024003402045202c460d012043202c2045412010a30522494100476a21432049450d01202c41206a212c204741606a2247450d030c000b0b204341ffff034b0d01200e41ba036a2147200e41b8036a2f0100215441002145203d2149203c212c024003402047202c460d012045202c2047412010a305224b4100476a2145204b450d01202c41206a212c204941606a2249450d030c000b0b204541ffff034b0d01200e41dc036a2149200e41da036a2f0100215541002147203d214b203c212c024003402049202c460d012047202c2049412010a305224d4100476a2147204d450d01202c41206a212c204b41606a224b450d030c000b0b204741ffff034b0d01200e41fe036a2149200e41fc036a2f0100214d4100212c024003402049203c460d01202c203c2049412010a305224b4100476a212c204b450d01203c41206a213c203d41606a223d450d030c000b0b202c41ffff034b0d01024020042802bc01223220042802b801470d00201220324101109b0120042802bc0121320b20042802b401203241c4006c6a2232202c3b0140203220343b0104203220333602002032413e6a204d3b01002032413c6a20473b01002032413a6a20553b0100203241386a20453b0100203241366a20543b0100203241346a20433b0100203241326a20533b0100203241306a20413b01002032412e6a20523b01002032412c6a20403b01002032412a6a20513b0100203241286a203f3b0100203241266a20503b0100203241246a203e3b0100203241226a204f3b0100203241206a203b3b01002032411e6a204e3b01002032411c6a203a3b01002032411a6a204c3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002011212c0b202c202c28020041016a3602000240202d450d00202d41226c450d00200e10230b2001200f460d040c010b200041013a0000200020323a00010240202d450d00202d41226c450d00200e10230b0240200f2001460d0003400240200141046a280200220e450d00200e41226c450d00200128020010230b2001412c6a2101200d41546a220d0d000b0b02402010450d002010412c6c450d00200c10230b20041083020c040b200d41546a210d2001210e0c000b0b200f2001460d0003402001220d412c6a21010240200d41046a280200220e450d00200e41226c450d00200d28020010230b200f2001470d000b0b02402010450d002010412c6c450d00200c10230b200041046a200441c00110a1051a200041003a00000b20044180026a24000bd80301067f230041106b2202240020024100360208200242013703000240412010212203450d0020032000290038370000200341086a200041c0006a290000370000200341106a200041c8006a290000370000200341186a200041d0006a29000037000020022003360200200242a080808080043702042002200036020c2002410c6a200210db012002200041106a36020c2002410c6a200210db0120002802202103200041286a28020022042002106102402004450d002003200441186c6a210403402002200336020c2002410c6a200210db01200341106a200210ed012004200341186a2203470d000b0b200028022c2105200041346a28020022032002106102400240024020022802042206200228020822046b20034102742200490d0020022802002103200621070c010b200420006a22032004490d01200641017422072003200720034b1b22074100480d010240024020060d00024020070d00410121030c020b2007102122030d010c040b2002280200210320062007460d0020032006200710252203450d030b20022007360204200220033602000b200320046a2005200010a1051a2001290200200420006aad4220862003ad84100e02402007450d00200310230b200241106a24000f0b102c000b102a000bdb0401097f230041c0016b2202240020024188016a200110c601200241306a200228028801220320022802900110e20120024198016a41086a2204200241ec006a29020037030020024198016a41106a2205200241f4006a29020037030020024198016a41186a2206200241fc006a29020037030020024198016a41206a220720024184016a2802003602002002200241e4006a290200370398010240024020022802502208450d00200241e0006a2802002109200241dc006a280200210a20022802542101200241086a41206a2007280200360200200241086a41186a2006290300370300200241086a41106a2005290300370300200241086a41086a200429030037030020022002290398013703080240200228028c01450d00200310230b200241306a41106a200241086a41106a290300370300200241306a41086a200241086a41086a290300370300200241306a41186a200241086a41186a290300370300200241306a41206a200241086a41206a28020036020020024198016a41086a2002413c6a29020037030020024198016a41106a200241c4006a29020037030020024198016a41186a200241cc006a29020037030020022002290308370330200220022902343703980102402001450d00200141186c450d00200810230b0240200941ffffffff0371450d00200a10230b2000200229039801370001200041196a200241b0016a290300370000200041116a200241a8016a290300370000200041096a200241a0016a290300370000410121010c010b0240200228028c01450d00200310230b410021010b200020013a0000200241c0016a24000bf84511047f017e017f017e0b7f017e017f017e077f027e027f037e017f017e037f017e017f23004180046b22052400200541f8026a41186a22064200370300200541f8026a41106a22074200370300200541f8026a41086a22084200370300200542003703f802418fcdc200ad4280808080f000842209100c220a290000210b200541a8026a41086a220c200a41086a2900003703002005200b3703a802200a10232008200c290300370300200520052903a8023703f80241ccc5c000ad4280808080900284100c220a290000210b200541b8026a41086a220d200a41086a2900003703002005200b3703b802200a1023200720052903b802220b370300200541b8036a41086a220a2008290300370300200541b8036a41106a220e200b370300200541b8036a41186a220f200d290300370300200520052903f8023703b803200541e0016a200541b8036a10880241012110024020052802e001417d710d00200642003703002007420037030020084200370300200542003703f8022009100c2210290000210b200c201041086a2900003703002005200b3703a802201010232008200c290300370300200520052903a8023703f80241a4dfc100ad4280808080b00284100c220c290000210b200d200c41086a2900003703002005200b3703b802200c1023200720052903b802370000200741086a200d290300370000200a2008290300370300200e2007290300370300200f2006290300370300200520052903f8023703b803200541203602bc022005200541b8036a3602b802200541e8016a200541b8036aad428080808080048422091010108b01410021100240024020052802e80122080d00410021110c010b20052802ec01210a02400240200541f0016a2802004104490d00410121112008280000220e418194ebdc03490d010b41002111200541003602900220054201370388022005410a3602e4032005200541b8026a3602e003200520054188026a3602a8022005418c036a4101360200200542013702fc0220054180c5c6003602f8022005200541e0036a36028803200541a8026a4184a5c200200541f8026a10311a20053502900242208620053502880284100a200528028c02450d0020052802880210230b200a450d00200810230b200541f8026a41186a220d4200370300200541f8026a41106a220c4200370300200541f8026a41086a22084200370300200542003703f802418fcdc200ad4280808080f00084100c220a290000210b200541a8026a41086a2206200a41086a2900003703002005200b3703a802200a102320082006290300370300200520052903a8023703f80241b8dbc100ad4280808080900184100c220a290000210b200541b8026a41086a2206200a41086a2900003703002005200b3703b802200a1023200720052903b802370000200741086a2006290300370000200541b8036a41086a2008290300370300200541b8036a41106a200c290300370300200541b8036a41186a200d290300370300200520052903f8023703b803200541f8026a200541b8036a10ba0120052903f8024202510d00200541f8026a200c280200221210c201200541d8016a20052802f802220a20052802800310cd0120052802dc01210c20052802d8012108024020052802fc02450d00200a10230b02400240024020080d00419fcfc000ad4280808080e00684100a4100201241646a2208200820124b1b2113201221140c010b4100201241646a2208200820124b1b21130240200c20044b0d00201221140c010b200541f8026a41186a220c4200370300200541f8026a41106a220d4200370300200541f8026a41086a22084200370300200542003703f802418fcdc200ad4280808080f00084100c220a290000210b200541a8026a41086a2206200a41086a2900003703002005200b3703a802200a102320082006290300370300200520052903a8023703f80241dce0c100ad4280808080a00184100c220a290000210b200541b8026a41086a2206200a41086a2900003703002005200b3703b802200a1023200720052903b802370000200741086a2006290300370000200541b8036a41086a2008290300370300200541b8036a41106a200d290300370300200541b8036a41186a200c290300370300200520052903f8023703b803200541f8026a200541b8036a10e40120052802f8022208410420081b220d20052902fc02420020081b220b422088a741037422086a210a03402008450d02200841786a2108200a417c6a210c200a41786a210a200c28020020044b0d000b200d20086a2802002114200b42ffffffff0183500d00200d10230b200541f8026a41186a22154200370300200541f8026a41106a22164200370300200541f8026a41086a220f4200370300200542003703f802418fcdc200ad4280808080f000842217100c2208290000210b200541a8026a41086a2218200841086a2900003703002005200b3703a80220081023200f2018290300370300200520052903a8023703f802419ce3c100ad4280808080e00284220b100c22082900002119200541b8026a41086a221a200841086a290000370300200520193703b80220081023200720052903b802370000200741086a221b201a290300370000200541b8036a41086a221c200f290300370300200541b8036a41106a221d2016290300370300200541b8036a41186a221e2015290300370300200520052903f8023703b803200541d0016a200541b8036a412010cd0120052802d401210a20052802d001210c2015420037030020164200370300200f4200370300200542003703f8022017100c220829000021192018200841086a290000370300200520193703a80220081023200f2018290300370300200520052903a8023703f802200b100c2208290000210b201a200841086a2900003703002005200b3703b80220081023200720052903b802370000201b201a290300370000201c200f290300370300201d2016290300370300201e2015290300370300200520052903f8023703b8032005200a2012200c4101461b3602f8022009200541f8026aad220b4280808080c00084100e20032001200120034b1b221f450d01200e410020111b2120200541a8036aad4280808080c000842121200b42808080808002842122200541a8036a41046a2123200541e0036a41086a2103200021014100212402400240024003402015420037030020164200370300200f4200370300200542003703f8022017100c2208290000210b2018200841086a2900003703002005200b3703a80220081023200f2018290300370300200520052903a8023703f80241bcd9c100ad4280808080d00184100c2208290000210b201a200841086a2900003703002005200b3703b80220081023200720052903b802370000201b201a290300370000201c200f290300370300201d2016290300370300201e2015290300370300200520052903f8023703b803200541f8026a200541b8036a412010890220052902fc02420020052802f80222081b220b422088a7410574210a2024220c41016a21242002200c4102746a21042000200c41e0006c6a21062008410120081b22102108024003400240200a0d004100210d0c020b4101210d20012008460d0120082006412010a305210c200a41606a210a200841206a2108200c0d000b0b0240200b42ffffff3f83500d00201010230b0240200d0d0020042802002108200542003703b002200542003703a802200541c0016a2006290320220b200641286a290300428094ebdc03420010a705200541a0016a20062903302209200641386a290300428094ebdc03420010a705200541b0016a20052903c0012219200541c0016a41086a29030022254280ec94a37c427f10a605200541f0006a201920252008ad2226420010a60520054190016a20052903a0012219200541a0016a41086a29030022254280ec94a37c427f10a60520054180016a201920252026420010a605200542003703c002200542003703b802202620092005290390017c7e2219428094ebdc0380212502400240200529037042002026200b20052903b0017c7e220b428094ebdc03802209a7417f200b428080808080c0b2cd3b541b200b20094280ec94a37c7e7c4280cab5ee01566a220aad7d85200541f0006a41086a2903004200200a410047ad7d8584500d00200529038001210920054180016a41086a2903002127200541e8016a2014200610bf0120052802e801210a200520052802f001220c3602f4032005200a3602f00320054188026a200cad422086200aad841010108b0102400240200528028802220c0d004200210b0c010b200528028c0221100240024020052802900222044104490d00200c280000220d418094ebdc034b0d004201210b2004417c6a410f4b0d010b200541003602c003200542013703b8032005410a3602e4032005200541f0036a3602e0032005200541b8036a3602a8032005410136028c03200542013702fc0220054180c5c6003602f8022005200541e0036a36028803200541a8036a4184a5c200200541f8026a10311a20053502c00342208620053502b80384100a024020052802bc03450d0020052802b80310230b4200210b2028210d0b02402010450d00200c10230b200d21280b024020052802ec01450d00200a10230b200820284100200b4200521b22044d0d02200541f8026a2014200610bf01200535028003212920052802f802210c41101021220a0d010c060b200542003703f001200542003703e80120054200370390022005420037038802200541f0036a200610c101200541b8036a20052802f003220a20052802f80310c9012003201c280200360200200520052903b8033703e003024020052802c4032208450d00200541a8036a41086a2003280200360200200520052903e0033703a80320052903c803210b0b024020052802f403450d00200a10230b0240024020080d00200542003703c80320054280808080c0003703c003200520133602bc03200541003602b803200541f0036a200610c10120052802f0032108200520052802f8033602e403200520083602e003200541b8036a200541e0036a108a02024020052802f403450d00200810230b2003201c280200360200200520052903b8033703e00320052903c803210b410421080c010b2003200541a8036a41086a280200360200200520052903a8033703e0030b200f20052903e003370200200f41086a2003280200360200200541003a00a403200520063602fc02200520133602f802200520203602a0032005200b370390032005200836028c03200520054188026a36029c032005200541e8016a36029803200541b8036a200541f8026a2014108b02024020052802c0034102460d0020052802b803200528028003470d00200f2012107221082005410120052d00a40320081b22083a00a403200541b8036a200610c30120053502c00342208620052802b803220aad841011024020052802bc03450d00200a10230b200541b8036a200610c50120053502c00342208620052802b803220aad841011024020052802bc03450d00200a10230b02402006108c0241ff0171220a4102460d00200a410171450d0010ef010b200841ff0171450d00200528028403210420052802f8022110024002400240200528029403220e450d00200528028c03210a2005280280032106200e410274210d4100210c2004210802400340200820104d0d01200c41016a210c2008200a2802006b2108200a41046a210a200d417c6a220d0d000c020b0b200e200c4f0d010b200520042010200420104b1b360284030c010b200520042010200420104b1b360284032005200c3602940341000d002006200e6b2006200c6b4f0d004100200e6b210a20052802fc0221080340201e200841186a290000370300201d200841106a290000370300201c200841086a290000370300200520082900003703b80320052006200a6a3602d803200541f0036a200541b8036a10c40120053502f80342208620052802f003220dad841011024020052802f403450d00200d10230b200c200a41016a220a6a0d000b0b200541b8036a20052802fc0210c10120052802b8032108200520052802c0033602f403200520083602f003200f200541f0036a108a0220052802bc03450d00200810230b20052802900341ffffffff0371450d01200528028c0310230c010b200a2008360000200a4110412010252208450d03200820092025a7417f2019428080808080c0b2cd3b541b201920254280ec94a37c7e7c4280cab5ee01566aad7c220b3700042008410c6a2027200b200954ad7c22193700002029422086200cad842008ad4280808080c00284100e20081023024020052802fc02450d00200c10230b20054188026a200610c101200541b8036a200528028802220a20052802900210c9012003201c280200360200200520052903b8033703e003024020052802c4032208450d00200541e8016a41086a2003280200360200200520052903e0033703e80120052903c80321090b0240200528028c02450d00200a10230b0240024020080d00200542003703c80320054280808080c0003703c003200520133602bc03200541003602b80320054188026a200610c101200528028802210820052005280290023602f403200520083602f003200541b8036a200541f0036a108a020240200528028c02450d00200810230b200541f0036a41086a201c280200360200200520052903b8033703f00320052903c8032109410421080c010b200541f0036a41086a200541e8016a41086a280200360200200520052903e8013703f0030b200f20052903f003370200200f41086a222a200541f0036a41086a280200360200200541003a00a403200520063602fc02200520133602f802200520203602a00320052009370390032005200836028c032005200541b8026a36029c032005200541a8026a36029803200541e8006a200541f8026a2014200b2019108d0202400240024020052802684101470d00200528026c200528028003460d010b20052d00a40321080c010b200f2012107221082005410120052d00a40320081b22083a00a403200541b8036a200610c30120053502c00342208620052802b803220aad841011024020052802bc03450d00200a10230b200541b8036a200610c50120053502c00342208620052802b803220aad841011024020052802bc03450d00200a10230b2006108c0241ff0171220a4102460d00200a410171450d0010ef010b0240200841ff0171450d00200528028403210e20052802f8022110024002400240200528029403222b450d00200528028c03210a2005280280032111202b410274210d4100210c200e210802400340200820104d0d01200c41016a210c2008200a2802006b2108200a41046a210a200d417c6a220d0d000c020b0b202b200c4f0d010b2005200e2010200e20104b1b360284030c010b2005200e2010200e20104b1b360284032005200c3602940341000d002011202b6b2011200c6b4f0d004100202b6b210a20052802fc0221080340201e200841186a290000370300201d200841106a290000370300201c200841086a290000370300200520082900003703b80320052011200a6a3602d80320054188026a200541b8036a10c401200535029002422086200528028802220dad8410110240200528028c02450d00200d10230b200c200a41016a220a6a0d000b0b200541b8036a20052802fc0210c10120052802b8032108200520052802c00336028c022005200836028802200f20054188026a108a0220052802bc03450d00200810230b024020052802900341ffffffff0371450d00200528028c0310230b200541003602d002200542083703c802200542003703f001200542003703e801200541c8026a4100200641c8006a220828020010a40102400240200828020022080d004200210920052802c802210c420021190c010b2006280240220e200841306c6a212c2004ad2127034020054200370390022005420037038802200541c0006a200e2903002219200e41086a290300428094ebdc03420010a705200541306a2005290340220b200541c0006a41086a29030022094280ec94a37c427f10a605200541206a200b20092027420010a605200541106a200b20092026420010a605200541f8026a2014200e41106a221010c001200541d0006a20052802f802220a20052802800310d7014200200541106a41086a290300200529031022092026201920052903307c22197e220b428094ebdc03802225a7417f200b428080808080c0b2cd3b541b200b20254280ec94a37c7e7c4280cab5ee01566aad7c220b200954ad7c2209200541206a41086a29030020052903202225202720197e2219428094ebdc03802229a7417f2019428080808080c0b2cd3b541b201920294280ec94a37c7e7c4280cab5ee01566aad7c2219202554ad7c7d200b201954ad7d2225200b20197d2219200b56202520095620252009511b22081b21094200201920081b210b200541d0006a41106a29030021192005290358212520052802502108024020052802fc02450d00200a10230b200541b8036a2014201010c00120052802b803210a20053502c003212920052025420020081b2225200b7c220b3703f80220052019420020081b20097c200b202554ad7c2209370380032029422086200aad842022100e024020052802bc03450d00200a10230b200541f0036a201010c101200541b8036a20052802f003220a20052802f80310c9012003201c280200360200200520052903b8033703e003024020052802c4032208450d00200541a8036a41086a2003280200360200200520052903e0033703a80320052903c803212d0b024020052802f403450d00200a10230b0240024020080d00200542003703c80320054280808080c0003703c003200520133602bc03200541003602b803200541f0036a201010c10120052802f0032108200520052802f8033602e403200520083602e003200541b8036a200541e0036a108a02024020052802f403450d00200810230b2003201c280200360200200520052903b8033703e00320052903c8032119410421080c010b2003200541a8036a41086a280200360200200520052903a8033703e003202d21190b200f20052903e003370200202a2003280200360200200541003a00a403200520103602fc02200520133602f802200520203602a00320052019370390032005200836028c03200520054188026a36029c032005200541e8016a36029803200541086a200541f8026a2014200b2009108d020240024020052802084101470d00200528020c200528028003470d00200f2012107221082005410120052d00a40320081b22083a00a4030c010b20052d00a40321080b0240200841ff0171450d00200528028403211120052802f8022104024002400240200528029403222e450d00200528028c03210a200528028003212b202e410274210d4100210c2011210802400340200820044d0d01200c41016a210c2008200a2802006b2108200a41046a210a200d417c6a220d0d000c020b0b202e200c4f0d010b200520112004201120044b1b360284030c010b200520112004201120044b1b360284032005200c3602940341000d00202b202e6b202b200c6b4f0d004100202e6b210a20052802fc0221080340201e200841186a290000370300201d200841106a290000370300201c200841086a290000370300200520082900003703b8032005202b200a6a3602d803200541f0036a200541b8036a10c40120053502f80342208620052802f003220dad841011024020052802f403450d00200d10230b200c200a41016a220a6a0d000b0b200541b8036a20052802fc0210c10120052802b8032108200520052802c0033602f403200520083602f003200f200541f0036a108a0220052802bc03450d00200810230b024020052802900341ffffffff0371450d00200528028c0310230b200e41306a210e201041086a290000210b201029000021092015201041186a2900003703002016201041106a290000370300200f200b370300200520093703f80220054188026a41086a290300210b2005290388022109024020052802d002220a20052802cc02470d00200541c8026a200a410110a40120052802d002210a0b20052802c802220c200a41306c6a22082009370320200820052903f802370300200841286a200b370300200841086a200f290300370300200841106a2016290300370300200841186a20152903003703002005200a41016a3602d002200e202c470d000b200541e8016a41086a290300211920052903e80121090b2018290300212520052903a802210b200541e8016a41086a2208200641086a290300370300200541e8016a41106a220a200641106a290300370300200541e8016a41186a220d200641186a290300370300200520062903003703e801200c450d00201a290300212620052903b802212720052902cc02212920054188026a41186a2210200d29030037030020054188026a41106a220d200a29030037030020054188026a41086a220a2008290300370300200520052903e80137038802200541f8026a200641d0006a108e02200528028003211120052802fc02212b20052802f802212e201e2010290300370300201d200d290300370300201c200a29030037030020052005290388023703b8032017100c2208290000212d2018200841086a2900003703002005202d3703a802200810234191d0c000ad4280808080800284100c2208290000212d201a200841086a2900003703002005202d3703b80220081023200520123602a80320052021100d22082900003703e00320081023200541003a0088032005202336028403200520033602fc022005200541a8036a360280032005200541e0036a3602f802200541f0036a200541f8026a106502400240024020052802f803220441206a220a417f4c0d0020052802f003210602400240200a450d00200a1021220d450d09200a410f4d0d01200a21100c040b4110211041101021220d0d030c070b200a41017422084110200841104b1b221041004e0d010c050b1032000b0240200a2010470d00200a21100c010b200d200a20101025220d450d040b200d20052903a802370000200d41086a20182903003700000240024020104170714110460d00201021080c010b201041017422084120200841204b1b22084100480d0320102008460d00200d201020081025220d450d040b200d20052903b802370010200d41186a201a29030037000002400240200841606a2004490d002008210e0c010b2004415f4b0d0320084101742210200a2010200a4b1b220e4100480d032008200e460d00200d2008200e1025220d450d040b200b20097c2209200b542108200d41206a2006200410a1051a024020052802f403450d00200610230b202520197c210b2008ad2119200541f8026a200d200a10e8010240024020052802f80222100d0041002106200541003602c002200542083703b80241082110410021040c010b200520052902fc0222253702bc02200520103602b8022025422088a721042025a721060b200b20197c210b2015201e2903003703002016201d290300370300200f201c290300370300200520052903b8033703f802024020042006470d00200541b8026a2004410110a90120052802bc02210620052802b802211020052802c00221040b2010200441d8006c222a6a2208200937031020082026370308200820273703002008202e36022c2008200c360220200841186a200b370300200841346a2011360200200841306a202b360200200841246a2029370200200841386a20052903f802370200200841c0006a200f290300370200200841c8006a2016290300370200200841d0006a20152903003702002005200441016a22083602c0020240024020100d00200aad422086200dad8410110c010b200541f8026a2010200810f501200aad422086200dad8420053502800342208620052802f802220aad84100e024020052802fc02450d00200a10230b02402008450d00201041306a2108202a41d8006a210a03400240200841746a280200220c450d00200c41306c450d00200841706a28020010230b0240200828020041ffffff3f71450d002008417c6a28020010230b200841d8006a2108200a41a87f6a220a0d000b0b02402006450d00200641d8006c450d00201010230b200e450d010b200d10230b200141e0006a21012024201f490d000b410021100c040b102c000b102a000b1033000b41002110200b42ffffffff0183500d00200d10230b20054180046a240020100bb40201067f230041d0006b220224002002412036020420022001360200200241086a2001ad42808080808004841010108b0102400240200228020822030d00410221010c010b200228020c210402400240200241106a2802002205450d0020032d0000220641014b0d0041002101024020060e020200020b2005417f6a4104490d0020032800012107410121010c010b20024100360220200242013703182002410a36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c20024180c5c6003602382002200241286a360248200241346a4184a5c200200241386a10311a2002350220422086200235021884100a0240200228021c450d00200228021810230b410221010b2004450d00200310230b2000200736020420002001360200200241d0006a24000bbe0201017f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841010108b0102400240200328021022010d00200041003602000c010b200328021421022003200341106a41086a28020036022420032001360220200341c8006a200341206a10cf010240024020032802480d0020034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034180c5c6003602482003200341386a360258200341c4006a4184a5c200200341c8006a10311a2003350230422086200335022884100a0240200328022c450d00200328022810230b200041003602000c010b20002003290348370200200041086a200341c8006a41086a2802003602000b2002450d00200110230b200341e0006a24000b8f0301067f230041106b220224002002410036020820024201370300200028020021030240410410212204450d002004200336000020024284808080c000370204200220043602002000280204210320044104410810252204450d0020042003360004200242888080808001370204200220043602002000280208210320044108411010252204450d002004200336000820024290808080c00137020420022004360200200028020c2105200041146a28020022002002106102400240024020022802042206200228020822046b20004102742203490d0020022802002100200621070c010b200420036a22002004490d01200641017422072000200720004b1b22074100480d010240024020060d00024020070d00410121000c020b2007102122000d010c040b2002280200210020062007460d0020002006200710252200450d030b20022007360204200220003602000b200020046a2005200310a1051a2001290200200420036aad4220862000ad84100e02402007450d00200010230b200241106a24000f0b102c000b102a000bbd0101057f2001280208210302402001410c6a280200220420024b0d002000410036020820002004ad4220862003ad843702000f0b024002402001411c6a2802002205450d00200141146a2802002101200541027421062003417f6a2103034002402004200128020022076b220520024b0d00200420024b0d030b200141046a21012003417f6a2103200521042006417c6a22060d000b0b200041023602080f0b2000200736020c2000410136020820002005ad4220862003ad843702000bee0f07047f017e047f017e047f017e017f23004190016b22012400200141e8006a41186a4200370300200141e8006a41106a22024200370300200141e8006a41086a220342003703002001420037036841db97c700ad4280808080f00084100c220429000021052003200441086a290000370300200120053703682004102341bbacc300ad4280808080a00184100c22042900002105200141c8006a41086a2206200441086a2900003703002001200537034820041023200220012903482205370300200141286a41086a2003290300370300200141286a41106a2005370300200141286a41186a200629030037030020012001290368370328200141e8006a200141286a412010890220012802682203410120031b210741022108024002400240200129026c420020031b2205422088a72203450d002003410574210241002104200721030240034020002003460d01200420032000412010a30522064100476a21042006450d01200341206a2103200241606a22020d000c020b0b200141e8006a41186a4200370300200141e8006a41106a22094200370300200141e8006a41086a220042003703002001420037036841db97c700ad4280808080f00084100c2202290000210a200141c8006a41086a2203200241086a2900003703002001200a37034820021023200020032903003703002001200129034837036841c0bdc300ad4280808080a00284100c2202290000210a2003200241086a2900003703002001200a3703482002102320092001290348220a370300200141286a41086a2000290300370300200141286a41106a200a370300200141286a41186a200329030037030020012001290368370328200141186a200141286a10ed030240024002402001280218220b0d004100210c20014100360210200142043703084104210b4100210d410021030c010b200129021c210a2001200b3602082001200a37020c200aa7210d4100210302400240200a422088a7220c41014b0d00200c0e020201020b200c2100034020032000410176220220036a22062004200b20064102746a280200491b2103200020026b220041014b0d000b0b4100210802402004200b20034102746a2802002200470d00410021060c020b2003200420004b6a21030b200141e8006a41186a22084200370300200141e8006a41106a220e4200370300200141e8006a41086a220242003703002001420037036841db97c700ad4280808080f00084100c2206290000210a200141c8006a41086a2200200641086a2900003703002001200a37034820061023200220002903003703002001200129034837036841bbacc300ad4280808080a00184100c2206290000210a2000200641086a2900003703002001200a3703482006102320092001290348370000200941086a2000290300370000200141286a41086a2002290300370300200141286a41106a200e290300370300200141286a41186a200829030037030020012001290368370328200141186a200141286aad42808080808004841010108b01024002400240024020012802182202450d00200128021c21062001200141186a41086a28020036026c200120023602682001200141e8006a1088012001280200450d01410021000c020b2001420037024c20014101360248200141e8006a200141c8006a108e02200128027041057421000240200128026c41ffffff3f71450d00200128026810230b200041057521000c020b200128020421000b2006450d00200210230b20002000418094ebdc036e22024180ec94a37c6c6aad4280fd87d1007e220f428094ebdc0380210a200c2003490d0220024180fd87d1006c200f200a4280ec94a37c7e7c4280cab5ee015672200aa76a21020240200c200d470d00200141086a200d41011079200128020c210d2001280208210b0b200b20034102746a220041046a2000200c20036b41027410a2051a20002004360200410121062001200c41016a220c360210200c20024b21080b200141e8006a41186a220e4200370300200141e8006a41106a22104200370300200141e8006a41086a220042003703002001420037036841db97c700ad4280808080f00084100c2202290000210a200141c8006a41086a2203200241086a2900003703002001200a37034820021023200020032903003703002001200129034837036841c0bdc300ad4280808080a00284100c2202290000210a2003200241086a2900003703002001200a3703482002102320092001290348370000200941086a2003290300370000200141286a41086a2000290300370300200141286a41106a2010290300370300200141286a41186a200e2903003703002001200129036837032802400240200b0d00200141286aad428080808080048410110c010b2001412036026c2001200141286a360268200b200c200141e8006a10f603200d41ffffffff0371450d00200b10230b2006450d00200141f0006a2004ad37030020014102360268200141e8006a10f7032001410036027020014201370368410110212203450d02200341023a000020012003360268200142818080801037026c20034101410510252203450d02200120033602682003200128027022006a2004360000200141336a200041046a3600002001410536026c2001200129036837002b200141f4006a2001412f6a290000370000200141c28289aa04360069200141023a00682001200129002837006d200141e8006a10f8030b0240200542ffffff3f83500d00200710230b20014190016a240020080f0b2003200c1038000b102a000b9a0d04047f017e027f067e230041d0026b22052400200541c8016a20012002108b0202400240024002400240024020052802d0014102460d0020052802c8012106200541c8016a41086a2001280204220741086a290000370300200541c8016a41106a200741106a290000370300200541c8016a41186a200741186a290000370300200520063602e801200520072900003703c801200541f0016a200541c8016a10c40120052802f0012108200520052802f801220736028402200520083602800220054188026a2007ad4220862008ad841010108b010240024020052802880222070d00420021090c010b200528028c02210a02400240024020054188026a41086a280200220b4110490d00200b4170714110470d010b200541003602a00220054201370398022005410a3602ac02200520054180026a3602a802200520054198026a3602b402200541cc026a4101360200200542013702bc0220054180c5c6003602b8022005200541a8026a3602c802200541b4026a4184a5c200200541b8026a10311a20053502a00242208620053502980284100a0240200528029c02450d0020052802980210230b420021090c010b200741186a290000210c200741086a290000210d2007290010210e2007290000210f420121090b200a450d00200710230b200d4200200942005222071b210d200f420020071b210f024020052802f401450d00200810230b200c420020071b210c200e420020071b210e200f200354200d200454200d2004511b0d01200f200385200d2004858450450d03200541b8016a20032004428094ebdc03420010a705200541a8016a20052903b801220d200541b8016a41086a290300220f4280ec94a37c427f10a60520054198016a200d200f20013502282209420010a60520054188016a4200200529039801220f200920052903a80120037c7e220d428094ebdc03802209a7417f200d428080808080c0b2cd3b541b200d20094280ec94a37c7e7c4280cab5ee01566aad7c220d200e7d22092009200d5620054198016a41086a290300200d200f54ad7c220f200c7d200d200e54ad7d220d200f56200d200f511b22021b220f4200200d20021b428094ebdc03420010a705200541f8006a200529038801220d20054188016a41086a29030022094280ec94a37c427f10a605200541e8006a200d20094280cab5ee01420010a605200541e8006a41086a29030020052903682209200f20052903787c220d420188220fa7417f200d4280cab5ee017e220d428080808080c0b2cd3b541b200d200f4280ec94a37c7e7c4280cab5ee01566aad7c220d200954ad7c210f410021020c020b410021010c040b200541c8006a20032004428094ebdc03420010a705200541d8006a20032004428094ebdc03420010a805200541386a2005290348200541c8006a41086a29030020013502282209420010a605200541286a420020052903382210200920052903587e2209428094ebdc03802211a7417f2009428080808080c0b2cd3b541b200920114280ec94a37c7e7c4280cab5ee01566aad7c2209200e7d22112011200956200541386a41086a2903002009201054ad7c2210200c7d2009200e54ad7d220920105620092010511b22071b22104200200920071b428094ebdc03420010a705200541186a20052903282209200541286a41086a29030022114280ec94a37c427f10a605200541086a200920114280cab5ee01420010a605200128022422072003200f7d220920072903007c2211370300200741086a22072004200d7d2003200f54ad7d20072903007c2011200954ad7c370300200141106a2207200728020022072002200720024b1b360200200541086a41086a2903002005290308220f201020052903187c220d4201882209a7417f200d4280cab5ee017e220d428080808080c0b2cd3b541b200d20094280ec94a37c7e7c4280cab5ee01566aad7c220d200f54ad7c210f410121020b02400240200d200f84500d002001280220220220022903002209200d7c2210370300200241086a22022002290300200f7c2010200954ad7c370300200c200f7c200e200d7c220d200e54ad7c210c200d210e0c010b2002450d010b200141013a002c200541b8026a200541c8016a10c40120053502c002210d20052802b8022102411010212201450d01200120033700002001200437000820014110412010252201450d012001200e370010200141186a200c370000200d4220862002ad842001ad4280808080800484100e2001102320052802bc02450d00200210230b410121010c010b102a000b2000200636020420002001360200200541d0026a24000ba10201087f230041106b22022400024002402001280208220341ffffff3f712003470d0020034105742204417f4c0d00200128020021050240024020040d00410121060c010b200410212206450d020b41002101200241003602082002200636020020022004410576360204200241002003109a012002280208210702402003450d0020034105742108200228020020074105746a21090340200920016a2204200520016a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002008200141206a2201470d000b200341057441606a41057620076a41016a21070b20002002290300370200200041086a2007360200200241106a24000f0b1032000b1033000be70403057f017e037f23004180016b22022400200241206a41186a22034200370300200241206a41106a22044200370300200241206a41086a2205420037030020024200370320418fcdc200ad4280808080f00084100c220629000021072005200641086a290000370300200220073703202006102341b8dbc100ad4280808080900184100c22062900002107200241086a2208200641086a2900003703002002200737030020061023200420022903002207370300200241e0006a41086a22062005290300370300200241e0006a41106a22092007370300200241e0006a41186a220a200829030037030020022002290320370360200241206a200241e0006a10ba010240024020022903204202520d00200041003602200c010b200241d0006a2004280200200110da01200241206a200228025022082002280258109002200a2003290300370300200920042903003703002006200529030037030020022002290320370360200241cc006a280200210402400240200228024022050d0042002107200241186a4200370300200241106a420037030041082105200241086a4200370300200242003703000c010b200241086a200241e0006a41086a290300370300200241106a200241e0006a41106a290300370300200241186a200241e0006a41186a29030037030020022002290360370300200229024421070b02402002280254450d00200810230b2000200229030037030020002007370224200020053602202000412c6a2004360200200041186a200241186a290300370300200041106a200241106a290300370300200041086a200241086a2903003703000b20024180016a24000b860301017f230041f0006b220324002003200236020420032001360200200341086a2002ad4220862001ad841010108b0102400240200328020822010d00200041003602200c010b200328020c21022003200341086a41086a28020036024c20032001360248200341186a200341c8006a10d0010240024020032802380d0020034100360258200342013703502003410a360264200320033602602003200341d0006a36026c2003412c6a41013602002003420137021c20034180c5c6003602182003200341e0006a360228200341ec006a4184a5c200200341186a10311a2003350258422086200335025084100a02402003280254450d00200328025010230b200041003602200c010b20002003290318370300200041286a200341186a41286a290300370300200041206a200341186a41206a290300370300200041186a200341186a41186a290300370300200041106a200341186a41106a290300370300200041086a200341186a41086a2903003703000b2002450d00200110230b200341f0006a24000bc00908057f047e027f027e067f017e037f017e230041e0016b22032400200241386a2802002104200241346a2802002105200241306a2802002106200341c0006a41186a200241186a290000370300200341c0006a41106a200241106a290000370300200341c0006a41086a200241086a290000370300200320022900003703404100210720034100360268200342083703600240024020040d0042002108420021094200210a4200210b0c010b200441306c210c200341b0016a41106a21044108210d42002108420021094200210a4200210b200621020340200241286a290300210e200241206a290300210f200341f0006a41186a2210200241186a290300370300200341f0006a41106a2211200241106a290300370300200341f0006a41086a2212200241086a29030037030020032002290300370370200341b0016a41186a2213420037030020044200370300200341b0016a41086a22144200370300200342003703b00141bdadc500ad4280808080800184100c221529000021162014201541086a290000370300200320163703b0012015102341c5adc500ad4280808080d00184100c22152900002116200341d0016a41086a2217201541086a290000370300200320163703d00120151023200420032903d001370000200441086a201729030037000020034190016a41086a2215201429030037030020034190016a41106a2217200429030037030020034190016a41186a22182013290300370300200320032903b00137039001200341286a20034190016a412010d701200341186a2003290330200341286a41106a290300427f420010a705200341086a20032903184200200328022822191b221642012016420156200341186a41086a290300420020191b22164200522016501b22191b2016420020191b200f200e10a6052018201029030037030020172011290300370300201520122903003703002003200329037037039001200341086a41086a29030021162003290308210e0240024020034190016a200341c0006a412010a305450d0020132018290300370300200420172903003703002014201529030037030020032003290390013703b001024020072003280264470d00200341e0006a2007410110a4012003280260210d200328026821070b200d200741306c6a221520163703082015200e370300201520032903b001370310201541186a2014290300370300201541206a2004290300370300201541286a20132903003703002003200741016a22073602680c010b427f200920167c2008200e7c221a2008542214ad7c220f2014200f200954200f2009511b22141b2109427f201a20141b21080b200241306a2102427f200b20167c200a200e7c2216200a542214ad7c220a2014200a200b54200a200b511b22141b210b427f201620141b210a200c41506a220c0d000b0b02402005450d00200541306c450d00200610230b2000200a37032020002003290340370000200041386a2009370300200041306a2008370300200041286a200b370300200041c0006a2003290360370200200041186a200341c0006a41186a290300370000200041106a200341c0006a41106a290300370000200041086a200341c0006a41086a290300370000200041c8006a200341e0006a41086a280200360200200341e0016a24000bfd1002057f047e230041d0016b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220341174b0d0020030e180102030405060708090a0b0c0d0e0f101112131415161718010b41f58ac7004128418c94c700102d000b200041013a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000c170b200041023a0000200041106a200141106a290300370300200041086a200141086a2903003703000c160b200041033a0000200041106a200141106a290300370300200041086a200141086a2903003703000c150b200041043a00000c140b200041053a0000200041046a200141046a2802003602000c130b200241106a200141046a108e02200041063a00002000410c6a200241186a280200360200200041046a20022903103702000c120b200041073a00000c110b200041083a0000200020012d00013a00010c100b200041093a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c0f0b2000410a3a0000200041046a200141046a2802003602000c0e0b2000410b3a00000c0d0b2000410c3a00000c0c0b200241106a200141046a108e022000410d3a00002000410c6a200241186a280200360200200041046a20022903103702000c0b0b2000410e3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c0a0b2000410f3a00000c090b200141106a280200220341ffffffff03712003470d0920034102742204417f4c0d09200141046a2802002105200141086a28020021064104210102402004450d00200410212201450d0b0b200241003602182002200136021020022004410276360214200241106a4100200310792002280210200228021822014102746a2006200341027410a1051a200241086a200120036a2201360200200220022903102207370300200041046a2005360200200041086a2007370200200041106a2001360200200041103a00000c080b200141106a2802002203ad42247e2207422088a70d082007a72204417f4c0d08200141046a2802002106200141086a28020021010240024020040d00410421050c010b200410212205450d0a0b20024100360218200220053602102002200441246e360214200241106a4100200310a2012002280218210402402003450d00200341246c21052002280210200441246c6a21030340200141086a2902002107200141106a2902002108200141186a29020021092001290200210a200341206a200141206a280200360200200341186a2009370200200341106a2008370200200341086a20073702002003200a370200200341246a2103200441016a2104200141246a21012005415c6a22050d000b0b200241086a2004360200200220022903102207370300200041046a2006360200200041086a2007370200200041106a2004360200200041113a00000c070b200041123a0000200041046a200141046a2802003602000c060b200041133a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c050b200041143a0000200041106a200141106a290300370300200041086a200141086a2903003703000c040b200041153a0000200041046a200141046a2802003602000c030b200041163a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c020b2001410c6a280200220320036a22042003490d022004417f4c0d02200141046a28020021050240024020040d00410221060c010b200410212206450d040b200241003602182002200636021020022004410176360214200241106a41002003109c012002280210200228021822044101746a2005200341017410a1051a200241086a2205200420036a36020020022002290310370300200241106a200141106a109302200041046a20022903003702002000410c6a200528020036020020012802d0012103200041106a200241106a41c00110a1051a200041d0016a2003360200200041173a000020004180026a200141d8016a220141286a290300370300200041f8016a200141206a290300370300200041f0016a200141186a290300370300200041e8016a200141106a290300370300200041e0016a200141086a290300370300200041d8016a20012903003703000c010b2001410c6a280200220320036a22042003490d012004417f4c0d01200141046a28020021050240024020040d00410221060c010b200410212206450d030b200241003602182002200636021020022004410176360214200241106a41002003109c012002280210200228021822044101746a2005200341017410a1051a200241086a2205200420036a36020020022002290310370300200241106a200141106a109302200041046a20022903003702002000410c6a200528020036020020012802d0012103200041106a200241106a41c00110a1051a200041d0016a2003360200200041183a000020004180026a200141d8016a220141286a290300370300200041f8016a200141206a290300370300200041f0016a200141186a290300370300200041e8016a200141106a290300370300200041e0016a200141086a290300370300200041d8016a20012903003703000b200241d0016a24000f0b1032000b1033000bc11702057f017e23004180026b22022400024002402001280208220341ffffffff01712003470d0020034103742204417f4c0d00200128020021050240024020040d00410421060c010b200410212206450d020b200241003602f801200220063602f001200220044103763602f401200241f0016a4100200310a50120022802f00120022802f80122044103746a2005200341037410a1051a200041086a200420036a360200200020022903f001370200200141146a2802002204ad420c7e2207422088a70d002007a72203417f4c0d00200128020c21064104210502402003450d00200310212205450d020b200241003602f801200220053602f00120022003410c6e3602f401200241f0016a4100200410950120022802f00120022802f8012205410c6c6a2006200310a1051a200241086a200520046a360200200220022903f001370300200141206a280200220341ffffffff00712003470d0020034104742204417f4c0d00200128021821064104210502402004450d00200410212205450d020b200241003602f801200220053602f001200220044104763602f401200241f0016a4100200310a00120022802f00120022802f80122044104746a2006200341047410a1051a200241186a200420036a360200200220022903f0013703102001412c6a2802002204ad42147e2207422088a70d002007a72203417f4c0d00200128022421050240024020030d00410421060c010b200310212206450d020b200241003602f801200220063602f0012002200341146e3602f401200241f0016a41002004109e0120022802f00120022802f801220641146c6a2005200310a1051a200241286a200620046a360200200220022903f001370320200141386a2802002204ad42187e2207422088a70d002007a72203417f4c0d00200128023021050240024020030d00410421060c010b200310212206450d020b200241003602f801200220063602f0012002200341186e3602f401200241f0016a4100200410b00120022802f00120022802f801220641186c6a2005200310a1051a200241386a200620046a360200200220022903f001370330200141c4006a2802002204ad421c7e2207422088a70d002007a72203417f4c0d00200128023c21050240024020030d00410421060c010b200310212206450d020b200241003602f801200220063602f00120022003411c6e3602f401200241f0016a4100200410a30120022802f00120022802f8012206411c6c6a2005200310a1051a200241c8006a200620046a360200200220022903f001370340200141d0006a280200220341ffffff3f712003470d0020034105742204417f4c0d00200128024821050240024020040d00410421060c010b200410212206450d020b200241003602f801200220063602f001200220044105763602f401200241f0016a4100200310a80120022802f00120022802f80122044105746a2005200341057410a1051a200241d8006a200420036a360200200220022903f001370350200141dc006a2802002204ad42247e2207422088a70d002007a72203417f4c0d00200128025421050240024020030d00410421060c010b200310212206450d020b200241003602f801200220063602f0012002200341246e3602f401200241f0016a4100200410a20120022802f00120022802f801220641246c6a2005200310a1051a200241e8006a200620046a360200200220022903f001370360200141e8006a2802002204ad42287e2207422088a70d002007a72203417f4c0d00200128026021050240024020030d00410421060c010b200310212206450d020b200241003602f801200220063602f0012002200341286e3602f401200241f0016a4100200410aa0120022802f00120022802f801220641286c6a2005200310a1051a200241f8006a200620046a360200200220022903f001370370200141f4006a2802002204ad422c7e2207422088a70d002007a72203417f4c0d00200128026c21050240024020030d00410421060c010b200310212206450d020b200241003602f801200220063602f00120022003412c6e3602f401200241f0016a4100200410a60120022802f00120022802f8012206412c6c6a2005200310a1051a20024188016a200620046a360200200220022903f0013703800120014180016a2802002204ad42307e2207422088a70d002007a72203417f4c0d00200128027821050240024020030d00410421060c010b200310212206450d020b200241003602f801200220063602f0012002200341306e3602f401200241f0016a4100200410b60120022802f00120022802f801220641306c6a2005200310a1051a20024198016a200620046a360200200220022903f001370390012001418c016a2802002204ad42347e2207422088a70d002007a72203417f4c0d0020012802840121050240024020030d00410421060c010b200310212206450d020b200241003602f801200220063602f0012002200341346e3602f401200241f0016a4100200410a70120022802f00120022802f801220641346c6a2005200310a1051a200241a8016a200620046a360200200220022903f0013703a00120014198016a2802002204ad42387e2207422088a70d002007a72203417f4c0d0020012802900121050240024020030d00410421060c010b200310212206450d020b200241003602f801200220063602f0012002200341386e3602f401200241f0016a4100200410ae0120022802f00120022802f801220641386c6a2005200310a1051a200241b8016a200620046a360200200220022903f0013703b001200141a4016a2802002204ad423c7e2207422088a70d002007a72203417f4c0d00200128029c0121050240024020030d00410421060c010b200310212206450d020b200241003602f801200220063602f00120022003413c6e3602f401200241f0016a4100200410b70120022802f00120022802f8012206413c6c6a2005200310a1051a200241c8016a200620046a360200200220022903f0013703c001200141b0016a280200220341ffffff1f712003470d0020034106742204417f4c0d0020012802a80121050240024020040d00410421060c010b200410212206450d020b200241003602f801200220063602f001200220044106763602f401200241f0016a4100200310b30120022802f00120022802f80122044106746a2005200341067410a1051a200241d8016a200420036a360200200220022903f0013703d001200141bc016a2802002204ad42c4007e2207422088a70d002007a72203417f4c0d0020012802b40121010240024020030d00410421050c010b200310212205450d020b200241003602f801200220053602f0012002200341c4006e3602f401200241f0016a41002004109b0120022802f00120022802f801220541c4006c6a2001200310a1051a200241e0016a41086a2201200520046a360200200220022903f0013703e001200041146a200241086a2802003602002000200229030037020c20002002290310370218200041206a200241106a41086a280200360200200020022903203702242000412c6a200241206a41086a28020036020020002002290330370230200041386a200241306a41086a280200360200200041c4006a200241c0006a41086a2802003602002000200229034037023c200041d0006a200241d0006a41086a28020036020020002002290350370248200041dc006a200241e0006a41086a28020036020020002002290360370254200041e8006a200241f0006a41086a28020036020020002002290370370260200041f4006a20024180016a41086a280200360200200020022903800137026c20004180016a20024190016a41086a28020036020020002002290390013702782000418c016a200241a0016a41086a280200360200200020022903a0013702840120004198016a200241b0016a41086a280200360200200020022903b00137029001200041a4016a200241c0016a41086a280200360200200020022903c00137029c01200041b0016a200241d0016a41086a280200360200200020022903d0013702a801200041bc016a2001280200360200200020022903e0013702b40120024180026a24000f0b1032000b1033000b92cb0206027f037e237f067e027f037e230041900b6b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e19000102030405060708090a0b0c0d0e0f101112131415161718000b200341e4096a4101360200200342013702d409200341a4c5c6003602d009200341043602c406200341cccec6003602c0062003200341c0066a3602e009200341d0096a419ca8c700103a000b410221040240024020022d00000d0020022d00014101470d00200141306a2903002105200141286a2903002106200141196a2900002107200141186a2d00002108200141176a2d00002109200141156a2f0000210a200141146a2d0000210b200141136a2d0000210c200141116a2f0000210d200141106a2d0000210e2001410f6a2d0000210f2001410d6a2f000021102001410c6a2d000021112001410b6a2d00002112200141096a2f00002113200141086a2d00002114200141076a2d00002115200141056a2f00002116200141046a2d00002117200141036a2d00002118200141216a2d0000211920012f0001211a200241196a2d00002101200241186a2d00002104200241166a2f0100211b200241156a2d0000211c200241146a2d0000211d200241126a2f0100211e200241116a2d0000211f200241106a2d000021202002410e6a2f010021212002410d6a2d000021222002410c6a2d000021232002410a6a2f01002124200241096a2d00002125200241086a2d00002126200241066a2f01002127200241056a2d00002128200241046a2d00002129200241026a2f0100212a20032002411a6a2901003703b809200320013a00b709200320043a00b6092003201b3b01b4092003201c3a00b3092003201d3a00b2092003201e3b01b0092003201f3a00af09200320203a00ae09200320213b01ac09200320223a00ab09200320233a00aa09200320243b01a809200320253a00a709200320263a00a609200320273b01a409200320283a00a309200320293a00a2092003202a3b01a009200341d0096a200341a0096a10c701200341206a20032802d009220220032802d809419ca8c70041004100108c0120032802202101024020032802d409450d00200210230b024020014101470d0041b7c1c0002101410d21024103210441808008211b0c020b200320073703d806200320083a00d706200320093a00d6062003200a3b01d4062003200b3a00d3062003200c3a00d2062003200d3b01d0062003200e3a00cf062003200f3a00ce06200320103b01cc06200320113a00cb06200320123a00ca06200320133b01c806200320143a00c706200320153a00c606200320163b01c406200320173a00c306200320183a00c2062003201a3b01c006200341d0096a200341c0066a10c601200341186a20032802d009220220032802d809419ca8c70041004100108c0120032802182101024020032802d409450d00200210230b024020014101470d00410d210241aac1c00021014180800c211b410321040c020b024020064280c8afa0255441002005501b450d004111210241eec0c00021014180801c211b410321040c020b200341d0096a200341a0096a10c70120033502d809210720032802d0092102412010212201450d19200120032903c006370000200141186a200341c0066a41186a290300370000200141106a200341c0066a41106a290300370000200141086a200341c0066a41086a29030037000020074220862002ad842001ad4280808080800484100e20011023024020032802d409450d00200210230b200341d0096a200341a0096a10950220033502d809210720032802d009210202400240201941037122014103470d00410121014200212b410121040c010b024002400240024020010e03000102000b410021040c020b410121040c010b410221040b200320043a008008410110212201450d45200120043a000041002104428080808010212b0b20074220862002ad84202b2001ad84100e024020040d00200110230b024020032802d409450d00200210230b200341a0096a109602418fcdc200ad4280808080f000842207100c220128000021022001290004212b200128000c210420011023418cdbc100ad4280808080a00184100c2201290000212c2001290008212d200110232003202d3701e8092003202c3701e009200320043601dc092003202b3701d409200320023601d009200341106a200341d0096a412010cd0120032802142102200328021021042007100c2201280000211b20012900042107200128000c211c200110234190d8c100ad4280808080c00184100c2201290000212b2001290008212c200110232003202c3701e8092003202b3701e0092003201c3601dc09200320073701d4092003201b3601d009200341086a200341d0096a412010cd01200328020c21012003280208211b20034180086a200341a0096a109702200341d0096a200328028008221c20032802880810980241002002410020041b2204200141d400201b1b6b2201200120044b1b2101200341d0096a41106a290300420020032903d00942015122021b210720032903d809420020021b212b0240200328028408450d00201c10230b200341d0096a41086a41043a0000200341d9096a20032903a009370000200341e1096a200341a0096a41086a2202290300370000200341e9096a200341a0096a41106a221b290300370000200341f1096a200341a0096a41186a221c290300370000200341880a6a221d20072005202b200654200720055420072005511b221e1b2205370300200341800a6a202b2006201e1b2206370300200341033a00d009200341d0096a10e00120022f0100211e201b2f0100211f201c290300210720032f01a009212020032d00a209212120032d00a309212220032f01a409212320032d00a609212420032d00a709212520032d00aa09212620032d00ab09212720032f01ac09212820032d00ae09212920032d00af09212a20032d00b209210820032d00b309210920032f01b409210a20032d00b609210b20032d00b709210c2003410036028808200342043703800820034180086a41004100200420016b221c201c20044b1b1079200328028808211b0240200420014d0d00200328028008201b4102746a2102034020022001360200200241046a21022004200141016a2201470d000b201c201b6a211b0b200341d8086a41086a2201201b360200200341a00a6a20073703002003419f0a6a200c3a00002003419e0a6a200b3a00002003419c0a6a200a3b01002003419b0a6a20093a00002003419a0a6a20083a0000200341980a6a201f3b0100200341970a6a202a3a0000200341960a6a20293a0000200341940a6a20283b0100200341930a6a20273a0000200341920a6a20263a0000200341900a6a201e3b01002003418f0a6a20253a00002003418e0a6a20243a00002003418c0a6a20233b01002003418b0a6a20223a00002003418a0a6a20213a000020032003290380083703d808200320203b01880a200341d0096a41186a2005370300200341f8096a4100360200200341840a6a2001280200360200200320063703e009200320053703d809200320063703d009200342083703f009200320032903d8083702fc09200342f3e885db96cddbb3203703b008200341b0086a201d20062005411f10990220034180086a200341c0066a10c601200328028008210120032003280288083602dc08200320013602d808200341d0096a200341d8086a10ec010240200328028408450d00200110230b024020032802f4092201450d00200141186c450d0020032802f00910230b200341800a6a28020041ffffffff0371450d4920032802fc0910230c490b4100211b0b20004100360204200041146a2002360200200041106a20013602002000410c6a201b4180801c71200472418010723602000c460b410221040240024020022d00000d0020022d00014101470d00200141106a2903002105200141086a2903002107200241196a2d00002104200241186a2d0000211b200241166a2f0100211c200241156a2d0000211d200241146a2d0000211e200241126a2f0100211f200241116a2d00002120200241106a2d000021212002410e6a2f010021222002410d6a2d000021232002410c6a2d000021242002410a6a2f01002125200241096a2d00002126200241086a2d00002127200241066a2f01002128200241056a2d00002129200241046a2d0000212a200241026a2f0100210120032002411a6a29010037039809200320043a0097092003201b3a0096092003201c3b0194092003201d3a0093092003201e3a0092092003201f3b019009200320203a008f09200320213a008e09200320223b018c09200320233a008b09200320243a008a09200320253b018809200320263a008709200320273a008609200320283b018409200320293a0083092003202a3a008209200320013a008009200320014108763a008109200341c0066a20034180096a10c701200341d0096a20032802c006220220032802c80610e10120032802c40621010240024020032d00d0094101470d00200341e9096a2900002106200341e8096a2d00002104200341e7096a2d0000211b200341e5096a2f0000211c200341e4096a2d0000211d200341e3096a2d0000211e200341e1096a2f0000211f200341e0096a2d00002120200341df096a2d00002121200341dd096a2f00002122200341dc096a2d00002123200341db096a2d00002124200341d9096a2f00002125200341d0096a41086a2d0000212620032d00d709212720032f00d509212820032d00d409212920032d00d309212a20032d00d209210820032d00d109210902402001450d00200210230b200320063703b809200320043a00b7092003201b3a00b6092003201c3b01b4092003201d3a00b3092003201e3a00b2092003201f3b01b009200320203a00af09200320213a00ae09200320223b01ac09200320233a00ab09200320243a00aa09200320253b01a809200320263a00a709200320273a00a609200320283b01a409200320293a00a3092003202a3a00a209200320083a00a109200320093a00a009200341a0066a200341a0096a10c601200341d0096a20032802a006220420032802a80610e20120034180086a41086a221b2003418c0a6a29020037030020034180086a41106a221c200341940a6a29020037030020034180086a41186a221d2003419c0a6a29020037030020034180086a41206a221e200341a40a6a2802003602002003200341840a6a29020037038008024020032802f0092202450d00200341d0096a41186a290300212e200341d0096a41086a290300212d200341800a6a280200211f200341fc096a2802002120200341f8096a280200212120032903e009212f20032903d009210620032802f4092101200341d8086a41206a201e280200360200200341d8086a41186a201d290300370300200341d8086a41106a201c290300370300200341d8086a41086a201b29030037030020032003290380083703d808024020032802a406450d00200410230b200341b0086a41086a2204200341d8086a41086a290300370300200341b0086a41106a221b200341d8086a41106a290300370300200341b0086a41186a221c200341d8086a41186a290300370300200341b0086a41206a221d200341d8086a41206a280200360200200341c0066a41186a202e370300200341f0066a201f360200200341e8066a2021360200200341e4066a2001360200200320032903d8083703b0082003202f3703d006200320063703c006200320203602ec06200320023602e0062003202d3703c80620034194076a201d2802003602002003418c076a201c29030037020020034184076a201b290300370200200341fc066a2004290300370200200341f4066a20032903b00837020020034180086a20034180096a109702200341d0096a200328028008221b200328028808109802200341d0096a41106a290300420020032903d00942015122041b212b20032903d809420020041b212c0240200328028408450d00201b10230b202c20067d2230202c56202b202d7d202c200654ad7d222c202b56202c202b511b0d022003202f200720302030200756202c200556202c2005511b22011b22077c222b3703d006200341c0066a41186a202e2005202c20011b22057c202b202f54ad7c3703002003200720067c22063703c00620032005202d7c2006200754ad7c222b3703c806200341d0096a41386a2005370300200341800a6a2007370300200341d0096a41086a41043a0000200341d9096a200329038009370000200341e1096a20034180096a41086a290300370000200341e9096a20034190096a290300370000200341f1096a20034180096a41186a290300370000200341033a00d009200341d0096a10e001200342f3e885db96cddbb3203703d808200341d8086a200341c0066a41386a2006202b411f109902200341d0096a200341a0096a10c60120032802d0092101200320032802d809360284082003200136028008200341c0066a20034180086a10ec01024020032802d409450d00200110230b024020032802e4062201450d00200141186c450d0020032802e00610230b20032802f00641ffffffff0371450d4b20032802ec0610230c4b0b024020032802a406450d00200410230b41ccc1c0002101410d21024100211b410321040c030b02402001450d00200210230b41c4c1c00021014108210241808004211b410321040c020b02402001450d00200141186c450d00200210230b201f41ffffffff0371450d48202010230c480b4100211b0b20004100360204200041146a2002360200200041106a20013602002000410c6a201b4180800471200472418010723602000c450b410221040240024020022d00000d0020022d00014101470d00200141106a2903002107200141086a290300212b200241196a2d00002101200241186a2d00002104200241166a2f0100211b200241156a2d0000211c200241146a2d0000211d200241126a2f0100211e200241116a2d0000211f200241106a2d000021202002410e6a2f010021212002410d6a2d000021222002410c6a2d000021232002410a6a2f01002124200241096a2d00002125200241086a2d00002126200241066a2f01002127200241056a2d00002128200241046a2d00002129200241026a2f0100212a20032002411a6a2901003703b809200320013a00b709200320043a00b6092003201b3b01b4092003201c3a00b3092003201d3a00b2092003201e3b01b0092003201f3a00af09200320203a00ae09200320213b01ac09200320223a00ab09200320233a00aa09200320243b01a809200320253a00a709200320263a00a609200320273b01a409200320283a00a309200320293a00a2092003202a3b01a00920034180096a200341a0096a10c601200341d0096a200328028009221b20032802880910e20120034180086a41086a221c2003418c0a6a29020037030020034180086a41106a221d200341940a6a29020037030020034180086a41186a221e2003419c0a6a29020037030020034180086a41206a221f200341a40a6a2802003602002003200341840a6a2902003703800802400240024020032802f0092204450d00200341d0096a41186a2903002105200341d0096a41086a290300212c200341800a6a2802002120200341fc096a2802002121200341f8096a280200210120032903e009210620032903d009212d20032802f4092102200341d8086a41206a201f280200360200200341d8086a41186a201e290300370300200341d8086a41106a201d290300370300200341d8086a41086a201c29030037030020032003290380083703d8080240200328028409450d00201b10230b200341b0086a41086a221b200341d8086a41086a290300370300200341b0086a41106a221c200341d8086a41106a290300370300200341b0086a41186a221d200341d8086a41186a290300370300200341b0086a41206a221e200341d8086a41206a280200360200200341c0066a41186a2005370300200341f0066a2020360200200341e8066a2001360200200341e4066a2002360200200320032903d8083703b008200320063703d0062003202d3703c006200320213602ec06200320043602e0062003202c3703c80620034194076a201e2802003602002003418c076a201d29030037020020034184076a201c290300370200200341fc066a201b290300370200200341f4066a20032903b0083702002001411f4d0d0202402002450d00200241186c450d00200410230b41e2c0c0002101410c210241808020211b202041ffffffff0371450d0120211023410321040c040b0240200328028409450d00201b10230b41ccc1c0002101410d21024100211b0b410321040c020b200341c0066a41206a210102402006202b2006202b54200520075420052007511b22021b222b2005200720021b2207844200510d00200341c0066a41186a4200200520077d2006202b54ad7d222c2006202b7d222d4280c8afa025544100202c501b22021b37030020034200202d20021b3703d006418fcdc200ad4280808080f00084100c2204280000211b2004290004212c200428000c211c20041023418cdbc100ad4280808080a00184100c2204290000212d2004290008212f200410232003202f3701e8092003202d3701e0092003201c3601dc092003202c3701d4092003201b3601d009200341286a200341d0096a412010cd012005200720021b21052006202b20021b2106200328022c411c6a411c20032802281b2104024020032802e806220220032802e406470d002001200210b20120032802e80621020b20032802e006200241186c6a220220053703082002200637030020022004360210200320032802e80641016a3602e806200342f3e885db96cddbb3203703d808200341d8086a200341c0066a41386a20032903c006200341c0066a41086a290300411f109902200341d0096a200341a0096a10c60120032802d0092102200320032802d809360284082003200236028008200341c0066a20034180086a10ec01024020032802d409450d00200210230b200341d0096a41386a2005370300200341800a6a2006370300200341d0096a41086a41053a0000200341d9096a20032903f806370000200341e1096a20034180076a290300370000200341e9096a20034188076a290300370000200341f1096a20034190076a290300370000200341033a00d009200341d0096a10e0010b0240200141046a2802002202450d00200241186c450d00200128020010230b20032802f00641ffffffff0371450d4720032802ec0610230c470b4100211b0b20004100360204200041146a2002360200200041106a20013602002000410c6a201b4180803c71200472418010723602000c440b410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f0100211b200241156a2d0000211c200241146a2d0000211d200241126a2f0100211e200241116a2d0000211f200241106a2d000021202002410e6a2f010021212002410d6a2d000021222002410c6a2d000021232002410a6a2f01002124200241096a2d00002125200241086a2d00002126200241066a2f01002127200241056a2d00002128200241046a2d00002129200241026a2f0100212a20032002411a6a29010037039809200320013a009709200320043a0096092003201b3b0194092003201c3a0093092003201d3a0092092003201e3b0190092003201f3a008f09200320203a008e09200320213b018c09200320223a008b09200320233a008a09200320243b018809200320253a008709200320263a008609200320273b018409200320283a008309200320293a0082092003202a3b018009200341a0096a20034180096a10c601200341d0096a20032802a009220120032802a80910e20120034180086a41086a22022003418c0a6a29020037030020034180086a41106a2204200341940a6a29020037030020034180086a41186a221b2003419c0a6a29020037030020034180086a41206a221c200341a40a6a2802003602002003200341840a6a2902003703800802400240024020032802f009221d450d00200341d0096a41186a2903002105200341d0096a41086a290300212c200341800a6a280200211e200341fc096a280200211f200341f8096a280200212020032903e009210620032903d009212d20032802f4092121200341d8086a41206a201c280200360200200341d8086a41186a201b290300370300200341d8086a41106a2004290300370300200341d8086a41086a200229030037030020032003290380083703d808024020032802a409450d00200110230b200341b0086a41086a2201200341d8086a41086a290300370300200341b0086a41106a2202200341d8086a41106a290300370300200341b0086a41186a2204200341d8086a41186a290300370300200341b0086a41206a221b200341d8086a41206a280200360200200341c0066a41186a221c2005370300200341f0066a201e360200200341e8066a2020360200200341e4066a2021360200200320032903d8083703b008200320063703d0062003202d3703c0062003201f3602ec062003201d3602e0062003202c3703c80620034194076a201b2802003602002003418c076a221e200429030037020020034184076a221f2002290300370200200341fc066a22202001290300370200200341f4066a20032903b008370200200341a0096a41186a20034190076a2221290300370300200341a0096a41106a20034188076a2222290300370300200341a0096a41086a20034180076a2223290300370300200320032903f8063703a009418fcdc200ad4280808080f00084100c2201280000210220012900042105200128000c210420011023418cdbc100ad4280808080a00184100c220129000021062001290008210720011023200320073701e809200320063701e009200320043601dc09200320053701d409200320023601d009200341306a200341d0096a412010cd0120032802304101460d01201c290300212f20032903d006212e20032802e80621040c020b024020032802a409450d00200110230b41ccc1c0002102410d2104410321014108211b4100211c0c030b2003280234211b20034180086a41086a200341ec066a221d41086a2802003602002003201d2902003703800820032802e0062124201c290300212f200341fa066a2d00002125200341fb066a2d0000212620202f01002127200341fe066a2d00002128200341ff066a2d0000212920232f0100212320034182076a2d0000212a20034183076a2d00002108201f2f0100210920034186076a2d0000210a20034187076a2d0000210b20222f010021222003418a076a2d0000210c2003418b076a2d0000210d201e2f0100210e2003418e076a2d0000210f2003418f076a2d000021102021290300213020032903d006212e20032f01f806212120032802e406211f202d2105202c210602400240024020032802e8062220450d002024202041186c6a211c202041186c41686a2102202d2105202c2106202421010340200141086a290300212b20012903002107201b200141106a2802002204490d0242002006202b7d2005200754ad7d222b200520077d2207200556202b200656202b2006511b22041b21064200200720041b2105200241686a2102200141186a2201201c470d000b0b410021014108211e0240201f450d00201f41186c450d00202410230b410021040c010b41181021221e450d18201e2007370300201e2004360210201e202b37030820034281808080103702d4092003201e3602d0090240024020020d00410121040c010b200141186a2111202041186c20246a41686a21124101210403402011210102400340200141086a290300212b20012903002107201b200141106a2802002202490d0142002006202b7d2005200754ad7d222b200520077d2207200556202b200656202b2006511b22021b21064200200720021b2105200141186a2201201c470d000c030b0b0240200420032802d409470d00200341d0096a200410b20120032802d009211e0b200141186a2111201e200441186c6a222020023602102020202b370308202020073703002003200441016a22043602d80920122001470d000b0b0240201f450d00201f41186c450d00202410230b20032802d40921010b201d200329038008370200200341d8066a202f370300201d41086a20034180086a41086a2802003602002003202e3703d006200320053703c006200320043602e806200320013602e4062003201e3602e0062003203037039007200320103a008f072003200f3a008e072003200e3b018c072003200d3a008b072003200c3a008a07200320223b0188072003200b3a0087072003200a3a008607200320093b018407200320083a0083072003202a3a008207200320233b018007200320293a00ff06200320283a00fe06200320273b01fc06200320263a00fb06200320253a00fa06200320213b01f806200320063703c8060b024002400240024020040d00202e202f84500d010b200342f3e885db96cddbb3203703d808200341d8086a200341f8066a20032903c006200341c8066a290300411f109902200341d0096a20034180096a10c60120032802d0092101200320032802d809360284082003200136028008200341c0066a20034180086a10ec0120032802d409450d01200110230c010b200341d0096a200341a0096a109a0220032d00d00922014104470d01200342f3e885db96cddbb3203703a006200341a0066a200341a0096a109b020b0240202d20032903c006220658202c200341c0066a41086a290300220558202c2005511b0d00200341800a6a202d20067d370300200341d0096a41086a41063a0000200341d9096a20032903a009370000200341e1096a200341a0096a41086a290300370000200341e9096a200341b0096a290300370000200341f1096a200341b8096a290300370000200341880a6a202c20057d202d200654ad7d370300200341033a00d009200341d0096a10e0010b024020032802e4062201450d00200141186c450d0020032802e00610230b20032802f00641ffffffff0371450d4720032802ec0610230c470b200341d0096a41086a280200210420032802d409210220032f00d10920032d00d30941107472221b41ffffff0771211c024020032802e406221d450d00201d41186c450d0020032802e00610230b201c411076211d201c410876211c20032802f00641ffffffff0371450d0120032802ec0610230c010b0b20004100360204200041146a2004360200200041106a20023602002000410c6a201d411074201c41ff017141087472201b41ff0171724108742001723602000c430b0240024020022d00000d0020022d00014101470d00200141046a2802002104200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d00002127200241086a2d00002128200241066a2f01002129200241056a2d0000212a200241046a2d00002108200241026a2f0100210120032002411a6a2901003703b8092003201b3a00b7092003201c3a00b6092003201d3b01b4092003201e3a00b3092003201f3a00b209200320203b01b009200320213a00af09200320223a00ae09200320233b01ac09200320243a00ab09200320253a00aa09200320263b01a809200320273a00a709200320283a00a609200320293b01a4092003202a3a00a309200320083a00a209200320013a00a009200320014108763a00a10920034180096a200341a0096a10c601200341d0096a200328028009221d20032802880910e20120034180086a41086a221e2003418c0a6a29020037030020034180086a41106a221f200341940a6a29020037030020034180086a41186a22202003419c0a6a29020037030020034180086a41206a2221200341a40a6a2802003602002003200341840a6a29020037038008024020032802f0092202450d00200341d0096a41186a2903002105200341d0096a41086a2903002106200341800a6a280200211b200341fc096a280200211c200341f8096a280200212220032903e009210720032903d009212b20032802f4092101200341d8086a41206a2021280200360200200341d8086a41186a2020290300370300200341d8086a41106a201f290300370300200341d8086a41086a201e29030037030020032003290380083703d8080240200328028409450d00201d10230b200341b0086a41086a221d200341d8086a41086a290300370300200341b0086a41106a221e200341d8086a41106a290300370300200341b0086a41186a221f200341d8086a41186a290300370300200341b0086a41206a2220200341d8086a41206a280200360200200341c0066a41186a2005370300200341f0066a201b360200200341e8066a2022360200200341e4066a2001360200200320032903d8083703b008200320073703d0062003202b3703c0062003201c3602ec06200320023602e006200320063703c80620034194076a20202802003602002003418c076a201f29030037020020034184076a201e290300370200200341fc066a201d290300370200200341f4066a20032903b008370200200341d0096a200341f8066a221d10c50120033502d80942208620032802d009221ead841011024020032802d409450d00201e10230b200341d0096a201d10c30120033502d809210520032802d009211d200341003a0085080240024002400240200441c000490d00200441808001490d012004418080808004490d02200341053a008508200341033a00800820032004360081084280808080d00021060c030b200341013a008508200320044102743a00800842808080801021060c020b200341023a008508200320044102744101723b01800842808080802021060c010b200341043a00850820032004410274410272360280084280808080c00021060b2005422086201dad84200620034180086aad84100e024020032d008508450d00200341003a0085080b024020032802d409450d00201d10230b02402001450d00200141186c450d00200210230b201b41ffffffff0371450d46201c10230c460b0240200328028409450d00201d10230b41831021010c010b41821021010b20004100360204200041146a410d360200200041106a41ccc1c0003602002000410c6a20013602000c420b200141086a280200211c200141046a280200211b4102210420022d00000d3e20022d00014101470d3e2001410c6a2802002101200241196a2d00002104200241186a2d0000211d200241166a2f0100211e200241156a2d0000211f200241146a2d00002120200241126a2f01002121200241116a2d00002122200241106a2d000021232002410e6a2f010021242002410d6a2d000021252002410c6a2d000021262002410a6a2f01002127200241096a2d00002128200241086a2d00002129200241066a2f0100212a200241056a2d00002108200241046a2d00002109200241026a2f0100210a20032002411a6a29010037039809200320043a0097092003201d3a0096092003201e3b0194092003201f3a009309200320203a009209200320213b019009200320223a008f09200320233a008e09200320243b018c09200320253a008b09200320263a008a09200320273b018809200320283a008709200320293a0086092003202a3b018409200320083a008309200320093a0082092003200a3b018009200341a0096a20034180096a10c601200341d0096a20032802a009220220032802a80910e20120034180086a41086a22042003418c0a6a29020037030020034180086a41106a221d200341940a6a29020037030020034180086a41186a221e2003419c0a6a29020037030020034180086a41206a221f200341a40a6a2802003602002003200341840a6a290200370380080240024020032802f0092226450d00200341d0096a41186a2903002105200341d0096a41086a2903002106200341800a6a2802002127200341fc096a2802002128200341f8096a280200212020032903e009210720032903d009212b20032802f4092125200341d8086a41206a201f280200360200200341d8086a41186a201e290300370300200341d8086a41106a201d290300370300200341d8086a41086a200429030037030020032003290380083703d808024020032802a409450d00200210230b200341b0086a41086a2202200341d8086a41086a290300370300200341b0086a41106a2204200341d8086a41106a290300370300200341b0086a41186a221d200341d8086a41186a290300370300200341b0086a41206a221e200341d8086a41206a280200360200200341c0066a41186a2005370300200341f0066a2027360200200341e8066a2020360200200341e4066a2025360200200320032903d8083703b008200320073703d0062003202b3703c006200320283602ec06200320263602e006200320063703c80620034194076a201e2802003602002003418c076a201d29030037020020034184076a2004290300370200200341fc066a2002290300370200200341f4066a20032903b00837020020010d0102402025450d00202541186c450d00202610230b0240202741ffffffff0371450d00202810230b419ec1c000211d410c210241032104410421010c410b024020032802a409450d00200210230b41ccc1c000211d410d210241032104410021010c400b024020014105742202450d00200341d0096a41186a2204201b41186a290000370300200341d0096a41106a221d201b41106a290000370300200341d0096a41086a221e201b41086a2900003703002003201b2900003703d009412010212223450d13202320032903d009370000202341186a2004290300370000202341106a201d290300370000202341086a201e29030037000020034281808080103702840820032023360280080240201b20026a201b41206a2202470d00410121010c3c0b200341a0096a41186a221d200241186a290000370300200341a0096a41106a221e200241106a290000370300200341a0096a41086a221f200241086a290000370300200320022900003703a009200141057421244102210141c0002102410121040340200341d0096a41186a2220201d290300370300200341d0096a41106a2221201e290300370300200341d0096a41086a2222201f290300370300200320032903a0093703d00902402001417f6a2004470d0020034180086a20044101109a0120032802800821230b202320026a41606a220420032903d009370000200441186a2020290300370000200441106a2021290300370000200441086a2022290300370000200320013602880820242002460d3c20014110460d3c201d201b20026a220441186a290000370300201e200441106a290000370300201f200441086a290000370300200320042900003703a009200241206a2102200141016a210120032802840821040c000b0b41002101201c41ffffff3f710d1f0c390b0240024020022d00000d0020022d00014101470d00200241196a2d00002104200241186a2d0000211b200241166a2f0100211c200241156a2d0000211d200241146a2d0000211e200241126a2f0100211f200241116a2d00002120200241106a2d000021212002410e6a2f010021222002410d6a2d000021232002410c6a2d000021242002410a6a2f01002125200241096a2d00002126200241086a2d00002127200241066a2f01002128200241056a2d00002129200241046a2d0000212a200241026a2f0100210120032002411a6a2901003703b809200320043a00b7092003201b3a00b6092003201c3b01b4092003201d3a00b3092003201e3a00b2092003201f3b01b009200320203a00af09200320213a00ae09200320223b01ac09200320233a00ab09200320243a00aa09200320253b01a809200320263a00a709200320273a00a609200320283b01a409200320293a00a3092003202a3a00a209200320013a00a009200320014108763a00a10920034180096a200341a0096a10c601200341d0096a200328028009221c20032802880910e20120034180086a41086a221d2003418c0a6a29020037030020034180086a41106a221e200341940a6a29020037030020034180086a41186a221f2003419c0a6a29020037030020034180086a41206a2220200341a40a6a2802003602002003200341840a6a29020037038008024020032802f0092202450d00200341d0096a41186a2903002105200341d0096a41086a2903002106200341800a6a2802002104200341fc096a280200211b200341f8096a280200212120032903e009210720032903d009212b20032802f4092101200341d8086a41206a2020280200360200200341d8086a41186a201f290300370300200341d8086a41106a201e290300370300200341d8086a41086a201d29030037030020032003290380083703d8080240200328028409450d00201c10230b200341b0086a41086a221c200341d8086a41086a290300370300200341b0086a41106a221d200341d8086a41106a290300370300200341b0086a41186a221e200341d8086a41186a290300370300200341b0086a41206a221f200341d8086a41206a280200360200200341c0066a41186a2005370300200341f0066a2004360200200341e8066a2021360200200341e4066a2001360200200320032903d8083703b008200320073703d0062003202b3703c0062003201b3602ec06200320023602e006200320063703c80620034194076a201f2802003602002003418c076a201e29030037020020034184076a201d290300370200200341fc066a201c290300370200200341f4066a20032903b008370200200341d0096a200341f8066a221c10c30120033502d80942208620032802d009221dad841011024020032802d409450d00201d10230b200341d0096a201c10c50120033502d80942208620032802d009221cad841011024020032802d409450d00201c10230b02402001450d00200141186c450d00200210230b200441ffffffff0371450d44201b10230c440b0240200328028409450d00201c10230b41831021010c010b41821021010b20004100360204200041146a410d360200200041106a41ccc1c0003602002000410c6a20013602000c400b0240024020022d00000d0020022d00014101470d0020012d00012108200241196a2d00002104200241186a2d0000211b200241166a2f0100211c200241156a2d0000211d200241146a2d0000211e200241126a2f0100211f200241116a2d00002120200241106a2d000021212002410e6a2f010021222002410d6a2d000021232002410c6a2d000021242002410a6a2f01002125200241096a2d00002126200241086a2d00002127200241066a2f01002128200241056a2d00002129200241046a2d0000212a200241026a2f0100210120032002411a6a2901003703b809200320043a00b7092003201b3a00b6092003201c3b01b4092003201d3a00b3092003201e3a00b2092003201f3b01b009200320203a00af09200320213a00ae09200320223b01ac09200320233a00ab09200320243a00aa09200320253b01a809200320263a00a709200320273a00a609200320283b01a409200320293a00a3092003202a3a00a209200320013a00a009200320014108763a00a10920034180096a200341a0096a10c601200341d0096a200328028009220220032802880910e20120034180086a41086a221d2003418c0a6a29020037030020034180086a41106a221e200341940a6a29020037030020034180086a41186a221f2003419c0a6a29020037030020034180086a41206a2220200341a40a6a2802003602002003200341840a6a29020037038008024020032802f0092204450d00200341d0096a41186a2903002105200341d0096a41086a2903002106200341800a6a280200211b200341fc096a280200211c200341f8096a280200212120032903e009210720032903d009212b20032802f4092101200341d8086a41206a2020280200360200200341d8086a41186a201f290300370300200341d8086a41106a201e290300370300200341d8086a41086a201d29030037030020032003290380083703d8080240200328028409450d00200210230b200341b0086a41086a2202200341d8086a41086a290300370300200341b0086a41106a221d200341d8086a41106a290300370300200341b0086a41186a221e200341d8086a41186a290300370300200341b0086a41206a221f200341d8086a41206a280200360200200341c0066a41186a2005370300200341f0066a201b360200200341e8066a2021360200200341e4066a2001360200200320032903d8083703b008200320073703d0062003202b3703c0062003201c3602ec06200320043602e006200320063703c80620034194076a201f2802003602002003418c076a201e29030037020020034184076a201d290300370200200341fc066a2002290300370200200341f4066a20032903b008370200200341d0096a200341f8066a10950220033502d809210520032802d009211d02400240200841037122024103470d0041012102420021064101211e0c010b024002400240024020020e03000102000b4100211e0c020b4101211e0c010b4102211e0b2003201e3a008008410110212202450d3f2002201e3a00004100211e42808080801021060b2005422086201dad8420062002ad84100e0240201e0d00200210230b024020032802d409450d00201d10230b02402001450d00200141186c450d00200410230b201b41ffffffff0371450d43201c10230c430b0240200328028409450d00200210230b41831021010c010b41821021010b20004100360204200041146a410d360200200041106a41ccc1c0003602002000410c6a20013602000c3f0b200141196a2900002106200141186a2d00002109200141176a2d0000210a200141156a2f0000210b200141146a2d0000210c200141136a2d0000210d200141116a2f0000210e200141106a2d0000210f2001410f6a2d000021102001410d6a2f000021112001410c6a2d000021122001410b6a2d00002113200141096a2f00002114200141086a2d00002115200141076a2d00002116200141056a2f00002117200141046a2d00002118200141036a2d0000211a200141026a2d0000211920012d000121312002411a6a2901002105200241196a2d00002104200241186a2d0000211b200241166a2f0100211c200241156a2d0000211d200241146a2d0000211e200241126a2f0100211f200241116a2d00002120200241106a2d000021212002410e6a2f010021222002410d6a2d000021232002410c6a2d000021242002410a6a2f01002125200241096a2d00002126200241086a2d00002127200241066a2f01002128200241056a2d00002129200241046a2d0000212a200241026a2f0100210841012101024020022d00000d0020022d000141014721010b200320053701e809200320043a00e7092003201b3a00e6092003201c3b01e4092003201d3a00e3092003201e3a00e2092003201f3b01e009200320203a00df09200320213a00de09200320223b01dc09200320233a00db09200320243a00da09200320253b01d809200320263a00d709200320273a00d609200320283b01d409200320293a00d3092003202a3a00d209200320083b01d0090240024020010d0020034180096a41186a200341d0096a41186a220429010037030020034180096a41106a200341d0096a41106a221b29010037030020034180096a41086a200341d0096a41086a221c290100370300200320032901d00937038009200341c0066a20034180096a10c701200341d0096a20032802c006220220032802c80610e10120032802c40621010240024020032d00d0094101470d00200341e9096a290000210520042d00002104200341e7096a2d0000211d200341e5096a2f0000211e200341e4096a2d0000211f200341e3096a2d00002120200341e1096a2f00002121201b2d0000211b200341df096a2d00002122200341dd096a2f00002123200341dc096a2d00002124200341db096a2d00002125200341d9096a2f00002126201c2d0000211c20032d00d709212720032f00d509212820032d00d409212920032d00d309212a20032d00d209210820032d00d109213202402001450d00200210230b200320053703c808200320043a00c7082003201d3a00c6082003201e3b01c4082003201f3a00c308200320203a00c208200320213b01c0082003201b3a00bf08200320223a00be08200320233b01bc08200320243a00bb08200320253a00ba08200320263b01b8082003201c3a00b708200320273a00b608200320283b01b408200320293a00b3082003202a3a00b208200320083a00b108200320323a00b008200320063703f008200320093a00ef082003200a3a00ee082003200b3b01ec082003200c3a00eb082003200d3a00ea082003200e3b01e8082003200f3a00e708200320103a00e608200320113b01e408200320123a00e308200320133a00e208200320143b01e008200320153a00df08200320163a00de08200320173b01dc08200320183a00db082003201a3a00da08200320193a00d908200320313a00d808200341d0096a200341d8086a10c601200341c0006a20032802d009220220032802d809419ca8c70041004100108c0120032802402101024020032802d409450d00200210230b20014101470d0141aac1c0002104410d211b410321014180900c21020c030b02402001450d00200210230b41c4c1c00021044108211b410321014180900421020c020b200341d8086a200341b0086a412010a305450d41200341d0096a20034180096a10c70120033502d809210520032802d0092102412010212201450d11200120032903d808370000200141186a200341d8086a41186a290300370000200141106a200341d8086a41106a290300370000200141086a200341d8086a41086a29030037000020054220862002ad842001ad4280808080800484100e20011023024020032802d409450d00200210230b200341a0066a200341b0086a10c601200341d0096a20032802a006220220032802a806220410e201024020032802f0092201450d002004ad4220862002ad8410110b200341c0066a41086a22042003418c0a6a290200370300200341c0066a41106a221b200341940a6a290200370300200341c0066a41186a221c2003419c0a6a290200370300200341c0066a41206a221d200341a40a6a2802003602002003200341840a6a2902003703c006200341d0096a41186a2903002105200341d0096a41086a2903002106200341800a6a280200211e200341fc096a280200211f200341f8096a280200212020032903e009210720032903d009212b20032802f409212120034180086a41206a2222201d28020036020020034180086a41186a221d201c29030037030020034180086a41106a221c201b29030037030020034180086a41086a221b2004290300370300200320032903c0063703800802402001450d00200341a0096a41206a2022280200360200200341a0096a41186a201d290300370300200341a0096a41106a201c290300370300200341a0096a41086a201b29030037030020032003290380083703a009024020032802a406450d00200210230b200341d0096a41186a2005370300200341800a6a201e360200200341f8096a2020360200200341f4096a2021360200200341840a6a20032903a0093702002003418c0a6a200341a8096a290300370200200341940a6a200341b0096a2903003702002003419c0a6a200341a0096a41186a290300370200200341a40a6a200341c0096a280200360200200320073703e009200320063703d8092003202b3703d0092003201f3602fc09200320013602f009200341c0066a200341d8086a10c60120032802c0062101200320032802c806360284082003200136028008200341d0096a20034180086a108502024020032802c406450d00200110230b024020032802f4092201450d00200141186c450d0020032802f00910230b20032802800a41ffffffff0371450d4220032802fc0910230c420b20032802a406450d41200210230c410b4102210141801021020b20004100360204200041146a201b360200200041106a20043602002000410c6a20022001723602000c3e0b41002104024020022d000120022d000041004772450d00200041003602042000410c6a41023602000c3e0b200141046a2802002102418fcdc200ad4280808080f00084100c2201280000211b20012900042105200128000c211c2001102341e4d8c100ad4280808080e00184100c220129000021062001290008210720011023200320073701e809200320063701e0092003201c3601dc09200320053701d4092003201b3601d009200320023602c006200341d0096aad4280808080800484200341c0066aad4280808080c00084100e200041003602040c3f0b024020022d000120022d0000410047720d00418fcdc200ad4280808080f00084100c2201280000210220012900042105200128000c21042001102341fcdec100ad4280808080800184100c220129000021062001290008210720011023200320073701e809200320063701e009200320043601dc09200320053701d409200320023601d009200341023a008008410110212201450d39200120032d0080083a0000200341d0096aad42808080808004842001ad42808080801084100e200110230c3e0b200041003602042000410c6a41023602000c3c0b024020022d000120022d0000410047720d00418fcdc200ad4280808080f00084100c2201280000210220012900042105200128000c21042001102341fcdec100ad4280808080800184100c220129000021062001290008210720011023200320073701e809200320063701e009200320043601dc09200320053701d409200320023601d009200341013a008008410110212201450d38200120032d0080083a0000200341d0096aad42808080808004842001ad42808080801084100e200110230c3d0b200041003602042000410c6a41023602000c3b0b200141086a2802002104200141046a280200211b024020022d000120022d0000410047720d002001410c6a2802002102418fcdc200ad4280808080f00084100c2201280000211c20012900042105200128000c211d2001102341bcd9c100ad4280808080d00184100c220129000021062001290008210720011023200320073701e809200320063701e0092003201d3601dc09200320053701d4092003201c3601d009200341203602c4062003200341d0096a3602c006201b2002200341c0066a109c02200441ffffff3f71450d3c201b10230c3c0b0240200441ffffff3f71450d00201b10230b200041003602042000410c6a41023602000c3a0b200341e8096a200141196a290000370300200341d0096a41106a200141116a290000370300200341d0096a41086a200141096a290000370300200320012900013703d00902400240024020022d000120022d0000410047720d00200341c0066a200341d0096a109a0220032d00c00622014104460d0220032f00c10620032d00c306411074722102200341c0066a41086a280200210420032802c406211b0c010b410221010b20004100360204200041146a2004360200200041106a201b3602002000410c6a20024108742001723602000c3a0b200342f3e885db96cddbb3203703a009200341a0096a200341d0096a109b020c3a0b024020022d000120022d0000410047720d00418fcdc200ad4280808080f00084100c2201280000210220012900042105200128000c21042001102341fcdec100ad4280808080800184100c220129000021062001290008210720011023200320073701e809200320063701e009200320043601dc09200320053701d409200320023601d009200341033a008008410110212201450d35200120032d0080083a0000200341d0096aad42808080808004842001ad42808080801084100e200110230c3a0b200041003602042000410c6a41023602000c380b4102211c200141106a280200211d2001410c6a2802002125200141086a2802002124200141046a280200212620022d000121040240024020022d0000220141024b0d00024020010e03000102000b200441ff0171450d010b200420014100477241ff0171450d0041801021010c2f0b4103211c0240201d0d00419ec1c0002104410c21024180901021010c2f0b201d41016a210220242101024003402002417f6a22024102490d01200141046a21042001280200211b200141046a2101201b2004280200490d000b418bc0c0002104411221024180903421010c2f0b200341d0096a202610e701200341c0066a20032802d009220220032802d80910e80120032902c406420020032802c00622011b2105024020032802d409450d00200210230b2001410820011b21230240201d410274221d20246a417c6a2802002005422088a722014f0d0041002102417f21042024211b03402002201b280200221e6a22012005422088a7221f4f0d0b2023200141d8006c6a220128022c212120012802202122200141306a2802002120200141246a280200211c2001200141d8006a2004201f6a201e6b41d8006c10a2051a0240201c450d00201c41306c450d00202210230b0240202041ffffff3f71450d00202110230b201b41046a211b20054280808080707c2105200441016a21042002417f6a2102201d417c6a221d0d000b0240202541ffffffff0371450d00202410230b200341c0066a202610e70120032802c006210120033502c8062106200341d0096a20232005422088a7220210f50120064220862001ad8420033502d80942208620032802d0092204ad84100e024020032802d409450d00200410230b024020032802c406450d00200110230b02402002450d00202341306a21012005422088a741d8006c210203400240200141746a2802002204450d00200441306c450d00200141706a28020010230b0240200128020041ffffff3f71450d002001417c6a28020010230b200141d8006a2101200241a87f6a22020d000b0b2005a72201450d39200141d8006c450d39202310230c390b02402001450d00200141d8006c2102202341306a210103400240200141746a2802002204450d00200441306c450d00200141706a28020010230b0240200128020041ffffff3f71450d002001417c6a28020010230b200141d8006a2101200241a87f6a22020d000b0b41ffc0c0002104411121024180901821012005a7221b450d2e201b41d8006c450d2e202310230c2e0b4102211b2001410c6a2802002104200141086a280200211d024020022d00000d0020022d00014101470d00200241196a2d0000211c200241186a2d0000211f200241166a2f01002120200241156a2d00002121200241146a2d00002122200241126a2f01002123200241116a2d00002124200241106a2d000021252002410e6a2f010021262002410d6a2d000021272002410c6a2d000021282002410a6a2f01002129200241096a2d0000212a200241086a2d00002108200241066a2f01002109200241056a2d0000210a200241046a2d0000210b200241026a2f0100210c200141106a280200211e200141046a280200211b20032002411a6a2901003703c8082003201c3a00c7082003201f3a00c608200320203b01c408200320213a00c308200320223a00c208200320233b01c008200320243a00bf08200320253a00be08200320263b01bc08200320273a00bb08200320283a00ba08200320293b01b8082003202a3a00b708200320083a00b608200320093b01b4082003200a3a00b3082003200b3a00b2082003200c3b01b0080240201e41104d0d00419dc0c0002101411a2102410c211c0c2c0b418fcdc200ad4280808080f00084100c2201280000210220012900042105200128000c211c2001102341f4e5c100ad4280808080a00184100c220129000021062001290008210720011023200320073701e809200320063701e0092003201c3601dc09200320053701d409200320023601d009200341f0016a200341d0096a412010cd0141b7c0c000210141122102410b211c20032802f001450d2b201b20032802f4014f0d2b418fcdc200ad4280808080f00084100c221f2800002120201f2900042105201f28000c2121201f1023418cdbc100ad4280808080a00184100c221f2900002106201f2900082107201f1023200320073701e809200320063701e009200320213601dc09200320053701d409200320203601d009200341e8016a200341d0096a412010cd0120032802e801450d2b201b20032802ec0122204b0d2b418fcdc200ad4280808080f00084100c221f2800002121201f2900042105201f28000c2122201f10234190d8c100ad4280808080c00184100c221f2900002106201f2900082107201f1023200320073701e809200320063701e009200320223601dc09200320053701d409200320213601d009200341e0016a200341d0096a412010cd01201b4100202020032802e40141d40020032802e0011b6b221f201f20204b1b2221490d2b200341d0096a201b10cb01200341c8016a20032802d009222020032802d80910d701200341d8016a290300212b20032903d001210720032802c801211f024020032802d409450d00202010230b201f450d2b200341a0096a200341b0086a10c601200341d0096a20032802a009220220032802a80910e20120034180086a41086a221c2003418c0a6a29020037030020034180086a41106a221f200341940a6a29020037030020034180086a41186a22202003419c0a6a29020037030020034180086a41206a2222200341a40a6a2802003602002003200341840a6a2902003703800802400240024020032802f0092223450d00200341d0096a41186a2903002105200341d0096a41086a2903002106200341800a6a2802002124200341fc096a2802002101200341f8096a280200212520032903e009212c20032903d009212d20032802f4092126200341d8086a41206a2022280200360200200341d8086a41186a2020290300370300200341d8086a41106a201f290300370300200341d8086a41086a201c29030037030020032003290380083703d808024020032802a409450d00200210230b200341c0066a41186a2005370300200341f0066a2024360200200341e8066a2025360200200341e4066a2026360200200341f4066a220220032903d808370200200341fc066a200341e0086a29030037020020034184076a200341e8086a2903003702002003418c076a200341d8086a41186a29030037020020034194076a200341f8086a2802003602002003202c3703d0062003202d3703c006200320013602ec06200320233602e006200320063703c80602402002280200221f0d00410021024100211c0c030b410021024100211c03400240024002402021200128020022204b0d0020020d01410021020c020b200241016a21020c010b201c20026b2222201f4f0d0f200120024102746b2222280200212320222020360200200120233602000b200141046a2101201f201c41016a221c470d000b024002402002450d0020032802f4062221201f20026b2201490d01200320013602f406200121210c010b20032802f40621210b20032802ec0621014100210202400240202141014b0d004100211c20210e020401040b2021211c03402002201c410176221f20026a2220201b200120204102746a280200491b2102201c201f6b221c41014b0d000b0b201b200120024102746a280200221c470d01024020032802e4062201450d00200141186c450d0020032802e00610230b024020032802f00641ffffffff0371450d0020032802ec0610230b41fdbfc0002101410e211c410e21020c2e0b024020032802a409450d00200210230b41ccc1c0002101410d21024100211c0c2d0b20212002201b201c4b6a2202490d0c2021211c0b0240201c20032802f006470d00200341ec066a201c4101107920032802ec0621010b200120024102746a220141046a2001201c20026b41027410a2051a2001201b3602002003201c41016a3602f406200341d0096a200341b0086a10c60120032802d0092101200320032802d8093602a409200320013602a009200341c0066a200341a0096a10ec01024020032802d409450d00200110230b200341d8086a201b109d020240201e41246c22010d00410021270c2b0b201d20016a2225415c6a212a200341f8066a2122201d2102410021270340200221010340200141206a2802002102200341a0096a41186a200141186a290000370300200341a0096a41106a200141106a290000370300200341a0096a41086a200141086a290000370300200320012900003703a009200341d0096a201b200341a0096a10df01200341c0016a20032802d009221c20032802d80910de0120032802c001212320032802c4012124024020032802d409450d00201c10230b20034180086a201b200341a0096a10dd01200341d0096a20032802800822202003280288081090020240024020032802f009221e0d00420021054100211f4108211e4100211c420021060c010b200341d0096a41086a290300210620032903d009210520032802f409211f20032802f809211c0b0240200328028408450d00202010230b02400240201c20024d0d00201e200241306c6a2202450d0002402022200241106a221c460d00201c2022412010a3050d020b2002290300200241086a29030020052006109e0221080240024020032802dc0822260d004100211c0c010b20032802e00821280340202641086a211c20262f010622294105742102410021200240024003402002450d01200341a0096a201c412010a3052221450d02200241606a2102202041016a2120201c41206a211c2021417f4a0d000b2020417f6a21290b024020280d004100211c0c030b2028417f6a2128202620294102746a4194036a28020021260c010b0b202620204102746a41e8026a280200211c0b20032802d80822024101200241014b1b2202418094ebdc036e222020022020418094ebdc036c476a22204101202041014b1b222020024b0d102003418094ebdc033602d40920032002201c2002201c491b20206ead428094ebdc037e200220206ead8042ffffffff0f834100418094ebdc032024410020231b6b22022002418094ebdc034b1bad7e428094ebdc0380a722023602d009200341d0096a2002418094ebdc034b4102746a35020021052003418094ebdc033602d409200320052008ad7e428094ebdc0380a722023602d009200341d0096a2002418094ebdc034b4102746a28020021022003418094ebdc033602d4092003417f202720026a220220022027491b22023602d009200341d0096a2002418094ebdc034b4102746a28020021270b0240201f450d00201f41306c450d00201e10230b200141246a2102202a2001460d2d0c020b200141246a21010240201f450d00201f41306c450d00201e10230b20252001460d2c0c000b0b0b2004450d28200441246c450d28201d10230c2b0b4102211b4100210420022d00000d2420022d00014101470d24200241196a2d00002104200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d00002127200241086a2d00002128200241066a2f01002129200241056a2d0000212a200241046a2d00002108200241026a2f01002109200141046a280200211b20032002411a6a2901003703c808200320043a00c7082003201c3a00c6082003201d3b01c4082003201e3a00c3082003201f3a00c208200320203b01c008200320213a00bf08200320223a00be08200320233b01bc08200320243a00bb08200320253a00ba08200320263b01b808200320273a00b708200320283a00b608200320293b01b4082003202a3a00b308200320083a00b208200320093b01b008418fcdc200ad4280808080f00084100c2201280000210220012900042105200128000c21042001102341f4e5c100ad4280808080a00184100c220129000021062001290008210720011023200320073701e809200320063701e009200320043601dc09200320053701d409200320023601d009200341a0036a200341d0096a412010cd0141b7c0c0002102411221014180802c210402400240024020032802a003450d0020032802a403201b4d0d00418fcdc200ad4280808080f00084100c221c280000211d201c2900042105201c28000c211e201c1023418cdbc100ad4280808080a00184100c221c2900002106201c2900082107201c1023200320073701e809200320063701e0092003201e3601dc09200320053701d4092003201d3601d00920034198036a200341d0096a412010cd01200328029803450d00200328029c03221d201b490d00418fcdc200ad4280808080f00084100c221c280000211e201c2900042105201c28000c211f201c10234190d8c100ad4280808080c00184100c221c2900002106201c2900082107201c1023200320073701e809200320063701e0092003201f3601dc09200320053701d4092003201e3601d00920034190036a200341d0096a412010cd014100201d20032802940341d4002003280290031b6b221c201c201d4b1b221e201b4b0d00200341d0096a201b10cb01200341f8026a20032802d009221d20032802d80910d70120034188036a2903002106200329038003210520032802f802211c024020032802d409450d00201d10230b201c450d00200341a0096a200341b0086a10c601200341d0096a20032802a009220220032802a80910e20120034180086a41086a22042003418c0a6a29020037030020034180086a41106a221c200341940a6a29020037030020034180086a41186a221d2003419c0a6a29020037030020034180086a41206a221f200341a40a6a2802003602002003200341840a6a29020037038008024020032802f0092220450d00200341d0096a41186a2903002107200341d0096a41086a290300212b200341800a6a2802002121200341fc096a2802002101200341f8096a280200212220032903e009212c20032903d009212d20032802f4092123200341d8086a41206a201f280200360200200341d8086a41186a201d290300370300200341d8086a41106a201c290300370300200341d8086a41086a200429030037030020032003290380083703d808024020032802a409450d00200210230b200341c0066a41186a2007370300200341f0066a2021360200200341e8066a2022360200200341e4066a2023360200200341f4066a220220032903d808370200200341fc066a200341e0086a29030037020020034184076a200341e8086a2903003702002003418c076a200341d8086a41186a29030037020020034194076a200341f8086a2802003602002003202c3703d0062003202d3703c006200320013602ec06200320203602e0062003202b3703c80602402002280200221c0d0041002102410021040c040b41002102410021040340024002400240201e2001280200221d4b0d0020020d01410021020c020b200241016a21020c010b200420026b221f201c4f0d11200120024102746b221f2802002120201f201d360200200120203602000b200141046a2101201c200441016a2204470d000b024002402002450d0020032802f406221e201c20026b2201490d01200320013602f4062001211e0c010b20032802f406211e0b20032802ec0621014100210202400240201e41014b0d0041002104201e0e020501050b201e2104034020022004410176221c20026a221d201b2001201d4102746a280200491b21022004201c6b220441014b0d000b0b201b200120024102746a2802002204470d02024020032802e4062201450d00200141186c450d0020032802e00610230b024020032802f00641ffffffff0371450d0020032802ec0610230b41fdbfc0002102410e21014103211b4180803821040c290b024020032802a409450d00200210230b41ccc1c0002102410d2101410021040b4103211b0c270b201e2002201b20044b6a2202490d0d201e21040b0240200420032802f006470d00200341ec066a20044101107920032802ec0621010b200120024102746a220141046a2001200420026b41027410a2051a2001201b3602002003200441016a3602f406200341d0096a200341b0086a10c60120032802d0092101200320032802d8093602a409200320013602a009200341c0066a200341a0096a10ec01024020032802d409450d00200110230b200341d8086a201b109d02200341d0096a201b200341f8066a221c10df01200341f0026a20032802d009220120032802d80910de0120032802f002212120032802f4022122024020032802d409450d00200110230b200341a0096a201b201c10dd01200341d0096a20032802a009220120032802a8091090020240024020032802f00922240d004200210741082124410021204200212b4200212c4200212d0c010b200341d8096a290300212b200341e8096a290300212d20032903d009210720032903e009212c20032802f40921200b024020032802a409450d00200110230b202c202d2007202b109e0221230240024020032802dc08221d0d00410021020c010b200341d8086a41086a280200211e0340201d41086a2102201d2f0106221f4105742101410021040240024003402001450d01201c2002412010a305221b450d02200141606a2101200441016a2104200241206a2102201b417f4a0d000b2004417f6a211f0b0240201e0d00410021020c030b201e417f6a211e201d201f4102746a4194036a280200211d0c010b0b201d20044102746a41e8026a28020021020b20032802d80822014101200141014b1b2201418094ebdc036e220420012004418094ebdc036c476a22044101200441014b1b220420014b0d0d200341c8026a20052006428094ebdc03420010a705200341b8026a20032903c8022206200341c8026a41086a29030022074280ec94a37c427f10a6052003418094ebdc033602d40920032023ad4100418094ebdc032022410020211b221b6b221d201d418094ebdc034b1bad7e428094ebdc0380a7221d3602d009200341d0096a201d418094ebdc034b4102746a280200211d2003418094ebdc033602d4092003417f201b201d6a221d201d201b491b221b3602d009200341d0096a201b418094ebdc034b4102746a350200212b2003418094ebdc033602d4092003202b2001200220012002491b20046ead428094ebdc037e200120046ead8042ffffffff0f837e428094ebdc0380a722013602d009200341a8026a20062007200341d0096a2001418094ebdc034b4102746a350200222b420010a605200341d8026a201c20032903a8022206202b200520032903b8027c7e2205428094ebdc03802207a7417f2005428080808080c0b2cd3b541b200520074280ec94a37c7e7c4280cab5ee01566aad7c2205200341a8026a41086a2903002005200654ad7c109f02200341d8026a41106a290300210520032903e0022106024020032903d8022207a74101470d0020032903b008210720032903b808212b20032903c008212c20032903c808212d200341880a6a2005370300200341800a6a2006370300200341f1096a202d370000200341e9096a202c370000200341e1096a202b370000200341d9096a2007370000200341d0096a41086a220241003a0000200341033a00d009200341d0096a10e001200341d0096a41186a221c4200370300200341d0096a41106a2204420037030020024200370300200342003703d00941bdadc500ad42808080808001842207100c221b290000212b20034180086a41086a2201201b41086a2900003703002003202b37038008201b10232002200129030037030020032003290380083703d00941c5adc500ad4280808080d00184222b100c221b290000212c2001201b41086a2900003703002003202c37038008201b10232004200329038008222c370300200341a0096a41086a221d2002290300370300200341a0096a41106a221e202c370300200341a0096a41186a221f2001290300370300200320032903d0093703a009200341f8016a200341a0096a412010d701200341f8016a41106a290300212c200329038002212d20032802f801211b201c42003703002004420037030020024200370300200342003703d0092007100c221c29000021072001201c41086a2900003703002003200737038008201c10232002200129030037030020032003290380083703d009202b100c221c29000021072001201c41086a2900003703002003200737038008201c102320042003290380082207370300201d2002290300370300201e2007370300201f2001290300370300200320032903d0093703a0092003427f202c4200201b1b220720057c202d4200201b1b220520067c22062005542201ad7c22052001200520075420052007511b22011b3703d8092003427f200620011b3703d009200341d0096a2101200341a0096a21020c230b20074201520d23200341d0096a41186a221c4200370300200341d0096a41106a22044200370300200341d0096a41086a22024200370300200342003703d00941bdadc500ad42808080808001842207100c221b290000212b20034180086a41086a2201201b41086a2900003703002003202b37038008201b10232002200129030037030020032003290380083703d00941c5adc500ad4280808080d00184222b100c221b290000212c2001201b41086a2900003703002003202c37038008201b10232004200329038008222c370300200341a0096a41086a221d2002290300370300200341a0096a41106a221e202c370300200341a0096a41186a221f2001290300370300200320032903d0093703a00920034190026a200341a0096a412010d70120034190026a41106a290300212c200329039802212d200328029002211b201c42003703002004420037030020024200370300200342003703d0092007100c221c29000021072001201c41086a2900003703002003200737038008201c10232002200129030037030020032003290380083703d009202b100c221c29000021072001201c41086a2900003703002003200737038008201c102320042003290380082207370300201d2002290300370300201e2007370300201f2001290300370300200320032903d0093703a0092003427f202c4200201b1b220720057c202d4200201b1b220520067c22062005542201ad7c22052001200520075420052007511b22011b3703d8092003427f200620011b3703d009200341d0096a2101200341a0096a21020c220b200141246a2802002104200341b8066a200141196a290000370300200341b0066a200141116a290000370300200341a8066a200141096a290000370300200320012900013703a00602400240024020022d00000d0020022d00014101470d0020034180096a41186a200341a0066a41186a29030037030020034180096a41106a200341a0066a41106a29030037030020034180096a41086a200341a0066a41086a290300370300200320032903a00637038009418fcdc200ad4280808080f00084100c2201280000210220012900042105200128000c211b20011023418cdbc100ad4280808080a00184100c220129000021062001290008210720011023200320073701e809200320063701e0092003201b3601dc09200320053701d409200320023601d00920034188066a200341d0096a412010cd0141b7c0c0002101411221024180802c211b200328028806450d02200328028c06221d2004490d02418fcdc200ad4280808080f00084222b100c221c280000211e201c2900042105201c28000c211f201c10234190d8c100ad4280808080c00184100c221c2900002106201c2900082107201c1023200320073701e809200320063701e0092003201f3601dc09200320053701d4092003201e3601d00920034180066a200341d0096a412010cd0120044100201d20032802840641d4002003280280061b6b221c201c201d4b1b221d490d02202b100c221c280000211e201c2900042105201c28000c211f201c102341f4e5c100ad4280808080a00184100c221c2900002106201c2900082107201c1023200320073701e809200320063701e0092003201f3601dc09200320053701d4092003201e3601d009200341f8056a200341d0096a412010cd01024020032802f8054101470d0020032802fc0520044b0d030b200341d0096a200410cb01200341e0056a20032802d009221e20032802d80910d701200341f0056a290300210620032903e805210520032802e005211c024020032802d409450d00201e10230b201c450d02200341c0066a20034180096a10c701200341d0096a20032802c006220220032802c80610e101200341e9096a2900002107200341e8096a2d0000211b200341e7096a2d0000211c200341e5096a2f0000211e200341e4096a2d0000211f200341e3096a2d00002120200341e1096a2f00002121200341e0096a2d00002122200341df096a2d00002123200341dd096a2f00002124200341dc096a2d00002125200341db096a2d00002126200341d9096a2f00002127200341d8096a2d0000212820032d00d709212920032f00d509212a20032d00d409210820032d00d309210920032d00d209210a20032d00d109210b20032d00d0092101024020032802c406450d00200210230b200141ff01714101470d01200320073703c8082003201b3a00c7082003201c3a00c6082003201e3b01c4082003201f3a00c308200320203a00c208200320213b01c008200320223a00bf08200320233a00be08200320243b01bc08200320253a00bb08200320263a00ba08200320273b01b808200320283a00b708200320293a00b6082003202a3b01b408200320083a00b308200320093a00b2082003200a3a00b1082003200b3a00b008200341a0096a200341b0086a10c601200341d0096a20032802a009220220032802a80910e20120034180086a41086a221b2003418c0a6a29020037030020034180086a41106a221c200341940a6a29020037030020034180086a41186a221e2003419c0a6a29020037030020034180086a41206a221f200341a40a6a2802003602002003200341840a6a2902003703800802400240024020032802f0092220450d00200341d0096a41186a2903002107200341d0096a41086a290300212b200341800a6a2802002121200341fc096a2802002101200341f8096a280200212220032903e009212c20032903d009212d20032802f4092123200341d8086a41206a201f280200360200200341d8086a41186a201e290300370300200341d8086a41106a201c290300370300200341d8086a41086a201b29030037030020032003290380083703d808024020032802a409450d00200210230b200341c0066a41186a2007370300200341f0066a2021360200200341e8066a2022360200200341e4066a2023360200200341f4066a220220032903d808370200200341fc066a200341e0086a29030037020020034184076a200341e8086a2903003702002003418c076a200341d8086a41186a29030037020020034194076a200341f8086a2802003602002003202c3703d0062003202d3703c006200320013602ec06200320203602e0062003202b3703c80602402002280200221c0d00410021024100211b0c030b410021024100211b0340024002400240201d2001280200221e4b0d0020020d01410021020c020b200241016a21020c010b201b20026b221f201c4f0d15200120024102746b221f2802002120201f201e360200200120203602000b200141046a2101201c201b41016a221b470d000b024002402002450d0020032802f406221e201c20026b2201490d01200320013602f4062001211e0c010b20032802f406211e0b20032802ec0621014100210202400240201e41014b0d004100211b201e0e020401040b201e211b03402002201b410176221c20026a221d20042001201d4102746a280200491b2102201b201c6b221b41014b0d000b0b4103211c2004200120024102746a280200221b470d010c230b024020032802a409450d00200210230b41ccc1c0002101410d21024103211c4100211b0c230b201e20022004201b4b6a2202490d12201e211b0b0240201b20032802f006470d00200341ec066a201b4101107920032802ec0621010b200120024102746a220141046a2001201b20026b41027410a2051a200120043602002003201b41016a3602f406200341a0096a2004200341f8066a221e10dd01200341d0096a20032802a009220120032802a8091090020240024020032802f00922270d00420021074100212641082127410021224200212e4200212b4200212c0c010b200341d8096a290300212c200341e8096a290300212e200341f8096a280200212220032903d009212b20032903e009210720032802f40921260b024020032802a409450d00200110230b200341d0096a200341b0086a10c60120032802d0092101200320032802d8093602a409200320013602a009200341c0066a200341a0096a10ec01024020032802d409450d00200110230b200341d8086a2004109d024104211c200341d8086a41047221280240024020032802dc08221f450d0020032802d8082123200341d8086a41086a28020021200340201f41086a2102201f2f0106222141057421014100211b0240024003402001450d01201e2002412010a305221d450d02200141606a2101201b41016a211b200241206a2102201d417f4a0d000b201b417f6a21210b2020450d022020417f6a2120201f20214102746a4194036a280200211f0c010b0b201f201b4102746a41e8026a2802002202450d0020234101202341014b1b2201418094ebdc036e221b2001201b418094ebdc036c476a221b4101201b41014b1b221b20014b0d14200341c8056a20052006428094ebdc03420010a705200341b8056a20032903c8052206200341c8056a41086a290300222d4280ec94a37c427f10a605200341a8056a2006202d2001200220012002491b201b6ead428094ebdc037e2001201b6ead8042ffffffff0f83222f420010a605200341d0096a200420034180096a10df01200341d8056a20032802d009220220032802d80910de01200341a8056a41086a29030020032903a8052206202f200520032903b8057c7e2205428094ebdc0380222da7417f2005428080808080c0b2cd3b541b2005202d4280ec94a37c7e7c4280cab5ee01566aad7c2205200654ad7c212d20032802dc05410020032802d8051b2101024020032802d409450d00200210230b20034180056a2005202d428094ebdc03420010a705200341f0046a200329038005220620034180056a41086a290300222f4280ec94a37c427f10a605200341e0046a2006202f2001ad2230420010a605200341d0046a200520032903e004222f2030200520032903f0047c7e2206428094ebdc03802230a7417f2006428080808080c0b2cd3b541b200620304280ec94a37c7e7c4280cab5ee01566aad7c22067d2230202d200341e0046a41086a2903002006202f54ad7c22337d2005200654ad7d428094ebdc03420010a705200341c0046a20032903d004222d200341d0046a41086a290300222f4280ec94a37c427f10a605200341b0046a202d202f2007202e202b202c109e02ad2207420010a60520034190056a201e20032903b004223420067c2205203020032903c0047c222e20077e2206428094ebdc03802207a7417f2006428080808080c0b2cd3b541b200620074280ec94a37c7e7c4280cab5ee01566aad7c2206200341b0046a41086a29030020337c2005203454ad7c2006200554ad7c109f0220034190056a41106a290300210520032903980521062003290390052207a74101470d0120034180076a290300210720034188076a290300213020034190076a290300213320032903f8062134200341880a6a2005370300200341800a6a2006370300200341f1096a2033370000200341e9096a2030370000200341e1096a2007370000200341d9096a2034370000200341d0096a41086a220241003a0000200341033a00d009200341d0096a10e001200341d0096a41186a221c4200370300200341d0096a41106a2204420037030020024200370300200342003703d00941bdadc500ad42808080808001842207100c221b290000213020034180086a41086a2201201b41086a2900003703002003203037038008201b10232002200129030037030020032003290380083703d00941c5adc500ad4280808080d001842230100c221b29000021332001201b41086a2900003703002003203337038008201b102320042003290380082233370300200341a0096a41086a221d2002290300370300200341a0096a41106a221e2033370300200341a0096a41186a221f2001290300370300200320032903d0093703a00920034180046a200341a0096a412010d70120034180046a41106a29030021332003290388042134200328028004211b201c42003703002004420037030020024200370300200342003703d0092007100c221c29000021072001201c41086a2900003703002003200737038008201c10232002200129030037030020032003290380083703d0092030100c221c29000021072001201c41086a2900003703002003200737038008201c102320042003290380082207370300201d2002290300370300201e2007370300201f2001290300370300200320032903d0093703a0092003427f20334200201b1b220720057c20344200201b1b220520067c22062005542201ad7c22052001200520075420052007511b22011b3703d8092003427f200620011b3703d009200341d0096a2101200341a0096a21020c200b202810be012026450d21202641306c450d21202710230c210b20074201520d1f200341d0096a41186a221c4200370300200341d0096a41106a22044200370300200341d0096a41086a22024200370300200342003703d00941bdadc500ad42808080808001842207100c221b290000213020034180086a41086a2201201b41086a2900003703002003203037038008201b10232002200129030037030020032003290380083703d00941c5adc500ad4280808080d001842230100c221b29000021332001201b41086a2900003703002003203337038008201b102320042003290380082233370300200341a0096a41086a221d2002290300370300200341a0096a41106a221e2033370300200341a0096a41186a221f2001290300370300200320032903d0093703a00920034198046a200341a0096a412010d70120034198046a41106a290300213320032903a0042134200328029804211b201c42003703002004420037030020024200370300200342003703d0092007100c221c29000021072001201c41086a2900003703002003200737038008201c10232002200129030037030020032003290380083703d0092030100c221c29000021072001201c41086a2900003703002003200737038008201c102320042003290380082207370300201d2002290300370300201e2007370300201f2001290300370300200320032903d0093703a0092003427f20334200201b1b220720057c20344200201b1b220520067c22062005542201ad7c22052001200520075420052007511b22011b3703d8092003427f200620011b3703d009200341d0096a2101200341a0096a21020c1e0b4102211c4100211b0c210b41c4c1c00021014108210241808004211b0b4103211c0c1f0b41022104024020022d00000d0020022d00014101470d00200141106a290300212b200141086a290300212c200241196a2d00002104200241186a2d0000211b200241166a2f0100211c200241156a2d0000211d200241146a2d0000211e200241126a2f0100211f200241116a2d00002120200241106a2d000021212002410e6a2f010021222002410d6a2d000021232002410c6a2d000021242002410a6a2f01002125200241096a2d00002126200241086a2d00002127200241066a2f01002128200241056a2d00002129200241046a2d0000212a200241026a2f0100210120032002411a6a29010037039809200320043a0097092003201b3a0096092003201c3b0194092003201d3a0093092003201e3a0092092003201f3b019009200320203a008f09200320213a008e09200320223b018c09200320233a008b09200320243a008a09200320253b018809200320263a008709200320273a008609200320283b018409200320293a0083092003202a3a008209200320013a008009200320014108763a008109200341c0066a20034180096a10c601200341d0096a20032802c006220120032802c80610e20120034180086a41086a22042003418c0a6a29020037030020034180086a41106a221c200341940a6a29020037030020034180086a41186a221d2003419c0a6a29020037030020034180086a41206a221e200341a40a6a2802003602002003200341840a6a2902003703800820032802f009221b450d18200341d0096a41186a290300212d200341d0096a41086a2903002134200341800a6a2802002120200341fc096a2802002121200341f8096a280200210220032903e009212f20032903d009213520032802f409211f200341d8086a41206a201e280200360200200341d8086a41186a201d290300370300200341d8086a41106a201c290300370300200341d8086a41086a200429030037030020032003290380083703d808024020032802c406450d00200110230b200341b0086a41106a200341d8086a41106a2903002205370300200341a0096a41086a2201200341d8086a41086a290300370300200341a0096a41106a22042005370300200341a0096a41186a221c200341d8086a41186a290300370300200341a0096a41206a221d200341d8086a41206a280200360200200320032903d8083703a00902402002450d00200341c0066a41206a201d280200360200200341c0066a41186a201c290300370300200341c0066a41106a2004290300370300200341c0066a41086a2001290300370300200320032903a0093703c006200241186c201b6a41686a21014200212e4200213002400340024020020d00410021020c020b024020012903002205202e7c2206202c58200141086a290300223320307c2006200554ad7c2207202b582007202b5122041b0d0020012005202c202e7d22067d37030020012033202b20307d202c202e54ad7d22077d2005200654ad7d3703082007202d7c2006202f7c222f200654ad7c212d0c020b2002417f6a21022033202d7c2005202f7c222f200554ad7c212d200141686a21012006212e200721302006202c542007202b5420041b0d000b0b200341d0096a41186a202d370300200341800a6a2020360200200341f8096a2002360200200341f4096a201f360200200341840a6a20032903c0063702002003418c0a6a200341c8066a290300370200200341940a6a200341d0066a2903003702002003419c0a6a200341c0066a41186a290300370200200341a40a6a200341e0066a2802003602002003202f3703e009200320353703d009200320213602fc092003201b3602f009200320343703d809200342f3e885db96cddbb3203703d808200341d8086a200341880a6a20352034411f109902200341c0066a20034180096a10c60120032802c0062101200320032802c806360284082003200136028008200341d0096a20034180086a10ec01024020032802c406450d00200110230b024020032802f4092201450d00200141186c450d0020032802f00910230b20032802800a41ffffffff0371450d3620032802fc0910230c360b0240201f450d00201f41186c450d00201b10230b41d5c0c0002101418080242102202041ffffffff0371450d1920211023410321040c1a0b410021020c190b20022d000120022d0000410047720d0e200141046a2802002104418fcdc200ad4280808080f00084222b100c2201280000210220012900042105200128000c211b20011023418cdbc100ad4280808080a00184100c220129000021062001290008210720011023200320073701e809200320063701e0092003201b3601dc09200320053701d409200320023601d00920034198066a200341d0096a412010cd012003280298064101470d33200328029c062102202b100c2201280000211b20012900042105200128000c211c200110234190d8c100ad4280808080c001842206100c220129000021072001290008212b200110232003202b3701e809200320073701e0092003201c3601dc09200320053701d4092003201b3601d00920034190066a200341d0096a412010cd0102404100200220032802940641d4002003280290061b6b2201200120024b1b22014100200220046b221b201b20024b1b22024f0d000340200110ce012002200141016a2201470d000b0b418fcdc200ad4280808080f00084100c2201280000210220012900042105200128000c211b200110232006100c220129000021062001290008210720011023200320073701e809200320063701e0092003201b3601dc09200320053701d409200320023601d009200320043602c006200341d0096aad4280808080800484200341c0066aad4280808080c00084100e0c330b200341c0066a41186a200141196a290000370300200341c0066a41106a200141116a290000370300200341c8066a200141096a290000370300200320012900013703c006200341a0096a200341c0066a109702200341d0096a20032802a009220220032802a809109802200341d0096a41106a290300420020032903d00942015122011b210520032903d809420020011b2106200341f0096a290300420020011b2107200341d0096a41186a290300420020011b212b024020032802a409450d00200210230b427f2006202b7c222b202b2006542201200520077c2001ad7c220620055420062005511b22011b427f200620011b844200520d0e200341d0096a200341c0066a109a02024020032d00d00922014104470d00200342f3e885db96cddbb3203703800820034180086a200341c0066a109b020c330b200341d0096a41086a280200210220032802d409210420032f00d10920032d00d30941107472410874221d4180fe0371211b201d418080fc0771211c201d418080807871211d0c140b2001410c6a280200211c200141086a2802002104200141046a280200211b200141d0016a280200211d200341c0066a200141106a41c00110a1051a200341a8086a20014180026a290300370300200341a0086a200141f8016a29030037030020034198086a200141f0016a29030037030020034180086a41106a200141e8016a29030037030020034180086a41086a200141e0016a2903003703002003200141d8016a290300370380080240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000d0020022d00014101470d002003201c3602e008200320043602dc082003201b3602d808200341d0096a200341c0066a41c00110a1051a200341a0096a41286a20034180086a41286a290300370300200341a0096a41206a20034180086a41206a290300370300200341a0096a41186a20034180086a41186a290300370300200341a0096a41106a20034180086a41106a290300370300200341a0096a41086a20034180086a41086a29030037030020032003290380083703a009200341d8086a200341d0096a4101200341a0096a201d10a002221b41ff0171411c460d4e4180bec000210141122104418080e8002102201b411f710e1c0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c010b200341c0066a1083022004450d2d200441ffffffff0771450d2d201b10230c2d0b200341e4096a4101360200200342013702d409200341a4c5c6003602d009200341043602a409200341c8abc3003602a0092003200341a0096a3602e009200341d0096a419ca8c700103a000b41ccc1c0002101410d2104410021020c190b41c4c1c0002101410821044180800421020c180b41b7c1c0002101410d21044180800821020c170b41aac1c0002101410d21044180800c21020c160b419ec1c0002101410c21044180801021020c150b4190c1c0002101410e21044180801421020c140b41ffc0c0002101411121044180801821020c130b41eec0c0002101411121044180801c21020c120b41e2c0c0002101410c21044180802021020c110b41d5c0c0002101410d21044180802421020c100b41c9c0c0002101410c21044180802821020c0f0b41b7c0c00021014180802c21020c0e0b419dc0c0002101411a21044180803021020c0d0b418bc0c00021014180803421020c0c0b41fdbfc0002101410e21044180803821020c0b0b41e6bfc0002101411721044180803c21020c0a0b41d0bfc000210141162104418080c00021020c090b41bdbfc000210141132104418080c40021020c080b41a5bfc000210141182104418080c80021020c070b4192bfc000210141132104418080cc0021020c060b41febec000210141142104418080d00021020c050b41e8bec000210141162104418080d40021020c040b41d1bec000210141172104418080d80021020c030b41b8bec000210141192104418080dc0021020c020b41a3bec000210141152104418080e00021020c010b4192bec000210141112104418080e40021020b4103211b0c120b2001410c6a280200211c200141086a2802002104200141046a280200211b200141d0016a280200211d200341c0066a200141106a41c00110a1051a200341a8086a20014180026a290300370300200341a0086a200141f8016a29030037030020034198086a200141f0016a29030037030020034180086a41106a200141e8016a29030037030020034180086a41086a200141e0016a2903003703002003200141d8016a290300370380080240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000d0020022d000141ff01714102470d002003201c3602e008200320043602dc082003201b3602d808200341d0096a200341c0066a41c00110a1051a200341a0096a41286a20034180086a41286a290300370300200341a0096a41206a20034180086a41206a290300370300200341a0096a41186a20034180086a41186a290300370300200341a0096a41106a20034180086a41106a290300370300200341a0096a41086a20034180086a41086a29030037030020032003290380083703a009200341d8086a200341d0096a4102200341a0096a201d10a002221b41ff0171411c460d4d4180bec000210141122104418080e8002102201b411f710e1c0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c010b200341c0066a1083022004450d2a200441ffffffff0771450d2a201b10230c2a0b200341e4096a4101360200200342013702d409200341a4c5c6003602d009200341043602a409200341c8abc3003602a0092003200341a0096a3602e009200341d0096a419ca8c700103a000b41ccc1c0002101410d2104410021020c190b41c4c1c0002101410821044180800421020c180b41b7c1c0002101410d21044180800821020c170b41aac1c0002101410d21044180800c21020c160b419ec1c0002101410c21044180801021020c150b4190c1c0002101410e21044180801421020c140b41ffc0c0002101411121044180801821020c130b41eec0c0002101411121044180801c21020c120b41e2c0c0002101410c21044180802021020c110b41d5c0c0002101410d21044180802421020c100b41c9c0c0002101410c21044180802821020c0f0b41b7c0c00021014180802c21020c0e0b419dc0c0002101411a21044180803021020c0d0b418bc0c00021014180803421020c0c0b41fdbfc0002101410e21044180803821020c0b0b41e6bfc0002101411721044180803c21020c0a0b41d0bfc000210141162104418080c00021020c090b41bdbfc000210141132104418080c40021020c080b41a5bfc000210141182104418080c80021020c070b4192bfc000210141132104418080cc0021020c060b41febec000210141142104418080d00021020c050b41e8bec000210141162104418080d40021020c040b41d1bec000210141172104418080d80021020c030b41b8bec000210141192104418080dc0021020c020b41a3bec000210141152104418080e00021020c010b4192bec000210141112104418080e40021020b4103211b0c0f0b1033000b2001201f103b000b2022201f4184d9c4001030000b200220211038000b41f0a6c700411941f4aac700102d000b201f201c4184d9c4001030000b2002201e1038000b41f0a6c700411941f4aac700102d000b201f201c4184d9c4001030000b2002201e1038000b41f0a6c700411941f4aac700102d000b200041003602042000410c6a41023602000c230b4100211d41808028211c41032101410c210241c9c0c0002104418010211b0c050b201b10230c190b4102211b410021020b20004100360204200041146a2004360200200041106a20013602002000410c6a2002418080fc0071201b72418010723602000c1f0b4102211b410021020b20004100360204200041146a2004360200200041106a20013602002000410c6a2002418080fc0071201b72418010723602000c1d0b20004100360204200041146a2002360200200041106a20043602002000410c6a201b200172201c72201d723602000c1c0b024020032802c406450d00200110230b41ccc1c0002101410021020b410321040b20004100360204200041146a410d360200200041106a20013602002000410c6a20024180803c71200472418010723602000c190b2002ad42808080808004842001ad4280808080800284100e0b0240202241306c2201450d00202720016a2120202741286a2101200341a0096aad42808080808004842135200341d0096a41106a2102200341880a6a21250340200341d8036a202d202f200141586a2204290300200441086a290300202b202c109e02ad2205420010a605200341e8036a200141686a221c20032903d80322062005202e7e2205428094ebdc03802207a7417f2005428080808080c0b2cd3b541b200520074280ec94a37c7e7c4280cab5ee01566aad7c2205200341d8036a41086a2903002005200654ad7c109f02200341e8036a41106a290300210520032903f003210602400240024020032903e8032207a74101470d00201c2900002107200141706a2900002130200141786a290000213320012900002134200320063703800a20252005370300200320343700f109200320333700e909200320303700e109200320073700d909200341003a00d809200341033a00d009200341d0096a10e001200341d0096a41186a221d420037030020024200370300200341d0096a41086a221b4200370300200342003703d00941bdadc500ad42808080808001842207100c221e290000213020034180086a41086a2204201e41086a2900003703002003203037038008201e1023201b200429030037030020032003290380083703d00941c5adc500ad4280808080d001842230100c221e29000021332004201e41086a2900003703002003203337038008201e10232002200329038008370000200241086a22212004290300370000200341a0096a41086a2222201b290300370300200341a0096a41106a22232002290300370300200341a0096a41186a2224201d290300370300200320032903d0093703a009200341a8036a200341a0096a412010d701200341a8036a41106a290300213320032903b003213420032802a803211e201d420037030020024200370300201b4200370300200342003703d0092007100c221f29000021072004201f41086a2900003703002003200737038008201f1023201b200429030037030020032003290380083703d0092030100c221f29000021072004201f41086a2900003703002003200737038008201f10232002200329038008370000202120042903003700002022201b290300370300202320022903003703002024201d290300370300200320032903d0093703a0092003427f20334200201e1b220720057c20344200201e1b220520067c22062005542204ad7c22052004200520075420052007511b22041b3703d8092003427f200620041b3703d009200341d0096a21040c010b20074201520d01200341d0096a41186a221d420037030020024200370300200341d0096a41086a221b4200370300200342003703d00941bdadc500ad42808080808001842207100c221e290000213020034180086a41086a2204201e41086a2900003703002003203037038008201e1023201b200429030037030020032003290380083703d00941c5adc500ad4280808080d001842230100c221e29000021332004201e41086a2900003703002003203337038008201e10232002200329038008370000200241086a22212004290300370000200341a0096a41086a2222201b290300370300200341a0096a41106a22232002290300370300200341a0096a41186a2224201d290300370300200320032903d0093703a009200341c0036a200341a0096a412010d701200341c0036a41106a290300213320032903c803213420032802c003211e201d420037030020024200370300201b4200370300200342003703d0092007100c221f29000021072004201f41086a2900003703002003200737038008201f1023201b200429030037030020032003290380083703d0092030100c221f29000021072004201f41086a2900003703002003200737038008201f10232002200329038008370000202120042903003700002022201b290300370300202320022903003703002024201d290300370300200320032903d0093703a0092003427f20334200201e1b220720057c20344200201e1b220520067c22062005542204ad7c22052004200520075420052007511b22041b3703d8092003427f200620041b3703d009200341d0096a21040b20352004ad4280808080800284100e0b200141306a2101201c41206a2020470d000b0b202810be0102402026450d00202641306c450d00202710230b024020032802e4062201450d00200141186c450d0020032802e00610230b024020032802f00641ffffffff0371450d0020032802ec0610230b410021040c030b024020032802e4062201450d00200141186c450d0020032802e00610230b41fdbfc0002101410e210241808038211b20032802f00641ffffffff0371450d0020032802ec0610230b41002104201c4104460d010b200041146a2002360200200041106a20013602002000410c6a201b4180803c71201c7241801072360200410121040b200041003602040c150b2002ad42808080808004842001ad4280808080800284100e0b200341d8086a410472210102402020450d00202041306c450d00202410230b200110be01024020032802e4062201450d00200141186c450d0020032802e00610230b024020032802f00641ffffffff0371450d0020032802ec0610230b410021040c020b0b200041146a2001360200200041106a20023602002000410c6a20044180803c71201b7241801072360200410121040b200041003602040c100b0c020b02402004450d00200441246c450d00201d10230b20034198016a2007202b428094ebdc03420010a70520034188016a200329039801220520034198016a41086a29030022064280ec94a37c427f10a605200341f8006a200520062027ad222b420010a605200341a8016a200341c0066a41386a20032903782206202b20072003290388017c7e2205428094ebdc03802207a7417f2005428080808080c0b2cd3b541b200520074280ec94a37c7e7c4280cab5ee01566aad7c2205200341f8006a41086a2903002005200654ad7c109f02200341a8016a41106a290300210520032903b001210602400240024020032903a8012207a74101470d0020032903b008210720032903b808212b20032903c008212c20032903c808212d200341d0096a41386a2005370300200341800a6a2006370300200341f1096a202d370000200341e9096a202c370000200341e1096a202b370000200341d9096a2007370000200341d0096a41086a220241003a0000200341033a00d009200341d0096a10e001200341d0096a41186a221c4200370300200341d0096a41106a2204420037030020024200370300200342003703d00941bdadc500ad42808080808001842207100c221b290000212b20034180086a41086a2201201b41086a2900003703002003202b37038008201b10232002200129030037030020032003290380083703d00941c5adc500ad4280808080d00184222b100c221b290000212c2001201b41086a2900003703002003202c37038008201b10232004200329038008222c370300200341a0096a41086a221d2002290300370300200341a0096a41106a221e202c370300200341a0096a41186a221f2001290300370300200320032903d0093703a009200341c8006a200341a0096a412010d701200341c8006a41106a290300212c2003290350212d2003280248211b201c42003703002004420037030020024200370300200342003703d0092007100c221c29000021072001201c41086a2900003703002003200737038008201c10232002200129030037030020032003290380083703d009202b100c221c29000021072001201c41086a2900003703002003200737038008201c102320042003290380082207370300201d2002290300370300201e2007370300201f2001290300370300200320032903d0093703a0092003427f202c4200201b1b220720057c202d4200201b1b220520067c22062005542201ad7c22052001200520075420052007511b22011b3703d8092003427f200620011b3703d009200341d0096a2101200341a0096a21020c010b20074201520d01200341d0096a41186a221c4200370300200341d0096a41106a22044200370300200341d0096a41086a22024200370300200342003703d00941bdadc500ad42808080808001842207100c221b290000212b20034180086a41086a2201201b41086a2900003703002003202b37038008201b10232002200129030037030020032003290380083703d00941c5adc500ad4280808080d00184222b100c221b290000212c2001201b41086a2900003703002003202c37038008201b10232004200329038008222c370300200341a0096a41086a221d2002290300370300200341a0096a41106a221e202c370300200341a0096a41186a221f2001290300370300200320032903d0093703a009200341e0006a200341a0096a412010d701200341e0006a41106a290300212c2003290368212d2003280260211b201c42003703002004420037030020024200370300200342003703d0092007100c221c29000021072001201c41086a2900003703002003200737038008201c10232002200129030037030020032003290380083703d009202b100c221c29000021072001201c41086a2900003703002003200737038008201c102320042003290380082207370300201d2002290300370300201e2007370300201f2001290300370300200320032903d0093703a0092003427f202c4200201b1b220720057c202d4200201b1b220520067c22062005542201ad7c22052001200520075420052007511b22011b3703d8092003427f200620011b3703d009200341d0096a2101200341a0096a21020b2002ad42808080808004842001ad4280808080800284100e0b200341d8086a41047210be01024020032802e4062201450d00200141186c450d0020032802e00610230b024020032802f00641ffffffff0371450d0020032802ec0610230b410021040c020b02402004450d00200441246c450d00201d10230b4103211b0b200041146a2002360200200041106a20013602002000410c6a201c41ff0171411074201b7241801072360200410121040b200041003602040c0b0b0240202541ffffffff0371450d00202410230b20004100360204200041146a2002360200200041106a20043602002000410c6a2001201c723602000c080b41012123410021210c010b0240201c41ffffff3f71450d00201b10230b2023450d0120032802840841ffffff3f7121210b418fcdc200ad4280808080f00084100c2202280000210420022900042105200228000c211b20021023418cdbc100ad4280808080a00184100c220229000021062002290008210720021023200320073701e809200320063701e0092003201b3601dc09200320053701d409200320043601d009200341386a200341d0096a412010cd01200328023c212220032802382124200341d0096a200341f8066a220210c30120033502d80942208620032802d0092204ad841011024020032802d409450d00200410230b200341a0096a200210c50120033502a809210520032802a0092120200341003602d809200342013703d0092001200341d0096a106102400240024020010d0020032802d409211b20032802d80921020c010b2001410574211d410020032802d80922026b211c20032802d009211f20032802d409211b2023211e0340201e21010240201b201c6a411f4b0d00200241206a22042002490d03201b410174221e2004201e20044b1b22044100480d030240024002400240201b0d00024020040d004101211f0c020b20041021211f0c030b201b2004470d010b2004211b0c020b201f201b20041025211f0b2004211b201f450d050b200141206a211e201f20026a22042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a290000370000201c41606a211c200241206a2102201d41606a221d0d000b2003201b3602d409200320023602d8092003201f3602d0090b02400240201b20026b4104490d0020032802d0092104201b21010c010b200241046a22012002490d01201b41017422042001200420014b1b22014100480d0102400240201b0d00024020010d00410121040c020b200110212204450d050c010b20032802d0092104201b2001460d002004201b200110252204450d040b200320013602d409200320043602d0090b200420026a2022410020241b3600002003200241046a22023602d8094100211b200341003a0080080240024020012002460d00200221010c010b200141016a22022001490d012001410174221b2002201b20024b1b22024100480d010240024020010d0041002101024020020d00410121040c020b200210212204450d050c010b20012002460d0020042001200210252204450d040b200320023602d409200320043602d00920032d008008211b0b200420016a201b3a000020032802d409210220054220862020ad84200141016aad42208620032802d0092201ad84100e02402002450d00200110230b024020032802a409450d00202010230b02402021450d00202310230b024020032802e4062201450d00200141186c450d0020032802e00610230b20032802f00641ffffffff0371450d0720032802ec0610230c070b102c000b02402025450d00202541186c450d00202610230b0240202741ffffffff0371450d00202810230b410121040c030b102a000b0b201c41ffffff3f71450d00201b10230b20004100360204200041146a2002360200200041106a201d3602002000410c6a200141ff0171411074200472418010723602000b410121040c010b41002104200041003602040b20002004360200200341900b6a24000bae0503027f017e047f230041d0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a200341086a290000370300200220043703002003102341b0dac100ad4280808080d00084100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad4280808080800484100d220129000037033020011023200241c4006a200341206a360200200241003a0048200220033602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200310232002280228220541206a2201417f4c0d0120022802202106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bce0203027f017e037f23004180026b22012400200141086a2000109702200141e0006a200128020822002001280210220210980220012903602103200141b8016a200141e8006a41c40010a1051a200141b4016a41026a2204200141af016a2d00003a0000200120012f00ad013b01b4010240024020034201510d0041002105200141186a410041c40010a0051a0c010b20012d00ac012105200141186a200141b8016a41c40010a1051a200141146a41026a20042d00003a0000200120012f01b4013b01140b200141e8006a200141186a41c40010a1052104200141af016a200141166a2d00003a0000200142013703602001417f2005411874220541808080086a220620062005491b4118763a00ac01200120012f01143b00ad01200120023602bc01200120003602b8012004200141b8016a1098030240200128020c450d00200010230b20014180026a24000bcc0503027f017e047f230041e0006b2202240041e4dec400ad4280808080e00084100c22032900002104200241086a41086a200341086a290000370300200220043703082003102341888ec600ad4280808080f00084100c22032900002104200241186a41086a200341086a2900003703002002200437031820031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100f22012900002104200241386a41086a200141086a2900003703002002200437033820011023200241d4006a200341206a360200200241003a0058200220033602502002200241386a41106a36024c2002200241386a360248200241286a200241c8006a1065200310232002280230220541206a2201417f4c0d0120022802282106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290308370000200341086a200241086a41086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290318370010200341186a200241186a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a2000200136020820002007360204200020033602000240200228022c450d00200610230b200241e0006a24000f0b102c000b102a000baa0406027f017e017f037e017f037e230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad841010108b0102400240200328020822010d00200042003703000c010b200328020c2102024002400240200341106a28020022044104490d0020044104460d002004417b6a4110490d002004416b6a4110490d002004415b6a4110490d002004414b6a410f4b0d010b20034100360220200342013703182003410a36022c200320033602282003200341186a360234200341cc006a41013602002003420137023c20034180c5c6003602382003200341286a360248200341346a4184a5c200200341386a10311a2003350220422086200335021884100a0240200328021c450d00200328021810230b420021050c010b2001280000210420012d000421062001410d6a2900002105200129000521072001411d6a290000210820012900152109200341286a41026a220a200341386a41026a2d00003a0000200320032f00383b01282001412d6a290000210b2001290025210c2001290035210d200041c0006a2001413d6a290000370300200041386a200d370300200041306a200b370300200041286a200c370300200041206a2008370300200041186a2009370300200041106a200537030020002007370308200020063a004c200041c8006a2004360200200020032f01283b004d200041cf006a200a2d00003a0000420121050b200020053703002002450d00200110230b200341d0006a24000ba00f03037f017e0d7f230022052106200541e0016b41607122052400024002402002200384500d00200441ff01712207450d002000290000210841002109024020074101460d004102410120044101711b21090b20052002370300200520093a00182005200837031020052003370308200541c0016a200110d704200541a0016a20052802c001220720052802c80110da0420052902a401420020052802a00122041b2102024020052802c401450d00200710230b2004410820041b210a2002a7210b0240024002402002422088a7220c450d00200a200c4105746a210d200541a0016a411072210e200541a0016a411972210f410021070340200541e8006a41106a2210200a20076a220441106a290300370300200541e8006a41086a2211200441086a290300370300200520042903003703682005200441196a28000036023820052004411c6a28000036003b200441186a2d000022124103460d01200f2005280238360000200f41036a200528003b360000200520102903003703b001200520112903003703a801200520052903683703a001200520123a00b80102400240200e2000460d00200e2900002000290000510d00200520052903b801220237039801200520052903b00137039001200520052903a80137038801200520052903a001370380010c010b200541033a00d80120052005290318220237039801200520052903103703900120052005290308370388012005200529030037038001200520052903d001370310200520052903c801370308200520052903c001370300200520052903d80122033703182003a721090b2002a7221041ff01714103470d02200741206a2107200441206a200d470d000b0b200541003602a801200542083703a001200b41ffffff3f71450d01200a10230c010b200541d0006a41106a220f200529039001370300200541d0006a41086a22112005290388013703002005200528009c0136004320052005280099013602402005200529038001370350200520052802403602482005200528004336004b41201021220e450d02200e2005290350370300200e20103a0018200e2005280248360019200e411c6a200528004b360000200e41106a200f290300370300200e41086a2011290300370300200542818080801037022c2005200e3602280240200c41057441606a2007460d00200441206a2110200c410574200a6a41606a211320054180016a4119722114200541a0016a4110722112200541a0016a411972210f4101210c0340201021040340200541e8006a41106a2210200441106a290300370300200541e8006a41086a2211200441086a29030037030020052004290300370368200441186a2d000021072005200441196a28000036023820052004411c6a28000036003b20074103460d02200f2005280238360000200f41036a200528003b360000200520102903003703b001200520112903003703a801200520052903683703a001200520073a00b8010240024020122000460d0020122900002000290000510d00200520052903b801220237039801200520052903b00137039001200520052903a80137038801200520052903a001370380010c010b200541033a00d80120052005290318220237039801200520052903103703900120052005290308370388012005200529030037038001200520052903d001370310200520052903c801370308200520052903c001370300200520052903d80122033703182003a721090b02402002a7220741ff01714103470d00200441206a2204200d470d010c030b0b200541d0006a41106a2210200529039001370300200541d0006a41086a2211200529038801370300200520142800003602402005201441036a2800003600432005200529038001370350200520052802403602482005200528004336004b200541c0016a41086a22152011290300370300200541c0016a41106a22112010290300370300200520052903503703c001200520052802483602a0012005200528004b3600a3010240200c200528022c470d00200541286a200c41011097012005280228210e0b200441206a2110201529030021022011290300210320052903c0012108200e200c4105746a221120073a001820112008370300201120052802a0013600192011411c6a20052800a301360000201141106a2003370300201141086a20023703002005200c41016a220c36023020132004470d000b0b0240200b41ffffff3f71450d00200a10230b200541a0016a41086a200541286a41086a280200360200200520052903283703a0010b02400240200941ff01714103470d0020052802a801210420052802a0012107200541a0016a21050c010b200541c0016a41186a220f2005290318370300200541c0016a41106a22102005290310370300200541c0016a41086a22112005290308370300200520052903003703c001024020052802a801220420052802a401470d00200541a0016a2004410110970120052802a80121040b20052802a001220720044105746a220020052903c001370300200041086a2011290300370300200041106a2010290300370300200041186a200f2903003703002005200441016a22043602a801200541a0016a21050b20012007200410db04200541046a28020041ffffff3f71450d00200528020010230b200624000f0b1033000b960903057f027e057f230041a0016b22022400200241e8006a200110c701200241f8006a200228026822032002280270220410e101024020022d00782205450d002004ad4220862003ad8410110b200241086a41176a220420024191016a290000370000200241086a41106a22062002418a016a290100370300200241086a41086a20024182016a29010022073703002002200229017a220837030820022d00792109200241f8006a41176a220a2004290000370000200241f8006a41106a22042006290300370300200241f8006a41086a220620073703002002200837037802400240024002400240024020054101470d00200241c8006a41176a200a290000370000200241c8006a41106a2004290300370300200241c8006a41086a2006290300370300200220022903783703480240200228026c450d00200310230b200241286a41176a2203200241c8006a41176a290000370000200241286a41106a2205200241c8006a41106a290300370300200241116a200241d0006a290300370000200241196a2005290300370000200241206a2003290000370000200220093a000820022002290348370009200241f8006a200241086a10c60120023502800142208620022802782203ad8410110240200228027c450d00200310230b200241f8006a200110950220023502800142208620022802782203ad8410110240200228027c450d00200310230b200241f8006a200110c30120023502800142208620022802782203ad8410110240200228027c450d00200310230b200241f8006a200110c50120023502800142208620022802782203ad8410110240200228027c450d00200310230b200241c8006a200110c101200241f8006a200228024822032002280250220510c9010240200228028401220b450d002005ad4220862003ad8410110b20022903880121072002280278210c0240200228024c450d00200310230b200b450d04200b2007422088a74102746a210d200c210a200b2109410021040240410041ff01710e03020300020b410021030c030b0240200228026c450d00200310230b200041086a4108360200200041046a41c4c1c000360200200041026a41013a000020004183103b01000c040b410121030c010b410221030b0340024002400240024002400240024020030e03000102020b2009200d460d03200941046a21094102210320042105200a417f6a2206210a0c020b4102210541002103024020044102460d00200c21060c020b2009200d460d02200941046a210941022105200a417f6a2206210a410221030c010b4102210541012103200c210620044102460d010b200241f8006a41186a200141186a290000370300200241f8006a41106a200141106a290000370300200241f8006a41086a200141086a290000370300200220063602980120022001290000370378200241c8006a200241f8006a10c401200235025042208620022802482204ad8410110240200228024c450d00200410230b200521040240200341ff01710e03000203000b410121030c030b200742ffffffff0383500d03200b10230c030b410221030c010b410021030c000b0b200110a102200041043a00000b200241a0016a24000bea0306037f017e0d7f027e017f017e230041306b22022400200241106a200110d704200220022802102203200228021810da0420022902044200200228020022041b210502402002280214450d00200310230b2004410820041b2106024002402005422088a722070d00410021070c010b200041706a210841002103200621044100210902400240034002400240024020082004460d00200441106a220a2900002000290000510d0020030d01410021030c020b200341016a21030c010b200920036b220b20074f0d02200241106a41186a220c200420034105746b220b41186a220d290300370300200241106a41106a220e200b41106a220f290300370300200241106a41086a2210200b41086a22112903003703002002200b290300370310200441086a22122903002113200a2903002114200441186a22152903002116200b2004290300370300200d2016370300200f2014370300201120133703002015200c290300370300200a200e29030037030020122010290300370300200420022903103703000b200441206a21042007200941016a2209460d020c000b0b200b20074184d9c4001030000b2003417f6a20074f0d00200542ffffffff0f832105200720036b21070b20012006200710db040240200542ffffff3f83500d00200610230b200241306a24000ba30301067f230041106b22032400024020014105744104722204417f4c0d000240200410212205450d002003410036020820032004360204200320053602002001200310610240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020002101024002402006200522046b4120490d00200441206a21050c010b024002400240200441206a22052004490d00200641017422002005200020054b1b22004100480d000240024020060d00024020000d00410121070c020b2000102121070c040b20062000470d020b200021060c030b102c000b200720062000102521070b2000210620070d00102a000b200141206a2100200720046a22042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a290000370000200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100e02402006450d00200710230b200341106a24000f0b1033000b1032000bd30503027f017e057f230041e0006b22022400418fcdc200ad4280808080f00084100c22032900002104200241086a41086a200341086a290000370300200220043703082003102341eecec000ad4280808080800284100c22032900002104200241286a41086a200341086a29000037030020022004370328200310232002200136023c20022002413c6aad4280808080c00084100d220329000037034020031023200241d4006a200241c0006a360200200241003a00582002200241c0006a41086a36024c20022002413c6a3602502002200241c0006a360248200241186a200241c8006a10650240024002400240024002402002280220220541206a2201417f4c0d0020022802182106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422074110200741104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290308370000200341086a200241086a41086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290328370010200341186a200241286a41086a2903003700000240200841606a20054f0d00200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a0240200228021c450d00200610230b200241c8006a2003200110bb01200241286a41086a2201200241c8006a410c6a2902003703002002200229024c3703280240024020022802484101460d00200042003702002000410c6a41003602000c010b20002002290328370200200041086a20012903003702000b20031023200241e0006a24000f0b102c000b102a000bbb0302027f037e230041d0006b22042400200441386a20024201200242015620034200522003501b22051b22022003420020051b2203428094ebdc03420010a705200441286a20042903382206200441386a41086a2903002207428094ebdc03420010a605200441186a20022003200620022004290328852003200441286a41086a2903008584420052ad7c22084201200842015620072008200654ad7c22064200522006501b22051b22082006420020051b220710a70502400240024020042903182206428080808010544100200441186a41086a290300501b450d00200441086a200220002002200054200320015420032001511b22051b2003200120051b2008200710a70520042903082203428080808010544100200441086a41086a290300501b450d012006a7450d02200441d0006a2400200342ffffffff0f83428094ebdc037e200642ffffffff0f8380a70f0b2004411136024c20044184abc7003602484188a9c70041de00200441c8006a41f8a8c70041e8a9c7001034000b2004411136024c20044184abc7003602484188a9c70041de00200441c8006a41f8a8c70041e4aac7001034000b41f0a6c700411941f4aac700102d000b8f1b020c7f087e230041f0036b22042400200441386a2001109502200428023821052004200428024022063602dc02200420053602d80220044198016a2006ad4220862005ad841010108b01024002402004280298012207450d00200428029c01210802400240200441a0016a280200450d0020072d000022064103490d010b2004410036028002200442013703f8012004410a3602042004200441d8026a3602002004200441f8016a3602d8012004419c036a41013602002004420137028c0320044180c5c600360288032004200436029803200441d8016a4184a5c20020044188036a10311a20043502800242208620043502f80184100a024020042802fc01450d0020042802f80110230b410321060b02402008450d00200710230b20064103470d010b410021060b0240200428023c450d00200510230b0240024002400240024020060e03000201000b20044198016a200110c70120044188036a200428029801220520042802a00110e101200441f8016a41086a220620044191036a290000370300200441f8016a41106a220720044199036a290000370300200441f8016a41186a2208200441a1036a29000037030020042004290089033703f80102400240024020042d0088034101470d00200441f8006a41186a2008290300370300200441f8006a41106a2007290300370300200441f8006a41086a2006290300370300200420042903f8013703780240200428029c01450d00200510230b200441d8016a41186a200441f8006a41186a290300370300200441d8016a41106a200441f8006a41106a290300370300200441d8016a41086a200441f8006a41086a290300370300200420042903783703d801200441386a200441d8016a10c60120044188036a20042802382209200428024010e20120044198016a41086a220620044188036a41086a29030037030020044198016a41106a220720044188036a41106a29030037030020044198016a41186a220820044188036a41186a290300370300200441f8016a41086a220a200441b4036a290200370300200441f8016a41106a220b200441bc036a290200370300200441f8016a41186a220c200441c4036a290200370300200441f8016a41206a220d200441cc036a290200370300200441f8016a41286a220e200441d4036a290200370300200441f8016a41306a220f200441dc036a280200360200200420042903880337039801200420042902ac033703f80120042802a8032205450d01200441d8026a41186a2008290300370300200441d8026a41106a2007290300370300200441d8026a41086a2006290300370300200441086a200a290300370300200441106a200b290300370300200441186a200c290300370300200441206a200d290300370300200441286a200e290300370300200441306a200f28020036020020042004290398013703d802200420042903f8013703000240200428023c450d00200910230b200441f8016a41186a200441d8016a41186a2903002210370300200441f8016a41106a200441d8016a41106a2903002211370300200441f8016a41086a200441d8016a41086a2903002212370300200420042903d80122133703f80120044188036a41186a201037030020044188036a41106a201137030020044188036a41086a201237030020044188036a41286a200441d8026a41086a290300221437030020044188036a41306a200441d8026a41106a290300221537030020044188036a41386a200441d8026a41186a29030022163703002004201337038803200420042903d80222173703a803200441386a41386a2016370300200441386a41306a2015370300200441386a41286a2014370300200441d8006a2017370300200441386a41186a2010370300200441386a41106a2011370300200441386a41086a2012370300200420133703380c020b200428029c01450d04200510230c040b0240200428023c450d00200910230b200441f8016a41186a200441d8016a41186a290300370300200441f8016a41106a200441d8016a41106a290300370300200441f8016a41086a200441d8016a41086a290300370300200420042903d8013703f8010b2005450d0220044198016a41386a2207200441386a41386a29030037030020044198016a41306a2208200441386a41306a29030037030020044198016a41286a220a200441386a41286a29030037030020044198016a41206a220b200441386a41206a29030037030020044198016a41186a200441386a41186a220629030037030020044198016a41106a200441386a41106a220c29030037030020044198016a41086a200441386a41086a220d2903003703002004200429033837039801200441d8016a41186a2006290300370300200441d8016a41106a200c290300370300200441d8016a41086a200d290300370300200420042903383703d801200441f8016a41186a22062007290300370300200441f8016a41106a22072008290300370300200441f8016a41086a2208200a29030037030020042005360298022004200b2903003703f8012004419c026a2004290300370200200441a4026a200441086a290300370200200441ac026a200441106a290300370200200441b4026a200441186a290300370200200441bc026a200441206a290300370200200441c4026a200441286a290300370200200441cc026a200441306a2802003602002006290300211020072007290300221120027c22123703002006201020037c2012201154ad7c3703002008200829030020037c20042903f801221020027c2211201054ad7c2212370300200420113703f80120042003370380012004200237037802400240200220038450450d004200210342002110420021020c010b200420013602d402200441d8026a2001200441f8006a200441d4026a10a202024020042802d8024101470d004200211020042903e0022103420121020c010b20044180036a2903002110200441f8026a29030021034200210220042903e0024201520d00200441d8026a41106a2903002113200441c0036a200441d8026a41186a290300370300200441b8036a201337030020044188036a41086a41003a000020044191036a200129000037000020044199036a200141086a290000370000200441a1036a200141106a290000370000200441a9036a200141186a290000370000200441023a00880320044188036a10e0010b200442f3e885db96cddbb320370378200441f8006a200441f8016a41386a20112012411f10990220044188036a200441d8016a10c601200428028803210520042004280290033602dc02200420053602d802200441f8016a200441d8026a10ec010240200428028c03450d00200510230b0240200428029c022205450d00200541186c450d0020042802980210230b0240200441a8026a28020041ffffffff0371450d0020042802a40210230b200242018521020c030b20044198016a200110c70120044188036a200428029801220520042802a00110e101200441f8016a41086a220120044191036a290000370300200441f8016a41106a220620044199036a290000370300200441f8016a41186a2207200441a1036a29000037030020042004290089033703f801024020042d0088034101470d00200441386a41186a2007290300370300200441386a41106a2006290300370300200441386a41086a2001290300370300200420042903f8013703380240200428029c01450d00200510230b20044198016a41186a200441386a41186a29030037030020044198016a41106a200441386a41106a29030037030020044198016a41086a200441386a41086a2903003703002004200429033837039801200420023703002004200337030802400240200220038450450d004200210242002103420021100c010b200420044198016a3602d802200441f8016a20044198016a2004200441d8026a10a202024020042802f8014101470d00420021102004290380022103420121020c010b200441a0026a290300211020044198026a2903002103420021022004290380024201520d00200441f8016a41106a2903002111200441c0036a200441f8016a41186a290300370300200441b8036a201137030020044188036a41086a41003a000020044191036a20042903980137000020044199036a20044198016a41086a290300370000200441a1036a20044198016a41106a290300370000200441a9036a20044198016a41186a290300370000200441023a00880320044188036a10e0010b200242018521020c030b200428029c01450d0120051023420021020c020b2004200237039801200420033703a00102400240200220038450450d004200210342002110420021020c010b20042001360238200441f8016a200120044198016a200441386a10a202024020042802f8014101470d00420021102004290380022103420121020c010b200441a0026a290300211020044198026a2903002103420021022004290380024201520d00200441f8016a41106a2903002111200441c0036a200441f8016a41186a290300370300200441b8036a201137030020044188036a41086a41003a000020044191036a200129000037000020044199036a200141086a290000370000200441a1036a200141106a290000370000200441a9036a200141186a290000370000200441023a00880320044188036a10e0010b200242018521020c010b420021020b2000200337030820002002370300200041106a2010370300200441f0036a24000b91470b017f067e017f017e017f017e017f017e017f057e167f230041b0036b22052400200341286a2903002106200341186a2903002107200341086a2903002108200329032021092003290310210a2003290300210b20054190036a41086a220c42003703002005420037039003418fcdc200ad4280808080f00084220d100c220e290000210f200541a0036a41086a2210200e41086a2900003703002005200f3703a003200e1023200c2010290300370300200520052903a0033703900341ccc5c000ad4280808080900284100c220e290000210f200e2900082111200e1023200541f0026a41086a2212200c29030037030020052011370388032005200f3703800320052005290390033703f002200541386a200541f0026a108802024002400240024002400240024002400240024002400240024002400240024002402005280238417d710d004110210c0c010b200c42003703002005420037039003200d100c220e290000210f2010200e41086a2900003703002005200f3703a003200e1023200c2010290300370300200520052903a0033703900341b8dbc100ad4280808080900184100c2210290000210f20102900082111201010232012200c29030037030020052011370388032005200f3703800320052005290390033703f002200541e0006a200541f0026a10ba01024020052903604202510d004110210c200541e0006a41106a2802002004470d010b4200210f20054190036a41086a220c42003703002005420037039003418fcdc200ad4280808080f00084100c22102900002111200541a0036a41086a220e201041086a290000370300200520113703a00320101023200c200e290300370300200520052903a0033703900341b0e4c100ad4280808080b00184100c221029000021112010290008210d20101023200541f0026a41086a200c2903003703002005200d37038803200520113703800320052005290390033703f002200541203602e4022005200541f0026a3602e002200541a0036a200541f0026aad428080808080048422131010108b010240024020052802a003220c0d000c010b20052802a4032110024002400240200e280200220e4110490d00200e417071220e4110460d00200e4120470d010b200541003602b802200542013703b0022005410a360294032005200541e0026a360290032005200541b0026a3602a002200541f4006a41013602002005420137026420054180c5c600360260200520054190036a360270200541a0026a4184a5c200200541e0006a10311a20053502b80242208620053502b00284100a024020052802b402450d0020052802b00210230b4200210f0c010b200c41086a290000210d200c2900002114200c41286a2900002115200c41186a2900002111200c2900202116200c29001021174201210f0b2010450d00200c10230b024002400240200f500d0041031021220c450d0a200c417f20092016852006201585844200522009201654200620155420062015511b22121b3a0002200c417f200a201785200720118584420052200a201754200720115420072011511b1b220e3a0001200c417f200b2014852008200d8584420052200b2014542008200d542008200d511b1b22103a0000201041014b0d010240024020100e020001000b200e41014b0d020240200e0e020001000b200c10234111210c20120d010c040b200c10230b20054190036a41086a220c42003703002005420037039003418fcdc200ad4280808080f00084100c2210290000210f200541a0036a41086a220e201041086a2900003703002005200f3703a00320101023200c200e290300370300200520052903a0033703900341a8c5c000ad4280808080a00284100c2210290000210f2010290008211120101023200541f0026a41086a200c29030037030020052011370388032005200f3703800320052005290390033703f002200541e0006a20131010108b01024002402005280260220c450d00200528026421102005200541e0006a41086a2802003602b4022005200c3602b002200541306a200541b0026a108801024002402005280230450d0041012112419ca8c700210e0c010b2005280234210e410021120b02402010450d00200c10230b4112210c2012450d010c040b4100210e0b20054190036a41086a221042003703002005420037039003418fcdc200ad4280808080f00084220d100c220c290000210f200541a0036a41086a2212200c41086a2900003703002005200f3703a003200c102320102012290300370300200520052903a0033703900341e4d8c100ad4280808080e00184100c220c290000210f200c2900082111200c1023200541f0026a41086a2218201029030037030020052011370388032005200f3703800320052005290390033703f002200541286a200541f0026a412010cd014113210c200041086a280200200e200528022c410020052802281b22042004200e4b1b220e470d02201042003703002005420037039003200d100c220c290000210f2012200c41086a2900003703002005200f3703a003200c102320102012290300370300200520052903a0033703900341a8c5c000ad4280808080a00284100c220c290000210f200c2900082111200c10232018201029030037030020052011370388032005200f3703800320052005290390033703f002200541e0006a200541f0026a412010890220052802602210450d0120052005290264220f37024420052010360240200028020021192000280204211a0240200e0d00411c210c0c060b4114210c200f422088a720192f010022004d0d05200541e8006a2212201020004105746a220c41096a290000370300200541f0006a2210200c41116a290000370300200541f7006a2200200c41186a2900003700002005200c290001370360200c2d0000210c412010212204450d072004200c3a000020042005290360370001200441096a2012290300370000200441116a2010290300370000200441186a200029000037000020054281808080103702f402200520043602f00241012112411c210c200e4101460d04200528024820192f010222104d0d03200541b0026a41086a221b200528024020104105746a221041096a290000370300200541b0026a41106a221c201041116a290000370300200541b0026a41176a221d201041186a290000370000200520102900013703b002201941046a2118200e410174417c6a210e20102d0000211e4121210041022112410121100340200541e0006a41176a221f201d290000370000200541e0006a41106a2220201c290300370300200541e0006a41086a2221201b290300370300200520052903b00237036002402012417f6a2010470d00200541f0026a20104101109a0120052802f00221040b200420006a2210417f6a201e3a000020102005290360370000201041086a2021290300370000201041106a2020290300370000201041176a201f290000370000200520123602f802200e450d05200528024820182f010022104d0d04201b200528024020104105746a221041096a290000370300201c201041116a290000370300201d201041186a290000370000200520102900013703b002200e417e6a210e201841026a2118200041206a2100201241016a211220102d0000211e20052802f40221100c000b0b200c10234111210c0c010b4112210c0b2001108302200041046a28020041808080807872418080808078460d0e200028020010230c0e0b4114210c0b0240201a41808080807872418080808078460d00201910230b20052802f40241ffffff3f71211b0c010b4100211b410121040240201a41808080807872418080808078460d00201910230b410021120b0240200c411c460d0041012103201b450d0a0c090b20054190036a41086a220c42003703002005420037039003418fcdc200ad4280808080f00084100c2210290000210f200541a0036a41086a220e201041086a2900003703002005200f3703a00320101023200c200e290300370300200520052903a0033703900341bac5c000ad4280808080a00284100c2210290000210f2010290008211120101023200541f0026a41086a200c29030037030020052011370388032005200f3703800320052005290390033703f002200541e0006a200541f0026a41201089022005280260221e450d0520052005290264220f3702542005201e360250200541e0006a200141c00110a1051a200541b0026a200541e0006a200541d0006a200541c0006a10a302200fa7212120052d00b0024101460d0320052802b4022222200541b0026a410c6a2802002223412c6c22246a2125200541b0026a41086a2226280200212702402024450d00200541f0026a41086a2119418fcdc200ad4280808080f00084210f41bbacc300ad4280808080a00184210620222118024002400340200f100c220c2900002111200541a0036a41086a221c200c41086a290000370300200520113703a003200c10232006100c220c2900082111200c2800042128200c2800002129200c102341201021220c450d04200c2018410c6a220e290000370000200c41186a200e41186a222a290000370000200c41106a200e41106a222b290000370000200c41086a200e41086a222c2900003700002005200cad4280808080800484100d22102900003703f00220101023200541003a00702005200c41206a36026c2005200c360268200520193602642005200541f0026a360260200541b0026a200541e0006a1065200c102320052802b802221f41206a2210417f4c0d0b20052802b00221200240024002402010450d0020101021220c450d072010410f4d0d01201021000c020b4110210041101021220c0d010c080b201041017422004110200041104b1b22004100480d06024020102000470d00201021000c010b200c201020001025220c450d070b200c20052903a003370000200c41086a201c2903003700000240024020004170714110460d002000211d0c010b2000410174221d4120201d41204b1b221d4100480d062000201d460d00200c2000201d1025220c450d070b200c2011370018200c2028360014200c20293600100240201d41606a201f4f0d00201f415f4b0d06201d41017422002010200020104b1b22004100480d06201d2000460d00200c201d20001025220c450d070b200c41206a2020201f10a1051a024020052802b402450d00202010230b200541206a200c2010419ca8c70041004100108c0120052802202120200c1023200f100c220c2900002111201c200c41086a290000370300200520113703a003200c102341e2c4c000ad4280808080a00184100c220c2900082111200c2800042128200c2800002129200c102341201021220c450d04200c200e290000370000200c41186a202a290000370000200c41106a202b290000370000200c41086a202c2900003700002005200cad4280808080800484100d22102900003703f00220101023200541003a00702005200c41206a36026c2005200c360268200520193602642005200541f0026a360260200541b0026a200541e0006a1065200c102320052802b802221d41206a2210417f4c0d0b20052802b002211f0240024002402010450d0020101021220c450d072010410f4d0d01201021000c020b4110210041101021220c450d080c010b201041017422004110200041104b1b22004100480d06024020102000470d00201021000c010b200c201020001025220c450d070b200c20052903a003370000200c41086a201c2903003700000240024020004170714110460d002000211c0c010b2000410174221c4120201c41204b1b221c4100480d062000201c460d00200c2000201c1025220c450d070b200c2011370018200c2028360014200c20293600100240201c41606a201d4f0d00201d415f4b0d06201c41017422002010200020104b1b22004100480d06201c2000460d00200c201c20001025220c450d070b200c41206a201f201d10a1051a024020052802b402450d00201f10230b200541e0006a200c201010a402024020052d00702210410246221c0d002005280260211a2005280264212d2005290368210d0b200c10230240024002400240024002402020410146220c20104102472200460d00200c450d010240201841086a2802004101470d0002402018280200220c200e460d00200c200e412010a3050d010b200c2f012041ffff03460d030b4119210c20104102460d08202d41ffffff3f710d070c080b4116210c20104102460d07202d41ffffff3f71450d070c060b02402000450d0002402018280208220c450d002018280200221c200c41226c6a211f200d422088a72120200da7410574211d03402005201c220e3602b002200e41226a211c201d2110201a210c0340024020100d004117210c0c080b0240200e200c460d00200c200e412010a3052100201041606a2110200c41206a210c20000d010b0b200541e0006a200541b0026a10c8010240200528026c220c450d00200528026821100240200528027041ffffffff0371450d00200c10230b201020204d0d004118210c0c070b201c201f470d000b0b202d41ffffff3f71450d030c020b418189c20041fd0041808ac200104f000b201c0d01202d41ffffff3f71450d010b201a10230b2018412c6a22182025470d010c040b0b202d41ffffff3f71450d010b201a10230b02402023450d002023412c6c21102022210303400240200341046a280200220e450d00200e41226c450d00200328020010230b2003412c6a2103201041546a22100d000b0b2027450d052027412c6c450d05202210230c050b200541003602f802200542043703f002200541f0026a41002024412c6d10a60120052802f002211020052802f802210c200520223602682005202536026c20052027ad4220862022ad843703602005200541a0036a3602702026200c3602002005200541f0026a41086a3602b40220052010200c412c6c6a3602b002200541e0006a200541b0026a10a50220052802f4022119200541e0006a2004201220052802f002222820052802f802221a10d801200541a0026a41086a200541e0006a41086a280200360200200520052903603703a00202400240200528026c450d00411a210c20052802a802212020052802a002211f0c010b02400240024020052802a002221f450d00024020052802a402220e450d00200e210c201f2110034020102802c8052110200c417f6a220c0d000b201f210c0340200c200c2f01064102746a41c8056a280200210c200e417f6a220e0d000b200541e0006a210e0c020b200541e0006a210e201f2110201f210c0c010b4100211020054100360264200541e0006a210e0c010b2005200c360264200541ec006a200c2f0106360200200541003602602005200541a0026a360268200541a0026a210c0b200541f0026a41086a200e41086a290200220f3703002005200e29020022113703f00220052802a8022120200541ec006a4100360200200541e0006a41186a200f3703002005200c36026820052010360264200541003602602005201137037020052020360280010240024020200d00427f2107420021084200210d420021094200210a427f21060c010b20052020417f6a36028001200541e0006a410020101b2218280200210e2018280208211c0240024002400240201828020c22002018280204220c2f01064f0d00200c21100c010b0340200c2802002210450d02200e41016a210e200c2f010421002010210c200020102f01064f0d000b0b2000ad422086201cad84210f0c010b201cad210f410021100b200f422088a7221c41016a2100200fa7211d02400240200e0d002010210c0c010b201020004102746a41c8056a280200210c41002100200e417f6a220e450d000340200c2802c805210c200e417f6a220e0d000b0b2018200036020c2018201d3602082018200c360204201841003602002010201c4105746a41e8026a210c427f2107427f2106420021094200210a420021084200210d03402005200c41086a29030022114200200c290300220f420010a605200541106a200f4200200f420010a605427f200d427f200541106a41086a290300220b2005290300221520157c7c2215201120052903082217842017844200522015200b5472220c1b7c2008427f2005290310200c1b7c220b200854220cad7c2208200c2008200d542008200d511b220c1b210d427f200b200c1b210820112006200f200754201120065420112006511b220c1b2106200f2007200c1b21072011200a7c200f20097c2209200f54ad7c210a200528028001220c450d012005200c417f6a36028001200541e0006a410020052802641b2218280200210e2018280208211c024002400240201828020c22002018280204220c2f01064f0d00200c21100c010b02400340200c2802002210450d01200e41016a210e200c2f010421002010210c200020102f0106490d020c000b0b201cad210f410021100c010b2000ad422086201cad84210f0b200f422088a7221c41016a2100200fa7211d02400240200e0d002010210c0c010b201020004102746a41c8056a280200210c41002100200e417f6a220e450d000340200c2802c805210c200e417f6a220e0d000b0b2018200036020c2018201d3602082018200c360204201841003602002010201c4105746a41e8026a210c0c000b0b200541d8026a200d370300200541b0026a41186a200a370300200520083703d002200520093703c002200520073703b002200520063703b80202400240200541b0026a2003460d00200541b0026a2003413010a3050d010b02400240201f0d004100211f41002103410021200c010b0240024020052802a402220c0d00201f21030c010b200c2103201f2110034020102802c80521102003417f6a22030d000b201f21030340200320032f01064102746a41c8056a2802002103200c417f6a220c0d000b2010211f0b20032f0106210c0b200541fc006a200c360200200541e0006a41186a4100360200200541f4006a2003360200200520203602800120054100360270200542003703682005201f360264200541003602602005200541a0036a36028401200541e0026a200541e0006a10d90120052802e002211d20052802e402211f20052802e802211c20054190036a41086a220342003703002005420037039003418fcdc200ad4280808080f00084100c220c290000210f200541a0036a41086a2210200c41086a2900003703002005200f3703a003200c102320032010290300370300200520052903a0033703900341d5cfc000ad4280808080d00184100c220c290000210f200c2900082111200c1023200541f0026a41086a200329030037030020052011370388032005200f3703800320052005290390033703f00220054100360268200542013703602012200541e0006a106102402012450d002012410574211241002005280268220c6b210e20052802642100200421030340024002402000200e6a4120490d00200528026021100c010b200c41206a2210200c490d06200041017422012010200120104b1b22014100480d060240024020000d00024020010d00410121100c020b200110212210450d090c010b2005280260211020002001460d0020102000200110252210450d080b2005200136026420052010360260200121000b2010200c6a22102003290000370000201041186a200341186a290000370000201041106a200341106a290000370000201041086a200341086a2900003700002005200c41206a220c360268200e41606a210e200341206a2103201241606a22120d000b0b201c200541e0006a10610240201c450d00201d201c41d0006c6a2118201d211203400240024020052802642210200528026822036b4120490d002005280260210c0c010b200341206a220c2003490d062010410174220e200c200e200c4b1b220e4100480d060240024020100d000240200e0d004101210c0c020b200e1021220c450d090c010b2005280260210c2010200e460d00200c2010200e1025220c450d080b2005200e3602642005200c3602600b200c20036a220c2012290000370000200c41186a201241186a290000370000200c41106a201241106a290000370000200c41086a201241086a2900003700002005200341206a3602682005201241206a3602a003200541a0036a200541e0006a10db012005201241306a3602a003200541a0036a200541e0006a10db01201228024021032012280248220c200541e0006a10610240200c450d00200c41306c21000340024002402005280264220e2005280268220c6b4120490d00200528026021100c010b200c41206a2210200c490d08200e41017422012010200120104b1b22014100480d0802400240200e0d00024020010d00410121100c020b200110212210450d0b0c010b20052802602110200e2001460d002010200e200110252210450d0a0b20052001360264200520103602600b2010200c6a2210200341106a290000370000201041186a200341286a290000370000201041106a200341206a290000370000201041086a200341186a2900003700002005200c41206a360268200520033602a003200541a0036a200541e0006a10db01200341306a2103200041506a22000d000b0b2018201241d0006a2212470d000b0b024002400240024002400240200241ff0171220341024b0d0020030e03010203010b20052802682103200528026421102005280260210c0c040b4100210e0c020b4101210e0c010b4102210e0b2005200e3a00a003024002402005280264221020052802682203460d002005280260210c0c010b200341016a220c2003490d0520034101742210200c2010200c4b1b22104100480d050240024020030d0041002103024020100d004101210c0c020b20101021220c450d080c010b2005280260210c20032010460d00200c200320101025220c450d070b200520103602642005200c3602600b200c20036a200e3a00002005200341016a22033602680b20132003ad422086200cad84100e02402010450d00200c10230b0240201b450d00200410230b0240201c450d00201c41d0006c210c201d41c4006a21030340024020032802002210450d00201041306c450d002003417c6a28020010230b200341d0006a2103200c41b07f6a220c0d000b0b0240201f450d00201f41d0006c450d00201d10230b200541e0006a41286a2210200541b0026a41286a290300370300200541e0006a41206a220e200541b0026a41206a290300370300200541e0006a41186a2200200541b0026a41186a290300370300200541e0006a41106a2201200541b0026a41106a290300370300200541e0006a41086a2212200541b0026a41086a290300370300200520052903b00237036020054190036a41086a220342003703002005420037039003418fcdc200ad4280808080f00084100c220c290000210f200541a0036a41086a2204200c41086a2900003703002005200f3703a003200c102320032004290300370300200520052903a0033703900341b0e4c100ad4280808080b00184100c220c290000210f200c2900082111200c1023200541f0026a41086a200329030037030020052011370388032005200f3703800320052005290390033703f002413010212203450d0220032005290360370000200341286a2010290300370000200341206a200e290300370000200341186a2000290300370000200341106a2001290300370000200341086a201229030037000020132003ad4280808080800684100e200310230240201a450d00201a412c6c210c2028210303400240200341046a2802002210450d00201041306c450d00200328020010230b2003412c6a2103200c41546a220c0d000b0b02402019450d002019412c6c450d00202810230b0240202141ffffff3f71450d00201e10230b0240200528024441ffffff3f71450d00200528024010230b411c210c0c0c0b411b210c0b02400240201f450d000240024020052802a40222100d00201f21030c010b20102103201f210e0340200e2802c805210e2003417f6a22030d000b201f21030340200320032f01064102746a41c8056a28020021032010417f6a22100d000b200e211f0b200541fc006a20032f0106360200200541f8006a4100360200200541f4006a200336020020054100360270200542003703682005201f360264200541003602600c010b41002120200541f4006a4100360200200541003602640b2005202036028001200541e0006a10a6020240201a450d00201a412c6c21102028210303400240200341046a280200220e450d00200e41306c450d00200328020010230b2003412c6a2103201041546a22100d000b0b2019450d042019412c6c450d04202810230c040b1033000b102c000b102a000b4115210c0b41002103202141ffffff3f71450d01201e1023201b0d030c040b4112210c410121030b201b0d010c020b1032000b200410230b0240200528024441ffffff3f71450d00200528024010230b2003450d0020011083020b200541b0036a2400200c0bce0203027f017e037f23004180026b22012400200141086a2000109702200141e0006a200128020822002001280210220210980220012903602103200141b8016a200141e8006a41c40010a1051a200141b4016a41026a2204200141af016a2d00003a0000200120012f00ad013b01b4010240024020034201510d0041002105200141186a410041c40010a0051a0c010b20012d00ac012105200141186a200141b8016a41c40010a1051a200141146a41026a20042d00003a0000200120012f01b4013b01140b200141e8006a200141186a41c40010a1052104200141af016a200141166a2d00003a000020014201370360200141002005411874220541808080786a2206200620054b1b4118763a00ac01200120012f01143b00ad01200120023602bc01200120003602b8012004200141b8016a1098030240200128020c450d00200010230b20014180026a24000b9b0b06047f027e027f067e037f067e230041d0026b22042400200328020021052004200110970220044180016a20042802002206200428020822071098022004290380012108420021092004420037038001200441c8016a280200210a20042d00cc01210b02400240200842015122030d00200441106a41306a4200370300200441106a41286a4200370300200441106a41206a4200370300200441106a41186a4200370300200441206a4200370300200441186a4200370300200442003703104200210c4200210d4200210e4200210f0c010b200441b8016a290300211020044180016a41306a290300211120044180016a41206a290300210c20044180016a41186a2903002109200441c0016a290300210f200429039001210e200429038801210d200441106a41206a20044180016a41286a290300370300200441106a41286a2011370300200441106a41306a2010370300200441206a20093703002004200c3703282004200d3703102004200e3703180b0240024002400240427f200d20097c22092009200d542212200e200c7c2012ad7c2209200e542009200e511b22121b427f200920121b8450450d0041a4acc500ad4280808080b00184210e41838a1c21120c010b200d200229030022107c2209200d542212200e200241086a29030022117c2012ad7c220d200e54200d200e511b4101470d0141f4acc500ad4280808080800184210e41838a0821120b200e4280807c832108200e42088842ff0183210c200ea72103410121020c010b200420093703102004200d370318200441c8006a41186a200441206a220241086a290300220e370300200441c8006a41206a2212200241106a290300370300200441f0006a2213200241186a290300370300200441f8006a2214200241206a2903003703002004200d3703502004200937034820042002290300220c37035802400240427f2009200c7c220c200c2009542202200d200e7c2002ad7c220e200d54200e200d511b22021b220c4280c8afa025544100427f200e20021b220e501b0d00200441c8006a41106a290300210e2014290300210c20132903002115201229030021162004290350211720042903482118420121192004290360211a0c010b420021190240200c200e84500d00200c200e10eb01200441a0026a200e37030020044198026a200c370300200441e8016a41086a41013a0000200441f1016a2005290000370000200441f9016a200541086a29000037000020044181026a200541106a29000037000020044189026a200541186a290000370000200441023a00e801200441e8016a10e0010b0b200441a8016a2016370300200441b0016a201537030020044190016a2017370300200441b8016a200c37030020044198016a200e3703002004201a3703a0012004200f3703c00120042018370388014201210c410021022004200b4100200842015122121b3a00cc012004200a410020121b3602c801200420194201512212ad37038001024020120d002007ad4220862006ad8410114200210c420021080c010b200420073602ec01200420063602e80120044188016a200441e8016a109803420021080b02402004280204450d00200610230b024002402002450d0020002012360204200041086a200c4208862003ad42ff018384200884370200410121010c010b024002400240200341ff017122030d00200c4200510d0041032102200441e8016a21030c010b2003450d01200c4200520d014104210220044180016a21030b200341046a20023a0000200341003a0000200341056a20012900003700002003410d6a200141086a290000370000200341156a200141106a2900003700002003411d6a200141186a290000370000200310e0010b200041286a2011370300200041206a2010370300200041186a200d370300200041106a2009370300200041086a4200370300410021010b20002001360200200441d0026a24000bf6c8010e077f017e057f017e0b7f017e037f017e017f017e017f017e017f017e230041d0016b220424002004200336020c20044100360218200442043703102001280204210520012802002106024002400240024002400240024002400240024020012802082203450d0020034103742107200441b0016a41106a2108200441b0016a41176a21092006210a03402002280208200a290200220ba722034d0d07200441b0016a41086a220c200228020020034105746a220341096a2900003703002008200341116a2900003703002009200341186a290000370000200420032900013703b00120032d0000210d412210212203450d02200428020c220e280208200b422088a741ffff0371220f4d0d06200441c0006a41106a2210200e280200200f4105746a220e41116a290000370300200441c0006a41176a220f200e41186a290000370000200441c0006a41086a200e41096a2900002211370300200e290001210b2003200e2d00003a00002003200b370001200341096a2011370000200341ffff033b0120200341116a2010290300370000200341186a200f2900003700002004200b37034020044190016a41176a220f200929000037000020044190016a41106a2210200829030037030020044190016a41086a2212200c290300370300200420042903b0013703900102402004280218220e2004280214470d00200441106a200e410110a6012004280218210e0b200a41086a210a2004280210200e412c6c6a220e200d3a000c200e428180808010370204200e2003360200200e410d6a200429039001370000200e41156a2012290300370000200e411d6a2010290300370000200e41246a200f2900003700002004200428021841016a360218200741786a22070d000b0b0240200541ffffffff0171450d00200610230b200128020c2113200141106a2802002114200141146a2802002203450d0320132003410c6c6a211520044190016a41106a210720044190016a41176a210c2013210a034002400240200a41066a2f0100220841ffff03460d002002280208200a28020022034b0d0120004181043b01000c050b200041013b01000c040b200a41086a2f01002109200a41046a2f0100210e20044190016a41086a2210200228020020034105746a220341096a2900003703002007200341116a290000370300200c200341186a290000370000200420032900013703900120032d0000211241c40010212203450d01200428020c220d280208220f200e4d0d02200441b0016a41086a2206200d280200220d200e4105746a220e41096a290000370300200441b0016a41106a2205200e41116a290000370300200441b0016a41176a2216200e41186a2900003700002004200e2900013703b0010240200f20094d0d00200e2d0000210f200441c0006a41086a2217200d20094105746a220e41096a290000370300200441c0006a41106a2209200e41116a290000370300200441c0006a41176a220d200e41186a290000370000200e290001210b200e2d0000210e2003200f3a0000200320042903b001370001200341096a2006290300370000200341116a2005290300370000200341186a20162900003700002003200e3a0022200320083b01202004200b370340200320042903403700232003412b6a2017290300370000200341336a20092903003700002003413a6a200d29000037000020032008417f733b0142200441206a41176a2208200c290000370000200441206a41106a22092007290300370300200441206a41086a220d2010290300370300200420042903900137032002402004280218220e2004280214470d00200441106a200e410110a6012004280218210e0b2004280210200e412c6c6a220e20123a000c200e428280808020370204200e2003360200200e410d6a2004290320370000200e41156a200d290300370000200e411d6a2009290300370000200e41246a20082900003700002004200428021841016a360218200a410c6a220a2015470d010c050b0b20004181043b0100200310230c020b102a000b20004181043b0100200310230b4100210641012102200441106a210802402014450d002014410c6c450d00201310230b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f4101211041012112410121140c040b02402014450d002014410c6c450d00201310230b200128021821172001411c6a28020021150240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141206a2802002203450d00201720034104746a2116200441c0006a41086a210e200441c0006a41106a210a200441c0006a41176a2108201721090240024003402009410c6a2f0100210c2009280200210d2004200941046a290200220b3703800102400240200428020c2203280208200ba741ffff037122074d0d00200e200328020020074105746a220341096a290000370300200a200341116a2900003703002008200341186a2900003700002004200329000137034020032d00002107412210212203450d06200320073a0000200320042903403700012003200b421088a722123b0120200341096a200e290300370000200341116a200a290300370000200341186a20082900003700002004428180808010370294012004200336029001200428020c220f28020820042f01840122104b0d0141000d004122450d00200310230b20004181043b01000c3a0b20042f0186012107200441b0016a41176a2206200f28020020104105746a220341186a290000370000200441b0016a41106a2210200341116a290000370300200441b0016a41086a220f200341096a290000220b3703002004200329000122113703b00120032d0000210520082006290000370000200a2010290300370300200e200b3703002004201137034020044190016a4101410110af01200428029001220320053a0022200341236a20042903403700002003412b6a200e290300370000200341336a200a2903003700002003413a6a2008290000370000200341c2006a20073b01002004410236022820042004280294012210360224200420033602200240417f2012411074221220074110746a220720072012491b411076220741ffff03470d00200041013b01000c030b200428020c2212280208200c4d0d012007417f732106200e2012280200200c4105746a220741096a290000370300200a200741116a2900003703002008200741186a290000370000200420072900013703404102210c20072d00002107024020104102470d00200441206a4102410110af01200428022021032004280228210c0b2003200c41226c6a220320073a000020032004290340370001200320063b0120200341096a200e290300370000200341116a200a290300370000200341186a20082900003700002004200428022841016a36022802402002280208200d4d0d0020022802002103200f200441206a41086a280200360200200e2003200d4105746a220341096a290000370300200a200341116a2900003703002008200341186a290000370000200420042903203703b0012004200329000137034020032d000021070240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a220320042903b001370200200320073a000c200341086a200f2802003602002003410d6a2004290340370000200341156a200e2903003700002003411d6a200a290300370000200341246a20082900003700002004200428021841016a360218200941106a22092016470d010c040b0b20004181043b0100200428022421100c010b20004181043b01000b2010450d36201041226c450d36200428022010230c360b0240201541ffffffff0071450d00201710230b20012802242118200141286a280200211902402001412c6a2802002203450d002018200341146c6a211a2004418a016a211b20044180016a41086a211c200441c0006a41106a2107200441c0006a41176a210c20182115024002400240034020152f01102114201528020021132015290104210b201c2015410c6a2801003602002004200b3703800102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f018201210e200441c0006a41086a220d2003280200200a4105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d0000210341221021220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200d290300370000200f41116a2007290300370000200f41186a200c2900003700002004428180808010370294012004200f360290010240200428020c220328020820042f018401220a4b0d00410221034101210a0c390b201541146a2115417f200e411074220e20042f01860122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201b21080340200c201629000037000020072005290300370300200d2012290300370300200420042903b0013703400240200e417f6a2003470d0020044190016a2003410110af01200428029001210f0b200f200a6a220941606a20173a0000200941616a22032004290340370000200c290000210b20072903002111200d290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e360298010240200a41e400470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d0000211720042802940121030c000b0b410221030c380b200428029401210a20034103470d362004200e3602282004200a3602242004200f3602200240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200d200328020020144105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d000021090240200a200e470d00200441206a200e410110af012004280220210f2004280228210e0b200f200e41226c6a220320093a000020032004290340370001200c290000210b20072903002111200d290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b3700002004200428022841016a360228200228020820134d0d03200228020021032012200441206a41086a280200360200200d200320134105746a220341096a2900003703002007200341116a290000370300200c200341186a290000370000200420042903203703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200d2903003700002003411d6a2007290300370000200341246a200c2900003700002004200428021841016a3602182015201a470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b01002004280224210a0b200a450d34200a41226c450d34200428022010230c340b02402019450d00201941146c450d00201810230b20012802302118200141346a28020021190240200141386a2802002203450d002018200341186c6a211a2004419a016a211b20044190016a41086a211c200441c0006a41106a2107200441c0006a41176a210c20182115024002400240034020152f01142114201528020021132015290104210b201c2015410c6a2901003703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220d2003280200200a4105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d0000210341221021220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200d290300370000200f41116a2007290300370000200f41186a200c29000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c350b201541186a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201b21080340200c201629000037000020072005290300370300200d2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a22032004290340370000200c290000210b20072903002111200d290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a418601470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c340b2004280224210a20034103470d322004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200d200328020020144105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a000020032004290340370001200c290000210b20072903002111200d290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200d200320134105746a220341096a2900003703002007200341116a290000370300200c200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200d2903003700002003411d6a2007290300370000200341246a200c2900003700002004200428021841016a3602182015201a470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d30200a41226c450d3020042802800110230c300b02402019450d00201941186c450d00201810230b200128023c2119200141c0006a280200211e0240200141c4006a2802002203450d0020192003411c6c6a21182004419a016a211a20044190016a41106a211c20044190016a41086a211b200441c0006a41176a210720192115024002400240034020152f01182114201528020021132015410c6a29010021112015290104210b201c201541146a280100360200201b20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221021220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c310b2015411c6a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201a2108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41a801470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c300b2004280224210a20034103470d2e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152018470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d2c200a41226c450d2c20042802800110230c2c0b0240201e450d00201e411c6c450d00201910230b20012802482119200141cc006a280200211e0240200141d0006a2802002203450d00201920034105746a21182004419a016a211a20044190016a41106a211c20044190016a41086a211b200441c0006a41176a210720192115024002400240034020152f011c2114201528020021132015410c6a29010021112015290104210b201c201541146a290100370300201b20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221021220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c2d0b201541206a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201a2108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41ca01470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c2c0b2004280224210a20034103470d2a2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152018470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d28200a41226c450d2820042802800110230c280b0240201e41ffffff3f71450d00201910230b2001280254211f200141d8006a280200211e0240200141dc006a2802002203450d00201f200341246c6a21192004419a016a211820044190016a41186a211c20044190016a41106a211b20044190016a41086a211a200441c0006a41176a2107201f2115024002400240034020152f01202114201528020021132015410c6a2901002111201541146a290100211d2015290104210b201c2015411c6a280100360200201b201d370300201a20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221021220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c290b201541246a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e20182108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41ec01470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c280b2004280224210a20034103470d262004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152019470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d24200a41226c450d2420042802800110230c240b0240201e450d00201e41246c450d00201f10230b2001280260211f200141e4006a280200211e0240200141e8006a2802002203450d00201f200341286c6a2119200441ca006a2118200441c0006a41186a211c200441c0006a41106a211b200441c0006a41086a211a200441b0016a41176a2107201f2115024002400240034020152f01242114201528020021132015410c6a2901002111201541146a290100211d2015290104210b201c2015411c6a290100370300201b201d370300201a20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221021220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c250b201541286a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20182108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a418e02470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c240b2004280224210a20034103470d222004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152019470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d20200a41226c450d2020042802800110230c200b0240201e450d00201e41286c450d00201f10230b200128026c211f200141f0006a28020021200240200141f4006a2802002203450d00201f2003412c6c6a211e200441ca006a2119200441e0006a211c200441c0006a41186a211b200441c0006a41106a211a200441c0006a41086a2118200441b0016a41176a2107201f2115024002400240034020152f01282114201528020021132015410c6a2901002111201541146a290100211d2015411c6a29010021212015290104210b201c201541246a280100360200201b2021370300201a201d370300201820113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221021220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c210b2015412c6a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20192108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41b002470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c200b2004280224210a20034103470d1e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201e470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d1c200a41226c450d1c20042802800110230c1c0b02402020450d002020412c6c450d00201f10230b20012802782120200141fc006a280200211f024020014180016a2802002203450d002020200341306c6a211e200441ca006a2119200441e0006a211c200441c0006a41186a211b200441c0006a41106a211a200441c0006a41086a2118200441b0016a41176a210720202115024002400240034020152f012c2114201528020021132015410c6a2901002111201541146a290100211d2015411c6a29010021212015290104210b201c201541246a290100370300201b2021370300201a201d370300201820113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221021220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c1d0b201541306a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20192108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41d202470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c1c0b2004280224210a20034103470d1a2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201e470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d18200a41226c450d1820042802800110230c180b0240201f450d00201f41306c450d00202010230b200128028401212020014188016a280200212202402001418c016a2802002203450d002020200341346c6a211f200441ca006a211e200441e8006a211c200441e0006a211b200441c0006a41186a211a200441c0006a41106a2118200441c0006a41086a2119200441b0016a41176a210720202115024002400240034020152f01302114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015290104210b201c2015412c6a280100360200201b2023370300201a20213703002018201d370300201920113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221021220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c190b201541346a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201e2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41f402470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c180b2004280224210a20034103470d162004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201f470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d14200a41226c450d1420042802800110230c140b02402022450d00202241346c450d00202010230b200128029001212020014194016a2802002122024020014198016a2802002203450d002020200341386c6a211f200441ca006a211e200441e8006a211c200441e0006a211b200441c0006a41186a211a200441c0006a41106a2118200441c0006a41086a2119200441b0016a41176a210720202115024002400240034020152f01342114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015290104210b201c2015412c6a290100370300201b2023370300201a20213703002018201d370300201920113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221021220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c150b201541386a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201e2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a419603470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c140b2004280224210a20034103470d122004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201f470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d10200a41226c450d1020042802800110230c100b02402022450d00202241386c450d00202010230b200128029c012124200141a0016a28020021220240200141a4016a2802002203450d0020242003413c6c6a2120200441ca006a211f200441f0006a211c200441e8006a211b200441e0006a211a200441c0006a41186a2118200441c0006a41106a2119200441c0006a41086a211e200441b0016a41176a210720242115024002400240034020152f01382114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015412c6a29010021252015290104210b201c201541346a280100360200201b2025370300201a2023370300201820213703002019201d370300201e20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221021220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c110b2015413c6a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201f2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41b803470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c100b2004280224210a20034103470d0e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152020470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d0c200a41226c450d0c20042802800110230c0c0b02402022450d002022413c6c450d00202410230b20012802a8012122200141ac016a28020021240240200141b0016a2802002203450d00202220034106746a2120200441ca006a211f200441f0006a211c200441e8006a211b200441e0006a211a200441c0006a41186a2118200441c0006a41106a2119200441c0006a41086a211e200441b0016a41176a210720222115024002400240034020152f013c2114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015412c6a29010021252015290104210b201c201541346a290100370300201b2025370300201a2023370300201820213703002019201d370300201e20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221021220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c0e0b201541c0006a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201f2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41da03470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c0d0b2004280224210a20034103470d0b2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152020470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d09200a41226c450d0920042802800110230c090b0240202441ffffff1f71450d00202210230b20012802b4012126200141b8016a2802002124200141bc016a2802002203450d022026200341c4006c6a2122200441ca006a2120200441f8006a211c200441f0006a211b200441e8006a211a200441e0006a2118200441c0006a41186a2119200441c0006a41106a211e200441c0006a41086a211f200441b0016a41176a21072026211502400240034020152f01402114201528020021132015410c6a290100210b201541146a29010021112015411c6a290100211d201541246a29010021212015412c6a2901002123201541346a290100212520152901042127201c2015413c6a280100360200201b2025370300201a2023370300201820213703002019201d370300201e2011370300201f200b3703002004202737034002400240200428020c220328020820042f0140220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221021220f450d05200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c090b201541c4006a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20202108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a2003410110af012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41fc03470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c080b2004280224210a20034103470d062004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e410110af01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a2003410110a601200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152022470d010c060b0b200041013b01000c030b20004181043b01000c020b20004181043b0100200428028401210a0c010b1033000b200a450d03200a41226c450d0320042802800110230c030b02402024450d00202441c4006c450d00202610230b200041003a0000200041046a20042903103702002000410c6a200441186a2802003602000c370b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b41002102200441106a210802402024450d00202441c4006c450d00202610230b41002109410021050c060b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100210941012102200441106a21080240202441ffffff1f710d00410021050c040b20221023410021050c030b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100210541012102200441106a210802402022450d002022413c6c450d00202410230b410121090b410021160c030b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100211641012102200441106a210802402022450d00202241386c450d00202010230b41012109410121050b410021170c030b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100211741012102200441106a210802402022450d00202241346c450d00202010230b4101210941012105410121160b410021150c030b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100211541012102200441106a21080240201f450d00201f41306c450d00202010230b410121094101210541012116410121170b410021070c030b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100210741012102200441106a210802402020450d002020412c6c450d00201f10230b41012109410121054101211641012117410121150b4100210c0c030b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100210c41012102200441106a21080240201e450d00201e41286c450d00201f10230b4101210941012105410121164101211741012115410121070b410021000c030b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100210041012102200441106a21080240201e450d00201e41246c450d00201f10230b4101210941012105410121164101211741012115410121074101210c0b4100210d0c030b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100210d41012102200441106a21080240201e41ffffff3f71450d00201910230b4101210941012105410121164101211741012115410121074101210c410121000b4100210f0c030b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100210f41012102200441106a21080240201e450d00201e411c6c450d00201910230b4101210941012105410121164101211741012115410121074101210c410121004101210d0b410021100c030b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100211041012102200441106a210802402019450d00201941186c450d00201810230b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f0b410021120c030b200a450d00200a41226c450d00200f10230b200041013a0000200020033a00010b4100211241012102200441106a210802402019450d00201941146c450d00201810230b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f410121100b41002114410021060c040b4100211441012102200441106a21080240201541ffffffff0071450d00201710230b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f4101211041012112410021060c030b20004181043b0100200310230c010b20004181043b01000b41012102200441106a21080240200541ffffffff0171450d00200610230b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f410121104101211241012114410121060b02402004280218220e450d0020042802102103200e412c6c210e03400240200341046a280200220a450d00200a41226c450d00200328020010230b2003412c6a2103200e41546a220e0d000b0b0240200841046a2802002203450d002003412c6c450d00200828020010230b02402006450d00200141106a2802002203450d002003410c6c450d00200128020c10230b02402014450d002001411c6a28020041ffffffff0071450d00200128021810230b02402012450d00200141286a2802002203450d00200341146c450d00200128022410230b02402010450d00200141346a2802002203450d00200341186c450d00200128023010230b0240200f450d00200141c0006a2802002203450d002003411c6c450d00200128023c10230b0240200d450d00200141cc006a28020041ffffff3f71450d00200128024810230b02402000450d00200141d8006a2802002203450d00200341246c450d00200128025410230b0240200c450d00200141e4006a2802002203450d00200341286c450d00200128026010230b02402007450d00200141f0006a2802002203450d002003412c6c450d00200128026c10230b02402015450d00200141fc006a2802002203450d00200341306c450d00200128027810230b02402017450d0020014188016a2802002203450d00200341346c450d0020012802840110230b02402016450d0020014194016a2802002203450d00200341386c450d0020012802900110230b02402005450d00200141a0016a2802002203450d002003413c6c450d00200128029c0110230b02402009450d00200141ac016a28020041ffffff1f71450d0020012802a80110230b2002450d00200141b8016a2802002203450d00200341c4006c450d0020012802b40110230b200441d0016a24000bb00401087f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841010108b0102400240200328021022010d00200041023a00100c010b200328021421042003200341106a41086a28020036022420032001360220200341c8006a200341206a10cf01024002400240024020032802482205450d00200328024c2106024002400240200328022422024104490d00200341c8006a41086a280200210720032002417c6a220836022420032003280220220941046a220a3602202008450d012009280000210920032002417b6a3602242003200a41016a360220200a2d0000220a41014b0d0141002102200a0e020504050b200641ffffff3f710d010c020b200641ffffff3f71450d010b200510230b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034180c5c6003602482003200341386a360258200341c4006a4184a5c200200341c8006a10311a2003350230422086200335022884100a0240200328022c450d00200328022810230b410221020c020b410121020b200341386a41026a200341286a41026a2d0000220a3a0000200341c8006a41026a200a3a0000200320032f002822083b01382000200936020c200020073602082000200636020420002005360200200320083b0148200041136a200a3a0000200020083b00110b200020023a00102004450d00200110230b200341e0006a24000bab120a0d7f017e027f027e017f017e097f027e057f057e23004190036b22022400200141086a28020021032001280204210420002802042105200028020021060240024020002802082207200028020c2208460d0020012802002109200241b0016a410c6a210a200241f0026a41106a2101200241b0016a410472210b20024188016a41086a210c20024188016a41186a210d20024188016a41206a210e41bdadc500ad4280808080800184210f0340200c20072200410c6a29020037030020024188016a41106a2210200041146a290200370300200d2000411c6a290200370300200e200041246a29020037030020022000290204370388012000412c6a210720002802002211450d01200b200229038801370200200b41086a200c290300370200200b41106a2010290300370200200b41186a200d290300370200200b41206a200e290300370200200220113602b001200241f8006a200a10d301200241f8006a41086a290300211220022903782113200241f0026a41186a2214420037030020014200370300200241f0026a41086a22104200370300200242003703f002200f100c220029000021152010200041086a290000370300200220153703f0022000102341c5adc500ad4280808080d00184100c22002900002115200241b0026a41086a2216200041086a290000370300200220153703b00220001023200120022903b002370000200141086a2016290300370000200241d0026a41086a2010290300370300200241d0026a41106a2001290300370300200241d0026a41186a2014290300370300200220022903f0023703d002200241e0006a200241d0026a412010d701200241d0006a2002290368200241e0006a41106a290300427f420010a705200241c0006a2013201220022903504200200228026022001b221542012015420156200241d0006a41086a290300420020001b22154200522015501b22001b2015420020001b10a705200241e0016a41086a2217200a41086a290200370300200241e0016a41106a2218200a41106a290200370300200241e0016a41186a2219200a41186a2902003703002002200a2902003703e00120022802b401211a2002290340211202400240024020022802b80141226c221b450d00201b211c201121000340200041206a2f0100211d2014200041186a2900003703002001200041106a2900003703002010200041086a290000370300200220002900003703f002201d0d02200041226a2100201c415e6a221c0d000b0b420021154108211e410021000240201a450d00201a41226c450d0020111023420021150b420021134100211b0c010b200241306a2012420042ffff03420010a705200241206a2002290330221f200241306a41086a29030022204281807c427f10a605200241106a201f2020201dad420010a60520024190026a41086a2221201029030037030020024190026a41106a2222200129030037030020024190026a41186a22232014290300370300200220022903f00222153703b0022002201537039002201d201220022903207ca722246c221d41ffff036e212520022903102113200241106a41086a290300212641301021221e450d03201e20132025417f201d4180807c491b201d20254181807c6c6a41ffff014b6aad42ffff03837c2215370320201e200229039002370300201e41286a20262015201354ad7c2213370300201e41186a2023290300370300201e41106a2022290300370300201e41086a20212903003703002002428180808010370284022002201e3602800202400240201c4122470d004101211b0c010b200041226a21252011201b6a221c415e6a21214101211b03402025210002400340200041206a2f0100211d2014200041186a2900003703002001200041106a2900003703002010200041086a290000370300200220002900003703f002201d0d01201c200041226a2200470d000c030b0b2002201f2020201dad420010a605201620102903002226370300200241b0026a41106a20012903002227370300200241b0026a41186a20142903002228370300200220022903f00222293703b002201420283703002001202737030020102026370300200220293703f002201520022903002227201d20246c221d41ffff036e2225417f201d4180807c491b201d20254181807c6c6a41ffff014b6aad42ffff03837c22267c2228201554221d2013200241086a2903002026202754ad7c22277c201dad7c221520135420152013511b211d0240201b200228028402470d0020024180026a201b410110a401200228028002211e0b427f2015201d1b2113427f2028201d1b2115200041226a2125201e201b41306c6a221d20022903f00237030020102903002128200129030021292014290300212a201d2026370320201d41286a2027370300201d41186a202a370300201d41106a2029370300201d41086a20283703002002201b41016a221b3602880220212000470d000b0b0240201a450d00201a41226c450d00201110230b20022802840221000b02400240201220157d2220201256420020132012201554ad7c7d221f420052201f501b4101470d00201520127d221f20155620132015201254ad7d2220201356201520125a1b0d01201b450d01201b41306c201e6a41706a221d4200201d2903002215201f7d22122012201556201d41086a221d290300221220207d2015201f54ad7d221520125620152012511b221c1b370300201d42002015201c1b3703000c010b201b450d00201b41306c201e6a41706a221d427f201d290300221520207c22122012201554221c201d41086a221d2903002215201f7c201cad7c221220155420122015511b221c1b370300201d427f2012201c1b3703000b201420192903003703002001201829030037030020102017290300370300200220022903e0013703f002200920003602042009201b3602082009201e360200200920022903f00237020c200941146a20102903003702002009411c6a2001290300370200200941246a2014290300370200200341016a21032009412c6a210920072008470d000b200821070b20042003360200200820076b2200412c6d210102402000450d002001412c6c210003400240200741046a2802002201450d00200141226c450d00200728020010230b2007412c6a2107200041546a22000d000b0b02402005450d002005412c6c450d00200610230b20024190036a24000f0b1033000b8d0303057f017e027f02400240024020002802202201450d00034020002001417f6a36022020002802042202450d03200028020821032000280200210402400240200028020c220520022f01064f0d00200221010c010b034002400240200228020022010d002003ad2106410021010c010b200441016a210420023301044220862003ad8421060b200210232006a72103200121022006422088a7220520012f01064f0d000b0b200541016a2107200120054105746a220241fc026a2802002105200241f8026a280200210802402004450d00200120074102746a41c8056a2802002101410021072004417f6a2202450d00034020012802c80521012002417f6a22020d000b0b2000200736020c2000200336020820002001360204200041003602002008450d0202402005450d00200541306c450d00200810230b200028022022010d000b0b200028020421010b02402001450d0020012802002102200110232002450d00034020022802002101200210232001210220010d000b0b0f0b41d095c700412b41c491c700102d000b13002000411b360204200041f08ac2003602000b0f00200028020020012002106941000bfe0101017f230041106b22022400200028020021002002410036020c02400240024002402001418001490d002001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b20002002410c6a20011069200241106a240041000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a4184a5c200200241086a10312101200241206a240020010bea1003057f017e077f230041e0006b2202240020012802202103200241306a41186a4200370300200241306a41106a22044200370300200241306a41086a220542003703002002420037033041db97c700ad4280808080f00084100c220629000021072005200641086a290000370300200220073703302006102341bbacc300ad4280808080a00184100c22062900002107200241d0006a41086a2208200641086a2900003703002002200737035020061023200420022903502207370300200241106a41086a2005290300370300200241106a41106a2007370300200241106a41186a200829030037030020022002290330370310200241306a200241106a412010890220022802302205410120051b21060240024002400240024002400240024002400240024020032002290234420020051b2207422088a7490d00200742ffffff3f83500d01200610230c010b2003200620034105746a10ac0221030240200742ffffff3f83500d00200610230b20030d010b200241306a41186a22054200370300200241306a41106a22064200370300200241306a41086a220342003703002002420037033041db97c700ad4280808080f00084100c220829000021072003200841086a290000370300200220073703302008102341bcbcc300ad4280808080c00184100c22082900002107200241d0006a41086a2209200841086a290000370300200220073703502008102320042002290350370000200441086a22082009290300370000200241106a41086a220a2003290300370300200241106a41106a220b2006290300370300200241106a41186a220c200529030037030020022002290330370310200241086a200241106a412010cd01200128021c200228020c410020022802081b220d470d01200542003703002006420037030020034200370300200242003703304180cdc200ad4280808080800184100c220e29000021072003200e41086a29000037030020022007370330200e102341d7a1c200ad4280808080c00084100c220e29000021072009200e41086a29000037030020022007370350200e10232004200229035037000020082009290300370000200a2003290300370300200b2006290300370300200c200529030037030020022002290330370310200241306a200241106a10ad0220022802302204410120041b210c200128022022052002290234420020041b2207422088a74f0d03200c20054105746a220e450d032002410036023820024201370330200128020021034104102122040d020c080b20004180063b0001200041013a0000200041036a41003a00000c060b20004180063b0001200041013a0000200041036a41003a00000c050b20024104360234200220043602302004200336000020024104360238200128020421092001410c6a2802002204200241306a10610240024020022802342208200228023822036b2004490d00200228023021060c010b200320046a22062003490d032008410174220a2006200a20064b1b220a4100480d030240024020080d000240200a0d00410121060c020b200a10212206450d080c010b200228023021062008200a460d0020062008200a10252206450d070b2002200a360234200220063602300b200620036a2009200410a1051a2002200320046a360238200141106a2802002103200141186a2802002204200241306a10610240024020040d002002280234210920022802382104200d210a0c010b20032004410c6c6a210b03402003280200210a200341086a2802002204200241306a10610240024020022802342206200228023822056b2004490d0020022802302108200621090c010b200520046a22082005490d05200641017422092008200920084b1b22094100480d050240024020060d00024020090d00410121080c020b200910212208450d0a0c010b2002280230210820062009460d0020082006200910252208450d090b20022009360234200220083602300b200820056a200a200410a1051a2002200520046a22043602382003410c6a2203200b470d000b20012802202105200128021c210a0b02400240200920046b4104490d00200441046a210320022802302106200921080c010b200441046a22032004490d03200941017422062003200620034b1b22084100480d030240024020090d00024020080d00410121060c020b200810212206450d080c010b2002280230210620092008460d0020062009200810252206450d070b20022008360234200220063602300b200620046a200a360000200220033602380240200820036b41034b0d00200341046a22042003490d03200841017422092004200920044b1b22044100480d030240024020080d00024020040d00410121060c020b200410212206450d080c010b20082004460d0020062008200410252206450d070b20022004360234200220063602300b200620036a200536000020022802342104200141246a200341046aad42208620022802302205ad84200e1013210302402004450d00200510230b20034101460d010b20004180083b0001200041013a0000200041036a41003a0000200742ffffff3f83500d03200c10230c030b410c10212203450d03410410212204450d012004200d36000020044104412410252204450d032004200e2900003700042004411c6a200e41186a290000370000200441146a200e41106a2900003700002004410c6a200e41086a290000370000200041306a41013a0000200041286a428180808010370200200041246a2003360200200041206a4100360200200041186a4204370300200041106a42ac02370300200041086a427f370300200342a4808080c00437020420032004360200200041316a2002280030360000200041346a200241336a280000360000200041003a0000200742ffffff3f83500d02200c10230c020b102c000b1033000b200241e0006a24000f0b102a000b9a0a03047f017e047f23004190016b22022400200241d8006a41186a4200370300200241d8006a41106a22034200370300200241d8006a41086a220442003703002002420037035841db97c700ad4280808080f00084100c220529000021062004200541086a290000370300200220063703582005102341bcbcc300ad4280808080c00184100c22052900002106200241f8006a41086a2207200541086a2900003703002002200637037820051023200320022903782206370300200241386a41086a2004290300370300200241386a41106a2006370300200241386a41186a200729030037030020022002290358370338200241106a200241386a412010cd01200241d8006a2002280214410020022802101b2203200010ae02200241086a200228025822042002280260419ca8c70041004100108c01200228020821050240200228025c450d00200410230b4101210402400240024020054101460d004180cdc200ad4280808080800184100c22042900002106200241f8006a41086a200441086a290000370300200220063703782004102341b4a5c200ad4280808080e00184100c22042900002106200241386a41086a200441086a2900003703002002200637033820041023200220033602282002200241286aad4280808080c00084100d22042900003703880120041023200241e4006a22052002412c6a360200200241003a0068200220024188016a41086a220036025c2002200241286a360260200220024188016a360258200241186a200241d8006a10650240024002400240412010212204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020022004ad4280808080800484100d220129000037038801200110232005200441206a360200200241003a0068200220043602602002200036025c200220024188016a360258200241286a200241d8006a1065200410232002280220220741206a2205200228023022086a2201417f4c0d01200228022821092002280218210a024002402001450d00200110212204450d022001410f4d0d01200121000c050b200141017422044110200441104b1b2200102122040d040c070b200141017422004110200041104b1b220041004e0d020c050b1033000b1032000b20012000460d0020042001200010252204450d030b20042002290378370000200441086a200241f8006a41086a2903003700000240024020004170714110460d00200021030c010b200041017422034120200341204b1b22034100480d0220002003460d0020042000200310252204450d030b20042002290338370010200441186a200241386a41086a29030037000002400240200341606a2007490d00200321000c010b2007415f4b0d02200341017422002005200020054b1b22004100480d0220032000460d0020042003200010252204450d030b200441206a200a200710a1051a02400240200020056b2008490d00200021030c010b200520086a2005490d02200041017422032001200320014b1b22034100480d02024020000d00024020030d00410121040c020b200310212204450d040c010b20002003460d0020042000200310252204450d030b200420056a2009200810a1051a0240200228022c450d00200910230b0240200228021c450d00200a10230b20022004200110cd01200228020421012002280200210502402003450d00200410230b200141004720054100477121040b20024190016a240020040f0b102c000b102a000b8b06010d7f23004190016b220224002002412036021420022001360210200241186a2001ad42808080808004841010108b010240024002400240200228021822030d00200041003602000c010b200228021c21042002200241206a28020036022c20022003360228200241086a200241286a1088010240024020022802080d00200228020c2205200228022c22064105762201200120054b1b22014105742207417f4c0d030240024020010d00410121080c010b200710212208450d050b41002109200241003602402002200136023c20022008360238024002402005450d004100210a03402006210b41002101200241003a008801200a41016a210a0340200b2001460d03200241e8006a20016a200228022822072d00003a00002002200741016a3602282002200141016a22073a0088012007210120074120470d000b200241c8006a41186a220c200241e8006a41186a290300370300200241c8006a41106a220d200241e8006a41106a290300370300200241c8006a41086a220e200241e8006a41086a2903003703002002200229036837034802402009200228023c470d00200241386a20094101109a0120022802382108200228024021090b200b20076b2106200820094105746a22012002290348370000200141186a200c290300370000200141106a200d290300370000200141086a200e2903003700002002200941016a2209360240200a2005470d000b2002200b20076b36022c0b2008450d012000200229023c370204200020083602000c020b2002410036022c0240200141ff0171450d00200241003a0088010b200228023c41ffffff3f71450d00200810230b20024100360250200242013703482002410a36023c2002200241106a3602382002200241c8006a360234200241fc006a41013602002002420137026c20024180c5c6003602682002200241386a360278200241346a4184a5c200200241e8006a10311a2002350250422086200235024884100a0240200228024c450d00200228024810230b200041003602000b2004450d00200310230b20024190016a24000f0b1032000b1033000bdc0603027f017e077f230041e0006b220324004180cdc200ad4280808080800184100c22042900002105200341086a200441086a290000370300200320053703002004102341d4bec200ad4280808080a00284100c22042900002105200341106a41086a200441086a2900003703002003200537031020041023200320013602302003200341306aad4280808080c00084100d220429000037034020041023200341d4006a2204200341306a41046a360200200341003a00582003200341c0006a41086a220136024c2003200341306a3602502003200341c0006a360248200341206a200341c8006a10652003200236023c20032003413c6aad4280808080c00084100d22022900003703402002102320042003413c6a41046a360200200341003a00582003200136024c20032003413c6a3602502003200341c0006a360248200341306a200341c8006a10650240024002400240024002402003280228220641206a2207200328023822086a2202417f4c0d00200328023021092003280220210a024002402002450d00200210212204450d032002410f4d0d012002210b0c050b200241017422044110200441104b1b220b102122040d040c060b200241017422014110200141104b1b220b41004e0d020c040b1032000b1033000b2002200b460d0020042002200b10252204450d020b20042003290300370000200441086a200341086a29030037000002400240200b4170714110460d00200b21010c010b200b41017422014120200141204b1b22014100480d01200b2001460d002004200b200110252204450d020b20042003290310370010200441186a200341106a41086a29030037000002400240200141606a2006490d002001210b0c010b200641206a220b2006490d012001410174220c200b200c200b4b1b220b4100480d012001200b460d0020042001200b10252204450d020b200441206a200a200610a1051a02400240200b20076b2008490d00200b21010c010b200720086a2007490d01200b41017422012002200120024b1b22014100480d01200b2001460d002004200b200110252204450d020b200420076a2009200810a1051a20002002360208200020013602042000200436020002402003280234450d00200910230b02402003280224450d00200a10230b200341e0006a24000f0b102c000b102a000bdd0201057f230041d0006b22022400024002400240410410212203450d00200341f0c2c98b06360000200128020021044108210120034104410810252205450d0120052004360004200241003a004820052106410021030340200241003a0008200241086a20062001410047220410a1051a024020010d00200241003a00080b20012004490d03200241286a20036a20022d00083a00002002200341016a22033a0048200120046b2101200620046a210620034120470d000b200241086a41186a2201200241286a41186a290300370300200241086a41106a2203200241286a41106a290300370300200241086a41086a2204200241286a41086a2903003703002002200229032837030820051023200041186a2001290300370000200041106a2003290300370000200041086a200429030037000020002002290308370000200241d0006a24000f0b1033000b102a000b2004200141a4b5c0001044000bfe21030b7f047e097f230041c0066b2202240002400240024020012802082203200128020c2204460d002001200341206a220536020820012802102106200241f8026a41186a200341186a290000370300200241f8026a41106a200341106a290000370300200241f8026a41086a200341086a290000370300200220032900003703f802200128021421074100210802400240024002402001411c6a280200220941014b0d0020090e020201020b2009210a0340200a410176220b20086a220c20082007200c4105746a200241f8026a412010a3054101481b2108200a200b6b220a41014b0d000b0b200720084105746a200241f8026a412010a3050d002006210c0c010b2001200641016a220c3602104108210820052004460d020240200941014d0d0003402001200541206a2203360208200241f8026a41186a200541186a290000370300200241f8026a41106a200541106a290000370300200241f8026a41086a200541086a290000370300200220052900003703f802410021082009210a0340200a410176220520086a220b20082007200b4105746a200241f8026a412010a3054101481b2108200a20056b220a41014b0d000b200720084105746a200241f8026a412010a305450d022001200c41016a220c3602102003210520032004460d030c000b0b0240024020090e020100010b03402001200541206a2208360208200241f8026a41186a200541186a290000370300200241f8026a41106a200541106a290000370300200241f8026a41086a200541086a290000370300200220052900003703f80202402007200241f8026a412010a3050d00410021080c030b2001200c41016a220c3602102008210520042008460d030c000b0b2001200436020820012006200420036b41406a4105766a41026a3602100c020b024002400240024002400240024002400240200920084d0d00200241186a200720084105746a220841186a290000220d370300200241106a200841106a290000220e370300200241086a200841086a290000220f3703002002200829000022103703002001200c41016a360210200141206a2802002108200141246a280200210a200241206a41186a200d370300200241206a41106a200e370300200241206a41086a200f370300200220103703202002200a36024c200220083602482002200c360244200241f8026a41186a4200370300200241f8026a41106a22054200370300200241f8026a41086a22084200370300200242003703f80241db97c700ad4280808080f00084100c220a290000210d2008200a41086a2900003703002002200d3703f802200a102341bbacc300ad4280808080a00184100c220a290000210d200241b8026a41086a220b200a41086a2900003703002002200d3703b802200a1023200520022903b802220d370300200241d0006a41086a2008290300370300200241d0006a41106a200d370300200241d0006a41186a200b290300370300200220022903f802370350200241f8026a200241d0006a412010890220022802f8022208410120081b210a02400240200c20022902fc02420020081b220d422088a7490d00200d42ffffff3f83500d01200a10232002280244210c0c010b200c200a200c4105746a10ac0221050240200d42ffffff3f83500d00200a10230b410221082002280244210c20050d0c0b200228024c210620022802482111411b10212208450d01200841176a41002800d7a942360000200841106a41002900d0a942370000200841086a41002900c8a942370000200841002900c0a94237000041041021220a450d01200a200c3600002008411b413610252209450d082009200a28000036001b200a1023200241b8026a41002009ad4280808080f00384220d1014108b01024002400240024020022802b8022208450d00200241c0026a280200220a4104490d00200a417c714104460d0041000d0020082800002011470d002008280004220a41036a20064b0d010b410410212208450d0b2008201136000020084104410810252208450d0b20082006360004200241d0006a41086a200241b8026a41086a280200360200200220022903b802370350200241f8026a200241d0006a10860120022802fc02210a4100200d20023502800342208620022802f802220bad842008ad4280808080800184101521050240200a450d00200b10230b02402002280250220a450d002002280254450d00200a10230b200810234104210820054101460d022006210a0c010b024020022802bc02450d00200810230b410121080b20091023200a210c0c0c0b200241f8026a10870120022802f8022212450d032002418c036a280200211320024188036a280200211420024184036a280200211520024180036a280200211620022802fc0221172002410036028003200242013703f802410410212208450d08200241043602fc02200220083602f8022008200636000020024104360280032016200241f8026a10610240024020022802fc02220520022802800322086b2016490d0020022802f802210a0c010b200820166a220a2008490d082005410174220b200a200b200a4b1b220b4100480d080240024020050d000240200b0d004101210a0c020b200b1021220a0d010c0b0b20022802f802210a2005200b460d00200a2005200b1025220a450d0a0b2002200b3602fc022002200a3602f8020b200a20086a2012201610a1051a2002200820166a360280032013200241f8026a10612013450d0220152013410c6c6a21032015210a0340200a2802002104200a41086a2802002208200241f8026a10610240024020022802fc02220b20022802800322056b2008490d0020022802f8022107200b21010c010b200520086a22072005490d09200b41017422012007200120074b1b22014100480d0902400240200b0d00024020010d00410121070c020b200110212207450d0c0c010b20022802f8022107200b2001460d002007200b200110252207450d0b0b200220013602fc02200220073602f8020b200720056a2004200810a1051a2002200520086a220836028003200a410c6a220a2003470d000c050b0b2008200941b0a9c2001030000b1033000b20022802fc02210120022802800321080c010b41012108410521060c010b02400240200120086b4104490d0020022802f802210a200121050c010b200841046a220a2008490d0320014101742205200a2005200a4b1b22054100480d030240024020010d00024020050d004101210a0c020b20051021220a450d060c010b20022802f802210a20012005460d00200a200120051025220a450d050b200220053602fc022002200a3602f8020b200a20086a20113600002002200841046a220b360280034103210702402005200b6b41034b0d00200b41046a2201200b490d03200541017422042001200420014b1b22014100480d030240024020050d00024020010d004101210a0c020b20011021220a450d060c010b20052001460d00200a200520011025220a450d050b200220013602fc022002200a3602f8020b200a200b6a200c36000020022802fc02210a200241f8026a41e9dabdf306200241206a20022802f802220b200841086a108f0141012108024020022d00f8024101470d00200241f6026a20022d00fb023a0000200241b8026a41086a2002418c036a290200370300200241c8026a20024194036a290200370300200241d0026a2002419c036a290200370300200241d8026a200241a4036a290200370300200241e0026a200241ac036a290200370300200241e5026a200241b1036a290000370000200220022f00f9023b01f402200220024184036a2902003703b802200241f8026a41086a28020021054100210820022802fc0221070b200241b4026a41026a2201200241f4026a41026a2d00003a0000200241f8016a41086a200241b8026a41086a290300370300200241f8016a41106a2204200241b8026a41106a290300370300200241f8016a41186a2203200241b8026a41186a290300370300200241f8016a41206a2218200241b8026a41206a290300370300200241f8016a41286a2219200241b8026a41286a290300370300200241f8016a41306a200241b8026a41306a290300370300200220022f01f4023b01b402200220022903b8023703f801024020080d00200241f4016a41026a20012d00003a0000200241f8026a41086a200241f8016a41086a290300370300200241f8026a41106a2004290300370300200241f8026a41186a2003290300370300200241f8026a41206a2018290300370300200241f8026a41286a2019290300370300200241f8026a412d6a200241f8016a412d6a290000370000200220022f01b4023b01f401200220022903f8013703f8020240200a450d00200b10230b200220022f01f4013b01b8022002200241f6016a2d00003a00ba02410021080c020b0240200a450d00200b10230b02402017450d00201210230b02402013450d002013410c6c210a2015210803400240200841046a280200450d00200828020010230b2008410c6a2108200a41746a220a0d000b0b4101210802402014450d002014410c6c450d00201510230b20072106200521120b0b200241b8016a41086a220a200241f8026a41086a290300370300200241b8016a41106a220b200241f8026a41106a290300370300200241b8016a41186a2201200241f8026a41186a290300370300200241b8016a41206a2204200241f8026a41206a290300370300200241b8016a41286a2203200241f8026a41286a290300370300200241b8016a412d6a2218200241f8026a412d6a290000370000200220022d00ba023a00f201200220022f01b8023b01f001200220022903f8023703b80102400240024020080d00200241d0006a41186a2013360200200241d0006a41146a2014360200200241d0006a41106a2015360200200241d0006a410c6a2016360200200241d0006a41086a2017360200200241f6006a20022d00f2013a0000200241fb006a2005360000200241f7006a2007360000200241ff006a20022903b80137000020024187016a200a2903003700002002418f016a200b29030037000020024197016a20012903003700002002419f016a2004290300370000200241a7016a2003290300370000200241ac016a20182900003700002002200c3602702002201136026c2002201236025420022006360250200220022f01f0013b017402404100280298ab474103490d00200241b8026a411c6a410e360200200241b8026a41146a410f360200200241b8026a410c6a410f3602002002410f3602bc022002200241d0006a3602d0022002200241c8006a3602c8022002200241cc006a3602c0022002200241c4006a3602b80241002802888040210841002802848040210a410028029cab472105200241b8036a41de03360200200241b0036a42df80808010370300200241ac036a41fca5c200360200200241a4036a4210370200200241a0036a41eca5c20036020020024198036a420437030020024188036a4204370300200241f8026a41086a4108360200200241f8026a411c6a200241b8026a360200200241dca9c20036028403200241e4a5c2003602fc02200241033602f802200a41a0a1c000200541024622051b200241f8026a200841b8a1c00020051b2802101102000b2002410b36029004200242023703e00320024194046a200241d0006a41e40010a1051a2002200241f8026a3602f801200241b8026a200241f8016a10b30220022802b80220022802bc0220022802c002108901210a20024190046a10b4024107210841062106200a0d010c020b4107210820064107460d010b410410212208450d022008201136000020084104410810252208450d02200841003600044100200d2008ad4280808080800184101620081023200621080b200910232012210c0c040b102c000b102a000b410821080b0b2000200c36020420002008360200200241c0066a24000bc60401067f23004190016b22022400024002402000410c6a2802002203417f4c0d0020002802042104200028020021050240024020030d0041012106410021070c010b20032107200310212206450d020b20062004200310a1052104200241f8006a200041106a10b702200241106a410c6a2003360200200241106a41086a22032007360200200241206a2002290378370300200241286a2206200241f8006a41086a280200360200200241106a412c6a2000412c6a290200370200200241106a41346a200041346a290200370200200241106a413c6a2000413c6a290200370200200241106a41c4006a200041c4006a290200370200200241106a41cc006a200041cc006a290200370200200241106a41d4006a200041d4006a290200370200200241106a41dc006a200041dc006a29020037020020022004360214200220053602102002200029021c37022c200220002902243702342002410c6a4110360200200241aca5c200360200200241043602042001411c6a28020021002002200241106a360208200128021821012002418c016a41023602002002420237027c200241b4aac200360278200220023602880120012000200241f8006a1031210102402003280200450d00200228021410230b024020062802002203450d00200228022021002003410c6c210303400240200041046a280200450d00200028020010230b2000410c6a2100200341746a22030d000b0b0240200241246a2802002200450d002000410c6c450d00200228022010230b20024190016a240020010f0b1032000b1033000bb30201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad2001103e21000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141a889c0004102200220006a4180016a410020006b104121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141a889c0004102200220006a4180016a410020006b104121000b20024180016a240020000f0b2004418001419889c0001044000b2004418001419889c0001044000bb31203077f027e057f230041c0006b22022400024002400240024041ca0310212203450d00200241ca0336020420022003360200200341003b0000200241023602082002280204210402400240200128020022032903684202520d00024020044102470d0020022802004102410410252201450d0620024104360204200220013602000b200228020041043a00022002200228020841016a3602080c010b024020044102470d0020022802004102410410252201450d0520024104360204200220013602000b20022802004184013a000220022002280208220141016a2205360208024002402002280204220620056b4120490d00200141216a210120022802002107200621040c010b200541206a22012005490d04200641017422042001200420014b1b22044100480d040240024020060d00024020040d00410121070c020b2004102122070d010c070b2002280200210720062004460d0020072006200410252207450d060b20022004360204200220073602000b200720056a22052003290000370000200541186a200341186a290000370000200541106a200341106a290000370000200541086a200341086a29000037000020022001360208024020032d0020220541024b0d000240024002400240024020050e03000102000b410021060c020b410121060c010b41022106200241023a001041c10021050c010b200220063a001041c00021050b024020042001470d00200141016a22042001490d05200141017422082004200820044b1b22044100480d050240024020010d0041002101024020040d00410121070c020b200410212207450d080c010b20012004460d0020072001200410252207450d070b20022004360204200220073602000b200720016a20063a00002002200141016a2201360208024002402002280204220620016b2005490d0020022802002107200621040c010b200120056a22042001490d05200641017422072004200720044b1b22044100480d050240024020060d00024020040d00410121070c020b200410212207450d080c010b2002280200210720062004460d0020072006200410252207450d070b20022004360204200220073602000b200720016a200341206a41016a200510a1051a2002200120056a22013602080b0240024020032903684201520d00200329037820032903702209420c88220a4201200a4201561b80210a0240200420016b41014b0d00200141026a22052001490d06200441017422062005200620054b1b22054100480d060240024020040d00024020050d00410121070c020b200510212207450d090c010b20042005460d0020072004200510252207450d080b20022005360204200220073602000b200720016a200aa741047420097aa7417f6a22044101200441014b1b2204410f2004410f491b723b00002002200141026a3602080c010b200241003a00100240024020042001460d00200121040c010b200441016a22012004490d05200441017422052001200520014b1b22014100480d050240024020040d0041002104024020010d00410121070c020b200110212207450d080c010b20042001460d0020072004200110252207450d070b20022001360204200220073602000b200720046a41003a00002002200441016a3602080b20034190016a200210ed01200220034180016a360210200241106a200210db010b20034198016a200210dd0220022802082103410410212201450d0020024204370214200220013602102003417e6a200241106a10612002280208220341014d0d012002280218210120022802142108200220022802102206360224200241286a200620016a2204360200200241023602102002411c6a2002280200220741026a2205360200410021012002410036020820022003417e6a22033602142002200536021820022002360220200241246a210b0240024002402003450d0020062103034020032004460d032002200341016a360224200720016a20032d00003a00002002200228020841016a36020820014101460d02200141016a210120022802242103200228022821040c000b0b2002200b1082040c010b024020022802282205200228022422036b2201450d00024002402002280220220741046a280200220c2002280214220d2002280210220e6a22046b2001490d00200728020021040c010b200420016a220f2004490d05200c4101742204200f2004200f4b1b220f4100480d0502400240200c0d000240200f0d00410121040c020b200f10212204450d080c010b20072802002104200c200f460d002004200c200f10252204450d070b20072004360200200741046a200f3602000b2004200e20016a22016a2004200e6a200d10a2051a20022001360210200120072802082204460d00200420036a417f732005200e6a6a2101200728020020046a2104034020032005460d022002200341016a360224200420032d00003a00002007200728020841016a3602082001450d01200441016a21042001417f6a210120022802242103200228022821050c000b0b2002410036023820024201370330200241306a200b1082042002280234210b2002280230210e024020022802382203450d00024002402002280220220741046a28020022052002280214220c200228021022046a22016b2003490d00200728020021010c010b200120036a220d2001490d0520054101742201200d2001200d4b1b220d4100480d050240024020050d000240200d0d00410121010c020b200d10212201450d080c010b200728020021012005200d460d0020012005200d10252201450d070b20072001360200200741046a200d3602000b2001200420036a22056a200120046a200c10a2051a20022005360210200520072802082201460d00200120046b2105200728020020016a2101200e210403402003450d01200120042d00003a00002007200728020841016a360208200441016a2104200141016a210120052003417f6a2203470d000b0b200b450d00200e10230b02402002280218200228021c2203460d00200220033602180b024020022802142203450d000240200228021022072002280220220541086a22042802002201460d002005280200220520016a200520076a200310a2051a0b2004200320016a3602000b02402008450d00200610230b20002002290300370200200041086a200241086a280200360200200241c0006a24000f0b1033000b41022003103c000b102c000b102a000b9b1201037f024002402000280200220141144b0d000240024002400240024002400240024002400240024020010e15000c0c0c0c01020c030c04050c060c0708090a0c0c000b200041086a280200417e6a220141074b0d0b02400240024002400240024020010e080011010211030405000b200041106a280200450d102000410c6a28020010230f0b200041106a280200450d0f2000410c6a28020010230f0b200041106a280200450d0e2000410c6a28020010230f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010230b0240200141106a280200450d002001410c6a28020010230b200141186a2101200241686a22020d000b0b200041106a2802002201450d0d200141186c450d0d200028020c10230f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d0c2001410c6c450d0c200028020c10230f0b200041106a280200450d0b2000410c6a28020010230f0b02402000410c6a2802002201450d00200141f0006c2102200028020441046a2101034020011096030240200141046a2802002203450d00200341246c450d00200128020010230b200141f0006a2101200241907f6a22020d000b0b200041086a2802002201450d0a200141f0006c450d0a200028020410230f0b0240200041086a2d0000220141174b0d000240024002400240024020010e180f0f0f0f0f0f000f0f0f0f0f0f010f0f02030f0f0f0f0f040f0b200041106a28020041ffffff3f71450d0e2000410c6a28020010230f0b200041106a28020041ffffff3f71450d0d2000410c6a28020010230f0b200041146a28020041ffffffff0371450d0c200041106a28020010230f0b200041146a2802002201450d0b200141246c450d0b200041106a28020010230f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010230b200041186a1083020f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010230b200041186a1083020f0b20002802042201450d08200041086a280200450d08200110230f0b200041086a280200450d07200028020410230f0b02402000410c6a280200450d00200041086a28020010230b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b200041186a2802002201450d062001410c6c450d06200028021410230f0b02402000280204220141014b0d00024020010e020700070b0240200041106a2802002202450d00200041086a280200210120024188026c21020340200110a20320014188026a2101200241f87d6a22020d000b0b2000410c6a2802002201450d0620014188026c450d06200028020810230f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d052001410c6c450d05200028020c10230f0b20002d0004417f6a220141034b0d040240024020010e0400060601000b0240200041106a280200450d002000410c6a28020010230b2000411c6a280200450d05200041186a28020010230f0b02402000410c6a280200450d00200041086a28020010230b200041186a280200450d04200041146a28020010230f0b024020002d0004220141044b0d00024002400240024020010e050800010203080b0240200041106a2802002202450d00200041086a2802002101200241b0026c210203402001109e03200141b0026a2101200241d07d6a22020d000b0b2000410c6a2802002201450d07200141b0026c450d07200028020810230f0b200041086a220128020010b402200128020010230f0b02402000410c6a28020041ffffff3f71450d00200041086a28020010230b200041206a220128020010b402200128020010230f0b2000412c6a28020041ffffff3f71450d04200041286a28020010230f0b2000412c6a28020041ffffff3f71450d03200041286a28020010230f0b200041086a2d0000417e6a220141014b0d020240024020010e020001000b0240200041146a2802002202450d002000410c6a2802002201200241c8006c6a21020340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012002470d000b0b0240200041106a2802002201450d00200141c8006c450d00200028020c10230b0240200041186a2d00004101470d00200041206a280200450d002000411c6a28020010230b02402000413c6a2d00004101470d00200041c4006a280200450d00200041c0006a28020010230b0240200041e0006a2d00004101470d00200041e8006a280200450d00200041e4006a28020010230b024020004184016a2d00004101470d002000418c016a280200450d0020004188016a28020010230b0240200041a8016a2d00004101470d00200041b0016a280200450d00200041ac016a28020010230b0240200041cc016a2d00004101470d00200041d4016a280200450d00200041d0016a28020010230b200041f0016a2d00004101470d03200041f8016a280200450d03200041f4016a28020010230f0b0240200041146a2802002201450d00200141c4006c21022000410c6a28020041286a210103400240200141786a2d00004101470d002001280200450d002001417c6a28020010230b200141c4006a2101200241bc7f6a22020d000b0b200041106a2802002201450d02200141c4006c450d02200028020c10230f0b20002d0004417f6a220141024b0d010240024020010e03000301000b200041286a220128020010b402200128020010230f0b2000410c6a28020041ffffff3f71450d01200041086a28020010230c010b024020002d0004220141024b0d00024020010e03020002020b200041086a220128020010b402200128020010230f0b200041286a220128020010b402200128020010230f0b0bef0401017f230041306b220224000240024002400240024002400240024020002802000e0701020304050600010b2001411c6a2802002100200128021821012002412c6a41003602002002419ca8c7003602282002420137021c20024184a7c20036021820012000200241186a103121010c060b2002200041046a36020c2002410d3602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420137021c2002418ca7c2003602182002200241106a36022820012000200241186a103121010c050b2002200041046a36020c2002410d3602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420237021c20024194a7c2003602182002200241106a36022820012000200241186a103121010c040b2002200028020436020c200241013602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420237021c200241a4a7c2003602182002200241106a36022820012000200241186a103121010c030b2001411c6a2802002100200128021821012002412c6a41003602002002419ca8c7003602282002420137021c200241b4a7c20036021820012000200241186a103121010c020b2001411c6a2802002100200128021821012002412c6a41003602002002419ca8c7003602282002420137021c200241bca7c20036021820012000200241186a103121010c010b2001411c6a2802002100200128021821012002412c6a41003602002002419ca8c7003602282002420137021c200241c4a7c20036021820012000200241186a103121010b200241306a240020010bba0201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210420034120710d012004ad2001103e21000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141a889c0004102200220006a4180016a410020006b104121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d02200141a889c0004102200220006a4180016a410020006b104121000b20024180016a240020000f0b2004418001419889c0001044000b2004418001419889c0001044000baf0203027f017e057f230041106b220224000240024020012802082203ad420c7e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410421060c010b200510212206450d020b200241003602082002200636020020022005410c6e3602042002410020031095012002280208210602402003450d0020012003410c6c6a210720022802002006410c6c6a21050340200141086a2802002203417f4c0d02200128020021080240024020030d00410121090c010b200310212209450d040b20092008200310a1052108200541086a2003360200200541046a2003360200200520083602002005410c6a2105200641016a21062001410c6a22012007470d000b0b20002002290300370200200041086a2006360200200241106a24000f0b1032000b1033000b980201027f230041206b2202240020022001280218419ca8c70041002001411c6a28020028020c1100003a00102002200136020841012101200241013a00112002410036020c200220003602182002200041246a36021c200241086a200241186a41c4aac20010592002411c6a41d4aac20010591a20022d0010210002400240200228020c22030d00200021010c010b0240200041ff01710d00024020034101470d0020022d001141ff0171450d00200228020822002d00004104710d0041012101200028021841979ec00041012000411c6a28020028020c1100000d010b2002280208220128021841989ec00041012001411c6a28020028020c11000021010b200220013a00100b200241206a2400200141ff01714100470b1c00200128021841e4aac200410f2001411c6a28020028020c1100000b130020004103360204200041f4aac2003602000b340020004196cdc20036020420004100360200200041146a4101360200200041106a41d8b5c200360200200041086a42073702000b130020004101360204200041f0b6c2003602000b3901017f02404110102122020d001033000b200242003700082002428080e983b1de16370000200042908080808002370204200020023602000bbd280e047f017e017f017e047f017e017f017e017f017e0e7f017e037f017e230041a0026b22012400200141286a200010bf0220014198016a41186a420037030020014198016a41106a2202420037030020014198016a41086a22034200370300200142003703980141e4dec400ad4280808080e00084100c220429000021052003200441086a290000370300200120053703980120041023419483c500ad4280808080a00284100c22042900002105200141c8006a41086a2206200441086a2900003703002001200537034820041023200220012903482205370300200141e8006a41086a2003290300370300200141e8006a41106a2005370300200141e8006a41186a200629030037030020012001290398013703682001412036023c2001200141e8006a36023820014190026a200141e8006aad220742808080808004841010108b0102400240024002400240024002400240024020012802900222040d00410221030c010b2001280294022108200120014190026a41086a28020036028c012001200436028801200141206a20014188016a108801200128022421090240024020012802200d00200141186a20014188016a10880120012802180d00200128028c01220a200128021c2203490d002003417f4c0d030240024020030d00410121060c010b200310272206450d062006200128028801220b200310a1051a2001200a20036b36028c012001200b20036a360288010b2006450d002003ad22054220862005842105410121030c010b20014100360250200142013703482001410a360284022001200141386a360280022001200141c8006a360244200141ac016a41013602002001420137029c0120014180c5c60036029801200120014180026a3602a801200141c4006a4184a5c20020014198016a10311a2001350250422086200135024884100a0240200128024c450d00200128024810230b410221030b2008450d00200410230b0240024020034102460d002005a721040240024020090d00410121030c010b4100210902402005422088a7200420034101461b4107470d00410121092006419cc9c200460d00419cc9c2002006410710a3054521090b200941017321030b02402004450d00200610230b2003450d010b200141a4016a41002902e8c8423702002001410136029801200141002902e0c84237029c01200141e8006a41186a4200370300200141e8006a41106a22064200370300200141e8006a41086a220342003703002001420037036841e4dec400ad4280808080e00084100c220429000021052003200441086a2900003703002001200537036820041023419483c500ad4280808080a00284100c2204290000210520014190026a41086a2209200441086a29000037030020012005370390022004102320062001290390022205370300200141c8006a41086a2003290300370300200141c8006a41106a2005370300200141c8006a41186a20092903003703002001200129036837034820014100360298022001420137039002410120014190026a1061200141e8006a20014198016a4104721090012001280268210a02400240200128029402220820012802980222046b20012802702206490d002001280290022103200821090c010b200420066a22032004490d07200841017422092003200920034b1b22094100480d070240024020080d00024020090d00410121030c020b2009102122030d010c0a0b200128029002210320082009460d0020032008200910252203450d090b200120093602940220012003360290020b200320046a200a200610a1051a2001200420066a2204360298020240200128026c450d00200a10230b200141c8006aad42808080808004842004ad4220862003ad84100e02402009450d00200310230b20014198016a41186a2208420037030020014198016a41106a2209420037030020014198016a41086a2206420037030020014200370398014189e3c400ad42808080808001842205100c2204290000210c200141c8006a41086a2203200441086a2900003703002001200c370348200410232006200329030037030020012001290348370398014191e3c400ad4280808080f00084100c2204290000210c2003200441086a2900003703002001200c3703482004102320092001290348220c370300200141e8006a41086a22042006290300370300200141e8006a41106a220a200c370300200141e8006a41186a220b2003290300370300200120012903980137036820074280808080800484220c101220084200370300200942003703002006420037030020014200370398012005100c220d290000210e2003200d41086a2900003703002001200e370348200d10232006200329030037030020012001290348370398014198e3c400ad4280808080e00284100c220d290000210e2003200d41086a2900003703002001200e370348200d102320092001290348220e37030020042006290300370300200a200e370300200b20032903003703002001200129039801370368200c101220084200370300200942003703002006420037030020014200370398012005100c220d29000021052003200d41086a29000037030020012005370348200d102320062003290300370300200120012903483703980141ac94c500ad4280808080a00284100c220d29000021052003200d41086a29000037030020012005370348200d102320092001290348220537030020042006290300370300200a2005370300200b20032903003703002001200129039801370368200c1012200141c8006a41186a220a4200370300200141c8006a41106a220f42003703002003420037030020014200370348418fcdc200ad4280808080f000842205100c220b290000210c2004200b41086a2900003703002001200c370368200b1023200320042903003703002001200129036837034841a48fc600ad4280808080e00184100c220b290000210c2004200b41086a2900003703002001200c370368200b1023200f2001290368220c370300200620032903003703002009200c37030020082004290300370300200120012903483703980141011021220b450d07200b41023a000020014198016aad42808080808004842210200bad42808080801084100e200b1023200a4200370300200f420037030020034200370300200142003703482005100c220b290000210c2004200b41086a2900003703002001200c370368200b10232003200429030037030020012001290368370348418cdbc100ad4280808080a00184100c220b290000210c2004200b41086a2900003703002001200c370368200b1023200f2001290368370000200f41086a220d2004290300370000200620032903003703002009200f2903003703002008200a2903003703002001200129034837039801200141106a20014198016a412010cd012001280214211120012802102112200a4200370300200f420037030020034200370300200142003703482005100c220b290000210c2004200b41086a2900003703002001200c370368200b102320032004290300370300200120012903683703484190d8c100ad4280808080c00184100c220b290000210c2004200b41086a2900003703002001200c370368200b1023200f2001290368370000200d2004290300370000200620032903003703002009200f2903003703002008200a2903003703002001200129034837039801200141086a20014198016a412010cd01200128020c2109200128020821082005100c2203290000210520014190026a41086a200341086a290000370300200120053703900220031023411010212203450d072003200129039002370000200341086a20014190026a41086a220429030037000041dcc4c000ad4280808080e00084100c220629000021052004200641086a29000037030020012005370390022006102320034110412010252203450d072003200129039002370010200341186a22062004290300370000412010212204450d032011410020121b211320042003290000370000200441186a2006290000370000200441106a200341106a290000370000200441086a200341086a290000370000200141386a41026a220620014198016a41026a2d00003a0000200120012f0098013b0138200141c8006a41106a42a08080808004370300200141013a006020012004360254200142a0808080800437024c20012003360248200141e3006a20062d00003a0000200120012f01383b006120014198016a200141c8006a10c0020240200141d4016a28020022034102460d0041002013200941d40020081b6b2204200420134b1b2114200141d0016a2112200141c4016a211520014198016a41206a2116200141dc016a2117200141c8016a2118200141c0016a2119034020014188016a41086a221a201841086a280200360200200141e8006a41086a221b201741086a290200370300200141e8006a41106a221c201741106a290200370300200141e8006a41186a221d201741186a2902003703002001201829030037038801200120172902003703682019290300210520014198016a41186a221e290300210c20012903b801210e20012903a801211f20012802a0012120200128029c012121200128029801212220012802d8012106200141003602a001200142043703980141002104024002402006410020031b220320144922060d004100200320146b2204200420034b1b220941016a220420094f0d004104210d41012106410021084100210a201421040340200420034f210b200420042003496a210902402006417f6a200a470d0020014198016a200a417f41004100417f4100200320096b220d200d20034b1b220d41016a22112011200d491b200b1b20032009491b220d41016a22112011200d491b1079200128029801210d0b200d20086a2004360200200120063602a001200920034b200b720d02200841046a2108200641016a2106200128029c01210a200921040c000b0b20014198016a41002004107920012802a0012109024020060d0020012802980120094102746a210402400240200320144d0d0020142106034020042006360200200441046a21042003200641016a2206470d000b200320146b20096a21090c010b20032014470d010b20042003360200200941016a21090b200120093602a0010b20014180026a41086a20014198016a41086a28020022033602002001200129039801222337038002201e20053703002016200129038801370300201641086a201a28020036020020152023370200201541086a200336020020122001290368370200201241086a201b290300370200201241106a201c290300370200201241186a201d2903003702002001200e3703a8012001200c3703a0012001201f37039801202041206a2204417f4c0d032004450d04200410272203450d052004410f4d0d06418fcdc200ad4280808080f00084100c2209290000210520014190026a41086a2206200941086a290000370300200120053703900220091023200341086a200629030037000020032001290390023700002004411f4d0d0741dcc4c000ad4280808080e00084100c220929000021052006200941086a290000370300200120053703900220091023200341186a20062903003700002003200129039002370010200341206a2022202010a1051a2001200436029402200120033602900220014198016a20014190026a10850220031023024020012802bc012203450d00200341186c450d0020012802b80110230b024020012802c80141ffffffff0371450d0020012802c40110230b02402021450d00202210230b20014198016a200141c8006a10c00220012802d40122034102470d000b0b0240200128024c450d00200128024810230b02402001280258450d00200128025410230b200141c8006a41186a22094200370300200141c8006a41106a22084200370300200141c8006a41086a2204420037030020014200370348418fcdc200ad4280808080f00084100c22062900002105200141e8006a41086a2203200641086a2900003703002001200537036820061023200420032903003703002001200129036837034841f4e5c100ad4280808080a00184100c220629000021052003200641086a2900003703002001200537036820061023200f2001290368370000200f41086a200329030037000020014198016a41086a200429030037030020014198016a41106a200829030037030020014198016a41186a2009290300370300200120012903483703980120012013360268201020074280808080c00084100e4190ce0010c1020b20002802002203200041106a200041d0006a200141286a410110c202200310c30210c102200142003703900220014198016a41186a2206420037030020014198016a41106a2209420037030020014198016a41086a22034200370300200142003703980141e4dec400ad4280808080e00084100c220429000021052003200441086a29000037030020012005370398012004102341d483c500ad4280808080e00184100c22042900002105200141c8006a41086a2208200441086a290000370300200120053703482004102320022001290348370000200241086a2008290300370000200141e8006a41086a2003290300370300200141e8006a41106a2009290300370300200141e8006a41186a200629030037030020012001290398013703682001412036029c012001200141e8006a3602980120014190026a20014198016a10c40220012802282109024020012802302203450d00200341246c21042009210303400240024020032d0000220641044b0d0002400240024020060e050400010204040b2003410c6a280200450d03200341086a28020010230c030b2003410c6a280200450d02200341086a28020010230c020b2003410c6a280200450d01200341086a28020010230c010b200341086a280200450d00200341046a28020010230b200341246a21032004415c6a22040d000b0b0240200128022c2203450d00200341246c450d00200910230b200141a0026a24000f0b1032000b4110410041d492c7001043000b1033000b4110200441d492c7001043000b4120200441d093c7001043000b102c000b102a000bab03010c7f230041306b220224004100210320024100360208200242043703000240024002402001410c6a28020041246c2204450d0020012802042101410421050340024020012d00004101470d00200141106a2802002206417f4c0d03200141036a2d00002107200141016a2f00002108200141086a2802002109200141046a2d0000210a0240024020060d004101210b4100210c0c010b2006210c20061021220b450d050b20082007411074722108200b2009200610a1052109200241206a41086a220b200241106a41086a29020037030020022002290210370320200d41807e71200a72210d024020032002280204470d0020022003410110a20120022802002105200228020821030b2005200341246c6a220720063602102007200c36020c200720093602082007200d360204200720083b0001200741013a0000200741036a20084110763a0000200720022903203702142007411c6a200b2903003702002002200341016a22033602080b200141246a21012004415c6a22040d000b0b20002002290300370200200041086a200241086a280200360200200241306a24000f0b1032000b1033000bee0b09057f017e027f017e047f047e077f047e037f230041e0016b22022400200241b8016a200141146a350200422086200135020c841019108b010240024020022802b8012203450d00200141086a2104200141106a2105024002400340024002402004280200220620022902bc012207422088a722084b0d00200128020022092003460d0120092003200610a305450d010b2007a7450d04200310230c040b02402008417f4c0d000240024020080d0041012106410021090c010b20082109200810212206450d030b20062003200810a105210602402005280200450d00200128020c10230b200120083602142001200636020c200520093602002002200836025420022003360250200241d8006a2007428080808070832003ad84220a1010108b01024020022802582209450d00200228025c210b20022002280260220c36028c01200220093602880141002108200241003a00d8010240024002400240024002400340200c2008460d01200241b8016a20086a200920086a22062d00003a00002002200641016a360288012002200841016a22063a00d8012006210820064120470d000b20024198016a41086a2208200241b8016a41086a29030037030020024198016a41106a220d200241b8016a41106a29030037030020024198016a41186a220e200241b8016a41186a290300370300200220022903b801370398012002200c20066b36028c01200241186a20024188016a1080022002290318a70d04200241186a41106a290300210f20022903202110200220024188016a1080022002290300a70d04200241106a290300211120022903082112200241b8016a20024188016a10b20420022802b8012213450d0420022802bc01210c200228028c012214450d0320022802c001211520022014417f6a221636028c012002200228028801221741016a3602880120172d0000221841014b0d034100210620180e020201020b2002410036028c01200841ff0171450d03200241003a00d8010c030b20164104490d0120022014417b6a36028c012002201741056a3602880120172800012119410121060b200241e8006a41186a200e290300221a370300200241306a41086a2008290300370300200241306a41106a200d290300370300200241306a41186a201a3703002002200229039801370330410021082010211a200f211b2012211c2011211d2013211e200c211f201521200c020b200c450d00200c41186c450d00201310230b200241003602a00120024201370398012002410a36026c2002200241d0006a360268200220024198016a36029401200241013602cc01200242013702bc0120024180c5c6003602b8012002200241e8006a3602c80120024194016a4184a5c200200241b8016a10311a20023502a00142208620023502980184100a0240200228029c01450d0020022802980110230b41022106410121080b0240200b450d00200910230b20080d00200241b8016a41186a200241306a41186a290300370300200241b8016a41106a200241306a41106a290300370300200241b8016a41086a200241306a41086a290300370300200220022903303703b801024020012d0018450d00200a10110b20012802142208200141086a2802002209490d04200820096b2208417f4c0d01200128020c210c0240024020080d0041002101410121050c010b20082101200810212205450d040b2005200c20096a200810a1052109200041286a201d3702002000201c370220200041186a201b3702002000201a370210200020193602402000200636023c200020203602382000201f3602342000201e360230200020083602082000200136020420002009360200200041c4006a20022903b801370200200041cc006a200241c0016a290300370200200041d4006a200241c8016a290300370200200041dc006a200241b8016a41186a2903003702002007a7450d06200310230c060b02402007a7450d00200310230b200241b8016a2001350214422086200135020c841019108b0120022802b80122030d010c040b0b1032000b1033000b2009200841cc96c7001044000b2000410236023c0b200241e0016a24000bad0407047f017e017f017e017f017e057f230041e0006b22012400200141306a41186a22024200370300200141306a41106a22034200370300200141306a41086a220442003703002001420037033041e4dec400ad4280808080e000842205100c22062900002107200141d0006a41086a2208200641086a2900003703002001200737035020061023200420082903003703002001200129035037033041e8ffc400ad4280808080b002842207100c220629000021092008200641086a2900003703002001200937035020061023200320012903502209370300200141106a41086a220a2004290300370300200141106a41106a220b2009370300200141106a41186a220c200829030037030020012001290330370310200141086a200141106a412010cd01200128020c210d2001280208210e200242003703002003420037030020044200370300200142003703302005100c220629000021052008200641086a290000370300200120053703502006102320042008290300370300200120012903503703302007100c220629000021052008200641086a2900003703002001200537035020061023200320012903502205370300200a2004290300370300200b2005370300200c2008290300370300200120012903303703102001417f200d4100200e1b220820006a220420042008491b2208418094ebdc032008418094ebdc03491b360230200141106aad4280808080800484200141306aad4280808080c00084100e200141e0006a24000b931107047f017e017f017e037f017e017f230041e0006b2205240020054102360208200541306a41186a22064200370300200541306a41106a22074200370300200541306a41086a220842003703002005420037033041e4dec400ad4280808080e000842209100c220a290000210b200541d0006a41086a220c200a41086a2900003703002005200b370350200a10232008200c2903003703002005200529035037033041d483c500ad4280808080e00184100c220a290000210b200c200a41086a2900003703002005200b370350200a102320072005290350220b370300200541106a41086a220a2008290300370300200541106a41106a220d200b370300200541106a41186a220e200c29030037030020052005290330370310200541203602342005200541106a360230200541086a200541306a10c4022005410036023041d7ddc400ad4280808080800284200541306aad4280808080c00084220f100e200642003703002007420037030020084200370300200542003703302009100c2210290000210b200c201041086a2900003703002005200b370350201010232008200c2903003703002005200529035037033041f3dec400ad4280808080e00084100c2210290000210b200c201041086a2900003703002005200b3703502010102320072005290350220b370300200a2008290300370300200d200b370300200e200c2903003703002005200529033037031020052000360230200541106aad4280808080800484220b200f100e200642003703002007420037030020084200370300200542003703302009100c2210290000210f200c201041086a2900003703002005200f370350201010232008200c290300370300200520052903503703304191dfc400ad4280808080e00084100c2210290000210f200c201041086a2900003703002005200f3703502010102320072005290350220f370300200a2008290300370300200d200f370300200e200c29030037030020052005290330370310200541203602342005200541106a36023020032802002003280208200541306a10f802200642003703002007420037030020084200370300200542003703302009100c22062900002109200c200641086a29000037030020052009370350200610232008200c2903003703002005200529035037033041f9dec400ad4280808080a00184100c22062900002109200c200641086a2900003703002005200937035020061023200720052903502209370300200a2008290300370300200d2009370300200e200c29030037030020052005290330370310024041201021220c450d00200c2001290000370000200c41186a200141186a290000370000200c41106a200141106a290000370000200c41086a200141086a290000370000200b200cad4280808080800484100e200c1023200541306a2000417f6a10d403200535023821092005280230210841201021220c450d00200c2001290000370000200c41186a200141186a290000370000200c41106a200141106a290000370000200c41086a200141086a29000037000020094220862008ad84200cad4280808080800484100e200c102302402005280234450d00200810230b200541306a41186a22064200370300200541306a41106a220a4200370300200541306a41086a220842003703002005420037033041e4dec400ad4280808080e00084100c22012900002109200541d0006a41086a220c200141086a29000037030020052009370350200110232008200c290300370300200520052903503703304183dfc400ad4280808080e00184100c22012900002109200c200141086a290000370300200520093703502001102320072005290350370000200741086a200c290300370000200541106a41086a2008290300370300200541106a41106a200a290300370300200541106a41186a20062903003703002005200529033037031041201021220c450d00200c2002290000370000200c41186a200241186a290000370000200c41106a200241106a290000370000200c41086a200241086a290000370000200b200cad4280808080800484100e200c102302402004450d00200541306a41186a22014200370300200541306a41106a22024200370300200541306a41086a220842003703002005420037033041e4dec400ad4280808080e000842209100c2206290000210f200541d0006a41086a220c200641086a2900003703002005200f370350200610232008200c2903003703002005200529035037033041c0e3c400ad4280808080e00084100c2206290000210f200c200641086a2900003703002005200f3703502006102320072005290350370000200741086a2206200c290300370000200541106a41086a220a2008290300370300200541106a41106a220d2002290300370300200541106a41186a220e200129030037030020052005290330370310200b1011200142003703002002420037030020084200370300200542003703302009100c2203290000210f200c200341086a2900003703002005200f370350200310232008200c2903003703002005200529035037033041e481c500ad4280808080a00184100c2203290000210f200c200341086a2900003703002005200f37035020031023200720052903503700002006200c290300370000200a2008290300370300200d2002290300370300200e200129030037030020052005290330370310200b1011200142003703002002420037030020084200370300200542003703302009100c22032900002109200c200341086a29000037030020052009370350200310232008200c2903003703002005200529035037033041eae9c400ad4280808080b00184100c22032900002109200c200341086a2900003703002005200937035020031023200720052903503700002006200c290300370000200a2008290300370300200d2002290300370300200e200129030037030020052005290330370310200b10120b200541e0006a24000f0b1033000ba67e07047f017e047f017e1b7f097e037f230022012102200141e0196b41607122032400200320003602182003418094ebdc0336021c200341f8076a2000108a0420032802f8072104200320032802800822013602e407200320043602e007200341b00a6a2001ad4220862004ad8422051010108b01024002400240024002400240024020032802b00a22060d00410021010c010b20032802b40a21072003200341b80a6a2802003602a40f200320063602a00f200341106a200341a00f6a1088010240024002402003280210450d0041002101200341003602e80c410121080c010b2003280214220920032802a40f220141d0026e2208200820094b1bad42d0027e220a422088a70d04200aa7220b417f4c0d0402400240200b0d004108210c0c010b200b1021220c450d040b41002108200341003602b80f2003200c3602b00f2003200b41d0026e3602b40f0240024020090d000c010b2009417f6a210b0340024002402001450d0020032802a00f220d2d0000210e20032001417f6a220f3602a40f2003200d41016a3602a00f200e41014b0d00410221090240200e0e020200020b024002400240200f0d00410221090c010b200d2d0001210e20032001417e6a220f3602a40f410221092003200d41026a3602a00f02400240200e41014b0d0041002101024002400240200e0e020100010b200341086a200341a00f6a10880120032802080d0220032802a40f200328020c220e490d02200e417f4c0d0e02400240200e0d00410121010c010b200e10272201450d0e20032802a40f200e490d02200120032802a00f200e10a1051a20032802a40f220d200e490d042003200d200e6b3602a40f200320032802a00f200e6a3602a00f0b2001450d02200ead220a422086200a84210a20032802a40f210f0b200aa7210e02400240024002400240200f450d0020032802a00f22102d0000210d2003200f417f6a3602a40f2003201041016a3602a00f200341a0146a200341a00f6a10990320032802a0144116460d0320034180176a200341a0146a41b00210a1051a20032802a40f220f450d0420032802a00f22112d000021102003200f417f6a22123602a40f2003201141016a3602a00f201041014b0d044100210920100e020201020b2001450d07200e450d070c040b20124104490d02201128000121102003201141056a3602a00f2003200f417b6a22093602a40f20094104490d02201128000521132003200f41776a3602a40f2003201141096a3602a00f41012109201021140b200a422088a72115200341a0146a20034180176a41b00210a1051a200320032800f0073602d8072003200341f0076a41036a2800003600db070c060b2001450d04200e450d040c010b20034180176a10b4022001450d01200e450d010b200110230b2016210d2017210e20182101410221090c020b200e200d418ca9c0001044000b2016210d2017210e201821010b200341e8116a200341a0146a41b00210a1051a200320032800db0736008b05200320032802d80736028805024020094102460d00200341d8026a200341e8116a41b00210a1051a2003200328008b053600d30220032003280288053602d00220152119200e211a2001211b200d211c2013211d2014211e200d2116200e2117200121180c020b200d2116200e2117200121180b410321090b200341a0056a200341d8026a41b00210a1051a200320032800d30236009b05200320032802d00236029805024020094103460d00200341206a200341a0056a41b00210a1051a2003200328009b05360093052003200328029805360290050240200820032802b40f470d00200341b00f6a2008410110ab0120032802b00f210c20032802b80f21080b200c200841d0026c6a200341206a41b00210a105220141c8026a201c3a0000200141c4026a201d3602002001201e3602c002200120093602bc02200120193602b8022001201a3602b4022001201b3602b002200141c9026a200328029005360000200141cc026a2003280093053600002003200841016a22083602b80f200b450d02200b417f6a210b20032802a40f21010c010b0b200341003602e80c02402008450d00200841d0026c2108200c210103400240200141bc026a2802004102460d000240200141b0026a2802002209450d00200141b4026a280200450d00200910230b2001109e030b200141d0026a2101200841b07d6a22080d000b0b024020032802b40f2201450d00200141d0026c450d00200c10230b41002101410121080c010b200341e80c6a41086a200341b00f6a41086a280200360200200320032903b00f220a3703e80c200aa722014521082001450d0020032902ec0c210a0c010b200341003602881720034201370380172003410a3602ec112003200341e0076a3602e811200320034180176a3602b00f200341b4146a4101360200200342013702a41420034180c5c6003602a0142003200341e8116a3602b014200341b00f6a4184a5c200200341a0146a10311a20033502881742208620033502801784100a0240200328028417450d0020032802801710230b0b02402007450d00200610230b02402008450d00410021010c010b200510110b200a420020011b210a024020032802fc07450d00200410230b2001410820011b221f200a422088a7220841d0026c220b6a2109200aa72120201f2101024002402008450d00200b41b07d6a210c200341e8116a41046a2117200341b00f6a41046a210f200341e80c6a41046a21074100210b201f210102400340200341206a200141b00210a1051a200141c8026a2d00002104200141c4026a280200210d200141c0026a2802002119200141b8026a280200211a200141b4026a280200211b200141b0026a2802002106200141bc026a28020021082003200141cc026a280000360093052003200141c9026a28000036029005024020084103470d00200141d0026a21010c030b2007200341206a41b00210a1052116200341b00f6a200341e80c6a41b40210a1051a200341d8026a200f41b00210a1051a20032003280093053600d30220032003280290053602d0020240024020084102470d004101210e0c010b2017200341d8026a41b00210a1051a200341b00a6a200341e8116a41b40210a1051a200320032800d3023600f307200320032802d0023602f0074100210e20062118201b2115201a211320042114200d211020192111200b21120b200341f8076a200341b00a6a41b40210a1051a200320032800f3073600db07200320032802f0073602d807200e450d01200b41016a210b200c41b07d6a210c200141d0026a22012009470d000b200921010c010b200341a0056a200341f8076a41b40210a1051a200320032800db0736009b05200320032802d80736029805200341a0146a200341a0056a41b40210a1051a2003200328009b053600a30f20032003280298053602a00f200141d0026a210120084102460d0020034180176a200341a0146a41b40210a1051a200320032800a30f3600e307200320032802a00f3602e007200341a0146a20034180176a41b40210a1051a200320032800e3073600eb11200320032802e0073602e81141d80210212207450d0220072012360200200741046a200341a0146a41b40210a1051a200720143a00d002200720103602cc02200720113602c802200720083602c402200720133602c002200720153602bc02200720183602b802200720032802e8113600d102200741d4026a20032800eb113600002009210802400240200c450d00200b41016a210c200341e80c6a41046a210602400340200341a0056a200141b00210a1051a200141c8026a2d0000210e200141c4026a2802002104200141c0026a280200210d200141b8026a2802002119200141b4026a280200211a200141b0026a280200211b200141bc026a280200210b2003200141cc026a2800003600f3072003200141c9026a2800003602f0070240200b4103470d00200141d0026a21080c030b2006200341a0056a41b00210a1051a200341b00f6a200341e80c6a41b40210a1051a200341d8026a200f41b00210a1051a200320032800f3073600d302200320032802f0073602d00202400240200b4102470d00410121080c010b2017200341d8026a41b00210a1051a200341b00a6a200341e8116a41b40210a1051a200320032800d3023600a30f200320032802d0023602a00f200320032802a00f36029805200320032800a30f36009b0541002108201b2121201a212220192123200e211c2004211d200d211e200c21240b200341f8076a200341b00a6a41b40210a1051a2003200328009b05360093052003200328029805360290052008450d01200c41016a210c200141d0026a22012009470d000b200921080c010b200341a0146a200341f8076a41b40210a1051a2003412c6a200328009305360000200320233602dc16200320223602d816200320213602d4162003201c3a00282003201d3602242003201e3602202003200328029005360029200141d0026a21084101211c0240200b4102470d004101211d0c020b200c41016a210120034180176a200341a0146a41c00210a1051a200341e0076a41086a2206200341206a41086a290300370300200320032903203703e007200341a90f6a211e4101211d4101211c024002400340200341a0146a20034180176a41c00210a1051a200341e8116a41086a220e2006290300370300200320032903e0073703e8110240201c201d470d000240024002400240201d41016a220c201d490d00201d4101742204200c2004200c4b1bad42d8027e220a422088a70d00200aa7220c4100480d000240201d0d00200c0d02410821070c040b201d41d8026c2204200c460d0320040d02200c0d01410821070c030b102c000b200c102122070d010c040b20072004200c10252207450d030b200c41d8026e211d0b2007201c41d8026c6a220c2024360200200c41046a200341a0146a41c00210a1051a200c41c4026a200b360200200c41c8026a20032903e811370300200c41d0026a200e290300370300201c41016a211c024020082009470d00200921080c050b02400340200341206a200841b00210a1051a200841c8026a2d0000210e200841c4026a2802002104200841c0026a280200210d200841b8026a2802002119200841b4026a280200211a200841b0026a280200211b200841bc026a280200210b2003200841cc026a280000360093052003200841c9026a280000360290050240200b4103470d00200841d0026a21080c070b2016200341206a41b00210a1051a200341b00f6a200341e80c6a41b40210a1051a200341d8026a200f41b00210a1051a20032003280093053600d30220032003280290053602d00202400240200b4102470d004101210c0c010b2017200341d8026a41b00210a1051a200341b00a6a200341e8116a41b40210a1051a200320032800d30236008b05200320032802d0023602880520032003280288053602f0072003200328008b053600f3074100210c201b2118201a211520192113200e211420042110200d2111200121120b200341f8076a200341b00a6a41b40210a1051a200320032800f3073600db07200320032802f0073602d807200c450d01200141016a2101200841d0026a22082009470d000b200921080c050b200341a0056a200341f8076a41b40210a1051a200320032800db0736009b05200320032802d80736029805200341a0146a200341a0056a41b40210a1051a201e200328029805360000201e41036a200328009b05360000200320133602dc16200320153602d816200320183602d416200320143a00a80f200320103602a40f200320113602a00f200b4102460d02200841d0026a2108200141016a210120034180176a200341a0146a41c00210a1051a2006200341a00f6a41086a290300370300200320032903a00f3703e007201221240c000b0b102a000b200841d0026a21080c010b4101211c4101211d0b024020092008460d000340200841d0026a21010240200841bc026a2802004102460d000240200841b0026a280200220b450d00200841b4026a280200450d00200b10230b2008109e030b2001210820092001470d000b0b02402020450d00202041d0026c450d00201f10230b0240201c4115490d00201c410176ad42d8027e220a422088a70d04200aa72210417f4c0d04201010212215450d034100210120034100360288172003420437038017200741a87d6a2113200741c87a6a21144104210841002106201c210f0340200f21044100210f4101210e02402004417f6a2216450d000240024002400240024002402007201641d8026c6a41d0026a2d0000200441d8026c221920076a41a07d6a2d0000220b490d002004417e6a210d201420196a210c4100210f4100210903400240200d2009470d002004210e0c080b200941016a2109200b41ff0171210e200c2d0000210b200c41a87d6a210c200e200b4f0d000b200941016a210e2009417f7320046a21090c010b201420196a210c2016210902400340024020094101470d00410021090c020b2009417f6a2109200b41ff0171210e200c2d0000210b200c41a87d6a210c200e200b490d000b0b20042009490d022004201c4b0d01200420096b220e410176220d450d002007200941d8026c6a210b201320196a210c0340200341a0146a200b41d80210a1051a200b200c41d80210a20541d8026a210b200c200341a0146a41d80210a10541a87d6a210c200d417f6a220d0d000b0b024020090d002009210f0c050b0240200e41094d0d002009210f0c050b2004201c4b0d022007200941d8026c6a2119034020042009417f6a220f490d0402402004200f6b220e4102490d002007200941d8026c6a220c41d0026a2d00002007200f41d8026c6a220b41d0026a2d0000221b4f0d00200341a0146a200b41d00210a1051a2003200b41d4026a2800003600f3072003200b41d1026a2800003602f007200b200c41d80210a105211a0240200e4103490d002016210d2019210b201a4180086a2d0000201b4f0d000340200b200b41d8026a220c41d80210a105211a2009200d417f6a220d460d01200c210b201a4180086a2d0000201b490d000b0b200c200341a0146a41d00210a105220941d0026a201b3a0000200941d1026a20032802f007360000200941d4026a20032800f3073600000b200f450d05201941a87d6a2119200f2109200e410a4f0d050c000b0b2004201c41d089c7001043000b2009200441d089c7001044000b20042009417f6a220f490d002004201c41e089c7001043000b200f200441e089c7001044000b02402006200328028417470d0020034180176a2006410110a5012003280280172108200328028817220121060b200820064103746a2209200e3602042009200f3602002003200141016a22013602881720012106024020014102490d000240024003400240024002400240024020082001417f6a4103746a2209280200450d00200141037420086a220e41746a280200220c2009280204220b4b0d010b20014103490d022009280204210b20082001417d6a221a4103746a28020421090c010b41022106200141024d0d0620082001417d6a221a4103746a2802042209200b200c6a4d0d0041032106200141034d0d06200e41646a2802002009200c6a4b0d050b2009200b490d010b2001417e6a211a0b02400240024002400240024002402001201a41016a221b4d0d002001201a4d0d012008201a41037422166a2201280204221720012802006a22012008201b41037422186a22082802002206490d022001201c4b0d032007200641d8026c6a220d2008280204221941d8026c22086a210b200141d8026c210e200120066b220c20196b220120194f0d042015200b200141d8026c220810a105220c20086a210920194101480d0520014101480d052013200e6a210e200b21080340200e200841a87d6a220b200941a87d6a2204200941786a2d0000200841786a2d00004922011b41d80210a105210e2009200420011b21090240200d200b200820011b2208490d00200c21010c080b200e41a87d6a210e200c2101200c2009490d000c070b0b201b200141f089c7001030000b201a200141808ac7001030000b2006200141908ac7001044000b2001201c41908ac7001043000b2015200d200810a105220120086a2109024020194101480d00200c20194c0d002007200e6a210420012101200d21080340200b2001200b41d0026a2d0000200141d0026a2d000049220c1b210e2001200141d8026a200c1b21012008200e41d80210a10541d8026a2108200b41d8026a200b200c1b220b20044f0d03200920014b0d000c030b0b200d2108200121010c010b200b2108200c21010b20082001200920016b2209200941d802706b10a1051a02402003280288172201201a4d0d00200328028017220820166a2209201720196a360204200920063602002001201b4d0d02200820186a2209200941086a2001201b417f736a41037410a2051a20032001417f6a220136028817200141014b0d010c030b0b201a200141a08ac7001030000b201b2001103b000b200121060b200f0d000b024020032802841741ffffffff0171450d00200810230b201041d802702101201041d802490d0220102001460d02201510230c020b201c4102490d01201c417f6a21082007201c41d8026c6a210b4100210c0340024002400240201c20082201417f6a2208490d00201c20086b220e4102490d022007200141d8026c6a220141d0026a2d00002007200841d8026c6a220941d0026a2d000022044f0d02200341a0146a200941d00210a1051a2003200941d4026a2800003600f3072003200941d1026a2800003602f0072009200141d80210a105210d200e4103490d01200c2109200b210e200d4180086a2d000020044f0d010340200e220141a87d6a200141d80210a1051a2009417f6a2209450d02200141d8026a210e200141a8056a2d000020044f0d020c000b0b2008201c41c089c7001044000b2001200341a0146a41d00210a105220141d0026a20043a0000200141d1026a20032802f007360000200141d4026a20032800f3073600000b200c41016a210c200b41a87d6a210b20080d000c020b0b024020092001460d000340200141d0026a21080240200141bc026a2802004102460d000240200141b0026a280200220b450d00200141b4026a280200450d00200b10230b2001109e030b2008210120092008470d000b0b4100211d4108210702402020450d00202041d0026c450d00201f10230b4100211c0b200341003602b00a200341d00f6a200341b00a6a360200200341cc0f6a200341186a360200200342003703c00f20032007201c41d8026c6a3602bc0f200320073602b80f2003201d3602b40f200320073602b00f20032003411c6a3602c80f20034180176a200341b00f6a108b04024002400240024020032802bc194103460d00200341a0146a20034180176a41d00210a1051a41d0021021220b450d04200b200341a0146a41d00210a105210120034281808080103702ec0c200320013602e80c200341e8116a41206a200341b00f6a41206a280200360200200341e8116a41186a200341b00f6a41186a290300370300200341e8116a41106a200341b00f6a41106a290300370300200341e8116a41086a200341b00f6a41086a290300370300200320032903b00f3703e81120034180176a200341e8116a108b04024020032802bc194103470d00410121080c020b4102210841d0022101410121090340200341a0146a20034180176a41d00210a1051a02402008417f6a2009470d00200341e80c6a2009410110ab0120032802e80c210b0b200b20016a200341a0146a41d00210a1051a200320083602f00c20034180176a200341e8116a108b0420032802bc194103460d02200141d0026a2101200841016a210820032802ec0c21090c000b0b20032802bc0f20032802b80f22096b220141d8026d210802402001450d00200841d8026c2108200941bc026a2101034002402001417c6a2802002209450d002001280200450d00200910230b200141cc7d6a109e03200141d8026a2101200841a87d6a22080d000b0b024020032802b40f2201450d00200141d8026c450d0020032802b00f10230b4100210c4108210b0c010b20032802f41120032802f011220c6b220141d8026d210902402001450d00200941d8026c2109200c41bc026a2101034002402001417c6a280200220c450d002001280200450d00200c10230b200141cc7d6a109e03200141d8026a2101200941a87d6a22090d000b0b024020032802ec112201450d00200141d8026c450d0020032802e81110230b20032802ec0c210c2008450d00200328021841016a200b2008108c04200841d0026c210820032802b00a2125200b210103400240200141bc026a2802004102460d000240200141b0026a2802002209450d00200141b4026a280200450d00200910230b2001109e030b200141d0026a2101200841b07d6a22080d000c020b0b20032802b00a21250b0240200c450d00200c41d0026c450d00200b10230b200341e8116a41086a2208420037030041002104200341003602b00a200341003600b30a200342003703e81120034196adc300ad4280808080900184100c22012800093602a00f20032001410c6a2800003600a30f2001290000210a20012d0008210920011023200320032800a30f3600b30a200320032802a00f3602b00a41fcdfc300ad4280808080f00184100c22012900002105200341a00f6a41086a220b200141086a290000370300200320053703a00f200110232008200b2903002205370300200341a0146a410c6a20032800b30a360000200341b8146a2005370200200320032903a00f22053703e811200320093a00a8142003200a3702a014200320032802b00a3600a914200320053702b01420034180176a200341a0146a108f03024002400240200328028017220b0d0041002109200341003602b80f200342043703b00f4104210b41002101410021084100210441002115410421180c010b200329028417210a2003200b3602b00f2003200a3702b40f200aa721090240200a422088a7220141024f0d004104211820012108410021150c010b200b2802082104200b2802042115200b2802002118200b200b410c6a2001417f6a2201410c6c10a2051a200320013602b80f41012108200141014b0d010b0340024020082009470d00200341b00f6a2009410110950120032802b00f210b20032802b80f220121080b200b2008410c6c6a22084100360208200842043702002003200141016a22013602b80f200141014b0d0120032802b40f2109200121080c000b0b200341b0146a2122200341a9146a212320034180176a41086a2208200341b00f6a41086a280200360200200320032903b00f220a3703801702400240200aa7220b0d00200341e8116a41086a22084200370300200341003602b00a200341003600b30a200342003703e81120034196adc300ad4280808080900184100c22012800093602a00f20032001410c6a2800003600a30f2001290000210a20012d0008210920011023200320032800a30f3600b30a200320032802a00f3602b00a41fcdfc300ad4280808080f00184100c22012900002105200341a00f6a41086a220b200141086a290000370300200320053703a00f200110232008200b2903002205370300200320032903a00f22263703e811202320032802b00a360000202341036a20032800b30a36000020222026370000202241086a2005370000200320093a00a8142003200a3702a014200341a0146aad428080808080048410110c010b200341e8116a41086a22094200370300200341003602b00a200341003600b30a200342003703e81120034196adc300ad4280808080900184100c22012800093602a00f20032001410c6a2800003600a30f2001290000210a20012d0008210c20011023200320032800a30f3600b30a200320032802a00f3602b00a41fcdfc300ad4280808080f00184100c22012900002105200341a00f6a41086a220e200141086a290000370300200320053703a00f200110232009200e2903002205370300200320032903a00f22263703e811202320032802b00a360000202341036a20032800b30a36000020222026370000202241086a20053700002003200c3a00a8142003200a3702a014200341203602ec112003200341a0146a3602e81120034180176a200341e8116a109003024020082802002201450d002001410c6c2108200b210103400240200141046a2802002209450d00200941246c450d00200128020010230b2001410c6a2101200841746a22080d000b0b2003280284172201450d002001410c6c450d00200b10230b200341e8116a41086a220842003703004100211a200341003602b00a200341003600b30a200342003703e81120034196adc300ad4280808080900184100c22012800093602a00f20032001410c6a2800003600a30f2001290000210a20012d0008210920011023200320032800a30f3600b30a200320032802a00f3602b00a41a4e2c300ad4280808080a00184100c22012900002105200341a00f6a41086a220b200141086a290000370300200320053703a00f200110232008200b2903002205370300200320032903a00f22263703e811202320032802b00a360000202341036a20032800b30a36000020222026370000202241086a2005370000200320093a00a8142003200a3702a01420034180176a200341a0146a108f03200329028417420020032802801722081b220a422088a72219410c6c21012008410420081b220d41746a210841012109024003402009211b024020010d000c020b200141746a2101201b41016a2109200841146a210b2008410c6a220c2108200b280200220b450d000b20034180176a41086a200c2802002201410c6a29020037030020034190176a200141146a29020037030020032001290204370380172001411c6a29020021272001280200210e2001200141246a200b417f6a220841246c10a2051a200c41086a20083602004101211a0b2003200d3602e80c2003200a3702ec0c200341e8116a41086a22084200370300200341003602b00a200341003600b30a200342003703e81120034196adc300ad4280808080900184100c22012800093602a00f20032001410c6a2800003600a30f2001290000210520012d0008210920011023200320032800a30f3600b30a200320032802a00f3602b00a41a4e2c300ad4280808080a00184100c22012900002126200341a00f6a41086a220b200141086a290000370300200320263703a00f200110232008200b2903002226370300200320032903a00f22283703e811202320032802b00a360000202341036a20032800b30a36000020222028370000202241086a2026370000200320093a00a814200320053702a014200341203602ec112003200341a0146a3602e811200341e80c6a200341e8116a109003200aa7210b02402019450d002019410c6c2108200d210103400240200141046a2802002209450d00200941246c450d00200128020010230b2001410c6a2101200841746a22080d000b0b0240200b450d00200b410c6c450d00200d10230b200341b00f6a41086a220b20034180176a41086a290300370300200341b00f6a41106a220c20034180176a41106a29030037030020032003290380173703b00f410021060240201a450d00200441246c2101201821080340024020010d00410121060c020b2001415c6a210120082802002109200841246a21082009200e470d000b410021060b200341e8116a41086a22084200370300200341003602b00a200341003600b30a200342003703e81120034196adc300ad4280808080900184100c22012800093602a00f20032001410c6a2800003600a30f2001290000210a20012d0008210920011023200320032800a30f3600b30a200320032802a00f3602b00a41b0dfc300ad4280808080a00184100c22012900002105200341a00f6a41086a220d200141086a290000370300200320053703a00f200110232008200d2903002205370300200320032903a00f22263703e811202320032802b00a360000202341036a20032800b30a36000020222026370000202241086a2005370000200320093a00a8142003200a3702a01420034180176a200341a0146a10c9032003280280172101200329028417210a200341003602f00c200342043703e80c200341e8116a41106a200c2903003703002008200b290300370300200320032903b00f3703e8112001410420011b211c2018200441246c22086a210f024002400240024002400240200a420020011b2229422088a7220b41027422094102752201200841246d6a22082001490d00200820066a220120084f0d010b201c20096a21072003200e360284172003200636028017200320032903e811370388172003200341f0116a290300370290172003200341e8116a41106a2903003703981741282108410421174104211a410021164100210d2018210b201c21190240410041ff01710e03020300020b410021010c030b200341e80c6a4100200110a60120032802e80c211720032802f00c21162003200e360284172003200636028017200320032903e811370388172003200341f0116a290300370290172003200341f8116a2903003703981720172016412c6c6a21010240200b450d002016200b4102742209417c6a4102766a210c201c210803402008280200210b200141246a41023602002001200b3602002001412c6a2101200841046a21082009417c6a22090d000b200c41016a21160b0240202942ffffffff0383500d00201c10230b02402004450d00200341b8146a2109200341b0146a210b200341a8146a210c2018210803402008280200210e20092008411c6a290200370300200b200841146a290200370300200c2008410c6a2902003703002003200841046a2902003703a0142001200e360200200141046a20032903a0143702002001410c6a200c290300370200200141146a200b2903003702002001411c6a2009290300370200200141246a42013702002001412c6a2101201641016a2116200841246a2208200f470d000b0b02402015450d00201541246c450d00201810230b200329038817210520032903901721262003290398172128200329038017210a200341003602a0140240200aa74101470d00200a422088a7210820032903b814212a20032903b014212b20032903a814212c20032903a014210a0340202a212d202b212e202c212920012008360200200141046a2005370200200141286a201b360200200141246a41013602002001411c6a20273702002001410c6a2026370200200141146a2028370200200341003602a0142001412c6a2101201641016a2116200aa72109200a422088a7210820032903b814212a20032903b014212b20032903a814212c20032903a014210a20292105202e2126202d212820094101460d000b0b200320163602f00c0c030b410121010c010b410221010b034002400240024002400240024002400240024020010e03000104040b200341003602a0142003290398172126200320032903b814370398172003290390172105200320032903b01437039017200329038817210a200320032903a814370388172003290380172128200320032903a014222a370380172028a74101470d042028422088a7210c202aa721060c010b0240024002400240200d41ff01710e03010200010b200f200b470d044102210d0c020b024020072019470d000240200f200b470d004102210d0c030b200b41146a2902002126200b410c6a2902002105200b411c6a290200212b200b290204210a4101210e4102210d200b2101200b41246a210b0c080b4102210e4100210d20192101201941046a21190c070b20072019470d054101210d0b200341003602a0142003290398172126200320032903b814370398172003290390172105200320032903b01437039017200329038817210a200320032903a814370388172003290380172128200320032903a014222a370380172028a74101470d032028422088a7210c202aa721060b4101210e4102210920272128201b21040c050b200b41146a2902002126200b410c6a2902002105200b411c6a290200212b200b290204210a4101210e4102210d200b2101200b41246a210b0c030b024002400240200d41ff01710e03010200010b200f200b460d02200b41146a2902002126200b410c6a2902002105200b411c6a2902002128200b290204210a200b280200210c41002104410121094102210d200b41246a210b4101210e0c050b024020072019470d00200f200b460d02200b41146a2902002126200b410c6a2902002105200b411c6a2902002128200b290204210a200b280200210c41002104410121094102210d200b41246a210b4101210e0c050b2019280200210c4102210e410121094100210d201941046a21190c040b20072019460d002019280200210c4102210e4101210d201941046a2119410121090c030b0240202942ffffffff0383500d00201c10230b2015450d04201541246c450d04201810230c040b4102210e4101210d20192101202c210a202d2105202e2126201941046a21190b2001280200210c41002109200a212c2005212d2026212e202b2128410021040b0240201620032802ec0c470d00024002400240024020090e03010200010b200641014621010c020b0240024002400240200d41ff01710e03010200010b200f200b6b41246d21010c020b417f200720196b4102752201200f200b6b41246d6a221a201a2001491b21010c010b200720196b41027521010b417f200120064101466a221a201a2001491b21010c010b024002400240200d41ff01710e03010200010b200f200b6b41246d21010c020b417f200720196b4102752201200f200b6b41246d6a221a201a2001491b21010c010b200720196b41027521010b200341e80c6a2016417f200141016a221a201a2001491b10a60120032802e80c2217211a0b201a20086a220120043602002001417c6a200e360200200141746a2028370200200141586a200c3602002001415c6a220120053702082001200a370200200141106a20263702002003201641016a22163602f00c2008412c6a2108024002400240200941ff01710e03000102000b410121010c020b410221010c010b410021010c000b0b20032802ec0c212f20164115490d032016410176ad422c7e220a422088a70d01200aa72230417f4c0d0120301021221f450d004100210120034100360288172003420437038017201741546a21212017412c6a2131201741fc7e6a212441042109410021202016210703402007210d41002107410121040240200d417f6a220c450d000240024002400240024002402017200c412c6c6a280200200d412c6c221a20176a41a87f6a2802002208490d00200d417e6a21192024201a6a210c410021074100210b034002402019200b470d00200d21040c080b200b41016a210b2008200c280200220e4f2104200c41546a210c200e210820040d000b200b41016a2104200b417f73200d6a210c0c010b2024201a6a210b024003400240200c4101470d004100210c0c020b200c417f6a210c2008200b280200220e492104200b41546a210b200e210820040d000b0b200d200c490d01200d20164b0d02200d200c6b2204410176220e450d002017200c412c6c6a21082021201a6a210b0340200341a0146a41286a2219200841286a221a280200360200200341a0146a41206a221b200841206a2206290200370300200341a0146a41186a220f200841186a2207290200370300200341a0146a41106a2218200841106a221c290200370300200341a0146a41086a2215200841086a2213290200370300200320082902003703a014200b41086a2214290200210a200b41106a22102902002105200b41186a22112902002126200b41206a22122902002128200b41286a221d280200211e2008200b290200370200201a201e3602002006202837020020072026370200201c20053702002013200a370200201d20192802003602002012201b2903003702002011200f2903003702002010201829030037020020142015290300370200200b20032903a0143702002008412c6a2108200b41546a210b200e417f6a220e0d000b0b0240200c0d00200c21070c050b0240200441094d0d00200c21070c050b200d20164b0d02200d200c6b210e2031200c412c6c6a21190340200d200c417f6a2207490d040240200d20076b22044102490d002017200c412c6c6a220828020020172007412c6c6a220c28020022064f0d00200341a0146a41206a220f200c41246a290200370300200341a0146a41186a2218200c411c6a290200370300200341a0146a41106a221c200c41146a290200370300200341a0146a41086a2215200c410c6a290200370300200c290204210a200c41286a200841286a2802003602002003200a3703a014200c41206a200841206a290200370200200c41186a200841186a290200370200200c41106a200841106a290200370200200c41086a200841086a290200370200200c20082902003702004101210b024020044103490d00200c28025820064f0d004102211a2019211b0340201b220841546a220b2008290200370200200b41286a200841286a280200360200200b41206a200841206a290200370200200b41186a200841186a290200370200200b41106a200841106a290200370200200b41086a200841086a290200370200200e201a220b460d01200b41016a211a2008412c6a221b2802002006490d000b0b20082006360200200c200b412c6c6a220820032903a014370204200841246a200f2903003702002008411c6a2018290300370200200841146a201c2903003702002008410c6a20152903003702000b2007450d05201941546a2119200e41016a210e2007210c2004410a4f0d050c000b0b200c200d41d089c7001044000b200d201641d089c7001043000b200d200c417f6a2207490d00200d201641e089c7001043000b2007200d41e089c7001044000b02402020200328028417470d0020034180176a2020410110a5012003280280172109200328028817220121200b200920204103746a22082004360204200820073602002003200141016a22013602881720012120024020014102490d000240024003400240024002400240024020092001417f6a4103746a2208280200450d00200141037420096a220e41746a280200220c2008280204220b4b0d010b20014103490d022008280204210b20092001417d6a221b4103746a28020421080c010b41022120200141024d0d0620092001417d6a221b4103746a2802042208200b200c6a4d0d0041032120200141034d0d06200e41646a2802002008200c6a4b0d050b2008200b490d010b2001417e6a211b0b02400240024002400240024002402001201b41016a22064d0d002001201b4d0d012009201b41037422186a2201280204221c20012802006a22012009200641037422156a2208280200220f490d02200120164b0d032017200f412c6c6a22192008280204221a412c6c22086a210b2001412c6c21092001200f6b220e201a6b2201201a4f0d04201f200b2001412c6c220810a105220d20086a210c201a4101480d0520014101480d05202120096a2108200b210103402008200141546a220b200c41546a220e200e280200200b2802004922041b2209290200370200200841286a200941286a280200360200200841206a200941206a290200370200200841186a200941186a290200370200200841106a200941106a290200370200200841086a200941086a290200370200200c200e20041b210c02402019200b200120041b2201490d00200d21090c080b200841546a2108200d2109200d200c490d000c070b0b2006200141f089c7001030000b201b200141808ac7001030000b200f200141908ac7001044000b2001201641908ac7001043000b201f2019200810a105220d20086a210c0240201a4101480d00200e201a4c0d00201720096a2104200d21092019210103402001200b2009200b280200200928020049220e1b2208290200370200200141286a200841286a280200360200200141206a200841206a290200370200200141186a200841186a290200370200200141106a200841106a290200370200200141086a200841086a29020037020020092009412c6a200e1b21092001412c6a2101200b412c6a200b200e1b220b20044f0d03200c20094b0d000c030b0b20192101200d21090c010b200b2101200d21090b20012009200c20096b22082008412c706b10a1051a02402003280288172201201b4d0d00200328028017220920186a2208201c201a6a3602042008200f360200200120064d0d02200920156a2208200841086a20012006417f736a41037410a2051a20032001417f6a220136028817200141014b0d010c030b0b201b200141a08ac7001030000b20062001103b000b200121200b2007450d030c000b0b1033000b1032000b024020032802841741ffffffff0171450d00200910230b2030412c7021012030412c490d0120302001460d01201f10230c010b20164102490d002016417f6a210920172016412c6c6a210e4101210c03400240024002400240201620092201417f6a2209490d00201620096b22084102490d0320172001412c6c6a220128020020172009412c6c6a220b28020022194f0d03200341a0146a41206a221a200b41246a290200370300200341a0146a41186a221b200b411c6a290200370300200341a0146a41106a2206200b41146a290200370300200341a0146a41086a220f200b410c6a290200370300200b290204210a200b41286a200141286a2802003602002003200a3703a014200b41206a200141206a290200370200200b41186a200141186a290200370200200b41106a200141106a290200370200200b41086a200141086a290200370200200b20012902003702004101210420084103490d02200b28025820194f0d0241002104200e210803402008220141546a22082001290200370200200841286a200141286a280200360200200841206a200141206a290200370200200841186a200141186a290200370200200841106a200141106a290200370200200841086a200141086a290200370200200c2004220d460d02200d417f6a21042001412c6a220828020020194f0d020c000b0b2009201641c089c7001044000b4102200d6b21040b20012019360200200b2004412c6c6a220120032903a014370204200141246a201a2903003702002001411c6a201b290300370200200141146a20062903003702002001410c6a200f2903003702000b200e41546a210e200c417f6a210c20090d000b0b200341e8116a41086a22084200370300200341003602b00a200341003600b30a200342003703e81120034196adc300ad4280808080900184100c22012800093602a00f20032001410c6a2800003600a30f2001290000210a20012d0008210920011023200320032800a30f3600b30a200320032802a00f3602b00a41bce0c300ad4280808080e00084100c22012900002105200341a00f6a41086a220b200141086a290000370300200320053703a00f200110232008200b2903002205370300200320032903a00f22263703e811202320032802b00a360000202341036a20032800b30a36000020222026370000202241086a2005370000200320093a00a8142003200a3702a01420034180176a2017201610d302200341a0146aad220a42808080808004842003350288174220862003280280172201ad84100e0240200328028417450d00200110230b0240202f450d00202f412c6c450d00201710230b20034180176a41086a220842003703002003420037038017200341003602e811200341003600eb11200841b0dfc300ad4280808080a00184100c220141086a290000370300200320012900003703801720011023200341a89ec700ad4280808080900184100c22012800093602880520032001410c6a28000036008b052001290000210520012d0008210920011023200341a0146a41086a20082903003703002003200328008b053600eb1120032003280288053602e811200341bc146a20032800eb11360000200320093a00b814200320053703b01420032003290380173703a014200320032802e8113600b914200a42808080808004841011200010e90320022400417f202541d0f7076a220120012025491b0bc30103017f017e027f0240024002402000280200220241024d0d004101210042002103410121020c010b024002400240024020020e03000102000b410110212204450d0441002102200441003a00002000280204210520044101410510252200450d04200020053600014280808080d00021030c030b410110212200450d03200041013a00000c010b410110212200450d02200041023a00000b4100210242808080801021030b200129020020032000ad84100e024020020d00200010230b0f0b102a000bdb1f07057f067e017f017e017f057e037f230041e00b6b22042400200441a0066a200141c80310a1051a20044198036a200441a0066a10c602410121050240024002400240024002400240024002400240024002400240024002400240024020042d0098034101460d00200441186a20044198036a41086a41800310a1051a024020032802002201450d00200341086a280200210620032802042107200441106a41d7ddc400411010cd0141002105200441a0066a2004280214410020042802101b10c70220042802a0062108200420042802a80636029c0320042008360298032001200620044198036a10c802024020042802a406450d00200810230b2007450d00200110230b200441e8096a200441186a41d0006a10c902200441a0066a200441186a41800310a1051a20042903e8092109024002400240024020042903c006220a4202520d0010ca02220841ff01714102470d0210ca02220841ff01714102470d0510ca021a10ca02220841ff01714102470d06200420093703980320044198036a200210cb02220841ff01714102470d0710ca02220841ff01714102460d0120084180feff077141087621020c0b0b200441c00b6a41186a200441a0066a41186a290300370300200441c00b6a41106a200441a0066a41106a290300370300200441c00b6a41086a200441a0066a41086a290300370300200420042903a0063703c00b024020042802f006410f470d004100210841870421020c0d0b200441e0066a290300210b200441d8066a290300210c200441e8066a280200210620042903c806210d024010ca02220841ff01714102470d0010ca021a4200210e20044198036a41186a420037030020044198036a41106a220f420037030020044198036a41086a22084200370300200442003703980341e4dec400ad4280808080e00084100c220729000021102008200741086a29000037030020042010370398032007102341f3dec400ad4280808080e00084100c22072900002110200441a00a6a41086a2211200741086a290000370300200420103703a00a20071023200f20042903a00a2210370300200441f80a6a41086a2008290300370300200441f80a6a41106a2010370300200441f80a6a41186a201129030037030020042004290398033703f80a200441086a200441f80a6a412010cd010240200a4201520d00200d500d090b200441f80a6a200441c00b6a10970220044198036a20042802f80a220720042802800b109802024002402004290398034201510d00410021084200210a4200210d42002110420021124200211342002114420021154100210f0c010b200441a8036a2903002115200441b8036a2903002113200441b0036a2903002112200441c8036a2903002110200441c0036a290300210d200441d8036a290300210a200441d0036a290300210e200441e0036a280200210820042903a003211420042802e403210f0b024020042802fc0a450d00200710230b0240024020082006470d0020044198036a200441c00b6a10970220043502a00321162004280298032107410410212208450d0b2008200641016a36000020084104410810252208450d0b2008200f3a000420084108411510252208450d0b200820143700052008410d6a201537000020084115412a10252208450d0b200820123700152008411d6a20133700002008412a41d40010252208450d0b2008200e3700352008200d3700252008413d6a200a3700002008412d6a201037000020164220862007ad842008ad4280808080d00884100e200810230240200428029c03450d00200710230b024020094280808080f01f83428080808020520d0041002108410921020c100b200420093703980320044198036a200210cb02220841ff01714102460d0120084180feff077141087621020c0f0b41034102200820064b1b2102410021080c0e0b200420093703f80a20044198036a200c200b200441c00b6a200441f80a6a200210cc02024020042d0098034101460d00200441c4036a280200210f200441c0036a2802002106200441bc036a2802002111200441b4036a2802002107200441b0036a28020021170240200441b8036a2802002202450d002002410c6c21082017210203400240200241046a280200450d00200228020010230b2002410c6a2102200841746a22080d000b0b02402007450d002007410c6c450d00201710230b0240200f450d00200f410c6c21082011210203400240200241046a280200450d00200228020010230b2002410c6a2102200841746a22080d000b0b2006450d0d2006410c6c450d0d201110230c0d0b20042d00990322084102460d0c20042f019a0321020c0d0b20084180feff077141087621020c0c0b4100210f20042802f006410b470d0e20044198036a200441f4066a10ab0220042d0098034101460d01200441c4036a2802002111200441c0036a2802002106200441bc036a2802002117200441b4036a2802002107200441b0036a28020021180240200441b8036a2802002202450d002002410c6c21082018210203400240200241046a280200450d00200228020010230b2002410c6a2102200841746a22080d000b0b02402007450d002007410c6c450d00201810230b02402011450d002011410c6c21082017210203400240200241046a280200450d00200228020010230b2002410c6a2102200841746a22080d000b0b2006450d0e2006410c6c450d0e201710230c0e0b20084180feff077141087621020c080b20042d00990322024102470d060c0c0b200020042f0099033b0001200041013a0000200041036a20042d009b033a000020032802002101410021000c0d0b20084180feff077141087621020c050b20084180feff077141087621020c040b20084180feff077141087621020c030b4180b4c0004119419cb4c000102d000b102a000b20042f019a0341087420027221020c030b2002410874200841ff01717221020c020b20044198036a200441a0066a41d0006a220610cd020240024020042d0098034101460d00200441c4036a2802002111200441c0036a2802002107200441bc036a2802002117200441b4036a280200210f200441b0036a28020021180240200441b8036a2802002202450d002002410c6c21082018210203400240200241046a280200450d00200228020010230b2002410c6a2102200841746a22080d000b0b0240200f450d00200f410c6c450d00201810230b02402011450d002011410c6c21082017210203400240200241046a280200450d00200228020010230b2002410c6a2102200841746a22080d000b0b2007450d012007410c6c450d01201710230c010b20042d00990322084102460d0020042f019a0321020c010b20044198036a200610ce02024020042d0098034101460d00200441c4036a280200210f200441c0036a2802002106200441bc036a2802002111200441b4036a2802002107200441b0036a28020021170240200441b8036a2802002202450d002002410c6c21082017210203400240200241046a280200450d00200228020010230b2002410c6a2102200841746a22080d000b0b02402007450d002007410c6c450d00201710230b0240200f450d00200f410c6c21082011210203400240200241046a280200450d00200228020010230b2002410c6a2102200841746a22080d000b0b2006450d032006410c6c450d03201110230c030b20042d00990322084102460d0220042f019a0321020b2002410874200841ff01717221020b200441f0066a10b4020c020b200441a00b6a41186a200441c00b6a41186a290300370300200441a00b6a41106a200441c00b6a41106a290300370300200441a00b6a41086a200441c00b6a41086a290300370300200420042903c00b3703a00b4101210f0b200441a00a6a41186a2207200441a00b6a41186a2202290300370300200441a00a6a41106a2211200441a00b6a41106a2208290300370300200441a00a6a41086a2217200441a00b6a41086a2206290300370300200420042903a00b3703a00a20044198036a200441f0066a41b00210a1051a200441c00b6a41186a22182007290300370300200441c00b6a41106a22192011290300370300200441c00b6a41086a22112017290300370300200420042903a00a3703c00b410221070240200f450d00200220182903003703002008201929030037030020062011290300370300200420042903c00b3703a00b410121070b200441820b6a20062903003701002004418a0b6a2008290300370100200441920b6a2002290300370100200420073a00f90a200420042903a00b3701fa0a200441003a00f80a200441e00a6a20044198036a200441f80a6a10cf020240024020042802e00a4101470d00200420042900ed0a3703d00a2004200441f40a6a2800003600d70a20042802e40a4102470d010b410421020c030b200441ec0a6a2d00002102200420042800d70a3600c70a200420042903d00a3703c00a20094280808080f01f83428080808020520d02200241ff01714104460d0241801021020b200420042900900a3703800a2004200441970a6a2800003600870a200041036a20024110763a0000200020023b0001200041013a000020054521000b20000d012001450d01200341046a280200450d01200110230c010b200420042800c70a3600970a200420042903c00a3703900a200420042800970a3600870a200420042903900a3703800a200441f0096a41086a220620042800870a360000200420042903800a3700f109200420023a00f0092009210a410021070240200241ff01714104460d00200441f0096a109201200628020021084101210720042903f009210a0b200441b4066a2009370200200441a0066a41106a2008360200200441a0066a41086a200a370300200441bc066a200429029803370200200441c4066a20044198036a41086a2202280200360200200420073a00a406200420042f00f80a3b00a506200441003a00a0062004200441fa0a6a2d00003a00a706200441a0066a10e001200441d7ddc400411010cd012004200428020441016a410120042802001b22083602a00641d7ddc400ad4280808080800284200441a0066aad4280808080c00084100e200420083602c40b200441003602c00b20044198036a41186a420037030020044198036a41106a2207420037030020024200370300200442003703980341e4dec400ad4280808080e00084100c220829000021092002200841086a29000037030020042009370398032008102341d483c500ad4280808080e00184100c22082900002109200441a00a6a41086a220f200841086a290000370300200420093703a00a20081023200720042903a00a2209370300200441f80a6a41086a2002290300370300200441f80a6a41106a2009370300200441f80a6a41186a200f29030037030020042004290398033703f80a200441203602a4062004200441f80a6a3602a006200441c00b6a200441a0066a10c4022000410c6a2006280200360200200041046a20042903f009370200200041003a00002001450d002005450d00200341046a280200450d00200110230b200441e00b6a24000bc02205017f037e047f017e057f230041900f6b2202240042022103024002400240024002400240024002400240200129036822044202520d00200241b8076a20014198016a41b00210a1051a0c010b2002411e6a200141206a41c20010a1051a200241e0006a41186a200141186a290000370300200241e0006a41106a200141106a290000370300200241e0006a41086a200141086a29000037030020022001290000370360200241f0096a20014198016a41b00210a1051a200241a00c6a41086a20014188016a290300370300200241a00c6a41106a20014190016a290300370300200220014180016a2903003703a00c200141f8006a29030021032001290370210541002106200241f80d6a410010d403200241d80e6a20022802f80d220120022802800e10e101200241b80e6a41086a2207200241e40e6a290200370300200241b80e6a41106a2208200241ec0e6a290200370300200241b80e6a41156a2209200241f10e6a290000370000200220022902dc0e3703b80e0240024020022d00d80e4101460d00200241980e6a41156a4200370000200241980e6a41106a4200370300200241980e6a41086a4200370300200242003703980e0c010b20022f00d90e20022d00db0e411074722106200241980e6a41156a2009290000370000200241980e6a41106a2008290300370300200241980e6a41086a2007290300370300200220022903b80e3703980e0b024020022802fc0d450d00200110230b200241b80d6a41086a200241980e6a41086a2201290300370300200241b80d6a41106a200241980e6a41106a290300370300200241b80d6a41156a200241980e6a41156a290000370000200220022903980e3703b80d200241b80e6a41186a4200370300200241b80e6a41106a22094200370300200241b80e6a41086a22074200370300200242003703b80e41e4dec400ad4280808080e00084100c2208290000210a2007200841086a2900003703002002200a3703b80e2008102341f3dec400ad4280808080e00084100c2208290000210a2001200841086a2900003703002002200a3703980e20081023200920022903980e220a370300200241d80e6a41086a2007290300370300200241d80e6a41106a200a370300200241d80e6a41186a2001290300370300200220022903b80e3703d80e200241106a200241d80e6a412010cd0141002101024020044201520d0020054200510d042002280214410020022802101b2107417f21012007ad220a20032003200a541b220a200a20037d2005827d220a42ffffffff0f560d00200aa721010b200241d80e6a200110d403200241086a20022802d80e220820022802e00e419ca8c70041004100108c0120022802082107024020022802dc0e450d00200810230b20074101470d01200241800f6a200110d403200241d80e6a20022802800f220720022802880f10e101200241b80e6a41086a200241e10e6a290000370300200241b80e6a41106a200241e90e6a290000370300200241d00e6a2201200241f10e6a290000370300200220022900d90e3703b80e0240024020022d00d80e4101460d00200241ad0e6a4200370000200241980e6a41106a4200370300200241980e6a41086a4200370300200242003703980e410021010c010b200241980e6a41086a200241c30e6a290000370300200241980e6a41106a200241cb0e6a290000370300200241ad0e6a2001290000370000200220022900bb0e3703980e20022f01b80e20022d00ba0e4110747221010b024020022802840f450d00200710230b200241f80d6a41156a2207200241980e6a41156a290000370000200241f80d6a41106a2208200241980e6a41106a290300370300200241d80d6a41086a2209200241980e6a41086a290300370300200241d80d6a41106a220b2008290300370300200241d80d6a41156a22082007290000370000200241980d6a41086a2207200241b80d6a41086a290300370300200241980d6a41106a220c200241b80d6a41106a290300370300200241980d6a41156a220d200241b80d6a41156a290000370000200220022903980e3703d80d200220022903b80d3703980d200241f80c6a41156a220e2008290000370000200241f80c6a41106a2208200b290300370300200241f80c6a41086a220b2009290300370300200220022903d80d3703f80c200241d80c6a41156a2209200d290000370000200241d80c6a41106a220d200c290300370300200241d80c6a41086a220c2007290300370300200220022903980d3703d80c200241b80c6a41156a2207200e290000370000200241b80c6a41106a220e2008290300370300200241b80c6a41086a2208200b290300370300200220022903f80c3703b80c200241c8046a41156a220b2009290000370000200241c8046a41106a2209200d290300370300200241c8046a41086a220d200c290300370300200220022903d80c3703c804200241a8046a41156a220c2007290000370000200241a8046a41106a2207200e290300370300200241a8046a41086a220e2008290300370300200220022903b80c3703a804200241e8046a41106a2208200241a00c6a41106a290300370300200241e8046a41086a220f200241a00c6a41086a290300370300200220022903a00c3703e804200241b8076a41046a200241f0096a41b00210a1051a20024180056a200241b8076a41b40210a1051a20024180016a20024180056a41046a41b00210a1051a200241e6036a20064110763a0000200241e4036a20063b0100200241c0036a2003370300200241b8036a2005370300200241c8036a220620022903e804370300200241d0036a200f290300370300200241d8036a220f2008290300370300200241e7036a20022903c804370000200241ef036a200d290300370000200241f7036a2009290300370000200241fc036a200b290000370000200220043703b003200241013602e00320024186046a20014110763a000020024184046a20013b010020024187046a20022903a8043700002002418f046a200e29030037000020024197046a20072903003700002002419c046a200c290000370000410410212201450d04200242043702bc07200220013602b80720024180016a200241b8076a10dd020240024020022903b0034201520d0020022903c00320022903b8032203420c882204420120044201561b8021040240024020022802bc07220820022802c00722016b4102490d0020022802b80721070c010b200141026a22072001490d08200841017422092007200920074b1b22094100480d080240024020080d00024020090d00410121070c020b2009102122070d010c0c0b20022802b807210720082009460d0020072008200910252207450d0b20022802c00721010b200220093602bc07200220073602b8070b200720016a2004a741047420037aa7417f6a22074101200741014b1b2207410f2007410f491b723b0000200141026a21010c010b0240024020022802bc0720022802c0072201460d0020022802b80721070c010b200141016a22072001490d07200141017422082007200820074b1b22084100480d070240024020010d0041002101024020080d00410121070c020b200810212207450d0b0c010b20022802b807210720012008460d0020072001200810252207450d0a20022802c00721010b200220083602bc07200220073602b8070b200720016a41003a0000200141016a21010b200220013602c007200f200241b8076a10ed01200220063602800520024180056a200241b8076a10db0120022802e00321060240024020022802bc07220820022802c00722016b4104490d0020022802b80721070c010b200141046a22072001490d06200841017422092007200920074b1b22094100480d060240024020080d00024020090d00410121070c020b200910212207450d0a0c010b20022802b807210720082009460d0020072008200910252207450d0920022802c00721010b200220093602bc07200220073602b8070b200720016a20063600002002200141046a3602c007412010212201450d042001200241e4036a290200370000200141186a200241fc036a290200370000200141106a200241f4036a290200370000200141086a200241ec036a2902003700000240024020022802bc07220620022802c00722076b4120490d0020022802b80721080c010b200741206a22082007490d06200641017422092008200920084b1b22094100480d060240024020060d00024020090d00410121080c020b200910212208450d0a0c010b20022802b807210820062009460d0020082006200910252208450d0920022802c00721070b200220093602bc07200220083602b8070b200820076a22082001290000370000200841186a200141186a290000370000200841106a200141106a290000370000200841086a200141086a2900003700002002200741206a3602c00720011023412010212201450d04200120024184046a290200370000200141186a2002419c046a290200370000200141106a20024194046a290200370000200141086a2002418c046a2902003700000240024020022802bc07220620022802c00722076b4120490d0020022802b80721080c010b200741206a22082007490d06200641017422092008200920084b1b22094100480d060240024020060d00024020090d00410121080c020b200910212208450d0a0c010b20022802b807210820062009460d0020082006200910252208450d0920022802c00721070b200220093602bc07200220083602b8070b200820076a22082001290000370000200841186a200141186a290000370000200841106a200141106a290000370000200841086a200141086a2900003700002002200741206a3602c0072001102320022802bc07210820022802b80721010240024020022802c00722074180024b0d002002411e6a20012007200241e0006a10d50321070c010b2007ad4220862001ad84101822072900002103200741086a2900002104200741106a2900002105200241b80e6a41186a200741186a290000370300200241b80e6a41106a2005370300200241b80e6a41086a2004370300200220033703b80e200710232002411e6a200241b80e6a4120200241e0006a10d50321070b02402008450d00200110230b2007450d02200241f0096a41086a200241e0006a41086a290300370300200241f0096a41106a200241e0006a41106a290300370300200241f0096a41186a200241e0006a41186a29030037030020024180056a41086a200241c0036a29030037030020024180056a41106a200241c8036a29030037030020024180056a41186a200241d0036a290300370300200241a0056a200241d8036a290300370300200220022903603703f0092002200241b8036a2903003703800520022903b0032103200241b8076a20024180016a41b00210a1051a0b200041086a20022903f009370300200041286a2003370300200041306a200229038005370300200041206a200241f0096a41186a290300370300200041186a200241f0096a41106a290300370300200041106a200241f0096a41086a290300370300200041386a20024180056a41086a290300370300200041c0006a20024180056a41106a290300370300200041c8006a20024180056a41186a290300370300200041d0006a20024180056a41206a290300370300200041d8006a200241b8076a41b00210a1051a200041003a00000c050b200241d80d6a41156a200241f80d6a41156a290000370000200241d80c6a41086a200241980d6a41086a290000370300200241d80c6a41106a200241980d6a41106a290000370300200241d80c6a41156a200241980d6a41156a290000370000200241b80c6a41156a200241f80c6a41156a290000370000200220022900980d3703d80c200241f0096a10b402200041036a41003a0000200041800a3b0001200041013a00000c040b20004180083b0001200041013a0000200041036a41003a000020024180016a10b4020c030b4180b4c0004119419cb4c000102d000b1033000b102c000b200241900f6a24000f0b102a000bf90403027f017e057f230041d0006b2202240041e4dec400ad4280808080e00084100c22032900002104200241086a200341086a290000370300200220043703002003102341c480c500ad4280808080d00184100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bad0201057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410212205450d020b2003410036020820032004360204200320053602002001200310610240024020032802042206200328020822056b2001490d0020032802002104200621070c010b200520016a22042005490d03200641017422072004200720044b1b22074100480d030240024020060d00024020070d00410121040c020b2007102122040d010c060b2003280200210420062007460d0020042006200710252204450d050b20032007360204200320043602000b200420056a2000200110a1051a2002290200200520016aad4220862004ad84100e02402007450d00200410230b200341106a24000f0b1032000b1033000b102c000b102a000baa1101057f230041206b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e16011112020304051106070809110a0b0c0d0e0f101100010b410021034190ce0021040240024002400240024020012d00040e0400010402000b2002411c6a41013602002002420137020c200241a4c5c60036020820024104360204200241cccec60036020020022002360218200241086a419ca8c700103a000b200241086a200141086a280200220110c90220022802082103200241086a200110c90220034190ce006a21040c010b200241086a200141286a280200220110c90220022802082103200241086a200110c90220034190ce006a21040b20022d000c21030b200041013a0005200020033a0004200020043602000c120b410021034190ce00210402400240024002400240024002400240200141086a2802000e0b0001070203030405050506000b2002411c6a41013602002002420137020c200241a4c5c60036020820024104360204200241cccec60036020020022002360218200241086a419ca8c700103a000b2001410c6a28020021040b410121030c040b4101210341c09a0c21040c030b4101210341a09c0121040c020b410121030c010b4101210341a8c30121040b200041013a0005200020033a0004200020043602000c110b20004180023b010420004190ce003602000c100b4100210341c0843d2104024002400240200141086a2d00000e050002010202000b2002411c6a41013602002002420137020c200241a4c5c60036020820024104360204200241cccec60036020020022002360218200241086a419ca8c700103a000b4101210341d0860321040b200041013a0005200020033a0004200020043602000c0f0b20004182023b010420004190ce003602000c0e0b4100210441a0c21e210302400240024002400240024002400240024002400240200141086a2d00000e19000a0a010102020a0a02030303030405060a0a0a0a07080909000b2002411c6a41013602002002420137020c200241a4c5c60036020820024104360204200241cccec60036020020022002360218200241086a419ca8c700103a000b4180b51821030c080b41b0e32d21030c070b41882721030c060b4190ce0021030c050b41882721030c040b41c0843d21030c030b410121040c020b4190ce0021030c010b4180c2d72f21030b200041013a0005200020043a0004200020033602000c0d0b20004180023b0104200041f093093602000c0c0b20004182023b010420004190ce003602000c0b0b20004180023b010420004190ce003602000c0a0b20004180023b010420004190ce003602000c090b02400240024020012802040e03000102000b2002411c6a41013602002002420137020c200241a4c5c60036020820024104360204200241cccec60036020020022002360218200241086a419ca8c700103a000b20004182023b0104200041c0843d3602000c090b20004180023b0104200041003602000c080b20004182023b010420004190ce003602000c070b41c096b102210341012104024002400240024020012d00040e080003010202020202000b2002411c6a41013602002002420137020c200241a4c5c60036020820024104360204200241cccec60036020020022002360218200241086a419ca8c700103a000b4190ce002103410121040c010b410021044190ce0021030b200041013a0005200020043a0004200020033602000c060b0240024002400240024002400240024020012d00040e06000102030405000b2002411c6a41013602002002420137020c200241a4c5c60036020820024104360204200241cccec60036020020022002360218200241086a419ca8c700103a000b200141086a28020021044190ce0021030240200141106a280200220541b0026c2206450d00200421010340200241086a200110c902200141b0026a2101200228020820036a2103200641d07d6a22060d000b0b200541b0026c21014101210603402001450d06200141d07d6a2101200241086a200410c902200441b0026a210420022d000c4101460d000c050b0b200241086a200141086a280200220110c90220022802082103200241086a200110c90220034190ce006a210320022d000c21060c040b200241086a200141206a280200220310c902200141106a280200210120022802082104200241086a200310c902200420014190ce006c6a4190ce006a210320022d000c21060c030b200141306a2802004190ce006c4190ce006a21030c010b200141306a2802004190ce006c4190ce006a21030b410021060b200041013a0005200020063a0004200020033602000c050b4190ce0021030240024002400240200141086a2d00000e0c000301010101010101010102000b2002411c6a41013602002002420137020c200241a4c5c60036020820024104360204200241cccec60036020020022002360218200241086a419ca8c700103a000b41d0860321030c010b41a08d0621030b20004180023b0104200020033602000c040b410021044190ce0021030240024002400240024020012d00040e0a00010402020202030304000b2002411c6a41013602002002420137020c200241a4c5c60036020820024104360204200241cccec60036020020022002360218200241086a419ca8c700103a000b200241086a200141286a280200220110c90220022802082103200241086a200110c90220034190ce006a210320022d000c21040c020b41a08d0621030c010b41b0ea0121030b200041013a0005200020043a0004200020033602000c030b4190ce0021030240200141086a2d00002201417f6a4102490d0002400240024020010e0400010102000b2002411c6a41013602002002420137020c200241a4c5c60036020820024104360204200241cccec60036020020022002360218200241086a419ca8c700103a0b000b41c0843d21030b20004180023b0104200020033602000c020b10f502000b20004182023b010420004190ce003602000b200241206a24000b040041020bda0607017f017e017f017e027f037e077f230041e0006b22022400200241306a20002902002203422088a72204200110c6040240024020022903302205a7220141ff01714101460d00200241306a41186a22064200370300200241306a41106a22074200370300200241306a41086a220042003703002002420037033041e4dec400ad4280808080e000842208100c220129000021092000200141086a290000370300200220093703302001102341e8ffc400ad4280808080b00284220a100c220b2900002109200241d0006a41086a2201200b41086a29000037030020022009370350200b1023200720022903502209370300200241106a41086a220c2000290300370300200241106a41106a220d2009370300200241106a41186a220e200129030037030020022002290330370310200241086a200241106a412010cd014100210b417f200228020c410020022802081b220f418094ebdc034180afd0e502200441ff017122041b22102003a7221120102011491b6a22112011200f491b210f024020044102460d0041800c2104200f20104b0d020b200642003703002007420037030020004200370300200242003703302008100c220b29000021032001200b41086a29000037030020022003370350200b10232000200129030037030020022002290350370330418c80c500ad4280808080800284100c220b29000021032001200b41086a29000037030020022003370350200b1023200720022903502203370300200c2000290300370300200d2003370300200e20012903003703002002200229033037031020022005422088a7360230200241106aad42808080808004842205200241306aad4280808080c000842203100e200642003703002007420037030020004200370300200242003703302008100c220b29000021082001200b41086a29000037030020022008370350200b10232000200129030037030020022002290350370330200a100c220b29000021082001200b41086a29000037030020022008370350200b1023200720022903502208370300200c2000290300370300200d2008370300200e2001290300370300200220022903303703102002200f36023020052003100e410021044102210b0c010b200141087641ff0171210b2005421088a741087421040b200241e0006a24002004200b720be90702017f057e230041e0016b22062400200641186a200520042902002207a72007422888a72001200210b6044200210702400240024020062903182208200641206a2903002209844200520d0020064198016a420037030020064190016a4280808080c000370300200642043703880120064200370378200641013a00a0012006427f37038001200641f8006a21030c010b200641003a004320062009370338200620083703302006200336022c410121052006410141112001200284501b3a0042200620033602442006200641c4006a360288012006200641c2006a3602840120062006412c6a360280012006200641c3006a36027c2006200641306a360278200641c8006a2003200641f8006a10c5030240024020062802484101470d004200210a200629035021070c010b200641f0006a290300210a200641e8006a2903002107024020062903504201510d00410021050c010b200641c8006a41106a290300210b20062802442103200641b0016a200641c8006a41186a290300370300200641a8016a200b37030041002105200641f8006a41086a41003a000020064181016a200329000037000020064189016a200341086a29000037000020064191016a200341106a29000037000020064199016a200341186a290000370000200641023a0078200641f8006a10e0010b02402005450d0020004180023b0001200041013a0000200041036a41003a00000c020b2006427f200720072007200120072007200156200a200256200a2002511b22031b22017d542205200a2002200a20031b220b7d2007200154ad7d2202200b7c2005ad7c220120025420012002511b22031b427f200120031b10cf0302402006290300a7450d00200641106a290300210220062903082101200641c8006a108503200641f8006a108503200641f8006a2001200210ea01200641b0016a2002370300200641a8016a2001370300200641f8006a41086a41043a000020064181016a200629034837000020064189016a200641c8006a41086a29030037000020064191016a200641c8006a41106a29030037000020064199016a200641e0006a290300370000200641023a0078200641f8006a10e0010b20064198016a420037030020064190016a4280808080c000370300200642043703880120064200370378200641013a00a0012006427f370380012008427f2009501b2107200641f8006a21030b200041003a000020062007370378200041086a2003290300370300200041106a200341086a290300370300200041186a200341106a290300370300200041206a200341186a290300370300200041286a200341206a290300370300200041306a200341286a2903003703000b200641e0016a24000bbf1705067f017e0a7f027e017f23004190016b22022400410421030240024002400240024002400240024002400240024002402001280200410f460d00410021040c010b41002104200141046a22052d00004105470d00200241e0006a200141c8006a280200108d03200228026022032002280268108e0341ff0171210402402002280264450d00200310230b0240024002400240024002400240024020044102460d002004410171450d00200241e0006a41186a4200370300200241e0006a41106a22064200370300200241e0006a41086a22034200370300200242003703604196adc300ad4280808080900184100c2207290000210820024180016a41086a2204200741086a29000037030020022008370380012007102320032004290300370300200220022903800137036041fcdfc300ad4280808080f00184100c220729000021082004200741086a29000037030020022008370380012007102320062002290380012208370300200241c0006a41086a2003290300370300200241c0006a41106a2008370300200241c0006a41186a200429030037030020022002290360370340200241206a200241c0006a108f030240200228022022090d0020024100360218200242043703100c030b2002290224210820022009360210200220083702142008422088a7220a450d01200a417f6a210b0c040b200041800e3b0001200041013a0000200041036a41013a00000c110b2008a7450d0041002104200a210b0c010b200241106a41004101109501200228021021092002280218220b21040b20092004410c6c6a22044100360208200442043702002002200b41016a220a360218200a200b490d010b200241e0006a41186a220c4200370300200241e0006a41106a220d4200370300200241e0006a41086a22034200370300200242003703604196adc300ad4280808080900184100c2207290000210820024180016a41086a2204200741086a29000037030020022008370380012007102320032004290300370300200220022903800137036041d8dfc300ad4280808080b00184100c220729000021082004200741086a2900003703002002200837038001200710232006200229038001370000200641086a2004290300370000200241c0006a41086a2003290300370300200241c0006a41106a200d290300370300200241c0006a41186a200c29030037030020022002290360370340200241086a200241c0006a412010cd01024002402009200b410c6c6a220e41086a220f2802002204200228020c410020022802081b4f0d00200e28020021100240200441014b0d00024020040e020300030b2001280248210d410021030c040b2001280248210d41002103034020032004410176220720036a220c200d2010200c41246c6a280200491b2103200420076b220441014b0d000c040b0b200041800c3b0001200041013a0000200041036a41003a00000c0d0b2001280248210d410021030c020b200b410041d8afc3001030000b200d2010200341246c6a2802002204460d032003200d20044b6a21030b200241e0006a200d10c30320022802602211450d0320022802642112200241e0006a41086a22073502004220862011ad84101822042900002108200441086a2900002113200441106a2900002114200241206a41186a200441186a290000370300200241206a41106a2014370300200241206a41086a201337030020022008370320200410230240200241206a200541216a2215460d00200241206a2015412010a3050d020b200241e0006a41186a200541196a290000370300200241e0006a41106a200541116a2900003703002007200541096a29000037030020022005290001370360200f28020022042003490d0420012802482107024020042009200b410c6c6a41046a280200470d00200e2004410110a2012002280218210a200228021021090b200e280200200341246c6a220141246a2001200420036b41246c10a2051a20012007360200200120022903603702042001410c6a200241e0006a41086a2203290300370200200141146a200241e0006a41106a22072903003702002001411c6a200241e0006a41186a220c2903003702004101210d200f200441016a3602002002280214210e200c42003703002007420037030020034200370300200242003703604196adc300ad4280808080900184100c2204290000210820024180016a41086a2201200441086a29000037030020022008370380012004102320032001290300370300200220022903800137036041fcdfc300ad4280808080f00184100c220429000021082001200441086a2900003703002002200837038001200410232006200229038001370000200641086a2001290300370000200241c0006a41086a2003290300370300200241c0006a41106a2007290300370300200241c0006a41186a200c29030037030020022002290360370340200a410c6c41046a2201417f4c0d0502402001450d0020011021220d450d070b20024100360268200220013602642002200d360260200a200241e0006a10610240200a450d002009200a410c6c6a210b2009210603402006280200210120062802082204200241e0006a106102402004450d002001200441246c6a21054100200228026822046b210d20022802642103034020012802002110024002402003200d6a4104490d002002280260210c200321070c010b200441046a22072004490d0c2003410174220c2007200c20074b1b22074100480d0c0240024020030d00024020070d004101210c0c020b20071021220c0d010c0f0b2002280260210c20032007460d00200c200320071025220c450d0e0b200220073602642002200c3602600b200c20046a20103600002002200441046a2203360268024002402007200d6a417c6a411f4d0d00200721030c010b200341206a22102003490d0c200741017422032010200320104b1b22034100480d0c0240024020070d00024020030d004101210c0c020b20031021220c450d0f0c010b20072003460d00200c200720031025220c450d0e0b200220033602642002200c3602600b200c20046a220741046a200141046a2900003700002007411c6a2001411c6a290000370000200741146a200141146a2900003700002007410c6a2001410c6a2900003700002002200441246a2204360268200d415c6a210d200141246a22012005470d000b0b2006410c6a2206200b470d000b0b20022802642101200241c0006aad4280808080800484200235026842208620022802602204ad84100e02402001450d00200410230b0240200a450d00200a410c6c21042009210103400240200141046a2802002203450d00200341246c450d00200128020010230b2001410c6a2101200441746a22040d000b0b0240200e450d00200e410c6c450d00200910230b410c10212203450d08412010212201450d0620012015290000370000200141186a2207201541186a290000370000200141106a220c201541106a290000370000200141086a220d201541086a290000370000412010212204450d0820042001290000370000200441186a2007290000370000200441106a200c290000370000200441086a200d29000037000020011023200342a080808080043702042003200436020002402012450d00201110230b410121040b200041003a0000200041306a41013a00002000412c6a2004360200200041286a2004360200200041246a2003360200200041206a4100360200200041186a4204370300200041106a427f370300200041086a4200370300200041316a2002280060360000200041346a200241e3006a2800003600000c090b20004180063b0001200041013a0000200041036a41003a00002012450d07201110230c070b200041800e3b0001200041013a0000200041036a41003a00000c060b200041800e3b0001200041013a0000200041036a41013a00000c050b200320041038000b1032000b1033000b102c000b102a000b0240200a450d00200a410c6c21042009210103400240200141046a2802002203450d00200341246c450d00200128020010230b2001410c6a2101200441746a22040d000b0b20022802142201450d002001410c6c450d00200910230b20024190016a24000be21304057f017e077f017e230041f0026b2202240002400240024002400240024002402001280200410d470d0020012802044102470d00200241f0006a41186a22034200370300200241f0006a41106a22044200370300200241f0006a41086a220542003703002002420037037041db97c700ad4280808080f00084100c220629000021072005200641086a290000370300200220073703702006102341bbacc300ad4280808080a00184100c22062900002107200241d8016a41086a2208200641086a290000370300200220073703d80120061023200420022903d8012207370300200241086a41086a22092005290300370300200241086a41106a220a2007370300200241086a41186a220b200829030037030020022002290370370308200241f0006a200241086a412010890220022902744200200228027022061b21072006410120061b210c02400240200141086a220d280200200141186a220e280200470d002003420037030020044200370300200542003703002002420037037041b0dfc300ad4280808080a00184100c2206290000210f2005200641086a2900003703002002200f3703702006102341bcbac500ad4280808080b00184100c2206290000210f2008200641086a2900003703002002200f3703d80120061023200420022903d801220f37030020092005290300370300200a200f370300200b200829030037030020022002290370370308200241f0006a200241086a10ad0220022802702205410120051b210a41800e21092002290274420020051b220f422088a72205450d062001413c6a21042005410574210841002106200a2105034020042005460d02200620052004412010a30522034100476a21062003450d02200541206a2105200841606a22080d000c070b0b20004180083b0001200041013a0000200041036a41003a00000c060b20062007422088a722054f0d01200241086a41186a200c20064105746a220541186a290000370300200241086a41106a200541106a290000370300200241086a41086a200541086a29000037030020022005290000370308200241f0006a200241086a108f020240024002402002280290012205450d0002402002280294012206450d00200641306c450d00200510230b0240024002400240200141dc006a2d00000e03010200010b20024188016a200d41ed006a29000037030020024180016a200d41e5006a290000370300200241f8006a200d41dd006a2900003703002002200d41d5006a29000037037041022106200241f0006a21050c020b20024188016a200d41ed006a29000037030020024180016a200d41e5006a290000370300200241f8006a200d41dd006a2900003703002002200d41d5006a29000037037041002106200241f0006a21050c010b20024188016a200d41ed006a29000037030020024180016a200d41e5006a290000370300200241f8006a200d41dd006a2900003703002002200d41d5006a29000037037041012106200241f0006a21050b200241216a200541186a290000370000200241196a200541106a290000370000200241116a200541086a290000370000200220063a000820022005290000370009200241316a200d41fd006a290000370000200241396a200d4185016a290000370000200241c1006a200d418d016a290000370000200241c9006a200d4195016a290000370000200241d1006a200d419d016a290000370000200241d9006a200d41a5016a290000370000200241e1006a200d41ad016a2900003700002002200d41f5006a2900003700290240024002400240200d2d00b5010e03010200010b200241d8016a41186a200d41ce016a290000370300200241d8016a41106a200d41c6016a290000370300200241d8016a41086a200d41be016a2900003703002002200d41b6016a2900003703d80141022106200241d8016a21050c020b200241d8016a41186a200d41ce016a290000370300200241d8016a41106a200d41c6016a290000370300200241d8016a41086a200d41be016a2900003703002002200d41b6016a2900003703d80141002106200241d8016a21050c010b200241d8016a41186a200d41ce016a290000370300200241d8016a41106a200d41c6016a290000370300200241d8016a41086a200d41be016a2900003703002002200d41b6016a2900003703d801200241d8016a2105410121060b20024189016a200541186a29000037000020024181016a200541106a290000370000200241f9006a200541086a290000370000200220063a00702002200529000037007120024199016a200d41de016a290000370000200241a1016a200d41e6016a290000370000200241a9016a200d41ee016a290000370000200241b1016a200d41f6016a290000370000200241b9016a200d41fe016a290000370000200241c1016a200d4186026a290000370000200241c9016a200d418e026a2900003700002002200d41d6016a29000037009101200241a8026a410c6a200441086a290200370200200241bc026a200441106a290200370200200241c4026a200441186a290200370200200241f0c2c98b063602a802200220042902003702ac0220012802082105200241e0026a2001410c6a10cd03200241d0026a410c6a200241e0026a41086a280200360200200220053602d002200220022903e0023702d402200241d8016a200241a8026a200241d0026a10b4032002280298022205450d050240200228029c022201450d00200141306c450d00200510230b41042105200d280200200e280200470d06200241086a200e200410ce0341ff017122054106470d06200241f0006a200e200410ce0341ff017122054106470d064103210520022d0008220141024b0d06200241086a4101722104200241f0006a41017221060240024002400240024002400240024020010e03000102000b20022d0070417f6a220141014b0d0d20010e020802080b20022d0070220141024b0d0c20010e03020c04020b20022d0070220141014b0d0b20010e020204020b20042006412010a3050d0a0c060b20062004412010a3050d090c050b20062004412010a3050d080c040b20042006412010a3050d070c030b20042006412010a305450d020c060b41808e0421090c060b20042006412010a3050d040b0240200f42ffffff3f83500d00200a10230b200742ffffff3f83500d00200c10230b200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a4200370300200041316a2002280070360000200041346a200241f3006a2800003600000c050b20062005419c90c3001030000b410521050b200541107441800e7221090b200020093b0001200041013a0000200041036a20094110763a0000200f42ffffff3f83500d00200a10230b200742ffffff3f83500d00200c10230b200241f0026a24000bdec70208027f017e127f017e117f077e037f087e230022032104200341800d6b41607122032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e16020103040506070108090a0b010c0d0e0f1011120100020b2002411a6a2901002105200241196a2d00002106200241186a2d00002107200241166a2f01002108200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f010021172001411d6a29000021182001411c6a2d00002119200141196a2f0000211a200141186a2d0000211b200141156a2f0000211c200141146a2d0000211d200141116a2f0000211e200141106a2d0000211f2001410d6a2f000021202001410c6a2d00002121200141086a2802002122200141056a2f0000212320022d0001212420022d0000210220012d001b212520012d0017212620012d0013212720012d000f212820012d00072129024002400240024020012d00040e0400010203000b200341c00a6a41146a4101360200200342013702c40a200341a4c5c6003602c00a2003410436028c09200341cccec60036028809200320034188096a3602d00a200341c00a6a419ca8c700103a000b0240024002400240200241ff01710d00202441ff01714101470d00200320053703d806200320063a00d706200320073a00d606200320083b01d406200320093a00d3062003200a3a00d2062003200b3b01d0062003200c3a00cf062003200d3a00ce062003200e3b01cc062003200f3a00cb06200320103a00ca06200320113b01c806200320123a00c706200320133a00c606200320143b01c406200320153a00c306200320163a00c206200320173b01c006200341e0036a41186a22064200370300200341e0036a41106a22014200370300200341e0036a41086a22024200370300200342003703e003418c97c300ad4280808080c00084100c222429000021052002202441086a290000370300200320053703e003202410234190f1c400ad42808080803084100c2224290000210520034190026a41086a2207202441086a2900003703002003200537039002202410232001200329039002220537030020034180056a41086a200229030037030020034180056a41106a200537030020034180056a41186a2007290300370300200320032903e00337038005200341c00a6a20034180056a412010e10120032d00c00a21242006200341d90a6a2900003703002001200341d10a6a2900003703002002200341c90a6a290000370300200320032900c10a3703e0030240024020244101460d0020034188096a41186a420037030020034188096a41106a420037030020034188096a41086a420037030020034200370388090c010b20034188096a41186a200629030037030020034188096a41106a200129030037030020034188096a41086a2002290300370300200320032903e003370388090b200341c0066a20034188096a412010a3050d18200341c00a6a202241b00210a1051a200341003b018809200341e8076a200341c00a6a20034188096a10cf024101210220032802e8074101470d03200341d00a6a200341fc076a280200360200200341c80a6a2202200341f4076a290200370300200320032902ec073703c00a2002109201419db3c500ad4280808080a00184100a4186a0c000ad4280808080e00184100a20032802c00a4101460d0141fc9fc000ad4280808080a00184100a0c020b202210b4022022102341823021030c4c0b20033502c40a100b0b410021020b200320023a00c20a2003410e3b01c00a200341c00a6a10e001202210232000410036020420004100360200200424000f0b02400240200241ff01710d00202441ff01714101470d00200320053703d806200320063a00d706200320073a00d606200320083b01d406200320093a00d3062003200a3a00d2062003200b3b01d0062003200c3a00cf062003200d3a00ce062003200e3b01cc062003200f3a00cb06200320103a00ca06200320113b01c806200320123a00c706200320133a00c606200320143b01c406200320153a00c306200320163a00c206200320173b01c006200341e0036a41186a22064200370300200341e0036a41106a22014200370300200341e0036a41086a22024200370300200342003703e003418c97c300ad4280808080c00084100c222429000021052002202441086a290000370300200320053703e003202410234190f1c400ad42808080803084100c2224290000210520034190026a41086a2207202441086a2900003703002003200537039002202410232001200329039002220537030020034180056a41086a200229030037030020034180056a41106a200537030020034180056a41186a2007290300370300200320032903e00337038005200341c00a6a20034180056a412010e10120032d00c00a21242006200341d90a6a2900003703002001200341d10a6a2900003703002002200341c90a6a290000370300200320032900c10a3703e0030240024020244101460d0020034188096a41186a420037030020034188096a41106a420037030020034188096a41086a420037030020034200370388090c010b20034188096a41186a200629030037030020034188096a41106a200129030037030020034188096a41086a2002290300370300200320032903e003370388090b0240200341c0066a20034188096a412010a305450d0041833021030c020b2003201837018008200320193a00ff07200320253a00fe072003201a3b01fc072003201b3a00fb07200320263a00fa072003201c3b01f8072003201d3a00f707200320273a00f6072003201e3b01f4072003201f3a00f307200320283a00f207200320203b01f007200320213a00ef07200320223600eb07200320293a00ea07200320233b01e80742002105200341e0036a41186a22224200370300200341e0036a41106a22244200370300200341e0036a41086a22024200370300200342003703e003418c97c300ad4280808080c000842218100c2206290000212a2002200641086a2900003703002003202a3703e003200610234190f1c400ad42808080803084222a100c2206290000212b20034190026a41086a2207200641086a2900003703002003202b37039002200610232001200329039002370000200141086a200729030037000020034180056a41086a200229030037030020034180056a41106a202429030037030020034180056a41186a2022290300370300200320032903e00337038005200341c00a6a20034180056a412010e10120032d00c00a21142022200341d90a6a22152900003703002024200341d10a6a22162900003703002002200341c90a6a2217290000370300200320032900c10a3703e00341002102410021014100212241002124410021064100210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f41002110410021114100211241002113024020144101470d0020032903f803210520032d00f703210220032d00f603210120032f01f403212220032d00f303212420032d00f203210620032f01f003210720032d00ef03210820032d00ee03210920032f01ec03210a20032d00eb03210b20032d00ea03210c20032f01e803210d20032d00e703210e20032d00e603210f20032f01e403211020032d00e303211120032d00e203211220032f01e00321130b200341da0a6a2005370100201520023a0000200341c00a6a41186a220220013a0000200341d60a6a20223b0100200341d50a6a20243a0000200341d40a6a20063a0000200341d20a6a20073b0100201620083a0000200341c00a6a41106a220120093a0000200341ce0a6a200a3b0100200341cd0a6a200b3a0000200341cc0a6a200c3a0000200341ca0a6a200d3b01002017200e3a0000200341c00a6a41086a2222200f3a0000200320103b01c60a200320113a00c50a200320123a00c40a200320133b01c20a2003418e023b01c00a200341c00a6a10e0012002200341e8076a41186a2901003703002001200341e8076a41106a2901003703002022200341e8076a41086a290100370300200320032901e8073703c00a2018100c220229000021052002290008211820021023202a100c2202290000212a2002290008212b200210232003202b3701b8052003202a3701b005200320183701a805200320053701a005412010212202450d3e200220032903c00a370000200241186a200341c00a6a41186a290300370000200241106a200341c00a6a41106a290300370000200241086a200341c00a6a41086a290300370000200341a0056aad42808080808004842002ad4280808080800484100e200210232000410036020420004100360200200424000f0b41823021030b20004100360204200041146a410b360200200041106a41a181c3003602002000410c6a200336020020004101360200200424000f0b200141286a280200210102400240024002400240200241ff01710d00202441ff01714101470d00200320053703d806200320063a00d706200320073a00d606200320083b01d406200320093a00d3062003200a3a00d2062003200b3b01d0062003200c3a00cf062003200d3a00ce062003200e3b01cc062003200f3a00cb06200320103a00ca06200320113b01c806200320123a00c706200320133a00c606200320143b01c406200320153a00c306200320163a00c206200320173b01c006200341e0036a41186a22074200370300200341e0036a41106a22244200370300200341e0036a41086a22024200370300200342003703e003418c97c300ad4280808080c00084100c220629000021052002200641086a290000370300200320053703e003200610234190f1c400ad42808080803084100c2206290000210520034190026a41086a2208200641086a2900003703002003200537039002200610232024200329039002220537030020034180056a41086a200229030037030020034180056a41106a200537030020034180056a41186a2008290300370300200320032903e00337038005200341c00a6a20034180056a412010e10120032d00c00a21062007200341d90a6a2900003703002024200341d10a6a2900003703002002200341c90a6a290000370300200320032900c10a3703e0030240024020064101460d0020034188096a41186a420037030020034188096a41106a420037030020034188096a41086a420037030020034200370388090c010b20034188096a41186a200729030037030020034188096a41106a202429030037030020034188096a41086a2002290300370300200320032903e003370388090b0240200341c0066a20034188096a412010a305450d00200110b4022001102341833021030c020b200320183701b805200320193a00b705200320253a00b6052003201a3b01b4052003201b3a00b305200320263a00b2052003201c3b01b0052003201d3a00af05200320273a00ae052003201e3b01ac052003201f3a00ab05200320283a00aa05200320203b01a805200320213a00a705200320224118763a00a605200320224108763b01a405200320223a00a305200320293a00a205200320233b01a005200341c00a6a200141b00210a1051a20034192096a20032901a8053701002003419a096a20032901b005370100200341a2096a20032901b80537010020034180023b018809200320032901a00537018a09200341e8076a200341c00a6a20034188096a10cf024101210220032802e8074101470d04200341d00a6a200341fc076a280200360200200341c80a6a2202200341f4076a290200370300200320032902ec073703c00a2002109201419db3c500ad4280808080a00184100a4186a0c000ad4280808080e00184100a20032802c00a4101460d0241fc9fc000ad4280808080a00184100a0c030b200110b4022001102341823021030b20004100360204200041146a410b360200200041106a41a181c3003602002000410c6a200336020020004101360200200424000f0b20033502c40a100b0b410021020b200320023a00c20a2003418e043b01c00a200341c00a6a10e001200110232000410036020420004100360200200424000f0b000b41022107200141106a29030021052001410c6a280200210620022d0001212420022d0000212202400240024002400240024002400240024002400240024002400240200141086a280200417f6a0e0a00010203040506070809000b41002103200041003602042024202241ff01714100477241ff0171450d512000410c6a41023602000c500b2005a721030240202241ff01710d00202441ff01714101470d002003450d09200610230c090b02402003450d00200610230b200041003602042000410c6a41023602000c4f0b02402024202241ff01714100477241ff01710d00410810212203450d452003200537000041aa9dc500ad4280808080a001842003ad4280808080800184100e200310230c080b200041003602042000410c6a41023602000c4e0b410021082005a721092024202241ff01714100477241ff01710d4c20034188096a2005428080808070832006ad8422051017108b012003280288092202450d4a200328028c092101200320034190096a2802003602ec07200320023602e807200341206a200341e8076a10880120032802200d4920032802ec07220720032802242222490d492022417f4c0d1b0240024020220d00410121240c010b202210272224450d44202420032802e8072208202210a1051a2003200720226b3602ec072003200820226a3602e8070b2024450d49200341186a200341e8076a1088012022ad22184220862018842218a7210720032802180d4720032802ec072208200328021c2222490d472022417f4c0d1b0240024020220d004101210a0c010b20221027220a450d44200a20032802e807220b202210a1051a2003200820226b22083602ec072003200b20226a3602e8070b200a450d472022ad222a422086202a84222aa7210b0240024002400240024020084104490d0020032802e807222228000021102003202241046a3602e80720032008417c6a220c3602ec07200c4104490d012003202241086a3602e807202228000421112003200841786a220c3602ec07200c4104490d032003200841746a3602ec0720032022410c6a3602e80720222800082112200341106a200341e8076a1088012003280210450d020c4b0b0240200b450d00200a10230b20070d4c0c4d0b0240200b450d00200a10230b20070d4b0c4c0b2003280214220820032802ec07410c6e2222202220084b1bad420c7e222b422088a70d1d202ba7220c417f4c0d1d02400240200c0d004104210d0c010b200c1021220d450d460b41002122200341003602c80a2003200d3602c00a2003200c410c6e3602c40a024002402008450d000340200341c0066a200341e8076a10f60220032d00c0064101460d0220032802ec07220c4104490d0220032900c106212b20032802e807220e280000210f2003200c417c6a3602ec072003200e41046a3602e8070240202220032802c40a470d00200341c00a6a2022410110950120032802c00a210d20032802c80a21220b200d2022410c6c6a220c200f360208200c202b3702002003202241016a22223602c80a2008417f6a22080d000b0b200d450d4920032902c40a212b2003200d36028c04200341013602880420032012360284042003201136028004200320103602fc032003202a422088a73602f8032003200b3602f4032003200a3602f003200341013602ec0320032018422088a7220c3602e803200320073602e403200320243602e0032003202b3703900402402001450d00200210230b202ba7210841c8ddc4002102410f210141002122200c4107470d482024419cc9c200460d022024419cc9c200410710a305450d020c480b20032802c40a2203450d482003410c6c450d48200d10230c480b0240200b450d00200a10230b2007450d4a0c490b0240201141024f0d0041aeddc4002102411a2101410121220c460b02402007450d00202410230b0240200b450d00200a10230b02402008450d002008410c6c450d00200d10230b41b49dc500ad4280808080d000842005100e41002102200341003a00c00a200341023a00c40a200341c00a6a10e0012009450d07200610232000410036020420004100360200200424000f0b2005a7210202402024202241ff01714100477241ff01710d0041b49dc500ad4280808080d000842005428080808070832006ad84100e200341003a00c00a200341023a00c40a200341c00a6a10e0012002450d06200610230c060b02402002450d00200610230b200041003602042000410c6a41023602000c4c0b2024202241ff01714100477241ff01710d1a2005422088a721072005a721080240024020064101460d0041b99dc500ad4280808080d0018410110c010b410410212202450d412002200836000020024104410810252202450d412002200736000441b99dc500ad4280808080d001842002ad4280808080800184100e200210230b200341e0036a41186a4200370300200341e0036a41106a22224200370300200341e0036a41086a22024200370300200342003703e00341e4dec400ad4280808080e00084100c220129000021052002200141086a290000370300200320053703e003200110234191dfc400ad4280808080e00084100c2201290000210520034190026a41086a2224200141086a2900003703002003200537039002200110232022200329039002220537030020034180056a41086a200229030037030020034180056a41106a200537030020034180056a41186a2024290300370300200320032903e00337038005200341c00a6a20034180056a10f7020240024020032802c00a22220d00410021242003410036029009200342043703880941042122410021010c010b200320032902c40a220537028c0920032022360288092005422088a721012005a721240b200341c0066a41026a2209200341e8076a41026a2d00003a0000200341a0056a41086a220a200341c00a6a41086a290200370300200341a0056a41106a220b200341c00a6a41106a280200360200200320032f00e8073b01c006200320032902c00a3703a005024020012024470d0020034188096a2024410110a201200328028c092124200328028809212220032802900921010b2022200141246c220c6a220241043a00002002200736020c2002200836020820022006360204200241036a20092d00003a0000200220032f01c0063b0001200220032903a005370210200241186a200a290300370200200241206a200b2802003602002003200141016a22023602900941e4dec400ad4280808080e00084100c2206290000210520062900082118200610234191dfc400ad4280808080e00084100c2206290000212a2006290008212b200610232003202b3703b8052003202a3703b005200320183703a805200320053703a005200341203602c4062003200341a0056a3602c00620222002200341c0066a10f802024020022001490d00200c41246a21022022210303400240024020032d0000220141044b0d0002400240024020010e050400010204040b2003410c6a280200450d03200341086a28020010230c030b2003410c6a280200450d02200341086a28020010230c020b2003410c6a280200450d01200341086a28020010230c010b200341086a280200450d00200341046a28020010230b200341246a21032002415c6a22020d000b0b2024450d04202441246c450d04202210230c040b2005422088a721012005a7210702402024202241ff01714100477241ff01710d000240200141186c2203450d00200620036a2102200621030340200341086a350200422086200335020084200341146a3502004220862003410c6a35020084100e200341186a22032002470d000b0b02402001450d00200141186c21022006210303400240200341046a280200450d00200328020010230b0240200341106a280200450d002003410c6a28020010230b200341186a2103200241686a22020d000b0b2007450d04200741186c450d04200610230c040b02402001450d00200141186c21022006210303400240200341046a280200450d00200328020010230b0240200341106a280200450d002003410c6a28020010230b200341186a2103200241686a22020d000b0b02402007450d00200741186c450d00200610230b200041003602042000410c6a41023602000c4a0b2005422088a721012005a7210702402024202241ff01714100477241ff01710d0002402001410c6c2203450d00200620036a2102200621030340200341086a35020042208620033502008410112003410c6a22032002470d000b0b02402001450d002001410c6c21022006210303400240200341046a280200450d00200328020010230b2003410c6a2103200241746a22020d000b0b2007450d032007410c6c450d03200610230c030b02402001450d002001410c6c21022006210303400240200341046a280200450d00200328020010230b2003410c6a2103200241746a22020d000b0b02402007450d002007410c6c450d00200610230b200041003602042000410c6a41023602000c490b2005a7210302402024202241ff01714100477241ff01710d002005428080808070832006ad8410122003450d02200610230c020b02402003450d00200610230b200041003602042000410c6a41023602000c480b202241ff01710d0241012101202441ff01714101470d022002411a6a2901002105200241196a2d00002122200241186a2d00002124200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f010021142003200241096a2d00003a00a705200320103a00a605200320113b01a405200320123a00a305200320133a00a205200320143b01a0052003200a3a00af052003200b3a00ae052003200c3b01ac052003200d3a00ab052003200e3a00aa052003200f3b01a805200320223a00b705200320243a00b605200320063b01b405200320073a00b305200320083a00b205200320093b01b005200320053703b80520034188096a41186a200537030020034188096a41106a20032903b00537030020034190096a20032903a805370300200320032903a00537038809200341c0066a20034188096a109702200341c00a6a20032802c006220220032802c80610980242002105420021184200212a4200212b4200212c4200212d4200212e4200212f024020032903c00a4201520d0020032d008c0b452101200341c00a6a41106a290300212f200341e00a6a2903002118200341c00a6a41186a2903002105200341f00a6a290300212b200341e80a6a290300212a200341800b6a290300212d200341f80a6a290300212c20032903c80a212e0b024020032802c406450d00200210230b024020010d00410f210341efdcc4002102418080102101410321220c040b0240202a200584202c84202e84202b201884202d84202f8484500d004113210341fedcc40021024180800c2101410321220c040b200341c00a6a41186a20034188096a41186a290300370300200341c00a6a41106a20034188096a41106a290300370300200341c00a6a41086a20034188096a41086a29030037030020032003290388093703c00a200341c0066a200341c00a6a10f90220033502c80642208620032802c0062202ad84101120032802c406450d00200210230b410021020b2000200236020420002002360200200424000f0b41002101410221220b20004100360204200041146a2003360200200041106a20023602002000410c6a20014180801c712022723602000c430b0240024020022d00000d0020022d000141ff01714102470d00200141086a2903002105200341e0036a41186a22244200370300200341e0036a41106a22024200370300200341e0036a41086a22014200370300200342003703e00341b494c700ad42808080809001842218100c2222290000212a2022290008212b202210232001202b3703002003202a3703e00341a89ec700ad4280808080900184100c2206290000212a20034190026a41086a2222200641086a2900003703002003202a37039002200610232002200329039002222a37030020034180056a41086a2207200129030037030020034180056a41106a2208202a37030020034180056a41186a22092022290300370300200320032903e00337038005200341c8006a20034180056a4120419ca8c70041004100108c0120032802484101460d14202442003703002002420037030020014200370300200342003703e0032018100c220629000021182006290008212a200610232001202a370300200320183703e00341bd94c700ad428080808030842218100c2206290000212a2022200641086a2900003703002003202a37039002200610232002200329039002370000200241086a2022290300370000200720012903003703002008200229030037030020092024290300370300200320032903e00337038005200341386a20034180056a10fa022003290340500d012003280238450d01200341e0036a41186a22244200370300200341e0036a41106a22064200370300200341e0036a41086a22014200370300200342003703e00341b494c700ad4280808080900184100c2222290000212a2022290008212b202210232001202b3703002003202a3703e00341bd94c700ad42808080803084100c2222290000212a20034190026a41086a2207202241086a2900003703002003202a37039002202210232002200329039002370000200241086a200729030037000020034180056a41086a200129030037030020034180056a41106a200629030037030020034180056a41186a2024290300370300200320032903e00337038005200341286a20034180056a10fa02200329033042b8177c42b81720032802281b2005580d0141f5a2c70041ce00418c94c700102d000b200041003602042000410c6a410236020020004101360200200424000f0b200341e0036a41186a22224200370300200341e0036a41106a22244200370300200341e0036a41086a22014200370300200342003703e00341b494c700ad4280808080900184222a100c2206290000212b2006290008212c200610232001202c3703002003202b3703e0032018100c2207290000211820034190026a41086a2206200741086a2900003703002003201837039002200710232002200329039002370000200241086a2208200629030037000020034180056a41086a2209200129030037030020034180056a41106a220a202429030037030020034180056a41186a220b2022290300370300200320032903e00337038005200320053703c00a20034180056aad42808080808004842205200341c00a6aad22184280808080800184100e202242003703002024420037030020014200370300200342003703e003202a100c2207290000212a2007290008212b200710232001202b3703002003202a3703e00341a89ec700ad4280808080900184100c2207290000212a2006200741086a2900003703002003202a370390022007102320022003290390023700002008200629030037000020092001290300370300200a2024290300370300200b2022290300370300200320032903e00337038005200341013a00c00a2005201842808080801084100e2000410036020420004100360200200424000f0b200141156a29000021052001410d6a29000021182002411a6a290100212c200241196a2d00002124200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f01002116200141286a28020021192001411d6a290000212a200141056a290000222b421888a7211720022d0001212220022d000021020240024002400240024020012d00040e050001020304000b200341c00a6a41146a4101360200200342013702c40a200341a4c5c6003602c00a2003410436028c09200341cccec60036028809200320034188096a3602d00a200341c00a6a419ca8c700103a000b200241ff01710d15202241ff01714101470d152003202c37038008200320243a00ff07200320063a00fe07200320073b01fc07200320083a00fb07200320093a00fa072003200a3b01f8072003200b3a00f7072003200c3a00f6072003200d3b01f4072003200e3a00f3072003200f3a00f207200320103b01f007200320113a00ef07200320123a00ee07200320133b01ec07200320143a00eb07200320153a00ea07200320163b01e807200341e0036a201710fb02200341c00a6a20032802e003220920032802e803220a10fc0220034188096a41086a2202200341c00a6a41106a29030037030020034188096a41106a2201200341c00a6a41186a29030037030020034188096a41186a2222200341e00a6a290300370300200320032903c80a37038809024020032903c00a4201510d00200341c0066a41086a200341e8076a41086a290300370300200341c0066a41106a200341e8076a41106a290300370300200341c0066a41186a200341e8076a41186a290300370300200320032903e8073703c006200342003703a80520034280a094a58d1d3703a0052003200341e8076a360280052003200341e8076a3602a0022003200341a0026a3602c80a200320034180056a3602c40a2003200341a0056a3602c00a20034188096a200341e8076a200341c00a6a10fd0202402003280288094101470d0020034194096a280200210120034190096a280200212220032d008f09210720032d008e09212420032d008d09210620032d008c0921020c380b41042102024020034188096a41086a2903004201510d000c380b20034188096a41106a290300210520032802a0022101200341f80a6a20034188096a41186a290300370300200341f00a6a2005370300200341c00a6a41086a41003a0000200341c90a6a2001290000370000200341d10a6a200141086a290000370000200341d90a6a200141106a290000370000200341e10a6a200141186a290000370000200341023a00c00a200341c00a6a10e0010c370b200341c0066a41186a2022290300370300200341c0066a41106a2001290300370300200341c0066a41086a200229030037030020032003290388093703c0064105210141d0a4c6002122410221244104210641032102410021080c370b200341c0066a41106a20053703002003202b3703c0062003202a3703d806200320183703c8060240200241ff01710d00202241ff01714101470d002003202c3703a009200320243a009f09200320063a009e09200320073b019c09200320083a009b09200320093a009a092003200a3b0198092003200b3a0097092003200c3a0096092003200d3b0194092003200e3a0093092003200f3a009209200320103b019009200320113a008f09200320123a008e09200320133b018c09200320143a008b09200320153a008a09200320163b018809024020034188096a200341c0066a412010a3050d00410021014103210241042122410b212441c5a4c6002106410321070c360b200341a0056a201910fb02200341c00a6a20032802a005220820032802a805220910fc02410321024104212241002101024020032903c00a4201510d0041dda4c6002106410b2124410021070c350b200341f00a6a2903002105200341e80a6a2903002118200341d00a6a2224290300212b200341c00a6a41206a290300212a20032903c80a212c2024200341d80a6a2903003703002003202a3703d80a2003202c3703c00a2003202b3703c80a200341c00a6a20034188096a412010a3050d16200341e8076a20034188096a200341c0066a20182005410110fe02200341e8076a41086a290300212b0240024020032802e8074101460d0042002005200341e8076a41106a2903007d2018202b54ad7d222a2018202b7d222b201856202a200556202a2005511b22021b21054200202b20021b2118200341c0066a41106a290300212c20032903c806212d20032903c006212e20032903d806212a4201212b4100212241002107410021010c010b20032802ec07220241187621012002411076210720024108762122202b422088a72124202ba72106200241ff01714104470d354200212b0b200341f00a6a2005370300200341e80a6a2018370300200341e00a6a202a3703002003202b3703c00a200341d80a6a202c3703002003202e3703c80a2003202d3703d00a02400240202b4201510d002009ad4220862008ad8410110c010b411010212202450d3b20024110412010252202450d3a2002200341c80a6a220a290000370000200241186a200a41186a290000370000200241106a200a41106a290000370000200241086a200a41086a2900003700002002412041c00010252202450d3a20022018370020200241286a20053700002009ad4220862008ad842002ad4280808080800684100e200210230b410421020c340b410021224102210241002107410021010c340b0240200241ff01710d00202241ff01714101470d002003202c37038008200320243a00ff07200320063a00fe07200320073b01fc07200320083a00fb07200320093a00fa072003200a3b01f8072003200b3a00f7072003200c3a00f6072003200d3b01f4072003200e3a00f3072003200f3a00f207200320103b01f007200320113a00ef07200320123a00ee07200320133b01ec07200320143a00eb07200320153a00ea07200320163b01e807200341e0036a201710fb02200341c00a6a20032802e003220620032802e803222210fc024103210241002101024020032903c00a4201510d0041dda4c6002122410b21240c320b200341f00a6a290300212b200341e80a6a290300212c200341c00a6a41106a2903002105200341c00a6a41206a290300211820032903c80a212a200341c0066a41106a200341d80a6a290300370300200320183703d8062003202a3703c006200320053703c806200341c0066a200341e8076a412010a3050d162003202c3703a0052003202b3703a8050240202c202b84500d002003200341e8076a3602a00220034188096a200341e8076a200341a0056a200341a0026a10ff022003290388094201520d002003290390092105200341f80a6a20034188096a41106a290300370300200341f00a6a2005370300200341c00a6a41086a41003a0000200341c90a6a20032903e807370000200341d10a6a200341e8076a41086a290300370000200341d90a6a200341e8076a41106a290300370000200341e10a6a20034180086a290300370000200341023a00c00a200341c00a6a10e0010b2022ad4220862006ad841011410421020c310b41002101410221020c310b2022200241ff01714100477241ff01710d15200341a0056a201910fb02200341c00a6a20032802a005222220032802a805220710fc02200341f00a6a2102200341e80a6a2101200341d80a6a2124200341e00a6a2106024020032903c00a4201520d002002290300212c2001290300212d200341c00a6a41106a290300212e2006290300212f20032903c80a2130200341c0066a41106a20242903003703002003202f3703d806200320303703c0062003202e3703c8062003202d3703e8072003202c3703f007202d202c84500d002003200341c0066a3602e00320034188096a200341c0066a200341e8076a200341e0036a10ff022003290388094201520d00200329039009212c200341f80a6a20034188096a41106a290300370300200341f00a6a202c370300200341c00a6a41086a41003a0000200341c90a6a20032903c006370000200341d10a6a200341c0066a41086a290300370000200341d90a6a200341c0066a41106a290300370000200341e10a6a200341d8066a290300370000200341023a00c00a200341c00a6a10e0010b20024200370300200142003703002006202a370300202420053703002003202b3703c80a200342013703c00a200320183703d00a411010212202450d3720024110412010252202450d362002200341c80a6a2201290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a2900003700002002412041c00010252202450d3620024200370020200241286a42003700002007ad4220862022ad842002ad4280808080800684100e20021023024020032802a405450d00202210230b200341cd0a6a2018370000200341c00a6a41286a2019360200200341dd0a6a202a370000200341d50a6a20053700002003202b3700c50a200341003a00c40a200341013a00c00a200341c00a6a10e0012000410036020420004100360200200424000f0b200141216a290000212a200141206a2d000021062001411d6a2f000021072001411c6a2d00002108200141196a2f00002109200141186a2d0000210a200141156a2f0000210b200141146a2d0000210c200141116a2f0000210d200141106a2d0000210e2001410d6a2f0000210f2001410c6a2d00002110200141096a2f00002111200141086a2d0000212220012d001f211220012d001b211320012d0017211420012d0013211520012d000f211620012d000b211720032001412c6a28000036008b022003200128002936028802200141c8006a290300212c200141c0006a290300212b200141386a2903002105200141306a29030021182002411a6a290100212d200241196a2d00002119200241186a2d0000211a200241166a2f0100211b200241156a2d0000211c200241146a2d0000211d200241126a2f0100211e200241116a2d0000211f200241106a2d000021202002410e6a2f010021212002410d6a2d000021232002410c6a2d000021252002410a6a2f01002126200241096a2d00002127200241086a2d00002128200241066a2f01002129200241056a2d00002131200241046a2d00002132200241026a2f0100213320022d0001212420022d000021020240024002400240024020220e050001020304000b200341c00a6a41146a4101360200200342013702c40a200341a4c5c6003602c00a2003410436028c09200341cccec60036028809200320034188096a3602d00a200341c00a6a419ca8c700103a000b02400240200241ff01710d00202441ff01714101470d002003202d3703a009200320193a009f092003201a3a009e092003201b3b019c092003201c3a009b092003201d3a009a092003201e3b0198092003201f3a009709200320203a009609200320213b019409200320233a009309200320253a009209200320263b019009200320273a008f09200320283a008e09200320293b018c09200320313a008b09200320323a008a09200320333b0188092003202a3703d80a200320063a00d70a200320123a00d60a200320073b01d40a200320083a00d30a200320133a00d20a200320093b01d00a2003200a3a00cf0a200320143a00ce0a2003200b3b01cc0a2003200c3a00cb0a200320153a00ca0a2003200d3b01c80a2003200e3a00c70a200320163a00c60a2003200f3b01c40a200320103a00c30a200320173a00c20a200320113b01c00a200341c0066a20034188096a200341c00a6a2018200541011080034100210220032d00c00622014104460d32200341c0066a41086a280200210220032802c406212220032d00c106410874212420032d00c206411074210620032d00c30641187421030c010b410021244102210141002106410021030b200041146a2002360200200041106a20223602002000410c6a20032006722024722001723602000c2d0b2024200241ff01714100477241ff01710d182003202a3703b802200320063a00b702200320123a00b602200320073b01b402200320083a00b302200320133a00b202200320093b01b0022003200a3a00af02200320143a00ae022003200b3b01ac022003200c3a00ab02200320153a00aa022003200d3b01a8022003200e3a00a702200320173a00a202200320113b01a0022003200f4108742010722016411874723600a3024200212e20034200202c202b20187c222a4280c8afa025544100202c20057c202a202b54ad7c501b22021b222c3703c80320034200202b20021b222b3703c0032003200341a0026a3602ac0a200341b00a6a200341a0026a109702200341e8076a20032802b00a222420032802b80a220610980220032903e8072130200342003703e8074200200520021b21054200201820021b2118200341b0086a280200210720032d00b40821080240024020304201510d00200341a0056a41306a4200370300200341a0056a41286a4200370300200341a0056a41206a4200370300200341a0056a41186a4200370300200341b0056a4200370300200341a0056a41086a4200370300200342003703a0054200212f4200212d4200212a420021340c010b200341a0086a2903002135200341e8076a41306a2903002136200341e8076a41206a290300212f200341e8076a41186a290300212e200341a8086a290300213420032903f807212a20032903f007212d200341a0056a41206a200341e8076a41286a290300370300200341a0056a41286a2036370300200341a0056a41306a2035370300200341b0056a202e3703002003202f3703b8052003202d3703a0052003202a3703a8050b202d202e7c2236202d5421222018202d562005202a562005202a5122021b0d172018202d542005202a5420021b450d2e200341e0036a41186a220b4200370300200341e0036a41106a22014200370300200341e0036a41086a22024200370300200342003703e00341bdadc500ad4280808080800184222b100c2209290000212c2009290008213520091023200220353703002003202c3703e00341c5adc500ad4280808080d00184222c100c220a290000213520034190026a41086a2209200a41086a2900003703002003203537039002200a10232001200329039002223537030020034180056a41086a220c200229030037030020034180056a41106a220d203537030020034180056a41186a220e2009290300370300200320032903e0033703800520034198016a20034180056a412010d70120034198016a41106a290300213520032903a0012137200328029801210a200b42003703002001420037030020024200370300200342003703e003202b100c220b290000212b200b2900082138200b1023200220383703002003202b3703e003202c100c220b290000212b2009200b41086a2900003703002003202b37039002200b10232001200329039002222b370300200c2002290300370300200d202b370300200e2009290300370300200320032903e003370380052003420020354200200a1b222b202d201854ad2005202a7d7c7c20374200200a1b222c202d20187d223554ad7d222d202c20357d2235202c56202d202b56202d202b511b22021b3703c80a20034200203520021b3703c00a200341c00a6a210220034180056a21010c2d0b200141d8006a290300212d200141d0006a290300212e20034187086a202c3c0000200341f7076a20053700002003202b3700ff07200320183700ef072003200328008b023600eb0720032003280288023602e80741002101024002402024200241ff01714100477241ff01710d002003202a3703a009200320063a009f09200320123a009e09200320073b019c09200320083a009b09200320133a009a09200320093b0198092003200a3a009709200320143a0096092003200b3b0194092003200c3a009309200320153a0092092003200d3b0190092003200e3a008f09200320163a008e092003200f3b018c09200320103a008b09200320173a008a09200320113b018809200341c00a6a41186a200341e8076a41186a290300370300200341c00a6a41106a200341e8076a41106a290300370300200341c00a6a41086a200341e8076a41086a290300370300200320032903e8073703c00a200341c0066a20034188096a200341c00a6a202e202d41011080034100210220032d00c00622224104460d30200341c0066a41086a280200210220032802c406212420032d00c106410874210120032d00c206411074210620032d00c30641187421030c010b4102212241002106410021030b200041146a2002360200200041106a20243602002000410c6a20032006722001722022723602000c2b0b2003202a3703b805200320063a00b705200320123a00b605200320073b01b405200320083a00b305200320133a00b205200320093b01b0052003200a3a00af05200320143a00ae052003200b3b01ac052003200c3a00ab05200320153a00aa052003200d3b01a8052003200e3a00a705200320163a00a6052003200f3b01a405200320103a00a305200320173a00a205200320113b01a00502400240200241ff01710d00202441ff01714101470d002003202d3703a009200320193a009f092003201a3a009e092003201b3b019c092003201c3a009b092003201d3a009a092003201e3b0198092003201f3a009709200320203a009609200320213b019409200320233a009309200320253a009209200320263b019009200320273a008f09200320283a008e09200320293b018c09200320313a008b09200320323a008a09200320333b018809200341c00a6a41186a200341a0056a41186a290300370300200341c00a6a41106a200341a0056a41106a290300370300200341c00a6a41086a200341a0056a41086a290300370300200320032903a0053703c00a41002102200341c0066a20034188096a200341c00a6a20182005410010800320032d00c00622014104460d2f200341c0066a41086a280200210220032802c406212220032d00c106410874212420032d00c206411074210620032d00c30641187421030c010b410021244102210141002106410021030b200041146a2002360200200041106a20223602002000410c6a20032006722024722001723602000c2a0b2001410c6a2802002107200141086a28020021092001280204210b4102212202400240024020022d00000d0020022d000141ff01714102470d002007410a4b0d01200341a0056a41186a22244200370300200341a0056a41106a22064200370300200341a0056a41086a22024200370300200342003703a00541fea6c600ad4280808080a001842205100c220129000021182002200141086a290000370300200320183703a005200110234198bdc600ad4280808080c00184222b100c220129000821182001290000212a20011023200341e8076a41106a2201202a370300200341e8076a41186a22082018370300200341e8076a41086a220a2002290300370300200320032903a0053703e807200341e8076a108103220c41ff01714102460d0241032122200c410171450d020b4101210d4110210a41cfa7c600210e2007450d280c270b4102210d41032122410d210a41c2a7c600210e0c260b202442003703002006420037030020024200370300200342003703a0052005100c222229000021182002202241086a290000370300200320183703a00520221023202b100c222229000821182022290000212a202210232001202a37030020082018370300200a2002290300370300200320032903a0053703e807200341013a00c00a200341e8076aad4280808080800484222a200341c00a6aad42808080801084100e200341e0036a41186a4200370300200341e0036a41106a22194200370300200341e0036a41086a22224200370300200342003703e00341e4dec400ad4280808080e00084100c220c29000021182022200c41086a290000370300200320183703e003200c102341f3dec400ad4280808080e00084100c220c290000211820034190026a41086a220d200c41086a2900003703002003201837039002200c10232019200329039002221837030020034180056a41086a202229030037030020034180056a41106a201837030020034180056a41186a200d290300370300200320032903e00337038005200341b8016a20034180056a412010cd0120032802bc01210c20032802b801210d202442003703002006420037030020024200370300200342003703a0052005100c222229000021052002202241086a290000370300200320053703a00520221023419ca8c600ad4280808080e00084100c2222290008210520222900002118202210232001201837030020082005370300200a2002290300370300200320032903a0053703e807200341c00a6a200341e8076a1082030240024020032802c00a22100d00200341003602b80a200342043703b00a4104211041002101410021020c010b200320032902c40a22053702b40a200320103602b00a2005422088a721012005a721020b200c4100200d1b2122024020012002470d00200341b00a6a20014101109b0120032802b00a211020032802b80a21010b2010200141c4006c6a220241003a000020022022360204200241036a200341c0066a41026a2d00003a0000200220032f00c0063b0001200220032902c00a370208200241106a200341c00a6a41086a2225290200370200200241186a200341c00a6a41106a2226290200370200200241206a200341c00a6a41186a290200370200200241286a200341c00a6a41206a290200370200200241306a200341c00a6a41286a290200370200200241386a200341c00a6a41306a290200370200200241c0006a200341c00a6a41386a2802003602002003200141016a220f3602b80a200b200741f0006c22026a2123024020070d00200b21240c240b200b41f4006a2106200241907f6a210841e4dec400ad4280808080e000842118200b212403402024280204211120242802002122200341c00a6a202441086a41e80010a1051a202441f0006a21242011450d2420034188096a200341c00a6a41e80010a1051a200320113602c40a200320223602c00a202520034188096a41e80010a1051a200341e0036a41186a22134200370300200341e0036a41106a22144200370300200341e0036a41086a22124200370300200342003703e0032018100c220229000021052012200241086a290000370300200320053703e0032002102341f3dec400ad4280808080e00084100c2202290000210520034190026a41086a2201200241086a2900003703002003200537039002200210232019200329039002370000201941086a200129030037000020034180056a41086a2215201229030037030020034180056a41106a2216201429030037030020034180056a41186a22172013290300370300200320032903e00337038005200341b0016a20034180056a412010cd0120032802b001210220032802b4012101200341e8076a200341c00a6a108303410c210a024020220d0041b6a7c600210e4103210d0c240b024020222001410020021b22024d0d0041aaa7c600210e4104210d0c240b200341c0066a2022417f6a1084030240200341c0066a2026412010a305450d004112210a41dfa7c600210e4100210d0c240b0240202220024f0d004108210a418ea7c600210e4106210d0c240b0240024020102010200f41c4006c22016a460d00201041016a2102034002402002417f6a2d00004101470d004101210c200341e8076a2002460d032002200341e8076a412010a305450d030b200241c4006a2102200141bc7f6a22010d000b0b4100210c0b200341c0066a2022108403200341c0066a200341e8076a412010a30521024114210a4196a7c600210e4105210d200c0d232002450d23200341c0036a41086a220a200341a0056a41086a290200370300200341c0036a41106a220c200341a0056a41106a2f01003b0100200320032902a0053703c003200341e8076a200341c00a6a108303201742003703002016420037030020154200370300200342003703800541c80010212202450d35200341e0036a108503200241186a2013290300370200200241106a2014290300370200200241086a2012290300370200200220032903e003370200200241023602202002410136024420022003290380053701242002412c6a2015290300370100200241346a20162903003701002002413c6a2017290300370100200320023602c00620034282808080203702c406200341c0066a10b901200341c0066a41186a4200370300200341c0066a41106a22014200370300200341c0066a41086a22224200370300200342003703c006200341c0066a10d10220032f01e807210d20032d00ea07210e20032800eb07211220032d00ef07211320032f01f007211420032d00f207211520032d00f307211620032f01f407211720032d00f607211a20032d00f707211b20032f01f807211c20032d00fa07211d20032d00fb07211e20032f01fc07211f20032d00fe07212020032d00ff07212120032903800821052001200c2f01003b01002022200a290300370300200320032903c0033703c0060240200f20032802b40a470d00200341b00a6a200f4101109b0120032802b80a210f0b20032802b00a2210200f41c4006c6a220241003a002120022005370019200220213a0018200220203a00172002201f3b00152002201e3a00142002201d3a00132002201c3b00112002201b3a00102002201a3a000f200220173b000d200220163a000c200220153a000b200220143b0009200220133a0008200220123600042002200e3a00032002200d3b0001200241013a0000200241c0006a20012f01003b0000200241386a2022290300370000200220032903c0063700302003200f41016a220f3602b80a024020032802cc0a2202450d00200241246c21012011210203400240024020022d0000222241044b0d0002400240024020220e050400010204040b2002410c6a280200450d03200241086a28020010230c030b2002410c6a280200450d02200241086a28020010230c020b2002410c6a280200450d01200241086a28020010230c010b200241086a280200450d00200241046a28020010230b200241246a21022001415c6a22010d000b0b024020032802c80a2202450d00200241246c450d00201110230b200841907f6a2108200641f0006a210620242023470d000c250b0b200341c00a6a200141086a41880210a1051a20034188096a41206a200241206a28020036020020034188096a41186a200241186a29020037030020034188096a41106a200241106a29020037030020034188096a41086a200241086a29020037030020032002290200370388092000200341c00a6a20034188096a109402200424000f0b200141086a280200211d2001280204211c200341c00a6a2001410c6a41a40110a1051a2002411a6a2901002105200241196a2d00002122200241186a2d00002124200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520022d0001210120022d000021020240201c450d00200341a0026a200341c00a6a41046a41a00110a1051a024002400240200241ff01710d00200141ff01714101460d010b0240201d450d00201c10230b41002103410221020c010b200320053703d803200320223a00d703200320243a00d603200320063b01d403200320073a00d303200320083a00d203200320093b01d0032003200a3a00cf032003200b3a00ce032003200c3b01cc032003200d3a00cb032003200e3a00ca032003200f3b01c803200320103a00c703200320113a00c603200320123b01c403200320133a00c303200320143a00c203200320153b01c003200341e0036a200341a0026a41a00110a1051a200341c0066a41186a20032903d803370300200341c0066a41106a20032903d003370300200341c8066a20032903c803370300200320032903c0033703c00620034188096a200341c0066a1086020240024020032d0088094101470d00200341ff076a2202200341a1096a290000370000200341e8076a41106a22012003419a096a29010037030020034189056a20034192096a29010037000020034191056a200129030037000020034180056a41186a2002290000370000200320032d0089093a0080052003200329018a0937008105200341a0056a200341e0036a41a00110a1051a20034190026a20034180056a10860320034188096a200328029002220120032802980210870320032d0088092102200341e8076a20034188096a41017241a00110a1051a0240024020024101460d00200341003a00c0060c010b200341013a00c006200341c0066a410172200341e8076a41a00110a1051a0b0240200328029402450d00200110230b200341a0056a41206a211e200341e0056a211f20034180066a2120200341a0066a2121200341e1066a212320034181076a2125200341a1076a2126200341c1076a2127200341c0066a4101722128416c2124034041002101419ca8c70021220240024002400240202441d8cac2006a280000220241e0ea91cb064a22080d00200241f0c2c98b06460d01200241e2c289ab06470d0341202101201e21220c030b200241e1ea91cb06460d010240200241e9dabdf306460d00200241e7e485f306470d0341202101200341a0056a21220c030b41202101201f21220c020b41202101202021220c010b41202101202121220b20032001360290092003202236028c092003200236028809200341e8076a20034188096a10880320034188096a20032802e807220720032802f00710e10120032802ec0721060240024020032d0088094101470d0020032900a109210520032d00a009210920032d009f09210a20032f009d09210b20032d009c09210c20032d009b09210d20032f009909210e20032d009809210f20032d009709211020032f009509211120032d009409211220032d009309211320032f009109211420032d009009211520032d008f09211620032f008d09211720032d008c09211920032d008b09211a20032f008909211b02402006450d00200710230b200320053703a009200320093a009f092003200a3a009e092003200b3b019c092003200c3a009b092003200d3a009a092003200e3b0198092003200f3a009709200320103a009609200320113b019409200320123a009309200320133a009209200320143b019009200320153a008f09200320163a008e09200320173b018c09200320193a008b092003201a3a008a092003201b3b01880920034188096a20034180056a412010a305450d0141808008210341f9abc3002101410d21220c040b2006450d00200710230b0240024020032d00c0064101470d0041002106419ca8c7002107024002400240024020080d00200241f0c2c98b06460d01200241e2c289ab06470d0341202106202321070c030b200241e1ea91cb06460d010240200241e9dabdf306460d00200241e7e485f306470d0341202106202821070c030b41202106202521070c020b41202106202621070c010b41202106202721070b024020012006470d0020222007460d0220222007200110a305450d020b20032006360290092003200736028c092003200236028809200341e8076a20034188096a10880320033502f00742208620032802e8072206ad84101120032802ec07450d00200610230b20032001360290092003202236028c092003200236028809200341e8076a20034188096a10880320032802e807210120033502f0072105412010212202450d392002200329038005370000200241186a20034180056a41186a290300370000200241106a20034180056a41106a290300370000200241086a20034180056a41086a29030037000020054220862001ad842002ad4280808080800484100e2002102320032802ec07450d00200110230b202441046a22240d000b20034188096a20034180056a10860320033502900921052003280288092101412010212202450d36200220032903a005370000200241186a200341a0056a41186a290300370000200241106a200341a0056a41106a290300370000200241086a200341a0056a41086a2903003700002002412041c00010252202450d36200220032903c005370020200241386a200341a0056a41386a290300370000200241306a200341a0056a41306a290300370000200241286a200341a0056a41286a290300370000200241c00041800110252202450d36200220032903e005370040200241d8006a200341a0056a41d8006a290300370000200241d0006a200341a0056a41d0006a290300370000200241c8006a200341a0056a41c8006a2903003700002002200329038006370060200241e8006a200341a0056a41e8006a290300370000200241f0006a200341a0056a41f0006a290300370000200241f8006a200341a0056a41f8006a290300370000200241800141800210252202450d36200220032903a0063700800120024198016a200341a0056a4198016a29030037000020024190016a200341a0056a4190016a29030037000020024188016a200341a0056a4188016a29030037000020054220862001ad842002ad4280808080801484100e200210230240200328028c09450d00200110230b024020032d00c0060d00200341c0036a1096020b0240201d450d00201c10230b2000410036020420004100360200200424000f0b4180800421034186acc3002101411721220b0240201d450d00201c10230b410321020b20004100360204200041146a2022360200200041106a20013602002000410c6a20034180800c712002724180167236020020004101360200200424000f0b02400240200241ff01710d00200141ff01714101470d00200320103a00a702200320113a00a602200320123b01a402200320133a00a302200320143a00a202200320153b01a0022003200a3a00af022003200b3a00ae022003200c3b01ac022003200d3a00ab022003200e3a00aa022003200f3b01a802200320223a00b702200320243a00b602200320063b01b402200320073a00b302200320083a00b202200320093b01b002200320053703b802200341c0066a41186a2005370300200341c0066a41106a20032903b002370300200341c8066a20032903a802370300200320032903a0023703c00620034188096a200341c0066a108602024020032d0088094101470d00200341ff076a2202200341a1096a290000370000200341e8076a41106a22012003419a096a290100370300200341e9036a20034192096a290100370000200341f1036a2001290300370000200341e0036a41186a2002290000370000200320032d0089093a00e0032003200329018a093700e10320034180056a200341e0036a10860320034188096a20032802800522022003280288052222108703024020032d0088092201450d002022ad4220862002ad8410110b20032d0089092122200341e8076a20034188096a410272419f0110a1051a20034188096a200341e8076a419f0110a1051a024020014101470d00200341a0056a20034188096a419f0110a1051a0240200328028405450d00200210230b200320223a00c006200341c0066a410172200341a0056a419f0110a1051a20034190096a4120360200200341e7e485f306360288092003200341c0066a36028c09200341e8076a20034188096a10880320033502f00742208620032802e8072202ad841011024020032802ec07450d00200210230b200341e2c289ab063602880920034120360290092003200341c0066a41206a36028c09200341e8076a20034188096a10880320033502f00742208620032802e8072202ad841011024020032802ec07450d00200210230b2003412036029009200320034180076a36028c09200341e9dabdf30636028809200341e8076a20034188096a10880320033502f00742208620032802e8072202ad841011024020032802ec07450d00200210230b20034120360290092003200341a0076a36028c09200341f0c2c98b0636028809200341e8076a20034188096a10880320033502f00742208620032802e8072202ad841011024020032802ec07450d00200210230b20034120360290092003200341c0076a36028c09200341e1ea91cb0636028809200341e8076a20034188096a10880320033502f00742208620032802e8072202ad841011024020032802ec07450d00200210230b200341a0026a10a1022000410036020420004100360200200424000f0b0240200328028405450d00200210230b4106210241f3abc30021014180800c2122410321030c020b411721024186acc3002101418080042122410321030c010b41002122410221030b20004100360204200041146a2002360200200041106a20013602002000410c6a20224180800c712003724180167236020020004101360200200424000f0b41801821244102212220022d00000d1d20022d000141ff01714102470d1d20012802042106200341a0056a41186a4200370300200341a0056a41106a4200370300200341a0056a41086a22024200370300200342003703a00541fee2c200ad4280808080f00184100c22012900002105200129000821182001102320022018370300200320053703a00541e1e6c200ad4280808080e00084100c220129000821052001290000211820011023200341e8076a41106a2018370300200341e8076a41186a2005370300200341e8076a41086a2002290300370300200320032903a0053703e807200341c8016a200341e8076a4120419ca8c70041004100108c0141032122024020032802c8014101470d0041d8e3c2002102410e21030c1f0b200341e0036a41186a4200370300200341e0036a41106a22244200370300200341e0036a41086a22024200370300200342003703e00341e4dec400ad4280808080e00084100c220129000021052002200141086a290000370300200320053703e0032001102341f3dec400ad4280808080e00084100c2201290000210520034190026a41086a2207200141086a2900003703002003200537039002200110232024200329039002220537030020034180056a41086a200229030037030020034180056a41106a200537030020034180056a41186a2007290300370300200320032903e00337038005200341c0016a20034180056a412010cd01024020032802c401410020032802c0011b20064f0d0041d1e3c2002102410721034180980421240c1f0b200341a0056a41186a4200370300200341a0056a41106a4200370300200341a0056a41086a22024200370300200342003703a00541fee2c200ad4280808080f00184100c22012900002105200129000821182001102320022018370300200320053703a00541e1e6c200ad4280808080e00084100c220129000821052001290000211820011023200341e8076a41106a2018370300200341e8076a41186a2005370300200341e8076a41086a2002290300370300200320032903a0053703e807200320063602c00a200341e8076aad4280808080800484200341c00a6aad4280808080c00084100e2000410036020420004100360200200424000f0b200141086a280200210320012802042101024020022d00000d0020022d000141ff01714101470d0002402003450d00200110230b2000410036020420004100360200200424000f0b02402003450d00200110230b200041003602042000410c6a410236020020004101360200200424000f0b2001411c6a280200210a200141186a280200210b200141146a280200210c2001410c6a280200210d200141086a280200210f410021224102212402400240024020022d0000450d000c010b20022d000141ff01714102470d00200141246a280200210e200141106a2802002124200341e0036a41186a22064200370300200341e0036a41106a22024200370300200341e0036a41086a22014200370300200342003703e00341db97c700ad4280808080f00084100c222229000021052001202241086a290000370300200320053703e0032022102341bcbcc300ad4280808080c00184100c2207290000210520034190026a41086a2222200741086a2900003703002003200537039002200710232002200329039002220537030020034180056a41086a2208200129030037030020034180056a41106a2209200537030020034180056a41186a22102022290300370300200320032903e00337038005200341d8016a20034180056a412010cd01200341c00a6a20032802dc01410020032802d8011b2212200e10ae02200341d0016a20032802c00a220720032802c80a419ca8c70041004100108c0120032802d0012111024020032802c40a450d00200710230b200642003703002002420037030020014200370300200342003703e0034180cdc200ad4280808080800184100c220729000021052001200741086a290000370300200320053703e0032007102341d7a1c200ad4280808080c00084100c220729000021052022200741086a2900003703002003200537039002200710232002200329039002370000200241086a2022290300370000200820012903003703002009200229030037030020102006290300370300200320032903e00337038005200341c00a6a20034180056a10ad0220032802c00a2202410120021b211020032902c40a420020021b21050240201141014622010d002010200e4105746a4100200e2005422088a7491b22020d020b41a3a1c20041b6a1c20020011b21064113410a20011b21072001411074212241032124200542ffffff3f83500d00201010230b0240200d450d00200f10230b0240200a450d00200a410c6c2102200c210303400240200341046a280200450d00200328020010230b2003410c6a2103200241746a22020d000b0b0240200b450d00200b410c6c450d00200c10230b20004100360204200041146a2007360200200041106a20063602002000410c6a202220247241801c7236020020004101360200200424000f0b200241086a2900002118200241106a290000212a2002290000212b200341a0056a41186a200241186a290000222c370300200341a0056a41106a202a370300200341a0056a41086a20183703002003202b3703a005200341cd0a6a2018370000200341d50a6a202a370000200341dd0a6a202c370000200341003a00c40a200341073a00c00a2003202b3700c50a200341c00a6a10e001200341003602c80a200342013703c00a2024200341c00a6a10610240024020032802c40a222220032802c80a22026b2024490d0020032802c00a21010c010b200220246a22012002490d13202241017422062001200620014b1b22064100480d130240024020220d00024020060d00410121010c020b2006102122010d010c320b20032802c00a210120222006460d0020012022200610252201450d310b200320063602c40a200320013602c00a0b200120026a200f202410a1051a2003200220246a3602c80a200a200341c00a6a1061200a450d11200c200a410c6c6a2109200c2101034020012802002108200141086a2802002202200341c00a6a10610240024020032802c40a222420032802c80a22226b2002490d0020032802c00a2106202421070c010b202220026a22062022490d14202441017422072006200720064b1b22074100480d140240024020240d00024020070d00410121060c020b200710212206450d330c010b20032802c00a210620242007460d0020062024200710252206450d320b200320073602c40a200320063602c00a0b200620226a2008200210a1051a2003202220026a22023602c80a2001410c6a22012009470d000c1b0b0b200341c00a6a200141046a419c0210a1051a20034188096a41206a200241206a28020036020020034188096a41186a200241186a29020037030020034188096a41106a200241106a29020037030020034188096a41086a200241086a29020037030020032002290200370388092000200341c00a6a20034188096a108903200424000f0b41822221010240024020022d00000d0020022d000141ff01714102470d00200341e0036a41186a22064200370300200341e0036a41106a22224200370300200341e0036a41086a22024200370300200342003703e00341b9f4c200ad4280808080c00184222a100c22012900002105200129000821182001102320022018370300200320053703e00341a89ec700ad42808080809001842218100c2201290000210520034190026a41086a2224200141086a2900003703002003200537039002200110232022200329039002220537030020034180056a41086a2207200229030037030020034180056a41106a2208200537030020034180056a41186a22092024290300370300200320032903e00337038005200341e0016a20034180056a4120419ca8c70041004100108c01418322210120032802e0014101470d010b20004100360204200041146a4113360200200041106a41ebe2c2003602002000410c6a200136020020004101360200200424000f0b200642003703002022420037030020024200370300200342003703e003202a100c220129000021052001290008212a200110232002202a370300200320053703e0032018100c220129000021052024200141086a2900003703002003200537039002200110232022200329039002370000202241086a2024290300370000200720022903003703002008202229030037030020092006290300370300200320032903e00337038005200341013a00c00a20034180056aad4280808080800484200341c00a6aad42808080801084100e2000410036020420004100360200200424000f0b200228020022224108762124200241046a28020021062001411c6a280200210b200141186a2802002108200141146a280200210c200141106a280200210a2001410c6a2802002109200141086a2802002107024002400240024002400240024002400240024020012d00040e080001020304050607000b200341c00a6a41146a4101360200200342013702c40a200341a4c5c6003602c00a2003410436028c09200341cccec60036028809200320034188096a3602d00a200341c00a6a419ca8c700103a000b0240024002402024202241ff01714100477241ff01710d00200c41808080054b0d01200141206a28020022024180a0014d0d02200341c8066a41103602002003419fabc3003602c406200341043a00c20620034183243b01c0060c1f0b200341023a00c0060c1e0b200341c8066a410c36020020034193abc3003602c406200341033a00c20620034183243b01c0060c1d0b20012d000521012003200c360290092003200a36028c092003200936028809200320023602c80a2003200b3602c40a200320083602c00a41002102200341c0066a2007200141ff017141004720034188096a200341c00a6a108a0320032d00c0064104460d1e0c1d0b02400240024002402024202241ff01714100477241ff0171450d00200341023a00c00a0c010b200341c00a6a2007108b0320032d00c00a4104460d01200341c80a6a280200210220032802c40a21010b20032802c00a2103200041146a2002360200200041106a20013602002000410c6a2003360200410121030c010b410021030b2000410036020420002003360200200424000f0b4100210202402024202241ff01714100477241ff0171450d00200041003602042000410c6a410236020020004101360200200424000f0b20034198056a420037030020034190056a2224420037030020034180056a41086a2201420037030020034200370380054196adc300ad4280808080900184100c22222900002105202229000821182022102320012018370300200320053703800541d8dfc300ad4280808080b00184100c2222290000210520034190026a41086a2206202241086a2900003703002003200537039002202210232024200329039002220537030020032003290380053703c00a200320012903003703c80a200320053703d00a200320062903003703d80a2003200736028809200341c00a6aad428080808080048420034188096aad4280808080c00084100e0c040b410221010240202241ff0171450d000c190b202441ff01714101470d18200241196a2d00002101200241186a2d00002124200241166a2f0100210d200241156a2d0000210e200241146a2d0000210f200241126a2f01002110200241116a2d00002111200241106a2d000021122002410e6a2f010021132002410d6a2d000021142002410c6a2d000021152002410a6a2f01002116200241096a2d00002117200241086a2d0000211920032002411a6a2901003703d806200320013a00d706200320243a00d6062003200d3b01d4062003200e3a00d3062003200f3a00d206200320103b01d006200320113a00cf06200320123a00ce06200320133b01cc06200320143a00cb06200320153a00ca06200320163b01c806200320173a00c706200320193a00c606200320064110763b01c406200320064108763a00c306200320063a00c206200320224110763b01c006200342003703f00720034280a0e5b9c291013703e8072003200341c0066a3602e0032003200341c0066a3602a0052003200341a0056a3602c80a2003200341e0036a3602c40a2003200341e8076a3602c00a20034188096a200341c0066a200341c00a6a10fd02024002402003280288094101470d0020034194096a280200210f20034190096a280200210e20032d008f09211120032d008e09211020032d008d09210d20032d008c0921010c010b41042101024020034188096a41086a2903004201520d0020034188096a41106a290300210520032802a0052102200341f80a6a20034188096a41186a290300370300200341f00a6a2005370300200341c00a6a41086a41003a0000200341c90a6a2002290000370000200341d10a6a200241086a290000370000200341d90a6a200241106a290000370000200341e10a6a200241186a290000370000200341023a00c00a200341c00a6a10e0010b0b200141ff01714104470d184112210d410321010240200a41808080054d0d00410c210f4193abc300210e410321100c190b0240200b4180a0014d0d00410421104110210f419fabc300210e0c190b20034180056a41186a2206420037030020034180056a41106a2201420037030020034180056a41086a2202420037030020034200370380054196adc300ad42808080809001842205100c222229000021182022290008212a202210232002202a370300200320183703800541b0e1c300ad4280808080a001842218100c2224290000212a20034190026a41086a2222202441086a2900003703002003202a37039002202410232001200329039002222a37030020032003290380053703c00a200320022903003703c80a2003202a3703d00a200320222903003703d80a200341e8016a200341c00a6a412010cd0120032802ec01210d20032802e801210e20064200370300200142003703002002420037030020034200370380052005100c222429000021052024290008212a202410232002202a37030020032005370380052018100c222429000021052022202441086a2900003703002003200537039002202410232001200329039002220537030020032003290380053703c00a200320022903003703c80a200320053703d00a200320222903003703d80a2003200d41e807200e1b220141016a36028809200341c00a6aad428080808080048420034188096aad4280808080c00084100e2003200a360290092003200936028c0920032007360288092003200b3602c80a200320083602c40a2003200c3602c00a200341e8076a2001410120034188096a200341c00a6a108a03200341c00a6a41186a2224200341c0066a41186a290300370300200341c00a6a41106a2206200341c0066a41106a290300370300200341c00a6a41086a2207200341c0066a41086a290300370300200320032903c0063703c00a20034188096a2001108c0320033502900921052003280288092122412010212202450d32200220032903c00a370000200241186a2024290300370000200241106a2006290300370000200241086a200729030037000020054220862022ad842002ad4280808080800484100e200210230240200328028c09450d00202210230b200341083a00c00a200341c00a6a41086a200136020041002102200341003602c40a200341c00a6a10e0010c030b41002102200041003602040240202241ff01710d00202441ff01714101460d040b2000410c6a410236020020004101360200200424000f0b02400240202241ff017122020d004102210641002124410021070c010b200341c00a6a2006202220021b2224108d0320032802c00a220220032802c80a108e0341ff01712101024020032802c40a450d00200210230b4102210241022001410171200141024622011b21060240024020010d0020064101710d01418024212441032106410f21224184abc3002101410021070c020b41e5aac300210141112122410021074100210202400240024020060e03000201000b200341d40a6a4101360200200342013702c40a200341a4c5c6003602c00a2003410436028c09200341c8abc30036028809200320034188096a3602d00a200341c00a6a419ca8c700103a000b41f6aac3002101410e2122410121020b4180242124410321060c010b200341c00a6a2024108b03024020032d00c00a22064104470d00200342003703d80a200342003703d00a200342003703c80a200342003703c00a4196adc300ad4280808080900184222c100c220229000021052002290008211820021023200320183703c80a200320053703c00a41a4e2c300ad4280808080a00184222d100c2202290000210520034190026a41086a2201200241086a29000037030020032005370390022002102320034180056a41086a20032903c80a37030020034180056a41106a221c200329039002220537030020034180056a41186a221d2001290300370300200320053703d00a200320032903c00a37038005200341c00a6a20034180056a108f0320032802c00a2202410420021b211a024020032902c40a420020021b222b422088a7221b450d00201a201b410c6c6a2117201a211503400240201541086a22162802002207450d00201528020021024100210141002122034002400240024020242002280200460d0020010d01410021010c020b200141016a21010c010b202220016b220620074f0d1a200341c00a6a41206a220820022001415c6c6a220641206a2209280200360200200341c00a6a41186a220a200641186a220b290200370300200341c00a6a41106a220c200641106a220d290200370300200341c00a6a41086a220e200641086a220f290200370300200320062902003703c00a200241206a22102802002111200241186a22122902002105200241106a22132902002118200241086a2214290200212a20062002290200370200200f202a370200200d2018370200200b200537020020092011360200201020082802003602002012200a2903003702002013200c2903003702002014200e290300370200200220032903c00a3702000b200241246a21022007202241016a2222470d000b2001450d002016280200200720016b2202490d00201620023602000b2015410c6a22152017470d000b0b2003201a360288092003202b37028c09200342003703d80a200342003703d00a200342003703c80a200342003703c00a202c100c220229000021052002290008211820021023200320183703c80a200320053703c00a202d100c2202290000210520034190026a41086a2201200241086a290000370300200320053703900220021023200341c00a6a4110722219200329039002370000201941086a200129030037000020034180056a41086a20032903c80a370300201c20032903d00a370300201d20032903d80a370300200320032903c00a37038005200341203602c40a200320034180056a3602c00a20034188096a200341c00a6a109003202ba721060240201b450d00201b410c6c2101201a210203400240200241046a2802002222450d00202241246c450d00200228020010230b2002410c6a2102200141746a22010d000b0b02402006450d002006410c6c450d00201a10230b200342003703d80a200342003703d00a200342003703c80a200342003703c00a4196adc300ad4280808080900184222c100c220229000021052002290008211820021023200320183703c80a200320053703c00a41fcdfc300ad4280808080f00184222d100c2202290000210520034190026a41086a221b200241086a2900003703002003200537039002200210232019200329039002370000201941086a221d201b29030037000020034180056a41086a221e20032903c80a37030020034180056a41106a221f20032903d00a37030020034180056a41186a222020032903d80a370300200320032903c00a37038005200341c00a6a20034180056a108f0320032802c00a2202410420021b211a024020032902c40a420020021b222b422088a7221c450d00201a201c410c6c6a2117201a211503400240201541086a22162802002207450d00201528020021024100210141002122034002400240024020242002280200460d0020010d01410021010c020b200141016a21010c010b202220016b220620074f0d1b200341c00a6a41206a220820022001415c6c6a220641206a2209280200360200200341c00a6a41186a220a200641186a220b290200370300200341c00a6a41106a220c200641106a220d290200370300200341c00a6a41086a220e200641086a220f290200370300200320062902003703c00a200241206a22102802002111200241186a22122902002105200241106a22132902002118200241086a2214290200212a20062002290200370200200f202a370200200d2018370200200b200537020020092011360200201020082802003602002012200a2903003702002013200c2903003702002014200e290300370200200220032903c00a3702000b200241246a21022007202241016a2222470d000b2001450d002016280200200720016b2202490d00201620023602000b2015410c6a22152017470d000b0b2003201a360288092003202b37028c09200342003703d80a200342003703d00a200342003703c80a200342003703c00a202c100c220229000021052002290008211820021023200320183703c80a200320053703c00a202d100c22022900002105201b200241086a2900003703002003200537039002200210232019200329039002370000201d201b290300370000201e20032903c80a370300201f20032903d00a370300202020032903d80a370300200320032903c00a37038005200341203602c40a200320034180056a3602c00a20034188096a200341c00a6a109003202ba721060240201c450d00201c410c6c2101201a210203400240200241046a2802002222450d00202241246c450d00200228020010230b2002410c6a2102200141746a22010d000b0b02402006450d002006410c6c450d00201a10230b200342003703d80a200342003703d00a200342003703c80a200342003703c00a4196adc300ad42808080809001842205100c220229000021182002290008212a200210232003202a3703c80a200320183703c00a41bce0c300ad4280808080e000842218100c2202290000212a20034190026a41086a2206200241086a2900003703002003202a37039002200210232019200329039002370000201941086a2209200629030037000020034180056a41086a220a20032903c80a37030020034190056a220b20032903d00a37030020034198056a220c20032903d80a370300200320032903c00a37038005200341c00a6a20034180056a10910320032802c00a2202410420021b2107024020032902c40a420020021b222a422088a72208450d002008412c6c2101200721020340024020022802002024470d00200241246a22222802004102460d00202241003602000b2002412c6a2102200141546a22010d000b0b200342003703d80a200342003703d00a200342003703c80a200342003703c00a2005100c220229000021052002290008212b200210232003202b3703c80a200320053703c00a2018100c220229000021052006200241086a290000370300200320053703900220021023201920032903900237000020092006290300370000200a20032903c80a370300200b20032903d00a370300200c20032903d80a370300200320032903c00a37038005200341c00a6a2007200810d30220034180056aad428080808080048420033502c80a42208620032802c00a2201ad84100e202aa72102024020032802c40a450d00200110230b02402002450d002002412c6c450d00200710230b20034188096a2024108c03200341c00a6a2003280288092202200328029009222210e101024020032d00c00a2201450d002022ad4220862002ad8410110b200341e0036a41186a200341d90a6a2900002205370300200341e0036a41106a200341d10a6a2900002218370300200341e0036a41086a200341c90a6a290000222a370300200320032900c10a222b3703e003200320053703d80a200320183703d00a2003202a3703c80a2003202b3703c00a0240024020014101460d00200341c0066a41186a4200370300200341c0066a41106a4200370300200341c0066a41086a4200370300200342003703c0060c010b200341c0066a41186a20032903d80a370300200341c0066a41106a20032903d00a370300200341c0066a41086a20032903c80a370300200320032903c00a3703c0060b0240200328028c09450d00200210230b200342003703f00720034280a0e5b9c291013703e8072003200341c0066a3602a00520034188096a200341c0066a200341e8076a200341a0056a10ff0202402003290388094201520d002003290390092105200341f80a6a20034188096a41106a290300370300200341f00a6a2005370300200341c00a6a41086a41003a0000200341c90a6a20032903c006370000200341d10a6a200341c0066a41086a290300370000200341d90a6a200341c0066a41106a290300370000200341e10a6a200341d8066a290300370000200341023a00c00a200341c00a6a10e0010b200341083a00c00a200341c00a6a41086a202436020041002102200341003602c40a200341c00a6a10e0010c030b200341c00a6a41086a280200212220032802c40a210120032d00c20a210220032d00c10a410874212420032d00c30a41187421070b20004100360204200041146a2022360200200041106a20013602002000410c6a2007200241ff01714110747220247220067236020020004101360200200424000f0b0240202241ff017122020d00410221020c150b200341c00a6a2007109203200341f0016a20032802c00a220120032802c80a10cd0120032802f401210820032802f0012124024020032802c40a450d00200110230b2006202220021b2101024020244101470d004100210220082001460d150b200341c00a6a200110920320032802c00a210220033502c80a2105200320073602880920054220862002ad8420034188096aad4280808080c00084100e024020032802c40a450d00200210230b410021020b200020023602040b20002002360200200424000f0b200341f80a6a2001413c6a280200360200200341f00a6a200141346a290200370300200341e80a6a2001412c6a290200370300200341c00a6a41206a200141246a290200370300200341c00a6a41186a2001411c6a290200370300200341c00a6a41106a200141146a290200370300200341c00a6a41086a2001410c6a290200370300200320012902043703c00a20034188096a41206a200241206a28020036020020034188096a41186a200241186a29020037030020034188096a41106a200241106a29020037030020034188096a41086a200241086a29020037030020032002290200370388092000200341c00a6a20034188096a109303200424000f0b200341c00a6a200141086a41a80210a1051a20034188096a41206a200241206a28020036020020034188096a41186a200241186a29020037030020034188096a41106a200241106a29020037030020034188096a41086a200241086a29020037030020032002290200370388092000200341c00a6a20034188096a109403200424000f0b200341c00a6a200141046a41c40010a1051a20034188096a41206a200241206a28020036020020034188096a41186a200241186a29020037030020034188096a41106a200241106a29020037030020034188096a41086a200241086a29020037030020032002290200370388092000200341c00a6a20034188096a109503200424000f0b2002411a6a2901002105200241196a2d00002124200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f01002116200141216a2900002118200141206a2d000021172001411d6a2f000021192001411c6a2d0000211a200141196a2f0000211b200141186a2d0000211c200141156a2f0000211d200141146a2d0000211e200141116a2f0000211f200141106a2d000021202001410d6a2f000021212001410c6a2d00002123200141096a2f0000212520022d0001212220022d0000210220012d001f212620012d001b212720012d0017212820012d0013212920012d000f213120012d000b213202400240024002400240200141086a2d00000e0400010203000b200341c00a6a41146a4101360200200342013702c40a200341a4c5c6003602c00a2003410436028c09200341cccec60036028809200320034188096a3602d00a200341c00a6a419ca8c700103a000b02400240024002400240200241ff01710d00202241ff01714101460d010b200341023a0088090c010b200320053703d80a200320243a00d70a200320063a00d60a200320073b01d40a200320083a00d30a200320093a00d20a2003200a3b01d00a2003200b3a00cf0a2003200c3a00ce0a2003200d3b01cc0a2003200e3a00cb0a2003200f3a00ca0a200320103b01c80a200320113a00c70a200320123a00c60a200320133b01c40a200320143a00c30a200320153a00c20a200320163b01c00a20034188096a200341c00a6a10d80220032d0088094104460d010b2003290388092105200041146a20034190096a2802003602002000410c6a2005370200410121030c010b410021030b200041003602040c020b02400240024002400240200241ff01710d00202241ff01714101460d010b200341023a0088090c010b200320183703d80a200320173a00d70a200320263a00d60a200320193b01d40a2003201a3a00d30a200320273a00d20a2003201b3b01d00a2003201c3a00cf0a200320283a00ce0a2003201d3b01cc0a2003201e3a00cb0a200320293a00ca0a2003201f3b01c80a200320203a00c70a200320313a00c60a200320213b01c40a200320233a00c30a200320323a00c20a200320253b01c00a20034188096a200341c00a6a10d80220032d0088094104460d010b2003290388092105200041146a20034190096a2802003602002000410c6a2005370200410121030c010b410021030b200041003602040c010b024002400240200241ff01710d00202241ff01714101470d00200141c8006a290300212c200141c0006a290300212d200141386a290300212a200141306a290300212b200141d0006a2802002122200320053703d806200320243a00d706200320063a00d606200320073b01d406200320083a00d306200320093a00d2062003200a3b01d0062003200b3a00cf062003200c3a00ce062003200d3b01cc062003200e3a00cb062003200f3a00ca06200320103b01c806200320113a00c706200320123a00c606200320133b01c406200320143a00c306200320153a00c206200320163b01c0060240202b42ffffe883b1de1656202a420052202a501b0d004102210241162103410321014109212241f99dc20021240c020b200320183703a009200320173a009f09200320263a009e09200320193b019c092003201a3a009b09200320273a009a092003201b3b0198092003201c3a009709200320283a0096092003201d3b0194092003201e3a009309200320293a0092092003201f3b019009200320203a008f09200320313a008e09200320213b018c09200320233a008b09200320323a008a09200320253b018809200341c00a6a20034188096a10d90220034180026a20032802c00a220220032802c80a419ca8c70041004100108c012003280280022101024020032802c40a450d00200210230b41012102024020014101470d0041162103410321014117212241afacc50021240c020b200341c00a6a200341c0066a20034188096a202b202a4101108003024020032d00c00a22014104460d00200341c80a6a280200212220032802c40a212420032d00c30a210620032d00c20a210220032d00c10a21030c030b200341c00a6a20034188096a10d902200341f8016a20032802c00a220120032802c80a419ca8c70041004100108c0120032802f8012102024020032802c40a450d00200110230b024020024101460d00200341c00a6a20034188096a10d90220033502c80a210520032802c00a2101411010212202450d2d2002202b3700002002202a37000820024110412010252202450d2d2002202d370010200241186a202c3700002002412041c00010252202450d2d2002202236002020054220862001ad842002ad4280808080c00484100e20021023024020032802c40a450d00200110230b200341c00a6a41186a20034188096a41186a290300370300200341c00a6a41106a20034188096a41106a290300370300200341c00a6a41086a20034188096a41086a29030037030020032003290388093703c00a200341e8076a200341c00a6a10d80241002103200041003602040c040b200341c80a6a4117360200200341afacc5003602c40a200341013a00c20a200341832c3b01c00a4189c4c2004137200341c00a6a41c0c4c20041d0c4c2001034000b410221010b0b20004100360204200041146a2022360200200041106a20243602002000410c6a2006411874200241ff017141107472200341ff017141087472200172360200410121030b20002003360200200424000f0b202210b4022022102341833021030c340b1032000b200041003602042000410c6a41023602000c300b41c5a2c7004130418c94c700102d000b410221020c220b4101210741d5a4c6002106410821240c1d0b41808004210141d5a4c6002122410821240c1a0b200041003602042000410c6a410236020020004101360200200424000f0b200341e0036a41186a220b4200370300200341e0036a41106a22014200370300200341e0036a41086a22024200370300200342003703e00341bdadc500ad4280808080800184222b100c2209290000212c2009290008213520091023200220353703002003202c3703e00341c5adc500ad4280808080d00184222c100c220a290000213520034190026a41086a2209200a41086a2900003703002003203537039002200a10232001200329039002223537030020034180056a41086a220c200229030037030020034180056a41106a220d203537030020034180056a41186a220e2009290300370300200320032903e0033703800520034180016a20034180056a412010d70120034180016a41106a29030021352003290388012137200328028001210a200b42003703002001420037030020024200370300200342003703e003202b100c220b290000212b200b2900082138200b1023200220383703002003202b3703e003202c100c220b290000212b2009200b41086a2900003703002003202b37039002200b10232001200329039002222b370300200c2002290300370300200d202b370300200e2009290300370300200320032903e003370380052003427f20354200200a1b222b2005202a7d2018202d54ad7d7c20374200200a1b222c2018202d7d7c222d202c542202ad7c222c2002202c202b54202c202b511b22021b3703c80a2003427f202d20021b3703c00a200341c00a6a210220034180056a21010c150b2000410c6a41023602000c130b20032802c80a210220032802c40a210720032802c00a21060c080b102c000b200620074184d9c4001030000b200620074184d9c4001030000b20004100360204200041146a4111360200200041106a4183aac0003602002000410c6a200236020020004101360200200424000f0b02402008450d00200c10230b02402009450d00200710230b20004100360204200041146a200f360200200041106a200e3602002000410c6a2011411874201041ff017141107472200d41ff017141087472200141ff01717236020020004101360200200424000f0b0240200b450d00200810230b200a450d00200910230b20032903c0062105200041146a200341c8066a2802003602002000410c6a2005370200410121020b2000410036020420002002360200200424000f0b200341c00a6a2012200e10ae0220032802c00a2101200320032802c80a36028c0920032001360288092006200220034188096a10c802024020032802c40a450d00200110230b02402007450d00200610230b0240200542ffffff3f83500d00201010230b0240200d450d00200f10230b0240200a450d00200a410c6c2102200c210303400240200341046a280200450d00200328020010230b2003410c6a2103200241746a22020d000b0b0240200b450d00200b410c6c450d00200c10230b2000410036020420004100360200200424000f0b0b20004100360204200041146a2003360200200041106a20023602002000410c6a202420227236020020004101360200200424000f0b024020032802cc0a2202450d00200241246c21012011210203400240024020022d0000222241044b0d0002400240024020220e050400010204040b2002410c6a280200450d03200241086a28020010230c030b2002410c6a280200450d02200241086a28020010230c020b2002410c6a280200450d01200241086a28020010230c010b200241086a280200450d00200241046a28020010230b200241246a21022001415c6a22010d000b0b024020032802c80a2202450d00200241246c450d00201110230b024020232024460d00034020061096030240200641046a2802002202450d00200241246c450d00200628020010230b200641f0006a2106200841907f6a22080d000b0b02402009450d00200941f0006c450d00200b10230b024020032802b40a2203450d00200341c4006c450d00201010230b410321220c040b20232024460d00200b200741f0006c6a212203402024220241046a2201109603200241f0006a21240240200241086a2802002202450d00200241246c450d00200128020010230b20222024470d000b0b02402009450d00200941f0006c450d00200b10230b200341a0056a41186a4200370300200341a0056a41106a4200370300200341a0056a41086a22024200370300200342003703a00541fea6c600ad4280808080a00184100c220129000021052002200141086a290000370300200320053703a00520011023419ca8c600ad4280808080e00084100c220129000821052001290000211820011023200341e8076a41106a2018370300200341e8076a41186a2005370300200341e8076a41086a2002290300370300200320032903a0053703e807200341c00a6a2010200f109703202a20033502c80a42208620032802c00a2202ad84100e024020032802c40a450d00200210230b024020032802b40a2203450d00200341c4006c450d00201010230b410021030c030b200741f0006c2102200b41046a2103034020031096030240200341046a2802002201450d00200141246c450d00200328020010230b200341f0006a2103200241907f6a22020d000b0b2009450d00200941f0006c450d00200b10230b200041146a200a360200200041106a200e3602002000410c6a200d41107420227241800e72360200410121030b2000200336020020004100360204200424000f0b410121020c020b2001ad42808080808004842002ad4280808080800284100e20032903c803212c20032903c003212b0b202a202f7c212d2022ad2135200341a0056a41106a2102024002400240202b202e56202c202f56202c202f5122011b0d00202b202e54202c202f5420011b450d02200341e0036a41186a220c4200370300200341e0036a41106a22094200370300200341e0036a41086a22014200370300200342003703e00341bdadc500ad42808080808001842237100c220a2900002138200a2900082139200a102320012039370300200320383703e00341c5adc500ad4280808080d001842238100c220b290000213920034190026a41086a220a200b41086a2900003703002003203937039002200b10232009200329039002223937030020034180056a41086a220d200129030037030020034180056a41106a220e203937030020034180056a41186a220f200a290300370300200320032903e00337038005200341e8006a20034180056a412010d701200341e8006a41106a29030021392003290370213a2003280268210b200c42003703002009420037030020014200370300200342003703e0032037100c220c2900002137200c290008213b200c10232001203b370300200320373703e0032038100c220c2900002137200a200c41086a2900003703002003203737039002200c102320092003290390022237370300200d2001290300370300200e2037370300200f200a290300370300200320032903e003370380052003420020394200200b1b2237202e202b54ad202c202f7d7c7c203a4200200b1b222f202e202b7d223854ad7d222e202f20387d2238202f56202e203756202e2037511b22011b3703c80a20034200203820011b3703c00a200341c00a6a210120034180056a21090c010b200341e0036a41186a220c4200370300200341e0036a41106a22094200370300200341e0036a41086a22014200370300200342003703e00341bdadc500ad42808080808001842237100c220a2900002138200a2900082139200a102320012039370300200320383703e00341c5adc500ad4280808080d001842238100c220b290000213920034190026a41086a220a200b41086a2900003703002003203937039002200b10232009200329039002223937030020034180056a41086a220d200129030037030020034180056a41106a220e203937030020034180056a41186a220f200a290300370300200320032903e00337038005200341d0006a20034180056a412010d701200341d0006a41106a29030021392003290358213a2003280250210b200c42003703002009420037030020014200370300200342003703e0032037100c220c2900002137200c290008213b200c10232001203b370300200320373703e0032038100c220c2900002137200a200c41086a2900003703002003203737039002200c102320092003290390022237370300200d2001290300370300200e2037370300200f200a290300370300200320032903e003370380052003427f20394200200b1b2237202c202f7d202b202e54ad7d7c203a4200200b1b222f202b202e7d7c2238202f542201ad7c222e2001202e203754202e2037511b22011b3703c80a2003427f203820011b3703c00a200341c00a6a210120034180056a21090b2009ad42808080808004842001ad4280808080800284100e0b202d20357c212d200320183703a0052003202c3703b8052003202b3703b005200320053703a80520032802ac0a2101200341e0036a41186a200241086a290300222e370300200341e0036a41206a2209200241106a29030037030020034188046a220a200241186a29030037030020034190046a220b200241206a290300370300200320053703e803200320183703e00320032002290300222f3703f00302400240427f2018202f7c222f202f20185422022005202e7c2002ad7c222e200554202e2005511b22021b222f4280c8afa025544100427f202e20021b2235501b0d00200341e0036a41106a290300212f200b2903002135200a29030021372009290300213820032903e803213920032903e003213a4201212e20032903f803213b0c010b4200212e0240202f203584500d00202f203510eb01200341f80a6a2035370300200341f00a6a202f370300200341c00a6a41086a41013a0000200341c90a6a2001290000370000200341d10a6a200141086a290000370000200341d90a6a200141106a290000370000200341e10a6a200141186a290000370000200341023a00c00a200341c00a6a10e0010b0b202d202a512102202d202a54210920034190086a203837030020034198086a2037370300200341f8076a2039370300200341a0086a203537030020034180086a202f3703002003203b37038808200320343703a8082003203a3703f0072003200841002030420151220a1b3a00b408200320074100200a1b3602b0082003202e4201512207ad3703e8070240024020070d002006ad4220862024ad8410110c010b200320063602c40a200320243602c00a200341f0076a200341c00a6a1098030b2022200920021b2102024020032802b40a450d00202410230b427f202d20021b212a427f203620021b212d202e420152210202400240024020304201510d0020020d004103212220034188096a21020c010b20304201522002410173720d0141042122200341c0066a21020b200241046a20223a0000200241056a20032903a002370000200241003a00002002410d6a200341a8026a290300370000200241156a200341b0026a2903003700002002411d6a200341b8026a290300370000200210e0010b0240202d202a844200520d00200341f80a6a2005370300200341f00a6a2018370300200341c00a6a41086a41003a0000200341c90a6a2001290000370000200341d10a6a200141086a290000370000200341d90a6a200141106a290000370000200341e10a6a200141186a290000370000200341023a00c00a200341c00a6a10e0010b200341880b6a202c370300200341800b6a202b370300200341f80a6a2005370300200341f00a6a2018370300200341c00a6a41086a41033a0000200341c90a6a20032903a002370000200341d10a6a200341a0026a41086a290300370000200341d90a6a200341b0026a290300370000200341e10a6a200341b8026a290300370000200341023a00c00a200341c00a6a10e001410021020b2000200236020020004100360204200424000f0b024020032802e403450d00200610230b20024104470d00200341c80a6a2017360200200341013a00c40a200341013a00c00a200341c00a6a10e0012000410036020420004100360200200424000f0b20004100360204200041146a2024360200200041106a20223602002000410c6a200141808004712002724180087236020020004101360200200424000f0b024020032802a405450d00200810230b200241ff01714104470d00200341e80a6a2019360200200341cd0a6a200341c8066a290300370000200341d50a6a200341d0066a290300370000200341dd0a6a200341d8066a290300370000200341003a00c40a200341013a00c00a200320032903c0063700c50a200341c00a6a10e0012000410036020420004100360200200424000f0b20004100360204200041146a2024360200200041106a20063602002000410c6a20014118742007411074418080fc07717220224108744180fe037172200241ff01717236020020004101360200200424000f0b41002108200241ff01714104470d00200341f00a6a4200370300200341e80a6a4280a094a58d1d370300200341c00a6a41106a200341c0066a41086a290300370300200341c00a6a41186a200341c0066a41106a290300370300200341c00a6a41206a200341c0066a41186a290300370300200342013703c00a200320032903c0063703c80a411010212202450d0320024110412010252202450d022002200341c00a6a41086a2208290000370000200241186a200841186a290000370000200241106a200841106a290000370000200241086a200841086a2900003700002002412041c00010252202450d0220024280a094a58d1d370020200241286a4200370000200aad4220862009ad842002ad4280808080800684100e2002102341042102410121080b024020032802e403450d00200910230b02402008450d00200341e80a6a2017360200200341cd0a6a200341f0076a290300370000200341d50a6a200341f8076a290300370000200341dd0a6a20034180086a290300370000200341003a00c40a200341013a00c00a200320032903e8073700c50a200341c00a6a10e0010c040b200241ff01714104460d030b20004100360204200041146a2001360200200041106a20223602002000410c6a2007411874202441ff017141107472200641ff017141087472200241ff01717236020020004101360200200424000f0b102a000b1033000b2000410036020420004100360200200424000f0b02402007450d00202410230b0240200b450d00200a10230b2008450d052008410c6c450d05200d10230c050b200b450d00200a10230b2007450d010b202410230b2001450d00200210230b4191ddc4002102411d2101410221220b20224110742108410321070b02402009450d00200610230b20004100360204200041146a2001360200200041106a20023602002000410c6a20082007723602000b410121030b20002003360200200424000f0b20004100360204200041146a410b360200200041106a41a181c3003602002000410c6a200336020020004101360200200424000b130020004101360204200041e8b9c2003602000b930a03057f017e047f230041a0016b22012400200141e8006a41186a22024200370300200141e8006a41106a22034200370300200141e8006a41086a220442003703002001420037036841db97c700ad4280808080f00084100c220529000021062004200541086a290000370300200120063703682005102341bcbcc300ad4280808080c00184100c2205290000210620014188016a41086a2207200541086a29000037030020012006370388012005102320032001290388012206370300200141c8006a41086a2004290300370300200141c8006a41106a2006370300200141c8006a41186a200729030037030020012001290368370348200141106a200141c8006a412010cd0120012802142105200128021021082002200041186a2900003703002003200041106a2900003703002004200041086a290000370300200120002900003703684180cdc200ad4280808080800184100c22002900002106200141186a41086a200041086a290000370300200120063703182000102341b4a5c200ad4280808080e00184100c220029000021062007200041086a29000037030020012006370388012000102320012005410020081b3602382001200141386aad4280808080c00084100d22002900003703980120001023200141d4006a22052001413c6a360200200141003a0058200120014198016a41086a220736024c2001200141386a360250200120014198016a360248200141286a200141c8006a1065024002400240024002400240412010212200450d0020002001290368370000200041186a2002290300370000200041106a2003290300370000200041086a200429030037000020012000ad4280808080800484100d220429000037039801200410232005200041206a360200200141003a0058200120003602502001200736024c200120014198016a360248200141386a200141c8006a1065200010232001280230220741206a2203200128024022086a2204417f4c0d01200128023821092001280228210a024002402004450d00200410212200450d022004410f4d0d01200421020c050b200441017422004110200041104b1b2202102122000d040c060b200441017422024110200241104b1b220241004e0d020c040b1033000b1032000b20042002460d0020002004200210252200450d020b20002001290318370000200041086a200141186a41086a2903003700000240024020024170714110460d00200221050c010b200241017422054120200541204b1b22054100480d0120022005460d0020002002200510252200450d020b2000200129038801370010200041186a20014188016a41086a29030037000002400240200541606a2007490d00200521020c010b2007415f4b0d01200541017422022003200220034b1b22024100480d0120052002460d0020002005200210252200450d020b200041206a200a200710a1051a02400240200220036b2008490d00200221050c010b200320086a2003490d01200241017422052004200520044b1b22054100480d01024020020d00024020050d00410121000c020b200510212200450d030c010b20022005460d0020002002200510252200450d020b200020036a2009200810a1051a0240200128023c450d00200910230b0240200128022c450d00200a10230b200141086a2000200410cd012001200128020c41016a410120012802081b3602682004ad4220862000ad84200141e8006aad4280808080c00084100e02402005450d00200010230b200141a0016a24000f0b102c000b102a000b340020004180cdc20036020420004100360200200041146a4104360200200041106a4198bbc200360200200041086a42083702000bc60201037f230041106b22032400024002402002412c6c41046a2204417f4c0d000240024020040d00410121050c010b200410212205450d020b20034100360208200320043602042003200536020020022003106102402002450d002002412c6c210203402003200128020036020c20032003410c6a4104106202400240200141246a22042802004102470d00200341003a000c20032003410c6a410110620c010b200341013a000c20032003410c6a410110622003200141046a41201062024020042802004101460d00200341003a000c20032003410c6a410110620c010b200341013a000c20032003410c6a410110622003200141286a28020036020c20032003410c6a410410620b2001412c6a2101200241546a22020d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1032000b1033000b950202037f017e230041206b220324000240024020024106744104722204417f4c0d00200410212205450d0120034100360208200320043602042003200536020020022003106102402002450d002002410674210203400240024020012903004201510d00200341003a00102003200341106a410110620c010b200341013a00102003200341106a410110622003200141206a41201062200141086a29030021062003200141106a290300370318200320063703102003200341106a411010622003200141186a2903003703102003200341106a410810620b200141c0006a2101200241406a22020d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1032000b1033000b8c0301077f230041106b220324000240024002400240200141027441046a2204417f4c0d000240024020040d00410121050c010b200410212205450d020b2003410036020820032004360204200320053602002001200310610240024020010d002003280208210120032802042106200328020021070c010b200141027421084100200328020822016b21052003280204210403402000280200210902400240200420056a4104490d0020032802002107200421060c010b200141046a22072001490d05200441017422062007200620074b1b22064100480d050240024020040d00024020060d00410121070c020b2006102122070d010c080b2003280200210720042006460d0020072004200610252207450d070b2003200636020420032007360200200621040b200041046a2100200720016a20093600002003200141046a22013602082005417c6a21052008417c6a22080d000b0b20022902002001ad4220862007ad84100e02402006450d00200710230b200341106a24000f0b1032000b1033000b102c000b102a000b5c01017f200028020022012001280200417f6a3602000240200028020022012802000d000240200128020c450d002001410c6a10d602200028020021010b20012001280204417f6a360204200028020022002802040d00200010230b0bbf0201067f230041106b22022400024002402001410c6a2802002203417f4c0d0020012802042104200128020021050240024020030d0041002106410121070c010b20032106200310212207450d020b20072004200310a10521042002200141106a10b7022000410c6a2003360200200041086a20063602002000200436020420002005360200200041106a2002290300370200200041186a200241086a2802003602002000200129021c37021c200020012902243702242000412c6a2001412c6a290200370200200041346a200141346a2902003702002000413c6a2001413c6a290200370200200041c4006a200141c4006a290200370200200041cc006a200141cc006a290200370200200041d4006a200141d4006a290200370200200041dc006a200141dc006a290200370200200241106a24000f0b1032000b1033000bb50905037f017e027f047e017f23004190026b22022400200241d0006a200110d902200228025021032002200228025822043602fc01200220033602f80120024180016a2004ad4220862003ad841010108b010240024020022802800122040d00420021050c010b200228028401210602400240024020024180016a41086a28020022074110490d0020074170714110460d002007417c714120470d010b20024100360268200242013703602002410a360284022002200241f8016a360280022002200241e0006a36028c02200241a4016a4101360200200242013702940120024180c5c60036029001200220024180026a3602a0012002418c026a4184a5c20020024190016a10311a2002350268422086200235026084100a02402002280264450d00200228026010230b420021050c010b200441086a290000210820042900002109200441186a290000210a2004290010210b20042800202107420121050b2006450d00200410230b02402002280254450d00200310230b02400240024002402005500d0020024190016a41186a420037030020024190016a41106a2206420037030020024190016a41086a22034200370300200242003703900141e4dec400ad4280808080e00084100c220429000021052003200441086a29000037030020022005370390012004102341f3dec400ad4280808080e00084100c2204290000210520024180016a41086a220c200441086a29000037030020022005370380012004102320062002290380012205370300200241e0006a41086a2003290300370300200241e0006a41106a2005370300200241e0006a41186a200c2903003703002002200229039001370360200241386a200241e0006a412010cd01200241186a200a42004100200228023c410020022802381b220320076b2204200420034b1bad2205420010a605200241286a20054200200b420010a605200241086a42004200200b420010a6052002290310200229032084420052200241286a41086a2903002205200229030820022903187c7c220b200554720d0142002009200229032822057d220a200a2009562008200b7d2009200554ad7d220920085620092008511b22031b22084200200920031b220984500d01200242f6cacda397cddbb320370348200241c8006a2001200820094106109902200241c8016a2009370300200241c0016a200837030020024190016a41086a41003a000020024199016a2001290000370000200241a1016a200141086a290000370000200241a9016a200141106a290000370000200241b1016a200141186a2900003700002002410c3a00900120024190016a21010c020b200041163b0001200041086a410a360200200041046a41829ec200360200410321010c020b200242f6cacda397cddbb320370340200241c0006a2001109b0220024190016a200110d9022002350298014220862002280290012203ad8410110240200228029401450d00200310230b20024190016a41086a41013a000020024199016a2001290000370000200241a1016a200141086a290000370000200241a9016a200141106a290000370000200241b1016a200141186a2900003700002002410c3a00900120024190016a21010b200110e001410421010b200020013a000020024190026a24000bc60505017f017e017f017e047f230041e0006b220224004196cdc200ad4280808080f000842203100c22042900002105200241086a41086a200441086a29000037030020022005370308200410232003100c22042900002103200241186a41086a200441086a2900003703002002200337031820041023024002400240024002400240412010212204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a2900003700002004ad4280808080800484100f22012900002103200241386a41086a200141086a2900003703002002200337033820011023200241d4006a200441206a360200200241003a0058200220043602502002200241386a41106a36024c2002200241386a360248200241286a200241c8006a1065200410232002280230220641206a2201417f4c0d0120022802282107024002402001450d00200110212204450d022001410f4d0d01200121080c050b200141017422044110200441104b1b2208102122040d040c060b200141017422094110200941104b1b220841004e0d020c040b1033000b1032000b20012008460d0020042001200810252204450d020b20042002290308370000200441086a200241086a41086a2903003700000240024020084170714110460d00200821090c010b200841017422094120200941204b1b22094100480d0120082009460d0020042008200910252204450d020b20042002290318370010200441186a200241186a41086a29030037000002400240200941606a2006490d00200921080c010b2006415f4b0d01200941017422082001200820014b1b22084100480d0120092008460d0020042009200810252204450d020b200441206a2007200610a1051a2000200136020820002008360204200020043602000240200228022c450d00200710230b200241e0006a24000f0b102c000b102a000b130020004103360204200041c0c5c2003602000b130020004102360204200041e8c7c2003602000bb01105097f017e057f037e017f230041c0006b22032400024002400240024002400240024002402001280210220441016a22052004490d00200128020022062107024020064108490d00200641016a41037641076c21070b200520074101764d0d032005200741016a2207200520074b1b22050d01419ca1c0002108410021094104210a4100210b0c020b4194a0c000411c41b0a0c000102d000b024002400240024020054108490d00200541ffffffff01712005470d02200541037441076e21060c010b200541016a21060b417f2006417f6a6776220941086a2206200941056a2205490d04200941016a2207ad42307e220c422088a70d042006417c712206200ca76a22082006490d042008102122080d01102a000b4194a0c000411c41b0a0c000102d000b2009200741037641076c20094108491b210b200841ff01200510a00520066a210a20012802002106200128021021040b2001280204220541046a210d200620056a41016a210e2005280200417f7341808182847871210f2002280200211020012802082111024003400240200f0d000340200d200e4f0d03201141c0016a2111200d2802002106200d41046a2205210d2006418081828478712206418081828478460d000b200641808182847873210f2005210d0b2003201041086a29030022122010290300220c852213200c4218898520134210868520134225897c221342a0cbbf9599b5a19f0a7c22142011200f6841037641306c6a221529001885201529000020148542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852015290008201342efcdddd088a580a21e7c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852015290010201342bed0fb8bf894dfa4327c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85420042adfed5e4d485fda8d800420010a605200341086a29030020032903007c2012200c7c85220ca72106410021050340200541046a2205200620097122076a2106200820076a280000418081828478712202450d000b200f417f6a21050240200820026841037620076a20097122066a2c00004100480d002008280200418081828478716841037621060b2005200f71210f200820066a200ca741197622053a00002006417c6a20097120086a41046a20053a0000200a200641306c6a220641286a201541286a290200370200200641206a201541206a290200370200200641186a201541186a290200370200200641106a201541106a290200370200200641086a201541086a290200370200200620152902003702000c000b0b200120043602102001200a360208200041003602002001200b20046b36020c200128020421052001200836020420012802002106200120093602002006450d040240200641086a200641056a490d00200641016aad42307e422088a71a0b200510230c040b200641016a21074100210541002106024003400240024020054101710d00200620074f0d0320062105200641016a21060c010b200641036a220520064922080d0220052007492209450d022007200641046a20081b200720091b21060b200128020420056a220520052802002205410776417f73418182840871200541fffefdfb07726a360200410121050c000b0b20012802042106200128020041016a220541044f0d01200641046a2006200510a2051a0c020b4194a0c000411c41b0a0c000102d000b200620056a20062800003600000b417f2106024002402001280200220541016a22102005490d00200228020021154100210f0340200f221141016a210f02402011200128020422096a2d0000418001470d0002400340200341106a201541086a29030022122015290300220c852213200c4218898520134210868520134225897c221342a0cbbf9599b5a19f0a7c22142001280208201141306c6a220d29001885200d29000020148542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85200d290008201342efcdddd088a580a21e7c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85200d290010201342bed0fb8bf894dfa4327c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85420042adfed5e4d485fda8d800420010a6052001280200210841002106200341106a41086a29030020032903107c2012200c7c85220ca7220e21050340200641046a2206200520087122076a2105200920076a280000418081828478712202450d000b0240200920026841037620076a20087122066a2c00004100480d002009280200418081828478716841037621060b20062008200e7122056b201120056b732008714104490d01200920066a22052d000021072005200ca741197622023a00002006417c6a20087120096a41046a20023a00000240200741ff01460d002001280208200641306c6a2206290200210c2006200d290200370200200641186a220529020021132005200d41186a2207290200370200200641106a220529020021122005200d41106a2208290200370200200641086a220529020021142005200d41086a2209290200370200200920143702002008201237020020072013370200200d200c370200200641286a2205290200210c2005200d41286a2207290200370200200629022021132006200d290220370220200d20133702202007200c370200200128020421090c010b0b2001280204220520116a41ff013a0000200520012802002011417c6a716a41046a41ff013a00002001280208200641306c6a2206200d290200370200200641086a200d41086a290200370200200641106a200d41106a290200370200200641186a200d41186a290200370200200641206a200d41206a290200370200200641286a200d41286a2902003702000c010b200920116a200ca741197622063a000020082011417c6a7120096a41046a20063a00000b200f2010470d000b200128020022064108490d010b200641016a41037641076c21060b200041003602002001200620012802106b36020c0b200341c0006a24000bbe4003047f017e027f230041e0006b22022400024002402000280200220341154b0d000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e16000102030405060708090a0b0c0d1514131211100f0e000b200241003a00402001200241c0006a41011062200041086a280200417f6a220341094b0d16024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a003c20012002413c6a4101106220022000410c6a2802003602402001200241c0006a410410620c1f0b200241013a003c20012002413c6a410110622000410c6a2802002103200041146a28020022002001106120012003200010620c1e0b200241023a003c20012002413c6a410110622002200041106a2903003703402001200241c0006a410810620c1d0b200241033a003c20012002413c6a410110622000410c6a2802002103200041146a28020022002001106120012003200010620c1c0b200241043a003c20012002413c6a410110622000410c6a2802002103200041146a28020022002001106120012003200010620c1b0b200241053a003c20012002413c6a4101106202402000410c6a2802004101460d00200241003a003c20012002413c6a410110620c1b0b200241013a003c20012002413c6a410110622002200041106a2802003602402001200241c0006a410410622002200041146a2802003602402001200241c0006a410410620c1a0b200241063a003c20012002413c6a410110622000410c6a2802002103200041146a2802002200200110612000450d192003200041186c6a2104034020032802002100200341086a28020022052001106120012000200510622003410c6a2802002100200341146a2802002205200110612001200020051062200341186a22032004470d000c1a0b0b200241073a003c20012002413c6a410110622000410c6a2802002103200041146a2802002200200110612000450d1820032000410c6c6a2104034020032802002100200341086a28020022052001106120012000200510622003410c6a22032004470d000c190b0b200241083a003c20012002413c6a410110622000410c6a2802002103200041146a28020022002001106120012003200010620c170b200241093a003c20012002413c6a410110620c160b200241013a00402001200241c0006a41011062200110de020c150b200241023a00402001200241c0006a41011062200241003a00402001200241c0006a410110620240024002400240200041086a290300220642c000540d00200642808001540d012006428080808004540d024108200679a741037622036b4104490d032002411320034102746b3a003c20012002413c6a41011062200220002903082206370300200341786a21000340200220063c003c20012002413c6a4101106220064208882106200041016a22032000492105200321002005450d000b200220063703002006500d18200241206a41146a410b3602002002412c6a4111360200200241086a41146a41033602002002200236023c200241a8e5c20036025c200241c0006a41146a41003602002002420337020c2002418ca7c700360208200241113602242002419ca8c70036025020024201370244200241b0e5c2003602402002200241206a3602182002200241c0006a3602302002200241dc006a36022820022002413c6a360220200241086a419ca8c700103a000b20022006a74102743a003c20012002413c6a410110620c170b20022006a74102744101723b01402001200241c0006a410210620c160b20022006a74102744102723602402001200241c0006a410410620c150b41f0e4c2004136418c94c700102d000b200241033a00402001200241c0006a4101106220002d0004417f6a220341034b0d13200041046a21050240024002400240024020030e0400010203000b200241003a003c20012002413c6a410110622002200041086a280200360240200241c0006a21000c030b200241013a003c20012002413c6a410110622001200541016a412010622002200041286a280200360240200241c0006a21000c020b200241023a003c20012002413c6a410110622002200041086a280200360240200241c0006a21000c010b200241033a003c20012002413c6a410110622001200541016a412010622002200041286a280200360240200241c0006a21000b20012000410410620c130b200241043a00402001200241c0006a41011062200041086a22032d0000417f6a220541034b0d120240024002400240024020050e0400010203000b200241003a003c20012002413c6a410110622001200341016a41201062200041306a2103200241dc006a21000c030b200241013a003c20012002413c6a410110622001200341016a412010622002200041306a3602002002200110db01200041c0006a2103200241086a21000c020b200241023a003c20012002413c6a410110622001200341016a412010622001200341216a41201062200041d0006a2103200241206a21000c010b200241033a003c20012002413c6a410110622001200341016a41201062200041306a2103200241c0006a21000b200020033602002000200110db010c120b200241053a00402001200241c0006a41011062200241003a00402001200241c0006a41011062200028020421032000410c6a2802002200200110612000450d112003200041f0006c6a21070340412010212200450d1320002003290010370000200041186a200341286a290000370000200041106a200341206a290000370000200041086a200341186a2900003700002001200041201062200010232003200110ed01412010212200450d1320002003290030370000200041186a200341c8006a290000370000200041106a200341c0006a290000370000200041086a200341386a290000370000200120004120106220001023412010212200450d13200341f0006a210420002003290050370000200041186a200341e8006a290000370000200041106a200341e0006a290000370000200041086a200341d8006a29000037000020012000412010622000102320032802042100200328020c22032001106102402003450d00200341246c21030340200241c0006a200010e0022001200228024022052002280248106202402002280244450d00200510230b200041246a21002003415c6a22030d000b0b2004210320042007470d000c120b0b200241063a00402001200241c0006a41011062200041086a22052d0000417f6a220341174b0d1002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e18000102030405060708090a0b0c0d0e0f1011121314151617000b200241003a00402001200241c0006a410110622001200541016a412010622002200041306a360240200241c0006a200110db0120002d0029220041024b0d2702400240024020000e03000102000b200241003a00402001200241c0006a410110620c290b200241013a00402001200241c0006a410110620c280b200241023a00402001200241c0006a410110620c270b200241013a00402001200241c0006a410110622002200041106a360240200241c0006a200110db010c260b200241023a00402001200241c0006a410110622002200041106a360240200241c0006a200110db010c250b200241033a00402001200241c0006a410110620c240b200241043a00402001200241c0006a410110620240024002402000410c6a280200220341c000490d00200341808001490d012003418080808004490d02200241033a003c20012002413c6a410110622002200028020c3602402001200241c0006a410410620c260b200220034102743a003c20012002413c6a410110620c250b200220034102744101723b01402001200241c0006a410210620c240b200220034102744102723602402001200241c0006a410410620c230b200241053a00402001200241c0006a410110622000410c6a2802002103200041146a2802002200200110612000450d222000410574210003402001200341201062200341206a2103200041606a22000d000c230b0b200241063a00402001200241c0006a410110620c210b200241073a00402001200241c0006a4101106220052d0001220041024b0d2002400240024020000e03000102000b200241003a00402001200241c0006a410110620c220b200241013a00402001200241c0006a410110620c210b200241023a00402001200241c0006a410110620c200b200241083a00402001200241c0006a410110622001200541016a412010620c1f0b200241093a00402001200241c0006a410110622000410c6a200110ed010c1e0b2002410a3a00402001200241c0006a410110620c1d0b2002410b3a00402001200241c0006a410110620c1c0b2002410c3a00402001200241c0006a410110622000410c6a2802002103200041146a2802002200200110612000450d1b2000410574210003402001200341201062200341206a2103200041606a22000d000c1c0b0b2002410d3a00402001200241c0006a410110622001200541016a412010620c1a0b2002410e3a00402001200241c0006a410110620c190b2002410f3a00402001200241c0006a4101106220022000410c6a2802003602402001200241c0006a41041062200041106a2802002103200041186a28020022002001106120012003200041027410620c180b200241103a00402001200241c0006a4101106220022000410c6a2802003602402001200241c0006a41041062200041106a2802002103200041186a2802002200200110612000450d172003200041246c6a2100034020012003412010622002200341206a2802003602402001200241c0006a410410622000200341246a2203470d000c180b0b200241113a00402001200241c0006a4101106220022000410c6a2802003602402001200241c0006a410410620c160b200241123a00402001200241c0006a410110622001200541016a4120106220022000412c6a2802003602402001200241c0006a410410620c150b200241133a00402001200241c0006a410110622002200041106a360240200241c0006a200110db010c140b200241143a00402001200241c0006a410110622000410c6a200110ed010c130b200241153a00402001200241c0006a410110622001200541016a412010620c120b200241163a00402001200241c0006a410110622000410c6a2802002103200041146a2802002205200110612001200320054101741062200041186a20011081022001200041e0016a413010622002200041d8016a2802003602402001200241c0006a410410620c110b200241173a00402001200241c0006a410110622000410c6a2802002103200041146a2802002205200110612001200320054101741062200041186a20011081022001200041e0016a413010622002200041d8016a2802003602402001200241c0006a410410620c100b200241073a00402001200241c0006a41011062200110de020c0f0b200241083a00402001200241c0006a4101106202402000280204450d00200241003a003c20012002413c6a410110622001200041106a412010622001200041306a412010622001200041d0006a412010622001200041f0006a41201062200120004190016a41201062200028020421032000410c6a28020022002001106120012003200010620c0f0b200241013a003c20012002413c6a410110620c0e0b200241093a00402001200241c0006a41011062200241003a00402001200241c0006a41011062200041046a200110ed010c0d0b2002410a3a00402001200241c0006a41011062200241003a00402001200241c0006a41011062200028020421032000410c6a28020022002001106120012003200010620c0c0b2002410b3a00402001200241c0006a41011062200241003a00402001200241c0006a41011062200220002802043602402001200241c0006a41041062200041086a2802002103200041106a2802002205200110612001200320051062200041146a28020021032000411c6a28020022052001106102402005450d0020032005410c6c6a2107034020032802002105200341086a28020022042001106120012005200410622003410c6a22032007470d000b0b2002200041206a2802003602402001200241c0006a410410622002200041246a2802003602402001200241c0006a410410622001200041286a41c00010620c0b0b2002410c3a00402001200241c0006a41011062200110de020c0a0b2002410d3a00402001200241c0006a410110622000280204417f6a220341014b0d09024020030e020009000b200241003a00402001200241c0006a41011062200041086a2802002104200041106a2802002200200110612000450d09200420004188026c6a2108034020042205200110e10220052802f001210020052802f80122032001106102402003450d002000200341c1006c6a2103034020024102410120002d00004101461b3a00402001200241c0006a410110622001200041016a41c0001062200041c1006a22002003470d000b0b20054180026a28020022034103762100024002402003418004490d002000410274210402402003418080084f0d00200220044101723b01402001200241c0006a410210620c020b200220044102723602402001200241c0006a410410620c010b200220004102743a003c20012002413c6a410110620b20054188026a210420052802fc0121070240024020000d00410021050c010b410121052000410820034107716b22034d0d0041024101200020036b22004107711b20004103766a21050b200120072005106220042008470d000c0a0b0b200241153a00402001200241c0006a4101106220002d0004417f6a220341024b0d08200041046a210502400240024020030e03000102000b200241003a003c20012002413c6a41011062200041086a280200200110dd020c0a0b200241013a003c20012002413c6a410110622001200541016a412010620c090b200241023a003c20012002413c6a410110622001200541016a41201062200041286a280200200110dd020c080b200241143a00402001200241c0006a41011062200110de020c070b200241133a00402001200241c0006a41011062200041086a22052d0000417f6a220341024b0d0602400240024020030e03000102000b200241003a003c20012002413c6a410110620c080b200241013a003c20012002413c6a410110622001200541016a412010620c070b200241023a003c20012002413c6a410110622001200541016a41201062200041306a29030021062002200041386a290300370348200220063703402001200241c0006a41101062200041c0006a29030021062002200041c8006a290300370348200220063703402001200241c0006a411010622002200041d0006a2802003602402001200241c0006a410410620c060b200241123a00402001200241c0006a4101106220002d0004417f6a220341084b0d05200041046a210502400240024002400240024002400240024020030e09000102030405060708000b200241003a003c20012002413c6a410110622001200541016a41201062200041286a280200200110dd020c0d0b200241013a003c20012002413c6a410110622001200541016a412010622001200541216a412010620c0c0b200241023a003c20012002413c6a41011062200041086a2802002103200041106a28020022052001106102402005450d002005410574210503402001200341201062200341206a2103200541606a22050d000b0b200220002f01063b01402001200241c0006a41021062200220002802143602402001200241c0006a410410620c0b0b200241033a003c20012002413c6a410110622001200541016a412010620c0a0b200241043a003c20012002413c6a410110622001200541016a412010622001200541216a412010620c090b200241053a003c20012002413c6a410110622001200541016a412010620c080b200241063a003c20012002413c6a410110622001200541016a412010620c070b200241073a003c20012002413c6a410110620c060b200241083a003c20012002413c6a410110622001200541016a412010620c050b200241113a00402001200241c0006a41011062200041086a22052d0000417f6a2203410a4b0d040240024002400240024002400240024002400240024020030e0b000102030405060708090a000b200241003a003c20012002413c6a410110622001200541016a412010620c0e0b200241013a003c20012002413c6a410110622000410c6a200110e2020c0d0b200241023a003c20012002413c6a410110622000410c6a2802002103200041146a2802002200200110612000450d0c2003200041c4006c6a210503402001200341201062200241c0006a200341206a220010702001200228024022032002280248106202402002280244450d00200310230b2005200041246a2203470d000c0d0b0b200241033a003c20012002413c6a410110620c0b0b200241043a003c20012002413c6a410110622000410c6a200110ed012002200041106a360240200241c0006a200110db010c0a0b200241053a003c20012002413c6a4101106220022000410c6a2802003602402001200241c0006a410410620c090b200241063a003c20012002413c6a410110622000410c6a200110ed012002200041106a360240200241c0006a200110db010c080b200241073a003c20012002413c6a410110622000412c6a200110ed012001200541016a412010620c070b200241083a003c20012002413c6a410110622000410c6a200110ed012002200041106a2903003703402001200241c0006a410810620c060b200241093a003c20012002413c6a410110622000412c6a200110ed012001200541016a41201062200041306a200110e3020c050b2002410a3a003c20012002413c6a410110622001200541016a412010620c040b200241103a00402001200241c0006a4101106220002d0004417f6a220341044b0d03200041046a21040240024002400240024020030e050001020304000b200241003a003c20012002413c6a41011062200041086a2802002103200041106a2802002200200110612000450d07200041b0026c210003402003200110dd02200341b0026a2103200041d07d6a22000d000c080b0b200241013a003c20012002413c6a41011062200220002f01063b01402001200241c0006a41021062200041086a280200200110dd020c060b200241023a003c20012002413c6a41011062200220002f01063b01402001200241c0006a41021062200041086a2802002103200041106a28020022052001106102402005450d002005410574210503402001200341201062200341206a2103200541606a22050d000b0b0240024020002802144101460d00200241003a003c20012002413c6a410110620c010b200241013a003c20012002413c6a410110622002200041186a2802003602402001200241c0006a4104106220022000411c6a2802003602402001200241c0006a410410620b2000280220200110dd020c050b200241033a003c20012002413c6a41011062200220002f01263b01402001200241c0006a41021062200041286a2802002103200041306a28020022052001106102402005450d002005410574210503402001200341201062200341206a2103200541606a22050d000b0b200441016a21030240024020002802344101460d00200241003a003c20012002413c6a410110620c010b200241013a003c20012002413c6a410110622002200041386a2802003602402001200241c0006a4104106220022000413c6a2802003602402001200241c0006a410410620b20012003412010620c040b200241043a003c20012002413c6a41011062200220002f01263b01402001200241c0006a41021062200041286a2802002103200041306a280200220520011061200441016a210402402005450d002005410574210503402001200341201062200341206a2103200541606a22050d000b0b200220002802343602402001200241c0006a410410622002200041386a2802003602402001200241c0006a4104106220012004412010620c030b2002410f3a00402001200241c0006a4101106220002d0004417f6a220341064b0d02024002400240024002400240024020030e0700010203040506000b200241003a003c20012002413c6a41011062200041086a200110ed01200220002d00054101463a003c20012002413c6a410110622000410c6a2802002103200041146a2802002205200110612001200320051062200041186a2802002103200041206a28020022002001106120012003200010620c080b200241013a003c20012002413c6a41011062200041086a200110ed010c070b200241023a003c20012002413c6a410110622002200041086a2802003602402001200241c0006a410410620c060b200241033a003c20012002413c6a41011062200041086a2802002103200041106a2802002205200110612001200320051062200041146a28020021032000411c6a28020022002001106120012003200010620c050b200241043a003c20012002413c6a41011062200041c8006a200110ed012001200041046a220341016a41201062412010212200450d05200041186a200341396a290000370000200041106a200341316a290000370000200041086a200341296a2900003700002000200341216a2900003700002001200041201062200010230c040b200241053a003c20012002413c6a410110620c030b200241063a003c20012002413c6a41011062200041086a200110ed010c020b2002410e3a00402001200241c0006a41011062200241003a00402001200241c0006a410110620c010b200241013a00402001200241c0006a4101106220012000413c6a41201062200041dc006a200110e402200041bd016a200110e4022002200041086a2802003602402001200241c0006a410410622000410c6a2802002103200041146a28020022052001106102402005450d0020032005410c6c6a2107034020032802002105200341086a28020022042001106120012005200410622003410c6a22032007470d000b0b2002200041186a2802003602402001200241c0006a41041062412010212203450d01200341186a200041346a290000370000200341106a2000412c6a290000370000200341086a200041246a29000037000020032000411c6a2900003700002001200341201062200310230b200241e0006a24000f0b1033000b4a01037f230041106b220124002001410036020820014201370300200110de02200128020421022000200128020022032001280208106202402002450d00200310230b200141106a24000bc30202027f017e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120042001103e21000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d02200141a889c0004102200220006a4180016a410020006b104121000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d02200141a889c0004102200220006a4180016a410020006b104121000b20024180016a240020000f0b2003418001419889c0001044000b2003418001419889c0001044000bff1001067f230041106b22022400024002400240024002400240024002400240024020012d00000e06010402030500010b2002410036020820024201370300410110212203450d082002410136020420022003360200200341003a000020024101360208200141046a28020021042001410c6a2802002201200210610240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d08200541017422072006200720064b1b22074100480d080240024020050d00024020070d00410121060c020b2007102122060d010c0b0b2002280200210620052007460d0020062005200710252206450d0a0b20022007360204200220063602000b200620036a2004200110a1051a2002200320016a3602080c050b2002410036020820024201370300410110212203450d072002410136020420022003360200200341023a000020024101360208412010212203450d0520032001290001370000200341186a200141196a290000370000200341106a200141116a290000370000200341086a200141096a2900003700000240024020022802042206417f6a4120490d00200228020021010c010b200641017422014121200141214b1b22054100480d0720022802002101024020062005460d0020012006200510252201450d090b20022005360204200220013602000b20012003290000370001200141196a200341186a290000370000200141116a200341106a290000370000200141096a200341086a29000037000020024121360208200310230c040b2002410036020820024201370300410110212203450d062002410136020420022003360200200341043a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0620022802002103024020062005460d0020032006200510252203450d080b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210610240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d06200541017422072006200720064b1b22074100480d060240024020050d00024020070d00410121060c020b200710212206450d090c010b2002280200210620052007460d0020062005200710252206450d080b20022007360204200220063602000b200620036a2004200110a1051a2002200320016a3602080c030b2002410036020820024201370300410110212203450d052002410136020420022003360200200341053a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0520022802002103024020062005460d0020032006200510252203450d070b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210610240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d05200541017422072006200720064b1b22074100480d050240024020050d00024020070d00410121060c020b200710212206450d080c010b2002280200210620052007460d0020062005200710252206450d070b20022007360204200220063602000b200620036a2004200110a1051a2002200320016a3602080c020b2002410036020820024201370300410110212203450d042002410136020420022003360200200341063a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0420022802002103024020062005460d0020032006200510252203450d060b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210610240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d04200541017422072006200720064b1b22074100480d040240024020050d00024020070d00410121060c020b200710212206450d070c010b2002280200210620052007460d0020062005200710252206450d060b20022007360204200220063602000b200620036a2004200110a1051a2002200320016a3602080c010b2002410036020820024201370300410110212203450d032002410136020420022003360200200341073a00002002410136020820022802002103024020022802044101470d0020034101410210252203450d0420024102360204200220033602000b200341003a0001200241023602082002280200210320022802042106024020012802044101460d00024020064102470d0020034102410410252203450d0520024104360204200220033602000b200341003a0002200241033602080c010b024020064102470d0020034102410410252203450d0420024104360204200220033602000b200341013a000220024103360208200141086a28020021050240024020022802042206417d6a4104490d00200228020021030c010b200641017422034107200341074b1b22044100480d0320022802002103024020062004460d0020032006200410252203450d050b20022004360204200220033602000b20032005360003200241073602082001410c6a2802002106024002402002280204220341796a4104490d00200228020021010c010b20034101742201410b2001410b4b1b22054100480d0320022802002101024020032005460d0020012003200510252201450d050b20022005360204200220013602000b200120063600072002410b3602080b200020022201290200370200200041086a200141086a280200360200200241106a24000f0b1033000b102c000b102a000b930201037f230041106b220224002002200028024036020c20012002410c6a410410620240412010212203450d0020032000290050370000200341186a200041e8006a290000370000200341106a200041e0006a290000370000200341086a200041d8006a29000037000020012003412010622003102320002802442103200041cc006a28020022042001106120012003200410622001200041f0006a41201062200120004190016a41c0001062412010212203450d00200320002900d001370000200341186a200041e8016a290000370000200341106a200041e0016a290000370000200341086a200041d8016a2900003700002001200341201062200310232000200110e104200241106a24000f0b1033000bf10301047f230041106b2202240020002802002103200028020822042001106102402004450d002003200441c8006c6a210503402002200310702001200228020022042002280208106202402002280204450d00200410230b2002200341246a220310702001200228020022042002280208106202402002280204450d00200410230b200341246a22032005470d000b0b20022000410c6a10702001200228020022032002280208106202402002280204450d00200310230b2002200041306a10702001200228020022032002280208106202402002280204450d00200310230b2002200041d4006a10702001200228020022032002280208106202402002280204450d00200310230b2002200041f8006a10702001200228020022032002280208106202402002280204450d00200310230b20022000419c016a10702001200228020022032002280208106202402002280204450d00200310230b0240024020002d0088024101460d00200241003a000020012002410110620c010b200241013a00002001200241011062200120004189026a411410620b2002200041c0016a10702001200228020022032002280208106202402002280204450d00200310230b2002200041e4016a10702001200228020022032002280208106202402002280204450d00200310230b200241106a24000bde0102027f017e230041106b2202240002402000280200220341064b0d00024002400240024002400240024020030e0700010203040506000b200241003a000020012002410110620c060b200241013a00002001200241011062200029030821042002200041106a2903003703082002200437030020012002411010620c050b200241023a000020012002410110620c040b200241033a000020012002410110620c030b200241043a000020012002410110620c020b200241053a000020012002410110620c010b200241063a000020012002410110620b200241106a24000bee0201027f230041106b220224000240024020002d0000220341024b0d0002400240024020030e03000102000b200241013a000f20012002410f6a41011062412010212203450d0320032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201062200310230c020b200241023a000f20012002410f6a41011062412010212203450d0220032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201062200310230c010b200241033a000f20012002410f6a41011062412010212203450d0120032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201062200310230b2001200041216a41c0001062200241106a24000f0b1033000b880f020a7f017e230041d0036b2202240041002103200241003a002820012802042204417f6a2105417f210602400240024002400240024002400240024002400240034020042003460d01200241086a20036a200128020022072d00003a00002001200420066a3602042001200741016a22083602002002200341016a22093a00282005417f6a21052006417f6a21062009210320094120470d000b20024188036a41186a2206200241086a41186a29030037030020024188036a41106a220a200241086a41106a29030037030020024188036a41086a220b200241086a41086a2903003703002002200229030837038803200941ff01714120490d01200420096b2103200241a8016a41086a200b290300370300200241a8016a41106a200a290300370300200241a8016a41186a20062903003703002002200229038803220c3703c8022002200c3703a80141002106200241003a002803402003450d03200241086a20066a20082d00003a000020012003417f6a22033602042001200841016a22083602002002200641016a22093a00282009210620094120470d000b20024188036a41186a2203200241086a41186a29030037030020024188036a41106a2206200241086a41106a29030037030020024188036a41086a2204200241086a41086a2903003703002002200229030837038803200941ff01714120490d03200241c8016a41086a2004290300370300200241c8016a41106a2006290300370300200241c8016a41186a20032903003703002002200229038803220c3703c8022002200c3703c80141002106200241003a0028200520096b2103200720096a210403402003417f460d05200241086a20066a200820066a2d00003a0000200120033602042001200420066a41026a3602002002200641016a22093a00282003417f6a21032009210620094120470d000b20024188036a41186a2206200241086a41186a29030037030020024188036a41106a2207200241086a41106a29030037030020024188036a41086a220a200241086a41086a2903003703002002200229030837038803200941ff01714120490d05200820096a2105200241e8016a41086a200a290300370300200241e8016a41106a2007290300370300200241e8016a41186a20062903003703002002200229038803220c3703c8022002200c3703e80141002106200241003a0028200420096a210403402003417f460d07200241086a20066a20052d00003a0000200120033602042001200420066a41026a3602002002200641016a22093a00282003417f6a2103200541016a21052009210620094120470d000b20024188036a41186a2206200241086a41186a29030037030020024188036a41106a2204200241086a41106a29030037030020024188036a41086a2207200241086a41086a2903003703002002200229030837038803200941ff01714120490d0720024188026a41086a200729030037030020024188026a41106a200429030037030020024188026a41186a20062903003703002002200229038803220c3703c8022002200c3703880241002106200241003a00c80303402003417f460d09200241a8036a20066a20052d00003a0000200120033602042001200541016a22053602002002200641016a22093a00c8032003417f6a21032009210620094120470d000b20024188036a41186a2203200241a8036a41186a29030037030020024188036a41106a2201200241a8036a41106a29030037030020024188036a41086a2206200241a8036a41086a290300370300200220022903a80337038803200941ff01714120490d09200241a8026a41086a22092006290300370300200241a8026a41106a22062001290300370300200241a8026a41186a22012003290300370300200241086a41186a200241a8016a41186a290300370300200241086a41106a200241a8016a41106a290300370300200241086a41086a200241a8016a41086a2903003703002002200229038803220c3703c8022002200c3703a802200220022903a801370308200241c0006a200241c8016a41186a290300370300200241386a200241c8016a41106a290300370300200241306a200241c8016a41086a290300370300200220022903c801370328200241e0006a200241e8016a41186a290300370300200241d8006a200241e8016a41106a290300370300200241d0006a200241e8016a41086a290300370300200220022903e80137034820024180016a20024188026a41186a290300370300200241f8006a20024188026a41106a290300370300200241f0006a20024188026a41086a2903003703002002200229038802370368200241a0016a200129030037030020024198016a200629030037030020024190016a2009290300370300200220022903a80237038801200041016a200241086a41a00110a1051a200041003a00000c0a0b200341ff0171450d00200241003a00280b200041013a00000c080b200641ff0171450d00200241003a00280b200041013a00000c060b200641ff0171450d00200241003a00280b200041013a00000c040b200641ff0171450d00200241003a00280b200041013a00000c020b200641ff0171450d00200241003a00c8030b200041013a00000b200241d0036a24000b13002000410536020420004198dfc4003602000b13002000410236020420004188a5c6003602000b130020004105360204200041d8adc5003602000b130020004107360204200041e0c5c0003602000b13002000410136020420004194a4c0003602000b130020004101360204200041e8a6c0003602000b130020004103360204200041d0a1c0003602000b130020004103360204200041dca1c2003602000b130020004102360204200041b4aac0003602000b13002000410636020420004188a3c5003602000b13002000410736020420004184c8c6003602000b130020004106360204200041c4eec3003602000b130020004102360204200041ac9ec2003602000b130020004102360204200041e4f4c3003602000b130020004103360204200041c081c3003602000b4d01017f230041206b22002400200041146a410136020020004201370204200041a4c5c6003602002000410436021c200041cccec6003602182000200041186a3602102000419ca8c700103a000bf00204027f017e017f077e0240024020012802042202450d0020012802002203310000210420012002417f6a22053602042001200341016a3602002005450d012003310001210620012002417e6a22053602042001200341026a3602002005450d012003310002210720012002417d6a22053602042001200341036a3602002005450d012003310003210820012002417c6a22053602042001200341046a3602002005450d012003310004210920012002417b6a22053602042001200341056a3602002005450d012003310005210a20012002417a6a22053602042001200341066a3602002005450d012003310006210b2001200241796a22053602042001200341076a3602002005450d01200041003a00002003310007210c2001200241786a3602042001200341086a3602002000200c423886200b42308684200a422886842009422086842008421886842007421086842006420886842004843700010f0b200041013a00000f0b200041013a00000bb10201037f230041e0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841010108b0102400240200228021022010d00200041003602000c010b200228021421032002200241186a28020036022420022001360220200241c8006a200241206a10b00402400240200228024822040d0020024100360230200242013703282002410a36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c20024180c5c6003602482002200241386a360258200241c4006a4184a5c200200241c8006a10311a2002350230422086200235022884100a0240200228022c450d00200228022810230b200041003602000c010b2000200229024c370204200020043602000b2003450d00200110230b200241e0006a24000ba70301087f230041206b220324000240024002400240200141246c41046a2204417f4c0d000240024020040d00410121050c010b200410212205450d020b2003410036020820032004360204200320053602002001200310610240024020010d002003280208210420032802042106200328020021070c010b200141246c210820032802042105200328020821010340200341106a200010e0022003280210210902400240200520016b2003280218220a490d002001200a6a210420032802002107200521060c010b2001200a6a22042001490d05200541017422062004200620044b1b22064100480d050240024020050d00024020060d00410121070c020b2006102122070d010c080b2003280200210720052006460d0020072005200610252207450d070b20032006360204200320073602000b200720016a2009200a10a1051a2003200436020802402003280214450d00200910230b200041246a210020062105200421012008415c6a22080d000b0b20022902002004ad4220862007ad84100e02402006450d00200710230b200341206a24000f0b1032000b1033000b102c000b102a000bcc0503027f017e047f230041e0006b2202240041e4dec400ad4280808080e00084100c22032900002104200241086a41086a200341086a290000370300200220043703082003102341888ec600ad4280808080f00084100c22032900002104200241186a41086a200341086a2900003703002002200437031820031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100f22012900002104200241386a41086a200141086a2900003703002002200437033820011023200241d4006a200341206a360200200241003a0058200220033602502002200241386a41106a36024c2002200241386a360248200241286a200241c8006a1065200310232002280230220541206a2201417f4c0d0120022802282106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290308370000200341086a200241086a41086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290318370010200341186a200241186a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a2000200136020820002007360204200020033602000240200228022c450d00200610230b200241e0006a24000f0b102c000b102a000b990204017f017e017f017e230041d0006b220224002002412036020420022001360200200241086a2001ad42808080808004841010108b0102400240200228020822010d00420021030c010b200228020c210402400240200241086a41086a2802004108490d0020012900002105420121030c010b20024100360220200242013703182002410a36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c20024180c5c6003602382002200241286a360248200241346a4184a5c200200241386a10311a2002350220422086200235021884100a0240200228021c450d00200228021810230b420021030b2004450d00200110230b2000200537030820002003370300200241d0006a24000b950503027f017e057f230041e0006b2202240041fba7c600ad4280808080f00084100c22032900002104200241086a41086a200341086a29000037030020022004370308200310234194a8c600ad4280808080800184100c22032900002104200241186a41086a200341086a290000370300200220043703182003102320022001360234200241346aad4280808080c00084100f22032900002104200241386a41086a200341086a2900003703002002200437033820031023200241d4006a200241386a360200200241003a00582002200241c8006a36024c2002200241346a3602502002200241386a360248200241286a200241c8006a10650240024002400240024002402002280230220541206a2201417f4c0d0020022802282106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290308370000200341086a200241086a41086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290318370010200341186a200241186a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a2000200136020820002007360204200020033602000240200228022c450d00200610230b200241e0006a24000f0b102c000b102a000bbb0402097f057e230041f0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841010108b0102400240200328021022040d00200042003703000c010b200341186a28020021052003280214210641002101200341003a0068024002400240034020052001460d01200341c8006a20016a200420016a2d00003a00002003200141016a22023a00682002210120024120470d000b200341286a41186a2201200341c8006a41186a2207290300370300200341286a41106a2208200341c8006a41106a2209290300370300200341286a41086a220a200341c8006a41086a220b29030037030020032003290348370328200520026b410f4d0d01200b200a290300220c37030020092008290300220d37030020072001290300220e37030020032003290328220f370348200420026a22012900002110200041306a200141086a290000370300200041286a2010370300200041206a200e370300200041186a200d370300200041106a200c3703002000200f3703084201210c0c020b200141ff0171450d00200341003a00680b20034100360230200342013703282003410a3602242003200341086a3602202003200341286a36026c200341dc006a41013602002003420137024c20034180c5c6003602482003200341206a360258200341ec006a4184a5c200200341c8006a10311a2003350230422086200335022884100a0240200328022c450d00200328022810230b4200210c0b2000200c3703002006450d00200410230b200341f0006a24000ba30f05067f027e037f0b7e027f23004180036b22032400200228020821042002280204210520022802002106200341086a2001109702200341b0016a200328020822072003280210220810980220032903b00121094200210a200342003703b001200341f8016a280200210b20032d00fc01210c024002402009420151220d0d00200341186a41306a4200370300200341186a41286a4200370300200341186a41206a4200370300200341186a41186a4200370300200341286a4200370300200341206a4200370300200342003703184200210e4200210f42002110420021110c010b200341e8016a2903002112200341b0016a41306a2903002113200341b0016a41206a2903002110200341b0016a41186a290300210f200341f0016a290300211120032903c001210e20032903b801210a200341186a41206a200341b0016a41286a290300370300200341186a41286a2013370300200341186a41306a2012370300200341286a200f370300200320103703302003200a3703182003200e3703200b200341186a41106a21020240024002400240024002400240200a200629030022137d2214200a56200e200641086a29030022157d200a201354ad7d2212200e562012200e511b450d004280808080b002211341e1acc500210d4180800c21060c010b2003201437031820032012370320200f20137c2216200f542206201020157c2006ad7c221720105420172010511b4101470d0142808080808001211341f4acc500210d4180800821062014210a2012210e0b200341d0006a41206a200241206a290300370300200341d0006a41186a200241186a290300370300200341d0006a41106a200241106a290300370300200341d0006a41086a200241086a290300370300200320022903003703500c010b200341186a41186a201737030020032016370328024002402013201584500d00200341f8006a200528020010970220034198026a20032802782205200328028001109802200341c8026a290300420020032903980242015122061b2113200341c0026a290300420020061b21150240200328027c450d00200510230b2015201456201320125620132012511b0d010b200341d0006a41206a200241206a2903002217370300200341d0006a41186a200241186a2903002216370300200341d0006a41106a200241106a2903002218370300200341d0006a41086a200241086a290300221337030020032002290300221537035020042802002102200341f8006a41186a2013370300200341f8006a41206a22052018370300200341a0016a22192016370300200341a8016a221a20173703002003201537038801200320143703782003201237038001427f200a200f7c220f200f200a542206200e20107c2006ad7c220a200e54200a200e511b22061b427f200a20061b84502106427f201420157c220a200a2014542204201220137c2004ad7c220a201254200a2012511b22041b220e4280c8afa025544100427f200a20041b220a501b0d02200341f8006a41106a290300210a201a290300210e201929030021102005290300210f2003290380012115200329037821174201211620032903900121180c030b200341d0006a41206a200241206a290300370300200341d0006a41186a200241186a290300370300200341d0006a41106a200241106a290300370300200341d0006a41086a200241086a2903003703002003200229030037035041808004210641fcacc500210d4280808080d00221132014210a2012210e0b20064180800c7141830a722106200dad221242088842ff018321102013201284428080fcffff0383210f410121020c020b420021160240200e200a84500d00200e200a10eb01200341d0026a200a370300200341c8026a200e37030020034198026a41086a41013a0000200341a1026a2002290000370000200341a9026a200241086a290000370000200341b1026a200241106a290000370000200341b9026a200241186a290000370000200341023a00980220034198026a10e0010b0b2006ad2113200341d8016a200f370300200341e0016a2010370300200341c0016a2015370300200341e8016a200e370300200341c8016a200a370300200320183703d001200320113703f001200320173703b80142012110410021022003200c4100200942015122061b3a00fc012003200b410020061b3602f801200320164201512206ad3703b001024020060d002008ad4220862007ad841011420021102014210a2012210e4200210f0c010b2003200836029c022003200736029802200341b8016a20034198026a1098034200210f2014210a2012210e0b0240200328020c450d00200710230b024002402002450d0020002006360204200041086a2010420886200dad42ff018384200f84370200410121020c010b024002400240200d41ff017122020d0020104200510d004103210d20034198026a21020c010b2002450d0120104200520d014104210d200341b0016a21020b200241046a200d3a0000200241003a0000200241056a20012900003700002002410d6a200141086a290000370000200241156a200141106a2900003700002002411d6a200141186a290000370000200210e0010b200041186a200e370300200041106a200a370300200041086a2013370300410021020b2000200236020020034180036a24000bb31d0e037f017e037f057e037f017e027f017e017f037e017f017e037f047e23004180086b220624002006200437031020062003370308200620053a001f02400240024002400240024002400240024002402003200484500d0020012002460d0320012002412010a305450d0320064188016a200210970220064198016a200628028801220720062802900122081098022006290398012109420021042006420037039801200641e0016a280200210a20062d00e401210b2009420151220c0d01200641e8016a41386a4200370300200641e8016a41306a4200370300200641e8016a41286a420037030020064188026a4200370300200641e8016a41186a4200370300200641f8016a4200370300200641f0016a4200370300200642003703e801420021034200210d4200210e0c020b20004100360200200041106a4200370300200041086a42003703000c080b20064198016a41386a290300210f20064198016a41306a290300211020064198016a41206a290300210e20064198016a41186a290300210d200641d8016a290300211120062903a801210320062903a001210420064188026a20064198016a41286a290300370300200641e8016a41286a2010370300200641e8016a41306a200f370300200641f8016a200d3703002006200e37038002200620113703a002200620043703e801200620033703f0010b42002110200641e8016a41106a21050240427f2004200d7c220d200d20045422122003200e7c2012ad7c220420035420042003511b22121b427f200420121b844200520d00200641c8056a41206a200541206a290300370300200641c8056a41186a200541186a290300370300200641c8056a41106a200541106a290300370300200641c8056a41086a200541086a290300370300200620052903003703c80541a4acc500ad4280808080b00184210341838a1c21050c040b200641f8036a200110970220064188046a20062802f8032213200628028004221410980220062903880421152006420037038804200641d0046a280200211620062d00d404211702400240201542015122120d004200210d200641d8046a41306a4200370300200641d8046a41286a4200370300200641d8046a41206a4200370300200641d8046a41186a4200370300200641e8046a4200370300200641e0046a4200370300200642003703d804420021034200210e42002104420021180c010b200641c0046a290300210f20064188046a41306a290300211020064188046a41206a290300210320064188046a41186a290300210d200641c8046a29030021182006290398042104200629039004210e200641d8046a41206a20064188046a41286a290300370300200641d8046a41286a2010370300200641d8046a41306a200f370300200641e8046a200d370300200620033703f0042006200e3703d804200620043703e0040b200641086a41086a29030022102003200d2006290308221156200320105620032010511b22191b211a2011200d20191b210f0240024020062d001f4101470d002005211920062903f801221b200f7c221c201b54221d20064180026a290300221e201a7c201dad7c221b201e54201b201e511b0d010c030b200641e8016a211920062903e801221b200f7c221c201b54221d200641e8016a41086a290300221e201a7c201dad7c221b201e54201b201e511b4101470d020b41f4acc500211241f4acc500ad42808080808001842203428080fcff8f0183210f200342088842ff0183210d410121190c020b02402005450d00200641b0066a200110970220064198076a20062802b006220220062802b806109802200641b8076a290300420020062903980742015122011b210e200641b0076a290300420020011b210d024020062802b406450d00200210230b20004100360200200041106a42002004200e7d2003200d54ad7d220e2003200d7d220d200356200e200456200e2004511b22011b370300200041086a4200200d20011b3703000c060b200620033703c805200620043703d0052006200136029003200641b0066a2001200641c8056a20064190036a10ff02200641d0066a290300210320062903c8062104024020062903b0064201520d0020062903b806210d200641d0076a200641b0066a41106a290300370300200641c8076a200d37030020064198076a41086a41003a0000200641a1076a2001290000370000200641a9076a200141086a290000370000200641b1076a200141106a290000370000200641b9076a200141186a290000370000200641023a00980720064198076a10e0010b200041106a2003370300200041086a2004370300200041003602000c050b2019201c3703002019201b370308200641d8046a41186a2003201a7d200d200f54ad7d3703002006200d200f7d3703e80420064190056a41186a200641e8046a221941086a290300221b37030020064190056a41206a221f201941106a290300370300200641b8056a2220201941186a290300370300200641c0056a2221201941206a29030037030020062019290300221c3703a0052006200e3703900520062004370398052010201a7d21102011200f54ad211a427f200e200d7c220d200d200e542219200420037c2019ad7c220320045420032004511b22191b427f200320191b8450211902400240427f200e201c7c22032003200e54221d2004201b7c201dad7c220320045420032004511b221d1b220d4280c8afa025544100427f2003201d1b2203501b0d0020064190056a41106a290300210d2021290300211b2020290300211c201f290300211e200629039805212220062903900521234201212420062903a80521250c010b420021240240200d200384500d00200d200310eb01200641d0076a2003370300200641c8076a200d37030020064198076a41086a41013a0000200641a1076a2001290000370000200641a9076a200141086a290000370000200641b1076a200141106a290000370000200641b9076a200141186a290000370000200641023a00980720064198076a10e0010b0b2010201a7d21102011200f7d21032019ad2111200641b0046a201e370300200641b8046a201c37030020064198046a2022370300200641c0046a201b370300200641a0046a200d370300200620253703a804200620183703c80420062023370390044201210d410021192006201741002015420151221d1b3a00d404200620164100201d1b3602d004200620244201512216ad370388040240024020160d002014ad4220862013ad8410114200210d0c010b2006201436029c07200620133602980720064190046a20064198076a1098030b4200210f0b024020062802fc03450d00201310230b0240024020190d00024002400240201241ff017122120d00200d4200510d0041032119200641b0066a21120c010b2012450d01200d4200520d0141042119200641c8056a21120b201241046a20193a0000201241003a0000201241056a20012900003700002012410d6a200141086a290000370000201241156a200141106a2900003700002012411d6a200141186a290000370000201210e0010b4100211220114201520d01200641d0076a2004370300200641c8076a200e3703004100211220064198076a41086a41003a0000200641a1076a2001290000370000200641a9076a200141086a290000370000200641b1076a200141106a290000370000200641b9076a200141186a290000370000200641023a00980720064198076a10e0010c010b200d4208862012ad42ff018384200f84210342002110410121120b200641e8016a41086a290300210420062903e801210d20062903a002210e200641c8056a41206a2201200541206a290300370300200641c8056a41186a2219200541186a290300370300200641c8056a41106a2213200541106a290300370300200641c8056a41086a2214200541086a290300370300200620052903003703c80541838a0821052012450d010b20034280807c83210d200342088842ff018321042003a7210c410121010c010b200641b0066a41186a2014290300220f370300200641b0066a41206a2013290300370300200641d8066a22052019290300370300200641e0066a22122001290300370300200620062903c80522113703c0062006200d3703b006200620043703b80602400240427f200d20117c22112011200d5422012004200f7c2001ad7c220d200454200d2004511b22011b22044280c8afa025544100427f200d20011b220d501b0d00200641c0066a29030021042012290300210d2005290300210f200641d0066a290300211120062903b806211a20062903b00621154201211b20062903c80621180c010b4200211b02402004200d84500d002004200d10eb01200641d0076a200d370300200641c8076a200437030020064198076a41086a41013a0000200641a1076a2002290000370000200641a9076a200241086a290000370000200641b1076a200241106a290000370000200641b9076a200241186a290000370000200641023a00980720064198076a10e0010b0b200641c0016a2011370300200641c8016a200f370300200641a8016a201a370300200641d0016a200d370300200641b0016a2004370300200620183703b8012006200e3703d801200620153703a00142012104410021012006200b4100200942015122051b3a00e4012006200a410020051b3602e0012006201b4201512205ad37039801024020050d002008ad4220862007ad8410114200210441838a0821054200210d0c010b2006200836029c072006200736029807200641a0016a20064198076a1098034200210d41838a0821050b0240200628028c01450d00200710230b024020010d00024002400240200c41ff017122010d0020044200510d004103210520064190036a21010c010b2001450d0120044200520d0141042105200641a8026a21010b200141046a20053a0000200141003a0000200141056a20022900003700002001410d6a200241086a290000370000200141156a200241106a2900003700002001411d6a200241186a290000370000200110e0010b200041106a2010370300200041086a2003370300200041003602000c010b20002005360204200041086a2004420886200cad42ff018384200d84370200200041013602000b20064180086a24000be40a06037f027e027f0c7e037f057e230041d0026b22042400200328020021052004200110970220044180016a20042802002203200428020822061098022004290380012107420021082004420037038001200441c8016a280200210920042d00cc01210a0240024020074201510d00200441106a41306a4200370300200441106a41286a4200370300200441106a41206a4200370300200441106a41186a4200370300200441206a4200370300200441186a4200370300200442003703104200210b4200210c4200210d4200210e0c010b200441b8016a290300210f20044180016a41306a290300211020044180016a41206a290300210b20044180016a41186a2903002108200441c0016a290300210e200429039001210d200429038801210c200441106a41206a20044180016a41286a290300370300200441106a41286a2010370300200441106a41306a200f370300200441206a20083703002004200b3703282004200c3703102004200d3703180b200441106a41186a200b200241086a2903002211200b20082002290300221256200b201156200b2011511b22021b22137d20082012200820021b221054ad7d22143703002004200820107d22153703202004427f200d20137c200c20107c2216200c542202ad7c220f2002200f200d54200f200d511b22021b220f3703182004427f201620021b2216370310200441c8006a41186a2014370300200441c8006a41206a2217200441106a41206a290300370300200441c8006a41286a2218200441106a41286a290300370300200441c8006a41306a2219200441106a41306a2903003703002004200f3703502004201637034820042015370358427f200d200b7c200c20087c220b200c542202ad7c220820022008200d542008200d511b22021b210c427f200b20021b211a02400240427f201620157c220d200d2016542202200f20147c2002ad7c220d200f54200d200f511b22021b22084280c8afa025544100427f200d20021b220b501b0d00200441d8006a290300210b20192903002114201829030021152017290300211b2004290350211c2004290348211d4201210d2004290360211e0c010b4200210d02402008200b84500d002008200b10eb01200441a0026a200b37030020044198026a2008370300200441e8016a41086a41013a0000200441f1016a2005290000370000200441f9016a200541086a29000037000020044181026a200541106a29000037000020044189026a200541186a290000370000200441023a00e801200441e8016a10e0010b0b20122010542102201a200c842108200441a8016a201b370300200441b0016a201537030020044190016a201c370300200441b8016a201437030020044198016a200b3703002004201e3703a0012004200e3703c0012004201d370388012004200a4100200742015122051b3a00cc0120042009410020051b3602c8012004200d4201512205ad370380010240024020050d002006ad4220862003ad8410110c010b200420063602ec01200420033602e80120044188016a200441e8016a1098030b201120137d210b2002ad210c200850210202402004280204450d00200310230b200b200c7d21082002ad210b201220107d210c200d420152210202400240024020074201510d0020020d0041032103200441e8016a21020c010b20074201522002410173720d014104210320044180016a21020b200241046a20033a0000200241003a0000200241056a20012900003700002002410d6a200141086a290000370000200241156a200141106a2900003700002002411d6a200141186a290000370000200210e0010b2000200c370318200020163703082000200b370300200041206a2008370300200041106a200f370300200441d0026a24000bb91e0b037f027e037f047e037f027e017f077e017f027e047f230041a0076b2206240020062004370318200620033703102006200136020c200620053a002702400240024002400240024020012002460d002003200484500d0020012002412010a305450d00200641286a2002109702200641386a2006280228220720062802302208109802200629033821094200210a2006420037033820064180016a280200210b20062d008401210c024002402009420151220d0d0020064188016a41386a420037030020064188016a41306a420037030020064188016a41286a4200370300200641a8016a420037030020064188016a41186a420037030020064198016a420037030020064190016a420037030020064200370388014200210e4200210f420021100c010b200641386a41386a2903002103200641386a41306a2903002104200641386a41206a290300210e200641386a41186a290300210a200641f8006a2903002111200629034821102006290340210f200641a8016a200641386a41286a29030037030020064188016a41286a200437030020064188016a41306a200337030020064198016a200a3703002006200e3703a001200620113703c0012006200f3703880120062010370390010b20064198036a200628020c2212109702200641a8036a200628029803221320062802a003221410980220062903a803211542002116200642003703a803200641f0036a280200210120062d00f403211702400240201542015122050d00200641f8036a41306a4200370300200641f8036a41286a4200370300200641f8036a41206a4200370300200641f8036a41186a4200370300200641f8036a41106a420037030020064180046a4200370300200642003703f803420021184200210442002103420021190c010b200641e0036a2903002111200641a8036a41306a290300211a200641a8036a41206a2903002118200641a8036a41186a2903002116200641e8036a290300211920062903b803210320062903b0032104200641f8036a41206a200641a8036a41286a290300370300200641f8036a41286a201a370300200641f8036a41306a2011370300200641f8036a41106a20163703002006201837039004200620043703f80320062003370380040b024020042006290310221b7d221a2004562003200641106a41086a290300221c7d2004201b54ad7d221120035620112003511b450d0041e1acc50021054280808080b002211141808a0c21010c030b2006201a3703f80320062011370380040240200629038801221d201b7c221e201d54221f20064188016a41086a2903002220201c7c201fad7c221d202054201d2020511b450d0041f4acc500210542808080808001211141808a0821010c030b2006201e37038801200641a0016a29030021202006201d370390010240427f201e2006290398017c22212021201e54221f201d20207c201fad7c2220201d542020201d511b221f1b4280c8afa025544100427f2020201f1b501b450d0041cfacc50021054280808080a002211141808a1021010c030b0240201b201c84500d00200641b0046a200628020c109702200641b8066a20062802b004222220062802b804109802200641e8066a290300420020062903b806420151221f1b211b200641e0066a2903004200201f1b211d024020062802b404450d00202210230b201d201a56201b201156201b2011511b0d020b0240024020062d00274101460d00201a4280c8afa0255441002011501b0d010c050b200641b0046a200628020c109702200641b8066a20062802b004221f20062802b80410980220062d008407212220062903b806211b024020062802b404450d00201f10230b201a42ffc7afa0255620114200522011501b0d04201b4201520d04202241ff0171450d040b41c6acc500210542808080809001211141808a1421010c020b200041043a00000c040b41fcacc50021054280808080d002211141808a0421010b200141037221172005ad220342088842ff018321042003428080fcff0f83201184211b4101211f0c010b200641b0046a41186a200641f8036a41186a290300221b370300200641b0046a41206a2223200641f8036a41206a290300370300200641b0046a41286a2224200641f8036a41286a290300370300200641b0046a41306a2225200641f8036a41306a2903003703002006200629038804221d3703c0042006201a3703b004200620113703b804427f200420167c22162016200454221f200320187c201fad7c220420035420042003511b221f1b427f2004201f1b8450211f02400240427f201a201d7c22032003201a5422222011201b7c2022ad7c220320115420032011511b22221b22044280c8afa025544100427f200320221b2203501b0d00200641c0046a29030021042025290300211b202429030021162023290300211d20062903b804211c20062903b00421184201212020062903c804211e0c010b4200212002402004200384500d002004200310eb01200641f0066a2003370300200641e8066a2004370300200641b8066a41086a41013a0000200641c1066a2012290000370000200641c9066a201241086a290000370000200641d1066a201241106a290000370000200641d9066a201241186a290000370000200641023a00b806200641b8066a10e0010b0b201fad2103200641d0036a201d370300200641d8036a2016370300200641b8036a201c370300200641e0036a201b370300200641c0036a20043703002006201e3703c803200620193703e803200620183703b003420121044100211f200620174100201542015122221b3a00f40320062001410020221b3602f003200620204201512201ad3703a803024020010d002014ad4220862013ad841011420021044200211b0c010b200620143602bc06200620133602b806200641b0036a200641b8066a1098034200211b0b0240200628029c03450d00201310230b20064188016a41106a210102400240201f0d00024002400240200541ff017122050d0020044200510d0041032117200641d0056a21050c010b2005450d0120044200520d0141042117200641e8046a21050b200541046a20173a0000200541003a0000200541056a20122900003700002005410d6a201241086a290000370000200541156a201241106a2900003700002005411d6a201241186a290000370000200510e0010b410421174100210520034201520d01200641f0066a2011370300200641e8066a201a37030041002105200641b8066a41086a41003a0000200641c1066a2012290000370000200641c9066a201241086a290000370000200641d1066a201241106a290000370000200641d9066a201241186a290000370000200641023a00b806200641b8066a10e0010c010b20044208862005ad42ff018384201b842103201741807e7121050b200641e8046a41086a2212200141086a290300370300200641e8046a41106a221f200141106a290300370300200641e8046a41186a2213200141186a290300370300200641e8046a41206a2214200141206a290300370300200620012903003703e80420064188016a41086a2903002104200629038801211102400240201741ff017122014104460d0020034280807c83211a200342088842ff01832110200520017221052003a7210d410121010c010b20062903c001211a200641d0056a41186a2012290300221b370300200641d0056a41206a201f290300370300200641f8056a2212201329030037030020064180066a22172014290300370300200620062903e80422153703e005200620113703d005200620043703d805427f200f200a7c22032003200f5422012010200e7c2001ad7c220320105420032010511b22011b427f200320011b8450210102400240427f201120157c2203200320115422052004201b7c2005ad7c220320045420032004511b22051b22104280c8afa025544100427f200320051b2203501b0d00200641e0056a29030021102017290300211b2012290300210a200641f0056a290300210f20062903d805211520062903d00521164201210e20062903e805211d0c010b4200210e02402010200384500d002010200310eb01200641f0066a2003370300200641e8066a2010370300200641b8066a41086a41013a0000200641c1066a2002290000370000200641c9066a200241086a290000370000200641d1066a200241106a290000370000200641d9066a200241186a290000370000200641023a00b806200641b8066a10e0010b0b2001ad2103200641e0006a200f370300200641e8006a200a370300200641c8006a2015370300200641f0006a201b370300200641d0006a20103703002006201d3703582006201a3703782006201637034042012110410021012006200c4100200942015122051b3a0084012006200b410020051b360280012006200e4201512205ad370338024020050d002008ad4220862007ad841011420021104200211a0c010b200620083602bc06200620073602b806200641c0006a200641b8066a1098034200211a0b0240200628022c450d00200710230b02400240024020010d00024002400240200d41ff017122010d0020104200510d0041032105200641b0026a21010c010b2001450d0120104200520d0141042105200641c8016a21010b200141046a20053a0000200141003a0000200141056a20022900003700002001410d6a200241086a290000370000200141156a200241106a2900003700002001411d6a200241186a290000370000200110e0010b20034201520d01200641f0066a2004370300200641e8066a2011370300200641b8066a41086a41003a0000200641c1066a2002290000370000200641c9066a200241086a290000370000200641d1066a200241106a290000370000200641d9066a200241186a290000370000200641023a00b806200641b8066a10e0010c010b200541ff01714104470d010b200628020c21012006290310210320064190076a200641106a41086a29030037030020064188076a2003370300200641b8066a41086a41023a0000200641c1066a2001290000370000200641c9066a200141086a290000370000200641d1066a200141106a290000370000200641d9066a200141186a290000370000200641e1066a2002290000370000200641e9066a200241086a290000370000200641f1066a200241106a290000370000200641f9066a200241186a290000370000200641023a00b806200641b8066a10e001200041043a00000c010b2000200541087622023b0001200020053a0000200041036a20024110763a0000200041046a2010420886200dad42ff018384201a843700000b200641a0076a24000b950201047f230041d0006b220124002001412036020420012000360200200141086a2000ad42808080808004841010108b0102400240200128020822020d00410221000c010b200128020c210302400240200141106a280200450d0020022d0000220441014b0d0041002100024020040e020200020b410121000c010b20014100360220200142013703182001410a36022c200120013602282001200141186a360234200141cc006a41013602002001420137023c20014180c5c6003602382001200141286a360248200141346a4184a5c200200141386a10311a2001350220422086200135021884100a0240200128021c450d00200128021810230b410221000b2003450d00200210230b200141d0006a240020000b901304057f017e107f027e230041e0026b220224002002412036020c20022001360208200241106a2001ad42808080808004841010108b010240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a1088010240024020022802000d00200228020422052002280224220641c4006e2201200120054b1bad42c4007e2207422088a70d032007a72201417f4c0d030240024020010d00410421080c010b200110212208450d050b20024100360230200220083602282002200141c4006e36022c0240024002402005450d00200241b8026a41077221094100210a4100210b03402006450d0220022006417f6a220c36022420022002280220220d41016a360220200d2d0000220141014b0d0202400240024020010e020001000b200c4104490d04200241f4016a41026a200241f8016a41026a2d00003a0000200241d8016a41086a20024198026a41086a290200370300200241d8016a41106a20024198026a41106a290200370300200241d8016a41186a20024198026a41186a2d00003a0000200241b8016a41086a200241b8026a41086a290100370300200241b8016a41106a200241b8026a41106a290100370300200241b8016a41186a200241b8026a41186a290100370300200220022f00f8013b01f40120022002290298023703d801200220022901b8023703b80120022006417b6a220e3602242002200d41056a360220200d280001210f200220022f0194023b01b601410021100c010b41002111200241003a00d8022006417e6a2110024002400240024002400340200c20112201460d01200241b8026a20016a200d20016a221141016a2d00003a00002002201141026a3602202002200141016a22113a00d802200220103602242010417f6a211020114120470d000b20024194026a41026a221220022d00ba023a0000200241f8016a41086a2213200941086a290000370300200241f8016a41106a2214200941106a290000370300200241f8016a41186a2215200941186a2d00003a0000200220022f01b8023b019402200220092900003703f8014100210e200c2011460d0220022800bb022116200220103602242002200d20116a220c41026a360220200c41016a2d0000221141014d0d012010210e410221100c050b0240200141ff0171450d00200241003a00d8020b4100210e410221100c040b024020110e020200020b41002111200241003a00d802200620016b417c6a21010240034020102011460d01200241b8026a20116a200c20116a220d41026a2d00003a00002002200d41036a3602202002201141016a220d3a00d802200220013602242001417f6a2101200d2111200d4120470d000b20024198026a41186a200241b8026a41186a29030037030020024198026a41106a200241b8026a41106a29030037030020024198026a41086a200241b8026a41086a290300370300200220022903b802370398022010200d6b210e410121170c030b0240201141ff0171450d00200241003a00d8020b4100210e0b410221100c020b410021172010210e0b200241b8016a41186a20024198026a41186a290300370300200241b8016a41106a20024198026a41106a290300370300200241b8016a41086a20024198026a41086a290300370300200241f4016a41026a20122d00003a0000200241d8016a41086a2013290300370300200241d8016a41106a2014290300370300200241d8016a41186a20152d00003a000020022002290398023703b801200220022f0194023b01f401200220022903f8013703d801410121102016210f0b200241b2016a41026a2201200241f4016a41026a2d00003a000020024198016a41086a2211200241d8016a41086a29030037030020024198016a41106a220d200241d8016a41106a29030037030020024198016a41186a220c200241d8016a41186a2d00003a0000200241f8006a41086a2206200241b8016a41086a290300370300200241f8006a41106a2212200241b8016a41106a290300370300200241f8006a41186a2213200241b8016a41186a290300370300200220022f01f4013b01b201200220022903d80137039801200220022903b801370378200220022f01b6013b017620104102460d03200b41016a210b200241f2006a41026a221420012d00003a0000200241d8006a41086a22152011290300370300200241d8006a41106a2211200d290300370300200241d8006a41186a220d200c2d00003a0000200241386a41086a220c2006290300370300200241386a41106a22062012290300370300200241386a41186a22122013290300370300200220022f01b2013b0172200220022903980137035820022002290378370338200220022f01763b01360240200a200228022c470d00200241286a200a4101109b01200228022821082002280230210a0b2008200a41c4006c6a220120103a00002001200f360004200141036a20142d00003a0000200120022f01723b0001200d2d00002110201129030021072015290300211820022903582119200120173a002120012019370008200141106a2018370000200141186a2007370000200141206a20103a000020012002290338370022200c29030021072006290300211820122903002119200120022f01363b00422001413a6a2019370000200141326a20183700002001412a6a20073700002002200a41016a220a360230200e2106200b2005470d000b0b2008450d022000200229022c370204200020083602000c030b200241b2016a41026a200241f4016a41026a2d00003a000020024198016a41086a200241d8016a41086a29030037030020024198016a41106a200241d8016a41106a29030037030020024198016a41186a200241d8016a41186a2d00003a0000200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a200241b8016a41106a290300370300200241f8006a41186a200241b8016a41186a290300370300200220022f01f4013b01b201200220022903d80137039801200220022903b801370378200220022f01b6013b01760b200228022c2201450d00200141c4006c450d00200810230b200241003602a00220024201370398022002410a3602bc012002200241086a3602b801200220024198026a360278200241cc026a4101360200200242013702bc0220024180c5c6003602b8022002200241b8016a3602c802200241f8006a4184a5c200200241b8026a10311a20023502a00242208620023502980284100a0240200228029c02450d0020022802980210230b200041003602000b2004450d00200310230b200241e0026a24000f0b1032000b1033000b9b0902097f037e230041206b220224002002410036020820024201370300024002400240412010212203450d0020032001290010370000200341186a2204200141286a290000370000200341106a2205200141206a290000370000200341086a2206200141186a290000370000412010212207450d02200241203602042002200736020020072003290000370000200741086a2006290000370000200741106a2005290000370000200741186a200429000037000020024120360208200310232001200210ed01412010212203450d0020032001290030370000200341186a200141c8006a290000370000200341106a200141c0006a290000370000200341086a200141386a2900003700000240024020022802042208200228020822066b4120490d00200641206a210720022802002104200821050c010b200641206a22072006490d02200841017422042007200420074b1b22054100480d020240024020080d00024020050d00410121040c020b2005102122040d010c050b2002280200210420082005460d0020042008200510252204450d040b20022005360204200220043602000b200420066a22062003290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a2900003700002002200736020820031023412010212203450d0020032001290050370000200341186a200141e8006a290000370000200341106a200141e0006a290000370000200341086a200141d8006a2900003700000240200520076b411f4b0d00200741206a22062007490d02200541017422082006200820064b1b22064100480d020240024020050d00024020060d00410121040c020b200610212204450d050c010b20052006460d0020042005200610252204450d040b20022006360204200220043602000b200420076a22042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a2900003700002002200741206a36020820031023200128020421052001410c6a2802002201200210610240024020010d002002280208210320022802042104200228020021080c010b200141246c210920022802042107200228020821010340200241106a200510e0022002280210210a02400240200720016b20022802182206490d00200120066a210320022802002108200721040c010b200120066a22032001490d04200741017422042003200420034b1b22044100480d040240024020070d00024020040d00410121080c020b200410212208450d070c010b2002280200210820072004460d0020082007200410252208450d060b20022004360204200220083602000b200820016a200a200610a1051a2002200336020802402002280214450d00200a10230b200541246a210520042107200321012009415c6a22090d000b0b2003ad4220862008ad8410182201290000210b200141086a290000210c200141106a290000210d200041186a200141186a290000370000200041106a200d370000200041086a200c3700002000200b3700002001102302402004450d00200810230b200241206a24000f0b1033000b102c000b102a000bac0603027f017e057f23004180016b2202240041e4dec400ad4280808080e00084100c22032900002104200241306a41086a200341086a290000370300200220043703302003102341eadec400ad4280808080900184100c22032900002104200241d0006a41086a200341086a2900003703002002200437035020031023200220013602742002200241f4006aad4280808080c00084100d220329000037037820031023200241146a200241f8006a360200200241003a00182002200241f8006a41086a36020c2002200241f4006a3602102002200241f8006a360208200241c0006a200241086a10650240024002400240024002402002280248220541206a2201417f4c0d0020022802402106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422074110200741104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290330370000200341086a200241306a41086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290350370010200341186a200241d0006a41086a2903003700000240200841606a20054f0d00200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a02402002280244450d00200610230b200241086a2003200110e101200241d0006a41086a2201200241116a290000370300200241d0006a41106a2207200241196a290000370300200241d0006a41186a2205200241216a290000370300200220022900093703500240024020022d00084101460d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002002290350370000200041186a2005290300370000200041106a2007290300370000200041086a20012903003700000b2003102320024180016a24000f0b102c000b102a000beb0e05017f017e047f017e067f230041f0016b2201240042002102200141d8006a41186a22034200370300200141d8006a41106a22044200370300200141d8006a41086a220542003703002001420037035841fea6c600ad4280808080a00184100c220629000021072005200641086a29000037030020012007370358200610234188a7c600ad4280808080e00084100c22062900002107200141c8006a41086a2208200641086a2900003703002001200737034820061023200420012903482207370300200141286a41086a22062005290300370300200141286a41106a2007370300200141286a41186a200829030037030020012001290358370328200141f8006a200141286a412010e10120012d00782108200320014191016a290000370300200420014189016a290000370300200520014181016a290000370300200120012900793703580240024020084101470d0020002001290358370000200041186a2003290300370000200041106a2004290300370000200041086a20052903003700000c010b200141f8006a41186a4200370300200141f8006a41106a22094200370300200141f8006a41086a220842003703002001420037037841e4dec400ad4280808080e00084100c220a29000021072008200a41086a29000037030020012007370378200a10234191dfc400ad4280808080e00084100c220a29000021072006200a41086a29000037030020012007370328200a102320092001290328220737030020052008290300370300200420073703002003200629030037030020012001290378370358200141f8006a200141d8006a10f702024002402001280278220a0d004104210a410021050c010b200129027c2202422088a721050b02400240200541246c2205450d002005415c6a2103200a210503400240024020052d00004101460d002003450d030c010b200541016a2800002106200541086a28020021082001200541106a28020036025c200120083602580240200641c28289aa04460d0020030d010c030b200141f8006a200141d8006a10f90320012903784202510d02200141f8006a41106a22052802002108200141f8006a41186a420037030020054200370300200141f8006a41086a220342003703002001420037037841db97c700ad4280808080f00084100c220629000021072003200641086a290000370300200120073703782006102341bbacc300ad4280808080a00184100c22062900002107200141286a41086a2209200641086a2900003703002001200737032820061023200520012903282207370300200141d8006a41086a2003290300370300200141d8006a41106a2007370300200141d8006a41186a200929030037030020012001290378370358200141f8006a200141d8006a412010890220012802782205410120051b21064100210302402008200129027c420020051b2207422088a74f0d00200620084105746a2205450d00200141086a41186a200541186a290000370300200141086a41106a200541106a290000370300200141086a41086a200541086a29000037030020012005290000370308410121030b0240200742ffffff3f83500d00200610230b2003450d02200141f8006a41186a2203200141086a41186a290300370300200141f8006a41106a2206200141086a41106a290300370300200141f8006a41086a2208200141086a41086a29030037030020012001290308370378200141d8006a41186a220b4200370300200141d8006a41106a220c4200370300200141d8006a41086a220542003703002001420037035841fea6c600ad4280808080a00184100c220929000021072005200941086a29000037030020012007370358200910234188a7c600ad4280808080e00084100c22092900002107200141c8006a41086a220d200941086a290000370300200120073703482009102320042001290348370000200441086a200d290300370000200141286a41086a2005290300370300200141286a41106a200c290300370300200141286a41186a200b290300370300200120012903583703280240412010212205450d0020052001290378370000200541186a2003290300370000200541106a2006290300370000200541086a2008290300370000200141286aad42808080808004842005ad4280808080800484100e20051023200041186a2003290300370000200041106a2006290300370000200041086a2008290300370000200020012903783700000c040b1033000b200541246a21052003415c6a21030c000b0b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000b02402002422088a72205450d00200541246c2103200a210503400240024020052d0000220641044b0d0002400240024020060e050400010204040b2005410c6a280200450d03200541086a28020010230c030b2005410c6a280200450d02200541086a28020010230c020b2005410c6a280200450d01200541086a28020010230c010b200541086a280200450d00200541046a28020010230b200541246a21052003415c6a22030d000b0b2002a72205450d00200541246c450d00200a10230b200141f0016a24000bae0503027f017e047f230041d0006b2202240041db97c700ad4280808080f00084100c22032900002104200241086a200341086a290000370300200220043703002003102341c5acc300ad4280808080800184100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad4280808080800484100d220129000037033020011023200241c4006a200341206a360200200241003a0048200220033602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200310232002280228220541206a2201417f4c0d0120022802202106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bd60201027f23004180036b220324002003200236020c20032001360208200341106a2002ad4220862001ad841010108b0102400240200328021022010d00200041003a00000c010b200328021421042003200341186a2802003602ec02200320013602e802200341c0016a200341e8026a10e502410121020240024020032d00c0014101470d004100210220034100360228200342013703202003410a3602f4022003200341086a3602f0022003200341206a3602fc02200341d4016a4101360200200342013702c40120034180c5c6003602c0012003200341f0026a3602d001200341fc026a4184a5c200200341c0016a10311a2003350228422086200335022084100a2003280224450d01200328022010230c010b200341206a200341c0016a41017241a00110a1051a200041016a200341206a41a00110a1051a0b200020023a00002004450d00200110230b20034180036a24000bea0703027f017e057f230041d0006b2202240041db97c700ad4280808080f00084100c22032900002104200241086a200341086a290000370300200220043703002003102341cdacc300ad4280808080800184100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240200141086a280200220541046a2203417f4c0d000240024002402003450d00200310212206450d0420024100360240200220063602382002200336023c200341034b0d02200341017422074104200741044b1b22074100480d0720032007460d0120062003200710252206450d080c010b20024100360240200241013602382002200336023c200341017422034104200341044b1b220710212206450d070b2002200736023c200220063602380b2006200128000036000020024104360240200128020421082005200241386a106102400240200228023c2207200228024022016b2005490d0020022802382103200721060c010b200120056a22032001490d05200741017422062003200620034b1b22064100480d050240024020070d00024020060d00410121030c020b200610212203450d080c010b2002280238210320072006460d0020032007200610252203450d070b2002200636023c200220033602380b200320016a2008200510a1051a2002200120056a2205ad4220862003ad84100d220129000037033020011023200241c4006a200320056a360200200241003a0048200220033602402002200241386a36023c2002200241306a360238200241206a200241386a106502402006450d00200310230b2002280228220741206a2205417f4c0d0020022802202108024002402005450d00200510212203450d032005410f4d0d01200521060c050b200541017422034110200341104b1b220610212203450d060c040b200541017422014110200141104b1b220641004e0d020c040b1032000b1033000b20052006460d0020032005200610252203450d020b20032002290300370000200341086a200241086a2903003700000240024020064170714110460d00200621010c010b200641017422014120200141204b1b22014100480d0120062001460d0020032006200110252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200141606a2007490d00200121060c010b200741206a22062007490d01200141017422092006200920064b1b22064100480d0120012006460d0020032001200610252203450d020b200341206a2008200710a1051a20002005360208200020063602042000200336020002402002280224450d00200810230b200241d0006a24000f0b102c000b102a000bc72606027f017e037f017e157f037e23004190066b220324000240024002400240024020012802000e03000102000b200341bc056a4101360200200342013702ac05200341a4c5c6003602a805200341043602ec01200341cccec6003602e8012003200341e8016a3602b805200341a8056a419ca8c700103a000b20022d0001210420022d00002102200341a8056a41086a2001410c6a280200360200200320012902043703a805200341e8016a20022004200341a8056a10b3030240024020032d00e8014104460d0020032903e8012105200041146a200341e8016a41086a2802003602002000410c6a2005370200410121010c010b410021010b200041003602040c010b200141106a28020021062001410c6a2802002104200141086a280200210720012802042108200341086a200141146a41c40010a1051a024002400240024002400240024002400240024002400240024020022d00000d0020022d00014101470d002002411a6a2901002109200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d00002119200241046a2d0000211a200241026a2f0100211b200341a8056a41186a4200370300200341a8056a41106a221c4200370300200341a8056a41086a22014200370300200342003703a80541db97c700ad4280808080f00084100c220229000021052001200241086a290000370300200320053703a8052002102341bbacc300ad4280808080a00184100c22022900002105200341c8046a41086a221d200241086a290000370300200320053703c80420021023201c20032903c8042205370300200341e8016a41086a2001290300370300200341e8016a41106a2005370300200341e8016a41186a201d290300370300200320032903a8053703e801200341a8056a200341e8016a412010890220032802a805210120032902ac052105200341e8016a410c6a200341346a290200370200200341fc016a2003413c6a29020037020020034184026a200341c4006a290200370200200341f0c2c98b063602e8012003200329022c3702ec01200341c8046a410c6a2006360200201d2004360200200320073602cc04200320083602c8042005420020011b21052001410120011b211e200341a8056a200341e8016a200341c8046a10b40320032802e805450d0220032802a8052101200341d0006a200341a8056a41047241cc0010a1051a2003419c016a200341d0006a41cc0010a1051a4120102122020d010c0e0b02402006450d002006410c6c21022007210103400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b410221012004450d0a2004410c6c450d0a200710230c0b0b200220093700182002200a3a00172002200b3a00162002200c3b00142002200d3a00132002200e3a00122002200f3b0010200220103a000f200220113a000e200220123b000c200220133a000b200220143a000a200220153b0008200220163a0007200220173a0006200220183b0004200220193a00032002201a3a00022002201b3b0000200320013602e801200341e8016a4104722003419c016a41cc0010a1051a20032005422088a73602bc02200320083602b80241d00010212201450d0c200341a8056a41086a2204200341e8016a41086a290300370300200341a8056a41106a2206200341e8016a41106a290300370300200341a8056a41186a2207200341e8016a41186a290300370300200320032903e8013703a805200341e8016a41286a290300210920034198026a290300211f200341e8016a41386a29030021202003290388022121200341c8046a200341a8026a10b503200141386a20203703002001201f370330200141286a200937030020012021370320200141186a2007290300370300200141106a2006290300370300200141086a2004290300370300200120032903a805370300200120032903c804370340200141c8006a200341c8046a41086a28020036020020034281808080103702d402200320023602d002410410212204450d082004200836000020034284808080c0003702dc03200320043602d803200341a8056a41a599c50010b603200341c8046a20032802a805220620032802b00510b70320032902cc04420020032802c80422041b21092004410120041b2107024020032802ac05450d00200610230b200320094220883e02cc04200320073602c804200341a8056a200341c8046a10b803200341a8056a41086a280200210620032802ac05211d20032802a8052104200341a8056a41a599c500200341d8036a10b903200341c8046a20032802a805220b20032802b0051089022006410020041b211c201d410020041b210a20032902cc04420020032802c80422061b211f2004410420041b211d2006410120061b2106024020032802ac05450d00200b10230b200341e0026a41206a201c360200200341fc026a200a360200200341e0026a41106a201f370300200341e0026a41086a200341d8036a41086a280200360200200320032903d8033703e0022003201d3602f802200320063602ec0202402009a7450d00200710230b200341a8056a41086a2204200141086a290300370300200341a8056a41106a200141106a290300370300200341a8056a41186a200141186a290300370300200341a8056a41206a200141206a290300370300200341a8056a41286a2207200141286a290300370300200341a8056a41306a220b200141306a290300370300200341a8056a41386a220c200141386a290300370300200341c8046a41086a220d200141cc006a280200360200200320012903003703a805200320012902443703c8042001280240220e450d0120034198036a41386a220f200c29030037030020034198036a41306a220c200b29030037030020034198036a41286a220b200729030037030020034198036a41206a2207200341a8056a41206a29030037030020034198036a41186a2210200341a8056a41186a29030037030020034198036a41106a2211200341a8056a41106a29030037030020034198036a41086a2212200429030037030020034188036a41086a2204200d280200360200200320032903a80537039803200320032903c80437038803200341d8036a41386a200f290300370300200341d8036a41306a200c290300370300200341d8036a41286a200b290300370300200341d8036a41206a2007290300370300200341d8036a41186a2010290300370300200341d8036a41106a2011290300370300200341d8036a41086a201229030037030020032003290398033703d8032003200e360298042003419c046a2207200329038803370200200741086a2004280200360200410410212204450d0820042008360000200341a8056a410c6a220741002900a59945370000200741086a41002900ad994537000020034284808080c0003702ac05200320043602a8052003200341d8036a3602c405200341a8046a200341a8056a10ba0320041023200341a8056a200341a8046a10bb03200320032802a805220720032802b005419ca8c70041004100108c0120032802002104024020032802ac05450d00200710230b024020044101460d00200341c8046a200341d8036a41d00010a1051a20034198056a200341d0026a108e02200341a8056a200341c8046a41d00010a1051a200341f8056a220241086a20034198056a41086a2802003602002002200329039805370200200341c8046a200341a8046a10bb0320032802c8042102200320032802d00436029c052003200236029805200341a8056a20034198056a10bc03024020032802cc04450d00200210230b024020032802ec052202450d00200241306c450d0020032802e80510230b024020032802fc0541ffffff3f71450d0020032802f80510230b200341c8046a41186a200341a8046a41186a290300370300200341c8046a41106a200341a8046a41106a290300370300200341c8046a41086a200341a8046a41086a290300370300200320032903a8043703c804410021020240201c41014b0d000240201c0e020005000b200341a8056a41186a200341c8046a41186a290300370300200341a8056a41106a200341c8046a41106a290300370300200341a8056a41086a200341c8046a41086a290300370300200320032903c8043703a805410021020c050b201c2104034020022004410176220620026a2207201d200741246c6a28020020084b1b2102200420066b220441014b0d000c040b0b200328029c042204450d01200441306c450d0120032802980410230c010b02402005a722060d00419084c300210441252102410021010c0a0b419084c30021044125210241002101200641ffffff3f710d060c090b20011023200341003602c002024020032802e402450d0020032802e00210230b0240201f42ffffff3f83500d00200610230b0240200a450d00200a41246c450d00201d10230b200210230c020b0240201d200241246c6a28020022042008460d00200220042008496a21020b200341a8056a41186a200341c8046a41186a290300370300200341a8056a41106a200341c8046a41106a290300370300200341a8056a41086a200341c8046a41086a290300370300200320032903c8043703a805201c20024f0d002002201c1038000b0240201c200a470d00200341e0026a41186a200a410110a20120032802f802211d0b201d200241246c6a220441246a2004201c20026b41246c10a2051a20042008360200200420032903a8053702042004410c6a200341a8056a41086a2202290300370200200441146a200341a8056a41106a22062903003702002004411c6a200341a8056a41186a22042903003702002003201c41016a360280032004200341c8046a41186a2903003703002006200341c8046a41106a2903003703002002200341c8046a41086a290300370300200320032903c8043703a805024020032802f402220720032802f002470d00200341e0026a410c6a20074101109a0120032802f40221070b20032802ec02221c20074105746a221d20032903a805370000201d41186a2004290300370000201d41106a2006290300370000201d41086a20022903003700002003200741016a22073602f40220011023200341c0026a201c201c20074105746a10bd03200341a8056a41206a200341e0026a41206a28020022013602002004200341e0026a41186a29030022093703002006200341e0026a41106a2903003703002002200341e0026a41086a290300370300200320032903e0023703a805200341d8036a2009a72204200110be03200341c8046a41a599c50010b60320032802c8042101200320032802d00436029c03200320013602980320032802d803220220032802e00320034198036a10c802024020032802cc04450d00200110230b024020032802dc03450d00200210230b200341c8046a41a599c500200341a8056a10b90320032802c8042101200320032802d0043602dc03200320013602d80320032802b4052202200341bc056a280200200341d8036a10bf03024020032802cc04450d00200110230b024020032802ac05450d0020032802a80510230b0240200341b8056a28020041ffffff3f71450d00200210230b0240200341c4056a2802002201450d00200141246c450d00200410230b20032802c0022106024020032802d40241ffffff3f71450d0020032802d00210230b20060d010b0240200341ac026a2802002201450d00200141306c450d0020032802a80210230b2005a722060d0141b584c300210441182102410021010c050b200341c8026a280200210420032802c402211d200341003602b005200342043703a805200341a8056a41002004107920032802a805210720032802b005211c0240024020040d0020032802ac052102200641002007201c20032802b80210c003211c0c010b2007201c4102746a21012004210203402001418094ebdc03360200200141046a21012002417f6a22020d000b20032802ac052102200620042007201c20046a20032802b80210c003211c0b410410212201450d0220012008360000200341b0056a4284808080c000370300200341b8056a41002900a59945370300200341c0056a41002900ad9945370300200341c8056a201c3a0000200320013602ac05200341043a00a805200341a8056a10e0010240200241ffffffff0371450d00200710230b02402004450d00200441e0006c2102200641d4006a210103400240200141706a2802002204450d00200441306c450d002001416c6a28020010230b0240200128020041ffffff3f71450d002001417c6a28020010230b200141e0006a2101200241a07f6a22020d000b0b0240201d450d00201d41e0006c450d00200610230b0240200341ac026a2802002201450d00200141306c450d0020032802a80210230b02402005a72201450d00200141ffffff3f71450d00201e10230b41002101200041003602040c050b41b584c30021044118210241002101200641ffffff3f71450d030b201e10230c020b1033000b0b20004100360204200041146a2002360200200041106a20043602002000410c6a2001360200410121010b2000200136020020034190066a24000f0b102a000bca0b03057f017e067f23004180016b22052400200541d0006a2001108d0341002106200541086a200528025022072005280258419ca8c70041004100108c012005280208210802402005280254450d00200710230b02400240024020084101470d004111210841e5aac30021010c010b024020020d00200541d0006a41186a4200370300200541d0006a41106a22094200370300200541d0006a41086a22064200370300200542003703504196adc300ad4280808080900184100c2207290000210a200541f0006a41086a2208200741086a2900003703002005200a37037020071023200620082903003703002005200529037037035041b0dfc300ad4280808080a00184100c2207290000210a2008200741086a2900003703002005200a3703702007102320092005290370220a370300200541306a41086a2006290300370300200541306a41106a200a370300200541306a41186a200829030037030020052005290350370330200541206a200541306a10c90302400240024002400240024002402005280220220b0d004100210820054100360218200542043703104100210c4100210d0c010b2005290224210a2005200b3602102005200a370214200aa7210c41002108024002400240200a422088a7220d41014b0d00200d0e020201020b200d2106034020082006410176220720086a220e200b200e4102746a28020020014b1b2108200620076b220641014b0d000b0b4101210e200b20084102746a28020022062001460d03200d200820062001496a2208490d040b200d200c470d010b200541106a200c410110792005280214210c2005280210210b0b200b20084102746a220641046a2006200d20086b41027410a2051a200620013602002005200d41016a220d3602184106210e0b200541d0006a41186a220f4200370300200541d0006a41106a22104200370300200541d0006a41086a22064200370300200542003703504196adc300ad4280808080900184100c2207290000210a200541f0006a41086a2208200741086a2900003703002005200a37037020071023200620082903003703002005200529037037035041b0dfc300ad4280808080a00184100c2207290000210a2008200741086a2900003703002005200a3703702007102320092005290370370000200941086a2008290300370000200541306a41086a2006290300370300200541306a41106a2010290300370300200541306a41186a200f29030037030020052005290350370330200b0d01200541306aad428080808080048410110c020b2008200d1038000b200541203602542005200541306a360250200b200d200541d0006a10d502200c41ffffffff0371450d00200b10230b200e4106460d00419fabc300210141102108410421060240024002400240200e417f6a0e050001020305000b41e5aac300210141112108410021060c040b41f6aac3002101410e2108410121060c030b4184abc3002101410f2108410221060c020b4193abc3002101410c2108410321060c010b2004280208210e2004280204210b20042802002108200328020421042003280208210d20032802002106200541d0006a200110d2032005280250210720052005280258360234200520073602302006200d200541306a10c80202402005280254450d00200710230b02402004450d00200610230b200541d0006a200110ca032005280250210620052005280258360234200520063602302008200e200541306a10c80202402005280254450d00200610230b0240200b450d00200810230b200541d0006a2001108d032005350258210a200528025021010240410110212208450d00200820023a0000200a4220862001ad842008ad42808080801084100e2008102302402005280254450d00200110230b200041043a00000c020b102a000b20004183243b0100200041086a2008360200200041046a2001360200200041026a20063a00000240200441046a280200450d00200428020010230b200341046a280200450d00200328020010230b20054180016a24000bb80904067f017e047f017e230041d0006b22022400200241206a2001108d034102210302402002280220220420022802282205108e0341ff017122064102460d002005ad4220862004ad841011200621030b02402002280224450d00200410230b41022003410171200341024622031b21040240024002400240024002400240024020030d0020044101710d04200241206a41186a4200370300200241206a41106a22074200370300200241206a41086a22044200370300200242003703204196adc300ad4280808080900184100c22052900002108200241c0006a41086a2203200541086a2900003703002002200837034020051023200420032903003703002002200229034037032041b0dfc300ad4280808080a00184100c220529000021082003200541086a2900003703002002200837034020051023200720022903402208370300200241086a2004290300370300200241106a2008370300200241186a200329030037030020022002290320370300200241206a200210c9034101210920022802202203410420031b210a2002290224420020031b2208422088a7220b41014b0d0141002103200b0e020302030b41e5aac3002103411121014100210502400240024020040e03000201000b200241346a410136020020024201370224200241a4c5c60036022020024104360204200241c8abc30036020020022002360230200241206a419ca8c700103a000b41f6aac3002103410e2101410121050b200041123a0001200041086a2001360200200041046a2003360200200041026a20053a00000c050b41002103200b2104034020032004410176220520036a2206200a20064102746a28020020014b1b2103200420056b220441014b0d000b0b200a20034102746a22042802002001470d002003200b4f0d022004200441046a2003417f73200b6a41027410a2051a200842ffffffff0f832108200b417f6a210b410021090b200241206a41186a22064200370300200241206a41106a220c4200370300200241206a41086a22044200370300200242003703204196adc300ad4280808080900184100c2205290000210d200241c0006a41086a2203200541086a2900003703002002200d37034020051023200420032903003703002002200229034037032041b0dfc300ad4280808080a00184100c2205290000210d2003200541086a2900003703002002200d3703402005102320072002290340370000200741086a2003290300370000200241086a2004290300370300200241106a200c290300370300200241186a2006290300370300200220022903203703002002412036022420022002360220200a200b200241206a10d5020240200842ffffffff0383500d00200a10230b2009450d0020004192023b0001200041086a410e360200200041046a41f6aac3003602000c020b200241206a200110d203200235022842208620022802202203ad84101102402002280224450d00200310230b200241206a200110ca03200235022842208620022802202203ad84101102402002280224450d00200310230b200241206a2001108d03200235022842208620022802202203ad84101102402002280224450d00200310230b410421030c020b2003200b103b000b410321030b200020033a0000200241d0006a24000bf90403027f017e057f230041d0006b220224004196adc300ad4280808080900184100c22032900002104200241086a200341086a2900003703002002200437030020031023419fadc300ad4280808080f00084100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bf90403027f017e057f230041d0006b220224004196adc300ad4280808080900184100c22032900002104200241086a200341086a29000037030020022004370300200310234184e2c300ad4280808080d00084100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000b940201037f230041d0006b220224002002200136020420022000360200200241086a2001ad4220862000ad841010108b0102400240200228020822010d00410221000c010b200228020c210302400240200241106a280200450d0020012d0000220441014b0d0041002100024020040e020200020b410121000c010b20024100360220200242013703182002410a36022c200220023602282002200241186a360234200241cc006a41013602002002420137023c20024180c5c6003602382002200241286a360248200241346a4184a5c200200241386a10311a2002350220422086200235021884100a0240200228021c450d00200228021810230b410221000b2003450d00200110230b200241d0006a240020000bda0905047f017e0b7f027e027f230041e0016b220224002002412036021c20022001360218200241206a2001ad42808080808004841010108b010240024002400240200228022022030d00200041003602000c010b200228022421042002200241286a28020036023420022003360230200241106a200241306a1088010240024020022802100d00200228021422052002280234410c6e2201200120054b1bad420c7e2206422088a70d032006a72201417f4c0d030240024020010d00410421070c010b200110212207450d050b200241003602402002200736023820022001410c6e36023c02400240024002402005450d0041002108410021090340200241086a200241306a10880120022802080d04200228020c220a2002280234220141246e220b200b200a4b1bad42247e2206422088a70d082006a7220b417f4c0d0802400240200b0d004104210c0c010b200b1021220c450d0a0b200241003602502002200c3602482002200b41246e36024c0240200a450d004100210d4100210e034020014104490d05200e41016a210e20022001417c6a220f36023420022002280230221041046a3602302010280000211141002101200241003a00d8010340200f2001460d05200241b8016a20016a201020016a220b41046a2d00003a00002002200b41056a3602302002200141016a220b3a00d801200b2101200b4120470d000b200241f8006a41086a200241b8016a41086a2903002206370300200241f8006a41106a200241b8016a41106a2903002212370300200241f8006a41186a200241b8016a41186a2903002213370300200241d8006a41086a22102006370300200241d8006a41106a22142012370300200241d8006a41186a221520133703002002200f200b6b2201360234200220022903b8012206370378200220063703580240200d200228024c470d00200241c8006a200d410110a2012002280248210c2002280250210d0b200c200d41246c6a220b2011360200200b2002290358370204200b410c6a2010290300370200200b41146a2014290300370200200b411c6a20152903003702002002200d41016a220d360250200e200a470d000b0b200c450d04200941016a2109200229024c210602402008200228023c470d00200241386a2008410110950120022802382107200228024021080b20072008410c6c6a220120063702042001200c3602002002200841016a220836024020092005470d000b0b2007450d032000200229023c370204200020073602000c040b20024100360234200141ff0171450d00200241003a00d8010b200228024c2201450d00200141246c450d00200c10230b02402008450d002008410c6c210b2007210103400240200141046a280200220f450d00200f41246c450d00200128020010230b2001410c6a2101200b41746a220b0d000b0b200228023c2201450d002001410c6c450d00200710230b200241003602a00120024201370398012002410a36027c2002200241186a360278200220024198016a360258200241cc016a4101360200200242013702bc0120024180c5c6003602b8012002200241f8006a3602c801200241d8006a4184a5c200200241b8016a10311a20023502a00142208620023502980184100a0240200228029c01450d0020022802980110230b200041003602000b2004450d00200310230b200241e0016a24000f0b1032000b1033000bfb0401097f230041106b22022400024002400240024020002802082203410c6c41046a2204417f4c0d00200028020021050240024020040d00410121000c010b200410212200450d020b20024100360208200220043602042002200036020020032002106102402003450d0020052003410c6c6a2106034020052802002104200528020822032002106102402003450d002004200341246c6a2107200228020421002002280208210303402004280200210802400240200020036b4104490d00200228020021092000210a0c010b200341046a220a2003490d0720004101742209200a2009200a4b1b220a4100480d070240024020000d000240200a0d00410121090c020b200a102122090d010c0a0b200228020021092000200a460d0020092000200a10252209450d090b2002200a360204200220093602000b200920036a20083600002002200341046a220836020802400240200a20086b4120490d00200341246a2103200a21000c010b200841206a22032008490d07200a41017422002003200020034b1b22004100480d0702400240200a0d00024020000d00410121090c020b200010212209450d0a0c010b200a2000460d002009200a200010252209450d090b20022000360204200220093602000b200920086a220a200441046a290000370000200a41186a2004411c6a290000370000200a41106a200441146a290000370000200a41086a2004410c6a29000037000020022003360208200441246a22042007470d000b0b2005410c6a22052006470d000b0b200228020421032001290200200235020842208620022802002204ad84100e02402003450d00200410230b200241106a24000f0b1032000b1033000b102c000b102a000bd00a04057f017e0b7f027e230041c0026b220224002002412036020c20022001360208200241106a2001ad42808080808004841010108b0102400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a1088010240024020022802000d0002400240024002402002280204220520022802242206412c6e2201200120054b1bad422c7e2207422088a70d002007a72201417f4c0d000240024020010d00410421080c010b200110212208450d020b41002109200241003602302002200836022820022001412c6e36022c02402005450d004100210a034020064104490d0520022006417c6a220b36022420022002280220220c41046a2201360220200b450d05200c280000210d20022006417b6a220b3602242002200141016a36022020012d0000220141014b0d054102210e0240024020010e020100010b41002101200241003a00b8022006417b6a210f417a210b02400240024002400340200f2001460d0120024198026a20016a200c20016a220e41056a2d00003a000020022006200b6a3602242002200e41066a3602202002200141016a220e3a00b802200b417f6a210b200e2101200e4120470d000b200241f8016a41186a221020024198026a41186a290300370300200241f8016a41106a221120024198026a41106a290300370300200241f8016a41086a221220024198026a41086a29030037030020022002290398023703f801200f200e460d0920022006200b6a220b3602242002200c200e6a220141066a220f360220200141056a2d0000220c41014b0d09200c0e020201020b200141ff0171450d08200241003a00b8020c080b200b4104490d0720022006200e6b41766a220b36022420022001410a6a360220200f280000210f4101210e0c010b4100210e0b200241b8016a41086a2012290300220737030020024198016a41186a201029030037030020024198016a41106a201129030037030020024198016a41086a2007370300200220022903f80122073703b80120022007370398010b200a41016a210a200241d8006a41086a20024198016a41086a2903002207370300200241d8006a41106a20024198016a41106a2903002213370300200241d8006a41186a20024198016a41186a2903002214370300200241386a41086a22062007370300200241386a41106a220c2013370300200241386a41186a22102014370300200220022903980122073703582002200737033802402009200228022c470d00200241286a2009410110a60120022802282108200228023021090b20082009412c6c6a2201200d3602002001200229033837020420102903002107200c290300211320062903002114200141286a200f360200200141246a200e3602002001410c6a2014370200200141146a20133702002001411c6a20073702002002200941016a2209360230200b2106200a2005470d000b0b2008450d042000200229022c370204200020083602000c050b1032000b1033000b200241b8016a41186a200241d8016a41186a290300370300200241b8016a41106a200241d8016a41106a2903003703000b200228022c2201450d002001412c6c450d00200810230b2002410036028002200242013703f8012002410a3602dc012002200241086a3602d8012002200241f8016a3602b801200241ac026a41013602002002420137029c0220024180c5c600360298022002200241d8016a3602a802200241b8016a4184a5c20020024198026a10311a20023502800242208620023502f80184100a024020022802fc01450d0020022802f80110230b200041003602000b2004450d00200310230b200241c0026a24000bf90403027f017e057f230041d0006b220224004196adc300ad4280808080900184100c22032900002104200241086a200341086a290000370300200220043703002003102341e0e1c300ad4280808080b00184100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bc89001070c7f017e087f027e0c7f017e0b7f23004190106b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b2003418c0d6a4101360200200342013702fc0c200341a4c5c6003602f80c2003410436028c0a200341cccec6003602880a2003200341880a6a3602880d200341f80c6a419ca8c700103a000b200341d80c6a41086a200241106a290200370300200341d80c6a41106a200241186a290200370300200341d80c6a41186a200241206a2802003602002003200241086a2902003703d80c200141046a28020022042001410c6a280200220541b0026c6a2106200141086a2802002107200421012005450d28200241046a2802002108200341f80c6a41047221090240024002400240024020022d000041ff01714101470d004100210220042101034020012802002105200341880a6a200141046a220a41ac0210a1051a200341f80c6a200a41ac0210a1051a20054116460d2c200341d8076a200341f80c6a41ac0210a1051a200341a8056a200341d8076a41ac0210a1051a200341f8026a200341a8056a41ac0210a1051a200341c8006a200341f8026a41ac0210a1051a200320053602f80c2009200341c8006a41ac0210a1051a2003200836028c0a200341013a00880a200341d8076a200341f80c6a200341880a6a10cf0220032802d8074101460d02200241016a2102200141b0026a22012006470d000c2d0b0b024020022d0001220141ff01710d004100210220042101034020012802002105200341880a6a200141046a220a41ac0210a1051a200341f80c6a200a41ac0210a1051a20054116460d2b200341d8076a200341f80c6a41ac0210a1051a200341a8056a200341d8076a41ac0210a1051a200341f8026a200341a8056a41ac0210a1051a200341c8006a200341f8026a41ac0210a1051a200320053602f80c2009200341c8006a41ac0210a1051a200341003b01880a200341d8076a200341f80c6a200341880a6a10cf0220032802d8074101460d03200241016a2102200141b0026a22012006470d000c2d0b0b200241026a2f0100210b200341880a6a4102722105200341b80c6a410672210c200141ff0171210d410021022004210103402001280200210a200341880a6a200141046a220e41ac0210a1051a200341f80c6a200e41ac0210a1051a0240200a4116470d00200141b0026a21010c2f0b200341d8076a200341f80c6a41ac0210a1051a200341a8056a200341d8076a41ac0210a1051a200341f8026a200341a8056a41ac0210a1051a200341c8006a200341f8026a41ac0210a1051a2003200a3602f80c2009200341c8006a41ac0210a1051a4102210a0240200d4102460d00200c20032903d80c370100200c41086a200341d80c6a41086a290300370100200c41106a200341d80c6a41106a290300370100200c41186a200341d80c6a41186a2f01003b0100200320083601ba0c2003200b3b01b80c4101210a0b200520032903b80c370000200541086a200341b80c6a41086a290300370000200541106a200341b80c6a41106a290300370000200541186a200341b80c6a41186a2903003700002003200a3a00890a200341003a00880a200341d8076a200341f80c6a200341880a6a10cf0220032802d8074101460d03200241016a2102200141b0026a22012006460d2c0c000b0b200141b0026a21010c020b200141b0026a21010c010b200141b0026a21010b200341980a6a200341d8076a41146a2802002205360200200341880a6a41086a200341d8076a410c6a290200220f370300200320032902dc073703880a200341f80c6a41086a2002360200200341f80c6a410c6a200f370200200341f80c6a41146a2005360200200341003a00fc0c200341093a00f80c200341f80c6a10e001024020062001460d0003402001109e032006200141b0026a2201470d000b0b02402007450d00200741b0026c450d00200410230b410021010c2a0b41022105200141046a280200210620022d00000d0520022d00014101470d052002411a6a290100210f200241196a2d00002105200241186a2d00002109200241166a2f0100210a200241156a2d00002108200241146a2d0000210c200241126a2f0100210e200241116a2d00002104200241106a2d000021072002410e6a2f0100210d2002410d6a2d0000210b2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f01002102200141026a2f01002117411210212201450d03200141086a41002900d69546370000200141002900ce954637000020014112413010252201450d042001200f370028200120053a0027200120093a00262001200a3b0024200120083a00232001200c3a00222001200e3b0020200120043a001f200120073a001e2001200d3b001c2001200b3a001b200120103a001a200120113b0018200120123a0017200120133a0016200120143b0014200120153a0013200120163a0012200120023b00102001413041e00010252202450d04200220173b00302002ad4280808080a0068410182201290000210f200141086a2900002118200141106a2900002119200341b80c6a41186a2205200141186a290000370300200341b80c6a41106a22092019370300200341b80c6a41086a220a20183703002003200f3703b80c2001102320021023200341093a00980d2003410a3a00980d2003410b3a00980d200320032f01b80c3b01f80c200320032801ba0c3601fa0c200320032f01be0c3b01fe0c2003200a2f01003b01800d200320032d00c20c3a00820d2003410c3a00980d200320032d00c30c3a00830d2003410d3a00980d200320032d00c40c3a00840d2003410e3a00980d200320032d00c50c3a00850d2003410f3a00980d200320032d00c60c3a00860d200341103a00980d200320032d00c70c3a00870d200341113a00980d200320092d00003a00880d200320032d00c90c3a00890d200341123a00980d200341133a00980d200320032d00ca0c3a008a0d200341143a00980d200320032d00cb0c3a008b0d200341153a00980d200320032d00cc0c3a008c0d200341163a00980d200320032d00cd0c3a008d0d200341173a00980d200320032d00ce0c3a008e0d200341183a00980d200320032d00cf0c3a008f0d200341193a00980d200320052d00003a00900d200320032d00d10c3a00910d2003411a3a00980d2003411b3a00980d200320032d00d20c3a00920d2003411c3a00980d200320032d00d30c3a00930d2003411d3a00980d200320032d00d40c3a00940d2003411e3a00980d200320032d00d50c3a00950d2003411f3a00980d200320032d00d60c3a00960d200341203a00980d200320032d00d70c3a00970d200341a8056a41186a220520032903900d370300200341a8056a41106a220120032903880d370300200341a8056a41086a220220032903800d370300200320032903f80c3703a805200341d8076a41186a22092005290300370300200341d8076a41106a22052001290300370300200341d8076a41086a220a2002290300370300200320032903a8053703d807200341f80c6a200641b00210a1051a200341880a6a410a6a200a290300370100200341880a6a41126a2005290300370100200341880a6a411a6a200929030037010020034180023b01880a200320032903d80737018a0a200341a8056a200341f80c6a200341880a6a10cf020240024020032802a8054101470d0020032802ac054102470d010b20061023410021010c240b200341a8056a41146a28020021092001280200210a200341a8056a410c6a2802002105200228020021022006102341002101200541ff01714104460d23200541807e7121010c220b200141086a2802002109200141046a28020021042001411c6a280200210641022105024020022d00000d0020022d00014101470d002001410c6a2802002105200141186a280200211a200141146a280200211b200141106a280200211c200141026a2f0100210c200241196a2d00002101200241186a2d0000210a200241166a2f01002108200241156a2d0000210e200241146a2d00002107200241126a2f0100210d200241116a2d0000210b200241106a2d000021102002410e6a2f010021112002410d6a2d000021122002410c6a2d000021132002410a6a2f01002114200241096a2d00002115200241086a2d00002116200241066a2f01002117200241056a2d0000211d200241046a2d0000211e200241026a2f0100211f20032002411a6a2901003703f00c200320013a00ef0c2003200a3a00ee0c200320083b01ec0c2003200e3a00eb0c200320073a00ea0c2003200d3b01e80c2003200b3a00e70c200320103a00e60c200320113b01e40c200320123a00e30c200320133a00e20c200320143b01e00c200320153a00df0c200320163a00de0c200320173b01dc0c2003201d3a00db0c2003201e3a00da0c2003201f3b01d80c0240200c41ffff03710d0041de95c6002101410d210a410021080c1f0b024020050d0041eb95c60021014111210a410321080c1f0b0240200541e3004d0d0041fc95c60021014112210a410421080c1f0b200320053602e007200320093602dc07200320043602d807200341f80c6a41186a200341d80c6a41186a290300370300200341f80c6a41106a200341d80c6a41106a290300370300200341f80c6a41086a2201200341d80c6a41086a290300370300200320032903d80c3703f80c200341880a6a200341d8076a200341f80c6a10e40420032802880a4101460d06200341880a6a41086a2802002120200328028c0a21042001200341880a6a410c6a2802003602002003200c3b01840d200320043602fc0c200341ce95c6003602f80c200341b80c6a200341f80c6a10d603200341083a00980d2003410b3a00980d2003410c3a00980d200320032f01b80c3b01f80c200320032801ba0c3601fa0c200320032d00be0c3a00fe0c200320032800bf0c3600ff0c200320032d00c30c3a00830d2003410d3a00980d200320032d00c40c3a00840d2003410e3a00980d200320032d00c50c3a00850d2003410f3a00980d200320032d00c60c3a00860d200320032d00c70c3a00870d200341103a00980d200341113a00980d200320032d00c80c3a00880d200341123a00980d200320032d00c90c3a00890d200341133a00980d200320032d00ca0c3a008a0d200341143a00980d200320032d00cb0c3a008b0d200341153a00980d200320032d00cc0c3a008c0d200341163a00980d200320032d00cd0c3a008d0d200341173a00980d200320032d00ce0c3a008e0d200320032d00cf0c3a008f0d200341183a00980d200341193a00980d200320032d00d00c3a00900d2003411a3a00980d200320032d00d10c3a00910d2003411b3a00980d200320032d00d20c3a00920d2003411c3a00980d200320032d00d30c3a00930d2003411d3a00980d200320032d00d40c3a00940d2003411e3a00980d200320032d00d50c3a00950d2003411f3a00980d200320032d00d60c3a00960d200341203a00980d200320032d00d70c3a00970d200341a8056a41186a220120032903900d370300200341a8056a41106a220220032903880d370300200341a8056a41086a220520032903800d370300200320032903f80c3703a805200341c8006a41186a2001290300370300200341c8006a41106a2002290300370300200341c8006a41086a2005290300370300200320032903a805370348200341003602800d200342013703f80c2006200341f80c6a10dd0220032802fc0c210220033502800d42208620032802f80c2205ad8410182201290018210f20012d0017210720012d0016210d20012f0014210b20012d0013211020012d0012211120012f0010211220012d000f211320012d000e211420012f000c211520012d000b211620012d000a211720012f0008211d20012d0007211e20012d0006211f20012f0004212120012d0003212220012d0002212320012f000021242001102302402002450d00200510230b2003200f3703d00c200320073a00cf0c2003200d3a00ce0c2003200b3b01cc0c200320103a00cb0c200320113a00ca0c200320123b01c80c200320133a00c70c200320143a00c60c200320153b01c40c200320163a00c30c200320173a00c20c2003201d3b01c00c2003201e3a00bf0c2003201f3a00be0c200320213b01bc0c200320223a00bb0c200320233a00ba0c200320243b01b80c200341880a6a200341c8006a200341b80c6a10e504200341f80c6a20032802880a220120032802900a10e604200341b80c6a41086a2202200341f80c6a41086a290300370300200341b80c6a41106a2205200341f80c6a41106a290300370300200341a8056a41086a220a200341a00d6a290300370300200341a8056a41106a2208200341a80d6a290300370300200341a8056a41186a2225200341b00d6a290300370300200341a8056a41206a200341b80d6a290300370300200320032903f80c3703b80c2003200341f80c6a41206a2903003703a80520032802940d210e024020032802900d2209450d00200341c80f6a41106a2005290300370300200341c80f6a41086a2002290300370300200341f8026a41086a200a290300370300200341f8026a41106a2008290300370300200341f8026a41186a2025290300370300200341f8026a41206a200341a8056a41206a290300370300200320032903b80c3703c80f200320032903a8053703f8020b0240200328028c0a450d00200110230b02400240024020090d0041012109201c4101470d01418e96c60021014113210e41032105410b21084113210a0c020b200341a40a6a200e360200200341880a6a41206a20032903f802370300200341880a6a41106a200341c80f6a41106a290300370300200341880a6a41086a200341c80f6a41086a290300370300200341b00a6a200341f8026a41086a290300370300200341b80a6a200341f8026a41106a290300370300200341c00a6a200341f8026a41186a290300370300200341c80a6a200341f8026a41206a290300370300200320032903c80f3703880a200320093602a00a0240201c4101460d0041a196c6002101410b210a410921080c1c0b41ac96c6002101410e210a410a210820032802980a201b470d1b2003419c0a6a280200201a470d1b024002400240024020032802a80a220841014b0d004100210120080e020201020b410021012008210203402002410176220520016a220a20012009200a4105746a200341d80c6a412010a3054101481b2101200220056b220241014b0d000b0b200920014105746a200341d80c6a412010a3052202450d012002411f7620016a21010b200c417f6a41ffff0371200841ffff03714b0d1b0c190b200c41ffff0371200841ffff03714d0d1841ba96c6002101410f210a410121080c1b0b02400240200c41ffff037141014b0d00200341f80c6a200641b00210a1051a200341920a6a200341c8006a41086a2903003701002003419a0a6a200341c8006a41106a290300370100200341a20a6a200341e0006a29030037010020034180023b01880a2003200329034837018a0a200341d8076a200341f80c6a200341880a6a10cf02024020032802d8074101460d0041002109410421050c030b4100210920032802dc074102470d01410421050c020b200341186a200cad42ffff038342004280e8eda1ba01420010a6052003200329031822194280f092cbdd087c22183703d8072003200341186a41086a2903002018201954ad7c22193703e0072003200341d80c6a3602b80c2003200341d80c6a3602a8052003200341a8056a3602800d2003200341b80c6a3602fc0c2003200341d8076a3602f80c200341880a6a200341d80c6a200341f80c6a10fd020240024020032802880a4101470d00200341940a6a280200210a200341880a6a41086a280200210120032d008f0a210c20032d008e0a210820032d008d0a210e20032d008c0a21050c010b410421050240200341880a6a41086a2903004201520d00200341880a6a41106a290300212620032802a8052101200341b00d6a200341880a6a41186a290300370300200341a80d6a2026370300200341f80c6a41086a41003a0000200341810d6a2001290000370000200341890d6a200141086a290000370000200341910d6a200141106a290000370000200341990d6a200141186a290000370000200341023a00f80c200341f80c6a10e0010b0b0240200541ff01714104460d00410121090c020b200341880a6a41186a4200370300200341880a6a41106a22054200370300200341880a6a41086a22014200370300200342003703880a41e4dec400ad4280808080e00084100c220229000021262001200241086a290000370300200320263703880a2002102341f3dec400ad4280808080e00084100c22022900002126200341f80c6a41086a2209200241086a290000370300200320263703f80c20021023200520032903f80c2226370300200341a8056a41086a2001290300370300200341a8056a41106a2026370300200341a8056a41186a2009290300370300200320032903880a3703a805200341106a200341a8056a412010cd012003280214210220032802102105200341086a41d7ddc400411010cd01200328020c21092003280208210a20032f01d80c210820032d00da0c210c20032d00db0c210e20032f01dc0c211c20032d00de0c211b20032d00df0c211a20032f01e00c212520032d00e20c212720032d00e30c212820032f01e40c212920032d00e60c212a20032d00e70c212b20032f01e80c212c20032d00ea0c212d20032d00eb0c212e20032f01ec0c212f20032d00ee0c213020032d00ef0c213120032903f00c2126412010212201450d06200120032903d80c370000200141186a200341d80c6a41186a290300370000200141106a200341d80c6a41106a290300370000200141086a200341d80c6a41086a2903003700002003418c0d6a20094100200a1b360200200341b40d6a2026370200200341b30d6a20313a0000200341b20d6a20303a0000200341b00d6a202f3b0100200341af0d6a202e3a0000200341ae0d6a202d3a0000200341ac0d6a202c3b0100200341ab0d6a202b3a0000200341aa0d6a202a3a0000200341a80d6a20293b0100200341a70d6a20283a0000200341a60d6a20273a0000200341a40d6a20253b0100200341a30d6a201a3a0000200341a20d6a201b3a0000200341a00d6a201c3b01002003419f0d6a200e3a00002003419e0d6a200c3a0000200320193703800d200320183703f80c20032002410020051b3602880d200320083b019c0d200341940d6a428180808010370200200320013602900d2003200f3703d00c200320073a00cf0c2003200d3a00ce0c2003200b3b01cc0c200320103a00cb0c200320113a00ca0c200320123b01c80c200320133a00c70c200320143a00c60c200320153b01c40c200320163a00c30c200320173a00c20c2003201d3b01c00c2003201e3a00bf0c2003201f3a00be0c200320213b01bc0c200320223a00bb0c200320233a00ba0c200320243b01b80c200341880a6a200341c8006a200341b80c6a10e50420032802880a2101200320032802900a3602dc07200320013602d807200341f80c6a200341d8076a10e2040240200328028c0a450d00200110230b024020032802940d41ffffff3f71450d0020032802900d10230b2003419d0d6a2003290348370000200341850d6a200341d80c6a41086a2903003700002003418d0d6a200341d80c6a41106a290300370000200341950d6a200341d80c6a41186a290300370000200341a50d6a200341c8006a41086a290300370000200341ad0d6a200341c8006a41106a290300370000200341b50d6a200341c8006a41186a290300370000200341023a00fc0c200341093a00f80c200320032903d80c3700fd0c200341f80c6a10e0010240202041ffffff3f71450d00200410230b200610b4020c190b200341ec076a280200210a200341d8076a41106a2802002101200341d8076a41086a2802002102200341e4076a2802002205411876210c200541107621082005410876210e0b0240202041ffffff3f71450d00200410230b20090d1b0c1c0b200610b40220061023410021084100210e0c1e0b200141286a2802002105200141246a280200210c410221060240024020022d00000d0020022d00014101470d00200141196a290000210f200141186a2d0000211f200141176a2d0000211c200141156a2f0000211b200141146a2d0000211a200141136a2d00002121200141116a2f00002122200141106a2d000021232001410f6a2d000021242001410d6a2f000021202001410c6a2d000021252001410b6a2d00002127200141096a2f00002128200141086a2d00002129200141076a2d0000212a200141056a2f0000212b200141046a2d0000212c200141036a2d0000212d2001412c6a2802002106200141386a2802002131200141346a2802002130200141306a280200212f200141226a2f0100210a20012f0001212e200241196a2d00002101200241186a2d00002109200241166a2f01002108200241156a2d0000210e200241146a2d00002104200241126a2f01002107200241116a2d0000210d200241106a2d0000210b2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d0000211d200241026a2f0100211e20032002411a6a290100370360200320013a005f200320093a005e200320083b015c2003200e3a005b200320043a005a200320073b01582003200d3a00572003200b3a0056200320103b0154200320113a0053200320123a0052200320133b0150200320143a004f200320153a004e200320163b014c200320173a004b2003201d3a004a2003201e3b0148200a450d072006450d08200641e4004f0d09200320063602e007200320053602dc072003200c3602d807200341f80c6a41186a200341c8006a41186a290300370300200341f80c6a41106a2202200341c8006a41106a290300370300200341f80c6a41086a2201200341c8006a41086a290300370300200320032903483703f80c200341880a6a200341d8076a200341f80c6a10e40420032802880a4101460d01200341880a6a41086a280200210e200328028c0a210c2001200341880a6a410c6a2802003602002003200a3b01840d2003200c3602fc0c200341ce95c6003602f80c200341b80c6a200341f80c6a10d603200341083a00980d2003410b3a00980d2003410c3a00980d200320032f01b80c3b01f80c200320032801ba0c3601fa0c200320032d00be0c3a00fe0c200320032800bf0c3600ff0c200320032d00c30c3a00830d2003410d3a00980d200320032d00c40c3a00840d2003410e3a00980d200320032d00c50c3a00850d2003410f3a00980d200320032d00c60c3a00860d200320032d00c70c3a00870d200341103a00980d200341113a00980d200320032d00c80c3a00880d200341123a00980d200320032d00c90c3a00890d200341133a00980d200320032d00ca0c3a008a0d200341143a00980d200320032d00cb0c3a008b0d200341153a00980d200320032d00cc0c3a008c0d200341163a00980d200320032d00cd0c3a008d0d200341173a00980d200320032d00ce0c3a008e0d200320032d00cf0c3a008f0d200341183a00980d200341193a00980d200320032d00d00c3a00900d2003411a3a00980d200320032d00d10c3a00910d2003411b3a00980d200320032d00d20c3a00920d2003411c3a00980d200320032d00d30c3a00930d2003411d3a00980d200320032d00d40c3a00940d2003411e3a00980d200320032d00d50c3a00950d2003411f3a00980d200320032d00d60c3a00960d200320032d00d70c3a00970d200341203a00980d200341a8056a41186a220620032903900d370300200341a8056a41106a220520032903880d370300200341a8056a41086a220920032903800d370300200320032903f80c3703a805200341f8026a41186a2006290300370300200341f8026a41106a2005290300370300200341f8026a41086a2009290300370300200320032903a8053703f8022003200f3703d00c2003201f3a00cf0c2003201c3a00ce0c2003201b3b01cc0c2003201a3a00cb0c200320213a00ca0c200320223b01c80c200320233a00c70c200320243a00c60c200320203b01c40c200320253a00c30c200320273a00c20c200320283b01c00c200320293a00bf0c2003202a3a00be0c2003202b3b01bc0c2003202c3a00bb0c2003202d3a00ba0c2003202e3b01b80c200341880a6a200341f8026a200341b80c6a10e504200341f80c6a20032802880a220820032802900a10e604200341b80c6a41086a2001290300370300200341b80c6a41106a20022903003703002009200341a00d6a2903003703002005200341a80d6a2903003703002006200341b00d6a290300370300200341a8056a41206a2201200341b80d6a290300370300200320032903f80c3703b80c2003200341f80c6a41206a2903003703a80520032802940d2105024020032802900d2206450d00200341d80c6a41106a200341b80c6a41106a290300370300200341d80c6a41086a200341b80c6a41086a290300370300200341d8076a41086a200341a8056a41086a290300370300200341d8076a41106a200341a8056a41106a290300370300200341d8076a41186a200341a8056a41186a290300370300200341d8076a41206a2001290300370300200320032903b80c3703d80c200320032903a8053703d8070b0240200328028c0a450d00200810230b0240024020060d0041032106200a41014b0d0141c996c60021014111210241132108410221090c150b200341a40a6a2005360200200341880a6a41206a20032903d807370300200341880a6a41106a200341d80c6a41106a290300370300200341880a6a41086a200341d80c6a41086a290300370300200341b00a6a200341d8076a41086a290300370300200341b80a6a200341d8076a41106a290300370300200341c00a6a200341d8076a41186a290300370300200341c80a6a200341d8076a41206a290300370300200320032903d80c3703880a200320063602a00a0240202f4101460d0041a196c6002101410b2102410921090c140b41ac96c6002101410e2102410a210920032802980a2030470d132003419c0a6a2802002031470d13024020032802a80a2208200a490d0041c996c600210141112102410221090c140b410021010240200841014b0d00024020080e020011000b200341f80c6a41186a200341c8006a41186a290300370300200341f80c6a41106a200341c8006a41106a290300370300200341f80c6a41086a200341c8006a41086a290300370300200320032903483703f80c41002109200341f80c6a21020c110b2008210203402002410176220920016a220a20012006200a4105746a200341c8006a412010a3054101481b2101200220096b220241014b0d000c100b0b0240202f4101470d00418e96c600210141132108410b2109411321020c140b200341386a200aad42004280e8eda1ba01420010a6052003200329033822194280f092cbdd087c22183703a8052003200341386a41086a2903002018201954ad7c22193703b0052003200341c8006a3602c80f2003200341c8006a3602b80c2003200341b80c6a3602800d2003200341c80f6a3602fc0c2003200341a8056a3602f80c200341880a6a200341c8006a200341f80c6a10fd020240024020032802880a4101470d00200341940a6a2802002102200341880a6a41086a280200210120032d008f0a210a20032d008e0a210920032d008d0a210820032d008c0a21060c010b410421060240200341880a6a41086a2903004201520d00200341880a6a41106a290300212620032802b80c2101200341b00d6a200341880a6a41186a290300370300200341a80d6a2026370300200341f80c6a41086a41003a0000200341810d6a2001290000370000200341890d6a200141086a290000370000200341910d6a200141106a290000370000200341990d6a200141186a290000370000200341023a00f80c200341f80c6a10e0010b0b200641ff01714104470d13200341880a6a41186a4200370300200341880a6a41106a22064200370300200341880a6a41086a22014200370300200342003703880a41e4dec400ad4280808080e00084100c220229000021262001200241086a290000370300200320263703880a2002102341f3dec400ad4280808080e00084100c22022900002126200341f80c6a41086a2205200241086a290000370300200320263703f80c20021023200620032903f80c2226370300200341a8056a41086a2001290300370300200341a8056a41106a2026370300200341a8056a41186a2005290300370300200320032903880a3703a805200341306a200341a8056a412010cd012003280234210220032802302106200341286a41d7ddc400411010cd01200328022c21052003280228210920032f0148210a20032d004a210820032d004b210420032f014c210720032d004e210d20032d004f210b20032f0150211020032d0052211120032d0053211220032f0154211320032d0056211420032d0057211520032f0158211620032d005a211720032d005b211d20032f015c211e20032d005e212f20032d005f213020032903602126412010212201450d0420012003290348370000200141186a200341c8006a41186a290300370000200141106a200341c8006a41106a290300370000200141086a200341c8006a41086a2903003700002003418c0d6a2005410020091b360200200341b40d6a2026370200200341b30d6a20303a0000200341b20d6a202f3a0000200341b00d6a201e3b0100200341af0d6a201d3a0000200341ae0d6a20173a0000200341ac0d6a20163b0100200341ab0d6a20153a0000200341aa0d6a20143a0000200341a80d6a20133b0100200341a70d6a20123a0000200341a60d6a20113a0000200341a40d6a20103b0100200341a30d6a200b3a0000200341a20d6a200d3a0000200341a00d6a20073b01002003419f0d6a20043a00002003419e0d6a20083a0000200320193703800d200320183703f80c20032002410020061b3602880d2003200a3b019c0d200341940d6a428180808010370200200320013602900d2003200f3703d00c2003201f3a00cf0c2003201c3a00ce0c2003201b3b01cc0c2003201a3a00cb0c200320213a00ca0c200320223b01c80c200320233a00c70c200320243a00c60c200320203b01c40c200320253a00c30c200320273a00c20c200320283b01c00c200320293a00bf0c2003202a3a00be0c2003202b3b01bc0c2003202c3a00bb0c2003202d3a00ba0c2003202e3b01b80c200341880a6a200341f8026a200341b80c6a10e50420032802880a2101200320032802900a3602ac05200320013602a805200341f80c6a200341a8056a10e2040240200328028c0a450d00200110230b024020032802940d41ffffff3f71450d0020032802900d10230b2003419d0d6a20032903f802370000200341850d6a200341c8006a41086a2903003700002003418d0d6a200341c8006a41106a290300370000200341950d6a200341c8006a41186a290300370000200341a50d6a200341f8026a41086a290300370000200341ad0d6a200341f8026a41106a290300370000200341b50d6a200341f8026a41186a290300370000200341023a00fc0c200341093a00f80c200320032903483700fd0c200341f80c6a10e0010c100b41002109410021080c0c0b41002101200328028c0a220641ff01714104460d272006411876210a2006411076210920064108762108200341940a6a2802002102200341880a6a41086a28020021010c120b2001412c6a2802002109200141286a2802002105200141246a2802002108200141346a280200210e200141306a280200210c200141226a2f0100210a200341d80c6a41186a200141196a290000370300200341d80c6a41106a200141116a290000370300200341d80c6a41086a200141096a290000370300200320012900013703d80c410221064100210120022d00000d0720022d00014101470d07200241196a2d00002106200241186a2d00002104200241166a2f01002107200241156a2d0000210d200241146a2d0000210b200241126a2f01002110200241116a2d00002111200241106a2d000021122002410e6a2f010021132002410d6a2d000021142002410c6a2d000021152002410a6a2f01002116200241096a2d00002117200241086a2d0000211d200241066a2f0100211e200241056a2d0000211f200241046a2d0000211c200241026a2f0100211b20032002411a6a290100370360200320063a005f200320043a005e200320073b015c2003200d3a005b2003200b3a005a200320103b0158200320113a0057200320123a0056200320133b0154200320143a0053200320153a0052200320163b0150200320173a004f2003201d3a004e2003201e3b014c2003201f3a004b2003201c3a004a2003201b3b014841132102410321060240200a41ffff03710d0041de95c600210a410d21090c090b024020090d004180800c210141eb95c600210a411121090c090b0240200941e3004d0d0041808010210141fc95c600210a411221090c090b200320093602e007200320053602dc07200320083602d807200341f80c6a41186a200341c8006a41186a290300370300200341f80c6a41106a2202200341c8006a41106a290300370300200341f80c6a41086a2201200341c8006a41086a290300370300200320032903483703f80c200341880a6a200341d8076a200341f80c6a10e404024020032802880a4101460d00200341880a6a41086a2802002104200328028c0a21082001200341880a6a410c6a2802003602002003200a3b01840d200320083602fc0c200341ce95c6003602f80c200341b80c6a200341f80c6a10d603200341083a00980d2003410b3a00980d2003410c3a00980d200320032f01b80c3b01f80c200320032801ba0c3601fa0c200320032d00be0c3a00fe0c200320032800bf0c3600ff0c200320032d00c30c3a00830d2003410d3a00980d200320032d00c40c3a00840d2003410e3a00980d200320032d00c50c3a00850d2003410f3a00980d200320032d00c60c3a00860d200320032d00c70c3a00870d200341103a00980d200341113a00980d200320032d00c80c3a00880d200341123a00980d200320032d00c90c3a00890d200341133a00980d200320032d00ca0c3a008a0d200341143a00980d200320032d00cb0c3a008b0d200341153a00980d200320032d00cc0c3a008c0d200341163a00980d200320032d00cd0c3a008d0d200341173a00980d200320032d00ce0c3a008e0d200320032d00cf0c3a008f0d200341183a00980d200341193a00980d200320032d00d00c3a00900d2003411a3a00980d200320032d00d10c3a00910d2003411b3a00980d200320032d00d20c3a00920d2003411c3a00980d200320032d00d30c3a00930d2003411d3a00980d200320032d00d40c3a00940d2003411e3a00980d200320032d00d50c3a00950d2003411f3a00980d200320032d00d60c3a00960d200320032d00d70c3a00970d200341203a00980d200341a8056a41186a220620032903900d370300200341a8056a41106a220520032903880d370300200341a8056a41086a220920032903800d370300200320032903f80c3703a805200341f8026a41186a2006290300370300200341f8026a41106a2005290300370300200341f8026a41086a2009290300370300200320032903a8053703f8022003200341d80c6a41186a2903003703d00c2003200341d80c6a41106a2903003703c80c2003200341d80c6a41086a2903003703c00c200320032903d80c3703b80c20034180106a200341f8026a200341b80c6a10e504200341f80c6a200328028010220a20032802881010e604200341b80c6a41086a2001290300370300200341b80c6a41106a20022903003703002009200341a00d6a2903003703002005200341a80d6a2903003703002006200341b00d6a290300370300200341a8056a41206a2201200341b80d6a290300370300200320032903f80c3703b80c2003200341f80c6a41206a2903003703a80502400240024020032802900d2206450d0020032802940d2105200341e80f6a41106a2202200341b80c6a41106a290300370300200341e80f6a41086a2207200341b80c6a41086a290300370300200341d8076a41086a220d200341a8056a41086a290300370300200341d8076a41106a220b200341a8056a41106a290300370300200341d8076a41186a2210200341a8056a41186a290300370300200341d8076a41206a2001290300370300200320032903b80c3703e80f200320032903a8053703d8070240200328028410450d00200a10230b200341c80f6a41166a2002290300220f370100410e2109200341c80f6a410e6a2007290300370100200341a80f6a41166a2201200f370100200341a80f6a41106a200341c80f6a41106a290100370300200320032903e80f3701ce0f200341a80f6a41086a200341c80f6a41086a290100370300200320032901c80f3703a80f200341880a6a41106a22022001290100370300200341880a6a41086a200341a80f6a410e6a290100370300200320032901ae0f3703880a200341a40a6a2005360200200320063602a00a200341c80a6a200341d8076a41206a290300370300200341c00a6a2010290300370300200341b80a6a200b290300370300200341b00a6a200d290300370300200341880a6a41206a20032903d80737030041808028210141ac96c600210a02402002280200200c470d002003419c0a6a280200200e470d00200341ac0a6a2201200341c8006a412010a305450d0341808020210141d5a4c600210a410821090b41132102200541ffffff3f71450d01200610230c010b0240200328028410450d00200a10230b4180801c210141930e210241cfc6c600210a410821090b0240200441ffffff3f71450d00200810230b41032106410021050c0b0b20032903880a210f2003200341880a6a41086a29030022183703b0052003200f3703a8050240200f201884500d00200320013602b80c200341d8076a2001200341a8056a200341b80c6a10ff0220032903d8074201520d0020032903e007210f200341b00d6a200341d8076a41106a290300370300200341a80d6a200f370300200341f80c6a41086a41003a0000200341810d6a2001290000370000200341890d6a200141086a290000370000200341910d6a200141106a290000370000200341990d6a200141186a290000370000200341023a00f80c200341f80c6a10e0010b200341b80c6a41186a200341d80c6a41186a290300370300200341b80c6a41106a200341d80c6a41106a290300370300200341b80c6a41086a200341d80c6a41086a290300370300200320032903d80c3703b80c200341f80c6a200341f8026a200341b80c6a10e50420033502800d42208620032802f80c2201ad841011024020032802fc0c450d00200110230b2003419d0d6a20032903f802370000200341850d6a200341c8006a41086a2903003700002003418d0d6a200341c8006a41106a290300370000200341950d6a200341c8006a41186a290300370000200341a50d6a200341f8026a41086a290300370000200341ad0d6a200341f8026a41106a290300370000200341b50d6a200341f8026a41186a290300370000200341053a00fc0c200341093a00f80c200320032903483700fd0c200341c40d6a200e360200200341c00d6a200c360200200341f80c6a10e001024020032802a40a41ffffff3f71450d0020032802a00a10230b0240200441ffffff3f71450d00200810230b410021010c270b41002101200328028c0a220641ff01714104460d262006418080807871210520064180807c71210120064108762102200341940a6a2802002109200341880a6a41086a280200210a0c090b1033000b102a000b200610b40220061023410021010c1c0b200341940a6a280200210a200341880a6a41086a2802002101200328028c0a2105200610b402200610232005411876210c200541107621082005410876210e0c160b41de95c6002101410d21024103210641132108410021090c050b41eb95c6002101411121024113210841032109410321060c040b41fc95c6002101411221024103210641132108410421090c030b410021020b0240200541ffffff3f71450d00200810230b410021050b200041146a2009360200200041106a200a3602002000410c6a2001418080fc0771200641ff01717220057220024108744180fe0371723602000c080b4100210a200541ffffff3f71450d06200c10230c060b0240200620014105746a200341c8006a412010a30522090d0041ba96c6002101410f2102410121090c040b200341f80c6a41186a200341c8006a41186a290300370300200341f80c6a41106a200341c8006a41106a290300370300200341f80c6a41086a200341c8006a41086a290300370300200320032903483703f80c200341f80c6a210220082009411f7620016a2209490d020b024020082005470d00200341880a6a41186a20054101109a0120032802a00a21060b200620094105746a220141206a2001200820096b41057410a2051a200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a290000370000200120022900003700002003200841016a3602a80a200341f80c6a200341880a6a41c80010a1051a2003200f3703d00c2003201f3a00cf0c2003201c3a00ce0c2003201b3b01cc0c2003201a3a00cb0c200320213a00ca0c200320223b01c80c200320233a00c70c200320243a00c60c200320203b01c40c200320253a00c30c200320273a00c20c200320283b01c00c200320293a00bf0c2003202a3a00be0c2003202b3b01bc0c2003202c3a00bb0c2003202d3a00ba0c2003202e3b01b80c200341a8056a200341f8026a200341b80c6a10e50420032802a8052101200320032802b0053602bc0c200320013602b80c200341f80c6a200341b80c6a10e204024020032802ac05450d00200110230b0240200341940d6a28020041ffffff3f71450d0020032802900d10230b2003419d0d6a20032903f802370000200341850d6a200341c8006a41086a2903003700002003418d0d6a200341c8006a41106a290300370000200341950d6a200341c8006a41186a290300370000200341a50d6a200341f8026a41086a290300370000200341ad0d6a200341f8026a41106a290300370000200341b50d6a200341f8026a41186a290300370000200341033a00fc0c200341093a00f80c200320032903483700fd0c200341c40d6a2031360200200341c00d6a2030360200200341f80c6a10e0010b0240200e41ffffff3f71450d00200c10230b410021010c180b200920081038000b0240200541ffffff3f71450d00200610230b41032106411321084100210a0b200e41ffffff3f71450d00200c10230b200041146a2002360200200041106a20013602002000410c6a200941ff0171411074200a41187472200841ff017141087472200641ff0171723602000b410121010c130b200341f80c6a200641b00210a1051a200341e2076a200341c8006a41086a290300370100200341ea076a200341d8006a290300370100200341f2076a200341e0006a29030037010020034180023b01d807200320032903483701da07200341a8056a200341f80c6a200341d8076a10cf0220032903880a21182003200341880a6a41086a29030022193703c00c200320183703b80c02402018201984500d002003200341ac0a6a22013602a80f200341d8076a2001200341b80c6a200341a80f6a10ff0220032903d8074201520d0020032903e0072118200341b00d6a200341d8076a41106a290300370300200341a80d6a2018370300200341f80c6a41086a41003a0000200341810d6a2001290000370000200341890d6a200141086a290000370000200341910d6a200141106a290000370000200341990d6a200141186a290000370000200341023a00f80c200341f80c6a10e0010b2003200f3703d00c200320073a00cf0c2003200d3a00ce0c2003200b3b01cc0c200320103a00cb0c200320113a00ca0c200320123b01c80c200320133a00c70c200320143a00c60c200320153b01c40c200320163a00c30c200320173a00c20c2003201d3b01c00c2003201e3a00bf0c2003201f3a00be0c200320213b01bc0c200320223a00bb0c200320233a00ba0c200320243b01b80c200341f80c6a200341c8006a200341b80c6a10e50420033502800d42208620032802f80c2201ad841011024020032802fc0c450d00200110230b200341f80c6a41186a200341d80c6a41186a290300370300200341f80c6a41106a200341d80c6a41106a290300370300200341f80c6a41086a200341d80c6a41086a290300370300200320032903d80c3703f80c20032f0148210220032d004a210520032d004b210920032f014c210a20032d004e210820032d004f210c20032f0150210e20032d0052210720032d0053210d20032f0154210b20032d0056211020032d0057211120032f0158211220032d005a211320032d005b211420032f015c211520032d005e211620032d005f21172003290360210f200320032900b5053703d8072003200341bc056a2800003600df070240024020032802a8054101460d00410421010c010b200341b4056a2d0000211e20032802ac05211d200320032800df073600bf0c200320032903d8073703b80c41042101201d4102460d00200320032800bf0c3600af0f200320032903b80c3703a80f201e21010b200341d8076a41086a221d200341f80c6a41086a290300370300200341d8076a41106a221e200341f80c6a41106a290300370300200341d8076a41186a221f200341f80c6a41186a290300370300200320032903f80c3703d807200320032903a80f3703e80f200320032800af0f3600ef0f200341b50d6a200f370000200341b40d6a20173a0000200341b30d6a20163a0000200341b10d6a20153b0000200341b00d6a20143a0000200341af0d6a20133a0000200341ad0d6a20123b0000200341ac0d6a20113a0000200341ab0d6a20103a0000200341a90d6a200b3b0000200341a80d6a200d3a0000200341a70d6a20073a0000200341a50d6a200e3b0000200341a40d6a200c3a0000200341a30d6a20083a0000200341a10d6a200a3b0000200341a00d6a20093a00002003419f0d6a20053a00002003419d0d6a20023b0000200341043a00fc0c200341093a00f80c200341850d6a201d2903003700002003418d0d6a201e290300370000200341950d6a201f290300370000200320032903d8073700fd0c200341c80d6a20013a0000200341c40d6a201a360200200341c00d6a201b360200200341bf0d6a200341ba0c6a2d00003a0000200341bd0d6a20032f00b80c3b0000200341d00d6a20032800ef0f360000200341c90d6a20032903e80f370000200341f80c6a10e001024020032802a40a41ffffff3f71450d0020032802a00a10230b202041ffffff3f71450d002004102320061023410021010c0a0b20061023410021010c090b200341f80c6a41186a200341d80c6a41186a290300370300200341f80c6a41106a200341d80c6a41106a290300370300200341f80c6a41086a200341d80c6a41086a290300370300200320032903d80c3703f80c024020082001490d0002402008200e470d00200341880a6a41186a200e4101109a0120032802a00a21090b200920014105746a220241206a2002200820016b41057410a2051a200241186a200341f80c6a41186a290300370000200241106a200341f80c6a41106a290300370000200241086a200341f80c6a41086a290300370000200220032903f80c3700002003200841016a3602a80a200341f80c6a200341880a6a41c80010a1051a2003200f3703d00c200320073a00cf0c2003200d3a00ce0c2003200b3b01cc0c200320103a00cb0c200320113a00ca0c200320123b01c80c200320133a00c70c200320143a00c60c200320153b01c40c200320163a00c30c200320173a00c20c2003201d3b01c00c2003201e3a00bf0c2003201f3a00be0c200320213b01bc0c200320223a00bb0c200320233a00ba0c200320243b01b80c200341d8076a200341c8006a200341b80c6a10e50420032802d8072101200320032802e0073602ac05200320013602a805200341f80c6a200341a8056a10e204024020032802dc07450d00200110230b0240200341940d6a28020041ffffff3f71450d0020032802900d10230b2003419d0d6a2003290348370000200341850d6a200341d80c6a41086a2903003700002003418d0d6a200341d80c6a41106a290300370000200341950d6a200341d80c6a41186a290300370000200341a50d6a200341c8006a41086a290300370000200341ad0d6a200341c8006a41106a290300370000200341b50d6a200341c8006a41186a290300370000200341033a00fc0c200341093a00f80c200320032903d80c3700fd0c200341c40d6a201a360200200341c00d6a201b360200200341f80c6a10e001410421050c020b200120081038000b41032105200e41ffffff3f71450d00200910230b0240202041ffffff3f71450d00200410230b4113210e4100210c0b200610b4020b200610230b200541ff01714104470d02410021010c030b200610b40220061023410321054113210e0b4100210c0240200941ffffff3f71450d00200410230b0b200041146a200a360200200041106a20013602002000410c6a200841ff0171411074200c41187472200e41ff017141087472200541ff017172360200410121010b200041086a20023602000c070b200041146a2009360200200041106a200a3602002000410c6a2001200541ff017172360200410121010b200041086a20023602000c050b200141b0026a21010c030b200141b0026a21010c020b200621010b200341f80c6a200341880a6a41ac0210a1051a0b024020062001460d0003402001109e032006200141b0026a2201470d000b0b02402007450d00200741b0026c450d00200410230b200341013a00fc0c200341093a00f80c200341f80c6a10e001410021010b200020013602002000410036020420034190106a24000bd69c0109067f047e0c7f027e037f017e027f0b7e0f7f230041b0106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0c000102030e0d0c0b0a090807000b200341840e6a4101360200200342013702f40d200341a4c5c6003602f00d2003410436029406200341cccec60036029006200320034190066a3602800e200341f00d6a419ca8c700103a000b200341b8036a200141196a290000370300200341b0036a200141116a290000370300200341a8036a200141096a290000370300200320012900013703a00320022d000121040240024020022d0000220141024b0d00024020010e03000102000b200441ff0171450d010b200420014100477241ff01710d050b200341f0006a109105200341f00d6a41186a2205200341a0036a41186a290300370300200341f00d6a41106a2206200341a0036a41106a290300370300200341f00d6a41086a2207200341a0036a41086a290300370300200320032903a0033703f00d02402003280278220220032802742208470d00200341f0006a20024101109f0120032802742108200328027821020b2003280270220420024106746a2201420037030820014201370300200141106a4200370300200141186a4200370300200141206a20032903f00d370300200141286a2007290300370300200141306a2006290300370300200141386a20052903003703002003200241016a220536027841f4c7c600ad4280808080800184100c220129000021092001290008210a2001102341a084c700ad4280808080a00184100c2201290000210b2001290008210c200110232003200c3702a8062003200b3702a0062003200a370298062003200937029006200341f00d6a2004200510d40220034190066aad428080808080048420033502f80d42208620032802f00d2201ad84100e024020032802f40d450d00200110230b0240200841ffffff1f71450d00200410230b200341fc0d6a2002360200200341f80d6a41063a00002003410a3a00f00d200341f00d6a10e0010c130b200341a0036a200141046a41a00210a1051a4102210120022d00000d0220022d00014101470d02200241196a2d00002101200241186a2d00002104200241166a2f01002108200241156a2d00002105200241146a2d00002106200241126a2f01002107200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820032002411a6a29010037038806200320013a008706200320043a008606200320083b018406200320053a008306200320063a008206200320073b0180062003200d3a00ff052003200e3a00fe052003200f3b01fc05200320103a00fb05200320113a00fa05200320123b01f805200320133a00f705200320143a00f605200320153b01f405200320163a00f305200320173a00f205200320183b01f005024020032802a803220141e4004b0d00200341086a2001ad42004280d0f29ce1c800420010a605200341f0006a200341f0056a109205200341f00d6a200328027022012003280278109305200341b80b6a200341f00d6a41a40210a1051a200341d0086a41086a22022003419d106a290000370300200341d0086a41106a2204200341a5106a290000370300200341d0086a41176a2208200341ac106a28000036000020032003290095103703d008200341086a41086a29030021192003290308211a0240024020032d00941022054102460d00200341f0086a200341b80b6a41a40210a1051a200341d0006a41176a2008280000360000200341d0006a41106a2004290300370300200341d0006a41086a2002290300370300200320032903d00837035002402003280274450d00200110230b200341f00d6a200341f0086a41a40210a1051a200341f00d6a41a4026a20053a000020034195106a20032903503700002003419d106a200341d0006a41086a290300370000200341a5106a200341d0006a41106a290300370000200341ac106a200341e7006a2800003600000240200341f00d6a41186a2802002206450d0020032802800e210141002102410021040340024002400240200141086a2205280200417f6a220841054b0d00024020080e06000101010100000b20020d01410021020c020b200241016a21020c010b200420026b220820064f0d07200341f0006a41186a2207200120024105746b220841186a220d290300370300200341f0006a41106a220e200841106a220f290300370300200341f0006a41086a2210200841086a22112903003703002003200829030037037020052903002109200141106a2212290300210a200141186a2213290300210b20082001290300370300200d200b370300200f200a37030020112009370300201320072903003703002012200e29030037030020052010290300370300200120032903703703000b200141206a21012006200441016a2204470d000b2002417f6a20064f0d002003200620026b3602880e0b2003418c0e6a2201108f052001200341a0036a41a00210a1051a20034190066a200341f00d6a41c00210a1051a20034190066a41086a290300210a200329039006210c0c010b02402003280274450d00200110230b200341a8066a41003602004200210c20034200370398062003420037039006200342083703a006200341ac066a200341a0036a41a00210a1051a4200210a0b2003201a4280c0caf384a3027c220937039006200320192009201a54ad7c220b3703980602402009200c58200b200a58200b200a5122071b0d002003200b200a7d2009200c54ad7d221a3703c00b20032009200c7d22193703b80b2003200341f0056a3602d0052019201a844200510d002003200341f0056a3602f0082003200341f0086a3602f80d2003200341d0056a3602f40d2003200341b80b6a3602f00d200341f0006a200341f0056a200341f00d6a10fd020240024020032802704101470d00200341fc006a2802002102200341f8006a280200210420032d0077210820032d0076210520032d0075210620032d007421010c010b410421010240200341f0006a41086a2903004201520d00200341f0006a41106a290300211a20032802f0082102200341a80e6a200341f0006a41186a290300370300200341a00e6a201a370300200341f00d6a41086a41003a0000200341f90d6a2002290000370000200341810e6a200241086a290000370000200341890e6a200241106a290000370000200341910e6a200241186a290000370000200341023a00f00d200341f00d6a10e0010b0b200141ff01714104460d000240200341a4066a28020041ffffff3f71450d0020032802a00610230b200341ac066a108f050c160b0240200c200958200a200b5820071b0d002003200a200b7d200c200954ad7d220a3703c00b2003200c20097d22093703b80b2009200a84500d002003200341f0056a3602f008200341f0006a200341f0056a200341b80b6a200341f0086a10ff0220032903704201520d0020032903782109200341a80e6a200341f0006a41106a290300370300200341a00e6a2009370300200341f00d6a41086a41003a0000200341f90d6a20032903f005370000200341810e6a200341f0056a41086a290300370000200341890e6a200341f0056a41106a290300370000200341910e6a20034188066a290300370000200341023a00f00d200341f00d6a10e0010b200341f00d6a20034190066a41c00210a1051a200341f0056a200341f00d6a10940541002101200341f00d6a41086a41003a0000200341f90d6a20032903f005370000200341810e6a200341f0056a41086a290300370000200341890e6a20034180066a290300370000200341910e6a20034188066a2903003700002003410a3a00f00d200341f00d6a10e0010c140b200341a0036a108f0541d6c5c6002104410d21024103210141142106410b21050c140b2001410c6a2802002108200141086a2802002104200141046a28020021054102210620022d00000d0f20022d00014101470d0f200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d0000211b200241046a2d0000211c200241026a2f0100211d20032002411a6a29010037038809200320013a008709200320063a008609200320073b0184092003200d3a0083092003200e3a0082092003200f3b018009200320103a00ff08200320113a00fe08200320123b01fc08200320133a00fb08200320143a00fa08200320153b01f808200320163a00f708200320173a00f608200320183b01f4082003201b3a00f3082003201c3a00f2082003201d3b01f008200341f00d6a200341f0086a109205200341286a20032802f00d220220032802f80d419ca8c70041004100108c0120032802282101024020032802f40d450d00200210230b41012107410321064114210d024020014101460d0041cfc6c60021104108210f0c110b0240200841e4004d0d0041d7c6c60021104112210f410021070c110b20034190066a200341f0086a109505200341f00d6a2003280290062202200328029806109605200341f00d6a41086a290300420020032802800e22011b210920032903f00d420020011b210a20032902840e210b0240200328029406450d00200210230b200b420020011b211e2001410120011b211f200341186a2008ad42004280c0a8ca9a3a420010a6050240200a200329031822195a2009200341186a41086a290300221a5a2009201a5122011b0d002003201a20097d2019200a54ad7d220b3703a80320032019200a7d220c3703a0032003200341f0086a3602b80b200c200b844200510d002003200341f0086a3602702003200341f0006a3602f80d2003200341b80b6a3602f40d2003200341a0036a3602f00d20034190066a200341f0086a200341f00d6a10fd02024002402003280290064101470d002003419c066a280200210f20034198066a280200211020032d009706210e20032d009606210720032d009506210d20032d00940621060c010b41042106024020034190066a41086a2903004201520d0020034190066a41106a290300210b20032802702102200341a80e6a20034190066a41186a290300370300200341a00e6a200b370300200341f00d6a41086a41003a0000200341f90d6a2002290000370000200341810e6a200241086a290000370000200341890e6a200241106a290000370000200341910e6a200241186a290000370000200341023a00f00d200341f00d6a10e0010b0b200641ff01714104460d00201e42ffffff3f83500d11201f10230c110b0240200a2019582009201a5820011b0d0020032009201a7d200a201954ad7d22093703a8032003200a20197d220a3703a003200a200984500d002003200341f0086a36027020034190066a200341f0086a200341a0036a200341f0006a10ff022003290390064201520d002003290398062109200341a80e6a20034190066a41106a290300370300200341a00e6a2009370300200341f00d6a41086a41003a0000200341f90d6a20032903f008370000200341810e6a200341f0086a41086a290300370000200341890e6a200341f0086a41106a290300370000200341910e6a20034188096a290300370000200341023a00f00d200341f00d6a10e0010b0240201e422088a74105742202450d00201f21010340200341f00d6a2001108b0520033502f80d42208620032802f00d2206ad841011024020032802f40d450d00200610230b200141206a2101200241606a22020d000b0b200341003602d805200342013703d005200341d0056a4100200841c4006c221b41c4006d109a0120032802d805211020032802d005211d024002400240024002400240201b450d002005201b6a2120201d20104105746a2102200341f00d6a41206a211c200341f00d6a41216a210820034190066a411f6a21114100210d0340200341b80b6a41186a22062005200d6a220141186a290200370300200341b80b6a41106a2207200141106a290200370300200341b80b6a41086a220e200141086a29020037030020034190066a41086a220f200141296a29000037030020034190066a41106a2212200141316a29000037030020034190066a41186a2213200141396a2900003703002011200141c0006a280000360000200320012902003703b80b2003200141216a29000037039006200141206a2d000022144106460d02200341a0036a41186a22152006290300370300200341a0036a41106a22162007290300370300200341a0036a41086a2217200e290300370300200320032903b80b3703a003200341f00d6a41186a2206200341f0086a41186a290300370300200341f00d6a41106a2207200341f0086a41106a290300370300200341f00d6a41086a2218200341f0086a41086a290300370300200320032903f0083703f00d200320143a00900e2008200329039006370000200841086a200f290300370000200841106a2012290300370000200841186a20132903003700002008411f6a2011280000360000200341f0056a200341a0036a108b0520033502f805210920032802f005210e412010212201450d15200120032903f00d370000200141186a2006290300370000200141106a2007290300370000200141086a2018290300370000200341f0006a201c10702003280270210f02400240200328027822060d00200641206a21070c010b200641206a22072006490d05200741c000200741c0004b1b22124100480d0520014120201210252201450d160b200141206a200f200610a1051a02402003280274450d00200f10230b2009422086200ead842007ad4220862001ad84100e20011023024020032802f405450d00200e10230b024020032d00900e4101470d0020032802980e450d0020032802940e10230b200341f0006a41086a20172903002209370300200341f0006a41106a2016290300220a370300200341f0006a41186a2015290300220b370300200320032903a003220c370370200241186a200b370000200241106a200a370000200241086a20093700002002200c370000201041016a2110200241206a2102201b200d41c4006a220d470d000b0b200320103602d8050c010b200320103602d805200141c4006a2020460d00200141e4006a2101201b200d6b41bc7f6a21020340024020012d00004101470d00200141086a280200450d00200141046a28020010230b200141c4006a2101200241bc7f6a22020d000b0b02402004450d00200441c4006c450d00200510230b20032802d405210e2010450d0e20034190066a200341f0086a109505201041057422064114722202417f4c0d022003350298062109200328029006210f200210212201450d01200120193700002001201a370008200341103602f80d200320023602f40d200320013602f00d2010200341f00d6a1061410020032802f80d22026b210520032802f00d210d20032802f40d2108201d21070340200721010240200820056a411f4b0d00200241206a22042002490d02200841017422072004200720044b1b22044100480d02024002400240024020080d00024020040d004101210d0c020b20041021210d0c030b20082004470d010b200421080c020b200d200820041025210d0b20042108200d450d130b200141206a2107200d20026a22042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a290000370000200541606a2105200241206a2102200641606a22060d000b2009422086200fad842002ad422086200dad84100e02402008450d00200d10230b0240200328029406450d00200f10230b200e41ffffff3f710d0f0c100b102c000b1033000b1032000b200820064184d9c4001030000b200341a0036a108f050c110b200041003602042000410c6a4102360200410121010c110b200141196a2900002109200141186a2d00002108200141176a2d00002105200141156a2f00002106200141146a2d00002107200141136a2d0000210d200141116a2f0000210e200141106a2d0000210f2001410f6a2d000021102001410d6a2f000021112001410c6a2d000021122001410b6a2d00002113200141096a2f00002114200141086a2d00002115200141076a2d00002116200141056a2f00002117200141046a2d00002118200141036a2d0000211b20022d0001210420012f0001211c0240024002400240024020022d0000220141024b0d00024020010e03000102000b200441ff0171450d010b4182a8082102200420014100477241ff01710d010b2003200937038806200320083a008706200320053a008606200320063b018406200320073a0083062003200d3a0082062003200e3b0180062003200f3a00ff05200320103a00fe05200320113b01fc05200320123a00fb05200320133a00fa05200320143b01f805200320153a00f705200320163a00f605200320173b01f405200320183a00f3052003201b3a00f2052003201c3b01f00520034190066a200341f0056a109505200341f00d6a20032802900622012003280298062202109605024020032802800e2208450d002002ad4220862001ad8410110b20032903f00d210920032802840e2104200341f80d6a290300210a200341880e6a280200210e0240200328029406450d00200110230b200341e00d6a200341f0056a109205200341f00d6a20032802e00d220220032802e80d2206109305024020032d009410220141024622050d002006ad4220862002ad8410110b200341b80b6a200341f00d6a41a40210a1051a200341980b6a41176a2206200341ac106a280000360000200341980b6a41106a2207200341a5106a290000370300200341980b6a41086a220d2003419d106a29000037030020032003290095103703980b200341f00d6a200341b80b6a41a40210a1051a200341d0056a41176a220f2006280000360000200341d0056a41106a22062007290300370300200341d0056a41086a2207200d290300370300200320032903980b3703d005024020050d00200341f0086a200341f00d6a41a40210a1051a200341d0086a41176a200f280000360000200341d0086a41106a2006290300370300200341d0086a41086a2007290300370300200320032903d0053703d0080b024020032802e40d450d00200210230b2004410020081b21052008410120081b2106024020014102460d002009420020081b210c200a420020081b211a200341a0036a41066a200341f0086a41a40210a1051a200341d0006a41176a2202200341d0086a41176a280000360000200341d0006a41106a2204200341d0086a41106a290300370300200341d0006a41086a2207200341d0086a41086a290300370300200320032903d008370350200341f0006a200341a0036a41aa0210a1051a200341306a41176a220d2002280000360000200341306a41106a22022004290300370300200341306a41086a220420072903003703002003200329035037033020034190066a200341f0006a41066a41a40210a1051a20034190066a41a4026a20013a0000200341b5086a2003290330370000200341bd086a2004290300370000200341c5086a2002290300370000200341cc086a200d28000036000020034190066a41086a2903002119200329039006210b20032802a006210702400240200341a8066a28020041057422020d00420021094200210a0c010b200741106a2101420021094200210a0340200141086a2903004200200141786a29030042015122041b200a7c2001290300420020041b220a20097c2209200a54ad7c210a200141206a2101200241606a22020d000b0b200e410020081b21012019201a7c200b200c7c220c200b54ad7c200a7c210a200c20097c221a200c54ad21090240200341a4066a28020041ffffff3f71450d00200710230b200a20097c210a200341ac066a108f05024020014105742202450d00200621010340200341f00d6a2001108b0520033502f80d42208620032802f00d2204ad841011024020032802f40d450d00200410230b200141206a2101200241606a22020d000b0b201a200a8450450d0242002121420021220c030b0240200541ffffff3f71450d00200610230b4183a80821020b20004100360204200041146a4108360200200041106a41c7c6c6003602002000410c6a2002360200410121010c120b200341d0056a200341f0056a109702200341f0006a20032802d005220220032802d80522011098022003290370211e4200210b20034200370370200341b8016a280200210420032d00bc01210802400240201e4201510d00200341f0086a41306a4200370300200341f0086a41286a4200370300200341f0086a41206a4200370300200341f0086a41186a420037030020034180096a4200370300200341f8086a4200370300200342003703f008420021194200210c42002109420021230c010b200341a8016a2903002121200341f0006a41306a2903002122200341f0006a41206a2903002119200341f0006a41186a290300210b200341b0016a290300212320032903800121092003290378210c200341f0086a41206a200341f0006a41286a290300370300200341f0086a41286a2022370300200341f0086a41306a202137030020034180096a200b37030020032019370388092003200c3703f008200320093703f8080b200341f0086a41186a2019200a2019200b201a562019200a562019200a511b22071b22227d200b201a200b20071b222154ad7d22243703002003200b20217d222537038009200341b80b6a41186a2024370300200341b80b6a41206a220e200341f0086a41206a290300370300200341b80b6a41286a220f200341f0086a41286a290300370300200341b80b6a41306a2210200341f0086a41306a290300370300200320253703c80b2003200c3703b80b200320093703c00b200920197c200c200b7c2226200c542207ad7c210b02400240427f200c20257c22192019200c54220d200920247c200dad7c221920095420192009511b220d1b22244280c8afa025544100427f2019200d1b2225501b0d00200341c80b6a290300212420102903002125200f2903002127200e290300212820032903c00b212920032903b80b212a4201211920032903d00b212b0c010b4200211902402024202584500d002024202510eb01200341a80e6a2025370300200341a00e6a2024370300200341f00d6a41086a41013a0000200341f90d6a20032903f005370000200341810e6a200341f0056a41086a290300370000200341890e6a20034180066a290300370000200341910e6a20034188066a290300370000200341023a00f00d200341f00d6a10e0010b0b200b200951210d200b200954210e20034198016a2028370300200341a0016a202737030020034180016a2029370300200341a8016a202537030020034188016a20243703002003202b37039001200320233703b0012003202a370378200320084100201e420151220f1b3a00bc01200320044100200f1b3602b801200320194201512204ad3703700240024020040d002001ad4220862002ad8410110c010b200320013602f40d200320023602f00d200341f8006a200341f00d6a1098030b2007200e200d1b2101024020032802d405450d00200210230b427f200b20011b210b427f202620011b212420194201522101024002400240201e4201510d0020010d004103210220034190066a21010c010b201e4201522001410173720d0141042102200341a0036a21010b200141046a20023a0000200141056a20032903f005370000200141003a00002001410d6a200341f8056a290300370000200141156a20034180066a2903003700002001411d6a20034188066a290300370000200110e0010b2024200b844200520d00200341a80e6a2009370300200341a00e6a200c370300200341f00d6a41086a41003a0000200341f90d6a20032903f005370000200341810e6a200341f0056a41086a290300370000200341890e6a20034180066a290300370000200341910e6a20034188066a290300370000200341023a00f00d200341f00d6a10e0010b2021202210eb01200341a80e6a200a370300200341a00e6a201a370300200341f00d6a41086a41023a0000200341f90d6a20032903f005370000200341810e6a200341f0056a41086a290300370000200341890e6a20034180066a290300370000200341910e6a20034188066a2903003700002003410a3a00f00d200341f00d6a10e001200541ffffff3f71450d0d200610230c0d0b200141386a290300210c200141306a290300211a200141196a290000210b200141186a2d0000211d200141176a2d0000211f200141156a2f00002120200141146a2d0000212c200141136a2d0000212d200141116a2f0000212e200141106a2d0000212f2001410f6a2d000021302001410d6a2f000021312001410c6a2d000021322001410b6a2d00002133200141096a2f00002134200141086a2d00002135200141076a2d00002136200141056a2f00002137200141046a2d00002138200141036a2d00002139200141286a290300210a200141246a280200211c20012f0001213a2002411a6a2901002109200241196a2d00002104200241186a2d00002108200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211b41012101024020022d00000d0020022d000141014721010b200320093702a806200320043a00a706200320083a00a606200320053b01a406200320063a00a306200320073a00a2062003200d3b01a0062003200e3a009f062003200f3a009e06200320103b019c06200320113a009b06200320123a009a06200320133b019806200320143a009706200320153a009606200320163b019406200320173a009306200320183a0092062003201b3b0190060240024002400240024020010d00200341d0056a41186a20034190066a41186a29020037030041102101200341d0056a41106a20034190066a41106a290200370300200341d0056a41086a20034190066a41086a29020037030020032003290290063703d0052003200b370388062003201d3a0087062003201f3a008606200320203b0184062003202c3a0083062003202d3a0082062003202e3b0180062003202f3a00ff05200320303a00fe05200320313b01fc05200320323a00fb05200320333a00fa05200320343b01f805200320353a00f705200320363a00f605200320373b01f405200320383a00f305200320393a00f2052003203a3b01f0050240200a4201520d0041fcc5c6002102418080202104410321080c020b200341f00d6a10910520032802f00d21010240024002400240024020032802f80d201c4d0d002001201c4106746a22022903004201520d000240200341d0056a200241206a2202460d002002200341d0056a412010a3050d010b024020032802f40d41ffffff1f71450d00200110230b200341306a200341f0056a109205200341f00d6a200328023022012003280238109305200341b80b6a200341f00d6a41a40210a1051a200341d0086a41086a22022003419d106a290000370300200341d0086a41106a2204200341a5106a290000370300200341d0086a41176a2208200341ac106a28000036000020032003290095103703d008024020032d00941022054102460d00200341f0086a200341b80b6a41a40210a1051a200341d0006a41176a2008280000360000200341d0006a41106a2004290300370300200341d0006a41086a2002290300370300200320032903d00837035002402003280234450d00200110230b200341a0036a41066a200341f0086a41a40210a1051a200341f0006a200341a0036a41aa0210a1051a200341980b6a41176a2201200341d0006a41176a280000360000200341980b6a41106a2202200341d0006a41106a290300370300200341980b6a41086a2204200341d0006a41086a290300370300200320032903503703980b20034190066a200341f0006a41066a41a40210a1051a20034190066a41a4026a20053a0000200341b5086a20032903980b370000200341bd086a2004290300370000200341c5086a2002290300370000200341cc086a200128000036000020032802a006210541002101200341a8066a280200220641014b0d0220060e020403040b02402003280234450d00200110230b41e3c5c6002102410d2101418080282104410321080c060b024020032802f40d41ffffff1f71450d00200110230b41f0c5c6002102410c2101418080242104410321080c050b20062102034020012002410176220420016a2208200520084105746a280200201c4b1b2101200220046b220241014b0d000b0b200520014105746a22022802002204201c460d01200620012004201c496a2201490d040b02402006200341a4066a280200470d0020034190066a41106a2006410110970120032802a00621050b200520014105746a220241206a2002200620016b41057410a2051a200241186a200c370300200241106a201a3703002002200a3703082002201c3602002003200641016a3602a8060c050b200620014d0d03200520014105746a220141086a2104024020012903084201520d00200341f00d6a200341f0056a200341d0056a200141106a290300200141186a290300410010fe020b2004200a3703002002201c360200200141186a200c370300200141106a201a3703000c040b41022108410021040b20004100360204200041146a2001360200200041106a20023602002000410c6a20044180803c7120087241802872360200410121010c120b200120061038000b2001200641b08bc7001030000b200341f00d6a20034190066a41c00210a1051a200341f0056a200341f00d6a109405200341f00d6a41086a41053a0000200341f90d6a20032903f005370000200341810e6a200341f0056a41086a290300370000200341890e6a20034180066a290300370000200341910e6a20034188066a2903003700002003419c0e6a201c3602002003410a3a00f00d200341f00d6a10e0010c0c0b410221040240024020022d00000d0020022d00014101470d00200141086a2903002109200141046a2802002108200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211b20032002411a6a2901003703880e200320013a00870e200320043a00860e200320053b01840e200320063a00830e200320073a00820e2003200d3b01800e2003200e3a00ff0d2003200f3a00fe0d200320103b01fc0d200320113a00fb0d200320123a00fa0d200320133b01f80d200320143a00f70d200320153a00f60d200320163b01f40d200320173a00f30d200320183a00f20d2003201b3b01f00d200341f0006a109105410321042003280270210102402003280278220520084d0d00200120084106746a22022903004201520d000240200341f00d6a200241206a2202460d002002200341f00d6a412010a3050d010b200120084106746a2009370318410421040b2003280274210841f4c7c600ad4280808080800184100c220229000021092002290008210a2002102341a084c700ad4280808080a00184100c2202290000210b2002290008210c200210232003200c3702a8062003200b3702a0062003200a370298062003200937029006200341a0036a2001200510d40220034190066aad428080808080048420033502a80342208620032802a0032202ad84100e024020032802a403450d00200210230b0240200841ffffff1f71450d00200110230b4100210120044104460d010b200041146a410c360200200041106a41f0c5c6003602002000410c6a20044180a82472360200410121010b200041003602040c0e0b410221040240024020022d00000d0020022d00014101470d00200141196a2900002109200141186a2d0000211c200141176a2d0000211d200141156a2f0000211f200141146a2d00002120200141136a2d0000212c200141116a2f0000212d200141106a2d0000212e2001410f6a2d0000212f2001410d6a2f000021302001410c6a2d000021312001410b6a2d00002132200141096a2f00002133200141086a2d00002134200141076a2d00002135200141056a2f00002136200141046a2d00002137200141036a2d00002138200141246a280200210420012f00012139200241196a2d00002101200241186a2d00002108200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211b20032002411a6a2901003703880e200320013a00870e200320083a00860e200320053b01840e200320063a00830e200320073a00820e2003200d3b01800e2003200e3a00ff0d2003200f3a00fe0d200320103b01fc0d200320113a00fb0d200320123a00fa0d200320133b01f80d200320143a00f70d200320153a00f60d200320163b01f40d200320173a00f30d200320183a00f20d2003201b3b01f00d200341f0006a109105200328027021020240024002402003280278220820044d0d00200220044106746a22012903004201510d010b4103210420034190066a21050c010b200320093702a8062003201c3a00a7062003201d3a00a6062003201f3b01a406200320203a00a3062003202c3a00a2062003202d3b01a0062003202e3a009f062003202f3a009e06200320303b019c06200320313a009b06200320323a009a06200320333b019806200320343a009706200320353a009606200320363b019406200320373a009306200320383a009206200320393b0190060240200341f00d6a200141206a2201460d002001200341f00d6a412010a305450d004103210420034190066a21050c010b200120343a0007200120353a0006200120363b0104200120373a0003200120383a0002200120393b01002001202e3a000f2001202f3a000e200120303b010c200120313a000b200120323a000a2001201c3a00172001201d3a00162001201f3b0114200120203a00132001202c3a0012200220044106746a220120333b01282001202d3b0130200120093703384104210420034190066a21050b2003280274210641f4c7c600ad4280808080800184100c22012900022109200128000a210720012f000e210d20012f0000210e2001102341a084c700ad4280808080a00184100c2201290000210a2001290008210b200110232005200e3b01002003200b3702a8062003200a3702a0062003200d3b019e062003200736019a062003200937019206200341a0036a2002200810d40220034190066aad428080808080048420033502a80342208620032802a0032201ad84100e024020032802a403450d00200110230b0240200641ffffff1f71450d00200210230b4100210120044104460d010b200041146a410c360200200041106a41f0c5c6003602002000410c6a20044180a82472360200410121010b200041003602040c0d0b410221040240024020022d00000d0020022d00014101470d00200141106a2903002109200141086a290300210a200141046a2802002108200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211b20032002411a6a2901003703880e200320013a00870e200320043a00860e200320053b01840e200320063a00830e200320073a00820e2003200d3b01800e2003200e3a00ff0d2003200f3a00fe0d200320103b01fc0d200320113a00fb0d200320123a00fa0d200320133b01f80d200320143a00f70d200320153a00f60d200320163b01f40d200320173a00f30d200320183a00f20d2003201b3b01f00d200341f0006a109105410321042003280270210102402003280278220520084d0d00200120084106746a22022903004201520d000240200341f00d6a200241206a2208460d002008200341f00d6a412010a3050d010b200241086a2202200a37030020022009370308410421040b2003280274210841f4c7c600ad4280808080800184100c220229000021092002290008210a2002102341a084c700ad4280808080a00184100c2202290000210b2002290008210c200210232003200c3702a8062003200b3702a0062003200a370298062003200937029006200341a0036a2001200510d40220034190066aad428080808080048420033502a80342208620032802a0032202ad84100e024020032802a403450d00200210230b0240200841ffffff1f71450d00200110230b4100210120044104460d010b200041146a410c360200200041106a41f0c5c6003602002000410c6a20044180a82472360200410121010b200041003602040c0c0b4102210402400240024020022d00000d0020022d00014101470d00200141046a280200210d200241196a2d00002101200241186a2d00002104200241166a2f01002108200241156a2d00002105200241146a2d00002106200241126a2f01002107200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211b20032002411a6a29010037038806200320013a008706200320043a008606200320083b018406200320053a008306200320063a008206200320073b0180062003200e3a00ff052003200f3a00fe05200320103b01fc05200320113a00fb05200320123a00fa05200320133b01f805200320143a00f705200320153a00f605200320163b01f405200320173a00f305200320183a00f2052003201b3b01f005200341d0056a200341f0056a109205200341f00d6a20032802d005220120032802d805109305200341b80b6a200341f00d6a41a40210a1051a200341d0086a41086a22022003419d106a290000370300200341d0086a41106a2204200341a5106a290000370300200341d0086a41176a2208200341ac106a28000036000020032003290095103703d0080240024002400240024020032d00941022054102460d00200341f0086a200341b80b6a41a40210a1051a200341d0006a41176a2008280000360000200341d0006a41106a2004290300370300200341d0006a41086a2002290300370300200320032903d008370350024020032802d405450d00200110230b200341a0036a41066a200341f0086a41a40210a1051a200341f0006a200341a0036a41aa0210a1051a200341980b6a41176a2201200341d0006a41176a280000360000200341980b6a41106a2202200341d0006a41106a29030037030041082108200341980b6a41086a2204200341d0006a41086a290300370300200320032903503703980b20034190066a200341f0006a41066a41a40210a1051a20034190066a41a4026a20053a0000200341b5086a20032903980b370000200341bd086a2004290300370000200341c5086a2002290300370000200341cc086a200128000036000041cfc6c600210541808004210620032802a006210e41002101200341a8066a280200220f41014b0d01200f0e020302030b024020032802d405450d00200110230b41a9c6c6002105410a2108418080142106410321040c050b200f2102034020012002410176220420016a2207200e20074105746a280200200d4b1b2101200220046b220241014b0d000b0b200e20014105746a280200200d470d00200f20014d0d04200e20014105746a220241186a2903002109200241106a290300210a2002290308210b2002200241206a2001417f73200f6a41057410a2051a2003200f417f6a3602a806200b4201510d01410e2108418cc6c60021054180801c21060b0240200341a4066a28020041ffffff3f71450d00200e10230b200341ac066a108f05410321040c020b2003200a370370200320093703780240200a200984500d002003200341f0056a3602b80b200341a0036a200341f0056a200341f0006a200341b80b6a10ff0220032903a0034201520d0020032903a8032109200341a80e6a200341a0036a41106a290300370300200341a00e6a2009370300200341f00d6a41086a41003a0000200341f90d6a20032903f005370000200341810e6a200341f0056a41086a290300370000200341890e6a200341f0056a41106a290300370000200341910e6a20034188066a290300370000200341023a00f00d200341f00d6a10e0010b200341f00d6a20034190066a41c00210a1051a200341f0056a200341f00d6a109405200341f00d6a41086a41043a0000200341f90d6a20032903f005370000200341810e6a200341f0056a41086a290300370000200341890e6a20034180066a290300370000200341910e6a20034188066a2903003700002003419c0e6a200d3602002003410a3a00f00d200341f00d6a10e0010c0b0b410021060b20004100360204200041146a2008360200200041106a20053602002000410c6a20064180801c7120047241802872360200410121010c0c0b2001200f103b000b410221040240024002400240024002400240024020022d00000d0020022d00014101470d00200141106a2903002109200141086a290300210a200141046a2802002107200241196a2d00002101200241186a2d00002104200241166a2f01002108200241156a2d00002105200241146a2d00002106200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211b20032002411a6a29010037038806200320013a008706200320043a008606200320083b018406200320053a008306200320063a0082062003200d3b0180062003200e3a00ff052003200f3a00fe05200320103b01fc05200320113a00fb05200320123a00fa05200320133b01f805200320143a00f705200320153a00f605200320163b01f405200320173a00f305200320183a00f2052003201b3b01f005200341306a10910541bdc6c6002101410a210241142108410321042003280230210d200328023820074d0d05200d20074106746a22052903004201520d0502402005290308200a58200541106a290300220a200958200a2009511b0d0041b3c6c6002101410421060c050b200341d0056a200341f0056a109205200341f00d6a20032802d005220120032802d805109305200341b80b6a200341f00d6a41a40210a1051a200341d0086a41086a2003419d106a290000370300200341d0086a41106a200341a5106a290000370300200341d0086a41176a2206200341ac106a28000036000020032003290095103703d00802400240024002400240024020032d009410220e4102460d00200541086a210f200341f0086a200341b80b6a41a40210a1051a200341d0006a41176a2006280000360000200341d0006a41106a2202200341d0086a41106a290300370300200341d0006a41086a2204200341d0086a41086a290300370300200320032903d008370350024020032802d405450d00200110230b200341a0036a41066a200341f0086a41a40210a1051a200341f0006a200341a0036a41aa0210a1051a200341980b6a41176a2201200341d0006a41176a280000360000200341980b6a41106a22082002290300370300200341980b6a41086a22022004290300370300200320032903503703980b20034190066a200341f0006a41066a41a40210a1051a20034190066a41a4026a200e3a0000200341b5086a20032903980b370000200341bd086a2002290300370000200341c5086a2008290300370000200341cc086a2001280000360000200f41086a2903002109200f290300210a20032802a006210e41002101200341a8066a280200220541014b0d0120050e020302030b024020032802d405450d00200110230b41a9c6c6002101410521060c090b20052102034020012002410176220420016a2208200e20084105746a28020020074b1b2101200220046b220241014b0d000b0b200e20014105746a221028020022022007460d012005200120022007496a2201490d040b02402005200341a4066a280200470d0020034190066a41106a2005410110970120032802a006210e0b200e20014105746a220241206a2002200520016b41057410a2051a200241186a2009370300200241106a200a37030020024201370308200220073602002003200541016a3602a8060c010b200520014d0d030240200e20014105746a2211280208417f6a221241054b0d00419ac6c6002101410f210241032104411421084106210620120e06050000000005050b201141086a420137030020102007360200201141186a2009370300201141106a200a3703000b200f29030021092003200f41086a290300220a370378200320093703702003200341f0056a3602f00802402009200a844200510d002003200341f0056a3602b80b2003200341b80b6a3602f80d2003200341f0086a3602f40d2003200341f0006a3602f00d200341a0036a200341f0056a200341f00d6a10fd020240024020032802a0034101470d00200341ac036a2802002102200341a8036a280200210120032d00a703210520032d00a603210620032d00a503210820032d00a40321040c010b410421040240200341a0036a41086a2903004201520d00200341a0036a41106a290300210920032802b80b2101200341a80e6a200341a0036a41186a290300370300200341a00e6a2009370300200341f00d6a41086a41003a0000200341f90d6a2001290000370000200341810e6a200141086a290000370000200341890e6a200141106a290000370000200341910e6a200141186a290000370000200341023a00f00d200341f00d6a10e0010b0b200441ff01714104470d040b200341f00d6a20034190066a41c00210a1051a200341f0056a200341f00d6a109405200341f00d6a41086a41033a0000200341f90d6a20032903f005370000200341810e6a200341f0056a41086a290300370000200341890e6a20034180066a290300370000200341910e6a20034188066a2903003700002003419c0e6a20073602002003410a3a00f00d200341f00d6a10e001200328023441ffffff1f71450d0f200d10230c0f0b0c060b200120051038000b2001200541a08bc7001030000b0240200341a4066a28020041ffffff3f71450d00200e10230b200341ac066a108f050c020b0c010b410321060b200328023441ffffff1f71450d00200d10230b20004100360204200041146a2002360200200041106a20013602002000410c6a2005411874200641ff017141107472200841ff017141087472200441ff017172360200410121010c0a0b0240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002108200241156a2d00002105200241146a2d00002106200241126a2f01002107200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820032002411a6a29010037038806200320013a008706200320043a008606200320083b018406200320053a008306200320063a008206200320073b0180062003200d3a00ff052003200e3a00fe052003200f3b01fc05200320103a00fb05200320113a00fa05200320123b01f805200320133a00f705200320143a00f605200320153b01f405200320163a00f305200320173a00f205200320183b01f00520034190066a200341f0056a109505200341f00d6a20032802900622012003280298062202109605024020032802800e2208450d002002ad4220862001ad8410110b20032903f00d210920032802840e2104200341f80d6a290300210a200341880e6a280200210e0240200328029406450d00200110230b200341e00d6a200341f0056a109205200341f00d6a20032802e00d220220032802e80d2206109305024020032d009410220141024622050d002006ad4220862002ad8410110b200341b80b6a200341f00d6a41a40210a1051a200341980b6a41176a2206200341ac106a280000360000200341980b6a41106a2207200341a5106a290000370300200341980b6a41086a220d2003419d106a29000037030020032003290095103703980b200341f00d6a200341b80b6a41a40210a1051a200341d0056a41176a220f2006280000360000200341d0056a41106a22062007290300370300200341d0056a41086a2207200d290300370300200320032903980b3703d005024020050d00200341f0086a200341f00d6a41a40210a1051a200341d0086a41176a200f280000360000200341d0086a41106a2006290300370300200341d0086a41086a2007290300370300200320032903d0053703d0080b024020032802e40d450d00200210230b2004410020081b21052008410120081b2106024020014102460d002009420020081b210c200a420020081b211a200341a0036a41066a200341f0086a41a40210a1051a200341d0006a41176a2202200341d0086a41176a280000360000200341d0006a41106a2204200341d0086a41106a290300370300200341d0006a41086a2207200341d0086a41086a290300370300200320032903d008370350200341f0006a200341a0036a41aa0210a1051a200341306a41176a220d2002280000360000200341306a41106a22022004290300370300200341306a41086a220420072903003703002003200329035037033020034190066a200341f0006a41066a41a40210a1051a20034190066a41a4026a20013a0000200341b5086a2003290330370000200341bd086a2004290300370000200341c5086a2002290300370000200341cc086a200d28000036000020034190066a41086a2903002119200329039006210b20032802a006210702400240200341a8066a28020041057422020d00420021094200210a0c010b200741106a2101420021094200210a0340200141086a2903004200200141786a29030042015122041b200a7c2001290300420020041b220a20097c2209200a54ad7c210a200141206a2101200241606a22020d000b0b200e410020081b21012019201a7c200b200c7c220c200b54ad7c200a7c210a200c20097c2209200c54ad210b0240200341a4066a28020041ffffff3f71450d00200710230b200a200b7c210a200341ac066a108f05024020014105742202450d00200621010340200341f00d6a2001108b0520033502f80d42208620032802f00d2204ad841011024020032802f40d450d00200410230b200141206a2101200241606a22020d000b0b200320093703a0032003200a3703a80302402009200a84500d002003200341f0056a36027020034190066a200341f0056a200341a0036a200341f0006a10ff022003290390064201520d00200329039806210b200341a80e6a20034190066a41106a290300370300200341a00e6a200b370300200341f00d6a41086a41003a0000200341f90d6a20032903f005370000200341810e6a200341f0056a41086a290300370000200341890e6a200341f0056a41106a290300370000200341910e6a20034188066a290300370000200341023a00f00d200341f00d6a10e0010b200341a80e6a200a370300200341a00e6a2009370300200341f00d6a41086a41013a0000200341f90d6a20032903f005370000200341810e6a200341f0056a41086a290300370000200341890e6a20034180066a290300370000200341910e6a20034188066a2903003700002003410a3a00f00d200341f00d6a10e001200541ffffff3f71450d09200610230c090b0240200541ffffff3f71450d00200610230b4183a80821010c010b4182a80821010b20004100360204200041146a4108360200200041106a41c7c6c6003602002000410c6a2001360200410121010c090b200341f00d6a200341f0086a10950520033502f80d42208620032802f00d2201ad841011024020032802f40d450d00200110230b200e41ffffff3f71450d010b201d10230b201e42ffffff3f83500d03201f10230c030b102a000b0b02402008450d00200841c4006c2102200541286a210103400240200141786a2d00004101470d002001280200450d002001417c6a28020010230b200141c4006a2101200241bc7f6a22020d000b0b02402004450d00200441c4006c450d00200510230b200641ff017122014104460d0020004100360204200041146a200f360200200041106a20103602002000410c6a200e411874200741ff017141107472200d41ff017141087472200172360200410121010c030b410021010b200020013602040c010b20004100360204200041146a2002360200200041106a20043602002000410c6a2008411874200541ff017141107472200641ff017141087472200141ff017172360200410121010b20002001360200200341b0106a24000bf06304147f017e037f027e230041b0046b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0a00010203040506070809000b200341b4016a4101360200200342013702a401200341a4c5c6003602a001200341043602f403200341cccec6003602f0032003200341f0036a3602b001200341a0016a419ca8c700103a000b200141246a2802002104200341c0006a41186a200141196a290000370300200341c0006a41106a200141116a290000370300200341c0006a41086a200141096a29000037030020032001290001370340410a2105410221060240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a290100370378200320013a0077200320063a0076200320073b0174200320083a0073200320093a00722003200a3b01702003200b3a006f2003200c3a006e2003200d3b016c2003200e3a006b2003200f3a006a200320103b0168200320113a0067200320123a0066200320133b0164200320143a0063200320153a0062200320163b016020034198046a200341e0006a10a604200341a0016a200328029804220120032802a00410e101200341f0036a41086a2202200341aa016a290100370300200341f0036a41106a2206200341b2016a290100370300200341f0036a41176a2207200341b9016a290000370000200320032901a2013703f0030240024020032d00a0014101470d0020032d00a101210820034180016a41176a200729000037000020034180016a41106a200629030037030020034180016a41086a2002290300370300200320032903f003370380010240200328029c04450d00200110230b200341d9036a20034180016a41086a290300370000200341e1036a20034180016a41106a290300370000200341d0036a41186a20034197016a290000370000200320083a00d00320032003290380013700d103200341d0036a200341c0006a412010a3050d01200341a0016a200441b00210a1051a200341fa036a200341c0006a41086a29030037010020034182046a200341c0006a41106a2903003701002003418a046a200341c0006a41186a29030037010020034180023b01f003200320032903403701f20320034180016a200341a0016a200341f0036a10cf022003280280014101460d030c240b200328029c04450d00200110230b410321060b200410b40241b6edc300210941802a210841002102410021070c220b2003280284014102460d2020034194016a280200210520034190016a28020021092003418c016a2802002206418080807871210220064180807c712107200641807e7121080c210b200341d0036a41186a200141196a290000370300200341d0036a41106a200141116a290000370300200341d0036a41086a200141096a290000370300200320012900013703d003200341f0036a41186a200141396a290000370300200341f0036a41106a200141316a290000370300200341f0036a41086a200141296a2900003703002003200141216a2900003703f00320022d000120022d0000410047720d07200341a0016a200341f0036a10a60420033502a801211720032802a0012102412010212201450d0c200120032903d003370000200141186a200341d0036a41186a2204290300370000200141106a200341d0036a41106a2206290300370000200141086a200341d0036a41086a220529030037000020174220862002ad842001ad4280808080800484100e20011023024020032802a401450d00200210230b200341c2016a20032903f003370100200341aa016a2005290300370100200341b2016a2006290300370100200341ba016a2004290300370100200341ca016a200341f0036a41086a290300370100200341d2016a200341f0036a41106a290300370100200341da016a200341f0036a41186a2903003701002003418b083b01a001200320032903d0033701a201200341a0016a10e0010c150b200141086a2802002107200141046a28020021094102210620022d00000d1b20022d00014101470d1b2001410c6a2802002118200141106a2802002119200141026a2f0100211a200241196a2d00002101200241186a2d00002104200241166a2f01002106200241156a2d00002105200241146a2d00002108200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703e803200320013a00e703200320043a00e603200320063b01e403200320053a00e303200320083a00e2032003200a3b01e0032003200b3a00df032003200c3a00de032003200d3b01dc032003200e3a00db032003200f3a00da03200320103b01d803200320113a00d703200320123a00d603200320133b01d403200320143a00d303200320153a00d203200320163b01d003200341a0016a200341d0036a10a704200341106a20032802a001220120032802a801419ca8c70041004100108c0120032802102102024020032802a401450d00200110230b410121014103210641152105024020024101470d0041f3ecc300210441122102410621010c1d0b0240201a0d0041de95c6002104410d21020c1d0b41a6edc30021044110210241022101024020180d000c1d0b02402018201a4f0d000c1d0b410321060240201841094d0d00419cedc3002104410a2102410321010c1d0b201841016a210a2009210802400340200a417f6a220a4102490d012008200841206a220b412010a305210c4193edc30021044109210241042101200b2108200c4100480d000b0c1d0b20032018ad4200428090cad2c60e420010a60520032003290300221b4280a0e5b9c291017c22173703602003200341086a2903002017201b54ad7c221b3703682003200341d0036a360280012003200341d0036a3602402003200341c0006a3602a801200320034180016a3602a4012003200341e0006a3602a001200341f0036a200341d0036a200341a0016a10fd020240024020032802f0034101470d00200341fc036a2802002102200341f0036a41086a280200210420032d00f703210820032d00f603210120032d00f503210520032d00f40321060c010b410421060240200341f0036a41086a2903004201520d00200341f0036a41106a290300211c20032802402101200341d8016a200341f0036a41186a290300370300200341d0016a201c370300200341a0016a41086a41003a0000200341a9016a2001290000370000200341b1016a200141086a290000370000200341b9016a200141106a290000370000200341c1016a200141186a290000370000200341023a00a001200341a0016a10e0010b0b200641ff01714104470d1c200341f0036a200341d0036a10a70420033502f803211c20032802f003210e200341003602a801200342013703a001410410212201450d1a200341043602a401200320013602a00120012019360000200341043602a80120014104411410252201450d1a200120173700042001410c6a201b370000200320013602a00120034294808080c0023702a4012018200341a0016a10612018410574210c410020032802a801220b6b210d20032802a401210641002105410021010340200b20016a210802400240200d20066a20056a4120490d0020032802a00121022006210a0c010b200841206a22022008490d0e200641017422042002200420024b1b220a4100480d0e0240024020060d000240200a0d00410121020c020b200a102122020d010c1e0b20032802a00121022006200a460d0020022006200a10252202450d1d0b2003200a3602a401200320023602a001200a21060b2002200b6a20016a2202200920016a2204290000370000200241186a200441186a290000370000200241106a200441106a290000370000200241086a200441086a2900003700002003200841206a3602a801200541606a2105200c200141206a2201470d000b200b20016a210602400240200a200b6b20016b4102490d0020032802a0012102200a21040c010b200641026a22022006490d0d200a41017422042002200420024b1b22044100480d0d02400240200a0d00024020040d00410121020c020b200410212202450d1d0c010b20032802a0012102200a2004460d002002200a200410252202450d1c0b200320043602a401200320023602a0010b2002200b6a20016a201a3b0000201c422086200ead84200641026aad4220862002ad84100e02402004450d00200210230b024020032802f403450d00200e10230b0240200741ffffff3f71450d00200910230b200341aa016a200341d8036a290300370100200341b2016a200341e0036a290300370100200341ba016a200341e8036a2903003701002003410b3b01a001200320032903d0033701a201200341a0016a10e0010c140b200341e0006a41186a200141196a290000370300200341e0006a41106a200141116a290000370300200341e0006a41086a200141096a29000037030020032001290001370360410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002106200241156a2d00002105200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703e803200320013a00e703200320043a00e603200320063b01e403200320053a00e303200320073a00e203200320083b01e003200320093a00df032003200a3a00de032003200b3b01dc032003200c3a00db032003200d3a00da032003200e3b01d8032003200f3a00d703200320103a00d603200320113b01d403200320123a00d303200320133a00d203200320143b01d003200341a0016a200341e0006a10a704200341286a20032802a001220120032802a801419ca8c70041004100108c0120032802282106024020032802a401450d00200110230b410e21024103210141152104024020064101460d004185edc3002106410521050c020b200341a0016a200341e0006a200341d0036a10a804200341206a20032802a001220520032802a801419ca8c70041004100108c0120032802202106024020032802a401450d00200510230b024020064101470d0041e5ecc3002106410721050c020b2003420037034820034280a0e5b9c291013703402003200341d0036a360298042003200341d0036a36028001200320034180016a3602a801200320034198046a3602a4012003200341c0006a3602a001200341f0036a200341d0036a200341a0016a10fd020240024020032802f0034101470d00200341fc036a2802002102200341f8036a280200210620032d00f703210720032d00f603210520032d00f503210420032d00f40321010c010b410421010240200341f0036a41086a2903004201520d00200341f0036a41106a29030021172003280280012102200341d8016a200341f0036a41186a290300370300200341d0016a2017370300200341a0016a41086a41003a0000200341a9016a2002290000370000200341b1016a200241086a290000370000200341b9016a200241106a290000370000200341c1016a200241186a290000370000200341023a00a001200341a0016a10e0010b0b200141ff01714104470d01200341a0016a41186a4200370300200341a0016a41106a22044200370300200341a0016a41086a22014200370300200342003703a00141e4dec400ad4280808080e00084100c220229000021172001200241086a290000370300200320173703a0012002102341f3dec400ad4280808080e00084100c22022900002117200341c0006a41086a2206200241086a2900003703002003201737034020021023200420032903402217370300200341f0036a41086a2001290300370300200341f0036a41106a2017370300200341f0036a41186a2006290300370300200320032903a0013703f003200341186a200341f0036a412010cd01200328021c21022003280218210441002101200341bc016a4100360200200342003703a80120034280a0e5b9c291013703a001200342013702b40120032002410020041b3602b001200341f0036a200341e0006a200341d0036a10a80420032802f0032102200320032802f80336024420032002360240200341a0016a200341c0006a10a304024020032802f403450d00200210230b200341aa016a200341e0006a41086a290300370100200341b2016a200341e0006a41106a290300370100200341ba016a200341e0006a41186a290300370100200341c2016a20032903d003370100200341ca016a200341d0036a41086a290300370100200341d2016a200341d0036a41106a290300370100200341da016a200341d0036a41186a2903003701002003418b023b01a001200320032903603701a201200341a0016a10e001200041003602040c210b0b20004100360204200041146a2002360200200041106a20063602002000410c6a2007411874200541ff017141107472200441ff017141087472200141ff0171723602000c1c0b200341c0006a41186a200141196a290000370300200341c0006a41106a200141116a290000370300200341c0006a41086a200141096a29000037030020032001290001370340200341e0006a41186a200141396a290000370300200341e0006a41106a200141316a290000370300200341e0006a41086a200141296a2900003703002003200141216a2900003703604102210120022d00000d1620022d00014101470d16200241196a2d00002101200241186a2d00002104200241166a2f01002106200241156a2d00002105200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703e803200320013a00e703200320043a00e603200320063b01e403200320053a00e303200320073a00e203200320083b01e003200320093a00df032003200a3a00de032003200b3b01dc032003200c3a00db032003200d3a00da032003200e3b01d8032003200f3a00d703200320103a00d603200320113b01d403200320123a00d303200320133a00d203200320143b01d003200341f0036a200341c0006a10a704200341a0016a20032802f003220420032802f80310a90420032802f40321020240024020032802b4012207450d00200341bc016a280200210120032802b801210902402002450d00200410230b20034180016a200341c0006a200341e0006a10a804200341a0016a200328028001220220032802880110aa0441082104200341a0016a41086a290300211b20032903a001211c20032903b801211720032802b401210820032802b00121060240200328028401450d00200210230b20080d0141dbecc3002105410a21060c170b02402002450d00200410230b4185edc3002105410e210641032101410521040c180b20034188046a20173703002003201c3703f003200320083602840420032006360280042003201b3703f8032017a7210a41d2ecc30021054100210202400240200141014b0d00410921044109210620010e021101110b03402001410176220420026a22062002200720064105746a200341d0036a412010a3054101481b2102200120046b220141014b0d000b0b4109210441092106200720024105746a200341d0036a412010a3050d0f4100210102402017422088a7220541014b0d00024020050e020010000b200341a0016a41186a200341d0036a41186a290300370300200341a0016a41106a200341d0036a41106a290300370300200341a0016a41086a200341d0036a41086a290300370300200320032903d0033703a00141002104200341a0016a21020c120b2005210203402002410176220420016a22062001200820064105746a200341d0036a412010a3054101481b2101200220046b220241014b0d000c0f0b0b200341e0006a41186a200141196a290000370300200341e0006a41106a200141116a290000370300200341e0006a41086a200141096a29000037030020032001290001370360410e210441052106410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002105200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703e803200320013a00e703200320053a00e603200320073b01e403200320083a00e303200320093a00e2032003200a3b01e0032003200b3a00df032003200c3a00de032003200d3b01dc032003200e3a00db032003200f3a00da03200320103b01d803200320113a00d703200320123a00d603200320133b01d403200320143a00d303200320153a00d203200320163b01d003200341f0036a200341e0006a10a704200341a0016a20032802f003220120032802f80310a904024020032802b4012205450d0020032802b801210720032802b0012108200341c0016a2f01002109024020032802f403450d00200110230b200341f0036a200341e0006a200341d0036a10a804200341a0016a20032802f003220220032802f80310aa0420032903b801211720032802b401210120032802b0012106024020032802f403450d00200210230b20010d0241dbecc3002102410a2104410821060c0e0b024020032802f403450d00200110230b410321010b4185edc30021020c0d0b200341a0016a200341d0036a10a604200341386a20032802a001220420032802a801419ca8c70041004100108c0120032802382102024020032802a401450d00200410230b024020024101470d00410c21044199ecc3002102410f21060c0b0b200341a0016a41186a4200370300200341a0016a41106a220b420037030041082104200341a0016a41086a22024200370300200342003703a00141e4dec400ad4280808080e00084100c220a290000211b2002200a41086a2900003703002003201b3703a001200a102341f3dec400ad4280808080e00084100c220a290000211b200341c0006a41086a220c200a41086a2900003703002003201b370340200a1023200b2003290340221b370300200341f0036a41086a2002290300370300200341f0036a41106a201b370300200341f0036a41186a200c290300370300200320032903a0013703f003200341306a200341f0036a412010cd010240200620086a220220064f0d0041f4acc5002102410e21060c0b0b024020022003280234410020032802301b4d0d00410b210441c7ecc3002102410a21060c0b0b024020092017422088a74d0d004109210441b0ecc3002102410c21060c0b0b200341a0016a200341d0036a10a60420033502a801211b20032802a0012104412010212202450d0820022003290360370000200241186a200341e0006a41186a2206290300370000200241106a200341e0006a41106a2208290300370000200241086a200341e0006a41086a2209290300370000201b4220862004ad842002ad4280808080800484100e20021023024020032802a401450d00200410230b200341d0036a109602200341aa016a2009290300370100200341b2016a2008290300370100200341ba016a2006290300370100200341c2016a20032903d003370100200341ca016a200341d0036a41086a290300370100200341d2016a200341d0036a41106a290300370100200341da016a200341d0036a41186a2903003701002003418b083b01a001200320032903603701a201200341a0016a10e0010240201742ffffff3f83500d00200110230b200741ffffff3f71450d11200510230c110b200341d0036a41186a200141196a290000370300200341d0036a41106a200141116a290000370300200341d0036a41086a200141096a290000370300200320012900013703d0030240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002106200241156a2d00002105200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a29010037038804200320013a008704200320043a008604200320063b018404200320053a008304200320073a008204200320083b018004200320093a00ff032003200a3a00fe032003200b3b01fc032003200c3a00fb032003200d3a00fa032003200e3b01f8032003200f3a00f703200320103a00f603200320113b01f403200320123a00f303200320133a00f203200320143b01f003200341e0006a200341f0036a200341d0036a10a804200341a0016a200328026022012003280268220210aa04024020032802b4012204450d002002ad4220862001ad841011200341a0016a41086a290300211720032903a001211b20032903b801211c02402003280264450d00200110230b41002101200341a0016a200341d0036a200341f0036a201b2017410010fe02200341aa016a200341f0036a41086a290300370100200341b2016a200341f0036a41106a290300370100200341ba016a200341f0036a41186a290300370100200341c2016a20032903d003370100200341ca016a200341d0036a41086a290300370100200341d2016a200341d0036a41106a290300370100200341da016a200341d0036a41186a2903003701002003418b063b01a001200320032903f0033701a201200341a0016a10e001201c42ffffff3f83500d1420041023200041003602040c1f0b02402003280264450d00200110230b4183aa2021010c010b4182aa2021010b20004100360204200041146a410a360200200041106a41dbecc3003602002000410c6a20013602000c190b41022101024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002106200241156a2d00002105200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703e803200320013a00e703200320043a00e603200320063b01e403200320053a00e303200320073a00e203200320083b01e003200320093a00df032003200a3a00de032003200b3b01dc032003200c3a00db032003200d3a00da032003200e3b01d8032003200f3a00d703200320103a00d603200320113b01d403200320123a00d303200320133a00d203200320143b01d00341aeb9c400ad4280808080800184100c22012900002117200341f0036a41086a200141086a290000370300200320173703f0032001102341a0bcc400ad4280808080800284100c220128000c210820012f000a210920012f0008210a2001280004210b2001280000210c20011023412010212201450d07200120032903d003370000200141186a200341d0036a41186a290300370000200141106a200341d0036a41106a290300370000200141086a200341d0036a41086a29030037000020032001ad4280808080800484100d22022900003703800120021023200341ac016a200141206a360200200341003a00b001200320013602a801200320034180016a41086a3602a401200320034180016a3602a001200341c0006a200341a0016a1065200110232003280248220541206a2202417f4c0d0320032802402107024002402002450d00200210212201450d092002410f4d0d01200221060c070b200241017422014110200141104b1b220610212201450d170c060b200241017422044110200441104b1b220641004e0d040c080b410021060c050b200341e0006a41186a200141196a290000370300200341e0006a41106a200141116a290000370300200341e0006a41086a200141096a290000370300200320012900013703600240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002106200241156a2d00002105200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703e803200320013a00e703200320043a00e603200320063b01e403200320053a00e303200320073a00e203200320083b01e003200320093a00df032003200a3a00de032003200b3b01dc032003200c3a00db032003200d3a00da032003200e3b01d8032003200f3a00d703200320103a00d603200320113b01d403200320123a00d303200320133a00d203200320143b01d003200341c0006a200341d0036a10a604200341a0016a20032802402202200328024810e1010240024020032d00a0014101460d0041002101200341003a00f0030c010b200341f0036a41196a200341a0016a41196a290000370000200341f0036a41096a200341a0016a41096a290000370000200341f0036a41116a200341a0016a41116a29000037000041012101200341013a00f003200320032900a1013700f1030b02402003280244450d00200210230b200341b9016a200341f8006a290300370000200341b1016a200341f0006a290300370000200341a9016a200341e8006a290300370000200320032903603700a101200341013a00a00102402001450d00200341f0036a410172200341a0016a410172412010a3050d00200341a0016a200341d0036a10a60420033502a80142208620032802a0012201ad841011024020032802a401450d00200110230b200341d0036a10a1020c110b41832a21010c010b41822a21010b20004100360204200041146a410a360200200041106a41b6edc3003602002000410c6a20013602000c170b2000410c6a4102360200200041003602040c160b1032000b20022006460d0020012002200610252201450d110b200120032903f003370000200141086a200341f0036a41086a2903003700000240024020064170714110460d00200621040c010b200641017422044120200441204b1b22044100480d0320062004460d0020012006200410252201450d110b2001200836001c200120093b001a2001200a3b00182001200b3600142001200c36001002400240200441606a2005490d00200421060c010b2005415f4b0d03200441017422062002200620024b1b22064100480d0320042006460d0020012004200610252201450d110b200141206a2007200510a1051a02402003280244450d00200710230b0240024020020d0041012104410021050c010b20022105200210212204450d020b20042001200210a1052104200341f4006a2002360200200341f0006a20063602002003200136026c200320023602682003200536026420032004360260200341a0016a2002ad4220862001ad841019108b0102400240024020032802a0012201450d0020032802a401210202400240200341a8016a280200220420032802682206490d00200328026022052001460d0120052001200610a305450d010b2002450d01200110230c010b200341ec006a2106200320043602a0042003200236029c042003200136029804200341a0016a2001200410aa04024020032802b40122010d0020034100360288012003420137038001200341cc006a4112360200200320063602a404200341123602442003200341a8046a3602482003200341a4046a360240200320034198046a3602a804200320034180016a3602ac0420034184046a4102360200200342023702f403200341c8e3c4003602f0032003200341c0006a36028004200341ac046a4184a5c200200341f0036a10311a20033502880142208620033502800184100a200328028401450d0020032802800110230b200341f0036a41086a220220034198046a41086a28020036020020032003290398043703f00302402003280270450d00200328026c10230b200620032903f003370200200641086a200228020036020020010d010b200341f0036a200341d0036a10a704200341a0016a20032802f003220220032802f803220410a904024020032802b4012201450d002004ad4220862002ad8410110b20032802f403210402402001450d00200341a8016a290300211720032903a001211b20032802b801210602402004450d00200210230b2003201b370340200320173703480240201b201784500d002003200341d0036a36028001200341f0036a200341d0036a200341c0006a20034180016a10ff0220032903f0034201520d0020032903f8032117200341d8016a200341f0036a41106a290300370300200341d0016a2017370300200341a0016a41086a41003a0000200341a9016a20032903d003370000200341b1016a200341d0036a41086a290300370000200341b9016a200341d0036a41106a290300370000200341c1016a200341e8036a290300370000200341023a00a001200341a0016a10e0010b200341aa016a200341d8036a290300370100200341b2016a200341e0036a290300370100200341ba016a200341e8036a2903003701002003418b0a3b01a001200320032903d0033701a201200341a0016a10e0010240200641ffffff3f71450d00200110230b02402003280264450d00200328026010230b2003280270450d0d200328026c10230c0d0b02402004450d00200210230b410e21024185edc30021044180801421060c010b410b210241a5ecc300210441808034210620032802b80141ffffff3f71450d00200110230b02402003280264450d00200328026010230b02402003280270450d00200328026c10230b410321010b20004100360204200041146a2002360200200041106a20043602002000410c6a20064180803c7120017241802a723602000c120b1033000b102c000b201742ffffff3f83500d00200110230b0240200741ffffff3f71450d00200510230b410321010b20004100360204200041146a2004360200200041106a20023602002000410c6a200641107420017241802a723602000c0d0b200820014105746a200341d0036a412010a30522040d01410e210641b9ecc3002105410b21040b200a41ffffff3f71450d05200810230c050b200341a0016a41186a200341d0036a41186a290300370300200341a0016a41106a200341d0036a41106a290300370300200341a0016a41086a200341d0036a41086a290300370300200320032903d0033703a001200341a0016a21022004411f7620016a220420054b0d030b02402005200a470d0020034184046a20054101109a0120032802840421080b200820044105746a220141206a2001200520046b41057410a2051a200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a290000370000200120022900003700002003200541016a36028c04200341a0016a41186a2202200341f0036a41186a290300370300200341a0016a41106a200341f0036a41106a290300370300200341a0016a41086a200341f0036a41086a290300370300200320032903f0033703a00120034180016a200341c0006a200341e0006a10a8042003280280012101200320032802880136029c042003200136029804200341a0016a20034198046a10a3040240200328028401450d00200110230b0240200228020041ffffff3f71450d0020032802b40110230b200341c2016a2003290360370100200341aa016a200341c0006a41086a290300370100200341b2016a200341c0006a41106a290300370100200341ba016a200341c0006a41186a290300370100200341ca016a200341e0006a41086a290300370100200341d2016a200341e0006a41106a290300370100200341da016a200341e0006a41186a2903003701002003418b043b01a001200320032903403701a201200341fa016a200341d0036a41186a290300370100200341f2016a200341d0036a41106a290300370100200341ea016a200341d0036a41086a290300370100200341e2016a20032903d003370100200341a0016a10e001200941ffffff3f71450d00200710230b410021010b200020013602040c0a0b200420051038000b41032101200941ffffff3f71450d01200710230c010b0b200041146a2006360200200041106a2005360200200041003602042000410c6a200441ff017141107420017241802a723602000c030b102a000b0b0240200741ffffff3f71450d00200910230b20004100360204200041146a2002360200200041106a20043602002000410c6a2008411874200141ff017141107472200541ff017141087472200641ff0171723602000b410121010c020b410421064100210241002107410021080b20041023410021010240200641ff017122044104460d00200041146a2005360200200041106a20093602002000410c6a20022007418080fc07717220084180fe037172200472360200410121010b200041003602040b20002001360200200341b0046a24000bb10101027f024020002802082201450d0020002802002100200141246c210103400240024020002d0000220241044b0d0002400240024020020e050400010204040b2000410c6a280200450d03200041086a28020010230c030b2000410c6a280200450d02200041086a28020010230c020b2000410c6a280200450d01200041086a28020010230c010b200041086a280200450d00200041046a28020010230b200041246a21002001415c6a22010d000b0b0bfb0201037f230041206b2203240002400240200241c4006c41046a2204417f4c0d000240024020040d00410121050c010b200410212205450d020b20034100360208200320043602042003200536020020022003106102402002450d00200241c4006c210203400240024020012d00004101460d00200341003a00102003200341106a410110622003200141046a2802003602102003200341106a410410620c010b200341013a00102003200341106a41011062412010212204450d042003422037021420032004360210200341106a200141016a41201062200328021421042003200328021022052003280218106202402004450d00200510230b0240200141216a2d00004101460d00200341003a00102003200341106a410110620c010b200341013a00102003200341106a410110622003200141226a412010620b200141c4006a2101200241bc7f6a22020d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1032000b1033000bfd0102027f027e200028024021020240410410212203450d002003200236000020002d0044210220034104410810252203450d00200320023a0004200041086a29030021042000290300210520034108411510252203450d00200320053700052003410d6a2004370000200041186a29030021042000290310210520034115412a10252203450d00200320053700152003411d6a2004370000200041286a2903002104200029032021052003412a41d40010252203450d00200320053700252003412d6a2004370000200320002903303700352003413d6a200041386a29030037000020012902002003ad4280808080d00884100e200310230f0b102a000b98980207087f017e027f027e057f0a7e287f230041b0116b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541154b0d16200141046a210720050e160102030405060708090a0b0c0d0e0f10111213141517010b200041163602000c450b2006450d4320042d0001210520012003417e6a22083602042001200441026a360200200541094b0d43410a2109024002400240024002400240024002400240024020050e0a00010203040506070809000b20084104490d4c2004280002210620012003417a6a3602042001200441066a3602002006418194ebdc034f0d4c410121090c080b2002200110880120022802000d4b200728020020022802042204490d4b2004417f4c0d1e0240024020040d00410121060c010b200410272206450d3420072802002004490d4b20062001280200200410a1051a200128020422032004490d202001200320046b3602042001200128020020046a3602000b2006450d4b2004ad220a422086200a84220a422088a7210b200aa7210c410221090c070b20084108490d4a2004290002210a2001200341766a36020420012004410a6a360200200a422088a7210b200aa7210c410321090c060b200241086a200110880120022802080d492007280200200228020c2204490d492004417f4c0d1c0240024020040d00410121060c010b200410272206450d3220072802002004490d4920062001280200200410a1051a200128020422032004490d1f2001200320046b3602042001200128020020046a3602000b2006450d492004ad220a422086200a84220a422088a7210b200aa7210c410421090c050b200241106a200110880120022802100d48200728020020022802142204490d482004417f4c0d1b0240024020040d00410121060c010b200410272206450d3120072802002004490d4820062001280200200410a1051a200128020422032004490d1f2001200320046b3602042001200128020020046a3602000b2006450d482004ad220a422086200a84220a422088a7210b200aa7210c410521090c040b2008450d4720042d0002210520012003417d6a22073602042001200441036a360200200541014b0d47410021060240024020050e020100010b20074104490d482004350003210a2001200341796a22053602042001200441076a36020020054104490d482004350007210d2001200341756a36020420012004410b6a360200200d422086200a84210a410121060b200a422088a7210b200aa7210c410621090c030b200241286a200110880120022802280d46200228022c220c200728020041186e22042004200c4b1bad42187e220a422088a70d19200aa72204417f4c0d190240024020040d00410421060c010b200410212206450d2f0b41002105200241003602d80c200220063602d00c2002200441186e3602d40c02400240024002400240200c450d000340200241206a200110880120022802200d05200728020020022802242204490d052004417f4c0d1f0240024020040d004101210b0c010b20041027220b450d3520072802002004490d05200b2001280200200410a1051a200128020422032004490d242001200320046b3602042001200128020020046a3602000b200241186a200110880120022802180d032007280200200228021c2203490d032003417f4c0d1f0240024020030d00410121090c010b200310272209450d3520072802002003490d0320092001280200200310a1051a200128020422082003490d252001200820036b3602042001200128020020036a3602000b2004ad220a422086200a84210a2003ad220d422086200d84210d0240200520022802d40c470d00200241d00c6a2005410110b00120022802d00c210620022802d80c21050b2006200541186c6a2204200936020c2004200a3702042004200b360200200441106a200d3702002002200541016a22053602d80c200c417f6a220c0d000b0b2006450d4a20022902d40c220a422088a7210b200aa7210c410721090c060b200910230b2004450d010b200b10230b02402005450d00200541186c21042006210103400240200141046a280200450d00200128020010230b0240200141106a280200450d002001410c6a28020010230b200141186a2101200441686a22040d000b0b20022802d40c2201450d46200141186c450d460c450b200241d00c6a2001109a0320022802d00c2206450d4541082109200241d00c6a41086a280200210b20022802d40c210c0c010b200241306a200110880120022802300d44200728020020022802342204490d442004417f4c0d170240024020040d00410121060c010b200410272206450d2d20072802002004490d4420062001280200200410a1051a200128020422032004490d1e2001200320046b3602042001200128020020046a3602000b2006450d442004ad220a422086200a84220a422088a7210b200aa7210c410921090b200041003602002000410c6a2006360200200041086a2009360200200041106a200bad422086200cad84370200200041186a200241800f6a41980210a1051a0c440b02402006450d0020012003417e6a3602042001200441026a3602000b200041163602000c430b2006450d3f20042d0001210520012003417e6a22063602042001200441026a36020020050d3f2006450d3f20042d0002210520012003417d6a22073602042001200441036a360200024002400240200541037122064103460d000240024020060e03030001030b2007450d4320042d0003210620012003417c6a3602042001200441046a3602002006410874200572220141ffff0371418002490d43200141fcff0371410276ad210a0c030b20074103490d42200441056a2d0000210620042f0003210720012003417a6a3602042001200441066a3602002007200641107472410874200572220141808004490d422001410276ad210a0c020b02402005410276220c41044b0d0002400240200c0e050002020201000b20074104490d43200428000321052001200341796a3602042001200441076a3602002005418080808004490d432005ad210a0c030b20074108490d422004290003210a2001200341756a36020420012004410b6a360200200a42ffffffffffffffff00560d020c420b200c41046a220641084b0d412003417c6a2103200441046a2104410021054200210a03402003417f460d422004417f6a310000210d20012003360204200120043602002003417f6a2103200441016a2104200d2005410374413871ad86200a84210a200541016a220541ff01712006490d000b200a427f4128200c4103746b413871ad88580d410c010b2005410276ad210a0b20004102360200200041086a200a370300200041106a200241800f6a41a00210a1051a0c420b02402006450d0020042d0001210520012003417e6a22063602042001200441026a360200200541034b0d0002400240024002400240024020050e0400010203000b20064104490d052004280002210620012003417a6a3602042001200441066a36020041012105410021034200210a4200210d4200210e410021010c030b41002105200241003a00f00c2003417e6a210c417d210602400340200c2005460d01200241d00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00f00c2006417f6a21062007210520074120470d000b200320076b220f417e6a4104490d0520022d00ef0c210920022900e70c210a20022800e30c210320022800df0c210820022800db0c211020022800d70c211120022800d30c210620022f00d10c210c20022d00d00c210b41022105200420076a220741026a28000021042001200f417a6a3602042001200741066a360200200a4280808080808080807f83210e200a428080807883210d200341808080787121010c030b200541ff0171450d04200241003a00f00c0c040b20064104490d032004280002210620012003417a6a3602042001200441066a36020041032105410021034200210a4200210d4200210e4100210141002109410021040c010b41002105200241003a00f00c2003417e6a210c417d21060340200c2005460d02200241d00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00f00c2006417f6a21062007210520074120470d000b41042105200320076b220f417e6a4104490d0220022d00ef0c210920022900e70c210a20022800e30c210320022800df0c210820022800db0c211020022800d70c211120022800d30c210620022f00d10c210c20022d00d00c210b200420076a220741026a28000021042001200f417a6a3602042001200741066a360200200a4280808080808080807f83210e200a428080807883210d200341808080787121010b200041003b0026200041003a00252000200c3b00062000200b3a0005200020053a000420004103360200200041286a2004360200200041246a20093a0000200041146a2008360200200041106a20103602002000410c6a2011360200200041086a2006360200200041186a2001200341ffffff0771723602002000411c6a200e200d42808080f8ffffffff008384200a42ffffff0783843702002000412c6a200241800f6a41840210a1051a0c430b200541ff0171450d00200241003a00f00c0b200041163602000c410b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541034b0d00024002400240024020050e0400010203000b41002105200241003a00f00c2003417e6a21072003417d6a21030240034020072005460d01200241d00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00f00c2003417f6a21032006210520064120470d000b20022d00ef0c210b20022900e70c210a20022800e30c210920022800df0c210820022800db0c211020022800d70c211120022800d30c210f20022f00d10c211220022d00d00c2113200241386a20011080022002290338a70d04200241c8006a290300210e2002290340211442002115410121010c400b200541ff0171450d03200241003a00f00c0c030b41002105200241003a00f00c2003417e6a21072003417d6a21030240034020072005460d01200241d00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00f00c2003417f6a21032006210520064120470d000b20022d00ef0c210b20022900e70c210a20022800e30c210920022800df0c210820022800db0c211020022800d70c211120022800d30c210f20022f00d10c211220022d00d00c2113200241e8006a20011080022002290368a70d03200241e8006a41106a290300210e20022903702114200241d0006a20011080022002290350a70d032002290358210d200241d0006a41106a29030022164280808080808080807f832117420021154102210142002118420021194200211a4200211b4200211c4200211d0c400b200541ff0171450d02200241003a00f00c0c020b41002105200241003a00f00c410220036b210c2003417d6a2106024002400340200c20056a450d01200241d00c6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00f00c2006417f6a21062007210520074120470d000b20022d00ef0c210b20022900e70c210a20022800e30c210920022800df0c210820022800db0c211020022800d70c211120022800d30c210f20022f00d10c211220022d00d00c211341002105200241003a00f00c200420076a210c200720036b41026a21030340200320056a450d02200241d00c6a20056a200c20056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a00f00c2006417f6a21062004210520044120470d000b20022d00ef0c210620022900e70c210d20022800e30c210720022800df0c210c20022800db0c211e20022800d70c211f20022800d30c210420022f00d10c210520022d00d00c210320024180016a2001108002200229038001a70d0320024190016a290300211c200229038801220e42ffffff07832115200e42808080f8ffffffff00832119200e4280808080808080807f83211b2006ad42ff018321162007ad422086200cad84210e201ead422086201fad84211442002118410321014200211a4200211d420021170c400b200541ff0171450d02200241003a00f00c0c020b200541ff0171450d01200241003a00f00c0c010b41002105200241003a00f00c2003417e6a21072003417d6a21030240034020072005460d01200241d00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00f00c2003417f6a21032006210520064120470d000b20022d00ef0c210b20022900e70c210a20022800e30c210920022800df0c210820022800db0c211020022800d70c211120022800d30c210f20022f00d10c211220022d00d00c211320024198016a2001108002200229039801a70d01200241a8016a290300210e20022903a001211442002115410421010c3d0b200541ff0171450d00200241003a00f00c0b200041163602000c400b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241b0016a200110880120022802b0010d0020022802b4012206200728020041f0006e2204200420064b1bad42f0007e220a422088a70d12200aa72203417f4c0d120240024020030d004104210c0c010b20031021220c450d280b41002104200241003602b8042002200c3602b0042002200341f0006e3602b404024002402006450d00200241d00c6a41086a210b0340200241d00c6a2001109b0320022802d40c210320022802d00c2107200241a00a6a200b41e80010a1051a2003450d02200241b0056a200241a00a6a41e80010a1051a0240200420022802b404470d00200241b0046a2004410110b50120022802b004210c20022802b80421040b200c200441f0006c6a2205200336020420052007360200200541086a200241b0056a41e80010a1051a2002200441016a22043602b8042006417f6a22060d000b0b200c450d0120022902b404210a2000200c36020420004105360200200041086a200a370200200041106a200241800f6a41a00210a1051a0c410b02402004450d00200441f0006c2104200c41046a2101034020011096030240200141046a2802002203450d00200341246c450d00200128020010230b200141f0006a2101200441907f6a22040d000b0b20022802b4042201450d00200141f0006c450d00200c10230b200041163602000c3f0b2006450d3620042d0001210520012003417e6a22203602042001200441026a360200200541174b0d36410421130240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e180001024f030405060708090a0b0c0d0e0f10111213141516000b41002105200241003a00a00f2003417e6a210c2003417d6a210302400340200c2005460d01200241800f6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00a00f2003417f6a21032006210520064120470d000b20022d009f0f211120022900970f210e20022800930f2110200228008f0f2109200228008b0f210820022800870f210c20022800830f210620022f00810f210f20022d00800f210b200241b8016a200110800220022903b801a70d4d20072802002204450d4d200241c8016a290300210d20022903c001210a200128020022032d0000211220012004417f6a360204410121132001200341016a360200201241024b0d4d20024190096a41106a200241d00c6a41106a29020037030020024190096a41086a200241d00c6a41086a290200370300200241f8086a41086a200241a00a6a41086a290300370300200241f8086a41106a200241a00a6a41106a290300370300200241c8086a41086a200241b0046a41086a290200370300200241c8086a41106a200241b0046a41106a290200370300200220022902d00c37039009200220022903a00a3703f808200220022902b0043703c808200241b0086a41106a200241a8096a41106a290300370300200241b0086a41086a200241a8096a41086a290300370300200220022903a8093703b008200e422088a72121200ea721220c4f0b200541ff0171450d4c200241003a00a00f0c4c0b200241d0016a200110800220022903d001a70d4b200241d0016a41106a290300210a20022903d801210d20024190096a41106a200241800f6a41106a29020037030020024190096a41086a200241800f6a41086a290200370300200241f8086a41086a200241d00c6a41086a290300370300200241f8086a41106a200241d00c6a41106a290300370300200241c8086a41086a200241a00a6a41086a290200370300200241c8086a41106a200241a00a6a41106a290200370300200220022902800f37039009200220022903d00c3703f808200220022902a00a3703c808200241b0086a41106a200241b0046a41106a290300370300200241b0086a41086a200241b0046a41086a290300370300200220022903b0043703b008200d422088a72108200a422088a72110200da7210c200aa72109410221130c4d0b200241e8016a200110800220022903e801a70d4a200241e8016a41106a290300210a20022903f001210d20024190096a41106a200241800f6a41106a29020037030020024190096a41086a200241800f6a41086a290200370300200241f8086a41086a200241d00c6a41086a290300370300200241f8086a41106a200241d00c6a41106a290300370300200241c8086a41086a200241a00a6a41086a290200370300200241c8086a41106a200241a00a6a41106a290200370300200220022902800f37039009200220022903d00c3703f808200220022902a00a3703c808200241b0086a41106a200241b0046a41106a290300370300200241b0086a41086a200241b0046a41086a290300370300200220022903b0043703b008200d422088a72108200a422088a72110200da7210c200aa72109410321130c4c0b20024180026a20011088012002280280020d49200228028402210620024190096a41106a200241800f6a41106a29020037030020024190096a41086a200241800f6a41086a290200370300200241f8086a41086a200241d00c6a41086a290300370300200241f8086a41106a200241d00c6a41106a290300370300200241c8086a41086a200241a00a6a41086a290200370300200241c8086a41106a200241a00a6a41106a290200370300200220022902800f37039009200220022903d00c3703f808200220022902a00a3703c808200241b0086a41106a200241b0046a41106a290300370300200241b0086a41086a200241b0046a41086a290300370300200220022903b0043703b008410521130c4a0b200241a8096a200110cf0120022802a8092206450d4820024190096a41086a200241800f6a41086a29020037030020024190096a41106a200241800f6a41106a290200370300200241f8086a41086a200241d00c6a41086a290300370300200241f8086a41106a200241d00c6a41106a290300370300200241c8086a41086a200241a00a6a41086a290200370300200241c8086a41106a200241a00a6a41106a290200370300200220022902800f37039009200220022903d00c3703f808200220022902a00a3703c808200241a8096a41086a280200210820022802ac09210c200241b0086a41106a200241b0046a41106a290300370300200241b0086a41086a200241b0046a41086a290300370300200220022903b0043703b008410621130c4a0b410721130c490b2020450d4620042d0002210b20012003417d6a3602042001200441036a360200200b41024b0d4620024190096a41106a200241800f6a41106a2901003703004108211320024190096a41086a200241800f6a41086a290100370300200241f8086a41086a200241d00c6a41086a290100370300200241f8086a41106a200241d00c6a41106a290100370300200241c8086a41086a200241a00a6a41086a290100370300200241c8086a41106a200241a00a6a41106a290100370300200220022901800f37039009200220022901d00c3703f808200220022901a00a3703c808200241b0086a41106a200241b0046a41106a290100370300200241b0086a41086a200241b0046a41086a290100370300200220022901b0043703b0084100211041002109410021080c480b41002105200241003a00a00f2003417e6a21072003417d6a21030240034020072005460d01200241800f6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00a00f2003417f6a21032006210520064120470d000b20024190096a41086a200241d00c6a41086a29000037030020024190096a41106a200241d00c6a41106a290000370300200241f8086a41086a200241a00a6a41086a290000370300200241f8086a41106a200241a00a6a41106a290000370300200220022900d00c37039009200220022900a00a3703f80820022d009f0f211120022800930f2110200228008f0f2109200228008b0f210820022800870f210c20022800830f210620022f00810f210f20022d00800f210b20022900970f210a200241c8086a41106a200241b0046a41106a290000370300200241c8086a41086a200241b0046a41086a290000370300200220022900b0043703c808200241b0086a41106a200241a8096a41106a290000370300200241b0086a41086a200241a8096a41086a290000370300200220022900a8093703b008200a422088a72121200aa72122410921130c430b200541ff0171450d45200241003a00a00f0c450b20024188026a20011088012002280288020d44200228028c02210620024190096a41106a200241800f6a41106a29020037030020024190096a41086a200241800f6a41086a290200370300200241f8086a41086a200241d00c6a41086a290300370300200241f8086a41106a200241d00c6a41106a290300370300200241c8086a41086a200241a00a6a41086a290200370300200241c8086a41106a200241a00a6a41106a290200370300200220022902800f37039009200220022903d00c3703f808200220022902a00a3703c808200241b0086a41106a200241b0046a41106a290300370300200241b0086a41086a200241b0046a41086a290300370300200220022903b0043703b008410a21130c450b410b21130c450b410c21130c440b200241a8096a200110cf0120022802a8092206450d4120024190096a41086a200241800f6a41086a29020037030020024190096a41106a200241800f6a41106a290200370300200241f8086a41086a200241d00c6a41086a290300370300200241f8086a41106a200241d00c6a41106a290300370300200241c8086a41086a200241a00a6a41086a290200370300200241c8086a41106a200241a00a6a41106a290200370300200220022902800f37039009200220022903d00c3703f808200220022902a00a3703c80820022902ac09210a200241b0086a41106a200241b0046a41106a290300370300200241b0086a41086a200241b0046a41086a290300370300200220022903b0043703b008200a422088a72108200aa7210c410d21130c430b41002105200241003a00a00f2003417e6a21072003417d6a21030240034020072005460d01200241800f6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00a00f2003417f6a21032006210520064120470d000b20024190096a41086a200241d00c6a41086a29000037030020024190096a41106a200241d00c6a41106a2900003703002002200229008f0f220a3700af0a200220022900870f220d3700a70a200220022800830f22063600a30a200220022f00810f220f3b00a10a200220022d00800f220b3a00a00a200220022d009f0f22113a00bf0a200220022900970f220e3700b70a200220022900d00c37039009200241f8086a41106a200241b0046a41106a290000370300200241f8086a41086a200241b0046a41086a290000370300200220022900b0043703f808200241c8086a41106a200241a8096a41106a290000370300200241c8086a41086a200241a8096a41086a290000370300200220022900a8093703c808200241b0086a41106a200241880a6a41106a290000370300200241b0086a41086a200241880a6a41086a290000370300200220022900880a3703b008200e422088a72121200a422088a72110200d422088a72108200ea72122200aa72109200da7210c410e21130c3e0b200541ff0171450d40200241003a00a00f0c400b410f21130c410b20204104490d3e2004280002210620012003417a6a3602042001200441066a36020020024190026a20011088012002280290020d3e20072802002002280294024102742204490d3e2004417f4c0d180240024020040d004101210c0c010b20041027220c450d2e20072802002004490d21200c2001280200200410a1051a200128020422032004490d202001200320046b3602042001200128020020046a3602000b200c450d3e02402004ad220a422086200a84220a422088a722010d00200aa721010c3d0b0240200c2001724103710d00200aa722014103710d0020014102762208450d3d200a422288a721090c3e0b200aa7450d3e200c10230c3e0b20204104490d3d2004280002210620012003417a6a3602042001200441066a36020020024198026a20011088012002280298020d3d200228029c022210200728020041246e2204200420104b1bad42247e220a422088a70d17200aa72204417f4c0d170240024020040d004104210c0c010b20041021220c450d2d0b41002109200241003602900a2002200c3602880a2002200441246e220836028c0a0240024002402010450d0041002109410021110340200241003a00a00f201141016a21112007280200210b417f2103410021040340200b2004460d03200241800f6a20046a200128020022082d00003a00002001200b20036a3602042001200841016a3602002002200441016a22053a00a00f2003417f6a21032005210420054120470d000b200b20056b22044104490d0320022d009f0f210320022900970f210a20022800930f2105200228008f0f210b200228008b0f210f20022800870f211220022800830f211320022f00810f211e20022d00800f211f200828000121232001200841056a36020020012004417c6a36020402402009200228028c0a470d00200241880a6a2009410110a20120022802880a210c20022802900a21090b200c200941246c6a22042023360220200420033a001f2004200a370017200420053600132004200b36000f2004200f36000b20042012360007200420133600032004201e3b00012004201f3a00002002200941016a22093602900a20112010470d000b200228028c0a21080b200c450d3f20024190096a41106a200241d00c6a41106a29020037030020024190096a41086a200241d00c6a41086a290200370300200241f8086a41086a200241a00a6a41086a290200370300200241f8086a41106a200241a00a6a41106a290200370300200241c8086a41086a200241b0046a41086a290200370300200241c8086a41106a200241b0046a41106a290200370300200220022902d00c37039009200220022902a00a3703f808200220022902b0043703c808200241b0086a41106a200241a8096a41106a290200370300200241b0086a41086a200241a8096a41086a290200370300200220022902a8093703b008411121130c410b200441ff0171450d00200241003a00a00f0b200228028c0a2201450d3d200141246c450d3d200c10230c3d0b20204104490d3c2004280002210620012003417a6a3602042001200441066a36020020024190096a41086a200241800f6a41086a29020037030020024190096a41106a200241800f6a41106a290200370300200241f8086a41086a200241d00c6a41086a290300370300200241f8086a41106a200241d00c6a41106a290300370300200241c8086a41086a200241a00a6a41086a290200370300200241c8086a41106a200241a00a6a41106a290200370300200220022902800f37039009200220022903d00c3703f808200220022902a00a3703c808200241b0086a41106a200241b0046a41106a290300370300200241b0086a41086a200241b0046a41086a290300370300200220022903b0043703b008411221130c3d0b41002105200241003a00a00f2003417e6a210c417d210602400340200c2005460d01200241800f6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00a00f2006417f6a21062007210520074120470d000b200320076b2203417e6a4104490d3c20022d009f0f211120022900970f210a20022800930f2110200228008f0f2109200228008b0f210820022800870f210c20022800830f210620022f00810f210f20022d00800f210b200420076a220441026a280000212420012003417a6a3602042001200441066a36020020024190096a41086a200241d00c6a41086a29020037030020024190096a41106a200241d00c6a41106a290200370300200241f8086a41086a200241a00a6a41086a290300370300200241f8086a41106a200241a00a6a41106a290300370300200241c8086a41086a200241b0046a41086a290200370300200241c8086a41106a200241b0046a41106a290200370300200220022902d00c37039009200220022903a00a3703f808200220022902b0043703c808200241b0086a41106a200241a8096a41106a290300370300200241b0086a41086a200241a8096a41086a290300370300200220022903a8093703b008200a422088a72121200aa72122411321130c390b200541ff0171450d3b200241003a00a00f0c3b0b200241a0026a200110800220022903a002a70d3a200241a0026a41106a290300210a20022903a802210d20024190096a41106a200241800f6a41106a29020037030020024190096a41086a200241800f6a41086a290200370300200241f8086a41086a200241d00c6a41086a290300370300200241f8086a41106a200241d00c6a41106a290300370300200241c8086a41086a200241a00a6a41086a290200370300200241c8086a41106a200241a00a6a41106a290200370300200220022902800f37039009200220022903d00c3703f808200220022902a00a3703c808200241b0086a41106a200241b0046a41106a290300370300200241b0086a41086a200241b0046a41086a290300370300200220022903b0043703b008200d422088a72108200a422088a72110200da7210c200aa72109411421130c3c0b200241b8026a200110880120022802b8020d3920022802bc02210620024190096a41106a200241d00c6a41106a29020037030020024190096a41086a200241d00c6a41086a290200370300200241f8086a41086a200241a00a6a41086a290300370300200241f8086a41106a200241a00a6a41106a290300370300200241c8086a41086a200241b0046a41086a290200370300200241c8086a41106a200241b0046a41106a290200370300200220022902d00c37039009200220022903a00a3703f808200220022902b0043703c808200241b0086a41106a200241a8096a41106a290300370300200241b0086a41086a200241a8096a41086a290300370300200220022903a8093703b00842002115411521134100211041002109410021084100210c420021180c3b0b41002105200241003a00a00f2003417e6a21072003417d6a21030240034020072005460d01200241800f6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00a00f2003417f6a21032006210520064120470d000b20024190096a41086a200241d00c6a41086a29000037030020024190096a41106a200241d00c6a41106a2900003703002002200229008f0f220a3700ef08200220022900870f220d3700e708200220022800830f22063600e308200220022f00810f220f3b00e108200220022d00800f220b3a00e008200220022900d00c3703900920022d009f0f211120022900970f210e200241f8086a41106a200241a00a6a41106a290000370300200241f8086a41086a200241a00a6a41086a290000370300200220022900a00a3703f808200241c8086a41106a200241b0046a41106a290000370300200241c8086a41086a200241b0046a41086a290000370300200220022900b0043703c808200241b0086a41106a200241a8096a41106a290000370300200241b0086a41086a200241a8096a41086a290000370300200220022900a8093703b008200e422088a72121200a422088a72110200d422088a72108200ea72122200aa72109200da7210c411621130c360b200541ff0171450d38200241003a00a00f0c380b200241c0026a200110880120022802c0020d37200728020020022802c4024101742204490d372004417f4c0d110240024020040d00410121060c010b200410272206450d2720072802002004490d3420062001280200200410a1051a200128020422032004490d1b2001200320046b3602042001200128020020046a3602000b2006450d3702402004ad220a422086200a84220a422088a722040d00200aa721040c320b024020062004724101710d00200aa722044101710d002004410176220c450d32200a422188a721080c330b200aa70d330c370b200241c8026a200110880120022802c8020d36200728020020022802cc024101742204490d362004417f4c0d100240024020040d00410121060c010b200410272206450d2620072802002004490d3320062001280200200410a1051a200128020422032004490d1b2001200320046b3602042001200128020020046a3602000b2006450d3602402004ad220a422086200a84220a422088a722040d00200aa721040c2f0b024020062004724101710d00200aa722044101710d002004410176220c450d2f200a422188a721080c300b200aa70d320c360b02402006450d0020012003417e6a3602042001200441026a3602000b200041163602000c3d0b2006450d1b20042d0001210520012003417e6a3602042001200441026a360200200541014b0d1b410021040240024020050e020001000b200241800f6a200110e50220022d00800f4101460d1c200241d00c6a200241800f6a41017241a00110a1051a200241d0026a200110880120022802d0020d1c200728020020022802d4022203490d1c2003417f4c0d0f0240024020030d00410121040c010b200310272204450d2520072802002003490d1c20042001280200200310a1051a200128020422052003490d1b2001200520036b3602042001200128020020036a3602000b2004450d1c2003ad220a422086200a84210a200241a00a6a200241d00c6a41a00110a1051a0b200241b0056a200241a00a6a41a00110a1051a200041086a200a3702002000200436020420004108360200200041106a200241b0056a41a00110a1051a200041b0016a200241b0046a41800110a1051a0c3c0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241d8026a200110880120022802d8020d0020022802dc0221012000410936020020002001360204200041086a200241800f6a41a80210a1051a0c3c0b200041163602000c3b0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e0026a200110880120022802e0020d00200728020020022802e4022204490d002004417f4c0d0d02400240024020040d00410121030c010b200410272203450d2420072802002004490d0120032001280200200410a1051a200128020422052004490d1d2001200520046b3602042001200128020020046a3602000b2003450d01200020033602042000410a360200200041086a2004ad220a422086200a84370200200041106a200241800f6a41a00210a1051a0c3c0b200310230b200041163602000c3a0b02402006450d0020042d0001210520012003417e6a22063602042001200441026a36020020050d0020064104490d002004280002210520012003417a6a3602042001200441066a360200200241f8026a200110880120022802f8020d00200728020020022802fc022204490d002004417f4c0d0c0240024002400240024002400240024020040d00410121060c010b200410272206450d2820072802002004490d0120062001280200200410a1051a200128020422032004490d222001200320046b3602042001200128020020046a3602000b2006450d06200241f0026a20011088012004ad220a422086200a84220da72110024020022802f0020d0020022802f402220b2007280200410c6e22042004200b4b1bad420c7e220a422088a70d13200aa72204417f4c0d130240024020040d00410421090c010b200410212209450d290b41002103200241003602d80c200220093602d00c20022004410c6e22083602d40c024002400240200b450d00410021030340200241e8026a200110880120022802e8020d03200728020020022802ec022204490d032004417f4c0d170240024020040d004101210c0c010b20041027220c450d2d20072802002004490d03200c2001280200200410a1051a200128020422082004490d282001200820046b3602042001200128020020046a3602000b2004ad220a422086200a84210a0240200320022802d40c470d00200241d00c6a2003410110950120022802d00c210920022802d80c21030b20092003410c6c6a2204200a3702042004200c3602002002200341016a22033602d80c200b417f6a220b0d000b20022802d40c21080b2009450d022006450d09200728020022074104490d042001280200220b280000210f20012007417c6a22043602042001200b41046a36020020044104490d05200d422088a72112200b28000421132001200741786a22113602042001200b41086a36020041002104200241003a00900d200741776a2107034020112004460d07200241d00c6a20046a200b20046a220c41086a2d00003a0000200120073602042001200c41096a3602002002200441016a220c3a00900d2007417f6a2107200c2104200c41c000470d000b200c41ff017141c000490d072006450d09200228028c0d210120022f018a0d210420022d00890d210720022d00880d210c20022802840d210b20022802800d211120022802fc0c211e20022802f80c211f20022f01f60c212320022d00f50c212520022d00f40c212620022802f00c212720022802ec0c212820022d00e80c212920022903e00c210a20022802dc0c212a20022802d80c212b20022802d40c212c20022802d00c212d200020022f00e90c200241eb0c6a2d000041107472222e3b0041200020073a0061200020233b004e200020253a004d200020053602042000410b360200200041c3006a202e4110763a0000200041e4006a2001360200200041e2006a20043b0100200041e0006a200c3a0000200041dc006a200b360000200041d8006a2011360000200041d4006a201e360000200041d0006a201f360000200041cc006a20263a0000200041c8006a2027360000200041c4006a2028360000200041c0006a20293a0000200041386a200a370200200041346a202a360200200041306a202b3602002000412c6a202c360200200041286a202d360200200041246a2013360200200041206a200f3602002000411c6a2003360200200041186a2008360200200041146a2009360200200041106a20123602002000410c6a2010360200200041086a2006360200200041e8006a200241800f6a41c80110a1051a0c430b200c10230b02402003450d002003410c6c21042009210103400240200141046a280200450d00200128020010230b2001410c6a2101200441746a22040d000b0b20022802d40c2201450d002001410c6c450d00200910230b2010450d060b200610230c050b02402010450d00200610230b02402003450d002003410c6c21042009210103400240200141046a280200450d00200128020010230b2001410c6a2101200441746a22040d000b0b2008450d042008410c6c0d030c040b02402010450d00200610230b02402003450d002003410c6c21042009210103400240200141046a280200450d00200128020010230b2001410c6a2101200441746a22040d000b0b2008450d032008410c6c0d020c030b200441ff0171450d00200241003a00900d0b02402010450d00200610230b02402003450d002003410c6c21042009210103400240200141046a280200450d00200128020010230b2001410c6a2101200441746a22040d000b0b2008450d012008410c6c450d010b200910230b200041163602000c390b02402006450d0020012003417e6a3602042001200441026a3602000b200041163602000c380b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541014b0d0002400240024002400240024020050e020001000b200241b0056a2001109c0320022802b0052210450d05200241b8056a280200210f20022802b4052111200241d00c6a200241800f6a41c30110a1051a410121010c010b41002105200241003a00d0052003417e6a210c2003417d6a21030340200c2005460d02200241b0056a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d0052003417f6a21032006210520064120470d000b20022d00cf05212820022900c705210a20022800c305210920022800bf05210b20022800bb05210c20022800b705210620022800b305210520022f00b105210320022d00b0052104200241b0056a2001109d0320022d00b00522084103460d04200241a8096a200241b0056a41017241e00010a1051a200241b0056a2001109d0320022d00b0054103460d04200241b0046a200241b0056a41e10010a1051a200728020022114104490d042001280200220f280000211020012011417c6a3602042001200f41046a360200200241b0056a2001109a0320022802b0052211450d04200241b8056a280200211220022802b405210f2007280200221e4104490d032001280200222328000021132001201e417c6a22253602042001202341046a36020041002107200241003a00d005201e417b6a211e034020252007460d03200241b0056a20076a202320076a221f41046a2d00003a00002001201e3602042001201f41056a3602002002200741016a221f3a00d005201e417f6a211e201f2107201f4120470d000b20023100cf05211420022900c705210e20022800c305212720022800bf05212620022800bb05212520022800b705212320022800b305211f20022f00b105211e20022d00b0052107200241800f6a200241a8096a41e00010a1051a200241800f6a41e0006a200241b0046a41e10010a1051a200241d00c6a200241800f6a41c30110a1051a2028ad210d410221010b200241a00a6a200241d00c6a41c30110a1051a200041db006a200d3c0000200041d3006a200a3700002000413b6a20143c0000200041336a200e370000200041dc006a20083a0000200041cf006a2009360000200041cb006a200b360000200041c7006a200c360000200041c3006a20063600002000413f6a20053600002000413d6a20033b00002000413c6a20043a00002000412f6a20273600002000412b6a2026360000200041276a2025360000200041236a20233600002000411f6a201f3600002000411d6a201e3b00002000411c6a20073a0000200041186a2013360200200041146a2012360200200041106a200f3602002000410c6a2011360200200041086a2010360200200020013602042000410d360200200041dd006a200241a00a6a41c30110a1051a200041a8026a200241880a6a41086a290300370300200041a0026a20022903880a3703000c3b0b200541ff0171450d02200241003a00d0050c020b200741ff0171450d00200241003a00d0050b02402012450d002012410c6c21042011210103400240200141046a280200450d00200128020010230b2001410c6a2101200441746a22040d000b0b200f450d00200f410c6c450d00201110230b200041163602000c370b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d002000410e360200200041046a200241800f6a41ac0210a1051a0c370b200041163602000c360b2006450d2420042d0001210520012003417e6a222e3602042001200441026a3602004106210c200541064b0d244200210a02400240024002400240024002400240024020050e0700010203040805000b20024190036a20011088012002280290030d2c20072802002203450d2c200228029403210b200128020022052d0000210420012003417f6a3602042001200541016a360200200441014b0d2c410021090240024020040e020100010b410121090b20024188036a20011088012002280288030d2c2007280200200228028c032204490d2c2004417f4c0d0f02400240024020040d00410121080c010b200410272208450d2620072802002004490d0120082001280200200410a1051a200128020422032004490d222001200320046b3602042001200128020020046a3602000b2008450d2d20024180036a20011088012004ad220a422086200a84220aa7210f02402002280280030d0020072802002002280284032204490d002004417f4c0d1102400240024020040d00410121130c010b200410272213450d2820072802002004490d0120132001280200200410a1051a200128020422032004490d252001200320046b3602042001200128020020046a3602000b2013450d01200a422088a721112004ad220a422086200a84220d42808080807083210a200da721124101210c0c0a0b201310230b200f450d2d0b200810230c2c0b20024198036a20011088012002280298030d2b200228029c03210b4102210c0c040b202e4104490d2a2004280002210b20012003417a6a3602042001200441066a3602004103210c0c030b200241a8036a200110880120022802a8030d29200728020020022802ac032204490d292004417f4c0d0c02400240024020040d004101210b0c010b20041027220b450d2320072802002004490d01200b2001280200200410a1051a200128020422032004490d212001200320046b3602042001200128020020046a3602000b200b450d2a200241a0036a20011088012004ad220d422086200d84220da72108024020022802a0030d00200728020020022802a4032212490d002012417f4c0d0e02400240024020120d00410121110c010b201210272211450d2520072802002012490d0120112001280200201210a1051a200128020422042012490d242001200420126b3602042001200128020020126a3602000b2011450d01200d422088a7210f4104210c201221130c060b201110230b2008450d2a0b200b10230c290b200241b0036a200110880120022802b0030d2820022802b403211041002104200241003a00f00c20072802002107417f210302400240034020072004460d01200241d00c6a20046a200128020022062d00003a00002001200720036a3602042001200641016a3602002002200441016a22053a00f00c2003417f6a21032005210420054120470d000b20022d00ef0c211f20022900e70c210d20022800e30c211320022800df0c211120022800db0c210f20022800d70c210820022800d30c210b20022f00d10c211e20022d00d00c210941002104200241003a00f00c200720056b210c200720036a21030340200c2004460d02200241d00c6a20046a200620046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00f00c2003417f6a21032005210420054120470d000b200220022f00d10c3b00e108200220022d00d00c3a00e00820022800db0c2223411076212820234108762127200d42808080807083210a20022f01e00820022d00e20841107472210620022900e70c220e422088a7212c20022d00ef0c212d20022800e30c212a20022800df0c212920022800d70c212620022800d30c2125200ea7212b200da721124105210c0c050b200441ff0171450d29200241003a00f00c0c290b200441ff0171450d28200241003a00f00c0c280b200241b8036a200110880120022802b8030d2720022802bc03210b4107210c0b0b0b200020063b0025200020283b0032200020273a00312000201e3b0106200020093a00052000200c3a00042000410f360200200041276a20064110763a0000200041c8006a2010360200200041c4006a202d3a0000200041c0006a202c3600002000413c6a202b360000200041386a202a360000200041346a2029360000200041306a20233a00002000412c6a2026360000200041286a2025360000200041246a201f3a0000200041186a2013360200200041146a2011360200200041106a200f3602002000410c6a2008360200200041086a200b3602002000411c6a200a2012ad84370200200041cc006a200241800f6a41e40110a1051a0c350b2006450d2120042d0001210520012003417e6a22063602042001200441026a360200200541044b0d2102400240024002400240024002400240024020050e050001020304000b200241c0036a200110880120022802c0030d2920022802c4032206200728020041b0026e2204200420064b1bad42b0027e220a422088a70d0e200aa72203417f4c0d0e0240024020030d00410821050c010b200310212205450d240b41002104200241003602b804200220053602b0042002200341b0026e3602b404024002402006450d00200241800f6a410472210c0340200241800f6a200110990320022802800f2103200241d00c6a200c41ac0210a1051a20034116460d02200241a00a6a200241d00c6a41ac0210a1051a0240200420022802b404470d00200241b0046a2004410110ad0120022802b004210520022802b80421040b2005200441b0026c6a22072003360200200741046a200241a00a6a41ac0210a1051a2002200441016a22043602b8042006417f6a22060d000b0b2005450d2a20022902b404220a422088a72103200aa721044101211e41002107410021110c060b02402004450d00200441b0026c21042005210103402001109e03200141b0026a2101200441d07d6a22040d000b0b20022802b4042201450d29200141b0026c450d29200510230c290b20064102490d2820042f0002210920012003417c6a3602042001200441046a360200200241800f6a200110990320022802800f2101200241d00c6a200241800f6a41047241ac0210a1051a20014116460d28200241800f6a200241d00c6a41ac0210a1051a41b002102122050d030c290b20064102490d2720042f0002210920012003417c6a3602042001200441046a360200200241800f6a200110cf0120022802800f2205450d2720022802840f2104024020072802002206450d00200241880f6a28020021032001280200220b2d0000210c20012006417f6a22083602042001200b41016a360200200c41014b0d004100211302400240200c0e020100010b20084104490d01200b280001210720012006417b6a220c3602042001200b41056a360200200c4104490d01200b28000521122001200641776a3602042001200b41096a360200410121130b200241800f6a200110990320022802800f2106200241d00c6a200241800f6a41047241ac0210a1051a20064116460d06200241800f6a200241d00c6a41ac0210a1051a41b00210212201450d2920012006360200200141046a200241800f6a41ac0210a1051a4103211e0c040b200441ffffff3f71450d270c260b20064102490d2620042f0002210b20012003417c6a3602042001200441046a360200200241800f6a200110cf0120022802800f2206450d2620022802840f210c024020072802002204450d00200241880f6a2802002108200128020022052d0000210320012004417f6a22073602042001200541016a360200200341014b0d00410021100240024020030e020100010b20074104490d012005280001211120012004417b6a22033602042001200541056a36020020034104490d012005280005210f2001200441776a22073602042001200541096a360200410121100b41002103200241003a00a00f2007417f6a2104024003402004417f460d01200241800f6a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a00f2004417f6a21042005210320054120470d000b20022900970f220a422088a7210120022d009f0f211f20022800930f2107200228008f0f2113200228008b0f210320022800870f210420022800830f210520022f00810f210920022d00800f2123200aa721124104211e0c050b0240200341ff0171450d00200241003a00a00f0b200c41ffffff3f71450d27200610230c270b200c41ffffff3f71450d26200610230c260b20064102490d2520042f0002210b20012003417c6a3602042001200441046a360200200241800f6a200110cf0120022802800f2206450d2520022802840f210c0240200728020022034104490d00200241880f6a280200210820012802002207280000211020012003417c6a22043602042001200741046a36020020044104490d00200728000421112001200341786a22093602042001200741086a36020041002104200241003a00a00f200341776a21030240034020092004460d01200241800f6a20046a200720046a220541086a2d00003a0000200120033602042001200541096a3602002002200441016a22053a00a00f2003417f6a21032005210420054120470d000b20022900970f220a422088a7210120022d009f0f211f20022800930f2107200228008f0f2113200228008b0f210320022800870f210420022800830f210520022f00810f210920022d00800f2123200aa721124105211e0c040b0240200441ff0171450d00200241003a00a00f0b200c41ffffff3f71450d26200610230c260b200c41ffffff3f71450d25200610230c250b20052001360200200541046a200241800f6a41ac0210a1051a4102211e0b0b200020233a00052000201e3a0004200041103602002000413c6a200f360200200041386a2011360200200041346a2010360200200041306a20083602002000412c6a200c360200200041286a2006360200200041266a200b3b0100200041246a201f3a0000200041206a20013602002000411c6a2012360200200041186a2007360200200041146a2013360200200041106a20033602002000410c6a2004360200200041086a2005360200200041066a20093b0100200041c0006a200241b0056a41f00110a1051a0c350b200441ffffff3f710d200c210b2006450d1e20042d0001210620012003417e6a222f3602042001200441026a3602002006410a4b0d1e410421304200211d0240024002400240024002400240024002400240024020060e0b0001022803040506070809000b41002105200241003a00a00f2003417e6a21072003417d6a21030240034020072005460d01200241800f6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00a00f2003417f6a21032006210520064120470d000b200241c8086a41086a200241d00c6a41086a290000370300200241c8086a41106a200241d00c6a41106a290000370300200241b0086a41086a200241a00a6a41086a290000370300200241b0086a41106a200241a00a6a41106a290000370300200220022900d00c3703c808200220022900a00a3703b0082002418f0f6a290000210a2002419f0f6a310000210e20022800830f210c20022f00810f211320022d00800f211e20022900870f210d20022900970f211420024198086a41106a200241b0056a41106a29000037030020024198086a41086a200241b0056a41086a290000370300200220022900b0053703980820024180086a41106a200241b0046a41106a29000037030020024180086a41086a200241b0046a41086a290000370300200220022900b004370380082014422088200e42208684210e200d422088a72105200a422088a7210f200a4280feffff0f83420888a721312014a72110200da7210b200aa7210841012130410021120c280b200541ff0171450d28200241003a00a00f0c280b200241c8036a200110880120022802c8030d2720022802cc032206200728020041c8006e2204200420064b1bad42c8007e220a422088a70d0e200aa72204417f4c0d0e0240024020040d004104210c0c010b20041021220c450d240b41002105200241003602e8082002200c3602e0082002200441c8006e220b3602e4080240024002402006450d00200241d00c6a410c6a2113410021050340200241d00c6a2001109f030240024020022d00d00c22034106470d00410621030c010b200241a8096a41086a2209201341086a290200370300200241a8096a41106a2208201341106a290200370300200220132902003703a80920022802d80c210420022802d40c210b20022f01d20c211020022d00d10c2111200241800f6a2001109f03024020022d00800f4106470d00024020034101470d002004450d00200b10230b410621030c010b200241880a6a41106a2008290300370300200241880a6a41086a2009290300370300200241a00a6a41086a200241800f6a41086a290300370300200241a00a6a41106a200241800f6a41106a290300370300200241a00a6a41186a200241800f6a41186a290300370300200241a00a6a41206a200241800f6a41206a280200360200200220022903a8093703880a200220022903800f3703a00a2011211e2010211f20042123200b21250b20024190096a41086a2204200241880a6a41086a29030037030020024190096a41106a220b200241880a6a41106a290300370300200241b0056a41086a2209200241a00a6a41086a290300370300200241b0056a41106a2208200241a00a6a41106a290300370300200241b0056a41186a2210200241a00a6a41186a290300370300200241b0056a41206a2211200241a00a6a41206a280200360200200220022903880a37039009200220022903a00a3703b00520034106460d02200241f8086a41106a220f200b290300370300200241f8086a41086a220b2004290300370300200241b0046a41086a22122009290300370300200241b0046a41106a22092008290300370300200241b0046a41186a22082010290300370300200241b0046a41206a2210201128020036020020022002290390093703f808200220022903b0053703b0040240200520022802e408470d00200241e0086a2005410110a10120022802e008210c20022802e80821050b200c200541c8006c6a2204201e3a0001200420033a0000200441086a2023360000200441046a2025360000200441026a201f3b00002004410c6a20022903f808370000200441146a200b2903003700002004411c6a200f290300370000200441246a20022903b0043700002004412c6a2012290300370000200441346a20092903003700002004413c6a2008290300370000200441c4006a20102802003600002002200541016a22053602e8082006417f6a22060d000b20022802e408210b0b200c0d010c290b02402005450d00200c200541c8006c6a2104200c21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012004470d000b0b20022802e4082201450d28200141c8006c450d28200c10230c280b200241800f6a2001109f0302400240024002400240024002400240024020022d00800f22084106460d00200241a00f6a280200211f200241980f6a290300210d200241940f6a220428020021092002418c0f6a2203290200210e200241880f6a2206280200211020022802840f210f20022f00810f211320022d00830f211e200241800f6a2001109f0320022d00800f22124106460d012002419c0f6a222a290200211520042902002114200241800f6a41106a28020021282002418e0f6a2f010021292002418d0f6a2d0000212720032d000021262006280200211120022802840f212320023301820f211d20023100810f2117200241800f6a2001109f0320022d00800f22254106460d02200241b0046a41086a200241940f6a2204290200370300200241b0046a41106a202a29020037030020022002418c0f6a22032902003703b004200241800f6a41086a2206280200212a20022802840f212b20022f01820f212e20022d00810f212d200241800f6a2001109f0320022d00800f222c4106460d03200241b0056a41086a2004290200370300200241b0056a41106a2002419c0f6a2204290200370300200220032902003703b0052006280200213220022802840f213320022f01820f213420022d00810f2135200241800f6a2001109f0320022d00800f22364106460d06200241a00a6a41086a200241940f6a290200370300200241b00a6a200429020037030020022002418c0f6a2902003703a00a200241800f6a41086a280200213720022802840f213820072802002204450d0720022f01820f213920022d00810f213a200128020022032d0000210620012004417f6a22073602042001200341016a360200200641014b0d0742002118410021244200211920060e020504050b02402005450d00200c200541c8006c6a2104200c21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012004470d000b0b200b450d2f200b41c8006c450d2f200c10230c2f0b024020084101470d002010450d00200f10230b02402005450d00200c200541c8006c6a2104200c21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012004470d000b0b200b450d2e200b41c8006c450d2e200c10230c2e0b024020124101470d002011450d00202310230b024020084101470d002010450d00200f10230b02402005450d00200c200541c8006c6a2104200c21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012004470d000b0b200b450d2d200b41c8006c450d2d200c10230c2d0b024020254101470d00202a450d00202b10230b024020124101470d002011450d00202310230b024020084101470d002010450d00200f10230b02402005450d00200c200541c8006c6a2104200c21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012004470d000b0b200b450d2c200b41c8006c450d2c200c10230c2c0b2007450d0220032d0001210720012004417e6a22063602042001200341026a3602002006450d0220032d0002212420012004417d6a22063602042001200341036a3602002006450d0220032d0003212220012004417c6a22063602042001200341046a3602002006450d0220032d0004212120012004417b6a22063602042001200341056a3602002006450d0220032d0005212020012004417a6a22063602042001200341066a3602002006450d0220032d0006213b2001200441796a22063602042001200341076a3602002006450d0220032d0007213c2001200441786a22063602042001200341086a3602002006450d0220032d000821302001200441776a22063602042001200341096a3602002006450d0220032d0009213d2001200441766a220636020420012003410a6a3602002006450d0220032d000a213e2001200441756a220636020420012003410b6a3602002006450d0220032d000b213f2001200441746a220636020420012003410c6a3602002006450d0220032d000c21312001200441736a220636020420012003410d6a3602002006450d0220032d000d212f2001200441726a220636020420012003410e6a3602002006450d0220032d000e21402001200441716a220636020420012003410f6a3602002006450d0220032d000f21412001200441706a22063602042001200341106a3602002006450d0220032d0010214220012004416f6a22063602042001200341116a3602002006450d0220032d0011214320012004416e6a22063602042001200341126a3602002006450d0220032d0012214420012004416d6a22063602042001200341136a3602002006450d0220032d0013214520012004416c6a22063602042001200341146a3602002006450d022003310014211920012004416b6a3602042001200341156a360200203fad421086203ead42ff018342088684203dad42ff018384210a202fad42ff01834208862031ad42ff0183842040ad42ff0183421086842041ad42ff0183421886842042ad42ff0183422086842043ad42ff0183422886842044ad42ff0183423086842045ad4238868421182030ad423886203cad42ff018342308684203bad42ff0183422886842020ad42ff0183422086842021ad42ff0183421886842022ad42ff0183421086842024ad42ff0183420886842007ad42ff018384211a410121240b200241800f6a2001109f0320022d00800f22224106460d02200241d00c6a41086a2204200241940f6a290200370300200241d00c6a41106a22032002419c0f6a29020037030020022002418c0f6a22062902003703d00c200241800f6a41086a2207280200212120022802840f212020022f01820f213c20022d00810f213b200241800f6a2001109f0320022d00800f4106470d0b024020224101470d002021450d00202010230b024020364101470d002037450d00203810230b0240202c4101470d002032450d00203310230b024020254101470d00202a450d00202b10230b024020124101470d002011450d00202310230b024020084101470d002010450d00200f10230b02402005450d00200c200541c8006c6a2104200c21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012004470d000b0b200b450d2a200b41c8006c450d2a200c10230c2a0b0240202c4101470d002032450d00203310230b024020254101470d00202a450d00202b10230b024020124101470d002011450d00202310230b024020084101470d002010450d00200f10230b02402005450d00200c200541c8006c6a2104200c21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012004470d000b0b200b450d29200b41c8006c450d29200c10230c290b024020364101470d002037450d00203810230b0240202c4101470d002032450d00203310230b024020254101470d00202a450d00202b10230b024020124101470d002011450d00202310230b024020084101470d002010450d00200f10230b02402005450d00200c200541c8006c6a2104200c21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012004470d000b0b200b450d28200b41c8006c450d28200c10230c280b024020364101470d002037450d00203810230b0240202c4101470d002032450d00203310230b024020254101470d00202a450d00202b10230b024020124101470d002011450d00202310230b024020084101470d002010450d00200f10230b02402005450d00200c200541c8006c6a2104200c21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012004470d000b0b200b450d27200b41c8006c450d27200c10230c270b200241d0036a200110880120022802d0030d2620022802d403220b200728020041c4006e22042004200b4b1bad42c4007e220a422088a70d0d200aa72204417f4c0d0d0240024020040d004104210c0c010b20041021220c450d230b4100210620024100360280092002200c3602f8082002200441c4006e3602fc08024002400240200b450d00200241800f6a410172210841002109034041002103200241003a00a00f200941016a21092007280200417f6a210403402004417f460d03200241800f6a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a00f2004417f6a21042005210320054120470d000b20022d009f0f210420022900970f210a20022800930f2103200228008f0f2105200228008b0f211020022800870f211120022800830f210f20022f00810f211220022d00800f2113200241800f6a2001109f0320022d00800f221e4106460d03200241d00c6a411f6a221f2008411f6a280000360000200241d00c6a41186a2223200841186a290000370300200241a00a6a41086a2225200841086a290000370300200241a00a6a41106a2226200841106a290000370300200241a00a6a41186a22272023290300370300200241a00a6a411f6a2223201f280000360000200220082900003703a00a200220033600f308200220053600ef08200220103600eb08200220113600e7082002200f3600e308200220123b00e108200220133a00e008200241b0056a411f6a22032023280000360000200241b0056a41186a22052027290300370300200241b0056a41106a22102026290300370300200241b0056a41086a22112025290300370300200220022903a00a3703b0052004ad210d0240200620022802fc08470d00200241f8086a20064101109b0120022802f808210c20022802800921060b200241e0086a41086a290300210e200241e0086a410f6a290000211420022903e0082115200c200641c4006c6a2204201e3a00202004200a370017200420153702002004411f6a200d3c00002004410f6a2014370000200441086a200e370200200420022903b005370021200441296a2011290300370000200441316a2010290300370000200441396a2005290300370000200441c0006a20032800003600002002200641016a2206360280092009200b470d000b0b200c450d2820022902fc08210a200241c8086a41106a200241b0046a41106a290200370300200241c8086a41086a200241b0046a41086a290200370300200241b0086a41086a200241a8096a41086a290300370300200241b0086a41106a200241a8096a41106a29030037030020024198086a41086a200241880a6a41086a29020037030020024198086a41106a200241880a6a41106a290200370300200220022902b0043703c808200220022903a8093703b008200220022902880a3703980820024180086a41106a20024190096a41106a29030037030020024180086a41086a20024190096a41086a290300370300200220022903900937038008200a422088a72105200aa7210b41032130410021120c270b200341ff0171450d00200241003a00a00f0b200241a00a6a411f6a200241d00c6a411f6a280000360000200241a00a6a41186a200241d00c6a41186a29030037030002402006450d00200641c4006c2104200c41286a210103400240200141786a2d00004101470d002001280200450d002001417c6a28020010230b200141c4006a2101200441bc7f6a22040d000b0b20022802fc082201450d26200141c4006c450d26200c10230c260b200241f0036a200110880120022802f0030d2520022802f403210c200241d8036a200110800220022903d803a70d25200241d8036a41106a290300210a20022903e003210d200241c8086a41106a200241800f6a41106a290200370300200241c8086a41086a200241800f6a41086a290200370300200241b0086a41086a200241d00c6a41086a290300370300200241b0086a41106a200241d00c6a41106a29030037030020024198086a41086a200241a00a6a41086a29020037030020024198086a41106a200241a00a6a41106a290200370300200220022902800f3703c808200220022903d00c3703b008200220022902a00a3703980820024180086a41106a200241b0056a41106a29030037030020024180086a41086a200241b0056a41086a290300370300200220022903b00537038008200d422088a72105200a422088a7210f200a4280feffff0f83420888a72131200da7210b200aa7210841052130410021120c240b202f4104490d242004280002210c20012003417a6a360204410621302001200441066a360200200241c8086a41086a200241800f6a41086a290200370300200241c8086a41106a200241800f6a41106a290200370300200241b0086a41086a200241d00c6a41086a290300370300200241b0086a41106a200241d00c6a41106a29030037030020024198086a41086a200241a00a6a41086a29020037030020024198086a41106a200241a00a6a41106a290200370300200220022902800f3703c808200220022903d00c3703b008200220022902a00a3703980820024180086a41106a200241b0056a41106a29030037030020024180086a41086a200241b0056a41086a290300370300200220022903b00537038008410021054100213141002108410021120c230b20024190046a20011088012002280290040d23200228029404210c200241f8036a200110800220022903f803a70d23200241f8036a41106a290300210a200229038004210d200241c8086a41106a200241800f6a41106a290200370300200241c8086a41086a200241800f6a41086a290200370300200241b0086a41086a200241d00c6a41086a290300370300200241b0086a41106a200241d00c6a41106a29030037030020024198086a41086a200241a00a6a41086a29020037030020024198086a41106a200241a00a6a41106a290200370300200220022902800f3703c808200220022903d00c3703b008200220022902a00a3703980820024180086a41106a200241b0056a41106a29030037030020024180086a41086a200241b0056a41086a290300370300200220022903b00537038008200d422088a72105200a422088a7210f200a4280feffff0f83420888a72131200da7210b200aa7210841072130410021120c220b20024198046a20011088012002280298040d22200228029c04210941002103200241003a00a00f2007280200417f6a2104024003402004417f460d01200241800f6a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a00f2004417f6a21042005210320054120470d000b41082130200241c8086a41086a200241d00c6a41086a290200370300200241c8086a41106a200241d00c6a41106a290200370300200241b0086a41086a200241a00a6a41086a290300370300200241b0086a41106a200241a00a6a41106a290300370300200220022902d00c3703c808200220022903a00a3703b0082002418f0f6a290000210a2002419f0f6a310000210e20022800830f210c20022f00810f211320022d00800f211e20022900870f210d20022900970f211420024198086a41106a200241b0046a41106a29020037030020024198086a41086a200241b0046a41086a290200370300200220022902b0043703980820024180086a41106a200241a8096a41106a29030037030020024180086a41086a200241a8096a41086a290300370300200220022903a809370380082014422088200e42208684210e200d422088a72105200a422088a7210f200a4280feffff0f83420888a721312014a72110200da7210b200aa72108410021120c220b200341ff0171450d22200241003a00a00f0c220b200241a0046a200110880120022802a0040d21200728020022044108490d2120022802a404210c20012802002203290000210a2001200441786a3602042001200341086a360200200a4280025a0d21200241c8086a41106a200241800f6a41106a290200370300200241c8086a41086a200241800f6a41086a290200370300200241b0086a41086a200241d00c6a41086a290300370300200241b0086a41106a200241d00c6a41106a29030037030020024198086a41086a200241a00a6a41086a29020037030020024198086a41106a200241a00a6a41106a290200370300200220022902800f3703c808200220022903d00c3703b008200220022902a00a3703980820024180086a41106a200241b0056a41106a29030037030020024180086a41086a200241b0056a41086a290300370300200220022903b00537038008200a422088a72105200aa7210b41092130410021120c200b200241a8046a200110880120022802a8040d2020022802ac04210941002104200241003a00a00f20072802002106417f21030240024002400240024002400240034020062004460d01200241800f6a20046a200128020022072d00003a00002001200620036a3602042001200741016a3602002002200441016a22053a00a00f2003417f6a21032005210420054120470d000b200241a00a6a411f6a200241800f6a411f6a310000220e3c0000200241a00a6a410f6a200241800f6a410f6a290000220a370000200220022900970f22153700b70a200220022900870f22183700a70a200220022800830f220c3600a30a200220022f00810f22133b00a10a200220022d00800f221e3a00a00a20062005460d2720072d000121042001200620036a22033602042001200741026a360200200441064b0d274200210d410021234100211120040e0725010203040506250b200441ff0171450d26200241003a00a00f0c260b20034110490d252007410a6a290000210d200729000221142001200620056b416f6a3602042001200741126a360200200da72123200d422088a721114201210d0c230b4202210d410021110c220b4203210d410021110c210b4204210d410021110c200b4205210d410021110c1f0b4206210d410021110c1e0b41002105200241003a00a00f2003417e6a21072003417d6a21030240034020072005460d01200241800f6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00a00f2003417f6a21032006210520064120470d000b200241c8086a41086a200241d00c6a41086a290000370300200241c8086a41106a200241d00c6a41106a290000370300200241b0086a41086a200241a00a6a41086a290000370300200241b0086a41106a200241a00a6a41106a290000370300200220022900d00c3703c808200220022900a00a3703b0082002418f0f6a290000210a2002419f0f6a310000210e20022800830f210c20022f00810f211320022d00800f211e20022900870f210d20022900970f211420024198086a41106a200241b0056a41106a29000037030020024198086a41086a200241b0056a41086a290000370300200220022900b0053703980820024180086a41106a200241b0046a41106a29000037030020024180086a41086a200241b0046a41086a290000370300200220022900b004370380082014422088200e42208684210e200d422088a72105200a422088a7210f200a4280feffff0f83420888a721312014a72110200da7210b200aa72108410b2130410021120c1f0b200541ff0171450d1f200241003a00a00f0c1f0b2013201e411074722131200241c8086a41086a200241b0046a41086a290300370300200241c8086a41106a200241b0046a41106a290300370300200241b0086a41086a200241b0056a41086a290300370300200241b0086a41106a200241b0056a41106a290300370300200220022903b0043703c808200220022903b0053703b008200241980f6a290300211c200241800f6a41106a290300211b200241a00f6a280200213d2006280200213e2007280200213f20022903800f211620024198086a41106a200241a00a6a41106a29030037030020024198086a41086a200241a00a6a41086a290300370300200220022903a00a3703980820024180086a41106a200329030037030020024180086a41086a2004290300370300200220022903d00c37038008201d420886201784211d410221300c1d0b200241d00c6a200110a003024020022d00d00c410a460d00200241a00a6a200241d00c6a41c40010a1051a20004112360200200041046a200241a00a6a41c40010a1051a200041c8006a200241800f6a41e80110a1051a0c330b200041163602000c320b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d0041012107024002400240024020050e03020001020b41002105200241003a00f00c2003417e6a21072003417d6a21030240034020072005460d01200241d00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00f00c2003417f6a21032006210520064120470d000b20022d00ef0c210620022900e70c210a20022800e30c210c20022800df0c210b20022800db0c210920022800d70c210820022800d30c211020022f00d10c211120022d00d00c210f410221070c020b200541ff0171450d03200241003a00f00c0c030b41002105200241003a00f00c2003417e6a210c417d21060340200c2005460d02200241d00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00f00c2006417f6a21062007210520074120470d000b200320076b2203417e6a4110490d0220022d00ef0c210620022900e70c210a20022800e30c210c20022800df0c210b20022800db0c210920022800d70c210820022800d30c211020022f00d10c211120022d00d00c210f200420076a2204410a6a290000210e200441026a290000210d20012003416e6a22053602042001200441126a220736020020054110490d022004411a6a29000021152007290000211420012003415e6a22053602042001200441226a220736020020054104490d022007280000211220012003415a6a3602042001200441266a360200410321070b200020113b000a2000200f3a000920004113360200200041c8006a2015370200200041c0006a2014370200200041386a200e370200200041306a200d370200200041d0006a2012360200200041286a20063a0000200041206a200a3700002000411c6a200c360000200041186a200b360000200041146a2009360000200041106a20083600002000410c6a2010360000200041086a20073a0000200041d8006a200241800f6a41d80110a1051a0c330b200541ff0171450d00200241003a00f00c0b200041163602000c310b02402006450d0020012003417e6a3602042001200441026a3602000b200041163602000c300b200041163602000c2f0b200241d00c6a200110a10320022d00d00c4104470d16200041163602000c2e0b1032000b20042003418ca9c0001044000b20042003418ca9c0001044000b20042003418ca9c0001044000b20042003418ca9c0001044000b20032008418ca9c0001044000b20042003418ca9c0001044000b20042003418ca9c0001044000b200c10230c1d0b20042003418ca9c0001044000b20042003418ca9c0001044000b20032005418ca9c0001044000b200410230b200041163602000c200b20042005418ca9c0001044000b20042003418ca9c0001044000b20042008418ca9c0001044000b20042003418ca9c0001044000b20042003418ca9c0001044000b20042003418ca9c0001044000b20122004418ca9c0001044000b1033000b200241a00a6a41206a200241d00c6a41206a290300220a370300200241a00a6a41186a200241d00c6a41186a290300220d370300200241a00a6a41106a200241d00c6a41106a290300220e370300200241a00a6a41086a200241d00c6a41086a2903002214370300200220022903d00c22153703a00a20004115360200200020153702042000410c6a2014370200200041146a200e3702002000411c6a200d370200200041246a200a3702002000412c6a200241800f6a41840210a1051a0c170b200241c8086a41086a200241d00c6a41086a290200370300200241c8086a41106a200241d00c6a41106a290200370300200241b0086a41086a200241b0056a41086a290300370300200241b0086a41106a200241b0056a41106a29030037030020024198086a41086a200241b0046a41086a29020037030020024198086a41106a200241b0046a41106a290200370300200220022902d00c3703c808200220022903b0053703b008200220022902b0043703980820024180086a41106a200241a8096a41106a29030037030020024180086a41086a200241a8096a41086a290300370300200220022903a809370380082015422088200e42ff018342208684210e2014422888211d2014422088a721122018422088a72105200a422088a7210f200a4280feffff0f83420888a721312014a7211f2015a721102018a7210b200aa72108410a21300b200241e8076a41106a2201200241c8086a41106a290300370300200241e8076a41086a2204200241c8086a41086a290300370300200241d0076a41086a2203200241b0086a41086a290300370300200241d0076a41106a2206200241b0086a41106a290300370300200241b8076a41086a220720024198086a41086a290300370300200241b8076a41106a222f20024198086a41106a290300370300200220022903c8083703e807200220022903b0083703d00720022002290398083703b807200241a0076a41106a224020024180086a41106a290300370300200241a0076a41086a224120024180086a41086a29030037030020022002290380083703a007200041d8006a2015370200200041d0006a2014370200200041186a2031410874ad2008ad42ff0183843e0200200041106a2005ad422086200bad84370200200041e8006a202a360200200041e4006a202b3602002000202e3b00622000202d3a0061200041e0006a20253a0000200041cc006a2028360200200020293b014a200020273a0049200041c8006a20263a0000200041c4006a2011360200200041c0006a2023360200200041386a201d4228862012ad42ff018342208684201fad84370200200041306a200d3702002000412c6a2009360200200041246a200e370200200041206a20103602002000411c6a200f3602002000410c6a200c360200200020133b000a2000201e3a0009200041086a20303a00002000411136020020004188016a20333602002000418c016a2032360200200020343b008601200020353a00850120004184016a202c3a0000200041a8016a20363a00002000203a3a00a901200020393b00aa01200041b0016a2037360200200041ac016a2038360200200041fc006a2001290300370200200041f4006a2004290300370200200041ec006a20022903e80737020020004190016a20022903d00737020020004198016a2003290300370200200041a0016a2006290300370200200041cc016a20223a00002000203b3a00cd012000203c3b00ce01200041d4016a2021360200200041d0016a20203602002000419f026a200a4210883c00002000419d026a200a3d0000200041a8026a20193e0000200041a0026a20183700002000201a3700950220004188026a201c37020020004180026a201b37020020004194026a20243a0000200041ac026a410036020020004190026a203d360200200041fc016a203e360200200041f8016a203f360200200041f0016a2016370200200041c4016a202f290300370200200041bc016a2007290300370200200041b4016a20022903b807370200200041d8016a20022903a007370200200041e0016a2041290300370200200041e8016a20402903003702000c150b200041163602000c140b200510230b200041163602000c120b102a000b200041163602000c100b4100210c02402004450d00200610230b41022106410021080b41000d062006450d06200241800f6a200110820202400240024020022802800f450d00200241d00c6a200241800f6a41c00110a1051a200728020022034110490d012001280200220441086a29000021142004290000210e2001200441106a3602002001200341706a220536020420054110490d01200441186a2900002118200429001021152001200341606a22053602042001200441206a36020020054110490d01200441286a290000211a200429002021192001200341506a22053602042001200441306a36020020054104490d022004280030213920012003414c6a3602042001200441346a36020020024190096a41086a2002418c0d6a29020037030020024190096a41106a200241940d6a2902003703002002200241d00c6a41346a29020037039009200241f00c6a290300210d200241d00c6a41106a2d00002111200241e40c6a2802002124200241d00c6a41286a2d0000211e200241fc0c6a280200211f20022903e80c210a20022802d00c210920022802d40c211020022802d80c212220022802dc0c212120022d00e10c211220022f01e20c213a20022d00f90c212e20022f01fa0c213220022802800d2123200241f8086a41086a200241b00d6a290300370300200241f8086a41106a200241b80d6a290300370300200241c8086a41086a200241d40d6a290200370300200241c8086a41106a200241dc0d6a2902003703002002200241a80d6a2903003703f8082002200241cc0d6a2902003703c808200241a00d6a28020021262002419c0d6a2d00002125200241c40d6a2802002129200241c00d6a2d0000212820022802a40d212720022f019e0d213620022d009d0d213320022802c80d212a20022f01c20d213420022d00c10d2135200241b0086a41106a200241800e6a290300370300200241b0086a41086a200241f80d6a2903003703002002200241f00d6a2903003703b008200241e80d6a280200212c200241e40d6a2d0000212b200241880e6a290300211b20022802ec0d212d20022f01e60d213820022d00e50d2137411821130c0b0b200c0d040c080b200241d00c6a108302200c41808080807872418080808078470d030c070b200241d00c6a108302200c450d060c020b4100210c02402004450d00200610230b41022106410021080b41000d042006450d04200241800f6a200110820202400240024020022802800f450d00200241d00c6a200241800f6a41c00110a1051a200728020022034110490d012001280200220441086a29000021142004290000210e2001200441106a3602002001200341706a220536020420054110490d01200441186a2900002118200429001021152001200341606a22053602042001200441206a36020020054110490d01200441286a290000211a200429002021192001200341506a22053602042001200441306a36020020054104490d022004280030213920012003414c6a3602042001200441346a36020020024190096a41086a2002418c0d6a29020037030020024190096a41106a200241940d6a2902003703002002200241d00c6a41346a29020037039009200241f00c6a290300210d200241d00c6a41106a2d00002111200241e40c6a2802002124200241d00c6a41286a2d0000211e200241fc0c6a280200211f20022903e80c210a20022802d00c210920022802d40c211020022802d80c212220022802dc0c212120022d00e10c211220022f01e20c213a20022d00f90c212e20022f01fa0c213220022802800d2123200241f8086a41086a200241b00d6a290300370300200241f8086a41106a200241b80d6a290300370300200241c8086a41086a200241d40d6a290200370300200241c8086a41106a200241dc0d6a2902003703002002200241a80d6a2903003703f8082002200241cc0d6a2902003703c808200241a00d6a28020021262002419c0d6a2d00002125200241c40d6a2802002129200241c00d6a2d0000212820022802a40d212720022f019e0d213620022d009d0d213320022802c80d212a20022f01c20d213420022d00c10d2135200241b0086a41106a200241800e6a290300370300200241b0086a41086a200241f80d6a2903003703002002200241f00d6a2903003703b008200241e80d6a280200212c200241e40d6a2d0000212b200241880e6a290300211b20022802ec0d212d20022f01e60d213820022d00e50d2137411721130c090b200c0d020c060b200241d00c6a108302200c41808080807872418080808078470d010c050b200241d00c6a108302200c450d040b200610230c030b0c040b4100210802402001450d00200c10230b4104210c410021090b41000d00200c450d004110211320024190096a41106a200241800f6a41106a29020037030020024190096a41086a200241800f6a41086a290200370300200241f8086a41086a200241d00c6a41086a290200370300200241f8086a41106a200241d00c6a41106a290200370300200241c8086a41086a200241a00a6a41086a290200370300200241c8086a41106a200241a00a6a41106a290200370300200220022902800f37039009200220022902d00c3703f808200220022902a00a3703c808200241b0086a41106a200241b0046a41106a290200370300200241b0086a41086a200241b0046a41086a290200370300200220022902b0043703b0080c020b200041163602000c070b4100211041002109410021080b20024198086a41106a220120024190096a41106a29030037030020024198086a41086a220420024190096a41086a29030037030020024180086a41086a2203200241f8086a41086a29030037030020024180086a41106a2205200241f8086a41106a290300370300200241e8076a41086a2207200241c8086a41086a290300370300200241e8076a41106a2220200241c8086a41106a290300370300200220022903900937039808200220022903f80837038008200220022903c8083703e807200241d0076a41106a223b200241b0086a41106a290300370300200241d0076a41086a223c200241b0086a41086a290300370300200220022903b0083703d007200041386a200d370200200041306a200a370200200041186a2010ad4220862009ad84370200200041106a2008ad422086200cad84370200200041c8006a2023360200200041c4006a201f360200200020323b00422000202e3a0041200041c0006a201e3a00002000412c6a20243602002000203a3b012a200020123a0029200041286a20113a0000200041246a2021360200200041206a20223602002000410c6a20063602002000200f3b010a2000200b3a0009200041086a20133a000020004106360200200041e8006a2026360200200041ec006a2027360200200020363b0066200020333a0065200041e4006a20253a0000200041cc006a200229039808370200200041d4006a2004290300370200200041dc006a20012903003702002000418c016a202936020020004190016a202a360200200020343b008a01200020353a00890120004188016a20283a0000200041f0006a200229038008370200200041f8006a200329030037020020004180016a2005290300370200200041a4016a20202903003702002000419c016a200729030037020020004194016a20022903e807370200200041b4016a202d360200200041b0016a202c360200200020383b00ae01200020373a00ad01200041ac016a202b3a0000200041c8016a203b290300370200200041c0016a203c290300370200200041b8016a20022903d00737020020004188026a201a37020020004180026a2019370200200041f8016a2018370200200041f0016a2015370200200041e8016a2014370200200041e0016a200e370200200041d8016a2039360200200041d0016a201b370200200041a8026a200241b0056a41186a290300370300200041a0026a200241b0056a41106a29030037030020004198026a200241b0056a41086a29030037030020004190026a20022903b0053703000c050b42002118420021194200211a4200211b4200211c4200211d420021170b200020053b002a200020033a0029200020123b000a200020133a000920004104360200200041c0006a201d200d84370200200041386a200e370200200041306a20143702002000412c6a2004360000200041286a200b3a0000200041206a200a3700002000411c6a2009360000200041186a2008360000200041146a2010360000200041106a20113600002000410c6a200f360000200041086a20013a0000200041d0006a201b201984201584370200200041d8006a201c201a84201884370200200041c8006a2017201642ffffffffffffffff008384370200200041e0006a200241800f6a41d00110a1051a0c030b200041163602000c020b200610230b200041163602000b200241b0116a24000b990403037f017e047f230041206b22022400200241086a2001108801024002400240024002402002280208450d00200041003602000c010b200228020c22032001280204410c6e2204200420034b1bad420c7e2205422088a70d012005a72204417f4c0d010240024020040d00410421060c010b200410212206450d030b41002107200241003602182002200636021020022004410c6e3602140240024002402003450d0003402002200110880120022802000d03200128020420022802042204490d032004417f4c0d050240024020040d00410121080c010b200410272208450d0720012802042004490d0320082001280200200410a1051a200128020422092004490d082001200920046b3602042001200128020020046a3602000b2004ad22054220862005842105024020072002280214470d00200241106a2007410110950120022802102106200228021821070b20062007410c6c6a22042005370204200420083602002002200741016a22073602182003417f6a22030d000b0b20002002290310370200200041086a200241106a41086a2802003602000c020b200810230b2000410036020002402007450d002007410c6c21012006210403400240200441046a280200450d00200428020010230b2004410c6a2104200141746a22010d000b0b20022802142204450d002004410c6c450d00200610230b200241206a24000f0b1032000b1033000b20042009418ca9c0001044000ba00a03077f037e057f230041d0026b2202240041002103200241003a00c8022001280204417f6a210402400240024002400240024003402004417f460d01200241a8026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8022004417f6a21042005210320054120470d000b200241e8006a41086a200241a8026a41086a290300370300200241e8006a41106a200241a8026a41106a290300370300200241e8006a41186a200241a8026a41186a290300370300200220022903a8023703682002200110880120022802000d022002280204210641002104200241003a00c80220012802042107417f2103034020072004460d02200241a8026a20046a200128020022082d00003a00002001200720036a3602042001200841016a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241a8016a41086a200241a8026a41086a2903002209370300200241a8016a41106a200241a8026a41106a290300220a370300200241a8016a41186a200241a8026a41186a290300220b37030020024188016a41086a200937030020024188016a41106a200a37030020024188016a41186a200b370300200220022903a80222093703a801200220093703880141002104200241003a00c802200720056b210c200720036a21030340200c2004460d04200241a8026a20046a200820046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241e8016a41086a200241a8026a41086a2903002209370300200241e8016a41106a200241a8026a41106a290300220a370300200241e8016a41186a200241a8026a41186a290300220b370300200241c8016a41086a22042009370300200241c8016a41106a2203200a370300200241c8016a41186a2205200b370300200220022903a80222093703e801200220093703c801200241a8026a200110b00420022802a8022201450d04200241c8006a41086a2208200241e8006a41086a290300370300200241c8006a41106a2207200241e8006a41106a290300370300200241c8006a41186a220c200241e8006a41186a290300370300200241286a41086a220d20024188016a41086a290300370300200241286a41106a220e20024188016a41106a290300370300200241286a41186a220f20024188016a41186a29030037030020022002290368370348200220022903880137032820022902ac022109200241086a41186a22102005290300370300200241086a41106a22052003290300370300200241086a41086a22032004290300370300200220022903c801370308200020093702082000200136020420002006360200200041106a2002290348370200200041186a2008290300370200200041206a2007290300370200200041286a200c290300370200200041306a2002290328370200200041386a200d290300370200200041c0006a200e290300370200200041c8006a200f290300370200200041e8006a2010290300370200200041e0006a2005290300370200200041d8006a2003290300370200200041d0006a20022903083702000c050b0240200341ff0171450d00200241003a00c8020b200041003602040c040b0240200441ff0171450d00200241003a00c8020b200041003602040c030b200041003602040c020b0240200441ff0171450d00200241003a00c8020b200041003602040c010b200041003602040b200241d0026a24000bba3308037f017e217f027e1b7f067e0d7f027e230041e0076b22022400200241186a200110880102400240024002402002280218450d00200041003602000c010b200228021c220320012802044188026e2204200420034b1bad4288027e2205422088a70d022005a72204417f4c0d020240024020040d00410821060c010b200410212206450d020b2002410036022820022006360220200220044188026e360224024002402003450d004100210741002108034002400240200128020422094104490d002001280200220a280000210b20012009417c6a220c3602042001200a41046a36020041002104200241003a00b8072009417b6a21090240024002400240024002400240024002400240024002400240024002400240024002400340200c2004460d0120024198076a20046a200a20046a220d41046a2d00003a0000200120093602042001200d41056a3602002002200441016a220d3a00b8072009417f6a2109200d2104200d4120470d000b20024198056a41186a220e20024198076a41186a220f29030037030020024198056a41106a221020024198076a41106a221129030037030020024198056a41086a221220024198076a41086a2213290300370300200220022903980737039805200241106a200110880120022802100d12200128020420022802142209490d122009417f4c0d1920090d01410121140c020b200441ff0171450d11200241003a00b8070c110b200910272214450d1620012802042009490d0120142001280200200910a1051a200128020422042009490d072001200420096b3602042001200128020020096a3602000b2014450d0f41002104200241003a00b8072009ad22054220862005842205422088a721152005a721162001280204210c417f210902400340200c2004460d0120024198076a20046a2001280200220a2d00003a00002001200c20096a3602042001200a41016a3602002002200441016a220d3a00b8072009417f6a2109200d2104200d4120470d000b200241d8056a41186a2217200f290300370300200241d8056a41106a22182011290300370300200241d8056a41086a2219201329030037030020022002290398073703d80541002104200241003a00d807200d200c6b211a200c200d6b21090340201a20046a450d0320024198076a20046a200a20046a220d41016a2d00003a000020012009417f6a22093602042001200d41026a3602002002200441016a220d3a00d807200d2104200d41c000470d000b200241d8066a41386a221b20024198076a41386a221c290300370300200241d8066a41306a221d20024198076a41306a221e290300370300200241d8066a41286a221f20024198076a41286a2220290300370300200241d8066a41206a220c20024198076a41206a2221290300370300200241d8066a41186a221a200f290300370300200241d8066a41106a22222011290300370300200241d8066a41086a2223201329030037030020022002290398073703d80641002104200241003a00b807200a200d6a210a03402009450d0420024198076a20046a200a20046a220d41016a2d00003a000020012009417f6a22093602042001200d41026a3602002002200441016a220d3a00b807200d2104200d4120470d000b20024198066a41186a2224200f29030037030020024198066a41106a2225201129030037030020024198066a41086a2226201329030037030020022002290398073703980620094110490d05200a200d6a220441096a2900002127200441016a29000021282001200941706a3602042001200441116a36020020024198076a200110cb032002280298072209450d05200229029c0721054100210d200241003a00b8072001280204417f6a210403402004417f460d0520024198076a200d6a2001280200220a2d00003a0000200120043602042001200a41016a3602002002200d41016a220a3a00b8072004417f6a2104200a210d200a4120470d000b200241e0046a41186a2229200f290300370300200241e0046a41106a222a2011290300370300200241e0046a41086a222b2013290300370300200241c0046a41086a222c2012290300370300200241c0046a41106a222d2010290300370300200241c0046a41186a222e200e29030037030020022002290398073703e00420022002290398053703c004200241a0046a41186a222f2017290300370300200241a0046a41106a22302018290300370300200241a0046a41086a22312019290300370300200220022903d8053703a004200241e0036a41386a2232201b290300370300200241e0036a41306a2233201d290300370300200241e0036a41286a2234201f290300370300200241e0036a41206a2235200c290300370300200241e0036a41186a2236201a290300370300200241e0036a41106a22372022290300370300200241e0036a41086a22382023290300370300200220022903d8063703e003200241c0036a41186a22392024290300370300200241c0036a41106a223a2025290300370300200241c0036a41086a223b202629030037030020022002290398063703c003200241086a20011088012005422088a7213c2005a7213d2002280208450d060c0e0b0240200441ff0171450d00200241003a00b8070b2016450d0f0b201410230c0e0b0240200441ff0171450d00200241003a00d8070b2016450d0d201410230c0d0b0240200441ff0171450d00200241003a00b8070b2016450d0c201410230c0c0b0240200d41ff0171450d00200241003a00b8070b02402005422088a72204450d002004410474210d2009210403400240200441046a280200450d00200428020010230b200441106a2104200d41706a220d0d000b0b200542ffffffff0083500d00200910230b2016450d0a201410230c0a0b200228020c223e200128020441c1006e22042004203e4b1bad42c1007e2205422088a70d102005a72204417f4c0d100240024020040d004101213f0c010b20041021223f450d100b4100214020024100360290052002203f360288052002200441c1006e220436028c05024002400240024002400240024002400240203e450d00410021404100214103402001280204220d450d04200128020022422d000021042001200d417f6a22433602042001204241016a3602002004417f6a220441014b0d0402400240024020040e020001000b41002104200241003a00d807200d417e6a210d0240034020432004460d0120024198076a20046a204220046a220a41016a2d00003a00002001200d3602042001200a41026a3602002002200441016a220a3a00d807200d417f6a210d200a2104200a41c000470d000b201b201c2903002205370300201d201e2903002244370300201f20202903002245370300200c20212903002246370300201a200f290300224737030020262013290300370300202520112903003703002024204737030020024198066a41206a204637030020024198066a41286a204537030020024198066a41306a204437030020024198066a41386a20053703002002200229039807370398064100210d0c020b200441ff01710d050c060b41002104200241003a00d807200d417e6a210d034020432004460d0420024198076a20046a204220046a220a41016a2d00003a00002001200d3602042001200a41026a3602002002200441016a220a3a00d807200d417f6a210d200a2104200a41c000470d000b201b201c2903002205370300201d201e2903002244370300201f20202903002245370300200c20212903002246370300201a200f290300224737030020262013290300370300202520112903003703002024204737030020024198066a41206a204637030020024198066a41286a204537030020024198066a41306a204437030020024198066a41386a20053703002002200229039807370398064101210d0b204141016a2141200241d8056a41386a20024198066a41386a2903002205370300200241d8056a41306a20024198066a41306a2903002244370300200241d8056a41286a20024198066a41286a2903002245370300200241d8056a41206a20024198066a41206a29030022463703002017202429030022473703002018202529030022483703002019202629030022493703002012204937030020102048370300200e204737030020024198056a41206a220a204637030020024198056a41286a2242204537030020024198056a41306a2243204437030020024198056a41386a224a2005370300200220022903980622053703d805200220053703980502402040200228028c05470d0020024188056a20404101109d01200228028805213f20022802900521400b203f204041c1006c6a2204200d3a00002004200229039805370001200441096a2012290300370000200441116a2010290300370000200441196a200e290300370000200441216a200a290300370000200441296a2042290300370000200441316a2043290300370000200441396a204a2903003700002002204041016a2240360290052041203e470d000b200228028c0521040b203f450d0f2002200110880120022802000d072002280204220a41076a221b410376220d450d04200d1027221d450d172001280204200d490d06201d2001280200200d10a10521432001280204221f200d4f0d03200d201f418ca9c0001044000b200441ff0171450d010b200241003a00d8070b200228028c052204450d0c200441c1006c450d0c203f10230c0c0b2001201f200d6b36020420012001280200200d6a360200200d1021221f450d13200d2142204321430c010b419ca8c700211d4101211f41002142410121430b201f201d200d10a105211d2002200d3602dc07201b4188808080024f0d032002201b417871223e36028805201b41ffffffff014b0d0402400240200d0d004100211f0c010b4101211f200d4101460d00203e41786a41037641016a211f0b2002201f360298052002201d201f6a221f3602d805201f201d490d05201b41f8ffffff0171221b200a490d082002200a3602d805200a41ffffffff014b0d0620022042410374221f36029806201f200a490d07201d4101201b1b211b0240200d450d00204310230b201b450d01200a410374214b200c200241e0046a41206a280200360200201a20292903003703002022202a2903003703002023202b2903003703002026202c2903003703002025202d2903003703002024202e290300370300200220022903e0043703d806200220022903c004370398062017202f2903003703002018203029030037030020192031290300370300201c2032290300370300201e20332903003703002020203429030037030020212035290300370300200f20362903003703002011203729030037030020132038290300370300200220022903a0043703d805200220022903e00337039807200e20392903003703002010203a2903003703002012203b290300370300200220022903c00337039805201b214c2042214d2040214e2004214f203f2150201521512016215220142153200b2154203c2155203d215620282157202721580c0c0b201d10230b02402004450d00200441c1006c450d00203f10230b02402016450d00201410230b0240203c450d00203c410474210d2009210403400240200441046a280200450d00200428020010230b200441106a2104200d41706a220d0d000b0b203d41ffffffff0071450d090c080b20092004418ca9c0001044000b200241e4066a4101360200200241ac076a41023602002002420237029c07200241e0e9c20036029807200241dce9c2003602e006200241013602dc062002200241d8066a3602a8072002200241dc076a3602d80620024198076a419ca8c700103a000b200241e4066a4101360200200241ac076a41023602002002420237029c07200241ccc7c40036029807200241c8c7c4003602e006200241013602dc062002200241d8066a3602a807200220024188056a3602d80620024198076a419ca8c700103a000b20024198076a41146a411336020020024198076a410c6a4114360200200241d8066a41146a4103360200200241d8066a410c6a4103360200200241f4c7c4003602e006200241033602dc06200241dcc7c4003602d8062002411336029c072002201d36029806200220024198076a3602e8062002200241d8056a3602a807200220024198056a3602a007200220024198066a36029807200241d8066a419ca8c700103a000b200241e4066a4101360200200241ac076a41023602002002420237029c07200241f0e9c20036029807200241c8c7c4003602e006200241013602dc062002200241d8066a3602a8072002200241d8056a3602d80620024198076a419ca8c700103a000b200241e4066a4101360200200241ac076a41023602002002420237029c0720024180eac20036029807200241013602dc062002200241d8066a3602a807200220024198066a3602e0062002200241d8056a3602d80620024198076a419ca8c700103a000b4190eac2004126418c94c700102d000b02402016450d00201410230b0240203c450d00203c410474210d2009210403400240200441046a280200450d00200428020010230b200441106a2104200d41706a220d0d000b0b203d41ffffffff0071450d010b200910230b410021090b20024198036a41206a2204200241d8066a41206a28020036020020024198036a41186a220d200241d8066a41186a29030037030020024198036a41106a220a200241d8066a41106a29030037030020024198036a41086a220c200241d8066a41086a290300370300200241f8026a41086a220b20024198066a41086a290300370300200241f8026a41106a220f20024198066a41106a290300370300200241f8026a41186a221120024198066a41186a290300370300200220022903d8063703980320022002290398063703f802200241d8026a41186a2213200241d8056a41186a290300370300200241d8026a41106a220e200241d8056a41106a290300370300200241d8026a41086a2210200241d8056a41086a29030037030020024198026a41086a221220024198076a41086a29030037030020024198026a41106a221a20024198076a41106a29030037030020024198026a41186a221420024198076a41186a29030037030020024198026a41206a221620024198076a41206a29030037030020024198026a41286a221520024198076a41286a29030037030020024198026a41306a221720024198076a41306a29030037030020024198026a41386a221820024198076a41386a290300370300200220022903d8053703d802200220022903980737039802200241f8016a41186a221920024198056a41186a290300370300200241f8016a41106a221b20024198056a41106a290300370300200241f8016a41086a221d20024198056a41086a29030037030020022002290398053703f8012009450d02200841016a2108200241d0016a41206a221f2004280200360200200241d0016a41186a2222200d290300370300200241d0016a41106a220d200a290300370300200241d0016a41086a220a200c290300370300200241b0016a41086a220c200b290300370300200241b0016a41106a220b200f290300370300200241b0016a41186a220f201129030037030020022002290398033703d001200220022903f8023703b00120024190016a41186a2211201329030037030020024190016a41106a2213200e29030037030020024190016a41086a220e2010290300370300200241d0006a41086a22102012290300370300200241d0006a41106a2212201a290300370300200241d0006a41186a221a2014290300370300200241d0006a41206a22142016290300370300200241d0006a41286a22162015290300370300200241d0006a41306a22152017290300370300200241d0006a41386a22172018290300370300200220022903d802370390012002200229039802370350200241306a41186a22182019290300370300200241306a41106a2219201b290300370300200241306a41086a221b201d290300370300200220022903f801370330024020072002280224470d00200241206a2007410110990120022802202106200228022821070b200620074188026c6a220420583703082004205737030020042009360210200441186a2055360200200441146a2056360200200a2903002105200d290300212720222903002128201f280200210920022903d0012144200441cc006a2051360200200441c8006a2052360200200441c4006a2053360200200441c0006a20543602002004413c6a2009360200200441346a20283702002004412c6a2027370200200441246a20053702002004411c6a2044370200200441e8006a200f290300370200200441e0006a200b290300370200200441d8006a200c290300370200200441d0006a20022903b00137020020044188016a201129030037020020044180016a2013290300370200200441f8006a200e290300370200200441f0006a200229039001370200200441a8016a201a290300370200200441a0016a201229030037020020044198016a201029030037020020044190016a2002290350370200200441c0016a2015290300370200200441b8016a2016290300370200200441b0016a2014290300370200200441c8016a2017290300370200200441e8016a2018290300370200200441e0016a2019290300370200200441d8016a201b290300370200200441d0016a200229033037020020044184026a204d36020020044180026a204b360200200441fc016a204c360200200441f8016a204e360200200441f4016a204f360200200441f0016a20503602002002200741016a220736022820082003470d000b0b20002002290320370200200041086a200241206a41086a2802003602000c010b2000410036020002402007450d0020074188026c2109200621040340200410a20320044188026a2104200941f87d6a22090d000b0b20022802242204450d0020044188026c450d00200610230b200241e0076a24000f0b1033000b1032000bd10b010b7f230041d0016b2202240002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a3602002005417f6a220541024b0d000240024002400240024020050e03000102000b41002105200241003a00a8012003417f6a2106417e21070240034020062005460d0120024188016a20056a200420056a220841016a2d00003a00002001200320076a3602042001200841026a3602002002200541016a22083a00a8012007417f6a21072008210520084120470d000b200241c8006a41186a20024188016a41186a290300370300200241c8006a41106a20024188016a41106a290300370300200241c8006a41086a20024188016a41086a29030037030020022002290388013703482008417f7320036a2107200420086a41016a210841002106200241c8006a21050c030b200541ff0171450d04200241003a00a8010c040b41002105200241003a00a8012003417f6a2106417e21070240034020062005460d0120024188016a20056a200420056a220841016a2d00003a00002001200320076a3602042001200841026a3602002002200541016a22083a00a8012007417f6a21072008210520084120470d000b200241c8006a41186a20024188016a41186a290300370300200241c8006a41106a20024188016a41106a290300370300200241c8006a41086a20024188016a41086a29030037030020022002290388013703482008417f7320036a210741012106200420086a41016a2108200241c8006a21050c020b200541ff0171450d03200241003a00a8010c030b41002105200241003a00a8012003417f6a2106417e2107034020062005460d0220024188016a20056a200420056a220841016a2d00003a00002001200320076a3602042001200841026a3602002002200541016a22083a00a8012007417f6a21072008210520084120470d000b200241c8006a41186a20024188016a41186a290300370300200241c8006a41106a20024188016a41106a290300370300200241c8006a41086a20024188016a41086a29030037030020022002290388013703482008417f7320036a2107200420086a41016a210841022106200241c8006a21050b200241286a41186a200541186a290000370300200241286a41106a200541106a290000370300200241286a41086a200541086a2900003703002002200529000037032841002105200241003a00c8012007417f6a2103034020072005460d0320024188016a20056a200820056a22042d00003a0000200120033602042001200441016a3602002002200541016a22043a00c8012003417f6a210320042105200441c000470d000b200241c8006a41386a220120024188016a41386a290300370300200241c8006a41306a220520024188016a41306a290300370300200241c8006a41286a220320024188016a41286a290300370300200241c8006a41206a220420024188016a41206a290300370300200241c8006a41186a220720024188016a41186a290300370300200241c8006a41106a220820024188016a41106a290300370300200241c8006a41086a220920024188016a41086a290300370300200241086a41086a220a200241286a41086a290300370300200241086a41106a220b200241286a41106a290300370300200241086a41186a220c200241286a41186a290300370300200220022903880137034820022002290328370308200020063a000020002002290308370001200041096a200a290300370000200041116a200b290300370000200041196a200c290300370000200041216a2002290348370000200041296a2009290300370000200041316a2008290300370000200041396a2007290300370000200041c1006a2004290300370000200041c9006a2003290300370000200041d1006a2005290300370000200041d9006a20012903003700000c030b200541ff0171450d00200241003a00a8010b200041033a00000c010b0240200541ff0171450d00200241003a00c8010b200041033a00000b200241d0016a24000b9b1201037f024002402000280200220141144b0d000240024002400240024002400240024002400240024020010e15000c0c0c0c01020c030c04050c060c0708090a0c0c000b200041086a280200417e6a220141074b0d0b02400240024002400240024020010e080011010211030405000b200041106a280200450d102000410c6a28020010230f0b200041106a280200450d0f2000410c6a28020010230f0b200041106a280200450d0e2000410c6a28020010230f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010230b0240200141106a280200450d002001410c6a28020010230b200141186a2101200241686a22020d000b0b200041106a2802002201450d0d200141186c450d0d200028020c10230f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d0c2001410c6c450d0c200028020c10230f0b200041106a280200450d0b2000410c6a28020010230f0b02402000410c6a2802002201450d00200141f0006c2102200028020441046a2101034020011096030240200141046a2802002203450d00200341246c450d00200128020010230b200141f0006a2101200241907f6a22020d000b0b200041086a2802002201450d0a200141f0006c450d0a200028020410230f0b0240200041086a2d0000220141174b0d000240024002400240024020010e180f0f0f0f0f0f000f0f0f0f0f0f010f0f02030f0f0f0f0f040f0b200041106a28020041ffffff3f71450d0e2000410c6a28020010230f0b200041106a28020041ffffff3f71450d0d2000410c6a28020010230f0b200041146a28020041ffffffff0371450d0c200041106a28020010230f0b200041146a2802002201450d0b200141246c450d0b200041106a28020010230f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010230b200041186a1083020f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010230b200041186a1083020f0b20002802042201450d08200041086a280200450d08200110230f0b200041086a280200450d07200028020410230f0b02402000410c6a280200450d00200041086a28020010230b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b200041186a2802002201450d062001410c6c450d06200028021410230f0b02402000280204220141014b0d00024020010e020700070b0240200041106a2802002202450d00200041086a280200210120024188026c21020340200110a20320014188026a2101200241f87d6a22020d000b0b2000410c6a2802002201450d0620014188026c450d06200028020810230f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010230b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d052001410c6c450d05200028020c10230f0b20002d0004417f6a220141034b0d040240024020010e0400060601000b0240200041106a280200450d002000410c6a28020010230b2000411c6a280200450d05200041186a28020010230f0b02402000410c6a280200450d00200041086a28020010230b200041186a280200450d04200041146a28020010230f0b024020002d0004220141044b0d00024002400240024020010e050800010203080b0240200041106a2802002202450d00200041086a2802002101200241b0026c210203402001109e03200141b0026a2101200241d07d6a22020d000b0b2000410c6a2802002201450d07200141b0026c450d07200028020810230f0b200041086a2201280200109e03200128020010230f0b02402000410c6a28020041ffffff3f71450d00200041086a28020010230b200041206a2201280200109e03200128020010230f0b2000412c6a28020041ffffff3f71450d04200041286a28020010230f0b2000412c6a28020041ffffff3f71450d03200041286a28020010230f0b200041086a2d0000417e6a220141014b0d020240024020010e020001000b0240200041146a2802002202450d002000410c6a2802002201200241c8006c6a21020340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012002470d000b0b0240200041106a2802002201450d00200141c8006c450d00200028020c10230b0240200041186a2d00004101470d00200041206a280200450d002000411c6a28020010230b02402000413c6a2d00004101470d00200041c4006a280200450d00200041c0006a28020010230b0240200041e0006a2d00004101470d00200041e8006a280200450d00200041e4006a28020010230b024020004184016a2d00004101470d002000418c016a280200450d0020004188016a28020010230b0240200041a8016a2d00004101470d00200041b0016a280200450d00200041ac016a28020010230b0240200041cc016a2d00004101470d00200041d4016a280200450d00200041d0016a28020010230b200041f0016a2d00004101470d03200041f8016a280200450d03200041f4016a28020010230f0b0240200041146a2802002201450d00200141c4006c21022000410c6a28020041286a210103400240200141786a2d00004101470d002001280200450d002001417c6a28020010230b200141c4006a2101200241bc7f6a22020d000b0b200041106a2802002201450d02200141c4006c450d02200028020c10230f0b20002d0004417f6a220141024b0d010240024020010e03000301000b200041286a2201280200109e03200128020010230f0b2000410c6a28020041ffffff3f71450d01200041086a28020010230c010b024020002d0004220141024b0d00024020010e03020002020b200041086a2201280200109e03200128020010230f0b200041286a2201280200109e03200128020010230f0b0b8611010a7f23004180016b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a2207360200200541254b0d014100210820050e261301010101010101010101010101010101010101010101010101010101010101010102030405130b200041063a00000c130b02402005417f6a41ff01714121490d00200041063a00000c130b02402005417f6a22090d0020012006360204200120073602004101210a410021094100210b410121080c120b0240024020091027220a450d0020012802042009490d01200a2001280200200910a1051a200128020422052009490d062001200520096b3602042001200128020020096a360200410121082009210b0c130b1033000b200041063a0000200a10230c120b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c100b41012101200541ff01710d040c0e0b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c0d0b41012101200541ff01710d040c0b0b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c0a0b41012101200541ff01710d040c080b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c070b41012101200541ff01710d040c050b20092005418ca9c0001044000b200241003a00780c090b200241003a00780c060b200241003a00780c030b200241003a00780b0b2002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b012420022002290328370310410521080c070b200041063a00000c070b0b2002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b012420022002290328370310410421080c050b200041063a00000c050b0b2002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b012420022002290328370310410321080c030b200041063a00000c030b0b410221082002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b0124200220022903283703100c010b200041063a00000c010b200020083a0000200020022f01243b00012000410c6a2009360000200041086a200b360000200041046a200a360000200041106a2002290310370000200041216a20022f000d3b0000200041036a200241246a41026a2d00003a0000200041186a200241106a41086a290300370000200041206a200241106a41106a2d00003a0000200041236a2002410d6a41026a2d00003a00000b20024180016a24000bbc1e03077f047e017f230041e0056b2202240002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541084b0d0a20050e09010203040506070809010b2000410a3a00000c0a0b41002105200241003a00d0032003417f6a21062003417e6a2107024002400240034020062005460d01200241b0036a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00d0032007417f6a21072008210520084120470d000b200241c0006a41086a200241b0036a41086a290300370300200241c0006a41106a200241b0036a41106a290300370300200241c0006a41186a200241b0036a41186a290300370300200220022903b003370340200241b0036a200110990320022802b003210120024180016a200241b0036a41047241ac0210a1051a20014116460d01200241b0036a20024180016a41ac0210a1051a41b002102122040d02102a000b200541ff0171450d00200241003a00d0030b2000410a3a00000c0a0b20042001360200200441046a200241b0036a41ac0210a1051a200241206a41186a200241c0006a41186a2903002209370300200241206a41106a200241c0006a41106a290300220a370300200241206a41086a200241c0006a41086a290300220b37030020022002290340220c370320200041013a00002000200c370001200041096a200b370000200041116a200a370000200041196a2009370000200041216a20022f001d3b0000200041236a2002411f6a2d00003a0000200041246a2004360200200041286a2002290200370200200041306a200241086a290200370200200041386a200241106a290200370200200041c0006a200241186a2802003602000c090b41002105200241003a00d003410120036b21062003417e6a21070240024002400340200620056a450d01200241b0036a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00d0032007417f6a21072008210520084120470d000b20024180016a41086a200241b0036a41086a29030037030020024180016a41106a200241b0036a41106a29030037030020024180016a41186a200241b0036a41186a290300370300200220022903b0033703800141002105200241003a00d003200420086a2106200820036b41016a21080340200820056a450d02200241b0036a20056a200620056a220441016a2d00003a0000200120073602042001200441026a3602002002200541016a22043a00d0032007417f6a21072004210520044120470d000b200241206a41086a2201200241b0036a41086a290300370300200241206a41106a2204200241b0036a41106a290300370300200241206a41186a2205200241b0036a41186a290300370300200241c0006a41086a220720024180016a41086a290300370300200241c0006a41106a220820024180016a41106a290300370300200241c0006a41186a220320024180016a41186a290300370300200220022903b0033703202002200229038001370340200041023a000020002002290340370001200041096a2007290300370000200041116a2008290300370000200041196a2003290300370000200041216a2002290320370000200041296a2001290300370000200041316a2004290300370000200041396a2005290300370000200041c1006a20022f00003b0000200041c3006a200241026a2d00003a00000c0b0b200541ff0171450d01200241003a00d0030c010b200541ff0171450d00200241003a00d0030b2000410a3a00000c080b20024180016a200110cf010240024002402002280280012204450d002002280284012105200128020422074102490d0120024188016a2802002106200128020022082f0000210d20012007417e6a22033602042001200841026a36020020034104490d022008280002210320012007417a6a3602042001200841066a360200200041106a20033602002000410c6a2006360200200041086a2005360200200041046a2004360200200041026a200d3b0100200041033a0000200041146a20022902b0033702002000411c6a200241b0036a41086a290200370200200041246a200241b0036a41106a2902003702002000412c6a200241c8036a290200370200200041346a200241d0036a2902003702002000413c6a200241d8036a2902003702000c0a0b2000410a3a00000c090b2000410a3a0000200541ffffff3f71450d08200410230c080b2000410a3a0000200541ffffff3f71450d07200410230c070b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041043a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c070b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c060b41002105200241003a00d003410120036b21062003417e6a21070240024002400340200620056a450d01200241b0036a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00d0032007417f6a21072008210520084120470d000b20024180016a41086a200241b0036a41086a29030037030020024180016a41106a200241b0036a41106a29030037030020024180016a41186a200241b0036a41186a290300370300200220022903b0033703800141002105200241003a00d003200420086a2106200820036b41016a21080340200820056a450d02200241b0036a20056a200620056a220441016a2d00003a0000200120073602042001200441026a3602002002200541016a22043a00d0032007417f6a21072004210520044120470d000b200241206a41086a2201200241b0036a41086a290300370300200241206a41106a2204200241b0036a41106a290300370300200241206a41186a2205200241b0036a41186a290300370300200241c0006a41086a220720024180016a41086a290300370300200241c0006a41106a220820024180016a41106a290300370300200241c0006a41186a220320024180016a41186a290300370300200220022903b0033703202002200229038001370340200041053a000020002002290340370001200041096a2007290300370000200041116a2008290300370000200041196a2003290300370000200041216a2002290320370000200041296a2001290300370000200041316a2004290300370000200041396a2005290300370000200041c1006a20022f00003b0000200041c3006a200241026a2d00003a00000c080b200541ff0171450d01200241003a00d0030c010b200541ff0171450d00200241003a00d0030b2000410a3a00000c050b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041063a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c050b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c040b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041073a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c040b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c030b200041083a00000c020b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041093a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c020b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c010b2000410a3a00000b200241e0056a24000bfc0802067f047e230041b0056b22022400024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541024b0d0420050e03010203010b200041043a00000c050b20024180036a20011099032002280280032101200241d0006a20024180036a41047241ac0210a1051a024020014116460d0020024180036a200241d0006a41ac0210a1051a41b00210212205450d0420052001360200200541046a20024180036a41ac0210a1051a200041013a0000200020022f00103b0001200041036a200241126a2d00003a0000200041046a2005360200200041086a2002290230370200200041106a200241306a41086a290200370200200041186a200241306a41106a290200370200200041206a200241306a41186a2902003702000c050b200041043a00000c040b41002105200241003a00a0032003417f6a21062003417e6a21030240034020062005460d0120024180036a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00a0032003417f6a21032007210520074120470d000b200241306a41086a20024180036a41086a2903002208370300200241306a41106a20024180036a41106a2903002209370300200241306a41186a20024180036a41186a290300220a3703002002200229038003220b370330200041023a00002000200b370001200041096a2008370000200041116a2009370000200041196a200a370000200041216a2002280010360000200041246a200241136a2800003600000c040b0240200541ff0171450d00200241003a00a0030b200041043a00000c030b41002105200241003a00a0032003417f6a21062003417e6a210302400240034020062005460d0120024180036a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00a0032003417f6a21032007210520074120470d000b200241306a41086a20024180036a41086a290300370300200241306a41106a20024180036a41106a290300370300200241306a41186a20024180036a41186a290300370300200220022903800337033020024180036a20011099032002280280032101200241d0006a20024180036a41047241ac0210a1051a20014116460d0120024180036a200241d0006a41ac0210a1051a41b00210212205450d0320052001360200200541046a20024180036a41ac0210a1051a200241106a41186a200241306a41186a2903002208370300200241106a41106a200241306a41106a2903002209370300200241106a41086a200241306a41086a290300220a37030020022002290330220b370310200041033a00002000200b370001200041096a200a370000200041116a2009370000200041196a2008370000200041216a20022f000d3b0000200041236a2002410f6a2d00003a0000200041246a20053602000c040b200541ff0171450d00200241003a00a0030b200041043a00000c020b200041043a00000c010b102a000b200241b0056a24000bcc0101027f0240200041c8006a280200450d00200028024410230b0240200041186a2802002201450d00200028021021022001410474210103400240200241046a280200450d00200228020010230b200241106a2102200141706a22010d000b0b0240200041146a28020041ffffffff0071450d00200028021010230b0240200041f4016a2802002202450d00200241c1006c450d0020002802f00110230b20004180026a410036020020002802fc012102200041013602fc01024020004184026a280200450d00200210230b0bd90401057f230041106b22022400200241003a000502400240024002400240024020012802002203280204220420044100472205490d00200241056a20032802002206200510a1051a2003200420056b3602042003200620056a360200024020040d00410021040c050b024020022d0005220441037122034103460d000240024020030e03070001070b200241003b0106200220043a00064101210420012802002201280204220320034100472205490d04200241066a41017220012802002204200510a10521062001200320056b3602042001200420056a360200024020030d00200620056a22044100200241066a20046b41026a10a0051a0b20022f0106220441ff014d0d0220044102762103410021040c070b20024100360208200220043a0008200241086a4101722001280200220428020020042802042205410320054103491b220310a1052106200428020422012003490d042004200120036b3602042004200428020020036a3602000240200541024b0d00200620036a22044100200241086a20046b41046a10a0051a0b2002280208220341808004492104200341027621030c060b200441034d0d010b410121040c040b2002410036020c2002410c6a20012802002204280200220120042802042203410420034104491b220510a1051a2004200320056b3602042004200120056a3602000240200341034b0d002002410c6a20056a4100410420056b10a0051a0b200228020c22034180808080044921040c030b0c020b20032001418ca9c0001044000b20044102762103410021040b2000200336020420002004360200200241106a24000b890301077f41012102024002402001280208220341016a2204200128020422054d0d000c010b0240024002400240200320054f0d002001280200220620036a2d00002107200120043602080240200741037122084103460d0002400240024020080e03000102000b20074102762108410021020c070b0240200341026a220320054d0d000c070b200120033602082004417f460d03200620046a2d0000410874200772220141ffff0371418002490d06200141fcff03714102762108410021020c060b200341046a220320054b0d05200120033602082004417d4f0d03200620046a22012f0000200141026a2d000041107472410874200772220141808004492102200141027621080c050b0240200741034d0d000c050b200341056a220320054b0d04200120033602082004417c4f0d03200620046a28000022084180808080044921020c040b2003200541b0bbc0001030000b417f200341a0bbc0001044000b2004200341a0bbc0001044000b2004200341a0bbc0001044000b20002008360204200020023602000b850605027f027e017f027e027f230041a0016b220224002000280200210002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0220054290ce005441002004501b450d012005a72103412721000c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d02200141a889c0004102200241206a20006a41800120006b104121000c060b41272100200241186a21060340200241106a200520044290ce00420010a7052002200229031022072006290300220842f0b17f427f10a605200241206a20006a2203417c6a200520022903007ca7220941ffff037141e4006e220a41017441ea84c0006a2f00003b00002003417e6a200a419c7f6c20096a41ffff037141017441ea84c0006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000c040b0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d01200141a889c0004102200241206a20006a41800120006b104121000c040b2000418001419889c0001044000b2000418001419889c0001044000b2007a721030b02400240200341e3004a0d00200321090c010b200241206a2000417e6a22006a2003200341ffff037141e4006e2209419c7f6c6a41ffff037141017441ea84c0006a2f00003b00000b024002402009410a480d00200241206a2000417e6a22006a200941017441ea84c0006a2f00003b00000c010b200241206a2000417f6a22006a200941306a3a00000b2001419ca8c7004100200241206a20006a412720006b104121000b200241a0016a240020000b1300200041003602042000419ca8c7003602000b13002000410136020420004188e6c2003602000be51b06037f017e077f017e277f027e230041a00d6b220324002003200236020c20032001360208200341206a41186a22044200370300200341206a41106a22024200370300200341206a41086a220142003703002003420037032041e4dec400ad4280808080e00084100c220529000021062001200541086a290000370300200320063703202005102341f3dec400ad4280808080e00084100c22072900002106200341106a41086a2205200741086a2900003703002003200637031020071023200220032903102206370300200341800d6a41086a22082001290300370300200341800d6a41106a22092006370300200341800d6a41186a220a2005290300370300200320032903203703800d2003200341800d6a412010cd012003280204210b2003280200210c2004420037030020024200370300200142003703002003420037032041abe3c200ad4280808080800384100c220729000021062001200741086a290000370300200320063703202007102341c3e3c200ad4280808080e00184100c220729000021062005200741086a29000037030020032006370310200710232002200329031022063703002008200129030037030020092006370300200a2005290300370300200320032903203703800d200341206a200341800d6a412010890220032802202201410120011b210d0240024002402003290224420020011b220e422088a722020d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b200341206a410041e00c10a0051a200b417f6a41d100704130200c1b2101200d41206a210f200d20024105746a21104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f410021204100212141002122410021234100212441002125410021264100212741002128410021294100212a4100212b4100212c4100212d4100212e4100212f4100210b200d21024100213041d1002131024003402030210720022105024002402001450d00200141016a2101200521020340024020102002470d00200d21020b2002220541206a21022001417f6a22010d000b20050d010c030b024020052010460d00200541206a21020c010b200f2102200d21050b0240024002400240200328020c220141056a2204417f4c0d0020032802082132024002402004450d0020041021220c450d0320034100360218200320043602140c010b20034100360218200320043602142003410136021041011021220c450d08200341013602140b2003200c360210200c20073a0000200341013602182001200341106a10610240024020032802142233200328021822306b2001490d00200328021021042033210c0c010b203020016a22042030490d032033410174220c2004200c20044b1b220c4100480d030240024020330d000240200c0d00410121040c020b200c102122040d010c0a0b200328021021042033200c460d0020042033200c10252204450d090b2003200c360214200320043602100b200420306a2032200110a1051a2003203020016a2230360218412010212201450d0120012005290000370000200141186a2232200541186a290000370000200141106a2234200541106a290000370000200141086a2235200541086a29000037000002400240200c20306b411f4d0d00200c21330c010b203041206a22052030490d03200c41017422332005203320054b1b22334100480d0302400240200c0d00024020330d00410121040c020b203310212204450d0a0c010b200c2033460d002004200c203310252204450d090b20032033360214200320043602100b200420306a22052001290000370000200541186a2032290000370000200541106a2034290000370000200541086a20352900003700002003203041206a2205360218200110232005ad4220862004ad84101822012900002106200141086a2900002136200141106a2900002137200a200141186a2900003703002009203737030020082036370300200320063703800d2001102302402033450d00200410230b2031417f6a2131200741016a2130200341206a20074103704105746a220120032903800d370000200141186a200a290300370000200141106a2009290300370000200141086a20082903003700004100210503402007200741036e2204417d6c6a4102470d04200341206a20056a220141df006a2d0000220b2001411f6a2d0000220c71200b200c722001413f6a2d000071722128200141de006a2d0000220b2001411e6a2d0000220c71200b200c722001413e6a2d000071722127200141dd006a2d0000220b2001411d6a2d0000220c71200b200c722001413d6a2d000071722126200141dc006a2d0000220b2001411c6a2d0000220c71200b200c722001413c6a2d000071722125200141db006a2d0000220b2001411b6a2d0000220c71200b200c722001413b6a2d000071722124200141da006a2d0000220b2001411a6a2d0000220c71200b200c722001413a6a2d000071722123200141d9006a2d0000220b200141196a2d0000220c71200b200c72200141396a2d000071722122200141d8006a2d0000220b200141186a2d0000220c71200b200c72200141386a2d000071722121200141d7006a2d0000220b200141176a2d0000220c71200b200c72200141376a2d000071722120200141d6006a2d0000220b200141166a2d0000220c71200b200c72200141366a2d00007172211f200141d5006a2d0000220b200141156a2d0000220c71200b200c72200141356a2d00007172211e200141d4006a2d0000220b200141146a2d0000220c71200b200c72200141346a2d00007172211d200141d3006a2d0000220b200141136a2d0000220c71200b200c72200141336a2d00007172211c200141d2006a2d0000220b200141126a2d0000220c71200b200c72200141326a2d00007172211b200141d1006a2d0000220b200141116a2d0000220c71200b200c72200141316a2d00007172211a200141d0006a2d0000220b200141106a2d0000220c71200b200c72200141306a2d000071722119200141cf006a2d0000220b2001410f6a2d0000220c71200b200c722001412f6a2d000071722118200141ce006a2d0000220b2001410e6a2d0000220c71200b200c722001412e6a2d000071722117200141cd006a2d0000220b2001410d6a2d0000220c71200b200c722001412d6a2d000071722116200141cc006a2d0000220b2001410c6a2d0000220c71200b200c722001412c6a2d000071722115200141cb006a2d0000220b2001410b6a2d0000220c71200b200c722001412b6a2d000071722114200141ca006a2d0000220b2001410a6a2d0000220c71200b200c722001412a6a2d000071722113200141c9006a2d0000220b200141096a2d0000220c71200b200c72200141296a2d000071722112200141c8006a2d0000220b200141086a2d0000220c71200b200c72200141286a2d000071722111200141c7006a2d0000220b200141076a2d0000220c71200b200c72200141276a2d000071722129200141c6006a2d0000220b200141066a2d0000220c71200b200c72200141266a2d00007172212a200141c5006a2d0000220b200141056a2d0000220c71200b200c72200141256a2d00007172212b200141c4006a2d0000220b200141046a2d0000220c71200b200c72200141246a2d00007172212c200141c3006a2d0000220b200141036a2d0000220c71200b200c72200141236a2d00007172212d200141c2006a2d0000220b200141026a2d0000220c71200b200c72200141226a2d00007172212e200141c1006a2d0000220b200141016a2d0000220c71200b200c72200141216a2d00007172212f200141c0006a2d0000220b20012d0000220c71200b200c72200141206a2d00007172210b200541800c460d04200341206a20052004410574200741096e41e0006c6b6a6a220141ff006a20283a0000200141fe006a20273a0000200141fd006a20263a0000200141fc006a20253a0000200141fb006a20243a0000200141fa006a20233a0000200141f9006a20223a0000200141f8006a20213a0000200141f7006a20203a0000200141f6006a201f3a0000200141f5006a201e3a0000200141f4006a201d3a0000200141f3006a201c3a0000200141f2006a201b3a0000200141f1006a201a3a0000200141f0006a20193a0000200141ef006a20183a0000200141ee006a20173a0000200141ed006a20163a0000200141ec006a20153a0000200141eb006a20143a0000200141ea006a20133a0000200141e9006a20123a0000200141e8006a20113a0000200141e7006a20293a0000200141e6006a202a3a0000200141e5006a202b3a0000200141e4006a202c3a0000200141e3006a202d3a0000200141e2006a202e3a0000200141e1006a202f3a0000200141e0006a200b3a000020042107200541e0006a220541e00c470d000c040b0b1032000b1033000b102c000b4100210120310d000b0b200020283a001f200020273a001e200020263a001d200020253a001c200020243a001b200020233a001a200020223a0019200020213a0018200020203a00172000201f3a00162000201e3a00152000201d3a00142000201c3a00132000201b3a00122000201a3a0011200020193a0010200020183a000f200020173a000e200020163a000d200020153a000c200020143a000b200020133a000a200020123a0009200020113a0008200020293a00072000202a3a00062000202b3a00052000202c3a00042000202d3a00032000202e3a00022000202f3a00012000200b3a00000b0240200e42ffffff3f83500d00200d10230b200341a00d6a24000f0b102a000b13002000410136020420004198ebc2003602000b3400200041fee2c20036020420004100360200200041146a4105360200200041106a41e0ecc200360200200041086a420f3702000b130020004102360204200041f0f1c2003602000b2d01017f02404104102122020d001033000b20004284808080c00037020420002002360200200241e5003600000bf90403027f017e057f230041d0006b2202240041b9f4c200ad4280808080c00184100c22032900002104200241086a200341086a290000370300200220043703002003102341daf4c200ad4280808080800284100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000b130020004101360204200041ecf4c2003602000b3400200041b9f4c20036020420004100360200200041146a4103360200200041106a41c8f5c200360200200041086a420c3702000b3400200041abe3c20036020420004100360200200041146a4101360200200041106a41e0f9c200360200200041086a42183702000b130020004102360204200041c0fcc2003602000ba40301027f230041e0006b22032400200341003a00050240024002400240200041c000490d00200041808001490d012000418080808004490d0241052104200341053a0005200341033a0000200320003600010c030b41012104200341013a0005200320004102743a00000c020b41022104200341023a0005200320004102744101723b01000c010b41042104200341043a0005200320004102744102723602000b024002402001280200220028020822012002490d0020002802002100200320023602082003200436020c20042002470d0120002003200210a1051a200341e0006a24000f0b200220014190e3c2001043000b200341286a41146a410b360200200341346a410d360200200341106a41146a41033602002003200341086a36024020032003410c6a360244200341c8006a41146a4100360200200342033702142003418ca7c7003602102003410d36022c2003419ca8c7003602582003420137024c200341e0a7c7003602482003200341286a3602202003200341c8006a3602382003200341c4006a3602302003200341c0006a360228200341106a419ca8c700103a000b8cc2010f027f017e067f017e107f017e067f027e077f037e057f017e067f017e067f230041b00a6b2204240002400240024002400240024002400240200141ff01710d00200241ff01714102470d00200441d0076a41186a4200370300200441d0076a41106a22054200370300200441d0076a41086a22014200370300200442003703d00741b0dfc300ad4280808080a00184100c22022900002106200441b0066a41086a2207200241086a290000370300200420063703b0062002102320012007290300370300200420042903b0063703d00741a89ec700ad4280808080900184100c22022900002106200441d0016a41086a2208200241086a290000370300200420063703d00120021023200520042903d001220637030020044180046a41086a2202200129030037030020044180046a41106a2209200637030020044180046a41186a220a2008290300370300200420042903d00737038004200441386a20044180046a4120419ca8c70041004100108c0120042802384101460d01200a4200370300200942003703002002420037030020044200370380044196adc300ad4280808080900184100c220829000021062002200841086a29000037030020042006370380042008102341bce0c300ad4280808080e00084100c220829000021062001200841086a290000370300200420063703d00720081023200920042903d007220637030020072002290300370300200441b0066a41106a2006370300200441b0066a41186a200129030037030020042004290380043703b006200441d0076a200441b0066a10910320042802d0072201410420011b210b200341086a280200220c20042902d407420020011b220d422088a7220e4b0d03200c41ffffffff0371200c460d020c070b200041023a00000c040b20004183203b0100200041086a4112360200200041046a41f5fec200360200200041026a41003a00000c030b200c4102742201417f4c0d040240024002400240024020010d004104210f0c010b20011021220f450d010b41002102200441003602482004200f3602402004200141027622013602440240200e450d0020032802002210200c4188026c6a2111024002400240200c450d00200b200e412c6c6a210a4100211241012101200b210720102113034020132802402108024002400240024020014101710d00200220084f0d010b20134188026a2114200721010340200a2001460d02200128020021022001412c6a2207210120022008470d000b200741786a2802004102460d0220134198016a2007460d02200741586a201341f0006a412010a305450d0220004183203b0100200041086a410f360200200041046a41bbffc200360200200041026a41043a0000200441c0006a21010c050b20004183203b0100200041086a410f360200200041046a419cffc200360200200041026a41023a0000200441c0006a21010c040b20004183203b0100200041086a4110360200200041046a41abffc200360200200041026a41033a0000200441c0006a21010c030b024020132802182215450d0020132802102116200441d0076a200810c10320044180046a20042802d007220220042802d80710e501200428028404410020042802800441014622171b21012004280288042118024020042802d407450d00200210230b02400240200120156a22014101460d004105211941caffc200211a4109211b200141e4004b0d012018410020171b210220154104742117201641086a21010340200128020020026a2102200141106a2101201741706a22170d000b200241a09c014b0d010b200841e807490d012015410474210103402001450d02200141706a210120162d000c2102201641106a211620024102470d000b4106211941d3ffc200211a4114211b0b20004183203b0100200041086a201b360200200041046a201a360200200041026a20193a0000200441c0006a21010c030b20132802402102024020122004280244470d00200441c0006a2012410110792004280240210f200428024821120b200f20124102746a20023602002004201241016a2212360248410021012014211320142011470d000b0b200441d0076a41186a22074200370300200441d0076a41106a22084200370300200441d0076a41086a22014200370300200442003703d00741b0dfc300ad4280808080a00184100c22022900002106200441b0066a41086a220a200241086a290000370300200420063703b006200210232001200a290300370300200420042903b0063703d00741bcbac500ad4280808080b00184100c22022900002106200441d0016a41086a220a200241086a290000370300200420063703d00120021023200520042903d001370000200541086a200a29030037000020044180046a41086a200129030037030020044180046a41106a200829030037030020044180046a41186a2007290300370300200420042903d00737038004200441d0076a20044180046a10ad0220042802d007211420042902d4072106200441d0076a10c20320042802d407211c20042802d007211b20042802d8072101200441b0016a41186a200441f4076a290200370300200441b0016a41106a200441ec076a290200370300200441b0016a41086a200441e4076a290200370300200420042902dc073703b0012001200141ffffffff0171470d0a20014103742202417f4c0d0a0240024020020d00410421170c010b200210212217450d040b41002107200441003602d807200420173602d00720042002410376221d3602d407024020014103742201450d00201b20016a211241002107201b210f4100211303400240200f2802004101470d00024002400240200741014b0d000240024020070e020001000b200f2802042116410021010c030b200f2802042116410021010c010b200f28020421164100210120072102034020012002410176220820016a220a2017200a4103746a28020420164b1b2101200220086b220241014b0d000b0b0240201720014103746a28020422022016460d00200120022016496a21010b200720014f0d00200120071038000b0240200720042802d407470d00200441d0076a2007410110a50120042802d00721170b201720014103746a220241086a2002200720016b41037410a2051a20022016360204200220133602002004200741016a22073602d8070b201341016a21132012200f41086a220f470d000b20042802d407211d0b20044180046a41186a2202420037030020044180046a41106a2208420037030020044180046a41086a22014200370300200442003703800441e4dec400ad4280808080e00084100c220a290000211e2001200a41086a2900003703002004201e37038004200a102341f9dec400ad4280808080a00184100c220a290000211e200441d0076a41086a2216200a41086a2900003703002004201e3703d007200a1023200920042903d007370000200941086a2016290300370000200441b0066a41086a2001290300370300200441b0066a41106a2008290300370300200441b0066a41186a200229030037030020042004290380043703b006200441d0076a200441b0066a412010e10120042d00d007210a2002200441e9076a2900003703002008200441e1076a2900003703002001200441d9076a290000370300200420042900d1073703800402400240200a4101460d0020044190076a41186a420037030020044190076a41106a420037030020044190076a41086a420037030020044200370390070c010b20044190076a41186a200229030037030020044190076a41106a200829030037030020044190076a41086a20012903003703002004200429038004370390070b20044180046a41186a2202420037030020044180046a41106a2208420037030020044180046a41086a22014200370300200442003703800441db97c700ad4280808080f00084100c220a290000211e2001200a41086a2900003703002004201e37038004200a102341bcbcc300ad4280808080c00184100c2216290000211e200441d0076a41086a220a201641086a2900003703002004201e3703d00720161023200920042903d007370000200941086a2215200a290300370000200441b0066a41086a220f2001290300370300200441b0066a41106a22132008290300370300200441b0066a41186a2212200229030037030020042004290380043703b006200441306a200441b0066a412010cd012004280234211820042802302119200242003703002008420037030020014200370300200442003703800441e4dec400ad4280808080e00084100c2216290000211e2001201641086a2900003703002004201e370380042016102341f9dec400ad4280808080a00184100c2216290000211e200a201641086a2900003703002004201e3703d00720161023200920042903d0073700002015200a290300370000200f2001290300370300201320082903003703002012200229030037030020042004290380043703b006200441d0076a200441b0066a412010e10120042d00d007210a2002200441e9076a2900003703002008200441e1076a2900003703002001200441d9076a290000370300200420042900d107370380042018410020191b211602400240200a4101460d002012420037030020134200370300200f4200370300200442003703b0060c010b2012200229030037030020132008290300370300200f200129030037030020042004290380043703b0060b2006420020141b21062014410120141b211f200441d0016a410c6a200441b0066a41086a2220290300370200200441e4016a200441b0066a41106a2221290300370200200441ec016a200441b0066a41186a2222290300370200200420163602d001200420042903b0063702d4012004410036028807200442013703800741012123200c450d01201f41606a21242017410c6a2119200441d0076aad42808080808002842125200441b0066aad428080808080048421262006422088a72127200441d0076a4101722128200441d0076a41106a211a200441d9076a2129410121234100210c410021020240034041e7ffc20021134183a01c21124110211420022007460d0120104188026a212a2010280240210f2002210a024002400240024002400240024002400340024002402007200a4d0d002017200a41037422166a221528020421082007200a41016a22024d0d01201920166a2101034020012802002008470d02200141086a21012007200241016a2202470d000b200721020c010b200a200741a4aac0001030000b2002200a490d010240200720024f0d00200220074194aac0001043000b02402008200f460d002002210a20022007460d0b0c010b0b024020044190076a201041d0006a2208460d00200820044190076a412010a305450d0041f380c30021134183a0c0002112411521140c0a0b0240201041f8016a222b28020022132002200a6b220141017620014101716a4f0d0041f7ffc20021134183a0202112411621140c0a0b0240201320274d0d00418d80c30021134183a0242112411721140c0a0b0240201041cc006a22132802004180a0014d0d00419fabc30021134183a03821120c0a0b200441d0076a200f10c3030240024020042802d007222c450d0020042802d407212d2004200f3602b00720044180046a200441b0076a10af02200441b0066a20044180046a109702200441d0076a20042802b006220120042802b80610980220042903d007212e201a290300212f20042903d8072130024020042802b406450d00200110230b20132802002201417f4c0d162010280244210a0240024020010d0041002131410121120c010b20012131200110212212450d100b2012200a200110a105213220044180046a41186a223320104188016a29000037030020044180046a41106a223420104180016a29000037030020044180046a41086a2235201041f8006a2900003703002004201029007037038004201041086a2212290300211e20102903002136200441b0066a201041106a10c403200441d0076a41186a2237201041346a2238290000370300201a2010412c6a223929000037030020042802b006213a20042802b406213b20042802b806213c20304200202e42015122011b203654202f420020011b222e201e54202e201e511b450d0141e680c30021134183a03c2112410d21140c090b41d880c30021134183a0342112410e21140c0a0b2004200f3602d806200441b0076a200441d8066a10af0241002101200441003a00df06200441083a00de06200420363703b0062004201e3703b8062004200441b0076a3602f0060240024002402036201e8450450d004200211e420021360c010b2004200441b0076a3602e0062004200441e0066a3602e0072004200441de066a3602dc072004200441f0066a3602d8072004200441df066a3602d4072004200441b0066a3602d00720044180046a200441b0076a200441d0076a10c50302402004280280044101470d0042002136200429038804211e41012101200428028404210a0c020b20044180046a41286a290300213620042903a004211e410021012004290388044201520d00200429039004212e20042802e0062101200441d0076a41386a203329030037030020292001290000370000202941086a200141086a290000370000202941106a200141106a290000370000202941186a200141186a2900003700002004202e3703800841002101200441003a00d807200441023a00d007200441d0076a10e0010b0b0240024020010d0020374200370300201a4200370300200441d0076a41086a22014200370300200442003703d00741bdadc500ad4280808080800184222e100c220a290000212f2035200a41086a2900003703002004202f37038004200a10232001203529030037030020042004290380043703d00741c5adc500ad4280808080d00184222f100c220f2900002130200441e0066a41086a220a200f41086a290000370300200420303703e006200f1023201a20042903e006370000201a41086a2218200a290300370000202020012903003703002021201a29030037030020222037290300370300200420042903d0073703b006200441186a200441b0066a412010d701200441186a41106a29030021302004290320213d2004280218210f20374200370300201a420037030020014200370300200442003703d007202e100c2214290000212e2035201441086a2900003703002004202e37038004201410232001203529030037030020042004290380043703d007202f100c2214290000212e200a201441086a2900003703002004202e3703e00620141023201a20042903e0063700002018200a290300370000202020012903003703002021201a29030037030020222037290300370300200420042903d0073703b0062004420020304200200f1b222e20367d203d4200200f1b2236201e54ad7d222f2036201e7d221e203656202f202e56202f202e511b22011b3703d80720044200201e20011b3703d00720262025100e0c010b200a41ff01714104470d020b200441003602d807200442013703d0072010280240210a410410212201450d0f200441043602d407200420013602d0072001200a360000200441043602d807412010212201450d0d20012008290000370000200141186a2214200841186a290000370000200141106a2218200841106a290000370000200141086a223e200841086a2900003700000240024020042802d407220f20042802d80722086b4120490d0020042802d007210a0c010b200841206a220a2008490d0f200f410174223f200a203f200a4b1b223f4100480d0f02400240200f0d000240203f0d004101210a0c020b203f1021220a0d010c120b20042802d007210a200f203f460d00200a200f203f1025220a450d1120042802d80721080b2004203f3602d4072004200a3602d0070b200a20086a220a2001290000370000200a41186a2014290000370000200a41106a2018290000370000200a41086a203e2900003700002004200841206a3602d807200110232010280244211420132802002201200441d0076a10610240024020042802d407220f20042802d80722086b2001490d0020042802d007210a0c010b200820016a220a2008490d0f200f4101742213200a2013200a4b1b22134100480d0f02400240200f0d00024020130d004101210a0c020b20131021220a450d120c010b20042802d007210a200f2013460d00200a200f20131025220a450d1120042802d80721080b200420133602d4072004200a3602d0070b200a20086a2014200110a1051a2004200820016a22013602d8070240024020042802d407220a20016b4120490d0020042802d0072108200a210f0c010b200141206a22082001490d0f200a410174220f2008200f20084b1b220f4100480d0f02400240200a0d000240200f0d00410121080c020b200f10212208450d120c010b20042802d0072108200a200f460d002008200a200f10252208450d1120042802d80721010b2004200f3602d407200420083602d0070b200820016a220a201041f0006a2213290000370000200a41186a201341186a290000370000200a41106a201341106a290000370000200a41086a201341086a2900003700002004200141206a220a3602d8070240200f200a6b413f4b0d00200a41c0006a2201200a490d0f200f41017422132001201320014b1b22014100480d0f02400240200f0d00024020010d00410121080c020b200110212208450d120c010b200f2001460d002008200f200110252208450d1120042802d807210a0b200420013602d407200420083602d0070b2008200a6a220120104190016a2208290000370000200141386a200841386a290000370000200141306a200841306a290000370000200141286a200841286a290000370000200141206a200841206a290000370000200141186a200841186a290000370000200141106a200841106a290000370000200141086a200841086a2900003700002004200a41c0006a3602d807412010212201450d0d2001201041d0016a2208290000370000200141186a2213200841186a290000370000200141106a2214200841106a290000370000200141086a2218200841086a2900003700000240024020042802d407220f20042802d80722086b4120490d0020042802d007210a0c010b200841206a220a2008490d0f200f410174223e200a203e200a4b1b223e4100480d0f02400240200f0d000240203e0d004101210a0c020b203e1021220a450d120c010b20042802d007210a200f203e460d00200a200f203e1025220a450d1120042802d80721080b2004203e3602d4072004200a3602d0070b200a20086a220a2001290000370000200a41186a2013290000370000200a41106a2014290000370000200a41086a20182900003700002004200841206a3602d807200110232012290300211e201029030021360240024020042802d407220a20042802d80722016b4110490d0020042802d00721080c010b200141106a22082001490d0f200a410174220f2008200f20084b1b220f4100480d0f02400240200a0d000240200f0d00410121080c020b200f10212208450d120c010b20042802d0072108200a200f460d002008200a200f10252208450d1120042802d80721010b2004200f3602d407200420083602d0070b200820016a2208201e370008200820363700002004200141106a3602d8072010280210210120102802182208200441d0076a106102402008450d0020084104742112034002402001410c6a2d000022084103714103460d004100210a02400240024020080e03020001020b4101210a0c010b4102210a0b2004200a3a00f0060240024020042802d40720042802d8072208460d0020042802d007210f0c010b200841016a220f2008490d1220084101742213200f2013200f4b1b22134100480d120240024020080d0041002108024020130d004101210f0c020b20131021220f450d150c010b20042802d007210f20082013460d00200f200820131025220f450d1420042802d80721080b200420133602d4072004200f3602d0070b200f20086a200a3a00002004200841016a3602d8070b20012802002114200141086a2802002208200441d0076a10610240024020042802d407221320042802d807220a6b2008490d0020042802d007210f0c010b200a20086a220f200a490d1120134101742218200f2018200f4b1b22184100480d110240024020130d00024020180d004101210f0c020b20181021220f450d140c010b20042802d007210f20132018460d00200f201320181025220f450d1320042802d807210a0b200420183602d4072004200f3602d0070b200141106a2101200f200a6a2014200810a1051a2004200a20086a3602d807201241706a22120d000b0b412010212201450d0d2001201029001c370000200141186a22132038290000370000200141106a22122039290000370000200141086a2214201041246a2900003700000240024020042802d407220f20042802d80722086b4120490d0020042802d007210a0c010b200841206a220a2008490d0f200f4101742218200a2018200a4b1b22184100480d0f02400240200f0d00024020180d004101210a0c020b20181021220a450d120c010b20042802d007210a200f2018460d00200a200f20181025220a450d1120042802d80721080b200420183602d4072004200a3602d0070b200a20086a220a2001290000370000200a41186a2013290000370000200a41106a2012290000370000200a41086a20142900003700002004200841206a3602d8072001102320042802d4072108203320043502d80742208620042802d007220aad841018220141186a2900003703002034200141106a2900003703002035200141086a29000037030020042001290000370380042001102302402008450d00200a10230b41002138200441003602e006200441003602b007200241037420166b213e201028028002210120102802fc01211641002139410021144100211803402014417f6a210a202420144105746a2112034020014108490d064101210f200441013602d8062004200141037622133602f00602400240201341014b0d002001210841002101024020130e020002000b200441bc066a4101360200200441e4076a4102360200200442023702d4072004419c96c7003602d007200441013602b4062004200441b0066a3602e0072004200441f0066a3602b8062004200441d8066a3602b006200441d0076a419ca8c700103a000b2001410771220f41087221082016200f4107466a210f200141016a410771200141786a4178717221010b2016410120081b2113201241206a2112200a41016a210a200f2116410120084107717420132d000071450d000b202b28020020184d0d04200a41016a2114201841016a214020102802f001201841c1006c6a213f203e2108201521160340024020080d0041a480c3002113411721144183a02821120c080b200841786a210820162802002113201641086a21162013200a470d000b02400240203f2d00004101470d00200441b0076a210820390d012028200429038004370000202841086a2035290300370000202841106a2034290300370000202841186a2033290300370000200441013a00d007200441b0076a200441d0076a200441d0016a107620042802b00721390c010b200441e0066a210820380d002028200429038004370000202841086a2035290300370000202841106a2034290300370000202841186a2033290300370000200441003a00d007200441e0066a200441d0076a200441d0016a107620042802e00621380b200a20274f0d03200f211620402118203f41016a2008350208422086200835020084201210134101460d000b41bb80c3002113411021144183a02c21120c050b200a20024194aac0001044000b200a410876410874200a41ff0171722112201e422088a72114201ea721130c050b200a202741d084c3001030000b41f7ffc2002113411621144183a02021120c010b202b2802002018460d0141cb80c3002113410d21144183a03021120b02402039450d0020042802b407450d00203910230b2038450d0120042802e406450d01203810230c010b20372033290300370300201a2034290300370300200441d0076a41086a2208203529030037030020042004290380043703d0070240200c200428028407470d0020044180076a200c4101109a012004280280072123200428028807210c0b2023200c4105746a220120042903d007370000200141186a2037290300370000200141106a201a290300370000200141086a20082903003700002004200c41016a220c3602880702402039450d0020042802b407450d00203910230b02402038450d0020042802e406450d00203810230b02402031450d00203210230b0240202d450d00202c10230b0240203c450d00203c4104742108203a210103400240200141046a280200450d00200128020010230b200141106a2101200841706a22080d000b0b0240203b41ffffffff0071450d00203a10230b202a2110202a2011470d010c040b0b02402031450d00203210230b0240202d450d00202c10230b0240203c450d00203c4104742102203a210103400240200141046a280200450d00200128020010230b200141106a2101200241706a22020d000b0b203b41ffffffff0071450d00203a10230b024020042802840741ffffff3f71450d00202310230b0240201d41ffffffff0171450d00201710230b0240201c41ffffffff0171450d00201b10230b0240200642ffffff3f83500d00201f10230b200441f0006a41186a20044190016a41186a290200370300200441f0006a41106a20044190016a41106a290200370300200441f0006a41086a20044190016a41086a2902003703002004200429029001370370200041086a2014360200200041046a201336020020002012360200200441c0006a21010b200141046a28020041ffffffff0371450d06200128020010230c060b20044180046a41186a2202420037030020044180046a41106a2207420037030020044180046a41086a22014200370300200442003703800441e4dec400ad4280808080e00084100c2208290000211e2001200841086a2900003703002004201e370380042008102341f3dec400ad4280808080e00084100c220a290000211e200441d0076a41086a2208200a41086a2900003703002004201e3703d007200a1023200920042903d007370000200941086a2216200829030037000020202001290300370300202120072903003703002022200229030037030020042004290380043703b006200441106a200441b0066a412010cd012004280214210f20042802102113200242003703002007420037030020014200370300200442003703800441db97c700ad4280808080f00084100c220a290000211e2001200a41086a2900003703002004201e37038004200a102341bcbcc300ad4280808080c00184100c220a290000211e2008200a41086a2900003703002004201e3703d007200a1023200920042903d0073700002016200829030037000020202001290300370300202120072903003703002022200229030037030020042004290380043703b006200441086a200441b0066a412010cd01200428020c214020042802082141200441003602d807200442043703d007200441d0076a4100200e1079200e412c6c210820042802d007223220042802d80722074102746a2101200b2102034020012002280200360200200741016a2107200141046a21012002412c6a2102200841546a22080d000b20044190016a41086a200441b0016a41086a29030037030020044190016a41106a200441b0016a41106a29030037030020044190016a41186a200441b0016a41186a290300370300200420073602d807200420042903b0013703900120042902d40721302004280284072142200428028807212c0240201d41ffffffff0171450d00201710230b0240201c41ffffffff0171450d00201b10230b200f410020131b21310240200642ffffff3f83500d00201f10230b200441d0006a41086a20044190016a41086a2903002206370300200441d0006a41106a20044190016a41106a290300221e370300200441d0006a41186a20044190016a41186a290300223637030020042004290390012225370350200341086a280200210c2003280200211d200441b0016a41186a2036370300200441b0016a41106a201e370300200441b0016a41086a2006370300200420253703b00120044190076a2031413270224310ad032004280290072108200420042802980722013602e406200420083602e006200441b0076a2001ad4220862008ad8422061010108b0102400240024002400240024020042802b0072207450d0020042802b40721172004200441b0076a41086a28020022013602742004200736027002400240024020014104490d002004200741046a36027020042001417c6a220236027420024104490d002007350000211e2004200141786a220a3602742004200741086a360270200441003a00f0074100210102400340200441003a00f006200a2001460d01200441d0076a20016a200720016a220241086a2d00003a00002004200241096a3602702004200141016a22023a00f0072002210120024120470d000b20044180046a41086a200441d0076a41086a29030037030020044180046a41106a200441d0076a41106a29030037030020044180046a41186a200441d0076a41186a2903003703002004200a20026b360274200420042903d00737038004200441d0076a200441f0006a10c60320042802d007220a450d0120042802d4072116200441d0076a200441f0006a10cf0120042802d00722130d02201641ffffffff0371450d01200a10230c010b20044100360274200141ff0171450d00200441003a00f0070b4100210a200441003602880420044201370380042004410a360294012004200441e0066a36029001200420044180046a3602d00141012101200441e4076a4101360200200442013702d40720044180c5c6003602d007200420044190016a3602e007200441d0016a4184a5c200200441d0076a10311a20043502880442208620043502800484100a0240200428028404450d0020042802800410230b0c010b200441d0016a41086a20044180046a41086a290300370300200441d0016a41106a20044180046a41106a29030037030020042802d407210f410021010b02402017450d00200710230b2001450d010b2004280294070d010c040b2006101120042802940721010240200a450d0002402001450d00200810230b41b9f4c200ad4280808080c00184100c22012900002106200441b0066a41086a200141086a290000370300200420063703b0062001102341c5f4c200ad4280808080d00284100c22012900002106200441d0016a41086a200141086a290000370300200420063703d001200110232004201e3e02b0072004200441b0076aad4280808080c00084100d22012900003703900120011023200441dc076a200441b4076a360200200441003a00e007200420044190016a41086a3602d4072004200441b0076a3602d807200420044190016a3602d00720044180046a200441d0076a1065200428028804221741206a2202417f4c0d0d2004280280042109024002402002450d00200210212201450d082002410f4d0d01200221070c050b200241017422014110200141104b1b220710212201450d090c040b200241017422074110200741104b1b220741004e0d020c070b2001450d030b200810230c020b20022007460d0020012002200710252201450d050b200120042903b006370000200141086a200441b0066a41086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0420072008460d0020012007200810252201450d050b200120042903d001370010200141186a200441d0016a41086a2903003700000240200841606a20174f0d002017415f4b0d04200841017422072002200720024b1b22074100480d0420082007460d0020012008200710252201450d050b200141206a2009201710a1051a0240200428028404450d00200910230b2002ad4220862001ad841012200110230240201641ffffffff0371450d00200a10230b200f41ffffff3f71450d00201310230b200441d0076a41186a4200370300200441d0076a41106a22074200370300200441d0076a41086a22014200370300200442003703d00741db97c700ad4280808080f00084100c220229000021062001200241086a290000370300200420063703d0072002102341bbacc300ad4280808080a00184100c22022900002106200441d0016a41086a2208200241086a290000370300200420063703d00120021023200720042903d001220637030020044180046a41086a200129030037030020044180046a41106a200637030020044180046a41186a2008290300370300200420042903d00737038004200441d0076a20044180046a41201089020240024020042802d00722010d00200441003602f806200442013703f0060c010b200420042902d4073702f406200420013602f0060b0240202c200c202c200c491b223b450d0020044190076aad4280808080c00084212f20044190076a41046a213e20044190016a41086a2127200441d0076a41086a2129200441d0076a410472212d200441d0076a41146a213a200441d0076a4101722113200441b0076a41146a211a2004419c076a213f20044190076a4104722128200441d0016a41106a210e200441b0066a41106a2110200441c0096a212a200441a0096a211c200441e0086a211b200441c0086a2122200441a0086a2121200441ec076a2120200441d0076a41106a21354100211f034020044100360288072004420137038007201d201f4188026c6a220f2802fc012107200f4180026a2802002108200441b0066a41186a2215420037030020104200370300200441b0066a41086a22094200370300200442003703b00641db97c700ad4280808080f00084100c220129000021062009200141086a290000370300200420063703b0062001102341bbacc300ad4280808080a00184100c22012900002106200441e0066a41086a2202200141086a290000370300200420063703e00620011023201020042903e006370000201041086a200229030037000020044180046a41086a2214200929030037030020044180046a41106a2219201029030037030020044180046a41186a22112015290300370300200420042903b00637038004200441d0076a20044180046a41201089020240024020042802d00722010d004100210220044100360278200442013703700c010b200420042902d4072206370274200420013602702006a721020b200441d0016a41186a22184200370300200e4200370300200441d0016a41086a22124200370300200442003703d001418fcdc200ad4280808080f00084100c220129000021062012200141086a290000370300200420063703d0012001102341b8dbc100ad4280808080900184100c220129000021062014200141086a290000370300200420063703800420011023200e200429038004370000200e41086a2014290300370000202920122903003703002035200e290300370300200441d0076a41186a2018290300370300200420042903d0013703d00720044180046a200441d0076a10ba01203720042802900420042903800442025122011b2137024020010d0020044190016a203710b801200441d0076a2004280290012233200428029801222410bb012014202d41086a22342902003703002004202d290200370380040240024020042802d0074101460d002004410036029c0720044200370390070c010b20044190076a41086a20142903003703002004200429038004370390070b200441003602b807200420083602b407200420073602b0072004200441f0006a3602c407200420044180076a3602c0072004200441f0066a3602bc07200441d0076a200441b0076a201a10c703024020042d00d0074101470d0003402009201341086a29000022063703002010201341106a290000221e3703002015201341186a29000022363703002004201329000022253703b00620182036370300200e201e37030020122006370300200420253703d00102400240200428029407220a450d0020042802980721170c010b200441d0076a410041e00210a0051a20044180046a41286a2201410036020020044180046a41206a2202420037030020114200370300201942003703002014420037030020044200370380044194031021220a450d0941002117200a41003b0106200a4100360200200a41086a200441d0076a41e00210a1051a200a4190036a2001280200360200200a4188036a2002290300370200200a4180036a2011290300370200200a41f8026a2019290300370200200a41f0026a2014290300370200200a2004290380043702e80220044100360298072004200a360294070b024002400340200a41086a2102200a2f01062216410574210141002107024003402001450d01200441d0016a2002412010a3052208450d03200141606a2101200741016a2107200241206a21022008417f4a0d000b2007417f6a21160b02402017450d002017417f6a2117200a20164102746a4194036a280200210a0c010b0b2011201829030022063703002019200e290300221e370300201420122903002236370300200420042903d001222537038004203a2025370200203a41086a2036370200203a41106a201e370200203a41186a20063702002004203f3602e007200420163602dc07200420283602d8072004200a3602d407200441003602d007200441d0076a410010bc0121010c010b200a20074102746a41e8026a21010b2001200128020041146a360200200420042802900741146a36029007200441d0076a200441b0076a201a10c70320042d00d0074101460d000b0b203420044190076a41086a290300370200202d200429039007370200200441013602d0072004410036028804200442013703800420042802d4072102410410212201450d0620012002360000200420013602800420044284808080c00037028404202920044180046a10bd0120042802840421012024ad4220862033ad842004350288044220862004280280042202ad84100e02402001450d00200210230b024020042802d007450d00202910be010b0240200428029401450d00203310230b200428027421020b0240200241ffffff3f71450d00200428027010230b2009200f41d8006a2900003703002010200f41e0006a2900003703002015200f41e8006a2900003703002004200f2900503703b006200f41cc006a2802002201417f4c0d0a200f2802442102200f28024021070240024020010d00410021084101210a0c010b2001210820011021220a450d040b200a2002200110a1052102200441b0076a41186a220a200f4188016a290300370300200441b0076a41106a2217200f4180016a290300370300200441b0076a41086a2216200f41f8006a2903003703002014200f4198016a2900003703002019200f41a0016a2900003703002011200f41a8016a29000037030020044180046a41206a2233200f41b0016a29000037030020044180046a41286a2224200f41b8016a29000037030020044180046a41306a2234200f41c0016a29000037030020044180046a41386a223c200f41c8016a2900003703002004200f2903703703b0072004200f290090013703800420044190076a41186a2238200f41e8016a29000037030020044190076a41106a2239200f41e0016a29000037030020044190076a41086a222b200f41d8016a2900003703002004200f2900d00137039007200f41086a290300211e200f290300213620044190016a200f41106a10c4032018200f41346a2900002225370300200e200f412c6a29000022263703002012200f41246a290000222e370300200f29001c21062035200429039001370300203541086a202728020036020020202006370200202041086a202e370200202041106a2026370200202041186a20253702002004201e3703d807200420363703d007200420063703d0012004200736029008200420023602940820042008360298082004200136029c08202141186a2015290300370300202141106a2010290300370300202141086a2009290300370300202120042903b006370300202220042903b007370300202241086a2016290300370300202241106a2017290300370300202241186a200a290300370300201b200429038004370300201b41086a2014290300370300201b41106a2019290300370300201b41186a2011290300370300201b41206a2033290300370300201b41286a2024290300370300201b41306a2034290300370300201b41386a203c290300370300201c41186a2038290300370300201c41106a2039290300370300201c41086a202b290300370300201c200429039007370300202a41086a20044180076a41086a280200360200202a200429038007370200200442013702cc09200441003602d40941b9f4c200ad4280808080c00184100c220129000021062009200141086a290000370300200420063703b0062001102341c5f4c200ad4280808080d00284100c220129000021062012200141086a290000370300200420063703d0012001102320042031360290072004202f100d22012900003703900120011023200441003a0090042004203e36028c042004202736028404200420044190076a36028804200420044190016a36028004200441b0076a20044180046a1065412010212201450d0320012023201f4105746a2202290000370000200141186a2207200241186a290000370000200141106a2208200241106a290000370000200141086a220a200241086a290000370000412010212202450d0320022001290000370000200241186a22162007290000370000200241106a220f2008290000370000200241086a2218200a2900003700002001102320042802b807220841c0006a2215417f4c0d0a20042802b00721170240024002402015450d00201510212214450d062015410f4d0d01201521010c020b41102101411010212214450d070c010b201541017422014110200141104b1b22014100480d05024020152001470d00201521010c010b20142015200110252214450d060b201420042903b006370000201441086a20092903003700000240024020014170714110460d002001210a0c010b200141017422074120200741204b1b220a4100480d052001200a460d0020142001200a10252214450d060b200841206a2101201420042903d001370010201441186a201229030037000002400240200a41606a2008490d00200a21070c010b2008415f4b0d05200a41017422072001200720014b1b22074100480d05200a2007460d002014200a200710252214450d060b201441206a2017200810a1051a02400240200720016b411f4d0d00200721090c010b200141206a22082001490d052007410174220a2008200a20084b1b22094100480d05024020070d00024020090d00410121140c020b200910212214450d070c010b20072009460d0020142007200910252214450d060b201420016a22012002290000370000200141186a2016290000370000200141106a200f290000370000200141086a201829000037000020021023024020042802b407450d00201710230b20044100360288042004420137038004200441d0076a20044180046a10e10220042802c009211720042802c809220120044180046a106102402001450d0020014105742116410020042802880422026b210a200428028004210f200428028404210803402017210102402008200a6a411f4b0d00200241206a22072002490d07200841017422172007201720074b1b22074100480d07024002400240024020080d00024020070d004101210f0c020b20071021210f0c030b20082007470d010b200721080c020b200f200820071025210f0b20072108200f450d080b200141206a2117200f20026a22072001290000370000200741186a200141186a290000370000200741106a200141106a290000370000200741086a200141086a290000370000200a41606a210a200241206a2102201641606a22160d000b200420083602840420042002360288042004200f360280040b20042802cc09211720042802d409220120044180046a10610240024020010d0020042802880421022004280284042108200428028004210f0c010b20014105742116410020042802880422026b210a200428028004210f200428028404210803402017210102402008200a6a411f4b0d00200241206a22072002490d07200841017422172007201720074b1b22074100480d07024002400240024020080d00024020070d004101210f0c020b20071021210f0c030b20082007470d010b200721080c020b200f200820071025210f0b20072108200f450d080b200141206a2117200f20026a22072001290000370000200741186a200141186a290000370000200741106a200141106a290000370000200741086a200141086a290000370000200a41606a210a200241206a2102201641606a22160d000b200420083602840420042002360288042004200f360280040b2015ad4220862014ad842002ad422086200fad84100e02402008450d00200f10230b02402009450d00201410230b0240200428029808450d0020042802940810230b024020042802e8072202450d0020042802e00721012002410474210203400240200141046a280200450d00200128020010230b200141106a2101200241706a22020d000b0b024020042802e40741ffffffff0071450d0020042802e00710230b024020042802c40941ffffff3f71450d0020042802c00910230b201f41016a211f024020042802d00941ffffff3f71450d0020042802cc0910230b201f203b490d000b0b20044180046a204310ad0320043502880421062004280280042113200441003602d807200442013703d007410410212201450d03200441043602d407200420013602d00720012031360000200441043602d80720014104410810252201450d03200441083602d40720012040410020411b360004200420013602d007200441083602d80720014108412810252201450d03200120042903b001370008200141106a200441b8016a290300370000200141186a200441b0016a41106a290300370000200141206a200441b0016a41186a290300370000200441283602d407200420013602d007200441283602d8072030422088a72201200441d0076a106102402001450d0020014102742116410020042802d80722016b210220042802d40721082032210703402007280200210f02400240200820026a4104490d0020042802d007210a0c010b200141046a220a2001490d0520084101742217200a2017200a4b1b22174100480d050240024020080d00024020170d004101210a0c020b20171021220a450d080c010b20042802d007210a20082017460d00200a200820171025220a450d070b200420173602d4072004200a3602d007201721080b200741046a2107200a20016a200f3600002004200141046a22013602d8072002417c6a21022016417c6a22160d000b0b2023202c200441d0076a10c80320042802d407210120064220862013ad8420043502d80742208620042802d0072202ad84100e02402001450d00200210230b0240200428028404450d00201310230b024020042802f40641ffffff3f71450d0020042802f00610230b0240203042ffffffff0383500d00203210230b0240204241ffffff3f71450d00202310230b200441d0076a41186a22074200370300200441d0076a41106a22084200370300200441d0076a41086a22014200370300200442003703d00741b0dfc300ad4280808080a00184100c22022900002106200441b0066a41086a220a200241086a290000370300200420063703b006200210232001200a290300370300200420042903b0063703d00741fca2c300ad4280808080d00184100c22022900002106200441d0016a41086a220a200241086a290000370300200420063703d00120021023200520042903d001370000200541086a200a29030037000020044180046a41086a200129030037030020044180046a41106a200829030037030020044180046a41186a2007290300370300200420042903d00737038004200441d0076a20044180046a10c9030240024020042802d00722090d00410021102004410036029807200442043703900741042109410021160c010b20042902d4072106200420093602900720042006370294072006422088a721102006a721160b0240024002400240200c450d00201d200c4188026c6a2115200441b0076aad4280808080c00084211e200441b0076a41046a211820044190016a41086a2119200441d0076a410472211141b0dfc300ad4280808080a0018421360340200441d0076a201d280240221310ca0320042802d0072101200420042802d807360284042004200136028004201d280244201d41cc006a28020020044180046a10c802024020042802d407450d00200110230b0240201d2802182217450d00201d280210210120044180046a201310c103200441d0076a2004280280042216200428028804220f10e5014100210720042802d807410020042802d00741014622121b210e200141086a210220042802d40721142017410474220a21080340200228020020076a2107200241106a2102200841706a22080d000b20042007200e6a3602d807200441013602d00720042014410020121b20176a3602d4072004200f3602d401200420163602d0012011200441d0016a10e6010240200428028404450d00201610230b2036100c22022900002106200441b0066a41086a2207200241086a290000370300200420063703b0062002102341f0a1c300ad4280808080a00284100c22022900002106200441d0016a41086a220e200241086a290000370300200420063703d00120021023200420133602b0072004201e100d22022900003703900120021023200441003a00e007200420183602dc07200420193602d4072004200441b0076a3602d807200420044190016a3602d00720044180046a200441d0076a1065200428028804221641206a2202417f4c0d0e200428028004210f0240024002402002450d00200210212212450d0a2002410f4d0d01200221080c020b41102108411010212212450d0b0c010b200241017422084110200841104b1b22084100480d09024020022008470d00200221080c010b20122002200810252212450d0a0b201220042903b006370000201241086a20072903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0920082007460d0020122008200710252212450d0a0b201220042903d001370010201241186a200e29030037000002400240200741606a2016490d002007210e0c010b2016415f4b0d09200741017422082002200820024b1b220e4100480d092007200e460d0020122007200e10252212450d0a0b201241206a200f201610a1051a0240200428028404450d00200f10230b20044180046a2002ad4220862012ad8422061010108b010240024020042802800422070d00410410212202450d09200442043702d407200420023602d0074100200441d0076a106120042802d807210220042802d407210820042802d00721070c010b200428028804210220042802840421080b200420023602b807200420083602b407200420073602b00702400240024002400240024002400240024002400240024002402002450d00200441d0076a200720022017107520042802d0074101460d0420042802d407211620042802dc07220720042802d8072208460d032002200720086b6a220220174102746a2217417f4c0d1b20170d014101210f0c020b2017200441b0076a1061034002402001410c6a2d000022024103714103460d00024002400240024020020e03000102000b410021070c020b410121070c010b410221070b200420073a00f0060240024020042802b40720042802b8072202460d0020042802b00721080c010b200241016a22072002490d17200241017422082007200820074b1b22074100480d170240024020020d0041002102024020070d00410121080c020b200710212208450d1a0c010b20042802b007210820022007460d0020082002200710252208450d1920042802b80721020b200420073602b407200420083602b00720042d00f00621070b200820026a20073a00002004200241016a3602b8070b20012802002116200141086a2802002202200441b0076a10610240024020042802b407221720042802b80722076b2002490d0020042802b00721080c010b200720026a22082007490d162017410174220f2008200f20084b1b220f4100480d160240024020170d000240200f0d00410121080c020b200f10212208450d190c010b20042802b00721082017200f460d0020082017200f10252208450d1820042802b80721070b2004200f3602b407200420083602b0070b200141106a2101200820076a2016200210a1051a2004200720026a22023602b807200a41706a220a0d000c090b0b20171021220f450d120b200420173602b4062004200f3602b006200420023602b8062004200441b0066a3602d0072016200441d0076a200710b20320022007490d0220042802b80622172002490d0320042802b80722172008490d0420042802b006211620042802b007210f2004200220076b22023602e0062004201720086b221736027020022017470d05201620076a200f20086a200210a1051a034002402001410c6a2d000022024103714103460d00024002400240024020020e03000102000b410021070c020b410121070c010b410221070b200420073a00f0060240024020042802b40620042802b8062202460d0020042802b00621080c010b200241016a22072002490d15200241017422082007200820074b1b22074100480d150240024020020d0041002102024020070d00410121080c020b200710212208450d180c010b20042802b006210820022007460d0020082002200710252208450d1720042802b80621020b200420073602b406200420083602b00620042d00f00621070b200820026a20073a00002004200241016a3602b8060b20012802002116200141086a2802002202200441b0066a10610240024020042802b406221720042802b80622076b2002490d0020042802b00621080c010b200720026a22082007490d142017410174220f2008200f20084b1b220f4100480d140240024020170d000240200f0d00410121080c020b200f10212208450d170c010b20042802b00621082017200f460d0020082017200f10252208450d1620042802b80621070b2004200f3602b406200420083602b0060b200141106a2101200820076a2016200210a1051a2004200720026a22023602b806200a41706a220a0d000b20042802b406210720042802b006210120042802b407450d0720042802b00710230c070b2004200441b0076a3602d0072016200441d0076a200810b203034002402001410c6a2d000022024103714103460d00024002400240024020020e03000102000b410021070c020b410121070c010b410221070b200420073a00f0060240024020042802b40720042802b8072202460d0020042802b00721080c010b200241016a22072002490d14200241017422082007200820074b1b22074100480d140240024020020d0041002102024020070d00410121080c020b200710212208450d170c010b20042802b007210820022007460d0020082002200710252208450d1620042802b80721020b200420073602b407200420083602b00720042d00f00621070b200820026a20073a00002004200241016a3602b8070b20012802002116200141086a2802002202200441b0076a10610240024020042802b407221720042802b80722076b2002490d0020042802b00721080c010b200720026a22082007490d132017410174220f2008200f20084b1b220f4100480d130240024020170d000240200f0d00410121080c020b200f10212208450d160c010b20042802b00721082017200f460d0020082017200f10252208450d1520042802b80721070b2004200f3602b407200420083602b0070b200141106a2101200820076a2016200210a1051a2004200720026a22023602b807200a41706a220a450d060c000b0b20042802b407450d0620042802b00710230c060b2007200241c494c6001044000b2002201741c494c6001043000b2008201741d494c6001044000b20044180046a41146a410b3602002004418c046a410d360200200441d0016a41146a41033602002004200441e0066a360290012004200441f0006a3602b001200441d0076a41146a4100360200200442033702d4012004418ca7c7003602d0012004410d360284042004419ca8c7003602e007200442013702d407200441e0a7c7003602d007200420044180046a3602e0012004200441d0076a360290042004200441b0016a36028804200420044190016a36028004200441d0016a419ca8c700103a000b20042802b407210720042802b00721010b02402001450d0020062002ad4220862001ad84100e2007450d00200110230b200e450d010b201210230b41002101024002400240201041014b0d0020100e020201020b20102102034020012002410176220720016a22082013200920084102746a280200491b2101200220076b220241014b0d000b0b02402013200920014102746a2802002202470d0041e084c300ad4280808080c00484100a0c020b20102001201320024b6a2201490d040b02402010200428029407470d0020044190076a20104101107920042802900721090b200920014102746a220241046a2002201020016b41027410a2051a200220133602002004201041016a2210360298070b201d4188026a221d2015470d000b20042802940721160b200441d0076a41186a22024200370300200441d0076a41106a22074200370300200441d0076a41086a22014200370300200442003703d00741b0dfc300ad4280808080a001842206100c220a290000211e200441b0066a41086a2208200a41086a2900003703002004201e3703b006200a102320012008290300370300200420042903b0063703d00741fca2c300ad4280808080d00184221e100c22172900002136200441d0016a41086a220a201741086a290000370300200420363703d00120171023200520042903d001370000200541086a220f200a29030037000020044180046a41086a2213200129030037030020044180046a41106a2212200729030037030020044180046a41186a220e2002290300370300200420042903d00737038004200441203602d407200420044180046a3602d00720092010200441d0076a10d5020240201641ffffffff0371450d00200910230b200242003703002007420037030020014200370300200442003703d0072006100c221729000021062008201741086a290000370300200420063703b0062017102320012008290300370300200420042903b0063703d007201e100c22082900002106200a200841086a290000370300200420063703d00120081023200520042903d001370000200f200a2903003700002013200129030037030020122007290300370300200e2002290300370300200420042903d00737038004200441d0076a20044180046a10c90320042802d0072201410420011b2121024020042902d407420020011b2225422088a722200d00410021150c030b202120204102746a211b200441b0076aad4280808080c000842136200441b0076a41046a211d20044190016a41086a211f200441b0066a41086a2108200441d0076a41067221104100211541002114410021112021210f034020152119200441d0076a200f28020010c10320044180046a20042802d007220a20042802d80710e501200428028004410146210120042802840421022004280288042107024020042802d407450d00200a10230b2002410020011b210e2007410020011b21180240024020140d00410121010c010b200e20146a41e50049201820116a41a19c01497121010b201941016a21150240200e450d002001450d00200441d0076a200f28020010c10320043502d80742208620042802d0072201ad841011024020042802d407450d00200110230b41b0dfc300ad4280808080a00184100c220129000021062008200141086a290000370300200420063703b0062001102341f0a1c300ad4280808080a00284100c22012900002106200441d0016a41086a2213200141086a290000370300200420063703d001200110232004200f2802003602b00720042036100d22012900003703900120011023200441003a00e0072004201d3602dc072004201f3602d4072004200441b0076a3602d807200420044190016a3602d00720044180046a200441d0076a1065200428028804221741206a2202417f4c0d0d20042802800421160240024002402002450d00200210212201450d092002410f4d0d01200221070c020b41102107411010212201450d0a0c010b200241017422074110200741104b1b22074100480d08024020022007470d00200221070c010b20012002200710252201450d090b200120042903b006370000200141086a20082903003700000240024020074170714110460d002007210a0c010b2007410174220a4120200a41204b1b220a4100480d082007200a460d0020012007200a10252201450d090b200120042903d001370010200141186a20132903003700000240200a41606a20174f0d002017415f4b0d08200a41017422072002200720024b1b22074100480d08200a2007460d002001200a200710252201450d090b200141206a2016201710a1051a0240200428028404450d00201610230b200420023602b407200420013602b007200441d0016a2002ad4220862001ad84221e1010108b010240024020042802d00122070d00410021020c010b20042802d401210a200420042802d8013602b406200420073602b006200441d0076a200441b0066a10cb030240024020042802d00722020d00200441003602880420044201370380042004410a360294012004200441b0076a36029001200420044180046a36029007200441013602e407200442013702d40720044180c5c6003602d007200420044190016a3602e00720044190076a4184a5c200200441d0076a10311a20043502880442208620043502800484100a200428028404450d0120042802800410230c010b20042902d40721060b0240200a450d00200710230b024020020d00410021020c010b201e10110b200110232002410420021b221a2006420020021b2206422088a722014104746a210702400240024020010d00201a21010c010b201a2101034002402001410c6a2d000022134103470d00200141106a21010c020b200141046a280200210a20012802002102200141086a28020021172004200f280200221636029001200420173602b401200420023602b001200441d0016a200441b0016a109903024020042802d0014116460d0020044180046a200441d0016a41b00210a1051a4101211702400240024020134103710e03010200010b41002117410021120c010b200441d0076a20044190016a10af02200441b0076a41086a201041086a290100370300200441b0076a41106a201041106a290100370300200441b0076a41186a201041186a2f01003b0100200420102901003703b00720042801d207211620042f01d007210941012112410021170b200441d0076a20044180046a41b00210a1051a200820042903b007370200200841086a200441b0076a41086a290300370200200841106a200441b0076a41106a290300370200200841186a200441b0076a41186a280200360200200420163602b406200420093b01b206200420123a00b106200420173a00b00620044190076a200441d0076a200441b0066a10cf020b0240200a450d00200210230b200141106a22012007470d000c020b0b20072001460d000340200141106a21020240200141046a280200450d00200128020010230b2002210120072002470d000b0b0240200642ffffffff0083500d00201a10230b200e20146a221441e3004b0d03201820116a2211419f9c014b0d030b200f41046a220f201b470d000c020b0b200120101038000b20192020490d0020152020418485c3001044000b200441d0076a41186a22074200370300200441d0076a41106a22084200370300200441d0076a41086a22014200370300200442003703d00741b0dfc300ad4280808080a00184100c22022900002106200441b0066a41086a220a200241086a290000370300200420063703b006200210232001200a290300370300200420042903b0063703d00741fca2c300ad4280808080d00184100c22022900002106200441d0016a41086a220a200241086a290000370300200420063703d00120021023200520042903d001370000200541086a200a29030037000020044180046a41086a200129030037030020044180046a41106a200829030037030020044180046a41186a2007290300370300200420042903d00737038004202020156b220241027441046a2201417f4c0d080240024020010d00410121070c010b200110212207450d020b200441003602d807200420013602d407200420073602d0072002200441d0076a10610240024020020d0020042802d807210120042802d407211720042802d007210a0c010b202120154102746a2107202041027420154102746b2116410020042802d80722016b210820042802d407210203402007280200210f02400240200220086a4104490d0020042802d007210a200221170c010b200141046a220a2001490d0520024101742217200a2017200a4b1b22174100480d050240024020020d00024020170d004101210a0c020b20171021220a450d080c010b20042802d007210a20022017460d00200a200220171025220a450d070b200420173602d4072004200a3602d007201721020b200741046a2107200a20016a200f3600002004200141046a22013602d8072008417c6a21082016417c6a22160d000b0b20044180046aad42808080808004842001ad422086200aad84100e02402017450d00200a10230b0240202542ffffffff0383500d00202110230b200428024821022004280240210f200428024421010b200441d0076a41186a220a4200370300200441d0076a41106a22174200370300200441d0076a41086a22074200370300200442003703d00741b0dfc300ad4280808080a00184100c22082900002106200441b0066a41086a2216200841086a290000370300200420063703b0062008102320072016290300370300200420042903b0063703d00741a89ec700ad4280808080900184100c22082900002106200441d0016a41086a2216200841086a290000370300200420063703d00120081023200520042903d001370000200541086a201629030037000020044180046a41086a200729030037030020044180046a41106a201729030037030020044180046a41186a200a290300370300200420042903d00737038004200441203602d407200420044180046a3602d007200f2002200441d0076a10d5020240200141ffffffff0371450d00200f10230b200041043a00000240200da72201450d002001412c6c450d00200b10230b200328020021070240200c450d00200c4188026c2102200721010340200110a20320014188026a2101200241f87d6a22020d000b0b200341046a2802002201450d0620014188026c450d06200710230c060b1033000b102c000b102a000b20004183203b0100200041086a4115360200200041046a4187ffc200360200200041026a41013a00000b200da72201450d002001412c6c450d00200b10230b20032802002107024020032802082201450d0020014188026c2102200721010340200110a20320014188026a2101200241f87d6a22020d000b0b200341046a2802002201450d0020014188026c450d00200710230b200441b00a6a24000f0b1032000bad3409057f017e017f017e027f027e097f037e077f230041d0036b2203240020012800002104200341186a41186a2001411c6a290000370300200341186a41106a200141146a290000370300200341186a41086a2001410c6a290000370300200320012900043703182002280200210520034198036a41186a2206420037030020034198036a41106a2207420037030020034198036a41086a22014200370300200342003703980341db97c700ad4280808080f000842208100c2209290000210a2001200941086a2900003703002003200a370398032009102341bcbcc300ad4280808080c00184100c2209290000210a200341d8006a41086a220b200941086a2900003703002003200a3703582009102320072003290358220a370300200341f8026a41086a220c2001290300370300200341f8026a41106a200a370300200341f8026a41186a200b29030037030020032003290398033703f802200341106a200341f8026a412010cd01410021090240024002400240024002400240024002400240024002400240024020052003280214410020032802101b460d002008100c2201290000210a200341d0016a41086a200141086a2900003703002003200a3703d0012001102341e297c700ad4280808080a00284100c2201290000210a200c200141086a2900003703002003200a3703f80220011023200320053602bc032003200341bc036aad4280808080c00084100d22012900003703c00320011023200341d8006a410c6a200341c0036a360200200341003a00682003200341c0036a41086a36025c2003200341bc036a3602602003200341c0036a360258200341386a200341d8006a10652003280240220741206a2201417f4c0d042003280238210c024002402001450d0020011021220b450d052001410f4d0d01200121050c040b200141017422094110200941104b1b22051021220b0d030c0e0b200141017422094110200941104b1b220541004e0d010c0c0b200b4120360200200320043602582003200341186a36025c200341f0016a200341d8006a108803200341d8006a20032802f001220520032802f80110e1012001200341e1006a2900003703002007200341e9006a2900003703002006200341f1006a2900003703002003200329005937039803024020032d00584101470d00200341f8026a41186a20034198036a41186a290300370300200341f8026a41106a20034198036a41106a290300370300200341f8026a41086a20034198036a41086a29030037030020032003290398033703f802410121090b024020032802f401450d00200510230b0240024020090d00200041003602400c010b20034198036a41186a2201200341f8026a41186a290300220a37030020034198036a41106a2209200341f8026a41106a290300220837030020034198036a41086a2205200341f8026a41086a290300220d370300200320032903f802220e37039803200341d8006a41186a2207200a370300200341d8006a41106a220b2008370300200341d8006a41086a2206200d3703002003200e370358200341f0016a200341d8006a108f02200341c8026a41186a220c2001290300370300200341c8026a41106a22012009290300370300200341c8026a41086a2209200529030037030020032003290398033703c80202402003280290020d00200041003602400c010b2007200c290300370300200b200129030037030020062009290300370300200341d8006a41286a200341f0016a41086a29030037030020034188016a200341f0016a41106a29030037030020034190016a200341f0016a41186a29030037030020034198016a20034190026a290300370300200341a0016a200341f0016a41286a290300370300200320032903c802370358200320032903f0013703782000200341d8006a41d00010a1051a0b2002410c6a280200210f200228020421100c080b20012005460d00200b200120051025220b450d0b0b200b20032903d001370000200b41086a200341d0016a41086a2903003700000240024020054170714110460d00200521090c010b200541017422094120200941204b1b22094100480d0a20052009460d00200b200520091025220b450d0b0b200b20032903f802370010200b41186a200341f8026a41086a29030037000002400240200941606a2007490d00200921060c010b200741206a22052007490d0a200941017422062005200620054b1b22064100480d0a20092006460d00200b200920061025220b450d0b0b200b41206a200c200710a1051a0240200328023c450d00200c10230b200320013602c4032003200b3602c003200341d0016a2001ad422086200bad841010108b010240024020032802d00122050d00410021010c010b200341d8016a280200210720032802d401210c41002101200341003a0078024002400240034020072001460d01200341d8006a20016a200520016a2d00003a00002003200141016a22093a00782009210120094120470d000b200341f8026a41186a2201200341d8006a41186a290300370300200341f8026a41106a2211200341d8006a41106a290300370300200341f8026a41086a2212200341d8006a41086a290300370300200320032903583703f802200720096b41034d0d01200341f0016a41186a2001290300370300200341f0016a41106a2011290300370300200341f0016a41086a2012290300370300200320032903f8023703f001410121010c020b200141ff0171450d00200341003a00780b410021012003410036028003200342013703f8022003410a36023c2003200341c0036a3602382003200341f8026a3602bc03200341ec006a41013602002003420137025c20034180c5c6003602582003200341386a360268200341bc036a4184a5c200200341d8006a10311a20033502800342208620033502f80284100a20032802fc02450d0020032802f80210230b200c450d00200510230b200341d8006a41186a2209200341f0016a41186a290300370300200341d8006a41106a2205200341f0016a41106a290300370300200341d8006a41086a2207200341f0016a41086a290300370300200320032903f0013703582001450d07200341c8026a41186a2009290300370300200341c8026a41106a2005290300370300200341c8026a41086a2007290300370300200320032903583703c80202402006450d00200b10230b20034198036a41086a200341c8026a41086a290300220a37030020034198036a41106a200341c8026a41106a290300220837030020034198036a41186a200341c8026a41186a290300220d370300200320032903c802220e37039803200341386a41186a200d370300200341386a41106a2008370300200341386a41086a200a3703002003200e370338200341d0016a41186a200d370300200341d0016a41106a2008370300200341d0016a41086a200a3703002003200e3703d0012002410c6a280200210f20022802042110410110212209450d00200941003a000041004100350280804042adfed5e4d485fda8d8007e200341d8006aad7c421f89220a3e02808040200341d8006a41186a220541eedcc400ad428080808010841018220141186a290000370300200341d8006a41106a2207200141106a290000370300200341d8006a41086a220b200141086a2900003703002003200129000037035820011023200341f0016a41206a4100360200200341f0016a41186a420437030020034184026a419ca1c000360200200341f0016a412c6a428180808010370200200341ac026a200b290300370200200341b4026a2007290300370200200341bc026a200529030037020020034100360280022003200a3703f8012003418080c000ad3703f0012003200936029802200320032903583702a4020240200f450d002010200f410c6c6a2113200341f0016a41106a2114200341d8006a41077221152010210c0340200c2802082205417f4c0d03200c2802002101410021090240024020050d00410121074100210b0c010b2005210b200510212207450d030b20072001200510a10521070240200520032802a002470d00024020032802980222092007470d00410121090c010b20072009200510a3054521090b0240200b450d00200710230b024020090d0020034198036a41186a22072005ad4220862001ad841018220941186a29000037030020034198036a41106a220b200941106a29000037030020034198036a41086a2206200941086a290000370300200320092900003703980320091023200341c8026a41186a22112007290300370300200341c8026a41106a2207200b290300370300200341c8026a41086a220b200629030037030020032003290398033703c8020240024020050d0041012109410021160c010b20052116200510212209450d040b20092001200510a1052117024002400240200520032802a002470d0020032802980222012017460d0120172001200510a305450d010b200320032903f801220d20032903f001220a852208200a4218898520084210868520084225897c220842a0cbbf9599b5a19f0a7c220e201129030022188520032903c8022219200e8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85200b290300220e200842efcdddd088a580a21e7c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852007290300221a200842bed0fb8bf894dfa4327c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85420042adfed5e4d485fda8d800420010a605200341d8006a41186a221b2018370300200341d8006a41106a221c201a370300200341d8006a41086a221d200e37030020032019370358200341086a29030020032903007c200d200a7c85220a421988a741ff0071221e410874201e722201411074200172211f200328028002220b200aa72220712107410021212003280288022106200328028402211203400240201220076a2800002211201f732201417f73200141fffdfb776a71418081828478712201450d0002400340200620016841037620076a200b7141306c6a2209200341d8006a460d012009200341d8006a412010a305450d012001417f6a2001712201450d020c000b0b200341f8026a41186a201541186a2d00003a0000200341f8026a41106a201541106a290000370300200341f8026a41086a201541086a290000370300200320152900003703f80202402009412c6a2201280200220741004a0d00200941206a210b0240200941246a2206280200450d00200b2802001023200128020021070b20062016360200200b20173602002001200741016a360200200941286a20053602000c050b2001200741016a3602002016450d040c030b202141046a222120076a200b712107201120114101747141808182847871450d000b200341f8026a41186a201b290300220a370300200341f8026a41106a201c2903002208370300200341f8026a41086a201d290300220d37030020032003290358220e3703f8022003200341f0016a3602bc03201b200a370300201c2008370300201d200d3703002003200e37035841002101202021090340200141046a22012009200b7122076a2109201220076a280000418081828478712206450d000b0240201220066841037620076a200b7122016a2c000022094100480d0020122012280200418081828478716841037622016a2d000021090b024020094101712207450d00200328028c020d00200341c0036a2014200341bc036a10dc02410021012003280284022112200328028002210b0340200141046a22012020200b7122096a2120201220096a280000418081828478712206450d000b201220066841037620096a200b7122016a2c00004100480d002012280200418081828478716841037621010b2003200328028c0220076b36028c022003280288022109201220016a201e3a00002001417c6a200b7120126a41046a201e3a00002009200141306c6a2201410136022c200120053602282001201636022420012017360220200141186a201b290300370200200141106a201c290300370200200141086a201d29030037020020012003290358370200200320032802900241016a360290020c020b2016450d010b201710230b200c410c6a220c2013470d000b0b200341d8006a200341f0016a41d80010a1051a200341c8016a200341d0016a41186a290300370300200341c0016a200341d0016a41106a290300370300200341b8016a200341d0016a41086a290300370300200320032903d0013703b001024002400240200341d8006a41d8006a22012003418c016a412010a305450d00200341f0016a41186a200141186a290000370300200341f0016a41106a200141106a290000370300200341f0016a41086a200141086a290000370300200320012900003703f001200341d8006a200341f0016a10ce042209450d01200928020c4101480d010b412410212209450d0220092004360000200320093602f001200342a4808080c0003702f4014120200341f0016a10610240024020032802f401220720032802f80122056b4120490d0020032802f00121092007210b0c010b200541206a22092005490d0c2007410174220b2009200b20094b1b220b4100480d0c0240024020070d000240200b0d00410121090c020b200b10212209450d0f0c010b20032802f00121092007200b460d0020092007200b10252209450d0e0b2003200b3602f401200320093602f0010b200920056a22072003290318370000200741186a200341186a41186a290300370000200741106a200341186a41106a290300370000200741086a200341186a41086a290300370000200341f0016a41106a200141086a290200370300200341f0016a41186a200141106a290200370300200341f0016a41206a200141186a290200370300200341f497c7003602f401200320012902003703f8012003200341d8006a3602f001200341003602a0032003200541206a36029c032003200936029803200341c8026a200341f0016a20034198036a1099050240200b450d00200910230b20032802c8024101470d01024020032802cc0222012d0000220941034b0d00024020090e0407070007070b200141086a280200450d06200141046a28020010230c060b200141286a280200450d05200141246a28020010230c050b200041003602400c060b20032802cc022209450d0402400240200341d0026a290300220a422088a741044f0d0041012105410021070c010b20092800002107410021050b0240200aa7450d00200910230b20050d04200320073602f802200341f0016a41106a200141086a290200370300200341f0016a41186a200141106a29020037030020034190026a200141186a290200370300200341f497c7003602f401200320012902003703f8012003200341d8006a3602f0012003420437029c032003200341f8026a36029803200341c8026a200341f0016a20034198036a109905024020032802c8024101470d00024020032802cc0222012d0000220941034b0d00024020090e0405050005050b200141086a280200450d04200141046a28020010230c040b200141286a280200450d03200141246a28020010230c030b024020032802cc0222050d00200041003602400c060b200341c8026a41086a290300210a200320053602d0012003200a422088a722073602d40141002101200341003a00e802024002400240034020072001460d01200341c8026a20016a200520016a22092d00003a00002003200941016a3602d0012003200141016a22093a00e8022009210120094120470d000b200341f8026a41086a2201200341c8026a41086a220b290300370300200341f8026a41106a2206200341c8026a41106a220c290300370300200341f8026a41186a2211200341c8026a41186a22122903003703002003200720096b3602d401200320032903c8023703f802200341c8026a200341d0016a10d00120032802e8022209450d01200341f0016a41186a22072011290300370300200341f0016a41106a22112006290300370300200341f0016a41086a22062001290300370300200341f0016a41286a2201200b290300370300200341f0016a41306a220b200c290300370300200341f0016a41386a220c201229030037030020034198036a41086a2212200341f4026a280200360200200320032903f8023703f001200320032903c802370390022003200341ec026a29020037039803200041386a200c290300370300200041306a200b290300370300200041286a2001290300370300200041206a200329039002370300200041186a2007290300370300200041106a2011290300370300200041086a2006290300370300200020032903f001370300200020093602402000200329039803370244200041cc006a20122802003602000c020b200341003602d401200141ff0171450d00200341003a00e8020b200041003602400b200aa7450d05200510230c050b1033000b1032000b20011023200041003602400c020b200110230b200041003602400b024020032802682205450d00200341ec006a280200220941046a2101200520096a41016a21072009280200417f7341808182847871210b200341f0006a28020021090240034002400240200b450d00200b21050c010b0340200120074f0d03200941c0016a210920012802002105200141046a220b21012005418081828478712205418081828478460d000b2005418081828478732105200b21010b2005417f6a200571210b200920056841037641306c6a220541246a280200450d00200528022010230c000b0b02402003280268220141086a200141056a490d00200141016aad42307e422088a71a0b200328026c10230b20034184016a280200450d0020032802800110230b0240200f450d00200f410c6c21092010210103400240200141046a280200450d00200128020010230b2001410c6a2101200941746a22090d000b0b200241086a2802002201450d012001410c6c450d01201010230c010b02402006450d00200b10230b200041003602402002280204210502402002410c6a2802002201450d002001410c6c21092005210103400240200141046a280200450d00200128020010230b2001410c6a2101200941746a22090d000b0b200241086a2802002201450d002001410c6c450d00200510230b200341d0036a24000f0b102c000b102a000bb10203027f017e027f230041106b220224000240024020012802082203ad42307e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510212206450d020b20024100360208200220063602002002200541306e36020420024100200310a4012002280208210502402003450d002001200341306c6a21062002280200200541306c6a21030340200320012903003703002003200141086a290300370308200341106a200141106a290300370300200341186a200141186a290300370300200341206a200141206a290300370300200341286a200141286a290300370300200341306a2103200541016a2105200141306a22012006470d000b0b20002002290300370200200041086a2005360200200241106a24000f0b1032000b1033000b930503027f017e057f230041d0006b220224004189e3c400ad4280808080800184100c22032900002104200241086a200341086a290000370300200220043703002003102341ac94c500ad4280808080a00284100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240411010212203450d0020032001290000370000200341086a200141086a29000037000020022003ad4280808080800284100d220129000037033020011023200241c4006a200341106a360200200241003a0048200220033602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200310232002280228220541206a2201417f4c0d0120022802202106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000b9a0302057f017e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841010108b010240024002400240200328021022010d00200041003602000c010b200328021421022003200341186a280200360224200320013602202003200341206a10880102400240024020032802000d002003280224220420032802042205490d002005417f4c0d040240024020050d00410121060c010b200510272206450d06200620032802202207200510a1051a2003200420056b3602242003200720056a3602200b20060d010b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034180c5c6003602482003200341386a360258200341c4006a4184a5c200200341c8006a10311a2003350230422086200335022884100a0240200328022c450d00200328022810230b200041003602000c010b20002005ad2208422086200884370204200020063602000b2002450d00200110230b200341e0006a24000f0b1032000b1033000bec0403037f017e087f230041e0006b220224002002200110880102400240024002402002280200450d00200041003602000c010b20022802042203200128020441246e2204200420034b1bad42247e2205422088a70d012005a72204417f4c0d010240024020040d00410421060c010b200410212206450d030b4100210720024100360210200220063602082002200441246e36020c0240024002402003450d00410021080340200128020422094104490d03200841016a21082001280200220a280000210b20012009417c6a220c3602042001200a41046a36020041002104200241003a00582009417b6a21090340200c2004460d03200241386a20046a200a20046a220d41046a2d00003a0000200120093602042001200d41056a3602002002200441016a220d3a00582009417f6a2109200d2104200d4120470d000b200241186a41186a2209200241386a41186a290300370300200241186a41106a220d200241386a41106a290300370300200241186a41086a220a200241386a41086a2903003703002002200229033837031802402007200228020c470d00200241086a2007410110a20120022802082106200228021021070b2006200741246c6a2204200b360200200420022903183702042004410c6a200a290300370200200441146a200d2903003702002004411c6a20092903003702002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c020b200441ff0171450d00200241003a00580b20004100360200200228020c2204450d00200441246c450d00200610230b200241e0006a24000f0b1032000b1033000b9c0603027f017e077f230041d0006b220324004189e3c400ad4280808080800184100c22042900002105200341086a200441086a29000037030020032005370300200410234198e3c400ad4280808080e00284100c22042900002105200341106a41086a200441086a2900003703002003200537031020041023024002400240024002400240411010212204450d0020042001290000370000200441086a200141086a29000037000020032004ad4280808080800284100d220129000037033020011023200341c4006a200441106a360200200341003a0048200320043602402003200341306a41086a36023c2003200341306a360238200341206a200341386a106520041023200341386a20022802002002280208109e042003280228220641206a2207200328024022086a2201417f4c0d01200328023821092003280220210a024002402001450d00200110212204450d022001410f4d0d012001210b0c050b200141017422044110200441104b1b220b102122040d040c060b200141017422024110200241104b1b220b41004e0d020c040b1033000b1032000b2001200b460d0020042001200b10252204450d020b20042003290300370000200441086a200341086a29030037000002400240200b4170714110460d00200b21020c010b200b41017422024120200241204b1b22024100480d01200b2002460d002004200b200210252204450d020b20042003290310370010200441186a200341106a41086a29030037000002400240200241606a2006490d002002210b0c010b200641206a220b2006490d012002410174220c200b200c200b4b1b220b4100480d012002200b460d0020042002200b10252204450d020b200441206a200a200610a1051a02400240200b20076b2008490d00200b21020c010b200720086a2007490d01200b41017422022001200220014b1b22024100480d01200b2002460d002004200b200210252204450d020b200420076a2009200810a1051a2000200136020820002002360204200020043602000240200328023c450d00200910230b02402003280224450d00200a10230b200341d0006a24000f0b102c000b102a000bc30802077f037e230041106b220224000240024002400240024002402001280208220341146a2204417f4c0d0002402004450d00200410212205450d022002410036020820022005360200200220043602042004410f4b0d04200441017422064110200641104b1b22064100480d0520042006460d0320052004200610252205450d060c030b200241003602082002410136020020022004360204200441017422044110200441104b1b2206102122050d020c050b1032000b1033000b20022006360204200220053602000b2005200129000c370000200541086a200141146a29000037000020024110360208200128020021072003200210610240024020022802042208200228020822066b2003490d0020022802002104200821050c010b200620036a22042006490d01200841017422052004200520044b1b22054100480d010240024020080d00024020050d00410121040c020b200510212204450d040c010b2002280200210420082005460d0020042008200510252204450d030b20022005360204200220043602000b200420066a2007200310a1051a2002200620036a2206360208200128021c210302400240200520066b4120490d00200641206a21080c010b200641206a22082006490d01200541017422012008200120084b1b22014100480d010240024020050d00024020010d00410121040c020b200110212204450d040c010b20052001460d0020042005200110252204450d030b20022001360204200220043602000b200420066a22012003290000370000200141186a200341186a290000370000200141106a200341106a290000370000200141086a200341086a290000370000200220083602082002200341206a36020c2002410c6a200210db012002200341306a36020c2002410c6a200210db01200341c0006a2802002101200341c8006a28020022032002106102402003450d00200341306c210603400240024020022802042205200228020822036b4120490d00200228020021040c010b200341206a22042003490d03200541017422082004200820044b1b22084100480d030240024020050d00024020080d00410121040c020b200810212204450d060c010b2002280200210420052008460d0020042005200810252204450d050b20022008360204200220043602000b200420036a2204200141106a290000370000200441186a200141286a290000370000200441106a200141206a290000370000200441086a200141186a2900003700002002200341206a3602082002200136020c2002410c6a200210db01200141306a2101200641506a22060d000b0b20022802042103200235020842208620022802002204ad84101822012900002109200141086a290000210a200141106a290000210b200041186a200141186a290000370000200041106a200b370000200041086a200a370000200020093700002001102302402003450d00200410230b200241106a24000f0b102c000b102a000bae0503027f017e047f230041d0006b220224004189e3c400ad4280808080800184100c22032900002104200241086a200341086a29000037030020022004370300200310234191e3c400ad4280808080f00084100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad4280808080800484100d220129000037033020011023200241c4006a200341206a360200200241003a0048200220033602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200310232002280228220541206a2201417f4c0d0120022802202106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bbc0601087f230041106b2202240020024100360208200242013703000240412010212203450d00200241203602042002200336020020032000290000370000200341086a200041086a290000370000200341106a200041106a290000370000200341186a200041186a290000370000200241203602082002200041206a36020c2002410c6a200210db012002200041306a36020c2002410c6a200210db01200041c0006a2802002103200041c8006a280200220420021061024002402004450d00200441306c210503400240024020022802042206200228020822046b4120490d00200441206a2107200228020021080c010b200441206a22072004490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009102122080d010c060b2002280200210820062009460d0020082006200910252208450d050b20022009360204200220083602000b200820046a2204200341106a290000370000200441186a200341286a290000370000200441106a200341206a290000370000200441086a200341186a290000370000200220073602082002200336020c2002410c6a200210db01200341306a2103200541506a22050d000b0b20002802502103200041d8006a2802002204200210610240024020040d002002280208210420022802042109200228020021050c010b200441057421004100200228020822046b210620022802042108034002400240200820066a4120490d0020022802002105200821090c010b200441206a22072004490d03200841017422052007200520074b1b22094100480d030240024020080d00024020090d00410121050c020b200910212205450d060c010b2002280200210520082009460d0020052008200910252205450d050b2002200936020420022005360200200921080b200520046a22072003290000370000200741186a200341186a290000370000200741106a200341106a290000370000200741086a200341086a2900003700002002200441206a2204360208200641606a2106200341206a2103200041606a22000d000b0b20012902002004ad4220862005ad84100e02402009450d00200510230b200241106a24000f0b102c000b102a000bc017021b7f057e23004180046b22032400024002400240024020012002460d00200341d4036a21040340200341f0036a200110bb0320034190036a20032802f003220520032802f80310b304200341d0026a41086a220620034190036a41086a290300370300200341d0026a41106a220720034190036a41106a290300370300200341d0026a41186a220820034190036a41186a290300370300200341d0026a41206a220920034190036a41206a290300370300200341d0026a41286a220a20034190036a41286a290300370300200341d0026a41306a220b20034190036a41306a290300370300200341d0026a41386a220c20034190036a41386a290300370300200341b0026a41086a220d200441086a290200370300200341b0026a41106a220e200441106a290200370300200341b0026a41186a220f200441186a28020036020020032003290390033703d002200320042902003703b002024020032802d0032210450d00200341f0016a41386a200c290300370300200341f0016a41306a200b290300370300200341f0016a41286a200a290300370300200341f0016a41206a2009290300370300200341f0016a41186a2008290300370300200341f0016a41106a2007290300370300200341f0016a41086a2006290300370300200341d0016a41086a200d290300370300200341d0016a41106a200e290300370300200341d0016a41186a200f280200360200200320032903d0023703f001200320032903b0023703d0010b024020032802f403450d00200510230b20100d022002200141206a2201470d000b0b20004100360208200042083702000c010b200341306a41386a2204200341f0016a41386a290300370300200341306a41306a2205200341f0016a41306a290300370300200341306a41286a2206200341f0016a41286a290300370300200341306a41206a2207200341f0016a41206a290300370300200341306a41186a2208200341f0016a41186a290300370300200341306a41106a2209200341f0016a41106a290300370300200341306a41086a220a200341f0016a41086a290300370300200341106a41086a220b200341d0016a41086a290300370300200341106a41106a220c200341d0016a41106a290300370300200341106a41186a220d200341d0016a41186a280200360200200320032903f001370330200320032903d00137031020034190016a41086a220e200a29030037030020034190016a41106a220a200929030037030020034190016a41186a2209200829030037030020034190016a41206a2208200729030037030020034190016a41286a2207200629030037030020034190016a41306a2206200529030037030020034190016a41386a22052004290300370300200341f0006a41086a2204200b290300370300200341f0006a41106a220b200c290300370300200341f0006a41186a220c200d28020036020020032003290330370390012003200329031037037020034190036a41086a220d200e29030037030020034190036a41106a220e200a29030037030020034190036a41186a220a200929030037030020034190036a41206a2209200829030037030020034190036a41286a2208200729030037030020034190036a41306a2207200629030037030020034190036a41386a22062005290300370300200320032903900137039003200341d0026a41086a22052004290300370300200341d0026a41106a2204200b290300370300200341d0026a41186a220b200c280200360200200320032903703703d00241e00010212211450d01201120032903900337030020112010360240201120032903d002370244201141386a2006290300370300201141306a2007290300370300201141286a2008290300370300201141206a2009290300370300201141186a200a290300370300201141106a200e290300370300201141086a200d290300370300201141cc006a2005290300370200201141d4006a2004290300370200201141dc006a200b2802003602002003428180808010370204200320113602000240200241606a2001460d00200141206a2109200241606a211220034190036a41c4006a2104410121130340200921010340200341f0036a200110bb0320034190036a20032802f003220820032802f80310b304200341d0026a41086a220520034190036a41086a2214290300370300200341d0026a41106a220620034190036a41106a2215290300370300200341d0026a41186a220720034190036a41186a2216290300370300200341d0026a41206a220920034190036a41206a2217290300370300200341d0026a41286a220a20034190036a41286a2218290300370300200341d0026a41306a220b20034190036a41306a2219290300370300200341d0026a41386a220c20034190036a41386a221a290300370300200341b0026a41086a220d200441086a290200370300200341b0026a41106a220e200441106a290200370300200341b0026a41186a220f200441186a28020036020020032003290390033703d002200320042902003703b002024020032802d0032210450d00200341f0016a41386a200c290300370300200341f0016a41306a200b290300370300200341f0016a41286a200a290300370300200341f0016a41206a2009290300370300200341f0016a41186a2007290300370300200341f0016a41106a2006290300370300200341f0016a41086a2005290300370300200341d0016a41086a200d290300370300200341d0016a41106a200e290300370300200341d0016a41186a200f280200360200200320032903d0023703f001200320032903b0023703d0010b024020032802f403450d00200810230b024020100d002002200141206a2201470d010c030b0b200341306a41386a2208200341f0016a41386a290300370300200341306a41306a2209200341f0016a41306a290300370300200341306a41286a220a200341f0016a41286a290300370300200341306a41206a220b200341f0016a41206a290300370300200341306a41186a220c200341f0016a41186a290300370300200341306a41106a220d200341f0016a41106a290300370300200341306a41086a220e200341f0016a41086a290300370300200341106a41086a220f200341d0016a41086a290300370300200341106a41106a221b200341d0016a41106a290300370300200341106a41186a221c200341d0016a41186a280200360200200320032903f001370330200320032903d00137031020034190016a41086a221d200e29030037030020034190016a41106a220e200d29030037030020034190016a41186a220d200c29030037030020034190016a41206a220c200b29030037030020034190016a41286a220b200a29030037030020034190016a41306a220a200929030037030020034190016a41386a22092008290300370300200341f0006a41086a2208200f290300370300200341f0006a41106a220f201b290300370300200341f0006a41186a221b201c2802003602002003200329033037039001200320032903103703702014201d2903003703002015200e2903003703002016200d2903003703002017200c2903003703002018200b2903003703002019200a290300370300201a2009290300370300200320032903900137039003200520082903003703002006200f2903003703002007201b280200360200200320032903703703d002024020132003280204470d00200320134101109601200328020021110b200141206a21092011201341e0006c6a2208200329039003370300200841106a2015290300370300200841086a20142903003703002019290300211e201a290300211f201829030021202017290300212120162903002122200841c0006a2010360200200841186a2022370300200841206a2021370300200841286a2020370300200841c4006a20032903d002370200200841386a201f370300200841306a201e370300200841cc006a2005290300370200200841d4006a2006290300370200200841dc006a20072802003602002003201341016a221336020820122001470d000b0b20002003290300370200200041086a200341086a2802003602000b20034180046a24000f0b1033000bef04010a7f230041106b220324000240024002400240200241246c41046a2204417f4c0d000240024020040d00410121050c010b200410212205450d020b20034100360208200320043602042003200536020020022003106102402002450d002001200241246c6a2106200328020421052003280208210203402001280200210402400240200520026b4104490d0020032802002107200521080c010b200241046a22082002490d05200541017422072008200720084b1b22084100480d050240024020050d00024020080d00410121070c020b2008102122070d010c080b2003280200210720052008460d0020072005200810252207450d070b20032008360204200320073602000b200720026a20043600002003200241046a2209360208412010212204450d03200441186a220a2001411c6a290000370000200441106a220b200141146a290000370000200441086a220c2001410c6a2900003700002004200141046a29000037000002400240200820096b4120490d00200241246a2102200821050c010b200941206a22022009490d05200841017422052002200520024b1b22054100480d050240024020080d00024020050d00410121070c020b200510212207450d080c010b20082005460d0020072008200510252207450d070b20032005360204200320073602000b200720096a22082004290000370000200841186a200a290000370000200841106a200b290000370000200841086a200c2900003700002003200236020820041023200141246a22012006470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1032000b1033000b102c000b102a000be503010a7f230041106b22032400024020014105744104722204417f4c0d000240200410212205450d002003410036020820032004360204200320053602002001200310610240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020052104412010212201450d0220012000290000370000200141186a2209200041186a290000370000200141106a220a200041106a290000370000200141086a220b200041086a29000037000002400240200620046b4120490d00200441206a21050c010b024002400240200441206a22052004490d002006410174220c2005200c20054b1b220c4100480d000240024020060d000240200c0d00410121070c020b200c102121070c040b2006200c470d020b200c21060c030b102c000b20072006200c102521070b200c210620070d00102a000b200041206a2100200720046a22042001290000370000200441186a2009290000370000200441106a200a290000370000200441086a200b29000037000020011023200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100e02402006450d00200710230b200341106a24000f0b1033000b1032000bf70b04047f017e077f077e23004180016b220524004101210602400240024020002001200220032004108702450d00200541e0006a41186a4200370300200541e0006a41106a22074200370300200541e0006a41086a22064200370300200542003703604189e3c400ad4280808080800184100c220829000021092006200841086a29000037030020052009370360200810234193e4c400ad4280808080800284100c22082900002109200541c0006a41086a220a200841086a2900003703002005200937034020081023200720052903402209370300200541206a41086a2006290300370300200541206a41106a2009370300200541206a41186a200a29030037030020052005290360370320200541e0006a200541206a10ef03024002402005280260220b0d004100210c20054100360208200542043703004104210b4100210d0c010b2005200529026422093702042005200b3602002009422088a7210d2009a7210c0b2001ad42e0007e2209422088a70d012009a72206417f4c0d010240024020060d00410821080c010b200610212208450d030b20054100360218200520083602102005200641e0006e360214200541106a410020011096012005280218210e02402001450d002000200141e0006c6a210f2005280210200e41e0006c6a2106200141057441606a4105762110200541246a21010340200541e0006a41086a2208200041086a290300370300200541e0006a41106a2207200041106a290300370300200541e0006a41186a220a200041186a29030037030020052000290300370360200041206a2903002109200041286a2903002111200041306a2903002112200041386a2903002113200541d0006a200041c0006a10b503200541c0006a200041d0006a108e02200141086a200541c0006a41086a28020036020020012005290340370200200a2903002114200729030021152008290300211620052903602117200641386a2013370300200641306a2012370300200641286a2011370300200641206a2009370300200641086a201637030020062017370300200641106a2015370300200641c0006a2005290350370300200641c8006a200541d0006a41086a280200360200200641186a2014370300200641cc006a2005290220370200200641d4006a200541206a41086a290200370200200641e0006a2106200041e0006a2200200f470d000b200e20106a41016a210e0b200541e8006a200e36020020052005290310370360200341ffffffff03712003470d0120034102742206417f4c0d010240024020060d00410421000c010b200610212200450d030b200541003602282005200036022020052006410276360224200541206a4100200310792005280220200528022822064102746a2002200341027410a1051a200541c0006a41086a2201200620036a2206360200200541f4006a20063602002005200529032037026c0240200d200c470d002005200d410110a3012005280204210c2005280200210b2005280208210d0b200b200d411c6c6a22062005290360370200200541e0006a41086a22002903002109200541e0006a41106a2208290300211120062004360218200641106a2011370200200641086a20093702002005200d41016a2207360208200541e0006a41186a42003703002008420037030020004200370300200542003703604189e3c400ad4280808080800184100c220629000021092000200641086a29000037030020052009370360200610234193e4c400ad4280808080800284100c220629000021092001200641086a2900003703002005200937034020061023200820052903402209370300200541206a41086a2000290300370300200541206a41106a2009370300200541206a41186a20012903003703002005200529036037032002400240200b0d00200541206aad428080808080048410110c010b200541e0006a200b200710f103200541206aad4280808080800484200535026842208620052802602206ad84100e02402005280264450d00200610230b200b200710f003200c450d00200c411c6c450d00200b10230b410021060b20054180016a240020060f0b1032000b1033000bf90403027f017e057f230041d0006b2202240041b0dfc300ad4280808080a00184100c22032900002104200241086a200341086a290000370300200220043703002003102341b4a2c300ad4280808080e00284100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000ba20b07057f017e047f027e047f017e077f230041e0006b22012400200141c0006a41186a22024200370300200141c0006a41106a22034200370300200141c0006a41086a22044200370300200142003703404196adc300ad4280808080900184100c220529000021062004200541086a290000370300200120063703402005102341bce0c300ad4280808080e00084100c22072900002106200141086a2205200741086a2900003703002001200637030020071023200320012903002206370300200141206a41086a22082004290300370300200141206a41106a22092006370300200141206a41186a220a200529030037030020012001290340370320200141c0006a200141206a10910320012802402107200129024421062002420037030020034200370300200442003703002001420037034041b0dfc300ad4280808080a00184100c2202290000210b2004200241086a2900003703002001200b3703402002102341bcbac500ad4280808080b00184100c2202290000210b2005200241086a2900003703002001200b3703002002102320032001290300220b370300200820042903003703002009200b370300200a2005290300370300200120012903403703202006420020071b220c422088a7210d200141c0006a200141206a10ad0220012902444200200128024022041b2206422088210b0240200642ffffff3f83500d002004410120041b10230b200ba721044100210e0240200d450d002004417f6a200d6e210e0b2007410420071b210f2001410036024820014204370340200141c0006a4100200410a5012001280248210802400240024002400240024020040d00200128024021090c010b2001280240220920084103746a21030240200e450d00200e200d6c210a410021050340410021070240200a20054d0d002005200e6e2207200d4f0d04200f2007412c6c6a2802002102410121070b20032007360200200341046a2002360200200341086a21032004200541016a2205470d000b200820056a21080c010b20042105034020034100360200200341086a21032005417f6a22050d000b200820046a21080b20012802442110200141c0006a419485c300411410a8034100210341204100412020044102746b2205200541204b1b22056bad422086200141c0006a20056aad84101822052900002106200541086a290000210b200541106a2900002111200141186a2212200541186a290000370300200141106a22132011370300200141086a2214200b3703002001200637030020051023200141206a41186a22152012290300370300200141206a41106a22162013290300370300200141206a41086a2217201429030037030020012001290300370320024041002004417f6a2205200520044b1b2202450d002001ad4280808080800484210b03402003411c71220541046a220741214f0d03200120056a2800002004410120041b220a70210702402005411c470d00200141c0006a41186a220d200b1018220541186a290000370300200141c0006a41106a220e200541106a290000370300200141c0006a41086a2218200541086a29000037030020012005290000370340200510232012200d2903003703002013200e29030037030020142018290300370300200120012903403703000b200a417f6a220520084f0d04200720084f0d05200920054103746a220529020021062005200920074103746a220729020037020020072006370200200341046a21032004417f6a21042002417f6a22020d000b0b2000200836020820002010360204200020093602002000200129032037000c200041146a20172903003700002000411c6a2016290300370000200041246a20152903003700000240200ca72204450d002004412c6c450d00200f10230b200141e0006a24000f0b2007200d41e8f6c3001030000b2007412041a885c3001043000b200520084184d9c4001030000b2007200841f8c5c4001030000b940503027f017e057f230041d0006b2202240041b0dfc300ad4280808080a00184100c22032900002104200241086a200341086a290000370300200220043703002003102341d0a1c300ad4280808080d00084100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422074110200741104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a2903003700000240200841606a20054f0d00200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a02402002280224450d00200610230b200241386a2003200110b70302400240200228023822010d00200041003602000c010b2000200229023c370204200020013602000b20031023200241d0006a24000f0b102c000b102a000bfd0201097f230041106b22022400024002402001280208220341ffffffff00712003470d0020034104742204417f4c0d00200128020021014104210502402004450d00200410212205450d020b20024100360208200220053602002002200441047636020420024100200310a0012002280208210602402003450d0020034104742107200228020020064104746a21032002410f6a21080340410221050240024002402001410c6a2d00004103710e03000102000b410021050c010b410121050b200141086a2802002204417f4c0d02200128020021090240024020040d004101210a0c010b20041021220a450d040b200141106a2101200a2009200410a10521092003410c6a20053a0000200341086a2004360200200341046a2004360200200320093602002003410d6a20022f000d3b00002003410f6a20082d00003a0000200341106a2103200641016a2106200741706a22070d000b0b20002002290300370200200041086a2006360200200241106a24000f0b1032000b1033000ba80e06077f027e037f0a7e017f037e230041d0026b2203240020022802102104200228020c21052002280208210620022802042107200228020021022003200110970220034180016a2003280200220820032802082209109802200329038001210a4200210b2003420037038001200341c8016a280200210c20032d00cc01210d02400240200a420151220e0d00200341106a41306a4200370300200341106a41286a4200370300200341106a41206a4200370300200341106a41186a4200370300200341206a4200370300200341186a4200370300200342003703104200210f4200211042002111420021120c010b200341b8016a290300211320034180016a41306a290300211420034180016a41206a290300210f20034180016a41186a290300210b200341c0016a290300211220032903900121112003290388012110200341106a41206a20034180016a41286a290300370300200341106a41286a2014370300200341106a41306a2013370300200341206a200b3703002003200f37032820032010370310200320113703180b02400240024002402010200229030022157d22142010562011200241086a29030022167d2010201554ad7d221320115620132011511b450d0041e1acc500ad4280808080b00284211141838a0c21040c010b02402010200b7c22174280c8afa0255441002011200f7c22182017200b54ad7c501b0d002014200b7c220b42ffc7afa025562013200f7c200b201454ad7c220b420052200b501b0d0020072d00004101460d0041c6acc500ad4280808080900184211141838a1421040c010b2015201684500d0120052d00002105200341c8006a2006280200109702200341e8016a20032802482206200328025010980220032903e801420151210720034198026a290300211520034190026a2903002116200341a8026a290300210b200341a0026a290300210f0240200328024c450d00200610230b200b420020071b210b200f420020071b210f0240200541ff01714101460d002015420020071b21152016420020071b2116024020054101710d002016210f2015210b0c010b2015200b2016200f562015200b562015200b511b22071b210b2016200f20071b210f0b200f201458200b201358200b2013511b0d0141fcacc500ad4280808080d00284211141838a0421040b20114280807c832115201142088842ff018321102011a7210e410121020c010b2003201437031020032013370318200241086a290300210f2002290300210b20042802002104200341c8006a41186a200341206a220241086a2903002215370300200341c8006a41206a2205200241106a290300370300200341f0006a2206200241186a290300370300200341f8006a2219200241206a2903003703002003201337035020032014370348200320022903002216370358427f20172017201054220220182002ad7c221020115420102011511b22021b427f201020021b8450210202400240427f201420167c221120112014542207201320157c2007ad7c221120135420112013511b22071b22104280c8afa025544100427f201120071b2211501b0d00200341c8006a41106a2903002110201929030021152006290300211720052903002116200329035021182003290348211a4201211b2003290360211c0c010b4200211b02402010201184500d002010201110eb01200341a0026a201137030020034198026a2010370300200341e8016a41086a41013a0000200341f1016a2004290000370000200341f9016a200441086a29000037000020034181026a200441106a29000037000020034189026a200441186a290000370000200341023a00e801200341e8016a10e0010b0b2002ad2111200341a8016a2016370300200341b0016a201737030020034190016a2018370300200341b8016a201537030020034198016a20103703002003201c3703a001200320123703c0012003201a3703880142012110410021022003200d4100200a42015122041b3a00cc012003200c410020041b3602c8012003201b4201512204ad37038001024020040d002009ad4220862008ad84101142002110420021150c010b200320093602ec01200320083602e80120034188016a200341e8016a109803420021150b02402003280204450d00200810230b024002402002450d0020002004360204200041086a2010420886200ead42ff018384201584370200410121020c010b024002400240200e41ff017122020d0020104200510d004103210e200341e8016a21020c010b2002450d0120104200520d014104210e20034180016a21020b200241046a200e3a0000200241003a0000200241056a20012900003700002002410d6a200141086a290000370000200241156a200141106a2900003700002002411d6a200141186a290000370000200210e0010b200041286a200f370300200041206a200b370300200041186a2013370300200041106a2014370300200041086a2011370300410021020b20002002360200200341d0026a24000bd20201077f230041206b22022400200241086a200110880102400240024002402002280208450d00200041003602000c010b200228020c220320012802044102762204200420034b1b22054102742204417f4c0d010240024020050d00410421060c010b200410212206450d030b41002104200241003602182002200536021420022006360210024002402003450d000340200128020422054104490d0220012802002207280000210820012005417c6a3602042001200741046a360200024020042002280214470d00200241106a20044101107920022802102106200228021821040b200620044102746a20083602002002200441016a22043602182003417f6a22030d000b0b20002002290310370200200041086a200241106a41086a2802003602000c010b20004100360200200228021441ffffffff0371450d00200610230b200241206a24000f0b1032000b1033000bef0602077f047e230041f0006b22032400024002400240200128020422044108490d000340200128020021052003410136026c20032004410376220636020802400240200641014b0d004100210741012108024020060e020002000b200341346a4101360200200341dc006a41023602002003420237024c2003419c96c7003602482003410136022c2003200341286a3602582003200341086a3602302003200341ec006a360228200341c8006a419ca8c700103a000b200441016a410771200441786a4178717221072005410120041b2205200441077122044107466a2108200441087221040b2005410120041b2d000021062001200736020420012008360200200128020821050240024020064101200441077174710d00410021040c010b0240200128020c220628020820054d0d0020012802102104200341c8006a41186a2207200628020020054105746a220641186a290000370300200341c8006a41106a2208200641106a290000370300200341c8006a41086a2209200641086a29000037030020032006290000370348024020042802082206200441046a280200470d00200420064101109a01200428020821060b200428020020064105746a22062003290348370000200641186a2007290300370000200641106a2008290300370000200641086a20092903003700002004200428020841016a3602080b4100210402402002280200220628020820054d0d00200341c8006a41086a200628020020054105746a220441086a290000370300200341c8006a41106a200441106a290000370300200341c8006a41186a200441186a29000037030020032004290000370348410121040b200128020821050b2001200541016a360208200341286a41086a200341c8006a41086a290300370300200341286a41106a200341c8006a41106a290300370300200341286a41186a200341c8006a41186a2903003703002003200329034837032820040d022001280204220441084f0d000b0b200041003a00000c010b200341086a41186a200341286a41186a290300220a370300200341086a41106a200341286a41106a290300220b370300200341086a41086a200341286a41086a290300220c37030020032003290328220d370308200041196a200a370000200041116a200b370000200041096a200c3700002000200d370001200041013a00000b200341f0006a24000b820101017f200120021061024002402001450d00200141057421030340412010212201450d0220012000290000370000200141186a200041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200220014120106220011023200041206a2100200341606a22030d000b0b0f0b1033000bbf0201027f230041e0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841010108b0102400240200228021022010d00200041003602000c010b200228021421032002200241106a41086a28020036022420022001360220200241c8006a200241206a10c6030240024020022802480d0020024100360230200242013703282002410a36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c20024180c5c6003602482002200241386a360258200241c4006a4184a5c200200241c8006a10311a2002350230422086200235022884100a0240200228022c450d00200228022810230b200041003602000c010b20002002290348370200200041086a200241c8006a41086a2802003602000b2003450d00200110230b200241e0006a24000bf90403027f017e057f230041d0006b2202240041b0dfc300ad4280808080a00184100c22032900002104200241086a200341086a290000370300200220043703002003102341d0a1c300ad4280808080d00084100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bf70503087f017e017f230041306b22022400200241086a200110880102400240024002402002280208450d00200041003602000c010b41042103200228020c220420012802044104762205200520044b1b22064104742205417f4c0d0202402006450d00200510212203450d020b41002105200241003602182002200636021420022003360210024002402004450d00034002400240200128020422060d00410321070c010b200128020022072d0000210820012006417f6a3602042001200741016a3602000240200841024d0d00410321070c010b2002200110880102402002280200450d00410321070c010b02402001280204200228020422064f0d00410321070c010b2006417f4c0d06024002400240024020060d00410121090c010b200610272209450d0820012802042006490d0220092001280200200610a1051a200128020422072006490d012001200720066b3602042001200128020020066a3602000b410321072009450d022006ad220a422086200a84210a2002412a6a41026a2002412d6a41026a2d00003a0000200220022f002d3b012a2009210b200821070c020b20062007418ca9c0001044000b20091023410321070b200241266a41026a22062002412a6a41026a2d00003a0000200220022f012a3b012620074103460d02200241226a41026a220820062d00003a0000200220022f01263b0122024020052002280214470d00200241106a2005410110a00120022802102103200228021821050b200320054104746a220620073a000c2006200a3702042006200b360200200620022f01223b000d2006410f6a20082d00003a00002002200541016a22053602182004417f6a22040d000b0b20002002290310370200200041086a200241106a41086a2802003602000c010b2000410036020002402005450d00200541047421062003210503400240200541046a280200450d00200528020010230b200541106a2105200641706a22060d000b0b200228021441ffffffff0071450d00200310230b200241306a24000f0b1033000b1032000b130020004111360204200041b885c3003602000baf0203027f017e057f230041106b220224000240024020012802082203ad420c7e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410421060c010b200510212206450d020b200241003602082002200636020020022005410c6e3602042002410020031095012002280208210602402003450d0020012003410c6c6a210720022802002006410c6c6a21050340200141086a2802002203417f4c0d02200128020021080240024020030d00410121090c010b200310212209450d040b20092008200310a1052108200541086a2003360200200541046a2003360200200520083602002005410c6a2105200641016a21062001410c6a22012007470d000b0b20002002290300370200200041086a2006360200200241106a24000f0b1032000b1033000b8a0301037f230041d0006b22032400024002400240024020002d00000e03010200010b200341c8006a200041196a290000370300200341c0006a200041116a290000370300200341386a200041096a2900003703002003200029000137033041022104200341306a21050c020b200341c8006a200041196a290000370300200341c0006a200041116a290000370300200341386a200041096a2900003703002003200029000137033041002104200341306a21050c010b200341c8006a200041196a290000370300200341c0006a200041116a290000370300200341386a200041096a2900003703002003200029000137033041012104200341306a21050b200341216a200541186a290000370000200341196a200541106a290000370000200341116a200541086a290000370000200320043a000820032005290000370009200341306a200341086a20011076200041216a200335023842208620032802302205ad8420021013210002402003280234450d00200510230b200341d0006a24004106410220004101461b0bd70408027f017e037f017e017f027e037f017e230041f0006b2203240020012002844200522204ad2105024020040d00200341c0006a41186a22064200370300200341c0006a41106a22074200370300200341c0006a41086a220842003703002003420037034041bdadc500ad42808080808001842209100c220a290000210b200341e0006a41086a2204200a41086a2900003703002003200b370360200a1023200820042903003703002003200329036037034041c5adc500ad4280808080d00184220b100c220a290000210c2004200a41086a2900003703002003200c370360200a102320072003290360220c370300200341206a41086a220d2008290300370300200341206a41106a220e200c370300200341206a41186a220f200429030037030020032003290340370320200341086a200341206a412010d701200341086a41106a290300210c200329031021102003280208210a200642003703002007420037030020084200370300200342003703402009100c220629000021092004200641086a29000037030020032009370360200610232008200429030037030020032003290360370340200b100c220629000021092004200641086a2900003703002003200937036020061023200720032903602209370300200d2008290300370300200e2009370300200f2004290300370300200320032903403703202003200c4200200a1b370348200320104200200a1b370340200341206aad4280808080800484200341c0006aad4280808080800284100e0b2000200137030820002005370300200041106a2002370300200341f0006a24000b130020004103360204200041ac90c3003602000b34002000418c97c30036020420004100360200200041146a4101360200200041106a419097c300360200200041086a42043702000bf90403027f017e057f230041d0006b2202240041b0dfc300ad4280808080a00184100c22032900002104200241086a200341086a290000370300200220043703002003102341c4a1c300ad4280808080c00084100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000b8b1304057f017e047f047e23004190086b22022400200241206a2001108801024002400240024002400240024020022802200d0020012802042203450d01200128020022042d0000210520012003417f6a3602042001200441016a360200200541ff00714104470d024100210620054118744118754100480d03420221070c040b200042033703680c050b200042033703680c040b200042033703680c030b200241003a00d0042003417f6a2108200321050240024002400240024002400240024002400240034020082006460d01200241b0046a20066a200420066a220941016a2d00003a000020012005417e6a3602042001200941026a3602002002200641016a22093a00d0042005417f6a21052009210620094120470d000b200241e8066a41186a200241b0046a41186a290300370300200241e8066a41106a200241b0046a41106a290300370300200241e8066a41086a200241b0046a41086a290300370300200220022903b0043703e8062003417f6a2009460d08200420096a220441016a2d0000210620012005417e6a3602042001200441026a360200200641024b0d0820060e03010203010b200641ff0171450d07200241003a00d0040c070b41002106200241003a00f0042003417e6a210a200920036b41026a210b200320096b417d6a210902400340200b20066a450d01200241b0046a20066a200420066a220841026a2d00003a0000200120093602042001200841036a3602002002200641016a22083a00f0042009417f6a2109200a417f6a210a20082106200841c000470d000b200241d0076a41386a200241b0046a41386a2903002207370300200241d0076a41306a200241b0046a41306a290300220c370300200241d0076a41286a200241b0046a41286a290300220d370300200241d0076a41206a200241b0046a41206a290300220e370300200241d0076a41186a200241b0046a41186a290300220f37030020024180026a41086a200241b0046a41086a29030037030020024180026a41106a200241b0046a41106a29030037030020024180026a41186a200f37030020024180026a41206a200e37030020024180026a41286a200d37030020024180026a41306a200c37030020024180026a41386a2007370300200220022903b00437038002200520086b417e6a2105200420086a41026a2109410021060c030b200641ff0171450d06200241003a00f004420221070c070b41002106200241003a00f0042003417e6a210a200920036b41026a210b200320096b417d6a210902400340200b20066a450d01200241b0046a20066a200420066a220841026a2d00003a0000200120093602042001200841036a3602002002200641016a22083a00f0042009417f6a2109200a417f6a210a20082106200841c000470d000b200241d0076a41386a200241b0046a41386a2903002207370300200241d0076a41306a200241b0046a41306a290300220c370300200241d0076a41286a200241b0046a41286a290300220d370300200241d0076a41206a200241b0046a41206a290300220e370300200241d0076a41186a200241b0046a41186a290300220f37030020024180026a41086a200241b0046a41086a29030037030020024180026a41106a200241b0046a41106a29030037030020024180026a41186a200f37030020024180026a41206a200e37030020024180026a41286a200d37030020024180026a41306a200c37030020024180026a41386a2007370300200220022903b00437038002200520086b417e6a2105200420086a41026a2109410121060c020b200641ff0171450d05200241003a00f004420221070c060b41002106200241003a00f1042003417e6a210a200920036b41026a210b200320096b417d6a21090340200b20066a450d02200241b0046a20066a200420066a220841026a2d00003a0000200120093602042001200841036a3602002002200641016a22083a00f1042009417f6a2109200a417f6a210a20082106200841c100470d000b20024180026a200241b0046a41c10010a1051a200520086b417e6a210541022106200420086a41026a21090b2002418f076a20024180026a41c10010a1051a2005450d032009310000210d20012005417f6a22043602042001200941016a360200200d50450d01420021070c020b200641ff0171450d02200241003a00f104420221070c030b2004450d012009310001210e20012005417e6a3602042001200941026a3602004202200d420f8386220c4204540d0142012107200e420886200d84420488200c420c88220d4201200d4201561b7e220d200c5a0d010b200241186a200110880120022802180d00200228021c2105200220011080022002290300a70d00200241106a290300210f2002290308210e200241d0076a41186a200241e8066a41186a290300370300200241d0076a41106a200241e8066a41106a290300370300200241d0076a41086a200241e8066a41086a290300370300200220022903e8063703d007200241b0046a2002418f076a41c10010a1051a200241f8016a41046a200241e2066a41046a2f01003b0100200220022801e2063602f8010c010b420221070b200241d8016a41186a2209200241d0076a41186a290300370300200241d8016a41106a2204200241d0076a41106a290300370300200241d8016a41086a2208200241d0076a41086a290300370300200220022903d0073703d80120024197016a200241b0046a41c10010a1051a20024190016a41046a2203200241f8016a41046a2f01003b0100200220022802f8013602900120074202510d01200241f0006a41186a2009290300370300200241f0006a41106a2004290300370300200241f0006a41086a2008290300370300200220022903d8013703702002412f6a20024197016a41c10010a1051a200241286a41046a20032f01003b010020022002280290013602280b200241b0046a200110990320022802b004210120024180026a200241b0046a41047241ac0210a1051a024020014116460d0020002002290370370300200020063a0020200041186a200241f0006a41186a290300370300200041106a200241f0006a41106a290300370300200041086a200241f0006a41086a290300370300200041216a2002412f6a41c10010a1051a200041e6006a200241286a41046a2f01003b01002000200228022836016220004188016a200f37030020004180016a200e37030020004198016a200136020020004190016a2005360200200041f8006a200d3703002000200c370370200020073703682000419c016a20024180026a41ac0210a1051a0c020b200042033703680c010b200042033703680b20024190086a24000bf90403027f017e057f230041d0006b2202240041e4dec400ad4280808080e00084100c22032900002104200241086a200341086a290000370300200220043703002003102341eadec400ad4280808080900184100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bc90402017f037e23004190016b22042400024002400240024020002d00000e03000102000b200441206a41186a200341186a290000370300200441206a41106a200341106a290000370300200441206a41086a200341086a29000037030020042003290000370320200041016a2002ad4220862001ad84200441206a101c41014621000c020b200441206a41186a200341186a290000370300200441206a41106a200341106a290000370300200441206a41086a200341086a29000037030020042003290000370320200041016a2002ad4220862001ad84200441206a101341014621000c010b2002ad4220862001ad84101822012900002105200141086a2900002106200141106a2900002107200441186a200141186a290000370300200441106a2007370300200441086a2006370300200420053703002001102341012101200441206a200041016a2004108d014100210020042d00200d00200441c8006a41206a200441c1006a2d00003a0000200441c8006a41186a200441396a290000370300200441c8006a41106a200441316a290000370300200441c8006a41086a200441296a29000037030020042004290021370348200441c8006aad4280808080900484101822002900002105200041086a2900002106200041106a2900002107200441f0006a41186a200041186a290000370300200441f0006a41106a2007370300200441f0006a41086a200637030020042005370370200010230240200441f0006a2003460d00200441f0006a2003412010a3054521010b200121000b20044190016a240020000bba0502087f037e230041106b2202240002400240200141086a28020022034105744116722204417f4c0d000240200410212205450d00200520012802002206290000370000200541086a200641086a290000370000200241103602082002200436020420022005360200200141046a280200210720032002106102400240024020030d0020022802042106200228020821040c010b20034105742108200228020021092002280204210620022802082104034020072105024002402006200422036b4120490d00200341206a21040c010b200341206a22042003490d03200641017422072004200720044b1b22074100480d03024002400240024020060d00024020070d00410121090c020b2007102121090c030b20062007470d010b200721060c020b200920062007102521090b200721062009450d060b200541206a2107200920036a22032005290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a290000370000200841606a22080d000b2002200636020420022004360208200220093602000b20012f010c210802400240200620046b4102490d00200441026a210520022802002103200621070c010b200441026a22052004490d01200641017422032005200320054b1b22074100480d010240024020060d00024020070d00410121030c020b200710212203450d060c010b2002280200210320062007460d0020032006200710252203450d050b20022007360204200220033602000b200320046a20083b00002005ad4220862003ad8410182205290000210a200541086a290000210b200541106a290000210c200041186a200541186a290000370000200041106a200c370000200041086a200b3700002000200a3700002005102302402007450d00200310230b200241106a24000f0b102c000b1033000b1032000b102a000b130020004102360204200041a498c3003602000b3400200041b0dfc30036020420004100360200200041146a4107360200200041106a41c49cc300360200200041086a420a3702000b2c01017f02404108102122020d001033000b20024200370000200042888080808001370204200020023602000b2201017f230041106b220224002002410036020020002002108601200241106a24000bd60201057f230041206b2202240002400240024002400240024020012d0000417f6a220341024b0d0020030e03010203010b41f58ac7004128418c94c700102d000b41b00210212203450d032003200141046a28020010dc03200041013a0000200041046a20033602000c020b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c010b200241186a2204200141196a290000370300200241106a2205200141116a290000370300200241086a2206200141096a2900003703002002200129000137030041b00210212203450d012003200141246a28020010dc03200041246a2003360200200041033a0000200041196a2004290300370000200041116a2005290300370000200041096a2006290300370000200020022903003700010b200241206a24000f0b102a000b881703047f067e027f230041d0036b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e16001101020304051106070809110a0b0c0d0e0f101112000b200241a8016a200141086a10dd0320004100360200200041106a200241a8016a41086a290300370300200041086a20022903a8013703000c120b20004102360200200041086a200141086a2903003703000c110b02400240024002400240024020012d0004417f6a220341034b0d00200141046a210420030e0401020304010b41f58ac7004128418c94c700102d000b200141086a2802002103410121050c030b41022105200241086a41026a200441036a2d00003a0000200241a8016a41086a200141146a290200370300200241b8016a2001411c6a290200370300200241c0016a200141246a2d00003a0000200220042f00013b010820022001410c6a2902003703a801200141086a2802002103200141286a28020021010c020b200141086a2802002103410321050c010b2002410a6a200441036a2d00003a0000200241a8016a41086a200141146a290200370300200241b8016a2001411c6a290200370300200241c0016a200141246a2d00003a0000200220042f00013b010820022001410c6a2902003703a801200141086a2802002103200141286a2802002101410421050b200020053a0004200020022f01083b000520004103360200200041086a20033602002000410c6a20022903a801370200200041286a2001360200200041076a2002410a6a2d00003a0000200041146a200241a8016a41086a2903003702002000411c6a200241b8016a290300370200200041246a200241c0016a2802003602000c100b02400240024002400240024002400240200141086a22032d0000417f6a220441034b0d0020040e0401020304010b41f58ac7004128418c94c700102d000b200241b0016a200341096a290000370300200241b8016a200341116a290000370300200241c0016a200341196a290000370300200220032900013703a801200141386a2903002106200141306a2903002107410121010c030b200241b0016a200341096a290000370300200241b8016a200341116a290000370300200241c0016a200341196a290000370300200220032900013703a801200141c8006a2903002108200141c0006a2903002109200141386a2903002106200141306a2903002107410221010c030b200241b0016a200341096a290000370300200241b8016a200341116a290000370300200241c0016a200341196a290000370300200220032900013703a8012002200341216a2800003602082002200341246a28000036000b200141c8006a3100002108200141c0006a2902002109200141386a2902002106200141306a2902002107200141d8006a290300210a200141d0006a290300210b410321010c030b200241b0016a200341096a290000370300200241b8016a200341116a290000370300200241c0016a200341196a290000370300200220032900013703a801200141386a2903002106200141306a2903002107410421010b0b0b200020022903a8013700092000200228020836002920004104360200200041d8006a200a370300200041d0006a200b370300200041c8006a2008370300200041c0006a2009370300200041386a2006370300200041306a2007370300200041086a20013a00002000412c6a200228000b360000200041116a200241a8016a41086a290300370000200041196a200241b8016a290300370000200041216a200241c0016a2903003700000c0f0b200241a8016a200141046a10de03200041053602002000410c6a200241b0016a280200360200200020022903a8013702040c0e0b200241a8016a200141086a109202200041086a200241a8016a41880210a1051a200041063602000c0d0b02400240200128020422040d00410021030c010b200241a8016a41186a200141286a290000370300200241a8016a41106a200141206a290000370300200241b0016a200141186a290000370300200241a8016a41286a200141386a290000370300200241a8016a41306a200141c0006a290000370300200241a8016a41386a200141c8006a290000370300200241a8016a41c8006a200141d8006a290000370300200241a8016a41d0006a200141e0006a290000370300200241a8016a41d8006a200141e8006a2900003703002002200141106a2900003703a8012002200141306a2900003703c8012002200141d0006a2900003703e801200241a8016a41f8006a20014188016a290000370300200241a8016a41f0006a20014180016a290000370300200241a8016a41e8006a200141f8006a290000370300200241a8016a4198016a200141a8016a290000370300200241a8016a4190016a200141a0016a290000370300200241a8016a4188016a20014198016a2900003703002002200141f0006a29000037038802200220014190016a2900003703a8022001410c6a2802002201417f4c0d0e0240024020010d0020024200370308410121030c010b200110212203450d102002410036020c200220013602080b20032004200110a1051a2002200136020c20022903082106200241086a200241a8016a41a00110a1051a0b20002003360204200041086a2006370200200041106a200241086a41a00110a1051a200041083602000c0c0b20004109360200200020012802043602040c0b0b2001410c6a2802002203417f4c0d0b200128020421050240024020030d0041002101410121040c010b20032101200310212204450d0d0b20042005200310a10521042000410c6a2003360200200041086a2001360200200020043602042000410a3602000c0a0b200241a8016a200141046a10d702200041046a200241a8016a41e40010a1051a2000410b3602000c090b200241a8016a200141046a10df03200041046a200241a8016a419c0210a1051a2000410d3602000c080b2000410e3602000c070b200241a8016a200141046a10e003200041046a200241a8016a41c80010a1051a2000410f3602000c060b200241a8016a200141046a10e103200041103602002000413c6a200241e0016a280200360200200041346a200241d8016a2903003702002000412c6a200241d0016a290300370200200041246a200241c8016a2903003702002000411c6a200241c0016a290300370200200041146a200241a8016a41106a2903003702002000410c6a200241b0016a290300370200200020022903a8013702040c050b200241a8016a200141086a10e203200041086a200241a8016a41a80210a1051a200041113602000c040b200241a8016a200141046a10e303200041046a200241a8016a41c40010a1051a200041123602000c030b4102210c0240024002400240200141086a22032d0000417f6a220d41024b0d0041012104200d0e03030201030b41f58ac7004128418c94c700102d000b200141c8006a2903002107200141c0006a2903002106200141386a2903002109200141306a2903002108200141d0006a28020021054103210c0b200241c0016a200341196a290000370300200241b8016a200341116a290000370300200241b0016a200341096a290000370300200220032900013703a801200c21040b200020022903a8013700092000200228000836002920004113360200200041c8006a2007370300200041c0006a2006370300200041386a2009370300200041306a2008370300200041086a20043a0000200041d0006a2005360200200041116a200241a8016a41086a290300370000200041196a200241b8016a290300370000200041216a200241c0016a2903003700002000412c6a2002410b6a2800003600000c020b10e403000b200241a8016a200141046a10db0320004115360200200041246a200241c8016a2903003702002000411c6a200241c0016a290300370200200041146a200241b8016a2903003702002000410c6a200241b0016a290300370200200020022903a8013702040b200241d0036a24000f0b1032000b1033000bae0803047f017e077f230041206b22022400024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0020030e0a0102030405060708090a010b41f58ac7004128418c94c700102d000b20004101360200200020012802043602040c090b2001410c6a2802002203417f4c0d09200128020421010240024020030d0041002104410121050c010b20032104200310212205450d0b0b20052001200310a10521012000410c6a2003360200200041086a200436020020002001360204200041023602000c080b20004103360200200041086a200141086a2903003703000c070b2001410c6a2802002203417f4c0d07200128020421010240024020030d0041002104410121050c010b20032104200310212205450d090b20052001200310a10521012000410c6a2003360200200041086a200436020020002001360204200041043602000c060b2001410c6a2802002203417f4c0d06200128020421010240024020030d0041002104410121050c010b20032104200310212205450d080b20052001200310a10521012000410c6a2003360200200041086a200436020020002001360204200041053602000c050b20004106360200200020012902043702042000410c6a2001410c6a2802003602000c040b2001410c6a2802002204ad42187e2206422088a70d042006a72205417f4c0d04200128020421030240024020050d00410421010c010b200510212201450d060b20024100360218200220013602102002200541186e360214200241106a4100200410b0012002280218210702402004450d002003200441186c6a21082002280210200741186c6a21010340200341086a2802002204417f4c0d06200328020021050240024020040d00410021094101210a0c010b2004210920041021220a450d080b200a2005200410a105210a200341146a2802002205417f4c0d062003410c6a280200210b0240024020050d004100210c4101210d0c010b2005210c20051021220d450d080b200d200b200510a105210b200141146a2005360200200141106a200c3602002001410c6a200b360200200141086a2004360200200141046a20093602002001200a360200200141186a2101200741016a2107200341186a22032008470d000b0b200241086a20073602002002200229031022063703002000410c6a200736020020002006370204200041073602000c030b200241106a200141046a10cd03200041083602002000410c6a200241106a41086a280200360200200020022903103702040c020b2001410c6a2802002203417f4c0d02200128020421010240024020030d0041012104410021050c010b20032105200310212204450d040b20042001200310a10521012000410c6a2003360200200041086a200536020020002001360204200041093602000c010b2000410a3602000b200241206a24000f0b1032000b1033000bda0b03027f017e177f230041a0016b220224000240024020012802082203ad42f0007e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410421010c010b200510212201450d020b20024100360208200220013602002002200541f0006e36020420024100200310b5012002280208210502402003450d002006200341f0006c6a21072002280200200541f0006c6a21082005200341047441706a4104766a21090340200241d0006a41086a220a200641186a290000370300200241d0006a41106a220b200641206a290000370300200241d0006a41186a220c200641286a290000370300200241306a41086a220d200641386a29000037030020062900102104200241306a41106a220e200641c0006a290000370300200241306a41186a220f200641c8006a290000370300200241106a41186a2210200641e8006a290000370300200241106a41106a2211200641e0006a290000370300200241106a41086a2212200641d8006a290000370300200220043703502002200629003037033020022006290050370310200628020c2203ad42247e2204422088a70d022004a72205417f4c0d0220062802002113200628020421140240024020050d00410421010c010b200510212201450d040b20024100360278200220013602702002200541246e360274200241f0006a4100200310a2012002280278211502402003450d00200341246c21162002280270201541246c6a211741002105034002400240024002400240024002400240201420056a22032d00000e06010203040500010b2003410c6a2802002218417f4c0d0b200341046a28020021030240024020180d0041012101410021190c010b20182119201810212201450d0d0b200220012003201810a105360093014105211a0c050b2002200341046a28000036009b012002200341016a280000360298012002200341146a290000370380012002200341196a290000370085012002200228029801360290012002200228009b0136009301200341086a28000021192003410c6a2800002118200341106a28000021014100211a0c050b200341106a2802002201417f4c0d09200341086a280200211b200341016a28000021034101211a0240024020010d0041002118410121190c010b20012118200110212219450d0b0b2019201b200110a1051a20022003360290010c040b200341106a2802002201417f4c0d08200341086a280200211a200341016a28000021030240024020010d0041002118410121190c010b20012118200110212219450d0a0b2019201a200110a1051a20022003360290014102211a0c030b200341106a2802002201417f4c0d07200341086a280200211a200341016a28000021030240024020010d0041002118410121190c010b20012118200110212219450d090b2019201a200110a1051a20022003360290014103211a0c020b4104211a2002200341046a280200360093012003410c6a2802002118200341086a28020021190b0b201720056a2203201a3a0000200341016a200228029001360000200341046a200228009301360000200341106a20013602002003410c6a2018360200200341086a2019360200200341146a2002290380013702002003411c6a20024180016a41086a290300370200201541016a21152016200541246a2205470d000b0b20024180016a41086a2015360200200220022903702204370380012008410c6a20153602002008200437020420082002290350370210200841186a200a29030037020020082013360200200841206a200b290300370200200841286a200c29030037020020082002290330370230200841386a200d290300370200200841c0006a200e290300370200200841c8006a200f290300370200200841e8006a2010290300370200200841e0006a2011290300370200200841d8006a201229030037020020082002290310370250200841f0006a2108200641f0006a22062007470d000b200941016a21050b20002002290300370200200041086a2005360200200241a0016a24000f0b1032000b1033000baf1f07027f017e197f017e047f017e097f230041f0026b220224000240024002400240024002402001280200417f6a220341014b0d0020030e020102010b41f58ac7004128418c94c700102d000b2001410c6a2802002203ad4288027e2204422088a70d022004a72205417f4c0d02200128020421060240024020050d00410821010c010b200510212201450d040b20024100360288012002200136028001200220054188026e3602840120024180016a41002003109901200228028801210702402003450d00200620034188026c6a210820022802800120074188026c6a210920024190026a41086a210a20024190026a41106a210b20024190026a41186a210c0340200a200641d8006a290000370300200b200641e0006a290000370300200c200641e8006a2900003703002002200629005037039002200641cc006a280200220d417f4c0d04200628024421032006280240210e02400240200d0d004100210f410121010c010b200d210f200d10212201450d060b20012003200d10a1052110200241f0016a41186a221120064188016a290300370300200241f0016a41106a221220064180016a290300370300200241f0016a41086a2213200641f8006a290300370300200241b0016a41086a221420064190016a220341086a290000370300200241b0016a41106a2215200341106a290000370300200241b0016a41186a2216200341186a290000370300200241b0016a41206a2217200341206a290000370300200241b0016a41286a2218200341286a290000370300200241b0016a41306a2219200341306a290000370300200241b0016a41386a221a200341386a290000370300200220062903703703f001200220032900003703b00120024190016a41186a221b200641d0016a220341186a29000037030020024190016a41106a221c200341106a29000037030020024190016a41086a221d200341086a2900003703002002200329000037039001200641086a29030021042006290300211e200241c0006a200641106a10c403200241186a221f200641346a290000370300200241106a22202006412c6a290000370300200241086a2221200641246a2900003703002002200629001c37030020062802f8012222ad42c1007e2223422088a70d042023a72201417f4c0d0420062802f00121030240024020010d00410121050c010b200110212205450d060b20024100360268200220053602602002200141c1006e360264200241e0006a41002022109d012002280268212402402022450d002003202241c1006c6a21252002280260202441c1006c6a2101034020032d00002105200241b0026a41386a2226200341396a290000370300200241b0026a41306a2227200341316a290000370300200241b0026a41286a2228200341296a290000370300200241b0026a41206a2229200341216a290000370300200241b0026a41186a222a200341196a290000370300200241b0026a41106a222b200341116a290000370300200241b0026a41086a222c200341096a2900003703002002200341016a2900003703b002200120053a0000200141016a20022903b002370000200141096a202c290300370000200141116a202b290300370000200141196a202a290300370000200141216a2029290300370000200141296a2028290300370000200141316a2027290300370000200141396a2026290300370000200141c1006a2101200341c1006a22032025470d000b202420226a21240b200241b0026a41086a22052024360200200220022903603703b00220062802fc0121260240024020064180026a280200220141037622270d0041012127410021030c010b4101210302402027410820014107716b22284d0d0041024101202720286b22034107711b20034103766a21030b200310212227450d060b20272026200310a105212620092002290340370310200941186a200241c0006a41086a2802003602002009200229030037021c200920043703082009201e370300200941cc006a200d360200200941c8006a200f360200200920103602442009200e360240200941246a20212903003702002009200229039002370350200941d8006a200a2903003703002009412c6a2020290300370200200941346a201f290300370200200941e0006a200b290300370300200941e8006a200c29030037030020094188016a201129030037030020094180016a2012290300370300200941f8006a2013290300370300200920022903f001370370200920022903b0013703900120094198016a2014290300370300200941a0016a2015290300370300200941a8016a2016290300370300200941b0016a2017290300370300200941b8016a2018290300370300200941c0016a2019290300370300200941c8016a201a29030037030020094184026a200336020020094180026a2001360200200920263602fc01200941e8016a201b290300370300200941e0016a201c290300370300200941d8016a201d29030037030020092002290390013703d001200941f8016a2005280200360200200920022903b0023703f001200741016a210720094188026a210920064188026a22062008470d000b0b200241b8026a2007360200200220022903800122043703b0022000410c6a200736020020002004370204200041013602000c010b200241f0016a41186a200141d0006a290000370300200241f0016a41106a200141c8006a290000370300200241f0016a41086a200141c0006a2900003703002002200141386a2900003703f001200141046a21030240024002400240200141d8006a2d00000e03010200010b200241b0026a41186a200341ed006a290000370300200241b0026a41106a200341e5006a290000370300200241b0026a41086a200341dd006a2900003703002002200341d5006a2900003703b00241022126200241b0026a21050c020b200241b0026a41186a200341ed006a290000370300200241b0026a41106a200341e5006a290000370300200241b0026a41086a200341dd006a2900003703002002200341d5006a2900003703b00241002126200241b0026a21050c010b200241b0026a41186a200341ed006a290000370300200241b0026a41106a200341e5006a290000370300200241b0026a41086a200341dd006a2900003703002002200341d5006a2900003703b00241012126200241b0026a21050b20024190026a41186a200541186a29000037030020024190026a41106a200541106a29000037030020024190026a41086a200541086a2900003703002002200529000037039002200241b0026a41086a200341fd006a290000370300200241b0026a41106a20034185016a290000370300200241b0026a41186a2003418d016a290000370300200241d0026a20034195016a290000370300200241d8026a2003419d016a290000370300200241e0026a200341a5016a290000370300200241e8026a200341ad016a2900003703002002200341f5006a2900003703b002024002400240024020032d00b5010e03010200010b200241b0016a41186a200341ce016a290000370300200241b0016a41106a200341c6016a290000370300200241b0016a41086a200341be016a2900003703002002200341b6016a2900003703b00141022127200241b0016a21050c020b200241b0016a41186a200341ce016a290000370300200241b0016a41106a200341c6016a290000370300200241b0016a41086a200341be016a2900003703002002200341b6016a2900003703b00141002127200241b0016a21050c010b200241b0016a41186a200341ce016a290000370300200241b0016a41106a200341c6016a290000370300200241b0016a41086a200341be016a2900003703002002200341b6016a2900003703b00141012127200241b0016a21050b200241c0006a41186a2228200541186a290000370300200241c0006a41106a2229200541106a290000370300200241c0006a41086a222a200541086a29000037030020022005290000370340200241086a2205200341de016a290000370300200241106a222b200341e6016a290000370300200241186a222c200341ee016a290000370300200241206a2209200341f6016a290000370300200241286a2206200341fe016a290000370300200241306a222520034186026a290000370300200241386a220d2003418e026a2900003703002002200341d6016a2900003703002001280204210320024180016a200141086a10cd0320024190016a41086a2222200241f0016a41086a29030037030020024190016a41106a2224200241f0016a41106a29030037030020024190016a41186a2207200241f0016a41186a290300370300200241e0006a41086a220a20024190026a41086a290300370300200241e0006a41106a220b20024190026a41106a290300370300200241e0006a41186a220c20024190026a41186a290300370300200241b0016a41086a220e200241b0026a41086a290300370300200241b0016a41106a220f200241b0026a41106a290300370300200241b0016a41186a2210200241b0026a41186a290300370300200241b0016a41206a2211200241b0026a41206a290300370300200241b0016a41286a2212200241b0026a41286a290300370300200241b0016a41306a2213200241b0026a41306a290300370300200241b0016a41386a2214200241b0026a41386a290300370300200220022903f001370390012002200229039002370360200220022903b0023703b001200141146a280200211520002003360204200041086a200229038001370200200041106a20024180016a41086a280200360200200041146a2015360200200041386a200229039001370200200041c0006a2022290300370200200041c8006a2024290300370200200041d0006a2007290300370200200041186a200141186a290200370200200041206a200141206a290200370200200041286a200141286a290200370200200041306a200141306a290200370200200041d8006a20263a0000200041f1006a200c290300370000200041e9006a200b290300370000200041e1006a200a29030037000020002002290360370059200041b1016a2014290300370000200041a9016a2013290300370000200041a1016a201229030037000020004199016a201129030037000020004191016a201029030037000020004189016a200f29030037000020004181016a200e290300370000200020022903b001370079200020273a00b901200041d2016a2028290300370000200041ca016a2029290300370000200041c2016a202a290300370000200020022903403700ba0120004192026a200d2903003700002000418a026a202529030037000020004182026a2006290300370000200041fa016a2009290300370000200041f2016a202c290300370000200041ea016a202b290300370000200041e2016a2005290300370000200020022903003700da01200041023602000b200241f0026a24000f0b1032000b1033000bf50501087f024002400240024002400240024002400240024020012d0000417f6a220241064b0d0020020e0701020304050607010b41f58ac7004128418c94c700102d000b200141106a2802002202417f4c0d06200141086a2802002103200141046a280200210420012d000121050240024020020d0041002106410121070c010b20022106200210212207450d080b20072003200210a10521072001411c6a2802002203417f4c0d06200128021421010240024020030d0041002108410121090c010b20032108200310212209450d080b20092001200310a10521012000411c6a2003360200200041186a2008360200200041146a2001360200200041106a20023602002000410c6a2006360200200041086a2007360200200041046a2004360200200041013a00002000200541ff01714101463a00010f0b200041023a0000200041046a200141046a2802003602000f0b200041033a0000200041046a200141046a2802003602000f0b2001410c6a2802002202417f4c0d03200141046a28020021030240024020020d0041012104410021050c010b20022105200210212204450d050b20042003200210a1052104200141186a2802002203417f4c0d03200128021021010240024020030d0041012106410021070c010b20032107200310212206450d050b20062001200310a1052101200041186a2003360200200041146a2007360200200041106a20013602002000410c6a2002360200200041086a2005360200200041046a2004360200200041043a00000f0b20002001290001370001200041c4006a200141c4006a280200360200200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a290000370000200041053a00000f0b200041063a00000f0b200041073a0000200041046a200141046a2802003602000f0b1032000b1033000b830703037f017e037f230041c0026b22022400024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b41f58ac7004128418c94c700102d000b2001410c6a2802002204ad42b0027e2205422088a70d052005a72203417f4c0d05200141046a28020021010240024020030d00410821060c010b200310212206450d070b20024100360208200220063602002002200341b0026e36020420024100200410ad012002280208210702402004450d00200441b0026c21032002280200200741b0026c6a2106200441047441706a41047621040340200241106a200110dc032006200241106a41b00210a10541b0026a2106200141b0026a2101200341d07d6a22030d000b200720046a41016a21070b200241186a20073602002002200229030022053703102000410c6a2007360200200041046a2005370200200041013a00000c040b200141026a2f0100210641b00210212203450d062003200141046a28020010e304200041046a2003360200200041026a20063b0100200041023a00000c030b200141026a2f01002106200241106a200141046a108e02200141186a2802002107200141146a2802002104200141106a280200210841b00210212203450d0520032001411c6a28020010e304200041026a20063b01002000411c6a2003360200200041186a2007360200200041146a2004360200200041106a2008360200200041033a0000200041046a20022903103702002000410c6a200241186a2802003602000c020b200141226a2f01002103200241106a200141246a108e02200041226a20033b0100200041043a0000200041246a20022903103702002000412c6a200241186a280200360200200041386a200141386a280200360200200041306a200141306a29020037020020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c010b200141226a2f01002103200241106a200141246a108e02200041226a20033b0100200041053a0000200041246a20022903103702002000412c6a200241186a280200360200200041306a200141306a29020037020020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000b200241c0026a24000f0b1032000b1033000b102a000be24e03027f017e3a7f230041d0036b2202240002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203410a4b0d0020030e0b0102030405060708090a0b010b41f58ac7004128418c94c700102d000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c0a0b2001410c6a2802002203ad42c8007e2204422088a70d0a2004a72205417f4c0d0a200141046a28020021060240024020050d00410421070c010b200510212207450d0c0b41002108200241003602c003200220073602b8032002200541c8006e3602bc03200241b8036a4100200310a10120022802c003210902402003450d002006200341c8006c6a210a20022802b803200941c8006c6a210b0340410021074100210c024002400240024002400240200620086a22052d00000e06050102030400050b20024188036a41086a200541186a29000037030020024188036a41106a200541206a2d00003a00002002200541036a2d00003a00a2032002200541016a2f00003b01a0032002200541106a290000370388032005410c6a280000210d200541086a280000210e200541046a280000210f4105210c0c040b2005410c6a280200220d417f4c0d10200541046a28020021034101210c0240200d0d004100210e4101210f41012003200d10a1051a0c040b200d210e200d1021220f450d11200f2003200d10a1051a0c030b20024188036a41086a200541186a29000037030020024188036a41106a200541206a2d00003a00002002200541036a2d00003a00a2032002200541016a2f00003b01a0032002200541106a290000370388032005410c6a280000210d200541086a280000210e200541046a280000210f4102210c0c020b20024188036a41086a200541186a29000037030020024188036a41106a200541206a2d00003a00004103210c2002200541036a2d00003a00a2032002200541016a2f00003b01a0032002200541106a290000370388032005410c6a280000210d200541086a280000210e200541046a280000210f0c010b20024188036a41086a200541186a29000037030020024188036a41106a200541206a2d00003a00002002200541036a2d00003a00a2032002200541016a2f00003b01a0032002200541106a290000370388032005410c6a280000210d200541086a280000210e4104210c200541046a280000210f0b024002400240024002400240200541246a2d00000e06050102030400050b200241d8026a41026a200541276a2d00003a0000200241086a2005413c6a290000370300200241106a200541c4006a2d00003a00002002200541256a2f00003b01d8022002200541346a290000370300200541306a28000021102005412c6a2800002111200541286a2800002112410521070c040b200541306a2802002210417f4c0d10200541286a280200210341012107024020100d00410021114101211241012003201010a1051a0c040b20102111201010212212450d1120122003201010a1051a0c030b41022107200241d8026a41026a200541276a2d00003a0000200241086a2005413c6a290000370300200241106a200541c4006a2d00003a00002002200541256a2f00003b01d8022002200541346a290000370300200541306a28000021102005412c6a2800002111200541286a28000021120c020b200241d8026a41026a200541276a2d00003a0000200241086a2005413c6a290000370300200241106a200541c4006a2d00003a00002002200541256a2f00003b01d8022002200541346a290000370300200541306a28000021102005412c6a2800002111200541286a2800002112410321070c010b200241d8026a41026a200541276a2d00003a0000200241086a2005413c6a290000370300200241106a200541c4006a2d00003a00002002200541256a2f00003b01d8022002200541346a290000370300200541306a28000021102005412c6a2800002111200541286a2800002112410421070b200b20086a2203200c3a0000200341016a20022f01a0033b0000200341036a20022d00a2033a00002003410c6a200d360000200341086a200e360000200341046a200f360000200341106a200229038803370000200341216a20022f00f0023b0000200341186a20024188036a41086a290300370000200341206a20024188036a41106a2d00003a0000200341236a200241f0026a41026a2d00003a0000200341246a20073a0000200341286a20123600002003412c6a2011360000200341306a2010360000200341256a20022f01d8023b0000200341276a200241d8026a41026a2d00003a0000200341346a20022903003700002003413c6a200241086a290300370000200341c4006a200241106a2d00003a0000200341c5006a20022f00c0023b0000200341c7006a200241c0026a41026a2d00003a0000200841c8006a2108200941016a2109200541c8006a200a470d000b0b20024180026a41086a2009360200200220022903b803370380024100210b41002113024002400240024002400240200141106a2d00000e06050102030400050b200241a4026a200141136a2d00003a000020024190026a41086a200141286a29000037030020024190026a41106a200141306a2d00003a00002002200141116a2f00003b01a2022002200141206a290000370390022001411c6a2800002103200141186a2800002114200141146a2800002109410521130c040b2001411c6a2802002203417f4c0d0e200141146a280200210541012113024020030d00410021144101210941012005200310a1051a0c040b20032114200310212209450d0f20092005200310a1051a0c030b41022113200241a2026a41026a200141136a2d00003a000020024190026a41086a200141286a29000037030020024190026a41106a200141306a2d00003a00002002200141116a2f00003b01a2022002200141206a290000370390022001411c6a2800002103200141186a2800002114200141146a28000021090c020b200241a4026a200141136a2d00003a000020024190026a41086a200141286a29000037030020024190026a41106a200141306a2d00003a00002002200141116a2f00003b01a2022002200141206a290000370390022001411c6a2800002103200141186a2800002114200141146a2800002109410321130c010b200241a4026a200141136a2d00003a000020024190026a41086a200141286a29000037030020024190026a41106a200141306a2d00003a00002002200141116a2f00003b01a2022002200141206a290000370390022001411c6a2800002103200141186a2800002114200141146a2800002109410421130b024002400240024002400240200141346a2d00000e06050102030400050b200241bc026a200141376a2d00003a0000200241b0026a200141cc006a290000370300200241b8026a200141d4006a2d00003a00002002200141356a2f00003b01ba022002200141c4006a2900003703a802200141c0006a28000021052001413c6a2800002115200141386a280000210f4105210b0c040b200141c0006a2802002205417f4c0d0e200141386a28020021084101210b024020050d00410021154101210f41012008200510a1051a0c040b2005211520051021220f450d0f200f2008200510a1051a0c030b4102210b200241ba026a41026a200141376a2d00003a0000200241b0026a200141cc006a290000370300200241b8026a200141d4006a2d00003a00002002200141356a2f00003b01ba022002200141c4006a2900003703a802200141c0006a28000021052001413c6a2800002115200141386a280000210f0c020b200241bc026a200141376a2d00003a0000200241b0026a200141cc006a290000370300200241b8026a200141d4006a2d00003a00002002200141356a2f00003b01ba022002200141c4006a2900003703a802200141c0006a28000021052001413c6a2800002115200141386a280000210f4103210b0c010b200241bc026a200141376a2d00003a0000200241b0026a200141cc006a290000370300200241b8026a200141d4006a2d00003a00002002200141356a2f00003b01ba022002200141c4006a2900003703a802200141c0006a28000021052001413c6a2800002115200141386a280000210f4104210b0b4100211641002117024002400240024002400240200141d8006a2d00000e06050102030400050b200241d4026a200141db006a2d00003a0000200241c8026a200141f0006a290000370300200241d0026a200141f8006a2d00003a00002002200141d9006a2f00003b01d2022002200141e8006a2900003703c002200141e4006a2800002108200141e0006a2800002118200141dc006a2800002112410521170c040b200141e4006a2802002208417f4c0d0e200141dc006a280200210741012117024020080d00410021184101211241012007200810a1051a0c040b20082118200810212212450d0f20122007200810a1051a0c030b41022117200241d2026a41026a200141db006a2d00003a0000200241c8026a200141f0006a290000370300200241d0026a200141f8006a2d00003a00002002200141d9006a2f00003b01d2022002200141e8006a2900003703c002200141e4006a2800002108200141e0006a2800002118200141dc006a28000021120c020b200241d4026a200141db006a2d00003a0000200241c8026a200141f0006a290000370300200241d0026a200141f8006a2d00003a00002002200141d9006a2f00003b01d2022002200141e8006a2900003703c002200141e4006a2800002108200141e0006a2800002118200141dc006a2800002112410321170c010b200241d4026a200141db006a2d00003a0000200241c8026a200141f0006a290000370300200241d0026a200141f8006a2d00003a00002002200141d9006a2f00003b01d2022002200141e8006a2900003703c002200141e4006a2800002108200141e0006a2800002118200141dc006a2800002112410421170b024002400240024002400240200141fc006a2d00000e06050102030400050b200241ec026a200141ff006a2d00003a0000200241e0026a20014194016a290000370300200241e8026a2001419c016a2d00003a00002002200141fd006a2f00003b01ea0220022001418c016a2900003703d80220014188016a280000210720014184016a280000211920014180016a280000210e410521160c040b20014188016a2802002207417f4c0d0e20014180016a280200210c41012116024020070d00410021194101210e4101200c200710a1051a0c040b2007211920071021220e450d0f200e200c200710a1051a0c030b41022116200241ea026a41026a200141ff006a2d00003a0000200241e0026a20014194016a290000370300200241e8026a2001419c016a2d00003a00002002200141fd006a2f00003b01ea0220022001418c016a2900003703d80220014188016a280000210720014184016a280000211920014180016a280000210e0c020b200241ec026a200141ff006a2d00003a0000200241e0026a20014194016a290000370300200241e8026a2001419c016a2d00003a00002002200141fd006a2f00003b01ea0220022001418c016a2900003703d80220014188016a280000210720014184016a280000211920014180016a280000210e410321160c010b200241ec026a200141ff006a2d00003a0000200241e0026a20014194016a290000370300200241e8026a2001419c016a2d00003a00002002200141fd006a2f00003b01ea0220022001418c016a2900003703d80220014188016a280000210720014184016a280000211920014180016a280000210e410421160b4100211a4100211b024002400240024002400240200141a0016a2d00000e06050102030400050b20024186036a200141a3016a2d00003a0000200241f8026a200141b8016a29000037030020024180036a200141c0016a2d00003a00002002200141a1016a2f00003b0184032002200141b0016a2900003703f002200141ac016a280000210c200141a8016a280000211c200141a4016a28000021114105211b0c040b200141ac016a280200220c417f4c0d0e200141a4016a280200210d4101211b0240200c0d004100211c410121114101200d200c10a1051a0c040b200c211c200c10212211450d0f2011200d200c10a1051a0c030b4102211b20024184036a41026a200141a3016a2d00003a0000200241f8026a200141b8016a29000037030020024180036a200141c0016a2d00003a00002002200141a1016a2f00003b0184032002200141b0016a2900003703f002200141ac016a280000210c200141a8016a280000211c200141a4016a28000021110c020b20024186036a200141a3016a2d00003a0000200241f8026a200141b8016a29000037030020024180036a200141c0016a2d00003a00002002200141a1016a2f00003b0184032002200141b0016a2900003703f002200141ac016a280000210c200141a8016a280000211c200141a4016a28000021114103211b0c010b20024186036a200141a3016a2d00003a0000200241f8026a200141b8016a29000037030020024180036a200141c0016a2d00003a00002002200141a1016a2f00003b0184032002200141b0016a2900003703f002200141ac016a280000210c200141a8016a280000211c200141a4016a28000021114104211b0b02402001418c026a2d00004101470d0020024198036a2001419d026a28000036020020024190036a20014195026a29000037030020022001418d026a290000370388034101211a0b4100211d4100211e024002400240024002400240200141c4016a2d00000e06050102030400050b200241b4036a200141c7016a2d00003a0000200241a8036a200141dc016a290000370300200241b0036a200141e4016a2d00003a00002002200141c5016a2f00003b01b2032002200141d4016a2900003703a003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021064105211e0c040b200141d0016a280200220d417f4c0d0e200141c8016a28020021104101211e0240200d0d004100211f4101210641012010200d10a1051a0c040b200d211f200d10212206450d0f20062010200d10a1051a0c030b4102211e200241b2036a41026a200141c7016a2d00003a0000200241a8036a200141dc016a290000370300200241b0036a200141e4016a2d00003a00002002200141c5016a2f00003b01b2032002200141d4016a2900003703a003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021060c020b200241b4036a200141c7016a2d00003a0000200241a8036a200141dc016a290000370300200241b0036a200141e4016a2d00003a00002002200141c5016a2f00003b01b2032002200141d4016a2900003703a003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021064103211e0c010b200241b4036a200141c7016a2d00003a0000200241a8036a200141dc016a290000370300200241b0036a200141e4016a2d00003a00002002200141c5016a2f00003b01b2032002200141d4016a2900003703a003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021064104211e0b024002400240024002400240200141e8016a2d00000e06050102030400050b200241ce036a200141eb016a2d00003a0000200241c0036a20014180026a290000370300200241c8036a20014188026a2d00003a00002002200141e9016a2f00003b01cc032002200141f8016a2900003703b803200141f4016a2800002110200141f0016a2800002120200141ec016a280000210a4105211d0c040b200141f4016a2802002210417f4c0d0e200141ec016a28020021014101211d024020100d00410021204101210a41012001201010a1051a0c040b2010212020101021220a450d0f200a2001201010a1051a0c030b4102211d200241cc036a41026a200141eb016a2d00003a0000200241c0036a20014180026a290000370300200241c8036a20014188026a2d00003a00002002200141e9016a2f00003b01cc032002200141f8016a2900003703b803200141f4016a2800002110200141f0016a2800002120200141ec016a280000210a0c020b200241ce036a200141eb016a2d00003a0000200241c0036a20014180026a290000370300200241c8036a20014188026a2d00003a00002002200141e9016a2f00003b01cc032002200141f8016a2900003703b803200141f4016a2800002110200141f0016a2800002120200141ec016a280000210a4103211d0c010b200241ce036a200141eb016a2d00003a0000200241c0036a20014180026a290000370300200241c8036a20014188026a2d00003a00002002200141e9016a2f00003b01cc032002200141f8016a2900003703b803200141f4016a2800002110200141f0016a2800002120200141ec016a280000210a4104211d0b200241f0016a41086a220120024180026a41086a280200360200200241ec016a41026a2221200241a2026a41026a2d00003a0000200241d8016a41086a222220024190026a41086a290300370300200241d8016a41106a222320024190026a41106a2d00003a0000200241d4016a41026a22242002418d026a41026a2d00003a000020022002290380023703f001200220022f01a2023b01ec0120022002290390023703d801200220022f008d023b01d401200241d0016a41026a2225200241ba026a41026a2d00003a0000200241b8016a41086a2226200241a8026a41086a290300370300200241b8016a41106a2227200241a8026a41106a2d00003a0000200241b4016a41026a2228200241a5026a41026a2d00003a0000200241b0016a41026a2229200241d2026a41026a2d00003a0000200220022f01ba023b01d001200220022903a8023703b801200220022f00a5023b01b401200220022f01d2023b01b00120024198016a41106a222a200241c0026a41106a2d00003a000020024198016a41086a222b200241c0026a41086a29030037030020024194016a41026a222c200241bd026a41026a2d00003a000020024190016a41026a222d200241ea026a41026a2d00003a0000200241f8006a41106a222e200241d8026a41106a2d00003a0000200241f8006a41086a222f200241d8026a41086a290300370300200220022903c00237039801200220022f00bd023b019401200220022f01ea023b019001200220022903d802370378200241f4006a41026a2230200241d5026a41026a2d00003a0000200220022f00d5023b0174200241f0006a41026a223120024184036a41026a2d00003a0000200220022f0184033b0170200241d8006a41106a2232200241f0026a41106a2d00003a0000200241d8006a41086a2233200241f0026a41086a290300370300200220022903f002370358200241d4006a41026a2234200241ed026a41026a2d00003a0000200220022f00ed023b0154200241106a223520024188036a41106a280200360200200241086a223620024188036a41086a2903003703002002200229038803370300200241d0006a41026a2237200241b2036a41026a2d00003a0000200220022f01b2033b0150200241386a41106a2238200241a0036a41106a2d00003a0000200241386a41086a2239200241a0036a41086a290300370300200220022903a003370338200241346a41026a223a2002419d036a41026a2d00003a0000200220022f009d033b0134200241306a41026a223b200241cc036a41026a2d00003a0000200220022f01cc033b0130200241186a41106a223c200241b8036a41106a2d00003a0000200241186a41086a223d200241b8036a41086a290300370300200220022903b803370318200241146a41026a223e200241b5036a41026a2d00003a0000200220022f00b5033b0114200041106a20133a00002000410c6a2001280200360200200041046a20022903f0013702002000411c6a2003360000200041186a2014360000200041146a2009360000200041116a20022f01ec013b0000200041136a20212d00003a0000200041206a20022903d801370000200041286a2022290300370000200041306a20232d00003a0000200041336a20242d00003a0000200041316a20022f01d4013b0000200041346a200b3a0000200041376a20252d00003a0000200041356a20022f01d0013b0000200041c0006a20053600002000413c6a2015360000200041386a200f360000200041d4006a20272d00003a0000200041cc006a2026290300370000200041c4006a20022903b801370000200041d7006a20282d00003a0000200041d5006a20022f01b4013b0000200041d8006a20173a0000200041db006a20292d00003a0000200041d9006a20022f01b0013b0000200041e4006a2008360000200041e0006a2018360000200041dc006a2012360000200041f8006a202a2d00003a0000200041f0006a202b290300370000200041e8006a200229039801370000200041fb006a202c2d00003a0000200041f9006a20022f0194013b0000200041fc006a20163a0000200041ff006a202d2d00003a0000200041fd006a20022f0190013b000020004188016a200736000020004184016a201936000020004180016a200e3600002000419c016a202e2d00003a000020004194016a202f2903003700002000418c016a20022903783700002000419f016a20302d00003a00002000419d016a20022f01743b0000200041a0016a201b3a0000200041a3016a20312d00003a0000200041a1016a20022f01703b0000200041ac016a200c360000200041a8016a201c360000200041a4016a2011360000200041c0016a20322d00003a0000200041b8016a2033290300370000200041b0016a2002290358370000200041c3016a20342d00003a0000200041c1016a20022f01543b0000200041c4016a201e3a0000200041c7016a20372d00003a0000200041c5016a20022f01503b0000200041d0016a200d360000200041cc016a201f360000200041c8016a2006360000200041e4016a20382d00003a0000200041dc016a2039290300370000200041d4016a2002290338370000200041e7016a203a2d00003a0000200041e5016a20022f01343b0000200041e8016a201d3a0000200041eb016a203b2d00003a0000200041e9016a20022f01303b0000200041f4016a2010360000200041f0016a2020360000200041ec016a200a36000020004188026a203c2d00003a000020004180026a203d290300370000200041f8016a20022903183700002000418b026a203e2d00003a000020004189026a20022f01143b00002000418c026a201a3a00002000419d026a203528020036000020004195026a20362903003700002000418d026a2002290300370000200041a3026a20024188036a41026a2d00003a0000200041a1026a20022f0088033b0000200041023a00000c090b2001410c6a2802002203ad42c4007e2204422088a70d092004a72205417f4c0d09200141046a28020021060240024020050d00410421080c010b200510212208450d0b0b41002101200241003602c003200220083602b8032002200541c4006e3602bc03200241b8036a41002003109b0120022802c003210c02402003450d002006200341c4006c6a210a20022802b803200c41c4006c6a210b20024188036a41086a210d20024188036a41106a21100340200d200620016a220541176a29000037030020102005411f6a2d00003a0000200220052f01003b01a0032002200541026a2d00003a00a20320022005410f6a290000370388032005410b6a2800002109200541076a280000210f200541036a280000211241002108024002400240024002400240200541206a2d00000e06050102030400050b200241d8026a41026a200541236a2d00003a0000200241086a200541386a290000370300200241106a200541c0006a2d00003a00002002200541216a2f00003b01d8022002200541306a2900003703002005412c6a2800002107200541286a2800002111200541246a280000210e410521080c040b2005412c6a2802002207417f4c0d0f200541246a280200210341012108024020070d00410021114101210e41012003200710a1051a0c040b2007211120071021220e450d10200e2003200710a1051a0c030b41022108200241d8026a41026a200541236a2d00003a0000200241086a200541386a290000370300200241106a200541c0006a2d00003a00002002200541216a2f00003b01d8022002200541306a2900003703002005412c6a2800002107200541286a2800002111200541246a280000210e0c020b200241d8026a41026a200541236a2d00003a0000200241086a200541386a290000370300200241106a200541c0006a2d00003a00002002200541216a2f00003b01d8022002200541306a2900003703002005412c6a2800002107200541286a2800002111200541246a280000210e410321080c010b200241d8026a41026a200541236a2d00003a0000200241086a200541386a290000370300200241106a200541c0006a2d00003a00002002200541216a2f00003b01d8022002200541306a2900003703002005412c6a2800002107200541286a2800002111200541246a280000210e410421080b200b20016a220320022f01a0033b0100200341026a20022d00a2033a00002003410b6a2009360000200341076a200f360000200341036a20123600002003410f6a200229038803370000200341176a200d2903003700002003411f6a20102d00003a0000200341206a20083a0000200341216a20022f01d8023b0000200341236a200241d8026a41026a2d00003a00002003412c6a2007360000200341286a2011360000200341246a200e360000200341306a2002290300370000200341386a200241086a290300370000200341c0006a200241106a2d00003a0000200341c1006a20022f00f0023b0000200341c3006a200241f0026a41026a2d00003a0000200141c4006a2101200c41016a210c200541c4006a200a470d000b0b20024190036a200c360200200220022903b8032204370388032000410c6a200c360200200041046a2004370200200041033a00000c080b200041043a00000c070b200041053a0000200041106a200141106a290300370300200041086a200141086a290300370300200041046a200141046a2802003602000c060b200041063a0000200041046a200141046a2802003602000c050b200041073a0000200041106a200141106a290300370300200041086a200141086a290300370300200041046a200141046a2802003602000c040b200041083a000020002001290001370001200041246a200141246a280200360200200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c030b200041093a0000200041086a200141086a290300370300200041046a200141046a2802003602000c020b2000410a3a000020002001290001370001200041386a200141386a290300370300200041306a200141306a290300370300200041246a200141246a280200360200200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041286a200141286a3502003703000c010b2000410b3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000b200241d0036a24000f0b1032000b1033000bec0601057f230041206b2202240002400240024002400240024002400240024002400240024020012d0000417f6a220341084b0d0020030e09010203040506070809010b41f58ac7004128418c94c700102d000b200241186a2204200141196a290000370300200241106a2205200141116a290000370300200241086a2206200141096a2900003703002002200129000137030041b00210212203450d092003200141246a28020010dc03200041246a2003360200200041013a0000200041196a2004290300370000200041116a2005290300370000200041096a2006290300370000200020022903003700010c080b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000c070b2002200141046a108e02200041033a0000200041046a20022903003702002000410c6a200241086a280200360200200041106a200141106a280200360200200041026a200141026a2f01003b01000c060b200041043a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c050b200041053a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000c040b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c030b200041073a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c020b200041083a00000c010b200041093a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000b200241206a24000f0b102a000b110041f58ac7004128418c94c700102d000b130020004101360204200041b8a9c3003602000b130020004105360204200041a8adc3003602000bad150f047f017e017f027e057f017e077f017e057f017e027f017e027f037e077f230041e0016b22012400200141c0016a41186a22024200370300200141c0016a41106a22034200370300200141c0016a41086a22044200370300200142003703c00141b0dfc300ad4280808080a001842205100c220629000021072004200641086a290000370300200120073703c0012006102341a89ec700ad42808080809001842208100c22062900002107200141d0006a41086a2209200641086a2900003703002001200737035020061023200320012903502207370300200141a0016a41086a220a2004290300370300200141a0016a41106a220b2007370300200141a0016a41186a220c2009290300370300200120012903c0013703a001200141c0016a200141a0016a10c903024020012802c001220d450d000240024020012902c401220e422088a7220f0d0041002110200d21110c010b200d41046a2111200d2802002112410121100b200141c0016a41186a22134200370300200141c0016a41106a22144200370300200141c0016a41086a22154200370300200142003703c0014196adc300ad42808080809001842216100c22062900002107200141f0006a41086a2217200641086a290000370300200120073703702006102320152017290300370300200120012903703703c00141bce0c300ad4280808080e00084100c220629000021072017200641086a2900003703002001200737037020061023201420012903702207370300200141a0016a41086a22182015290300370300200141a0016a41106a22192007370300200141a0016a41186a221a2017290300370300200120012903c0013703a001200141c0016a200141a0016a10910320012802c0012206410420061b211b024020012902c401420020061b221c422088a72206450d00200d200f4102746a211d201b2006412c6c6a211e200141a0016aad4280808080800484211f201b2106034020152006410c6a2902003703002014200641146a29020037030020132006411c6a290200370300200120062902043703c001200641246a280200220f4103460d01200641286a280200212020062802002121200141106a41186a20132903002207370300200141106a41106a20142903002222370300200141106a41086a20152903002223370300200120012903c0012224370310200141306a41186a22252007370300200141306a41106a22262022370300200141306a41086a222720233703002001202437033002400240024002400240024020104101470d0020122021460d010b200f4101470d03200141d0006a41186a220f2025290300370300200141d0006a41106a22282026290300370300200141d0006a41086a2226202729030037030020012001290330370350202041024b0d03201342003703002014420037030020154200370300200142003703c0012016100c222529000021072017202541086a290000370300200120073703702025102320152017290300370300200120012903703703c00141a4e2c300ad4280808080a001842222100c222529000021072017202541086a290000370300200120073703702025102320142001290370370000201441086a222920172903003700002018201529030037030020192014290300370300201a2013290300370300200120012903c0013703a001200141c0016a200141a0016a108f0320012802c001222a0d0141002125200141003602880120014204370380014104212a0c020b02402011201d470d0041002110201d21110c030b2011280200211241012110201141046a21110c020b20012902c40121072001202a3602800120012007370284012007422088a721250b201a200f2903003703002019202829030037030020182026290300370300200120012903503703a0010240024020254103490d0041032126200141033602880120254103460d01202a41246a210f2025410c6c415c6a212503400240200f41046a2802002227450d00202741246c450d00200f28020010230b200f410c6a210f202541746a22250d000c020b0b20014180016a2025410320256b222b109501200128028001222a2001280288012226410c6c6a210f02400240202b4102490d002025417e6a21250340200141003602c801200142043703c001200141c0016a4100410010a201201720012802c8012227360200200120012903c0012207370370200f41086a2027360200200f2007370200202641016a2126200f410c6a210f202541016a222720254f21282027212520280d000b202b450d010b200f4204370200200f4100360208202641016a21260b20012026360288010b202620204d0d012013201a2903003703002014201929030037030020152018290300370300200120012903a0013703c001202a2020410c6c6a220f41086a21250240200f2802082226200f41046a280200470d00200f2026410110a201202528020021260b200f280200202641246c6a220f20012903c001370204200f2021360200200f410c6a2015290300370200200f41146a2014290300370200200f411c6a20132903003702002025202528020041016a36020020014190016a41086a20014180016a41086a2802003602002001200129038001220737039001201342003703002014420037030020154200370300200142003703c0012016100c220f29000021232017200f41086a29000037030020012023370370200f102320152017290300370300200120012903703703c0012022100c220f29000021222017200f41086a29000037030020012022370370200f102320142001290370370000202920172903003700002018201529030037030020192014290300370300201a2013290300370300200120012903c0013703a00102402007a722270d00201f10110c010b200141203602c4012001200141a0016a3602c00120014190016a200141c0016a1090030240200128029801220f450d00200f410c6c21252027210f03400240200f41046a2802002226450d00202641246c450d00200f28020010230b200f410c6a210f202541746a22250d000b0b200128029401220f450d00200f410c6c450d00202710230b2006412c6a2206201e470d010c020b0b2020202641e8afc3001030000b0240201ca72206450d002006412c6c450d00201b10230b200e42ffffffff0383500d00200d10230b200242003703002003420037030020044200370300200142003703c00141b9f4c200ad4280808080c00184100c220629000021072004200641086a290000370300200120073703c001200610232008100c220629000021072009200641086a290000370300200120073703502006102320032001290350370000200341086a2009290300370000200a2004290300370300200b2003290300370300200c2002290300370300200120012903c0013703a001200141a0016aad42808080808004841011200242003703002003420037030020044200370300200142003703c0012005100c220629000021072004200641086a290000370300200120073703c001200610232008100c220629000021072009200641086a2900003703002001200737035020061023200320012903502207370300200a2004290300370300200b2007370300200c2009290300370300200120012903c0013703a001200141086a200141a0016a4120419ca8c70041004100108c01024020012802084101470d00200010e803200141e0016a24000f0b41ce83c3004131418c94c700102d000bc36008047f017e017f027e077f017e057f047e230041e0026b22012400200141e0006a41186a4200370300200141e0006a41106a22024200370300200141e0006a41086a220342003703002001420037036041ecf7c300ad4280808080f00184100c22042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004102320032006290300370300200120012903c00237036041fbf7c300ad4280808080d00184100c220429000021052006200441086a290000370300200120053703c00220041023200220012903c0022205370300200141a0026a41086a2003290300370300200141a0026a41106a2005370300200141a0026a41186a2006290300370300200120012903603703a002200141203602cc012001200141a0026a3602c801200141c0026a200141a0026aad2207428080808080048422081010108b010240024020012802c00222030d004102210620014102360294020c010b20012802c40221092001200628020022063602d401200120033602d0010240024020064104490d002001200341046a3602d00120012006417c6a22043602d40120044104490d002003280000210a2001200641786a3602d4012001200341086a3602d0012003280004210b200141e0006a200141d0016a1084042001280260220c450d0020012902642105410021060240024020012802d401220d0d000c010b2001200d417f6a220e3602d401200120012802d001220f41016a3602d0010240200f2d00004101460d000c010b200e4104490d002001200d417b6a3602d4012001200f41056a3602d001200f2800012104410121060b20012004360298022001200537028c022001200c360288022001200b360284022001200a360280020c010b200141003602e801200142013703e0012001410a3602d4022001200141c8016a3602d0022001200141e0016a3602dc01200141f4006a41013602002001420137026420014180c5c6003602602001200141d0026a360270200141dc016a4184a5c200200141e0006a10311a20013502e80142208620013502e00184100a024020012802e401450d0020012802e00110230b410221060b20012006360294022009450d00200310230b200141e0006a41106a220320014180026a41106a2209280200360200200141e0006a41086a220a20014180026a41086a220b29030037030020012001290380023703600240024002400240024002400240024020064102460d00200141e0016a41106a20032802002203360200200141e0016a41086a200a29030022103703002001200129036022053703e00120092003360200200b201037030020014198026a20043602002001200537038002200120063602940202402005a722032000470d00410121030240024020064101460d002001280284022106200141a0026a20014180026a41086a108504200141f0006a2006360200200141ec006a200141a0026a41086a280200360200200120012903a00237026441002103200141e0006a21060c010b2001280284022106200141a0026a20014180026a41086a108504200141f4006a2006360200200141e0006a41086a20012903a002370300200141f0006a200141a0026a41086a28020036020020012004360264200141e0006a21060b20062003360200200610f70320012802800221030b024020012802840220036a2000470d00200120014188026a220d3602642001410036026020014190026a28020041286c4105722206417f4c0d02200610212203450d03200341013a0000200120063602a402200120033602a002200141013602a80220012802880221062001280290022203200141a0026a10610240024020030d0020012802a802210320012802a002210b0c010b2006200341286c6a210c20012802a402210920012802a8022103034002400240200920036b4120490d00200341206a210420012802a002210b2009210a0c010b200341206a22042003490d072009410174220a2004200a20044b1b220a4100480d070240024020090d000240200a0d004101210b0c020b200a1021220b0d010c0d0b20012802a002210b2009200a460d00200b2009200a1025220b450d0c0b2001200a3602a4022001200b3602a0020b200b20036a22032006290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a290000370000200120043602a802200641206a290300210502400240200a20046b4108490d00200441086a2103200a21090c010b200441086a22032004490d07200a41017422092003200920034b1b22094100480d0702400240200a0d00024020090d004101210b0c020b20091021220b450d0d0c010b200a2009460d00200b200a20091025220b450d0c0b200120093602a4022001200b3602a0020b200b20046a2005370000200120033602a802200c200641286a2206470d000b0b20012802a402210641eeebc300ad4280808080c002842003ad422086200bad84100e02402006450d00200b10230b02402001280260450d00200141e8006a2802002206450d00200641286c450d00200128026410230b200141e0006a41086a2206200d290000370300200141e0006a41106a2204200d41086a28000036020020014100360264200141063a0060200141e0006a10e001200141e0006a41186a220a420037030020044200370300200642003703002001420037036041ecf7c300ad4280808080f00184100c22092900002105200141c0026a41086a2203200941086a290000370300200120053703c0022009102320062003290300370300200120012903c00237036041fbf7c300ad4280808080d00184100c220929000021052003200941086a290000370300200120053703c00220091023200220012903c002370000200241086a2003290300370000200141a0026a41086a2006290300370300200141a0026a41106a2004290300370300200141a0026a41186a200a290300370300200120012903603703a002200810110c010b2001418c026a2802002206450d00200641286c450d0020012802880210230b200141e0006a41186a22094200370300200141e0006a41106a220a4200370300200141e0006a41086a220342003703002001420037036041ecf7c300ad4280808080f00184100c22042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004102320032006290300370300200120012903c0023703604188f8c300ad4280808080d00084100c220429000021052006200441086a290000370300200120053703c00220041023200220012903c002370000200241086a2006290300370000200141a0026a41086a2003290300370300200141a0026a41106a200a290300370300200141a0026a41186a2009290300370300200120012903603703a002200141203602c4022001200141a0026a3602c002200141e0016a20081010108b0120012802e0012206450d0520012802e4012104024002400240200141e0016a41086a2802002209450d0020062d0000220a41034b0d0041002103024002400240200a0e0405000102050b2009417f6a4108490d0220062900012105410121030c040b410221030c020b2009417f6a4108490d0020062900012105410321030c020b200141003602880220014201370380022001410a3602d4022001200141c0026a3602d002200120014180026a3602d001200141f4006a41013602002001420137026420014180c5c6003602602001200141d0026a360270200141d0016a4184a5c200200141e0006a10311a20013502880242208620013502800284100a0240200128028402450d0020012802800210230b410421030b0b02402004450d00200610230b2003417f6a220641024b0d0520060e03040503040b1032000b1033000b102c000b2005422088a7210602402005a722032000470d002001410436026020012006360264200141e0006a10f7030b200620036a2000470d012001410036028002200141e0006a41186a22094200370300200141e0006a41106a220a4200370300200141e0006a41086a220342003703002001420037036041ecf7c300ad4280808080f00184100c22042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004102320032006290300370300200120012903c0023703604188f8c300ad4280808080d00084100c220429000021052006200441086a290000370300200120053703c00220041023200220012903c002370000200241086a2006290300370000200141a0026a41086a2003290300370300200141a0026a41106a200a290300370300200141a0026a41186a2009290300370300200120012903603703a002200141e0006a20014180026a1086042008200135026842208620012802602206ad84100e02402001280264450d00200610230b20014102360264200141063a0060200141e0006a10e0010c010b2005422088a7210602402005a722032000470d002001410336026020012006360264200141e0006a10f7030b200620036a2000470d002001410236028002200141e0006a41186a22094200370300200141e0006a41106a220a4200370300200141e0006a41086a220342003703002001420037036041ecf7c300ad4280808080f00184100c22042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004102320032006290300370300200120012903c0023703604188f8c300ad4280808080d00084100c220429000021052006200441086a290000370300200120053703c00220041023200220012903c002370000200241086a2006290300370000200141a0026a41086a2003290300370300200141a0026a41106a200a290300370300200141a0026a41186a2009290300370300200120012903603703a002200141e0006a20014180026a1086042008200135026842208620012802602206ad84100e02402001280264450d00200610230b20014101360264200141063a0060200141e0006a10e0010b200141e0006a41186a22044200370300200141e0006a41106a220d4200370300200141e0006a41086a220342003703002001420037036041fee2c200ad4280808080f001842205100c2209290000210820014180026a41086a2206200941086a29000037030020012008370380022009102320032006290300370300200120012903800237036041e1e6c200ad4280808080e00084100c220929000021082006200941086a290000370300200120083703800220091023200d2001290380022208370300200141a0026a41086a220a2003290300370300200141a0026a41106a220b2008370300200141a0026a41186a220c2006290300370300200120012903603703a002200141d8006a200141a0026a412010cd01200128025c210f0240200128025822024101470d002007428080808080048410110b20044200370300200d420037030020034200370300200142003703602005100c220929000021052006200941086a29000037030020012005370380022009102320032006290300370300200120012903800237036041f4bdc500ad4280808080b00184100c220929000021052006200941086a290000370300200120053703800220091023200d200129038002370000200d41086a2006290300370000200a2003290300370300200b200d290300370300200c2004290300370300200120012903603703a00202400240200141a0026a108103220641ff01714102460d0020064101710d010b41041021220a450d01200a4100360200200141e0006a41186a22044200370300200141e0006a41106a22094200370300200141e0006a41086a220342003703002001420037036041fee2c200ad4280808080f001842205100c220b290000210820014180026a41086a2206200b41086a2900003703002001200837038002200b102320032006290300370300200120012903800237036041a0e3c200ad4280808080b00184100c220b29000021082006200b41086a2900003703002001200837038002200b1023200d200129038002370000200d41086a220b2006290300370000200141a0026a41086a220c2003290300370300200141a0026a41106a22002009290300370300200141a0026a41186a220e2004290300370300200120012903603703a002200141203602642001200141a0026a360260200a4101200141e0006a10f603200a102341041021220a450d01200a4100360200200442003703002009420037030020034200370300200142003703602005100c221129000021082006201141086a29000037030020012008370380022011102320032006290300370300200120012903800237036041e7e6c200ad4280808080c00184100c221129000021082006201141086a290000370300200120083703800220111023200d200129038002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903603703a002200141203602642001200141a0026a360260200a4101200141e0006a10f603200a1023200442003703002009420037030020034200370300200142003703602005100c220a29000021082006200a41086a2900003703002001200837038002200a102320032006290300370300200120012903800237036041f3e6c200ad4280808080e00084100c220a29000021082006200a41086a2900003703002001200837038002200a1023200d200129038002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903603703a00220014100360260200742808080808004842208200141e0006aad22104280808080c00084100e200442003703002009420037030020034200370300200142003703602005100c220a29000021052006200a41086a2900003703002001200537038002200a102320032006290300370300200120012903800237036041f4bdc500ad4280808080b00184100c220a29000021052006200a41086a2900003703002001200537038002200a1023200d200129038002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903603703a002200141013a00602008201042808080801084100e0b200141e0006a41186a4200370300200141e0006a41106a22124200370300200141e0006a41086a220642003703002001420037036041fee2c200ad4280808080f00184100c220329000021052006200341086a290000370300200120053703602003102341a0e3c200ad4280808080b00184100c2203290000210520014180026a41086a2204200341086a29000037030020012005370380022003102320122001290380022205370300200141a0026a41086a2006290300370300200141a0026a41106a2005370300200141a0026a41186a2004290300370300200120012903603703a002200141e0006a200141a0026a10ed03024002402001280260220e0d0041002113200141003602c802200142043703c0024104210e410021110c010b2001200129026422053702c4022001200e3602c0022005422088a721112005a721130b200141e0006a41186a22094200370300200141e0006a41106a220a4200370300200141e0006a41086a220342003703002001420037036041fee2c200ad4280808080f00184100c2204290000210520014180026a41086a2206200441086a29000037030020012005370380022004102320032006290300370300200120012903800237036041e7e6c200ad4280808080c00184100c220429000021052006200441086a290000370300200120053703800220041023200d200129038002370000200d41086a2006290300370000200141a0026a41086a2003290300370300200141a0026a41106a200a290300370300200141a0026a41186a2009290300370300200120012903603703a002200141e0006a200141a0026a10ed03024002402001280260220a0d0041002114200141003602e801200142043703e0014104210a4100210c0c010b2001200129026422053702e4012001200a3602e0012005422088a7210c2005a721140b0240024002400240024020020d002011450d012011410274200e6a417c6a280200210f0b201141002011419c7f6a22062006201141016a4b1b2215490d01200141003602c8022015450d03200e20154102746a2100200e210203402002280200210b02400240024002400240200c41014b0d0041002106200c0e020201020b41002106200c2103034020062003410176220420066a2209200b200a20094102746a280200491b2106200320046b220341014b0d000b0b200b200a200641027422036a2802002204460d022006200b20044b6a21060c010b410021060b2001200636026041b0e7c200412e200141e0006a41e0e7c20041f0e7c2001034000b200c20064d0d03200a20036a2203200341046a2006417f73200c6a41027410a2051a2001200c417f6a220c3602e801200241046a22022000470d000c040b0b41f9e6c200412641a0e7c200104f000b20152011103c000b2006200c103b000b410021064100210b0240201120156b2203450d0002402015450d00200e200e20154102746a200341027410a2051a0b200120033602c8022003210b0b024002400240200c41014b0d00200c0e020201020b41002106200c2103034020062003410176220420066a2209200f200a20094102746a280200491b2106200320046b220341014b0d000b0b0240200f200a20064102746a2802002203460d002006200f20034b6a21060b200c20064f0d002006200c1038000b0240200c2014470d00200141e0016a20144101107920012802e001210a0b200a20064102746a220341046a2003200c20066b41027410a2051a2003200f3602002001200c41016a22033602e8010240200b2013470d00200141c0026a20134101107920012802c002210e20012802c802210b0b200e200b4102746a200f3602002001200b41016a220b3602c80202400240024002400240024002402003450d00200341017621062003410171450d01200320064d0d03200a20064102746a28020021000c020b4180e8c20041c300418c94c700102d000b200320064d0d0220032006417f6a22044d0d03200a20044102746a280200200a20064102746a2802006a41017621000b20012802c4022102200141e0006a41186a22094200370300200141e0006a41106a220a4200370300200141e0006a41086a220442003703002001420037036041fee2c200ad4280808080f001842205100c220c290000210820014180026a41086a2206200c41086a2900003703002001200837038002200c102320042006290300370300200120012903800237036041a0e3c200ad4280808080b00184100c220c29000021082006200c41086a2900003703002001200837038002200c1023200d200129038002370000200d41086a220f2006290300370000200141a0026a41086a22112004290300370300200141a0026a41106a2215200a290300370300200141a0026a41186a22132009290300370300200120012903603703a002200141203602642001200141a0026a360260200e200b200141e0006a10f6030240200241ffffffff0371450d00200e10230b20012802e401210e20012802e001210220094200370300200a420037030020044200370300200142003703602005100c220c29000021052006200c41086a2900003703002001200537038002200c102320042006290300370300200120012903800237036041e7e6c200ad4280808080c00184100c220c29000021052006200c41086a2900003703002001200537038002200c1023200d200129038002370000200f2006290300370000201120042903003703002015200a29030037030020132009290300370300200120012903603703a002200141203602642001200141a0026a36026020022003200141e0006a10f6030240200e41ffffffff0371450d00200210230b200141e0006a41186a22094200370300200141e0006a41106a22044200370300200141e0006a41086a220342003703002001420037036041fee2c200ad4280808080f00184100c220a290000210520014180026a41086a2206200a41086a2900003703002001200537038002200a102320032006290300370300200120012903800237036041f3e6c200ad4280808080e00084100c220a29000021052006200a41086a2900003703002001200537038002200a1023200d200129038002370000200d41086a2006290300370000200141a0026a41086a220a2003290300370300200141a0026a41106a220c2004290300370300200141a0026a41186a22022009290300370300200120012903603703a0022001200036026020074280808080800484200141e0006aad22084280808080c00084100e0240200b41e500470d002009420037030020044200370300200342003703002001420037036041e4dec400ad4280808080e00084100c220b29000021052003200b41086a29000037030020012005370360200b102341f3dec400ad4280808080e00084100c220b29000021052006200b41086a2900003703002001200537038002200b10232012200129038002370000201241086a2006290300370000200a2003290300370300200c200429030037030020022009290300370300200120012903603703a002200141d0006a200141a0026a412010cd010b20094200370300200442003703002003420037030020014200370360418fcdc200ad4280808080f000842210100c220929000021052006200941086a29000037030020012005370380022009102320032006290300370300200120012903800237036041b8dbc100ad42808080809001842216100c220929000021052006200941086a29000037030020012005370380022009102320042001290380022205370300200a2003290300370300200c200537030020022006290300370300200120012903603703a002200141e0006a200141a0026a10ba01024002402001290360427f7c4201560d00200141a0026a21020c010b20042903002117200141e0006a41186a220a4200370300200141e0006a41106a22094200370300200141e0006a41086a220642003703002001420037036041b494c700ad4280808080900184100c220329000021052006200341086a290000370300200120053703602003102341bd94c700ad42808080803084100c220b290000210520014180026a41086a2203200b41086a2900003703002001200537038002200b102320092001290380022205370300200141a0026a41086a220c2006290300370300200141a0026a41106a22022005370300200141a0026a41186a22002003290300370300200120012903603703a002200141c0006a200141a0026a10fa02200141306a2001290348420020012802401b221842e807802219420042e807420010a605200a42003703002009420037030020064200370300200142003703602010100c220b29000021052003200b41086a2900003703002001200537038002200b10232006200329030037030020012001290380023703602016100c220b29000021052003200b41086a2900003703002001200537038002200b10232004200129038002370000200441086a2003290300370000200c2006290300370300200220092903003703002000200a290300370300200120012903603703a00220012903302105200141306a41086a2903002110410410212206450d05200620173e000020064104410810252206450d05200641013a000420064108411010252206450d0520062005201820194298787e7c42ff07837c2216427f20102016200554ad7c501b370005200742808080808004842006ad4280808080d00184100e20061023200141a0026a21020b200141e0006a41186a22094200370300200141e0006a41106a22044200370300200141e0006a41086a220342003703002001420037036041fea6c600ad4280808080a001842205100c220629000021102003200641086a29000037030020012010370360200610234188a7c600ad4280808080e00084100c220a290000211020014180026a41086a2206200a41086a2900003703002001201037038002200a102320042001290380022210370300200141a0026a41086a220a2003290300370300200141a0026a41106a220b2010370300200141a0026a41186a220c2006290300370300200120012903603703a0022002ad428080808080048422101011200942003703002004420037030020034200370300200142003703602005100c220229000021052003200241086a29000037030020012005370360200210234198bdc600ad4280808080c00184100c220229000021052006200241086a29000037030020012005370380022002102320042001290380022205370300200a2003290300370300200b2005370300200c2006290300370300200120012903603703a002201010112009420037030020044200370300200342003703002001420037036041c599c500ad4280808080a00284100c220229000021052006200241086a29000037030020012005370380022002102320032006290300370300200120012903800237036041b09ac500ad4280808080900284100c220229000021052006200241086a29000037030020012005370380022002102320042001290380022205370300200a2003290300370300200b2005370300200c2006290300370300200120012903603703a002200141206a200141a0026a10fa02200129032821102001280220210b20014180026a41186a420037030020014180026a41106a220c420037030020064200370300200142003703800241e4dec400ad4280808080e00084100c220a29000021052006200a41086a2900003703002001200537038002200a102341e8ffc400ad4280808080b00284100c220a2900002105200141c0026a41086a2202200a41086a290000370300200120053703c002200a1023200c20012903c00222053703002003200629030037030020042005370300200920022903003703002001200129038002370360200141186a200141e0006a412010cd01200141086a200128021c410020012802181b22064180e59af70020064180e59af7004b22031b4180e59af700200620031b6bad220542002005420010a605200542a8c30180211620104200200b1b210542092001290308221042808090bbbad6adf00d7f20012903102010423f87521b211002400240200641ffe49af7004b0d0042ffffffffffffffffff00428080808080808080807f2005201620107d22167d22104200531b20102005427f5522062016427f554720062010427f5547711b22054280ec94a37c20054280ec94a37c551b21050c010b42ffffffffffffffffff00428080808080808080807f2005201620107c22167c22104200531b20102005427f5522062016427f554620062010427f5547711b21050b200141e0006a41186a220a4200370300200141e0006a41106a22094200370300200141e0006a41086a220642003703002001420037036041c599c500ad4280808080a00284100c220b290000211020014180026a41086a2203200b41086a2900003703002001201037038002200b102320062003290300370300200120012903800237036041b09ac500ad4280808080900284100c220b29000021102003200b41086a2900003703002001201037038002200b10232004200129038002370000200441086a2003290300370000200141a0026a41086a220b2006290300370300200141a0026a41106a220c2009290300370300200141a0026a41186a2202200a290300370300200120012903603703a0022001200537036020074280808080800484220520084280808080800184100e200a420037030020094200370300200642003703002001420037036041b494c700ad4280808080900184100c220429000021102006200441086a290000370300200120103703602004102341a89ec700ad4280808080900184100c220429000021102003200441086a29000037030020012010370380022004102320092001290380022210370300200b2006290300370300200c201037030020022003290300370300200120012903603703a002200141a0026a108103220641ff01714102460d03200510112006410171450d03200141e0006a41186a4200370300200141e0006a41106a22064200370300200141e0006a41086a220442003703002001420037036041a7b3c500ad4280808080c00084100c22092900002105200141c0026a41086a2203200941086a290000370300200120053703c0022009102320042003290300370300200120012903c00237036041f4bdc500ad4280808080b00184100c220929000021052003200941086a290000370300200120053703c00220091023200620012903c0022205370300200141a0026a41086a2004290300370300200141a0026a41106a2005370300200141a0026a41186a2003290300370300200120012903603703a002200141e0006a200141a0026a108704024020012d006022034102460d00200742808080808004841011200141e0016a41086a200141e9006a290000370300200141e0016a41106a200141f1006a290000370300200141e0016a41186a200141f9006a290000370300200120012900613703e0010240200341037122034103460d0020030e03010001010b20014180026a41186a200141e0016a41186a29030037030020014180026a41106a200141e0016a41106a29030037030020014180026a41086a200141e0016a41086a290300370300200120012903e00137038002200141e0006a41186a220a4200370300200141e0006a41106a220b4200370300200141e0006a41086a220442003703002001420037036041a7b3c500ad4280808080c00084100c22092900002105200141c0026a41086a2203200941086a290000370300200120053703c0022009102320042003290300370300200120012903c00237036041e0bcc500ad4280808080c00184100c220929000021052003200941086a290000370300200120053703c00220091023200620012903c002370000200641086a2003290300370000200141a0026a41086a2004290300370300200141a0026a41106a200b290300370300200141a0026a41186a200a290300370300200120012903603703a0022001200141a0026a412010cd0141002109200141e0006a2001280204410020012802001b220a108804200141a0026a2001280260220b20012802681089040240024020012802a00222040d00200141003602d802200142013703d00241012104410021030c010b200120012902a40222053702d402200120043602d0022005422088a721032005a721090b02402001280264450d00200b10230b024002402003418002490d00412010212203450d072003200129038002370000200341186a20014180026a41186a290300370000200341106a20014180026a41106a290300370000200341086a20014180026a41086a290300370000200141e0006a200a41016a220a10880420012802602104200120012802683602a402200120043602a00220034101200141a0026a109c0202402001280264450d00200410230b20031023200141e0006a41186a220b4200370300200141e0006a41106a220c4200370300200141e0006a41086a220442003703002001420037036041a7b3c500ad4280808080c00084100c22092900002105200141c0026a41086a2203200941086a290000370300200120053703c0022009102320042003290300370300200120012903c00237036041e0bcc500ad4280808080c00184100c220929000021052003200941086a290000370300200120053703c00220091023200620012903c002370000200641086a2003290300370000200141a0026a41086a2004290300370300200141a0026a41106a200c290300370300200141a0026a41186a200b290300370300200120012903603703a0022001200a3602602007428080808080048420084280808080c00084100e200141d0026a21030c010b200141e0006a41186a220b20014180026a41186a290300370300200141e0006a41106a220c20014180026a41106a290300370300200141e0006a41086a220220014180026a41086a2903003703002001200129038002370360024020032009470d00200141d0026a20094101109a0120012802d002210420012802d80221030b200420034105746a22092001290360370000200941186a200b290300370000200941106a200c290300370000200941086a20022903003700002001200341016a22093602d802200141e0006a200a10880420012802602103200120012802683602a402200120033602a00220042009200141a0026a109c0202402001280264450d00200310230b200141d0026a21030b200341046a28020041ffffff3f71450d00200328020010230b200141e0006a41186a220a4200370300200141e0006a41106a220b4200370300200141e0006a41086a220442003703002001420037036041a7b3c500ad4280808080c00084100c22092900002105200141c0026a41086a2203200941086a290000370300200120053703c0022009102320042003290300370300200120012903c00237036041abb3c500ad4280808080800184100c220929000021052003200941086a290000370300200120053703c00220091023200620012903c002370000200641086a2003290300370000200141a0026a41086a2004290300370300200141a0026a41106a200b290300370300200141a0026a41186a200a290300370300200120012903603703a002200742808080808004841011200141e0026a24000f0b2006200341c4e8c2001030000b2006200341d4e8c2001030000b2004200341e4e8c2001030000b41e093c700412b418c94c700102d000b102a000ba383020c047f017e017f017e037f017e097f017e1f7f047e067f027e230041800d6b2201240010ea030240024002400240024002400240024002400240024020004101460d00200141e8036a41186a4200370300200141e8036a41106a22024200370300200141e8036a41086a22034200370300200142003703e80341a7b3c500ad4280808080c00084100c220429000021052003200441086a290000370300200120053703e8032004102341a4bbc500ad4280808080b00184100c22042900002105200141d8076a41086a2206200441086a290000370300200120053703d80720041023200220012903d8072205370300200141c8036a41086a2003290300370300200141c8036a41106a2005370300200141c8036a41186a2006290300370300200120012903e8033703c803200141b8036a200141c8036a10fa02420020012903c003420020012802b8031b220510eb037d220720072005561b42d804540d00200141c00b6a41186a22084200370300200141c00b6a41106a22094200370300200141c00b6a41086a22034200370300200142003703c00b41db97c700ad4280808080f000842205100c220a290000210720014198066a41086a2204200a41086a2900003703002001200737039806200a10232003200429030037030020012001290398063703c00b41bcbcc300ad4280808080c001842207100c220a290000210b2004200a41086a2900003703002001200b37039806200a10232009200129039806220b370300200141a00a6a41086a220c2003290300370300200141a00a6a41106a220d200b370300200141a00a6a41186a220e2004290300370300200120012903c00b3703a00a200141b0036a200141a00a6a412010cd0120012802b403210f20012802b0032110200842003703002009420037030020034200370300200142003703c00b2005100c220a290000210b2004200a41086a2900003703002001200b37039806200a10232003200429030037030020012001290398063703c00b41d0bcc300ad4280808080d00184100c220a290000210b2004200a41086a2900003703002001200b37039806200a10232009200129039806220b370300200c2003290300370300200d200b370300200e2004290300370300200120012903c00b3703a00a200141a00a6a1081032111200842003703002009420037030020034200370300200142003703c00b2005100c220a290000210b2003200a41086a2900003703002001200b3703c00b200a10232007100c220a29000021072006200a41086a290000370300200120073703d807200a1023200920012903d80722073703002004200329030037030020014198066a41106a220a200737030020014198066a41186a220c2006290300370300200120012903c00b37039806200141a8036a20014198066a412010cd0120012802ac03211220012802a8032113200842003703002009420037030020034200370300200142003703c00b4180cdc200ad4280808080800184100c220d29000021072003200d41086a290000370300200120073703c00b200d102341d7a1c200ad4280808080c00084100c220d29000021072006200d41086a290000370300200120073703d807200d1023200920012903d807220737030020042003290300370300200a2007370300200c2006290300370300200120012903c00b37039806200141c00b6a20014198066a10ad0220012802c00b211420012902c40b2115200842003703002009420037030020034200370300200142003703c00b2005100c220829000021052003200841086a290000370300200120053703c00b2008102341bbacc300ad4280808080a00184100c220829000021052006200841086a290000370300200120053703d80720081023200920012903d807220537030020042003290300370300200a2005370300200c2006290300370300200120012903c00b37039806200141c00b6a20014198066a412010890220012802c00b2203410120031b211620012902c40b420020031b2205a721170240024002402005422088a72203450d002016200341057422186a2119200141dc056a211a200141c00b6a41206a210d20014190056a410472210a200141e8046a410472210441002108410221030340200141b8046a41186a201620086a220641186a220c290000370300200141b8046a41106a200641106a220e290000370300200141b8046a41086a200641086a221b290000370300200120062900003703b80420042006290000370000200441086a201b290000370000200441106a200e290000370000200441186a200c29000037000020012003417e6a220e3602e8044100210c0240200e200410ac020d0020014190056a41206a200141e8046a41206a28020036020020014190056a41186a200141e8046a41186a29030037030020014190056a41106a200141e8046a41106a29030037030020014190056a41086a200141e8046a41086a290300370300200120012903e80437039005200141c8036a41186a220c200a41186a221b290200370300200141c8036a41106a221c200a41106a221d290200370300200141c8036a41086a221e200a41086a221f2902003703002001200a2902003703c803200141c00b6a41186a220e201b290000370300200141c00b6a41106a221b201d290000370300200141c00b6a41086a221d201f2900003703002001200a2900003703c00b200141b8056a200141c00b6a108f02200141e8036a41186a221f200c290300370300200141e8036a41106a2220201c290300370300200141e8036a41086a221c201e290300370300200120012903c8033703e80320012802d805220c450d00200d20012903b805370300200d41186a200141b8056a41186a290300370300200d41106a200141b8056a41106a290300370300200d41086a200141b8056a41086a290300370300200e201f290300370300201b2020290300370300201d201c290300370300200141d8046a41086a221c201a41086a280200360200200120012903e8033703c00b2001201a2902003703d804200141a00a6a41386a221e200141c00b6a41386a290300370300200141a00a6a41306a221f200141c00b6a41306a290300370300200141a00a6a41286a2220200141c00b6a41286a290300370300200141a00a6a41206a2221200d290300370300200141a00a6a41186a2222200e290300370300200141a00a6a41106a220e201b290300370300200141a00a6a41086a221b201d290300370300200120012903c00b3703a00a20014198066a41386a201e29030037030020014198066a41306a201f29030037030020014198066a41286a202029030037030020014198066a41206a202129030037030020014198066a41186a202229030037030020014198066a41106a200e29030037030020014198066a41086a201b290300370300200120012903a00a3703980620014188066a41086a201c280200360200200120012903d804370388060b200141d8076a41086a20014198066a41086a290300370300200141d8076a41106a20014198066a41106a290300370300200141d8076a41186a20014198066a41186a290300370300200141d8076a41206a20014198066a41206a290300370300200141d8076a41286a20014198066a41286a290300370300200141d8076a41306a20014198066a41306a290300370300200141d8076a41386a20014198066a41386a290300370300200141f8056a41086a20014188066a41086a28020036020020012001290398063703d80720012001290388063703f805200c0d02200341016a21032018200841206a2208470d000b0b20014100360290042001420837038804201741ffffff3f71450d01201610230c010b20014180096a41386a2204200141d8076a41386a29030037030020014180096a41306a220a200141d8076a41306a29030037030020014180096a41286a220e200141d8076a41286a29030037030020014180096a41206a221b200141d8076a41206a29030037030020014180096a41186a221d200141d8076a41186a29030037030020014180096a41106a221c200141d8076a41106a29030037030020014180096a41086a221e200141d8076a41086a290300370300200141a8046a41086a221f200141f8056a41086a280200360200200120012903d80737038009200120012903f8053703a804200141e8056a41086a2220201f280200360200200120012903a8043703e805200141c00b6a41086a221f201e290300370300200141c00b6a41106a221e201c290300370300200141c00b6a41186a221c201d290300370300200141c00b6a41206a221a201b290300370300200141c00b6a41286a221b200e290300370300200141c00b6a41306a220e200a290300370300200141c00b6a41386a220a200429030037030020012001290380093703c00b20014198066a41086a22042020280200360200200120012903e8053703980641d0001021221d450d07201d20012903c00b370300201d200c360240201d200129039806370244201d41386a200a290300370300201d41306a200e290300370300201d41286a201b290300370300201d41206a201a290300370300201d41186a201c290300370300201d41106a201e290300370300201d41086a201f290300370300201d41cc006a2004280200360200200142818080801037029c042001201d360298040240201841606a2008460d00200641206a2104201820086b41606a211b200141dc056a211a20014190056a410472210a200141e8046a41047221060340200141b8046a41186a200441186a2208290000370300200141b8046a41106a200441106a220c290000370300200141b8046a41086a200441086a220e290000370300200120042900003703b80420042900002105200641186a200829000037000020062005370000200641086a200e290000370000200641106a200c29000037000020012003417f6a220c3602e804410021080240200c200610ac020d0020014190056a41206a200141e8046a41206a28020036020020014190056a41186a200141e8046a41186a29030037030020014190056a41106a200141e8046a41106a29030037030020014190056a41086a200141e8046a41086a290300370300200120012903e80437039005200141c8036a41186a2208200a41186a220e290200370300200141c8036a41106a221c200a41106a2218290200370300200141c8036a41086a221e200a41086a221f2902003703002001200a2902003703c803200141c00b6a41186a220c200e290000370300200141c00b6a41106a220e2018290000370300200141c00b6a41086a2218201f2900003703002001200a2900003703c00b200141b8056a200141c00b6a108f02200141e8036a41186a221f2008290300370300200141e8036a41106a2220201c290300370300200141e8036a41086a221c201e290300370300200120012903c8033703e80320012802d8052208450d00200d20012903b805370300200d41186a200141b8056a41186a290300370300200d41106a200141b8056a41106a290300370300200d41086a200141b8056a41086a290300370300200c201f290300370300200e20202903003703002018201c290300370300200141d8046a41086a221c201a41086a280200360200200120012903e8033703c00b2001201a2902003703d804200141a00a6a41386a221e200141c00b6a41386a290300370300200141a00a6a41306a221f200141c00b6a41306a290300370300200141a00a6a41286a2220200141c00b6a41286a290300370300200141a00a6a41206a2221200141c00b6a41206a290300370300200141a00a6a41186a2222200c290300370300200141a00a6a41106a220c200e290300370300200141a00a6a41086a220e2018290300370300200120012903c00b3703a00a20014198066a41386a201e29030037030020014198066a41306a201f29030037030020014198066a41286a202029030037030020014198066a41206a202129030037030020014198066a41186a202229030037030020014198066a41106a200c29030037030020014198066a41086a200e290300370300200120012903a00a3703980620014188066a41086a201c280200360200200120012903d804370388060b200141d8076a41086a20014198066a41086a290300370300200141d8076a41106a20014198066a41106a290300370300200141d8076a41186a20014198066a41186a290300370300200141d8076a41206a20014198066a41206a290300370300200141d8076a41286a20014198066a41286a290300370300200141d8076a41306a20014198066a41306a290300370300200141d8076a41386a20014198066a41386a290300370300200141f8056a41086a20014188066a41086a28020036020020012001290398063703d80720012001290388063703f805024020080d00200441206a2104200341016a2103201b41606a221b0d010c020b0b20014180096a41386a2223200141d8076a41386a221f29030037030020014180096a41306a2224200141d8076a41306a222029030037030020014180096a41286a2225200141d8076a41286a221a29030037030020014180096a41206a2226200141d8076a41206a222129030037030020014180096a41186a2227200141d8076a41186a222229030037030020014180096a41106a2228200141d8076a41106a222929030037030020014180096a41086a222a200141d8076a41086a222b290300370300200141a8046a41086a222c200141f8056a41086a222d280200360200200120012903d80737038009200120012903f8053703a804200141e8056a41086a222e202c280200360200200120012903a8043703e805200441206a2104200141dc056a212f20014190056a410472210a200141e8046a41047221064101210c410121300340200141c00b6a41086a2218202a290300370300200141c00b6a41106a221c2028290300370300200141c00b6a41186a221e2027290300370300200141c00b6a41206a22312026290300370300200141c00b6a41286a22322025290300370300200141c00b6a41306a22332024290300370300200141c00b6a41386a2234202329030037030020012001290380093703c00b20014198066a41086a221b202e280200360200200120012903e8053703980602402030200c470d0020014198046a200c410110b401200128029804211d0b201d203041d0006c6a220c20012903c00b370300201c2903002105201e29030021072031290300210b20322903002135203329030021362034290300213720182903002138200c2008360240200c41086a2038370300200c200129039806370244200c41cc006a201b280200360200200c41386a2037370300200c41306a2036370300200c41286a2035370300200c41206a200b370300200c41186a2007370300200c41106a20053703002001203041016a22303602a00420042019460d010340200141b8046a41186a200441186a2208290000370300200141b8046a41106a200441106a220c290000370300200141b8046a41086a200441086a220e290000370300200120042900003703b804200120033602e804200e2900002105200c29000021072004290000210b200641186a2008290000370000200641106a2007370000200641086a20053700002006200b3700004100210802402003200610ac020d0020014190056a41206a200141e8046a41206a28020036020020014190056a41186a200141e8046a41186a29030037030020014190056a41106a200141e8046a41106a29030037030020014190056a41086a200141e8046a41086a290300370300200120012903e80437039005200141c8036a41186a2208200a41186a220c290200370300200141c8036a41106a220e200a41106a2239290200370300200141c8036a41086a223a200a41086a223b2902003703002001200a2902003703c803201e200c290000370300201c20392900003703002018203b2900003703002001200a2900003703c00b200141b8056a200141c00b6a108f02200141e8036a41186a220c2008290300370300200141e8036a41106a2239200e290300370300200141e8036a41086a220e203a290300370300200120012903c8033703e80320012802d8052208450d00200d20012903b805370300200d41186a200141b8056a41186a290300370300200d41106a200141b8056a41106a290300370300200d41086a200141b8056a41086a290300370300201e200c290300370300201c20392903003703002018200e290300370300200141d8046a41086a220c202f41086a280200360200200120012903e8033703c00b2001202f2902003703d804200141a00a6a41386a220e2034290300370300200141a00a6a41306a22392033290300370300200141a00a6a41286a223a2032290300370300200141a00a6a41206a223b2031290300370300200141a00a6a41186a223c201e290300370300200141a00a6a41106a223d201c290300370300200141a00a6a41086a223e2018290300370300200120012903c00b3703a00a20014198066a41386a200e29030037030020014198066a41306a203929030037030020014198066a41286a203a29030037030020014198066a41206a203b29030037030020014198066a41186a203c29030037030020014198066a41106a203d290300370300201b203e290300370300200120012903a00a3703980620014188066a41086a200c280200360200200120012903d804370388060b202b201b290300370300202920014198066a41106a290300370300202220014198066a41186a290300370300202120014198066a41206a290300370300201a20014198066a41286a290300370300202020014198066a41306a290300370300201f20014198066a41386a290300370300202d20014188066a41086a28020036020020012001290398063703d80720012001290388063703f805024020080d00200341016a21032019200441206a2204470d010c030b0b2023201f290300370300202420202903003703002025201a290300370300202620212903003703002027202229030037030020282029290300370300202a202b290300370300202c202d280200360200200120012903d80737038009200120012903f8053703a804202e202c280200360200200120012903a8043703e805200441206a2104200341016a2103200128029c04210c0c000b0b0240201741ffffff3f71450d00201610230b20014188046a41086a20014198046a41086a2802003602002001200129039804370388040b200141c00b6a41186a22084200370300200141c00b6a41106a220a4200370300200141c00b6a41086a22034200370300200142003703c00b41db97c700ad4280808080f00084100c220429000021052003200441086a290000370300200120053703c00b2004102341bcbcc300ad4280808080c00184100c22042900002105200141d8076a41086a2206200441086a290000370300200120053703d80720041023200920012903d807370000200941086a200629030037000020014198066a41086a200329030037030020014198066a41106a200a29030037030020014198066a41186a2008290300370300200120012903c00b37039806200141a0036a20014198066a412010cd0120012802a403210420012802a00321084180cdc200ad4280808080800184100c22032900002105200141a00a6a41086a200341086a290000370300200120053703a00a2003102341d4bec200ad4280808080a00284100c220329000021052006200341086a290000370300200120053703d8072003102320012004410020081b3602b8052001200141b8056aad22054280808080c00084100d22032900003703800920031023200141cc0b6a200141bc056a360200200141003a00d00b200120014180096a41086a220d3602c40b2001200141b8056a3602c80b200120014180096a3602c00b20014198066a200141c00b6a106520012802a006220a41206a2204417f4c0d01200128029806210c0240024002402004450d00200410212203450d092004410f4d0d01200421060c020b200441017422034110200341104b1b2206102122030d010c0c0b200441017422064110200641104b1b22064100480d0a20042006460d0020032004200610252203450d0b0b200320012903a00a370000200341086a200141a00a6a41086a2903003700000240024020064170714110460d00200621080c010b200641017422084120200841204b1b22084100480d0a20062008460d0020032006200810252203450d0b0b200320012903d807370010200341186a200141d8076a41086a2903003700000240200841606a200a4f0d00200a415f4b0d0a200841017422062004200620044b1b22064100480d0a20082006460d0020032008200610252203450d0b0b200341206a200c200a10a1051a0240200128029c06450d00200c10230b2004ad4220862003ad84101220031023200141c00b6a41186a22084200370300200141c00b6a41106a220a4200370300200141c00b6a41086a22034200370300200142003703c00b41db97c700ad4280808080f00084100c220429000021072003200441086a290000370300200120073703c00b2004102341bcbcc300ad4280808080c00184100c22042900002107200141d8076a41086a2206200441086a290000370300200120073703d80720041023200920012903d807370000200941086a200629030037000020014198066a41086a200329030037030020014198066a41106a200a29030037030020014198066a41186a2008290300370300200120012903c00b3703980620014198036a20014198066a412010cd01200128029c03210420012802980321084180cdc200ad4280808080800184100c22032900002107200141a00a6a41086a200341086a290000370300200120073703a00a2003102341b4a5c200ad4280808080e00184100c220329000021072006200341086a290000370300200120073703d8072003102320012004410020081b3602b805200120054280808080c00084100d22032900003703800920031023200141cc0b6a200141bc056a360200200141003a00d00b2001200d3602c40b2001200141b8056a3602c80b200120014180096a3602c00b20014198066a200141c00b6a106520012802a006220a41206a2204417f4c0d01200128029806210c0240024002402004450d00200410212203450d092004410f4d0d01200421060c020b200441017422034110200341104b1b220610212203450d0c0c010b200441017422064110200641104b1b22064100480d0a20042006460d0020032004200610252203450d0b0b200320012903a00a370000200341086a200141a00a6a41086a2903003700000240024020064170714110460d00200621080c010b200641017422084120200841204b1b22084100480d0a20062008460d0020032006200810252203450d0b0b200320012903d807370010200341186a200141d8076a41086a2903003700000240200841606a200a4f0d00200a415f4b0d0a200841017422062004200620044b1b22064100480d0a20082006460d0020032008200610252203450d0b0b200341206a200c200a10a1051a0240200128029c06450d00200c10230b2015420020141b21052004ad4220862003ad841012200310230240024002400240024002400240200128029004450d00200141c00b6a20014188046a10ec03200141a3066a200141c00b6a41086a280200360000200120012903c00b37009b06200141073a00c00b200141cc0b6a20014198066a41076a290000370000200141023a00c40b20012001290098063700c50b200141c00b6a10e001200141a0056a20014188046a41086a28020036020020012005422088a722393602940520012012410020131b220a36029005200120012903880437039805200141e8056a20014190056a41086a10ec032001410036029006200142013703880620012802e805212b20012802ec05212d20012802f0052106410410212203450d0d2003200a36000020014284808080c0003702dc07200120033602d807200141c00b6a41b599c50010b60320014198066a20012802c00b220420012802c80b10b703200129029c06420020012802980622031b21072003410120031b2108024020012802c40b450d00200410230b200120074220883e029c062001200836029806200141c00b6a20014198066a10b803200141c00b6a41086a280200210420012802c40b210c20012802c00b2103200141c00b6a41b599c500200141d8076a10b90320014198066a20012802c00b220e20012802c80b1089022004410020031b210d200c410020031b210c200129029c06420020012802980622041b210b2003410420031b21032004410120041b2121024020012802c40b450d00200e10230b200141a0096a200d3602002001419c096a200c36020020014190096a200b37030020014180096a41086a200141d8076a41086a280200360200200120012903d8073703800920012003360298092001202136028c0902402007a7450d00200810230b2006450d01200b422088a7211b20014198096a211920014180096a410c6a2129202b200641d0006c6a2116200141c00b6a41d0006a211a200141c00b6a410c6a211d200141d8076a41c4006a211841002122202b210c0340200141c00b6a41386a2204200c220341386a290300370300200141c00b6a41306a2206200341306a290300370300200141c00b6a41286a2208200341286a290300370300200141c00b6a41206a220d200341206a290300370300200141c00b6a41186a220e200341186a290300370300200141c00b6a41106a221c200341106a290300370300200141c00b6a41086a221e200341086a290300370300200141d8046a41086a221f200341cc006a280200360200200120032903003703c00b2001200341c4006a2902003703d804200341d0006a210c200341c0006a2802002203450d03200141a00a6a41386a22202004290300370300200141a00a6a41306a22042006290300370300200141a00a6a41286a22062008290300370300200141a00a6a41206a2208200d290300370300200141a00a6a41186a220d200e290300370300200141a00a6a41106a220e201c290300370300200141a00a6a41086a221c201e290300370300200141a8046a41086a221e201f280200360200200120012903c00b3703a00a200120012903d8043703a804200141d8076a41386a2020290300370300200141d8076a41306a2004290300370300200141d8076a41286a2006290300370300200141d8076a41206a2008290300370300200141d8076a41186a200d290300370300200141d8076a41106a200e290300370300200141d8076a41086a201c290300370300200120012903a00a3703d8072001200336029808201820012903a804370200201841086a201e280200360200410410212203450d0e2003200a360000201d41002900b59945370000201d41086a41002900bd994537000020014284808080c0003702c40b200120033602c00b2001200141d8076a3602dc0b200141b8056a200141c00b6a10ba0320031023200141c00b6a200141b8056a10bb0320014190036a20012802c00b220420012802c80b419ca8c70041004100108c012001280290032103024020012802c40b450d00200410230b024002400240024020034101460d0020014198066a200141d8076a41d00010a1051a200141e8046a20014188066a108e02200141c00b6a20014198066a41d00010a1051a201a41086a200141e8046a41086a280200360200201a20012903e80437020020014198066a200141b8056a10bb032001280298062103200120012802a0063602ec04200120033602e804200141c00b6a200141e8046a10bc030240200128029c06450d00200310230b024020012802840c2203450d00200341306c450d0020012802800c10230b024020012802940c41ffffff3f71450d0020012802900c10230b200141b8046a41186a221c200141b8056a41186a290300370300200141b8046a41106a221e200141b8056a41106a290300370300200141b8046a41086a221f200141b8056a41086a290300370300200120012903b8053703b804200128029809210d41002103024020012802a009220e41014b0d000240200e0e020003000b200141c8036a41186a201c290300370300200141c8036a41106a201e290300370300200141c8036a41086a201f290300370300200120012903b8043703c803410021030c030b200e2104034020032004410176220620036a2208200d200841246c6a280200200a4b1b2103200420066b220441014b0d000c020b0b200128029c082203450d02200341306c450d0220012802980810230c020b0240200d200341246c6a2802002204200a460d0020032004200a496a21030b200141c8036a41186a201c290300370300200141c8036a41106a201e290300370300200141c8036a41086a201f290300370300200120012903b8043703c803200e20034f0d002003200e1038000b0240200e200128029c09470d002019200e410110a201200128029409211b200128029809210d0b200d200341246c6a220441246a2004200e20036b41246c10a2051a2004200a360200200420012903c8033702042004410c6a200141c8036a41086a290300370200200441146a200141c8036a41106a2903003702002004411c6a200141c8036a41186a2903003702002001200e41016a3602a009200141e8036a41186a2204201c290300370300200141e8036a41106a2206201e290300370300200141e8036a41086a2208201f290300370300200120012903b8043703e8030240201b200128029009470d002029201b4101109a01200128029409211b0b200128028c092221201b4105746a220320012903e803370000200341186a2004290300370000200341106a2006290300370000200341086a2008290300370000410121222001201b41016a221b360294090b200c2016470d000b2016210c0c020b200141013a00c40b200141073a00c00b200141c00b6a10e001200128028c042203450d05200341d0006c450d0520012802880410230c050b202d450d01202d41d0006c450d01202b10230c010b02402016200c460d000340200c220341d0006a210c0240200341c4006a2802002204450d00200441306c450d00200341c0006a28020010230b2016200c470d000b0b0240202d450d00202d41d0006c450d00202b10230b2022410171450d00200141f8056a20212021201b4105746a10bd03200141c00b6a41206a20014180096a41206a2802002203360200200141c00b6a41186a20014180096a41186a2903002207370300200141c00b6a41106a20014180096a41106a290300370300200141c00b6a41086a20014180096a41086a29030037030020012001290380093703c00b200141d8076a2007a72206200310be0320014198066a41b599c50010b6032001280298062103200120012802a0063602a40a200120033602a00a20012802d807220420012802e007200141a00a6a10c8020240200128029c06450d00200310230b024020012802dc07450d00200410230b20014198066a41b599c500200141c00b6a10b9032001280298062103200120012802a0063602dc07200120033602d80720012802cc0b2204200141d40b6a280200200141d8076a10bf030240200128029c06450d00200310230b024020012802c40b450d0020012802c00b10230b0240200141d00b6a28020041ffffff3f71450d00200410230b0240200141dc0b6a2802002203450d00200341246c450d00200610230b20012802f805220c0d010c020b200141003602f8050240200128028409450d0020012802800910230b024020012802900941ffffff3f71450d00202110230b200128029c092203450d01200341246c450d0120012802980910230c010b20012802fc05210e41002106024002402039410a6e417f7320014180066a28020022086a220420084b0d0020394101203941014b1b2203418094ebdc036e220620032006418094ebdc036c476a22064101200641014b1b220620034b0d0120012003200441036c220420032004491b20066ead428094ebdc037e200320066ead8042ffffffff0f834280bbb0217e428094ebdc0380a722033602c00b2001418094ebdc033602c40b200141c00b6a2003418094ebdc034b4102746a28020021060b200141003602c80b200142043703c00b200141c00b6a41002008107920012802c00b210d20012802c80b211b0240024020080d0020012802c40b2104200c4100200d201b200a10c00321060c010b200d201b4102746a210320082104034020032006360200200341046a21032004417f6a22040d000b20012802c40b2104200c2008200d201b20086a200a10c00321060b410410212203450d092003200a360000200141c80b6a4284808080c000370300200141d00b6a41002900b59945370300200141d80b6a41002900bd9945370300200141e00b6a20063a0000200120033602c40b200141043a00c00b200141c00b6a10e0010240200441ffffffff0371450d00200d10230b02402008450d00200841e0006c2104200c41d4006a210303400240200341706a2802002206450d00200641306c450d002003416c6a28020010230b0240200328020041ffffff3f71450d002003417c6a28020010230b200341e0006a2103200441a07f6a22040d000b0b0240200e450d00200e41e0006c450d00200c10230b20012802980521080240200141a0056a2802002203450d00200341d0006c2104200841c4006a21030340024020032802002206450d00200641306c450d002003417c6a28020010230b200341d0006a2103200441b07f6a22040d000b0b2001419c056a2802002203450d02200341d0006c450d02200810230c020b41f0a6c700411941f4aac700102d000b20012802980521080240200141a0056a2802002203450d00200341d0006c2104200841c4006a21030340024020032802002206450d00200641306c450d002003417c6a28020010230b200341d0006a2103200441b07f6a22040d000b0b02402001419c056a2802002203450d00200341d0006c450d00200810230b4193bbc000ad4280808080c00184100a4184bbc000ad4280808080f00184100a0b0240200542ffffff3f83500d002014410120141b10230b200f410020101b210c200141b8046a41186a4200370300200141b8046a41106a22064200370300200141b8046a41086a22034200370300200142003703b804418fcdc200ad4280808080f00084100c220429000021052003200441086a290000370300200120053703b8042004102341b8dbc100ad4280808080900184100c22042900002105200141d8076a41086a220e200441086a290000370300200120053703d80720041023200620012903d8072205370300200141c00b6a41086a22082003290300370300200141c00b6a41106a220a2005370300200141c00b6a41186a220d200e290300370300200120012903b8043703c00b20014198066a200141c00b6a10ba01024020012903980622054202510d0020012903a0062107200141c00b6a20014198066a41106a280200220e41016a10c20120014188036a20012802c00b220420012802c80b10cd01200128028c0321062001280288032103024020012802c40b450d00200410230b20034101470d002006200c41016a470d0020054201520d00200141e8036a41186a22044200370300200141e8036a41106a22064200370300200141e8036a41086a22034200370300200142003703e80341b494c700ad4280808080900184100c221b29000021052003201b41086a290000370300200120053703e803201b102341bd94c700ad42808080803084100c22162900002105200141d8076a41086a221b201641086a290000370300200120053703d80720161023200220012903d807370000200241086a221d201b290300370000200141c8036a41086a22182003290300370300200141c8036a41106a221c2006290300370300200141c8036a41186a221e2004290300370300200120012903e8033703c803200141f8026a200141c8036a10fa02200141d0026a200129038003420020012802f8021b220542e80780220b420042e807420010a605200141c00b6a200e10ca01200141e0026a20012802c00b221f20012802c80b10d70120012903d00222152005200b4298787e7c42ff07837c2205427f200141d0026a41086a2903002005201554ad7c501b20077d2135200141e0026a41106a290300420020012802e00222161b210520012903e802420020161b2115024020012802c40b450d00201f10230b200442003703002006420037030020034200370300200142003703e80341bdadc500ad4280808080800184100c221629000021072003201641086a290000370300200120073703e8032016102341c5adc500ad4280808080d00184100c22162900002107201b201641086a290000370300200120073703d80720161023200220012903d807370000201d201b29030037000020182003290300370300201c2006290300370300201e2004290300370300200120012903e8033703c803200141b8026a200141c8036a412010d701200141a8026a20012903c002420020012802b80222031b2207200141b8026a41106a290300420020031b220b428094ebdc03420010a70520014198026a20012903a8022237200141a8026a41086a29030022384280ec94a37c427f10a605200b200520152007562005200b562005200b511b22031b21052007201520031b211520012903980220077c21362035428086ebc7f5002035428086ebc7f500541b42058842ffffffff0f83428094ebdc037e4298ac9fd60380213f4100210441d87d210302400240034020014188026a2037203820034180cdc2006a3502002207420010a60520042015200129038802220b200720367e2207428094ebdc03802235a7417f2007428080808080c0b2cd3b541b200720354280ec94a37c7e7c4280cab5ee01566aad7c22075a200520014188026a41086a2903002007200b54ad7c220b5a2005200b5122061b6a210420152007542005200b5420061b0d01200341086a22030d000b200141f8016a2037203842e8aafa0b420010a60520014180026a29030020012903f8012207203642e8aafa0b7e2205428094ebdc0380220ba7417f2005428080808080c0b2cd3b541b2005200b4280ec94a37c7e7c4280cab5ee01566aad7c2205200754ad7c21070c010b02402004417f6a220320044d0d00200141f8006a2037203842c0f0f50b420010a60520014180016a2903002001290378220720364228802205a7417f203642c0f0f50b7e220b428080808080c0b2cd3b541b200b20054280ec94a37c7e7c4280cab5ee01566aad7c2205200754ad7c21070c010b02400240200341244b0d00200141e8016a203720382003410374220641d8cac2006a280200221bad2207420010a605200141c8016a201520012903e801220b200720367e2207428094ebdc03802235a7417f2007428080808080c0b2cd3b541b200720354280ec94a37c7e7c4280cab5ee01566aad7c220720152007562005200141e8016a41086a2903002007200b54ad7c220b562005200b511b22031b22352007201520031b22077d22152005200b20031b200b200520031b7d2035200754ad7d41002004410374221641d8cac2006a2802002204201b6b221b201b20044b1b22044101200441014b1bad2205420010a705200141b8016a20012903c8012207200141c8016a41086a29030022352005420010a605200141d8016a20372038200641dccac2006a2802002204ad2240420010a60520014188016a20354200201641dccac2006a28020022062004200620044b221b1b20042006201b1b6bad220b420010a605200141a8016a20074200200b420010a60520014198016a420042002007420010a605427f427f200141a8016a41086a29030022072001290388012001290398017c7c223520012903900120012903a00184420052203520075472221b1b2235427f20012903a801201b1b2207201520012903b8017d200b7e2005807c2205200754221bad7c220b201b200b203554200520075a1b221b1b2115427f2005201b1b210b200141d8016a41086a29030020012903d8012235204020367e2205428094ebdc03802207a7417f2005428080808080c0b2cd3b541b200520074280ec94a37c7e7c4280cab5ee01566aad7c2207203554ad7c2105200620044d2003730d014200200520157d2007200b54ad7d22152007200b7d220b200756201520055620152005511b22031b21074200200b20031b21050c020b2003412541f8f6c3001030000b427f200520157c2007200b7c220b2007542203ad7c22072003200720055420072005511b22031b2107427f200b20031b21050b200141e8006a20052007428094ebdc03420010a705200141d8006a20012903682207200141e8006a41086a290300220b4280ec94a37c427f10a605200141c8006a2007200b203f420010a60520014198066a200e10cb01200128029806210320013502a006210720012001290348220b203f200520012903587c7e2205428094ebdc03802215a7417f2005428080808080c0b2cd3b541b200520154280ec94a37c7e7c4280cab5ee01566aad7c22053703c00b2001200141c8006a41086a2903002005200b54ad7c3703c80b20074220862003ad84200141c00b6aad4280808080800284100e200128029c06450d00200310230b200d4200370300200a420037030020084200370300200142003703c00b41db97c700ad4280808080f00084100c2204290000210520014198066a41086a2203200441086a2900003703002001200537039806200410232008200329030037030020012001290398063703c00b41f8afc300ad4280808080a00184100c220429000021052003200441086a2900003703002001200537039806200410232009200129039806370000200941086a2003290300370000200141a00a6a41086a2008290300370300200141a00a6a41106a200a290300370300200141a00a6a41186a200d290300370300200120012903c00b3703a00a200141203602ec042001200141a00a6a3602e804200141b8056a200141a00a6aad428080808080048422151010108b010240024020012802b805220a0d00410021080c010b20012802bc05210d2001200141c0056a280200360294052001200a36029005200141c0006a20014190056a1088010240024020012802400d002001280244220e200128029405220641c0016e22032003200e4b1bad42c0017e2205422088a70d042005a72203417f4c0d040240024020030d00410121080c010b200310212208450d0a0b200141003602880920012008360280092001200341c0016e360284090240200e450d00200141c00b6a41206a211d200141d8076a4101722118410021164100211b0240034041002103200141003a00f807201b41016a211b02400340200141003a00b80420062003460d01200141d8076a20036a20012802900522042d00003a00002001200441016a360290052001200341016a22043a00f8072004210320044120470d000b200141e8036a41086a2203200141d8076a41086a290300370300200141e8036a41106a221c200141d8076a41106a290300370300200141e8036a41186a221e200141d8076a41186a290300370300200120012903d8073703e8032001200620046b36029405200141d8076a20014190056a10e50220012d00d8074101460d02200141c00b6a41186a201e290300370300200141c00b6a41106a201c290300370300200141c00b6a41086a2003290300370300200120012903e8033703c00b201d201841a00110a1051a20014198066a200141c00b6a41c00110a1051a02402016200128028409470d0020014180096a2016410110b101200128028009210820012802880921160b2008201641c0016c6a20014198066a41c00110a1051a2001201641016a221636028809201b200e460d0320012802940521060c010b0b2001410036029405200341ff0171450d00200141003a00f8070b02402001280284092203450d00200341c0016c450d00200810230b0c010b200129028409210520080d010b41002108200141003602a00620014201370398062001410a3602dc072001200141e8046a3602d807200120014198066a36028009200141d40b6a4101360200200142013702c40b20014180c5c6003602c00b2001200141d8076a3602d00b20014180096a4184a5c200200141c00b6a10311a20013502a00642208620013502980684100a200128029c06450d0020012802980610230b200d450d00200a10230b2011201141ff0171410247712121200141003602c80b200142013703c00b200141c00b6a41002005420020081b2236422088a7222241c0016c220e41c0016e109a012008410120081b211c20012802c80b210620012802c00b212002402022450d00202020064105746a2103200e2108201c2104034020032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a290000370000200641016a2106200341206a2103200441c0016a2104200841c07e6a22080d000b0b20012802c40b212d200141c00b6a41186a220a4200370300200141c00b6a41106a22084200370300200141c00b6a41086a22044200370300200142003703c00b41db97c700ad4280808080f000842205100c220d290000210720014198066a41086a2203200d41086a2900003703002001200737039806200d10232004200329030037030020012001290398063703c00b41bbacc300ad4280808080a00184100c220d29000021072003200d41086a2900003703002001200737039806200d10232009200129039806370000200941086a220d2003290300370000200141a00a6a41086a221b2004290300370300200141a00a6a41106a22162008290300370300200141a00a6a41186a221d200a290300370300200120012903c00b3703a00a200141203602c40b2001200141a00a6a3602c00b20202006200141c00b6a109c0202402021450d00200a42003703002008420037030020044200370300200142003703c00b2005100c220629000021072003200641086a2900003703002001200737039806200610232004200329030037030020012001290398063703c00b41c0bdc300ad4280808080a00284100c220629000021072003200641086a2900003703002001200737039806200610232009200129039806370000200d2003290300370000201b200429030037030020162008290300370300201d200a290300370300200120012903c00b3703a00a200141c00b6a200141a00a6a10ed0320012802c00b2206450d002015101120012902c40b42ffffffff0383500d00200610230b200a42003703002008420037030020044200370300200142003703c00b2005100c220629000021052003200641086a2900003703002001200537039806200610232004200329030037030020012001290398063703c00b41bcbcc300ad4280808080c00184100c220629000021052003200641086a2900003703002001200537039806200610232009200129039806370000200d2003290300370000201b200429030037030020162008290300370300201d200a290300370300200120012903c00b3703a00a2001200c41016a221a3602c00b2015200141c00b6aad22374280808080c00084100e200141e8036a41186a22064200370300200141e8036a41106a220a4200370300200141e8036a41086a22034200370300200142003703e803418fcdc200ad4280808080f00084100c220429000021052003200441086a290000370300200120053703e8032004102341b8dbc100ad4280808080900184100c22042900002105200141d8076a41086a220d200441086a290000370300200120053703d80720041023200220012903d807370000200241086a200d290300370000200141c8036a41086a2003290300370300200141c8036a41106a200a290300370300200141c8036a41186a2006290300370300200120012903e8033703c803200141c00b6a200141c8036a10ba01200141c00b6a4100200828020041016a20012903c00b4202511b10c201200141386a20012802c00b220620012802c80b10cd01200128023c210420012802382103024020012802c40b450d00200610230b024020034101470d0002402004201a460d002004201a4f0d0141d9c1c000ad4280808080800684100a0b201a10e3010b200141e8036a41186a22084200370300200141e8036a41106a220a4200370300200141e8036a41086a22044200370300200142003703e803418fcdc200ad4280808080f00084100c22062900002105200141d8076a41086a2203200641086a290000370300200120053703d8072006102320042003290300370300200120012903d8073703e803418cdbc100ad4280808080a00184100c220629000021052003200641086a290000370300200120053703d80720061023200220012903d807370000200241086a2003290300370000200141c8036a41086a2004290300370300200141c8036a41106a200a290300370300200141c8036a41186a2008290300370300200120012903e8033703c803200141306a200141c8036a412010cd01200c41026a21030240024020012802304101460d00200141b8046a200310cc010c010b200141c00b6a200128023410c201200141286a20012802c00b220620012802c80b10cd01200128022c210a20012802282104024020012802c40b450d00200610230b024020040d00419fcfc000ad4280808080e00684100a4100210a0b200141e8036a41186a220c4200370300200141e8036a41106a220d4200370300200141e8036a41086a22064200370300200142003703e803418fcdc200ad4280808080f00084100c22082900002105200141d8076a41086a2204200841086a290000370300200120053703d8072008102320062004290300370300200120012903d8073703e80341fcdec100ad4280808080800184100c220829000021052004200841086a290000370300200120053703d80720081023200220012903d807370000200241086a2004290300370000200141c8036a41086a2006290300370300200141c8036a41106a200d290300370300200141c8036a41186a200c290300370300200120012903e8033703c80341002003200a6b2204200420034b1b21060240024002404100200141c8036a10f0012204200441ff01714104461b41ff0171220441034b0d00024020040e0400020103000b200641064f0d020b0240200641016a4106490d00200141e8036a41186a22084200370300200141e8036a41106a220a4200370300200141e8036a41086a22044200370300200142003703e803418fcdc200ad4280808080f00084100c22062900002105200141d8076a41086a2203200641086a290000370300200120053703d8072006102320042003290300370300200120012903d8073703e8034194e5c100ad4280808080d00284100c220629000021052003200641086a290000370300200120053703d80720061023200220012903d807370000200241086a2003290300370000200141c8036a41086a2004290300370300200141c8036a41106a200a290300370300200141c8036a41186a2008290300370300200120012903e8033703c803200141013a00b804200141c8036aad4280808080800484200141b8046aad42808080801084100e0b200141003602b8040c020b200141e8036a41186a220a4200370300200141e8036a41106a220c4200370300200141e8036a41086a22064200370300200142003703e803418fcdc200ad4280808080f00084100c22082900002105200141d8076a41086a2204200841086a290000370300200120053703d8072008102320062004290300370300200120012903d8073703e80341fcdec100ad4280808080800184100c220829000021052004200841086a290000370300200120053703d80720081023200220012903d807370000200241086a2004290300370000200141c8036a41086a2006290300370300200141c8036a41106a200c290300370300200141c8036a41186a200a290300370300200120012903e8033703c803200141c8036aad428080808080048410110b200141e8036a41186a220a4200370300200141e8036a41106a220c4200370300200141e8036a41086a22064200370300200142003703e803418fcdc200ad4280808080f00084100c22082900002105200141d8076a41086a2204200841086a290000370300200120053703d8072008102320062004290300370300200120012903d8073703e8034194e5c100ad4280808080d00284100c220829000021052004200841086a290000370300200120053703d80720081023200220012903d807370000200241086a2004290300370000200141c8036a41086a2006290300370300200141c8036a41106a200c290300370300200141c8036a41186a200a290300370300200120012903e8033703c803200141003a00b804200141c8036aad4280808080800484200141b8046aad42808080801084100e200141b8046a200310cc010b201c200e6a21030240024020012802b80422190d00200141c00b6a41186a4200370300200141c00b6a41106a22084200370300200141c00b6a41086a22044200370300200142003703c00b41db97c700ad4280808080f00084100c220629000021052004200641086a290000370300200120053703c00b2006102341bbacc300ad4280808080a00184100c22062900002105200141d8076a41086a220a200641086a290000370300200120053703d80720061023200820012903d807220537030020014198066a41086a200429030037030020014198066a41106a200537030020014198066a41186a200a290300370300200120012903c00b37039806200141c00b6a20014198066a412010890220012902c40b420020012802c00b22041b21352004410120041b212b410021020c010b4101210220012902bc0421352019212b0b200120023a008806200120033602cc032001201c3602c8032001200141c8036a3602ec03200120014188066a3602e803200141003602f004200142013703e804200141e8046a41002035422088a72203410574220641057510b10120012802f004211820012802e804211e02402003450d00201e201841c0016c6a21082018200641606a4105766a213920014198066a4101722116200141c00b6a41206a211d20014180096a4180016a211420014180096a41e0006a212920014180096a41c0006a211f20014180096a41206a2118202b21030340200341086a2900002105200341106a29000021072003290000210b200141b8056a41186a220a200341186a290000370300200141b8056a41106a220c2007370300200141b8056a41086a220d20053703002001200b3703b80520014190056a200141b8056a10860320014198066a200128029005221b20012802980510870320012d009806210e200141d8076a201641a00110a1051a410021040240200e4101470d00200141a00a6a200141d8076a41a00110a1051a410121040b0240200128029405450d00201b10230b0240024020040d0020014180096a410041a00110a0051a0c010b20014180096a200141a00a6a41a00110a1051a0b024020012802e8032d00000d0020012802ec03220e2802002204200e280204460d00200e200441c0016a3602000240024020014180096a200441206a220e460d00200e20014180096a412010a3050d010b02402018200441c0006a220e460d00200e2018412010a3050d010b0240201f200441e0006a220e460d00200e201f412010a3050d010b0240202920044180016a220e460d00200e2029412010a3050d010b2014200441a0016a2204460d0120042014412010a305450d010b20012802e80341013a00000b200341206a2103200141c00b6a41186a200a290300370300200141c00b6a41106a200c290300370300200141c00b6a41086a200d290300370300200120012903b8053703c00b201d20014180096a41a00110a1051a2008200141c00b6a41c00110a10541c0016a2108200641606a22060d000b203941016a21180b200120183602f0040240203542ffffff3f83500d00202b10230b2018ad42c0017e2205422088a70d012005a72203417f4c0d0120012802ec04211f20012d008806212b0240024020030d00410121040c010b200310212204450d070b200141003602a00620012004360298062001200341c0016e36029c0620014198066a4100201810b10120012802a006210d0240024020180d0020012802980621160c010b201e201841c0016c6a211b2001280298062216200d41c0016c6a210e200141c00b6a41a0016a2104200141c00b6a4180016a2106200141c00b6a41e0006a2108200141c00b6a41c0006a210a200141c00b6a41206a210c201e21030340200141c00b6a41186a200341186a290000370300200141c00b6a41106a200341106a290000370300200141c00b6a41086a200341086a290000370300200120032900003703c00b200c41186a200341386a290000370000200c41106a200341306a290000370000200c41086a200341286a290000370000200c200341206a290000370000200a200341c0006a290000370000200a41086a200341c8006a290000370000200a41106a200341d0006a290000370000200a41186a200341d8006a2900003700002008200341e0006a290000370000200841086a200341e8006a290000370000200841106a200341f0006a290000370000200841186a200341f8006a290000370000200620034180016a290000370000200641086a20034188016a290000370000200641106a20034190016a290000370000200641186a20034198016a2900003700002004200341a0016a290000370000200441086a200341a8016a290000370000200441186a200341b8016a290000370000200441106a200341b0016a290000370000200d41016a210d200e200141c00b6a41c00110a10541c0016a210e200341c0016a2203201b470d000b0b200128029c062129200141c00b6a41186a22084200370300200141c00b6a41106a220a4200370300200141c00b6a41086a22044200370300200142003703c00b41db97c700ad4280808080f00084100c2206290000210520014198066a41086a2203200641086a2900003703002001200537039806200610232004200329030037030020012001290398063703c00b41f8afc300ad4280808080a00184100c220629000021052003200641086a2900003703002001200537039806200610232009200129039806370000200941086a2003290300370000200141a00a6a41086a2004290300370300200141a00a6a41106a200a290300370300200141a00a6a41186a2008290300370300200120012903c00b3703a00a200d41c0016c4104722203417f4c0d01200310212204450d06200141003602c80b200120033602c40b200120043602c00b200d200141c00b6a106102400240200d0d0020012802c80b210320012802c40b210d20012802c00b21040c010b2016200d41c0016c6a211d410020012802c80b220c6b210820012802c40b210d410021060340200c20066a210a02400240200d20086a4120490d0020012802c00b2104200d210e0c010b200a41206a2203200a490d0c200d41017422042003200420034b1b220e4100480d0c02400240200d0d000240200e0d00410121040c020b200e10212204450d0f0c010b20012802c00b2104200d200e460d002004200d200e10252204450d0e0b2001200e3602c40b200120043602c00b0b2004200c6a20066a220d201620066a2203290000370000200d41186a200341186a290000370000200d41106a200341106a290000370000200d41086a200341086a2900003700002001200a41206a220d3602c80b02400240200e20086a41606a411f4d0d00200e210d0c010b200d41206a221b200d490d0c200e410174220d201b200d201b4b1b220d4100480d0c02400240200e0d000240200d0d00410121040c020b200d10212204450d0f0c010b200e200d460d002004200e200d10252204450d0e0b2001200d3602c40b200120043602c00b0b2004200c6a20066a220e41206a200341206a290000370000200e41386a200341386a290000370000200e41306a200341306a290000370000200e41286a200341286a2900003700002001200a41c0006a220e3602c80b02400240200d20086a41406a411f4d0d00200d210e0c010b200e41206a221b200e490d0c200d410174220e201b200e201b4b1b220e4100480d0c02400240200d0d000240200e0d00410121040c020b200e10212204450d0f0c010b200d200e460d002004200d200e10252204450d0e0b2001200e3602c40b200120043602c00b0b2004200c6a20066a220d41c0006a200341c0006a290000370000200d41d8006a200341d8006a290000370000200d41d0006a200341d0006a290000370000200d41c8006a200341c8006a2900003700002001200a41e0006a220d3602c80b02400240200e20086a41a07f6a411f4d0d00200e210d0c010b200d41206a221b200d490d0c200e410174220d201b200d201b4b1b220d4100480d0c02400240200e0d000240200d0d00410121040c020b200d10212204450d0f0c010b200e200d460d002004200e200d10252204450d0e0b2001200d3602c40b200120043602c00b0b2004200c6a20066a220e41e0006a200341e0006a290000370000200e41f8006a200341f8006a290000370000200e41f0006a200341f0006a290000370000200e41e8006a200341e8006a2900003700002001200a4180016a220e3602c80b02400240200d20086a41807f6a411f4d0d00200d210e0c010b200e41206a221b200e490d0c200d410174220e201b200e201b4b1b220e4100480d0c02400240200d0d000240200e0d00410121040c020b200e10212204450d0f0c010b200d200e460d002004200d200e10252204450d0e0b2001200e3602c40b200120043602c00b0b2004200c6a20066a220d4180016a20034180016a290000370000200d4198016a20034198016a290000370000200d4190016a20034190016a290000370000200d4188016a20034188016a2900003700002001200a41a0016a220d3602c80b02400240200e20086a41e07e6a411f4d0d00200e210d0c010b200d41206a221b200d490d0c200e410174220d201b200d201b4b1b220d4100480d0c02400240200e0d000240200d0d00410121040c020b200d10212204450d0f0c010b200e200d460d002004200e200d10252204450d0e0b2001200d3602c40b200120043602c00b0b2004200c6a20066a220e41a0016a200341a0016a290000370000200e41b8016a200341b8016a290000370000200e41b0016a200341b0016a290000370000200e41a8016a200341a8016a2900003700002001200a41c0016a3602c80b200841c07e6a2108200641c0016a2106200341c0016a201d470d000b200c20066a21030b20152003ad4220862004ad84100e0240200d450d00200410230b02402029450d00202941c0016c450d00201610230b200141c00b6a41186a22084200370300200141c00b6a41106a220a4200370300200141c00b6a41086a22044200370300200142003703c00b41db97c700ad4280808080f00084100c2206290000210520014198066a41086a2203200641086a2900003703002001200537039806200610232004200329030037030020012001290398063703c00b41d0bcc300ad4280808080d00184100c220629000021052003200641086a2900003703002001200537039806200610232009200129039806370000200941086a2003290300370000200141a00a6a41086a2004290300370300200141a00a6a41106a200a290300370300200141a00a6a41186a2008290300370300200120012903c00b3703a00a2001202b3a00c00b2015203742808080801084100e2001201a3602c40b200141053a00c00b200141c00b6a10e0012021201c2022201e201810ee030240201f450d00201f41c0016c450d00201e10230b02402002201945720d0020012802bc0441ffffff3f71450d00201910230b0240202d41ffffff3f71450d00202010230b2036a72203450d00200341c0016c450d00201c10230b200141c00b6a41186a221a4200370300200141c00b6a41106a221b4200370300200141c00b6a41086a220e4200370300200142003703c00b418fcdc200ad4280808080f00084220b100c22032900002105200e200341086a290000370300200120053703c00b2003102341ccc5c000ad42808080809002842215100c22032900002105200141d8076a41086a2209200341086a290000370300200120053703d80720031023201b20012903d807220537030020014198066a41086a2221200e29030037030020014198066a41106a2222200537030020014198066a41186a22192009290300370300200120012903c00b37039806200141206a20014198066a1088022001280220417d710d04201a4200370300201b4200370300200e4200370300200142003703c00b4189e3c400ad42808080808001842236100c22032900002105200e200341086a290000370300200120053703c00b200310234193e4c400ad42808080808002842237100c220329000021052009200341086a290000370300200120053703d80720031023201b20012903d807370000201b41086a20092903003700002021200e2903003703002022201b2903003703002019201a290300370300200120012903c00b37039806200141c00b6a20014198066a10ef03200120012802c00b2203410420031b22293602a00a20012902c40b420020031b2235422088a7220d450d0341002104202921034100210603400240024002402003280200200341086a22082802002003410c6a280200200341146a280200200341186a220a280200108702450d0020040d01410021040c020b200441016a21040c010b200620046b220c200d4f0d03200141c00b6a41186a22162003200441646c6a220c41186a221d280200360200200141c00b6a41106a2218200c41106a221c290200370300200141c00b6a41086a221e200c41086a221f2902003703002001200c2902003703c00b20082902002105200341106a22202902002107200a2802002102200c2003290200370200201d2002360200201c2007370200201f2005370200200a2016280200360200202020182903003702002008201e290300370200200320012903c00b3702000b2003411c6a2103200d200641016a2206460d030c000b0b1032000b200c200d4184d9c4001030000b2004450d00200d2004490d002029200d20046b220d411c6c6a200410f003203542ffffffff0f8321350b20012802a00a2103200141c00b6a41186a4200370300200141c00b6a41106a22084200370300200141c00b6a41086a22044200370300200142003703c00b2036100c220629000021052004200641086a290000370300200120053703c00b200610232037100c22062900002105200141d8076a41086a220a200641086a290000370300200120053703d80720061023200820012903d807220537030020014198066a41086a200429030037030020014198066a41106a200537030020014198066a41186a200a290300370300200120012903c00b37039806024020030d0020014198066aad428080808080048410110c010b2035a72104200141c00b6a2003200d10f10320014198066aad428080808080048420013502c80b42208620012802c00b2206ad84100e024020012802c40b450d00200610230b2003200d10f0032004450d002004411c6c450d00200310230b201a4200370300201b4200370300200e4200370300200142003703c00b200b100c22032900002105200141a00a6a41086a2204200341086a290000370300200120053703a00a20031023200e2004290300370300200120012903a00a3703c00b2015100c220329000021052009200341086a290000370300200120053703d80720031023201b20012903d80722053703002021200e2903003703002022200537030020192009290300370300200120012903c00b37039806200141186a20014198066a10880202402001280218417d710d00200141c00b6a41186a22064200370300200141c00b6a41106a22084200370300200141c00b6a41086a22034200370300200142003703c00b418fcdc200ad4280808080f00084100c22042900002105200141a00a6a41086a220a200441086a290000370300200120053703a00a200410232003200a290300370300200120012903a00a3703c00b4194e5c100ad4280808080d00284100c22042900002105200141d8076a41086a220a200441086a290000370300200120053703d80720041023201b20012903d807370000201b41086a200a29030037000020014198066a41086a200329030037030020014198066a41106a200829030037030020014198066a41186a2006290300370300200120012903c00b3703980620014198066a108103220341ff01714102460d002003410171450d0010eb03210520014198066a41186a420037030020014198066a41106a2206420037030020014198066a41086a22034200370300200142003703980641a7b3c500ad4280808080c00084100c220429000021072003200441086a29000037030020012007370398062004102341a4bbc500ad4280808080b00184100c22042900002107200141a00a6a41086a2208200441086a290000370300200120073703a00a20041023200620012903a00a2207370300200141d8076a41086a2003290300370300200141d8076a41106a2007370300200141d8076a41186a200829030037030020012001290398063703d807200141086a200141d8076a10fa02427f200542d8047c220720072005541b22052001290310420020012802081b7d22072005560d00417f20002007a7417f2007428080808010541b6a220320032000491b220320006b220420034b0d002004417f6a4195014b0d00418fcdc200ad4280808080f00084100c22032900002105200141a00a6a41086a2204200341086a290000370300200120053703a00a2003102341bbacc300ad4280808080a00184100c22032900002105200141d8076a41086a2206200341086a290000370300200120053703d80720031023412010212203450d01200320012903a00a370000200320012903d807370010200341086a2004290300370000200341186a22082006290300370000412010212204450d0120042003290000370000200441186a2008290000370000200441106a200341106a290000370000200441086a200341086a29000037000020014190056a41026a2206200141c00b6a41026a2d00003a0000200120012f00c00b3b01900520014180096a41106a42a08080808004370300200141003a0098092001200336028c09200142a080808080043702840920012004360280092001419b096a20062d00003a0000200120012f0190053b009909200141c00b6a20014180096a10d2010240024020012802c00b4101470d0020014198066a41186a2203200141dc0b6a29020037030020014198066a41106a200141d40b6a29020037030020014198066a41086a200141cc0b6a290200370300200120012902c40b3703980641201021220e450d03200e200129039806370000200e41186a2003290300370000200e41106a20014198066a41106a220a290300370000200e41086a20014198066a41086a220c29030037000020014281808080103702bc052001200e3602b805200141a00a6a41186a20014180096a41186a280200360200200141a00a6a41106a20014180096a41106a290300370300200141a00a6a41086a20014180096a41086a29030037030020012001290380093703a00a200141c00b6a200141a00a6a10d201024020012802c00b4101470d00200141c00b6a41047221034102210641202108410121040340200141d8076a41186a200341186a2902002205370300200141d8076a41106a200341106a2902002207370300200141d8076a41086a200341086a290200220b3703002001200329020022153703d80720014198066a41186a220d2005370300200a2007370300200c200b370300200120153703980602402006417f6a2004470d00200141b8056a20044101109a0120012802b805210e0b200e20086a2204200129039806370000200441186a200d290300370000200441106a200a290300370000200441086a200c290300370000200120063602c005200141c00b6a200141a00a6a10d20120012802c00b4101470d01200841206a2108200641016a210620012802bc0521040c000b0b024020012802a40a450d0020012802a00a10230b0240200141b00a6a280200450d0020012802ac0a10230b200141e8046a41086a200141b8056a41086a280200360200200120012903b8053703e8040c010b200141003602f004200142013703e8040240200128028409450d0020012802800910230b200128029009450d00200128028c0910230b418fcdc200ad4280808080f00084100c22032900002105200141a00a6a41086a2204200341086a290000370300200120053703a00a2003102341e2c4c000ad4280808080a00184100c22032900002105200141d8076a41086a2206200341086a290000370300200120053703d80720031023412010212203450d01200320012903a00a370000200320012903d807370010200341086a2004290300370000200341186a22082006290300370000412010212204450d0120042003290000370000200441186a2008290000370000200441106a200341106a290000370000200441086a200341086a290000370000200141b8046a41026a2206200141c00b6a41026a2d00003a0000200120012f00c00b3b01b80420014180096a41106a42a08080808004370300200141003a0098092001200336028c09200142a080808080043702840920012004360280092001419b096a20062d00003a0000200120012f01b8043b009909200141c00b6a20014180096a10f2030240024020012d00f00b4102460d0020014198066a41186a200141c00b6a41186a29030037030020014198066a41106a200141c00b6a41106a29030037030020014198066a41086a200141c00b6a41086a290300370300200120012903c00b37039806024020012802e40b41ffffff3f71450d0020012802e00b10230b412010212209450d032009200129039806370000200941186a20014198066a41186a2208290300370000200941106a20014198066a41106a220a290300370000200941086a20014198066a41086a220c29030037000020014281808080103702bc05200120093602b805200141a00a6a41186a20014180096a41186a280200360200200141a00a6a41106a20014180096a41106a290300370300200141a00a6a41086a20014180096a41086a29030037030020012001290380093703a00a200141c00b6a200141a00a6a10f203024020012d00f00b4102460d0041202106410121040340200141d8076a41186a2203200141c00b6a41186a290300370300200141d8076a41106a220d200141c00b6a41106a290300370300200141d8076a41086a220e200141c00b6a41086a290300370300200120012903c00b3703d807024020012802e40b41ffffff3f71450d0020012802e00b10230b20082003290300370300200a200d290300370300200c200e290300370300200120012903d807370398060240200420012802bc05470d00200141b8056a20044101109a0120012802b80521090b200920066a2203200129039806370000200341186a2008290300370000200341106a200a290300370000200341086a200c2903003700002001200441016a22043602c005200641206a2106200141c00b6a200141a00a6a10f20320012d00f00b4102470d000b0b024020012802a40a450d0020012802a00a10230b0240200141b00a6a280200450d0020012802ac0a10230b20014190056a41086a200141b8056a41086a280200360200200120012903b805370390050c010b200141003602980520014201370390050240200128028409450d0020012802800910230b200128029009450d00200128028c0910230b024020012802f004220c41808004490d00024020012802940541ffffff3f71450d0020012802900510230b20012802ec0441ffffff3f71450d0120012802e80410230c010b200141c00b6a200141e8046a108e0220012802c40b210420012802c00b210320014190056a20012802980520012802c80b41057422064105752208109a01200128029005220e200128029805220a4105746a2003200610a1051a2001200a20086a2216360298050240200441ffffff3f71450d00200310230b20012802ec04211d20012802e8042109200141c00b6a41186a22044200370300200141c00b6a41106a22064200370300200141c00b6a41086a22034200370300200142003703c00b418fcdc200ad4280808080f000842205100c220a2900002107200141a00a6a41086a2208200a41086a290000370300200120073703a00a200a102320032008290300370300200120012903a00a3703c00b41a8c5c000ad4280808080a00284100c220d2900002107200141d8076a41086a220a200d41086a290000370300200120073703d807200d1023201b20012903d807370000201b41086a220d200a29030037000020014198066a41086a2218200329030037030020014198066a41106a221c200629030037030020014198066a41186a221e2004290300370300200120012903c00b37039806200141203602c40b200120014198066a3602c00b2009200c200141c00b6a109c020240201d41ffffff3f71450d00200910230b2001280294052109200442003703002006420037030020034200370300200142003703c00b2005100c220c29000021052008200c41086a290000370300200120053703a00a200c102320032008290300370300200120012903a00a3703c00b41bac5c000ad4280808080a00284100c22082900002105200a200841086a290000370300200120053703d80720081023201b20012903d807370000200d200a29030037000020182003290300370300201c2006290300370300201e2004290300370300200120012903c00b37039806200141203602c40b200120014198066a3602c00b200e2016200141c00b6a109c020240200941ffffff3f71450d00200e10230b200141c00b6a41186a22064200370300200141c00b6a41106a22084200370300200141c00b6a41086a22034200370300200142003703c00b418fcdc200ad4280808080f00084100c22042900002105200141a00a6a41086a220a200441086a290000370300200120053703a00a200410232003200a290300370300200120012903a00a3703c00b41ccc5c000ad4280808080900284100c22042900002105200141d8076a41086a220a200441086a290000370300200120053703d80720041023201b20012903d807370000201b41086a200a29030037000020014198066a41086a200329030037030020014198066a41106a200829030037030020014198066a41186a2006290300370300200120012903c00b37039806410110212203450d05200341013a000020034101410510252203450d052003200036000120014198066aad42808080808004842003ad4280808080d00084100e200310230b200141c00b6a41186a4200370300200141c00b6a41106a220e4200370300200141c00b6a41086a22034200370300200142003703c00b41fea6c600ad4280808080a00184100c220429000021052003200441086a290000370300200120053703c00b20041023419ca8c600ad4280808080e00084100c22042900002105200141d8076a41086a2206200441086a290000370300200120053703d80720041023200e20012903d807220537030020014198066a41086a200329030037030020014198066a41106a200537030020014198066a41186a2006290300370300200120012903c00b37039806200141c00b6a20014198066a10820320012802c00b2203410420031b210d0240024020012902c40b420020031b2205422088a7220641c4006c22030d004100210a0c010b200d20036a21044100210a200d210302400340024020032d00004101460d00200341046a28020020004f0d020b200a41016a210a2004200341c4006a2203470d000b0b200a20064b0d020b2006200a6b211b200542ffffffff0f832105200d200a41c4006c22046a210c200d210602400340024020040d00200c21030c020b200441bc7f6a210420062d00002108200641c4006a2203210620084102470d000b0b02400340200c2003460d0120032d00002104200341c4006a210320044102470d000b0b0240201b450d000240200a450d00200d200d200a41c4006c6a201b41c4006c10a2051a0b201bad42208620058421050b200141c00b6a41186a22064200370300200141c00b6a41106a22084200370300200141c00b6a41086a22034200370300200142003703c00b41fea6c600ad4280808080a00184100c220429000021072003200441086a290000370300200120073703c00b20041023419ca8c600ad4280808080e00084100c22042900002107200141d8076a41086a220a200441086a290000370300200120073703d80720041023200e20012903d807370000200e41086a200a29030037000020014198066a41086a200329030037030020014198066a41106a200829030037030020014198066a41186a2006290300370300200120012903c00b37039806200141c00b6a200d2005422088a710970320014198066aad220b4280808080800484220720013502c80b42208620012802c00b2204ad84100e2005a72103024020012802c40b450d00200410230b02402003450d00200341c4006c450d00200d10230b200141c00b6a41186a22064200370300200141c00b6a41106a22084200370300200141c00b6a41086a22044200370300200142003703c00b41fea6c600ad4280808080a00184100c220329000021052004200341086a290000370300200120053703c00b200310234198bdc600ad4280808080c00184100c22032900002105200141d8076a41086a220a200341086a290000370300200120053703d80720031023200e20012903d807370000200e41086a200a29030037000020014198066a41086a220a200429030037030020014198066a41106a220c200829030037030020014198066a41186a220d2006290300370300200120012903c00b37039806200141003a00b8042007200141b8046aad42808080801084100e20014198066a108503200141b8046a41186a220e200d290300370300200141b8046a41106a221b200c290300370300200141b8046a41086a2209200a29030037030020012001290398063703b804412410212203450d04200320012903b80437000020034114360220200341186a200e290300370000200341106a201b290300370000200341086a200929030037000020014281808080103702c40b200120033602c00b200141c00b6a10b9012006200d2903003703002008200c2903003703002004200a29030037030020012001290398063703c00b200141c00b6a10d102412010272203450d0041fba7c600ad4280808080f00084100c22042900002105200141d8076a41086a2206200441086a290000370300200120053703d80720041023200341086a2006290300370000200320012903d8073700004182a8c600ad4280808080b00184100c22042900002105200141a00a6a41086a2206200441086a290000370300200120053703a00a20041023200341186a2006290300370000200320012903a00a37001020012003412010cd010240024020012802004101470d002001280204211f2003ad4280808080800484101120031023201f450d01200b4280808080c0008421354100211c4100211803402001201836029806200141c00b6a41186a220920351018220341186a290000370300200141c00b6a41106a220a200341106a290000370300200141c00b6a41086a2216200341086a290000370300200120032900003703c00b2003102341c00010272203450d0341fba7c600ad4280808080f00084100c22042900002105200141d8076a41086a220c200441086a290000370300200120053703d80720041023200341086a200c290300370000200320012903d807370000418da8c600ad4280808080f00084100c22042900002105200141a00a6a41086a2206200441086a290000370300200120053703a00a20041023200341186a2006290300370000200320012903a00a370010200341386a2009290300370000200341306a200a290300370000200341286a2016290300370000200320012903c00b37002020014198066a200341c0001089020240200128029806221d450d002003ad428080808080088410110b20012802a0062104200128029c06211e20031023201d450d0202402004450d0020044105742108201c2106201d21030340200141d8076a41186a220d200341186a290000370300200141d8076a41106a220e200341106a290000370300200c200341086a290000370300200120032900003703d80720014198066a41186a420037030020014198066a41106a420037030020014198066a41086a420037030020014200370398060240200141d8076a20014198066a412010a305450d00200141a00a6a200141d8076a109702200141c00b6a20012802a00a221b20012802a80a109802200a290300420020012903c00b42015122041b210520012903c80b420020041b2107200141c00b6a41206a290300420020041b210b20012903d80b420020041b2115024020012802a40a450d00201b10230b427f200720157c2215201520075422042005200b7c2004ad7c220720055420072005511b22041b427f200720041b84500d002009200d290300370300200a200e2903003703002016200c290300370300200120012903d8073703c00b20014198066a200610fb0220013502a0062105200128029806210d411010212204450d0620044110412010252204450d0a200420012903c00b370000200441186a2009290300370000200441106a200a290300370000200441086a20162903003700002004412041c00010252204450d0a20044200370020200441286a42003700002005422086200dad842004ad4280808080800684100e20041023200128029c06450d00200d10230b200341206a2103200641016a2106200841606a22080d000b0b0240201e41ffffff3f71450d00201d10230b201c41c0006a211c201841016a2218201f470d000c020b0b200310230b10ea0320014198066a41186a2208420037030020014198066a41106a2203420037030020014198066a41086a22044200370300200142003703980641e4dec400ad4280808080e00084100c220629000021052004200641086a29000037030020012005370398062006102341f9dec400ad4280808080a00184100c22062900002105200141a00a6a41086a220a200641086a290000370300200120053703a00a20061023200320012903a00a2205370300200141d8076a41086a2004290300370300200141d8076a41106a2005370300200141d8076a41186a200a29030037030020012001290398063703d807200141c00b6a200141d8076a412010e10120012d00c00b21062008200141d90b6a2900003703002003200141d10b6a2900003703002004200141c90b6a290000370300200120012900c10b370398060240024020064101460d00200141c8036a41186a4200370300200141c8036a41106a4200370300200141c8036a41086a4200370300200142003703c8030c010b200141c8036a41186a2008290300370300200141c8036a41106a2003290300370300200141c8036a41086a200429030037030020012001290398063703c8030b20014198066a41186a2208420037030020014198066a41106a220a420037030020014198066a41086a22044200370300200142003703980641abe3c200ad4280808080800384100c220629000021052004200641086a29000037030020012005370398062006102341c3e3c200ad4280808080e00184100c22062900002105200141a00a6a41086a220c200641086a290000370300200120053703a00a20061023200320012903a00a370000200341086a200c290300370000200141d8076a41086a2004290300370300200141d8076a41106a200a290300370300200141d8076a41186a200829030037030020012001290398063703d807200141c00b6a200141d8076a4120108902024002400240024020012802c00b22040d0041002103200141003602a80a200142013703a00a200141e8036a41186a200141c8036a41186a290300370300200141e8036a41106a200141c8036a41106a290300370300200141e8036a41086a200141c8036a41086a290300370300200120012903c8033703e803200141e8036a21060c010b200120012902c40b22053702a40a200120043602a00a2005a7210a02402005422088a7220341d100490d0020014198066a41186a2208200141c8036a41186a29030037030020014198066a41106a220c200141c8036a41106a29030037030020014198066a41086a220d200141c8036a41086a290300370300200120012903c803370398062000417f6a41d10070220620034f0d06200420064105746a2206200129039806370000200641186a2008290300370000200641106a200c290300370000200641086a200d2903003700000c030b200141e8036a41186a200141c8036a41186a290300370300200141e8036a41106a200141c8036a41106a290300370300200141e8036a41086a200141c8036a41086a290300370300200120012903c8033703e803200141e8036a21062003200a470d010b200141a00a6a20034101109a0120012802a40a210a20012802a00a210420012802a80a21030b200420034105746a22082006290000370000200841186a200641186a290000370000200841106a200641106a290000370000200841086a200641086a2900003700002001200341016a22033602a80a0b20014198066a41186a420037030020014198066a41106a220c420037030020014198066a41086a22064200370300200142003703980641abe3c200ad4280808080800384100c220829000021052006200841086a29000037030020012005370398062008102341c3e3c200ad4280808080e00184100c22082900002105200141d8076a41086a220d200841086a290000370300200120053703d80720081023200c20012903d8072205370300200141e8036a41086a2006290300370300200141e8036a41106a2005370300200141e8036a41186a200d29030037030020012001290398063703e8030240024020040d00200141e8036aad428080808080048410110c010b200141203602c40b2001200141e8036a3602c00b20042003200141c00b6a10bf03200a41ffffff3f71450d00200410230b200141800d6a24000f0b1033000b200a2006103c000b2006200341e0fdc2001030000b102c000b102a000baa2309057f017e037f017e017f037e037f037e017f230041c0046b22002400200041f0016a41186a22014200370300200041f0016a41106a22024200370300200041f0016a41086a22034200370300200042003703f00141a7b3c500ad4280808080c00084100c22042900002105200041d0036a41086a2206200441086a290000370300200020053703d0032004102320032006290300370300200020002903d0033703f00141f4bdc500ad4280808080b00184100c220429000021052006200441086a290000370300200020053703d00320041023200220002903d0032205370300200041a0046a41086a2003290300370300200041a0046a41106a2005370300200041a0046a41186a2006290300370300200020002903f0013703a004200041f0016a200041a0046a108704024002400240024020002d00f0014102470d00200142003703002002420037030020034200370300200042003703f00141e4dec400ad4280808080e00084100c220629000021052003200641086a290000370300200020053703f001200610234191dfc400ad4280808080e00084100c2206290000210520004188016a41086a2204200641086a29000037030020002005370388012006102320022000290388012205370300200041e8026a41086a2003290300370300200041e8026a41106a2005370300200041e8026a41186a2004290300370300200020002903f0013703e802200041206a200041e8026a10f70202400240200028022022070d0041002108200041003602f002200042043703e8024202210941042107200041e8026a210a0c010b2000200029022422053702ec02200020073602e8022005a72108200041e8026a210a02402005422088a72203450d00200341246c21062007210302400340024020032d00004101470d00200341016a2800002104200341086a28020021012000200341106a28020036028c012000200136028801200441c28289aa04470d00200041f0016a20004188016a10f90320002903f00122094202520d020b200341246a21032006415c6a2206450d020c000b0b20002903f801210b200041206a20004180026a41e80010a1051a0c010b420221090b200a10960302402008450d00200841246c450d00200710230b20004188016a200041206a41e80010a1051a0240024020094202520d0041002101200041a0046a21070c010b200041e8026a20004188016a41e80010a1051a200041f0016a41186a22044200370300200041f0016a41106a22014200370300200041f0016a41086a22064200370300200042003703f00141a7b3c500ad4280808080c000842205100c2207290000210c200041d0036a41086a2203200741086a2900003703002000200c3703d0032007102320062003290300370300200020002903d0033703f0014188bbc500ad4280808080b00184220d100c2207290000210c2003200741086a2900003703002000200c3703d00320071023200220002903d003370000200241086a220e2003290300370000200041a0046a41086a22072006290300370300200041a0046a41106a22082001290300370300200041a0046a41186a220a2004290300370300200020002903f0013703a004200041106a200041a0046a10fa02024002402000280210450d002000290318500d00200041a0046aad4280808080800484210c200041a0046a21070c010b200442003703002001420037030020064200370300200042003703f0012005100c220f290000210c2003200f41086a2900003703002000200c3703d003200f102320062003290300370300200020002903d0033703f001200d100c220f290000210c2003200f41086a2900003703002000200c3703d003200f1023200220002903d003370000200e20032903003700002007200629030037030020082001290300370300200a2004290300370300200020002903f0013703a0042000200b3703f001200041a0046aad4280808080800484220c200041f0016aad4280808080800184100e200442003703002001420037030020064200370300200042003703f0012005100c220f290000210d2003200f41086a2900003703002000200d3703d003200f102320062003290300370300200020002903d0033703f00141bcbac500ad4280808080b00184100c220f290000210d2003200f41086a2900003703002000200d3703d003200f1023200220002903d003370000200e20032903003700002007200629030037030020082001290300370300200a2004290300370300200020002903f0013703a004200041f0016a200041a0046a10d10420002902f401210d20002802f001210f200442003703002001420037030020064200370300200042003703f0012005100c221029000021052003201041086a290000370300200020053703d0032010102320062003290300370300200020002903d0033703f00141c8bbc500ad4280808080a00184100c221029000021052003201041086a290000370300200020053703d00320101023200220002903d003370000200e20032903003700002007200629030037030020082001290300370300200a2004290300370300200020002903f0013703a004200041f0016a200041a0046a10970420002d00f0012103200a20004189026a290000370300200820004181026a2900003703002007200041f9016a290000370300200020002900f1013703a0040240024020034101460d0020004188046a420037030020004180046a4200370300200041f8036a4200370300200042003703f0030c010b200041f0036a41186a200041a0046a41186a290300370300200041f0036a41106a200041a0046a41106a290300370300200041f0036a41086a200041a0046a41086a290300370300200020002903a0043703f0030b200041d0036a41086a200041f0036a41086a2903002205370300200041d0036a41106a200041f0036a41106a2903002211370300200041d0036a41186a200041f0036a41186a2903002212370300200020002903f00322133703d003200041a0046a41186a2012370300200041a0046a41106a2011370300200041a0046a41086a2005370300200020133703a004200042013703f001200041003602f801410110212203450d05200f4108200f1b210e200041013602f401200020033602f001200341013a0000200041013602f801200d422088a74100200f1b2203200041f0016a10610240024020030d0020002802f80121060c010b200e200341286c6a210a20002802f401210120002802f8012106200e2103034002400240200120066b4120490d00200641206a210420002802f0012108200121070c010b200641206a22042006490d06200141017422072004200720044b1b22074100480d060240024020010d00024020070d00410121080c020b2007102122080d010c0a0b20002802f001210820012007460d0020082001200710252208450d090b200020073602f401200020083602f0010b200820066a22062003290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a290000370000200020043602f801200341206a290300210502400240200720046b4108490d00200441086a2106200721010c010b200441086a22062004490d06200741017422012006200120064b1b22014100480d060240024020070d00024020010d00410121080c020b200110212208450d0a0c010b20072001460d0020082007200110252208450d090b200020013602f401200020083602f0010b200820046a2005370000200020063602f801200a200341286a2203470d000b0b0240024020002802f401220420066b4120490d0020002802f00121030c010b200641206a22032006490d04200441017422012003200120034b1b22014100480d040240024020040d00024020010d00410121030c020b200110212203450d080c010b20002802f001210320042001460d0020032004200110252203450d070b200020013602f401200020033602f0010b200320066a220320002903a004370000200341086a200041a0046a41086a290300370000200341186a200041a0046a41186a290300370000200341106a200041a0046a41106a290300370000200041fb036a200641206a360000200020002903f0013700f303200041fc016a200041f7036a290000370000200041c28289aa043600f101200041023a00f001200020002900f0033700f501200041f0016a10f8030240200da74100200f1b2203450d00200341286c450d00200e10230b200041a0046a21070b200041f0016a41186a22044200370300200041f0016a41106a22014200370300200041f0016a41086a22064200370300200042003703f00141a7b3c500ad4280808080c000842205100c2208290000210d200041d0036a41086a2203200841086a2900003703002000200d3703d0032008102320062003290300370300200020002903d0033703f00141a4bbc500ad4280808080b00184220d100c220829000021112003200841086a290000370300200020113703d00320081023200220002903d003370000200241086a22082003290300370000200041a0046a41086a220a2006290300370300200041a0046a41106a220e2001290300370300200041a0046a41186a220f2004290300370300200020002903f0013703a0042000200041a0046a10fa022000280200211420002903082111200442003703002001420037030020064200370300200042003703f0012005100c221029000021122003201041086a290000370300200020123703d0032010102320062003290300370300200020002903d0033703f00141abb3c500ad4280808080800184100c221029000021122003201041086a290000370300200020123703d00320101023200220002903d00337000020082003290300370000200a2006290300370300200e2001290300370300200f2004290300370300200020002903f0013703a00420004200200b201142017c420120141b7d22112011200b561b3e02f001200c200041f0016aad22114280808080c00084100e200442003703002001420037030020064200370300200042003703f0012005100c221029000021052003201041086a290000370300200020053703d0032010102320062003290300370300200020002903d0033703f001200d100c221029000021052003201041086a290000370300200020053703d00320101023200220002903d00337000020082003290300370000200a2006290300370300200e2001290300370300200f2004290300370300200020002903f0013703a0042000200b3703f001200c20114280808080800184100e4100210120094200520d00200041f0016a200041e8026a41e80010a1051a200041f0036a41186a2000418c026a290200370300200041f0036a41106a20004184026a290200370300200041f0036a41086a200041fc016a290200370300200020002902f4013703f003410121010b200041e8026a41186a200041f0036a41186a290300370300200041e8026a41106a200041f0036a41106a290300370300200041e8026a41086a200041f0036a41086a290300370300200020002903f0033703e802200041f0016a41186a22084200370300200041f0016a41106a220a4200370300200041f0016a41086a22064200370300200042003703f00141a7b3c500ad4280808080c00084100c22042900002105200041d0036a41086a2203200441086a290000370300200020053703d0032004102320062003290300370300200020002903d0033703f00141f4bdc500ad4280808080b00184100c220429000021052003200441086a290000370300200020053703d00320041023200220002903d003370000200241086a2003290300370000200041a0046a41086a2006290300370300200041a0046a41106a200a290300370300200041a0046a41186a2008290300370300200020002903f0013703a004410110212203450d020240024020010d00200341003a000042808080801021050c010b200341013a000020034101412110252203450d04200320002903e802370001200341196a20004180036a290300370000200341116a200041f8026a290300370000200341096a200041f0026a2903003700004280808080900421050b2007ad428080808080048420052003ad84100e200310230b200041c0046a24000f0b102c000b1033000b102a000b940405047f017e017f017e057f230041f0006b22002400200041c0006a41186a22014200370300200041c0006a41106a22024200370300200041c0006a41086a220342003703002000420037034041a7b3c500ad4280808080c000842204100c22052900002106200041e0006a41086a2207200541086a2900003703002000200637036020051023200320072903003703002000200029036037034041a4bac500ad4280808080a00184100c220529000021062007200541086a2900003703002000200637036020051023200220002903602206370300200041206a41086a22082003290300370300200041206a41106a22092006370300200041206a41186a220a200729030037030020002000290340370320200041106a200041206a10fa022000280210210b20002903182106200142003703002002420037030020034200370300200042003703402004100c220529000021042007200541086a290000370300200020043703602005102320032007290300370300200020002903603703404188bbc500ad4280808080b00184100c220529000021042007200541086a29000037030020002004370360200510232002200029036022043703002008200329030037030020092004370300200a2007290300370300200020002903403703202000200041206a10fa022000280200210720002903082104200041f0006a24002004420020071b200642d8047e4200200b1b7c0bfe0304027f017e067f077e230041c0006b220224000240024020012802082203ad42d0007e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510212206450d020b20024100360208200220063602002002200541d0006e36020420024100200310b4012002280208210702402003450d002001200341d0006c6a21082002280200200741d0006c6a2105200341047441706a41047621090340200241206a41086a2203200141086a290300370300200241206a41106a2206200141106a290300370300200241206a41186a220a200141186a29030037030020022001290300370320200141206a2903002104200141286a290300210b200141306a290300210c200141386a290300210d200241106a200141c0006a10b503200a290300210e2006290300210f2003290300211020022903202111200541386a200d370300200541306a200c370300200541286a200b370300200541206a2004370300200541086a201037030020052011370300200541106a200f370300200541186a200e370300200541c0006a2002290310370300200541c8006a200241106a41086a280200360200200541d0006a2105200141d0006a22012008470d000b200720096a41016a21070b20002002290300370200200041086a2007360200200241c0006a24000f0b1032000b1033000b990402067f017e230041e0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841010108b0102400240200228021022010d00200041003602000c010b200228021421032002200241186a280200360224200220013602202002200241206a1088010240024020022802000d002002280224220420022802044102742205490d0002400240024002402005417f4c0d000240024020050d00410121060c010b200510272206450d02200620022802202207200510a1051a2002200420056b3602242002200720056a3602200b2006450d0402402005ad22084220862008842208422088a722050d002008a721050c030b024020062005724103710d002008a722054103710d0020054102762204450d032008422288a721070c040b2008a7450d04200610230c040b1032000b1033000b4100210702402005450d00200610230b41002104410421060b41000d002006450d002000200436020420002006360200200041086a20073602000c010b20024100360230200242013703282002410a36023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c20024180c5c6003602482002200241386a360258200241c4006a4184a5c200200241c8006a10311a2002350230422086200235022884100a0240200228022c450d00200228022810230b200041003602000b2003450d00200110230b200241e0006a24000bff740a067f017e057f017e047f027e017f027e037f017e230041f0026b220524000240410810212206450d0020062001200241c0016c6a220736020420062001360200024002400240024020000d00200541a8026a41186a22084200370300200541a8026a41106a22094200370300200541a8026a41086a22024200370300200542003703a80241ecf7c300ad4280808080f00184100c220a290000210b200541f8016a41086a220c200a41086a2900003703002005200b3703f801200a10232002200c290300370300200520052903f8013703a80241bcfec300ad4280808080c00184100c220a290000210b200c200a41086a2900003703002005200b3703f801200a1023200920052903f801220b370300200541d0026a41086a220d2002290300370300200541d0026a41106a220e200b370300200541d0026a41186a220f200c290300370300200520052903a8023703d002200541c8006a200541d0026a10fa022005290350210b20052802482110200842003703002009420037030020024200370300200542003703a80241db97c700ad4280808080f00084100c220a29000021112002200a41086a290000370300200520113703a802200a102341bcbcc300ad4280808080c00184100c220a2900002111200c200a41086a290000370300200520113703f801200a1023200920052903f8012211370300200d2002290300370300200e2011370300200f200c290300370300200520052903a8023703d002200541c0006a200541d0026a412010cd01200b420020101b2005280244410020052802401b109404200610230c010b0240024002402002450d002006200141c0016a3602002005200141226a2900003701aa0220052001412a6a2900003701b20220054198016a41086a220220052903b0023703002005200141326a2900003701ba0220054198016a41106a220c20052903b80237030020052001413a6a2800003601c20220052001413e6a2f00003b01c60220054198016a41186a220920052903c002370300200520012f00203b01a802200520052903a80237039801200541d0026a41186a220a2009290300370300200541d0026a41106a2209200c290300370300200541d0026a41086a220c200229030037030020052005290398013703d002200541f8016a41186a200a290300370300200541f8016a41106a2009290300370300200541f8016a41086a200c290300370300200520052903d0023703f801200628020420062802006b41c0016e41286c41286a2202417f4c0d05200210212212450d04201220052903f80137030020124201370320201241186a200541f8016a41186a2213290300370300201241106a200541f8016a41106a2214290300370300201241086a200541f8016a41086a22152903003703004101210c200541013602e001200520123602d8012005200241286e22023602dc01200628020022092006280204460d012006200941c0016a3602002005200941226a2900003701aa0220052009412a6a2900003701b20220054198016a41086a220e20052903b0023703002005200941326a2900003701ba0220054198016a41106a220f20052903b80237030020052009413a6a2800003601c20220052009413e6a2f00003b01c60220054198016a41186a221020052903c002370300200541003a00c8022005200941216a2d00003a00a902200520092d00203a00a802200520052903a80237039801200541d0026a41186a22092010290300370300200541d0026a41106a220a200f290300370300200541d0026a41086a2208200e29030037030020052005290398013703d0024102210c41c800210d034020132009290300220b3703002014200a2903002211370300201520082903002216370300200520052903d00222173703f8012009200b370300200a201137030020082016370300200520173703d0020240200c417f6a2002470d00200541d8016a2002200628020420062802006b41c0016e41016a10980120052802d80121120b2012200d6a221841606a220220052903d0023703002008290300210b200a29030021112009290300211620184201370300200241186a2016370300200241106a2011370300200241086a200b3703002005200c3602e0010240200628020022022006280204470d0020052802dc0121020c030b2006200241c0016a3602002005200241226a2900003701aa0220052002412a6a2900003701b202200e20052903b0023703002005200241326a2900003701ba02200f20052903b80237030020052002413a6a2800003601c20220052002413e6a2f00003b01c602201020052903c002370300200541003a00c8022005200241216a2d00003a00a902200520022d00203a00a802200520052903a8023703980120092010290300370300200a200f2903003703002008200e29030037030020052005290398013703d002200d41286a210d200c41016a210c20052802dc0121020c000b0b20061023410821124100210c410021020c010b200610230b200541a8026a41186a4200370300200541a8026a41106a22094200370300200541a8026a41086a220a4200370300200542003703a80241ecf7c300ad4280808080f00184100c2208290000210b200541f8016a41086a2206200841086a2900003703002005200b3703f80120081023200a2006290300370300200520052903f8013703a802418cfec300ad4280808080f00084100c2208290000210b2006200841086a2900003703002005200b3703f80120081023200920052903f801220b370300200541d0026a41086a200a290300370300200541d0026a41106a200b370300200541d0026a41186a2006290300370300200520052903a8023703d002200541a8026a200541d0026a412010e5010240024020052802a8024101460d002005200c3602b002200520023602ac02200520123602a802200541d0026a200541a8026a410041002005109504200541d0026aad4280808080800484210b0c010b200541d0026aad4280808080800484220b101120052902ac0221112005200c3602b002200520023602ac02200520123602a802200541d0026a200541a8026a2011a741012011422088a71095040b200541a8026a41186a220a4200370300200541a8026a41106a220c4200370300200541a8026a41086a22064200370300200542003703a80241ecf7c300ad4280808080f001842211100c22082900002116200541f8016a41086a2202200841086a290000370300200520163703f8012008102320062002290300370300200520052903f8013703a80241bcfec300ad4280808080c001842216100c220829000021172002200841086a290000370300200520173703f80120081023200920052903f801370000200941086a22102002290300370000200541d0026a41086a22082006290300370300200541d0026a41106a220d200c290300370300200541d0026a41186a220e200a290300370300200520052903a8023703d002200541306a200541d0026a10fa022005280230211820052903382117200a4200370300200c420037030020064200370300200542003703a8022011100c220f29000021112002200f41086a290000370300200520113703f801200f102320062002290300370300200520052903f8013703a8022016100c220f29000021112002200f41086a290000370300200520113703f801200f1023200920052903f8013700002010200229030037000020082006290300370300200d200c290300370300200e200a290300370300200520052903a8023703d0022005201742017c420120181b22113703a802200b200541a8026aad4280808080800184100e200a4200370300200c420037030020064200370300200542003703a80241db97c700ad4280808080f00084100c2209290000210b2006200941086a2900003703002005200b3703a8022009102341bcbcc300ad4280808080c00184100c2209290000210b2002200941086a2900003703002005200b3703f80120091023200c20052903f801220b37030020082006290300370300200d200b370300200e2002290300370300200520052903a8023703d002200541286a200541d0026a412010cd012011200528022c410020052802281b1094040b410810212202450d022002200736020420022001360200410810212206450d0220062003200441c0016c6a221436020420062003360200200541b8016a200241fcbfc400109604200541c8016a200641fcbfc40010960420052802d001211820052802cc01211220052802c801211020052802c001210920052802bc01210f20052802b801211520054198016a41186a220c420037030020054198016a41106a2213420037030020054198016a41086a22064200370300200542003703980141a7b3c500ad4280808080c00084220b100c220a2900002111200541d0026a41086a2202200a41086a290000370300200520113703d002200a102320062002290300370300200520052903d0023703980141a4bac500ad4280808080a001842216100c220a29000021112002200a41086a290000370300200520113703d002200a1023201320052903d0022211370300200541d8006a41086a220a2006290300370300200541d8006a41106a22082011370300200541d8006a41186a220d20022903003703002005200529039801370358200541186a200541d8006a10fa02024002400240024002402005290320420020052802181b221742017c22112017540d00200c420037030020134200370300200642003703002005420037039801200b100c220e29000021172002200e41086a290000370300200520173703d002200e102320062002290300370300200520052903d002370398012016100c220e29000021162002200e41086a290000370300200520163703d002200e1023201320052903d002370000201341086a22042002290300370000200a200629030037030020082013290300370300200d200c2903003703002005200529039801370358200520113703a802200541d8006aad42808080808004842219200541a8026aad22164280808080800184100e200c420037030020134200370300200642003703002005420037039801200b100c220e290000210b2002200e41086a2900003703002005200b3703d002200e102320062002290300370300200520052903d0023703980141bcbac500ad4280808080b00184100c220e290000210b2002200e41086a2900003703002005200b3703d002200e1023201320052903d00237000020042002290300370000200a200629030037030020082013290300370300200d200c2903003703002005200529039801370358200941286c4104722202417f4c0d06200210212206450d05200541003602b002200520023602ac02200520063602a8022009200541a8026a10610240024020090d0020052802b002210220052802a802210a0c010b2015200941286c6a210d20052802ac02210c20052802b002210220152106034002400240200c20026b4120490d0020052802a802210a200c21090c010b200241206a22092002490d07200c410174220a2009200a20094b1b22094100480d0702400240200c0d00024020090d004101210a0c020b20091021220a0d010c0c0b20052802a802210a200c2009460d00200a200c20091025220a450d0b0b200520093602ac022005200a3602a8020b200a20026a220c2006290000370000200c41186a200641186a290000370000200c41106a200641106a290000370000200c41086a200641086a2900003700002005200241206a22083602b002200641206a290300210b02400240200920086b4108490d00200241286a21022009210c0c010b200841086a22022008490d072009410174220c2002200c20024b1b220c4100480d070240024020090d000240200c0d004101210a0c020b200c1021220a450d0c0c010b2009200c460d00200a2009200c1025220a450d0b0b2005200c3602ac022005200a3602a8020b200a20086a200b370000200520023602b002200d200641286a2206470d000b0b20052802ac02210620192002ad422086200aad84100e02402006450d00200a10230b0240200f450d00200f41286c450d00201510230b0240201142017c220b2011540d0020054198016a41186a220c420037030020054198016a41106a2209420037030020054198016a41086a22024200370300200542003703980141a7b3c500ad4280808080c00084100c220a2900002111200541d0026a41086a2206200a41086a290000370300200520113703d002200a102320022006290300370300200520052903d0023703980141b8bcc500ad4280808080e00184100c220a29000021112006200a41086a290000370300200520113703d002200a1023201320052903d002370000201341086a2006290300370000200541d8006a41086a2002290300370300200541d8006a41106a2009290300370300200541d8006a41186a200c2903003703002005200529039801370358200541a8026a200541d8006a10970420052d00a8022106200c200541c1026a2900003703002009200541b9026a2900003703002002200541b1026a290000370300200520052900a902370398010240024020064101460d00200541f8006a41186a4200370300200541f8006a41106a4200370300200541f8006a41086a4200370300200542003703780c010b200541f8006a41186a200c290300370300200541f8006a41106a2009290300370300200541f8006a41086a200229030037030020052005290398013703780b20054198016a41186a220c420037030020054198016a41106a2209420037030020054198016a41086a22064200370300200542003703980141a7b3c500ad4280808080c000842211100c220a2900002117200541d0026a41086a2202200a41086a290000370300200520173703d002200a102320062002290300370300200520052903d0023703980141e0bcc500ad4280808080c001842217100c220a290000211a2002200a41086a2900003703002005201a3703d002200a1023201320052903d002370000201341086a22082002290300370000200541d8006a41086a220d2006290300370300200541d8006a41106a220e2009290300370300200541d8006a41186a220f200c2903003703002005200529039801370358200541106a200541d8006a412010cd012005280214211520052802102104200c4200370300200942003703002006420037030020054200370398012011100c220a29000021112002200a41086a290000370300200520113703d002200a102320062002290300370300200520052903d002370398012017100c220a29000021112002200a41086a290000370300200520113703d002200a1023201320052903d00237000020082002290300370000200d2006290300370300200e2009290300370300200f200c2903003703002005200529039801370358200541003602a802201920164280808080c00084100e200541d0026a41186a200541f8006a41186a290300370300200541d0026a41106a200541f8006a41106a2903003703002002200541f8006a41086a290300370300200520052903783703d002417f2015410020041b220841016a220220022008491b410d74412872220f417f4c0d07200f1021220d450d06200d20052903d002370000200d200b370020200d41186a200541d0026a41186a290300370000200d41106a200541d0026a41106a290300370000200d41086a200541d0026a41086a2903003700004128210e410021064100210202400340024002402002450d00200c2009470d01200a41ffffff3f71450d00200210230b200620084f0d02200541d8016a2006108804200541a8026a20052802d801220c20052802e0012209108904024020052802a8022202450d002009ad422086200cad8410110b20052902ac02420020021b210b2002410120021b2102024020052802dc01450d00200c10230b200641016a21062002200b422088a74105746a2109200ba7210a2002210c0c010b20054198016a41186a200c41186a221529000037030020054198016a41106a200c41106a220429000037030020054198016a41086a200c41086a221b2900003703002005200c29000037039801201b290000210b20042900002111200c2900002117200541d8006a41186a22042015290000370300200541d8006a41106a22152011370300200541d8006a41086a221b200b37030020052017370358200541a8026a41186a221c2004290300370300200541a8026a41106a22042015290300370300200541a8026a41086a221d201b290300370300200520052903583703a8020240200f200e6b411f4b0d00200e41206a2215200e490d08200f410174221b2015201b20154b1b22154100480d0802400240200f0d00024020150d004101210d0c020b20151021220d450d0d0c010b200f2015460d00200d200f20151025220d450d0c0b2015210f0b200c41206a210c200d200e6a221520052903a802370000201541186a201c290300370000201541106a2004290300370000201541086a201d290300370000200e41206a210e0c000b0b200ead422086200dad8410182202290000210b200241086a2900002111200241106a2900002117200541f8016a41186a200241186a290000370300200541f8016a41106a2017370300200541f8016a41086a20113703002005200b3703f801200210230240200f450d00200d10230b20054198016a41186a2209420037030020054198016a41106a220a420037030020054198016a41086a22064200370300200542003703980141a7b3c500ad4280808080c00084220b100c220c2900002111200541d0026a41086a2202200c41086a290000370300200520113703d002200c102320062002290300370300200520052903d0023703980141b8bcc500ad4280808080e00184100c220c29000021112002200c41086a290000370300200520113703d002200c1023201320052903d002370000201341086a2002290300370000200541d8006a41086a2006290300370300200541d8006a41106a200a290300370300200541d8006a41186a20092903003703002005200529039801370358412010212202450d06200220052903f801370000200241186a200541f8016a41186a290300370000200241106a200541f8016a41106a290300370000200241086a200541f8016a41086a29030037000020192002ad4280808080800484100e20021023200541d8016a41186a200541f8006a41186a2903002211370300200541d8016a41106a200541f8006a41106a2903002217370300200541d8016a41086a200541f8006a41086a290300221a37030020052005290378221e3703d801200541a8026a41186a22082011370300200541a8026a41106a220d2017370300200541a8026a41086a220e201a3703002005201e3703a80220054198016a41186a2209420037030020054198016a41106a220a420037030020054198016a41086a220642003703002005420037039801200b100c220c290000210b200541d0026a41086a2202200c41086a2900003703002005200b3703d002200c102320062002290300370300200520052903d0023703980141c8bbc500ad4280808080a00184100c220c290000210b2002200c41086a2900003703002005200b3703d002200c1023201320052903d002370000201341086a220f2002290300370000200541d8006a41086a22152006290300370300200541d8006a41106a2204200a290300370300200541d8006a41186a221b2009290300370300200520052903980137035841201021220c450d06200c20052903a802370000200c41186a2008290300370000200c41106a200d290300370000200c41086a200e2903003700002019200cad4280808080800484100e200c102320094200370300200a420037030020064200370300200542003703980141a7b3c500ad4280808080c00084100c220c290000210b2002200c41086a2900003703002005200b3703d002200c102320062002290300370300200520052903d0023703980141b8bcc500ad4280808080e00184100c220c290000210b2002200c41086a2900003703002005200b3703d002200c1023201320052903d002370000200f2002290300370000201520062903003703002004200a290300370300201b20092903003703002005200529039801370358200541a8026a200541d8006a10970420052d00a80221022009200541c1026a290000370300200a200541b9026a2900003703002006200541b1026a290000370300200520052900a902370398010240024020024101460d0020054190026a420037030020054188026a420037030020054180026a4200370300200542003703f8010c010b200541f8016a41186a20054198016a41186a290300370300200541f8016a41106a20054198016a41106a290300370300200541f8016a41086a20054198016a41086a29030037030020052005290398013703f8010b200541d0026a41186a200541f8016a41186a290300370300200541d0026a41106a200541f8016a41106a290300370300200541d0026a41086a200541f8016a41086a290300370300200520052903f8013703d002200541003602b002200542013703a802410110212202450d08200541013602ac02200520023602a802200241013a0000200541013602b0022018200541a8026a10610240024020180d0020052802b00221020c010b2010201841286c6a2118410020052802b002220e6b210820052802ac02210c410021020340200e20026a210d02400240200c20086a4120490d0020052802a802210a200c21090c010b200d41206a2206200d490d08200c41017422092006200920064b1b22094100480d0802400240200c0d00024020090d004101210a0c020b20091021220a450d0d0c010b20052802a802210a200c2009460d00200a200c20091025220a450d0c0b200520093602ac022005200a3602a8020b200a200e6a20026a220c201020026a2206290000370000200c41186a200641186a290000370000200c41106a200641106a290000370000200c41086a200641086a2900003700002005200d41206a220c3602b002200641206a290300210b02400240200920086a41606a41074d0d002009210c0c010b200c41086a220f200c490d082009410174220c200f200c200f4b1b220c4100480d080240024020090d000240200c0d004101210a0c020b200c1021220a450d0d0c010b2009200c460d00200a2009200c1025220a450d0c0b2005200c3602ac022005200a3602a8020b200a200e6a20026a41206a200b3700002005200d41286a3602b002200841586a2108200241286a21022018200641286a470d000b200e20026a21020b0240024020052802ac02220c20026b4120490d0020052802a80221060c010b200241206a22062002490d06200c41017422092006200920064b1b22094100480d0602400240200c0d00024020090d00410121060c020b200910212206450d0b0c010b20052802a8022106200c2009460d002006200c200910252206450d0a0b200520093602ac02200520063602a8020b200620026a220620052903d002370000200641086a200541d0026a41086a290300370000200641186a200541d0026a41186a290300370000200641106a200541d0026a41106a290300370000200541a3016a200241206a360000200520052903a80237009b01200541b4026a2005419f016a290000370000200541c28289aa043600a902200541023a00a80220052005290098013700ad02200541a8026a10f80302402012450d00201241286c450d00201010230b410810212206450d082006200736020420062001360200410810212215450d08201520143602042015200336020020054198016a41186a220c420037030020054198016a41106a2209420037030020054198016a41086a220a4200370300200542003703980141e4dec400ad4280808080e00084100c2202290000210b200a200241086a2900003703002005200b370398012002102341f3dec400ad4280808080e00084100c2208290000210b200541d0026a41086a2202200841086a2900003703002005200b3703d00220081023201320052903d002370000201341086a2002290300370000200541d8006a41086a200a290300370300200541d8006a41106a2009290300370300200541d8006a41186a200c2903003703002005200529039801370358200541086a200541d8006a412010cd012005280208210d200528020c210e200541f8016a41186a4200370300200541f8016a41106a22044200370300200541f8016a41086a220a4200370300200542003703f8014180cdc200ad4280808080800184100c2208290000210b2002200841086a2900003703002005200b3703d00220081023200a2002290300370300200520052903d0023703f80141c9a1c200ad4280808080e00184100c2208290000210b2002200841086a2900003703002005200b3703d00220081023200420052903d002220b370300200541a8026a41086a200a290300370300200541a8026a41106a200b370300200541a8026a41186a2002290300370300200520052903f8013703a8022005200e41ac026a41ac02200d1b3602d00220164280808080800484221a200541d0026aad4280808080c00084100e200628020022022006280204460d022006200241c0016a3602002005200241e2006a2900003701aa022005200241ea006a2900003701b20220054198016a41086a220a20052903b0023703002005200241f2006a2900003701ba02200920052903b8023703002005200241fa006a2800003601c2022005200241fe006a2f00003b01c602200c20052903c0023703002005200241e0006a2f00003b01a802200520052903a80237039801200541d0026a41186a2202200c290300370300200541d0026a41106a220c2009290300370300200541d0026a41086a2209200a29030037030020052005290398013703d002200541f8006a41186a2002290300370300200541f8006a41106a200c290300370300200541f8006a41086a22022009290300370300200520052903d002370378200628020420062802006b41c0016e41057441206a220910212212450d0620122005290378370000201241186a200541f8006a41186a290300370000201241106a200541f8006a41106a290300370000201241086a20022903003700004101210c200541013602e001200520123602d80120052009410576220f3602dc01200628020022022006280204460d032006200241c0016a3602002005200241e2006a2900003701aa022005200241ea006a2900003701b20220054198016a41086a220e20052903b0023703002005200241f2006a2900003701ba0220054198016a41106a221020052903b8023703002005200241fa006a2800003601c2022005200241fe006a2f00003b01c60220054198016a41186a221820052903c0023703002005200241e0006a2f00003b01a802200520052903a80237039801200541d0026a41186a22092018290300370300200541d0026a41106a220a2010290300370300200541d0026a41086a2208200e29030037030020052005290398013703d0024102210c4120210d0340200541f8016a41186a2009290300220b370300200541f8016a41106a200a2903002211370300200541f8016a41086a20082903002216370300200520052903d00222173703f8012009200b370300200a201137030020082016370300200520173703d0020240200c417f6a200f470d00200541d8016a200f200628020420062802006b41c0016e41016a109a0120052802d80121120b2012200d6a220220052903d002370000200241186a2009290300370000200241106a200a290300370000200241086a20082903003700002005200c3602e0010240200628020022022006280204470d0020052802dc01210f0c050b2006200241c0016a3602002005200241e2006a2900003701aa022005200241ea006a2900003701b202200e20052903b0023703002005200241f2006a2900003701ba02201020052903b8023703002005200241fa006a2800003601c2022005200241fe006a2f00003b01c602201820052903c0023703002005200241e0006a2f00003b01a802200520052903a8023703980120092018290300370300200a20102903003703002008200e29030037030020052005290398013703d002200d41206a210d200c41016a210c20052802dc01210f0c000b0b41cacec50041c90041a4cfc500104f000b41cacec50041c9004194cfc500104f000b200610234100210f410121124100210c0c010b200610230b200541f8016a41186a220a4200370300200541f8016a41106a22084200370300200541f8016a41086a22064200370300200542003703f8014180cdc200ad4280808080800184100c2209290000210b200541d0026a41086a2202200941086a2900003703002005200b3703d0022009102320062002290300370300200520052903d0023703f80141d7a1c200ad4280808080c00084100c2209290000210b2002200941086a2900003703002005200b3703d00220091023200420052903d002370000200441086a2002290300370000200541a8026a41086a2006290300370300200541a8026a41106a2008290300370300200541a8026a41186a200a290300370300200520052903f8013703a802200c41057422084104722202417f4c0d02200210212206450d01200541003602d802200520023602d402200520063602d002200c200541d0026a106102400240200c0d0020052802d802210620052802d402210920052802d002210e0c010b410020052802d80222066b210a20052802d002210e20052802d40221092012210d0340200d210202402009200a6a411f4b0d00200641206a220c2006490d032009410174220d200c200d200c4b1b220c4100480d03024002400240024020090d000240200c0d004101210e0c020b200c1021210e0c030b2009200c470d010b200c21090c020b200e2009200c1025210e0b200c2109200e450d060b200241206a210d200e20066a220c2002290000370000200c41186a200241186a290000370000200c41106a200241106a290000370000200c41086a200241086a290000370000200a41606a210a200641206a2106200841606a22080d000b200520093602d402200520063602d8022005200e3602d0020b201a2006ad422086200ead84100e02402009450d00200e10230b0240200f41ffffff3f71450d00201210230b20151023410810212206450d032006200736020420062001360200410810212215450d032015201436020420152003360200024002400240024002402000450d00200628020022022006280204460d012006200241c0016a360200200520024182016a2900003701aa0220052002418a016a2900003701b20220054198016a41086a220c20052903b002370300200520024192016a2900003701ba0220054198016a41106a220920052903b80237030020052002419a016a2800003601c20220052002419e016a2f00003b01c60220054198016a41186a220a20052903c002370300200520024180016a2f00003b01a802200520052903a80237039801200541d0026a41186a2202200a290300370300200541d0026a41106a220a2009290300370300200541d0026a41086a2209200c29030037030020052005290398013703d002200541f8006a41186a220c2002290300370300200541f8006a41106a2202200a290300370300200541f8006a41086a220a2009290300370300200520052903d002370378200628020420062802006b41c0016e41057441206a220910212212450d0620122005290378370000201241186a200c290300370000201241106a2002290300370000201241086a200a2903003700004101210c200541013602e001200520123602d80120052009410576220f3602dc01200628020022022006280204460d022006200241c0016a360200200520024182016a2900003701aa0220052002418a016a2900003701b20220054198016a41086a220e20052903b002370300200520024192016a2900003701ba0220054198016a41106a221020052903b80237030020052002419a016a2800003601c20220052002419e016a2f00003b01c60220054198016a41186a221820052903c002370300200520024180016a2f00003b01a802200520052903a80237039801200541d0026a41186a22092018290300370300200541d0026a41106a220a2010290300370300200541d0026a41086a2208200e29030037030020052005290398013703d0024102210c4120210d0340200541f8016a41186a2009290300220b370300200541f8016a41106a200a2903002211370300200541f8016a41086a20082903002216370300200520052903d00222173703f8012009200b370300200a201137030020082016370300200520173703d0020240200c417f6a200f470d00200541d8016a200f200628020420062802006b41c0016e41016a109a0120052802d80121120b2012200d6a220220052903d002370000200241186a2009290300370000200241106a200a290300370000200241086a20082903003700002005200c3602e0010240200628020022022006280204470d0020052802dc01210f0c040b2006200241c0016a360200200520024182016a2900003701aa0220052002418a016a2900003701b202200e20052903b002370300200520024192016a2900003701ba02201020052903b80237030020052002419a016a2800003601c20220052002419e016a2f00003b01c602201820052903c002370300200520024180016a2f00003b01a802200520052903a8023703980120092018290300370300200a20102903003703002008200e29030037030020052005290398013703d002200d41206a210d200c41016a210c20052802dc01210f0c000b0b20151023200610230c030b200610234100210f410121124100210c0c010b200610230b20054198016a41186a2209420037030020054198016a41106a220a420037030020054198016a41086a22024200370300200542003703980141b0dfc300ad4280808080a00184100c2206290000210b2002200641086a2900003703002005200b370398012006102341bcbac500ad4280808080b00184100c2206290000210b200541d0026a41086a2208200641086a2900003703002005200b3703d00220061023201320052903d002370000201341086a2008290300370000200541d8006a41086a2002290300370300200541d8006a41106a200a290300370300200541d8006a41186a20092903003703002005200529039801370358200c41057422084104722202417f4c0d03200210212206450d02200541003602b002200520023602ac02200520063602a802200c200541a8026a106102400240200c0d0020052802b002210620052802ac02210920052802a802210e0c010b410020052802b00222066b210a20052802a802210e20052802ac0221092012210d0340200d210202402009200a6a411f4b0d00200641206a220c2006490d042009410174220d200c200d200c4b1b220c4100480d04024002400240024020090d000240200c0d004101210e0c020b200c1021210e0c030b2009200c470d010b200c21090c020b200e2009200c1025210e0b200c2109200e450d070b200241206a210d200e20066a220c2002290000370000200c41186a200241186a290000370000200c41106a200241106a290000370000200c41086a200241086a290000370000200a41606a210a200641206a2106200841606a22080d000b200520093602ac02200520063602b0022005200e3602a8020b20192006ad422086200ead84100e02402009450d00200e10230b0240200f41ffffff3f71450d00201210230b201510230b410810212206450d032006200736020420062001360200410810212201450d032001201436020420012003360200024002400240024002402000450d00200628020022022006280204460d012006200241c0016a3602002005200241a2016a2900003701aa022005200241aa016a2900003701b20220054198016a41086a220c20052903b0023703002005200241b2016a2900003701ba0220054198016a41106a220920052903b8023703002005200241ba016a2800003601c2022005200241be016a2f00003b01c60220054198016a41186a220a20052903c0023703002005200241a0016a2f00003b01a802200520052903a80237039801200541d0026a41186a2202200a290300370300200541d0026a41106a220a2009290300370300200541d0026a41086a2209200c29030037030020052005290398013703d002200541f8006a41186a220c2002290300370300200541f8006a41106a2202200a290300370300200541f8006a41086a220a2009290300370300200520052903d002370378200628020420062802006b41c0016e41057441206a220910212212450d0620122005290378370000201241186a200c290300370000201241106a2002290300370000201241086a200a2903003700004101210c200541013602e001200520123602d80120052009410576220f3602dc01200628020022022006280204460d022006200241c0016a3602002005200241a2016a2900003701aa022005200241aa016a2900003701b20220054198016a41086a220e20052903b0023703002005200241b2016a2900003701ba0220054198016a41106a221020052903b8023703002005200241ba016a2800003601c2022005200241be016a2f00003b01c60220054198016a41186a221820052903c0023703002005200241a0016a2f00003b01a802200520052903a80237039801200541d0026a41186a22092018290300370300200541d0026a41106a220a2010290300370300200541d0026a41086a2208200e29030037030020052005290398013703d0024102210c4120210d0340200541f8016a41186a2009290300220b370300200541f8016a41106a200a2903002211370300200541f8016a41086a20082903002216370300200520052903d00222173703f8012009200b370300200a201137030020082016370300200520173703d0020240200c417f6a200f470d00200541d8016a200f200628020420062802006b41c0016e41016a109a0120052802d80121120b2012200d6a220220052903d002370000200241186a2009290300370000200241106a200a290300370000200241086a20082903003700002005200c3602e0010240200628020022022006280204470d0020052802dc01210f0c040b2006200241c0016a3602002005200241a2016a2900003701aa022005200241aa016a2900003701b202200e20052903b0023703002005200241b2016a2900003701ba02201020052903b8023703002005200241ba016a2800003601c2022005200241be016a2f00003b01c602201820052903c0023703002005200241a0016a2f00003b01a802200520052903a8023703980120092018290300370300200a20102903003703002008200e29030037030020052005290398013703d002200d41206a210d200c41016a210c20052802dc01210f0c000b0b20011023200610230c030b20061023410121124100210c4100210f0c010b200610230b20054198016a41186a2209420037030020054198016a41106a220a420037030020054198016a41086a220242003703002005420037039801419dcdc200ad4280808080a00284100c2206290000210b2002200641086a2900003703002005200b370398012006102341d7a1c200ad4280808080c00084100c2206290000210b200541d0026a41086a2208200641086a2900003703002005200b3703d00220061023201320052903d002370000201341086a2008290300370000200541d8006a41086a2002290300370300200541d8006a41106a200a290300370300200541d8006a41186a20092903003703002005200529039801370358200c41057422084104722202417f4c0d03200210212206450d02200541003602b002200520023602ac02200520063602a802200c200541a8026a106102400240200c0d0020052802b002210620052802ac02210920052802a802210e0c010b410020052802b00222066b210a20052802a802210e20052802ac0221092012210d0340200d210202402009200a6a411f4b0d00200641206a220c2006490d042009410174220d200c200d200c4b1b220c4100480d04024002400240024020090d000240200c0d004101210e0c020b200c1021210e0c030b2009200c470d010b200c21090c020b200e2009200c1025210e0b200c2109200e450d070b200241206a210d200e20066a220c2002290000370000200c41186a200241186a290000370000200c41106a200241106a290000370000200c41086a200241086a290000370000200a41606a210a200641206a2106200841606a22080d000b200520093602ac02200520063602b0022005200e3602a8020b20192006ad422086200ead84100e02402009450d00200e10230b0240200f41ffffff3f71450d00201210230b200110230b200541f0026a24000f0b102c000b1033000b1032000b102a000bdb1104047f017e137f047e23004180036b220224002002412036022420022001360220200241286a2001ad42808080808004841010108b010240024002400240200228022822030d00200041003602000c010b200228022c21042002200241306a28020036023c20022003360238200241186a200241386a1088010240024020022802180d00200228021c2205200228023c411c6e2201200120054b1bad421c7e2206422088a70d032006a72201417f4c0d030240024020010d00410421070c010b200110212207450d050b200241003602482002200736024020022001411c6e3602440240024002400240024002402005450d00200241a0026a41c4006a2108410021094100210a0340200241106a200241386a10880120022802100d062002280214220b200228023c41e0006e22012001200b4b1bad42e0007e2206422088a70d0a2006a72201417f4c0d0a0240024020010d004108210c0c010b20011021220c450d0c0b200241003602582002200c3602502002200141e0006e3602540240024002400240200b450d004100210d0340200241a0026a200241386a108304200241e0016a41386a2201200241a0026a41386a290300370300200241e0016a41306a220e200241a0026a41306a290300370300200241e0016a41286a220f200241a0026a41286a290300370300200241e0016a41206a2210200241a0026a41206a290300370300200241e0016a41186a2211200241a0026a41186a290300370300200241e0016a41106a2212200241a0026a41106a290300370300200241e0016a41086a2213200241a0026a41086a290300370300200241c0016a41086a2214200841086a290200370300200241c0016a41106a2215200841106a290200370300200241c0016a41186a2216200841186a280200360200200220022903a0023703e001200220082902003703c00120022802e0022217450d0220024180016a41386a2218200129030037030020024180016a41306a2219200e29030037030020024180016a41286a220e200f29030037030020024180016a41206a220f201029030037030020024180016a41186a2210201129030037030020024180016a41106a2211201229030037030020024180016a41086a22122013290300370300200241e0006a41086a22132014290300370300200241e0006a41106a22142015290300370300200241e0006a41186a22152016280200360200200220022903e00137038001200220022903c0013703600240200d2002280254470d00200241d0006a200d41011096012002280250210c2002280258210d0b200c200d41e0006c6a2201200229038001370300200141106a2011290300370300200141086a2012290300370300201929030021062018290300211a200e290300211b200f290300211c2010290300211d200141c0006a2017360200200141186a201d370300200141206a201c370300200141286a201b370300200141c4006a2002290360370200200141386a201a370300200141306a2006370300200141cc006a2013290300370200200141d4006a2014290300370200200141dc006a20152802003602002002200d41016a220d360258200b417f6a220b0d000b0b200c450d0920022902542106200241086a200241386a10880120022802080d06200228020c220b200228023c220d41027622012001200b4b1b2201410274220e417f4c0d0d20010d014104210f0c020b0240200d450d00200d41e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010230b0240200128020041ffffff3f71450d002001417c6a28020010230b200141e0006a2101200d41a07f6a220d0d000b0b20022802542201450d08200141e0006c0d070c080b200e1021220f450d0c0b200241003602a802200220013602a4022002200f3602a0020240200b450d00410021010340200d4104490d042002200d417c6a220d36023c20022002280238220e41046a360238200e280000220e418094ebdc034b0d040240200120022802a402470d00200241a0026a20014101107920022802a002210f20022802a80221010b200f20014102746a200e3602002002200141016a22013602a802200b417f6a220b0d000b0b200f450d0320022902a402211a200d4104490d04200a41016a210a2002200d417c6a36023c20022002280238220141046a3602382001280000210d024020092002280244470d00200241c0006a2009410110a30120022802402107200228024821090b20072009411c6c6a2201200d360218200120063702042001200c360200200141106a201a3702002001410c6a200f3602002002200941016a2209360248200a2005470d000b0b2007450d0520002002290244370204200020073602000c060b20022802a40241ffffffff0371450d00200f10230b02402006422088a72201450d00200141e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010230b0240200128020041ffffff3f71450d002001417c6a28020010230b200141e0006a2101200d41a07f6a220d0d000b0b2006a72201450d02200141e0006c0d010c020b0240201a42ffffffff0383500d00200f10230b02402006422088a72201450d00200141e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010230b0240200128020041ffffff3f71450d002001417c6a28020010230b200141e0006a2101200d41a07f6a220d0d000b0b2006a72201450d01200141e0006c450d010b200c10230b2007200910f00320022802442201450d002001411c6c450d00200710230b200241003602e801200242013703e0012002410a360284012002200241206a360280012002200241e0016a3602c001200241b4026a4101360200200242013702a40220024180c5c6003602a002200220024180016a3602b002200241c0016a4184a5c200200241a0026a10311a20023502e80142208620023502e00184100a024020022802e401450d0020022802e00110230b200041003602000b2004450d00200310230b20024180036a24000f0b1032000b1033000bd90101037f02402001450d0020002001411c6c6a21020340024020002802082201450d00200141e0006c2103200028020041d4006a210103400240200141706a2802002204450d00200441306c450d002001416c6a28020010230b0240200128020041ffffff3f71450d002001417c6a28020010230b200141e0006a2101200341a07f6a22030d000b0b0240200041046a2802002201450d00200141e0006c450d00200028020010230b2000411c6a21010240200041106a28020041ffffffff0371450d00200028020c10230b2001210020012002470d000b0b0bfa0301067f230041106b22032400024002402002411c6c41046a2204417f4c0d000240024020040d00410121050c010b200410212205450d020b20034100360208200320043602042003200536020020022003106102402002450d0020012002411c6c6a2106034020012802002105200128020822022003106102402002450d002005200241e0006c6a2107034020032005412010622003200541206a36020c2003410c6a200310db012003200541306a36020c2003410c6a200310db0120052802402102200528024822042003106102402004450d00200441306c210403402003200241106a412010622003200236020c200241306a21022003410c6a200310db01200441506a22040d000b0b200541e0006a210820052802502102200528025822042003106102402004450d002004410574210403402003200241201062200241206a2102200441606a22040d000b0b2008210520082007470d000b0b2001411c6a2105200128020c2102200128021422042003106102402004450d002004410274210403402003200228020036020c20032003410c6a41041062200241046a21022004417c6a22040d000b0b2003200128021836020c20032003410c6a410410622005210120052006470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1032000b1033000ba90603067f017e047f230041f0006b22022400200241286a200141146a350200422086200135020c841019108b010240024020022802282203450d00200241086a2104200141106a2105034002400240200141086a22062802002207200229022c2208422088a722094b0d002001280200220a2003460d01200a2003200710a305450d010b2008a7450d02200310230c020b02402005280200450d00200128020c10230b2001200336020c2005200837020020022003200910a4020240024020022d00104102460d00200241186a41086a200441086a280200360200200220042902003703182002280204210b2002280200210c024020012d0018450d002001350214422086200135020c8410110b2001280214220920062802002203490d0102400240200920036b22094108490d00200941786a2107200128020c20036a41086a210a0c010b4100210702404100280298ab470d00419ca8c700210a0c010b41002107410028028880402103410028028480402109410028029cab472106200241e000360268200242de80808010370360200241c79ec00036025c20024213370254200241b49ec00036025020024200370348419ca8c700210a2002419ca8c70036024420024201370338200241ac9ec00036023420024113360230200241b49ec00036022c20024101360228200941a0a1c000200641024622061b200241286a200341b8a1c00020061b2802101102000b41002103200241003a00480240034020072003460d01200241286a20036a200a20036a2d00003a00002002200341016a22093a00482009210320094120470d000b20002002290328370000200041186a200241286a41186a290300370000200041106a200241286a41106a290300370000200041086a200241286a41086a2903003700002000200b3602242000200c36022020002002290318370228200041306a200241186a41086a2802003602000c050b0240200341ff0171450d00200241003a00480b200b41ffffff3f71450d00200c10230b200241286a2001350214422086200135020c841019108b01200228022822030d010c020b0b2003200941dc96c7001044000b200041023a00300b200241f0006a24000b13002000410236020420004184b0c3003602000b3400200041db97c70036020420004100360200200041146a4107360200200041106a41b8b7c300360200200041086a42073702000b2c01017f02404104102122020d001033000b20004284808080c00037020420002002360200200241003600000bb20201057f230041106b2203240002400240024002402001410274220441046a2205417f4c0d000240024020050d00410121060c010b200510212206450d020b2003410036020820032005360204200320063602002001200310610240024020032802042207200328020822016b2004490d0020032802002105200721060c010b200120046a22052001490d03200741017422062005200620054b1b22064100480d030240024020070d00024020060d00410121050c020b2006102122050d010c060b2003280200210520072006460d0020052007200610252205450d050b20032006360204200320053602000b200520016a2000200410a1051a2002290200200120046aad4220862005ad84100e02402006450d00200510230b200341106a24000f0b1032000b1033000b102c000b102a000b9111030b7f017e017f230041d0006b2201240020014100360230200142013703280240024002402000280200220241044b0d000240024002400240024020020e050001020304000b410110212202450d062001410136022c20012002360228200241013a000020014101360230200028020421032000410c6a2802002202200141286a10610240024020020d00200128023021020c010b2003200241286c6a21044100200128023022056b2106410021020340200520026a2107024002402006200128022c22086a4120490d00200128022821092008210a0c010b200741206a22092007490d082008410174220a2009200a20094b1b220a4100480d080240024020080d000240200a0d00410121090c020b200a102122090d010c0b0b200128022821092008200a460d0020092008200a10252209450d0a0b2001200a36022c200120093602280b200920056a20026a220b200320026a2208290000370000200b41186a200841186a290000370000200b41106a200841106a290000370000200b41086a200841086a2900003700002001200741206a220b360230200841206a290300210c0240200a20066a41606a41074b0d00200b41086a220d200b490d08200a410174220b200d200b200d4b1b220b4100480d0802400240200a0d000240200b0d00410121090c020b200b10212209450d0b0c010b200a200b460d002009200a200b10252209450d0a0b2001200b36022c200120093602280b200920056a20026a41206a200c3700002001200741286a360230200641586a2106200241286a21022004200841286a470d000b200520026a21020b200041106a280200210a02400240200128022c220920026b4104490d00200128022821080c010b200241046a22082002490d06200941017422062008200620084b1b22064100480d060240024020090d00024020060d00410121080c020b200610212208450d090c010b2001280228210820092006460d0020082009200610252208450d080b2001200636022c200120083602280b200820026a200a3600002001200241046a3602300c040b410110212202450d052001410136022c20012002360228200241023a0000200141013602302000280204210902400240200128022c2208417f6a4104490d00200128022821020c010b200841017422024105200241054b1b220a4100480d052001280228210202402008200a460d0020022008200a10252202450d070b2001200a36022c200120023602280b200220093600012001410536023020002802082102200041106a2802002208200141286a10610240024020080d002001280230210a0c010b2002200841286c6a210b2001280230210a034002400240200128022c2207200a6b4120490d00200a41206a210820012802282109200721060c010b200a41206a2208200a490d07200741017422092008200920084b1b22064100480d070240024020070d00024020060d00410121090c020b200610212209450d0a0c010b2001280228210920072006460d0020092007200610252209450d090b2001200636022c200120093602280b2009200a6a220a2002290000370000200a41186a200241186a290000370000200a41106a200241106a290000370000200a41086a200241086a29000037000020012008360230200241206a290300210c0240200620086b41074b0d00200841086a220a2008490d0720064101742207200a2007200a4b1b220a4100480d070240024020060d000240200a0d00410121090c020b200a10212209450d0a0c010b2006200a460d0020092006200a10252209450d090b2001200a36022c200120093602280b200920086a200c3700002001200841086a220a360230200b200241286a2202470d000b0b200041146a280200210902400240200128022c2208200a6b4104490d00200128022821020c010b200a41046a2202200a490d05200841017422062002200620024b1b22064100480d050240024020080d00024020060d00410121020c020b200610212202450d080c010b2001280228210220082006460d0020022008200610252202450d070b2001200636022c200120023602280b2002200a6a20093600002001200a41046a3602300c030b410110212202450d042001410136022c20012002360228200241033a000020014101360230200041086a290300210c02400240200128022c2208417f6a4108490d00200128022821020c010b200841017422024109200241094b1b22094100480d0420012802282102024020082009460d0020022008200910252202450d060b2001200936022c200120023602280b2002200c370001200141093602300c020b410110212202450d032001410136022c20012002360228200241043a0000200141013602302000280204210902400240200128022c2208417f6a4104490d00200128022821020c010b200841017422024105200241054b1b220a4100480d032001280228210202402008200a460d0020022008200a10252202450d050b2001200a36022c200120023602280b20022009360001200141053602300c010b410110212202450d022001410136022c20012002360228200241053a0000200141013602302000280204210902400240200128022c2208417f6a4104490d00200128022821020c010b200841017422024105200241054b1b220a4100480d022001280228210202402008200a460d0020022008200a10252202450d040b2001200a36022c200120023602280b20022009360001200141053602300b200141146a200141306a2802003600002001200129032837000c200141346a200141106a290000370000200141c6a4b9da04360029200141023a00282001200129000937002d200141286a10f80302402000280200220241014b0d000240024020020e020001000b200041086a2802002202450d01200241286c450d01200028020410230c010b2000410c6a2802002202450d00200241286c450d00200041086a28020010230b200141d0006a24000f0b102c000b102a000bd00703047f017e057f230041f0006b22012400200141c8006a41186a4200370300200141c8006a41106a22024200370300200141c8006a41086a220342003703002001420037034841e4dec400ad4280808080e00084100c220429000021052003200441086a29000037030020012005370348200410234191dfc400ad4280808080e00084100c22042900002105200141386a41086a2206200441086a2900003703002001200537033820041023200220012903382205370300200141186a41086a2003290300370300200141186a41106a2005370300200141186a41186a200629030037030020012001290348370318200141c8006a200141186a10f70202400240200128024822020d0041002106200141003602102001420437030841042102410021030c010b2001200129024c220537020c200120023602082005422088a721032005a721060b200141c8006a41206a2207200041206a280200360200200141c8006a41186a2208200041186a290200370300200141c8006a41106a2209200041106a290200370300200141c8006a41086a2204200041086a29020037030020012000290200370348024020032006470d00200141086a2003410110a201200128020c210620012802082102200128021021030b2002200341246c220a6a22002001290348370200200041206a2007280200360200200041186a2008290300370200200041106a2009290300370200200041086a20042903003702002001200341016a22003602102008420037030020094200370300200442003703002001420037034841e4dec400ad4280808080e00084100c220829000021052004200841086a29000037030020012005370348200810234191dfc400ad4280808080e00084100c22082900002105200141386a41086a2207200841086a2900003703002001200537033820081023200920012903382205370300200141186a41086a2004290300370300200141186a41106a2005370300200141186a41186a2007290300370300200120012903483703182001412036024c2001200141186a36024820022000200141c8006a10f802024020002003490d00200a41246a21032002210003400240024020002d0000220441044b0d0002400240024020040e050400010204040b2000410c6a280200450d03200041086a28020010230c030b2000410c6a280200450d02200041086a28020010230c020b2000410c6a280200450d01200041086a28020010230c010b200041086a280200450d00200041046a28020010230b200041246a21002003415c6a22030d000b0b02402006450d00200641246c450d00200210230b200141f0006a24000bed0803067f017e057f230041f0016b2202240002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002005417f6a220541014b0d0320050e020102010b200042023703000c040b024020064104490d002004280001210720012003417b6a22053602042001200441056a36020020054108490d00200429000521082001200341736a36020420012004410d6a36020041002105200241003a008801410d20036b2109200341726a2106024002400340200920056a450d01200241e8006a20056a200420056a220a410d6a2d00003a0000200120063602042001200a410e6a3602002002200541016a220a3a0088012006417f6a2106200a2105200a4120470d000b200241d0016a41186a200241e8006a41186a290300370300200241d0016a41106a200241e8006a41106a290300370300200241d0016a41086a200241e8006a41086a290300370300200220022903683703d00141002105200241003a00a8012004200a6a2109200a20036b410d6a210a0340200a20056a450d02200241e8006a20056a200920056a2204410d6a2d00003a00002001200636020420012004410e6a3602002002200541016a22043a00a8012006417f6a210620042105200441c000470d000b200241086a41386a2201200241e8006a41386a290300370300200241086a41306a2205200241e8006a41306a290300370300200241086a41286a2206200241e8006a41286a290300370300200241086a41206a2204200241e8006a41206a290300370300200241086a41186a220a200241e8006a41186a290300370300200241086a41106a2203200241e8006a41106a290300370300200241086a41086a2209200241e8006a41086a290300370300200241c8006a41086a220b200241d0016a41086a290300370300200241c8006a41106a220c200241d0016a41106a290300370300200241c8006a41186a220d200241d0016a41186a29030037030020022002290368370308200220022903d001370348200041106a20073602002000200837030820004200370300200020022903483702142000411c6a200b290300370200200041246a200c2903003702002000412c6a200d290300370200200020022903083702342000413c6a2009290300370200200041c4006a2003290300370200200041cc006a200a290300370200200041d4006a2004290300370200200041dc006a2006290300370200200041e4006a2005290300370200200041ec006a20012903003702000c060b200541ff0171450d01200241003a0088010c010b200541ff0171450d00200241003a00a8010b200042023703000c030b20064104490d012004280001210620012003417b6a22053602042001200441056a36020020054108490d0120004201370300200429000521082001200341736a36020420012004410d6a360200200041106a200636020020002008370308200041146a200241e8006a41e40010a1051a0c020b200042023703000c010b200042023703000b200241f0016a24000b130020004107360204200041dcc2c3003602000b340020004196adc30036020420004100360200200041146a4109360200200041106a4198d9c300360200200041086a42093702000b910101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002404120102122060d001033000b20062002290300370000200042a0808080800437020420002006360200200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000200241206a24000b2d01017f02404104102122020d001033000b20004284808080c00037020420002002360200200241e8073600000b13002000410436020420004188e9c3003602000bcd0505067f017e047f017e027f23004180026b22022400024002400240024002402000280200220320002802044f0d00200028020c2104200141086a2105200241a0016a4102722106024003402000200341016a360200200241186a2000280208280200220710f60220022d00184101460d0120022900192108200241086a200710880120022802080d012007280204200228020c2203490d012003417f4c0d0302400240024020030d00410121090c010b200310272209450d0820072802042003490d0120092007280200200310a1051a2007280204220a2003490d062007200a20036b3602042007200728020020036a3602000b20022008370310024002402001280200220b450d002001280204210c0c010b2006410041da0010a0051a200241186a410041840110a0051a41e4011021220b450d074100210c200b4100360200200b41046a200241a0016a41dc0010a1051a200b41e0006a200241186a41840110a1051a200141003602042001200b3602000b2003ad220d422086200d84210d024002400340200b41086a2107200b2f0106220e41037421034100210a024003402003450d01200241106a2007410810a305220f450d03200341786a2103200a41016a210a200741086a2107200f417f4a0d000b200a417f6a210e0b0240200c450d00200c417f6a210c200b200e4102746a41e4016a280200210b0c010b0b2002200837022c200220053602282002200e360224200220013602202002200b36021c200241003602182002200d3702a401200220093602a001200241186a200241a0016a1080040c010b200b200a410c6c6a220341e4006a2207280200210a2007200d370200200341e0006a22072802002103200720093602002003450d00200a450d00200310230b200028020022032000280204490d010c030b0b200910230b200441013a00000b20024180026a24000f0b1032000b2003200a418ca9c0001044000b102a000b1033000bc91305027f017e067f037e0a7f230041b0036b2202240020002802102203200328020041016a36020020002902142104200028020c2105200028020821062000280200210320002802042100200241f0016a41086a2207200141086a280200360200200220012902003703f001024002400240024002400240024020002f01062201410b490d00200241d0026a410272410041da0010a0051a200241386a410041840110a0051a41e40110212208450d0420084100360200200841046a200241d0026a41dc0010a1051a200841e0006a200241386a41840110a1052107200241386a41086a2209200041b0016a280200360200200220002902a8013703382000413f6a2d0000210a200041386a350000210b2000413c6a330000210c2000413e6a310000210d200841086a200041c0006a20002f010641796a220141037410a105210e2007200041b4016a2001410c6c10a1052107200041063b0106200820013b0106200241d0026a41086a2009280200360200200220022903383703d002200b200c200d4210868442208684210b0240024020054107490d002005410374200e6a41506a200e200541796a22094103746a220e200141ffff037120096b41037410a2051a200e20043700002005410c6c20076a220541b87f6a200541ac7f6a2205200841066a22012f010020096b410c6c10a2051a200541086a200241f0016a41086a280200360200200520022903f0013702000c010b200041086a20054103746a220741086a2007200041066a22012f010020056b41037410a2051a20072004370000200041e0006a2005410c6c6a2207410c6a200720012f010020056b410c6c10a2051a200741086a200241f0016a41086a280200360200200720022903f0013702000b200120012f010041016a3b0100200241286a41086a220f200241d0026a41086a22102802002205360200200241086a221120053602002002200a3a0017200220022903d00222043703282002200b3e02102002200b4230883c00162002200b4220883d01142002200437030020022903102104200028020022090d01410021120c020b200020054103746a220341106a200341086a2203200120056b41037410a2051a2003200437000020002005410c6c6a220341ec006a200341e0006a220120002f010620056b410c6c10a2051a200341e8006a2007280200360200200120022903f001370200200020002f010641016a3b01060c020b20002f01042113200241d0026a41027221144100210002400340200220093602242002200341016a2212360220200f20112802003602002002200229030037032820032000470d01201341ffff0371210702400240024020092f01062203410b490d002014410041da0010a0051a200241f0016a200241d0026a41dc0010a1051a200241386a410041b40110a0051a41940210212201450d0720014100360200200141046a200241f0016a41dc0010a1051a200141e0006a200241386a41b40110a10521002009290038210b200241386a41086a220e200941b0016a280200360200200220092902a801370338200141086a200941c0006a20092f0106220541796a220341037410a10521152000200941b4016a2003410c6c10a1052116200141e4016a20094180026a2005417a6a220a41027410a1052117200941063b0106200120033b01060240200a450d00410021032017210003402000280200220520033b010420052001360200200041046a2100200a200341016a2203470d000b0b2010200e280200220336020020022002290338220c3703d002200e20033602002002200c370338201341ffff037122004107490d0120152007417a6a22004103746a2015200741796a22034103746a220520012f010620036b41037410a2051a200520043700002007410c6c20166a220541b87f6a200541ac7f6a220520012f0106220a20036b410c6c10a2051a200541086a200f280200360200200520022903283702002001200a41016a22053b01062007410274221320176a416c6a201720004102746a220a200541ffff0371220720006b41027410a2051a200a200836020020072000490d02200120136a41cc016a2100034020002802002205200341016a22033b010420052001360200200041046a210020032007490d000c030b0b200941086a2205200741016a22004103746a200520074103746a2205200320076b220141037410a2051a2005200437000020092007410c6c6a220541ec006a200541e0006a220a2001410c6c10a2051a200541e8006a200241286a41086a280200360200200a20022903283702002009200341016a22033b01062007410274200941e4016a22056a41086a200520004102746a2205200341ffff0371220120006b41027410a2051a20052008360200201341ffff037120014f0d0520092000417f6a22034102746a41e8016a2100034020002802002205200341016a22033b010420052009360200200041046a210020032001490d000c060b0b200941086a2203200741016a220a4103746a200320074103746a220320092f0106220520076b221341037410a2051a20032004370000200941e0006a2007410c6c6a2203410c6a20032013410c6c10a2051a200341086a200f280200360200200320022903283702002009200541016a22033b010620074102742217200941e4016a22056a41086a2005200a4102746a2213200341ffff03712205200a6b41027410a2051a20132008360200200020054f0d00200920176a41e8016a2103034020032802002200200741016a22073b010420002009360200200341046a210320052007470d000b0b200241106a41086a200e280200220336020020112003360200200220022903382204370310200220043703000240200928020022030d0020012108200b21040c030b20092f0104211320032109200b21042001210820122100201221030c000b0b41ecdbc4004135418c94c700102d000b200241d0026a410272410041da0010a0051a200241f0016a200241d0026a41dc0010a1051a200241386a410041b40110a0051a41940210212203450d0120034100360200200341046a200241f0016a41dc0010a1051a200341e0006a200241386a41b40110a10521052003200628020022003602e4012006200336020020062006280204220141016a360204200041003b010420002003360200200241386a41086a200241086a2802003602002002200229030037033820012012470d0220032f01062200410a4b0d0320052000410c6c6a22052002290338370200200320004103746a41086a2004370000200541086a200241386a41086a2802003602002003200041016a22004102746a41e4016a2008360200200320003b0106200820003b0104200820033602000b200241b0036a24000f0b102a000b4183dac4004130418c94c700102d000b41dcd9c4004127418c94c700102d000bb30301027f230041106b220224000240024020002d00004101460d00200241003a000e20012002410e6a4101106220002d0001220341094b0d010240024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a000f2002410f6a21000c090b200241013a000f2002410f6a21000c080b200241023a000f2002410f6a21000c070b200241033a000f2002410f6a21000c060b200241043a000f2002410f6a21000c050b200241053a000f2002410f6a21000c040b200241063a000f2002410f6a21000c030b200241073a000f20012002410f6a410110622002200041026a2d00003a000f2002410f6a21000c020b200241083a000f2002410f6a21000c010b200241093a000f2002410f6a21000b20012000410110620c010b200241013a000e20012002410e6a4101106220002d0001220341024b0d0002400240024020030e03000102000b200241003a000e20012002410e6a410110620c020b200241013a000e20012002410e6a410110620c010b200241023a000e20012002410e6a410110622002200041026a2d00003a000e20012002410e6a410110620b200241106a24000bbc0201057f024002400240200041046a2802002202200041086a28020022036b20012802042204200128020022056b22064f0d00200320066a22052003490d01200241017422042005200420054b1b22054100480d010240024020020d00024020050d00410121040c020b2005102122040d010c040b2000280200210420022005460d0020042002200510252204450d03200041086a28020021030b20002004360200200041046a200536020020012802002105200128020421040b024020052004460d00200028020021042001200541016a360200200420036a20052d00003a0000200341016a2103200128020022052001280204460d0003402001200541016a360200200420036a20052d00003a0000200341016a2103200128020022052001280204470d000b0b200041086a20033602000f0b102c000b102a000b9e06020a7f017e230041d0016b2202240041002103200241003a00c0012001280204417f6a2104024002400240024003402004417f460d01200241a0016a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c0012004417f6a21042005210320054120470d000b20024180016a41186a2204200241a0016a41186a220329030037030020024180016a41106a2205200241a0016a41106a220629030037030020024180016a41086a2207200241a0016a41086a2208290300370300200220022903a00137038001200241a0016a200110d00120022802c0012209450d01200241c0006a41186a220a2004290300370300200241c0006a41106a220b2005290300370300200241c0006a41086a22052007290300370300200241c0006a41286a22072008290300370300200241c0006a41306a22082006290300370300200241c0006a41386a220620032903003703002002200229038001370340200220022903a001370360200241c4016a2802002104200241a0016a41286a290300210c200241086a2005290300370300200241106a200b290300370300200241186a200a290300370300200241206a22032002290360370300200241286a22052007290300370300200241306a22072008290300370300200241386a2208200629030037030020022002290340370300200241c0006a200110cf012002280240450d02200241a0016a41086a2201200241c0006a41086a280200360200200220022903403703a001200041386a2008290300370300200041306a2007290300370300200041286a2005290300370300200041206a2003290300370300200041186a200241186a290300370300200041106a200241106a290300370300200041086a200241086a29030037030020002002290300370300200041c8006a200c3703002000200436024420002009360240200041d0006a20022903a001370300200041d8006a20012802003602000c030b200341ff0171450d00200241003a00c0010b200041003602400c010b200041003602402004450d00200441306c450d00200910230b200241d0016a24000bbb0504037f017e087f037e23004180016b220224002002200110880102400240024002402002280200450d00200041003602000c010b20022802042203200128020441286e2204200420034b1bad42287e2205422088a70d012005a72204417f4c0d010240024020040d00410821060c010b200410212206450d030b4100210720024100360210200220063602082002200441286e36020c0240024002402003450d0041002108034041002104200241003a0078200841016a210820012802042109417f210a034020092004460d03200241d8006a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a0078200a417f6a210a200c2104200c4120470d000b200241386a41186a2204200241d8006a41186a290300370300200241386a41106a220a200241d8006a41106a290300370300200241386a41086a220d200241d8006a41086a290300370300200220022903583703382009200c6b220c4108490d03200b29000121052001200b41096a3602002001200c41786a360204200241186a41086a220c200d290300370300200241186a41106a2209200a290300370300200241186a41186a220a20042903003703002002200229033837031802402007200228020c470d00200241086a2007410110980120022802082106200228021021070b2006200741286c6a22042002290318370300200c290300210e2009290300210f200a290300211020042005370320200441186a2010370300200441106a200f370300200441086a200e3703002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c020b200441ff0171450d00200241003a00780b20004100360200200228020c2204450d00200441286c450d00200610230b20024180016a24000f0b1032000b1033000bb70204027f017e027f037e230041106b220224000240024020012802082203ad42287e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510212206450d020b20024100360208200220063602002002200541286e3602042002410020031098012002280208210502402003450d00200341286c21062002280200200541286c6a21030340200141086a2903002104200141106a2903002107200141186a290300210820012903002109200341206a200141206a290300370300200341186a2008370300200341106a2007370300200341086a200437030020032009370300200341286a2103200541016a2105200141286a2101200641586a22060d000b0b20002002290300370200200041086a2005360200200241106a24000f0b1032000b1033000b8c0201037f024002400240024002400240024020012802000e0400010203000b41012102410110212201450d05200141003a0000410121030c040b410110212202450d04200241013a00002001280204210320024101410510252202450d042002200336000120012802082104410a210320024105410a10252201450d04200120043600050c020b41012102410110212201450d03200141023a0000410121030c020b410110212202450d02200241033a00002001280204210320024101410510252202450d022002200336000120012802082104410a210320024105410a10252201450d02200120043600050b410921020b2000200236020820002003360204200020013602000f0b102a000bd20402067f047e230041f0006b220224002002412036020420022001360200200241086a2001ad42808080808004841010108b0102400240200228020822030d00200041023a00000c010b200228020c210402400240200241106a2802002205450d0020032d0000220641014b0d004100210102400240024020060e020100010b41002101200241003a0068200341016a21072005417f6a2106034020062001460d02200241c8006a20016a200720016a2d00003a00002002200141016a22053a00682005210120054120470d000b200241186a41186a200241c8006a41186a290300370300200241186a41106a200241c8006a41106a290300370300200241186a41086a200241c8006a41086a29030037030020022002290348370318410121010b200241c8006a41186a200241186a41186a2903002208370300200241c8006a41106a200241186a41106a2903002209370300200241c8006a41086a200241186a41086a290300220a37030020022002290318220b370348200041196a2008370000200041116a2009370000200041096a200a3700002000200b3700010c020b200141ff0171450d00200241003a00680b20024100360220200242013703182002410a36023c200220023602382002200241186a360244200241dc006a41013602002002420137024c20024180c5c6003602482002200241386a360258200241c4006a4184a5c200200241c8006a10311a2002350220422086200235021884100a0240200228021c450d00200228021810230b410221010b200020013a00002004450d00200310230b200241f0006a24000bf90403027f017e057f230041d0006b2202240041a7b3c500ad4280808080c00084100c22032900002104200241086a200341086a290000370300200220043703002003102341b4bdc500ad4280808080900284100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000b8a06010c7f23004190016b220324002003200236021420032001360210200341186a2002ad4220862001ad841010108b010240024002400240200328021822040d00200041003602000c010b200328021c21052003200341206a28020036022c20032004360228200341086a200341286a1088010240024020032802080d00200328020c2206200328022c22074105762201200120064b1b22014105742202417f4c0d030240024020010d00410121080c010b200210212208450d050b41002109200341003602402003200136023c20032008360238024002402006450d004100210a03402007210b41002101200341003a008801200a41016a210a0340200b2001460d03200341e8006a20016a200328022822022d00003a00002003200241016a3602282003200141016a22023a0088012002210120024120470d000b200341c8006a41186a220c200341e8006a41186a290300370300200341c8006a41106a220d200341e8006a41106a290300370300200341c8006a41086a220e200341e8006a41086a2903003703002003200329036837034802402009200328023c470d00200341386a20094101109a0120032802382108200328024021090b200b20026b2107200820094105746a22012003290348370000200141186a200c290300370000200141106a200d290300370000200141086a200e2903003700002003200941016a2209360240200a2006470d000b2003200b20026b36022c0b2008450d012000200329023c370204200020083602000c020b2003410036022c0240200141ff0171450d00200341003a0088010b200328023c41ffffff3f71450d00200810230b20034100360250200342013703482003410a36023c2003200341106a3602382003200341c8006a360234200341fc006a41013602002003420137026c20034180c5c6003602682003200341386a360278200341346a4184a5c200200341e8006a10311a2003350250422086200335024884100a0240200328024c450d00200328024810230b200041003602000b2005450d00200410230b20034190016a24000f0b1032000b1033000bf90403027f017e057f230041d0006b22022400418df8c300ad4280808080900184100c22032900002104200241086a200341086a29000037030020022004370300200310234196f8c300ad4280808080e00084100c22032900002104200241106a41086a200341086a29000037030020022004370310200310232002200136022c20022002412c6aad4280808080c00084100d220329000037033020031023200241c4006a200241306a360200200241003a00482002200241306a41086a36023c20022002412c6a3602402002200241306a360238200241206a200241386a10650240024002400240024002402002280228220541206a2201417f4c0d0020022802202106024002402001450d00200110212203450d032001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1032000b1033000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000be50f04107f017e067f017e230041b0106b220224000240024002400240024020012802082203200128020c460d00200241d00d6a41c0026a2104200241c00a6a41046a2105200241ed0d6a2106200241c00a6a41b0026a2107200241c00a6a41c0026a210820024180086a41046a2109200241106a41086a210a200241900d6a410d6a220b41076a210c03402001200341d8026a3602082003280200210d200241206a200341046a41c00210a1051a200a200341d0026a2903003703002002200341c8026a290300370310200341c4026a28020022034102460d012001280210210e20024180086a200241206a41c00210a1051a200241d00d6a200941bc0210a1051a20042002290310370300200441086a200a2903003703002002200336028c10200241c00a6a200241d00d6a10c9022001200128021420022802c00a6a220f3602142005200941bc0210a1051a200241b0056a41086a2210200a290300370300200220022903103703b005200241c0056a200241c00a6a41c00210a1051a20024180086a200241c0056a41c00210a1051a200241c00a6a200941bc0210a1051a200841086a22112010290300370300200820022903b005370300200220033602fc0c02400240024020022d00880d41c000490d00200e450d00200f20012802182802004b0d010b200241d00d6a200241c00a6a10dc034100210e200241003b01a80d200241900d6a200241d00d6a200241a80d6a10cf02024020022802f00c2210450d0020022802f80c2203417f4c0d070240024020030d004101210e410021110c010b2003211120031021220e450d090b200241003602d40d200220113602d00d200e2010200310a1051a200220033602d40d20022903d00d21120b0240024020022802fc0c4101460d004101211020022802f00c450d01200241d00d6a2007109d0420023502d80d42208620022802d00d2203ad84101120022802d40d450d01200310230c010b20022802800d21030240024020022802840d221041014b0d00200241003602fc0c0c010b200241013602fc0c20022010417f6a3602840d0b200128021c28020020036a2113024020022802f00c450d00200241a0106a2013108a04200241a80d6a20023502a81042208620022802a0102214ad841010108b010240024020022802a80d22150d00200241003602d80d200242083703d00d200241d00d6a4100410010ab0120022802d80d41d0026c220341d0026d211620022802d40d211720022802d00d211802402003450d00201641d0026c21102018210303400240200341bc026a2802004102460d000240200341b0026a2802002211450d00200341b4026a280200450d00201110230b2003109e030b200341d0026a2103201041b07d6a22100d000b0b41002111024020170d00410021030c020b0240201741d0026c0d00410021030c020b2018102341002111410021030c010b20022802ac0d2110200220022802b00d3602d40d200220153602d00d200241086a200241d00d6a108801024002402002280208450d0041012111419ca8c70021160c010b200228020c2116410021110b410121032010450d00201510230b024020022802a410450d00201410230b02402015452003720d0020022802ac0d450d00201510230b200241d00d6a2007109d0420023502d80d211920022802d00d2110410810212203450d092003201336000020034100201620111b36000420194220862010ad842003ad4280808080800184100e2003102320022802d40d450d00201010230b200241d00d6a200241c00a6a41d00210a1051a2013200241d00d6a4101108c040240200228028c104102460d0002402002280280102203450d00200228028410450d00200310230b200241d00d6a10b4020b410021100b200128021c28020021112002200b2900003703d00d2002200c2800003600d70d0240024020022802900d4101460d00410421030c010b20022d009c0d211520022802940d2113200220022800d70d3600af0d200220022903d00d3703a80d4104210320134102460d00200220022800af0d3600d70d200220022903a80d3703d00d201521030b200220022903d00d3703a010200220022800d70d3600a710200620022903a010370000200641076a20022800a710360000200220033a00ec0d200220123702e40d2002200e3602e00d2002200d3602dc0d200220113602d80d200241013602d40d2002410d3a00d00d200241d00d6a10e0012001280220200f36020002402010450d00024020022802f00c2203450d0020022802f40c450d00200310230b200241c00a6a10b4020b410421100c010b200241d00d6a200241c00a6a41bc0210a1051a200241a80d6a41086a220e2011290300370300200220082903003703a80d4104211020034103460d00200241c00a6a200241d00d6a41bc0210a1051a20024180086a41086a200e290300370300200220022903a80d37038008200321100b2001200128021041016a360210200241f0026a200241c00a6a41bc0210a1051a200241e0026a41086a20024180086a41086a29030037030020022002290380083703e00220104104470d0220012802082203200128020c470d000b0b200041033602bc020c010b200241d00d6a200241f0026a41bc0210a1051a200241c00a6a41086a2203200241e0026a41086a290300370300200220022903e0023703c00a2000200241d00d6a41bc0210a105220120103602bc02200120022903c00a3703c002200141c8026a20032903003703000b200241b0106a24000f0b1032000b1033000bc21903027f017e087f23004190016b22032400418df8c300ad4280808080900184100c22042900002105200341c0006a41086a200441086a29000037030020032005370340200410234196f8c300ad4280808080e00084100c22042900002105200341d8006a41086a200441086a2900003703002003200537035820041023200320003602082003200341086aad4280808080c00084100d22042900003703182004102320034184016a2003410c6a360200200341003a0088012003200341186a41086a36027c2003200341086a360280012003200341186a360278200341286a200341f8006a106502400240024002402003280230220641206a2204417f4c0d00200328022821070240024002402004450d00200410212208450d042004410f4d0d01200421090c020b2004410174220a4110200a41104b1b2209102122080d010c050b2004410174220a4110200a41104b1b22094100480d0320042009460d0020082004200910252208450d040b20082003290340370000200841086a200341c0006a41086a2903003700000240024020094170714110460d002009210a0c010b2009410174220a4120200a41204b1b220a4100480d032009200a460d0020082009200a10252208450d040b20082003290358370010200841186a200341d8006a41086a29030037000002400240200a41606a2006490d00200a210b0c010b200641206a22092006490d03200a410174220b2009200b20094b1b220b4100480d03200a200b460d002008200a200b10252208450d040b200841206a2007200610a1051a0240200328022c450d00200710230b200341d8006a2004ad4220862008ad8422051010108b010240024020032802580d00410410212204450d032003420437027c200320043602784100200341f8006a1061200341106a200328028001360200200320032903783703080c010b200341086a41086a200341d8006a41086a280200360200200320032903583703080b200341186a41086a200341086a41086a2802002204360200200320032903083703182001200241d0026c6a210a02400240024002400240024002402004450d00200341f8006a200328021820042002107520032802784101470d01200328021c450d04200328021810230c040b2002200341186a1061200a2001460d01200241d0026c210920012104034002400240200441bc026a2802004102470d0002400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d0c200a41017422072006200720064b1b22074100480d0c02400240200a0d004100210a024020070d00410121060c020b200710212206450d0f0c010b20032802182106200a2007460d002006200a200710252206450d0e2003280220210a0b2003200736021c200320063602180b2006200a6a41003a00002003200a41016a3602200c010b02400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d0b200a41017422072006200720064b1b22074100480d0b02400240200a0d004100210a024020070d00410121060c020b200710212206450d0e0c010b20032802182106200a2007460d002006200a200710252206450d0d2003280220210a0b2003200736021c200320063602180b2006200a6a41013a00002003200a41016a3602202004200341186a108d040b200441d0026a2104200941b07d6a22090d000c020b0b200328027c21070240024002400240024020034184016a2802002204200341f8006a41086a2802002209460d002003280220200420096b6a220620024102746a220c417f4c0d0a02400240200c0d004101210d0c010b200c1021220d450d0c0b2003200c36022c2003200d360228200320063602302003200341286a3602782007200341f8006a200410b20320062004490d01200328023022072006490d02200328022022072009490d032003280228210c2003280218210d2003200620046b22063602382003200720096b220736023c20062007470d04200c20046a200d20096a200610a1051a0240200a2001460d00200241d0026c210920012104034002400240200441bc026a2802004102470d0002400240200328022c2003280230220a460d00200328022821060c010b200a41016a2206200a490d11200a41017422072006200720064b1b22074100480d1102400240200a0d004100210a024020070d00410121060c020b200710212206450d140c010b20032802282106200a2007460d002006200a200710252206450d132003280230210a0b2003200736022c200320063602280b2006200a6a41003a00002003200a41016a3602300c010b02400240200328022c2003280230220a460d00200328022821060c010b200a41016a2206200a490d10200a41017422072006200720064b1b22074100480d1002400240200a0d004100210a024020070d00410121060c020b200710212206450d130c010b20032802282106200a2007460d002006200a200710252206450d122003280230210a0b2003200736022c200320063602280b2006200a6a41013a00002003200a41016a3602302004200341286a108d040b200441d0026a2104200941b07d6a22090d000b0b2003280230210a200328022c210920032802282104200328021c450d06200328021810230c060b2003200341186a3602782007200341f8006a200910b203200a2001460d04200241d0026c210920012104034002400240200441bc026a2802004102470d0002400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d0f200a41017422072006200720064b1b22074100480d0f02400240200a0d004100210a024020070d00410121060c020b200710212206450d120c010b20032802182106200a2007460d002006200a200710252206450d112003280220210a0b2003200736021c200320063602180b2006200a6a41003a00002003200a41016a3602200c010b02400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d0e200a41017422072006200720064b1b22074100480d0e02400240200a0d004100210a024020070d00410121060c020b200710212206450d110c010b20032802182106200a2007460d002006200a200710252206450d102003280220210a0b2003200736021c200320063602180b2006200a6a41013a00002003200a41016a3602202004200341186a108d040b200441d0026a2104200941b07d6a2209450d050c000b0b2004200641c494c6001044000b2006200741c494c6001043000b2009200741d494c6001044000b200341d8006a41146a410b360200200341e4006a410d360200200341c0006a41146a41033602002003200341386a36027020032003413c6a360274200341f8006a41146a4100360200200342033702442003418ca7c7003602402003410d36025c2003419ca8c700360288012003420137027c200341e0a7c7003602782003200341d8006a3602502003200341f8006a3602682003200341f4006a3602602003200341f0006a360258200341c0006a419ca8c700103a000b2003280220210a200328021c2109200328021821040b02402004450d002005200aad4220862004ad84100e02402009450d00200410230b200b450d03200810230c030b200b450d010b200810230b200341d8006a2000108a04200241d0026c4104722204417f4c0d01200335026021052003280258210820041021220a450d0220034100360280012003200436027c2003200a3602782002200341f8006a106102402002450d00200241d0026c210a034002400240200141bc026a2802004102470d0002400240200328027c2003280280012204460d00200328027821090c010b200441016a22092004490d08200441017422062009200620094b1b22064100480d080240024020040d0041002104024020060d00410121090c020b200610212209450d0b0c010b2003280278210920042006460d0020092004200610252209450d0a20032802800121040b2003200636027c200320093602780b200920046a41003a00002003200441016a360280010c010b02400240200328027c2003280280012204460d00200328027821090c010b200441016a22092004490d07200441017422062009200620094b1b22064100480d070240024020040d0041002104024020060d00410121090c020b200610212209450d0a0c010b2003280278210920042006460d0020092004200610252209450d0920032802800121040b2003200636027c200320093602780b200920046a41013a00002003200441016a360280012001200341f8006a108d040b200141d0026a2101200a41b07d6a220a0d000b0b200328027c210120054220862008ad8420033502800142208620032802782204ad84100e02402001450d00200410230b200328025c450d00200810230b20034190016a24000f0b1032000b1033000b102c000b102a000bec0101037f230041106b220224000240024020002802b00222030d00200241003a00072001200241076a41011062200241076a21030c010b200241013a00072001200241076a41011062200041b8026a2802002204200110612001200320041062200241076a21030b200220002d00c8023a000720012003410110622000200110dd020240024020002802bc024101460d00200241003a000720012003410110620c010b200241013a000720012003410110622002200041c0026a2802003602082001200241086a410410622002200041c4026a28020036020c20012002410c6a410410620b200241106a24000b1300200041013602042000419cf8c3003602000b3400200041ecf7c30036020420004100360200200041146a4106360200200041106a4188f9c300360200200041086a420f3702000b2c01017f02404108102122020d001033000b20004288808080800137020420002002360200200242003700000b2201017f230041106b220224002002410036020020002002108604200241106a24000b130020004109360204200041c882c4003602000b3400200041aeb9c40036020420004100360200200041146a4103360200200041106a41b8b9c400360200200041086a42083702000b8d0503027f017e067f230041e0006b2202240041ecf7c300ad4280808080f00184100c22032900002104200241086a41086a200341086a290000370300200220043703082003102341f0fec300ad4280808080c00184100c22032900002104200241186a41086a200341086a2900003703002002200437031820031023200220003703382002200241386aad4280808080800184100d220329000037034020031023200241d4006a200241386a41086a360200200241003a00582002200241c0006a41086a36024c2002200241386a3602502002200241c0006a360248200241286a200241c8006a10650240024002400240024002402002280230220541206a2206417f4c0d0020022802282107024002402006450d00200610212203450d032006410f4d0d01200621080c050b200641017422034110200341104b1b2208102122030d040c060b200641017422084110200841104b1b220841004e0d020c040b1032000b1033000b20062008460d0020032006200810252203450d020b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821090c010b200841017422094120200941204b1b22094100480d0120082009460d0020032008200910252203450d020b20032002290318370010200341186a200241186a41086a2903003700000240200941606a20054f0d00200541206a22082005490d012009410174220a2008200a20084b1b22084100480d0120092008460d0020032009200810252203450d020b200341206a2007200510a1051a0240200228022c450d00200710230b200220013602482006ad4220862003ad84200241c8006aad4280808080c00084100e20031023200241e0006a24000f0b102c000b102a000be91305057f017e047f027e037f230041f0006b22052400200541c0006a41186a22064200370300200541c0006a41106a22074200370300200541c0006a41086a220842003703002005420037034041ecf7c300ad4280808080f00184100c2209290000210a200541e0006a41086a220b200941086a2900003703002005200a370360200910232008200b2903003703002005200529036037034041fbf7c300ad4280808080d00184100c2209290000210a200b200941086a2900003703002005200a3703602009102320072005290360220a370300200541206a41086a22092008290300370300200541206a41106a220c200a370300200541206a41186a220d200b29030037030020052005290340370320200541186a200541206a4120419ca8c70041004100108c01024002400240024002400240024020052802184101470d00410d210b41b8ebc3002108410221070c010b2006420037030020074200370300200842003703002005420037034041e4dec400ad4280808080e00084100c2206290000210a2008200641086a2900003703002005200a3703402006102341f3dec400ad4280808080e00084100c2206290000210a200b200641086a2900003703002005200a3703602006102320072005290360220a37030020092008290300370300200c200a370300200d200b29030037030020052005290340370320200541106a200541206a412010cd012005280214410020052802101b2109024020034101460d00200541206a210e0c030b200541c0006a41186a22064200370300200541c0006a41106a220c4200370300200541c0006a41086a220842003703002005420037034041ecf7c300ad4280808080f00184220f100c220d290000210a200541e0006a41086a220b200d41086a2900003703002005200a370360200d10232008200b2903003703002005200529036037034041f8fdc300ad4280808080a001842210100c220d290000210a200b200d41086a2900003703002005200a370360200d102320072005290360370000200741086a220d200b290300370000200541206a41086a220e2008290300370300200541206a41106a2211200c290300370300200541206a41186a2212200629030037030020052005290340370320200541086a200541206a412010cd012005280208450d01200528020c20094d0d014107210b41b1ebc3002108410321070b200041831a3b0100200041086a200b360200200041046a2008360200200041026a20073a0000200141046a280200220b450d02200b41286c450d02200128020010230c020b20064200370300200c42003703002008420037030020054200370340200f100c2213290000210a200b201341086a2900003703002005200a370360201310232008200b290300370300200520052903603703402010100c2213290000210a200b201341086a2900003703002005200a3703602013102320072005290360370000200d200b290300370000200e20082903003703002011200c29030037030020122006290300370300200520052903403703202005200920024101746a360240200541206aad4280808080800484200541c0006aad4280808080c00084100e200541206a210e0b200128020821082001280204210c2001280200210d200541c0006a41186a22114200370300200541c0006a41106a22124200370300200541c0006a41086a220142003703002005420037034041ecf7c300ad4280808080f00184100c2206290000210a200541e0006a41086a220b200641086a2900003703002005200a370360200610232001200b2903003703002005200529036037034041fbf7c300ad4280808080d00184100c2206290000210a200b200641086a2900003703002005200a3703602006102320072005290360370000200741086a200b290300370000200541206a41086a2001290300370300200541206a41106a2012290300370300200541206a41186a201129030037030020052005290340370320200541003602482005420137034041041021220b450d02200541043602442005200b360240200b200936000020054104360248200b410441081025220b450d0220054108360244200b20023600042005200b360240200541083602482008200541c0006a10612005280248210702402008450d00200d200841286c6a2106200d210b0340024002402005280244220220076b4120490d00200741206a210820052802402101200221090c010b200741206a22082007490d04200241017422012008200120084b1b22094100480d040240024020020d00024020090d00410121010c020b2009102122010d010c070b2005280240210120022009460d0020012002200910252201450d060b20052009360244200520013602400b200120076a2207200b290000370000200741186a200b41186a290000370000200741106a200b41106a290000370000200741086a200b41086a29000037000020052008360248200b41206a290300210a0240200920086b41074b0d00200841086a22072008490d04200941017422022007200220074b1b22074100480d040240024020090d00024020070d00410121010c020b200710212201450d070c010b20092007460d0020012009200710252201450d060b20052007360244200520013602400b200120086a200a3700002005200841086a22073602482006200b41286a220b470d000b0b2005280244210b0240024020034101460d0002400240200b2007460d00200528024021080c010b200741016a220b2007490d0420074101742208200b2008200b4b1b220b4100480d040240024020070d00410021070240200b0d00410121080c020b200b10212208450d070c010b200528024021082007200b460d0020082007200b10252208450d060b2005200b360244200520083602400b200820076a41003a00002005200741016a22073602480c010b02400240200b2007460d00200528024021080c010b200741016a220b2007490d0320074101742208200b2008200b4b1b220b4100480d030240024020070d00410021070240200b0d00410121080c020b200b10212208450d060c010b200528024021082007200b460d0020082007200b10252208450d050b2005200b360244200520083602400b200820076a41013a00002005200741016a22013602480240200b20016b41034b0d00200141046a22092001490d03200b41017422022009200220094b1b22094100480d0302400240200b0d00024020090d00410121080c020b200910212208450d060c010b200b2009460d002008200b200910252208450d050b20052009360244200520083602400b200820016a20043600002005200741056a22073602482005280244210b200528024021080b200ead42808080808004842007ad4220862008ad84100e0240200b450d00200810230b0240200c450d00200c41286c450d00200d10230b200041043a00000b200541f0006a24000f0b102c000b102a000baa0704057f017e0a7f027e23004180016b22032400200341306a2001200228020c220411020002400240024002402003280230450d00200341d8006a41106a200341306a41106a290300370300200341d8006a41086a200341306a41086a290300370300200341d8006a41186a200341306a41186a290300370300200341d8006a41206a200341306a41206a280200360200200341106a41086a200341e4006a290200370300200341106a41106a200341ec006a290200370300200341106a41186a200341f4006a290200370300200320032903303703582003200329025c370310200341d8006a200120022802102205110200417f2003280258220641016a220720072006491bad42287e2208422088a70d022008a72206417f4c0d02200610212209450d032009200329031037030020094201370320200941186a200341106a41186a220a290300370300200941106a200341106a41106a220b290300370300200941086a200341106a41086a220c29030037030020034101360208200320093602002003200641286e2207360204200341306a2001200411020002402003280230450d00200341d8006a41047221064102210d41c800210e0340200341d8006a41206a200341306a41206a280200360200200341d8006a41186a220f200341306a41186a290300370300200341d8006a41106a2210200341306a41106a290300370300200341d8006a41086a2211200341306a41086a29030037030020032003290330370358200c200641086a290200370300200b200641106a290200370300200a200641186a29020037030020032006290200370310200f200a2903003703002010200b2903003703002011200c290300370300200320032903103703580240200d417f6a2007470d00200341306a2001200511020020032007417f2003280230221241016a220920092012491b109801200328020021090b2009200e6a221241606a220720032903583703002011290300210820102903002113200f290300211420124201370300200741186a2014370300200741106a2013370300200741086a20083703002003200d360208200341306a200120041102002003280230450d01200e41286a210e200d41016a210d200328020421070c000b0b2001200228020011040002402002280204450d00200110230b20002003290300370200200041086a200341086a2802003602000c010b2000410036020820004208370200200120022802001104002002280204450d00200110230b20034180016a24000f0b1032000b1033000bd60302057f047e230041f0006b220224002002412036020c20022001360208200241106a2001ad42808080808004841010108b0102400240200228021022030d00200041003a00000c010b200241186a28020021042002280214210541002101200241003a006802400240034020042001460d01200241c8006a20016a200320016a2d00003a00002002200141016a22063a00682006210120064120470d000b200241206a41186a200241c8006a41186a2903002207370300200241206a41106a200241c8006a41106a2903002208370300200241206a41086a200241c8006a41086a290300220937030020022002290348220a370320200041196a2007370000200041116a2008370000200041096a20093700002000200a370001410121010c010b0240200141ff0171450d00200241003a00680b4100210120024100360228200242013703202002410a3602442002200241086a3602402002200241206a36026c200241dc006a41013602002002420137024c20024180c5c6003602482002200241c0006a360258200241ec006a4184a5c200200241c8006a10311a2002350228422086200235022084100a2002280224450d00200228022010230b200020013a00002005450d00200310230b200241f0006a24000b290020004101360204200041086a200128020420012802006b41c0016e2201360200200020013602000bf40101047f230041d0006b21020240200128020022032001280204470d00200041003602000f0b2001200341c0016a3602002002200341c2006a29000037012a2002200341ca006a290000370132200241106a220120022903303703002002200341d2006a29000037013a200241186a220420022903383703002002200341da006a2800003601422002200341de006a2f00003b0146200241206a220520022903403703002002200341c0006a2f00003b01282002200229032837030820002003360200200020022903083700042000410c6a2001290300370000200041146a20042903003700002000411c6a20052903003700000bf30801087f230041f0006b2103024002402001280200220420012802042205460d00200241016a210603402001200441c0016a2202360200200341003a0068200441c0006a2d00002107200341013a0068200320073a0048200441c1006a2d00002107200341023a0068200320073a0049200441c2006a2d00002107200341033a0068200320073a004a200441c3006a2d00002107200341043a0068200320073a004b200441c4006a2d00002107200341053a0068200320073a004c200441c5006a2d00002107200341063a0068200320073a004d200441c6006a2d00002107200341073a0068200320073a004e2003200441c7006a2d00003a004f200341083a0068200441c8006a2d00002107200341093a0068200320073a0050200441c9006a2d000021072003410a3a0068200320073a0051200441ca006a2d000021072003410b3a0068200320073a0052200441cb006a2d000021072003410c3a0068200320073a0053200441cc006a2d000021072003410d3a0068200320073a0054200441cd006a2d000021072003410e3a0068200320073a0055200441ce006a2d000021072003410f3a0068200320073a00562003200441cf006a2d00003a0057200341103a0068200441d0006a2d00002107200341113a0068200320073a0058200441d1006a2d00002107200341123a0068200320073a0059200441d2006a2d00002107200341133a0068200320073a005a200441d3006a2d00002107200341143a0068200320073a005b200441d4006a2d00002107200341153a0068200320073a005c200441d5006a2d00002107200341163a0068200320073a005d200441d6006a2d00002107200341173a0068200320073a005e2003200441d7006a2d00003a005f200341183a0068200441d8006a2d00002107200341193a0068200320073a0060200441d9006a2d000021072003411a3a0068200320073a0061200441da006a2d000021072003411b3a0068200320073a0062200441db006a2d000021072003411c3a0068200320073a0063200441dc006a2d000021072003411d3a0068200320073a0064200441dd006a2d000021072003411e3a0068200320073a0065200441de006a2d000021072003411f3a0068200320073a0066200441df006a2d00002107200341203a0068200320073a0067200341286a41086a22072003290350370300200341286a41106a22082003290358370300200341286a41186a2209200329036037030020032003290348370328200341086a41086a220a2007290300370300200341086a41106a22072008290300370300200341086a41186a2208200929030037030020032003290328370308200341c8006a41186a2008290300370300200341c8006a41106a2007290300370300200341c8006a41086a200a290300370300200320032903083703482006417f6a2206450d022002210420052002470d000b0b200041003602000f0b20002004360200200020032903483702042000410c6a200341d0006a290300370200200041146a200341d8006a2903003702002000411c6a200341e0006a2903003702000b34002000418df8c30036020420004100360200200041146a4102360200200041106a4194c2c400360200200041086a42093702000bc40201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff01832001103e21000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d02200141a889c0004102200220006a4180016a410020006b104121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d02200141a889c0004102200220006a4180016a410020006b104121000b20024180016a240020000f0b2004418001419889c0001044000b2004418001419889c0001044000ba20403027f017e057f230041306b22022400418df8c300ad4280808080900184100c22032900002104200241086a200341086a29000037030020022004370300200310234198c4c400ad4280808080e00084100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023200241206a20012802002001280208109e040240024002400240024002402002280228220541206a2203417f4c0d0020022802202106024002402003450d00200310212201450d032003410f4d0d01200321070c050b200341017422014110200141104b1b2207102122010d040c060b200341017422084110200841104b1b220741004e0d020c040b1032000b1033000b20032007460d0020012003200710252201450d020b20012002290300370000200141086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020012007200810252201450d020b20012002290310370010200141186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b200541206a22072005490d01200841017422092007200920074b1b22074100480d0120082007460d0020012008200710252201450d020b200141206a2006200510a1051a20002003360208200020073602042000200136020002402002280224450d00200610230b200241306a24000f0b102c000b102a000bf00201057f230041206b220324000240024002400240200241046a2204417f4c0d000240024020040d00410121050c010b200410212205450d020b200341003602102003200436020c200320053602082002200341086a106102400240200328020c2206200328021022056b2002490d0020032802082104200621070c010b200520026a22042005490d03200641017422072004200720044b1b22074100480d030240024020060d00024020070d00410121040c020b2007102122040d010c060b2003280208210420062007460d0020042006200710252204450d050b2003200736020c200320043602080b200420056a2001200210a1051a2003200520026a2202ad4220862004ad84100d220529000037030020051023200341146a200420026a360200200341003a0018200320043602102003200341086a36020c200320033602082000200341086a106502402007450d00200410230b200341206a24000f0b1032000b1033000b102c000b102a000b88090b107f017e017f017e017f017e017f017e017f017e017f230041306b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200241286a22082000200441306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e2903003703002013201029030037030020052002290300370300024020032001490d00200321040c030b2006410d7420067322044111762004732204410574200473220620077122044100200120042001491b6b220520014f0d01200241286a22082000200341306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e29030037030020132010290300370300200520022903003703002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200241286a22032000200441306c6a220141286a2204290300370300200241206a2206200141206a2207290300370300200241186a2208200141186a2209290300370300200241106a220a200141106a220b290300370300200241086a220c200141086a220d290300370300200220012903003703002000200541306c6a22002903002112200041086a22052903002114200041106a220e2903002116200041186a220f2903002118200041206a2210290300211a2004200041286a22112903003703002007201a37030020092018370300200b2016370300200d2014370300200120123703002011200329030037030020102006290300370300200f2008290300370300200e200a2903003703002005200c290300370300200020022903003703000b200241306a24000f0b2005200141f8c5c4001030000b200420014184d9c4001030000bf20907077f027e0b7f017e017f027e017f230041306b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d02200520062000200641306c6a22072903002000200541306c6a220829030056200741086a2903002209200841086a290300220a562009200a511b1b21060b200620014f0d03200420014f0d022000200441306c6a22042903002000200641306c6a220529030056200441086a22072903002209200541086a2208290300220a562009200a511b450d03200241286a220b200441286a220c290300370300200241206a220d200441206a220e290300370300200241186a220f200441186a2210290300370300200241106a2211200441106a2212290300370300200241086a221320072903003703002002200429030037030020082903002109200541106a2214290300210a200541186a22152903002116200541206a2217290300211820052903002119200c200541286a221a290300370300200e2018370300201020163703002012200a3703002007200937030020042019370300201a200b2903003703002017200d2903003703002015200f290300370300201420112903003703002008201329030037030020052002290300370300200621040c000b0b2006200141a8c7c4001030000b2004200141b8c7c4001030000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241286a220b200041286a2205290300370300200241206a220c200041206a2206290300370300200241186a220d200041186a2208290300370300200241106a220e200041106a2210290300370300200241086a220f200041086a2211290300370300200220002903003703002000200741306c6a22042903002109200441086a290300210a200441106a2903002116200441186a2903002118200441206a29030021192005200441286a2903003703002006201937030020082018370300201020163703002011200a3703002000200937030041002105024002400240034020042002290300370300200441286a200b290300370300200441206a200c290300370300200441186a200d290300370300200441106a200e290300370300200441086a200f2903003703002005410174220441017221060240200441026a220420074f0d00200620074f0d02200420062000200641306c6a22082903002000200441306c6a221029030056200841086a2903002209201041086a290300220a562009200a511b1b21060b200620074f0d03200520074f0d022000200541306c6a22052903002000200641306c6a220429030056200541086a22082903002209200441086a2210290300220a562009200a511b450d03200b200541286a2211290300370300200c200541206a2212290300370300200d200541186a2213290300370300200e200541106a2214290300370300200f20082903003703002002200529030037030020102903002109200441106a290300210a200441186a2903002116200441206a2903002118200429030021192011200441286a29030037030020122018370300201320163703002014200a3703002008200937030020052019370300200621050c000b0b2006200741a8c7c4001030000b2005200741b8c7c4001030000b200741014b0d000b0b200241306a24000f0b2007200141f8c5c4001030000bb80c050a7f017e017f037e0f7f230041306b22022400200041c07e6a21032001417f6a2104200041306a2105410021062001413249210741012108024003400240024020082001490d00410021090c010b410121092000200841306c220a6a220b290300220c200b41506a220d29030056200b41086a290300220e200d41086a290300220f56200e200f511b0d002005200a6a210903404101210b20042008460d03200841016a210820092903002210200c58210b200941086a290300220f200e51210d200f200e58210a200941306a21092010210c200f210e200b200a200d1b0d000b200820014921090b2008200146210b20070d0120082001460d010240024002400240024002402008417f6a220b20014f0d002009450d012000200b41306c6a2209290300210e20092000200841306c22116a220b290300370300200241286a220a200941286a2212290300370300200241206a2213200941206a2214290300370300200241186a2215200941186a2216290300370300200241106a2217200941106a2218290300370300200241086a2219200941086a220d290300370300200d200b41086a221a2903003703002018200b41106a221b2903003703002016200b41186a221c2903003703002014200b41206a221d2903003703002012200b41286a221e2903003703002002200e370300200b2002290300370300201e200a290300370300201d2013290300370300201c2015290300370300201b2017290300370300201a201929030037030020084102490d052009290300220c20002008417e6a221341306c6a220a29030058200d290300220e200a41086a221f290300220f58200e200f511b0d052009200a290300370300200d201f2903003703002009290310210f2018200a41106a2903003703002015201229030037030020172014290300370300201920162903003703002016200a41186a2903003703002014200a41206a2903003703002012200a41286a2903003703002002200f370300024020130d00410021130c050b200c20002008417d6a220d41306c6a220929030058200e200941086a290300220f58200e200f511b0d04200320116a2109034020094188016a200941d8006a29030037030020094180016a200941d0006a290300370300200941f8006a200941c8006a290300370300200941f0006a200941c0006a290300370300200941e8006a200941386a290300370300200941e0006a200941306a290300370300200d450d032009290300210f200941086a210a200941506a2109200d417f6a210d200c200f56200e200a290300220f56200e200f511b0d000b200d41016a21130c030b200b20014184d9c4001030000b2008200141f8c5c4001030000b410021130b2000201341306c6a210a0b200a200c370300200a200e3703082000201341306c6a22092002290300370310200941286a2015290300370300200941206a2017290300370300200941186a20192903003703000b200641016a21060240200120086b22144102490d00200b290330200b290300220c58200b41386a290300220f201a290300220e58200f200e511b0d00200b200b41306a2212290300370300201a201241086a290300370300200b290310210f201b201241106a2903003703002015201e2903003703002017201d2903003703002019201c290300370300201c201241186a290300370300201d201241206a290300370300201e201241286a2903003703002002200f3703004101211a024020144103490d00200b290360200c58200b41e8006a290300220f200e58200f200e511b0d00200b41e0006a21094103210a4102210d0340200d221a41306c200b6a221241506a220d2009290300370300200d41286a200941286a290300370300200d41206a200941206a290300370300200d41186a200941186a290300370300200d41106a200941106a290300370300200d41086a200941086a290300370300200a20144f0d01200a41306c2109200a210d200a41016a210a200b20096a2209290300200c56200941086a290300220f200e56200f200e511b0d000b0b2012200c3703002012200e370308200b201a41306c6a22092002290300370310200941286a2015290300370300200941206a2017290300370300200941186a20192903003703000b20064105470d000b4100210b0b200241306a2400200b0b8f0201027f20014180feff07714108762102024002402001410171450d00411f210341e5bac000210102400240200241ff01710e03000103000b41c100210341a4bac00021010c020b41c100210341e3b9c00021010c010b411f210341c4b9c0002101024002400240024002400240024002400240200241ff01710e0a00060102030405090708000b4120210341a4b9c00021010c080b4127210341c4b8c00021010c070b4117210341adb8c00021010c060b418eb8c00021010c050b4126210341e8b7c00021010c040b412b210341bdb7c00021010c030b4139210341ebb8c00021010c020b413b21034182b7c00021010c010b41d100210341b1b6c00021010b20002003360204200020013602000bfd0303037f027e047f230041106b220224002002410036020820024201370300200028021021030240410410212204450d0020024104360204200220043602002004200336000020024104360208200041086a29030021052000290300210620044104411410252204450d00200420063700042004410c6a200537000020024294808080c00237020420022004360200200028021421072000411c6a2802002200200210610240024020000d002002280208210320022802042108200228020021090c010b2000410574210a200228020021092002280204210820022802082103034020072100024002402008200322046b4120490d00200441206a21030c010b024002400240200441206a22032004490d00200841017422072003200720034b1b22074100480d000240024020080d00024020070d00410121090c020b2007102121090c040b20082007470d020b200721080c030b102c000b200920082007102521090b200721082009450d030b200041206a2107200920046a22042000290000370000200441186a200041186a290000370000200441106a200041106a290000370000200441086a200041086a290000370000200a41606a220a0d000b2002200836020420022003360208200220093602000b20012902002003ad4220862009ad84100e02402008450d00200910230b200241106a24000f0b102a000bfa0101067f23004180016b220224002001410c6a2802002103200141086a280200210420012802002205210602402005410471450d0020012005410872220636020020040d00200141086a4281808080a0013702000b2001200641047236020020002802002100410021060340200220066a41ff006a2000410f712207413072200741d7006a2007410a491b3a00002006417f6a2106200041047622000d000b024020064180016a2200418101490d002000418001419889c0001044000b200141a889c0004102200220066a4180016a410020066b104121062001200336020c200141086a20043602002001200536020020024180016a240020060bbd1103077f017e0e7f230041e0076b2203240041002104200341003602a803200320023602a403200320013602a0034101210541012106024002400240024002400240024002400240024002400240024002400240024002400240024002402002450d0041012107200341013602a803024020012d000022080d000c020b0240024002400240024002400240024002400240024002400240200841c00171220741c001460d0002402007418001460d0041012106200741c000470d0e410121072008413f712204413f470d0541022107414121044101210603402007417f6a20024f0d0f200320073602a803200120076a417f6a2d0000220841ff01470d05200441817e6a2104200741016a2207418302470d000b2007417f6a210741ffff032104410121090c0c0b4200210a410121072008413f712204413f470d0641022107414121044101210603402007417f6a20024f0d0e200320073602a803200120076a417f6a2d0000220841ff01470d06200441817e6a2104200741016a2207418302470d000b2007417f6a21074200210a0c010b428002210a410121072008413f712204413f470d0541022107414121044101210603402007417f6a20024f0d0d200320073602a803200120076a417f6a2d0000220841ff01470d02200441817e6a2104200741016a2207418302470d000b2007417f6a2107428002210a0b200a50210841ffff032104410121090c050b200820046b21040c030b200820046b21040b200441017122090d060c070b200820046b21040b200a50210820044101712209450d010b200720024f0d0141002106200120076a2d000041104f0d050b410121062007200441016a4101766a220b20024b0d042003200b3602a803200b41026a220420024b0d04200320043602a803200b417e4f0d012001200b6a2f0000210c410021044100210d024020080d00200341106a200341a0036a10a40320032802100d0520032802a803220e20032802146a220f20032802a4034b0d052003200f3602a8034101210d0b200341023602f402200341023602e802200341023602dc02200341023602d002200341023602c402200341023602b802200341023602ac02200341023602a00220034102360294022003410236028802200341023602fc01200341023602f001200341023602e401200341023602d801200341023602cc01200341023602c001200341c0016a210603400240200c41012004410f71747141ffff0371450d00200341086a200341a0036a10a4030240024020032802080d0020032802a8032210200328020c22116a220820032802a4034d0d010b410121060c070b200320083602a803200641086a2008360200200641046a2010360200200620114120473602000b2006410c6a2106200441016a22044110470d000b200341a0066a200341c0016a41c00110a1051a410421040c050b2007200241d4c9c40010300c060b200b200441b4c9c4001044000b200720024f0d0341002106200120076a2d000041104f0d010b410121062007200441016a4101766a220b20024b0d002003200b3602a8032003200341a0036a10a40320032802000d0020032802a803220d20032802046a220e20032802a4034b0d002003200e3602a803200341a0066a200341c0016a41c00110a1051a410121040c010b200341a0036a200341a0066a41c00110a1051a200020063a00010c0e0b200341a0036a200341a0066a41c00110a1051a200341c0016a41186a200f360200200341c0016a41146a200e360200200341c0016a41106a200d360200200341c0016a410c6a2009360200200341c0016a41086a200b360200200320073602c401200320043602c001200341c0016a411c6a200341a0036a41c00110a1052112410021054100211320040e050c020101030c0b2007200241c4c9c4001030000b000b200b2007490d01200b20024b0d02200e200d490d03200e20024b0d04200b20076b2114200120076a21152001200d6a2116200e200d6b2117410121130c090b200341023602d407200341023602c807200341023602bc07200341023602b007200341023602a40720034102360298072003410236028c072003410236028007200341023602f406200341023602e806200341023602dc06200341023602d006200341023602c406200341023602b806200341023602ac06200341023602a006410021060340410221080240201220066a2204280200410246220c0d0041002004200c1b220841086a2802002104200841046a28020021100240024020082802004101470d0020042010490d0841012108200420024d0d012004200241d8bcc0001043000b20042010490d0841002108200420024b0d090b200420106b2111200120106a21100b200341a0066a20066a22042008360200200441086a2011360200200441046a20103602002006410c6a220641c001460d080c000b0b2007200b41d0bdc0001044000b200b200241d0bdc0001043000b200d200e41e0bdc0001044000b200e200241e0bdc0001043000b2010200441d8bcc0001044000b2010200441e8bcc0001044000b2004200241e8bcc0001043000b02400240200d4101460d00410021080c010b200f200e490d03200f20024b0d04200f200e6b21062001200e6a21080b200b2007490d04200b20024b0d05200341a8066a280200211820032802a406211720032802a0062116200341186a200341ac066a41a80110a1051a200b20076b2114200120076a2115200341dc076a2802002110200341d8076a280200211120032802d407210c410421130b2000411c6a2018360200200041186a2017360200200041146a2016360200200041106a20093602002000410c6a2014360200200041086a2015360200200041046a2013360200200041206a200341186a41a80110a1051a200041d8016a2006360200200041d4016a2008360200200041d0016a2010360200200041cc016a2011360200200041c8016a200c3602000b200020053a0000200341e0076a24000f0b200e200f41f0bdc0001044000b200f200241f0bdc0001043000b2007200b41d0bdc0001044000b200b200241d0bdc0001043000bcc0503027f017e047f230041e0006b2202240041aeb9c400ad4280808080800184100c22032900002104200241086a41086a200341086a2900003703002002200437030820031023419cbdc400ad4280808080d00084100c22032900002104200241186a41086a200341086a2900003703002002200437031820031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100f22012900002104200241386a41086a200141086a2900003703002002200437033820011023200241d4006a200341206a360200200241003a0058200220033602502002200241386a41106a36024c2002200241386a360248200241286a200241c8006a1065200310232002280230220541206a2201417f4c0d0120022802282106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290308370000200341086a200241086a41086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290318370010200341186a200241186a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a2000200136020820002007360204200020033602000240200228022c450d00200610230b200241e0006a24000f0b102c000b102a000bae0503027f017e047f230041d0006b2202240041aeb9c400ad4280808080800184100c22032900002104200241086a200341086a290000370300200220043703002003102341c0bbc400ad4280808080b00184100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad4280808080800484100d220129000037033020011023200241c4006a200341206a360200200241003a0048200220033602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200310232002280228220541206a2201417f4c0d0120022802202106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000be40703027f017e067f230041e0006b2203240041aeb9c400ad4280808080800184100c22042900002105200341086a200441086a290000370300200320053703002004102341a0bcc400ad4280808080800284100c22042900002105200341106a41086a200441086a2900003703002003200537031020041023024002400240024002400240412010212204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020032004ad4280808080800484100d220129000037034020011023200341d4006a2201200441206a360200200341003a0058200320043602502003200341c0006a41086a220636024c2003200341c0006a360248200341206a200341c8006a106520041023412010212204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad4280808080800484100d2202290000370340200210232001200441206a360200200341003a0058200320043602502003200636024c2003200341c0006a360248200341306a200341c8006a1065200410232003280228220741206a2202200328023822086a2201417f4c0d01200328023021092003280220210a024002402001450d00200110212204450d022001410f4d0d01200121060c050b200141017422044110200441104b1b2206102122040d040c060b200141017422064110200641104b1b220641004e0d020c040b1033000b1032000b20012006460d0020042001200610252204450d020b20042003290300370000200441086a200341086a2903003700000240024020064170714110460d002006210b0c010b2006410174220b4120200b41204b1b220b4100480d012006200b460d0020042006200b10252204450d020b20042003290310370010200441186a200341106a41086a29030037000002400240200b41606a2007490d00200b21060c010b2007415f4b0d01200b41017422062002200620024b1b22064100480d01200b2006460d002004200b200610252204450d020b200441206a200a200710a1051a02400240200620026b2008490d002006210b0c010b200220086a2002490d012006410174220b2001200b20014b1b220b4100480d01024020060d000240200b0d00410121040c020b200b10212204450d030c010b2006200b460d0020042006200b10252204450d020b200420026a2009200810a1051a200020013602082000200b3602042000200436020002402003280234450d00200910230b02402003280224450d00200a10230b200341e0006a24000f0b102c000b102a000bb20403037f027e057f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841010108b0102400240200328021022010d00200041003602140c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d002003200141046a36022020032002417c6a220536022420054110490d002001280000210520032002416c6a3602242003200141146a3602202001410c6a290000210620012900042107200341c8006a200341206a10cf0120032802482202450d00200328024c21082003280224220941024f0d01200841ffffff3f71450d00200210230b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034180c5c6003602482003200341386a360258200341c4006a4184a5c200200341c8006a10311a2003350230422086200335022884100a0240200328022c450d00200328022810230b200041003602140c010b200341d0006a280200210a200341386a41046a200341286a41046a2f0100220b3b010020032003280128220c36023820032009417e6a36022420032003280220220941026a36022020092f000021092000200637030820002007370300200041206a20093b01002000411c6a200a3602002000200836021820002002360214200020053602102000200c360122200041266a200b3b01000b2004450d00200110230b200341e0006a24000ba00302037f037e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841010108b0102400240200328021022010d00200041003602140c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d002003200141046a36022020032002417c6a220536022420054110490d002001280000210520032002416c6a3602242003200141146a3602202001410c6a290000210620012900042107200341c8006a200341206a10cf01200328024822020d010b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034180c5c6003602482003200341386a360258200341c4006a4184a5c200200341c8006a10311a2003350230422086200335022884100a0240200328022c450d00200328022810230b200041003602140c010b200329024c210820002006370308200020073703002000200837031820002002360214200020053602100b2004450d00200110230b200341e0006a24000bc20101047f230041106b2202240020002802002200280208210320002802002100410121042001280218419b9ec00041012001411c6a28020028020c1100002105200241003a0005200220053a00042002200136020002402003450d0003402002200036020c20022002410c6a41e0e4c200105a1a200041016a21002003417f6a22030d000b20022d000421050b0240200541ff01710d0020022802002200280218419a9ec00041012000411c6a28020028020c11000021040b200241106a240020040b130020004104360204200041cccac4003602000b130020004110360204200041b4cec4003602000b950302087f017e230041106b220224000240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002006450d0020042d0001210720012003417e6a22063602042001200441026a3602002006450d0020042d0002210820012003417d6a22063602042001200441036a36020020060d010b200041003602040c010b20042d0003210620012003417c6a3602042001200441046a360200200241086a2001108801024020022802080d002001280204200228020c2204490d002004417f4c0d02024002400240024020040d00410121030c010b200410272203450d0120012802042004490d0220032001280200200410a1051a200128020422092004490d062001200920046b3602042001200128020020046a3602000b2003450d0220002004ad220a422086200a8437020820002003360204200020074108742005722008411074722006411874723602000c030b1033000b200310230b200041003602040b200241106a24000f0b1032000b20042009418ca9c0001044000bee0201047f024020002802082201450d002000280200220220014107746a21030340024020022d0000417c6a220041094b0d00024002400240024020000e0a00040102040404040403000b200241086a280200450d03200241046a28020010230c030b200241046a2802000d022002410c6a2802002200450d02200041286c450d02200241086a28020010230c020b200241046a2d00004102490d010240200241106a2802002200450d00200041d0006c2101200241086a28020041c4006a21000340024020002802002204450d00200441306c450d002000417c6a28020010230b200041d0006a2100200141b07f6a22010d000b0b2002410c6a2802002200450d01200041d0006c450d01200228020810230c010b200241046a280200450d00200241106a2802002200450d00200241146a280200450d00200010230b20024180016a21000240200241f4006a28020041ffffff3f71450d00200228027010230b2000210220002003470d000b0b0b880d05037f017e0b7f017e037f23004180016b22022400200241086a2001108801024002400240024002402002280208450d00200041003602000c010b200228020c2203200128020441246e2204200420034b1bad42247e2205422088a70d012005a72204417f4c0d010240024020040d00410421060c010b200410212206450d030b4100210720024100360218200220063602102002200441246e3602140240024002402003450d00200241cd006a2108200241eb006a220941056a210a4100210b03402001280204220c450d032001280200220d2d000021042001200c417f6a220e3602042001200d41016a360200200441074b0d030240024002400240024002400240024020040e08000b010b03040205000b2002200110880120022802000d0a200128020420022802042204490d0a2004417f4c0d0c0240024020040d004101210f41010d010c0c0b20041027220f450d0e20012802042004490d0a200f2001280200200410a105210c2001280204220d2004490d0f2001200d20046b3602042001200128020020046a360200200c450d0b0b200241c0006a41086a200241d8006a41086a29020037030020022002290258370340200f41087621104105210e420021052004210d0c050b41002104200241003a0078200c417e6a210c02400340200e2004460d01200241d8006a20046a200d20046a220f41016a2d00003a00002001200c3602042001200f41026a3602002002200441016a220f3a0078200c417f6a210c200f2104200f4120470d000b200220092900003703402002200a290000370045200228005f210d20022f0158210420022d005a210c200228005b210f20022900632111200841026a200241d5006a41026a2d00003a0000200820022f00553b00002011428080808070832105200f41087621102004200c41107472210c2011a721044100210e0c060b200441ff0171450d09200241003a00780c090b200241d8006a200110ae04200228025c220d450d0820022f015820022d005a41107472210c20022d005b210f200229036022114280808080708321052011a721044101210e0c040b200241d8006a200110ae04200228025c220d450d0720022f015820022d005a41107472210c20022d005b210f200229036022114280808080708321052011a721044102210e0c030b200241d8006a200110ae04200228025c220d450d0620022f015820022d005a41107472210c20022d005b210f200229036022114280808080708321052011a721044103210e0c020b200e450d05200d2d000121042001200c417e6a220f3602042001200d41026a36020020040d05200f450d05200d2d000221042001200c417d6a220e3602042001200d41036a360200200441014b0d054100210f0240024020040e020100010b200e4104490d06200d28000321122001200c41796a22043602042001200d41076a36020020044104490d06200d28000721132001200c41756a3602042001200d410b6a3602004101210f0b200241c0006a41086a200241d8006a41086a290200370300200220022902583703404104210e4200210541002110201321042012210d0b0b200b41016a210b200241306a41086a200241c0006a41086a2903002211370300200241206a41086a22142011370300200220022903402211370330200220113703202010410874200f41ff017172210f20052004ad842105024020072002280214470d00200241106a2007410110a20120022802102106200228021821070b2006200741246c6a2204200537000c2004200d3600082004200f3600042004200c3b00012004200e3a0000200441036a200c4110763a0000200420022903203700142004411c6a20142903003700002002200741016a2207360218200b2003470d000b0b20002002290310370200200041086a200241106a41086a2802003602000c020b200f10230b200241306a41086a200241c0006a41086a290300370300200220022903403703302000410036020002402007450d00200741246c21042006210103400240024020012d0000220c41044b0d00024002400240200c0e050400010204040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012004415c6a22040d000b0b20022802142201450d00200141246c450d00200610230b20024180016a24000f0b1032000b1033000b2004200d418ca9c0001044000bfc0303037f017e037f230041e00a6b220224002002200110880102400240024002402002280200450d00200041003602000c010b20022802042203200128020441c8036e2204200420034b1bad42c8037e2205422088a70d012005a72206417f4c0d010240024020060d00410821070c010b200610212207450d030b4100210420024100360210200220073602082002200641c8036e36020c024002402003450d0020024198076a41f0006a2108034020024198076a200110d303200241b0066a20024198076a41e80010a1051a2002290380082105200241d8036a200841d80210a1051a20054203510d02200241f0026a200241b0066a41e80010a1051a200241186a200241d8036a41d80210a1051a02402004200228020c470d00200241086a200410ac0120022802082107200228021021040b2007200441c8036c6a200241f0026a41e80010a10522062005370368200641f0006a200241186a41d80210a1051a2002200441016a22043602102003417f6a22030d000b0b20002002290308370200200041086a200241086a41086a2802003602000c010b2000410036020002402004450d00200441c8036c210320074198016a210403402004109e03200441c8036a2104200341b87c6a22030d000b0b200228020c2204450d00200441c8036c450d00200710230b200241e00a6a24000f0b1032000b1033000b8e0305037f017e037f017e017f230041c0006b22022400200241286a200110880102400240024002402002280228450d00200041003602000c010b200228022c2203200128020441186e2204200420034b1bad42187e2205422088a70d012005a72206417f4c0d010240024020060d00410821070c010b200610212207450d030b4100210420024100360238200220073602302002200641186e360234024002402003450d00200241206a21080340200241106a20011080022002290310a70d022008290300210520022903182109200241086a200110880120022802080d02200228020c210a024020042002280234470d00200241306a200410b20120022802382104200228023021070b2007200441186c6a2206200a36021020062005370308200620093703002002200441016a22043602382003417f6a22030d000b0b20002002290330370200200041086a200241306a41086a2802003602000c010b2000410036020020022802342204450d00200441186c450d00200710230b200241c0006a24000f0b1032000b1033000bb10201017f230041a0016b220324002003200236020420032001360200200341086a2002ad4220862001ad841010108b0102400240200328020822010d00200041003602400c010b200328020c21022003200341106a28020036027c20032001360278200341186a200341f8006a1083040240024020032802580d00200341003602880120034201370380012003410a360294012003200336029001200320034180016a36029c012003412c6a41013602002003420137021c20034180c5c600360218200320034190016a3602282003419c016a4184a5c200200341186a10311a20033502880142208620033502800184100a0240200328028401450d0020032802800110230b200041003602400c010b2000200341186a41e00010a1051a0b2002450d00200110230b200341a0016a24000b8709010f7f23004190036b2204240002400240200141046a28020022052f01062206410b490d002001280208210720012802002108200441306a410041e00210a0051a200441286a22064100360200200441206a22094200370300200441186a220a4200370300200441106a220b4200370300200441086a220c42003703002004420037030002404194031021220d450d00200d41003b0106200d4100360200200d41086a200441306a41e00210a105210e200d4190036a2006280200360200200d4188036a2009290300370200200d4180036a200a290300370200200d41f8026a200b290300370200200d41f0026a200c290300370200200d20042903003702e802200441306a41086a2209200541d0016a290000370300200441306a41106a220f200541d8016a290000370300200441306a41186a2210200541e0016a290000370300200420052900c8013703302005280280032111200e200541e8016a20052f010641796a220641057410a105210e200d41e8026a20054184036a200641027410a1052112200541063b0106200d20063b0106200a2010290300370300200b200f290300370300200c20092903003703002004200429033037030002400240200128020c22014107490d00200d41066a210a200e2001417a6a220c4105746a200e200141796a22014105746a220b200641ffff037120016b41057410a2051a200b41186a200241186a290000370000200b41106a200241106a290000370000200b41086a200241086a290000370000200b20022900003700002012200c4102746a2106201220014102746a21020c010b200541086a220a200141016a220b4105746a200a20014105746a2206200541066a220a2f010020016b41057410a2051a200641186a200241186a290000370000200641106a200241106a290000370000200641086a200241086a29000037000020062002290000370000200541e8026a220620014102746a21022006200b4102746a2106200121010b20062002200a2f010020016b41027410a2051a20022003360200200041013a00002000200236023c200041386a4100360200200041346a200d360200200041306a20113602002000412c6a2007360000200041286a2005360000200041246a200836000020002004290300370001200041096a200441086a290300370000200041116a200441106a290300370000200041196a200441186a290300370000200a200a2f010041016a3b01000c020b102a000b200541086a220a200128020c220d41016a220b4105746a200a200d4105746a220a2006200d6b41057410a2051a200a41186a200241186a290000370000200a41106a200241106a290000370000200a41086a200241086a290000370000200a2002290000370000200541e8026a2202200b4102746a2002200d4102746a220220052f0106200d6b41027410a2051a20022003360200200520052f010641016a3b0106200441306a410b6a200141086a280000360000200041003a00002000200236023c200041106a200d3600002004200129000037003320002004290030370001200041086a200441376a2900003700000b20044190036a24000be60b020f7f047e23004180046b220624000240024020012802002207417f6a2005470d000240024002400240200141046a28020022082f01062209410b490d002001280208210a200641c0006a410272410041be0310a0051a41c4031021220b450d05200b4100360200200b41046a200641c0006a41c00310a1051a200641c0006a41186a220c200841e0016a290000370300200641c0006a41106a220d200841d8016a290000370300200641c0006a41086a220e200841d0016a290000370300200620082900c801370340200828028003210f200b41086a200841e8016a20082f0106221041796a220541057410a1052111200b41e8026a20084184036a200541027410a1052112200b4194036a200841b0036a2010417a6a221341027410a1052114200841063b0106200b20053b010602402013450d00410021052014211003402010280200220920053b01042009200b360200201041046a21102013200541016a2205470d000b0b200641206a41186a200c2903002215370300200641206a41106a200d2903002216370300200641206a41086a200e2903002217370300200620062903402218370320200641186a2015370300200641106a2016370300200641086a201737030020062018370300200128020c22054107490d0120112005417a6a22014105746a2011200541796a22104105746a2209200b2f010620106b41057410a2051a200941186a200241186a290000370000200941106a200241106a290000370000200941086a200241086a290000370000200920022900003700002012200141027422096a201220104102746a2213200b2f010620106b41027410a2051a20132003360200200b200b2f010641016a22133b01062005410274220220146a416c6a201420096a2205201341ffff037120016b41027410a2051a200520043602002001200b2f010622134b0d022002200b6a41fc026a2105034020052802002209201041016a22103b01042009200b360200200541046a210520102013490d000c030b0b200841086a2205200128020c221341016a22104105746a200520134105746a2205200920136b41057410a2051a200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a29000037000020052002290000370000200841e8026a22092010410274220b6a2009201341027422056a220920082f010620136b41027410a2051a20092003360200200820082f010641016a22093b0106200520084194036a22026a41086a2002200b6a220b200941ffff037120106b41027410a2051a200b20043602000240201020082f0106220b4b0d00200820056a4198036a210520132110034020052802002209201041016a22103b010420092008360200200541046a21052010200b490d000b0b200041003a0000200041046a2001290200370200200041106a20133602002000410c6a200141086a2802003602000c020b200841086a2210200541016a22094105746a201020054105746a221020082f010620056b41057410a2051a201041186a200241186a290000370000201041106a200241106a290000370000201041086a200241086a29000037000020102002290000370000200841e8026a2213200941027422016a2013200541027422106a221320082f010620056b41027410a2051a20132003360200200820082f010641016a22133b0106201020084194036a22026a41086a200220016a2201201341ffff037120096b41027410a2051a20012004360200200520082f010622134f0d00200820106a4198036a2110034020102802002209200541016a22053b010420092008360200201041046a211020132005470d000b0b20002006290300370001200041013a00002000412c6a200a360200200041286a2008360200200041246a2007360200200041386a2007360200200041346a200b360200200041306a200f360200200041096a200641086a290300370000200041116a200641106a290300370000200041196a200641186a2903003700000b20064180046a24000f0b41ecdbc4004135418c94c700102d000b102a000bb30604017f017e017f047e230041a0016b220624000240200341ff0171450d00200641306a2001ad42004280c2d72f420010a605200641206a2002418094ebdc032002418094ebdc03491bad420042a08d06420010a605200641f0006a41186a4200370300200641f0006a41106a22014200370300200641f0006a41086a220242003703002006420037037041c599c500ad4280808080a00284100c220329000021072002200341086a290000370300200620073703702003102341b09ac500ad4280808080900284100c2203290000210720064190016a41086a2208200341086a29000037030020062007370390012003102320012006290390012207370300200641d0006a41086a2002290300370300200641d0006a41106a2007370300200641d0006a41186a200829030037030020062006290370370350200641206a41086a290300200641306a41086a2903007c2006290320220920062903307c2207200954ad7c2109200641c0006a200641d0006a10fa020240024020062802400d00410021024200210a0c010b2006290348220a4200552102200a427f550d00428080808080808080807f4200200a7d200a428080808080808080807f511b210a0b200641106a20072009200a428094ebdc0380220b420010a6052006200a200b4280ec94a37c7e7ca722033602702006418094ebdc0336027420062007428094ebdc03804200200641f0006a2003418094ebdc034b4102746a350200220a420010a605427f200641086a290300200641106a41086a2903007c2006290300220c20062903107c220b200c54ad7c200b200a2007428094ebdc03827e220a428094ebdc0380220ca7417f200a428080808080c0b2cd3b541b200a200c4280ec94a37c7e7c4280cab5ee01566aad7c220a200b54ad7c220b20097c200a20077c220c200a54ad7c42002009200b7d2007200a54ad7d220b2007200a7d220a200756200b200956200b2009511b22031b20021b200c4200200a20031b20021b22094280c8afa0257c2207200954ad7c220920057c200720047c22042007542202ad7c22072002200720095420072009511b22021b2105427f200420021b21040b2000200437030020002005370308200641a0016a24000bb62103027f017e037f230041106b2202240002402000280268220341024b0d0002400240024020030e03000102000b200241003a000020012002410110622002200041ec006a28020036020020012002410410620c020b200241013a000020012002410110620c010b200241023a000020012002410110620b024020002d00002203410e4b0d0002400240024002400240024002400240024002400240024002400240024020030e0f000102030405060708090a0b0c0d0e000b200241003a00002001200241011062200041046a2d0000220341044b0d0e0240024002400240024020030e050001020304000b200241003a00002001200241011062200041086a200110cb040c120b200241013a00002001200241011062200041146a210302400240024002400240200041086a2d00000e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a000020012002410110622002200041096a2d00003a0000200120024101106220022000410a6a2d00003a00000b20012002410110622003200110cb040c110b200241023a000020012002410110620c100b200241033a000020012002410110622001200041056a412010620c0f0b200241043a000020012002410110622001200041056a412010620c0e0b200241013a000020012002410110620240200041046a2d00004101460d00200241003a000020012002410110622001200041056a412010622002200041286a28020036020020012002410410620c0e0b200241013a000020012002410110622002200041086a28020036020020012002410410620c0d0b200241023a00002001200241011062200041086a2d0000220341044b0d0c02400240024002400240024020030e050001020304000b200241003a000020012002410110622001200041096a41201062200041306a29030021042002200041386a290300370308200220043703000c040b200241013a000020012002410110622001200041096a41201062200041306a29030021042002200041386a290300370308200220043703000c030b200241023a000020012002410110622001200041096a412010622001200041296a41201062200041d0006a29030021042002200041d8006a290300370308200220043703000c020b200241033a000020012002410110622001200041096a41201062200041306a29030021042002200041386a290300370308200220043703002001200241101062200041c0006a29030021042002200041c8006a290300370308200220043703000c010b200241043a000020012002410110622001200041096a41201062200041306a29030021042002200041386a290300370308200220043703000b20012002411010620c0c0b200241033a00002001200241011062200041086a2d0000220341064b0d0b024002400240024002400240024020030e0700010203040506000b200241003a000020012002410110622001200041096a41201062200041306a29030021042002200041386a2903003703082002200437030020012002411010620c110b200241013a000020012002410110622001200041096a41201062200041306a29030021042002200041386a2903003703082002200437030020012002411010620c100b200241023a0000200120024101106220022000410c6a28020036020020012002410410620c0f0b200241033a00002001200241011062200041096a2d0000220341024b0d0e02400240024020030e03000102000b200241003a000020012002410110620c100b200241013a000020012002410110620c0f0b200241023a000020012002410110620c0e0b200241043a000020012002410110622001200041096a41201062200041306a29030021042002200041386a2903003703082002200437030020012002411010620c0d0b200241053a000020012002410110622001200041096a41201062200041306a29030021042002200041386a2903003703082002200437030020012002411010620c0c0b200241063a000020012002410110622001200041096a41201062200041306a29030021042002200041386a2903003703082002200437030020012002411010620c0b0b200241043a00002001200241011062200241003a000020012002410110622001200041106a41101062200041046a28020021032000410c6a28020022052001106120012003200510622002200041206a2d00003a000020012002410110620c0a0b200241053a00002001200241011062200241003a000020012002410110622002200041046a28020036020020012002410410620c090b200241063a00002001200241011062200041046a280200220341024b0d0802400240024020030e03000102000b200241003a00002001200241011062200041086a2802002103200041106a2802002205200110612005450d0a2003200541286c6a2105034020012003412010622002200341206a29030037030020012002410810622005200341286a2203470d000c0b0b0b200241013a000020012002410110620c090b200241023a000020012002410110620c080b200241073a00002001200241011062200041046a2d0000220341024b0d0702400240024020030e03000102000b200241003a000020012002410110622001200041056a412010620c090b200241013a000020012002410110620c080b200241023a00002001200241011062200041086a2802002106200041106a2802002203200110612003450d072006200341d0006c6a2107034020012006412010622002200641206a3602002002200110db012002200641306a3602002002200110db01200628024021032006280248220520011061200641d0006a210602402005450d00200541306c210503402001200341106a41201062200220033602002002200110db01200341306a2103200541506a22050d000b0b20072006470d000c080b0b200241083a000020012002410110620240200041046a2802004101460d00200241003a000020012002410110622002200028020836020020012002410410620c070b200241013a000020012002410110622002200028020836020020012002410410620c060b200241093a00002001200241011062200041046a2d0000220341054b0d0502400240024002400240024020030e06000102030405000b200241003a000020012002410110622002200041086a2802003602002001200241041062024002400240024002402000410c6a2d00000e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a0000200120024101106220022000410d6a2d00003a0000200120024101106220022000410e6a2d00003a00000b20012002410110620c0a0b200241013a000020012002410110620c090b200241023a000020012002410110622001200041056a412010622001200041256a412010620c080b200241033a000020012002410110622001200041056a412010622002200041c8006a28020036020020012002410410622002200041cc006a28020036020020012002410410622001200041256a412010620c070b200241043a000020012002410110622001200041056a412010622002200041c8006a28020036020020012002410410622002200041cc006a28020036020020012002410410622001200041256a412010620240200041d0006a2d000022034104460d00200241013a000020012002410110620240024002400240024020030e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a000020012002410110622002200041d1006a2d00003a000020012002410110622002200041d2006a2d00003a00000b20012002410110620c070b200241003a000020012002410110620c060b200241053a000020012002410110622001200041056a412010622002200041c8006a28020036020020012002410410622002200041cc006a28020036020020012002410410622001200041256a412010620c050b2002410a3a00002001200241011062200041086a2d0000220341064b0d04024002400240024002400240024020030e0700010203040506000b200241003a000020012002410110622001200041096a412010620c0a0b200241013a000020012002410110622001200041096a41201062200041306a29030021042002200041386a2903003703082002200437030020012002411010620c090b200241023a000020012002410110622001200041096a41201062200041306a29030021042002200041386a2903003703082002200437030020012002411010620c080b200241033a000020012002410110622001200041096a4120106220022000412c6a28020036020020012002410410620c070b200241043a000020012002410110622001200041096a4120106220022000412c6a28020036020020012002410410620c060b200241053a000020012002410110622001200041096a4120106220022000412c6a28020036020020012002410410620c050b200241063a0000200120024101106220022000410c6a28020036020020012002410410620c040b2002410b3a0000200120024101106220002d0001220341054b0d03024002400240024002400240024020030e06000102030405000b200241003a00002001200241011062200041026a21030c050b200241013a000020012002410110622001200041026a41201062200041226a21030c040b200241023a000020012002410110622001200041026a412010622001200041226a41201062200041c2006a21030c030b200241033a000020012002410110622001200041026a41201062200041226a21030c020b200241043a000020012002410110622001200041026a41201062200041226a21030c010b200241053a00002001200241011062200041026a21030b20012003412010620c030b2002410c3a00002001200241011062200041096a21030240200041086a2d00004101460d00200241003a000020012002410110622001200341201062200041306a29030021042002200041386a2903003703082002200437030020012002411010620c030b200241013a0000200120024101106220012003412010620c020b2002410d3a000020012002410110620240200041046a2802004101460d00200241003a000020012002410110622002200041086a28020036020020012002410410620c020b200241013a000020012002410110622002200041086a280200360200200120024104106220022000410c6a280200360200200120024104106202400240200041106a28020022030d00200241003a000020012002410110620c010b200241013a00002001200241011062200041186a28020022052001106120012003200510620b024020002d001c22034104460d00200241013a000020012002410110620240024002400240024020030e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a0000200120024101106220022000411d6a2d00003a0000200120024101106220022000411e6a2d00003a00000b20012002410110620c020b200241003a000020012002410110620c010b2002410e3a0000200120024101106220002d0001220341024b0d0002400240024020030e03000102000b200241003a000020012002410110622002200041026a2d00003a000020012002410110620c020b200241013a000020012002410110622001200041026a412010620c010b200241023a000020012002410110622002200041026a2d00003a000020012002410110620b2000280270200041f8006a280200200110c803200241106a24000b9f0201037f024020002d0000417c6a220141094b0d00024002400240024020010e0a00040102040404040403000b200041086a280200450d03200041046a28020010230c030b200041046a2802000d022000410c6a2802002201450d02200141286c450d02200041086a28020010230f0b200041046a2d00004102490d010240200041106a2802002201450d00200141d0006c2102200041086a28020041c4006a21010340024020012802002203450d00200341306c450d002001417c6a28020010230b200141d0006a2101200241b07f6a22020d000b0b2000410c6a2802002201450d01200141d0006c450d01200028020810230f0b200041046a280200450d00200041106a2802002201450d00200041146a280200450d00200110230f0b0bf8f00102517f0d7e230041d0106b22012400200141003602102001410036020802400240200041086a22022802002203450d00200141f8076a4102722104200141fd026a2105200141d0026a41206a2106200141386a41206a2107200141f8076a41206a2108200141186a41186a2109200141186a41106a210a4100210b0340024002402002280200220c200b4d0d0020092000280200200b412c6c220d6a220e41246a290000370300200a200e411c6a290000370300200141186a41086a220f200e41146a2900003703002001200e29000c370318200e280200210c200e280208210e2001410036028008200142013703f807200141f8076a4100200e109a01200128028008211002400240200e41306c22110d0020012802f80721120c010b20012802f807221220104105746a210e0340200e200c290000370000200e41186a200c41186a290000370000200e41106a200c41106a290000370000200e41086a200c41086a290000370000201041016a2110200e41206a210e200c41306a210c201141506a22110d000b0b20012802fc07211320104102490d0102402010417f6a221420106c410176220c41ffffff1f71200c470d00200c410674220c417f4c0d00024002400240200c0d00410121150c010b200c10212215450d010b201241206a2116200c4106762117410021184100210c034002400240200c41016a221920104f0d002018410674211a2012200c4105746a21112014211b2016210e0340200141f8076a41186a221c201141186a290000370300200141f8076a41106a221d201141106a290000370300200141f8076a41086a221e201141086a290000370300200120112900003703f8072008200e290000370000200841086a200e41086a290000370000200841106a200e41106a290000370000200841186a200e41186a290000370000024020182017470d00024002400240201741016a220c2017490d002017410174221f200c201f200c4b1b220c41ffffff1f71200c470d00200c410674220c4100480d00024020170d00200c0d02410121150c030b20174106742217200c460d02024020170d00200c0d02410121150c030b20152017200c10252215450d0e0c020b102c000b200c10212215450d0c0b200c41067621170b2015201a6a220c20012903f807370000200c41386a200141f8076a41386a290300370000200c41306a200141f8076a41306a290300370000200c41286a200141f8076a41286a290300370000200c41206a2008290300370000200c41186a201c290300370000200c41106a201d290300370000200c41086a201e290300370000200e41206a210e201a41c0006a211a201841016a2118201b417f6a221b450d020c000b0b02402018450d00201520184106746a21202015211e02400340200141386a41386a201e41386a290000370300200141386a41306a201e41306a290000370300200141386a41286a201e41286a2900003703002007201e41206a290000370300200141386a41186a201e41186a220c290000370300200141386a41106a201e41106a220e290000370300200141386a41086a201e41086a22112900003703002001201e290000370338200141f8006a41186a2218200c290000370300200141f8006a41106a220c200e290000370300200141f8006a41086a220e20112900003703002001201e29000037037820014198016a41186a200741186a221129000037030020014198016a41106a200741106a221a29000037030020014198016a41086a200741086a221b2900003703002001200729000037039801200141d0026a41186a22192018290300370300200141d0026a41106a2221200c290300370300200141d0026a41086a2222200e29030037030020062007290000370000200641086a201b290000370000200641106a201a290000370000200641186a2011290000370000200120012903783703d002024002402001280208221b450d00200128020c211c0c010b200141f8076a410041c00510a0051a200141e8046a410041e00210a0051a41a8081021221b450d0c4100211c201b41003b0106201b4100360200201b41086a200141f8076a41c00510a1051a201b41c8056a200141e8046a41e00210a1051a2001410036020c2001201b3602080b201e41c0006a211e024002400240024002400240024002400240024002400240024003400240201b2f0106221a410674220e450d00201b41286a210c41002111034002400240200141d0026a200c41606a412010a3052218450d00201841004e0d012011211a0c030b2006200c412010a3052218450d04201841004e0d002011211a0c020b201141016a2111200c41c0006a210c200e41406a220e0d000b0b201c450d02201c417f6a211c201b201a4102746a41a8086a280200211b0c000b0b20022802002210200b4d0d032000280200221d200d6a220c28020841306c221a450d0a201b201141057422236a41c8056a211f200c280200210c4100211803404101210e0240200141f8006a200c460d00200c200141f8006a412010a305450d00024020014198016a200c470d004101210e0c010b200c20014198016a412010a30545210e0b200c41306a210c200e20186a2118201a41506a221a0d000b20184102470d0a2010412c6c210e0340201d210c200e450d0b0240200c410c6a2218201f460d00200e41546a210e200c412c6a211d2018201f412010a3050d010b0b0240200c41086a280200220e450d00200e41306c211a200141f8006a200c28020022186b211d20014198016a20186b21104100210c0340201d200c460d032018200c6a220e200141f8006a412010a305450d032010200c460d03200e20014198016a412010a305450d03201a200c41306a220c470d000b0b41082124410021250c070b200141b8016a41386a220c200141d0026a41386a290300370300200141b8016a41306a220e200141d0026a41306a290300370300200141b8016a41286a2211200141d0026a41286a290300370300200141b8016a41206a22182006290300370300200141b8016a41186a221c2019290300370300200141b8016a41106a221d2021290300370300200141b8016a41086a221f2022290300370300200120012903d0023703b8012001200128021041016a360210200141a0036a41386a2226200c290300370300200141a0036a41306a2227200e290300370300200141a0036a41286a22282011290300370300200141a0036a41206a22242018290300370300200141a0036a41186a2223201c290300370300200141a0036a41106a2225201d290300370300200141a0036a41086a2229201f290300370300200120012903b8013703a003200141d0076a41186a222a2009290300370300200141d0076a41106a222b200a290300370300200141d0076a41086a222c200f290300370300200120012903183703d0070240201b2f0106220e410b490d00200141f8076a410041c00510a0051a200141e8046a410041e00210a0051a41a8081021220c450d17200c41003b0106200c4100360200200c41086a200141f8076a41c00510a105210e200c41c8056a200141e8046a41e00210a1052118200141f8076a41086a221f201b41a3036a290000370300200141f8076a41106a2210201b41ab036a290000370300200141f8076a41186a2214201b41b3036a2900003703002008201b41bb036a290000370300200141f8076a41256a2216201b41c0036a2900003700002001201b4188036a2f00003b0188042001201b418a036a2d00003a008a042001201b419b036a2900003703f807201b418b036a280000212d201b418f036a280000212e201b4193036a280000212f201b4197036a2800002130200141c8046a41186a2231201b41a0076a290000370300200141c8046a41106a2232201b4198076a290000370300200141c8046a41086a2233201b4190076a2900003703002001201b290088073703c804200e201b41c8036a201b2f010641796a221141067410a105210e2018201b41a8076a201141057410a1052118201b41063b0106200c20113b0106200141e0036a41026a221c20012d008a043a0000200141e8046a41086a2234201f290300370300200141e8046a41106a22352010290300370300200141e8046a41186a22362014290300370300200141e8046a41206a22372008290300370300200141e8046a41256a22382016290000370000200120012f0188043b01e003200120012903f8073703e804200141a8046a41186a22392031290300370300200141a8046a41106a223a2032290300370300200141a8046a41086a223b2033290300370300200120012903c8043703a80402400240201a4107490d00200e201a417a6a221d4106746a200e201a41796a221a4106746a220e201141ffff0371201a6b41067410a2051a200e41386a2026290300370000200e41306a2027290300370000200e41286a2028290300370000200e41206a2024290300370000200e41186a2023290300370000200e41106a2025290300370000200e41086a2029290300370000200e20012903a0033700002018201d4105746a2018201a4105746a220e200c2f0106201a6b41057410a2051a200e41186a202a290300370000200e41106a202b290300370000200e41086a202c290300370000200e20012903d007370000200c200c2f010641016a3b01060c010b201b41086a220e201a41016a22114106746a200e201a4106746a220e201b2f0106201a6b41067410a2051a200e41386a2026290300370000200e41306a2027290300370000200e41286a2028290300370000200e41206a2024290300370000200e41186a2023290300370000200e41106a2025290300370000200e41086a2029290300370000200e20012903a003370000201b41c8056a220e20114105746a200e201a4105746a220e201b2f0106201a6b41057410a2051a200e41186a202a290300370000200e41106a202b290300370000200e41086a202c290300370000200e20012903d007370000201b201b2f010641016a3b01060b200520012903a804370000200141f4076a41026a220e201c2d00003a000020222034290300370300202120352903003703002019203629030037030020062037290300370300200141d0026a41256a22282038290000370000200541086a2211203b290300370000200541106a2218203a290300370000200541186a221a2039290300370000200120012f01e0033b01f407200120012903e8043703d002200141ac026a41026a223c200e2d00003a0000200141f8016a41086a223d2022290300370300200141f8016a41106a223e2021290300370300200141f8016a41186a223f2019290300370300200141f8016a41206a22402006290300370300200141f8016a41256a22412028290000370000200120012f01f4073b01ac02200120012903d0023703f801200141b0026a41186a2242201a290000370300200141b0026a41106a22432018290000370300200141b0026a41086a22442011290000370300200120052900003703b0020240201b28020022180d004100211d200141086a210e200c21180c0a0b201b2f0104212641002145200c2146034020014184046a41026a2247203c2d00003a00002022203d2903003703002021203e2903003703002019203f2903003703002006204029030037030020282041290000370000200120012f01ac023b018404200120012903f8013703d00220014188046a41186a2248204229030037030020014188046a41106a2249204329030037030020014188046a41086a224a2044290300370300200120012903b0023703880441000d03202641ffff0371211c02400240024020182f0106220c410b490d002004410041d20810a0051a41d8081021221a450d1b201a4100360200201a41046a200141f8076a41d40810a1051a200141d0076a41026a224b2018418a036a2d00003a0000201f201841a3036a2900003703002010201841ab036a2900003703002014201841b3036a2900003703002008201841bb036a2900003703002016201841c0036a290000370000200120184188036a2f00003b01d00720012018419b036a2900003703f8072018418b036a280000214c2018418f036a280000214d20184193036a280000214e20184197036a280000214f2031201841a0076a290000370300203220184198076a290000370300203320184190076a29000037030020012018290088073703c804201a41086a201841c8036a20182f0106220e41796a220c41067410a1052150201a41c8056a201841a8076a200c41057410a1052151201a41a8086a201841c4086a200e417a6a221d41027410a1052127201841063b0106201a200c3b01060240201d450d004100210c2027210e0340200e2802002211200c3b01042011201a360200200e41046a210e201d200c41016a220c470d000b0b2034201f29030037030020352010290300370300203620142903003703002037200829030037030020382016290000370000203b2033290300370300203a203229030037030020392031290300370300200120012f01d0073b01f407200120012903f8073703e804200120012903c8043703a8042001204b2d00003a00f607200141cc076a41026a221d20012d00f6073a0000201f203429030037030020102035290300370300201420362903003703002008203729030037030020162038290000370000200120012f01f4073b01cc07200120012903e8043703f807202a2039290300370300202b203a290300370300202c203b290300370300200120012903a8043703d007202641ffff037122264107490d012050201c417a6a22114106746a2050201c41796a220c4106746a220e201a2f0106200c6b41067410a2051a200e203036000f200e202f36000b200e202e360007200e202d360003200e41026a20472d00003a0000200e20012f0184043b0000200e20012903d002370013200e411b6a2022290300370000200e41236a2021290300370000200e412b6a2019290300370000200e41336a2006290300370000200e41386a2028290000370000205120114105746a2051200c4105746a220e201a2f01062226200c6b41057410a2051a200e41186a2048290300370000200e41106a2049290300370000200e41086a204a290300370000200e200129038804370000201a202641016a220e3b0106201c410274222d20276a416c6a202720114102746a2226200e41ffff0371221c20116b41027410a2051a20262046360200201c2011490d02201a202d6a4190086a210e0340200e2802002211200c41016a220c3b01042011201a360200200e41046a210e200c201c490d000c030b0b201841086a220e201c41016a22114106746a200e201c4106746a220e200c201c6b41067410a2051a200e203036000f200e202f36000b200e202e360007200e202d360003200e41026a20472d00003a0000200e20012f0184043b0000200e20012903d002370013200e411b6a2022290300370000200e41236a2021290300370000200e412b6a2019290300370000200e41336a2006290300370000200e41386a2028290000370000201841c8056a220c20114105746a200c201c4105746a220c20182f0106220e201c6b41057410a2051a200c41186a2048290300370000200c41106a2049290300370000200c41086a204a290300370000200c2001290388043700002018200e41016a220c3b0106201c410274201841a8086a220e6a41086a200e20114102746a220e200c41ffff0371221a20116b41027410a2051a200e20463602000240201c201a4f0d0020182011417f6a220c4102746a41ac086a210e0340200e2802002211200c41016a220c3b010420112018360200200e41046a210e200c201a490d000b0b41001a200141086a1a201b1a0c0d0b201841086a220c201c41016a220e4106746a200c201c4106746a220c20182f0106201c6b41067410a2051a200c203036000f200c202f36000b200c202e360007200c202d360003200c41026a20472d00003a0000200c20012f0184043b0000200c20012903d002370013200c411b6a2022290300370000200c41236a2021290300370000200c412b6a2019290300370000200c41336a2006290300370000200c41386a2028290000370000201841c8056a220c200e4105746a200c201c4105746a220c20182f01062211201c6b41057410a2051a200c41186a2048290300370000200c41106a2049290300370000200c41086a204a290300370000200c2001290388043700002018201141016a220c3b0106201c410274222d201841a8086a22116a41086a2011200e4102746a2227200c41ffff03712211200e6b41027410a2051a20272046360200202620114f0d002018202d6a41ac086a210c0340200c280200220e201c41016a221c3b0104200e2018360200200c41046a210c2011201c470d000b0b204541016a210c20014180046a41026a220e201d2d00003a00002029201f290300370300202520102903003703002023201429030037030020242008290300370300200141a0036a41256a22112016290000370000200141e0036a41086a221c202c290300370300200141e0036a41106a221d202b290300370300200141e0036a41186a2226202a290300370300200120012f01cc073b018004200120012903f8073703a003200120012903d0073703e003203c200e2d00003a0000203d2029290300370300203e2025290300370300203f20232903003703002040202429030037030020412011290000370000200120012f0180043b01ac02200120012903a0033703f801204220262903003703002043201d2903003703002044201c290300370300200120012903e0033703b00202402018280200220e0d00204d212e204e212f204f213020181a200141086a220e1a204c212d200c211d201a21180c0b0b20182f01042126200141086a1a204d212e204e212f204f213020181a204c212d200e2118201a2146200c21450c000b0b201b41086a220c201a41016a22114106746a200c201a4106746a220c200e201a6b41067410a2051a200c41386a2026290300370000200c41306a2027290300370000200c41286a2028290300370000200c41206a2024290300370000200c41186a2023290300370000200c41106a2025290300370000200c41086a2029290300370000200c20012903a003370000201b41c8056a220c20114105746a200c201a4105746a220c201b2f0106201a6b41057410a2051a200c41186a202a290300370000200c41106a202b290300370000200c41086a202c290300370000200c20012903d007370000201b201b2f010641016a3b01060c090b200141f8076a41086a22292018200c6a220e41086a290300370300200141f8076a41106a222a200e41106a290300370300200141f8076a41186a222b200e41186a2903003703002001200e2903003703f807200e41286a2903002152200e41206a2903002153413010212224450d0f20242053370320202420012903f807370300202441286a2052370300202441186a202b290300370300202441106a202a290300370300202441086a202929030037030020014281808080103702ec04200120243602e8040240201a41506a200c470d00410121250c060b200e41306a211d2018201a6a220e41506a21194101211a0340201d210c024002400340200141f8006a200c460d01200c200141f8006a412010a305450d0120014198016a200c460d01200c20014198016a412010a305450d01200e200c41306a220c470d000c020b0b200c41286a2903002152200c41206a2903002153200141d0076a41186a2210200c41186a290300370300200141d0076a41106a2214200c41106a290300370300200141d0076a41086a2216200c41086a2903003703002001200c2903003703d0070240201a20012802ec04470d00200141e8046a201a410110a40120012802e80421240b200c41306a211d2024201a41306c6a221820012903d00737030020162903002154201429030021552010290300215620182053370320201841286a2052370300201841186a2056370300201841106a2055370300201841086a20543703002001201a41016a221a3602f0042019200c470d010b0b20012802ec042125201a4102490d05201a4102470d0441e0001021221d450d0f200142023702fc012001201d3602f80102402002280200220c200b4d0d000240024002402000280200200d6a220c28020841306c221a0d004102210c0c010b200c280200210c41002118034002400240200141f8006a200c460d00200c200141f8006a412010a305210e20014198016a200c460d00200e450d00200c20014198016a412010a3050d010b200141c8046a41186a2210200c41186a290300370300200141c8046a41106a2214200c41106a290300370300200141c8046a41086a2216200c41086a2903003703002001200c2903003703c804200c41286a2903002152200c41206a29030021530240201820012802fc01470d00200141f8016a2018410110a40120012802f801211d20012802800221180b201d201841306c6a220e20012903c804370300201629030021542014290300215520102903002156200e2053370320200e41286a2052370300200e41186a2056370300200e41106a2055370300200e41086a20543703002001201841016a2218360280020b200c41306a210c201a41506a221a0d000b20184102460d0120012802fc01210c0b200c450d08200c41306c450d08201d10230c080b0240201d2024460d002024201d412010a305450d00200141f8076a41286a220c202441286a220e2903003703002008202441206a2218290300370300202b202441186a221a290300370300202a202441106a22102903003703002029202441086a2214290300370300200120242903003703f807200e202441d8006a22162903003703002018202441d0006a220e290300370300201a202441c8006a22182903003703002010202441c0006a221a2903003703002014202441386a2210290300370300202420242903303703002016200c290300370300200e20082903003703002018202b290300370300201a202a29030037030020102029290300370300202420012903f8073703300b2001427f3703f0042001427f3703e8044100211a200141003602c8042001410036028008200142083703f807200141f8076a4100410410a401202441e0006a211420012802f8072235200128028008221641306c6a211020012903f004215420012903e80421574100211803400240201d201a6a220c41206a2903002253205756200c41286a290300225220545620522054511b0d00200120533703e804200120183602c804200120523703f00420532157205221540b2010201a6a220e200c290300370300200c41086a2903002155200c41106a2903002156200c41186a2903002158200e41286a2052370300200e41206a2053370300200e41186a2058370300200e41106a2056370300200e41086a2055370300201841016a2118201a41306a221a41e000470d000b024020242014460d002010201a6a210c200141e8046a41086a290300215420012903e80421572024210e0340200e41306a211a0240200e41206a2903002253205756200e41286a290300225220545620522054511b0d00200120533703e804200120183602c804200120523703f00420532157205221540b200c200e290300370300200e41086a2903002155200e41106a2903002156200e41186a2903002158200c41286a2052370300200c41206a2053370300200c41186a2058370300200c41106a2056370300200c41086a2055370300200c41306a210c201841016a2118201a210e2014201a470d000b0b201620186a211620012802fc07212d200141003602c001200142043703b801200141003602a803200142043703a00320012802c804210c200141a0036a41004101107920012802a003222820012802a803220e4102746a200c3602002001200e41016a220c3602a80302400240024020012802c80422184102490d00200141b8016a41004101107920012802b80120012802c001220e4102746a201841017141037322183602002001200e41016a220e3602c0012018417e6a21180240200c20012802a403470d00200141a0036a200c4101107920012802a003212820012802a803210c0b2028200c4102746a20183602002001200c41016a22343602a80320012802c804417e6a210c200e20012802bc01470d02200141b8016a200e410110790c010b200141b8016a41004101107920012802b80120012802c001220e4102746a410120186b3602002001200e41016a220e3602c001410320186b21180240200c20012802a403470d00200141a0036a200c4101107920012802a003212820012802a803210c0b2028200c4102746a20183602002001200c41016a22343602a80320012802c80441026a210c200e20012802bc01470d01200141b8016a200e410110790b20012802c001210e0b20012802b8012227200e4102746a200c3602002001200e41016a220c3602c00141041021222c450d10200142013702d4022001202c3602d00220012802bc0121360240200c450d002027200c4102746a212620272122034002400240202228020022214102490d00202b201f41186a290000370300202a201f41106a2900003703002029201f41086a2900003703002001201f2900003703f8070c010b202b2009290300370300202a200a2903003703002029200f290300370300200120012903183703f8070b02402002280200220c450d0020002802002210200c412c6c6a21142035202141306c6a211a034002400240200141f8076a2010410c6a220c460d00200c200141f8076a412010a3050d010b2010280208210c0240201620214d0d00200c41306c210e4100211820102802002219210c02400340200e450d03201a200c460d01200c201a412010a305211d201841016a2118200e41506a210e200c41306a210c201d0d000b201d4541016a41017120186a417f6a21180b2019201841306c6a220c427f200c290320225220012903e8047c22532053205254220e200c41286a220c2903002252200141e8046a41086a2903007c200ead7c225320525420532052511b220e1b370320200c427f2053200e1b3703000c010b200c450d002021201641c4e6c4001030000b2010412c6a22102014470d000b0b202241046a22222026470d000b0b0240203641ffffffff0371450d00202710230b20012802a403212e0240024020340d00410021270c010b202820344102746a21364100212720282134034002400240203428020022224102490d00202b201f41186a290000370300202a201f41106a2900003703002029201f41086a2900003703002001201f2900003703f8070c010b202b2009290300370300202a200a2903003703002029200f290300370300200120012903183703f8070b02402002280200220c450d0020002802002210200c412c6c6a21192035202241306c6a211a034002400240200141f8076a2010410c6a220c460d00200c200141f8076a412010a3050d010b201041086a2226280200211402400240201620224d0d00201441306c210e4100211820102802002221210c02400340200e450d04201a200c460d01200c201a412010a305211d201841016a2118200e41506a210e200c41306a210c201d0d000b201d4541016a41017120186a417f6a21180b42002021201841306c6a220c290320225220012903e80422547d22532053205256200c41286a2903002253200141e8046a41086a2903007d2052205454ad7d225220535620522053511b220e1b225342002052200e1b225284500d01200c41206a220c2053370300200c20523703080c020b2014450d012022201641d4e6c4001030000b200c200c41306a20142018417f736a41306c10a2051a20262014417f6a3602000240202720012802d402470d00200141d0026a20274101107920012802d80221270b20012802d002222c20274102746a20223602002001202741016a22273602d8020b2010412c6a22102019470d000b0b203441046a22342036470d000b0b0240202e41ffffffff0371450d00202810230b202c417c6a21182027410274220c210e024003400240200e0d00410021180c020b200e417c6a210e201841046a221828020041014b0d000b0b20012802d402211d202c210e024003400240200c0d004100210c0c020b200c417c6a210c200e280200211a200e41046a210e201a4102490d000b4101210c0b0240201d41ffffffff0371450d00202c10230b024020180d00200c450d05201f2001290318370000201f41186a2009290300370000201f41106a200a290300370000201f41086a200f2903003700000c050b200c450d0420012001280210417f6a360210201b41086a210c02400240201c450d00201c417f6a210e200c20114106746a2118201b20114102746a41a8086a280200210c02400340200c2f01062111200e450d01200e417f6a210e200c20114102746a41a8086a280200210c0c000b0b200c410020111b221b41086a220e2011417f6a410020111b22114106746a220c2900002152200c2900082153200c2900102154200c41186a2900002155200c2900202156200c41286a2900002158200c41306a2900002157200c41386a290000215941012130200c200e201141016a221a4106746a2011417f73220e201b2f01066a41067410a2051a201b41c8056a221c20114105746a220c290000215a200c290008215b200c290010215c200c41186a290000215d200c201c201a4105746a200e201b2f01066a41057410a2051a201b201b2f0106417f6a3b0106201841386a2059370000201841306a2057370000201841286a205837000020182056370020201841186a2055370000201820543700102018205337000820182052370000201f41186a205d370000201f205c370010201f205b370008201f205a370000201b2f0106210c0c010b200c20114106746a200c201141016a220e4106746a2011417f73220c201b2f01066a41067410a2051a201b41c8056a221820236a2018200e4105746a200c201b2f01066a41057410a2051a201b201b2f0106417f6a220c3b0106410021300b200c41ffff037141044b0d0341002122200141086a210e201b210c410021190240024002400240024002400240024002400240024002400240024002400340200c280200221a450d1302400240200c33010422524200520d0041002121201a4100201a2f0106220c1b211a42002052422086200c1b200ead8421520c010b2052422086200ead844280808080707c2152410121210b02400240201a41a8086a220e2052422088a7221841016a220c41027422276a221c28020022102f0106221f200e201841027422236a2226280200221d2f010622146a222f410b490d0020210d05201f450d01201041c0006a2900002158201041386a2900002157201041306a2900002159201041286a290000215a201041206a2900002153201041186a2900002154201041106a290000215520102900082156201041086a201041c8006a201f41067441406a10a2051a201041e0056a290000215e201041d8056a290000215b201041d0056a290000215c20102900c805215d201041c8056a201041e8056a201f41057441606a10a2051a20190d034100211d0c040b201941016a2119201a2f01062116200141f8076a41386a222c201a41086a223420184106746a220e41386a290000370300200141f8076a41306a2236200e41306a290000370300200141f8076a41286a2228200e41286a2900003703002008200e41206a290000370300202b200e41186a290000370300202a200e41106a2900003703002029200e41086a2900003703002001200e2900003703f807200e2034200c4106746a20162018417f7322346a41067410a2051a201d41086a222e20144106746a220e41386a202c290300370000200e41306a2036290300370000200e41286a2028290300370000200e41206a2008290300370000200e41186a202b290300370000200e41106a202a290300370000200e41086a2029290300370000200e20012903f807370000202e201441016a22164106746a201041086a201f41067410a1051a201a2f0106212c200141d0076a41186a2236201a41c8056a222820184105746a220e41186a290000370300200141d0076a41106a2218200e41106a290000370300200141d0076a41086a222e200e41086a2900003703002001200e2900003703d007200e2028200c4105746a2034202c6a41057410a2051a201d41c8056a222c20144105746a220e41186a2036290300370000200e41106a2018290300370000200e41086a202e290300370000200e20012903d007370000202c20164105746a201041c8056a201f41057410a1051a201c202641086a412c20276b10a2051a0240200c201a2f0106221c4f0d00201a20236a41ac086a210e0340200e2802002218200c3b01042018201a360200200e41046a210e201c200c41016a220c470d000b201a2f0106211c0b201a201c417f6a3b0106201d201f201d2f01066a41016a3b0106024020194102490d00201d20164102746a41a8086a201041a8086a201f41027441046a10a1051a2016202f41026a4f0d00201f41016a2118201d20144102746a41ac086a210c2016210e0340200c280200221c200e3b0104201c201d360200200c41046a210c200e41016a210e2018417f6a22180d000b0b20101023024020222021417f73724101710d0020194101470d102016410020211b20116a2111201a20236a41a8086a280200211b0b2052a7210e201a220c2f01062218450d064101212220184105490d010c140b0b41d4dac4004120418c94c700102d000b20102802a808211d201041a8086a220c201041ac086a201f41027410a2051a4100210e201d41003602000340200c280200221c200e3b0104201c2010360200200c41046a210c201f200e41016a220e470d000b2019417f6a211c20102f0106211f0b2010201f417f6a3b0106201a20184106746a220c41206a220e2900002152200e2053370000200c41186a220e2900002153200e2054370000200c41106a220e2900002154200e2055370000200c41086a220e2900002155200e2056370000200c41c0006a220e2900002156200e2058370000200c41386a220e2900002158200e2057370000200c41306a220e2900002157200e2059370000200c41286a220c2900002159200c205a370000201a20184105746a220c41d8056a220e290000215a200e205b370000200c41d0056a220e290000215b200e205c370000200c41c8056a220e290000215c200e205d370000200c41e0056a220c290000215d200c205e3700002026280200210c02402019450d00201d450d052019417f6a201c470d06200c2f01062218410a4b0d07200c20184106746a220e41c0006a2056370000200e41386a2058370000200e41306a2057370000200e41286a2059370000200e41206a2052370000200e41186a2053370000200e41106a2054370000200e41086a2055370000200c20184105746a220e41e0056a205d370000200e41d8056a205a370000200e41d0056a205b370000200e41c8056a205c370000200c201841016a220e4102746a41a8086a2218201d360200200c200c2f010641016a3b010620182802002218200e3b01042018200c3602000c020b200c2f01062218410b4f0d07200c20184106746a220e41c0006a2056370000200e41386a2058370000200e41306a2057370000200e41286a2059370000200e41206a2052370000200e41186a2053370000200e41106a2054370000200e41086a2055370000200c20184105746a220e41d8056a205a370000200e41d0056a205b370000200e41c8056a205c370000200e41e0056a205d370000200c200c2f010641016a3b01060c010b0240024002402014450d00201d2014417f6a220e4105746a220c41e0056a290000215e200c41d8056a290000215b200c41d0056a290000215c200c41c8056a290000215d201d200e4106746a220c41c0006a2900002158200c41386a2900002157200c41306a2900002159200c41286a290000215a200c41206a2900002153200c41186a2900002154200c41106a2900002155200c41086a290000215620190d014100210e0c020b41d4dac4004120418c94c700102d000b201d20144102746a41a8086a280200220e41003602002019417f6a211f201d2f010621140b201d2014417f6a3b0106201a20184106746a220c41206a221d2900002152201d2053370000200c41186a221d2900002153201d2054370000200c41106a221d2900002154201d2055370000200c41086a221d2900002155201d2056370000200c41c0006a221d2900002156201d2058370000200c41386a221d2900002158201d2057370000200c41306a221d2900002157201d2059370000200c41286a220c2900002159200c205a370000201a20184105746a220c41d8056a2218290000215a2018205b370000200c41d0056a2218290000215b2018205c370000200c41c8056a2218290000215c2018205d370000200c41e0056a220c290000215d200c205e370000201c280200211802402019450d00200e450d082019417f6a201f470d09024020182f0106220c410a4b0d00201841c8006a201841086a200c41067410a2051a201841386a2058370000201841306a2057370000201841286a2059370000201841186a2053370000201841106a205437000020182055370008201841c0006a2056370000201841206a2052370000201841e8056a201841c8056a200c41057410a2051a201841e0056a205d370000201841d8056a205a370000201841d0056a205b3700002018205c3700c805201841ac086a201841a8086a220c20182f010641027441046a10a2051a2018200e3602a808201820182f010641016a220e3b0106200e41ffff037141016a211c4100210e0340200c280200221a200e3b0104201a2018360200200c41046a210c201c200e41016a220e470d000c030b0b41dcd9c4004127418c94c700102d000b20182f0106220c410b4f0d09201841c8006a201841086a200c41067410a2051a201841386a2058370000201841306a2057370000201841286a2059370000201841186a2053370000201841106a205437000020182055370008201841c0006a2056370000201841206a2052370000201841e8056a201841c8056a200c41057410a2051a201841e0056a205d370000201841d8056a205a370000201841d0056a205b3700002018205c3700c805201820182f010641016a3b01060b2022417f732021710d010c0e0b0240200e2802042218450d00200e280200221a2802a808210c200e2018417f6a360204200e200c360200200c4100360200201a10230c0e0b41b3dac4004121418c94c700102d000b2011201b2f0106490d084100210e024003400240201b280200220c0d00410021114100210c0c020b200e41016a210e201b2f01042111200c211b2011200c2f01064f0d000b0b201141016a21110240200e0d00200c211b0c0d0b200c20114102746a41a8086a280200211b41002111200e417f6a220c450d0c0340201b2802a808211b200c417f6a220c0d000c0d0b0b41d095c700412b41dcdbc400102d000b4183dac4004130418c94c700102d000b41dcd9c4004127418c94c700102d000b41dcd9c4004127418c94c700102d000b41d095c700412b41f4dac400102d000b4183dac4004130418c94c700102d000b41dcd9c4004127418c94c700102d000b41f58ac7004128418c94c700102d000b201141016a21110c030b200b200c41b4e6c4001030000b41ecdbc4004135418c94c700102d000b200b201041a4e6c4001030000b2030450d002011201b2f0106490d000340201b280200220c450d01201b2f0104210e200c211b200e200c2f01064f0d000b0b0240202d450d00202d41306c450d00203510230b20012802fc01220c450d00200c41306c450d0020012802f80110230b2025450d03202541306c450d03202410230c030b201f2001290318370000201f41186a2009290300370000201f41106a200a290300370000201f41086a200f2903003700000b2025450d01202541306c450d01202410230c010b2004410041d20810a0051a41d8081021220c450d0d200c4100360200200c41046a200141f8076a41d40810a1051a200c200e28020022113602a808200e200c360200200e200e280204221a41016a360204201141003b01042011200c360200200141d0026a41026a221c203c2d00003a0000201f203d2903003703002010203e2903003703002014203f2903003703002008204029030037030020162041290000370000200120012f01ac023b01d002200120012903f8013703f807203620422903003703002035204329030037030020342044290300370300200120012903b0023703e804201a201d470d01200c2f01062211410a4b0d03200c20114106746a220e410a6a201c2d00003a0000200e41086a20012f01d0023b0000200e41176a2030360000200e41136a202f360000200e410f6a202e360000200e410b6a202d360000200e41c0006a2016290000370000200e413b6a2008290300370000200e41236a201f290300370000200e411b6a20012903f807370000200e41336a2014290300370000200e412b6a2010290300370000200c20114105746a220e41e0056a2036290300370000200e41d8056a2035290300370000200e41d0056a2034290300370000200e41c8056a20012903e804370000200c201141016a220e4102746a41a8086a2018360200200c200e3b01062018200c3602002018200e3b010441001a201b1a0b201e2020470d010c030b0b4183dac4004130418c94c700102d000b41dcd9c4004127418c94c700102d000b201741ffffff1f71450d05201510230c050b2014417f6a2114201641206a21162019210c0c000b0b1033000b1032000b200b200c4194e6c4001030000b200b41016a210b0240201341ffffff3f71450d00201210230b200b2003470d000b2001280208220c450d00200128021021170240200128020c220e450d000340200c2802a808210c200e417f6a220e0d000b0b02402017450d00410021080340024002400240200c450d002017417f6a21172008200c2f0106490d0141002111034002400240200c280200220e0d00410021084100210e0c010b201141016a2111200c2f010421080b200c1023200e210c2008200e2f01064f0d000b200841016a2108024020110d00200e210c0c030b200e20084102746a41a8086a280200210c410021082011417f6a220e450d020340200c2802a808210c200e417f6a220e0d000c030b0b41d095c700412b41c491c700102d000b200841016a21080b20170d000b0b200c450d00200c280200210e200c1023200e450d000340200e280200210c200e1023200c210e200c0d000b0b200141003602b004200141003602a80402402002280200220b450d00200141a8046a41086a21422000280200210c200141e8046a41186a2133200141d0076a41106a2146200141d0076a41086a2147200141d0026a41016a223b41286a2149203b41206a214a200141f5026a2145200b210e41002125024002400340200e20254d0d01200141d0076a41186a2248200c2025412c6c22416a220841246a29000037030020462008411c6a2900003703002047200841146a2900003703002001200829000c3703d00702402008280208450d00410021300340200141c8046a41186a200c20416a280200203041306c6a220c41186a220e290300370300200141c8046a41106a200c41106a2208290300370300200141c8046a41086a200c41086a22112903003703002001200c2903003703c804200141386a41186a221e2048290300370300200141386a41106a22152046290300370300200141386a41086a221f2047290300370300200120012903d007370338200141003a0058200141b8016a41186a2206200e290000370300200141b8016a41106a22102008290000370300200141b8016a41086a220720112900003703004101211d200141013a00d8012001200c2900003703b8010240024020012802a80422180d0041002118410021140c010b2018211a20012802ac04221b211c02400340201a41286a210c201a2f0106221d41216c210e41002111024002400340201121080240200e0d00201d21080c020b02400240200141386a200c41606a412010a3052211450d0041012117201141004e0d010c030b200c2d00002211450d03417f410120111b21170b200841016a2111200e415f6a210e200c41216a210c2017417f470d000b0b0240201c0d004101211d0c030b201c417f6a211c201a20084102746a41a0036a280200211a0c010b0b4100211d0b2018211a0340201a41286a210c201a2f0106221c41216c210e41002111024002400340201121080240200e0d00201c21080c020b02400240200141b8016a200c41606a412010a3052211450d0041012117201141004e0d010c030b200c2d000022114101460d03417f4101201141014b1b21170b200841016a2111200e415f6a210e200c41216a210c2017417f470d000b0b0240201b0d00410021140c030b201b417f6a211b201a20084102746a41a0036a280200211a0c010b0b201a20084102746a41f4026a21140b200141a0036a41186a2238201e290300370300200141a0036a41106a22392015290300370300200141a0036a41086a223a201f290300370300200120012903383703a003200141003a00c003024002402018450d0020012802ac04211a0c010b200141f8076a410041eb0210a0051a20494100360000204a4200370000203b41186a4200370000203b41106a4200370000203b41086a4200370000203b420037000041a00310212218450d074100211a201841003b010620184100360200201841086a200141f8076a41eb0210a1051a20184198036a204529000037000020184193036a200141d0026a41206a2900003700002018418b036a200141d0026a41186a29000037000020184183036a200141d0026a41106a290000370000201841fb026a200141d0026a41086a290000370000201820012900d0023700f302200141003602ac04200120183602a8040b024002400340201841286a210c20182f0106221b41216c210e4100211102400340201121080240200e0d00201b21080c020b02400240200141a0036a200c41606a412010a3052211450d0041012117201141004e0d010c030b200c2d00002211450d04417f410120111b21170b200841016a2111200e415f6a210e200c41216a210c2017417f470d000b0b0240201a450d00201a417f6a211a201820084102746a41a0036a28020021180c010b0b203320012903a003370000203341086a203a290300370000203341106a2039290300370000203341186a2038290300370000203341206a200141a0036a41206a2d00003a0000200120423602fc04200120083602f804200120183602f0044100210c200141003602ec042001200141a8046a3602f4040c010b200120423602fc04200120083602f804200120183602f0042001201a3602ec042001200141a8046a3602f4044101210c0b2001200c3602e804200141f8076a41086a2235201f290300370300200141f8076a41106a22362015290300370300200141f8076a41186a2228201e290300370300200141f8076a41206a221c200141386a41206a2d00003a0000200120012903383703f80741341021220c450d06200c4200370208200c428180808010370200200c20012903f807370210200c20012f00d0023b0031200c41186a2035290300370200200c41206a2036290300370200200c41286a2028290300370200200c41306a201c2d00003a0000200c41336a200141d0026a41026a221e2d00003a000002400240024002400240200141e8046a200c10ba04280200222428020041016a220c41014d0d002024200c3602002038200629030037030020392010290300370300203a2007290300370300200120012903b8013703a003200141013a00c0030240024020012802a8042218450d0020012802ac04211a0c010b200141f8076a410041eb0210a0051a20494100360000204a4200370000203b41186a4200370000203b41106a4200370000203b41086a4200370000203b420037000041a00310212218450d0c4100211a201841003b010620184100360200201841086a200141f8076a41eb0210a1051a20184198036a204529000037000020184193036a200141d0026a41206a2900003700002018418b036a200141d0026a41186a29000037000020184183036a200141d0026a41106a290000370000201841fb026a200141d0026a41086a290000370000201820012900d0023700f302200141003602ac04200120183602a8040b024002400340201841286a210c20182f0106221b41216c210e4100211102400340201121080240200e0d00201b21080c020b02400240200141a0036a200c41606a412010a3052211450d0041012117201141004e0d010c030b200c2d000022114101460d04417f4101201141014b1b21170b200841016a2111200e415f6a210e200c41216a210c2017417f470d000b0b0240201a450d00201a417f6a211a201820084102746a41a0036a28020021180c010b0b203320012903a003370000203341086a203a290300370000203341106a2039290300370000203341186a2038290300370000203341206a200141a0036a41206a2d00003a0000200120423602fc04200120083602f804200120183602f0044100210c200141003602ec042001200141a8046a3602f4040c010b200120423602fc04200120083602f804200120183602f0042001201a3602ec042001200141a8046a3602f4044101210c0b2001200c3602e804203520072903003703002036201029030037030020282006290300370300201c200141b8016a41206a2d00003a0000200120012903b8013703f80741341021220c450d0b200c4200370208200c428180808010370200200c20012903f807370210200c20012f00d0023b0031200c41186a2035290300370200200c41206a2036290300370200200c41286a2028290300370200200c41306a201c2d00003a0000200c41336a201e2d00003a0000200141e8046a200c10ba042802002223280200220e41016a220c41014d0d002023200c36020002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240201d450d0020140d03202428020041016a220c41014d0d172024200c36020020232802080d0a2023417f360208202328020c220c0d014100210c0c020b2014450d03200141f8076a202410bb042001280284082144200128028008214e20012802fc07213120012802f807213c200141f8076a202310bb042001280284082143200128028008214f20012802fc0721400240203c20012802f807223f460d00203c28020841016a220c41004c0d08203c200c360208203f280208220c41016a220e41004c0d09203f200e360208203c41106a203f41106a412010a3050d07203c2d0030203f2d0030470d07203f200c360208203c203c280208417f6a3602080b20402043410274222c6a211c20312044410274222b6a210c4100211d41002118202b450d0541002118201c2111200c2117034020402011460d0602402017417c6a2217280200220e2011417c6a22112802002208460d00200e28020841016a221a41004c0d0e200e201a3602082008280208221a41016a221b41004c0d0f2008201b360208200e41106a200841106a412010a3050d06200e2d003020082d0030470d062008201a360208200e200e280208417f6a3602080b201841016a211820312017470d000c060b0b200c200c280200417f6a3602000240202328020c220c2802000d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10d602200c28020c210e0b200e200e280204417f6a360204200c28020c220c2802040d00200c10230b202328020c220c200c280204417f6a360204202328020c220c2802040d00200c10230b202328020841016a210c0b2023200c3602080c150b200e417e4f0d132023200e41026a36020020242802080d072024417f36020802400240202428020c220c0d004100210c0c010b200c200c280200417f6a3602000240202428020c220c2802000d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10d602200c28020c210e0b200e200e280204417f6a360204200c28020c220c2802040d00200c10230b202428020c220c200c280204417f6a360204202428020c220c2802040d00200c10230b202428020841016a210c0b2024200c3602082024202336020c0c150b202428020041016a220c41014d0d122024200c36020020232802080d072023417f3602080240202328020c220c0d00202341003602080c140b200c200c280200417f6a3602000240202328020c220c2802000d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10d602200c28020c210e0b200e200e280204417f6a360204200c28020c220c2802040d00200c10230b202328020c220c200c280204417f6a360204202328020c220c2802040d00200c10230b2023202328020841016a3602080c130b2008201a360208200e200e280208417f6a3602080b2001410036028008200142043703f807204420186b210e0240204320186b221241016a2217450d002017201c20406b4102762208200820174b1b211d0b02400240200e0d00410021080c010b200e200c20316b41027622082008200e4b1b21080b0240201d20086a2208201d4f0d0041002111410421224100211e2040211a0240410041ff01710e030d0e000d0b410021080c0e0b200141f8076a41002008107920012802f8072222200128028008221e4102746a210802402017450d002040202c6a211b2043417f7320186a2117204021110340201b2011460d012011280200221828020041016a221a41014d0d122018201a36020020082018360200201e41016a211e200841046a2108201141046a2111201741016a221820174f211a20182117201a0d000b0b0240200e450d000240200c20316b4102762211200e4d0d002011200e417f736a220e20114f0d01200c200e4102746b417c6a210c0b200c2031460d000340200c417c6a220c280200220e28020041016a221141014d0d12200e20113602002008200e360200201e41016a211e200841046a21082031200c470d000b0b2001201e360280080c0e0b203f200c360208203c203c280208417f6a360208204fad4220862040ad842252204ead4220862031ad842253204420434b221e1b2254a7211d024020432044201e1b2215410274220e450d00201d200e6a211c41012117201d2108201d21110340024002402017450d00201c20086b41027620174d0d03200820174102746a21080c010b201c2008460d020b2011280200221828020041016a220c41014d0d112018200c3602002008280200220c2802080d09201141046a2111200c417f360208410021174100211a0240200c28020c221b450d00201b201b280200417f6a3602000240200c28020c221a2802000d000240201a28020c221b450d00201b201b280200417f6a360200201a28020c221b2802000d000240201b28020c450d00201b410c6a10d602201a28020c211b0b201b201b280204417f6a360204201a28020c221a2802040d00201a10230b200c28020c221a201a280204417f6a360204200c28020c221a2802040d00201a10230b200c28020841016a211a0b200841046a2108200c201a360208200c201836020c201c2011470d000b0b2015450d08024020442043201e1b22170d004100410041a4e7c4001030000b20532052201e1b2252a72218280200220828020041016a220c41014d0d0f2008200c360200201d280200220c2802080d09200c417f36020802400240200c28020c22110d00410021110c010b20112011280200417f6a3602000240200c28020c22112802000d000240201128020c221a450d00201a201a280200417f6a360200201128020c221a2802000d000240201a28020c450d00201a410c6a10d602201128020c211a0b201a201a280204417f6a360204201128020c22112802040d00201110230b200c28020c22112011280204417f6a360204200c28020c22112802040d00201110230b200c28020841016a21110b2052422088215220544220882153200c2011360208200c200836020c201741027421082018210c0340200c28020022112011280200417f6a3602000240200c28020022112802000d000240201128020c2217450d0020172017280200417f6a360200201128020c22172802000d000240201728020c450d002017410c6a10d602201128020c21170b20172017280204417f6a360204201128020c22112802040d00201110230b200c28020022112011280204417f6a360204200c28020022112802040d00201110230b200c41046a210c2008417c6a22080d000b02402052500d002052a7410274450d00201810230b201d210c0340200c28020022082008280200417f6a3602000240200c28020022082802000d000240200828020c2211450d0020112011280200417f6a360200200828020c22112802000d000240201128020c450d002011410c6a10d602200828020c21110b20112011280204417f6a360204200828020c22082802040d00200810230b200c28020022082008280204417f6a360204200c28020022082802040d00200810230b200c41046a210c200e417c6a220e0d000b02402053500d002053a7410274450d00201d10230b203f203f280200417f6a220c360200203041016a2130200c0d0e0240203f28020c220c450d00200c200c280200417f6a360200203f28020c220c2802000d000240200c28020c450d00200c410c6a10d602203f28020c210c0b200c200c280204417f6a360204203f28020c220c2802040d00200c10230b203f203f280204417f6a220c360204200c0d0e203f10230c0e0b41a795c700411820014188046a4184e7c40041c095c7001034000b41a795c700411820014188046a4184e7c40041c095c7001034000b41c394c700411020014188046a41fc95c70041d494c7001034000b41c394c700411020014188046a41fc95c70041d494c7001034000b41c394c700411020014188046a41fc95c70041d494c7001034000b41a795c700411820014188046a4184e7c40041c095c7001034000b41a795c700411820014188046a4184e7c40041c095c7001034000b41c394c700411020014188046a41fc95c70041d494c7001034000b410041004194e7c4001030000b41c394c700411020014188046a41fc95c70041d494c7001034000b410121080c010b410221080b034002400240024002400240024020080e03000103030b200e450d06200c20316b410276220841002008200e6b2218201820084b1b22084d0d06200c20084102746b417c6a220c2802002208280200221b41016a41014b0d010c080b0240024020170d00410021170c010b2017417f6a2117201c201a460d00201a280200220828020041016a221841014d0d08201a41046a211a200820183602004100211820080d040b200e450d05200c20316b410276220841002008200e6b2218201820084b1b22084d0d05200c20084102746b417c6a220c2802002208280200221b41016a41014d0d070b200e417f6a210e410221180c010b2017450d03201c201a460d03201a2802002208280200221b41016a41014d0d052017417f6a2117201a41046a211a410121180b2008201b41016a3602000b0240201e20012802fc07470d00024002400240024020180e03010200010b0240200e0d004100211b0c030b200e200c20316b410276221b201b200e4b1b211b0c020b4100211d4100211b02402017450d002017201c201a6b410276221b201b20174b1b211b0b0240200e450d00200e200c20316b410276221d201d200e4b1b211d0b417f201b201d6a221d201d201b491b211b0c010b024020170d004100211b0c010b2017201c201a6b410276221b201b20174b1b211b0b200141f8076a201e417f201b41016a221d201d201b491b107920012802f80721220b202220116a20083602002001201e41016a221e36028008201141046a2111024002400240201841ff01710e03000102000b410121080c020b410221080c010b410021080c000b0b20012802fc072151200141f8016a41186a224b4200370300200141f8016a41106a224c4200370300200141f8016a41086a224d4200370300200142003703f8012038420037030020394200370300203a4200370300200142003703a0034100211402400240201e0d00427f2154427f215541002126410021344100213241002127410021290c010b201e417f6a2110427f21544101210c41002126427f2155410021344100211b427f2158427f2152427f21530240024002400240024002400340200c211a2022201b4102746a220e280200220c28020841016a41004c0d010240200c2d00300d00200e280200220c28020841016a220e41004c0d03200c200e360208200141d0026a41186a221c200c41286a290000370300200141d0026a41106a221d200c41206a290000370300200141d0026a41086a2215200c41186a290000370300200c200c280208417f6a3602082001200c2900103703d002201e201a41002010201b4b1b220c4d0d042022200c4102746a280200220c28020841016a220e41004c0d05200c200e3602082033200c41286a290000370300200141e8046a41106a221f200c41206a290000370300200141e8046a41086a2206200c41186a290000370300200c200c280208417f6a3602082001200c2900103703e804201e201b201e201b1b417f6a220c4d0d062022200c4102746a280200220c28020841016a220e41004c0d07200c200e3602082028200c41286a2900003703002036200c41206a2900003703002035200c41186a290000370300200c200c280208417f6a3602082001200c2900103703f807200041086a280200412c6c220e2108200028020022112117024003402017210c2008450d010240200141d0026a200c410c6a2218460d00200841546a2108200c412c6a21172018200141d0026a412010a3050d010b0b200c41086a28020041306c2108200c280200211703402017210c2008450d010240200141e8046a200c460d00200841506a2108200c41306a2117200c200141e8046a412010a3050d010b0b2058200c41206a2903002257582052200c41286a29030022565820522056511b0d00204b2033290300370300204c201f290300370300204d2006290300370300203a20152903003703002039201d2903003703002038201c290300370300200120012903e8043703f801200120012903d0023703a003410121342057215420562155201b21262056215320572158205621520b03402011210c200e450d010240200141d0026a200c410c6a2208460d00200e41546a210e200c412c6a21112008200141d0026a412010a3050d010b0b200c41086a28020041306c210e200c280200210803402008210c200e450d010240200141f8076a200c460d00200e41506a210e200c41306a2108200c200141f8076a412010a3050d010b0b20542158205321522054200c41206a2903002257582053200c41286a29030022565820532056511b0d00204b2028290300370300204c2036290300370300204d2035290300370300203a20152903003703002039201d2903003703002038201c290300370300200120012903f8073703f801200120012903d0023703a003410021342057215420562155201b21262056215320572158205621520b0240201a201e470d00201e213220342127202621290c080b201a41016a210c201a211b0c000b0b41a795c700411820014188046a4184e7c40041c095c7001034000b41a795c700411820014188046a4184e7c40041c095c7001034000b200c201e41b4e7c4001030000b41a795c700411820014188046a4184e7c40041c095c7001034000b200c201e41c4e7c4001030000b41a795c700411820014188046a4184e7c40041c095c7001034000b200141003602d802200142043703d002202920276a21500240024020320d00410121214100210c0c010b201e417f6a21374101210c205041017121074100211441002110410121210240024002400240024002400240024002400340200c2119202220104102746a222a280200221c28020841016a220c41004c0d01201c200c3602080240201c2d00300d00201e2010417f6a203720101b223d4b222e450d032022203d4102746a222f280200222d28020841016a220c41004c0d04202d200c36020802400240200041086a223e280200220c0d002019210c2010211d0c010b20002802002218200c412c6c6a211b202d41106a211120102026462034457121164100211a2010211d034002400240201c41106a220c2018410c6a220e460d00200e200c412010a3050d010b201841086a2206280200221f41306c210e4100210820182802002215210c02400340200e450d022011200c460d01200c2011412010a3052117200841016a2108200e41506a210e200c41306a210c20170d000b20174541016a41017120086a417f6a21080b2015200841306c6a220c2903202153200c41286a2903002152024002400240201d410171450d0020070d01427f205220557c205320547c2256205354220ead7c2253200e205320525420532052511b220e1b2152427f2056200e1b21530c020b024020070d004200205220557d2053205454ad7d2256205320547d2258205356205620525620562052511b220e1b215242002058200e1b21530c020b427f205220557c205320547c2256205354220ead7c2253200e205320525420532052511b220e1b2152427f2056200e1b21530c010b4200205220557d2053205454ad7d2256205320547d2258205356205620525620562052511b220e1b215242002058200e1b21530b02402053205284500d00200c41206a220c2053370300200c20523703080c010b200c200c41306a201f2008417f736a41306c10a2051a2006201f417f6a36020041002127410020212025201a461b212102402016450d00202621292026211d0c010b201e20104d0d08202a280200220c28020041016a220e41014d0d10200c200e360200202e450d09202f280200220e28020041016a220841014d0d10200e20083602000240201420012802d402470d00200141d0026a2014410110a50120012802d80221140b20012802d00220144103746a2208200e3602042008200c3602002001201441016a22143602d80220342127202621292010211d0b02402018412c6a2218201b460d00201a41016a211a0c010b0b201d41016a210c0b201e200c41002037201d4b1b220c4d0d072022200c4102746a280200222e28020841016a220c41004c0d08202e200c3602080240203e280200220e450d0020002802002218200e412c6c6a21152010202646203441014671212f4100211a2022201041016a4100203720104b1b223d4102746a213e202e41106a2111201c41106a211b034002400240201b2018410c6a220c460d00200c201b412010a3050d010b201841086a2216280200220641306c210e410021082018280200221f210c02400340200e450d022011200c460d01200c2011412010a3052117200841016a2108200e41506a210e200c41306a210c20170d000b20174541016a41017120086a417f6a21080b201f200841306c6a220c2903202153200c41286a2903002152024002400240201d410171450d0020070d014200205220557d2053205454ad7d2256205320547d2258205356205620525620562052511b220e1b215242002058200e1b21530c020b024020070d00427f205220557c205320547c2256205354220ead7c2253200e205320525420532052511b220e1b2152427f2056200e1b21530c020b4200205220557d2053205454ad7d2256205320547d2258205356205620525620562052511b220e1b215242002058200e1b21530c010b427f205220557c205320547c2256205354220ead7c2253200e205320525420532052511b220e1b2152427f2056200e1b21530b02402053205284500d00200c41206a220c2053370300200c20523703080c010b200c200c41306a20062008417f736a41306c10a2051a20162006417f6a360200410020212025201a461b2121410121270240202f450d00202621292026211d0c010b201e20104d0d0c202a280200220c28020041016a220e41014d0d10200c200e360200201e203d4d0d0d203e280200220e28020041016a220841014d0d10200e20083602000240201420012802d402470d00200141d0026a2014410110a50120012802d80221140b20012802d00220144103746a2208200e3602042008200c3602002001201441016a22143602d80220342127202621292010211d0b201a41016a211a2018412c6a22182015470d000b202e280208210c0b202e200c417f6a360208202d202d280208417f6a360208201c280208210c0b201c200c417f6a360208024020192032470d00201e210c0c0b0b201941016a210c20192110201e20194b0d000b2019201e41d4e7c4001030000b41a795c700411820014188046a4184e7c40041c095c7001034000b203d201e41e4e7c4001030000b41a795c700411820014188046a4184e7c40041c095c7001034000b2010201e41f4e7c4001030000b203d201e4184e8c4001030000b200c201e4194e8c4001030000b41a795c700411820014188046a4184e7c40041c095c7001034000b2010201e41a4e8c4001030000b203d201e41b4e8c4001030000b0240024020274101470d002029200c417f6a460d010b41c0001021220e450d0d200e20012903a003370000200e20012903f801370020200e41186a2038290300370000200e41106a2039290300370000200e41086a203a290300370000200e41286a204d290300370000200e41306a204c290300370000200e41386a204b29030037000002400240205020124b0d002043417f6a221b450d014100211102400240024002400240034020112043460d01204020114102746a2218280200220c280200220841016a221741014d0d0a200c2017360200200c28020841016a41004c0d02200c20083602002033200c41286a290000370300200141e8046a41106a200c41206a290000370300200141e8046a41086a200c41186a2900003703002001200c2900103703e8042043201141016a22114d0d03204020114102746a221a280200220c280200220841016a221741014d0d0a200c2017360200200c28020841016a41004c0d04200c20083602002028200c41286a2900003703002036200c41206a2900003703002035200c41186a2900003703002001200c2900103703f8074100210c02400340200c41c000460d01200e200c6a2108200c41206a210c2008200141e8046a412010a3050d000b4100210c0340200c41c000460d01200e200c6a2108200c41206a210c2008200141f8076a412010a3050d000c090b0b2018280200220828020041016a220c41014d0d0a2008200c360200201a280200220c2802080d05200c417f36020802400240200c28020c22170d00410021170c010b20172017280200417f6a3602000240200c28020c22172802000d000240201728020c2218450d0020182018280200417f6a360200201728020c22182802000d000240201828020c450d002018410c6a10d602201728020c21180b20182018280204417f6a360204201728020c22172802040d00201710230b200c28020c22172017280204417f6a360204200c28020c22172802040d00201710230b200c28020841016a21170b200c2017360208200c200836020c2011201b470d000c070b0b2043204341e4e8c4001030000b41a795c700411820014188046a4184e7c40041c095c7001034000b2011204341f4e8c4001030000b41a795c700411820014188046a4184e7c40041c095c7001034000b41c394c700411020014188046a41fc95c70041d494c7001034000b02402044417f6a221b450d004100211102400240024002400240034020112044460d01203120114102746a2218280200220c280200220841016a221741014d0d0a200c2017360200200c28020841016a41004c0d02200c20083602002033200c41286a290000370300200141e8046a41106a200c41206a290000370300200141e8046a41086a200c41186a2900003703002001200c2900103703e8042044201141016a22114d0d03203120114102746a221a280200220c280200220841016a221741014d0d0a200c2017360200200c28020841016a41004c0d04200c20083602002028200c41286a2900003703002036200c41206a2900003703002035200c41186a2900003703002001200c2900103703f8074100210c02400340200c41c000460d01200e200c6a2108200c41206a210c2008200141e8046a412010a3050d000b4100210c0340200c41c000460d01200e200c6a2108200c41206a210c2008200141f8076a412010a3050d000c080b0b2018280200220828020041016a220c41014d0d0a2008200c360200201a280200220c2802080d05200c417f36020802400240200c28020c22170d00410021170c010b20172017280200417f6a3602000240200c28020c22172802000d000240201728020c2218450d0020182018280200417f6a360200201728020c22182802000d000240201828020c450d002018410c6a10d602201728020c21180b20182018280204417f6a360204201728020c22172802040d00201710230b200c28020c22172017280204417f6a360204200c28020c22172802040d00201710230b200c28020841016a21170b200c2017360208200c200836020c2011201b470d000c060b0b2044204441c4e8c4001030000b41a795c700411820014188046a4184e7c40041c095c7001034000b2011204441d4e8c4001030000b41a795c700411820014188046a4184e7c40041c095c7001034000b41c394c700411020014188046a41fc95c70041d494c7001034000b202328020041016a220c41014d0d032023200c360200024020242802080d002024417f36020802400240202428020c220c0d004100210c0c010b200c200c280200417f6a3602000240202428020c220c2802000d000240200c28020c2208450d0020082008280200417f6a360200200c28020c22082802000d000240200828020c450d002008410c6a10d602200c28020c21080b20082008280204417f6a360204200c28020c220c2802040d00200c10230b202428020c220c200c280204417f6a360204202428020c220c2802040d00200c10230b202428020841016a210c0b2024200c3602082024202336020c200e10230c020b41c394c700411020014188046a41fc95c70041d494c7001034000b202428020041016a220c41014d0d022024200c360200024020232802080d002023417f36020802400240202328020c220c0d004100210c0c010b200c200c280200417f6a3602000240202328020c220c2802000d000240200c28020c2208450d0020082008280200417f6a360200200c28020c22082802000d000240200828020c450d002008410c6a10d602200c28020c21080b20082008280204417f6a360204200c28020c220c2802040d00200c10230b202328020c220c200c280204417f6a360204202328020c220c2802040d00200c10230b202328020841016a210c0b2023200c3602082023202436020c200e10230c010b41c394c700411020014188046a41fc95c70041d494c7001034000b20012802d002221820144103746a211120012802d402211b2018210e02400240024002402014450d0020182108024003402008280200220c450d010240024002400240200c200841046a280200220e10bc040d00200e200c10bc04450d03200e2802080d09200e417f360208200e28020c22170d01410021170c020b200c2802080d07200c417f36020802400240200c28020c22170d00410021170c010b20172017280200417f6a3602000240200c28020c22172802000d000240201728020c221a450d00201a201a280200417f6a360200201728020c221a2802000d000240201a28020c450d00201a410c6a10d602201728020c211a0b201a201a280204417f6a360204201728020c22172802040d00201710230b200c28020c22172017280204417f6a360204200c28020c22172802040d00201710230b200c28020841016a21170b200c2017360208200c410036020c0c020b20172017280200417f6a3602000240200e28020c22172802000d000240201728020c221a450d00201a201a280200417f6a360200201728020c221a2802000d000240201a28020c450d00201a410c6a10d602201728020c211a0b201a201a280204417f6a360204201728020c22172802040d00201710230b200e28020c22172017280204417f6a360204200e28020c22172802040d00201710230b200e28020841016a21170b200e2017360208200e410036020c0b200e200e280200417f6a2217360200024020170d000240200e28020c2217450d0020172017280200417f6a360200200e28020c22172802000d000240201728020c450d002017410c6a10d602200e28020c21170b20172017280204417f6a360204200e28020c22172802040d00201710230b200e200e280204417f6a221736020420170d00200e10230b200c200c280200417f6a220e3602000240200e0d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10d602200c28020c210e0b200e200e280204417f6a360204200c28020c220e2802040d00200e10230b200c200c280204417f6a220e360204200e0d00200c10230b200841086a22082011470d000c030b0b200841086a210e0b2011200e460d000340200e220c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2208450d0020082008280200417f6a360200200e28020c22082802000d000240200828020c450d002008410c6a10d602200e28020c21080b20082008280204417f6a360204200e28020c220e2802040d00200e10230b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10230b200c41086a210e200c41046a220c28020022082008280200417f6a3602000240200c28020022082802000d000240200828020c2217450d0020172017280200417f6a360200200828020c22172802000d000240201728020c450d002017410c6a10d602200828020c21170b20172017280204417f6a360204200828020c22082802040d00200810230b200c28020022082008280204417f6a360204200c280200220c2802040d00200c10230b2011200e470d000b0b0240201b41ffffffff0171450d00201810230b0240201e450d00201e410274210e2022210c0340200c28020022082008280200417f6a3602000240200c28020022082802000d000240200828020c2211450d0020112011280200417f6a360200200828020c22112802000d000240201128020c450d002011410c6a10d602200828020c21110b20112011280204417f6a360204200828020c22082802040d00200810230b200c28020022082008280204417f6a360204200c28020022082802040d00200810230b200c41046a210c200e417c6a220e0d000b0b0240205141ffffffff0371450d00202210230b02402043450d002040210c0340200c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2208450d0020082008280200417f6a360200200e28020c22082802000d000240200828020c450d002008410c6a10d602200e28020c21080b20082008280204417f6a360204200e28020c220e2802040d00200e10230b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10230b200c41046a210c202c417c6a222c0d000b0b0240204f41ffffffff0371450d00204010230b203f203f280200417f6a220c3602000240200c0d000240203f28020c220c450d00200c200c280200417f6a360200203f28020c220c2802000d000240200c28020c450d00200c410c6a10d602203f28020c210c0b200c200c280204417f6a360204203f28020c220c2802040d00200c10230b203f203f280204417f6a220c360204200c0d00203f10230b202141ff0171211102402044450d002031210c0340200c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2208450d0020082008280200417f6a360200200e28020c22082802000d000240200828020c450d002008410c6a10d602200e28020c21080b20082008280204417f6a360204200e28020c220e2802040d00200e10230b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10230b200c41046a210c202b417c6a222b0d000b0b203020116a2130204e41ffffffff0371450d02203110230c020b41c394c700411020014188046a41fc95c70041d494c7001034000b41c394c700411020014188046a41fc95c70041d494c7001034000b203c203c280200417f6a220c3602000240200c0d000240203c28020c220c450d00200c200c280200417f6a360200203c28020c220c2802000d000240200c28020c450d00200c410c6a10d602203c28020c210c0b200c200c280204417f6a360204203c28020c220c2802040d00200c10230b203c203c280204417f6a220c360204200c0d00203c10230b20232023280200417f6a220c3602000240200c0d000240202328020c220c450d00200c200c280200417f6a360200202328020c220c2802000d000240200c28020c450d00200c410c6a10d602202328020c210c0b200c200c280204417f6a360204202328020c220c2802040d00200c10230b20232023280204417f6a220c360204200c0d00202310230b20242024280200417f6a220c360200200c0d040240202428020c220c450d00200c200c280200417f6a360200202428020c220c2802000d000240200c28020c450d00200c410c6a10d602202428020c210c0b200c200c280204417f6a360204202428020c220c2802040d00200c10230b20242024280204417f6a220c360204200c0d040c030b00000b2023202436020c0b20232023280200417f6a220c3602000240200c0d000240202328020c220c450d00200c200c280200417f6a360200202328020c220c2802000d000240200c28020c450d00200c410c6a10d602202328020c210c0b200c200c280204417f6a360204202328020c220c2802040d00200c10230b20232023280204417f6a220c360204200c0d00202310230b203041016a213020242024280200417f6a220c360200200c0d010240202428020c220c450d00200c200c280200417f6a360200202428020c220c2802000d000240200c28020c450d00200c410c6a10d602202428020c210c0b200c200c280204417f6a360204202428020c220c2802040d00200c10230b20242024280204417f6a220c360204200c0d010b202410230b0240200041086a280200220e20254d0d002000280200220c20416a28020820304d0d020c010b0b2025200e41f4e6c4001030000b202541016a2225200b470d000b20012802a804220c450d0220012802b0042118024020012802ac04220e450d000340200c2802a003210c200e417f6a220e0d000b0b2018450d014100210802400340200c450d014100211102402008200c2f0106490d00034002400240200c280200220e0d00410021084100210e0c010b201141016a2111200c2f010421080b200c1023200e210c2008200e2f01064f0d000b200e210c0b200841016a210e200c20084102746a41f4026a2802002117200c200841216c6a41286a2d0000211a0240024020110d00200e21080c010b200c200e4102746a41a0036a280200210c410021082011417f6a220e450d000340200c2802a003210c200e417f6a220e0d000b0b201a41ff01714102460d032018417f6a211820172017280200417f6a220e3602000240200e0d000240201728020c220e450d00200e200e280200417f6a360200201728020c220e2802000d000240200e28020c450d00200e410c6a10d602201728020c210e0b200e200e280204417f6a360204201728020c220e2802040d00200e10230b20172017280204417f6a220e360204200e0d00201710230b20180d000c030b0b41d095c700412b41c491c700102d000b2025200e41e4e6c4001030000b200c450d00200c280200210e200c1023200e450d000340200e280200210c200e1023200c210e200c0d000b0b200141d0106a24000f0b102a000bdb21011d7f230041b0046b220224000240024002400240024002400240024020002802004101460d00200041146a2802002203200328020041016a360200200041106a28020021042000410c6a2802002105200041086a280200210320002802042106200241e0006a41206a2207200041386a2d00003a0000200241e0006a41186a2208200041306a290000370300200241e0006a41106a2209200041286a290000370300200241e0006a41086a220a200041206a2900003703002002200041186a29000037036020032f0106220b410b490d01200241c0016a410041eb0210a0051a200241d9006a4100360000200241306a41216a4200370000200241c9006a4200370000200241c1006a4200370000200241396a42003700002002420037003141a0031021220c450d05200c41003b0106200c4100360200200c41086a200241c0016a41eb0210a1052107200c4198036a200241d5006a290000370000200c4193036a200241306a41206a290000370000200c418b036a200241306a41186a290000370000200c4183036a200241306a41106a290000370000200c41fb026a200241306a41086a290000370000200c20022900303700f3022002200341ce016a2f00003b01182002200341d0016a2d00003a001a200341d1016a280000210d200341d5016a280000210e200341d9016a280000210f200341dd016a28000021102002200341e7016a2900003701c6012002200341e1016a2900003703c001200328028c0321112007200341ef016a20032f010641796a220041216c10a1052107200c41f4026a20034190036a200041027410a1052108200341063b0106200c20003b01062002412c6a41026a20022d001a3a0000200220022f01183b012c200220022903c001370330200220022901c6013701360240024020044107490d00200441216c20076a220741ba7e6a200741997e6a2207200041ffff0371200441796a22096b41216c10a2051a200741206a200241e0006a41206a2d00003a0000200741186a200241e0006a41186a290300370000200741106a200241e0006a41106a290300370000200741086a200241e0006a41086a29030037000020072002290360370000200441027420086a41686a2107200820094102746a2112200c41066a22002f010020096b21040c010b200341086a200441216c6a220741216a2007200341066a22002f010020046b41216c10a2051a200741206a200241e0006a41206a2d00003a0000200741186a200241e0006a41186a290300370000200741106a200241e0006a41106a290300370000200741086a200241e0006a41086a29030037000020072002290360370000200341f4026a20044102746a221241046a210720002f010020046b21040b20072012200441027410a2051a20122001360200200241146a41026a2002412c6a41026a22132d000022013a0000200020002f010041016a3b0100200241106a41026a221420013a000020022002290136370196012002200229033037039001200220022f012c22003b0114200220003b0110200220022903900137030020022002290196013701060240200328020022070d00410021000c040b20032f01042115200241c0016a4102722116200241306a41016a210a410021000340201320142d00003a0000200220022f01103b012c200220022903003703182002200229010637011e20062000470d03201541ffff0371210802400240024020072f01062200410b490d00200a41286a4100360000200a41206a4200370000200a41186a4200370000200a41106a4200370000200a41086a4200370000200a42003700002016410041ed0210a0051a200241e0006a41086a22004200370300200241e0006a41106a22034200370300200241e0006a41186a22044200370300200241e0006a41206a22094200370300200241e0006a41286a220b420037030020024190016a41256a2217200241306a41256a29000037000020024190016a41206a2218200241306a41206a29000037030020024190016a41186a2219200241306a41186a29000037030020024190016a41106a221a200241306a41106a29000037030020024190016a41086a221b200241306a41086a29000037030020024200370360200220022900303703900141d00310212201450d0920014100360200200141046a200241c0016a41ef0210a1051a20014198036a201729000037000020014193036a20182903003700002001418b036a201929030037000020014183036a201a290300370000200141fb026a201b29030037000020012002290390013700f302200120022903603702a003200141a8036a2000290300370200200141b0036a2003290300370200200141b8036a2004290300370200200141c0036a2009290300370200200141c8036a200b29030037020020024190016a41026a220b200741d0016a2d00003a00002002200741ce016a2f00003b0190012002200741e1016a2900003703c0012002200741e7016a2900003701c601200741d1016a2800002118200741d5016a2800002119200741d9016a280000211a200741dd016a280000211b200728028c03211c200141086a200741ef016a20072f0106220341796a220041216c10a105211d200141f4026a20074190036a200041027410a105211e200141a0036a200741bc036a2003417a6a220941027410a1052117200741063b0106200120003b010602402009450d00410021002017210303402003280200220420003b010420042001360200200341046a21032009200041016a2200470d000b0b200220022f01900122003b0130200220022903c001370360200220022901c6013701662002200b2d000022033a0032200b20033a0000200220003b019001200220022903603703c001200220022901663701c601201541ffff037122034107490d01200841216c201d6a220041ba7e6a200041997e6a220320012f0106200841796a22006b41216c10a2051a2003201036000f2003200f36000b2003200e3600072003200d360003200341026a20132d00003a0000200320022f012c3b000020032002290318370013200341196a200229011e370000201e2008417a6a220341027422046a201e20004102746a220920012f0106221520006b41027410a2051a200920113602002001201541016a22093b01062008410274221520176a416c6a201720046a2204200941ffff0371220820036b41027410a2051a2004200c36020020082003490d02200120156a4188036a2103034020032802002204200041016a22003b010420042001360200200341046a210320002008490d000c030b0b2007200841216c6a220341296a200341086a2201200020086b41216c10a2051a200341176a2010360000200341136a200f3600002003410f6a200e3600002003410b6a200d3600002003410a6a2002412c6a41026a2d00003a0000200120022f012c3b00002003411b6a2002290318370000200341216a200229011e370000200741f4026a2203200841016a220041027422016a2003200841027422046a220320072f0106220920086b41027410a2051a200320113602002007200941016a22033b01062004200741a0036a22086a41086a200820016a2201200341ffff0371220420006b41027410a2051a2001200c360200201541ffff037120044f0d0720072000417f6a22004102746a41a4036a2103034020032802002201200041016a22003b010420012007360200200341046a210320002004490d000c080b0b200741086a200841216c6a220041216a200020072f010620086b41216c10a2051a2000201036000f2000200f36000b2000200e3600072000200d360003200041026a20132d00003a0000200020022f012c3b000020002002290318370013200041196a200229011e370000200741f4026a2204200841016a220941027422156a2004200841027422006a220420072f0106221720086b41027410a2051a200420113602002007201741016a22043b01062000200741a0036a22176a41086a201720156a2215200441ffff0371220420096b41027410a2051a2015200c360200200320044f0d00200720006a41a4036a2100034020002802002203200841016a22083b010420032007360200200041046a210020042008470d000b0b200641016a21002014200b2d00003a0000200220022f0190013b0110200220022903c001370300200220022901c6013701060240200728020022030d002018210d201b2110201a210f2019210e2001210c201c21110c050b20072f010421152018210d201b2110201a210f2019210e20032107201c21112001210c200021060c000b0b20012001280200417f6a2203360200200041086a280200200041106a2802004102746a41f4026a211220030d030240200128020c2200450d0020002000280200417f6a360200200128020c22002802000d000240200028020c450d002000410c6a10d602200128020c21000b20002000280204417f6a360204200128020c22002802040d00200010230b20012001280204417f6a220036020420000d03200110230c030b2003200441216c6a220041296a200041086a220c200b20046b41216c10a2051a200041286a20072d00003a0000200041206a2008290300370000200041186a2009290300370000200041106a200a290300370000200c2002290360370000200320044102746a220041f8026a200041f4026a221220032f010620046b41027410a2051a20122001360200200320032f010641016a3b01060c020b41ecdbc4004135418c94c700102d000b200241b9016a4100360000200241b1016a4200370000200241a9016a4200370000200241a1016a420037000020024199016a42003700002002420037009101200241c0016a410272410041ed0210a0051a200241e0006a41086a22014200370300200241e0006a41106a22044200370300200241e0006a41186a22074200370300200241e0006a41206a2208420037030020024188016a22094200370300200241306a41256a220a20024190016a41256a290000370000200241306a41206a220b20024190016a41206a290000370300200241306a41186a220620024190016a41186a290000370300200241306a41106a221520024190016a41106a290000370300200241306a41086a221720024190016a41086a29000037030020024200370360200220022900900137033041d00310212203450d0120034100360200200341046a200241c0016a41ef0210a1051a20034198036a200a29000037000020034193036a200b2903003700002003418b036a200629030037000020034183036a2015290300370000200341fb026a2017290300370000200320022903303700f302200320022903603702a003200341a8036a2001290300370200200341b0036a2004290300370200200341b8036a2007290300370200200341c0036a2008290300370200200341c8036a20092903003702002003200528020022013602a0032005200336020020052005280204220441016a360204200141003b010420012003360200200241e0006a41026a200241106a41026a2d00003a0000200220022f01103b0160200220022903003703c001200220022901063701c60120042000470d0220032f01062201410a4b0d032003200141216c6a2200410a6a200241e0006a41026a2d00003a0000200041086a20022f01603b0000200041176a2010360000200041136a200f3600002000410f6a200e3600002000410b6a200d3600002000411b6a20022903c001370000200041216a20022901c6013700002003200141016a22004102746a41a0036a200c360200200320014102746a41f4026a2011360200200320003b0106200c20003b0104200c20033602000b200241b0046a240020120f0b102a000b4183dac4004130418c94c700102d000b41dcd9c4004127418c94c700102d000bab0b010c7f230041306b220224002002410036021020024204370308200241003602202002420437031802400240024002400240200128020041016a220341014d0d0020012003360200200241086a41004101107920022802082204200228021022034102746a20013602002002200341016a22053602102001280200220341016a41014d0d002001200341016a360200200241186a41004101107920022802182206200228022022034102746a20013602002002200341016a2207360220200128020041016a220841014d0d00200120083602000340200841016a220341014d0d0120012003360200200128020841016a220941004c0d0220012009360208200128020c2208450d0502402007450d002007410274210a200841106a210b20062109034002400240200928020022032008460d00200328020841016a220c41004c0d072003200c3602082008280208220c41016a220d41004c0d082008200d360208200341106a200b412010a3050d0120032d003020082d0030470d012008200c36020820032003280208417f6a3602080b20012802002103200128020821090c080b200941046a21092008200c36020820032003280208417f6a360208200a417c6a220a0d000b200128020c21080b200828020041016a220341014d0d012008200336020002402005200228020c470d00200241086a20054101107920022802082104200228021021050b200420054102746a20083602002002200541016a2205360210200128020c220328020041016a220841014d0d012003200836020020012001280200417f6a2208360200024020080d000240200128020c2208450d0020082008280200417f6a360200200128020c22082802000d000240200828020c450d002008410c6a10d602200128020c21080b20082008280204417f6a360204200128020c22082802040d00200810230b20012001280204417f6a220836020420080d00200110230b200328020041016a220841014d0d012003200836020002402007200228021c470d00200241186a20074101107920022802182106200228022021070b200620074102746a200336020020012001280208417f6a36020820012001280200417f6a22083602002002200741016a2207360220024020080d000240200128020c2208450d0020082008280200417f6a360200200128020c22082802000d000240200828020c450d002008410c6a10d602200128020c21080b20082008280204417f6a360204200128020c22082802040d00200810230b20012001280204417f6a220836020420080d00200110230b20032802002108200321010c000b0b00000b41a795c7004118200241286a418c96c70041c095c7001034000b41a795c7004118200241286a419ca5c20041c095c7001034000b41a795c7004118200241286a419ca5c20041c095c7001034000b20012003417f6a220336020020012009417f6a360208024020030d000240200128020c2203450d0020032003280200417f6a360200200128020c22032802000d000240200328020c450d002003410c6a10d602200128020c21030b20032003280204417f6a360204200128020c22032802040d00200310230b20012001280204417f6a220336020420030d00200110230b20002001360200200020022903083702042000410c6a200241106a28020036020002402007450d0020074102742108200621030340200328020022092009280200417f6a3602000240200328020022092802000d000240200928020c2201450d0020012001280200417f6a360200200928020c22012802000d000240200128020c450d002001410c6a10d602200928020c21010b20012001280204417f6a360204200928020c22092802040d00200910230b200328020022092009280204417f6a360204200328020022092802040d00200910230b200341046a21032008417c6a22080d000b0b0240200228021c41ffffffff0371450d00200610230b200241306a24000ba50201047f230041106b22022400410021030240024002400240024002400240200028020841016a220441004c0d00200028020c2205450d0620002004360208024020052001470d00410121030c060b200528020841016a220341004c0d01200520033602082001280208220441016a220341004c0d0220012003360208200541106a200141106a412010a3050d034101210320052d003020012d0030470d030c040b41a795c7004118200241086a418c96c70041c095c7001034000b41a795c7004118200241086a418c96c70041c095c7001034000b41a795c7004118200241086a418c96c70041c095c7001034000b410021030b2001200436020820052005280208417f6a360208200028020821040b20002004417f6a3602080b200241106a240020030b13002000410a360204200041f8e9c4003602000b3400200041e4dec40036020420004100360200200041146a410f360200200041106a41e8f4c400360200200041086a42063702000b2b01017f02404101102122020d001033000b200042818080801037020420002002360200200241003a00000b6301027f230041206b22022400200241003602082002420837030002404104102122030d001033000b20024204370214200220033602104100200241106a1061200041086a200228021836020020002002290310370200200210af04200241206a24000be00101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002400240412010212206450d0020062002290300370000200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000412010212203450d0120032006290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a29000037000020061023200042a0808080800437020420002003360200200241206a24000f0b1033000b102a000bae0101017f0240410410212202450d002002410036000020024104410810252202450d00200241003a000420024108411510252202450d00200242003700052002410d6a420037000020024115412a10252202450d00200242003700152002411d6a42003700002002412a41d40010252202450d002002420037003520024200370025200042d4808080d008370204200020023602002002413d6a42003700002002412d6a42003700000f0b102a000bcc0405067f017e017f017e047f230041e0006b22002400200041d7ddc400411010cd01200028020421010240200028020022024101470d0041d7ddc400ad428080808080028410110b200041306a41186a22034200370300200041306a41106a22044200370300200041306a41086a220542003703002000420037033041e4dec400ad4280808080e000842206100c22072900002108200041d0006a41086a2209200741086a2900003703002000200837035020071023200520092903003703002000200029035037033041d0ffc400ad4280808080e00184100c220729000021082009200741086a2900003703002000200837035020071023200420002903502208370300200041106a41086a220a2005290300370300200041106a41106a220b2008370300200041106a41186a220c20092903003703002000200029033037031020002001410020021b360230200041106aad4280808080800484200041306aad4280808080c00084100e20004101360208200342003703002004420037030020054200370300200042003703302006100c220729000021062009200741086a2900003703002000200637035020071023200520092903003703002000200029035037033041d483c500ad4280808080e00184100c220729000021062009200741086a2900003703002000200637035020071023200420002903502206370300200a2005290300370300200b2006370300200c200929030037030020002000290330370310200041203602342000200041106a360230200041086a200041306a10c402200041e0006a24000ba41d08047f017e017f017e047f017e047f017e230041f0016b22012400200141a8016a41186a22024200370300200141a8016a41106a22034200370300200141a8016a41086a22044200370300200142003703a80141e4dec400ad4280808080e000842205100c22062900002107200141c8016a41086a2208200641086a290000370300200120073703c8012006102320042008290300370300200120012903c8013703a80141d483c500ad4280808080e00184100c220629000021072008200641086a290000370300200120073703c80120061023200320012903c801220737030020014188016a41086a2206200429030037030020014188016a41106a2209200737030020014188016a41186a220a2008290300370300200120012903a8013703880120014188016aad428080808080048422071011200242003703002003420037030020044200370300200142003703a8012005100c220b290000210c2008200b41086a2900003703002001200c3703c801200b102320042008290300370300200120012903c8013703a80141d0ffc400ad4280808080e00184100c220b290000210c2008200b41086a2900003703002001200c3703c801200b1023200320012903c801220c370300200620042903003703002009200c370300200a2008290300370300200120012903a8013703880120071011200242003703002003420037030020044200370300200142003703a8012005100c220b290000210c2008200b41086a2900003703002001200c3703c801200b102320042008290300370300200120012903c8013703a80141e8ffc400ad4280808080b00284100c220b290000210c2008200b41086a2900003703002001200c3703c801200b1023200320012903c801220c370300200620042903003703002009200c370300200a2008290300370300200120012903a8013703880120071011200242003703002003420037030020044200370300200142003703a8012005100c220b290000210c2008200b41086a2900003703002001200c3703c801200b102320042008290300370300200120012903c8013703a801418c80c500ad4280808080800284100c220b290000210c2008200b41086a2900003703002001200c3703c801200b1023200320012903c801220c370300200620042903003703002009200c370300200a2008290300370300200120012903a8013703880120071011200242003703002003420037030020044200370300200142003703a8012005100c220b290000210c2008200b41086a2900003703002001200c3703c801200b102320042008290300370300200120012903c8013703a80141f3dec400ad4280808080e00084100c220b290000210c2008200b41086a2900003703002001200c3703c801200b1023200320012903c801220c370300200620042903003703002009200c370300200a2008290300370300200120012903a80137038801200120014188016a412010cd012001280204210d02402001280200220e4101470d00200710110b200242003703002003420037030020044200370300200142003703a8012005100c220b29000021052008200b41086a290000370300200120053703c801200b102320042008290300370300200120012903c8013703a80141f9dec400ad4280808080a00184100c220b29000021052008200b41086a290000370300200120053703c801200b1023200320012903c801370000200341086a20082903003700002006200429030037030020092003290300370300200a2002290300370300200120012903a80137038801200141c8016a20014188016a412010e101024002400240024020012d00c80122080d00200141c0016a200141e1016a290000370300200141b8016a200141d9016a290000370300200141b0016a200141d1016a290000370300200120012900c9013703a8010c010b20071011200141a8016a41186a2204200141e1016a290000370300200141a8016a41106a2202200141d9016a290000370300200141a8016a41086a2206200141d1016a290000370300200120012900c9013703a80120084101460d010b200141206a4200370300200141186a4200370300200141106a4200370300200142003703080c010b200141086a41186a2004290300370300200141086a41106a2002290300370300200141086a41086a2006290300370300200120012903a8013703080b200141a8016a41186a22064200370300200141a8016a41106a22094200370300200141a8016a41086a22044200370300200142003703a80141e4dec400ad4280808080e00084100c22022900002105200141c8016a41086a2208200241086a290000370300200120053703c8012002102320042008290300370300200120012903c8013703a8014191dfc400ad4280808080e00084100c220229000021052008200241086a290000370300200120053703c80120021023200320012903c801370000200341086a200829030037000020014188016a41086a200429030037030020014188016a41106a200929030037030020014188016a41186a2006290300370300200120012903a80137038801200141c8016a20014188016a10f7020240024020012802c801220f0d004100210a20014100360230200142043703284104210f410021100c010b200710112001200f360228200120012902cc01220537022c2005422088a7210a2005a721100b200d4100200e1b2106200141a8016a41186a22024200370300200141a8016a41106a22094200370300200141a8016a41086a22084200370300200142003703a80141e4dec400ad4280808080e00084100c220b2900002105200141c8016a41086a2204200b41086a290000370300200120053703c801200b102320082004290300370300200120012903c8013703a8014183dfc400ad4280808080e00184100c220b29000021052004200b41086a290000370300200120053703c801200b1023200320012903c801370000200341086a200429030037000020014188016a41086a200829030037030020014188016a41106a200929030037030020014188016a41186a2002290300370300200120012903a80137038801200141c8016a20014188016a412010e101024002400240024020012d00c80122030d002002200141e1016a2900003703002009200141d9016a2900003703002008200141d1016a290000370300200120012900c9013703a8010c010b200710112002200141e1016a2900003703002009200141d9016a2900003703002008200141d1016a290000370300200120012900c9013703a80120034101460d010b200141d0006a4200370300200141c8006a4200370300200141c0006a4200370300200142003703380c010b200141386a41186a200141a8016a41186a290300370300200141386a41106a200141a8016a41106a290300370300200141386a41086a200141a8016a41086a290300370300200120012903a8013703380b0240200641fb01490d00200641857e6a2208450d00200141c8016a200810d40320013502d00142208620012802c8012208ad84101120012802cc01450d00200810230b410121090240101a2207422088a72202450d002007a721090b41002108200141003a00e801200921030240024002400240034020022008460d01200141c8016a20086a20032d00003a00002001200841016a22043a00e801200341016a21032004210820044120470d000b200141d8006a41086a200141c8016a41086a290300370300200141d8006a41106a200141c8016a41106a290300370300200141d8006a41186a200141c8016a41186a290300370300200120012903c80137035802402002450d00200910230b412010212208450d0220082001290308370000200841186a2204200141086a41186a290300370000200841106a2202200141086a41106a290300370000200841086a2209200141086a41086a290300370000412010212203450d0320032008290000370000200341186a2004290000370000200341106a2002290000370000200341086a200929000037000020081023200141f8006a2003ad4280808080800484101b108b0120031023024020012802782204450d0020014180016a2802002102200128027c210b41002108200141003a00e801034020022008460d03200141c8016a20086a200420086a2d00003a00002001200841016a22033a00e8012003210820034120470d000b20014188016a41086a200141c8016a41086a2203290300220737030020014188016a41106a200141c8016a41106a2202290300220537030020014188016a41186a200141c8016a41186a2209290300220c370300200120012903c80122113703880120032007370300200220053703002009200c370300200120113703c801200141a8016a41026a220d20014185016a41026a2d00003a0000200120012f0085013b01a8010240200a2010470d00200141286a2010410110a2012001280228210f2001280230210a0b200f200a41246c6a220841003a0000200820012903c80137000120092903002107200229030021052003290300210c200820012f01a8013b0021200841236a200d2d00003a0000200841096a200c370000200841116a2005370000200841196a20073700002001200a41016a360230200b450d00200410230b200020012903083700102000200636020020002001290358370030200041286a200141086a41186a290300370000200041206a200141086a41106a290300370000200041186a200141086a41086a290300370000200041386a200141d8006a41086a290300370000200041c0006a200141d8006a41106a290300370000200041c8006a200141d8006a41186a290300370000200041e8006a200141386a41186a290300370000200041e0006a200141386a41106a290300370000200041d8006a200141386a41086a290300370000200020012903383700502000410c6a200141286a41086a28020036020020002001290328370204200141f0016a24000f0b0240200841ff0171450d00200141003a00e8010b41d08ec500412c200141c8016a41b0e3c40041fc8ec5001034000b0240200841ff0171450d00200141003a00e8010b41d08ec500412c200141c8016a41b0e3c400418c8fc5001034000b1033000b102a000bcf0405017f027e027f017e017f230041e0006b22032400200341306a20012902002204422088a72201200210c6040240024002400240024002402003290330a7220241ff01714101460d0042002105200341306a41186a4200370300200341306a41106a22064200370300200341306a41086a220242003703002003420037033041e4dec400ad4280808080e00084100c220729000021082002200741086a290000370300200320083703302007102341e8ffc400ad4280808080b00284100c22072900002108200341d0006a41086a2209200741086a2900003703002003200837035020071023200620032903502208370300200341106a41086a2002290300370300200341106a41106a2008370300200341106a41186a200929030037030020032003290330370310200341086a200341106a412010cd010240200141ff017122024102460d00417f200328020c410020032802081b2207418094ebdc034180afd0e50220021b22022004a7220620022006491b6a220620062007491b20024b0d050b200141ff01710e03010203010b200041013a0000200041036a20024118763a0000200020024108763b00010c040b200442ffffffff0f8321050c010b427f21050b200041003a0000200041306a41013a0000200041286a4200370200200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a2005370300200041316a2003280030360000200041346a200341336a2800003600000c010b200041800c3b0001200041013a0000200041036a41003a00000b200341e0006a24000b920303047f017e017f230041e0006b22032400200341306a41186a4200370300200341306a41106a22044200370300200341306a41086a220542003703002003420037033041e4dec400ad4280808080e00084100c220629000021072005200641086a2900003703002003200737033020061023418c80c500ad4280808080800284100c22062900002107200341d0006a41086a2208200641086a2900003703002003200737035020061023200420032903502207370300200341106a41086a2005290300370300200341106a41106a2007370300200341106a41186a200829030037030020032003290330370310200341086a200341106a412010cd014100210502400240417f200328020c410020032802081b220620026a220220022006491b22064280808080f28ba80942808080c0f588fe06200141ff01711b22072007428094ebdc038022074280ec94a37c7e7c4280cab5ee01562007a76a4b0d00200041046a20063602000c010b200041800c3b0001200041036a41003a0000410121050b200020053a0000200341e0006a24000b340020004189e3c40036020420004100360200200041146a4104360200200041106a41f88fc500360200200041086a42083702000b3400200041c599c50036020420004100360200200041146a4101360200200041106a41d899c500360200200041086a42123702000b130020004102360204200041dc9ac5003602000b3601017f02404110102122020d001033000b2002420037000820024280c2d72f370000200042908080808002370204200020023602000bb60101027f230041106b22022400200220002802003602082001200241086a410410620240024002400240024020002d0004220341024b0d0020030e03010203010b2002410f6a21030c030b200241003a000f20012002410f6a410110622002410f6a21030c020b200241013a000f20012002410f6a410110622002410f6a21030c010b200241023a000f20012002410f6a410110622002410f6a21030b200220002d00053a000f2001200341011062200241106a24000b130020004105360204200041c89dc5003602000bd10201037f230041206b220424000240024002400240024002402002200141346a2205460d0020022005412010a305450d00200441186a200241186a290000370300200441106a200241106a290000370300200441086a200241086a290000370300200420022900003703002001200410ce0422020d010c040b200141306a2802002202417f4c0d01200128022821010240024020020d0041002105410121060c010b20022105200210212206450d030b20062001200210a1052101200041086a200236020020002005360204200020013602000c040b200228020c4101480d0220022802082201417f4c0d00200228020021020240024020010d0041002105410121060c010b20012105200110212206450d020b20062002200110a1052102200041086a200136020020002005360204200020023602000c030b1032000b1033000b200041003602000b200441206a24000bdb0303017f047e097f230041106b220224002002200041086a29030022032000290300220485220520044218898520054210868520054225897c220542a0cbbf9599b5a19f0a7c2206200129001885200129000020068542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852001290008200542efcdddd088a580a21e7c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e852001290010200542bed0fb8bf894dfa4327c8542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e85420042adfed5e4d485fda8d800420010a605200241086a29030020022903007c200320047c85a722074119762208410874200872220841107420087221092000280210220a2007712108200041186a280200210b200041146a280200210c4100210d024003400240200c20086a280000220e2009732200417f73200041fffdfb776a71418081828478712200450d00024003402001200b20006841037620086a200a71220f41306c6a2207460d0120012007412010a305450d012000417f6a2000712200450d020c000b0b200b200f41306c6a41206a21000c020b200d41046a220d20086a200a712108200e200e4101747141808182847871450d000b410021000b200241106a240020000b8d0101037f230041206b220324004101210402402001200041346a2205460d0020012005412010a305450d00200341186a200141186a290000370300200341106a200141106a290000370300200341086a200141086a2900003703002003200129000037030002402000200310ce0422010d00410021040c010b200128020c41004a21040b200341206a240020040b02000b8e0704057f017e087f037e230041a0016b220224002002412036020c20022001360208200241106a2001ad42808080808004841010108b010240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a1088010240024020022802000d00200228020422052002280224220641286e2201200120054b1bad42287e2207422088a70d032007a72201417f4c0d030240024020010d00410821080c010b200110212208450d050b4100210920024100360230200220083602282002200141286e36022c0240024002402005450d004100210a034041002101200241003a009801200a41016a210a034020062001460d03200241f8006a20016a2002280220220b2d00003a00002002200b41016a3602202002200141016a220c3a009801200c2101200c4120470d000b200241d8006a41086a220d200241f8006a41086a290300370300200241d8006a41106a220e200241f8006a41106a290300370300200241d8006a41186a220f200241f8006a41186a2903003703002002200229037837035820022006200c6b220136022420014108490d03200241386a41086a220c200d290300370300200241386a41106a220d200e290300370300200241386a41186a220e200f290300370300200220022903583703382002200b41096a3602202002200141786a2206360224200b290001210702402009200228022c470d00200241286a2009410110980120022802282108200228023021090b2008200941286c6a22012002290338370300200c2903002110200d2903002111200e290300211220012007370320200141186a2012370300200141106a2011370300200141086a20103703002002200941016a2209360230200a2005470d000b0b2008450d022000200229022c370204200020083602000c030b20024100360224200141ff0171450d00200241003a0098010b200228022c2201450d00200141286c450d00200810230b20024100360260200242013703582002410a36023c2002200241086a3602382002200241d8006a3602282002418c016a41013602002002420137027c20024180c5c6003602782002200241386a36028801200241286a4184a5c200200241f8006a10311a2002350260422086200235025884100a0240200228025c450d00200228025810230b200041003602000b2004450d00200310230b200241a0016a24000f0b1032000b1033000b3400200041a7b3c50036020420004100360200200041146a410a360200200041106a41b4b3c500360200200041086a42043702000b910101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002404120102122060d001033000b20062002290300370000200042a0808080800437020420002006360200200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000200241206a24000b130020004102360204200041acc9c5003602000b2d01017f02404108102122020d001033000b20004288808080800137020420002002360200200242f02e3700000b2d01017f02404108102122020d001033000b20004288808080800137020420002002360200200242d8043700000bcc0503027f017e047f230041e0006b2202240041bdadc500ad4280808080800184100c22032900002104200241086a41086a200341086a290000370300200220043703082003102341d2adc500ad4280808080d00084100c22032900002104200241186a41086a200341086a2900003703002002200437031820031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100f22012900002104200241386a41086a200141086a2900003703002002200437033820011023200241d4006a200341206a360200200241003a0058200220033602502002200241386a41106a36024c2002200241386a360248200241286a200241c8006a1065200310232002280230220541206a2201417f4c0d0120022802282106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290308370000200341086a200241086a41086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290318370010200341186a200241186a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a2000200136020820002007360204200020033602000240200228022c450d00200610230b200241e0006a24000f0b102c000b102a000b13002000410536020420004190d0c5003602000b34002000419df5c50036020420004100360200200041146a4101360200200041106a41a4f5c500360200200041086a42073702000b9b0604067f017e027f057e230041f0006b220324002003200236021420032001360210200341186a2002ad4220862001ad841010108b010240024002400240200328021822040d00200041003602000c010b200328021c21052003200341206a28020036022c20032004360228200341086a200341286a1088010240024020032802080d00200328020c2206200328022c4105762201200120064b1b22014105742202417f4c0d040240024020010d00410821070c010b200210212207450d040b41002102200341003602502003200136024c20032007360248024002402006450d000340200341306a200341286a10f6020240024020032d00304101460d0041032108200328022c22014110490d01200329003121092003200141706a220a36022c20032003280228220b41106a360228200a450d01200b41086a290000210c200b290000210d20032001416f6a36022c2003200b41116a36022841032108200b2d0010220141034f0d01200320032800303602402003200341306a41036a2800003600432009210e200d210f200c2110200121080c010b410321080b200320032802403602682003200328004336006b20084103460d022003200328006b3600632003200328026836026002402002200328024c470d00200341c8006a2002410110970120032802482107200328025021020b200720024105746a220120083a00182001200e370310200120032802603600192001411c6a2003280063360000200120103703082001200f3703002003200241016a22023602502006417f6a22060d000b0b2007450d012000200329024c370204200020073602000c020b200328024c41ffffff3f71450d00200710230b20034100360238200342013703302003410a3602442003200341106a3602402003200341306a360268200341dc006a41013602002003420137024c20034180c5c6003602482003200341c0006a360258200341e8006a4184a5c200200341c8006a10311a2003350238422086200335023084100a02402003280234450d00200328023010230b200041003602000b2005450d00200410230b200341f0006a24000f0b1033000b1032000bc5130c037f027e027f067e027f027e017f017e027f017e037f027e230041a0046b22032400200341106a2000109702200341206a2003280210220420032802182205109802200329032021064200210720034200370320200341e8006a280200210820032d006c21090240024020064201510d00200341f0006a41386a4200370300200341f0006a41306a4200370300200341f0006a41286a4200370300200341f0006a41206a4200370300200341f0006a41186a420037030020034180016a4200370300200341f8006a4200370300200342003703704200210a4200210b4200210c0c010b200341206a41386a290300210d200341206a41306a290300210e200341206a41206a290300210a200341206a41186a2903002107200341e0006a290300210f2003290330210c2003290328210b200341f0006a41206a200341206a41286a290300370300200341f0006a41286a200e370300200341f0006a41306a200d37030020034180016a20073703002003200a370388012003200f3703a8012003200b3703702003200c3703780b4200210d200341a8016a22104200370300200341f0006a41306a4200370300200341f0006a41286a221142003703002003420037039001200c200a7c2112200b20077c2213200b542214ad2115200341f0006a41106a211602402002450d00200241057421174200210d4200210f420021184200210e200121190340024002400240201941186a221a2d0000221b417f6a41ff017141014b0d002011200e201941086a290300220720182019290300220a56200e200756200e2007511b221b1b220e37030020032018200a201b1b221837039001201a2d0000221b4102460d010b201b41ff01710d01201941086a29030021072019290300210a0b2010200d2007200f200a56200d200756200d2007511b221b1b220d3703002003200f200a201b1b220f3703a0010b201941206a2119201741606a22170d000b0b201220157c2107200341b0016a41186a201641086a290300220a370300200341b0016a41206a221b201641106a290300370300200341b0016a41286a201641186a290300370300200341b0016a41306a201641206a29030037030020032016290300220e3703c0012003200b3703b0012003200c3703b80102400240427f200b200e7c220e200e200b542219200c200a7c2019ad7c220a200c54200a200c511b22191b220e4280c8afa025544100427f200a20191b220f501b0d00200341c0016a290300210e200341e0016a290300210f200341d8016a2903002118201b290300211220032903b801211520032903b001211c4201210a20032903c801211d0c010b4200210a0240200e200f84500d00200e200f10eb01200341f0036a200f370300200341e8036a200e370300200341b8036a41086a41013a0000200341c1036a2000290000370000200341c9036a200041086a290000370000200341d1036a200041106a290000370000200341d9036a200041186a290000370000200341023a00b803200341b8036a10e0010b0b2007200c5121192007200c54211b200341c8006a2012370300200341d0006a2018370300200341306a2015370300200341d8006a200f370300200341386a200e3703002003201d3703402003200d3703602003201c370328200320094100200642015122171b3a006c20032008410020171b3602682003200a4201512217ad3703200240024020170d002005ad4220862004ad8410110c010b200320053602bc03200320043602b803200341286a200341b8036a1098030b2014201b20191b211902402003280214450d00200410230b427f200720191b2107427f201320191b210d200a420152211902400240024020064201510d0020190d004103211b200341d0026a21190c010b20064201522019410173720d014104211b200341e8016a21190b201941046a201b3a0000201941003a0000201941056a20002900003700002019410d6a200041086a290000370000201941156a200041106a2900003700002019411d6a200041186a290000370000201910e0010b0240200d2007844200520d00200341f0036a200c370300200341e8036a200b370300200341b8036a41086a41003a0000200341c1036a2000290000370000200341c9036a200041086a290000370000200341d1036a200041106a290000370000200341d9036a200041186a290000370000200341023a00b803200341b8036a10e0010b200341b8036a200010d704200341086a20032802b803221920032802c003419ca8c70041004100108c0120032802082104024020032802bc03450d00201910230b0240024002400240024002402002450d00200341d0026a200010d70420024105744104722219417f4c0d0220033502d802210d20032802d002210520191021221b450d03200341003602c003200320193602bc032003201b3602b8032002200341b8036a10612002410574211120032802bc03211a20032802c0032117034002400240201a20176b4108490d0020032802b803211b201a21100c010b201741086a22192017490d06201a410174221b2019201b20194b1b22104100480d0602400240201a0d00024020100d004101211b0c020b20101021221b0d010c090b20032802b803211b201a2010460d00201b201a20101025221b450d080b200320103602bc032003201b3602b8030b201b20176a200141106a2900003700002003201741086a221a3602c003200141086a29030021072001290300210a024002402010201a6b410f4d0d00201021190c010b201a41106a2219201a490d06201041017422162019201620194b1b22194100480d060240024020100d00024020190d004101211b0c020b20191021221b450d090c010b20102019460d00201b201020191025221b450d080b200320193602bc032003201b3602b8030b201b201a6a221a2007370008201a200a3700002003201741186a22173602c003200141186a2d000021100240024020192017460d002019211a201721190c010b201941016a22172019490d062019410174221a2017201a20174b1b221a4100480d060240024020190d00410021190240201a0d004101211b0c020b201a1021221b450d090c010b2019201a460d00201b2019201a1025221b450d080b2003201a3602bc032003201b3602b8030b200141206a2101201b20196a20103a00002003201941016a22173602c003201141606a22110d000b20032802bc032119200d4220862005ad842017ad42208620032802b803221bad84100e02402019450d00201b10230b024020032802d402450d00200510230b20044101460d0120001096020c010b200341b8036a200010d70420033502c00342208620032802b8032219ad841011024020032802bc03450d00201910230b20044101470d00200010a1020b200341a0046a24000f0b1032000b1033000b102c000b102a000b130020004104360204200041fcf6c5003602000b3400200041bdadc50036020420004100360200200041146a4104360200200041106a41848bc600360200200041086a42083702000b830101017f0240411010212202450d00200242003700082002420037000020024110412010252202450d0020024200370010200241186a42003700002002412041c00010252202450d002002420037003020024200370020200042c0808080800837020420002002360200200241386a4200370000200241286a42003700000f0b102a000b130020004101360204200041bc93c6003602000b3701017f02404110102122020d001033000b2002420037000820024280c8afa025370000200042908080808002370204200020023602000ba60203017f017e047f230041106b22022400200029030021032002200041086a29030037030820022003370300200120024110106220002802102104200041186a28020022052001106102402005450d0020054104742105034002402004410c6a2d000022064103714103460d004100210702400240024020060e03020001020b410121070c010b410221070b200220073a000020012002410110620b20042802002107200441086a2802002206200110612001200720061062200441106a2104200541706a22050d000b0b02404120102122040d001033000b2004200029001c370000200441186a200041346a290000370000200441106a2000412c6a290000370000200441086a200041246a290000370000200120044120106220041023200241106a24000b960503037f027e057f230041106b220224002002410036020820024201370300200028021021030240410410212204450d0020024104360204200220043602002004200336000020024104360208200041146a280200210320044104410810252204450d0020024108360204200420033600042002200436020020024108360208200041086a29030021052000290300210620044108411810252204450d0020042006370008200441106a200537000020022004360200200242988080808003370204024041000d0020044118413810252204450d010b20042000290024370018200441206a2000412c6a290000370000200441286a200041346a290000370000200441306a2000413c6a29000037000020024138360204200220043602002002413836020820002802182104200041206a28020022002002106102400240024020000d002002280208210020022802042107200228020021080c010b200041057421094100200228020822006b210a2002280204210b034002400240200b200a6a4120490d0020022802002108200b21070c010b200041206a22032000490d03200b41017422082003200820034b1b22074100480d0302400240200b0d00024020070d00410121080c020b2007102122080d010c060b20022802002108200b2007460d002008200b200710252208450d050b20022007360204200220083602002007210b0b200820006a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200041206a2200360208200a41606a210a200441206a2104200941606a22090d000b0b20012902002000ad4220862008ad84100e02402007450d00200810230b200241106a24000f0b102c000b102a000b881703047f067e027f230041d0036b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e16001101020304051106070809110a0b0c0d0e0f101112000b200241a8016a200141086a10dd0320004100360200200041106a200241a8016a41086a290300370300200041086a20022903a8013703000c120b20004102360200200041086a200141086a2903003703000c110b02400240024002400240024020012d0004417f6a220341034b0d00200141046a210420030e0401020304010b41f58ac7004128418c94c700102d000b200141086a2802002103410121050c030b41022105200241086a41026a200441036a2d00003a0000200241a8016a41086a200141146a290200370300200241b8016a2001411c6a290200370300200241c0016a200141246a2d00003a0000200220042f00013b010820022001410c6a2902003703a801200141086a2802002103200141286a28020021010c020b200141086a2802002103410321050c010b2002410a6a200441036a2d00003a0000200241a8016a41086a200141146a290200370300200241b8016a2001411c6a290200370300200241c0016a200141246a2d00003a0000200220042f00013b010820022001410c6a2902003703a801200141086a2802002103200141286a2802002101410421050b200020053a0004200020022f01083b000520004103360200200041086a20033602002000410c6a20022903a801370200200041286a2001360200200041076a2002410a6a2d00003a0000200041146a200241a8016a41086a2903003702002000411c6a200241b8016a290300370200200041246a200241c0016a2802003602000c100b02400240024002400240024002400240200141086a22032d0000417f6a220441034b0d0020040e0401020304010b41f58ac7004128418c94c700102d000b200241b0016a200341096a290000370300200241b8016a200341116a290000370300200241c0016a200341196a290000370300200220032900013703a801200141386a2903002106200141306a2903002107410121010c030b200241b0016a200341096a290000370300200241b8016a200341116a290000370300200241c0016a200341196a290000370300200220032900013703a801200141c8006a2903002108200141c0006a2903002109200141386a2903002106200141306a2903002107410221010c030b200241b0016a200341096a290000370300200241b8016a200341116a290000370300200241c0016a200341196a290000370300200220032900013703a8012002200341216a2800003602082002200341246a28000036000b200141c8006a3100002108200141c0006a2902002109200141386a2902002106200141306a2902002107200141d8006a290300210a200141d0006a290300210b410321010c030b200241b0016a200341096a290000370300200241b8016a200341116a290000370300200241c0016a200341196a290000370300200220032900013703a801200141386a2903002106200141306a2903002107410421010b0b0b200020022903a8013700092000200228020836002920004104360200200041d8006a200a370300200041d0006a200b370300200041c8006a2008370300200041c0006a2009370300200041386a2006370300200041306a2007370300200041086a20013a00002000412c6a200228000b360000200041116a200241a8016a41086a290300370000200041196a200241b8016a290300370000200041216a200241c0016a2903003700000c0f0b200241a8016a200141046a10de03200041053602002000410c6a200241b0016a280200360200200020022903a8013702040c0e0b200241a8016a200141086a109202200041086a200241a8016a41880210a1051a200041063602000c0d0b02400240200128020422040d00410021030c010b200241a8016a41186a200141286a290000370300200241a8016a41106a200141206a290000370300200241b0016a200141186a290000370300200241a8016a41286a200141386a290000370300200241a8016a41306a200141c0006a290000370300200241a8016a41386a200141c8006a290000370300200241a8016a41c8006a200141d8006a290000370300200241a8016a41d0006a200141e0006a290000370300200241a8016a41d8006a200141e8006a2900003703002002200141106a2900003703a8012002200141306a2900003703c8012002200141d0006a2900003703e801200241a8016a41f8006a20014188016a290000370300200241a8016a41f0006a20014180016a290000370300200241a8016a41e8006a200141f8006a290000370300200241a8016a4198016a200141a8016a290000370300200241a8016a4190016a200141a0016a290000370300200241a8016a4188016a20014198016a2900003703002002200141f0006a29000037038802200220014190016a2900003703a8022001410c6a2802002201417f4c0d0e0240024020010d0020024200370308410121030c010b200110212203450d102002410036020c200220013602080b20032004200110a1051a2002200136020c20022903082106200241086a200241a8016a41a00110a1051a0b20002003360204200041086a2006370200200041106a200241086a41a00110a1051a200041083602000c0c0b20004109360200200020012802043602040c0b0b2001410c6a2802002203417f4c0d0b200128020421050240024020030d0041002101410121040c010b20032101200310212204450d0d0b20042005200310a10521042000410c6a2003360200200041086a2001360200200020043602042000410a3602000c0a0b200241a8016a200141046a10d702200041046a200241a8016a41e40010a1051a2000410b3602000c090b200241a8016a200141046a10df03200041046a200241a8016a419c0210a1051a2000410d3602000c080b2000410e3602000c070b200241a8016a200141046a10e003200041046a200241a8016a41c80010a1051a2000410f3602000c060b200241a8016a200141046a10e103200041103602002000413c6a200241e0016a280200360200200041346a200241d8016a2903003702002000412c6a200241d0016a290300370200200041246a200241c8016a2903003702002000411c6a200241c0016a290300370200200041146a200241a8016a41106a2903003702002000410c6a200241b0016a290300370200200020022903a8013702040c050b200241a8016a200141086a10e203200041086a200241a8016a41a80210a1051a200041113602000c040b200241a8016a200141046a10e303200041046a200241a8016a41c40010a1051a200041123602000c030b4102210c0240024002400240200141086a22032d0000417f6a220d41024b0d0041012104200d0e03030201030b41f58ac7004128418c94c700102d000b200141c8006a2903002107200141c0006a2903002106200141386a2903002109200141306a2903002108200141d0006a28020021054103210c0b200241c0016a200341196a290000370300200241b8016a200341116a290000370300200241b0016a200341096a290000370300200220032900013703a801200c21040b200020022903a8013700092000200228000836002920004113360200200041c8006a2007370300200041c0006a2006370300200041386a2009370300200041306a2008370300200041086a20043a0000200041d0006a2005360200200041116a200241a8016a41086a290300370000200041196a200241b8016a290300370000200041216a200241c0016a2903003700002000412c6a2002410b6a2800003600000c020b10e403000b200241a8016a200141046a10db0320004115360200200041246a200241c8016a2903003702002000411c6a200241c0016a290300370200200041146a200241b8016a2903003702002000410c6a200241b0016a290300370200200020022903a8013702040b200241d0036a24000f0b1032000b1033000b8f0403027f017e077f230041306b22032400200341086a200141086a28020022043602002003200129020022053703002005a72106024002400240024020040d00410021070c010b200441057421084100210941002107200621010240034002402009450d0020092001412010a3054100480d004115210a41ed96c600210b4105210c0c020b024020012002412010a305220941004a0d004113210a41da96c600210b4106210c20022001460d022009450d02200741016a21070b20012109200141206a2101200841606a2208450d020c000b0b2000200c3a000620004183263b0104200041013602002000410c6a200a360200200041086a200b360200200328020441ffffff3f71450d01200610230c010b200341106a41186a200241186a290000370300200341106a41106a200241106a290000370300200341106a41086a200241086a2900003703002003200229000037031020042007490d01024020042003280204470d00200320044101109a01200328020021060b200620074105746a220141206a2001200420076b41057410a2051a200141186a200341106a41186a290300370000200141106a200341106a41106a290300370000200141086a200341106a41086a290300370000200120032903103700002003200441016a22013602082000410c6a200136020020002003290300370204200041003602000b200341306a24000f0b200720041038000b870803027f017e067f230041f0006b22032400419df5c500ad4280808080f00084100c22042900002105200341086a41086a200441086a290000370300200320053703082004102341fcf5c500ad4280808080900184100c22042900002105200341186a41086a200441086a2900003703002003200537031820041023024002400240024002400240412010212204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020032004ad4280808080800484100d220129000037034820011023200341e4006a2206200441206a360200200341003a0068200320043602602003200341c8006a41086a36025c2003200341c8006a360258200341286a200341d8006a106520041023412010212204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a2900003700002004ad4280808080800484100f22012900002105200341c8006a41086a200141086a29000037030020032005370348200110232006200441206a360200200341003a0068200320043602602003200341c8006a41106a36025c2003200341c8006a360258200341386a200341d8006a1065200410232003280230220741206a2202200328024022086a2201417f4c0d01200328023821092003280228210a024002402001450d00200110212204450d022001410f4d0d01200121060c050b200141017422044110200441104b1b2206102122040d040c060b200141017422064110200641104b1b220641004e0d020c040b1033000b1032000b20012006460d0020042001200610252204450d020b20042003290308370000200441086a200341086a41086a2903003700000240024020064170714110460d002006210b0c010b2006410174220b4120200b41204b1b220b4100480d012006200b460d0020042006200b10252204450d020b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21060c010b2007415f4b0d01200b41017422062002200620024b1b22064100480d01200b2006460d002004200b200610252204450d020b200441206a200a200710a1051a02400240200620026b2008490d002006210b0c010b200220086a2002490d012006410174220b2001200b20014b1b220b4100480d01024020060d000240200b0d00410121040c020b200b10212204450d030c010b2006200b460d0020042006200b10252204450d020b200420026a2009200810a1051a200020013602082000200b360204200020043602000240200328023c450d00200910230b0240200328022c450d00200a10230b200341f0006a24000f0b102c000b102a000b850604067f027e027f057e23004190016b220324002003200236020420032001360200200341086a2002ad4220862001ad841010108b0102400240200328020822020d00200041003602180c010b200328020c21042003200341106a280200220136023c200320023602380240024020014104490d002003200241046a36023820032001417c6a220536023c20054104490d00200228000021062003200241086a3602382003200141786a220536023c20054110490d00200228000421072003200141686a220836023c2003200241186a360238200241106a29000021092002290008210a41002101200341003a0088010240034020082001460d01200341e8006a20016a200220016a220541186a2d00003a00002003200541196a3602382003200141016a22053a0088012005210120054120470d000b200341c8006a41086a2201200341e8006a41086a290300370300200341c8006a41106a220b200341e8006a41106a290300370300200341c8006a41186a220c200341e8006a41186a290300370300200320032903683703482003200820056b36023c200341e8006a200341386a10cf0120032802682205450d01200341186a41086a2001290300220d370300200341186a41106a200b290300220e370300200341186a41186a200c290300220f370300200320032903482210370318200329026c2111200020093703082000200a3703002000201137021c200020053602182000200736021420002006360210200041246a20103702002000412c6a200d370200200041346a200e3702002000413c6a200f3702000c020b2003410036023c200141ff0171450d00200341003a0088010b20034100360250200342013703482003410a36021c200320033602182003200341c8006a360244200341fc006a41013602002003420137026c20034180c5c6003602682003200341186a360278200341c4006a4184a5c200200341e8006a10311a2003350250422086200335024884100a0240200328024c450d00200328024810230b200041003602180b2004450d00200210230b20034190016a24000b13002000410c3602042000418497c6003602000b130020004108360204200041dc9fc6003602000b130020004104360204200041a4a8c6003602000b3400200041fba7c60036020420004100360200200041146a4101360200200041106a41f4b7c600360200200041086a42073702000b130020004101360204200041a4b9c6003602000b3400200041fea6c60036020420004100360200200041146a4103360200200041106a41a4bac600360200200041086a420a3702000b1300200041073602042000418cbec6003602000ba30c02097f027e230041e0006b22022400200241386a4100280298c942360200200241306a4100290290c942370300200241286a4100290288c942370300200241206a4100290280c942370300200241186a41002902f8c842370300200241106a41002902f0c842370300200241086a41002902e8c842370300200241002902e0c8423703002002410036024820024201370340200241d0006a200210900120022802502103024002400240024020022802442204200228024822056b20022802582206490d00410121070c010b200520066a22072005490d01200441017422082007200820074b1b22084100480d010240024020040d00024020080d00410121070c020b2008102122070d010c040b4101210720042008460d0041012004200810252207450d030b20022008360244200220073602400b200720056a2003200610a1051a2002200520066a36024802402002280254450d00200310230b200241d0006a200241106a109001200228025021080240024020022802442204200228024822056b20022802582203490d00200421060c010b200520036a22062005490d01200441017422092006200920064b1b22064100480d010240024020040d00024020060d00410121070c020b200610212207450d040c010b20042006460d0020072004200610252207450d030b20022006360244200220073602400b200720056a2008200310a1051a2002200520036a220336024802402002280254450d00200810230b02400240200620036b4104490d00200341046a21050c010b200341046a22052003490d01200641017422042005200420054b1b22044100480d010240024020060d00024020040d00410121070c020b200410212207450d040c010b20062004460d0020072006200410252207450d030b20022004360244200220073602400b200720036a41023600002002200536024820022802242103024002402002280244220620056b4104490d00200228024021070c010b200541046a22072005490d01200641017422042007200420074b1b22044100480d010240024020060d00024020040d00410121070c020b200410212207450d040c010b2002280240210720062004460d0020072006200410252207450d030b20022004360244200220073602400b200720056a20033600002002200541046a22063602482002280228210402402002280244220320066b41034b0d00200641046a22082006490d01200341017422092008200920084b1b22084100480d010240024020030d00024020080d00410121070c020b200810212207450d040c010b20032008460d0020072003200810252207450d030b20022008360244200220073602400b200720066a20043600002002200541086a360248200241306a2802002108200241386a200241346a200228022c4101461b2802002205200241c0006a10610240024020050d00200228024821040c010b20082005410c6c6a21092002280244210720022802482104034002400240200720046b4108490d00200441086a210520022802402103200721060c010b200441086a22052004490d03200741017422062005200620054b1b22064100480d030240024020070d00024020060d00410121030c020b200610212203450d060c010b2002280240210320072006460d0020032007200610252203450d050b20022006360244200220033602400b200320046a200829000037000020022005360248200841086a280200210402400240200620056b41034d0d00200621070c010b200541046a22072005490d032006410174220a2007200a20074b1b22074100480d030240024020060d00024020070d00410121030c020b200710212203450d060c010b20062007460d0020032006200710252203450d050b20022007360244200220033602400b200320056a20043600002002200541046a220436024820092008410c6a2208470d000b0b2004ad210b2002350240210c02402002280200450d00200241086a280200450d00200228020410230b200b422086210b02402002280210450d00200241186a280200450d00200241146a28020010230b200b200c84210b0240200228022c450d0020022802342205450d002005410c6c450d00200228023010230b200241e0006a2400200b0f0b102c000b102a000bd41c03057f017e037f230041f00d6b22022400024002402001450d00200220003602100c010b2002419ca8c7003602100b20022001360214200241900a6a200241106a109b030240024020022802940a2203450d00200241900a6a410c6a280200210120022802980a210420022802900a2100200241b8066a200241900a6a41106a41e00010a1051a200241900a6a200241106a10b10420022802900a0d0102402001450d00200141246c21002003210103400240024020012d0000220541044b0d0002400240024020050e050400010204040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b2004450d00200441246c450d00200310230b200241a40a6a4102360200200241c4066a4104360200200242023702940a200241e8c1c6003602900a200241043602bc06200241e0c1c6003602b806200241003602fc022002419ca8c7003602f8022002200241b8066a3602a00a2002200241f8026a3602c006200241900a6a41f8c1c600103a000b200241f8026a41086a2205200241900a6a41086a280200360200200220022903900a3703f802200241900a6a200241b8066a41e00010a1051a200241286a200241900a6a41e00010a1051a200241186a41086a22062005280200360200200220022903f80237031820024188016a410c6a200136020020024188016a41086a20043602002002200336028c01200220003602880120024188016a41106a200241286a41e00010a105210120024180026a2006280200360200200220022903183703f80120024188016a10be020240024002402002280288012200450d0020024188026a2000417f6a10d403200241900a6a200228028802220020022802900210e101200241b8066a41086a200241990a6a290000370300200241b8066a41106a2205200241a10a6a290000370300200241b8066a41186a2204200241a90a6a290000370300200220022900910a3703b8060240024020022d00900a4101460d00200241f8026a41186a4200370300200241f8026a41106a420037030020024180036a4200370300200242003703f8020c010b200241f8026a41186a2004290300370300200241f8026a41106a2005290300370300200241f8026a41086a200241b8066a41086a290300370300200220022903b8063703f8020b0240200228028c02450d00200010230b200241f8026a2001412010a3050d0020024180026a280200210120022802f8012100200241003602c006200242043703b806200241b8066a4100200110950120022802c006210402402001450d00200141c8036c21052001410374210320022802b8062004410c6c6a21010340200220003602f802200241900a6a200241f8026a10b302200141086a200241900a6a41086a280200360200200120022903900a3702002001410c6a2101200041c8036a2100200541b87c6a22050d000b200341786a41037620046a41016a21040b200241f8026a41086a2004360200200220022903b80622073703f802200241b8066a41086a2004360200200220073703b806200241900a6a200241b8066a1085010240200241d8016a2201200241900a6a412010a305450d004196b5c000ad4280808080e00184100a2001ad4280808080800484101d200241900a6aad4280808080800484101d0b02402001200241900a6a412010a3050d00200241fc016a280200210620022802f8012103200228028002210520024188026a20024188016a41f00010a1051a2003200541c8036c6a21002002280288022108200321010240024002402005450d00200241b8066a41f0006a21042003210102400340200241d0056a200141e80010a1051a200141e8006a2903002107200241f8026a200141f0006a41d80210a1051a20074203510d01200241b8066a200241d0056a41e80010a1051a200220073703a0072004200241f8026a41d80210a1051a2002200241b8066a3602800a200241900a6a200241800a6a10b30220022802980a2105024020022802940a450d0020022802900a10230b200241900a6a200241b8066a41c80310a1051a200241003602d80d200241800a6a200241900a6a2005200241d80d6a10c50220022d00800a4101460d04200141c8036a22012000470d000c030b0b200141c8036a21010b20002001460d00034020014198016a109e032000200141c8036a2201470d000b0b02402006450d00200641c8036c450d00200310230b10c304200810e703200241900a6a10c404200220024188026a410c6a28020022043602e80d200228028c0221032002200241900a6a410c6a28020022013602ec0d20042001470d042004450d0320022802940a210641002105419debc300ad4280808080c0028421070340024002400240024002400240024002400240200320056a22012d00002208200620056a22002d0000470d0002400240024002400240024020080e06000102030405000b20032006460d0d200141016a200041016a412010a3050d050c060b024020032006460d00200141016a280000200041016a280000470d050b200141106a2802002208200041106a280200470d04200141086a2802002209200041086a280200220a460d0a2009200a200810a3050d040c0a0b024020032006460d00200141016a280000200041016a280000470d040b200141106a2802002208200041106a280200470d03200141086a2802002209200041086a280200220a460d082009200a200810a3050d030c080b024020032006460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a2802002209200041086a280200220a460d062009200a200810a3050d020c060b200141046a2802002208200041046a280200470d012008450d04200141086a280200200041086a280200470d012001410c6a2802002000410c6a280200470d010c040b2001410c6a28020022082000410c6a280200470d00200141046a2802002209200041046a280200220a460d022009200a200810a305450d020b2007100a200241b8066a200110e00220023502c00642208620022802b8062208ad84101d024020022802bc06450d00200810230b200241b8066a200010e00220023502c00642208620022802b8062208ad84101d024020022802bc06450d00200810230b20012d000020002d00002208470d06024020080e06000605040302000b20032006460d070b200141016a200041016a412010a3050d050c060b2001410c6a28020022082000410c6a280200470d04200141046a2802002201200041046a2802002200460d0520012000200810a3050d040c050b200141046a2802002208200041046a280200470d032008450d04200141086a280200200041086a280200470d032001410c6a2802002000410c6a280200460d040c030b024020032006460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a2802002201200041086a2802002200460d0320012000200810a3050d020c030b024020032006460d00200141016a280000200041016a280000470d020b200141106a2802002208200041106a280200470d01200141086a2802002201200041086a2802002200460d0220012000200810a3050d010c020b024020032006460d00200141016a280000200041016a280000470d010b200141106a2802002208200041106a280200470d00200141086a2802002201200041086a2802002200460d0120012000200810a305450d010b41e4b8c2004127418c94c700102d000b200541246a21052004417f6a22040d000c040b0b200241086a20022f00810a20022d00830a4110747210a2042002280208200228020c418c94c700102d000b41b7b8c2004124418c94c700102d000b419bb8c200411c418c94c700102d000b024020024188026a41306a2201200241900a6a41306a2200412010a305450d004196b5c000ad4280808080e00184100a2001ad4280808080800484101d2000ad4280808080800484101d0b024020012000412010a305450d00418bb9c2004128418c94c700102d000b0240200228029c0a2200450d0020022802940a2101200041246c210003400240024020012d0000220541044b0d0002400240024020050e050400010204040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b0240200241980a6a2802002201450d00200141246c450d0020022802940a10230b02402002280294022200450d00200228028c022101200041246c210003400240024020012d0000220541044b0d0002400240024020050e050400010204040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b024020024190026a2802002201450d00200141246c450d00200228028c0210230b200241f00d6a240042010f0b200241f8026a41146a410b360200200241f8026a410c6a410d360200200241d0056a41146a41033602002002200241e80d6a3602d80d2002200241ec0d6a3602800a200241b8066a41146a4100360200200242033702d4052002418ca7c7003602d0052002410d3602fc022002419ca8c7003602c806200242013702bc06200241dcb8c2003602b8062002200241f8026a3602e0052002200241b8066a360288032002200241800a6a360280032002200241d80d6a3602f802200241d0056a419ca8c700103a000bb10301037f23004180026b22022400024002402001450d00200220003602000c010b2002419ca8c7003602000b20022001360204200241f8006a2002109b030240200228027c450d00200241086a200241f8006a41f00010a1051a200241086a10be02200228020c21030240200241086a410c6a2802002201450d00200141246c21002003210103400240024020012d0000220441044b0d0002400240024020040e050400010204040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b0240200241106a2802002201450d00200141246c450d00200310230b20024180026a240042010f0b200241f4016a41043602002002411c6a41023602002002420237020c200241e8c1c600360208200241043602ec01200241b4c2c6003602e801200241003602fc012002419ca8c7003602f8012002200241e8016a3602182002200241f8016a3602f001200241086a41f8c1c600103a000b8b3a020f7f017e230041d0006b2202240020024100360238200242043703300240410810212203450d0020034115360204200341afcdc200360200200241306a4100410110a501200228023020022802384103746a20032902003702002002200228023841016a36023820031023410810212203450d002003410c360204200341e2dcc400360200200241306a2002280238410110a501200228023020022802384103746a20032902003702002002200228023841016a36023820031023410810212203450d002003410c360204200341bedcc400360200200241306a2002280238410110a501200228023020022802384103746a20032902003702002002200228023841016a36023820031023410810212203450d0020034108360204200341acdcc400360200200241306a2002280238410110a501200228023020022802384103746a20032902003702002002200228023841016a36023820031023410810212203450d002003410a360204200341b4dcc400360200200241306a2002280238410110a501200228023020022802384103746a20032902003702002002200228023841016a36023820031023410810212203450d002003410b360204200341a1dcc400360200200241306a2002280238410110a501200228023020022802384103746a20032902003702002002200228023841016a36023820031023410810212203450d0020034118360204200341cadcc400360200200241306a2002280238410110a501200228023020022802384103746a20032902003702002002200228023841016a36023820031023410810212203450d0020034116360204200341afabc300360200200241306a2002280238410110a501200228023020022802384103746a20032902003702002002200228023841016a36023820031023410810212203450d00200341193602042003418881c300360200200241306a2002280238410110a501200228023020022802384103746a200329020037020020022002280238220441016a22053602382003102320022802342106200228023021072002410036023820024204370330200241306a41002005410374220341037510950120022802382108024020052004490d00200720036a210920022802302008410c6c6a210320072105034020052802002204450d01200341086a200541046a280200360200200341046a2004360200200341003602002003410c6a2103200841016a2108200541086a22052009470d000b0b200220083602380240200641ffffffff0171450d00200710230b2002280234210a2002280230210b2002410036022820024201370320410410212203450d002002410436022420022003360220200341edcad18b063600002002410436022820022802202103024020022802244104470d0020034104410810252203450d0120024108360224200220033602200b2003410b3a0004200241053602284119200241206a106141c4cdc200210c02400340200c2802042106200c2802082204200241206a10610240024020022802242207200228022822096b2004490d0020022802202105200721030c010b200920046a22032009490d02200741017422052003200520034b1b22034100480d020240024020070d00024020030d00410121050c020b2003102122050d010c050b2002280220210520072003460d0020052007200310252205450d040b20022003360224200220053602200b200520096a2006200410a1051a2002200920046a220436022802400240200c28020c4102470d000240024020032004460d00200421030c010b200341016a22042003490d04200341017422092004200920044b1b22044100480d040240024020030d0041002103024020040d00410121050c020b200410212205450d070c010b20032004460d0020052003200410252205450d060b20022004360224200220053602200b200520036a41003a00002002200341016a22033602280c010b0240024020032004460d00200421030c010b200341016a22042003490d03200341017422092004200920044b1b22044100480d030240024020030d0041002103024020040d00410121050c020b200410212205450d060c010b20032004460d0020052003200410252205450d050b20022004360224200220053602200b200520036a41013a00002002200341016a36022802400240200c28020c4101470d00200c2802142107200c2802182203200241206a10610240024020022802242209200228022822056b2003490d00200228022021040c010b200520036a22042005490d05200941017422062004200620044b1b22064100480d050240024020090d00024020060d00410121040c020b200610212204450d080c010b2002280220210420092006460d0020042009200610252204450d070b20022006360224200220043602200b200420056a2007200310a1051a2002200520036a360228200c28022021030240200c28021c4101470d002003200c280228200241206a10640c020b2003200c41246a280200200241206a10640c010b200241306a200c2802101104002002280234210720022802382203200241206a10610240024020022802242209200228022822056b2003490d00200228022021040c010b200520036a22042005490d04200941017422062004200620044b1b22064100480d040240024020090d00024020060d00410121040c020b200610212204450d070c010b2002280220210420092006460d0020042009200610252204450d060b20022006360224200220043602200b200420056a2007200310a1051a2002200520036a360228200228024021040240200228023c4101460d0020042002280244200241206a10640c010b200420022802482203200241206a106402402003450d00200341d8006c21094100210503400240200420056a220341346a280200450d002003413c6a280200450d00200341386a28020010230b0240200341c4006a280200450d00200341cc006a28020041ffffffff0171450d00200341c8006a28020010230b2009200541d8006a2205470d000b0b20022802442203450d00200341d8006c450d00200410230b200228022821030b2002280224210502400240200c28022c4102470d000240024020052003460d00200228022021050c010b200341016a22052003490d04200341017422042005200420054b1b22044100480d040240024020030d0041002103024020040d00410121050c020b200410212205450d070c010b2002280220210520032004460d0020052003200410252205450d060b20022004360224200220053602200b200520036a41003a00002002200341016a22033602280c010b0240024020052003460d00200228022021050c010b200341016a22052003490d03200341017422042005200420054b1b22044100480d030240024020030d0041002103024020040d00410121050c020b200410212205450d060c010b2002280220210520032004460d0020052003200410252205450d050b20022004360224200220053602200b200520036a41013a00002002200341016a36022802400240200c28022c4101470d00200c2802302105200c2802382203200241206a10612003450d012003412c6c21062005411c6a21030340200341686a280200210d2003416c6a2802002205200241206a10610240024020022802242207200228022822046b2005490d00200228022021090c010b200420056a22092004490d062007410174220e2009200e20094b1b220e4100480d060240024020070d000240200e0d00410121090c020b200e10212209450d090c010b200228022021092007200e460d0020092007200e10252209450d080b2002200e360224200220093602200b200920046a200d200510a1051a2002200420056a360228200341706a200241206a10632003200241206a10602003412c6a2103200641546a22060d000c020b0b200241186a200c28023011040020022802182105200228021c2203200241206a10612003450d002003412c6c21062005411c6a21030340200341686a280200210d2003416c6a2802002205200241206a10610240024020022802242207200228022822046b2005490d00200228022021090c010b200420056a22092004490d052007410174220e2009200e20094b1b220e4100480d050240024020070d000240200e0d00410121090c020b200e10212209450d080c010b200228022021092007200e460d0020092007200e10252209450d070b2002200e360224200220093602200b200920046a200d200510a1051a2002200420056a360228200341706a200241206a10632003200241206a10602003412c6a2103200641546a22060d000b0b200228022821030b2002280224210502400240200c28023c4102470d000240024020052003460d00200228022021050c010b200341016a22052003490d04200341017422042005200420054b1b22044100480d040240024020030d0041002103024020040d00410121050c020b200410212205450d070c010b2002280220210520032004460d0020052003200410252205450d060b20022004360224200220053602200b200520036a41003a00002002200341016a3602280c010b0240024020052003460d00200228022021050c010b200341016a22052003490d03200341017422042005200420054b1b22044100480d030240024020030d0041002103024020040d00410121050c020b200410212205450d060c010b2002280220210520032004460d0020052003200410252205450d050b20022004360224200220053602200b200520036a41013a00002002200341016a3602280240200c28023c4101470d00200c2802402105200c2802482203200241206a10612003450d012003412c6c21062005411c6a21030340200341686a280200210d2003416c6a2802002205200241206a10610240024020022802242207200228022822046b2005490d00200228022021090c010b200420056a22092004490d052007410174220e2009200e20094b1b220e4100480d050240024020070d000240200e0d00410121090c020b200e10212209450d080c010b200228022021092007200e460d0020092007200e10252209450d070b2002200e360224200220093602200b200920046a200d200510a1051a2002200420056a360228200341706a200241206a10602003200241206a10602003412c6a2103200641546a22060d000c020b0b200241106a200c2802401104002002280210210520022802142203200241206a10612003450d002003412c6c21062005411c6a21030340200341686a280200210d2003416c6a2802002205200241206a10610240024020022802242207200228022822046b2005490d00200228022021090c010b200420056a22092004490d042007410174220e2009200e20094b1b220e4100480d040240024020070d000240200e0d00410121090c020b200e10212209450d070c010b200228022021092007200e460d0020092007200e10252209450d060b2002200e360224200220093602200b200920046a200d200510a1051a2002200420056a360228200341706a200241206a10602003200241206a10602003412c6a2103200641546a22060d000b0b02400240200c28024c4101470d00200c280250210f200c2802582203200241206a10612003450d01200341386c2110410021090340200f20096a220341046a280200210d200341086a2802002205200241206a10610240024020022802242206200228022822046b2005490d00200228022021070c010b200420056a22072004490d052006410174220e2007200e20074b1b220e4100480d050240024020060d000240200e0d00410121070c020b200e10212207450d080c010b200228022021072006200e460d0020072006200e10252207450d070b2002200e360224200220073602200b200720046a200d200510a1051a2002200420056a360228200341106a280200210d200341146a2802002205200241206a10610240024020022802242206200228022822046b2005490d00200228022021070c010b200420056a22072004490d052006410174220e2007200e20074b1b220e4100480d050240024020060d000240200e0d00410121070c020b200e10212207450d080c010b200228022021072006200e460d0020072006200e10252207450d070b2002200e360224200220073602200b200720046a200d200510a1051a2002200420056a36022802400240200341186a2802004101470d002003411c6a280200210d200341246a2802002205200241206a10610240024020022802242206200228022822046b2005490d00200228022021070c010b200420056a22072004490d072006410174220e2007200e20074b1b220e4100480d070240024020060d000240200e0d00410121070c020b200e10212207450d0a0c010b200228022021072006200e460d0020072006200e10252207450d090b2002200e360224200220073602200b200720046a200d200510a1051a2002200420056a3602280c010b200241306a2003411c6a280200200341206a28020028020c1102002002280230210620022802382205200241206a1061024002402002280224220d200228022822046b2005490d00200228022021070c010b200420056a22072004490d06200d410174220e2007200e20074b1b220e4100480d0602400240200d0d000240200e0d00410121070c020b200e10212207450d090c010b20022802202107200d200e460d002007200d200e10252207450d080b2002200e360224200220073602200b200720046a2006200510a1051a2002200420056a3602282002280234450d00200610230b200341286a200241206a10602010200941386a2209470d000c020b0b200241086a200c2802501104002002280208210f200228020c2203200241206a10612003450d00200341386c2110410021090340200f20096a220341046a280200210d200341086a2802002205200241206a10610240024020022802242206200228022822046b2005490d00200228022021070c010b200420056a22072004490d042006410174220e2007200e20074b1b220e4100480d040240024020060d000240200e0d00410121070c020b200e10212207450d070c010b200228022021072006200e460d0020072006200e10252207450d060b2002200e360224200220073602200b200720046a200d200510a1051a2002200420056a360228200341106a280200210d200341146a2802002205200241206a10610240024020022802242206200228022822046b2005490d00200228022021070c010b200420056a22072004490d042006410174220e2007200e20074b1b220e4100480d040240024020060d000240200e0d00410121070c020b200e10212207450d070c010b200228022021072006200e460d0020072006200e10252207450d060b2002200e360224200220073602200b200720046a200d200510a1051a2002200420056a36022802400240200341186a2802004101470d002003411c6a280200210d200341246a2802002205200241206a10610240024020022802242206200228022822046b2005490d00200228022021070c010b200420056a22072004490d062006410174220e2007200e20074b1b220e4100480d060240024020060d000240200e0d00410121070c020b200e10212207450d090c010b200228022021072006200e460d0020072006200e10252207450d080b2002200e360224200220073602200b200720046a200d200510a1051a2002200420056a3602280c010b200241306a2003411c6a280200200341206a28020028020c1102002002280230210620022802382205200241206a1061024002402002280224220d200228022822046b2005490d00200228022021070c010b200420056a22072004490d05200d410174220e2007200e20074b1b220e4100480d0502400240200d0d000240200e0d00410121070c020b200e10212207450d080c010b20022802202107200d200e460d002007200d200e10252207450d070b2002200e360224200220073602200b200720046a2006200510a1051a2002200420056a3602282002280234450d00200610230b200341286a200241206a10602010200941386a2209470d000b0b02400240200c28025c4101470d00200c2802602105200c2802682203200241206a10612003450d012003411c6c21062005410c6a21030340200341786a280200210d2003417c6a2802002205200241206a10610240024020022802242207200228022822046b2005490d00200228022021090c010b200420056a22092004490d052007410174220e2009200e20094b1b220e4100480d050240024020070d000240200e0d00410121090c020b200e10212209450d080c010b200228022021092007200e460d0020092007200e10252209450d070b2002200e360224200220093602200b200920046a200d200510a1051a2002200420056a3602282003200241206a10602003411c6a2103200641646a22060d000c020b0b2002200c2802601104002002280200210520022802042203200241206a10612003450d002003411c6c21062005410c6a21030340200341786a280200210d2003417c6a2802002205200241206a10610240024020022802242207200228022822046b2005490d00200228022021090c010b200420056a22092004490d042007410174220e2009200e20094b1b220e4100480d040240024020070d000240200e0d00410121090c020b200e10212209450d070c010b200228022021092007200e460d0020092007200e10252209450d060b2002200e360224200220093602200b200920046a200d200510a1051a2002200420056a3602282003200241206a10602003411c6a2103200641646a22060d000b0b200c41ec006a220c41d0e2c200470d000b02400240200228022420022802282203460d00200228022021050c010b200341016a22052003490d01200341017422042005200420054b1b22044100480d010240024020030d0041002103024020040d00410121050c020b200410212205450d040c010b2002280220210520032004460d0020052003200410252205450d030b20022004360224200220053602200b200520036a41043a00002002200341016a3602282008200241206a1061024002402008450d002008410c6c210d200b41086a210503402005417c6a280200210e20052802002203200241206a10610240024020022802242209200228022822046b2003490d0020022802202107200921060c010b200420036a22072004490d04200941017422062007200620074b1b22064100480d040240024020090d00024020060d00410121070c020b200610212207450d070c010b2002280220210720092006460d0020072009200610252207450d060b20022006360224200220073602200b200720046a200e200310a1051a2002200420036a22033602282005410c6a2105200d41746a220d0d000c020b0b2002280228210320022802242106200228022021070b0240200a450d00200a410c6c450d00200b10230b02400240200341046a2209417f4c0d000240024002400240024002400240024002402009450d00200910212205450d0a200341c000490d04200341808001490d0520034180808080044f0d01200941034d0d062009210d0c070b41012109410110212205450d0b200541033a00004105210d0c010b200541033a000002402009417f6a4104490d002009210d0c020b200941017422044105200441054b1b220d4100480d092009200d460d010b20052009200d10252205450d090b20052003360001410521040c040b200520034102743a0000410121042009210d0c030b02400240200941014d0d002009210d0c010b2009200941017422044102200441024b1b220d460d0020052009200d10252205450d070b41022104200520034102744101723b00000c020b200941017422044104200441044b1b220d4100480d042009200d460d0020052009200d10252205450d050b20052003410274410272360000410421040b0240200d20046b20034f0d00200420036a22092004490d03200d410174220e2009200e20094b1b22094100480d03200d2009460d002005200d200910252205450d040b200520046a2007200310a1051a200420036aad4220862005ad84211102402006450d00200710230b200241d0006a240020110f0b1032000b1033000b102c000b102a000bbb0601057f230041900b6b22022400024002402001450d00200220003602000c010b2002419ca8c7003602000b20022001360204200241b8076a200210d303024002400240024020022903a0084203510d00200241186a200241b8076a41c80310a1051a200241e0036a200241186a41c80310a1051a2002200241e0036a3602b807200241a8076a200241b8076a10b30220022802b0072101200241b8076a200241e0036a41c80310a1051a200241880b6a20022802b007360200200220022903a8073703800b200241086a200241b8076a2001200241800b6a10c5024101410220022d000822034101461b220010212201450d01200241003602c007200220003602bc07200220013602b8070240024020034101470d00200141013a0000200241013602c007200241086a410172200241b8076a10810420022802c007210020022802b80721010c010b200141003a0000200241013602c0070240024020022d000c22044104460d00200141013a000141022103200241023602c00702400240024002400240024020040e0400010203000b410021040c030b410121040c020b200241023a00e003410221040c020b200241033a00e0034104210020014102410410252201450d07200141033a0002200220013602b80720024284808080303702bc07200220022d000d22033a00e003024041010d004106210020014103410610252201450d08200241063602bc07200220013602b8070b200120033a000341042103200241043602c00720022d000e21040b200220043a00e0030b024020002003470d0041000d070240200020004101742205200041016a2206200520064b1b2205460d0020012000200510252201450d070b200220053602bc07200220013602b8070b200120036a20043a0000200341017221000c010b200141003a0001410221000b200220003602c0070b200241900b6a24002000ad4220862001ad840f0b200241246a4104360200200241f4036a4102360200200242023702e403200241e8c1c6003602e0032002410436021c200241ccc2c6003602182002410036020c2002419ca8c7003602082002200241186a3602f0032002200241086a360220200241e0036a41f8c1c600103a000b1033000b102a000b102c000bcb1305047f017e017f017e0b7f23004180026b2202240010c304200241106a41186a22034200370300200241106a41106a22044200370300200241106a41086a220542003703002002420037031041e4dec400ad4280808080e000842206100c220729000021082005200741086a290000370300200220083703102007102341f3dec400ad4280808080e00084100c22072900002108200241b0016a41086a2209200741086a290000370300200220083703b00120071023200420022903b0012208370300200241d0016a41086a220a2005290300370300200241d0016a41106a220b2008370300200241d0016a41186a220c2009290300370300200220022903103703d001200241086a200241d0016a412010cd0141002107200228020c410020022802081b10e703200342003703002004420037030020054200370300200242003703102006100c220d2900002108200241f0016a41086a220e200d41086a290000370300200220083703f001200d10232005200e290300370300200220022903f00137031041d0ffc400ad4280808080e00184100c220d2900002108200e200d41086a290000370300200220083703f001200d1023200420022903f0012208370300200a2005290300370300200b2008370300200c200e290300370300200220022903103703d0012002200241d0016a412010cd012002280204210d2002280200210f200241003602b801200242043703b001200241b0016a4100200d4100200f1b221010950120022802b801211102402010450d0020022802b0012011410c6c6a210d0340200241d0016a200710c702200241106a20022802d001221220022802d801221310b70302402002280210220f450d002013ad4220862012ad8410110b200741016a210720022902144200200f1b2108200f4101200f1b210f024020022802d401450d00201210230b200d200f360200200d41046a2008370200200d410c6a210d20102007470d000b201120106a21110b20024180016a41086a2011360200200220022903b001220837038001200520113602002002200837031020024190016a200241106a108501200241b0016a41186a20024190016a41186a290300370300200241b0016a41106a20024190016a41106a290300370300200920024190016a41086a29030037030020022002290390013703b001200342003703002004420037030020054200370300200242003703102006100c22072900002108200e200741086a290000370300200220083703f001200710232005200e290300370300200220022903f0013703104183dfc400ad4280808080e00184100c22072900002108200e200741086a290000370300200220083703f00120071023200420022903f001370000200441086a200e290300370000200a2005290300370300200b2004290300370300200c2003290300370300200220022903103703d001024002400240412010212207450d00200720022903b001370000200741186a200241b0016a41186a290300370000200741106a200241b0016a41106a290300370000200741086a200241b0016a41086a290300370000200241d0016aad42808080808004842007ad4280808080800484100e20071023200241106a10c404200241003602b801200242013703b001412010212207450d0020072002290320370000200741186a200241386a290300370000200741106a200241106a41206a290300370000200741086a200241106a41186a29030037000041201021220d450d02200241203602b4012002200d3602b001200d2007290000370000200d41086a200741086a290000370000200d41106a200741106a290000370000200d41186a200741186a290000370000200241203602b80120071023200241106a200241b0016a10ed01412010212207450d0020072002290340370000200741186a200241d8006a290300370000200741106a200241d0006a290300370000200741086a200241c8006a2903003700000240024020022802b401221020022802b80122136b4120490d00201341206a210d20022802b001210f201021120c010b201341206a220d2013490d022010410174220f200d200f200d4b1b22124100480d020240024020100d00024020120d004101210f0c020b20121021220f0d010c050b20022802b001210f20102012460d00200f201020121025220f450d040b200220123602b4012002200f3602b0010b200f20136a22132007290000370000201341186a200741186a290000370000201341106a200741106a290000370000201341086a200741086a2900003700002002200d3602b80120071023412010212207450d0020072002290360370000200741186a200241f8006a290300370000200741106a200241f0006a290300370000200741086a200241e8006a29030037000002402012200d6b411f4b0d00200d41206a2213200d490d02201241017422102013201020134b1b22134100480d020240024020120d00024020130d004101210f0c020b20131021220f450d050c010b20122013460d00200f201220131025220f450d040b200220133602b4012002200f3602b0010b200f200d6a220f2007290000370000200f41186a200741186a290000370000200f41106a200741106a290000370000200f41086a200741086a2900003700002002200d41206a3602b80120071023200228021421032002411c6a2802002211200241b0016a10610240024020110d0020022802b801210d20022802b00121050c010b201141246c210e20022802b401210f20022802b8012107200321130340200241d0016a201310e00220022802d001210402400240200f20076b20022802d8012210490d00200720106a210d20022802b0012105200f21120c010b200720106a220d2007490d04200f4101742212200d2012200d4b1b22124100480d0402400240200f0d00024020120d00410121050c020b201210212205450d070c010b20022802b0012105200f2012460d002005200f201210252205450d060b200220123602b401200220053602b0010b200520076a2004201010a1051a2002200d3602b801024020022802d401450d00200410230b201341246a21132012210f200d2107200e415c6a220e0d000b0b200dad42208621082005ad210602402011450d00201141246c210d2003210703400240024020072d0000220f41044b0d00024002400240200f0e050400010204040b2007410c6a280200450d03200741086a28020010230c030b2007410c6a280200450d02200741086a28020010230c020b2007410c6a280200450d01200741086a28020010230c010b200741086a280200450d00200741046a28020010230b200741246a2107200d415c6a220d0d000b0b200820068421080240200241186a2802002207450d00200741246c450d00200310230b20024180026a240020080f0b1033000b102c000b102a000bd81405017f017e017f017e0a7f230041a0066b22022400024002402001450d00200220003602180c010b2002419ca8c7003602180b2002200136021c200241106a200241186a1088010240024020022802100d00200228021421012002200241186a36029005200241003a008005200241003602f802200241003602f0022002200136025420024100360250200220024180056a36025c200220024190056a360258200241d0006a200241f0026a10ff03200241b8056a41086a20022802f8022201360200200220022903f00222033703b80520022d0080052100200241d0006a41086a22042001360200200220033703502000450d01200241d0006a10f5040b200241fc026a4104360200200241e4006a410236020020024202370254200241e8c1c600360250200241043602f402200241e4c2c6003602f002200241003602bc052002419ca8c7003602b8052002200241f0026a3602602002200241b8056a3602f802200241d0006a41f8c1c600103a000b200241206a41086a20042802002201360200200220022903502203370320200241306a41086a2001360200200220033703302002410036024820024208370340200241d0006a200241306a10730240024002400240024020022802504101460d00200241d0006a41086a22012903002103200241d0006a41186a4200370300200241d0006a41106a22044200370300200142003703002002420037035041b494c700ad4280808080900184100c220029000021052001200041086a290000370300200220053703502000102341bd94c700ad42808080803084100c22002900002105200241b8056a41086a2206200041086a290000370300200220053703b80520001023200420022903b8052205370300200241f0026a41086a2001290300370300200241f0026a41106a2005370300200241f0026a41186a2006290300370300200220022903503703f0022002200241f0026a10fa022002280200210020022903082105200241c0006a410010ac01200228024022072002280248220441c8036c6a220141023602980120014202370368200141a0016a2003200542b8177c42b81720001b220520032005561b3703002002200441016a22083602480240024020022802302209450d002002280234210a02400340200941086a210020092f0106220b4103742101410021040240024003402001450d0141c296c7002000410810a3052206450d02200141786a2101200441016a2104200041086a21002006417f4a0d000b2004417f6a210b0b200a450d02200a417f6a210a2009200b4102746a41e4016a28020021090c010b0b200941e0006a2004410c6c6a22012802084104490d0020012802002800002106200241d0006a41186a4200370300200241d0006a41106a22044200370300200241d0006a41086a220142003703002002420037035041fee2c200ad4280808080f00184100c220029000021032001200041086a290000370300200220033703502000102341a0e3c200ad4280808080b00184100c22002900002103200241b8056a41086a2209200041086a290000370300200220033703b80520001023200420022903b8052203370300200241f0026a41086a2001290300370300200241f0026a41106a2003370300200241f0026a41186a2009290300370300200220022903503703f002200241d0006a200241f0026a10ed0320022802502201410420011b21044100210002402002290254420020011b2203422088a72201450d00200141027420046a417c6a2201450d00200128020020064721000b0240200342ffffffff0383500d00200410230b2000450d00024020082002280244470d00200241c0006a200810ac0120022802402107200228024821080b2007200841c8036c6a200241f0026a41e80010a105220142023703682001419c016a20063602002001410936029801200120022903b805370370200141f8006a200241c0056a29030037030020014180016a200241c8056a29030037030020014188016a200241d0056a29030037030020014190016a200241d8056a290300370300200141a8016a200241d0006a41a00210a1051a2002200841016a22083602480b20022802302209450d002002280234210a0340200941086a210020092f0106220b4103742101410021040240024003402001450d0141f0fdc2002000410810a3052206450d02200141786a2101200441016a2104200041086a21002006417f4a0d000b2004417f6a210b0b200a450d02200a417f6a210a2009200b4102746a41e4016a28020021090c010b0b200220092004410c6c6a220141e8006a2802003602bc052002200141e0006a2802003602b805200241d0006a200241b8056a109c03200228025022000d0120024129360254200241a992c70036025041f8fdc2004125200241d0006a418084c30041a0fec2001034000b41b0fec200412a41a0fec200104f000b200241d0006a41086a280200210420022802542106200241d0006a200241f0026a418c0210a1051a024020082002280244470d00200241c0006a200810ac0120022802402107200228024821080b2007200841c8036c22096a200241b8056a41e80010a105220142023703682001200229039005370370200141f8006a20024190056a41086a29030037030020014180016a200241a0056a29030037030020014188016a200241a8056a29030037030020014190016a200241b0056a290300370300200141a8016a2004360200200141a4016a2006360200200141a0016a20003602002001428d8080801037039801200141ac016a200241d0006a418c0210a1051a200141c0036a20024180056a41086a290300370300200141b8036a2002290380053703002002280244210c200241306a10f504200941cc036a2201417f4c0d01200110212200450d02200241003602f802200220013602f402200220003602f002200841016a220d200241f0026a106102400240200d0d0020022802f802210020022802f002210b0c010b200841c8036c41c8036a210e20022802f402210420022802f8022101200721090340200220093602b805200241d0006a200241b8056a10b3022002280250210f02400240200420016b2002280258220a490d002001200a6a210020022802f002210b200421060c010b2001200a6a22002001490d06200441017422062000200620004b1b22064100480d060240024020040d00024020060d004101210b0c020b20061021220b0d010c090b20022802f002210b20042006460d00200b200420061025220b450d080b200220063602f4022002200b3602f0020b200b20016a200f200a10a1051a200220003602f80202402002280254450d00200f10230b200941c8036a21092006210420002101200e41b87c6a220e0d000b0b2000ad4220862103200bad21050240200d450d0020074198016a2101200841c8036c41c8036a210003402001109e03200141c8036a2101200041b87c6a22000d000b0b200320058421030240200c450d00200c41c8036c450d00200710230b200241a0066a240020030f0b200241f8026a200241dc006a290200370300200220022902543703f00241c3a3c7004128200241f0026a41eca3c70041fca3c7001034000b1032000b1033000b102c000b102a000be60203047f017e017f024020002802002201450d0020002802082102024020002802042200450d00034020012802e40121012000417f6a22000d000b0b02402002450d0041002103024003402001450d01410021040240200320012f0106490d00034002400240200128020022000d0041002103410021000c010b200441016a210420012f010421030b2001102320002101200320002f01064f0d000b200021010b200341016a210020012003410c6c6a220341e4006a2902002105200341e0006a28020021060240024020040d00200021030c010b200120004102746a41e4016a2802002101410021032004417f6a2200450d00034020012802e40121012000417f6a22000d000b0b2006450d022002417f6a210202402005a7450d00200610230b20020d000c020b0b41d095c700412b41c491c700102d000b2001450d0020012802002100200110232000450d00034020002802002101200010232001210020010d000b0b0bc82109087f017e0c7f017e017f037e017f017e017f230041e0026b22022400024002402001450d00200220003602180c010b2002419ca8c7003602180b2002200136021c200241f8006a200241186a109b0302400240200228027c2203450d0020024184016a28020021042002280280012105200241f8006a200241186a10b104200228027822060d0102402004450d00200441246c21002003210103400240024020012d0000220741044b0d0002400240024020070e050400010204040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b2005450d00200541246c450d00200310230b2002418c026a41043602002002418c016a41023602002002420237027c200241e8c1c600360278200241043602840220024180c3c60036028002200241003602642002419ca8c700360260200220024180026a360288012002200241e0006a36028802200241f8006a41f8c1c600103a000b200241f8006a41086a22012802002108200228027c2109200241106a200241186a1088010240024020022802100d00200228021421002002200241186a360250200241003a0020200241003602880220024100360280022002200036027c200241003602782002200241206a360284012002200241d0006a36028001200241f8006a20024180026a10ff03200241e0006a41086a20022802880222003602002002200229038002220a37036020022d00202107200120003602002002200a3703782007450d01200241f8006a10f5040b2002418c026a41043602002002418c016a41023602002002420237027c200241e8c1c600360278200241043602840220024180c3c60036028002200241003602642002419ca8c700360260200220024180026a360288012002200241e0006a36028802200241f8006a41f8c1c600103a000b200241306a41086a200241f8006a41086a220b280200220136020020022002290378220a370330200241c0006a41086a20013602002002200a370340200241013b015c2002410036025820024100360250200241d0006a41086a210c0240024002400240024002402008450d002006200841c8036c6a210d20024180026a410272210e200241e0006a410472210f200241f8006a41106a2110200621110340201141e8006a2903004202520d01024020112802980141024722120d00024002400240024020022802402213450d0020112903a001210a200228024421140340201341086a210020132f010622154103742101410021070240024003402001450d0141d5b0c0002000410810a3052216450d02200141786a2101200741016a2107200041086a21002016417f4a0d000b2007417f6a21150b2014450d022014417f6a2114201320154102746a41e4016a28020021130c010b0b0240201341e0006a2007410c6c6a220128020841074b0d00201742808080807083422984210a41a992c70021140c020b200a42f02e8020012802002900002217510d034131211841ecb2c50021140c020b201742808080807083421c84210a41ddb0c00021140b200aa721180b0240024020022d005d450d004182a6c7002101413121000c010b200241d0006a10f5042002410036025820024100360250200242e2c289abb68edbb7f40037036020024180026a410272410041da0010a0051a200241f8006a410041840110a0051a41e40110212216450d0920164100360200201641046a20024180026a41dc0010a1051a201641e0006a200241f8006a41840110a1051a200241003602542002201636025020162f010622114103742113417f210041002101024002400340024020132001470d00201121000c020b200241e0006a201620016a41086a410810a3052207450d02200141086a2101200041016a2100200741004e0d000b0b200242e2c289abb68edbb7f40037028c012002200c3602880120022000360284012002201636027c200241003602782002200241d0006a3602800120024180026a201420181074200241f8006a20024180026a10800420024180023b015c200241206a41086a200241d0006a41086a290300370300200220022903503703200c060b41d5a5c7002101412d21000b2002200036027c2002200136027841eba4c7004122200241f8006a4190a5c70041a0a5c7001034000b20120d0020112903a0012119200241f8006a200241c0006a10730240024020022802784101460d00200229038001210a200241f8006a41186a2200420037030020104200370300200b42003703002002420037037841b494c700ad4280808080900184100c2201290000211a200b200141086a2900003703002002201a3703782001102341bd94c700ad42808080803084100c2201290000211a200241e0006a41086a2207200141086a2900003703002002201a3703602001102320102002290360370000201041086a200729030037000020024180026a41086a200b29030037030020024180026a41106a201029030037030020024180026a41186a20002903003703002002200229037837038002200220024180026a10fa0202402019200a42b0ea017c560d004200211a2019200229030842b8177c42b81720022802001b220a540d020c030b41b0a5c700ad4280808080d00484210a201b428080808070832018ad84211b4201211a4100211c0c010b200229038001210a200228027c211c4201211a201d4280808080708320023502880184221d211b0b2002201b3703702002201cad422086201a843703602002200a37036802400240024020022d005d450d00413121014182a6c70021000c010b024002400240201aa72215450d00200241d0006a10f5042002410036025820024100360250200242f4d2b59bc7ae98b8303703200c010b20022802502113200242f4d2b59bc7ae98b8303703202013450d00200228025421140c010b200e410041da0010a0051a200241f8006a410041840110a0051a41e40110212213450d0a4100211420134100360200201341046a20024180026a41dc0010a1051a201341e0006a200241f8006a41840110a1051a20024100360254200220133602500b200a422088a72112200aa7211e02400340201341086a210020132f01062218410374210141002107024003402001450d01200241206a2000410810a3052216450d03200141786a2101200741016a2107200041086a21002016417f4a0d000b2007417f6a21180b02402014450d002014417f6a2114201320184102746a41e4016a28020021130c010b0b200242f4d2b59bc7ae98b83037028c012002200c3602880120022018360284012002201336027c200241003602782002200241d0006a360280014101102121010240024020150d002001450d0c200141003a000020014101410910252201450d0c2001200a37000141092107410921000c010b2001450d0b200141013a000020024180026a200f10900120022802800221130240024020022802880222160d0041012107201641016a21000c010b201641016a22002016490d0920004102200041024b1b22074100480d0920014101200710252201450d0c0b200141016a2013201610a1051a200228028402450d00201310230b200220003602880220022007360284022002200136028002200241f8006a20024180026a1080042002201a3c005d200241003a005c20150d022015450d03201c450d032012450d03201e10230c030b412d210141d5a5c70021000b200220003602782002200136027c41eba4c7004122200241f8006a4190a5c70041a0a5c7001034000b200241206a41086a200241d0006a41086a29030037030020022002290350370320201c450d032012450d03201e10230c030b201141c8036a2211200d470d000b0b200241206a41086a200c290300370300200220022903503703200b200241c0006a10f50402402004450d00200441246c21002003210103400240024020012d0000220741044b0d0002400240024020070e050400010204040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b02402005450d00200541246c450d00200310230b02402008450d00200841c8036c210020064198016a210103402001109e03200141c8036a2101200041b87c6a22000d000b0b02402009450d00200941c8036c450d00200610230b200241003602682002420137036020022d002c2100410110212201450d032002410136026420022001360260200120003a00002002410136026820022d002d210020014101410210252201450d032002410236026420022001360260200120003a00012002410236026820022802282200200241e0006a106102400240024020022802202201450d00024020022802242216450d002016210720012113034020132802e40121132007417f6a22070d000b200121070340200720072f01064102746a41e4016a28020021072016417f6a22160d000b200241f8006a2116201321010c020b200241f8006a2116200121070c010b410021012002410036027c200241f8006a21160c010b2002200736027c20024184016a20072f0106360200200241003602782002200241206a36028001200241206a21070b20024180026a41086a201641086a290200220a37030020022016290200221a37038002200241f8006a410c6a410036020020024190016a200a37030020022007360280012002200136027c200241003602782002201a3703880120022000360298012000450d01034020022000417f6a36029801200241f8006a410020011b2213280200210720132802082114024002400240201328020c2216201328020422002f01064f0d00200021010c010b0240034020002802002201450d01200741016a210720002f0104211620012100201620012f0106490d020c000b0b2014ad210a410021010c010b2016ad4220862014ad84210a0b200a422088a7221441016a2116200aa721180240024020070d00200121000c010b200120164102746a41e4016a2802002100410021162007417f6a2207450d00034020002802e40121002007417f6a22070d000b0b2013201636020c2013201836020820132000360204201341003602000240024020022802642216200228026822006b4108490d00200228026021070c010b200041086a22072000490d02201641017422132007201320074b1b22134100480d020240024020160d00024020130d00410121070c020b2013102122070d010c070b2002280260210720162013460d0020072016201310252207450d060b20022013360264200220073602600b200720006a200120144103746a41086a2900003700002002200041086a360268200141e0006a2014410c6c6a2201280200211320012802082201200241e0006a10610240024020022802642216200228026822006b2001490d00200228026021070c010b200020016a22072000490d02201641017422142007201420074b1b22144100480d020240024020160d00024020140d00410121070c020b201410212207450d070c010b2002280260210720162014460d0020072016201410252207450d060b20022014360264200220073602600b200720006a2013200110a1051a2002200020016a22013602682002280298012200450d03200228027c21010c000b0b102c000b20022802682101200228026021070b200241206a10f504200241e0026a24002001ad4220862007ad840f0b102a000bbf0101067f230041206b220224002002419ca8c700410010a80302400240412010212203450d0020032002290300370000200341186a2204200241186a290300370000200341106a2205200241106a290300370000200341086a2206200241086a290300370000412010212207450d0120072003290000370000200741186a2004290000370000200741106a2005290000370000200741086a200629000037000020031023200241206a24002007ad42808080808004840f0b1033000b102a000bc44705037f017e067f047e077f230041d0126b220224000240024020010d002002200136020c2002419ca8c7003602080c010b2002200136020c20022001417f6a36020c200220003602082002200041016a36020820002d000041034f0d00200241e00a6a200241086a10d303024002400240024002400240024002400240024020022903c80b4203510d00200241c8006a200241e00a6a41c80310a1051a20024190046a200241c8006a41c80310a1051a200220024190046a3602d807200241e00a6a200241d8076a10b30220022802e80a2103024020022802e40a450d0020022802e00a10230b200241e00a6a20024190046a41c80310a1051a200241d8076a200241e00a6a10c60241012101024020022d00d8074101460d00200241e00a6a200241d8076a41086a41800310a1051a200241a80e6a200241b00b6a220410c90220022903a80e210502400240024020022903800b4202520d00200241a0126a41206a22004200370300200241a0126a41186a22014280808080c000370300200241013a00c812200242043703b0122002427f3703a812200242003703a012200241d8076a41206a22064200370300200241d8076a41186a22074280808080c000370300200241013a008008200242043703e8072002427f3703e007200242003703d807200241f00e6a200241a0126a200241d8076a109401200241a0126a41286a2208200241f00e6a41286a2903003703002000200241f00e6a41206a2903003703002001200241f00e6a41186a290300370300200241a0126a41106a2209200241f00e6a41106a290300370300200241a0126a41086a220a200241f00e6a41086a290300370300200220022903f00e3703a0122006420037030020074280808080c000370300200241013a008008200242043703e8072002427f3703e007200242003703d807200241a00f6a200241a0126a200241d8076a1094012008200241a00f6a41286a2903003703002000200241a00f6a41206a2903003703002001200241a00f6a41186a2903003703002009200241a00f6a41106a290300370300200a200241a00f6a41086a290300370300200220022903a00f3703a0122006420037030020074280808080c000370300200241013a008008200242043703e8072002427f3703e007200242003703d807200241d00f6a200241a0126a200241d8076a1094012008200241d00f6a41286a2903003703002000200241d00f6a41206a2903003703002001200241d00f6a41186a2903003703002009200241d00f6a41106a290300370300200a200241d00f6a41086a290300370300200220022903d00f3703a0122006420037030020074280808080c000370300200241013a008008200242043703e8072002427f3703e007200242003703d80720024180106a200241a0126a200241d8076a109401200820024180106a41286a290300370300200020024180106a41206a290300370300200120024180106a41186a290300370300200920024180106a41106a290300370300200a20024180106a41086a29030037030020022002290380103703a0122006420037030020074280808080c000370300200241013a008008200242043703e8072002427f3703e007200242003703d807200241b0106a200241a0126a200241d8076a109401200241f0116a41286a200241b0106a41286a290300370300200241f0116a41206a220b200241b0106a41206a290300370300200241f0116a41186a220a200241b0106a41186a290300370300200241f0116a41106a200241b0106a41106a290300370300200241f0116a41086a200241b0106a41086a290300370300200220022903b0103703f011200220053703c011200241d8076a200241c0116a200310c504024020022d00d8074101470d0020022d00db07210720022f00d907210820022802801221060240200a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b024020024184126a2802002200450d002000410c6c450d00200610230b200228028c122106024020024194126a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b024020024190126a2802002200450d002000410c6c450d00200610230b4101450d02200820074110747221000c090b200820024188086a2903003703002000200241d8076a41286a2903003703002001200629030037030020092007290300370300200241a0126a41086a2203200241d8076a41106a290300370300200220022903e0073703a012200241e0106a200241f0116a200241a0126a1094012008200241e0106a41286a2903003703002000200241e0106a41206a2903003703002001200241e0106a41186a2903003703002009200241e0106a41106a2903003703002003200241e0106a41086a290300370300200220022903e0103703a0122006420037030020074280808080c000370300200241013a008008200242043703e8072002427f3703e007200242003703d80720024190116a200241a0126a200241d8076a109401200820024190116a41286a290300370300200020024190116a41206a290300370300200120024190116a41186a290300370300200920024190116a41106a290300370300200320024190116a41086a29030037030020022002290390113703a0122006420037030020074280808080c000370300200241013a008008200242043703e8072002427f3703e007200242003703d807200241c0116a200241a0126a200241d8076a1094012008200241c0116a41286a2903003703002000200241c0116a41206a2903003703002001200241c0116a41186a2903003703002009200241c0116a41106a2903003703002003200241c0116a41086a290300370300200220022903c0113703a0122006420037030020074280808080c000370300200241013a008008200242043703e8072002427f3703e007200242003703d807200241f0116a200241a0126a200241d8076a109401200241cc0e6a200241f0116a41086a290300370200200220022903f0113702c40e41000d0820024184126a2802002106200a2802002100200b280200210720024194126a28020021082002280280122109200228028c12210320022903981221050c020b200241a0126a41206a22004200370300200241a0126a41186a22014280808080c000370300200241013a00c812200242043703b012427f210c2002427f3703a812200242003703a012200220022800f0113602c0112002200241f3116a2800003600c311024020022802b00b410f470d00200241023a0013200241800e3b0011200241013a00100c090b200241d8076a41206a22074200370300200241d8076a41186a22064280808080c00037030020024184086a20022800c311360000200241013a008008200242043703e8072002427f3703e007200242003703d807200220022802c01136008108200241c00e6a200241a0126a200241d8076a109401200241a0126a41286a2208200241c00e6a41286a2903003703002000200241c00e6a41206a2903003703002001200241c00e6a41186a290300370300200241a0126a41106a2209200241c00e6a41106a290300370300200241a0126a41086a220a200241c00e6a41086a290300370300200220022903c00e3703a0122007420037030020064280808080c000370300200241013a008008200242043703e8072002427f3703e007200242003703d807200241f00e6a200241a0126a200241d8076a1094012008200241f00e6a41286a2903003703002000200241f00e6a41206a2903003703002001200241f00e6a41186a2903003703002009200241f00e6a41106a290300370300200a200241f00e6a41086a290300370300200220022903f00e3703a0122007420037030020064280808080c000370300200241013a008008200242043703e8072002427f3703e007200242003703d807200241a00f6a200241a0126a200241d8076a1094012008200241a00f6a41286a2903003703002000200241a00f6a41206a2903003703002001200241a00f6a41186a2903003703002009200241a00f6a41106a290300370300200a200241a00f6a41086a290300370300200220022903a00f3703a01220064200370300200241d8076a41106a22074200370300200241d8076a41086a22014200370300200242003703d80741e4dec400ad4280808080e00084100c2206290000210d200241f0116a41086a2200200641086a2900003703002002200d3703f0112006102320012000290300370300200220022903f0113703d80741f3dec400ad4280808080e00084100c2206290000210d200241c0116a41086a2208200641086a2900003703002002200d3703c01120061023200720022903c011220d37030020002001290300370300200241f0116a41106a2201200d370300200241f0116a41186a2008290300370300200220022903d8073703f0112002200241f0116a412010cd012002280204410020022802001bad210d024020022903800b4201520d0020022903880b220c4200510d05200d200241900b6a290300220e200e200d541b220f200c7c200f200e7d200c827d210c0b200241d8076a41206a4200370300200241d8076a41186a4280808080c000370300200241013a008008200242043703e807200242003703d80720024200200c200d7d220d200d200c561b3703e007200241d00f6a200241a0126a200241d8076a109401200241f0116a41286a200241d00f6a41286a290300370300200241f0116a41206a200241d00f6a41206a290300370300200241f0116a41186a200241d00f6a41186a2903003703002001200241d00f6a41106a2903003703002000200241d00f6a41086a290300370300200220022903d00f3703f011200241c0116a200241e00a6a109702200241d8076a20022802c011220020022802c811109802200241a0086a280200410020022903d8074201511b2101024020022802c411450d00200010230b0240024020022802a80b22062001490d00410c10212207450d0e410410212200450d0c20004104412010252200450d0e200020022903e00a370000200041186a200241e00a6a41186a290300370000200041106a200241e00a6a41106a290300370000200041086a200241e00a6a41086a2903003700002000412041c00010252200450d0e20002006360020200742c0808080c004370204200720003602000240024020012006490d0041002100410421010c010b410c10212201450d0f410410212200450d0d20004104412010252200450d0f200020022903e00a370000200041186a200241e00a6a41186a290300370000200041106a200241e00a6a41106a290300370000200041086a200241e00a6a41086a2903003700002000412041c00010252200450d0f20002006417f6a360020200142c0808080c00437020420012000360200410121000b200241a0126a41206a428180808010370300200241a0126a41186a2000360200200241b4126a2000360200200241cc126a20024193116a280000360000200241013a00c812200220073602bc12200220013602b0122002427f3703a81220022002280090113600c9122002200542ffffffff0f833703a01220024180106a200241f0116a200241a0126a109401200241f0116a41286a20024180106a41286a290300370300200241f0116a41206a20024180106a41206a290300370300200241f0116a41186a20024180106a41186a290300370300200241f0116a41106a20024180106a41106a290300370300200241f0116a41086a20024180106a41086a29030037030020022002290380103703f0110240024020054280808080f01f83428080808020520d00200241003a00db07418012210020024180123b00d907200241013a00d8070c010b200220053703c011200241d8076a200241c0116a200310c50420022d00d8074101470d0220022f00d90720022d00db074110747221000b200241013a0010200220003b0011200220004110763a00132002280280122106024020024188126a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b024020024184126a2802002200450d002000410c6c450d00200610230b200228028c122106024020024194126a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b20024190126a2802002200450d0a2000410c6c450d0a200610230c0a0b200241003a001320024180063b0011200241013a00102002280280122106024020024188126a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b024020024184126a2802002200450d002000410c6c450d00200610230b200228028c122106024020024194126a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b20024190126a2802002200450d092000410c6c450d09200610230c090b200241a0126a41286a220120024188086a2206290300370300200241a0126a41206a2207200241d8076a41286a2208290300370300200241a0126a41186a2209200241d8076a41206a220a290300370300200241a0126a41106a220b200241d8076a41186a2210290300370300200241a0126a41086a2211200241d8076a41106a2212290300370300200220022903e0073703a012200241b0106a200241f0116a200241a0126a109401200241f0116a41286a2213200241b0106a41286a290300370300200241f0116a41206a2214200241b0106a41206a290300370300200241f0116a41186a2200200241b0106a41186a290300370300200241f0116a41106a2215200241b0106a41106a290300370300200241f0116a41086a2216200241b0106a41086a290300370300200220022903b0103703f011200220053703c011200241d8076a20022903980b200241a00b6a290300200241e00a6a200241c0116a200310cc02024020022d00d8074101470d00200220022d00db073a0013200220022f00d9073b0011200241013a00102002280280122106024020002802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b024020024184126a2802002200450d002000410c6c450d00200610230b200228028c122106024020024194126a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b20024190126a2802002200450d092000410c6c450d09200610230c090b20012006290300370300200720082903003703002009200a290300370300200b201029030037030020112012290300370300200220022903e0073703a012200241e0106a200241f0116a200241a0126a1094012013200241e0106a41286a2903003703002014200241e0106a41206a2903003703002000200241e0106a41186a2903003703002015200241e0106a41106a2903003703002016200241e0106a41086a290300370300200220022903e0103703f011200241d8076a200410cd02024020022d00d8074101470d00200220022d00db073a0013200220022f00d9073b0011200241013a00102002280280122106024020024188126a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b024020024184126a2802002200450d002000410c6c450d00200610230b200228028c122106024020024194126a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b20024190126a2802002200450d092000410c6c450d09200610230c090b200241a0126a41286a2200200241d8076a41306a2201290300370300200241a0126a41206a2206200241d8076a41286a2207290300370300200241a0126a41186a2208200241d8076a41206a2209290300370300200241a0126a41106a2203200241d8076a41186a220a290300370300200241a0126a41086a220b200241d8076a41106a2210290300370300200220022903e0073703a01220024190116a200241f0116a200241a0126a109401200241f0116a41286a20024190116a41286a290300370300200241f0116a41206a20024190116a41206a290300370300200241f0116a41186a221120024190116a41186a290300370300200241f0116a41106a20024190116a41106a290300370300200241f0116a41086a20024190116a41086a29030037030020022002290390113703f011200241d8076a200410ce0220022d00d8074101470d06200220022d00db073a0013200220022f00d9073b0011200241013a00102002280280122106024020112802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b024020024184126a2802002200450d002000410c6c450d00200610230b200228028c122106024020024194126a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b20024190126a2802002200450d082000410c6c450d08200610230c080b0b200241b80e6a200241cc0e6a290200370300200220022902c40e3703b00e0240024020022802b00b410b460d00200241003a00db07418102210120024181023b00d907200241013a00d8070c010b200241d8076a200241b40b6a10ab0220022d00d8074101470d0420022f00d90720022d00db074110747221010b200241013a0010200220013b0011200220014110763a001302402000450d002000410c6c21012009210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b02402006450d002006410c6c450d00200910230b02402008450d002008410c6c21012003210003400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b2007450d062007410c6c450d06200310230c060b200220022d00db073a0013200220022f00d9073b0011200241013a00100c060b200241d4006a4104360200200241a4046a41023602002002420237029404200241e8c1c600360290042002410436024c20024198c3c600360248200241003602dc072002419ca8c7003602d8072002200241c8006a3602a0042002200241d8076a36025020024190046a41f8c1c600103a000b4180b4c0004119419cb4c000102d000b200241c0116a41286a2201200241d8076a41306a290300370300200241c0116a41206a220a200241d8076a41286a220b290300370300200241c0116a41186a2210200241d8076a41206a2211290300370300200241c0116a41106a2212200241d8076a41186a2213290300370300200241c0116a41086a2214200241d8076a41106a2215290300370300200220022903e0073703c011200241a0126a41086a200241b00e6a41086a290300370300200241c4126a2008360200200241a0126a41206a2007360200200241a0126a41186a2000360200200241b4126a2006360200200220022903b00e3703a012200220053703c812200220033602bc12200220093602b012200b20012903003703002011200a2903003703002013201029030037030020152012290300370300200241d8076a41086a2014290300370300200220022903c0113703d807200241f0116a200241a0126a200241d8076a109401200241106a41086a20022903f011370300200241106a41106a200241f0116a41086a290300370300200241106a41186a200241f0116a41106a290300370300200241106a41206a200241f0116a41186a290300370300200241106a41286a200241f0116a41206a290300370300200241106a41306a200241f0116a41286a290300370300200241003a00100c020b2000200129030037030020062007290300370300200820092903003703002003200a290300370300200b2010290300370300200220022903e0073703a012200241c0116a200241f0116a200241a0126a109401200241106a41086a20022903c011370300200241106a41106a200241c0116a41086a290300370300200241106a41186a200241c0116a41106a290300370300200241106a41206a200241c0116a41186a290300370300200241106a41286a200241c0116a41206a290300370300200241106a41306a200241c0116a41286a290300370300200241003a00100c010b200241013a0010200220003b0011200220004110763a00130b200410b40220022d001021010b410110212200450d00200242013702e40a200220003602e00a02400240200141ff01714101470d00200041013a0000200241013602e80a200241106a410172200241e00a6a10810420022802e80a21000c010b200041003a0000200241013602e80a200241186a2903002105024020022802e40a2201417f6a41074b0d00200141017422064109200641094b1b22064100480d03024020012006460d0020002001200610252200450d050b200220063602e40a200220003602e00a0b20002005370001200241093602e80a200241286a2802002101200241306a2802002200200241e00a6a106102402000450d0020012000410c6c6a2104034020012802002109200141086a2802002200200241e00a6a10610240024020022802e40a220820022802e80a22066b2000490d0020022802e00a21070c010b200620006a22072006490d05200841017422032007200320074b1b22034100480d050240024020080d00024020030d00410121070c020b2003102122070d010c080b20022802e00a210720082003460d0020072008200310252207450d070b200220033602e40a200220073602e00a0b200720066a2009200010a1051a2002200620006a3602e80a2001410c6a22012004470d000b0b200241346a28020021012002413c6a2802002200200241e00a6a10610240024020000d0020022802e40a210920022802e80a21000c010b20012000410c6c6a2104034020012802002103200141086a2802002200200241e00a6a10610240024020022802e40a220720022802e80a22066b2000490d0020022802e00a2108200721090c010b200620006a22082006490d05200741017422092008200920084b1b22094100480d050240024020070d00024020090d00410121080c020b200910212208450d080c010b20022802e00a210820072009460d0020082007200910252208450d070b200220093602e40a200220083602e00a0b200820066a2003200010a1051a2002200620006a22003602e80a2001410c6a22012004470d000b0b200241206a290300210502400240200920006b4108490d0020022802e00a21010c010b200041086a22012000490d03200941017422062001200620014b1b22064100480d030240024020090d00024020060d00410121010c020b200610212201450d060c010b20022802e00a210120092006460d0020012009200610252201450d050b200220063602e40a200220013602e00a0b200120006a20053700002002200041086a22003602e80a200241c0006a2d00002106024020022802e40a2000470d00200041016a22072000490d03200041017422082007200820074b1b22074100480d030240024020000d0041002100024020070d00410121010c020b200710212201450d060c010b20002007460d0020012000200710252201450d050b200220073602e40a200220013602e00a0b200120006a20063a00002002200041016a22003602e80a0b2000ad42208620023502e00a842105024020022d00100d000240200241306a2802002201450d00200241286a28020021002001410c6c210103400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b02402002412c6a2802002200450d002000410c6c450d00200228022810230b02402002413c6a2802002201450d00200241346a28020021002001410c6c210103400240200041046a280200450d00200028020010230b2000410c6a2100200141746a22010d000b0b200241386a2802002200450d002000410c6c450d00200228023410230b200241d0126a240020050f0b1033000b102c000b102a000b2002419c046a4104360200200241f40a6a4102360200200242023702e40a200241e8c1c6003602e00a200241043602940420024198c3c600360290042002410036024c2002419ca8c700360248200220024190046a3602f00a2002200241c8006a36029804200241e00a6a41f8c1c600103a000ba5360a047f017e017f017e087f017e037f017e0d7f017e230022022103200241a0046b41607122022400024002402001450d00200220003602300c010b2002419ca8c7003602300b20022001360234200241a8026a200241306a109b03024002400240024002400240024020022802ac02450d00200241386a200241a8026a41f00010a1051a200241a8016a200241386a10bf022002280238200241c8006a20024188016a200241a8016a410010c2024100410028029cab472201410120011b36029cab470240200141014b0d000240024020010e020001000b410041e49fc00036028880404100419ca8c70036028480404100410236029cab470c010b0340410028029cab474101460d000b0b2002410020022802382201417f6a2200200020014b1b22043602b401101e4101470d01200241a8026a41186a22054200370300200241a8026a41106a22004200370300200241a8026a41086a22014200370300200242003703a8024180cdc200ad42808080808001842206100c220729000021082001200741086a290000370300200220083703a8022007102341c9a1c200ad4280808080e00184100c22092900002108200241e0016a41086a2207200941086a290000370300200220083703e00120091023200020022903e0012208370300200241c0036a41086a22092001290300370300200241c0036a41106a220a2008370300200241c0036a41186a220b2007290300370300200220022903a8023703c003200241286a200241c0036a412010cd010240200228022c410020022802281b220c20044d0d0041002107200241c0036a2100200241b8016a21010c060b200542003703002000420037030020014200370300200242003703a80241db97c700ad4280808080f00084100c220d29000021082001200d41086a290000370300200220083703a802200d102341bcbcc300ad4280808080c00184100c220d29000021082007200d41086a290000370300200220083703e001200d1023200020022903e001220837030020092001290300370300200a2008370300200b2007290300370300200220022903a8023703c003200241206a200241c0036a412010cd012002280224210e2002280220210f200542003703002000420037030020014200370300200242003703a8022006100c220529000021082001200541086a290000370300200220083703a8022005102341d7a1c200ad4280808080c00084100c220529000021082007200541086a290000370300200220083703e00120051023200020022903e001220837030020092001290300370300200a2008370300200b2007290300370300200220022903a8023703c003200241a8026a200241c0036a10ad0220022802a802211020022902ac022111200241a8026a41e9dabdf306108e0120022802a802210920022802ac02210a02400240024020022802b00222000d004101211241002113410021140c010b02400240024020004105742201410575220741ffffff3f712007470d0020014100480d0020010d01410121120c020b102c000b200110212212450d020b200920016a210b2000410574210520014105762113410021010340200920016a22002900002108200041086a2900002106200041106a2900002115201220016a220741186a200041186a290000370000200741106a2015370000200741086a2006370000200720083700002005200141206a2201470d000b200b20096b41606a41057641016a21140b0240200a41ffffff3f71450d00200910230b20144115490d0402404101450d0020144104744160712216417f4c0d000240201610212217450d00200241003602e801200242043703e001201241606a2118201241a07f6a211941042107410021014100211a2014211b0340201b210d4100211b4101210b0240200d417f6a2205450d00024002400240024002400240201220054105746a200d410574221c20126a41406a412010a3054100480d00200d417e6a210a2019201c6a21004100211b4100210903400240200a2009470d00200d210b0c080b200941016a2109200041206a2000412010a3052105200041606a21002005417f4a0d000b200941016a210b2009417f73200d6a21050c010b2019201c6a210002400340024020054101470d00410021050c020b2005417f6a2105200041206a2000412010a3052109200041606a210020094100480d000b0b200d2005490d01200d20144b0d02200d20056b220b410176220a450d002018201c6a2100201220054105746a21090340200241c0036a41186a221c200941186a220c290000370300200241c0036a41106a221d200941106a221e290000370300200241c0036a41086a221f200941086a221b290000370300200220092900003703c003200041086a22202900002108200041106a22212900002106200041186a2222290000211520092000290000370000200c2015370000201e2006370000201b20083700002022201c2903003700002021201d2903003700002020201f290300370000200020022903c003370000200041606a2100200941206a2109200a417f6a220a0d000b0b024020050d002005211b0c050b0240200b41094d0d002005211b0c050b200d20144b0d02200d20056b210a201220054105746a211c0340200d2005417f6a221b490d040240200d201b6b220b4102490d00201220054105746a22002012201b4105746a2205412010a305417f4a0d00200241a8026a41186a221f200541186a2209290000370300200241a8026a41106a2220200541106a220c290000370300200241a8026a41086a2221200541086a221d290000370300200220052900003703a80220052000290000370000201d200041086a290000370000200c200041106a2900003700002009200041186a2900003700004101211e0240200b4103490d00200541c0006a200241a8026a412010a305417f4a0d0041022109201c210002400340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a220c290000370000200a2009460d01200041c0006a211d2009211e200c2100200941016a2109201d200241a8026a412010a305417f4a0d020c000b0b2009211e0b2005201e4105746a220020022903a802370000200041186a201f290300370000200041106a2020290300370000200041086a20212903003700000b201b450d05201c41606a211c200a41016a210a201b2105200b410a4f0d050c000b0b2005200d41d089c7001044000b200d201441d089c7001043000b200d2005417f6a221b490d00200d201441e089c7001043000b201b200d41e089c7001044000b0240201a20022802e401470d00200241e0016a201a410110a50120022802e001210720022802e8012201211a0b2007201a4103746a2200200b3602042000201b3602002002200141016a22013602e8012001211a024020014102490d000240024003400240024002400240024020072001417f6a4103746a2200280200450d00200141037420076a220a41746a2802002205200028020422094b0d010b20014103490d022000280204210920072001417d6a221d4103746a28020421000c010b4102211a200141024d0d0620072001417d6a221d4103746a2802042200200920056a4d0d004103211a200141034d0d06200a41646a280200200020056a4b0d050b20002009490d010b2001417e6a211d0b02400240024002400240024002402001201d41016a221e4d0d002001201d4d0d012007201d41037422206a2201280204222120012802006a22012007201e41037422226a2200280200221f490d02200120144b0d032012201f4105746a221c2000280204220c41057422006a2109200141057421072001201f6b220a200c6b2201200c4f0d04201720092001410574220010a105220d20006a2105200c4101480d0520014101480d05201820076a21072009210103402007200141606a2209200541606a220a200a2009412010a305410048220b1b2200290000370000200741186a200041186a290000370000200741106a200041106a290000370000200741086a200041086a2900003700002005200a200b1b21050240201c20092001200b1b2201490d00200d21000c080b200741606a2107200d2100200d2005490d000c070b0b201e200141f089c7001030000b201d200141808ac7001030000b201f200141908ac7001044000b2001201441908ac7001043000b2017201c200010a105220d20006a21050240200c4101480d00200a200c4c0d00201220076a210b200d2100201c2101034020012009200020092000412010a305410048220a1b2207290000370000200141186a200741186a290000370000200141106a200741106a290000370000200141086a200741086a2900003700002000200041206a200a1b2100200141206a2101200941206a2009200a1b2209200b4f0d03200520004b0d000c030b0b201c2101200d21000c010b20092101200d21000b20012000200520006b41607110a1051a024020022802e8012201201d4d0d0020022802e001220720206a22002021200c6a3602042000201f3602002001201e4d0d02200720226a2200200041086a2001201e417f736a41037410a2051a20022001417f6a22013602e801200141014b0d010c030b0b201d200141a08ac7001030000b201e2001103b000b2001211a0b201b450d060c000b0b1033000b1032000b102a000b200241cc036a4104360200200241cc006a41023602002002420237023c200241e8c1c600360238200241043602c403200241b4c3c6003602c003200241003602e4012002419ca8c7003602e0012002200241c0036a3602482002200241e0016a3602c803200241386a41f8c1c600103a000b4100280298ab474105490d042002410f3602c4032002200241b4016a3602c003410028028880402101410028028480402100410028029cab472107200241e8026a41e902360200200241e0026a42df80808010370300200241dc026a41fca5c200360200200241d4026a4210370200200241d0026a41eca5c200360200200241c8026a4201370300200241b8026a4202370300200241a8026a41086a4108360200200241c4026a200241c0036a360200200241d4a5c2003602b402200241e4a5c2003602ac02200241053602a802200041a0a1c000200741024622071b200241a8026a200141b8a1c00020071b2802101102000c040b024020022802e40141ffffffff0171450d00200710230b2016450d01201710230c010b20144102490d0020122014417f6a22004105746a21054101210703400240024002400240201420002201417f6a2200490d00201420006b220a4102490d03201220014105746a2201201220004105746a2209412010a305417f4a0d03200241a8026a41186a220c200941186a220b290000370300200241a8026a41106a221d200941106a220d290000370300200241a8026a41086a221e200941086a221c290000370300200220092900003703a80220092001290000370000201c200141086a290000370000200d200141106a290000370000200b200141186a29000037000041012101200a4103490d02200941c0006a200241a8026a412010a305417f4a0d024100210a200521010340200141186a200141386a290000370000200141106a200141306a290000370000200141086a200141286a2900003700002001200141206a220d2900003700002007200a220b460d02200b417f6a210a200141c0006a211c200d2101201c200241a8026a412010a305417f4a0d020c000b0b2000201441c089c7001044000b4102200b6b21010b200920014105746a220120022903a802370000200141186a200c290300370000200141106a201d290300370000200141086a201e2903003700000b200541606a21052007417f6a210720000d000b0b200220043602d4012002200e4100200f1b22013602d001200220143602cc01200220133602c801200220123602c401200241003602c001200220043602dc03200220013602d803200220143602d403200220133602d003200220123602cc03200241003602c80320022010410120101b22073602c003200220073602b801200220072011420020101b2208422088a74105746a22013602c403200220013602bc012008a7210c200241c0036a2100200241b8016a21010b20024188026a41086a220a200141086a29020037030020024188026a41106a220b200141106a29020037030020024188026a41186a220d200141186a290200370300200241e0016a41086a221c200241a8026a41086a2209290200370300200241e0016a41106a221d200241a8026a41106a290200370300200241e0016a41186a221e200241a8026a41186a290200370300200241e0016a41206a221f200241a8026a41206a2802003602002002200129020037038802200220022902a8023703e001200241b8016a41206a2201200241c0036a41206a280200360200200241b8016a41186a221b200241c0036a41186a290200370300200241b8016a41106a2212200241c0036a41106a290200370300200241b8016a41086a2220200241c0036a41086a290200370300200220022902c0033703b8012009200c360200200220073602ac02200241013602a802200241b4026a2209200229038802370200200241bc026a2205200a290300370200200241c4026a220a200b290300370200200241cc026a200d290300370200200241003602d402200241d8026a20022903e001370300200241e0026a201c290300370300200241e8026a201d290300370300200241f0026a201e290300370300200241f8026a201f280200360200200241003602fc02200241a0036a200128020036020020024198036a201b29030037030020024190036a201229030037030020024188036a202029030037030020024180036a20022903b801370300200241dc026a2101200241fc026a211f200241d4026a211c200241e4026a210b200241ec026a210d41002107034002400240024002400240024002402007450d00200241186a201c10b0020240200228021822074108460d00200228021c211e0c020b024020022802d4022207450d00024020022802d80241ffffff3f71450d00200710230b20022802ec0241ffffff3f71450d0020022802e80210230b20012000290200370200200141086a200041086a290200370200200141106a200041106a290200370200200141186a200041186a2902003702002002200c3602d802200241003602d4020b200a2902002106200a20022903d80337020020052902002115200520022903d00337020020092902002111200920022903c803370200200241003602c00320022902ac022108200220022903c00322233702ac0202402008a72207450d0020022902cc02212320012011370200200b2015370200200d2006370200200220083702d402200220233702f4020c070b20022802fc02450d01200241106a201f10b0022002280214211e200228021021070b200741796a221d41014b0d030240201d0e020500050b20022802a802450d0220022802ac0221010c010b2023a721010b2001450d00024020022802b00241ffffff3f71450d00200110230b200241c4026a28020041ffffff3f71450d00200241c0026a28020010230b024020022802d4022201450d00024020022802d80241ffffff3f71450d00200110230b20022802ec0241ffffff3f71450d0020022802e80210230b20022802fc022201450d03024020024180036a28020041ffffff3f71450d00200110230b20024194036a28020041ffffff3f71450d0320024190036a28020010230c030b200220073602a8032002201e3602ac034100280298ab474104490d00200241153602bc032002410f3602b4032002200241a8036a3602b8032002200241b4016a3602b00341002802888040210741002802848040211d410028029cab47211e200241e00236028004200242df808080103703f803200241fca5c2003602f403200242103702ec03200241eca5c2003602e803200242023703e003200242023703d003200241c4a5c2003602cc03200241083602c803200241e4a5c2003602c403200241043602c003200741b8a1c000201e410246221e1b28021021072002200241b0036a3602dc03201d41a0a1c000201e1b200241c0036a20071102000b20022802d40221070c000b0b200241c0036a41186a4200370300200241c0036a41106a22074200370300200241c0036a41086a22014200370300200242003703c003418fcdc200ad4280808080f00084100c220029000021082001200041086a290000370300200220083703c0032000102341ccc5c000ad4280808080900284100c22002900002108200241e0016a41086a2209200041086a290000370300200220083703e00120001023200720022903e0012208370300200241a8026a41086a2001290300370300200241a8026a41106a2008370300200241a8026a41186a2009290300370300200220022903c0033703a802200241086a200241a8026a108802024020022802084101470d00200228020c2004470d00200241e0016a4100419c94c700ad42808080808003841014108b0102400240024020022802e0012201450d00200241e8016a2802004104490d004182ecc3002100200420012800002207490d014187ecc3002100200741056a20044f0d010b2002200436028802200220043602b801200241c0036a41086a200241e0016a41086a280200360200200220022903e0013703c003200241a8026a200241c0036a10860120022802ac0221014100419c94c700ad428080808080038420023502b00242208620022802a8022207ad84200241b8016aad4280808080c000841015210002402001450d00200710230b024020022802c0032201450d0020022802c403450d00200110230b20004101460d010c020b024020022802e401450d00200110230b20000d010b10fa040b20022802a8012109024020022802b0012201450d00200141246c21002009210103400240024020012d0000220741044b0d0002400240024020070e050400010204040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b024020022802ac012201450d00200141246c450d00200910230b200228023c21090240200241386a410c6a2802002201450d00200141246c21002009210103400240024020012d0000220741044b0d0002400240024020070e050400010204040b2001410c6a280200450d03200141086a28020010230c030b2001410c6a280200450d02200141086a28020010230c020b2001410c6a280200450d01200141086a28020010230c010b200141086a280200450d00200141046a28020010230b200141246a21012000415c6a22000d000b0b0240200241c0006a2802002202450d00200241246c450d00200910230b2003240042010be36f0d027f017e087f017e017f027e037f027e0a7f027e0b7f037e1c7f230041d0066b22002400200041003602f004200042083703e8042000410036028005200042013703f804418fcdc200ad4280808080f00084100c22012900002102200041f8056a41086a2203200141086a290000370300200020023703f8052001102341bbacc300ad4280808080a00184100c22012900002102200041a8066a41086a2204200141086a290000370300200020023703a806200110230240024002400240024002400240412010212201450d00200120002903f805370000200120002903a806370010200141086a2003290300370000200141186a22052004290300370000412010212203450d0020032001290000370000200341186a2005290000370000200341106a200141106a290000370000200341086a200141086a290000370000200041b8056a41026a2204200041a0016a41026a2d00003a0000200020002f00a0013b01b805200041d8056a41106a42a0808080800437030041002106200041003a00f005200020013602e405200042a080808080043702dc05200020033602d805200041f3056a20042d00003a0000200020002f01b8053b00f105200041a0016a200041d8056a10d20141012107024002400240024020002802a0014101470d00200041a0016a410472210841012107410821094100210a034020004188056a41206a200841206a28020036020020004188056a41186a2201200841186a290200220237030020004188056a41106a2205200841106a290200220b37030020004188056a41086a220c200841086a290200220d37030020002008290200220e37038805200041f8056a41186a220f2002370300200041f8056a41106a2210200b370300200041f8056a41086a2211200d3703002000200e3703f805200041a0016a41186a22032001290300370300200041a0016a41106a22042005290300370300200041a0016a41086a2205200c29030037030020002000290388053703a001200041c0006a200041f8056a10d301200041c0006a41086a29030021022000290340210b41201021220c450d02200c20002903f805370000200c41186a200f290300370000200c41106a2010290300370000200c41086a2011290300370000200041a8066a41086a2005290300220d370300200041a8066a41106a2004290300220e370300200041a8066a41186a20032903002212370300200020002903a00122133703a806200320123703002004200e3703002005200d370300200020133703a0010240200a20002802ec04470d00200041e8046a200a4101109f0120002802e804210920002802f004210a0b2009200a4106746a220120023703082001200b370300200529030021022004290300210b2003290300210d20002903a001210e200141346a4281808080103702002001200c3602302001200e370310200141286a200d370300200141206a200b370300200141186a20023703002000200a41016a220a3602f0042003200f2903003703002004201029030037030020052011290300370300200020002903f8053703a0010240200620002802fc04470d00200041f8046a20064101109a0120002802f804210720002802800521060b200720064105746a220120002903a001370000200141186a2003290300370000200141106a2004290300370000200141086a20052903003700002000200641016a220636028005200041a0016a200041d8056a10d20120002802a0014101460d000b0b024020002802dc05450d0020002802d80510230b024020002802e805450d0020002802e40510230b418fcdc200ad4280808080f00084100c22012900002102200041f8056a41086a2203200141086a290000370300200020023703f8052001102341e2c4c000ad4280808080a00184100c22012900002102200041a8066a41086a2204200141086a290000370300200020023703a80620011023412010212201450d03200120002903f805370000200120002903a806370010200141086a2003290300370000200141186a22052004290300370000412010212203450d0320032001290000370000200341186a2005290000370000200341106a200141106a290000370000200341086a200141086a29000037000020004190016a41026a2205200041a0016a41026a2d00003a0000200020002f00a0013b019001200041a0016a41106a220442a08080808004370300200041003a00b801200020013602ac01200042a080808080043702a401200020033602a001200041bb016a20052d00003a0000200020002f0190013b00b901200041e8046a200041a0016a10d401200041a0016a41186a2206420037030020044200370300200041a0016a41086a22014200370300200042003703a001418fcdc200ad4280808080f000842202100c2205290000210b200041f8056a41086a2203200541086a2900003703002000200b3703f8052005102320012003290300370300200020002903f8053703a00141e4d8c100ad4280808080e00184100c220c290000210b200041a8066a41086a2205200c41086a2900003703002000200b3703a806200c1023200420002903a806220b37030020004188056a41086a2208200129030037030020004188056a41106a220a200b37030020004188056a41186a220f2005290300370300200020002903a00137038805200041386a20004188056a412010cd01200028023c211420002802382115200642003703002004420037030020014200370300200042003703a0012002100c220c29000021022003200c41086a290000370300200020023703f805200c102320012003290300370300200020002903f8053703a001418cd9c100ad4280808080d00284100c220329000021022005200341086a290000370300200020023703a80620031023200420002903a806220237030020082001290300370300200a2002370300200f2005290300370300200020002903a00137038805200041306a20004188056a412010cd01200028023421052000280230210c20002802fc04211620002802e804211720002802ec042118200028028005210120002802f00421192000410036027020004100360268201920016aad42e0007e2202422088a70d042002a72203417f4c0d044108210402402003450d00200310212204450d040b20054104200c1b221a41014b211b200041003602e005200020043602d8052000200341e0006e3602dc05200041003602b006200042083703a806200041a8066a41002001410574220541057510a90120002802b006211c02402001450d00200541606a410576211d20002802a806201c41d8006c6a210c200041d0016a2103200041c8016a210941002104200721010340200041b8056a41186a2206200141186a2208290000370300200041b8056a41106a220a200141106a220f290000370300200041b8056a41086a2210200141086a2211290000370300200020012900003703b80520004188056a41186a200829000037030020004188056a41106a200f29000037030020004188056a41086a20112900003703002000200129000037038805200041e8006a20004188056a200410d501200041a0016a41086a4200370300200041a0016a41106a4200370300200041a0016a41186a4200370300200041a0016a41206a420037030020094200370300200341186a2006290300370000200341106a200a290300370000200341086a2010290300370000200320002903b805370000200042003703a001200c200041a0016a41d00010a105220c41d0006a41003a0000200c41d8006a210c200141206a2101200441016a2104200541606a22050d000b201c201d6a41016a211c0b201a4101201b1b21012000201c3602b0060240201641ffffff3f71450d00200710230b200041f8056a41086a200041a8066a41086a2802002203360200200020002903a8063703f8050240024020032001490d00200041d8056a20002802e0052019410674220341067510960120002802d805210420002802e0052101200041b8016a200041c8066a360200200041b4016a200041f8056a3602002000201720036a3602ac01200020173602a801200020183602a401200020173602a0012000200041e8006a3602b00120004188056a41086a20013602002000200041e0056a36028c0520002004200141e0006c6a36028805200041a0016a20004188056a10d6012014410020151b2216ad42307e2202422088a70d062002a72203417f4c0d0620002802800621010240024020030d00410821070c010b200310212207450d060b200041003602a00620002007360298062000200341306e36029c062016412c6c2203417f4c0d060240024020030d00410421140c010b200310212214450d060b41002119200041003602582000201636025420002014360250410021152001201620012016491b221d0d010c030b024020002802fc052201450d00200141d8006c450d0020002802f80510230b024020002802e0052201450d00200141e0006c210320002802d80541346a21010340024020012802002204450d00200441c8006c450d002001417c6a28020010230b200141e0006a2101200341a07f6a22030d000b0b024020002802dc052201450d00200141e0006c450d0020002802d80510230b200041e8006a10be0102402019450d0020194106742103201741346a210103400240200128020041ffffff3f71450d002001417c6a28020010230b200141c0006a2101200341406a22030d000b0b410021070240201841ffffff1f710d000c040b201710230c030b200041a0016a41186a211a200041a0016a41106a2109200041a0016a41086a211b41002118034020002802f805210402402001450d00200141d8006c21032004210103400240200141d0006a2d00000d0002400240200141206a290300220b200141286a290300220d8450450d0042002102427f210b427f210d0c010b427f2102200041206a427f427f200b200d10a705200041206a41086a290300210d2000290320210b0b2001200b3703002001200d370308200141106a2002370300200141186a20023703000b200141d8006a2101200341a87f6a22030d000b0b0240024020002802e0052201450d0020002802d8052205200141e0006c6a210a0340024020052802382201450d00200141c8006c2104200528023041206a21010340200028028006220c200128020022034d0d04024020002802f805200341d8006c6a22032d00500d0020032903202202200341286a290300220b84500d00200041a0016a2005290310200541186a2903002005290300200541086a2903002002200b108201200320032903002202427f2002427f20002903a80120002802a001410146220c1b220d7c220b200b2002542206200341086a22082903002202427f2009290300200c1b220e7c2006ad7c220b200254200b2002511b220c1b200d200e845022061b37030020082002427f200b200c1b20061b3703000b200141c8006a2101200441b87f6a22040d000b0b200541e0006a2205200a470d000b20002802f80521040b201841016a211820002802800641d8006c2101200441a87f6a210303402001450d04200141a87f6a2101200341d8006a2103200441d0006a2105200441d8006a220c210420052d00000d000b02402001450d00200341186a2903002102200341106a290300210b200341086a290300210d2003290300210e4100210403400240200c20046a220541d0006a2d00000d00200541086a2903002212200d200e200d200b2002200529030022132012200541106a290300221e200541186a290300221f10800141ff017141014622061b210d2013200e20061b210e201f200220061b2102201e200b20061b210b2005200320061b21030b2001200441d8006a2204470d000b0b2003450d03200341013a0050024020002802e0052201450d0020002802d8052204200141e0006c6a21172003410c6a2110200341306a21110340200441e0006a211c024020042802382205450d0020042802302101200541c8006c210503400240024020102001460d00200141246a2011412010a3050d010b200441186a220c290300210e200341086a220629030021022004290310210d2003290300210b20032903102112200141186a200341186a2208290300370300200141106a20123703002001200242002002200e7d200b200d54ad7d2212200b200d7d2213200b56201220025620122002511b220a1b200d200e8450220f1b3703082001200b42002013200a1b200f1b370300200629030021022008290300210b2003290300210d20042003290310370320200441286a200b3703002004200d370310200c20023703000b200141c8006a2101200541b87f6a22050d000b0b201c2104201c2017470d000b0b201a200341c8006a2900003703002009200341c0006a290000370300201b200341386a290000370300200020032900303703a001200341286a29030021022003290320210b02402015200028029c06470d0020004198066a2015410110a401200028029806210720002802a00621150b2007201541306c6a220120002903a001370300201b290300210d2009290300210e201a29030021122001200b370320200141286a2002370300200141186a2012370300200141106a200e370300200141086a200d3703002000201541016a22153602a0062018201d4f0d0320002802800621010c010b0b2003200c41a4e4c4001030000b102a000b024020002802e0052201450d0020002802d8052210200141e0006c6a2116201541306c211c20004194056a221741186a2118201741106a211a201741086a211b4100211903402017201029003c3700002018201041d4006a290000370000201a201041cc006a290000370000201b201041c4006a29000037000020004100360290052000420237038805024020102802382201450d002010280230220a200141c8006c6a2111201041106a2109410021084102210f0340200a220641246a2104200641c8006a210a41002105201c210320072101024003402003450d01024020042001460d0020012004412010a305210c200541016a2105200341506a2103200141306a2101200c0d010b0b41ffff0321030240200920061081010d00410021032006290310201029032085200641186a290300201041286a29030085844200520d00200041a0016a42ffff0342002006290300200641086a2903002009290300200941086a290300108201427f20002903a80120002802a00141014622011b2202a7417f200242808004544100427f200041a0016a41106a29030020011b501b1b21030b200041a0016a41186a22042006413c6a290000370300200041a0016a41106a2205200641346a290000370300200041a0016a41086a220c2006412c6a290000370300200020062900243703a00102402008200028028c05470d0020004188056a2008410110af01200028028805210f20002802900521080b200f200841226c6a220120002903a001370100200c29030021022005290300210b2004290300210d200120033b0120200141186a200d370100200141106a200b370100200141086a20023701002000200841016a2208360290050b200a2011470d000b024002402008450d002008417f200841808004491b210c02400240200841226c22040d00410021030c010b200f41206a2101410021030340417f2003411074220320012f01004110746a220520052003491b4110762103200141226a21012004415e6a22040d000b0b200c41ffff03712201450d012003417f73220641ffff0371220320016e21050240200120034b0d00410021010340200f200120087041226c6a2203417f20032f0120411074220320054110746a220420042003491b4110763b0120200141016a22012008490d000b0b024020062005200c6c6b41ffff03712205450d00410021010340200f200120087041226c6a2203417f20032f01204110742203418080046a220420042003491b4110763b0120200141016a22012005490d000b0b200041a0016a41286a220320004188056a41286a280200360200200041a0016a41206a220420004188056a41206a290300370300200041a0016a41186a220520004188056a41186a290300370300200041a0016a41106a220c20004188056a41106a290300370300200041a0016a41086a220620004188056a41086a29030037030020002000290388053703a001024020192000280254470d00200041d0006a2019410110a60120002802502114200028025821190b20142019412c6c6a220120002903a001370200200141286a2003280200360200200141206a2004290300370200200141186a2005290300370200200141106a200c290300370200200141086a20062903003702002000201941016a22193602580c020b200028028c052201450d01200141226c450d01200f10230c010b41a0e5c400411941bce5c400102d000b201041e0006a22102016470d000b200028025421160b200028029c062105024020002802fc052201450d00200141d8006c450d0020002802f80510230b024020002802e0052201450d00200141e0006c210320002802d80541346a21010340024020012802002204450d00200441c8006c450d002001417c6a28020010230b200141e0006a2101200341a07f6a22030d000b0b024020002802dc052201450d00200141e0006c450d0020002802d80510230b200041e8006a10be010b2007450d06200041a0016a41186a220c4200370300200041a0016a41106a221d4200370300200041a0016a41086a22014200370300200042003703a001418fcdc200ad4280808080f00084220b100c220329000021022001200341086a290000370300200020023703a0012003102341a8c5c000ad4280808080a00284100c22042900002102200041a8066a41086a2203200441086a290000370300200020023703a80620041023201d20002903a806220237030020004188056a41086a2208200129030037030020004188056a41106a220a200237030020004188056a41186a220f2003290300370300200020002903a00137038805200041f8056a20004188056a412010890202400240024020002802f8052206450d00200020002902fc05220d370284012000200636028001200c4200370300201d420037030020014200370300200042003703a001200b100c220429000021022001200441086a290000370300200020023703a0012004102341bac5c000ad4280808080a00284100c220429000021022003200441086a290000370300200020023703a80620041023201d20002903a806370000201d41086a200329030037000020082001290300370300200a201d290300370300200f200c290300370300200020002903a00137038805200041f8056a20004188056a4120108902024020002802f8052201450d00200020002902fc05370294012000200136029001200041003602a801200042013703a001200041a0016a4100201541306c220441306d109a0120002802a801210902402004450d0020002802a00120094105746a2101200721030340200341086a2900002102200341106a290000210b2003290000210d200141186a200341186a290000370000200141106a200b370000200141086a20023700002001200d370000200941016a2109200141206a2101200341306a2103200441506a22040d000b0b200020093602a80102402005450d00200541306c450d00200710230b20002802a401212020002802a0012121200041003602b006200042043703a806200041a8066a41002019412c6c2203412c6d10a60120002802a806210420002802b0062101200020143602a8012000201420036a3602ac0120002016ad4220862014ad843703a0012000200041c8066a3602b00120004188056a41086a222220013602002000200041a8066a41086a222336028c05200020042001412c6c6a36028805200041a0016a20004188056a10a502200041e8046a41086a220120002802b006360200200020002903a8063703e804200041e8046a10b9042001280200210120002802ec04212420002802e80421252000410036028005200042043703f804200041f8046a41002001412c6c2203412c6d10a601202520036a21192000280280052107024020010d002025210f0c030b20002802f8042007412c6c6a2108200041d8056a41086a2117200041d8056a41106a2116200041d8056a41186a21182025210f0340200f220128020821042001280204211c2017200141146a29020037030020162001411c6a2902003703002018200141246a2902003703002000200129020c3703d8052001412c6a210f20012802002210450d03200041f8056a41186a221a2018290300370300200041f8056a41106a221b2016290300370300200041f8056a41086a22142017290300370300200020002903d8053703f8052010200441306c22036a210a0240024020030d00420021024200210b0c010b201041206a2101420021024200210b0340200141086a290300200b7c2001290300220b20027c2202200b54ad7c210b200141306a2101200341506a22030d000b0b024002400240200a2010460d00200441306c2103201021010340200141286a290300210d200141206a290300210e200041b8056a41186a2204200141186a290000370300200041b8056a41106a2205200141106a290000370300200041b8056a41086a220c200141086a290000370300200020012900003703b805200e200d2002200b109805220641ffff03710d02200141306a2101200341506a22030d000b0b4200210d41002101410221110240201c450d00201c41306c450d00201010234200210d0b42002112410021060c010b2023200c290300370300200041a8066a41106a22152005290300370300200041a8066a41186a22262004290300370300200020002903b805220d370388052000200d3703a806412210212211450d06201120002903a806370100201120063b0120201141186a2026290300370100201141106a2015290300370100201141086a2023290300370100200042818080801037029c0620002011360298062006ad210d0240024020034130470d00200d42ffff0383210d42002112410121060c010b200141306a2126200a41506a2127200d42ffff0383210d42002112410121060340200d21132026210102400340200141286a290300210d200141206a290300210e2004200141186a2900003703002005200141106a290000370300200c200141086a290000370300200020012900003703b805200e200d2002200b109805220341ffff03710d01200a200141306a2201470d000b2013210d0c020b2022200c290300220d37030020004188056a41106a2005290300220e37030020004188056a41186a2004290300221e370300200020002903b805221f37038805200041a0016a41186a2228201e370300200041a0016a41106a2229200e370300200041a0016a41086a222a200d3703002000201f3703a00120132003ad42ffff03837c220d201354ad210e02402006200028029c06470d0020004198066a2006410110af0120002802980621110b200141306a21262012200e7c21122011200641226c6a221520002903a001370100202a290300210e202929030021132028290300211e201520033b0120201541186a201e370100201541106a2013370100201541086a200e3701002000200641016a22063602a00620272001470d000b0b0240201c450d00201c41306c450d00201010230b200028029c0621010b0240024042ffff03200d7d220b42ffff035642002012200d42ffff0356ad7c7d220242005220025022031b4101470d00200d4281807c7c2202200d562012200d42ffff0354ad7d220b201256200d42feff03561b0d012006450d01200641226c20116a417e6a2203410020032f010041107422032002a7417f200242808004544100200b501b1b4110746b2204200420034b1b4110763b01000c010b2006450d00200641226c20116a417e6a2204417f20042f01004110742204200ba7417f200b4280800454410020031b1b4110746a220320032004491b4110763b01000b200041a0016a41186a2203201a290300370300200041a0016a41106a2204201b290300370300200041a0016a41086a22052014290300370300200020002903f8053703a001200820013602042008200636020820082011360200200820002903a00137020c200841146a20052903003702002008411c6a2004290300370200200841246a2003290300370200200741016a21072008412c6a2108200f2019470d000b20002007360280050c030b200d42ffffff3f83500d00200610230b02402005450d00200541306c450d00200710230b02402019450d002019412c6c21032014210103400240200141046a2802002204450d00200441226c450d00200128020010230b2001412c6a2101200341546a22030d000b0b2016450d072016412c6c450d07201410230c070b2000200736028005200f2019460d000340200f2201412c6a210f0240200141046a2802002203450d00200341306c450d00200128020010230b2019200f470d000b0b02402024450d002024412c6c450d00202510230b2007ad422c7e2202422088a70d012002a72201417f4c0d0120002802fc04211720002802f80421190240024020010d00410421030c010b200110212203450d010b200041003602b006200020033602a80620002001412c6e3602ac06200041a8066a4100200710a60120002802b00621010240024020070d0020002802a806211c0c010b20192007412c6c6a211120002802a806221c2001412c6c6a210620012007410274417c6a4102766a2116200041ac016a2108200041b8056a41186a210a200041b8056a41106a210f200041b8056a41086a21102019210c0340200a200c41246a290000370300200f200c411c6a2900003703002010200c41146a2900003703002000200c29000c3703b805200c2802082203ad42227e2202422088a70d032002a72204417f4c0d03200c28020021010240024020040d00410221050c010b200410212205450d030b200c412c6a210c200041003602900520002005360288052000200441226e36028c0520004188056a4100200310af01200028029005210402402003450d00200341226c2105200028028805200441226c6a21030340200141086a2901002102200141106a290100210b200141186a290100210d2001290100210e200341206a200141206a2f01003b0100200341186a200d370100200341106a200b370100200341086a20023701002003200e370100200341226a2103200441016a2104200141226a21012005415e6a22050d000b0b200041a0016a41086a22012004360200200020002903880522023703a001200841186a200a290300370000200841106a200f290300370000200841086a2010290300370000200820002903b805370000200641286a200041a0016a41286a280200360200200641206a200041a0016a41206a290300370200200641186a200041a0016a41186a290300370200200641106a200041a0016a41106a290300370200200641086a2001290300370200200620023702002006412c6a2106200c2011470d000b201641016a21010b20003502ac06210241002103200041003602b006200042043703a806200041a8066a41002001412c6c2204412c6d10a60120002802a806210520002802b00621012000201c3602a8012000201c20046a3602ac0120002002422086201cad843703a0012000200041c8066a3602b00120004188056a41086a20013602002000200041a8066a41086a220436028c05200020052001412c6c6a36028805200041a0016a20004188056a10a50220002802ac062110200041a0016a2021200920002802a806221c20002802b006221110d8012004200041a0016a41086a280200360200200020002903a00122023703a8060240024002402002a7220a450d00024020002802ac062204450d0020042101200a2103034020032802c80521032001417f6a22010d000b200a21010340200120012f01064102746a41c8056a28020021012004417f6a22040d000b200041a0016a21040c020b200041a0016a2104200a2103200a21010c010b200041003602a401200041a0016a21040c010b200020013602a401200041ac016a20012f0106360200200041003602a0012000200041a8066a3602a801200041a8066a21010b20004188056a41086a200441086a290200220237030020002004290200220b3703880520002802b006210f200041ac016a4100360200200041b8016a2002370300200020013602a801200020033602a401200041003602a0012000200b3703b0012000200f3602c00102400240200f0d00427f2112420021134200210d4200211e4200211f427f210e0c010b2000200f417f6a3602c001200041a0016a410020031b220c2802002104200c28020821060240024002400240200c28020c2205200c28020422012f01064f0d00200121030c010b034020012802002203450d02200441016a210420012f0104210520032101200520032f01064f0d000b0b2005ad4220862006ad8421020c010b2006ad2102410021030b2002422088a7220641016a21052002a721080240024020040d00200321010c010b200320054102746a41c8056a2802002101410021052004417f6a2204450d00034020012802c80521012004417f6a22040d000b0b200c200536020c200c2008360208200c2001360204200c4100360200200320064105746a41e8026a2101427f2112427f210e4200211e4200211f420021134200210d03402000200141086a290300220b420020012903002202420010a605200041106a200242002002420010a605427f200d427f200041106a41086a290300222b2000290300222c202c7c7c222c200b2000290308222d84202d84420052202c202b547222011b7c2013427f200029031020011b7c222b2013542201ad7c221320012013200d542013200d511b22011b210d427f202b20011b2113200b200e2002201254200b200e54200b200e511b22011b210e2002201220011b2112200b201f7c2002201e7c221e200254ad7c211f20002802c0012201450d0120002001417f6a3602c001200041a0016a410020002802a4011b220c2802002104200c2802082106024002400240200c28020c2205200c28020422012f01064f0d00200121030c010b0240034020012802002203450d01200441016a210420012f0104210520032101200520032f0106490d020c000b0b2006ad2102410021030c010b2005ad4220862006ad8421020b2002422088a7220641016a21052002a721080240024020040d00200321010c010b200320054102746a41c8056a2802002101410021052004417f6a2204450d00034020012802c80521012004417f6a22040d000b0b200c200536020c200c2008360208200c2001360204200c4100360200200320064105746a41e8026a21010c000b0b02400240200a450d000240024020002802ac0622030d00200a21010c010b20032101200a2104034020042802c80521042001417f6a22010d000b200a21010340200120012f01064102746a41c8056a28020021012003417f6a22030d000b2004210a0b200041bc016a20012f0106360200200041b8016a4100360200200041b4016a2001360200200041003602b001200042003703a8012000200a3602a401200041003602a0010c010b4100210f200041b4016a4100360200200041003602a4010b2000200f3602c001200041a0016a10a60202402011450d002011412c6c2103201c210103400240200141046a2802002204450d00200441306c450d00200128020010230b2001412c6a2101200341546a22030d000b0b02402010450d002010412c6c450d00201c10230b20002007360290052000201736028c052000201936028805200041a0016a20004188056a20004190016a20004180016a108402024020002d00a0014101470d00202041ffffff3f71450d05202110230c050b200920096a22012009490d012001417f4c0d01200041e0026a280200212e200041dc026a280200210a200041d8026a2802002124200041d4026a280200212f200041d0026a2802002126200041cc026a2802002129200041c8026a2802002130200041c4026a280200210f200041c0026a2802002131200041bc026a2802002132200041b8026a2802002110200041b4026a2802002133200041b0026a2802002134200041ac026a2802002111200041a8026a2802002135200041a4026a2802002136200041a0026a28020021072000419c026a280200213720004198026a280200213820004194026a280200211c20004190026a28020021392000418c026a280200213a20004188026a280200211920004184026a280200213b20004180026a280200213c200041fc016a2802002117200041f8016a280200213d200041f4016a280200213e200041f0016a2802002123200041ec016a280200212a200041e8016a280200213f200041e4016a2802002116200041e0016a2802002140200041dc016a2802002141200041d8016a2802002118200041d4016a2802002142200041d0016a2802002143200041cc016a280200211a200041c8016a2802002144200041c4016a2802002145200041c0016a2802002127200041bc016a2802002125200041b8016a2802002146200041b4016a280200211b200041b0016a2802002147200041ac016a2802002148200041a8016a280200212820002802a40121220240024020010d00410221080c010b200110212208450d010b200041003602900520002008360288052000200141017636028c052009450d02202120094105746a2149200028028801220941057421142000280280012115410021062021210c0340200c41086a2900002102200c41106a290000210b200c290000212b200041a0016a41186a200c41186a290000370300200041a0016a41106a200b370300200041a0016a41086a20023703002000202b3703a0012009450d04200c41206a210c41002103201421042015210102400340200041a0016a2001460d0120032001200041a0016a412010a30522054100476a21032005450d01200141206a2101200441606a22040d000c060b0b200341ffff034b0d0402402006200028028c05470d0020004188056a20064101109c01200028028805210820002802900521060b200820064101746a20033b01002000200641016a220636029005200c2049470d000c030b0b1033000b1032000b0240202041ffffff3f71450d00202110230b200041f6006a20004190056a280200360100200020002903880537016e024020002802940141ffffff3f71450d0020002802900110230b024020002802840141ffffff3f71450d0020002802800110230b200041d0006a41106a200041e8006a41106a2f01003b0100200041d0006a41086a200041e8006a41086a29010037030020002000290168370350200041f8056a41086a2205200041de006a280100360200200020002901563703f805200041a0016a41186a220c4200370300200041a0016a41106a22014200370300200041a0016a41086a22034200370300200042003703a001418fcdc200ad4280808080f00084100c220429000021022003200441086a290000370300200020023703a0012004102341b8dbc100ad4280808080900184100c22042900002102200041a8066a41086a2206200441086a290000370300200020023703a80620041023201d20002903a806370000201d41086a200629030037000020004188056a41086a2204200329030037030020004188056a41106a2203200129030037030020004188056a41186a2206200c290300370300200020002903a00137038805200041a0016a20004188056a10ba012001280200210120002903a0012102200041ab016a2005280200360000200020002903f8053700a301200020002900a0013703a8062000200041a7016a2900003700af06200041c0046a200d370300200041b8046a2013370300200041b0046a201f370300200041a8046a201e370300200041a0046a200e37030020004198046a2012370300200041c0026a41183a0000200041c8026a20002900af063700002000418c046a202e36020020004188046a200a36020020004184046a202436020020004180046a202f360200200041fc036a2026360200200041f8036a2029360200200041f4036a2030360200200041f0036a200f360200200041ec036a2031360200200041e8036a2032360200200041e4036a2010360200200041e0036a2033360200200041dc036a2034360200200041d8036a2011360200200041d4036a2035360200200041d0036a2036360200200041cc036a2007360200200041c8036a2037360200200041c4036a2038360200200041c0036a201c360200200041bc036a2039360200200041b8036a203a360200200041b4036a2019360200200041b0036a203b360200200041ac036a203c360200200041a8036a2017360200200041a4036a203d360200200041a0036a203e3602002000419c036a202336020020004198036a202a36020020004194036a203f36020020004190036a20163602002000418c036a204036020020004188036a204136020020004184036a201836020020004180036a2042360200200041fc026a2043360200200041f8026a201a360200200041f4026a2044360200200041f0026a2045360200200041ec026a2027360200200041e8026a2025360200200041e4026a2046360200200041e0026a201b360200200041dc026a2047360200200041d8026a2048360200200041d4026a2028360200200041d0026a2022360200200042023703880220004190046a4100200120024202511b360200200041063602b802200020002903a8063700c102200041e0046a2006290300370300200041d8046a2003290300370300200041d0046a2004290300370300200041c8046a2000290388053703002000200041a0016a3602d80520004188056a200041d8056a10b302200028028805200028028c052000280290051089011a200041b8026a10b4020c030b0240202041ffffff3f71450d00202110230b0240200028028c0541808080807872418080808078460d00200810230b0240202841ffffffff0171450d00202210230b0240201b450d00201b410c6c450d00204710230b0240202741ffffffff0071450d00202510230b0240201a450d00201a41146c450d00204410230b02402018450d00201841186c450d00204210230b02402016450d002016411c6c450d00204010230b0240202341ffffff3f71450d00202a10230b02402017450d00201741246c450d00203d10230b02402019450d00201941286c450d00203b10230b0240201c450d00201c412c6c450d00203910230b02402007450d00200741306c450d00203710230b02402011450d00201141346c450d00203510230b02402010450d00201041386c450d00203310230b0240200f450d00200f413c6c450d00203110230b0240202641ffffff1f71450d00202910230b200a450d00200a41c4006c450d00202410230b024020002802940141ffffff3f71450d0020002802900110230b20002802840141ffffff3f71450d0020002802800110230b200041d0006a41106a200041e8006a41106a2f01003b01000b200041d0066a24000ba90504047f017e057f017e230041d0006b22022400200241206a41186a4200370300200241206a41106a22034200370300200241206a41086a220442003703002002420037032041b0dfc300ad4280808080a00184100c220529000021062004200541086a290000370300200220063703202005102341bcbac500ad4280808080b00184100c22052900002106200241c0006a41086a2207200541086a2900003703002002200637034020051023200320022903402206370300200241086a2004290300370300200241106a2006370300200241186a200729030037030020022002290320370300200241206a200210ad02024020022902244200200228022022051b2206422088a722044105744104722203417f4c0d000240200310212207450d002005410120051b21082002410036022820022003360224200220073602202004200241206a10610240024020040d0020022802282103200228022021090c010b2004410574210a2002280220210920022802242107200228022821032008210b0340200b2104024002402007200322056b4120490d00200541206a21030c010b024002400240200541206a22032005490d002007410174220b2003200b20034b1b220b4100480d000240024020070d000240200b0d00410121090c020b200b102121090c040b2007200b470d020b200b21070c030b102c000b20092007200b102521090b200b210720090d00102a000b200441206a210b200920056a22052004290000370000200541186a200441186a290000370000200541106a200441106a290000370000200541086a200441086a290000370000200a41606a220a0d000b2002200736022420022003360228200220093602200b2003ad4220862009ad84210c0240200642ffffff3f83500d00200810230b200241d0006a2400200c0f0b1033000b1032000bbe05020c7f017e230041306b22022400200210c203024002400240024002400240200228020822034103744104722204417f4c0d002002280204210520022802002106200410212207450d012002410036020820022004360204200220073602002003200210612003450d02200341037421082006210303400240024020032802004101460d0002400240200228020420022802082204460d00200228020021070c010b200441016a22072004490d07200441017422092007200920074b1b22094100480d070240024020040d0041002104024020090d00410121070c020b2009102122070d010c0b0b2002280200210720042009460d0020072004200910252207450d0a0b20022009360204200220073602000b200720046a41003a0000200441016a21040c010b024002402002280204220720022802082204460d00200228020021090c010b200441016a22072004490d06200441017422092007200920074b1b22074100480d060240024020040d0041002104024020070d00410121090c020b200710212209450d0a0c010b2002280200210920042007460d0020092004200710252209450d090b20022007360204200220093602000b200920046a41013a00002002200441016a220a360208200341046a280200210b02402007200a6b41034b0d00200a41046a220c200a490d062007410174220d200c200d200c4b1b220c4100480d060240024020070d000240200c0d00410121090c020b200c10212209450d0a0c010b2007200c460d0020092007200c10252209450d090b2002200c360204200220093602000b2009200a6a200b360000200441056a21040b200341086a210320022004360208200841786a22080d000c050b0b1032000b1033000b200228020821040c010b102c000b2004ad422086200235020084210e0240200541ffffffff0171450d00200610230b200241306a2400200e0f0b102a000bc80204047f017e017f017e230041d0006b22022400200241206a41186a4200370300200241206a41106a22034200370300200241206a41086a22044200370300200242003703204196adc300ad4280808080900184100c220529000021062004200541086a290000370300200220063703202005102341bce0c300ad4280808080e00084100c22052900002106200241c0006a41086a2207200541086a2900003703002002200637034020051023200320022903402206370300200241086a2004290300370300200241106a2006370300200241186a200729030037030020022002290320370300200241206a2002109103200241206a20022802202204410420041b22052002290224420020041b2206422088a710d3022002350228422086200235022084210802402006a72204450d002004412c6c450d00200510230b200241d0006a240020080b3f01017f0240410410212202450d002002418080800536000020024104410810252202450d0020024180a0013600042002ad42808080808001840f0b102a000bfd0503027f037e047f23004190016b2202240002400240024020014104490d0020022000419ca8c70020011b280000220110c303200228020022000d01410021000c020b2002411c6a4104360200200241c4006a410236020020024202370234200241e8c1c60036023020024104360214200241ccc3c60036021020024100360284012002419ca8c700360280012002200241106a360240200220024180016a360218200241306a41f8c1c600103a000b2002200136020c200241106a2002410c6a10af0220024180016a200241106a109702200241306a200228028001220320022802880110980220022903304201512101200241c0006a2903002104200229033821050240200228028401450d00200310230b2004420020011b21062005420020011b2104200241086a2802002103200228020421070b024002400240410110212201450d0020024201370234200220013602300240024020000d0041002103200141003a0000410121080c010b200141013a0000200241013602382003200241306a10610240024020022802342209200228023822086b2003490d00200228023021012009210a0c010b200820036a22012008490d032009410174220a2001200a20014b1b220a4100480d030240024020090d000240200a0d00410121010c020b200a102122010d010c060b200228023021012009200a460d0020012009200a10252201450d050b2002200a360234200220013602300b200120086a2000200310a1051a2002200820036a220336023802400240200a20036b4110490d00200341106a21080c010b200341106a22082003490d03200a41017422092008200920084b1b22094100480d0302400240200a0d00024020090d00410121010c020b200910212201450d060c010b200a2009460d002001200a200910252201450d050b20022009360234200220013602300b200120036a2203200637000820032004370000200021030b2008ad4220862001ad84210402402000450d002007450d00200310230b20024190016a240020040f0b1033000b102c000b102a000bd10603017f017e057f230041d0006b22022400024002400240024002400240024020014104490d002000419ca8c70020011b280000210041b0dfc300ad4280808080a00184100c22012900002103200241186a41086a200141086a290000370300200220033703182001102341c4a1c300ad4280808080c00084100c22012900002103200241286a41086a200141086a2900003703002002200337032820011023200220003602442002200241c4006aad4280808080c00084100d2201290000370348200110232002410c6a200241c4006a41046a3602002002200241c8006a41086a3602042002200241c4006a3602082002200241c8006a360200200241003a0010200241386a200210652002280240220441206a22004100480d0120022802382105024002402000450d00200010212201450d042000410f4d0d01200021060c060b200041017422014110200141104b1b2206102122010d050c070b200041017422064110200641104b1b220641004e0d030c050b200241346a4104360200200241146a410236020020024202370204200241e8c1c6003602002002410436022c200241ecc3c6003602282002410036021c2002419ca8c7003602182002200241286a3602102002200241186a360230200241f8c1c600103a000b1032000b1033000b20002006460d0020012000200610252201450d020b20012002290318370000200141086a200241186a41086a2903003700000240024020064170714110460d00200621070c010b200641017422074120200741204b1b22074100480d0120062007460d0020012006200710252201450d020b20012002290328370010200141186a200241286a41086a2903003700000240200741606a20044f0d00200441206a22062004490d01200741017422082006200820064b1b22064100480d0120072006460d0020012007200610252201450d020b200141206a2005200410a1051a0240200228023c450d00200510230b20022001200010b70302400240200228020022000d0041002100200241003602280c010b20022002290204220337022c200220003602282003a721060b200110232002200241286a1086012002350208422086200235020084210302402000450d002006450d00200010230b200241d0006a240020030f0b102c000b102a000b8f1907097f017e057f017e027f027e047f230041f0116b22022400024002402001450d00200220003602000c010b2002419ca8c7003602000b20022001360204200241c8036a200210b1040240024020022802c8032203450d002003200241c8036a41086a280200220441c8036c6a210520022802cc032106024002400240024020040d00200321070c010b200241c8036a4198016a2108200241f00a6a4198016a2109200241c8036a41f0006a210a200321070340200241e0026a200741e80010a1051a2007290368210b200241086a200741f0006a41d80210a1051a200741c8036a2107200b4203510d01200241c8036a200241e0026a41e80010a1051a2002200b3703b004200a200241086a41d80210a1051a2002200241c8036a3602f00a200241e00a6a200241f00a6a10b302200220022802e80a3602dc0a200220022802e00a220c3602d80a20024190076a200241d80a6a10d3030240024020022903f8074203520d00024020022802e40a450d00200c10230b200810b4020c010b200241f00a6a20024190076a41c80310a1051a410121004100210d024020022802880c2201410d470d00200228028c0c4101470d0020022802900c210e20022802940c210f0240024020022802980c22104188026c22010d004108210d420021110c010b20014188026dad42f0017e220b422088a70d06200ba722004100480d060240024020000d004108210d0c010b20001021220d450d090b200041f0016ead21110b200e20016a21124100211302400240024020100d00200e21010c010b4200210b200e2101200d21000340200141086a2903002114200141106a280200211020012903002115200241b80e6a200141146a41dc0110a1051a024020100d0020014188026a21010c020b20014184026a2802002116200141fc016a2802002117200141f4016a2802002118200141f0016a280200211920024194106a200241b80e6a41dc0110a1051a02402018450d00201841c1006c450d00201910230b02402016450d00201710230b2000201537030020002014370308200041106a2010360200200041146a20024194106a41dc0110a1051a200041f0016a2100200b4280808080107c210b201341016a211320014188026a22012012470d000b2011200b8421140c010b20112013ad42208684211420012012460d000340200110a203201220014188026a2201470d000b0b0240200f450d00200f4188026c450d00200e10230b4100210020022802880c21010b024002402001410d470d000240200228028c0c4101470d002000450d02024020022802980c2200450d0020022802900c210120004188026c21000340200110a20320014188026a2101200041f87d6a22000d000b0b20022802940c2201450d0220014188026c450d0220022802900c10230c020b0240200228029c0c2200450d0020022802940c21012000410c6c210003400240200141046a280200450d00200128020010230b2001410c6a2101200041746a22000d000b0b20022802980c2201450d012001410c6c450d0120022802940c10230c010b200910b4020b024020022802e40a450d00200c10230b200810b402200d0d030b20072005470d000b200521070b4100210d0b024020052007460d002003200441c8036c6a2101034020074198016a109e032001200741c8036a2207470d000b0b02402006450d00200641c8036c450d00200310230b0240024002400240200d0d00410121010c010b2014422088a741f0016c4105722201417f4c0d010b200110212200450d01200241003602f80a200220013602f40a200220003602f00a02400240200d0d00200041003a0000200241013602f80a0c010b200041013a0000200241013602f80a2014422088a72201200241f00a6a10612001450d00200141f0016c2105410021160340200d20166a220141c0006a28020021120240024020022802f40a220020022802f80a22186b4104490d0020022802f00a2107200021100c010b201841046a22072018490d05200041017422102007201020074b1b22104100480d050240024020000d00024020100d00410121070c020b2010102122070d010c090b20022802f00a210720002010460d0020072000201010252207450d080b200220103602f40a200220073602f00a0b200720186a20123600002002201841046a22123602f80a412010212200450d03200041186a2213200141e8006a290000370000200041106a2217200141e0006a290000370000200041086a2219200141d8006a2900003700002000200141d0006a29000037000002400240201020126b4120490d00201841246a21180c010b201241206a22182012490d052010410174220c2018200c20184b1b220c4100480d050240024020100d000240200c0d00410121070c020b200c10212207450d090c010b2010200c460d0020072010200c10252207450d080b2002200c3602f40a200220073602f00a0b200720126a22072000290000370000200741186a2013290000370000200741106a2017290000370000200741086a2019290000370000200220183602f80a20001023200141c4006a2802002113200141cc006a2802002207200241f00a6a10610240024020022802f40a221220022802f80a22186b2007490d0020022802f00a2100201221100c010b201820076a22002018490d05201241017422102000201020004b1b22104100480d050240024020120d00024020100d00410121000c020b201010212200450d090c010b20022802f00a210020122010460d0020002012201010252200450d080b200220103602f40a200220003602f00a0b200020186a2013200710a1051a2002201820076a22073602f80a02400240201020076b411f4d0d00201021180c010b200741206a22182007490d05201041017422122018201220184b1b22184100480d050240024020100d00024020180d00410121000c020b201810212200450d090c010b20102018460d0020002010201810252200450d080b200220183602f40a200220003602f00a0b200020076a2210200141f0006a290000370000201041186a20014188016a290000370000201041106a20014180016a290000370000201041086a200141f8006a2900003700002002200741206a22133602f80a02400240201820136b41c000490d00200741e0006a2110201821120c010b201341c0006a22102013490d05201841017422072010200720104b1b22124100480d050240024020180d00024020120d00410121000c020b201210212200450d090c010b20182012460d0020002018201210252200450d080b200220123602f40a200220003602f00a0b200020136a220720014190016a290000370000200741386a200141c8016a290000370000200741306a200141c0016a290000370000200741286a200141b8016a290000370000200741206a200141b0016a290000370000200741186a200141a8016a290000370000200741106a200141a0016a290000370000200741086a20014198016a290000370000200220103602f80a412010212207450d03200741186a2218200141e8016a290000370000200741106a2213200141e0016a290000370000200741086a2217200141d8016a2900003700002007200141d0016a2900003700000240201220106b411f4b0d00201041206a22192010490d052012410174220c2019200c20194b1b22194100480d050240024020120d00024020190d00410121000c020b201910212200450d090c010b20122019460d0020002012201910252200450d080b200220193602f40a200220003602f00a0b200020106a22002007290000370000200041186a2018290000370000200041106a2013290000370000200041086a20172900003700002002201041206a3602f80a200710232001200241f00a6a10e1042005201641f0016a2216470d000b0b20023502f80a42208620023502f00a84210b0240200d450d0002402014422088a72201450d00200d200141f0016c6a2110200d210703400240200741c8006a280200450d00200728024410230b0240200741186a2802002200450d00200728021021012000410474210003400240200141046a280200450d00200128020010230b200141106a2101200041706a22000d000b0b200741f0016a21010240200741146a28020041ffffffff0071450d00200728021010230b2001210720012010470d000b0b2014a72201450d00200141f0016c450d00200d10230b200241f0116a2400200b0f0b1032000b1033000b102c000b2002419c076a4104360200200241840b6a4102360200200242023702f40a200241e8c1c6003602f00a200241043602940720024184c4c600360290072002410036020c2002419ca8c700360208200220024190076a3602800b2002200241086a36029807200241f00a6a41f8c1c600103a000b102a000bf20603057f017e067f23004190016b22022400200241c8006a41186a22034200370300200241c8006a41106a22044200370300200241c8006a41086a220542003703002002420037034841db97c700ad4280808080f00084100c220629000021072005200641086a290000370300200220073703482006102341bcbcc300ad4280808080c00184100c22082900002107200241e8006a41086a2206200841086a2900003703002002200737036820081023200420022903682207370300200241286a41086a22082005290300370300200241286a41106a22092007370300200241286a41186a220a2006290300370300200220022903483703282002200241286a412010cd012002280204210b2002280200210c2003420037030020044200370300200542003703002002420037034841e4dec400ad4280808080e00084100c220d29000021072005200d41086a29000037030020022007370348200d102341f9dec400ad4280808080a00184100c220d29000021072006200d41086a29000037030020022007370368200d10232004200229036822073703002008200529030037030020092007370300200a200629030037030020022002290348370328200241e8006a200241286a412010e10120022d00682106200320024181016a2900003703002004200241f9006a2900003703002005200241f1006a290000370300200220022900693703480240024020064101460d00200a42003703002009420037030020084200370300200242003703280c010b200a20032903003703002009200429030037030020082005290300370300200220022903483703280b200241086a41086a200241286a41086a290300370300200241086a41106a200241286a41106a290300370300200241086a41186a200241286a41186a29030037030020022002290328370308024002400240410410212204450d002004200b4100200c1b360000412010212205450d0120052002290308370000200541186a2206200241086a41186a290300370000200541106a2203200241086a41106a290300370000200541086a2208200241086a41086a290300370000200441044124102522040d020b102a000b1033000b200420052900003700042004411c6a2006290000370000200441146a20032900003700002004410c6a20082900003700002005102320024190016a24002004ad4280808080c004840ba50a07027f017e047f017e017f047e027f230041e0006b220224002002411436020c200241eeebc300360208200241106a41eeebc300ad4280808080c002841010108b01024002400240024002400240200228021022030d0042002104410821050c010b200228021421062002200241186a2802002207360224200220033602200240024002402007450d0020022007417f6a3602242002200341016a36022020032d00002107200241c8006a200241206a10840420022802482208450d00200229024c2109200741ff01714101460d012009a72207450d00200741286c450d00200810230b20024100360230200242013703282002410a36023c2002200241086a3602382002200241286a36024441012107200241dc006a41013602002002420137024c20024180c5c6003602482002200241386a360258200241c4006a4184a5c200200241c8006a10311a2002350230422086200235022884100a0240200228022c450d00200228022810230b4102210a0c010b4101210a410021070b02402006450d00200310230b4108200820071b21054200200920071b210420070d00200a4101460d0020052802082203ad42287e2209422088a70d012009a72207417f4c0d01200528020021060240024020070d00410821050c010b200710212205450d030b02400240024002400240200741286e220820034f0d002008410174220a2003200a20034b1bad42287e2209422088a70d082009a7220a4100480d08200741274d0d01200841286c2207200a460d022007450d0120052007200a10252205450d090c020b2008ad210b20030d02420021090c030b200a10212205450d070b200a41286ead210b0b200341286c210a42002109410021080340200620086a22032903002104200341086a290300210c200341106a290300210d200341186a290300210e200520086a220741206a200341206a290300370300200741186a200e370300200741106a200d370300200741086a200c3703002007200437030020094280808080107c2109200a200841286a2208470d000b0b200b20098421040b2004422088a7220341286c4104722207417f4c0d00200710212208450d01200241003602502002200736024c200220083602482003200241c8006a10612002280250210702402003450d002005200341286c6a210f200228024c210620052103034002400240200620076b4120490d00200741206a2108200228024821102006210a0c010b200741206a22082007490d052006410174220a2008200a20084b1b220a4100480d050240024020060d000240200a0d00410121100c020b200a10212210450d080c010b200228024821102006200a460d0020102006200a10252210450d070b2002200a36024c200220103602480b201020076a22072003290000370000200741186a200341186a290000370000200741106a200341106a290000370000200741086a200341086a29000037000020022008360250200341206a290300210902400240200a20086b4108490d00200841086a2107200a21060c010b200841086a22072008490d05200a41017422062007200620074b1b22064100480d0502400240200a0d00024020060d00410121100c020b200610212210450d080c010b200a2006460d002010200a200610252210450d070b2002200636024c200220103602480b201020086a200937000020022007360250200f200341286a2203470d000b0b2007ad422086200235024884210902402004a72203450d00200341286c450d00200510230b200241e0006a240020090f0b1032000b1033000b102c000b102a000bb40f05047f017e017f017e077f23004190016b22022400200241c8006a41186a22034200370300200241c8006a41106a22044200370300200241c8006a41086a220542003703002002420037034841a7b3c500ad4280808080c000842206100c22072900002108200241286a41086a2209200741086a2900003703002002200837032820071023200520092903003703002002200229032837034841bcbac500ad4280808080b00184100c220729000021082009200741086a2900003703002002200837032820071023200420022903282208370300200241f0006a41086a220a2005290300370300200241f0006a41106a220b2008370300200241f0006a41186a220c200929030037030020022002290348370370200241c8006a200241f0006a10d10420022802482107200229024c2108200342003703002004420037030020054200370300200242003703482006100c220329000021062009200341086a2900003703002002200637032820031023200520092903003703002002200229032837034841c8bbc500ad4280808080a00184100c220329000021062009200341086a2900003703002002200637032820031023200420022903282206370300200a2005290300370300200b2006370300200c200929030037030020022002290348370370200241c8006a200241f0006a10970420022d00482105200c200241e1006a290000370300200b200241d9006a290000370300200a200241d1006a290000370300200220022900493703700240024020054101460d00200241286a41186a4200370300200241286a41106a420037030020094200370300200242003703280c010b200241286a41186a200c290300370300200241286a41106a200b2903003703002009200a290300370300200220022903703703280b200241086a41086a200241286a41086a290300370300200241086a41106a200241286a41106a290300370300200241086a41186a200241286a41186a2903003703002002200229032837030820024100360250200242013703480240410810212209450d002002410836024c20022009360248200942f02e3700002002410836025020094108411010252209450d00200942d8043700082002411036024c20022009360248200241103602500240024002404100450d00411021050c010b411041017422054118200541184b1b22054100480d010240024041100d002005102122090d010c040b41102005460d0020094110200510252209450d030b2002200536024c200220093602480b2009420137001020024118360250024020054138714118470d00200541017422044120200441204b1b22044100480d010240024020050d00200410212209450d040c010b20052004460d0020092005200410252209450d030b2002200436024c200220093602480b2007410820071b210d20094204370018200241203602502008420020071b2208422088a72209200241c8006a10612002280250210302402009450d00200d200941286c6a210e410020036b210b200228024c2104410021090340200320096a210c024002402004200b6a4120490d002002280248210a200421070c010b200c41206a2205200c490d03200441017422072005200720054b1b22074100480d030240024020040d00024020070d004101210a0c020b20071021220a450d060c010b2002280248210a20042007460d00200a200420071025220a450d050b2002200736024c2002200a3602480b200a20036a20096a2204200d20096a2205290000370000200441186a200541186a290000370000200441106a200541106a290000370000200441086a200541086a2900003700002002200c41206a2204360250200541206a2903002106024002402007200b6a41606a41074d0d00200721040c010b200441086a220f2004490d0320074101742204200f2004200f4b1b22044100480d030240024020070d00024020040d004101210a0c020b20041021220a450d060c010b20072004460d00200a200720041025220a450d050b2002200436024c2002200a3602480b200a20036a20096a41206a20063700002002200c41286a360250200b41586a210b200941286a2109200e200541286a470d000b200320096a21030b02400240200228024c220420036b4120490d0020022802482105200421090c010b200341206a22092003490d01200441017422052009200520094b1b22094100480d010240024020040d00024020090d00410121050c020b200910212205450d040c010b2002280248210520042009460d0020052004200910252205450d030b2002200936024c200220053602480b200520036a22042002290308370000200441186a200241086a41186a290300370000200441106a200241086a41106a290300370000200441086a200241086a41086a2903003700002002200341206a22043602500240024020092004460d00200421090c010b200941016a22042009490d01200941017422072004200720044b1b22044100480d010240024020090d0041002109024020040d00410121050c020b200410212205450d040c010b20092004460d0020052009200410252205450d030b2002200436024c200220053602480b200520096a41013a0000200941016aad422086200235024884210602402008a72209450d00200941286c450d00200d10230b20024190016a240020060f0b102c000b102a000b2b02017e017f10eb03210202404108102122030d001033000b200320023700002003ad42808080808001840b9b0b04047f017e0a7f017e230041b0016b2202240020024188016a41186a420037030020024188016a41106a2203420037030020024188016a41086a220442003703002002420037038801419dcdc200ad4280808080a00284100c220529000021062004200541086a29000037030020022006370388012005102341d7a1c200ad4280808080c00084100c22052900002106200241e8006a41086a2207200541086a2900003703002002200637036820051023200320022903682206370300200241106a41086a2004290300370300200241106a41106a2006370300200241106a41186a20072903003703002002200229038801370310200241203602342002200241106a360230200241386a200241106aad42808080808004841010108b010240024002400240200228023822080d00410021070c010b200228023c21092002200241386a41086a28020036024c20022008360248200241086a200241c8006a1088010240024020022802080d00200228020c220a200228024c220b41057622042004200a4b1b22044105742205417f4c0d040240024020040d00410121070c010b200510212207450d040b4100210c200241003602602002200436025c2002200736025802400240200a450d004100210d0340200b210341002104200241003a00a801200d41016a210d034020032004460d0320024188016a20046a200228024822052d00003a00002002200541016a3602482002200441016a22053a00a8012005210420054120470d000b200241e8006a41186a220e20024188016a41186a290300370300200241e8006a41106a220f20024188016a41106a290300370300200241e8006a41086a221020024188016a41086a29030037030020022002290388013703680240200c200228025c470d00200241d8006a200c4101109a01200228025821072002280260210c0b200320056b210b2007200c4105746a22042002290368370000200441186a200e290300370000200441106a200f290300370000200441086a20102903003700002002200c41016a220c360260200d200a470d000b2002200320056b36024c0b200229025c21062007450d010c020b2002410036024c0240200441ff0171450d00200241003a00a8010b0240200228025c41ffffff3f71450d00200710230b0b4100210720024100360270200242013703682002410a36025c2002200241306a3602582002200241e8006a3602542002419c016a41013602002002420137028c0120024180c5c600360288012002200241d8006a36029801200241d4006a4184a5c20020024188016a10311a2002350270422086200235026884100a200228026c450d00200228026810230b2009450d00200810230b2006420020071b2206422088a7220441057422094104722205417f4c0d01200510212203450d002007410120071b210a20024100360290012002200536028c012002200336028801200420024188016a10610240024020040d002002280290012105200228028801210d0c010b410020022802900122056b2107200228028801210d200228028c012108200a210c0340200c21040240200820076a411f4b0d00024002400240200541206a22032005490d002008410174220c2003200c20034b1b22034100480d000240024020080d00024020030d004101210d0c020b20031021210d0c040b20082003470d020b200321080c030b102c000b200d200820031025210d0b20032108200d0d00102a000b200441206a210c200d20056a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a290000370000200741606a2107200541206a2105200941606a22090d000b2002200836028c0120022005360290012002200d360288010b2005ad422086200dad8421110240200642ffffff3f83500d00200a10230b200241b0016a240020110f0b1033000b1032000bf41705037f037e017f027e037f230041e0026b220224000240024020010d002002200136020c2002419ca8c7003602080c010b20022001417f6a36020c2002200041016a36020820002d0000220141014b0d004100210002400240024002400240024020010e020100010b2002200241086a10880120022802000d05200228020c220320022802042201490d052001417f4c0d010240024020010d00410121000c010b200110272200450d03200020022802082204200110a1051a2002200320016b36020c2002200420016a3602080b2000450d052001ad220542208620058421050b0240024020000d004100210342002106420021070c010b20054220882206a72201417f4c0d01024020010d0041012103420021070c010b200110212203450d0220032000200110a1051a200621070b200220033602b002200220064220862007843702b402200241e7e485f30636029002200241106a200241b0026a1086012002280214210420024190026a200235021842208620022802102208ad84101f22012900002106200141086a2900002109200141106a290000210a200241106a41186a220b200141186a290000370300200241106a41106a220c200a370300200241106a41086a220d20093703002002200637031020011023200241b0016a41186a200b290300370300200241b0016a41106a200c290300370300200241b0016a41086a200d290300370300200220022903103703b00102402004450d00200810230b02402003450d002007a7450d00200310230b0240024020000d004100210342002106420021070c010b20054220882206a72201417f4c0d01024020010d0041012103420021070c010b200110212203450d0220032000200110a1051a200621070b200220033602b002200220064220862007843702b402200241e2c289ab0636029002200241106a200241b0026a1086012002280214210420024190026a200235021842208620022802102208ad84102022012900002106200141086a2900002109200141106a290000210a200241106a41186a220b200141186a290000370300200241106a41106a220c200a370300200241106a41086a220d20093703002002200637031020011023200241d0016a41186a200b290300370300200241d0016a41106a200c290300370300200241d0016a41086a200d290300370300200220022903103703d00102402004450d00200810230b02402003450d002007a7450d00200310230b0240024020000d004100210342002106420021070c010b20054220882206a72201417f4c0d01024020010d0041012103420021070c010b200110212203450d0220032000200110a1051a200621070b200220033602b002200220064220862007843702b402200241e9dabdf30636029002200241106a200241b0026a1086012002280214210420024190026a200235021842208620022802102208ad84102022012900002106200141086a2900002109200141106a290000210a200241106a41186a220b200141186a290000370300200241106a41106a220c200a370300200241106a41086a220d20093703002002200637031020011023200241f0016a41186a200b290300370300200241f0016a41106a200c290300370300200241f0016a41086a200d290300370300200220022903103703f00102402004450d00200810230b02402003450d002007a7450d00200310230b0240024020000d004100210342002106420021070c010b20054220882206a72201417f4c0d01024020010d0041012103420021070c010b200110212203450d0220032000200110a1051a200621070b200220033602b002200220064220862007843702b402200241f0c2c98b063602d002200241106a200241b0026a10860120022802142104200241d0026a200235021842208620022802102208ad84102022012900002106200141086a2900002109200141106a290000210a200241106a41186a220b200141186a290000370300200241106a41106a220c200a370300200241106a41086a220d2009370300200220063703102001102320024190026a41186a200b29030037030020024190026a41106a200c29030037030020024190026a41086a200d290300370300200220022903103703900202402004450d00200810230b02402003450d002007a7450d00200310230b0240024020000d004200210741002103420021060c010b20054220882207a72201417f4c0d010240024020010d0042002107410121030c010b200110212203450d0320032000200110a1051a0b20054280808080708321060b200220033602d002200220062007843702d402200241e1ea91cb063602dc02200241106a200241d0026a10860120022802142104200241dc026a200235021842208620022802102208ad84102022012900002106200141086a2900002109200141106a290000210a200241106a41186a220b200141186a290000370300200241106a41106a220c200a370300200241106a41086a220d20093703002002200637031020011023200241b0026a41186a200b290300370300200241b0026a41106a200c290300370300200241b0026a41086a200d290300370300200220022903103703b00202402004450d00200810230b02402003450d002007a7450d00200310230b200241106a41086a2203200241b0016a41086a290300370300200241106a41106a2204200241b0016a41106a290300370300200241106a41186a220b200241b0016a41186a290300370300200241386a200241d0016a41086a290300370300200241c0006a200241d0016a41106a290300370300200241c8006a200241d0016a41186a290300370300200220022903b001370310200220022903d001370330200241e8006a200241f0016a41186a290300370300200241e0006a200241f0016a41106a290300370300200241d8006a200241f0016a41086a290300370300200241f8006a20024190026a41086a29030037030020024180016a20024190026a41106a29030037030020024188016a20024190026a41186a29030037030020024198016a200241b0026a41086a290300370300200241a0016a200241b0026a41106a290300370300200241a8016a200241b0026a41186a290300370300200220022903f0013703502002200229039002370370200220022903b00237039001412010212201450d0320012002290310370000200141186a200b290300370000200141106a2004290300370000200141086a20032903003700002001412041c00010252201450d032001200241106a41206a2203290000370020200141386a200341186a290000370000200141306a200341106a290000370000200141286a200341086a290000370000200141c00041800110252201450d032001200241106a41c0006a22032900003700402001200241f0006a2204290000370060200141d8006a200341186a290000370000200141d0006a200341106a290000370000200141c8006a200341086a290000370000200141e8006a200441086a290000370000200141f0006a200441106a290000370000200141f8006a200441186a290000370000200141800141800210252201450d03200120024190016a22032900003700800120014198016a200341186a29000037000020014190016a200341106a29000037000020014188016a200341086a29000037000002402000450d002005a7450d00200010230b41a40110212200450d01200242a4013702142002200036021041a001200241106a1061024002402002280214220b200228021822036b41a001490d00200341a0016a2104200228021021000c010b200341a0016a22042003490d03200b41017422002004200020044b1b220c4100480d0302400240200b0d000240200c0d00410121000c020b200c102122000d010c060b20022802102100200b200c460d002000200b200c10252200450d050b2002200c360214200220003602100b200020036a200141a00110a1051a20011023200241e0026a24002004ad4220862000ad840f0b1032000b1033000b102c000b102a000b200241bc026a4104360200200241246a410236020020024202370214200241e8c1c600360210200241043602b40220024198c4c6003602b00220024100360294022002419ca8c700360290022002200241b0026a360220200220024190026a3602b802200241106a41f8c1c600103a000bbd0d03037f017e077f23004180036b22022400024002402001450d00200220003602080c010b2002419ca8c7003602080b2002200136020c2002200241086a108801024002400240024020022802000d00200228020c220320022802042201490d0002402001417f4c0d000240024020010d00410121000c010b200110272200450d03200020022802082204200110a1051a2002200320016b36020c2002200420016a3602080b2000450d0120022001ad220542208620058422054220883e02dc02200220003602d802200241b0016a200241d8026a10e5020240024020022d00b0014101470d00410021060c010b200241106a200241b0016a41017241a00110a1051a200241b0016a200241106a41a00110a1051a200241003602e802200242043703e002412010212201450d03200120022903b001370000200141186a200241b0016a41186a290300370000200141106a200241b0016a41106a290300370000200141086a200241b0016a41086a290300370000200241e0026a4100410110a00120022802e402210720022802e002220620022802e80222044104746a220341e7e485f30636020c200342a08080808004370204200320013602002002200441016a22013602e802200241f0026a200241b0016a41206a1077024020012007470d00200241e0026a2007410110a00120022802e402210720022802e002210620022802e80221010b200620014104746a220320022903f002370200200341e2c289ab0636020c200341086a200241f0026a41086a2802003602002002200141016a22013602e802200241f0026a200241f0016a1077024020012007470d00200241e0026a2007410110a00120022802e402210720022802e002210620022802e80221010b200620014104746a220320022903f002370200200241f0026a41086a22042802002108200341e9dabdf30636020c200341086a20083602002002200141016a22013602e802200241f0026a20024190026a1077024020012007470d00200241e0026a2007410110a00120022802e402210720022802e002210620022802e80221010b200620014104746a220320022903f00237020020042802002104200341f0c2c98b0636020c200341086a20043602002002200141016a22013602e802200241f0026a200241b0026a1077024020012007470d00200241e0026a2007410110a00120022802e402210720022802e002210620022802e80221010b200620014104746a220320022903f002370200200241f0026a41086a2802002104200341e1ea91cb0636020c200341086a2004360200200141016a21090b02402005a7450d00200010230b0240024020060d00410121010c010b20094104744105722201417f4c0d010b200110212200450d02200241003602b801200220013602b401200220003602b0010240024020060d00200041003a000041012100200241013602b8010c010b200041013a0000200241013602b8012009200241b0016a1061024020090d0020022802b80121000c010b200620094104746a210a2006210103402001280200210b200141086a2802002200200241b0016a10610240024020022802b401220c20022802b80122086b2000490d0020022802b0012103200c21040c010b200820006a22032008490d06200c41017422042003200420034b1b22044100480d0602400240200c0d00024020040d00410121030c020b2004102122030d010c090b20022802b0012103200c2004460d002003200c200410252203450d080b200220043602b401200220033602b0010b200320086a200b200010a1051a2002200820006a22003602b8010240200420006b41034b0d00200041046a22082000490d062004410174220c2008200c20084b1b22084100480d060240024020040d00024020080d00410121030c020b200810212203450d090c010b20042008460d0020032004200810252203450d080b200220083602b401200220033602b0010b200320006a2001410c6a2800003600002002200041046a22003602b801200141106a2201200a470d000b0b2000ad42208620023502b00184210502402006450d0002402009450d00200941047421002006210103400240200141046a280200450d00200128020010230b200141106a2101200041706a22000d000b0b200741ffffffff0071450d00200610230b20024180036a240020050f0b1032000b2002411c6a4104360200200241c4016a4102360200200242023702b401200241e8c1c6003602b00120024104360214200241b8c4c600360210200241003602f4022002419ca8c7003602f0022002200241106a3602c0012002200241f0026a360218200241b0016a41f8c1c600103a000b1033000b102c000b102a000bb70302037f047e23004180016b2202240041002103200241003a00402000419ca8c70020011b210402400240034020012003460d01200241206a20036a200420036a2d00003a00002002200341016a22003a00402000210320004120470d000b200241186a200241206a41186a22032903002205370300200241106a200241206a41106a22002903002206370300200241086a200241206a41086a2201290300220737030020022002290320220837030020032005370300200020063703002001200737030020022008370320200241f0006a200241206a10f902200241206a20022802702203200228027810980220022903202105200241e8006a280200210002402002280274450d00200310230b4104102122030d011033000b0240200341ff0171450d00200241003a00400b200241346a41023602002002410c6a410436020020024202370224200241e8c1c60036022020024104360204200241d4c4c600360200200241003602742002419ca8c700360270200220023602302002200241f0006a360208200241206a41f8c1c600103a000b20032000410020054201511b36000020024180016a24002003ad4280808080c000840bac0505027f017e017f017e017f230041c0076b22022400024002402001450d00200220003602100c010b2002419ca8c7003602100b20022001360214200241f8036a200241106a10d30302400240024020022903e0044203510d00200241186a200241f8036a41c80310a1051a200228021422014104490d0120022802102200280000210320022001417c6a3602142002200041046a360210200241f8036a200241186a41c80310a1051a200241e0036a20024190056a220110c9022002200320022903e0032204a722052004422888a74200420010b604200241086a29030021042002290300210620022d00e4032100200110b402410410212201450d022001200536000002400240200041024d0d0041042103410421000c010b024002400240024020000e03000102000b410021000c020b410121000c010b410221000b200220003a00f8034108210320014104410810252201450d03200120003a0004410521000b200041107221050240200320006b410f4b0d002003200341017422072005200720054b1b2207460d0020012003200710252201450d030b200120006a2200200437000820002006370000200241c0076a24002005ad4220862001ad840f0b200241ec036a41043602002002412c6a41023602002002420237021c200241e8c1c600360218200241043602e403200241ecc4c6003602e003200241003602f4032002419ca8c7003602f0032002200241e0036a3602282002200241f0036a3602e803200241186a41f8c1c600103a000b200241ec036a41043602002002418c046a4102360200200242023702fc03200241e8c1c6003602f803200241043602e403200241ecc4c6003602e003200241003602f4032002419ca8c7003602f0032002200241e0036a360288042002200241f0036a3602e803200241f8036a41f8c1c600103a000b102a000bcc0503027f017e047f230041e0006b2202240041f4c7c600ad4280808080800184100c22032900002104200241086a41086a200341086a290000370300200220043703082003102341fcc7c600ad4280808080f00084100c22032900002104200241186a41086a200341086a2900003703002002200437031820031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100f22012900002104200241386a41086a200141086a2900003703002002200437033820011023200241d4006a200341206a360200200241003a0058200220033602502002200241386a41106a36024c2002200241386a360248200241286a200241c8006a1065200310232002280230220541206a2201417f4c0d0120022802282106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290308370000200341086a200241086a41086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290318370010200341186a200241186a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a2000200136020820002007360204200020033602000240200228022c450d00200610230b200241e0006a24000f0b102c000b102a000b13002000410b360204200041f8cec6003602000b3400200041f4c7c60036020420004100360200200041146a4104360200200041106a418080c700360200200041086a42083702000b6001027f230041106b2202240002404114102122030d001033000b200342003700082003420037000020024294808080800237020420022003360200410020021061200041086a200228020836020020002002290300370200200241106a24000b930301027f024020002802082201450d0020002802002202200141c8006c6a21010340024020022d00004101470d00200241086a280200450d00200241046a28020010230b0240200241246a2d00004101470d002002412c6a280200450d00200241286a28020010230b200241c8006a22022001470d000b0b0240200041046a2802002202450d00200241c8006c450d00200028020010230b024020002d000c4101470d00200041146a280200450d00200041106a28020010230b024020002d00304101470d00200041386a280200450d00200041346a28020010230b024020002d00544101470d00200041dc006a280200450d00200041d8006a28020010230b024020002d00784101470d0020004180016a280200450d00200041fc006a28020010230b024020002d009c014101470d00200041a4016a280200450d00200041a0016a28020010230b024020002d00c0014101470d00200041c8016a280200450d00200041c4016a28020010230b024020002d00e4014101470d00200041ec016a280200450d00200041e8016a28020010230b0bf112010b7f23004180016b22022400200241003a004002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802002203280204220420044100472205490d00200241c0006a20032802002206200510a1051a2003200420056b3602042003200620056a360200024020040d00410021062002410d6a2107200241106a2108200241246a21090c140b2002410d6a2107200241106a2108200241246a210920022d0040220a41254b0d0141002106200a0e261301010101010101010101010101010101010101010101010101010101010101010102030405130b200041063a00000c130b0240200a417f6a220441ff01714121490d00200041063a00000c130b024020040d00410121034100210441002105410121060c120b0240200410272203450d002003200128020022012802002001280204220a2004200a2004491b220510a105210b200128020422062005490d052001200620056b3602042001200128020020056a360200410121060240200a20044f0d00200b20056a22014100200b20046a20016b10a0051a0b200421050c120b1033000b200241003a00784100210402400340200241003a004020012802002205280204220320034100472206490d01200241c0006a2005280200220a200610a1051a2005200320066b3602042005200a20066a360200024002402003450d0020022d004021030c010b41002103200241003a00400b200241d8006a20046a20033a00002002200441016a22043a007820044120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c100b41012101200441ff01710d040c0e0b200241003a00784100210402400340200241003a004020012802002205280204220320034100472206490d01200241c0006a2005280200220a200610a1051a2005200320066b3602042005200a20066a360200024002402003450d0020022d004021030c010b41002103200241003a00400b200241d8006a20046a20033a00002002200441016a22043a007820044120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c0d0b41012101200441ff01710d040c0b0b200241003a00784100210402400340200241003a004020012802002205280204220320034100472206490d01200241c0006a2005280200220a200610a1051a2005200320066b3602042005200a20066a360200024002402003450d0020022d004021030c010b41002103200241003a00400b200241d8006a20046a20033a00002002200441016a22043a007820044120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c0a0b41012101200441ff01710d040c080b200241003a00784100210402400340200241003a004020012802002205280204220320034100472206490d01200241c0006a2005280200220a200610a1051a2005200320066b3602042005200a20066a360200024002402003450d0020022d004021030c010b41002103200241003a00400b200241d8006a20046a20033a00002002200441016a22043a007820044120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c070b41012101200441ff01710d040c050b20052006418ca9c0001044000b200241003a00780c090b200241003a00780c060b200241003a00780c030b200241003a00780b0b2002413c6a41026a2206200241d4006a41026a2d00003a0000200241286a41086a220a200241c0006a41086a290300370300200241286a41106a220b200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20062d00003a0000200241106a41086a200a290300370300200241106a41106a200b2d00003a0000200220022f013c3b012420022002290328370310410521060c070b200041063a00000c070b0b2002413c6a41026a2206200241d4006a41026a2d00003a0000200241286a41086a220a200241c0006a41086a290300370300200241286a41106a220b200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20062d00003a0000200241106a41086a200a290300370300200241106a41106a200b2d00003a0000200220022f013c3b012420022002290328370310410421060c050b200041063a00000c050b0b2002413c6a41026a2206200241d4006a41026a2d00003a0000200241286a41086a220a200241c0006a41086a290300370300200241286a41106a220b200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20062d00003a0000200241106a41086a200a290300370300200241106a41106a200b2d00003a0000200220022f013c3b012420022002290328370310410321060c030b200041063a00000c030b0b410221062002413c6a41026a220a200241d4006a41026a2d00003a0000200241286a41086a220b200241c0006a41086a290300370300200241286a41106a220c200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a200a2d00003a0000200241106a41086a200b290300370300200241106a41106a200c2d00003a0000200220022f013c3b0124200220022903283703100c010b200041063a00000c010b200020063a0000200020092f00003b00012000410c6a2004360000200041086a2005360000200041046a2003360000200041106a2008290000370000200041216a20072f00003b0000200041036a200941026a2d00003a0000200041186a200841086a290000370000200041206a200841106a2d00003a0000200041236a200741026a2d00003a00000b20024180016a24000b9e0c04047f017e0a7f037e230041b0026b2201240020014188026a41186a420037030020014188026a41106a2202420037030020014188026a41086a22034200370300200142003703880241f4c7c600ad4280808080800184100c220429000021052003200441086a29000037030020012005370388022004102341a084c700ad4280808080a00184100c22042900002105200141e8016a41086a2206200441086a290000370300200120053703e80120041023200220012903e8012205370300200141086a41086a2003290300370300200141086a41106a2005370300200141086a41186a200629030037030020012001290388023703082001412036022c2001200141086a360228200141306a200141086aad42808080808004841010108b010240024002400240200128023022070d00410021030c010b200128023421082001200141306a41086a280200360254200120073602502001200141d0006a1088010240024002402001280200450d0041002103200141003602400c010b200128020422092001280254220a4106762203200320094b1b22034106742204417f4c0d030240024020030d004108210b0c010b20041021220b450d050b4100210c200141003602602001200336025c2001200b36025802400240024002402009450d004100210d0340200a450d042001200a417f6a220436025420012001280250220241016a36025020022d0000220341014b0d04420021050240024020030e020100010b41002103200141003a00a802200a417f6a2106034020062003460d0420014188026a20036a200220036a220441016a2d00003a00002001200441026a3602502001200341016a22043a00a8022004210320044120470d000b200141e8016a41086a220620014188026a41086a290300370300200141e8016a41106a220e20014188026a41106a290300370300200141e8016a41186a220f20014188026a41186a29030037030020012001290388023703e80120012004417f73200a6a220336025420034110490d042001200220046a220341116a22023602502001200a20046b220a416f6a220436025420044108490d04200341096a2900002110200341016a29000021112001200a41676a22043602542001200341196a360250200229000022124280025a0d04200141a8016a41086a2006290300220537030020014188016a41186a200f29030037030020014188016a41106a200e29030037030020014188016a41086a2005370300200120012903e80122053703a8012001200537038801420121050b200d41016a210d200141e8006a41186a220220014188016a41186a290300370300200141e8006a41106a220620014188016a41106a290300370300200141e8006a41086a220a20014188016a41086a29030037030020012001290388013703680240200c200128025c470d00200141d8006a200c4101109f012001280258210b2001280260210c0b200b200c4106746a2203201137030820032005370300200341106a2010370300200341186a2012370300200341206a2001290368370300200341286a200a290300370300200341306a2006290300370300200341386a20022903003703002001200c41016a220c3602602004210a200d2009470d000b0b200141c0006a41086a200141d8006a41086a2802003602002001200129035822053703402005a72203450d03200129024421050c040b20014100360254200341ff0171450d00200141003a00a8020b200141a8016a41086a200141c8016a41086a290300370300200141a8016a41106a200141c8016a41106a2903003703000b4100210320014100360240200128025c41ffffff1f71450d00200b10230b200141003602f001200142013703e8012001410a3602cc012001200141286a3602c8012001200141e8016a3602a8012001419c026a41013602002001420137028c0220014180c5c600360288022001200141c8016a36029802200141a8016a4184a5c20020014188026a10311a20013502f00142208620013502e80184100a024020012802ec01450d0020012802e80110230b0b2008450d00200710230b0240024020030d0020004100360208200042083702000c010b20002005370204200020033602000b200141b0026a24000f0b1032000b1033000bae0503027f017e047f230041d0006b2202240041f4c7c600ad4280808080800184100c22032900002104200241086a200341086a290000370300200220043703002003102341e082c700ad4280808080a00184100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad4280808080800484100d220129000037033020011023200241c4006a200341206a360200200241003a0048200220033602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200310232002280228220541206a2201417f4c0d0120022802202106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000b934f07087f017e017f017e017f027e4f7f230041f0066b220324002003200236021c20032001360218200341206a2002ad4220862001ad841010108b0102400240200328022022040d00200041023a00a4020c010b200328022421052003200341206a41086a280200360234200320043602302003200341306a3602a802200341106a200341a8026a10a3030240024020032802100d004108210602400240200328021422074180012007418001491b2201450d00200141057410212206450d010b200341003602a806200320013602a406200320063602a0060240024002400240024002402007450d00200341d0066a2108410021010340200341003602c806200341c8066a2003280230220920032802342202410420024104491b220a10a1051a20032002200a6b36023420032009200a6a3602300240200241034b0d00200341c8066a200a6a41004104200a6b10a0051a0b20033502c806210b200341003a00c806200328023422022002410047220a490d02200341c8066a20032802302209200a10a1051a20032002200a6b220c36023420032009200a6a220a36023002400240024020020d004200210d0c010b20032d00c806220241064b0d044200210d02400240024002400240024020020e0707000102030405070b200341c8066a200c4110200c4110491b22026a41004100411020026b22092002410f4b1b10a005210e200341c8066a200a200210a1051a2003200c20026b3602342003200a20026a3602300240200c410f4b0d00200e4100200910a0051a0b2008290300210f20032903c80621104201210d0c060b4202210d0c040b4203210d0c030b4204210d0c020b4205210d0c010b4206210d0b0b0240200120032802a406470d00200341a0066a2001410110970120032802a006210620032802a80621010b200620014105746a2202200d3703082002200b370300200241186a200f370300200241106a20103703002003200141016a22013602a8062007417f6a22070d000b0b2006450d0620032902a406210d200341d0066a220a4200370300200342003703c806200341c8066a2003280230220720032802342201411020014110491b220210a1051a2003200120026b3602342003200720026a36023002402001410f4b0d00200341c8066a20026a4100411020026b10a0051a0b200a290300210f20032903c8062110200341086a200341a8026a10a30320032802080d03200328020c2209413820094138491b22110d014104210a0c020b20032802a40641ffffff3f71450d0520061023410221010c060b201141c8006c1021220a450d030b41002102200341003602a0042003201136029c042003200a36029804024002400240024002400240024002402009450d00200341a0066a410c6a2112200341a0066a4101722113410021020340200341a0066a200341a8026a1090050240024020032d00a00622074106470d00410621070c010b2003419c066a41026a2208201341026a2d00003a000020034180066a41086a220e201241086a29020037030020034180066a41106a2214201241106a290200370300200320132f00003b019c06200320122902003703800620032802a406210c20032802a8062101200341c8066a200341a8026a109005024020032d00c8064106470d00024020074101470d002001450d00200c10230b410621070c010b200341fc056a41026a20082d00003a0000200341e0056a41086a200e290300370300200341e0056a41106a2014290300370300200341b8056a41086a200341c8066a41086a290300370300200341b8056a41106a200341c8066a41106a290300370300200341b8056a41186a200341c8066a41186a290300370300200341b8056a41206a200341c8066a41206a280200360200200320032f019c063b01fc0520032003290380063703e005200320032903c8063703b80520012115200c21160b200341b4056a41026a2201200341fc056a41026a2d00003a000020034198056a41086a220c200341e0056a41086a29030037030020034198056a41106a2208200341e0056a41106a290300370300200341f0046a41086a220e200341b8056a41086a290300370300200341f0046a41106a2214200341b8056a41106a290300370300200341f0046a41186a2217200341b8056a41186a290300370300200341f0046a41206a2218200341b8056a41206a280200360200200320032f01fc053b01b405200320032903e00537039805200320032903b8053703f00420074106460d02200341ec046a41026a221120012d00003a0000200341d0046a41086a2219200c290300370300200341d0046a41106a220c2008290300370300200341a8046a41086a2208200e290300370300200341a8046a41106a220e2014290300370300200341a8046a41186a22142017290300370300200341a8046a41206a22172018280200360200200320032f01b4053b01ec0420032003290398053703d004200320032903f0043703a80402402002200328029c04470d0020034198046a2002410110a101200328029804210a20032802a00421020b200a200241c8006c6a220120073a0000200141086a2015360000200141046a2016360000200141036a20112d00003a0000200120032f01ec043b0001200141146a20192903003700002001411c6a200c2903003700002001410c6a20032903d004370000200141246a20032903a804370000200141346a200e2903003700002001412c6a20082903003700002001413c6a2014290300370000200141c4006a20172802003600002003200241016a22023602a0042009417f6a22090d000b200328029c0421110b200a450d07200341c8066a200341a8026a10900520032d00c80622194106460d01200341b4056a41026a20032d00cb063a0000200341e0056a41086a200341dc066a2201290200370300200341e0056a41106a200341e4066a2207290200370300200320032f00c9063b01b4052003200341d4066a22092902003703e005200341c8066a41086a220c280200211220032802cc062115200341c8066a200341a8026a10900520032d00c80622164106460d02200341fc056a41026a20032d00cb063a000020034180066a41086a200129020037030020034180066a41106a2007290200370300200320032f00c9063b01fc052003200929020037038006200c280200211320032802cc06211a200341c8066a200341a8026a10900520032d00c806221b4106460d032003419c066a41026a20032d00cb063a0000200341a8046a41086a200341dc066a2201290200370300200341a8046a41106a200341e4066a2207290200370300200320032f00c9063b019c062003200341d4066a22092902003703a804200341c8066a41086a220c280200211c20032802cc06211d200341c8066a200341a8026a10900520032d00c806221e4106460d0420034198046a41026a20032d00cb063a0000200341f0046a41086a2001290200370300200341f0046a41106a2007290200370300200320032f00c9063b019804200320092902003703f004200c280200211f20032802cc062120200341c8066a200341a8026a10900520032d00c80622214106470d050240201e4101470d00201f450d00202010230b0240201b4101470d00201c450d00201d10230b024020164101470d002013450d00201a10230b024020194101470d002012450d00201510230b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012002470d000b0b2011450d07201141c8006c0d060c070b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012002470d000b0b200328029c042201450d06200141c8006c0d050c060b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012002470d000b0b2011450d05201141c8006c0d040c050b024020194101470d002012450d00201510230b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012002470d000b0b2011450d04201141c8006c0d030c040b024020164101470d002013450d00201a10230b024020194101470d002012450d00201510230b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012002470d000b0b2011450d03201141c8006c0d020c030b0240201b4101470d00201c450d00201d10230b024020164101470d002013450d00201a10230b024020194101470d002012450d00201510230b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012002470d000b0b2011450d02201141c8006c0d010c020b200341d2046a20032d00cb063a0000200341b8056a41086a200341dc066a290200370300200341c8056a200341e4066a290200370300200320032f00c9063b01d0042003200341d4066a2902003703b805200341c8066a41086a280200212220032802cc062123200341003a00c806024002402003280234220120014100472207490d00200341c8066a20032802302209200710a1051a2003200120076b220c3602342003200920076a22073602300240024020010d00410021010c010b20032d00c806220941014b0d0141002101024020090e020100010b200341003a00c806200c200c4100472201490d01200341c8066a2007200110a1051a2003200c20016b22093602342003200720016a220736023002400240200c450d0020032d00c80621240c010b41002124200341003a00c8060b200341003a00c806200920094100472201490d01200341c8066a2007200110a1051a2003200920016b220c3602342003200720016a2207360230024002402009450d0020032d00c80621250c010b41002125200341003a00c8060b200341003a00c806200c200c4100472201490d01200341c8066a2007200110a1051a2003200c20016b22093602342003200720016a220736023002400240200c450d0020032d00c80621260c010b41002126200341003a00c8060b200341003a00c806200920094100472201490d01200341c8066a2007200110a1051a2003200920016b220c3602342003200720016a2207360230024002402009450d0020032d00c80621270c010b41002127200341003a00c8060b200341003a00c806200c200c4100472201490d01200341c8066a2007200110a1051a2003200c20016b22093602342003200720016a220736023002400240200c450d0020032d00c80621280c010b41002128200341003a00c8060b200341003a00c806200920094100472201490d01200341c8066a2007200110a1051a2003200920016b220c3602342003200720016a2207360230024002402009450d0020032d00c80621290c010b41002129200341003a00c8060b200341003a00c806200c200c4100472201490d01200341c8066a2007200110a1051a2003200c20016b22093602342003200720016a220736023002400240200c450d0020032d00c806212a0c010b4100212a200341003a00c8060b200341003a00c806200920094100472201490d01200341c8066a2007200110a1051a2003200920016b220c3602342003200720016a2207360230024002402009450d0020032d00c806212b0c010b4100212b200341003a00c8060b200341003a00c806200c200c4100472201490d01200341c8066a2007200110a1051a2003200c20016b22093602342003200720016a220736023002400240200c450d0020032d00c806212c0c010b4100212c200341003a00c8060b200341003a00c806200920094100472201490d01200341c8066a2007200110a1051a2003200920016b220c3602342003200720016a2207360230024002402009450d0020032d00c806212d0c010b4100212d200341003a00c8060b200341003a00c806200c200c4100472201490d01200341c8066a2007200110a1051a2003200c20016b22093602342003200720016a220736023002400240200c450d0020032d00c806212e0c010b4100212e200341003a00c8060b200341003a00c806200920094100472201490d01200341c8066a2007200110a1051a2003200920016b220c3602342003200720016a2207360230024002402009450d0020032d00c806212f0c010b4100212f200341003a00c8060b200341003a00c806200c200c4100472201490d01200341c8066a2007200110a1051a2003200c20016b22093602342003200720016a220736023002400240200c450d0020032d00c80621300c010b41002130200341003a00c8060b200341003a00c806200920094100472201490d01200341c8066a2007200110a1051a2003200920016b220c3602342003200720016a2207360230024002402009450d0020032d00c80621310c010b41002131200341003a00c8060b200341003a00c806200c200c4100472201490d01200341c8066a2007200110a1051a2003200c20016b22093602342003200720016a220736023002400240200c450d0020032d00c80621320c010b41002132200341003a00c8060b200341003a00c806200920094100472201490d01200341c8066a2007200110a1051a2003200920016b220c3602342003200720016a2207360230024002402009450d0020032d00c80621330c010b41002133200341003a00c8060b200341003a00c806200c200c4100472201490d01200341c8066a2007200110a1051a2003200c20016b22093602342003200720016a220736023002400240200c450d0020032d00c80621340c010b41002134200341003a00c8060b200341003a00c806200920094100472201490d01200341c8066a2007200110a1051a2003200920016b220c3602342003200720016a2207360230024002402009450d0020032d00c80621350c010b41002135200341003a00c8060b200341003a00c806200c200c4100472201490d01200341c8066a2007200110a1051a2003200c20016b22093602342003200720016a220736023002400240200c450d0020032d00c80621360c010b41002136200341003a00c8060b200341003a00c806200920094100472201490d01200341c8066a2007200110a1051a2003200920016b3602342003200720016a360230024002402009450d0020032d00c80621370c010b41002137200341003a00c8060b410121010b200341c8066a200341a8026a10900520032d00c80622384106460d0120034198056a41026a220720032d00cb063a0000200341a0066a41086a2209200341dc066a290200370300200341a0066a41106a220c200341e4066a290200370300200320032f00c9063b0198052003200341d4066a2902003703a006200341c8066a41086a2208280200213920032802cc06213a200341c8066a200341a8026a10900520032d00c8064106470d04024020384101470d002039450d00203a10230b024020214101470d002022450d00202310230b0240201e4101470d00201f450d00202010230b0240201b4101470d00201c450d00201d10230b024020164101470d002013450d00201a10230b024020194101470d002012450d00201510230b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012002470d000b0b2011450d03201141c8006c0d020c030b024020214101470d002022450d00202310230b0240201e4101470d00201f450d00202010230b0240201b4101470d00201c450d00201d10230b024020164101470d002013450d00201a10230b024020194101470d002012450d00201510230b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012002470d000b0b2011450d02201141c8006c0d010c020b024020214101470d002022450d00202310230b0240201e4101470d00201f450d00202010230b0240201b4101470d00201c450d00201d10230b024020164101470d002013450d00201a10230b024020194101470d002012450d00201510230b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010230b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010230b200141c8006a22012002470d000b0b2011450d01201141c8006c450d010b200a10230b200d42ffffff3f83500d0220061023410221010c030b200341b0026a41206a220e200341c8066a41206a2214280200360200200341b0026a41186a2217200341c8066a41186a2218290300370300200341b0026a41106a223b200341c8066a41106a223c290300370300200341b0026a41086a223d200829030037030020034192046a41026a223e200341b4056a41026a223f2d00003a0000200341f8036a41086a2240200341e0056a41086a2241290300370300200341f8036a41106a2242200341e0056a41106a2243290300370300200320032903c8063703b002200320032f01b4053b019204200320032903e0053703f803200341f4036a41026a2244200341fc056a41026a22452d00003a0000200320032f01fc053b01f403200341d8036a41106a224620034180066a41106a2247290300370300200341d8036a41086a224820034180066a41086a224929030037030020032003290380063703d803200341d4036a41026a224a2003419c066a41026a224b2d00003a0000200320032f019c063b01d403200341b8036a41106a224c200341a8046a41106a224d290300370300200341b8036a41086a224e200341a8046a41086a224f290300370300200320032903a8043703b803200341b4036a41026a225020034198046a41026a22512d00003a0000200320032f0198043b01b40320034198036a41106a2252200341f0046a41106a225329030037030020034198036a41086a2254200341f0046a41086a2255290300370300200320032903f0043703980320034194036a41026a2256200341d0046a41026a22572d00003a0000200320032f01d0043b019403200341f8026a41106a2258200341b8056a41106a2259290300370300200341f8026a41086a225a200341b8056a41086a225b290300370300200320032903b8053703f802200341f4026a41026a225c20072d00003a0000200320032f0198053b01f402200341d8026a41106a225d200c290300370300200341d8026a41086a225e2009290300370300200320032903a0063703d802200341ac026a41026a225f20034195046a41026a2d00003a0000200320032f0095043b01ac022007203e2d00003a0000200320032f0192043b019805200c204229030037030020092040290300370300200320032903f8033703a006205720442d00003a0000200320032f01f4033b01d00420592046290300370300205b2048290300370300200320032903d8033703b8052051204a2d00003a0000200320032f01d4033b0198042053204c2903003703002055204e290300370300200320032903b8033703f004204b20502d00003a0000200320032f01b4033b019c06204d2052290300370300204f205429030037030020032003290398033703a804204520562d00003a0000200320032f0194033b01fc05204720582903003703002049205a290300370300200320032903f80237038006203f205c2d00003a0000200320032f01f4023b01b4052043205d2903003703002041205e290300370300200320032903d8023703e0052014200e28020036020020182017290300370300203c203b2903003703002008203d290300370300200320032903b0023703c806200341ec046a41026a205f2d00003a0000200320032f01ac023b01ec040c020b1033000b410221010b200341a4026a41026a20034198056a41026a2d00003a000020034188026a41086a200341a0066a41086a29030037030020034188026a41106a223b200341a0066a41106a220729030037030020034184026a41026a200341d0046a41026a2d00003a0000200341e8016a41086a200341b8056a41086a290300370300200341e8016a41106a223c200341b8056a41106a2209290300370300200320032f0198053b01a402200320032903a00637038802200320032f01d0043b018402200320032903b8053703e801200341e4016a41026a20034198046a41026a2d00003a0000200341c8016a41086a200341f0046a41086a290300370300200341c8016a41106a223d200341f0046a41106a220c290300370300200341c4016a41026a2003419c066a41026a2d00003a0000200341a8016a41086a200341a8046a41086a290300370300200341a8016a41106a223e200341a8046a41106a2208290300370300200320032f0198043b01e401200320032903f0043703c801200320032f019c063b01c401200320032903a8043703a801200341a4016a41026a200341fc056a41026a2d00003a000020034188016a41106a223f20034180066a41106a220e29030037030020034188016a41086a20034180066a41086a29030037030020034184016a41026a200341b4056a41026a2d00003a0000200341e8006a41106a2240200341e0056a41106a290300370300200341e8006a41086a200341e0056a41086a290300370300200320032f01fc053b01a401200320032903800637038801200320032f01b4053b018401200320032903e005370368200341c0006a41206a2241200341c8066a41206a2214280200360200200341c0006a41186a2242200341c8066a41186a2217290300370300200341c0006a41106a2243200341c8066a41106a2218290300370300200341c0006a41086a200341c8066a41086a290300370300200320032903c8063703402003413c6a41026a200341ec046a41026a2d00003a0000200320032f01ec043b013c0240024020014102470d00200341003602a806200342013703a0062003410a3602bc052003200341186a3602b8052003200341a0066a3602f004200341dc066a4101360200200342013702cc0620034180c5c6003602c8062003200341b8056a3602d806200341f0046a4184a5c200200341c8066a10311a20033502a80642208620033502a00684100a024020032802a406450d0020032802a00610230b410221010c010b200341e0056a41026a2244200341a4026a41026a2d00003a0000200341a0066a41086a224520034188026a41086a2903003703002007203b29030037030020034198056a41026a223b20034184026a41026a2d00003a0000200341b8056a41086a2246200341e8016a41086a2903003703002009203c290300370300200320032f01a4023b01e00520032003290388023703a006200320032f0184023b019805200320032903e8013703b805200341d0046a41026a223c200341e4016a41026a2d00003a0000200341f0046a41086a2247200341c8016a41086a290300370300200c203d290300370300200341f8036a41026a223d200341c4016a41026a2d00003a0000200341a8046a41086a2248200341a8016a41086a2903003703002008203e290300370300200320032f01e4013b01d004200320032903c8013703f004200320032f01c4013b01f803200320032903a8013703a804200341d8036a41026a223e200341a4016a41026a2d00003a0000200341b0026a41106a2249203f290300370300200341b0026a41086a223f20034188016a41086a290300370300200341b8036a41026a224a20034184016a41026a2d00003a0000200e204029030037030020034180066a41086a2240200341e8006a41086a290300370300200320032f01a4013b01d80320032003290388013703b002200320032f0184013b01b8032003200329036837038006201420412802003602002017204229030037030020182043290300370300200341c8066a41086a2241200341c0006a41086a290300370300200320032903403703c80620034198036a41026a22422003413c6a41026a2d00003a0000200320032f013c3b0198032000200f37030820002010370300200020193a002820002002360224200020113602202000200a36021c2000200d37021420002006360210200020123602302000201536022c200020032f01e0053b00292000412b6a20442d00003a0000200020032903a0063702342000413c6a2045290300370200200041c4006a2007290300370200200020163a004c200041cf006a203b2d00003a0000200020032f0198053b004d200020133602542000201a360250200041e8006a2009290300370200200041e0006a2046290300370200200020032903b8053702582000201b3a0070200041f3006a203c2d00003a0000200020032f01d0043b00712000201c3602782000201d3602742000418c016a200c29030037020020004184016a2047290300370200200020032903f00437027c2000201e3a00940120004197016a203d2d00003a0000200020032f01f8033b0095012000201f36029c012000202036029801200041b0016a2008290300370200200041a8016a2048290300370200200020032903a8043702a001200020213a00b801200041bb016a203e2d00003a0000200020032f01d8033b00b901200020223602c001200020233602bc01200041d4016a2049290300370200200041cc016a203f290300370200200020032903b0023702c401200020383a00dc01200041df016a204a2d00003a0000200020032f01b8033b00dd01200020393602e4012000203a3602e001200041f8016a200e290300370200200041f0016a204029030037020020002003290380063702e801200041a0026a201428020036020020004198026a201729030037020020004190026a201829030037020020004188026a2041290300370200200020032903c80637028002200041b8026a20373a0000200041b7026a20363a0000200041b6026a20353a0000200041b5026a20343a0000200041b4026a20333a0000200041b3026a20323a0000200041b2026a20313a0000200041b1026a20303a0000200041b0026a202f3a0000200041af026a202e3a0000200041ae026a202d3a0000200041ad026a202c3a0000200041ac026a202b3a0000200041ab026a202a3a0000200041aa026a20293a0000200041a9026a20283a0000200041a8026a20273a0000200041a7026a20263a0000200041a6026a20253a0000200020243a00a502200041bb026a20422d00003a0000200041b9026a20032f0198033b00000b200020013a00a4022005450d00200410230b200341f0066a24000be90404017f017e077f027e230041206b22022400200220001092052002350208210320022802002104200241003602182002420137031020012802102100200141186a2802002205200241106a10610240024002402005450d00200020054105746a21060340200028020021070240024020022802142208200228021822056b4104490d00200228021021090c010b200541046a22092005490d032008410174220a2009200a20094b1b220a4100480d030240024020080d000240200a0d00410121090c020b200a102122090d010c060b200228021021092008200a460d0020092008200a10252209450d050b2002200a360214200220093602100b200920056a20073600002002200541046a360218200041086a200241106a10e3022006200041206a2200470d000b0b200141086a290300210b2001290300210c0240024020022802142208200228021822006b4110490d00200041106a2105200228021021090c010b200041106a22052000490d01200841017422092005200920054b1b22074100480d010240024020080d00024020070d00410121090c020b200710212209450d040c010b2002280210210920082007460d0020092008200710252209450d030b20022007360214200220093602100b200920006a2200200b3700082000200c370000200220053602182001411c6a2200200241106a10e2022002280214210520034220862004ad84200235021842208620022802102209ad84100e02402005450d00200910230b02402002280204450d00200410230b0240200141146a28020041ffffff3f71450d00200128021010230b2000108f05200241206a24000f0b102c000b102a000bae0503027f017e047f230041d0006b2202240041f4c7c600ad4280808080800184100c22032900002104200241086a200341086a290000370300200220043703002003102341d083c700ad4280808080e00084100c22032900002104200241106a41086a200341086a2900003703002002200437031020031023024002400240024002400240412010212203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad4280808080800484100d220129000037033020011023200241c4006a200341206a360200200241003a0048200220033602402002200241306a41086a36023c2002200241306a360238200241206a200241386a1065200310232002280228220541206a2201417f4c0d0120022802202106024002402001450d00200110212203450d022001410f4d0d01200121070c050b200141017422034110200341104b1b2207102122030d040c060b200141017422084110200841104b1b220741004e0d020c040b1033000b1032000b20012007460d0020032001200710252203450d020b20032002290300370000200341086a200241086a2903003700000240024020074170714110460d00200721080c010b200741017422084120200841204b1b22084100480d0120072008460d0020032007200810252203450d020b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821070c010b2005415f4b0d01200841017422072001200720014b1b22074100480d0120082007460d0020032008200710252203450d020b200341206a2006200510a1051a20002001360208200020073602042000200336020002402002280224450d00200610230b200241d0006a24000f0b102c000b102a000bf80202027f037e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad841010108b0102400240200328021022010d00200041003602100c010b200328021421042003200341106a41086a28020022023602242003200136022002400240024020024110490d002003200241706a3602242003200141106a360220200141086a290000210520012900002106200341c8006a200341206a10cf01200328024822020d010b20034100360230200342013703282003410a36023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c20034180c5c6003602482003200341386a360258200341c4006a4184a5c200200341c8006a10311a2003350230422086200335022884100a0240200328022c450d00200328022810230b200041003602100c010b200329024c2107200020053703082000200637030020002007370214200020023602100b2004450d00200110230b200341e0006a24000b13002000410c360204200041a08cc7003602000bad0302027f037e230041d0006b22042400200441386a20024201200242015620034200522003501b22051b22022003420020051b220342ffff03420010a705200441286a20042903382206200441386a41086a290300220742ffff03420010a605200441186a20022003200620022004290328852003200441286a41086a2903008584420052ad7c22084201200842015620072008200654ad7c22064200522006501b22051b22082006420020051b220610a7050240024002402004290318220742808004544100200441186a41086a290300501b450d00200441086a200220002002200054200320015420032001511b22051b2003200120051b2008200610a7052004290308220342808004544100200441086a41086a290300501b450d012007a741ffff037122050d0241f0a6c700411941f4aac700102d000b2004411136024c20044184abc7003602484188a9c70041de00200441c8006a41f8a8c70041e8a9c7001034000b2004411136024c20044184abc7003602484188a9c70041de00200441c8006a41f8a8c70041e4aac7001034000b200441d0006a24002003a741ffff037141ffff036c20056e0bde17021e7f037e230041e0036b22032400200228020821042002280200210520022802042106200341186a2207200141206a290000370300200341106a2208200141186a290000370300200341086a2209200141106a290000370300200320012900083703002006410174210a2003410772210b200341c8016a41186a210c200341c8016a410c6a210d200341c8016a41206a210e2001280204210f20012802002110200421024100211141002112024002400240024002400240024002400240024002400240024002400240024002400240024002400340200420126a22134101762101024002402013410171450d0020062001490d03200120064f0d05200341013a00d001200320053602c801200320013602cc012003200520016a2d000041f001713a00d1010c010b20062001490d03200341003a00d001200320013602cc01200320053602c8010b200341b8036a20102003200341c8016a200f28020c11050002400240024020032802b80322140d00200341c8016a41086a2202200341086a290300370300200341c8016a41106a2206200341106a290300370300200341c8016a41186a2213200341186a290300370300200320032903003703c8014130102122010d010c170b20032802bc032115200341c8016a201420032802c00310a50420032d00c8014101460d13201141016a21110c010b200120032903c80137000120012003290020370021200120114100473a0000200141096a2002290300370000200141116a2006290300370000200141196a2013290300370000200141286a200341276a29000037000020004101360200200020013602040c140b034020032802e401211620032802e001211720032802dc01211820032802d801211920032802d401211320032802d001211a20032802cc012101200341206a200e41a80110a1051a200328029403211b200328029003211c024002400240024020010e05150f000102150b410021010240201341017420196b221d200a20026b221b201b201d4b1b221e450d000340200220016a221b410176221c20064f0d0a201920016a221f410176222020134f0d0b2005201c6a2d0000221c410f71201c41f00171410476201b4101711b201a20206a2d0000221b410f71201b410476201f4101711b470d01200141016a2201201e490d000b0b02402001201d460d00200042003702002015450d180c170b201d21010c020b200320163602dc01200320173602d801200320183602d401200320193602d001200320133602cc012003201a3602c801200c200341206a41a80110a1051a02400240200a2002460d00200241017622012006490d0120012006418898c7001030000b02400240201c0d00410021010c010b201b417f4c0d1302400240201b0d00200342003703b80341012101410021020c010b201b10212201450d15200341003602bc032003201b3602b803201b21020b2001201c200210a1051a2003201b3602bc0320032903b80321210b20002001360204200041086a20213702000c0d0b0240200341c8016a200520016a2d00002201410f71200141047620024101711b410c6c6a220128020022184102470d00200041003602040c0d0b20012802042117200141086a28020021164101211d410121010c010b20032802a003211e200328029c03211d2003280298032101200320163602d001200320173602cc01200320183602c801200d200341206a41a80110a1051a20032001360284032003201b360280032003201c3602fc02410021010240201341017420196b2216200a20026b2218201820164b1b2217450d000340200220016a221b410176221c20064f0d0a201920016a221f410176222020134f0d0b2005201c6a2d0000221c410f71201c41f00171410476201b4101711b201a20206a2d0000221b410f71201b410476201f4101711b470d01200141016a22012017490d000b0b0240024002400240024020012016470d0020182016470d01201d0d02410021010c030b200041003602040c0e0b201620026a220141017622132006490d0220132006418898c7001030000b201e417f4c0d1202400240201e0d00200342003703b80341012101410021020c010b201e10212201450d14200341003602bc032003201e3602b803201e21020b2001201d200210a1051a2003201e3602bc0320032903b80321210b20002001360204200041086a20213702000c0b0b0240200341c8016a200520136a2d00002213410f71201341047620014101711b410c6c6a221328020022184102470d00200041003602040c0b0b201641016a211d201641016a210120132802042117201341086a28020021160b200120126a21122002201d6a210202402018450d00200341c8016a2017201610a50420032d00c8014101460d130c010b0b0240024020164120460d00200341c8016a41086a22192009290300370300200341c8016a41106a221a2008290300370300200c2007290300370300200320032903003703c8012016417f4c0d100240024020160d0041012101410021130c010b20162113201610212201450d120b20012017201310a105211b413010212201450d16200141043a0000200120032903c801370001200120032f00aa033b00212001201636002c200120133600282001201b360024200141096a2019290300370000200141116a201a290300370000200141196a200c290300370000200141236a200341aa036a41026a2d00003a0000410121130c010b201741026a2d000021132017410f6a2900002121201741176a29000021222017280003210120172f0000211920172900072123200c2017411f6a2d00003a0000200341c8016a41106a2022370300200341c8016a41086a2021370300200341aa036a41026a20133a0000200320233703c801200320193b01aa03410021130b200341dc036a41026a2219200341aa036a41026a2d00003a0000200341b8036a41086a221a200341c8016a41086a290300370300200341b8036a41106a221b200341c8016a41106a290300370300200341b8036a41186a221c200c280200360200200320032f01aa033b01dc03200320032903c8013703b803024020130d00200b20032903b803370000200b41086a201a290300370000200b41106a201b290300370000200b41186a201c2d00003a0000200320032f01dc033b010020032001360003200320192d00003a00022015450d01201410230c010b0b200041013602002000200136020420150d110c120b2001200641a8bcc0001043000b2001200641b8bcc0001043000b2001200641c8bcc0001030000b201c2006418898c7001030000b20202013418898c7001030000b201c2006418898c7001030000b20202013418898c7001030000b200041003602000c020b200041003602000c010b4100211e0240201341017420196b200a20026b2216470d004100211e41002101024002402016450d00410021010340201920016a221b410176221c20134f0d05200220016a221f410176222020064f0d06201a201c6a2d0000221c410f71201c41f00171410476201b4101711b200520206a2d0000221b410f71201b410476201f4101711b470d012016200141016a2201470d000c020b0b20012016470d010b2017417f4c0d040240024020170d00200342003703c8014101211e410021010c010b20171021221e450d06200341003602cc01200320173602c801201721010b201e2018200110a1051a200320173602cc0120032903c80121210b2000201e36020420004100360200200041086a20213702000b02402015450d00201410230b200341e0036a24000f0b201c2013418898c7001030000b20202006418898c7001030000b1032000b1033000b2000420037020020150d010c020b20032d00c9012102200341b8036a41086a2206200341086a290300370300200341b8036a41106a2213200341106a290300370300200341b8036a41186a2219200341186a290300370300200320032903003703b803413010212201450d02200141033a0000200120032903b803370001200120023a0021200120032901aa03370122200141096a2006290300370000200141116a2013290300370000200141196a2019290300370000200141286a200341b0036a29010037010020004101360200200020013602042015450d010b201410230b200341e0036a24000f0b102a000b8a0201057f024020002802102201450d00200041146a280200220241046a2103200120026a41016a21042002280200417f73418081828478712105200041186a280200210202400340024002402005450d00200521010c010b0340200320044f0d03200241c0016a210220032802002101200341046a220521032001418081828478712201418081828478460d000b2001418081828478732101200521030b2001417f6a2001712105200220016841037641306c6a220141246a280200450d00200128022010230c000b0b02402000280210220341086a200341056a490d00200341016aad42307e422088a71a0b200028021410230b02402000412c6a280200450d00200028022810230b0b130020004101360204200041f898c7003602000b3400200041b494c70036020420004100360200200041146a4102360200200041106a41d49cc700360200200041086a42093702000b130020004101360204200041a49fc7003602000b2d01017f02404108102122020d001033000b20004288808080800137020420002002360200200242b8173700000b1f0002402000280200450d00200041086a280200450d00200028020410230b0b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f0240024020012000490d002002450d01200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000c020b0b2002450d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200041016a2100200141016a21012002417f6a2202450d020c000b0b200420056b21030b20030b5701017e02400240200341c000710d002003450d012001410020036b413f71ad8820022003413f71ad220486842102200120048621010c010b20012003413f71ad862102420021010b20002001370300200020023703080b5701017e02400240200341c000710d002003450d0120012003413f71ad2204882002410020036b413f71ad86842101200220048821020c010b20022003413f71ad882101420021020b20002001370300200020023703080b7501027e200020034220882205200142208822067e200320027e7c200420017e7c200342ffffffff0f832203200142ffffffff0f8322017e2204422088200320067e7c22034220887c200342ffffffff0f83200520017e7c22034220887c37030820002003422086200442ffffffff0f83843703000b3e01017f230041106b2205240020052001200220032004410010a905200529030021012000200541086a29030037030820002001370300200541106a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a10a905200529031021012000200529031837030820002001370300200541206a24000be20502037f067e230041306b2206240002400240024002400240024002400240024002402002500d002003500d012004500d02200479a7200279a76b2207413f4b0d0341ff0020076b2108200741016a21070c080b02402004500d0020050d040c060b024002402005450d0020034200510d0620054200370308200520012003823703000c010b20034200510d050b200120038021010c060b2004500d030240024002402001500d0020047b4201510d01200479a7200279a76b2207413e4b0d0241ff0020076b2108200741016a21070c090b02402005450d0020054200370300200520022004823703080b200220048021010c070b02402005450d002005200137030020052004427f7c2002833703080b200220047a423f838821010c060b2005450d040c020b024020037b4201510d0041bf7f200379a7200279a76b22076b2108200741c1006a21070c060b02402005450d002005420037030820052003427f7c2001833703000b20034201510d06200641206a2001200220037aa710a505200641286a2903002102200629032021010c060b2005450d020b2005200137030020052002370308420021010c020b00000b420021010b420021020c010b200620012002200841ff007110a405200641106a20012002200741ff007110a505200641086a2903002102200641106a41086a2903002109200629030021012006290310210a0240024020070d004200210b4200210c0c010b4200210c4200210d03402009420186200a423f8884220b200b427f8520047c200a4201862002423f8884220a427f85220b20037c200b54ad7c423f87220b2004837d200a200b200383220e54ad7d2109200a200e7d210a420020024201862001423f8884842102200d2001420186842101200b420183220b210d2007417f6a22070d000b0b02402005450d002005200a370300200520093703080b200c20024201862001423f8884842102200b20014201868421010b2000200137030020002002370308200641306a24000b0bb4ab070300418080c0000b0c318d0596a0101000a010100000419080c0000b85ab076361706163697479206f766572666c6f7700000034001000170000006e020000050000007372632f6c6962616c6c6f632f7261775f7665632e727300db0010004600000068010000130000001600000004000000040000001700000018000000190000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f72001600000000000000010000001a000000c8001000130000004a020000050000007372632f6c6962616c6c6f632f666d742e72732f72757374632f366465653566313132366466643563393331346565356165396439656230313065333565663235372f7372632f6c6962636f72652f666d742f6d6f642e72737372632f6c6962616c6c6f632f7665632e7273292073686f756c64206265203c206c656e2028697320000074011000140000008801100017000000180f1000010000002101100013000000f10300000d000000696e73657274696f6e20696e6465782028697320292073686f756c64206265203c3d206c656e202869732000c8011000120000003401100016000000180f1000010000002101100013000000210400000d00000072656d6f76616c20696e6465782028697320000004021000140000008801100017000000180f1000010000002101100013000000330500000d000000656e6420647261696e20696e6465782028697320380210002000000058021000120000001600000000000000010000001b000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e646578206973203030303130323033303430353036303730383039313031313132313331343135313631373138313932303231323232333234323532363237323832393330333133323333333433353336333733383339343034313432343334343435343634373438343935303531353235333534353535363537353835393630363136323633363436353636363736383639373037313732373337343735373637373738373938303831383238333834383538363837383838393930393139323933393439353936393739383939000044031000060000004a03100022000000696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e677468207c03100016000000920310000d000000736c69636520696e64657820737461727473206174202062757420656e64732061742000030e100016000000040800002f0000005b2e2e2e5d000000180410000b000000ed0d1000160000005704100001000000cb0d10000e000000d90d100004000000dd0d1000100000005704100001000000180410000b00000023041000260000004904100008000000510410000600000057041000010000006279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f6620606096041000020000008004100016000000560400002400000080041000160000004c040000110000007372632f6c6962636f72652f666d742f6d6f642e72732e2eaa04100016000000540000001400000030787372632f6c6962636f72652f666d742f6e756d2e727300010305050606030706080809110a1c0b190c140d100e0d0f0410031212130916011705180219031a071c021d011f1620032b032c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f00d11454964658084b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f7475962f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab35280b80e003190801042f043404070301070607110a500f1207550703041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a06213f4c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b32d740c80d61a0c0580ff0580df0cee0d03848d033709815c1480b80880cb2a38030a06380846080c06740b1e035a0459098083181c0a16094c04808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b020e041001110212051311140115021702190d1c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f802f902fa02fb010c273b3e4e4f8f9e9e9f060709363d3e56f3d0d1041418363756577faaaeafbd35e01287898e9e040d0e11122931343a4546494a4e4f64655cb6b71b1c07080a0b141736393aa8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d0aeaf79cc6e6f935e227b0503042d036603012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a8126524e28082a561c1417094e041e0f430e19070a0648082709750b3f412a063b050a0651060105100305808b621e48080a80a65e22450b0a060d1339070a362c041080c03c64530c48090a46451b4808531d398107460a1d03474937030e080a0639070a81361980b7010f320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140050b020e97f80884d62a09a2f7811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a80ae381d0d2c040907020e06809a83d8080d030d03740c59070c140c0438080a062808224e81540c15030305070919070709030d072980cb250a840600280a1000200000000a0000001c000000280a1000200000001a000000280000007372632f6c6962636f72652f756e69636f64652f7072696e7461626c652e72730003000083042000910560005d13a0001217a01e0c20e01eef2c202b2a30a02b6fa6602c02a8e02c1efbe02d00fea0359effe035fd016136010aa136240d6137ab0ee1382f182139301c6146f31ea14af06a614e4f6fa14e9dbc214f65d1e14f00da215000e0e15130e16153ece2a154d0e8e15420002e55f001bf55a80d100023000000520000003e00000000700007002d0101010201020101480b30151001650702060202010423011e1b5b0b3a09090118040109010301052b03770f0120370101010408040103070a021d013a0101010204080109010a021a010202390104020402020303011e0203010b0239010405010204011402160601013a0101020104080107030a021e013b0101010c0109012801030139030503010407020b021d013a01020102010301050207020b021c02390201010204080109010a021d0148010401020301010801510102070c08620102090b064a021b0101010101370e01050102050b0124090166040106010202021902040310040d01020206010f01000300031d031d021e02400201070801020b09012d03770222017603040209010603db0202013a010107010101010208060a020130113f0430070101050128090c0220040202010338010102030101033a0802029803010d0107040106010302c63a01050001c32100038d016020000669020004010a200250020001030104011902050197021a120d012608190b2e0330010204020227014306020202020c0108012f01330101030202050201012a020801ee010201040100010010101000020001e201950500030102050428030401a50200040002990bb001360f3803310402024503240501083e010c0234090a0402015f03020101020601a0010308150239020101010116010e070305c308020301011701510102060101020101020102eb010204060201021b025508020101026a0101010206010165030204010500090102f5010a0201010401900402020401200a280602040801090602032e0d010200070106010152160207010201027a060301010201070101480203010101000200053b0700013f0451010002000101030405080802071e0494030037043208010e011605010f000701110207010201050007000400076d07006080f000000000a80d1000230000004b00000028000000a80d10002300000057000000160000007372632f6c6962636f72652f756e69636f64652f756e69636f64655f646174612e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f6620607372632f6c6962636f72652f7374722f6d6f642e7273426f72726f774572726f72426f72726f774d75744572726f7270616e69636b6564206174200000690e1000010000006a0e1000030000001cd4110000000000680e100001000000680e1000010000003a27272c2020202020000000940e10001a0000006a01000026000000030e100016000000c30700002f0000007372632f6c6962636f72652f7374722f7061747465726e2e72730000c00e10001b00000052000000050000007372632f6c6962636f72652f736c6963652f6d656d6368722e72732c20000000160000000c000000040000001c0000001d0000001e0000002c0a00001600000004000000040000001f000000200000002100000028280a2c290a5d5b030e100016000000800700002f000000a50f1000260000006672616d655f737570706f72743a3a686173682f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f737570706f72742f7372632f686173682e7273496e76616c696420726576657273653a2068617368206c656e67746820746f6f2073686f7274001600000004000000040000002200000023000000240000001600000000000000010000002500000026000000270000006d61782d77656967687461637475616c5f7765696768743d48617368207461626c65206361706163697479206f766572666c6f77401010005b000000500000001b0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6861736862726f776e2d302e362e332f7372632f7261772f6d6f642e727300ffffffff16000000000000000100000028000000290000002700000016000000000000000100000028000000290000002700000000000000541110000e00000000000000641110000100000000000000000000006c1110000100000000000000000000007411100006000000000000001cd411000000000000000000000000007c1110000100000000000000000000008411100007000000000000001cd411000000000000000000000000008c11100001000000000000004e6577417574686f7269746965730000071210000d000000e3111000240000005061757365640000bc11100027000000526573756d65640094111000280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e417574686f726974794c69737400000000401210000700000000000000481210000300000000000000000000006012100003000000000000004f6666656e636500f049110004000000f44911000e00000031cf1100040000007812100055000000cd12100053000000201310004700000020546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e6420286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e206c61737420656c656d656e7420696e64696361746573206f6620746865206f6666656e636520776173206170706c69656420287472756529206f7220717565756564202866616c7365292e0000000000941310000a0000000000000050241000010000000000000000000000a013100002000000000000004e657753657373696f6e0000b0131000550000000514100022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e53746f72656452616e676574696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672e009c1410006200000088000000120000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e332e302f7372632f636f6465632e72734572726f725377617070696e672064697361626c656426fb100042000000590300002200000026fb1000420000005303000020000000000000008c1510001400000000000000a0151000010000000000000000000000a8151000010000000000000000000000b01510001600000000000000a0151000010000000000000000000000c815100001000000000000005061726174687265616452656769737465726564baf01000060000000516100035000000506172617468726561644465726567697374657265640000d015100035000000205468652070617261746872656164206f662074686520737570706c696564204944207761732064652d726567697374657265642e204120706172617468726561642077617320726567697374657265643b20697473206e657720494420697320737570706c6965642e00004c16100069000000440000000d0000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f7072696d6974697665732f61726974686d657469632f7372632f62696775696e742e72730000000000000000000000617474656d707420746f20646976696465206279207a65726f0000004c161000690000006d000000090000004c161000690000007e000000090000004c161000690000009c0000001b0000004c16100069000000d40100001c0000004c16100069000000d50100001c00000063616e6e6f74206669742061206e756d62657220696e746f20753132380000004c1610006900000090000000090000001600000000000000010000002a0000001600000000000000010000002b00000072656d696e646572206f6620646976206279206320697320616c77617973206c657373207468616e20633b20716564001600000008000000040000002c000000e517100070000000680000001b000000726573756c742063616e6e6f742066697420696e20753132382f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f7072696d6974697665732f61726974686d657469632f7372632f68656c706572735f3132386269742e727362616265736c6f744241424520696e686572656e742064617461206e6f7420666f756e640000008c1810006e000000cd0000000d0000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f7072696d6974697665732f72756e74696d652d696e746572666163652f7372632f696d706c732e727300001600000000000000010000001a000000486f737420746f207761736d2076616c7565732061726520656e636f64656420636f72726563746c793b2071656400004c1910007000000008010000090000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f7072696d6974697665732f72756e74696d652d696e746572666163652f7372632f706173735f62792e72731600000000000000010000001a0000001cd411000000000072756e74696d6552756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e67000000617474656d707420746f20646976696465206279207a65726f0000002c1a10006a0000005f0000002b0000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f7072696d6974697665732f72756e74696d652f7372632f67656e657269632f6572612e727348617368206e6f7420657175616cb41a100065000000f6030000130000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f7072696d6974697665732f72756e74696d652f7372632f7472616974732e7273426164206f726967696e43616e206e6f74206c6f6f6b75705472616e616374696f6e206469737061746368206973206d616e6461746f72793b207472616e73616374696f6e73206d6179206e6f742068617665206d616e6461746f727920646973706174636865732e412063616c6c20776173206c6162656c6c6564206173206d616e6461746f72792c2062757420726573756c74656420696e20616e204572726f722e5472616e73616374696f6e20776f756c642065786861757374732074686520626c6f636b206c696d6974735472616e73616374696f6e2068617320616e20616e6369656e7420626972746820626c6f636b5472616e73616374696f6e20686173206120626164207369676e61747572655472616e73616374696f6e206973206f757464617465645472616e73616374696f6e2077696c6c2062652076616c696420696e2074686520667574757265496e6162696c69747920746f2070617920736f6d6520666565732028652e672e206163636f756e742062616c616e636520746f6f206c6f77295472616e73616374696f6e2063616c6c206973206e6f74206578706563746564496e76616c69645472616e73616374696f6e20637573746f6d206572726f72436f756c64206e6f742066696e6420616e20756e7369676e65642076616c696461746f7220666f722074686520756e7369676e6564207472616e73616374696f6e436f756c64206e6f74206c6f6f6b757020696e666f726d6174696f6e20726571756972656420746f2076616c696461746520746865207472616e73616374696f6e556e6b6e6f776e5472616e73616374696f6e20637573746f6d206572726f724475706c69636174655265706f72744f6666656e63654572726f7200e424110066000000460000001f000000e4241100660000004f000000140000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32302e302f7372632f6e6962626c652f6e6962626c65736c6963652e7273000000c01d100065000000e10000000f000000c01d100065000000df0000000f000000c01d100065000000e10000003d000000781e1000570000004b00000042000000781e1000570000004a0000003e0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32302e302f7372632f6e6f64652e727300781e1000570000006b00000022000000781e1000570000009a00000032000000781e100057000000aa0000003e00000050687261676d656e426f67757353636f726550687261676d656e426f6775734564676550687261676d656e426f67757353656c66566f746550687261676d656e536c61736865644e6f6d696e6174696f6e50687261676d656e426f6775734e6f6d696e6174696f6e50687261676d656e426f6775734e6f6d696e61746f7250687261676d656e426f677573436f6d7061637450687261676d656e426f67757357696e6e657250687261676d656e426f67757357696e6e6572436f756e74536e617073686f74556e617661696c61626c6550687261676d656e5765616b5375626d697373696f6e50687261676d656e4561726c795375626d697373696f6e416c7265616479436c61696d65644e6f74536f72746564416e64556e69717565496e76616c69644e756d6265724f664e6f6d696e6174696f6e73496e76616c6964457261546f52657761726446756e6465645461726765744e6f556e6c6f636b4368756e6b4e6f4d6f72654368756e6b73496e73756666696369656e7456616c7565496e76616c6964536c617368496e6465784475706c6963617465496e646578456d70747954617267657473416c7265616479506169726564416c7265616479426f6e6465644e6f7453746173684e6f74436f6e74726f6c6c65725761726e696e673a20412073657373696f6e206170706561727320746f2068617665206265656e20736b69707065642e626f6e64626f6e645f6578747261756e626f6e6477697468647261775f756e626f6e64656476616c69646174656e6f6d696e6174656368696c6c7365745f70617965657365745f636f6e74726f6c6c65727365745f76616c696461746f725f636f756e74666f7263655f6e6f5f65726173666f7263655f6e65775f6572617365745f696e76756c6e657261626c6573666f7263655f756e7374616b65666f7263655f6e65775f6572615f616c7761797363616e63656c5f64656665727265645f736c6173687061796f75745f6e6f6d696e61746f727061796f75745f76616c696461746f727061796f75745f7374616b6572737265626f6e647365745f686973746f72795f6465707468726561705f73746173687375626d69745f656c656374696f6e5f736f6c7574696f6e7375626d69745f656c656374696f6e5f736f6c7574696f6e5f756e7369676e6564426f6e6465644c65646765724e6f6d696e61746f727356616c696461746f72536c617368496e4572614e6f6d696e61746f72536c617368496e457261536c617368696e675370616e735370616e536c617368536e617073686f7456616c696461746f7273536e617073686f744e6f6d696e61746f7273457261456c656374696f6e5374617475730000000000000014241000060000000000000064a511000200000000000000000000001c24100001000000000000000000000024241000050000000000000064a511000200000000000000000000002c241000010000000000000000000000342410001a000000000000005024100001000000000000000000000058241000020000000000000000000000682410000f00000000000000782410000100000000000000000000008024100001000000000000000000000056221000060000000000000064a5110002000000000000000000000088241000040000000000000000000000a8241000080000000000000064a51100020000000000000000000000b0241000010000000000000000000000b8241000090000000000000064a51100020000000000000000000000c4241000020000000000000052657761726400001f2710004f000000536c617368000000d6261000490000004f6c64536c617368696e675265706f727444697363617264656400007cff10000c0000007d26100047000000c4261000120000005374616b696e67456c656374696f6e006e2610000f0000002a261000440000006a251000230000001cd41100000000008d25100054000000e125100049000000556e626f6e646564452510002500000057697468647261776e000000d4241000570000002b2510001a00000020416e206163636f756e74206861732063616c6c6564206077697468647261775f756e626f6e6465646020616e642072656d6f76656420756e626f6e64696e67206368756e6b7320776f727468206042616c616e6365602066726f6d2074686520756e6c6f636b696e672071756575652e20416e206163636f756e742068617320756e626f6e646564207468697320616d6f756e742e20416e206163636f756e742068617320626f6e646564207468697320616d6f756e742e204e4f54453a2054686973206576656e74206973206f6e6c7920656d6974746564207768656e2066756e64732061726520626f6e64656420766961206120646973706174636861626c652e204e6f7461626c792c2069742077696c6c206e6f7420626520656d697474656420666f72207374616b696e672072657761726473207768656e20746865792061726520616464656420746f207374616b652e2041206e657720736574206f66207374616b6572732077617320656c656374656420776974682074686520676976656e20636f6d7075746174696f6e206d6574686f642e456c656374696f6e436f6d7075746520416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64206e6f742062652070726f6365737365642e204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e20546865207374616b657220686173206265656e207265776172646564206279207468697320616d6f756e742e20604163636f756e7449646020697320746865207374617368206163636f756e742e45726173526577617264506f696e74734572617356616c696461746f7252657761726445726173546f74616c5374616b654572726f723a2073746172745f73657373696f6e5f696e646578206d7573742062652073657420666f722063757272656e745f657261517565756564456c65637465644572617356616c696461746f725072656673457261735374616b657273436c6970706564457261735374616b657273556e6170706c696564536c617368657300000000000000092110000400000000000000442c10000300000000000000000000008c2c10001100000000000000000000000d2110000a00000000000000142d10000100000000000000000000002c2d1000100000000000000000000000172110000600000000000000ac2d1000010000000000000000000000c42d10001a00000000000000000000001d21100011000000000000001cd41100000000000000000000000000942e10001200000000000000000000002e2110000800000000000000242f10000100000000000000000000003c2f10000b0000000000000000000000362110000800000000000000942f1000010000000000000000000000ac2f10000b00000000000000000000003e21100005000000000000001cd41100000000000000000000000000043010000b00000000000000000000004321100009000000000000005c301000010000000000000000000000743010000b00000000000000000000004c2110000e00000000000000cc301000010000000000000000000000e43010000b00000000000000000000005a21100013000000000000003c311000010000000000000000000000543110000100000000000000000000006d2110000d000000000000001cd411000000000000000000000000005c3110000500000000000000000000007a2110000d000000000000001cd4110000000000000000000000000084311000060000000000000000000000872110001100000000000000b4311000010000000000000000000000cc311000010000000000000000000000982110000d00000000000000d4311000010000000000000000000000ec311000010000000000000000000000a521100014000000000000001cd41100000000000000000000000000f4311000050000000000000000000000b921100015000000000000001c3210000200000000000000000000004c321000070000000000000000000000ce211000100000000000000084321000020000000000000000000000b43210001e0000000000000000000000de2110001000000000000000a4331000010000000000000000000000bc331000130000000000000000000000ee2110000e0000000000000054341000020000000000000000000000843410000d0000000000000000000000fc2110000600000000000000ac2d1000010000000000000000000000ec3410000600000000000000000000000222100011000000000000001c35100001000000000000000000000034351000030000000000000000000000132210000a00000000000000d43110000100000000000000000000004c3510000700000000000000000000001d221000180000000000000084351000040000000000000000000000e43510004a00000000000000000000003522100021000000000000008435100004000000000000000000000034381000050000000000000000000000f85310000a00000000000000d9b211002300000000000000817f1100050000000000000009b7110015000000000000008554100005000000000000008a54100011000000ac5d100059000000055e1000210000001cd4110000000000265e10004c0000001cd4110000000000725e1000490000001cd41100000000008e5d1000100000001cd41100000000005fb211000b000000bb5e10003500000065ca100008000000f05e10001a0000001cd41100000000000a5f1000540000005e5f100050000000c7b211000c000000000000009e5d10000e0000000000000009b7110015000000685c100059000000c15c10000d0000001cd4110000000000ce5c100054000000225d1000590000007b5d1000130000001cd411000000000011531000550000001cd41100000000008e5d1000100000001cd41100000000005fb211000b000000665310003a00000065ca1000080000004e5c100010000000c7b211000c00000000000000817f1100050000000000000009b71100150000006958100055000000be58100040000000fe581000490000001cd4110000000000475910005200000099591000300000001cd4110000000000c95910004f000000185a10004f000000675a10003f0000001cd411000000000030541000550000001cd4110000000000a65a1000120000001cd4110000000000b85a1000260000001cd41100000000005fb211000b000000de5a100050000000a0531000260000002e5b100059000000875b10005c000000e35b100054000000375c1000170000004e5c1000100000005e5c10000a0000004f5610004b0000001cd41100000000009a5610004d000000e7561000130000001cd411000000000030541000550000001cd4110000000000fa561000130000001cd41100000000000d5710001b0000001cd41100000000005fb211000b00000028571000550000007d57100051000000ce5710003d0000000b5810005e000000c653100032000000c7b211000c000000000000003c5610000500000000000000415610000e000000025610003a0000001cd4110000000000da521000370000001cd411000000000030541000550000001cd41100000000005fb211000b000000665310003a000000a053100026000000c653100032000000c7b211000c00000000000000d35510000700000000000000da55100028000000e2541000440000001cd4110000000000da521000370000001cd411000000000030541000550000001cd41100000000005fb211000b00000026551000490000006f5510002e0000009d55100036000000c7b211000c0000009b541000320000001cd4110000000000da521000370000001cd411000000000030541000550000001cd41100000000005fb211000b000000665310003a000000cd54100015000000c653100032000000c7b211000c000000000000008554100005000000000000008a54100011000000025410002e0000001cd4110000000000da521000370000001cd411000000000030541000550000001cd41100000000005fb211000b000000665310003a000000a053100026000000c653100032000000c7b211000c00000000000000f85310000a00000000000000d9b2110023000000b6521000240000001cd4110000000000da521000370000001cd411000000000011531000550000001cd41100000000005fb211000b000000665310003a000000a053100026000000c653100032000000c7b211000c000000000000009ab611000300000000000000aa5210000c0000008a521000200000005e5210002c0000001cd41100000000005fb211000b0000004e52100010000000c7b211000c000000d35110005300000026521000280000001cd41100000000005fb211000b0000004e52100010000000c7b211000c00000000000000115010000a000000000000007671110011000000a051100033000000000000009b51100005000000000000009db611000c000000585110004300000003511000410000001cd41100000000005fb211000b0000004451100014000000c7b211000c000000000000004a45100003000000000000004d4510000800000000000000f65010000d00000000000000d2de1000080000003350100051000000845010001c000000a0501000410000001cd41100000000005fb211000b000000e150100015000000c7b211000c000000000000004a45100003000000000000004d4510000800000000000000115010000a000000000000001b501000180000008149100058000000d949100057000000304a1000310000001cd41100000000003d4c1000290000001cd4110000000000664c10003f000000c94a100059000000224b10004c000000a54c100056000000fb4c100049000000444d100022000000664d100042000000a84d100048000000f04d1000280000001cd41100000000006e4b100057000000c54b10000e0000001cd4110000000000d34b1000510000001cd41100000000005fb211000b000000184e1000570000006f4e100027000000964e10004e000000e44e1000370000001b4f1000500000006b4f100052000000bd4f100054000000c7b211000c000000000000004a45100003000000000000004d451000080000008149100058000000d949100057000000304a1000310000001cd4110000000000614a1000290000001cd41100000000008a4a10003f000000c94a100059000000224b10004c0000001cd41100000000006e4b100057000000c54b10000e0000001cd4110000000000d34b1000510000001cd41100000000005fb211000b000000244c1000190000001b81110031000000c7b211000c00000000000000724910000f000000000000009db611000c000000000000004a45100003000000000000004d4510000800000090471000440000001cd4110000000000d447100053000000274810004a000000714810004d0000001cd4110000000000be48100056000000144910001e0000001cd41100000000005fb211000b00000032491000400000001b81110031000000c7b211000c000000df461000380000001cd41100000000005fb211000b000000174710003c000000534710003d000000c7b211000c00000000000000bd4610001100000000000000ce461000110000008f461000190000001cd4110000000000a846100015000000554510004e000000a345100058000000fb451000300000001cd41100000000002b461000240000001cd41100000000004f4610004000000000000000f944100007000000000000000045100013000000000000001345100013000000000000002645100012000000000000003845100005000000000000003d4510000d000000000000004a45100003000000000000004d4510000800000055391000380000001cd41100000000008d3910000d0000009a391000450000001cd4110000000000df391000210000001cd4110000000000003a10002b0000001cd41100000000002b3a10003d000000683a100054000000bc3a10000c0000001cd4110000000000c83a10004a0000001cd4110000000000123b10002a0000001cd41100000000003c3b1000320000001cd41100000000006e3b100053000000c13b100047000000083c10004c000000543c100054000000a83c100058000000003d1000260000001cd4110000000000263d1000180000001cd41100000000003e3d100039000000773d10003e000000b53d10002b000000e03d100055000000353e1000570000008c3e1000100000009c3e100043000000df3e10001b0000001cd4110000000000fa3e1000300000001cd41100000000002a3f100059000000833f100059000000dc3f1000500000002c401000270000001cd41100000000005fb211000b0000005340100059000000ac401000390000001cd4110000000000e5401000590000003e411000520000001cd411000000000090411000380000001cd4110000000000c841100027000000ef4110002600000015421000270000003c421000370000001cd41100000000007342100045000000b84210003f000000f74210004200000039431000450000001cd41100000000007e4310004f000000cd431000570000001cd4110000000000244410002300000047441000220000001cd4110000000000694410002b00000094441000270000001cd4110000000000bb4410003e000000c7b211000c0000005c381000300000001cd41100000000008c38100057000000e3381000580000003b3910001a00000020556e7369676e65642076657273696f6e206f6620607375626d69745f656c656374696f6e5f736f6c7574696f6e602e204e6f746520746861742074686973206d757374207061737320746865205b6056616c6964617465556e7369676e6564605d20636865636b207768696368206f6e6c7920616c6c6f7773207472616e73616374696f6e732066726f6d20746865206c6f63616c206e6f646520746f20626520696e636c756465642e20496e206f7468657220776f7264732c206f6e6c792074686520626c6f636b20617574686f722063616e20696e636c7564652061207472616e73616374696f6e20696e2074686520626c6f636b2e205375626d697420612070687261676d656e20726573756c7420746f2074686520636861696e2e2049662074686520736f6c7574696f6e3a20312e2069732076616c69642e20322e206861732061206265747465722073636f7265207468616e206120706f74656e7469616c6c79206578697374696e6720736f6c7574696f6e206f6e20636861696e2e207468656e2c2069742077696c6c206265205f7075745f206f6e20636861696e2e204120736f6c7574696f6e20636f6e7369737473206f662074776f20706965636573206f6620646174613a20312e206077696e6e657273603a206120666c617420766563746f72206f6620616c6c207468652077696e6e657273206f662074686520726f756e642e20322e206061737369676e6d656e7473603a2074686520636f6d706163742076657273696f6e206f6620616e2061737369676e6d656e7420766563746f72207468617420656e636f64657320746865206564676520202020776569676874732e20426f7468206f66207768696368206d617920626520636f6d7075746564207573696e67205b6070687261676d656e605d2c206f7220616e79206f7468657220616c676f726974686d2e204164646974696f6e616c6c792c20746865207375626d6974746572206d7573742070726f766964653a202d20546865206073636f7265602074686174207468657920636c61696d20746865697220736f6c7574696f6e206861732e20426f74682076616c696461746f727320616e64206e6f6d696e61746f72732077696c6c20626520726570726573656e74656420627920696e646963657320696e2074686520736f6c7574696f6e2e2054686520696e64696365732073686f756c6420726573706563742074686520636f72726573706f6e64696e6720747970657320285b6056616c696461746f72496e646578605d20616e64205b604e6f6d696e61746f72496e646578605d292e204d6f72656f7665722c20746865792073686f756c642062652076616c6964207768656e207573656420746f20696e64657820696e746f205b60536e617073686f7456616c696461746f7273605d20616e64205b60536e617073686f744e6f6d696e61746f7273605d2e20416e7920696e76616c696420696e6465782077696c6c2063617573652074686520736f6c7574696f6e20746f2062652072656a65637465642e2054686573652074776f2073746f72616765206974656d73206172652073657420647572696e672074686520656c656374696f6e2077696e646f7720616e64206d6179206265207573656420746f2064657465726d696e652074686520696e64696365732e204120736f6c7574696f6e2069732076616c69642069663a20302e204974206973207375626d6974746564207768656e205b60457261456c656374696f6e537461747573605d20697320604f70656e602e20312e2049747320636c61696d65642073636f726520697320657175616c20746f207468652073636f726520636f6d7075746564206f6e2d636861696e2e20322e2050726573656e74732074686520636f7272656374206e756d626572206f662077696e6e6572732e20332e20416c6c20696e6465786573206d7573742062652076616c7565206163636f7264696e6720746f2074686520736e617073686f7420766563746f72732e20416c6c20656467652076616c756573206d75737420202020616c736f20626520636f727265637420616e642073686f756c64206e6f74206f766572666c6f7720746865206772616e756c6172697479206f662074686520726174696f20747970652028692e652e20323536202020206f722062696c6c696f6e292e20342e20466f72206561636820656467652c20616c6c2074617267657473206172652061637475616c6c79206e6f6d696e617465642062792074686520766f7465722e20352e2048617320636f72726563742073656c662d766f7465732e204120736f6c7574696f6e732073636f726520697320636f6e736973746564206f66203320706172616d65746572733a20312e20606d696e207b20737570706f72742e746f74616c207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265206d6178696d697a65642e20322e206073756d207b20737570706f72742e746f74616c207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265206d696e696d697a65642e20332e206073756d207b20737570706f72742e746f74616c5e32207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265202020206d696e696d697a65642028746f20656e73757265206c6573732076617269616e63652920453a206e756d626572206f662065646765732e206d3a2073697a65206f662077696e6e657220636f6d6d69747465652e206e3a206e756d626572206f66206e6f6d696e61746f72732e20643a2065646765206465677265652028313620666f72206e6f772920763a206e756d626572206f66206f6e2d636861696e2076616c696461746f722063616e646964617465732e204e4f54453a20676976656e206120736f6c7574696f6e20776869636820697320726564756365642c2077652063616e20656e61626c652061206e657720636865636b2074686520656e7375726520607c457c203c206e202b206d602e20576520646f6e277420646f2074686973205f7965745f2c20627574206f7572206f6666636861696e20776f726b657220636f6465206578656375746573206974206e6f6e657468656c6573732e206d616a6f722073746570732028616c6c20646f6e6520696e2060636865636b5f616e645f7265706c6163655f736f6c7574696f6e60293a202d2053746f726167653a204f28312920726561642060456c656374696f6e537461747573602e202d2053746f726167653a204f2831292072656164206050687261676d656e53636f7265602e202d2053746f726167653a204f2831292072656164206056616c696461746f72436f756e74602e202d2053746f726167653a204f283129206c656e67746820726561642066726f6d2060536e617073686f7456616c696461746f7273602e202d2053746f726167653a204f287629207265616473206f6620604163636f756e7449646020746f2066657463682060736e617073686f745f76616c696461746f7273602e202d204d656d6f72793a204f286d2920697465726174696f6e7320746f206d61702077696e6e657220696e64657820746f2076616c696461746f722069642e202d2053746f726167653a204f286e2920726561647320604163636f756e7449646020746f2066657463682060736e617073686f745f6e6f6d696e61746f7273602e202d204d656d6f72793a204f286e202b206d2920726561647320746f206d617020696e64657820746f20604163636f756e7449646020666f7220756e2d636f6d706163742e202d2053746f726167653a204f286529206163636f756e7469642072656164732066726f6d20604e6f6d696e6174696f6e6020746f207265616420636f7272656374206e6f6d696e6174696f6e732e202d2053746f726167653a204f2865292063616c6c7320696e746f2060736c61736861626c655f62616c616e63655f6f665f657874656e6465646020746f20636f6e7665727420726174696f20746f207374616b65642e202d204d656d6f72793a206275696c645f737570706f72745f6d61702e204f2865292e202d204d656d6f72793a206576616c756174655f737570706f72743a204f2845292e202d2053746f726167653a204f2865292077726974657320746f2060517565756564456c6563746564602e202d2053746f726167653a204f28312920777269746520746f206051756575656453636f7265602054686520776569676874206f6620746869732063616c6c20697320312f31307468206f662074686520626c6f636b7320746f74616c207765696768742e77696e6e6572735665633c56616c696461746f72496e6465783e636f6d706163745f61737369676e6d656e7473436f6d7061637441737369676e6d656e747373636f726550687261676d656e53636f7265657261457261496e6465782052656d6f766520616c6c20646174612073747275637475726520636f6e6365726e696e672061207374616b65722f7374617368206f6e6365206974732062616c616e6365206973207a65726f2e205468697320697320657373656e7469616c6c79206571756976616c656e7420746f206077697468647261775f756e626f6e64656460206578636570742069742063616e2062652063616c6c656420627920616e796f6e6520616e6420746865207461726765742060737461736860206d7573742068617665206e6f2066756e6473206c6566742e20546869732063616e2062652063616c6c65642066726f6d20616e79206f726967696e2e202d20607374617368603a20546865207374617368206163636f756e7420746f20726561702e204974732062616c616e6365206d757374206265207a65726f2e2053657420686973746f72795f64657074682076616c75652e204f726967696e206d75737420626520726f6f742e6e65775f686973746f72795f6465707468436f6d706163743c457261496e6465783e205265626f6e64206120706f7274696f6e206f6620746865207374617368207363686564756c656420746f20626520756e6c6f636b65642e202d2054696d6520636f6d706c65786974793a204f2831292e20426f756e64656420627920604d41585f554e4c4f434b494e475f4348554e4b53602e202d2053746f72616765206368616e6765733a2043616e277420696e6372656173652073746f726167652c206f6e6c792064656372656173652069742e20506179206f757420616c6c20746865207374616b65727320626568696e6420612073696e676c652076616c696461746f7220666f7220612073696e676c65206572612e202d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e205468656972206e6f6d696e61746f72732c20757020746f20202060543a3a4d61784e6f6d696e61746f72526577617264656450657256616c696461746f72602c2077696c6c20616c736f207265636569766520746865697220726577617264732e202d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e20546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966206974206973206e6f74206f6e65206f6620746865207374616b6572732e202d2054696d6520636f6d706c65786974793a206174206d6f7374204f284d61784e6f6d696e61746f72526577617264656450657256616c696461746f72292e76616c696461746f725f7374617368202a2a546869732065787472696e7369632077696c6c2062652072656d6f76656420616674657220604d6967726174696f6e457261202b20486973746f727944657074686020686173207061737365642c20676976696e67206f70706f7274756e69747920666f7220757365727320746f20636c61696d20616c6c2072657761726473206265666f7265206d6f76696e6720746f2053696d706c65205061796f7574732e20416674657220746869732074696d652c20796f752073686f756c642075736520607061796f75745f7374616b6572736020696e73746561642e2a2a204d616b65206f6e652076616c696461746f722773207061796f757420666f72206f6e65206572612e202d206077686f602069732074686520636f6e74726f6c6c6572206163636f756e74206f66207468652076616c696461746f7220746f20706179206f75742e202d206065726160206d6179206e6f74206265206c6f776572207468616e206f6e6520666f6c6c6f77696e6720746865206d6f737420726563656e746c792070616964206572612e204966206974206973206869676865722c2020207468656e20697420696e6469636174657320616e20696e737472756374696f6e20746f20736b697020746865207061796f7574206f6620616c6c2070726576696f757320657261732e205741524e494e473a206f6e636520616e2065726120697320706179656420666f7220612076616c696461746f7220737563682076616c696461746f722063616e277420636c61696d20746865207061796f7574206f662070726576696f7573206572612e205741524e494e473a20496e636f727265637420617267756d656e747320686572652063616e20726573756c7420696e206c6f7373206f66207061796f75742e2042652076657279206361726566756c2e202d2054696d6520636f6d706c65786974793a204f2831292e204d616b65206f6e65206e6f6d696e61746f722773207061796f757420666f72206f6e65206572612e202d206077686f602069732074686520636f6e74726f6c6c6572206163636f756e74206f6620746865206e6f6d696e61746f7220746f20706179206f75742e202d206076616c696461746f72736020697320746865206c697374206f6620616c6c2076616c696461746f72732074686174206077686f6020686164206578706f7375726520746f20647572696e672060657261602c202020616c6f6e67736964652074686520696e646578206f66206077686f6020696e2074686520636c6970706564206578706f73757265206f66207468652076616c696461746f722e202020492e652e206561636820656c656d656e742069732061207475706c65206f66202020602876616c696461746f722c20696e646578206f66206077686f6020696e20636c6970706564206578706f73757265206f662076616c696461746f7229602e202020496620697420697320696e636f6d706c6574652c207468656e206c657373207468616e207468652066756c6c207265776172642077696c6c2062652070616964206f75742e2020204974206d757374206e6f742065786365656420604d41585f4e4f4d494e4154494f4e53602e202d204e756d626572206f662073746f726167652072656164206f6620604f2876616c696461746f727329603b206076616c696461746f7273602069732074686520617267756d656e74206f66207468652063616c6c2c202020616e6420697320626f756e64656420627920604d41585f4e4f4d494e4154494f4e53602e202d20456163682073746f72616765207265616420697320604f284e29602073697a6520616e64206465636f646520636f6d706c65786974793b20604e602069732074686520206d6178696d756d2020206e6f6d696e6174696f6e7320746861742063616e20626520676976656e20746f20612073696e676c652076616c696461746f722e202d20436f6d7075746174696f6e20636f6d706c65786974793a20604f284d41585f4e4f4d494e4154494f4e53202a206c6f674e29603b20604d41585f4e4f4d494e4154494f4e5360206973207468652020206d6178696d756d206e756d626572206f662076616c696461746f72732074686174206d6179206265206e6f6d696e6174656420627920612073696e676c65206e6f6d696e61746f722c206974206973202020626f756e646564206f6e6c792065636f6e6f6d6963616c6c792028616c6c206e6f6d696e61746f72732061726520726571756972656420746f20706c6163652061206d696e696d756d207374616b65292e76616c696461746f72735665633c28543a3a4163636f756e7449642c20753332293e2043616e63656c20656e6163746d656e74206f66206120646566657272656420736c6173682e2043616e2062652063616c6c6564206279206569746865722074686520726f6f74206f726967696e206f72207468652060543a3a536c61736843616e63656c4f726967696e602e2070617373696e67207468652065726120616e6420696e6469636573206f662074686520736c617368657320666f7220746861742065726120746f206b696c6c2e202d204f6e652073746f726167652077726974652e736c6173685f696e646963657320466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f662073657373696f6e7320696e646566696e6974656c792e202d204f6e652073746f7261676520777269746520466f72636520612063757272656e74207374616b657220746f206265636f6d6520636f6d706c6574656c7920756e7374616b65642c20696d6d6564696174656c792e737461736820536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e20466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c20626520726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e202d204e6f20617267756d656e74732e20466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e2054686520696465616c206e756d626572206f662076616c696461746f72732e436f6d706163743c7533323e202852652d297365742074686520636f6e74726f6c6c6572206f6620612073746173682e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e636f6e74726f6c6c6572202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e706179656552657761726444657374696e6174696f6e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e202d20436f6e7461696e73206f6e6520726561642e204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f66206074617267657473602c2077686963682069732063617070656420617420436f6d7061637441737369676e6d656e74733a3a4c494d49542e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e746172676574735665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e707265667356616c696461746f7250726566732052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e20456d697473206057697468647261776e602e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e20456d6974732060556e626f6e646564602e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c6564207669612020206077697468647261775f756e626f6e646564602e202d204f6e6520444220656e7472792e203c2f7765696768743e2041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e20456d6974732060426f6e646564602e6d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e000000000000106c10000c00000000000000000000001456110003000000000000000000000000000000000000000000000000000000000000001cd411001c6c100000000000000000002c6c100007000000000000000100000000000000646c10000e00000000000000000000001456110003000000000000000000000000000000000000000000000000000000000000001cd41100746c10000000000000000000846c1000010000000000000001000000000000008c6c10001500000000000000000000001456110003000000000000000000000000000000000000000000000000000000000000001cd41100a46c10000000000000000000b46c100001000000000000000100000000000000bc6c10000d00000000000000000000007671110011000000000000000000000000000000000000000000000000000000000000001cd41100cc6c10000000000000000000dc6c100003000000000000000100000000000000562210000600000001050000000000009db611000c000000000000009db611000c000000000000000000000000000000000000001cd411003c7210000000000000000000f46c1000010000000000000000000000000000005c2210000600000001020000000000009db611000c00000000000000fc6c100029000000000000000000000000000000000000001cd411003c7210000000000000000000286d100001000000000000000000000000000000306d10000500000001050000000000009db611000c000000000000008a54100011000000000000000000000000000000000000001cd41100386d10000000000000000000486d1000010000000000000001000000000000003bd610000a00000001050000000000009db611000c00000000000000415610000e000000000000000000000000000000000000001cd41100dc6e10000000000000000000506d100001000000000000000100000000000000622210000a00000001050000000000009db611000c00000000000000586d100019000000000000000000000000000000000000001cd41100746d10000000000000000000846d1000010000000000000000000000000000008c6d10000a00000000000000000000004d45100008000000000000000000000000000000000000000000000000000000000000001cd41100007310000000000000000000986d100004000000000000000000000000000000b86d1000090000000000000000000000c16d10000d000000000000000000000000000000000000000000000000000000000000001cd41100d06d10000000000000000000e06d100004000000000000000000000000000000006e10001500000001050000000000004d45100008000000000000007cff10000c000000000000000000000000000000000000001cd41100007310000000000000000000186e100001000000000000000000000000000000062810000b00000002050500000000004d45100008000000000000009db611000c00000000000000206e100024000000000000001cd41100746e10000000000000000000446e100006000000000000000100000000000000f42710001200000002050500000000004d45100008000000000000009db611000c00000000000000206e100024000000000000001cd41100746e10000000000000000000846e10000b000000000000000100000000000000e22710001200000002050500000000004d45100008000000000000009db611000c00000000000000415610000e000000000000001cd41100dc6e10000000000000000000ec6e1000050000000000000001000000000000007e2710001300000001050000000000004d4510000800000000000000de4d11000c000000000000000000000000000000000000001cd41100ec7010000000000000000000146f1000030000000000000000000000000000006e2710001000000001050000000000004d45100008000000000000002c6f10001d000000000000000000000000000000000000001cd411004c6f100000000000000000005c6f100002000000000000000100000000000000912710000e00000001050000000000004d4510000800000000000000de4d11000c000000000000000000000000000000000000001cd41100f46f100000000000000000006c6f1000020000000000000001000000000000007c6f1000080000000000000000000000846f100007000000000000000000000000000000000000000000000000000000000000001cd411008c6f100000000000000000009c6f100001000000000000000100000000000000a46f10001300000000000000000000005f3a110007000000000000000000000000000000000000000000000000000000000000001cd41100b86f10000000000000000000c86f100003000000000000000100000000000000e06f1000130000000000000000000000de4d11000c000000000000000000000000000000000000000000000000000000000000001cd41100f46f100000000000000000000470100002000000000000000100000000000000112810001000000001050000000000004d4510000800000000000000147010002f000000000000000000000000000000000000001cd4110044701000000000000000000054701000010000000000000001000000000000005c7010000a0000000000000000000000667010001d000000000000000000000000000000000000000000000000000000000000001cd4110084701000000000000000000094701000040000000000000001000000000000006c2210001300000002050500000000004d45100008000000000000009db611000c00000000000000b470100017000000000000001cd41100cc7010000000000000000000dc701000020000000000000000000000000000007f2210001300000002050500000000004d45100008000000000000009db611000c00000000000000de4d11000c000000000000001cd41100ec7010000000000000000000fc70100001000000000000000000000000000000922210000d00000001050000000000009db611000c000000000000000471100017000000000000000000000000000000000000001cd411001c71100000000000000000002c711000010000000000000000000000000000009f2210000900000001050000000000003471100023000000000000005771100022000000000000000000000000000000000000001cd411007c71100000000000000000008c711000020000000000000001000000000000009c7110001600000000000000000000004d45100008000000000000000000000000000000000000000000000000000000000000001cd41100007310000000000000000000b471100001000000000000000000000000000000a82210001200000000000000000000007671110011000000000000000000000000000000000000000000000000000000000000001cd41100cc7110000000000000000000bc71100002000000000000000000000000000000ba2210001200000000000000000000007671110011000000000000000000000000000000000000000000000000000000000000001cd41100cc7110000000000000000000dc71100002000000000000000000000000000000d52710000d0000000000000000000000ec7110002a000000000000000000000000000000000000000000000000000000000000001cd411003c72100000000000000000001872100003000000000000000000000000000000307210000b00000000000000000000003d4510000d000000000000000000000000000000000000000000000000000000000000001cd411003c72100000000000000000004c72100001000000000000000000000000000000cc221000110000000000000000000000547210001e000000000000000000000000000000000000000000000000000000000000001cd4110074721000000000000000000084721000020000000000000001000000000000009472100015000000000000000000000031cf110004000000000000000000000000000000000000000000000000000000000000001cd41100ac7210000000000000000000bc72100001000000000000000100000000000000a48711000e0000000000000000000000b287110008000000000000000000000000000000000000000000000000000000000000001cd41100c47210000000000000000000d472100004000000000000000100000000000000f47210000a00000000000000000000004d45100008000000000000000000000000000000000000000000000000000000000000001cd4110000731000000000000000000010731000010000000000000000000000486973746f727944657074681600000000000000010000002d00000048821000230000001cd41100000000006b8210004e0000001cd4110000000000b982100043000000fc8210002b000000278310004400000056616c696461746f72436f756e7400001600000000000000010000002e0000001e8210002a0000004d696e696d756d56616c696461746f72436f756e740000001600000000000000010000002f000000ce81100050000000496e76756c6e657261626c657300000016000000000000000100000030000000fa801000560000005081100053000000a38110002b000000ba801000400000005374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00000069801000510000005061796565000000160000000000000001000000310000003080100039000000df7f1000510000004e6f6d696e6174696f6e733c543a3a4163636f756e7449643e00000016000000000000000100000032000000867f10005900000043757272656e744572610000f67e1000170000001cd41100000000000d7f100059000000667f100020000000416374697665457261416374697665457261496e666f000016000000000000000100000032000000477e1000360000001cd41100000000007d7e10002e000000ab7e10004b00000045726173537461727453657373696f6e496e646578000000fb7d10004c0000004578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3edd7d10001e0000001cd41100000000007d7b1000580000001cd4110000000000d57b10002a0000008d7d10005000000016000000000000000100000033000000ff7b1000260000001cd4110000000000257c1000560000007b7c100037000000b27c100047000000f97c10003d0000001cd4110000000000367d1000570000001cd4110000000000d57b10002a0000008d7d10005000000016000000000000000100000034000000397b1000440000001cd41100000000007d7b1000580000001cd4110000000000d57b10002a000000af7a1000420000001cd4110000000000f17a100048000000457261526577617264506f696e74733c543a3a4163636f756e7449643e000000160000000000000001000000350000003b7a10002b000000667a100049000000b97910003b000000f479100047000000466f726365457261466f7263696e670016000000000000000100000031000000a479100015000000536c6173685265776172644672616374696f6e001600000000000000010000002e0000002d7910003e0000001cd41100000000006b7910003900000043616e63656c6564536c6173685061796f75740016000000000000000100000036000000ad78100045000000f27810003b0000005665633c556e6170706c696564536c6173683c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3e00160000000000000001000000300000007c78100031000000426f6e646564457261735665633c28457261496e6465782c2053657373696f6e496e646578293e0016000000000000000100000030000000d2771000490000001cd41100000000001b781000320000004d7810002f0000002850657262696c6c2c2042616c616e63654f663c543e2900160000000000000001000000320000006577100051000000b67710001c000000160000000000000001000000320000000d77100058000000736c617368696e673a3a536c617368696e675370616e730016000000000000000100000032000000ea7610002300000028543a3a4163636f756e7449642c20736c617368696e673a3a5370616e496e64657829736c617368696e673a3a5370616e5265636f72643c42616c616e63654f663c543e3e000000160000000000000001000000370000006d7610004f000000bc7610002e0000004561726c69657374556e6170706c696564536c61736800002e7610003f000000d5751000590000008f751000460000001600000000000000010000003200000036751000590000008f75100046000000456c656374696f6e526573756c743c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00007874100059000000d174100058000000297510000d00000051756575656453636f726500160000000000000001000000320000004c7410002c000000456c656374696f6e5374617475733c543a3a426c6f636b4e756d6265723e000016000000000000000100000031000000df73100052000000317410001b000000497343757272656e7453657373696f6e46696e616c00000016000000000000000100000032000000b17310002e000000160000000000000001000000380000005673100033000000e48711001f0000001cd411000000000089731000280000004d696772617465457261000016000000000000000100000032000000187310003e0000002054686520657261207768657265207765206d696772617465642066726f6d204c617a79205061796f75747320746f2053696d706c65205061796f7574732054727565206966206e6574776f726b20686173206265656e20757067726164656420746f20746869732076657273696f6e2e20546869732069732073657420746f2076332e302e3020666f72206e6577206e6574776f726b732e2054727565206966207468652063757272656e7420706c616e6e65642073657373696f6e2069732066696e616c2e20466c616720746f20636f6e74726f6c2074686520657865637574696f6e206f6620746865206f6666636861696e20656c656374696f6e2e205768656e20604f70656e285f29602c2077652061636365707420736f6c7574696f6e7320746f206265207375626d69747465642e205468652073636f7265206f66207468652063757272656e74205b60517565756564456c6563746564605d2e20546865206e6578742076616c696461746f72207365742e2041742074686520656e64206f6620616e206572612c206966207468697320697320617661696c61626c652028706f74656e7469616c6c792066726f6d2074686520726573756c74206f6620616e206f6666636861696e20776f726b6572292c20697420697320696d6d6564696174656c7920757365642e204f74686572776973652c20746865206f6e2d636861696e20656c656374696f6e2069732065786563757465642e20536e617073686f74206f66206e6f6d696e61746f72732061742074686520626567696e6e696e67206f66207468652063757272656e7420656c656374696f6e2077696e646f772e20546869732073686f756c64206f6e6c79206861766520612076616c7565207768656e205b60457261456c656374696f6e537461747573605d203d3d2060456c656374696f6e5374617475733a3a4f70656e285f29602e20536e617073686f74206f662076616c696461746f72732061742074686520626567696e6e696e67206f66207468652063757272656e7420656c656374696f6e2077696e646f772e20546869732073686f756c64206f6e6c7920546865206561726c696573742065726120666f72207768696368207765206861766520612070656e64696e672c20756e6170706c69656420736c6173682e205265636f72647320696e666f726d6174696f6e2061626f757420746865206d6178696d756d20736c617368206f6620612073746173682077697468696e206120736c617368696e67207370616e2c2061732077656c6c20617320686f77206d7563682072657761726420686173206265656e2070616964206f75742e20536c617368696e67207370616e7320666f72207374617368206163636f756e74732e20416c6c20736c617368696e67206576656e7473206f6e206e6f6d696e61746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682076616c7565206f6620746865206572612e20416c6c20736c617368696e67206576656e7473206f6e2076616c696461746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682070726f706f7274696f6e20616e6420736c6173682076616c7565206f6620746865206572612e2041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e204d75737420636f6e7461696e7320696e666f726d6174696f6e20666f72206572617320666f72207468652072616e67653a20605b6163746976655f657261202d20626f756e64696e675f6475726174696f6e3b206163746976655f6572615d6020416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e2054686520616d6f756e74206f662063757272656e637920676976656e20746f207265706f7274657273206f66206120736c617368206576656e74207768696368207761732063616e63656c65642062792065787472616f7264696e6172792063697263756d7374616e6365732028652e672e20676f7665726e616e6365292e205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e204d6f6465206f662065726120666f7263696e672e2054686520746f74616c20616d6f756e74207374616b656420666f7220746865206c6173742060484953544f52595f44455054486020657261732e20496620746f74616c206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207374616b652069732072657475726e65642e205265776172647320666f7220746865206c6173742060484953544f52595f44455054486020657261732e20496620726577617264206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207265776172642069732072657475726e65642e2054686520746f74616c2076616c696461746f7220657261207061796f757420666f7220746865206c6173742060484953544f52595f44455054486020657261732e2045726173207468617420686176656e27742066696e697368656420796574206f7220686173206265656e2072656d6f76656420646f65736e27742068617665207265776172642e2053696d696c617220746f2060457261735374616b657273602c207468697320686f6c64732074686520707265666572656e636573206f662076616c696461746f72732e2054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e2049732069742072656d6f7665642061667465722060484953544f52595f44455054486020657261732e20436c6970706564204578706f73757265206f662076616c696461746f72206174206572612e20546869732069732073696d696c617220746f205b60457261735374616b657273605d20627574206e756d626572206f66206e6f6d696e61746f7273206578706f736564206973207265647563656420746f207468652060543a3a4d61784e6f6d696e61746f72526577617264656450657256616c696461746f72602062696767657374207374616b6572732e20284e6f74653a20746865206669656c642060746f74616c6020616e6420606f776e60206f6620746865206578706f737572652072656d61696e7320756e6368616e676564292e2054686973206973207573656420746f206c696d69742074686520692f6f20636f737420666f7220746865206e6f6d696e61746f72207061796f75742e2054686973206973206b657965642066697374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e204578706f73757265206f662076616c696461746f72206174206572612e205468652073657373696f6e20696e646578206174207768696368207468652065726120737461727420666f7220746865206c6173742060484953544f52595f44455054486020657261732e20546865206163746976652065726120696e666f726d6174696f6e2c20697420686f6c647320696e64657820616e642073746172742e20546865206163746976652065726120697320746865206572612063757272656e746c792072657761726465642e2056616c696461746f7220736574206f66207468697320657261206d75737420626520657175616c20746f206053657373696f6e496e746572666163653a3a76616c696461746f7273602e205468652063757272656e742065726120696e6465782e205468697320697320746865206c617465737420706c616e6e6564206572612c20646570656e64696e67206f6e20686f77207468652053657373696f6e2070616c6c657420717565756573207468652076616c696461746f72207365742c206974206d6967687420626520616374697665206f72206e6f742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e204e756d626572206f66206572617320746f206b65657020696e20686973746f72792e20496e666f726d6174696f6e206973206b65707420666f72206572617320696e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e204d757374206265206d6f7265207468616e20746865206e756d626572206f6620657261732064656c617965642062792073657373696f6e206f74686572776973652e20492e652e2061637469766520657261206d75737420616c7761797320626520696e20686973746f72792e20492e652e20606163746976655f657261203e2063757272656e745f657261202d20686973746f72795f646570746860206d7573742062652067756172616e746565642e0000000000dc8310000e000000000000007cff10000c000000000000001cd41100ec8310000000000000000000fc831000010000000000000000000000048410000f000000000000004d45100008000000000000001cd4110014841000000000000000000024841000010000000000000053657373696f6e73506572457261000016000000000000000100000039000000658410001c000000426f6e64696e674475726174696f6e001600000000000000010000003a0000002c84100039000000204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e65786163746c79206f6e65206f6620606d617962655f76616c696461746f726020616e6420606d617962655f6e6f6d696e6174696f6e2e69735f736f6d656020697320747275652e2069735f76616c696461746f722069732066616c73653b206d617962655f6e6f6d696e6174696f6e20697320736f6d653b207165640000108510005d00000063090000220000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f7374616b696e672f7372632f6c69622e727300000000000000cc2010000d0000000000000064881000010000000000000000000000c420100008000000000000006c881000010000000000000000000000b72010000d0000000000000074881000010000000000000000000000aa2010000d000000000000007c8810000100000000000000000000009e2010000c0000000000000084881000010000000000000000000000902010000e000000000000008c8810000100000000000000000000007f2010001100000000000000948810000100000000000000000000006e20100011000000000000009c881000010000000000000000000000622010000c00000000000000a4881000010000000000000000000000552010000d00000000000000ac881000010000000000000000000000492010000c00000000000000b4881000010000000000000000000000372010001200000000000000bc8810000100000000000000000000001d2010001a00000000000000c48810000100000000000000000000000b2010001200000000000000cc881000010000000000000000000000fd1f10000e00000000000000d4881000010000000000000000000000e61f10001700000000000000dc881000010000000000000000000000d01f10001600000000000000e4881000010000000000000000000000bd1f10001300000000000000ec881000010000000000000000000000a51f10001800000000000000f4881000010000000000000000000000921f10001300000000000000fc8810000200000000000000000000007e1f100014000000000000000c891000020000000000000000000000681f100016000000000000001c891000010000000000000000000000511f1000170000000000000024891000010000000000000000000000381f100019000000000000002c891000020000000000000000000000231f100015000000000000003c891000010000000000000000000000121f1000110000000000000044891000010000000000000000000000001f100012000000000000004c8910000100000000000000df8e10001a000000ca8e100015000000b18e100019000000938e10001e0000007a8e100019000000698e100011000000478e100022000000148e100033000000ef8d100025000000c68d100029000000938d1000330000007c8d1000170000005d8d10001f0000003c8d100021000000f98c100043000000c08c100039000000808c1000400000004c8c100034000000208c10002c000000ba8b100058000000128c10000e000000398b100057000000908b10002a000000f48a100045000000a18a100053000000348a1000580000008c8a100015000000eb891000490000009a8910005100000054891000460000002054686520636c61696d65642073636f726520646f6573206e6f74206d61746368207769746820746865206f6e6520636f6d70757465642066726f6d2074686520646174612e20546865207375626d697474656420726573756c742068617320756e6b6e6f776e206564676573207468617420617265206e6f7420616d6f6e67207468652070726573656e7465642077696e6e6572732e20412073656c6620766f7465206d757374206f6e6c79206265206f726967696e617465642066726f6d20612076616c696461746f7220746f204f4e4c59207468656d73656c7665732e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f72732068617320616e2065646765207768696368206973207375626d6974746564206265666f726520746865206c617374206e6f6e2d7a65726f20736c617368206f6620746865207461726765742e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f72732068617320616e206564676520746f20776869636820746865792068617665206e6f7420766f746564206f6e20636861696e2e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f7273206973206e6f7420616e20616374697665206e6f6d696e61746f72206f6e20636861696e2e204572726f72207768696c65206275696c64696e67207468652061737369676e6d656e7420747970652066726f6d2074686520636f6d706163742e20546869732063616e2068617070656e20696620616e20696e64657820697320696e76616c69642c206f72206966207468652077656967687473205f6f766572666c6f775f2e204f6e65206f6620746865207375626d69747465642077696e6e657273206973206e6f7420616e206163746976652063616e646964617465206f6e20636861696e2028696e646578206973206f7574206f662072616e676520696e20736e617073686f74292e20496e636f7272656374206e756d626572206f662077696e6e65727320776572652070726573656e7465642e2054686520736e617073686f742064617461206f66207468652063757272656e742077696e646f77206973206d697373696e672e20546865207375626d697474656420726573756c74206973206e6f7420617320676f6f6420617320746865206f6e652073746f726564206f6e20636861696e2e20546865207375626d697474656420726573756c74206973207265636569766564206f7574206f6620746865206f70656e2077696e646f772e205265776172647320666f72207468697320657261206861766520616c7265616479206265656e20636c61696d656420666f7220746869732076616c696461746f722e204974656d7320617265206e6f7420736f7274656420616e6420756e697175652e20496e76616c6964206e756d626572206f66206e6f6d696e6174696f6e732e20496e76616c69642065726120746f207265776172642e20417474656d7074696e6720746f2074617267657420612073746173682074686174207374696c6c206861732066756e64732e2043616e206e6f74207265626f6e6420776974686f757420756e6c6f636b696e67206368756e6b732e2043616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b732e2043616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e63652e20536c617368207265636f726420696e646578206f7574206f6620626f756e64732e204475706c696361746520696e6465782e20546172676574732063616e6e6f7420626520656d7074792e20436f6e74726f6c6c657220697320616c7265616479207061697265642e20537461736820697320616c726561647920626f6e6465642e204e6f742061207374617368206163636f756e742e204e6f74206120636f6e74726f6c6c6572206163636f756e742e416d6f756e744c6f774e6f7456657374696e6776657374766573745f6f746865727665737465645f7472616e7366657200000000000000848f10000e0000000000000064a51100020000000000000000000000948f1000020000000000000000000000a48f1000100000000000000044a51100010000000000000000000000b48f1000010000000000000056657374696e6755706461746564000007901000560000005d9010004600000056657374696e67436f6d706c65746564bc8f10004b00000020416e206163636f756e742028676976656e2920686173206265636f6d652066756c6c79207665737465642e204e6f20667572746865722076657374696e672063616e2068617070656e2e2054686520616d6f756e742076657374656420686173206265656e20757064617465642e205468697320636f756c6420696e646963617465206d6f72652066756e64732061726520617661696c61626c652e205468652062616c616e636520676976656e2069732074686520616d6f756e74207768696368206973206c65667420756e7665737465642028616e642074687573206c6f636b6564292e4475706c696361746564486561727462656174496e76616c69644b657968656172746265617448656172746265617441667465724b6579730000000000609110001100000000000000749110000100000000000000000000007c9110000100000000000000000000008491100007000000000000001cd411000000000000000000000000008c911000010000000000000000000000949110000b00000000000000a0911000010000000000000000000000a891100001000000000000004865617274626561745265636569766564000000799210000b0000004992100030000000416c6c476f6f64001492100035000000536f6d654f66666c696e6500fc91100018000000b09110004c0000002041742074686520656e64206f66207468652073657373696f6e2c206174206c65617374206f6e63652076616c696461746f722077617320666f756e6420746f206265206f66666c696e652e5665633c4964656e74696669636174696f6e5475706c653e2041742074686520656e64206f66207468652073657373696f6e2c206e6f206f6666656e63652077617320636f6d6d69747465642e2041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f72697479496460417574686f7269747949641600000004000000040000003b0000003c0000003d0000001600000000000000010000002a000000c090100009000000417574686f726564426c6f636b7300005b9310001600000023a11100020000005b931000160000007193100012000000696d6f6e6c696e6570616c6c65745f696d5f6f6e6c696e652f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f696d2d6f6e6c696e652f7372632f6c69622e7273536b697070696e6720686561727462656174206174202e204e6f7420612076616c696461746f722e00939410001c000000659410002e000000339410001a0000004d94100018000000179410000a0000002194100012000000ff93100018000000e993100016000000cc9310001d0000004661696c656420746f206665746368206e6574776f726b2073746174654661696c656420746f2061637175697265206c6f636b4661696c656420746f207369676e20686561727462656174417574686f726974792020697320616c7265616479206f6e6c696e6548656172746265617420616c72656164792073656e74206174202e2057616974696e6720666f7220696e636c7573696f6e2e546f6f206561726c7920746f2073656e64206865617274626561742c206e657874206578706563746564206174204661696c656420746f207375626d6974207472616e73616374696f6e00fc9210005f000000fa010000340000007061726974792f696d2d6f6e6c696e652d6865617274626561742f00fc941000080000000495100020000000249510000b0000002f951000030000005b696e6465783a205d205265706f7274696e6720696d2d6f6e6c696e6520617420626c6f636b3a20202873657373696f6e3a20293a2000001cd41100000000001cd41100000000001600000004000000040000003e0000001600000004000000040000003e0000003c7761736d3a73747269707065643e00000000000c8f100004000000000000001cd41100000000000000000000000000f89510000d0000000000000000000000108f10000a00000000000000acaf1100010000000000000000000000609610001000000000000000000000001a8f10000f00000000000000e0961000020000000000000000000000109710000e000000000000004e9a10002f0000001cd41100000000007d9a1000580000008c9910001a0000001cd4110000000000a6991000350000001cd41100000000005fb211000b000000869811000a000000f79910001e000000159a100039000000bab211000d000000c7b211000c000000089910002f0000001cd4110000000000b09a1100340000001cd411000000000037991000550000008c9910001a0000001cd4110000000000a6991000350000001cd41100000000005fb211000b000000869811000a000000db9910001c000000f79910001e000000159a100039000000bab211000d000000c7b211000c00000000000000d3b211000600000000000000d9b211002300000000000000d79810000800000000000000df98100029000000809710001a0000001cd4110000000000b09a1100340000001cd41100000000009a97100045000000df971000400000001f9810003d0000001cd41100000000005c981000180000001cd41100000000005fb211000b0000007498100046000000ba9810001d000000c7b211000c00000020437265617465206120766573746564207472616e736665722e202d2060746172676574603a20546865206163636f756e7420746861742073686f756c64206265207472616e7366657272656420746865207665737465642066756e64732e202d2060616d6f756e74603a2054686520616d6f756e74206f662066756e647320746f207472616e7366657220616e642077696c6c206265207665737465642e202d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e20456d697473206056657374696e6743726561746564602e202d20437265617465732061206e65772073746f7261676520656e7472792c206275742069732070726f7465637465642062792061206d696e696d756d207472616e7366657209202020616d6f756e74206e656564656420746f20737563636565642e7363686564756c6556657374696e67496e666f3c42616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265723e20556e6c6f636b20616e79207665737465642066756e6473206f662061206074617267657460206163636f756e742e202d2060746172676574603a20546865206163636f756e742077686f7365207665737465642066756e64732073686f756c6420626520756e6c6f636b65642e204d75737420686176652066756e6473207374696c6c206c6f636b656420756e6465722074686973206d6f64756c652e20456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e202d20557020746f206f6e65206163636f756e74206c6f6f6b75702e202d204f6e652062616c616e63652d6c6f636b206f7065726174696f6e2e202d204f6e652073746f7261676520726561642028636f64656320604f283129602920616e6420757020746f206f6e652072656d6f76616c2e20556e6c6f636b20616e79207665737465642066756e6473206f66207468652073656e646572206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e6473207374696c6c0000000000000096a610000700000001020000000000009db611000c00000000000000df98100029000000000000000000000000000000000000001cd41100709f10000000000000000000309b1000010000000000000000000000389b10003600000020496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e000000000000a89b10001100000000000000de4d11000c000000000000001cd41100bc9b10000000000000000000cc9b100001000000000000004d696e5665737465645472616e736665720000001600000000000000010000003f000000d49b10004700000020546865206d696e696d756d20616d6f756e7420746f206265207472616e7366657272656420746f206372656174652061206e65772076657374696e67207363686564756c652e506172656e7420686173682073686f756c642062652076616c69642e5472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642e00b39c100032000000446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e53746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e00000000000000c09010000900000000000000149d10000200000000000000000000001cd41100000000000000000000000000c09010000900000000000000449d100019000000000000005d9d10000a00000000000000679d10002f0000004865617274626561743c543a3a426c6f636b4e756d6265723e5f7369676e61747572653c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e6174757265000000000000c99010000e0000000000000000000000285f11000e000000000000000000000000000000000000000000000000000000000000001cd41100909f10000000000000000000f89e100006000000000000000100000000000000d7901000040000000000000000000000289f100013000000000000000000000000000000000000000000000000000000000000001cd411003c9f100000000000000000004c9f100001000000000000000100000000000000549f10001200000002050500000000007cff10000c00000000000000669f10000900000000000000aa39110007000000000000001cd41100709f10000000000000000000809f100002000000000000000000000000000000b49210000e00000002050500000000007cff10000c0000000000000004df10000e000000000000001456110003000000000000001cd41100909f10000000000000000000a09f1000020000000000000001000000b7a010004c0000001cd411000000000003a110004400000047a11000340000007ba1100040000000bba110004e0000005665633c543a3a417574686f7269747949643e001600000000000000010000003000000083a010003400000052656365697665644865617274626561747341757468496e646578001600000000000000010000003200000027a010003c00000063a01000200000001600000000000000010000002e000000b09f100045000000f59f10003200000020466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f662060543a3a56616c696461746f7249646020746f20746865206e756d626572206f6620626c6f636b7320617574686f7265642062792074686520676976656e20617574686f726974792e20466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206041757468496e6465786020746f20606f6666636861696e3a3a4f70617175654e6574776f726b5374617465602e205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e2054686520626c6f636b206e756d6265722061667465722077686963682069742773206f6b20746f2073656e64206865617274626561747320696e2063757272656e742073657373696f6e2e2041742074686520626567696e6e696e67206f6620656163682073657373696f6e20776520736574207468697320746f20612076616c756520746861742073686f756c642066616c6c20726f7567686c7920696e20746865206d6964646c65206f66207468652073657373696f6e206475726174696f6e2e20546865206964656120697320746f206669727374207761697420666f72207468652076616c696461746f727320746f2070726f64756365206120626c6f636b20696e207468652063757272656e742073657373696f6e2c20736f20746861742074686520686561727462656174206c61746572206f6e2077696c6c206e6f74206265206e65636573736172792e7573657220646f6573206e6f74206861766520616e206578697374696e672076657374696e67207363686564756c653b20712e652e642e160000000c000000040000004000000060a210005d000000fd0000000d0000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f76657374696e672f7372632f6c69622e727300000000000000028f10000a0000000000000014a310000100000000000000000000002f56110017000000000000001ca31000010000000000000000000000f98e1000090000000000000024a310000100000000000000c5a31000220000006ea31000570000002ca310004200000020416d6f756e74206265696e67207472616e7366657272656420697320746f6f206c6f7720746f2063726561746520612076657374696e67207363686564756c652e20416e206578697374696e672076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e7420746861742063616e6e6f7420626520636c6f6262657265642e20546865206163636f756e7420676976656e206973206e6f742076657374696e672e0000000000b69010000a0000000000000020a41000010000000000000000000000a3901000130000000000000028a41000010000000000000046a410001900000030a4100016000000204475706c696361746564206865617274626561742e204e6f6e206578697374656e74207075626c6963206b65792e00000000009ca41000070000000000000000000000a3a410000e0000000000000002000000010000000100000000000000b4a410000c0000000000000077657374656e647061726974792d77657374656e64000000df6acb689907609b0200000037e397fc7c91f5e40100000040fe3ad401f8959a04000000d2bc9897eed08f1502000000f78b278be53f454c02000000af2c0297a23e6d3d03000000ed99c5acb25eedf502000000cbca25e39f14238701000000687ad44ad37f03c201000000ab3c0572291feb8b01000000bc9d89904f5b923f0100000037c8bb1350a9a2a8010000006772616e62616265696d6f6e70617261617564690000000040787d010065cd1d00e1f505d85aae1ec0542205b0508f1f38e4750488467020d853e903603c5121d0bf760338323222a8591903402013236039cd02480ef423a82a8f0268f8d42470955c02b8dab525c05a3302d8c4962648bd1102e0b27727a855f601e8a05828e8fedf0180773929c0cacd01586d1a2af8f1be019053fb2a50d8b201d00edc2be0fca80138edbc2c48f2a001e06d9d2d80669a01c80d7e2e500f9501c0575e2f08b6900140323f30e0278d0148202031b0418a0108a3ff3120e8870120bedf32f0fb85013856c03398698401f0fda03478218301b8d87f35d8178201d8c26036183d8101b8223e37508d800188d21c38c8fc7f0168b5f93898877f01a829d139d8297f0120d6ab3ab8db7e0168ae803b389d7e0100ca9a3b68957e01496d4f6e6c696e654772616e6470615374616b696e6756657374696e67417574686f72697479446973636f76657279526573747269637446756e6374696f6e616c69747900000000642f11000600000000000000410000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000430000000000000000000000000000004400000000000000000000000000000045000000000000000000000000000000abb110001800000000000000460000000000000000000000000000000000000000000000000000000200000000000000000000000000000002000000000000000000000000000000000000004400000000000000000000000000000044000000000000000000000000000000a7591100040000000000000047000000000000000000000000000000000000000000000000000000000000004400000000000000000000000200000000000000000000000000000000000000480000000000000000000000000000004400000000000000000000000000000034ca1100090000000000000049000000000000000000000000000000000000000000000000000000000000004a000000000000000000000002000000000000000000000000000000000000004b00000000000000000000000000000044000000000000000000000000000000fb93110007000000000000004c000000000000000000000000000000000000000000000000000000000000004d0000000000000000000000000000004e0000000000000000000000000000004400000000000000000000000000000044000000000000000000000000000000bd56110008000000000000004f0000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000510000000000000000000000000000005200000000000000000000000000000053000000000000000000000000000000c54c110012000000000000005400000000000000000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000000000000000000000055000000000000000000000000000000440000000000000000000000000000007e9311000a000000000000005600000000000000000000000000000000000000000000000000000000000000570000000000000000000000020000000000000000000000000000000000000044000000000000000000000000000000580000000000000000000000000000008fa61000070000000000000059000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000005b0000000000000000000000000000005c0000000000000000000000000000005d0000000000000000000000000000008931110008000000000000005e00000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000005f000000000000000000000000000000440000000000000000000000000000004400000000000000000000000000000050b110000a00000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000002000000000000000000000000000000000000004400000000000000000000000000000044000000000000000000000000000000dbcb110007000000000000006000000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000006200000000000000000000000000000044000000000000000000000000000000630000000000000000000000000000007eb110000f0000000000000064000000000000000000000000000000000000000000000000000000000000006500000000000000000000000200000000000000000000000000000000000000660000000000000000000000000000006700000000000000000000000000000088a6100007000000000000006800000000000000000000000000000000000000000000000000000000000000690000000000000000000000000000006a000000000000000000000000000000440000000000000000000000000000006b00000000000000000000000000000080a6100008000000000000006c000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000006e000000000000000000000000000000440000000000000000000000000000006f0000000000000000000000000000009da610001200000002000000000000000000000000000000000000000000000000000000000000000000000044000000000000000000000002000000000000000000000000000000000000004400000000000000000000000000000044000000000000000000000000000000b0ef10000a0000000000000070000000000000000000000000000000000000000000000000000000000000007100000000000000000000000200000000000000000000000000000000000000440000000000000000000000000000007200000000000000000000000000000039ba10000c0000000000000073000000000000000000000000000000000000000000000000000000000000007400000000000000000000000200000000000000000000000000000000000000440000000000000000000000000000007500000000000000000000000000000096d6100009000000000000007600000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000007800000000000000000000000000000044000000000000000000000000000000790000000000000000000000000000009d7a110007000000000000007a000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000007c000000000000000000000000000000440000000000000000000000000000007d000000000000000000000000000000f4a3110008000000000000007e000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000800000000000000000000000000000004400000000000000000000000000000081000000000000000000000000000000ae1c1100080000000000000082000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000084000000000000000000000000000000440000000000000000000000000000008500000000000000000000000000000096a61000070000000000000086000000000000000000000000000000000000000000000000000000000000008700000000000000000000000000000088000000000000000000000000000000890000000000000000000000000000008a0000000000000000000000000000000dfc100009000000000000008b00000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000008c00000000000000000000000000000044000000000000000000000000000000440000000000000000000000000000008ccb100004000000000000008d000000000000000000000000000000000000000000000000000000000000008e0000000000000000000000000000008f00000000000000000000000000000044000000000000000000000000000000900000000000000000000000486973746f726963616c6d6f72655f6174746573746174696f6e73546f6f4d616e794174746573746174696f6e7346696e616c697479547261636b6572000000648a11006a000000910000000d000000526563656e7448696e747352616e646f6d6e657373436f6c6c656374697665466c697052616e646f6d4d6174657269616c42616448696e74416c72656164795570646174656466696e616c5f68696e742f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f72616e646f6d6e6573732d636f6c6c6563746976652d666c69702f7372632f6c69622e72731600000004000000040000009100000050726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b2071656400000000000000000000b8b210003d000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b2071656400000000000000000000000000000000000000000000006bb11000130000000000000024b3100001000000000000002cb3100035000000204d6f7265206174746573746174696f6e732063616e206265206164646564206f6e6c79206f6e636520696e206120626c6f636b2e5570646174654f72646572656448696e74734d656469616e616c77617973206174206c65617374206f6e6520726563656e742073616d706c653b207165640074b41000660000006e0000002b000000726563656e7420616e64206f72646572656420636f6e7461696e207468652073616d65206974656d733b2071656400001600000004000000040000000f00000074b4100066000000790000001b0000007072756e696e672064696374617465642062792077696e646f775f73697a6520776869636820697320616c776179732073617475726174656420617420313b207165640074b4100066000000940000001100000074b41000660000008e0000001900000074b41000660000008f000000190000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f66696e616c6974792d747261636b65722f7372632f6c69622e72730000000000047eb510000e0000008cb510000b00000036b510001300000064b510001a00000036b510001300000049b510001b000000617373657274696f6e206661696c65643a2062697473203c3d20726573756c742e6c656e28294361706163697479206f766572666c6f773a20206f766572666c6f777320616c6c6f636174696f6e2073697a6520206f766572666c6f7773206d6178696d756d206c656e67746820566563746f72206c656e67746820206f766572666c6f7773200000000000e6b110000a00000000000000c4b51000010000000000000000000000dcb5100002000000000000000000000044b61000040000000000000048b6100017000000ecb510003d00000029b610001b0000002048696e7420746861742074686520617574686f72206f66207468697320626c6f636b207468696e6b732074686520626573742066696e616c697a656420626c6f636b2069732074686520676976656e206e756d6265722e68696e74436f6d706163743c543a3a426c6f636b4e756d6265723e0000000000a0b110000b000000000000000000000018b8100013000000000000000000000000000000000000000000000000000000000000001cd4110034b8100000000000000000002cb810000100000000000000010000000000000067b310000c000000000000000000000018b8100013000000000000000000000000000000000000000000000000000000000000001cd4110034b81000000000000000000044b810000100000000000000010000000000000073b31000060000000000000000000000285f11000e000000000000000000000000000000000000000000000000000000000000001cd411004cb8100000000000000000005cb810000100000000000000010000000000000061b31000060000000000000000000000285f11000e000000000000000000000000000000000000000000000000000000000000001cd4110064b81000000000000000000074b8100001000000000000000000000000000000f45e11000b000000000000000000000031cf110004000000000000000000000000000000000000000000000000000000000000001cd4110034bc100000000000000000001cd411000000000000000000010000005665633c543a3a426c6f636b4e756d6265723e00dfb810000e00000016000000000000000100000030000000c9b81000160000001600000000000000010000002e000000bdb810000c000000160000000000000001000000320000007cb81000410000002046696e616c2068696e7420746f206170706c7920696e2074686520626c6f636b2e20604e6f6e6560206d65616e73202273616d6520617320706172656e74222e20546865206d656469616e2e204f72646572656420726563656e742068696e74732e20526563656e742068696e74732e0000000000000060b910000a00000000000000285f11000e000000000000001cd411006cb9100000000000000000007cb9100001000000000000000000000084b910000d00000000000000285f11000e000000000000001cd4110094b910000000000000000000a4b91000010000000000000057696e646f7753697a65000016000000000000000100000092000000f3b91000460000005265706f72744c6174656e637900000016000000000000000100000093000000acb9100047000000205468652064656c617920616674657220776869636820706f696e74207468696e6773206265636f6d6520737573706963696f75732e2044656661756c7420697320313030302e20546865206e756d626572206f6620726563656e742073616d706c657320746f206b6565702066726f6d207468697320636861696e2e2044656661756c74206973203130312e4174746573746174696f6e7350617261426c6f636b4174746573746174696f6e73526563656e7450617261426c6f636b730000000000005ab11000110000000000000098ba100001000000000000000000000094cc1000010000000000000000000000b0ba10000500000000000000b5ba1000100000005f6d6f72654d6f72654174746573746174696f6e73000000000000005aba1000100000000105000000000000285f11000e00000000000000d0bb100011000000000000000000000000000000000000001cd41100e4bb10000000000000000000f4bb10000200000000000000000000000000000045ba1000150000000205060000000000285f11000e0000000000000004bc1000040000000000000008bc100014000000000000001cd411001cbc100000000000000000002cbc10000100000000000000000000000000000028cf110009000000000000000000000031cf110004000000000000000000000000000000000000000000000000000000000000001cd4110034bc100000000000000000001cd41100000000000000000001000000496e636c75646564426c6f636b733c543e000000160000000000000001000000320000006ebc10003c000000aabc10003300000048617368426c6f636b4174746573746174696f6e733c543e1600000000000000010000003200000044bc10002a00000016000000000000000100000032000000204174746573746174696f6e73206f6e206120726563656e742070617261636861696e20626c6f636b2e2041206d617070696e672066726f6d206d6f64756c617220626c6f636b206e756d62657220286e2025204174746573746174696f6e506572696f642920746f2073657373696f6e20696e64657820616e6420746865206c697374206f662063616e646964617465206861736865732e00000000000000c3b110000e000000000000000000000038bd10000c000000000000000000000000000000000000000000000000000000000000001cd4110044bd1000000000000000000054bd10000300000000000000010000005665633c543a3a486173683e160000000000000001000000300000006cbd100058000000c4bd1000580000001cbe10001100000020536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e672062756666657220776974682060626c6f636b5f6e756d626572202520383160206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e0000001cd411000000000023a111000200000000000000d8b110000e0000000000000078be1000010000000000000000000000d1b11000070000000000000080be10000100000000000000acbe10003200000088be1000240000002046696e616c697a6564206865696768742061626f766520626c6f636b206e756d6265722046696e616c2068696e74206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b0000f0b110007000000053000000110000006e6577686561647350617261636861696e20686561647320636f756c64206e6f74206265206465636f6465642e00000026fb10004200000037040000140000004e6f2070617261636861696e20686561647320666f756e6420696e20696e686572656e7420646174612e7265706f72745f646f75626c655f766f74657365745f6865616473546f6f4d616e794865616455706461746573546f6f4d616e795061726143616e6469646174657348656164734f75744f664f72646572556e7265676973746572656450617261496e76616c6964436f6c6c61746f72517565756546756c6c496e76616c69644d6573736167654f726967696e4e6f56616c696461746f7247726f75704e6f74456e6f75676856616c6964697479566f746573566f74657345786365656473417574686f72697469657357726f6e6756616c696461746f72417474657374696e67496e76616c69645369676e6174757265556e746167676564566f746573506172656e744d69736d6174636843616e6e6f7450617946656573556e657870656374656452656c6179506172656e7456616c6964617465446f75626c65566f74655265706f727473526571756972655375646f7375646f7365745f6b65797375646f5f617300000000000044c1100005000000000000004cc1100001000000000000000000000054c110000100000000000000000000005cc110000a0000000000000044a5110001000000000000000000000068c1100001000000000000000000000070c110000a000000000000004cc1100001000000000000000000000054c110000100000000000000537564696400000031cf110004000000b6c11000180000004b65794368616e67656400007ac110003c0000005375646f4173446f6e6520546865207375646f6572206a757374207377697463686564206964656e746974793b20746865206f6c64206b657920697320737570706c6965642e2041207375646f206a75737420746f6f6b20706c6163652e50617261636861696e206865616473206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b0016000000080000000400000094000000496e76616c69642f6f75746461746564206b6579206f776e6572736869702070726f6f662e4661696c656420746f207265706f7274206f6666656e636500000026fb100042000000e90300002f0000006f7264657265645f6e656564735f646973706174636820636f6e7461696e732069643f2126fb100042000000d20200001d00000076616c696461746f725f726f6c655f706169727326fb100042000000090300002f0000000000000075bf1000120000000000000094c4100001000000000000000000000087bf100015000000000000009cc410000100000000000000000000009cbf10000f00000000000000a4c41000010000000000000000000000abbf10001000000000000000acc41000010000000000000000000000bbbf10000f00000000000000b4c41000010000000000000000000000cabf10000900000000000000bcc41000010000000000000000000000d3bf10001400000000000000c4c41000010000000000000000000000e7bf10001000000000000000ccc41000010000000000000000000000f7bf10001600000000000000d4c410000100000000000000000000000dc010001700000000000000dcc4100001000000000000000000000024c010001700000000000000e4c410000100000000000000000000003bc010001000000000000000ecc410000100000000000000000000004bc010000d00000000000000f4c4100001000000000000000000000058c010000e00000000000000fcc410000100000000000000000000009fd51000100000000000000004c5100001000000000000000000000066c010000d000000000000000cc5100001000000000000000000000073c01000150000000000000014c510000100000000000000e2c7100038000000c3c710001f00000079c710004a0000004dc710002c0000003bc7100012000000f4c6100047000000d5c610001f000000b3c61000220000008ac61000290000004cc610003e00000013c6100039000000f2c5100021000000bec510003400000095c51000290000007cc51000190000004dc510002f0000001cc510003100000020556e65787065637465642072656c61792d706172656e7420666f7220612063616e64696461746520726563656970742e205061726120646f6573206e6f74206861766520656e6f7567682062616c616e636520746f2070617920666565732e204865616420646174612077617320746f6f206c617267652e2057726f6e6720706172656e74206865616420666f722070617261636861696e20726563656970742e20457874726120756e7461676765642076616c696469747920766f74657320616c6f6e6720776974682063616e6469646174652e20496e76616c6964207369676e61747572652066726f6d2061747465737465722e20417474657374696e672076616c696461746f72206e6f74206f6e207468697320636861696e27732076616c69646174696f6e20647574792e20546865206e756d626572206f66206174746573746174696f6e73206578636565647320746865206e756d626572206f6620617574686f7269746965732e204e6f7420656e6f7567682076616c696469747920766f74657320666f722063616e6469646174652e204e6f2076616c696461746f722067726f757020666f722070617261636861696e2e20546865206d657373616765206f726967696e20697320696e76616c69642e20546865206d6573736167652071756575652069732066756c6c2e204d657373616765732077696c6c206265206164646564207768656e2074686572652069732073706163652e20496e76616c696420636f6c6c61746f722e2043616e64696461746520697320666f7220616e20756e726567697374657265642070617261636861696e2e2050726f706f736564206865616473206d75737420626520617363656e64696e67206f726465722062792070617261636861696e20494420776974686f7574206475706c69636174652e20546f6f206d616e792070617261636861696e2063616e646964617465732e2050617261636861696e206865616473206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b2e000026fb100042000000990400003500000000000000acc010000400000000000000b0c81000010000000000000000000000c8c810000a0000000000000000000000b0c01000070000000000000018c9100001000000000000000000000030c91000090000000000000000000000b7c01000070000000000000078c91000020000000000000000000000a8c910000b0000000000000000000000c97711000400000000000000cd771100170000003ecb10004e0000001cd4110000000000b09a1100340000001cd41100000000005fb211000b00000065ca1000080000006dca10001900000086ca1000180000009eca100032000000c7b211000c000000000000009ab611000300000000000000d9b2110023000000d0ca10005d0000001cd4110000000000b09a1100340000001cd41100000000005fb211000b00000065ca1000080000006dca1000190000002dcb100011000000c7b211000c000000000000004c8111000300000000000000d9b211002300000000000000c97711000400000000000000cd7711001700000000ca10005400000054ca1000110000001cd4110000000000b09a1100340000001cd41100000000005fb211000b00000065ca1000080000006dca10001900000086ca1000180000009eca100032000000c7b211000c0000002041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c207769746820605369676e656460206f726967696e2066726f6d206120676976656e206163636f756e742e202d204f2831292e202d204c696d697465642073746f726167652072656164732e202d204f6e6520444220777269746520286576656e74292e202d20576569676874206f662064657269766174697665206063616c6c6020657865637574696f6e202b2031302c3030302e2041757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f206b65792e202d204f6e65204442206368616e67652e2041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e5375646f00000000903811000300000000000000000000009db611000c000000000000000000000000000000000000000000000000000000000000001cd41100e8cb10000000000000000000f8cb10000100000000000000010000001600000000000000010000009500000000cc1000210000002054686520604163636f756e74496460206f6620746865207375646f206b65792e000000000000006cbf100009000000000000007ccc100001000000000000000000000094cc10000100000000000000000000005abf100012000000000000009ccc1000010000000000000000000000b4cc100004000000000000000000000028ce100005000000000000002dce100016000000e3cd100045000000000000006acd1000060000000000000070cd100073000000d4cc1000400000001cd411000000000014cd1000460000005acd1000100000002050726f7669646520612070726f6f66207468617420736f6d652076616c696461746f722068617320636f6d6d69746564206120646f75626c652d766f74652e205468652077656967687420697320303b20696e206f7264657220746f2061766f696420446f53206120605369676e6564457874656e73696f6e602076616c69646174696f6e20697320696d706c656d656e7465642e7265706f7274446f75626c65566f74655265706f72743c3c543a3a4b65794f776e657250726f6f6653797374656d2061730a20202020202020202020202020202020204b65794f776e657250726f6f6653797374656d3c284b65795479706549642c2056616c696461746f724964293e3e3a3a50726f6f663e2050726f766964652063616e64696461746520726563656970747320666f722070617261636861696e732c20696e20617363656e64696e67206f726465722062792069642e68656164735665633c417474657374656443616e6469646174653e00000000003c5d11000b0000000000000000000000acd0100010000000000000000000000000000000000000000000000000000000000000001cd411008cd110000000000000000000bcd0100001000000000000000100000000000000c4d01000040000000105000000000000baf010000600000000000000aa39110007000000000000000000000000000000000000001cd41100d8d010000000000000000000c8d0100001000000000000000000000000000000d0d01000050000000105000000000000baf010000600000000000000aa39110007000000000000000000000000000000000000001cd41100d8d010000000000000000000e8d0100001000000000000000000000000000000f0d01000120000000105000000000000baf01000060000000000000002d1100012000000000000000000000000000000000000001cd4110014d11000000000000000000024d110000200000000000000010000000000000034d11000160000000105000000000000baf0100006000000000000004ad110000a000000000000000000000000000000000000001cd4110054d11000000000000000000064d11000030000000000000001000000000000007cd110000d0000000000000000000000baef10000b000000000000000000000000000000000000000000000000000000000000001cd411008cd1100000000000000000009cd110000100000000000000010000000000000028cf1100090000000000000000000000baef10000b000000000000000000000000000000000000000000000000000000000000001cd41100a4d110000000000000000000b4d110000400000000000000000000005665633c56616c696461746f7249643e93d4100025000000436f64656dd41000260000004865616473000000160000000000000001000000960000003ad410003300000052656c6179446973706174636851756575655665633c5570776172644d6573736167653e16000000000000000100000030000000c1d310004700000008d410003200000052656c61794469737061746368517565756553697a65287533322c207533322916000000000000000100000097000000dbd21000510000002cd310005600000082d310003f0000004e6565647344697370617463680000001600000000000000010000003000000097d210004400000016000000000000000100000032000000d4d11000560000002ad21000520000001cd41100000000007cd210001b0000002060536f6d6560206966207468652070617261636861696e20686561647320676574207570646174656420696e207468697320626c6f636b2c20616c6f6e672077697468207468652070617261636861696e20494473207468617420646964207570646174652e204f72646572656420696e207468652073616d652077617920617320607265676973747261723a3a416374697665602028692e652e20627920506172614964292e20604e6f6e6560206966206e6f742079657420757064617465642e20546865206f726465726564206c697374206f662050617261496473207468617420686176652061206052656c6179446973706174636851756575656020656e7472792e2053697a65206f6620746865206469737061746368207175657565732e205365706172617465642066726f6d2061637475616c206461746120696e206f7264657220746f2061766f696420636f73746c79206465636f64696e67207768656e20636865636b696e6720726563656970742076616c69646974792e204669727374206974656d20696e207475706c652069732074686520636f756e74206f66206d65737361676573207365636f6e642069662074686520746f74616c206c656e6774682028696e20627974657329206f6620746865206d657373616765207061796c6f6164732e204d6573736167657320726561647920746f2062652064697370617463686564206f6e746f207468652072656c617920636861696e2e204974206973207375626a65637420746f20604d41585f4d4553534147455f434f554e546020616e64206057415445524d41524b5f4d4553534147455f53495a45602e20546865206865616473206f66207468652070617261636861696e7320726567697374657265642061742070726573656e742e205468652070617261636861696e7320726567697374657265642061742070726573656e742e20416c6c20617574686f72697469657327206b65797320617420746865206d6f6d656e742e00000000a1c010000b00000000000000d4d410000100000000000000dcd41000200000002053656e646572206d75737420626520746865205375646f206163636f756e7473776170646572656769737465725f7061726174687265616473656c6563745f7061726174687265616472656769737465725f706172617468726561647365745f7468726561645f636f756e74646572656769737465725f7061726172656769737465725f7061726150617261416c7265616479457869737473496e76616c6964436861696e4964496e76616c69645468726561644964436f6465546f6f4c617267654865616444617461546f6f4c617267654c696d697450617261746872656164436f6d6d697473000000d0d5100023000000605f5f49676e6f7265602063616e206e6576657220626520636f6e73747275637465644e6f4b6579734475706c6963617465644b65794e6f4173736f63696174656456616c696461746f724964496e76616c696450726f6f667365745f6b65797370757267655f6b65797356616c696461746f72734e6578744b6579734b65794f776e65722f686f6d652f6461766964642f6465762f706f6c6b61646f742d77657374656e642f72756e74696d652f636f6d6d6f6e2f7372632f7265676973747261722e7273526567697374726172446562746f727300000000000065d51000110000000000000034d7100001000000000000000000000076d510000e000000000000003cd7100001000000000000000000000084d510000f0000000000000044d7100001000000000000000000000093d510000c000000000000004cd710000100000000000000000000009fd51000100000000000000054d710000100000000000000bed710001a000000a8d710001600000091d710001700000079d71000180000005cd710001d00000020496e76616c69642070617261206865616420646174612073697a652e20496e76616c6964207061726120636f64652073697a652e20496e76616c696420706172617468726561642049442e20496e76616c69642070617261636861696e2049442e2050617261636861696e20616c7265616479206578697374732e55d6100041000000640200002d00000055d610004100000002020000110000005175657565644b65797300000000000029d6100008000000000000005cd810000200000000000000000000008cd810000c000000000000000000000031d610000a000000000000001cd41100000000000000000000000000ecd810000a0000000000000000000000b13811000400000000000000a9db10000700000000000000b0db10000500000000000000aa3911000700000041da10003a0000007bda1000480000006fd91000310000001cd4110000000000a0d91000350000001cd41100000000005fb211000b000000c3da100022000000e5da100016000000fbda10005900000054db100055000000c7b211000c0000003cd91000330000006fd91000310000001cd4110000000000a0d91000350000001cd41100000000005fb211000b000000d5d910001f000000f4d910001c00000010da100031000000c7b211000c0000002052656d6f76657320616e792073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c65722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d204f284e2920696e206e756d626572206f66206b65792074797065732e202d2052656d6f766573204e202b203120444220656e74726965732e202d20526564756365732073797374656d206163636f756e742072656673206279206f6e65206f6e20737563636573732e2053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b657973602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e202d204f286c6f67206e2920696e206e756d626572206f66206163636f756e74732e202d204f6e6520657874726120444220656e7472792e202d20496e637265617365732073797374656d206163636f756e742072656673206279206f6e65206f6e20737563636573732069666620746865726520776572652070726576696f75736c79206e6f206b657973207365742e202020496e207468697320636173652c2070757267655f6b6579732077696c6c206e65656420746f2062652063616c6c6564206265666f726520746865206163636f756e742063616e2062652072656d6f7665642e543a3a4b65797370726f6f66000000000000003bd610000a000000000000000000000020de100013000000000000000000000000000000000000000000000000000000000000001cd41100c8ef1000000000000000000034de1000010000000000000001000000000000003cde10000c00000000000000000000007cff10000c000000000000000000000000000000000000000000000000000000000000001cd41100e4ef1000000000000000000048de10000100000000000000010000000000000050de10000d000000000000000000000031cf110004000000000000000000000000000000000000000000000000000000000000001cd4110060de1000000000000000000070de100002000000000000000100000000000000f8d710000a000000000000000000000080de10001e000000000000000000000000000000000000000000000000000000000000001cd41100a0de10000000000000000000b0de100002000000000000000100000000000000c0de1000120000000000000000000000d2de100008000000000000000000000000000000000000000000000000000000000000001cd41100dcde10000000000000000000ecde10000300000000000000010000000000000045d6100008000000010500000000000004df10000e00000000000000a9db100007000000000000000000000000000000000000001cd4110014df1000000000000000000024df1000010000000000000000000000000000004dd610000800000001050000000000002cdf1000140000000000000004df10000e000000000000000000000000000000000000001cd41100ecf01000000000000000000040df10000100000000000000000000005665633c543a3a56616c696461746f7249643e003ae110001f00000043757272656e74496e6465781ce110001e0000005175657565644368616e67656400000016000000000000000100000032000000a5e010004e000000f3e01000290000005665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e0000160000000000000001000000300000001ee010004f0000006de010003800000044697361626c656456616c696461746f72735665633c7533323e000016000000000000000100000030000000b1df1000200000001cd4110000000000d1df10004d000000543a3a56616c696461746f7249640000160000000000000001000000320000008adf100027000000284b65795479706549642c205665633c75383e2948df10004200000020546865206f776e6572206f662061206b65792e20546865206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e20496e6469636573206f662064697361626c65642076616c696461746f72732e205468652073657420697320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e732061206e657720736574206f66206964656e7469746965732e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f727320686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e0000000000000058d510000d0000000000000090e21000040000000000000000000000f0e2100005000000000000000000000049d510000f0000000000000018e3100001000000000000000000000030e3100001000000000000000000000039d51000100000000000000038e3100001000000000000000000000050e3100005000000000000000000000026d51000130000000000000078e31000020000000000000000000000a8e3100008000000000000000000000015d510001100000000000000e8e3100003000000000000000000000030e4100005000000000000000000000000d5100015000000000000001cd4110000000000000000000000000058e41000070000000000000000000000fcd41000040000000000000090e41000010000000000000000000000a8e41000080000000000000000000000bbeb100002000000000000001ae710000f00000000000000d2be110004000000000000008eec10000800000000000000a63911000400000000000000aa3911000700000000000000e9ea10001100000000000000aa39110007000000bdeb10003e000000fbeb1000230000001cd41100000000001eec10003d0000005bec10003300000000000000bbeb100002000000000000001ae710000f00000096eb1000250000000000000091eb100005000000000000001456110003000000faea1000500000001cd41100000000004aeb1000260000001cd411000000000070eb10002100000000000000a63911000400000000000000aa3911000700000000000000e9ea10001100000000000000aa3911000700000081e91000290000001cd4110000000000aae9100053000000fde910004e0000001cd41100000000004bea10004c00000097ea10004a000000e1ea1000080000000000000061e9100003000000000000001ae710000f0000000000000064e9100009000000000000006de910000a0000000000000077e910000a00000000000000344011000700000064e81000410000001cd4110000000000a5e8100050000000f5e81000570000004ce910001500000029e71000320000001cd41100000000005be71000480000001cd4110000000000a3e7100056000000f9e71000510000004ae810001a0000000000000015e7100005000000000000001ae710000f000000e8e410005900000041e51000590000009ae51000570000001cd4110000000000f1e510005800000049e610005000000099e6100056000000efe6100026000000205377617020612070617261636861696e207769746820616e6f746865722070617261636861696e206f7220706172617468726561642e20546865206f726967696e206d7573742062652061206050617261636861696e602e2054686520737761702077696c6c2068617070656e206f6e6c7920696620746865726520697320616c726561647920616e206f70706f7369746520737761702070656e64696e672e204966207468657265206973206e6f742c2074686520737761702077696c6c2062652073746f72656420696e207468652070656e64696e67207377617073206d61702c20726561647920666f722061206c6174657220636f6e6669726d61746f727920737761702e20546865206050617261496460732072656d61696e206d617070656420746f207468652073616d652068656164206461746120616e6420636f646520736f2065787465726e616c20636f64652063616e2072656c79206f6e20605061726149646020746f2062652061206c6f6e672d7465726d206964656e746966696572206f662061206e6f74696f6e616c202270617261636861696e222e20486f77657665722c207468656972207363686564756c696e6720696e666f2028692e652e2077686574686572207468657927726520612070617261746872656164206f722070617261636861696e292c2061756374696f6e20696e666f726d6174696f6e20616e64207468652061756374696f6e206465706f736974206172652073776974636865642e6f74686572436f6d706163743c5061726149643e20446572656769737465722061207061726174687265616420616e6420726574726965766520746865206465706f7369742e204d7573742062652073656e742066726f6d2061206050617261636861696e60206f726967696e2077686963682069732063757272656e746c79206120706172617468726561642e20456e737572652074686174206265666f72652063616c6c696e672074686973207468617420616e792066756e647320796f752077616e7420656d70746965642066726f6d2074686520706172617468726561642773206163636f756e74206973206d6f766564206f75743b20616674657220746869732069742077696c6c20626520696d706f737369626c6520746f207265747269657665207468656d2028776974686f757420676f7665726e616e636520696e74657276656e74696f6e292e20506c61636520612062696420666f722061207061726174687265616420746f2062652070726f6772657373656420696e20746865206e65787420626c6f636b2e20546869732069732061206b696e64206f66207370656369616c207472616e73616374696f6e20746861742073686f756c642062652068656176696c79207072696f726974697a656420696e20746865207472616e73616374696f6e20706f6f6c206163636f7264696e6720746f20746865206076616c7565603b206f6e6c792060546872656164436f756e7460206f66207468656d206d61792062652070726573656e74656420696e20616e792073696e676c6520626c6f636b2e5f69645f636f6c6c61746f72436f6c6c61746f7249645f686561645f686173682052656769737465722061207061726174687265616420666f7220696d6d656469617465207573652e204d7573742062652073656e742066726f6d2061205369676e6564206f726967696e20746861742069732061626c6520746f206861766520506172617468726561644465706f7369742072657365727665642e2060636f64656020616e642060696e697469616c5f686561645f646174616020617265207573656420746f20696e697469616c697a6520746865207061726174687265616427732073746174652e20556e6c696b65206072656769737465725f70617261602c20746869732066756e6374696f6e20646f657320636865636b207468617420746865206d6178696d756d20636f64652073697a6520616e64206865616420646174612073697a6520617265207265737065637465642c206173207061726174687265616420726567697374726174696f6e20697320616e2061746f6d696320616374696f6e2e696e697469616c5f686561645f6461746120526573657420746865206e756d626572206f6620706172617468726561647320746861742063616e2070617920746f206265207363686564756c656420696e20612073696e676c6520626c6f636b2e202d2060636f756e74603a20546865206e756d626572206f662070617261746872656164732e204d7573742062652063616c6c65642066726f6d20526f6f74206f726967696e2e636f756e74204465726567697374657220612070617261636861696e207769746820676976656e206964696420526567697374657220612070617261636861696e207769746820676976656e20636f64652e204d7573742062652063616c6c656420627920726f6f742e204661696c7320696620676976656e20494420697320616c726561647920757365642e20556e6c696b65207468652060526567697374726172602074726169742066756e6374696f6e206f66207468652073616d65206e616d652c207468697320636865636b732074686520636f646520616e642068656164206461746120616761696e73742073697a65206c696d6974732e50617261496e666f000000000000b0ef10000a0000000000000000000000baef10000b000000000000000000000000000000000000000000000000000000000000001cd41100c8ef100000000000000000001cd4110000000000000000000100000000000000d8ef10000b00000000000000000000001456110003000000000000000000000000000000000000000000000000000000000000001cd41100e4ef10000000000000000000f4ef100001000000000000000100000000000000fcef10000f00000000000000000000000bf010001e000000000000000000000000000000000000000000000000000000000000001cd4110030f1100000000000000000002cf01000020000000000000001000000000000003cf0100006000000000000000000000042f010002e000000000000000000000000000000000000000000000000000000000000001cd4110070f01000000000000000000080f0100006000000000000000100000000000000b0f010000a0000000000000000000000baf0100006000000000000000000000000000000000000000000000000000000000000001cd41100c0f010000000000000000000d0f0100002000000000000000100000000000000e0f010000b0000000105000000000000baf010000600000000000000baf0100006000000000000000000000000000000000000001cd41100ecf010000000000000000000fcf010000100000000000000000000000000000004f11000050000000105000000000000baf0100006000000000000008eec100008000000000000000000000000000000000000001cd411000cf1100000000000000000001cf110000100000000000000000000000000000024f110000a00000000000000000000000bf010001e000000000000000000000000000000000000000000000000000000000000001cd4110030f11000000000000000000040f11000010000000000000001000000000000009fd61000070000000105000000000000baf0100006000000000000009db611000c000000000000000000000000000000000000001cd4110048f11000000000000000000058f1100001000000000000000100000050617261636861696e735665633c5061726149643e00000016000000000000000100000030000000546872656164436f756e74001600000000000000010000002e00000058f410002d00000053656c6563746564546872656164735665633c5665633c285061726149642c20436f6c6c61746f724964293e3e000000b8f31000540000000cf410004c0000004163746976655665633c285061726149642c204f7074696f6e3c28436f6c6c61746f7249642c20526574726961626c65293e293e160000000000000001000000300000006cf2100057000000c3f21000580000001bf310005600000071f31000340000001cd4110000000000a5f31000130000004e6578744672656549645061726149641600000000000000010000009300000008f210004f00000057f210001500000050656e64696e67537761700016000000000000000100000032000000eff1100019000000506172617300000016000000000000000100000032000000c5f110002a000000526574727951756575650000160000000000000001000000300000008bf110003a0000001600000000000000010000009500000060f110002b0000002055736572732077686f20686176652070616964206120706172617468726561642773206465706f736974205468652063757272656e7420717565756520666f7220706172617468726561647320746861742073686f756c6420626520726574726965642e204d6170206f6620616c6c20726567697374657265642070617261746872656164732f636861696e732e2050656e64696e672073776170206f7065726174696f6e732e20546865206e65787420756e75736564205061726149642076616c75652e2053746172742074686973206869676820696e206f7264657220746f206b656570206c6f77206e756d6265727320666f722073797374656d2d6c6576656c20636861696e732e2050617261746872656164732f636861696e73207363686564756c656420666f7220657865637574696f6e207468697320626c6f636b2e2049662074686520636f6c6c61746f72204944206973207365742c207468656e206120706172746963756c617220636f6c6c61746f722068617320616c7265616479206265656e2063686f73656e20666f7220746865206e65787420626c6f636b2c20616e64206e6f206f7468657220636f6c6c61746f72206d61792070726f766964652074686520626c6f636b2e20496e2074686973206361736520776520616c6c6f772074686520706f73736962696c697479206f662074686520636f6d62696e6174696f6e206265696e67207265747269656420696e2061206c6174657220626c6f636b2c206578707265737365642062792060526574726961626c65602e204f726465726564206279205061726149642e20416e206172726179206f6620746865207175657565206f6620736574206f662074687265616473207363686564756c656420666f722074686520636f6d696e6720626c6f636b733b206f72646572656420627920617363656e64696e6720706172612049442e2054686572652063616e206265206e6f206475706c696361746573206f66207061726120494420696e2065616368206c697374206974656d2e20546865206e756d626572206f66207468726561647320746f207363686564756c652070657220626c6f636b2e000000000000001dd610000c00000000000000f8f4100001000000000000000000000006d61000170000000000000000f51000010000000000000000000000f9d510000d0000000000000008f51000010000000000000000000000f3d51000060000000000000010f51000010000000000000084f51000190000005cf510002800000042f510001a00000018f510002a000000204e6f206b65797320617265206173736f63696174656420776974682074686973206163636f756e742e2052656769737465726564206475706c6963617465206b65792e204e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e20496e76616c6964206f776e6572736869702070726f6f662e4469676573744974656d206e6f7420657175616c546f6f536f6f6e4368616e676550656e64696e67526573756d654661696c656450617573654661696c65647265706f72745f6d69736265686176696f723a6772616e6470615f617574686f726974696573666f726b2e726563656e746c792065786563757465642e416c726561647950726f78795374696c6c4163746976655468726573686f6c64416c7265616479566f756368656444656c6179506572696f644e6f74467269656e644e6f7453746172746564416c726561647953746172746564416c72656164795265636f76657261626c654e6f745265636f76657261626c654e6f74536f727465644d6178467269656e64734e6f74456e6f756768467269656e64734e6f74416c6c6f77656461735f7265636f76657265647365745f7265636f76657265646372656174655f7265636f76657279696e6974696174655f7265636f76657279766f7563685f7265636f76657279636c61696d5f7265636f76657279636c6f73655f7265636f7665727972656d6f76655f7265636f7665727963616e63656c5f7265636f76657265640000000000004cf810000f0000000000000044a511000100000000000000000000005cf8100001000000000000000000000064f810001100000000000000e452110002000000000000000000000078f8100001000000000000000000000080f810000f0000000000000090f81000030000000000000000000000a8f81000010000000000000000000000b0f810000e00000000000000e4521100020000000000000000000000c0f81000010000000000000000000000c8f810001000000000000000e4521100020000000000000000000000d8f81000010000000000000000000000e0f810000f0000000000000044a51100010000000000000000000000f0f8100001000000000000005265636f76657279437265617465640031fa1000320000005265636f76657279496e69746961746564000000f0f91000410000005265636f76657279566f7563686564009aa61100090000009aa61100090000009aa6110009000000a0f91000500000005265636f76657279436c6f736564000062f910003e0000004163636f756e745265636f76657265642bf91000370000005265636f7665727952656d6f76656400f8f81000330000002041207265636f766572792070726f6365737320686173206265656e2072656d6f76656420666f7220616e206163636f756e74204163636f756e745f3120686173206265656e207375636365737366756c6c79207265636f7665726564206279206163636f756e745f322041207265636f766572792070726f6365737320666f72206163636f756e745f31206279206163636f756e745f3220686173206265656e20636c6f7365642041207265636f766572792070726f6365737320666f72206163636f756e745f31206279206163636f756e745f3220686173206265656e20766f756368656420666f72206279206163636f756e745f332041207265636f766572792070726f6365737320686173206265656e20696e6974696174656420666f72206163636f756e745f31206279206163636f756e745f322041207265636f766572792070726f6365737320686173206265656e2073657420757020666f7220616e206163636f756e740000000000bcfa10000900000000000000c8fa10000100000000000000000000001cd41100000000000000000000000000d0fa10000a00000000000000dcfa10000300000000000000000000001cd4110000000000000000005363686564756c65640000001bfb10000b000000446973706174636865640000f4fa1000180000000cfb10000f000000a25411000e0000005461736b416464726573733c426c6f636b4e756d6265723e4f7074696f6e3c5665633c75383e3e426c6f636b4e756d6265722f686f6d652f6461766964642f6465762f706f6c6b61646f742d77657374656e642f72756e74696d652f636f6d6d6f6e2f7372632f70617261636861696e732e727326fb100042000000e70200002200000088fb10006400000033000000120000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f7072696d6974697665732f72756e74696d652f7372632f63757276652e72734772616e64706146696e616c69747950656e64696e674368616e676553746174655363686564756c65724167656e646100000000dcf51000120000000000000048fc100001000000000000000000000060fc100001000000000000000000000081fc10000700000000000000aa3911000700000068fc100019000000205265706f727420736f6d65206d69736265686176696f722e5f7265706f72740000000008fc100005000000000000000000000098fe10001b000000000000000000000000000000000000000000000000000000000000001cd41100b4fe10000000000000000000c4fe100001000000000000000100000000000000fbfb10000d0000000000000000000000ccfe100023000000000000000000000000000000000000000000000000000000000000001cd41100a41e11000000000000000000f0fe100001000000000000000000000000000000f8fe10000a0000000000000000000000285f11000e000000000000000000000000000000000000000000000000000000000000001cd4110088ff1000000000000000000004ff1000010000000000000000000000000000000cff100007000000000000000000000013ff100020000000000000000000000000000000000000000000000000000000000000001cd411003c221100000000000000000034ff1000010000000000000000000000000000003cff10000c000000000000000000000048ff100005000000000000000000000000000000000000000000000000000000000000001cd4110050ff1000000000000000000060ff10000200000000000000010000000000000070ff10000c000000010500000000000048ff100005000000000000007cff10000c000000000000000000000000000000000000001cd4110088ff1000000000000000000098ff100002000000000000000000000053746f72656453746174653c543a3a426c6f636b4e756d6265723e0016000000000000000100000098000000240111002400000053746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723e00f3001100310000004e657874466f726365640000c40011002f0000005374616c6c656428543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d6265722900a00011002400000043757272656e74536574496453657449640000001600000000000000010000009900000018001100570000006f00110031000000536574496453657373696f6e53657373696f6e496e64657816000000000000000100000032000000a8ff100056000000feff10001a0000002041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f7220776869636820697473206d656d62657273207765726520726573706f6e7369626c652e20546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c69746965732920696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e20607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e00000000c0f610000c00000000000000d4021100020000000000000000000000040311000d0000000000000000000000ccf610000d000000000000006c0311000200000000000000000000009c0311000d0000000000000000000000d9f610000f00000000000000040411000300000000000000000000004c0411001b0000000000000000000000e8f6100011000000000000005ca9110001000000000000000000000024051100160000000000000000000000f9f610000e000000000000006c031100020000000000000000000000d405110019000000000000000000000007f710000e000000000000005ca911000100000000000000000000009c06110014000000000000000000000015f710000e000000000000003c0711000100000000000000000000005407110014000000000000000000000023f710000f000000000000001cd41100000000000000000000000000f407110015000000000000000000000032f7100010000000000000005ca911000100000000000000000000009c0811000b0000000000000000000000f9bf110007000000000000009db611000c00000000000000c97711000400000000000000cd77110017000000ba1b1100290000001cd41100000000002c09110045000000710911003a0000001cd4110000000000ab0911000c000000e31b1100490000002c1c1100400000001cd41100000000005fb211000b0000001c781100250000006c1c110042000000c7b211000c00000000000000b61b110004000000000000009db611000c00000000000000570f110007000000000000009db611000c000000861a110047000000cd1a11001d0000001cd4110000000000ea1a1100320000001cd4110000000000ab0911000c0000001c1b11002e0000004a1b1100470000001cd41100000000005fb211000b000000911b110019000000aa1b11000c000000c7b211000c00000000000000731a110007000000000000007671110011000000000000005971110009000000000000006271110003000000000000007a1a11000c00000000000000285f11000e000000c9161100570000001cd4110000000000201711004c0000006c17110052000000be1711002f0000001cd4110000000000b09a1100340000001cd4110000000000ab0911000c000000ed1711004900000036181100350000006b1811004c000000b718110047000000fe18110025000000231911004f000000721911003a0000001cd41100000000005fb211000b000000ac1911001a000000c61911004b000000111a11003b00000087161100270000004c1a110027000000bab211000d0000001cd41100000000001c0d11001b000000c7b211000c000000771411003b0000001cd4110000000000b214110047000000f914110049000000421511002e0000001cd4110000000000b09a1100340000001cd4110000000000ab0911000c0000007015110045000000b5151100400000001cd41100000000005fb211000b000000f51511003e00000033161100540000008716110027000000a611110039000000ae1611001b000000bab211000d0000001cd41100000000001c0d11001b000000c7b211000c000000211211004a0000006b1211001a0000001cd4110000000000851211004a000000cf1211001d0000001cd4110000000000ab0911000c000000ec12110035000000211311004400000065131100150000001cd41100000000007a13110049000000c3131100090000001cd41100000000005fb211000b000000d81011003f00000017111100470000005e11110048000000cc1311003b0000000714110047000000df11110027000000bab211000d0000001cd41100000000004e14110029000000c7b211000c0000005e0f11003d0000001cd41100000000009b0f11004b000000e60f1100470000002d1011004c0000001cd4110000000000ab0911000c000000791011004b000000c4101100140000001cd41100000000005fb211000b000000d81011003f00000017111100470000005e11110048000000a611110039000000df11110027000000bab211000d0000001cd4110000000000061211001b000000c7b211000c00000000000000570f110007000000000000009db611000c000000370d1100450000007c0d11001a0000001cd4110000000000960d110048000000de0d11003e0000001cd4110000000000cb0b1100410000001c0e11003c0000001cd4110000000000ab0911000c000000580e1100440000001cd41100000000005fb211000b0000009c0e110021000000bd0e11004f0000000c0f110030000000bab211000d0000001cd41100000000003c0f11001b000000c7b211000c000000410a1100570000001cd4110000000000980a110045000000dd0a1100420000001cd41100000000001f0b110049000000680b1100260000008e0b11003d0000001cd4110000000000cb0b1100410000000c0c1100390000001cd41100000000005fb211000b000000450c1100180000005d0c11004a000000a70c11004e000000f50c110027000000bab211000d0000001cd41100000000001c0d11001b000000c7b211000c000000f4081100380000001cd41100000000002c09110045000000710911003a0000001cd4110000000000ab0911000c000000b7091100460000001cd41100000000005fb211000b000000fd09110044000000c7b211000c0000002043616e63656c20746865206162696c69747920746f20757365206061735f7265636f76657265646020666f7220606163636f756e74602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207265676973746572656420746f2062652061626c6520746f206d616b652063616c6c73206f6e20626568616c66206f6620746865207265636f7665726564206163636f756e742e20506172616d65746572733a202d20606163636f756e74603a20546865207265636f7665726564206163636f756e7420796f75206172652061626c6520746f2063616c6c206f6e2d626568616c662d6f662e202d204f6e652073746f72616765206d75746174696f6e20746f20636865636b206163636f756e74206973207265636f7665726564206279206077686f602e204f2831292052656d6f766520746865207265636f766572792070726f6365737320666f7220796f7572206163636f756e742e205265636f7665726564206163636f756e747320617265207374696c6c2061636365737369626c652e204e4f54453a205468652075736572206d757374206d616b65207375726520746f2063616c6c2060636c6f73655f7265636f7665727960206f6e20616c6c20616374697665207265636f7665727920617474656d707473206265666f72652063616c6c696e6720746869732066756e6374696f6e20656c73652069742077696c6c206661696c2e205061796d656e743a2042792063616c6c696e6720746869732066756e6374696f6e20746865207265636f76657261626c65206163636f756e742077696c6c20756e72657365727665207468656972207265636f7665727920636f6e66696775726174696f6e206465706f7369742e202860436f6e6669674465706f7369744261736560202b2060467269656e644465706f736974466163746f7260202a20235f6f665f667269656e64732920546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64206d7573742062652061207265636f76657261626c65206163636f756e742028692e652e206861732061207265636f7665727920636f6e66696775726174696f6e292e204b65793a204620286c656e206f6620667269656e647329202d204f6e652073746f72616765207265616420746f206765742074686520707265666978206974657261746f7220666f7220616374697665207265636f7665726965732e204f283129202d204f6e652073746f7261676520726561642f72656d6f766520746f2067657420746865207265636f7665727920636f6e66696775726174696f6e2e204f2831292c20436f646563204f284629202d204f6e652062616c616e63652063616c6c20746f20756e72657365727665642e204f28582920546f74616c20436f6d706c65786974793a204f2846202b2058292041732074686520636f6e74726f6c6c6572206f662061207265636f76657261626c65206163636f756e742c20636c6f736520616e20616374697665207265636f766572792070726f6365737320666f7220796f7572206163636f756e742e205061796d656e743a2042792063616c6c696e6720746869732066756e6374696f6e2c20746865207265636f76657261626c65206163636f756e742077696c6c207265636569766520746865207265636f76657279206465706f73697420605265636f766572794465706f7369746020706c616365642062792074686520726573637565722e207265636f76657261626c65206163636f756e74207769746820616e20616374697665207265636f766572792070726f6365737320666f722069742e202d206072657363756572603a20546865206163636f756e7420747279696e6720746f207265736375652074686973207265636f76657261626c65206163636f756e742e204b65793a205620286c656e206f6620766f756368696e6720667269656e647329202d204f6e652073746f7261676520726561642f72656d6f766520746f206765742074686520616374697665207265636f766572792070726f636573732e204f2831292c20436f646563204f285629202d204f6e652062616c616e63652063616c6c20746f20726570617472696174652072657365727665642e204f28582920546f74616c20436f6d706c65786974793a204f2856202b2058297265736375657220416c6c6f772061207375636365737366756c207265736375657220746f20636c61696d207468656972207265636f7665726564206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64206d7573742062652061202272657363756572222077686f20686173207375636365737366756c6c7920636f6d706c6574656420746865206163636f756e74207265636f766572792070726f636573733a20636f6c6c656374656420607468726573686f6c6460206f72206d6f726520766f75636865732c20776169746564206064656c61795f706572696f646020626c6f636b732073696e636520696e6974696174696f6e2e202d20606163636f756e74603a20546865206c6f7374206163636f756e74207468617420796f752077616e7420746f20636c61696d20686173206265656e207375636365737366756c6c792020207265636f766572656420627920796f752e204b65793a204620286c656e206f6620667269656e647320696e20636f6e666967292c205620286c656e206f6620766f756368696e6720667269656e647329202d204f6e652073746f72616765207265616420746f2067657420746865207265636f7665727920636f6e66696775726174696f6e2e204f2831292c20436f646563204f284629202d204f6e652073746f72616765207265616420746f206765742074686520616374697665207265636f766572792070726f636573732e204f2831292c20436f646563204f285629202d204f6e652073746f72616765207265616420746f20676574207468652063757272656e7420626c6f636b206e756d6265722e204f283129202d204f6e652073746f726167652077726974652e204f2831292c20436f646563204f2856292e20546f74616c20436f6d706c65786974793a204f2846202b20562920416c6c6f7720612022667269656e6422206f662061207265636f76657261626c65206163636f756e7420746f20766f75636820666f7220616e20616374697665207265636f766572792070726f6365737320666f722074686174206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64206d75737420626520612022667269656e642220666f7220746865207265636f76657261626c65206163636f756e742e202d20606c6f7374603a20546865206c6f7374206163636f756e74207468617420796f752077616e7420746f207265636f7665722e202d206072657363756572603a20546865206163636f756e7420747279696e6720746f2072657363756520746865206c6f7374206163636f756e74207468617420796f7520202077616e7420746f20766f75636820666f722e2054686520636f6d62696e6174696f6e206f662074686573652074776f20706172616d6574657273206d75737420706f696e7420746f20616e20616374697665207265636f766572792070726f636573732e202d204f6e652062696e6172792073656172636820746f20636f6e6669726d2063616c6c6572206973206120667269656e642e204f286c6f674629202d204f6e652062696e6172792073656172636820746f20636f6e6669726d2063616c6c657220686173206e6f7420616c726561647920766f75636865642e204f286c6f67562920546f74616c20436f6d706c65786974793a204f2846202b206c6f6746202b2056202b206c6f67562920496e697469617465207468652070726f6365737320666f72207265636f766572696e672061207265636f76657261626c65206163636f756e742e205061796d656e743a20605265636f766572794465706f736974602062616c616e63652077696c6c20626520726573657276656420666f7220696e6974696174696e6720746865207265636f766572792070726f636573732e2054686973206465706f7369742077696c6c20616c7761797320626520726570617472696174656420746f20746865206163636f756e7420747279696e6720746f206265207265636f76657265642e205365652060636c6f73655f7265636f76657279602e202d20606163636f756e74603a20546865206c6f7374206163636f756e74207468617420796f752077616e7420746f207265636f7665722e2054686973206163636f756e742020206e6565647320746f206265207265636f76657261626c652028692e652e20686176652061207265636f7665727920636f6e66696775726174696f6e292e202d204f6e652073746f72616765207265616420746f20636865636b2074686174206163636f756e74206973207265636f76657261626c652e204f284629202d204f6e652073746f72616765207265616420746f20636865636b20746861742074686973207265636f766572792070726f63657373206861736e277420616c726561647920737461727465642e204f283129202d204f6e652063757272656e63792072657365727665206f7065726174696f6e2e204f285829202d204f6e652073746f726167652077726974652e204f2831292e204372656174652061207265636f7665727920636f6e66696775726174696f6e20666f7220796f7572206163636f756e742e2054686973206d616b657320796f7572206163636f756e74207265636f76657261626c652e205061796d656e743a2060436f6e6669674465706f7369744261736560202b2060467269656e644465706f736974466163746f7260202a20235f6f665f667269656e64732062616c616e63652077696c6c20626520726573657276656420666f722073746f72696e6720746865207265636f7665727920636f6e66696775726174696f6e2e2054686973206465706f7369742069732072657475726e656420696e2066756c6c207768656e2074686520757365722063616c6c73206072656d6f76655f7265636f76657279602e202d2060667269656e6473603a2041206c697374206f6620667269656e647320796f7520747275737420746f20766f75636820666f72207265636f7665727920617474656d7074732e20202053686f756c64206265206f72646572656420616e6420636f6e7461696e206e6f206475706c69636174652076616c7565732e202d20607468726573686f6c64603a20546865206e756d626572206f6620667269656e64732074686174206d75737420766f75636820666f722061207265636f7665727920617474656d70742020206265666f726520746865206163636f756e742063616e206265207265636f76657265642e2053686f756c64206265206c657373207468616e206f7220657175616c20746f202020746865206c656e677468206f6620746865206c697374206f6620667269656e64732e202d206064656c61795f706572696f64603a20546865206e756d626572206f6620626c6f636b732061667465722061207265636f7665727920617474656d707420697320696e697469616c697a656420202074686174206e6565647320746f2070617373206265666f726520746865206163636f756e742063616e206265207265636f76657265642e202d204b65793a204620286c656e206f6620667269656e647329202d204f6e652073746f72616765207265616420746f20636865636b2074686174206163636f756e74206973206e6f7420616c7265616479207265636f76657261626c652e204f2831292e202d204120636865636b20746861742074686520667269656e6473206c69737420697320736f7274656420616e6420756e697175652e204f284629202d204f6e652073746f726167652077726974652e204f2831292e20436f646563204f2846292e667269656e647364656c61795f706572696f6420416c6c6f7720524f4f5420746f2062797061737320746865207265636f766572792070726f6365737320616e642073657420616e20612072657363756572206163636f756e7420666f722061206c6f7374206163636f756e74206469726563746c792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f524f4f545f2e202d20606c6f7374603a2054686520226c6f7374206163636f756e742220746f206265207265636f76657265642e202d206072657363756572603a20546865202272657363756572206163636f756e74222077686963682063616e2063616c6c20617320746865206c6f7374206163636f756e742e202d204f6e652073746f72616765207772697465204f283129202d204f6e65206576656e746c6f73742053656e6420612063616c6c207468726f7567682061207265636f7665726564206163636f756e742e202d20606163636f756e74603a20546865207265636f7665726564206163636f756e7420796f752077616e7420746f206d616b6520612063616c6c206f6e2d626568616c662d6f662e202d206063616c6c603a205468652063616c6c20796f752077616e7420746f206d616b65207769746820746865207265636f7665726564206163636f756e742e202d204f6e652073746f72616765206c6f6f6b757020746f20636865636b206163636f756e74206973207265636f7665726564206279206077686f602e204f2831295265636f76657279000000000000c01d11000b00000001050000000000009db611000c00000000000000cb1d11003a000000000000000000000000000000000000001cd41100081e11000000000000000000181e110001000000000000000000000000000000201e11001000000002050500000000009db611000c000000000000009db611000c00000000000000301e11003a000000000000001cd411006c1e110000000000000000007c1e1100040000000000000000000000000000009c1e11000500000001020000000000009db611000c000000000000009db611000c000000000000000000000000000000000000001cd41100a41e11000000000000000000b41e11000300000000000000000000005265636f76657261626c655265636f76657279436f6e6669673c543a3a426c6f636b4e756d6265722c2042616c616e63654f663c543e2c20543a3a4163636f756e7449643e00000016000000000000000100000032000000b81f1100420000004163746976655265636f7665726965734163746976655265636f766572793c543a3a426c6f636b4e756d6265722c2042616c616e63654f663c543e2c20543a3a4163636f756e7449643e0000160000000000000001000000320000002e1f11001a0000001cd4110000000000481f1100450000008d1f11002b00000050726f787900000016000000000000000100000032000000cc1e1100240000001cd4110000000000f01e11003e00000020546865206c697374206f6620616c6c6f7765642070726f7879206163636f756e74732e204d61702066726f6d2074686520757365722077686f2063616e2061636365737320697420746f20746865207265636f7665726564206163636f756e742e20416374697665207265636f7665727920617474656d7074732e204669727374206163636f756e7420697320746865206163636f756e7420746f206265207265636f76657265642c20616e6420746865207365636f6e64206163636f756e7420697320746865207573657220747279696e6720746f207265636f76657220746865206163636f756e742e2054686520736574206f66207265636f76657261626c65206163636f756e747320616e64207468656972207265636f7665727920636f6e66696775726174696f6e2e00001600000008000000040000009a0000009b00000000000000000000009c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016fc1000060000000105000000000000285f11000e00000000000000c42111003a000000000000000000000000000000000000001cd41100002211000000000000000000102211000100000000000000010000000000000018221100060000000105000000000000aa39110007000000000000001e2211001b000000000000000000000000000000000000001cd411003c22110000000000000000004c2211000100000000000000000000005665633c4f7074696f6e3c5363686564756c65643c3c542061732054726169743e3a3a43616c6c2c20543a3a426c6f636b4e756d6265723e3e3e00001600000000000000010000003000000094221100530000004c6f6f6b75705461736b416464726573733c543a3a426c6f636b4e756d6265723e000000160000000000000001000000320000005422110040000000204c6f6f6b75702066726f6d206964656e7469747920746f2074686520626c6f636b206e756d62657220616e6420696e646578206f6620746865207461736b2e204974656d7320746f2062652065786563757465642c20696e64657865642062792074686520626c6f636b206e756d626572207468617420746865792073686f756c64206265206578656375746564206f6e2e005c23110049000000920200001a000000942c11004800000002020000230000005c23110049000000a301000027000000010000000100000000000000000000000000000001000000617373657274696f6e206661696c65643a206d6964203c3d206c656e5c231100490000008e0200001d0000002f72757374632f366465653566313132366466643563393331346565356165396439656230313065333565663235372f7372632f6c6962636f72652f736c6963652f736f72742e72730000005c23110049000000a1000000300000005c23110049000000a400000030000000ffffff1f87241100160000009d24110016000000542411002d0000008124110003000000842411000300000000000000200000000000000002000000000000000200000000000000030000000100000020000000080000000200000000000000000000000200000003000000020000002000000000000000020000000000000002000000000000000300000042697450747220726567696f6e2063616e6e6f7420777261702074686520616464726573732073706163653a20202b20203d204269745074722063616e6e6f7420616464726573732020626974733b20746865206d6178696d756d2069732000e424110066000000700000002e000000e4241100660000008f00000034000000e42411006600000068000000340000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f7072696d6974697665732f747269652f7372632f6e6f64655f636f6465632e7273000000000000d1f510000b00000000000000bc251100020000000000000000000000c5f510000c00000000000000cc251100020000000000000000000000b8f510000d00000000000000dc251100010000000000000000000000b1f510000700000000000000e42511000100000000000000c526110042000000072711002a00000057261100450000009c261100290000001c2611003b000000ec251100300000002043616e6e6f74207369676e616c20666f72636564206368616e676520736f20736f6f6e206166746572206c6173742e20417474656d707420746f207369676e616c204752414e445041206368616e67652077697468206f6e6520616c72656164792070656e64696e672e20417474656d707420746f207369676e616c204752414e44504120726573756d65207768656e2074686520617574686f72697479207365742069736e2774207061757365642028656974686572206c697665206f7220616c72656164792070656e64696e6720726573756d65292e20417474656d707420746f207369676e616c204752414e445041207061757365207768656e2074686520617574686f72697479207365742069736e2774206c697665202865697468657220706175736564206f7220616c72656164792070656e64696e67207061757365292e00000000000000b6f610000a00000000000000f4281100010000000000000000000000de8a11000d00000000000000fc281100010000000000000000000000a6f610001000000000000000042911000100000000000000000000009cf610000a000000000000000c29110001000000000000000000000093f6100009000000000000001429110001000000000000000000000085f610000e000000000000001c29110001000000000000000000000073f6100012000000000000002429110001000000000000000000000065f610000e000000000000002c2911000100000000000000000000005bf610000a000000000000003429110001000000000000000000000052f6100009000000000000003c29110001000000000000000000000047f610000b000000000000004429110001000000000000000000000039f610000e000000000000004c29110001000000000000000000000030f6100009000000000000005429110001000000000000000000000025f610000b000000000000005c2911000100000000000000000000007456110008000000000000006429110001000000000000000000000019f610000c00000000000000242911000100000000000000272c11003d000000032c110024000000ce2b110035000000a32b11002b000000702b110033000000482b1100280000001c2b11002c000000e42a110038000000b02a110034000000852a11002b0000003e2a1100470000000e2a110030000000d32911003b00000093291100400000006c291100270000002054686572652077617320616e206f766572666c6f7720696e20612063616c63756c6174696f6e20546865726520617265207374696c6c20616374697665207265636f7665727920617474656d7074732074686174206e65656420746f20626520636c6f73656420546865207468726573686f6c6420666f72207265636f766572696e672074686973206163636f756e7420686173206e6f74206265656e206d6574205468697320757365722068617320616c726561647920766f756368656420666f722074686973207265636f766572792054686520667269656e64206d757374207761697420756e74696c207468652064656c617920706572696f6420746f20766f75636820666f722074686973207265636f766572792054686973206163636f756e74206973206e6f74206120667269656e642077686f2063616e20766f7563682041207265636f766572792070726f6365737320686173206e6f74207374617274656420666f72207468697320726573637565722041207265636f766572792070726f636573732068617320616c7265616479207374617274656420666f722074686973206163636f756e742054686973206163636f756e7420697320616c72656164792073657420757020666f72207265636f766572792054686973206163636f756e74206973206e6f742073657420757020666f72207265636f7665727920467269656e6473206c697374206d75737420626520736f7274656420616e642066726565206f66206475706c69636174657320467269656e6473206c697374206d757374206265206c657373207468616e206d617820667269656e647320467269656e6473206c697374206d7573742062652067726561746572207468616e207a65726f20616e64207468726573686f6c64205468726573686f6c64206d7573742062652067726561746572207468616e207a65726f2055736572206973206e6f7420616c6c6f77656420746f206d616b6520612063616c6c206f6e20626568616c66206f662074686973206163636f756e743432110063000000720100003300000034321100630000007201000011000000942c11004800000001020000230000002f72757374632f366465653566313132366466643563393331346565356165396439656230313065333565663235372f7372632f6c6962636f72652f736c6963652f6d6f642e7273617373657274696f6e206661696c65643a2073656c662e6c656e2829203c204341504143495459617373657274696f6e206661696c65643a20656467652e686569676874203d3d2073656c662e686569676874202d2031617373657274696f6e206661696c65643a2073656c662e686569676874203e2030617373657274696f6e206661696c65643a2073656c662e6c656e2829203e2030842d110056000000a5040000520000002f72757374632f366465653566313132366466643563393331346565356165396439656230313065333565663235372f7372632f6c6962616c6c6f632f636f6c6c656374696f6e732f62747265652f6e6f64652e72730000842d110056000000b60400004c000000617373657274696f6e206661696c65643a20656467652e686569676874203d3d2073656c662e6e6f64652e686569676874202d2031436865636b576569676874436865636b457261436865636b4e6f6e6365436865636b47656e657369734368617267655472616e73616374696f6e5061796d656e74436865636b56657273696f6e004e6f6e5a65726f526566436f756e744e6f6e44656661756c74436f6d706f736974654661696c6564546f4578747261637452756e74696d6556657273696f6e5370656356657273696f6e4e65656473546f496e637265617365496e76616c6964537065634e616d653a65787472696e7369635f696e64657866696c6c5f626c6f636b72656d61726b7365745f686561705f70616765737365745f636f64657365745f636f64655f776974686f75745f636865636b737365745f6368616e6765735f747269655f636f6e6669677365745f73746f726167656b696c6c5f73746f726167656b696c6c5f7072656669787375696369646553797374656d426c6f636b486173684e756d626572506172656e744861736845787472696e73696373526f6f744469676573740000000000743011001000000000000000843011000100000000000000000000008c301100010000000000000000000000943011000f00000000000000a4301100020000000000000000000000b4301100010000000000000000000000bc3011000b000000000000001cd41100000000000000000000000000c8301100010000000000000000000000d03011000a0000000000000044a51100010000000000000000000000dc301100010000000000000000000000e43011000d0000000000000044a51100010000000000000000000000f4301100010000000000000045787472696e73696353756363657373583111000c000000643111002500000045787472696e7369634661696c656400175611000d000000583111000c0000004331110015000000436f646555706461746564002e311100150000004e65774163636f756e740000133111001b0000004b696c6c65644163636f756e74000000fc3011001700000020416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e20603a636f6465602077617320757064617465642e20416e2065787472696e736963206661696c65642e4469737061746368496e666f20416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e4f6666656e6365735265706f727473436f6e63757272656e745265706f727473496e64657800001600000000000000010000001a0000004576656e74730000d83111002e000000063211000d0000004552524f523a2072657475726e6564206e6578745f6b657920686173206e6f2076616c75653a0a6b6579206973200a6e6578745f6b65792069732044656665727265644f6666656e636573003432110063000000980100001e0000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f7072696d6974697665732f70687261676d656e2f7372632f6c69622e7273000000000000000000617474656d707420746f20646976696465206279207a65726f000000cc32110048000000bb0100002d0000002f72757374632f366465653566313132366466643563393331346565356165396439656230313065333565663235372f7372632f6c6962636f72652f6f70732f61726974682e727384341100660000007100000013000000843411006600000088000000180000008434110066000000b4000000190000008434110066000000ff00000042000000843411006600000013010000420000008434110066000000570100001500000084341100660000005c0100001e0000001600000000000000010000002a00000084341100660000005f0000001a00000084341100660000005f0000002c0000008434110066000000cc010000240000008434110066000000cd010000240000008434110066000000f1010000230000008434110066000000f30100002400000084341100660000001602000035000000843411006600000017020000350000008434110066000000200200002400000084341100660000004202000035000000843411006600000043020000350000008434110066000000580200002b000000843411006600000059020000280000008434110066000000630200002b000000843411006600000064020000280000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f7072696d6974697665732f70687261676d656e2f7372632f7265647563652e72734576656e74546f7069637300000000000000e72e11000a00000000000000b0361100010000000000000000000000c8361100010000000000000000000000f12e11000600000000000000d0361100010000000000000000000000e8361100010000000000000000000000f72e11000e00000000000000f036110001000000000000000000000008371100010000000000000000000000052f1100080000000000000010371100010000000000000000000000283711000100000000000000000000000d2f110017000000000000001037110001000000000000000000000030371100010000000000000000000000242f1100170000000000000038371100010000000000000000000000503711000100000000000000000000003b2f11000b000000000000005837110001000000000000000000000070371100010000000000000000000000462f11000c000000000000007837110001000000000000000000000090371100010000000000000000000000522f11000b0000000000000098371100010000000000000000000000b03711000100000000000000000000005d2f110007000000000000001cd41100000000000000000000000000b8371100020000000000000000000000593a110006000000000000005f3a110007000000173a11004200000000000000103a11000700000000000000aa39110007000000f53911001b00000000000000f039110005000000000000002e5d110003000000b13911003f00000000000000a63911000400000000000000aa391100070000008c3911001a0000004539110047000000000000001239110013000000000000002539110020000000ea3811002800000000000000d83811000500000000000000dd3811000d000000bd3811001b00000000000000b13811000400000000000000b538110008000000933811001e000000000000008a381100060000000000000090381100030000004538110045000000c8371100590000002138110024000000204b696c6c207468652073656e64696e67206163636f756e742c20617373756d696e6720746865726520617265206e6f207265666572656e636573206f75747374616e64696e6720616e642074686520636f6d706f73697465206461746120697320657175616c20746f206974732064656661756c742076616c75652e204b696c6c20616c6c2073746f72616765206974656d7320776974682061206b657920746861742073746172747320776974682074686520676976656e207072656669782e7072656669784b6579204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e6b6579735665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e6974656d735665633c4b657956616c75653e2053657420746865206e6577206368616e676573207472696520636f6e66696775726174696f6e2e6368616e6765735f747269655f636f6e6669674f7074696f6e3c4368616e67657354726965436f6e66696775726174696f6e3e2053657420746865206e65772072756e74696d6520636f646520776974686f757420646f696e6720616e7920636865636b73206f662074686520676976656e2060636f6465602e2053657420746865206e65772072756e74696d6520636f64652e636f64655665633c75383e2053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e7061676573204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b204120646973706174636820746861742077696c6c2066696c6c2074686520626c6f636b2077656967687420757020746f2074686520676976656e20726174696f2e5f726174696f50657262696c6c000000000000088711000700000001020000000000009db611000c00000000000000903f110025000000000000000000000000000000000000001cd41100b83f11000000000000000000c83f110001000000000000000100000000000000d03f11000e00000000000000000000001456110003000000000000000000000000000000000000000000000000000000000000001cd411001c4011000000000000000000e03f110001000000000000000000000000000000e83f1100130000000000000000000000fb3f110006000000000000000000000000000000000000000000000000000000000000001cd411001c401100000000000000000004401100010000000000000000000000000000000c4011001000000000000000000000001456110003000000000000000000000000000000000000000000000000000000000000001cd411001c40110000000000000000002c401100010000000000000000000000000000006a2f1100090000000105000000000000285f11000e000000000000003440110007000000000000000000000000000000000000001cd411006c40110000000000000000003c40110001000000000000000100000000000000444011000d0000000105000000000000145611000300000000000000aa39110007000000000000000000000000000000000000001cd41100404a110000000000000000005440110001000000000000000100000000000000732f1100060000000000000000000000285f11000e000000000000000000000000000000000000000000000000000000000000001cd41100f840110000000000000000005c40110001000000000000000100000000000000792f11000a00000000000000000000003440110007000000000000000000000000000000000000000000000000000000000000001cd411006c40110000000000000000006440110001000000000000000100000000000000832f11000e00000000000000000000003440110007000000000000000000000000000000000000000000000000000000000000001cd411006c40110000000000000000007c40110001000000000000000100000000000000912f1100060000000000000000000000844011000b000000000000000000000000000000000000000000000000000000000000001cd41100904011000000000000000000a040110001000000000000000100000000000000c0311100060000000000000000000000a840110023000000000000000000000000000000000000000000000000000000000000001cd41100cc4011000000000000000000dc40110001000000000000000100000000000000e44011000a0000000000000000000000ee4011000a000000000000000000000000000000000000000000000000000000000000001cd41100f840110000000000000000000841110001000000000000000100000000000000ea3411000b00000001020000000000003440110007000000000000001041110021000000000000000000000000000000000000001cd41100344111000000000000000000444111000a00000000000000010000000000000094411100120000000000000000000000a641110016000000000000000000000000000000000000000000000000000000000000001cd41100bc4111000000000000000000cc41110001000000000000000000000000000000d44111000e0000000000000000000000e241110005000000000000000000000000000000000000000000000000000000000000001cd41100e84111000000000000000000f84111000100000000000000000000004163636f756e74496e666f3c543a3a496e6465782c20543a3a4163636f756e74446174613e0000001600000000000000010000009d000000164711003a00000045787472696e736963436f756e740000e84611002e000000416c6c45787472696e73696373576569676874576569676874000000a346110045000000416c6c45787472696e736963734c656e160000000000000001000000320000005346110050000000543a3a48617368002d4611002600000045787472696e73696344617461000000de4511004f0000009c45110042000000804511001c0000001600000000000000010000009e0000003b451100450000004469676573744f663c543e0016000000000000000100000030000000ff4411003c0000005665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e001600000000000000010000009f000000d7441100280000004576656e74436f756e744576656e74496e6465781600000000000000010000002e000000a94411002e0000005665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e000000160000000000000001000000300000007742110049000000c0421100250000001cd4110000000000e54211005400000039431100510000008a431100390000001cd4110000000000c343110053000000164411005300000069441100400000004c61737452756e74696d65557067726164654c61737452756e74696d6555706772616465496e666f160000000000000001000000320000002242110055000000457865637574696f6e50686173655068617365001600000000000000010000003200000000421100220000002054686520657865637574696f6e207068617365206f662074686520626c6f636b2e2053746f726573207468652060737065635f76657273696f6e6020616e642060737065635f6e616d6560206f66207768656e20746865206c6173742072756e74696d6520757067726164652068617070656e65642e204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2045787472696e7369637320726f6f74206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2077656967687420666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e205468652066756c6c206163636f756e7420696e666f726d6174696f6e20666f72206120706172746963756c6172206163636f756e742049442e4e6f646520697320636f6e6669677572656420746f20757365207468652073616d6520686173683b207165649c4711005c000000750300001c0000009c4711005c0000007d030000110000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f73797374656d2f7372632f6c69622e72730000000091311100070000000105000000000000584911000d000000000000006549110034000000000000000000000000000000000000001cd411009c4911000000000000000000ac4911000100000000000000000000000000000013321100100000000000000000000000b449110019000000000000000000000000000000000000000000000000000000000000001cd41100d04911000000000000000000e04911000200000000000000010000000000000098311100160000000205050000000000f04911000400000000000000f44911000e00000000000000024a110012000000000000001cd41100144a11000000000000000000244a1100010000000000000001000000000000002c4a1100120000000105000000000000f04911000400000000000000aa39110007000000000000000000000000000000000000001cd41100404a11000000000000000000504a11000600000000000000010000005265706f727449644f663c543e4f6666656e636544657461696c733c543a3a4163636f756e7449642c20543a3a4964656e74696669636174696f6e5475706c653e00000016000000000000000100000032000000534c1100520000005665633c44656665727265644f6666656e63654f663c543e3e00000016000000000000000100000030000000e94b110059000000424c1100110000004b696e644f706171756554696d65536c6f745665633c5265706f727449644f663c543e3e160000000000000001000000300000009f4b11004a0000005265706f72747342794b696e64496e646578000016000000000000000100000030000000804a1100440000001cd4110000000000c44a11002f0000001cd4110000000000f34a110052000000454b11005a00000020456e756d65726174657320616c6c207265706f727473206f662061206b696e6420616c6f6e672077697468207468652074696d6520746865792068617070656e65642e20416c6c207265706f7274732061726520736f72746564206279207468652074696d65206f66206f6666656e63652e204e6f74652074686174207468652061637475616c2074797065206f662074686973206d617070696e6720697320605665633c75383e602c207468697320697320626563617573652076616c756573206f6620646966666572656e7420747970657320617265206e6f7420737570706f7274656420617420746865206d6f6d656e7420736f2077652061726520646f696e6720746865206d616e75616c2073657269616c697a6174696f6e2e204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e204465666572726564207265706f72747320746861742068617665206265656e2072656a656374656420627920746865206f6666656e63652068616e646c657220616e64206e65656420746f206265207375626d69747465642061742061206c617465722074696d652e20546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e706172613a646f75626c652d766f7465696d2d6f6e6c696e653a6f66666c696e5472616e73616374696f6e5061796d656e740000000000304d1100110000000000000000000000414d11000a000000000000000000000000000000000000000000000000000000000000001cd411004c4d110000000000000000001cd411000000000000000000010000004e6578744665654d756c7469706c6965724d756c7469706c696572001600000000000000010000009900000000000000cc4d11001200000000000000de4d11000c000000000000001cd41100ec4d11000000000000000000fc4d1100010000000000000000000000044e11001200000000000000de4d11000c000000000000001cd41100184e11000000000000000000284e110001000000000000005472616e73616374696f6e4261736546656542616c616e63654f663c543e0000160000000000000001000000a0000000734e1100370000005472616e73616374696f6e427974654665650000160000000000000001000000a1000000304e110043000000205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b2074686520626173652e3a6865617070616765733a636f64653a6368616e6765735f74726965000000000000c82e11000f00000000000000544f1100020000000000000000000000ae2e11001a00000000000000644f1100020000000000000000000000912e11001d00000000000000744f11000300000000000000000000007e2e110013000000000000008c4f11000100000000000000000000006f2e11000f00000000000000944f110001000000000000000f51110045000000fa50110015000000a950110051000000fa501100150000002a5011003c0000001cd41100000000006650110043000000ea4f1100400000009c4f11004e0000002054686572652069732061206e6f6e2d7a65726f207265666572656e636520636f756e742070726576656e74696e6720746865206163636f756e742066726f6d206265696e67207075726765642e20537569636964652063616c6c6564207768656e20746865206163636f756e7420686173206e6f6e2d64656661756c7420636f6d706f7369746520646174612e204661696c656420746f2065787472616374207468652072756e74696d652076657273696f6e2066726f6d20746865206e65772072756e74696d652e204569746865722063616c6c696e672060436f72655f76657273696f6e60206f72206465636f64696e67206052756e74696d6556657273696f6e60206661696c65642e205468652073706563696669636174696f6e2076657273696f6e206973206e6f7420616c6c6f77656420746f206465637265617365206265747765656e207468652063757272656e742072756e74696d6520616e6420746865206e65772072756e74696d652e20546865206e616d65206f662073706563696669636174696f6e20646f6573206e6f74206d61746368206265747765656e207468652063757272656e742072756e74696d65626174636861735f73756261735f6d756c7469617070726f76655f61735f6d756c746963616e63656c5f61735f6d756c7469000000000000905211001000000000000000a0521100020000000000000000000000b0521100020000000000000000000000c05211000e000000000000001cd41100000000000000000000000000d0521100010000000000000000000000d85211000b00000000000000e4521100020000000000000000000000f4521100020000000000000000000000045311001000000000000000145311000300000000000000000000002c5311000200000000000000000000003c53110010000000000000004c5311000400000000000000000000006c5311000200000000000000000000007c5311001100000000000000145311000300000000000000000000009053110002000000000000004261746368496e7465727275707465641456110003000000175611000d000000ab5511005600000001561100130000004261746368436f6d706c65746564000078551100330000004e65774d756c7469736967009aa61100090000009aa6110009000000065511005200000058551100200000004d756c7469736967417070726f76616c9aa61100090000008c541100160000009aa6110009000000b054110056000000625411002a0000004d756c746973696745786563757465649aa61100090000008c541100160000009aa6110009000000a25411000e000000175411004b000000625411002a0000004d756c746973696743616e63656c6c6564000000a05311004c000000ec5311002b0000002041206d756c7469736967206f7065726174696f6e20686173206265656e2063616e63656c6c65642e20466972737420706172616d20697320746865206163636f756e7420746861742069732063616e63656c6c696e672c20746869726420697320746865206d756c7469736967206163636f756e742e2041206d756c7469736967206f7065726174696f6e20686173206265656e2065786563757465642e20466972737420706172616d20697320746865206163636f756e74207468617420697320617070726f76696e672c20746869726420697320746865206d756c7469736967206163636f756e742e54696d65706f696e743c426c6f636b4e756d6265723e4469737061746368526573756c742041206d756c7469736967206f7065726174696f6e20686173206265656e20617070726f76656420627920736f6d656f6e652e20466972737420706172616d20697320746865206163636f756e7420746861742069732041206e6577206d756c7469736967206f7065726174696f6e2068617320626567756e2e20466972737420706172616d20697320746865206163636f756e74207468617420697320617070726f76696e672c207365636f6e6420697320746865206d756c7469736967206163636f756e742e204261746368206f66206469737061746368657320636f6d706c657465642066756c6c792077697468206e6f206572726f722e204261746368206f66206469737061746368657320646964206e6f7420636f6d706c6574652066756c6c792e20496e646578206f66206669727374206661696c696e6720646973706174636820676976656e2c2061732077656c6c20617320746865206572726f722e75333244697370617463684572726f72446561644163636f756e744578697374696e6756657374696e675363686564756c654b656570416c6976654578697374656e7469616c4465706f736974496e73756666696369656e7442616c616e63654f766572666c6f774c69717569646974795265737472696374696f6e7356657374696e6742616c616e63657365745f62616c616e63657472616e736665725f6b6565705f616c69766542616c616e636573546f74616c49737375616e63654c6f636b730000000000b4571100070000000000000064a51100020000000000000000000000bc571100010000000000000000000000c4571100080000000000000064a51100020000000000000000000000cc571100020000000000000000000000dc5711000800000000000000e4571100030000000000000000000000fc571100010000000000000000000000045811000a00000000000000105811000300000000000000000000002858110001000000000000000000000030581100070000000000000064a51100020000000000000000000000385811000100000000000000456e646f776564003d5911002f000000447573744c6f7374ce581100500000001e5911001f0000005472616e736665729aa61100090000009aa611000900000009a7110007000000a85811002600000042616c616e636553657400009aa611000900000009a711000700000009a711000700000077581100310000004465706f73697400405811003700000020536f6d6520616d6f756e7420776173206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e20412062616c616e6365207761732073657420627920726f6f74202877686f2c20667265652c207265736572766564292e205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c7565292e20416e206163636f756e74207761732072656d6f7665642077686f73652062616c616e636520776173206e6f6e2d7a65726f206275742062656c6f77204578697374656e7469616c4465706f7369742c20726573756c74696e6720696e20616e206f75747269676874206c6f73732e20416e206163636f756e74207761732063726561746564207769746820736f6d6520667265652062616c616e63652e74696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c506f7374496e666f3a20426162654c6174656e6573730000000000245d11000a00000000000000000000002e5d110003000000000000000000000000000000000000000000000000000000000000001cd41100b05d11000000000000000000345d1100010000000000000001000000000000003c5d11000b0000000000000000000000475d110027000000000000000000000000000000000000000000000000000000000000001cd41100705d11000000000000000000805d110001000000000000000100000000000000885d11000b00000000000000000000002e5d110003000000000000000000000000000000000000000000000000000000000000001cd41100b05d11000000000000000000945d110002000000000000000100000000000000a45d11000b00000000000000000000002e5d110003000000000000000000000000000000000000000000000000000000000000001cd41100b05d11000000000000000000c05d110001000000000000000100000000000000c85d11000a0000000000000000000000d25d110016000000000000000000000000000000000000000000000000000000000000001cd41100485e11000000000000000000e85d11000a000000000000000100000000000000385e11000e0000000000000000000000d25d110016000000000000000000000000000000000000000000000000000000000000001cd41100485e11000000000000000000585e110001000000000000000100000000000000605e11000c00000000000000000000001456110003000000000000000000000000000000000000000000000000000000000000001cd41100385f110000000000000000006c5e110009000000000000000100000000000000b45e1100110000000105000000000000145611000300000000000000c55e11001d000000000000000000000000000000000000001cd41100e45e110000000000000000001cd4110000000000000000000100000000000000f45e11000b0000000000000000000000ff5e110008000000000000000000000000000000000000000000000000000000000000001cd41100085f11000000000000000000185f110002000000000000000000000000000000ab591100080000000000000000000000285f11000e000000000000000000000000000000000000000000000000000000000000001cd41100385f11000000000000000000485f110005000000000000000100000045706f6368496e6465787536340000009664110015000000417574686f7269746965735665633c28417574686f7269747949642c2042616265417574686f72697479576569676874293e0000160000000000000001000000300000007b6411001b00000047656e65736973536c6f7400196411003e000000576411002400000043757272656e74536c6f740016000000000000000100000099000000046411001500000052616e646f6d6e6573737363686e6f72726b656c3a3a52616e646f6d6e6573733e6211002e0000001cd41100000000006c6211000b0000001cd41100000000007762110041000000b86211003e000000f6621100450000003b631100450000008063110041000000c1631100430000004e65787452616e646f6d6e6573730000160000000000000001000000a200000027621100170000005365676d656e74496e646578e26011001f0000001cd4110000000000016111003d0000003e611100400000007e611100250000001cd4110000000000a36111003b000000de611100420000002062110007000000556e646572436f6e737472756374696f6e5665633c7363686e6f72726b656c3a3a5261775652464f75747075743e000016000000000000000100000030000000496e697469616c697a65644d6179626556726600160000000000000001000000320000005b601100400000009b60110047000000543a3a426c6f636b4e756d62657200001600000000000000010000002e000000705f1100360000001cd4110000000000a65f110045000000eb5f1100440000002f6011002c00000020486f77206c617465207468652063757272656e7420626c6f636b20697320636f6d706172656420746f2069747320706172656e742e205468697320656e74727920697320706f70756c617465642061732070617274206f6620626c6f636b20657865637574696f6e20616e6420697320636c65616e6564207570206f6e20626c6f636b2066696e616c697a6174696f6e2e205175657279696e6720746869732073746f7261676520656e747279206f757473696465206f6620626c6f636b20657865637574696f6e20636f6e746578742073686f756c6420616c77617973207969656c64207a65726f2e2054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d6560206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e205765206d616b6520612074726164656f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e2057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f2060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e20576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572792065706f63682e204e6578742065706f63682072616e646f6d6e6573732e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2043757272656e7420736c6f74206e756d6265722e2054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e2054686973206973203020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e00000000001c6511000d000000000000002e5d110003000000000000001cd411002c65110000000000000000003c6511000200000000000000000000004c651100110000000000000004cf110009000000000000001cd4110060651100000000000000000070651100050000000000000045706f63684475726174696f6e000000160000000000000001000000a3000000c8661100430000000b6711003f0000004578706563746564426c6f636b54696d65000000160000000000000001000000a40000009865110041000000d9651100440000001d661100410000005e66110042000000a06611002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e20546865206e756d626572206f66202a2a736c6f74732a2a207468617420616e2065706f63682074616b65732e20576520636f75706c652073657373696f6e7320746f2065706f6368732c20692e652e2077652073746172742061206e65772073657373696f6e206f6e636520746865206e65772065706f636820626567696e732e65706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b2071656400b46711005a0000006a0100001b000000b46711005a00000072010000200000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f626162652f7372632f6c69622e7273000000000000545111000500000000000000ec6811000100000000000000000000000469110012000000000000000000000059511100060000000000000094691100020000000000000000000000c46911000700000000000000000000005f5111000800000000000000fc6911000400000000000000000000005c6a1100290000000000000000000000675111001000000000000000a46b1100040000000000000000000000046c1100200000000000000000000000775111000f00000000000000046d1100040000000000000000000000646d1100160000000000000000000000817a11000500000000000000867a11001700000041781100200000001cd4110000000000617811003b0000001cd41100000000009c7811001f0000001cd4110000000000bb7811003c0000001cd41100000000005fb211000b000000f778110029000000bab211000d000000c7b211000c0000001cd41100000000002079110056000000767911004d000000c379110056000000197a1100540000006d7a1100140000000000000034b611000500000000000000627111000300000000000000c97711000400000000000000cd77110017000000e4771100380000001cd4110000000000b09a1100340000001cd41100000000005fb211000b0000001c78110025000000c7b211000c000000000000005971110009000000000000006271110003000000000000006571110011000000000000007671110011000000000000005b7511000f000000000000006a7511002100000000000000c97711000400000000000000cd77110017000000ba71110056000000107211003f0000001cd41100000000008b7511002d0000001cd41100000000004f72110054000000a372110058000000fb7211000e0000001cd4110000000000b09a1100340000001cd41100000000009c6e110056000000f26e110051000000436f11001c00000009731100570000006073110055000000b573110036000000b8751100230000001cd4110000000000db7511004800000023761100470000001cd41100000000006a76110057000000c17611005600000017771100380000001cd41100000000005fb211000b0000004f771100150000001470110034000000487011005000000098701100520000006477110049000000ea7011003000000039741100360000006f7411003f000000bab211000d000000ad7711001c000000ae7411004c000000fa741100240000001e7511003d000000c7b211000c000000000000005971110009000000000000006271110003000000000000006571110011000000000000007671110011000000000000005b7511000f000000000000006a7511002100000000000000a97111000900000000000000b271110008000000ba71110056000000107211003f0000001cd41100000000004f72110054000000a372110058000000fb7211000e0000001cd4110000000000b09a1100340000001cd41100000000009c6e110056000000f26e110051000000436f11001c00000009731100570000006073110055000000b573110036000000d66f1100340000001cd4110000000000eb7311004e0000001cd41100000000005fb211000b0000000a7011000a000000147011003400000048701100500000009870110052000000ea7011003000000039741100360000006f7411003f000000bab211000d000000ae7411004c000000fa741100240000001e7511003d000000c7b211000c00000000000000597111000900000000000000627111000300000000000000657111001100000000000000767111001100000000000000877111000900000000000000907111001900000000000000a97111000900000000000000b271110008000000146e1100560000006a6e1100320000001cd4110000000000b09a1100340000001cd41100000000009c6e110056000000f26e110051000000436f11001c0000005f6f110058000000b76f11001f000000d66f1100340000001cd41100000000005fb211000b0000000a7011000a000000147011003400000048701100500000009870110052000000ea70110030000000bab211000d0000001a711100220000003c7111001d000000c7b211000c0000002043616e63656c2061207072652d6578697374696e672c206f6e2d676f696e67206d756c7469736967207472616e73616374696f6e2e20416e79206465706f7369742072657365727665642070726576696f75736c7920666f722074686973206f7065726174696f6e2077696c6c20626520756e7265736572766564206f6e20737563636573732e202d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e202d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869732064697370617463682e204d6179206e6f7420626520656d7074792e202d206074696d65706f696e74603a205468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e20666f7220746869732064697370617463682e202d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e202d20604f285329602e202d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e202d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f662020207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2e202d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602e202d20492f4f3a2031207265616420604f285329602c206f6e652072656d6f76652e202d2053746f726167653a2072656d6f766573206f6e65206974656d2e7468726573686f6c647531366f746865725f7369676e61746f726965735665633c543a3a4163636f756e7449643e74696d65706f696e7454696d65706f696e743c543a3a426c6f636b4e756d6265723e63616c6c5f686173685b75383b2033325d20526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e7420696620617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e205061796d656e743a20604d756c74697369674465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c757320607468726573686f6c64602074696d657320604d756c74697369674465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f722069732063616e63656c6c65642e202d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e204966206974206973206e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2e204e4f54453a2049662074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2077616e7420746f20757365206061735f6d756c74696020696e73746561642e202d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292e202d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e202d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c207769746820612020206465706f7369742074616b656e20666f7220697473206c69666574696d65206f66202020604d756c74697369674465706f73697442617365202b207468726573686f6c64202a204d756c74697369674465706f736974466163746f72602e6d617962655f74696d65706f696e744f7074696f6e3c54696d65706f696e743c543a3a426c6f636b4e756d6265723e3e2049662074686572652061726520656e6f7567682c207468656e206469737061746368207468652063616c6c2e202d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e204e4f54453a20556e6c6573732074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2067656e6572616c6c792077616e7420746f207573652060617070726f76655f61735f6d756c74696020696e73746561642c2073696e6365206974206f6e6c7920726571756972657320612068617368206f66207468652063616c6c2e20526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c7420696620607468726573686f6c64602069732065786163746c79206031602e204f7468657277697365206f6e20737563636573732c20726573756c7420697320604f6b6020616e642074686520726573756c742066726f6d2074686520696e746572696f722063616c6c2c206966206974207761732065786563757465642c206d617920626520666f756e6420696e20746865206465706f736974656420604d756c7469736967457865637574656460206576656e742e202d20604f2853202b205a202b2043616c6c29602e202d204f6e652063616c6c20656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285a296020776865726520605a602069732074782d6c656e2e202d2054686520776569676874206f6620746865206063616c6c602e63616c6c426f783c3c542061732054726169743e3a3a43616c6c3e2053656e6420612063616c6c207468726f75676820616e20696e64657865642070736575646f6e796d206f66207468652073656e6465722e202d2054686520776569676874206f6620746865206063616c6c60202b2031302c3030302e2053656e642061206261746368206f662064697370617463682063616c6c732e20546869732077696c6c206578656375746520756e74696c20746865206669727374206f6e65206661696c7320616e64207468656e2073746f702e204d61792062652063616c6c65642066726f6d20616e79206f726967696e2e202d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e202d205468652073756d206f66207468652077656967687473206f6620746865206063616c6c73602e20546869732077696c6c2072657475726e20604f6b6020696e20616c6c2063697263756d7374616e6365732e20546f2064657465726d696e65207468652073756363657373206f66207468652062617463682c20616e206576656e74206973206465706f73697465642e20496620612063616c6c206661696c656420616e64207468652062617463682077617320696e7465727275707465642c207468656e2074686520604261746368496e74657272757074656460206576656e74206973206465706f73697465642c20616c6f6e67207769746820746865206e756d626572206f66207375636365737366756c2063616c6c73206d61646520616e6420746865206572726f72206f6620746865206661696c65642063616c6c2e20496620616c6c2077657265207375636365737366756c2c207468656e2074686520604261746368436f6d706c6574656460206576656e74206973206465706f73697465642e63616c6c735665633c3c542061732054726169743e3a3a43616c6c3e5574696c69747900000000fc7a11000900000002050200000000009db611000c00000000000000b27111000800000000000000057b110034000000000000001cd411003c7b110000000000000000004c7b11000100000000000000000000004d756c7469736967734d756c74697369673c543a3a426c6f636b4e756d6265722c2042616c616e63654f663c543e2c20543a3a4163636f756e7449643e00000016000000000000000100000032000000547b1100250000002054686520736574206f66206f70656e206d756c7469736967206f7065726174696f6e732e000000000000006d92110008000000000000002c7c11000200000000000000000000005c7c11001800000000000000000000009f5611000b000000000000001c7d1100030000000000000000000000647d11000d0000000000000000000000799211000e00000000000000cc7d1100030000000000000000000000147e1100020000000000000000000000aa56110013000000000000002c7c1100020000000000000000000000247e11000600000000000000000000007d7f11000400000000000000d9b211002300000000000000817f11000500000000000000867f11001300000063811100360000001cd41100000000009981110042000000db811100480000002382110045000000688211002d0000001cd411000000000095821100460000001cd41100000000005fb211000b000000db8211004c00000027831100330000005a8311005a0000001cd4110000000000b4831100130000001cd4110000000000c7831100540000001b8411004b00000066841100350000009b84110058000000f384110052000000458511003e0000001cd4110000000000c7b211000c000000000000004c8111000300000000000000d9b2110023000000000000004f8111000800000000000000867f11001300000000000000578111000c00000000000000867f110013000000997f1100250000001cd4110000000000be7f110048000000068011004200000048801100460000008e801100400000001cd4110000000000ce8011002d0000001cd41100000000005fb211000b000000fb801100200000001b81110031000000c7b211000c00000000000000777f11000600000000000000d9b2110023000000000000007d7f11000400000000000000d9b211002300000000000000817f11000500000000000000867f110013000000187f1100540000006c7f11000b000000547e110054000000a87e1100100000001cd4110000000000b87e11002f0000001cd4110000000000e77e1100310000002053616d6520617320746865205b607472616e73666572605d2063616c6c2c206275742077697468206120636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e20393925206f66207468652074696d6520796f752077616e74205b607472616e73666572605d20696e73746561642e205b607472616e73666572605d3a207374727563742e4d6f64756c652e68746d6c236d6574686f642e7472616e736665722045786163746c7920617320607472616e73666572602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74206d6179206265207370656369666965642e736f757263656465737476616c7565436f6d706163743c543a3a42616c616e63653e20536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e63652028606672616d655f73797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e77686f6e65775f667265656e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c20747269676765722060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e636564602e2020202d20607472616e736665725f6b6565705f616c6976656020776f726b73207468652073616d652077617920617320607472616e73666572602c206275742068617320616e206164646974696f6e616c2020202020636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e0000000000c55611000d0000000000000000000000e48611000a000000000000000000000000000000000000000000000000000000000000001cd41100f086110000000000000000000087110001000000000000000100000000000000088711000700000001020000000000009db611000c000000000000000f87110017000000000000000000000000000000000000001cd411002887110000000000000000003887110006000000000000000100000000000000d25611000500000001020000000000009db611000c00000000000000688711001c000000000000000000000000000000000000001cd411008487110000000000000000009487110002000000000000000100000000000000a48711000e0000000000000000000000b287110008000000000000000000000000000000000000000000000000000000000000001cd41100bc8711000000000000000000cc871100030000000000000001000000543a3a42616c616e636500001600000000000000010000003600000093891100260000004163636f756e744163636f756e74446174613c543a3a42616c616e63653e0000160000000000000001000000a5000000a28811001b0000001cd4110000000000bd8811005600000013891100300000001cd411000000000043891100500000005665633c42616c616e63654c6f636b3c543a3a42616c616e63653e3e160000000000000001000000300000002b8811002e000000598811004900000053746f7261676556657273696f6e52656c6561736573000016000000000000000100000031000000e48711001f0000001cd411000000000003881100280000002053746f726167652076657273696f6e206f66207468652070616c6c65742e20546869732069732073657420746f2076322e302e3020666f72206e6577206e6574776f726b732e20416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e204e4f54453a2053686f756c64206f6e6c79206265206163636573736564207768656e2073657474696e672c206368616e67696e6720616e642066726565696e672061206c6f636b2e205468652062616c616e6365206f6620616e206163636f756e742e204e4f54453a2054484953204d4159204e4556455220424520494e204558495354454e434520414e4420594554204841564520412060746f74616c28292e69735f7a65726f2829602e2049662074686520746f74616c2069732065766572207a65726f2c207468656e2074686520656e747279202a4d5553542a2062652072656d6f7665642e204e4f54453a2054686973206973206f6e6c79207573656420696e20746865206361736520746861742074686973206d6f64756c65206973207573656420746f2073746f72652062616c616e6365732e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e000000000000004f5611001200000000000000e48611000a000000000000001cd41100f48911000000000000000000048a11000100000000000000160000000000000001000000a00000000c8a11003500000020546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e000000648a11006a000000a700000009000000648a11006a000000a7000000350000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e332e302f7372632f656e636f64655f617070656e642e72736d6f646c70792f7574696c69737562615a65726f5468726573686f6c64546f6f4665775369676e61746f72696573546f6f4d616e795369676e61746f72696573556e657870656374656454696d65706f696e744e6f54696d65706f696e7457726f6e6754696d65706f696e74416c7265616479417070726f7665644e6f417070726f76616c734e656564656453656e646572496e5369676e61746f726965735369676e61746f726965734f75744f664f72646572000000000000de8a11000d00000000000000d48c11000100000000000000000000003a8b11000f00000000000000dc8c1100010000000000000000000000498b11001100000000000000e48c1100010000000000000000000000eb8a11001100000000000000ec8c1100010000000000000000000000fc8a11001200000000000000f48c11000100000000000000000000006d8b11001500000000000000fc8c11000100000000000000000000005a8b11001300000000000000048d11000100000000000000000000004fa3110008000000000000000c8d1100010000000000000000000000559211000800000000000000148d1100010000000000000000000000218b11000b000000000000001c8d11000100000000000000000000002c8b11000e00000000000000248d11000100000000000000000000000e8b110013000000000000002c8d11000100000000000000bd8f11001d000000918f11002c000000698f1100280000003e8f11002b000000128f11002c000000ce8e1100440000008a8e110044000000528e110038000000068e11004c000000be8d110048000000728d11004c000000348d11003e00000020412074696d65706f696e742077617320676976656e2c20796574206e6f206d756c7469736967206f7065726174696f6e20697320756e6465727761792e204120646966666572656e742074696d65706f696e742077617320676976656e20746f20746865206d756c7469736967206f7065726174696f6e207468617420697320756e6465727761792e204e6f2074696d65706f696e742077617320676976656e2c2079657420746865206d756c7469736967206f7065726174696f6e20697320616c726561647920756e6465727761792e204f6e6c7920746865206163636f756e742074686174206f726967696e616c6c79206372656174656420746865206d756c74697369672069732061626c6520746f2063616e63656c2069742e204d756c7469736967206f7065726174696f6e206e6f7420666f756e64207768656e20617474656d7074696e6720746f2063616e63656c2e205468652073656e6465722077617320636f6e7461696e656420696e20746865206f74686572207369676e61746f726965733b2069742073686f756c646e27742062652e20546865207369676e61746f7269657320776572652070726f7669646564206f7574206f66206f726465723b20746865792073686f756c64206265206f7264657265642e2054686572652061726520746f6f206d616e79207369676e61746f7269657320696e20746865206c6973742e2054686572652061726520746f6f20666577207369676e61746f7269657320696e20746865206c6973742e2043616c6c20646f65736e2774206e65656420616e7920286d6f72652920617070726f76616c732e2043616c6c20697320616c726561647920617070726f7665642062792074686973207369676e61746f72792e205468726573686f6c6420697320746f6f206c6f7720287a65726f292e000000000000915611000e00000000000000bc9011000100000000000000000000007c5611001500000000000000c4901100010000000000000000000000745611000800000000000000cc901100010000000000000000000000615611001300000000000000d49011000100000000000000000000004f5611001200000000000000dc901100010000000000000000000000465611000900000000000000e49011000100000000000000000000002f5611001700000000000000ec901100010000000000000000000000245611000b00000000000000f490110001000000000000001e92110027000000ec91110032000000cf9111001d000000b19111001e000000769111003b00000052911100240000001f91110033000000fc901100230000002042656e6566696369617279206163636f756e74206d757374207072652d657869737420412076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e74205472616e736665722f7061796d656e7420776f756c64206b696c6c206163636f756e742056616c756520746f6f206c6f7720746f20637265617465206163636f756e742064756520746f206578697374656e7469616c206465706f7369742042616c616e636520746f6f206c6f7720746f2073656e642076616c756520476f7420616e206f766572666c6f7720616674657220616464696e67204163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c2056657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c75654e6f745472616e73666572496e5573654e6f744f776e65724e6f7441737369676e6564636c61696d7472616e7366657266726565666f7263655f7472616e736665720000000000e09211000d00000000000000f092110002000000000000000000000000931100010000000000000000000000089311000a00000000000000149311000100000000000000000000001c9311000100000000000000496e64657841737369676e65640000009aa6110009000000549311000c000000609311001e000000496e64657846726565640000549311000c00000024931100300000002041206163636f756e7420696e64657820686173206265656e2066726565642075702028756e61737369676e6564292e4163636f756e74496e6465782041206163636f756e7420696e646578207761732061737369676e65642e417574686f7273686970417574686f724f6c64556e636c65556e636c65416c7265616479496e636c75646564546f6f48696768556e636c6547656e65736973556e636c65546f6f4d616e79556e636c6573556e636c6573416c7265616479536574496e76616c6964556e636c65506172656e747365745f756e636c6573496e64696365734e657874456e756d536574456e756d5365744163636f756e7473556e636c6573000000000000689211000500000000000000d4941100010000000000000000000000ec9411001000000000000000000000006d92110008000000000000006c9511000200000000000000000000009c951100100000000000000000000000759211000400000000000000d49411000100000000000000000000001c961100100000000000000000000000799211000e000000000000006c9511000200000000000000000000009c96110010000000000000000000000034b611000500000000000000489b11000f000000579b1100270000001cd41100000000007e9b1100380000001cd4110000000000b09a1100340000001cd4110000000000b69b11003d0000001cd411000000000061981100250000001cd41100000000005fb211000b000000869811000a0000009098110027000000109a110019000000bab211000d000000c7b211000c000000000000009ab6110003000000000000009db611000c0000000000000034b611000500000000000000489b11000f000000299a110058000000819a11002f0000001cd4110000000000b09a1100340000001cd4110000000000e49a11004a00000009981100580000001cd411000000000061981100250000001cd41100000000005fb211000b000000869811000a00000090981100270000002e9b11001a000000bab211000d000000c7b211000c000000d6981100260000001cd4110000000000fc981100580000001cd411000000000054991100560000001cd4110000000000aa991100440000001cd4110000000000ee991100220000001cd41100000000005fb211000b000000869811000a0000009098110027000000109a110019000000bab211000d000000c7b211000c0000001c97110056000000729711003b0000001cd4110000000000ad971100320000001cd4110000000000df9711002a00000009981100580000001cd411000000000061981100250000001cd41100000000005fb211000b000000869811000a0000009098110027000000b79811001f000000bab211000d000000c7b211000c00000020466f72636520616e20696e64657820746f20616e206163636f756e742e205468697320646f65736e277420726571756972652061206465706f7369742e2049662074686520696e64657820697320616c72656164792068656c642c207468656e20616e79206465706f736974206973207265696d62757273656420746f206974732063757272656e74206f776e65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e202d2060696e646578603a2074686520696e64657820746f206265202872652d2961737369676e65642e202d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e20456d6974732060496e64657841737369676e656460206966207375636365737366756c2e202d20604f283129602e202d204f6e652073746f72616765206d75746174696f6e2028636f64656320604f28312960292e202d20557020746f206f6e652072657365727665206f7065726174696f6e2e204672656520757020616e20696e646578206f776e6564206279207468652073656e6465722e205061796d656e743a20416e792070726576696f7573206465706f73697420706c6163656420666f722074686520696e64657820697320756e726573657276656420696e207468652073656e646572206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206f776e2074686520696e6465782e202d2060696e646578603a2074686520696e64657820746f2062652066726565642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e20456d6974732060496e646578467265656460206966207375636365737366756c2e202d204f6e652072657365727665206f7065726174696f6e2e2041737369676e20616e20696e64657820616c7265616479206f776e6564206279207468652073656e64657220746f20616e6f74686572206163636f756e742e205468652062616c616e6365207265736572766174696f6e206973206566666563746976656c79207472616e7366657272656420746f20746865206e6577206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e202d2060696e646578603a2074686520696e64657820746f2062652072652d61737369676e65642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e202d204f6e65207472616e73666572206f7065726174696f6e2e543a3a4163636f756e74496e6465782041737369676e20616e2070726576696f75736c7920756e61737369676e656420696e6465782e205061796d656e743a20604465706f736974602069732072657365727665642066726f6d207468652073656e646572206163636f756e742e202d2060696e646578603a2074686520696e64657820746f20626520636c61696d65642e2054686973206d757374206e6f7420626520696e207573652e000000000014941100080000000102000000000000489b11000f000000000000004c9c11001c000000000000000000000000000000000000001cd41100689c11000000000000000000789c110001000000000000000000000028543a3a4163636f756e7449642c2042616c616e63654f663c543e2916000000000000000100000032000000809c11002200000020546865206c6f6f6b75702066726f6d20696e64657820746f206163636f756e742e000000000000f19311000a00000000000000d09c1100010000000000000000000000e89c1100010000000000000000000000099d11000a00000000000000139d11000e000000f09c1100190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e000000000000001c9411000600000000000000000000002c9e11003a000000000000000000000000000000000000000000000000000000000000001cd41100689e11000000000000000000789e110001000000000000000100000000000000889311000600000000000000000000009db611000c000000000000000000000000000000000000000000000000000000000000001cd41100809e11000000000000000000909e110001000000000000000000000000000000989e11000c000000000000000000000031cf110004000000000000000000000000000000000000000000000000000000000000001cd41100a49e11000000000000000000b49e11000100000000000000010000005665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e000016000000000000000100000030000000049f11000700000016000000000000000100000032000000eb9e110019000000446964536574556e636c657316000000000000000100000032000000bc9e11002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c65730000000000df9311001200000000000000d09f1100010000000000000000000000cf9311001000000000000000d89f1100010000000000000000000000c29311000d00000000000000e09f1100010000000000000000000000b69311000c00000000000000e89f1100010000000000000000000000aa9311000c00000000000000f09f1100010000000000000000000000969311001400000000000000f89f11000100000000000000000000008e931100080000000000000000a011000100000000000000bda01100230000009ca01100210000008ba011001100000075a011001600000055a011002000000036a011001f00000008a011002e0000002054686520756e636c652069736e277420726563656e7420656e6f75676820746f20626520696e636c756465642e2054686520756e636c6520697320616c726561647920696e636c756465642e2054686520756e636c6520697320746f6f206869676820696e20636861696e2e2054686520756e636c652069732067656e657369732e20546f6f206d616e7920756e636c65732e20556e636c657320616c72656164792073657420696e2074686520626c6f636b2e2054686520756e636c6520706172656e74206e6f7420696e2074686520636861696e2e25a111000d00000008a111001b00000023a111000200000033d311003c000000310200000100000042616420696e70757420646174612070726f766964656420746f203a20657865637574655f626c6f636b00003ca1110010000000696e697469616c697a655f626c6f636b54a111000f0000006170706c795f65787472696e736963006ca1110013000000696e686572656e745f65787472696e736963730088a111000f000000636865636b5f696e686572656e747300a0a111001400000076616c69646174655f7472616e73616374696f6ebca111000f0000006f6666636861696e5f776f726b657200d4a11100150000006c6f63616c5f76616c69646174696f6e5f64617461000000f4a111000e00000070617261636861696e5f636f646500000ca21100090000006765745f686561647300000020a211001500000067656e65726174655f73657373696f6e5f6b65797300000040a21100130000006465636f64655f73657373696f6e5f6b657973005ca211000d0000006163636f756e745f6e6f6e636500000074a211000a00000071756572795f696e666f000088a211001a0000004552524f523a20436f72727570746564207374617465206174200000aca211002a000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a20546f6f4d616e794669656c6473496e76616c6964546172676574496e76616c6964496e646578496e76616c69644a756467656d656e744a756467656d656e74476976656e537469636b794a756467656d656e744e6f4964656e746974794665654368616e676564456d707479496e6465784e6f744e616d65644e6f74466f756e64546f6f4d616e795375624163636f756e74736164645f7265676973747261727365745f6964656e746974797365745f73756273636c6561725f6964656e74697479726571756573745f6a756467656d656e7463616e63656c5f726571756573747365745f6665657365745f6163636f756e745f69647365745f6669656c647370726f766964655f6a756467656d656e746b696c6c5f6964656e746974794964656e7469747953757065724f66000000000038a511000b0000000000000044a511000100000000000000000000004ca5110001000000000000000000000054a511000f0000000000000064a5110002000000000000000000000074a511000100000000000000000000007ca511000e0000000000000064a511000200000000000000000000008ca5110001000000000000000000000094a511001200000000000000a8a51100020000000000000000000000b8a51100010000000000000000000000c0a511001400000000000000a8a51100020000000000000000000000d4a511000100000000000000000000000ca311000e00000000000000a8a51100020000000000000000000000dca51100010000000000000000000000e4a511000e00000000000000f4a51100010000000000000000000000fca5110001000000000000004964656e74697479536574009aa611000900000010a711003c0000004964656e74697479436c6561726564009aa611000900000009a7110007000000d5a61100340000004964656e746974794b696c6c65640000a3a61100320000004a756467656d656e7452657175657374656400009aa61100090000001ba611000e00000072a61100280000004a756467656d656e74556e7265717565737465644fa611002300000029a6110026000000526567697374726172416464656400001ba611000e00000004a6110017000000204120726567697374726172207761732061646465642e526567697374726172496e6465782041206a756467656d656e742077617320676976656e2062792061207265676973747261722e2041206a756467656d656e74207265717565737420776173207265747261637465642e2041206a756467656d656e74207761732061736b65642066726f6d2061207265676973747261722e4163636f756e7449642041206e616d65207761732072656d6f76656420616e642074686520676976656e2062616c616e636520736c61736865642e2041206e616d652077617320636c65617265642c20616e642074686520676976656e2062616c616e63652072657475726e65642e42616c616e63652041206e616d652077617320736574206f72207265736574202877686963682077696c6c2072656d6f766520616c6c206a756467656d656e7473292e54a71100230000005f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e000000000069a311000d000000000000005ca9110001000000000000000000000074a911000d000000000000000000000076a311000c00000000000000dca91100010000000000000000000000f4a9110012000000000000000000000082a31100080000000000000084aa11000100000000000000000000009caa11001000000000000000000000008aa311000e000000000000001cd411000000000000000000000000001cab11000f000000000000000000000098a31100110000000000000094ab1100020000000000000000000000c4ab1100170000000000000000000000a9a311000e000000000000007cac110001000000000000000000000094ac1100110000000000000000000000b7a3110007000000000000001cad11000200000000000000000000004cad11000c0000000000000000000000bea311000e00000000000000acad1100020000000000000000000000dcad11000c0000000000000000000000cca311000a000000000000003cae11000200000000000000000000006cae11000c0000000000000000000000d6a311001100000000000000ccae110003000000000000000000000014af1100130000000000000000000000e7a311000d00000000000000acaf1100010000000000000000000000c4af1100130000000000000000000000f9bf110007000000000000009db611000c000000e2be11001f0000001cd411000000000001bf1100470000001cd411000000000048bf11002b0000001cd411000000000073bf1100260000001cd41100000000005fb211000b00000099bf110039000000d2bf110027000000bab211000d000000c7b211000c00000000000000d2be11000400000000000000d6be11000c00000035bd11004b0000001cd411000000000080bd110056000000d6bd1100150000001cd4110000000000c1ba1100590000001abb11000a0000001cd4110000000000ebbd1100240000001cd41100000000000fbe1100230000001cd41100000000005fb211000b00000032be11005700000090bc11002200000089be110049000000bab211000d000000c7b211000c0000000000000018bd110004000000000000001cbd11001900000068bb1100240000001cd41100000000008cbb110056000000e2bb11004c0000001cd4110000000000c1ba1100590000001abb11000a0000001cd41100000000002ebc1100270000001cd41100000000005fb211000b00000055bc11003b00000090bc110022000000b2bc11005000000002bd110016000000c7b211000c00000037ba11004e0000001cd411000000000085ba11003c0000001cd4110000000000c1ba1100590000001abb11000a0000001cd411000000000024bb1100270000001cd41100000000005fb211000b0000006ab21100120000007cb21100210000004bbb11001d000000bab211000d000000c7b211000c00000000000000f5b411000900000000000000feb41100170000000000000030ba1100070000000000000009b71100150000007cb81100260000001cd4110000000000a2b8110056000000f8b81100070000001cd411000000000078b711004e000000c6b71100150000001cd4110000000000ffb811004800000047b91100560000001cd41100000000009db911000d000000aab9110029000000d3b91100040000001cd4110000000000d7b911002a0000001cd41100000000005fb211000b00000070b411000e0000007cb211002100000001ba11002f000000bab211000d000000c7b211000c00000000000000f5b4110009000000000000001ba611000e0000001eb711001b0000001cd411000000000039b711003f0000001cd411000000000078b711004e000000c6b71100150000001cd4110000000000dbb71100520000001cd41100000000002db811002c0000001cd41100000000005fb211000b00000070b411000e0000007cb211002100000059b8110023000000bab211000d000000c7b211000c0000000000000034b611000500000000000000feb41100170000000000000006b71100030000000000000009b7110015000000a9b61100470000001cd41100000000002bb311005600000060b51100290000001cd411000000000089b511003e000000f0b61100160000001cd41100000000005fb211000b0000000bb611000a00000015b611001f000000c7b211000c0000000000000034b611000500000000000000feb4110017000000000000009ab6110003000000000000009db611000c0000004db61100300000001cd41100000000002bb311005600000060b51100290000001cd411000000000089b511003e0000007db611001d0000001cd41100000000005fb211000b0000000bb611000a00000015b611001f000000c7b211000c0000000000000034b611000500000000000000feb41100170000000000000039b6110006000000000000003fb611000e00000035b511002b0000001cd41100000000002bb311005600000060b51100290000001cd411000000000089b511003e000000c7b51100440000001cd41100000000005fb211000b0000000bb611000a00000015b611001f000000c7b211000c00000000000000f5b411000900000000000000feb411001700000000000000d3b211000600000000000000d9b21100230000000000000015b5110009000000000000001eb5110017000000fcb211002f0000001cd41100000000002bb311005600000081b311002d0000001cd4110000000000aeb3110049000000c5b11100560000001bb211001e000000f7b31100530000001cd41100000000004ab41100260000001cd41100000000005fb211000b00000070b411000e0000007eb4110022000000a0b4110026000000c6b411002f000000bab211000d000000c7b211000c00000000000000d3b211000600000000000000d9b21100230000005cb01100510000001cd4110000000000adb011005900000006b111005200000058b11100210000001cd411000000000079b111004c0000001cd4110000000000c5b11100560000001bb211001e0000001cd411000000000039b21100260000001cd41100000000005fb211000b0000006ab21100120000007cb21100210000009db211001d000000bab211000d000000c7b211000c0000002052656d6f766520616e206163636f756e742773206964656e7469747920616e64207375622d6163636f756e7420696e666f726d6174696f6e20616e6420736c61736820746865206465706f736974732e205061796d656e743a2052657365727665642062616c616e6365732066726f6d20607365745f737562736020616e6420607365745f6964656e74697479602061726520736c617368656420616e642068616e646c65642062792060536c617368602e20566572696669636174696f6e2072657175657374206465706f7369747320617265206e6f742072657475726e65643b20746865792073686f756c642062652063616e63656c6c6564206d616e75616c6c79207573696e67206063616e63656c5f72657175657374602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f206f72206d617463682060543a3a466f7263654f726967696e602e202d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e742020207769746820612072656769737465726564206964656e746974792e20456d69747320604964656e746974794b696c6c656460206966207375636365737366756c2e2023203c7765696768743e202d20604f2852202b2053202b205829602e202d204f6e652062616c616e63652d72657365727665206f7065726174696f6e2e202d206053202b2032602073746f72616765206d75746174696f6e732e202d204f6e65206576656e742e2023203c2f7765696768743e7461726765743c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263652050726f766964652061206a756467656d656e7420666f7220616e206163636f756e742773206964656e746974792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74206f6620746865207265676973747261722077686f736520696e64657820697320607265675f696e646578602e202d20607265675f696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206265696e67206d6164652e202d20606a756467656d656e74603a20746865206a756467656d656e74206f662074686520726567697374726172206f6620696e64657820607265675f696e646578602061626f75742060746172676574602e20456d69747320604a756467656d656e74476976656e60206966207375636365737366756c2e202d20604f2852202b205829602e202d204f6e652062616c616e63652d7472616e73666572206f7065726174696f6e2e202d20557020746f206f6e65206163636f756e742d6c6f6f6b7570206f7065726174696f6e2e202d2053746f726167653a2031207265616420604f285229602c2031206d757461746520604f2852202b205829602e7265675f696e646578436f6d706163743c526567697374726172496e6465783e6a756467656d656e744a756467656d656e743c42616c616e63654f663c543e3e2053657420746865206669656c6420696e666f726d6174696f6e20666f722061207265676973747261722e206f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e202d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e202d20606669656c6473603a20746865206669656c64732074686174207468652072656769737472617220636f6e6365726e73207468656d73656c76657320776974682e202d20604f285229602e202d204f6e652073746f72616765206d75746174696f6e20604f285229602e696e6465786669656c64734964656e746974794669656c6473204368616e676520746865206163636f756e74206173736f63696174656420776974682061207265676973747261722e202d20606e6577603a20746865206e6577206163636f756e742049442e6e6577543a3a4163636f756e74496420536574207468652066656520726571756972656420666f722061206a756467656d656e7420746f206265207265717565737465642066726f6d2061207265676973747261722e202d2060666565603a20746865206e6577206665652e666565436f6d706163743c42616c616e63654f663c543e3e2043616e63656c20612070726576696f757320726571756573742e205061796d656e743a20412070726576696f75736c79207265736572766564206465706f7369742069732072657475726e6564206f6e20737563636573732e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564206964656e746974792e202d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206e6f206c6f6e676572207265717565737465642e20456d69747320604a756467656d656e74556e72657175657374656460206966207375636365737366756c2e202d204f6e652073746f72616765206d75746174696f6e20604f2852202b205829602e20526571756573742061206a756467656d656e742066726f6d2061207265676973747261722e205061796d656e743a204174206d6f737420606d61785f666565602077696c6c20626520726573657276656420666f72207061796d656e7420746f2074686520726567697374726172206966206a756467656d656e7420676976656e2e202d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973207265717565737465642e202d20606d61785f666565603a20546865206d6178696d756d206665652074686174206d617920626520706169642e20546869732073686f756c64206a757374206265206175746f2d706f70756c617465642061733a206060606e6f636f6d70696c652053656c663a3a72656769737472617273287265675f696e646578292e756e7772617028292e6665652060606020456d69747320604a756467656d656e7452657175657374656460206966207375636365737366756c2e202d2053746f726167653a2031207265616420604f285229602c2031206d757461746520604f2858202b205229602e6d61785f66656520436c65617220616e206163636f756e742773206964656e7469747920696e666f20616e6420616c6c207375622d6163636f756e7420616e642072657475726e20616c6c206465706f736974732e205061796d656e743a20416c6c2072657365727665642062616c616e636573206f6e20746865206163636f756e74206172652072657475726e65642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564206964656e746974792e20456d69747320604964656e74697479436c656172656460206966207375636365737366756c2e202d206053202b2032602073746f726167652064656c6574696f6e732e2053657420746865207375622d6163636f756e7473206f66207468652073656e6465722e205061796d656e743a20416e79206167677265676174652062616c616e63652072657365727665642062792070726576696f757320607365745f73756273602063616c6c732077696c6c2062652072657475726e656420616e6420616e20616d6f756e7420605375624163636f756e744465706f736974602077696c6c20626520726573657276656420666f722065616368206974656d20696e206073756273602e202d206073756273603a20546865206964656e746974792773207375622d6163636f756e74732e202d20604f285329602077686572652060536020737562732d636f756e742028686172642d20616e64206465706f7369742d626f756e646564292e202d204174206d6f73742074776f2062616c616e6365206f7065726174696f6e732e202d204174206d6f7374204f2832202a2053202b2031292073746f72616765206d75746174696f6e733b20636f64656320636f6d706c657869747920604f2831202a2053202b2053202a20312960293b2020206f6e652073746f726167652d6578697374732e737562735665633c28543a3a4163636f756e7449642c2044617461293e2053657420616e206163636f756e742773206964656e7469747920696e666f726d6174696f6e20616e6420726573657276652074686520617070726f707269617465206465706f7369742e20496620746865206163636f756e7420616c726561647920686173206964656e7469747920696e666f726d6174696f6e2c20746865206465706f7369742069732074616b656e2061732070617274207061796d656e7420666f7220746865206e6577206465706f7369742e202d2060696e666f603a20546865206964656e7469747920696e666f726d6174696f6e2e20456d69747320604964656e7469747953657460206966207375636365737366756c2e202d20604f2858202b205827202b2052296020776865726520605860206164646974696f6e616c2d6669656c642d636f756e7420286465706f7369742d626f756e64656420616e6420636f64652d626f756e646564292e202d204f6e652073746f72616765206d75746174696f6e2028636f6465632d7265616420604f285827202b205229602c20636f6465632d777269746520604f2858202b20522960292e696e666f4964656e74697479496e666f2041646420612072656769737472617220746f207468652073797374656d2e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605265676973747261724f726967696e60206f722060526f6f74602e202d20606163636f756e74603a20746865206163636f756e74206f6620746865207265676973747261722e20456d6974732060526567697374726172416464656460206966207375636365737366756c2e202d20604f2852296020776865726520605260207265676973747261722d636f756e742028676f7665726e616e63652d626f756e646564292e202d204f6e652073746f72616765206d75746174696f6e2028636f64656320604f28522960292e6163636f756e740000000060c111000a00000001050000000000009db611000c000000000000006ac111001a000000000000000000000000000000000000001cd4110084c11100000000000000000094c1110001000000000000000000000000000000fca311000700000001020000000000009db611000c000000000000009cc1110014000000000000000000000000000000000000001cd41100b0c111000000000000000000c0c1110002000000000000000000000000000000d0c111000600000001050000000000009db611000c00000000000000d6c1110021000000000000000000000000000000000000001cd41100f8c11100000000000000000008c211000300000000000000010000000000000020c211000a00000000000000000000002ac2110036000000000000000000000000000000000000000000000000000000000000001cd4110060c21100000000000000000070c211000400000000000000010000004964656e746974794f66526567697374726174696f6e3c42616c616e63654f663c543e3e1600000000000000010000003200000078c411004800000028543a3a4163636f756e7449642c20446174612916000000000000000100000032000000ccc311005800000024c4110054000000537562734f662842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e2900160000000000000001000000a600000057c311002e0000001cd411000000000085c3110047000000526567697374726172735665633c4f7074696f6e3c526567697374726172496e666f3c42616c616e63654f663c543e2c20543a3a4163636f756e7449643e3e3e1600000000000000010000003000000090c2110053000000e3c211002a0000001cd41100000000000dc311004a0000002054686520736574206f6620726567697374726172732e204e6f7420657870656374656420746f206765742076657279206269672061732063616e206f6e6c79206265206164646564207468726f7567682061207370656369616c206f726967696e20286c696b656c79206120636f756e63696c206d6f74696f6e292e2054686520696e64657820696e746f20746869732063616e206265206361737420746f2060526567697374726172496e6465786020746f2067657420612076616c69642076616c75652e20416c7465726e6174697665202273756222206964656e746974696573206f662074686973206163636f756e742e20546865206669727374206974656d20697320746865206465706f7369742c20746865207365636f6e64206973206120766563746f72206f6620746865206163636f756e74732e205468652073757065722d6964656e74697479206f6620616e20616c7465726e6174697665202273756222206964656e7469747920746f676574686572207769746820697473206e616d652c2077697468696e207468617420636f6e746578742e20496620746865206163636f756e74206973206e6f7420736f6d65206f74686572206163636f756e742773207375622d6964656e746974792c207468656e206a75737420604e6f6e65602e20496e666f726d6174696f6e20746861742069732070657274696e656e7420746f206964656e746966792074686520656e7469747920626568696e6420616e206163636f756e742e30c5110045000000be0300002200000030c5110045000000da0300001500000030c5110045000000e80300001e00000030c5110045000000f10300001800000030c5110045000000f20300001900000030c5110045000000f50300001a00000030c5110045000000fb0300000d0000002f72757374632f366465653566313132366466643563393331346565356165396439656230313065333565663235372f7372632f6c6962616c6c6f632f736c6963652e7273696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f6465000000c0c511005e0000008f0200001d000000c0c511005e00000039030000360000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f6964656e746974792f7372632f6c69622e727300000000000057a31100120000000000000070c711000100000000000000000000004fa31100080000000000000078c7110001000000000000000000000047a31100080000000000000080c711000100000000000000000000003da311000a0000000000000088c7110001000000000000000000000033a311000a0000000000000090c7110001000000000000000000000029a311000a0000000000000098c711000100000000000000000000001aa311000f00000000000000a0c711000100000000000000000000000ca311000e00000000000000a8c71100010000000000000000000000fca211001000000000000000b0c71100010000000000000000000000f0a211000c00000000000000b8c71100010000000000000000000000e3a211000d00000000000000c0c71100010000000000000000000000d6a211000d00000000000000c8c711000100000000000000a9c811001800000094c81100150000007fc811001500000072c811000d00000062c81100100000004fc81100130000003dc81100120000002cc811001100000019c811001300000003c8110016000000ecc7110017000000d0c711001c00000020546f6f206d616e79206164646974696f6e616c206669656c64732e205468652074617267657420697320696e76616c69642e2054686520696e64657820697320696e76616c69642e20496e76616c6964206a756467656d656e742e204a756467656d656e7420676976656e2e20537469636b79206a756467656d656e742e204e6f206964656e7469747920666f756e642e20466565206973206368616e6765642e20456d70747920696e6465782e204163636f756e742069736e2774206e616d65642e204163636f756e742069736e277420666f756e642e20546f6f206d616e7920737562732d6163636f756e74732e000000d4c8110055000000310600001b0000002f72757374632f366465653566313132366466643563393331346565356165396439656230313065333565663235372f7372632f6c6962616c6c6f632f636f6c6c656374696f6e732f62747265652f6d61702e7273436f756c64206e6f74206465636f64652072657175657374656420696e686572656e74207479706521000064c911006b000000ae000000050000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f737570706f72742f7372632f73746f726167652f6d6967726174696f6e2e72730064c911006b000000af0000000500000054696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b002cd411004900000022000000090000007061726974792f7374616b696e672d656c656374696f6e2f54696d657374616d704e6f77736574616c726561647920626f72726f7765640064ca1100430000006e030000090000002f72757374632f366465653566313132366466643563393331346565356165396439656230313065333565663235372f7372632f6c6962636f72652f63656c6c2e7273616c7265616479206d757461626c7920626f72726f7765640064ca1100430000001e0300000900000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565001600000000000000010000002b0000001600000000000000010000002a0000002ccb11000600000032cb110010000000496e64657820206f7574206f6620626f756e64733a2066696e616c6e756d000064c911006b00000047000000230000006ccb11006f00000075000000450000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f737570706f72742f7372632f73746f726167652f67656e657261746f722f6d61702e727353657373696f6e486973746f726963616c53657373696f6e73a70000005800000008000000a8000000a900000018cc11005d0000004d0000001c0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f747269652d64622d302e32302e302f7372632f6e6962626c652f6d6f642e72730000000000000040ca11000300000000000000a4cc1100010000000000000000000000bccc11000900000000000000000000003ece1100030000000000000041ce11001200000004cd1100160000001cd41100000000001acd11005600000070cd1100360000001cd4110000000000a6cd110051000000f7cd1100110000001cd411000000000008ce11003600000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e6e6f77436f6d706163743c543a3a4d6f6d656e743e00000000003dca110003000000000000000000000004cf110009000000000000000000000000000000000000000000000000000000000000001cd4110010cf1100000000000000000020cf11000100000000000000010000000000000028cf110009000000000000000000000031cf110004000000000000000000000000000000000000000000000000000000000000001cd4110038cf1100000000000000000048cf1100010000000000000001000000543a3a4d6f6d656e74000000160000000000000001000000990000007dcf110024000000446964557064617465626f6f6c0000001600000000000000010000003200000050cf11002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e00000000000000dccf11000d0000000000000004cf110009000000000000001cd41100eccf11000000000000000000fccf110004000000000000004d696e696d756d506572696f64000000160000000000000001000000aa0000001cd011005a00000076d011005a000000d0d011005900000029d111001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e54696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b54696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b734765747320616e64206465636f6465732074696d657374616d7020696e686572656e74206461746100ab0000001000000004000000ac0000000cd211005f000000d00000001f0000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f6672616d652f74696d657374616d702f7372632f6c69622e72735468657265206973206f6e6c79206f6e6520666174616c206572726f723b207165640000001600000008000000040000009400000033d311003c000000dd0100000100000054696d657374616d7020746f6f2066617220696e2066757475726520746f20616363657074496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473214e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f72212f686f6d652f6461766964642f6465762f706f6c6b61646f742d77657374656e642f72756e74696d652f77657374656e642f7372632f6c69622e727300617474656d707420746f20646976696465206279207a65726f000000a4d311002d000000d1d311000c000000ddd3110003000000617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a20e8d311003400000064657374696e6174696f6e20616e6420736f7572636520736c69636573206861766520646966666572656e74206c656e677468732cd411004900000028000000090000002f72757374632f366465653566313132366466643563393331346565356165396439656230313065333565663235372f7372632f6c6962636f72652f6d6163726f732f6d6f642e72730000001600000008000000040000002c00000071202f206365696c28712f246d617829203c20246d61782e204d6163726f2070726576656e747320616e792074797065206265696e672063726561746564207468617420646f6573206e6f74207361746973667920746869733b207165640000f8d411006c00000064010000270000002f686f6d652f6461766964642f2e636172676f2f6769742f636865636b6f7574732f7375627374726174652d376530383433336434633337306132312f316439373339372f7072696d6974697665732f61726974686d657469632f7372632f7065725f7468696e67732e7273f8d411006c0000006b01000027000000f8d411006c00000076010000210000004661696c656420746f20636f6e76657274004198abc7000b08000000000000000000f69f03046e616d6501ed9f03aa0500196578745f6c6f6767696e675f6c6f675f76657273696f6e5f31012a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f3102246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f3103296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f31041e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f31051c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f31061a6578745f73746f726167655f726561645f76657273696f6e5f3107376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f3108286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f3109216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f310a1d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f310b1c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f310c1e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f310d1d6578745f68617368696e675f74776f785f36345f76657273696f6e5f310e196578745f73746f726167655f7365745f76657273696f6e5f310f206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f3110196578745f73746f726167655f6765745f76657273696f6e5f31111b6578745f73746f726167655f636c6561725f76657273696f6e5f3112226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f3113236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f3214286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f3115346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f3116286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f3117226578745f6d6973635f72756e74696d655f76657273696f6e5f76657273696f6e5f3118206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f31191e6578745f73746f726167655f6e6578745f6b65795f76657273696f6e5f311a1a6578745f73746f726167655f726f6f745f76657273696f6e5f311b226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f311c236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f311d1c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f311e236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f311f256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f3120256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f31210c5f5f727573745f616c6c6f63220a5f5f72675f616c6c6f63230e5f5f727573745f6465616c6c6f63240c5f5f72675f6465616c6c6f63250e5f5f727573745f7265616c6c6f63260c5f5f72675f7265616c6c6f6327135f5f727573745f616c6c6f635f7a65726f656428115f5f72675f616c6c6f635f7a65726f65642909686173685f746573742a33616c6c6f633a3a616c6c6f633a3a68616e646c655f616c6c6f635f6572726f723a3a68613566306535653834326364613163302b08727573745f6f6f6d2c34616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68333466326439363261306133656336382d29636f72653a3a70616e69636b696e673a3a70616e69633a3a68363666663863623431656237393339322e673c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c26542c636f72653a3a736c6963653a3a497465723c543e3e3e3a3a737065635f657874656e643a3a68643134313632623662636165643561392f25616c6c6f633a3a666d743a3a666f726d61743a3a68383765613432376665623761323738653036636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a68303262666133616364666639366234373123636f72653a3a666d743a3a77726974653a3a68376435353637373938616236653862383248616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303333623066313762636138353139633348616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303030303461356163313563353166393433636f72653a3a6f7074696f6e3a3a6578706563745f6e6f6e655f6661696c65643a3a6835373432343139313566633864343931353a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6835653233323038336335343963653133363b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6861326264383531623736356263653636373a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6839653534623965393531623637353032383c616c6c6f633a3a7665633a3a5665633c543e3a3a696e736572743a3a6173736572745f6661696c65643a3a6837623736633238353166313361343339394e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a68353033646134666265376565343631353a2d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a68363561333939373462633735646131633b3c616c6c6f633a3a7665633a3a5665633c543e3a3a72656d6f76653a3a6173736572745f6661696c65643a3a68303134313932333463366237343964383c3f616c6c6f633a3a7665633a3a5665633c543e3a3a647261696e3a3a656e645f6173736572745f6661696c65643a3a68363563643736346262663266323636613d39636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653a3a63616c6c5f6f6e63653a3a68646338643634393661373862643066333e2f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a68393738396630323639633064616665643f11727573745f626567696e5f756e77696e6440313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a68356430383831303839366462353536324135636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a68333034343734646238383737386466344243636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a68326165326132306532373661633532334334636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68623532376436336130376365343861384436636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a6833666139386131373562356566303330452c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a6863376136613262346230386533623339462e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a686438346436643138336338303230356147323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6834666233316133633762663631626138484a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683362333865333364373738623631333949323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68353835643432366237393961616636664a47636f72653a3a756e69636f64653a3a756e69636f64655f646174613a3a6772617068656d655f657874656e643a3a6c6f6f6b75703a3a68313030666232373836323430336137394b32636f72653a3a756e69636f64653a3a7072696e7461626c653a3a636865636b3a3a68316533316630666162356466373231394c49636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a68613266303731633335633466623437354d453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68336136393861346565626438306261334e483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68363430343466643666663439646637354f2e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a683762353636393261313435626665656150303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683233386463363831353065393366393051323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683136393133643238656262376364396452533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6831653333623633613261643465323036532e636f72653a3a736c6963653a3a6d656d6368723a3a6d656d6368723a3a6834616435376236623738633262663264542f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a6861383962343039653035353263356439552e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a6833373932646664386336376430633834563a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6838323430376561663662663939633330573b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6865373233653834313363656164393266583a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68393630336533353761316331373136305939636f72653a3a666d743a3a6275696c646572733a3a44656275675475706c653a3a6669656c643a3a68653930303364656631636662623461315a37636f72653a3a666d743a3a6275696c646572733a3a44656275675365743a3a656e7472793a3a68666664653036363031663966383231615b443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68663066336439353534333334333736365c313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68653366393638646530643165353739635d8001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a68663163333665343366373434383062645e4a636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a557070657248657820666f72206933323e3a3a666d743a3a68306566613962626536663832373035625f3e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686363643639613534353464323764663160693c6672616d655f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6866393237336565633130363664363332616c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683831363537383736353164303031623962543c616c6c6f633a3a7665633a3a5665633c75383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4f75747075743e3a3a77726974653a3a683831663631373464316234396461626263693c6672616d655f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683465323863386362363432393166663864483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683561636630613031653733626661643265513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6835666331623361363635616636646635663a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6866323433643738363163353565643432673b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6837363933613834333232363936333435683a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a683030336338373633653031613564393369503c6672616d655f737570706f72743a3a64656275673a3a57726974657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68393138666634306466623732653137666a4d3c6672616d655f737570706f72743a3a64656275673a3a52756e74696d654c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a68373438616538653039663533353263346b493c6672616d655f737570706f72743a3a64656275673a3a52756e74696d654c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a68353833383562353631393061373138346c323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68326437616361633934393938386663666d383c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a68313635636264653130373738626661366e343c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a68316537646531373862303632353066646f363c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a666c7573683a3a686330386661623861626464323931353670573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a683166393166363335356463663439333871513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6837343166373632333632653630396463724470616c6c65745f7374616b696e673a3a736c617368696e673a3a536c617368696e675370616e733a3a656e645f7370616e3a3a6834316632383830393436626164636130733a70616c6c65745f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a683762343364383634633038303235643974453c737472206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a683738393536623938373434353332616675497061726974795f7363616c655f636f6465633a3a656e636f64655f617070656e643a3a657874726163745f6c656e6774685f646174613a3a68626562323562623531333530323231377649706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a6c6f63616c697a65645f7061796c6f61643a3a6833383634376435326266336530653564778f0173705f6170706c69636174696f6e5f63727970746f3a3a737232353531393a3a3c696d706c2073705f6170706c69636174696f6e5f63727970746f3a3a7472616974733a3a52756e74696d655075626c696320666f722073705f636f72653a3a737232353531393a3a5075626c69633e3a3a746f5f7261775f7665633a3a6830323336333330373665666133393437783a73705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6c73747269703a3a68653631613634643963353264626661337937616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68303338373933363166386665623939667a3773705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6164643a3a68643366623862373461373433306636307b3773705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6d756c3a3a68663562373933353463313266626130347c4473705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6469763a3a7b7b636c6f737572657d7d3a3a68396630616564646264323235393838647d4b3c73705f61726974686d657469633a3a62696775696e743a3a42696755696e7420617320636f72653a3a636d703a3a4f72643e3a3a636d703a3a68616639346234613463396436613637337e303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68343338323065613565383161376164667f513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68616337353132373437623231633331328001533c73705f61726974686d657469633a3a726174696f6e616c3132383a3a526174696f6e616c31323820617320636f72653a3a636d703a3a4f72643e3a3a636d703a3a68333961353536316231313935646535328101583c73705f61726974686d657469633a3a726174696f6e616c3132383a3a526174696f6e616c31323820617320636f72653a3a636d703a3a5061727469616c45713e3a3a65713a3a683635663962613162653061386461663582014673705f61726974686d657469633a3a68656c706572735f3132386269743a3a6d756c7469706c795f62795f726174696f6e616c3a3a68353631336631643166653764376130648301413c73705f696e686572656e74733a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68653966306436343262373237303338338401323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683932383631623732643636373830303685015373705f696f3a3a747269653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a626c616b65325f3235365f6f7264657265645f726f6f743a3a683237353166653436323632626363663086013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a683135393463663930333639613536363887014d73705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6e6574776f726b5f73746174653a3a683861323231326432316162643535363688016b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683135633235363439303230313262373689015273705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a7375626d69745f7472616e73616374696f6e3a3a68316138356633396338396461356432358a014273705f696f3a3a6c6f6767696e673a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6c6f673a3a68643061646133306361666263646662658b017c3c73705f72756e74696d655f696e746572666163653a3a706173735f62793a3a436f6465633c543e2061732073705f72756e74696d655f696e746572666163653a3a706173735f62793a3a506173734279496d706c3c543e3e3a3a66726f6d5f6666695f76616c75653a3a68386139333065303664303835323036318c014373705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a726561643a3a68323232633565356466636531326539328d016073705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a736563703235366b315f65636473615f7265636f7665725f636f6d707265737365643a3a68613662616263396135373562666662668e015173705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7075626c69635f6b6579733a3a68396538393663383766313161663966638f014a73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7369676e3a3a686161323163336361383964343539356390016b3c73705f72756e74696d653a3a72756e74696d655f737472696e673a3a52756e74696d65537472696e67206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a68383762316535643134643833353861369101573c73705f72756e74696d653a3a72756e74696d655f737472696e673a3a52756e74696d65537472696e6720617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68373962343532323633623762333434309201563c73705f72756e74696d653a3a44697370617463684572726f722061732073705f72756e74696d653a3a7472616974733a3a5072696e7461626c653e3a3a7072696e743a3a68653532633735643832376263393837379301473c73705f72756e74696d653a3a44697370617463684572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683432313763363131306163363733313694015373705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a6863313236323538333436393737316233950137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830656266303934386562353161656662960137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830323864626364336261323465376165970137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830346165646465316238656461656263980137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830366133316534643838346265663937990137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68306465323236643037383231376261659a0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68313063316434636466306162353034619b0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68313662656237383266336137616234359c0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68313663326163383733306431306163369d0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68313663653363616631623862326338309e0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68313738396537646266633964656364639f0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832343231303632316130363633613431a00137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832626236363631366531653331646535a10137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6833333164323936613962353331396563a20137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6833333361353236306363336133653431a30137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6833386533343739656634333431376533a40137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6833653333353535383965393733623366a50137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6833663165663462316532393738643463a60137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6834323334386532333735386132383464a70137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6835343137393662316566653439353563a80137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6836303065633731313864646564326161a90137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6836613366336437653962363163336139aa0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6837623362353933356564666635383661ab0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6838346162383335386563333632626336ac0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6838623162653838663535653931393433ad0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6838663231386161646630656236373166ae0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6839623230386430323934316635396236af0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6839653933623431643436313532653334b00137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6862303866636166383838376464366631b10137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6863323036643834636438373161313330b20137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6863363432666365613430306632306639b30137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6863396339336238353137383466633263b40137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6864626635386530323162353737343735b50137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6864663937313135633231653236396233b60137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6865353161616562636535656435633565b70137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6866303438623961346238326237373730b8015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839613863363232393032313264393064b9013b70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a7265776172645f62795f6964733a3a6830306561316432343034306133643162ba01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838326239383031383336303662326137bb01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830333037303132623534363464613363bc014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6863356536386137343264353734663234bd01723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6838373437626530383763326131616336be01613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6865313163353764643239336165356663bf01706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6833646134613838393766663064643263c001706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6838663461646337313934333639613966c1015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6834363833636532653735653861323139c2015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6836396462666264633533383163303834c3015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6838656239386662656262336237313063c4015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863303635313435636430353265316237c5015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864343237313535616237363232323466c6015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865303539653965343561333634303634c7015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6866656332313335656630373333386231c801746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6864666262356366663062653536636663c901386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835323363313333323765303438326266ca015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832333662383662323763363339323330cb015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864333534313630333032316663376433cc013570616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6e65775f6572613a3a6832393366393663646338616233313366cd01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836323630366538656161663937626434ce014370616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a636c6561725f6572615f696e666f726d6174696f6e3a3a6831316338326363633735366330333032cf01543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6861643530643064653130303131663431d001860170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7374616b696e673a3a4578706f737572653c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a6836663235373639653330666264376361d101303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837343463396664633263333139396335d2018b013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61704974657261746f723c4b2c562c4861736865723e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6835613263666334326538626534353165d3014270616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a736c61736861626c655f62616c616e63655f6f663a3a6838353036356239653438636231353732d401533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6834656136343735313539303434623265d50148616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6833366165383765323137636162333536d601633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a666f6c643a3a6836386133653736323666303732306131d701386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864343765656537313161623363306134d8013173705f70687261676d656e3a3a6275696c645f737570706f72745f6d61703a3a6834303731633439383437383934643037d901513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6862313830303239316633366339643337da01706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6863373464656161333362323066343862db01723c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6861303533613666646362636437316637dc012d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6838316566343264643165656634626237dd01706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6864336136306435333062353538646639de01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837346533313037313266323235383037df01706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6862363661636232386331343538373638e001416672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6576656e745f696e64657865643a3a6831623763393439636230613135666264e101386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836333338363337363464356338616463e201386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838613262346631303237346362646231e3013770616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a73746172745f6572613a3a6863616164396463616561326336306332e401386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864633430623162363962646439636237e501386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830636262636437363861393638306565e6014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6864396433363235356565353731636632e7015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833376533646636656631316233363531e801386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865633165366363623935343639343731e9013570616c6c65745f7374616b696e673a3a736c617368696e673a3a646f5f736c6173683a3a6830303132353063623334393936663731ea01446672616d655f737570706f72743a3a7472616974733a3a43757272656e63793a3a7265736f6c76655f6372656174696e673a3a6839626266613262366431303362343436eb01456672616d655f737570706f72743a3a7472616974733a3a4f6e556e62616c616e6365643a3a6f6e5f756e62616c616e6365643a3a6863613939313838386631356433383831ec014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6833333738316434643864666436656234ed016f3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6834393865383166633130613134653763ee013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832363132323231393639373462373631ef013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a656e737572655f6e65775f6572613a3a6830363535633030383037383564383039f001386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834623762623735643362636133653030f1013e70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866623230626262373533363362393533f201723c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637453746f7261676556657273696f6e3c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862396436373939613536386130396334f301753c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374457261456c656374696f6e5374617475733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862666164653262383364383065643234f4016d3c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563745370616e536c6173683c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832306135316261636461633439373964f5013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6834306363633634636639663264353439f601723c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637445726173546f74616c5374616b653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832383938303336373164343965363932f701743c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637445726173526577617264506f696e74733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834636163303865623366323366376130f801763c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563744572617356616c696461746f7250726566733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838303234326639353265353966306430f901763c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374457261735374616b657273436c69707065643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832373364643466356232333461633036fa01713c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374496e76756c6e657261626c65733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834383238626465343434643963386536fb01793c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563744d696e696d756d56616c696461746f72436f756e743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838393031373062333438306562363634fc01703c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374486973746f727944657074683c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832633761363061613730323930393431fd014770616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6863303036396166623837663465643964fe019b013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f6e64696e674475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866386365323530313835643336366136ff019a013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53657373696f6e7350657245726144656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686430363465366535396131666639653180026c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683661333863376663326237613064633981028e0170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e3e3a3a656e636f64655f746f3a3a683533303135303263616637316232373482028b0170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e3e3a3a6465636f64653a3a683139663031303035363032313939363383022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a686534663835313733336437616337393984025b70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c41636375726163793e3a3a66726f6d5f61737369676e6d656e743a3a68333032663139373933663437643236668502437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68636532646130613864366534613561328602ba013c70616c6c65745f7374616b696e673a3a53746173684f663c543e2061732073705f72756e74696d653a3a7472616974733a3a436f6e766572743c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a636f6e766572743a3a68363063343330623233356162303131668702f4013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e2061732073705f7374616b696e673a3a6f6666656e63653a3a4f6e4f6666656e636548616e646c65723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c283c542061732070616c6c65745f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249642c203c542061732070616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a54726169743e3a3a46756c6c4964656e74696669636174696f6e293e3e3a3a6f6e5f6f6666656e63653a3a68306361313930623832303762366565328802386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68616361303163663938303839306638318902386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68613030623436633335663836396138338a024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68396534353037353364356138363764328b024970616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a6572615f7370616e3a3a68333931363230356161316237356234308c023570616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a64697361626c653a3a68633862643266363665303163343162358d025e70616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a636f6d706172655f616e645f7570646174655f7370616e5f736c6173683a3a68653061633232363038313230363733658e02443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68373332383233396561356330336530308f02d3023c70616c6c65745f7374616b696e673a3a4578706f737572654f663c543e2061732073705f72756e74696d653a3a7472616974733a3a436f6e766572743c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c70616c6c65745f7374616b696e673a3a4578706f737572653c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c3c542061732070616c6c65745f7374616b696e673a3a54726169743e3a3a43757272656e6379206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3e3a3a636f6e766572743a3a68303130306136653633333963356433399002386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683436646136656337363839323561623491026a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a68653733373063386438393865323662669202493c70616c6c65745f7374616b696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68323332316635313138326632383437309302623c70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683165363633373562633563343064313694025a3c70616c6c65745f7374616b696e673a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683432313735363364633661303461653295025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68643331336138303734346235613461669602336672616d655f73797374656d3a3a4d6f64756c653c543e3a3a696e635f7265663a3a686130303164613161613336386361366397025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68363034626331623838346165653839399802386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683937383334303861656239333735366699028d013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f6c6f636b3a3a68386539383332376637323535393236369a023870616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a68323333393139343937306562613430339b0290013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a72656d6f76655f6c6f636b3a3a68363961643363353963643762383465379c02437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68306466376134383931643832313030659d02746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a68356230373362656432643965646163649e025273705f61726974686d657469633a3a7065725f7468696e67733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a68373466396162323963616135663864389f023970616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a6838393134303834366562636466316661a0024870616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a636865636b5f616e645f7265706c6163655f736f6c7574696f6e3a3a6862633632386362623665313235396437a102336672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465635f7265663a3a6862653566623830666433656563346362a202b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6830613365386630326430373963633961a3025b70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c41636375726163793e3a3a696e746f5f61737369676e6d656e743a3a6832633837316139373664333966626261a402386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831303330643066333562623236623965a502633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a666f6c643a3a6831383937373036323634316465666333a602613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6836383338636633653235316565353364a7025f3c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6836623635316564353564306138663366a8023a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6832313737373264343165626362333138a9023b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6833383163666139626161343636636633aa023a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6863336561646439653661643733643939ab026b3c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e2061732073705f72756e74696d653a3a7472616974733a3a56616c6964617465556e7369676e65643e3a3a76616c69646174655f756e7369676e65643a3a6831636137396631333866383436353632ac023d70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a69735f6f6e6c696e655f6175783a3a6830616539396237623730316133373062ad02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835633933616362336564343535386339ae02706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6839353233663435373937333366353239af024873705f72756e74696d653a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a6838663264656433613038356665646366b002633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6837366338653630653661353637656362b102473c70616c6c65745f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830386439333236346161336261633561b20247636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207533323e3a3a666d743a3a6830363038633233636664376438363635b3023e73705f72756e74696d653a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6836333262383438636565646538616130b4022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6864623061353930353239353338636562b502583c70616c6c65745f696d5f6f6e6c696e653a3a4f6666636861696e4572723c426c6f636b4e756d6265723e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861353839626230393239316431363836b602303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831366531613666633830663231663161b702443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6835653461373432356165306430643935b802383c285431302c205431312920617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834616266313431303864333838623738b902303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6836376630333365363637316261613236ba023c70616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864393465373664343030643338633233bb023e70616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6836386163343933303665666639313563bc024770616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6830333237373033343137313633356264bd029d013c70616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e5665737465645472616e7366657244656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861323636306361373430326265616535be02726672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a696e697469616c697a655f626c6f636b3a3a6863643463666166376535353431346365bf02746672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a657874726163745f7072655f6469676573743a3a6833333765663764386636303130663635c0027a3c6672616d655f737570706f72743a3a73746f726167653a3a6d6967726174696f6e3a3a53746f726167654974657261746f723c543e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6834623438383235366462373035646664c1024b6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a72656769737465725f65787472615f7765696768745f756e636865636b65643a3a6835653737393733616231633161353561c202366672616d655f73797374656d3a3a4d6f64756c653c543e3a3a696e697469616c697a653a3a6864613031323530616631313861366264c302763c285475706c65456c656d656e74302c205475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6834366136643866386634653361663664c402437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6837623966633166393539646134653835c5027a6672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a6170706c795f65787472696e7369635f776974685f6c656e3a3a6864316265623562356236616436623135c6029f013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073705f72756e74696d653a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a6865613461663166653232626138326232c7025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832663965613735386464333938653866c802437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830643062366662623139376334383939c902683c77657374656e645f72756e74696d653a3a43616c6c206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6861396639393066333166633764643834ca024473705f72756e74696d653a3a7472616974733a3a5369676e6564457874656e73696f6e3a3a7072655f64697370617463683a3a6861623030383763383361343632653335cb02406672616d655f73797374656d3a3a436865636b5765696768743c543e3a3a646f5f7072655f64697370617463683a3a6833343336363434376463393039376432cc027d3c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4368617267655472616e73616374696f6e5061796d656e743c543e2061732073705f72756e74696d653a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a6838363463356664323865393665313137cd0283013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4c696d697450617261746872656164436f6d6d6974733c543e2061732073705f72756e74696d653a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a6837323261396236303866393538333263ce0287013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a56616c6964617465446f75626c65566f74655265706f7274733c543e2061732073705f72756e74696d653a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a6862623064663361663631326263643333cf02583c77657374656e645f72756e74696d653a3a43616c6c2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6838666138646561643934626565386332d0023e70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864333161373836333434396133303730d1023f70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a6e6f74655f617574686f72736869703a3a6837633932623065653739323664613663d2024070616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6861343434663866616263636131316634d3023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6830386332653738326433666263646537d4023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6863636238336434663762386364653161d502437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6839626466333166383536626164373164d6022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6861653134343765363062363238366364d7024b3c70616c6c65745f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832336332343831363835316538353236d8023970616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a7570646174655f6c6f636b3a3a6839633661653839323364646139626539d9025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863396663333838316434633432343931da025f3c70616c6c65745f76657374696e673a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6862373863376234626130326535616461db02613c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6831366234633334383031333332626231dc023e6861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a726573657276655f7265686173683a3a6838316634653564306332306135613264dd027477657374656e645f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722077657374656e645f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a6863323263616264306266663465343537de023f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6833393733623236666363646331626466df02303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863663361333164356334363164663335e0026f3c73705f72756e74696d653a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6863306634346334343836663062306662e102a601706f6c6b61646f745f7072696d6974697665733a3a70617261636861696e3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f7072696d6974697665733a3a70617261636861696e3a3a416272696467656443616e646964617465526563656970743e3a3a656e636f64655f746f3a3a6835356334383535666438393831653163e2027c70616c6c65745f6964656e746974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f6964656e746974793a3a4964656e74697479496e666f3e3a3a656e636f64655f746f3a3a6830633764363063626239613466323632e302820170616c6c65745f6964656e746974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f6964656e746974793a3a4a756467656d656e743c42616c616e63653e3e3a3a656e636f64655f746f3a3a6834623163336531623136343735316437e40280017061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202851302c205230293e3a3a656e636f64655f746f3a3a6832346536616661646135336463363062e5027877657374656e645f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722077657374656e645f72756e74696d653a3a53657373696f6e4b6579733e3a3a6465636f64653a3a6865633439393436613965326366353034e6024377657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73797374656d3a3a6832346435333666366461626236393765e7024477657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696e64696365733a3a6866633661353633616565366633633163e8024577657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f62616c616e6365733a3a6862613266663464313662636133306162e9024477657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7374616b696e673a3a6865663235343139393034336237643632ea024577657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6f6666656e6365733a3a6832373630396165336130376336656566eb024477657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73657373696f6e3a3a6835316263613032383363376262366239ec024477657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6772616e6470613a3a6866323865613437343165313139343763ed024677657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696d5f6f6e6c696e653a3a6839663632353335613265353763333965ee024677657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7265676973747261723a3a6861646565313332366263663535633066ef024477657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7574696c6974793a3a6830303930363738613734656561613137f0024577657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6964656e746974793a3a6835653262356539656138366439626337f1024577657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7265636f766572793a3a6865383166613666626239623061376438f2024477657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f76657374696e673a3a6837333163653763323138623361623564f3024677657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7363686564756c65723a3a6837363662666335326661363563663061f4024177657374656e645f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7375646f3a3a6839633637393530383165366262336537f502763c70616c6c65745f617574686f726974795f646973636f766572793a3a43616c6c3c543e206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6862346132303338303264373132333332f602483c5b543b20385d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6864353563616664363062633430326563f702386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865663632383331666261343036396334f802437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6836633163333262386138626638343838f9025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839663966373864363864396633666565fa02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863333337373430666433393630623433fb025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839363532613637656266613538623236fc02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838653163616234366630346464346137fd02b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6837333634333666396561646561363235fe029a013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a726570617472696174655f72657365727665643a3a6835303166306264353435643562646464ff02b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6861623766393830623235353766666639800385013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7472616e736665723a3a68373733613264663466313732333662668103386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68353463376132386339303938376233308203386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68613231343762633834306437623934388303437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68383133333565346536306663303139638403366672616d655f73797374656d3a3a4d6f64756c653c543e3a3a626c6f636b5f686173683a3a683438316662646431653531353538666485033770616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a683766656462353664643538663166393186035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68613530343866373037373566633330618703386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683537326337326435633065653236366488035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683263316262303437373632373165613289036f3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68633437663333373962646235383435328a03a9013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4d6f64756c653c543e20617320706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a5265676973747261723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a72656769737465725f706172613a3a68626334646437613537656663616563318b03ab013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4d6f64756c653c543e20617320706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a5265676973747261723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a646572656769737465725f706172613a3a68393233373964346332643734633466348c035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68336162353738373235623434356239668d035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68383034363963653237356439336463618e03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68333361646264396262666638623762348f03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683530376333323962316161366330623390034a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68616438303435353636616431346165669103386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a686464356539383932336635326661346692035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683732613563393362643335613263343393035a3c70616c6c65745f7574696c6974793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683964323632313336633738653139383494035b3c70616c6c65745f6964656e746974793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a686465633235643263656664336461316495035b3c70616c6c65745f7265636f766572793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68313664376163353764326230393465329603463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a686235313832343065303735343136356397033c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a683133353763646134656134386162346598034a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a683830373135613532616337396233316499037177657374656e645f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722077657374656e645f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a68313535643236333238303832333366349a03543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68373062323731633463656365646430369b03723c73705f72756e74696d653a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68366330316364386532326265373434639c03543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68626635636437343038323133303739669d037d7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c205230293e3a3a6465636f64653a3a68386533346461656232333533316666639e032b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a68646230613539303532393533386365629f03573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6863653164666161613635383031663332a0037470616c6c65745f7265636f766572793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7265636f766572793a3a43616c6c3c543e3e3a3a6465636f64653a3a6839373732326330333436613331623634a1036c70616c6c65745f7375646f3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7375646f3a3a43616c6c3c543e3e3a3a6465636f64653a3a6831393365616535646134336231616563a2032b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6864633736316466333637353061383365a3036b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830333763626638343266363865313530a4036b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6866333066376131326331366538613331a503303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6836323333386363366161636331313162a603723c70616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6839383030656631656236386433326130a703763c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a6174746573746174696f6e733a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6832646534653030616234303332616133a80390013c70616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a52616e646f6d6e6573733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a486173683e3e3a3a72616e646f6d3a3a6837663830396237633632663038356336a9034570616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863306465323763633639363361643032aa034770616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832396536373561316661656430643531ab035070616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6832333362353563326532376639653736ac039f013c70616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a57696e646f7753697a6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866323365663438333961643661336239ad035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6861386534636262323531643562633462ae0353706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a6174746573746174696f6e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832623161363264346239326463643566af0355706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a6174746573746174696f6e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6839333737616233633638626537386130b0035170616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832323062623265313965303364616438b103683c70616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6866396239653535633464646632623034b203703c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6833656664313965663539633034393536b3034c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a7365745f68656164733a3a6861386530613062346134336265386265b40396013c70616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a4b65794f776e657250726f6f6653797374656d3c2873705f636f72653a3a63727970746f3a3a4b65795479706549642c2044293e3e3a3a636865636b5f70726f6f663a3a6832653235396162666266613963626335b503443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837346661336532656565623661383130b6035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837313739326233386233306262323262b703386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838303435373830376663643664626639b803543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6836643161643639623136373765376638b903706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6861303564303466386161633161343737ba03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6861633766366633643137333062363235bb035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6834396163373630336132633863396561bc03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6866373433323432663234666461626131bd03513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6833663937646633666166623266626231be033c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6832643539323066303437623832373765bf03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6831343164613565373239663538376330c0034670616c6c65745f6f6666656e6365733a3a4d6f64756c653c543e3a3a7265706f72745f6f725f73746f72655f6f6666656e63653a3a6866666666353335636530396562306135c1035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6836636637623266393962396233663564c20358706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a63616c63756c6174655f647574795f726f737465723a3a6838633863616661666431316533653937c30351706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a70617261636861696e5f686561643a3a6866373330386437333561623063383662c403443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832353339356239383562393539393232c503b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6833316637636639333137303431646531c603543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6833653462646165353333303061353962c703673c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a6864353234353863663730303736363534c803483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6865643563323235333931663131626530c903386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864386164303463643931336565613233ca035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832303637616432333063353465383035cb03543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6864633332343762333263396233643564cc03743c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6861343337656232666530663466633466cd03443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6835663361393566313430653332373339ce035c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a446f75626c65566f74655265706f72743c50726f6f663e3a3a7665726966795f766f74653a3a6861376562626331643836346534376335cf03743c70616c6c65745f62616c616e6365733a3a696d62616c616e6365733a3a4e65676174697665496d62616c616e63653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a54727944726f703e3a3a7472795f64726f703a3a6834383137313033376235656238386432d0033970616c6c65745f7375646f3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6834656230353466396636383836333564d1033b70616c6c65745f7375646f3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862613332386138623232346231656666d2035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862643066656461386639626461653561d3039c013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6861326463663262633531323432316437d4035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6838333035633737643263333033616161d503553c73705f72756e74696d653a3a4d756c74695369676e61747572652061732073705f72756e74696d653a3a7472616974733a3a5665726966793e3a3a7665726966793a3a6839363539393963306538306538636638d603437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6834623535653535616163343638333533d70351706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6836363739333134333232623130333332d80353706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838633233386639323365303030356534d9038f013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a5f5f4765744279746553747275637452656c61794469737061746368517565756553697a653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834323531343861623431656538356662da037d3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a5f5f47657442797465537472756374436f64653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832303138313937666634643530633961db03463c70616c6c65745f7375646f3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832316164313664663231656366373635dc03473c77657374656e645f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830396565323463616234396531356234dd03473c6672616d655f73797374656d3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6865633738353835643832376633376332de03443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837356233613430306536636366656339df035e3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a70617261636861696e733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836366233326438393032353862393565e0035d3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838633762623133346463636265666535e103493c70616c6c65745f7574696c6974793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6862343633353532376530613737353732e2034a3c70616c6c65745f6964656e746974793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6835363863663332663362336664636365e3034a3c70616c6c65745f7265636f766572793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6866336333643130653334383937326230e403463c70616c6c65745f626162653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832376237653633303766306562373461e5035c3c70616c6c65745f7375646f3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6834376666373434353035626533613933e603733c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6837636261346264646233356538633333e703723c285475706c65456c656d656e74302c205475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e46696e616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a6866653166663835333730643764623566e803723c285475706c65456c656d656e74302c205475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e46696e616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a6838643438393732346230623835373031e903763c285475706c65456c656d656e74302c205475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6836643730313435656138363465343039ea033870616c6c65745f626162653a3a4d6f64756c653c543e3a3a646f5f696e697469616c697a653a3a6863313639333265316539646334383938eb033e70616c6c65745f626162653a3a4d6f64756c653c543e3a3a63757272656e745f65706f63685f73746172743a3a6830373732396230316338653565366130ec03443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6833666566643462626637303732633330ed03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835653966396662663031646530326135ee0397013c285475706c65456c656d656e74302c205475706c65456c656d656e74312c205475706c65456c656d656e74322c205475706c65456c656d656e74332c205475706c65456c656d656e7434292061732070616c6c65745f73657373696f6e3a3a53657373696f6e48616e646c65723c4149643e3e3a3a6f6e5f6e65775f73657373696f6e3a3a6836353964363235663337363135363964ef03386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866343932383231643365316335353735f0032b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6863376165663463396437633432616163f1033c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6838373461333364643537303635343134f2038b013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61704974657261746f723c4b2c562c4861736865723e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833356439313663346137373334666435f3033c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6837323766346532336264313239626138f4033e70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6836643339383630666435366266343239f503703c70616c6c65745f73657373696f6e3a3a5f5f4765744279746553747275637443757272656e74496e6465783c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866323632303134386538396238356430f603437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6831363262383630633164306337326235f7033970616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a6866643836333638366363376430386335f803376672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a6866363862646634616133346563646661f903a30173705f636f6e73656e7375735f626162653a3a646967657374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f636f6e73656e7375735f626162653a3a646967657374733a3a5261775072654469676573743c5652464f75747075742c56524650726f6f663e3e3a3a6465636f64653a3a6830333933303135333438333235373930fa0350706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830386666623339346561333630346461fb0352706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6839373462373833353934393965396635fc037f3c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a5f5f47657442797465537472756374446562746f72733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834303336323939353964653239363063fd0382013c706f6c6b61646f745f72756e74696d655f636f6d6d6f6e3a3a7265676973747261723a3a5f5f476574427974655374727563744e6578744672656549643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830646663313362636630633061646461fe035f3c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6866306164623565353834626362336665ff036f3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a686364393761623362373131396133653980044b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a68343431643131663731366137326133358104aa0173705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a5472616e73616374696f6e56616c69646974794572726f723e3a3a656e636f64655f746f3a3a68323331373265323032653537383961668204533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a68363038633231326632616265363439638304960173705f7374616b696e673a3a6f6666656e63653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f7374616b696e673a3a6f6666656e63653a3a4f6666656e636544657461696c733c5265706f727465722c4f6666656e6465723e3e3a3a6465636f64653a3a68613437393866343064653439303061368404543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68646633663261343163386261613465348504443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683863636339343062306362326461653786043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68383461313935306432313861643133648704386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683365363864386237313862336139653988045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68656138666363333238666335663862308904386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68356439626539336639613564646565398a045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68346162373032646233626536646632328b04693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68316537386336383537656139643765318c0481016672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a617070656e645f6f725f696e736572743a3a68313662663335633833616138626338648d048d0170616c6c65745f7363686564756c65723a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f7363686564756c65723a3a5363686564756c65643c43616c6c2c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a68653433633761653333393633396536338e043c70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68383638326363643363393231316362308f043e70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68393231663133383035633839353532339004703c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637443757272656e7453657449643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68636634323434666662613066623262669104693c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686561333837313265653039396463306192043d70616c6c65745f7265636f766572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a686234303036343263393862656538643093043f70616c6c65745f7265636f766572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68316633383262633566393734656531349404776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a683131626136396634666531663633653795043d70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a7363686564756c655f6368616e67653a3a68346230626131353835313565626135349604513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68383030386234363334313736366663349704386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68663433616639653630633134646565649804683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a68303532623931626462366163383962329904633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68303237303534663136386436616238649a043e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a68636166373230303961643530383139649b044070616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68656638623161623963346562366531659c04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68393965613964626233313864626662649d045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68353062383633386266393239623237309e04437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68663038333539633663383066643435329f0434636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6836663236633362653936356338383130a0042e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6838376264373861323363313663336637a1043c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6839376539366435393130356231373665a204363c5420617320636f72653a3a636f6e766572743a3a496e746f3c553e3e3a3a696e746f3a3a6832653462386566633138613364666664a3044a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6837303430383466646230363130666231a404383c2a636f6e7374205420617320636f72653a3a666d743a3a506f696e7465723e3a3a666d743a3a6833323130373634663365323961666332a50439747269655f64623a3a6e6f64655f636f6465633a3a4e6f6465436f6465633a3a6465636f64653a3a6865363830636630653131393666356361a6045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6838643466313333613261363564373933a7045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865313563316562623733306164316634a804706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6864333665663038336162643935306439a904386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835396166326363663336343432656135aa04386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862633264386630653765663965383663ab04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862336530636438653263363265663961ac045f3c70616c6c65745f6772616e6470613a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6832613835633139653135326333316666ad04603c70616c6c65745f7265636f766572793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6831643235333030336236393730363939ae047d7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c205230293e3a3a6465636f64653a3a6862363037633537366133313937353164af04463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6862343061306663613965623062383264b004543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6835306461326334396234636335636137b104543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837323165353634373030363463613131b204543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6838383937393538363832653038613330b304386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863343866626435386461313934366139b404fa01616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a48616e646c653c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4e6f64655265663c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4d75742c4b2c562c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4c6561663e2c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a456467653e3a3a696e736572743a3a6831643963333537383266356533646163b504fe01616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a48616e646c653c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4e6f64655265663c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4d75742c4b2c562c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a496e7465726e616c3e2c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a456467653e3a3a696e736572743a3a6830353364366539336239383837616263b6045770616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4368617267655472616e73616374696f6e5061796d656e743c543e3a3a636f6d707574655f6665653a3a6866303163393331643264633538343163b704463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6862643231396366663430393464613462b8042b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6836363336316239393639313432386636b9042e73705f70687261676d656e3a3a7265647563653a3a7265647563653a3a6861616365313962373439616434396339ba0448616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a456e7472793c4b2c563e3a3a6f725f696e736572743a3a6838343433373537626163643430666535bb043373705f70687261676d656e3a3a6e6f64653a3a4e6f64653c413e3a3a726f6f743a3a6835333134653065333036393035326365bc043b73705f70687261676d656e3a3a6e6f64653a3a4e6f64653c413e3a3a69735f706172656e745f6f663a3a6837383862373133313232633231633062bd043a6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6836306137353232323565373536313839be043c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832393132643862623237633438393134bf04703c6672616d655f73797374656d3a3a5f5f47657442797465537472756374457865637574696f6e50686173653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865386566643232383530633436613638c004683c6672616d655f73797374656d3a3a5f5f476574427974655374727563744576656e74733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866346232323530323635313832383132c104703c6672616d655f73797374656d3a3a5f5f4765744279746553747275637445787472696e73696373526f6f743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866633536336237363561373862393638c204693c6672616d655f73797374656d3a3a5f5f476574427974655374727563744163636f756e743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831303338316531376539373439363439c304446672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6e6f74655f66696e69736865645f65787472696e736963733a3a6864353664363839306333366264333562c404346672616d655f73797374656d3a3a4d6f64756c653c543e3a3a66696e616c697a653a3a6839356337303365386535333635343233c5043c6672616d655f73797374656d3a3a436865636b5765696768743c543e3a3a646f5f76616c69646174653a3a6839626237313132646231333438326462c604436672616d655f73797374656d3a3a436865636b5765696768743c543e3a3a636865636b5f626c6f636b5f6c656e6774683a3a6836663830333530626130343636663333c7043f70616c6c65745f6f6666656e6365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862353636633166313335386434333834c8044a70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6836303639353032623934626266303430c9045370616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6839663866343432633235663333393765ca04aa013c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866646530343262643633643235316663cb048a016672616d655f737570706f72743a3a776569676874733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206672616d655f737570706f72743a3a776569676874733a3a4469737061746368496e666f3e3a3a656e636f64655f746f3a3a6831306364616566323763653735343065cc045d3c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6862326435663537313338323633386131cd04503c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c543e20617320686173685f64623a3a4861736844425265663c482c543e3e3a3a6765743a3a6838613035383333643833366661653239ce04366861736862726f776e3a3a6d61703a3a486173684d61703c4b2c562c533e3a3a6765743a3a6861623866333639343364643934376535cf04553c6d656d6f72795f64623a3a4d656d6f727944423c482c4b462c543e20617320686173685f64623a3a4861736844425265663c482c543e3e3a3a636f6e7461696e733a3a6830356231663661303965326333376463d0042b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6830306331306537613566373265616235d104386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863633262633663663830636432333566d2043b70616c6c65745f626162653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862306334336135396638323234653965d3046b3c70616c6c65745f626162653a3a5f5f4765744279746553747275637452616e646f6d6e6573733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830366261343130623232653865353937d4044470616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6838393236313637663639356438653362d5049a013c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836383562353761346335663739373937d60496013c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833343362383237656437623262616635d7045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839363265653638643836653666396432d8043c70616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835656631313033396634366233306665d9043e70616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866666433366363636233393966306334da04386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862323339613066636363656262336432db043d70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7570646174655f6c6f636b733a3a6866323135316336323238386434656661dc043f70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6832303961663563336439373639663637dd044170616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6838613339336266633562383730643961de046e3c70616c6c65745f62616c616e6365733a3a5f5f476574427974655374727563744163636f756e743c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832316166346565313133633731626464df044a70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6831373634376137326664343566373038e004a3013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578697374656e7469616c4465706f73697444656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865616135313935326363623131663239e104a201706f6c6b61646f745f7072696d6974697665733a3a70617261636861696e3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f7220706f6c6b61646f745f7072696d6974697665733a3a70617261636861696e3a3a43616e646964617465436f6d6d69746d656e74733e3a3a656e636f64655f746f3a3a6834613139353731633733653931336365e2044a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6836333734366230393430316636373732e304473c77657374656e645f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830396565323463616234396531356234e4044670616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a656e737572655f736f727465645f616e645f696e736572743a3a6864383236356365626363643632353862e504706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6863393235333435303431386263613761e604386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839303633626661383232643737356339e7045f3c70616c6c65745f7574696c6974793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6836393962346366316666323234303265e804623c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6865336436363664656637653632396264e9043c70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6838343234376161656662613766353934ea043e70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863346566393238373432643236646331eb043f70616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6839323263626633633432633737626237ec044170616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865313266346335383331393639303634ed04623c70616c6c65745f617574686f72736869703a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6861633033653861636538363961316532ee040c436f72655f76657273696f6eef0412436f72655f657865637574655f626c6f636bf00415436f72655f696e697469616c697a655f626c6f636bf104114d657461646174615f6d65746164617461f2041c426c6f636b4275696c6465725f6170706c795f65787472696e736963f3041b426c6f636b4275696c6465725f66696e616c697a655f626c6f636bf40420426c6f636b4275696c6465725f696e686572656e745f65787472696e73696373f504613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6836303338663465646366326363336266f6041c426c6f636b4275696c6465725f636865636b5f696e686572656e7473f70418426c6f636b4275696c6465725f72616e646f6d5f73656564f8042b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6ef904214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b6572fa044f70616c6c65745f7374616b696e673a3a6f6666636861696e5f656c656374696f6e3a3a636f6d707574655f6f6666636861696e5f656c656374696f6e3a3a6834383334623634346166643238373665fb041850617261636861696e486f73745f76616c696461746f7273fc041950617261636861696e486f73745f647574795f726f73746572fd041f50617261636861696e486f73745f6163746976655f70617261636861696e73fe042850617261636861696e486f73745f676c6f62616c5f76616c69646174696f6e5f7363686564756c65ff042350617261636861696e486f73745f6c6f63616c5f76616c69646174696f6e5f6461746180051c50617261636861696e486f73745f70617261636861696e5f636f646581051750617261636861696e486f73745f6765745f686561647382051d50617261636861696e486f73745f7369676e696e675f636f6e7465787483051e4772616e6470614170695f6772616e6470615f617574686f726974696573840515426162654170695f636f6e66696775726174696f6e85051b426162654170695f63757272656e745f65706f63685f7374617274860521417574686f72697479446973636f766572794170695f617574686f72697469657387052153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b65797388051f53657373696f6e4b6579735f6465636f64655f73657373696f6e5f6b65797389051d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e63658a05205472616e73616374696f6e5061796d656e744170695f71756572795f696e666f8b055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68393835383237656637346337323137378c053d70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68653934616232383534663163656238308d053f70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68643633636233613865393830663564648e056b3c70616c6c65745f6964656e746974793a3a5f5f47657442797465537472756374537562734f663c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68316230653639333861336238653238378f052b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a68383165366232623438353063353134359005573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68616435393861323831653633643538379105766672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6765743a3a686330393131303234383639643737363592055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68346135366636343439346332373436399305386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68363638303138376461623132323336369405776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a686239663732623565326132653639396495055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68313763613266373339356137643932399605386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68343833356166303561656432633263669705603c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a683264643764343333306362383263353298057a3c73705f61726974686d657469633a3a7065725f7468696e67733a3a5065725531362061732073705f61726974686d657469633a3a7065725f7468696e67733a3a5065725468696e673e3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a6862636531663964396162633362613864990538747269655f64623a3a6c6f6f6b75703a3a4c6f6f6b75703c4c2c513e3a3a6c6f6f6b5f75703a3a68343734383732396130333534363166659a052b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a68366537646636383631343332626234629b053e70616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68306238396539363431393734303762649c054070616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68313563616332663836386539616632659d054970616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68383439306665633062363266306230379e059b013c70616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68653766393235383866303335336539619f052b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6862623937363635666436376331643830a005066d656d736574a105066d656d637079a205076d656d6d6f7665a3050462636d70a405095f5f6173686c746933a505095f5f6c736872746933a605085f5f6d756c746933a705095f5f75646976746933a805095f5f756d6f64746933a9050c5f5f756469766d6f6474693400550970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105727573746325312e34342e302d6e696768746c79202836646565356631313220323032302d30342d303629", + "0x5f3e4907f716ac89b6347d15ececedca487df464e44a534ba6b0cbb32407b587": "0x0000000000", + "0x0b76934f4cc08dee01012d059e1b83ee5e0621c4869aa60c02be9adcc98a0d1d": "0x10a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a72bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e300174bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950bd5e21ce53b32bef696d6f6e8072bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e3001": "0x9ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950775c11433d27a3e6696d6f6e80a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f": "0x08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e169034245138345ca3fd8aebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934": "0x00", + "0x3fba98689ebed1138735e0e7a5a790ab0b76934f4cc08dee01012d059e1b83ee": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb303adc196911e491e08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d": "0x9fc415cce1d0b2eed702c9e05f476217d23b46a8723fd56f08cddad650be7c2da8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4fa8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4fa8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4fa8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e16903ce6a96a3775ab416f268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836": "0x00", + "0x3a65787472696e7369635f696e646578": "0x00000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950cf58e078d2188b43617564698074bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e": "0xf268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d6dc0db87ce29bd36261626580a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f": "0x08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da99406b1b580f3fd70373207c005e38adff268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836": "0x000000000300407a10f35a000000000000000000000000000000000000000000000000000000407a10f35a0000000000000000000000407a10f35a00000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950e696c69c865d348f61756469807ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a": "0xaebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da937af01a62f70176413143d943b7d30b9aebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934": "0x000000000300407a10f35a000000000000000000000000000000000000000000000000000000407a10f35a0000000000000000000000407a10f35a00000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195093c237b163af4d50617564698072bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e3001": "0x9ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195053c90cc3c184c72c6772616e80feca0be2c87141f6074b221c919c0161a1c468d9173c5c1be59b68fab9a0ff93": "0xaebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934", + "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x00004de97f22e20d0000000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc60566b5cb12e1bb0dd3301e8ab40c6d0508264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d": "0x047374616b696e672000407a10f35a0000000000000000000002", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19502c959753b2d73959696d6f6e8074bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e": "0xf268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195071eb6ac6f0e199fd7061726180a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f": "0x08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d", + "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a000000005c69b53821debaa39ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19508f3986108b781adb6772616e809fc415cce1d0b2eed702c9e05f476217d23b46a8723fd56f08cddad650be7c2d": "0x08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d", + "0x5f3e4907f716ac89b6347d15ececedcaa141c4fe67c2d11f4a10c6aca7a79a04b4def25cfda6ef3a00000000": "0x0000e941cc6b01000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x5f3e4907f716ac89b6347d15ececedca308ce9615de0775a82f8a94dc3d285a1": "0x02", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc4d92e108794d5f65011d80545fd17e2b58671d451c3d4f6de8c16ea0bc61cf714914d6b2ffa2899872620525419327478": "0x08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d0b00407a10f35a0b00407a10f35a0000", + "0xcec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903": "0x1008264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606daebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c439349ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81df268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe705c69b53821debaa39ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d": "0x8011fb3641f0641f5570ba8787a64a0ff7d9c9999481f333d7207c4abd7e981c", + "0x5f3e4907f716ac89b6347d15ececedcaac0a2cbf8e355f5ea6cb2de8727bfb0c": "0x54000000", + "0x5f3e4907f716ac89b6347d15ececedcae1791577e4efcb083fdc3cb21e85b2e4": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195004564cbf88f48197626162658074bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e": "0xf268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc4b807e5088f44d540645b9875a5c73c31caf27345aebc2fefeca85c9a67f4859eab3178d28ef92244714402290f3f415a": "0xaebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c439340b00407a10f35a0b00407a10f35a0000", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a00000000ce6a96a3775ab416f268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a0000000003adc196911e491e08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a000000005c69b53821debaa39ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d": "0x0b00407a10f35a0b00407a10f35a00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19504e2a9aebc209c0bf706172618072bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e3001": "0x9ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d", + "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a0000000003adc196911e491e08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe70ce6a96a3775ab416f268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836": "0x4c17a9bfdd19411f452fa32420fa7acab622e87e57351f4ba3248ae40ce75123", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc46095c93c32e331c00441c72d2b5397df8011fb3641f0641f5570ba8787a64a0ff7d9c9999481f333d7207c4abd7e981c": "0x9ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d0b00407a10f35a0b00407a10f35a0000", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade984245138345ca3fd8aebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950e944edfdfb59968570617261807ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a": "0xaebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade985c69b53821debaa39ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb34245138345ca3fd8aebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934": "0xfeca0be2c87141f6074b221c919c0161a1c468d9173c5c1be59b68fab9a0ff937ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a", + "0x5f3e4907f716ac89b6347d15ececedca0b6a45321efae92aea15e0740ec7afe7": "0x00000000", + "0x3a6772616e6470615f617574686f726974696573": "0x01109fc415cce1d0b2eed702c9e05f476217d23b46a8723fd56f08cddad650be7c2d0100000000000000feca0be2c87141f6074b221c919c0161a1c468d9173c5c1be59b68fab9a0ff930100000000000000959cebf18fecb305b96fd998c95f850145f52cbbb64b3ef937c0575cc7ebd6520100000000000000fc9d33059580a69454179ffa41cbae6de2bc8d2bd2c3f1d018fe5484a5a919560100000000000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f308ce9615de0775a82f8a94dc3d285a1": "0x01", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9afdf816f281ad669fe59fe0f725f72759ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d": "0x000000000300407a10f35a000000000000000000000000000000000000000000000000000000407a10f35a0000000000000000000000407a10f35a00000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0e0cdd062e6eaf24295ad4ccfc41d4609": "0x1008264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d9fc415cce1d0b2eed702c9e05f476217d23b46a8723fd56f08cddad650be7c2da8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4fa8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4fa8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4fa8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4faebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934feca0be2c87141f6074b221c919c0161a1c468d9173c5c1be59b68fab9a0ff937ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a9ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d959cebf18fecb305b96fd998c95f850145f52cbbb64b3ef937c0575cc7ebd65272bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e300172bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e300172bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e300172bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e3001f268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836fc9d33059580a69454179ffa41cbae6de2bc8d2bd2c3f1d018fe5484a5a9195674bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e74bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e74bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e74bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a000000005c69b53821debaa39ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe7003adc196911e491e08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d": "0x8671d451c3d4f6de8c16ea0bc61cf714914d6b2ffa2899872620525419327478", + "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a000000004245138345ca3fd8aebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934": "0x00", + "0x5f3e4907f716ac89b6347d15ececedcab49a2738eeb30896aacb8b3fb46471bd": "0x04000000", + "0x2099d7f109d6e535fb000bba623fd4409f99a2ce711f3a31b2fc05604c93f179": "0x10a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a72bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e300174bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e", + "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3": "0x02", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19502d9ed59755f843d8706172618074bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e": "0xf268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e1690303adc196911e491e08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e169035c69b53821debaa39ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc472e2b7edbdd300480b61e7ad485ddb234c17a9bfdd19411f452fa32420fa7acab622e87e57351f4ba3248ae40ce75123": "0xf268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f58360b00407a10f35a0b00407a10f35a0000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f2f72e2480caa5c862616265807ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a": "0xaebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3ce6a96a3775ab416f268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836": "0xfc9d33059580a69454179ffa41cbae6de2bc8d2bd2c3f1d018fe5484a5a9195674bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e74bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e74bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e74bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e", + "0x1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d": "0x10a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f01000000000000007ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a010000000000000072bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e3001010000000000000074bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e0100000000000000", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a000000004245138345ca3fd8aebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca28dccb559b95c40168a1b2696581b5a7": "0x00000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade98ce6a96a3775ab416f268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe704245138345ca3fd8aebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934": "0xcaf27345aebc2fefeca85c9a67f4859eab3178d28ef92244714402290f3f415a", + "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a000000004245138345ca3fd8aebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934": "0x0b00407a10f35a0b00407a10f35a00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195072134b407e7eb75c626162658072bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e3001": "0x9ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d47edb55da4253996175646980a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f": "0x08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d", + "0x5f3e4907f716ac89b6347d15ececedca5579297f4dfb9609e7e4c2ebab9ce40a": "0x109ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81daebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934f268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f583608264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d", + "0x5f3e4907f716ac89b6347d15ececedcac29a0310e1bb45d20cace77ccb62c97d": "0x00e1f505", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950eb4a0fcc18f0aed36772616e80fc9d33059580a69454179ffa41cbae6de2bc8d2bd2c3f1d018fe5484a5a91956": "0xf268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836", + "0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b": "0x6648d7f3382690650c681aba1b993cd11e54deb4df21a3a18c3e2177de9f7342", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc637af01a62f70176413143d943b7d30b9aebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934": "0x047374616b696e672000407a10f35a0000000000000000000002", + "0x5f3e4907f716ac89b6347d15ececedcaad811cd65a470ddc5f1d628ff0550982b4def25cfda6ef3a00000000": "0x00000000" + }, + "childrenDefault": {} + } + } +} diff --git a/polkadot/node/service/chain-specs/wococo.json b/polkadot/node/service/chain-specs/wococo.json new file mode 100644 index 0000000000000000000000000000000000000000..0ad7334685f1ffd209d00c0c43fc53ce8d12709e --- /dev/null +++ b/polkadot/node/service/chain-specs/wococo.json @@ -0,0 +1,218 @@ +{ + "name": "Wococo", + "id": "wococo", + "chainType": "Live", + "bootNodes": [ + "/dns/wococo-bootnode-0.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWQC541JNa6dguvifYYjwPnviscJHqbwvoNDMX3WBubPJZ", + "/dns/wococo-bootnode-1.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWG9v9Aexs6EvBYAwy9cqLyw25BRi2U1RQNQ2r5QJRxfFm", + "/dns/wococo-bootnode-2.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWNza3xSzCbw6phggjKD4QyqF8xvVpDFk7ctkoM5c1PQz2", + "/dns/wococo-bootnode-3.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWJ4ngb7S1Lkq5C4ZYqfFuJswxTE3UC5zjui5TLhAULTRU" + ], + "telemetryEndpoints": [ + [ + "/dns/telemetry.polkadot.io/tcp/443/x-parity-wss/%2Fsubmit%2F", + 0 + ] + ], + "protocolId": "wococo", + "properties": { + "ss58Format": 42, + "tokenDecimals": 12, + "tokenSymbol": "WOOK" + }, + "forkBlocks": null, + "badBlocks": null, + "lightSyncState": null, + "codeSubstitutes": {}, + "genesis": { + "raw": { + "top": { + "0x0595267586b57744927884f519eb81014e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x06de3d8a54d27e44a9d5ce189618f22d4e7b9012096b41c4eb3aaf947f6ea429": "0x0500", + "0x06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385": "0x0000300000800000080000000000100000c800000500000005000000020000000200000000005000000010000700e876481702004001040000000400000000000000000000000000000000000000000000000000000000000000000000000800000000200000040000000400000000001000b00400000000000000000000140000000400000004000000000000000000060000006400000002000000190000000000000002000000020000000700c817a80402004001000200000005000000", + "0x1405f2411d0af5a7ff397e7c9dc68d194e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0x1405f2411d0af5a7ff397e7c9dc68d196323ae84c43568be0d1394d5d0d522c4": "0x03000000", + "0x1809d78346727a0ef58c0fa03bafa3234e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x196e027349017067f9eb56e2c4d9ded54e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x1a736d37504c2e3fb73dad160c55b2914e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d": "0x10006078f6e6a00db1f40097f0d07953008b04cda71ad831e70f37e93eb2b40431010000000000000022371e9715d00b3a21c9a899ba3eafd11f5143b821b159b864025ba1eabdb6310100000000000000e6b8162c3e767f8e61892f7fcd06d27041d806e5e0335c59dcdafa5c8e181c5b0100000000000000585a72774ca9465ba0e7407e4e66d239febbe906cbf090169b6cfa15dd44e5770100000000000000", + "0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000", + "0x1cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4c": "0x10006078f6e6a00db1f40097f0d07953008b04cda71ad831e70f37e93eb2b40431010000000000000022371e9715d00b3a21c9a899ba3eafd11f5143b821b159b864025ba1eabdb6310100000000000000e6b8162c3e767f8e61892f7fcd06d27041d806e5e0335c59dcdafa5c8e181c5b0100000000000000585a72774ca9465ba0e7407e4e66d239febbe906cbf090169b6cfa15dd44e5770100000000000000", + "0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0100000000000000040000000000000002", + "0x2099d7f109d6e535fb000bba623fd4404c014e6bf8b8c2c011e7290b85696bb3": "0x10b691bfd2cd584abd1531b7deff6d0e34893960b59ae550348c33abd76af4cb490e93248544c963f34bb9cde63c97f85ef7a1939d3c9075907b26edf368fe846e5ed9fdbd8dffeb5324935a7fafc536de96d62abee0a05d7eefa961c1cf3de266ca24971e2ec596d510c673f4f8d36d0a8a407b59ffd0643f621369973a335656", + "0x2099d7f109d6e535fb000bba623fd4404e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x2099d7f109d6e535fb000bba623fd4409f99a2ce711f3a31b2fc05604c93f179": "0x10b691bfd2cd584abd1531b7deff6d0e34893960b59ae550348c33abd76af4cb490e93248544c963f34bb9cde63c97f85ef7a1939d3c9075907b26edf368fe846e5ed9fdbd8dffeb5324935a7fafc536de96d62abee0a05d7eefa961c1cf3de266ca24971e2ec596d510c673f4f8d36d0a8a407b59ffd0643f621369973a335656", + "0x26aa394eea5630e07c48ae0c9558cef734abf5cb34d6244378cddbf18e849d96": "0x000000000794e321d00fb2d42000", + "0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01", + "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da942cd783ab1dc80a5347fe6c6f20ea02b9ed7705e3c7da027ba0583a22a3212042f7e715d3c168ba14f1424e2bc111d00": "0x00000000000000000100000000000000000064a7b3b6e00d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da994dc96e49150ac7c3ab5917a8d347ea0aa7ca70cae6201086232336a1535399c34f372320c0aa15d68c4cfa493079f27": "0x0000000000000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da99a0d9ba64d584162e7d1fc85d6d19ad1005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f": "0x0000000004000000010000000000000000407a10f35a000000000000000000000000000000000000000000000000000000407a10f35a0000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9a1e0293801ecda3bccddad286cfce679fa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c": "0x0000000004000000010000000000000000407a10f35a000000000000000000000000000000000000000000000000000000407a10f35a0000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e39abd9d6d25130391c9ff6fc64a35ef18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758": "0x0000000004000000010000000000000000407a10f35a000000000000000000000000000000000000000000000000000000407a10f35a0000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9f4c6172605184c65d6c162727408dc0be4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b": "0x0000000004000000010000000000000000407a10f35a000000000000000000000000000000000000000000000000000000407a10f35a0000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0xb9921c77657374656e64", + "0x2762c81376aaa894b6f64c67e58cc6504e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x2aeddc77fe58c98d50bd37f1b90840f94e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x2b06af9719ac64d755623cda8ddd9b944e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x2b06af9719ac64d755623cda8ddd9b949f99a2ce711f3a31b2fc05604c93f179": "0x104a611c52c43142e11767e4443eb56b908babae266b4f446271d11ffaaafbb16ece83a2b5c733f98b4018856a1fb0bdf0138dd883cc93a883f97de48b762d6b12ded28f03696a0c9f9dec223f3cbc44c4895d8b243ebe5cee12f9f02bf0c5043c9e3e67bfc0daed31db022fce484b2cf0d757e9aafded1988293da74301275b38", + "0x2f85f1e1378cb2d7b83adbaf0b5869c24e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0x2f85f1e1378cb2d7b83adbaf0b5869c298ef7dc060436e4ed803af07632b89b65153cb1f00942ff401000000": "0x481a2bb5d6b9d282f3597f76299e767b1bbf06577a886d6def364451d4a95a5204000000", + "0x2f85f1e1378cb2d7b83adbaf0b5869c298ef7dc060436e4ed803af07632b89b6b4def25cfda6ef3a00000000": "0x481a2bb5d6b9d282f3597f76299e767b1bbf06577a886d6def364451d4a95a5204000000", + "0x2f85f1e1378cb2d7b83adbaf0b5869c2ff3ae12770bea2e48d9bde7385e7a25f": "0x0000000002000000", + "0x31a3a2ce3603138b8b352e8f192ca55a4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x3a636f6465": "0x52bc537646db8e0528b52ffd005894a2041e01468413521028ee4c3a03850c0b278ae1c05fe510045e30c88789ed5828071801ae10048d27c39f9eff086b9b6f23fd1d87552800107259f316bc3f938f9f81ae1d78d1903cc5c228dfe9c050dc7b93bdf796322599028915a61196126d79ea34800c255ac677be934ced1499782df3671103be5364d28fd4930a906ff7cf6e8bd4b5393500e74f1202e3cd66bb25bdfdde7ccf633fe29e95e39d5f8e97ce19c5a7f7f447eae9eeeef3dd67f77bb76dcc493ffd9e19cc6f5bf67bcfa9057250f9b71fe4008c202b19f9fd5964c23fc52622d86cb62b972db7acf46e3fd821b7d1fc36e296f523b593b465fd476339deee07616dc4b71f9ce1d846fd3c6de4df0f6ba379fb5964e294b412c185aa7977be77a78d39994f7f3eb551f3ba6591c9b4e5e4a0b64b7f19a8e6735a01f2e5a072bcfda0d74625100aae8cf3cbf0f697fedc327ed0c924e37c05cc5fe29695f4f223353849bf212f799a5bf3fbc1194e92de90973c4daeebd45d2b3deefc7e91973c4ddb75b2e05a09effc7e1c5ef2346dd7c9826b85bbf3fb7378c9d3b45d270beefc7e1633a036db9d8fd46087cc4be697fedc327eaf8dca79fdf94127bd96f1178dfefc2c5e405bc6efd66b193f52831d4eb26fc84b9ee6ed5ae1eefc7e91973c4ddb75b2e0ceef9fa20246db9d1fb611df7e163398b63b1fa9911aa9919a496e193f07b55d1a2f03d57af6182037c85c13e37c7e7e25d1a27f40d3e695a489246e24d94ab244122592dc923891a44cd11b49b614bd507447911a454220f9a2e88c22348a42509446911c48d214f9501444111d455f8ac0147900091792358a862882a3680a24531471a0a805246f14d990cc81040d247420c903091e48d61495510404923b8adc20f1a2c88c2232908081440d246f90c081240e24669090416205923690c881c40d246c20d12aba02899b242f247121090b455b90d851c4a6284dd116456314c581a40b2468909c4112022475146d21e1a2088c222a8acc24c12a12a3488ba22f8ac2282a53d406899a222c3f27f870116405e48b4c0b912000d0449028826c395744741c01e3481547bc38b28634e288185cd6912fb83a9ecc6b7930381dc0e1008e961e2d7ae0003a1392f14f78d66c06c70188866f8aefcc3c63aa31e77818de082138cc1626b063ca118a11e4871f32260833011113a099e0cc045b4ca0c504464c70c4ec61080e212708c9d236d0db04369c159a061f5bb40c568b69e342d03708a11282c6871600a2f82a8ace04e182134311acdfe1ad78153e88bfe157f8241e8b17e251f81f5eebcbfc97e7c0d0d6bf30d4c5501443594363866810fa3244c4501148a818da61a8035fc39f301447cf143d65becbf7f0576058de09224d1059828812b32366453c1244789885a95d33232640629685238790aa1f567e35b44576466685ac0a1c15e81c436010a9304447ad6288d6903543b6866831248c2169867c3104cd102b867831648b216a868831a48b21600ce162c815e11a4249082121f48690182130e411424f08951182c26261b5849c1022039484101540480845012446480a202584a6003a42c88cd018a02580c2e4a090a3454809a13c84f010a243680e203184ba84e410ba432804424c0875114283d00e423e70250835d1d3069011422c0861cdad203588b8217246cf193d680455116486c81a3829f84843223181160e17223b10f152ad009aa2c895213986cee80941112c3331403600d500644565b06f9c89a1376618cfc6bbe1acfe8c08ee184ad37366e80ccc03436e43a8a074f4680d9102b683c5a3c78a508d908d212d863cf1d3c64c882155846d009d300404302086b6f859e3b70c19d383054c871fae19113f6c005d195266081343cc0c89a2a78a214df4a0015f18320550094026c4de0c210384a5278b1f356279f49881fd40e5a03b0c71e26db02f301f864001f322e445880d1c08c912fa41880e3f050c4c111b28e64b781e46aaf7020be32088208f7721880786e6e81963288f66c189a8558d058435abe1278c190d311d462484d4308af1f1c30f184fc6cf18432efc6cc572188241a807211d7cf4f023c69bf165fcb0f914be852229fc1213042181580fbee6a9be0a081e0038c1d5781f22c0e38b8009d143c79025e81943b21863800d21f40656c40f1c436aec1d30227aec80bd016b031b03d605901b8ab470573d6e0cb9111a6202218e702114840f20261842c80c426e98d930d4829007848410f2c20718528c8f21c62992702131a3e7081f5e90a4e1a34b511b3f667c5570577ca2f0c1e203059984cf989f363f5f08754186f986f819be309f98a13486c6f826be0344c8980d31f4450f153d5bfc11301e6c1e40290055c9da7c60da04224504b501e2d25d7c404c31b80e10ad80e40cd81148b2f8be3417afc35bfdb851d7f0127cd2206133040bda45b3fcd657401c780f5026a80f4031046d016d01d2020443510a8d03100b3d5c00cd00d4012246c07aa8b61f33640c3721888ca03282d87c37a017820881440bcf010805ce8e1e2fdc8aa88e590c45687ad2e821038914456a7abee8b9e26789cf123445cf9a1e36453d14b1f0f3464f9b216d884040c404d18da889b103130dd00af54acf56671561d1a3a6c8861e307aca40d206280b123186b001ba1a42c6c7d0d385102c402e246921d68107025ca2888b24b61e357e941872a69a415206500b40321459118b014914496010fac0cf1a2120623c8c4cc476f0e183100f3f5ec470189d1893f071c5e8858e31761979105a414805a11484b408a120748277a9587c98c7eae9ea71f357cf042582f6e05544cce89903266602377ac2187263e88e1c3886d0bc14435e501ce80d425c7e082015605d80d4e86163088d2036681b1f85bf41b982cc781b7aeab06c0c750dbd19b223e88ca13080e0701bfc8608de0c893114829e3886d608c500fb006dd323076844cf1b435cf4ac010b6288cd0c852049c08c182283560d7105b9a16c1e049f45101543cae04ce8e102e2ca39c10716a2d5d00b6411454aa86e0051f598d123c6509bca06908d4819f6cc58424f9abf62b4fd2de4a23c80508036803380348059a00ea013e00d6013600de013200ee00ee11aa22d360dcb65d518aa63888da13582b882e40872e3080f477c38d2c5c7161f2dc8e29075c9e438d2c2110e1c7161c8367445f66656c2cc16048d206b044983481c940c227208591169038819d40d206e828c1184cd11218e147164082279fca0f0a325e887202282809099217343e606481040c4001162c88c213c86ca206283680ea236666d6668ccc8808d8191814101d405f406a80e225510d9828815416e08e243101c80e4000408203ac84a90a120c342a4070743c4072220202205112680d4b40f405c0ca9e12c0cb5e12b10214174055112631651184468106d11b540d4012217884210e211de31011e445413e4f139bc12ff8117f3543c11cfe55978135e86a7e1a178338fc363f92cbf52c5f8dad427be313e2b3e293e2abe321f990f04df125f0e5f0f5f97af86cf876f852febfbe123e2e3f271e083e17be1bbe1b3e1a3e1dbf2b1f0b5f0617d1ee0b87c42d4339f0edf0cdf07380e7074705ddc1b9c1b5c159c190e0dee0cce0d670657064706d78663c38dc125c189c19de1d0705770487062b830dc119c115c111c11dc109c105c101c18ee039c07b82d2e0c0e0cee0b6e0de705d705c705a7864bc36dc169c145c141c18de19ee09ce0a8e0a6e0ca70645c0cae06ee06ce068e064e062e0b9702a785b371287027702b703170581c0cdc0bf54dcda3e251b92a9b9a4645a39e315da83cd426aa13b586fa43bda1da50b5d4126a0a3404d40e1a079d81a641d1a0773817dda26fd03aa819b40c2a86b3e16b20e9a2705027681395066f837aa1587405da855ed114280d9405da8297416ba043d02f9403f4054a4583a042d4351406aa023d81264191a046d030f4082a866ea139d01f681114086a03d5c1dd7034aa09455c1e858f71285c0a47a26885ea8307f1055175f00eb80e3e43bdc2b5780a9c0b5c0bed45d7d173f417cd469bd170349be6ea33da8d2ea3c1e8375a8c5ed374341a6d4787a0c9e8aebea3c3e831ba4d6f751b1d47cbd169f41aeda6d5a85e2a1deda57f681dba868ea1b934077a86cea13b507b987974d56461de314330ed98757c2ecc35661ab5cb44639631dd9874cc37a617138c59c5e4626631cf7c66e69aa935bff02fea0ef387e9c3f432393061b0124214d4531981064cac07cc2a077ce0c1930b5880011b2820013306240468e0e40018346162800258305fa00089d191a40f0d705e9e3b467ced4a5050309054058ad2074949e074294d4a4949af181e0c258a4a084e49504d4953aa5c0f9aa62c41896ac04fec0ea612951402568ad20485090a0692a844254145354da11214b383a1a43c41c980d2d3942a178a890a950d9aa6804025013656479791181d44b1399898a0446162825200393e88f2a04989290e5652ea20894a5452d4071e4c51cac02c060743314d8112a524254949a90309626f30950e9aa6248df0a4148253d2942a37aa49098411a06cf0313758294a1395a62428519aa82420ca0d12e39242258a929408626d30d4084a4b5023283969001963036a8a0146b8646c0d0a626a04c5d26011949a7ac4d0e033f8832854aa28c5626ef829040fa674d044254ad2942a57090350683d3133248895a12446064b999214a504f51442941fb1360ca534256aca13950fa2428092e441d2942a174a15294d509e2e101263c350504a4c416263ecc4c4d8e2a8a610a84449ea008a12534f2c0c7e0201041010901303833ba042e5a94a5295291f403d293565804ad2084a4b42b12f588a52930753a09a428842c5ca94109c9492a29ea854517a328aade12825a8242f186a0ad4081d28296120694a953b42074a4a349f58170ca514154215a829527c625cf00750503eb03135acf4542549e9694a084e4a4f49501d58a902144bc3514d4a207460a58a2cb60543294551b19294d444e527a6058f80812434504c4a4d4d503e8892540584a70f92a434854005034d53ce4435518992e40482942c180a04284f50aa243d51c182a9740024a6c550514d4a5694ae600f9aa6486952aa92a4140545ca14294d50a2148959c14a52a8440912ab829fa87400a5046586a1a242a81215029521312a4008010a0a8a506c0a861205454a521395295294a2a0a6403d295591205686a1949ea844491a216a0ad3140c40619a02c50a948f9161a82a215079f22049484c0a867aa21205450503284f503680c5a2e00c4ca9729f94969ea8444001640c0a56520a4129840538408a92071e4071c0506c0c432d4551fa20ca130c15d5a4f4a4f441d3948f39d134a58358ac098e3205aa69ca5394084a49233055a90225e949490ad39410684b51a830d17e62378602126382a124fdc440c0202441898222054a94120274624b68600a13942951539aa6f4c494e0a52854983090a4141542142511947ac492e0272a0508792a3161004a5453081d244545517a9a22a5694a52d28f263b591dc867cab09d21a3eb720de49bcd7667cd7f705f1a5f1ab3caec684c285663b5c66aadb50a4da0ee6ee4aef38e763d3277eecdccccdc51eeee66ee3a6606996b771cd31cf6ca1dd3d0f30eab3b129feded1030e2a0bb3bc88ea4411ed01fc003823ddd7bce6ef72110e4ced199ed808f7dfa00290fc875ce5c77fb9c5f03dcd9c13ec25d77c43b4a3d2fa49476775d73c8ceed3977cd4e2973ced42975dade75ba7bbb7b5d1006e2a0fb6cf68e015d7b17c21848c83427877ae8ed79d4d3d1e9605de7dcb5bda3edeeec614e377bb6c75d91912e80739a67d8711ec8cd3edadb79d28675be41b7d75ed7b9b333656705544e00d8b5334936f51c012c343570ef3aca0eb213a20988ba09dc3fe6cf9d9939ce39e738e6f873671de73866e738678e391c6ee6388e73c6e1388e63678efbf8e3188763ff98a773cc4dce999bd971983f9c8fd9793abb73b3e7d15a996b4729f53ca6ddde5c6953ea850e80d8ecba7bcec9516a01103a33ed3a6f721fe0a313e4c9a041c76036051dbcc079dcfb0765ef26c8ee3983dcddd81ee49ec7ee79edce1eed3af62031a849539fee5c698e7b8e91168570c784727777eededdee4e475a8436a5a304eeafaedd3ba75d7b03754073769d01e6ecba6e4eef66e798326d8f36b357bb4177aeb53aed997b538f9967773b13e18e1974f77e396de6d9b9778e7b74ba479d763b1070086477afbb69d775dd8feffbda81747b7beeb9bb33b3b37b17a0eb3aaf0bbb473a76de799e4723e2ec5d77eda60d3a77333373d77533e7ee66efbaeb983d9e2137737787eeeeee733ab377f3f4ae767b77b367d7753b3c3cb6eb3acbc37d4366666f76a7b4760c32651e42ddbd870fb377eecddeeded3d643fdcd99d65ee3dbcdbf33ccfbdbd87f774f7e93edda7cfe993b677d7deeeededdd7993ddbd0787d9dde3d9b39dbd2773b777ee3cdbd99ddd9b6958dd27fbecf6e9dc4e296d66e76ed1bbf6c9ce4dd9b9eb3a77666fa79fe7eed51d67327b74a7bfe6a8736177c779dedcf5e8e9c13db9ddc7bd63ea4e43cfa39ce879f727b677ccdeed941964e7f666e7913bee98c97677dadd71473def80b477dc75dddd5402ea1dd376caccb0eedc7b3ad85dd731e8d4636ea79d7bedbaa6ee4e29a5ee79cc5dd74d29a5cced4cb99d3265cacc4c29336577da75dc31779d3be5cee36e6f88d79dc7deb1333ba5eedcee94b9e3aeeb9cdd9d99b9e35ad9d9a937927b3b3373e7eedddedd59d075ef79dd7973d68e0003a8e05f0015d6755dedba9d2501e80aa3d5ebba9c6e6fefbaaeebbabb4ea7761d775c531ad2a6d49bbb7677e79cd6aebd634fa2459234dec33dc21315109440e03e26252b4a4c4922400121821f1e50614af2a0698a071e5061fa815305042851504a204c89fa1f0c84003553824a02818a9426284f16270a2a69e9894a06a2949a827e40c994c88ea4344149527a825205042a497a3041894285898894294c50ac2441011949517a5292f24425c98802244a539ea28848f00309152a4f4096a240c10013139527221440517a02f223e4e7474f14d4141194b8a82850a09aa03c4525454d0101042a3224533a507aaa627d624d4a55aa40997c040421aca4f4d441d21395282851a8303141f9e123204c896a0ae1c9fa7410154210104268f21141e983a4a8a6294f5592a2404d01e1a72789511011a864204a881105487a94203992844469090a1306923c689af20114940f7c88a024a5694a52d314281f44e9a0032a9f044a8208949692a244506a2a124194920712f87882a2c4142549c903284f54a2a092a4304df9204a52145308503a509232e3a29ea04441498004a8a8c9832950a40e1f811a41692929ca14260c845045f60425f462245294a0a0949eaa8040254ad29392152a51949e92a0404989a2947464c988022455a228411d7d1f4489828281a40fa0a6344de9402664840ea63c295901b2d2a4e441f84852139529504f4a569294a2a03c2935297990148023145080448a521295a82a233c45498a124149c84a93921fc911a33faee6dc547d3de15a8deb6ab529ef09d7a6a65c7c529bb5599b3953535da3fd646ad6a6a6dc9f4c4d6faa3635459fd4e6d454835dadd63de1da543fe1da54ad466b944e4d71ed7bc25353dd93da9c9aea27b5599b9a9aaad5dca7a6fa094fcd27b539359f706d6aaa366bfd646a6a8a6bb5eec9d4e427b5c93de1a9a95a8d3e999ab55a3fa94daed527b5c94f6ab356ab798d3ee15aad9f70ad56f327b5599b4fb8369f44a0663199798200058503f4b9dfb2e672df6dc0010b574efbe1b2368a71ff41b2271f6ce15269417ed4b8b5481b95dccbb8b2f78e41c8c19336aa4c4683369ab73e110b636efd249512ddca68c8dcfadc463f6ec96d6e151550e576dffc51dced0769501bd57fea293a49badd7bdd377796b9085bf0e35edcf397b3fb263ddb911c59d62eb75476cfcf891974dd77b624e1f6f3e56c396f37e90fcef66f2793b34ee677fd1f106beb72649d576ee93ddfacc68c204f1b715f9f8a17785f92f02683f99c2dfbcaf51ee4b6791d89e4dc953bdbb93c376059c1e5a39ce71fdb487c7e9e367a3df3ff7c501b79cf2f6b23ee6bf7458aef913510041fa94332e6fd7765bbf4c513b807b1409e5723dfb0b22e7d903e08d666f8df073e38c177f20b3eb81473d27da51d4ee7a4c3e9c0f71efc5ecff77bd926de7fff695dfaafbf5dba54ffb3e5bcdd87ef91f37e2e3679bd5e2fbb54bfa40f55530054ed86bfc43d5500fdce96dc87f67b24bf9f07d690c5d09652377c8e2ce9e53e87f4b6623e326954396fc57c84fb4943f290046bc891fe3924d33cd2c96797c4a72f3e8b4c92bc19c5770e7cce96e28336067ef7d5097dd1c640ebc47bee3d90235fdf2d795ee7c4ebbc0ce87fb6e41e7c1024cbf063dff3059f23639f6d521fe49e2f16984b1f7cb0c3a5d783b69cb7e43e7cd0c317197e396fd862133003d0321b29c1f7ff2c1b29bf7705d0076df97aeec179b979e7e56699a482cbcfee8553007de5f2e3f012befc444aa666edd5e10a2b90f12e14c66451418769420836059b9c0f5632569fbbeb4f8e8cd59fb7e34e87be04d7bf7b26eb3773cc31d7cd676e4e92d7dc49f67724f748ce91f582959c0fce89659c7fc5c34ac35ac326e75726b384713e58c526bc86eb6438b39244b7d98e2d93e07a8d9b9e05c8538591beaf30f6072edf60c8e1b60d976f2e505dd9e55b0b4464108585eb963525b85b86c04214973f67ae30ba13976f1d60e3ce31976f31f8708b5cbe71c9628a17bcaad8ba4e4f2e570dd7690ae79651638001b3e196515e6c00c7b865140a63d45b427151c410125ab7840aa375d9b3d9f8cde5bffcfd02e8342f7d9092f56b4d732702fcdb96371be2b8f4e9cfef49c69cd434977e4d734ba8daa55f49be4efce6cd9bb276fb6b1c773ec85246beed60e69297bc60874d46702b59d3dc295ef0567aa68d6a277ffb9d04bbc50be69beb34df541bcb60beff05f3dd46817cab81eb46f5adb6ecb732af7fed3a799d246f478197bf5667df01e64e7bfd27f7cc04e5c8d9936ae45b0a59d7bba0fbef975eef7dfdf0fd418eec0771c818cef32d6b17e743b2e438eb9473ad44f5c5f916c918cecf9bf3200d9b2cbdef079b8c65406db60b3ebd7ec16fb26f8b17e0bc48e67c48e23c477a2892f482340c4996e38aa45fb08621c921b822d917a43db97694cbf9fe90643caec87536c58939e127debcb9fd7ecb9a1236dbed90e43597239be43e87141fc945b2f252bff7ae418d09efd9f3fab9c9fcfe2966d0ef3d8843820fce108764362ed8210ec96f5cd0431c92e3b8200d39127c1c12aabb56fa7af0342ff8f5ca051fe4c48965049fc559c248c526bce6820f72f53969cf3939201cf0798cad848b43125df07b7d83e2331bf940f1c38f2cfdbe3e7c85dfeb41f2291445eec3d77f6439efcb321779d98fdfbb5cedd8326aed750b6b9938bb24c011467af996820b238cf5f22d052ecc468044310c45f1270982288aa2f81c247681e0eb05823f4910401004c1e720f08deff3bceff3befbeffbbef778c9f71cf4d9a571aa415acd014eb1b95c58cbd848d7dd246d59e7b191ee27090208ddd38f9730f1784919202b8d5df760ce057c8340ce9d737776e7bae7c8908d74d4631af99602d5addfd147ea8efbae7b8ebc80eb5a07f002be390f32c95b2eac65640b97d908cf6772de29b2919c908de47c934c23ce8b1f3ef84ce3ebbff7be7ba691fb5a7a3727e7435ed29ff3222fe19bf39d0306e80f3a9993417781b7f871dfdefbf7de73ee1ef7819df74e5a99d7f3be9bdc8ee3fe6eff7a76c9fbee594480f7d9b276bff94979eeee3d923b49dd9eefb593dff6fa913a0363ff0473989f8cf9cff76f32e6ef24064897b948d97df74ef2edbef39ea2c22ad77b16337872bdf7f8828e2cbd5ff2ef1ef448fbe4c45c36db8dea715fef1e15ded77bcfa202aadcef91da239f9c2cb8cd46fca3b8ebf5f5ffc827efa3b8fb7a169d24ddef23b8df7ba4930577b291cf3fcb5cc45f6c52dff3c8f95d392f7f25cbfef92c5e30af3b39b68cbfe6cd8e0a90ab8ed707ab3f38c57e1ad8b52d6bb7a754c7ccfc1ddf493a49ddd939f965713e528339d3325952cf9b4cba3b756fdebcb9e37a4d3af9f5ac93d767ee3bb2ecdeca7899a8edca2dfb9dba3baebcb956bcf25ba2ef3ddb72bcfc4d86fd563aa7272bdd85aadd6999f0233993dc7754dfd773ffb24ef38e4b3f32aa2f7d1bcb60deae7f8b4cfc3992cbf9dc3b69a5b92eb9b7a593d4a55fcbdaed66e7d952ea7adfe4eceef67e42d52e7fbf9337e1efe79cfcd24bed92ff7c169d5027f3dd2ef1377fd3dbd2b2287880e5d8a296db3f194b5e32ffde449fd436daee9cb6cb7380f3c11cbee1f333d1fdf8f5bc6486e4b311a2cbcf65e091a4f79e23f524f94ef105be9a7c39f3822c32e14e676cd9ebbf077f8a4ca62d6b777ee48b043dd2cabce5bcdf4fd2cabcdff71ec99782ded31d675a27bfb1267ee74ffb6c847f5e8ffcec92f7e053d1c9bbdc832198c355277cfadf4f5184ee3fcb3f418f2cbdff5eb6acddd764f2026d2975c19fe4477a4f2e32bf3c408d89cb5c64fef748ee2475fdf317e9e4d79f3f3203e378fd91ba49be1d69e472a4478233f4c8b2fefc8e8c4deb342f67798ccd76876e37391e40c7baf49d741a97ea4b70cb6aa79696f1e59bd518706a6923bef49578c913d1edc25fe3327e3eb3e52c9595111af7573b342d6dc473e90349d235964c776a69197d223236a0e27e3e525319cba9e5d22f998c4b5f8a7ff4991c331c61c31160b66c361af79436491bfd41851c4ac061091a959511dafcab1d1a3f9555d3babf22006d3e475e118026f5c501f3a536f019fda975e9732ff5c501dd73560ac967f43b2bf5c501dc4f2bf53ea3cf5922bedde697acc5739850a6cb1a5df82046167fe95350c2c8b4da0b6696a8a18626d40801078d69fc25d1a5cfa203de66a34d2d6d24c1a53fb1ba690d20f39292a8966394c18b7ea574ea7a6573a9ad25d7d1ef6c13674bee993c08ae5b2df7a5db52ea5277c256ac7039dbc5ab5f4e5da6da0c976b1a00d5edd62fa92d45b8dec45660ddfaa5062ee56c13b7b9d56a7901c104699ca05ac0dc9fcb372d2e5cb0c34a7691e29fca79f3e6cd0cb4af8bcd078c20b09c61a33f9dfccd9bdbc51624851d5cc87a12cafa00195b54156e73bbd82648e384cdca00a86e22d8d80a2c1a7fa9815b9f5900cc13947c3bc1cc8d9ab74b09dc86f6591bb7a1b195e29f6aaae1062eaedc61b3d13c6ba3b2d968fca5d4bb2dab8034f4487e4afab7088109d234f186a62306183ce481e5cd1b1a3fcff5e696009d52b2fe9c9d57ebfb7be4582bd7e11499740a2ed69f976f27c470612dab4fc979410fe97395ce4bbbbf00f9691bf17bbcc4a77befdf3bf7cebdffc7bdc7f93bf7debdbb831cc9b732e91790ba9ffbc97d8cfebc7d639403dcd78ea3249dd76323dc6b805c9ff212eef92b2fe1c8242dab285ca296d567d14baff4de8f5e5f5fe647e0d7ff6923da32efeb2be125cf46bcaf0f9263cfbc7f915ecf3c1f9e1fc17ae67d7d581b7d5f9fd5b865925bdf072f99b73ee7bd5f712477defb6751737f5ae67dfffc297a1febde6fdf58679de69bdb3ddf4e58e1f2ed84142eac65de734ef47e965be65536c2cf226523fc48cd91f34e75adb60701721b75fed496f3d2b023e7ad17d4a7df95749a6f9af8d34f618b4504f8d3f79edad2bbb4fb293a894055c215db752a3310023cde5ceea16a97b350f5b9659d2de97725993caa12ae5ca7f9a614a145279e2d450059bca03e7d2a36e19ed948593b725e8e749a6feefcca84da5806fef4fda95deaa7d649ea967ebbce7e02ec1e9c2213f0c3afef91e2332fc179ee411cb249ed96e183cf62130f67c97bfe902cbd9f0fcecbb713a86e65235c8b4dba5f24bd7f91f382208b08e8ffbe17c9ef5f24cf6791c967cbef3bfcc879c1476a90c9f041922fc8e2056ccb79f9c3073b042f785d6623253f08ce100c1fa93904498f0c5be6bf34860ffeeb965e06de0dedd2f70d92e5f7f3919c4527fddf149de69bfb7a2447ea17c9f723f97a7c39b29294a42de3703a1790a18cf44bd8ad9e9236aa44b77efd24f5616b6efd9f3e6a5aade0d622b7fed846fdb5d6fa1c54ed12dfa640e6c93ca580dce9842da33c1bb451f92ec46ec9682efdfa9d57ff76dc97ace67630a4362a3d0cdaa81c3f68a3ee2b68a31fb77b0eda886f59c2dcee2bd04794e6ac86c7dceeb98d80dc92e7964a6e571fa97fc0263b33f3cced1eecb0c9be302d6ef720f764c7719a6f2e77cfd346f4bbeebbe7a0ce2e31977b01b983916f5ae2b8a577ab41cdf5e7eb955e7b4bb23632c14dcf2f613f3ce6368fc3aebff33c9a34ffd1792e009963622c4322262f09ea11641c708491b68ced738f3f2561e414d09f834abe997087fbed1fdbc87fdcfe0f6f39dea0b0653006701c380ca1668e225a60210d1aebe84cd97d256d548e976f573adcfe227dd4b4fe0a9c9c776c1fb73f9c36bc7cbb72e1520b6bd9e49b1d204719db0b8540a6c0d80fe274012fdf4c98e1c27e402b4770c99286096bd8d042e3109ccf41251139c1495b36692b80b60c0459bc80b3e55fee3dee7468cb6c19e5af87b511f8fe3f6dd481ddf7d9f2fbd77f5dd8b2b18dbaeffdc18e9c17fc5a16fe142ff0b9a12dc37f7d47f20dc928bfdf83b3793a4e47f20549beaf0f76e77b7e94e569dc336623e5cf9db6e4bebe3fe87372245f0be67b6454bd33043b14e172cf64e9b9c89dce7ca622579db065412df3effe5bd65924679292e5bcfc1c19e5977f9263cbfaa7c8846db55ecb7abceff911b5d96c361bcd5fc64bfc7ad07dcd4a83bf930f1845088ca5574d70e1765b8db9fd3f9584b56c963f773e8b0f18e7f3bc745601b94190c39a036111640c8c7cb322e2d6cbb7aa3597756e93d2283083d165393e1730b27880daa5d47a764e03185180a41b1877e6fe0ef95bd4a07697d83a4d5dfeb27f9c4954dd2edfaab26ee95dfa43976f54715c0a722438aba841edd20be6e5beac5dce7a4d5270a53e484526d5450d6ad759e43ec6d926f372cf59af65f3795e0ea27669e4026630bff4ef4926c9634e6e02f20246ae7a7f5b7f5ab90bfafd919adb28d6a4dfdfb9b2fe923f7d8e7baf8dfa7237901730d23badd732faf4c19c0b9ca62e656a3100727b8ed746fefdf4b98d28d822133a450d6a949c9745af00c86dd41e3209b29291def082394cbdb08dead35f7327f9346f7fbf93f45964e2342bc9372a37179ce124f936e924df4a8a34ac24dfaab42eb751d39fefb5d1bcf35b6432c3cb62136add7a4dd6e89c50801c446526bc446d5456f06d54ca2a6823fafe45daa8bbfe631bf18d4a89ebcfd3474d0bea6e99e4fa8333e43e1a7de6cfcf4cdb68a97f3e4f1bf5fb731fb1cf9cea70cbc296cda70f76383f9ccf7dc434fef076f9a7d8cf62937efa19f4d3b08d9a6f6d05c80df27350396db7795a8d7c3b21cc9db6230f99741a97fcf996d3d6976f2790b9f3ce9fa202e695cbb69c36fa4c5aa1979f924e722ebf93cc4b4afab10c5e975aa79ccbcf692ed12df9cd2dfd9b2f39b78cf3e7e5a6807f8a4eef345eb7d3d654800c65ec2fbdebfeeeefee58bc5c7777ca41ce8485aa04354a00f36dd4df2f6ba392deee0fba5db9e3c8695da46ff973fbb99f0ad194916f5794b87cbbe2c22d65b7bfe8f2cdb67559640281b11c917a1cc336e2effa971fac245f27e70559c9382fe76125b99f2213e79e450d6a9703a798417dce96f5eb832d6630defa2cd296d10769e8e4bca0871c597f8adcb292e7ce074116395bd62ef74e965e7d77b2a4977ba4069d2c0d70fd41163b5b8a70bb77b2e4dbf5af64c92d13a1ca074f38b8fe25b7acdce0fa971583eb8fe495e4db914efee6cd9bae5bdfc9b2824b1f9ca193f42bc997450574d739d2a9bbd596f3ba759a6fdebc7973cbdaf5a724b76c5adab2f94497816adca45740268232f2cda6753d32973feca349e387b511df6c5c2effcfe5e720b600e425e37c7efe4090db88e79dcf0fe6701b316da37e7e708234e436e25b7a9759a7016410d132be4edfbfdf452601e12dc77b99244bd87d91e506ecb5b1a90c5dd7755df7484db9e3265d13abb94bdd7bdf91fef4bb0ee7f98b1025e125e0f3fff491cf98d3438700574febe1d9797e591db24bcfeff08c3edf3a3b0f6b59f7fd3d48dab2ee77489e9675ef437ecfba7f91b296f520f9ea907589f1fbf7a31e9d570fe9f5ac7b1d726c59f72349d4b2ee73c8242deb1e873440cbba17490c5ad67d486ad0b2ee41720336d23dfb91929e75ddcf9f6293be2fcb2debbccf862de3efe8dce9ca033867b73ba515e4c2f99dc8040666645bf27010235b6e8a19f92b0e7b62870ed257fdb8d0f35ac6d4f3affe4b95a77799993b9c52844bafe75dbe3c69fc92835207bbc9fd6023954a39a5e11bd12fbd861388efbe20835d05823cc01474e97313f4c227ff817ae9772213fa3f2de3e78eabd47bb287036323fc55c624a2682dbbaeeb28574639e8c20cfb04b6250657c9a53f8718e7334f268a1031ceffa15fbabb331b296597614a5cfaee3f8b18e73b138fb9742ae1484ee9bb130118c167ad5b2629791a899770c046c42f1fe74bd99192227d24f39987dd336def3d3b9918cbf10523fa1eeca0fb7d8b4e34a0850f5a605d2622341ab44ceb4e9cd167539c2139af48d625c65289123fca797fa41c927d36c3cf8f787ae65df8201895dc97123fa2fae2bdd5d372dedf006df4bd67e4bd3f066dd4afff3eb4e58fbfc0772625f77b179d4895d9a20398cbc46a5e24bd2c7eb665391da964b256d8dc11debccd57732bac8f30f0597d253eabcfcf498cf4a55a562b12632d62fcc9a58dfadb46cdcb648636eab28068a3ce7601d34661da28d653cbadcfb71b7d56bf8e97b92c65aebac4581f030e78491363c95bb7fe13296de47dfd0f6c555aaa8d4a26d99ddf5f5f040d3c5b321a179970368a4e22d848fda6a0e4e9c8ba04fbe4d2f33696cc756bfd2a51a51211a617aa2ff4ad9ee65f7fead0467366b511fdfa15b4d1ec8cf8d60e03be9e65e2314e36b043166eb62e136f79f47224bd9464da14cce7e923a679341e6fa59545ae7f9db76e055a6b65e798f9613cb37d0b121ba9404905828c600aaa49f86541b3fc9f89c4e45a49ce0d90861388d2fbae1ce97931b6f5287ae7f7876d34c7a9c5dd97eeee1d13c980f87e7002c17d7f254bd8e5ae563642df7d7264c9c3b7926578d94bc246ec58e500e9fc26a7065b6ecb0daeff244ba23be79cb3945d0d5ad6ef241311a3b98dd4b2fec963ae920ae65473c928a164c9d4c45b7769da1a9d2e46c9edf2bbe781558f49e879484db9839e954c7e1e58c9f1b48c83fde5385bc92ebf299d5c71fa5964a2c49b350d0882fc4df21721bacd632a1074f9a538aafcb94c419793dc1e5bd63cd3d6971579264f279392cb4fbb9978cc9dcf4d4f81be3bf3d72f398e9fe35fe298df997d3ac13f8118e797f4b677a713e3fc19067801572b737daebf44bf6919e5b73efde1a95f524a2b69cb27b73e25e707c6f934aade5a2db7aca45fd6ba54e7176aa98fb58d4abf6077777b7b9b00f697eeee4fbd79bd96cd257e4b66667a998dfccbeebbf4d4d7dfbc611600fdd2bd979c924ff346f56527fce6cdbccc4bfccb26dd8b71deb65e543bb1e0d67cba0b39979b60c3c3bc324efe014ef2029e4c7ae19a73766bf1920758432a3261faf4071be9a7e20564155964422d4fcbd848bf93208c7ceb0188cbf363142fdf7a9821e6c49f3eb5a506ae5bbe7407907bfa7397f3b4e574e29bccbb4ad6a2b694b92d65773e7fffdcd20246e7bb1fc7d7e9dcf851cf8fb2b948e829bbcbe708e6e3c3fcb0cda56fdfc146b1c3f8acc1f8acdb8bcf3aebe685cc2d27176bddb26ff4cace2cd8f7f0f99deff9f93e4a0fd6c396ff3bb684d972cc6a2e5c3e3d5d3e226cf9f8d8dcf85cf95c71f960f96075f574dd925e91c1e30a1a101f2d1f1f981a18ecfb7bcb8f7cfc88c52ccb8000b13f7efcf061a90f1f21ecb1f44c988fe57efecc9a59647aba19e7d6f3effc54f39cf34cabe2f9a9f539e487669c36e727999e1f3eb42619355a55587adec7c2aa7c1e4bcffc614980591f1f3bdd40d56edfd848378f2dbd1d5b8e3d6c09d3b1a56cb4e5f7e7907de3aeae33626ee800196ee4409335192b35e838618d37b4cead0853060db63a92a07d5d471c3cd84cb0f54003d1a8c2a2468b2f96a0b1cf705e7cdff271738587125c58dec585da48a05924502f4fb44193f1a0e696f44aebf60d47261b5fb6847db68479b6fcdbd9dbedf6cb6e593e632f9c2d3d30d59663189ff1a5b6842179b9f98cafdbf22f989dde9101e4a092deaecffb84f1f1230c981f3e7e4ccac567fd3ee89c5a5d3c3d3c3c3e3e3f7c7c7cf8f800e9e9e1b1555878be0af6f33eeff3dd13fbe98000f998f7ec473eac8f07f2fdb0e0330d6649f0b124f4fceb418a058a4fafc49ca7b61c9df7aeefaeeee2ea5be7613c07f33dbb1722cf6b37ee5bf4ab7aacabe9792c3c3bcfb4aa1eeb5abf43522e538b8bd6eddff9726a79b965dbb888bad8bacb8fda8bcffabd11d65e6e3f68bbdad63bb6bd4c5b7b193dd838b5a697d94566d2fa695683e2e73c1799db5cb7b558cb8f7a78d4c07e039fcd2d1f3ddcf83cfb6cfc9e9e679fe13c16e779f659f8cd63d967e0833ddef3bce863d967dff77c8e0fcb3e7bbdcfeb48c12cd1f7532e7ee4c36ee0b3f93e3d6cc96aee7c1d5b7a3da32d79ebcecfb1e5c863d96738b6643777be684b58684be6baf341cae5f613f9d1cb96de67cbd123ea88bc6abdf9defd6a3dbac71b200781ec47dff3835d5c93f69193c65b97b5a8179fd9bcab118b9fdafcc83f0bc665c4babaed8dd4d580d1f223a6a9d9a26ea81730bdc55c7ee54755533b34ef3d2fafd04b56f8cae2f2555221172c3faaea1e0be759bff2597f671dcbfdaac3dcabdbef6a2cbf774f9ffbf92fcb6ebbb3cd59f6d9c4ea2d375c6e7fd9616e7f63f9d1e8c1467735306abbdd58358ca583994c7bd82dc7fb914c9bb7e9c64dc771cd1b98d945268c4debd6576ac8f8acb9b9d5d4cb6deac58f1a8828c020a3032a4c41eba760fcc85fb0e38e2e3ee0e004ad9f86f1a3698502176fbade6c41eba7373f3a22450c63bcb11a43eba764fc681e51470b57726cb1d19a4bffe4e2475293067ebfbebf3f0ae347dcf75709fb45f023d062e0b3c662dafce86537e89f577ef4590efa2796679f90c0d90f7cd6df4d5d0d1be97735b7dfdda77bff0de3a45c5d8df60885087ec4a0f77d39b95cb69ab4ef73741e879f5faf073f143ffcf173be9c5797df2375ec0ce366b4138cd5a4e588767a19f937b09a349d7f795f32992ff9067ea9e472f825d1e597f991d406cfaf434e32640e39d5e090738b9c6ebee7f744f099ff063e139f7f14413baf5e7662b52d617672f1d9b4e55fd6d22233bf9c59a5ecca3cf0fd89bcd07b7f259e47bfeffd31f023107c99cfe683f63b5b32993bbf7cce967c837d76acb65472e797a3e7336a4ba23b6b7f25801c54f66dbe7fc95d4fbf642d6a4bb6a5ecb22db9ebfae73096330bcc2db9ab8bcb8fd4a8d9da72e3a69c64fc48eaa77668fe33cb8fa4c4e7be76e1835f3299aebefefb926fb5f3befb52c92d67168e952241e4accc672d4502f7e5cc0aed83646e2f0bfbf816c6b363a7040c673df6594974fb55eba64f802307fb765a3bee719eff43efbf17188a3cdff3fc9ee3e48c3a3b3d3e7635693c3d3e3e803c959547fbf130a7b222a2c52c901f240f8cdcf1e1d343c278c81f7c64fe0ee975df8b8f802190d80f1f092224023e8223e68c3a3d804c772ca991bee8fbad6df5e9872fe5e0cd766b5b0e16f7be7b29f7a72f155aa9e6f29983a942347e38e0f87a291f5bcb672e35b5a4786265813abdc5552b35b97e82c9f95be8b6efd636db2d24fab8c07081f9beeb2d707ca6815f7696f89a5923ce973ce6d8c7b19e96185a1868c7c6faece85998d6d40eadb39ecffa99c659a651cfa9cd7e5501725039b9bc8eabcfff7e449f9f232b89c52989c53b52aae73d52cac74fedd0a8ac441ae5de6ad2382c4abfd297f2de6ad2bc97aaaf8feb5b4d5af557cfced6ebad26edd563a5a8ac441ad59505b49eb79a34a92f0ee0f99e97f261a57cacd5a4f5f8f3f8ef58a9b9e533ff1ed66ad25efe3ab68acffc3f2bf5c467fea3b59ab4ea9f635f0ac75a4d9a67a5443bb3a4d867fea1b59a34ce1fb413cb675a1ef7dc58b3e68d6a71cf5b441d735d7f7d39b75e766a8756ffb3533b34fa4cebbc679af7e504e3911dc99195a4e4fb6c4e9edaecaee3ba23fd1256fe2d651f9af1a93ef7fc2f9cf7ef7b4b82087ebf5ea025e10b9f3efb51684978e5fc7cf6a3aaf043333acddb91a155852f755544cbb12480389684b0e3bab82e3f126d95285aaecb67fea1ad0ac3ee2799ce960fda2a109cb7694bd8cb56bd1e8bf7552fcb617ce64f2dd7f5d9aaefb17896042cf30ded0b7da6557d967dd63fc1f8acb37d68c627eebb8b87abf642c60bdf78b8ba1ca735bd78f123292c3eb543f35eff2f0f06f3fe358eb79c5ea4ae8a681f1e5a342c4e02fbcc022e9a970fcdf8b76d399de87f68c626fd654766d2304e1ac6b2cbe2baca2e4bcdf4d2b7ecc87464fc687af199bfe78d230c76cb8eccf567ffbfb62eab23d365719b5b725a5c17a785e4969c8df3c2d92a1835150ccf2de956bd7add9262d13025c5aab7f49bbb712e7e6b2ee742a66caeceb291f172bbbc94b38b68dabe643544a5777d668dd38671defe727ae9b82e034d79b5da396ec01f13d0b0f8168d008bdf01a4439e9fa06e07090d4bdbfaad6647f31c9afba07904349780e6568afbab225a535d19a161f12e9b1547ebaba6f58bd63d680d84d696d644686da5ea5f15715c0115968e764544ebb7729a579a8b34efa179109a0bd1dc4af95f15b5d3da568afed40eadeb9ae31e8bc36ae5ece856eaaa88e67f554493da71cb3e9b3fb543bb2aa27193dec0f7a3abb19d3e95d5c368dd53598d34eec1e7f7fc88ea2a098d8ae7ad94d05e6f15d2a8ac9ef6bdf7fc303fa2bafa09c51c9c1fdf2a88063eff487525a3515929a1e93c9515116de7ad64b41e6f05a38d4f654544e364b4ca47e653593d8df291f9cc14cce7df2171f8c8fc1ea4c847e6eb90397c64fe488e4cc1fc1cb2878fccc72179f8c87c91f4e123f343d2071f990f92302e9aff223b3e32ff23433e32df233da6808fcce748207c647e257ff8c87c4a06e123f39d14c247e63719011f993fb533db0a90a36fb5c315505d11d1fcad28ad9d56fafc9df7bdeaf387d57a3839a34e0f7f7e1eaee08af6700557a10f5770c5e3832bb8fa81710557413fb882ab22b4b6b0185770e5fd7005576310aee00a26842bb87a5a3f7f045cc1958cc61550cb2257e07604c215b47d9fcde79fa2b3b7400e2aab960c6359bd5432e263a1b730df63e1334bd401e62a098dbe14162f7e64a5dc9a60014db4525236ce4a716f8205b4cf4ad58070c2846aa546a842e22a88298878439332c1021ab5525366ccd005172f6a5aa039fdfa5456218d0bf21ed7edbfe2a17d5ce584fc8b666d551f4f79de074ffd1ead08be8716c5a2f65d7ca92f0e20dfbe14f8e44bc51ea47fbb0d7b20d4f60f7b29dbedbfb908f4413e3f2ff5c5013beff352bdf352dd4b5df1d0fc430ae6b67339981f8ff352606e3fd7ed202b253e907d6ba546d24a2181e0c7ac14bd01b1521466a5fcaddf7c5829e6e1f91e2b45b55c2b024bb17460ffb2525488a53488b52a42f3fefb72bc7dde0f908ff578d1c773dd7ebd4ed66bebf67b593dff656df156cc4a890fc43ef159bf8f95dac067fd3b568ac867fd9d95b22a42eb3eb452148c73399806f3c336d7b3161107137df8bc8ff1b99d9c1fc1dcc6f91cacdbe2e33856f8229696cd8795e2dec7ce1e56aa8acffa75acd4cc7a5929df92f2accf4a75568fed2dde62aeaccac3ed58a92f0ed0f91e2ff5bdd45512daeba5be38a03ea775fba5be38c0fbdab75b0f2bf5bd8e9da3959a607cd69f63a5268e95722cd14a3556685bcb36c1f09925eac0a2e067a5a8ac42dacb4a7d71c0f7f4a5e6d6edbf4a42a356eab373cb67fdf4392b35b57cd65fad547bb66f93b3030a3aac28828a2b536b7261b3831969ba60e9ec544b4144105bb0b843061ab5936bcbb9e85616d5c2d2a2376abb791605c37de95c60b81c0c672b97adfaa5676dbdc9aab6623916fdb2b5ba376ff2e022cd143260515baffa36d9d8a20b363690e982c634ffb26db7bb2c38b0851813aa5883c634b7d5e6b3fe7272ddfe39c338bfacb6db5fb52e034dd9da6c9f1576b8e302be73ce39e79c930cd948efa0c60e655ca6916f35a8b9bdc3181e7f73976f3bacb9b0490711ecf6f3cf97b511ccaaebf6ff1469a386b58c87c90ff823b0426e19b600b6ac5ebed5e0c667fc8cc34728259dc625fa12dcb2d6ead4a55f7e086036b7da2e5e7d26bdaf2425ab07c145f3ac8dadc0a25f7ed71fc92929c105278b1390e04ecd5aedce82798a3beff42bd76d396d974527f352eacf6459bbfcec34af3f33b311fec902c80f088740a779bb051d6ef8f59b849ab7bf450cf87e7669fed74f938dd48ff2ae13bfb9e0b7d824fcd70bb421c06e14ecd6ef8fe42bfa610b2edcf0bf07c11af6ebbf169dd00cbe0fc19f24f81f19be8b4ebc9fd3321b9965dbc946e67f0f9265dff959f1ae93e7618b9ab77f7e8d9bbdc664fa4337dd8f6dc4372eba6ed77171c7edba8eb363cbe8fb0923df912d65616c7fca12e459886e6a6650639b210d17561a30b6a4c9424b9a301d88e0f22d4d0c17e7f22d0d0a69ae9c60870973506db106165ae4c1826fb1020c545bec0003d516496871aa2db6d8420ac71254448d30f028a32a051e8ca8e3882ddfe59b167268c1058d07dca6430b4d04d1460d31bcc1a34b0b2f2be431e4f24d8b2b2e77f9a6451926dee0d178108d9d1804a79da787a3f57decf478cd10f438f6f32347084c07c8e7130187a68b2d0b343854f12d0b342ea8f059a059a16acc020d0a545e1668aeb0d02cd060a9ea2ccedc61421667daf8cc5c61450eef716fc1d5f7ea1533a470860d3ca810620e3a50b0ba42a3e30c1be399326e397e0a200795ac4544c437240c0c8081066d5432055d5993480638a375c6cc35d3c42d89c88c5f18ad33429439d365fc86028711043414c1e58a16c4a8e0c4992c469ca122e20d1376082147155c41a401a60c2ac4f0c09a21d21c91451455842193c4134a8060cc58c5003156229a00f3050824bc48a1c31359b719ace0b2840b1fc0ba3d45165a90daddb3b8baeece17a92d6b7d4760d175392517cce934e314934c4771e5363905c063aedc36aa9ee884b3612593748dfefef53b91499d7ffdffba9dcfdf894ce60599c379a3da39272fa9f391dca9bb9f5daa4f4bfa50b55be79c5a3a6071758512578cc1e16fb1895fb64e7eb99f5ea3b92fee59ac8fd42293cee36a061c579f726037c57a39ebb191f948cdf463235f69d0028bc6020b2c80da1012811d47b49186082670a8620e8ad3849823b2ba60c14518397c08297187095b62182166883884782cd882861b34d08839230738668d8918b884d1410e2754c87ac3b611d4060b9d1455407401430a255410c38d2da310369aa0218e2460d042838ba4c20133a6f88289243820a60d164221388083184250f96045171b5bb8a63138d0859736389801c61a2cfcc8c0c4095cb080e8620726d478615187981cc6d80a030c34696ca92fd070460520b276f0210c1a5b7e9c71238b2b9cc80185338a3863cb1759f3851757e8f8001a17dcf8019c08e30a398ac0810b0f98214249424c9b2a8630030818cac0718375071a14d098238f26c8d8e25150c7950c3cb031c10626dab0108406ad1956508335039a366cb6e46c91214d550b6cc6546d31c6161d074c61c21a62c8e8e1033088c1428c871daa60e80281196cd26c6d89a003319480e14a1a6adee0100690019c29238c1b5b43c0e104183d6eb719dc50820520b88ef8620bac6675a3e1035b361adc4063cd169f1f2e9210e384aa3ac084c08b1e266ea860f3a14bab0c25ba60a18fbc18e1810f98218607d470b1c3682491031a798c49022b0c355bbe342c809d0504be943122cb863a4030038ddba2cff06b714bd8eda4ae159c6093c51d5d7c8036fa116d4d0d5c64d1f0450d1968fd7f59ecbf48cd4133ccf318ee2bad7506132a0f8cab473f622b60b8d5c6f3b5d66ae6d63d587145adb0b99bc1c34c171e17cc8171f37084444597cff8de10e6c83a630bab336668a071672e67c676393329a4d05dfa0ab07682177668c9a005870c6b689c05d40e3b30f76c2cc8c441464bc3904287e58a32545c9913b0b8e04d31c3145a6e4f81c5e7f2adcc1a655ca06568b86ac1ba2db3c3550b65be58b550660813ba051a74f956a64c1924b82bc0cf051abc1dca7ce92edfca0c41ab0e2077fbc8c17b90a03c5754365c1b17164e728a1080267861d7759de7519145c596d7cee51b1560c07092543cf1c28939e1ae7fdf72042a05d83438f779bc643e7bd8e3061136040e79f90605153950a8318693fcb97c8b02850b6b59adb5725d98b1cb2bfcbeef7b81516cf9b87c8b820c4e288aa2889323850b40976f5170f1bc0e3de12423b87c93620c4fb8e3beb3c3bfc3d3e3b111b652dcf1e3f24d0a36fcfa3c1027e624bcfe7e4ba8ebf63303e4fec08ce10b5bb66c1913e6092b7a055a29ad0a88a3082caea4a1421d4ed068994bc790a1ea145e976f63e000c1182e2c5ac6a841a565cc1958b48c3973bbcbb731665a85460185ce12c45169f127b0b43c31c3094ff090a54fe07c2edf9e08733f50b100a942acd70c39dfe5db133c5c187b4fa638b30ae40e46faa557d25b9f6f4ec471fdbd7efd00e4067f765963e64e3277b6b925cc89196ee939b1e6faff30d1e6fa24a7ed5eb64ca6a52213a7a03b27d545ead9dd5623df9cd0724bd8edaebf97738aeb0f53e2faffdc9a3073fd833c0a4e6c32a760232202babffbdb965d86975072966123b3dfe3256d9d7809517d01e4204a29a5944ec14bf8b2a5e0ca38c9dcd2bb5d23ce3c42ba818067d308e91605cbf8963ed7a711976fd9e322ddc27038058074538227e03bb58ef07a47adf39dd908992e04394a88640f1baf3c9ad32efe6428a5d4bb94524aa92d29a5341ca37aadb57aad95d65967a5b5ce699d66a5b5d65aab2d6badb536273707e84d1a36defe9b1a779299fd0a98649a6a9cb7c7e522030e236b884ea6146d38cd3797cc14005ffeae917f76e1255093eace2e6c847f09d42cc3031be16fcac3a5960c2f81e236efb6f49f525cb7930c1be16faa916f8fcbdf5846f0f28d0935e1104c90b9acc5addffeb1eeea91f7f58b2831401b4defe7d69ef1974447af2f2b789163cffa3fd2ebd9acbfe35ccb7baed1205fa62037f87ef4f3fc1854f1237f8e3dffbcf9d17c3d3fd2077e347bfe89e547113cdbe71f95f8133f0af21c3e073dcfef3c3f077ed4e379c8f34f2fcf2ff323d8f36fe047429e5f043ff279269f882dbd4be49b8cc95e8217fa4afed82a20fff31c6981defe7f474660ab38a197bd47ce6c55d79f3d4806d9aaa07fa017c920fdf5bdd72187d821cfbd04df4392b6ca921ff43e4821b66ad6f3deff20ab625f25e497e8ba449ea7082d8890fff91cb24a88cd3244ab125fc803f917109b058716c1c76cd58fcff91f9ba58756d53d9087c59ee75fbf4356c578fee7717e1ee7796c16a755f9f89cffc8aa1f9bc508ad4ae77f70fef594acc2b1590640ab025fc8cb66f9a155bd1ec8c76c161e5a55ece9f720ab7a3c9be507adca7b20df368b47ab8a7dbfcf6c9649abe2f99fefb159385a15ce0bf96ab3f4a055f57ccefb9055329b2546abaa1f93c06609a255c13ee7877c48560db1595eb4aa1e9ccd9243ab0a5fc80bd92c4a6855dc03f991acc25255a305d92c12d0aa62efff36cb8c56e5f339dfff933fc92a209ba56955e3ff3c96aa1acdda2c04a055e5bc105bf5d9aaf1ab74beaac757f1fcce679934214fda2c47b4aaef81d82a209f65d2de56cdafeaaff2afaa4f3f02b22a66abb24c5aec85d82aeeabbaaffa7e7e10b26ae77f6c55cc56f57c95cf57f9f8aa1f0ffb2c9306c456815f157e95f855398ff3484e849cbadd1f248c94f98cdf07b981cff87d48117cc6df43ce2c9ff1f3909ecff87748229ff1f72039f099cd67fc2339bdf88cf97148253ee317c9273ee30fc979e5337e909c607cc6ff22613ee3ff48249ff17be4073ec3f2193f47ce303ee3afe4fb8c9f9218f88cdfc92a3ee36f7272f1d9cd67fcb539356baf0be7f3fa175a2d4f3692d8c2d55a9350e1d65adb502449a490c3c85dbe2561c22d7f72ed5a545a2ba572bbe3073b6278c30b17ad36c1061d31f8081beb582ff0450e611071060aaa386855cc15a1182f5a60e3f95cbe21e1c62dc7f733aa5377ca468511e6f3ba2391e6ba169abbbbbbcf36469ccb3724ca84976f482c71ebe51b1261e800cb2ed4edd417fe2f4b4c4cfc6d9beefca9aecd6e027a6dd44d7af399e79cb59e730a0210800004d0825d30a71b4b25d7c87f727194e32819d4320f7cd532115d8ee338fb3e9b39801ef56ae5b830335c8e0b83c3e5aed038ae5236d4b97e1083e58e1cd0b0230d9a5b701d8923aec32e5223758744d61d2fdf90c0aa68c8e00820c6cce53819408e0b2f37398e7bea3dc7711cd766e4b88ea42da31cf7238cc65dae4e36235ffaf43d0ea22c705367d868228b356dd26c410027ae9d2a3e10870976ac40c31d021083c327e6871b6aadb5221113c3f7859598155e47bc500572109718135460336b1e1fa51485365668038b095814b1240c1b310c970a6cc25c8113e60b3639976f47587139dc8c501346cb113770d58af8e28b13a2e0001848b010804b7f3ce2d23048bcc086e7f2cd88372e78f966841964cc18b7fc887333b9b8a9e533ce92c0d9d4705d5b57136b7211c1cb15911f75df5f2aa94fa3e4fb8cd3aa640c02f4eb574b82f794c6341a8b4c3658c0a4755fe977768a7b5aa5be4060b251c414369af7f4a5a6b8efdeb353dc9330d5599baf49c3051b8d3eaddf0ff3234a81dbda4bd940dcf95e6210a8cf7d7d4ac620409f7bfadca49123696badbba30124f2a3a6f183395eaee73cce1307afffbe7bb0c8819487d40c101f7cd092d0e34507693aef9609ede1e9b8b9f3e9d69ddf7179cf539fa73a5d8f17bd07c50745d0c6fabfb669f96c7e0f35b1eebaf371faaab31aabb9dcf9957caa2f82def7f81e96049df79e69628fdff91d4b42f73d9e69e0b765d23cbfa3f33ccf2207ddef3cd6d59d2f72b9f379c818f7351acf83957ceae720e7bff77fe2e0f538efef040129f0c3cf790848893ffeebc12972a0f3de4f9183ee7bfc0654def708dffb1e3646dfc78b083e9baf43da627466ddf93d160c0f49e6cedf21635c98db9d2f7224613e7b829ad7c9e989010c78a7270e6210787dcebffa9f388841208704f1739e693dbe2d93faf475be7b50e759e440fcdb8324d22163fd359af7201519c034aad7e74000fcd7b7c881f8394f3908fff52c7230da1c1bf3c7d112431224d9672f32e676036e0ad47864ac6b34f6d9d458abed9d01b9c71823680c2222e0b822a20d2aa0cb3722cc5c269e2bd133a571441877bc49c1863234a34b7f24a2844b4da0d10f72cb44348a976f44f870bdcb37228e5842646626828819de00b941fa54866bb992948db4378d7c0343c465ca4beaf7575ec2b30317369da4538b9ca3c9ac00d1498e15ca3e27e0077b16a501b98d687bd7fb8e97741c2fe12a2fa9ce4bbc79494f5e32d908f71ec9dcb44bdcfb73b439d0eb7e4ecf96def52ef75dc771b552eadebce47acffdcca0bbd563efb9f63aebd4dda57e2ffda16ab76d7793ca007a0c5baacf7d19c26477ec5e6cd25d66235faba51e4ce6f96c723dd198930c07bc440af8252cfc92b54a465326b93a9ff3aff1f93568a3eec8f359ebd4af7bf14191c47910f4beeffb6c599f7ba4f6ca0dee12597edf971b5cef91fab325d1fddeaba577716cf95d912c3dcb44743f269d0d496ed908e690fc6aa3fa738ab1fcefe3580925899210895d63008f18673fc28af012ae497697e8d7eecba0db0f56f27b0eae7fadf43fb274cb24bbfe1446edc83ee3f96123f367995abfab2572d2ebd632ddb84903ce5b59c1e5247de4d16e4390b90901c624337e501b79fdf945cae96450cb828869410d195edca0c695247378795051cb44746badd59f2b6381040a2868c1b505133a14b5a967a4f02f83e283de8f463feaecd7c260b199a20937e8500303adbed746486efd51cde58600e3f2ad7e902d99882eb50fc538ff83c22c6ef944f58a1b613c65b2f4082bc7cb030214aa0d63c5893f502c401a96e31d61f5cb221318b9093166aecee526c2b4a95fc6f9e37cd84f4999822e0a251c511a6d19fbd1d8b20fe94d88142e7d8a85462fb52553d0e596f98f63461efd887a4d8e3c3d9b5f71187d5cbe09e1c2a5976f4260dd72bcf369bb1620b38ed7b2222dfb52e63a3c2d8b515dfa31ce36e9cb3ddf40c075eb2319208edb5f45aa8ffc66b3d9aed0fa356823be8159739b68cd6d5a395e0cda686c2a6aa3ba25bb39a20ab96c369b8df6856f41e8704b8ee3f6736403c8e0221b3006d98031b45ac697a88d7a5e2569a3090070cb0a1a40461c4ef2651bd4b2eed2fdb4ac751ac066bced614d0f70b9f4bb07733c8f965dc73db5657ff71e39bfb8b9de775fd45ceebb69c5d83f29dff0f5fc2017fed42625fdef395b76ffb2b10cb8ff9efbcfa3cfd9b27b4ecca07befbf8d38491e6367973a9e0cbae7de4504703f9d7d1847563bbacf00727f4138df0357977efdd275812edf8098e2821e7ed84663cb380c5d6c52cea7dfd9d18617843a0d6063c6867689fb7e6acb9fb23e0f7dce2e55fb2de3ef2d353142e000868b2e38e0008266e4323f524de27d4469fc1c3447983e84f961861eb47a5073fbc11c0e9a5d8ce5ffd77d831fc9538af1f57c5f3ffbd52dd1a70f5691c9a741edce09ba9841f7d3964bdd4f917e472e711f39afd7d16791a3f39bce06076b7ace676666e6c9fcccccec313119256e7c0073b9efb807bfd65a6badb582e0d767b149fd7ae4d1e67b7d346d369bed8ae65935b7f494f8d1cef773c04b7ae87ce9ddefb98f9e5419bff4eeeba79ab19cb6696b23ef73826e15eb87f5b98fea83df83dc808dd4df21897a560dd0556a1dade795b20b3e0e59fe055f244bd8053f24cbf182f689de72daf856b219cf7a9ca5168c4ed338bc3bb7b4f007bda7a447bf92256f6ddd3ad38c257789e047ed7dd349279d74d2497fd22eda45bb6817fd52762d51cba82d2710b79fb6c8a4da699978eb723f45272268e1831657b77a7ef479b7bb89dddc6a97a8f5c296cd2d8a830702499287d326a2bbe41fb68c1fecdefbe69e7ec94474bdff1ef448af65518cddf3adde653ff268fd9ea7002bf34e4b6d13d1e5ec12fd6a476f360a58b8bbfb7cf7d9dd4f1d0c22cf6f063d3e68f103d17ca23e650aba4e6f54df0c7ec2b8d1e6cea7245310bdf3e95c33452693c559df4526ee64d73fc5f92d7acf390758bf6466f66a994e346477bc38cfef2d31bee8e190329fe17c77f7e1731f853debbe7bb07b1c5264225aaf65dd23794896de9db6e47991e5d83d4c21c6d2bb1c67270557461e73e70c337affa4b611af91a17933301ed3557094a467f53bcf1b4718ec5f46d4b23a7664395db89ce5b15dbe476abe75ed5f445b12a151c3662edb52fc293211dd26a2bb14feab0c6d4974c30fe279fe6f239d92e7ee7c8fe70a5ad6cf4326e9d98e057fec41becfe6e704c178ae28fee8473d46f6d968a72dc3ef1ec973c8f2aff83864395ed19601a03da8c409954b94899a24a5530acdd00c82800623156040402c160d482492a6e8f50114000e94b04e5240934bc324c63114648c3106180300000400200446866cac003eaf82cb8762cecfb5d69ac2b5b976b3a285b3e016443f2c8212281b4d9a62047eb73106fceb9e929881cfa5c24c2e5c64699e1cb73040233b3f120b4f0ea9a64ddafda0210d0dad697261b0131fa73ec8ce8bb7741d1eb8e40067e26f738d2a23536ae20d0bb48bf66b7723b79b8b4355592db0a1048cad7565ef4d6dd2262a4fb3efe6db2f69eafe8c7b55f1f1f2822be9e0471579b298153a6357d17fb35900ba581d6035b772a40c9a7d57ebe026f1b85b8ed51c69f66f6ae8f1cabd79ea8894bb73574af906db9db503bd2250fe2532581d15eea62d5130ddf849ef45aaa84fa3b544dc4e716a8d16611fdcd957db746d2e2b3a6b8595de76b3a0db565bf46d2e2b1a6bc54ad776b7a0db565b7436372b7a6bc54adf76b1a0d956597436172b7a6bc54ac78e4bf767aeeef5c3706ebba5b0154fa92bebbb98b85d222f26aea7e03c9f20db9b43bb8f5cb1cd9a06723f121366eaeceb3666c46d56b38dcdd4da751833629b1f8d8537dc4f9e29c471623c6f04b75e2b8913f1a61285ad81f9124caad0129b59425997f331e0d8cf0e0b4344ebe0496bf73473172f5c18b0ca0c8a8a0d9408a4ae8ad146228056dbaaf084e1759afdd721488fa5ce01a0213a4f7e33f8b0cb535feb9d2f55f43524f67e3500d36bdf17c06713203ef960fdf9049b9729bb7cc294ad6d482509a0c7f268272c0f8635b6fdc948e319d0d6b009d24c6e643b444caa19d0e07369032869986d0506df0b1358e52170fad77c0d56b6412f38f0ba98c0160f9153866c2a84785dba002a2f88d3b17636f13264d7dba058e8dae9392285d8cb329ede8c6183d0805000170205aa83affb536497d0e251ae2cfbfaa8daccee07cb8eaf9d1a0c4cf9d7cb5cdf66d210ab1d9a397f1f4c554997e5788a4c5b9919bf6d350644ef023efc4150cfdeee60fd6c8d0ac70d3172f0034401a2c1065510439da39aa8f21751b2f9ea4524a21bd0784f10d9bc63e754f2321dbb36a5d9bd3e6184a82557e2b9f311610cc117d731603e8efd8d3fa52fb4d5e6c2745abe22118535af8084ada365cec08d000717973990641229e184ed27a4cbf83993c813b4e308dbe6095d7251a81dad02f93c53a4a95e86c39d9d232486a20f46aa36cc3805112b9f5e04a4c0b253dc26cf40abd127871fdb9d8c5a8152bce49a16b005120fc2df87b56e6d515694c58529564a25f306311696deec25d0e055564eae4dcaab8e5fd2a9aa492ff1734bb1731481358a86ac6b6cc7d4f36b3d16530db734263dcf0ebade076df71228f8d86bb9aa12d737f7f7167345d80fbd81b5487ff53c0a80f95a5bf43f60afb286d4afde8002305ecb36e8652193cd0f7aaa67ef9f67d512fd2d9ef749eec406fd21304cbfbe0db4482dec7fb68e152a053d9237b10dfda185202cc7ba45574a8ff48f7b7f5700c272ac5ba02b5d7c97dc99dc827e158a40d88eb545477983f4996cd17f8282f1f3f691ae90dfe8f1fdc426b93fd98e8ed222004cdfda0c5defc516b23fb1195da88a70308e650bf487161b64fee46674a55184c276ac5bf48b37a47ff44a06c1fcebdb5fb25209f3df4d6215aaa84df226b6e817c3c1f8f94d638ab542ce771b2b933e921ff7aac2c70dd4b138117c4b8b3eba6deeda3ce55a10f8b22d7a89926243a7cabd0302df7d953462df25e92e45d1490c96b50093fd37062b000995c5604bae3551d9e08636eb0e1f2922e0ecb2649a79863b40ccfed4382ea62e007674278a7853d42ea2e05716537610f31156ad7187703accd757039c5c4659554e62e924180895ac23442acd0cab2ee5891fe750299157088e6fa42dc2c2e90d331a4b4a0eeb1e465d67530d898a1cea28104953428ba6fdd52f7f42d1caa05d766eabaadb45f048047cea499ccb6614ac0a28ce668b0058d1f4af49e8639de41b9fc38caa2e6dd2c95fae219ce658b826ce3091fa2f2ca9b92425137f2d925cc5141b07fb82b7c9401211ba46ae8f8073f3203384fda9d21976b6159fce446dde30b099d891a5f804b478dd0f88e5c1c795aae44d564b51c794ffac07ee7a99bceb5b391f8869f2c319c7bbff8bb2cd6705f41f0471404f8417b489f4da895e1c90b2df62b2a41f1e37f2818e13a4d021f818f940f5b6eaf49fb503649c650ce3e3b95cd817257518f41d7fc4c15550e103677051f7c88ea4ae6304751fc110ec9b9cee01b463f26c5ee776ea245dafd98598397cef2ee10be32e00d09c780e5b4584db773d0bd6f43c7a16d9e57ec27e80c7be749be9b6bc3ad47bec109535220eb6b4f4b2a11688b4d8e467960e9071e8face4cc436dc564be2057c0a4f8564b43525f285730a351f51ee38977fb6034ee773f562b878bbf1c8023f097c0bc15d3d2bd643616b5f066c14fdd6743b7b411dadce4b2cf4c3844db5048bb2264042119ef6ef98e0400927223b05a2c85be30ba66f999503c1551191f26afb72463b08c3a77260a7cc26f6e95becf0d014c7778e036a8c6cf447c019f8251aa8b11adb1c97f28dbfa081a96f3081ecccbd7e6082875109ce1f536db93e2c933d5a49f8eeb5afcf1300fa5d5deba0643ca31e885230ddfae9c545af766e187883f673d5b9475b43aae2ed0e0bdb411edb410816311d01cb4abd370d8e62f766e2a9831a5346a455f3cd8844fe67348588e9fea6f845f45c24850efdf382f77c583e243edf7b787d1898dd1e0db84ae2f0c9f19a33227b56b14d6cde4098c3fe8f6796a113a6f214d9c424bd6e907cd4a96c3de522d1450f5b3a69711fc781fde320b5ad0d3201cd60826589bfb98129ca8bf7a50130bbc254b964e2299af09004d2fdf462cd05d382d9ec4a6f73291850da4d9cfceae618f6b9fc6f54ee0e22be96033a95c54499d4f0b9b5238d307104f2ade1e5121f9739a1141ba2b4a52e8e4574fe6612859878f81d38b43cbb71c6b1caf219d1d632c41843eca660ec5b8f1a206d8ee4c93494370fcda6ad43f91e5a068f5e5f5457e44e265a825baab93dd29016a8cda7cc5b85db0949ef68c9408a2389182b71139087aaf806bd86baaac6efa846e49da0646f4f8de5793ae29ad1d73fd8b8c6e9fca0136ce8b941a8fd029c0d4e1afff42bdbf6c6c270152e92cb8ef6c66114e69f132a90950b9b3293bab2e7bed2f2c55119de913760e42f5c9868d13c28b2b544c4cb55c570b371bbf45fe4292bb6ea073a7195719dd04314497ab71152c69fbcdb0e211dacce55dfa1fade46b1f4a7b4ffe62b797a994b063dd72a002573e687b0961b88f1512c4a491666d6c2ca23a40ebdbc6ffe06261f50df138d50c4a69c50094dbaf21017203329144aed8dc30713d1edb5ca11ece2527e10bbc358c415be3458c0f48ff9ef1015af9d961aceccd875f163c22ce46a01bf79c674cc8f5be9a90324f39c0ea699ddcbe503653aa34ab53777edda9dbcb17e8660f3e09fe8f4f0e78ec9cb51054a5ebad7c5c7457f39b1af6e1f70a2a0d618d00d613226c85b4787bf192bfc40323bf502f65718d1a4be772c4e5e19b9d48ab2ec8df8b37f545dc10267028842ebb5045dafa5582daaadc0760ba805b601b72c6c55a3eb0fb40761fcd34a67cfc7fa298282fbc2a3841bd9faf5fe2665694aff3d4cde122ce2464ce5b5e277eb561dc812d6909745589f8b7023a677415b5a21e0442ceaa0b6f2d0d8b532bd571683ad5286f8372049a7b6d7ff4d695607db7173f317c2307207634140ab4697ad91797f2a05f0b01975876b10d9ae616009012a50b070c3a9d35baa0877864182c7d729fd13dccfb84f87f420dd92fb54d97f66dda04fb2ff42aab61077f8b5ac2d40f345d343904f6c99fc34afbedeb1bc2ef4356737e894414bc52878ffd111af22984a3b0e8d834ca37b7975608bdd45a751e10816e65cf7a958744c9c4a0471f9b336d28782df1c4b4a074cdfc7cb1957297b23f74b2f6ceba491ef61d496d3e9d763cbca2a852fb8504df1724891755056e5a33141003f6de2521d109812097dbb4c4bd0f0adf5fc28c5e8cdd1931af507f4fc7773eebf8ec17e0c835dfe309434f8291f8bd2292869fe086ffabe8dd9833178a58e269af51296e089d21b08e925757c46edebe58463b34141f00bec9b7d9f57893b561206dc3aa391c9d26e76ef0df8ccf24495f6d701851e382cb81f74f18d4f1718249e0267fe1bff021b4cc7c08bb8c24c7fe76ed3565dd854c7fc15c0dee13c9476bc6dfc086435288787bfb982a776e9aa290b297b9e8b7c834ab24ff2626e811ac2186231edb0114d7373dab53b98c8f8c3f27ab095321349581d9ab3f901164a3fcd6058ddb031dbe1e3c56d500eb7e727a00ab793e42d04b4a5b6524d25c3b543a9a89cec89c351aadd423471cf883d1a7147b7789a1be71cb97143512431d586f3d950bc068ac8e624faf03bf67374a31e4bb3b9c667e70d02c449c9c0ef604d2f3181fad84ebeffcaf4a856cdef3670fa7c6b4e8f436705c135bf04008939d81cfd9fc1344836281b375fc075bbd8e3629f4c4a1e1d164f14c3c84cc2d683a2be1724d2c6c6ad3d69b84398ca59ef9de1d4c08cc5a1c15808c026cca8bc7c1b894d35882fa6730b9df4016b1a74d86691502504dc18188f6d2ef3e948169ef43e23af8e2388890179df775479bafe7c39715ae747f0c1832462f6d6f9688a0d201a9996d540fb59dc8e0517d01ac8ea50b5a49ac2a3947b6c564aa146e1d802ae903d04e504e8b0af2aec4d2c86ec62f7e0722d509e5f388e5a472d00c7a889b1c86656d70ab81263a8843c35b980809e77d684cd9b18fce0507c6227e7664f823bd5b1c4bf50a0b93431009aafc1be750d4e94931d8aad58ca2d0a67b99d388a50799bac45e277deb2c158a40e1cd5292b2065d2818dbf0e7ec144381c72598292358f692c0cdbb18ead17433d90a2902211623b2bb2d3316c0bc8fc073c87792b2a0834d056f6be63862368503007fabeac5a6e37d8243d42c62f49a60b3f702ff8adf6ae0b7d1103c0192a2dfa82f3d0d7af7e32579f4205a90fec8a36be6f645ca416f1a6f2b09dafc872202bc4d4f65cc1ed55638028508991c6d2988fc954c71ab40ec46c04834f958c8ff241b5c0617ff93df3610a39264aa9526e2ee336975134b99bace08d179b640858a4c06af0f93b0b9978420856b2dc02679649ea078eb4c7c264db17e358a6b2fd94d599176c6da5b801f22785e364936e34f3d17574c47395015f21b36dbecca695c57852987a0f212b70c234effd22f16d588c1c665061a2a890f65ff16602e0a417cb0f77f366cd19ea1bb2152df36739bb6ba51a85b9e10a75149e17c0cc426ceb59f3edff614cf4962fd529f6ee374bb81bd1ec352231ea41cf99e5c4943c12e28a5c9ed5de708413d3ad334708769836d837606d09af0a1aabae4adfccfc135b693f59dd041ad92ea50283b71cbdc1c89ca61a6b1289c1c7930db16fcfba1988d5b208e5228b7da9df858c25ce86257336736f8397be46d18aa9a88283108eaed9ab4b92f6df953ecf5b80f359d6124a3c33a1bb7450eac8014c2e6c6f23314ba1daa20679a275e5b675f6e97a34ae9973b735d8dbc43b057eb89475f8286b185b50071bb64041867a9ec18cc8f0be06051fc1255ecf67c0840a408da017e464a580d284f9132cdcfd27c890c2ba717c0394b546a4dde92938c19ab2a47daddc6c9850667c4da0727716b54025a7e464548c0f2cca7cce9f4b87f8f1c9ce107c9ecab899a11686cff8281179e1c9c172f69e91a73d2bbf76f20412a14d31327b8cb820c5e10e82f0112b1d373182e03fe490a3081d0ba6b67977c43d68d6ce478295b7e0678309448ea13a0f12899f0a6be27f8e08efa36d177088568e1dd4e2ecc53c53c6ce28e730a6e2f0a4ac6d9d555afcc3805638f2200214f2b8872368e8db1ec79f3707b4765ff0a1abfde7a141b736cafa428742465efe61cce10287227448280d932d4bf37a996d398ad58f4546d4d776428b8a409019f824244d12d26c9a8220209182dcb93b10bc2cfc7c3d1129af59899c015f1724489c7b3be79f37824c6427dd9ff129e671f36fc5037ecfd74832ffd6119f6248764d0c27125e23c05d1a20f2cde3fa0e58552312c24677a2e31e9198fba43a6aabcf66c358175d133147b41fc27abae6ab291202994fe056f1074f4132cd094310fc7b3647bd41fb20b97e6f4696a2ceee219f2035ac7e1f5d184a545fc167f7eb76a794ea94106ecf0e46d0cdb4d712935ac3c5acdaa9ede4ec3ad662f4f78f4e8e10417bf47303e58543942b24cb457dfe6d04f54d64ddcb8a6a19add0532fff8bd29f9d306bcc00a151766821325916511747e1565f29aa1bc0f65ba8fe6bece2abcc0b9e745b3a624c0364ca8d377dd234575dcd5a11854014538a91761961f546f7db96638bdedc076bc69cbb40d6835111cc9cac3c94bf76b2c6e76fcadeae6ecb2b6a4a050e3c4d022c391191200e2331b555240e54cce04c407e9029d0579e35bcca2e03b4d4b5a5c0028e87990e0fd511318c998a6a8d0573ac5268a2c43f8f367b88c6a527204485f2eb30744e32a0fa618778abdedfcd917cecb480b04b36ecaef6752784dd7e812f4dd69ea941b5247625dd5383c0dbbc3d970aeca28153c98b063a6bfdf075ea90553099499631bc39910426bc4df15e05d4b986e19d470deed8add9ac6a2e5822c78fdd7fbacaecf93444e5380f66a04280312d0a6014adb33e0eaaeea300dfceb401cd57306eb21f48b7ce3bec03ce82020b03751c08a0330f2363b0661c7990f6ecaef03935f9deae0558b8612c6e967abe56a986ee8cc7c8e9ec64c86c8c92056b5a966663e995538d88bfbb2368a14d824b1cab3412b297420dfaf94f53931c303b16397a243b5f4e9020abe2eb3987860f2e4314baeabd039cc2c799270fcb0c83463d6139ec2adab5e06ed873f2d74c63988c837d0a1b2b686e3b966813830cebc6e003c5c20e61651f982dc24a39455e458475af067fb9fb302f601974b7156b0fd345722fcff232932608262a63b12ae4d82571cf36f28691714877f141a2b36ace71478046c960030d5107834d8e6b4b1e523c46be157c3f08a937eac4f647ce1efea3dc1c001a950b5877ba75a0666dfdd7df6d1b5489397a841db6d7f6a7424afb0617246a3f6cde24995ee53538b2d4248a420fd1d1004f9c4780e5a28379b65c8bdd3300e2143bac63d1bbf3653d0d90cf3e3aa318dd4638bd5df39340732d58fbea060f181854359a6d324f8a9fb91a0d72a5aa69f1d54e25578d80734df34860ad6de4aaab51961528afa8fc199e0985a0a55fc0e0cf5213a5ccaf2c19ae216e625f7bc19decac39a8a4e4c9a8bd6c99530a9a159a9828315f0d0de303dd19c9084f4f82ac7cafef3824fe76347c63a78f3bd3ca748d6181b3aae4589f3dd9a158a31354fda8f23842950fbdecff517af1abdc582d3729655bb3d62ebf82b2d76202b030ab3edd6b3bcf9872a21020d098cfe474131d9f8881b8e320b1d2f92a1e6a6155ac7c825afaea89859cb6925f8db13a1b368bf035f966c361322d16cc9c7c432b89e3fb4c9f5ede8060703ba617e0ee3e1be41e8878e61e691dcd91971a1eab52bb2094206f3ed31a90a9c7425791b93596adb98188dba61a0ae98257d82925271625a1561e25fe62a5f4ec490cb33f1f84f291e709047901a3d230d647ae10e81eddf6059a3a14f3f0aa1dcba6c58ad04fbd54c860925e988a20112329eb460e6b766d7c632a0c995e75cf2525126e0454b7c703cb30ef606c5cbe3a620e6254bcb7ca8bb31cf844bda553c800a5dbe1fdeb65a9827a40ceb129e8cc8c64857030d5b2ace7aaa7d6448771bad1ee3eb5d33446ddf86c5340cbc30eed683ce3154670352da535a4ae9ca877ee99d01da38f76b0761796b9ab45fc4132b95dfc91eaecac6d3641156fa3af3e9d7e5d58686c8fb1dc59e312c5f8610c9a3f461c14c33a8cc29d3dbca82fa0905d291fad098fce9327bf3532eb4e80e41124c7f7d6fa25969148e92796844f79b9b14a1a775ff7679d81647cdfbac382f3478b3b10c861c42d1b9eaa7998aa9de41b83946f682f8aeb0dbcb1b7007df86e6fcc6a4cb5bc08562bae4233c01a32dd8e2fc98cd8e2da5162b48ea349c46318c13d941b79f7b9017a1abd747550b30ae18250f4c9ee2569f77ae15411261d39c1c4d8cff22d71ba34249f7805cca4e0357178e9fd05bf89eb50775e10cd84868345c6c19246c124a82535508004e488ccdee4287b70e51d1c48cf2cdb65925c82a54f6d2bde84654497bd64446a74890674443317ad4bbef9e48e7acf7f1cac6a7add9cba48340aa658292fff206192b2378fff77e64831a0247b663aace9094902e6eb7c8320db16c9af5ff806e02ace02bc30a0e22dfb0a0b1a457b10fc1cb1e90c2f215ce9cb11882650895dae92d4a29cd625c6401713c8c2c8805f00988201352816c6039d3e6940624e396af85bc5b2134e0fed64a53847d6be900bc525e93b1627789b4e2a8d94986eca33ddc4c2ca4c68d895d5c6d1bd70cbe2683f9d7603e67570a04604593c6e14f003064186e9048bac1342ffb4f09d369e4e42f3f816e1122b211b6fda741efa7a66ac9c44d18999f0ef7d1599f3446fd4f543d63d1326271b94317358cf39f19a8d56a0cd99a323b8f1cf3dc9505705877e4ef2b042e12e2a7e5c04a4e40487694133e740fa73127b9e371fd5ddf549a7e242a405e1af5ffa45a71a2492f73b840a28bb9e5d6636664e06fe53ba09dd289b400292d86def32387d22d79a4e63ffec3a170a95cf7fde59a8ce47bc1ea19794da82272661351f8826e261fc9cc4a4a748a8a88e0257772d98c821f2643cdfddd7044c4cdef8fb4cc22a1222286e49c69638eb59530400a4112a5240cf8b74f458ccd6d989ed13c52e16f0052a5a064bd78415466aa9a88aee0f0c936439d7a0c0e36749b66f8ced871d8ca8aae5f9c0ae7e7c5f69b1e42d70dbbea1321e922bf10e92d5e5713a5cfbff493459395622337344fe1f1c194a02dca875cd68446816d23401f3b45340b9795e33b6f5dd26b22ec2d04b6c20a0cebe12e58c3631d323007d6dbba7717d602432eca6c06424342e21373b78f45585f65c466783a445fe101750795d558f944d2c2b2bcc618562cd8af6207ec66713b460b523020115bbca4838b84077e0c84c8264dad76ae4048c29671554ca45da725d2bb84bae4b6ebbce50ad02580a28a2b460b8f1de23d99e7152204bf5e8e99a00406b08af4f3b70fd25c3b63ef07f5a148904af9a06be3649702f69bc8cb594034539c8055f06f7de2f988e0a0fba5996630ff34f0628fa3398515e9888d72125991169b1c957d4777445eccdc86f00c871ccb28e68d5211b3a9d97f910d5ac17451bea92b1371d4423956a3670743e0fdc94fc15d668e7f67dc9fa77755663d2ba5bc5289e839bcf36ee0a7ab7c0c7b3b6273b0b95ba65c30d0057e4272a3dec8670c32b03176ca5e0c0564a5c682bc10719fa01d0486eb8ccbb65121561aecae76102cb1fd130f39515656430584f2eaa8bf83a31cb928a59bd0c5ec33084323ae99060bd19bad9a6ff4db1302b8d23d957c21d256b11b73fe9c8442a46a54e1a194406a7655556b34d7551d4a873a373e98336b12b7ffd5f1ac623bc89efaa95227444d9402902da3656e2dd42224356fecbb90c100896b103f18127fe06348828f7e95f138c1dda1bfd3b80af0eecdb44c0fe55373848d88bf6773ca637f18331816c4e1f514adcf5888885c4e82cbb5aa6981666dcb083a28a5528abce836ba58cda4ac12866c25a53b439a35325571cb418c59cbd5f4b0a14435fae728a6c22eb63ba21f0b02ea2c88fc6931185faaa8bfb170bd997c49fad6c4c10ec4e85af1a8c0551b2c071552727596e7a4c6383ee81591c8d51e04b0348e40668cf0864db44c470607b66bce09bbd9d49aca8af8422db542406249450b70c2a88b5474aa05ac6f02541531b1a3278774a52ef50243b7e684e5cf89e21967a60f66f59d95f665af2a46132cbb3a40df1fbd2597b46d04ac644b14d8d44edbe6ced96b750c35d7ef65a705cdb35782dd7817a771cb830a69582b64ec18fbb470b69de10b744205b2b716c1a45f84b35602affa802c781ecf05a855512adc67601ad6066ed965e7d09c66d4aa3f07c1b3811ab615dee36719a67fdb391ba28c101822f0e947fe6c40e29a2461f883045d5236c6acf98c0d4e516d92bda8ca55b8e86305f984477984b78ee01a071e50aadbc6d8ab4e18b65b40a35963bae13d0d8d03567c6265cd69087cb48255b55c8d084eac238b3217c5ba8f431d1ee73956585bd296b339df433356d3cdd003708daad999fe7548a5836ce2cb614013208e2710719fe7d7cc959e5ad28f9b2d2fa8e6005044f000c636eee67ce69c2c488f9059dcbcd6445fdb0582467c26e8529c410a3a35dacb2d4f909c21033f090c5909f5cec4aceca0f84639f6fa8cb5592bd2d98dec5c945fc4de62a410d4684fb0cb10745872293a626bbb63fb4d5cec198789dfca975030edc7303d840b4d270da1e501a54704f93d6ec1b760d006e107ddfa245070f3049f423f512795b690beb048cac6ab104e6d8110a3d95668ef1ddde484f24866e74c6d05234985483dd58a2883896e0a096d090b2ccfc5743cf49bd84912e521a93345511cce6733dbc0cde1447a1f17c7d970279fef0113a656fd0c67090c154ecf47f79c15d315f5bc5f4431880d4bd71f733a54e1f72374db709cc62f6fe04b38e6fd57cd18ff31c08c4904180dce7972eb2819181ec8033f3cff01bb91f8193a858065e1d784f1258a2341d823856b5540c34f8bea03c9f184648040b4e15a404f17d7a4861e0d3d06472b05904e3a09bf5c84baa6be6db017b810fac420fa7593d0fc364d40726300897a58b4bf0379d470245036ea5842be219028d27c120ac55cb4dd390543216ca982372eea7599706757bad8b70de3512cf63e37aa5bf7f18c017c047a3a40db8949ba7c75981a12cdb6232847eb244bb58e5addaa71491a1c38d7873555d1195ba9bd300bfd56d5fa4a39b577f4e8768b08c820f17b6e2c83f881998e108488ffc03be9e18ceed0cb1e13f768d62015d10952be1042d612e023d189e7261c2fb4ff6d155e563a330b5b0074dc8c2c702cca6257435070d63781ca0f9e6cd9707485ce13a144ebe98a8671d8cc4e03be923d102034a14d5b3bae298de44a9a3b98127742014a90bfda0eb4c554c4125b5165c8ae33bbc8b061e37383a01311d55669b99a4900ee76b2557c14caa389dc69fb56046612bf1035f44aa8d7d4688b85a2f272c74120f667e81e696af47b9dc0da3c1df39fdb836d60bcee929b5775a45c799fded0457f4fc00be748648df675fd1601db4122ebe132aecc9842e16fec36246f444adad8618f3161b71ac1127c22300d35a323ae0f85fac514c2e2cd319f2457965303b24639825e55c98463ea021693af1df30fde2c8ec6affadd3864e0f0ad06b9168b0d0c14c7a5073490150ea22b9f87a9f36981a3c68e54a9bc47066681be04a5dee16d6d4aecc8bbdfec2aa01a8d6159c7b99a1f5194d3eeb4c6fe818d6ebdc5343ce0fc379e6a00b9a1d5e5b869480eeb868dab03167ccd0a55ca4de06879308f49daa2f715d0d6c97bf50f4f42708ca49380172195a1595a672380633b6cedd1b05ea060b6ff7049f67352aed578b16161345c4eb0fd44a42d55566234916a2d84a079065aec1450dccbe353ec376275fc8fbe3856e95a799701755d821cfa047dc05dc734c5b62acc58f0523fe0f68effa2755d9329662c1c67da38fb806348d9f06a9957d84a7a7d905efa582ce6212b564d0fcade56ec6e5cd899bfcc1f6960cc5e12228a757992bad2ecd074b3605e912c9033c595d0825ed60f89cb9cc2fb14c03d3e5865db4bf2ed76db903c3b8849797558e53497a6cacaab99016b29423b3d399297a093806c6a4b385f75c2bb2781582517417de24e744c3f2289395784d549e3366b99fefa9edad9b67691dd2d1bcc990091e4e786ed8a1bbc12b45a48005d83dfb439985f39e983a89a4b52ef6b82592e26affc2145d50f75110a3f4e84b0484b9fa67c8ca1b323f66e9b1b28e73e7f673734a42263ca57fd68a3f1efb29952f6a68310ec53a18c815fab46a52a375f07253763788165256f45940a4386d9563b9bf00a009b42218848a4f3e77d23735971b941462a9001807f46c8ce58293a5ab526443391d6d07befff21e20ae805fcaa225d336dd0142e9149c2a63d883c6c1aca1789b76defe3e2ef3571de63dda4eb1ec57b86477a5b8d674ac2ee963193a804b78c73b9c5cac05eae8f6b819bd574a4d94d731b6047b2b24684b72989be179e2b241de3c4fc57366424ed7877ab483b1be00b912d3a38fc262bb00342f81d94e1d8c9b432bf09d6fbb8429b73abe4ce58b3ee5d352c8d68fa96aaef56266a0f0b467defd9c0adcc0884683b2e6276280651624dbe5c107a6535980792f472ae2e28490b9c14eb309346d2ee2488d9890a2a4df78172ccdf422ad98502a333e1eb7c77d01b8885a03a13bf84bd46c05b899b0ae87b50f2e46ca2566918feff7bb2ba06c244d7974d9de6d3fa0c86893e3aa91ce4d3ecf223a4b931b6eec80374ff3306e23a8dbdf267979172a8a4d8cd918821926d3e93ee2598c3d03ce99ebea59523b2f578ae365860f99a3ec9b1f11267f878f279d274c0b740a6b3fcfc2f74e60f50a92d0189b9a36511ff3db9c8d28bb643595a5adbbc87cfdd213422562cf307ab0a88c8e528c52612b35cf27c8fc03e41ee9e40a7353d333a1de661a7cccd91da7e5ee1b660aab410a3d35ba4b80b95ac67c4d1bed1e3f8e41be022a76e48f290cc5b7ce8f7b3efaa74136271262b8bea133efd87b7b8b0e40df52f220b0f4bd6dca9eb30c69ea89dd187e94a8b5491c4f2376a740fffdb4ee5c61c202e01f903e8de6658c6fa97ed23ce494472da69e78da422df06f92b944710a521d648d243b2c31df30bea187b2a6184e86b6d9174a35a888c25419505530a81d89cdf0e53284215b7994967971a2a3f288c1b09061669f595e191ab202e53576d5c7445cd42e2876e393ed1d7ef2b074e2f344afc1566fb7d10854ba1e0207b52d13bc235cadf0c77afe27417881ede993174093ad11804c8016383e8021228543858594d17ff2c0bc8850e52d2a6ff939caa8a50fc96d4d8d7294be8715a405219c85f607540038fe8da71d73cb17954001bd0d6d64e478afd09dab1831278e8400e075aec38effc78f819f5f9a9b9626e10c29e9acdac9f3cbb3fde043b5850af8720662b1b2a3d3ec2dad1aef992798e91403c8fc5d004b85075e72cdcfd17277332c73bcba6a5008271196b006fc34b4d4b86d5fa169131f4b0d970a26cbcb16d5ab44635c2110c16c49dec6ea7c61a3f2a4c2a0b8f495b795dc704c8a7a40f7299f191e400004ffd0401221295210ed78537d53fa5a197865acaf5d06c271ba08f664ff4a72a40bde666af7db6122cd1d2ebc1a08ba0d8dc3b0688091d626b7039513254cf367c90641b65f017d654ecc1397cbc380cfe89a615024bc8d979fe4aa3c11ce5073a204279a53f437068b33386c6e6b583ec8a5c538e68d1614fe2c5d1cfda510493ba803162360a98d522644091a30f11153e8123c9d04cd166233a0172062231c0b85c0b0e810f5d68970b3a3fcd4443587d88778e07800ff0fc8650b89148ae7d61e62cb89135f25ade7e4f80612ef765326564dfa6c8a458e6319dd0e2e3713422c52742f2c27ee814bbed56f037fa4318c6ca8ca406bd4119cd983e0368ec684bb2262c3dab68ce27fe52aad9237ba6543b6dac382ec64e3466e2078b5824aa5a03d0c66edf71a70bc8e4b0a6d7d32f8a93ee70df2601cb3ca4beeebbdc0b016fe8c2f29e1998ed8a9a7bc67d7794ae275bc0379ffbe2e2076bd8d882374a52dc20d49220d955009c01dd5f35fe3fc5b0f0f26068747e74e6d410e8bb7c258998e2e1351d91261232e6ab8cb7693551bbdee21f07dac98bd4c2c06f96689410d4871bc4a33aa4f42e4c871c9c067643a19880be554c3ddb2b91795987d6f4f00501f24cc87750508966be3c27f681c35fe4aa37166557431ae96e21d8db35c6ef8a4923aab921ff83fb42f8290e3aaa97eed961bcd54b024f37c446f87e2d4bfe41c79767c6c4842cf002e4b94d438f9c7910c68e858e1233d204a14cf1e28bbf95ca976158f4a2f002ef6191d800840fbb3880eda65dd763c360e25b25c9bfaccb14a09116eaf8907e3a749b9e944f06daca1bec60fedb8940142cb596adb2908927d491a3cc00a5912936aa14eaf78bcd822058cc6b9bc81ea951cba07bccb33ca03d0f078efcf8f944e01337a2e3e1f740a620a9ee6e0cfc181068473be6008e410f67cd134ed81c81d219fe0d58dc7810ea1bab2b3f37bd46ea7e0df1d8a2e22d944c05e13bc09da9c1554ad12043f5e4656e0b845fa4768ad419061f862a2f39677929c1e2b140fa471e01fb5c8f8ddecc13dfb6477940b444f2708325e6518837631837d07399ba49802db594ba2fcde6957e8b1e2ef01beb0486f55834f58a12a641b4f3c1e5011db971be73dfb351116296e0b6d2ffded4ea717492ccd3d4ff85c584bde21b6ff38c77b09ab9517ac8f6c1adba5fecd8e69f76573332436650c19a6830012b822f585dc0e754ad9d5ffb80736f17610d02ee211a1f4b691242831405c4da0f3bb63ccb0b8842c679a9844e1769b406afd9df8f1c185f7a5cdaf27030a8089abe04a43bdfee115689cd5d49709e73baecaccd3c35065e4c5016bf02da8635da9b863921fa74694198797d1f4c476fafb62acdd9cd6ace13811a1e7698817981a511990981c94b263925093493cc42c1324f437a505f79f91c8805a087f6c2bc4014e09d46155f1a07f5bcdf1655e42622f119d89442cf2f04e3e302ca8bdf706f68c6b1544f7b4f0c1f873f767502402bdc1a9e6c4b57fc0c7b8a532e63d858b1402d5342916a118f47b481aa82e62954d6b1fa79ac1ca6e16a1ea4a81ab6c3bf2d6fef8865f04ff8a5fdc9de2167d223ed628d9502292b90708cf3b9956bb3863130d4426b43ad384ffa40d3abb59f05489ae7b4a4a15a03ba654e996213e493cb471a5c2694832ea0735ca94c7f9a2e11a2ee5c27db0ca397367947313c24ba8ca9da0d5202f0879487ac3a0938ae7ab8f4f12c3868e376e283409dd46d7a90a680199bf1cbd0c016a9b1f3b3890559697a64d1f36b1549a718491efe5bf4821ae0db4e7de2c86948527e62560332b5de90b3131f2207eecf27de8e248defc14190016b621045225f40403a16846be7465520144315583cc7930dcf928662522c1c542111268e5c3e5eebfbdfa50b0ba25130525db8a30fad0198c02598a4041a1c3a28ae934d3152c182d08ca21302b81a29f93234f0882c50f4c2aead4fe0a982e011ca49ec43dd89ca65e9fd4e3d8ae4d7e7043d263d349593976b8af67cd9826f28f49649a7682b9e7901ad1e04249174ed60a39804469cd95a9d10d81ed0f2e6eadf5157d10c91bd661c1a805fb18050cca10edc8002c83c12ab16bfb787fa354a71b4cc7276adf4e9be5e474adfd2b76b5ac02dc8e17f325235ad142e4f3d890ca1789b1534bd4800f421fcc0e1fdfee96e7bab63302e20781aea6dd03bc6981d488612f279d149bb2f84b83eeca1a5c1a32cf9791991f6e38c06608db697be973dc1bf697783906b156747a42e02bcec59564899fe6763a52d3cd1a84a776a4675e695bccede27ba13a60ab79e7aa6a6e509fd5616250527ea86a00a3bd609c926a4bc07f4c20ebae18ea8e5ec2dcd020a4025a3049743a162e90292f64adadca2933f8ff4c4496da1794aca21bfd3f19f8eea592600afd480c95ca5a7904745a9561c6b733051e757232b8920fe6b617629719f7e867fcc38d9dc76c41e217bc9cc92443ddbc6650a11bd6ce36e3b20a01c314d244d52ae85bb1d0ecb36ad42eaa5193986eafa5d216ac67e483b1d4c21e6fdc730f81200c5ebcf3ef30da45fedfc2965e4d6841fb1121542222b4fc11d168a2cd6edb567eca780a9cf5c21f9c624686dbc9737c7f5e3339a8442a11446ecb6cd2cc18d0946a30cc4157317bee4e162061afe05d49bf6bdae800e1e3053f01e9438a507801c53c1b59acd5d5c9c9a10bf2fdd369fa574b591c6c7fade3b8f5fa830730b3e37b82b1b4e92b0124ca5a0a10c15915417a206c056744823bbe521968388bd8e980922d25df6f431dd1b3dc3e80802dbadbb6afdaf8b22d5fdb25ed7d8bf5b5b8eeae646da02873b2605eb86785f75c38cfca59eddc9787e5e0500e9eae39de9ccb5166b9818e6e5478f6f7b542703a4356bf004e5b41c5a7cc6efba5ced0f01aef42bfa2aa0cf1d941e833205ae7dbca6f5e232788f00cc65035626c0aa0e77e381e952b544757a815141c5eb6524f4e7d54cbbaaead0aca33bf3dba9ecfb58259107636f517737d3f8501c6410749d8583b8bd11708f7a007929040c05dd1bc763f06899e0540e26715fe3f88bec8d2dd0feceedf8cf7bdc0981296e1fed5ebdeb581d9d85d24fff1dfee8cdcf9f85405405a1d63e7fe4226dd132a19975198d9071affe8541a18b1ce3665d6464f94bcc356210d7cd24e8db6ac709a8a5d17d2f52bd9b05234901c962d8314f4d077a709a0e7ba526852ebc61908b48d3240bed75c769b8895e0f14fc880fdd07e5229373971a4ecc463a8e7130d5bb1dd3f2f42bb7306b6c5e070a849ccbc5dab181bd1a2f3d4ddb73ac1399e133feea459ed8d555a0add025cd11634b39fddaa61b84b875805e3857d092239f4f5873f4fcc2a93a3952131a61bf821231172893574ae9674f94c7ab0a8e061cae60bbb56b6024b51e14b7d31f6eb6aa3a491058502e0d0f4f0572b85100513128d02c046b6d56cec21c8c9aa4a411a32a42bcfcb49d57319ed71a29cecca6c0f6de8862390d7e37b78a77ec196ea8239d1d1b06c16816e58ed2711ea9ef781d30770fdad5d9d16eb0788d718f55863db9fefa4e03d7a213f5b897189c2974ceb06fad5bb6944cb88050a6713991adc5d3f511f64bfc4195ecca2edad235ac6d39b431881bf145b88fab84ec5bcb77872773e783b9eb7646d474084518cafea8f906d0d93dda09e89b4fd7a246d0f36a68448211c4b02852f042d4b783aecd0482a0d70e6180fe838af8e9df78e2bb5c304a9af4d44a80973aa8f03a7325170da19f0f4650ca02e0950dde9d3d12ff0e94090c373e5344ee7de32add94ada20a30c9579bae908d89fb9b4542a730b784e2dd6d878c2852e566a01de3e98465d42759ae35447bbf10c8fa4809f93335aa1b01b0a10b363687bfcf4c55e7995c237e35a1bc9ed7c4e78a9166b38517ed17176f94215b63128c613141f48f11afa0380ab1069ad336cb7df1096234add69ca6ac5251fc48306d53f506426eb0c7d6c21389818a3196efc2448ed07ceed9eb602354a44ef682b4e1b60865964f54a3a601429cfc0e30d2226cdf3ed3236e850fbbe3a2833862fb2562379d215f8301dc6c3b15806a78f41def7bae83827d7e617d80b55a5b11e929376e3917da90471f30c928f0b59a8cedfdcd225bc9f939394bd00cfac11cf3e2c59b368d340451af5684c87cb6239e3280c137ba7f84d04a53fc6829ff65b169cc3384e326e385a1788884ddc5c12d436fd6699b863e1a73242a01b349277207b78d53622521c069e124a2c942bacacd7f65d663cb1bf16d32f63329cd15e81306681e87358473967cd33ee8826e632c05ad2d53f85c73981c9260a01a2c8a89a79007dc1b4483e144ee238ab52945020a53da023945fe074f500129126aca5a5b6036b0705b4c4b6fd9c6ab03a2f91286aad0400cd5db4ba28faab50a7e7f6c4509d413f73e6652a5b41d36b27ab08fbc216ffd7cdc1337363b0a96baa56ae00c04af90fb7cbc2b2a79964e0940c9e86095cca56b40d3931a98f1fd5d8d2e283f3652afb720efc78883582b9c3ee7612e54bd5e0cd2f10829b77f9bf93a7e955f30b33fef351f090600045f5e7d8048e65abe2475817d70a4dc824558dafb7dcdd813cc9f9dc7315177dd7252908faaf23419d14c19159a959d562751c26160e760718d905dae85b95b17690c9162cd6ce71bbba576ff5b8bc0c35245b3c5aed8b63f3d2e8358dbf3e396e71de18af3e934e5660402ca00f0da9701fe9a9f8a0a2b48521f3becbd7684410ffc6138e073aad52c8237a2d18691a7fae91b780186c8a2e2c1d8a614f36994620cc9960dfff9c64cf8d9f653e84129ec7483550c43e09191c4a711496b165fee52f9703db2bd9c7827e74e54d812a0e5b11fbfb0f47842475abb538b7d68b128e95469d5b53fda076b44bc08cb1d0ecf0d56cf498257e8d611df02726377a3e98225981bda288e5c830be82eff9382ce3baf58829b164cb941d2788b4869eb2e4d726c8c57a372c342d50672508cdafca699f039dcb9e9976f9135cf88d24915b1a82505eba34adb37dad3743d1e21f1cf69a8edfec93e9ae17b8eb50e72989e36899bbfa8ad67388fe954c987a31625699fc358348d7379cba9899cce1a9f1fa0edfb01a39ccd1db3b0515f929705ea91cb0def5061a6f146cc56a8f92147401c8aaa7afbb96b2f8b02bdf3e28a141efe8e080b9f4c90187c2aed72d33ff8270d2ebbe915ad3fe19d60d67710ec7caf0e37d0ef451ff76e00f9abee414e0cdd9d150f2fb2c846c9057cc0bea80a21a0dbc10aacfb1e15877e5ed5bbed932d34f5b53aa29990294a4436dbbbedfd3a14b92042bd7311a8286c55821c71bd4238b54ab46b58052c850ab5178734a8eef11a0d5834e22f617984fe6bda844a90182b1847a14547ab03b18e552f28f1ef885f21c23a44741a5473b1157e34753bdb9eb9fb53cae4fc5085ed9f34a8c03e597d3f71ded7ea05262a0c29bbe11c303a662ea23597ecbb1d90e7e87014efbb5eda763c60d7e00de3c11a4e05209721227894a4607aeb0d345293f540abe61af357523dac4a8183211c93c88be70d324c390ed0fdfe15ee18144fa11016c5c2f5d6920edbfd8d12f17423a5ace94b535ed840b6985fc80a68a14d3d5518ac970a79973a990a87d4aa664e87834aa2766713ad41edc85ef9659e504cc99626012ec0e2127137096e4904edd1e7eef44a0ed16f3a55ce1f48ad06b78054ea818a72ce76623fddb460a4d0dcc056b5300db058ec0451ffd91624d047e6f804aa8c1621265d84263f775209f25e6a04be2bfe3dba127dfdd2423ce673b187f0b2af791025003dc221aa1a0ffb180282e55b6bd028bdf6919b6a64154d226f7c24a3d14cbf25ec66d60aef96bbabf19820d0f9f935c88bf2c28b2a6d29ab96d194c5a6e02a39bd14836629d0409d730f32fad846ea64d5c9adbe9b6a41cf302826497a2bb605836177cdd8716435d01fd6bcd4d3cf2bcbdfb16dd5b8dd94c72faad3e1e06fea6065015abc3621e71fececa9f359c608a85085d84a6cac8c78fe7993d23a75f37c390b86b1182f92987ef3c8884caf1d71da327dbc8089ce2d578aafeb000013cd7c38ca879c62d442a25523627420c0509471ccb3c66543780c962cc8d7fb87b9d8730fd00efe21f806b5252a41838bb16e2d6454f747da4c329f03f27fe1ff34442da8b899602ec124c19fca9423643b09e487fdd10ed257f7a2177bf7afc9ad1dbbe18800791a965e55a528c433063a4dc9f90dec4a51128f7900bc90b1bdca0dca45cf610b657dd897b055a1b478e79e326042ca212eb4b314e6726db888e3bbfe407452d201e610c2bca69d580fe55fcdc0e1f90676892b1255c5a65d716222145c9ea4273b3e1b725cb33708331a3f3d7350363bafa0c24e0330d92d7514c3633bbcc7b0e45abd0a957cadab2f65a56fa8ccad50d3d2f86091d392123d9684cda1e1ef7e27e162913547206d70dda236a302c8a104837b1e4a6f22a8102527d3e4869db0ea03fc4ff34fee564b71bf784a6c3b0dab7f69ec34e8dc629ff62581830e6290684041acfbea00c8d04176ba0a8127ec1a5c66584594eb51604ab753b9240516e14a563e75f285cf2b093f422961400683daba17e4926bb9e2c18b928f02d39a044599b0005c0a25230b6122024e1059a02094f8792eef5d2bb4edeb1fd6647dac018586e76feb2eba6db812aadfec394c7a50ad3880512189d9f3b26f30ef33771ed3a826d65286d39eef9b46c409bd150769e1da02b1f033603af6ba75f1d09f02dfbe1d3a2cb32bd4e9cee44fd435f7a870c28b1633290fe4ba8b1ee4ba1195109973315015d7cb7001c3ef242f22a5c5b0412adc938773559f7439cdce4356f901cfff034648b76cb9485b4dc0baa875182062627e15703e36cf1c021e5796f7b7f5948de6d711eee38d1beab86e689b08c562ef263da3b0256a090a01cc7f29986ad2465984a82d2285b29ffb8b4d1609b6977c313f389f0742bfca305e96dbc52b9222c2fa96455c4b81c6657e0cf32b5307a4bf84dd7ce2b78f69341434ba5c73af70b88d46ec9d9ccb8aa311e40e9499f0641103a346531e0e705a4b00d7eb6024096e47467b2fd340cf009d0244931a3016cf4f3f299ad062130c7b759ec0b455d8819532bbdd81e619ecd52ac946b791cff8395df53d0c43e702b8f5bc7fa23e2113f6df8aa4a260a3c0c78773c43b45474e2b8ad21721a90dddf1938bc2ae2d673932d854a82aeb2f2f9e109c0882a224c2a29a1f29425616a970fd6b1171bd9369a14a541a943f6dedb97d523f9b76f8c094f18d9d14d908b641a74a175b94ef9176411bd3af459057e7169a2ebf0837c465b39b1bbe5b623a1f51523fa5fa8422f4ea8b0a0d2a810c238b0992cc0c17ff41e38b80490b987f0a4bd35b0b010283d61ae8f8aad7325e1fbd949be78c3fe2829178b047fb31dabe020c816996f3833636093f50a58c74398f0b2096bea02e75268c0f3875da06528ceacd992c09214e9cc2b5172b010c1c7c5c4ba648de01e7a9a65e170a4ac6f9076a129b34e367b8b61e2ce0ee576b620a34f4aeb6a1e0c5a0f8cac3f166ab29e930b0d0fc3f11a46360b8e6ade77efa3874da75fca5abd5d7783e253082c5c7d28748dd17e6820ef342e525c48c4574bbe38c371d80d6a7ebeba9064219687aefd1a0a8c71655642203793889aecda940ea85b96d1dd266a0900e06bf6ebe66e027ace0017e9a782805bcabd5832fba43c4511f1496962b1cc531ea511d2f434dab7f3f1728813d7959f65533f878b1c1677e65700cd0f886605058d8ef71a43ede73ef200f1965cbcb5970920e77dc8d9db47bfee212044baa074fc89b337fad2afdd509219b61104f4db903526344cb1b000951ea55e99780a0b177cc0fc8623130c40e044174d6e055a4dd6b2fb42de21d647f39fe081dc22a5f5577c8260e031fefc54323b8887c9baae08c4643b0a8ea7f2073ab3ef8bf556a0e9864e8610bd2633b411f00d0207d90503cd684c2c079b47bac495f0d2ec6e0d1188a23645e91df49a3ce4d59922f25e4d4bc3e4e34ff965db18f78bff91c27e2d7dc8b33bea9186bce80eda2f072d0f4010126ad4527ac06cfb100f00da150022fdd9a552acff0a5398e38dcfb85bd364eeb87087cce3210b2069a61fce68fac169d1e3974ae5e8b871143cf16bbbaffa7e27857c077db17a8fb0f81abd21db1b3f952d848983d995023d2510ce92a1f7a1d10d40ea4141b426acb2cb274d3a051fd02f04b010dc0b5521d5519eb2bb1868b4f3449ad131e0b93f8e67b11cfd88da7d00ea7c4d80596ec2cfc26bae226bcd6cb5aa7cc828c8a17b0c51f35b320ffa711f0bc19b8fb87844d5479904bad7cc0131b9965e90585529015e128723266172ce89d40569709989f34d0bbfc80e466b7130f679cc2d66a318c9428e619dfabdcc2c116539333ebd7d7ae5d8034626e7d872879628bafae12cc12b9e4107a502c5dd344d6604e03b1c9f20056bb255a2fc972aff986b3366dbcaff5cb4a3dc27d6c2972e18e64b47760c46c731da94c7f6427950ac7975ab2c4137a5a38548cc16520b79bdc74320c0c4ee5d05c8985fdbc0178e46291829bc74212af80158020b35b46acb10f4bc1fc1aec672e169bdfbabb2480973455af4b98e0eed42988cf5db15dc4547b94aae7d0933a58e7e0c62f1e1447d255bc564ee1a6e2aec9fc222b69149cf45500bb19a086329d780b442a24ac98e5d9a98593f2142c97713fff18be0d33f69a325fb7a8e09888a0d411b5dfe1daf57ab1da01b21f95991d9ca3010bac9420123142f3ed9aae8bb3533b2beb0c6cf5a47266de9f013a19e19ba8b75e052272838d81becdd34c488c088ec856200c94db4ac655f98e475f98b6d0d667fab96bfb474675bba5b7c348486cc542ae8c314f522d3e6a648e0da2dbfcfc727636a34484820de1b1245fbdba5284254dc704dd140317a99ebb209c3c4190fe837e0a9bacda2bdded31681c1976a56912efc9aad35f5eb945fdd341d94bc06ade6ee631243d59aa8369c8ad8275a5b2637cd7ec522a3b99cba7dfad92eef7119fc33c68feb71949925ed195d5140b47e9c2c0debff9e4a1a96ed25005889a5a3dcc9d0ef912f74a98a71024d3b57488d6f467798efef8004f17335f905a6042b27174cb0f3ff70e0ff4347bddec9100623a069e82015359ad1c8b008ecf75c02359571a64348caf4177da4d75b743b3f10bc24776711c0409f8b4d40ea5682a0e34027f3e75ae85e786882d7747b7e5e7012e32430731776aa14f05266f43b375468a52e83e926d2660b5e8d299249dd197aba85bef1e634db6ebe9eaefd0ed3a938cbdd48166c6cb75be3b3c9a49ed2c8076da9406ae30b964f3eedf92eeb97e17d8e1957292908997a90c34117fca37eb6f309093acb80a2c957d60ea26bd8cbe1e3b06e79ba99a18306eb0ed8152572847c27187878c6564e6c834bb6cc59849aaeb814d0eb22d33fcd193fde201d383afe17138fffea71605a4a30578b1a2b5cb0b0a4405720d6568fe3379bd68c58cd907941000b6bb03255988ede0148d1d0c40af65c804245f20f62f7f5a4d488f80db71b18f97ee9d592ce3c96982bea82fbfd08e877c22702f980b55428796925ee10281095129c9c851fb642c2ed9c9583474e25dbfaec645c13dcc4928723cc59471b9e8a03ec98c026a2e24b75dff0321693dc8a947c43a4a1b00c4d8b0d132aab4ddbccac38fbba37b3c0854e0e512d263eeecbf1da16bdd1b9b0c10294226cf350621bb37a980ecd37e63ceaa308c3c2b9a7701800818d607227fd02b1fc11a5bd2a0a468d807ae337133537db20f1e9b0bff969f241dff4fce387b4a9984750b09d9ef2fd14b3cc06934a9d874a8ef4201fa1f45a2927834246fba5f825b164132add32b5f824c0e9bdbf8ad95da535a9b392e3fc1d476f3617f58f34e92783dfb34ac33dde1a6a223aebb66d2142098775d82788e5e30f4f08f46385718d3676b9b8291b924079e15cce146ca885007d263bad75b17290a9617dfd5bd32ad616edd80eae20b2682b2f12aa8d24a84cb48355c2998b235edcc0abfbcb938ab128ac40aa043218e22035952504171dafae1e772e6442c7a4aa2adcd4066c61920d3058b647c74685cfa6b85e3a24c926dad2c25ec945ce0a849cda6c0642aea96a4f39f5197db3828ecd3f1b6970e14acb17195c7dd14a8ef5e5d5ea33e2c1d8ab4ab400d69aabb49e21c665d0a8d7a3f6b6d34b9babb6eb61712c098c1bbf99cf86f7d4a776129acd8da0e3505b3c44ce91805b7c85b9f7db3e692b358472a3184b1a8300a7c872a593320d87aae2604dc37dd141f8dd30aa8ee696ec3a0ed87860af25b9815024e4d623116af07dddd840ff6874c7f9309b40e605a9117799462b03fbc6009eb7b2bc0c80e31e89398393df1371c2730a9da598230c6a33d74ca46586e6e4a15e8581ce6c758cec6c13410304a6ababca34b2f2222e833996066ee30c15885a0d209d4539d5c1649a01af7c047d96b06bcf179eac6ac84c40e2a7525d072ec6cb3cf1afd4277ef8cd171eed848ac72c75a88590f18537597dedb298cf0d89efd2b544949ea6375cec96dec66d1b64a15ff7961844f6c5da0be5be9c75adfbbe8c5ebfcb5dd9e7008938357a00c0a97a55b105cbb2e901f9d42e61d37ead65f6edbc78ab95e7ce644ecf479ad6da4d0d3a2c037417e96aed421103d1481b3bde161ffcb7d717ace7224ef92ae8c7490a840741bce7edf8f4ecb8d73b9e2229b1fea44c725dfcf608c911a138516e9be057c6f672bc6d5881abe68ae211b2765c753195ae9d5f836f000a7ca2376c33a4b96ac606946159495a6a7eb206567ca49d361211f684f3730bc483507c76eb469463f34717047f581ad9094688c0a4e805c066bf6ff4b7496ec25b3e7654e4503ed2cce07a173330d79d3ef439c5e24b485ff918766966c3f0417e2b269a42aec98758ed262824461b2461190205a0f64b09ad0d5cbcb8a5475b3a102071c788f28d299d5ed249e8a31191483cac336c9b669d4b588cf6ae8cf6c3428bf9ef121ba781490bc3067fe9524b49455d9f3c63040fc5aa21e2ee1a9c4cd5a4db1e62a5d6096e6767e9d1306ed4505529badcb592ecfb02f535651991028c04684024cfd83ec6b70d7a2abb0e2b809dcc3df9b4030b16c1d271061418328008b51cd13869c8fb8e3dc55fd910cf60756f3fcddb187406b9c936e2b328c725077cdd3260d6965cc4e625a4f7537cb4584c7111c7769912dccbd83901e1acc0e85f62361b5931353991cbd153a8e651e3cd2b7e0d79aef4fbef7d7ddb866042d40dff4a8438c8de185c7bd9fb07e9fce07c58ac019b1e3c1815b755b2d7c60601d90d4ca6e2765429028c79ce84b2c45afb8270bd8b8923c0b0e3c67797e283f0d7ffff3b18f3141e19d502c678c06fdd096e27a72a4c36983deaed3955a897916c87a25ec2e9fd4bcf51f81fa70203863a747f21544824184cff1031572338a6376404799a05a81accd94eab18aece2db6cd112c615dd05cb14c81c80c049450d67884a07f2dc27c4d6bd11533c258fc3acbd2220745e7866626ddf3de4d738a9f4c7ab4da342b0c0b1fbef982d8b378d68f9c63bdb1a12d5166d7ddedf57ea1e258da88517a17409f6dfbb7d93d35408db035e7c395e34214e3d2dc14fabdf7fde8156c51036a07279c5b304ec29274bb8a9f70fa3bb5581935bedc72750d77cebe5f39e3ba8e1bdce16d9e025e32a8012709ee806172d9f10f45c0418511326320c4fa324dbe4880612983341679a985267fd89707d8527d1fff6e8d10d2c82664efbdf70e280a1e0a840930c78c59a80b62a4b502608e79230e608e1f2feb80d6c6ebcefa0af3acee619e1eb1bbc7193a4269e8c527cd13a1b779383a217ab7ce457c42fcd16c1e311b695de4ddcb45db6d6720c0c6b9c9df968db4160e329b3bf57ebcbfa4ce6cfeb6c96a90f46ccbc2f0177fda09d9b97c346bd0883572d3876a1cc21cacb3a8d038f478b0bcfc25b5f72f7e75ae35a7945dfee257e7dec246483dfb4b8a469387286e546a4098c3289e039863c66c03e6983b4e30a2b2f47ad387740e610eef4628243595576efad0eb10e6e8de51d1c93fd3a7cb545ef9d52361f335300c7b2061f334b090c763c56375e871f93a244cb3363cf1d149f36cb98795a1630c317f20c036d2ba3ec8ecfa4f9b41e69765238d87c836bd6d9a35b803f6b41defc295ff7e3ac8ecf889236d64786f2da59411e390b028a594b2fe7b65ffae264f218456be5ad2fc6d1d6f83b621b8b5900cc3d58830e8421f1804a70f4f4730a0be908236a195d2dac319564439a20b233988d1240d16309c2963c9059c9a346150a521635cd79279860d4dc66d358c22e387fe2e65818c2858c32832ac20430568220c5022d10a92b4e0c4922a59c06012060aa048a92a94a182242790218a0d3ec07084909aa72c672c21250a2e5e384305031479840c22b36a99a6699a96a1b92e4dd396ce6c9b1018509880c203d5192918d29c5a4b03050c67b274c185a9cb134baa34350d654bc21862c9942890e8c0c517225050040d4ac0449168c0e862e9099a23619041e40c4593c688a5336184d11306174d6c2c90a9b77ae1620b1446b408a3045431c9174a645f988005321998a1f2810b9ac4926c184575c58c172e8e6c2172132509aa245fdc400535b940f24510934c060da3cc983133a6bffbcab4c59831669a78610506108b1880507a6205438841128f98b981c8ccc28c1066aa68f18217fcd46c3ecb9ed45cf5448855d100f25476b1034eeb2c0e2263ee26984b69853bec2b26a2364308fbb26bbfd5f3317d8ca0b357fc11d12eca1e44b63db775d123a26de3a471b26ad7ac5d4866f788b267578b330b072150959202510865072744d882114228699465347921a55bb4d2e811510873c4493d1f1ed1942f9af952096b0a77403aa394a14c94324e554899a5c7434e28e3a39705dc31e79cb5c619e7a49389c639a38882461169a54bb668a506219416c2ac07ae669add2c948a4f54326a3acd298aa5669ad5a49ea864d4749acab40c4a3d51c9a8e9446b56a59ea86414ad54ea896a4221a594500a0a5751cb4cb1c01cf016098ed64cb39bfd718a5154f2494ad19a6956fb7ee054748aa2924f35d3b2efa7e154748aa2a235ab59748aa295fec0a9e844e7cf07a7e4e5f73363114a99a594fc548239ac1417532f1b301c29b830aa8c527f2faafeeccb060c07cf08d96103914a43dbaf663111261d43d99becd0b6652b34a7090918d33053e1a1478251432a645741a34074ca7c7aca03f308da699e001cd2324da2b20ac1c5a04c0c9426970ba3b890eacf72a1c4059718343504229586b467a7a2e5ecf84ba169d1916c9a83cc86c769e8f91040c34c45050a44a79c555512425855359451c90ebd0a7c3094e5532b36082184509b19ad9566134208ad0da2b75a17cd393728a5b666eb0f4208a99cd375a3a89d84c10975b709756d47a8ab7584ba5947a85b7b425dda11eace8e514ca82b3b36d1f013ea6edd84bab0e39c1342281b465a63765d383a68ad74ce154c08218410c2292d9c70bee69c52374648e7dc5622b8351031030b6450a206254f3811450d468c4832658816889043087141892c5166b85ce1c450e6c2163c2c21020a0729276503a8c6508d99ea32c605635830446c61cc146354101404617d869bec509651207728ab95662a197c86e1f4d122280852f8798e074f7648a4c90ed96fd770931dd20ef1270488541ab2df30938e212d08ed7a1ea2f834f3278427cb2368870de40ec11d490d2f34a3525b0c4df8ac4f95740b375b70e1a59431cfc9820b2f63532c30071052167167116cc195873b64cb4f5c95608e08c54d2f930a0be1e76a0821a4ffe69c738a39a71415fe9b734e0a735017048210f6dd9e70ba7ae274d1e4e69cb4e10aa8a45a67adb5f77eaf20087de6617e430dbac805371e526abb19c58df0a3dba684fb6174523a55706dc3a8314b3c31e604ef197384ac32c68619269d4e8c5902c5a4713284182c9c0c91d3304a4c97179021434669cb16366c5165891e46c47b5ea76494d2a9a527622045142da0d03054896cc142dda2880c4454326932326b881071d3304a8c11bdd3304acc1315a7969f26b85fa6be9421f365ea4b94724e4a6bd53129ad35cb344bad9d32da9a659a66eda659bb6dab15d7d1ae9b3276db6ac5715de7756151166bcac8e2b2eab8aef33c16abc56241b57c4b4bcbdfdb4d6c23addcd09b9b29e38dac2261f26ad44824b2498d54529346aacb172f5da4ba708956629528a54629f18954930696a9653ef079203fd8e5f3408784c97351ca3929ad19cdb2296316e59c94d69ac9a8d19a659a66edb6a2abd59471a5d96d5bad38aef3a8e74d19bd15d7759ec762b52ebd77ca783d56ab75af8dcd0d0ec5c19932e2dce0b85c39393468d478d1d76bcaf8b2e16e7070ba895d1e08b15f1236f109b4733c1072ba8969c01ab4468d29630dcbe2f1317b3ef687d413e6582bbd48983c08379a6a81394e703fdb5ae08e9c96af4d7007ac4e0618829387102e408b10420821860459c44861218b1825629880f89159f4e1ce865162967ab8b261949821dfc54c1854f5bcebf593c1808cfefe339f7ea815187431afdc551617062d4832b3689aff45e2893cec3d302df233e81e065894e8e07abd4069f2706fc328183c350c064fe6d4b480a245136d880e3be8604455c60c3334712a628cb8d48466e125cbb2ac669183992154b0400c5392a18c052d94322d9894ec20a5699a0e57d3b0b841fa402cacd84b801228d9e18521674c118338040ba88a452cc90e5946352c82a85814b1b4c3902a3f557aa68c602187a91f5c9839ec348c9a7232b504879e1965eac8549139c534a51406cd9130655c7012468b262761aa30e2248c1461a24ca9b4560a258732d6c8d04512481c31a404860b0d0c18d7752f09392c010410506081e24915982a565a1461a12006532aad95c22996f8e209314fc4e8a18535608c5430501ca9b75ea1a62e69baf7bac210b1c31565ae60614ef14087261bb27c011304d4503d03cc11158c0992541e6e28a50c0053821598254d0c00e3640566880b538657c328306284514225108f0f696357ed45ab67ae8eb948fb8ae29a8ba6b77ac51b2edabec23ee4370d7f49add94c63cf9c646344c17c22e374c282294306cd40d1f20512499cd800859a39e73c921d3f67944a4a4a4a4732cc8c21869e187e60f881a1c7e9ae1a467d49f385ca0a30ace8e26659c6e46699154a481fd89b155da40feccfdeb6620a2bb040329b5cf1735f3f2c5372b586515570e9ef875511357da07d4f1551aa90a1bfffbcae69dad7dd9fefd5dae1764dd38e5ced54cbd60553d20792913e3048c80554d207d60d5bec9230146c80810d450cd9e28392195528d92a9a94c05e195d9dd63b7de8e9675b2ba3036761eede06e3d89c758524bd0dfe6877f9662a61347f498d93bfc8800b633520e9f91c353def3ac7c5aecedb1d0ed6dccf843e9a5de4fa3cf444c8b9f7e1bcc667fe681cba8a5aa76fe1da14df2ad3ad7bb1127ce9f99c13b13e6d3e5fbd1ff4ad1ff7f8a3ddd970197210c0f9fd6ce5ee75de9c464f84ee33f3709f679d621e2e13dd73b739f571cf9d953fa49e36b9c53d0b2136ce6fb202865c9abd1f386fe5229cdf5ce4bd7524bb958f64e3e42efb886f3d7a445e86af7c343be7f4adfcc1fcd1c847b35da739f98bed72e14f48cfd6bb731d6ee1e811cdae037d278d9e081ff7d6bb4c25ec3b9aedcadf0a6dbbcee3b1fac4728ad0ca54c2ba73f9e68ffe687697bfa349654fa0ee337f47b3a513775e5e4876e9d2dd295e7de20fa9e727eb1c0b7f2974eb38e720073be9fdb867dd06b7f247dbe62c0c25cce6d1eb7193bfa4be394da16dfed9be67e54ec25a17923678fe067bdd5918e7acdb642b61adb3f047bb75e8fdb0c954c25a792542ec2e17ada447b4ca5f524f1cfc659f581361eb8e420964f39bbf23798ff3a223d938ff5c876fdd0643096be5ef48f6fd77248d6477e72e2eb2396c0ec6a6782e5602a8e6b8d9410f049bfc09699bb37ef19742db6ee9fc1ecafbd67530943eada2351d24f6cd61db60d8f6d3eb111b270789ddfd62d82e7c24896477b988fa88e7ceddf50ee3dc85897058f94bea5ffcc5beb90deb2d6cf31b7c59d8bb8dfdc5b2b9d851fc71eff0179b87cd3b7cdfc21f52b76e83896e8612d67a47bb0e73671db6388fa8cb5efe843477d87538f68ae655fc3c4aa1436a4a0f3d4a673642eaa3d831e6747c0d79bfa04f9420899a31c87c212589288e78a23f30a9b706608c22ae009344ccc816a82369e8113538c49e5ef0f3ba659eb0e8ba3852a728d19242093dfde2e48c2bb09082e2a2ca962bf40726515346a8b8a411828b17461c69b24d71ea1ac69e5aa0c36d8d7452fad40492d85394112ef4e98a12b7b00c19acd8912249bad45b8d4c21e9628086311ad6f46d18a3c10b321905f3a5bf7fb9374d84b9341ac6680882aee0b61ac668c081b2204683136ac5bd6918a3a105155caf618c04699a0454596c4a98ae0d6353aa18e21533221573814c9922ce50c2d444ff9edf8c1319265b921091aa41cb54cb8c121a502021860f6188b1c3154395882e5d2c899726daa5d53036c50922b22935c450a7286942cd6032c12063246629608c70c90d6352a0da6b1893e2837d2226e509c60eea0538eaa48b9329b4a56ce93f675cd3346d8634358a528dd254a338d5faeb625aad344d5b729f4463f284c9d38f8553df2bcbb20c8a12d20776b153dc2f2f2da40f845206d69af6c35429a5558b413993699aa6695ae682c6f49f6c053186a718aad417b8bc2095314d891509154bdb8603932f8c0061354dd334a9e903ad912e90ac564c61e212271903550c69cc60a23ac24292180a4c30840c4a456ee68299e9d4249748fd4c19a6a40f6c19c8d8fb1e09d3344dfb7b7eed9fed980c544cda2f61308dfe5ed35cf8ffb346d3340d0625a40f6c18bad8ab691a5396d11f622f78a182ad844b1225524c4b44cac54b37998a4274166b42c605da650acac49719a79452ce4b39e315386ad470c6071c4cc48a90e923d945aa348c3191e9988d3e6814de10e6c84129a551b2c22139a91377524aeb51a8231099978f5fc498bcf4775bd0a2e75db116caf4ece969b36c0585a486431991fa80a463387deef49947c1892b3fbf4b75a505466c7152521a8243578ae851a059041a48266ac37960c488541d89b5f0c40b223122638ad0238844b5ab618c881538d5f4f630d2dba802a4357d08406450064e4a4a4a4380608c8527fd71a0a3e9c4e2037dba02634b4d34ace9b31ae9d253d3209a66e9cfd514ce202a7de2e9ed855332090ad52383885022d9895c8967820d3da9bf782984e95996e5a2792ae30438288130070f6f70570611217285e967a81e66c8f4a12bf4490dbd1eb6a906544262e40067255052cbc31d19dc611bfe1e19697d64a47552438f47aceaa4183d408615306c482021c30a183624906c0045005d74128882d185ce6c2da4b1214c74d6303684c94d42911420c22a85522c95d35a09460baaf1e4c51866383571c61243110817861c691a42a408185c14419345139a98521435cd94561a2b4ab49ac6c9437226960228549090811233c60f638ca18db10686334a6374918d110611a52825aeb84bb5d65aa5bca85be5a56467098e5164694c12413cb992c5932358c4e872c5f8c2033d4dba12c391303698a98229053e8861a525c6961766e882091b9cf0b266cc0d3d88d182184ca0d888a1871c4e20a50a1dca5c996285060c15344bb090504a29b582260b8706892629689a5e689e98700d634a42d840b98e0822e6c30c3b249182072938b0e82284124b9ab26061071d4d9b64e00a2a33be280286142774e88a8605a6a720a6c494b24c21a9c59474e8efbeaaea0a5dbab6614ca9043125253f02380060d0250008b808a302a83252c4804a95333cacce08b185bed6334fb433342039433d8882c3162baaa4a0a162a85209e30cd6992349cee0348caa32a386269e8651555355524e9452baa64a8934554274fcadbad28486ea348caa6a32cb58f3459135655a580306defb9a73aea1a2089a1b144811d740b930e79c66ac01e2755d5d0efddd9fd1fabb61f8b07426022a50aa12c5499a1f7cc8218c285d9f9638a12d545a2bcdf9a10a8c2643b23c85c1218c178c9c0963090b67ec9a26aad59a0d8d111dae6c11c30f4a88bce00630a86870358c3a038b0d9a6b514dbe5a5ee62fc2182d75dd2c7f2f1a63cc166ed0f0ff6e34fd97d3f49fd7f415066ddfa0cb9fe5329cab0ce796219c4111fac4cf53b883a7a5cecbe6ce8d1a51840c2668ba41c30dfa99a437503a339a61f86a6affdded9f9d59a6356f56a3b235258d3566514a29a39410f6e4ac71a12f50c38194f247fb47a9a438e8912b8fe5c6aea7266d099d8c138c32aa920ca96a5a930607ba74461367405111a77cb0a4276ac474f981c9174d4031246d68f92bff9f1f29c44882da920311246862c904b11ae01429c80203314d5445bc94008525630c81260c1250a0787942010044c85c41021ec814e142c3093d989902e6092926579c48808207b62471450b66920881c3949b2866ce78610c274a674429f5abb5d619b3fa2ffe933282a12ec42e6e861a0bfb39d3f31c0895d184a7e7cd68f2f33ac34affc02e3d3fd70f0424d07b9e030914a3f4fc4b8d969eb7315f1ef48cf387edf86d8712b6610bc2a6c11c47b3351fdacd5938bff873fd9eb3f966730873acbe3a17e18e20b6bb2077c21d415edd3d3e9e4220d842b3fbbcb79ef3ae0b627b7b6cb5aeb58783c4c38e39b7bd1d85a4ee8cba1f19699d9383d8ee320712f6e3adb09084cddb600748d83cda1e3968ad1edfddfbfdf77342eb5c766ee5ad56ddca6be1a3d9ad67b828bb4dce5739b9a8bbedd585a4c7b93aeeabb770d1eaadd79553ed13821869dddd2856b591eb473c446fefb0bd5c6414abbacb416cc7cc810bc2e21ff38794b3e11320cc71647bbbd0e4a2d1ecee42b2bbf71cfc25757721e9c23fd8c80101f1b13e1151a515d0303604550f11d5b086b1219ef41052cd75774ad5f45c0fdc61737821074820ed9f0d570e0534f420e82bbb01b7c2f2f224f0fcabb1f3ef7ef6b334feddc971ddb66d5b878b56d06e5b7cd7e93c1acd5cd47df5c3469b3fd972c60f4e7dd00573ce4f478edffccc73cb45dd7734fb9b597bc5dfed9a25210949a16b8c95aae92ffb912ca271213df137bb5e7a44b3b789ebb57ca6bfd8db8fed2eedd9b9ef48fe488a304f43368d47fc51aace221553d70551c4289882cef907b998f00373d634b4472d3e9ec68564d4a24c9841bf9c8512084784559ef8d3c95b5e5d7b46c20c8a4e3ae7c95f8ddef1fecaafd7f042237b692a0251fdfc513fe36999d8c17cccdb9cdfceb37f94ea8bf334def27e745d1fb57b9ddccaf7b2ce6bd4f82b3bcdd7b7935bf52c0f84f8a22d7bf762ade772bdcd3ab9cebff2f7d3d96be4569cf7bafad45c57b36eceeef0a421243f5a06843a2f3473b0cd5d58c3c1acc7d52ffe6accacc30942a0af46d37f96be07ee084102dd8060731df4b6cb9fdd7474cc5f8dfe74348d556a748af71fd4a2b7b8dd5c54df7dfb273bea45ec20bb512f2e531c703b1cac89f9fb8947b51341fbd61175f1f51bfe8e64c7cc63af3dbb09332846c52a356adc7b2fdd9e95c04177ff4ae0a07f5a3b92ddddfb475bbb0d7ec11cf1d603a17bd1cddc35ef47d79d0ef489a73f54f85cdcf154e6af040e7a7b2b7f3f2cbcddcb1fedecd48bd841973f14927a3b778f87962955af3057b3b69f0a5dcfc12825eb1b41d7dab42dd75aa65e44036479ea155fa51ae12261346481caf2d45c8b936fd25e4fc4ab8f1cf75a3daed6ba4247428b7217b29d72b8e943dc3dbcd462d2cebde21584ac4eb3d2eaddbb4c84493b3dcf7c933d9753e878382434271ea17e859b3e947dc34b2d5b0f8734bcf4c1503dc530cb4c35ab404f339c3e51c82aca32b5a936fdc482082296a54b55928258104a3455177ee8d2b4610c082dfddd7b81ad41064d81c0d29489f938a90b5c3c8e3f94e1d24af626d1772f8ae10a574e0032946519a96624ed40b8d7ecf4ab8ce4e548b5ca48d46a07e29dbed6af0ee4e6f51c969c73df72bc02c4f5ec3723d9e49b91329b91b48c44e9b97b4f36f7ceca518af59bac94fde6393962a9c7c94837198995913c29efabdbbc012d236967dd26c727fa564662ad32d2eadcbd3c02d21520f65d46e232d22ae76bc27cdc7274a28a727afd4c61894af751ea54d6e6d79496af5496ed3f18759314a55d524a6a2e762f1df7470bccdaf8246a79327de6e123ae97988876643a9a3e66cb9678b68e06b7514a870b4fd4ce9bf06fdcc83bd6f264387d7432eded1c8fed37b16dbec25f0acdf3cff52f3e290201f6f6ed1ed38683afd4ef481ae7242ea2ef4e0092c1770e04c7750e7532d2959ddf388e0ca74f06b625d28d8cb414ab86aed4efe4781d0cbb633de7acc3865e8fd8f13458a771d6699c8b5de52162bd3beb1d8fc7fc3af478d4b8907ce1cfc5c1162271c71380e8dcc68164709d2b2700b9719d676023c3bc824e46d2f90db8bac43a45461f5455ad691ea29c73cf3977a883e150ac818d62c7cc43c49dc6b9d3c837bfcfc146d1e6d2e3c143c4bd3bf72e07995de4cab08e1e8fd6639a1944052f998b740588ce77be9375f2a7cf84dde7df1dc0bff31c0e11e0d7c13b8fd8023adfc948397a3c12d8b9ce2db093756e01a11b02381ce2b9d0bc81e1f44162fa10cf77ae839b00f09d13b9113d1fb463fe84743cc7edec9c931e09446eecec7c6705211b9ce7366a27b54ec3d80f4e4d420be9d7390f464a1ae239573d1288ec9ce9433a171280f31c7a1568e9e01584fc3c59e9b7711b99081300ae739e1100f0a69ef31c0eede0a60fedfc065e6a3101e03c1b5c48cafc69df2c90afc383938662fe58df727cc4de6f0e32fb8375917c7c0b1365ed9d0078009884e933ef8361f803d3675e0029f4f741a9e3a60f6df000e0a556555555d5d006990900cfefc14b1f0cad0080ac42ce7048fb0a7f45311fcdd62e876cc4c284bff3f9146690ce27cfa78dcf0c3ecfc23630928d33e11fcd8ee7c1483c67c247d23913fe0d8c757093ce7f1edca4f31bb7819b74ce730f176997e732c04d3a87d327030c878e6fe02d7f4793e76876cc3af80acd461f74cc45f630aaa39719b4f309e947989f56626ee9839ab9df78065ff1e41534381cd2f9dfc119c4b4f4c19006e7f977347bbb6d08633f7cf94187e668f71914bd5c1d3ff5c8fda2162a133c10a6d107fdcca4c16dbce3f209b2e59934f88d7fdba3971904876666d2e03a5fe56fcb47b3650e92b5cd5434c82a6460af979ecf00c3e993693948d623cca01b59c75a1b7927d6b59ee6222a3ba754745eab8ed4e1d1c13cf985a5527314c3a8dec12aec601574ce456f049d6cbd09c0219d7ca74f54438fc7083a592ab554a221779c903009f45d255ade0610481a4764023617bdd80f50585a1e07f48ce8920e456ec0e2e415cb0b4c5890b4e0c3181fbca0103b09abd0b3a1801656240cc22aede15618624fb1ae42f38351332ac619ee07a38222f499f25b179b9e9fd7e9adbf974d7f2f9dfe5e33521f2e8fcac2133028d1f50ef8800492b74f5c16748557d0292365659d65aa31380e7a705bd6defb7ac15af2a81192e9af7ef5ecabec8910939e7409904cc77c24916ab5f5f35cc5b2ebb755fee68fa48d5d8d84d80bc988635bdc437e491dbbb831536ac54a9ac72b52b687277b5f363a2b61d3f640f59eee9140966ea150c4ac54b9e1880d312b53fafb4f0b9ea4fcfd8b00e18c2c659499e28297344bd4292fb4e062069918f8305451d0b5d66a9fac48996225ca0fa45694b8ea82bb358cf1102340c3180f643a6b18e3e1052fd42653b6263918a99f0d4770e0014a4b539312b4c91225f4b4491353520b5f7028c2f4248910349c8089199449950b536071ebad5bb68022028acc1157c29880091395499718ba58170f34f4772fb7f090d0c3def32f9139c598952443ec10eb9c86b11dacfcdcfac3323a299dd4cb5d358cf1d0448c8718e5f2f7f090a549052650dc52bdb532a952995c59b203193b6cb1c5153a1489e2de31aab82d3254dceecb14b79392e2ba1ac6aa40d11654d941aaca932a4e036818cb618c1cc0682249149b2215085654117a6a9b9a8e9c8006335600262a49119b6409127ac6eacc4699b8f4540c8b56d151b1c48de19888612dd52a3a2a96e82913978aa58c04081692a822f414490f1409554252820dc90e44febf07378ce5b044d36818cb014b7fffb15f3858c3996803177983163adff5777b5abeb3742acd0993e8af87e2e0454688632c87272d8fc303fb751289fe6c646a2677cee69c4df71b6c933fdaf7147fb6efa3c7837528816e7e2f346df0679bfe2677f2e256dfbba721ac714cedca0ca965d1566bce09e3b80e6b1dce7aabede97038fb8ee6f1d8ce6d1c27b36f9be72356d11eda1aeeb06c4eeb3a1c81b818bf248cdae839ffc3a55f61050cb9f69986b743cf6e767a3e60156dc844d3f8b8fcf534f70ce7df6d48a0968532c87a39af38b9cb48c0daf57a07e0fce6f53f1208e7c3590175af34f26737178d4f2f04d834f251f53182aaaa2aa92ee1a7bb2e07df8569e374bfe96e835bb83beb6db1edb84dcb5db649377196b17ac430c218e36a750ec2c715f7898de08acb2bbc7a9176bbcadf4fafae7dbe751874836c6036f8f8855b2cce831c6bb5c2b023ed819be776aa941bc20c62dd0fc64502499140b06f90401d0fefe7e22d8e31bbb6d2342dd3f20a1b7d90651677b7d923ce628c51b3efbaae7b66332139bd1eb6bfbb65efb68d0c439843cb9f2b3bd7d95b57401f8e8ee7380e56ab7bd5e3e19deb70769bbff855b7bad0f4563a665074faa9435cf82f3e7985307de45bf9b3f65e2e5cb81e09a4e1ed1f88a712887bf41e9f61792381bacbdf649d4bc278acf29530a3687109afce1ebd10a80d228d91242c2ad95809b33087ec88b8f04a4f884b1b4a685711de4804cc2855d727f80cd6a79b655a966959ad35a35419c5d589938f506212242c52aa84c4f510471ef9e8d431aa85244782f4e621862d53e82a65c542d348eb2aa4e57fe098424d8a4e12162f1f9bd2355aa620424b7f47f22b8183ce3e29b594d20be92aa9643dc7cd67194603d04b4ccbb4f478cc1fd48b6800f9ec328b414501111487e26d17b91424a654129664a4359cac4b20994fb37035eaa9b58c83210835cc284c5ab191f6cd4803743502cd5f6c4fcb3dece785267d12443b9d4443c3305d3384396a3c0a496de1f47ac4dbf9ee5c0d5c4f03d7a4bef9c43854ad9dc7c7bc769d6b3c5eaf18def5ed2d1be5d4da6b9452739faf4f9cf38a59f5d9b49f337f499c0782769c5b8c731b5cc4dde62d7c83795e874d63ded76b4c1d9d73d7c93cafdc23a96bfcbec6efef8e07c2bcb5af816f4e03df3c077fdeed5db8c8e6da6bfe921a277fdced85e60ebeb1c145f65772ef700fed36f39c1ac52a6e9b1b554fbbc5a99e7935bf59eb3d2029899e19421cf69a2702bd263da3d83de8b57f34d34f99e11f09935158b88638eafcc41fa5f3f007cd1f124f0ff81692124218a4b9087ebee42a08cee5da70ecafdbb08bc9ddfe759d5d3b35caa53618d0f421c900f9f9eb3a5dbd66587a3cb2735de6a980bcf709c87b39a937fcd9debee2f017b757ed96835eecccea5c496946ab7fc52c1ec253a8696bd5f2d7f576f86a21dc3119b0eae4fc0adbe9537db8df7bc6b8c588a98459ad8370079cf61589fbc1a8a33a1f820370cca9e18b5f32dc78a865db495885e1c28e19c21c529a129628a10ed3226e0831c61863cc1fbdd00cd7040993778084c9f7e8de14ebe80e771206a5469841d6de2be58010b8fc597bef96bfd7eb30d84fa740e365093a7cdcdc900218e29374c42630877c8dbaaeef158bb8dfebf57abd92b8985171ce76360509f421b596bf791362b8b1e351d719764998bc094732e84a2aa957b3dcef2da5bcc49270ea9911c11db17b64d772440708b1e08e0eee881d3fedf3161769405488da20aacfcee160ebddd890401991aee7f1619fddf50a7b7a37ffb2b3b4cf3ee7b3cf6e40a2496b5de6f1b8b9c5f7365acfdee3d2fb51afe52ffbc1dd66ceeb7a3caf4752dbdc8604a2399e7aa798e7e6382058d773f097dd0777d7b9bb32cfcd797ce0dc3bcebd1196e250138407f8ece7691c07dbfc06f7486a9b4ce3e2a25666e1222f6f588784c5fc7559f60eee40814aa02c476b351cabc546b16a6e266cda8f328b4fd87e6c6065bf6956a3210845af47f68c76300784393e160f2298235e48b69098e49256697eb6ce7acbbaea3f1b3bbc7f76459f9dc57a77da43cf51d65b871eab5559b5b26a8639e23b2cf7b318aeba7a3cb647af87bd76a1b9e1795b424fcf98613a1f69969e0f1b5abec862b2e214433f4f37ae9b56c222dc3e4ae97744eb6114fd808b52090e76e0c258124a2d2fef5b2debb97ab23ef3a7bdbe851530e4b6befdcda3f57be8b56e08b05b997a3e608be561bbbaf651fea852296f692bce2bacb5d65acd5eb3d67e9b9cc5dcb76b78d3364d4866759ba26ee7b6c32db397b0ace727b3d80856d5aa652b7afb8a43d0d345dab343099f75f62e890b25ac669a19f9f98162ed4f4f8f134a7b5eaf27af1b3ba249ec8824360d63506a8eb8a15f1226e5122256b7b2590b1e70500645a5ef477640a1caf4777bda2662505f62d5f2d1a65446a818949586b12d518d8086b12d4a9a6b5979eaf1a85a6efc8ea6762189a9846995d2cc515c9b5cfa9a6d0de2d6118090103b885d1f935cd930b60549d363590107250793301c3862ea7a6556484e6dce995dcb2285924a4ae9948ff1f58ed4e883aaaaaa4ec2609d210a387bb8af1933428d11696214353ed9ed96769c734e4af3e76a9abf98a3069b9e4aa0861d4fa92410bdc5100861360e98038f70975c2f1f98d6defb7afdb00f9221e1fb998279b9148d92ff9174e2fb947969ea378c05d1458834fdd3302604136d04992640c358115f3a5a5b3ff805da6d1e7a3e563de1ab0782760a3f614f2313ca6bf81b8655a71bfffdd8634002f5c4ae9946c7cd0d2960a2e3e7350016ecd082973caaf4a8d617669c61a8bca2be10a7f4e4398977384873e761d3476f1e7af247b5635555557bb14af628a7e65adc59361aceee1046ac9de3e2773ba336b3f17675211df1373be36ca49fd9e7b55c2ee266ab88fbca7b9c5efe6473f63ba2d1e622eeabd34af3479bded624a42c66df0a337ef547b2685e4853fc4da2d95a96d5db78fbc52699968b28f57e7c124aa0d6bfe814b97fdbb32c7fd129e372feb47c24bf2d6759f62f9b998df45ce659ddbe12c57b3fe2e94990404db103fa2ccf0bcd9ef4b379b5d730cbcb2cb5c947b2b35f9bd1db65f98b9c5d793cb618d51c8761d38cc3943687299d343675462ff1cd3ddc3dc3f52d9c91206135c695d56ea35dd947576f187634123ba8acfa1dc95844b3dbfcc52a8938fc1d4d1eeddeab7d5d79590143ee7734b7dfd8d777199757af466207d17ef5ed24508fc7e6d4356b0dc3a694d2d6b21c8d44035421318925ef1053dd759d4ba8c46b17ec9a9864cca119010010000316000028100c098542912c8f035d1f14800980984a6444150e235992a32888a120066218438831c600640c40062968cc06c7d6aa6cf15efb8212c56a10b70dd666790d283b4401ca2d5ad676b843b80de83885b0fff6b496b450287d2fb03940b9a5edfcd1235cc7eb090f5e05af9e0e80ddb55e9221b9a3b423cf2fc1c6328a41f1a53ff4ee92cdef7efa5dcb4b5255c905eeec7ca8243e146cf16c3333f79bf7a1968581ddccb18897661dfc79258478454a2c27754b26a6f52e7eed08b25f15b8a75270b85059415056ff99310bf578b27c600e3c18cc0f5aa93a6041e6b68afeb8da1f184e13e471bac2c836be96d12bd748203b38c2861359581b8a953c1991c0b085cf3da0c241959072f035703d45d0d3afe19b71a616b552ac40ba21863774ff0616d76101903231a510d0c32f2a0f3c54fe58e97ecd14dd1429fcd5dcf9dc03dddc1fa88f45bf649bab3317d6ffb410096b3a7fca0b7038b50ca820b929817433ac87d5260bf59041ef8457a20199e31525084fdf5a0305e21128005afc71ddeba585092a6cda5565411fd3ced687355ef39e86b03a70a18d2bca2e429fc8503af4018aee5bf68cc3cbd44d0d4569f3a79d1d077b1045e4939676cd9171c8cb5376a85a5ac0f7503f20ea8caff640513468d1940ca5eaa12173c98e063d93e7bc1cff26a0dd9028c3dd11e7b5670064a90fe5e6732977f8a76ff15db05ec89ed03aaa246e353087766446ce3beb75f1e06fa206ccc10d61ee400d053c0ee279e8a2d86984e6343e4933c72f388362f511bae7097493d0d17343d5d4d1e01a043c8864a50c48269072030b0b852ecbdd622e845695032d1bf2d95c994a7a115420b9694e78140fd269b917c41eec6a7a623be660cbceb563a9c023f760cac14b83d453682a248ed7d3ca9989bc80783a3bc9f3baf59c6664b648daf094e48690f30260dbb135730cc152d34447d3a218b3af0c3af77b91f184d3896c989200528d7c688b33eb27e133cb029d58d5dee8a95684dc530cd8a166220277f8852c30e78cb196c1937639ae73fd2478eff23af9b20cdc2332a5e9af48db22b123d9bec1c13be74e309e179c22ce70a19c995079ec30beb41a592a01b37990768069b164a4ef7643b3d3a3e5128cd29cd9fd002af84eaefd9bb517daaa32b5931b8284bc9d3c2b1d2d8d0915812c6684b9f212ba5a37cc15f1199960db6e486ce20a88b8d0511c8da23688b226cdc5c0842fd096f67c10774ef10991e5ad44cdfd2db77bd0ae5e92ae2aff8d9be7299fd8c98ca27a9cf05aff568510c1165f8f05c154b6eac195ec18149777b6a14bd73454b1c8f8b0a0465f15487331efaf87f0f75f97ed2f04845712c40484e9d27f6f0ef423045421d49201ecdbdb903db2ba846f79ebb293cd76a32734738504ed6c7fe57523da0ae84c619c202e41b8255a45a0bdbb6001cd3d75cae76d38fd6ebbbf6acb90cd3a0f306a60b2637a1a33b4e7926b296c5b8ee9844cb92371f4a4d46d14e04715d6c9797ad2ee088ffb74e2ba397d8d06602833a6a0934b1f74c7249b0d0007095488aefcc0832c8a4e1b16ef74885157804d6e996423d424ef371aa3d2d341b5de1582ce3cbd25b6953ad7f05211a8ddbe159838c161486adb51faf2d41eaa08911afd5d88c0e21e4ae48ed424cba8212f5e2c7048576010fb9ed429bba1c372c8cb8525afd111884dd3ca64fa99e1afddb87973a922d6de849fd2ba5f1f28f043151cdec077ddb1db82a0608f88dcf070fc3ca8283ef86422001f54ddf2733c956ba9716a33ff21d214117d0853f5a053148216e74d1dc3776586d5b67b327d8e45442a369656c06c414576dfbf7f6019f79df604145f407be3fe8a793024bb92804d6a63fe1874441579857d8d5c8be3153ac73ae402d7fbbb61af1e526840a2fdf3e46d3e83390453e0c4b6f0e65c76711e860080486ad7ac862653889da7594261ac6b1e971aa8f088466f225b11f9fc932ca31ddfd89fb6c93f02cf95cbf5e1b2c6f1a808fe360fa0ae1dc9e713f3840e7b21b61db2fe3cabc5989d0207b90bb1f4ab296ed1bffda0deafb8d2f8e333eb6290d59d8f3b6975b9bc7b4e80e059d0510b0a4fb47edfa89cfaf8e281397a8bbf8a243074259a9a05776ecb98a8cdcf3b71fb8ab137061ec2270b698884763e1e2f9870eae07b5bea0046ba15bcbfc16b9e71da2cb7f10c88acbda5448ba2ae10caf364cd645313e585b2c37814c189b15265276d3a13d84c8dfb4d09d61f3870deb64002e656d6dc1e00907407f74b29677e92c251914c1e5e188d085c4e436e20af21de19853cc69f3ba600b2078851142c0349791b9ea6338ee153cb7405cfa3de9ef6623df13e033ef52fa5cc29210a6b66b9af3f9ecaadc62f36b80550cbc800503fe36b140b19b72b253039b6dec6689bd1b6346ed6c3ed6186861a57b352b18e13833fcf35d069f315ca6b8d82b6d7fde34107b56efb7d5dcef698da71ed86e2fc79a2bbf426d5df1530a5f576e4e00af49181fa4a8f70708a2030d8670238b9d50b6d5c5f0b68f334a797598d5a142bfc373378523c571b820844ce86dee05c888add0942038628497feb52cfb2c6276b889f6ebcc4515c07339c573723f77490b247b205d62dd64f613abc4e546343ecc333635b2ecb8d653946937f29607e3fef560dc8ff222a3d71a9f3c1b4a80786e524a347d1cdfda5a3ea18208d1e5586a70d57d9d156237c3cf65d0486b3e904e1a6b34302e2120387b3e8e99ca21f6cb3692618727fda2d6f7f57160d48e4677f19db9319b2c894ad0535a2b5cbd7a22a211c49c99cd9ae76edeac5adbca24525e56ca667b234e154cc7e2a411658f057093fb954bd3d90650f64809518bf5b5c9c40da1560652ffb1b7af91d0b46644a6caf5f293e68fa2e150a2cfdbece235fc112800513052f0970937a57b57dd8d9bb4d284aaabe8451d2b9d604c0eb6cbb1619b67665c4ab74f91759204001d55b98927a22ac84b2fd0810a3af83aabb50b07079bf1649d43d72b8ee827da3a28ebd2fe268bbd6a632052abbfc271c99ffe3cd92a4e7c3faafcdf2472009125ec29821d6a4a66395a6a0e5922f29024d92e7c099d8888490bd304117be10c16e38e57c66c7c4e2b85a5eeec889779caeeda6e15c6acf4b9186a4579c9924133ebf74221f9d370999030f4d129fe52d6d357c3a625ec56e783d76d77987644ddae926e7220556bfefff2d4c268857f87bf2b9179e99680f3d2829f80576eecfe383fcc64acf15b6f24a206560c62e310298ee20c60638a44e486ff1684a3603a1ad1602bb52407f67721f22aa2a3755d5120de44c0da0c81f4cf9ec307ee388b2f702b959d0f7c470fbfb8dbefcee814ed7fbc79325207274bfa142da1636ae51f6eb6db2fad33da00fb904570ae90a32e162425fdd6c235ead51835169442eeddc9f9ced91f6f625a5116b1441b1e3bf2a690925de4982e16ac29c2523a35ed106ac92252774002df30f2ee8c35b39015bb21a1eaad635ae9040008aaf56f30032920ae4955d902bad3262067993fcb0dc509475f8b8558d5ca5103bf684bca77acc2667473993ffcd09e80fa3c43dbd80545688d674024ea496054e6f1ab6d999882c6fe8c6e195c1af35be01284b510475ba4226c9deb8970cf6563e820b9811cbbe45e9ae8ea29a1ea4488b197e9969c87d8b7717b73c87598d4a6f91318ff02ebccc2408147c1f14263bd4f82b933a90092e618fc39e4c7e4ce4736504bd4475ae9e532aa731268a8d463c0ff6804e25e2cc12f346e45fb3594b275146d02484177833565c598ab765d3dacbe24bb60cb7b8ce27cf6f5b905e420160ba614330d35a1f7d6eb3c0d23f074c4b5d81b768e0bf59b278155333b07958bee4977d1400efa4daa7b78e0eac6ef48f308b3042ae36388d2e183dfcec1663c7766475e757fe2d449ec9c14de72bd5aa033bb623fafe0c7cb7b07d4d34ccfe56ab3fffac847e6d08d1596976ae38663d0bea0d220cd1c5ae4555b312ec59ca86322eb0eaa52e5192ee224fc822d2d23258d3911a0cf8e2295deca0d9ab23fcd08e00305422a0d5868a555b4d5b3faedae3e1e935864f3b701a13f9ab16d07d15b41a08104c60568bd4f2e951974f8b593b1acce185605c1239e12b2a361bea9983c56651a44d97e8a1b024a9aec307782ee8d3d94f996236a845d810dd1e88986df5c87ba9d581b46403e2aad4534bc3effaff6ff316a24c7c3d5bd958975097e404a537a761f40809207a96aa3ce8b2b0df2aa4af642e5c462dd1f7ef64342ab5547d34f7f40dd9d42cebe246628c443014fd960bfdb40873ecdbb67c9f1f933163e6a34b3a05d3ea58af89ffea5cce1d057a80c62d939473bec8004d51194782f9cef79f20ab64b56364bcc1851bf19f9100229921fb25f26d0ec44f5d8e903c19ab41434ff4184e1a94fdc3730a34e57d732222a0db7348723428c4f31e829819092f0eb4281f9cad903ae8e8bdff57c9c72ea76990a0aa685294c14df494aa96f115b79d5443b5694ec77c3881519db863f5f7b5327f61db6b6b63b72c6e7ddbe1d1bfd72967db3ff9a211067783d5f16070064400a3252859059e623801720fca17df6a434762bfa5de879cd2b24fcb5225f43d970f08468865f21a5a20cddc4811d472d2ec5926eb96a0173bca4c1898a7777149740b553c00f291c8816524b6f388bc5d946e70777a972aa6243865a36790b9120fcc1e91d4a7b8e88627ee80dac6578d0274bef7cc20f93de209cc92e88728080dbf47b2f746ea874aaeb32978b984a05b50fd6bfb9848eaa7d90e254fb2d1048a25181f6dfd64b2e2b679576d73baeba9b1e3687eece1e5e4ab9e4955b196112b34061fa24e067efc76f3346b9d644a12b2cc0a7e61101c0533bf6601c97eb6ab51e4ea3bc4088881373198e5f1b60fd08a5105f8a67c4f144fc6199b7588de0fdb3a31cefcdd2f225ce7358f9d16cdfc7d4326c440a1779e5f93edadde2e01d6fcd0eb91f74581927d11fcd694d685172d13c971ae385c23ed65dd78be06c07dfeff10fd2d44d419b6b7bd4c7c22236061358383d5db8b0aa56aeafc406115fcce24ee778c4812b5b0b1bc05bae35ab8a009c4a59b9d7ad8131d64a4f261a1c12ff998538971ccbf748ec0a0dc5881893b62082e9d118f2d1a64eee150815b45a096a96611f22beceeb71245af0566886f249fbfccd8ea1a8836247f552301eb461f52f281606b7e40a0e44de2fa8880174862031f612754d839e815b4d0d386802b0781c1004b2278138005e3dcfdd0d85746ad253531daf2a54fd1f1af4b7eb3696578684ae94b509d043a64d2742c07ede78a20c2a7f8cc2be6832e1d39dce86d1a3e3c97f324f3836bd6063432a90c0e6f9b320bae1ba8a0a9934bfb9046c48191e496ccd817b93177357e33885bb246dcdc1d3f6a0a3323f18b9c8c0d466f6571c63866157b143a0406a8e7388a63b5d0af7088441f9a4b002955251a462effc72c27a603f8b5c0f4f418c5573e65b4d7de19e699f03a436d142b08b4d84b315d34fd324b18ed0d23d4f01a742c9a1f3e6075c1964b2a56afad1128555325d29cc101dc80a9a3807d3f93dd3253cd780ebfeb7530bd06d7bbe271c0c86ebe3d8b57c2d4f0ea2c677e349106028a75270c67250afa46909252269dec56ecd8e0189dd8f1cd661d7629eb7549c51b38f299ea49a4183444193fd1bb99989b252f09915d7d010e7c058e3220f1d53171352b9bca134fbf2a9a576764ef8897f040ce936e7b2da421933f93115ebb9517b6a96464432f91b31cad710b53a0417d5679e32c3d814b38fb02738f19ae0f6abb374ccfc9ca7def3064df14605eccb08752281826f9624544d5d55539bad9d580aa85790a13fbeb33f0128229ff0abffc1b48c5d7ca38dd600074c5b692975bc1960d1cc82758aa6a5e6a9f85c598a5bd9b8e6e90a21a7f27382a334e0b09b7816a5cc856b99218fa0dd16c1b9486842ea5c0426d8b3fa52478684a6add5a4daa9157f437589f1c864763eb348bdb6ecd4b7b678269eb3ea69a1a1dca51d2a8816875908a13eb65e8135cf7a7effa0e63363655a11074afb52d5650a2be9648242e164bc1ea69a0a492a08c9947b0fe1bbeb7e640f09999ee8108d4c3a2449bea5d221bba05b8c67065959a86d8bbff24aa89338687d0002711bbdbc6d87cbf8d013f177b05d9a38cbaea5164dc2d5e97909b15069a3b86e2aa3d28a541d05717e5938871f79c0c2e2ecc7cee6a9c1574ca9c52a12dca8ba140b80b999122b9a963e4bcb601e56e26bb9492d0eb7496d0e2d2b26d4529aa80265e3875870fa78ad215abdde436bbed15a81eeb9a9eed20a38e4e1476d01413a0f3ed4251a41cbd5ca54df10758a5265b150e56114c5ac001c93d4c61a3a8fb2bcbc9e7532ce9bca75d378af6c7375024462ae80269b7cefb5cb7cdd890f7ed2cfbdcbedcb2d9371106fd8ef349cb93b6884e10706a87d794fb3315dc9231399b0d21fe75c35a78b05f59e1a609256c6a31014d3a6c672272ff44573ae043e220496792514e0e090dec069edcf3d2917a14b1684fb7668cede95f7fc2ed009ffaf96d1bb4ce5428f92fdb66065b9aff5fb3007fca851f001e6a9d7a6c2fee5c6ff000a52443a164db3a2b64b652ec191853ed6913c5d09a5c331988c31d5946dd0b56bcd60fe84335ae49b61b0d04301157be4ab220245eb6d33a6f60b1fcb37ad3e039b1265df048b8b2681deee6b5a50c8ed94d33febcaf2b246e8248fb5782f16d47b4bec466d2e9014ba7844c386630655d361eb121495f46078642c0891266d3c4548f8c52fe9aa1f7ce2954bcfcb3fbbabf783bb014c00c3fffc04428002950a57050a7418c3685339a05be3e5e231683ca87770ec4a2aa8f6655739475b774780d271d145a5d58c43666ba27c369199ef2f503ef06fb041a5c7ec4bea4f90bcd5e1d06d2f97c837095922af02391c526d3ebd03b7ebabeeb288ef398b6489477e96f58a9df4e15c7d960596e83f0620ed14be7540df0673f4adb1e74ca547c088ae3f4ac0c314fbf1725466392e543488e0983ad25bde5b1b0c412d9db7dc3d21f87c0ca55e39d9273d187407ab7c9f1f7a9b6c8be763410cff6eb522966808110a80ae50057044280aab96fe4a8e58823b0a5adb5f503b0b1a043a2859bc565315503b76850a642ef36204c5d7b859b645f7e3a99fbd4b72ae0017ab66c519a2d54507698b74517698be03d5f4793b9e01469bee052d3ba790fb1bc71d3a0b7d37c06d14306a39aeceb3fcb34225f4cdc494abe71a461e83c07badad06adba1c650532a560f8491ad02482c11e56518a50ebce273f222974d61555e75efc7952bb19f5f7473565e8ec7f29ae192b586ef27c3496ae02f54c27cc76224f0fb084d89566ebac2377d7168853167f3b00e812e2a4b7f72d9223e26f53a51274f5e169b4f4f269d6d8241e58de388d2377ee9d00aff5030cd75e86a6818a4c4c2509a3ba1f12c5b45cb95b1e7f577791f3fe016571a1cdf5409993010f52fa9cfbd2678a88657192d10a0b12a63582d0dcd130e863a900885ef0ad2952e8de9958fef33dff29665051e8055571099a52faa8afc21021359b8455183e281460ac3a31ac47a2d018e36fc72c05b9b368ef13487880412c648db879bdf8510baaf55149c24efb70ce0ab8064971e03f79040df765536d8b1561316b0c964c109b2ffb1e5d58184b1533f0a2210d90b4b91df5dc7294a848225b0c213ff407f121a5a25ad9882d80b9e48e5ca6776b7ecb2096e3f0617c9394d08f598b4978525c632af99c26bb17c0e03f4d50944e147382fc6f76d805d03945188b3962478c0b6343701296267089a3edba182cf3ca5ff9eba65a56c41bcc11a4291febf35da25c58c2fc24e44786a3177a18d8920850ccb523b5c4309a9a155cb45b3d6a2fef4dab2eee3f42c0308b9a24505020545f1925565c336bc9f080ff80023fa13663492614e41db01707102a8120ad7395021bb11f23e81a55b81751c569c9e8eb80010a8b4188d3b1314df973255b311c5cdde162111962a52fd9c4ec1106b0fe7583f0bb112a84fa260da185fc83f1363263a13093f3195133233faf58a1376734c82c502da5c0f0a6b3d17a404eff93ce504190f7a30664b1a9d10b45547d4ac6200ad998e5a8ce398123e18a658548f3f31e2d04b7e62cd2d5e44bdc926c060d0097f7ba8efafbae641bf3e561006ec366f8d6e1e581b72185219068a6996f67410378e712073eed8909243cac8e35a34b5b4af2bb1d9d2c2c30d87c02f340f7a215e4f01dd04beeb6467213b8286c87a1fd43e4094c40c34fd4ee791a4062e7528b22b8164c8c32b8156388aa65a291a99e5bcb33dc195b4ca9307095c0a81b7e18cf45652432b763755279f3a605a51fa3975f30066e1749c2c2ca4d0210bfe34cc1073a6d93ecc5818cd8bb071300c794ff761e4084867592ae2f041f4c25f30ed08e15bfe7152e4a53bcc3c62eec15be40193e150dbfd02bcc3e1c1c110737fb476d29ced5c40a86cb476e46c724ab1b25d1e0bb9c1cb2ec3026efb8442377048edd5b5710e7f2188d8524623d15d11285bf86fffb6f03988356825dec96ee6bda8db1d3e433ffed76e4807176043939e1b9296b9e104dd59eac28c7e12770b6019598f78e33befa1bb606bbca0b9eed3059d66b3f4a154b4372db1327e75cb0688554905ba9c5cad48d3513d72c188c53ed9c945790622d1a427ae6f277ee6b519f7d8af822b7ee50d647c5bca816ffed298a345830dea5ba6cb860091cd6ade07dc43346ffd508204d72d651f98c33a4ac5310fd9777f518c936aec46f643eb42dced05017f0dc17964a6c9c3212501f81d7c17fc9cb2fdc9051e8cd004fd91afcaa2d86568c7e952e9b3a2d9791325a58b95382d6ee12f5aa3063c48081fae17f0f35d062fad442059c640650442c46390e0eed547613ae7bd9eb59b1c56526dc4d9d94678fe3d9de1762fb34896e18a80e4706a35597d4a6388cbdd5f4f957bda701f117cc1a94c3417c01b1ac2e827c3090f220e223a48c921f1fcdd4499b895d8c3e54f099747760d8e92ff5749b8f30317c49aef2874be7bc9c56699e96d82b235e5562181e3b6de50bf1cffe537451226c9f057eb43ef2c60d1084e80a89cc2ed4b73845bf16c800d240c7cc5a85ca7d8cd51cc1cbe7eb8f1fe860f4a5d41968397d871e1bd59c67b2b0ea0f5f8f813867f94b4504d2420b094200b43e690616abea555beac01fc87dbf60314986bffdbeb7397072b7d8b1a8efe3b5404557cc80b61abb0c52592c75eec1a7067aff372d4a55ce3384640925c1a3d35ca1d0eef0e81481a31c8ad4bc0e3fed25905130130f02bdb885a393fad88c94ce861772aaaca8c1ddd8a665554cb3d8722b25b56bd92fdba74ec847703a4cc7cc28a68f01ca7351b1ae28e9055e3d8cc603afe9b312d4eb66a3ae26921a751c8427031cdd3fb3137ffe0006c92066ecc0989160560e48170fe89710b6c708d348b3dceb2d0c52f8522285f2c14b8ebbfacb17ee13ce8702c2aea21dc099512ed4b448224e49096ff72e4db296f693acd99cc96181bb380a8491a0caf81afa24a6e42b626d7f3785eb08e31cc0e035968a34e33678976ab254bbfdf05bd47c7c0412489d33b1f53a23fbf4f257164a5a7a7baedd20e535da24153b1b5a4ee7acf262e3ae10c724e0871981a9fc85c49f0ca6770854002ddbcb1bcc3ddafe5899e98b11bf6e12217211bcac19de9785448127e4baa876cb00dc273cfe34d93f7c11cd970a6a05810beb10a5f71c58ca2f622428ef1ff03c7e8df8dd0a90bb4714cdf7b2e81c7e8ae41e66c3dda953515410adb0ee3bbe15495c34bc83097a1ab1703e16e31922f48f32e9df65e71adbdcf98abdeab3277a4c93ac8c58965d674603b79ec5f11ae88ce92869c0fe3a214aa7048f5759db4df02d0a0a167bfc6ad086c53c82abd97e88b0dbe9bb7c2f58d5e3f8ae8362272895351b1cc5c8a80de2f76dc4b9daf2215661521fb54118fcd03c21f573a67980c1f46978ba1366c515d8b360bea577010fe9fd2da66fc83305b320086e30e3a31edf6ac4ad71a93a0ad79716aed6671e189f089f3603a85f605319b0ec31a58a7d731eb3aed37cf59cf18e34223abed453845ef1002b4e4fc41d37840c6c79f8dc3ef144920f05e191e8d1bf5d48e15ddc16746a7583688061946d68b6bb027cc5ffb39a279a6565f30c6ac0c893b1588013fced2582554a8d312058a8161602e996b435e05cb7c3f8ea7fa5e0ccc7b17580b72148dfadbca34dc7c2dd3a9d97c4203021de590d34371f917c3dcce11270200db35699a461c73262b1d2760b7199711cd07bde1fa1d2797ad1150ef6f5b944a414c44e33d1dc71dfa60b70001f9e535b35eb3d8f53a32e10c82678fbfe2a5008a24eb1d5806c393a55499e58b0fec0265df7a2dc67c16acb04ad8f4ea3364a1cec30025a4226edacfe4614f9b82c2393309b18924bb77224b7bc2052c06f39388428cc1361377f23850b460a39006c714ac9aaa1cf6a80cccc4edfbfa71f10b940828b971ad6045985206b05260481c36d283d2c23b022fa6fef61e87799900d5254c2bcf4d5d9f06a6f729184fcab5ca2384db8a5b626c6178e1b49d815c1d3ed11f9014b12273690bd82de336a01f5f55dcacef1fb31f00cc8f001d228312c7fd3acfe77b19fbe2222f56f445e57ee1356d3e178a89b3e38fb4b925bb561064c9bc819a9b22f468bc9d47f0913ca812ee284e3247c8214ea5a6c44501738789c15b841e462c319cba24f951219203cc53e9a104131c1020868060f0467a4242a08e33b178b5c73e9d7755425795eca72431b03443ad05fa408832535f277a6e9becf0b30829c008a21d3ef669666587d607b465dbd521d2ab4a89728023fd0ad9c1750a0d1490f0e83513028ec54c0d23a15588af731bb3ceec4fc452d5d93674e5570f9de939998e3d424d5e49eae634a4b312269e12bc0e54ba2ec36605696c0a00035d2130374a12d150228b081f350eab00cd7f4e1565d020dd28c247b8464d316b709ddff78a9f92c5ab03653e352cba4e70d94aa09e70b9be13ee3a3988ffc46e09072f557d32a14e3a18a42487812c5cfd4453c212b99bee5e9d2b6714816265a6cae3f9b12ff9b9543fd1c7995d226a65d6abc8e425d1a0aaca155a47d85b52066bcafca582dbe7869649db20c0a3f9494050bb836b23f23da39fb5d9ca634b95dd495fe0461375235d91b9af9fe87d2d2cfdbea89d3ed8390330718ade607c80d50ec049cb93c308d4ac0ad15a7fa2c79361c4c5cc2c5101b8fa94befb358dc4bc408b5778f1c1c658a583fc99331d7c1a9310ca9e030166499e4a616be4b17ab21345565019c2639652a7481e313041a51f116007527db0512e978a18cd009c7ff50a4fc471212a7086cacdb69728055c090aa2363fe19b931e14e421c68495ee01550d825305462db56857f5e5fc8e410a754153ad3c9021905b6bfec3c32207bc0e9a5e508f30e2a1408e7b1f1380fdac824e86721781b38b4aa1c7698fe45473fbcc68b5c06cc7c31f65a5bc23c89dd5f8e7db80dedf20b1c4b3f6a4d7f01fa505390784cd0bca3c3d80d5fb0bf09e4211b2d35bf8d5e5c8fadb38bf2205074096637e58def35484b929f290f24d02e1a3f5d008b7ad5a5864cb1f6e3b9d6c4061ff33563bb4fb13e7167ad7ae620d015759a0c74b8b68b685da5309df3e0d2e6ab112768c608191a45897ce2fe42ce288c023996ab748fe7520249fcdfca0496d7e977f1a88869141fc181d49936ba5d637f55f617bad72335978f3cd324140defc4efeb3a111cfaf60fef8a42bdf84ff1204eedea657525c155850f0265eb298bc4a4511cd82607d1f3e495b616f35b7255ee78499376c872fa5db0cc9198b1a33f1214c74d6e72c69a53c72e2e85036b841e7aa092d600db4ce3e60721ff9a2d110c80b56c0e41e49ef642098d1b24c23e852eb442293da81af607240b8dfd4300d43ae9f8c59ec7067240ef8550d3da90835032d132a3dfb2e911dbc1ca0590631ac66d247d7d25b625188d03b1a2663a2e32f1904909505a297ee4f7d144dd40fbc7394946f32d9ae07a552993a54dc25c753ee8470577fe5d92096925af781767b8e122d1665a4f9226716008e8dd158cc31813dce4261d6b4cb362070b6f508dd44d5f3b06913d4e3b6c866d0402170e06c82edd24235e02156c3b1c674d467d3700a200b664ef0517f9368091c292ba6ca69b18ae6df3ec8e5f7336bf3923b65278c95c615a327b4d2727f4786bb98b7c61aadb4184d559cb2b81c18c720e347f51deb82052dc75ca51950d305f33f027ac5a02f60da4d003d57c7dd41d8c526461e4d1fb1214b3be26359fb3009c5036aa34cdd8853511c6a37239b2a8f7c1867bbf2aa17cb34f430d56d15a00a0259c41019ef4edee4222e1c0000137253957647eebf0571f7a026671f174781c06b51d9ad0016bb621db66e44dd3b0b514b1f8dd766b22bfc766ddd6934a17b2e62426552c5deb30e018815900f3d3067414b12785c99f2363b9fe9b7599eed9b6cb7d809a29a784985c97745d931e747bd84a8297e1b79641e019cc5645338a591c85d33749e159bedf41353178d4870a78a63ac7fc2a9be8dd8249c64e25ad141b17ef426040efd19f5c8ab4f65a4b121379fea7548aefe9a280897207a05075a7f989f9676cc1f378afabfd6594830e1b8fd7ed923ad58baa8549bfda2743c4f14e5bb5c3773f0b8124fc1180c61d7022d058182058b33561b3b121bfa08c3bbb10509dc3b32bfb5d6afee9317ee61ffe6ad619132b8ab3b747b851977bbb94db951c4b9d7cc11cc8a95808e4c789d39c4c606c90de8b1b3df6ee04a879d3367e50afc53c9b5ea81ca0c864d078afa883b3e9f595d630980061d8fac0a531cd98bba02d3c33afeae8a2e5a7459a8a71d84bcf14876b08c603f38ac8163ec22ee8b15314be0587ecf6862592bf5a2399b19f855fb04e5da7d0fe5ac383db990fcd27a5763e8bb8b19a3d8a47331a5b8ec9c1a63e4447ce92e7b204a64a951c72152c730c91fc3213d380debb1713d10f8c54790b21b8fa484ebb1651eae7bbe3b8852c214b6c2163f2f5d4f60c44aa72cc0c13b4df1af4912b8cf2d966416ecb8f62de26cd793f4000680ec9afc1229dddea6ce94e9f413850c708d2bc332d1c382917b32f876d93cc76dc552c7c3788f0eac2bba57b2756eccb3bfacd017b2cd8a011ecf952ea59a79712878e90bc6f4f7f47d8de4f5910f23c2a2c836b28fce656d84eef186c2d780d9548b93491fa477356b89e30e27db37e005116a53946ccc07aa5f90c73c147c6acc0f12b3d1fe7198678fb5da0ad0ce011b86e6720bda4fcd5b2c9506c790484a93d127f8040a06bed9079bea637af7fd36f760a8da33d1c8cfc69a7fd42ca289b9072a858a092c0f25129fc6a54b948ef3ee61f0d627222870467b6b20fa045e1440a75fd3cb4f04224b7eaa522e33bc086833fee829696e09429813f5302bd0593f02c4f6104b47b6ba58f81a5e09fc0f75e4b93d1e0574509c90e884b840ccb7778121f5a6228f4e468813296e2c47655be4505f3657825ab3f31e4a1ccd39d91337aa09cb7252b31ad223defed728c52ee26bd8e09dff503750bf4d6ccb2718cb6720d81e5717e9d6fe17c08fc607a6b1da238fdcbdefe2c7f0989113b804db2881839269a7a6bb8e8f354cd5553fcbb1aae84e31e8daaebaa6f0c25a07e9cb4d3b3e6d59adfe15ca3d2b44a943c725f8e2721eedb9d2f1d16cc0d7792d30c4fb5de7607886f5740a4612e8f2bbb9c2a0c871819ca707ef7802c29166ea55624dc007cf36df4922f482bab26b03d9b8b6ce222b50fc6c8a1cce983d98ee58c36bdc189b1f1bf36942598ef0d8e104c80b05c659e60170c260745dcaf2abfa2016db3ba30822d1202e139dd46a2b281984b88554c6277eb87d033ec5ebe5e0c2308363fcbad7cb89745d485e398264dd918743ca9264a04dc244a5a5aa832850912a79f120a026418b205aed0ee02903098c0afd6a69899a8fccdec6542c894b47c74fa0c5c5c89b7b636edd87c4478154f947ee8d43ea9abb173bc2a9fd055a130f25948fd855f4d52151371e73cc8157f66c747406a716501d09efee0f8e9ab9f548b532164a64dc8b019791bf3b11166de98efc818c9d07d63b508f3395d4337b9286ed370ee30b9bca8a7da489799a66c2b35b8bae4fa3c54470388a08b0bd54887a4c0e7310186971ce8628443851d7c059c136d03ef4309b2c59d196ced534e9cd0a1b8c4ac783f2d22de95ef13c3846c5f0e21246848c5a5bb0fa11821e8cd4ddda6223c0d4537af5d0d0acfb7ed405a6e5a806d981df0211537b5f7e4b7fdb1766da1adc70ad1e256490ccea08bc1e756b3bfe6bdaf573afd34f483d342db89cf81ba9a29352736c80c776748ef67806cc810af38b274812c27f364366d475612d77b2a62fdf4785e72db5de881f7855d773616cc1979afaaee1b401278a2696441e1b2ec5ca6a31cbd76a672d24426c8db989ec839fa2426a8614bcd39b501af308e13ede8ffd7091570f9c813235f080fa68313a4bfd87d81d6eb5c49969c30850843229773f5c8951a697150d6fd9715422e8bdcb9b9deec94b06dd4376d3f2d749c6407f6a63d699142ad3bf76ddf228d04096f0ce29ecd8a7d1b580b37fc7cbc7ffad5d0f582372f3a19e2c4daf2c44c1a68818b46acfea1e034bb94d6b35b3d62a67ebdcc2cc5e4e027e74429dd9b582f049a398299cc8344261c09cf5bba1e4cefdb7b1465b7f0265ba9c47d4fc8b728b4854aece7e7732430e1c685641b4a2e34ba19daafc95b9b5d11470c2c474ef537de8558e9e9a195a7ad5e7221223b08dc480e749d5957771cd920c484d797411f3c1b1103a6682733eff6061cd47bbf032ad4156f0a97b16bb2a062adb76ac7d6377bffb4edbc40ee47d77e96d4a3e112e50d4b9a6b83765c3b68d89419cbf3a00d8c199df11a2cd333b64e677bfe92735537ff126df850e5035ece0b5d488abb723d910cd1bbd2c8df8ddb190614e5ea5921b09c3ac445621277ed7ebbd4a672041294fc9f51b03f3aaae4f33b2ab64aaaa9233279b1e57f6f1f36c09dc16684f302cd42692e92dfd9c422b946c652bba057108979edacb18509a1013b0b378885f46fe7af83ff939d045e44dc86223a62a446b7185136cd73dc99a69545c2aeb2d692daed276fb6be7243666105901ee2ec36e26a511820c178f8cbe9aee3e343366939a7a994948451822845a27288a7c88f4bc71eb97139b5518af8d1053f8edbed85c6130d8eda72430d68e6c842ae9912c7e6f3c88182587df144395013fae5d814494f077f526f6521e9bcbac44581a1f3ad523227e0d7d1327a45dd08b160d8385ce09bed4a6d9af86b278b23b0d31ff7b54a136e275dd07ee0304378009fe09bfe7276f9e815948a8f88b1d522a32ca64ef56cb46b5830680c57eb7ba1a7518dff8001f2973aafc1635c9caf583e90db0502bed409dc11dd65997fae8e07c50aeb1d6d303a00bb7a16b063592e66dc9ceca0a5d7301dd6b1257de7adb0b91113aa15c6f4742e23d310c4a44c30db3cd7e6cee70e6ec7e4f587f1b2e96dfdd225eedc1d0ad513705df13a56d641656128f34ab673873d04326cd1ed45f0edaf8e24dd8c2005958bff6eaf848065f06100ef124a7d6d1ee9fc52b80b59c9473dff0072a88def6a902d20d67b436a7131a9949988e36a4033f406a5363f52cb0aeff1999466e940ab9274ced4ef565c3e9e792ac3a4c57caafa0ee4ef62d5017199c74e0005d65433fc06906a262a17b24212d73c6adcd0a3e414cd994fdbf1bf36f562d3ab4126a56fba10b584177b545e1e19e5d2e82f201a95d1ae1f3b3599f94766a7abb59fa1e47a4c6d8e6689ed50367e12dab77e180b0d5d5606f5f5d3d92007798f2d1ca8e44006eebf381cdd918fa3a0b2c00c16bcfe6cabf8a7bb308724e3b854583a6226af7c53b4551dca41c4008fb145d83a04c9b44c980a26ea1522e8c45cd02d9645fbb85eeb6e9e0abb4285a1975ef9fb7f82a86359b9ddda2584894c58cce689ac0fd8060a92ac9e4fae9eb32f8bf4b54a3c469d9bd37e0ec022d73f7f61e5814f2363eb2d295de67e4f8c778e8a269734c2d6c351232ae614a72a261454815822e91276097f9f45fe28215c1de875ec2bfb518fe0383a446799cbab5346093e16a6a8037bb6066aab1d0a80b26d5ea1979215a8d9a1a865e633284daa888696b7870bfc6963c8c3bb537cebfb66b142508bc8333d296708edca5263e126ee82d3813a069a1b79875908728c11f29c219753961a7e0c1ac03ecb61303552207d2cc413c8923f9687337773b4176783c015734209fa9f55c2a301d69fc729c12556a42fec8b5fe36df6ca296f79f476e915024974baa2b34a820e7e3d3d9b7275c80eaa0030c8477f011bde9610115e3398774a129af37450a7408a5f5a66dcf1c2fc4185d7a85261443d286ac838ef08c3ae5803f5f274f48f809a8e8a887e36956416cdbae7cda4975f63732f60b295cedd6518b0ef9c01c7bcf5bffc20f5655b3cdd1448185da6a84bbf9a0099c6f68e96ddab22a80fed7f0445a47a53b380e7baa0ca7df3c0cd937d21ced1e66424215e8207b08a5dec4e4bf8efe680b037ba49424de2ed21c670f3f5fbfe96e10acc2bb0eedd15a1944fc59b99e9537188f3ee2e1bc8663f2b363f14561c342f016a284713ca4c28d9b9fb21714928592aa4f7157069a2fe587d592b3b454529c5025d59da8a4e9eaf44bbd11e2d38dc182d1a39d0d3b20d713b2bf2ec01b84f93f6889064038bd76208010eb550e2ca5bb9c712cf4edcf43b8b6ba70a1c0ce65c2c467252825a44f36f5a7b5016ce0708f4044a7357319b9d63f05d75d2f328d819c7aa81ee57d6e1d528c0ccfd65e27049423b65831ebe04740fe1310195cc7ae049588d8e72ff2c12bd3491e747412eaf4ddcab40b9490f2ca742e41f6cf75446ead4c47888376bee3f50494246b12fb60189990382f4110c34b8513e4bf993bcd4dadc74391c0fa05e47d0e18fd2ce8d4e79beb377526d845e7c4632fd1555e447021ad4138c59517ef2a8689dc34079163c01bf2205c1dc6f15c5e9d6e314db332ec252625894b3709d2cf9b7b4367864b54ef44b2463dfed4b286496d82cb7dccaf38905a89379132557f6bd0706b84d4ca751cea6adbf5962970d65322a4f2c473ea65dac6e464e1e2ffe24e7b7a9e59e9ef6f2b3602b87b4a201a2fd8d61f08e017520aa3008b4fb2e5647eab8cb53317c3904ddb0522b4a97ab86b189e678fbfa3e15b9a05fe8634b5528f5cf529e4c5ba9637c95217fcf3f68e56415ec1723d4cb96f4aa0d4015319c2267a417ebaa7e815d2d699a1ec310c70947e3c123c358ce6d3256cd6ba8f34f62da6ff67e5cd111ea0142038bd2232dacaea817f2a7af66a07dfb85ca91eb945470fcf9c3fdc1e3163dd61cefcea3634c3622c4ae897e4ac36b0a16cb0f6fd7b37de0ac567149d277d65dc525f7b07339c509590fde99fb489fe5d20ebd114839c5760ce3956867adf90700a9a3654a8b72668e21cbf71b6b03f5f62dee43f877fbac927a45064d4c06fdf551204b38e0b64e468b03605e59633653b94e6f1103eaa1748e67386db1a50a0c9d27eb487339bfee8243c3e00a688eaa2bab66fe557540635fb3be3eba80ce9ce13c0e6509f66bd0a6385d1c810c6221f0e6a980be45229f9f9b90b3ae99034332b73c99607f171e8ed69191dd6299bf128cb6fc05ce49aecb7e0e73da83aae60a024d491b4bd32e3fb5fc588743a40f9e84c5b229cccf50d7b9546dd4c26194d6a6426518fb0259a9133c2965e56b2a0fd76076b60cf5e780b80228c4db5b83c2ae77d5840993a361eb41de02dd815f0f9f01c69ca85dd0ba054fb93ef67d56f43ddc70052d1b50cdb38b216b850c2e8adaa696fdf4938093416e40d6e2c8b9a30bcf00c72d8325a6fe8503cd40250026a55c6b90a0ca855d6ed97198b45fea374982e0232ef23a5f560c855ab1c87e0b0b3f41d7fd2be210990c97905f22ffe7d88e5729604da2c2e0cceaa58b067e4e98170192081eea355341941cc007ac885f992c690017b030219fe0ee653b9edafcf90c55aebe6823f3c13ccca04bb6af869e78f50ebf893f78667cd50dcba94d93c00d8dc56ede45f406908f82abae471e91a6e55d7e887573603785c611007c743fa995f92901f2167f046424fd02715e15859d993a23fb06be33b59287297052ffa0649ad3b5573ec8a1e3bc107f442e88055f493f9f08233bef448e3a31e71dfb64f8070a36d826f3273678d731c26415099de10fc613c9f3328b49263e332bec8a6849e7d9944dd4a17bb870ce6eb6525a7f70fea139a465050f32236842e82506cc8573a669076ac27d8727d3019a199713e69033c2ca2bd47c584b090ee463efa420c7cb2a64534d389816ee4be8fc2f069ed8a1d5af85bb128b9b7dac14c42d8ea3c22da4486366a88d5180285af55910d3dd40d095a95629c1a5afa15ad3928fe8db55cb3669975fe1f83d327a14371943e91ca35b3fde43ea6b8eff6d9335e3e582bd875a168212e2be5bdee74b5567b0640bd8bc7057041550250639b3f10dda7ba720d59455274e5e0d788b9845481ed3a5c5327067c988feb0b626bce89f4bc0c47b74eb10a08364b7be65e69c8c8330c4f471c167a0458bcc4345725812640115ef9c13b5f4a039b36f51da68b338255da43a7e100c8cf8c11e1724b5739918897e82a378c534ee9d633549f54c6d871e1977f98e9a329f45647068277fac21e5ae41b0de697946557108143e8373b408003e49ec0d1049b6690ca88883d6c4863fbde0c7c88762d5800b00484a1dbe566d7964884cb8ed0906935fefa897c38621490be2cc5009db028d9dd37e4f29b8107d16bdee514e88de670a23b15d20f35d786d25d420d04736eb7f285dee5b88803adb9081463d9ba9c1a7e52f42a051e29c5c7caed8471f9336ff911e4ca4eb341776498aab4e5b4d7a93be347e8e002a8a3e071a59f79058a2ac388c40d833954e15c3780dc5071d33d0ebcc2a70051db367a63a5a03be0303df446d6ee182df467b4625ba4cc1932818b5b1cf029f7b88a4c034f8e90959d204de867aac866033aa704c27c846b889d3357655f3c018c22c6ad3c05005f7887451c64da4e6c81184e690c9df59074ecf6ef7409e84ad064c53985e75cc836868458321d84fd69473a94abe37c7b6d94f75ac23f09cedfc2e8bedba3cd37b27da476646ba547da11e6e3a713f6cc19c4d280e7ca4aa82f62b37d55c0fe9576c5d7439a0cca6a235e7e113f65f3e472a431e9511d00419c5cee4e4ce7b4e44c475d0b85be7ca17a48a36080adadef9d090ccc2021546019bdfe232a1a748e54ff9191ec2fae0e3dc6751148a0dbcf4fcc7a128321897958bd3402d9d4116864137e02a34325f04326062552e0244ac69c0a1a0f97955830f3e7130a773e59801b51f062ac1db0bc24476025133070a00a8fc6e30c61ca725f85a6267c66d3d361c4d3c605080946fd178ede29c62b618d3b454e4886138916112a051f9cc92599c8fe4373c17447e1b1c29b10895c7ee4d4dffcc3ee0098e3aa0cef08866c22811b994d096c353349fcc980df74335563a822ff00098420a40f67add5de7480946a7afda320b56f2020dcc11228171e200a5171a2ee3b0461c96d2992a931c5173a2ce86f9038dd68a78715f395310a942f8d9040f281643d90207a6f92cc423ab596c0013f15112b21715cdb33dac1b2d3b1262359431f17179d326cc4a1319ea2cd848e54027b257a473060a76ce3a09665a05e0aae208cb9fb16c4949fb381cd8ca52b083ebecc3a87611e2ef75723d97cc06f9e4a33a9ca436e06520486367444552a0ae8ead41007dff37f1bf9032416fd1b101abbd5771720d34ee963a498618241de0c23e9db5ab38ac6c3de3c6ec2c9bdcedba3472b78cce0f0309fbe63b9477dd4064eb2e854bade4885d906efee473e152cf1b3d73b4ea5bd6d692aca9d6523923b502f4115df15a31832935e03217e493158f1f25594e1d8969bda0dc630926da5b4c1375093e7021c01b8d4cb7430b83c6cc54103c2f65db6b3ff5018c3d24444234634a8fdc74db6bd8bb0fe331505b480a01d1926834a8d5147c52d2621c535dcfdeb525b5d593da377976fc94f3caee650b9ae6a5667aa48abd5e91e03ff7af89e9f41ee2388df4c50ab7b3f51d368f99487ec89f9af479fd624ea986a78678005a3b41affec490ed424742d98b3786ed3f2b8a8abbcd420b58a85806da8b4548ba15623cde091355cf42fae38ca03c6cdd6e1dc23648e3772fc81e82da65ad3272c106d6a2c568d9c8a44c925ab6350b280171db8180f8308873a7e018d9b460b76327deb813edfcd0e18e3f7a59255e74a56c9f3a51358385889f1476762faae57df924a663b07d4b0c593b59bbdaf48dbe11616322d7e3247750c65e4c2d5bbb1073eb6140645ecfd4db3ed6e7ac6511090af3904ec3abd0210180af84f8b3361a9b84ffc6a6e9882dcb0e9cf7068f97086ddfeef52022552da0c640a1090ca946864f9821434387a3150582c7ed6f22b42365a57ac4e71926b306b521c8251d090d907d65f29ec525241babf43ed9426e6ca6eeed209d8ca7c5e33299720193308ed6c6352b092cfdc089619a1457f0f8a6f5750617c6ad9e7cd0385dba6ebf8e55888aefd911e0fc0c0c4350d63a19e8e1e459b442a6f1c0315b6729f5184bab2b7f5f064831b5413e45072d9391973a663073c61c58cd00e014f133ea9ea482aa45d90090012d99438053fbf6cdfe37ced73312fbe43256483b0dd9f46af1e39bee4397a59b27feeecf8cb27ccb5cc88eb4c409879110533a159f5ac9f7a439290df8294cae6564e59fb2f487102be04cecbd3f52ce2e6abe3d0b0692426e035d08e2022e90537d9e67a5dd0cddc7c04760ec2908cbb2db5c587f71538c2def77521dddb71f4dc8168ee6b8a1483e8c98fdedea3ffd80adafa14150aafa6182c118bde0be8938808e25ba9d360e50bb6a53513698bf58de3af16c4f8c98dc750d42277a060596c568cfa97bec61275d1d6b469c78a36a11bf007ab13ba1acdadcb907af0f1f0df96f914f6e7566254fc020bbea44a3ae178a5f18d93beba6c9fb2eaa73416a817bb8f706b4f15525ea1710ef404ed5798e001779aa1dc7b728af181552abf577c01bc60320a5940d80a04760ad4e31bbfe6f301e76332f4997cbaa9ecb358809b30b8480954d8c7818289269d4de4d0b2467c14bfd423e8c138d0bdb883e2f1d2dd2c9e8eaacaede62057529f49d9ee02c3e2451c8b8d7b2df454ee40dfec170864268e8de62e755691115d8f23309a5c6a00370ba98328ca5070e2fa532257ba20cf03368ce3999ddf2bd102609078481a02554b5fca1d454348fd05e282d3d21aefea64610272aa1bb47875c21b8f7edaca793435791e9e4cfeb506a02f641ac5d2eb083dc23339ade6cb5c657de9be9b04d92416751ccd04662be131c84ee6fa1e0a38c94766880151f0b53037608acba22e7bb2b2a8077c5e5b91c8263a481694d385b0cee5cc38701a71bd2e9ac9771ec0e7b4e661f67acb2ad7a9a2cb0ba7da9d8a5d5f6b75fcfa6206a4c482ff049b7a3a04709cc083a1be54c7610a1f508822f73afa6611e9afc78b576484fed6ae822959cb78f69422b98508954ab7c79b95824b1482172258e88969377268fd1b348b619a76db8e9fdf0fdd8e8d80045ba87d9d75f5c5a9f64391ebd5eaac69c8daa3b519d5f7f023fb26d329c7ee932307fdd47d527ff411ba29a1b08a29635da8055d86e74ff59784695bc28abef3661a4898834dbd7615c28a08d9150cf64312957f9fa91cd9049937c8e5196d372a1af0f31c7c0fee2eb42f20e289f99b274f485d67b450fec3ab60715f234bb8c4e88c4f6fa6a890a9df59c281148cab187fd13cd746dbde2e34eaa1b8221b4491e0911b2fafdaf0fbbe7469869bf2d7713cd66cd64cff5aabb39363f924a4f35323787ae977b95e5ad71d768915834911bb1fee75cf6f4acb4ed0414d756eeb646e56bca5a13823382e481357bc8eae2815ed85fbf3708bb11da9921abeb33f76f13384d73062555ff33354b9bbe2ac1a195ee83bfdd6e9da9578de214ca5c72bcd87268a413adbf31bb4abc909d838f36e30a131f4e6ad133ba8798672fcba0843935ba1dfab93a478da81461854c9d91ddd87bf21391196e603f8b04dedd75e8de045315e40de25ed81ed24b5df8980cb752bbc3d5c242d8ecd51048d20584e61998f5101eb746fd392cadddff1da0ed90ba3d59e8ab4de9abb48489ba60ccaa6b46e065833be418eb7f5936c0c31291901e469bdaad6ca6ac3020132afcf0439d45ce5a44bd9b5a41d2be81af88051ef584a2f293c0a3cd2641c52d1a4b6c97426a8482140fef9a106e59f44ae74b694092956ff40c509d708e095f872743e36281d0f33270aad9a994a1555725e34efbaed519bb8be302ef913f92377e6eb60a63c5bf77679292ddf6582567e51facbb8b96af850cede7f5dbd8ad6efcaa0295f2cffb26e7e1dac5e3942b18ba32ffb9f4bd556e3f8bf7e81cd315231dac98c2aa286dfba488828e1dc9beea9fe3c858d0faeff15516c808b1519250de18e1523f894463ef93793dc2388d8fc56d25703834758037fdf304cefecd07c43029cc46f2550bc0d8be3aeb45050b97b62ad3750cbfe4abd83e1c8a646011b65db92ff612096e819e33aaff68b769590686b5e6fb683c02cb507df1359ded7f8cdba091db2258c0a53d06607c85cb84d0a507c5eb2f3a56c7fa21032485fe37b06ab50c0d171c283aba1e35a7e577fddfcf4d2958329e8f8aa2d25dac7c37d5ce0ce75550018edc35717705e614e76e15d9ffdc751c4425da2290c84d775736a74b6a50b2f33cf63f6ae54d9ba27d9604d3e3ba784f0978f8df4f308a28e0c1e46c6c66446dad54808e1a6c65937580aa8ede59396a57d5e182b76150b87151378968a11dd1bdd135ecf85ae055ecb44f335439f6a050f594723ed36570b3e3c5a55eac21616e8e87c55d1a60142b1875710314f90fc6dc682b8e2d3ee908cdf302bab5df7fd17e4422ff0c7b5810118997a1c602b30e2364637c1d161e8044a93abd422b0d8011ce092f93018f95296490485f6bd5305810d082d077760b4d36125ed811927cdf46955475613ee5a235fc7a2326abca841a03d7732f4741a55b27948349b14b514c97c50484518c0cb21df7878d02fee7785c707c618f053c00708c539bd8a087fc87198f876260d03ea35c4c4400e0194474a979e39ef9a835cb18f4a659923b5aebb3f36815eccef8bf07eb5dabc0292109f2e8b870a812f8ee60b7f1277b1c495706f98abf9d06e970d08fc8cd0019571dac46bc0697742f688bf43c60b9d328b45b17e67ac5ad46efb28876de3cfb87e7db43ed6ea098391f9960b0136225e44a24992aa674d42c94443e69fcc78bdd4869e17e62571ccfba5146de0c64c7bd9bc9bebdaa0a4884ed4badd217e8a0bc2d9ed00abe7530ac025f166c027fe54eb26ea9380601ae10f9021e734d909afe8bd40a4828ae476d784df2408376a827a27b5f41fcc70eb9449184c31794219f4e532fe70ef5e8bb0c85edadd9942a20e19c906d0b4dc3706741a5eaa714069132aa4f35e02d78f729e7cf261d8b9246792bf2e0e0024c9c2e376f72a5958776e6702a98c6a5aeafe04928dd86635b7f4ba980a9de4fabad617517081e6cd6a2cb3c756baf921513863a3a881a2444627ca9dccef87a173d36bfed09a1135f02b3794422d933fc9fa5814e0df6777d8f20f3b799f42f3df20b9363291f907b8ab4912289dea57a6c04e6b72e40cdf328d357cec17f878eb0ae192117d589cda5b81f123fdee172eb359285d7e5aed07e1a8e54d802565955cf31f462276cc53fcb984cbaf39c8712b618ec73ac0b837ba4734bec072f00b642082a8553fb061683bbb5398abdbdaf19a96348e89f8aef7322df731728d54f502321c55410b6cd92c9ff15bbd0fd4b10b4c7db050bed9aa0654af012a5e65485c30d0514a3ad532f37f2e47450000583da200024082214aa8d26e4e0324b2d1ac75c32a68eedd333e057f5d8038be5058e139ae8eeb3c8fdb89e380cbbb8f0a34c4810b5e7982c3c919e14d4a29fbe0dfa2b60921e5b78490bdf7de321a045f047904f7d36bd500bf3a0cfc0ac7a078c08b63dbe5bf7e6d61e72fec9794ae8967ae6240f234c32227f3e49ee140e9152c5e320da611d46fd7688e9ed7869deab5a81ea79e97a5a161a611d8d7a88a3f273dd2248abd22a4a7a74d9b2dce16a7bb08e92e42341390682620c92aa5a5073c49c9f5d48a1ca0107a30fd9455ecb4d2926b1ecd5915397956cc81ba06ca295321aaadd5de58e189939b35609cdabcaa17253a3428e7665484cc6e6062c1a498514992c35e11ca3dbbc242de72cfae10d9ce51a4f96675175df2a7483d5d839f610c0aa6eaba09fb4e714c7a13df4b89b66f67e154df83e9bb6ee21814cc44d04d040149f97a987cad97e7c130d65998069638664489b69b78103681632ff0f612b153a2ed40b83b187ef742158e41b56af4bc3bace71d8e41f13ca68281ff704c0aa144dbc1cb4bacc2b110285187278e49274ab4bdc3725ece4f1c7392db558f79bf46abf7abd3cc8bd2e9e7fdda7cde2f79f105ed09fb0586fde24291dbfe13c6a060dd7d704cbe3a26d57b7e432628986a7bcf9958e400b19481126ddb5938a930530c8a02fdb2d7deaf1ecc64bfbdbeb05f5ed82fd5bcac72240be59e559121773d7b7e4b6cbf9a02fdd20e827cd9570f6d58494aa1736b6265a80e59b1563eaf56d741d05a0bbeb360e87d077dac8d13d876df771004c1bbfa0eb6badb107aeb3650fcc441cf7ad6eb700bc35070e00d45affbc0ef20f8893783206ead70ab86d05b87091df679a0f87d608795541e0882e03b1004411004c1d63d47914e248117c267e5ef47e8365a5808db38819f41100441a196d0bd6fdd7b2fd81da8f5d5bd0714c25a58e83f3e610d0f7cbf75e92581f8bb5dadc2993d10045bde57ffde0a4f5c284401deae42d8891a2770eb5f08438185c05fd0de568dd64f1cd6c227304c08831f7d714dcc1f31ef42f146ee6afd7eefc5a2fdeabbd174dddbb053f22eebadf7febebd0f3ed6745dec894b2cafde4024d71b7ce45aeb69ad9556fafdfebb7df7859afc9d6227dfaba6c4c9d5e7157cbdf53eb8ff3e58bdfbe7590fb7402c63853bdcafb7de7d56df3d6cafd52bbd09d857dc5abddefb0d5bab77bf1c27defcb55658464f97f79eaeee1df6b07823d76ff3c47bf1122b7bafd7bc155652fd2eb13ebcc4ca3fb8e2abaaf6b7565bebf7fbee86dfadb7abd5fbf76b6bfdeebd0e8bb65e5a7b3c8ae5d6534ac74c1973bddfb06725deece373aef3094556aee02bbe1ffefe8282ffc2d56da8f2fe62de13d7e7d68298b5c4f2eeeabeaff79efb1753be9b822577bf2b2c36e5d56df885e28dfcfde7e6ef2097bf83170ac17f5fafc22f9c1e56badf7dff3b7823e962ef1604c39957a1d883975879aabcf0da7bf60bbddf50bc21e3fe931e0c7b7089057e788995559eaa090a8d1b5c4bbd20e584953dd0522f48c16062ae5c9899c9629dcdc0cc665b6633391548d7b39344b8eedc79cebd37086f97cdd5662b824c2f6bbfa3754afa894db93b85ec66cf5309394ff6daa0dcb328292da30f28d88143102549c87881c1cb131f760c919e164aa8b51699a3c29c147cf8a105515e568c1721d5cb90a71ce480391c91c23f14058328186cd390382cd071410e282b300993b7281d798b1202e44c2692430aee304142ca8d54de7eede4cd4b113fb05008f8886a52a5c7d4ec04306c52982f32427152021263643a6c51415a3471ea0c91c38720468058f9e2250642ec192369a494d288141d80644489e6c501a418ca111000071e4815f36298c5d398aee95980124dd91c842055cc8f4073d398471f982eb1edd4ec0482791be10421480ee411a9c2c88308d42cbac02c1a515c3929f2860fcc2359a65df353529944537220a54815f313cd1da9439e1765903ca553cc8bf20431a408d2c89568b63927a55a501625920074117d0d3be8227a8e22bd8928529051a6ae17995e4ac9743af1e0c8c14c173a6da28e9c997599ea22666a6a6ad605ca8c0b175ba60b9620645ab9675c58c0c5890d3b8c1973c4aa2c50d792416f1f83e2a67ced9d372d14eb95ec459ecb53194adb79de8395e4edad2743debe477b4f2893c8da7b249ddc371226ebc6ba5e86ed59cfebbaf7e9904af57defcf2f6cd78ae90a7345a34c912e758d567c9f4af5beb452f743d7c57d3748817e3dedf0de7dc777d5a5d7aae1bd3bccc31d867d3889dc4d154da2f1e4bddbf1e1a6443b54f8e24b89fa5a13cfe47ae8e49dacbdbfdd6e9193b55beb2535599e933073ed34557b31aa27c6a60bf0e276cdfb407b8bf4deb583a18fbfc0db30167301e2580cfc087ab298efc9e2fb40bbed7987aacfb03bf7f16cef4231964512a6d89435b96df69db94f2f89b35bdbc6ad19999bf588f6d992c7ed1917205976cd75629defe49453ab732ad94f5a513032cac271465ab09ca0258c0f2d674ab038685a66a0054ec7c5d88cc6b47089170c451e2cac9bb7ed60c851221e8945a09903acace14d62126af66ea95cb105cfb6852c70dcedf21cb7711b9dd10194ec7d3bfd56abbb82ad7eef731c6b7af9ac66ab55a39e1e04d683dedace7d0bba7c07864c2b28d8ea4067ba4038e673f0b19f7f0f0a5bda83de2f1ab634dcaa714f0fc2ea411833059dbe5f4cb2171432f97c751a3205bd55e3e7f7367cbe0a0aa142266e4b62851c25e2790d79b8190e69722371afd680f72c69ba4df5e158d32b0625ff7d25c3a617688300b96759e6642d44b2d7aa417f6f23e8ab7314e9ae5a367cbe3aece717c7a0b8ffc07c5e3e3354df3c1a4fdfc12d0c615e9479ab41bfba8da053a4d5e5e5bdda633fbf18b67ac5319faf30b7c4a2de0c158d12ef0c3371a0bf981ce56ccf61f5abc3e8ef6d95eb318107fa173205fd63058550ddbf90e97b094ecab649d936b1b11889acbc6d6f9e737293de0734ab5458844ea20b61e08178368e156a4bac1906907a41cac47fb00f7651227b164eb75f2630d47c09ccc4f4739f0361a6efe045178da71d3fb8c5f9e0d6b6e3c3ad9eb7380c83dd5310b77a708dd5eb5b1b0661f5fa7bfa1608f7f4176b5f18d335afbd00b3c03cd232a08523c8acdd4cee647b494be4b51a52f9399287ae67d743484f3d595049bb2a31372dbd3db598a32fa8bc06c4a5956a162fa9329d2fe8824c504ae98a2217540b97abc888530195b84874403fb7df5ae773bf0e5fe27339ba0b74ab218ebb2b582c10d6cdc6df5dd1b526e5ce4f9c7b362526f7065d37b7aa801b2ad3d5b3292f59662dcad56470c5b79847a2ca681e892d1c308f241df9a189245f2bb29424a05e12a51c5c91cbb5d65a25a5de6c61c99d2b9517d8346f8694dbf66dce229da7ba4f50d51e773d64514c226b9358d365574c977dd174d9bbae415dd1e5b2b7ddeb8a2e17daed8b8c387b953d50d5704f8f8ee73e414dfa27a8966f56c7ddae9b97abdd27285abf00344972cfce30c908c83d9b2a2277a00bd7872b5ee225f4f392627b5f4ca943ed6e2a5588570325f74c0d938c807c5b4c5710d7034abb978b7a7aa0591a3b999eced46cc974898fbf2aa672ce183a1832cfdb5b07436679e95f50253a8ebbb7fb3e41f1f88b355950a026779e9b427345029a445a0aae6abae6e5e4d4df7934e7edb685dd2ed15e9bf6b3ede9cc13c7d0a45cf383932c1ae55944631ecd0b4860de480e963cbf62ce1eb2d860f2ec54da2b6651226e68bae6f3a533acb4b8de16cda38a6f9a2b7fd453d239bfee1494dedea6d9529b72e7160c304a0051775fd2194d36f42c5725fb69b7a730709db9c9ca99a58a5a4b206ecb8b20cba95569ad2ca9605852694aac94714bc66e16738d74c52dec25d7528d07e3d69eeb5f504acf256dd20660d3704bc63cf680cdd5c889665597956b9db756956dd3b648db924a6372af5c79f152ab69784995ebe50bb5258303aaac74e910f3ce23ed12690450b35219f51a164facb073279d732ac92b1da7c5e02a5129cdd489cda6867cb967533cb2fc6d3ca717a3bd9e4d25994d3de94ed1d307ed08a575d36ca55372e0f6cc4c9b5c6b0d5d4f0955cd4c9989d363cb925551519a547043c3161de312a91cdab0c033abb6564b274b9112ac99fac10c10362a7c3340d990c4cc103327ac596266878f32449409224a7dadf5b59e709bf3922c9612f77469d1768cd05cdef0f8c10447a4941c5113860004b334427aecf084c6870f9088dcf590bb6a3a341d649af49715d891f5406448112767ca4cf1290366c8900c5f782c0903a58434536562d8cad400848332dbc1ce6c071334993453264e0fed6995258365a484808cd39814eeb41419213a8c20a30219148e28a2082644fc880194212e30e24299313a469e21c4b40973041133f8a092050a1b3b4d80903b88a943270c99303a8479626b28ba440b6497945cf8b07a49769e864bae3ca515daf2e6499eaf4b2ea12d6f66e0e6aca1ce1043586b2d105ba5b5d6fe30917b261525558309d0481559018d940940d0ac72cfc0cc91c2319dee1cfa854dee4f1c77becb3dfb3226f76512b7e69e7d0193fbdd803877daf005060be7aa72cfbeb060df7c91593777cb3dfbf2c37ec1e1824e4e39299247bbe5e46e93bb7bc5f41ac5d0069a685e883cbb081c79be872bc125332ad242a220cf4b7c63cd95f7a06e378558012fb44de465bb61b10399069786ae8ae625cc1a20ea1841040f241d0f131e2356361c385831f2a3ce953063b8cc2714cd0d3c26f8b06809b3810a0788913077b63cdcd48279ffeefd7b0f65564fd78dd1d9d5295c9d429ea34494a8674331d483c5a17abab1e691b8a4129754d2a962250dc8729346753de73d01c2155d4379bae014899c9c31e4295f513a99bb763deb8e9ce79cc0ec4d1d4979a65c794a69e87a7e060749cfe0c8a02487b1860102a5862751a48e308101098ab41d1ac62a6390c584acd1ac91693d8e4822e4383b40614a9a1ad89861f23497e81052447b83429015888c2a645bc6a6c1b8b59c27697a1053068e0a9458f951846b400b4a2823c40c737880325d70e3a508179f04f0303e4066c78c2b999d517bd34210233b8c6846997ce1c7d874cc8c0e9045913f7499156c9093024d268170e91ce4938ee2314e19bd5c2665304e194d30aa5818652518657208a0b941b3429f51520339839e49138c18629c1a8f64478c358c1b1c4026934f498c0b90a501e334ca6418eb141939902d2933ca1e258e1865dd430b9944a18190748a185b8751460227a391cc881690482a50903833fe304a1c58d66b84d0ec4ce226851edb4c41dedc3cc99ec8240a904959bf09e382b1875187232e64b2ca281bd271646d240ef28bac4da7d122b784e9199c30b21965438c6e464ef62588b103991063016431b494dc21c9b4606c1efa4a1799182cd285a632031c15481f1d4410306393b16b40345eb98214b24ee24e0a5de704b288f18651fa30caac8c329e2e467e54e141899311b385376a8c344046664432800c0b0ac639308c7072b46c85ac719077a48cedc38ccdc882110c80ec05515a46993432350a692f5d462ba34bf666446244800c8851eed059240c54181920333316c99888195b2764e19812ba8ad4dc0831ca5a8d948c3346b580053cb8d0650ac90a1305b3372b3032676421837223d53411a30ead069a96c49d3b94522a4fa95419dd015a40912d708042705745f0e49eb199937bc6264df674905f93468d1d6d0629ac82d47fe867038427485d33c75b834410adce87d84c6143038f498446c748a36324d3c4c93d431327afc83d43f3248ba0e2be983dd41d7408503366cb1d2832929b6a9b5e52925b3539570e75d4daea66b6fc517dd419334bdc9d62f366ccd36b1e8cf91773ce1918c039cc4af5d3fedacf6b5e52a594ca4aa0fda0fd2045a049dcc9d249768a29372cdb654550731d413b095c1e81849bed65abb035363babaa1ed054d49351b326e9b76d58046ae711b5a14b71bb76f333d4a26e5173d01de04aa0484a29ef80e9926f315d73ae072d281227258b355dd0cba3b89406b82fe68b3975744477835a6badf545ae6b50b785abbed6ee755dd3857d7d9151bdea40f3c862570c9965cdd1c190b95f00cce32f6eb2d05e9b5c7a133a02dc183f1d0c9907707bebeeeeb6aff573c9c6620d5dcca2445daebd0f9d006ed70ef774313f7178a56440f7dbb5d35a534d9776edcb0dc0b517394d0200a094dee95a51e482e18aae16f3a8bbaa36a04107436614abae75bb5ad574598ab516aef8dbbbe06eed0542c1e113f7096af3b25df651fded6e4053dca297d9664be7acd20949d67d82923cfeeac9a203811a2c5aa87272c57b8158281e042bcba43bcfc5e8fc0fe6aa55ef656e1eb5ea4790ad8a4590995ee6257df9da6ae6ccf2bcc074cdc3028e80a8d4eb570c7b523ae668040000005315002028140a07c562c1481829a3f80114800b7f883a563e2a1305e280300c08034118c3200083000000010080300882501008a1591ee2edf6dbefb4632431d2638457e0950f90e50fec5f3819971108be0694fb6ceacfa0deac733f030dd040acdf8de7c501c297974a675e52dbfab1762036ebf7e827fefc38fcc96afd7b4a85d254231da45b38712592239d16bdc0b443ff6ab70e4206ae8619aeccf46a64bfbd2d2f064c7a4de210a918dc964afa1ba5efcb55b2adb69154569056991759e5dbd4a656a81a986d9c93a788b2b7bdedc63c9f5ef8b21800baafa6a6f250a55a63b03aeaf0a24728e38cc8b162cd68b2f7e8f11ca84a44d021c43c346116bdcc4c067caa684048115b99c938071c6598e78904b10fc7146638d86eeabb45951d151385531182fce71929ca662aa680f74b105872eac4cbb44414299b4cc72ed9914d4bdcb86e40e98dee59934b466cc8a3338e280aef86583e6c88a6f01575e73e4440f4023b7d43fa98d1c7ded49d206bc780e22384a1f8d1989c489c3d39b75e76f25b1209737ca2599ced168126417b17fde707e1538cea3ea118036d6fbb9e3415184935a3d16126757e492deeabb9a7bb75b90bfaf126159675aa5cf90d1a9bee9afe04dea81b4fc78c5f8a3db935d964c330f2b7c97663ebf6bbfabc022bd6c584b87912e1d2a3bb82b8dd2ab094d736f72d39d159dea273d37eb14ee8154b8d3811dfc15fadc48515ea84c9b7d6160f30eb96f360e47c609550a51c36d8ec8ec1c01995a46eb0d758ebfe2bf07592f4050fbe6ec0a68306fbe74263ae99cd33de641742d5f3371904e8a1ad95cf1551b191415001c185bb5552a402602443bb6a1ed34ebdba9f2532fa261e6eb407ca16a3320fd5580e9fa7bfcf59fd5d24e9281ddf75cf1909638a975ac7b38c64b555414c73c229f7706d16873da1ba0b618fc50642e5ab548aaac919d3394891098f93246c6d4fa15bf17e0e0044c8e7a3e5e61ebc1f52fcf42ccccd03c6c3b4596c905f8a6c0f73108c7992d680504d9a3aa702c8637cb300f730e22e823c8a382d021226fe0e1a3dd3ac76fa5110a93bb3ca3d4ab703efe256f2a73b5ea0e229abb10ab1a2d623b3010cc2a7be67bb66e1eaf9ba071f3e3da041c0816020427d2e178c0715ac3d4acd30c4a287ee0f233db809e2a2c6632ee733e70173403ca8f8f6ac6bb1aaeb9b8369e8ca87dd23dba9d8e079b4fc43f42cd35b642fca4e55011a7a15aa1e3ce8913d53385684d0c74d957ab8e1f7170fb9b33e94f693be63113c0f2c68ba5e2ce7b3631021224fd43619844508af0fe33d38f5b081a01fc445ba27b26ef6601e4c358b404fa4ee02d803a983229007691b7cb0c0ce370e1c482ef2fb81c7ea36218414161ee3368bdbe3c31920fa3e40722a44f1666316328e8abbc1032eb702ce03778e84f0f9f658dd2cb2792e274d888b569ef566e8e197102a1e1e98ba9eabc7300df00729403c0f1a1f0fe63cb406e2e2c753b2b5c2437bb3621dbdee478fcb191e84591d8fe9cd02db63b9cd10ae108b3e78214610740ab182eeb18bf329f3c4dd24f1a082e3a1dbb4205ef981c1b40166d44a25bd568c7945fd6af6ce4941f001077f02eac32d8db749a3ab864cab0bf6aebee7d8600cc21abe0f3ea37a78dbd21e341089405cacf604eaa400f44c1dc007ed1af0a062c7a3bf81c5fb0474a5d3be3ce8a1b8a11f68f56601f7c8840df1fcb8e31ff80f7511817b03fef351c2d9da8371353f78218cfe7082b0f1a13e1017340f649c8a98c752c74c0179823a2904780c75650578366916829ea43b20449e753de69b05cbc31ecee7e181b76631f3c4b8481ede1f12f5b038889f2d0f480dff414220ca02abb778fd70f82b64ffe2503e26e2963d54370441f903570f628866105b88be0f753dc843581be202e2b1db9585d163daf83f98206a1ff87c20fd41855c4f6b530bf18118f1c00c62f310de8815681ee38e72f11e94c6405ec5ad7bbb20ba170fc9b1d27f74b362b9f5354f8f5b337c4172b57c0d20b131d0867fe4f3637ab320f370ed6a63e0b1340a3c58507878ee6d102b7e3c65772a44e3693d98130fb17f0837a82c24eeef27c5f303cd67e62174c37b90108829583daa8d1084951079727a70ea18573d071ae00f16201ea7e30f41138459aed1c808ca8e7f193f2f1ee71753e159b2d5023105bd67e6c0fa403d44283a1e4e3a15550f0b348bcca342ee42e6d9c0a988f7b0b059e43c2a701772cf906dce43680f748170a7650fb866c1f2b097f3797ae0ad59cc3d31d7481078763df4b6ed871442b1c784cbab2aee97db0d0fc10181c803ce43b3da565a9667e348bac001fd042385e5b1dcf8ce552e981e375a3c84e70f2978cb2de2c385215685cbd1f2b613a2dd22b2792ed87452c83d0cd32c528fa04384e8f480b80762fe8253145d7ae0d03b12b028e7b1634df60b60023b43a07ad97bfeb985ee56e6dada45630f3bfadb1443b81202cc98e0c0125b5ee2c17c40911f31fa8f70a2c4e7614a8f32575b4a66cfe99a8eec32ce74002557ca3a3210faf6bf365beb225250cf601e0e972b780b41962be7e0d21baea8575dacbd7ad494a21cc60c8e9953e3fd75220d9503a3e7945944e780a92f6ae417f1b37bfd0c1f1955221184e8c77f88749a708f5a8aeccae89d95b9c2eb8e6744f81a1d9a8e593271185d2e42c8789de397102a3538c6f33e16b41cbe84448160e240fbbe8d036bf4dc717c566030590c214c10fcee5d914d1170012a9d51f3b411e2ae1e7ed6a729ee390dca342ba4a9aaa7a14b01bf44360f3d9c8050d6da5f320ce4d189d38db0b09e2349424ebb11f0014670bfa6e8d47eb1a74c2bceb2acb8adff1e70f75d96ab1fa1e8ea08edd7b0dd95a88e03444af1b35aa58c4406026b083affa05fa7c8fc9a9da02bb8ce0c702e3fb4ee15a23ce8964e6a7f5195bd53763c8b48100f335f72e9ff09a08c3170134ece422d212a9498b410918f46e155e9c8912c8a68f24e2d1cd188991caa69f3df9e9f7229162a862f7e3bd65c21fa47d7d7b21a6e735b08e414111753275098fd5f89494e20f02163b0ab81e2a1131bd44a2d3dc637537e35e4a2e3ffc05a2428dd32402eede9822607c8476c5cdc7bff23a05b03fe24d7c99cee8eafed0c1933dd8f560c78669c2c692a31622c3cd4f9548c5cd5565916396f13c14d08dcddeb5d31600a1541c2b1f17c8936048c69640171151a0a28fc7784cad2f04d7255e794fd767a0f90e3ade1b4428dcf5928d4376aada0d0a153a481125a7eca2b2f22ca1607829a008ba378e129dac44d10be352c165aed0ff17e528a6071489f4b5910dfa2429580809188cf21ae9609997de2526be78f54b9431f6ece33538a58c7f581d332f69262513d5d3fa21a5bb71224b1e3dcab0545d9c94713013a71c7ac8028443a27178f83b3005ec4393cb8581dad901f9b57c70d03d27f7dfc1576c7d5cd3238f420bec1d81cfe41f64242594924439ed2f0ba5bc0e41ecae1d99aea454f0801da82477b1420ea9dbb9238b820e50a048e00ad9fbc29e26b5a3cfa8d8ec871e84260446db2b999cc3219fcfc86f0b0c0e93b9eaafefe75fb8d40fd7c990f09762df1a2be369be08bc0c90710304f87ec367b35127c16ea4094b78e10e54f8d7cf1eea287e3e64fd90a68e1a91af66c681acec05f0186cb325821552f19beb5652014ee277c539ab592f1642c17fbf02054585db2804fbd262a5483c5a9d2276ef4fe1990ff785dc4712a13821ea9d6419d72dc576279f3c6aa16dae5b3cd211c5146c4f1161031408c9c2bacba5a49bd2065106e837277a06623e866e17028d81b23b0585c7cbf0728c4226462e23fb4166dc421f3f4734b735ea00467adf44dfabe191cd0447a5754421e510d221203ea6b0e79d5f39a8ae1d851407c47fa09065cf59c7d446ed8fa49559f216ef2e600a3661a0e3e330c3e086a5f598056b7481b9d310f530324199d8707e19436616b00893021b50cdc80694103717e50a731d62602cfa9dc26bd016113f8c03c33555f90d322b3d8ce881ff46bfeeadcdeabce3c4020268ced7c0933816729dd66dc232497f4cb8ed0069bf7fcc9f9be7fcc8e069f6ee2c207a2ea0b4b79229af5aaa4b42e5015ee9024e2df142c04144e407dd0a73ca68c80966410bd94d77798338834d45045902fe282e80cec78b376cc2d1672430f7f370245491a171ba12ecb83adb1f4328cc3e6477ebb00d04c848ad105be62adcb5beb1a23846a828d6b2e6c927e4d7274bf88409643d801ad0c674b1e75b39449a361b1cb200221f3d82d74206764f421d05b35f13ad3daea5210f150d0bd893f864b85a4fa3667d830cc56c3056132ef55c2cc2a2ec8ef6109792208a17f928d0f8eef96132b7281a8add9ae1e97885a5682e7128373b86ce584489808e738f357b3b0780a917ba89af76e19e8bc0f1d35b52bcabbd963166dedad2a520afb7ab8cc32e88a4e156bd4e886354d3463ad9db35c23edb3aed8d70eea6c94a20dfdfa455d2f34219ee49ebee88658f9206137cd5d355b45ada842924868085011a0c9ac95d5e00ea3e33d8a6d42a0b5aca5bee8c43c0d9cb9bf407248c98b20c5235464e3910d75a48486c8a5909c416d20a77a7159af20be7569de6819abf6e9f81abf4cf4b94198398b5fcc5201492cb2c4e5b7beda7d6b70a9f920d3503d05763106c1a98f4af801d976993cf74d6a220f76224215884d083a592f2e9095ac330a2511b40d25c400babd1f040771b7101f9961926e20d0932a2ef86818ad4d408a8b040f368c02550b0beec27f1b7d140c6a64e30ab9cbd896a7bdfda80dfea4c81c96aa1b1fcbb130c9644ab40d51009a87153683e08abb9049a6bd7f055d4cd4b1c003539664ac68ca1faa396afbb6dbc80ae4c921826a167b94d7b99420e9e3e4ea7d3d5682bb2e5daa2b6188522292ee40e5d94f938493426c3eabe2531e3d26dd17c234363016988e703746a96120b9d8bbcbab4652e4afcda56e7e15b4588f2029ed83b44a24d2703d02206456bf859563044044f1e78190762d681bd3717fb4b5b86a512afaf1bef1ac607f8c9b7b01088fe8fe91ab083da6c5d9c7a716b9ae31c831a055313f35bdbd61df1e327bdb1d6a69ab3be7914ab4faa46f8ad563a4d99030de430f6f429258244ed3cdeae15157577621b586163110eb02b5574ff3a728e9719527d9bb92bf70a9b6aac6f793f201d263166a99682b9ce312559360abb49272f8c0fc17fd0ce063b2fc5c07dd2448903b7dacf784069785ea4673ed6c806b2d0308b8130892943748fc3241a620acea31d05c05f1ca77f05b05c6dded530aec54a12856393b14e8b36206947772ea412ed2fb40ff06ec7a3b3e66c36868fc5d0d47da604b61e0abbb4134680a989042b3825aed0ab179243a1e02e500fa7b1230730a81a5dca50c7e1f43a0c839b3f0312f462c741ccf8dd6b6aa1871619948a2efd3bf2170574af0a5a1023bbfcf128712a8cc2446745ac76d0a51a9cebb4644c6ff6fdabfb8e8674c8553d20ed48cf906f17190d14a0cc9011dea0414a1d5d97cc7b829f441694c9881de47969bc8cd55f11c9530cc127bef75d1c1c4f0c212b25d8b0a2d25ff9ef1a8bc99b02258001d309e96f609547aae9eb9aea7d66c9fed926a1db1f54810267901fd8d0842cf65500a4c308038ff42afc6e61e368eb44cf9785474c77aae1dceb08b1d9704c5224effb85568a41a24602e637bd4300d4b0dc38bb4f2ab7b82671e03e297a015c9e3e8a99f6c15595003bab193a835651b28a479a3bfedc6fe76728322274f11f1fba2a44883302af587a0fed3cf67a039ef998fcba4192a92c1427eccaa4223d670ecac4f4d8138e3aad52a16b1ec526621303b224e0fc81c14bb5b6dd0033f9f8844f7607c1ec6d654354ef604d52040bd1e66dca302231e1a4a8ba2f8a3f8706d653e3336cae37bb15f7d7e1bc3269f392ac09f859d432c4f7ca0dbfba0cb1cc7583f74089d021ae93812e01135cb58daf6c4f7e165868d4e285b2a265175051878b0c4ba168d8dcc19b8986ba346a4dc566211e832fc2892b227faf955e46fc1711faf70fcf9c2345e7ca22df0fa7a95b5b314f07ecd618d3f4bc38e195d2257c0b7c00af2ea78e6a4f99e532c11f9bce3c6ebce68ec60b99e72c70efbe087d97135ecf5a309a915e5ee12908b7182f8cddc92c48358025f8a80ddd27587a23b8e85eda6c09f3b548fa1ab35029842252e6482c10950beca836591af7739a217e137d7d3dbef6c18cd41197a261132f0650c48046ffdf18531797fd82a8444f899f04de2dcb95aed9c1f72bda9c4ba7f93c9fe8a4f52464c75fad5d029fa1b955793bf45a0a282f812726804e7529f2cea109afe5c4dd71efa6d9a4e6c75d7d3a597125f79dec530b0dfa53617f6d480e6b49f6df051d89a8a026d3e8c1b31e6367c87ee8ded494cdc56bddfb9f493b47f1bd472f8ad9a297a891bb8e54390ada64768845c17eb1f8918480a5f6cbe23dfa63c8faa491fec967cb708a8bb5600601c362563ff5169ceefb9a141ff5cf6b758504054fb0d599f80608d8b572f8f366950d3f954574b2607e0c8705cc53a5f2d684c3cec6ad0fd91075f745cbdd1e4d039fdb37ced06d8628c9fe820d3a5db08b6d904b4008f091d7e21c0305455edbbf45713f15ac93d5885a6989b55d105a9955aea4cea5bdfb58fbdba99574344b5e4bd708313b369753c84f4f7b795d9fb740a83dfb63aa56968b38fc54617cb74cd97129b11541635c07d6aaa2b40c9316e31449cdb86946dcfc64d0246d156c6e2cbe333d7920c3d0bd028f53821b4a04cb8a999484ca0081ee070123174b09ab04cb24543e1debd7ba1c1036de4972fd1a3a80351e56bf0d07c157530f00195c1555e8f71d988a54831e223f988d6c99da0fafe3511ed4847860dbeee1ce88640d5292187bff05fb592152c864bce893c454296e8466c575a85a725b87a5f1c7539f598a8eacf3c9693d28955ffcf50611873bbd24c7fe35979c86900dfd71329f167505efc38e8e0ef818412721583d59782301f36362029656d68534d4b1961dd25610a3c8338dee31b163b65b6fbc0b435f1dbed0289422cd1b8f06409df03d9ecc19150a224f8f90ba32536c073dd2bfc0c60897d9a2c020f0d4b003329d14106868ec6156cd820329a4b7d12ea45d49bc86e70acfd475c51ca8803913efd08f771dfd2c5b2ee10c725511d2fd25336651a53040efed31172ebd2a067a92ddfc9641486f91de77e3a90f6ff202e975c42e4ddccbc9763e1411d980a311dfe2e1b9114608f006a0ccbcf949584211b6666c19838e0c8f645c7882b2f050b9623f9fd8e37f5dbbe9a7edab58cbdf615d6aaeaa212837ea171a95189fa3ee9d69a5cb6c02441b18968204f30f28a9fd75b51a934600938977cbc4b583885641e54d891e7484863772246d94febe22589ebc204ae10b452f68d4534518288ded5f4edae8ab54b65878bc408d021c89e65cb3729c151b432fec9338c59bd129c359b4cd9adc9c3901d70dbfe8d578333d2fbdb0d20eefc1075c3503f75eb5b52cf22bce4a39587fea0c9bb52e8853ee1de60d6615593d6275adf804834ca00cf57b7c0eb6d32e1a39c659606cf45c5ab7c547eaefc9c0b826e3700a614bb393f47141d102238d9feb071ebf6ef9809bbd48d3d6f9635a30ea06d8a8bd399785f212bddc1fc52bda3afdc11c50ababf90a6171ccd6e202b334181ef1260b0f22499e03580078f63c388b45c20564d1f2fde7c5ae30c1fb2692c63517cb23420bb4c145b7cbd89eb175f30910be31343a2bc6d3e04e37c890483c77a07b43556b0b3a4c5f7ce607ae431fbc123e7031f0e54f53bb580f1e3c0340735af1547e0ba73254396ed03d9ebe92bc68ec300b417ccf32dea983bb313d16be65e34205032b9e7d4da6e580bff49d063658a0205856159e52297c4d6cc3d41d3f5e610bd32a9661c6996a315b6edaf48e4a304a621fb718c25af9ca321287d353a1b74c5ea167bec2cbbd0e82b458fdf6dc52ebd755abc4bbae65578206cd807c5a7c9456889cb9df7750040d6ed8319fe81cab9ab5ba5d3b18c94c4dbf45881980bdd9b36146a961333f444ff16def30073ebbe2422397b5859c63508fb77cb395e75d980848c489ae1d64b6e96ca722802591a121ac153026a2c2b40e7b73a845b9faed3a99e09a787145f78f9c347a54a5799fb16966980179c6d036b88dd06a110747610938df9cb15718d97f2ad6f5245019f2aea649c7d1d5c7681fdaff09077198c4304d4a24a58feb62d89cf6d4f79145ccca206ea76e72ec1aa63420eedfb9950c1a3e729420ed42bcc3e01b1b856f46a3a16f28e0a73e82ca8ef62283ff4f6207d6b830264f70081915381cb63c784e794a825823e0e94260b194588e304377b6def672e6d74b1836e5a81adb206572279b8749ff0598ba9f69f84064669a7c569fe340bf91def17a3257817cdbe1042ab9424471d01b75a207ab39e18f31c2d17ac4b840a113875397ec1d2b7798e0e52428f21543bf8ac29d78aeb251dd89002d5c66d868e2038eef9d41d03629d6be33812e2d0c651836b2226a9c0e7ec1fa211764cc30540f88850277c5511e3921d9bc556477e95c58bb76ab1b483db38f0dd4ee4b11defdec7fe538962ba95113c05d09541987df907d1869c16f8d3a1c6057674f174c3ddc7c7378a8864b9c5ecfb99ec8aadae183c9f69ee129672bf9124a6f2a7fd80be1f9910490af5ac05d197e706f3861a5ceff1025d573e28d87c1999fb265b963b348e70ef247e1953cbf045506c8c7408f7550943358e1b1b78907ad428e17229f23b89b3603f3ac2c86d0c74b02df6c18873655bc2f95b9012287ca08161c601e7584f773b74b4631c9bed3636b655f82fff20e4de1d9569a9730c87b3fbd23ff18b87c41a6dccc4141fd496a1a8679d4b247e0d1b4e6b9526eb20a503713465f96d29f2eb9f6ed7ce046c05edb27be3882bca1c9828aa5c02bdff02780801c4ee39d4d698e18f6aa09f5f327602a17ed5ed06812475542efa2b29e2786063d7193f37ffcd39d05d13d4a1332fe1878f7a7f334784b9e70afdd6b98806225d2a7e5eb08ffe3d761672bf6d7d86fd5b89cf652b7cc1c5c67e4a332b6da9369e6d68ea526b5d6756593050bc9f1c10777dbe79dc048a9efb0c5f8c607e014842a9d3dd067c0068c651d594a3b6211f49b250a265b9492f1e34732d9d87580e7bb20417b517c86a075213a312d4a71029b255f72447fb6b1866a19bc278ad525f0991ac7034cbc5d86690cc3d931cf370f093a187409799d85cb06fa7b03ad6d71c6a7324615d9fd134783544c624f2045dfd19a4d287907c08dd72fe958fa50f3ce37e6eec3375ae0ee5e985ef15268808857a2b6e991732ef98f6b9b3cdb7a3e57f8aa07ae71c6ffdb6f6297279506bc71e4c2434d1ccc5dbaa096fc96d780efcaacd2c9970a99b1cebb6d07a8d19e776c32589f0f390b20fa249320b310a42b37fda82f26aed5e8c852ce3c6812f7e3031efb9a7f3b55e6487096caa1001e091d033862c5f59949471fb7863128d266728eadeb00d21ab2943ed65d0924fe9bed4aac9276039a5b4fa2d331c51c943460940cfd8887368dd36c4106748101ec2771ac47d6ddf0fd42c09a6212904c3a4f3bdd24c8c5369a340e8230c6dff21c9b7bb8a3ae3781ecda7fdb150c4dd60fc2fc8a7fdb162b2fd654daae46fe9a37364aeabcf064a9cbd0c2207a2aa3936b5a83ea31d17c0d58b5d4fdf2c90949d37febe66c6b5dd14356a6fc8325e4418ee6be17c3c54842e8ae3737247bf35debfb03da16d748303b9484faca395a6ba11fdb47d4445eea2e6a0346a1dcf761c4edb0eecd4b6b0a982bb12ed4e592906312f1f7aa211561a8e0189b5d8866954ceb31db74c391162fb8e7ab4e65256e2f503591d70d423e37fcb6a4ff5fd15f532c156d72c0a1ee11ddb20f2382a762e8a9ed3932456de9df35cbd1f953ee3fb0fbe010165158661751d29e4d653b3110399a8ca03eaafa441030ae21f875fe2c731a747be546e6a059c7c87f64563afc3f98c897098ced67e9cad036e167c7f41aade1469a15d3cc047454e1d31f12e6e275c113a2ad8c2fed9505839c7da1781dca4d6d180eec1c9c3be3740d462a4b87ced13a61250750e2eba8addde2e64cc73e343777812f04902f886c373169f51149154e50863c9ca634746723fc8c7037b87aed78e669af242ea569c6a0bdc00d43bfc208f6b2d5bee0f2f45699107768aec7d22e4f4094407f745b93e97781fee3f1067487f1fbd783f18b60a721f08fe4097be6cce2de41c3a9145c1372eaf55480f2462f5803ab34d2cd1f5ecacad36dbf9af94cc75ee103abaf9c4e197e5e67169feb2a35fe8dfff97eedc88947419c83d70a8b8c6661481467413a7cb195e5af69f77fa6d27fc53d95f530ad5578e2a9c2deb32e87943d7b4c95ecd01afb7ad0afd73532f9965053d2a77df0aa3435120634336d51dca6c8d2735a413ec6886935a38ad1d2ee097a6bc6e0e333def699ba3b90baef2c9ad71ac92b93c1047d0ffabc7a55f856bca93f3ebabbbd21107b7149d48114a572456a2c55d68d5995ad55b2307720443712ebb502425d41bfddd742b359210d5c73eca955be3ff31f01ce8f54c456d8483b360510f5fe323f393becad2b39bce57a59160483347d2a4d6bc93b5ff018cabd2cc1322f4ef7bd2fc07f33f171663dd661304e1e4243a8f7a0e0b24b14390f4ea2c077685c6b9f954d45fd26ac4b0269276bfed04cbb86ca7ad290ebc97e208cbb4bcb3978cb97f7bbe74d1a615250a8b065d8bcd4aacde4e2b96e7a1dc3e3afbc6457894dad26c08076aa914f0ba01a6f61069a78a35a3f22c5e0a626211dab76019d512a47b5a06a17745de35e0298aaa520a2152bdf54175df99f1a97ce70ceb313ac54d6286169dbc7901127c456b5df91641c21a390650e19a5e4a9c49e78d07c8fd79ef0a3e6266060e498c7796016ccc1e6891c103b44cf6649fd1d0a8d80377e3751a55274d22c9d4590f708ca9938b015c0756b19fc7b55aaafe47f2f8c3fce9b591956202dd722dca77ff29fac3152cd857484fa2601ab51db913e397d529c215bc02f38808019ec3168d4115b7f049b9cc042b85687965e7121e6bc87184cbab6a41b73f227736698c6fbfd7b2a0e556820b3af3938c38a3fb0ae59515309b4c91b966712e540a43e68aaadf3c17028b752c2fa59a1eef5d5a09516dce5e8fc8923fc9398f7b7cf96443920295b633bf6b5584fa88ebf98ec4bd066ff1e220ccac8f56338c1c7dce599c2c7a14d6d52bc342d17ecd01d2a3af9736f4fa7d96444f038bd638e230f421c8662df253c827c92e1532e413d3ea1913e153f2e476dc3ce09e52abc3f2d47a5387ac5b774a882f87d784d822d5c74d212ed62eee95d077d14c3f8134b41698a9b34851ee75d2bd2560fd09d6213f58e40e7ef9a3dd6cd004c863b3c88e366305f6943482c4bf7b1608410e535c9a36aba1ac7debcf626c107302c4b99bf112650e9767603052d721a619a3c159305c0f1285b7885dafef140cb1ce773e21d115bfeb09866cd361d76ffe86addc517cb5a09d39652b0e8095f1e2db6d4db3fc19a5274334de7679198e3f74032e81fafbd2cf4cc8c2c8743634e4128260a8598773b0a87bf3032c4911e259464cb27e363355a4b720081925c38faed0515dcad10e6803c6f0fb2e1c7e12d6ccdac261b4f61b6ca0447f018aca8145809e51ca84be86a3729c509a1aacc61306f6107e3e8b037b8ca2751e4ac2b3535d150ad093ce4e3b4597a3138e2a3a677cf67f9be48de44cabc8a73295851a22d8b1db987b943e14c3d3c065c7097f9458fb3d2e19357bd0b3c6f5b888bc9774d8ba2fe3510e1725c70925ad1d70cf8544a9c6bfe2240a1ca24a5a2507672d31b6633d473bc20b380600fd355065d7a2847483e5c719ecd76e4592812745517808147dd9c2a87ab1a9108255d1c2e58a34e10b0fd85cc0e43a88c088d95a10f52a46601d09464cd58fd7b0c64972a27fedfd696066a2901c51c4493bd2050ec0e668a49c445c9a66051b6964ca3e7f2db35741dc4880cd3f995b1eea5d4ebc76a4af6aecc138d92d48587a69e8026cb2c0fe66ecb37352f35792d2a622db150d6f5bcc6308b05dd0e4a3b7972d05020cb570f24200a9f21d15970740bacc67119e2b77ad02094511c28616d5837bb96bb5005d0732f769ce59afbc511d7d99f38bec675ee1acb8ef60b32e593ffcdeb7268bf4cbaeeb2e533c283440bd3569297836b4f9d67ed064a37b9542f1474d7cb3445ad47580fae772893607eb29d64b8c6fcde5b543d0ea1b0aa72093cdede472832ae87a4d7717689e7df144906cc004f4ad8d6871c1b7b6e36e2d83eae122c330d3329035642d4895ce99c7820160f3e41932f0c8e649944a3563471e169bc7527491bc86193ff81cdf4375d310eeb2d6b4b777b98f8a4b068e7218024fee652d9c9d974d39b4367f819d990d9ec09ff1038d31bbb4e4463f0a44ea8d5b8974cbbb805998a2f94383e054d213c12f4db8eb9fc82657659123fce94cb7fa3c6772abe0ad55c9cef2ce36bb06c2c40a0875d716713deb7122c2ecf6c35d0244537c32fcebbb9cb1a6c0ab3acb4bec9a76c20bf7140f924e8ecaf337c4623e4d2cfdbb669c2972a3f0b7f8aef52152c053e235bcc0013ff671e5f5ff328d1a6d383029006bb00e1c5c57dd80d515c5e5351434746bdfef258e3fac55a1afdaa098fa9b469cf470e24eb6f8d29ca2ee3ddcaac5bb397309d748036853d1ff50e0138dec27a930b7360a3d452c4f03aa7b728058304c5a4a071711631ab52662bccb7ad70acaa50c92f2a50430bc2699cb9bd5ae999f297e27f1be956c2f8e2ab63eea22181e3e158747dea1c635755764cd95960bb1d3fac69ad8879f300f43fdd2dade7b6f29654a524a19b20881077b07fdb1f38704e6fa49fa40e4cf2cf6ab951f85342430fd08c43ea604ee8ffd32dac0bebf312fc84f7eeca517665f28e31da1be8d3288fd6ecb2ad484c9f6af961cf37d3639831ca560e0f24a326f1f5aebd2cac6ee5fedb7fad6dbacb52e6b1fccf7377bb5cc36c5a890ce12f4b79f4b7eef4202b3bdf602916fff7e28df75dfbf2728df7eaefbdd095afb6df4e38757c96a181238c84f96b148c6af562e4cc9d685a61c73cc5819fbec35a24923a44f947dd82d1f635c0e29bf1676c9dfbe5d52b6d47c7eb290cef7953afbd66541ddf685f2b9b751dac942b8ec5dfedbe705b19f8b1b21fbb0cfe58fb9631f66dfaf615efdf6b2daedb9faedbbfae3d77e30639f615f2c92616757bbfa430273134d3072d242d162b41144daf9c2f92ed77e342229296172943f3f977f4f3469d0100459bebbb42e24304720f233b094a7fc5c4860962f3fffc2fe8200913fe5cf8f68522552b4641b394a45a923058315189a3211510af2eb4f17fd9094fae6a81f97c0324757fdfe76d58fefaa0f66ff0f09cc4e148be2f3b03de6b427f7db5ab31b23f7ae4ccbb0cd5ea4fa91dbb42c04a26915054ed6fed6c9ad032b02cfffa4d4e1c2b2b731c60f2247b89f1049391efdf11322b39d1cfd7450195dd8db7f4d72f473611f1298eddf1df5239aa08c51931309285c3210fa6dc3bfbe7b417eb2f4c23ab911e8d3ef39bfeb5276d1289426b996b027fbcb3a997ec3c9f33136997ebf540b64b49ffb5af8960b0173059139be90cef283fc64f969f61322fde52744e6f8fd84fe29ecc03903f3b1b7af4d4bbdd05f49e6c69e621f100c04397a21f6b17b07f6f3b5f64299fb72417e7206622ce24179ccc7da132285c8dcf773edb04f5f49e6fa3590f94a327b109983c83c33d9337cbfb5d27fa55ae092efd77e193bd6185fee4202f38c09d2efbce5f01503b3c24164269a20fd07bbc7af4ce7107dd944997e8cb0e9635c8eea91878c9bf7e476ccafc3cd0315b0bc5c8e5ec0521ebadf7fdfb91d3588ccf6ed174e212328c9dc55158916278d2012abc261bffc3a4bb5d04488ccf4bb0ed07e6291fc9f6823fe0b2bdca76816b2706a0aa24d9b1715350e21f5a4082916a49eccc1dcd0c98c38f63d6fdc20012587208e1c0d0b55578a052b23d8d48b1ca59e483d2183f9e0162842c74d0c4d554cd1c41195caf48991dce116cd51ea09d3c4a24915132c1f8a8ce0e614e97fa1771f5c60c00c1a288488f29282a7233f33a6cd28b961c3b2196101c8c99391ee7692c4499a6e62076b628593344ea8c83e394a39b19272e745c09c528709b461c1ce961f9690c28c991ed0a0799de9260d21327206965a4548ad2047aa490f6646861f2e4fcc9ca953e68a16288a1c7999254a32a9252d34b9b2522be869828d915a0244fec9516a89188c0c0f9898172f2530312f2ad5e444d672946a52220a336384d51378ee3ca96192b1d24f2cd41ca59aa85a4a29a594524ad98f630ad18a5d2b864172b395a3f2da89ddfb4550be8c5c0833538fe648811eb00239394a35a5c95a46ffc3b81068a6af65514eda3ef4bf9a070383e7471adb9573d298f4a3d26e96b1ef74da218d3286f2bbf507a74d69532ad5b425532a4794524a293582bd0478705fc1963451690167394a35b1905b4ac955ce729452f28409fef532f2194637bad70c29256e32cd514a499b7cc3f890c3970f3cd8a72ff6cb965be68a0c542c104a9ca450a244852c7a98022b52e7e21027cb117982b850d43499b152e4604350c39593a5aa8afd014a9215ee144998965401270a3b022690c0b92abc99e204189233f648981c6eb8754a00830c760629b709244c6e0d488a5819acb0b273a7892594b84d86b04cd81481e6ae20c6668183dda2e5122102ecc90b728e38b958478e582bf4d82bf0604d4e5ca6aaaa226c560a2c961e6e123231783981096e1123b0384cb15e8cb0b084912497092cae1057d80a746c9515582e465c2653547eb04d94e1010cc684cb3d024b1231d81b8ab4104491a6db258b0e1516092892c811011263dcdc2780b04444d91774b836d8f00309ac15a72857052a2cb1a2820a9607ac5b458aa939764d122b10e236ad712365b5ec70a1a0b298218610b8808226f7881493915b822bdedc7962654ba0024b4584a50205174d9a9bc498a72e4ed0e094f5648fc882e172c97a72a9b2905827f6ec90a7c8133b2ce102d5fdd2c6b6f1c10ec1c3942f36055b4c90c5952b9505958b250b27ac49164af46461ab98c2481d3671aed5116782b050a8b164cc189103096ab82f64598345952e5840d182c50a73b060ba46aa1083b1289c608c093c1883b307636f2cd49a28686c93317abc6049b6a8c172a3f65499b227ca8db387c985628f91337a6c0b79ac0b74b0e2d82790b860de5c5963078d11632c09bc5c24b664c172e1e8a972f7e88962023d4cace83102464f993c4cd0b13dc4b12c20a1c41b356bdea04933c686f162a3d8729560b9575754997345947bc3154cacd41546a8e8b933e4b15174ccc4b14a90b039bcd161cd6501cda562cc0d81172cb68800cb94155560b022ca1d6305136bc60a2356083df64a9e3a744e10e7224162046f745873a5a0b150c60ce1a5862d3460218355850d561429584c6c142c2362f414c9b3023a9892385b90b82978e3c39a2ad0d81963dd78b1366cb95eb0e4a9124494364ce25461c45eedb177a6b874a2b84a348145954d638475e2063bb226877f69a0224d0e5fafd7192ac834bd627e4571b0478b930bc6c95ef550afa692f815114dfa6a054de855144dae982289d3142f646bf000c164c323c4120d8f122b64160dbe56e0105f81c338d53c6a98f89b16faeb9ce03c7b56b842d2e4aa0524779e68536a122a323c40e01162c3a304a5b41dcf159e26ec566badf63a6547b20dc3302cd3f268c9f3847118a04d7a795a6c32cf9b9f9f9f1f8cf3d4c92327cf1e24ad56abf5e2c5d594ab16362dc338ad083c5994e0d9d2240b3c3ac8b992b3042381339183cf298325cb997026be14a9599706bbc28d224bf30163c267ec133117883b5eb21ccfdca1e14e95a965c1b325164505e09192c30d4f933d39bc57399eb923e7cc1d387782c03e211aa7c50341adec42ef31cd191c11f47f39b7691976639aec5edd566bbd3f2a9caa51762cd336ee861acc7d1877dd3f08be5e46463da84c79df006a4a73a56f64a7aec1dde7766f75f7eeae39d09a83df0d1be5f946797e5d1331ee9a468ded938cdce0c8be10d7cd2b610e51af9223a5db6f238ba5b5be043712ce1b34699284ec2feb67d8fd91734cafb58db29d3bab97f7bf491b98bb5d2fc6a13be4d6cd8ed63673ccad73b5725b866df7c0d9fe4b7b652fec8757f75763b39bd06ac7ab2c9f29cb194a35f757adbeac5d3fec059191959535f1f5af3ffaaf19b386cfd321aa548b28610ed17f5a0387fd7cbff6ba09d6ef87121c39efe350ffe6c5d8a3ded7a2b2282caa6a750b7bc7e7ce31df6b5656d61552ed60d36ea94ea8fc7e2aa97c295b4af9c5392fdb9b7c8c79ad01d7aa65b1bae63b3e57fbb5b5b5fefceadf956bc9ed23702ade42eef715620d4c879aa28dfafd1941ad69caa11be55cbf4c4d2c0ae351610604942c73a6cc75a8cc4ecff084a4b13aad4778ec1bd968b8e5d5daf2c3b8eb1a77ad0ef3fa7ef5fbc5d7ece6312c6d6e47fd227737487271ab9313290eb13919adbb629996f432d3695dd661dded9eee86bba19e2822fa9d494162b07f5f8c5f5c5eaf202120a064099a92737df35bad5273a91d8803d8607bd7eadd995eb1ef34aa23583f563b69a451c4f62994a7d0fca2db0b7203e5c66a0d2c9426c3ae0c1d9eeb67148be86b8025f64d123a41c8b36c76383055a1a6a850158a4dbd2128fb57a35c4b6a548daa50f2694a4b85daecb44fef6e2aa750a8bb81004a4e4921a72e1b9753536c72fdb00566ff64d504e96f7364d5ddb09c6a2aa250c9294a8536e51eb2146689ccd297dc5fac53bf85727c2cea97de1784667d8d511f10602877fbbc176be037ea3e83bb49b046d567d36464ffec0b6564ec1b1206cb27a13b1b6bffc8ed5899d2343f4ad02c91e6c9f280b9edfd9fd6f0a9d7c8cd8c081a75f55e119c41c4c77b0eecd7e6e138e4af7938f3302f468c51c04646b9bfaeb34b5099ec6753ab6470fdaedfc51bcebe07418b69c0f2c3a826aa897d9366b8a04ac10a4e98c1d44c3acaae76fe06bb7774764622306a23afb55b88671a1c487bcfc0c2cda33fa5e95e4b579a48f20b42b3e078d507a664f92f050ee594906bc03c8a74e89b49d32af74fef7ed704ea34ad50b0618995eb875d9e4e0da047f6a3afa98915ede47062dd0d4fab598709d4b4f2aaf6924175c08e3bd1c10de54e21100eb9bfa192dce987a88286caa13f6590fdc3a606e0c69f1a871cfa53eeeb4ef287268cb853cea07c883de3635a837bf7bf5fa8e4461cc9de080a4c4c4c4c473eaf699a578ffca88f34ba691e3d9a475add344f1e71dbfd987f249e81855d483f40fc71e89f6b07cef2b1667d702ca2afc9cdbf06e27fbffd43eaec5f3da0407228fb03f2b97664ffbaf37625bf92e9edf4a6ce8e658c89606d224d6d56cf335a14129a207d70d2a060f8edf3fda24450f045372df3f1301da2336c9003961f5e14b0cfbf29d906bf7c14e8b5b57a765e087cbdb8afec4202e242f2af5fbf10c8d61fce665361a9c724305b8b06dbccfb38e4efd8ad60f6215e3d5b7fe93747ce4f00a9b4de2218dcdf17d7cf82e5874f635f7aa5be70d240541695fbbf0adc8f834e2f298b9a21501625e34b0c0f54c099995c3f04caf427a7e395fdcba66211fda021b07c1c34cca632fdcea2e2126892dc2c2abf708a027537902814caddddf21b4b3a44bbb91cf3c338fb30a6c97d63065118d4ea846ae0a043f4c3edfa7c48733b0814901d5c195078ab11270524083176609f7e471f7f21fef97cbe70e630c2b9dc175e8cb58fca26cbe590d9b36c924d2578264cb066ff7ec422fa187cc1f237eba520efdfad4635b95f72483e56c2dc896a724f5042d92d4a324051b1ca910a558eff94e3fb546e2919a272bf8d3684b4e572b862f49064964a7db911e4c7b7dc08f60b3d7af5e9ad9b679bf4427f97f48f55c9da11c22597ed1cde2e976c97ecbc791cc7433e752ab2ecb12c7b4c8a942836510a9165d4c5ae75ecb3b71c12fdec2bb703fbb2cf85fda663663c4139f3b42fb91dd7de2577935193c67d99464db635dbcf031570bc9ef40662ffeeb05fbb328e99c3ceec7ec4ff56b93ad244df66c9f6ef12fb97be5b9192fdab8b8a55ace50273d1a2f18b4db29934688e30381d322adbaff3bd7d5fb6000272df1f8843e276dcaf2778ffde98b34fc7cc7182dacc38a8d5b64ee87543041f3f92861c71b2a265d2f83269ccdcaf59e0dc7664c36eb7c5f940eedbfa9b643369704852caca97cbedb8b8b5a37efdd1d93252f791513f53347fa72a4c394ac590850a56fe4935249b95957595bd68a1d6f16b1d5a9c5168cef9d7b7cbf1f0c7fe6a3b341fee351f7c5b139ce187af792efbc5095a6d6a5b1099b5cfe77d7ce47dce0bc19cbda671a1f30092615253ea64ee43dffcb5d7ac177b29db2ff4a7dc08a1cb7e7b739fcb02c9b0f76f577f7d211ed967df7e9fa78c396255d89d680aab33a36bbe957a012b47a917a46401e428e58255bedb9efc394ac100276bbdb54fcffa332066c7ecc718d85f8ec750ae9be442983b865c48a0ccae1d33cf177281a51c73f3a83fbf70ee703d98fd8b6cb4385f7efeedd9c8e5684ab1eab6524ec7ac2f65c8e998efb28ff1a85ffdb1ef19a49f2a332ac833b9bfbbb4cdfa6462699f4b3079c5326d9b4166d332ec8a500235ad26f665a3750cf10d54958aae40a9144335d9f4fd9bd193ce395a767db80d3b537d5edceb0ae55ba713e9aea2aa7a9d2ec54e63396555cfee57ee9e5ffbb196f432a361158a8fa01005ac7defae65a2268724ebd7b1c897724c416f755ab51afc6ed84d557577f75a6b9d23a03d5c2cd336231d36dc755dd7753d66989aba1b36726a015bac6a9b731c56a9bbfdf68e92b1a55f3df0bdb39e898a6d42d7e51befc51d6f5f8cc14f0204635f6a85bcd85e2cab75c35dd7753306143c12b5567797d46badd475907de78c7aec547777f75a6bbd17e3aefb07411c5aa2bca913b1facd2cf68d712593b9db8bd92cfbb06b9da6ba8ed16ef45a6badd473f00c886c8c166bb595ced8d47a75afb556fbc5bdb6dbbbe4156dd4770777f0bc0802207bcdf5fb58e4fd3fbe5b09bd97462aabfc6299f7ecd9b3b1110c466d14fbb65012afd5dddd5a6b8974ed1384a86ed8650c3f88e623e84244b4acb18b310ad82725136badf47aadb5de08fac188cedd2eb6b7a3ba1763b006257d6f7577ea1fb9103008132b06619ee8396787b1db5627f45814789b52be9aa63ab04ac7be58d2f49de2dd699e6aadee3ea17a4aa982d675541bee2e7e7579d5971a4d66d9f3fba32ea4a66a3aca845cbb2ed7d851fd11b16f7717ac03bd2252bfd486bbe1f844e4823b3a44a7a72465d7961c3c42ecfb3bbcd0b535c3ea77336c7e999a7a21f03617dcb346d206e648923ff2e8813fb681dcd103f740bdde11193df05bdd566bddabc3d1be3541da94cb516badd5c60e6ad7ccb3ea6d39daa9e35627dbc818630d2fad0dfed7ebf58a7de514f7c936576033faaab5d638e4debc436e23f14a6164ffaa13004660a7a9eead6141f4c6c1825883cec7c2e6faa52073f8b16fd339e7a9babbbbbbd75aebbce285fa7037dc4ad45a659d357aadb556ea598c62df24ee9473592d02bb9d79f2e8f58280cc3ae23e02c421ff2004ef128007f62ae042aa9dfea5bacb2adbebf42b75cba54a8dc31d72ad7bbd5254510f3ddaa8565be264fbe18b21446211fd9f2811cb7318b1366c85d59901072b5985037d22061911455f5300a534ea540a707f5ffc3edf3df87a9752e453eeee3855a37c1213ab6416ef5baf70dcc9aa2064550e25a592589762c522fada172c9f52d1482fc5c2aa02024a1659953d2a86a8bead32d76e015b54ea627aab33f1bbe188a77a9d26f0d8774a3997982a21fb7727055ddb5dbb2031f7628c810a3c688a6659aed3361f2fd221ecdaaf443cc657c6beaf3ba91576eed56efbe6f5a04354f31eafa91e5353537d2f363b091294720fc97d9340796b74fd0deed075d706f510debb61b0bbd8b958a6b9fbf7c518638cc34b5454ecdb4426d02eb617cb76c061252aea6eb8c1f8e489fac558a66d9c52f5a1ebbaaeebba8e0419a8a8ee869faeee0ba397da0aa2a9b55afbc3da21d756b7eeb5da7a44f528a9727728d5c8289fee24973855adba68e97cbef0725d47353087dd2b8b8e99efd7690610c453776bc9217d9256fd45cf9a2bad9cc945d04051770bb5296d2a4b2943b7ea80940e4cc9b2034e59034c5963cafed30b93dc2af7cbe8148be447ae017d14e990b4ca52ca2cdc9f75a92d74acaa5c3f74ac3eb29f467505961f6a54474ba146956975abec502f14c95edd2a0345390ab4f8011e932b9a1c7639dac0d4406d9d91d1eb05821fbbaeeb2177fd8de321b91d314a666d46397dc2a5dcd12bd8b53dd7d003b9e5fc3ace16753777293ec59fb29c69b2f43413f4a926fb4bf7efc6ac9e69a69a59e37e7fdd1410b3cab9cc21fab99627dc13742dae254da6b4ebfc63d80fad9d6c0a96924db1d9944cb3e4d0b54cd1244da64ce58e2ab23d16a6977a111168d16badb5d65adddde90b318afeb1536df818fc26e2e16eaedd9b791bf4b877eafefdf0e69003086c2081eccd087ebe5f583b90db659c3ef793b1c8678db1c87f89c6be44165cb9b28128f75761b876eef6859436c9d42977966fb3fc9a727f3f1dfc622af717ceaf49142af7d70b4788dc3fa7be688742e50027fb540e69148c5cbfea3441fa00c042a3a61039a477c374def0050aad2d07b7a49c4ea5f47b6db531bcdbbbbf8d89eaeeee5e6bad93041b6e2a056ef9f4762f48c4dcffbeb41e63014bd9fd9bf385fa42dd0fdef042e00469f4e697ee85c08e83214c30c4edb295163fc03f51415d9452762b7778658cb1c3a496b5afc9f0e6a9798c45336ce1db2a73efcf0fe80a037ab70c4085cd9c566e298c5bdf57a973fd29e787e3ac5e03775c70ab139a43fdbd94ebfe1a428b1fe07edcc25882e04a348aa68075fbdfd7a496959543224c4cb9bf14b0ee16323356eb178416b5bcdb047b3629d1aca6b99de2540366769b0ad3463e60dcba715488037b2d6a778b5cfdc225a85cbf3dad65529ca237c77d1d92434a406e2c7e3e48f87a58c0c28c7da7b6395ea84c35b14c77c3d7cbce79a4511f8b33dac836ebe31df1f9247ff4f31de5b850d6b89b371441ff1fb5aaaae801d8500472ff47397db2efc6227f0cfbc20de4eee881dfea81ffac77c3d55a9f91fbd36675d395e9034de61511f32a4e2db97f6689555743c42cce6582f4f113da34b5e490365dcd2a2e48e655eecab4839dba41142d9ebe8d35623cc59e7e0ccfc621ec5b783482d80379d85fe0616f6564ec3beca3dc0818f68db54cdf028f3e0e5a2541b8b103fa1d804cff4746a6ef9365fa8549461ce7853387b26a48d6bccc8b2d3ba8f4b3fd5dff7c72316593279c7295328928637f2f51bed8c55edd927c719ce7630ed51034a714879f5b84affff15cfe3fdf7aecb91ac873f5e76a00d073ef03e8b91afaf381ffc547a4f540bf74e4e3b91af0f3ad77f9e7e3e75b2e1f3edfc273f9bff8a523179ecb3f57035c7c8bf7e1e25bbc7f8b8f480dfef968f12f3e222e7f4c87ea2f1db578222eff52f0f1e261bc03e2d1914b87eab71ec64784088c87f1bdf8968e5cfcd2910745f011c77df1a805baf0e2510b2f1e0179f1087bf1e8c75b3af2f1968e364fce4fa99230c1fad41bc0093036e563823d306883e9cfc7416b705f3f05cc211c13acaf55c1fe3d9decbc4fc4973f279671f6f4a0d3cb31230b7f9e1fca276f08add1803844df08a625327d2732a55e2c92d3648231872fea3399b27f036883697c2128986a5330a54734db21340d4880e58715a783246784b0a2085043022c988200bb817a0e4080186e609b065058fed00a583ea594524a69e490524ab38fd1831cc618a3b66160c700dbc6819e02705b8c34aaa4b43ffaf2d96244d1c1cf8697c418638c45780b72e2e0026d423864004281418b0dc885f642c6e9132e5dd0da06b044f7627be5b1e0c2d886a08061c1d6b179d16d1aec09ba60e3e04dab636c18cce0c2b5c5a0a145d00636015d0c360e6cc0196c728ce0bc8400d97c4cd3ddc87106518e2fbf2b611081e537a59452aab58c4d0325b2fe6d003c5c6f7bb1a9dff66aa235d85e3050a16d033158c6d911001b57446eb0bd9460f95402404883cf7b19196010e48a312ee862b400c68b968b1640f8c787037de204e34f1713f4d24bb7f7f6895c0e0cd4e2714c17b171eb855e337028a0878f1f25a0a0c474c4494a96818969a638b520a7489902c4e5903d48f925a6916470e4ec79a8b26982934904476413c6524bcd144a013774b8310485275828280df9b1c2ca8d2c2218993132e10714ab1f2598e073c7c968ca02667c9941428f28543d7c90c039218fcc68d2e355e625020e2b510d0e0588b02d81f5924c3e88a2888c5e2c18bd6618694ed421ba22013c0382ef02f84260664515684501a11d92843a2c85bef6daedeecfc9e5b850dc2c492867707e806470cc3c25cf59967d77831870a6c53ce73797437baad11282c6d8cfbca4202d0c0a83b296655d967d3868cb3b2128872584f4afbd37ee64fa25056517d6c5674227553ff392baae6bb5ec6b2774393421d3bfd5bebadca2b6304a6a89d93ef3925ab715b67296354da35f987ddd4e68e530c9b91c5b15a25f522b036d404428e01c7eda6ad9873828a88574b68fe3a4f1f33d6bf41c92206cb203ed7ff0cf5b2f44216fcde5f8f9943ae38c5f931bfe6467a52d8ccf675ed266b5ee664fc36dcb99176e597bea855bf6d1dee7af04e1ca0eb4205bae5fa894b7c731339fa75c0e9fd7b2b2b2acc8db97b465ae33e5be213903a3e0f8d43ff39468a6f289d22d7bda050575b8d5c25ba665f6ab10ed338f7af45b82106507f4370f07fd82d0dcf5a93724dbbf958764626262722135a0e1c280e32300488f122f983017841c8ca991024c948b2530ce510a0c940b1ac06c712103982b645c5803a68909ee295accc1148f194ca500428235396bb0abc0c51078f3a155678796121b5a1481b91ca5be8cc0096b394a7d4982efe09f2a6cc0581451700c2154802f9bd614d87f6871046e3438087cc7b4a0c058971660b0dde2e20a5f2c4074bc5469517991d2f201df2b5a64e992670ab675701250745e14c13707a039d8e628d5e5861c6217497429410e1f57813b47a92e5780cae09aa354172b524f7ac8d090c37fdda777c58fd9a543e6f8fde498437e6440d49ce019fa351cf52398efc7d068aa071df294e61045a107bc4d30dece625cbd97cf008620fd05ccefba4887260e29259df3f33141da6382340337b8f354c0a4c124673b1169f487734e1957e0ce73769043196da49c722e4d29ab341b3fb168ca3658e6f027cf973fd146cc22782e19b128462e030c825c312ee82c80f1a2e5a20510fef1e1362dc3aeadb1281671f471cc1af48b71487e8c20904b734e39af2111fa8cbb467ca13d784a29a517e79578344d6a4ef07c6dce386577c7a739242225a5d487062dc61af4e5df5863befcee4b201e08a69480162308734ad94108ddddfdc590524a638c31c69e4c9a4610fe8557dae897d1bf7eed9e12f5eaf14ba173a7a029a57fe3bd4dbddb7bd23975ceb9013d408e10b3d65ae3a431ebdf5823c3708e1cd24fae1f2386710b58aa9f17d656961fd552bd76b56d6bd8dedd400f8823e7e73712b8fbb7ee966d25d9e0f0f31335d003e234a1fde109d2f03e9df369831d94a81fbdfa309ac0f3c36995ed19ec02e10b3aef8740027c90e5df1962190816fa635efb17ca1a7f831df0a4534e8ef1b153d2bc82e2d4d556acd65ab3af2fa30d98adb5d65a6bb5ef66b4ba550ffbcccedaf58478464c1554f735fbbe24c5b8fa0f3078ab35c3aea5b8d57584e3f6de97bb7badf5bbae5a5badadd5daead6bd565ba99dcea4dded7aadb5d65add37dc755dd7755d8f104c4ddd0d1bb999aa5a88a0a014a972f74ffb34d73d63125911a84e80fbfb6211680d07397caf1aaa463695b16a42a5052106864b25a35ec05db451adb576e6fa75b1c82f58ba383a0a436e755badf54b6de8d7a665443c8011f4dfb4cc8522d8ee6d83163fc0d14cae1f1020fb90770150c4b2fb191b603c066af1da17be8bd6635ff87af18d617c2f8c8c5aaf970b106cf10fd475f8fbf9cec4be372e05a1c5a8f4eb1a4b82cea119100000005000e3160000180c0804c321b170246771b60714000d6ba24262422e1ecc62418ca4308e8294410819420021c010023364354e004537f1204098669d1d42ac3462d2c53de8a8328b40eba4ad3dbf83fbc6b37bc8bd36424f55ebc4f293d5ac06eec74ab957233e8243f47de080008d98030f1a84a231ec52f64724bac43872d6f2bca42a59468ca3249eb08c2546741f8902e7e14d890d6a44bb7291f1d40f4a03b09bcad3dc422353fafd8586691e58cbc31f877826a4bdf66b2089efbe03c00b3969af6f91f2f0c7eda3299bc75c8d5b483d97c957e62b6f62983c4bf265d65a21db8ac137f5db83dbdea3a98df1181b572f7891f20ef5b6a62481036f44b20ae80861f430557b8d223435de8b26ae00735432a3b4fb3610bca06415d863f59ec65c21a2bb728fddefbfc8c17d2326f79ea421fad4f1bdff0bb7431dba4c6e4580faf0cd228b00babbfba569b1735935a814a3e4c3177bab6dc53632b644c0798ca5422def76f9f86401459dfca7cc7eee1a4d6c1fc2d27dd76502522e208ec03de3092af7916cde6e5cf2794e97380101bf91351e7ae7d931a2baebb8c7e9e8bc6f71c6675496b04b6721c04e13d6f8730d0ece03f4d2e6b28444358baebb7262e6ef43f5fc4af6dd7d5cf51d39082ad3451b80bea0582330b10d78c4423c4a04b57c04fcaf5a5600ad745d438966f65a3e04403a623e0997f1c170aa6d5da17521552b685912bb68ff58d1a57e8a6d5714cf55efea284be6a8576f2b96613086924aefeacc1732c60cf1c1b534e152f57a5f81d83c61d7119e7d9fce517c904e8bcd512f65460242bf368c1479d7077615e42d189974aea3e75d7f96ee3cc8ed2e83f6fabf5e24572e17f50ac8cf40add54297235240840ffe1f1cb6be09b4f9081c521f00d48399ea84a156e322b2bbb71b0307d927ccf9fef2de5c29777deb9914dbf270f77ec89f9b904ee1f5d342cc7e59a1567dcd172fa1308ed87e1490a364abc3ce7cbc4795ee460f84872d4bef5f3d1362e133e73f305cce160d78a1952462d6ba5228b6d4b0871e235dc1e5ba1c7ffd3d00d0c34309645e9bf7551f3b4b32df397c8fb89de1e2f42a0d3129941696d27401516e1e157a7e309ee9716c634d880bdeace90053991f97f68119bdb28f830d0d8b9f8a0c3356ee029534d055e526660c481747bebc5b6a4ed4df4afd6ca84f8952209acc88dea0d77f84477bfcf236c1e6660770210318c90998e54b2981cd966aa7a1c2b2f74236e48a801896ce192b1582b804beb8d2619014b0fbbe8e3c99c24bf0921e6c5d61d673c5410140a31c1901088ac937ab7100e72dc71901d49d5b2654aa17126f8d801fb35f165b356b6246ad3a6000514ef61920e05255e3ff12e94aa888c5a370e82f8ad67a9824fb8042fc0bdc4e5881254e6541f33d84a995d468bcc2cebce44acd81b1e1d05d1d523a05ee5d40ac4a2a6a72e2d8fcd2f06be15e25d04d1e9bbe34254754fd5878d0d376431022608c3a7c14dce8e6054af0fcc7fc099bc54dc1e4bf63fd9276550521458a28409feb32df3178c245224cb496780e32f00230198c00520027814a2b589f85039de2e675e0cd06c6035a1f67579babc59b64c546b75aea5a65c78af224dd5a99d32770c35662ca6c3f1af8ff4634349423565aa85100d44c96cec5094d9ad7ee46704119c1c83abf6c7bc7a26d4da74c537f062703c566f6d368bde2171af315dae19a996e2ba2c145c425087b2ad063ad355d2badc20ada21387b28d4e15d235d8b63ec805559320f971f324de5e92e83594fafc7cac296605f8151e0f875c2153256a5545addf36154a33b33cc7a25252baa0dcc5eb2c4afd052995ddbb1f3f7c830baaf519365a8e6b9d634ab99287f84e0198c1de0b1ba87719fe8dfc083f40e5ba9ccc9980f28e33c72a09ace9c712370fc9f991f5e827a7f1869139e24b73060ae9f02c3fc01da4dc0bc1230c1113a9ad5f8ac43bdc69396c86fecc47f9f322866a6d9844496526a640b837e734160c7be6f07141f16b78dd1c9dc997e2046f603dd48ebd4ad8b62a743dcc7dea6ae64a0162e6c08a335b0971ab85594492111cbe275164253c67bce0f5ef0ffbbf387210d902dad7f38ee6ec5faf9c0b6621720a26a523c52f81e9bcb73ad43f6046413086aa524aab68216e7f2d34c8bcf867fa4d6f14f7ef0d9440bd662cfcef3412ce54c27288f88439a5a029c4d46e8113069594839b1b0eac3b028968f9d484acbf2332552e93fae60498188802174a924f7968ba66ff46188f0945497c527e4aac3877b1010b0a07a45508baba9e3a1d62c16a3d939a648524b903fed28eb1297dfedd7b2413b4ab8f9ea6db912689db7a8178bbbf956bc4a5af7ee2a7434bfcb69689bf57727a9d65033f7a4cc1bf17f7aef30e7e4bc3f7b1952dae0573a9d0005dfd77e1485807da9a5f9d46d1628f1173e9cfa485ae30284b29b57c06b24aafbc802218740fd8a441254aa6be674a125183ab0d3af6c3bcef9bff92e64f0398b6360d07c48beb0293a3b73790b42f161d41b184aa1b6c898dfc38a5bab1320a28af339b1b53aec3bee52e55aa7274af34372e089d457c210504383fa555f744dfac828f220511080747df5be53f6349c3750b5b8787b9b74670454702b11decf259e26d53a71b3ce1117c3fe226a6a70640af6479b162f416e1ba400524c51abc74d83f8298ba22abe59d0e86f8cfc8bdf88135e6fb87a37faa72817d43e98e3144d8e27e4973e76d44caaa56fe39451627a238a639766f2e0590d70b09c24e00155491613a810229e08a59099a3869cf6a41d36c593c4ee68813dc1d43696289d42b7934abdc4a2b7e8bdaab35569d5346d432d1c1648751873e6167134b1772738b94bd491bf717d8b2f7fd29a798261051f6d7b16ef9f8615d6faecb86851ff5422f61bb6e031fa03604806a7dc4ba0612ba74ac576a4d1096ba759ea6c2ddccba16dd48d338b9027a22be34c650d21c1dc07e2cf4acfa2701e192a99fef600457dea54efe25036e69bf7d89b9e6b00c22bf26cd60f59af269081add21368d94e084b93c9c4b757d8d6a1ed1683a14a66a7e69a40295a23039a2e3699bf877b77bd52863c3159f8ba0560220cbdd7f26873dcf2bbca4ff5c4d3fac439223e6db06a00764bb5f543e4996b361f282fad3434077c0cd0f7c9c7ba0bb7524ba424f1627dd86fe27c764a99b2aff669cae9931becdb6c9c18cc17327a6d59c88929bcc686d49731493191a6a560225a0045bff1dd9434b8fddb1f2d25c101352fde95062f3495222de6cb9b5edfd002e76b4788fbc3e273406cdf8218134f46dcfdb5c3649a528e34e0246a0cafa72d6a95615831a61f67dc216ebecfa65f56d0e7f2d9614dade0dda6687c98376c2fcba247d149bebd742502be6257b80368b732df38faf7904bd13d6b58c786f9936a4723e3757b642abe31698f0da91e7729581e4ff930fcc2f6f61f628dd0974be4be0aff5430046c9b7fca4a818299a52aa6fde9fdcdebaaf9cb84cf19824a329543b0a01969f95b7a77b1b6aedfad4a6085fcfe7d4956056ffbcd4dc74fbe3c26746d911f563e48f21247f61055b8b8d540931309bb66b09a5108dac72a078442a5385dc05f52264463a75372965967ea74baf305de0ac02221d59b989cec9045be911523277d299fe03e59cf340467d23df6d54b1653bd0a7d253eaf22338b83c9454faab25d7690eb8a9bc53d96c957c8eaac44c55dd8d4d659690cc971b56c132b1745ce8843570adf143d86879aaa46a4dcc8d11731df4946f26bba6230566de3e520fc8c2cad7f4f8a123b5fa90df3465bc2907ad09216bdef6451958736ce122d99735b2d9761c48cd568abaad92e885c5c3bfcb80acf38d76db1802d3d63bbf01f651061fe8be941ab412b002e183d4e5150fe28a5a437bfa3ef338f1651dd12e80e148631d48d974905cc096e46774e32418abc0c8c4844ee1ec5fd558bb71188a3a8bff0c495da4be7f1192025ce9dc1951032548c2b4650df823c44a6632065b9626e349649e55abcbc1c2886bc9b2617187ff57ed60cf0948319fa05cd4dc81b3c4d5aba7e463318e4b0757f2cc52def6353a6f4e785c53820def6e45245bae401c1b13c7a67fc9abaed72f4ee868f1d732f99e4e388f65d2d50966d84b9e598061673025b9be74f7eacd839af3f2b492d8afd4a1692e36fe182953469b3e1cd7610ba6ae796c5007f64d516bfec467b1ce8a303d0dff2e97691187a97b8891a6b81796ba7718753d74fe96995a195d2b056356e946a22dfa9304c2f1f02372b8ad924653f48c90f212824bf7756f5ae398d50b9cb439dac010b77a765ca0573fe2d2f88194b46c9b130fda564ece68af56a087fccde015265e49aa67c0d00f3154fb50322de75011e69d1c9c4f844874a2c7187b572a978f1de4e873c1b3c523116d563558133f21f09762332a3b02fcd3d6336c5494cdd875b1e4ee61e293fe2999ac86eb765b99e101e2c9d1c6aa4fa0086d6a24c9348f4c06bcfa46342132105472bdf6dc723d56546a30eb5a4d75518d2c62ba82d1f68c1b164314fd6066ed81b48c94541c847b8364577c58cce2d02c422a9d818d6b0f63401baa4ed3138cb6d4705ebd6b0091a46442aec265d0744ea5cb0e7e41d2953cd1475952253386abff5e6c042efd5a029b8471cb5c8600e2bac5862c12258924a79a0222b053171da45c01d77580a8c6bf2ce49f4f902b9f15bf923ff7c02701fd62f2b480396ea778028be42e9f9780017678797f222275442a0f894f014467909a8548fc2078a291dfd6e8483082d8fbd805b147b200741202855eadded19e17594c22f9f016c16a9b441a7b4d221c1be8b82927fc26e5b4620b01f32fa864d6f5ca82a6c4b7759294c3237a332435881f21dad3ced5e23209083e778122bd86c28ac58a906cc07cc5f2fa40e40d135247da7bcc4352b0cf703e00f692750e7a73e0dfa0f909878de1fb7dff43554aeb49d413126956d1b8b0c15f1f12e366eebe394520daf071e0eb964db8a6930707206e5990e61fb8257a70d58e3d789b30e7d977fa5231612e84a4cadc167aac0660055952bf66fd7ac7480704539d2ee374d3060567934ab1914e3e520d10cc6a38af8af560e528d23b30b7abee9086cc4e91fb8ab97f69321c34a5d20bc904c32a24fafcf3d19de525da9078de43a0317177a48a0d4bb6eb03688c99068696687362adee054e8e8abee46701bfbf0d9d95031c5851ed6d793bf37069ef4017b3e9a49b720acbbedaf8cc1f5fc505e1bd7db115634566c2534700d143b01f58ad027fbb4ba10b3847ae1ddaca1ebee871f4f43fffda3ae5011dfa3c6fedfda3bdb9eeb2f9093f49a78ca04fd1cb52c7694c93f0d090cb59de09173b26e846d4e591622d6257e1775d7e2712fbffd0a41408585b0830d566d9cc76d4ffb9c5c0d9c0832e2eafa7eb3b7781aaabf758865aeb4b75a62d71c21710c0ab2306056a4059d25a5a072999ea50b7c02e4e7918180bd065407e4b214920986947c002b2b7bb884ba42540fa911087c172a810b50122c6b76084b793f14cffa724d114c4049c47726d9a6940da2a8da4a9211495ea5022bfcdf93af2d11ebae4871913995fe1303b3ff5ee5cab0f6aaade1fee8534d15ac4171492a885ea3bc8be9a9bbcc03b933143a1a8ed70db473e872b5550ef0056952e88e27e7e10a1081524cbf45d1664a751693fb52a8eb251a2461d98061576d0f00502da2a686d0554982204ab9b9c324789e854d08edf8d4b1bbb7ba5477a8e2da4cd87a6879e904b130ffb5001ab68c5e9aaa59a92d1318e6dbb31886a95868f296424879df0785c9550545ccc857da849b1829542e738cf6aec6c4521ab3f20dfab9a27471a394c23f1ce31c0a2ec96b4ec18e11e669e1888de64d34f2464c46074b7b3cc947198360780ef38f1feb59d91c053eeb88489351685f9860f15db08ceeb9f96c7b445f25f6d98c435ecfaf457921d03e05071bd2f1a812f64d82db4dc6cd1249a565502c6d045bc1a1387fed9c24ccc5c4fe98b086862f5e981f8ed17870a6bb14ebae117de40a75112e3b6ba1cb420d856b82c0feaac3357773d38df8494657efaf1736cee2f1df30eb00810f959511f1839203c50f42e34f0c67baad4833da8e0370ce221539a829043a5138ded465b2a06a717ab00f7d94710046e31b13033dbe92921e2fb913d8736f10c8ea495c4809b72b04784a3da4ce9b13fc6162b867a61ddfa37dc581422a45d3dca020c95e1ed974bdccee0f55725176a1924b561e15cf960e503c97ff591caab065fcf8f21c89fe54202fd799a43c96ca3ffe247b2394b7cf3bae2992a6ed1741cd4a0c5701e7c7681562a4267ec92db4022f46fb1858db88bedf7ebb089e12369f553c449955d81664dc26cd0314ae6c217d91e080e466b07950d3ac5d983759b176ddce22dc37762297038d348b54b8018f955bf4a647469959c86925389f2637a046fa4eeb5d927973abe49a4031c76f0fcd120c08490dfbae127ba6d50bf3a754fde660bea7d8ed87bbcbc7a1885b59970f07770505f00b17958c1395a74cba31ac04906ef02bb52066cab6017e2611ad2d5a11c1bb3d687412636e218dabb21964a50976c4e14b894e8b0e1e43dcd6aaa27ea4ad252399250a020823601dc15d12b76dba5196a9b8e523ba1dd4e6555a4fca62ce9fa71803c63a6a5faa19aeb1816d5b3ae534b44a9b58b9027435d020e535ac481722c914120473b91259b350206bcecc617136c1d1ccaa4412fcc80000aebfc6c3ed00f486c55e339208acd4d75a8bf6534631a30ecd42a08739ebc788d81b6b740126f79988bcce5b1730988cf85cb1ec3d49db6fe212acb91ce5ed91b6467bd34802b08cfe57222e3e670515de8162cd1bcb12c815d9f360dee239d8fbc4c64e671473f1ec32356a251b3a34527a0a44440c222bca7b25cec4fd523ff692b5ff80e309a1f4d9254aefaa46eb2d45661070d4c1ba70c7cc51a3f7cf7bbecd2287f31380438cfaf74f4deb62b3f308f3fa7b2f95779311ff386ffd71843cdb5a45c628ec79562238a322cc6afb8120ae3b434caa3c352b0c6a8b04cc68a9af7b03c46688df855ad90220654cd364dd93e4699da98c4bb4fda37307aa3a1bd2e5d504ce6a960b26bed5fc845ec748db0760fb5ea574929fc6ddccf94b6804b0a76fdb1ad8f6ff97fd9bc94ed34c0ca6b3f883cdfc52e9185fd9e574fa73f036563852d1924a635628638ce8a509c33d0ae5192ae581f2f0205589e545c2982c3c24e2a2ce2270fc95b62b65a4105fa621818771d3468b5c58687daa56d2089382782488f85969cbdd7a17c999c0fb7e01c91c5c1c3106a32b7bef3131b945eeb16b5c14d6ab60e295e5805cc52637560c1a872508f5e0f3c08a067dea7118619aa0896ce1ceb979a710b9e2bbc17a83cef70f9fb8e17578c61557cb8017367136b397961a82a8fa7d37421fe070f68bcb6e151688aa7749f4803012eaf0f2d50dd899d32f5d4419d7c7fbe767ed7a44f3ea022afd4181362f808062573ff9b172f84a5aa426e66f18e691727ba9310b269f2a43da6ab6347e27ad1db2e3f15c7972e107abccc464f6dfd3d08e0e119b7c434507275ba9d4fb300935b5941b022d85592fb208563e20e2dd24810c2ba8841b04eea969af085941c0689a8245c79bfeea7640f53a1cefbe0253145975fffe89ec4abe4338713f310657bcc84a021e35f8eb9e51dc4e14336272663a08af5150bc8b71e601829ed7a255684793e9b06a77681a7ad9a1a001977cf9c3748bdfcc2c77a812b028b2db9d46ce341e6ef6d96deaeb5ebdc7fc6700ebfdbdc1cd25bbb00fea7eb0e910e61ff736ab56844abbcde86428f45f1c6ad583f9257d2e8964db9e90b1fa72778fc02898ec9e02ced6d22c2427c5f497e1bd8cfb5b469a940606ea1bb1aad8e73429b26f07c2b697bfae9bf8b64ba85de219e67924271d20e4f2d0fb464cb7582d9ef65d4f5e89202959fcd77832fe3081e74eb3e4b232c6c377733432fb5567d9b38fafb3dd88c674bfb222b73eacc66670cea3678d963d907b15740b9b45ff6628da799d86b857239f0a2c334f3ea8f6dadde0a9cf4b018c3155fdadab661b0301372fd26ec1892a3db86352cd72bc56ffe4825d768c5a79dac8aae4f5c9d2a7d5d72e2fda5d915188d2a2579d30049b2e9a42e6ce2af008dc4f139f8ba293c8690ea455bb64f514692ec0b7098be4210816ef8bbbeff759193c3097eb4283641c2753660741899f97d91c3d1581475a1cefd46d24c314b7cdc2dd80333dd62901cd3981c6c8d71b507c74745bb6d6474b2736e30c4c863e8a42cb10d850dd280856d2c57cebfb50d190414557e9836e95090cd599a3164aa281317b55cce0604634824f8155c615aee7a414187491b00caf1f63c3ba4e50e18411485aa2906acd31303b9403f31ae7d983952cc0dc5436343aed0f41ed09511fa04c06375d53d2cfeb49b16f522bb8a5f7af755f182bd02a3816ad32f9bbaceccbbb099f35a662a8d8ac43d279a4ef7bc5f7a61bca549fd5433b6dc620108f65e2d1b21905b732e64e1bb00cb51155dc932b3a6d5e8c702eed6d6e1c8a35030b8f45cfa2a5ed895dc8d1666de1f6df55db55a3201bc8a832e46d7f0e8592d76def18ef9285dfdae14505b5789f3cfb4e4e5fa4051f0dd93a03b2d3f731e77bd1ad93166e32968b8e4b802faa890bb5cc33631f0af86634e8ed396ab8490b979c005426b6fc5d78a8cee25f0e6c546f2baed71a03473b5567e39aeabc7e6f493bd45992b7c50c0fb96d46ddf824c6961ef33b1edef0eb446e8b1965479838e6d01e3ec1517ff38db0b9add8e17cd789608f38b06e9a6a5a7acc0dc7bac96bd0842fcc9eef6aa04dad4bc11240a5ad5e924e651328bd7cf360951f870237d7890b113f9373f3fca2197247e62f5a1857db5d1bec4b856a50656a1c18e8241736773b2e3723295cf8644a1319686ec988d67d0e054b636abc976c3f6bbfc59ecea1f46328f16e41c4d2067c9742f0e87ba510ad9496d04e000e82aba721dd347557226e9378ca275680683be3ee3178db50e30a63fc69bba7dba2fa85aa28ba797245441ba367a2795ce0e6b3450d74144991312f871655771b7ddc310e8b1f680485b6f4892c59a1177c05f63056a891bc3055dc7720a83f585eed1d75c03d0a807338dd558b8112716e5edf797c8bc00a65ca319c83a80aaca8f0bd794da50f01654d79dbf4980d951bc3db460a1fadfbcc9c2c4db6708f4e4e2e95af4bf7dda5c3515be3bb44082163d5b340745442ace13eb73cfe35834d177359022fd04b3233af577b53710e6fec36f79c4f30b69a0369d58f0519fc26cf8e3c674ab5bd55809416fde0a2b1aa9355e57c4a2ea81abb6359a9d25313374ca2542caa2e814dc5a0158011c8be688a9ad291cda7a90175a0c038f336cec9aded85b797da10f75ccf733effbdbeb9e619af3da2a57c10ff20b160bfa4a0863ee36ba07e8720da4bd26babf7bd97a003001f6ce86e1b406241dcf171e8699dbc2eda696dac135371c3140e800da5e390f7f1bf04472934157e827705ac9a316b667e4d40673079aa582a43307537755177d58769adae52f1bd1f34897071eba7908dfab4d66abc6b4d14836a7b0c05159cc80b39fec4401d51fa3b820e6f7b5a6150a0aefe3dd946d9e609a5d23aca8207c0c2c31e91c5e0c24e61aaf142c42520c8fa920eaf8813060f39781ce300302c71acf4141cf897c782821ae3fc01bf939eeca6700540eb6ffada1f6abeb9a7b57ab584618a0ea5d113a901d0748f2555785eee32bad03018736019a1612b1924da14b830918d25941033f9171c9c7aef27a3e53bcaed403a500b24b5ff8828554706221bfbdaaf5d0d05826a067f211c949143e76f06bbe3205774411c693a714770d28e50060e630633c4f5eefc72a031592cc869a4fb4d1b94931fb1c82af83bb2c1ab369680b0469dfc1c4b67637e1b0921748bbad5750f1b4436a3253c3bc0eb785f2cf97f23f1c981e681b6d85f980725363d480757a58bfdb984cb592ac709eab610bc34189bfd871bc5c2035e45320b3696070aca618cc348dd779829adedeb048a24b629a23c4dc0de1d8dd4bea80108e3999dc1649f8e7703e61ad37a8ce402a1dfccd60613eb2e266ff37dd1f3c7fe642efaf399e774fb5fa903aefea4e9273536ced5a289b8a805249df7759e33b80edc1fe3399f49f5e639f50af83b0705b12b3084e24c56579828b495e56cb3d818751f41a0dc793b9c662f109570a3cb2bfbadb48b7fc0e64c62da0cacd261e950fe20f70096c1790ed05de4578fd3ec83646f2da8d053b3434fe740e164c9772925cbea9b32b2883ccdbae6bcdb4e569fcf2b59d9badf9c95e2b12b00e2eaba0e6d1c9427473f62beb92830d0bce0228e7c6f86c37768a08c93cd64a43ebe032df7cadd57aff524705c2434a9c52794b25b58b272417847742798a3fce053400e84b9a02b94cb3adc7352e50fb8eb6d0c831c7f18dc05381ff6f307e81ebaf11c9972da53515b3c1c83c554e452a3c0e23b2c04dd1ecd360f0d659e72e15d7bc75f65f7c9c30401505df05283f84965ca16cf983c9e2fc6d2b194a006b92b148b956d7920d4769256b806f20c64859a524b2af6d47f3471b733f06083bfaf0aa328acd8767760161107a2fbf44d1b4da93e19632d8c092a03b452b8e355b47366f0ce44d07ce7dadd4c7e6596b79cd7f9af8d910dcb71c8b22b69cff629b1ef559679e72a622e971cd9fba274904f6be889a615d41ea230444db24391d4b15572c9acf2a8409aeebf15c72a4b0d9b39c5d52e82da799fa579d4fbe2bd20b71b701c29ef2b4f08b5fa414a0014b40377fa92153518fe091a130322775f73448fa39eedecbe80c6cd332cf74ee8432a12bd025a10d3410919625ecb95f8310ba557d3f14ed8e7731e6d9cacc8a7ffd7b265ece2077decba0a95246102add7a8ec4fef73a4762f5de8320803d385c96dfef62306999ac48565d15a32a919e02c0b13bfb58654d9edce1085cc8eca4bf11de91c89014c983648a290a6911e693c30d163b677e04ad3257b28687fba51ab45264bf925d994b3ec10ea50ac2055c2cbf7c3e31f541306457605f99d40437fee0cdf54264f9a6d6f34fa7e4cb6f00b3eb3efefccf91a0e16d8995f9c731d30a13e4a0c1fc1602d0d0832075470872aa3ce4a6d0a7c071fe99c0213d29878c23d05a4a0aac2cfc339aa010ec8c632511915331eac10c42cdd7812df8afb895160dc51b30f51d49cb9ae88904a4ca89af4606c86325f286e15804452938574a541743640597b4dc1444ca2d9401cc455ac2b1740c936e2039a9ea35741524a88d22a4459030f5e62c4916445865fd050594950cfc2d81f6195a6e054811561f4389049c54b9a63186890f79c1e4a43d4815883f5065617d32317186392c5c0ef64fff81848d45298fce425e202f012afacc46c59b8c85131f812cf46c2b1f872b613a5e5a0c02f10ff742e02cd29cba30f9f7b85c9a296c28a3b7084129be6a00dcb05c724b17d959cd56afaa04aff4f362946d822eb6c6bb59ef4c400cf04d981125991271554c4a124e30c4890be55a45d16e9673e3f30f5d51162103bccfe7b2778c76c63801939116da462bdfad6093ea196001e698202260739559ffd79ec2f767f679dc2b68daaff32b6e9fc142c8a8da1cb0097202e6655082bd71e4a470a734fdba57e1195158b12a099f59afab45790f795e6bf2c3900ee7165de261f6c1ecebb14f2f01d79ed01ad848a90151fdcd92558db54b653defff1b7b3430a42451ecbfabc43d8ad1fde3bc444056a055c2b3abae14a0c991a2e0b8f1a6168ff0fdf3efcced9b9209f11dccea5382434b7878c0a395ffdacdea0fed51628232ecc8bb134be464c6d02c8f91d6cb0ab3dda4e7cc29b07b5887ed9a2cd39f689081b9f61b3b34260b8239113db45912ce6d5d18c964cd3729902ffbafc3bc3f1846463b221af38b71981c0c575016bf6707b8fd32d91624fe4daadc136d11af2dbcd4e7dd6718c13f9a08dee831cf0f41f22f2cc3bfab49c1c5eee358d714356dfa7efe49c8d833f69e3adac4cf46c8393606f71165192cfe67809d45637bd223abbed8ca63fbd2923673f45363890322f624bc0897d5c56b33210a59f8a369ada30b8976ce00ba3d4837ab00cd65c568f5c0ee6d2907090136eeb70a5f1755e6816eee74d51d39e9fdc244b96ed45550127ff8d9d9e7deff2386733ace8062daeb3e028455854fc992e9198091c44693949356310c04f7df476c16fbdadfe03fb978dbdf11aab2d6e2079490e980c1487d1e751e7d8d892da11eb0b3e3bbdf5bf403dbc4c12784de1941530e86990c4538728a0668dfda43000a79fafc9093bb9446f39142805bdf19a3c2f41fb3326e853751a1684fff93b534437a76988e699a214191551422bf7959ac4e49b0acba0d9904c82c2a5a677c3283bd0c627cbf491180bf369ce894dd2477c26a071c1ebdc71922dd200020fa5d1aaf3c68f8d57b4ca9be90ff23b4e26730817c47a0a2493302f91a5a405bc23968dbd93b5e18269854d459889cb108eeac40b398c2d7cca85d705d6bd878033cca24151965185ae97268779a3be2b166a87c1c92d3e87904d93f5198b64558ec64fdbb4d81ca5b15161d618f4164129f5448ec8bc4a017db75beed4a807b8fb1e45a52429c4509f52a7a8beb524dd7e1c0efcd2ce1e7dbd5d25fffa91694c6b6267e36ed15aaf5137704f7ba26370b0580857c8b6cbd0bd3754e47c5770910cdc2511aa5066178bc75c7c579939f0018a82619aec8671b85517e04288128a5451a009bf9b00b480960e7fd0ce322d386753069574e1159417a677a74eb9f6d46719d598cbfb78da040c89b33062d441905f6ad711b580124637d8311525910a2f15da35b85cf16ee4b63ff35bd31952798fcb645c2c02059695892caf323282b70ba79405631480c886579e0c3e91cdc463b2d43081da8a3670b7c62320818a07b68df01b5d56038e162d3728bd3840534e8e8d60b360742d4e638bfc90a08f7ebbc02d0735db8ad259059e1b6035eb40885e4d4e67b9adacaa2da338fd1cfb0c4f0972ac70808c02802b8a58919d08aa0aab95b3730fc67e4a03b87ed1a8606f934a58e095d8a1f762dd226071792ae5e0052b27388736e9ee3a098d5eabed81325eb98b395573896b8661f5fbde9171981f04a1041da243ee960fbdee1e634dd3b5d6a8d907474301c3821149e2a9db4f2e878c22eed1f4d6d003c9623b591c71e196c4eb1efaa7d38b2fc2d256785ffa86047e3943e34a7e5109244eefc30a8de1c7d5503800d2c0db3c2585b73b61c8088e39cde54fc7165715cbdcbc4b004335ec5b319c93302fe809f1887cc319dc8e205898e45f39cd2902b3bcb41e2df9d518e6493c1a6a9e4667a331fab4ca605fd8c699d1782c085895572b1ed891f18c12c09d8f13962a8449f1718f14b529b79a309868f40bd4592d4326772c6e852793f0e28a92cda7918189d0ce7fd116943964778484e911e2067aa90108f14c2153031505a92a9efef80332fc4484f029068184894efd54c7f15c0c9331fdadda472e1ad8376a406c397d10e865196fdd308296706b428fc70aa6cd8cb2a090b8ffca6e3d7a75f153bad7cd1bc3e891d84086ec02731689e5de6ac2c2c3565f3bb16ed1230598e367a815fb282840ef4fb48fc3e1ce24fadd7392ad1b33edeb89ba5edc9438cdfb11d56c620225937221855fc6b94d18bb459fb2fb218a0667dbe4f8540e1809ca1989ac9113504c887e4bd36cf10988a83f2203ed25884c12405a1d0fd2ad7721e4163d26d254a247b602e0cb7525631376140a8af84133fbe5f57ae183bdd7e6a3192027375bf201e45e0a38c58ebfc83cec52af2386519a8a1c22873de1a9916636295bbc8fda5aae8016885a516359b019659f16c884fa26fb81182080d00360690c669863b66e61f936858050ef28d1c4853173ae1cd992bbd253912ce03ad8d3ed02c219f854c54e2f24a5ff4fc9c2a5d3fb2e9c4b90a2ffd6f5efc82a245297d89a2e19755a773847b9b65ace7b245de542aef594db563114e0079a4e89b8d7b844dcd11a1a5008e37280e222ff44bce9f2f3552c9d3ca76ec5546b8390e1556143b11419957765af818eb048e067884b94af53b66a5478551d3b1ea513fbf51f78dd10e308dc1662eb47012f3f6e4ca1085a7dc0491f19179a20ef4d4dbe7e9f9d0953c98659461410b76ce636631503ba55cb95d2d4a28ad04913863acae09bd42e0d0ab297d16503c5bdb4ef9de466eb52220c457c18356aa58f360406d059d7f1237e69124bc876f17cc37e4b1e668fc8814abcb5f204d3886ec519561c41c7ce89a94e04bc9c4fe16bb3828e5dd928ca2573fdf07aea351f2630e5747c8cc0493b0f4543f329ee64d4ce57fc24196d8c2f255e6d9c1212063861e1217d728dda92da6932dd49721387ad07b9ad03ff55c291bc1172ce7320eee7d39ae6d774c0ea1330e7fa38ef79d5aeb8d36c82c8af296afc9590fc6c2645e2c558763a5be1a750779666b0994d08a35170fa250ba54f18d2ebc0f4311b998fd1d15a348da10145cfc68e7f6db433900e1a3b5f1d996e4653665fb8ba79a18e44bcc3d83fdb52784b88cca80994743c856044708a47847c832040764c6795d64803c858361154336d8de2454bbc24a9c916dcdc89e2c0e0313cc0a640837b8326f8a376c403c2ad11abc4e22f7457cf7ebd8a421228e8f60d175069c6b4c84abf1cab17f212e44cba8e3c63802f7762ff5e954352363d1f54944b8fc123d3dde20da549c8e2d56d3784fea93c8eddc0791f553c993dc3b20ad088e20f3e469190d6cd01acf4f6fd5a8937b761c40f27f426c28f414a719d31e11ea8e6d8b1edc9d03a3e66287502a7e901a36f311492ec3313d6efe1e580b792dc5695a8f122ed142d4cf05849ae57107c28d4650bc480250b92a547ef497602763e14cdad20772bc7209f787439f53d9780ef48e6436f7e1017753552eb222e115f157f202f08eea1ff8d4e132b021d600e579ecec2551f44685a645500b3fb7d96f645a06be9344314f44738cb94dff929cacf7d51ef3fdb5b6cd8b3563d05faeb9a1f41e7a873fe622bcb9056041c98c47e61c52149f96dc9034ac99dadf404ee02dc0a9c1ea93d81862400f03d0fd0c61394748472f613a2faddb723a896c48a6039945a42a811bef4ccbd2795acf8d1aa64ae815b2b352025621c32963d9b4d3356a0e658559afb1c5caf84b646a826331e0e6ba699aa6c0ab5b1a10e622be199ad14282daad931c6b02db7b80edddcb11a616c3880b62a579987711d36f6aef6fc6493485d9e3b703591f6e8bc2e82b11e2ed002f4e8a51474491a494e0ba87e1e6e913fd12d89fcd82e65655eb39443550723928082261a3de1d8e067d6f8699663aa153676a1591854704bd94edd31278ee4dc524a73a28c12039342645579af50ab5691ba5f34f5ba8697118a4d9c5636926efe535701bff43331cfc25f6cba8728a348e10b714bef3104f93c429729b52daf6386101676c14a0013630998d617085104295222e3e26b6f5ecfbe6bc29d776accce90695b1919236c88d8e59c3c62c5da1049f54ad773bc69ca184542726cfbda6d790421dfacf75b4e3f85228306ab21b05ffb25ba1de79d6d915dd23c510ac4337c78fda5bd2faaa8926b89d612ff84545d8fbabfa08f2758616b6d796c4c3246a2fc2ba93b1732fe290c79b2fc4a64020ff3c49afeb3e75c763a4f69ae68a6c0282f967d62125e4463f9618a426512936cddfe1a14948c4b5b23c9c16354431cde981044975ee83ecaabb2a61de18933518e56ed7f54380c61d9594bb0884224b8229bb5b03858688998cfdc6c56b6e36fbfd86cb485f5ca60bb6c888de80f6247105849bcdd65ed21bbf195c6b2b3a4158e6d7499ce5141f0fb8e9908374d7f321cc6f38e142638a9852c2f5cc22f7f1202342cbb2921cb8721d10a44df8b22025b4525f914f9d7ce208e5e9bd993b41315c555f84200aafa3f10189dacae82fce368450ae3e103c1a98fbefeb0296ed27db2b429cee84ef6a9bb14ee895f0b916f8283824d08fb6823850958e6b73d25b05437ea94b23fd01223c9f1fbc82764f3523e52558c8b7ef95ee531f39a15c2a6f8999d0cf30e0c7abdceee2b603dac090d96963f03943f6d85becce3b470704af2feefde22162cbb892caa0882de665aeb3b958bcbfab09cca6f145840ad6dfc588d2d643b606c7b9a33c1ec52e4d195a390879c5abbfd3d4297e85f11c0532840d8c2398a0c7bab081bf6887c415aa28ee1fb24c743a9395eb8748886c0630c191166bc60c64113272244dacb917a9b04a1a76638776443dd27feab2e7b3c7b2066a7c4d1a83786f2696003253e463e653b2cc21e36b3311742f22977285127f9650d2af273198a3a09f5c4ef4587c8e8500bc22015940b566b4f859a07cc49aab416db2b25e9f8bc5df4db51d15a0b628f03bf82904783e492052efd0479cc4a504934c363b085faddd9502469333844ed51dd91e50636f25f35accae352e9bff265a4245e1d4a7132e9349bb00975571682707b1042082eb121eea2da0d2ac4032d4aa2db4603aa54157209a5a8e0b0283433aa5afdae38ef5486cb79ca34d5f62463a28e04c5e6586fe2a7240d27018eb4295581f8e9b4eccdd3921d14d41d67262e3c1aa0b08141e1279d96272f1a8dffc7847614bc194deab718744a984e1a5efd38b7b8242e152a9d0f3519e1c777955126a7a00be80f90ca550273d08603cc4bad30a36c59e545d22f3f5d00dd7fd964c2011a76168ca4e681c4ee0c1e0562498c13bd32ca92496268896cc3c8dea4f387934593a9bfce91948e78ce0c0058346f2c1b77b1c4f38283113e57495fa0825741a78b05726675468585b9c7010b42d1700b85f0d131f0f7e7b2ae8a4509c09b09df2ba531de55987d70bd5d31623bf8d77f9c532808bcc611f78b3ddda2e4a042f906061beb8b217aac230209a1f2e060c145e249cdcb3b2eb2d7fe8fafa12cbe630e5b2dcc60eb265164bc85aff27b1f875c3a5b7142b06742e349af1024085905d67b7550d6e775da89756a497894451d1c73af8edc4333b60e10c51b8968c30a5a0107718e1421b89df7dc270f73653a448be76e8725475bbee7b8bb58ced24329bf7afe78f681cfcb5faada2396981826de59327255546f9f47a92988ce988dfa227dbd0198fe96f0f7b776f8f532e3d534702346f73b780789c2b8868342099390e5f65b1981e5cc33ea255bd96deb1d079ec6a15296a5a20da47980f42e49bcc2fd48674f0f6c473f2e2eea749d042938cac486826af0ba4879f8a4a6cc92fb30b929e97f711c2710f3683f3d9c525fe0ed9a61a186294894087410296a94b61e0e85429edd007f3d88b24632cb6e3f7e8df8c5e27c72ff055b20601472f5727d6f0094937f5103008e932969c910d94a5ece242b735af0eae7e9baccb3a71adf072d25d2d88d54990142be4ecf91a8ce684b949dba0634f887ca7b71935ab169a10021b0524fe799850fdee4b75651bc6e8968d33971a0229e39fca932105ce49ec0198481652e5a16a123334c8f575460646593f2d4b71f50e1f445f1130a3700786f64c815ac01cf822f92083913c2a81e075eb7c0f0420b275b149a65912bc2d4b10afefa21aee309d702cb2b51715d54fce35ffacbcaa4d10cd43647dc7c506cf861aaa06cdd63522013460667b6acabf5f4d68ea8ddb668787dd01b55ed6545abe849c22c1abf3be2eda0dca8bdf260023ecda47e6f5fd508d6614a0bc07ce446b435415425f2b8c0277e553a7fadef744bf9e81a56c78a3191d8152c1e18a17b8e10b8a71db20413ff69c4664161c2691b171a694bacdeccac8d688992a793cc3000154a281682975f303a2f6d0c1eec89285853072f0c3f93423f0df6bea003c102b07f2ed0bd08c1945e193fc0b10057d74cb0062b0380a95940d4cffd97a1cd7fc694afecdb7d2fef3fa248b3000e740bd031bd98c99864eefc7da5f2b289fe4d555bf49f136fcb6a01127a85e5499ece29676c7978a777b5ec6fd13a0d6c2840f976820805547bd876efd072363d865c5580623cdcc969e95da7a287f727b7c3beaaf681730788c91d13eb3fbf565a6a7d42c15dd85273a8fbd3f819a036d4ec5e37cbd9def065d00be7d34ea70b00504093cdf01168c56f52c786ac9ea23a57952fca8aba27aa6f4e7baef016129edad125c9c967ee4f8ef3287cec25a0911a47386a2ea6c89058a780f71cc7de86ba982219c478c68ae5ddeff428dfb7a6a4320c36ab637bcbb01263dd0133e6d8acb7c153d569090b0355ae09666483c2ed0c4e4d7d63e29f70f40bbb8b5cb7f06df40124a32b8d335a8577880ed1e837dde0d010b00f4bcbfe20bebc2ccbeb4bbe7ea0f7326a4adf7a2648f3187ae24365e91c191f88eabdb1d868fd0076fb827551493ed4306c54c5e2f89f0d1ad6f5022fcbb0040b03d5ece3a3ead037ea8d2433bc928ea1d77b0b9b39c2cb1c355244b188e7d4cf4de5831c4a72fafc9e9f89ffd2a94f7e68c4d6a42eec19d02ffc65752568659751de5a81b592c57f8b47007f50fdd01c354d57f69955154b1ed00d39c6d464c7bbc13b2acb86198500d1f58edb82da5721e0fbf6781ea99ceb9c2206ac37f8a628aabd0ffd36c14d087c54a9b16fb8783214bf9f1101588bfbe99104ff0747dd7d4f3687e3e65ae5a7c6b3f0ba117ce38872d378a6af300e1335bed149b9e43c07d0d6cbe08c8e182212bdf88da265088f529cbd678bf6fc3d2e270cd0126124a140e5051c969ea4147070e220eeb912781de9615bbae9fa1dd043049c91afa75cfb3b20aa43130ebf9b1fa7d8c5436ec1320c5cdef60ca6fcc1a4a6baffc1c7c868211add81e63e0b6925c28cf143513796eef271885c2f5ce83a59740df059576529fffe3dc575d2a342469474aa7c3f32c732514ed7101f3f496556ef0765c7f068d14f2d90d74918707b3531ffc023ef9f3fb098f0d59fe745865b01e5d59c429fc58353ed2775341cd97f501ab80f9345e69165e4758a6b147c84e66698a645e976202f9728e164e324269c3a117e3e6c543f1fa66c71025ca7e78303aa832ab0ccfbf375b396288911ac2de21d0ab05a79536fd3f3567940d607463e18a793f87c550be0a335bc44b1c886c22acbd298afac8d737a5b1a30ab37e4b063d4d21daada28152c7afbc6bf9f8ab323c102e0b244ef189f4e934a30ace1ae5d4d5acda32ee9fe84c1fc9661b8d3333608fd3c4fdcdd05e697f90d27131c498c9e190374038bbcf504cc4f681470d4aaa3e58c9efe3b102a17c1df6bf5296f1d19d7f0bafba75b13c9cacda73ef854e3447e0281125f64673d43790751483be4a3e490708506905dc4c2fed074ff96b9cc311996149ebf7df31c2cef81f9840efc46e72b97b1358f3d4224439602a2d333d06df47af5bdfa80054649eb43e8d1c2f1512f51fb6d862bc69f6297a2c7859cb2ef366a47ba4fe2dba220d04271bc41e835a13d7e100152be16e3034014367bafed000066668fc023a701f68d0c2ee343de46c8142e1361c7ef2b8b20598f73838fb3a8f02614c029f919c8d35aea5175d2ed6bfb2dd256aa2b71739ca5cc5dbe59df0a9a07123cc908a00fea922d4c0e1e78d125cb3a6b65986015a428ae8483120ae019b106d5ee5b1c950014474d0e69a6368888383cd841282ca6d0ac1d96093e6c13f8825de136b333c432a2b491b3a2f427f8f3bad64c195b7535c156bfb3d5075a2aa5a2fce8ee39504901e9d39696b1195567e79b7a1a91af090301543664ec60b6b76b1d002c32eef821dce153a3d0ab4aea03eeefdd4206a781376a395c1597d3e6a1264ee58b719936fe339c4c57aa0a35125b072205c247bf61e1da9b3786427854c893309d2706c7b210b71d89d67687da7e0907540b7fde869853962ebaccca98fe0d2851e43b54bf2f42a404782fdaca31c29398bee519b08ef34861a25810e5994541a0468a924595e5f845bde8bfdaab81cc67e230b9d75a8d1bed62669f5027258b3681c5b93c5998909673725e478d2c7f83cd3505a33a02e9e1003348d2081a707ef197585814bba8c920f4351bd24327d04747dc67118415edc23e5da530f042491db8d6a0ecb82b87e9659ea5240348d1f5d85365b18b88815306b5b96430a18581c294fd6569193104a7503276bd52509dda5a7db7d676583e7659d38aa78a58052ac61644a48d2c6e075720369aeb3d6a4ae35def2e12e74a65d0ddc2eb3c030eafe03a6d736c0adc4684b9344267b8b61df9b200b14706ddc4f1ef057a6eeb0d9d0ac18b4ae558366572c12029824dba6bca497a2af6473f9a82f0ff813ef07c23f052ac2d76b7133befc9b659f2d5e04c1be47f4d8acb3ce5c84eb81c4a4a1528958468862dea7e8c555a6e24825021a6b4982bcc2c322edd1c9ee7be21eb7bf83fc5923b14d62ea17617b107355670f769803197e0823382b1924e24c4509ef4cb4f01139c1194ff50bd0017c4a451c2f0a54806477cd8e708f41cf3d0da5c7fa7c1e01e260485d1f8fdc47ebba92e9a487df58ce6e6ab5c816ade8f2405f2d2518b325f031d17df1a353a89801daab9e3bf4cd4d7a8960c49b20a4574577fc61e162f94b3ae16705532c1ceaaf615862951524ed189bf0a99f29c46a59e0fa36698f803987638c496abf9cebe69038fa53e85126e98e3fa9037e45e08d45fa473fe91b0a9accc7cb0c7951647903510ad037f82fe328766c122332c46748c208ed7434a882be380afb489cfa02aa8a48c954362b81db9c517666d634a4049ec472a4a53f151c6a67df2e8043a59f2530d9aaad1e3fde621d921769db4fc88872a8a452aa510b332d10df25d1567d7d18c814245367615b57faa1db87e425bb5680fed7d247fa512016ab54c03ec41dd31eb48cee89b7ccd3ac0d7d815e50b61d1f7c5f7e5649a94f5d2fb86fdc2918807b2f3d9177b3632656316b642521f1004c0d4ce6b208117d51477f25745539eb56df676f9ace2493dfe9f3cde7543f15f64927b1c7ac5c0c0a1d1632766afa17c13c5c65ce670499a3bcdfdc4fa5b1b1b3c8dddd359d9a51c902bd36f44b5bbfd518570439bb1a6b897636502830c2cc7a30993e9dd9c4674c934916e6ffdae50377ca71138b6659067d7646ad0e4d97ba66cbf8ef39ac292f2a3262f0050c8bef2e92f95aab23955dbaa558f1c401d73d7b2a003511377bba5a933698935481391f5b38770d4513d9878bcb81d0d26d69977fbda81f206816eec2bd86bd7490fe9240105b9f3143acd7f9cc029dc9b94502feee672dce6d1231a088f085113f4d15300ac10814eea3c658c3cf2e6a4c2edb185350fd05b574c6780baeedcf02368d9702724251a4a7603b06a2a992a59c4649d20b567d81fd5f667b928d31d76fa5aa6722aeede4afa8e487f885fea162e547698c3f29a9cab8fb641b6e3222a55e95f124929b63526cacdca2f55eac60c54469bb82429fca549c470d38a825dc77561a8ba61f0b26949382c4478e7a899f45bbe48d71ca5dc7111f393cdf355383f3ac8c864425f7accefe5c7c1cd59c77df9890103d43b7215da0d9277bfc34eddf72983c5fac7651e0661a87cafd3a2df19408dfe05d2679382d02eea73624fb22ade7a4580d45549f20bb957c4fd32731257a5c76aeafc81941c656169cfb43b6f9d28e353fed2ebc4fdf8bb163eb2662525cba89b45464e9c62d92b3a06a796007594dded2352d5043a9925fbd45643eeebc2db0fb06aa553709c131fc269020483972f7ebb75f2a787f3c4600a734eb35514ddd61f5eb01d9b52e67c4c3a20d982a86e014b74af0e91b078836bd0044ef511f1e11de462e0eece781f040be4aea39231d9a909a7b051b5c294363837c6946bc3c07f0eb9a266046788f323f7221b326501e62e1044e7985865b6b32aefb514f4e83bfb2f786390e561015f308cbed514576850f1b3893944787bd79c1bb74abc824fc6a7df04e70853c8269f62291abfa2f7f7c6b2c00bf98a49d4e6a3702009274feb8d6dae69ad4867f1b375b2e728e2196cf3d051d7ee92deac28f44125bbd8400fe390524cc453a0dc41167c34a61c16da1fc58c1a3d7011cf70bbc28a2594426a4b318d6b551adbbc45cb8abd901686d8eef7c5e5dd8e9a574372207a8b268dd22db4b49ae88d7843610b5998d1613b8b38376e16c8274ff1fe87a61514318d6ad7eaa1a2ba33ae578fd6295ee6005948b66e406479ebfe9b0fbf36c3b0b9db4a1d2adf232b76f7851eab71abf0caaca84366b10ff21aff76585ca272d24119c50c1107cdf35ed6e9c36f60bde593c16437e1620eedc70e67421906a2702ec138eeaed890bd2054d9c5f296611b443570bfb99b506734326186457077a5c4e3eda2cdbd7f3f5738685f8e37f7811459ddb6770e488744549b742d20c974200c8e522c96a9b2236ca9b9f71735ccb790abd46627828684263a1ac10b37eb2869d7996f39939a281f10ac724781425494041b0cd1272a9379967fe85fefc0746ea854f806687089badc1b1c850c805f20d523d0966a2bfe0c4dccfdfdc88ce00464b89a42d943718426f1448f2aad939d78d11e7dd284b4f9cce72337e3dc2c6c622128c6868f8b946884fca3cc3d1015383a8619e0c22c23988413bda433f7b7cadf132c3dc2eaaa8196ccbdac2b6eef8e0e5bb77121c4a32b08d76d05e0f0b756d561a5e66a56c28b212e269a7e378bbbc0a514690da57ecc93dcd26ebe6ce9e4d1ca00d89e9681853f8c0973008be73704e9990bb472059a0f570797a5990c8a4401590b739e575425424780600d6c2c1aaa42cf7beb7910517b5adc8046126e66e60556fa81d82c5faf6078e8301f55308ac7098e9f9d787304a021026c4fe26af0b8d2aa61ebd15ba8c27a8ad847920cfcf42836b38e8fb8dcccc6d9fc5df77e0726db388a7327a2b4bf4d2f81b26a4fafc7383970d4ef7b2ace91866618cc51e51966eee5723e219c2c8da621616d94a1b829f96695d3bcf1c5e701a0e7989ca284f4f8a0089a9cfe2bc98cc6d46d732a417da1f9f46721151dfaf96bee119ebcc355b9b899a15a58d8beab4c3cbdac6da3e124123a68284f4442d9e18381a92fb8d032d9dfbba7aac84ab327b057fa9e33e653d391c1b909629d410bead3e8db46bf7a10ff999b6adbcf9c8b2b411aba15633e7564c4c9843ea3c9d9b26277b49c65c701f14cc102fcda00a4c9fa3595bac1055490f8b1cfde75e1c44eb15fdddfee6ed20ca9cc66fed32165c22b864921c69e4430679f1acf4c25732582a9a3e3bc2ccc524670968a041e784356348b4272bd756b41003026155050a9adf39c81aaac633c2ae453706b7c214d98b34ae87d4c391d049d357e62bda59599db6a816c84393884961ec9db3470ab2bd99a2db2c81c350e6b19d5f8f44d1a507b7555acf83fe2b21f30f5168348b07fae23d50b77b3a3aa3120e9acf650aaf77c526974260c607c77f7801636ce2c2b3decd2c4f2a868c31494a3ae1a9b3eb0b80a56e231e0120d57f3803ee5e050ab86059d9e5a094f9126de892608ed3083b121d1c3cf4a2c113eb7da787d279d9c5087bee5e381cb7911d7547e75bd2a71d3229f7fae4f546023b420950acdd6dd900b9a5104b2673c2b7a69529eeece9a10a114e741fc4d5db5cacea392881f097b934399585e34b1cef20d05e8d992ede2848220a9c770e3f706576e09bfbd937d115d5435bdd6770a7be580df35477e48243c7d67da58c4b3f113e30eec4f995a36b58688b0c5397f76c3e11de8ffc22591ee4372568b076c77b8cb16918bf835489abab23a12653671bc2f30baaf4e75b74323ba72bb83020c7450b0e526f5ff2d46a563843471c5e0a20deb84e94aae718979cc7f80e2dcc6e0fe275066ac398f8bf9234ef31cfe0f7a7cbfc8a990231726a270eadfdde087b2c5ebb5e4767248849ab0e051ca1240c826a6536c1edc907aff2077c2d613da4d9c89a0c2e95ca2c58a238d94d485be6406c3fcfddb5978108aa3e392192ccdb4a17d3256340f7e9207cbbe293c200e9593d6c55aead3f54da81351ddead8bf6332c9f4944259fcdf2f313e897292d78cb405a1a66e3d8ac8ade847f35d3e5c0fb5d897ea07c25c391d9e42f6d69e591a836f380fa4f34b73e58610c42359e3f38246ead4ebd69de4275fa023b181ac60b6d976637653de4a81610d94bfa03e9ba25f9f99de6ea8fc5600c2e5f14a36f0b0f61d445dff6ef86ce9ca1b599c353373466fc47dc19be1fdc0beddea45a2797033e63251d4fa33868e630d992f78c339ef11fd92bca66b32479dbf92697b7e8669bde9ef2b39743da2a6a68f906cf27edc44026e5f8835ce71f46ad750f1e845eb90ff74c27c7e4283bbbe37682abb550ca8e0aeb2b70864b296720c3a29d05ca01c1b474942def66859419dccc37be3cb5fa2a5da0e238abdac9176ca3fb342259ecc10c8e294ac87ea12d0d614d15e603a438848e8386b39324e15b68e46fd1288a7ce261e4434b6f41aaf64de6914d1b444f59da7d5c8ca0febdf190e5616a57cffc42af2cecc654cca81efa251b5fd97090744069d4adcd36b67b346446c9c41883b9a1e4d7c90a4d705b343c31a4834001489cf9169419420d891ab0b4b1f78fcdc29952e85e074746698ba3fad9538d8d3febfe38a213a9538a323db9f43f9c0e7e2b9ac606d16977906ecded9b2579fe059cdc7c8bd706b19895db5dc1b1a9a9d76e1475e695b68ade8f2a0a4470253643d99ff64e0242a042f7134a0cede28b3773ace0d1886f055c128b1127bb72ff58472b3fbb357e6816ff0f8a637bea0685c239377c16432fd918980c8932760c08488b85635bd4ed8d07f3f7f2fc8345e326d811b2e7c43d7c06e692a4d16c5e5f62d979373b6f831f941b48ddb5e5a6f2c6a2ca9dda3ceeae70a9eadf7888d816ed8313c975fa948213781be7a9350af17607e902f7e6f944822322bb885c1e21a370a15128e903376711ae4d0f3a0a82c6d40765307fc2bc1fc2bde0ff4829952f22d618c9aa447e3552bc353aaec1272e5471d0de4484e135e416953a4a0b73483dce11472c3f3065a0d1479924f6f0939838c35afc6e2ac6e442a6c0b6c8fbdea829de695d26876856e50a87ee3c500818bed4505578d318e5e8a7eabb0fa37429995ba630738dd248c68ae96e15c9b91e9f7bd8409f28da82ca4fcec5371a56fd11c7346c2e158d3cc2a201fb3c9c1ff445994ec8307f0e04fd081b3800fd6804a57e97195bf5af69de73ed74da7d6d79f6b60fd5a7172c0a05da505c7d1a5d42ad0169f09e8f06d761559a5ad1aa0292144183f168b16edb23178fc37cd69549dd1f295eb3ac1717c4d7264c566d7b1f4cfcaeceac67e0a23af1f1d015d130e324933d0bfc555719726d6558d949082cf4c8a1a4d675a7d5de95bea64d058903d757baaf95cd003ee495b2cf8ccfae950b37cf92482695b338b34d673287ebe10954d0fd57e4dc2443f099b2ed66815dd979c72b1b1ebb8c0e906a5c6c1ecd4eb3f0551eaa83efd680e3a0d8e973fab72a37b3ba0036f0dc6226f49220badceac1df6accc5165754a15f864a5016f705ea3db451bf1039d623aa54c1676e7b5209ca53ad575827328daa51bcb316f55f1acd6f50e7e80888224a9b00cd5f1554f9c1d817475900402e429b4232e34d190d28e10c89ae2d8eca07253f37021bb8c4b180da854ae2bdade8c2d8c4a61295db236b15001a8905401acdb008c8faea2b7801b1d63909cc4d075f61ef1fec1eb4d071f0b2b360afa2cdef866377617d6d7c574622026a90d2bd6ff9bb14b54319cb14e24c0d788ab82aba96b563a953dbb465d8e3425b280c277711fc691bf61abd83b7896b543dbece055618fc9c95e1662c55821aa3990f33c2f2d77640e3f316d8f9ce258d14cebfd934a1f7abe51e3de00757c4c739c7a721b97388983b5af4c71bbf5e7d7a620c2397b5a27921ab57cc78c9bc543e9349aac14dc1f077fc50ffafcf2237fdc105a659c8bee5b3fae351dddb067bc6bee552eb36989f6d8e4dcb2730068e4dd8271f9ecd3f46f18731c2f47a9f6a059587d37766e84f2bb2c8c32375fb89f012e0127e7d2637c0618f77bd464da4742dbfd4bde65eda98385e41f7d9330da7af57250efb3424d790b1be60ff4c18c2422feb0c630d530b94bd6bb81f9239528569c6b542bb41aa86cd680aba1aa59618a11d460b32f81207b5a70d5ac5595bf19e9594d2bca4af85e4989fcbb175108a9ebf61075fa0d16cbe420f4b9f350bb141ada1499b4480c1cbbddea0708914932621186b4517970637aa40808914fad5727b6eb949a60f8ac3aebc18c66c3e623cca8ca0f51823633b488d4268ed01069ae70a2acf213c5a915f4b5170d01fecda19b8f1a0bfba2264dae0b97c394c473bf39db5be11c50c4aa77b0e7b2c2ee65cf96ac2f0502e455032a41d7b35c20cc59451dd40e978334902c07e15d18bce9d600a41b8dc742351a088416d3bed988622a8a590fb1c9899778bae1bb9523f340fad9c50946bf5df00e5fb86ed2fb1d79ceee810704d8b197c779dcd7f3e897a46bc9de7b6f29939401820a2a0b680ba39dcd72264751c4168f78c4e3cd36e3d9ac2c45d5be5a5e91887befbdf742f9a47ae2d5dd1d2f0fafb23cc053655003cf1663dbade96f2e97cbf5701110d46a9bcb1a6329fea8ba72ce244966f2e648922473cea5bacdb73fd37cac62759b6aa9beff3cc0389ff1d0ab1bf67a38cff9cf82e8d4ac09bdcd501dfff10715ca80d1a2ea4267ca553ec4a60e22c0e8ed250a3d38b9d2db7b62265f2d44354cb614a1b7e7c6578b9c6f30c14918bdaf3057dd709d71cc41af167924df7f5413a38a8c37400cd601c4abaf623e2ccfebf0e8e8bccedb2f314e84200eb8678af8207b9e1761e7653cea081e67c96e67e77754cfe9a4370b1f5dd447352e5bdbe34f5ffb46a6b4fd45c1d13b0bb5fd1519eabcb32beed09eb80cf0d5797788eebc1ba530ce4ee901cca12ffaa4306ec50b3e40fd7e18e762bd2f4e89408c83f100840fbbdc7a5f0c629cfde58259887126826033842fb7decf438c73d164ce7ac511fb1dea8baa5b14eafb1e605cbe8aa930f5de9cbea608a5ef93eabe3c7da7f4cebb5e9612de17873b8cbb543ea408d7fb9997aff0a81b7ba354ee8957764dfac284a7d357dce99b77220fab5bcce9fb56dd396b44afd8e547eb35708f0188ce9f3dcdef7abd699aafd49e0e82a8f32866cf3f74bfb6d4ec4777b52ffc03fa59db2a451081e136ab77b47542a404edd774cc73d9dace1758813892e4bfcda6a6c06633528a81739712c1608d4d166be328021147123416f6c40f8e913ca1a8b68ba5b25370e66f16ba25ed3867fedb6cb75b93b6b5214baa1498224769be8917a6331569fb576db98864675c27cd3dcbbec3719ccdb33c6b7cf11f1f21b9395f42b499dbd2a0f7f70c160bb2dac0d4367bc24cccb3806ee8fd4344a03af7ba76787c6836786c8f4e656ec33521b29e4b43a6bb3addc266448f0f4fcd6d41467c7c69ffce5292deafc9b2246db6db4d934a4f3f332a1d20f096660684028f8c00da1fabe9fd7a2ccfd9ecdfb3ec89590f4142b01a893742b4978cf6ab4d2501979080a00dc139b3b2f4908f2122d794bf4a413f888a5a0bf0593d0b1fd96614bd7995906ef8f4b4ce540e6b48505295a491f0a25a671ab515417e144b48d4ba88c1a0945a89b32a6bbb73903d41440923db294b7a7b02077adfa882f3f5c3e2a3396805a775a6daa5a1b2d9ec95b31d9d34991ff9d71ce759b8fdda657af4ac2b473deb2603bdef3a3aad33d9b47d97eda802a31235126afa365b10d0ecc7e6d313b3d9643c3b3a28ec75ba5a369bcd669636d236da3000c37987fde8cbffc5d9ab4691e12a9dc951ff20493351cbdb024a9224a96e5114c51ff7ed893727b4bfb22c33f918cf66a31dd5adb14d63704549410179b221c0f9c076606f4b355b8b30ae1fa82b76fdba4c964becd78ea5de2e70de2c2c6a9aa669fa2d4bd9ac242f49925634c0bdaa1d495d5ebfd7afdf8bfd71c62216b18865497889e636bfe52d97b71a7aeff5f975f5030bb46569b65caef3b4544bd65a186c8cc562622c63bf317bc2b608bab4274c1375c97c0984112daa01dd378dfa7dd97cd7f15d6f17ae1a3ecfd70b06b3c56228aaa36381b7a5246b6532ecd77cbd5ceb64989001cab205cc9e983535611ee7b9a27df486ca744e1ebfa58ecece0e0f8f4c166b71f371a1e55902e5ab647f6787874766976c4f8fcda7366bf1f3e2c0b5cc9eb03f4b87e855373ab4aa8232f5ebf1b84f2174e960a9e976cf9bc9a057454b7214b31016121212f26b61b0ed420b39605cc76fe96d02fd63544b7cc4d3f373ef7541a1fb14af92cc85f6c8d0598fcfab458b9fa0202122d0abde9692c4a1a1a13c34847d68e80e0d0d0d599fd90ce8d52228484888461b1a72594b44545484b6f8d29e989d404157c862d81e416757d0290b9ac972168ebe6919d4d57dea1bf432c0d54231daab057aefbdf7e27cba9a6343e918f4aafb242afaf4d542bde4bdd69e6cce7befbd379f188dd9576a04eaeace3ed0921c4b98b0ed420ff90cfd0ccd808686868686827a8686868686fc56005bb7b8accb854e15d4f6452a2d667124f348966669b65c2dd7f9b2f6b42f1bbb9d3c60b0286d3fe6d336456dba1d4a5b1eda7acf6df6b3b01c86e7b0b2b0aea6a05001a14c41f95d1ebd7be3f26edc9d6369fbf8aacabe58e5c1922fdd5cd71de39cc5eb18e72c8a6316c79124cbd2244bd36cb55caeb3e53acfd70b068bbdce0b3b6f2c765e546767e7b436dda5ede939ad8fcf697f2e0fcf7953d98b03db73efbdaa03dd6651f85cd6da6bd5105cd65dbe5de87c95ee936174de206bebb61707a22eed891ff8736e8e1e5f11d059b15ac6ae7695a7a721b89a0421b03ee8f2950052df1fba20f747612e97cbade62b0146faaa24b87f733084baf54a808fbe6a08363075b627ee6f806a2b667f952f9284ed1268d8eb057b89b0d7eb057bbd60b0d7e97ac15aafd7cb086645ec37db1809732b8c314e5d34a0f74590f52eb1fb6b03f1af3d614370e7e0bc4710da00d5f6adde595f545b9cd56c4f94e0d343617075676dad0838c0babc4af73930656e2b5ddc7b7ff474fea88702e24f30ae2e16021cf4832b1d0faa763a08960470b170dbcfde96786a2d7a6e4e4d1293382555d4257e0f3e5d964f6caf1d4ff15af1baccf3049241016af57c2bc6337bc166b0d7eb63feb222a27bb6fff76d3769d0b4a3ee9b8eba6deafe98ba6730f564e1ad1e9e54b6442aca7a91fd1511115d19a2b118b27e940361f401817ab108e2d6b4745bd2fbe658f0e83dc1889a8468d4581c9150280c23868cc50d093d37041c5a55d16e4ee8b76dc945f323fbb3bfeb130adf34f16eec6c6c098bed96644bd2dbfe9668c040876e43341a15a1a0df9f2414a45a3f1adee084b0935a9d24aab76587a95fd3dbfe92b0ae3e70db7d9f97cff758cd63754bbb2cedb541ebb17ac3b5619958b0389afa3bcfd38c99ae173fe67a20e82de18565c2d636c3e28454d2de5cef3a8dc08586e9e084ccd7514fb7394f67e7e07695f2a3ea2ef505ba6df782a925aadc763eff2d08c8fe6a5709bf6afde80ac7df49b7158a20e7627adfdc8541e717dd56e50156774d63d3344dd3344dd3344dd3344dd3344dd3344dd3344dd3344dd3344dd33481ccccf4af12c69836c318d3f4beb95a97600742412f1412120a83828442e10fdd57b86f6e687555f543fb0192a1970782089c4200da0ce88c347fa3321a8b5ad08ff9b39909125a788018637c060131ee5d24024e17a903dbb94e17f836dbce0f2c1d810b0dbb4012eba8db49984a7495f205c6d471867f40b7652ab7f9ce773fdfe1b840dff90e07f4590664fda8bcc059d3d2ed0748f6f3030444b423229aa157c99ca9d98fcccf663e3f9025d96ae80e1897fde8dca59d02427eda0c8a751cd0cce512cffbe2a0f5a6ba4f6dfeec344182037b947f93424cb0c7cf637140afc1799e27ece634205dfaf5d63a9556e9fc57ecf12b01e7dfa91f8d73b19dbf4e3a8f3e7ed24983abf481eab63c1505c550d43b85ad0dff2c25735883eb64c91fec5a271d810bed7a7f2100a373e66897fa57e987711aa8bb545de30ccfd40bb465fe0cc4b82bc447f9b31028547140f74d97cbbf999fffc4697995ccf26ca5fb837314bf27bd5a965ecd935e6daf2eafd649af46d3ab6357bfae765d8d0b72ad6adc4f596ad79ba9bd4aaed3f53332f6db8436496853032126f4774c9bbf79f48669f34feb74855729bf697e36c922262849aa33b7e5306ef6f9ff3ae13973749106fa98c5cd1ea3f9b1650a3624ebe8623d1a62f604e3844855841629c208e61c2a66a6d6727cf34d5504f34755a8837104db43efc85aba5080163b68b958cd54a803b374b1126d41ad5d5ba2280a75307eeb5baa08ad1fdfc54aa6421d90ef7a972a82ebc977b1ba5ce9dbbaa02d222ea875db5d6feab68d7ee0587635adabc0698d0623a7ef3b61c2335aa273ce6648ba81ee92e74c6165a28a1012a3127ece231cec8592038c95d5756764f458c9d466b959ef93322f60ad2e7c8ee99d21c3ca6a25533bc5c3eab2e29d2224861c2b99da2a2bab0be8144a7214c404907649c08ae1855584116640842bf923dc281beb98d904ad56114620b192aa751532c67554adabb043b4293ff0f0a3e5142958f9ad2ea2f3beb30933945a7194363ca6ae9ab748596ff08852182530298c4031ce4ee14dedd61f1b1ce3d0eb2482fb94a8a921b78ed0d2c25b830819c056e9fbb64adfed42498b93dceaaa9d29caa0d9615836644988f81c19c69040e91cf9015665e42956448d8b063409d68f949053490a5a46a2e848c5408fb08149f9503b92431092140025e9018604078f92283b455029393f48aee82819c28e0811fb622ac92166240518122433253fd1c80d4148c2c8928c8949f1701d910195521233920586232675065582024f122d4758801951b35384cca9444b7924064c490c3c4570bca2aa5c44a488437c98446028a3905c79153187cc907f6511dd6bc8d3586408932ce24389dc400e715312a10a1a624546adc94374d8611353521229614705344a86d71021446e9043c2b488d0500e5143f27002f18a6a131bb2a58cc2c15564ca8cfa220e319f642267cc21c056911bc42146ca23a2d06022534a677269fb9667fc8d39d1850e7c0b145ec1fc0a7d8d3bd30a49e0ce7de295ff6e6e04febcf713e21f292c7322b0dc61e028bcbd7aa2effa7a39bc23af7aa38ffc9dd8777b18e739581a35d7dd1d632b7ded8a6b87c0d06edd88cb45037afdfa891ddb13f9955f1b5c7b42c422c61ca05af5142ec7802ae37b7189dfbf5ca2dded7db57035ae98b8cbd93d97270f8d71b62bec5ffb6aa18a3bb75d372fcc7092830d14e4a870040d2366085170e2f3f2a2088aa9ad131f15a9ad4a16c04542dd20d0245cea5b67cad61fe7b2442db557e9df3a531ecb53e69fa2b20a8c52ebb9f5d6998ede3f8f65eb9cbd7f11ed8f6cd67339f4d6994cbc7f1ecbd609436b49fe44b624134847b60a8c4ad4544f4fbc7f1ecbd609437764feb7267fda52d389241348d67379a2416f9d49e9fdf358b64e18ba23f3997d40d3fe2c06e02fa4c10094509c4832817464abc0a8444df534c5fbe7b16c9d307447e6330ba2114001fe400750408a9b128a1349d67379a2b2d9cf5b67bae0fdf358b64e18ba23f39905d188bea6fd3b9880ffec0113b8c0821437251427ace7f24465331af9fe792c5b270cdd91f9cc826844afd63cd80012d4df07031b50b1748105296e4a28ace7f2446533da7b2ac3a13891c4644205d2d2d105360b2a4861742ba154fb0004ff1e1080806352b1748105296e4ad67379a2b219ed6b9e8e00504271a2290967820949c5d192ed820a2c304a51e2567bf70f21e7cff3f6c58108390034e198542c5d60418a9bf55c9ea86c46fb9acd539db7cee4f4fe792c5b270cdd91f9cc826844afd68c6c4849286e4b3068f8efe86838ad0040138e49c5d20516a4b829a138916402e9c8568151899aea2906ef9fc7b275c2d01d99cf2c8846f46acdc8869484e266c152d38e7704f5476ff03060e1b402004d3826154b1758603d97272a9bd1be664bbabd4e4f6101b020c52d03250c50b038e1f4feb3201ad1ab35231b52128a9b054b4c4d1fb078e2e11febf108400618b0705a0180261c938aa50bace7f2446533dad76c49b7254fb3bec082141adc02a094010a0c4eb0487232b1020900474d365c054c462a4a2cd546289fff0b884f6b10800c3060e1b402004d3826154bd67379a2b219ed6bb6a4db5253ecf4d4f5d69904f0fef93a2dbdff789d2eb0e0fd5bd7694df1feb0eba4df1fbd4eb7f7dfb94e1abcbfec3a29bdbfcf750ac0fbcfae138af70fba4e19bc3fed3a9d787fa2eb84c1fbff754a7a7ff53ab178ffda7532f1fe46d7c909e9fd91aed38af74fba4e47ef8fe23a01e0fd6fd7c9f6fe165ca7a6f75fba4e15bc3fd375c2bd7fd375327aff15d789e9fd595ca712ef9fc17552f1fe1a5ca7da8d4aef12ff534abd4b0490aea3f6d72dedaf410076b47f063eda1f8320edcf8248fb3ba9da7f8591f6070092f66f42a1fd7116687f2626edaf6285f65f4aed55f2bf20f5abe46f419aaf927f8ab4bc4afeb7542945af923f8a547695fc4fa4b3abe49f94d2ae92bf89f4af923f525abb4afe47a9ed2af9dbd2a4abe45f417abb4afe46e9d255f22f91365d25ff5acae22ab92a3b5d35a0a84b1cc9d26cb9ce172c86eee8c048a46a9aa69f16a57b3694d2d27ddb2cb685324bb7a5d2f87ff0fba43de9b6561abf2cdd164be3e749b7cdd21886c6af83a64f1a3f0c6adf287d97e09fdd08e04108bbbca22d75bfcd547793fd95eab6401b24d551dd37a713d57d79bd7d7dfa264db96c4d6d01d33ee9e64c58085ffc5e8e64cee5488ee398cb91ccb91cc9711c733992399723398e63bee907a6fdb1d0f8bd1cc99ccb911cc731833042f958942399733992e33866164f3c9abc1cc99ccb911cc7319b4be548e65c8ee4388e7989c6cdcb91ccb91cc9711c733992399723398e632e4732e77224c771ccb9242f4732e77224c771cc495658362f4732e77224c771cc36e1b0e6e548e65c8ee4388ef9831a5597c7efe548e65c8ee4388e190471d3b4f8ad3197188fb9cc39e3990c3d73ce2a56dd84b2815908208040769b357d200b41e30741e37224cb911cc7717c274b932ccdf2cb59a98670ce40c80fc2b945d025ced915444404add1de769d32b84afe654a4bbf56c403dd1968ff3183eb24aaf62a617c3aceaefe77c70cbbe5c80b296d56909a636415835a7c418b28646449a2a6078f5f142d2ce435566690a10d0d64cc647943837421898ec8550e3288b182e54d8c34bb29554b56903ac2062a3964065458628236f0680343106c4852acc22128670d9a16c0007145da1e80c8b5c0438c1150bd2b6598aaccf074668c0fbb1dc0aa23533c64612204101c575686c099a0468e0d4286e0f0429520e922852e6f72ac70028c2c6ca80021ba817155839c1ad6b440c39429a2288aa228ea40040a54d0e880e605333ff0f0b57ff1dc411591c6461b2162d6ec83ce3f9d73cea2288aa298a489912b2798b11292c47b70930437ae3dda3a91e1041e222a09ea0cabd4cc8bac2b1f328490d19a9261c6913145864f8609478669848c2732701647b2345baef3a5d3e3e136f7b9ed46b9cddff358b64e186a6f94e3eeefb704ca71d7e7f33d39eef67a3c768ebbbbdd85e1b89ba3a1ed87f081e33cf0c0710ac047fe58f6f6c78ce64ce58fafd91f7f5b6a72a61fcfc2995eb01f4f00678aa16f5f01416fbf0367d279fb0f70a69db73f0167faa1fb55e8eda7bdfbb350eebde5abc53d82061f0823a986d76331a66f72ec9a44dd8da5ace6885cddb09c1ec2244fe1a0e913ba2ff076f9a1fb95f63cef7fa93c03dafb5fa033f1d0785a62d07327fd21f4463a219d212a4b7f04bd912ec8e58a996a501ad01be9805e56d0da8fd91be966af970b0834c9e636fff1f3635241976e6ef31f3e3e96c4425934b9cd7ff47c8f88033a801fb237d25d2a3fbac015d003b8cd9f006ef3d791c1c49334594fd2d478216218f2bc6972c51d6d74c4da0059a2053646caeef024cac60ebc2657a6b27298593314b9002f851d478ce88218712955799883a5aa81f4818d2faa284bef4a8e109ff9ea4adb78a52e9468809ff7461092bd4c7ace7a2e3792427755038d7ff7272c93b8acb6e697ba9de941e9364bbb1dce824d5ac4b3198afa85d2fed3e2af258e20cce5ac508b2e7af6878022fc177b36e3b2d862fb98fc22f79114c7573dc0aba0f6efd9619cb6e12a3706c75005366b0ebd7b7827d8a1c995188c88a143c6ba7b7a9aa7770f54d2950a5474594a7858adbbc7e782de3d52da7ff7fcb4ffee813246e9a93146e9b1d193ebd169efa1318535052728130687c12bed2f83c2381731c24cb901cacb0f4684ac2de82df315210306166c58a2a6c6ba65521ae3d05bf62b929542929e1aa08e75cb6ee82d036aff2d0b6adfb22ea30e598f5187ec878c27eb01e92de331f66434c69eec862fcb27cb6d994efbf3fc30cec593951d67726489e184322b0b7af34ccd30860a18149e788962c3ba79807a05bd7982082032e7c8092f549841c8ba7954d09b67a8fd37cf150fd61a1e266b789af0f878a4b4f388593c6216cfa8e319753ca38e67278871299c12b85061d31b23c43bbd77d4e40893664dcec81632ebde196a1b7aef5c4d400629147ce4baec08b2ee9d2c9d82de3c39edbf7974da7ff3d0c0b28305cb8e969da91da0f61daae0922094e18e6fef48697f9d2b8c83400f5a9854ada9f16bb2e21a7aeb6c29f20688304f65daf858f74e8e86de3b3a0708717246386307189ed6bdb34341ef1d5e8f87f6df3b503b40c4203a66c4203a6874843a43ed3a56a24f87cad7e5a7f3fbe94cfd80da5f478771568e9424249ce0c3148d124ed05b6767c20c99253f689022e58675ebf0b4097aebf4703cc9b98a01c4c90d32ebd681d23abd757cda7feb4869df3a4b70e8c4c0a133c30a0b8e761d18220f0d8a3c5428f286da1fed61dc0a83eac96e871c1d7a2b9ea1378ac5081ea66ea4a0838da875a33e2d436f54aa05c41597286a8850b265dde82f86dee894f6df2850a354620c54871803dd81c24069a037b4a34fa22e962585712e7ce86cc8b041851f479cb0c2d03bf6fb5923430a1141cc21d364ddb1a9177ac7807b8ac70b7290a430049a75c782ba04bd63c2a195f6dfb1ab18969758112fb12331a8984f7b2c4a187b12c6785cc57457b1dd558ca7fd61408c73b16308d50e47600189a8c124e80d0bc2b0a3d2a1431703140feb8609714e6fd8b00a09951ea8c84c91938275c3e6e80ddbb1188c22302a456056603fd89476d814295894146cc914ac37058382f9b4ff6b88712e9a0451c20e2345a2b4e890a3f7ebca043a60b901072f0b971fd6fdcad271f48689b942058798a7184480ac1ba683a3376c7783de301eec29d7788dc9355e645ec19750fbab2aef5e535e54b9f7927afdf26b4afbbf7218775550e2e4ca9ba7ac39eb1bbd5f3aedbc145e2c01e2451160d6fddab9d1fbc5539f9cb440c3191e5e08b1ee571bbd5f50da7fbf7cafa83171c6ccb9cad27ec2199e55c3d32aeb04669dc12ca1f63f7918e7e2871b334222acbc59e188354befb3e7019829210e2a1c5a0062dd27141bbd4f1f1a1678109a70264c0deb3ea552a0f7f9d3fefb9c3aa75c39715cd1f7f7e98276c13973a7eedca17a9f37a8aca8b0b4bfcb87712e4890423363481318ac80ac6bf476b93012e3c91a2d504d8cd0b06e1796de2e2d63866a5648014c8c34eb76a9f1df2e218e5cb7ab0a337105c14c5c425c375c4f2e1ea7de2e20f8e782817f3480c2ab56166e67dd2d3818472b0ac6d192d2926afdb4b7a0605e0b082f4a3b143ec2ad1e6e0931ce850bc2334d8218e105051fd623f4368746dc049126cb1a1cb0acdbbc4aa3b79955a5cc0c573c20094324c8ba5b577ab774da7fb776ad1b6ec6f4e266cc2f26d00c6a37bb5c9950fc6a8af6377da6d4367fdabfccc2383bf461f93043e3c98696158dde66ce4e09218ca1460c9b9c6fdda6ee8cdee64e7b0d35783e72e0d2244a93759b66f4367bda7f9b5026102c6bb0b029bb945556da4bac6039152c81c1a0f62f7718575af1f144881833b08258adf42e79598260434557e5f3a1cabacb9e117a9766e01c41454610389cf1adbb2ca37729a5fd77f92ba1ec50d6d8a1b48105a78421a47749038a1fdddf6495762856be1f090ca33719d4be6eb28bf7207b780ff2074983bc413e69ff4df280ca8222739bd44d614084114eb0449d6075c2ba47a02e42ef3138d4fe7bbc1ab1e28c4ce28c4d46df28a57d5ce2b991470e88f61f77236f8f3ded20303324492e8735715058877a8b46ac80c30b3324e400c4c8bac52119bdc5abd91b2961649409734388758b5944f81e75238d312296315aca758b4bb60845bb3845bb48a57d888f7cc39ca5137940df220f266698a0c9c26190ded9ea97a97eb90b30ff80790a0804e30608e0902668b6ac3b8fd13bf77696dad13b2fc19163e0d0f7779e919573da330ced3c6cc5c382c241ed58e842071d32f42893c6cc0b1e6b95de182abd2108205d789070e4ccbab14f8cde58ca49ae4c0e090d412552d68d7f61f4c6534636a6ba31b08e1b43dfdf7887c630b4bfdd58877798a73dcba530ce5a098961aa87353bf0c06405a3b7ff4a807983c310bb304760acdba7844ec5820b319c19daa05ab707f517bd5d38b4f22b526fc7a28017b15e8e385494f627ed3c78dab7efb4ebac930aab44458595a628ed4d4b44de0a59b2f818a690c33a84de3738ccf2b11dc63a45dffb76bfc868ff0c58a79755baef7a5f9e178d0229283e2938d82027c6baafae8bdef60a1643460e34360c093659fd27e038bb1ea00967ed32bee48045b5054cf0caea5cb48b1e5747f410e64a162c6e56dfe22287325582f0e2e480e2b2ba104ca3f657cda04a24a0dbb5d3f751c8a961a1bb35d4f76b6ad0ddcad2f753d480a68042770ba8efdbd8a0bb95d3f76d2940776ba7efa76801dd6650df4f8103dde650df375102bacd9fbe7f4402ba4d287d7f48886e73a7ef0f59a1bbccd2f7915280ee52a8ef979881ee724adf47ba4277e9d377ca8f9d26c97ff26d78467326176bf9b1578b12f66a41061581ee92a7efa78882ee32a7ef0f55a19b1ceafb29a2d04d02f57da439e826a5f47d5a0d74933d7df7e9e587274368fc65128d1ffd010a0f1affe0638ac6ff7ab5c0363d3e3a468fe3f8b671fcd94def53e3a72e1a0ba171151d4534fef3d502a3e497d6f56a41b65e2dc65a10748f57fabead0cbac7297ddf5604bac7a0be1f1485eeb1a7ef071141955a40b798a5ef2bdd40f7a8d3f76f57e81683c320314080e95242e3378fc8a05bf4e9fb4744a05bfce9fb331e505115a360d7cf99ac0f5576686a1a7f8904447716eafb4856d0211ee8ce52fafe100de8ce53fa7e900fb407ba734fdfb7c540371eeafb3618e8c6595cac74c9014963268bc5063d8a484ed08d79fa3ed20fdd184adf27c105dd7ea5ef93d8826e9cd3f7512041b707f5fda127e876287dffc604dd9ed3f76f4bd0ed3b7dbf66028aee40d118d05b18f40606dd174ab7d1f965355bfe19cd715e459bd0a2c50dd5e871a3975bf197166757ecaf16f9ea30ced5c347f7afab175b836e574fdfdf2e297ddf25e54c4bee153940b4aa3176413953ef1607fd1b1cf49c839e72d05b0e559a53414ebb801f887ad1f04ddd6c7fb35d12bc84e05530887759474fca27ba807f418df1efd734a6000492324aa4172ef389e7836a1da1711db9190683c39385f34a9779af1a3cdf0d980a31a41be80b2fddd8d35d9dce0ea89fd4ce0952c026cc830210283bfa017b6640fd6cef836403eae7fa39aa22059cd2f85d3318b2c65d561610520b407138250886d0110f3cdf8c7644e51ce686743d2917518c17701c669ec6ef2ae205af82c1cf21ccbaaa0a12509b2299707df7ef94bef7fefd571715bfc8c3b8b32783a2f944298d4f9f2328fea339b953f70aba48e47a525f3b7d8ea04838501b44189fb67ff29c69bf867a1c6afcafa133ed5750e3c7ffea624bfcbac272b97ea0d773ceee6f67492da0a3deafed1654e405357ea0be39bbc5476e94138b9871a497039a4204911c5388209263bd249c0c7d58302aa35404295ea1a0a4c93ac2cf708591cacd3ac2d0d43acef4c5b81437640cd792cc3e1f737aeb98fa151dab08b74910619aac23e42b7156f2c754040b0497758413a8be0a78c010400d08e005bda54df8c85fa90b7a2353d79530c4d43aa6970417566fc1841aa0d631bd466eac2eb2cc5ea60c99e03aa6178d95d5d53aed7d71c297e03a065946310621da6431020607197284b09a01e6e39980cc1a3725d000d38209eb189462441c538a958ca7f2c90c2d4f66fc744cdb273372c0d222813241a498e111216c83b3a0985a41890e5e7468c30563f91c3e6e70128304333a48cd9a4c692b84b64e74b0d2285902d15dea7bee406966d03dbb679660e90cb475b2244a0b39404784116e1042aab7eabc75287f2dc0ae3a3a2aea630b2eff5d9b31c619bf288ee2288ea288313e4770b5891ca8433910ddbbcd86d51a0d74a3da51d47fe39af147f2fdfe78bd063eaba1b85aabd63f805d61daa3fb68e9692c15f277fd5d61a990fff9792553215737c01abfeb99945bd9d2b60a9b307aa33717ba65a6dba64d9254b76961697eb568fd7d6d805be29b1fd8f4f84ebe7d3939fa4b5df2a352bf44f556ea2012d40cb537dd520dec89fb4126a0af77e9d2b64a1a2edad5b2e5a3ce95b3bbbb6aff031f82c06daeba75b76e1de79cf39679ead302ea3f8b01bb19c9b224c72360a46024c9f1861646b2345b2db32447373c18e2a3214772446a73de7b84d5187224c714aecfaac84896a65992a38e23ac46921c7f7073a507940c7224c7204fba287132a6857194338e24902339c6c87ee443e6c3921eb21c6a0e21d345a920eb61c90e16a8e43568016a1af4be5f6bcb6ff3e3fb982471b624eaf9b105f47d2c922ef4bd591473a431ce30ac8abba8968b3abb02bffd8b44dfb7d7ae660e9e7b6d30a4af6afaec097f211d39b727448c028d5da38f26c8246f07a4332d4ecce1231773624ecca91520dfe5d75e0ccbea25f36adf3566ecb04cbe38b062f4f8fedae0c82c4bcfb0b195fbe112eae1abd376e31745f1e6b2548f30bea9601d70577fd77b04fdc3d511ae63ac273213d0d7151ca83975062d7f3a5c64317ec860a0798d4e148a8fd8510115bfc84e40c2e31123532303fa06e5624386c30bb21725047770f4d8a0838605ab305b60d8c981eee830859646748aa0a490aa730679a3e7c6a07ed436385c799566e0ace2766bd5da647189d45b0c92297010472d1700816e83339236b500a780812c53e017a54906bd7131421c4a63b6b42801812d24362d170a9bcba0322eff62b1de62d0bba43072be92c4da90170c8d8961cc76061643fab7d96e370f3a12438f94624075e6d8e0ec689cc3d2d92153411517ed2f1e0d7778d818fd8c0a4f09a1f6ac149388231383b591851185f185f866a74667c59036dbedd6d4342251f5a438d221f165b431ce10e7b0415392c9123d2bfb10945da16afb60c4a03d1164c3cfec4b1a0cb66c26cc807e44120254f4454c172345091222831291f8820ae5d36d2874a00d896866b42128434442312a444552f4f62cfb3ec7e244213e22fec642c6dff807f91bef10832e5cd9d02e0e6790627076d37b36f2b4bf18c447a80c62b0e8bf0005833ac33fc539b64f6740a88e18b447fed6bec8c5e23c4b7c3353831a518a6232e6a5ea69456f3168c52fda4b40ed0a9cb6ef4ad5f48b88d2215a2a940601a5e92c4d7f529f9e589a653c3b3a689aa6a959a6e428a6d8d3f4620026065f62306857d89e5c8a125caa1bf4be7525dd0e3537bf5248004a5b1c0c523cb1c8473054e4a1232ec848591694414628a5389254234254daae86ca202920a51db3f2b6e6271f15e133abd223877691b0c8f2500d3c4137ec5cdb093a483e3423f1e0ca24842d51c49edd1f7b391485ccb72a233a435011b9cc81de77ecb717e8fdf2838066294cc8003edafff5e680765546e5321163a603ba73920d7497474a486441773e8f4077a96d76858bd65aebd65a6bef0e97084028b5ff7d970c7497362b025283506aa10db0f7b02730072f6d55e725a580a23c06f85ae2233f4a82ee8c2e41793ce73953fe5d6a9d97d3582d5106e5c0753e9d9c2327a7b17aa6417799452cfab50f739d8b0861525b274b725e4a1b9aaf462bc8691790e90336dd81fc52b40b138430def8c008d1c604cc83ce34bb226b4bb59b11040e14354ad8ace33fe07afed1f5cbaa4bcab5440574bba4fc97b46dd2d655c4288eab88d11ca32a232b232ced4670a48c8052464129a1f637e2619cad92821738526478f283308ade463d3447a4a4c42899a2c2ba8da03414bd8d7cb92d4dd00c0922c30c69d66df4446fa39ff6df465346535c358c70b86a18b960a433da6937bae1dac171ed8c60b87ac32b57af4496f62fe1c338dbe5ca8b255a803f6a20013bd1bb846fcb0b6aac54ad80e5c5ba4beca07789a906ecc0c342048b1a2266d65de2a77789a0f6df258425aac6940832a6849012bd1250da4b001996b8312cf19455229755425762a7fd6b53403cb97253f5a3a189de3520961a2635048181cc9a75d7825a07bd6b3f64958172041161e204d75d63a277ed4afbef5a560d4e8b492d4a8b494d4a4d4afb4f7b0dcaaf06e4578b02d678c05aaf06a5fd490831ce0e212c22e4c7952531aad6257a9310ea40f5420c45b2f0725837892bad446f12595b786fa8a81932c5c2ba6b49f4aee9b4ffaeed6a375a3590f0d2aa81c4171250484c2141a59d440b088916107d7f9358a2fdd52c8cfbc091210c2266b06145b722d19b448ec44efb1b2b53c670598363ceba49f0b494de2436091240e2ac89c366788581de2a564eed92ab6aedd4a9d64e05b6766a50fbab3b8ccb808d174a644cd912c411bd552f47544172c6061abe2feb567bda88deaa7d93a5431539327a40a265dd6a11bd5529edbfd59f0ac5546b98aa0d35a7eab4ab3482f8c80cc219a6c2e17078a5fd53288c5b81c29cac5f112cdcc0244aefd40160825015c11a62820aeb4e89e89dfe56189cd4f025d7c40a9b75a743f44e81da7fa7c1b40b93b40793f4474a23bd913e694f79fcb27e692ed569ffff61dc8f1416568842254b9b22d61cf4fea967c1871edcbce0bde9d1c3badfa7f70fb5fffe2b2cb3c733317b7c93e7f1403e4afb2f31a1de847a13ea8b8218b7424e1a1b457038a1861d84e85de4e2c906126cb0d1029c15d0acbb0807bd8b461e0a37b8bc0903a565dd4541f4fe9cf6dfaf7b1a668d222c668d222d454b8aa0144d59d2bb88cadc154199bb22df2e9222cad215f1b4ff2eea15f15863660d1a222aa22e4455da89acb2887e5944535940ed4fa4c3380f50cda0d21d412487901588de443b385e6008b243814c967513f16ed09ba877e288950ebc34bd1a4dd64d046583de44be357a1349112df14214c30bd10c2b2c38da8960088782c221a170a8fd877a1867bd649541814b121276bfb506bd87a04a6832868d9a2f5f86f4d63d04a5f7909406e4d028218a90c90b22eb1efaa1f7d094f6df43c021aa28433aa20ced1882314463e8460abd879ea6685753b4aca9a19cf6a749619c15c286609037737a6d7ef0a137ed07d42ed4fe9b36d4fe9b665506a1152983d08ed09e683c6840b4d3a24a9aaea4ed4a1a4ffb0b0131ce6a6943c29c345cda38a9d1436fa1a0d05028ab4a6f5a8e06a3c42144a5c46145bb50949094d04f684abbd0149e508f2704b5857cda3f68887176c8c20c537c6082a5872f2b0fbd83ae2eb0f1338302950d6194ac3b284bd3a0b7508ec6973342b0f060268799750be9f40c7a0bedb4ff16e2093dc5091a1327884cd09420aaa02e28f40eaa2a83a4caa05f1934a5e3054169ff1de40b8a1a1367cc1ca02a2b2ced40708640c021507028d4fe403c8cb3728ee8a2be544163e58d0c7a03f5807cda898021851d622013e7c6ba81a47a7a03fd78d01b684a3bd0142a4038a800b900070806108d24bd816e0087c02b6096f69ff9300e045382d83862640b112ff00ebd6743ca1cd126852e3964e1b1ee198e41ef599a2a3162868849018fc6ba6740ad43ef5950fbef997056556416a4c84cc8ecc6ec69c6c384de332052b39cd44c27b5d3fe3f531897fef0222589148f2b403ce9fd0314fe5c69fffd93f50387d4f11385d4f123e507c84fd4cf12ed3f50c81f1ef9d3237fa0b4bf8f10e32c1a1c6cc0700299aba71d5618f4f6198e09e24b95135e8f20d4ba7f5ed0fb47a7fdf7cf4efbef9f1ba4093e5e48137cbef84099b27d80c0ed4375a4b74f1792864f144943dfdf3e4b723b9f9ef6df3e50dad7ed03c4cc1a336c744f971ee1f04a7b0fd655cf549e6ba854891bb06a1e430a8dd00c30000800d317002020180c0a265194c33018a8f80114800f57d4466062349587032946410619639001041000000084101828a2a1028567d1b226b4bd4aa59c74df112fe9e745961ab089a06531c51865e1868367715b8b3ee44983ebbca863a5773581d46121ca4663cba6cd4e0343c4d04673c1d5e7ac7d4ca5d49a8a52d86c639fed8a8b53ad8d484356b2f15da32175023c5fc1a1a3406aae947f48ed9b5b460b9a4d5bd7db88c6be3fe1c1ca7c60d8bfd9407f0c2509760f9f687fa5869b0978248ac902e205ce24157cc869dcdcc279362e2dc234c9d64ad65cf3bacc921ded1c2908afd2b8a90c0ced1d3b51b5ac94de5dd89131936765151e21bab3a28e5847cd3639f6d321ab887fbac5a7489530ee2052d3f73d3ec92aa346609b5bd42c5c733a10bdc4d189ee47eb5f105567229052bccd95dade9f3c9a3cb901f0de6ddfba5f1b3c0ba5a64046cd269ceee38df62d9d5759420046eb4a22e92f545c77935e85aa3873e962a4d61790ac017f8d8041b62b4c1d6d07a096110d7641b481ab4530c9240d7a106ca74b45111886559b373f21036996b03a3eface203126c1929a0290dc1cdd73498cbc29e224310f46d68cd41753b372cd27ea7672120712ca92066b3f3e342fe9cb3fe3979619c98399fa90d8cac953500bddfff3782a7673ef857c703a275484638e631d55bc5c8683ea81e3b2397812174e72ef64762d26bbac995189a33a50b9f1aba67050ffd359bbfca6bde5373d90dc96d312d0342c4dfa498d22973c4a2ad04b56fb8dc30c150b00998a885acc67c2b0bd4ace29bdec4c75e3484c2a5e642a47e31245a87e440544a057268c2353fb3372892516cd5782e6e25da7d3a25c45556c9e0f4ff21582cbb96192aeae59c05cb5e01c51f615802a46339bc463b0b84f264f2ecf6a93c4f09f00f63ffcb14f0420059e02a411e59cf116b0bc95778e49f28201595f96aac13a961b84ecbdc97228473f85a22a9d7c598e510a0c265ebc3b94131afb280b09b54470987f43b6f1e71c6bee53941322254474f2d010c398198da6561582dc7411df68d6599d2fadfa528ffdff6f9c95f985ee388ba1c500249e55d6b2cacafc1fddff87e4a4f43ba903975ad434713bb177a999b640a92aafd452a6bf4cb9d0538af63b4aad4f25d336a5789b5002998203eae2f7e737c5aef2444cafc3a383dc68eff571b06f34ebacb232ae8fcea11db5540ffd7bc70dbb47def4a5bc118c853a91177d6f9e43f3e80f8d47ffd102f536df9cc1631fbaf9a24ee4c5ef7d7e1855ea7bbca4b2f3d2cf131f950ab22af5dd04988070c6a17f9442154d9a892de5f2fc94b9b94e602c4b8ecc5db611f17526c389f751ba5c2f10d1a8077f8c1a48c942839843dd5f41271aeff52fd08538eb9759211e697a1999e804a12fb0e8c584dd2f985a6169b3e59578a6a020f341d1397d4e52e85a1ba67098f43b87735909425ac10f2175b1cfb46f35a17b6e7c7d2cd0101b81bde7894cdc708291c5237415eceec07282d278fe506cad1ccaade18bd176a20ea2030fa84a30c2158dae71c199330fdb114f199d9ae04a85062ba6e8c111e27863b4fc4c37eb1304b2e753bccc3122117b0d3147bb809f72d7847fedeb897fde4ea9aff7dff4e223f7ebcedb48d945a29e904eb2a694797707b43287e155a2a6e08777ec35167c8946eaa18dcb15bea2d20d87aadba98cc825b71ef8d46f3d64e7e5fa5c72591e78a45df446a5a579f472c9072d54a791f92676684950142d2aa602a91cc422bd3c44e8ff2025cb6a2ea81bdef5113c9f9f8fda7440866650176dfc4da3e4159f51b2c02345cd75e72bf41670993b0228bf78604d8d34c99bbf6e43ee982d81661ecd77386183097842cac467d0ee659e022248fbd1950e168a9b2a8f5587c04116ec5021d03074a5f6685c81f5a493c2294f99e43a7e43f17dbfc44a0ebf17455de1f77cae669e79e37450880ba930c10f9dea0d92c375067bf00f0e7e30c206fd543c432a57acb63b0bc3efa813c644fc73dd07b058fc8359eb3911bf7228c07ccd59c0f92c72ce021668fee6e8382a7f19d150f2f746529f09a0fda529f91bf3c084298937db7ceb9f032a3f1fc46598242a17d63190c43dcdab7d9331ac70f3808993201dd575d044aee4b6dbdbfc981a58d0111ff588a1d359b5fedf77d290ffd13442b56c90090e73c8fa2700f9ecede018d5cee57999d28dbd5b48b2dad44f39d44027c01feb69d853d488c0451d267dfb78c78ba0734921d160fc45cd86fb7d86b85552ad4662692d6df52b93006f7b1a373b7a6f3d5b77c80eb9e51a0f6d6eaadbecafe6aeb883808693df48b55a07e13d3f0706046950687b68f7ad37beca9641ff79a0c2e0b8402de30e4cef6a3b39897c2783f508e9497bbad79b0260778a527b07e189f7b2f918d0a13c8e5404d15d2f8ed982c379eaab88783372e8d074a9ddd99db710b6c1872f57e79cc91cb8737f0422c9d0ea5d62bab1a109148c24bb35e9cef7d2ef3f0155967cc64e075e0dec6f46d72d24c5be29b919f89dd651e4f522be9414b7455572a4c2aae1f57181b1d674e20b76e78bb6958d4d821c2016cf0a6a6a0a8d6e75be026dc4b689afdd3cd2cf2838ce73b38c1cc2733567d618944c7874d939629c762e6b24f211a07a54925c7000dc8d48db39a73b10191a48914541df8ad9918ea0c46241c2ffa4f8b8a24102e1b1912ff428964ebed4882f6b10a84aace2f59914e782ec559ae703b6b0dcf2b4c06800ada5fe480cf9705d8d1b339a5226c9cfa3a96457721029c1b6f5876809b0f7159d6d12484634c2110a0320b9499edae7d03057f54bc87d4a3ff5141e822e329513bf2a077be5c6ca62ab8a9a8a140fc9e54f0d717496273551e062372cd6ad0d4b85a207b9b009fd5cf7f61cb32780d619b7f9a0f9e8ce646ce5cfba5e12a0a639d3202e42dca0eaf9ba2f8323fd1a6dc34c58875bb4044b03893cc11fc7b77d6a20830f4e5b5a24437c4b87d7f5d96b2258860fe01f86796d1bd11536b125fdc8be02aa2efcfdbaa2e97dbc1b77978354f675e7dbde6fcd95d1b22d7501aac64268414c5bc939eb3020b137ca5722ab5c16909b976fec16e9390007d4b678ccc3e356ad977c784b40496f1bfeb27fc7649a0f1a28966fb1f834eba1753297e8604b5058a37de7c076deb2ea8e450b4b56b4e47f0e89f3021d5680f3f87e9ae0b97083d8d8aad8a9ce5f64d3f3fdfb057d7a0bfaf50b7bf50bde61473b77f6ec17ecdb2f74c7ce5edd027dfb85ec3c1d1470dcd98753508b830a1dc273677f4e413375accb2ba8c1a1426b71ee7011ec74f2f63b930d3d8ffd6a65965b9f5b5c017e0353b9df2c8fd9fbe21530d34e9e3b7abe4ce285a2466f9707a6b33deb6eaf450d2487afeff2ba21164091469c783bccef45e927b9fea057078f1233d69f0924248a1d6c2712ee45e89e39261d79392b51e82e2a670cbd7c8db998fce4305da877b85e3eb7574e3905c4286d6458a333cbde24a5623e325f5f96910ce1f53cb97816650b8eb3430e6a9892c282a237ed55ad9e3278835a83b5247e478877fb1a2a3eb90bf41361b9024dc17199ee9f1148f47824be669f6e43bfce83dce230c598b0db7b95f5a72baa661b1188ead1696108ec74f856efa6564ec5e523d757072e4955f913c109735d514c4009458b569a72eb621835b4813dc750b60562feee80d4f13955e79685e3bca22f843fdc393487af7c0daf7b34dce7d00adae649bbe62fbf98867f338aeddcfb9c697a5492a6aef43982f5f3e7bb02f0cda3cf2bf322b77922963d6a7a83207ac661b7c61e79450304608150da40dda562d261472254ecb95e7f88d2ec5de289fff0ad3f75c0fe0941996247d82a0a3d1b62411caeab5f5f50e22a0e3eb4158c5b95499550348ca6f91bff91dbc0db282cb24ea729667a0c71eeb6b631f2ae6b1d3bff222a210e534969d5766bca7212538918b2ef5477af396468fdaab81ec8d4876c9f4d1b941a03dfd012d79e234070d053757e72142ab2e49c9cad9a7aa907432dab14832def283cdaf021bc2aae20416f3fc979a87c7e0394666f3f2b98bf15bba04b262e3847251aa568a2044bf629f0cc3ff820a72baeda9c8e5841bc756f2c4cfd2e409aa563ed87425da2ba5a77ee11a129249a06df0f41444cafc91f0f45f3908f2acb21ba7f5587b3c5aded7a81a6586d3ee091c4984aa0edab4d921e3bd171d5e4aac059d120df811fb17cbb409e5770073682a8979aedb3997414dc2d13646e15eeefcace6113fe29e0f08a57361c1f87a3146be1171454897bbc2e96f66b97beb8135e545dae14fe51f1338c15b0f6d8b1e881cffa66df5aaf269736b56e488d29fe7ce176ceed92c7219b3053b15896195225be4a2d9a62808e7fa42d8fc273799b92a633ac81a5c6cd8ba6908b5e6b753b12093c56a4da3ec816672240c2a181f6127ee30250d426c0b99841b643840e848249cfff7d83443aa6de74654c12e0f48d39d6a2afc799949680c7106b74570a424f66936fa7b062973ea4fbddd33c27aaa21ca283efc9358d64317bb1c55e041ceea0e95d2b0caf7d7a65751410b5736848ed24f82b56eff78a68605126c998837017f1d99e7d646ff8a4cca18a7dd5a7a5e185383403d7a1c9c3782f604cf072c5747101f6c6e7f5a2921a086f60d5d7abe6acb1f4f2ac9c91c6e8f8e986014cada507ea12e471f4c21d016d2fbe187724a5699bae881d11f76f74b09aeb9a67ced28417b5331950e2fac3ca6691f83f4952c695e82906025c39f6abc9ac2ec43258a01b61340c22d7e5892dadd5cf5690697a600ceee77a0a4beb7afb5d35c314417af0ba2c5eb94b235589400af20760600b05d2681128575f6bf668b177ecd90fbbbf24dfc606f8902f4282f6888ce0eb82f6d858483e7c22da033e445f28373659cc196d6cb79ac686b11d0e432a823d35d8a303e5889bf581e6ec9ad382ce74cbef14f5c233c6ff6364bb69d4f660373eccb5aebc5befd1f13cbc787640e3bb8c104e2c63a8d43eb4ef8fd084b11e198d65cd9ce8d86b9d118bc8fcb308718c4a152cf0023f000a2f5b43782b4f985b25742f06388e3556ff9cd7f7954cd2f6d2ba79b82b25b7a98a20a5d4fcce6f14dabdce4016084a664ec485fcf738d55b832a3e75d080ddaf2e32e9566c3d66fc30dec78b722394df27d9e157ede7b68ece25f0a40f0264737e0e2f1389de87099e0a3b31c8daeb7333964662aca9bbbe3c7cf5f87c7a4e8afc65b9e702224d4fb1100f47d986d2a8ca60250de7f478bce06ef0ae81cfcde8e1b1d64d190224878754af858f2aa01282e74111eefc677c6018d8b48eba0e536944ad8e45c9205cae6f76a2d1b1410f67b8317e0259a84ea119b77c501a5234577202f09bed685de86aee0493b5e7bf743fef78d6395e5a2b5e800bb07a2a48be2126524ecae1f4b93a06e2ec6c08abd08fdfff615dd7bbc6e5921ebe320d757fb77ec0c4ffdb7c6f0d17596f7e514af4efeefede5a03e9bf6bd3b8ec19b9f1a96f0501f56eec721997db30d26154c2012a33c492b0e9c33a97d7bc63e168b10f6cbaa3537c321c78d6d6656fd040ec0d5129223d26cd445fe7094baf17f61b90212442c69599cbead1f48059a37fd37bfd4ab1affc0d7b8ec77622316b26d6d05ce27093ea064e3ba655870fc4936a21af4aa5c46a982c9d9d0d4a79afb583fa9345727c99ca696186cf96dff78eaa5db7fa415723431364c324eef73e0ae89f96e5f60b9876964558e239a85ee3655ae8c9355ea490997197a1610ddc19192342e89f3009165cb3a16e4e9be718bd02baa9b07c0d06449a47e9555c3564891d76b3b40cacb5ae403399194c1ece526b9392fd19c7b772bc50a8a4112450071e9db6471f26b2df469a28fd1a4763851322cb89d80f3caf01596740b5aacb4936c1fe70ae6f8e83faaf638a472abe4072b6ba0a07550d7b85ea0a5293fcad69b215605e162c3684da7e2844a9068ad9fe7af78d25b81ea379eb3fbf7a7d0ab175462d06e818e7a1d3a1ed6ffce0cb879661892ce96408c1197dd3eb7ebb45b47618447247a81e958468957239e9b68f20ca183c34688254011dc1f04f13f336e723fdafd02f7489c51c22c0c65caa1b3785b00f51720094e8ee82abb94c375dae55e40b25610a6b3314ac9b7a1d4852d4f1421616bce457d168bd575bd30834f7ac090f5fdaef2019e5e972330e2291e9abfce61973a275d580239dc0588a0bf20a0a0cbcb7ea1452396e555076f698c230d0409a394d059c2939b6b6068799c6561f881940d4783c7757f249c0e43150ebdb46a7bfa35ee8116270fdcc543c8c384c4ee3b6708268888c711c96badb4bd94f3ea1446cd28954d0dde9f6f0aa32d958cbc888c9007ec16fbf9781d2affc84bfc4fd61b22591fa2f3394a26eeec3621a9691b98ba1191f6a26e202485d91f707e6338a442da1af8c0736f28542e60c7709bd07d65a60ecdc35ec16758404a8485091a777335c80e28c74f8d274a72e0cdfe023daa9bcfcea45ed1eb15e6b717ea7fd344d9d949ed93be01e4a61c3fc3e9dd269151dd5a16d55432033c79990f314d8b13f11d34112a1913e31b0cfc2087951b224bba2656bf57548143e0e66c20d7c807763135f7f1ede1edde019f061a58f1b8d5b20d0a3f320bee3ee0014084a2ff19bd6e55aea5130ea93410c87393729020cde15958ce506af4bfd1fccd2a569747df2db5e50a551de30b02de3170dac3d52217c0313adbd213cb0b7a3d8f59dfd57de8939fd884815ed9d67909cf4db43bcf71c33a7122b9655459c1000ab2bb3556c404f9d6349babae05d1c69c1e532bdf64cc952f0df2de1e2d4418711d670653b40b2442d89efe14e07ff641adc805998984b362f5da445067e2154e56b158dc9c51fd3373d76646497ad798ee7aea6c6f625819ff2e7a76c623c46806cca3bfb9861ac348d2523f8ad089cac7f642f883e9577e9630a8c6c4d402538b42b4da3bdd853984d76602be7ca06bb7fe9291e426c25456e3692bf8608c0634ada05c8786818290a87e1c8c1f22d19552f452239ee72e1cfb9b340252d1cece58c3645353ab8ef9702a93236a55a10c50f7de444211a462c2c00a585328d0ec47c5cd323a43f0cb798160bd190c813076ed7080659baa38fccbda191699185cd64e8e69b4983b739d2cc9c3edbc266364a87b235896d7e6735a8775e89538e42f099a39e889dc6c51b4edc2967959a2980fa00e5671ec08b48fde8f9022f1753013a5faebf182b007d4249c70ffb9985c7b6a8849f8699cccbfb6641934059925bbb51f0385499a48b2762871a96cfb3476c322c7f186314439a66f0aa4225e491c5675b151278bffddc6f2825d15cb1c0d2342fb20302cad79a54a4ff38cbbf1dd74d087abb4beb57f1e353bf7c690bb72efb47556916082c4315ceb2f3ea8f0ad12678f328acccd750230f213eeec8a74560c08a5ec12a5530a1117a1ebdc93c92afb32fe87c5efd30d84c140b2eee3b879d30c9f7283977c74dbdfcc9d7a89f942dbf71a1678adaffceaca09bfbf34655f60c34e72b05ef848293669023e68a3f95bd5ae8e474023041e81bea132c9277514a208e64b64a89376f76f06ada142887412aab912eb542a3492009193e3e1c3eeeab1e13ede5705a2afb94b24720df5f0ee2d7589ef12c0d1c8a1371de62c953b2116f8084f3464952051eab56876095d7f419a3ab8931e2482a783f7c5f034891c612b7122297e03c343c76b4a080d35db53265c1165a2c73564150bbd6560815f3f3e13aeca3ae20d0590db6eb3cb64de7df43b112a27cce72c47f9bc4bdc540a2c603e3c570093438b3d5eec5657d2cd67ccb5a402d11ed8bfa569b6659ac2053f645f2a4103f87a7cf1db1fa721fa24fa09c48e7a6abbad7e924cacc2f01a7f498f066546c42dc185d8574791f83f2c5d9913ef0d805ff55ce4efb32c769ae26667a12bfbeca27acc8ec22c753120ece2b72102d4beac253ec18f014cfeaca7839c458a8600a81397adc23acf24d0e97260695ea5926dd6b7f8b05f579b0a670b790474b4f367d4c219ab5c42d3b656b3918d448f311d5e9160701b31b92a2e445fff06f08afc1eb09d0c11d14b06e00615e14465fcb5998396a5782d09dea6fa6480d1daf972cafa083ce4dfefa8d0e7be1d88ec7d34934ec42a9ff4817ef12cfdcb2ec3544899425c5224f659d665fa09ca9d2803c49740c6276de2af4d3c6021f6aa5a936a44e651fdc6e8a663ec3dba3f635c3c8bb97f37ecff498da8d89e22a7d89133589abce94c7affc6e7c02d6b0406afdb20ad1ac4fc1e838a520afb287e81e57026ef8285272826f77309a60c1dfee4b2e271c390ab98c0bd7660a2afa669f42faf5be6a1efc66fbb407f9ea12113a63e40265bbaa98590354b604012760d34de84cb3e768dd62bee137d02af13d1a6869de9257f94da6795e0d64be436942ba7b67a206184071c26551ab221c017d1d20824cc2d5eb61c288a77d89dd7fff174b055e0c3c40b924657775e94fcbb7f9010a95ac3adad9604a0cd9c0812298407315fd7933223d3f0b172cb41e30f4451109380604d97dd5d383faee1b76f5566576f7c3631fa962b86a2aa9aaaed904e539536f886b94f392c93c5ebde8295b815813ebd77e566b212aa0ca10aff53752693b6087d54508e3ea0f5e40d1a757335280704c69b78d2b72b4e9eb3379f02510971b667f212da94b6a492d82f743d2e0e6da7dabd71e9da373701dd9e37b688fcca17d7c8ed375b29696f36a5ef4777b780eeea17d648ecea13db08ecf91393c8753a327d7c406cde46bc7f6db2373681c9bc37b740fce017360d2f9d7f357b373b4201dbce305bbc7424a224bec29755a4fae893df55f31fc93f2e07dcceb4cb4f74cdf395c9d7bbd6d77fd7ac86139b8723d743fec87ed61bd0bb5cfda31ba6b41bd4b2500b80be8aa271f91ab7fee8f74aea50f885700f68cfe398185ddb844ec45e3abe69d45d756db93e408b27252e2d93fc9bc3e5a1d2ee46fe6534a7dbe8f94e2f32f44daa28544259bbce0ef01ae791f30858791be5d850909df32437d8feab36c7e87ed6a6d2702b4728523e57e11140a3ee7287007a4747c8c1727d5a48408c062546f750bd27d19e2955dd0602327892931b62814cad2f14afbae02a61dafb7ce0bec9f9549bd3ed068132fb2383bc3e8f19d5ba6608a40167122d318b50fed5b9d04e085363c3a26408a80268088986b33151256edcf6fecd7e96ce75b3b4485815baf6a29f2f5d0a3e284cf5a6a18f2050863de89a1b3333ef86d34aabb8088932e23a470d9252e94dc1fa04df083f5494e208bfc1bd017e406f30a3f1a78da234d755ee809602aeedf6394ccc1fb0136e27f526ad102c5bdf6da0680e0f1ca5171be99c6f1d01a09a6283102b21e50d1e23b296dd55ac3014027fe946f0b3562667cb5b0cfa4b188932ca030b1e0c9803111763f50d327cb2489bed2f93f3382e84c21ea4d2ba78cf6b2ec6dd1c144486d9ad55e504324ce8ebe92295b4e251a38020307fdfbdc10626604289e4e4f5f8ea3439a144f1b2d073035eac09e0cae7406482313f8810c17ba02a61faf544f8a6968f4db2ccfc4a76a69f7dbedb9491a57c90faddf9f1a0141d6bcb8c5b00014d0c89b6ec324346ec7fe9756827811c1d622296b65ae0e2b6d0527769b704a4113309c4ba8415e54aeb93c46b57cab965000c12d94f3718f1936e00312aee53f120c4ce03ec4c6be50a636a7c45ee98644d4b7a1365133414596eacd5ead2ab245c4cf78b23a33040d309c6331a4ee4010fa1934a8da4ced4c8047055502f0127350707608354098dc29234bef41e2fd5ed10314592bf079370c38945b0578643907cd3cf8fae0569e07afc681178e0a8142b0962ddacee3ef8c452b162f8e9ff3273744fc073714fcf71b04fd158d0db6fddfbbdea60002fc899980cebbec04f3c287e5bf4cb30e873133dfc35c783d44b0547844b1303c905888785cb22c7a78ecc1465a5df4f6f0e04254c2138f19eaead357d2ec9f4a5a22cff4c5316270262f6c96f4789704f45497a2f6f096d0f49097ae7a565df2f48851e9aa6d89b9ba53b370f78cec400514d89dea00f55f2beeebe98eaf0e873157e276bff068c6d9368e2f396ce3e89283da38bfe4b08dc34bce6ae320b5b336cebe376be3107ae261603419506ce4a2cc84948de18b28c814d70c470b975f8633d9311e11dee1669c78f7a2dfab984433c1a07ea6be2a473e987cc41f405b3812d1dd15d9b5511d2a2a450ea965389be9cc0773b38205e30815c41df02196a445293b13d1d1a26fd6c6c4cc909bd0a8a088654885f3a3deba262be87326ed18b68ebd62960bbdf1cb3cbde89609bd57cbeb7b3dcba27a2b96a37b99cbc87a89972f7b17963dbd027144206ccbd684b1f27a43d70a97bbe5617bc374beb3a0c3cbbce99df3bede0d771104234f774ae4c9b3de6e85a4eb91542f5eef403d9a9b591d819b50fd967b81ba835b4cbd1677bc3a831b499d9efba6fa2ab7a74b41b96f5b7120532721d556167660ff85bd17ebb5d2314be469e989f2eb5af32a9cbd7d06092abbe057824317ce2538ebc219090e5d3896e09c0b27253875e1840447550d2438e614f59fb98f36d4a76118a86ee0ccc4cc98d5fb98093e74948a8e963257cce7a2f9dae06d947596ea122fc8235a70f752bd9de988c119261a0eb30d406605c6f4abf244a0c2756d696ca76337dce3a9328286c0a05986d02958fc3d82d718e8dc08a750f72b6be9f1ccd25cc649ac96892aa10f2ab57a629ba77549eda1d95b9ffd16cc6c2a7094fbea48badaa42fad157de354faba147d0ae7a7e434cdbba79f31ce265aa40a80b61c8a2b7c5e317913fa7d144f9ebbf823d6a677061847ab17f38ec44d8d68db16c080ab804144e8c2806a257926ba3c9e566095db1a86ec6df7e799f65a96101ca89fd16ed28f0ad83c60d7fba8f9fdab29659c2206f1406ddc512a664cff8833b102dce8d19d0cedb615bf1293d08f5bf1b88a6cb407f8804ec13f432eadc2e2030062230332ec9a5dff825a0690d67684b3f61cd9ccc064a802982a647fb2cf1313d4b317e5e09b2ec6ed650e5415220d82cd48264109ddf685a09767e70c63d2a0d81542523b55c353f1fd6f538f39574ac2e77080b4e66fafc71ca746c24ff383f8ed6eab8b39a782de550097187478acd5216c1bd91b0ec8466a5600e01ee950f87eb7adc79c15be743ae0fb6c1202c832b9cca327fedacc55eb62ee0a7c4d057d9f4d826e2c635293c240f1eddc5e8fb9bf022f9a5b949110b9a5e463fb620d31b5c29cbd73f640d113fd6ac7aaea317785444b5dd6f84020a378092c492f2152384cbf9ab94a5dc8bd95723fc60de2dbbbad16736e35301fa261f9dadd5e8b72be02f85d9f4bf59962658660894f1ed79c504e25770613e3a174fd6f578f392b30242df839f6099e82b8404d488be577775b3de45a01fe55f0f3d9255c29d18338513896aefd6d75216785a75d057d3e7b0308a52980e861107d75c72ab52877056ffb4d329b723781bc0bd70a09174de891aa1345fcc3fceb1dabd4c59c6da1484fb147717a27229326d0532b72e1f55e6c7831c4bfcad98e151d76ba0563a81928211dceb0e54ece84ed2cea3bd25c11824642d7e4bcf37664512eb435c7ef0f851900c735ccf4c382c6cdf374e7fedae8e9e52f2ab89193f30fe155838ae33869157f59b684c153df87f4316e70b8e36db83783ce8fe12e80cc62f54d48d3dafe9c8a29a78702d257110ee6e7641404edfac842e9a07309f02b6229e2ebb99fbd8551ea96c639d183058e7e13bcfc791612270f8a8680e62df22e6c75a68b95c1a017514fc6bd7b018c64c47c9bacde136e2d1d30b8bc4e3b1b33e948a9ec0e833d48faeb2242dc2d1668f7a25734ccd281241e90fa3d940ddb679f6fffd1713b467be7fae0ee21d150b7a3bb8744a3f05f3084e47044cee5d1264bbf13f38c5a65f3b1e1b63f6ec0a23ef8430e18902889184ff82aad61359131700aa3292841770ef8114ab9ecf609cf7a98a841e22eebf3045b1702f547c46551db1544826ac12c0fe9ba185c45dc7fb7fc6953d9a2559c97715008e885cf92eb320f5f0f816ea24f4067a01be806ba897e99f4efc0e4fdebb04cf9dffbd7d1bffcc1fbd74999e67ffdee80a61073107c6d38f1116dbbd3d4058e717901f254fdee3972666b801b1678fbcf35657620146b81630c1798a4ed0586ff0103ffe50623b017dee2cc87ba4d5aa8908a4f93e6f355e1bed98a0f6020f4f0e31c98aabe5b3597834c00ad0a10e052f025d48738a0fd9f1e8174e84d8e0ea976121a2d46d8ee822e00f654e65c1b67ab2cb8489b869ee2b80f98dc1d47d2caa08802ad049fbd7007220f225a546aa05abd1cfdd4b47106771a385fcd07aaf50e51085f0fcc91808c54b9f04062016e3ea3713eaaca3228b493b436befd8647726a53bb484dcf1b1b03cf75aaa5725b89a96861c5c6f03d972c39e1692faa4f2a70f00cdf29bd0f8afc7dc07cef7f46d7393004343761a6cbb5d4c0c000920234b6adaa43689be9b7be08631b6819b3ff95e2239629f569d5a8a0d63a204111954c1a6b1b5ff5cf3e11f6443e9c09f5d8799827a4f046e73ba3a389c7aacb8a9a0022dd547dd65dd3915e50432640d4914f8062e24aae004167cf927f675e80ab0afc5a0bf96f7a03d1a3e2a6ac932688d6a81bbe0e60b28105264c6c614dc2043a865203ea4bdf27b190ed85dbb5ebd16ef39ff9d84d5d388f1e08cf0e2ba868fca8aeab8afb3f6d561b702d39d2aea62f0ca5b7d26518908dc83300e29af1a554b98800c40e7773f9773e09138b1a37bf8df3df447219f7284c62b14bb15bfbf32d4dfe709cc3f8d1b4aa665d872b978006f2b9959c502a0a19d5c9095bb24609c55eced6af4b0ef753725cb06ba2796c4cc5fdefde4f0a1d8863c612148f811cd46e9716c910943223e0c2f860e8d11313e4fea18129e0553140672f149cd8e1b0449cda0706cd7d53aa46b894ba29507d2ea91d59c12d2384451890950d8814b93f4750e0d00b3828ed99e4348230bb7ca7d7dc7610bdd519b89939b207d6ef9d0a3b90c0210a1e768e2518a4171d25ec4bae23ed4cf423201dedb4a79945cb2f16a9b56d8b16bf32bbdf79d42d3e9d8f9ef7e742a91d406890e34267c532d34951567ffec2fdabd79c7627e52d04122441d3c48954d6cd6d460e22059e98aed1b84038d72c73300b48564844f3ec7515ed13b93a50c4a2ac1b9245ce754d25db94ebd36b6202b722223c045dc24dae00d1ca6d2cd30a98d3952d27945519d31552127332d5b8e187a9975c9d9e513f5c0d08889719bbf200e616f3fb8c15efc3b1c8853123c6a2a4e15fe0ee646eafcc7d312483e1077029374b3c1f404865e1c7e455c48bfdc1a8002b268ab16fd3297be05c19a12608feb9b2d613d54799543e0e697e1415facf1c18eb2dc0e60e2dc3a3312fdc3ed6dae375bd532793f3986ee8904d1dc5b8b12c1a498636ffdf8854efd07791298deecd21d71f13720f58a13620cb31da41592e40224070337301f7a035915c4c0f5353b03f086c41c202932cdc18d0bbe73bce7ad6c6281f0b885b1d202a36cc433d9fbcb8e8cba2de3174ea6adbedc6b2ff77b4eee8f913aafe2c609315bd5b6d7d00f91b053e577415bca05ce93efa9679a009e418a86d6611f10b4fba5cbbd820eea42b464148d79fc873fb3244ed335166262d8cfd8f5cedc873543b4300529c35e9c3950f1b32c281e87852989839b21e7580c57cfc6ccf3490761c32b831f97850d7226012a14f0a6931a6ffabdff8e2e9de5b05bcd84d013e037dc88d1740e8f7a52f9f464ce248eb3da9ec7b200e0442df92aa20cd071ebd5d825e91fc2132d168a2834a5abcfee500c8e185594b7f24b6de524dedf0ff4f5e35fda40cacc3849f68a198b1599097e19878a22d3e19d12d129d5aced427c8eaa9db502a367f74c3fdff949c330a7ae27e9e2970c508634da8a1316791a12a931c08d8313a6840f268c2e75b4c6d81ca6692f3ec3dd784ddea53330659eaa075fed6fd8b6168580938cb5f162b8502c5c68b00d2b024069641265cb02e2e176b40b071756c76efedd69b1f152ad3f99d4eadc5c8b1384418ef2c5acf5c17148089861725b145e4b1c707cfbb6733dcc93ef8dcc277d6e730dd1b3bf6912fa31cc9b876cf39f67c2853c03ce2af404a9730011804c724d60f4a29921565c0c7a50c5d98280f42a1f3a9cf501a2960b183602f3a657224c03f1831c6501396ee74630f9b327fcb782ce2cacb0fa4f74ea54c93440e31ea501a836e381ae2877f03c9b6cbab911cbc3e5a6a409d03ea62520f6f53cb4615cdb89977c40fa0c41fac30f87f57536b991b148ab5978f7c80705910d1c2d4abdb3b7ee14cce8f6043f3dc86cf60979f0fd2f48269405f1bc2586a022ae9d5abf6dec3f678c4bb1cce343a267032098a6ba6f9053948cb9799b0d2bf052574b1c401995954c13810d1ba899afcc0928e13b2e7256880dba3d21906ab312469bb44e4f4ce9f30622375c687377951b36681b3d706359ebf52b0ebeaae35614eedcbf19cbaa9b339ad43788dd31def415e456cba24bb9137afd07f907beb8fb760d321a4c9b8156e55ff8abd81992cc8350e803d9102b27c2d2ee31c443bad80ed05e409cd1783b9c813bb14568eae9f6d696c7ca30c8363fd8a639a8e2d36b83abcefc378777621d1d49267e441146573e065cf870efe1dba001698fe135a17dcd58d06a312ed03ab477d85afd134e9590adc96965c3abda91fab64d13b043d14e1491eed12f5edaf405d43cfb52bbb8c242919ee4b76177c55dbd2c29ae5dec778bd99f723a175fc28c6a5f95f6a66f9d651890176a4745c7146101afac940fbcc6999f111461153ab359caf4e083d4e1b8ac932d4fe6c807f950681a87eeb65394e03f86bd5ac195a0c5cc98ae71b416e4371b78cef8f5b25f1673b39eb1cd13bdd7b04847a95908173c54f480dd4de8ea70fd983d60764a9718c6650268528153e6d43e4e33330570414979911e5c86574660483a4f09de2eb87646354f704943d56dd1c598e00a74fed12a9949eebadb7a915b46bf40be5e6a1af00b8a6693a965ff3fc22d4a778311f42de5fe7739d2d18eab0a256a894fd3704d7e56c9a48edd8004c6d03946973c10965f14fa39d29d8f94ba61356c486f3b184aa1b06652b97128847d1ac732899b7f8a4de6f49088f40894d200eb8c66499b956600fb9bdd0aeafe6680eb99537d76be89e01ffff5546018f0eb85d4d10566e6b10da940e877442d2d6fecabf3c790896cfc821e2910235f3029d0f951cced15ed4f034e13db06bac69085438e4fb9ecc2a619946bd462a66a84bfc950fbbcdc6bb7ec03bbcd100387dba042b3f0d5e0be12cc21ffd972253d3a337a9ad019787a63971a66d47a6963dd361e1ca1aa1e9179105e9262a08cbdb9fdf3812696cb0be08afc13bde57688a27781c8d06dfddcd218dd8060d809c77d5b8edc2ddf29c81dfcbc9304eb0d22df8796540303232f900a48c3ac68783f2d2fc97541918b1a72629f3eb17eb035c5f94a5c86eb1e468b23c94e344f067ee83e4cf98fe570ac8b4a73b8c7665282db0ee9dc191bd75dd82913269faade8d646d1802698991bfd21367ac1a3e34e3b40e01d0fddbfd74e6c26b50741330cfffac215a4e180a75a1f71df3ae137d20f8b508512db6e31429cfc46ed9390126c1e5d0c9f45b194221284e0306691a03124a625546c10759f01c7fe2c21a8a901d8b8d63192fc440c714b3dfcf809bbd9ea10ac64f3a4bb82d655b6d87942c63f47ab1838e607100c5e97b19aead2d705a9e12299a84238518a0c58585e94233f4ec00fe7be027a899f67edc633b8e9d2d08c335212aed5e6ce8c636af6f7404ce3d7876173b5fc88228b0ac1977639624b9005694284551eaa7bddbe3c7f28e6ae7b95ccd4cca36da2be974c3bb430accfbbad0fd6136de14b390494152e523a689861098bcc326c4873def0e0b0910c5cf0641910cccf4421318f1b60a2de169a622f5abe1df6533fe0cdd118da80c68bd412c624e5fd0104b3b9cd8d69a6a096a64dedff94554f5b078b5e3f5286907f0918618b1ddedcd874deab8125d012b0be9efbd8b5c95f78a5ba1bd86dc733aa708685ed6c49bbb65f02366f4cfb0d31c2bc8cf9107163586c376be1635e86a691cbc46f78450dfb898dd418fbf10d8425a3cecfd22cb6c3d9a1e466f2036d88cfb17943cd205ed514a8b0be831403d2a8a2bdf4d439f0ec6a365259cc8d557d099aa83b7577e33f7b1cb68af3b3765b50ef1b1dc7860970be9b1e98f118b749d8d71690a88ed77c88f5aa70e1e76d44433d71e4cd46e9bf67f3d37d65fa8326109b1b130bb12451af9b7afa4cc3e5df7da16d05644e4a2bb4753b037d0c5e2ac00ab937a4d31b36312645d6753b3f6a5eb58f4a0765fbec04368b033517491997a3da3da37faa168a45bb995336b7774dc8aed81a69a646a2e08a3cf67de7494eb5387bb89074b833eca7b902caa2bc1015567b9301b52175703ac71632c511ccffce2c8070a08c33b66f2c9e949e13240813f735d88077e8676b078d6c75c07fc204977023d0b657fc00b3e31b01a53d7eb711dbc28700abff02b88dc00d81d60d3c11c545aa188466301f881b0937792c8b768805cd4208cd73736ada525fc8c782af35c4cfd224143aa62e46be898f411f6c668426e8c33a68b073125e44a4419f3245fc1504d2da3a4cbbff70fc74c46c94ba9a1a76c4c3879fb69e84d3813ee7e9fc81e9df6286f85720608a894afcc912fa763373353cf2617eb40186e92987a22a5fd3710b0769018a3f106b1318518c1c0ddedadc63cfd9b074dbfb534173cdc53fdbc60010f5c9aa1aac82f40f983d97e53f9ebe7032037643f0b9db9eccc250cedc93507bc95018cb6e77465434b599e57963197091f8195205fec4f167ce1b03a0e883dd002152d0941a6e28d271db486718655d7d2b1308f1a765cd8dec57b7deb13c0437ec6fde2b57ae38f14fffddb11bd0419c2583baeaad3aac00afba6033c67cb3922699ff036986bfad45238c6b05fd2acde7a86ff49648187395b7ebf6dcee53b1f71b81f768eb2b2840236644da9eeb7ef210eaaad08481d8ae5d3897e6505e291a684726c6936909a03f48163984303ec0d5f8db6b93ad20cb95f7f071df6020cbd08edc38049c787d7311362cd5a4108a5bd5a62416b581d1193bd51a2ffd472c5101d89a3367360a8dc32d80975c07e77875c4136c204f2434e1419d9a4b894193a01c2d5a1dfa239d69272f0b925cc606a082cabee18f40278ebde45b6cf1970e6c380ea9e19c089c066b23b1a6e5a5fa330823e0aad7720c793cb468512b334c53a39bd62320ed505fbcba97c6b760c80480000820cd66de59fd510bfb1960d3c7ea2b1b54bdac4227303457957245d25509512c4e93739ec2afb53dbaa73853ccb117a672bdc149a85adbee9fc168b9d40d35074708bc5c46b66047833e6345bed87786c79c160e0c1c4574aecccd09f55e7c284b4fea038a2cb54d339e6663ff69cec6c81932fab2ae4f090997bd482c56a97c47a50063651a58b7a91123657298aa8c94fa840b7d3b3a9b0869c7f94200aaef806395c21b2c3f566fd8108db8f6049934d13120a0313512a8fe54cda45e3b1b0155ab939dc0ca90110770e3076d75b6958f0d8c89c9a9bfec020dac11e46cbca59a10a16d2fdef55ad60f83d59656e64c9a27bcf09c664d59fd4d0afcd00cc7e648c7431b9f17c81752a0573f8cedc2a75d0e18fa11582ebd949dd7c740c4d829f12095f307c082918654d7d6c14030f44c323a0a4f9a6cdf86ed908a475f7afc0634dc44c44e284c9548d903ac2dacf762a363f27c5eee6a6091897325c6070ecb54bcd61d1b003ebafe19d6f0822aad3363c4e9e8c89b6fc8e103b07b9b96b49dae3b071e932c3a2d50d30905c6391dc70bf1d8c8c72b3a9dcceaff228f113ab9d9b32cb263ede28c45ea9946f1bf390a0c43b29841fd46c7de1a18453be4a26865652faa42761deff2a2146589506928b56da4cde2cab07a203b8557606431438eca2de8a82fbd0dc7d4431c7ea94d28c05a0f1b704acca08bfd454d80127a03c46b60f8f3e82c28abec20e5b6a8aafda09fb02bd29335d8d5f4c10595dbe0b39199c75cf07fcc0053461ccb96670768af79a356560e9d9e6faf8bde9f3dc0059ac5317337f01c1d348490882408e8457b45665e5843f0013755c3faf689318d49872c77fff511fc1b449b565f9b20bc871ca0d475cce1fd7fd80a86ece074c5cc815556c5766ac8922cf81ea414ec7bbbb2ef1244a9b966ce8bd7518111bdcfeb49a780351efefe6be758fa8d2c458802f1b31b471a0bebfa8157c2d0c0eef8cf38e0fad744ca3af32122f95b6c4c12e9aff3ac388b65bbadf75dc15c8a6c9baf16d58bc3a0f78e4a983a78999181f06fdaeeeec2c3c780ff77e4b7622143109f59e3b5ad08d4ea1335c11ced461aa86985f183400b4d1e63ca800d058f0f6134286a72ceca0f6f2728710fe6619afbb23a58b6c4b0ae238de05d828ad92e212cb7ff13b48891035a72b67f201c572299ea77e31a213ae305639b6cd3eb43c8cf9bd0a7545283c7be8601f1d89f52436ae3a5c41a312e3bfcc1d80d864cd6edf9219ce7945d2921226d5f6249a60ab33438ebc282276424593cdc632bd0e44858c5469a80a7345103ebf7442aa7465f6d0eb0de58c73da48f634ecbcb35e53bbaf7210e7880089b7cb43ebe51f11c3953dc991dad8e51cde111509452d5a6ce1107560489c00122a9cbf58b6005e385b06966acfdf94a0880d4cb20dc513bf0466d38be6ee6f04b27ac26be728608d2da3fe657497c27a4754bc75b537e3720c22ac16448f888c60cc82b108890dcc39e7f64fa101f26a1c526d9e99ac8f59f44fe111fe0b619b693bec9de4255175374ac438448c33677ac55c58c1e3f2a20d2f1e61aaaba98e2e33522443aa6b963b52a66e4f8d5039106ec371b75ba22ff55030ac907b90455930891e6b86bbefc4ccb678a85684014e615508125c236371ac462c4d302bd1a0d2d05a23f4892a38ab63cdcd569f0ddaa031198c6039908414265bec58105bb1586c04b2642bfb0c8b5daec6d707ed782bd3e28f6abada80f73c6a698f1dfa155af140ebffce40bb67b4e5c4d494ab2414c0c792b71757274020cd5fee1fea5a888e92d184f85f039672661a878e3c2a727f72f57a3248fe718c5ff0c01cb65a659e21f060d96a1bafc4865e5cf81af6f2cf3f08982999f0cb9de55b4b3e6f5049b8b85a9da501517ef92ba97cc67e0608514ec5b88946a17454b7298cdce4c3716e616ed3004ba06e539f8819881ef8c9bdcb6666b3549d8e561b3bd10a154a85cbd99d234c107acfe7971ae72ab052bab4bd5cabf5255e662bc0c501740ad431a6eaa6e62984dd978535d766eea8a9cfbf80695992e1d05b38084583104c1280085c0bc4ba286fec61b60ed2b2c5ad276b5731438b2546a7ce3552ca3e5e935c054764cdc46d1824e529407179c71b8d164e78e00660b20ff56e8be331c9370ab9b933f32bcba588314a8006086d9587db7a6bcd3f412e30968723b51d28b816ac0db93d9a23641d715120193274a9a9ba7672d948941a3d9619c44716b426ad3df25d37332c9dc6d2f83902e0390d87463f821a4e69f3158d8741149f204333e18afd55765fcddee8dd07cca0d080ab786c6827c195dc7ef22ea6e97a71c8be03a9280f86dbad1569fe9a68862bc004612058cf04c77fd00a25bf7a4addcdfb30a536c30f30fa44e1c5bf6bb1b2f66ccd5f8aa98888237d3b42c0d29ce3d005f0d914ad084333d3baf9754df851f59c79d58ac0f757be6fc9c18bbc290737e887e7a5271fd4ffebed2f0be7f1876b43fb6bae3aca3a395d5900a334234c209bb2e0abe53fb08b50fa792c9fe12ab2f405312be4f81737bf8216b1c9c25e82c3312775fcc1690055a0a63d77dc514eb9cee5685863d020b7a1097475d6be7254ae258be7dbb5ccc8b4ee8a6a94e0259c32dd765bb6a6b40b98d6481b8faaeb96992fd948150c7fdcb4537447f5658677053f564b416bd6fe5670e81d8f154aa682bfc744105eff8c19d02550015d3bb6e042fbb03dbab781684401e214f74dbd90b54a01fb581ff6c49e1c0791a077e13b50157ba655d2d6f07b80ce3fa172dae9f9a7f7afa7f8c098fce93b693a12bd6fa3da45b8f617d0bfb7bff8b1f8ff8f3b300dbfd6fccbdfcb928f5c8fe512242d7b96a8421aae4003727b500998d8e454b3787138fa864c5b6b46f1a209de9c3f02af4f45521f8359111f157ba59be8fa25b83b47839f84c37d112caddf0f5fdfaab531ca97a325aab1eb7e22bae5fb79aeba7eddd507fcc7ff83c7f8da1e7038b95a29e26b64dec95f07d45b61a0baae9f04d6f02b15647ef3692f2d2f48c98bd376ecbdaa06eb64a3c00af251c28dbee8c26226b087ecf06824a0cd9f73c8cb91efa9eaa0b6144167644ded947b0a7446907be0c909add06b0fe049bb2a4424b35eadc591683636f0394e1e51d1e9e8653c15e10bc83dff12bb48409fb92a8a1af5985a938b224009d8f8416b3e9af838e98e3de49146a588007f94d3b94a7eabe88cb5beca323c056429fbde4b0c34bcd6e6f82d0e9f1aab02faed1d6e3ec23b356018162f66a09a75281af460c29728535e84b7f8e390afbc6ba9e5852b29c04e37efd03a516e6745908b930bdd5ef4daed39244c2704abe8556fc02c5904cb6178252b625039810f53c877ef87fdfd8f252afbcfd034d1c1c58622e4bc212d681b51d08db9a94a035da3889880f78555a73de07784380b2f1b243b1bf8f9337dbed3c8b715926a6dd38a053b5c69f6bfa309f515e6aedffe191a514997758be5b8c12cba1eff8b75f69087a42e1711ef078114c0a8ed9a8d5f2e4e2ec1edc457d724281f3fd58d98b3e901f8ff88d9e79e2a4ad3587ffce60d48685f7a171360a72dc45d79a2beb41496b15ea85ed41c68f0783fd515be44bd3103ace6e54f7eb0738cab3031df84c8c7a80e29bed08079ce086aa9709b62f8b211e7d7554c480abb19b5fd3531652a665102a474837e8a4d2c0fb9819b412086166db4c2ca5754a1a78e1a03053dc95714f79d4d226f407390dd53252c2fede0c6abf44d9a0ed5526962652bf3f2451274c92674229c19932dfa71c7b369eb0548e9ccd54d9288dd20e12e59faf84bde276f99b49d866a200551038c60d94a2b13ed104654ede6062e8493914dec00e350ec9e0b42833a68faf2ba142ea2612dec00fc62e5f4369197461c9ed67e2105ed31f94a1783fbb77c85d498832ff42720a43d69938086fbe0f0839e6c7eaaf88b9db1a9512a0976fe216624a74a978201d6d2feb74ec8810abd413646267f7d4fb09b39dc0c1e1c449230adf4af95bbb06df8613b3c93f385f9e1050c69dac6317b7beffbfa27ec701ca498e6f771f0449022acbf40328283e1b82e04d8185e7ebabde41f2058a7fb2d51965489405a21b9c1be0e79ce7f8b7790c7a466ff8772272b0abf3cd3ffa26120bae56ec0bc3724a932b52f29f04c84f6d498c6cd398150dc34e9e35cdad0a76960039f009982cdb4573b1263e0ac213e006030a22ec0952aec6a39ae6919f952f83dc416c0440f3aac0e41008c79d6031ba0e93bd2ade7edb7ecaaa7e051625d41f3363e9b6cfedc11cbb1b4319e64e82b970c75a1008db60cb8bb45000f64130041e96407fe30bb96853bc5a936fd3961a45d1b6731074ac32cb4788d572f860cd7725c8972418286564ab180bea1a00668c71168f57c4ac1abd7659587b25977041a7bff8071464e21007a5c08c54bc9d30eb41830902cc2f19c9ba5dcbe2589adfd2377289a3494b9e63c0a48cce3891665daf16cd77c8d721bd3924bf59bf64dde264cac94d35bc2083eb60fcb15a0a28cf91a584bdc3043ddf3041c5457d3beccd3be99947baf1ca1d03c6106405cf4d08c68ec79223202b95468781c1732c3431590086ee69b844fc690edd4d26390942a527e34b6010ce1f4edca1949f1ca605a67180394d5dc98b7f006860fdd81078ef586b1011604a2ffa20525374b9391f5b9ceec44a4bc8188aa6f0771d7c47032a8ae2815920d2324e07ae1bb517385f946d1f81df40133407b665049b347fc5178c491eec9d8374f88277766276dfcdb9f8e9bb110a11e230102fa2f89b8e723b995efa8190e1daacc12108ee5bfe957286691482f66eeb4da49432a514fb0711080f08eda2fea35da8a77e8342bba453d7591c7e4a5da35ef541a54ebffa5a986c170e29b0d06094c1217cb55a55ab1e1a354d93a9a749049a403f745d9992e40cdc6432991ef04529b236c88ca166320d1541f1a607b0011459fb7325c64f55cddfa1308230ad214d4e27c5228c15cc28517bfc0e2191910592110c69b625cc0beaccefd00e92bcfc1ddac2c687de8a51b6762d0a2f6728690d46dfe2473364916c2b00d69d04a443a1d9d9b65b814a13357d343beb279fc0fae993546a9faa59fcda0e2faa77bf57ccb8c1872dce3553c720e95b13eed14e74f91da18152236b7d61abb891b5d217169d6b7ac1c8df4d83eb377b94032d6798dc24cf602829cfe9222121219a18076140c57ca4507cf10dcc2e5988a7481f16f2915fc8322939d949393b0e65f2f6e89426a7d4644a7ddc44b338e52d4c68aa2ae731608bfb56d13b5f18e7e1ca0704d29d972324b2643b3a33223cec498c4a82c2ca6fd1ef10143d4ad4690fbcfc9ef13bd4031b1c4bb552e547afe28b8180ec8b650c145f4522507cb10681f8fcc319e17143fc8054a75a65f1c541b023f1ec7189671917b11110cf7a68ab153d9d346d8b31517a4dc56ca89389524ab90a3b47a901925d90b8b3397793b37d606c71334a07c6c35180f8681b02cd904582991c8a6988c935d73e249a9bbe8531a047f6b1db31b9b6327db19b80e60b3375b78f6ec59bc88a1dc1c82e407d3a095f582183d1a8c00e856627950a13264c1898e943e233fc763bf4a3d160f5a3d9998b04ebd13bd4e77784064a8b7e0e4656f7f47422abe3e742bb918cb29fbef1d19c4a693c21a414a4b9c64a4a3f4ab128907ea5f81d8a62889705cd668065968493df7270ec755769d9d1d64a428d4633b1e0f49a22a6f0177692e3d05ad6deb29ec2445b79a176b514bb5186025b9c34b8ff75d1cf5e2143e9c34e52cdd49a22aa7fd8493d6656ab9fad4d991e85c70d0de42588af91712d0df6518325085175b0af06da9eb2383798ed829f1e723fc4be7a8a113fbd26490ddb68a36baba5180bb9c89a2e25a51c77ce28de987af48edb5037ba20d2b98300759366f22af5ed98f25183d353ac794af34d6a50fb2d06c5281da7fc0c9a517efac6296de4a3034b18a3166089d4ef1535c6f8c1b55a211ffdf4255e8a1b90369ab335adf694130a393c5419b4a7699fe13f6ca39e48ed8597226bbaa605958044dd7829be7a8b654dffe2b9fcf446e3a76f3a38ea315283d36953cadd4a318bc2e7270b0d45f183521ada810f947b5b71d4db9ae3a5f85a58ece7fc69a3b5991e838c627eaf7459e2c3fa2ca0ba20fd0939753aa8ef08c3b6a0069f10404b95daf427314a0c929f0b732a45d6f412c4a893c6e44ea3c3301a2245226bfa0cb09cdee123c307032bc517ea8b2d128c66088ac6088c631f0d946d61532ed1661744fbd8c7e7a76f1eff44d67494c74091357d87cf94df13c9410d4e0e3ae2a47619b5ab7d3a6b31791ca541290d4e5fc9aa7fd846517efe5e4143083f3d0a3538dd871ab2901635cda49962151f94e4f4a2c892453f4f260f694ea7fee9adc5c94fefa3e8e3b149bf72fc3452bbb60aa5253f7dca4f0fdbcbcfa59fb33366303ba12a948cf8302ef9d9493ffda4997a4abbc218f4d3a7c7a076ed1091949f1e9fb46bb9fcf47ea25d51cbcfef54a03a14f1f463194ff1f88906a77f2ca853a2cc03c3be955043dd82cc9805c5885ce0e44f7e8a3f284e9327d946dd009a211c121a2831ceb0230c4339e70bbba274c53717e3a7c578286fe5536bfaf30da9414e6ab041f61284a80d665f6cc5f6d2e2f0b3f71aeb6223c6b2af5e5ad2f2ec354918a95d26676ea3f8e22f96c5cee599d178f63594be8df848e9287e6127f938511a513126c62f4cc5a09ca97792d414e3c9679f7c9e5a4bb3d837e6da88070d6d147f7cad6fa3f8e23c7e212b01b9b979d6111259393b7c64acb4c3473a0db2b3d219332bd29059e1c597df2207051561a61829a5d3a3a79add04226cfb0010450ddb28063724197acddba85d27676f2dd1fb18e9f7826abed02c9ae8f2e357248ceaf4f74a196a7ce469d0490dd7680212c63b66d58780c387bbc401220df251fc39b5ca0654b01cfd16e1970a16629c2133e3e88ca0df347e878abce021bb05463364ce8f262e4c763bd3e9778406cacabb092c4c0149eac21609b6301a28d417b62ae37df40782ade9dd4456cb0c25be51d8fd72643a421a64dfe153fdc33d52eaf9fec2557221dc231ece4b65e758a4ec4afd04cb47ef28edea3e6ae9178fa0e82da55d3b44c54acb3ec69f2f3eeca28fb12476884a113e6c2c610b7de481d187fdc4476f1939de134aa03dbbda8805256b1bd0c3d7c186b23d3ec96559d2e5ee490846420c6a2897a4cf2519fe52de58da555f7a0bf5146f59eca2c5e197deb376edd0d00f5ece00939a94dc412d35d952b2c719c43b78ca8e70700ed6c1377886554c6347fa4583222fa538e9d948bb68bc93b216af5888326fce414664473416a5f308ebead3f1852be939beb04ac7318f545fa8cd7c618d2115fae8724916656a294aef38e93de40c921ea5a3e229464d3a8d2bce69c927ec0afc1408c34ba742b36c47c778d13ebfa5da0b0044fbac22273d8d93e24bca3a56145ff2a8270be160a0993935eef9769ef89ab336d22e1e3ee3b6955e5389c6bbf7cb47e7e119392a8ac5a018fd285c19551d5f8e2f5ce1f8c2aa8acd7ca106543f68f55e510d39a5679f3323a599ac8867e18ac6eba02865d157d5953ec68ec99e7d3e7a4d633cfa048686522a976a951e64d023ebaaaa6aa5438a9c2043898c1e72e0c345193ea83298fc506b55d55fa2151861e15bfca048660b178c10f12647487c2d6c66fa6068d08c4abf560744951e0a0db6695685163e55402105d58286ede7a36f13169e7e71345f2827cf69d9ddecd26432994c26d3f43297941a4401900e2bfcc24c7a197d5b3295e6520b138602c287274deb52e8ef30df2454a98cda3ca751dec6dac5d1376f4697b0ed5490a78f867d61aa6645d73e1a76edf9ab3b54fa69b1f3a1ce9f067bfba1ad45f9a1872f5874fc122531828732ba1cfda8b5728d3c5932c7ef86add47067617d1e17c0f0123d9a7e8968a841fdae4035d4fea88c280db0445d7ddd0eb50357981851c105131cbf44350c612b420f3a442b607aac7451e35bfa704dab9ab6ac76ed0b4d9e364211883cbb16351666885fe8cf1f68a5defc68ef0e7fec501b3b7cb86a52e50f926509fa25cddab4ef58139acab8420c13264c988fdf8e05db67a7825c21c6f8c5109f7ef3a3cf9fd1d9d31aec72a8ecdd458df5823ea2ebec74df68252ce176a9f5bb9b7baccc7284a0d0ae28c632370760c3c973bac6c552851a7bfaa9802c0efd20c07ffa6aec4ddf8fa55a63bf4f3d3ac73ea7270b61939a2c214bbdc9892fead223abe553a99b3c5c2dce0276ec0bc78a960f5843ddcdda485583d24df446264da93740728ac8d0af95100a6c7c5961313ada2e4555d5a3a6aaa6a4b249df56e392e8dd679e796e8f86bffaace3d95b3d773b37f77ce3993d9a49335df514f53c9ddb2e66676da457606da4b7d73d4fef07973a95e2ab15595bac2b671a2dce517c9d5c8673c9f58005a58753cb4bcdc399f452ba84f403d6b5c282f2a4e90859419eb4d64a0042bde1892ca9d3daa2f2f76b5e17a785b5912e5d665f13609674108c971e7a2fc3fdc14b0f77e8ac8d741298a8dccee60fef8c499f33c9ec9366cef9d277a4f3b40b072fe9178f1f179efc76991d6a2b95ecf1b2690cc5c396002a68dcb871d7b7188f81e24f0e2726d3899e28cd31445d9fce42dd3fdc84813ce4273f43d5a3b849b3a6871c35f93e7f3e757ae43c6eb20d6edfcf8fea43fee956b061f5546784f98db91e7e26e8b7c85129c3e7974a972b9e3d1afac510db883d7513def59be4d8ab45e858e237ca4b634c0cf14fbe92a2e8b7c971ecd9239111b2e74f86fe18524f02ed4fbe518ebd1b4cfc66e2d8e37af09bc6b177c38aa731f95251daf226678fc6e4aad77c4371eca13e7a4b458908bf6d5cf44cce9ef6834b1d81fce95428be60a041ac8b63148806d1295c037542a3fc848163ed621fcee1d5dfc63f413e7d03e7b0e4d9e78c12e3fdd06ffaac0d7f355abb4e58ccb67cc87d8de92e860a1a34bcc983d241a0fbfe9a78dd7317847f1a9cdebaa1ee771ee3ec1fe33a2dec6c673bf3d15a1ce6616da64f3fc0be9809b3a6cf70c787fcb37ac1cfd64f16e2a787a70f5bfc43021315e49ff91359d43bcf07508dad0df5295b1c1c3f9dfed0e9b336d473fa67fe746ed2ae1d62234abb70fc7496b5cb4abf7afc0c7d41fab933294271680c363ee4299a5212d0875ce567c841b31ad0c74ebb6292969f637cb8483fa9c71da9ac3a31c2cf734af61b73eba9a29415a3674f2dd59e7ee998a5b0b46b87b84c79fe30555453b376d5e7a467a1212e491fa6949e838290c387a92fcf736fda158ee0f3ec2bc6b383ad1ebca9277e53523a15e54bc95e8baf007869163ba79af8d4133fbf5491fc02a0d4a00967d4f53055f42c01b0c1f511aa241d4de9e18a0d003ee8ee6eea39624b2f3d47acb2b66bfa783f3a7d7e492f7b9b37ae119ba9354e3ba16eaccd9cf9090294875ad68d5e16ea670928a5bc3b3da7e5f46dc648294571ab7669ced3773bcaa98a81a547b934ae68a494720c51bef6c9152a88ea136314001895bde7943e130537efc6daaf93afaf64d6e646083e9e962523828f2c797a69828f53ce2394d229e56ef45dd39ad6b4bbfb710d4aa72af7699f2524283197b893b5dda76ba2d428a38c174d82da0acc775d03c6572b168bd500636f85373860195e2c447893ca08d7cbef9767ee619f2d53bcc94475087aea93fba97a39bf98e227183bfc0463f6d39dc91738ecbe0ca004d38a3e54fd091f5d3be3a8061f7d81d0c447efddd722c1ba7907dbde545003659545bcb367203c796915946be46489357c0802119ec0208c97b27b29a5943dac50f161cd950f7d843f8070f1850fb4c8404b144fddbbe8e1a9835d1c3df596173378ea375e2c3df500c8bc04910200ce142f5de302cacb1f6879e93dba20b25640280856a6502386c4114868704129a534a71f60b1051b2f9d4755ba42db51e5c31e3e3eac711941f1d4575be4f0d47d8b2a8c7e9efaaa0b42c11960b04312432c99014689d0162f3b4829a5d4c1a97a64f9b0468ba7aee9f0d46b16264f7d9505e9a9bb1638c8c2064f3d078880289c70620635c8e2450e60128c20c860464a297140b15750d7b010f1d42b16242cb678eaaa2e08ddad428c31c298d2e58a1b80895f0c01071d4aa2b8e20a0d0b262f7da60b222b481bf01428073a50234b1757102107183d22ead14186a7df58e9323fb158ec860674f1819352ca2a554f7dc31e4fe9873f3e04f274ab8c508518b32733242b6eb0a2ca154a9efa5611c5534f15a93146aa0a255e4a8f91415e745922e6a9dfa04029a574eb6ed70591b30aa0498217394043c98b95a39e0804329456fb94524aa76f6b7445e3a0582c868316bd7829fd06051d29a5d4eaa90b329faa6a9efaf8d1830f81845b85e8c3b5f2b4084f5db6cb004f5dab519efa8aba33f1d4c129bc3cf5160d9efa8d15223cf59c279eba9076ed1015609ebad605a13b53ead94c61bc749a84b5502a639b21f70d78e91a151fd4f0d265f59bf85a201031eba189227cd97283d8c51092361f0438aa2108b6925ebee410c8d3a2a7be1af54abd15d3f3c09ae00388dabf73a29cf3586473ce91a0bc73249b732e3ddca4c91dfbf4783c179a1539df1c49e72847c2f9d639ca8770bea1bcf32128ef3e6e73ae8b007b39d4e9d4c335e27161714e1e1d03eb62c082d119c8da44df50a6afd51f78030408c56c8c94925c9ceed74d5812b238351f9d059d1d02f8a09a7c6bce0045b57fb737e650ce5d10289c73f75b8842a15028946f1724a7230b424eaea1b62dba109d766d93066348a8a2b687cc71634cc7749ed331d3883a4a8804368e3a4ac8e9033d4632ea94b31a6e9190188b620a3544139a5fa21e29c07819e19748499526cc84c9951db4d44085ab616527050b4a426469a3870a304813cc92102bfb2d4da2736cf976d47882294292d8c5971aae08716444c31195ab5aa8fd5119b277bb77bbb77bbb9db9bbbb5bc951d2168443195fc0c880b38163c79ef5a045e968e7070f8fce8ca7d65a797476663a3b3c3a3b3c370db2b71a64d6e1d969970bfc5a1ba0f8d0ebc686dcc152116a1c39f970e5a4872c86da0863c41361a010220b16a2243e59200d81a1011320303fa06109498911db972caa0c855182490db498f925ea2182c915552c99bf443d3e4149315f7c51228a6d1182131e6aa3890f5731499dfd7005155d946c21424e01c66c8a2dc89892b74fbf443474f15b98a94311ac84012344962628986428b025727348693b752a842953ca4ebf707a4296db83ac6c8ecccc28b48b59fe6817110d3c7cb8622299d8b6464ae93cf1c5f513e95c4a29a59452cafef0e606885cd2a094dbe4780821633af1454369e847d302e7313ea4f3d487248524899d94778e24464a27125f33eeabbd599ceec66a1539c6935a2a3fe75dcf62e0df5c07b57d1ceb3c4eba942ee5b7234b9ddfb7415a532f663e8e8e889c1ae5454b91c8919050bbc25d8ab23848aceba641230b3b61a5c8889400846a24fa682d2eeac951ce421a0bc5578e905094b53172c2baa430129b630292b5c0a519d5210b27381c51654e188807557393170132dd008aaf1b5f2bb2a2d66ab9a7c33ad8d76e0b3676170cb438257c7476b238719545a5a207ab1a7ce424baf8bae1f186e3702433ae7224371c874f9fcd747416a73d7a0bfbe2202a032151f98c23c1e1377c7afb8eca677c0787dff0ed68fa6b41e5333e44f5ddf08dac2138be1b331f658244c3e637edda3c02f1d1c3129e5d00d16f78a8cdb8cac3150e67af591ce9ec383c06f236b266bc8dac8d0175f3de7c7b01dc505e8b4be5df3c6c6dfea3c1a8d3eecd2e05d3f708bfb9c75504da52cede07da53be3587a9be2970ce32be1d7b0a31ce5fcddac8f80c3442f6d953d8e7aff350becc17be007efdc27694cff039bd796f1ee3c5c0618ab48bfbd65f58b238d2638f97d68f7eb113066a31508b815adf8a2f09cb294245dfe1a56a1fd81d5125b8365d65a98ed1a2584a69de30e4e0528dc0c0ff4a79e7610f0f6b3ebcf9ed26e5edcdd27c7a95f56d6f6fdff617aa2438842a1b9ca8f837f1a55ad6f4e93b9ca8eb6c5a47799b3c44a1d651a8da2e546b5a45edeb665927af5c83bdee27cd7b3f233068dbe5bbb7cb0b444a7cf89b226abbd4b8d8a94d58a896968c70f746d626fa669364c926499d1eee929156177573cefb4798eaf373e2cb51d4b9d307c3da448fd1f4c97c55653f10c128729431c618390412026922253a3c57351d6aa8fd9113e69b9b1b1e42d49097382fe1e118d3b0ae4a24be5691151de5330b46bf591b9b2435be4e7b78b39ad4a47d1c9b8934ecd26a47962a635744954ab2e8218a016104162fb1258c90f9f9d8e22fbc94034e9a50529e1423ab466b7d6b6db0b0d05a1ccda31f605fcca5557dc0a0f287ad6f99b0549b07345669714c1fbd531e7a9fb438de474f79bbac5323f1b18bf8d8416c1e360d6b08a93e032cd25c20e5d577625cc6d965be2349f0b793f2fa1d497d7506182f8af70b65984f1df46d90c6ee0bb5ed0beb6a89cfda44cf69d6c223881a72d2c7460d46ef5c50f98785e28b85ee32432ad2220bc11fd63e4e5a587f42369347a9c72f9ce4949778c42a1351d9a3cccfd69b0f22b3f4a8d5ba5af92fa1a89063294aebaaba66a2a813cb2879501a6aa30b27ddb7b2a8d1898b61333c6d99d4e6c33fb2aebed03f828ffac2cfa7c125339e91c8ead8fc9cc86a6fa3c64feb86a8ec1dc5b892a5892b587c214a92044cecdb9b73f6e4e738aa9ba3bcd560cbdf6e3fd084a5aa81ed71574dc0b713591cfe9e59038defe5f2ed0c14bdea71deb6de0178a8db2d2faaea439204fbcc872487e3f06db0a369e186cbf8ce8d6fa3ccb793e3d3725ae52d6cc65b18c8a46e8326ce0b6f9edb422d04ffc60c0e6fbd5d56e733deee0dafdb640b0b5bcec106bbd5ae9039865b7fc3d95703bdd615753d04a9cb783cf1b5a7ae617d235fe7af15390984f55bdf6db52bc69b3fa6f3f5c2193e8cf1d44dfd42235f9dbd30ca9e390a1f013dcf9e7d9e7d7362f56230f2d543157c2a06d3d72fdc94e734c738fb16e3b53c308d9af2ee039daf7fa073ceb78b40e79c0745c63b19f7d12f196f07653c179ad57df3f05052b7cfbf55835d10d5e36a833596ea0d072c331f9aa6692d50080b3e1446cbc723c6d8b6664630084fbb46c09c83b589ce375813a24777a15ffc44b3a2f314238d27b26430410795faa4503618e26bfb6ee28d520addf3ac4d741f4018f12c4ef7a72e85eef9e3296b13bde5454592c40eca4f8e44f3cd91a0fce4d265ef80dfa132a23c77ec5bab8b8a24899d93a31cc9e69a233939ca650b9b6b3ee4e4289a1634df7c88e6db7724899d8d3504e5a7ef080058b045085162b0ed5b45d611454962b08525c14222abca0bbeb1977393029006a3f30a235451ca71993c3a907ef550a9c29b0f4fd4706542725a3744bbbbcc656b83be9232caa8ead1aee8926fa8eccb4d98a3047110476957d086fcf3f3ec424f64354051c34cc49bf5ec3a74a84588c4f080a52c7b1b757d03914ea73c2498c14ce70eec6550a972777757daa089adb97671fd238718f5a6156343abbb5b56832b1b3d6eceee6e8cdd2bb041ca78747472d6137283fed9767458588ecc8c024bced9a29431c6d821f79ab74b2f279e342981683f5a6094abcaa60f985c36689ab1638c4647d835df2e0254869603b80177c39430ba8a96bace521aeca674b9a8358db2cfb2da69518332ae227396fcb2d94a0d5936a5a85d56dad5cccccca1369b425baa98f0840d5b92383b18dbbd41b0bba6c1c8f9681758bd5514757d7182b0edeeeeeeeeeeeeeeeeee7677735134dab62646891af678f6ae02801fd42efa5ad6a0137559f6ecb314f8dc5d972ba59431b089ba6957fa7a5a8f1eed9a6ef2612e11c020c5f892b2582cf604b6becccc31f2501b43fdc3b6350dae0d8f8e0b66558e7a543a74505795631d293640f1ae09aa52e0c0be52397faa06bb6a26a75fb8dfaaca181afc87e6400e306a112248ec113759c9bd76c5856dab4495a886f307020178d9af57a2da523a33730fef05f039257bf49c3c670ccd0ae0b3f78716784ec52d32cfc9cc2c5f88421bbb147a3cb7bc61db9a982715f5a409d414a106fbe3a2862821d41494107ba820541421d445013d3b8a898982b6bb1be5eeeefe18604b77445ddf2844134aa670376ce9196a430996eb6adfad356ada4af0476cf1f0304ea9034c8d344ad4e81c75a9f96a9a474d7a74d30b5c8c73a3976d6bbcc15eb92683945a556d8f5d2937a60555484e1a753d5c764dab75b5720f35ed679465a7c096260dee3b7b65fe56aae9a66fb575a52d55ae450359bb7dbb18824487007f478f9350c0560c47bee312d8466d99610cdb2e8d39a787375f77a8d3432d32a1c49a56eb2e98b3365f54168a14217254a4d65a8b10e1c011110e1489443850a475841cadd177b8472fb42bec1de7aaa64485a493e3d7cd4dd6e8e9b238e9c18b13a2580d49b6343104c68c2446bea34b8d5fed90a8ec32a4e1a447071770ed6aae5dfddbaf9e932b7118cad77755ed5a5f2d57f9358fb5a10d055e3ac7983e706d22cb0235ab80e827cf5701d129f835efdf5f4bc9b151bba34fa98294809447ba3df637828eb304fdcd1d4d5466d9b6a67fdd6b166705fab33dcde35d1bcd9935fa8d8046e73521763853108105a3cbeea88546b4a8d576cda83820ab9a1924454a4b699774a17e492dcd9a8e34a58bcc4b91fc32eb315af27367939f2d64240021eaf4b085b40539862351e8a7d3c4c853da35d35dfa15f3f3049616ea26b4fcdc643238e3c346fac95306523ecae619b482c98349cd2106453e6186f881dba8126377778c313633470370a9a1169be2439735c62c26ff68d56788c15a1a6f268eb18fa6695a4f748ecd22447a7a89121de289301fae92fcb024090e92b010b4d05046121bc4d840c592990f4dd3344e72861041f01024a5062321e634d139a3d6b19db08154030bc688d1243114c60922a6f4d5aab72356416fa332b70abc2cc1648c2c3c309102e628c993a13690bef480d141932eb31811664409c02f910d67bcc08a1220a29e35ae18e32706414b4a73ce394da7d3696a4e4f27133dcd93364d7482e08d0b1a7bbb18417c41aac109d73fc34bd4b41abeb0218a2e8266663f6441225212e5c77892860f609a5019424e89524a29a594329a20ab21479404880f9d65f18a1664c41eb460d2460f0d3cd044df5f57799cacaefaabdd95ba9e0122767011461a51887cb4c861064d6491a38c31c6c83ca80cb54104eda3a861630716d55d7ad4b4d5aae67783f0a1734a78a8ccc387da3951d91f30afb0a28551684e53a36a426234455914a2699a2624a73b27e6a020240e85b13293411882933037240123238a7911625ab146951d597770a9d5e46df2d8a636f1f8536f8d7af48dceeee841a2e4995cc6b441fca244085e3c91e397c8061e3e5ccd7e884c3c3ad8eb608d8fef6fd520b89520a56ecc95a045e56ea150aff145bfdd41a5caafdba2aeb76f4d7fe1eee9dcdae9a469da69e3b4537f45909c36edd4ae793c2e346b3b3992cd519c9f7cc8e6a893733ee4e4dc7764e37a615bf7476fa845a8464d9a0975a293eb340afa68fad1aeb0d5bb141d09a70323471647d620093ec2071db88dbd93ff68d7a9571e578ec391e470952359390e9f289741fb986d974eb0ace84690a83c8723c1e12b67df51790edfc1e12bdf8e86bf16549ec387a83c870e5f7d34ed0bd391a3bf1bbe7908fe8ccff82639ee866f93f36ed43a232333939ab971e264bc9af246207f1b810cf5b92e5decbe50d3f2f214b03738bc9cd6a91524d31a125d5e1ceadb3b9a0ad2355ff500dd29f595bb69004ed470f5916a1f8d693bd30781eebf69970664714c1fb736d1a3ef783281f0b8e651d3d835d79c6a9ab62c1e4f4727f2d09c06a3b7c3e342ecee6e55d7ad89261c52b3b935a76a30ea9055eab3fae26cee51abe17cf704ce3713966a0be0e2d07cf4d6e29c565cea17bbc56a97ca02629c6bf57659298fb5a8fd4222bfdfa1bcf3f6d79361be167a1fbd864ff0d684e89184efdf3c5f9be828af7aaad50e222a9d433535db7a1671c4d506bb5f3e6171742c8ed4a458b662790b2a1f25af3850c4355b87cacf9dc9bb0b32024aa9ec99951144e54e4ed248f944bb76888c263ea63e7ae917af4089abb46b87ba1c3dcbc820fa908fb61f32aaf890bb701163f9e8726eb1b963a8f671a048830c3bf9eae4d521b47aa445ac3bbad060f42dc6efc6e47dd3d427ca656894f782f781b5891e9da7a854ad75953d6d152212000000000315002028100a8603c2b1703011255df70114800c819e4a72509689a35112e3484a21630021c00000000002402432800ec2a808552a4fb95e25c5402877b4a5322d7db62dad6c132e8cc756a4ab81e467b797e7045abb852912568df70f2650b5325d894d86cb1fc2cceaa7f4a53b2411aa121acdd32841150f884341ff71075239aa00e0526bd5454689f81feed7cbe5330f6f6f72b81670d41b36820203c55794f2836f7a796f07e164cb9b3b43d0016f70e564abf27eb4606e107015389585f2baba0c8c52640f1b1faefdd18d9055e4ae3f183452f2c3b66a93c019d85ab8db0c9a7b9b136bb06e96f31e62b54639297b856d4f5dffbb68f348d062a8428b6f611e3b2c76bff2327c84eddbb32181e5292ec5284bc410db3dd79ee29ba29864a41b021cf7446b00d8ac59741a00aa43ec6f1fd360fb1b4836eae4be14065841aac902320d092400b8a798f35921e1d51d4ff3f147acce69c0f460f8396c2a22c5b7ff9c50b7aa5bbf9544aa1c0ce3d95293916278f35f190aeb3a3b54bdfca840eb9f550d09049291ea61c5d00bfe950224b653fb8406dc248996a80eea5ab516c74c6d51be03e63642d4ac53c20bc5601d4086d6991607992d789bc818b9659ca6fbd2fc77c3996afac980ca8c8aa9557e11041852b0db177de6785769f8b49423c0adfcb36f48dab1ef4bf1b349e6df0bf8e8890bd33aedca4b1689ca362fd2474b522b57a577d2f56cd7bb92cbdc466675c74ccb2bdd8689419dd5fe3a6c44d030c386f35fbd9bd9a9ca498b5289ea49700a75f87e22562a6269701704e77a9a7e4480b610bcbd0fe25d3735f7a2a43e078501d2f9af3b59b8a5a66440f5e38471bd6cf69fa3f90932d28687fc13351cef734ae645ab5f29cedc44d8817098093dbbf291e9187bc99e8338aa37af87134a5fc516b17500146cad14cc38a7608757295d269bb159af1fa6109de23b5a714f1aeaeba285c7cd7eb65c39e79f267d9b29685752b2b88af24c37c1a6c3967c726a5fcb6bd1d5fa89f69092be5429f631a294585afff90e75fa52ef394fe4b2e0fe97ceb8aee2e283ce4b46e8dc1f18a9521ddc908423b1c4ecd4bd2acc3f24c6478b9953e8dfc7d5875812b7dc4ce8bbedb54901748eb158e356d49810288b124a72f5b6d435665baf2b8cb75096b319ff67452bd40cdce4294b6ce9fdf5af6be2bfda72adb6f6b9723e63a662172d86a72002c924541e502b94bae59c33286660c22b142ffd1f98446c5f126030176f82b2f4880fe2209090c54cce25b153f5d41278cbd6c77f65b646848d19accd5f525623fdeb31ee6b37a429ba7b2b9cab8ca746afd325db899c31211d89849a3f13d066b1c1c82208a0c293e4baab5a3172bb148c91d0751ee8d6794dca74a6ce15a8e4c9f2acf084aac54ea835ddb951b78e42c56a12604453ad76e0588316e79e630022e155121fb728956d9b76811ffb0ce937023c1d7fc14726302557195794b42d74395a4c6e109feefd1746c751979075f45c15627b13447ca5eb12dabdb048c69f6b57dfdab4cce0937faee28a92691933da5abc34254f0ed4a6abe8b3efa618bdb6c4ecb559b46767514d52ebfa1013ba60cd565893b26c8ed10cb1b2e78c29bac76f7331f8d8bdad6382f9e655b80c50231fa9370ae1970134101afa358bbb95ebd91e9890b60d34a69a7f54ba088177bb87f51f28cc05e7f33352ec8e2f390c6d4fd6460feb20890c3accdf720a74ce331fc07f3fdc30ceecfcaa3e1a1654611724779164b12356a17bb06e34fea13a73e82db1931752ae161b988091310fb0178b06b301acefd8d260fa04902d20075eae7b7bfaaff3abdfdda2f5f5e79151dbc8149ccb305cf86b0334e991fda2892ae2700d445a095ebdb940cf412bfc549df3fa26b572d04c744b619c405d11c802a9ca58bdc8de369d9b0239be6a0506777a896fcb6b24345cca61cf87bcd6ef55f86ed6970822b2870f1310f08bc9737ce0ee6d2206af904c10fe6797a711cd8a1e250f42deb59981232a19f3dee4632f17adb33d5610af42943df892e6ba7aa64d4e6bb62fc6a06d12843650c310ac4b2e029378cd6144948c0d6e014d0bb8cca0568e591bf220975977724d48a3de1fd542f5357f4b3de0dc2187d89d4fcfaf6a0f3358bbc9d93149c1b463199cf5d9f0b1d90f2432f74f1bfd3b81f2709154832542c5e468504ec664a982205732bdca8b6ee4fdd2dccc7bb118c72306f47efe4554c98e90d8b51abcf094501279343567862e011460778d1bf114dee3585745627a44745b196b9d2276a810a6b327ced8fdb186845f59eb566201a617d6bf523c5ab83af73c578487239e3d48c725826560b7f99c623237ec9b71508160067a13bf28138c78d9bd65062c827a3272ef80fbad6aca177f0b5cd6f173d0277df712be1a44c2b54cb1c9e29362219b72baa2e2b457f389fd05accdfe0a589c31e53d5c04d06bc65a6e8c10d9bb6bed9e7224583e40805f1304c251b8d4bb028fb74a38e71c22139cd09382a323dc625e2390dee832172017b7d039976528f78c71062247a796dd27046ae42a3ed64270406fd0ea1dfb5916522ac5ea2ae86af1f080aa94ed907988ebd543c0a545c56644e595bbf39d10528afc2255ffaa7787730956b206f3db977fb6aa8b342f56a79c94f041cd6836379e8805b65dee2e410ac10f95767d87225c31733938e818cc5c4b469ca7204c79d72d682d32036d18d14b2c8f656e92940437ac0bba5b916409eeb5782e2d7951b9f5b708784f608ba7a00b2a335e4c050d251c5608ffbc1be4948c24e4ccb21f065f1c04fe681901e59e6492125ef744e2e98383f2fa442c63039cb224a06a128dbb4843142a17637ebb289380cbf280e12fecb68f4339407b8da83d45632c22dceecc156c962840235d25c4bd3b4edbf400115dddfe5f39785d87ab2b8b32d832406289e8c4b55e31d6e9e3ae1f589afbce00d42e944f91e34dfa49712abcbe3ead43d6d9c0ff44d54a31d623275ab89e8f7eb21e9f1a384457c6087ce273b46ffeda4568a9ff255206e2d9eea6d89a9feab252cf05c848cb4e1666cc24a5167d96850a33ea51fb387b966c434179cafbf7117eb8452449874cd3bc8f116209570c5544c873e91c5540c39a0f944c615b971c1b8bdfc4f7863a1c2a4792bd5b34279b13594776348647bf43c49f5e3533fefa0143ab7a838913f1885118996d9e01b25aa73fec0c500df6ccaf657be6ddf4617b83efe0e1b948ff2f75e67133fbffd7bfd358796c50c58628cce8985da8600fe27de7e01c4645be40fbb4fa36965b28586d7230c457c4a0ac0d50f64a8f2b7fc4befa72fc3202dec915acb054fce64d020b15812f31ea363e602b88bc809982841404bdb4373832e52762e490229d0990965642a84585c504d8a7774acfc68efe24842f97392817f5e8cd01a407220dd2ee666866a95b0f56404542cf2cf260fb33bd1bd503a0345ca6f8795f256f24e7d70a9bc3dc6b74663f0aa66ba497734a4c42f947bc7d920f26cb9409dae8ae3a50c4aa175f286e158b49c779cb40ac970b41ce465d1400ca9fac15fddb8b003bb716775818859f1cde3d5825ff9d3b28bdf58e08300b9519a4746b3123a84c0222f70ea6756eb6f2efaf2c31bc12349e35971fa222c211174177709e20812fbad902887a647be6ee7c8e8cce768f3ceb3f31a653e725087fd234d37a3f889c94ce2bcb3eddb26cf71a7fc6a638fd3809c7dc2755a6f9a5805df71be07364dd414864ffc1cba49ef49b1c4891a395cc0430d12e2b63bcd4184a9171c102008010696f7efbbfb72fad429475639b5087b270501d64373b3bb86edb8bbe381f37454fb9b449cf75d3b0526c0865a9b92f1ca8f3a0a5fc1b605bab481afd2b68d415d0e33b083d0faddec5e43fadc4482c8d1a42c0ca264835adbf5a3a1e87d40df4f617ae81ec061088c0d387e6a1c99e7038cb1bab9185663156f827dcf500cb8b91ed11f1d7c212219bd1bc781bffb1f131c65f40b787e223cbde936c2df7c23a941c94cc768303d25289c99ed202f63b0736fb0698abe47cde91c70b3e9d33a5883a07bc9859171d6b7db2ff157f737dc83826bdb6c8ca1b71df1ca807b08ab2429d790c91b5bb7bf36d79876b393d4e2c5aa608866d26d48e9262f09206188151881afc08b93c26ad1b1445730540b221edfae68fe16fcd8b420c1e48fc0562f9db0a2eab33de100e333dfb4a0b1a55262bf09534e07795483f5c10a5a46912ae088e205c88ce5e1a38a1c846571b2032e008849c5c8324e042cd53770a519739f7c508b37753f91105e88008f72d6a8bf6c2027a76b3b0b0280965c8b8f817c85f9f889d5464bf47a6e66cfd8a09a4721ea586dc82697aa6a581ef0c7cd76302fc6e1575c551109d02c3460215a800fb27030695a0703cad545ced9cd18cfb14e71e80dfd89bdf75c8df576c80fe5d9e00c41718425afabe6de4d3e61f180e42491a7a909053c959f70659f813ae9c3af5d34289cbb39f52fe57f6b39de01f9b9e761f383ff6ed3f6bba26d383c6732edde05b97e65aba099eeed9331f2fa4b7dcd34515fcaad39e19c2ab9139cb4b274bb55fde5324d5f00457edfe73fe683844238b3c17e1c79acb2d7e5401c27a915cc57d1e5b25148d2c7b5081b1cca4175f4c5dc88094ca5125b66e10aa80e61d30e1c632818d34566ef28e46780ce21c841f0a599986fda3b4d4fd7cdea9a199d0174ad401fb74cb49379903254b7ee5b630b32e600cc44cedc0f53037a8dc0f7b3fb15c11f75e270e8af42f7196d1b222dac9ae3b7da27fa45ec9b6aff45ed42129087b66da5f9e659f65f45f94d2879dac8afa01129d0da1f511e919ea44475e612ece7abff5b3deb8c484ec93e9c5178357ae7128998e7bf83dced982d0c0287897bc817fa6d9bcc990e0433bc02f9b43b17a84539835d99a2896a6164fad2c2ac160fd99696bf54434f011ecb891ec7108f765db3d2c4541d4d8bfb13910f057284b6741dfa0be56c8c7d8e52ff0c20a9d01f5931e82cf23ea3b0aa764d32f152a99e4b5b05fa6104837397f138e99f3f82844cad4dc16f429e0e0b7ea3e1f2d9890390dae6d004e5a43a76e501e81f8b077774a0f6264f74d213490281f60c65ca604143b3eeaa9bb63ab4bac530f79d5a0ddeb7089abb754fe6755551efef6432aea5ee0f6ec2e19681e8e676059f5428383ec7f456040e624d1e840f31fb1811b04a7b30206b20afc9a62aaf65400585099160ddcacdebdb556c6d13dd34c003678b5618129ab3b0c355446eb4d94e00a69730bec25c3a20ed4624889fd2fd59ec8f5cc4a34146fbd179227e06b607d7e0fa0100a2ef832ab07358ddc28af6844bb0aa3a5639855a5634c08e806fddc225c981b66c378ae56ba5d70e160150618086a2368e2b262581e50fa1b29a5fcbc9bc5dae05ad30ae7c28d1d9b85d6ad4994e073ab74a50c13a6ed2e5d7b33af534f04655322e3cb63ae8234c1e6161a7616a5814a0981816279488a96e1551d5c5342bcad5bae2998176451ff42a8de544d0624f02830bd5d87cf84c6acb4dbde9a63e3db1fe66d9fb84e66e096d2d35b4595a8f0a86576f7b6e98605447f4fb643774df77d595032f9596c79449f36a5de9953959569ca84e8f5b2733f6bf08386a0cabb23d56c9ff6742c5e2d3ac0620e3677fbbf8f52f37b3956231fc64c19279b3fc650ec3db12fe4e2d8962179e80358f6e76d76d6c53660e8d279b67beb98a0812de38c03e8574c2610f14bb08d89e29987a072864a53c101ffbf61ab18ea55b3eaca7b3ade282a63efe5a3175bc2b3f09100ccf1c1d43584d432a4368b5d2373fe3971f2161d46dfa498b7b371c72fee807bf5c2eca052f8e6a40b0c9d76d47b11e858e6a885a8e82980cc7cb0a6830e8f16cb644b4dd5a9edee77db4c0b4ab352e3570599cec618d498e23e7152bb4da0921ed19e168746beee3abd6897a3f4883046e85fc3eb1b8088b8e9afa71f60b37123b53e6c34a08ec60be102f7ef59fbadf8b87881c5e7c803758fb9c23d577560c8e44244a716b17d27c7cc6a27a90acd1c868c5e15e2f051916d7162244af5758355ff02694affee61386b05c5e5efbbdf4238254ccb5b1e84a873d9e9d49d900df30fa2bba1e586b20a149d087dfd214e553920c61d339f8f26d483ea53e0f629bf88322bd0027c42816415e0eaeb3a33c063a795d2399287c30454b90b358059dd792f47b7e0de3e5cd7088f9c0b266d87170b3e5c06c1377ff203e31081fac0b59e180d3a2366abb56320344c66fd4d988b695a9a82b1abdf700d78a45542170e02a0f3a1a6b6b8ec70e5af774501b437c92e14dd35e057637ef69a7e464f25e530885fa7c4df7da5cd2d4ae0eecb16a8074506c05dac22de0a84169a7e8e78194f646684cc99f5ee8253edd0a6351f4deba98798357341a81b03f8e0a81237385f6458b44aca09e2507ddb7e17cc9d29cf0855f8ca46124cdfb0b6fbcef933dc0f2d9667450b8da186271b658760d7bb341eebc1eb0d7547435485ddf74762b7bda2715a14b25bde8fe160a485a69a79e717457ecdfc4a6d27e3c2fd8909440030329e69bf91e4b88c2a34eb9b20fb9756044fda72ef6765e8a2d481fb0ab41e7c501d8b765c20ed5aa5e8e99930aff86b0ffaf584b044432b93e6ecc92129147f97e9fa1cfe02755c74a70daaf2ec1bc4f02b784217197513c68368d578fb05b49861082700622618196047ffa57937199da5430b9abd64a742fe062f4a09cc62e08ed91197d9dd3f9fbb66769b53f1ef4155bef863362570c14e21709c1045259418b6a38ebb7f7d0cef00266c660d88677e33eba8e346afc9fd9b9987af6e227bbb525d08e5949bc667e3822c21cf696f955eb0bd4abf2cdd44ec5a19599b91e991d8692ee54927079e5d2da0b6aeaa05956f86ed35824e603a965a7e87879b1c468463ee02afe038a6217de7e470f9d06eb3fed212e6b85185a323363978ac299171752d3f71f8e5ed114c276797cea9c939db076823c7cd1e43ad138534a31fac2158f149418137e78c9a2a999b1b8a0758390d1c02c19f83f7606d9534999d731109ed88c46a2fbae928dff18a7005faa4fc7f906c8907d5447131213418150cd65169a9222e75d292a236a38738af53c6f9cd2334ae16e94ed185e8cdc65490f30fb7340c8808ed09e43bdb5902c7530b1cc75b01a89e07457bd87e3dd577965b7ecfe7334401e27ec1bcd2b2d718873d602324a22d6bb391cfd8422e1472d2d130013c2f622aa97ff1788ede82d061dff9bb1942bf327cc1793ea43f14cf4f2dcaf3a9e58cfdcdc225b11f3b7d4db6f345154354f4a5e9e164c5e3fd9d74b22f0d9bfd7cd61e608807b8c43e60f9ec275c484d49ee064476f0f63dddeb761ce8a23950683d6bd04938e97faa68a191934987087afe3eebb45c31f7284be837311e8a78badde14be6e32f8d05f9cbb25e702a684a327f0f26ecf6f8829357a18e1c6ec400c6d2ee2afbdaff08c5dbe7dfbcf0ae44cea24494fb2af785054ee380974440fa7a9de9e43fe0f430b2ab8ed2008c9f61d4803f855a596153ba1e4c08c508008be4f53b7d210e7048b618b0fa4a09e55213ec64f01968589293272116724be2b4fddf5e6eb8e4ad01f89ce03be24bfd6043c3ce5da58ec1360a5fc22191c02b4c11de47f8bda7ebaafab0a99257cd3ff9d74d8466d9b923e05f167072cb48df748638e5f770cc730aefba7550d4e36da07ce56cd81f02743af15085ca23ce7b446d317eb9d66c9c2a7e111314b743331feb623e4c0f8976f686ad85a08b8754e761bfb8d722286358db2e05f782d3fefb6a9f09bbea62c7484a032d6e0e7d7df3a0780ab127ae914ea3608fd0447230d2aa86fe9d74943a6633414cd45f34c2b2bd7667a65756128cb7ceef3ac488a98956395f0aa423dbb3d0f67ab66e0f100a44803a72674b708ac3e21491c93c861bf8613c5980cffcf6a0287433c42811556c2e5aea46f7feb515a9c3b59a001c662062d1244f3929349bea716973c447a8522df25016b1accabc96cd2660aed5a7ee4adfb07dddd5b14765ffff875c08829810f832ae60bec71d4cc0f6b725f2aca084aba5fbb723109593a822defccbd14b780059f10a7ffd11c0a223813aeb0128744b067b2b26dd2e8081a8f5029922be06180426a12ad24ea1edbb9d800eb2510cbeb874ec9603e287bc0740e8ee23553ebb21cbfbe378dd723308b1d5cb401dfa10361d79dcf24ea9ce298934a3acd06bc29f9b65dcc047e21d8233970a25daf91b1162aca18a89d576024aa59adc023fd1ceb1e0f80310940a810b73e3186e18af795b38a5e1883216a20ead6efa701c85d8d3b96ebf0424b8dab333833a3912904ea94fce5d8b1dee9e52bb436453e445f62e47d040fa7d6d7fa395fbf31d4440298c7bf0942ec73bd1f2650166aebc6b82030cb1a448a70d2c3c5d34e5e3cefece78a053ab24a430929ecd644ebd283819339269c130e1ed2eb9b14f946cceed5a6b8b81e165a147bbf047f92a02f5b90e67c8ffd1cc3eab31c136a325c67f89a335d44093181bff05dfa66e43ecb800f6ee3ae898063489165374f059d133ef60ccf8ebaadd88af388c06c0b20aa9848b853dcc8b3ee76524a59a70be573095c428c18631b4874811602933942b55b353911828a2ab041164f63c3cb1a8d4a0faee8ed2e835d08a350c6a6e0da73b45d7e5891c91bc7b336015e6ffb485b5c6c39d2c079895fc10663a50d4b54689f32392f17a512ea781002ab53563cd5edb6f17e8179f621ea1648ff2d3043538f48bd5acae50e8f40e8c59cb93ae58612b75e44ff7f982f53d08dbde05c638328726fbc57a271bb27e976be6c8c237c941fb8d6e003e772c44d06f10322adab5f7057f84de73ed289210543ac1e8d61bca04746fdd2025cf5e8e756bb065bdec5f444e2e665557d84b540982c6d8cbca1052ae827bf9857b172469fabd1ce5edb5315e39fa5ee674be04db51c19194b33527c1435c8e3e915b3102bc949c61a397e8367f7466bfd9c339fa2553b9c2712e93f0f80665ed62bdba01f147b607e92bcdee5e99ea2b25ddbd7526d76181e306fd2596b56bcf3f74361edd5dafa42b8edcaaeb3ea43072ad2ec4ccaa8d8b511bafcb663a97c457ded1482e79974851bec3fde53f24340b689c3bf9223a779dfa30b4075d5b4ee5c4dd4196ed311ceefc73ec541afc733546f16ad1cbd467520469b180acc12c337a63c318c7c45000394b10e2b5f2729911db28a70f7b23de1a6652aaaaaff025ff792a4c3677222ffe055dae072597875220059fde7192e859ccd9c8b0b0b7019334654e8c42aba7ea771806f13cd6969f8b3577074a9a24ba5f393ae93ba09776c1c3ede2d7859884a3ee117af959ff1b3f0bc27eb2cfac902ce9784fd2e00fc14ef04a1b547a464a765919f1a2688f5b1453f95b491f18c9d9b2f8878bfb88611f9efe9de432e95e1eca1351fcff06fbd76de318ed459113a488a46fea0cde8445fc48650e46caac39c01cfb07d94c7418a84bfa00eb5f095c45f08338d0a4e5576f23b71e846e05a422e252a44f1a55b3707fabe45bf16aba908f824fbb9124c5d29bc9cac674b39751911d49b1dd7b58f5563ce2d675910f4c7c78b065cd4bb1e036261960b4bb30b5a93f4b0cc613dec7593f523a8dab3c3e113027553e11d846411355f0b080e2dbfb9652f132b04a7e883b7362067fc7bb4653250f77e1ee98b4d75462af2be22873b2266ff3199c2e77434de3c7b71fccdb78cc82448f864a49923812b9d18b8dd65f33376280ff989108684b31bf8a99366021f39a7170b70537922d9ab953772d17c291858d2c62829367030dd94fffcf5a0bf1119ad55d52cb48437110dde5745b7bdd944e4fa9c0f83d5d37ca9c83decfc2e0508404e217f7cc459b73336a17d94cd8cd7e1059160231691a1398a5af42c7c95123f680fcd59a57ca08d935c80ad86fa9a61812aac52e804e613b49cef4b9a16eb8ba1ca77867235a4b38190aa2efaaeca564ebb7e55088b1c81050f841813646f47a47e051ea2bd19c0f586cf467b23ee6db094039afd1e609d25c808b4842c7fa310ee7d35e5261d27610ef6976888ce064c8005ab4a86c4eca818ceee60bd85d110dca0e463772fa48c390c11bcf52a91ed79da2620a55f2c5cc78d5a730676de0a2e2fbe65ca184958cb7cd191569266aa259b1619a0d0fed1b5de08bea0f84ff26874db511c274f1c7dc8ca10f981779ee57255b078ac71992ccc0d46243dfc391f083105d1b170070d8f07b8a605e206fd8e12e9f0e56442e61978f7723fa3d2ba2e274244475f12c5eda44208aae74a4247e5ef5ba51a22e9abf0137dc87b413fd9b6ab3896fd1827eb18d21114798c1ec351099763dcf370679e5923c2ba485420eb94b6b7a3977cb9768c2e80bbf6340bbbf39e2750a508691f7e8f7767adda94f952171af6df48907216bb84e9a7dc4da8039b63fa85ee1d400d0d16b147918a2291f40d69b4759bda84c54d44c94b51b0816335dd16af028d226a4d0a2acba998e67c15c944674bd22a2a9527391b535d925c30e595edc8c3198d0521eed115025f580736ece28abf8dc3b1a27623ac00722d3fb8322a6be927b4b82b37e4a919518898abab14c30cc9ef2af219a9b21bd1e040a15d82aa6ba6c18ebda9271e0750d42f27ad683018761e4196adfb40bdba6930c016187617a9c0ac518bf9ee3f21889f0fe402b77d5993761332bb6b0309fad100640c59305209be186ab8b0b1f0aa3c03c0c7d25273f058879bf4fc3965129040d247ff7b697328a843970c86b6182a4edbab4e4f1aef954934a90ff8e45ca6053cde370d30a2485f4f50b13e93bbb9462d6b277c274a743f97ab5a0effa9909c998e5d036d99a7e5eb3198fb15f4d286eec617f2e6f5edaf47b3571145d0ee726ab0dda81c2c7bcf3d1a66226c6056084c4b6513a5d08ffad865d39819c1e354308cd0978d78a7a6262dd941ebcd232e01043e48040519df68f85e98b18d7be3608e618c9851e42ce1e0d39a8bf388d3a95780ff8f8d5c6c558262b182f8b9fd14b8df9d09facd8b0a0cef1c3436b1fbd34379c25342d89e6446ac220b04e10f15ca07e52f6a99ec06aa1f80b5e7c47cac1f70e8a90cf60b8dfc2953d62b8a20eff90c1c8a2e65453954f21634c56d62d17e67135ae13ab5b05a1dd441309ef81ad6b9a5c599823fdbb1107641a6273053a2eacf1e5de558ba72079965accf28fa5b09bb8d48464f830c16aca8f4f3c08139c90a5013ea3956b9934f8ab72f987fff7b599203f6d4ed67143273a30e987281792ca7d508ac8da38a3fb96eb419638c7b3eea6a36363a463cc1a4195eb82c697630a87e46b17f11f2239f32b231ffa2137cdcc20dc40ee6e31ab0676c24902151864ebc0d09526ac3903869ce4bd0a264a065cde78dbab18fcc7c4133171b1e69bd4e57b4877701326b13d34da52ec1947941ddcb94061e6f68237b3e40c7a52ad300f915a65e0b64d81199c5602e82cf477f5c859546770b2e816c8fe5d03c58498477e804df1da3574e6c5e0c97226d8c92d330db14ccf8dffcbd27b51b0dd3bd450981b7ad5d9ce5cab02b9ffa6f24f5a348a3197fb6324eaf86166abf238488002f018844338c962b70d8750200672d098391d9e2c45aef54e09d91174bc02ce6d0956d9347d08357fed0619c8de225d0446e4d72788be38458cf6c15e7cebf2cd8811361f178e4d74729ccbef8a0de8ed6c99beb156ca465c1d2291e1d23c87559a567e0a461cf8d2e3f728129fbaef387c7436dd524d5fa166e9d356c86289d7460f0f9944aae5dc3474dc300e48c09f61f409e4f4cdbb29165c2818c9eadbc41e81f9923f702a317e4e06d3a38ada5162e8c899f9951f3de0a19771e68fbab6708b9aeddb16a4dbe4a968dcaec3c407389da6bd92cd0c65fa5161d64faa8344cc680e3252936e9188a6540ad8e26f5d113a5055e439df0a8cffd81d567085b93252772f61ebb019ee97660b77e78d52511a22ee5050409c215e1e67636caefed4f2c90e12fecb8d19f689686f6d169eec4cd0f43f7a2d3e7b84475bc7bfcba39a928234b9ff4aba8bd1debe83e8f927cfd568d8c11711f19610962ebdf78830c9bb44ef8cc2bc3342d5eae70033bb89254b179693a1b5247e6dd62a68e1a24236e8c1101b000bf7d14230a90736270b3ccca483aff9bcb93b41e53e8d6dcb82583ab745802f53a1943b08c9ddc40ff6958b5d8ce4eb0d542a9ddb596a227844fae18bf0ee835761576665c02d878677a180317492444202f4cafcba7e2f86ee301f96a61c3fc107acb7d36684e7ee4efd52fbb1dff185b664fa3a3398cca908b380cc877c520851c9ef3589765f1d3adcf88869a2fda3584afd61fe8a1818238fe59c21c19c4b054b5c0c46b812e45952622b66d809227968e7f50c2d19173a6d470dd249520c74bf1089a1f50306030f665cdb31904b7ca0f534c5c5ad92af887618a94716d3d5461f628a568aa0b5e36d5942d8954d19f42e813340090926ed8fd68d2bbd46688414be9ac4406e28d292e5d42f496197e5848812468d86632304e72571542f1af3413ba296a18182a82990c554d1e9758df5c3ba4ea48d4756c3a79345722b24ebb3a0e6982ceeeae46c921aa6b735a4b69b6936b1a0f2d3302a101155311f3c5e8976744508c2cd3d96101fdaff1b27b72e7d1f97a669b3dbc795292be76735878c6ab4131060af817a794e6b6b6823517d0de6ce2634f3e29137304817c9cfc6181c2c977494f21a749a9ae1838c1e0a5650b4e6d370c0a5fac91b5364883b26f988d4104bd41b0d2e95d344f1a691c970c90837b23275baa872366014223be4aefc2c230d229b7b29921ff665a6c4ded0bbcfc87f8ecd010d9046882c8bec836b0f6461defc16c8999d98dd0bc9e650884fa113560112be501342813ae5990de32f01850cdd57ab967cb5069e387c7c455d50aed64b71047504d495ee22f0bca340f5f7d812e2a1f53ec10183ebc67decce1239f204066676f735180cb3bb0d002eb78814f58ec80e96908ad56d690bbeaf25e4d985cbc18960cd212792e697226835b3964dec804b23c5a9855a57f6051c31f9aa16a1d043f12d13e768c326aa28fcf547d37e9cc2895c122b8df44b7817d33a228585640c8b474dd39b0e751045ac7e0894253dae41f98f222b9668408e0796c61f49cf01e1b0351cce659a875317415032dfea0cbe13a6e4ded76893b3fae48a03e08bab72e1a0e8efbd909e11178fed8351f5d545c1139750fc061ec6bc9f38aacd045c73c32c77aaedf16cb24314d64f58427ee5a3d695d7353fc4bf4e925f6bf1f2431d20927a036d12c5e62e9a5e9bb110d642a0153f0161036e40b357219b69ee27d546a9cbae3b99f24c0e8dabfd1207ff9d14743a274411ced4aaf5c25090970df5501243c418def9e4b2522d41812b45abc0b21280ba3b9da5dbedc76c336100059ac69b2f2d38ec5aa950bea0d898a57e6e5ddcc73e545f538b5889e47a6e0444e41f0ce3f870e5e6f31eb2e33acb21b807e2a195be733b2457c002beb281d879c02a48f37a691823ef83ca4181a346bf7f90567806734ec1c4aca334ab69f1d49bd154591068d341f52a2d650be0bbc3a7a84e2c9c50e0ca0b70cc9b39be6505565d9113587220e2665bdd20a4e32080516585ccdaa4214b01c9849820a3c8871f69f03503b4cc08273d3260c3452bb938775cc9b151ddeee3ee3cc841ed320ba1237d819904410aface7eb71b773abc45d251b755e799288b4d63f0ba373d84ec4b8ad973d824c2f6d57781949c12af5a7ae72ed8bf97745fcf44b588c4582fad6460b562e783dcea0ac4c52a6502981046c3997786703ca5a32b8c9dff99e9e8ee4595212c1e7cd930e4bd69e48134302d1613976fc2682cf184a0233df653c65939ca5a845b674b81fe387d4077f09e42f426e4df9fc3211797125dbd5ea41242c5730b7d21ce2e75b21e8151a7664f9c9810743e50908ab7161fe87c2166c8ef2391c4d5b1987f869f80b8caf3c64a45cdf6160cbf6b84db051bcf87f974209ae7eae64d190fa00c30863c010681e3af6646d57b7c2cf09fe7fae7d9166d9b85235b232733ba64b46f048020e3de84514775f25a4bafa16c5c488f8511b7daab4f03c3cad651f2ac654109de20632e9b452c52ab0566ea0c9835b42195023c8a97405fb38a5d34eb7dbda2704b6387595d01c88e57e58b70673db036bebce155252597bbfe10d59fb4291724721387bd87c3bb36dd596a41f05bf49d6e0f235905b84208d124358b994e1d438c63923a331a308e1794ef41de6dae1ba8522a7a35bf78b770475d70cb5979f97c194b333c8b0db7db656519f855f55c6e4b68fa5608e9f948cfa97b6ee00ffe50666357d4ebf115f6e2c9b4b5341946c564e3d9f31934a326bccd07078f6c3c807d940bf5af88c2bde5ea59d7868d4073c1aad997d2b6219b696af9ac8eefeb368202c8b10e824f4a59ea281905da0e43d4c3356e3cad4dbb8286b95271b63a6a9bc2b16fccec6ded99b89304c7517e7e619426de64c61b4bf08f266a70df417b2627da759bb83ea4f2a18c148236b1a50a6cae115009fa27b1a3e9fcef9598dcf2a585a49e24b1afbb842a7e3550280c2c3d801bdf0fb264dab30d091e4f9f74c01cb89e8d0c9b85241254b9ce330f98b90e72450305744e8b05d1b854edc4d2d4469e3c50d1ef870fc5721da6132c95cd7b0c44adc4db039fcdb2a1087f2d5058ab6d3b723a7a145b6b02deac6a7b069b0c6cc61e7be7fb9a7bdf13505bd11b02a57212e08c5333a2973bd62d4436b5640be6665c269580582b868fb1204008e6e292a539299563692a650a319c6b5a426f4523ebc69afc74b334999f5f71bdb9785d3d59fcd4b164e9720153a852d8a205a08f35894e936f460146ffa1e0715f56283e7216d0d8b3658bf3f0a5cc0a7abfb0a69d6de130d801bcc1306eae3c2219d192065ad138a08ac57fd51ed1ff34e2411be2020d63d83de2d2767bd0507763fa8c0b574988c0a67b5efce75aadac42995e65fbdc1aac7b47a98bd4787c15820309e39328744c08123f365c2a13abb04d8d763e01ac20ab4e5b2259bc6a738ed0146c0a87ffab50775ae16b56e3ff714957a33aec254a8c86a3424652edbafcd9b0ade51d0a74b4d3f6a56b41cf1bc4b7d6a584d4dc8a0ab831bd7121a39a79e974b172dfc8d12e8bdd0f136bdf40acf712244da352f5c61962a94e8b2d44bfa81bcdfeeee22e24fa8743f5ad0df096efdf172249247904021ae8efe15422900c00c3eff20a16050f83ebcb5d3d02c4300e44aa52f83a0702306dddbba84209b96feeb11e0498264cc50babf4545716102301459c9eec3cfeb4e55cdf1f3ea903f709f2f8f3aba7e3fda513c62951264f2028089a7fbb8b409bedbb3a73c22607cba5f646004b19eb537e9a0ca6893de572c00633487a8cef45870234e3406f4c6e2f85ea5d5559a277ed076bca495a8b682fbd7e40d346a8c53cb723158df84a05b5df3e69dd5d0c2ecd3f5d20b37389ca5c45f763bf77a37b5d274f0d43028ebd991186aac32b2e565c4081e64068340485e9a16ff12eaadf5684a87f31cc17a27fe7ea86fb6c055429bff042975cb51aa8ecf2af6ca113dcc59504886cad62318161d8542d0a08270136143ba2ce4570f81fe09a68337b1a73a50b372143de237e4848299d755f9e33b7e681c8ebc993ba1035a7c1407120bd63715e9c99a529cdb3b6980b756f19b0acb850ef62eec5af6b38482146c54847c25b81ac1989de646f191df313bb571628c2b08f2e7f8d7e710f8e14faf4c48874d40515d211fad5becd201d060e9518c3f271f1208456d86affb134294f9235fd3f6fadca72e835be09f727891ff126340a2217e746795df2ca29a340fc0237cc9d2a5fb83a682ec4896dc3b34b9abbbf8fcccde25a0a22dc78fbc806fc54389f2454c2cbabfde26e6ac67dce8f592a536425c321aa1f49a1e2a05cfa708b903b6fb1109b01970669e955668533c3295e107d65dbfc2c26c7a678b4b88c3d3bfa8bfec9dcf7cc888cf58902a128ffec68d9b006d89887836a7bf32fa84982d996b94cbde669db19df1b606ea50f23e06fd616c900c1a04e7800fa5dd62160043d6a1374d043630093a388f014d26f7f8428e6644d0b5d0825a3fd8155e2ee8fec9add6e992269d148528a551552c4bd45daabd0a7621f5c93e043d6de44f2e9a15e5ff19b7201424bbb4037c4e4a517f7da55b45a1e43cd5ada7b90115d7a5a0020ae94a5c08d5cffb2100d2fa24a8b889aee275a582966c51566144948454b70c732ce4fd5732aa6f19846660f3f8ebc4fcb471e5ac46d5e726341551e40b6423a158138cf32d7c4f8faa72fe42884a7a11ee538e21b06953eeb2b2d42a459368ce074101650f4b4fd9e29ac78aa0413b03182a0a119d9fad4a37fb7e1fd39a8eb9f15512e7217a21b215cec76011f2a70b84b6ae3f6763d3a9cd0b07397f1a91ba9bf73582483f4890b80ddbb3eaa099e42b7248f2742b92b89ee7e84e0991bb8ce15c58aa6b0d478cdff13bd04890bee0c3eb3d352a2959bc0b642c5cb2daef458844ddbdfc4eb0863e88c2d462634de9012dd88bdba5f89001b64bef1ab18bb90c06ad32bbc640e07874e96fdda94dd77b0c5b7c443eeb3656d3b843ecf0ed98b0980568ac67bc0ccdf39d8e503892ae348105070cc046f3631185873c22f81c0c0e87403d1a72e4c91af386211f8fdcb26e1320966ff3216ccc2e44c54d0c6041d9ed3be79f1fef9cb68165bcd58a03f410ca2ffed909a3b331377b40f7785b42d8989db773150ac0fe839e924e0f1239b7c9f9b06ee03c1f4fa2c22fd1d16eb731d86aca6c5aed6e8dd8d151bf44000a970464880b33678be32582b3f7e6f182aa95e97b50010cb34fd642ded0ca23d708fb364f7ab36582039b7a34cb006670fda09a2c1f5bf3f0da2978bb0c8395abf5cc7ed676b2ebf7227f52601e27144f54d6ad740c3e3c8fcf67bf7a86f6a62abafe7729952519a01e5a01b81e9a57f257f38f310f410e322b9d07b800a0aab4e3f5c5af2fe5d0dfcfeb2046b7b53485b8ac9d70c600683cd70da2a6e336a867c084d4c55101716fb1b0cf9a37aaacab24e7147517d9fad0e72a2dc8b63c488260a6600c5582da101d75626cc85c34613a4f2cccfc24863a628fc47a5c812d3876f501e94e09695e05165a298f56a8d1043a6c23c06fb0d3e0d7c81b9dfecd43a535e0adce36743b5f2c2a8e591fdec67849249acd45339b77037e5688859586e2b8527686648ecba0f1ebcd5812508a296aefccffe1011f59eac70ff2e6cca1b781e26651b9a8f0a853c51ede9a0060e189705abba66312a9fb5c743aa0908816491822aa30b298491b7afce5489a7ddb4663904376656cd8e8cc113bc5f095092d9852382428e9e6cdc6112eb124aa17a91196c97e53bc66d1f7c1a3cb96efffcf8b526317cf410530512a661782375212aa73405d4543600e5682510d1a222c60938144c0bfa7c36e0c60f2ca2359c0f413eb31059e45580a6ab975835f3f897364c787bfa60ac80b6dcd2a7a09fcbeca5d8c4a57d37c3779879a198a5be3dd8dc74f5039a11360b9952eff5f8bc0ceba9effda60027092c5ada7912d9e8ea9a881c9e2782549725445843f451bfd99c52d2acb64f7b6d07f9ce6ebdb474ed9dbda55825801dc21336196c48faafa2068d9b8e75674e94b54978206d24987a0197f12e22ca50044e41d17f7acf9f52c59a1a51efb1f082e99dab7be12a57115145b8cab507b976b28105340aec6c0dbf316178c64dfb384d84f89a525256933082cf79e9849878ea29b1c8b30e8ca6167556eefdb01dd31c70868dd791427b72220722f513321d3360584f13e53718d8e5d4addca8b92a3189207d8c331fff6bfedbae65a770ca88512cb6c82f12f6c9d9b6e109873ee17bc6f2475f0972a17b5eb10275817fd12677ffe50bbc82f6d20858ca622b9344f0db6693d15ebcc1090c0b655bb77c2fd5b2efb15a067076e79cb6b7dca71f244c9dc66488b716c7c3c607c14d02f4510cf9d37ed98fe978ec9182c3a220fc460bafdf2302f9419fd7c445002b0a51810b388747db44f3698db0c72c476345948bf99179130230b536a6fcdacf12b9301d5a59a8c56dbb9875d5132e75fa7070b9a7b342a599d74cfcd400dcedb9337850ec75cfea95c72f0419bf2920c760d39bb82dd76772a09daf08471ddd72896625b621a1e26b929a9667e77a654fdbd1a5ccf570b9b2b7a583a97de53f320ff4807576d82867f6398cbd514d3e26bb3fc37fa0fa8759fe8f87d09acff0cf4cdc752f0e873b67f9770c948e4b4247a5e7dd1640d0f549d116a5463d82c665f9b81c17124f10f1a27cb490b73654cb59bf7d93045deb21568392a890e6e40d9de8bb2e4b433d1a925f989a43830f0d751cc4e38e7b26ae25864cf89500b8687151159a7621276e45685757a309775559dafe2cd0cdf03fb16bf307176089c33e1d8f540cd8dfe7238477280d0dbce0bb6cacc01d09374bf04a40a927ac25c4e4adb7a6ca45e49a4157bc444640765c629999ffb4ab00748684b749b13c7caedf82fb8c2aa51cff1abc06e0310d06f6ca3206db4f7de2b2f1f0ed7c2631f984d4a7a7fdfb404070d9fa98cd760e4757867325558b01e00e5e4b859d6a9b49ec0d467a9d7fe4054c8762bd0b8f5f1fbcbf420b5671de585db87b69c19e52cfa62654c50b1362ed6d964f1edb5ec89c75027e32d9d5e9e48186dbe49f09e893aab69a54925b1917333009a9664cc60e5c570f5af34a81a0b0fc6b423fdbbfdadb3b84b4cb353d1755ed7a7b889294a839939f533e7b9316073984b512123b3f45930d6ebbdd9876c29c557debf32fc50c0bdf3651307c51daa06fce71f19a99026b1736db47d5c3eecb1b5b6a222c6d981e27928ed18285cf369ef2f61e86b5acb7fb1f36b11cd88402bc2861675281c82468edb800c7afa177e6dfbc134518c08c54f7cbe1d5e3f696161736300df90a79853e8e8674c591eccdc7e4847166d860d25f01fccf33368cf55ff14dc92303bba0ff7d72eaf58793823c109ce6defb5b2b35615a0e11d130b60b5a6c05a0829412619a325c400b8cd26c5d66b5c6d3462ab8e9f17c67095f67d6a89aff37e50d0b8f0b0b78cd4114863f0dcfa90f218a9753b2e13f1f5bb7e724831c24203ad16ecb96197327997e7e5e9e84ffee65f2abdcff45f18dcf8b868c41397e845207f19d92f8455569a6986911ece9c540d9032fbcbe41377b0fe555caeaf94d1acb771f2a8f5aa7a1e081e01dcc75b5e90153bcc273550c5c928c23ad17635e3b3796d4981b3a4bbbb6b8961f1fdb9debd12fa6e8885c77c594ffd50da3ce7f90643cb448949dca8e7e9b3ffd622c807920915da568c66bf68ee24127661a503148e83ca14e0e3945f2c4db94120ea62e7f19bf1a49732b3728193076343dd50c8ab38999b02eddc94a3f15465a84d4d4ca0c3b227214fe601f1708c0335559e3599b38e64754630ea889bbf388afcaf4a03f1cac116be6becfa46f3898adc332aa6b42f98412a6543c325162271b42f9474f676a0d3c6a08dd7600b2deeff48e312e15622941a8db9b001f679a920cc7f5ccc4a4b205b0c137ba699125d2f51b03ee246d27e1270e0a2948c0e263658a8996d3b290e3748ca6e420f017817a24386422731266c82d3cfeb7923fd5825d67800843ec312edd94a0c3e78c6e9de955b68a614e16e1cace32e3e90b3217db517fb8fda6cd49c13fc07891469fc9f949a1118504c9c6c339c66bb9dae28b5a23bb588c7c245257a140ab95ff6e909d59d4e69b57d2cf06406d3850d34d5e609574b26457585b1a0fa610bf8dad53cd7d173a41e89f6ac95d999f9264f7c20fb887ec0317b00c8247a13a120fff976f81269d57d3026a95c7855b8bae352e5d30838755012779645fe7580c8772fcb8787431694b780dbc58fb47b4a8d1cb2074588074b20b9a10ed024c1fc80141e3ba170f0778e045eb34b3fc00cefdf196997d587dd964f87efb26f62a0579af24276a934a4958bea1b54834ae07e42c9ba21b0b70e1d5c3a1918955773706d97d8371b13a2adb59d00f276fcc7ec80a87f4ac7e6aeb918d93dd02582e88449e30899c752bd47db30c6cb6c6049e9c44a4d698da3cbeeda3c314bd7912bd1780252b9944f512003a711c2b8b7cf8624aaed96171aaf50fc11d941c58acd79a31101b3122a740e326871b6694cefe771397f3c7ca7c0f24d8276dc1c3af0abfbfe1229bef80ba6753c327647fe9638a591209b694b3a0f49ddbeeb1fd17c4e9b4491c642d3afd131bb7f6cd67b475e4f63c0cbfaad87ab9f08bac8fc45812cd79f75cea5ae1001d957772e82b1c15f4be7cad543504d578a38b0a3a339775fe44d207cdaa1c7a6ed851cf09fd04ed9d0c3316e2f6d4feb43ed0b1932b625eac149693abcee031b2b9dfec38da3b7f0b5c526f07eedd0e4405bd3f1980959f80b35c105938eb9e826a8052cc022a78b927d53e1a4e7c2dbdae05d5cadcd29f7200834fd3f253e408d3565d9798e03f00eba3db52e302401d2b223c13dbdb271e317472dea84bce7628e1a4e71724ce5e3e2152d8d239e6b6690df69220e262c55b786657200c4fc8e257f9e3fcd127a0fa95cf646f0da9c345528307aeb297771a162e5079b7baff9d18fcdeade68f2e00c8f8f25aa6b663c9dd719bdb6a423c02f09566a858b496fa564a998d7581004629c23ef19724a4678acbe1088538877291d6c010e7f16efe732ec4597b07a06501c61971a001d6754ea7c431a028e053752596b9dd52f55781633b62d1ec2b634102d2cd821eb90c95bc13d8af2d3c2977560e73377b6fe2e1dc035d92e31d3e67de794ee811bd0fa83ec9b17c1a5724f82a918397d59958394e5b41a91583567db30015b68414205742aeb9fbd088327502729dad9315fa0ff52164a4f86d41bffa1b279a951438e4d7724746a617d55c8998fad29ce3604bbf299fdaeee26e1a5d6e7129af07732c819badd5cabb79b138c4d59cabba6f08087258c0bba8cea50abce7fdd217797e9a2a5bbc6a12f1100aa7f3ebf7ce049485ca8627a07d63b9d9f07a1bc6f35efc86d3f01114932915800e7f64d26ae80ae1268c159f89493c92e60918027e88b6dc67f301417d9e30c3e8da6e34f365988fcaed473b2ec90618a2cfff308bcbbec65d1cd0c1b3c4b3b3313af64b2897b6e8f8600347bb3752c9e6c21b7803366d09a08c98ebf0884c6c15e5840fcab092c7bb0da44bf0d4ffa2210e3800534b8c7fb2a9db40c0f7f343667a6fde031e9b3b39e8da1d8151d3725b3651c7068f602edfeed979b04dde5ac73a25f6983e1da1a389171578e182fcc5f2441bedd29a68199a0b5a7deb538689435db0fe9d3d462511253dd457bd1afc1c52f1b9b607c80a024204436c8bf4cd7c789c529b43bd02117bd0dd2d8fab1c39941552cb2c01cdb8972105f5164620c2fd534f13ffc0ac5b80773b9d077779a68e091c9f2c940dc0506fe2fa3be52921aef990bccea222a6c06546c39e89d9c2c0880068e10d01248a5b86ad801ee705b114960d2e5517b7f355d8078a70c0746c89fc5375052c730e1f0c2e933267d808fc168d4997113727cd30cb8dcf380f2e85e42f676c32bc4ae2e23a1d031c04d3a57970f59bf819bf35bc658d04b09eadff8ad7887306574e7fed804400ea432edc0b0a3c966865d5edf81297414d972d5d494f4fe4c4b641eaf028fb5971c74315bee15e5240d68a7e0236b2b508dd54850805814ef946f19fe642494d489913744718fb06cb1d82904f7d1dfa098b349e4188008737b0f87b07c2a5b0113cfcd7dc5d32971aded4ae19de2365a4be2b4b2938ed6987e118aae431a8bf3d87597b485821270fe3480d166c20cf1a0da38719ae7f873807e82dcd3172ee1b99c650930fe4c54a90f6fcca49e0573b64b7aacdd160e5943a339a4e862a22e7f7a352e3a275b39d46433e9923f881c198ced76faabcef021a69b90d5413ece452df6465bb83d56272c8dce599363016f546f577f113d6a39585125c01f6bccfe84064c8e1a85f625ec0ead56c2b5bb00c7e31d63ea284b0ec93919099b32318a029205c6f307318374d66aadbfa6c3cc79269ffbda3b72efaa828e0bbb9063846bf3307c54bedccb4dfd567545f315411230fec3b30c1314f7e072dbf4d8178c3b36e428df152cf5e27a97f70e69c159b07b5e8b4873244d276d27f7196c29ae2d6f3c39df5787e8c18567a33e63f948ca8300b2f0ae1c37595242da3e9ad1355666f32cd44bf5baf3742857d4ea6af83b981d85d5be1b2ccacf9590ac67745f433f6d432fe11a152e549d4d9bb581e4b0d44395d895d717c710abefb56e564c4267682ab408eec0f793fe9597c97dc506ddeddade255e8c02b81ad7bde44535e78d7d2ecdbe4e5ebff4b92b15deba365be43ba8ef4f559d9958538e402998193c13dc6d6073ff6dd9f1240c573ace1310b3c0de1511b704b1f47e1b840d2c4555a3fecd422819076f3d208fc6bef066cd26ff70082fae29cf3da1059c50cac77ccd52d5b856ca1c7b2fe1d8c4d5053923e3c78363559e3115f23a9965350bc4f4489e894fa3e561b75b81117f8c46b80ecbd71849419073e4c131bd5746e709638a4fee14fc921490a455899b4212df1aa782fd633214704a3c8a7ab9b1611bb1138e67180aca70d801eb07d6c8ccc667346d17e20a5089b00967bedc0f7b6872d433550f0422510014b59a9afe458ca36c3e71a3bcac368543ae33a15314773593d7026d0f6e8f8a1c8816e216f8b3db51bbdd004d0b5ca53ede082cf999978285edd26cda35a891b708eb2a0e2722f9038e8965c1fb08fef374dade4b0d974abd24d3f922b17c5c9841329c7ca6f75e58a58b324b4b36288b7a4279344a4dec1d7209c68707c63e76c6e6e349a36646351c4803b38ad8ce0a1d1a958cfa294ce65094f1a7a2572c4c020742f9eb3bc1fc44fd7e0d216bb39356c984187ce40e829d192de3d92fdd8466e1b548e8fc8d8ce2385b88df7b3b83e98b1112fe2d3e4ce94389de905aa3c0959789d25ef34fd5e9091cfdbb1833a84d6a59c341ac9f9eb5c511b573c40d1f3321790a01a8531e11013d6cb92f6320e6eccdd96bed1bee7aa4055f1ece91c61ddbf7e0d5c27fd489da9045cef1c280e5bfc096e246da436791539fcab8cbe2bd362bfed42afa363b82e1072e27f256f7dfd202d0fe568c4a5ad757101fda7a479fc5b9f2a83d9e615067d4a7775dc094f750ce33b0e55f4d04bcb2b794698f4b551613d2245856c6ed4546968227bbeb00eea07d2999835c1b94a3319efce077f4c056ce1636eabdfb40da7d50ce25d78c17083b809ffa1c1625e41090e45284b4c60b0ca231ea6a60fe4a8a35755d4c6d10eb600c45d5033b20ce42d00395e4cd5cab140ac091e67005e3dd200c9dc5c10d37414549a5a7f523165abdb762a25bc974b006eaa960e19a6472b369d9f5d62d9fd80f1218c2b1dbd4d64d94a863f2c4965b46631679a5dda65e81d35530d8ce8fac79f4b9ab2ad50292857237a6d395098eec9c9f6b87901c6cee8538ee7d34882fd077f19a193b11e9c83264bd29840a34d7d52f6517b6e03145374874b730fbc8e301b8427b0ceb8d2ace0d7b8829c2f8b7b48a2f3dc10564b09c3a2bb180589aa3391ca002049b91e4b192e373cc4d28d26132e500d1a515fa6fba9327ace55f42f5ffc667c19cee3a099021cd0133ddf8b884b1d62ee6115400f6ebc1f1048ed955153e4b79bc0b2eacad34d239d193613c52019b912cb4fc9b862258d5eaf33bc924e46a47b9f3e4c6acaa04e4944f080b8f2929e298cce19c1e671c24d493e85b79357739444ccc8df8bfb0471aeb0c27a4b12fbfeef4506c094aeeea63a49127206226744e4e95ba555609218dd4930018752fd4c4aa63b868d83ea7b8fd0e800f1a45661befd7bec24a35c35b0837edcb24c39dcb54e2a00a18cde5362271e6da2ec20a97988fef4569948d3d3b562037fb67e1a80d43d1df838c00a469da3ed5c392e0877eee70b1dba11aa2c1f8ec6ae5cd456425eb7a05734f24f0fa89fa5bc48cdcc3eff48ada1193c83e31834a88676d938f3e6898f8ed1e0ed54bb726c2befddec0ec35b771fe0778f8e53c8efab2d4b8726c8d1a4bcb0597a34a77ba2f038197472f0b04cd7e9244dea459361030b1c958c8b320d58925104545b23f38db098d338f9db5b0b92101c6f29962314f6f18d26716037640fbb883184defacc02a192a7501ba2f000401ccc561cb39415d6ad2a1ae24292b88434e89ce082725b52966e8223c213d2c6811c1bbbe069cbbbaef502ba7003f4532a1a73406fb700b2c50dee7b38068e006d229ed367a6dd94f8cbb485b2e4816517eb9af9fb35179989b29a0264843a48aef208aa0c2c56e3ebef47822ca61823f7d2a2ccfca60b487986cfa57ea5a067e182e579cfb3a0db9d05f5f2f1237222aadff5fffb14e724d15daf0b6943f98a3441ad29d4a85fe09e4efe6c3a6a459d8ca4dc83e12ef039e77d8ab3f384a786f71c9ec53d91b12f4296b0e0a3a02a84dca24930bbae36b6080b174658d2e2a148d0e6b9f65b0a18290696edb47d83945d7e64b1be93525c4a06e21494691a5ab1a30a18e89131e840d6d2fc3979e6ff09998bca72ab992e8bbc08c2b387363ea0f20e4adab26137533dfe49930af6b5c692c6c2b51f2f7e12fd8f55829f366595b0cd80f6045f4d1afdf11846fc1c6a4545e47726316b1f8f6bf12f25df23a63fade7c81589f41d3ffd71a51d5f2e97407907eb4efaa7bf2a371f1279b403fd24c1c4a495546cf693661453ae30b82214e1ad9ec51125d00c69252ea172121dc1aa5ae52468d403682484df7910d30e0f9c6695d7471df5de22bc35426ee49ef5a8a52118e053360a8b0330ca7e14d4a3e06622d2b1d2bf75851c3c5bc2daa7c3cffd6d2a1d2060ff22552fdc0a323617c9fb749c693e811f5b6ec29234d6a679416956143b0077a2ff3be93859ece54b8e558a4f4c8c6192b870d682167ad9f839258ab3a7bd92e244d594abe9ecf72d2472b96c80063c603d274be0cd4c4a08b189931c3c607172f298a1ab3430e760eccd784521c3ff7bfd75f5734c96996ad851331f13cadac914d362a9582e5c7b178b31dd5e9d8f60e6242a466758cfe024100965d049ad0d4afcc8f91bbaaa1904eab5484079259e6396333a686769ac44fba7a9c96bfc5945189d6d1fb1be68e4c289bc244ce998753b029695603cdb8d4075acac5c779ab3529a9508af7cc9e816f610d76271182b7e65f8ca33a1e4ea9569e9d125539928d4409734cd54a455328bb17f2482ee1a5a89b447a2093dc4f89dd4253797625f8df74eca2a65435944290f95039a7ea3816e55bcde5187d3612c067f16f367512877f262ae34a78d99bbaf8a79980dee5e5042fd416bdc1ac3bea313c7cbccea36ac56e9ad659561a2bc38ad703584367de559a764dc22638b5cb3fb76b44b228e50be00a9d02b4e377471450e24f13325f001f2481663155726ba3912b10a303aac52cff9524796c79cb33a53c1492c29769937732e285968eced219cbf395e5885302de7a929962273d6949568b0163252e4e6f4283b34a7706b1e9131d89b2d90a851380b79382ed5912bacfd00f5891ba5e63b641593172b9659a34d6ddb3054e7d8610dce671e79be4ecf33ce2be9079998eec51e300a426541601bc7066e66163b54c1771c708e35fef3aa314ce92ff59efc702abe825bd6e3c4d8b8ad26938e252cdb8a62635c25598606c1d6d13648b640e74a9ca11c3ac36439e9b2622152638bb8b1de3d16be08e066cc1040dfb2c86fd3e57f4e4c64c54817c989aad6f5f54e5627af7ab1fd53589a6ec7a9537fd6494c1e25c67fcba3061af34959de4710637c69b05228b0e0b3e80582402894969d45b7341545523c40c3b3d86f09ca8e1529529d4661dcdf88269480033a720e805b30ccc24a0799a9bf0c88b14bc38603246a0a987ab69e85a65cdfa5bd72cdd838e9037ad41c38c5a386d94db9f48a2df06000106faa88d3f3a167dcd5e41d40410bef82b89745b06b53dfbed761212ed4ca4636d964cbbda54c49a6a007b5073d083be84b7e22238fbc9741ad6f8548244c08b60a2794962d66330dbe262db528574dcb1632f9ab8efad7439c2bbab35a752f9ba47c799473e54b26e9d43efd6ac924f952495e91bfea28087f8b1cb9f31770c19d43524952611c4a300ed9c44e968cd23c124946995de54ac9a55b1ef9d1917b87b2c7dae431791284eaeeeeeeee7dc5abbca32fbb70b0418288b01798ad2533dc30a94c1a0fd99236ad746f31a198ce201268d9d205f999b1fc3e96a6d4081e00fd8c40c2088ca3dfda124620410891f6b18f64a643826b369bcd74fc4041d911922cfd2dfc27818ccbba46805a927253e3e1e423c8c9c9c9e9471945d663bb39a6ac0fde31e3f607f10ebf5d5140858b9ac04f5f46396a71262b280b129ddec9a9abddcd4d77a2a14697388e9bcc851ca74365abfdae8dc2f04ca6b05029cbe53e44a8b26577d7da4d5b65d053d9eda993070dfeb428e23c507b3ffe9a30afbb0891dbbd578bd85bc391c8edc221deaf4058bdf71f921a1658b1416ebe6bdd8022742d10488b3e70b0a34be4c0c56a9c29384038cf7a2af33b649c0ebd077290fb55bf7f95b5b9324edb076a0e1ac7823490b05b68d558f97587c5e31b234f91031d1eb4cf28b20ed15f765ad7b66d9cf8a3a345dfc2b2b88264664a397e4efc3576bef3b70adb73d5973f96c0ba6a2cf7cc00ee87f06f3f4b605d2e9cb27a0657ab4b63cd19cbdf3d53ca263563d95c0fd9410aecc84e22b48ff6995fc170d52bb2dc6208cce3cfc4a3c0dd7d7bfe919db65a6dadd60757f7cab25e59567a19ad4ba3ebfc342e6f51e2e49c0a52e79b7a43f4db62f991b0f3d0cb6ab21cba6cab488e6116583c454484201f4ef2458471f46b20c56e2e570b091123ed73f3fd4764ac7dec0d7773f3d6da9c9c9c9c9c1f2552ce0d0e0c18383716b461a4fb6e9056ff6365bd08c4abea85ab07f20eac5c3361f620c238a4d82d1c3db82d3615fd6584ea5d4fc4b6a268e2b23077dcd538b2f3fde933a51b83459889aa70dbaaeb6a573bb0088f4666f71cfd154854f4b02af237e6ba716864fe48000f91bffdea3d5ac1078d34f79b91f92301555555979b5356ff63e31dfe7939b43030e1a45600a6ea8a3bba947c9374a21940d8f9f2e74549e4dffb4b59fb30d843be0712098d2c56c68eb46eb0fddf03b5e38cadffde6b136cf10202ebbf9fdf07acef5e8238f37760bcefc0083fe80be30892daf5d6f59747441349862fae53e91751dd3203d2f59fd2c45b6490c1f0a610bfe23a1716c6b3ff94f0e3af23b5be171211d2831d194acabe3f09edc33821f390191af1fbbd0c8df8657d7df97dc0faef5be0900ffc1b199c807f7cf9dd4b17984118cb4a382dddee3baf82a3fc311fc8d9ebba50c6901cb9dd94442dfa4bd916b6a725058eeccacc2003083b8a326ad68479c7bfffb2dbeaedc87a0e2dd0c172e0fd8dc779fbfd50ae7d1c1c1c9df774741e04be3aa18eabf3423ae028dfc2f89c6750e84a23f4c208092073589d166f8cb5f5a3fdec78a3b6c26fd10b57f43bd084c9c9a79ef5d78d8fc2f2e7c8ad8a273bca952fa300f990524a29a59453148887bcf289b40f5f09c34c4b1654ae7cc962ae7cda3c1d50c5b4d665dff552268de41107f97256ca1e188d2f6c873544da6eb0331b488e344b1d41d23edc0fb12f85f8eb041d223064132ec22fd17998fca5e3c5ed27c23b6a8c1f41213140e61c7090e1f63327e991c2324c27dc09829193f31b0e0e33b37df9a3b438cc8ff3d632b39065599061800ccbb9224bbc3d8a2bb1138f2089110979174bd9d9143e3b90024442e4c76d9c5eb36aafea2adcf9b17aee415885957ba1bb715ba8e335f9d6e16b7203e522f8c851023b2b37a4fb8d9ed0faef7bd6f7cf05e21ddded97b21fde0132133db3622c5f86b5c29d20d6ef00f99edfaec2ad566bbd2146e8283b505e79bd5f7d07cabb715d81a3d0ddb66f7b064d98f272208326ccfbd65aeb4384ed037f9ca76bc43e1b6ea056bdf52047c98576d2a8597ec952324bc972b214414ab9b93f3333f3d87339195358e73e4858023f5de692b0948653ea7308a45ff5db5f1546b9f06b18d99fcc9bb59cab371dbbb95bf701d46250102f2e2f5e9ef5f588e7eec93ee3e45bbf5b8256c795054341c19793fe7cb9c30feb381950557eb785fe358a2c9d2f43b75115a3f4729d6b51da67c8ce75bd0fe14be3fd6512ef1001bf5c4ec45f40327ec633c778e69c67066512e3f0a7014a24504669d145c03c33c2517279c5084729c4f5d70947574e0823c409ad75adb89a18c67268b3b0fc74869c5c3cbe61431ad1b8884c02f3ba7a661f01b0e8ef7ddffa1eceb76f81412c0178a1d8c3535cebe9790e5ddcef5bfc3b90c2ce7f4fbaf8b9c93d3ff73605565e8e8774ab70e747f7f541e8c25538f26f40de4ea803b9e70a7e9cf71b38c57b9d7e790fde689e6bfd356b306939b1dc399464a625b924979268605aec7fa239cd69fe92b0db6896e4d2683d944a5e2305e950be0473bfa4d23edcf707dd7cdde8ec64ec260ce2daf5327cb0fb207fd5ee168ac19ea060abb7fe9247368869fc5d00f9ddd6348566195143b8bb872c841725f524c60bad89cb1526252a5190a6a8c8d4a0a29c9ab80dd40866b03cc80050c508f541c70d19ec4f8f16eeee38cceab2e17a19f2bbc0e7d0868c31b67bcae666d7e6da5c2e39bfe50c02f4f3c3850b171e445177145d722ba2bab2c49a28312c33d07400f1f00114b055b8e4c60d503021ab62d4c40958957effeaaf1c231518014543115670817912d117221078a15a010de6310ce1440b2a0002052a70df0d8b09d250819aad914aea64ed231d8bf6612d6b9eeeab3ba32b9f86b33476e075d1b88d73bb5f86dcd7a3c31d0f8bc82af07ec1620716a7f4d7ead4a9a6d2fdaae97b619dea6234ec6254758a2ab5cf54176b1f6ea516975ab4b29e5bf8f598b615d5a26411b558a306db4aed23252b1ce9b7c00f64c96255ac7fa502a7b07e822ca266c5da87be7c16d8549a1573964c498ded62619d6ab135b3632baa15d53e3b2e1b756aec64379a36eb819a53e21dfe7c31c0c1e65c2ea28922ae09f28e9c522b79ac6200023bb6d2c829d13356032adbfa0dd0d8b14e6d10b335a8528d9115e3942655baf23f247f713225eee8ca1fbfa52b3fa62bbf46019258897465ada82bbf226257be9525d99193c9fc85f3b24ad5ca3c96204a3160673ec3bade19f6d4ec8004b6bf93daa743c9d4f2700aeb815a89a5c40aeb14a754a738261d9c524f0fce92d739495eb549d8fa2cd78fe5d2b2125a2e768bdd0244e4f18d9183baf3d348562f4903d0b06932c7fcf9ed03eff0b09b48c1d2f7fac28861e0c53a7db2341c19aa979cc7359be63cf3aba5cd2eec9af3cce79eeeec69c2f6d7d0b438394a39fadcc655ae7295e3e8acb5387f9b5339d0d8da9c3b73ce71d6ee9ccf417153ba780eb999b9796edcc66ddcb6f156a7ed208de50fc093e56dfe56abf4e4e4386ec61d49ee890bc23c521ec99984d2a2dc5ede2963475a9492e8693eb1ac31a8eaec5ce0bf516277786acc1d3f0d147f9d838de51b523675e5dbf679970d69c30f35530390b2fcde063a587f29bf9b78475f07798cdd794078c2dc79407702fdee19c65f7f863b40e6f6d38350ee3ddc01e248e87b178ace63c57a0e4e50047b7e8036864d9061eeaa01a5a90cd31d9ba6636d437545bafd9ef4ea847778a8e54a7ffed12f3ff7c4c441c13b64d841308efee6dbb2319f63e47c727f6e8a7178c13cfd2d1b733bc9ed97dc93f37c378717763ef98b6b729efef9c43579b4277f414903f8f75727dc0af8d55bb8cea4013ceca69019c7b85af5f40840001860b0b3939323313081f51fb9a6d175594f7664a9a6db2fa6c5213ba15a7c6a41b13bae266b2f3311050bb75f724fced3dbb715efd84c4ffe6a26e7e9af341cab65e29eaec3b6b09f9ca767aa7f9c4f524fb7a7092bbf2235e99e0d921749deeeededdedd6ab55aadbc6738428e34ce8594cbaa75031dece84744fcc5fa9ef542b09b23fe6abdf74230fb4230f97ec43bfa08112b76e49acb3a8ffc015c91038d1d19eafb2f44227edffa8f05b27680787fe342d1113198f74230d600aab0e3fff4388ffc0e4660c71e1f1874b12337b9b8acc67c61a3c57525b034dd916b4c7e6500454b0e24288af5257f71171e60f29da97de47b96f6e1ae0481af8e2acbdd1d7f2d3664b9fc81c05d576a5176e1e17a1447f2a416650f3f6a71c8fe955fcea4704719cba1c6cee90911b201cb06a0dfdd77230869634910b2024da85f0485d85d75947e3dbaeb9c73e88cb0ea6f498ca5d3dddddd3d69adb3ce3aeb9c3d9148223568d490995a9a52f21c8c0aa28a1873e5f2d7c3c33a25350515e58e3c05e5ca472265463743f6480662ac0946ecf52caee01c72c60f96b57481e68e2e15259f6f1733a75273e58e2ea586ca95ef64daa7a8985bcaeed1b63f10e6fba7a3cad27710fc52facc38e6d3903b2c767a38762369517e7da0f6a8f6e910aa7d6acd4165479eea701c10a5c46e9f838de50240c5dd31d05277887f87637dfa9e9f70d4521fb4ae4b25b13556efb05528c4799abe83f5479eea516b448c801b8e03a2aeb0052c6bf142eab2162fa0ae7c242ee5f506f67352e30947d7a5c0ee3fa0713b21ce337bb850582ba1a5c8f8ab03b27e471887f49a4bb528ff63b2a390d44dccf2c77260a85c477f88f48c20063d906bc92209cdae5cb19e931b47eb5bd0c53eb76df2e9cb8d6e9259bf052111827dad1f6b502be8db79008c6ffdcef6f237efbd0f3cc11fc9cdce03fc5bdf0a19c66a8127dc00b9790fabf3d4bbeae72f02386f6180d579b897b547d0172211827def6d1beb83aaf3480efa80f8b72a1018df0a91dc3c8cb03a0ffdd1fd0604e76d0c2702feadb7808b1dabfcc013beb7ef09c9150a387f332fdd444a2bf7b4886f9bdfeeb72e2c226b384a8e03b9b9cd184e58a5dffad7809b7007c817ee3ca0f5feadfa81adef0fc8f7adef817ca3a0119f5db392eaf7bccd23447484d81182d4a0e9e3d69ba7df0335f74cb97f2ebc790b84b063a5bfbde436ae72ac258dd1bd794e3e077e3da4f4af876c85a3d06d3d07eefcb0bffd0ef75cfd71b5f3a332d5bd796e0387ac565fc3d9e2b67ddf02fb7b9e94cc366f9e0baf63f127b57041a5050d997bc380efb7afa3ac5f0f19c2f7db03f51742ebb7705c7d6ba4dd618001fef52d30c28e555e7048ebbb9f5f09fdab6f3d078ecfb2a1c3da46bb6df4b722dc463790efe75555a37394db9a6b0cf477a17f1f6ce14e085cb8f3a3be7be3bc5b0db7979c91b69f64c55023862c1cf8f001d4e4a3d65a7d00f16802e2e10388870f79449d9569b38db37497d25dba4bf7210a054487b5d66e340848902020415c02524a295768824a29a594533cbe31c57be23d90356591652d5ad0eefcbf9eec29476a2a8ff9912b3915bfd2af19504e1475e5bbcca1c8a66a51c6a65a94376ab0634f5d39e5b1e68203565c01668d105b54b125863376881528a1a245a52b71a2c1249504d1f2999b13a651e982c9134e3c9121c184e18895344ed470683302a6f9829218585c4910058b12496ad6b030a12891ddb460835ccec305cd077ec26989232d94a4bcf0329f6c51a2649b459469439db00f6089154e30540598232749cad8eef76cb4cf9c377e86366cfbcce962efd60ced0ad679a094f2130738810d391ca93113049926f475fc504aa9d74aaabcc31b890829bacc5e08b3048a2c9ecc9914dd1313c0a02e687024c56989194cc0a60817b2dc74f885851c9ca84266892fb3851fb8762299e8e0d127494440fb659439e7ecaeebc2ae5b385a1a4a77274157213bc2882b64a290010a264d3cdac439ca09055ed6d87046cb10462b70667a92e0219b7a010c132d4bcc4c169224e9da49c7aa2cc142658531544eb0b9029a6f87a44fca704f29a594524aa907599a82e0824492279a8051152ea594524aab0e16db3fdab83abc8376173e6527f8dc0e218015ac70822ea868e9c10bd84cc189305fb091a228894bcc045e3b99928522563e73631ca04cf1214c973654cc5094854a913506112a185521c5cc89159660a1592c2389c2a585262e9234b182a887eee739adbb134a2c4102043740bd1055c5900d394fa058347ca9a18cd2136698288981fb49b375123d9c846a0461ca30c981851f66922db1211d9171c8a04201fb93282db448b1028c1398196bb3cd1f323f3d45efa8ea02e60b0d8a1665aaaad254273db236510111290062080b2a947c71054bc6161346448f7340822a555a9a98e1c2429b2a315f076460ee5de40e9a0e48cc906ce0a18aaaca8b950184955183d12a658ed89eb49525684c9420f64312166ceefce72e55586e9cadc021091a155c8cda04b1a6ca4a4dea090ca5400567c898a0062b5ed0a083802a1560d0266d9d78e9e243d3942ca2a6aa564e325083c2c8051e9048e20b3577fe7b1935d52bd0a5c6860627ba3c99d245988d86a02150c508881e6a59ac400b4ff385961833d9c3955663f9c20aa54ea068511475441651303ca1f9624a6d29424555c28ce182091f5450c2b9f882c8a33ddf35ff25d39ad5f6a4f90c12558c9081082956b50554ebc9b7b7d684a9624a0d4458a1428b25e68ca1ed2513a11ab644e1044d1924ae58521302c66d58f38e221a014f706813851a154ec0c2191fbae5acc692051a5a5400d305549b12b031b303d733488d1d6d50ed298877f0e859050b189668218d175bac81cd3277bab084e8872e5176488a0136c9207949d89e908336767471d0405d04dda087ed04963639c9ec8febc7c5b936ea4c3e27bbbbcb8072da7577779f6ce386d5a1cd24e41834dc0d9415519c58fa48bafe22681943268b3b32980da8b0233f6df4fd3798c2b6e8a328765e9d5b85413a77ce372af3a74f2e277f107f09c4b8fe5206a55f39342d6d66d77db274ff225e97d3d1a54da9a4316220d1aa65e9205551bbf3c1777d308ef9ab2bde0e88b0bdfaed837441dcfb20e23cf33790132f7f3b0dd8be3e90edebf709dc77bf024fa8d22110eebb70a74fd8be863b1d06c12898f91d1844e30b4b9fe84783a5b43b5fec442ff4616be80ac2b2124d50dd919db68f8323dbfd73caa9bbe5fb1021e8c80ba70684cd911835998aca16e718a93beae009d5bd454d769f733233b3e419e5a66b3758e9b700de289ded459779bbfc0df26c6219ac183a393070ec4dab67b064d4d6c7f2565df5195f0893c17e6a302db29c1df22b2d3135556f59cffa0889abc5b6af87cf39674d800c89d65aa766fd0b18caa7acb53afb5b77f95ff71a030833563a27db9835cc4072eeee93a3dcc671ed5bd39eedee19dc9983c7bca399673061d56ee798c95cfe464375f967e8445d7b69302da6a3b8eee911454f003f1934544dc4790123266ae3a85cfe2b553ac7715c68745b124d212d72731c94cb512e3ff5a4cb6e24a59424b4c82f638c95928316b9bbbb5d3b3fee88020c25a6ecee6e29657777cbeeee39635b73ddb8d093dcc68526cc4b85584929e55c8554ae6449da684b972ebf735a6d475bba74a72b4aa9fface66a257f25dd12396de9d2a56c2f9587afea6ab55a8523fdd97577d565e8f726856dce16a791bed2485ff9fd84598a0ce69c73eb2bbbdda5cb6a5df4cef60fe6edb07e61e44dde41011083f28b33e057ebb9fbb100970f70998db8ccfcc465293e90d2df40df9ec34b2970fd63c0dff985b04d9673b6b850320e4ae7106eda9a36f16afb7c358605802b83c72116e00097c3d15f76ff7c3a19874fbfbbbb14a61b27ece4e532952b5992b6366a281da58928ad950c1aaa28e6995eb9d65aa5918412e5f24b222783868a84e621a7d35aabbb3b4b674ef71b159c37e698c3917ea5949bdb9c7352caee54b20ef3f05329a5942c49a170e138670dc7ea944afadb7bb47f9c736e28c8ee2c6e3696ddac5cb970745df60d344299524a299d4f277b13b5beceec5651d85964e5773d228650c35f41617ba965b774972e25925b2347182b7ff5f23de01dfeaa60105b1086f5d3a383fb7ac84929a51dc7753bb37bca715cd7e35f0ffaae1bccbd7cf60224b1fe3bf4a7dc9c7a4b6fe92dbd654b29a5cc80c9fa338ffc4ec746dfb8cd38e437795578f31d1cbba022095bfd0a64310edade23118279ef75ff1023f316a93ff26fc0ef140f785f90170e09c560434850a822628a336ad8b4a98279bf4408e6854b58bf0ac322f5e96f44ee164ef19e05a220634d483319919224b021ae82c968c0bc5005ef97a0b04408b67acff3bee807e63d0a5eb85aad566f8114ebdf4b50c0414415396839c304089e846455101111c97e60de0ff91731984ce4a8623198cc05f37ee8662a168bc16415e63dd1d0cafb2111c90b51109a1246c99a1d68d021491330a2ba45e98b241811d1d005b50a5bfd5002a05cb0d5130d71555391085b7dd14fcccca262df7ef2749ad35d937264443a57375896f428bc5aeb98525db24caea67712693d4f975952363b1a25d28a99198ac7e7d1ba9078ce3959f393dc0b1eb30fddb6e9328a8e2757aeb34bda5a766ffcb4d2aedbf869edaebbbbfb19765de71d333b1934542474775dd8ddee3c24b3bbbb4f1f6f796146923539d5b1cb724932c926e9246931e791b323242429aef1948c597e621aff5cee69fe5e629a1c823f436faa178463b516840c80906d84e3ef841e8e3d34c2f1e77a758563b533c2d1ca084797d718e15875c29c100a46d804355a28a87a138eb5157e61c7905c8e149bb1199b3177f7a6ef69e2a62e1cc51a8e3d3f488ee4481ef398c7a0a0a0a02652add6363d3b235124d757eb426a71de71224da409ca1ca997d2dd5dfed859e4732fd5ea944ad29c735a1a268bf6d91e5975382dbbea5637f6266c7de19c82f31ac87056dd94ac5b75329c38385fe0bc831ac8706490dd342745dfc0d1e0932ca5e4592d6ff040cd93e52dd5491b3cf795f681f1fccdd43e599ada4783e76f2eed93c1f3b753fbdc78fef6d2621aaaa39ad62f1751bfaa918572f96554bf2a198be6caa47e552a52579ab991c454230be592d02f59c958344e542e312c25f340a643a6546533663237027dd6620d5d96c6ce16fb5dd643f4573b89566c0c7eac2128e47fac17fc682df8d105801fdfc68fe2ce8f3d97a5dca95a97729efe6aa792f3f4cb26558bb516c94c342d4e510d409a01486520356ab11f07a433257f4d27e7e9a74a4ea3dc9e52764a6120154a81b20fc77a41385a0bc2d10580707c1be128ee84638fcb9cbc1a4e349cee2a1c5dd7a55ce10c975a4d998c70ac752ae92829ddfee9b4b1604c279cd043d6db66fd4db3bed59d24a6f5dc44ad703c81ea655494eb2f5949ac7044410c110a541c1585b964b9c11a4857159e0d969db31a99b35a164be9eeee5e7dcc7477f6ba6d1cc7715cebf85e4ee736fe1b22072cb69e57ef6dfef560fdf7c3ef275be1d7faef6f5ae16cf1036f78a11653ba9516abbb0abb9fab1eab6e0b3924eca663a7d8775083220bde689ed7c1ca58ec7a68a3c5a25673683cbe3176352676a4506e277d2725b55447855deb31c3850e4ad7cdd4748d429968fa45e9a47482e917ad626cd484d2af6d369b516649332ab7e795db33cbe4727b9c5ed0f46ba3d1a86893886674fb1d4cbfb62ae64691b9cdd52c96cbcccb6d6ec979fa2b073a96a8dcfe46d32f8e1ef9ab83d23cfdaeb16bb5f66e86a4a33476b3a5ee0ad36d1dd4a99b1959f96337bbddd12aadcdfcd5cd66dd6cd6cd5eece9f16d46f357add568355a8d76fbb79abf2acd79fa6935da569bf9ab2e2dcd96664bb3dbcf2df9abce664b4b348ee62faee63c4d6994465d2e6b395a477375b48ed6cdfce7a7a74714ff5dae6e36e7acd56a351a8d465b5a5a5aaab3d9acce6e733577b998abdd7eef6a9d945134a72d2aa1e7ce8f59a90110195861e52b7d415564a568563427b3ff9ccc25341a4fc70f43f55cef3beebaae63fe6ee53dcf3c4695f54079d491b1accab560e567251479246753581bb318bdc2f349ff03796d48b9bd8df6e9b9b15aedd3a22c7623076ef7b5ec6eb5c2c9383cef0bc70fdcee59f43c24b7ebc2c96ddd5d1cddbc60e5bbd46556adb5d65a2fa8b6b9982e65ed9f55ca8a739946e73dc3ca381c0720544caef0a209095868327d30734435f3e568dbb66d6b800f4d358480c90c0886983d98b1e28b90a06688e08c78e205a31c365a78cc3e733ab7dcfe029f397d2680ad8c924e1627dbb66d5b992f1d519db587299e243134e50b125073e9882bdd154d92b0ccec4064868905445b983ac50af4a99911b090086228095dc31d110ba3e4ffff460a5277fc9e4f0492d987a5e4d9b327cf4df23b13ef8e76dbb629a5b685d7068ab53a34427047fb32565e6bc6d7126aabc5baadd657b088cf78a0a63e3e592f19cf6fe3bde7ffe9d70c18393a31deeab0885363d7282408bfde2d68754ab8372c4b4407ac2c2339e06411c7e2dcbc7c1820b388f3f25b805ffbdc3e1c8e48eecd4d38672b2cfa58a08f163b0402d3581e3e589c0d96d54306c8636371fb7c3404c2c24db5d65a6baddcd699b1365c57a7bb1e3cfeb1f3fa8c19e67b2fe5b394f2b92bdff90b8113e2ee04c77e0d085d69a42fdd7e30984bc39d1f3de4b2971496c47081b7c899ed8042cb10496ef092041a2b4558d46dc6e5029fe9a49958b30ec63c41d1224605158480872225fb33ac406489216614c590104c72a8521402da529a73ba12822a15c8b23051297aa1e584cf6451810f3f7051827261872226b59b7092182b9820620b1e8c7862ea20053700162c103b5145b5b80ca166dbb6add665674b114d86eaac12cb192cba335cc8eac42133a36ad344a6450a660e67d8e4d45a8081524aa9cf103de8f0c30d4b2091c554aa25e5d4b0381142c51341a490e5882f4773ca19256ece88694106029dcb5b642d744870146cd274f1830d35f0602465c9190b9e9879428211ec606609a9852982252b603df9a425b41c30466f789e5e45061a84a04226b543088e58b9649461b2f2a5cbd30f52a6e08106822553749e54b9a4898c0aa559786269167b82c50a163878e17ad2b206053039c126071cba78b10352540c26445d76a6133944d483cb09910d392ebb9b58c94ea6a81da18594238080e1062ee69cb3461296efbcfd339f36dcf92fa3c2520ccc50022d4c65b068920446670d972a3143c40ab21234a5604d94a1a78e82f4e9f6f5b6ab41d29284d2941254340c7d5975a165ce89e48513a927589431028a19868ea83b247512da70660829696a35c8305404dd21a9ed11b4dc1ea5d982821c5ca87a4a22651e0d4599c14cb60cb5d0a24d9454ddf02ba186a8942d18f538cad0d808000000019315000028100a0544229168344c6459f40114800e6e90467a5c2e15c8a320087214859031c000420020001042666686a62800a065093dbf6c504496aa7ddb404fff664ab1060d8e68a73476cca6ed2024646232ca16e72b5cae526abf39f664b3f6501b51220d29896a1c7917971a598a8bdf6149c9eae39135a8054f6aa4b2d2a44968f119f4b1558bf43f21741db85b2587145fb623740d14e974fdb37067c4e55d115e45277b1327be339cdda378dc1706440ead81da87e513ca87adc32e68692ffc3ecbaa548e0772080ac324bfe3d7dfb46fb673a36d93913303aa827844d94d8ca129ab2e517f57b21215f57df0997e516ccd05f36ba74760d61afad47d15d5fb70032dec4bc712658790e5a18fe233aaf7235271e429e2aba44a2dddf0652a33a467c7a1f7419caa98936881152a439e592f2843710091c18d892ce30cded80f7f2a2e6c89bc5b53aed1aa7ce5647870ac9418a027c8269e48c16f60a3221c24094c1fb3508009d610cd4423e638d04602bfa72999722eb78a9885e3426abcf2ac779153025321cedca34b2b6ea542c8f4d0a33559e6c9569d49b11caa14e2df02984b210e23c52ff20b402a76a30eb380facde81aad14c86be08827846f868a386952fc6a29b20c01634cc59c755a3ea81009c65ea4f9805090c917a1fe7d7138f609f1d2c0f9d0c4ad89aaf4231e636091165f105e4f39087c0a338d9e01fc4fe365ee729b9bd4fc98e50750657557dbcc4f68fcf18bc24b35be2a21e608d6410a0adb27f350de37a14aa5f5e8585bd83d8e56f5ecc5fd401b5772f161c45a7957ba4a0553b1b440d486adb1d095fcd27c350ae726de169984d78ffc561f4ceec2575904358d1846d2503950009427ea931c76f3c9df2a3811eff245df237df6b9f14cafc7b55baad2792be93b88c385c4b81edafa40b6e139be65a7f5b7d8cb04570951e166b5405cab1c6a7c4c3345ff2dfdf03370cfa9e1dd15e80bbdf81e459f24c2346334bdb2a0e797c4c794fd4e3ed737d4d4001d1f40467a15ef4e53e050a5ddab8d277269c8c189d544de76cc31f4d9e1744d1d670af7636f2415cfd398a0323fc7de3f3c27154a24aca7ccf33eb2767800eb54f7fca9e84e67b1420ce7ac0d2ca3f8561db1d79dc24e7985bc2010e4adfe55f12dd1759cde71e505c27aeed68cf3c492796f8bdbc2371c0ea5b670a936ae89334f31d2a1e5513fb79a2d989fe972fc9a186232ff36ea5e536e87436cbceda0a463bde6d3fd2256138d81677e6384178dd6ed12465d3d9f2ee6f698a62b31b33b88d70db67fceafb83f84894a8a42bf060c3ec78f69f889a2791a261e990e078747bb260cc2b0a64f264825f78f92f36da8990b99e6268f31967f358f2ab1ed9b03d8e3b05e2a75280db2acfc999d5033df7339c0c6f937ea29d04213f927097708eaeec3d22a17ab7d580a7984022855e49a4194acd4eff7ff372d4b5e3371b85224107bcfff78cd8ea228b945c79fb0718fd42e47a8c7fc1a5898e67b29cfb87ef0e29a0cce1d35c6ab3e47c181e2fbcb3072407fd055fabea29fd6838f94de4b9c56547b4f910802421db18b66c874d1d2c8aa40dbb7725ed6b5c7e0998b44bbc9f30b68ed0630e544a7c43e0ad4924fbb0649e6bbf213e77f052913598ef443b884944583668554f58805ce335154c2b0f9f4dcf29521f94eca229ec2fcaf2979698492c116ed33c3a71e1d66d81cb9bf55c5a7fc814d642f63816b858861c953394ca605869f9c8101e1b6276e68c3d137350a0a0c034e60b0c8a57425742534280203f22282e9770e04270dd721d6ac24f5b4767a3114b520c8599defa88fc0b082db03c76da5dc2114fef67d139f15fae1425f7e097685b50efd4af36b773f5227bbba5351a45551464e23bce1c4d8139b5a3c792e2f8fddc88e20c1eeac58160b52f147aa62f652ecb545db0bd82011a1c8209216ef27ef95ea67dfd96fbef1b1962415fd805c83627cc6ad24d147c155bd6840eb896664c873bec27fe360367b34d7804c7a0e3714c809048739b929dd9c1852d11c882cebb0e58e3b6b7160676816794e4181c966250318881fcdeba17302b7fa9415e2d24b1cd07f619d422b527d76b235860dac82a3670af26d9c5ccb993c2d3595ce6a42374bd11b04042b0f6cd4c0af45369d88fd473f725903af10baeaed4d78651767714791a924da4541c1901f242f7974686860910da5e5015c4f6a0505aed81446b6aa93c45d6c741e185689ef245c505255240c5416ff1b0031d0f6a36b94fd0556df128920a1f4d7a2fac4158e6bf4652bdedc8b002c8f70e44f2e83cd11e13cbd59a49775df661fd4e6b3482e511da432d16f5681c609da701c989e853a9d4c9d1f8b79fa8939a6fc2fda568da02cd381d47aa70eb12ea02e669898a3ee2be20c30e60306b536b6a8f215269ed4cd705b330426133ddc90d00991a6f9a8e981ff2a9c168aba817f725b6c8ddcbc03572d4f458e123963594a382b1326ef0fef325ff407aec894644d1770577a3660408797277a72b2e234e3b054da1aadac966e54414369dec98e29cded083dad1ee720ebcf7c7072dfffdd41e5a16d41f4f81861e636954f738f970f690159a9e5b38c16297e9867acbfc30572f43a571282d771a8b08e63acbbacb38e063e757904d8984bc9ee7a357e3ab3b94b9938699562670267be5c1fcb17b56401fc0403a8a0b94c322b283cd5595f135d8628bd8cb040c8e1db824b81f99a494305b01c1fae5686ee21ffa014d50519330383e06ec6f29e5e256ba62abe511269e31415143545515244c90eea3ea24851494679155dc440105224ea8a314a5e673465f0eb64521bf16f23edd24ef6b339e5cac99ba55f99f2b89118620ee9874e73483b30d41351e81cd277c959e897c924fdb94bd1964d480935d5cff66e56503ba23f359b52c1a710b3112b25feb320fc76f904823f23c52b08d91cfe3cb5150a77b55112e00d0ca9423c9d716de94220c403548e6b3eb9cec53f453143973d127348bee6b28cd1111040b91c6de30878f51fb64f50dfc5f55d58c5cd3f48dd2fb28009bc944ca7328bf9392b030f2a87f4c88279e5e5b9055906399c23cb27d9e8f624205a5ca3bba5b2b1c1ab7931a1c852bfde5334b6235f35376d67fddcd74ed798e8de81298b4d256cd64473b3e9cfe15dff217e3d1e5f0601c90abca48ec41758f0100b9544e09b54d893c3445358356b21ac8376c6f6776728a13bf1d13557e44c6ca519babcf7ecec45be63fc524ca6d48f05c21c40ff57a97aa4a90f81c7faa489402da6db3ff69b313ab804121170a8281028b78e18593af0542ee5794a2369459c144c20c803bbe493699a13f6180436de47054c2500d5ef801bf434b5d7eb44f9f128727565ac2e882213995a939498ea4d1629ab10837c18e020eda17ef90352dcdf942501b5c177b28d36e420e2a7a6412bb3d848e58e1349f847476353ae28a744a5b040288797abde9abec0a03333c780c5d13b81cde57e2e8b19d912ed535110c7aa72a614498ca969a5bd8531a02f031544f542e7f2d213323dee6913fdd64d7b5da11455a69052a4f36a0404a638458c41fc6d696ddca7795d99f412c7c2efceaf38223eaaf5f6007856d6f5d0c00bc93d046e0ed1a009485e9e06daffc55349451928d83656f8746e2a43b1782750aa293a86fd53bdc0918e1b75c6d5ffaedd7d6f55b8d3b1607ec9d50d492b869abb416438c91319651e699e5ed710ae6ce461e7b7c78597830fce2c4b31048e6b5358b0895d50397fc2acadc67a7a0e6f6ab947a8fc92b2b53ca35575eb5ab28bae1f4140152466779fc0d1e9dface6919fd554fa2b6538b857cda5c03fc62e30d6dc381b94200194a49f58c5bf71c817be00e09ba0900581615f7a427f67df259a53ec2df5f30d6dff18867e5136d1d502120190cd5345242fd4089938008e582bb78c9b107e34a1f3dd9e13c6fc98282332a183f13b152a86b5043d676059eaef05d42d024dd8a345e74651a9a8eb17b7af5de6357cbd199a0986cd7af543c0af938e406192e7f9c4d2d797f5bfac88f478b67382e452e7c893741754dfbc85bd37acb62d8af1397c7b7b62ffa65617dd62bc5628eda850beb702e46c149ceb670a58de59b83b6aa0a3f111668e193e5f2527fa48cc1be7ca19be08c82ec02ac816c096f0b67f30e3dcdb83923867b7c5e71c823ea8f87229c4bdbfdab1b781f7af3df637707fb467df4a0174b78d0a29b8deec4e819aaa958544a7ee28acf486e649a26026934330cc2f9c27c090632d271913e2209a474ed7e31fb1f88f9c3efa058d1bb1dcdaa8bc1b0a94d30f8ca5d4643a0cb7c9daba4131324ea917c8ebed05026f671c0ec55c22f3cc0536bf878f06ad2b0fcfdfa8b52f1aed249acddda836e2161d68f4fdd14efba11ac89f75537a191d74992e19eee045c705adda4dcbb09c4c086932458f4feae4e6ca1a8b53e01c9fa8c1211a0535fd9121164e6e3d097d2512f8869279a6be29bb220f59578e35a545cafd31657a2e90e2a3e6173fe1050796c9be751f87f0d7cbb92877bcdc7bb21a3e81a2b4449b916810795804b70c1ee835d29de063e3c11d76f7496856c69abf6b08d88cdf8dba5d75282e4253d21e5f6727533bbeb0674c4dad10ae43d643fe3c7a3756815d21d76763fbebeb57a676c7deb32a701ee91b649a738f1ea7e98502c0c0a7aea68a9ad25c9328ab968b7ab8766400234296ec21f2705327d94cf0dbecfa922e55434ced87e18eb673bf8875bc402835f59c40f87218dd88cfd6d4f1d6019502149dd6e312a1c12b52ad406a150c425e7d4ac0c4bdfeab516cb5db4a615952e90efff8c0a95fe5e2f567101dd081b3b9909cb9dcc913df642d291869d2b7f2d227a211a1399328722c64ad260c3a1cc309d3d859340e9e442c7a89c30d9867f46aafd4947ed8a830345d62945c02253e051aa2087c2c2addee5235368ca20809611e5474e1b77c635214bae3ee3099c3cf381c9f5a31acfdd66d1fe938aa931ef3f0e6c9638541973712352262945234aadba2cf7871d97d74e705b03bfb2d1e98c92a7477a1d82b9e469439e537d65c2471b20d389b977f95cfcbcffab0ca650b79dab1c4c036aa132e47db89809ca78c8db9f2bc5bdb93092820728e52db84cec26e434cd03ac3ac022c4457b4b7582139ff1692eaf0036fec2a20718f855c64d401f8f26cd85701dee53e5c47fd9e553135a3387ef64d523027a4b3ab21184287a38f184287b991f43a5d233a6e9a6aff4d54fb8ebad91a8297c273a013a30ba32a26ecffe9fe4819fd9d07faf0eafc5272684da6db9fbd3a7f760cff0b62a3754ac8f86f7753cdb5f0bf443caa432fc403d727f423965cb3f927c12905b8a324d47f5f62f6604b3e4bd5d46fff22a8a78f0c841a39531c770c82b019eb7541eae96cf570baaed7501fc7ac126a217aeccdc5aa3fe1213d4a0ebb8bce5c9b4c07621585fed13e07f51904b6f16331d97509d019436c090fd02320bf2f2e4f823437a88886a991775bae47c505c426b7990182c23928833aa10c28a965a6ce88d0e79aeb164d0a10fe1889868a0643afc945b4f5b0f1ed249ea0cebc915f69354130bbb0fe770e089a5479716e32da2c1a50388747b2511b28721a3c2f288a9a553d127726a3d11d6b1ca607c2ee3e6ceb01638cf6f885d998d4dced1c2763b722f58eaf14a444b6ba3766fdeb46b3929485e62df897559a4297461d00c1ab184eef05fc64463b64e7b04bf563186abf5b08deec51881483faf549b64ea429c99bbdc3c181a086f7e495d741779ece2da2e4cd9555276f42b79d0728e5cd3253645ce74d59a5a8cb06370c3e480aad45fff1efe43abc495823fd841de39936bdb327b199b93662d65e2c3ed426ad838fc45bb6026d4b7e7333da1c4d12938130d1444c8ed435c96beb6b926da81278d07a3d186694a2515b20e9b8de574f4194fe8e2b9f3d46f63fac16518f24d421659723c57b4658db8673734f0cc2507e0141864e0dd143304b87d146c26ff54d9f7462e2b8aaddaa0d82783a4dbae1579bfd193a874bf5ed63ef38dc034b5a4bee5fc2683597d00a8c119c7ddb2841da7da13e506485c82be5120c794fbb205cc2299bc32be0a730d6c7aea321893bf25d652064d4575b872a41fe77d641244b610ef5144244ea0c3898fd232e118f912f04f7541921c3cd0fcc9139f03947f8d36aba1632d52c3147730420d100921c1c80e6bbf016285cae4522d163c51137d7789e1846cdd453ced01581cab226804f2156d3ff671ef1a38fc02620fa26ba1be00ba05be203a5ed3e71b271beaa3b9615730c97737cffc14bdfd255ec13911bf4625f05f60b3ade365d8c31397aaefa9c1b8666e7a3d77531a98f1f0681627d98de82ad95b24262a9532b1a17f85856542fbc90b8e21cf2b5eaf77fc2c1c676b81d9e8a5d8272c87c0cc032868432c3b2f02acc5f04db773942cd77aa971f60499f7bde6451271150689957b52141f7cced7163e919219533970c0c40a7f0b13330bbd35b72c41cbac2f9aa8e7c2b28498309c3939c28bbb140d9f7bfae812240e04052e1c8d40d49bbb866d5601161e789c515a53bf160dce1f86fa02116dbd3963ae3552e5fa811b506564517f93243b7476373c9b40e2549b333899c8b66508d5e4e192b22f30877f5e91179e4fb61e198ea98fdf1225e43d865f5f9cac666ab4903dafeb8a48135100f462a878090cff895daa9e89da47dc603849e357bafc21a7bd2881dec5820366b97b823b9b9e54c8f45cac662d8f3aefcc9323a4f9cc9c4845c0d76da07e431b6cac3bde5146f2ade50b2c72c53f59bd2b323ab47ae4b21f5956e9aa4db07a0e824036a6d5ba9382e448d99ede78883b5c47d6ee89a540e9a518dbc73ac84fbbe89f1c7b41ae58acec27930c913054b2c0ebab033355fcbef42e26f85b64f41208051176a0743994fdda0738f5b6a8b698591f12e4dff18d8f78f623406d7b0b74e5dd62bae8885a02533a49847e23fb8803247731fb41c4da084d88596257193a48b023edd10ba81ab58905ca9ce95a80a57432874d3bb920834a957e83c578e0090d50e70a291677d42441f9334035d6327c163471e03c667d4140567f342b6d1e40fd937d1632532b885ac7cc4bd90e2f8ac14d8f7889a3c027730ba369015207537b863a40de12b4196dc615e02f4c3a274022626f694c9b8a2c0228acdb5c65778bb9baba8fb172d2883a9861b6f3f6104441813f06e17852b8cabc19ae28fbdd9aaae263148b4800c99e9fb83c583191a7f545a67bb3c17c2626a5723a3611829e08e60035c45baaf8c86163668ad0b435f62da346b37774b438fd3573d17834aef4fe8383fa60042c418b5a62082959115588fa7d16310c8457cced8b1156a556799c00646e4049b0c46720e44e1446328ac76d4df84acfbc0a729b1bfcf380c65cb1d37e4c005b6986a63c8a661e040dc1054cf8a0d4ba29262c8197d9d50f71f900d1a96d94bdb56f0c9e025f32f1fc4bf06bae929ada326dc5c313137780cf00a4a0b8721caa6470a9962291b308e8f99e3777af824e2de7cd20a7e2a716a58bb8eef172d51e570856d9f66a5bf15a80fd4b11a35b07799f8471558cbba42f18b4766a6ea73fdc241d2a98533622bfa284ca6baa2b2c1d9492052e1dcd6dad17236ac157c167871d76456fcf274805634393a34c5b2d6dfecf49c5f9c5b6533a538568cd4dfb5be14446841b7ac5ba51ea5cb9fa47293406002116307b20de5c9543d142be9113be570a1f28e976acaa1be9d5f9caea408fe7a7d3a9417fc5f62a02933d7382a9b6910cf7b55ea85479507daba4eea2d90e78b78db939c285cb280496444a713584ca79ff9b40ba0db389624bb382b9f0f9a968e3b72050c3b746a31ed70326fe9de0d6c4cda5caeb5803cb7bbf294e06bb907930e3e1832d932a2da98b29a7130cb61c2d0d0033e03a56392ec53ef8d509a9129fa9e2a9d2e4b4394c6ed26bc6d488754d59a6a8b119b8e35d27b586111b555690731f9bccce207ea69eb884ab73b1b8cdca07e09a6f00a3ba7576e63b6efd5f83795aa4735c34baae27e615a81a2578e80b9d2fd23f4427238b34eda88ba7bcf32c3c3757d5b0c919c0ef3936d2918b492c577bc0860a4ff718c54d9493ccbe24bb69b1c6a832943a43df9367e2e08cd6ecbe18b04f032380f0eaf37a99a017b603048ce63f070b1c9f3d57a10cdb712dd571df5d825551a2ace482a75031ed10246e55f5aded649fec41b984010e78b55780a27c763551668eee2cb87aa44edf8c13763f44315a16247d840a4611b7883863f0f01157952df07a92feec012fdbd56455d7806d8b431ec284fe18d4097ab625f583fcc7412d9cea5a18919024f626131e7e391e3ed8656976637afcb74cb4b6f1845c0cf59e63298b915d013f0af616dd3f485cb6794d065f0c849c734d5dc1c67daebd5553ea009d1d2586e8b2dc6162ff09c4fa369595427a27bd9098f2d33889700f14ecca7fbf489d4ce93df5c77344b5f95951082f854f8aa79a02751a63fd906c8f31e7e1b33f502aa10fa99825d6eab147861e41f3814bcfb063d5c31418c04d19263d2456872c13cf7cabda24feac75fd74e1ed5ae1f38444aca26ac4bb123e4e5ecacd5222a1cbdeb6578965fe5287a7642792a9b91dc8ae41851a80a2edf192a3b8d47a369c259a76803517d91800869898f1c2e51608c74df167c6d62d6e550df86f920042dc71ca3862063ef02225dad6b9c5d08d50a1fa5ea20738c567855a366407312e9802c4681d11ca3db883cdf9c2ababe724ec14585a6d00970b7f23b7782f117421558ceed2b47b9a8b73fdfee016e5df0b5b7144ebed4102c93cc5e4123999d853d2a0315501cf1ad062ccf5e8770c08ab53d231fc098458b2b6af149abe84e81fe23065b2c923d7caa2591a8865b17bd4bd1c9bceafc9268574a9b75d211bab0726157d758474e14f3e7e501170bf9546a723ee6bad48516019a99b1509db9b8cf24862019995073ff25ea52770790bb7ccc46b43b44adfd68be9ea1e316958d21dcb1820653468468d1e1182931391d736b46fc81912a70e96552ecc08be14a7bfc2212e16c297c8f145214d92a06a3e2a84e1db35376b16f00e14287a4fd6656f5f47162e383845f6082ad45d5c41c0ff779ad87e0bdd983e1602972502754558e05bd67188c516c97d7d2130dd743edcdf387369574decbc75276dad3277fa311d7a9e191b17a1072cbc420ab91eb2c2a1e156bc280cc81f65c12f7f2428e6829ed2c9edbbc36a4b935c82098edd1a4c0d2e9417113e59efa56ac35956bef0abee79ff0efdf9a3a4e287f673b921fd2affceb4b0e0d34af51300f5e40e14863938687f2f40c84a49a951513bd55fdb1a11b28cd64310c90b45c9bef227626e36fb220c74973c8514151571d19ad1129e1699b006946e2653460fb862d08e22cfd4adee90ec77ad529662e9eb072c1cc6963c8ae00c4932580aeea306ce20e1a7da908a7af520693ef98c95618f6f37148884711976d78afcc15439bdc60d3f585918f89daf552d149d3d81455966ae29977e1dfeaacc40ca55db3a47af48f11a4e76421970d40e088ba85ed7022967ef0390bec7315b8eedb5dc47a22cd16986e8f5ba5910b5121c06d57b2e073f82930d8015b2b65e6855c9aa02fb5f1e44a02d71f2ecc4c3551202e8fe323de716e1f83d63008afeb5788697ba52787c27e42c6d6a470988fcd4d083c671bc5200da87d46009133da257ca0c893d43cf622045e8aa187a93017a8e829c9ad979798de23309344634ed4398751109e885d75ff35a682d97472a48353bd55300b13d604ca6d580c518e30836f324073a12c5f69ec2a77ecc01696da5465d4ac085f48e400b9a236df8b96497485a67511919c14c41944ad4d260c00f03fbe051a74b18eee885aaf67d5d2fc624203c90e2796bbb0462fe8b987942fb1ba008a11606301ddecaa95372e041743853f8ad1733434b387823a4790259c4fc352e3c56e2e231a7fac7e6bbf82b02c74005250e760193f973fadc7565e3e6e41f43bd0c319b94879f8e935ac9fb1ba5fa81d697ac5421871ae39dd02cc94cf1dc52309e79a855288fca8c14fae5e8f345f6ee68b8cb8f0a80e1d25cd917a15b9b13aaaacbeb5946461b3388667e81000165cefa952a189db9b5dc043ac511290a1e757d801fcea739265ddeb2c0c63f6b7fb1fdadc7b9c934fe9ac2a1026c3cb94e127beb194d24922c379a8bac470b1085dec6f8eeb412a1fc2b39ef07c1c24cf8bcfbf38092d614130c661a262324b4eb40a623f68aad2af3bec53b3cc53e3414ca1268bf1450b7c85219a9a52b1fb15d3cb4650243714ce16a450932b30d0d1a189023265cdeed3ad34bac0c2195d63f16055a9c6e8cd3b5cb41a1402c97378e54dc26245195508ae45a60f23d919e14d53367856e98faa023e0f5a272eb5e33b707708684f485395f9a0446162414cb51f3eb82a1d1e2eda68cae9e8779382e4b351ee739532df23b4d5e649c7717816db2953762a6abfe490ee09210a5a10b43041f4547b34f5575a8b46085267e4b8a62cd287ca68b8c3992b8158e4045b715fb9a38501791e27b551bb4b14245256da1cc000ea844553e4c0a421f5bcf0ccf556d9dc3990a3abd5be94ed041cd5700c590854ed03ca0eb3602d3bf6c57bb7c5d7443c9625e6c11e520f6f87b49dc824df319efc5d4aa3976dc9ca24f46c638f3f37dc896ac989ffeee5612433bf554eb5fa50f3d624bfcf514f1a64f6a9eb8a6c745f0b53362c9e64dac1b378bcbc24b1c63438dff71e203ad2d1cf241041d2c5c1ea4cf5718782a455ab5a021b6a19a19b8b70fdbfd362946b6dfa58602f34dd310eeb1367e078b851fb53b5de0cf50c49b8b910dc47ab492345c05a721193b191d11d185e86fd52e1c9bc41008c9b5aa09f022e5e1463e66d5f2c6933c550dcb33bc8771cbe24758b9cde905e88f62ce969f4c61cbdb2a5384418a9905181743a24bd87dc88a877891e4673c38bff5b9dcef9ff4d4b680ec8513054f7a25c114aa34fe100556960903f479541b145726dd74008a9c407a762ed531e8af332914079432f50318797dd74ad980064048b853eec9b8d6b4435bff03dc74be662d98bbe56a2fe39698874a121999e57606593359c5a04ad28dd218d2d89984b48e6137425750d8d33166b28ac58ea6470a93b588a658450ed57177538e9b7f907eeb62867c39faed6ca0bcbfc97f41c726e2e53758bd4756a45609a7784f305b2694f91327df19605244f2c10430d361c25894d934762e1d70d962bbf3c4cb4fa8ba63ce250c1a73d6a3551952b4ab82306ff73c507d76dad79c7dc722f9a7a8e5814dafaf930f052bbc832b061000dc9f06c184306dc32b420d702c26a22c904aa05d6e9b1d4593f519f3a5180a6f104243c4521a464ce1b46885875106a5122dc6c75379f8d22cac0429272d101daf4c90abadb50d3716fda708a06064ccbcc8d384cf070dfe75b17fd5793276f465c114e23f4d391d19fc9ebffbe657f7f81b8c34c4a4147f4191d73860e4a08421106fa995c62c6e55e601d621b91e31af0445f0a9fcea90ba3308cd2361ac8c3849904e2ba50986b5a1c0e1d9b92ed008f8a082a6783c607ed6f16dd8cf47df04541484130473915e620ae96aad9d0ba28e20f0b22a699e7db17f5cffe2b750826fac492ff33dbb95623fd13aca35fed5ee3c361942524aace7fe0a907bd10125b032d4c56a669ea50a4252cbf1acb9738cc46545d8413edbc6b70311db9317a9dceb59c605819730d01a4e2ce8ae578415a7397cd6a9e348d70502cfd81d421b90b8d4b772c63de7c3454b4537628d9c9144c47be6d09fcd53eaf7020314551783d9c78289bd163550b273f6092966fd1f379a639104519c2905ab606b75c4e2e611ae24c2de20e48c7e549265a3d04770d7ce89385c4fc5894bc6b406da0cdc073f54cc137ffa292e6aeccc45420815f24a66ac33233fff885239ab024ee0cee950af4d536b5580422b1b9952f5c712aa07c3d38a456eb9faeb42080c7390c59a4a889d6986db142c8e7c6b34db8d8b65a31115e07d35ec4c279586bbcc205b929fbbeb911786d9dc2675157ac493ba1f188a4511101ab5c385ef49b0d9ad18d74e161628a145273d8ad292e6329a9c9005314c5a4b145d4142faaa3de889b4d4a9d415420adcbcc1266933eff510b387dd68fb900d7940c1a152a828fd0ef02fbcfb830bc4547fb03190cf5c9878bab97f1b034582658d2c8f51039bc04f1e3542736352be29137836616a60c4a308e93010d63125ad3121656bb22b984d92ab03214f7c131add49e978177bf5031722bbc26f1c304a9bdf42e1c450e0102b6d0940dca33d4d6b447d03d152d32a623d9652e732e0f2f5281d27b4de058f10a52f1fe989651441e3e2d7eb2d9a731c15c4a55781e2b82cf06ca0c440d777c087708782b335ca87b32dd8a14612c98bef99c24f862bd52d408c3101d3fba752305d56317b8b5fc484044844a901481a0498395e178a7fc6d2d96aff4ca881fa39324ba574751bdb1c6a5f5c0bd69cd644144d13e8ba58ecbd5e68e8f97b89f7d3a138c02b206108dba40246938664cdb5e4011fe6fc3d4083ce41faa469fd03d0c72da0cbc692c477e784b501e12f167b24606802d0c4d110e0f227efc108ca1ec50be5b9fd3ea83679104c2078888b290cd554280c58461a4cf437787f7d397b84996de8ade2006bba191a7aad241734d0f2ea4397fbea860af7b67b70d9180be2775a163afab5ede52d6be4a188ee6ce6377cf46cd9d058186f761f3109d5313d6005fae63c2b40f92504432cca10ea626b2282ff0ca9b6e43242e6d5782798ee9e38cb5e257fb3130d134489ab7318be6e625aaa52c27f53526fc90e62ee95abbd76195d452e8e9da028cf2cfa76525dad856cff524bc93113a147d694af9f979cacff9b6dfda464847f869943c29a8bf840657eb63106b520f55a5b6f0a2406483fd0086e4a2118f1d1b74253578bf11c75433a0073091bb78a109049cdfbb8148aebc597721c0f71fe2f243f60992f6fa584bef85139290a81192a201c330be31b40d1eab08c4c40224434705cc634da9d61c4ec6c21958cc30000e78b1a5abaa78481bd9d946423099d079b5955c1128fba89674541684fd07e44946c56af4a0ce7725176693483c7dc41d401e827b9ea57f1813592d5f306b43ab572f7facc85572010d279b707ea0b50ecb26aecaced20165a0ec4641f55588a322fc3ecb851151846f555a7f32a98b5d1d04b5648e220647258489dfceeb82a6d52d2eb40aeab252ebb2b7fd8e107b00365df95adaafc417fc2492db94f66d71fdc15eccb9e5c376fa7eeb8c674127eb8aaa1eb91a19336ed7678f0513b4fd6d34ed54ae57881a5a4d6643af3512cb58d32269235ac533b93174984118f39dc5bb88955aa88903847200f53b408d29daf821d601658337453729d2e6471ceb504566bb32b4126af9c005980c23301318a71309033ad542109e845753250480bafb50d8f9687f663a90bdfeee663ca0f921748cc0f6b5857b1dd5e0039e6d6dfcd3cef4992e95df30f3936ed66eb7d0797c6f9c53a34c1fbf278ae8b3331b6834a845f6f4dc2837b4a5bfc70ee3db07f00887ae0216513bffdda6169a4d1b661fad79556b6278b33291e3570fbbfa710faebbf3b05cca2b68a16feb6677b3b40292b0a21f0bd38cfd6d64f2e40424f2d4397d90c826b1b8a28df020f86c6e221629e6ea26e2917931817c220cf6338aad2ec501b0704dd8366479f995c32449c3e8932e32fff4c01088b7d103b6147722eed3712955a3308acf0bd4b6c48600d01c11dc95e3a7a4df7f9469fba1bdcb07b40039fd4d5e7e4c66f0fff8b145bd60833d6f34d6b95e4f76c15edae47a4c3ba274ce81f05210bd55389f8b248a2ae01ddadb23988d5042929fe26e47ebc0474ffd1f6ef0f90ab67e73a307bb11190cbd39bf8d409ccddb2fedbe7d54258fd4340732984cda953c1b047c0dc63cf9e60634c7439126f5eb9e045b2c729422de9b04e9ad44ae7fabb85bdc3fe5b73bda650082c4f7c654195f15c6c301d52c082eb28c98d5598ea2e6550dd9fa66e591980a1074c85b1a8b8896c1e816fa6b7e1803b9f83d821e9283f6c8a20162876a4c985ee4d94892f38ce1c2e984913f2a70e3380280258240efe79a74897d3d160c23fe8773a64843471c5c978b77d4e327c7229349524719834e03258be06b1391a4d8178c7c98a988850f9cd5695865ef15838d6f853b0a262ed31113e6bd62c091c625ad205b25a032c9d94dc001612d1c0776d58615313a5245118b4c0b91ae7c83a0a2c08e64d33daa2f19a10d86db15a9d2256b3cb469848674c993ebc060c62104ed690019820c82297a2fe08c47ddb2083c7ed2d233cd370081c8fd634450201c58b2fae6350ad36d48bf21ae9d484556c5beff0a3d4fcfedfda7d9c95fb145a5621410ded5318739ed405a7e714c1792a42f13139ce59718be22a0ec17eb83fae87ff2cf380f2cec44d080ce793e20a1c1dea1289307570fe60eb0abdeb90364862b1dbd2c1d824c329f1800aaafafbd1f9f98205692a723cc666538a44f5db2feafeb5462632a53f2c41d22625136064ff41cc0ff3c9b92b0c65d375ab6ce69aa8b1729bab958e9ff20e676f266ab3d07c11cc894c8f17c57264353c686b1c08f37b912a79d98f834490231952d49f408e61934d602b40a929b3be021bbf0a5b5c6c148022611aeafb58c620722115b54392935078fcd5a4ba8d9c99e0c0872fb9266708c52e41c4e625657bcc2952c040eda7f1aa49e4040f989de08ededc9b8ef35145921dcf159137893a9f6dd89d28c96e1b4905bf2b88200501e433042258c5ce6b0948819c2d108cabec3d57d7cff2bfb11d7212031328b1b0b58039a11fb6c0f2ba2aa5a31170a9d0ca0c0dcfa99fdf90f024abf8c40ff411cf364431cf0e047fb4c58f7a0ce3c6acccee0ac503d11c02c24156e4291cc0590aa0b91d0c2f6357df111a55a0402738a120f4c698b38f83aa32a540c1998a3205c1c75336726a897246909ddcb9948635ee5dc36b71cdc6f09e265c1d46a4905151cf685dea21a54614bc160a82c5acab1d23832dcbacd74a7900606220bca802fa82193b8f49a849cff8642813d0db9f3553dd606f2015d0ebcff6e602b5db02b00ac46419e3b1dc2067ba44dd1499a38bb2ee5d2e1fa950198f2016c6ce62794e2e8e23108bac3c105d00b3da024fb00818564feadbd7304766abc8fb83f8a191b2e3e5b3f012bdd2b0bbc82a7473e0f047e27ebfdb0db52fc3f52e8a05c39d21de8b0c332639ea281623871210d9b28dbac557b6a650d051b1c9bb04cd8478a98182473fe66f2dcbfb0412abf5a5fd7f8de8ad38c90685c50d9492b46d0f108175a67359b326e0e924dd2c679946b3f2b40d00d855833de01350eebc1b0b42122e319e009b78ebe66afa451c9a6a02ab35aea04f50e414728f2e5383ba9c6248bec5b6e210c5dd809a24941328d87881ac81860ead46c715dbeff9335625c56a03f28e2584a8d2591e6294b850825a664b7dd1e359344b28f7734a25ce785a9aa579ff73927367b91bc9f91444f1f1a0670c03ae655a0c99403826d5348cdefc1ccab0842748714c1c419c4821f9fec081a8087123b5bb1e79c179792870151edfdb5b84d878775cda460a95a1507236c9d673231ce6ce73028ea481e2c8172395a4ec836eda25b8838f9076757ce42622ab1639ff82aa2210322f215a4cf49a0c3c60cfc2b11001a914f8f858d751a03c395628cce3e4e9b5d88962504e8562d21c455026af654e510631361144b2ec48770a0ec1284df1653c5fb317f57ff4bebaef2cf1bdb356cdf7a16852dcbde399d15e752531c4bf513247f284ca138db46e1a9d0d6529e2459c1b61efb9f5a90c13bf56a11eeaadd6713dd2eaf601958a1c014ffd2f4615e72d79c2e94094e990202a0cc939bde89cec17793cbb08ee61462684faaab5685ccf94c71c661ac3643edace8b6b8044f3c642062841a6045fa221684d31e6d3e1f03a5e3ad502b41aaf55be90945aa8cbf13c5061d5d53ff4363d987334088766c40b107510087718ad2d93c86e17b7cd563e1e84d454cad49c7583075821365c37968cf795da6ca8c0c94a4737cb38cbc6c146e0a6fe6ae38f257823c98d7b66b656fa24f24222439e13f8a57c372574e770d15f8f70a47cdc62911985c6b5a77c2f3c351beaf5527cfd5c44640e3c97297d9b4109b05204ad13e771acd73ce406a9307aacac8233ea03ad7d6c63ede4ff98fbda0d9482405c032f525523bf2489bbbcee0b8d1099121cf62ed1b5fb2727ce88ccaa70f5d7fdca9aa0bf0e651811aa36608fcaecfbf2d718688c7f22128893f04bd0ff7d4c9b3743c7f892e33553b43dc09803f0c330b7aab0f016bd2719675bc521325331ffa34c5ae7d6788dabb45b1b13fc155d1ddfdc70d9f2be5b65e8a26eafb57b20ab4369a31fc0fa65d61f75e9aa3fe4aa360f5defcf11dcb33bbf16f8a0cb727ed34f11789782e95be7dc9b6016ae7a3952ad03817db3acd6c4668857812430c58692656af2d50154b4b3bdc8628328ffbeecf4b30c1226c9aa5d11105bf215595da1ce3d20130b1a72761b3470f355ce3a326f28a8dcb3ff48d6d34fd6925df59f26b9182f5726341907ab623d09f9d44364102ea4433fe0410050ac4d12b5a53a000f3e49d41370ae5c23df7058c3138e4d0ff85c4038ffd51953007fcd6be5eb65ad35e80c78f5e07223787a7a924ee0a8caaa7aea63106d8b30da083e4dd666e2d4aba2f2e66b3924c776473aa32ac459bd5740621f8bc758954b565cda150e3312e52fdd247e996f428cba1021a2fc366644a677dfbe2498a165dca0635b445b0fdc2682e49ae5965c9690ca72bb285cca9ad85e6c5cf70e1144b095d1ac160421ddbd0e8c436fabba076217bc0df2e69098a94dc61cfa27f77a44f931903ab8e91476d6c84432f44db63b687ac7c02678e1900688cd583f4a3365865fcaf4a66121bfb3d934a51a3553afc33bc1fd77f69a1e508e3c9b51f0341d6fe840f48a1ad883fcbb5190096e26a73ff80f01e80eab14f49fff97d7bc0b59324ddc3de48e8e8f7cc0400eb8f1f23d8c588a935607dcc83607a066b512448cee86bd614a8c9e5a43807a3d0bafbe64b240b475c348f98480519635c2e12cb1a0b2b06c696193bbab880baa2ebc861f34ebd88567cb5dfd94c1cca7225e4e9a5c659772e68cb8a2421497a41851dfff759df3c68701b0325a3a564668fd41696d627ce4928d52c59a924eb67f69058d87fbde1daf65ff3a850d1007d3df8f928a95c4ed1fe464a6f90850fe852571849137edb0308fd5ecaead386fc9a10bccb654fcee75c8f4d7be7743b54380898208ec7e00b825fbc3cfbe043f8f8e984a78211f5239b55a02085bcb0c826800e86baa5ce80d0971a0421caf6983a99c9293fcbde9b4adca7e2a2046c8b82c46520407b59c3b6ec71671584096aae4a5599378a4105aa98a1880fada3a425e4be9a8e04089f90ad259420241e53b6985aacd0114ea26c2de6525b032484ce1b8e4f84ad1411ab8e6b418c946974d9b80c10d6359719432885f6cca4800ae38d37aad0be12041924c7991b0e125210d48f3ec8afb195ae8df38729abc9d8f0420375873902a1cecc0465c036d00f4cf82090462a11bf0e86d3692b4407834ffa296d534547ce5fbe8ace3f05642644c0103e0a5740f415736a8ea459601e19e97651e8519ee21f5a1ba608c4a9c7d578fe2341f0d46c82cb680616c6bc64508b182c66def08959218e632d01514187ec8f7aaf120887f0b6f62af4c5e1573a5fbd69d9cb828824c9f6fb5196712b151c0b4bd399b603612122ead94dfb45d9d9166b1d586f2f48bfcf64cea22e44065b0ab69c9c8fd28f94f7b1b72e1a6a8f8f8b1d10062c5a4f6469478c824a3b803272ce6ead3bc0bc19e500802ca65a93e3cee933cd714a8acc95ad4273509f3ec9312a5c099ea2ce5c433716e4eed08ecbec1c61adfe9b8d1ce6a416267506b456ef4e0a3d613ea3f1d5e5a9a25e4a419a32cec9a55a51d3db8a5c6ecc5366b4a57d1e49138c8088bfae02a5b6b6b4af3d210f78634fa95c2f10fc0055c5824dc7ad3c1db3510cce39b0cd5a3ab1918d886b3f684b90fefef9ff90eb8b33d82c8fc289bdc52b6ee50a4936f9ee16d6c60be67449b5feff1e69caa548a2e9e8b946f40984f23696af49a382aa1601e72f6b7820dee37e986eb88faf2482159d787d66b0f047aeecabec55772c935692c55ea28ad62febaf88875051169598ab1934396227076f698c0a3f89110c0c4700f4673a62a90297e88f3da14b5a2d3aa58717c4f89866c4a9c00eebfdedff9d668e2c6f6d242eae85a9084f426c410fe1d44ae6741d094964aeeec02ff42c8875dcde95047b246f0fbabd94a1c49ab000922c1ad692b9f05e09108bcaaf3c43d9504f2d84cab2dac7268b1d2eeb24c9deca36192dd2c8336054ada7d8cf1dda0dbee65abe717dd1bbe4306ea0f08a8adffb9457aa6a70bb10e260dcf5e469604f521844d92640c8d659e1dde8dc99b2e8d52a7224b99cccfe2561f3e5b81a5f18f4025d72af11d838a599049cfb4bcaec88a1f7ae5f817a2b815d76b4b512051ba8760604a423d981f0612c035a0c4da439384ba284755890b5e5b896977585b41ed1ea82f93efd3fd3e1809174ba5783447558466889180296c4bea8b1845d7fcfddb878230fb9b57703a80890b1efad457b3a47fb51940b2566b4e9df38c0c2f5f819181f3698d1aed7aa5f8a1ce282acc4a301e76a00de92b1de5472300d563d0af93b11ba4c57f1abfe3227d477d0f4c00db2ab01aee036eddc2979af698db533f34b0a8444f3348617a469278a26100c71bc923851590c43e92a489a200aa06d132d7ef6d870f74245276d6b6fb3705c1e394d68a626599e3e68d65dd5e77e0c20efaa0c0526201b21c15265a6f8ba04b610752401f03731cd59176888b08c4fa601d1643c5860fb5b05ef664596429bc55c9a73f1b922247ee85fa00125f7483ab40601e150471a07a217979239e125030aa8c604899803569798945f16e8b4b25a3a3017221f275dfba39a4285cea54c41487ca6f41edf641a4e37d88dac49a37274398cab476c5a41995a86f8a7b363fadd101066d17fc3acd7f97bf48198541f98635db7976b460bd4316996698568ba71b05111ba2c7107cfa865716251774d00a611ec93bb1db5ee478c6368f023001592c63219e6c60571f6692b8f0b743959ca23139007983ac00c6fcfcafef4744eea2d84fe8b6a4537063b6b5f60d7a243af9f736ace6d0181a1c4ea5ca5e86b6a74e2a15150b368462359ae456c49dee344166aeeff851949001687c9c5c2c8d07ae87d02d2a43416f215ab08b41bc01ab5ab4ea8a50fadf5a26372cae6aea42b4974e5b7b79c00c954d0b20ea6a250246b8faaa54331b60f929dbb5ec0daf0bb825a70fb9ed9bce41ada71a6480226748b3a77c046124bb2806b1cadd3600cccc2c9d67fd60e488324723ede4110573fbcd51103fbb1d9d99d00729548cf0eaf9e32f42c8cfa884bf291ba89d39912010a1a757e1964c013bec0474e88839956bd6fc1625e418e4817321ee27a3c0ac9aa445e5062cd9a4dda1cd03618855890d505191527ec18bf0242d41d1c2c8e18b515412ce9c5c25cbdb0babc51012751c5ca96a8acd9430c24c63382320002dfa7658c7075621cf5506c4c42216ee4d37ef2e8575ff51b50536e11ee0cdadb6ba14d96619209838955f55d10d1dfd1c81c44147b3482a71c5482f1d22ab8fcb9b3842c846af5fbd50eb0a52c34a8153fefb2e2549af0dab472000468795110ddd0f9acac0e8e6865a4da3277bad91a6dce137f2e59b1c4bd58f9c643842dd7bb6f1eee70dc6f100f2f4bd795b9593de1b013ea8183343130b189607f1523371fb34f1ea0b682aba5b85e58af42941e15da5195cde5e21a9e9460adee2e007dc17c813389817131f8b73629e29984db0c538aabdfbcb03a7ca261ce0d71c2d2224acfc72c097b869549a793d74f51b9a852dac9658dc565017b1720f86ae3ad6a319ce19d5d5158b6063fc20b4a252aac4d8088d283228385c9dae38606c74802e7687b7c56b7315a194873e0bdeaca6ca2e155ab085bdb7a774681a384c77c563bf89e007786a007036a9cb72dc96686d1a50586892d438484864eb6c87c2af3d1a65fa25ed3cc6336a2361aef15951d7230a15234a366784881c601cb6a985dae6bb84e6b0658e4ceb99142712ebb12d92243233c6283ae260569e26a73411d6d52400f23dd2a596696ce47a1ec23755029f82484428bce73a9c1c914988bbfc3457fef481e26c779640350ed24df20572422bcfaa1cc2ee25df8dc58c2c6fcae8c41a3e3bec21326dace00b43ec224e7980c6d14cc2d53887d07567b6ca7b52e5340745244a565616680b1d8a273460031268c1bc37699829f047830509e1eff340729b319132acd0d51823e2505a5c9da66812111b2f073b7725676acd95c5bb7ecdd0036f16ce4613378846f6e48b04968a54dd66d60a5dddc4b1bd0b7bfc1de38ed37f8a660859d866f169e006ea5595c34236b59f26643c6210a461e24079a6c42104287c43ddc58ba90bfcf5e2fd41282c56d83281446a0be7a40e4325db217c95972e30396e40344b6566b3bf3ba5e9b3048bf62c7ab17277e456342a4d89d47eaab541bf93139b3e309edaf0382c00ee76d80897583d867a84d04b69edc69869c8ccd893b3b700f73eca19b9c9b948487b4262a54b7ea3ebec5d07d8b901b434f60c6cc06f9f8c4dcb991a998afcd5f2be90a797e7c820d9c9796e064a868593309b851e2fb1933e65ab1a61e013019afdc28740a2240877f43dc15223de8b5125c8700cc2290d7476984c6c75c7ead9b557076bbb61fb29ef92069aedd66d03bf1fb1202e979a45e6f624dc9ccac9297a24a6bac975f85e26488037947ee907648d2a3791f9ae7e7ab132aeb7390841463e863e520c475247adcabc09bae7de65d1e30bc9982b58c643c1a4b172b346759f1182d8b2248dd18a90064fc5b3b71941daaef704e1a74dbc018b0c6b34eb712b03aad7367ca9685aebccd2c392545a6d5e94a459fb770491ec0328beb138c4773f3e8bf761b2a70ca5dcdb2a8091ee6aae4a8874a1f1c3a3de48d9657a08875bf0ef2ff67d800771d5b986f78c775bfa835d22274626918c15b9a00aeb375bfe04569e1cbcf40f2780e9af3f13cc0b45cbcd318e68d8aaac87ce119eed8c55d5283b2dc557fa95c0d9555276ffe569c1b7866d1da6cc4ffe8531c939843e8aeb2381c8dcd9d094a3b3908eb49c8672dd0f513fdca68d9dfe3dfd91f4f2f9c748ca93c6b701cbc501f605542bc3c97d725b7b6390ab240d1091a76aae011d50174b2bd22898af32edb2617a88d0d8dc21da2224750f84528ff9cc4faa691ff0df48cb1f0644f72075ce7d484ebef7c8efdd6a36e5adeb9a0fc5b41eba288c1f91a3257890f542661614ced1df3187a53cc0217e20cf03e585b1ac191176e87fee82af1466dfc775f3a4673b0d1ededecce65a92d379f17391a704b53abe695032038c656a77991879aa7b72b8da7de34c07908ff89fff57afa5f2f2d55493bb663599c28bef515df8463ca1a318923a1a993c1fe7b4948054f1f429c702914628d6ed229484085b174dad8067795f7d26dcf96891f25bc5d869e8db5e98f43701a5f3fc5e1266c0c2b991815bf82b3608f31b84542209eb4e4c6042af3181a59148834feb037f6e59185148370a10bcfb48784e28539d126d720b2292c7bfb8f8edd1a61d5487df099652ee9a225c6d6f2f8fd7d0d17c6e9811cc6d00a8876c0c0a085e78556cbbe08687e293196b5b61b812f0d36c5b093e2438d51dd386219cb72563c36018398dafc44858b1f3889c53277655c73d4953af814f852454ec39fd94766487bb24a263ed18542a1071ab91dbfcea59f0109c5ba588c6232d4b07f3a6ef3767d6a553c757b66c719174cd0a01007319edc3ede26487ac2b98f68c9dd540fe300588e7b37fb4e206c3c0511d7e2027f01f6dbfb59694f5075c8fb611d50365cb757b1a2519a325be31290621a1ca4c428a3d1025b354bfd8b8057605fa3c91b50d6f4be8944d55c54659bd472db65c58d9fcb962b92b371ffd3a30303ae709f886ffdcd43ad66a8a712dc280553fb64fb092cff36fbf125960224344cbb28ae91f2577407ec036ba6f7b7905cb259512470112c3cda89cd5e42897c2947bc65585a0baad60aa64080824bd66596c85db037b5e6c321c58225720cde8671736577595bb37b3ab21f0e56f580f43dde22b4ed0e4ce1aa56a1f6004f833c3fff1c2908d1414daedf9230b9b25ac72a746da7abe0432b44d5a0fc58f11400faade84edf9bace4e00184226033a6ee810323b6e42bc8d1ae567476e9f350c857c66092d61c46d7da01a4d7358f65c306ac4a9dbb5dc35c84a470b178454d61f2899160b52883de05d1ba7f671a600a27f24710eb51cd5233eb061c22c0e1d677402e45615910a2fcf05ea652649a2801f9e073b2cfe2425e4360200b6411407a26e029160a8e10ff1f385e3da663eefe4000b9f2dc12bcd2ff1ac8436602ccff0fe6fec342cbc9d0352e22240b56dea0671c984cc6eb35d97a65ff15f48e005c72b553f873f7604e13d8ae26f8885aa08ca81446503a424d6ed8710054cb122acac5e8e04856a16e8029101a3d438947ad409f863cdbd083b7812cdcebcdd70dd8c4389640b930e8de5d725acdfb2aae937d595932c5acab8e221c531c007e89c3c8beabc422aa8d427c09dda74b54e2be9d81669bd2fdee0e3b1a0a5a514103921c593be91049441d701085a0624170cd677505c79aa68619a3e359a32338e4cd20be1a1ba8a38ada1f603662dcbb301205a25e1d2a83ec0bff82316334688c37386ddd9f470b971b23d3b21ab05260f86f49dab32634f465dc7cd4789b20672d251d8ca37f71f4d88454fa274644734d345c9b1986532d009a639c76b84f1d22563c2ad752b99a99b39b4956d9dfcf964f339bb9cdc66a08fc3026fd2c60ce3df7a83ad128ad1adb9602cfb189041a2bdd6979b1542269c14253e76e188bc2373c4eaa7bf015f49a75f6d1b09c653b951be3c156db45d4562234aefe52520f5bcef29c4ec1d2f9fd56a69cde9040b0c4e32067a320bdd662e82607b826bdeceaa0adc4d36a35c014377816a67e90e225f855490e788b00abadf893d2082d04ab7c58abe7697ed078380c6a180e2e2e95037838a183c72df89773fcc749c62516d9a7e97486e16516ca8ac4ed3fcce0dc6419b348d1eb3ca7bafa4e07241639ae5386346623ee99ff99d177b915b204d008fa0fc039451d722c1a674bf633652320ccaa03c8f54dd89673cedc2e7afb3ac16c75edc44f03a9731d02bcf8ef80d720420f3c1a22e005ad8800b3dfeca1682bf46efc0005239ba00a87003c286bd88d8d7670cf7108f809cc0ab835bc93db9c1480159cd1122f456e3d04c464fd3f8e7fa75640f22c00ecf6b43aa97e6c91816cef9cd1fe08fdb2c57dc77fbaab0752fe5179b9af0692891c72bdd041f338d9136ffd9b68ce0ac603c7763e0890303c5d553b9e2b5dfc0df3ce29b81d8521449f6996f4d1b2f1cb6833b65b631d5ca7c35e382a4f18ae80c68056452a269eb33ce2c1463f71696e38c4cce75bd0b94e97a438bb133b65606b12bd173319303a5d9c830a17ac6798e8076d3ae7ba96e92f48b6afc2b4cc0a5d921a83af00f45e2e46140df51af25fca2c06affae02dfd3f9e88baea2621bf4e6d9d73d6ea550cc80743c76d98df57193a61a6f52b4e389bd6c8296cea196e9a136a2bd2711f543f3f0fd2707262cd9f865d80ac98814de31ab2e5add261d448c4a6397304b8c697c487dae57a09714b907a77b88178c1a10561c2cd657a183ca31bc229234428501ecc3a3f438afe45a391a9a632796bde66f5de5932371f33f21f3d105c7551d45d3ef3801fa88dfd247d32e99995396e297fcd218470f14c81959e0aa0ebc6c828f009266305964f8b5997ef9393fecb42387daf570ce7346d2a4b765b998fce3b85b8dd22facd2101a10f01f41cf0dcb1aa76df5a2708de4ed664560a19730ddb08c473458a4ad8ec254d041023674c25d330e060e0d37c9f0d6d9002a923a726c6409eee403865b584a533918949c6fd4f5a842af43783a1ee80ede83a32a6d1821562100a47708fc5d3ef81733c0012f4f12506fc632ec1a2217de3daba7eb4367ab340749597230a9be0430f3d3bca0c3d8f58923d8b7e061410f7b50ed84ff3ea142720317eb653f9ee6203bd5e113471f6f6bc35fb0a2bd93004e14a2451713553130283fc8d1d8bcaf62c38a164853881ebe5ed7d3c0891e81c9c21e97b15c6a67474a7f025685baa6f8000616172cd3af61e94ff376f6667cab9ee5755d4ee674594012db8d85f4111082ec35ea86857d20ef57b749101f06524fcc9ac7ed96af2ffea419d149e7334b1c218f7df12938103573f70f47fca209b114b787f878b4c00ccc523d96069c2dbfd63090bd03c8615ff10621f2a10fe3a7c62e1c0ac997fd9c3d027dcc6dadc96e5311985d330a57bc4c437060ab825911ce9f92a2fb458e206d8dd0088f9708c60663c36870157ad5e1a0103bd4ff6cccf0b6de03ef722e647fa4d6ee0fd56bc4619cfc8d5c192185904ac87f6448e38c9ff4dda09402e86de0bbb24fc9c2c310557e126895b1e866268100211616e5c3818e9e94368d37d4f57b06002217c0be9f53ff58e20c6a10bd55420addb251c778cbec661dc046ba5b7fb5a10180fa80464dbb055e23ef9a7b1d22413fb97779bf811647c7ff04909dfb8a3059659ca5ccaaadc8f3576a72e039ed6d927c8b0c125ba4ca2811e597e67ae803dbd13e1f71fa5b3e75f0413b03f153d843aef9651ad23cece89762fb9d4260b7fd354e2433f29787fe7e967361e7b4af457bf3a1794901c89d5d905be55eed84f02e2b70802edf7823b3de9db2ed9c30b86085875b7f821a5695f8bba7bbf3977784b822cfcb0a551efa30a865ed193987bf0c3222e3464feb738d61b36bcaecfdea84219ad07d83e022ae172e7c1daa637c37daadb68d6743e3a0e19877eef584bf16641f87033ec606a3f183f8ae06a0b80fe100a8e3ca805f16575eeabec5917efa6f66c5ebbdc565ab94c3c2d65cb191bdee9f52005c58043a1cac32a9f3682634aafc4c88ad3c10538bb4ac8cab72368cd9e47d18576023c5861a8dcd4cd5a37bdc7544e13db55cebe54f8e9f54d5231e2fa670fbcd40b220b968cb7f643ea7416473d670ea67e62d362dc0435470093bd9449bc5a83ec6dcf3c74aaef4dd92319c092cb094320c9c6e4c3e3e15c8d0ffe8b361b850d5ec2776b6c9efacc511dfb6e65d2c6bfedc8d94ec87cd079606b4478422d7e695b7c5bb517206209fdcd682bfd65dcf8929b2d639ad98aa14374c22a17e8484862d13473489e520e159046f76bea9618563cb75608649457b05ede1b8458cd818969ee0cb1ca388dd3eb2838ea832d700a5fd2ad009730e04b2d28fa9a3b8f13ae2f9bd023cd4faa1ba8d3bd0a28db2076b8d0e9ed9ddd79a1f2517917c470a7678bdc63e5ac9ed11ae74955ee36ef002a423338b69d2d04cf5e9ba6a4490eb38210cf058901ffcd6275cccc815a6914c362ad90b797128c43ba854b21dd520dbc7cb0a5f2cf96ac8bb98e8ff5930ac39acbdd398f29cfe873f6bf396dabb0a638791aa13ab80079935341fd03757f42d395df7399c8c6442cd003ff139bc6a69dbd4c47e77d32cfdbaa772ef25881025718907dfbd874169ff110141868aab505ce4727db30e8da258030d5f27abe7d45d0d10abf151149e2f1121f44ec984db3dd7171de2017122f0eafebc95ef37ab58cfda03e215e038bf4d004fc5b8156bc2092966b237f1d61307833a7013d9f546260b80549e786f485d74188aac80836b09e038a30f4a09fbc2928da8dff24c44754a5ebe225cc930221d9516543b930f645f9846c7c02a103d5431fe031e18a669ac52d58feb56ac0440c4b51152b17248455f5e247f857de8ffa2d921733f030889d538f4536801f4f45b40eb63b1ba2f46f5498f9e1eb3861d9fe69fcd90145f41030a217195417ad9136ecf67a29d69fe45103322244cfb4e53386c566a482f750d50efdab3ac3160905c9a7021d1f3bb6d3b1529186a15dd75ae19c60a967c8fd9cd50a7b76ac0abf7777d754f2766b41b1a16e466e0065f94becc730e6f8c26f8628fb0d8a25f4715da1b29151dc7364c18d59cbf6f3b6a46b81131a0c006fa97cd8e118ab58ee04a16cd1ad7ebdbece865eae347b259f4c739af7bf1651752aea438c4f532eac5c7009c9b0e27b7b3f32d7caf445d156577446d4cdd90559a170f14119260af106681929f04f13fb882820a8c55a892b3af68aa6462ebaece5b71916e2a5ae18512783fb6a081cbc4a77477afbdcbe06c53ed53f25a151f40e06c68af8bd440493b56e555760d3170b5735786eb655c886a72aeb30595ab237760992e898078df48bb2fa253ff2de8c8588cb02c27c4038dac6b3028c437e45bd2adc2566e28c8260f8d5bfed16aa4e34b1cf63d62c632585a6c5817091794a7b0aab9ce2ab5158847b36cd71c89773421a9d67efe9101bf3cf4ad44bf4b5bd057998ade1f59bdcc81795f3eac169ae23b60c0649c37e1598577ee6af72e6d7ffd6b212c29cc25464f4aa73fec6aa1510747262843b52bcb6331aca9c35439d6997165ae6af13fb6b6a81c14cbccfc4db0077e3f9365ab5bf70d8e3c56022d8f3c81b25eefa81049017dfa933c0bcc39511b67e716b7f0fc6a812458ffa60224c0e54c258ea8f88457b62e14282b3153cd1cf388a7416a1496d0e1290abeb21bac42c7a9e6862d5b03e0f5dc5cacf8c2340e08641088a725da64b5e5c1f175cfac24694e8fb2cbb7029f7d6e69496e2fbdc20ce74a6aa78c3561c378f97fa3b405fccecb5da286281c5f45f5b5767507cb6e39d04535fc5916c9d0b58843bcfdbf43a0c5bdac3aee06e92b66a1cc9fa81fa6446c04930e68e5a839f08dd3d6c9b19080567fa2b18406c058c824ab5730784fd267dc0f77a205a6c499c138e1c4692e0ba9203bf3245e82092fceb81d1d256af900535879fa50c83160bed8900fccce560e4a4a93d117247403c405303ce5bc119ed3c533b15a3089f4c273ca6bfb87513d6a158d493115d7adf8866416bfc0618dee93ff283dfc16db386d381fb42127be0575422eb6fc8bcf2655fedad96d5a5e3ea8d7e58126d3a5ba3ff032c5e29fe7e1d76673e07780544b97ade0e18bbb023c88c5fea11e97cd33cedc475d89ba678c61ec7d32fd3e58ab1f231481027639688688848e4cb7b15240b05e0e3bdda93b8e752f5d18df440d09cef84f81e5d595ee3d48ce05ceb6b7b95d84da29125372624a6319e84cbe57d655cf8905c9774b60175162e9a68db790df257e71bc8c2fb4ad855ecce84110616e0f22889482e0bf8de7d2e4115cc7be4c4ca99bd7b8a638e5265ac02f7f3e47c01d2a0b2e7c7d1c87e302c136a09fe64795b527124d31b848cfa71f5548da638757a98973ffef2623b8f0758fb7ebd594ed9231e9b01c992ed98e52c3b5e485418ef82fbfcc880ba5eab4d3139d81fcde0eedce82b673e83a8221a6b752dd0a513fb0e6cd8066a67196be7d7f40c00a03fc71ec42e964d5ef77e4cdd1debe93ce46cfc7c4d251229a6fe4cbb53fe0664abd4446ab2bd4cd33251d4135020a66d522f9eeeada961fb63670761e5f0508318ff96ed0ba1e98ccf354de95f3cb10a9021e48637ac2cad1089274a7bd21fa2dbe790b21b558fdb17b61df4d1188e09e327164bfc9d8d5db2c9d4d2efa6cceb4d994582c8aba5488d66fd3523d09fe40e4ac1de4a12cd936b43bf46984b6b52b32604b670307982ef0addc94ac1b5930a7de2a9af13e6b09246d0023a49bcd37c52012dba814b04c945c837700498f7be48e227258e0007accb1919a90c486cfd3ac0dd0924f3cad159c763e59d282b61b09bf04e8305b8a82b952736aba0510f5eb61bbf1ab405a7df18d368705445910c0bc65342c8ccf3c101c3dc7cfee7345055e6cb176956ec114a92d4d71b0c84de90660e8109a06ad376a4c5b9502064ae97678929f0f5956d0e24ec5d6e6e00184585552e9e5c748bccf5ec0eeea19f8d7c32f279c4e7d19f478ba74260230575a710afe867aae3c90d28c4dc47781afd646499a28dddc5c50408f14ced91799a2a6088a657f56b9ac15a2333eb441575b9d36c0268e5601513bb0df1853404ae3abd3721f6f89d3e5e4c606e19aaebdec9baed58a2f3f801ad8c5b80480e47449e6d52e6aed02744c293a014cddd175399d0a5e75ae0f2d3411462eca12b797659630c04e95768f9e9d3417502d21ce74f25a73fb3c2ed76b5b84a694fdcac365ea11f89ce3e4d8417f7d1c5e8b8de25ac887ffee36083e6cba4bd356a5c32e92ee15dd86e300858420842c96926083d7701370cf4e7d73457de25b777b316f8295f3b02de61b7d714887f85cba3eae2752fa07c9575dc4e35dee11eefcaa6ecffb7ce782870b9c576f6c35be3e8a576285881adcef1c74af0e7b2c476135845e89802da40846075f773426e99c810a376ee6df1cb94f318202ad08765e5714590f412fcec02ba656a805d304cca9a0e75dbb9e7efd7dfbdfcb6fdfb38350435fa7aa56dcbd93c7a83eeead8ecf8fd86055072cb6ae45320bae5eb43bb8b1a8886efeee7d5817b13737641c193c51d2ea63ebd7af2cf7d8817514a7eb790b6f7de524a29b7945206a4076907d2072cdee35a3ce743e77ae81314b92a3d86ee38e8145d3f47a5733cf4096ac089dc0e7d822d38fd28d80ec304fd3aa3091abcee3a011867e89ea381f7bbc5efaf4c5e0baf8506238edc735ee765bc2ab95f674cc1f69cfd1b0063a9c7b1e4e258be7e2c3f83b12463178ce58bfd1884c1e2d6c39780ede11516fe0e5f45f80a9f8ee5bfe86118be1ecb172cc459c9f07344ae92e15b20ea4a86bf42fc2a19be8f7d89b48722eb5588a5de5f8178024781587efb5de27e1c1105dbed875cc91a6b5ddae0cfbe7a8f7e2b91760fecdef7519086fdee2992cad3ed0d963266a761ad0cfb29d8eef7de13f4be8f0c0e2e743d6f0cf8c8e090a46bfdca607ea07fffd4d9a309d646560f8e7853a79cdae3624ef7abdb8936f8afc61c38cfff8a365acf1a7384dffa1f8297934904126ab0c04f31f84dbc82df63dc75afbdbfef7963d9d9ee5583045014c1bbd7fb6e86f75d775de2eab9134ae0c2d0e5ea72ce99036978cfd92f145bef12f95f5183f0e9bdf7d65fe6fafeae2586cf45d77722b8bbaeeb401a22386e318331f277600c8e86f7b3929d0663e4ef4e28c146abf53a6425d877d996fe4f74a1dfd31bfc1efcf45f1a7b6f9dabce9a6a9a3d0f863792b68793e1d94524781dcb4ad5bdffa67ad745f5ae7ba8debd4fe540f67fb4cbef75627eaf25ae9e8bacdd755d476927e6ae1bcb1b95caa7eed1a72a0d3975fd9d1054a6faf71d1759df12575f03bf0839032a5c0609638d4a8225b87e35e6d868fdea572dd69863835fb1e458651dd3336b55a5e7b17b0fa4a1bf1b3d9caffb278297f7bd1a95c4f8b5d8e98739e12664a0fbe9d4f177630d126ff0fbfb205412ff279628d49ec7fde057307f5f411a5fce9fbf6ff4795149fcddfb541feb7ddf9e32175f155d88af4ae2e7e29481e2f72e5185f0b9b7a20a382229c62a8969ef9e25e6d02163bd377ebf1f14bfe7c00678a393fc17a491bf1bbd09ce70b21a57b0410312f0fb2c1432e0bd373a61d990f318fb44b2925e774118de7b9e27ee2d42f719648027727d1cc26427925079f48f5f492d7ae19c0d9cb73ff280f1d7a83c12e0be35e6d8089ff5e1eb904db004fb7cccb181c37a9c91bf0e191f7535407dcffbaefb95986363f5fcf99883ffea75c858628e0dd6b7be35e6683deb75c83c2ece2e54d6c85a620eaf0b0f468cc856a8008a8533b2590dd03dfdf1f1041336191727182132c82608a35be96eb3c609a5ab054c5898ae24d5a4151010c4089264f79de0bf39a88c525518ad239d72c3bf979c89177af95f105e6ace5d2f1f126a4f0637164340b11773e95d544a5549fa742a00697859912897c37174aaf250559ea944a4aaf254d0e957a20ba0de549ea934a4aa53207c6ba1971549a744844b2f6b519d555b2795120035bcac489d7ed2fde251ce9a94e3386b5a6b31a5f59df0e86b1d7b315f5bfc5b33fffaafffb7fff38399648ddcd0e9e30c99f0b04fa521b37f32045b15103f38d16f9f4a361fbdfc98116551fa3c4da7f4756e9c7a09e865e962de6c39bb00a097b3a977a0a65ed25a11bda443ddfe2ce992559f6fba7dcebef601a6dbe73e4ad0edff8fa36e9ffc71a6db8f092575fb2f7c6cddbe084cbafd1a50ba7d0954004cb7af815a996e9f033574fb1e00f2440302650b22058950b74a4296e8469d726eb8124d8ad6bf930342324001e4698b5013a427aef4cb5f5bb88ba44f6f962160a0b203922b4666326e8a10679cb47e01af4a6ee15e956716e1a5ee940bf2583d38473fa7e63187f7f87374bf5f87582327a77ef73a6439c61c07ecc76f633ffe5a471bf647ebd16ff325fc8eadb963f5a8ebfffc80cf9d07506eb4b65a25365dee54d72f7e823fff7b8b6491eadbaf36c9f6e4d8587dfd6a450febb2d2bafe0ec5133f3107bf0e99751273f05803c8325998c61e1401c4e5c2a70cfc1a16a6ff3f870df6f5c72c4c7fd78d397c2c4cff37d631871d73bc65fa9f32a82459f765aceb37000f2eebc69c3d56a092fa3560615aff8a197f2dc41927bde45dfffed23275ed8122bc9c55746661faada88114ad736cd8af6f47eb64758e8deeed7b50786999f468c29daa1547c15e8e312bf9deb4009f37a15ae7a04f2f462c75cfab9e950e725494aa72552337453b5dc2f1935079ea63ad395f5918c67fc1b3f86973be85a881a823ce09c3790bd208df5ab001fa5bcf7f82325cff3d97399d0227e2c89dfb3205db9ff53ef604da5d6279635ae9c43205dbed7b9b8523b6c4509c9504c5fa24ce1a25e2c8238edced58a52a499f8584d727b5a74ed55aedb1b55687ea122a45f5c61e3da93d768ab33d357559aa22e5095d42876a5254f3cd8ddac31d91507bb89b8bdac34d59187efc64e501ffa9a90b082c480e099fb23d15686aac53629db2d91e3ae66d19d828a645f42f386271443fe768a9d3b7602cedad63fa2bc6d23ad17f8da585a2af622c6d54c76fa76c0f05aab04ac138e51aa73a7ece667b2e70441f672c5fe15872fabad91e9d0a9b02a1d3eed6319d62801ecb3aa6533086fd146c97eaf4331e4db8360c2aaf920204e8e507490b5a901f90883a7a12448734605a6996602201279c304ac24c0d619a7039a8e1b1b3a8112ab23a62105334e6091a8854c920b3529a988a6080c71494162812a09122c3210d934f091f384d0d77c73c0a99f03443564c6855f2106e523a29a594ce3927a594d24929a5a212c783629ec71ac2e9dfa8b7aee64e3df79c576f130274a8872fdec27f7bbbc08485bf80090b3ffc0cc6f2153e0663c9c3bf609c0a9fc558eaf073c692876fc158be567047e1636ec2c2f05f47e1ab380abf82f02908df153eceec32e80b082f756fc0ace44e82d42be82b9658eae82c16088e390cf81e7c19df833afadea504fae63fc1b0e3e304a807abdf62e9a2af58a2eb5722ce7fa2b741182b0674ffbd8ceebf5147f7c4502c73f4f0b7f889a504baf75efd76f83e55470f45146a678d13a01e80ef89a58b0eba1e1471bea31a67fc6048e1e58d02f4fb1cfd9658d6a2cec5135c48755aa34f3a96aab53cdea854bdbe8e0de8ca0b6fb56a2c90c562ad2a0ec769f1b0b562b142d13e8ec8378bc56271fedc86ad15c8024116eb2b4883c562b13e90f581ae50051c16e71febc1ff4056abc5f9fb58ceaadfeaabab55ad2c91eb6088c3398b87227f1cb1c55babd56ab55a7d2b90c5fac015ceafa042d6e2cfc356c80a71582bd68ac55aad56ac0f64ad3e10e77178785b5c74bd8be384add6ea592bd66a05d25e592bd68ab7be157231fc9087630b27e45d0540101e6ee5f0e77b61f53acff3bcef30ee76015eecdb75b1de9195c4f85f58189e780482cbef4895675531a8c2f7afc0fd3b6fb1c3c97bef4d690bec3e77bbfbd5efc711edbbc4d65323a395488d565f52a2911ab55adfa2e0ad1d27f8e1c7bf12a1a811893fd7ae133fbf9769ac56abd103f8f78a252ea092f871564f81985382c5e1c49c1238155cde4af41121870e59ebbb71f5f559e2ea2bd8802efcfc7677616b77df8d4e5aef635b22f854125323dcd1e886b851e5f12c08c3f3b13d9ccccebacef75db2a8f1d241e49ae249df0a360dd5bb57e1288b65bea110eb9d8ff5c41b5ff7722f69d7e306629dc5dfa776e057100638a2503b7f3c925c5f895c7ffa2d71569857bbca71de57c3c3093f667b5a1f3e088260ede1c08d58cfcf5f3ff0fc2577bdc82e5cffc71f7b3e7af569110c2fb9be376bac7904c30f5dbf820a59abf52d9cd0c7e28853e63a81f3c40bc2e81e479cb2187e9738657b855f87f4becc0faec0f7c0d56a7fce1b7c13bad7dd7bbf4513baf7c69c3dc6a07dbef72f29f8633e61fb31ffc95a8d63d979fa393eeaf8698742d58fb1fefa7da1e87a17ce07c2f0f658ae10da68b5eedd39bcfb8e658d0e7ea13865dbfb4ebcddedba0efcd52d2714b81a3db0acd1bb07c50dc47a59a39be07d37de8875ed7d19d39af3d7eb7f6ae3df6417ce7afe78f5187c4cfebf9e8bf3668d61e8af25bade8503c35ba177bf5be29863a395630fd124062ab21cad77d57ea04271cca160cc318d58d224cb11fe0a2a64ae6f0515329c7156039420f48d63769f3f14a7ac4523d6f7e3a07d03b1bec7b246bf11eb9a627af32a00d0789be36e70daf33c4ef49e8a3826f83ef57a0fd28f9b1facde7e969b9ce33c8ef3eed5747a4fbdfbe07bf6f3e8eac1fd6d4e7bf62fa7bb7af7e7794b1b844aeef9c1eef3f5475be2fd509c5d53d7534a690e1c972f96d8e8d03793622fc8d893af59717e56ef3d7c6feb43fc5d71863862a9bb37967cbf4b7fdc58ce1bd62b2fa97b2fba17f3be7b7cbfe7e9f7bef7bc7d7fef172d0ac6f2e57a41862f5ef4f245dfaffb0467643c86ef7df7adc4dbf5473b7745d673d07371163a2efab6208cd54f105c79a0e77ddea8bb91ae686b4c93319d459f4a4d983aebfed557fce64efdf91be053e985aa5e9f4ed1672d53b01d07adeaf439fc93e299bf3e383f98f3b6be39959a4cd139d081f7a9d484aad3afcfa25713e67847149ab4a1f5fa3866b55e3c1cf4e7cfece1c84d9058bb7a2b70f53eb5d4fb27ebb553e8d1b0eaf03b11c7e49e3f276e60deba09e173efb5debbeb5e8ba5a7350883b6996ae1a86f5adf3fcb6aebfb675997f45dd5770f27f3a9df7b4a31dc98aafa56228aea3d55b64bfaa6efdaa56f9085052cdea77a6e662d34d997cefed96227bfb11d79e29cc6d0be634a336ee7df0665f00fff25ce1edb4f55493a1505df3ffb544222d56b2f6bd298de4365fbeb6d7692d32fba26bbfeaeb97efd5ce5c9e1b1e0f57f9567c5eb91e3388eac3c15fc579244e27aefd72359c91d95032f51b87dc5e32f69148b1c0b7ebfe8ae587791ddf5ddf5ea2ede5d3fab6bbfeb2798c1dc69b1f3e2ec95a9f2e871ebf7de637d2c100685e2200cfa54c9913ad513dc8ed82a130744bf4f509ee77dce5f6fc7c58e8be7c0c5cececef53ccff3bc5283d7b9b7a53fa703aa3c5bffed53c94852df397d7fa5559bed01ba47468ee8fb2b92cab3a4f600eda4a15adf5f8b6acf8c22692339eafb6995edb1b2fd1da7932a4f9941dfbf4b3aa6efdf2575eafbf753a7ca93392b5d6a53e5a1336efe155f4f98b1e263ff5af11e99f334868a264ebf7b154d54fc2aa92bb9ffa58453b0475ec9fd52c27d2c8da2529527e7f7f7bdfa8df3fbe99bdaf3b2fd15a8f64cd9fe0ee07c4ebf1e8c3036f818544518ce2575ee87bec1dfcf79eff5fdbeeffb3e17bff3b01d173b1cb878dd39e860031777e7eedc1d17238edc37780ec6146cdf60e4602229d6a44aeecfe004149451972a2900f1870302e0441c4e682f13c0cfb9e344009c38e74e37bb00c429a3417069ea9c88834eb07b9f1a55c9fd9d48a72ab9ff8a94aa92fb0520d22a0b93aae47edde25ebf06dfe2035b4a85cd2a4b5d9a9e661819a3e5c74dc74135ecbdf71e01aaaac2e64cd3b8ed85e48948a3d808628e5ecc262b629a8430e2490d125b9a96e82d63dcb440857e70b4468c0f5b76bc2942864b3044638c318611c6696f8c31aee11ac585b683140e9025ccb4a182540226333c09cda5a61d435a781282169e1cb1c46da162fa51017e8db748716649128efef08c80f01777711e46484bce3967194d20b1b0c919e1c3105e02b262cf2c9989ba41353614904c52445104c3945a18126c6123c54792eca4c5461bf2b37715ff7122f223c622a1a4a6889604638c4560a2cac2a6662ac31454b1bcd853e5ab6f4eefedf5bdf7de54153683de68205e7b0dfd920a9b307a1455d8c42f3a80c18c97216b82fcf0862b02cd952a6c7ad08047fcd58e31c6980d5285cd24cd54619bcdadc2662f5f7d6f9b44c76ea03a56724366a846618bdd4a54be78f66b4a6d7d2a4131ea59072232241d01e5079b28b24cc4d0678548a8eb7e7ace3f1dd59310206183b204872170121349bace084f49d7357156a028c95e2c1017db8f33453fb85084171e444e9ae0c20c09c55a53678e9c5ab60c35b1f0029a293780d122a4082b448fd7f9b7b01db02c0124042c1c197db15243579a320282f1c61b6f404a96a9265fcadc3044966f3d278de979cb1a37b60c88882da185c683054e001f784f016248c460d02425ebebfa1f8beea1603b9d41ff56100667394bbf0ea1449484525a6b138ee3b87b95889e281155e192a8a8717befada00c97e9585b8307dd6bede5eefd399f35c4c7decbcdce71b509d1adf2bc5ed46216887cf35455aad631757e6daaf42708b3e7365558fd273d864bbda8febee91503f58a6b16d85aaf5f826055743ade5b016ab38e8bcc0f864c04d0e9011db2f303fcf53d9a450b546175b4b31d1c2fb1e1218c048ffaf38886e008b0837337ee51d795a42020400fbc524e8f3abd477d82f6a8fb540a78ac1e7cc5acf7ef28458e8dfddd7775bf0e598e8d6e5c41856c8f36d0d721abd3963509927ebf7295b4138a0317a815b0b5d63c4bdd80fad4a2c999e3083afa7c159ecc9f321b9e66dda336e905a2c9d94ad541a83de14d498954a7559c2701f592ec7409512f0bc0535a5a7f5379b8a57a81115e914cda9a5fd62adb53a3aa206082a24aceae01db539fd67f52ebacdbb47853a703291cd75aabfe4cbf9e73075238ee400ac77d762085e77941155ed623fb765679802ccdda2acf50b5327bb8230bb3ffcd0f3657a60a2a8d93999b182612247de99643d2923fe73c9e4061641ecac3bd051bd03180fbea7197c7579f9f7bb1e05ef5a80329fc4af99278451aeb5125ed13f129abb17a50ac5516665f8b95aa1ecd1dfbdc91eda951266c469511034502a72f372d4c56bafdba03529dba48bafd8ba4f22c29aa3cfaedd47354758a7b43ab806aaddb2278598fbafdb23275bb7afb15c9f6806fbf2679d5c7eca113469b1fd0bd69a5adb0345e56daacb3fa19a8d7c7b4ca8d2b11fcee91a7c63b41a7b4b73eeb539c1dcf7aedb37b49955cba20899735c9ce2802f8d3b74995673e7dbb547be854f89607a5f727edc93f29a5ab67b99e7e65b23d384fed5285d10fc7d276e9948b76463da05f67b6c7f2a030fa94359616a9531dc0b1b423e8f4bfb1ac47de585a1aaad11e4bdba4d3d7635989f2585a17ee585a229d52981d4bfba36b6a932e708197352a69667beaacc2e6539ab6d11b5ec3c29832514f509d52a7da25aa97af790beb25e27d80d73e955c58c223c06dda30588ec2602962e3cdecc5638c294c528766c22aac4bb23d9d9385d5cad3455532cce4e99a98647da72427db73bdcc229c3acb3e53bf37caa3ae8eaa3c17a9925c8766f6dcae4daf7f75b063c5d7ea7091e845ba48310cfa8ee250b837bb6bf2d3bf368f52ca3da5f869e74d166bef09d0ecbe5c4da1dba7ba82a0dba7baeba4e4916eafcb52eec518634c01fc02c7e92bb4f941ee93766db6471bc0fedd31790630c98adf1ee0ed48bba48ecb24eb9797c8f67448d7c7e4e99884e023b6e722591853e5c1b48ecbe4c142934442b23d5d9909ab5fd1f4faa5c6b4ee664b161dbb9ba5d4720e743a8377fa611a0567e84e31adf2cc49d2af94cee03ac542668fc6471e74d22207bce2c60aa306d01e45dc2d3873e0944e8a7441c734fb7a611ae6fe3b6b478759b3b2bbd1b983adcd9875bb81526aef9c734eeefae8b3e7fa9830adb3b596e7fa98640b2ad65a7b6d13afeefb544a65def1d2acb5d33e9d77367766dd4f5a4cb15c8b29f339eef5e25c6b7aefbd39449cbee5b87b4147eaf35a6a9f5210dcee51e79ee7708ffa7c3b764194524ae9cc52269cda25b87b83eec5e106d191e2c08d73ee70d65a8b4410479f8917172970ef0bb72e5dcb71341a85a3511be58e74ee5c2d347ac1d4f5ce2817254aa7630e0c9cd6a3f90106f3ce2aebe85aeee7732f8f054ae957c9178dda39db19959d510c0cfaca69eed4e750387d8fab74764673a7febd53cf1e1693003ef0f2125da2ca53d419f1e02c70faf55a5a579d5167d419b18e381a28a51c476905b99fd3ceba7272dfa7d212a8ec8e3954905d9bad75062356f853c70b45db3dfa8522d7bd19869fc552855acf8f2352b085136e9f8584570fbed41d7cc9777ebaf85273f025df00003a1ab40880477a30cfdabcffc46ffcecf713d4956785052f16ebe8d539ef7cf2f05b5f6f61f81edcc2efe016fece48c74c5818be8b193e07e16f609bb070860fb3cdf049db0c3f00b6197e0b6b9be16b606d337c9db18c3df5f00130962f80262cfcf0c75b1308638ccd1c55d8444ada32cc30ededa6ffbcb14a5c68d52a2e3522ce54c081921f6bb0d4209444c8fdf191a4262134c49281a9c2e60d860c4efa628cf19526523ac6242822a281e887500c97479accc350125bc570098292aa008c143055c02c1911c3123ac2915350c617638cf197a28e31c6180b69ca39e759adc2e6909e315bc25f51685a1047a46e89aac2ddaa30422b261b9c202002274830c8e0449829ee0e162e103f8ef01777718e874ed0fd88f07383ee114494001d868c647c31c6185f0952d431c6b8468450abb6d912c51426a4ce39e79ca59a2a6c3e8d910a418a0a9339e7a01ba4c78c31c618e79c73ce38e79c73eef145a79905d19bc50489854d8df10f3a15b350b3d90c864aa7fac4d204149d7a9d2d5dd02ea245e04b1927d87821a2c8963b6b43c5aafa89e1c9d7f91f9273d85396f8c95df6de7bebb0a4c266d113295542d06109c7b009a02859b2959e9862e801c492b958e39d8d1c55d8444a62bac530e2b4a17e68adb5d64fe81f410cdd278c31c6337e60da1b07c566888049cfc0c3b6cdf0d4e15a0e8ac2352c738b0faa302b7e9e7c9dff225214fc0411a180cc11192432499f73ce5989a7abc498ab84d45582ea4df0a42594c72c097131e49c739e42626153df5ad7e59c8942109b402459d8d44f95f6e4ebfc733ce89031c618e31c442dc8de7bef1fa30a9b4748494c23fcdc706c4b112edaba8031c63dbce918631ca4c98311a6dc5004cb9a26211edc146d767c3b18d99b08a19a85e93219e514817283f0b76d606f80600b24d10509342efc90d122c51331dc1f74890452f72e19d145087f7117e776c82e71e151e5028d31ab7950521536a942807ac35f510c310424e70064db5898a45ea7882692448fa1a322316c8132858a8537536e8e3cf93aff78e8b66507d14107310523882a5cabfdd423b800c1d084eb4a11aa9f5be3b151b83001a3e66f8c236e9a8885e55625087f7117e7b8b6267673ce99095285cd11982469fe83338773ce39671c948386c421319d71de37e79cab3855d8849a51254ad32841232033858d922e5038e91ba08acc608364f16c5a6ea0629b5a6ca0b2b5127e6062046ea072908205ee0441fba7822b4c8c02e0048a3053c84045197263c38aca9029c594a316923c51e5049baa2a2db0aacc30e408204a724083b444941b17a33654805ca142f4e4ebfc43d14247e5e88706258810e2862778f821e4e14b0b686c8582a20718920cc088cb0e188ccc36341d3dec1003458a8793241c38364b2cf8e0b4b4b1c59069b53b173084b613c524c60c1a1794da50910189aca9716b3e3559781009f1cf39e79cf30fb5fbc3102f00192b4c84b450b325e1d42c01c25fdcc57976b2e50711007102c91fcd66b32217499f4c225842c25d3cd810fef01777f1c999ac24ad8640189262176b9c31c618cd5085cd25454fa4541901cd527ea1a3e6880f486badb5ae6bcef4b003153261764863045093a1275fe72f00a64d15102e360c8d996a0aca4d408498e1b2c80014d5731eca72039adb65c684885110246a1033dac7f295164954dd99a58814d31291294236454154a0e8f1f444173436cc04d5100ba48c3e9673ce67de54d804aadd109c18fa9c99e09c73ce79f6f8dda5cac2a6be351c369b8c2fc618e3304015366b3b8430432f3a9566684c063a7e3461c30e4c9cf010c4893646865e370c646f2821fe96895b626b736a01b4aad9027cd09684d6f4087a414b144e41578b1448423c27292a6084642172c2e10c950f239cce38ef9b73ce4574a9b0d92442114ff795998060a2c65fdcc5276f13829ca58d0d4143c812d8701027e37664538253e616ab5e9c5e27c893aff36f95a859c01cb12df1a58acbf2e58d92bdf7de49552a6c2e75697a1a232523890a27bd19aae24d6e865ac641684f208e88f1310b3215e408291fbea22db60e98e4e0a44689251ace345134c3292a02c3de144869869f5d04d5020b6fc10070ac3405f5c8926ba042f23d4006344194a18a326485891d43b05e4a52bbe5fd0548164dad0b2ae6521b2a8aaff090a646c4accefa54f2416ad67f9218e129a98153f2319cc354ec669ca166b359909c73ce39e779a5cdade73cd57daabe0ad822359b8208881d4666a2e813ec20822543f9044a0c19c118e399a587a68ef10d5bf9e9f85d4344bc0e213339dc9c6ae801081da29ef012249673ce4f482c6cea5cc3f20485c3f2c56631c6184fa9aab0399b8144bb5553b3d94c48ce39e789c546eb3957753a332245a7543405d01014b19c733e32abb049b3dd194790fc90edc9d7f9671a53c3772404b69a962344b896731055cccec045c994a9bff8de7befbdf7de4b63aab07973828a9aca31685539bf48624449d011962233475c19212e999f179e08f122468b11646e43b7f0ae2102a766fbd9b62f40f636c10c31f4e8888c7ef01777716e6b5451b3d90c08c618cf2b4a48758ca36e103913c38f1e40587e8c298374af94e981c91015f7e05e679cc3a82a514b515d7854d3eb8170427e899fb9232937d93b96a03df93aff4cba9665c76dd78480b1a9b0b52d53f860c2057194df8ba10489854dade586b11891fac15fdcc5798daa9b518608071182d6272e2cf830a3b110a41f1968b6d96c3664d3fa54425a428b715c882c6c6a261873790b91ceb2c588080d374db0e9a18d9317922c9145cb9955962e4e465982a0dd294c827c0c3f89dd344916367518aafbf3e4ebfc3f55234fbecedb40e2855bd5134f88e008a704161990e0b6a8c162a496f1c57a573253163675d0ed02db0217234554ae9e73ced98c940a9b556e0866965e59e8079029ea0844b3208e83c4405d3a279636433d67a8be4208277e4c69117204164e4c11c7c388097f7117e7380d96aaa2d6951e7c0c71c3a960c89b4b92854d7d827cc3a089dbd663ec5299237a78a1618476a6523c55d81c23452582146f44980228c79098603d05b9f75edd612eff30d1749773ce415ab014bdc966d6d4780461b5112f5d6078692287a061472541ebbaf9e64a1311da88ae8b8ab23f765fc880126a7c3842ca06c5170e4a088721199058a1b929b2238935666c2e8c6c94583f5b9e0881f76302af078dcd941a5a8fbd340589fbf331175e550aaac266d416416aea55839cb03380d0b6c632cb526f7bef9b86a8d48b5989635a2a64230000000802d3160020300c08060442b1348fc338ed3d14800b659050664a2e248742410e03298661180641108461106308410618a6a454492000145cc4f1f5c5acd8677a00f47d7aa2bfe9581490966cb80a536ef0f5dc93f51788c7ffb28c22f55f7c6d68b8a7b681db8c8f8ba539e401d52bd96b7ff35198cdeafc4f13eb65a523ae8d31048f5a5112e2a3c06e53b28bfd76246aa452445322aaae0cd70acfe5d5218305725b227e7754979bfdf45162e3d76c410dcb302b1bdcb1ffd120847f7ee7502c4cb50ec073d93cc81df03e123562372519533e4f45fa99159edacfa47df528bc3515096b1ae98f7f8b8a2abbb077549e626674860ac0d1f5c2ac7fe351f4b86adbaa969c4a8e730ee0b5603920a92b2d3ba2fbd5218e79c3fef8c010529700452ef4094674dd75fea9e459f1e3036a85f71247cbd135693c11bf44da6a56edccc465d64a5b998a1f3534e1578fdac71b75f9f1d77b0024e0fef17ed73e205dd6d308faab382ae44a379a806267f40f61d133ac3185c614ecdea3af9ebe38e8205dbb4aecea2032f7946c8cf92f32d402a7ede3cc80fa394b0fec1d608feb8e85c5121beebcfd60800bc01e514a15c33412fef3410a002d0960cc90e5410ae0f880918487b67d42321beb3e1af8b4232612e89d1e56e25b306c5882875f11a65c12604b6360c0190d907605adbd1b9113003a30714d9b134c710a2f2f6eef2eed055f4ed311794cb762f0b48495dc744a08b2d833a5ec2e576b9c1857cb0db30fab18056d3d8f665257ae14c971b96394b93c01b04dd102e2a4a533be836ca441ee06d584aadabfca6db57beb12b07bab0b472eb7265033b2adf6c75237067c695e916ec2a8cf25c3e525f67005479386510b1fae51e8e23c45597b0fefbb49ee33636538dc884ffa7e2a46db441be4e0e002d75db7f5f85c990c47a477a768909d8ed7c1d7aa15080538127b76cb9dc85aa317a0a1c18ec21fd0324106b82b6ec9d170121f654e5f3d5f5998e89318297238f09ad95a2fa176971389d21962c46a85eb6b583bfed7b168747ae9f84da607e5c6204569e2471b7dad3494f2863b9c969e6bcfd6f99132a3c26b6b98b27b428ec70cb5d89d0ec59db2939011cfd8442de96904b2da2855851811f8f2162c135619675646eabeddec779158b2b8cd10d10841a13d9f1c15a3f01a0fed93759b4cc79bf863850ff213ab10442909f91ce48db6e60c579ac04fa915cca4e8ceffda425386053a95cf06e6a8dd71ea15207fb8ec1e9ab06b65e173e45a2ea4054c396f0fe95d7f0ac3684bfd7fc0166061d151700dbb890f26cc31a49f04117ca6b0182bcb949b35a944086765b2f0623d77072f10b46de2ccb0796c93ed6773ba2cdf05655777822539f309488576d3d80983c9a1db0923cf0c041e954d61850f5749babf566bc2a42bca5a915ffbe4f17a505588c984311fbd30bde360bda14b94a0f6b5715ec602a2bf64c1ea77952f1c8c44cdd7020e3febc425fced38feff9445bd84d347958b2b0be63156d5bec0c5af6b6c15f12e043b2c10e055946ed5d574a38a4f5fffe421fe79bd3b312ffa5278ef36dbe830a377e90e999fba1ec9350d7c59682f0d4d4017d8fa394cd8cac28d0b40a0006c6ba49e7878c0de92ab4fb9f0e9b716eb7b4aaed8959f2979d421c9975f6bac8e2b7ed29622aa99c5365864ec4e1dce6a3f052dc4690713531b0b9d3ff8a001ae846c6c48d4970016bbb079aed682b6177d24ab913243ff207d3910733c12da76ba4a7fb3aa79052296688f5844a31e15d3c0383cc3506d35196c8d16ba4b09a69646656d800e8e22476274d0c0dd8b4e769110d5f0aed94eb0398f44749bd0906bd3caf1e44e246e11753b7e3ff721fc2e05d4c223aac11b68aa7158af220af9f6d05c43d2500b4b426f1cde69951f1e91acee0b21857932413773f1dc5c8dc32cad148a8336d23aea8b6421e07840c587e52ac3041baf6dc98dd9e5247b5e819dbfd2921621b69722559efb945744a3529ccc8609aa46e560d116ec7055f9c23549e5e006bce60eccb620328516048716e6f54cab190162a22bc33a1d6d72be471e93163b7d3f7eaf6a604f9665697bd2fcf13303ffba588c6c5980e03498c180e9f29a63cedc90a6b1702bfbbfb5af3da10dc2f3316673f1237f1fab898ea92f1b7d711f0b74652df2564379105afdccbccf267771358f42d22f818676808e65b05973a2a15d27fd091a9a76841bd0fb67adcb342be0f2322bd7296d651c368c30b315fd8177c2f11391d51a4b900368345a102a94a8dcd58e550f6cee1a4177b793d230ef04058ee5babc6223a6931a57e1abbf22ab84b8e427e4352a952ae3c3bb325b97fba0f088737084d5742eaa9e5a36efd9c545a125526959d34b18119ab91bd59b72058e265261a3e51b2badcea2177efd978d3cc23549dfbc03471a3fe7b0f5f1958ac933e5d652011b6392cd41249d2f63ea75d9fe31c8aed70a1755b4a46f343b758bbde235a03ac4ffe58e361b789676d29fd0d84c9c23a5f49a5c0df8077edb4beb88610c0a4c4e9cc90cabcd0e1a14d2221ef71df60e668f3874b8ba669ee21d124711bbbbeab192a7bac54fb889ccde28419f2b394963f25a97e309cd422798c9b33418ed2813067c5e119cdd339a0fabb59ae94641887e689c43a3f16de572b9c6c7f7031ba1b4bc109c90ce980ef5f864c734a715e54f9c9036c446d016d0e1a16f610a974a4947ccb456044fd79bcf3f7d83acdbb73caa50bf600fe299f8dbdb3ecf58139ed8682807cb271326b04788f64d8c286428dd3950a7241047fa1c048048d7981a764fcce56d4cb8cfaa08eab1bbace4ebd9776d4f42a08fb1ad484c4726cf0deb6f7427caee5d7c004f9940e5ad384573bbc8510e8694f052a159347482c72a282c9e3cbce1705cb91850c6fcbfca7c0711ec57bcfa5af6719759f8ed1e8df861fca0c6b05224c491dd86fd49d28772dc6f4fa7fbccc1a0a6ecd7d60518bd8d6732c43399298cb01395bacd951a8cd806456c4e8086c4359328d1e0990cf512a28a3029624b43ebd1115eaca4f21a7b9842a9a80289f097dca19e9514aeea4617c7315cf223630072b4cb56343930b2145770c595080a20870b9c3c1bdf48492fde25ba8608015f459a987e14731466bda3f11cf750a1166494861633be59cff4878b42ab1f88f141b34307225288a1979058608a2f55b5b953b6470cf9bcdb5d32c3c6b8400d9fb5413df5d8c6cb36addb8aeca37cb5d719a5c9adfdead54f9b14b340511416487dedc755af3469f6591be5021f253038e204b940908d9e73f457dd6c127d76dde6d83559c367526d84b3d183fed52e2a877e7ea81180848ebf691b921c89f36812454c3c90a06c61744fc99ce31a81e18872d23bd22e1490f207f40e575a467aeaf1fec90a47ae159a2923575567c895181ba7eff1628dac31dde6d3e005c04f20b9be56203a0b8bb59de1e4c1c06d36c55fededd6d5da21b966d1a0c345e2b0dc38a6150e0b92a2538ae44333dc45456d8b22e3dc56f4871c20ef5db0c79478d4a8833978a42b5e1eb7749b960dd23a2bbc646ef0f178a70bd2ee4e3de8bc041b071c3d96b45df32a0b4109feb5f13023f70023ce1b861c7316d75d0f225bd0eb15af59f68f27b19a5b69bfe4989dd1e4e386bf09edc480bc284e62faa548d2207231c9bc3210a87f73846a641e6889c663a0493daaac742d3a68285d410da1519f440a8788a7e77e9a3dd35cf2cefe0be4aa2cbecdc7781187c18d3efc24563dbef10190470ab87961c6cf401040441ddee3cef718ef1054b133b48b4a3a3b16512051dc6a4b7bb1bfe78ed65d3f6b469305b2839f6772c8d621be5979342c53c0bc9507daf7470d98ad3a10f1d613a56e6b8de6a22296661abe95359619e4bbbf7791ac5217c34bb1a188e93a33749a83f35cc82bacc9908f46dfc008643249a923241e5cb4b274583e9649c10c60cef2b7aa79d0a06cb2cc95230ee28e31f33d64cb45a13dcf778210dc98188d09d490f0a60b6fb658aa6fe9184fd651941c069799f4e2fb7af2158e71565e3cedf5e8dab0224b4fe8102e1e31a184a0cd1d94c583f485816b265e4b421964ec835e79b63f802214341b0f9960a49ec14161f11ba27465c2e46a1596161c69783cd98cd2ea83703694a55b634d818a0a8422e3922c2588f765afdf637a3c97f243db741660a5a3a9929bb812966a78bea0fe324bb7f60b4c345813f61e09815dc93ca5f88292a9013bd0cda87917b2e69eb402cf73518eff8a93ba3a663233b28749e09bc8e63727e1140559786c5008aa5be33654190510f4e6990c8a08d8dc187fd741ab15987fbfa24c792632f01133fb29dfea5b866286c53420b1d2ccbab23c5457f730220f1e9fdb604e1793615d9b6518ab544f3d31dd939a4cf05514b1f29e49f79b7bb2c655bb9825bd9d98b1f3809cc87999980c44d0cfffa6d8082f7bacc4f734fdb2509160f1d366643a5556deb713c8d39eb899f5a69f75ce56ccba28e0cc2d1ab7120da15185ed84a93a28eebe3e99fccf60f65f3dd42459e31a95c4f384a0603aff91d3be37df9fa910b78e3b2049b7e23bcdfdd7f73e59ca88503d06d6c471ceefa2b4a6ef3550e34431523bf562837fefe8be66dfacacf1ae75d419d532f88858db7a1a357d564a0661a8fae818ebb8fbcb2e9278ed1321065d602eb82f50635fe83f421d3a841bad38c7f1b9d599b1ef65afa43b808ad07c0aa1043b327946994e9c4d7bc98ab41dc3e2b473e36724f94fdbd024d20a09a025dbdc2c54249e130ca4486673c632481e4f6b032420aaa7cc0a847c695d3502322688e2a422cc5a33d2aa1bda03a3c53cd206481b64102df4caf2932f17383197897e5c836d941a91385dd833c637b15d75445018fb035f3d00df9e59db60781f5240c68651359e315c5e1e65c65742c9e23543d4a2e8f50606257588cb9398caf7569d70ac9fd1b6c5fb939550d02d0cd700f3b1e507bd6dd459185d7d9e817d6c346ecadddbc0118265b6351b3e565b6b59ccc47d3501965c2a866572ecef491cd285c3159f6f11caa632a5230476cda523c29c5712b159e50be8076d0e631371320fe360dfad8225d5c0820dc6c72d5a81f58311527ad378a742c65805c33f0bb57a364a04ab29d84de9d7b0ee2daf1f5152131c8177eabc40a33a4789976c7876d52aef93edc575a2600b6f90290567345fb07fb5897fef3c865808afafa0eba3f6b9480a85747d97115998681f2e5153f7709ece09f3b5c355ac0a1882f07fb964d2531eaaa82eb427a6bd52804c6bdc1e475ff3c1b08067a0e2d0847a7138f736ca511499f501bb2dc1b2d230231a227eb8ca76d39a987ecad158bd9d010d5a51b1fd916a45e435118dd796be418648281c6762ca02521f58f32105c1a0feb77314eedb1e83865652d981374874420a042deba90932514ad2b706a5ffec4fb3a6fbf84159db945601d7f84c83dfcd8ffa854eb42185ee10e23fc9ff698ddaafbc365f0104f87ab53316c75960ca83582186c10569594ec52ba39e7d3428218812e31c6fbcb1e595ab268dc95a7a7c0067256abca9902aabe5532b825d490d1b8c08f7c821581aaecee613036c349b1fa54247648e13e9b3f9c0caa151e22bc411a13a8f4c92882ef5089324ac21b0d6a1e5ea381953a9ef174d3fb7ce662028e5a8f341a4d9af33e737658ffd8e86b03fd89ab29c6512cceedecb1e1703f6e2c51a49fc260288bafc976e19c161e4442495291df0e083e7cfe81c543dcac7d3af62f70b4e2b75443573f62a77cb1e87010d6b3cfdf4ddd9231819dffa9afab8a5e2d92f64ee9a743028f3317f6d29b74ca0d53571285d5494eb0b350979f20d20e4b46499c496a69b1b99d4607e92db7904c2ab05df4a4798fdb78a6b03ce26ced6290d4b625757ffeb1c0d339906d9d896989952c59119b8cbcc7b1a4a72dfe06ceacb09b94cf2d3a4973e181b18c49f94212a9b950c7e7992d94fc94ed67453369ead79a9200529d2c32fa1af88b4aeef4049f358b22dd17a2778f134dd8ecc8cd0a644684ab8517a0a89d60bfd2344f79d5b2f7b526a1caaeb0484cb5cb874b31d5768896864c9f6fa805085ba540a70c025e66e85ba4281c9bd5a340e956f3581bb0ac9e9649d23a6a17280f3369628e14376151853ca301a6445cd74e14dee6c65682cec5a1cdf362f527b35c768f486e5b4c9c9df3e3568db0d2a6d3707837a2ae78cc1c8647fe8c1b5e304db5251d7b2979c96ece6ca6a0d747d301675a4fb71712b98e0eb418307e597f9e3a28edca92b8a89f77a1011cee88999da98f8432c68c58aa4f1049856ebaa675dcda8e419c2315887a6c73342693ec9133ac9c0036271f35eab122715eb5bad3d17468771a21d74f9daed68a30d08e52f1e8800b5b85e569670813c093fb156d8ab074c5bd1fa45c118cc4a589500ba025d8973835f75748a5e2e17034aa50a36d4f781255262f5d8ecbcb7c1da674a9f6872cb23a601421a13af29d1708b61227d9228d9798013184111409b5b62bb1f60932c3bb15e7700dc3eb9dbf27248a8f8ed0a4d8149ff43b1d3ed7bf86497088d980587efdf6ffb561a3e66f3e06659a435bc5b455ca6ebbe05ff067c1988861d860caceb407a6562ab0da54a417e5ad55c6e0ae3f44d91bbc9877f623f211fe501e6c8f5572a777464474078c4cdcce73656170bc58598c87887aa7a05123c96937e3ca28ab39769dae38e3af4a5e36bfa0b2fac019160c95482758645af214163343f124206a5607b0c5a579823291992324fd4cec2effe45cd5486740b3e3650914989ce4ed27e586ca28fc0b600f53f6a1358fee1d97f6251e89549811a26ebdaae93fa16132aac6f1aa110314dd11475eadfe6605170be4431206b0ddc53008e1c11f87dc2a90698c8450dac600626802c1191314300fe29ab01c46213d085269733985fd7d40eac2788521fb5d627dd79652fcd884bb63b42d52047d212e30b773001f3065a5fde3c65572e90fa18ea654a870736c116e4185a194bc177c4e48da42c8e029874d4e39238b2c70e9fe148c6c1430305f7fc557b8f552037382e33c68121da15268ba01e0f86dfcc5a08e15952e27724fb949eabbca72e0a8500f4e6f3def9e378806e07e954c91eb9a0c6f91481d92c18c156bb95b313258a40fd138bc881afbc906815ced8de33609e367d5b6aa377f3f97a8737c0157a27bfc15c727445940bc7fe44358410bff3f9cc0e5cc95d6ece8952888f41199ef09096d9aea4671da7db0ec61fcb6e5b5488ab5b2c50a668b953f7009a9e8def04b79d2ca6066bc846ba43f11d83216f267a08f8ae1683d5dd596b0f756b37bb7bc98ae76e932aee5efdae819adeee36334a67517e4aac530dfed6a31596287f287872676c57a89894691c60a41afc099c83887bc90c8d72dcbb3b2c723e358156bcad4225ca954c715de43eaa84c8d302f33e4a9eec86318a2fa6bae0da6a1c59b8aa7623277681a8cd78b8c4d6e4b125701a3c98d5cdc83f0a1b41d8f47638b1d112bbe8317b19ba5316ba6376835014483d009d7dae6e0cf13b984a9d140fbc4a276a0a6a5afdb6535dddaec8f4dbaf8806d07cfbe135b43a110f23618cd115d3d9b8a8638cd752335ef086697c548094da524d40bc3aca36c9694f325377ed0d5626075544d7e34ddfa8e4f5099425470f99df2eff57590d9c00f1d9487e04c15827dc16b38fbd09701f1be5f5f1c73d9621d2df5ba47f0d6eeb60989cb3724286560ab80c92c865bce530785412f695f6df6b3771f7c7fabcd7f6d4d472949b1f50c6a74e7862432a49e9ad325cf99ade2f8a7683139135905551cf773bc1a7c7928e381027f38dbca8a5fb8dc3a9e576b4979e0eddbbe3cf867f97a1d2153a6a507114dec1db730eef84dfe66f824373a96da85bd728f8e261c3058bba8c43568fe18cfb0398489357910737b48a8a0aa9b9c4c6b70f3ffb81a368ee891f4862d500fa2f2122c08b53b4587d9a5854dcea0f8594ed58c385c46a8942e7631e138e4b9bfeaf7c718081d53cbf81b855b56229e2fb29b4ef08fb2a2b9bdaa1bb4b6f1105a3da5dfaac1708920a3722e668ad9be499d5e40685240950e6187799c99d76810f6c3369ff6e63262d67e030e8dd6e7f209d315371d8d5d21ba366028a7cc720cb2c9883aaacfb1b29f5e123c8ff496a578a4db060f9880f09d4ca7b8842bc73d30a85be39a4e7d11ec6afa46c438bc9b1b4118bcf2d1ad27ddbbe3196369bc10bd49901c427a82eecb766e6f840b71f04d1b88f7ba57ef4c2858d8f97248be5b918c357daac02e1f79aff2f4a06e783880fc4f2d29c08c5b286d3a62da19ff5269f3f049dec4514dc46dcd187191540737df54479cf4485a2f5c0fb7891091e9d0eea9843b710f866f511ac2789e815dd9cc7862ae35f3e2b4b26a5ea16082c99bae6117611e972f010127ba9162c9c06cde264e71155e47e697f404824d0c71ddd18c21c359bec9b16ddd7805bc8b05ac43ff4537a3de5136fca10d1226f7a6aa6ad4a17755f22fb672e7967082c8bd9c0380cbdc590d1753e849ad8bb8ee4d03524457afdea5a352f1dabd5d11fa0df0a57d9218bf9fb24784bec82f273ad8e1b498cfe6f70d94ccab3a7ceebe6ed60a4a19992dc38bf5add5b80a5ca20ccbed33ce140d03d2423a9cab858209350aacc00e434d654f3772867be118759556526b6be89b3a63c7a7a545385c0f0ae5d258fb3a5b2fbe32b2b7d4f40951b79bcaf4905122ce5ba3146969ff5ace88d6d60d3a0808333f225582e800edbc405716e7090c7deb05dac382ac4e82c66e4724f7a876c2167099c31b1e7587a1922bef0af7fd9443cb92742a071be9b678502584cb931e0e44de019cb1cb6bf07fbdbe53b235e00b0316c2fe249540731f684e9074aa07e15071b75133e779f1062f856b21d1dc2662616748323349f38bb6d4965d199ca7e2d71eec6caff402d5e43cead273e3912cb8650c748ce24d8c0409c47883f3da46026c4995b828cc8e0255f474a0b0e2894f6ed20afd2aa8607349fe1f7fc0ebf0184ba3f8988840afa2b202fb55dfc5797d7fdb005ecdfda5191ecc5c0b2489fa249a41bfe623b01991188eac13d6f320a836887fa091871d8f88bbeccdfa1dbc26e45edb88aad83a464405a5e976a7f11a9f4cef88e93cfa236879826a0e8186dcfdc67cd33d05ca56b45252288523bf35fca50ada65a9f20e57eaa0e8a28b900b48dbdb323cc312eac053043682e235e6805a1d50de9b771065a8cf77e3d21a0522136467e0260c05fe4591882f08fcb46f11c87649843725ff536dcf788436792cb3b9a446fd9c02aa2b5773b4d7474ab7307e8836e157a17446c7692fded6dadec52a300cd95e214735a7675adac5aaee5dfec255dcd178dc9b890f8f0876264a9d840a1d7da44502ff19133a9e781a1ab6c17cd2800922ac4f7d251e21c9d43d9ad1e0261b7f0dee137cb5f57fc65a274bf8241c89e856e9f129434fc48f1c711d8449942d785a515c38df209bcf41fc665be73ab583c32d7f4b31ede1e19d41acf9f10d5e91fe9f624d733fc3a19cb3d2d59619290e94e1feaaa9b7c807027a973a0b8d6cdafdcb3625a5ab1b40825f92fe8a53a275e88110f2693df378875598bbd15a72045c50dc061cd41730263d1903cf2645f55f18a230e69618c0d90872ecd3489845ee286ce4f4829ead84f3261bffc6bf1be9efcd0fef090400d0c8a36caea68df0d88d4b37ba88ef7047fc8a47ec2b10a791d4dc9997d3e0bed6c780edf953e3099cf9274545e078cb5d6499f868d1cf0b665f69f276f87b5bd8b8ab93c3783278e0915612d39513e025582411a6f0030c8c6283dd69cb1df1ba539b309be5eddc9b90098c1567de59c4a4f0990d1a38774850213eff7f4e048010a2f56ba0ed3929cbb48cd57c2563fd50091cc3c13114e66acbce96d0d03f37e3076515b981d1c606ce395f832baf1ff43d57af47b0e0dbb60db3c598b5ff6b908f6d6ed61efa9995404825a342ad1da40c78947456f5c1cb1401db0828b2929a5d33a89b50ffeed9be412206edf52780baac3ab2c6d3d1a38f0c80978af9c44d53f1b0c27d3c330d26485737fc560035d34ee26af95ed91f4117611e1afbab95bbafdc5bbc4a5ab79220f8fd09f46fbbaa6e030d950fc9bf90e3b35a765c0b1919a64e7f701591902a0528980b718cc78b4241a5e25a761bd014ad8490429fde16e1a895d2b12c505e0051a13bf2b732dd4c6e9c01870266d1ea083792919ed879957533a1a7216b89d2b2e3600ccb688a24a16c7f392495148134f3d5078a7499934f15208a9c19facdc72f28aaa7a38c5297ab150f640be12b0a9fd1aa90a48f3926271f0dc5b46d028ac133b4fd88ce951843e405dc5150a77a339896a6eb12bbd318a43cf6f2efc2c275dd19d9de1747b8da94b9810fa41a7c62cb26c374b72357c013665f21b50576458f5a06dcd73a23cb7769195b0e38c24371fa8e69321c0beeeb6e5a3b7588591766a3562ada6f24f837b429032ee9176ec1ec5583c271c47634ff35b4cefacbaf940b7e31a7c7d3b4faeda2401b46c25fa2e3eaf3ae99a537ba3166ac4a68e7469a710e1130447a552122bc227eb78641b1cd1254be7956c264cf179cb1f2e7884fcd6c5a1e90a41ef2cca5862a5ead2efa0c43e4247163b6694cf1fbac73cc55c9debda94847b2ee3461c6170cf353fc64b5a6a77d22888dd16237a2ad23a9c5aaa1c7bef733b2efddc58b096d5659ef33b41cd47cffd79ac5daf0ad6ac1d70a8ad7b5c93e0ba2653e8082825af58806bcbe43f7138b2b93e618252c0cf3c85fe76a53f1522bb8ac153a3459c1844a130caad5856c4ff9ee09e2ef604b35fd3f6dc873948dd40f93ca41edd1626a3ac3420ce835a429b051cf6857f22b070ed90a05e3912f408b64f790f3c00dd3b9d86ddc0a8c82d0647e9efd10243afc288582c1e79aa7fe8c0d8a2f3c482a0f3fe0dd117113610ef0f81cb0f39a7a1f9e43a1f504a5c2dd1a261bff4a6025a426fd6e6b62db933b5b6473d558c53da96760b88e0adbd56fa0e98da85ebb07176fd7e2c7fc518b431ca5b25ff42c198b994c7a30f02f568f6b27412a3bff85d010cfafb42d81596f1821001c1b1ae5dc0452bfc9e14136cff29c57f94fc29dbf2c38178272f4b81be1d2c586671e63f761e43982e064d94cb79ce38cdbaeb87db35fa5b68224588c09d54b0f17a7eb6ef30b323810d7ecf30929907b42179c0a1826d1f678c54fe9a68641f989997412255f016317eb9123aad5e903095cb23884a7f9bf593fa57202abd01c59282a9a5759cf5f0712fa917fcd5168b97be8787a25f481e9f12d67e233de7bee99600bd0e316108d2e8ebba72c15a2d9b1994689eab0a21ac86930d340de12b439462215b92d29f05f59ae2cdda3509a866565e66ea5da096e2d76f918eaed266684eb7761bf782f80c2a32640260814b9a5c6d5ec5fde49f173d1252e54c767750d118d4a778152d76904167e95f781e6ae033042136632a40faab62f4d3ef31783914e6d9575e5432ba5404a1395e70c361bfeb3fa3f93d218bf51b59925b3d6e7b1019136c2a34f152f734e3ff896f93c443e34061db9ebea0b4eb3b1eadd916b63df842ec427c1297d9a29cfc3c54fcea36f79b88abf8f4556fbdb0e58dad5d23100ca50bcc8877be225baeb020d486409470f2c51becfc2a5042b640f79d0dc2bc04a3bd1578b27a471f1221c87c08de0883e1f60a9873929444d5c6cca3481732cc8946a83501783f9eb96b8c45d84022941808db8b135fe5ed5abb6eebdee1d609c2aa91aee045c4d59b9141c0d01d13d28c5500b76d6e67f90ed2593701c0f85a2852474ff0d13c8efa2658e4998421214378b3cf9dca22fa858821f189de812cf34ac5bc595662a16c725126634940bc494b994ca558318be04f63ba9d3886fe5aae44add493de1f11a0c05e01138d97590eda5257418591013176b735ceb6160991458425fdd1a28b747a3092aaca17844d445b71c5af25f6ce4487f02bbc71f96db7af99f63c1f0fa944d009115ad12c0192db328f1b222289634ce6535352c848455a9723d50de8dda51776b29630d0d96c6750c90f2de9548e27af9c3d3108bfc052d7961e98e609f784fa0708ca908cb72253383e0e015387e45af5865b1c4faeb69c49ccb5fd54b9ba307b01f67580be33164d157b9463c95a9935bae271ee01c6dde6d9928d406abd9f1b3759410ed3fc6cb8e89dc6fbbfc4795287311f8e2f2ee6bd1126ede90e41ad4a3f0da04c3e957c24c28b693749aff1ab218ab66d46cb168e442becde62a5000faac101c768a4eed28c9e57b01bbc97ceb6f1b2fba46469d01c6cb889956b374f2d0ae129db4ebb275edec2cb803ed113d088c3070fd5ee4503c895557ea554e37a0e46ae5526d5aa54a07f59bac03194e89c88bb4267cbffe442b169936768c43ad974269a7400b7cf6761650498e106d50b95001ecba8d5a89fae53c28a7744fa979a433950e10d243e282e2d98dd02ef6121ee010aa0e2faeffe085d9b813fcf39f144d80d7db5908848e951e8f1f14abab096ed187d76434b52674221714c43e3f6a855de037f5fef75d16b4a1c4943e1de9a5c37d43ce0d3f6a008ec4643729307e0a79822c9df08ec2e71959662a737b782098001388d7662b211fb80ddf4033c08c3bdae9e95d33c39a2ebee067a33c9fc6de9c7738336b9c4cd4f196f4ca8f5c496e730c6acfbce980be9a92e7790e53eccfd785ab7cb0a7b93f9aced503a66d3e3747ea432c33b88d923c8bdd884e5e6fee0f009ad4b8953ddca736e760b93d64d3971fdb9fadcb65b603d07af2a671107c9b957b6583a3410f04dbdc40d4a3fada90b6fa7ae4601e0f0a8ce008816371042619cf9f9df9131ea9ef8a07c8d1987994f81b869901356e77e6eb503edcb21acbffa425514606ddc471d198746f47a403ed25481afa12cc854ec5dbec02e0832eaf4d0ecd73d024eb7df1c62204f52a75ef557b36012b0fc191cc8a77cb319ee90f88e31e5e8bbb57644a3c2926a155f30c54f2a9d6f4a3d3796d605527f99ca408c79d2f0db6714fae9e2aa96474b61d5521e50197d6dba13b507973de61bc973f3d32adcb468f21832e930e266a71b3bc7da11c40a490459793c9f1ef56a4b87ccca436e9c6907cf2942f494420fb40756df2b25f6e854eb3fc971e8f16a9c2020f79f1ecf4987bd3bf05ed79e5ac06ae9a30701d14c54b09f65d68fd6b84a7e6285e1c77899f02169f9618af2b05266b38eff8692f7ce892bf70612fa2eecddafd94491d9c96a6aa3bb2263dc68e9f0a5569ba145e3d14b4024296bd5843c32fd46ea1b2be331fa5872ef525fd7050e1608488d8c1dd5ef35b3a30d91ee4692da05c1b76d8dc780dc844095e695dbbb78bbc78343006748154800879597eb52452e7da2846855e6a6ecbf7b05ef7bcc2bdc3d8048851a3207f6d8bde9f120428af4a1f13abca1fe427b2cbe1be8c344bd74bde366b95042e2f7d0c0e863b053c0c9f67c831b4ec711a616900a0017576a363c687d520bfd934be8a337f90f806cbff14ad9022049ce6d244e769a3b067ae285cb9f6dee0ca2949fe5f360c3386a735d27aefb4e31101c73151b1f3c639eb725fbb2565cb63bc8b4380db3dc9f601cda9a496499eaf55f88d23c735d70b727aed17fd3cfa83c2c368df544bd88580a2ae3931822a6c56a9082b2d94a5d1089af18c7cd4840ac189aa265590f0110c328bf970853abc92568a80404a8bb1207af3c5b819cd6f3760e38d2320a1b3e6948715b8e22eedf23334f80225a3bdd679c46c664e88217e3615ccd992764343870c08a4ec26e8e6a24fc2e14d1e9a4121e0e6c31ca15edd180ca52be8f6ecc8f5c881ba12ec5ed0260a52c2e7af3b15cb8072149d62241ac7026149a4398ef62bfb063a4a905b1cc7653e443a3333bccc81d4f73595e615e71f516c680116c3c2642d98b76f710f9be08d49e1d1a44e79fc51d88cca4e25e572385b571c91e9917b18921a263d82137a42a888c615ac097230be41613997c181167da7249abbb3072bf8fa49c277f90238b61dbc94e3932a9d1cfb35f51587fe6648ac847d94a194d71f0e4107cb096647e6d120cab11f07df345b410c4eaf93c484e602a0e551d111c84669354f49d7af2978e979b42981065e4bb49d0a1f3115191417021e141b1f66396310a26884884ab87dc124d2b40be5fee5fed0dcc248bdb49bebb9b7165336fe73f0c16994b24a6ade844df7184bf3c7931a8895e567bd4931c18882acba27ae5f29c8c54d317becf0d9e083aa3e2c3028f91306052e33e08aade03e71864451a57237b15aa6c63a42b32d181008af1eadf60d2a788eacf5e1f8f5e519e9c1da2bed8c88b37d3a033087e47059f060b41b4f1703a0839cd0b9c7c535ccb66ec014ade130438da545e9559b3a0fd205c2bc5cd3b4f37888670b8328d026b137e081b7992a9cde4228ee5b2c7c262e3a9a3c48c11000749e508cca15f3bfca860ab5d6272a93eccef9d27d34e81f77a999d17e04d8a340d8262c8e52a69c14b51684dab046c2d10f22f186b4a7be4e287c7866398c01d08568b808128b196b4cfdf5a50a519e89d665aeaa01f116132631710a69b18b52db21a6afc84d6b259a19a2adcb01313f51da8e52a64222a12c6d10fc5a67a4fc3741cd17eaf06697096743e29067966b788de258203209a8eb033f5922189acf0def82aa49c085982049ddc137adb121c47253a6067255c84c978933ceca7b8a9619e5f5bf951b9a20dfc4003ad09ea2585f1e1a7fffc2c40461c0b3bf22efaacca329214ed3fdd3c1140c843ec5c27f26ff15f291e6c6dceab5d2daa3aae8b4d77999c120d039a0f5a7db9db20570a4c76bad4cb4dbfc4c254f37d0890bab72f88997ac5b709270e582546be6fa5344674b668e3ccc20e31a5cd810cd13e4ccb053f6ca0fc0327e1e87440fd3198502359e635040674a0fe1fd456791b3ba0c2515a70caa0152587ee9e0e033a4b15a87cc313e2ddae6bee1b03fb6fd3b0f09a1a1613d912238ab9edcc30add23af84a5839e597087c28796073830c432f958f0ac92f3e79d0b75d9d3808b8ec25d94375b30250173aee472d1f433fb8097ca9190310fe15d5f95e3f8656b8c0fdc4e18b16350589ea34556a446e8f46cb127540ded72e39a8904e60b7b1901a48c03fcf060d9dcbb365460b6bb22a7de751bd1c57b1c1c8c4d3c6dd2eaba87e274df7319a8275f9ca8cabf57d4d42a0cc1b6c46eef8e86f66f125b35eadf8ef5f009818948b37b5e3786c8f8c4d3b61f088ecb623c91d4c1d063b548ec70ff93698ec40fb1b351edcc0abc2f9d9c231ea7859b4b703ffb1ba0d84767f9d59142643028de6589a61c81f9d9612a4b9fc0058a3a0ef4af08f4e1b267e4d09856a8080b5768b434cfd115f226799a599c3d292b9260c458692468beeca40da7742ab40de86390a70fd80d50ff690072e54c12dad1e7c01421f49bfdf93837db8502e015cead83c11513619db7ce8244b9c836d36e3725aa96acb14e0f2137ce2d9581437958c0722cecaa8be8e51a55f0ccb324c521e5a29aa73ded909f8ae2ba61b1a9114c2309ef1a86a3033685c5c855ff09cc2d8a3c8a18eb01b2ea275d4c339735dcee3d97293f50c47605f8b43270e42e56a3fa37894303cf4e500a8ca5bab2a0d1c3ed271a66cd663bd99c362bac00cbda72b0e87c11d2131528f91c281fdba0cfb100ef3a7f724a6eac92dcdd3b77975c315860af8a66396611291d8f0a4474679d75c454aa54f9eca62223c62618dab43b44d259395a73e02c8cd8807e26093558c10d6ad747fa082463f4ee98cc8b1130c6a759110f3f43f5635e64684e094b51a38b56ebd000efdf8535e3593cc04887d89b2ff9bb2df8f51f178f2fd520844c8023badb7703d622ba228cc2d6669746361c752bc23b80a1eabcb567d2b0c6abdfb748b8239b50b2fc946563f6c135d20d79a174c4cea6dd6d804a927900f1ffd3096b57b091200d00ca52934f3c0776587c9f83d8a905de1b90c02411f3f04a2c75a9d6562a800786afd1076934c412747ca8faa480a018da09c06be6343a242cdcb502663c48fb7559223be7c384b69dfea943208e5e6a241b51fe268248c7c8965e639dc2098bd28171da4b9424fba41e8e2d07bce483ec863e355a1c3eace14c58c10ee4dddc64a1ea1a9b430c831b324e16a7cae069d7b89106e2d37b4067a2b64a28ee15b4543755fac47e00a3c19a90639feaa0940a6a4206a1f868cba562757ed6b4ec01de866f88d07158b2b3e55bfad0b6f4494a678818e5e270b65f3796cb0c41ed9c8004eb13cd8c447b3333811c4bdc66eede360e6f662490ed04948f13554958a93002a8c27218d61f3b7766aea829244ef63a4e537220c5a02db087e9ed0b2735c402df274f43b7243f7b0b3767b317458b9721fb440856ec89437372902a36913e09975ac73cae56945fe5e68154ec0d0d41350c60bf25a5648bc8318fe5e651f0c90503cba7189860b361507b2d6dba6b8f957d8a62d31e38aa10eb95dde55a586db1c908cd316d9dc6da4cb02f101a00092f8cc4e2437ef332167d708451175afe9f414b599bd45c751ad33b432d0d30eb9a7caee0b4dd5905726c3741e323c7f48513f77ee4ea717554b4398010e17ab3b5a1c258df1157a1f64dcd5b81f877b62aa9137e59c591794f79ad02a6b6db127d138adbe3244d4a1603edc735e7d4848e578c883562dd6861881d3854af25b97b94c22bc03e4f56daf83cf50e2289db4b3a88bd4595ffc1349039cb6e74edb37bf3bfa19f89f1e7d7a12d59c3d137b59c1b0591823ca82f70c6c0ef7999547b4f25a253a2222b6b6dc8538067aad7b23864535888c3f07c23570ee4c166b51431ee47348e3bae6d7cddfbfde562d6aa524d2c09aa6dae8867cb706865d17f07ef29fcddc7e6b4fef0b52ab9b93cf8de14af0d80df470e5f1e9221f6b19e4fe70f7e163c6b982972759afaf64be7146f4b9dd1d3eaf152755607403913d0980a90291234b704c2c078c15f82388754ff6228f90a4bbb5ccebf9137068afa6efc90097b006f6f6c8a29f890d1048df750048b800491cdc8cd5370fd7ec369cead78045932a308e5eaba1c58371e6316a30fa1f313da0b95209252cd3368582f80e3b00041000f88048fde4beda159c613e6030f1b2f506d23d1dfef3a90c81a3af931d37db4dce2ec9af02ea4874d9513b81a086cc958b54e29010bd70bfa39240c0a15211838a94f31e103d380817e04d270de59c426bb82b1f303a53953480d22c0e53acb70df4388ecbaa626892af12cdcadb8f6d78bd5a7407db58b21511d0658745f6ad0e80840f3ad83a6f02b0dc8efff2bd3f1db664a758da63782c76ebcba36162c7607664a6cb16412acf7ca5c1a445e8cc6ff1395bb31f7463250633034dd2a2fe447f55c69811ace8b56763e6c88bce2f384a480e9c884cbd9bb0ba342bb5aef03f4cadb0576f7ad60fce87b7f5417d34829cb16ee7b914265f7bd694881f79bdd9fa84c307c52ad2804b87c728467f055e986386d8cac36d861e6ddcf8c1db922d5132254b0296e431d4140ba0d506c873a7dd838a448d8304711531bb32508cc1e938f5cedc037810b6fab436433d8e6c705cc298adcd1b2ba5e29998d6e6162ec11f290d9b0a7060d0f373dacbe367992bbd5426522a9aadc1f53dc884f36b44fc9a3cbeeb5e20a032549162d369fafdf8638593bf672383096d0ed0c61fa770c1408018f33d30e12f3ee1562360ab27e6ead08c5f8f0285144e03c086a02e0fdee50654ae935d97f5f7e1490b2bba10b22db7449cd51ffd794e8f813fa5cb6ae924ed8f5d6a41d72999a8477eac0e1fbf6ef382d5505db31284f4842864bc087fdccf693f24240038556366bfa0167e2829fa976dea3d59194a3e9b238694a400e5dad742414dcef6c83459725fb2e08e725bc29489f3a11e9d5cb7aab02e73d5ed0bdc9d5474e98325dbf29635d8f3b6a595998aa7421ce226220faa6793fc66b56164ad01e744f4ed000c28785e92821205c4f4db68bfcd2dbfe945a084e83a39ae513825b87380a365f5714ca9208e3fba00f40e1fee8414dbacdbad1c836463d87646438cdc1706b34bf5da10e25e9585a451f90265c381ad722cb3d09f430140fe9c34077500019bd2e1b1c3b7149019218b4607a551945e33ac509c150a7edf42dc0b80d9fb425f17812abd2d46df5955460f6acbc219a08921b3dd4ede1c5624da88294db4b7605f082ccfa8b298b10ae24be1c4e78f19edd466465bee2c6d5a4445ef790df1f29521d34f907b9d48c57f6ce82c91bcefc5c2a2d6e6a9e6f66b13a53063bb75a020f37fed04f0e81155991bbb6584a9c4a18eeda6d88c01cb5965e5a4434032ff7c9df0bc9b5dbdd16b57a1bf749381d17e8edbbea62380216cdfc6d5e6ba4ccf692cf9b420c25e104b414026cae1cf54ff13a2cbd4bf9b8b88731647c3bc9b9b688d72e208139594ac36f83ed2dee804c88df06bff5709b013af34edfa6483317d962741d7166f8f4161b370d4e92454b7b065bf9f73ed982f81e6b4843c6d62a2f5623eeaec53148f8e1abdd543d32cf5819701293eb29c3c2859c3467a30cf7dccddc24bafa1b6ae1b14221e20ed836f2377d0c2bbb9c3fc0d8cee131ebd901277202068b98e1e89888a01455066734243a76ecc15ffcb0eaba89129cc5c861be43ecc539b97d73e1ec898a4ee623f589be0b75e72ed67ddda6ddb7fe6c880e9eecab18d80a67335596dad9f0a68514f085042786992ef749de1ebef0071c6a857da30227cb446689cc4ffa23e15cefa8bb2f8a040ad3b1a2b1d675b611b4aab0deb2d24640506105edb8f6a3eb1d8f8319e68f638196c11d015099f5fff75774edb3900b152c8cd39629fab9f7a024d0849bbf8a8c53460a407cf714f73e8e5269f9b17bef455619efc620b6e0eec68496ee70217015822d16ee92c0ad1893746fe659d2f3ba7d0f73591f71594a966ffdf8bc922361b499e8d4677a85a51c8349eb7d3bba0290f5f581937299cc1be593a30b4387333bcb4003c9d31d14fe60d7b1fd59db58bdce62d690d7d9a1cc81d963b00212d3bdea37309cbb3bb6b7204c8a54a005fd5073859f591fe36a0bc398dc0ce16e3cecfc04be0e3ecdfcb07316dc484d62735a63c77f18298ca8c8cbae4064f768e0d77283213855ead0075e22dddc5100c2099d1f5b2e0817c4343e6e04a80ef18410f20c18f78296770c5e53bddf78f562e91f0a37e06b55c1c1c7027f2cea3a45781b4e5da097a40e83195b7b7dc8a1947d9bc430b66dae5618980ae11a7069eb26d8593c76ffdcc73d3c76e0f7cc56df32e05d6d4220c6ec5524587b3e70a726b69c2f402bc58c9b4646e5d08443a8966cdbe439d491e49277903ba4686bf5c65f50a369738492d6c351d085507cbffa3926015da181f1c68082988896a4ab0e691a82a8d7a4a4e4ad6b664a4d692e402b4d2c4538297c606013d1136edca4c645901a6ebc3eaa6aadba4a8aaaa8737392f3fa5e9f3561534bca77eec11378700f534c99f65c506b207e5cf85d2ece6f4922d73315a0bd092b50d2a38951befd976bd844a73be9dfd474fa7cad624d20c5925016de07b220de4e8d7d08a635b05810116f8519d17048e86cfc049bb5035d1a91a72f70408e89a8a58886480ef81e678b267ecd1d59e502b567e574157bdb8f0385fa284168f409625543ff536fed657dc955dbc60371e4bef0275ba6f55fc6db29db67e54c18d7bc4cff130300302b3c1644d58c831ed7eb9bcc89f45232d48ff877ab84176ecc5da6cc3606d7e033974306b47b22fde33f17e9c2147bc883c2eb39015c94a233c09b1ea814eda96e51c3707d43da7c757a222ffec34d7c01b5bf33d95037dc4033bc6b8b2d73de8790db9659f40ad74bbd0174aa727574b0a68adec9fc6564d1c478d6652a5889bb292f5e4dcf0c2e2ac499dc28b1f838e73b8f99ea0b3efd12046c795938f7cbc7ebe04d5ac4adf4bbf2498a3742ef7038289bc1a5515cc0d2ac54eea0e91aff090e31f646fceac42083b46cf2bfa7af3c1211146fd1987562c8ffdfb491e6a8193aa12e71a177b8f40b7c81399f8e80efe2f9b47a2d7cdeda16c0a1310bc2d3b2f45d9c6bb82db9a4d47c991b657f01d418a30e61f1efec955b5d4033419582d7e0a41f42c8c184fbb8746c06a3b0476af310f3ff0a872407d17a2f939a5946648900346303eee8eee293885f9c7f80b23bcaef5aa05faa87e0646b65c3590f62001d7990b118ce2ec6edf76034a3c3c3b3b293072383cd47f2cca0da7a28e978940306ddf833f3ca489e8de5d86adfd2b5f065048706394c3401fe77d69ab0f0ed1b6dc23f55c01bbe3e3f906672e33805c33b63c32d9f33454450cc546d98326333b626743c175ca30347c5a5293609dc498906b222211fa035a2222ca32b3679a1f847843546081df85cfebed718858759452a9c1ac518f4456c9db745277f8f63fc82e0503b5cde39e8266342ae9f5c68500acff458594779d7d2ca1480ba664b571bdaf62866d163aa2ca9d8b350908f148458e96f847072bc0eeb52ec0547cb3975f080467aab76caf7c983a3a1a3d6b2ffe73614b55437a01f705ca29e4c2eae81771c53e95ce6415b55f5c3d8f94435ededa5ab23e2ade3f1c9c6aac2ca01723de4c066c3fcb7bcd7da2b6c723acf5cfa38d0d7b1ffdaa9d2c8c3655f5cc8d4aa39768d4c3f34a0ddca9e98df163758790e3dbbcc627042034f95688201656651e11d9210797cdc28a88cec1b754658ca45cee421c3836f3d44e698673eea1111366a0ddb45301340aab3a591208045420e6cbbddd69d7ef2713213fc4f7e8694ecfc9c663845df46e15aa9dcdb2b9b91258e543ccf12c288e9f9291e2dccad994f56729e45643ba7bd2e76c33d17900a9d574906d66baa2d3823d288441a5a84f4e2dab902d6ecedad32ea9a7d204377783825181e5d38c90834f5c778b0b6495cc97862b96389480e556a3344d9280e40d1804844594393ee26d865ae2f36197a6e09b00be72b08c4f71bc2d372a96995d29e25f62caf78d3f754cda66da871d31c5f64eaefeb9735b34dc4654ebc0ed37d30746b91283040e9e47f5a68d72b2ba0964e890bce4118cc569b9e31c501568b4c211849e20801ef32c6411113f5da6e778207d73c0d5c01c2780d1e14393021da7c54925a0ca2ccd271d996566eb12b8073ed43b3a9ac761b4841bf7226a9c41ca0c7067626c28e139e801f81b0b6cd430772ac75c024272dc8d7635208166dfdfb262e8920507508adee94ed3c10a03530e39c2a71534f13c28685a9b2e0b83d8d5c074661e7d26af6c3939b771df5ead9ef9e650a039c8981af5815f50f27b17f1a1fe08d5dd45efb26bee6252911c4ffa8bef1382bf00864e3d3b174fa57fd0c5d72360fe74b56be05098dd9e7830dd76f70d309116f85dcb5ee172e871aab69b219b74360e6d0684bafbe52e3104333f4150884562185b983c3c046511235832cc1ca922f1d64f1d1c026cabd828031930a95219bb593dc7e3ce7e08d77bfb9019690f641fd2db115d0d832dd04ce7109deb548cdaaba424def333cf8a9a4d9dced2bafc5236cc82377b40c04bbfa7ca00cddeb8493851b7e27cb9de1ea2d26da382a7bc3d54e8a8a231374613c2c928e9fbde524677abdc7b6d82677893506227ad6dd7edabd627384e95c0e56ec5ec2c4278e01f445cdeafa2db586830cb666e44614be938c6b5ffeab87ff61b3a272062b844ae111ac2e6cd86cb8992c18540b59cae6f57588cbe34600d079b8a32c541c1128d0650822dc0071726696cdcf1bdc0c399b19bfcf2dd92906d5cc6d949045ac1e9ddb916000f1e228912021b28d7c129dffbdd02afb0b61797ba5aca603d83dc9d2fa074b021d8a5f3c05e22208261ae1b6311e7cf2e575c1eb17c4ff33c484800f2438a92f571b6207a29b962e8e3c58c3859beafccfdb4e1edb6ddbac22c184a161200f645ab435fde33ed86d22d5e27c6fc6907c5fe471eaf4d442d8cd7c099d79bba947b977288dce0effb2b845101aae2983156708e65753ab40f498a72929fc9824c545f13672fc6b5863fc09a5df3a7e862bf074b7c304d8ad6137fe399b736d0b39cad0df424f752d23650b21e0bf59ad7f235abfeb6d8eda7c1cd36584fb30bb0d0e44e916dfbcbfc020b03f502ad4d6badb5d6607345dc10d7dd30ec8ef8577eaa6f8646a55e2429351f717717d278733804becfe78ab821ae3b94bdbbbbbbc7ee88ff18b08af0a9d01ad1ac6b9822fa94d1a7903ea5f429a6fbffeb58a2a12affff9ffdec773a39040b9a6d694d2cef5f0677651050bdd5dd1daaa6be39b74da07a206e5455cc45d0c5c265455dbda8ad44071b094f37927854d32f171d7b5049aa6f5e369dfa44e529b2c401d782b4b4b63dced4ada496172cd90c4ea1bb3b2eaabe59ea552bc9e55880b48072f0dcdd999a3653d466aadafb88094b87e53c4e44114a9fa409ad9329453011d0047f20a3d575856401bea05b7a0098e668c94e2ce794055be3d9ecc819368bdfddddddab82ea9b8946e40e51a5dc3b031835a951d58ccd51b35435b55531f1002c0ac4a0f32b624dec18443912d91186688ca24440a39c3e789dfbf0bb45938c860fb0e27162815f526d79036cffffffc56f7d33ab6d2d484b6b5b1e8e569dfa2811b3b7cd6d3adbc6aa37c09e31b1a3140b6e527023800bacc024999f1466a209e0717beff6d6fa748f9d0e74038a817c472d9c329cde7befda507d73f1985c36496aceafaf2f9f1a3f391b28342e0682ae5f2e4a3a57546820e16cf6afe399eb5a85fa3434a8a1440d356a28526b764742a64254df6c44a2a828b70bff586bd01c1b039f667edc7bef7d0453df7c8b7d41a283e831baaf3e8711852185e115a3f6aedddd3d7adcdb6f23fb69a9413c35db55d76c78b17baa98d99cbd2901a894544c2aa598cde7ee3e2daa6f3e2651a64bde503af46a6532483eddae0569696d0b4b8b9270a4b4d61c42dfc85493b6e1939bcdba543c9e197dadc4ae881be2baf1278dac339b2be286b8ae0a4aa8e08a0a24d74dc33822581c2b399cfbffdf04eb7df8d7cda552c32a5c5c8b1fb20b2a6631f784da326ac1878aebb6e215b48d80366490524a8e8beb9bd94f71117a97a68bdaf5ff6f13d5206ca4ed7f4b05be7b1e6bb59aceb3110b5e4f77df48ac67d5edad42f3eeeedbb78b4c45e0183a62c63bfaf63782d099aa85049615a3539629cd1467ca33059a12f54b1396264e6d0e2390c9f9a03e8a767a689aa3e11fb140f3ffff248eea9b93cb260a09a71629f6863c57e5e3bd1f56da7b6f64527df3b2e97c424f9051dfc0dd7dc409adb54ec152df3c05bbc53e1295e06f205c7d30b8ffff38c5f5cd6cee1fce33c3f5cd7e3483ecc542c8d1837b86acba66e819977875aa2fd472ae23d1e9b06cf1082761d3cdfcffdf30d5372b3545e9939b2a91141c84ffff308f01563657d6d2767b43751b9c4127d1697422b5fbff2dbbddbb7615a6a7bef9370c01530471dd97b2fbd1810acabb2087844bd48197d813763640e3274091749f147999c0fc91bad2a5f4e07ce0c00fde744af20ab021b569ad7515527db392a9d454521565e42d484b6b5bff2f0a5b14b0ee926090b200e8b9e1ec304a45457d68fc8406007a89a20d4901d881707ae9e13aeefc64e9112b7b3724a3838c0d878b1e24b36548cb086d90c94af969a9b74c75d31d1e00b7a3466f018f898066448e4b6badf5ad4a7d33d614c40dec066225fe9196d682b4b4b695f9845cd775fe5aaa6f6e3a35085f4f374f9b3646349588a9e9c4f0d0e9a0ecc1dc38117376963b27ed23fae2e18188476c23bb71775f7153df1cfb82c49315c61ff9ff77f5fbd4231541387677af515bdfccc64bf1948a9a989cb0a508d751949c2d8df7ff0f77698021800d37c00cd1f5cdac6de981039c5658c1c51d61301a6697037228417272a06379636822e5c48b7e699292354de134e049aa8172b9eb7c1eb6a236ca5655eb6e9bd183092be7834503cad5ebe0e375cb1ebb652694ea9b99214c28c9340a0c4d77f85dbbbbbbd5d09395540537456a17980d2856b5cdbaeb46feffe19a0601e75add22739f50eff686eaf6de9b0798fae65bec0b124d7a18dddde19c550a4ad55619b38b9da2d35557dbbf0cc58d7d429fd1a7f4e9f5540b09732106e7b24a9f3228a355d824e8fa66d60dc1bdafb10b003086eb9bd95746edc7448f8a334bf374f85e078d106edd954b00f507ef88954d76d0cd3a8c0c9c9f38455720f14b711cf6806480f48e0ac6369a4eb1c06a89b318b7202dad6db93c66dddfdd7d17ab6ff60589c6103be48f046f0e128d274ba488bb3bac13f12b5c8f999f1ed197618bfacb350d254cff718ddc86ddde3d5c2dd6d99c98242e894da293f8dc22303b174a5e2f98bf79087449572216713b8367331f49433d3a32e828837084c21e3ede622436288edbcfa7ea1e29e0d552f2c452ea0791c5a17909bb85c561beb0601831cc18860c53c22d484b6b732b9461efbdf72642d53747a52644af5ace04a7e77bd7eeee8e4354df6c6491ed098e12c48d47d4a41be22daacc2506d569ad754d7d73aef71b168f499bbc145ddfccbac32331a68d92e78ab821ae1b1bb13e2dc2cd484f4a5a8b2bb813844206158a1b97979169415a5adb96c0a36b07d4910ca3095d82c587b73a32c68eb91d1f0d98b1b475f06393c2c666f22c854c3a29be70dc347974dae647a765e1fbc97cac4f8526792b8ae633c6828405cb028c66cbebbbbbbbf7620fb2f570eeee4e7223e9116f25ad58881896b2d80922132dfeb2181191ffffffcbfcffff7f8da109c4a924339e6bfcefc26ad75aebd75aeb9da2fae66372d9743edf6407ba59994f46830364d290a9e5b2efef45f5cdc7e4d2d571091933a7cadddd9d17c74a9a7a1eeb098839a08699a8aff1c933b9c23ddeb90b9fa6af98c76319a422047cd7eeeeeeeeeeee62c5f2833b0a492b668ab4286ca7872e706cb2173439eeee59b9f5cdec1a2fe522e853e8f4eeee70507d33d188543243c04a3e1c9665599665996ff37ff84a6bad35b2a7bef9372c1e4140267f64e8a9450b3f3c9b0533406f7d21a5994250c5b670d8eaa93d378497036ea47dd3746d04a32d2dc76feeee2b39f5cdbd9fc9ca70bb6ec4e2c4f9d820d962078ea0db12ae31ca41e5cc31942eeedba66c64303647dc90789cef011a5eb6d5d9d24cb4acf1d4030f18c2bdf7dec8a0fa66a211a9649620957c03f7382b6beb9bd91a3da11b5f39828e5f3aa8c2650775ffff9fa01ffeb5d05bd7b611b5e686c43bc519bb652f76c98bd629b7211ed1cebabbbbefe4d437f77ec3e2916427a979accbce40ce7ee2988dc6885a60a9f173b30e3bb70cbfbdf76619aa6f2e1e9301b0ce75bdbe68aa6f763e35082fa06ed6d78d0b272420289d6b415a5adbdae054145014d199a28699250777dddd8db76d8cb7d1b78d41d771203d113f61046cd56c4b31a9212f1bc160c650ae46315ab064ad3062394277748a77edeeee24b7dede502a782b8a0ed4639f6e28592afe6b9e8e313092d851a3868a28b40aa940d5bc09189d60d1f134e5ade81e1b0f5082e0081ed2dcd411f5ffcf7345dc10d76d6ac8fdffc31cf874093140e123f4d1555342540472812115d58e3112a99ebb4bcd0e1f47b71dac1756348fad0943c316a5a83ddd7d32f4664c8496614c3a6060c9b2b50043ef08b1b81e985ac996b6e63ac4f984aaf90ffbec7839255982dd4884621b1b242e3a1306c3920eb349c4b3daf0d2c61b51d90dac5d3eb95ac2ce18566e7d33fb2b86be762eecfbc76620ce609c0109022c8e50c1710304d228ae963c407daa2eee74541ed41e3ba22ce0ff7f727df3ff7f0cb3e400b3b41be9e086d4986e1946f6eeeedbb7cb7a559f330c91538cbd7041c1883003561334bdfab1a44f1ca132a463d58bf2e6256b0628e71793318c736e39b1ffffc312743ddd88efdadddd91788e1fdcdd7902e8648e62741a11f5d0c0c321da80e38c5fe8d5a2b5d6563ff5cdc3e2315962b514b6de234464816eed74ce55d4beb28a59aa20622ce378bab648baf9a145a3400c9085af3124e3c1ea42528960176ec4037022aa6f3622952038315de4ff63b4d65aeb7777ffffffb7c1c5764c96a313755099ae2ae754a5b8b4987c2e4b136d692debffff51ebff7f9c77c55218b2b162e9c6891c321f78f145f65c76e0b5202dad6d6302587e0b6b6bba0526bd49e3ffff7f9665599655c1b923da48c16a93048cc2b1a16ab10ce6b7be998db5d65af792ea9b974de7131a35e94985ef83c66a3a6e7bcb6493a35f7348c3126f6d693a65ef1b29450cc8f80130e57c188af0d6ffff3aa6fa66a5268da28bd27ab318e898b1d212450586a35988b142d5c0ffff5246f5cd48a506418ae9e26478ea095241369aa71d463cda440c345a645432847a46cc6b95d66a35e19a9bc05acc6bd9c6bff4c5923867d76dc6368dd2963e35904aa8f46c9e08e50014f31998040d0371280ce418e3061400070e8888c87468e0381e0804e290300c060442412018000480c16030181c0800e150326bf978007ecc1c439bcdb579f4ddb22aa2219d581ce6b8205eb04a0af55dc41b5218cb40237be5343fa500a58c387f0643eb08620753abcebfc05d14105b7ced075e454aa2b5dc89a2191f2e10f7e078f1ca4db72fe924efa56e8c4b1e092b5df28ffa87f6c6b2c0a4cecdcf3c02febf37a1796abe834ec1eca425dfe134a0383a878650b17a383a5bad599eedb2bfa2310aedea97028c2a77696d167f1b2e0516c79945925ac38e986e0507d3e098fbda2a9b72a3a1286c099e2189e7f2491e93e94fc76368f92df029385f9b2c5c763da187f0d3156f7d03d7e5edc61b3c2e187954b6ea4b5cde7e5347aafa44fbc63cc0db7a1641443bfa687bf1014411289e74dab42a10b5f75c8d83a4ce314ec5eb1937f38638584938755ffd375c2ef57d02500169f092e3b4e301e21840f03e395570a6cbdd7ba624f3eb06c09fcc12210bda7b7e85ee6a366368332557052d85364b61087e3e5cd048fc42138c4cf569b12c6f12fae10488a351e19f87228b9614c87fb86a8087d73328b9e6540d10794ab38e76a1aefe0f811eeb3d2e8f2a0a94dc69047328c44417e891071e2e796cae4b70a8def412b093056d10c4c1f501051e62d33a83ffe1016a01b20ccaa94e4afd9742a9e83fc862893a57d2c4a270ca3233d26bfe5640ab04020dce44ac54d4fc059760d89814abe8d0ae0bce31a80fe112ab1b632de2bf7877175a988dc3423f10173de33454cc54b7bde2a59d1021a3eadbbb30c8cd59f5e7a3b341533858f09f9e57d3bd3592ad6d019bbe910456508f6f47f9c1eeb64fc80ccb2919e422b8a928a38f2c94307d43b8956a26af0224d2c85fa8be93067e80d13a240449bae09a617a086f87ab236efd433815390066cd4dc8d1e7241617046d4ee3c00eb23d9322ae1b878124638c5b8ddba1c4fb1fa2503e2674468c9ade1335497e74db048952a2ce42ab7d4091973278b1b173abb9f9a307611d761f4f2102a9bd5469b6cbb1037ca407a092d47a79157910e7322f837ba7f25db036538e76d118ed5c0acf2f718510046fc9c575f757d68c25e3324c6c7a97ca6a687324b60fad72d4c629b4797385547a9d57c4537d584dc520b61608e5b739ba17061d3672f659365d3dde4822a4b10a2fba79a63e0d4fa6331a97ffc3c00fe81d25964a10f99531ebda1a366a1b98d852ca4b28d662c437e231a76472634facd946fbb8afd9fb52e7310129f98da2316e4fb30e61731f59299b4c1dc8c7cec7e7d9d3ff409113f7238f718a8903778a95704efbeaea53ab39fd0fc37b677ea9b5544d4a42feadb97bcf35ae40c4c3a32d5e7b2bd31b71f9976f13d723f56399a184b36be76d3fec3c498d60c4af634432ebba81dc99a882c1f0e77a52be34b510254bcbd9eb63252b6e0d7e4574a62d51fe34d340ff162d05a0a456a704c85879b4e61f3acf6a8bae6a59661921c8e6b1fbdedc06f1b1b455cdc4067e18a5f8c077875a2bf7be871ebe1ed3bbfe72f0fd46402b55bdf2396429105a8e0e1459705beb4742ef268527044babf053eb22e4ec511b5649ab8dcdfa8b669420da024d850817a5b24f4c0d346dde2f412107f5b191f91140dc09824cdd18483d7b0df8c3c70dec819a3cdc4603376187495639f65801300e8cd00ea8e5e136211d17f6006310bfe710002c91db4639fb88a704d4940b55a46af179206c614bf78ed6457ed3f8295575c9ece4d1aaeb0a18f8d3767302941e5aed1a778bd3b7efb1d27c973ce6c808c1b540aa3d6f3f4b17d1ddb2692dfb882697fcf6728b6f62b49eb2c22a5acbfc644b927f052cd8a5cc365a22c76c9a314ebc7d55e70aae315aa4530afe2cbe2668245dd5af01eac10ac709b51148dd6b6e6c97cfb37c21e9a016c102a1cd3707ed5a5ffcf61b6b7b43838cc520954966373ff65836447edd03855106b1f042bfd9bb2a5362bf26f2cbcd1f5b0a471f9647d7106d42bce9bb6493cf214d88d5f51711346dfa781ab183bcf12b6548e3d64882c8d8e568135699876e3fcf6e0a6a6bb28c93111c91d0f98e1239ca2f06d19f846eb271641d7c05883af3ad7d424381a8f8905e4e153456ea3cd2ffd8e6755da9a687b4e6f13a80f3fe559082aceaa16e4305a7b3d14fc35ee73705ab1c8b63763d2a6fa43321b131675123ca543eb9005714bce255c802200a7a41b5656190d24da920200d5699b9b6709c8aa62a1ea5b86dfc2a9abddf8f24d29e96d3e646c27240be3dadd8d6d1c762f28f59ceb1203a1e28d5062d6e7c1802d59a113d502d8507c38819188dd6e2f3f040dd190a820943b40d40effe8de5bacf4743e6cefcd35e03d935adbbc945a035878d4370bd8de552d6644d9edf4c4534175f6ef3104e6b30f9668a66d26fd434887612c3a2809d506cf2ca5c3aed3b72830053a9a0dc65c7a03fe324860ff36e006c8bf04dda145f2082ac03b570931ae03b098d4a7ef14816eb1a2a96ab5e3825641d38e305035ac1022ba663cfe59102ac384db8093dc1f7e727a6912d133c45e33a1131be947c075db85fa38b95ae4596b1e91dd3a6fcad250fb051e338941420c9fd1b8d7640340aa5bf6d9e03983d3b2bdd2789714f4df6001f0a43b3d579b03882407a03a7bfa4ad41d2f83ad15ad231e4907bb93bb7a18ea02e44f0f3982adf6444a2af453c032741fa8d7ae61b0d7c36f1ed2c2e65778e6fadcb17f80842be8b0c5e8ec942def2cb49d6e170c4b1fb1f4e74e8ed5ad047706391d9e9b461d1e60a62a3ee3854aacf9c29348a920350ccccf7cbb33e01038f98e6d0ba1e178c866f39cc27fcee7fc0655b98592bab48d7f811426a99b1c121aadb55858c3c401ebb278cb6e95ebac4c6bb2dc6643bcfe2aed104e9ac0cfe96ce95b56eacc185f27eff04274ba0297842d1d04fa04dfb1ca5304308b8c42b34dc40724ac41bd49fc3265adaba394a60aa8d71c163a257ee016e70cd714f2f9dc4d3be796192cf22cb290930f5689706655206789352d374a585378666634b04a946279265175b581a2e96ade44ced9550d4236cab62b28b1f626bed264e6768ed0cf07ef873133f6488c93edad42854788976c7705d299caf0f60fa6790f378828e43d5b071da24d3e6a6e44c891f7e8997fe04211dd8028fa4b09e2028b10568b8ea7bba237ceead691d31e5c97e52f0c3163d57ab58c541098be009797ca4e00a7ac1e9e2e08afe34657b0e345148099f1c28d936fb923dc77a43832c964aee807a267baad381651887a19feafec85c73f3638a8e3f182ff83bba669a4a73ad44656327b4d521422899e827191bc4b9ff2b6b269cbab5de885adaf83aa8e08459c634f682b6a84d46709281ba36b4f9a65ded307eb5b5dfd7043a56b2e16fe8655e973e3d40e3f08a89690fe45bc87711c1c9cb2a478550c18acf7f0568bb0865f501b54e8f1ea07a6c7eb374e285e5a4141377b8924979aaf9dbe1867a4ba06e694a7c79e1c644bfe16ec7bd008c959f614f9cf9bd4893979380ba4b01765b7334a4ab57d7bce189aa0b81aa9ad38b04ce3f93665ba25ed8f32d2631906525482e8eb037e5ae76412988ce4e299a4d3482206aeb654052f2263e4fc7a6d659f20d1cc72dc7065df33c1e116b9925326d6e4b54eefd748348b43d3d1ae1947a767802c845e4655e84b525485eacdd8381cd6913638454c5d623f006d99ec1629b4579621e51d71c4aa7ac4b7dd215302c12ad0a0273d7b0923e90127c28c93d35cbd7bfd65c2012b4668ad9cda92c498fd98040566b6e159dda5465f6d9adbd076909b7506782fb007fc3bf27b5b8799d8acb606f6fd47563fa7eb0534ace2fefa1001d484baa1321cc266d360557fd2159844d056aa2ad1a69f0e55658c92570abb6a7287cc3dbb88e714a194e8171256c6b37e5fa0a3a1a70811ad6bee4a1e8e68ab09f1064c428c5dcb98cd1b7a14a76f3005cb67042a99bc9340bd9dc01e300a2677eb27b1890ce48afd02e333ab49fe921c55486a750736ae158c2c95d0ac381cd0ef1ba245a2aac7506a5f7c6b2b770b1c0335ec3d29af73d3c509c9475715b3b9edbc9e234c3b31eded60e21e60316a7e4371e53fcf1dcc601851544e6272f6dfe484f23b4a4e045a117ac962c80a2d044747f682337c51fef2ae9766d1f50f9e7c42ab475bdaf9ee4ba75f21dc4bc27c2c3e99c09dd826530f240e0210690835115f75578681b8ef20ce684368a5584d808c434cf33a6e66608b710478bec4f3cb232d2859dcf85799725634f7dc2984c3631831aff6218fe034ea37a9b327ca1884208baef8b8b10655ede148d665c4dbfb8bd2d83167414662c409f317272a5127b774c9bcd4849ebdb571e5264711a1446bfbc3a49c3d0277612da1d22b29963030abc76c891655318db238fb89634c0990f5fe047ab2da16513d6c4c21d8dba5e63142b8e81345be26f1d5cd9b9ea1484e741f8700fba7352346e6060c2132f9a2664d56db2f98a391cdb5e32b72155612a235d7e71cc9d65ba049539b073aef48c313b2c213832d248534e6dca314d6f3ce90240aa1b2600249e850ed61c61b1e153e0b5eb7c7ba4b31e58c0ea7f64817f8b0e283a9b0ce5c599a1edf0918117d5ce5a1d7d58342a584dabc0819bd782ecfb7c2ed9d1228fb8691ed8782d56eddbde20cb6d97a46e09caa272d0e46f798918f5f241150b53b4a6986fd4353c608727eced89587e66fc11448a08a611120793f4452664fcb976696a9efd74f18b8206d0d3883f05d6a0302db1b4b1ee1ad1632336d27a721f6c1e18efdb5aa351b3e5e6539e56a0d4b883e8b948ed5f936d56fcd956fe71c08fdb1a25aef5c7eeae7d664e538251f6baf673d849fab8514e64e133e106ee7f8aaa03a6c47c4d1f17d6b0298e2b77cb29fba3927a87163d7bc2c0693700e962f364d5156a13f3ba3a868e26412ce9caeda4f09c437025abb792e996250922d53c5b2d0de4317ed96ae3725e98cc2b42223e4f067f3fea04291f3c66a8dc7e83fa1730593f0748dfd7457a743ccb9ad7edac2a2455a6e619404477bac5eb1385b6ccf5371d0e29718a8c4372549bd914c3f876c7513997b75da2599d158f388c1f77bdca954e49adb0cc753b2048cc7f714315cf214b81c8739497c49b750c7dd33bd6a282e69280c6f45e921ad2d3372aff5b1547808c23547e33ae6fbc0372c36fec6029c546f923cd737fc90065cc97100a3d007e39a23072d217728188f198f3afe4ada875674a52c842978041b5c2cb5ed77525629b4cc3159bd26f84e181ef29d533d3e24ecce8ed5ef399171fa357ec5de94220d3e0142243fb98d3f1f1542609a34b061cd1cb418ba71d166648a9563cafac0ac586171c643626eb3875c433571fe8137e61b74ad945f134e30673793a4d01418d3df26c89256a49f33401cdb660e652447fe103586331238f8ad7dc9f5963b6cc44fe9ec622e3f1f1740d9a9e4e076f136ea89b9b350fe275a695d7b37d8939f1e96285fc235e48e98c52c33a8096c5e03c447f1c81a6ccac42b6d9475963dccad0254c24cb916c97c2e0e15ab6a961d94a0b1c541f41c4fc171faa3893053c84a33b6b0ec25c532f703d8d1b400c377cfbf590540f0e4498fd800830be952f37f124d03a8d6c8b03910dac91d680cd40cf898d4a79c91d3a645fe9d60c64aa958bbde2f71c8e1971ca2210e1199f143882d4cb005d3c5cd1b1a65f5e8855e466b32dda216204e86391b2e6559137b17b388fdaf7feb3e1a001ca90aa1e1fa658856695aaac3020a686ac1ce494ec8d15a8f5bd3b272b8216394d0d9b5d5f8af8206b82306509f832e0c585ead66dec6df749b0c7eca105574472dec734983a1cc32993d05d0ae559d65a89c2b21629a90bbe508dda51f4dcdb2813470293f7409fdcd335b1cf8953c8de21f9887a483e69030e90c3d2d17c37dd0632fa1579b822d3ffde15f61f4868aafa7ce89b1944e9a212387bf47cea2103476522a66f5a7f5297129625c702705fc790b0b35ad5c3ba31e3e0972f82041e6791833b4e27b4d188642bad5ad127a46c96dc14785d27019785d97bd819063e8d75badf0a27ec30a016f1e514247d750c6bdd124fe3c0318889418425a6b15d2a989b38a270838f421120de66a6a78f5385a33beaf4ff13af909957f740fe31d071b403e7b27153a4b73438dd7b1a14d78459d6ac73b9560aef244deb0cea099c993490f2544a1e05337869fca053f16d395518dfc5349cbe7bd36d0abdfa0d4dc397c89f1637a2dde4ad83d15cb3c23dabde9ab69946f5a319779271892a52022d0a7454e78b61718b7b79d1646a5587fc36a99c562f6c817799b0e6bd42972a7a32b4a6cf73e50a63109f0270b75e699b3305f22e44aed0d7eeedc2310efbe542245912689fe43cfd95ca414336241339e0e5611556a56c0df0960412b74293b9ce780bf0f5511421c138a6c4f904c049fe2680dc6ba304beb9b4d1f89b93a3431072d0a92a1c739552de036b3ee30b69c9e031ea4c400f12c6d341dd01951a971c0a931e1cb33792468e8896f8acea7fb908337bdf8e3bec6b14e85cfdbedcc458bf6600031336a3e8683dbfe06edb37b80f19846e0adeab5403b83050aa4386be5039e94db5e62e9deb3cadecb9a64d03c9806d5c584b7d9a03731a527fe036f30483269aa051dde6c770cbd08067f1d81b480bb4497b63862e8898c236cb4510936cd2ccfcb4b3e50003603430020e36a4ab26aee0262e7158aefaf2c4b447cc16ce1a5d0d114943b2a4cdf60b8840834b6384b1a150b5a3c45cd9aaecaff8dfd0922005b844b7f610c5c1478c5373a6291e06673337bbff92396f638162e149f7adfa84dd8bd5fc2a51edd27924a9135a8e42baf1f31cb8ad293f9d5c61a849ef2be47907839c10fc435f55eee4e47156ddb9e6fdab77bd259623ceba59d14c98819c1501f30d5c5a6566db13424c0b41d48eacbb58a6d75b028f120d06e7196f21c9dd5f7e62e4d1a4725810cedc7b479344161c09e5fc9edd277a38d9c45f9d3faaf84ba75ea24b68848e35adf7fbb36efdc412109a042a1d744d9cf3afe09d1ee5f379ab36fdd0c3f4f3c00ffdc7e7632ba3115dc637a001b4c631e9c2313a62eb9f9db79e6da229668867f0467556d02ac4df488275faa2bf50e73920d46c5a301d6ab508d0c3844e1fa12ce26c8fc7398885983e1aec2ce91a9ff4d79c52746896c316016d5945a107307b80553411e52e15d22f9adfe2819006aa85d8fdd1d7348e8fa541cb8e2605f0d903e9467f2c9f9d8be2214d4a4a6a2ab647d1b1b6382741c71c9fb7c7be066dad42cb68998feb50c44fd9536f45cee8197192a59c87b130941b38e07ad5cafddaca1b0eb5017fc0e7195a88d679eea0e04f9745d31073058c73992aa956a2c8c4d06f055297d4ff090f98c47a981aa1973801e19fa164b378c05e5708147fc502462d1aa0f752e3b95d65114ce2ce220d4e0fb4637835b217a34d9a6be536bd1cd4839defb0da4cac08c98d49a117685cb9494b74caea90260e05e95eff663a3ed2f249dcc61449f545b397a8b6e88022417e0d279383ba937e707a7d139cd3c9e0402bb5536d18b43bcadf75ceb4449f785c1e9c76a72bcf3c7dabb856435352c470d45c5abff838d1c115e621128e799d5b015474b88b2b646c5507a9833ea3d585689de582edbe6d8e1ea16e94cd6f171ec961286cc8b202f2359eedb94c90b49840a666c25df5cea04c23ccc106646a66084ef8bbed85e0a4b65a3170bd80c23591eefef70537ba023d4e7bd475e95e0ae01f993d384d36b424e77b1ca683449ce55183d114cf0a5a2302080ad9a0c64680be41741905f103c92a5b87f2add2aa71ca8319ac93c094f54b86ded82a4059f55edb04b850ab036d328fe7e9826e440ee22872406790e50fd28a4d9d51a9af681b6fe69ae595c1c97e077425425d8a76d2b248e7a8f002868d2d8b1de7299733837508c7111c0a150044b2f1407c4a09ea8fade288d1930fefb7e3abdf3d80934a3b1883e2c19805e116ad506a6012284883408758034490b9cabc410ac812c1100dd87024be46a031bf83edb2398fcc58cf02a077b07be5feda2cc206700899926731abd95872980e7f36b52a370c2ad9142f4a64139859cb7031226ae288926450e678250115814698ce4ece839125e5e32889da946f24e06bcbb27d39b7589208da63bd47ace879b6f2245d2ca7ae186265b3f9bf91aab440014a015e0c09af3dc639866067b7b6c1169d6e0cc63918e8288c88dd19127c865c340e223c9bdb30ba03a4eea229a51a62be35bfd6ee5fa1b021dc369bfbd1e71eeb82691fe38477424920763d8be4e6a19237bcfa6f3228119d73c973d5e4fde2bb972e7de4a51ee27e620894a479ee350f05c6cb0dd931bd9b75c60660b65d903924aeec5d51c7397ff571e4f59cd14c2b35cd3d341b0bdf79f06b354cfd44e5e9f116a646c06d3f577a747cd945cabd16f491eecf6af0bd48b6643c485a34bf1764612b3f9a97fb8825e4fd921efd16391374a083c8b0ffb4ef64161ead6684901278817f467f18210da480aa7925c039f8a2cc7a81afcb75b5b5dc747d3ed681d4b55029a25376667f9d44f6f22a155342baa764595e21960aa04cee7f3df0c50d9fd53b5a58406d8981589dad7184002fb8fdf5a8e35a1e8d386d7bc841dca238abe4342613c0ce28db32e3c40d807447fa484106cf8b244531b00602d8b48923e0825d6db061e92493004ca88e5c56a39911d316c02b2e8fba525bc9a05053f42ac4ae481de82504c0281abb85a171ff362d6bf5d0d62b0190eabc8e39c117b9af5891c98ca1e9da879225f81a9ce96d6847cf4a4d1a3c8f0c3d11d5b0e539e45864dc58fd406c6903e578baec9a89a44765cd6e45b14b7c6cac13a72428a7c78b430bdfd8c0fc2b88c88f144b832b589d541808adf6a21cdab0be327546e1eb249681961a2cfdfed236557d6cdbdcce58da5614f41458f421371b47b6d268bd25ee58cb6d34e807641ac8339bb1689a62004d30decf6b7851a94cac0a3d124f30ba7003aeed29ddef00f82ddc2ee6588dd9e1b1f96f9f75ea06d6f6465a1e4f5321ec9acdea72c5266a9f59adb5ecfc031f4b1ffc58d3c9026e29d07260cb4049c760aa4dbc51c8f6d832366ec7f6b4b6ce95b37a2cdb30c8725e4fabb5beb9825aa68fc03684cd241a585a88cc4f8588fffec5faad031ae6693246b2f70dae97d7b9581d593a5b683ce0c262e1d224dc5058a737c1a24360f75770586dad22255c559aebf76e8156c1aa901539c2fc0054d511702fbc3572a445ab5edd116c11f3f9c96557f54644c0d66494d587f23e14c76ada816ce316f27e132891f51887b44b41ca5049978f60dc133a9ea7598cb633873c09ba51254ba313b53385711afcb0836de736e59579573c9b7aa2570c58a6676c6d7df767b0d0065f30b476b115e2bda6f4c95a8e99e79b80bc3a93cd8b3eb4989192418a7211c1cbcf2a0786190674016f8fb00b92cb2d17dc52421b6d2a52af7c8b3658ae8eae2a65752451f5eea46e3c6552a7e9c1275466de0e70b440fdccf8515613bcc80ef5af9edc6765fe70ba8cc9cc88ee06f61c0579b543cf3dd384553ec748ed02263156bd57b01842ba4cfc08b14864eec0ecdd441a192804a39a3f20c82cc2d51b269fa02b8af2974bb7349c4fc480ba794c1bdefd7f10063a5d3244279bb988f1285ec3094c3fbefa0c5bc9b024b5025063176670edc4e5dc0bb44662c2cbcd55ba0a51012447d3e86a6f498a56c21dfa429a12efb09865f06df8f038f8be9af855af6db89ae78ed3931bc6976bbec4c55d470216fad2f6a09e09e4e592792dd07cb4b970104953f24f956dc320f350cdc32196487c605508fe1a1097c6d76892ab79bb6d8523ee0577d334137b1eef821c977b3c78140e2d85013aa30e6efb79c2f3ae1113929f0d1b56dda226ef43b3bf9542ad4ccc10374d7c5e90e91065b3d0a453140273ca2c90a8aed1f6a963ea87ba0351a08fb2f44829225b287ca11d1d5c837e441e2ada06b6324fcd9c5dcea8bc004727a48e87aaa19c1399545a224fde195bc80214ebe2f54353778da3078e165d8bf726a8e4bcf18dd2e8ba8f8de964c5b422b4e3966dafbc30a6cfad6e0689c5348bcdc858a4865cd743114336d60a8265cc31d92d15a62ba4f91c4c5cb140354b699114cd279b7582a43cedbe60a89a43bf38264ced48737728f942108593828482af3ca1f26034fee6a6485177f13dc548a3f8f240a1374e6afc2b7a5e2b4bd94d91a00160c26907682dc8406d5652adb8bbb481fe85994c9ff21fabd5fd49e21c3d1d741fd1570fe420347cd0bf4c6d22f4c82fa30f701581d0fb60eb1bd1fa17c473df6e4ed19ada68e0c5efea39814d783fe70101ccb0b85f812e9f5596ed7b8253605c5792fd8ffc3bc326e44b0d047c401cb4bc017a28e7c7bc63d790ce2ef356243ba69ea3ed018f24d3075b0d641bca696bf4567503b0948d5c4d94ae114eb927e913deeed182160918873ae99c3f2d4c9b6230e60ba2fd6c4edca2bbec40b8ca00a0e085839c6b2037504eef9c77b2e79e62f19d12ebc179618f3ed45bde8981f4a626f6370317d0d35dc462d15bc35db41bca6cad7efa465bf9a81c14dbedf29847a1cd05a75684956f74eb01aa37b9425e508a49a30eab46d71126c6a7313efd19913061ba07847b235e3e4e88c67591e33855cc68f90431b196583174658a63708c240008220002200900200808c31825052145b3a475cd9326b392d6c2d22a2ff25b93d77b0449db5ba6249394325904f3032f045cdf838085cfaa4bddff7f0b3a2a71c1e71920e98251c5246928054782e5b708b9500d0d493d54dea3cb0c92ac32614887c4fbfe302d3ef5367b1b68f991b32bf7de0b24acb749f40e80ac662dfa07806e01a3a8f5ffef4192073d4c3f11c4b87a7aa91bc0aea0df74814968d2e0e1f8d9df63e9691e126f89e7c493fac9a18667f882a84b88c631046a7d2149922467f8ea6d028346494c276640596981f5fcfffbf418efdf0e3c58f536b7c2f8099e317e62858fedf2c808f19a87efbdd7cae77eefbd426070f589876f74904e8290dc922449923288ea6d16212d39494d7d0732aafebf098ca9c34876fdffbf8a55bdcd6216178a2a5d28ae7417b7a2e7eeee7e7b4d9544c554feef62e8ed7629d8005a21872e8a4a7d656991a1d7fe65e536cdd84d251e19e68767242b0745481cec9664d89f1c46afae2fdd17efcbf705fc0a7e195d1243603076b6c9bc31c667e687247d58e2fb7aa6109167022ea89eb2dae0426bebbeffffbf0ca47a9b4b24036438cdbe0bae3e11f66d8ef7de7befffff7f0d8ce3b248bc233f20d3f7a27b94498e251f76d8efdf7befbd42a0ae7caf5b71a0ddffff172179f0b3f4fffff3ffcf63abde66980d788cd9a0878f09c2a72be2ae9c9535e52cff6ff8dce89541374cd8a2a5eb4b92233f3283871d6176b667e4ffffaf98fa365f44170d879a680df5064af06aa14425a84372a81e2a522afcf0d2c4032da27cc08df4c4b041841befdfcac4d4b739fe154d6f491351e6bb498c7e1eab5f5ae4c00537a3d5abb7f923da40ab6886bba084502faabc6c78111aeeffff7fd0a4faa2c1d7236a0292e4e9aec85ac1b5a2cbed7c127c629483ecc1605d25c93381a732592e9d4ed78356a63c957cf161c27141f31812f5c81afae2bf1001b8d098c19544c50716cf8f2f27315b570c106e365dd5dbc46ada2a9bc2cc70f77c066e8a118a294925f9f3f28379f93911894311872c1cb870e8d23d076378ff3dcd010b5c2ed4c3367c83f110d9db41aa005289d9b154030b583b1662ccb4803d54375d8251bc25514292d778e491aab7c93335f25495b351868c48546fb308a903e2d20a42841479a005312b9276aeaf90af2de2f12967654d59fe604a7c04ffbeffffbf922346f9bf01512f04e9b9c012036c7ac14aa90165005e8a3f3540f428e1e81bbea066622528fcff47c2d1ad1a61ca59af876df806e39f4fe6bb3e4b867a3908611bbec1580879a56749500d1706b59234127dfeff3f86effd6081801f4f760c591756305c507a4203c8510e1ccee4e20677e11564bf64512e55495946b8d4e0f581a5a00f3a61bd4da295a3d015b1d10ab1234245bbffff203d32c88f0c4244062922832091e4470dc9bf24c6ec85d1d2d01130bd2a5b25d8f0012212833ad90245076fc78f18620c89817f2ae9d5dbfc8d4465d1cc032548d876048b058e2cc5ac2c5a42969e8008afc01003110b8fe9c7d2d6122536d408428166ac7861b6c028d06b743282b89682c244a5cafbdcfbe28771fe9359d1f56d8e3fe5acac29cb1d0e06030fdfdc1eb6e11b8ca5048e2bbd364742b6af03ac1fab38a7f3cbd16c757c5587061541b15b9a4f2be3800eb07580b5daae75ce59c3f645a6d87d330786e99871bc42705ebec54c312cc72ad35a4e04db248aa9099196f97c40603098e7c4ceeb1ce7f5cd4270a4ccdddcb837e94e828f257cb973b14b4bf468d74af0ba84101541f1fde112ae6c803c874aaa72acce313b2ee1ab36fa4eadb5b66b1d74f63d0f1c241260a276adb826c3b51b56b371c00ca6c120cc609ada0829c41a568bd54098996d1bd8c00636a062758c5aec18b65875227c694eaba1c04639e21c0e875347d83a426669301c8b591acda2e5545c12f2cd72dab0c8529ec3272805e4397cd2e5f283b16f141740ab9c7d13c1e6145dcb4d3a0315d1d8715b3a031561b18fb3a412bbe082d98dabb56bad55576badb5d6da15d75a97544aebdc35dcb480b6920455313a2db0b6bbdb005cdddddd6d69770b2d43abd495227c002b25ceb959eefaca395ba696ae28296e5a299bb41a8f724e4c43e048d4113613285631bdd302da36dd33101463106e28a594769d976219adc9f4d21baa149bd3e6df6badb516ac46b5d65a6d5e3188eac23a73a54cfec050098e58c5f38646332d684c6d28b585c8ca8d71121800d4900731b7d414260d7bd490739338346a41eb1cf628e6c6354b720e04b679da0ac5dddd7d45f53691969ca4a6aa2e037c57f702657aca59595396f706dd7b2f96a47a9b4c1b6081f2d948f5f3ffff6f141444516c49dab9d57f8f78a5ea6d4e5509ddbbeb26de7dffff7f5edfe6f8ffdfa3a23748fdb0f58008d0c72b9a7256d694a5ac67c348a5687b312f2b8235624b564bc5a5ac25aea52e213a21bcfeff8f81556f732b458c30ff3b2c5f6a34f160eaa1a16406d59c32b24fffff77de778743212b050a5c6517a17b65be1ec6790d3ac583ed7abc7f49bff7de2fa29ff8b22a7d630f045652a5422afebfa0204b308b51f90383179157911792d792979397d4c5ddeba167f774939490f4ff8fc3a586f4b258113d0e21efe91101dedf58b7804ed8baef1fe2cae7aa573e960f6da128d8231fe6c3367c8371932e22556f73aaea8a4c5104cbe67816af2e16293f30d8c5e3b55258883fb8cae5a310ecab46a17befdddd7bef1554dfe658b4fbf2ffdf34a6dea6cf89157a636460707112bed0bdf70e21f66d8e5734bd7256d69465cf865aa4576ff3474432a0481116fa72dfff532431a5e881fadfc9764bf5369da4a6aaae50ecb02e09628c86bbbb7b540e191a394c5696c6143109ca91846a848a42638771f7a7bff0701f496a21b222c38910304945973292e4090c8cbbf7de17c07a9b41a3142f921cffffff93bb7b7755a6074dc2db498ea03cf45ca6becdf17f2e17a175f20161fd4c7119baefffff2f14e2e57ffb630b0625e64554d1d69799609504941047002265edfab6fc1b665f6ebc08d365384647b4e355b24bb9e539f471946772e45c894b18f1cfffff67dda19407ec7c5e909c80c971c5850e1838feffdf0acc05157777cfa105d8547424c9c0000390e730cacb5101ae8a3676316a0067f81419b4ecfeff9f0b8d91de1066a4e7eeee50becaceddddbf2cc58cf4dc2a4aced9421c111f0255414c925c8199b1647824240319a9140d80430b26a09f989f211d4ea29031ecf8ffff7f20bf3ff60a8a4673218943c4e4dcb4ca3dafba8754e13050ace7ffff0a16d8951a64fc5cb8bbbb0f1956d0055094d1084f0cdf5490e7b008950c803c8745a4720ee3c6296182514f86a04811f291f245a3257482631bbec198449409c4312a146fa0c1a3eca001c9c969e0f23def79ef46092be7306ebc81afbbfbd80e5b4a355eb470b72d58ec38b553c96727653be4390c72f594242be8f3f7ff0ab73029d5b8b63c87467e467a4627c480be7c294d3980d1c211e30b4a8e20a0ef852cc3af21158e7441f2a5eab564f998ed3fe498e75029f847ff3df80689f971ecfff747e6e23a219215c3758e8a1f528cac90c5c89413a91d225388d450a79002c0af223a23567e98bcf0e501098ce11c33e44a0c4641475c7afc49949328ab1e4d56b910249aba480d9b92e4ee1e3609c911e4396c227216b32c2d3e8e6df806e3ac1764bc0d6cd15a821185051d4a4e6e978f5a9471866f6253720ee36498bdffbb4d91a20b202a28f9f2216a0d814105656815c99caba1c973a834c649591c1edde8e0353c223201f733821e9074075f47f930a53d4cc155100c35940f443aca0c51354cfd21478b281d921a4a0d8ef6e003821f1d6589afe78b945c0c875c6532cf219115462c6a5e74140f4f5dc6d041224128508dd4532d4a08158b1d43c1ddce74e106f7d3655996351e9e72aec4bec2038f9e072732a2fcf36c392b6bca92ca7fcadbb13c874a5e9ee0fee7ffff9180e9915950422e45862f3c212e3ddfcfa96678600d2d563feef41f48c9e80e83e090bbf10c3793e73008973c93e75009c8580582136cb020e3f9f27324f1d061545499e7300a09d528fc27e5cd7318a5d5c14609cb731855cc396c6b866cc9dd3f8c0a66993c87512f74d5ac181ec108aa756f78b4cb398c836201ddd30d4850e00174a3c9025a859150cc0e0a9520aa17a67c3801a01b41865e90806424c1d9f8bb7f0ae20d136028066940d97126d9dd7de6f0118b10c3239fb2666834264b755f9c77dcc400a771fa0374a962779a456d1077afb94fdaeff718e0309813dbfe39d2cdafac58d52d4f631fe7acc16a393be79ce338ce398e739cd7f1949976c44eb378a4e56891e6e98e1fcfec343be79c53459e7f5d28d6b55fe6448d4d99ee5895b57f379d3d33b1117edac54deb5f6ea96ca2c61c97fbbb296e99138d6bfffcfd65d531a0223af6b348bb69fdab7536adcd6aa359fa4bfd035152e02b6d8d69cd75feb2a5098049999b184899c3188926310910c0535aa44c36c17c74e6a929e7687e309f5561e62937b6b400704d0b90b2066cce7da0f9e5c64efb00556d8d33e852561013e49a6e5ad038032ee507a80988b9590b15f0a606147b2d675598b590bb1641307705bc0c6a9415e72620e66e3c017102ab9a4e02a8dc13e40a8a36496cde64f0e4eeab2129478a1bcb4a10d886c3e1c086d6ae959132e7beead547fad896b78633c59370a8ca9cfb72e746a73a22e7bdecab237e75c463ebf693ea081b8ba72f79af8e98998e53831a9b1b00b9a1b64cacc7caf5f7330499894ab1b02896a340b188bc9ad9826235291bc3203a9501e162af91604377bcc693ed5cccb33b3e8e77e30e9d1758fc20d89d5bdbf5d0ec38ae3bb6cade6b735e60b1894abb52a6d8ce9c7d04c81144bd99d13ab082c4303c02ac661381710412c36aa5cc07a48a146c66fefbb5842362907204791e11e3cb944e1d982ecfbee55a2398b72a1bcb39656674b6a4445133516d5486a9b435779c9b756085e3c7235cfc359b083c1ef158ebc0ad957da3f86b29d87c3071b6e5d22b369b44e330d70c5747cc8a558b2eac595ce8c2ec5db5e84217de1fb15c0893388ad0e5d4a0dea92bbcc44b458b5d2ff112f3a8bbc24bbc442a3109747e3a3e1da00e30eb08757c3ac022b1594738edbdbe7706284ecef53b549e5c6ddf6dc5d6da766badf5b78d41ff9b707737515598a836fff69a5388d99a3362d99c502470335b99a675aa2b787b7b75aa4eb96ee5ea549ddaaf2e36a94ea53a3911709e448bf1ffe36ac3187bf5fe9a3392305b6f3792666bc596fe77775b776f5bbd7bc4c6ce194958acabad74a94e5cdb02e9102aa2620bb4c06c85340968813b5f2f53cc79b586001e272d1e6d2d2782b54953030194e895e095f095f0e512502578257c5cb15947e44290602be744a8311a146d6bdb0073c5df1264555bedffef6f1cb3ff5fcba9c8d904bff1db0c5111b5bdbdaab009b6db04b30d51822c9913956613ac36dbd5d2d93356b1776c698e6d755aa5cd8a8d9ce618274facaf55a6e26edbde3e76e34aabfd458bebe3bcb5b63e4eb559ff3a9dbe8e9963244824c0c405726e8a1cd8aaf096a56d0b6125e7706aadddb359f794951db1538308f2c43745a829dbe528ab1941bbcaa495793a0ee7736377a74066aded9b22f18a446e9c81b8cab99bb173261e9bce16eec4d3628be9ac8d73ce2e7e502fa5f3d6a9719cc1c394e270b859a3bcb2fc119b37398f8b1fcc1c12736cdcccc1cd9cb26f22d41b0664282dd707c44924e270389cd36a69a7c515c051b17983279d934e3ae73f9d18a839a5a53aaa2ba98ef4a2f3e920f02a29d7139e2164c73d628bc92165d7644aeb07b52b0501945da8c4adfa7ce7cc0809009000b3170000280c04850382288a9234c7743e14800a378a446648344a1c0d85026150140844410c03311083300cc44018043028c8d2d0e4014eed174c4bbd5e4256559250678a784d071a2f4550eaab072e2e6854e9a3f81910214337feaff0952191194d4bf7df3623633e8fbffe23e2e1abf5cbb8de99f2ba5e9fbb47a08cdc7d96814d56ba2a2295e7737051601d17a23d3c97b8e212077e4be1389db2039b9b1841ee45f8438c54c8f1a0bb2357f6bf2ebb1aad5dd3ebc70c5a3f8d9abf52e17516cfb34db02154928c205c783a5ff59e5eda33140ae64c2ed10b8386535d645489c4a62baeb8bdfc8a858ad34e631fe2e28cf1b51500e076bdd24a7a313119a71988baa1775755e6a79cbdb7dc58a67edce494b24228b57d67c4a27ecbf6ba89063681a17b03051d09510d29e39d38ce8ac221772ef56459c1795da054118952853296edb506a5dadba6f56fa74d29d2f2943046799df33c8fbabda8596113844b4b85abd86626913dc2a9c681ab5593ffda7c74c520582b3593703b6e56a022353dd23480d6f0d9d93333ba39b5cb64cc0090bc6bdade45c3403b31f1413312780a430314a98ca31fb180244405e862101aa0bb829f091f88f0ce1a1c1b6736a688f97ab168b152d590037db7e85efc4de597c12327ed45c0865e3b886373dad8351077e3cd5bd91c16ad172b669081f1bba7780df11a5f3a09aed4d6cbe2f7c3fcbccfb5eadc80a808bc97bc1f8a04fae12254fd5f0b069395314fa204c5113e992839ad0cf9a68bd75ee1394a95678ab7cfe1ff68b0ea68a16836613fd93a9b35ae6918d13ebce980972b40e722d958c93471d194797047883a60d6542ccf6f1b907dedff81584fc481b56a231ec6bbac7fe98e3a2260aebeb9245cb3bc76904c5b766cd4eeef46f5ccc1338d4db58128a51a64a07fa156ff2e54d5e2a7005b5671f77d6d9cfee5df37fa2c4cb0d9840c19a77edff35cc92bb12178900b6d99ed99e0b8ceebacd6f2ac190ab6845a2ae51b4f4ee211677789c906eccbf28b08142a6ea8c7d4f4a83249478d99a4d2f96c851bbf36f681cdb51ac4b5ddcf326062bc36d0d6c673d187c76ab2a37ebaac2c99ec1a4f85bad5dba4a6175402d3c513085b374496696d6f52a395a4d2904aa338de892311081447fad1fa5572aa275b7f095a58b5598d02141da5d969daf9789457c0e3df9b51661b5cd94a3abe79864ae3d439b489b3acdb7216b187a75fa42c1037b1bb1efbee9cbe90d701f1711118a4f09da710753ea52f3217978244908b8cb2b4a2dd9b29fad1cdcf7238f930dae7a1631416b187a75fa42c1037c1fa9ceec7f81eb825d7e91d331cafb60eee6bc1d08c7d92b4102260afd7aa52087d0017d02421f2d18a7e5d93519090c8e7d517c561d9330ab089c222fbf1f48b6871ce2a3cddf4eb5dc653d00d78088e38c05791926804b86cce41b27d7459f933646ea8bd8a971bcbe504cdc08ae3de741a2cfbf95b7fcb01c7f56c556c24c1819bfadfd3e7a5a4b19ad3d0e54e9f7031646f7219cafe4b14cd5b2fee3b802f38d1581f5b7a56ddb7fe7b2154e4bde4b0698d31cf76e6aaf447957e398e52b67be46f042453a9dedc530e3e43e1ca2431f5f41c4ef10366c2b20ba3203cdaf1431bf32a24fcf7d109f526daf710da18574dbd7f4aa17b1e7b29e133fe63a9946cc101a0c31e6b54982c55653488b1f0b8d546f317e9f74cc9b80c66253909c8861be06c15de5fc53f33410ba953cadfe05dd5b3fda2a22c54d2cc9a4c6bf3276b07bb43e6b5f88b04f0556cb07a97b03c3bfdb5b1424ac188503e367356c3d860940fac6f0a93579c01077c60c72a2a962ed6624de0bd0fe88bf8c924c2ec98579b0de7d7648d2169152a026593a4749ae464fc826a7cdc63adc62a9267242fc31c8ccfe37f299f563da3e3276cbeb3a461da4c3cb3fc243bb952a341714c0f88ab7e81dfc3d8c6602a75e56e09d1552170c260554a966263032b85c90529f79851950e805f3a0df574ff7e5a0200b8721bc22b684951be1cbc453412f8c1dd72608323987f931013a5072bd0f3b7a754529d689f63336a36bf1b8f94f74e100b41e78e9c1feda952cead86179e40b21b750f3a3e47279b84d6f01a6463b52e98ded4bb7c0ad4f5646bac849bd17f783749cdaa48832b68c33a9a279e78a240634541779e0feca9937033b3121df74b6077252551e37afc6d12999dc7250ebbc92ac13f2bc6900089ff0cde51cf3fcdbc24ae0a82fe9c6933f3eea8be9cec72f066970d52fde815e5a7e578dfd04a3d6b19841877a851b4d3560944317d1505a4da58095d96b9a2c6f9c00e8c8f836448927d2e6791fdf7f48fe92436ea9ca8ad51d2af74194f5937e0213882af63cb506c500a0a72d4217fd58301087c07f4d414558f106b88184aaa91dbf2c77042c8081cc55ed40178ab43e2f8f8f02c791770688221faccf55f87c30d3de10686cfef779055557b7f672500d0cff9adac065b37d6e5c064087c95a44d80d7a542ea032bead38b4badea4fe0762418f637fbd852327ab894ef0a8d1b6fcafd2e8c844ec9c2a078114bda8a6e1680c19a048686ab5f3d1be2fcd7e8bb98c4b914653521408f528a94661e4a7648fc5f26628d561a63a24a06d893b0ed329e89ceb097dee6c27b28acc477fdc3754f6098fc4339c03662ca46f9836844177ef7005bc7a91656f3db16efd61825ffddc88ad5585f1141c402d8f4716445777ef0a3988cd618fce3fc8f1c52657d051f466f00f9a937a913dba55c496f5860c406ff86e405124b5fa0d363e90d402f4fff436f263a24b54cf82bc38a4aae795eba96556f4c5b08e52286b79660def27f24ac2a412c7d05f9172a0785a8fcee34a9552c462b57b391c4548faf0e7256f29957d16bf0d95448d96493ba0e0c60da685e4c57d7200069129169b67b9641c3ec47874ce2c8b3cb0eeeb8770a4957d94239a6ebc0865bba29d55b20744ebcfae8b8caf4b29663a946388065d7590a622a983514b282957649826c139244373e8c1566cd80e5000e027879cad4c7069801b530a70437d2d42bad24ee4c3b003c0d3b2632fa0a3f369e0450f7ee9cb328367853cea081ab115e2ae1c864bc88e7f4709d0e0ed3b09a3f687ff8f49fd28dbea9e5c042cc64f2b83afc9b3b642875cc53a5b4c7ab4a5c562b894c5169065462423e1a0c4a1a1b0a7578b6333099cd5026af52e80bc361eb94a6ba3446891ed19739ff8f749d1ccefbc2626935e1cf3207094a0b5a28c5329b280661ff0c26d5851344151886c9dcb235e168d2c5f6040dae5b85b13d27ba9279ab043f3214f6082e3c05b892d013782e150d03a4a725932e055fceae3f443f3adc1ce1e63a08c1c20c821f0ee347b43ed25f6aee46d7c73b0c9689440290a6a8116ca721bd03329a8da193c2bd60cb1b1b46e6e8e1db463c6b8d89eb119806850e9ae5ace16e361c6ed10d5a4d72fa38a7fd3b5488dcfa2e5bd3b0f10c15f9eed13d675b2e1f0796782b7c075a7994b9f8f419fbbc6f89c2b3d1ae83d84aa1b311893617650964a38d9424167a7fc815ea64b0abf3820558b2f2063f14322db01f0297c567ceb028ea6365ff8dffacf1b49c94a8b88545da540d200053c97c67f4ab1bb3c740e4ff307ee67cb84b092c4e474b1f78270f62cef62ad40cd07c25c214778e731c92b81a41d2e8cdae0777579820696b2024e9562f0cda3bd67f7a989eb6a4c3a5d96f76b4e2e5d2fe68334e5e97b68f58b862c0cf30e4aae53eb6df73da17e3bec6adb63b08e9483d5c86e0c84477755c9a874fe673434ce9ac731b3fdc817c6923899e5bc67f67d2b5f4bf5b335e7992b39ccc6704cd21c6a1c00b73f692808eac28e51d922bc8cad28a3ea762bd61c657140fd080c7a7d90f04ba29f7f1be7f04efa0fb09f0e7fea9598f1bae408a27cdd899d3c08a43e2046c4b58b688c0ea6aabbb9df44c9cfa714e67837a82ffa6093fb7cb94bd35e6a0456d60515c5afbc2361eea8e182716f8bd936d8cd6a2b09de73eda909ce4b3adc3985d2920224f613076e1ba17e081cf8942b235d26ab7bdedba443c0d0aff5b32b3678d5b6efa67abcc515044be2507e0b7a8fa8a7eeb344a101cf2b0c0f2104094b2992f0b66e18e9077d9e0601d07420ff93232e020f0f9560a8c965a0e4cd010d9ff1666004284961d9e9102591b2e7f31ec7a6dfee3225c879fdc432754f2c53e4abdc5d2abe5b09d484bc192b83ae3bbba022189711d228e33d95f5cd414c7630198f7acd5baa10b2db99e38814e4576717cfd0e25e6a551fc535a819dffdf23a5e2c079a988b2c2a2a228f5cfc238a9018978c2b6c6b979e8fb10e44908b02ad12148327e754d295df3c493a2693bccd6d72612d74616a8d61a6ca6faab184b82dd9b8c290cb1926ee22ae0985bab94742eb42a4da8d6412c4fc8579a3c23ec00c92a95e02472e1ecdd24de3a98898f2065b7b9384e7ff51f4a1f03d6a6c4c8aa7a5691983842bab2f97ff5c3477538672c27575a8cff1ebaf9c34336a65ae222dcfbbc20642d32a2e461f0a2dca0887ae42a94254de708f4f94f01034139bd8efb842b881081f12cf0e6c6266aed4c7341d494a6702cd4c16892d27b29095b7484010190a54962357be24d2aea7834c5930105b8a242edbcf76b1fb9a7b8b11a037abfba267b280a879b7d1e3206fe6427115559408efc772fb931051afe87db2660144741385f08834444bcbf5d9bde54317e954210bfbd8fb786c9603ddcff590ecb402a59eea7469f7a37d1d2782c791ac703460b6560ab909e73cbcae5299cffec0e01f3d50589e4c642f8468c6cb439d3b30f1fd09bc54b1f9062a0d7aa699a0d30ab7e188c117e65717cbdee4cac1badea10f1bc22b420498fbffb20098356c5cb93b0546bc3804d0452a49e0a92063d9cf1dd18a21bc5e1fb1fa5f17013cec7e72f2eb2ca4c7541c8a71f86cd2c640c5e500aa25fe97610cc87a71bded107a2c161f1f0dbc164e1f2a02bbe0b31394b4e8806a7319f90bdeed33823f6dd0f600353d8be7ff1fd2b0fd4d3947aff74bbeebaf7b7000a666e2c287ebb087abb2804b5503ce71700653c780551a29b64bde174499f67862ed4815233f175d024c6fe7d91a56b351b8ee14d76816c2f4a44f29c84a57bd514c1cfa627bc6aaccc3c5a7773071940fa6a20d7cb722ed17c665f3868c694631579cea9a99ba9a5ce146d7c8f1551a8e131bdffa9665b38bccb6bae1a65337cbbce5d2bb175d71e12e3d093c9724a63cdb6382dc84760a1ea878691e49fa9464dfe2b94785a3f3902a3e6117b120ad5c2ca7cb2358395be67dfd28d99907d0d91a4bad064d6a8a418c342a1bb7c314dfa8f3d2e7a70dffbdc0a09e34a3953f40c2bd821dd41efc2be496b5831e9694c65c03ccca1d71d82d89128d01c1c278c8d28d06caa003daa83e4685d6e47f6f1e5c6ff1c872d01a24ac9511718187da197e017fa66ad488318866177421cb168729563e15682a1e28621c553880e3bd5bc5df16a1015d4b8483ffa88c1cc3329e063400437e819e330f85f16d30c6237c19a7a5e1f771053125e56ec4ddc4e493f3a31b4607473d29bac4fe1d61e65f14c72ce576c03e1a52aa86fd00910da9eb552ecf2b0c963f835e164fd43de567a7c78c9d701bc658a3bcd38e9c23c31f0b80d01fa2a66d6c0b6db54637b7e7c817cf6a757fc59b6efdd0d1728537f6e9b3483bed5c2f29967af2a0146e19698eee12c51c31517b1bb692b0fb78296a4c6ecd70afdc62338a298b84bef98c46ece8d181f7841449fa8de22d2fd70c7cc350bc11572fc27311669a943f5c3d0cf188aca77bfaf4cb5ceb31cf98fa3559e82684e9c18ad2da52076336fb0c53320a0edb858a3c3b706228d9063740451d2f16ae82682d5b28f5a5fe21889b98fbd785dd55267c6fecc9bab0dc2e4c2eeec025860610aa039a5d448d9a0c27b5bd553daf571272c22ef86105b0919a2ec94a34130e03bf6b7d2bd229e5467885dc68de1a4b4f0c8683b028a499f87dfcbecb61ec00344a4a023fdc1be3e02ceb3e2aab3476b7f9da64f8ba68d7c4fac2420085f4ded87371c8db3032e900b30116ec4416788da10e4b425d52070273f6a0956746728301f0f3e564dcaf348fead42ae28ef007433c3349dbe8eb8aab8622b5387ea77b6ddafa21d02da7c9dbe9d314f806a7b906177e6c49800a6b646ddb36379c9d529ca1d6dd7c987c6fbc5cb79bf9dedb1bfead3abebff79d5f1b26bdbe5341df53a6f46cf7a027e077d87a4429b03143b724775ee341dedae833a008c75292757e72fed5258a877d0dd107adeeedf3b72bfb3dd3d546c0bb4f8cf7f27c4359965f5420e4dda7aabd4c5d654bd0266947028d22625f2409696b15b4a9736a7f38fbc3dc4ca155e91a63ea376aca8790941701dbdbeb39d7e6e619c65d5d4a9dc792539a666815976bece9fce31400f6b6c9027d27d8aeb8c6b94a74db56c46fd23475fd0063e44c5622b723a9576a8ab1d411e01861549d91d1a128dd9d1a5da2915f55bfb6ea61191d46db4cd9fdd421cd6e81d1cd7ad4f87c0b0e769f6cb4883f612ec38acf3aab3ca9b7af288e231e1e344ff0e2386385e2afc72afdb5c84c76e969b2cab591e67692bfc56d5c6bd8b6ea12ef7ae00c3dcb306770d6715d8472352172e22d906279f80010c6be21049b584168f5d1eed045ac076e28454d0c36f8da2e304da957ed71505a81ecce373779fae48eb78d9b4363ad30dd591a081a227534d78bb35ddcc1deb6a182fee2ee93f371471cf0fc8772f06a7aaf69ca81b447f5864a0dc5048b07951fee89262def05f979ab72f0273d8718e7c00a302b89cbe8e8b43649ad432699963ee2585527303db6884b8bea4e8e4ef06e8d315d6cbc4865b6480db59e438fb722372cbb499b8c21d4903cc3e99e8322d496d0b32717ba3048f8d3aaa81a49201ea4d089bea53dbf5ced8c2ac9e2a1f6c5e14969a06298deb1f6700c22f875d94c1bc4058064ae4d5f6f59a8445777e646344fa05a087e4431f1427c07b2a757c066a18df2a532aa996e15d700fe454774e2e110801ec15d1ec88a0bede61e9d48f2b363a6abfc5459e0e925de2bf74c684679e7617b085b27edd8be8c8702359eecf36e90c31e9b145bc259dfcc598523ac33f246dd45a610b1721b2168ed30afae4022746b4e07e73397bac093b63a79f2d8c598fa4effc3bd155e0f42049df0734f723ac78a78d7d47ecaa9771d68f0224f7a413bf97efeb7a2eb511fc39c16d85f22efccb4dfcf43dfe6e09f23bec395d7a5d837ea3fd718fae7ddbf2d4dd2b4f7d80e98c9a46203624ccc8394ec028967d50f3d4c5412e8334481059360a592006cec83cf51c78b09623089b391327c8e5324f5dcf93f5a4e78b051320cb41522854dac1c5c8a8d27f014b8ac06d40cae9cb77f92ac1b603bb413f936a8d70cd210942acc194da9256863abadde39128cbaf1bbf00a638be735435d1ff47a1a5e4c477639d129baaa42cf77ce646109297644b1678574e3b790b8708bfe4d3e42d3d5c6e8d0cf0d3f393ac3ae9efe5020943ebf62121e4d43698a3219ff7294c93b43b5df4da6067db29985bba96a9bd6b6dca544023e920b271a072afe162c825e76bf89af798fefe8ff34c41372e85105d1c14380451c2ee94474d8ad5f1d6566af0ad63b90d0245306e3725ccf7e4582eb2f60eb47eadfc2a9bf65d497ec979ddcf1845c5c7f78da0c88135daf2e81779018711078a6f7cad048be9f92f5b469f2348084dd1c6ad637f5c94994184a6a4d6210eddd2b32728d6888760cb3d16d6188fe1e3ef9aba8833a67dd1ac00ae03a91e85a128ca0f261176b8dce8114214cb41824ad00c210a069e7e18090bdf8f8f228fe60492955e4aec8b5c6300aa8d0bcc6bc2175d3344ef0124bbc5bb82184d9d9ca02c26b36abb3236c9f7991d8fb6922189c831cdd35eac5273be86ae2e701f4d0f4cab6c2f5d0b79a24fb3dc25a68101b495253025c3119f64a6f64ec508692d9625e37b8e4454fe63206cc27e6e25c19dd7faaa8307b5f4ae497bc53f0a06bf1cd9249d4c0d8d9aa3bdac0314d2ffaa76dcf0a62b75d869a2a46002bd42d8e3c2fffaf429b3c41d390e0cc752ecfa859a9a9bbef342f86ed23a256470bfc18bd3dad9b0cb423a6d6cda30f088da51a4de97237cdea0969e3d22308ec89a4a8f346def193f8583f63d97c1b620c069869dd1466f7c86b9aed63ac8deba4712b2514efc505cd8e58fb191ee421d0622d218b90485fd5aa8a4dfa79c5ceb935905dab4aa282c3886014b55178b87ae822283279ad67f74c2e19c95089ed147bc6ead21bfb8d00889ef5552c9d35747daed3c06502fed52154d23ed026535b3e1093065484539f03f78a9f6b7e0ccdf88661283d9ac68d6fec011d19a6a4f892e80d52e0d5b0d882a84f2d173374c586cea81c2c08d4827c7eef741825dcd3327a8c82b5e6c081373b64445cbffea60f7848494a3269380daea20d65e55462b809caef920a9ce2ce72f7dc4d2d9b0a08bcec92ab6472f7fe4771029bedf167115445e9e45d822dbf088cb3562df5612a8d4b56e74d76c05b47751d9e0f47d8dbbee564292c004b7a003c52426982a64ea16ea8c0f671aac521e36129ea736378c57701401c5e94561e2edc10f620499e97af8e971af78cc0aef62825acb8435b003967d4e76ca28849d8535ecf597ee3e1c772a87a695adede38a855845b97cfe981b225c7f24758cdad0d9c38a7b2050d07160081421e542990b6951228372cdbbe400fdb6025b07ee63b75fec8911a012b5e6ae7ffdf41741070480abad0bb864e7262dfaba3074674fa52cb7a614ea116850284dfae5163fa8ce273cb63dc25672858a9581e86d5c0a522d4143ae7d80bbae160be05301f23716165366a16c68dc8fc6401c45b1f098ae5270704547543a8bd0ec30fd116db9034cb75fcb7e338e4e1de5cc6d6177fc27f2a9c3e62d4b84f98bb93488f939aedd5f8ec92f411f7d8876b0029029307797694519a681acfc4bb5b4005c75b173d0cab15591e826ed0c688cc0316bc1a7e2818d6cddc41933623ca8713a3a8048d9c233383f3790ad432d25e1eeab9dcc07021e91d075611cef6328cbcea50b79bcdf1e292fb52589fafd374f0b5615e353cabf7b72ec2f067136d357638af6ec725fed91401241fdd8117627cfe58601ec3cc20c9a15427d2de78bbdf27cca425c8e02841656491a490c2539d225293627e0b31295ffd8ebdf89ec2e5bdbaed054dacc4a9470ec36a218613ea85575282435c8a00853cf473ab650334cd691b5b27747a13821470d60622bf0b1c8ecf0c85d5f621a98198da6d2aaa3655234dc89e36b15a680c88678a2f1557912b369e2ce9b0a7d858d6cb745f1b531426b488efd37f3741acf2577ae6f1f15595f8ae54a33fb7bb447dd681bda9c883fb3cbba63ab5295ea7601ce753daced2a92b3296dd218ccad7887244efc374528eb71da2e4f2eb43a44c493378726abbe92502dc02fe1e175b5c06448371e143a68b91d235d1d5fbfd937967648ca5bfe589cf79759f146ed6f6533d478e782858d758eca964c07227d94190cfac7064a5e753418b37e7ca37a255d76cc04bab062df30361648f521168a696d90a95443a991e8b8c87f92f902f7102761a1e94343c98854323f58bcd7daedf88a9196c700f2e07a542d553307cf554690da9031665bf4768334d6579802100ac568856ab8d4264cc4d999f338273e9b487f4361b16a7d44d45b2c68846cfb8c1c843c69e683c1f5e562b71566d388a96423020963f8881cf7339d6a5b7c9ae0c088422cb9bacb5a88be4ad6981c742c5a1e9d1c97138efd6dd0172ddf61ba0ea6586836511d5314ba99c258ac4fa9b493e5988c70221bf5426d4ee7764882af094e68e56ca288f504d243a98452b36fbb0bdf5e6d06435cb12b8e835c790405a331a2b6d8e9b5e543272c87288a8ab88889822438ba498d0c65c5d083556bc6c1ef018899d7ba4b20be937c8a616531314ba01743e956e7a1cbc862dc025f15001bec29ee0dd14fb022ef4102b4ce684e78c22f08f37f484b11d4d508fc13807a2a7c085eddff9c8a7b1863419ce5c65bf4b41f0f82de8ba4801903a0f7c0f6b61aae7dcfb6d93b33c5a94dd8bd612def927a76d9ee99dd201ab1aadc3217696e8841fc49a6be8e04c71d3db4647e5ea2d9c5ff23f84744fe2ec0c6e30260642e22d6d54d7d9c84917adacd1b86f4309ea19b4f32b067e46e4cff89f56a7c3f6085d7a147a1625153ea513f1b5139afff626e370023534caf5b677d26454f34e54cb7244826a89bf3cb50466054eca273ed2e6af2916e05134fcce004e50cad8ab567ab59be868e74076199b0a3d46650c0b8b88e1c5152d1699af18bd27e22ff0e8bd2c9f999ef8a8dee38b38dda500e67f78087166db7c96021db6c53eb470d22a32babca348d27a0ab5152da10881c965e22a3aac0b3d6230a8d26a049c13ad0073a70783ffa99d1aba82e346c62a06db055705114d0e19ec8e0d2439e770a173a4fc781b27523626d27c52dfd755f339b3acaefccc08a5a57e37fd1d34e27a7064e530d8a1c877bb6a44bd64d13bcd52e0caeb3664f32f220ec8db716c39028155987046da14885bdf560df441fb046440c24c4f8df456ff6c4a15852cee9e2bb1d2d740569a237d84b95435054295046d246c16b1ad5851f1b72a914485ab3ad295f7ba57535aaf6397aaca8d7d5777d0f786ac96f1b9f30e5dc92e0f28009b4889c5c4b27e63010cf61c33dce42276c2a599206a22209b432937e283160d501bb114427287eff7494c84bfda77fd7ec4166089f5db796832f346ffb58c269f91adecaca06b23c9c886c29068354cd0e2aaab5c31bb7d6edffc890add6e03c49e2c3a2dc1ea077e264d51b44ae2aa20cbdcce33eccf02da8ad606f8e63247bae24c29888131905294c497dd0f3b8afc4bb943ef5afdfa0c48e513e1b365fd0c507e53e79b3411a2e04fd564ca3d0264effbebd4007034bda66ddab911d1222ec9379f316b93afbba2f610ee5423062d717b10ba322279a48ec2cf753a32a129ca120d08192d038b22b02c2e12a57c60f37f46389bb822de419b33b7276adf0b1fa69861f07457c159cace0043c5b9b2b26baf48cbc0387588d4a4efb26cfd6aaf6c5d2e874ea4606f40a98f4b23d7b34984d3ab5e83bed512d26b67a7891decf494883976b7eb3a4db61348870184aa2c63682e61ac5561a824c273e45089ae4800b3531e157366348794899e63944ae41bc845d468ad519380eb78088ff96bdb9302876d9d4659712b34738cab0a646211365188da9a561d305473394f52064bf991904e0624c8221ff29be1c0a571ac9031cf268299a335dfeeb4e6ed08699c7f711e050d23f961c82f6f33e118a517651e9d7a6c5fe5962506480c6e2b652928e81ec37ce174bc6580cb6de821947aea2696ae7b98e5ab2e78d77d4f1cd3b5ef082c06268033d736616226bca938ebc822165710fd7806c2cccc68ee4c310e85b492bca15a5f7a1bd1a672ebf0b1b032c3ef090e0f412b7e650a8b54ed2a84240ab90db3743a638d3e2ec145413b32c03df97f0d5289bdf9f51c6f7336b628562a79014995a23481e5335acd6f2a64273ef6e0df0f97a2575f0a46ee5a0f95c98d885f96470cff4e32854d988ee6e261301ac083dae3fb73caa28fc666576b805ed0e0800654382ae946c42a15e9bf6bd31ecfebe8b6b78322e897206cea0096a1137413345650a347808f5885a651519b30b6825fb9b02a9d8ed20a7403f6604bdb2208b91a7fb59ce643f12ee483251acbf8bf847b83f45d7fe65412c9143debb7ac3c846d1354323066e0ef0924e932670e7e6d25cbf27dc405ff6fec38f67a5795053bfc04e91058b1fcf15ddecbb96cbaa87467c1ab06320fa35bd938da682c4d607d40d60c0b50e5367f06240d4fdca5b0490a3f97178b6c6eb56c9678c7dc8f5a44172668beb38da136b823e6be144ff29b6f3cfb5e48640c670f78dfd6cfe40e1296c581ee91debe739cae80e47ad80a2dd9d7d94bbc6078bbe470f67bb217642032b35f213e0797cd0c3286e7ad0b6fae370484a4dbf772d11164067c52a46f8bb96abea4c8f56628f27680d672b1b77f8e9bebffef7641ffa623c7c226d137b027036e1365dcc4c5515a1c8cbeb67d25644421f4cae292ad35315f60c6d2833a6e81b7131ce6b0a044b4913728e120363632b09a1abe437acbf232db2e9508c1bf547079ae2b378ac4c18b55a4b66b65b2257f18006172b4de292225915c96a34d617a665a3685cf5bdfc24a47a660817e55a489d39a63af44d49aadc71dc2762b5dce66ee25461eb82a154546116ee8de15a9e497c44fc092b223d98394076c537963fc7e0d5cdc55ed9d91872451c36374d237a236974d64cc2a59bc400cea9dd07ed2aab28256faa85580bea0bd48762ae977ffc1facb24d101a866305cf1c1c24e0fafd8f31ddd17417166879b0c5647a97323ae81a45b4abe1334f2f52b6dff6974ebd235e605b9f2bfd6e0d9bc273d26a913fb0b0f6a36e28a3669fd85177979b5a6c03ed48874e8a084ad468a07fa69784ac34430eef6c278459c914dd12741924357ade724149e91709fa95f202ca4e750ae1afe658938d73484def6c0ae52f360f824614f4be6d9bd39bdaaeafb15c9ad7d4980e11d6ea10df44066ba1a8afbc2e49c564207d125d3757fb1dbc6b95086abc4d2d7da11647e2b83d2b1e44c71f98a1284b82231901dbddca530803ee7436a23d70a269ac4adee089701d0098a300cab055ca464083202e37ae0739ade1b2bedf905e3232ae2adb40f8139195b04d2fcd64c17e14fb2381fe168efd52f915a875e5d5bacd83cd6eee0941248e27188a9516ef71a31fe2d30880cec39decfad5c844308600d1a7205e80e5a3354e7089aa7a8568d00341ca63aa574a36a150afdddb1e18afc6287a8fef2138f15a9904ef1e058b26c5742f9ba3f670893a3e21f83b12cdd623f6751dce7d6b1b453d827c78af32e7f0da7962ad448cfe5a4c6784de2980bda9e1ccd1bbcef8f9adae72b10974ee88b6a80fff67315592d1eaf89ed567ca5c3b8cff34a6c37be24c704d299ce83fc5feb8c8dfc4ff42d49f428d785d03a00380c3e7a47077ed90516cf2ed7a385514e784def81704ab98a99486df617cf6407c10ee6f82a1dc8b41ff8dfc722667de016f81e0894edac7b2992962dfeb49aaf868e511d8ee67fc7a8c5caec10c426f77ac1f3e4b44cef874c0134998d67aa1a3c9f1ca2ca47462feb3d8eb07a80ddef585490d9606c1bb1b07ee7340e74d50832ecaa81bcd9fb0335e79fcc6793787c952c42d11dba50d20ffe0496da0392d32edde32018c3fa363c3ef282cad20125a08c07a40850c21c291d19634f3c3413469c74e49e02e88d87e3597c84eaa8bd56942e124fdecec881004615b63cfd55ade023d207b417f2d3b84f05f04459e379d0e0c364eecbc1b682874ad2f0cd90d8def363f3cc39423c18d3b35e538c4351f32b95734bd065a23a7b30fab871c52500d8f417bdd2a7ce0fadb3e398afab18cf587b8b15272d2e5fcbff82a2b2cb568a342bebc420d6a4938588549945e02441f42c70d3a5db313d045c0b81c6af942b8ac3f367ad35b3bbdcbdb0a4e5bd454f9e86094f070222b1d2b795d82cd7c22834fa8aaa91886c874cbab380b6ea4dea4f3394c13f1f3b9423f99c19cf3d215fc889f594bfe5a84b67a2880484b6c7bce2d99d89c5ffd9e8cce5a96adbb9bd6a15102b64590ae40a7a834a64ed2543cb4f76b364177bcd20a53f271b454d5f8359f4e1c4d4b0468dc046c1cfa64da4ecdd2c41d5a6919e071ec6f7a8d36b83bad89891f4a862cb5ce64e1462f8cb75363291a5038896d36aad2cf5e72ddd7dac63c275aaa453990c6d4d55d36c6c70f32ca8c131ae78fa065831bb40f4c876df499c7e98c7f61fbc5fe476862c593021b93ec245f5dd760a7b2b284d1949fc27a594cc9215893dd49de270ac1d695f80d2ae5d658973a6f3dddb73079eda5ead98efd557e84984d1f9a147c4612bf9cb17b9966a5344c2899b86ab817c3545ca3d3c6d36b747332657be140fb7c1d0dc01a3ea2e4344479248c723d9b34f0500e0977a20ff42ce657ebba3bcce06deccde5f8f5624d9723a712343e67f0432567d68bc416c8657eed3e8c71013fcd22edede9257ce27960710dcfde875c4e51ee9cea40b8873880418142d0412a95319244554bf1a0ca90a671270735e9b7b344417a47f49b6af1727b34823c2152ff98f3f20e5fb34bbad7997354a82abbdd74d5da57541f4a630bc1774d4dd516328d869d4411909bcdb3e621db115874247c2dd789489e1568ef9ae6b3479208d00fa921ce8d4cee9a6bd93f4efb7531a40761a97184999aef965afb27dc712dd0802319df80faa47a220271148520615b03489737a13ee8067af853e5d42481073315e93ed487ed67eaa6630e4b687034be9f946fa60cf01341e2516a90c5832f68523efcccb4d65658ce182947a1e3ef3b988a365fa036d719cfaba3bd1dd4e812de3478dde16ff3d4f43f6cc2153fe432feba75595969fe69c582618759eaef5b0d715433085a52ce61e59f5e2681f4284e31244c8dea186e1b67cbfa8004c851222fda6791658fcbc8bb19bcd62e128f6829837df5e64aa44ce2dd6d857ca55ba77c547c97d76ca4da0ca5ba0a79b7edc3355be5a36f20fe7074571334eb2bbaa26034078e5e208bb514cdc8e834d52b9b33024b27baf67ff148d00e577afe05dc7193276450c86d23da1ef3fe1c8e18723b01b3167bada30e0761054266b2085562df5685beddd88ea27154472e43209080904f354ef8064cea3b9ae6ba9293583a97bfd49cfd4db4c515e84871ab7d8202dd3cfa023b9ed445ee585a29c9346837225ab107d7428107a605b2024809f08bcd49e77e31d8f8fa3bade8201853700377628b6b27868db75a82651277ac750586a267a8d6b84e95d743311db89459036e5c64fe904e1f2860e5cfcba6f684b70cdb023a20f05f71d34ff6794d53fbff5f42d4da69283ea778cc71f78481260498fdc80216a2b8aca8bf30ad8bf71947662987552b09d81e210448e8e4d907bb9f0fa82131aa06bb6290d39e235c64e822105f47c2e5912c8f9aa673c4a6f0ea872eae181e89f5ae0ff862240d50c9365ac3f66ac3dc091cf87e450309041235ba254313d4d119b0830f5325467475e3e25daceb4b20be2c13cb84867ccf5750e34febae47d51db582bfc5ca150dfd10351da5b758c595077404d34e4f277a736d94df0173de10763601258295911a59414aeaae97bdf50a01c1a924e83a89550547eb8dd5e493d670736557f43783dc3da162ee48836b1319216dba35556bd5993c7f31219ca5d90f8640a8aa1603539ef4a70528c591e3d98ba0beff6e1a373b84172e5916727370bcd6d064cd9e41d2fe381aa2382cc7a0894443cdbd35c25ad847b304083dfb5db2e964e1f21693030bad5350faf263408e88ef15aea1061a316db71ee63c389e8e001be13b646d9f0d16092423db0bdbebce8435992cc08d06486f4c2e2a563b377baa4b55a9ac9ec9332fb38a1f404eb41a8bc70325be2b2f4d7696d8da5b48cf36103bf94937ae8cce21ea836d40297e2337aaa7a24fbb7d59826d95b9fd148a39507e903182e3ed090f02ac4ef637ca3b9089e250ecb4435a53965a6b41cd0c44c52d102dd34d50b72d4be85885d17711ad1017c189b716383776ca1aeb6d50f66d9a1da4d8385873d4edbc325eb4888d0a8e032583ccc092b5778bddffd7c39e6cc2ef36daf3b4a78e9e378cb6faf4675fc6747ccb4d0fdfc0c8bdbdb6bd0036f4b934fdd3fcbe4590667b626e726670a3a76fda64c1d581f8c0f48ee6f1266944ae9be9f618b44c1a11f6441234f4bc601dbd770f794349e0f89d877c536f79c19e354151cd773352a0d26041b8c6f5ba787960a517d176181a42673e1016acc23c47cd3306dc3fa090eeeb38605510617c6e7fc47c0a5a9bc23600392239455a5886b4bcd5c27408646404fa58cba456305e55a503b96d31dc07edd030740ae233d813a4e45a32669b93e5c430b61421ac57a8c39cdbcdb3819d3984f60a00301cee0910e6eafb824e49e7346bbcc7dcf57fe4a2eab20dc2e1ed73e8efbdc9965b4a99524a01b00a4e0ab509f25d4a28656729df9a8dca739d98d59dd42bd46f73cef41f4cd131aca9a35e58548952332c4a3ecde2a36c10aa9276a1caa743eb83a462d83e53d01743c714d42994976f3a6212ea14e9e5a37cccca638874ca5f888318a87e3174be183a3e957bea174327864e8c1f31763ad5285505c8694c19fd66c6423f6f4505880e752f29dd4b517bf249dd8b92f6e46fdd0b114af792e46528c8695e781c25bfc76765020a9aa6208b7e322d2e70a6772f55ab27753b75355c689d4014a72f40967091d39e34d29e741703ecfabdc3315aa904a900714f6c2a409d822f5fc588dc41652a3d7c194ec35d0fad8755c26f7fa669f396469bba98e328f8a52eaa1c059f83524a19736abc542be50c17114e5655aa9c4605a851f2e5f6a900c9c7ac2fe50c559a825480e67fa53654f956d7f56c8c748113e402a73df93f9461833cac3646fe0f64d85ce0eca0ba5e460e55f917fda01426a8f2a3434d6580e07f3ba8aafc2f864e95bf83fc1d749e87d5cee0aad0f5ec8cf912a7cad9efa20660676b12120ce37e6c1f4cdddf196cfb8bc216e6d3a1a867b42c98c519236f391bbf943408cb8a2635d9715a12927254368ed046b356bad30e29c75f8521b57c482249248924113cf1583eaa3f770a2a91459249a7a06c62e15839968f4e4d95139dfab1d3292096904e9d18aeda939706a32679e0c1b675bad5c59df674bab0c1ef48e5f20f46d83e4ef5ab2cce38b1911647518b916ef5d772ba19a11ffa1536b1d9919c68cfbbeb56ea47caf95577fda14ff2444a56d6b4689095202a6f3dc9076985329517ec919acd88ebc1f6653c4dcac1c1f6fdeaa4fa2624648dac6c43b2096539cbcda0fa3b0783ada200d9f865c430af36dd5070b0adb64b8317d4681016b8d1202b324619317a8a3488ca674384a86caa51b6333386ad258a6de5557854e8a908ae07cb73bf352c3d3c56e8a988952f7d89f650f9955f56298285621cc57454ba9e287d568d31c196604bb0263e2b2999994816c100c2829c46e57989ca194e65c886ad47ab9cca2f89a60e06e4287e16161e0f145487a0d126286c4962c708b78004bb8ab6708494d33d5b0843d016dc10619372b650fd93449f2482d6f4d10feeee9646fa8f4409f93920b0fb15507bff1364836b626924d1a25c8e210d2bcde67fda3b7155c9f6fdea312e63cdc649b531febd011b2e2aa4365cd4a63353f975144b6c89f839d53508aca3547e63e418636c9793af0315be0a954cb41a1bb0e1551b5e859ac639812d93faa4b9ac995b9bc96283afd908a2f290663e3895d3a8d04ce7e464b4aa186739eebf52c1489a0dd6a43ddf843626d57f43a9fe1b932667a8fdb06867c0df95c9db32194ea3f2590ecbaaf2c09ce15790c214713a9baa5331d53f73a269b81f3f6aafbc4a8a3ac7832d08e7de4939b248e5bbbbbbb9c3f13f8d32d29ebf4aec20fd5517e4c39854efd8dd29affa4715a7c3b2c324c3a9fe180a0a6632f93eb692ad68367384f234ba351bda4c16dbf6a3971f7fb5992c2c78d22dfb90c2559b525d536b35200e13c7a9da0b0018b638bb95bfb62dda606958a82906895190b68c67cb7a3ad543f5cf86340d91ea8fb50f51d874c026653f7606bf4a76494122c217915099970791676770e461e14a1c4fcbcad4c2d4a2454b8bbbbbcb3ce96c4c0c36a8c3d0136ba4669f0e4ea83a04551d84b227da3fe3f96213f58b3c3564937254b575764e1b2117643b7d9c0ad3d918ffeebafac30cf8e354964efd4c264ef565f581608a7606c7169535caccc572c1ed60d3d919d005f5c2c6dfdddd9de0cb8bcf68928d5f05feea60e36751c1d998f8f185f5449acdc6396836db43fa4d6d4731d826d604b0e907bf17557edb174d50a12c924452497bb40b1b3fdc8ab2ae7ff53f8d7a4e061bcbb350ce89469172542829a7fb7f9a8685723acda9de48733c476a8b0fb66f2454f96591d370efa552f72b477194ae74009a21c3b64be851e980ba8e6652497bfe94126d8cffb685ac67dbc2503d3343751e1b6c19cf0800598ea33ccb21e5643930c2786a6e48a72c1f22dc4fa72c2023dc914e9d20749911a2c2454619a54b7b0ee98c15b68f9443d221f14098f1746abb5b31b5376386ed93445be4d9a139641c902d07ad8657331e8d497bae35a91c900dd32113d26c3624ed3907562f86adb9c3315ac180e1799a4de6a1000000e6549c8a7322068546633df4001db2e0542cbb62e848dd2bb610547fa87bc5500d6acf0ccacf6836271f2d8e4705c3461ba9b91f31462b5a3162a3f7b746188659d8c8e280b4c713b34b9b57cc2e6da27c76691313fa70a0bca5d974443919c000341b58b3f069a015612a4b6936d66327196b36463f3386ad47086c48094a0e7400da19d9fb8b0a3538a1849248d36a5835a331c7af7ead7f76ebe084ea8f75b167a4d9f02aa428377081c306e3a8fb24c5117b349b297f76f065b4309a8ccbc126835a61e35f79963fd570516155f9f83b7fb5fdea57abed4a461261a46c9d4665e55768a5fb2047f9ab740f44ca5ab6fca01ffaa05ffdea7f3aa5fd9117fa9f37f2407fa43da15fd1701a0dbbd15b1d0e14ad3915c454b019a517df0e05c8e1708055ff8cc769a28ed0f671aaa8c339c18d3ee360b03346b59f9786532dd782a5d9845aa83aa7d9340b4ebdb41f569bd0ce58695959cffde0ba65cb7e6ea74776dc4e7bfe9c4ae3549c133a1c108ea7539c13dc0fcae9b4c701891dc7a3916013da86b6ee043721a7813332ee061ba6c2e35404cbaffc0aed71ea67f9d2b3fcd6a8504ce7574e45a83cf71ced716a1ac4f4352bf4a6a6e987ed54fe8edb71947fa933759caa07e099eacb742a3f7c49e42820182708c6a94d25d7ae3198d83e4924896491ca69e6dc36938994f39ec795321e7eb07d3a04a5d47dccd4a9affbd829dbc75c325565272afb307524550fc0bf44da8140d790721ce50f0020dbc7a9be5f459d9557a19c8ea3fca15684ca479d5f390dcbfb3f50a71a32914443d5ff8d348d24924c1e49f42189389df65828d7c30fb6f81f2987dbd9bea843c3f23df55ba9dfaf9ee6574143aa037d51877feac7fde09c68943f6b35bcda9453b5e78f92c1f6653cfda736f1f0c6f4ab7473052b8001b2edd4a9860b58bdbacf03131ba7c281906206c87669587eb3289686859256b6215415520e15d5bf856643cab1c1c62f8976c66867c3993907c8b615184f3a7fda719a958c6706eb3994bfaa2bdd49676234b81a6c1f2967a53bed384a7ec63303af30e3e154271d156cd67f9c4a487ba49c4ef90cb68f9443ca69cfffa5b6ac36c69fcbd93e524ef58f537d51a77e9c8a24a4fac3ee3bc5e0d453fd49399d8a3e549dd2f941da21f174ead4bf24219d9a3d433a45a45393b422fd908c7c50fd23edf91bf99f07fa9566c3aa3acc9061e3fa71aaef5755070119278046cd341e62c4f4e0030050de0e3074900980007e9819408a46064c0e04a0330a608003748f8004d0a8304a6f5e9993dd987e4e559d53714ee8547f4ea753a6eacfad38234d3383fbd1a92de2031527a4470af5e37caa5b42b4503fee87dba9fe32c2d54fa7a216aaeb206fb6669d1e144055001d02e4b824404e2480ca075b188cfbd1317667d3276793b965460cdb375b0b620757ac28d2a1ca98926a066c61be169cea8fedefc79e9db152f7a3cfce803b83ab34db448cc10dea7e33161dad3606093c3bdce0635063137189e8137f28c366c3455dd91961d1826767f0632b48bf163c1861b1c2a405cfc6f8a314ad30a9fe2845284c5676760677116d8c4f0b4edd1c7618aafefbad5874a46a4927c65994a2eec39e45128c03a6fa0f7e0a29cb20e59c724acb92f39a02323377b725a324f204150c1b32cbc72073949625f789fabdb7351d3569e67fb57fca04b9e20c62acc21663d48480383831c6d561c52c0ae1d57accca628c1a10d69c3487578beec6b084d70c20197a5b8860ebc76407f3a31c6cdcd06b1482676d252a3f4b8e1f08a4d48480d6f6b427578739b5a0a068db2243404185fdebbc3d4c545b67b98728422208bbc0441107dbf68630085811204081bf88138434f14d537b1bc4774a18d704ae3bc992c9d4e2bd056df13d4cbf359ed0f6f5cee628ed3f19557baf5337e663af6559463f1c48d4f9721d35a2f2afee867c6c76362f8ab136c41228797d7bda6a9493b4474a799595f715ace525081bf74248b4b7b897f4d340fd30ceb43f3939c9b2ec6dcccf581ebbd9012b0be52eb00fda5fddc7437aa73dab81b4676d5cb7d215c17d89f680a2c7e9b92fa2f44e7bf497aef7cbbf08ef7795ebeabfbe290f28ae76e9ee9493bf1cf7277ababe54faebf4f2b153c77d77a5f7aea5ebfe1edb3232329ba3ac6ffadea3290d47594338cafb94fdd60f87a95e9fc92cb3d622aad667970c3ad2190de2a2db9eca4b3ac412dc979e86ab741bd7f9735f447f89f6287d3f47fb7b9cde7f6b52baad75dab3de89f6acdfba56b5677d0341f9759a93e4be8896ff165a04f72ddf427b949ea35bc3f2d49da4949408976fa13c4aeff23c4eeb5b7cee2500dfe569b4ffe95b5c680ff73fd193fcee2f7d7f899e1ed0f2a73f9d4e44949e7b7eecd4f997ba7eae6be94e1d0f2888387d89f2e0010504b666891e5010e1f2a5efb18e7af91e2ef40847595ffa177fa2eff2a7ff58258217540343382fb44419c75196e582768ea3acef010511a5e75abe4789f2cec7382270396d4d0bdd1c3504673dd7358ea3acbf640685f0635951240427aaf52bf4fdd00fc860613b4388eae73eb2ebeb201ea29e269c64d529ab71aaf5d68957ed59bf957fdab3de8a5e4852bf16e285faf5902ed41d2e5843d69b56dbb391f6ac97cf40ed59cf40d5abca7a4b552deeadef1ca729bdf518d76d4df378a05e5476dff5f2fa2ffe975dff99aa4b954fc3af97dd07ebf572ce396a203b3b4e036bacbf9e3599d11f5bf6f3b98e6b5a49a7b2b75e761cd49ef5a58e851c653d4ac8b6f5244bcf3d11a5e7b82f51498968297d0bdd66a93b8dbee56f6ab8ee34a2a707705ffad197280f28469488d2b7501ea511fde4ffdfd49046ffb550b5fe74a27d2fe9d4d73bd57aeb74426b743d197d5bdf482c8b89e358ef39eec33a0d59df49a460fd8936dab1be8158cf418c2e9a3d57eab626fbd6aecfe6f3c4b267ad01a30e87a9ce1f75df56b94ada994addd6704b70137eabdf7aeb7d07a55fb20099610efb80bd2b43199900c28937a6351bd8d56671604987ff6247ac31c6998e041bbfcb77fab9bb5b724e93094208654011f4776a6b0c99994e5dfbfb5bd6ed9a82e6f33f8c274306109bb533f009ce19c90c01638c1126a1614cb1edeeaeb71b1318b69ddac760f7d7f68fbbbbbb67f7c9fa14a8c07667585e5b903094dd19563cb168ac3792b9081b6536c66e1921840288bccbb0c9feff7f8c4e31f6f23301f9efbe8cbdd0b045a86d9091051ad547bc60f3e720be3acd4c33c866492f88b70f1bdec0081f9fca44438c584a77b88f8f107c7c563f30a2841864c157f13b868c2adb8b21434a79e1489691e1a1adb340a32cd05e29071b44e11542e95062344a97c3b3f87daa80e62fe1600bc222aa283f040a35a2872a782c1a88a818814e8d120d06151b6aa0906f816f875c58b17d2e4db3bd05b64e031d7b2118c14ec9bfe6100a688fc60b156cdf06d5789665fe43d050801114e0557d49c2f6c9703df90ce59b3213c6e11c56310feb00ad56688788b6a888559cb3f57b55460603a504610f79aa86423f233e192926952ea52375281d0eef84624046d5e8b7802efba8d9640f71784180200646c0c053318a434695d222aa237a5ae86a10aadf16656d8146391c8a58633a65b0edd0830d5343d1aac61f091a3ba38f68cf73b0f5b305e8113237d8f89977b44e1902130d31b1002341a623dcc35d6022266cdf0a0d19ea15ecf866a6d83e191468850455151d0b362a4a700422fc9010abb3d9c4363308e113b64fc6f487f3ad2e89583989ae4c6fc0f76f20d7299a198c8bc9c7d635486a7b92da9d620117c0752aec322ab66f8928cff6795ed1ca58e11729d8ac7708e3d58c025c007e31c2f6c9b03e3ec397fd1898a95214e971a248143e3e4070708eac400d8c066ca8fa0a0c1aef080b744ae5f791e854caaf367f31f829eef759480f0f611f26c241473ab5fd3e0bed0cd26f12262afdb6fc5a6153a6f6fc4febf9e3681a995db24d96a8eba3eebad48571a1919d36c53958cf7f877d1ce5af838c4f276384d3f09007dc7f48e88587de646a41b3c3afc3e876f895966e2bc47cb6f2b497834df513ebf9384daf7c7e6da29ccd67e3c074d7eafa81b15b79224f6c6a4e317ddaf39f2b47f9cca16752facd174de497e9857ea6cd05fd3617ea3f4ff49b2dddacdb76e95c395e31cfae557bfed35ec55a6bc0c461c1f65d446a895e403fed390756a39518462b0d036a2f46d983fd50cc08b66aaf071a6cab4efd74ea4ad21890d35cf41aa26fd8becb7baea0eb48d3ecf0fe1791e9d3298c083ba7c08854c77ab0211d36574e83f154ffd192119351130c07cbc1583a4c85613ad88fd16a94d28d80da1b196994ff9189644b12a404d58dbc6ea4ba60745792468d761ce57f296994bf8fa9a7faf38c7cfc68095393ed5aa2d315a5eb7ad271d5eaa8db24f5ea24aaeb150e4e8dd76d15ab2da8706ae66a065d3a3e9938cdd6acdef4a6edd299db6452fd61745b0329b6447b5d4d546c7f0d557f0219c450571c04c6b643071bd51f2b3bc6cd214d03e3fdbd676867c08740aaf7ecd0c180d1c146313694439b8e802d0cf76377bb6ca5b9d7638703b60e210e0f622890abd0c1c68fe3b0c745f57ae34c04cfd3ce76dad9fcf99d6be019b07e0ca506770d1bf0bba94ebd2fd6fd1a504606324766ef010f90e1287e198edac7a2b4566468cdda0366d6da037cdddd3d467f9b0dd818d56863549dce1a432c410212d8cc6451796a367863f87966965683b75e5a8d4bb3d170a4f963281090b181a13cc086b6dcf3c47f32363a815f234648215f41583fd61db7838d7d67276a3652a542e176b07db0a7c76668a8baca55bd2a2ae21ddef936682bff9e740da71288298a6d6adaffc024a3f483d20f4a526cee991a648f6f526c526c41d86ef733333333f3f22eefeeb5ee733608d68b1b585489de2c2a7ea42ba8f1bf8d4b50e3a2a1460dac0ff1a453281fdf009dda3e3e8dd8e3341b855c3027ab3007fa8828759d46468cf16bbce28c5ba4d27993f6e2a774cec497745ed4b992f6e29f744ed45e7c194ee33d8e8a1f818266ec9ca2eeeeb6a4775317d239edc5b7baf6d15e7cd9b5aabd18bdfda38cf1f752917a6201c33820def291fa03c66388435d4d0894ba746e4c0ef72cd650591362ab4b4f45c89afe51fd3e5083349d8eda7d1766c8220eb535215aea5214ae18d46c5c158858bf1e756ecc641f5cb381283a6a5875bf46d7a5f382975f57bc668cd7755d578c56c7c832c618d73b616e6603b6305f0076aae4ddac3d8790218419f7df8a4b898e548e0ab267c826b72aa34f95454b4052bfb8aa52ae963086fa452355feb478d4237f34a45391a8ca1f85a17e2322558241461564f9a3203882262ac7be1815a66914d0bf344c6ed88c18a2858f8ddfd4556c5fbf9f4fc0c248fd64e0cb604b43f455f5a2b85a51c057ab59db61ec6ed8706780f5ebd8a51f7f8e1d5c77633e0ef8e7b02aec7ae3aca3fdf9e3f388f402dedf0572f0a8961039bc5af3b1ed2e906337467e90cb9a17c891cdf6ac979605a3e5b3ba95c34ac26b7710fea59d2d13e286530c783d0541bf9b2fed6cb0bd660718c1a99b1121d5a56e1123aa5a440766dbaa8a9edaef1263657fabf41c1bb8a92eedf2feec2e5d873bacfe34dae9e7f406fc7df9fb939e2e7ac37ffedac8e1d21e7fdffcd1c7a7df4dc57e6b86fd37fa484d23eca71018bd31fffa1b7334ff7ae1862dfea4dff537ac3fc9df7a536f4c1beb0f5df6a10e21205d8ae5b0a65585155318a95d5d2ba6e0a9180a3f8672f3e2c706e3a1c4d1470ca3a720e0636f033e466f2af3c779719474bbafd052fab1c17708dde9891f568690fb198bf762c8c88610d25310fcf06df043da7db0f2befc79ddd41500fb209f865b0de30c5b578880d1f73f3df9c39a82ed653211aca490d9c5b83d9aecd7a1b432f8b36510ae87fd621e1801016b5b72d44e04cb267477f7010884b0ddddddd79977d9e3df801b638c71cac8d46563f6473a309960e66fda19ed6fe297ef3fd9b21a4a973242e855b8649dd262062c78691b88ebc5ab031004d58180ce909ff99d067a9b0309a5e52058132cc1c08b20901a10977481cbceb0b229eb7e8cce114687b15d7646accd9a7f47fa37b0a035bdaef374d9195dd7f9b27179749e7334fb8b36feef2b3672d9199625652e2bb085819833bbbb333bb3bb67edc11fdbb7451e2110c61e1a6c23222bb056571149b49a423e62133a569214401d39a938836559564ea4220b17ac98544c9ac069d4d66f6e4e3401441343965564a5836a499a0560c1c451a624acc4ba4590a0d298c062821e202a45b612159b17b6ae6e911e2aa4b861fbba457ad89092646ba95b440a1890966c2eea1691420a9a209090e3a887f9a16e11299e5061dd22ab21f57b9924eeeeeef2dbfade19496c75672461aafcb0db24e6af06bb244e40d4486fccda1bb8a99c837f470eabae0c8df60cd01f239dd918ff4865a6f3afc51cd99237e2cf0a7f568e6f25e1358755573a057baa47246031c2e7c840c867fac5282d18234ba8011173be40a4a8fa50b708112a2ac6d9c2a659028a5310bec3ab3f135f03057fa43ba47cf8b0012fde7a6865ad09c11d4be698b5c7c409dce3aebca64557d26beeae9846802defeef62e6f154a3e98d9dbfda699add8c11165d0c577b9306cfbee1e3dc61833eb2d8fef91dd610fef6edc655ee6ac891c82544689c1046fc31a27b5e9f6085c3881dd6b1ac26e25b8b9096f0c0a8cf25f48ef1cee37915b0dddf0bb97b7616fed35a4eba82177d38c75c76c2a707cde5dc89561e38f304ace8263e49f58ef46b62cb9bbdd4b186e8cbf1620fd62c591d5cec27e7c76dfe57f40d7344d09416525b85b083baf7424d8f699ab43c885aeebbfbe0ca13b8410babbcb38ad69b9bfe16d6c85f23f7777e9524a194d1bb3045b195b8a776185dbf4d474eb55d710dd7dcedd6f87338e0c72120873209f004208dd23d436c6b38de1973a5808368613ee42c81176f127a42b04f601c238d9074208b7bdddb803561e089d77f73714cbdd37777722308890c07c7d77d97ddd7757ae15d9e9b631356821b2ed77ffc670f70df38d3977777787e839e784bb3256bcbb2b572c4bf02c14ffb6e8c6851f29ec87102ad1dd3cc03ab8bbbcbbbbbbdb8960db67662deceeccc6bcf0c0bc4b7bfcbebb307e59dd328f7523e4c802feab5b66ef26f3fc6be5e73fea3ec8ccccd12d19a78df42e7aa0728cf1999d99a373e50ec66ddfdd8d69d8e50b075b7f13d65d67de5d76385760f6bebb7177bb07f0b196018420c618e5ee7ef20633ee3abd0117c6107a1d6ec38731c5eeaeef3a1530ff5e15d2b6158124dbddddddfd829db3427803424f02363bb5b066b3bbe7f47f71d30c4980c19e106a42c00e52e40948ea2723f38423b57f8646d72e62c5121aae59aec0b6412c585523fdb57f26a80923b5bb7b9d9979f4a526b6eb4f1e7bd97d292f3feb74a0bcca6ff7b13cb6dbf6b6bba4dd256dddbbddfd396664342a6392f6afcf5e7b79d2e920fdc98f3a1ddbaf3c4ac7d261ab6d07892c24425de9b66e87d7ed51ba1bfb288f5d9d8eeb7778b5b9680eabde5869c00abd91bdd67d39ac7a7d0a4dc2eb45bf8cee8fba8f4473585b77e3e4faafd75f3409af237a02e22bca7f45a14978cda020a476f5df2e1bedc907e1b4ebdbddddddddbf7e73eccf6c4c2f75d998feeda6414cf4ea603aaf33407bfd5c67cd5eef7d4884eddedd9984d7a5b0bd5ee90c09d80e8e68f3ef7064ebb94b2c02063f891018e9eed2a55b32ca8fef7f23ca6949e952baf4fd02063bc6ae91eb8df8ec438c52ca186394b1932e31d20dc58350a45ce952ca13a45b63f52598bb4308e90de8188531848803ba43ffa5d3795cc667daed4599f66eabccccedab44df7877181620830b32902079382a36f838f807ce6bbea45f67bd5b0f9f465f73be35d78fa4e0540c05a742fa6d0b159bbf7cfe66758f5b5352702a8dd601941be3524a098ff85e52eaf25dbae528801042226afcedb02d040cf9b99b58802f5fc6a80c219431ca18a3c2d6c27f6eda98a5524ad957f049a7e4688aff6ff042ed77d927345137186c9ff7fcd64b3afb372bb6a146c6915549d98a9625fb07a7f2f1968c452041ed35d47e18202c2caab32f0f363819c14f09509af0f302136831c61885a4c1045524610c4b38c2179480445302162cc8fe6188d0440718ccb7b7d05d3c4666e6f69e30c2b853acef95c1c86baee4d1e8e5cf39929347c320d963108b0c63224eba2fdfb22c26a09490660926be26fb116833fb7654185d3af53b626f54af118f3a3d06d1b621db965128fc61e4f85b37fce30042b0d9c88e6b36d773c8037e0c9a12932329a59412c69101b099189fcb0a0c94f48395f7a7deb8247c39b47185504a7ac25e62d8cfeeb480add85bffc13afa9b1310f1b1b7111fa338f647c2b9f0e662188339c22cf8d74fa7f1c7a837a2d7dc2e997a833f997a59968543a6f2cbc7641a36ae9675fd1c3dff474f230a44d78feb097bbfa9183d15111f3e0422c52103ffa64eeb67675950fa8d54c2db9d102d282d19a7e4872f21c4e17d61e30aa1fc68fdc7929e2c4ac43aeac3e1d5283fbaece0c70e421fd8ca8ae4f6160a1beff433b94cbad210a6dee087a9567cfef811074cf5ce64868df906d3d3fc8f2b3d4d2b09ae32d613a00005302ef0627c2276c727e210282bd8f87b6a0cb8a990ea80b56930c5143744f6a7f67b4eeccffe0861bb872ef408b6fd888d6033d16d4ea087239b7b50f061aabb3156f854ef93f19d8a5507acb14623476ad74433d46f26ca872720fcbbbb9b3b1d49c01d2720aaa4376812b3423a5319e35161d4b11b03e90e779ac3abbf7cb77663befda9103acbf0954e39836164b57739ac4e87e760a73b72e4b0aaf6b34b228755359b13fa25e155a3dfbc6a464ff3b77e36cdf4ab31626b7ee7b0ac3ae90729d34f099cca4ae054ff52135be9c8667d7fe9c8367f7f4e1d8d5373588e5361241cb08589f186b631fe48449bb91b13df7aabfb9088d2b1d6acee460ecea22631abf548e8689c3a690e8b66edb9c935ea5bf37fb3bbbbbbbbfb17c69180313337e14162e44757f7eeee529edccdd643c8902143e896a5811d1ee8d49416ec38e8eaf888507b8ee308242c30b4434349883ac55f64830ecae15eb0f512d577f7374bfeae543d2ad944b59ba8c6a7d157737773f7c518866118d67cf10df7822d0a176c5fafbe8ea27f3a8a9db195e7e39dabe39e9d06d23c3ca43d16386c1fefec3010e6e9a0511558d685921a36decf610a5bfcc2c6ec9752f053f7f71bd2c05c1461eb8fcf71bb1b76ef0ed943459c5004480b1543813b7634bd21df7fe90df8fd315248d7c60eaefdfecb2f78b0f9cf954e71e5ce8ec42123b67737a8aa68d0c0baa9b7109d76a0104beae748b0ce85da7b2183ed5b28f80f418411429c64108794aca66d27ff7d45f97d6ce8a6a9ebb4079f2d6b63fc4fba1731d83e8b8602fc2d297fce193f7b1bf1339afd4dedbebaeb459d05b3ebb666617cd4de032c0859af98300cfb936e1d8565dcafbd8d7eed6feaec3e58a796751776532f2925c7945b2f5f846c2e03574c2e0fe3b505a1f439e79cd0ea97d875132b36bae0b4e04309218cbb9a50ab59a781fefd5a37dfda9a9697216cf05dc674cdd1c7c73ac6c774baebbadec6d68bce64b1fdf537b5bbef6536ea9b3a3b0d649485c03e584fc331cba5bdf5e67a6ff99cebbb128259ec0bd83adfc6d6f937b5fb8ea83359c47ed9ddd4a502601f662a0b01db4eb5ff8eaecc1a5301b00fce837a85ee0efb318c339f73be0df8f36f2a77d65a3bba4aea2c601ffca1c50c84dddd5db8bb70777737b2c092d29216fc852e2974f77508954068c54bdffd1bd1dd7de19b868023460861840b172efca5d0a3304dcf84052740f9524a990a21f4604c01abc07621847083d07ddd7dddd77fb777b00b77f7fb17ba69fe0b08e1ee3a5c1dfcfc0c1952840940f60507849999b98f307f5cc264495194c9184669314b6b5e56c6f31a3133377333377733777337333333337333f328632ce34c3b41e1666ee6e66ee66ee6666ee6e66ee66eee66666666666e66eee6675ec26449d1cf91a01fa09f153be130b28a9bb9999bbbf9086ee6666eeee6e6666ee6e66ee66e6e6ee6666eee66eee6e6666ee6e66ee66e6e6ee6666eee66eee6e6666ee6e66ee66e6e6ee6666eee66ee6666666666e666e66e6e6ee6666eee66e6519b9fe9f6f0836d33333333333333333333333333333333d3853fc0b69f07256cfc71ce39e75c21c833957d2800e7ac0ffd5f4c910e44958798eb762f86b0f15bd65b5fd83ecea97dc339dc710e3facc11fb3d3ccc9809bca70fe09be6c8d0127486157d89ecbf06e7e3264649ad4f8be84a1911a1f2efde04f8dabe8bcb1a33cf92b0b5bfc1c5cdd710a82e9a744650a8b2a8dc62e2c6c417266cd35c408388b9a6ba65331daf3fe7ba2966cdf09fefec76ef90203b6301fd3e88c860216c000d53637c346994906b6c98c645cf4eb213e4ca43d9f93552b43c646ca3ded390b710b1f391df480aef180a3fc5b54a162525dd56e8450751f9240576421a77ed91559c0a97b0592a22b9024a97b0592235720b1a26a75af40b2aa3cbdba340925b33d1e148142109c400436b1b407988dd576999fa0e4094dfa8753e1477b333b753eb62f41f5487d31d2deea6705e4f342a4723f5e80549e3a513ba81576755bbbebcb0e6a2775bde8a086d4f91fcaa7ce971f6c729a1455d18eca0b50048921458551173e2e5675becd45449cb0dba8d0f6a5ac5e55677fa81dae88e1b0cddfba45a0f85163fd5e86be9455116aa7535d86cfa4d2a934b066be0c91a17e2821a89def45a7ea3815f1f2f123edf1e2c2c5d06f0d0076b688da41f1d4f93bf86043ed380dfcf9281ea789b4a7ce77c153e763336378d1a9f363cfcbb753e78b903a7320da98f92d516c2e74eafcef858807a4a722648de5a288477cf12f688f9a222cea8288bad84959653bf58b45acd918a1434b4bd0923a7f3f97faa5ace0971234a393a3a4cedf2f36914bb8d42f16750b13465245528e4549397f53133b528fa326ec4824a2eb62c3757d93945c2d3a5211690993f65454baeb5b742392924e2d29494722222921ea54ffca0a0a0aca9cdda5f8e4f0e4905429909254357a74b5b8ac7c888cae1e430b9377293e9dc27e7e8aca697e60b2692d061e08238f90a8d9a080486959735ed768c4861e8cd8f41084f50094659a767282e201226488cff66ccc146283ead9341bb0a27836663e46ca38201be9495a0dafa27c78c8696ff2e0a3bd99a2d9a086b4377f34ea0ed5d3dea4289fd56c503c2a2a2b59ca68842282c353d150abf626b692719a0dea877b4eb34111696f964a5ceaa6289ff6260b0bc7955040341b148f89c56432ada8a4984ca4cd6432a1984e3493c924773841a5f438cd890808694a4f0a8fd39c88b01ea6f058f41d357f3522ac8794077c8b9a1c35df058b6df4a8386c5fff45bfd1aa6e1d6160b4aa713d3ba9c5e5f429485a5c5c5a84300076a20032dfe5d432a39a71a253510cb04b014a09d26c864859396abe090a5bca639ec10ec5e3a81e47cdc720335cd2c9f7813afa8149a76eea7c2cfec0c4697e1872d4fc39fa8189d46a78f587a1f6e6a3deb0ed155f3852bf1f86ea7c17382e723af5fdc0a4ce1fadea87daf9614635a3da195c678aea6508b5b333463f4754d48f6bfff7325443a68ee8d2abc5635f7f8bf78ea6a83ae5d5f9d83ae9c2469f8204c39688c247369442b444872125757e4a90d3c09af9d86868b4b3311305a453110b9e4eb108e9e9d4c910944fa7567e3e8a48a722181a00abb7307513686f7ea9fb5044ea7caefb50ab3a9fa5fb483975fe4af79178ea7c95ee23f9e8602d4555e7a7743a20a9fb4c28ddb729a9f3793ec9a7c8537cf0909234cdac998fe9ec8cad736b564c7aea7c92929efac5a213fa9174b09dba15f1d41290d378a4a1f9a4261b90d36ccd0cda84bca14d680b4a59b5913a494275fe87ad7c10c3e6e25fbe3f33e208213e2d2d707c7ec422d7c2e8ea22a2c84448e200c5253336a9532ed19a8d96bdb8f8cf5461ea7e10d0884e653f7f029dd27efe119dea9fbf00a7913f7f08a7b17ebe37e7f48a88efe2852e01c548eb0ec5d3dec4ae6bf4578763b40ae2e269f4cc286a2732894d244e9da89d0e05a4bdf92e3a144f0f6016396a7e7fca6a3ed61d12edcd4f59d599b29a9ff2333f05687e4ad1fc9426f3538ccc97a13aff4b415267ca509d294475a62ca93325a8ce1f5dfd32d4a96f895e92c47a21d1a9f9176aa276eafc991d9696c185a02abfb4836d6bb6263efc518fcfb96da31db953a55c47c997f387912a3f0275ea48d3d0d51659c2901aa8d2a864cd96653d0b198d0010000200f314002020140c87c462b16834ced3104c1f1400117e96527a581749d324c8610a19640021041043000044046666260d020ebda43f7ab3ccbe7a0dc09a74248965857fb3b7d0aa343991d131898af16686613d801f00902eefe80fd6c5e0372a4d0c6021d9337fa777e9e1581a3e59a1887a142aa468729f587169e065bdf718488758729e1c071f2877d33118c6f816767ccf0a992361cf633c054dc8b06a36418a45fd29c76587983c9616c4100d651c269c36ba92290a182d002c0144a9549140dc557b155efad27f1afd1b1743e893bba442645fe0b342e64848372376fbf2967909bddf3fb247865d2221c3de048e98238c84b02fdbe847b9c87163ebb023237a1861b42d4252b3974ae865cb23be07bf0dcbddaf319c45d8ca06aa56262a56d1d08ddc0fa294ead932601153b44d84d419e705880dd32f9f2f9974e6f3bf1e4bc0363f22961967ab22aaeda5641c2717980ee6010078a6af1d456da08184589e6a475d06c583e7db9898c2d543747304a174989ccbeda7c838ad4a8bf4ccdae45bb7a8c1cf2562577f143049c69331ce1b9b513a21025b4b513dc33d2b05f19e89289fbbc255179b60af2ee0272322ab1a91543c4c193c40a235a3e1bfc6e24c1ac6cd254341f70e9c3f4f513d681316d1006cf704103f2c81ed7de523901a16c04c53b72f988064974a6bed0008ab40fd6e61e4d3facf5a6dc0eda9c88a976350533a6b2593c704249ddcf15a8ee99c8fe62f718d43f3cb3bab457891f9e823bf392955050da096e39db6ca7d2bbe3b58831b0a1065fddc33c2f4a4d5c353771f3fb577487668fdd4f3f8181719b2d5c73f49879c426284d85fe6baddd61fa4a08588de3e859b42de9b598d9496d7cfba3830acc7ee3b55ee5698863fa7f01f716b4d7b5caa98207d52d6a27585b5cfa30532395b9f5215ca0cb31ef1aebf758844015b7f850c001ba295326d16d9cea28310d0066a190d1f29288822104934f4fbcd64aca97602f43e6d20691ee576b1d07f83c7c9d48bbf7b57e6769cad132483d763bfcc8e3686a8aca268e5d4e0f47c5119f814054ba41b65790976db62b9869dcae109869e19d07c0fba0946885f02e25444a731052edd7022301627f9a8ab6f4ee7c7890819a0c7726adca0ba3fb4b9d2b5a731b8ab11c68ddf9ef08d80f8cfd3d5bcb4baafd47ee29c0a7ec925747bc739f3294b3481720f3c8480f79c4febae43e1f9338b5e783b0035bd8aa52ae18d7ba9f26308c61646d2233e9782f885e6ccdf3d7b4c2722bdf7077e345a6621e1f4048525e1ad0e5260b7b39d01f034bfca2a08438c73f900c978a1690e8c8a824b2c9cf33b880570f42c5de80621eaf07a60c252fd90e494609a96a033278b72ed1912155c8973f54d930d20bf4fbba751f88fa2932c189c2cc85b3504c7b611cc030da5c884a73e16afea03609b2f04b1d180e1e4d3187c7516e4ce7ca83110129c1b9b66011aaf2436ec73ea17d8e39584c0c5c1332ae202c81bd0e23a2a08fbdfabe66760a1fbc836d8b92a2e1c35021101e68003ba58f71b817b029e39c27a6149f828c10a5ca2b85215341e20ec20ea1829db06f41eca0c068dfafb586e455f775e0cff6b455d2e5fe94f0f09456170b2e210afc840120d7dbb536b6b55266b2fb2a1905b94954a2573411b0f83265fd7287a81e89966f535a2461b41f0808ed8b177075bfe7ebc576cd5b1a3637051df711e3f00f8a6008ea877b5ffd139e7485d17c5460c7673c013c0e58262c636e896aaba1fca6aacf9f7f291bd0243b500de1d07e77901788ca064c6b200618c17c722c9d57c5de683ed2cc6e5f09fc0b0898fcd9789e975802f5f679622b2951b2d68af53b9364debee750863c6081411ad40f2a9ce0facfca042f979f49bbee9ac6ef4439a59805f87522d04c26315c5e0f453a3b02f1c26cebea5acbd7eb2bc88f5577172e53353ccab5328cf4404e2dca8ddc5f1d669c32c4710fbbdd941206a7674ad4c2fbae0b0e2e5c9e54be3e699432f0cb76505fe5b0444f6d3803b6fe063c134227f69482ab9e88b89d537c49ec113d971bf1c6d12b7fe1896d227f07156cc4c91f99c8ab815fef95d3368f335c40194d4e036617eccdd4c102b88137ee004b9c74a9e21fa38c2c0b4362eb44ff5ff71158e7077f5fe18e2c8faff704191102a6eaa4ee39e79b5492cae949a8c66f9263d4dd8ed2249859c99d7d79b0d69f817a658678c95fe43a6dc6b62f3d3b39d9d84abc4e21badbf69aea5ac230384804c3ed0af81c8780da526da55bfd950b6b8e36554a07364999b4701e7fa711bd451ac53c4e1de8010ef7d2c56424bd11de74a56af02bd01317a85b94e5f360e5112ac2500c163aab8ec20d47ac3ef7f755479a96b71604afbed1ae76e9e09b244cefb9509c82ada2c9c5d5777a22c202a9377ad1cf101a1476e9992513c12366321de1fb9b780329fac0aa3c51ebab72f4eb2c9d5a4b21959c445dce49374ff8382d261103fbe24dd001793dbaa765e72b7d20d593e9815e85e9094b94fef5c7f835af572d055fa62248356f19c6bdf2f727be3ce5ccd9f297371ff9a1a18d46c779746c3150e65d90cb88521e30865e602e1edd97ef8aa735a2459c047af581ea64164423cd70faf3602fac4d2b0562f89b4909e34143275bad74f4d261fae702a2030aa3275af4bab4316837f228e98c0b04efb3c8dfe67081cff743e4053179881fb567a9591af0d169921ccc447ac77eaec3eb4ee99e44fa6102e3555ab24d97aac56d25d34c87c1ee37abeb6ee0933168d81d6ada10c84856f9eddd15baf4b29111772a71f9f129151d17b5ae77bb7f0324858c6a7b12924a497fed34905852261cea2b834a77eea7b4a47195634ec62e9548df4cd5cdee36381d95b959213601f0522b4f8eb1ceb66e4c7d473fa5c1d345b57688bc0a0d935d7241f1c28a069e22ac0621b9c01b6ba4d2978ad1ac368ff646a63cbfcc16e383aafc9621e22f57098d6e25134c90e250d68f4704e548c173ae3b21b26921b8712217900292dda6a9e5c02b7ee016d2b35fc604f70baf999e9a3c3fa93d4e2181d0e65a273f9f09aedac56feb291b4679e84299f4c06c6759b8586801354592731238913244c81b2ecfbb30897c4bb8854f958c8b98cdda971e328bf50fc0fddc11e43f6c8e5255c0f36926244a9205cb2c5b5c97454cd43922647e48505a5687c7205dce139bf7c53454237039ad37486e34dfa269ee9c24f608c1ee8a5510afc0a784e7af94dc80a8698685d8dee15cc612d144cd3ff711154ee70a83563b66eb64a14b127ef0ce8077d29eca70f3982822534290ea3592e5242f27bc8d425f5c8af1145278eaa111f03ab4a7f04128bd38385ea27e6d4606922b93e0eac6e5ef8c07da489198d372ebd570c0b97dff7736c724e96e6b7e496e96ab4d55ba921ac26ff8bb563345587caff0af7a9a58433558db0aaa4680be3f2708f79ed3d78afdd805517f9382876f0677332925558c0e6bf8b7939449dee3e447a7cb0daf98721cd625c7026b8f0802b04fd09b52b4110520e32a6c84d479acb0f0b571d4216245c311d1b5823255fcc9affad019f1cabc520dac89ee1701afe3d22c7d4af6519eba4d8a6d1867a8832b17072e702143fe9a3709d2d61bb828406b7a81fb5fc791d9d1bb36f71eba5c29eee17d50acbcbefc7f46dce4adb86519ae0d33ecb4e274ad259d73ccc9802395fd550ffb81c9e35dd97b9883331a0be88d9242518d417bfa81fca9b65db892646b35a415547ec09af411b8dd568ff1128e0eb37c24c677ffcca819e18e4095b531fb5ce0b228216067e30fa6915801a806c2c33060e05d21fda2b7e0159a04dfdf14bae5509f71b19cb6e08344a9f0308a22fdcbf6bea7de189a308d451ac52871afaa3b4734b51040653e7cfef2f28331ebcc361e6f6af1b486f39f5512b89bcaccc84aa54dabd977eed0398242632b872e43aca54881503fba875824fc098841cb07158da3224dbe2ef5189095d1e5dc16073606db98f5a17db0008682c55c6a206636fc0fa8268554d432d34a78a3e5ee15d46c24d90c24d925bb0a62fa8cd58db5c1fb50a530107438f7b99de7ff5f8f60543f800813ba7bf952d277f99e6ef724f1fb5ae0b134856a31aa0f1034b27f5a6eb62badc61346515310fe5a6cfaa71b9e3bed03eaf5e7830b678d245de013131aa7219313d75c20b9bde72494efaa85552382af938d0279ee1aa87797eadf581bd7e92431f90da5a18870ed0278d457e2014ebf204e35e2e60a5f8faa3ab73defece45c80a2bd14f6bc624586c6060808cd8717d6c97338ca65c393a8151e130dc7e005b52262e32d23268ccba10f003662a5746814c410cfffcf3b5cc124c7814545c99f02888c82bed7923243d5cddbfd5f228737b51e9ad9fe6a7179e20e22350b444c5be72517764b53d56b4b2f5fe40d040cbea3212da985a6f5edf808acc80ac8fa064cbafe9e30ba690b8112c2c21715fbcc85d52dd8e2bac597d3f2830a2b2764c09b68cb697af3742a22650e627011fb58e56073983bf47b7d9b637b40e2c3713ed603f78dfffc4d49dfd4227a364988b4f57ead845fed029d6915e759a25a2d79db08af8a553ac23bcea344b44af3b6115699316b7a619d4ecd415c437a5154fab3ca6de13a3903679617cae4b57786a7cb7fb7da079a0759d661119fed38351d1781a5eb154440c0ae5f218750d3d8114604e1c97e3e87fc15d8e3b3ca5b913b3e281caffad88016a2f5a1cb38821c2eb7136a5b06829a25a8e1287c23c677a4f9b9c34c12ac8a800ef2b4f1911872e90e62105d4e9f97ad4471fd202c0044455767cb5c3811757fe15a447817aff8fc0fcdb60f46f9a7c9c1388082eb412ab46a1f418a1d8b8294cdd138d39ddcb953d31303164fc7d371adb36f1bc36a521c0da5ab4ee5de48656e07697fdba0a862a2c41115059e874a27acb8b3d9b557bd4503d3a4ac759bce186dc1a44f8d11a90a1a94b22502eb944a4c0ecda333a8fb0fc75d166432a368f42d3640e0f119eafd898ec285d354d32061cac83b2f4981abc4dbcff38ed48c04f4fbd7dbd0f9d27bb70d37780fc6f90915df7b071bb7c07a8431d0c6cfe8f6571544453dcc1f665a6b11150e6872a13a48fd201e90e162bba6389a30edf970a98232710d9fd9d182380ab346fd2b38e7b0e9411ab9a71ba04412a353b14e4f0f2ec14a313281e78340987f3ba6227f230124c27e620e20ecf4b5022ce579852807a2eacece9bb24fa28cad162d05d07ea76086ab8512a4e4ffefe6d1a2632aa2e7699d64d23e19e455c163c892fa43a5708b778bc1ea82d9ce592300911ae0aa5e15f4b6170e24a808616038c50ee2c5682a9d70628f555ba41503d7046a0709777dc8c8537d9cca28b91868417176d493ee481c20f0d13673673d3fb179ecfa6475b360a7c985a6e2060cdf273c273dc9313c0fac319aeb5430f770b106df17e061e60952555d64caa9e206e21b8f482b8ad82290f1ad06c6bad7d07eac79543b69ed3d951289bbe51f41d9fb1b494805dda2a4d53294ca13b0f209c2f5f87e1d0f245db88024c63d777d4e76b8ca2c645ecaa3894ddbca33e7f42d1d2c932519357e63e04373bc01287857a2f61897db68fc4333d9c5b9c09bd46244d62f17ec07013361188a26f00ffa4ee91143584f5cc39f407a1eea88a886a2bc9d10aac5553ea8bbf68539a428839da65afce98c107e643a4e3e5be02204a9d7735a9715cd93d885a9ec71fbcc357604d444b5c5f7a6c73a5f74ee5d7c260fea1934d1f02b79b9c23547a0ff44474879e263b565d108d9eb735becdd4744a4a5274018f9fb5f5a5b05d680f46699d5cb078e2ae22f09ee763fa0e2e014636ce6579940b231768124b778432f72e2968805b3d726549404f5f88a84a443694bea6f406b4c3b72cb341a0a98177a09d90065c4e24f039980b56cd4ff28bf962a450e0b0f506655ed72fb3ce14065bf6cae925c8b6fea6b339bf5963452ea45192a2d6bd3788300d88b5114909a3b2d32176c274509440394fc0f02f2b414460048d9e1cb0badc2ae049e00f2542c0f38971a2eda721d5f9e08e216f0d829cd68d7c01d720209536bc279a98dff9c1ec16ce7bb29b7407d88cc5211037291b37aa2ec628190dfed98b81a051b7584c83407ed4791b514b33bdf5cda9d7b21182c55fd176eee826b61c4f50db1319ed308dbaf88146e9dc40ca9f1632fb96300ac7b523c11c294ba46e36033116ca7e068f1107da0eb005c81727cee235d1f808463c1b04023013c34f2de13fc588176f171ddafcf99c60c4d55100f53b3a20b5363947871dcb01bb25eb93cf25203eef18991e8d75efca90725d0727260b47d9ba10dd7bf06eebf0b6e1a61bea948e19a49284dd5e60d97c2ef3ef988981708c3e017cde1c28a74be3eaf7f340ea9c00a48098daa434199fc5602546601d499a70db315ae99a04832ebde01e426a1767709c48fa76be175ea4a98e7798e0f1414632b7ce5c1b3696f645450a9b607ad8e787d7c6e2d56907bc33eaf807448bf95bf9fe6c835dcff7bad4963f38c4ab267612e032215a2803cd0e47a1c6f38f0b3e9697632ac35a8406adbc206359ce3a70f0668cb35fe31507868034b408600b33b8c6a598e82be768727359b8139c99a34c5b10e3561d93d13f0beadbdad44df561acea2924d2306e256443550a8a9c868e1e4399dd39509b127ac608f008d52bb78e26a0098a9cb77b9e21a881e880920b444275e516cfa9919e65d3546a81c95da7e780d8c20674e01ec68c9a88c4f778866d22424233f53fa350570fd510e4c4ccba81b42c97bc04e94af3f98b2006cf9ae5fc55951e260b70835797f02103110f10b87effce9e06012e6f1949a0ff87e96871a1cb7239715a661d90d7d617ed5850fb84403fe185de1b4fc4f545ff09e5f20741fbe02330cc1d751d2636fa5b1620b5b22641ff509fc5b3ce3844b5522b96104539cbcc9fecb473cac4b60508f59d090e030ee4c3a3ab8fae9112174cc48c0205f045a524eedd0f31de47ee9eee6f05818c04a9b55bf4ece38a243faf3e474a60f334e20f9210bc32e75ef3175ae5ccab55610282841744df7ebdbfd25f9c5d3e45c8b17cb880b730ef0b19828875fb6dea9313afb0078e1ade9494c7feee1b521b39793d4424115b1585c7600ebd2228a9bd45a42e1ba4c1c76f0056afb64b95a7c199c925e634d5b0c4454783f6f497656f5e1ec89d80b7f3dfb2c6fb15036f8fbe01889fa8d821cbaa607afc79dee644e9b152bdf4c501da7342d09740d9976671ded8f102e6db2bdbad4137c6353d07c62928842f58a1ff1be61f5adb280cfd8a19aed81a96f9c3d54cb7f686b14f05dd1431c4bb279700f03bab229b696597640e3a49218edf6d8fbb811800b25310ad93c0b0f51b09e57876d77cfd13e2b00aca86291db63ba8443bbe49223a88be21a53e6612cd8152ee044803881a9dffb72344132152815d8773ab550e166384aef86ba5d085d71097d6e2dd68ecd6d6805c0e3bda86158390c097b0bf0099580000e4377e014609b921bca7d5f44660f47e0ba47308111a265533d889492dc077a1d8708d85d9dc65277766e0b7a6db019181630e56642978112ccbabc88316be830bb3aec64c32292e1706862bc84be8a78abeaf8b3d3b98ff02abfd7bb31792136e4e08190ba4288126e4a57e5b26b7e933233fdfa5661d3b677caa32deae9491a0e8a1b4f4884121fd40cc34659e511b5f1764ba3869c3a29c609ca95adb1fb9f77fc263a969fdfa6126fe218c91c1a73978c907032e9844bb52c20e8f807428f64258380106a057222a6a3a64b2c12303e3dbf0182eaed2a0924b21a13c6bfd6c18db74ed7490ba92640bb9edc9af0ed2b397ea201d6c384798fffdc78d92d2b633d07ae9e5ba4607e9b45bc9b57913a15dfe283f07096a842e0efaa808aa9ec6f1aec88ac65e84f6f2ed0fed8ced5d305fd784108ebea61214d74ee02d5e3c398902dbc65c8fb218d30709b3278f525c54ba012baefcbe7434353dd98834f71cd45ded711829e28aab2166644f7c6a457181065f9971722287e5c75adc96cae31819a48556b2a176434fa137a9cd53334c0181d66d079982759bee99ebddc4dba39e4f35b84826aaa424458c57c28444350053fc1c9e426fb735868b1974ccf4f6518ea6a272df105882475abcde4de227de0229ed1e4d020a8505a3fa8e21748e26342ffb4071a1c8649456a8ce9406344f99e56a3d110eb80b32e2ba5c26e0fe3d016b70a604239e59f7a9952ea5ed40270e07d648fbee50a4e7104ba17439930510bbf83236dceb5190eebc0a6b79eb99eb8390d7aba7580d3b7c433e94bd0077df3572cc060be2318153d0bf71f9fae3e4b7701e3eb1a52cd0edc13b7cf8a0961afd2c4dbc0f5cfc4b975cdc707f081cf265a710c1b68c6a9f07305af9cc9f5b1263235a34e586bb1a7f31299cdfaa83b0fce234fb8c82049fdc71d78787dfc9dd487052e46b6dfd7690d9bce247e6c8fad0834ee7b0df15220d5bffd2ba6082ba8f6ab1ab498f5cb37b06b082113b79d249cc81d1e9fe7de075565f9aa27341c0216717ccb17c3639b9109c95d72b4343917b53977f2b0baab1596a1b526db8c3986441173ae27b1f15e64562b7ea17e058efeff412cc6160e8357e785e371f17812954350cd1739079121934cca83910520f69df3ca739530cfa36e10c8c4880bbb55bacba515291684338c805df9c117334942e0e3eb671f219ee22f1ef651e12dc8c2451d6401a210f30ede7f15e37940e5a21a67f5774a05980f8ed32b4face018d9e3dfc03a4b596d89bf5524e25cb686f06b25e835c01be43f4dfeb0e0841d2eb072accc26122ad115465e02e9cfc86562e957f750631bae26eaad962b55c2678caa5c6deb81f3bb12c574210f1acdff73cecfdde0a39db03c058116629a4558fa4992a0eb88f02002fae04244ba9bf17cc08906134649b194018f17bc95ee4c772fd1325e31c0b3f318e7525b19191c3ba9a9aa9e6bc80ed27b51805645953b1ff3c674b110f658dbbd3d8a97ce1514867b6ab20ad8625b70d342955023018171b013478d0b610a306399c4f7989d56bb7482a3a28bd3f3b55516c2002065de59a8bed1b10eaaf4abc0176b478c1e576734549fe185457589c57a2d39f3a7ba4e9e66ab32532eef82e5bf80f9585cca5422888dad240266f938e4a49888b24446e7cf42275e72ddbca377e0a102d6120136e6752f6b2bf2c3c5312f47fb2e678b3081a90bdee9060cfce12bc70fec16ed7526ec339f2716ccc827c42b4705ba1e4156db5a9051128d47c3ab73c7d5ed2b8d902a4885a49c395f8db9f5529c05be93311120181fddba14126a03d9ba12e8a8389956687d13a8b95b49e297d02cae01c4a6acbbbe1d59baa26ba0e5371d2b53ea0a600e6add41b6f64fd91d816fde115aa715019d105536ce78981adb49f0c8dad9223229a5144acbb4aad089e1220af4f33a5aad647d54127154d53b5c0f922453e6ee4b1a3d229953209ae6152e10164a2c5c08d965d8d327cda24fe5fb2a6235746881ad15a164cbb8de1730b454fcb3ec5079194cf694d224da933857978617a45a309da26f7999e06ffbdc25308918291d8c48063833250cbb5483d74f8cc1342d372371168954b51a471512b32ff504f260d21d83605e43585723bab69333341799eacf37e9f2878cf3b5c6054547164a75ebe6378672e6432cfc7e8b34419cc72ddce61bc2e5f3761bbdabc5b34c0f7ce10d258decbc2c42bef96ecc016020bafab552d94a2fd9840dcc1bda9f20e37b803a6eb15bb376d59f1d6ca8bfe3332d6ee7f28616c22d92e534d9aab2568cdfa8a56709b1f71676623bd5c2bb670f743b637a8ce599e8046aaf6363e55f2236a82b8761f0b951d19828ea23694dcc9e9c660c0f1494f833ee9ebb82a1bb34a32d5950b645fd7b10a28e3fc5f3bf2f507020fd1cf1620926ac82bd2d856d6a8838215ddfaa0cd08a7f5b51018bc7673fe750ac7ad6416df27164412eb7e10c0dea6f71092f6d2fcbf6e5431790a4f5b336d5f25c1bc529ce9e1b7ae8660a8fcdc927d4de21c4d759209d97838e7c0372b64f901820f1ae18982123fe49cb6fd90ed865055b663e02c60b20f7cc38131fc0ccaa109c9eb515b10955896a9541864205a0219b02d4b7c5792a772f2a4402aa4d3b2aaf1025d8d091ab12cee3fc6821b1946b5340a88387b71479ca5528f14b03064293a68c8c87084851dd8bf65c0b976827cf2c38984907bfc55f2cd93cdcd58b8c564a2b32dc522525551adba2bda8ec3aac2e7119a1879035f35eeb4a0c05b2d018b0d36dcc16d9707e6ab93e6e82dc4576acfddc2068850eb415015b6374434856bb9a30dcdd0691ecb6fee349667050262f9975cd718537b2abe0311d7ab25bd954a377145712e95f6800da866b61fbd3d049ab99455bf83ccd9207de6200d5f5c2cf7cc1cc8136a9d9f994830c0fbb86671155ca451079867237519bed9c5aa9718aed1c6e794373ef68d33b5259a49c3d96a5458bb0e9ce5a0cb98c204f06e8367cd7420a7c902056ed0f0ec7b93307e4e927e754bbcb84365fb24f953c0200b6020a9c2ea9a2f987c6c9e80f0da56461c6019e4c4fec01d6a9a4f70e3832baf290c5d80dddcc0a102ccc3005499f81e5135abeaaff2a40671458e15e3a81196d8f578e24e26f28121e758d6146e393cc4dd3c43be01d4b62f5629c947e6a70c0da0a45ff9163dbadc03057105b46abad11db7c0988958037bd437fb91fa61abe08998862f1dafed53db7ffc9ef13ae2724224d337bbca48ab817ba5f920a3a03418f7c8e60acc7d1bdb94f6e44d747bd0ec56a8614043a6ed30800c914807e3020173afa580968a09762791d0b90230628e02af5314d1741091b0fe17b04e9b6a6d7c62db661bf55264c75eb92891c4d9f51adf5c0fe47777b3fb90d291dd490c059edce9d20161f1f2448d124ec98bf53cfcc9854adbb5521e6cdf0c51835a5a931288da758269fd15b657c0b31697c24f2c286141564e735eded7d8615af2893c7a345a0422f2481e44552b156ab793c9e867d718990ea056418047d7e868a435462c2857a2e7b6149d1e46d834e1898e6fb8fd483962981b1226f213acaf20d758c59f171dbf74661c324de5ca4fce748972ee7147ec0938592359afde74b3be78231001fa065563b911b73604b939f8b1a3ff43b65fa417aecc1012ae5f511fd845bad91bd6b49472fe2ee314870046adfc2e79e9ed6a98ef553d2f83ca8a0b8796ca741a2a4e441897e2116c8fe84907ce9c4cb52d9e60c45330969cb1fb9f3510064b425605313a35362e7f9f5e1e466b5d96669a815f158f14294fc634344984e60787346eca1df173c00383de39c6a7538998a20370176f5a82b47a24632e4cb4e1598fe03ec3232ec5a9740546c07638da69f4783b031c11ca84673091ae0771aa031bb5d962d1091d663ca678a5a6b4d80e22189fe736825a5e01dd24c6eb4aaadb608b14ec03425603e33ef798a2c50b813fe3a87a1129140e1c0df6b0b61af1e2a5f52fae3c1effd67a013b3bdfd0212bcf07fae45e180ecc626bd0fc22acb84d6d2ccd9ad90f7c57d247593bfb440b184999990cbfb5b9763e2cc6099373088e67b8b8577a8f89f3d703b9319ff714f62342b2993ec81db60cb5635addb088249fe192ea2954b00ed0ac4494050aeb88cc196109bb87c4220e241752a8d26f97365a8792cda735bc3f6081cd56ca9a561f8a28c5a876aeb1729934f19f71377ee17fb83d2e33a99e27123c6efc85d04d1545889452b3fcbddb1c66c15bd3916cd730cd6d90a5cde97b8506a17aace9e35f9ad84027436ee0e03ae02025e800ba5864ae68ff4c8d2e9c31d0667e7b290946bdac6e9b7c248b5f4450a4b3db6c4cfee4d8fda1d9ca783eaa9c6bca600aee7d930adcd5c0711244f078374bda6ea47b4fbfa81845e5536429141201c1c605ee75c1545a48074316ca384e6938313f7e4a4bee086e472e36a0349eb2ead70005bb8489fddb5709174ccd05e428c5b31292a6293be6aa4659e0f81ab6eaebe63581f25c610e773ac266f95d617034c654ad7e60ade9d793cdde2c6c7150b2d6044bcad73cda8a473520bd041a3be83b4343aa028b3b02c0bca7905725a15b9e379210f778c3ce3203804ab09414030f782e91821129b333541e2674b2b8e55c8ef72d9c806798c77b44a050e6b64236a55eb8c0b63318000df409f9daaba074a753eb56df52c79f5231b0dc5d738ca0f19cd92a39e128ba787a29e83b50de15b6ab509b817b442abb7668e5f4336c91567139292e7ff0b60e5d8a7c376a3743b8f9466de73c48ac332a5c11d7cdc005a0532804ed5a84593dddfce520f41b1589312535e557b3d1081f2d922d206727b3c8955c2909e0feb0acdb39845368d770b6a2b5c8597d11feae810fc01aefba41c7b7fb4744fa00ae557cceb96878b0d646895a82afe8d63c140694a901cd969f95b7e856e96b8d6f6317b97a99716aa26faebecb7f04b4505e51c34bf34899df1a90ecb8c33c05f8563d2069c5633d21d0462bb072782378d18a8485a74f27ce5befa570688417c24248892d353bf46d8c5e93be7774228d5829f4e93b6fe1893ee07071e0ae50db5dee2940d1faf4f872624aaed2f29d9e2453aa045918a0ce7a0168b14aa370ff5a3c9bb7dea8437a2bed39e410e9310a503eaeac5fc6ce3e84badb64b50bd0afb6039669d71292a7bb682ba47aed37ec16949efaa58ee604c3e31b74f3564049fb3ca50e10d40297c77d5a08d37c7df62e7b5a5249811c9c1e74f824a4073121c5961840324c33be30dfaf3682fc6f43a68174379209af03846e64c2a1c62f5fb21eda84837c50284fd389e0c42dae4f6d69919e8e4960e2428cc2da2a22bc066f496753e72a134d88f8ab46e37edbd278d228bbcb3f4bb388549de2ef746b1c6a7c3e5290a49f96d85608a583996b25e60a9284dcc0e48078394316349cf2e347e2e084e7926366855c97286514614612da0a1b337f5a050010a19b855852f32064f071624a03a29cb5575769817d588477584663dda2047b6999e28c8de5a6224a64021d96f5bd9a502742834af2047d164fa09927d1c1cf551fe6070285a9be888999fbc5a15a5dd105f09cd30250f90dfcc8bc4a6ae36cec8141052d16c616bf0d58face3455172ae43bd003b079e05aea0f1d90454566134ebaf2cf69153e0ca38e0f28c8a7d4e99f4ae5570747bede8b02c8319d5eaa3a8e947a5a5c31b989f17c8caefb2ff331eecb6b90a18b00a872437957a8472802a90b2800dd957314d565b85f62b449f8f67a7082d96a3e46ee70bae9f41b909662178573083075de851a869256da034f1cff29ce605ce9aec7b6e3065fcb3c93363cf20f6bb354e6e06fcfb0fb764f3e68b70d1074b203cde63b6e5a50ef153ec79f29e6d40c80686fbba6ab185553bd743b1661876ab650e60d76665d159e3209dd9106646b2dcae1e490176255ae5a031e6fe087f628b9b9cfae5710aee80adbd831b3a641e0b20f7b0f9b9033bedb16d807aefa38f5ce28fed307bccc071def3663e758b07920988f832f3b82bdb4fb0ae7631ec2e6771aee5d77611d591fc5cd541836e20a1268f1b648935c949b1305c1f7a8a839c143e882e7064949b2805af97db067b607b14fc37f389b56ce9e3402dbac35bb5d0e0ebdb3ed0631fccdbfdee3dcc9be4f2b2a3ea7f84dba22e6f647c60509ee7104c456b83435bfd8a889b4451117f9e70c4826103ec542c142e4d5a02d781e7c381530b4e1008af96913c0219771381c09aad1830f7833fa1a08b1551fc57b954fd3c68e6e0b72e083090a5298d6a255f3b6749397ef2ca95893c1eadce08cb13407bbfbecda46b873f6a1700cedec08f830dd031c9b03cf0d46789c33e78e878373d200e3cb883f4a1ac244fe174e2bb7044a8cf94158600987bac4c88c151327cb224ae0cb05e2264344883a1deb1888c94256f27acf9a07246d1c4246c67ecc60e41d03e4c41cb1f33e38a39c33f163481d9bbdec34268f2057968404ab42ce94b0176074a9357226d8f396deb1510ad776e2d970a682796749b7b0b74ed66cec0e4feb22a569cdf4d8aec99fa8936b985203c3574c0f4d0eee041f25b6ea0c6d3c591a0b81b1e937dc6e62c67bc7ae9a627c37dc1f80b65657eb03b1013cf1bb6a817caf7ba277c371713556fca618e596aaf2751044416e999a9df65ff6c1768ab51176b3c50ba8a7d1030da56ee8d53f820fb276d5fcb3e014cca7aedbd66ad5d7a5b88179938381cb7fe4259de7acd7117ece63a3e25f76445f661ed03a8fafb7408b98c43f3675854c2ad9477de2ba7fa437b3d382a3a8262569ecec1692712e39b9dad67cdfaf533ac64fe316fc86151462628beb9c32f902fd32df6062460c80f7ea4ec3135f8636722a802fa5ef13416b9f6e04714b2230cfa2fe37a1105decc2ccbf1a9e495aed3614235e7daea635383198b27bf1631a4ae3d151015c1512704655d3cf97307a4ac612c56b0262161a908d2fab7683d2355629727adb25d8b52e76fca6e684c2c14ff3117902848c1b42e9dc23fd708c5b928819c030525ed45f1a3b7623b1d387c95c3e5af1940775bfadc8ce2b533c189b83514f5a0650402a95ed2a2a2ca5d6b3d46f10fdfaf0b407a79c2809b8b81041d7d4964251fc2e5f4fc1af34e66caf82f4864d2f61254468185f0300530132d0e003080af5caf801e6e4715d80419a3a486a19a817cf0dfd7af4d80407234841f5dc2db86b3377e73876b1b33eef2145f92fa3dc343eefe02b2984d10ce07069a7e503febcff834f45f7a31d3ca66f7779ecd43ebb4c7c6be4b12f94ae1bb593a17dff9c276e05e9e60c0b2c04d28abbca44e53b5d0e6949167a77283155a20929876e266db6e17f8282f9bbf84cef9b8dea88c38af58d919892617044bba51d20a9534a5d251f2dfbce27d62034e040b0212480d1a61d2a2d6ea7c8da9c028c8da6c893f6c6ef96d1d72653527a998766a11bc20fbc7042a3afaad81e8cfe572699defcf83f0247918ad4da2c1cf702930e2c22c9da491517c28f19f7cf50d6cd6129da58c3f7ea649e75558124c405ed956abdfc4892c22bd78c2a3da204782f878c931317df8a6d53cf1cc36c609116b82b1c299cfa3db033c63c69be7e3cbdcdd415c0bac43b6c49c8f159fa7008013e62200f0ee5cc74faef7e91ebb4cf6b8711fcd39a19119b16130bf0cdcb5867031b18b65adf1a26b99383c7f9120e2350e58d68a0c7828ea205de67aeaf9376d9833d1298e7c6487c2dfcbf42a53aa0a0f99ed410fe26f3e4e5d24fadeaef8b4b80e9428c06f2047845201ed7cf6db84fc93d9a294a9587a8129d60b354d84e400835e7353c2899b029240e0afadd8c9a05bf2677f492f50e78d493e6e97b9c54042b418bb54c293c5492d5e050f62197292d1dac08ccb4e773fc4bf11775e815f8524ec7c7535c87dacbb5b27a4ac24684863b04519691cc915594b038a1b341d8330658d7102a224db2d5ecf49413593855105fb89fc635e447e848a58134c0e36a5412ad69d5957f1bc5ceb2d1edb34ac2df0c3430e79ad9fbae694bd1a6ee41bb4510a57531e672401c082a40b995a33bbc0282cbe27b49abce90c059b7c5be86ea96e2c048e6f16e8bee66361db8a0e21e8225c025d08cd3416e4adfb0492f5089ce506c21853efbac077e316c11c894d09fd06ed7311011311bf5650c282801c6c711030de0fa0c42b683c627da4b650e36224394253e457de767572953bf919f23b904b941e238364c737fe0ecb886babdc69680cdc59529cd0a94ebe4e0b77c9364b3ba54b6f5f508c1b3e4836f07dcb985c0f4b679d937c219c53f800af589918b77d7e896da010e8efde020d0c84fcd85537a7682d3925c81e15bb21403c48cf6389b4422ef9eca2ffdf2b44c0c6c8fb6222506922cb5d14a2eebc67ce634550332e231bf29e35b2fb14209edd16c738821ab91dc682534df8a6815ba338f35b2813c85d2e58387b16be1240a174b0e19223a6a93c1e494a2f33f8a604930811f4b20b9de6d86f928f3c2afe6366d250ef27dfc371fdb7e321c852fdfb0bb6e0e3d754bc2006c0cf9f5ad44a75199068d3aacd6610979ad0d2336acbbc9671dc484b4d53cc0bb0f986e54d3a13760696f2ae2b0e4dc92a52570f2c014d2a4982871474ec4fd1ded035da6ed4369213b63a5861a3df30854679b2c0b96e2b0c4ef1aafd85fcd94c47c5d583c408ac392e735c04509514ee2ee4ca3b290d8879926f20294e2b0c495d577e63c1e822f743c6c4bd2d385662f5a1a872555821ef24844cf4cd84ec0f3d5b66e5d46ba814cf464155b054e0f0fa8f1b1d11780685c6edab535f11ccfbd1eb58e71b9455f8891f215d282b200ff4fe15ef658b1d57f365e3e905b9fecd086b1407e7735507f9c3309b943e1964b5d1ba3ccf0304a3236615c6918e7c9c6cd088dff0076bd07b8cb05da31bb8e7d53be1a3a2f35149d32a3a3b7afd4ef417ef850de8c7cdd2d6f5eb4aad603ecfb00716e9dbd15a52a43066ec7d129ecdb834e23ebefe89dea48fff861303f7b6ff2f2e465cae8b104f037df9fa4043f5562d95cea51484b8944dcff3c728930c801f69856713ecb365d0701ad76051e8204cafcb50add00f9e0d6d0c76a1c3b03b55192d3f9759391748d4f4c136463da8c2734e17422eea51234e4d213c18d3de89db53387a3fcbb3852218f462fe48ec2ff32e8b572659a52b1e7d6e50d967b6aef649f2409a06fc7c05a015326a9aebac06fe839a5ab9e9bc14928910cc8b6379eb354a78db5ed94443c163dd9c3def17870311666446c15a89292e92f04d25bf78ab9503b7df02688a6e902c75b51ea03248c0675ea4ec5ffe5c63b5f6e8ec4f6c21daec248349455f26224d5a6282260d6fbc5249cdcbfd1f902d1aa39b5ed9932375ccb9ccbac28b12c13edfb67949da00f50cdda7d3f0f04804234762547d20c40a0bbd9ba62a49d822048d279ce5f85705da7b85fa24e30153dca19a90cbacb06d9c5c41a633bd65e008fbc6e25d161cd6916195e719146f285b42c313c2964135e064c03a0a8000c50e0c0b638b752aa689eba4aaed8a2fe24493da19dc35a1fd6d7a19e17c82836b2421d4133646315b017b567c9a618dcd4282345032b1649e5cf0c451267909f03b62e278ded470cd43dcda5649625fc33d1c42f0259a30c0ebe838e9a0f4b9d128da068734e25ab3dc09ca0a4cfd6bd9e48b821755c4f5738c96f20e6984e56420778cd13252cb973c74426720c19bc4334d8aae5a5dce625f06d722e67a93dd6f6cd486a2babbde889e32beefcc33fb690b57501d0134e68342e63738ecb3e0de7fb46e5adffccf84b9f7981a9d3de575a9f8bca96517041a8d937c6e5b96ec1dfd634110a5cda48e498b5a78ecb61a2a4464a22719cc9c4ab02298c4a60e5c9eba5917b757d30032a7b6418b6a56045f8cda0d251a0b47912064127e3b74e99c57893359f819708763f1ac698be9f7ea45986311a59999a4b497f00d2658a305133581c99238c7247b0251ab4c5a046ef8b9130feff03cef07fe6e82c3c4d64e126bc5c71422c916da7896f2f9a8877406a62c4089e07987980fdc159f624d6ec396893d000039a4ce7f0594c42cf39cde13b572f6a64f551a91c7088319c74b9d28a7505be9fbcf28d55880bc4377ba34885e1135cfece59396ef3cbe442d99b7992472e89c3ae619048969593ad102b859885742928261329f617c1f9a59d8a8a1a3249130a1c3c94a0e1be8b8bbc80a55eb314c6b8fca99805ac2827e3958853097016010037e731a27d969d4837977109a7aee5acd298305be2a57e78db7b98fd29c050866f8351db498070400d1f75fea1216b6bd85b61061f9956886eb4a1f404cb22a728127a4c8d78e69011c66e44270029af75cb14708ac70e75915bb8d238afeebc268f241a1989cb343d1d181805233b706b0f383b2222890fefbc80334261324cdf22ea9c63f8b659126fb8553c31311138b1a6e959fe5acf600567ee4369883721b4e80d90af4cdc1dd293f938b98c6009481c0ccc1f4843120227527dd00b7f1c7df930203b463f25034bbe035a96d79b1f2908fd5f6bf366aea321e97ce642e5a025ce8d77b39ade9a39a46a5e12b2f3c44bbc5b5f6297f1a3c2a4272a739f2229f9e2fe84fe2609e8e1ab97091e71ff21f3e3856515d0888795425f269650342ea3df80c67d2c678a5be24ce30392c64dce50c71c9e0f49145b7e6033af2c0820fdca07b04d53d90fe235efb6c054237fe620b67652f218b2f9a2dfc0fe4ac199b65bffbf11583d46286474a4d726cb3d6f3efa0327d054a3cebbe3725a4654386faaa0536a36163d6b0b74b0c215bc9150be753600387e664456ff17436986452f4469fd03aa6124e4abe7b974bad040a0f8b35a8c88da98e475cf4832bf71f648eaf68bb88a6029c373e08bdf043452a5abfcc9c37e82468eda73d7e9fb5aa18957b7189bf84b1dfd400f94390cab8e1a77b938205393464481b88c54e28865b0ed0e6c75033fd6097748c8b38287c801541c4c29192d416e39e5208d2da8a00538bc9a654685da6799d022bade6a866d74bd41cd0de98f4a8da8e8002c8421dd05da08113b28615b68168530a79799453721c7065b4f8d49560e908373d5e7f34e112d3387323700f5bf8807b5e57ecaaad47f663fa44e849e9a8862c9757865791c97ab6662a1d6c248cc70389a2b351cf3d149c71a6ea3b2a635c6a3ddb243b4bb2622b75ad1fbf117d4ee21e07db3e6f37c1d61a237dca4dc2396774ef69aefdbe002175ff86161430de034c802c9aa86b227e8a6ba3a96a0ec4c906ef5c5c576fce083219d8e765a212c2adeb74bc79a8bdd59ac5b55e5894d8b5658aa4d061a675ad201cd13caca7c4b27f24c5a245599f855734d2b272251f3888d26184b5c127d3d356a0d763595ac100b081a834fe4ec20b849d59ba6f5961fded27b30a15cc4a022251258da5df25954df1027b80eba515e1990bfea6a4ee228ed4dcb69c39ca47111913cfcd99aae6df8784b88b6598343dae2b7a826ce98f71f90a796a382eae88f16d46f162a23eac9d423e1e2b16151d0b05ffd731c601f1af9ffd3bfc064f98a32e35efc6e3fad756ce46dec4899f66c090d4139c43f66a370e61183f6ee0feee0a0b2613a2fedf7cd65badeac6d23cd9c27f4ded8940141104f81e4f422f6025aca5f024a3d016170a2c325366b7117fa1ce0af85f53c7002072d22c37c92f708f1bc32de98723bfec26ed8fa328ed8f49e4fe939121b779304ddb430370182c24df4be4dfecef7a35893a2054b1b1ff78b8919ff6250a23ce1e1530ce1b88e9b01e019c7ad07a64ecb758fdc1c5cd906c78bdd7b10de453839c0c8281c135c14be3a1af4ad904822a1af63b0d162268317b29760811a099f066dbf85b9b2f262ba5e922614ea63c68c9287c3bdf05f4352f3207c73193da6f22c63500659dd313cbb017f6a421ec38f1a67a2625366109de50c746d0b825e3d67696405dc6f1c31630e00ef86bd9f7b13440e02ae2c49da91f17a28eb1502b5dcb3bfae9e7e9800594f01e615f6d50f15693a41fbead2bf4500ead0c352ea46b9dcd17d512223393f9c4e7da660b27ac8013da763dcde938515efbdfa6839a8e149de287e3ec1526b944f80f3b1970ad68acdcac4f595dbce3b4edecd83e2fc3c897f09bf09f73304fa56473b398e99cc7d7420a03b83c39d262e9ce6f45574904c16385f46e3c1c742307e6f8d1842f1d4586433442a11ef90ce4fb3e4e8c222981c752502913f42639a15dde86c9b99bcfab25a13eb2f72526a183d6b7fed40a0098156aade6e87e89aef13ac03140b2a7536a76571c51715e97c70682e92ca9c1490c4f1b27f7925e0b8af745294fbbdec33ce750e3352f16e8ab56211a3b44e3127b2080b0fd89418dc9cbd525ba5ce5002d213def2782a9c5e9653568efaec602b0c6ed9b6ed2dc4076a241486782113e376037b1d205fa9244ec1a9d71fa1815d1a0b548916ef3d8979beeb1e3cefedab402ed67db1279e0668c7095452b9be3246de5dbee1d0357d7dea7e0b9534a67b939cf8f75825b1ba3f834ab3b1a82473c05139160e4dd69b2616f82927930358f7aff61d081b7cc704f50d62189fb6a0150ada8c41922bec42c121033358f4a7aa040768d3e6ab92c42685e6a50a5bb7089e59585651ae43ab0110db310cfa9524d90ea7195c6e8e3480a2279a26572278b1092a74c0bb279fe8bddf17409e714b7b2297e865700c1d644cfa4b7c7ca200f60912827a4953a88046f7c0f1a9fd7ce80d7f20ab17194f3c8a670085e1d189e8152e151b04d4439bec81261c017ad6064678055089a8b0176f237730dd17bde55a1bdc35a96668abe78b6d2ac2912de5f063b17e49dbf34f0c178ed81cba9f986914b46ccd5023c70db9205d8e07fc4ccb31be44ac88141a5d0bb89f9e2237f9806424cc23e2d4487dc9c99dd8102b0211b6221e20ee7227122e74c64181f2c677a198b908e61bc29368d100c97c95c71e8b6da2e2fcf45d1a83dfab1647d2f2d7682f21f65700ba6f5078a938ea7f5cbf7ee45d1c795e3ccd94923df3e31a236ae7fbfb4435e275c8434a6a1af10e4bfb63bedb3826a48adb21586ce9d3728a743a11511334fa1f61eaf431cc4ba2896e57105244f508eed7b49cb34a2aabbc0bd6283f23dcdc36a28cd28e526593e99c322392cf00a3f1e21d779f10217865864713e08334d9ddd34c5cd1a5055fa64379b72127b79ba5a3f60e9b2516dc26f1382f34a96d3ba742ef04082b0043799498e07de278fbf19451dfcb378657d1c6df4fa6e74fb9157ad287ebbc4f52593cce3bc61fbe648860381f35fa3d92de437d48993fecbfe8f507f3fbd017605aa0c5673facf249bc6ad5b0daeaf8cbf7ff6ab16ce66720a2a44f7db5421b5d7f6bf8449bd8adce853205d3896594be02a5fbc2cbdb50d7315b11c7df3f9d1709c3e457415461bf1f9816c6b5c1c83fc76ac010f9b741e8bf0301d2160bd59234e8cb2b737d4087de22a55d80f04860f9c2a110312d1b3028f66f380df4e684c6c8280511065accb3d4e215ec2542fc632f4f08aab82d2a8eef7ff78967421b0ec19c90d2937d6e209d0318414e33f4890c40fdcffb9a27094bcfa35ebdf607ab9342678279b21fca4f7f4355cbe1ff4de91bc500f80e0807fc4466e1e6f258e8a47727f4574fa982b29ec616a43b1b97957b12d14db8c742af0340c4ecc82ac69eab2ce8fe6858b8fd5d073f66a994050a4f7110188698d355119454f8c79460709565976014370b25acd8a9f11714d01a50ab805886384ca16022065479c915c6d7eb816e6af7b99618cefb716e2d9889489eb6e2f28afdcc14ae8508d922b5b6bd1464b59b1057836d9585ced5ef2183e3a0cf0195f9c9551b8017d368bd8a2f1d1f82c9cd35cc90668cd1dd7317d066946c475bc1d51eaae65066194550000ad372baa2b880625fc2f426f036923b86c113b5bb2a256a447ea77a7aa2991536c423a330d0c758ab36c7bf2bba71d2cc43a76c04f5bb5c5e3dedd7c12f1e73231018177503eb45c9cc38c563bbe40ca8416900503c79d53d8d82f44490af414c849d9349ae42a8126cb2d040a8cb08b703696cb083409d81bc404ab19f260057c33b30d35368e61415f0f6f09aeb26e84b73351841f1d0c52bae47955dbca4a85f8ff98c2fb74ed08220bae0384081352a59298355a2f6f61b0a232048b03e0d267f0260941e6a283661f3b8585371c267023afe8fdbbdfb1293368f101ddb17a0ca7b9fac82183608a7652e39bcb8b59522ba6df813740037c639df81c5479ec8ae65f6510b1792b8d45cc3a5b168042a0e05493aae69b82ce89521e666a653f8bf8402bf2e7595bb4d1daccd216726184138710483e40eb8e74408752c79d08f17ba089640b98669c9d509c4613a52a8fe3c81b4245b19170a2bd0558fc734589df664ae62e2b1596593871d1c14539225d7e0a12b63e04ac4811dcecf95156a4a5766cb0a9e20833607c785f30ffd9ed931b432669948470117172929ee0f073b1e8bf4cde4daf4d8b4a45e26dd9c2410aeba9b08ca3d38268bfc9a450d04c127dd347d8c7a92b7e16be785000de369ba0911796193122bc74184f62922e679e3e89b83a62fa891c5f10cb9f1506d8c18c94a09a3acf0d713cc336c855eb46409fec463d0f9126a101a419deeda53bc8dfb415885541874bb16a7446361d62cd639e8232bd92d61c60356925c96f41f103048e9cf79aa5b9d11e93fbccef538f56e49867efb5c4f751d6b173b6e210c8039ccadf8a9c47c5d8f36b5c64f2f467428a833f87b0c4cd83775de45b87d7f937178c577b17b2fb573c07c9ff5527f3456030a3026992d096cd88a5700e7a1c42a6699ea13c6a92460244bda9178310f6656b1c69c656415752e1ea1a842b4046a649384fc6d6000db4a3b011273dcf5ec7b7f316c9271ea843d7a3961a439064703815f7e3a401f269ed8ddb1bab90157650542c02436c3271093cf3af5127a3b5520648f64d60b30521b8c077c7f3cdabf8ae3c91c0e8a07c620ec90410f5d2b60da632c39e608ccfcb1d1603c0037f3783c44664dc91d0f9a6504e8d2ae6be1c4dd3df7d78740d9638dd59d2a3ea61eadb219774f630d169ba402dd026127fa16121664ee0fe6b6d807e0f857123a913023514a5e700f4ae4387f7c70c3a6c1784a459729de554a7011004c4e89a7be259248c02c3b80e2b14ebc00ae4472538c0fee7e3da913fa73cd6522498e31658825cc448a2267550e76a23efb86f1f21dc6655b1fc26ef18bcb2f3cb4c5d2dded5f5fbc20cd9db7383cc71318da43dc9f30b72f7ea6ea8546e05db1e28683d72c8798f2bb0875d02f35a2d303b26c72a97a7ab5561a6eab92025e85a4b80cfcd5c0c00fa4b831fe12f4da8d874ed434a84bb3d1fe92711cc79b2bf4c4b23aee08faf239f18ddda7bd8cd9b173751d5e9586686ae82b0cea682ee7b9f5d74a03c2011e0d9e0e2af53a6d4a6d0abb692de70ee7be39557710e1c9dc4f657b1d9769103f242eab355c59089fd573220870e0300ee91ae4437f47d8c4b6014419c687746514d82a83a6fb0b0cff1bbcdfdedda33d2ced1f228a6514b400956be971c17aa0ef1bd749a51f00fe0e6f24b0e888c91c4567c9168adbb628f63ac335d180462e6992a8040d6d60ad8c57bfce2d6248f8ed60828614d817762b4f4f62d553ceaaa17b1a266adc7fff0d4d412eacb739c16e68f508d9000f2a56339a5bd89eb16ea0815ae93347cdd09c327ab602af4f1f94a5b411ee133d31e2ff149afb6bc3081f2743beb1b8392510d4510a45b9dee80cfbb6fd3c2ab8a57fede921bc3eabbd83737ca0086c343cbe23eb6f8e499e4022e5f50a860eb377f82557f11bd7367123abfa96873e8e8bdea8f56ce37e15730c63e7435637d2c03a7d553f32583a4841cc8478ad7486bd48d0906c0c330d09277c94c4927e89e185e8e067cc68c205d44914570af084397c4f14972ece02c3aa821cb3c778f9327523e5a445f996593bf8036f1f09f8936969ace749d4d2944b3812e0a7a81d33bb5406699345c03afe500ed4edc87b385cd5bd2f9902774cace66c25234e96da38cdd40c0daecdeb08ebd2f51f0fc56e8ac562c20e459e8a7838be336020101fd9ad9c4e7d49456fa09c39f412d60d7cec3424c115049c76748ba7793e54431b0b131883c3d6160f3440a2d40129cb1d9e1668d4c1eb66729c822d9ffbb36a11c1d9a560066f9ed1bd964970103e1c3246b48291ed6b6d8ddc8450f4ba632b6b284730b465d338bf927eae182a974377ea4103f40f29b31725d896d54ba2aeb4a93be942626680b3e9be88845c4b9fbeebf6aae8d12dda9aa1fab58dcbb6fa2f24f0d1cfbc20c10b26b4900134b4ab4c18ff0e3a3528e8ba697448cb07991ce47f93fb1f1c2c56f846a7715df0f88808b778875b826d6e67b4ee2077f452b67db801439d976ead1b46163df770e18377974d0412263d9c7f59ea91c1a10a09d2d35a026261a06970d0f5e62863df06cd5a9d2601e340f7023db77a90b782ea2d18971585e5a3acf249c8f02374100498f6bd402217e959e58a3fbd3f9df3962eb93a818e8a3b1968c2e90c1240a1ac2f0a7f4b100a4192e4d6a9c789a70138ca587d01397371dd7218588cbd8eddb8e13fb1fd7793e1a611f2a53fb1c97d74a5f7f0e26f2311f958c6df2421eb89f9673d3ee301d470edbb702ee77e9720888f7b3f0b282e70d4aae5a4098b4e4f8ff906167f8964455a4a2119659ce3747a4d6fb86d06a7bbc3fa5790251929220d01e1c26a240ead266d6a761b6eb574f306dff937dfb72b799e0dc07ba72a7219e5c228fc1cce4ebaf13a0d231b6f8b38cb091ae0b40863f4164804cfa31637acef0c491aaa1e0568cf91f967f1041f250abc4a91e6f5615b0421c5cd56d7255ec71a8da04808c343a7748008388d4c20b9b7c15002926f1ab23b00053eb9c03e8c8b443f4ad76a67aacbee3dd957c493ada9eccd552397bf3049ade7f128a3e72de932fbd33728dddbb819a501d611214a083a46eeee74b71dfebd2ab31d9d887686bfedc5c6feec41f40e4cf0c9dac1af4e5f30f7940624027512e02f19a9968203f080d20a9c8d31682e59e8517e4a7016a9de6369caf2240c00144fe0f0e32d1a09fd7f432622193fc88882524558e2a8d0b0a5139a73040ac87cdb4af357bcad7dd3e6a527613800a2da0d812e8d092deccf94b20221ffd33ca528aa0502322e5d0dbae226c5505483c29a1ff439a5c2eea9099a39530215756d112749b8d28acefa3a862b348e1f543fedde7f851c55a0149c714b870ca452dd9b7f3d023577bd5e5c00b354ea4b0c372f5ed28cec8dccc5d210ef8033283ae50b174353fd61436bcc25e1bc9469ce4b039058e8d61f00ead8feda468afd15618016d587b0c66968c6fab7606c91cf8f863c25e9d8ab2acf21443789358489e90ea46a183c560e00b65200aea1cbd01a50dc218a50a886c495e6b2bcf29ecc7e7075b443c88cd823508451f51d4cf929499cf6911b87c8cea2ce8c07b6635b2187e8681e847a7e1c1b3db2f55ac5972da3f02732685cf371c53ca0cc45394ba744cde7a8aa60a79d701abe5b3491a03e07c4c5149cbfa8e4ebafdd7fa3b2cf1cf92af9f0e60bcb9ea55a7540334cef7ff813adce29c78e828b22354a6e144af1d48eef825e66f32ecdfd974e27e938f333cd741ddc7a02ba85c4454e0bab7ebff8df4a0be9ba7e1496e328b12cb6f50b9d81e60bc99d0a7725961c2f3f74b31068aa3df291c1290e9b2d89bd11652b50809ada92d8215e6262d5d330e1c472a4571593f7114228df9b1288f157790ce1c9090192ebff1638720b509a58985bf9ab3bf5bd2712f89e034dd15d6dd05f60b6122d070355a9f5c43d56bf27c5ad7fcf42f5cf2c3115866295cd55ec8b2762bd8d4d9d49ce42efb2348cba6b11377aec20345b0177649f8e14111a2a0cbe3274a4c011b69e931af1f4d40526c10b350108c66a4242852d4d76ea204356fd2df8e8f82913039a137b306525828258f49af9ba1966d9fd6907bcb3687839b115f249a7aa0500f17ec4f831c11f50b0d8fd614be4006b7408eec34d1c423e5eb964dc8d8601fb2cd7f705a01af427bc78fc12d4723d5ae0d043d74d1512fd92f34cf0e0e8f8718fe506c525f7947d5a18709981a1710871936ec6bdc4c077376304a451afd9933079f82126b17a0a68af052c4c02737e057b932ff5ca21e01ac1f6fc2daea40a5b3d669335d2dd83dee46a8f7846ab7a4a3b52f11b96916071f8091abc8b084f4e30bffb405bf34a9734476f4683d55f892560a7e967fb02a7d516c8089a298217370fc6651c29068da5aa851b9ca6e89526714a460c79da5d9fbb570110042d7c0fbc012d048cf6d317bfa4cdd63846c06ccfafb839d91ed699fd6baa116ce3710baae375992541542884464867ea45f88b309b6b353d69de23d4ed51b1b254f471b1754f945e6500564fdaae9b57122dd338e758ad5a66be8bc8f332da8717091d1d18a64ec926427992a35c5f29e0810fdc6e761cdacb1424979e61c1017d1770d9aeb27e605c1e0eb857d399b90054248d9de5dd425569c857d614901320b46fa85e3f02af61ed5b237483c00c788da3acfdd33b728554b49e43f3e35ae160b3bff54cfd44eaeafcda5d0fdd386ae3024b25f898e0280c86716ba6e7d49acca80bfc6d9ae2a6f7b2e1576863e3e10a1481a8f1a324475dfaaf74803da1005d164a9a054e740571a11a4f9cbb68874fed11b6276ced89d91fc1e42df7df2802931191e0138fe49f3c41299d861027186197b15142ff3907bc633c15e6b66bb07ab80bf6863fe1dfa90518b0ce0eff4829887a8dc0c00824bda431115ab3dec2215eb26bad6137065c2cc29a8335be62ee76ec51e2df4ced7010238eb779fb157801b85d86e737eb52663f86ad3d22cdaa19de634c9dac3a115274059d19ecc81e4288851c4c698da92a07ee6ff05af0a4771729290d62cc3c68c66a493eb9763d7ac464add0ca4b6c05cf737474a40975ebbdafbad40bdb5760b2b778cee9a33f88e139acfa116730724b4a3799eac29af292a1cbcbeee61167fdc57fea94f92a534a226fe30452f89aafac0554d5a40af1fc9fbb82b0652b1ea925d151d67d50c5d9fe7ecbf5ba7c8936135a4031adfed82c17137dea5f77e5c2f198e420b1fd8ac3ba3521210f04ef2cbc598c9f73a03c12e0f429a44223dcf903f610e0c919f2bf0f44fa50946800422ce400badd767ba9e2639821bf12aa575feb091c7b505dd80da65f2112440bda30f80d5267d90814a60f12ed8fa8d9c0d25ef069ebe32c36cae60d2681d80dc181ca2d3cd1245fe08b4ab55dbc4fa111fd820e48ac03c9da8f81d934a7506173e5aee824165d58c3a0d5611e8aa73474d5c22916a7f0b9e03152d669dafb209d51d05f7f953212c7e690feffdecad66a97a19f75abd2f32cd055ba1648ff5314197166819c330aa292315882a736dd068640c1aff10f571220e1d8335d0d729cd1dcef251a775551053f9a05a746cf2c4a998c04c4bd37d3561359ff752a65153404ae981e1666d514f2cc171a41774ff7eedd2db667be2b8dbd5d7a49c048c0d97201e6f6be118b46feaac62bc4be75146e02da7debe806c875d97d37c0a5dfa8b014d0ce1f77a918e0c380652d010254c047184d320eabf81f9d4de0061c787d0680ca390168f14aede3f2cc2e1446f2426142acd0e2be52632133d42fc9186157c01620a449aca7e295931ee037e9071781c15f795726e0e591f107a7f0e2cd3503b6cfbaa2374067649f191dbdc9f5d2aab04813101999b0ce54f2cd3b3106db9a43a82fbe3197a4c0b7abcf41db710be10b266882be4b927a12696c38995a57fa09499af533f128f4cdc370a303b98229bf5c1f60e84d500b9af33f732f9161d373889797a543676c9e9738b9a2053e36934878a46234569ccabb9ac51d0c972f16d32fb20f71cb5337318d97d1f3c145a8f31b334a0969c83620d805b5e8d886f875261b270df5592a3238c039cc6336ccbbab2d8582de7884549bc679f2e7501b4791fb35e61845d2b90f9c3773b0cbd146bc017c6e4d638e4e8fe3e13f9194900eb2018ce88806a35811d40f0281b418a4f6e20ce4edfe041a3c9cea7db10be6ea154c92132d697fa53ab04b304432d55c3b5aa49aa6642163b0d7813f2029579a56d2038022c2250b30ef8f82195613d9712344d25e752629835f7efef199bc49bc9bee40176d365055747149d53ee6d2c3f540d4aa45ee28bc104c1f63ce37464ebc4dbdc1a04c54f23937f43c231f8fa5747118a4f8fb78217819a157245ef942b161c3b430b7693e3b638852b8796230f74aeab38a9a0f88cb1d637241360335a58339666e202aef2b33d8443391ddc20965b195d5bde4dc4432ebb965e1a49bb9ffdd647c395a3db5fea4d245bcc5580efdb297c07306327652054a4e32732445a29e657e7955ce39effac409e69c412bdc604ed79110c7a1d4c247d7a896c361f630eb7102ff9bf36c004185263ab47cc6f2dfecd28ce0ac3b9bf47b32290e52125a515a417644a20a231063e05e3c2254b6a199e39c2462743d221fcb132752cb45b7d817a1fc940c362812c07883b80e6c42c6fc7f9c05138c2eed91666f30b61dad593b958cda767e8414d58cded5a8e7ac20680c0e732673113fbc900f746df0e3d8576083795ec9452a4d723b28c5050a261105a05d574eb969d4f03b712b91ed40b802a7af985ae28ef1bb8b46776151ba2e41c3f90c0d34f931a1a2db5d58e5d3f3ead0991256a7b6ac217b4fe1e2ac2f6f355f6a473d4b3bc6971188c71f20fc03fe675481a206c23fd0a9f9e37590579a8e23b721da080233c0da08131caa8e956b8b7c0ca657380883c97ca9443d557d0db7dcfbbea079c88a0aaf2e9fef3259db5e8807085eed4077abb05f954e8e83c9cd5b4f491fc6face21acc841d7ebf2f8163b75af76b0a0e79cba3b7bedcdfadd6295ffb377c6c65b64cbb245cb7a1c6bac59badb1fac1bf30fe19799c35529dfb84e9dc55a5e7f3df31119068c02c3ad063abe30eda0e73746ab2d264c4fecd3cd94e46b05ed9fb83c31b8fffa24c042a830a144b9314164460958e11ecb0f70bb4493fc27b8651f74877787cc55f5abb125172625ee16cd2d3880bd3239f9a9b469843461b1fbfc64fb7ac3719ddf94c0355c19498f208eda70fdb3ad0c8abc0fef27bf18a0065259be35861340b7577550194b5502a4370d632fe555cc1098cc500905b3e49bb3d267869ef508a52382f69d5f3277e05581bacb426c5eb5a63f1ec59ea1dd2510d02219158e98d9e1ea5b6cab047a39909204170cd8cd083a1d73e91517945ea003c3ae922156e4fac1f0a6b6b3e25e21d99c1e0ce606881765793044d63ac18698d7482e9d29aeff2a672e6886c507c356a4203d71e3b734ee60bd4197d947a02b18ef6309603ad2bae5f67a56b3edf59800ce5e59d08405256765e310ede2920f6fc21d85d78a8e76dfe87111582700b289562ce14e311743640a5cd63ad2d3eebda9fd2dba5a1e8fd6844c53dbfd6f1e52dbb1765ee61f73c27549002bbd7ddfdd8362156b56cb4509887aab5198fcf442ecb4380e591ded27ed42cf295f213dcdc4ef640354ded3b3548ccdb21a82ec464aa93b147c1f45118d99794cb79f87381390676e52b6207f9147e402f4b55a77bc4b863409d06d14028a8a6bec2cacf263bee494bd358ad1f1ae721eb7e4f1336564d640473f17aa5702d28e800c49ee61f3bd07c2dfb367a1935b6a28115fb3417186367606f05c16a83316bbb684ed01b4426a3f87f4708e1b983a9c569e952142eb194a7bee5bda5549755f321c1ea968c0bb40be7ec1c98571e814a85585e485253cad90166b808649dd11a798f734be11e3201df7ef0bb6c40e5aec2750a241a2c18a5c11646a8805b9744d804f5824a9b874143dfa4f6131e51a6955e23914085882228bba5275dc0aafe2d7a496bf74e86e36d0d0b7dfebecf08807caf37270e584f2131f4774e2eb2254c79b81b3a9de9b0a08f549df53fb77e43eddf5aaae9a817abc53cf08c6f9c9bf8bf27fcd9561a3c851333a218cbebea89e1077af8e2948d484837d2923362925c22794123e936de5df2793cf7160190bdd4b9b7d7716eeed16af4be4f4c660a357481080d70f74bd43e78a168f7daa3e887b693b42a62228f09fa2ba06c823b0fcf422a40eca3e39010b89c51d2df06558eb01b90ed29759a74d59a7def9247e822b686d42ebf6a40d2dd81ac06ca24b1592c2f9abb692ba20755d91b9224a7f1eeefe2fde0ed86972cca5bafd6615b3f8b8b189a99c2a86554411e41031ccc06de31670625fbe0b04ac0302a4332bf171b62390f79205725df6a14a7f4287b6b7dd9db9dbe9f2ec0cda855815e87337b987ac4726c7798a687ead64ab75d972ce0daff55c424f970f1b6ef7aa3eb02e123fcd4aa87ff6068382939b35a3dd642e04272b77ccb766e37680267f9ac91fa887653ac3093c0c31ceb3552851da5474f8bfcd6b63f992d00884f14f0b0d64517e941fdb13348c0db52645ca1d1b643a8bb24c98e32b793489ee5995cf489e81e54d280bd0b27f939f202919fbdb2ef0f28333ecde59e70c4b0111e40784eec32dbe4a86668d99180253831b1f5aa0fb577333931538e85fb412363c0e992c233d87196580446c6e3a0e9b4ca3af006295dba8181a7ca559b0d94b60528a96c4a1852e4111180bb7315a427b887cbbd5b397175c059e082e3aa3f45af30ef9da26d80dffdce66e1987a7d8fafd578bf83078daeec007d3256d14da1461d6bf746a9e83bb0d69a0f6bdede3bb1c4b99629f0054a81546f95f2c42cb91ace7c5f6094e110c0f634cf12fd89b47ca62463c6f0a30c1260f8026868828b552c481baafdfefc6b6ad6c0b98b685b037c3468e6197dfeddd71c31fbbf4033e451d821327d1310090dc9a13da0895750ada5107767866b95b4d5308cd1ba22300a62d55a48955c6cba6a09917dc4d2f29f5ab2e4a5e8b5a4849f03ee65480e43a1aa37792a17f468064da81dae738d1055b174c7572c27ad3318834c8a7ea41d91789f325321b818f997face9e54f86cd2fd3e8e810b9ef82495f52f002f39dfe79416767c7971ca78f9a5dfa22080b43c39a0caac2880450bfb676ab75c6a24afac0e36826e93aa64aea9935ab04230382ef26813dc68a112aa826867d319cda03725c5e9af791ae074da51fccd6f5c481e1d7cea928f32d62f435ebd73d76d86b35c1414587afeca427cd928b741ab4965a54f3b4f95ef449ebb4a91821396fd671ecf1ac1bfa2b13daea981c3118ed575c0f16bfd41bae96be70dbae25096ad3a41306d00e57b1136ab49308b3989365481e2f8a1c28aae369bf8278fe88ed26dd977085501d0cc146dbdef0c7da70e05c70c89e6ca7c45a55a2adf1e496ebd2c8e62b8187aa2366fcd5e016c5dd74b86a8a6ab0d96ef9ae822ff1df09562294580691d3466799d6ca6af376a274ccbdab583f97a53dfc1ed4e8aeb70638bfca8369a6e88b11255a1998591a2b473854ac02223683ef5d138384a5ffe31f551efd6b012bb6fd2f0abd841a2973a173ae256fdd28b70b033043c042f284ba651c230a13cb07c0fcd54ab4f3b7e31a1064b9ba4134a6ca4608edae5f0216b1f227f5c20d769d7a4c0e80a649a17767c5cec0dbc7e9b29121bc46da0213ef9c1d576c7d94c860eb0e5c0b8bd7f02b7b6d6d184a003d96d37f532e5917c0840fab6e3e076b22a9d144496a327f54d2f13971f9c3bc4deda09358132ca35b0f1cb0b4310481e0b9d7f6f303ef99984c92fd0074e0648b423efa6199d2d9d1374bf0c40671f9d11eeca99c03d976b50406c25b9098fa63f088871f3ba208d65b47d1607f0b56238d5760deedb6a2b8faf424709597db7a598821924a119694beb8ebed553d99d1db023ed27d5909578408d5f60b91b14194243736ca311b5f9069a5dad726c24db15aa9960829e3ff28174f69061b5091c7c9506792fc551270a185480b9b5e0b49104931e99fba22d59703ddebecc87a2ec176b2696de400486e2f800104560229ca9004cbf44bd7fa7cfb971ed745eead24a145e87a4881e7b66f23307048b1c35ce44950ac64496c652739354fa7be895d82d1a2e591062155a2e97cb19c7693db123628e042b51bbbaacd0b5c3c586186b10b5fb09d8b17a8862c5bc6bf04dcc952f8376589348916bc6ab53563e8ca24586f28254ad705d975e76761b2465c052c79fd10b81c81abc576e8e89c2955ce7aa67225a953400dcfa6b4f1d99e3b891685785a7dc1b86d1b0b21b721a90aae49c0c170231266110b3eb44813c1ce478a70c4c96c6e803bcd5658fd402b50b954bd20c6225ec9cd0789f697eb519518003e77444fa6a135788c33c3d5ca193b73283997cac63867514afd9a7e36f1188ee7f6b7b5cfbdc21bac2cda14d839bbc5cfa644343e17396483c220465f10d3a20661f617dd0f96edf9968ec0f5573b0e1fb64c0333af5e97169063d6418598d3e79918fe0d6e2b344de5742aa39fe22f786ff7ba4cfd14d0051065554c3286567c2fbb7c5fb6614b91077a9d043f9a8c930429271e1c3c6e75dee520d04efc2e18b5d36ac84895e33d85ddec5209e9971d6c1479b4ef21f840cb4b214f171c6bb0a9f5cfd6722865d327ac09dab35582a03ba8625a04848a49543c3a9d53790a6b942d3c0610499cb8eef606f80f077b599aaa638b25b557499f9eaf8b3f84cc6be39908f40fe108f626878ba25277816e7622757b0754ad0086e93a422221f795cbe2eb0ade33c454ddde8b4f6fe51f0c866271cbe9fb1af4d1c6490bdb7d04c78e1aada5f6aac296288c4fd20957e948d7d992d75883c1d21c3af091e98a86af81801967a6a29e969575fd442f3ea56e751727d5fa22c28a13de38f54554d4d75f4cfd753ec786950a0556f330265807a9822a6a0033e6f209308ab83f372dda24ec67b314d9e10c7a28bbdc3d6fb7117b7f6780496709a6571bd1918ec3ea7b563563e9489fed1592add8c6a3b3a1cd19d8b4f949092028e8a0cee123042d15cda6cf8928fe429fe6e50ec64dab6ecde6a5b59ed6192823c6b14997836268e868e646139fdcc85baa1fc6adea93b2d8a376b6397706bd91b22d4d74da4df53b937c770cc492fa44dd45ac74f3f431f532b80e60fea0dc77be8f63b37d2c806e88892786b962e023423bbf46bfb3f588f9b9d13bcb4708c3ca27dd98dce6ab2483876c2b2ed942982567c6017119bbda2a45860025832f732ca959bb92a1b1122fab647bf7736fdcd19aef771c4f623b234c25ee3b2295b5e14082a2537f5fbb896259e7234166fd916d3af6925ef06ec15195e7199fd310a2d4b8761ac63325825419e08ee11778723752acab59a9759b73055be692d6121ee600fe207c8c803381fe065f0d94a65eea8f454c4e21571db4835b67a63c2512ca9d78eb6be55fc0a9a64c48609a57476dbb6cf4003b7ca6708730d14b2eaf2dab69d40d920839ccd7300ed6deff6742314b26faa9a176d8391d9fc66ffbf896ffcf6333af5bb0eb0da2454a675efd415b1755aed8cc672c13243414e53d03fbbb4f68d14c8b642280728021abe8a34bc32a296faeae4831300276693c4b572eebc41326768ae655571ef70fb52341aaea33b52e6141d35ed3ea3c027cf4829566add92a529f4285e0f0d41922830b4ea8fa5cfa1027a86004d55d626f6b69309e1c4ad9603562152e356667a902239fc75a37e8a964e2a9b85b9149718807ff3cd2d42a32af01c6cc178dc80bd050740ca347f13ad6c435512f854191d5c94da4de425597f1339fbe898104a487341a2a2ec2298d4fd0c995d408ba56b67c25d81f57f731fd2c997a969c9639995a0cd12d6352eb6fc25059480466118af8c6a01d4275977b3bcf8f266318083383e193ac7c69b5c733fde412db20770efd2d61ad9da611fcc5b750b554fee0914784ccfd2d414a4b7546ece9273af5edf7c499aa11e458562a5a366a756734b8d95b3bae7edadaa78c8e3f16760800040e4005aaa04400e00f1507f499b343251661c355bc5dfbb1aec32300c11c4dcf5c266c240c21f3969e88d5b345b2ef8c16db39027fc4ad4bd10cf4946d26db32150f2aa6bfb6acbaad68bfee66a8cc95f79f81cbb2ef09d86e07b9e59bc7894290db74f7d250e350449c786c3692d30bf25615c8ad13128ac332d222e1cb556424f70deb220825eb5bb9b43887ada31e835794b852c8f6eff5239f2fa301bf0e2b440dd6e4656338078aca805cdbefe92dbb47947de3cffc028ba214784b86dc10f54c849a2300fee4a97af4e3154e87c130b0ef205cb7484a49fe788f29c569a6cab98c112eb0ab3364f9d4efc7ff1e2381a9144d31dfc1d4ee21cca69ef95efc490b76201df50707eba8c515584c48b070f8e8bbd1e5a241d353d7e7404f1b703cfa07c507d9425c27f63d193bda5521fb6c29414ad0099b58140e07ad94e35ec0eaaa4ab57bff9d57430b0ed18eab6029765862b53926b74b1202d3c1fb42a82e114618b9ec2384dee0c5701d02d08fe37494e52ac98b841b93764cb712932e2269b370345195b2fe1a8472b550ce9092a49f835b81f3f03c0536e5723b21442dda5f2c15abc53ff30b4acf09d377046060f2a7a4f755613b4fef62d64323f07ac9116c68c65925ae0b2f9fad7339bcbbee1a4d485bab2f1a00c746f9749a4ea347be3ecbfed92354c8fe5d92223ac4f347881f5525d0a675dbe9a9a0723ba33d8a80cc65cb4cda4e9392d32597f46f54995f0fb5abf65caf02e59065c63242b7ebac20089772cf5f6775ab67c565329d7fbf7cc29fbeff37825432c2cb722a360f40b3e4173ed936429e327db4558ed9f7987b445d84c8c126f4ebe9f7ccddb0f97776709408b89a5e8d46f79a0ede2761ea19bad432e013428298a3bf768301fec9a67e62b628d92121b33923fc7ff1327751f47beecce2b37554bd8d0dc151a67c6c865c1c659cf8ad2a4e854dd0877cd58f6bb5712b1895f1f71e19e03adf3489115ac776272fa3964871573994d2d268287f3d8bfe408b6d97308b95a19672b87c67e58992c0a6cdf390b2ccd5272003fd87ab66592bfd75377a03624a1b0435b14a02969a4dcbd1585d06532fe23dad0e504211a5948b75fe0f8bdc10e1385971c40bdd450c82917ce0c042bd5e8413d233e1e3989f0f8dcd8cb7a1ffa2f6db0976efeb9760d7625e1daef685f4eb2d89e9c50e07c33ba50af50833c8a66c282ca0a291dfe539f050a62d981e9d63900375416e35bae4803937ac851a979400ab04f20b6c6b2982d5771757df59421b4eea69e052e461f767157920aa8ad167a996fa78f96c1be5acd2a77d41dd6e2be32929fb8c13bfa48bc6cc95029857a628bcae691580d119591443224535ce58b11b035346c1d5d8974f9afd26b45d206c0297f1bed225d141786eff326f1907ab4838fa2ce8cf2fdc22240d62d9fcf0be72ea3ad1cb73f58ff599d0d37b97a1b3c887577b6383100a2ce37da58b443ad0ca503499e02dee9e64e8998b2d9c90952cecef1ee68990247c384dc8d01564c998deda6fd9e1a4be855e86667f459f3c3886525ad4a90af2a9e56dee92de6a6856bc8babc22e408c8902799a4ab6a31f44b1155bfbf7a4fd26e7ef1a210fe457760fe75a2ae0231920928ba47efbf807f244b02aa7e1fc181b4aeb0089d25c380072c15e835aefc1d1746720d43aed4b5128cb764f506f8531cb50a33e105a510fbe2f41dc12ff5e7335957ed36f6c692d866eb0042f4859558757bcc97934bd52f75b40582f4ad850208e824113b12aaa2f25e810d01c168f590af6f0a5f53fbb4ae253d2d7afce2d4b70518c3a8df4fbd0241176837ed7f9e7b57ca2689875baebaba7a81e588524408b3ad58bf038e1471febaf45cd33a9264245a5eb9b647d8762c2a700510da3850b0448db40de2c211c89f8c06b64ab82dd66bd471d40b9687672cba17aa2e0f84ac0cd96572d6c2aa9be6cd4c0a7ba8530f30a8a1639f713781530cd8baeeb974c70e7256a5e19b31f0e5270ed5fd551913550613f6c8456f3892922a60b2c35032a30d66f5930165aa5037d958bad7613c6141c0347cbcf13a2ae9d53eddff1b4921bea3249ba41918cb938996f64f8b1e320defc7c7e1febf81e26c6eb0f33b1d4b0ac6e504789f78cf18deea5051f1f6a9092ca46f6de64cbbda54c29a5b5062907f50648dbd7d96d5f0f6793d6c2557e83f1be7f7b2efbcf7d58409b88fb7ac8c4030af3610fc1782aeaab6ee1b42fc6f46bfa587be3957fe39fa5e91df04f1bcb982f2e2cddb3f646f59a969ab2f5bc7bcff6f5e8aafa5c48e5a28cf4f1abc1feee099d1ff2cb0704ff552a4a597bd3dcc4d2fceccdf60d842ae30b0d50b52ffd4e7fa82f9c34a4aaaafd83557bee63fde6b19646fb62b4e7efe13534400d1789b534ec44a8d5d07b42cd009d648018946a194cd87666ce4612c14fec74620f989aa15847f3cca041031ab298555936332ca19f2580a0821b585125c75f060aa80c97dd3802e50f456054311110d57e1c8f431a2974a31d5f358a75701d4ab2ed4c11f1f9670a1d954fc8ae1ae3170e69a4eadf1474a9af96dc7851166333010f497a7288146112f800054f4e7c2245fc891459b5408828e4c42fd2a5000805396ef32487489125929213bf26fd455eb4c8f1af09ff7e91e6076c1b71909f0307bc627f43c6b3f6173bf05fd728fe63efdb433829c88832a2cca83dd92e3d935266ef9ef4ac17734fbabb673273bfc1a5c4fcf3ef27d9cc24866558e69e3d69d03329a709fad52f492489b4e0a0c84131c60954e7d1049a4013c8db316f0692076620b5b0040d690d87b4506759966531ae1817105c98abbad11240090db9daedc2a44b4a77b9cbc8594ace64d6e9c46c6eefae6c99652f9755f7cbb26c6659f6383d33ecd7e3cf8432ac6ec4a4e024878883f8d348d57f6223618dd448fdf29fea44eed32ffff19f8dfbaaec23645f42a4902edaddb1f640e7c88123070a5e9ed8dd23dbcecc8fc9322cc618635e31c61863c464fc187fe712ce313a629b93a3363cba66c610aa67b89ba30e1b2931a7e0c0c13a24588a13473ff7cdf9a6676179adc3c13a58e4e230f5943a196ae9719c0ba34d0e1c93c53a16470e29774a0fcd91a3722773c8219a4012aa5f770a212a533801545975a768c24afda9560c655ce439e74b3a5f0bb9ce974fbd9303b63abfe6fa35f98bd3dbe4b876a1f62c2f3dae74fa187fd26fc6f9b2f3c14c510dfaabf6436a7aa14a1ceffab749a536529d9f753adc05dfe8d7bc207e711077c13ab6ce9f9a79fb0365247feef8ddd418115d9d54e3cf460f3d97a6bf9becdada084ff537c2038f5e8c7c1c70aabf9118f9c5e0420dfe4ee369d47e1a0b88a6da8f0335d57e538d3abbf5ccccfe5b1be12bb5bdb0880eb55bc7bd0d74cd81eb5ea95b717c63fcb7d6b0ef5f0c2ed47e1c76a8ee1703830bb5df85da5fbc52b7c8c5591483bd641dad43895bd6c15ce4d451f7a5a6356ad4f9dd50a3f6a0f5064eaaf3067e75de264cb234407ea9e469a5ae73805c400d7b763e1650e777c302eadc9be5d81e4d1be8ca01ac4ef9c5af312c367e2a5edcd340444654aa08ea9c26aaaa2aa4d47e19d0862a0ea5461097c6555ff98bbebdbb2d05125c84d9adfd6e5e9a1eddc5267999635c949f67abe86d7777ac65c7eef6ee96e284139397398a8d852b1c8bed29ca85dd9dc7d8766765e6ee66ee3e62b9f9c5aac17efd9391338b52b1a0523502a28aa7f05203ea88be01ebb0cc2c3414f217a5c9b470bbea5f17c79e33971ae2a3ead6ad61fc62604055ec5195db6ef9e7636b44a2b5d4c854c53b90ff2d02c46d810db6e64d5f052008cadf2d194cb6aa1836808a49a0c6de1556aa180726f604a05ed3b22bcc838932c68e31c6c85b32c98f6769ab56b6903cbb4658a041e3094e64dc76a2542362bd55e8003486abca0f95eee1e6719ebd7123a39e410da70e554c9ea5e9971e10959f9e88b1509bc76b32293d537ca8d4eeac4aed6c0ca31a4a9e1e2f557e9911112e82d048e5a5914fa36b603f6cd84e214514f760aaaaa6a28cfa52330fdb5534d58843ede91eaa6e18e79e4bdd32cebd53dd26e75e0bad5b89738fa56e9ca96e1ce75e57b7cec4b9b7d58d8573af54b7162ed3ead6b29d38f732ac6e28ce3d59b717cebd58371929d516336386c93fb934f123086a232086a0f68c988e467c4b648b8121db6f379659b7e5eeac1a89dc816dbb156304000530b92c8b312301a67a1778196cbb37fd52438cee9cc4c60bc6d8fe72bb4df2dbe86d443291c844702936f94fe8607bc03b6463c362ad0f2ab6831a87bc36b1ed4c36ebd7dbac04213629c3f5aa9d852894c15eb5371b6dbb37546b5998ba600b15a8d1e3292766811a33d3fc7869b0ae5811e998acedd5c06a66cd3b1dfadee9b070a4a88deb4290aec75facd92e8879c5be585b1e8380111504e920060aa068428423e4645ecb177298b735d790488d6179fab17ca8215c35d118025d7062a58f1b6b29931d0cb1ce2f8c35235231ecb18ee76cfe0c06dbd240d707422055ec6362f0e6b86b00f61a4f2fe42b755ea95ae600ec596ae64d166e2249a70aab9ab1a75aaafb7de3dff4dfbf8f715950ebedaa59eddfffd27457ff61d0c20b680b2fa0fcaeda1fcaeba191eade132337e602176473069105d11263ee7418f4c2670b9672370a8542c5e9cd8bcdcf9d8b744765f6bc79cac93133f7c79c7136a27b748961980dcf21f3fb9aac3859323b434580a4ab5cd15582ba8d784e4d2b95b66d9779dbdd65664dd36280e8d6dddd1d876ac40065df3534c2dc4ca7e238aeeb3a1b269085858552dad272da5545c1cccccc5dd799be72ccdc73ea98220b6d51a9a2601365666e693971a7938b8b0b9d28144b47468a53454197994f27171717e6dd17666695aad3f190687f21e5eeeeeeeeeeeeeeeeeeeeeeee8f99b3ec9bbe72715145415f5e64a4524582d8a809ac8a8251a8f9425f50d29d7993c1c9e874646ca9948ae3182f687fccac52a960603a9d193366c4c4c4c8c8c8b0c0b1c0c2b63468d4a851839959d5f56066d40c957467f6f6f6f6e62d26468693e974a87b8c3246140b5e12687f214783468d1aff1ec72cc3020daec67352782bb43fef6b814b434b88dff103eddf5ca4331c771e18d4bf30522e0aed6fe6e149b57f4e19676c58a0af5a0aa1b60c7ca3378c33aadcc5ce22a6c46b9a49cbc03a9a057ba3ff493b69172c4d7fd835dc22ffdad582122ce37850db05d3ae6ed7aeda055bf3e309550ea80d5a890acafaa3052594334e15050dc159358f4e24df2d51f92a0048402cc6bd99459d8e1b551ca251fcdab53571ad27692a400d01841abe0b0eb4d0012a0b2aeb4aa185901641438d6198c4a4aa772693999c4fc9e248185f7ce1544551aaf66a34c2ab4e1e2c70168a6312c3304c0a2c5e1593ab6ab0478a1045c9ba524831a286f4977012c347082940b838a12f75a5c8a24a104d8a210b2429b2f89182083ec8a288270348c2891fb872a2c7297922c70528b208ca895e4c0f72b6e6a2d78a62a5b801114439455894a02ab300837582185408ca298275e16d41ae1ce911712b496c90945384a506440e608411fce414c18ee05dc020477a445a8b2326ace414613922671b015818d5708620780594da6fc3264a92da3f33a31451fb3970334c4ef76f2e0d7f15400c01e5446fbf4092e3416cbbbbbbbbbb46f844196394438ec304951f820df02b5778417ed0796fc47618c0ed16dbe8567f32d94ad99ae1f0b081880cac175e4819167b72cccc4fa63ad141a0926e612c560e214376f4cf16d9acd11e61b27fba154e1750925622df3f2848486888d5acfe384a01aaf029a25bfccd641f2be9964c50fc62db9824625b30915cf69ed74de37496687d44e5031ab6cf775bc9d443cf62757372946e9f7b7f21585b00a2db3caaa72a7f07f21a1c39fe1ee42ee443ee446ed4ad95e2c84af5f728dd3a619f6201c53e6c1f77f9ca7f4e4a55aa0759c7e4c9da5d47a8fc42cd35bf7b9aa741f7817a51b7b0f7f718b85c49b7e2113df0e18aeaef407b13bfa50506c6aba1bbb8ee835f4cf69b3313933dd7ecfb1ebc148488993fe6c580c1807d31b3725018a2861e84727a64598789a7eef7dedc345b591aff8d89bc2612f9cabf25ffe8c8c888886868e83dfcf06d9c80862fbf08a54157f1c05d2e55dc1091a7330209092968bb62343434448420b8087717b53a688eac5d35ab52c76a54f77fe7ffca5f87fe81dfc76f614820628b306a0f21043f0ac6430d41095c710431a4f0021d9eb0018b6505f82c56945045c48b872a3108630a3c47c076a8fdb409a130784933e15bfc37c1232042153504a5137e650c122481e14c20810c181411a98aa228d5764055f71f5cea16f548e118639312c4b430b1041260d058b7688914b868a96ed11224c096e82188d4ce38bd6842852b5016303ef935d96204282ac50a1e9a4041a9a0b46e51131cd03068aa6e519324a068520294942b271eca8971a2826e484130c9a288899110a722e86907340ad445095a040a53b78849095ca0d059b7884910a7218aaa5ba4441496f0851529585019758b94802288bed42d5282064aa05ddd2225a8aa488921b222257ea85bdd222552a005618300a507202215464544aaa2284a8340c5944c88ad080815a8ea16f534a19eea16010104152e84117530120410485c56e8c0053bb0c0098c270c1c5850610a57c8e0892190d0c4d1912200c51bf088c1846d0b221fa41c77d2440644394e9690c349497216014173917686fc28c981e8880d3d3e495ef8d1ad1094214af5b937d8af0f6eeae2a8fb03d81a70a5cd16af4e70fb42ce769a7f6797a67f89a64d0fca9ecc603118d6d32d2440d5a1748d0f49c1850f122ba1d51928f2702154430e4ae2e2a886fca4fa6351ee744b5ea95e05fb257451778d50f721b0352c0fd81b8de5dbf195bf69ceeef3a90a02dd1ed4f504d45d03f8dcd5f44045420abd0bd438e79c99f6cd7f61ce1e22fed8cf3d7352ba2163df2f0d7b1790697049693666246bcd67db993006695c8360806abbeba7a7a7a787b537daf3647e013508feab5498a669da6b1be74dd40ed989da3d27a5fceab6e7dac7a77dda47e3b40ff9a56d40c07ec76b60bedf86cfa28931ffbe6f03da4f96d76c6fb3a357363fa0fd218b3dc667c97696ec8f95433a2056e740575f37658fd391c56a50fe6fdef495ccd1a0fced9648f9d393f2713a004ea88d0dce4e0e3ce4ef0eb95498c8f7c83cd808640f453d2c38a20739c5951791ccde6c9592d99dd99dddb9c80724f80e2f222a76f0a2093c7bce28258665d99c1a7bfba5fd5269db38aedb5dd3e4eddd35e9b0743e629db4a57b4869686b399ddc770818b2f7f2224306cb40a15e64743a5bea25954aa15c4ea9540b4da5522c2953974aa5301905b0a5e005dbb651e8fe76745358436da3069767db9970c66fccdcb1b12b68482b95284c15312ce3743a1f319b736a9a562a95b60d5bba343adc6f9c8f58b94e87e5b7aed3e97e3399d6d4e9d0df58b869fa8d72a56efed6b2bd1ef724b16c6aa5d3eeee6edc9958680b4cddb4ba71dd4a1ed78df3b86e9be4388febd68d722a2250feada5bb61e3c1eb4acd619feb763128612529e2914c4c8e21abd47d49a53120af99f1fb12698988b691847cc87fbc46f59bfa2a781175df89d8565b41a2e219a3a9748df3f8ca676fb4df69ea1ce84813197f8d50d288e5b7f4266f65bcb0705c894371a78e4a2b720a13f93a7d385b3ea426d6242af1f84ad334a4a30d664b9c7b8b691be71e6b1e637d4a72fad1a697ba754ad2328a3cead6494983fd35ea01ac40f21a2ea93667a5a23c9694f285c54ab3acd39999a675a75cb2aa3cce2835e3897c1a2ce2874bc205c17f5898d0175f4de955bf7c65732bcd6eefa3ed9b41d9d44ed4e4a1a8a092aa5819c3a77f7c2514e4527262325db8166e7aa8176a0a8a0a2a0955a557fd45fc9c7e4e4127a0d3cf29c9e987ab8b42725169258f2b578e6bb7795b5d38f7ba1924bb7b3a61613c588f7c49a424d56b6998043911e2e28994dae00c2b49af2954663665aa05b5b5ad14fd33753adc9b3a1faa28133b7dc0080b82021624b3c4e5b7e65e5e3a9deca3b731aa2397122089c5731faa5c3ba241c3f33a9dd2eeff12e83e8eaf271fdbbecde35c0d3637868d731c5843ed48d3269276a41dcd17932027427e6472b1f349affa5fbe925e0df6f74a29e9ff4e47fbef7cc4aa8a4243f9f2a13ac2c92ce5c24af3f4b57cdf1776952a1ff7953e0e68f654964e24d0d2f06b4192898c815422d5821900e0dc7381f19a40607366683c2ca8f1b4f69372f5f8aaa79329349fcca11527a3ce6f0635d8134af6a16a6e1f3fac475ac1782492275f1a92f6eaf11a49a557495ea325f94ae3e9968685c6c3b634290bf657d17a6a6b47d4e3da05c0b4220047804e47be07868d0270d3e35c4a98785c5083eda457fd5154158afb7cd24bc9d38e8cbca6c74bcd70fc007bed48320d57c22a8bc74bf3324ad7a80ac0b91753b71b9c7b336ac95be2f2d25b3263c6278dda05ea2b16e71e4c95de12978fdf3400e75eaa6e598671a54ee794a4c1fe80d143816ad89f5c0df649eb743c202bddd2302f87e9d5e9c8292c5c0e1d68d7f99855fbb4a3a5e9cfc1030d4f3f3f5ed3d26265f2d01ed5c967fbba4af6f9917ac4d4f590b1030d4f3fd817ce199e14f215d7b89c5e642480530d81aaa25019ec4bb9e46b477bc3c15449b97abc54ec8349e25e724ad7b860fd2e29405382a8085519d288a66846934aca25a9683f5ec331e19c682eee89f6c341d182b822ed27ca506d2944dc14cd489be2d28e1a9cc101cd4c9312d3e9649f7694cd29b992b61d803379ac1a0295e9b0eff443a1c8b4a36e695298744dca957239a14f5450b822222e4aed9411272575c44dd1a6d4fe2de5f21a14955ef5a3aa00a1c6a0478490a45c45a4885e92d4ee1725b5fba4e4f4e3e29d92d0c03e14121898b6a5aa8b774a52a3d3d1bed30f57057b896d1fc53c2df31220bd25311f63647c7f8c979ae1cd97375d0db6922a365458f2a572529bc97c184f26492bbeea57795ccae35ebe6af9e28c96a67f7adc0f97a43917a7a40adbda6d2bdde2aa58b0bfdf799cc7795c556578da91affa5f3ceda521f9aaffbb1eaaca955c9e028143aa25ae0a07867644fd6275683f7ca37f6fb4ef4f29e91a97ef4fb95c3c4d4aaffa5b3892f18243e2a8746bfb7e2e6906cdd7de38e91a4e8a942953b4a350beb4a350beb4a350beb4a357edafd1f578a9d1f595a2abf26f4f4bda4f8b4be5ff013b9df960e72356ed03d0f978a9dbc7e1f8010d39a423fe9043aafd1bd8c1d0b16af24bde4fe5f0f4533d2fe5621dbb377aab9cd2c1b9a7ede0dc9b9b02302f36b8373294c574eab8ada4cd98192663016e2cc09b5b644cbb34fca53ac355b785229a9196de80128bcdc73e22e09439d3db1ca63ba57603768a3c82944d4ba2cccea876246cce7a4d36c3fcd247b32f7d325f500cfbcd9b5ff2b28f5e581a9a61fbf911d9bebb194a9f7d44be3b086c8eca57fe31a734a43494b3d872ced6cb8add4298af7999f6d94744a54da0f4f323529abe72da5ff23647f33647cae77580fcbcb909dbd63135025ef72eb8dfb9ec53fdfd6d7877778360b75836d8c78a159fbaefed9f799c118e3b28c4cc06b956a1ca641f3666562a65d9c65ffae2a66ddbc6a59fa5df7e2b6ddadc782bb13699b3e8ee49f0145514a2a5811285c6fd26e5787797774ed74ad7d206b9c94d1a7d72541ec9a1068d429534720f6551946e85544ae956288b6451b7d6f59248dbcf708a07b48500f9b146cccc3c51a4cb9f5bc39f8ad6904e943fe5f5969510534c501bd5b570ef25541b7b3fd4b61f8b0914dc82f2ef744f813b61c2ea9ff99918dfc683144608cabf7be38fead6ca8f5b4fb972b033fe97bdc1af0a7764d4e885d55b7a30357a18a858163fa25eb02fac0135a4364790e744a12236c49c4ef8b66db387f60cd9f77bc65f4f7fc83cfdd8f33bc6cc53f9f9f9f999c75df3ee0682f3a3c12348768424c9f0b45a61144287f0a8a73258184938383b7264b1356b6476c53fc3d9a8ccfd82d780be923ffd0b553c1afc81ca6f0ea75bed80af210d34094a98436d106401a121870d222936502246c4932bbc98d881358661ad8abb62907330eb9fa592a1b307576441a44550e829a21205231b1f39c6d831c618658c3146ee6d87211c1e2fc810e72cea81a2072936f95b8c33f42ac9c6c8c686394a299923330c0f462c4b8c3737b75286de1dec779f86067798336615efb490ee15b2d3bbb33f6ce20b391ad2bd42768e6818d240ba45dbdb8b2c67724e37cd389fd86e059438e49ec52594e03f66e041126468a900d9a4b5724462ad90bef0c3a388eb0fafc1414285d8f0e307c6e367698468b846fc535bbc6c2323111bc98cadcd0e9bf9fe3b6ca8541435d70ab49f5d563889821b25d990838b099117120ff8fc60212b64211aa8c44eeb627cc69ef7469431e29001092223f64082b8cc62361fa7810009e2cd204b34df231eac1c4358635730334b8eccdc3f8880044142348fc098689f4e7da657fe362cd51428ab5291e9964d4f8e1d51c8d0509006e90f28702285cd9edfb3dfa102cdf86968d0f9736ca77b47080d42765cdbf12c46410856aac418b128638ccdd18806a39d2146b1a84707db143220b69df1191b9d6347dd95e999d6667809a1c187930c19638779b827c3e4048abcae52c55ef94e691d357e02f6c60e1e933f1cf8739835014b13ffa647edf7a9809001b5df63f0cafc8509a83e6abf0bf1176abf4a45296bdedc55fc92b74176f8a31e88fc41bac59f3710ad3f195e20e261c3fac0061d0a54c8cb3d48db81fc4d4658236a7a4da986e33c54afe4cba7316835fe16e7cbdef057853bb583c16bc681ae13a6c2106bd69a865a1afff085aba1c6b82baef640c1406b4824beec96420fbf94eeeece557abbbb7b1047dcde3416314c6232722c35dca1fd6e7534606ff8c74f8655103404b9bde91d3ad4cb13d4866ef9f70be956d7f8de42220d3146efb1cd68faee77ba25a4c1b8d360dc69303e0dfd020515e23bdddace371a21ea41f64625049d5e57f76ee02bfed30bb2343374ab9f7a110d52d6d200a9b1028ac3e3856e953e3e4bd6bdc2d108511a211aeb6accdbf3fbd89edf4825f295fb92c7ee38f886f6ed711efd62bc6ede36f8cdd0609c3dbace2f882a899abefb991ca5f78fa5ee2bbdd7e08f6a307ad43eecde3ece49690bd99efb6df3541e457d8dce3de7d1294ae5a5cf068c1e63906e457777ff21d650649f0e054fae80d453d4c3048924a0cc259048e28314824e498a30a380841090b80071c41149f0988e8c684136059398c9aa457e2ccaa8699f69f363d4a216b538638c32fecce2cfd0ad6ce587d360b429a23fba35438ccf030735046b8c2f5f4974aba38bca0fd1941f7e20628942fbe5ee6a4621f9b204b109c9051055663edeb33747427e24680ce9d353b221530f4a50654744951f4a2e3a9fa5918f79426300fdb0696869e4c72091b150331fafe1a6f44a3e959f2a2e6e0ca02abb234155764884aa2cf90c55f9cdbd1a944f83082a3f2cf9b42c0d9f2abfcc40ed9758a8814aabfc2dc6c8340994dc2c3ed914323eb40e57a86264a31b9b734e1658802c68e3f0701f865055604482969147d6bddddddd94d2a6ddb1bdbbb1ef054fb2e19543337f405c0734e4923c9043b7c245226264f4c35705947982e82c82babbbbbbbbbbbb637b77472050a0f80b3f24a9a1ca08f945ece2f5b2b1a33f768c317ee923c738e78c33462cca18637f38fcb1c006fde3122d51f7b7ffb00912238d31fee0450de98cd90e5c042849188f2c46c6be92174ba552292bcdac548a338bdf0b2c8f8b6818d24595e722d6ce90219c23453f2c51b91891a03b68820fcbcecc9aad09f6334a25194adc6c8900129434b8d8cb1d0d4aec931810f67e605f7a4ccad2ae344dca9f5262ff43fe9801fb701a943645345ca31f0b45ca8552e5f328ea21a2ca5f425f4ff054b92ad59c35dc079ef7a8b44df844ad648a46000000006315000020100a088422a1682c8c7449451f14800e73884276583a9647931cc9711c848c210611430c21041822333344346a01a564d300cea0c9ac1a2203948275aa1d91c069ce227dc9b8cf622de73110dac35c5c5cf6ab97188ad269b41d59fac43d0a6921abb0574d5491f74264ff4f4d1f41379c5ffce0299dd8c009874bd37be50477288c8a9c320d28f6c675e6dba70c040ecdae9c2bf624d4ec16e35c78dde8f728eaf4db2c39b642f668b23d06c796171c43644676207ced8847d2599a8a62a4ec28e50e4d0252e095ed8b786d0b918896ec53b300e0ccb3b2f95cc8990042322293f49b1704568006afc09840eb2ec68efd40015035d05289fbd5cc89c43ec2459d85800c3d27a03d409bb6ff400601c401fa6f7d6809b1204399d1968149664a4f3097a11f6919b1b145078fc6a7e6181cdbbd2efbf00db2848c223180659af3480e17099f05ecf823f63247cb08ec6226bbe892b42d60876f46625875412ea2c643fb98097cb54b0e66ba781189e1658d4160bf64c6f3c990200d357fbf8f6a457106b36c1e9794c3c62915201bfd0dac603c9d6829b03a892eca892d3909fa5d5b2a6fb65f834efe8abdd4a90c3344cfea1c74ceb3e9f7358868a5c398f95598763a15f773177f2f5c8eedeb5eb1620f1cba264dcbb932d633117d8923d53731ae9ccc00cb82bd4a466e3518238fddf60a514aa63ffd82f57b7e45ab76b5ff5c6937e712c4e79461896703df60fc90abe088d7db1e1cabbceaef18c508fdb21cd460c8d0250f9e2b71195eafd761676fe564df88a1717345dcb34a534b5a63417dba9a00b9394a3771503ce1ca3c156762e6b27b31c8d39e402bac0ae1af3ceb09589c5d77494d3528982b050fc8d7e9b6b11a2584a15d28c158e6cd12b0c3cfda0d57b72eb6290845a01de0b6c242b576c2fb80eb767a87a185c3fef73f9718cbb809089e387b0800654a4cf0b0b867be9518c41a46410153de74703e4de6226a8a1246c4f3352767fc9147dfc91745ff24b8209538657b5762e8a12f876150f94f4f432bf777e87e3d22f1204616afc32d5e7a576b1961d64a132f03b7899ad8f7795a799711513eb09398f9710806e19384984533e73e763fa6babe09c371fb6e4d4f69c67958078c129ec6364a80cc1e7c99aa76094d2b33eabd05d027ab064c019273622564a71a3bc8db4cbd93883ebd0147700ad700df13a4b6480391bd1bbbc616b75226d2e2d8e889989c1b087321349e2bcec7409432fd4d5fe1ce324b25b0fc2bcb08699412a92710d381f8f71340a115b11edf1b052fd962afac38f6b5cbadc438d38866289065c3a117721dbb33964f1be7a1a728d68330cd4aefc1de374f17d72a7fc3c73648bb6e1855a2de08f43bdff0cdd2c9635d24343d70a42857f5f4552d03a6f157b2f674328ce4adbd38fb67839225167d478fd1ea9dee1966ea5a924bbad31979833e0170b38e436743ad560202bc6527384df10a3453260a8bc5b773588768f238a156aee152a000988c88f5c5603ae9679615d8305d6b88eef66d1128b1bf5cd11bd6e1de8f3ec59fb839ac431947f6330b17344ff48294b2665b03031f6d949cf6b00ead92416997393774bb5e496a1c08a2d18b73091d22e4139ad51fbc006a8499a4befab5d0857b9f3f10825dcbb2b5911366403ac45694bced2a7fca4865eddb9fcee07d34351028a7b7dcdb8fb699d8a700dd64f25cb6e601a7e30f2afbf76fe581726a5512ded92203180a9f6be9e67b3555ae84f5e5eb828420c87e3e8344205a00dc75360ed32ff01429752329c93fcc3e361c810af2d00149679e648f6ea66ad1c246f63cb75f929e64782eeb53d326580c1208af10d6d5d0ae85ac6e864c4cedc48315be13d71153073004226851b0463ec769754216cc8b2f5889641d4f5f9710cd2bc079b2fa3464f40a7c5f160cb53b6f22d1df294b1d756a81707afd4c564ddc3d80372a879b76a0db4c8cdd5fe0b51d31e412ea84bca4e5282682dd455197534356f78ca4c47b75f108e59489f16afaea6206bd7a0e2acb4eb9ac9c73a3fa4338fa7ea12783283d4b90f9888897c8c474fb12f6e8f01a0b1e2d4a16a476bc6ae3a342b6ddc6e0af7342f898129d27faea1f3af2fc9d932912f6f4fc483456722c3cb6bad492c07b079de5dbe31a200fde8e6e600c2ce660fa4fe5a08ba10000026ad5bba916873674000221c308be9f53721ea05590cc406281602df5876f00edf3ca1265df2aca81f60de3c83cc4808761a17cacb91134134d1097fb12ead24420e276d623409b630e4043a763ec88c9e23c0ca0041604977cf56227164bf69a4ac62cc71d7ba35e02767929761b3a0faa54eb5813f654332781e20f1c20155b855cb390d7304919a6c981a2242847cd0b050aed31cc4adebdd56f02188284071ed7be2a19c6b1d53a230c8ca79e7438e0a749fdd80dc7b896fed30c629ed670cf33cabbee0842042cd7976290c116a3b66cdd6b4bce7aa6fd73baef7afdde2df4761bdefb4fb7abb4b3d9769bf7a545fd58f625f32d66bfdd976c99cdb588b7908ebd79936cbad4cf71f731034cd9036ef03df3f41c15d60363c2152d5280d4674ac66fd2cd9964c92f6a2006ecf6e5bd0445baa1dcf538070897a471e045c55518328bfb988de426167e93435aba81dae739ffd335cc83a43041d78cea65a29f226b4b78f0e83dba7f15cb9d6809fd068b76b756545ee2a17e4683a80728137e98dc56855c78db6abe4c30d96459ac188558c22f1c8558f4c78a748744d10f6af4d565ab29c9024f3a68342b36abcda717813abd15b77374532abdb1402ed3874ae47372d5419115802cfa19e3bf538b627dda8709b330fe865f1af85b4bae2ea4d9bddfdcf2d8a8a567eff26156f3d4bbf4c75a6cf11390977a2d5a302c67bd18e6957bf6ea675b6a69d2794594c547d2ce855c9744739882d9e0fbe332eaaf1ea581369bc22dde627034319a8006fa337236dea12fbe66d4d5271beff600edc7ca786b63696ca047fcd124fad5c40304f66b9e54f1c7adce1ad33d5a0cb61f422a4fb2e2bf8609d16b6257759e5a9d3110a9dff99108bf2f889efebe1e72cb341c430c292880a1310d1872cb866338830a2911537c5f406c4cfa1ce82c882fc21e0f83ae5506239dbf8bffcc30c56b6e04830afcd6b24d7468cd6d683a8e9356471e8da3a0ba9be2eb0a43d68e1adbf4d2dd96244ecf21fa3c183967acbb8becd0c4ab7956406361878cf547dc807106ee19556041f474b25c0b781674b02f1a1400ac75474da0f026fcacc6c7be804938bd45ad7b157bcdc22e1b753101b5e43aeada54e7dace1ff44b8478f0e904e15327c38f883dbeff19b7c5f59b28a1397f904b5d95af7bd847d259bb75f012d88e14ca7b0f029af554ae78dd3a9857b5b9c96bee01a48c357acf09ca582d74e69c66fcf175ebcc2420a7bd6fc71b45e870a8962f6d3f204f5ba72c771769d73ac31bca7e04e6f08b968041cf9ffc61cdd2a38b606a463e83140f177380d6fa9bef68f325636a705a4435ae01d5787f53dd8edc7563c5c785b7d50b458185e60c14920bc05a3a0a577595aa9cdb555943ab2668363835eccdc88573e2dc1aa7182a25d5440ad306489c6cef378daa2bee676e9d84d40f779144ee2260241610b34e5177d6b81b31a4ed2ec61022181e95342342e590e6ffe14269ff72e39218e3cf8a323670ae62069704b38e9f160014fcc1dc8e389a989d80845e1b7c266da9166dfb5ba67c7eb84903ca894204ea3c380fc97c83b5eefa0a8e1c29991163b6f3c4a182da02d0a28b4eca9ff508161689488895cd6b502b5a4adb2926aa8b20f55f1f14a1eed308129ff2678c3b656daa0c7e5971dd80e009760bd6e527f886f914a6cdb04245e3f268b8f74d36ba8805273a67d01e7c4560a83b6d41471d50abc0134c8bf1bdc28f04fd81b5b3483d8574ca04028a927dba0f66864a0542b0c348259bf9b0c2fc511a5d7054385bba269970626513929016b378daf291404ccb9b8067015fe5a5114a94631407f930ed251091ee7326e802078ba9e0ca054b8e7beff971ddc56b7c7e7ce77c943be438f2215d50b3bc8c9a91fd4fb318371e35d97284a54987f2384e46fe73e3fc10b548efb5ccc77495e3d1653e1c91178950725c8a12391e471a06b23054998ace1e31efabada48a5729ea9e7419bd96ee8bbe4ba77be596baceedaf754ca5ac4ad7623e46002eb8f0268b8f9f3ac4f44bd9ea58930e1adc792a5918ce918eaa5d2c6a8d8a34d36e325d4e413adb5d6ad12393eda6d92766ce4426639b644c762f7d63d10580a231c0d2d949a08735a01e536a24cd8adfe77b2951158437b5122956f709eb8a91f3ff38679fd3c7d2540296e60b9151cc8219967eab30528f2f1736a12854ee4464375e1dbfd200efc6850b615457fdb9227d06e81994e094a86efcf112b23198eddd4ed45f744898e95f70c08b54f96e58878f90066f076da291033ad3ef310935df18a1ec1c7184ae9f6103d72f7b42f2be5d7e2d3425954b21423d8c707838a9cbe21c41d3f6405bbcab14333d9659655b9c6b87d3234f8dbba0f5e13a93620671d926cc7d2e32893e8e45ce8a60b8ed555ab3b888b386130e0e60313fc87bdcf96368d33078865ee743b3c979683d08b63b5deaac54491595658f2e3a2f27f11f1390d81bf8148328b2975d13d610bd196ab0eff4199622d60af727878dbc090da5f8cceda7c1f404cd1b34f595691f99ed08db9837598ff835bf0534a10c0fe7a4e3cc8bbe1f1268b816cf9d752d3113caa0b820e2a15deab489750f17103d5903ce4c2062aeb9d0d0e064d03f494d37627e2e5f043cb869c1411898eeac319c4fb06da4f4ddea90e0cd5c970823da5167dc746ad11a823967a188c45f13c7eefe313ed3d49910558c79f5065d22a778c5662a333b28b4519057eda0cb4db07c92c633ddffc5db251b8fd2a7d54715088c015a76c055672f5efaad29436e9d8f5bebfeb45dae770b08a0b1573e9329660e2cfce960337d29a3df98c8bf7bd400f4dee0a620adc0b58afe554bb35acb6a3755dacf3123762221aa95c4c9cec6086a99cd5c6770961f088addc1ab289b54af08379fa764b6783857ea2db73317d286768fa16287ce58397e048a3e5beefb887f4e7bde7aeaada410f1e73a41170fca1f8cac7567f6e31e0846a4766f03f667140bfe7cfcf8f09414ede47c3d1700c4db84c04ddbc242fd6d090dd1a493dba57b74b56725dc0899a4fd555bd3d9ea11473a42c96243f0148a3113a4937e4aa32237873e5a4189b5b32da07e9a455786d60f1ba25935e9fdf0b9231c706a644e2441f9e903f4c1468e164481c988cfe3c022e9ae1287136329cc2e66be825adde773b3e4d6125455851cf42d0d2f869d86af2c9511bf0c0868b41e60a8c2997dc314e8f334eb7adbd28266a4627cab616b4b612d129f0c709c369e4d86abb4ad541bb040cf139692dfc16a3c35b4eaf1b71e4c5fb2027b686788ba15e54feb9ee5689c038f21c00dfee12ce6aef638bbff99fd15c726a6e7f5e022978e43edb748c2f1614232011f96207c31e1d47b388d66b98faa905000b675198b810cae7569055f182ace474034a13a7d4e9e139f9ea722eaa221388d483de40ee5da25f33248b543cd8a280955af06312d05f646c444fd9a4816d2e019302cf3c65f64cbf03253557b3930954c13951f7bc741436fa3588012d5b7be2ce0e5543c64c8396a7ff657af4911a81e01fb40d577c014b5d7298d6fa5e8a06138284bcdb9c9a8dc0e29d6576fba07a88a4007053df6f158462d0324ae6751932b9c0552db8f4cdd49224ea9d9f1dd44fac3a91cfab0fc9194434cea8fc709ea99fe18537e8cf07974aa59cf17e421d0afbc58470ea807a51c6d8ab7968e47738216f050bcba075d498613b97abb3b482b6af2cd7927faa4865c9d3323d35822e23e1ce689ecc1cfa05a2b7964484f641cb1768610b552c4614b5ddd9c09999901c013aca942c660f65c3c706a65da865cd2d51bf42e4ca6d00820003a8d9babc4796c5610a364daa66c62783d7461d17d538e41be62d94c95f24c5fc22e91e2c04b356ab1ae7f1996db9842e9002edaa163e76b36115f23283188eefa3a40d9098c6591baab6c4aea0d023f2ea3324a3deef5942a3f7fd9c338d253424a5f169a4101c3b1f998afffe49b355b2422812b0dd4de06d1b7a29a801b34593a6e975f2dbcd61be3c6b264e5ab20e518b906ef43caeb479749a485d4ebfb1c8ee02860cf9df9647b5a9b6bded8916ae882945cc5b3c6f631b9e5f0d63d96ab46d00677c91fe054e51b27bce8024af39cf0ec3283ba8d59c66ed7ffc0d7982c6c4ddb495a60235655d2bbe5c15545abb7ee6defe23bbafbda0525f0dc6af316bb97b94bc868e30a67023a767c250728f74160163bf5f1f529d7ce05ba10bcaa5b5e80b8bcd59f214beecc431bcd895b13cf528ae56fc0f5a33e38ed182965be713cf073e3162d21b9844b3e6f4cb645bd753974a08964571e163dc5929c2dea5ff5a4f56429aa22994dd06c6e9606ca618dc909f967525ab067bea08e576cd5cf7d8b9b406eddc06ff2c4551b8280bbb1d74f269b5bf2b05eba780e98177bf4432e8490b257f637ed360c6edcf7276e837b8830af9c6163be613a99bd19dac659803fe32e6da22e4a1c2481c951ffec3e2a47536fcb57cd84157418f9e8e8eaf88ea07b7b5ab5af2961f72428f6bdbc31d328340a94a988aad226e8dc908a5ff36b21a5816c8d6b60e8634482ef12040cf17f278e4dafdc3bbec06692ba1ddf1c0efe61d32fd4fa5af59451c38e6cf2480dea46d5d8e0ab0947464f01fd57c0e3bcd1c05d1ab77aa8bb5b72a592117f662a4842fb27fdfbad2dc6639c80af4b9e0372beacc2be5daa1d2b8f27bb077a087ca54c1855665df429ffe1bf0a8dade0305f0f7983bd8e52cffcf09a6665f9687d1a2c6c034af9c4fe1deae8e07314a1a5b36a079942bb9fa727058483ea13f6531d187d5bbef6c19a56ea2f5ba7d90b6153577a6d0f49194f54e1b401cb2c8e60423c24b9485b63697da0b90cd821f378b541d89b65ec0fb582d499a2f5c25cca60e71f204e2aaf0781ea443cb4d57173d4b205a7a8aac01190df9993587eee56af083fc62aa9144b6cc02849412e3fb9541882738203402fa3fe787571b700976c520141263087480d8792ba9d398a4fff8298d35652f7105dbde4996039c818d46c8c74e12e34711149460228f0bf0a7f0b7755c8432d778c8531ddde08c02d3d13b65b0fd0324d0f335bb8dbd253b180c9762d87a07c579b49f2622d04590a308b43f2fcb13235261ce2b3660d86e133965d87f43d88cfb6282d4d80e12022ad90b3ddf26e2c97f3541fa2440631e892c51ad44f41c3e5cc3dab515851edcc81c586b275e49a724d93e956cb3b4e0679e1ce57bafd008694bf36ba40a8dbed9dcd76c058cb81660b56f341579fe8e586c5d259321919738cab8a1c3c1ab702218a2adc6f9917fa34ab750129b8657570576499a071d7640de7c66c05236842e76ec78fb20864ab4e9d2cab4013e7b65b0b94609f3950cdb2b9581350876b19475bd722742b318566319a8415c011330828160646935c4a6ab0023c53dc652b8b6007e200d1135bdba7d67f5a3f8e41b95f542bb24a5df08525c205baf7459372abbea27d8b158bf90a5ef46e12171e80cceb35c90e108f84c168e87995020b7930450d77d2163c824eb6cb7376003c19923b98effa4a4c64a71ccc8dd94369b2643103b218309a3f5e8d551008de9e6151b7f4fb9d9f82993e0223225f35230b59067e083e11f1a9d3e0b80a62d6ab8cd05c33aa3a29ff8f14c2fd3651ec0256737cec9cf8f6216da733dea3390d8b0b74221483010259932829b69d8e7a6d470ab1f340d289b2078e9c33a9364d37f4230ab17b4832a6ea86c2a3cf7df57b0f2bbd86ec64659657f7ac3b79acb07fe56b6d9a9f3b344f1afbc240bd6a15c00cd974cb484cc44dd95e9889b6c9160f6a36e4b326678826d2230a3075c206ae725eea9801df5d9973745729251e9778a99371cd383c78385e79ae942b6c41b47da8dc15e81ee894989254bcd515cde252ae3a0c9610a023267f7b019c7ab7804d02c15414b955c9d71f9fe2ede2d8475b114b913756c37e57d933890f9d0b0c60e6ac690c62ec3b12d5700e71ed8c975a90cdfc3c7498ee04071dc590ccd06d548c5d91b2c9ef61b216560be9c887a4e5c061ddfe04f9c50c46491b4168fb2ce1cb7c3664921237fb1a51d419525792776b5b615d63a5f44649d1de99c63deca0162a7bb213fa858f22a1a294934c4924112b56fe2b81ca0af5e4df817690ae6726ae24c18ed18139dcbc5534e7e5001cb2588290af8c974bc284abdeb0f2741b017eceedee0cedc16af16005cbabb12607273e0c8f8808d3f37cba3c5b0cd5cdbcfddc065e14c4867d660ecf1de8cc0f08185498f07ba5670e4ee206e3e47ab1b10c3384e84f7d40c85b3660164a27e4f6247f24799ac3ac8606c630e0efe8245171e2ab13686fb18db1f8871acb4cf292b48317265b61e14270c443aa88739e86990cbb8b1108154f28da0dc93bfdc3b8315ce6046d3d370620e6065a414e274980bd190d7b65804eae04ef8782ae5b95baa0c404f39a30b7eb32b31d8f1576237cecc85cc04a1f8aba55345cbb71af3b5b8a3c327ba4c51f8e7cd8784efa6049e10ac79fc4718d576eb6ceff8f83c22c394ef5eaba2d720f2fb042f6be6d695947b8cf972a2920fc85fd17a54364aca817c75bda24cd244d81a79c30d400bd219d9723efe424e5460e062846388787db7e673edfa57996dd9a5d83009bdac74db8a2ee116b2c42b82011c8aa32fb283e9b836de14138a81139b2f997fd4521702a54388fe52b8aa1f95df26436828004fe13444a1ea33a1dc3b956ab22b97adb754ffacca8b397dd8f58742841ec699129718f11fe2c094b2a4161a55e261dc3a2c77696e122e379f97f2668214596bef74be4d6a84f20f22eb7e9ca680b9d33bdd65c39461bf902a1c0cd94383ecef820b518e1b57ff583653a8bb9e32e2d20a97c3afb77c3033bcab41cfd93e5fb1bb45f2139a08b7fe1967de43c69b3a541d88feb26d6a4af7fa4d6b32bc3526b473144b0d461eab842cfa0a7470b50d7215b7a6f5e6f5ea1aa26beeef4437d2a4ac44a68031b09b7ba40186594c36674401a0de29cac6ac1b3a92ef0e9fdedd9e44c60a29b2a765844376a0b52612c6bea042953da1b3b4b3bc9343f55a4ba4bee8df4f8a8c99e8a7581491fcb2906ccdea4f82367362e1b8eb0039c611a8d208c1a43c51cfba7ff1b06a698391cebc2eb08a5a8be5ece3fa2a84f2e927b2db9704b90ced7b11bf5e60692c6be6f1218b1a015a15459c4ab88236eacc6f36d58bac0dffab6ce6abc87f5950893a2b524e5b54548594bb716467047fe4cb3b4c32c91c845d4fde8c153564012fb54776f4729d5d7fc6ccc3e8daaeea2ce448be3ce28cbe3f4970c1c20fac51df700682e9d9007dd442a3a6fa514dd21dee8cc3a2c089534308fddc0bf8ee4d6742fde2805e4099d27178defc07f6fee7b474de3fcc11b7aba4ea9476e7d48cd1d40e141aaafff27dc7f4291755223c515f75d998947408a0e2821f86a53caf23f17f2100a5eda6280288bb1028f0000927a3c51628c482a7d276ad8c4887ed5b1c0e90fd6eeb9a965426f7d8de17bce152984c76aef60095ae8c8468fa80ebc0c83ec01f1255b813ff2e564c0933fd05b6716868818a27f138ee2c2e630ca49da2760c5f8ba5766ce264f9e9c6857bf4ffcf9c7dbdfaea63c9c0ffcc96b519a2765d2a0d7e11fce728ff440123dca04062d669e0249a4e6c1907df80100a606f5f6c13a21f755615a000f980cbe2db0e22e04e81b02459e3e99bc2ecf4591753f6ede9701be91e17c5663550c949bdd498eb0ca82302022111e25864b687ed3934aa0ac0c38e0597cbd42a18c83ba32f099cb79a94f84de00df861f91406849bf57d7ea6bb132790fdf65be39040858c8703b529c61282f1da19d2a675193ec74e5b2063b6f0743fb29074e56eb9b8d98fd335719a0c890e7977178cf3b10a8745e6629de440587afdbcbc5b64d86f22e9f1c80e24432d42c87b5ba9834fe0841b0bee226534c22ca22de25498f9f4a12c0ee1b8510e81aa04b82911c4009fc6aca705ee8cdf5c208de15e380c26f501f142fcd92ee96cd33f4a4530b7ed7345405e6f0b22c78fdc00cde1c15af49ce7df831f446869292e7fea6de1ba63b44a1ea3118165501ca0f9a811379179e5efadd8b1501147204535d6890d0f1ac503a3094845acba2c47b122d9124b0b871cff4ec99f717ecc2997ca82f719e5afcbdfcf426ab20f670dfdeb87480152bade227ff7657d64f6e4786338578efb5642da1e8e17c975788e013c3c7190d6aa63b3a2dfd50342fc2e3c18dd1cd5297e668ca9af7d43d5420e9b9b5783b85634845019c62d9ecbc851ed333db894950aad994c6aebf67a2078e025627664a1574b7547adb496a6ad03944be562600ecdeb3b059af34f531e825bbecc91b724004d3a23f2b306609a82ee1daeab9550865b62b8f261ea0a6bdf277a174fe8a61e4c675e4f91062cbfedb6dc15b6a1b9de2767f2fcc02fb84d9d418a882d498d449efe22266d1f17037a3daf4b9431af68acae32bb3af30c1ca79fbb1361e36624a53eefa1e168af7eee53407256ce862febcdd93507662ee1d5ff34cb9b21922bb7c4c18fe5331d2ea13cb8cd04cab11cca0304766ab1be3bbda347b21b2daee5070a3b1b30a4a309120c6acb9b0496c8e194a8c23b5508068aec0518ccf220be97725d71d80ab38ad713a788d29d7c680552c59263c25fbcc933d17b71d718bf3f01158d564d81f3f6d2047cf9ba2b62562c55892a49cf70d795b0edebcefe88b93c369b257b467ed9af22b3a28856beac0098addfe28b868a60eb87cb23e00deedb1497768386f0f4523a3dfdb533243c3db1b8e8bbd96cec1ab8e9a39a112c2449805ac11416b2fb35d5acc68bc7ce8711f5a0c9091f2906082a26f093f43211ebb28fcb49074d98550ea9e4a2f6d2e8a4660fecbd3b1e87040fd6f47159b25a5e2792b12527bea93c59abcb2341c6bf08439f365de145bd360e60abbc0b144643373435fe2e66a5e0414d57df1de383f27d5ebe5aac14ec2af9758964ec76797b1dc27f0859c9c507860a101358a7ac29f2cf479c0abb33835457d57bc508eaa9892716553e31e4aa718040d290dfcca986789e65c7096b98e70e1831713a305a4832f2dc1d9b82018650ea1ad909868cd1ee42fcead511dfaf4a38253bb0d372802087998760f42dc1a288ec8760979079db60740de531118767e0e1e3193c3ccfc2a624f1421e77f82e5a927d14ec6fcbc62b91f6d67688d54ddba655002e11346deef10642640bec650d143b88277596aaf2412f1aac868abd7fb84baa33ed754f8860126085aed77fe6cb237e65f33dd8293d5f1d4eb7e3c71f106c3855666a4070642299977095cbe9b565a733fa7b7a2d0fbf90f5a80ae83226097203fdfdaf9d58515855dd4cc40b60b6f2a7643f368c140c2a68c93d319b58850b0369248ef6f6f265324bf53ac49dc2cb248f1c0c20dd61b78abf1ebca2cb18e631cbf8f58fb540f7347d4eb46d4f560ba2297a2ab076b161f84dd69904a37500993d120035d476b613878b78257ec2284762a44a1e95b3d0691219500e4feb9ec9555626489904216912a61bc8c99f534531c1322d919c4718597053f8e68706a75604008c065b9094eecf144e09b1488b3002be84d6e4a54a35eb124de03196b653810eb42e1473be4811dc57aa05936c56a059afb3b814229abd30ec6a602acadf77aac0a6479c88f559333fa36a1910a79d3443274a36d49b5e7f89b68414cdbbaf11867ebe3d2a36c8ce5b67e74452f47672d07e7d9e542171e7068f1832bc155995a7dc7093e06dbdd5b47b326daa6ad659eb55b08b6e793735fb16b68cb16b88bccab69a6d3600a120c2510b830d4a856149f68360055d52b69bd14d0b2636dd5462d979dd2f16330f513242a6194436fc133652036bd3ec2294d94f621ba1ff4807ae04a0373976375923fa32dfeb36d2903412eb889ae6f4b19f0fbe22020e4d20e56e06629833261a697a8b74a12c86a405cf6903c21856b46654cf81f726b3899d67a6175914850379bfbae2cb240aaf9e4253410b1ac21332caf0eb15b804dbca870670d1591fbbdca4324adba945336004ddc1144c899a165cda946bf11e0ca39c77e0723fff3b81626d8a625f006d80c5d3e1c5eaa8f7c33c1225e6c27b88089dd4ae91f2e506cdf7cc9bef5a3c02fa266e857d9c7aa316311b78408a7c401804528c702b57c0b5d763e7dd97f06b5fc7249635614131992f5e241d215b9fbd90aff1a64c5b729f85fbfe9ca66efdc905bbfaff6e684351d3c3a0634860b6945c31e464e096e5a7d0bd6c12cdc3a3b74595a97c166969bf22bb9b1ae0c6496e07d0e7775ff1466196b7d0ea790f35bb611f2371bac2b7d6b283ae5163039e4735014a890284450b2158a1eae95e2790fb0811ebd6bb78a928a2fbc5b56d9feffe49ac361d90c97ca0f5a74ecd04e1ae98c2945290c2e4bca2e11c0e07e048d182f26f8c1478c6413c1d36cd3ffed2e00daa2d9e929edfdaf4a6fcd99a750ce105acd5d231d3fd77d06d0f6df041f46c0ed9d858cdfa27f1f7bb7c2a3d2c7800255ea1d3da2ba7422ad56ff5720725ddfc2a0db6f5da0e7cd7fe37df60aeca395da2e77bef94700683c70a4ab0c6094bda8eb236dd3c489b5072438f76f9fee25b4480fb07803d2a863150fe80ff365847d76ed606d8bcd8c53e15a30bc0639e36c6278618281b927a13f68111134aea64cac007ac1b9bf52dc938809707ae8b69183972be68aaff327f7169e2d1228069d5fd979e303e650378a741dd747652fc9186e756fb2ff2fe13aae4682bea633d24be85214391e8cfe38aa05a72d4f1e84072ebce7d24603562f67ad6e49bd0a153fb99a0de77f915c66a7c57045368fc623fc1992fff8f5ab008f4b6fa0a283f070bbe04e0ff9ae35cd3c02b88d669b60486cc3066a12cceff85fcbdc6261e0314ec3b038597cd1207d33c1cde2de9ebd7a856d491ba61d084abba56b8fa0ae9b014de35fd6a61d8bfda42b7430896dd820d184080d588bf40d65087167b3b88712c75381b77a95f2a79524fbddd4a2f3bea680e655a4b22591e132deea53f7c44428d7facc772a450ccbbea805102772080c4a44bb643fa3b27f4f05574ffc3d2a3a5310726dd8a143da8c10915b1d5245497c5b30064516b02a5fc8cc129f10ee97896126bb290046f09fd177ecf9ba13f12abe904d2b517f49ecdd2f73e0948c191be4dfb157b17a35a02b9134124f508876b0b51fd9402d2f406ec58530f54e7b7c275e1e2c9ec09e935ded31fe63ff3579b65d91f03f0dadcecfc09b5e710f52d851531a33f07c11f06fdaa7cb678c95f069614dee53992b665846d2a61642bab11d24e7b8deaa8a2c01699a120db70cbfabde42014e331246988a39f2d5d880822190f2fa9b316824197c4b330fd8463d13855a88a3ad2481447b00e94a296c6dd4e042a6486b7d341ec64ea6d29fbf46346aa4e169d4f92ba53385f663ec781ab394ffea238d7ff4a196db3dbd8fc2a149237bbe3504c975d0afbc0e75e494d06d78d3bed49b10344dab1b61d547d6d0480b0a24b10d1c1a1ede9f6b4a71d56dfd2da48d403806da531ca75e24bb23cd52be6e0f86b29a27e6e587c9ff12f2dc272406baa47765c44b2f7601a3879e81c777d82a58469829b74697cd3bf6c8f5166f9a3ed56a43ce47183c7b15fec0ed66d13dec7c7b3497a4098b795c78fb0ef41a8400a42849adfc61ce9c4d9219f761362d65e7e8b26de09cc66dd46c4cd2a34f215cbf26188535a146cdc8cbcc8b87fef353c1bac4aa6e1fa9ded4bb94a166e5666098db7cef8ff689f2fb33eaa5a9be2e995db34d2c3f775aa6a0bc37cebe4ffceb42ec15926d545b2264879483d38a68398cd7500fc8dc2936ce2c8b4a73c49bcb193cb50838050d5b23f46db21b6111ca201b1272b48cc83524d064d36176892f1cf5d80b3bfcd7043cdd52102c2f192be4e558eb7fb1a362c002a2116ad39b697022888d385ed42c192883190c8e156a2cbe91596d3a840d178150ce12de2d6ae6f1544dfadbbc1350f17e94b57431d4c138908514d0d4f482505add3888462aed9f15340d30f361ee83b81b392839923d5f50c24288d6aed45cbe30d92e9918df682e43cc74648352e352891bd63ce7625cecb128114d2a3d8b29e46b4a791f88ccdb737858cd08cafdb9dd612f3b3ad8d20ed12b8324fdf9b1263d0131fc3f94e437698ad9a1a5cdc8a6782ca9595084fcf49fada6cfd7e83e1801378a9a680948197722c92df68fd42c3bf412372163b4cbf1ae9fa1867d3d5720ddfad74696480196b6027e2135ab3c7ca51165b949d8c56005da63d05a910f4efec09b5048cdaa6e2dd64df1063543bbb980ab6f0b8ea910163ecc4255a0626162659af13c036d8cb8c32d70ff8bbec85d758c3d5e93bcdfa4d485d8d0ebdd55f126faa44bd1649c05074c47cde296bef9ea8490f3b9d5e6ad35942fea51ae37d8bf51334b60c4569d6f09657484f67e5ec83999b978a146cdcf03ea56004ca3e6158c838acbc3eae3dfb0fae757ce541d9aea55946b2c2aaf5df747158d2be5879fc4c1bbbb4346cdb5c0546ca03f9b316a664fb0caf1384a16a63f38a62fd11d56050196b73cd734f84aca9de410b9b1d89184f241275d30c189ca7c4c86f321995028a6662757d45c0697746e766996397c32a5f3f65b22ae579f710e5b484c5b81024f5968b49ba266e68245de5464e69792f9a02444aa08915ec0f0375133e9fbbf5c92ef6756169833ecea4f44cd0ac7de5aef05ec7507dd1e06fce39eebd493a48bd47775baebe960493d6e3b9a91a95b3ae396d98d5dc7243de6943d57e34b6b676797d042772c436086c17f909fdea8c2fce633196a3e66b28449640d3f4365b8c6c56c1b7e3f8584626f65869a152c762278e145bfe77e4657688a0d00c04ab1071561d2ba481bdc43bce715723282a5220ca99a09ba9fccdbb42ba2041f814ec406e9073bd6e39df7727c2ba49258a6a54ac5d14e26ae88e626cb0146d74158fc170a2a65fd5b3dda8a0b6007a2d7883e4757a0d70913aa1a0e71673f8300bed97688f8dde82910ee465afcaf844e9a28ef8d761cbf5bfdbde3d86c476a5e4d6ec49066abf4b4380b608c3e6aba4ff0a211c01e679ab9f1a85ba222c6244c83040e872b83a1ddde3329d4a74fde63eca5a3f0898fe6751bb5b20a2d081d34111154fa4c81e5b7579518b7680d42d0dd971255adec5d12a149f9d783eb957f6e4594d5e196d0376b6d5e9d085d16c4b3af8ec7255aa81b1d0908ea484cfb2d0f07eddf71d0e48fb94e9c40cb4bcd24e9e7857432ae56809743cc04e9afcd5186d333d4ec982fd942c1f054e42fc39112c45a8c83f9b5b68a853d58fae328033e961b38821c48365112d70e4fff10417dff0142959c40bfc0472051edd4a0e310fa49fdcf77548ed040f9e1b1ff7894f47fc2dc45e944064c0f338a706a3d8c066c0d1092bb2a958fde4a0c94df30ef134595edad2fcbcb6ab11e2db80a1637a97f9ae18d6f86c2f714daab10a197078817faa3dc075b835d3af2b90c8db2654b27bb04f1ecd4876104939856b8c0b9af61411c753ded80dce74b8eef08d075485df56d9c8ad94c4a3b450501df3f778e572bd8b951cd0e2c5b3e56073387332894885711d5d5340e8af0b5fffc36a115376d6d2ee18baacdb573a52841b96134aecfaeb622150a3363d60b4ee8f60b0918973cd0b260d2234342623f9114dc5abdfec730df48b27c203623fc7e0eff065f8870972c27d6dcd4d5a4a3402403c9d456083cc9ee3ef928736750023cdb938cb1b946e4a38236c523f880b120537c8f3fcabebc11293009cdbd821b4a860f0a359a6a6ca952bc02959a13acf83af0d06123845334897dd1fdf3095bd94e0d1a76acf32c7e14132005953cd750172aaae69e891988d03bf25ddcd0ef7a850cd6e5cdfe6fe5453f1063a5ad81b3b4c3a834091bb912ff48d8e38a5174986f36bcd219d07a510f4aaed8f3514024c321062cc6ce7a2320c1c1b0077de004d01a716194446a479b4b87b40707dd59cc5c0223ebda9bc0f8661f69e5de5eccfadb282c6295e5837fb580f33b74f86fcc61fa3cfad6a91f0b2717783093d61693abbfa5a93c598610b91a1c4d42480037b43b1e51f798be3052dbeaf2373ca30773964cc21e872280029a08fb83304cf2022a7ee0cfb1a8dda7b5bab7cabb053c443387d3cf567fc0718bd44f4463586a70bca1e96617eabe8f04751e6974590b29490fefa2b3e3127867cd3cb629ee02fa9d07ee2363358e6db390f8d0bd54c17c278491c9550d62f3091a9c1213e2e416050a1a8c7585e0057c308223320d817327b8e94f9915d9de5694ecce8847abdd0751417057bb2e368bf53cb7480d4039c36742260c61dd744f453b9db1553283f1d37f75e172f10d9589fdefddaa015178715710d3a2800c5e0a22a1d72910249171ad5458666eaabe3e246d0368d4a2af7e1294622be487263ea466ded9213bc24a7b0f5ce42e19b030a3fd81aab6561b778b1acad2912760f548344f5b1fe012f83249463a91fac36906e69b965834a766456bdc80f6ea8d971cad07cb163dd0bd1f50c41499e311e9a703848ff950c5604e9ecb50f99e5861bab58a1be56cfd56c208706f8af76805fb564fa4693a08265df50c6eb67c7931b488f1baab70773174a5c28a785799e97f6875de05a7774939ea4426e7ddf0fe41f2c0909cdccbbcb788fdbd48d97bc55f558a64131e11c810339eaef0e82770ac45c90b97bc780eaf7b87b73eddbb3657d63b76d97d69747c14121fc060820930e3b6e1e2280c2c73aa7fe1a324a5a96b685f9b0443a806ba3ec547731f7b8f4970bff051c90251a909cb766d1a697bd2e693c36c4ced36c810038a5afc9ec176049df4e1b4e72fbd3c799980175126fc8bf16d06c6a6ea4d3e94c2aa2a3878367635e3326b3dfa017a04c77d24743e53e072b6b830401948ca0b42c596ce9483a1b4b8ae435e751f329707d2f52c80f5a1f72c76f32564af24ee574a157c788c3da86ca747499afb6a091e36ec7c6d773f45581ab15afb313a1045ad2d300262e7f60025b337fcf9441ff9c0e3b4e663b0326265840cdc2b5b4df7f8a519de49da06b5c77e2d3ba44f0cf4b08aa9b4338d731107696481c7666c06912840d68c2097cfeff95df2f60ba0d481b22b9441e2b1c57d4318e89a3511f4d858ece53082dc6198a5549eb2840cc222e86e49efeaf1daaeeaea8ebfc9930b5fcd085c092d2add35fd5da326b4f268adc358e67b8f0ccfb2eebae0dc3c31f4e5aa58f36b4069cb201fb0d514397a015262d2ec36b409a2a2a217dd60ada5887fb8244cbe5a328fa07db48892efd90a0fd693b34161477cf6729cd62a0e7e5e506765ca75a2f2abc1958632c53493e1559bafa8d82c20779af442bba558c0b274cf4f8294223270641a245336b71be32b75cf878c886b0e8e1bfeee4181029303511e058c0bf5ee7ce296e80c3252ec3a4ebbca62ac390cfaf573db8df4560771ca2edcae35799edb494314ccb45d31b7510791ccf11d503e0a7d864fcb3c57fe801232863b3d4f1e4f89e06b85b8332588fae16a800d5b5475137457961c5350c01f2f101f8e1396bab5fa2f288ba938efd6f19207c0e9aa75681a5d5f240930a948f67d352e73d50496a98f672c97aceadb2e725284b99c171980f9b5c1f22bee24ef379b5d673bb5e9f3bfaa871daaf6eddd2bac49c013f27dd36534dc5d3fd0c2d9e5a4339bd60f0a4a09ca7e14d5a91281ec45ff1cee3e2d456f852243a0c0d32f887d00d19936ee37e663122fc6798f7b1dfd3cc2fccbe1b6bf78a31f246a16af0b77833df327b3798083c4d17140dba702f4fb5aaa3d090a8482a875f45349e3186f2805a252bee9c6e42ec2941e73d94db8677118f110fe729cad428c4d123aa907df2bb193721b1c8017ef2370d45296bce7f7028cbef920be8eafd38f5e325dba1517752c2f460b50133ac9ffa264bfef3d570ee497585b81faee653a28f7a9db1d120c6f0750555d17cae5d869419b5a45fd800039dc979fe1adb447e2b4017556dae3abb121c6cd400184fece4076a4b30a44e2c40c860da55ff075ac5ffa12e11c21ac7cad4f65e17c0f8538962c3ab5cb5e2ce0352426416411cf81871705dc8063920aa887a1b44491cae9e78838c1baf6ebd90af718df28c531d09db877b8ce84f49e4d421aa2ce75d16e21d2c8cc284110acec2d610febf1ad579692dd004ac28b35bcb9c54d27c2dc8dadb749ddf83615a76d12f40e48f35def7ad54036075ed09820eac3d504f24b2d8826f69271fe2d40e023be9b792629fae805c2a88067da57ef5d0feca1582a20c39c97cadb8a493ab16d4249eeebce27e02a4c2dd53e822f2361870148fbe210e4645d01923f6e2ab6cf5faadb67af8aa283daa913be0d3d31b886358823edf43bf4e32191dd987d2b2653bf16e8bdd85acbf1320da62eed80ab45ac955bbbbd2dfda60c93a1f132e9e43738acc82bb546838793bc55884309951d726657b38b674d44b5df216efca7d18bff7f383c6cb953c3633b956f75a8b1038a4b3d67b01e69dee7be60b072678be9f790f2fe645f08fe664560e90f3a670e336c36dd147fb118d17c16a8b6c454b310aba7992b016d40e063e5fb7d64550f9458d7032122b8c445907a49b0475484d9e3440e94c6872139ac2f957d596f9b0c54e88cc401022e34d0d4f86283b37c169e09d2a8a40ed931458fc41c08e2f956a93b6196145837e50f8b1d0d5bdc3f888b42ca105ec609000e4fb373a778f0c698a9d4b1bdcf03746f2cf0546bb2333004f35b58256d1ab25917abd93d4cb61675df821cdf0759b3f48b19829e041538423513e913467b4a830ea57e2200b3c932e90fe5d395f4fdac69669ad7b6bac9496f278e585583b78c7b118b725539ccfd0c2b96fb412bdc2b3b4a9519af8aadd3e11ff1614022199e60e739513a7ab567cf8496c7d14fb6f37802562492be2c87563f5cd5c63e79d55a1acd42057841aaba3edef5651b26ca6d43f9c0f36a05b05fc9f159f89bb3bca882171403d2c7d9d523bc829da9b69beaeb2af83f70382ce0c2e61c65052e341ca27e0d2b97f676d1aab539258961e3db1ba4199060988b36833cd10166960c9f55ba2d2a6d9c598151296bb6cd1066a740452eea5ca83a6c84c019073eed6e698da24ce3e03fb3ea60a3f891e7d89d910506b2fd14bba68e114a6b0137955e8a1f918966b94ce6200f471030d5770950002a17aa6fc82cb1eed1cc122393e4d2b537a1035c3a02e7e714e814f70e1a72b0ecc65a5ac44ea4f5a925c16a881266a98f3250e540b72782fbe9d76549e291108dfd200ef590a815d54185498b338a10185fda89c8811479ff62b0aa99dbd880ead58de12dd21b19c09fa1a9ff2051892c79c17c526ec6a44dd2dda1c64170794eb882a33cffe576d7e6bc208481027a591d88ce7e3672056c2d2ab97cc046eedf3c2ca738756b8212e1819cbd5c16091ac44052a0eb44813f8636b24231d54e8995fc27eebc13f7203c756c024b304f5426107a0f3ccd5c1da7dc697adc61bb1f73b348b1e1107cb9635ca428f33025b6fb03220584b0969b418e697093830b7e374e9b101d851b42c80fd0371b7c51bc0ffd53db8be0aa5bb8d58f52e62dcb9474f6d462829fd117b962b5afb1814d33ce7857d86c303f0195d899e26e363b59c82b37d0cfa29c515a96c05c0c555ad94dfb52ad367d48960a2d4b6bf357adf8be01e2188aea388cf2f05b5270f9f7f428002b2b29f60ff63d40480d30cc23cd5c27bb83050e9b7f3ae485ffa68723c61e29ac850a70262c5f8adda2eb2374aaf94b1b169ba8e7b0b761125a84e9e17f992759af0f1ffd9ec8ef95be9523011e99127e7d6140a426e4141dbf404b58c651ff94bb45c181a85ed24214e7f7bbc0481370eb6c168fd0f22388940eddadd960599a38ea50337a2a9628290b2ec40aeb6cb90ad080c1c3b9fc973b41e85d5915eaf4a668ec1de8d9a12f8ad98549139d116f4652d80fd540d4a04da7d85ac68664a90eacd345499d96c72caf8872ed680a5b50c51b19e0bc80fce10ea6e50ddd4a0b579d5521dbf871e99344ba926082aec0fafd10d34da455b09a323d6b2be95fb127b5b63613b22e8eef7eb87b4df949dee3f197ac912b36470eb754154c855b056f230702d5b37a62d95cc2d792714c946379a6ac2cc3cc8214d903a8394ce6175dcec4afb435a6a3e87ba5c57376851cee485c0481ea1547637667dee15ab1c67be1d0c89292664e841de5f1656a90ad04fec771bcd56e9007764167c1f45f66ecc1f6f3e4e2518e113d87c8e4926b2a3ddeb5a7d09a139f6abe70cf182398b9e02e0c44d8058576b06c5303e6f49116a2b99a783f19c9aaccd926009143bd26eab40659bb7ef8cd502b7be8423ff3ee3ca738f27a073ec46ab6be789c157d6952fdf6e760d1d65aed20b4f8b433386e7326e3c736398fde62fd582347e1bf7063fb33e87c68f5cdae66518d4c2bd22f38464cf92fb768998044cf67bd0a6bee224479722a34f37c703bd059c1cb5eae6b8bc480d580af626a8b6077f1474a1c593b20f75f430178d7e2eda4e93f2cc417e524f36436970eeb48beb64c00521e118e88bae00c718a5822ef1c0e44f0a4ad1eac5b8123c0901eb73973024f03429eb8059fa3118143fa4b426dd5adb900875a4e80731665039b82e09bf30b71fe92e3d260ec5ad3cee71ee480d28c69a85ac284d05617f8c05c8861565a3c0ed2a18f9094dcbf87c652dbdf039abed8ea7a185f222e2c97815fd2171931a8997ec9704f1a20b1b9eb6bba32c09afedc531290f2ac9957cfdcc68e75b3f26c1d90ae208b0529d479296172265738e3622261fb1a142e4f65ee6ad0b93d4a830e3149159953a8ae2cbcdc1c9100a51633144b0233ef67d1f684ac61cb60c647a9228753a9533b108dc7d83585e65f4429100db52773cdca60fdc5676807b2c29e4cfbb9374c8dc10e343d9c450bab9e4c0e0fc76a61dbf5cd75a1f3a16b37400f036a9ad6788b33392ebe7db4d6d8e62783b9d868b496484e79482da57da6a3ca8d09a0ad88c581cc68442104bd5cab9c27a1ba9038612f7d774ffc5d3fb28ee32825797e895363d1b7c401bd536c0e388cef100f08e27d75d56ac85fa4e0ba0c4ccc2ab2fb7221814e38ed048ba0a3b1fe20fb1861d45bcac37521a216c6af787360350f44d193f297a7c120311aecd4f4a5bc7b99ea9e908dc6c797e9bffeecc0045b9d16938f867323cd13b9c262f2aa772899fb246ad8dcd001a521f683ba62ddd0305a91321077554c4e7746a4a338a48cab08bac32d5109d78bf927ade143b154deb8dea8c30fc20675c551ab2a2279664349f42631fdb5a5c3a561123a9198ae945ac39c4327efd05d0d5dd68115d32e8ab2da58633e97ee61977bca4d52f29c4f01e38992ec211ff20beb0eaedf4c35475f982e3f31cafa82da8d50ea950ddde46712b23d6b4c62e19e0e855d574fd98c28a1882b0284069eefd8a4099b94d6b50c6e24debd2fa5f2a02ab6bae5c10c2b2a05c05f3ca80f254fd890860aec3a442f49c35681cb2595881a494ba56dbea34db1becf4fac2024447c70201d398f5682b915822f690e407d3c6107402a7f02f50fb04331c70b3397d1a0b03c083b574ab78ea15bf3c508712a33cfaf0e034940e709a2db66b558ad2328074b57fe1c6c1ba5868861d707ff9bbaee664283de8e41f99cb94a64f16b745866405207e7c4c841e3d902d828b3ca09689a443e6140544bfe0b59f93263d7695c41ac76aeb062feb5742c5390aa2ee52443a8a88e25280fa15ceecec44e87243d90171af93fd2757eca2722a3636945796c28d6a1a22f729aa6f6207a34286acb0c2c8d569fb004a5d63424fe79cb6c15d1311fb1899d7b457159895ec05c22d423bf614168001d7d84504291758beaefba84665321fb38a5c61a4ffbe893b9f7ac6e32b69f327eb495e02051464fdb1d2b4a443d8b1b505052e2aa18b8ae660e02ba19b1edc4f7514a84bdc81e20808b742f029e891601e12b95e538f620d1e9e96332ffe9636434a88f29ddb8cef0994a9ca541aa8fc589d1c68cf7541c856d5a827b309b5544fc20ab6075124509434ecc5a16183a836967ee53bc53173cfec21e659815b3b05a5466e7daf4a7973bfbd415294c1ef82aa33a006d9d4f235882fa48adba24add53a6f1cd5e9b7133d5ba23df6d8541740a7cccea9cec83b783bf614cf7640dab7cea718442a03ddffecca23b30efe244522166e863ddb9912d746b650e9243808e4c04cdfd1654a395049efd31c76d2f9cb1d01881f1c4263df0a119bde59ca279d85e23cacc60e30c56c1691f03ad389c38d63d6cfd43f53964260ed610600b63fdde9ee66ed3ba8aaf24b787af1384c9ead95515139f13f2f9fd42797f2ed381bf3817a9681aa4a8a79864013e966635a65d59090043afcaf254274d97b116d2df16274cdda682d3386a28e55452cf911381d2cac3ba07fb004339eb67bf1532676597fd00f6a79bc55e331069cfb77b8be986477031fd79b540d529601ff38ee9230f7674c7487ea436ee15313da24869638342e1c3d08b3dcba7b14447b7ec125647c3cf2c5546e45bba5c4451c9999425b9c48a9dc081a80d90c7811e6cae593544b9f84ba5f93c62e01ec903593c6a7829bf2520a8106f8fce58fdd271415947b6a50132de245731188b725066838f490b3f463fa483e213b5ee2e74618277a691177278aab4528b901ad764eb207147f70ca972b177ce88de4b50babc7610d3ac42e05b8ee7c1b0727ea9348dc8fa3e22c538c41bbadb48a5f6c1a71467568000093673e4649500cd95765497d1897e1f36207d5e144970149fe327884a987c15ed78b13f48c65c802d2733c7bef5e3c6e7ff9da7d072a717d0068884191b85adfbc7621de843948425a16a5ee3f64274e6d2583e89c6773c024fdaf360ede8913d7a8834b0546dd101c196305127687098a0fe1d1f12727463e848453f15a0f799f873960d36353f35898c7a600154b66bd0010eed898ed0537a38908289be2b500dd3b58e6066b1296b679100a8cdf6fef73c3ed76f3d53a99c0f2416fc465c9685c958dbc9c6e667a89cc24ab483d258899aef92d3cea39f3cd983fe9744df868b74fc68b045a89dcb44bd62d4f77997d0b4e97bf5365df0b694e829b325e689d8878c786e732fafc195c227f85ab4f2803bb19a702051574a5f058b746ff62bd64e36a9f19bbd88e8a6ebe9685381f76aef7516eddd92f0e26de040f1e30e99fb7ce1991f2a0b37f037961394f0e8aeeb0a19ab84b4257a257e419c0f497496cc68375b1e1348c6b69af3cbdaf292b474434c91289f01ae3b91fcda47c0e5102136418f71b37b9180827544d83d1c038f0a172c10528513cbf8606436a13ae1848c2b6623b346e65f30f8574571fe28fa7196e4151c8fd6c1f44c7dc900c3bdb93d13ea98f185e5bb9c02724c6fb394cc6e26ad0cb6e0e8c6c7cda5f53915715b37eabf64f7b7b899cab0ea5f510ac84372c007661f14cd3505f64732dc42e1fedb5e8baf47a6b9f44608e7e5b5f17a4c8335b5b65b5cc62e016ecabac3a6ff62b953ccd7e4c187732cc6e8206aef7d08f575d50c8d80de4bbf3bf81b49c72ef2ddc0b2cb7adbb86e0f6abf3a13eab615942580f553ca436fade7ac08893bc57e53544f221819c715215c89d0e83ca248fa98cf06379eac253d938f9aa1522c903ccd980100f1b939052ef9471c1e97c4a31328e17d09cdb6c7c8a4c82ea413ec7abde291aa1a3ecbe16a6ba53ccfb9558d9ff19421e1625a0196b79baa39bf9337d327c7d980442b34f5b34295a5658344965ec2018860f7841daffcf04776f9f1ca6152b4c98b2bc36ba3abc94f2bcf4ab2570d5fe012999123be1d5f90799f1ee075e4aeedfc8abccdfeefb0dd8f106ef426923143ac2fde916ac68480ef35d28ea4f293dc297e19cca4301c8b4aeeeaa8e63f9bb427e8d272ab1880e3c0d010a45b1e4fd3e081516bb13677927236d8bf1dac0fca5eff0706906802adda38ca6330c5a1c310557607d7724d2dd7e1566e56497026b4bd0cbe273824102dd4dc80749c02a495fea8007ae42703374c8d436b606af9c1acd233bdd209f39e3c36b2e57669b2405f6b683825a3b7fe54578da23db7f573c018d650ae2917d925929f2c47d1aee2731038b4fa2b31deb12fef669a232b8fdb1c595c600385c1adb2cd5b484b55267b7e53c0dc63098ed6d0dac39155bb00a2dfaddb57c3c258e05b923812b5f47d038b8909ca3ed80df7ce08ee1e812d9dcac0a4b011105f85cb037f2e556d13cb84dafdd7c0ba1134fa1f9c01686631281970c0cfc98c2f0c21b7d89ef51201c97a0fc9bc2306898bbd51168d82977d1c136370ee50d6b68bd1070218ca46c1c91fff78001e851d923fe9090c34fbdac82a7ac10188fd65311210384bac5ef0896250a4c021a1a13d7b6fab8718fa8f95e8eb2e9e5334a1b572160cda8296f304dace4cb0120ea8d56d4020e609099625c8953cab475048ef868e0a3cb13d20fafe9532f078fe5b4b613b89924f3c63f83ed3bf5cc678270b407e8307514ef3d89058da445d5ffbaaa507e1b60c4e3a69a4f5f01b12a058079e95df1b3ce7ed70389849e5beb0c5d4e56814a5607459851a57f31783c99859d986a718c7d503a103c2678e823e904f9defe09700d6ecec5835906f7c10532474e82966bac9526e4abe781398fd4b8f8e340a8c6935b24386849a164d51cd6fff7383cbd77d8991393588031d98ae211b3436e20351475ab2352ea99e107318d6467ed5a912d4788a3781824095473d905c93c9814b5c88ed23a1a3aedc6c3840521b32ae3f9372409cfd558447bcbd56c6ab912e4b62143c2d93d662d8343b1eca5e2de0ef63366a2ca5bbb9da494b15965ef34627aa35340395b931bb2130ac1905b89eb1a0a81d84e0a747b5eff9ab93838610585be7beb400c53dfbe5139971e9b4198daf5925602cc1f326cf48bd5c1684ed968d90deb892981b859c1965b3600b36468a553d6748e74814c1ece14c0190651c04093e887f299c082ef4e4fdbe56a0cd73c5258c94ee7fb264852f60bcfe1e633d1e212d438f8863181148158aa8b27d89811f4726cd3ee2565e370818a7dbd3c81084c3089dd3c3110e71e1631c55a7bf5ad40b310e3b4ece36cceddffcafe5f2997d0b9f122c9ccabc7022be455d994bcf0120d4fe8182feb8ce702ef8f4b38acd281d94e618ba1fe9f782b0e81f1677d9142c61f8ba9d153f4119b2619751b4adca0455f27dd34d62680737f5480c4c97eeef5c38f37c7b89994382c35cc23fa911ac798beccdfccfd258dc7ae1778d44003330da771b10907ed9b055191169902c43915bad2e6bac38fa78baec7b7e214f8864c883214a419aae09c6fe049eeb954ab3d4bb0e2e0475d74f37c994dc9e4ce30b9b2c55a4c0beff32698641ecb15ee4bd3d4785513f6a8242d4c69d6c56c756071bc38ca4bd5760288f42d1133866125c7e3458ca8ad036f672688741d3e1252074cbdf08c05bf14b1efff540bf549e0ccd1660c28fbb08c5d434ba0cbac0a1c17206a26a8e266f28051ce80fc7e7898972b188832a316380d236a117550db3f749700415de5058ca65bb248786c668e3e514b01cf0c3c5d14d3a238aca4fe98a84798608a836770c6183d99e8ee233f5e00edda2c294ae5ddadf1191cc1f34942e11f9fefcc31240efaa6ad7a4f61f5c3c2d5c35eac418b8c7080da1c4af0233cb10a0b851f12e44f937861914740b46d6a3a98a4b9961ba39c6709ba1fb14e34e149856f52609e07aa867f62213149ab091ca52724ba8a120eed232b8e65f8d90aa517a77a3dc72b3c0bae66d655f2c71c6cb84aeaaaf607117455b1a0bb016810f804608003626e6182015077b317ce5be114170b2909cfba44ef8c626c9c6d993dc19a8bd23b125928ac390044de9cf0eab2ca3922da2539622f3a068fe49cccf5e42fb39db64c228b1f611269ac654ea6f8272489ff53dd2711526c209d6667f7472431dd992bbb4654bf7fdf7bcd6e304b276b9b4aa20cdca0a43024959c20beceba773c9820a6121fe26b7bf8ac67e7530591051f790be5f8e8a9670d89da721973c894c16c521f03a12bafa0688e01577b228da14c7e485d748f38f7b1ffc0b463729fc1911f59666af96977613edec814ee3345fbb1c5db4a4fa7a9df2ffcea36266fa4b8274d489347c85f3ca183227816ed00e5c525e873af678138f0d000febcf10af03ea6461e9ac74bb98e5711740a30cacaee36132934eced014f3d653b1ccdc3c2f0f4c447489dc8b9186b59bd8cc56faebcd42284a125497b3d25beb1b3505d7b9c05dd860ef90a76c771db676f3ad66f81d4495a3247f2811ad47a1f8ad8b30905da319cab956b7abbec564df8746e163a39f8704a36a0786b260d0e2c15695c1ce72f17563be5b8b4c5f7a7235c444d703eb7b3de92c463859f4f1cd78ae7389882d0bbae6381c0963a2c8257bb1ddcd0136adcdf5cae38e10ba72f141cb7be7c2ea4d388048f2c639e520feb16393ecd82f5666c00eabec7303310bf01172de690c366a6e7a4ebd758b775689f86bb5485028a9941535a304ec29a0eba960768b7ab6bd04ab9023b9dc204bf4150b15308b8fb766da3990025bcf339c46dde1c8f2b9b41d61d4375a4c200ed43c94ef93c4e2a6cdd22bab164f223c029945dd3906275374fd4965937215b6e29534a3205ef042805f4042cb3b1d0130b7db29a930caab6bd7a9daafac5e89e76fd27c3c9a1445f8c5aed97d57a88c6643932590d4726abc956b0ed603f104ca8f265b67ebd2895d96ad042c681cdc5a8ac5ec2628c87bd954c8a6359266aa38cd1a34b973fec480943416d178e5825ec0435d6a44b9942f4a49d627a0e10429d356c8722a0637ffa39689af5ff16c9a55ad016f1d1110bd1928c2cf1df30615ce082ba462420017352fa7afd82b04316d89ef6f6a78323fa41232320415bc43529341f4fca28e37cf96f0ffce5169c4ceee10271739ae0dc74b911f2431819c205e2c83032cbc85db7ad24388e939c7495b0662a3b8e48654e6f6db1293d458d5162a1a5a62a4c9ef7867eb0569b62eb245642aca47af5f4143566f5c442ab2816fa56b715d42acc8a86981afaad6c2bdbcac9575253700dd6e0181e6a5b952d3568834fd17d82bcaad437b818ac754f3f075ee8f60d98e4e486d73c0aedcc928f17759b4a62a19a133865c6acb6400018d00f42d85aea25dac028659c738534060aca391413b7077e27a8bc3f7bc319aaf17fea6e366cd86c6c738682d2a57bf428a56cae045c8b6081e04b1374ecfd81ef3e707092bb37320edc1f8fe14ac7996166602dd4c1f95aa81f6881a36127c628a3d4e0e36105bcf73eec3595554c72500395dd0b7bd227085655a759cbe8552c647404dd00990102583fcf6331d10f52412ac8c6f9068f714c972a36c2424a29b986707b985bfdc51354347e7c1677ec1863437974972e635c62ce1e275c4c921a5b146b2c6001b304ac082e2c50ff7accc7fe04a0488d2d8a5e34112390f941fe46f72f1fd9efac84c1cac17ad6831f61df8f042abbb73fb00785ca20c09fb05f10a0acbac73ee063d6fd3531327b1e006aa0be038cb0ae0c21c3d6f702f46d1cf7ae50b0fa59fe0ddb059234a48ccccccccccc2ca3f31be81ce7ec6a00ac134d3c01b70b2c4d0019053f3c695458f09b33a22368b405be36463d3043d785c38504fd5a19d8159cd00d6c4c052f68104a247821a17d83151da3224b141433a8f6e089aecb6504ddb7c15a70b0d0392711745d2e1bddaffdc0892245d7e51a82ee63202a68841c36bed0fda64d9b7a41220ad6ca3ea6555e3e32628f6529a01f1bf1111b2d0c52b15715049514cb032e745d2e26ca347884065e6890ec09259a7d41bfb5cd499b591e78a1eb7275a1fb523fd26c4195041757dcd8c0be49b4b1b2ae96122a5b19581e44a1f26d30944d188db9a02884b3a9c8719ce4a4c7588ec042eea34a67752bba94fc1c47d96c89790f7e1321a1dfec687facd06f6d397c8b565667c90f5b207e8f6174c9304ad8052aa43e5c53c8312a1c9cf3b5e3d28c142b98bafbcc864c0a28e3e89b4977fb897a68b6397ac8c6f6f0efd74285947e0b889a17748b38ca183dbae4d616c5f7fd993f398f8bf9b047a58b4949a58cf2bdaea35bc44f5c5c287c0650fa7afd7b3964506071e9527292f3d85541e72afcc8d2a3092acbb81e7cafdddd63f104ce73d2a29b2f5b28fb7a7900747eb5a10c21ad376884eeeefe157a7777bf972e5dba74bb5b76ec6ee619377737f30658689eafe666ee4908b4051db3dec142d0db333eec757bcd43c70ef6ba0b8ffd915104fdbcda3a884461a13d27a5afd556d6fecee491f954d6b3964829638cd13061f5f149587d8c2dee116b17430004623debc55eb3623cecf5372b0944e8e779449146fcad2ea39865dd3ef89bdfc5ccbbdf7a166ced43f8dc1046e968f1a4ecc2d162c10a8d5e013960b82f567c7105911aaf90c28aa51a778770ba308104cd69ef7c50bdcf64a9fdaf336d6aff4ad5ee2188c4e5073335a31b7c83b983dd0c0f83a89c24dcab40535d56dd6140c3e1afa76f56dfa91baac4e0e5a8cc0e6d24911c2f553e28a145298a891c0225a40a2420843946d0a08a7e3311563254c9b10066a8a8336afc199fbaa9b10a227272a041b5ea5c8844fd8cc1715c99a9a39ca5269d32688ce07c7c5aa6aa88ab2a278621ad9dd7138e1116169bcb8622aba3560e43ba1acb0a9189e568d58484f3c1a8eba2447631127c689a4242c20aa2a6aa1842c295a729354448c8b2341503dace6b89d63d3bcd0c39c25465a6091112988cf8b586467768782dcdb8d951c62833f081d2ba5f9838c3c522135535464e7ac1e1a8c6bd559d354274a8501c263a2aa03875bf8091a203d5a9fb05cc151580e1f284baea7e01b344064cd056dd2f60c8fc97db9268040b5656ce562701bee127612bc782ded06f5f04b0f2f7c2231b51a4f550176b312fe6b1177dac60b47be27c45ff78a6898b1512e9871abf8df010676bda22788649aaabdc7a4a543bb1f5122aa2355c889048b6fd719da9727bb251517db36a9b05d97ac8b5c4e5e4c93525ca55e5c624b5e58c8dca45fb66d5360b9a512af77c726ccdb3ea03b0b2c329f44537284245b0451c0d1a757f831561020bd42fb7889ddda1430eaac1637f68a071beb68869cec44210d47f7776bc6374e65a8ce503f58fd1a1140b50cab7f4883ad43fcef6879be36251ca8f3bdf7b519d1bfd6b8399cbb833fbb3f825c738209fbbd1ef39ee1c77e72674778ffe12eed7c3658c5344aaf06d4c1ff5129e62ae6aa336c24d3c9573d8a1d5c73dd47d2fb59f9b7a68157330b687d947962871543f1e8f6f7cc6dd18c009fa4527b53f3a61a18f972a13b7455c632d0231a3d1b6ea296a0c0958a87d00995ef70c800dfd96aa851e378fd15f3c42bf1eb38f0a5b5d2505c2163190d9cd2748fe745057c60e79ddd354d46fd7d4fe4fa8ea981e17933232344a673dfe1c0f883958ab1c0fc8b1822b10b688a5229b0eeae8d46d03050152183a8c2b43c870e132e33057172ca9f2d76b04cac4fd87cb84d9b50c64236676f723a054100b357c8aba4d3d45dda0c210d56f46349bcd66b3d90a3235f483361b740a62a16e4939992fbcd577942c08b9830b34b9ae38ef3858ac2bae5bfdaa9b93151b817b7ac5838dc5f2c2cbe1d1dda3cf085c4822ab55952dc6f7a6e733e347e7b808a3374bc971124ea4b6b1522b45dda65ae9eba6aed24c68ea37abb7af6b5d536ab5adc38861a18d1e63f46efd593afbc3efc1ef563bbfce0231b350618c2d0f7e531d0f38e4a84b2334f8781ea3d39fb5d6e3a73fb39143070bcd08f3f5b8557dbaf77085976a18b38ad23400466867b10253bb71cf2385a3252bb051a10a1a19e1dcfb018525faed8d689fe091020a4423904c5483b9e56702e91c510da21a4435b626c56ae95246199db9e17250c67c1569384a19b955f7d0f31c5fd00821e4f6f6d8cc62c9282778dc9d8ac7aecabfebf1afc7421c3c4f5d16d2934ae973e4ab8810461c8f45256a7f74444b32b2e496438326fa412323205ff3f13c46ff800faed52d68499732cae8b345b570d116a60b0704d3c5d3bdfbce1582cadf10f6a8ecabeff759b59c89e81ee7b3628ccc1e29fd246d6483cff019a662a18fab180db3e1a60db0d763847e2cc5523ce56dc49061b132847cc41f0a6ae458571637dce82e6b9b1d1e73ee60ef032a4c3a2da874c778631d98d1243417023ed70863f4e89099ab4b45c668f73057d7c5c31eef53c961a505aac760b1e48747441532a96728b3c1b19dd131909225334320c8524ae66676ba72d9730daac77ac4246696c1ef497b366df5d3c89a25f8a8fdeefce6618d6f06df659c5cdcee7e81830d036bb2d0c7fdc63e66c8c19c9d9d9d5d46f7f61c58dcbbbb3d2264d93d1d638c13896500281af7e5c3e52407e4fbdf683fc7391786c1d240080a7737f62f8017d8065c719268d21554e8b29061b5785af85f4a052929a3a6b29385b6ea4205198244901fb6b9bb0cfbbcba905bf6bac7637428fccfed71b09ff399bd4c99c25f5890b7c53bcce3b32177b9b59cc2d486bc69411627cc3cb9c1452a3fdda232bf6c282e191919f130d43c3e4135eab74e61766ad12c9b75032580fac12ab57fe196a0fa41272818664c6d3885864d6de8068853fdd88898faf11227eac74ea6d4a81f5761e22db59d188ac37041ab41b57f522e9c6affab8b26b5ffbb4853fbbd599593da4f54d5a6f6db88c197da9f4387174d6a3f0f15bc58aafd1b88a1f6b740822f90187d41e6c88d0e34375a24d5c040525a0203872630d8d89c9ea2c2a8ba4925b15fde88a9fdb0aa072323314757683fda24c190446d8a520c6e969a9a6a3fdb160a8813940c4e6ead96ad2e172852f5eb6ed95a43540ef453cbe9066c39d575e160d84df97c716154a64b1b281bb40122892edcc8f795ce4205a85129070c7d99b3b13d1ba99723319bf18c6594326600069b2d4f663cd36172e3a1c80d882046d567f68ac2c25ad9a7b3348d7632640155d18f917a88f541ed67da166df7bbabf76fc1e0514323031441f93f3ee2261eb25dece31d621f43a9a1369297aef6a4abd8475f1f7cf200baf981872ca9d9e10c14a91a6e8cd4dcb43fcd46b0cab585c2ff6095ce9215ff62529551f7a3d1166d4739ff84ee67cc851e76f4cf7781bf8b27b8d03f63375cf0bac7bf7b1766dde33f1f7eb3e7f5108d1db1a5b1637eff8ccdee81557f1faffe3c56e0211e5a109b25d5dfc9fd39195fe6fc4e158486afc7684480bf633e7af0f7d1cfaf1dabe7e7980ffe558cee6b670ffdbc017d88b59302f7c4f77a8815dba9eb10ba4b97ee4b2c34b75b029368af14d88bb78fde7804a5a132e965ad87f89b047372d58475c044bf176b86d4972dc6dc966a844d3542a7c9097daf14e2abc0429e26d6f8df43fdf1a58d0323030b1832aa509ac512c59962e7294a46923543c8385ab3b446c9c682b1e76566b8ddddceb0ee6eeeeee62582993dc6e8edeece0cabdbdd8aae12be7280df67c702c891dbdd63c710ea0160b0d3396297583175bfceb950090abf5b9dbac1eca10780fd37d7e97c0fed8d7dda2869637ff8d76603c7cae4dc6547f7e8eeee4210c20819026d4308bb074777778f9ebb7b373919bf17ea42a0fd5983500a84522094e2d1a394125d4a81508afc95fe90ebc8c98e5c6c22471e3d4a29d1a5148feed16cb4e852ac40111672d7918b524a29b919a10890adbc66d0624038c434d8c3af040af57f8ce53583c6801fd3daf6b2616bd1edbacf40f1595d0745e80a93d885c3634c8b81722eff8ea5ffe45e1028ce8898c6b48e9569fbc3efd2c66bc662af014c81b00585248543afeee18fabfb7145d881406c6bd16c345a123b415a20fe2a532acfb03fbc43a3ad3a9801164474e65ece1138e8300dfe8ce88aa90c98c6ab8747472ca93913322d55b7c3533b59ed7c6a57bfa0dafd22d5ce4bedbaa7b7dafd2b4d0eb5fb4fa3a676efa9f9a1763fa31a52bb9f2e1c1dd19c5c111c27ab9cab7e3e952ba2721c1640540e0b302a876688ca6501e48a2eb8dde8015054a42affd6a0a89c994b628830dc99b441051e4550a2b93fec85aac00347c8adc6e589886633f87ac1dda53250e8d1dd3d762c7963bbb7d0f2b8bb7764d9eaeeee5e085bddddddf37ba1e244a192713ad775773bd5f081ddc1acdb7b3e146015e8cabd8ed705aa731042d83b7c822c6445d97fe7d1238f1dec31cfabe5ea1d4a77e868b1375b6e20b7c7990e0b4634e5be3e7b458d4d6a1360bdf82c69c2026af733961fd47842edd81280025c0ca24072ad6ed6d60a419f997744bbd58a1565ff1debe716753c5de4b589785e2d57ef50eac209e21e9ecd3a46570938adb945ddec98556539c9ecdc3326632e1cdcccccdeb284e5584e2073dc2e17f61f59724aaeb9c9b383dd5cf9b3d0ce9db3cbc3f9afd9eb5f0f458507a818398421d3218a0e69aaff0c287260dac085c35b709312c59418aaff6bca98eaff72e1f07777e979abbabbbb03004a69125f468c6ab4d09da2014409e2449431fe19bc7b0d5b6c41630c004a923050caa011801351103de9010a1c8454c741071cdcd49ea069a6101354ddc9069a0d553734e184290547aaff8c484a75a814b8c959410d567880c324c6938caa23511d2a0989ea3548a9fe2e170e8f31c6b864886cd174e3c2cc953137620d3562b154638c31c62825c2c7535d56dda7facfa045f533504ba06002447528266daa43351153a168e0a1e604c1c48e92284cb099a14bf55fadd1d910907e80528254fde98b4c08f5dba1814132aa9e6385c683575d05323740d5e713266114f9a2054b52d59b956f51fd766afc36112a09971ae3bf604318a5355982148962ca0da7812a890ef41bd0a19028ad0b9a60497164861f5bf57f7df9160c1c809974e6701c57436a9dc1b9c2dae9f3ca8d7bd6015728114d565a945a459e50d231d95845ac489a586aab1f50b82c525d141a240b96e60f4d225315a74412df79311d750f9923ed002c51110b24bcf3caa2d43d3ba18cc4e0880f35a823418e38c08728fafa9d2c2ff85ab3441052a0c9e00a4a4388113446dd2f64a2d4efb520c33403192f65a8a84235a8fb854cd5ceeb83ba5fa64062a4fb19a76b0ced7ebe8cd0cf8b2fdba3356a7cefdce5ac154972d9bd0d8e1911ab7b2cd41e7b3e6c226b29420d41431352bf8de2a4a0882831bb60d0a8caffaeeb3ad7b3bc05e30b600c853c5e6cfd36ab8b7d3d560fbf83c918fc0ed6170bb986a8eb7b55d7efba5cadd83759b1af475cb92000eb629ffb204016b40755e7d4d4dd833dff30dce31d05bdca1f0707fab5a89a7aa893ba878985e0df6e51514f4f365b53d30cf796aaee1d55ddbda95c89c7dfe8b97b17a91a942caa6c579ee062a4090c4abcb822c90c9124649808d105cd90b894113414a698fa8206c5140bdcc825475574fc080a8bb64112499e4c11c2840aa6663842a245d055a8dd8af871a44d112d5249182f3c49424452153b60614510242ea6e73c45e8f79aecb6b601221172c311f2551323429e9670d412c30b162243985b91a5a8224c34215626ed322d90c2889a268c9c18934488137777774e729cc338c903039d81850cc960d5a45fb84149073260806881a484a4fabffcd185bb03e068d64393bbaf9851c39921b298b2c3174ef248999d85e213cc50fd3873268b911c8c6c1341c050115c86cacc4cae5853a58d151954ac6862470d9b17c4d0924514394eaca96d704333840c28aa2c1c9c49b385979cb9bbbb5c5ca9fb414423e8d8ddf78dcd9ea2709f27e5270ed7b93f32f3ee72961947ec10216bc611d421ec8405bc79f3e6cd8df92c87edee98b11add1d3ae52186bb3b4308934120d83caea4394a01a0a83f74ee5dfe748f2fe194d1a57cc6da999a626f91a8a08a51351082b6bbfbb7ddcd42372d004cd0ee9e5272dc199dc6199595f3b17fdc814010b6fe31b6fb43bd6342f159cc321669651b0299a6a894adba8cd4b1d100080053160000200c0685c30181409aa88134b60f1400115a80427c5a3619c763418cc3300aa218800108310611638c210421a610111e75f981451cc4099e59853b1abc58b45cf63d339aa5ea852ad448e43b8d6ed186b1fcad85e08d4dc5bbce427949c70002f11a255ae68914ba7c3e195f9bf7713de11ff974e5b4aa45c4b0d742cde91c86af6e818ea30e1e0105a389695b35c2f47d4c320cbb6e11d47249fe4da06793aaa541913fe04275cf05aac4990925861d1ba5817496f05eec82382fbea1692cc07684f445f4769204b913224b130ebbe6fd88b3a36554e05abce84a227498981d6f7bce573538d3b2b4b7fc39daf2f31e36465fd36bb4b077891c9d3696f994f7feb8a30f360faeba432c88ea02d4d5acf13be068a4f5a3ffa7ea1ceddb8e8ddbdba96dd4ef38ccbd61e0db4b744e47301536eacf31809087c7c7ac3482a2864177cf5cbad1c60e5a240cd468c8eae9ea7bab3b2fe0fc582632256b77ca82640d5ad555256a263e563f429837b983818dc07625ded0d0941b05f30cec1d458387dfff9dd1706b3db848c808d5d6facbd9cbfe57c4ed0ba9e4830d9456c57006b3ba51557e21eee864424c556588aea1408f35cee3f454b64fa02933cf4ac925e659660e0d4c81075afb1649d7aa2fe1a0e1c567b1c9e59433d9712cf57180c07acd480716770579a2a98d08c8427356e833b4e13b3d0bfb9e0878d40ce9a3363cc574771c48f2b577150ea0eb163dcb7aa6f83fe9da45ae50a97344fc637bb2c64f44a88228c09f16d2e5a7cb666e5d0ee92b3972dc816a9ed0d64eb030d79e0d4c7bd7e858233240a6a8611f71b2616c019101e257ed917a9b2a90e7c519138a75dda7204026002489cd8755b41a1e7c4e8d12c32f236a8668607d15c24165bc138ab1b941768a95c278eb8fdb0d2db215060229717a70a510a8d8b0d5f4822547d6f0952755fd2c276c1b8d5e1040e0f22c0c98be1ce58a3568145d4edbe110902736584fa6c2788dc5a7c25d50caf419dcd1630f4c52e5f949006f5a024cf17e10dca9f6e6f11f46f83aa138a5316b97926e29d3c5531e18f24a47d84d80de4972a1263675da5cd44269cd7936a1acc6bf8be0d6fcd52bda276df08cec518190fd0e2f7eb50f52bd2341dd79a49745d363bb48709a2dcbdc3d9c0317dbea3b988a57805965587fa39e69a2a54638aaec8dc6dc5d81ed50506a339591a05469f6a406f11fc2e226442cf40a9a34a7d0d992f84688bc22a48c49f173729315410efdda53fc1c7fad457bb68ced758f476cf9c8f0fcf45aa19f072855185d082536569194e649a977724cdbe043914e4b8b45170737758dd37276ffd5dc8831cb335bf18adb887a9f61c22e1734849175eaeca4af8f5c8fc88af74038f33c73ac0d4042ef1086bbc71472c5c31f4476dd1b2a187529ed1d1cba7d8dcea83d3bf677bbe38cccc51c4b27ae6083e5725e9518662ef028dfbf4c37e1037c2b3ba93f64804e9168648df62eff1380b6351943cec710d0fdaab2af7bffc90acf089f35ffc8b85dd105199fc41cd858bf70d42a59ccde8f8f0b63bb8619aba054aacb9b4e4518caf7c9770b153328253a678ca865967a7c476b33a709efa1b164fa7efcf311f2db0f1f204c2c9440314b59ed90d9631aa0652b1c4ab64c39e1e0fa4e38d7f76a38276050d03a7cf4fa5826f5a923c3ab467b802958e7fc4d5e38e95b05558f69d827c39a478e6b03a077d1b2eb9979f3dd9fd30b2444530285bb4ad38ab82171d7dcc93bef6cfa8580eabd88ee415d9f58f4627b65ee0021c3b248079c03fc7286362690c06c15416a2ac09b76ee1c698640a61de511e008b507c46a6714d49d10332053bedda1bcc3fa62f164cef3bc216fdc8efac20de86015c76635e99138cfa8f589db0801c03e9c57b23fc89a285534b1a2469299c444403f91d1c5cb9579541e3efb095e17e66a60eae48234026748504c8db4aae81d67f2551eaf13fd74e4d74d0c7c3ec5dce658ad8407451a0059f6cf74ef51c14ca9d877eb2456c90e9a9759d43ac304a94e99f5efe2535d10a0fee3fc80230575834b6c0a98070198fd8bd01a05caf52d202d460c2f5e25f5dbbf81db81b41b48989761686d61630b07403e834717730ac41e172c737d89611a246cdf8dd4c33f87ce8266e2864cc10c5b4de0a2863e3b76e85ff222dfb040f3c8ba3b1986905da0c23eabf28c81ee0065f65244e49bfcd26959f1aa4e569d01b5e1ae0d9c9c2b0edffa4f495784efceb80d385e225b8f4f507a4655c7b0141445eda3c30ec6edbd1cc74532083534509899f52fe055651c730affbd0d85f9c5784ed05374bea2d282bd9ea85e1b42b76453cfb614b05ee9e86ae0b2f2b1efe15bfb4c18aa592236551199db4be3dee0af527949e2eb0131ae11bca465bcb41aa3f41f78b5aeda853599f5ab2c3291ad62fff4deaa1f3af478acb08c782d9c5770e2ea736c38094f91a2affd6936035f610afc8bfdb19b40163740ec8d5702111f5072393c1422d3f64f15e94bbc3dd0a884126e387d840848658b88d888d638bfc7442a65c97499dc7dec2dce11cce1e59be47b1f820c646d63aab4b12069d535b4da24d19eaa37722b8de0abc682798722890ebf4b8d51a9644d96bc584c5e641ef0490e1c1b84d378fdd3467356e41703a7c86c24959318906f6054f3910cb314f849c4ae883832e27886e0c3f7c137ce17c7dced7abbc4a674ce30f3d85e13bd62d8dd454cedaeb913cbe52627179f15afe721df9bad493525d534eff6f77ad0abd94a6b9742e63cdbd9ef316fcd36a9e94b74ca0f67f64467e3802f7cfdc4faf38406603b52529d4da944bb06f073ce9d3c1e9f9067836930af7aec69a266e48f3d3686d08a723efce7ddb80201a3125018fe9ceb279c1361d934a1de105e4b0742accf77725c8ef9c4b8672679e65919db6132394173a90885f875d60a8660c3d8b828569c74ba5609d13de1535b61d07d63d857dd7c2438bab92ffa50ecc7d12cddd791c9726e3b30ce2d191a7ea1c31d0648acac0d2d4d857b6a59aa6422147e35f1b2cf84bd2448bc00cb04455df09b550e25cb8475bd98cfafc854e16b148f10a4a44e1a55269995d4ffb12830be03a5536249404e3518a3542185986e03652eea3782619286e289131fd2436883251a14983c4062327e3ca09e60f27d1b3c84f11e61095081bd004a4168d841afc68b6444ba650f12ceb9d84a33af744475d6b907c5e915bce9b8f5abc0ca5c525e42155ce819363340a6accc5bee1b5d11d3a25d3362d7466b1b9944987460ebb8f0143a64feedda734da26c489ea5e7ec780af0fd58bf47bf012127482ca3b7d1c75545d6a4e9780449cb20d9e66b83e6c14b5853d013c2037c34e0e6125777e3a88a23eb26d3d3a8bb0db7d8ec59d43244af996622793c64e62ab7cd90d6ac807c88318f45de408cd494d899fecc69f660f460cdb44a62a7e44d7968e0593f9330802875c707f64d8e3497484d47ebee8e91a4cc776b186f9e27c8dcb47e33040279e5af69de092c7778f74e3ecba87efc7e3fcafe4c0c94eb844f80408e712fd674128167b0b5812586c63f9e617115eb031a3b4b6700e1bcf51324f13319a6465fb05b80c43cadd31130c5c8f3f38bc21e290bd54b3eca42ca8b6be342ca2a621a84802251682603745bb441bd04068ac426dfc2cf4ef27b2712f1fc457acaacfb9d25a9bc307e00479d6522443d9a0ccdfe77de3d592f219f5e0ab250b1f2d2e4dc25cb6b3eaa80d784666a3ffdf25839ac4037b7e85852087052deacca052d172e7cc908b63ea598ce53b59623927fa301738c00344c5091287753d2eb64ae62ff8ff550b07e4077367b38e29174c8ce525aa3af7937a01dd80dc033c932fd08cfe742ce8151598c0c1af34a73acc849bfc52fdb6b4104e025a0eb65785037134e6c51e5a51e2ce1ac1a2466cde452c265b9d1f4b0db1820dbb2a34b9d6cb2f12b6d7d7fa998fad2ef4ac68965e8c83fc360f1029061ba7b6506983721c8369cbb8035f2f1c86cda0cb14ddec29a01483753ae08b794256681feeb0a135435f863119a10397cf05834e13d18b3f1c9ce8d94db88dad8c762c9a494dcb7c9fa5874ecefe543c9202115019450c1ebc4e76db369b05b5028b7e698b693e0ef566bad97c11bb6ba14dd80f8918a9327377419c488aa19dfe2a5c89674897b8b3258e3969d14b6bad1dd7620cd42ce80a6188bb45c8dd60cac486f2e5737ce8e38af5cda6c1dbec26a71507cb771e4188334b4d68f5d5ee7b9e67e06c5febb4bb0102ca4fb3e0ded265effaa11ca98a04e1475ffac3ced828dede66d4235d87d6919ffe3b14ef843fe19f30e76d51de9e9cedd62bf0afd67e7177f4c98afac30818f1a2c774ec4a9ff53005300a349a3a91d63e42ec536526f8e05f2a97c6b1380c28facdf340c56d192c84973226df012e8606225a8bc202841ea9748403d4c3b462b1c6d97019542f56c330846f0e1e487e01c4c1f640c714701960ab9ee01330bf9a2009603b9ee00330079a201cb86dcee00330179a200cb875c1ffc4c1d494a4a01ebaaab848263b5201d4f5d047d834e516de3008c4d60d0dc47f77d10601340caa50c03c7b202ee7571d49a8a2cb8bd8c02ab44f263e6b0ea5105c22be2dd517b377b407928aac396a784a1ec1765ec3dbdd8fa29d2da63ce798ec5fd2318c72c2c75d320a21854ed9efa53b930ebf64ad43e3b8f115ed583c107ff9cbc040b4ab192011cf3c0b1dc8ea6a3c32e1480c0848dd796e03007ef87045a80cac00cf8d633de764a854c411067bab5672d20c17fbc25a696435ddd03c404ce85af4ccd671115245942e57c48c7f9f5029ce8d614e19ee30ef6c757d34134ceb2952d64e4375c85eb71ebc9931c262aed672e59256b351e9536425091a636bbeb752f628d1be5b2958bbb08e78041684094721104b65b78592a96062931be31fdedabfe07c042d13aed36769d3c1a0626eb0e573b686a8134f42e503b1d82bf53f0876218020204d070af3c0e3640b080a7382d857c0247bef6fc3801cacb8ae8caf6cd1ca071cc1b25f6c27116601ec6446a5298fe59693b2078d6087e9667a40aa3a25d83464ae43edb28a93470a220e23452e4d934cbdb7a8c6df92e8accad5608377ca67212d2d7ebdacd3a6fb1023d5064dbf1094f062aaeb75e881125a76460480f726314466f118ac45a0d6da91fa8ca971c31a6624ee5e207154cdfc590ad6ee1eaae212dd1cea777d037c3087445b1832f1a121c0d04f0c1f496aa45aafdd6770b87cab1c9086836df0ab03a16e98d7b375e21a4bf7f41d187e6aaaabb96c16d32bace6bbaca20a2d935b1fb30e78a502be0c1ce11962eaf4a25ecb4c191c1c2c7c8e7a1c2e9a5d0b533b498ccab83d8355c4cdfd5379d7159638bfd57ffea1c8e2fe900815ffc20c8a134bae1b1a3693c5bd03f65884df1d89fda934c62b054d4f68a0c145b2ea890662da436171353d8efa49d0797dd8106c354cc991537bbee0319429d95f3f134719336b4ca47e3d44d8373a50a37f300c6ddf2ef527338f014856dcbc830da4db524d05f3c0ef25ec0b7a964d204eb4f604adc8936e1b0bf8d4658c230ff9b2acd642cd0dc79b68f28045ce8fca2f36d2465d387ca34ff590bb52877fc39348c68a24327990333d00de74b3b4834a69dad1e74d7dd2024f9df8084bfb914d3808efdb4bafb2900021a24388b5c45335c459083f419b9797945430dd6129aaf6add04d5c65327dd24f995e2d22a4864178fd4ed136102aebcda6201a59140caad4812c5578555fe34ba5fdd1a59ea3605b907818bedcb94c69c3ba3bec41d54b29e58c155d5073ffccad80be7c09f2d755090c9c93ebb35cbe5017ac2944a5fd3171b62049a65c2a4dd0d91dc8e6fbefe6447b8f78642c7b9955bc2887a847ea23002e1a80767d60c8bcf45a4d004e6287b840aeb68b78cf51d605dc457891bf771f06d6d7f3d584dac98eb5ddb96c7f5f4d1256282a06d39656babe588295d8b122d578c967e0402c01efed26edc358b26944fac9590f06884ea4e9c3c3a4d770167b6999997f2fcc43d6befcc8aa291a24149dfea17bd7a3c491f68e38364d8a6c9d0e8b7f63adb628dae65198169af833885efdac645dc8ef66466e207d829811e0416ca8efa86bb28539354dfe003f3e93bee09f41c4c8976167cd4b854467daf6fad627ea7b5583121465f75ec7550100b8d8039a52802029791997da738c4b1812ae82020b39cde02b4de26dd501669b5332c80d0e9279721635eb8f50a462e5b2b9f110eb817dec4caae4f766eaac3a08ebd69d09fd46515735f7e417ddcd9ba73982da2064f415aa5071235185edeb068195153613f1cb5c4c7a7b261743de29c9c965c342d2068c637122808079a1d7c70e02f7ba49e61d12289c8d1a5b86254c4b527ff3862cdc980f5d907c520400872b1025e75a68a09ae19235037542d228b68175095932394a860cf01cb234cda77573284e3027957a7d349281601a5b5d5534997f1e074a93b6c110726c5febac236adbf276a37f63e8a52d9f4783928c3dc67f2c0ca9ce4c31c14d45052ca385d89f3fb11d004e965ea7a4ac701d93b08ed24c967a304a0be021e49aa18d905790c8dc9bcfb9556380e326bc18f4fc1982d10872f882da106c97a71d993b9f5413031fc4e9f02b78d53461591845c92ce421e44653c0b27613b236f4c0a0a8455f83ab3a75f16a04860bb2255618c91c46725d6dcd0b4b60a6599c0a6fd5382f407b77f0037bc453286451d5bf8948218886368534c79b702c1df12ed6e6862d1516c2e6f946da95377e48d8ba544859137b0ffd7065379c02d75f306054ae98ef0b92a750b69ebf93583b2338f932ac7e3cef4518d64d3509500a8c9ee28dcff756bc28a47280984548b5a1400bdd60f1a1d66b0e3572f4bacfd56fd96db9d6489361d121f1e855a757bae50ced7ae99c1257bc02c7911058d46f6ed96db717229d88e3bfef92133f9f9888cff350b75bad2ff5a4bab88e478c3bfa602122667fbd7742bf5197ff5037b5f5b1c9bd9ebd5cbbec6807c289f87c994cd82ffe4dbfadd964095eceb16bb41780f40bffb7b6dd0ccbdb6fcf6b58718b4d7f474ae47ff7085cdb4c2254abbb6364148d741dd63692e3ec146dfcde511f429ed8dbfa93a784188a1c02783dfb2484614c694ca7b0b25c1995301f150f5fb84f9c3c09e3c3a9ed63ed9a6e2769702f9d0e8da2e524dae876ee7e2cb039b3951ae09fce6875af9456ba3c8ea216fe0cd3b822d7b653548962b62e06cd1cdee2ae62531cd3b60843389eeb1589493e3c550b16bca43931d74bc824234ad2d07ade83966d1aef427f2f4a9faaff326d146e9b1fc9c7145e8bdfcc6b81e9e6b94a247ae824e3cf8bebc58039f3f1af242ef8fcccb3dbe75212028c4d30b03764da7408e2047b499de9b1f625acefc89649387210dd8aa96813e19513d43ef3f2f4ea8972d40d8139cbd34c716c607a356f08ffee08d2d907f78d26ea5916c69d04558b58cc6663464e5b4a8cbeae22b05e8c81c486d43f896eb1762e11e0eb0799bd62687f11e98fa68d616c11f0ad69f3bd8d7f10bfefbc153f64c6a6f9548e11472e650649b6aa8ca437cb9b76f27d7e0f6df561db11661899c287b6429dd35393915d92bd7059a730dcca0e16948f6b6cc06f4fcea32653e88b7f7ba14732ebde082a8e02c8b0496cc7a7c9f1d4dc12c9b0a6c793e1a124eba4990ea63f2e6c121891ada1c7c455fa1ec2f02622761b8747d412619851af567c91a43333616e01165bc9b0e9751ea4f36fe264cddf296328491f8ea382c09523402b5e318d2af8aed68206627a580dc6e5d04f54df6cf17a75223612960cb0efb39c80b72e5557014b9e6a37a02ce8c05e6d79d97faa540c83e1c7c1d52296cc263b5ee75f4a76724da7926c6560ebcde61216407e5af14787523254581d358957448f9406a555fac9d1f4b99ade2eb7931982eb0ab852a13063b7efcb76cfbdea452ded11bd3617950736fef05e684c6e7ddb0a395c0db80c5a8e2b568c49d3af847bbc88fb2a2a38996e55662b487679ef49ff54effc6a1012173f3d0444bba24317c7f7bab2e6a097c3fef689bea75bc268e62328ff2824f4ae3bbd15f5cf3ae7e34f651494dd6bbaae6b0337b93046161b7c2f4a6085793c9e7536d40575b5cdc7e1f7a65acf408c46f9e89f26f35540616d01b10f5d90427a2e8631a90f5f3a7dc7a354fdb7b0a85a74adbc820ea9e33e208de2495260b46f82cbc82aa8de9d0c600a5618e9e51cee8ada6f20f8939f00ff27627fbbb17cdf5b15f16bdf976125a64be5beafa46542a091598c9171fa9a6b0ad37839c51efb1d49c929f81498c2a9706fff988c15c134c918031d48763a399dcbdc8433e1c029ac3bc45495a6dab10211fe59bcd3411a50a46d0de5d1f435a99f2ced0b7091ba29a9fbe45a0c2c4ad6e3d70ba88fd841c6fe904eae6c81938817c139970d1a2d9c3d2e9d42eea1695e5c207b1adf58167f6aa5987d01d81c0239ad6ecfea5993ae24efd35830a598c44ee5f662e47688cc1d21ac241b75d1521786d3a1c376ebb7a04f2c5253017a93815a808cf0424bc837c4a975b30d12d51a611045e1d61d26f2afb4625f42786f5bcbfd4fc58d24db78fa869452c42c909a5ade3958b44406e057cf90ff49bde70be3808f5dcf0db25907ac7d5dbd001740736cd7eec35075cef64f439493c77141e08422df8abaa94726316f058cd4979cde96ae3d980e2e697ae2ab27ffd8bcc3850643cad181e35ee5691b1e50e751e0802fc60c122e50cb46ae1869683e1f3e60a885c4a54ececd9083e21901a938f5042692addfd3799d1834601b72a5729b7f620fcd86680c7bbad7c7115a2099f71a47a8db0f2b9482fdfdc0d3d6a44f64773e033e3f6369f8deae10b41a8715b4a6f9453a6d3db64021d1e617f9e173e1c6e95b6f5fd54bcfd1fcbcc02364e91e242f8fcd335d803d20a1d3db535133a83b2302bd8b44dfcb7ef3354204c2bc5dbccd05cba0189251ae8e84762e61e0d3956b45e51d39085ae63917f9e5fe8836f81f512741314acfa766cf21d51beba4fa1630501479c65debce709abf50c81eeee2de4e00605a071769805b8e2581be09cf840703386efe89c8cbb7bcfe3699304002395cad2e9de66df84a02b26980d82666c0dd5457a8cccc4c28ab88ff0ec9ad6b3c963ed1d6135c2774db0cd861775222c1e5b44a40c64151bcdfd971df05b7e2441555a0b9a09119cb3061bf34eb724b58b4d522ca5422ff0b55520011474362f542ba65d4e365641400b47dec7e6ac363d966c6a7de1f7204d271e0535624d3f16d9b2ba8dba218a4232d295add17b45c2723d09cef6e3225019e8bee4bbd642d04cdacc81a60ac47e0d95db8f6a66618c8e4a06ce4c84d57c137de5884fa322e0e2ab6471bf39ec2b22d8d2a81959d9000597fb16c212ae2603d7412cfd039fa7ccfc7d9207c8f5039b234842792736618e66a0b09115c0926fa09ccf063bd05e896cd55eb8f9b2ba5bd961549300c24dd6285e29aa8d2164a73bbc6c041938957bf72560dfd77150eda4934cd9130b386eb44af3b3882a8ec4a8ae013dac03e9184e3c6c851c4722d3a4833518487233c6eaa01913439f603d5f626568cb5606aa079fbfaa3f8588b7890a772ccd012382db3a221060d81850fc4bbba807a47158f4951dd4590e8b3c4a4d8fe77d84f60ed822eae635ccc83a3dc0936d23dc68ee4aa0902dbdbf80d3cb08c549b208c29f9239d4e5807b989527c1f51b135ae941a5e144d6b4392e166cbd5bac7c4227e0254a7af79afc433089d57cfc1bef8f56b403dcc28d6b0c0d56a044ee6aed730faecee0c115524e1e2cf322980b72cdf5155c56627f9dd3d1e3052125f24e6ca2238b4cb668ae82d2909c1d043c72bfbe1dc1844a7fadb9fa2fcea3aa9b47784d460e1f411ee95dfa73f617c243e45e3d8e0d1719b13220394c806aedcd384c9d3f80f1218cf1bd52435e6be0b90e3d83510b736a38edb42ef89847df99bcec8e9849fd67251b6e66680ff0b4bce3aabfa529a7055e111aad5ed7f4aa1dc1b71415e77422f4468310f2864af8bd2a8b35545165d0c44304d9ea5ed0724015df0e00525546180598e2c30020bb79199a933da29e5737303187d47528ad76e9b577ed13f0611c159e30d2bed0fd8dc9f91a0f00853856da62330ddc45c01969f6df14b1762df0ec2980a0c2ab118de0f9673f9d28031d6f4a6d2ba16344a613820e93d132c1ecaed26f3c6229f518326d34051349789ee8d028ef66806037044ecd28c2aaa0b142cc1dd48a0a2cb9ff22f881dda73b10c89e7c9a2b6fe567412549529e6af19e641b6e3556d5d964d7d6aaf6bc843a179b34b2424619e16372d31a0b2e0f486c1a23431397ac20c02f11ef5ed468ef12f16e4ba92b99bf28e029953e19c7864cc90835d0b802a5e1261d0fe15c7a3a683f50bec72cd9ee4c3a5970acdb09194f4e3a912116167f1404d833944247b44ed863d3d6c7988b4158c68fb68db87774de1bf6d4cd0335ed5a64d005ea40c8c829afa8214251806b023b4863466c980c7d4e664f802c0a53badeea3777278054933b51a2d070bdd93f4d1ca9801cfddbf402efde3de6de175c6f06fe41d28659588a3c4ced994dde075f0d36bbe8e9f681a1a8c8c21240c10201ce052a87c488c0ba552015d5de33f4dca4db4a7a636a5a667a380afab98b0092e4dee52f8e9148a9bef873b704b98ee09463ed5ea52e46f40ca9a7e475a974a7b690cc08d081bed99d0a715f1f5d7b50604d1d420e2433e7ea15647d5d623d6eb194094517a0d056f9c9067f591c5eee5fa0295ef8b8680a6d77fb5cb3284d2e669eedb3aa105ffad86b10c3c0bc8c6e6e06d11f6ecd1752468d6fa16214c8480e746183413e62feff402bf6e443f6ff3825294a9b35acef54e7fee1c7bc07d9c881a585dcc4da53f19805d260f4160f99665645d7c892944ad25039f53c90e4b982308099cfe4831ce4e0e8468c1406c3dacecef79cf994d712846162eb75d1b548907c9ee5f57be83ab39dd022a9904da689e75be7fb080a50ff750c0d5771d9a5a8a993fcd60102c49edb87c3576fc89310213de499606a181e1e9b4da6d923768713e93a0d6efdab3fee982240b710a8e3c89c944d0ee1b06e6f332947d9f442a2571d5a743d9e336b21ebbec5b40619adc2be20cca99aeb468cd31033334c1a47f70e54c54d0ca507300b6fa4ea5db36048d6934325da8947bb6563874e2fe2948cde05c3f9281bb006df167caf6a3a4f576f336528639c35f40d3e5be9d869689723e740095ab0effe6a1799e958a523daf33aeaed05a22acc73629986e5d13546675d93477fa33e14afb5c2599b54c4550e1d57fdd4792a8f5a1da5a249ea8a501b02413d346c17a44827bfbbace15b1d3707152fcbb606abc597b58da4ba948b088ca6dee3c1114cf151ba8582b50483f712dd1ac0de2fce2262f9d984a212e85ecd47d5d5f6012eddccd304ad77315d1b3d588e81a453ae7b9e1056955f78174d7777a3cd366b68533dffc82b29faa47b11e25c787799c46c666b7c0135c80793582e48bce66cdbd8a53a349bf0ae21c789c74066838d3b1267fb6fcf3c0b14bfbbc5220f3cc078779f7140e6729a6662ceed2edba89b24d4fd944e8a47115ccdf54e593b12e5bb4114cbf1df2e4ca41b5d795f9c8aaa408975f60ad4a91b0313bc41e5cabb2d4d46f3be5c6b3e8faeba6b648cd2dd47a8dba1d7b0e61c08c7705fc8d9a6bf4a58de53294fa90276c2e43808321badbaa0b74970e9231cfc1f359c165dfa37684abcbc21c2c2488d14403c54b93b0d35b5eb7596db900e4f3f74b4e9135980ef0b4454edd9ae689c9580afa39861a2fd24870c6c78da2fbee4e7af6d19f35b0d78e0ebe8b3343c0d5f935a36a227a9fe4589891af39646bd1ac3a85c84baf8515fb8b54ae2e2c4dbfa136cb9e55f6075d4fa5e3203f59d0b66eeb5530425249a8e8dd288dcf3c60020bbb4b11629e441b8c458ad606e207df425a0fc312716b11b67def82ba818d37dbf4b874a07aa6c39c483ed8b29cc80487032b9214cbb9892479f7936e6d67ce79816487cd1ee3c8d2d542072ce03711fce740454cd01b2fa3a302a62bc2898b455e0796aa88ab271e8ebea74fc84f2710518e0391a922917bee05aa89649d7f30bb1a470a5a6290ad0810428d90fc2bd647e65e6004b6a1ec009b895bb1a418814ee3ea1db5b2bc36d9ad281320252a2388bb2724a9afc22867c7d8cacddeb200511bcd8e997b4a9600c4706737763b858813b5cfa885b3ca891fb4123c46abaae3eb59d65e58b607f60b785a351b8854b0fdb945cf627f9be28a897b136428c5dc7740778c7d3a570f64ec8c360d13ad42e489df6184e4c24c1fd68584d92ee6b04e789678b185ee9c2aacd5edf2a0fe68946185ea218d05030167520a2e0280c92f38c07cc3b964601070925c9d31ca76e82a2163bb799be7e2d4143a4d6e3f50a3a2245a5842a326277d6c70d90d22460ad2b48e4f4f6a309a1594ec6eb087c8980225d6ce8c1dc07679aa420dfaf072ebf5077ae3811957f740baf1a9ef8bb2384de5dc09df702128e3e9687427f6e3fa136b4a4401adb010c49dae8089384226e53f42bc05a23cc0f0646758aae5dd044909a7c12f8e54dae8013212609906df64117cbccf6340679a237691116d430358b596701f28afa0b2d6dc9584e6e241ff54c8493a7bbfd621dad50ee1f8ed4ae6379841738cd4861778384b86a1d2edd3cef535b3939395ea7bee05c345d351aec2c36e4d7b4b1749c45e4b0991e89707f18b1c9c2787b9c96ea60c7072c87f85f1c51eca72ee6d0d16baa8074e8431edbe829c802541041ad439ed2003b091d21b26c46fea000bbe0711a3ee29d3554b5d5e8f80b62f2522ff6ce0cbe46597fed9f662a3c4265c4ba848d64563e39df79916a6d0739d9b26cb16de58b12658f19faf02f73f9f851d36c60fcedfe99c58e9a9eb50f6efcfd605c77c41e2e84bfdc8a3cba5901cc09dc6c49eaa49c6925c45cdad57cd82295566aa39783365025c27766e9b1359de7e7c0e0610a56a905c68c5c8fcc095058228f39bd508d5c4642a67333a9736d65e7aa781440d2b5e2e25ff018a9dc8f68063a24b143533d80f9b80efd1b41902fbc4d61b1726325f58dd5515a98db07990dd765b19aee7198fc1bea2f80fc15e62898169d9df130cd5bc53b76369acfc6ea40ba3085648234dbec48371653c1dc3a8ea2f62a2ad8609edc373d813ba91178f2f38301185c40aa3728ed82496d01179062fc657ec241dca102619c63b2675aee076fa30a05269a0512402ec9c319fead6b80d8d14dc66f69fa157d064afa9224d111a44193852215eb803db33eeea1810c532d749e81238f094f09dd1fc6ff18b2b2eac72d550c834d38d5ae98845fb7288b8b24561cc7bfe8d9fc40f4e5210a5cd326c81a9ade7e9e2d99192f2b00d5a603013c7472d1c844760731b852118d9a041d1d41f88ab73479b99fc040c2b0bb5c301aa47bea6297e67e0774e72113edbb2a4cbf9f78721982cd7edfd2b010f3b8cda691e939d59ebcb03c2035d11f41e48a66ae3c486110846c864f3d572a48fd687242060322965e0759619b10a4f7c64c13eeec8bacc08c4a0787799b6c5adccac59bfc005cc6084e95816af7e50d1edb74ae53049393a548636c81e045cf2e8d5e7eb363f364edaacbc0ce6a50950b8d2382a9c0d69c11b440a28ac519c3c521fa22c78338ae77427026c71ef40b7f47530c1f5df980333f3b661dadfb9e97f36752db2e2b92896c091d124886b3e8337840397d9a701f387235f3357389422d9395695e2b6330e51d812750b9966b8becc9491fc8e6a73ca01d8ba1946ee40b6cb5f71014889c43813e974f2e353afd9fa8ab11b77cf75ebd995d77b2c5191210021346e7943098e31cdd7dff5becae46366763d5a7cc4350d206261c36c0b8011a193a49da841381a11ba76cd0a914d3336f3d788cbbaa2459a5127e3f9502c4803c0bf1b5741bd3c14088d4c63e32d51d0f5a8b58861156114c81dad8e5adf274c46d6ca16ced8552e4cff3a4f5ceba9006d1a02cae6c0304ef743bd68bb1ed1319284fe8158d4fa66144464eab60aa3886c99c155e6e8ad148abeb315c3ad28af938097083f1bd635fb53041f57e31b25c1189f8386a8d0f3fb6325c5d48483706978cf09fea40d083f88ec0fd71f10a350f0cdd70833a2ed71fc0d686e98a3a8b097459c65b4b20e0c54a82a45f2be850f288bb3a8158d909e98c44eec8ab73fb444512b32804b594fe92114055389e06a91f604e88a2d0e708e630ce4dc8e1b4c78eb40f1bb7b52019c0672ce4b31d14b01e1649839b14fec9ba483dd421beb27f0f9898314d0bf5691a4dd73a605b5ab8fedea9e991a780525eabae1cbbbf182a877a32185af1e864c7e3f5101f1396fa3020015d0f07ca4f30f17ad39469cf4c01b10aecdbd8168b0f6293e0ac66cb01d0082dfe77215f9c5bf5db63cf3907c1ce76154f13ec8d06adff687c19ebf5a1e885c24f3e1baff2cd25569c7d5a1f01704bd2a2dcd32953bc7b3703b2c26b9cf0c8400a2e8f5683d3ab933c4d5126611c72982d81ee1ad474a59cdedc07d42597e05db887f2759f8411fc73bae83c865a55d75c34002e53a20ac8d6ca98e3c064678e5036db699e760024c0ae87f709c2aee93d947019260f3c0a7749e896154d28f017c0a5c6c0927460a014afce47a8b338288c295bf94d4aa9eec3d349b8c5e21780db499d5644b5581f5105ab9fc05f114e3b0c9bcfc99a136b84d8fa08cef2cb223ad8d6af8883fd2d1b293c6fb8c711078695af200830e21d1db8e253ae8665c16fbf7482b58dc9d33a5931eb2fcb001e2d48e2baca865c9518a4cae65c792c6207895648015d0fb1dc4bba326dc608350209a69eb648ce30f89ef32986736b3e4b74bd43db53fb90412a7e053c2ff1715b82d452fa36a2609db78981a552ecdb69bca17a6f4615543dd946af4490068085b0c88f7a54c71fb99369f18c3b77c6099b5782c1a0a99aa7b6bbdadbd8d522115fce6de07531e3f77d3d0f8a780c6c4362aaabe56dabc0ac48108dfdd3061be88b7ab6f89e1f91ab0287a5cb86b59e67025c1334902d9bdd4f785a28bee4b351011038f8810d1b611dd3033f2ec648d86889b10e3c433e66235fe90a69927bac63a2224712fbd50968ed0ca9a45ca2e3f6a2d02aebf8c1a4772f7818ca79e52ef1ec487bc7973e1bbc3789a492f8ff665b378c94cff4a973a191ec11d4819d553c1a2686bd52d678668995a7492e887fbbc12c5e10337d603c1c90878185dc3884c51fbd8e4c09583b8cbeac68c42f74be2b7dfffa2b217d13ce20d2229ae0b452f3e1a45967fe384f794b0912d46829a8d42813274c842e6f8e68b164d40116e774fe36e46779a7d8da1a52d9c3a8d7ca459bfbb2a05b0ecaeaf1fb636cabdf23a40769154d06e6198a3c637d07f9d149067298fcbeac9ce88d8c3639ccee81b2f6499f347d22c36602372c1ed36256a6356cc0391ac9ed7e2bfcb738322c07818315db9f61a3db340f6989a738e7b6390c0347233431de2964e3bc944e3621b08a8b6bc44b9379c1b994334c8131dc7ed096671e950ff90c435e2a962f04b44eac54e8b1ccfdb02d87c5a08cf4688f7217639e772975a3ce9db169d221cf89b3650391dc11857450276ccaf9cf54cb84ac4895fe68e4812141897f2ea075d14ad404e516a7e5371074ee75dcfd4f21d1a65e8724153206e0550c3137f8d6c127cb8920f323e23a5310828dd5eb89c434e50c0f46918ef4b8b0488009f53e713b8bf9b6b3babe20064e26b18a0a9594bf87301721cfa051d30e8e3004fa40a7cb359388f20f6c74309666d5f5abec838d193c98a92db36cb02b31fa39e89c8aec64f67fab1052a9be667f64e9d87862ab3437d2b3c1f31d2d2974a9bc3c71c0938db3e150a6f7cfa0164ce597a27e3e9f48ec9fd826ececf026dce8913af69127705f8d7293b3828001535a24837c38e51c39ace2885678139d35a2470df16e6cc931cd1f1d31e7b889624c6690a56208da5afe799409b54473ce5d9aa5568eb5953ac305592b757e80504d9f24b81b2f8a9696b6e812faf1eefcca5975181bb77bddae5be9755b3f2ecde750750fa33a25d697be72e96b55f0674f4fbd6711ba34f8359f45b860056727923777e54208eb71bd6195802c257a45fb973f3a775c817424ca7c64b23514f3c365ac8e45948f594dfbb37f4355230fd7a3d1b6301a51d5961452c895e2a3ceeaf2914c230f61ccb8f5f4443be32d8f1428ed928c3330e9852867f94116e1920b8f985d0b409ed447d40542c0da572a34763ff6f9daf00fff35338a64e51f929d8248ccd23bf17ca8f7fedbcae9ec452c9f447cd1a6971f35b04fcf7f8a54743596da1411f660c5074812bc1faccab89e7a066cd6fa08374e87f96cf1eb64a56f87495c24bb5d03c4e87f69fab9a50d56110199df5daf47ea2cf3c884da8f6796eb82e82e405e41b32bcfec5c93fc535aa3ca8cc43320bb37a960323539acf418831bf7aec91887a20a5aa7e4fb83f75196fbd98e0d3f94ccd9ee6eaddcd1263addafcb81a5e8c9f4abba44f8f281c77e7a7db35fb1caa55bc604e1751c050a1198232ef98c3d260610e31a95de5a4e0d0803aa141e3b8f607410ccd920886824d10a63b94453bb1033233a5f36981e744c18f7dfeef266b31175aa028499d38eb7391b2a029592ff4dc116832ed78d4afdc63ec302beb9431d534887af1b931bd5e7b6afcdc337e0c1fba377adcda5b0e0c8c1909711836ea6ebca97884d019cfa06a99e18707cc85fa96050107239bea442a248fa45954f305a688b800355910a814aa7e03208f05c4d5f2d9879bf9e3ea01de08d14b56e3ddad4ba3d1d974968de4c0eea7411840c760bec3ea75b526bfae5c8838486027f2fa1d05d2ba302ad75713d298cdb6371ab902d108e164e4c46f86bc6a465b09731f5d174e7ecc4df3a1d936c6c242ac07bb784acc4fe3d5aa6f9a2d741c158c4d063f7465ded55fbb6e7155032bdae673f6bc56686229be1bb26d86cf98f49c845db3fab18203a2493f1fb9a150d6278e025379dad240f4f4e4d3acfc4aec029649223a8348068ee40cf809a316976440f7a607a77ef4d0ff52d7005e888f8c489d487fd129a308e047b133a46da98e0d0c4c2824783fc4831a705a28d07592b228a6f71a51599b350fac68d913519f6d9d6ce44b8e03d030587a6e2d710524ba76a0c9a82294e49d252742b23666ae5f199a034f983494230e7be7502ed50f42bbab28a1e87fb2432b781ac3c25395a6578c0d46a7b0558736d2a81d93cef43c448c51983505e3f1d54c2fe905c1220034d35343a285c856a32c7675be6e409de78b0a783db881c7913077546c8d8624ceb031f9935976581df1a42452ad1bf72ae10dd0407036416689b04f01318f821f57b0ba498eff089bad77d82068b409efd4c8009eecc4b0e1d04861db4f2f0d0df81c43a5861def3c727773fa2fab4dd53720bb3b319c4bc6246a38926f5d0713c3311fd12134a96c8d9c22441f8688a71b436644e4578dca0901ac586f4f41e3f64f72885017a6d19aec2a0013ff77b0ebd6a63bb50145b06b727afce48f83a2df9843acffcbd1a498414a247f3e544e530f453c9ac2e61f06d4fc900c7ade859868875c209c1e2d1994c40f6aabdeced7430c766c90f1ca9c5b1be7a3c0e7a95c19128cd1c404606326ba742d1bb03fbd1fb2a149096fd90fe67b3c55aa73b02a9f972c5a8be90a7a0c68eb89c33a999160e498aa5788aa54d991869c7367ba3f29a1f3d7616bb36cfefc5ea6ae03ff85d758bf9a3da9ef21a7bf813673a99ec72af0c84b60690e9c63299770514db7d9403fb351fb127aee082f4b75ab9656592a63cf110985a39bf07f448c6f5f81a5a8f98c7907687718bc47a8f35c67a914157a84bdcf52e3c48661e27c0c9d4ae85d88ef297410b0f04f6b08115a068a0421e79e3047de12b3296e186776ceb7514c4564001dbda03aa5bc3bd12d84564bd77c7546e88bf7519f444fbfa5002894106cad10a413c66ac43feee7885e8e10fe1b37717237a403fdce3d16bd7677be3c96d073462a10835016fb0a6f189f66b727b9c53475e402f2491ea54a9fee32a9b59fdaef50192e8794c01fc4650fb57a4d0b46dfcf4814293c59fff99ee64ca86dbaccfaa661083dc78c2d246613f13b74d1a154ecc17ffae8ef4b4ca67bd14fb5af73be1e0fd46e48731da8c62ccf9d3b28611adc5bb2e31721f20e7019ebfcb299cfe20f0283a8b384a7736d07f38fac3843ba1db06f93635fa4110992eb445b8a30f6137bbaf2e93b876fc70a5b3005d79e963ce1ac0349c735e180accc9623911fcea422c42e47c540f58abc76a1af5818a2a1c26f02c73e352a773ff032946caaa31766e5f7d5dea909d36992c0a9772b8807cdf519b73125ad4288bf8c233174c6a85e06f433cf7a603ac1ae70cba78ab57fe6be6446b18164ed7ae4b3c29929c9b3822c0890abd4cb2a9870cc7fa173b4b8a119d5fa4595543af65fa896307902ba501a923c674cc2cd13d9067cc9a80d40e9e158e4fad882ff67a7858508a2020dc2677b87e4cbb625ba028c474e71acad69d2295d04f339da3cafd1edfa64121b2b9a5fd509081d18eeec8d4738971ad32dc96a8707f594b0b1e7e08f1e99192b594ce9593091c28b71b946b7c1ca0e6bc8a83d8c63ae5c989a096e02208ffb15d896b091cfd3b4b892740e9da7d3c30d00eb86dd808fcd0d3e7b389e8f799b14493364fffa24f86cba161c7ad8a2666289d8850516224090e5df6cadb0e5c58b9ed0273fdfd1378c0f82ceb26202701b20d2d97f01d24017a7d808f261b04c855f2131025bda47b0256c8f25061b37505c7bda4bef955c5f3b391a2c89e7f2125dc51f7a4b5505729ba6babc64c9087905315f9a0f5ff6a15a1eb16be08db1d5d68e534e02136b96a08b03eaacc48a1a344c838f9ec6155b9e0350a7cc5360b9b77153ab1ab48118e4f6527ffa711d26b104700836a0f4ab69ffb298fdc250657825e4727c86d49eef827aa1cef8483126c743730ccb6ca1717d7c82a0ddf544d9eb6f2a1a981f7a95b0e5a7de3f3b5837d05fad753eb0f6ae4f88c0234228c74b57f28b73f22bcc049ff4e7fed71f319cf34316a18e59a9caa298e10d0df1fe387f07b71703da7a46df5a8d538ce4798ed353a05db3bd81e435c56f0096432cad1da052d16c2e0b9fbf88209cc4a819fbd3e5d2e0c08238d42aafb4f414764c01be329711118632e8c23bc85f3e56ce299d4dba0d95eb07da5e54ad6f2c332c4032776fbeee9ea215b35b45443b24a67fb31ba6414fe085082872ac9ef41bb11e802718cbdb02e8995d4e386e538481822f2eff1295f8c8904f4d2529ff55fd7e39ae9eaaa17794f5474c00b614edec32c65027fcd7e6e8ace322c4f09484373c39ed46a6e5ba631d6d42315041a001c919ca0c9460158a005151fefacb7a2639d60c815de8239f76285d4be00c8e29c3ab8c1c547344ada81b60ab282212ae83966e0a4e14eedfd2542020e0ecac783728d072a95eec10c5d06052d6b24657a6fac4599ae961a0f30284f9c2620d274db3b3397e53957c5237bcf3f901d7557791dcc06b132b9f7943500b332b0bdf5eba35f0dea7bcd5fbba84d1fea3e964d7008f8116a131c680a63bcfb5465d8f8a222acd950ea3d6efec76f57535857fc6415fc7817fdf7cd35e37ceb3eaf735c6df80df2876bf20f8eb6048a9027351548b248c1774030d95323dd740f67b5b78795c10d1dd335f10114203eb0ba4ca960e6ef93f56609b583d72c253f4c3ad59c4f42871fbe1475a238e3673916b9ef9aecb5e8a445f2cc7c389fcb08f08813fa8829702bcfe47ba5dc4a03d6424ec52494e37b9a53ac8f3480cf520899b90d3b3b4c00633eba6b4a851b0640fc80454d9ffc55d306935e6b10382f0e76784813153c86e005896378e03c55103169fb94a93c37f7ebec3944cca7fcd41abe28127eef1bb0ff1459deb8998702b690731d6816c1ac4d0ee8a22a5861f047cee9c7c91b52e3875db85cf670346b6dfea9537fe6bbb2edc09c2bad35a06f4a90797b92bb614490b7c278aff1e08294bba62e9596f079036299f9c6124c4c7359fd8d6f53ba49a7128991417ac3fa36d94845fcb2effa3a255b306447ede4d90a33b1c183a8ba44d8607a7c35142fe39ca90e585f8bf5242acc14036b2e7eb314af0207bf6049c9fca22741b776bb570d8475c90d28579c87325f93d47e8e9e0bed15675e7558498f3d53ec74d6f20a6bf8949506ecaec7b108a540905b50c1a4d4b0a9f744d8aaea39ed44055f6ada1fbff0047db67e980694bc05bf375640a891cf2d8691049610d137ccdd7bd2dbd0468518b0d219bd1430225298f5a12e520d8da1220d9a56056230cd5d87d88cc7f4378c519308dc32459c87cf10988b7f0d173549045afbe7316f991e19c40bcb63118967db4ace0d2713839e299e155fe29645a4036291a448e2a296428651e76b8917aa80f0035bfe4cde994c2531e43b8f95ff7c659991e942a0e84cb9953ba5c692fdc204fbb071746399297388070aa9a38029d770791eb2ea7247bc50c7edaf747a6fcdbaf99be2e124c1c7ff588763c4b9ddb4a823231aff1ae1a1701c0ffd5431f9b197bdcbd6110bc584e995dbf2a3de6485d57c93e5783d13f0eb4a170f77bcb727bb6c24788e78f434a953c6ee1c66048851a4e23351d544eea8509850a58e1268474ad8e4a9ad7a76f3b580b4e2e9621a2eb027a52050a432ebb2c7e146d974277c97755b873bde786b28f82cae3b4315d62162a6dd0853a844c55d7bb556e31b5d8dc3af7583448542c95823f2420b73da7cdf1315a29d08669eb55ab60bd3debf545a76a9af21e60e71ccd2909cb5636ac9e183e44ea9cb285aa36791eeac5cc2715febb458e6d4760a73c89c64b6c72dde937577e8db1c1bd7b33fa65652267507f21cec45580789d1e844aafb9769a47c9096a573a586a77a93f291351ecb1290024aa1b8707bf8ce3967e6d88aa28b1a59f7a50a595cc4878c14fdfe6215276313fc0b39bd9c353a8e78edb2eb38d9dc999bf00b0f3107003df723c27656f850b441ea195c1b86b1bfd5cae5271d2c52016e2e48b919ddacf099b3ac8a04a50a96bf52878d9b62d770c61cfe0d9924481cf50a5dc9c141d7ac4c06c2b30830c331af236eac8f8694228be79e16ba1d848a89cc268e824264c54c4c224af51d94bf22bd99d3c9a2f493551457948298a528758a2c4a5f5452eade6bdc865874934797b0cba892927125e9a22a064dff6f60fcc8572fb8bb28ddb708bf86a2941b5e684949317ef57b8c39fa9d2fcf4b7e55166e23924c0069983fe045a9668a922f14ed9ee2a8fc6c1ef127834a9ccc6395a36e109dcd0ea45c037a60be7c5e40103a52074533bf136b7f8978c5634883d0aa92f485d8c58844c095b2a72bfbda1ece0e29bfa2855fa60fbea6bf6c241357cb5dcb03f4c81439d3129f1d22ea8085405f30337a666761d5d1ece52fd232f07154f964ef12eeb6a54c49ca93079f079d07e1890aa6f99ef8722e99fe4785ba1af649913b84352c46c37e9c61249b77466a584d16c6be862199917233ac8c7a3522135265b2930c1d40084f5566843efbd123168a3d1536a3940184ed00a333457046a206f0d03d60859f1640105900024008a155a1cb1df5c6cd4dc691c24ad44123fc59e53b5bcd58a5affa41d8398927d8ec2921b83e48233c55c135e14e36efac6568186d18a8ebc6623aa7ee540ca4dc8d794c0431c757a5cbfe7223b0421942180cd4f5e5429d1ccb3344bedcd733193a004708533998157e08f3764298bbee9ddd19ce28f18418f9d260c0f585d8733ab16a748d00d4009010eef0cd680ed415c2603de486c9d001a61447054365233b5033058b75d648284ea372805328f45b3275ff859e9d665da3f1cf3a77f959a55bb667ac9eb17ac6ea196bc69ab943e9d2fd5a969619ad71ebac59f636f2a70caeed9a29b83e6debd7ff85108943070ad59fd64b9e10caf5ebd77cbbc367a91c0890fe056aa66fe3c50df00d4b4bae37d6f2e0330223404a635adfb9f7f04162d2ae1a6403b2a5eed0ea4148727400531f5df6a83a5f75c76aa9bee940ee729d03e5fe6ad25dd5b9ab5fa82c3bb9b3e41e7e5385e5534ae9ca84d26fba3329ddc12e937e1c2dc20ffe77f0cd8e813eeee881791c0d9e0092e667f03d514a24a2df3ba4b6dda0f4b79476d520646dc467a64444ed016aae362635259576037cbf2f8f6eede83246136c55e0d1b1f07bd1939e60b363b0f01355da8b8c0ed8d665adb76ed9db47b774f8b94844368c923528861ae42e99982791255286347d5f0c093eee3bd23a36aab0c3866c08f490935549af9abe30265ff8e0ef99eae4b85c1f3cede0991d5b9d73efb4cc92554923a1c51481ddb5c20c2130fd195260fa95ba781c0d7668a5cb5a77aa2eb703d8ef851deb1a04eb1227921ead06d5a02d3467565aacbf6556baa43810b424c0d682a3093386c0167c4a71267db5e0581a2b2c859ca0fe1ad4adcf842e73682fd23ea4d14824b2c660540a2a0b6c760cc73c5b73df279226cea290344f60f820d9315a135a2d442da425e214a41deead39785e4b91c1019bf063c5073f14493056695d6b389a8e6e81a40935d7ff7db8c272b93f249e60513b585211effa7d3444b21fda9181645329d9846e5d2b3eda1f47d38fd565ac63373a76d365531f7ba757fdf4752fd9b556695d928860d7755969a0b0b4ec8fc2013669d77fc7b8694a80dce540bef2f77e9d2e97c3e1cef3a467937e85e63880edf7b97b9fb8ead3e5d9a5b7290aac0307a9083e75c86b5c9ff59571e8a89982bbad37ee5465774b132d61832d1506d90ace17100d34f107a28126f6473e3ef55d0e8d3e6cf4aa5f1c819f892cb2c82db3e30c1eb0efba551fbcc1ee4c2580be3e5f752a01f4f5beea7fe1f5c24b487d8de80b487d8dc81951e096b593f506b2dc4997bdb3347c57965666b1a861cd14ec24265228bc903b0753ef5ab26bcc7c21c42ab5c862a7c7f3be660a76d1c616f8849e94933d7cf4aaff850f7e13ef70d78aaefa6b44c9fd3434a1dafd7e72218879381ab16804528100bae17c7d38c040386e7f1f0b2d744bd5e507fc1be0853ef287bb60230e1d5a4e0f48f5be0fdf5aeb8f2e6134c8fe0072bfc2bed65c758a5dcd9192ef8dddb75e6d1185ce22991954017bb568809a451b5be0cf2ed4ec42cd3868cdfd0c501a843543be4fe9bd7f2b49860aa4cb1f4cb0a95275ab8e8038f3055f0c9ff4d4bdd2c63af3d57d5215b81ae971d3f72bed15e66f0482d282edd35cb3bb30cca9f2d3091c3b09cf0eec35a307dc9f0a3dcddf0d8a4c126c3ff7806f47b2855edd0743213856134c1183bd484f70e35359dff348b385308610d8fb9d7c59f8f0cd29743d928528d7bbf7698466b7d66cb0babc2c1772541dadb1ef7dc80b897576d3e57def7a649d75498a01f78f1074bfea40ebd92d8fe28890ef57247dfbf67d0f9fa31c48694c97cf36698640c277795064e222e503c93f9d5c4e17dc126cba9cd95f1c8134911b72385fa2a8850c22274f45b0e972ba9c80884f7a1cdd12bd08d9df3f140abdcbf8a1b2108d96ba70b3d76f9bfc5ad45709979ffcf23ef2fd9711888b7f791f4117632f718509d86b060ef8c67f0cfd539c2338fcea792f8eaad30c29a1afe34d97a12f8d38ba0cbd3805364f39f4aa6e89f5455f4953fcd187fee462ac29a01274be484c60f33f150a816f431fe660938e108457b8a13822e4d0dfc0a4793ab99026c624f2c51187bfb8703d700c8946b37e95ecd9ffc694016abedff9fe252570e9cbe507eceb02f0de6b2ba983f82c895dab03b0865e3dd93f21816bc52fe4f453670c816f37a55f76794f395491ae6013e31e92cbb686589cb51bdc703402a92e30028af33502810d7a603386c026dd926d55e29b92e9586355f603362910902e4957b05973b2b50fa45b395565ada8002c5abe7034d21928d172deba6323652ba55d350b5b35d22dea53fbc91648492d5b28b7764eb76c4e0bddf272c8220e5a63adbd48f00c1c708db98b852f02b4e534fc902497edb3608fe0b63350d7c72a0f47b2ad43b2fdfe3edcd657f68e355665329064c0a62afff7dd6fa14b5b67a02bfb4370476cd718adb14ff660a14b91096949b7388501bc842580385ff7745e710a598d7569493b60b3c6beaaaa39971d80fd16a08f82f7236a81cd9002200f32775723b007748b06359a67bd9c873b6fb69aa7a3d56cb7d3c379394fe7b9bd7ebd6bad5f1228578f8d4a6068f1cc7a568667b29faf5d5fcd9ebc6f7dfb859c66439ef5665ec8561c51549385358a53fdeb9576793a5fcd284e2814331282ed047939bb2d40edfddc2c9ece5de0965ef5e7fcec0019d92109caad24046312cb7d2e1ba3e00b0675d9f6fb5341c4642a9e60cad6f4d32d99dc3f52c1f74d97c9644beadc25f4d968f499afea0887df4bd8a58971ee9fc41c56464ce18511fe1105d8c44f93095d26b3a920b089ad0d8f9e7e59bfa6128d4618443577b9cc572daa8d58d63433d44cbe230e472ad814d532e8b5a95b4b8ec62c1abf178daab65d2e1ba960d3d60f6d00b0024cd9ea9b9d8371f152c2f4e7c7c5649132fd94ad73dd1233fdf002b64a6debd7696db75eedd7cf4d9a36df07ed583e8d254b776b9d88776db56d59ee7d7509dc4ba63e7ba469bfcb9697345fc94b96ff659b69ecffbd392bd5ad67fa30d5ed25dd90d7d6ae7cc0e6d7e077eb1373b8ad559429c5b16428d3b71ffeecd7f2b2bbc85a15cc25b19326bea098e3da2fb4ddb25dd66c0588bdeeeeeeeaef757fb506207069af64cbfd868ffb5e1cf611a0b5e3e8c4e30dd83cb9d98267cb354471680d40efedbdd7f3bcdac701dc7549eb8e0020cdd4fa90e33911152a4958c9272f532a4964a135069260432dd19ade22c4b4464b3655a80960ea33822bd93ca94e14a7e6fce12a485eb4cb4efafa3199529c7641715ebe7edd519c92f8f55d46717e288ecbd74b9bc8f6bd24d97ea85e91ed7f0d25db17e964fb238f22db071fb5245b32bc49d0266c48e261a957849c341418744c110f4b60fe6574f120581a5f1e043d2c8d2f2f8ea5076f4882791771c47fbdd0271a816128248df66913d9dfbf5e91fd1b4af6779decef51647fbb24bbf7a60dcafeaad09b3789ec9ffadef46cc8fe3714c7d2934694e84d0f4bf6f742d2f862f466c849f61785a4f104bef9c190fd5dc8846f7e4e647fd268cae29b221eb27fca0030d9fe97614617e30e5a53ff65ac345a53bf34d61dada98fc73e694d7d97d165b4a63e69f41fb39ad5a453b0303b4af621b98a6c7fc831a21dd80478bdd027fa767dbaecc7daecf5425fe80b79a7cbfcc75e2fe4edfa74d9f5eeaecf6b693bef5c0835d41e787878787878787878787878787878787878787878787878787878787878787878787878443133e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8f4c36451dbedf5429f68048622c905975e5cc0c498644e2f5029d50f0d666d29d48b938ce9c29889a17219ede67e4c31302e5e4a313e452b6117d28fa82af37662087abbdc3f1ac917b2dd28447e70aa9fec031a996c13045b5bfec9a6c8f613934521d04063ca364130a5b426041a64843139b6049a3b739001142749b0084192173cb0858807748c18b18490d7d521dfc729c822887c7578ddcf33f511414e36f1e3e04da9ed1dd8ea44104129a5f6f36a2d2c168bc562b15a63fe361b2c21ac1b37426e685ec8d3288594305808569d849cba14c2d2a8656983c5aaed2a3f9d68fe63b07d2f6900b4a67f0003f01d44f5eb907bf65e4b29a52010f1f5175a2bf2788810a1a71e77a7b1a136aabd2b4d190095fd3b9b10c84eda20404a8393a29416615194624add9eac0ca59e774d21198d81a13404a188eae75fc13457bfc9a0e1fad6dddd2d08455c2f54c40bf56a1f382a8560682f4da4945a4cf24477775b23d5bc59a63276c0f5afe8b5da1084223cf710cf1801297d118140847fd6412022145620108aa89e4c06bc1411cf74b2eeeef6ce18c1f5698de9326badb5d61d8422704d0d01a188eb9882a8179d425577550824e7b6ec2f83961273d077eaae52914b62a3b3a2521f9492e89ec8b9ec5c76ba24ba9c2e279259c1b11003f2d123b6f3742b23a714e7e9a91a6872628801879033051d4270b7369be1505d210c36dbe9c013f6da6b6978b906aaf554c65dcac080e6595f5de177fb62d7ebf314c9ced30b75ad694dbbb58d86b6792d43a152aa53ef74ac63304c9dd3b099986ba5455ae0ba2548243b897061db796405da01729179e03cbdd0e770b8243fba8a4a7d504aa2a3c1de5391ec565912dd29ba41241315a1aece89723873f5eab448a2cbe972b22f949d52ced8e9224b729e3a990eca2d76d39d5f2d89eef44263a5cd62aaad46434d27925131e414d51c186c2756635556eb08a4cb1f600837f48015680b2cc4807cf488ed4e17e8eaea8da2bac2d357fde628f4a13537f0d86100cf5e4532dd13b9a6425d7db614b943297d8e357091f5d9525cb4b8ec5c766178dec2538708628e1ecf6597c4890475b9ec5c762ad07db51999cbce454bbb3cb2ab744e24eb9611370147ecf442f72c9f863fdd7575f7d49d3f3af886c562d568d5e954230015464502151911c9c2337778764b4abbae95abbb5d5d4c05fb40043a50ea314a3b5701af5f600d53f4d5af7ec100a650a8d67649718c6200438aab2a5789516762c4f0f7d50d54769a22b866950d1a68f4aa7f8403b634c6f5aed6ab70b9b19d1b6bb75fee44057ba211188a24175c7a7101630a29c5499d30d08b1c3df52768f722448555577328544a754ac9c030c1988949cd800393692a86cd2f77897061c3f9ea92f54cc9806d26193d9cc817afe63d95263be510900ea618b1a7da50a90f4aaaf05405064d37ce94ce66887c10d5d67a81c066fdf9a135ed35af31b9df5feeba65fe1341cbfd343ff54ad50252150d7dfa73e5a4729b87c51391836168a85b7caa2798b6b49a3f6013d75aebedafa4115e1bc09c267e2d3eed601930e0fed7d15a66a32971125a81cda6d1dcd54d8bc9ac4d169b65295dca880114484430c3112e08dab16cacc082077eb4d8e554987f3f155b0718889f1d3cdaa69f4609c64fb878de985396ac5a56160d16f5cab6e9b2bc2969dcb04d6d48a34ba7f900c6b8cc5dc2c801bb3ebaf2f206597ede14b6963b9c216926305eae621360efd62dda320fca77ebd29eb8dc350ba55c01367b76b396b433b36731d8273b5722c0f696fba9f5722e50925361a99efb22f6dd60a73a65da4200800a7cc10f07d83e4c101826532636a0259b3813f9e911f4e34aee07b2c203b4e84841051e2348e1c0b983c71052727f03709850c5c94a6de8344e36c61b183c9620bc3c40271eb6dcdf802f54d9a6d4c230cd298c50f0cd0dba8ba10999e526066c7e5f2d811424f79b608899fb2ad7da03ae6db79b96a6f5aba574ee3afdfcf390cc48a5a93c24a71a2f0873de0ddd5f73d71080394d449f0752d09226c5ddd8187d699d344334fb884f378abb203cc126cefe9ee3f22a06dc4fa42c858092fb69d8f87efc1c0a91acb266ef56d657d2a8fd3236700211ae78e1b3812d98f5d9a75eb26e32405dde1d24e794beff07c5a1df45e8aa3f041248a4894b3821f12ac826ddb132dddde4fae9aace92317e54a06e9974d743085aeef7a1b392650bb522d7aadb0175ade84a67b262e8421040f63749c866d5517fb304259098a20228a8642a4536ab6ea436fe7894416d7c01b9d2953f7693010ec8f52925698e53d444dd22e57b7796fd58edb9bb7b3774effb685a807a30ac6f14f2af9b1bb0c9baf1cf9b65034503fe6cb260904d7ab2be18f600c64eb6e47e98a7b1a1b2ff654983bff29f06e64422a2fedb2aa721d83ce5b6d1029ba79920566e4e9c843cfb611a1a5129c0eebd7d5bc9d34b6503fe68116c966f04e839a1e5d0b6e9b6e9ef210216dc5fe9fbe8c356d27ed48e34c8b1f83881e57e20d4c2d41c1b37366e9434fe4785b54d3f49086cd220ef0710b10a4c6929a3027e4e5e25d96f8d341b979d7a5bc9f63d5c975e5bc9de83d56c5cf6baf4ac47d21bc213dc4fd3038c7de820b2e4fecea2c5615570b9ab941bad9f0f6b3f7ccb4ddd4f265ddaba744aaf3b69260de48d42fed53b19361b68e73550b7b2d41a47604a4beb301b4e5272bf8a5a181aabcaa1df7769a9d7f1c4031c30a1a73fa53159df04d70f820986a1c1f5a98f3590d0e1aed1f7519cf9d9e2faa2effb300e91b46993954c610424be90669f582188ea7804b193fb1b7085c70a326c52dd0a3c1a90834daaab05a0c1a2856fb2e4fe1bd4c248a96f6f84fc0b47dbf4e319366f6e6ec88801d3a7b4f4ef5c9fb4b4c6c9134a00861e48956c9900f991fdfb0525d9690bce247b0837dc2f03863194efdddddd3f0bf816f7daef5f80cd8f660b560c894b4e13bf65dbf4bbec807b62ffba64ca2d798a823f871ee660f33b6300027793bd1cbdb9417dc29c26d6dba954d79dd24b29beee273f1dd736fde0073d1504d8f433e3bae567b7a4541721d8f472397739edc3de12baeaff21f7132f0a0dc8bcf16ab4a62603089b2cb7e1edbe10d8d87480cd4a0b6380ab0cd7ae75a539c64018c9fd3034254e9ac91218d6ff857e05cc69725fc8bfbca7342ab8d75a2b49df02e56ad35f83065c491e3b4c36e0930ed83c79df1e89c36f4ad616d06403aeee262b3bc0d4016c9e9e52911d407168e6a1420e3f13ab80619600739a5898edee211a7f68c12e39b81fb603e6dca734e6775e5ddbfcb44dbf8c0c38083edd65ffea7637e80275cbec5defb45cddb572b3f49629d8b45aba77f671b4ebdc65bfafceecb6a477b27218c37ca745019863af4dff6f81ddffebaed276e0725b51426972ccafb23a9351b2ce8c5459cb6739b8caaaac6b6eb0ca3c7c4fa71d32bfb2938c94e5643959ae73b20ab05961a45c5f0a5ca2900b05619fd298f52cbbc6da0646049bdf59820a039d2929b8e2d55f5980bf0fe3d3e9ffe62687525447c18f2ebbd65a6b85b1f75e1f405c60b8878f1f40bae57f7f6092fb617ab8fad5392a6badb5d6de5abdea55afc2e4fab7f62581f4187f903ebaec37ebcfcf95763dacff0bbf1080f54569ccde027fb32ddf0f3bb2182ebb151f5b6d876c5623486498c0fd0da3df4e80394dfc85fceb3e8b060dbd6dfa4d58bc68b45ed11ab69d6e7f96b85ed1172dd72baa002c5abaf5c427fbe87c019b45250560f101410560d93958c3f6c9926956800b72dda2516290cb0ac0b2eb562ae76400ad8377a451b0e47e5e764c41f1022b0b746038ab1025370479d911e78617a52228cb0c2f3bd2279a7881d609273a45d015148102f4b263093878c1004a620722535e1ae8132079612c3ae05e97fc7cd529285e96c4a10e975d521b4f9ec07510f65f78d1785f7bb26389e2d01b5a63bbf4f1618bd34ef87aad31db03e2d8da6e2f3d7585c1b87a2175d1f88b9f87dc695acce1df47ad7d82660ba6dfa9c238823f6fc1f697d4d05631ea64af09055e0c0a60fce62ebf9d67a62ef399db3c5d0fc99e14dd355fe9bae5436829056db9115a761ea360d38d982ebb478ef0c0435eb2c4fa91233ec4fa90aed967eef242a4fb34d74b86320806752b26f78f51b05fbf3aafe60533a728138d88b2dc5f45b8918f54417038ba8d6c99fea8e6aed40849a63f3a425ba72e69ee523dfdd18ce2949e8e532420f2c9f4454ad0160b5de6280e7efa221cc579794a7774e6e9dfd35d309efec5b9eb9fd66009755920bb83bb936d50975dc385c1b4c082ba2eeccaeea5b92bc6bbb03b1f807015504ca1ae3b3382aefa4d8bcbf46d14eaba5705164aa66f9fd0d6c57599b3f4ed6de48205ea16d90b9f5293cca35e9c4221538c2a08feec158d3da9d40e6cd0ce0a1004c51c3d29f1851643a33598741d29691465629150175221d2c41e8066b013f9f44a1486632ded4ab4971a5e62eec188582e238c7cf2cf6452d236dde508b992261a152f347761db8bb194115d5c280e0b25e6e899f1f1ba3065c6d4ad6dfabfd27e9e2ce62b180a282708ca0abaa2dd6c4a9c4fe8ca49fe8196504cb9e59ed16a3652ca26d6f0ccf8a2a45777acb9aac0989898ef1466d1d833339392d5e0c3cc0b0d9602675e8846172a8c680a0bf8dfa43bdc79f3956966a2996a26db12baea87915f48148e069b8981f9c9e13069a27cb2c80a8f747064bb9db84a9ac41abe7db31831c41c234f15049b299b0792225c97fddec8c5222115261e4e10e15236116ec6466ba466620f64b87b214d941451861239138534256d8304365f6831b66ed9a77da310d7ecbf98a3fe8fa38fa571fc53aa448bb50468eb458796fda55d2907344725d4853bf1065126d2c41e68d92fd6c694adcb940846ef25254a3ab16ea1a2b0f27933cd4c345ad35fca0136f14086aa0d6018618c972c1a7b62fc288608370253a53115a335b3d44e6a86140d1505f532a2240005f58496fde78fa61b8c99d154ab8169663a4257342e48d3ec881128c2c58021d6702815337e1fa44470265405c122488ab52e41b04313ea237b6248eca2b12786fc3cefdad148248a628e1725f7a5460bc71bbc6a432484e0832384ef228bc61e95ea63c69c9817f2bd7284fc2b47087e913ffebf3762e0cbf66d50b7425ddb1dd05628052d61ee2ad152365f5d23a82bcc015ddd5b69d75705b455ca829617267367e428fa406bf48fa3d88492d0ffa3b884daf4a746d1368a37d1d640c401b94b8c42578d80d02b86146bb4463f0942b844381394dc26272f6f9a98646ccaa1df748496f012ab23501cf067b426940249ee56ea082d5341e8ca49d32535c34f8ed6f4a76cee4255415739d0e52974d52d9412b42c65e1938364b299b26191b25991b2e54c3313ad4b2535dbedc4f9aa2f89c291300436c5da8747da2528c221c9d549ae3fb99d097625b9fe0b697e455e68c8fd33a3c318411b365e0240820d1b3636620eff5a475fc1a738ac02c0c89844e17a4c4f020da71a431cad51a2893750d74b0d2f315da82bc96433dc615aa9542a1161c3a6d51a39add56a591648bed0a698b94b94b5280b73dd2a01754885b64a33a0e5ce5de1ae44739708e735505748057d89b92bd4f98ad6ad97590fb4f592032dfbc39d4b364b3b97fcb2cb3225d294119568255acc984a8d299aa75c4654d0e8820f5c9a41ca4809a85ba921b40c77ee42694157a958b8452a48ee1f513a5ad32f8e281c4a8473170a0abaa222a773174a09baca0125e565d62d54145af68e0a2b70a82a7041d934e142a32907d3116a4262a29950a3c966ba995aa659143c933303ebd6f78d64c788e7ece46aa66c9e93eba76c5dcd94ad6bca56df9cd951e59ab2e5fe94ad5b4e5237d39872d2ab7e97ed264cd9c41c29275da67c48d9523ed890f5e1fb811165dee2cc471109a18f1f68231cc72f6c855666b430d8cb472f87a6f1348a79d1d81343d25efdc7b8211cba1ecc49a4116b34620e91c907628e944daca56c291bad9c1142080078a1bdd48839441274804dd38c96fb4db56e99622df70c89896652d22db305b7f58bb54a615cbc94b00b490c618023d18fe40737563327e90517edc306174f60dd0b8de5d553b5d62651258a0d86a8c284861a1747aa28994195232fb52a3ba51360520f5c1c81c12c5cf060910c604a40a5054b5061e2a990a008cd0b162a3d180b951c4a4fa8c868c0305b4a3c60100b1d0eb12089620a2ccad4c78929d9fc378248aa88133e3821821438c10376e2066bad9581133b3a4ce1c14fd9f1c0b8b0e24a0904539e78e100c699fa4c49e2862936173698d2838b9d29b2124cc9290dc160a63e392d72c06296cf55f1e5d394b9267250723d44c9e570839c0c380a2cea00e6078b57bc5cd1c41332c03199fa3471440e8b99fa3421c4973605baa769a2872642e0328227525ad862ace4498d9658f0aa927d451794cb758bfa3c01cab2c5ad5c0bda4b530220c7f96cc9d55da16f2fe7e016cf018dbb5c835ef020920053d29230dd7605b89bdbaea47123e5d5c91eaf7a63e982b22c7d681bd36f38dfd9912b8be15805c26605fadb4d97fb1d8a149c6fb802ddd8cdbcb1bb135e9a0cc09c7be6b66199acfeef298e5b99afdace727fe85f7899a71c1a2d2cd7fffe85978da52a994240e8edab107afb1fb9732041d4572127ef25af8dbcf515eab0c9325d87a266c74cd7b9ee96fbdd8a5fe9c15e5914ecc194a435974dd765d735c1fda52d69dc1306375a13fff691d2b2000d858e154e1cb79cdc6fc20e15aef834cca9cbbe0c2738a5c27dfb975cc157adc35d29157cc0377a4e26cdb17cb553dedcdc701ae46a2b1001b443852be7ed04017691015787e2a7df680d0d09f66e4f684d7b365ff57b37a7a585badc2d7bb42e691477cbfd3a52f08a78329f39ad07dc58075c9f3563b1623888f061d990626135ae60b3cc250d59c38288b8d55a7dd411c326d551ddff90ea726d39dedfc73096da7a81daa67fccc166fd01ba3ff5a75bee359f56a8e46cb7263d0c0d8d0000000800f314000020100a08c582e18030cc0345550f14800c7b924272589d0bc4490ee330ca20430c21841000080106189899192902003785e9c5854614280c374fc0c372a733ea5d31214daa140a65a8db3c8ef3f165d8fbebaa82c88e2d80dee085a218ebf4ef8c626a7bfbc47ff5a359e402a0a53c5eca43119a1fffdf1840b80f13fa552b3875d5bc7276fb1ddebaa266a389ac23915075e94d542ba95ad6f1fecd19e6a1de6ca5d20ffc5e2784fbb66386512261b5370844ad7facc07f55e16d24d2e1b03d626cf7a2b14384cca659bce1b19c59e9ad1060384dc3474a9ab6e6bfda666d145e89da85d470614e564b989adf9f456431acc54ad398894c5fd49b07a381ee3d11bdd69008aad52ea247eadb946603e50a4c69c485f8f06550eeca89f0c30d5993f1b7f036b011fb3a896cb93ab0e0351a4a4d6b30825e3946c368548e453cbf543a2a8b5a35bb2c2c1d19a043e4d53bf89b9ac57052d1fe4527592f98e00d09d5da9a0d3848db67026335303313d4d95179bd1bdbd5644cf7beafe7ba046bab5c4781b7222eaad0d6672b99ff1842d65de11c365d7b78abcc4ee6abea7f9d5248aade9c682816be1500ab303bc58be62f2d81d11ba6f1290318e91d00c73b98b9da745d354d4a637f2c078dacf78cd222d27fecef534db3e88cf933a11e0a4cb0114d539118f1a2b1cb4f282f0f3827717b93470d6c7844e2b91e8a8921d8c435aea0a68fbe6b36f04c34e9bb592fbd216cc2f25de031204cd0d789ac7b989715c311ca848f996688075a6ce1d5319457c65e10e824317ba1855d0c99b6faa68bdd62e366dee1f42b97fbc422cfdfc23446b5494402032bb14d62ae2b8cb6f9a482dc032535f6eeaab1d04c803e655993b6533b43ddd1f2490ba8940df82599d6f61bfbe54a03c131910ac65bb7428392b7673dafcb8885e585b84498a2e7d64c3a8fec88808b9d7dea5d328b33ab43a7a2a1012ddd99b14382c399d5807a2f55176cc4fabf52359690e7be5041c6e5277cc92a11158c88ed9c48c7fdd9afb078aac4c826004916f2c58336e192a14d59e2941d8883975045beb1f75fe33402a6bd99effe0eaf5a80907bd909e8fde64ed07530bfb0fd3cf778b508ded21f27018a4c67b3519dbe2c89a231cbaac37d8b12d50c64ed701219e539128ec27649ac6191156761c8354fb4e5795065799d8a3a4de43b0be3eb090d8d31a23ced5813bd9fa93bc5d194cfaf63f7ebe19f31f2a52896026d77fdf7e3705dd12b238164898455887826364440a2a60198fd85e802166fe5e331770d464f25f33a3d75c5f434d31f939112d4f738b8e363c3756f822843d4fff03f87c86e626b33cccc9dc120a462c76ba391a6af2d7c656195245cd9e9832f984b83ef2fe5ced89f5fb15539894796b3b9b98c669ce9e0b4206efa6c6387b5d144b2882e76d7f0148db818415dee683eec8bf24e3edb5a512c86ded4b366c4bd90bbe4dc2e8df1324bd07024e277ae6bf7823b5c8f6fe47381af3f1cf2c26019d4f45516bd1be6660487ca330c438ed350de74fa75b281574b9104bd21af70cbda1a125487749f62d885c20872050b98a6efc2cf2a0ec494a66540d4156f2ab4543506161cf39d7cd382d8de143aebee686a28aeed1697e9f7676c840626efcdb699296ea04f7128114c9d7fad739a83982092b3b0912fbf390a374fcf3ad31c57adb5ef1f306a7ba34e25a729c7d1f1d894b10372fa9a711b330652579b0d246ba1786194b56000b105e7d3c427657b10d89636718cd0f5c39e806db149aad4ed1b701009775bebf6b28338b2d93cfb23b50a558ebe41623dca1b53c9bf666ffad4350b09c191ba980ec6780053b3be17efa12dec25b97f041feef1a0e6a2721d627d911e2489248a3256c319976ed5b5d551e96cf348c35fa61063cae8a3a929277e6fb9ef9c518878cda2b1529cd36d07dabc9218ff431faef7719d76557c135eeb98a211c753618f80e74d49f658b23baa87e8fe52081885eb53fa98a1e9e1348019587251a54df3947ade5e40a0f173cee27ffe9462d58a5d086208950c801732a460cd9da202a7507a08ec5838c2b9d985afe809c3f1abaddeb4b999e971e1ce3a931346d7848aab27b6fbacd591ab6e1d0c8815c52b198a4eff7c84e78f31015226cad651eb601cc9f06465db7550345dca3a18b25e91a79052e6113e6a9d5d00ffd8493ef549a958370ad607ecee378848b0e77090506a77f041b25bb21ab4d2a57256684c3a44518680f17927eddf06928385228612e472e13ab74eaf38533803de6c99cd5e57ba828592995e3d18bfcda49be54e1b89841b7fa03dc0100dd59a65743175b2e0e49e9fecc4973807826b1479a7d30727d02eed00123d0438d8d6479ca6e88e6f7807f714701a2b6864d7af2c9193f499295becf6029efed5ac1658200a305fbae74ec1bb0f2b55b3f1f8dfa6ddfe3f8150876e92947850082c806c4a2cf9c9af519624ab08096c105041fd69ce63e31c6a55df234618e874e0f2f975f7f435db8f4fa4d8a8c177e8acdb1c6a0bd0aed07db1ddcb9e30b3d15359473ad0ed979666a0690e76887ea1f30fa0ebbcdee1a4e1681bc4526979ad92a732e822138cb2c93b4c4c63cbf75f999390ada7c1359be00186929b17c9959092e9ba76a02e2529f4c330355c2a694da2e3b4326c9092945026de4e681341dd997d94340cafc9ebbc1d3bd822624ced2051c998cadd87250692d0a9d1029d77133aa1b06e66d99d4ce6051c19bf8134a01f80ee94796f8082b6a4052effd0da2ead3bd450cf467becb3b65258c67458ff17f2446238eb70b13c72e3eae96637695da7879eafb0c3818e868f23f47d0e143ef3fc778e0ae8d7e94e8171911dd07114897dd3f3c31be6059458887be37bee6c7d270da68bb7b5dfb6a4f7961b12c7db2a53932aa7db110d8d8bc2296a2ffcef7d689082bec549d732025a6d2f2f44b849f602e538647240278dc779b757601222adda73c123cd902a234f9672d44d4cb0495d2e64d9b02d30ea569f3498163f139ef20f4998d89785df54750e6732138d01d9f250ea8f59994c7d21b6151c84d72c88ff752237e9167096aa6c3eb0ab993abd873981d2a404482bb94597a826015778a6ac057f888cd79d29c3a00dfc2fef49282ed2a6266abf456b3854998e0a584f050f78833a885d73eaae359830b80e4afa987c511de0b0cba37c3f8b63b5c6ada30a26aed62437a303b8e62b24da4056b6c0706719454062e3f786fa46158da9274f098ab040677ad2dc0c7919a1f8cfd9860954b93a10c6cf49463a610137c9257c13bae84eab191951044930ec13c378faacbf0594b2260176e01ffc827fa954a914f92e9232a32a419ef8728600d23a160f76420369f227637cf672db2ffd28693734c5c5d2b289c578d3fa0928241c9e163d6ab17ac3b3ca9ec155adbcc090496375b82d6cc5b588e35ebe453b07021eabfb0a942f3ffb378495e61a1d78cba7c425e8c661293aca950eea7d5c1c4afce4883931dd76d2974caccb262e386ce21f4d0b3f737e9a1c9ba23c4cde11bb1747a22bb7c90f9b3922faf9b7d28b46c39de3ca52b49efcfb5757310674689c605a80efcea79bf2acf0751c348326f6599d6b468d9e5568b39fd49e773199f7d84f186967210c134690a6f3356b8d266174e9d6ab9a3e4280a78940c3f4318411e911a9fb00c268d84026b1820304150fc4fa7be227d03992905f6830f2f0e713a638e00e8c013a4ac4159ff0652187bb02058f8d5934570a330ad89acb494b244bbf14fe03a3485b1c18794fc9c0680b083cf0c2421ce65ddcc504462c1767ff2341724d53c088f11f29562a3b14b813dfdf98a1856eff03303a66dabb9c1cc665e32d2c61daa34aea3afafc8e76d4b02248a8c40c765c2fa80901d28a4908ffd750673697d65ea23a6e35e376de81096526b578d188fce5a2d26d316f6e42e4710fca1392ae81b4ff2e740551ca5bad15d04f914200e85d762febf3c92024e440087bbe5d210e573c4cb401ef70fe2f6014f2a7209dc4f15cea393d57b8a97be3794ba0d894aaa83dc7543ef800104f27df09b9027fc27239cd4b3ca6cd0796cc2dd1d06974fc8328013c933a4477dbfcc530ace5e3541c3b2bd85aa4745ac96d37bc9fc0f032718dbfd306f4b68c21a1a80ceb8aa025a940ce6218d3cd6f894f858f78b0b6ff31451ae5acdd47a56546a838b022d69c6e04908a6472d6537673508b35c06eab7b4984bf18a3ff8fd6dc0e9be5fbb4ea6b5bdb423e69d8513dcc60f2e38bdbf843d77644265bed89379461183764c508bc71ca6da83ef059fe83eff967f3cc7ad53e727510b7911bdc8fd6f60a32e346a722596865d2ad6e733d4c9cf7b0decbb8dc1d4eab8d6c68baab08dae24233c4423145cc89fd5e59e2b8ff2af6a4c5aa6e6a00a0c8d448587d4d2edf36271360b74b3d9badce38cfecf52bc96e3a87ee05f38bee7014c2db4fb0d1028c9f0f268b0758e45eadd5b883f9cc3bc0c27ca4a48d39e7f546e6ddbcb203d603f52727097ba64c4ecf0d641ae9ca18a2a09782a5807147878af8c4ac19e73593d0f27bb070fe965ce4d0b25ae3402bbed728e9e1995aea2c60834b4db5afa729e1e100565636afb523df61c8aefd14e3b232b0167268c5ff0abf539c19dad74aafe59d27e6fb024603827678d0e4e134dcfcc0da78d98327e6f1f51eab115d81f1cbcbc5704756eba77cfd09adba1a83a7a95a128abf32c74b0b07585df4b88d735022f8f5e7d291de91661616971cd908e6659e27218dc5fef6e4c82fec6e29d9054deb0bad1246e40a0952b8f8331123e7c38c388ad7d20eb41046385007baaac781461e644a0e3444d5f75943677832983d2da785c6618f3f151486de79a4e24536fe47f9d7c08e631be9084d437ae32ef69a94b1a131aa0c764bcad508fbcb44a31d5b3e20692e7aad3082f838699e45e4b35026d32e1a2af11f11b9885505cb502606a0334d6fbaa6190708389b95d30e636abfe370df90c12e4cde7bb03e58b2268de156591e66c6b0b56ef038b7df11db96969f42e33770d3a6d48e060f76795c7014c9df2ffa934a4ea8622c1cf8c6c661c12158f2a66fa63a26051fb4ec1b4e13c221955a711544c975290cc74e95dfd63c0563e359a81e2ec46ec31b1cc37a5745b294ea6b2f046f4b575783ceb26a18b90170fa96100904c00391b761768bccaa6e20fc8cce9554ae24a06fb2af242f00a2dff5ebbb1a39e4d1eb8ef2059f1a4989bb1d443e43a4c8862b3ffcfbc596542ea9d62e4c9e1999a1bdd194d665522825b870a0d45bb2d15388966e38e4299e39d1a167fe1c222af15bad1f0210d2eaa0bea1d2bf8feaa4650c5aa849b2f9ca8033ab47264aad5c6f9d492c0e11eb23d502c97c32120c6eac4170ddd40de8b48808291c0887cb7c81ba8e8402ddcd824c29d267ec669a30f75fcc7cf5daf744a282b238d3ec29aefb2c4302c2078c15e7a114ee774627421e8510574234ffb4aa2169ef554f8cf98dce22c21a08995db4be16daf63f7c5b63bd562e57115a5879c62356366a6d31b81343a8fe94e55979c1ef1b8bbabe4d29a72df86ecce58baf078116b9f55135384d2f21f1aad51fad6d96ad1cc0c9e9e6ba71e9351974ffef4941ebbad658c2bf1a880ce7abd545b7f71823249b02ee6043b475a939bafc723fd99d4957d0d4ee6da0d22692d83a0e972792ff57ffd811fcd5d6cefa89846f39821807e2960250d117dc55af96c8381a94a95bb9cc6f0d68b0a8dd64a084c1adffdb6f64882b97a140bd0599c67d84b6db3d059dd9ba8bf630533cdcf5a575cd696991a578c4de8e0b265ae33474dd4f35eeb6a4e85565895a946ef1d7ba91eb3c839a0b1a7081800ebf4c695f9ce3cb0acb96d7675cf177ed4ecc914ff7ac017f282c4cdb787bdd72f04ee1086377823c51833c795ab3e61d4e3c6a97b0925180bb78a4764180b29517b40bd12e7f9502bd442ce3e363006e28743a9f9d400a0e06aca09a9568aaed3126855d85e20927af35d8af150c07b390350b7a45a04fb1d1f0b62ed8e59980d544ef2445ca50b4d8184173527c5a3791e1e7907288d334751df5a94f1392234b08af1cc38f09fa963067c9e3ae9ff45d7ebaeee5a35e8e853aeb8aa1341b231539bf4415b3c3e5d125f139dfed0b1e7d0ab6a9657634f8ab9120fe46e7c6992fdf1c9d66b196898c01766cf908c7dbea1506b8a5326ecbfa05aa44113c1a2460963a82edb608d0f05eac4d889abe6d3a0d214be5e9c17f3367e2a9319df1663d84aa187fad452a38adac4d93305e439f5fa6c0cc84399f0e076b87a0940213c1d74d58befac94dbf9bec47984de8d7597d212d48d2e4493d22299fd6cd46e3df091f0217ed0c452a454b0f0a7de412300c0c5ebd40548494d6986ec84d007bd603d85cbedcd8392f2ba6360e89c682180103a15f55132f9bb4ff1c42cf7627b56b7992348843be94c6905247924aff08480ad485a479032059268ccce2c772310c4afa9028dd1b539871a3d91e206a1767fe587eb3b6c1d1dfa88505f757c50b8b444ee14dadf8bc2942f6f4be2f2d6f5914f890091f0e74bbbcd359c10f1a17027473ae6ade582950ba30cdf75d4cf2bca3b29d4976f06da1226a2be40565256648b30ef98709663c5d51ab33628745a004dea0bacc5074ba0c8846d2125b24253043cb4a2b413f19e84e965609b45012772b468ae8c5ae6ec8d45c308186104744f747beab7d40e048d2ed5b00076e68ad7eb6a7d368a91ed5f8a0179e6c5f370011f84d0d96a8f9e5d0992e27e857f94cac80b1e1b2ecccb8ebcfeb3db674d9d139c2406279645e97c8e61745f24ed84426c0d9a4cca3d9a70f479e02e97f8870e13671597d6396a74bf8ebf0dc3c2bdc165dcf30faa4a7fc8ebff9ddc7ef30dc3b21a4328b453245a97722d0bf9e782835b00d86de7ac8f19ea4d9016fd7fa7c24ba1f13148f893a5200ca57595151cfd531fabc78919d192fe076cbc90a4aeb44fef43a405772a6d32bd90718dd6715dc1f3d77e9c3c2445bccb83b8c21c2d12b296423a292703906165757f254a727aa79e6ca317090ab5ef8ad615863c7236369ae6f62cbe1701a2eb491f108fa60cb88c45b7612147c14426d3b1845dcaf654b905c2cc76a1593b269916814b5517ff12d915aed7520275b2cd58f19ba76e9aa415df5a0a701b122f4b036fac4878ded1e98d3dbfb6846cfb382dc903c139135206ca146d96a9aac5634391c473021d68b8e5992fbb7e78f6927c9976aad788d01f351f8fec5c7b3885e5eaffe99562e113f2b74335734b544ca998a37145e9d21bf37872a8b9622244ed4b0aff631efb6f1897f1c3e991ba016b3b4c906a2e00d80ca37417464b95b16fbb1685deead4b5ed146854f702f0452a0e9e71c89f11093cc42b5f091f689e329936b5e110fd54a22829e988369025003cbf5cd80eea5cd16d2c1acd4aabe1065c889ec7b4094713904973feec14570da958a9d39422ee7181dc275c9752574633f786882560194d41ab20550ba4614f311c2375b367695ec11a4a895e96ccd91a9af80c04ad39d3216521cab34272e4331792f61ea4310d9896964865a02866646bf60d710d06960b826323171ccf1a8ec8dab68d861346b054c0bb65d27b0ba93d06a448df7c55e6005efa2f992f9cb561c2396de3ccb4f37d95e23605407b3ab9bc14156b80d02120575b23e208e015151c5b96c40ce48210e185b8291fb6b3d38dcf10f4d3aaf906ebe3e747a8f76bd967fffec37d3bf12a608822d8592db7eb0e4d716871bdd2084e75d1e516c45bdf0008bfd1bec9c220808da493218b2add20ae1349e6fe2435dad86df1a54963e6be2b2120372464c9d1737da475485811edaf53741cd904d692dc03bff926e5a2a58485777e5bce67ddbe93027da8e1b933d3cc7224d30b07d133b49d95cbd1ef8be823c325429ea733f6ddd5ff85e75726d492000f429ce268336342e9c45f7eed1de0b546ca46a761582af681456d41612472e55f158008eadf6489dd45db5e723e9479aa10e5b0956f10c3c33751a99639f44401b0f741cb84fce33accd2a79c46363455fbd97fccffeffaf07b89ea947004c6a6fd34a81221342b8a889aba2fc8426e868bd520736dd71568c7f213bc6909b42802957618654c85d5c22d4f67f09cd7428fb6a99062f67eabd0dfb57f63d9bf6b5414e8bea770cc63fbe1690dcf295fe35637e40917225b2e61083d71f4a214dfb218c7866b274c366c10d051232660e92f795aacd1c4d1a9d2bd62633166bc5fe62256fef493a86ab15f30b4f54f797a4f5c29011bdafd281126cde266747fc823be87e2c181b81f20022aab95142113aea228acf8c1b5de5b9d7ffa8083b91d0f1bd7b7a89b155d403efd49cf6b887493330ac1f5d46f5eedaf40248dbacaf40ea86296885da2d36a1a4a185799124a0677901a867f7d4e9249a92c8db69dd3adc889a47174aca0e4052164d423e8c2242c69a46439d569b6e3dbd66b1499c859b71aaa9ab240dce7601323e7f821a0edc859b97c20c5bd1664484ec2955894074e1330e259b8b4a207f9bf62bc8d027108660c914e4f4196f06ad7a203510ccb5795fe328711d49e9a330c08651c9de00995efd35efed0993a27dec350786563960843a11fb8be9751c6c4aa168031a0a9dff4ce04c0a3cf3a3f9259557a3814602b72cdac51976607a98b5169b3f33fb19fdde818a31a1bea268cb970ccd7ba043a13d8eb7bf2979eec28a03373137ded94963ff0248f69e8b2facbe4f1cef16b5468ef942549fcb4e75c9f56221cfe22952c9f367551ebcb032586871eaa89a833ef5852a7628aa74e51ffe426b6f1fc82b503f1494ed7f519f3a6f138688ffb4ea83a10c8c783d1aced63e3ac964ab5519fca6137707febb881ed6ae553468954ccafbe86c5804d65a5fac98889f67c0d4cf33b6bd4db19409c9049665ea13e8526f9e82f2e8960d8a4f4c3dbd8b8a5457334f922aaa92794d490ec1859b46260948f4e0ecb620546d66af41efde01b8c01380c337345d65c4f878bb253b9140bc3b281cdd078859415840217336dee8be3f53fa4a4dcae768fae88aa85a58e25fa82f86f521383675fdecbfe1dbf9d501a1ead03611ed0f57fb3162ef1ba69d8bb82b2d118ea5395a7bb49f2dc98e0b8a6757db57aef90201f74b948d4af693fa8327004d027f4e8970f987a5539699b742d09dba0d2f628aa05bd922168af21e690c6a1b7afa598490ec538d925971386a66c422bb6432e043d6783de94875ca8ba830cbb90993822e51dfbdc3bdcd87e30d5d45bf49c3d3e8d5d3cd05a8e1febbe96c0b3a6ef20f758a9b89bd7e13ca0d6e5eb03df79299f5935477f6920a7a920cbe8d2c4bf736ab4a6c1c9354a7c71f058537a86d9d76c61a8e1e10de7c8ffb3d566922f4b64f7ba2d5b1c528db5e1b8b3c75739623d4fbb9f580f9d034ce1718ccf4a5094cbe21d589be0e94107c56db4e495474ac8e305091a60a99a81dc2a8dc437ab2278edf4ec80b97a67f6afaa7a6fdaebc794f1b27c449ffbc9cbb997d413aed9f84c5c2df9153c907bb9a95fa3dad358000735857b722b08de3d60138f80deb2129a2ecd47e9e88977148166ce7f85f1ae4fdd4921a541d3a83bebbb8d4cbb75d6cbd86f0ff67029abb506ce4c6f61fb6325d62e002c16686cd3dd330c694054d7023674a5ea56b1d19cafa92b3cbb8e0ed47e656d0dd6e5855fff01b27f4e62fadf84da4b0af8abc583db43e24fe8091a98a95bd9f41082e982de3e4ebed784ceafbc1ac6d7ea0f4cdb41fdef97e210dee561128ecfc0063e46f0bdb4b7ced57273335a91f5985204266790ac9f59fbc161b4de2bcede896ccab90a93e7613a280a10e4433b5aa3f08e8cfa9be9fb2780608bbc376f0f0bbe3e4137430994d3cae90274a80f37c9dc6a670b670d60da5dd6aee52677aaa2bcbb2011ed40785be1e5e03a6520583a09b542374141399814f67085ea702ab4fbd0b74e2cc9068b0a1296fed47811039117a094c9113d873a534fbaf110e3808bd3f5897ed58358773b820e3be1939b5792dc68591fe1ac49a5ed19c2c01c8bdbb40bac3cc0577d655cc47a56765cb84e5045101b6b92a298899edda5dea35aea5f2e912df72aae292436f5b6565c2dcc7eba47c64e83e1e9adeddfef06a5f1f44c3259bb1453d4e1c443a73134b2d95fc9d7a6001e4d41f72bf5ae44d2f4a5f08277e36011d9997b408e1bc3090d2c269fb73df499a8f80f6e666ab4e1dd3a9db7dc18b4a048f754a9a4f42c0c6f3f7c20456e973bb3714d768018142bc3866ec3702504447002f85b4a6eff3ee6c8d574371672a15bb42deef1ebd5725eaddd5fd4651d8d31d6c74cf10602f0dd7290b78abcb39afbe967f3fb244f549c5f80c80e2f6a516e95a1801c0eb1a6f98eb6ab7d37b37624281a39985fc34849223c2eca64d6f2a0748925bcf7620c07a9778603a1ebdd3db433e5d01e6853eb18a1cd74f2d318ea1b63588e3eea3039212b78dba7c85ef0900a8cfb7fd2b8a9d86a908a36cb7b0eb6bba8c6a787d334177f85de93a8268358b7043166e9f9442f08c426330a0948fbf6065781a1fc3a5907a74e9e308c420735d77fb5e12fa3acfdae5ee7a798bea1295d2907a1714328849f767e8b09fe0532731af798074420d91d4c3513a0483b0f4f9b1c834fb3de15de6a9c5017800bc2a79bc0efb954fca0f716a4abaf0a2415682b946f9816dfa861c15f0e7ff6d726fed29998e0e91e9b688442977a19722b1356d817a616a299acaedab5452c9747474376b899390caa7f962615ebfef12d84fc96304a8702fd9b5853a52fdf6e27efa4c679a7985aaf9fc215a0a556a230e8c85b3ba225234bd3b468ff3db649df5df4606ec90f1dd8d233067a112f36f1a24a5cf52253057c9b840fdf11c30135ccb4a6c000b05075c103a9aa23ff08003de9a38f15d4b15d026ff4fd0873fd755aef41abae64cd37c43037811a26962f517b399a625cd4f911494cd85177ff89e844946777b8388dd1fcd00df1efe9fd0ee6da0de8c0616bd360e580592f6076c969f4762a9bfc03fc0f22a1e2da3492485b98d4f4747c0d857598e84f0e010aa5116c29878cca6a335ae9a0d28f757b6b9ae813053b2f8e504a3960119617476875db735459251741e3b1ccc79726bdb2509d54485366488e45c12507b5b3c08658786c61081a17d992f5cb05da1aceedcd4fb5a6896fdb6b9c393075aba19739c91725aafc612620f6d3a6cbf0c4be029cf66e9641ee10d08f11a3d1f3cc11265dd1a19a792970f4d6e48cef91acf8ae0fffd4fbbb07d383fd3f1313dcb28d1814b7e2b5c6adb011c467697a070b2d87ebf758284d7c1ac4cf43210c8e3db4557e30c2479c9cbc5164346b9235bf8177265d5ee73ff6c1606702e56b0aed5776f9715bb3faef7fede1ce2f34351f93f68efc5d3333d840c1a475e9fe9648cdbd0ea459d30c55d229c69f70de3ce8c65cdedb86e2152cd6dbc2c9f033e10120f662c964858bf11d49e1a4e1e0b767a83516b15e7f127f7a0091a8c37d7bcebd5d577e64a3df6608d13d596fd2c0bf4d23e3e0a4a58bde0b5d230bbe6285b139452c81de28fbfa2b089687aefc2bf7e2549cc73cabcdd31e7101d6a93d5ec6ed151ea5d43ca6874300534315baf462c6fe73ed9d26655f5df0a2d959ab7d8208fd52e343d106cac15824948412b112efb41926fcb264df3d69a005df0fa15f5264e80bae42abf43a95b3b14366098805dba3877b86269ceea948e94529d5745b33910f72d2c42f69e42cc39bd68cc26b71533f191bc3accaaffecc8576c8578c96ae94c0c2df6c77fde879a738b92ab771599dd6ad7250169a5d85710ae4ae07360fc16b978e898962666d8873c1d395ec89ab7f3fbcc8a9f11f760f0f0f06c0bb3cbcd5cebcc2602a41f2ecdaf89d0fe971edfb01f42f35510a7a8ff59c33a3ce3a65b55442cfd3e32aa1c0532f0c6358e9e18fa30b8dbea43c02c4265055317046cf05dafcbb93f2f783df4c1286a247e89e39a97d7feead71d1fc8787cc7784c03b6a445e22b590d1bc9cdb753a9e96528d597be848f2293590233e9ad75696c10133ac226d50ba7c4f24ceb42d648177ecd6448400d5327e1f1226f6d2b67d641734ab6a19d41937e9f62e6c58890574c6519b750d3daaa2a37332a3fd6b418d1ce59c8e221c29e0172fa3e3e38db31df7e5c27b0f9109c930d4b435c2db02b89c24d4c18c777c13ea544b9b39c3704d40a67d959da44a69818455d6cdefd81e2a96d1ac1ff9273ca816ffd40e6f7ed7fcae7c01666a4e84bad372e89be07243757dac2045024d53f67a8e2c8c5f21249b800a4a2dc94030c76da3d5e5230cc7ed85a62d32ca9059d1c8ab631d65c8ceed9f82e50651eea96595c989f3b5c0a590cdbfe7070b6ba45877effbf55601deae5e74a17771193691a45cb6d0ef9c585e560954126a58089a17a9d948c059cb1f3f401c25d85170fd5340d45f0c3454f98866ea6f6c51ba9193d306da27ac01a16cf7d65db31ee97356da2a443e820cd8d21077723dce0703f366f87c3dc48ba7cd74e8f8485dc5d639bf43af23f0c1453448079bdce6d4fd310f52ceb9cc99bb6af821fe46f23648d2ed002ae1a175ddb77bb4197a713d9a2457cbaf4bc55e59bac8a7e30256693d02f8deba06fb0899f8b38783d24e99c9dd37cad4c943be73e74976a27ecbeace08e5df25c8aa329359ea810780fafc61aaa29fd0a2eb88647b121beab9f8a87db6c17036a8da67ced175590df54a0cbde86a9fad33392f41050c588972bf87d6f929e09d19b1763b9ca643afcf164d22358d624dd174ed83309df0c7733c8d2ae120a7d9f95eba0c1070a0e8d78ced74075e230c9c10b6676f3975bade8314e84449bb614b335386a413f1b256ccee631b24354947d198b3db6ce63d750abddb0189711236b54a0925cbe284dde377ec713b77a47424f37e90140ee4d16fe2daf2ad34c0f36806fed13b4c5036d5202ff573052267e3605fd0c5c8b7718c45a51a43f844cf2715a7081a1f31ca57e972db46190ce1a460c539b9a990c8dbf10da7ca21d1deca717147a5e00e09a6281db6e67a5456724cf09faaa580e9447c44c0b0516a2b6342a10af1ebbc303899a63268694ea78588acf623925cd5ab1847ae7ce40256280221b9ffcc6ea8d7d5322b2e05055187efafa34d418a79e34d4dbc166fefb32b5579ecb95f009e49f138793a3770ab11a450187b3a921fede13940335f33078f4c78c0e1df9170e2d47c669c2112e319672f5ecd6a3f76e7ebb635bc9114412172e0eacad0f82d5e59d0fbb52b984fc6878b486022f1ff3a2e750647f8a56ca0786a6716775febc434080d31647719833c0ddf24d1af2f2c10e4e1bb23324c3a7bb872e1d62eeae5043c6b888346347d05af68066e914d2b95d062ff17f981532606d3d58a02921bb6bd113548f20c273eebe8b3ecfd52907d37a2e4cf4b5a88b7ee614a6aeb5b3bcdd9a97881f00e13bd90e57958e975851b5115e9fc2ff020d23b204c20e0e53fe7021254f4234dfba033a382ab275e551ed23bae1fb6e9c394154cc2f15c049061ea519b9f271cffdf1e042075821b41175cad34b73c5acd2403fd93c95936e50bfee1b19aaa7420822f31bb04949a9e5275e51d196b89fb4081fc058daa70343ad5e5d1a48b679b5af06a340743d8d3893403a25f7cc0084e3e51fdab5be0f3c95d5c2b6638c5041ea6d91461b51843445fee04b0cdeab7ce47f7590436c6bb54f0e038228c5d14c904aa74f25b561bc98cb706289e355fa107bd65154f0389eafed7a8e3b03f59ebaeaf79d5ac4b15df9478b15dcd25f5257d9f809b2ac6bd9dc63a4900965a69f8395c08be5c5df61d4155c6ab015161779b418cb6a07766f06f21cead971ea3c1384de3d23c0073fa514b9490f9a743c2d34a92756564786f920e21247a9cdaa71271191e24e3505802636e518df2b478e4b53468ba20ee98d961c0bad501096a567daa74d31600a136ce0af8fa845f538a7e28356bcfdd0afda6552ed9b86965f9e3624fd26f05bda58357d480bf6304aaa88e7287af3865edaa79f7e80031eefa4cf3ea858193c56552e3c07aa35e145022c057c8056d1f01404d1464ff0e1526aeabaf0eea805d03c16a996b1a3e3a96061dfdbd5a045eeedd4dec8d6b5ff4e85190664bd36a94a17fb213d5978fbe49b35ab047c1d095ad6e0d230c40be1ddef54602b467676c4f0d4c6fe8b99d0025f3b7e4c20633d16c99d9ae9322963ca548f28b1486c2d0012df3947cfa5557e8401d516c98c206591e3cf80c6bfc82adc4251df6a32fe5379d73e289e4e8f3c85f8ca836919155e3ea4cb0500bb8880616046eeb987ca46d26fea85c1d7af1b1d4365d3412d7909ba473f2e01c8cb097c542fd78e79b4d8c906bf86d38c858a094cd79d329de47ac2218fbfc8928d30e7cf5922aaff429b7e2b831b7282bb0c542944a221b888375722efdeb7568f0462db846219acd3a664e946074ca485a86b8c2fa91dd4d7973840bcd4410f08d3b48d5852fdf37a5bc207ca5b88ad8094121c0f36afe0c272ad136600b2634a6f6f0d536657819c3e64854664c4b48305d8929ac9a27ec573a5970cc9478d18f5a4470603c32e19d2c697ab0d48bdd82a11c885daa7345639de560135fef034b2ee1135c03e44373e27509ca7ec2730a34625f4b334636c1b956b9bbd43b25c8074bb358e0f968c474f7609f83a25275b37544629a30a3980d896356ea0754a14010c3cea65d1ef63a6929cbf87bf5b8d24655e00ad191235da6183b59410fde12cc5a3f3493f2c5be9918650edd71564d24c880d4ed501c42c753f2c6068013573f004a927a6631d38b213e42137e5500b18d590767b07ec26b5d7b7f2cd6743bb25c8ca7ec2cc6b55a398e502e0d73c219dd87e1af968058a288face77e64c2a1c29c8f59cd9ed7c4189694cb4be2772c378907bc111b505288b1d60005ffa0ec2ffc38df58b81200680136639ec5106ec82cbd06668bcccbe5aa5f0a189773685e8ee7f341e834337d67c91444c3a4041c67ff1e8ca2dce1c890e31403aba71faaecc4a13aec17a533369f5a9d5c7f96ae467cadf5da62cc767bb061391328aeb4f9cf93bd756416f8b147fb0f929bfe0f39873787ca09e5e6898a6042ec6e7f29502a9aca6a7b6d45e18a73cb3c61910c6519514b821603e7a9196931f52024056f49ce6a736c287b10ca4d3846f1a0799ad3e859ca369e331a2a5ce3f227cc15e897ef1857740b6b5bd841595f02c1be3ed19ebd5011dce8698435d29369a73b13be78c4878944c79c08d6736ab32ab93074fd7ab6d3534c5bcad82d26d1b6498f79eb286d9759998dd40cc6afcbb98e40ed6b1ba17ddb64751ddfd2ae73eaffd49521e92eabde9a9ba31520c3d4aedcf14e019e1f6614eec622753ca829e5d3ccf19a0702d671a71bda12d4261862505b6fd511ee06c8e287c9d22fd0cbffb5a3cc77af8be89c3c77feb65c0999e713bc17d5c6f7c36546c1ba22120253f5e3cb577c91221fad4131d94be7913f124568a52862e275ac9d3e4ccef35e22d32d550e2545e34c4126346c31185beee26f3a232214b742e0989991179a8d5099a9e95b46f5244e1f1e75b8ddc3ee73e4b075b1ef9176f3b3408ab3cc5c06c5aeff11d789e3cc054ceec2c0c627f4cbca3e4d8138f7f5aa654ed3030d6199fbda0ddc9370980da0d5c31b368a648aec51aa71247ed1ceaaa70b2af6313e0140dafcbadff3dcca92ca02dc62225654e3675f39573bb1ad0701c83ba28c16fa4adccaaa9bf8d3d0720dac23a5168d21d4ed5a1918c1563d93d773871f9cb3b6790019c68c61e3fb7d9850b31f9db695ce5a05b1c92b3114305f26de01a52ff66bf88fcc252e596fc6b0e1e3b3c20dc07244dac4b70275c6b0f1fdfe94e7d0cd2371b509c8d674b18fda97d47f8f9c6e47b8659862b2028d213da97aec2a26596553146af8ae3066b66c09272f82dbb44f4c9bf7fa06d6241e2be2189eed52f1ef59333fc0b1bc7a11dbe17b3b6eff47edf7d2735f7b77fc9e0edbffac2ffff6fdd0fe1d32eed5717b3f6e3f47ffc7f6efd0ec56c0888dd1462c65f54061a78ff4c71693ffb1eeaf9e3329434145b6479efe11f7f8bd1e76efc3eef7d4dfaffb3d7aafc7ddffd4577ff73eee7e0f33f6f6b8fb1f752f4bff61f77ad8743750898de84b2c6e75f0d43d0d3189bcaa17631f0610896273856a42938bba91afbfd3082340e6cc9a380665e7acc4635076664f1c07b3e7b660c19e73503d5daa4ae776a1e2bd20ae11fbbb8125eb91f032f6a63cfeeefbd0ed1d67774b41d9466a01a7ef18d212c50c0537ab4c815e937d02092af0caeaebfe7a98f33ed7dc513b9888d3367a13a4ad6faa738e3d39b14fae203f6d276bccd1b517cc8134673026432895f8469e358650be8dd89f58f5b1c5e67fc3e290e47dcc3a231b91b03f1f05fe9fd892a75a3545d71dbab56f0d03158166fd8fb5b242a64b63e6f44fc9092e69eb10ca2d3b0b2a4ea23fddd40c1327eaaa55ffac7e1c0c175f406be1cf5333a40757e71d50b8b12aa965305ba0f7490c0b8727464e14c9668ab1016a228a37f1dba7d2acfcfb36dda06a7f1785711ca444e5b36534528c7a0c73e20024b65977faf2db57007c2bb2c70fb939723f9130e27e63b2353b598c1ea9751313f609bd537b65407bc35a0b67be458b8bed69d95ceffe79fd5609c2b801f5b30671d46f7de16a501aa75f5a401fc888b5e23308d0790d2bd61e176f6d9592e13d7956e5008b01273b05223e5afa905f2cf60affbec51f340fda1970ae50795d5f3176b856017c96a722a283a3dc1a5053daa206696238a08693b926a45237113ec8e4bb4f81c9da1a18f69cfa19d2d2176c851264b831798895b7f10f632c39d086e1ac2a7a91fa3f79ea8e2498c7833218ee62eef3ef6fd905893ef8485426ea672d0c08bf1e3f823873165487e2c5ea851c42af6cb01cb881046bdf9c0d5a93c95aaf471688fcf2dc2ccc02562e0ff012981a72036e34fa0be194e5b1e467f0eadae83997b6b3c3fb3f5a73a4304333da585154ff63d054e60ff9c835cb5c2c63476669d6f780b3221f16c32bfbc93131b8734f97b530fcf91d9c307b8d9454468b507bde9ea0e37b5aaec885dd9b5f0e9ffc01c0894fd4e785c298cd5ef32589b9fdfb23fb1618ec1774f85535a2f800450bc2209f82de7892b0a9d39f630f1665ba056a3754199b4238f67a874281a9ac8e21f802878e97c3ff482fb978ea2c5be1f38e8a3bfd092ef5cef7a972e01ee31bbfd62f7e89a1f0cf0a9cc4e9de107672521798789a13f7215d0654058007ad62cf692fdb9cdadc2af24b2bab0aec98803509e077cfe40b2c2c754d5d86e3de655d31a1df2a3ae8fbfab52aaa79be4b6f646428b6c1fd3a457433512ce0178429d8af4a0213d55a11750931f4410c87659ab22a0102499afbe529c5e0a2b2b14f2a99343ce4ba39d7ce64370974cfae6f2f06c227d11f49fbc32c2631a4082e8dd12aebdac8a70afdd7448c833b3bb0506082423530af88b7d46842157ecf560c772eb1b51bdf1b5da777afa660c2c444c7459b28738a9894d6578d29aba146f552c260291f241fae56b4035e8cae26993784aad1de9be750f43b18aa9d80311a879e0f7f6b3fdfde854816302b3613bb008bfcfff5f5704713145c742b9330d59506235c36934471b4a9c94b12524d6a971bc2c0b64d60b942f3ade7a089854028916a8d2c5c599d7df5ab48b4999e005b1f520b85e8486013a761d84a2cfbdf5d9d4a338f83fd66df292aa2a8dfd6a0b7425bda060fd11b13fc7d68c80a3177439bbd04d7a9c571dec07def4143509fa06351480425e8a2ef171638943b4b23cedc9624e20c5829b9e30b2e37337be212fb40b0db2b6d5c35733582d304faaa14efd971add0cba1dcb58c3c8d51513049d3168c43923f79dfc3d26c5c04360abb096c010672a6d4d3a1cf78375ea791d9700225603d8789c46cb12f7f2327886e34f888f1c2373ff48f1faadc28330767fbb019fff4d203063b94f49ce07486f5019acf6887ba9d529acf5d57b4fa8d5d27abcdd01e2b5fff007a13bcc9ef6df22ac558988c55a65089d99e476fbfdef45a4ee9d0852702e5cc5df283ad7efabdcfdf6d99ef93cb22aa1f015af1ae916d72fedafe97891e6a56415792bce8acbcc18a1edbf1e24afb1e130e51faaf481faceb3b8d73869e5dae08ae75bc9de06bf3615cdadf58c2eb9bf23030418f26f1869c51ffdfedb57ffe4d6461d777173952108b984cc8a73e3d7ecc4d5e53f10d2841b035f122f16da1e8438994a4c06e9179afe44fa8bbd6cd0128e1b7debc31626782fbd4852fd5f862cef2996c666867535adf5bd482832f47a2da34eef4dc4ed4913609d2b9331ccb9bf1028b5093815711bba33c364263e8e4ff3fc8680a4bc68153976e49ebd17b34516134c128ea8ba1357d88c91da2f67bb1a0e5901be444b74e38d9a77041a303a2d54fd0e58d1e4dd4d4e4fc063b62dd7b4d4b6edf3d89c838bf945a009910e5600ebeb13572cc0c98bd8ab5af9baa339d490fd5c6c15de46a2771f46cc9f0366e719d911e57a358826412b4fabf0864bb9d25517dccbb36c07b572fc81b3b5a52e73a33e25b3deb908bc6dfc1996434c3650d40e068d16ba1608cfca57ad614013a77cdc24a33f2a1a62e0b88a562e6e1090b34f445985da48ef65cdb255f69e866aed60bd133cd129d874acbf2352a19c61a7c2b0d81d831f0cef6c2a5d2acf4c283c63ec5ab274c94fe4db62957c745b021d9919739d9481c7022e56af24d3636aa9cf0a4b0cfe233b1ca9c5e204959e6d48e13a6344de3b33d8a158175e14d263d981da7643b19ece08b962f3ee097a4ef0d6681b48d7b3815b7bfb58e73728114e5179f01f18fc54ccecef11f587cd7ee460c68e8920b3099c8f2503324b74b4678f8ee4aaed721d16cbf64233dff433d555b1efc426064c40442ab313e48660583be12e8fb6cdc04015ab99c8691abdb6a4dd14fc29b5e848c7bf789455e69c96e028ff9fa2a38e4a4e3f42c2bc80200459c89559fc51061960779a632c3f633fece7150fbc826b4eb301b1e5f6838fb142580956a20abdc681b25829058b5c8cdbbabbbda26585f24c28b3bc7adb243b609fcbfd76d09b11c6f705f9eeadeff866bccbe347389ad29be2fe5c797721c1a073198bb26cf7b99e407d146d508ae275036b0c69507f7ffb0b028bcb3b9f28f558c27bb16d6f088f629cf387581c3dab679065d4b4b8b7598bfa8dab796b6d39aab61d1550b54b0b734e3969753178d479604100109996972de361b64991a49b08b79b1cd248f0784c5873c0218e4afa9cf2f43e7e05545546ab6647caba3b06e3055f665756d114f43a2f6cccb3600da6dc3b2c25ce1bcb8bfa5a752a45ebbe0e9acdc6029366620d77bc3eae5c05fd495d72abb6424b9466658d1b6777050be21d119149f8d8fd6c1249189780ec55e2e5bdfe8c7fb58fa2358864729f46ef9a46166881bad1cc2a46df50c9e043cc93baf442b3bc75f0a1e96db3c7e3bd1dc28873b271aaa4914ee9cc4ab1f400b9c801a430dbb8b240f80d82f6c98becd844640e8554359653d2d42c41dbd930f302fc524b7928e13511f3a135b01cefd9a55424396fd36d228a4686f87f69a161085de34d071c201f3b3ba80a1eaa7cc918488d337fda443135ac8ea84c347d1bfd22206b96084a2a4a756d378085f7733f83450333693bcfdf838c62054ffd32c21c79beb678286d0b51574def42003b6ca583f58d5cb95437a0fc2c41d1c3d69a9ee0296b8b12844211828a9e9026f5536e413fabef906fe8182af1c5c811fbdeabe300d6f2358c0bd95a99ad0f7435bb5d59c7792b46aa77c10e5e016670ef4eeee5f37d102bbd764a77179e061d317d7080d626a0aad29f53b8ebaf375933f1b403831d87ad272720c33580ab174de6c961cb644a03f5c22c7a43b13decf8583373ef12ae8a70c40ca0190cf99d077fe09f0452ebe55426792c8201479c8826971ef0bea342e5371612a678dded6a918cc7bd5a0b9a5e6fd6f3e39e0c3b0ea2ca0d8d42004bf6319b02452148c0c22131ad76c26743bab6a5795eeab94fe1d9056c404bdc76d14780d428ce558b97f8228235577bd181a2dc3dc71141bf089d1b8e786213de70a80e5bd0d420faf5f6bf7704b61ba97164e1a4bcded88e2fd28674008cb1356b892e45d402bbad7012915bf76f1a98ce802f8966e74629629a575928d5ae412de5d41ced84ad18bf4eb51c0f017b6c3177678ef9ebcd15ce616bca0ee12a8ae8f599caea89d2eef0b453685e629a488449f0f65be50a454f8ad50c32989d540256300f4b6e580e1854b880c9b137bbdaad06f3464e2bf6f513dce03fd0510715ebc046a8e5777b8a695ba9bad6d6633a21b36b4b0eeb22af91ce04a9dc0d51557d2191f12ff34cf93ea87cd47d756c37db2a81ec4ce307e49dc123aa1f4f741078f6f2aeb43de00adbe2b5d44d0acfbe75a1e76583a0c5c7e365e2d160602ed2316a4070a88c4161fb28b5516059d6aa6a22b9c59c4f3e8c6acfe2e52eaf46317fae1b623425974f7e85414d3a0ea46c41b263af5b22264e19b93b5b7b163085ca418123a2c3f6461a1f3b4a4386ed5a7216cea36b844bbcb7b6ee251c0c930010fa65a6a9073e818c7e41bfbe0e391559f61e1f6e22b87268b0db8dcec5198ab377e5884dfc37156721f92128ec27308f8a0908fa07e823fde2c1dd16af053a1d112a08c565d5dd7b327540d393572d5ad81917ae51b39f1bece4fd01009badefdefc6a8e585083bdb9db266cd89b9abda94aa2bf23e3ac1a8be7c8a2852a33d8bb7c030427a983c8bc8bd8b5d068e4d388e881e59c0356b99e2503452d2b746b73e90f348302d442d45d8880eb95aaa6b9352ac017807247bc9b1a8c50b165d4215c7a37e2b7f3ccf56657eee9ae67dc29631cf22c68a623ec567d0e5367334217d88d8a55040c6efd0991d7c879c20f82e6aae7a843f7146dafe4843a378d06899875514aaa832f6b1010b4bbdda6bb1bb009ac885b1d2015e82d2dc789e8e138c06ececef52748214fa74dad2c9ab24c55e36b32601f0148028cd5df91fc00451201ced4c08c6eb19993a283e636b2a38b49278d866ae920e9c4f16fe7e1df53c27bc23f3d9cf9070fd1ebe56a7bf88ffc38f8749f48d403790785924d6b7f1b048384e5ab4b9d3ca9119ea26a02109e2efd84abec599932d917c5dd98dc0ae5dd552883e8c6e077009b7203dba00a53ad2d8703eae5016a5d901d9ee1f588a827d9e4eb5e241235f8ce57d60a38c2bb0188efce5ef99d3fcc01b107dd40ff4193f82847766bb85b130108866420a54c3386739b34cf9c8a17fc020f61ce8106fff68db26c03330b356bd55ffd62a6fae11c1ba2b9ae984ad3f442cc3a50236786ce28df9ba4cd5d83f106fab5205106a1a395e054d7bf228149a140e71a8f44d5adf6a72f413cefacbfaa7d7d595e400fbb504a505a42041c48a13b85eb4e3278deb36536e32c0f754cb9faba6a16d076176fb11317e8077e361e97ddc6a9687e34d20decb900772d7ca1eb8715c4dd6569f009cfaedf3b810f3dd07400ab03dc69431f2d48c37655f00742d8e1b959f9972fd37e8615c059a315606e8c07495765f6d4bafe8d956fdf6023ce6f3fbebf289ceb9ce40064d78503bc9d26014cc25f43c461857521a695becd8eedb30c9b06cb248cbfe4bafbdb8e879a092932913adee89811103ee65bf36650a5468e0f3b2d504f1bd38744238bda47497b5350a7349b7ac7124ca7a75e165e3edc7f61c8a7b870ea841d1d1baccb90a4a0f50c6169901bae0fb0b112c5594822af8a20a5637eac0513e1ed07ce595c2a1386977a4e4ad207e1f1c0b2bb026699116b1778c837826673e39e11c7a44d9d1814c43abd23c968044d4324e6df216110c932bedfe9ada727e6f862d12b6f06f42a0cc8759408e3488b0831861c5bd33d82e71ac8fab886ee9c5081d1275b1bd6ef8708d587ec29f1a8da6782120c302c6aecdb81d22b0300adfb4d4a625d818c738c29679b384afa926e5ec687fe721682ddb2d2d8b8bbe59c1e163cf1262d976d6690dd1febcbfa9d021010407014adb061a5c6d86c2532f8ef69bfe79ca88ae41a57a8072056182a749726eb75d09c70b7768956bce57b4adcc2ab80efe4a2332f8b314605d531480b9bc51a9487e432576ff8d8650ced370d68c5255285a9a676b8cc10e7842c2efb07fb2b4d7067ec404ca76abbda7717c9db9501284f1a49b158106c99836d4adc48c046e28647f08a0f8cb4221232c1e230437a166ceb21350cae41959014de91274d92b002d2bf889a608ca8fbd5af0ae6ef5e6d5d135900ba4fc0c2f95363e97226202697c3f1e2e16fdb7e384444beb28303c1c291413a43643b1560cfa4be2f7a2262a557458c52033bb6202bb40c8d5fff41e2147515240e6d75f3d1cb1613f80cfd7bf08efd87709537ca7bff4f725424e825633a007a33c8d72d2c3c9e7ea3ce9cae849736ce6468bbeba45238394586779177c7ed39c42f29ca6ed639d24cf8db322a392090a919b76b8ad22757c07bba299712be6248a09c176ef84adfff6c7ee3ff832c9cdfd893838b58baeed7e762da42acea787d7d5e48de889ca8145187f0a8e96dc0a411f8897fbab1dc6d0f8eb9660cea256e61e02f18223e5089745d36f915de2fcdbb53554b4ea8fe1e6f672efef7639100bb71d670b9bd9bc5ea5ec506359197768b01438d43b82435f985da2cdc090cdf46ce477191a48e0da8a730c22a9ca82b6020cd6c0d6d09886a7138a0a3c874f8e4a066ff9bf1c5c8b40a5ef66d1c016c9fee06781e7e78456a7404a40d317fded50d120d6f2ae7b762736608b7573d692d42daf0ccbf14128836fc6be15355a65d4b00730f8d36af26c76d7087fe915ce63857ad1dd5bfe4ac474499ebf5c77b42d83a955714b95ca266511c4a919ede1e4c92ce99d3cae40ee7ef43e56793afb58b5f6b97cbeb1211e63e5f525a1b6f62d9d7568e8c4e5396b1f19bc07179e15e4750380985411f376b3dbc078d9efd89f7181d42f6b02234b4de0f279c3a3ac65f172c204a6bc666324e3485398d8da4e5bdae6790efae72f891730ceaccd73bb17d6fae63fba9d052b6270ed9b6656f0a4a965e38255c447047f40c2bfe488c1a6ce6c60fbfdd47029f64c3cda3367a288cb292ba374a2229d4e04daccf04b43fa9ad6db5677f69dfb111db405d05de7cea443b12bd61077b1d609f305dee7139c06e4d8e3a95d7a74e7051e039f55efb25c20a56d188a427df7aae7c117b900b65ab1def5667a7a0a7f2bc457fd21ebee29f09056bac5d8331d70f97df48af3f3ad627e8933fa3d845800892f41e685f1983d289d407d01ede813f1ad7cc7c8f4142be8b6106874035f7114806b938417d0deaf7d112d4511ce1fb194eac1531331bc06ac3df18e8c7a61abe266a9892bc4c2a8cd1225ea867b5ac14987043a2906c4f3c72499e8b05b767db9741dcf079d60dba789442eba2ee276c6fadcdd9b54330e1c23f91b3a90c193e9c130c9713534a44ff0b00d90c8e094bb2887206408dc61a5549c60e81e62d76878c50360620bbfccab2d3f718dc20a7b43ae445647aacab43bba855c8609e9df3b02c765650db29f1095f69cea93b102e97709d11b465f5f163bd5efa96422ddf3739c15d6b02001670ab94b45ed2077e3355e652a133b01bf8b9ee05ed8a3e43454e1b0964781fd01b541c106f234038471246e9bbb112d26faf02b8a3e0f8ab285fa841375887c7a2a4aa406e18294a84883013e7b3f11fd65aa48e2b80662e87f3cbfa7d85cd3a1e113b840a2bbd7696807ec3db07ead9430989b7da1d39b7046e2ca156b79666382cfebe577f15949ab98434695ba8fbef87a8fc3391e49972466bcf46eabd8423b13320ee5a775a31587a5e41a5a447c0350134b4d7902f10d1d172cd928e1d7b8c16ab99aa470d118b2e3c4369b8aad2c7bdb61cb095a026a7ceb4045cec46f3a82c09108568680c0c594eb83252518ae625f34eac77767fb86bfe86faf8af2aeb3dfaf0aa4743edbc04bd43f480212b5e8c06d616d89d749ad0818bf2a04f9e1aa14a8a718efcc66a5b04934017b112a4bef30eae5f729f6968ba10e68cb11f4a40adc120fccf304849d8d1ef8ad9612dceb12068e4f49267db115c10773ccb2b26e45d04dea31742e23c8b8a200a73082fe7e0746953f9c5c3186b46bacf66641bffc9eca06fa41eb01bea40ad1a4dfd17aa510ecd3571ba26841b069ff34af224700ce7b150409153116b68f789589d409dec1cd98192fd6a0af48f9ac6ce2ec3a4de26ee75893a2f46930e7f07b03235d2c234a185d7b9c58fe58d13e83e6752675a1e3a3c2da9132b5f7e55a593af69b6301cea52bf7d6f008fe769dba07fac9e808d108c2ba752f4116c09fb166c02fa3d0fba63644cff82e58381cf547e703343e14a9680a2aad15a2e1e66c1582b045a317347afa81467e659bdc517863eac777f044b1ea63b2cae433c48cfe49498e989ac9679721e63327d816845bb0bb7f664b7903dab503526f6d24e18646385b785889c0c61787104c21ba18d3342a64d1074d3ae240eeb4bcd517f8235973fad20a64a387bcedc29dd83f502accb831341812a51e62012d4ff3d460f03f07145099396ee6606950e91a09e5a7faa590bbac57104facdf2d5848fce0a06f84c4a9af0ceeffcb28a4e66144bc12171cb66d62a4139321eff9b30da104a1c85538cd838a691f5d9edb9be71cadc69fe3c6d3198346222c0805ee34c7293102dfe88288170cd1efae85e4aac8c858f7c64093228eb67574f0acc13ffeb9029d1deb37e7501400410189d3a4c67d70425e005cf1685b0b69d152bfa9af894f9ab7c15e60b2537f864b37aeb03f9b3f2f79a353f55029a6d9b1a66039ab53d53fd814d21b43b42f7e36a7ca5e3dfb0f31dc64eca037ad53c091d65ef52bb391c31d5c53f7a73af98cc3753b90b0f1e5274d91029c00cf0f1d0def063be2bfc4854ce33be0fad071dfb6c4f4ff67e372dca1af78d013a909949f9ca9aa069a542a8979f25d4a115d7f82c5b9977e5a135bfb1fca5c97badc0562346e9d269c50545bb3166f526a9f1c160956b61797ca9d2dc3261d063ddf66aa8368086dcbdf4c59cd0ed778eeae4dfbaf6a545cecd22f849d89ea144673b1abd2bfd81c8fa77ed962a51a980ec63fabb68b4d7e94ba2ef8474ff93d45b431035efaa9049927c4942d4f69f777e1402c54df2a4531d52da29aa63a6e5bcc7cd1ddba773954ee727105f6154198410f17699af6c4b079d59ef300d810fd90b6ef986e7bf61eccc79c593702e480004fde06fac26297ac2de1e16992dbfe2dff1a8e1d5d0e3ef416a07f898af15f189459692c3e127a694cb21b9db05980028b90b3c2cd16e8ea64fea6d667adbe8dfc323609d18d7bfaefd8a538439d71e68fd486489748d6075f88591ce4225bac8907bcb750942503d9350d4faa4103fdd1cfd9f39f4473887637a577d1854c9178ba30c8b4c49854c7459aad663bd05d3770f5c33c886f9a395bb71ba01d1eec2495cae8f01d9d6879ec471254821e173d2b193a4f1321f3af2c47b5b206ba5ace0360057f06a5ce252ab1480ad9035f5d58ed257bed9972fb20a92f4568b05066c1ee149500323798a26f3132ea5b1f20f76191161f0a18d7c5e9c5534604622e03f955e97bf447fdd9522668a988b10e37ced23597d5e1a1db78045baeafacf6aa42f224317a859bf366198c84d351fa4ceea3fb01bf5139e01c3a51fccafa0f0223c30d18ee2dbab4a6ad60723ef61ff2d1362999e04ef6b2d0eac53bb86e3858e81b9511fc26ac4090a5e0f3991807344ee8c076b25f7706077ed846c08cee490f02b74c3e1db3bfb0bd0514c761e30264746973477abd44e7566412b2b5736d5134483ba6fec687fe258e1f5b33a0886e6917d5cf96ed1aa3f879ba04700d204c90e99c1e1a790134bffd32d3ecaf686dc878b8e716beda618807472251f135123bdbedabdcf8562536fc1febebcbb29ab7263041aadfa510b4fb7b4b567ca1d3e86ec871410c5053e775f35b7442615e4d79681f1fd48928a7760b18a77372957010adb751b8c3522609862e6ff1746252c2b630bd79ff4a15c3507d50239f9e3f9a0a7f47032b50d52bad4f81ec0a517c528b2d4ff5772e70d0eddb24ab4d6789d734e64df70ba97b4f0950a98f8d83c129f1f6e3f8f238aa48a5261253aaa20ba0e184e95074347796eb87e9150089e3fdf2061a209449e5ce5fd476f98f68bdee78281a24fc0e6bc42d04fa3c9d793dbeb34be44752711b0e8d9f57877be8fa08cf9ebdd07c1d799a10d01e58fa9890e1089cf8323842ba0cc6f14c6ed111d2954e722c31d12e170181f6231033acc44d35546b5cefd4bc950ab68aad07166d41d22908fb8545c3600ae26d4e41aae7b7da8b5a228acc858330425ae4a8c5a17ab55f08d80ac63d5334d2e84ef3716210b3f1157108057354db868345b6a4f648de524cf444f192b58009a1e8ae4e69eceaaa01f60cb83bcc109905d619f8ff52ba83f9b527c83a7d9e2bcfc61b0840198e45175d5f17925c9449cf19d42864e4839bdf683a11f1f5452415f78ab151e412911e6ad4ac96a08473b1517bff763815b3b1684bb3c8ec4e65a63587ee50cb8492b67f7dfa3259d8e18b4008563c0f31a0c9065b12091576fd7f1a18a52b62d6ab4d9e1c3bff10dcf822ddb0f85268b66e67abd079c190e2f4cb3a0fdb0c2826102de806b33fae2027f2f697b064b594165b3909deadc2545c0b710b985640adff85c96ea25a13ebcf751825500cba7740f35c128faf7c2944190831a36a5439f0330b6e3b25622c4110570a2387a09c3a540e53410c3eaa8d3a8189477b75259fb66cb4bceadc8231214d36e7ade98d972c401731c932b6cec9b999874cdfb30e647748a7400919a542c1ca8ffb97489f20ef5011d81842db6b0f2081d41b8e74584555b255edbdaed78e0b6284b0be10b48048a27f187e574538cbb588b31d6b3bfde32aa96b4c13c9945cdeb04b339ff836e8e2689e5f44b52c6263f78f987537262691bca385f161493a3738b6850a342852517e2b90dc337cb871bea077839ff63a6d6bec7114f2c3de0a46425c3e22837895ddd230d8c1781a4c64aec51bcc510b2789dfcb9a96f078a45c84b8f53a0c39fb54da4216f60ce70d65c0d065fa8e28ca87f46b1b9ac4e41cfb5e535fb1dc5df7085b1332d3ac0aa244411b14ca75f5e0ef10107183052feacbc5cd500d59fac2a24d04416390470c5d8b4d3b22c7355b4a76cd206954ab94755a6757d143cd3ebe2d2db85b6cb1633492ad8e1ffa3c5c1b409a9cad893ad01ba58ce1001aa4882353709851377fb7d6ca63f4d5f8ea166fd222f2af9a78192b89b52f4b5d4d84d360c9f5bd43a13e487450db116c9fc5c5c4e3624da965e6b5ef90b59504f15560d9f10a6c8a6b5ddfd7edf706b564fd624b9949a60d0215024702660e7feefcd598daac56a156f4d9685f7d8eae0a5fef49141786b94fc5bd9f63ad47e28f7c42edaaf75bfd8afa5dbbc8751cd79cefd7f67b56b7fbbdb7ab6775bb3507c5f7b5874d3b7d6f57cfea76ab668da94d2ac5798bb3cef524d2bf99c3acd13d3d45d7b9318adc003067a5e4903b00e6a894eca4d791351ab9eeacb350fb84d784d52541720b2871e00b7f1261d573c53428920b437ff43ea4a33568ede719bac28de54845b9303c05bd7db4868f7e53ede74be9306cd7e6d879fadfea57ddfadab6f441c55c850a60faef6f70ffffff7fceffbc1eef7f1e8fff2d8f67753b1edd6afdfb5eb73746d973cce6ce4c1f379667e6ad574396643f4b9c49439944efe7eabfbfc1fdffffff39fff37abcff793cfeb73c9ed5ed7874ab5d66f7dde71969b3f98f69cc1a4d5c1a1305b326cfc85acfb350ebe3ce4a21250e8769cc15c8a5318988cc9a9159d3cb5ef6bee699ee9dab47751dbda146c85a9ea138ac248e1f640dadf1f3b57986da2885a0b5129767a928447a564c93aa02b55181ee68d115da5f4f726790dc17be5e8eb1ba1c3bdb1cc3e707f9ef6f70ffffff7fceffbc1eef7f1e8fff2d8f67753b1edb4d8f5a8f205c3b53d80c705569668761d34e7ffa512fcf4e3a6c3e1583fff42ae6a19efbbeb7dfb3badd5fd79cefd7f67b56b7fbbde756dfdbd5b3baddda73abefedea59dd6eedb9d5f776f5ac6eb7fad4dbf2810661843770a20a810757e6e67c65319f988abef7debc0681ad20d01a0466cd3914857428abd920175f39efdb65385e46977b75cb07abb85c977afb6431cd19ab2eb228430ce32628bba5d2ae490acb5c91462adabdf796f4c5c149e5fcc24199c4f0645269f7de9b429d26a472cea8a6dd7baf5649e16d50dc4146a07d237e3ee24dbd2d56c95b3b6471a539e7d0b662dba8edf27db3411e8a3a720e6d3ab076195f34edde7b5f21189d412f214284f85e381bbc38b2abda89094599e6622886a18c3649d9200f6932543636c83ffc859355461733f8850b181c883bc8e52f48042ecf3767182f5cccc8c862623098178c02984c5199b033d639e7101f6185c0b1b91dce0d2677099d0ab24cdc54d095415663f86c3d6cadd6add62915ca42ad465348aba88cb931b7daa050a228fe3c8669d46ff57ded3746ce981b7363ae45da481ee6cdd4e15c4f9d524889d3bd5093518752d0ac29bbe9c3bc8d3bef75ddf7ae33699556999c66da3d5808fa84bce7d89a63381d373f76dc9828d5fba9283cd5c98599e5d9fb3ec77edfafab74afaad4cc954aa55ff77d35a6362a9cea475785fcaffb8efaa326b56808682dcacfd7d3b55f89dfeafffaef8c2ec748bf29ead89a6a598bfceafdfab5fe5a6b57e8234a5571ea9c3bbfd6ff94f56f0c4fd6c81c7e0ce9767880d3fbee755dff31b569b56e3af4733d897433c76fa247d66c6c3820bd1eb9963894a75de81765dd75c8dd300d6a248a8a7da7aff77501a653e98422a152a3146aa2aa52b5da2b164bf681d997ead435ba5a442d2e219717d0cb4be505f3818189b058188bc931320c82604a8a11948138c7e4307641d005de19118b1f988fca4b05f4020ab984442da2d135ea54939c5c69891d842b2cac1283cdb257e28d8925067b97aad244cd516a4442ed08545036482a9d4aa7e9349da653e98422a152a3146aa2aa52b5da2b160babb542da2df26f9eead435ba5a442d2e219717d0cb4be505f3818189b058188bc931322c930965643232d90c8c730670cb28c2c3086b56f49c332a4db73b54915f2446f6052e24d103880a282021c287871432a8e28a2a8aa2288a4cb40144e0d022c2fb19863cf1392011410d613886800200e8068c4f6787e8e160000bdc3eb1a27ad92438294ef8f3f99472e00029b5d82eea65718c18b580738508fb44c28ebd92c1b4b15fea6589e094b71d532f4be48f46b041fa61a7ea65737ee0728e309bd830ea6573a48c96ec560d5b14e925198a30b1a7280285a4c446dd28d1b06136438030a2bc0108294639e8944012a2c3c3c94ea997d5c921b1a0c3c45ca2630549ca669550e6d8a41e7e972b147b46bd6c477244c7c23cb2cd1aa58f8dbe3052b24f41f66fb3d4cb1a516246d92bf5b246a628996c558d12093da8388243c49125371ce19940ec52bdec911e9b204820adb055ea65839881c4ee967ad92070600e24b9350140bd6cce0635542f5b441bf238e710c45ac414a8721bbc3c8738a4c959bc6208de9c2fda006c02d00b22fdc40669a09c75688b6660917a00e6613449d92a291b7ca1e61cdeeb420d739e516f3d3d6aec744dda1476685c27072cc0c42f67dda1061c2106176a3c089c3c4901c4d598f2fb0ebb53819311857db9cf3a74c1b379088e2e1aa8cae0a9b4f06601d8535b3eec0f5669a1005b6cf07f605369993320f29b13c85cc502b0a77e5c32421e866b786bd721320fdd120fe6074035db50a3a447c5393004b30dd3d0c29a1e98e6d3230c6fe10e3f15f31087694e15f3b00d797806d610de609acbb23ed1c62ab9a1d2429d8a9bd0c29c8a790866916400ab68906c005433c7a4022c1238d1539367618d4c80450d6bd85653b55051592cb1a24795f1edf886695e9cb069b78f07e459ca315f8086067926e223c724c72b9c85630edef26c735c72ccc135cf4c8e39d849257e726c3aa1f22c85573ce42c8e790579d6e29ca73c6da5ac749566ae4a3347334fa14ea5f4e61829f39199779a394bda2353519a412eda073a545ae616803d8d336f5b9dcefbded715c4e19a8c39d67109b898e3da0ee43d017bf04cf75aad56c20cccc129bf3be3b2b91c0cdee01d7abc9de112590cc3dce672638364089a815c5846945bb8863715f64981f0c1a51d19508663722c8489309f97ca0bc825d422728da9e6646b655f57be2c96d55695686a84229d4aa6f334954e24d42865a22caa1532ebd6c84569c8056a5171f9bc88af1026c3702c0463ae6c8506822a130228cb31398c81a2f85379a9805e40219790a84534ba469d6a92932badd083708585b569ec4d63ef52559aa8394a89e2af742a9da6d3740689bca804cb75ca96d188200003190000c23014c59128c9d11ce894071400144a60505c54309c47a481582408e23808a11806401886010000821800aaa8625204f073b99f25f659e99ff5feacabff2c6b41efb31443e3feac82e1d47e634d3e4157188fce5c0a6a87c2e4935b61f7d820f73a40b91b76f559585be0c6ca1afb2cf4cf7297b3e83f6befb36ecfa2c7286e8691955b819225b751ec8067d83ef7e9b81b965a3883b10229ebaeb3ea3f4b8f65f90df24c3f2bddb3dc9e15546b35fb049d61c8722b3e9fa87b61e6b23d011f4b69911e791852457cb296bb064746562899f4ae2fc4a7cb3724b664c87755b44b37937bb67eed99fb6c0f4fa0b929e4c90a49ef610afa0e858ec10ab7d1ec0970005c792ae9717a39d154b22e5639129c797139f44bc987eff6e3e6faa848043d909df57ee3bda299990b8a13a89758f6add6b6d4847341c809721052b5410102e49c31a8c279ed209ae90eb0744d0c8f3649c659541519cdb1ab85c2a37a907bf6758a1370507162ee6b52df2adda593f5a47147d8b5a4faa741407e674eae16522444cb8ab88e6e4b92bba65d206895d8d48c4db0ab13e61ba543981d360e18ef3624630566fc3da50e58bd704bbaa88b900d20e1ad8ddc424411726e49ff0da50c170df0a34bcf4d4ef699ce91f67867df31aac00df7514f5a330e708919c9737e500f412cd60d312b5eb11055d0b611ed5c6e0d026d89f2447abdfe44480e8eaf252b7adab16ac10866567d03a1183aaffa1eeecdbb19df785f95280f58bebf4f7b2439fa89cc3d498703f61d33fdb3dbc735d0e34017b1f9ba8001715947d1f07810d8ce0911dc9cdb40b9f3aef732caa3d2951d496abae9179755483f0a9f518207ea7cec31ddfd55a2e18f2827a076f2680a8d3fdc7009bbec40d7abefe7e91e9cf730bf96698723014b33fa7068773630113720f651ff385b15fae75e8f25e2ab811c8447cee128c4b69a47ccc8fa47164f9ad99d51ca1a4a83ef5c1fdc17460076643dd230ba4814cc9f2f71980a2b20049158aa9b6c268ddebb51512509121e9eec274001b5cf557a6f533af6ce213c084af1c5a87dbecc9773ec7693d3e78820daa40dcfc2cc10a9b54a905bc5a7ab2906200d09b12c4f206a491bf84d3068228db2bd09ddf90884ab413d624b88b459a3f3188abbe04d7ebb70b3c6f0eb31fb30e02ded55f8ac96ebf4eaa8f76e603d5419fb92ce670cce2ddd38529f16a728da8331388da67aa39d1b794108248670ace17d9455ec8014741b9a9f27ca8e8a96cd6c31412b087b5bf9d76dbab519e47c57987087510080e1df2baee809e2ebdf659912fc455c7ced439663c051769f237538166259bef75b49bac1d731ac8fb550223e9bb237318d11c3b875ec114ee4266de1171ccb4d8cb414e6d7ded92c77e0b229be3e42164198da8426adf0f2882c8230d5362a663267c9e9c714aabec7492067d4f3a895232454c0cfc547cd623e1c26e3b841d4dcbfbb1d39c52c8238771ba121c11eeba306420fceec5e2b875925079a2b300ad3d4fca846125c49c1d416a1e462ca263469859747641184299bc00d6a3536ea2117fa3ae19818c4cb3e899720aee5905d3087df33e415c6b99bd8d68ebfcf9857107336a14d2bfcc4c75448f82d96d48cc6add6e6a460c25282a5f6ccd2ba63ee450a16e0ec415d30db22c56ce1998c7e1f30a2d1c40103bfb53f52caf2cf0d7d3b585d9df589c900d3b5032a0309d544bf8b502d99ea927e932d19d9d80dfa1c25d85339d7038b671a64c8f3fffbad2a3ecfa89fd8f8b4a57da6a577653c81b1ab19c1cac63385bc5d88ffcf129495fef7b46cf81f23a4e635fb83b840147397fff4ed7daf8bcf33a38ee5f1391e26862320479e7fefeb75f138a3dec4c6a797f6322dfd959ddf7fefb76a16373b9b517a88502f5bb483c925b6bbb2da1326e001e571f3bcae94c23194f2038d4e199a4b547247723a7b5e574bb8704d66ad9901fa8e6a91c2d49912cfa8919d4ce6adcd955a5354113fddcc89618c8c90006f9f4cbc88662db718d13c403fa9618f189da1c57b984bd97ae8fee01639fab814baa6ea01a41492664ee3586faba53355014000f00400eaf0500e0762305ccb0e57169fe279c5142cb5666e4d37e3402ca18e8253cfc5c8650a73849f9fac9779581aeadadaa419ded0682a6a00e60d4539cc732a5e30942caf6472b29c1efb76484d96ad0c10d68a4012641a008a21bfc80092ee17161e3b6137723085ad97086d0bcdbf18050396475201983c15f9482a2c643a15adfa68492a81a93150644038028000e00900d4e1a11c0ec460b8960186f033de5ce12e27fab0b51607d2895a407b903646b5eb388a65d1cf4f2d14e4b5844ed73418af6eacc7fa56f277a040cea06921deb4954d5cb45df152698a7d2be1a542c710557f85a6ad79fc521dbbd39aeec024f655f6b9d45408cc632ec9b7ed08194ab12820f2deadc10f5decca8482549961ed65b251cdc95704fcbebbe8ca875878a95bcd7db0a5cab940a111a8d8ced2931279b04a8a13082d27962a35f3304d97be057835157a3fd92c104f13f300654bf066c61bb3eb92df08a3e43b4de79211b0f01e14bea4e9a421ce4909a00f2f0fb329db19a85235e6e4fd25b55ccf0826e8d8cc7386613715830cdf6b517c6f1d066aa0e51d58e06440736dc87a62ead5058b16cc37a62dd0638aa315e25ece9ebd1e54d7746b00aca9f1a0d478a3a263fd2152d862c228fe0bee0f2af6b953e1b9dba8baaf93122ea6339c7b1b710bec055620d26cb1c8c6e01a0eb000a10f361f74e3bd0adbf060c101d8df84c67d3002406cfe93add5024194014efa20001ba688fd566ac4bf154280e27fa7c38b4424c59f9495bb7e37175cffb671aa9e0f16eb53704a0035f129190cc1c9e9f8e050dda4d01cdf8cad4be4e8f442406237bd676a6ec41d1128da561dc28fb3a272f26671ad888ec451c0676417e0e57e04bc9cb9bae1802740a370063ba09fdf321eb2d1594902f6802aa88792647b8d249d8dfbc0cd00d7b16e3ccf9f583c391c393e60b0646c7c61cebe7012bdab8cf73bde8cd24024d625a46a3c50b7143ae1c158bb8a3f4ff3bfa802ea2e67243749b612da2a13a0d5aa08ab095b1526439bdcde6435147bbf7e8b4894b89f1cd4e233944e20e6c4f15a425ec05f2cfd9b276440941fdd8f10dd1b2e4339d9403593db61500dfe6e1f23a16a204c186fcaef47d38e60c0a0b53411311e7a3d450bb9cff6bceeea0ac35e63d04b4cc14fd4b09f21eb7383e9f34a2d568d5e08c2cfe8194dabd06911537d0777987dda7e2c10ea497c221a7f03d733866b3fa98a5701b1e6105dd7e78e019a3f9328f98298f4972106b88f519c488aeb390011085ef2281d16a65e248c288417b3fc03929301359ea22101a6651ee0d2a4ff37d2ccf00d885b17673199d6df2883d521e5aa9824a726c76899d8c1805df0c53f79fe375d205bf9273326211352aa2d7d9f44e89a84d77419d0f02ba7df69ba57342887ad129e7ede51d32eba5fd2ff0f5e00975958fca5136d0e80236fe2e53185faec9797445ac8255ba4b4e7775e18835fa4c85426311c645a831a4de9baec4f9af240e39a03726f605bed660c0d485b9d8fbfb14496f2d3c1f6f88f54eb5ddd112f47c09235ce7620900325f94a369a4be51837c8f12fe6388aaf438e668168b60a803a019c46b1300afe7d35e69370c8960fa302468b9310a257d51d17d02cc7b444793db54290ff4dda2cbd2e75a51f80d2283529ffeede9a2be23fbbc3873887b1d319872b0c2dc04fc3fb3e867186d5b813447b22ce74cad0dcd23749d742b66fb64ea3a02b6614ab79e3a1f50dd425e94e3385106621d43b378ba161a9d10ab30aeb65fdaf4063efc3a150005afaf8335b5a5628b40c59bdf1e07be612de1efcae842e1356f8713424c412a5b7cfdc644c361e6dbc97ff612866d28a93bc6fe7f8c5d183de1e3300d36fdc35332d73174d007f6e99df3e2d57c85da6bb98630234156d6f71d65b4de7741fb720661eab47a1ceaa0d8e41496278065aa010d53f65f40fb382d028fe6e886d561cc613fae6bd25f3c9770e503732bd26fe3d4dcfe0f5c560bc0d5e6c03b1cf802cb1e6606dff0854ba441634d5c52222c261120b79c85b149767128564600702af15d2d26dfd427d8e3b86d726501d3b51dca405eff10fa68820c8bbdc7e6865527b9a52a656179701cd20436631ba3c2d586ed6e9ba3d197f93fb9675112b88367128ba72b3011254eefb44e85d2bb7e9d789990593c65b3712a88c9faba86df71921490f54b9596fbf2d13da30eec83da707c7a534665fe6acf0015f4a1e75085708628ca72d2f626729d8db9c9de6616d6188e66b3933347d740516306d25b908a93d850005dc46c5adb75281c9634da958c96cdcb275bc0ba34ee6901bd49dd33735be09ccf6131cc352f293c67af564cae86e6f61c4dc4aa06c0171588ac62311743b2e7412495e5cff92bb214b79a29eab1012b3598da1883b225077e9b15033dd854dd659d9e7a56d3a9a842214f01cea8517e6af79316b20fdea939aad24638dd20f959f8c8f5220b780699faa61b15401202a562577dae8ad3885e84f8d64997142f53d59b34b0053b9180d4cdb91d7f692eb585a758aec6990d711ff31dd459d723ce2c2bd1b822de3730ce7d32911471dd892f2a19918a92c19ffe38fe2a54e2da9d0a1e6b2651511d49a602acf2310f66caabacf9fac0f5124b6c638c9a4944d39262169df4564998943842983e9f02f047d34f1dfe2189ea8782e09e2ab451247b594a4f9ef8826d2a837d207590924d72c4d1d0e25f6372e2630dace566e75bf0a919738e324a4b6e3a0ec19989480350da41b954a12921fc184e1b28fb027411bcbf3e000ec68ae4ed7f5664948c914f28c465ea6165f7c58183c9a9a1ee03edcb4bf1f0a3d24b6e1460ae2ed58bf22e3768c66917a465de49e4f9422e273dea03ea6ed06193f2605a6f95d343dc0d47d186e237348bee22fe0caeaa50b1437a1688477018abca869d6ff4933cadc22a2d869d624ae0cdc6712d34d2765c93768ada51ff9def9826d7cf123ffa83b1df6dd114525147307cf0b99f42cf8286a6fd33d951051b75f62c1699e454706466d88caa8f0e21c16dd747a0b0cd894287efd1c7a200a477951a507df43743f59ea1cd7a167baefce5c780899fb657cfe9cb53edb8543e20b05ea151fced431ef3fc79bd58164030935d85b4f778eed3a9f64d623176654ca6acb8eca10115da0befef1686133c7299e9f3cddcaa28e159e892c50352fe31d4fe2acb09cc80c01ca9c6c814a5498d0c681835ae33ccb02553bb8f9d3aa8069997e1ae9cb397fbad08005ca5cc7f5f4bcc8febb6be24ab8b98d6f1e37e2c505d80e576635f0eb4f854735facbdc1b3a9cd54db525ef9477b7c875c07a77222774683213ea4f3260b9c696566cb7788344fda9e21185a3353a9bdbe644722a1b338ce685fe245d47323a90f2bfcec6ac3fb9837a36f8dd7f1fe3cf2bf021fda97e0c5ca3ab65bbb6eb8e64ddb1dd7a53004d8bad4d108c7479b462ec3227a6b49ef924cfbd11550f102b116f0893410203ae04f81ba4ee8e5230067908119ede282d723145a4d481852aacc9fe1987ff01e61a98224af8d011131614c595e839259401954d619546899aef6c3da75af2df94db59659a26823135ef4d9e53fd3dc3e663e42bba19869caec9c8d05132adf4c873da8104de1ae07f05fb4b2cdabb9789a782ac01de833ad061feb31ba555bcc84ea251cf69c777f15475c19782e484cd7b1a5fb5070ade3c76bafd6753e0b4d35fb4c19a1b527dd81bd24f1b0151728153f0bb71bb8611b201c3070ecd54133fb149e08d44553d2963ba1331cea40f096b32e70095dc4001d68c97f46c63aa5e1b56fedf2db182923906ec4c0ab42fc191030e2361cc2a4cc89ecc0796c55185118a3cc9bb8d8a8f1be34d8121eb58f3a5e6e2fdac780eb4974f983bec3302884fd632207fb7096bbb0d170c527f1f3d9ff043404d4aa5f17fdcea644df84d21990d2746950522b94d8c4b68031f4e18d276185c7d4d9e666153b9bd0c82802b3c9a08753279706509f2409e5effc6d114546a8ac3019cbba46bc4366060b91b8fbdd22661537acee98df14753d50e5b8f973a2fc5eca63c1ef4c108198290c2d578c6238fa6a78907c00d9164e8755b7fd4ab2c7e9b0c4cc5e4049176e7272b0796c10cf89c4341d628ecc0fc3bb27b5d7955793b8311458a33930531b652701d24dba22fce50a8915a33a5c643288c671b5184c616e686c6e9a04e80a6782a65f84bbbbf7b39cf08a6eba1257da6e2185efa0041aef0e499ece72246705f89bf2d71108ff98f397a2a4d227f29509fc69a253fd74a76979597c4cea9dad6fcc99fbb81fb35700fabddd55438addedca1ae20b2fe6bcf089c2966f21267b81ecd46156969fc5fa46dbe5b9eb6c494fadd46d4a4836b5844f69d0c398ba15023a546aa868750986733b20ccd2ccc09ccd1419d00cdc88c8948d9c52a96cde412f95431d4071a3be526322210f59cea70bd9a206190b1ec6d6b335922cfe4081c8f3f4bbef06057a02a559e824e99d8378d21b578a392d1156b7f41bf6b335588aaa5e4298a12919f8dd123f5b1561e612841e4cc8e2441c87d531f9524b53b7b88590cee5589ca9393527d1d99cea25325550a0cfcf43683fd748ec8bcc8bc90cd3d0c584120194e30622883719396a3f0902403209140527a00250b7102b15f01a703e6dfb815fab06d8573f43bda38969560beda3df42d29248ac7ee18a49864de6ffe81c0d3f83eedabb6bec87a3ae80be2d01452d86d547d5c886a12512a6b5ce88ea58ca41141296e310e2508a291512967310e2e69ed492429f5ba866f56354bd27323094aec9b010a0a053a6050ca41e3069ae9b91f0d2df454b9cac393b35fcf12a408d7c30b6ec8e95eb450bb8e93c6e28e59acd003c277f44e7f309200089270751600476002618ae11ce7386bd37305085a96f954135dca1ea1768981590ae05146a614d9253ba594520a6d0394039f032e5cb08cb8dfdc8bfe467990d5d3888b08263059ddefd0ce53710fcf50615f8a7bae2bbdd535dcc3bdb6e7e3a3e1c4fe8665124c9027a0005340ab00fbc0bd1bcb98c7adf5b6b72dfcdc9e462ae8b49f998fac87e60224f39092a4a4a41c3a6ad4a88123870de61e8b1eaff40f6cbc297aaafee767ee2387dc877d57e896beacf4f4e451281ae5103a9208b66c2107044def6dc3a336d0d96c46e3a298c4933c0dfbead8b95e8f61d0e9743a2174ba5c2e97cbe5f6de3939688b2466198dad7387e97558d1630a685f84ed28515040fb1b96c362599dc3ccd19c73be330f9645010318f7d8dd238a4a38c618176157e210048c3590c35803b9f36c85409b6d869996dd174eddc7dcd8b33d7aee53d78888a036bc6d5796718f4a64e3e0b4d96c428e64e2dcb3aa75ad25c4f9356cdf4b81994f5156653831ce332dbb50a7d6b0565667bb6717e95805f9c985b2813a553e137950d08062a04150b481731c677befa1cf078d1a47435608cb830a25dc6acc1d44004ee9f1c4023d2a500505128ef06eae3f4f14f5616518e3dbc379c4d84a1d7f3e520787a2349acd66e6741ecbe575ac9563b0117ed4372eec4b8dcc0ccaa233342550c772ea3b6f31b8322907dd64e0628e62d81c84358998bddafe9b58e1d4a004fe0cb44e0a67f6a6cee665715e025f386f31b8affdadbcc5e052d038f3eac66130dfe23f5de34060d3c7d777796f7cb9dc9cbe35d3defb8816d6e2745e0e4e6747c551ff168393096619a89f5534c5260ff7fcf41748d331ecc92bcb3e39e80618c341d30fc6679691ccf05fdcc2fa3724ab19037fdf47c979c3bf8ea79a88e4a0191c8585b80903f3f8b14fc7b43f6b60372c2401fbd1a0b01b96fa9b48fe3330bc94550d83f1327e9966c6df348f8606f59a978374c8fc1a1e41a8978eec3450376928edd3437ef634e8ccbd4138f7c9c740ad8f7e89a3ae90e8d5248f8fd02c27d59d62fb61202e2ffdc6087f5b4e7fd9cb5ef6b2972dd2341b4cf752bd94d5ec6552ad43f3b26a82c7a9613c8b97cf1e06366e2c17274b99eea95d756559eae79674031991eedf1e92ee977437a53bb8851b6a47a5fb49ba7159cd4739967dd2a874de4075fcec759416ea981eea589594d4389e278a7aafe2df6f99e64fa6f88fe98df257a9e8d39b54bdab6ab3d96c36d5a32766a5f24765987a797c62aa1cd33c170fd5335c19ad4056c2bba676c7c344f211901b361bf96fb0c9d28719a24248858a5e433f2f301e355141684888e5cda18ed3eb2f8b5f59be3227449c70d0644a93274f1ffff18421a2a1a12541fd6f7049d3fe371855e58956101129e9059b44406cda28c678c50a9611bfb22b53b20b3a71e167dfa37ea58fe684e7644742c67983514affdf6054d2e757e8a22cfad0d0d0100b16324c56ac58b1a2458b162ca3162d584657967d0b960bfc8b9864f99bbc237abd007242a118dcfc07df42a4cd7ff0cd37d2e63fa0726cddd6e9b4d66dddd6e9469861efbda9dcc06e1a8c7d1fffd81ffb637feccf0985241b48f64a1cc531971bc5205641ecdc46b28398a103549c9cb0d8b0b1d9ede4e474c3af0792edc4ee1edb89dd3dc4511c5722942dc289fde8139db638ecb19dd8dd636f91dd620f2428e472b95c2e972301cb0dbe9d58be9d38df2cdf4e54b0006d383939e11eeefdb0f9e69b6fbe3710bb0812eea9e963784f4b4d608c9198909890989098b416e680c007507c8b5bd4e9c421f6105cb73787da7c081970002218ac4a4ada9b236d1e3c72a408d30f28be85489bffe05b88b4f90f51e41b76c5e0e63ff816226dfe836fbe45a4cdc51f5039b66eeb745aebb66eeb74bb2adde642a4cd837b73a4cd834054c590140c06b11831826ab3b7b84700d7706f2c815c5909443830a6025c72de7a8bb3de7b73ceb917592ef68ae562244bb3b346b49c2e2f30b48ef6b697706be270c7cf3d0717872fac01e4b5c9d55f20f8b0af9b1e96bf9da6a7a9981ac07b5a6a2285f1c0706238396a4e89203b3e76a6848e8e521f518faad7f65d46706f66a86b781ccf13457bbd9b382c3fee85a0b37399f47627b60387c7b31135df2bd5680108207b592d62a4d98001553c3c26521e9a166102073949df5b5acda4f93d12fbb8b5de9a30f4e6df70ef9421c8cf7d97d5191d643e20bc58f63543e533b399d15cb49a9f13246e1a43efb0206ad435337d110110100af406458a2099a05a8c2b58b3a90802e30336f556c75c4dbed577d9055121b4e385d7db2bf3f1704e0011ad70419162058b73d758d05ab46c1cb457a4ef6d8611870220b708c5a6a217b5d8039c746b788795c42166fff52e7708ebf02ce35e0ff7b08e07cb8205cb887b165e489f47ad217178336d8e7c595d1ae221bcc29df1b8b20c05f74e5f8ba21d9dc7732529a27d8ef46fb887f381abc1d1fe954441a311d96c2c584500a041d0a39a10f4d5e96259de1bd10260e21e8a7b29f6f95c919d70626f4260d425e849ae5d7619e92dd083aed477596d03ae1a9b6b5323012a1cbcd5b4b171bdeeab063bf999c05bcd57cfe98c55a73356f3e6e6e5f2d79fd9041286b0abe97d2b75d9a042b0b79a69d7298ec23264b7ea1a1e885a4d9caed39c0353d36ae6749d92547a54ad668912d909d207bf1c1d1daccb409454899d1d221fe8c0a783d551c8841b7a40dc8e4e714e31c75dd9f65d598c65b47ac07084d5c0d01bd488fed6a08303c375c6aa733a963e72580323b320c214e0e2fe98effbd817694e444eefaab92f01f86bc07d9fc36e0e107e195c651971d8c5b979d9b86a4cd3e45bf3b486e4d0ae39bdeb8cfd009dbd2f6fde5db9d572cd9e844fc271244b9e1e63a93b9cff76bbf9af6cafad6c75ed5cc14ade2e5b9beaf282736e13a68219a2dfbb057fbe5b9dc74bb7e7de7c6119f193f7983e8e322f21426c5097111a12352ed4e62573b37fcadb1defb539845204ae34b639845204ecb3afe4b910ff86711e5f812f711f5fe22b7c8c2b7d62d9964a7c4984f11ec771c9394b6071b5d2e93c31af5c5a1e6db978746c8db07375dbff9b3b2cf29a1a6ffc79ba47acfc981a5989e98dabbd6d794cf4c87cb637c132e23c983c73ad6c5b947bdeb6c0f376661a5bb642eca97f79abf27634213ef6b7b2d5b0a95fa666b9f4cf1c9f9f3dbf91674fe7cd8fb29f7d8ac379737ddcf6fc7c23d7c61cc4f333d7f1b38bef72508c9fc840d8c879dbdf47d66362d6d2ae720a0e0883688050f455117dbd1288b106e7c5000a3f19c01a267c54e322c29b99862461f2fd9ba485debf8d49987aff2661dafddbfe99e983eff26f920b64f998b3b013524ef262a8e158c53c01e5c4300a8a45479ce9ca0167bdb9b81ac9d2ecac11f8babcb8bcec92fa0b0b63fc0273009309066db1f6dead9818991819254d323332334ab2cca03328e7600411280d4a23228d66076848d09058f281922823891a1235bf254b4b6e2c1901edbdf71ad79227238679a1a5a5a5c5e635be6e5e372d31e41cb5e0cd5e8b89d2185c92e5c6df78263b26bd8dc2c0c0c0f8f4c96e658989898949614ca69842ccccccccc070c62e858686860627c7494d4d4d4d4e09f209239141674767274ac798349e3e76facdcdcdcd8e3a6e1e6a4c8d19d929c43a4e4bf8685671707070784c942851a284899ee06e1902b3a6643e321fa82c50533f2553a2a28c3d8acfcc67368589d3c86232a3cd68bbeacc00ed87f613958577fe9cf839a1046a65036977703e9d003a61026dde09840208484a6c42b33a9bcd6628502c9932fefcfcfca448b1e437b2a66073879aad5623973a8e97233615013b58bf76cf8379736e5ab8a471fa460ebae529dd3bd2383607c9689f06a293744b964d992a6799fa4b1ad74f8dcb41471aa793344e0bb1f8eed0dc00b318c4c841b855ba21030116f45ec0b8a0c895836e77a86e1444fd244b1e0383de61318632eef0ef715fdfea07f3055996649973ce3973929324274b7e018c171d8605305ee420b62f0ee43ed3e45244383007e12fc3a73815cf926bd70a8f07b9902c7f40f8901ce4f3730fbf6ffad29bb963d6b87f5786661567507ad3df4a6f6eee6f63c9819cd6c753b5115d2a5f8b2c39300711d9ae2bc35ef4636ac276745f96b9ec300e1cd23def7ed5d3ce474ec2ceacf6d5b87b99c70fcc6bde2e05f84bd22c49d324733b944265966404158ce379a2e8d5365acee86fa447b3ca928084ddbb5d0810650839f6ab5dc61a190c8021833bc220e07af0fdec6394e408c1a8a63bab3b58bfb2fc985778454b8f585ee757168c05d2934841631c61991c4958ec0a5dd2b35218a351697ad284e528c1d89561df32f388e5f5f47a7a3dbd9e5e4fafa7d7d3ebe9f5f47a7a3dbd9eb6dff7defbc3d5576bacf1355d449cdbdff80eb68d805c38d92bdb5d21f3afa47e96f9f966cfdb2b74c52d8a9cf3587be894638174ca1d11f9dee5a09cb50fbfe48940ec763b24392a41296c304a8f223b1f8218af5761c34652528dbd7a0ccc7b6f947f7d06ce5839f1c537aa2e141fb5d67bdb08b94d7b1477705929809973367767f638c689cfe2dfd4ecc7eccfec3d8df6e457986fce7750a4a10617e201e7ad53d7aecf037d470e538173ce5b3eaee4f8d89fc12b3ba4f36c5961e10a082ef01882340941b72e56723bcb4fe8851d4a3624f9546822c62004288aa2288a220c4520e0ab4cfd9ba7a28948d9061c130ece3358e58795950ebef62d94562549950f14c15db82c11e67b56833c3cf144241981ae1de561ceee67ef8b5e1c75281ef8d95f906b98062e188525c520ddc3f731e238cd40f43dab22cc8be6e83b89a288b3f4254c2557beff7437c159025438b26ed5acf98722bc75c69ad3192b962a52ab39769d6e283c44ad26e9036f35cbaed3adc394a8d534bb4e3194232b00d77d8294e16ab2ba4e310e138032b59a23ba4ef31086dd6ab6749de61d4ca85acdf3cc51ae00757ad7dc825d46fd82aeea0452c2436a3561ba4ef3ae06a7a83537d9416abd35744038b5e6274fb8354749a169cd1b80f25b3307a89a569344d769d68146d48a9d503549ada62b9038a854ec9c8aa963030000802200e316000020100a864442498cc228946c730f14800d597440685a3692c943a13820863110033114c3500c08500c8331cc38a39052790b06ef7603c01189de3639f212fdb5dc99e0418fba4407b7b7da5f49f0ad1c3216c30ca8372cfcc5293f042cf120ecafd1298e0c37e38be34b145e988f1a261dfde866cbce9d510ef9944592345140e2c2b2d67882ffed0871468ebc3f1d4e52ebe59e1155df5495e284a8104f74975fc0a1c3ff5363facb2b48814e9e0265ce73267a61383036da3097386e4cf603fe9a8426c620f88bfcef64c038e0ed0c10ca4da507da3eb5055dab9565b2d06eb55bd072bb8a3164ea073a1459a96d957e1aaa4ec39a3c3136db725bab9e15233f79d1f6cd1a84d6019b4ad7626ed377830228626403184df78d591d18c3d630fe456284e2ed64eb42a0416a598d9e1043c80d75933e8e0127ca19a13fc2c49bdfb134ae52508eb1b3259db0cd0b68b5e10c07814f2e0f35a7d495a5ba0504b2ec4db0c06889281550f98b54e8572041ee1674b800a40fa81510a82c0537b7a60040d731165398a0653f5b39a2112524e8992276107486fd383ad377711e71ba5f26cf0c378e024a6786cc3ae0c2003f78c055bab0e77fd577f27a0b5be62d266b5f1dbb2533eeb82ae63ae6b4045e1aeaf36bdbf2acd6968749cf127a640d110422e145a9f8567f87ddf0b3dc9af5da6335754a5a7d10702865e21aceb07c44a6359629fbd079cf12070b632d10947f73f33b40688b47889049c6597004961af2c4fbc4e5190d490ff4b39dad438a50d13df70ae9d611236b9135b87a24e0de549fc21b9170583ab628e03c6b04b9aac3b683f85542128fc733f78a30d37e855d61c652cf46c5c738af38e7d52d05caaa66cda3a4241b12d4b47a743e3c53568ba83e5f11de6476d3f3cb51bd441703310efde96eebe2883f2046eda54d0757abd1f5110bd241401822175aee07188a25a58bec87427b01c49a0e7c350d88b715661b2a1a5ca34036642d4334478963538fd2eb741d30d6391807ad894a6e15b6085f74bb0173222c7fe5dd28a2714b31ecda409b85f05de20baeaf699bca83365b90b65b8e06c62c01ba02a1900897cbd335f7441fd66e70397af49cccc2ab4f2ad8f3aaf9260cece89f54a08be006aa23b8c6b1f1f2df343508e5645f2c03918cb378a2ba25fc6b6b2fecd0752b77d41b7b65c5be11eeed424e2a52a99cfef79f7b105a63d573e1615d0ca3ab03dab0a11a97c5e31bd0c08e068944e8c3047bad12e47992b540a22ee240ea8de994bd3e3924d35ba8358a529211abbd468633dc67fb908d7fe939e7998f73acd84106136f0b7d2c7340b04f198677a3fbed8f0ea8dc5a4caca1cf08698b89c905daaa711bee8873649e4cee4fdc0ab1293a64b5e04374effd29205209fb24cf411b0d6f1ad0b51c0283c230a2704ed3d1f8fb1239349c5f9ef676d0c8498d2a9e05645880b1efddb0bdadaa247e3b8dcc98999c8aa0f666cf76de890481e69c985de28dd555509d9442136caa14f189beb91a37a71411ee4d7a3dd1050a369b1ad08cd0405890a63dabfc29717cf4c035e1b28cdd2ccd3fbcd9d49eb4cb850d673f8da36e55ba3be954968d31cc1441b5319b1654a3e6438c6077fe19defc2c041d9a9645317defe1ad867a4818e98305cb34b4ab05e94c99a55f4ed084ece3a32ee938f762fd96bdc15623798927b588243600b8f312baf02b2c59ade03a0bbcd98f2f71ba61cd5a922719cc29db93217fec9ea820bd999cd48ecb4880353b2d0f981f72daa7e81e8a91e464e2b75ccfb5255104447401063c5769df2defb646cfbc48b652c8d1a2ce9ea7a20cdf11d334b6a8b8ee96d12c39a7e01be18036a7666e3459cd7704f40c0a1847efc5cc7e4e797d9393e2c4bf186bb8451c40804555d985d29c188f4284770845da1521f8573c6f2e01ebd0ef640e3183bde11cf186c786d3760e650d07c0af7c438976f377446344e7d8861b90c188dbe6522dc3e4066224029eab3dd6e5cb4880fbdbbd981c9e4b3289bd1fe9540ab0fa92be9f668c49c8e4540eaa71ca3a13c15872ab5474361168cf7eb1c6740b008ccbeaf8ca1a003e484539a50a8e93f4deb95722dd7e097ac3b23c5a7f5dbcc3ad1851b286d50c19f05e2cb81ec6ba545f5456a03b8c91bd3884ca5414919a4463270f264700ac496731aae2884dc858f96441b2a0830d2a6891127a3847436c9c711420af1160868a48143d5c6c8574467eb61e6aebc9281cda3d60400be2df462bee755581f7ace1376009ff3e0944d6e8c3ab4533040a08521a1ea8f05d63f6464ee397281179bac42088fd2870ddda680bb49feb0f366c3e40bac715e30370072b8bb9abc4997cda8cbce00ec6a8d4e290852fb872e156950592bcc018c63166a25f4e13c7b2b012fd7471819715309173592ded240f4e1fcb3f81c0d7704258cae3847e64ae6755fd4475f5e2125559399959ef9f05a70879cb3feb36ff91ce9b94fb09510e59953397d7eca689e7c2caa068d42525cb4b99d81f530bde6c723fbdc6d5460dbe769ef863abff0883a04444fc103626559785513e74daa99efe444bf8afd19046002b9dfe8459a955ab1d6de82cd170572bb95d48827a4db3986d4ade42899851834d889901351039a64bf15e13f7d3697ac1ea4294a52bcfe659fb46afac3cd90b96d31caad4af927095f249c533901dda18f50207c5a1102412b36398e5c44f00758915732916cffa8289a6956ee0ff6cc040f5034b71ec1b15858d0f2433df36e9ad95486e6eec0586db75d76d4035d61a51d9d9872c5a5ec6ab103f9e95448790368bc9fe0dec075e7685df800f21612d137378baf47c1d0a875d28c43c1808d98a99c62291c6e0369358f867782e8d13cd322331a7459e0eb4808ae5daaa40295f9ce09f3dd7e890b38c887c037bd09c1657018b03e01165528b1ecadfc8d5d8c5cf6b44d5a272a4499a02523dabc1c37fe4bdefe6b3dc8dd00d4bbfad5cff58a31c86a5d8eed537885666cc7d1efaea7b07145b3eca0a1aede8a8285535ec50d5e6393f4fcbbd45061a8b8a97e008a804bab46d8ab9b6a1a713160ad11d4c36e612996cd86debbdc7d985d7a3b564b34ba991d7c66fa40af45c68eda570c4a9763a36498a00a1d20ad8ab69b549751c5de9328bad724a11d01af899a529b4b6523ae2543b0d9b1444243c30fe9a7521e512fd2fed35291438d7928e2d09b13c0a8fb3fdeb93ac14c78803f542a56da406e7fbcba242935a1a11297af8fc4acea70815fbaabd94f288a4aa9b9f3629ee8f1eb5fc8c56983c73c0cf45ea2f21639220363b1bdff0b2a09a11da681e90e149fd74fd4e64257f39e03712c6312e9915cf71097d4277ac8197896446ce1bbc01f3b152c5705c2f36ede3899aad292e73d907e110c7f9d28af43751dd6a713f6746111e4afdf483568b86390e108b0b455852cac457d8dd2eb4fae943ce6a29b0aad0a05e78e51b7e94842fae3d5fb71f3bc14ddad31301b471f3372f0618aa8642025d136e8036495f4aa40c7133bc1e82b26790bf5cc9ab4e338cd23accc0b40c144d29a342f68d337fed661118c42238495644b67afa3048e19630281974655109f14c107099877be7da103c6680f41847487f4f102f8c7a1b506164677dd5126855128855c5c1a3a9ba2ac9b7b19540b537d751d97b6aaf6de20e9395f5ab502d5900b4b9bef97f0ecddb2f90063ae85fad578bd31dfa01a0e9aa55111b88fc70f300358356d39c47c166ec9f00cd6c3dabca188f39c60e9c0fae8e7577a73459349d21cf4a4317398314e618de945f78865b6e080db6661c2982dba9e40cfc8b0e678fe3ece8863f9b76f5c13886224278fefa81e320cd4df62f436af885dcbbb85bb7d05a64bf1f4cbfd3c4ae9815ef6c23ec75551652e31285c1dafd02a9f9318eaf656785e37d8b704d7dc9b8e410ef0cb6eb14401f0d0f9e04757175a7e5900a4d9f60a3800631774f9a4140183ace0111f87daf2afc2c1fb5aefd461828e5c44add667eb423a843d276770ec4cf540939a08a9d1cc10da9aa5579937117acae73f8884547c888b64021dbd879bf69a6b131db28217b44a06345f45b4fb7bd2798594e359e0e6c9ab58417a8b4843f2ed5d9b33efec45aedab8f9c389ded7c83a8db127aa432ffeb4917cd0cb753eca9b556991655a044f3213a0e982d59c918460e8e3f63fdec6e1654c666eeb95fccf16befe3cd35494546fd25cd9307ea92829a215d22260d3b4674fa82ec121c42ec5a26da4bae266b8a8ad0fdc19a7b436ee4377d689db1bd62ba76a130c65b6f30a3da8cfb6cca4881343457f245aa460d9e9d4e507ed37216ffae2c99310ba467c9be26216afa5e72708b07fd6cc52a21b19c3b6c3b57f8afc19ed021a37f02ebc8acfa5520a29f2213718f87e26eb88f6d3075644c368365cc3cd2a1f132ac369da44d806b61d76167a883292b8ab781144fe68881ebe3cae0dd4b1798695ea1edc8af02c85583be0672e078073ccc0c0e40f2188990566e4436ba7ddda43fb3a556254bfae1cebb9412525a52a35ae24fb702c5c3c04f2f779ced70e904940ad74d8a671f3f59787d5cf23e8d3a06ddd418a25549beb327faddcd843bd2e877a9299755e9718c4cb128d79ad41eee003ed147f658ed3609a03722d13205a5a8a808d46b8cbca88528d403b010a3979099e5fc4b2e73e9d75f290f97199c94adc83f49c709618619ae409d54675875b2d6192b1266c9b6cdb498759a7032595a2eb325fc1f6a85895c6493471559285d5627776d97380d24cd0d2278eac4ab146700fc96a062277c4d47c31fb16e12cee4f1397ad1b01fdee3e9c56c1fbe3a3a3433f8fb27346d95a163bc7cb6a01314f53efbfed9386251db06b5ff6ce46468469b3f14932fd96a571d25d1bd6282692488f57878b545aac98fdf649b0fd622bbc2412b29feb91e67f605121dd70b668c304fbb2eff2c401dabff6289fba7dbcc7a717263657a26f348fb8535143122e2b356f0c1a03236e0ad7c3951ec273c90811ee79d49e131052c29838a2b4219020cfbf779e4734e04d5dab73a2d517417a4659a140bae010030fc5099bd38785a47a7d3c94a34560ad46a155f0f993eb783764e15a106ac06f75b95e7bd507a149361a3cb9db8cb376516a94214e5e1f0f08e2dd179ca6ae998be6e74065c0f240d8754d792cf93b60c249a9f9b1a9090af19487c821358d2e61745a7899fcc0386abfc9d49b5d3296900363891971d7f240b3e19e98bc4e4abc9febdfae996c3a5f4bb6eeeca7881e7a7ef196db941da0e63941df5218d0c46455ea32d9b0fd745c8eace3c4270318a967cdb673d2ec2b9467d386765f3bb3e479cc234ffd75b3b0e28f8a8edfcee25ca8ac41beb461b84a395f1390fab48b3957f5453d58f5e0f34ea90ea6a87a07e87e9918f60b8a55f7b26e9a611ef69195a6585aef990177c3ae4174c11c67885e987c9043b9ef3cbcbc40b911a66ab700da64042fca38a5ef822d3d743738d95d5ab37d2fd7fae491ed30f2097e7a58d0a1288635669e569afe98d017245bba24e0c906b85868016fae30e332f5e5ab1fbb9da5940a0d2fbf37c709a5233b0e778b29a39bf1bb5068c3c904a9cb4ef9355f72ea6cecf7cc3298b5773d7fc4129b029440fb97525b0c0c8ca77946f0661302e41dc3980d498f5c4a209fcb2024d72d8b9e67b0751a801da389f3e512186446baa0234a1dea8e7d8a188e52e57031a39de9756b1a358880108aeff696c0816e115c073c9ca5b3f5920438c55fc48652930912d8c48f4b262d41d49b35101ddb001d147a7ebbf53abbf1490e9d454af6faa95d9bd8ee814046d6b172c919bdd434b7cbc7d4966acc95547a446b575c31da3ef3e20c6d754cd3a3c7ce2f6c899b11f4f621c69a036c1bdf8385fd14fe98b11ea6b30004b56e9305edfc10d061ee9d2c60a773acf85374a47e624967adbb92ffac7d66dadde91b41a4f469786a65394754c3613dbc4b4139f3eab7de0e9150461d1aacdc5aae71f1b7e9d15adaec458ae181f7dee38752d8f91a6657a5f24cf8a86f87bc3a36abd4085a5155769367f6df0ea5f635757f91afc4675402c135594bdec4aec163f9ab26634a58cf475066625474af6e6738f409924d966d9e095cd58ad4819469a2cb2fc6258dbba630a9d7ca597ca03775ab2c114204c02eaefb6370fdb55276ed86daf6ca6587befcbcb0cbbb631c2f2d5f07c1929c6e4f81cc20d3e9c3d7277ecab4588ce7712b1b02722052668dd9d7fda67fb19e67f16b28ecec9c9cd7d712c7a8b483eab5bc7b4a32c71de778e5f1c786d1e8d7e91d8fac5d6dd2bcf3e206d5a3a2b7d947d5510246a22283ae3466a3cb095ea2c8e1891680d198866947c6516d5ef2e2cb75261b282637e338a1fb899752dc88a7acf8affe0c586987a3e570c8007bb7c31e89863ad576756470ea23d8593b46c12e5c03cfe1f8f99e0c8378fe64c35c676739369e5851f6ea768a88f53a355b58e5124ef3b4e03387834812c6de99058b589c85c0143ac7689c0e0d744d32d859bad781f00ee5a929576a9282949e8669121a0c5718d1dc17b05760049428feb359fc1a0cc5786d3013712edc991bb512fc4b33756ae06673278894d2eb7371114eba9a710b9151b567d586fc91805521b9e5b6c88da11d8bf082488b049bd5eae46a6b47000fd546a22861faecaee776d6e2aa9b839ce94237b67a44f424ae1581b29824ab12d757b546d9df77a4dffa3b88842a7488efc4941ea834dd96ad7aed4d91b8dd628038e06602c06ffd56438928f27c654500df180f15a5d07d6bb27e7a04d676b34dd92ac5541f2dc7035644222563de2a7b4fec251439c0bca10cd0a9185ea003372c023cd5cfcf769520333d964b66e02077d650a5da27821468c4b59d15c684727d2497f9109cad73f4b03e15f35f8bbd081905e09d9a673b5c045a7c2b61f43087343c32183ad79bc3fa646008ae17c2b1ad804c58cdc3f3206f9d9083c77a66cbafec2a8654c7b24e3ed00ad002b44c055fde4118849d2b1c84a949d58e2fead659347fa66fdb4103425653f8837d37c2c9df451fc57be161c5c3821878d93c462178d178b8e104ff2f92704756284076c0c21e75413e49ab5f64ccd820e22a77b0f38b14db5adfa63b4c3e1a0f23340433cd09a3d01e8cbb310014a45f94d420ae680080beb76598aa9e26cc5e6746ed98866cde4183063c80c1925f0f11ca33742f1be3627c3e4812b1b08bd390ceeea18fc1bb3cb204e11c7df6b82c2381b112db7ffb5ff6ca3c0b6f5c893e8d5090def747dc1eb7a41219b8ca3e4ea1f7fceb2648c628a68be780fa8ec76a5a26c75dab720c80572d97bf2e16bf73481af76229674e0c4d0a592236cb2c61c451c61e12367346150679692875841f00ee377589f22f7d6aab65769ba6bf6c5c0197372aee1bd0510eafddb36a95f1930c6341962f06cf34e786d8a4699c04a38746a0980c8b017a71cfd9341773a382ef7b32f3e93c62f8b128fc72ab03c70a219b0211e60ad3dc2f128e5e5738b7120a36416dc54be5fd8931bd28c671e5b2a1a53885947c98b26b3268b818a4171502e44156617d398994ec18ba6b18ed607c59b030df119d5a711a01c69f9ec3288a711f05cb3b2e9ea45c76e475646787e1fb79a2d9b0e83789e01cd2d2b9fae9fe1ea18d7d21639541c08c00ff0031168a94fb92822527a0e9292c9f93aed1b256538df35a3be10382533c113bdd4668833431a567c7dc367c81fb4ce9fbaa0fa47b0a5cebbf5f0fe181b253913dfb6df1bce060fa741b3aab0ca78cc028466a55d8290af101cd516ab5f33a35c2cfaedec43714138bb93967dfc33add774687c189ac5a365ea356aa5096a91f035d9b1fd446b563c88138447a1f3c803ee81e9eac8d7da3b0d5c9bbadecd13fad75dcad055a10862a91fd4c60dcd0bdd2f8f756c2ec2a423e1ae59039dcc62aade18431125447af59b50f38b4c249243deb1cbcf73520a299eb07a25a13796c568988e56901bfb8f4dc967e7410ea310db6d89e059bc7f37b37e125475e052db88dd0952971fae45c33b7d58875a15d2f3810549600b2f027e1cd95a51f80a56dfa4c02936edb3548c9c3721019ea63578a1b762912893c19c7583c204ee73f45764e2f9859c78ca970e898a3405da4a09e97e4311a1319442aa0c78c220f985edf9a42bb33e0a42921e3e5c176038cce86cd496d4067c2af9c72d8370b8740befb5d58e2cd6f164c289e9fefe4cb918d5f2199f3a3ea05f033a3f5d943cccbce368ec0e2adb42f1086a8303e2dbf2565593320d88307c29dfb89d459ab1cbcaa328a37f7647b1b18aefc74d5b657a4cc73ce100d5e203682fce4134e1158e3d4d31d452c83aae9eef0ecab1bd17d0257157cd24bc1234b833a78a418a36b804ea86adcd50cb2342e3f351c1cb7bcf8a4a730ed13b08b0154d577b5da8e61038e629fe43a3c8f4254cbee923b056da040469476a02154e278dd7f96c175411f5e46368a4d981ff80c8665f167a310207a72112433b59766bf9081861ee4f373403e9020a201ef8211821c8a4d49aa2432d76b15a024038854d9620ddb944b822a031dca72baa244c7d62acbeac6b86f835673936312e94e634881c98c28821a28365e1d68180a4291d8219f3399e993dd0c2e7334d5770c5fa5c91d3d4e2cfcf25ef49c5f4951a1c39f7525e9042789848ca98dedd8dbe1fac51683d5c12b528287bbd4fe1777923f310f0d5cda469902aba7b570f88f1a29e6cd995ad8f0122358795032df7c22e1e57e4af13fed5f7c47d92c9d565accdd6a20a040dad5485475e251d9cdc6fee1c75fb3d7efed89619753ec3b330a27d98c13b61d2c2d5c10e35bcb14cc9c890104458a07933c1c421542d5f0f34b81e958b4ff4d89c4855ab44846bd7f3c65bbaaa8833da18007ba323564a9f25f4f907597317542d6dc4b1bef6f40c0fc76562707623fdfa4408f57108383fe381e7c557cccb807a054daf76f14a284d03e912973847ac5ad6e2b17336b75290dadcb7060982eb081861a0a56e71cc747ca883fb776be2c33f7bf14eae6fc2f6c84eafff77c0a4844abf7000336708bbc9d56201f74637ebb6c64d82747f7720d342a65c7a27719941a8c76f62487fe356f7511d6367b8bc40c5eaf58018e1266038c6704a0f4f05fbc5b2c2a5334083712c29e8c670d9f1fe5b88afedcb298e5b11b2054e72a8413c934170b8d852b4027bc9594a10893f248bf18d0872e12a7341c5bdec5c502122edf1201074019815ff4cc922a44a3339a7441c38a641ff717d3260f27a2556b4ff39e5ffb080ff503a91832c03f57023382840d08b1ad007a3815b384e2991d9853d060950e45b3e085542e91c060ec4467d2b8eb6ce0b463b40b04313a98cab4b35c46074e77dc031d1f0be4903ca3497c515630ce2954cf2bcb6d96c234e8b1f7e4d54b3681263ce023c27c31645056b5cf554c127ccc7a67a13e78ce2c8c4e3b812d02640b5abaee2479cacbc8e49346bab600c57f5787e4c65195096f53f380e3c4cac3c86bcc41c03fb69915f226eaf9285d4e20d54652cbd317afd2fcc9fd2ae951c54d787b23db52fa599a089a35c6ebff455e66f97460fb1eff24fba4e4dcf21d66e5355702e1c5cef443815643a294498b36aaea5c4d74c1f4735e9712c6087a1ba840e2acc90ce53cc50a722bcb7e8ac0a317f5786f1911810e116a890f733fe4b1b1a6fe5288c1ea00b432053a5086b254e24e4123b055c15bddcd9c10e1bef4a17fc5a523e96ca2e5e9aa2cf609cfcddaf2a3dd21da014c9383b763d233c5e918ca53afcfdddfa0b4f64923f005bdbec8915add863820a3526c2608fd78737145281e32f7bc3ba8b3fcbcdadc587fae3d6c3f3d8f342e0706fe1b223cb4a2c11fe0cb708c4530ab8898ca95ac4019a09904bf38e546b00fe3ce8297441da600f72983e82dcd6481a12b4ec1b9555b8d713b7402b1dd21a92fd3d1e5f86e325658196dca06287bbbe3afbfc77cd495e33e016f1edf7c0513bbe525cf5e3aabf2a68f252b23844dee24bef730bd3e9e20d29bf687ff4e55ba1b95eafe032340340dbae86dd3d4c252bde881a9600678c8bbbc6ee3cc03a974d870358a9dbee7d5c8f947404f673d226b462900dae53a3982c5a036da11422ea637990f79ebb59f9e14cec5c0e50496c58b323ece403e2ae8f7d4aa9c4ad1ce38470654c7c9b6e289d546000298d974b4cf53d457aeb4e77d1a19be3c2496a1d3f83113389241d1df62c3aca340eac2c755a644e9299c5a24272a2091ce00c1bf75c80e8a0b783f0ce4b88297b3644daf8fb6c40706572a1e20cb12ec7fc836fcdf51791876e19b555b849f03f8da07953c6aad1daa4389388f7d9561cb8ed8997398aa69851d932f791cf7355e65024d4ebb68d71be2f07b9de234ea467269276e20873b42c3fd184cd10051bca36c6f4d0e135e75223614688c519192b32ebc04c0a628fbd6c392826a4d5cffbec36bf34b4f99f64722a686b7a26507781c13bbca21a0b06971e0ce4e933372b1bfbc64a3971a9edc1441f00bf9a63fe22e88eec90fb4077035ee0b90028ea5be380552f44244419de250dc14677a5ec79bb013d848f2365105a94a8b0bb4423244e86091ec9f11e3becc0781ccbc6824d378f15b001578d6ab5a81ae32f0495b3d34276a92b040c1e26e7162d7a96cd1a3b3b5c108df8f71ff71a71bfd4ab412d4798930ba85ef03f0f51dabcbc72a6a0193cd85b372bf250cafad866591f8e9d5cf364b450a0c728a420ea1dae231bd7dbc7ebe2fb48dcb1f16a51e652649faf17417ff57ddfc1be04117a89d87a92a35c63a10ba56020bd5fd2a4b89945507f6c947450244ab9c31864c3aa16e04a2b6c8d04abba3891e5f4c55d3c567e83d13e01d4afe8c731e9ae1a8dc802fdff75f274f51696573b00ba1c58cf31db41d6af7f2894f1529e800cfda9adc538c7671131809590acca53c909285f43d7503b1c35448dda743554d0c2f838812aedd16ec57070b36bc920523b49df50c309c526e2f2c552674a1146159c48d8dc9895030565384138c607feddddab9fd30cda96cdd557864bbc787b534e58c865a42d47dc8dc4e3555b6166f0c3d8ad9e3e7b75c6158267921be7f936b2326eef45bd36f50a5b4c43673de92ffd438492962a22071c73bbe98702dc14eb6695b7332032b70b879c81b41724e986067daf86401113985c8e81587965bc711e46ea20de702959f4b24a60f2886f3f0422773f545541493cf2a071d11b2ea6d47597a5a30bb0e0d8611ec6e86428af6fb06d5c02ec4411f5eec443391c55659fd2118f99b735a4dd9e6fd8350719e9a06ad4592c0b45e4e87b4f4a8ffeaccf393a36dc906dbdcfc501acb9d877bbfcf661fc8dd305407c9b95259c877123fd1b5d779812c6a3e26ea22b1791f2be18cc1e5f4eedadd548280c9d20556f9e91f2642031b33094c5952ede49a262cf1e909169763a39015024c40039ab0340d2c4b0d887ab54547909f0f84186470d57b765db22856bc1f6f3f54fdfb12597c9924080d6a07fe6bcc8931365858165fcd80b804a6ec07f7de0b3ed30ab6d9ac37edb242afa77f2766082c4470d2475401a7ea0636cb635c5db8988a8dd3457f756304d50b67b883ef85b2a0230d2e396220d289e741e69feb9d2de89c6d3afc64767104588f128aa3001db7d6d89ab5fd74ea15028f731b48985adb0e43bbb9c72c4046a606ba4cdcfc493302d1e12c06761376fbbbb9833f13a167e43a972ec09e9c58f83063c366e8611c380460f49c0bd417bb58576547b6020a1c8c416f181037d16cf78fdea557df686496c4a6b25b70ee151762eb6a68587769dfbc3870c58820585093ff769ff325c1c41105051d1f37c70a7a796a7b6b69734fed5f876bf64ccdcc8731c1dff8ab96941a16518332dd89bbf0038b3c10c09788ec39270baee9f0daa256271c158ac251fdd386220380efbb3f9790754eb8fe06e406936a8680ed48749068f2fd9f62c80e858de56a756451017bc8c6dd503197e96c932b1bece4c08737952f14ee0a1f72ca74fd5bbf8ef239e0c7f5bc5fed4b5c67bac47c8128a975f23ab0740b2556e704429dcc6c86db15952dc442a556f60d4bd5dbbfda072e307b66c3997744923a182b73bdcd9b67833305aabe53bf4e10682e92ad9745083d02eaae8a24daa9f4e0d0d60c7570d2b002c4385c275a1e6eec2c9d339e20e806f71ffaf045d88fca113e40bce4ae8c822193a6da803a6d04961e09dda2074387ef89e884304da32983264fefed83a18d4da39ac3b9c23f8d2e0bae7e89c5907b3e701fe490fa903d8355503c847a9b8ff6b5207053c074a60ee5f6bddb94fcc7450263e2cb48570e6c7d56ae13e14f83746176c133ad4765ca58afb2c0ae7931785bc49f727ef411bb3d14a1116c10d9bbd8ad5a997463e622bfdc96b1a09d24fc4227461c96412715812a08b8b8511792c87d8740ac970796e070e3514a3643b0685bdac05531f4395c38755e7b6f0178e604132bcc73cd84147c1a2fd1dff083450c060b58cbe65247879168a886323ebca3d74d3c9a1b3dd69d6c5cb9a4d0ee2d0ae49a57d8b81d660720a2d9dcdc22a3958f0f29ee1f3547b61bc77924acacec3de0b317024c48b8d9ed33568fbe59f812e4432098e505dacd31aa8a32c562e0cf2829eb1eb2f180fa80199ba6dd05eb63efb8e0d61730b18424d8db3f395dd96cba7f85830e56ec24c4bb39dd5b9931110306259ad161362fbde21b4bde781cc1853c59ce4e2d95849b0852a6c391c7c219763653a12ca701a8dadd01a0861e001748d3e6d72b40da6b78ea70bbd8dc4da93a75a493d85b5aded9fa19430b653bc2d12f4fe89f21d11767f9a228b06381e8e240d62eb9aee33d79249b5592774e70ab93d88845d5a0a102b619940a9285606709bb3e603b5d511648042f3359a52ad24e11ccf0970e1175b6d25156f3ac1053c3e32b2f7fbe27334ac20b561d6d08414ded0d9b33615e8036feebbbb13bb374bf9ed2ea0cf1adcbca023d2f511bf5ee4ac21f687e8b21cb0b20cbeefc74b04861b326deba64e5400490b0bf0ac88bdb42bc410e8da3b4f3419b13f34d5776d675b2e1a0d4a50f0f34219bcb72cc617e62fbb1e33b73544d6820c823335b3754a4cf0560e3513212678a741a46c1e368378189239e948dbeca3c03b0374209892f02d8c3f9dc56b30918994b5d7b3e0decfe2032fbe32f8298bde9d95de3b8b9e67d51b2bff7b8c038c0f04fa5b63a958305c554d63991148ae5fc76ebd7cbd2f157b5b3d1245acb403d3331159e94314fff28fb89d5ab31670fed31d43b0660004b349f606bca974783586a9c1a680491ad9abfaab542c6d326ab4d42428a4edbdbbc9bdb79452caa00aae0a490a28f7b0d4dd5bb0aac474a12d5c6fa60b3d22c6a0df58031106fd66a1a3ca4c01411531d0335c2ab8dba5e9cd0c294eac3611460874f7b4d1255c350a8e32474b3cca524a29f3a669c93c143c85cc9d2f5ca9eff7dcd931efab0d2dcd0d841e1de57394bbb93385d0c7a9a2bd93f63cedbd4e58b5a12ef49ee7551b53a6a5fc791fe1d13d1c67389af93abcbf4ce3d22315cc1a7d27cc2a3d6ad339ccba8f1aa575528b4aba6bce8d1eadab64568f95b7deca3f5a5f794dcc877ba85c25b37ab0fc5039cb6b62a287c4dd309a75ed87bad0b360200a6365ad4766ade7cae0e2af7c6b439a528fb3992f0d67be52a7d794982ff0f45ace7ca14eafd1d3e9b520d776342143a84d8a2a25653569104d9fb252a5703d22d60dc4da81583f10ab08625d2286f41fbda43652485231437a143d09cb25272c9960d9044b27339457b0c031e638c6a88c46dff7893eda36d2e54758be9b43f3f57df48d46fff21c9ae168f4296638121a2519c9233c464eaacffaa8d5de3885cc7024f1f79dbe9feae974fa4e790a99e1e8f5fb88e8d149df3c009ce04ebdafa70d31724650834cb1935300a93f1ff0593d58ce3a2bff609d25b3c846e4abc4af8795b37ab06091593d5a677116f9c7df9ada90b624d69841f487c2b2219422b1999990c983c371ce45b658f419e53da347fff0e99399d1f2f2a7fce111de215dfafb27ef8d5670c598daec90c30c29ed41676e6ef7ff2bf1931919c1825932ab07cb57bec2f295d7c4b0302bb37ab08e8f59972bf2fbbcb3708c6191a34fe63da3695c2c38c6a0e01fbeef525e05b37aa8ac5ce535312dccead162796b8545b2ace0a88410bc20c607ad8263cc87496fe118a3b5708c51c1318685630ca95ee5736b8ea6530ac5a61085d523a20b7ded800834fd0934bd14a2361106a59741e8a8dacc57d5f4f50667be589abef2d42313f6a22a315f5189088e68aaf5ec6a736a44d36aa3e9479fd6335f7beef8ccd7d69cfcccd79e5b76a7da0f3427f3b55d4372d27a343dea8abb23130fab38dca267e8d52d473563b0d0c5962d492fe13da34b29f5abaccad553d5b15dfad65a6bcdfbdef418bdb81404e9f2a278adc78942e594bc6d2bef7bbdcccafb379fb22c7b2ce1a84d78d39cf4ecf4ebde451c3dba7e3544d7a7de75d49330a9b3dc5580956a835f79cd7b74d70c294c10f7a7df67ef2ed6aa8987d3ef0ef944977e9f91325246ca48198965ca3ae4135dca9794593b48f9e491504898446a995e3a09e524d69de1dd575fd3f7bd47b9a49b300b7b58a504bbd1a572a43cc37a9f82776907f0a6fbecdae56f0e74f4bdea5d74c08d4a7280a3eb572a3ffde23da3ef4f988572d24fa66bbaa67b4ddfa1be2c946c3ae9a5df77f13365160f9329d727a8a7bc46cb6f070fd6516ec2f289969f77d3c73aaa54ba572add74d687ad174bc9fb6ad229e95e269d23dd848267f46997be5df0b179c29b74954ce3884bca1f0fe06f0e02bc2907a1fa7d09d3b84899c6a541958a65b592eb28fba03af54ca71e9b29528aa479d701da54805d3ae937d7196e1f54a7f22e427f3c6801482593eb7b75c1f8dcba63068c4cc27b7727917e3c70fafbc5dd5178cf68d4a9e5b26b3063e55da359bfd6de5beb492927bda33944cd5d85a4a34693328b07e9adef20e596d7e8d2e387f2127ecaf74f8fd4f4583a0a0e5bf8250df743a8e41f5d7fcadbe67d5167e1d153706c86547f3f25954c8ff3f4385f5779db53de375295ea27817987df0e97aeb9bbf7d89c1f8f2eef1a7d5138769dbca7c4c890f66af48cebe5250c5b5aae33155d7fca5b65c2aa9f8e9255149329effb9b4cb9f4e3385d4a281590da74ef79f7de8c3efd94e3b312de529b4ec27b46d79cbd62d24db854c25393f046c9342eedddbe9bde872fdede2750b3bf1df7155fdc8204b77ebb74a5716d23b4f7a40509eea67169eff171149b5fb78d60a2e3ce8c8ed7aa56a74b57406af9f8f140e9d664b99941180391c8d2217b7d1629508c5aa5caa89655b85e85c50cf733ebea27933d93d1826a1c2ac2bd163a5dfd0493d1b77fcf322dcb3222e293212dd2b493888aa8888a44930a3b3f459a26d2ac280301811e339c9a46339bf4a8e1b1922602e530bf03cc18b0db2acdec335d7125e1aaadb522c96222c48896a40b4490553483286148880c3f9a977d386a510e85694056742fd0c33045fbae3a39ecd0c3871f1c0081194e306b402d125ca977d5a9475c393fb749932baeb8b95162c9122aa898620a29a4883fbbea4424376ee85d7566cc78c2dd2a1512eef6f48e3f780a77c71f70897df709443b275708e1d241d86f42f6c72601a230dbd3730d4b4dd33491a88b9ad470cddba5331df27b46cb6bf45adef276d36cb729852572727aa838426e0eab075064932b8e6562839ae879fb4361762ee9a1301b346d108f0ddad6c80e8e90f9da556708939e263f499c00cdd79e427a8a88ccd7f779d19177df22237a5a23f3657166b839a130ae676b325f5294a30189723420518e0624cad18044391a90284713e57044001244935f01a49e1a67e4071a9026a462df89724440443a221f5192098b45101205011224e211f5889088764444f4bc48933aeceb0e91084c5d95f21dba52709c2bacc2291c2788e3d42eca3e84163d36e96c8de04a4d67bee2ce7c09d186cc97e8f31a118d4733325ff7289fd78ecc57e9f39a8ff6a3e7536638b9d34647bd2bca84429d640978a058a2077532f19827882a88b505918918c620d622d1063107319cd76989e05e4728800ce95d75e8123a44a998a1d00ca7a0415200e5f0e8e9845e31614eaa8d0a0875889437b409984540689329ca594191238625b47cd14224ee0e592e3d63eab864de754885a93a570051583d4174996f818e819eaf36d0f341146848eb44185394b3440abdaf96b10e6187043d7ae618a17588d6a4284714b4335ff3558368103d29093781a34a1dbc4a486b820ce7352548ad09b18613220ed500c0ef2ede487d6b52d0b31e51e1aa8248a30a1942846786291ca38cdde95d75620cc0ae2d10551d51d509d205223bf3c5fa9162c2a21080a2921134e9c978443085ded5670b63d0bb261102d2bb6a4014e6d2010a9470c203450802932d579d19e2dc3d8574e46bb4053c3ce3c9b55a7b543202241badd112fba07acb320919835ec319a61c93d39c61022e20710288121eadbd0b5d9f6298c14ea4d24774cdfe419ac5a26fd8be8b32463a6a228bd9708c11590c435db416ed9aa196e590baa498d00e01950f3f4cd8d6694d7e8a61063b31f50e91df7c992eda8b2b9c2104300d6e0864fb5462e2d870640e04628da837eca22e9ad4a1301b254eac11436b3446c5a3356d9e0c97ca4f4cc3f9cc98a1f6d8c42f3374cd50fb9d5c0954bd43fdc9842f132695d0244e8c9dbbe390d6b44360beb44b9b6d2f8f9ca2336801888807a210715c0c871d54aa3f0c5daed30c7f00e2871e333b5ef8ef49c5fee6d0f23036d3e38717d73dbd7859e5b6842dff9998c1cef4f8615b9dc30c5b5c9ebd21cc0d1c4eaa9367d1d0c59d23393f427686f800493105119e9d0de5000992a3b213d668ef9a71c3bb3b42bc1a77763222d94ecc986c67a86f79b9d6dbc187192e9819201c407323766386cbc692c0e6e472b976e0ba8e9b9d887bcb8b8a9e5c3bcc970f335c3033403880e646ecc60cd70c98192e97cb4604303652971dcb849c965863c63a918beb3a6eee300383e39a7163fe25c258c2b510c001f4f16387991d7088e190030e3eb11c0b05755d3a63a9cb0b17dc6d339128933f0061bd1f7acc582dd7db3317239a6b107947d471d3292a82134e54e184134e38e104e7012456a88ebf51c4591b2a924e5d69b6e1aa6d38d3d18b611655a48d39b5efc96dfb2c08fb7a297af6f1b0226bb126424e5a33695d8cb6bc1d9152564943459c66b78e74bdd187623aad5097b36a96f370628de94d15441b5ffc5850e3e48a3566c0f4f0e1070bfcf882c41a25d3c927d640325fabc7cb9ff94a79bc4c3261f2474a0184684352017e4b2874fcc489b0f82796d0f172c88449cb132f55106d48224458a0e3e5cd840d415de6ad123afe02d1865442c638831d8a4f40b441b3243ac17563ee00e87819d1c60e32c654d97879b14be2e78d8e72c87e3a349db2faa142f5f303e63de737941c923c435bf24c9daa825c9243e466ce67a56f3404138972493334a30894b7bc02887a9b75ede072752d235232994da68bb421b71063cccf1b3d6fdef28a2e4839d404ab65e4ca25d365680b57d2bc9af70b2e4dd3ba00024dd3344d4819e896820edc0a28e81d6afa42e955ae4f89d682ae8bb18696553a638c519331b6e0665b8c1693c5c4d0982ef3342fc332a65ec3b5661f8f1843841798e146d3344d13ca2c0082279c30022f6ce10c4bd0a0488274821c22594f8d01bdd94076c3031b6c47dc64200c1e38010a88e808610a5a1038214784d8ba4f9a42e1e998c48a1698a08bb1463667cda69453b3973ea3534eb905e982a9f552d66b236cd63cb740e3e7084a3ee0640a3f3c409041568324341d0d892ccbb26c05160615891f114c4dd382d0c48a9d26430f9b0831d1fb2e209db5314e997dd68c6619cd599665d18859934d2a24e5eaa10b2674659206755d8caff83d679d93c658278b2a98b833c638c3205a9519d56a9609a95a2624d32a95a7995629955a568508c9b4d065f4b2cec70afb1e819830d2631cd26268c355b5742ed1060e32c6fc765bb31612bed1a5eb3eb98eb3dde43a2eef2134518843186e39871764d5b66839db16ad5298ab3497c37c6597deac56c6980f6f74b197d102f1610fcb8fc7b543e8ec32cb75668719f6982e93478c311fc61a3ad81ca206e405090de59043fc91999631e97c6081b41c820b871362122d5fe3e34b45d75a230c4ad029a402c31531d65a7318431164a024890baea0424cd57c741dc90c0c216001030d74f609c4e4092f4a066bb76ddb6e96183a818e4c1a8630b14107e6197a2a131e2c21abcd9141c3b6370913242421738621d590187c443b505911cdb4acd4048e1217a56312211374408808aac8e5744c22d4832b849b6c43a209614990ce3e3f996c0731f4240943152d55084318b8508528f59411c35883859e77f900043d05a0a77c78d3dde32e923afb24961975e18e8ec8abcc97ea93ba44179ac30863867a5291d5726c8a7013dfed773b5ff865bacc7b18266cada0de52cb3d7e228e8a28bdb62aad18633ec32c114675852120016d2e8872f2882eb3a582fb19d2e80aba72db9f1c228c5a3f10dc6d6b08408479618cf89a32946136271d11b155ce14615e8c315fdf45527c65af755b293b49e98888add61861ccc3b0e26699969fcccc0d975577c6e6a87bb43ec004901d9b982d47ea427514ca9a20a4e95542d65e88c2264f37c2ac79d4f7d17b7c1f7d7e947f1499b9c7e828d67c69f41f2ccdcecc3a0078d47b38bd948b28fd54ca3782df6b62507a54a7df872c50dc7a233d33a4983583ca31ea623a6bc6741602b4c7a0ceea41a2324bcb2c05988e7a0f282fe5228af4301d7594bc7a0fa8a31c251761ca45b6ccd261fb3cf77954661d20f5d5595aee21f515ab07d559579df51803669676f03531a78c02f38f22de7fb0ec59d94fa8ccaa67694779b9878965b3047a947e8f801803fef41ec09f72fee1a22ef4a50cd4c3a908943c73326556cd1240408c291df51e4a47e5fb2250f28fe71e6e06a22666471fd4b74b65fb7cd41425e531c6948bb0749841709f2ffd84ef5118e526ee1e16a58e8018937a0fadab1e3f96762dcfacee432b1799675df59a9854ebaafc43f5562eb23df59a1895eaa71701be08551ee2f4d45ba7918116455de5e04fdfd2063cea0a385d25b36650a8cb1893e932c5d25698a565d64cea51b3ae927facceca45b8a7e653f847911ea9aff2eaf745e414b1ca32e73e75d6696480b52377a80b3d0d9b8bf294977e3fd6014a47b902ee53326b06e52c04c41814560f32867419437a6caeb08c516119a3616964863c33e43992f5f44c9b119e3cd36687080f4fcc24e283c427cb49eacfcfce8ea5dd41d4e69d4cdbebbb8cc36f9961f68b49f852173ba70d75c146ee9e3e538af9da936706ed699364be3692f9d27c7ee6ab9edaccbc270e4b02492926909ce23368f250589c757bf66e66d56aaf557bd56e758561c5ad7ad78f87f62ddb196612a5869ba728ba2e723252bba0707564a1b7c7628d987dfbb615416fdb5d3c5793c741149498e0054aa2b022667bfc666ee6b35117ee568d8edc1dea6d7be89a2fd145f6f122014497edd166980863fb86d11bd7d222da04bd869bc0b13174cb700ed485baec8e7a30acb853d348b71bd365bb8c485a2bb8e145d7aeb2df1e3faea31cb53a7ed6ce70b3dbb7db5b9b374d186e505cfb6db5c7d276f3605871331db75f1bde5881e1da0c33c3ed5f08666eb224d58be55c397461528855a31015f72e9cb9597a63bee86dc6d932101656b8da3c0ec1ddd24726caa26bd7524c20ed12775b3d69de524745d5811825121a4851bd9a5d4a29a5d462ac5ee6a9722e0b2cdcebadd230d4855ec57387c8fc87a14b661655b8a2580f341cebc18e7624f395d97c04109c416f79ab8e645ab63da6014161dde976859c17af0a86745da3dcf359ebe5e82273943d4d709738cb26d385498a09ee691888a0776452bd252efd86e51433a417e18e7ab1a094100124e152fa23d227cb9ecf0ad7011098af5fca79d901b3cb71baf468203c70e7c3a0efad91de6a43e242175bba986d67590b7343a80225a902289caf0b540513edf3850fe81d97e87aab6da1eba53e8937a64b85717267cd3e5fb3d7f9f99acd2c7b3d27fa107afe2df335b36a86f599add5060a95eade189ea68b4be4444e93a647a9cf267d49085d9f692831a4476573ce7c230cfa08505a4f831024489021e044a10a258ec00132ac2071b72bdb7b2a98152656986829a1a584182874f1b1a5b5843c809c4e24d04edd7234cdbeef8ba3efebbe6ff47dd4c5388aa3388aa3910fa9a5e7718fcd1396babbf7799ed779ffba4ccfae93ba9bdedc11b5cc02138fe5313e70a5ca61ad4fa59589e8afe33c0e732132197da3d368341ae5694344c49100e93e6c6cd680862b0309f7fb0b2e5c16ee7387c25876a6102714c6922791397764f8e06eadc783b1e400992f9d1deee3885c16967bf9f47a4d0a59efe3f28a07f79a0c4fe82fdfcfab6424e172dfd566c89371840bdee0ee6a0364f475124f2173880c1edc967ac251c7f8c08d12d727b9fbde7f08a3b8dc4faf36347a1fbd68c2c3342d5a9e3e77bee32460cde707587b22c6a02761ed488441b51e1947ee3c85694141228bf2d8ec3a2700f92e83b4204d2f6308b7d69bea12831bc40352bf8eeff686f3c9a4ba579bbddde89a335f52ab5e36b019432b104d2711ed83884d7f973a4618f7376f0a50fde56dfa5780efa3a1f9ba99afefa44f14d67ab4a10a50ed08fd64525785e09a2e35ea5d17f3befe24cc0d15d70c55f8727acb55a978f7f459ed7da31178d463b36657fd5dca572f4689d834782f89a0e025fe1e3ff9819fe0e7a743045f750ae78a33437a13ae3755460fee9e3b2e98dc4dd3a2ef4b2f7dcf1db0ea6b844bfad67a6e2dae7d32f34984215fc39282bbe7936ab372f97a53e5e713d4593e1e1364c1d448d7cdb0eafb15def7a9cb0f9575dc8394c7c7d4b42786ebe5000000086ef7fa31267533eb00381e7b0f39ae7311fa391ecb4514e9a19fe345c48ee331a606d963034f0f8f919ed7aed12efe02fc8d1dc77b88e51a7ad079f6e4cf68172e729ce18b6cc365dc701b601cb4010000c0317e830c182f311e3f19178e811f3f19182fee22efaa5dbceba153bfefb42fce50b31cf5ee395e1373c1cc3a008ee7780f1ccf917f1401ffe3f6c0f11ccf917fcc9e5c1303e67d7d4130b5fa05ef7d6ca2f07ed137a3c2aff006c0e3c7830d076b780abb5cfadccce23175ca593c465de097db80e510b9b3ad0eff02bfc0c02fd848cf0ce29e6a1004c120eea5eea4b78dd020b5a138d486de4c406a30752f792e963df75bf218c9b2678672025483990819040787e2f4e0ca203654f6641becf404cdd79641b444f2e2c5bdbcfca989a9899136d4e002b5ba8bc2a4cfbdf449ddafee512e6cc8353cd2ec22dbccddfb7b1c38034d34cb490fd29dc8b3f32575f613478f3103328d32a1e803e352b17c7b7fa1be4fa3b7c0516bd28694dac6d7ca47ef364f7bf1fb22f52e7e5267be5232f66df5f78da1301cdfa1067f0acb71f03138521716d73886237569f149fdc5bb94fc0b2c7352974f3d3673e048a50f6d61f14e7e291cf52abeb8bc043261f3052c761cdf56a73c46588e14954e790cd31c1807ee3a4f7e3a6696385907575efef824992fb9c1cbd5ea5dfc529e3a885779bf6c981efabefb645cce82b74ba679d12c0f0fe2dd4387e7be1d3395f78c4e1dc41bfcea1777abbb9af1e49e82342e0da29e8277ea3ff7c98039ced045de56a3f22e3dcc3cb0749d67e74bbe1be1fb1678c57a9536c0b3be7dcc21e05509dd200d3e4630fbc974eaf63bfa6c9817df2e17dfe1caf735c802a24030f5fbecd381d3a9acc918f7f5db01be45de52b7b897a3576923ead1bd266d447d6f87ccd7e8066916964940242b5db87bf6f0d01c7be543bd6d7786bac86f382e735c9ef2fc32e5f239e47160e9435d5e64177925b364e93de58f9fcc0adee035f87bcf4ae17d9dfa0a6fa957ef40bc236a10af1e3f03b0ce81df113598673cb9acbcefff1a7dcf721466adb2219a856b58b00f4da7644dc6f8102dbfd110bd82a50f964f3243f91969bfca3b4ce57d5606f3cddbea15dce2c7a34b1f0aa3ac15c7b558165488a2f2b67695f7bd5b254f7d6cf649e5d659795b0be67d75ebfbaaba3074b95adf302acfb87e32ac633c8f7c3b52cef215bc6bf44a4bb3acf2aed1ab83785f83acbca566fd9786a1eb3e5ed655deb1f0f4c1b3070797756486d2874a8e4bfd79db548a5b39885b4fe1ed23d32c3ca49c25df8ba35ec1296fe17dad52b9042f3f7de62b46fd4e05b3de494f85c5e397957d68f7b70252df4c93f22d75ca5578b8f4ea60ded247da0c71b2a3c10bde1c21219fa11f26404e34784110fc8ee0370c0b6fd4538f1f0f99a357acbc81d0ac8378bb34f88bf74110bc8f5116f69169162b250be1d2abbc67342af58b55aad4e3e91195695cfaf44f86e65098175deee5bd776fdea54cf3a24947c93cdc4c22e1a8e956f9f8ec0c604a1034d1494969b59b96554a27a53347461f4dbd69b32dcbb250c7586b16c30da67e32f14b60e20c6fe838916434a3b9d67a15fb9249bb5197add2cd87c4057b6b085d30330870c1d80c8380197bc31aec4d7265b541304d1f83a4cd4deb8787bba136524a23a5477411565d79b7e8998d10933786dea9c49e418a2cc48082115d5f6b199c98a109339441d7672ead033838c117862021899e2a888081347c810a66b809038ece10860072416751e80c064e74a426b327c86c739be1ec2c6745d6e63d71f8f9968e1385d5d62da35678cb9c487432f3b185270b4fff1bf3154f1fd68a5be4f78ba62e40f252cb24b2546bedb4ce098e931ceb834854451c57ad5725d775a2ee15e54d986e65edbe75dfba0ee528ef5070ad175dab55d41de507944e7a9ee72181132541c5894c2825530945b4719c674772249de4889ce49fbb5511a5643afda084f6aa3e9a26287ef241bd984e27ef74328519e5a9984c97524a29a577530666f40411367ba80e127a680c7a680b7a1061f26742f163842568bba14820f9237f64920d054802c91ff9237f807c482d530f3efbe9643aa1502693c96432994ce0515906fe844fa719339c59169b20aeba931eca83c00c29159ae9a182e791e9d2a3e46eaa33031481a80e153ff494baa378c7994a94b0d4e012a80e854d1dea426feda53a54676849d0143487e2cc70882ed97a50a8959fac3eedab4fa6bce5c1afe0185d4c6fe118554c288a02df81f87bfc3cefdd77c1eda7479a32d5993a5487ead02054c7c87c39892e518f9cd84497a869eadb82df1765fae99d09d31daa43754ca74152795b304754de2a2de9ce7c99323565ba93a90ea529df5693489f38f3c53abdfcb9aa873fa64b6c329d4e4741994e28479d50defd84c2cab1199a1e9b2816309d5ee2984c4f894e56a654361dcc1b954d3f491c5346b99438f69784f75442d38ff0f6e83faf53511961862f137663862a9fd55c9dc174797a2c5de2929452966e32992e4d2553b6a57cea58a5d2a594524ad9bd843aca095d325f92c2a20fa5d435831b757c76d4bb9bb2c4bb9a2ca04fd57af7a43aa150264cc4a651a6c74f9a72407da28e7a099770133646609e1ed8c4942e4b37954a97ba54ba7c290b313f1de44d9986ea8dfa046ab4e9258c797a60a3e3c7032a9bb2109c96a72ed3ba8ed52541f9fdf6edd4a328586a104805b56da753ebac6fabf218b74a9bf29647bd8555708c2e2c5cca5bfe74c2db3f19d43b14eebc2f87a8bb771f09b5c9922c459f39c4847e6418a22e517fabd128459502512753c974f912962559f229994cbfa79fcce93ba66b3afd74dc7337612122900ee2a6e4d8c55bca952a6f9bda2a54de0f4d32df97280a8efa6e1fe1cff391e9ed9c3ddd22dcadb255ace4d6bcad6aa29ef006dc8884224ef44ac72398014813410a6d6f458f40a54c8a264a8fcd1d1a5d1fa5a089425af439b485089b38d16528d650d174b260e89641531c307820c2a4cef72481a629f88e4e901952d54ecd724747ea5cd70caed440d06abd7b526d95fa18ad98bb868960f5607a13a76f5ce5b07cfcaad444d73e1de493274f9e70b8ea13b6c946986e7a67b22922847cbd114584903ad4cb1c048dcc42d46f99866ad11d806344a5c78e5219847384bbe790c8e62477fbc8ea4707957087e8adb599f684446648a708a1b8532868863df3e51da13e2938dd25674da27cc2265cc231ba6c79edf693e93e7ba9f1b8bd28d38145eae08c1e9b232673e889fb2adc3d876ea41077200313a24bd428585e7e2e2961157591b9f42df36442edd01d9adb521739850fdbaa3ea98342736c863950180ed3075a3fca41416197f7b91c14459d150887c24a0f5d30580837cb7b0ec1cca12115ada51cd20441a00981090d54269068c1151b0d133b5dc0c2133d3a68424332841b021337f841fc028dd48a2be81566846d769b73e69d5dcbac2ac67735467a2db764af59a5f1f392c9a6cda0a7270c3d3d3d3d3d49c0d1b21ab716d52acaac4d7bb769ddccb20df1456411c31923baccc718f32c303d75b63d36ed76b91f1f3d7e3277341a4d3cfa25652323f91d2140749498574c2755b89175f549e5a3126356cd1f0aa3534497782a8096e8f8f9a3256da2e32792f9ca320d9a619c4ae079933343392d3ee53a5bb26f5038821315bcd010895bd2c4008624f474d529a64b10159c0469a9679e3034b8f80af17b0ed15730a1b0ba2397ccd7bcac416628a7132de58f8e653c77b2b0a0b22a251e30c2a3c4031990a1b36f314802063a9b223b4326850c67093acb70aed059078aa033559665d911c4e08328b4e88343025deda3a86208a719051b9470800aedf20125480ca938b00da159544d6a2fb3aaa94e5ae57470a710264c6ce68b35e3c3aa0bf7ba4908c270b2e076aaa6549943e1cc3b0a01d52a536515eaec7c49e98289dac36dcb3bcb4851bb8db0792d6f5d8d68d9b7565a552a6baf5d6a3eb22ce480d614b73eaaa86879d904152b6aa522dbb56c70a9ddaaea12a1cee738435ae5a659ea92595c29d5e8f4b137945cfa184b79e2d2571f9ace68165ba816bacece17959e66338b6326a7d452ea99c919f442ba982d626cd19b524aa96591650d6fb72ca215aed5a978ac2f65b422a96e2ac6186946a9e97432a14a204aeaaa48ab51cac7f254ba16b72262b1dfb0963316b585b6982ee40b17a72b5851e59e6951c52dda8ace25214aa26294b658034364d1257bcc2680aaba6b4175e7e245c5f2059d3286e128bbf6849db09bed1a2079226b5fe88ebad05d6dd1729166358d85eeb6ac3b8b7527baee3816dd752bbaf35abafb547437225d9492e9b4610d0c112d80fa78584dc1544977aad5d55d0acbb32a9fee5add0a0ba7bb8b7487adee328bae25d35d0b4b75f7c2250c4734c708a35ed66453bc085b842dfada98f17564e156ba96a7f2b14629a4d555a1a44aa00965ed7c9de27c99c0520a457557a494519c2f8fabf15a465dc418bad808633ed688cfa690ba236559969dc25c97c26274c0051c10da4015a4f08498ac083ad3c117862459f244154ec4643f4a6ea84045a184bbb31d3ddf52c2ddaafa1361d4fa136bace879fa196b4c4d35c784b336365f328bb3db9a45d1e767651c71b73c95a24cf3a2b363215e7410f4128b5c226b39eedb6645798bce3d362ddef27ed1f219d621faeea1ad102f7af7d041886e5fb4e8f7ca2be5e595a181bba30ff7d97215d5e95a2b3abd04ea8bd64e3524d45a2ba694525a69ed6a27e23c6fce395fa3299df1e4f3bc53cfeaae761c3ecdb0562c825aebeb8b6bb69c46336ba2748e7b57c291bac48f873843940ec8683442c1bb6a94df4b7afc64f78b6bb4244dbc67e8ee31ca75254e8477d59604a4990de9624ba7da26de2ff3a6c8943e127b323270630ce9f6db7624dc75d2a7ebdec9fa1a3d31f6f0b65ace78c27da34c7f79015e9ca1a7ade844c231467e3ab65bb9695eb496af92c1dd61cba6a92d276f6647001909d236e8a804075168baa3dd256d88ae69a2efaab78f88e446ce9b06ebeda21cb77cc3b763bb2b461a81b48667cc9967282c6e3493d99be18a16ee0c9df1aaeb5d631891e83a43fe066943ea7a4da1e8e45523b89bdacc781a986437e16dfad5947ee061aff07ac109f52e26423ed1241074b95cb0d761e7e22743e3b159430035cec54f06e6b1d9ad1899a14cada456a8d4bd20085ebcad0653e0bd57fa701cc7711c7765dcdc1d817c64dcdc2d7d3477f999f9ba0765b8d541bc3a0a53cde58a936b37777884681a466e348dd300d2699eccecb6515b636c6ef2d3913a8dc7288cc6258dc7e6e452a9542a954a499e498586f9963a75449323906898c3fc0829524f3987edbdfb6eb55aad56abab7d9cfd643af9ada4cfaa5a9b7d3a52efacbdf4d3913a4c8da7602e35cc53f0aed130d73e1d52c37cfb74b8f1011c85f75530d7e5135a7b1f61d447287e3b508e1f9b99a77df7306cc3868d6bdf3de9dab88da75ed8d1cdbb76351f79f3c5a15071be502b142aef1a99558c4d993b91770f8220088259eed44f060473769cc87162078912aac0d171093b377acb1c1634197d3a467ff10ebff8bd0b2a8c08d1a37752dce8d1bb0c00516283448f5e83129b2646f4e83084e89177b19da18bfcfc1a5e830a8cabcc9717f9f2f2f2f252447c797979f9510323b3c0951aee8289d021b50d7fa92136b5eec5bbf8edf86dde2fdad65af3ae3615c7e7de1b10d3af5ebff8f8b9e8583d3be951b79e92e32d381ccff1d8ec3a19f39ac380917be4784cfe117b8effd0c7f19a98f8b53c0766c138011e637060168c981802e42262cff19898965fcbe3d7227399e3525cab95e30c53f2b6dbd3f6da57386a174c848c0d7fc93af0af76f114de57e7b3c04448dde5d39ce30cbd5c430ddd47effeb9c85bbe902e729c6198bb987918bd7b0b2642ea01e46dc371b5a1b01a037e325cde3f340782e0ca39ec63ead1519fcce89dfc88909ad4a285c5ea16af8076f4e897c7468f6e933cc9d151c90d80b44a472537e8d1499ef8e8d1ef3bcdb30147dd227d361500b46deb34c6f118ce7116586a1296ba05961a63fb162cb50d586a2a44e5673a2af47d715cdf071c59df871c43e8d463efe2e79af1e47e06c417d3b8748a3b88531c88bf5f7cbaf401802a8bf6332fb28b94b972faf130facd2c1dec511ef5ead546d5caa8bc02f3ca47b78f4d8d6b622c8e9a058e2d70d42d38ea18ae8941c1bb468fa4d05147fd7d29af174bedcdd7aaf5aac177ad56eb2d14eaf16bb5f2aed1a82ca37c32f771957a07e20d7e7e05e85e81a98300bff21d2b0753e7704cc12cf045ec2e707c849bc09159e0713cc757f0b639959b886516987580398de7c8374560afe3c837456a9c038f292280cf4fe666160f98d338cc69bc033d2aa0d031c91321dab3826996c1bdafd1570798dff88d1cc4ca611e593ad0f8fdcd41ac9cc6a3ae91f34e798dc3c2bc5d1c76f96e05bff80f9dba5dd101b6de516f05db7b100461a030b802ef2a5b1d20f7ee377ff4d88c510ea73c855dbcc05b6a22288dafc0d4f808ef1f1ab642c305f631358da7601f53c39c08f904bc75fddedb38875d07b18defab5d366e6ddcce97eba28f87ed49b633743d7e3a6c64e9534300303c2e1896485e34b04cb281bbe54e077ade7c814fa59ee252a9bc6b34f74e469bf271f776be6af4bd277d321c2777be94c76fe53cf375b3367b5aa36ef6485db22cb3a71bcd60b97da9c4dd960e82208759403c010982602aef7bfb2d7d58306ac5826b3487a35ec568c94aa158436a397b5400c8f2a24f06cc1b3c98bb8b5b49eefd59dcdb098b315707c026c6900f40d42a291cdf2ad5e384e9ab3e43613ae71c19474e459dc255efe220c0a79e4a5d45e59de6a9a8c408630740effb14c7711c77f1c63f3478ae9b1e6bc7bd8d16d360bdca37c818a9c7a814923e2a2c75d749cfb26ebfc2bb46af568f4d2e5fbcb1be07f1668006cfc21d8727103f8efb8ea839207a58200bd768f05a955b9c7ab7b27a27bd152c35c86265560e51b3be236a56667d5f106fcc007dc14b83352adf206304405b954c6d52b96706c51ab2cbdb6e1a572b6f95765d1967f122df701739c6e5c7438c9b4c38ea19784b9dc5788ccb8871518cbc695e7496675cfb0d8fd11932f00d78ab740054c7fb94695e74dd3db4466f34ac0272e5bb4a52e153a1ef49077fcf7a17bbcc8bdf8efc56eb5dcce97684fce81b6ec33510a46d38d855251ae8d14a34c0a3e525120974df22ef1adde2f7663b6486a3679f4ca355a8742c3775514c1dab11081000002315002028140e868342c160280bb31cdd7d14800f84a04c6e541889a320876198428610620c30000010000110a899d90000eabf0d84608d5ac7964f775033ba8f6c277d1dcdecdf172299baa2042d9c30339ae6b09060c04581df86fb93bb50f438a49f81cc7caa8dc7ede65e4e82d856e0add177ca0423226adad00edd23c9fa5f248843d893b6b2f0a010835df8d94f0d053d06eff1c42d56eec92e1d68279f27928652a62a378653bc850defe6979b8313adf53c4442ae6aa04be0b6445b7edffcad9924f362f44d52ab8687feaa6525009d4b7638b214b05dfe047e9b1b52bd14c8e4dbb044ae9e599e1576047cb0f82746e10b10fe169ccd54254f7718a2ef36d9b615ea8ac2fc73658cbfbccabe2065cdd5a3531ccc5decb56883c9bd0472619980320663848de8cc061560c62f40ec8f3cba6fa3654256ed8ae6ebb2ffca3db30f82cea5aef07e9f3ab1cabf7abf94a60662f1061a162b0141e746494b12a8c5d824053acb5b3d75c3eb37d98e9517c2542cb01950552140e637299c68a9e0bf09cf8870caa114973fe645201545801647f6e3163c76a8c1d480097c261d814506ffae6aa12adec5bd29003022250e0068640b6a628560c3c255e58e6894f799aa86dfe1460cf72c3216ef82e85d6439ba943c2b48f92a76d4b0436a7f062e3498a6e958314d6c80d6dea3b4bc7f70c1b373f9288763970081eed6f4235da91da8bb75f67f923ac9f2d183cd35f695047a3d26a8bd26f64b4880873635e27b684b9db80d4318b71fabbeb8244aebe7d6c90aa5699a934cbc3e4c6c45c9c9050933c7aa0f3061f5ec4c555f1b63a8a42c48118b0ac54405a4013d5032e03a4beb26e5a49064336f7d88e4d6c4f42ddafb23d58a9a47eaa0ee938c75ace53cf9c9a678a1dc004b9d73d912f9cd6b74ebec01b93add9ea057041835b09ff55c3801f26f51722ddb8d7235276fc3676beacaa18fa03cc94b758d03b59e67f2ccb2279733131efbba1433cdaf0abae6f86c0b7c386039c4f3aa1d5d9de99fec1619d519593a656b59c609ed65eb1abf10e51e28f39b3f0f434f5f77f1c4b2f9a467c75e2f73e844f109285995712891b1e40f338836bcd88c01ea43471cee6e1940d3a7c46ff754289606c17dfa9b31a6cdfee2eeb0710c0c2f79f101f3feacaa37b605cf339f5f224914ba0f12de6463c9cf30990ac5fe616e5ebfca919908a86d6120820253b2387d8a628ac0e2cd64183ce9b74a57ff244edefbdf62891334896a19cb3fefff177f46780be06a788d3164a362e255d75a1bf1f09b9ed27cb840d83956784b190365fdb8728e392d044e38d3b760c7b706960f1647d5247470a5bf33f9dd5ffd144c4f374fb970f2b7e136e72be28d2321875491bcca6c41290e68f74b4d182451afa09f7dc155b901ae568d67e1e5c0be5b7c10171a1825ff31a358ce20a17dac13f312d48a13dae162f7c3dbab7152e3c27c911a08343adf64410d324dd81948af66e867bb107c30e084339a231cd4cc3a38f5286558ae503ed0ea4e4c3ab51799636eb6a9d093710f92994477158246e7e034e6ae1accd55ce3cd1783d243fdc63e17a3aefae93cf669ef3df4b2782f070c8e45a17a1ba81f2c71b5e4f6d2c9aeb10002d689c1e01916e01cc1c93412798ed68b0ec9cfe506655bbe1fc85a5a710971a011dbee2d3a44c3f12095f33906a62fea8e4d8739425e106778d4315d387169233154dccc92d64a18d476937b39f1b3301e40d25b4cc4405e347054f1508955fb9780c92873c2f104b3ffc1741766c6b4ca28df042abe8421a0f9836a50118797a6535281e5165c4681c5145cdc02c32db89cc28b2b588c85c35bb83c058b53b818afc0efd5d64b508a976ab9706baddee362df93520a04641a6fe605f96cf9f646dd83533818dd3f128530451b637a4504da8fcf69bc935138d98583af705805265778f28507abd0f00a4ca6e0640b0f56c1b0154e5ec164170cae82e12b9cac82c92f18ac2e28bff68caefcdd0cc08f67eac24690ef9971234385c0ce8822890ad94f92dab4263b5184922a4531919567e279dac37df0ec4a842a1ff885065c49d00fb9586ab1ea4c6e7aaff94d0bd0eb42e145735ad486cc04027794fcc14baf76604f84a00923570ce98a96c87699736c63fda28eccf42e7b5e6cf67a0ef678c0246ac88b8adcb6f499d8d02eb6718ded95803a6b2a252f6b03aa8d8f3cd597d5593c075ae7cd7e5daae35515f6e469dfea83bb6dd4224a9dcd4b97e907b4c3f7e8fd5881624703d9d111ccde91ca9b4079c93d59efb020d672081d58afbfaa99d33ae57dd7a7cc25262de657066759d637c350415c52c76d5f2d749b02f9639642ef4c0b3af3784c99d966e41e570f1fd852ea2af29309b279d445b65fcac6ab09770ac8601b63949be2a0ac009be718135ccef19a7ec643c08f505b8e37f79d7945449f8721244e0fc382374fe0f68c88c2bc70ffc29686f5a7374dc8206056104aade846cd89d45e4caab8b62358f2c9919291c3f3600e00dcbdaf4cb56ed6e1b6c817c77171127e59983d31e77c952ef4e51a18536fc7e01a7afc7c3c0154dee18a011e5d4036ca4148e5ffd62884823976dfd8ef62b7f9f8e0e76de032956a99e55a040e017b5ec6b0f8cb158be7fce8b3b78c4bc234232895f5096078af868fc3522e306d6ba2a0c1183d5d5368354de2723766c25397db5b6759cb2e9fb074a5db11245b43d4efa3a8eefc192d2a9e71ddbe00cb594a918c0b834a8af903c377009d020105ca61a72964433ad99405960e19d001d63eed0b81c8dd3ccdf903d93e0e5e0ed5c0271ca527be5c59c2b860eaaeae2a9192941d467d96a700da808d8a3e2319504881ef548d8772e3509460a0477370670b9ed353df6d5f64a194045dfe3947528564c124d477018950226b788ea125fa573cc630a249839a4c40863cbdba48306f1e4adf7d1f63789bc71732f257fea37236da1992f026d2dafdc86595f4ca883826e1d3b8bcbbcfe894945e7108fb028cb02cfd73c5b8306cd62034ef25ae9dbda19da7b9fb8cfe6b25fad0388e99a89b1d3ddd459207cdd09ad4d1f8e00b85516da2c31028a46a695ffee1ca379b7ad3d2e92f4a5a0bc89edf1fdacfa1144d046b403cd2f915a553df420e41eb653d99516f92d7a2dcea6c2bdd84f16e2f9cd27f7706e05cf49442dba291671cf4fa66384c8dfeb452505bd2ff76a931277588802e6b4ef4548d638169ad917605132d6eb25ef6eea538aab61d63b12139ff020c2aae17914118c6ec6e54f7b77df69d58032b66f284ac64f161fcf7b808ad0b5ee5898010f8e309475e362a13bf52381c69664e9450dd66d7dc1b525a011b10b889f20f8d57f5324cd0f0b3b969a103696197f5c69a191c819761f9fd7415c42e5ec8adf7dffe9631946cb2c4554b2b2a8503ea54c425347184acd2198c9abb663bdde78c3dd31c2469f09fb6b360cc8b71862612daec322861719865a4f506d424fe51786a82d0711649993962f9d664b462084816068b0e3e0c1d02b1ed8900b001ef8301cc21cf7d2449d764d03d311c039e52404e97a4f0c42475aaa095a9e4d47e1a394b71abb1344d04bb467a9642ee45aedfecf027be36a611f9f1070e96659ab704c0b036e45d00390d15cd1a98ef43b25bbc260378bc3bfd666c27bc7b0aad2ce391c2b8214180925593e669889e486da8009c58ab5d677f920f791a56585424d8c835f2792b78e4f53055994769020ea1b132a3ed99c5924400daedb9df97c7957accf31641200d040e035615a2ef812b4817440e01fde026babdcf2e19be236ccb2d44b14968b5ee0e464f80ef2329b27f4e132615bfe48b3af6d5c0fcec3d647426b65cca180302662c9481cce19e4ebd9c3c5b3ba2b4bc1697bc38ba4248f1f0b81d47fa62122beeb3ec962e98b4266cf8cc0e7d678d2be296567bb7a2af1536383fd89b0314058a6d7b8eaa6cefc87dbfce5245639653ec5db264eb5e3534f7c1e3b9092677943b8f4b19001a7d0cdda68518824fcedd85197b677483fd68c898ca5df5d051948ddf83b258a12bc9ea803c1c8dba2d8c4f40d9c4319d9fb2ba03f1584c40e43e39d218f1adb9c2897cd16ac96202b50e4fa97c18c06175bb680b2a9182cc0e0f363ff4aa73fe883bf2df8c2c1a3ab50f44a56edbbdeb8ea1d300d911f38e55bfe2b35ec842a1a3292e13a1d60d0280ef760ba19078dead2fa9e700a57c556046fc7153e516365a85a6453504767723f06891f2cda940ba4d11ba97795a746f946ec4b2ea265032abb866dfef9db8206d63f4897ddf0a2e43111c0860d2cb6d74ed86b1400b80582049f2d10f19188f4746b278a8089e365f2fff068ceaf019ba006a4c69950fb8e24607f2a843f0b3cd3ae121631bbaa355edc1080d8671f3dd9ba8822d4ae3412ceddba504d87e000d505660513b07f03a00a2ac469bbb38e4191b3b83e0f9b0320bde701d1ce05da875e9e70a0dbd4585087145906a05f68018a2e84375755c9d98f612b2ee18792ac2529034b9a055c025c819e490ca0a989afb0caf6d1f9c18573996dcaf50d620a8d7bc3d7c20e639faa6a826e16ae312ab05e407b9bdffabbc5eb0b70d5e6f4b56c2ba27775a7090db623d674c9843dda9c6d9c1ca8d77a02392be373be9c5c1fc73b0fea84f4a65e90da3d852e09447ad1e44dded3bd38fe1434fb8e9158776ed14ab6d7dfb1f18c5bd6564f78453a6ab2cf2aa3eec2d946cb79937ee7b757fb39ff172f578590d9d9da5fa8ad09acd4195688d78be9465b156cab88b24800d59b2bf0b95031b525c5638be1e723c624d37b5b8d6d3c628c0289d41cfab5cf01e06c4e0b44e3296e7c2ca9f02596a4b38c50bc78610eb607c431d2343191c4bd88ca65985fa007c09872a6744936d3620c430f583473139be0929303af06b937bf1977b556c81a3ae3187227606f2b0811ee4eb74bd23c4dfea329434f9f909630eaa11c3cbfe65b9c41f39d9becf9924284face44e392577bb40ba7c3d13a8dfa1ef665ba663e26a48783e388851003445f2330ecdc5039ca6f909d286ee03c2fe5d923bec3a3c31294ff2ba4bb1103a00bfa3001a49fe4e42b26de928d76c86bf7ba8332039da7bdde103cb7331740c51e3ed5be1c0426779f68367afdf2986222bc1d3123cae8680fb78dc88bd4fd2ad3bd923c4267b4d0a516315ab7ab661586c46684751b9a36fe8b0efe7ad92d75b9018cac0a829fc7bf18838410d3852c20161ac83f5a70eb1eb4f61ff22564d5eb28b3c28b3a1ad79b0705cc5118516e15ce045070a871df102ad456cbc70bb6283f406d2b0ade04d0ef62bca8db5fc32ae9d2c5e4de6af257e6698b77212cee17704f947109151320989a9910621019448d68a80ecb11e6c239eba404b79820c0379fdae2c46f4d1eef6e67fdcf04461e720c509353ff8057616494e02d254e444fbf8dd662978e5c283b165715b617e2a948db84bad6537c7e551a489243c848185e4d12859f817dc5cc25d5b6d2e0209c99d45444210ed99a7bec4ec5276a12751efc5fa500e5afea445ff68d374210d40215cd6480350b1f60f99eb4fd49e068288b62781395291c0b59c247de60455fd90c8b89061dc5e5b8d4cfd965a2e5b6214fad6819ce9a6c82e1d12926cd78bdd1c5e81400aa608bf2a9d297a2f82f055080e3064fc2a6ed7bf8e648cf7bac947e9e32f8a3a6cdf8efd3616afe6d65b4a09883933f20f23ed03f574ceaa68a8e55a58d535f60006e8b819a73b5e2331cedafa83340bb3e988bfd0d9b0843cefdb5141be6db89f03d42d891a353cb6035865ac924ee1a32ed2c94f11349d9cc8ca28e3cf13a021d8de0ae55a172e9c90eaecd2b8fd702bff22864d4c8048e4667ec5f2aa9031b8cc4027c37709e3ad592a0fa16d5de61222f8145c09d9a4b0f5de193095ff3467d03b28bd871df9c5f45e54ccf99261d980d4f3f31f7421c8eba6d6af3ce2a45b6169caf3d3dce7119785eb998032dd5db6a684ef9cf01462c7e6be5cd638941966cc0dd46252c48fd169df5ab3391a31c3bc7cadca0f34df1bcab34e3a7ca2eb016169219b8d253e2ce00a56fac9f29685e8823f54df12b1f754d3ee65ace0884137cbb1c65df6e8a4010f454cc732d32dddcdb5e96ea0b3e5efe0c6f0c7a7b705d4e15322aec0cd58384fc8046b925b3feb3ffd7601023c7abb6802246c19838ee2a6d608e2df5f3b82a23cb8fd378b2164574945c08b6fecd19dad9777a26fe385a1ba8d8cc3f0031934802c1ce833939719848380772045005e253864fb44d5a6a2e92e70393633959ef0a41c161a56734ca2f9f018252c1b7987240ddc8b6ccdda4dc7a3a40cf10cbf96e4a7aacdf2575f85aed526852e92511a0182e295efa668ee939dbdc4bb761bf95f0509914eab73a065e0cb1c4ff314e573f3cafa67cc3637fb5699194f1eb3f44ab088dcbdd5c446bc954eb20589c80289e25ce7672d217345c4897771fbb9cbaa10ca5a385c9e781f1bceae67c408cc76b307fdf5cbf984977c2fa4290e0d7792043dc5435de893cd52ef619282fa1ee08e7082c2ae181063c8810c29d68c4e48b2cfdc590d990e1944feb0d18a7f3804058d3cbe703a4ed6941f11567616c8f773eb79417a242c879280a7a08809ad71fa98fb46ed88d93c82b227eac990b19cb7a3e5547a9e5d6912160958ce83f5ba7aaa16659db47ca60751174c1190fa21ec29a3e4f6040fd56dc8b2f6f7241cc268538c22003b5018b0a6c37069a647654254a0c0e55078409740c1b05eab2d630c757853a76a108176ec2fa8c18e6e2a8571228f341c9083050b5ad93abd465d92a42e1b0e5b8d18233c59a7678c3ed026235009557c2b5d28835bfba5ea70e1ee640b275bad8201465cfaf67c302bb459c0c015a14f834c16e7d248d0c9a3844c22c81d97195e08492999da947568ab1099ab74b19d6a9f7a3df8ce97ff45114080f390e016395c00f2a703628da9de9b331e1cf6962c0e4e246a5dc60f01f81f19c33b266a80de13d44b23150b753c7fd447dc01cb5896648236cc50ad20e585ee5712ff61f7b3bba75d9752ee3b7fef42f377dab4fd132bd6ffa425963e3680b814b07b80735e626cb1798a4698a456c5642a73993645f40819c03a6ea32cd35817360eb88d7ad1183f318b48f37c3dcef7cf9366081c07265daf28d4b1991b995d15d474d3ae9db8ccd3bdbfb585769f670b9e1a40d748fcce11252e1a1410bfbdb00358cf997b0f4e176bab642de513e2ee9bd2b3e67f3976a5c6e5d8d15683b9f72b0eae996ce03aa337a983bb00e5e1ce534d074f2d9babeda674dd8d85eacd7679e409ec3b5becceb790d3717c1ada7900baa17bb5de8165752936079b2b3de650122c21dfff9963553872dfa894280ff734f00eb84648c823c28301bf754651d9d2dfe77c868804ac24ee3e14541cde65ae0a7d3cd9f6a4b6753161ebc527aef59625e716633e643cf66a5a76e1aa7f14a3e4b880c435475a4f864b61e13d8ce14899e7f7cb7424d585374cc65533598df71c243f4fe95fde2632340931fd07aa158d5dd09e7d38fbea2a0ce023956db175956ffce88318396ef3966967ffafe522ac55306610f3fdde3e6a2e587f9442b6f0594aed38d19ae6496161fa270615c6a81c08949fabaa352e568036b13f3aaaa3e48b8715e494ad456ea1c63f51d02d9760fce38309bd5bb9b169e0e72bd5987ceb3e16836dae54208154e01f0084ce97970f2eaf8e1322ac891f50c88afe2b2771cfe2287fd35820c647140fd45a41dbe88ef3eb564b098ec45c432f7889613dafe571b4f51118a8a86083bf364c24e5f602069173afdd3c3032a5fb4a249a13d1332264b6b8c52b4017c423a17b2d1394e25bbeba7fda1ca85d4cdf6043e86c6eb67b5c658cc3ddc635b95a61ef62ae89f6849b3b939eede1080d28a6df1fb60260448778efc4a002a28cbb002cc212d11f21b59686a2697561c87de63a752a260ab8298ad9e6d1e1afcffa504e43dd037857f9fbaf9605b0b0f7f7360d2e2f4f9d5c6050e71aa028584d7c632f5abc391b595c57d0006bb3467d1b87f722c27064ac24860579443df61c16654dc0af949c1b41c339736fd6d988834473e7c24ed4f6ea9bd8c3a7a2752dd86f57e98010b691ab247fabe5652b82fd328a55600954335130f756bb002f09555fd0192e4cd8dcbba4a0d3035ce0d42ac055ad6f3c31d9615513fb18a89506ffe6972efb9423f6bae3ee075275968bdc82793beab1d9f0af63da829520d21e992091df1b3b9c40c3eade108ad88ab815cee264603d40b5752e1e4cccf3b98516c5e281c974fe9a51ba906a570f93c0f21e26494f3fe8b24380da8c86ce38107bdf6cecf9fc7d71faa2e6d873513998b24a9d452fb46f95edb724e08df2d3cc801173a00e2361f6c51efb67d4845c997aecda81bca85ae65a44e413c3f1175d7e9a4fbd73b04f5fea47daa40f00ec64e95cf27d3c39a5baf45e336aab283b8f0b2fac96fbce34bb702ce2204921e1a3c7368f632b6c461de9fa5e524d3609b13f8538fdfab3b1c47acced0e29d80ac0b84cb4f33cbe80a1a3146a1822be734d7b8edee2afe1c54d9e1cc9cc1462259fe66a01bec026a39a4ef079ec27cc025e39aea2ad8c15a063b3ed8f25af47c94d3dc6bb8469e9fdfd492b288192613662bd8023780e6a88dfd93f047bf885b54c17e3b974ecfd19cab37458b214904937a68d1976e50af9482871e97e97f4155d7b20abfb97afa32cdb66a88caf716ba04eb1ca044de6fbe8c4607ee396315e1a5c1e1bdc40faa99891e9b3cc708d15c1affc1c827c7f0bf28c819ad45255b0272a8cf1f78321dda886085d958bb08845529e0cda7c563c5f6acf106e982407e6eac31a6366d83596f8bc61792bb0a9ad0dcdfb8ef21063ee017d9f30fd440bfe699a64e1958af259b5e30ff9f15a6fcb75ef7d1142d56c5209befff4d9a44a2cd9fae95f8241efba54b44e966678925fd6872532deeaa531c6163639a9a2bd0d4f9182c09ebf9f5d71e18027f57ac086b352601eece31bb41e3266e5d51fd8af998a8eed9f4e88119b010734ec8920dd66d88fdb39cae2fe4760ceb3990ad7ac3c4a7f388231ef888fa721fa75beff8355b900511120a4d7ab0e51ed48d3d24a5bf81faa59ce50d55e2151d5e77f4f2f3391552777602b438a04e9cd15210b1f4c9c7e53d48d2504e3bef8fd10714f13cc089e4a5157132c7a821c0840aaa51175c9f7cba0b7f331f16b268805d232885873c020fd041379cd3ab02c2413e7477f59f43e7b0175bc643403c24e7bdb67843d69773972a73b01f07234fe050728e979bad273f0e7c75a53fa02ff52184f8785f0fc77dc4d3dcac5094de6a2924bf13737d81996edb5c59bb2af2ad2db85201f08507f40061b0385fb580e1fe8c3692677fcd0594ca9f837243fc1549ae731133b0e920160b88601c8cfb6dcc1580a608e6ee58a0c28c33103443c9ca203de01e3e4d691f98119f90b5692af0becf8586acb38ee9d8572485888e22d2018318ac4b438ca9c5ee1622434b5e13d43fc874b72e58d47344d3918c11965df210275e0a7fa2ba0e3385cb00ae836d9259378feb67d8c37ac91f2cfb068f29fc5504cdb470cd12fe6237de31fb6b9800d357ecf59fb5656e2b58d8f548c579816f0c120a34b1f964e688935be94b90efe0038943f014df94bf021a350485e7747ee725f7b95b300df6b4a3a86e44db6002a83b24e661a5ee14fdb7f92505054bac1259828de9f9e58a10446c472dba4d341a1751df7d307d997857e9c6c9a328dcc2f40f63a5ee0dda372d9b163105798f2472b7d5cbdd27da952490e2b4551de821d68ca8205107974d4e60d946d68a9f7e65d6919f3c6b845e3244426cedbe0aeb3259d6c4a9d5b3008b000c2341670fab29b669ee436ab70b9259b97da87a320f7e349c88fdca9b1b7a78444432a2825797e37285481c6a59f6a7f7c52f6ab4bea00d7bbcef4e4f6bdd7537f841e531c894f90e6c360cd02ede301a3b4461ef3e838b7e7dc6335c87661312809dfef1479a35ab989ae0d0654a8ccd68b8b2d62aca65071675128afec0684913712b1773b800795cfa28d55960b0bacc874ead99453f0ca7e68519008e68100563f681f0235fc910cc0c957c5666d14a7046914dfd13f440a1519c02b3e03575b3beb63904efa1854db459766a84fcfafe611b16dbf78bbe81b3e97c1921057b010ac14eea2cb8356bef0066fbbef12a357c70b416c62f46271968e13d8f99728971b98bf9fdb45f7b7bb35f0ef44d776d1a5dbaf978313a76c7bae5fd75ef79363e12dbd6f2e4f2eba6a135fc8baba2263738a8227184829ae772d1a1ed07a8717d58b0729bde6b73f670511a31690fcd2cf534d7e1c6c663e4ce7579ede364cdf63084ed4390149018c2f867903bf67a7e79391ee95c534ca6d3b961ccfe2d7b8eb474f3116fd99f4e8c49b5118e7b0dc63cc2bc59a521f2c2e656c2f634ba01e6cfb9826d16e6a633135b13c9a6f81b651fa7cedc53e4ba3cfb2e21a95be59376bc6e16f69f70bf9b5f2603a98b181e0c569d479510ea08a6c4c43793646eda580e69fa20c2cccc5e60b00f1d3178003ffe842f06b8f57d2c67967e3d4c2317347a440e76dd9f8a6b50c4ec4eb4e518abad7dcdf1e77406fbd710f86a0b730c063ee9d2efe1b41bdf4bd21da8269dc30aa0499bd19c778eef77f5e6aebfbf3a5d3894fa6de962ddcc4bd398693e5ecb737cdb762759463301ee4e74e0d0224c7b6476d83002888359fdba2c721b70fdcf71564a291bbf58c411acb9ade0a06cb82e494bbdb4ae0c1bb270b108e18d55081f7b37316e3ea6f0e0b285ddfc951518e103e045abb10e2c86ec6bfb66d34c88d4bf1e3edff9bf9be0ab07bc4e5c632a7cd8dab1d24f94795f8591e1deff5d4d7a721c7af7e540e8297a30879cc6060745c5e65c11f9a2fa3c22be5a21782aab203160cec52a48b0f3a4679844661ec7a43d34e9a08af3d4061772aa460bf9657d5c064ab712d2fad2b0af887f7090f3da1237d3bc7748444afc63618fae3806e08b3a3e086f386d1c390b197c7c02505514542e560cf74cfc6d5e3396266784489901284c3a2fc4e102b829362aec7af79b68ad99f957611c6d1895962eed65e83936b83df5a9e2a2dcb2473afe7f37a531b16a8468419ea7e2e78f9ca42062649b6d8d1a8e9a3a92428ed26a140bc98e64a67d469b328bfc541147b382ada34aa575948f8eeec71ba0bcdd08d808fc937993d8c9da698c9af976f66922a045a3dfee3dce5a5d82d149995c05acec8227dfda8c1f8e99e2d14985b1b5ee26506a31739ba80f37916956263380c9a38a12843a1f9ad95b5e85472fc662e70246032da9be6ec6ce126e2d63e3229531be477df7521a3bb8ff6202195ee0443a008b6de142053708bb207c601ca2579a178bbdb19f7998ed86500946bea597a613c751de216f5ba35e823172124b4cf165604a9c89afcb98bc5a17ce10d22c6a7c983fe2e8a3e5a17a62513562cc660885481f905d330d51ea43b3900bd81b101aec55df07c54caa9aa409e652e875551f1a0edf6230ab7fc1a937f2ed4bde598a29fc3d26f62e7f0cc81f1868182f089d3e0e794657591bcbf43f03f77524a97f3b4e927eaa06bdcb04b1db4ac3ac410a81a363ac3afbf4f324af2c25bc9b934ab0e785051a2ac895e6bddfc75f73ed36f23e682066ccf583fa2a60cedb94973c5d87c33f16ebdf5c5bbb86c30eeafc3b76c276f7391de7553376f74f03a000914ad41adeafddea589153b4c89404b9d6c5f1c05879d5ac6691411a7673528a3685118e4d43449189a10d711a0b335701f528a031597641e2f8aebeb00b91a0aab6e6b6b1dc79b81b8bd70a05316baa15076fb3a26f8f68d530d6dacd9e8e76f43792ea1df7c3ef3eed9447464aa01325fbb596c12aadd0b688f3c76b345a94d083773cfc482f5dbcd86c40e09db94e0a070f0dd02a843d6153c96e1962ff03923e5be09d412dc50663256a8ad74092ac12b49b8e0f52bd0c12723e439103848119871380a61a531e45749c2358b42203938f2aefaa338ca5f1ce42b6a963cc72b3cef7be1712f83a5c75ec43401fb57c106bb194b8f36fb94cfcde7d51c8e925a514d3b36d4f54d1c7b0fb7a62f63632b869325bcddceee48e7bc03675e446335ac874c555715bb1fd15305499e23c511f106e7c02e257c70de997eed5a918040a911781dd304d28ee10ad4318af93a9602d9106ff3c9e6f74c76a74914b408909d9ccbe945d4123bff791903e900505e63417134e87f74193828d659ae0b35758acbe73e5a7631c9c72b4d538631c0d886960da2f60efdf0402993e186b0be88cb3a1aa3595b18ce51261a24dae766dcbab4e57ec190228db74c3f3456f495abcab449a106dd17b7c42d234e4508d4745b32c880bd6499c84f3e46f994616d644f4a3c8906de4d555332b6bf8652dcb0fef2289b1e4120efab8b780bcc90e896b0d62d46b0298f2a8866490436dfb5d1de01e7b3c3362780dc9427d4484b86776ee00612a3dfafd5969c315e53425fcd770fc2c07eaa4c98c06e3c9c4461e85148ba293713d764af5fb403067ce587e883c422ef24eccb1aeca560367d5ef4201ccb8c20f239d9043fc5a33c6d5d8ef9d3c8abce045ba08cf0e8e66862c119aeb380ca8b87b4a45bcc4841ea0cbaa0f5218b861e80f71fb91686886d4e2d2d9f154568e9d264ef015dfc3fa061358a53b815affc139b77e5d5fe4c6f1b6d7fc8ba9f31279619a097f1f544871a8e9dbe9e3cd0abef161203b1bccc36d1013167e327c8962f28591bde1290a2d4b4e667aca5c96cdc520dc14a4fa510ad6ae2cc6e917c3551dd268f1c7451cc0e30bac9899ac417bef95cb453d61114f7439aff16a078b386ad9ebfb60437dc0a17004d62f10837f0d62c8dbe53a4e95eb59878f52f42cf76fdbbed6aaf58fd73d31524e69a508161243102fd19e1f136bc196c75d7be357096a0b528e88bfbc62d3a9b0288f9718c32c59e4f947f78dd8a0267570abc58a7f8eaae7b0269d5b466ae4eadf0451ab36a83db8c2d06670db9468663aad0c3589aa0cf94d6b29e74e36b998337b04c9dc673be2abd59e42eea680bc119bb281f084f1c7eddc6c9917a527756a0b82b82695b7b147abf6b0a30208cf8e104d5a1a3f282a54d248c01a63b9dc7a76e9aa4dc984140d0797912522ada42bc1402834e86b9101a18de38e15bbf221a9f318670cba47d5c4b3539c59d743bdcba68bf21824c6839665c995f3eecc3271b2395281ef0c07f803b27a62b3bf573da8eed0beb9761a511cc5b1cd01301de621f1ab280c059070be9206d810610fbca5cf4f03c84f453e94ab14425da72371fdd3cf8e6aa06e908a46c68c2754aa6d6b084a48e46e9b94c9e7a2e7c759c389927967ec2b5b834e0695e70c77b0c620a5f7e25910095d631194366a8f4f87c106f60403a0fb43e03eea59e052036fe7720ef863cd52e63c51b4eeb072ce8b5d0ae9749532a543109f1503c6742ba7c600bd87d532d8d3d45612706050b852677c200ed123f8eb58178757ab85bc04ca5f859d14689c202ec3c3ab5b4312f58f606430b8ad506c72d6a0c83a4d739de4bfb736cff4520a8b6b1efa1e0ed09eee56c4610a8b0384b282fac8f997fcdd4aefd120114d4f5c4ab969a15bb13104d035610f33fd07f7110097d34f3cb31c6a84840d77516c07bc567f24dece5e12cd53d104ce412a3306b0ac12604e8c2bb97a5c686716548bb5c98af61685c8aeedf7b96a9694bd7dacaa1a5694e21be422be132a91963e3fed03e5f179603407926bbc0311b765ec22afe9d6b1900a9a622196a099d89ff5d7df9df1cda22adf21d6fb28978e874a3d6430c19578aad9fb2c0d43cf1c0241ef71e8bce834e8a59d736c1b81a5ebed419d1e5cdca74123c50ad95376bf60987b1633f379bc8755041cfe03c0f6a12c175538f5525e00b8f8ed2b29c7f9d805c95db2cf1dab9ef4a71f183c1c1da91dd14137e0e52f426be503bc781170e67db00f983381c953b8e874987023c03b17153b88338f08d9a87c1bbb6093b0d8eabcc47f13a7227499890550ad4791edaea905ccfa63895e6540754a3e5d3ddde05811c6752b65fdcb55f537e4884ce6f98eca2e43f41b7bfeab44c44ca1881143ee26451f3d43af7f2a51b680100ca5ef7c04ea57cc23db699b8feb4e7413f285762b71297a25f1ebb14179c734008d7bfd9aed7765b4ef940c1bf0e912b5fe5821e7137b93466244e5ac308bdb8c3ca9395df43190f2c619aa1a774f8cd3b2115d44736d66ee402c20c5370d8e4f9a14fd7f44fe0c2b6bb37fad43870984abfc3e7bafd4907ca5e6648fcb2f0abef6b3ca2c25dc3a6c37772a2374b79435155773a25d5026886ec6cd0d8996f96e9433018f771da17b45bfb709f540104e6006233b9b64f827fb00b785efe3eeb641d4a2b3845ffb34912eb85939ea6ccd72d089f4cc0126b41c18678caa80efcf667d88bc5f52543d95bed461638569e4f0098f29c133638c91b00e6743579a89e7ae13be0bd02035497b4471e9867a796bb49fe1e8b760ff1b8c307918288c16d1cf635a824fb8dd364eef559abf1b6d629d18a6c537dc413a0c363c7e543cd86d65000bda0ff2b2720c318b5c48f1589da2a02a4134befdf688cc847a66db508c3ad722cb1ffdfb2255f6f9e6779ae423fcf3dc660f4ae885a9d3c176429e242442f4324d77c33467345f066fc4f1c2df629aaad786d948c97b9d8ccf966fccda172300500d180e95533ee9c59af9a94ad95dfeb0e691c367e7266cf3b84bd81f63c92faee9afb1280d63bc448f61657fff1a18761cdbc3ccde2242253ee12f47565bf62196a91d292f4c22d814e98e7f3e9f92b57f41f37ea6e303713ea457f35b1fe14e80edc32efb3974f033b8f9bb3dcf743b5aeca05837a76b9165268ddddeff51f9914a9aa75b92661ee8a178639c465a422baff88533275aaaee54005c6951923400cbf79ae59a502afab0106d9757adf0a75a35aee9bb77449768ff695bcad682291b1ee99648dd9108351d5f2a19c4a9a100472d81b09f2f402d6797e23c1348aaad7ccb0230baa28e7bbe0bb1aa0a166f0314ce6fc554ce62237e26f4ddf5eb68f7a1bd051ae025ec866ee8099c8256bb60c7aadcd713642f28751d2f8995ab3bf905fa8e086ca008f0576dc0f50998014c6f91ebdceca1a3dcf4ddd8dcc9b04bde7c14ea93234442c3ae0b224bbb3e37290af11f36131c75c6e9bd9b3835442092d565ef6275c48c788bab26181f6cff0dcd3c45ad61cc16fa5687b472ee9ffdd0d4870e30b5cbab039bc9036f2f9905c6375627e9029bf0f441e7468f008fb76e81f8b1aa65e49df9b3bd7b921dad9992c34d5e1db2ccfaf140d8b18fd7128c74f175fc248647708b49ede524c0917a78580ad85e20722e5d466f4148c505c8fbf600700bb94cc4c8adacf03424192567418c61acf45e03c5e5e8ba0f26f129400c44b1ae339f11e3a93ae199735920c1c63a96c9ecc36f033011ee04123ad0e4a948f6742a33a9e124c1a06adb9c7bdb525037e2d68064f351f98652e4c2ca1cb3dec4825dd48ac4b02ec263172dd55fd594123a84c6126b1155bcdb1dd03f5325a7b6e0aae2c9a2f8094964acc260844567d0a04acb30b365be788775f9a73a54c89b586a1af797e4a212585c2be291156aa1b43536f2945e194d29c3ce1332f265ddcff2d4bbf9d2f6a5dba49b405bd05397f440f6826039aae370461617cc4b6f01ef93cc16990673d2b6af2c45d6de88d306a407836a9a0c502e588d0d8de0b7aef80a1a84060821a8c49e75c54215fa9096a12c089808d2841ba865458584bc5e751b0bd003ce692c979bc6ca82d8ab588f6b47c61039a43685c13eae6b8980208781eb145923a3586a1c9d18659bb6efa3078b4fe817182420a1a987ec64fa257b5a9f859c4031021c3a251b7b42c8b772c125e2233b5701dea1db15669126d61fa27fd652b1f8ef2f68bed2f32083901e5161fb8ce9001e069e745089cb056813a9d68a2ae40be437f021341926e597361edd46e8371b78e12095c6653f34e32737dcb9fa7ff887708314b4756a78be91935948a9d3fb25767336e077e99a8856eee956775bb78767896a3fc7a49834fbbd018eb02b6f5da9e67bb9a3cd9fc47ad45e22ed60c1b433f513f352e002c096abcd2f70ceab802d55a99af115faea472258fa7727073f266b5f51e09e282dbc93e87adec84a942c1c921300acb229ed21225215b2377db715c5c1401150106bb798c0bde5f868ea93fcee61b8116183799e2a7046035a1a4b012d9727fece2f93165df497cda2e2af581c7177b8a6c123a9ac7f92036acac3f8d153f49448cfa01cbd1a2d87c92896d493b487552c3cdd66b1b80887b7a48fefda1e1bb32d5d5dfec93089949c69fd5231feccb3c21969f50cbf36419d6576d3f0464e19a77b14cd4461e87b46006cf52d08d04ed35d862d23276718b90a3f696293d0d2f3e2cc9537fcfca09f4fee8150beb6944dd9a138a1ca3d760b3b41de093d50f311de38244a9a65e9cad5f058e77cb1ff78510bae6ae90a6ce2dddeb8d2a26e231a2c9181c044708d0a7a1f1e05d09e24d1165b1674cfadea2c4e79e95a93ab4b15eaa52524ba439af421bb3c9e586eea0848e5b5c3c33766975b2f43b60c1ff368a6152df0cf3f9868a43260e851c8132708170d3abf286c3e6032a086e9c3e32f4eebb0a703c39548230d0415d78f178a05ced8e56a2e506f1b98e4dd65b990086d923691ffb0b184091f00e1f236171f636821a70b6a0210e494fd8424c26cffc3346d88b417b8a389f3fa041b28aab92464cf279b84e58084b4e421b8770236743df1c8f2dd8ddd5c7afdd96e4d50e23d766553521e8bcfdb65661c9d6d595767d7846d3f0021c797981da37deb06dcf5de78ad6a9666d182ba1d37e42e2df5745faef7592f6f4eca8e1ab252585d761d64939889af92e789a8279697cdc5e77016e788fa26bd6349ead490deaf6eac687b330297759139c91207c245ef7dec1e64e1b504920593b9c3570d911376343574d266dbe92b85faab5bcd4579915b7f734dafb6c32498aacc6ded10d3c2ec7d8d4719146781b313d411042bc2ec54df032a929b711e8f59aaa987d678b9d9d3dc0b77bfc22a743f04a0ccb4e9e88a9afad39446bd21de91e53907a70948ccb7991ccb01202610fe14c6fc6976ce63a21643c2d536bd31bd42eba848bfb4a6683b5a9cae5291a35fd0c2a728a350bb639ce09832ca5bea781fdb74005549b5d838af5bd199f3e65ec89f56e7fe090575765ee2a92db30347e571555507df82f78a1aad66962b54fcf9b9cbb788030ca7761b54e7e0512ab16c044d6f9d6540bf00a59c7c13b81e154ea3ec960ad24edc73a3ec83a1f104ed535a32b060ac0bab1d50c0f596b88f8f1dd0e533d609aa44a2428adb0549f20e36cbbb5a9d78b0574dad38b2edd6a2b2f4f155eee59e4cdf578bf00662967e5dfeedd80941be83cf6f4dfe4a19e1ac9fceeda87e0604a8ad677363fd261645e4e44df3bf5fe22a81cad9a2c04a28aa70a217f12cc867b0e458e3e286365d3ffd8fd349b7040b9c02b849924cb1e2ccfbbe2ce81b92b969d17015b017545d7dd35f9a1c80f131b51fbff2076b4c802e59abbd0f1630c8d67abf190ac0e64fb0bfa9017b5379f185096c6acf4f340dd2bc672b51709d78972581de129d847dcb5d67623e3ec20023350cb7d1c0ed120035a79007f2112de0cd4f8aed861b530e3fea630c25901045eb3bbba2ab06dadc237ecf7feb12a52f48028b66329862343d1b054b648ab1cb0c9f179a9f16373e55fa2627ea9e0b8f5c797c861d9863678e6458299cbb22655606bc109b3609cd7c03ba0c739515defe3d5b78053ee117843c93b23daa7191a448860c7d066ca17a4a702c5153c81d84f60bde9e2299327a17301df0d65650e514bd836680042701138a5f77ae44a90f88ccf47bb55313b619e1723537915f3f04d363a8e5738285b2ee85bff92166beb329ece20fe6699b3f03aeb85b13ecef64a0f14ce5a09078f84ab8c80ec56fc23f2e1444a6186e35198d1d8e52d58e0e32a34b83b8a65489387f613681e5e383d88c329ae080d270cca47e307c86978cf2c0d4c13c6a2adfb797f8b99c16fcc0bdb4074bdb148f612df181aae16184358a850052b5de4e57894faad3c131b17386c0e793a42b593e82dc75a2a044ba05b0eef757a3a0be45c92560280499f5b14ae62380a9d2a23c449f3e4dd1becf84dbb4f369d3c1d26d7876937839664439741930db1ecd77b6fc2366ce9bad0724ba2a007875b99a7a4ccd4c5785fee4b15179dc30dfb69b1b16079cb6beae37ae639dc1a8330ce862764668abf1123e34692d8a18663499544614c154753ab42f897324575ff786c1dd3c6511c9b8b57c8745fb3032186cd505b67abad1866b9b87e742bc0df940e287769234aac4c043a2615c33b74a003a90bd62bb8fe934fef2aee954c38be61df7757c1432787ac5efbb752629798dbd662b48241a66ea1d839e5c2abc8d3a101001686832c47174b5202cd73166e5fe87b5b63622ace49a9585ec11eabff50289457d012863dcea9cabd1aefb93c6759b939d926a7dc5220ac8dfc7c67b80c670ed1786ba08c7af2d4ae938e503f4a32f06dba2d691f954c6d4d2b08225d2662c5e8f842ebd87c117e2626fc54312272707073fb16b4b009507f07c14cd59b2a0ae3f96ef8036d681abda3d4e5b6523287675a997745597d514df1731d256988a9423eb896611bdfc6aa08f271c654419e5b11524b2dad1a155d2f8fcea1c8bab0a3a99810c15c92071ca1689ba2a3c75f7aa26378f1e3c596a6ba3c0081b74e6c2fb9f804429172a70dcaf38a104ae8e1a29a4bcebe89c0970947d278508e19c787c07d0524e02a9007cf793db53b263379ba675706006591a154d08db1f210e0e0d48e4b9979d88599b9cb36191b5444a5e7b2eb8ee89f5b847a847d8fb2703cf0047c1df1fa50c938c4403aa8851299c30f5bf809e6521c7d58701f6ec9297e1d477483b5690c1946a9949406fa1df4dd3995280e8859d63fb008ad11089f4311b2eb07c45a82939430a6e0acd86f096a4c89d0df5e75fbea80d0a3b24d234dc2b3296c182c6d14c26e5091647e6635f3f7056d57513dc161c8d9868081cd92f894152a8fda6d90d7969a4ee786b523c240b0a60b97d906504d5840a1a0af8552085a81a29e980a37523a5ad25c0fdc12a231e56f71a572f2c6ffbf8413ddfd7211a2a5d9fac0a1b5242ff45cc30920b65e8db5945295649550892d4c3609a122903ac1cf62cfba1f50a7abf63aae2696472a2180e5902e3bc0010d5757865ecca31190882a02ed626176e1717b40bf1f91f2c2eece43e565fd0a8df7e08f3849ea23f490bca9eb2865fd1b37da2f3a958cdfc72304ba11236b1b399e070194fb2cc8f13a579ba8047a779886f345aa166a978283d0dbb65f0f114cac58d244f3a09ff9613481f05b910649b7b31695bcd3df9b099f422c825a0836b20d47eeda034f668167077ffa89e15db2fb46a9b6fa8918d6da4dc8a302639fb79f945c977f3dac11fc7efab9a45397bd16a7421664ad21140c109e4859122d963d0bdcf12fdeebf53a66e965224e69fb4a1f63a281403ee8ffed384ba3ad7014dc5466226ae5e8b376a515439a8258b636d7243790fecd946c009748e73e7d348eadb412b65818e8a8d101a8d2b32f888a6bd63cf88fb729bb7c868c63a67916fa803e1d2249617a81abb457f882d561853c38f09f28a3eb54accf9f797e23de509a41ca890b22f6efa421e817055d2df9838fc228d60d3b4e3f961622f78bdd52ac232b5b35b83b114c9203b8592769b704bd5f5e7ed5a3d97269ae8aff99341b4cd8827d3925d6714ebd7c044aaad172e433cd83301694e93532af341617714cd6a8101b394f227462c34c1ef65a7f634ca33f3fdea16629ebe154d090e1e84414de7500abbed835fdce108e606bdfe0940da74def081bf69f2ee9c41852696bbb8410a08c7763757d35d5ea6f83b157f22f6be803735a9c9392bc1232182025b417cbda5b27f5409c468177346012fe76caaf2dac5a551831eb0093b88bce8ada67bf7d738b721d99b2f271ba9d99d9dd15527bff7137806840edbb6afd78256913c350326a1c3481c2abbf260a619e03b08b835306639b1911aad689f794bdc489064829f51beaa7d6e2947e01e1ae9a64aee283729754768d6772462aa0a3dd70d341af5fe51ef321b78f652a0ff0310c0486bcbd09d9fa9ad00b1a21f9501bf9c58316added8b2bbc93b4a06da9fa5c720fb87633d0295a3a2cb2901ba9f91a96c8193814d637fb877ed620d414403a8548a9c63aff47db75628c660a72ef44e306d4eba348c4e71c7c025c49cf81ad5095f4f9b86fe0e7d43477115d0b0a599968a76714b8e55814920dbacbe9944d154ac75eca9ff6f523117e9547cebe98c6369edd3addd3d8b8d0d5351fc8552266b4a54ee7055a4ea981e30b5ac54d849a4a4728dd2459af28ea5f8e9acee0e60faf4caa13e12ccda61e740908a926c62cab00132eda366c9a62e15ab983377787e56f306444f34b0c94200f5a9c05d43e129434c07fd8c1fc66df6d192454ead4c3ae53778c71e0d919f4ae7d9f0748c63adb80094ba99113a1017d7aed0807a072e8b1a71b5d915efe7478de22d90f097662bd9a614269295233d3c8ad26ea33a0df37c8de331467edee87360fd4cd5f1d0f6f54902b3e7a875f6a04fb46820c59f680d5b2032258692d97165d18deb22e1245602ef9b156a09aba19ad133e51c028788e87a57d00a2f9664ff5f56fc7fc90848a1e5086b7aa3e1c4186a762e299c2456caec5b062e064d49526a14f1eae45d2e2ca96667b1ee01116ad1a93272a3776e535a5440551c10556b9a6fc120ec5d9a6591d6ef3820303ddb65dc9f2d660e1bf58bb5d8a81e91a3469fdbdbf5cd2b7040c206fc7b790514730bf3e0aa5e67ec37985a7ce84fcaa39554ad29b5472dcf23d207c17964d7a236b0d8326f4482f45d077e9b162e299b0bbfb3b21679094d6ebc545d67bcf109568496d6da06ed8dc6c5ef358252a4a1840a5ad5f0c4d7ba74eaaddc2c6a17c085c266ec4eb0840441c57d9278f92008875313b0f9c04b3149ba2ecc586423ac70835f8d59aba4f9c989032d027f9d615032cc47387129b3081681f4091bc6a1b3f364faebe9d14a61bd99e8804bfd6bc4b3b9b9730ee0db7ec0ff1d8a22fa5f2fd2eb6b7da7b032de38ce1cb03863374d3218bf7ecedd77f1b7bf73daa10eff791c2fdbf8b22b37d3ab5167e0286f75f1521be6febd4ce92ccbfa687542d482fdf23251a19798a474f23930bc52261948204b2d41a27cbda83454b5dae6d490fb60306b5d20e82c0ecc75b98c4240f11f0f759a745b8b262fa6bbf8eb7d1d52864ccdf77594610a572630d9e0ed9f871c5c36f76180d5a5778c8141fda976506991d2587a1029c830858c6d97ad2442947112a1dbf401ae435a81446c4055dcdca12b3ac08b9b72479ca4c4e8668716b1f77a35512bb4ee98657138927425815e9fadacf63a44a7f7ced7e87340ec8ff9dd1efedf7c9881c192a1359c8f41ff9e5eec32eb7de080756b5bde44f17e9f66de8e63416ea6cdb22ec722d2158f512f060032ed8b0d8f4ebe64fbc7112ab1692663ca37559c05c17a6fe3fbe201c2a1c3cd7108a6c715e8d8ef1c5771a023e088a8ced037a168f8bab7ce6b48b61d1aa05e2bc5801e31afd3ed5f9a70bd3fd4c8278d25e6ddf559a015caff8eaec2475040307a8c7c3888af8d03420ce5d71e4ad8d43103879f0041dca8832e6d067bec8ac3103ee20a5ccce39ab6b546e1fe7115f7bbf285a57d21a5d5ae408ed8372afa720fb50b04f47f7644e3058b6802fded8d18778a89db4020a7b9cc192cde6044d2bd5e363693f47f79e638b76075a0cd7b25eab66ef4e7b6f5aada2eb9fd860ccb1ff10766eea351145a9071f35d421f6d06e4673d23556a2e943b54811451b36b8209fafc81d908b44fdaa6000ff35b45438987c46f853215cdbde5b74a2743c1b82649491cf2a6885fd2e76b1f69f3973b06d24cb3b140c6ff62ddd4f466d9e394309642db6dad8cd313f708f018881b53ae2f57f202bb2d70cab654630b1acfc966a3cb87a5346df5415dbd968eca78a355363edc503dff0c1229b8a1318755e122a3ac84bc273da1ed33171c8e78b3f8cdbc42be982c6036ed63401b8e21cedb6199c1bfc5d20511830eef57b636493b78c81425a85ea985be7b584cc914a5c11e4a92dea29a2db922edbb4fddd8160d60a0ecc3f4f31e9e393f18710f05c272697905f00b429e2b369ff2d15344c6a1e02442ac583c0d2d1e04e52697f3d59952d39c0342fd09d7536bdd42df2112c5f4e661ee5af31432ea12bc73f3e36301f11a6cfe80ea3782fa988ede35c1a88869564970b972e2a003bf2077eabe33b28c37865bf323fb02bcaf6e7e20d58b3df0e96e38cace6e79dc0786dee70e200ef7fbf8ae171c6587537b72b16993c29d35f28f24269b46e083f8206d4d6986623a7a26a36f29a3e115067a5030218c3066839491fcb015cffabbb09fb505f9067057f7bff7d1332220644a6f14b7d6df1b56138d714ec1263f4029cd4253b0559792da586c9675b31a02b6a5b15a4bf4e955e552f01a377832cd2c56b7a8937426569a9fdc2076e707cce33282149faee8df2dfaebbd5786ae3e769ae8e4bfe8834393d586a0cf3e608551ff051ffcbf28526f5fb6c67b2ffa1c7bfb1343eadd97930a5485321025c9db16d13e1521f4661b0e2b7892b9670e960d7886a6c829792e3b19742fa1ee61ab1c38310aa4171aa99a1c05ff33e14d423e0a0f754fe2425285345a32907450495388047fdcc5a6141c32067d5f39c93596f08efccb48b6c5c07942432223fa289ad9871884a9974e6b405783a0f05392e008d0eb66f6106db45441561df11d12ac9fd095d446afcb977d664352c73390beea618cbf0a86d7b2de2e90d5d19e6f59aa3fd9baebb495c3b7d93fa876aaa0a41136511682a41f0dd38ade123846aa099429d1cb53c7bbde95543bfe321c346ea2581f9d51700cbee9d54e611ba985b3b5a598f43ffadd5b8ecec0701912e97290869c67c515103f370e83b365250def0ada58ef6993f3154330f269341a60a168255d70aba3b1e0e2cddf93f33861760aff0ee2f2e20f169f5e3f7f0b7a6b29234d7de4c513427042db2006ca74518fa2a0b42d4a24051270381072527804ecf964122e5946865061299c91f1d46301fc6eef16facc9ea6f092c951bf48cb936c4c0f5ed219949203dbd956338e42c669934400042078188c40e23957bb62ed3ea331bb0e47cd209054c4c2dcad672def4807009969de12083910a8baea698319c98bd8b60b76d49de5b6852cc2421b0cfd32dc16a4d66004382ce171908a088d1055d13c6502d08b271cfca2ccac54d9237722cc33298acd557404957467fd5d8af9e6b1a3bc783ee4de908ff7e51fd350a9eab6ee0c0a5a361a008e016316c9cacfa2a20ab363bb4b7959ddaa5f124285c91b1929349672f09ff381017db232b6b0953346b79436b0d5424ee46b4fb276a6561e8fd1eba36da9a5ef1da9afb9a59d8c28adaa5dcccf1d285c10571bb51a00cc8232ec4949e324a0a32d82c299af7a267ca35d69cc1368565071097bb02ae2589c6a4479d92769957e0b7f95d1134e171df55823d0c76e90acef6d2887c201fba7414f0fa624d520a1f854d4b6495f8ca5be04ac7711fbf7e096edadff6d99fcc254401cf84db603b36204a27a06fe41a9961e1d5dfbafb322b5e2f2ee9b2e44ae7aeabb40c7e7bea9415754acbdccba3577400ebb7413f2009903acef1b54c940def66b7786c55dbee7abce22c75f2689780e5edd420a2397e95fb63cf30d1276de24a3dcc91219650822b92187effe31056f9e54e71b2ca0ab27d5dca6d7a1dc6618753d1193bc1de8b5c8c50af580d122b91f41e21d8e0bb6a9d002eb049d4fd774c021680ada83783d4eac09c6abc3a4753c6f804e85ae832c12fc789e5f3ff031c18fabd908c86508a11502fb4a0e904fc1d4c337b999fa6b715a6a60ef5f3062b8c09442ab1336b07c52e7abe1d279bba2dcb71c70849adeecb37a5859cbbbdeaa144854e0f2332711142a81cb17e636af5c456a57f49802c6ea78038f326b506c116f971553db0af7d62380ac7b4629646a89c1743f62aedfbd27212831ac8d756819c3941ffc21c59ec639a75d41840a2d55d808b75917f65c4dcef87bb0d2bb3aff62c2d758cb958924976288d44930eb0bfa51c146b3356533bab23ac960aaa4ef52deea04a2358e9f81defe5213909d05e4293da2c5b5e211721b1bd47fa370fe7786270a07c3c069a9e98bf20e5a318848e527b6d6511981d19d60f8810fc85a70876e6991196328b54a4574d27d0cb4d16d12176f603b70c46d5d33bd6e0e6682f79ad09193229fcf9c1747c16e0041d45d77d2bbf35a49775481d4cbce302f80f4cd4508b6a466e0d13ef386263bd4197a6defbcb34c5245576edbeda1f77c05aa07e68fa3fc8f0d68c50c65ef0a952a15ba5e4fc0e20a6a96a85669a4e86400ffbf1f3a3af525c9d59e98e8952783f0d30d3a55e64730019c5d1c154cc97a8fd0eae9d047c547e054a84ff8fccac345961fc3407afe5526ebcee2777f166f6518536d264765c38f12757ee4c5caeef632edbc7aac4b0ae21a10a7f4b36e443ac4a95f223eeb9a3f15a85ae80ad23b18cfd0e9cbaec1f812df7d13383e048ddccb6834fb177c72974048d6977b4ec03482d2dc1f721642031f230fe8442017101626d84ba1477cbaa3698eae40709ce2fd79c9beed74084c99020b4bde94a868094419328a04e3d294fc5112d6a44f4c929e1a69408f56341b321c2e839e2e1d42f3ad713822e27ff27041bc45be05043f3264ae4472e973c0f01d5e2133aa02776584f2cb0edf152df5ba39e39ab900306742c42ea7fe7f3692a5d8b06f1c9c59f0f677d52c3e55f6661f2cc6d308e47e7a007ef9739132eb4a0afb60bfdde35d7c67087a87677d5d568120437a0f29994b79c75a22a752542db469bb1c4c9a0de0e3749e042ae36d5fbb5196538700d1f4884d83d6bf9b250adcd7bf0e89c02057e656154f0a3070c85db69c3d1dee29fcb198726e54e2a58faad9afe02e8dc5774fd614a0761f13c89d7f3875ebd4895c72386abf3e883c8ad0b2bf0a0a648a1bf3b7f0e20645e95829f2213781ee0766ae6c7d6586b8540ee4f99c8cd655a673d36304c59b7794317948a9af2deedcc66b87042140ac0fb33b47ba95f78a4a147e679f38203a4764264c0cbef7b07967d50090c2de6f9de9d39a9b3820adc7c059945d3775e90aaea6340dd5e5e444caeebe572f25ef0b3eba292335c0757e1745749cf24f1dc23e4ea117596bb6676c6a0859c670319a94bbab076577700bd042ca316d25645f8849957bf4c664968a0995449eb735d7ce1bf9cd852e45f196824f6670bad517f3d1efd2b8e800cb1207a5f8702072994a504a9832126b450c251db7a0c69ee054aa406aa143f9c467e872e751744bd72eb9e6bb5972185eb9930c4ca4e8bc7ce2b39f6c92d1104cf9857c2c0762a81c4f363dc5d16ff23993a4d448fe4c2f0b0d3352de4d1e74b5bb3b36d989ef6cdb8920b3cae4995537721616aacac9bc2223c698373843350249c0660e176f0d4eeda1875b249033d4f27584ba557097d092d8fd3711fb60d764529a92587e89aeccaca41fa86433891f0aac95b22e99a3ba34c5bfb051f0ee019cf6c3f0559b62cf88528a80ffef640a9ad737974afc013e140941930bb4aa0b7afc1a3e6bb016c1902a06a616be7a2ebcb73672ae44b82c71e76785ee4f5fef5ba61b612590ace7b7a1f5a6b6eb0c19cf910f3a7f1ebc75834275711a14119473d9f2445971df5f849780091d62b24f360e968d0cde95be78b47402004ab02cc9e64c2cf0910bb4d1669e7cb8a2591f0ebe23c1cf8074f0cdd9c39b19355d6771a42e591f1426dbdfc5def188cf931421886087218266318582566d9027e7e4a3ffc928754ae147f26cc23d6828207aa033b43c33342460444dc68a34d92764e3a761819e11e83810e5e8c4a7d8f53173f86a0f34112212e11a9d57cdc51965324da0652bc456964d260242938c0c58db7fc38714044a59b3d4b4b1a41029be1164436fce4040a846bb8e4686a84dbbf1ab26b7c43930d80a6b3e34e461a670fe8970abb80c9198b0f0ff5eb10f60572944a5a20a1583448adbe90ca05391385d09627975e6d3636fbda76519c647547b12079e8e5890a1a5e5466d220fb6670863b8b804fbbc154857b9ac5eb4b5f8b7ce57271bc0becd0706b8e381ac1b25dadc4da8d348dbe1c29a10291688cfd89284e55a957d6ea4d4440be63982120b85898aca798553b00c50d5cd69bc512ea4064a2c45af190cacb6f8c7ea6fc2242d47234adb7861696a2c6dfca688125b033acccbbf15b2b665211389c373d921d3398f09b01dceb039e3f221018320ffd3c1a9b183f1f2ab88e804e0b8781a3d1b12278114e58d744b96dd9c54a9f42dc6e6af397a8c7edde98ea0344646adfb3bd2071989cdbdcbf018f2eac62f47d900aa4b0c3dde406f5bc1879363cb5ba592004fca1adcec3b239106d8eaccde125ff937d2288df7d8a95f075a7264838565eea004022c99bae261e47bc40b3b5eb83c4a0a75e5a37e478ae9eabc307e40d234e9fdb3ea932869e80c9b9a2a0cbd12b8b720acd86a512505676627210d242ac8347d8bf50c7a558ecbf7472e4a9eb2a67c1cbf533ee81892ef0022f2d2126d6b5a42d0152478b172e42344b1ee55da21f4fd82ac9beb66ee264ffb82acd835c598e8b9be24edc482c1d19c1b9860546c532ecd9252bca20012e77b0d0edd5fafbc4bffb4aa738e36fc2040628367d0a1b03088320614535e074d3a69d089567485b92b79eb50597d3b76ceeac071b10c2bbf999d31a31133534d3e4c5f1d204003254b51b161a1cd13cfc094201dc9d74977146f2676f68d6aa6270da4fa4cdf4a95d6c64a91ae8ed9132bba58f8303dbbbd54183c8f5691a502e9f49c55d7113b48db972dd4d99b46e845fdbf8ea8f1c9b82e4af6761cb1cfd4cfe8aa8a441b4988777f30ba1fa7dcb12b48041cdbe2b7e378d1c2307b01678eec11f2cae287b6e4e0c8f72ed094763251ed35ac903fc14253f63f344b1d4a31a5bfcce3f11307e1c5128c23bed3632da95f879abdd066ca7b3d7719c8b47f445980a6b546bc29c219507b9a0daf8e6e1f8333ca733c0c99b1e5ea48090bcc40328e526ece835add38ed077ee518f3932d10984e36ded2e646f947232ce73003e892220af241e3984175158114132468d5a360b534c5a69e503efde54a3684a2cfac9596d69562220723acea5ba39547e66d3a91aba498c38f2e6397b716455541ad0dc754e147135e238419858826bc8e5c61914815edd1880b23386e619daa85c3ce7d3703c32f45ea0242fbe1d01239391153a418894fda3f4a05eaa0004124da06c19657f18678d63d28e6ed807655b42c495249d0e748f2f80238e8fca6687b4413e6941212d1b001dfd6397c8bfbdf2be85a1adb1f8cdf71ac8dee0f189f33f59d44117d09d85f8a018894332677aa8599fb17c8f690ede161010ac49271e16179074c440615cbacca31c0023b481ec5ee4f844778534adfa851254d0b158a3245562bbb0520ff33c3c19ea3bef2122bbc4abeab0cc3794f93a1d69b10041a514b40534b705611617ca1143afb75de9d8d68fe73284ba29c5e154442173a977ee380edc32c83742f3a3fca861cff9d474806a29cd5ff61bf60c33c42f1b5914c06e8c3a6f202fc196f75c5f2ec6bbac9848b728e730f5b58f6a7ce9bea71e90f721e3fcc26026b34cbe032211236d1fabb29ce1d89b35f3bc655155e4587e6f04ce540cbb97cb8d94814d17ebf7b065eea08125a35352aac884c60be1015fee6f001fd57985be1459f08314fe1f875660b6ff096a28cd45cc93eaa9b3fad91d718512958788fddf6624483cdad7248f8e8008abaeb9731a1ca66304824b69ed02a11ddeba860d08d2cfb825f94b4772da9488e247ca523ba2e5be43c2809deb8c4f082e5184d6d0382ef2e36a8f3ee9e7a3823480553317c3809bf011fd533297770e856c4fa4c8e6c582ea605caea30a7cfe5105f7cbdf310f83dc6cdbf8cac876f74b73288e81ab2a34ee50baf65806de08d05aeb0edfca43ae8a88e4b34795d8dedd5fdc845b1817e88c802d0ddc8c92d0145c8b7090f7fa1d04c75572bd817add98a99170da53bc8bd1a8f223c83ce14c671956ce4615736bf246193eba43291b5574dc2e4327b9504a5eb66c557677909c0af9e0960e7d7b5cc7472f26c8bb9f6618ce5a870c7bf73298df4de28b3db38ab07cd4da56267097cded3c0f55a8a3ea6aea128cd14cf3c457a34f5a05b0078a03170157f4ed97c18615a6240ce3f650f40cf3cce84d24e5423f5c508beeecaea3f2679d53ae6e9449cc731f5a5b0b295fb8dddd6ac86535f1e52b6e855c7056338e9dc9d907d904621c269931b59a3b26529fd7e7f3482f84082d10fc5739d3d1d16a1e465998fa3b64f67b95abb9f222f722a2ef28c1f139e12f6265c809c3d14400f503a524bb89ba01daa174b59d79faa7d4e809b7aa4fea9cc0527e610c13e84ce5380059c64796d70c0c7f859461ac1b0d55b464f969fe3f11aac8dd2daf909643802d9902f20ece249a34cc82542afe6cec71a325d334981a4e9922f743a53331d8e520634f1f6cf2234338487e9beec3343242150dec47d9bde477d6a8d26229af131f93e8af22cceb26626bf1e1f597a2642e9e89c76806e0768c36fad86f7f1370d4b84967fbc85d0aa696c07cf2f2a704070c834414a4c38e8c9af9674066961039d49d528251d33f74966e990260670ea0f1d63322bb833106b1676898940e9a47aa85a707a288ae6b714ec92140ce35987050744c4da9b31e6692726ad27f2498e33d5548805e9966cba26993978e900424a44127faefe34a7a7c8ab2382f3b293558a2d13fc733d242beff18c1aff096732a95296225a8abaa54741450f05c3ed182b16aaf1f5336908f66b797fc7d66c2bbba60e37173c68492e67e9e066f3e30f3667d506271334d52f143180ad186be6d5bd667b6efcd9c140290f5a837a3e7c76a061e6c67f302df2125d868f5d9b36f33d58137843e58cb2c29e3170ffe0e77618b1dfc2e1f1b7a887ed5280e6b12c7133d0d0205b1c9c1bc68b89c0a104499440ff5acc4e89ad83730690e38cc74c6a692c46cbe4579f2398dd77816a0bf78363202ee9dd96db880b4986048351476794c29d60a1312247119a3c31ab1226bc865864e01191e4b99fef7c088ac14af5af64b2c18fc868ad279752689fb71ac63936f12bba685e4b71c7e5218b153316f0d7c265114cd618da57b3b288801521a38b26b4ea4f4a9fcf07261b1bf8b6ef2bce37c1fc3a0b4d7bfa5794e8ff3174626ffe3ed87116072227b8bc707a0500d26338543d562f74235fa19a098baf41f45a747842fad7dc14dd5c8416917d71fc737d16ddabb3c65ec7093707155e1ffa90cc8928e5f410ebcbf79cf49b2e468a16119a0af3799ec8b899224b45ed52921be44d01767dd22b27ffea362e6eb850f1dd8c495309361ce4a67d1d8e718a0183f52430688c3829f26314d178a9dca21490d141df3e9423956bdac30c370f436b00488c12cd31c4ba9f9c781400ac2d992862a421c26b29521f92b5ef90f6c16ff340d79a17fc8d3d23d44d03e821162c416f9dd469d20ce2b9ab57a72b6570b0c6706481ca33645cac71889f895e7ee77cf3f248c9804eebda606b1cf51a27432390047d747b2a70956811d3943718b7d38fa9f8eb3f6ffe923fa8710140b58def944237115d66f361ebe2eb1e5643738bcf689f0ace66ee584ba5c2df54a2108f457198ba0b25e9df96697a691cc7e996a4128cb5dbdfee7f83ba0fe965432d7014cdd8eb78bdb59857a33ce00b9381e9beea4a245d00005248dbd037e45f0d81c0d967b703f7a7316fea3d097b395ab894ab7db1326a32ebc06d85fb83351113232ccaf79fa6b51005c22a2fc497a1abad27e1b29b25c309920abff357404913b3fe150429c20e703580c61af7d2d9245cf722987493ba9030139286f7c23e7b03e1fa36028c1181d5df446061ebd1d7e7496b7a3369d8a2f6c9115802a84368dc46e0d17dea7750d6d588f118f2b2a44e730f9bc191af7a133a969b656cb9eb57bee54f41bff4c3f723267d392495764b146b31df5f43ad625ac25188f8b73521ab07b3d33abd6fd04261cbe110ac52b7bed057ab063e7bd83c33b8b4cb37397153a4e8ecf39d3444cd99632f33215c42741b03b23ee4f5d8191503d42d70f3f64005b88e530aad170dbc649d3782bbec4f1eb44d08645302e4b50fdd8f0e48206b91ce7b4069f715576f64401a18b66f9301f6cb2fa7fa6eaa803914ffe563f58824d43d7274ad4ca93f0c09d815687ab8063704744426dd0a6928c5bd4fb5a62cfaa95144b618e33ee1d39f4cd4b1fd66f8509949c0a5759d00f00f05fdff0354b52cf4157e44afc916912bc90a41dc1800b8b6ab7428be7a62506d27190d4c00e7af8994b9c59546100021a894a9431f09d135e0479ec24506b48284150ecd160d84bc4934e25330c125445e92eab7fdd9f8e90a8d2efc7d3e2b26e11f4a45282bd2fa92ab87808e017069ec0f57dc0a6edea0005c506a0820a2ea8436886cbb6e44036c7bc9c4d64fc9e4b8b20c5de14d6ef76d8b56fedc82444930f42776a8b6911b912849cad96a1c8b49bf7a65152ad0ca947c5fa2731677140415fad330dd3110e0c06c1121017a97ad0a9f462bd6d8078045273e08f5aef85d40c397365af87f7aac4c921f0a58de95330b50fa5b830942e847dadf0def84a85527483fffcc0e07fb6a0d6433a05e69dd6271412832a8f6cb7ff2b126711be20d37338ec2f730ac17fc507a1710e5d0804e1637dfd3ea3b334cabf7ef73ff92ac06d25a79ff7c568c621e1ce5397040ac5f271336db3ae10146e6092802d1b4fa44afef373d71166c9761be273ae375e469aa1fce49a9b127a187bb7b1a2c291ba020319855068cfdc8f61ae96ea746800dc184cb4a3e5d8e12661707c4671da1081e22b150c09943846337c90f656ca95c11fe34c52f1723eccbfe2d2a329dce9e3e341974d781fd327b3c7e061a6034ceca28ce8781c695c724e1b15d2be44f28527c340b6999950354ad62dbc189b20ee290dc9c133b09e89938c6da876924f14a22452901c96a28c9e93b9aa4de4fddcd6f30f1814638cf026b258862c997de8481f6b56913381a9410dc28f416ef7d3ac2521a6d802c17a53fc24801933957015cdf030af802955c30da15a70365509f835539fe1c56cc348760c19dca557aa499a25dc5aef1b507a31c165d01515d169a070a2f7cf1777a5f8d0a82b480a0bec85061cc06d7ae801f048f3887efd746a9c451542b3e35215bee2d775bdb7bcb94a494019509510941092fc82692e578ae56a2b0b285e5cf04ed7745d850fef8f70bdf3f957021c24e2673156fb84818faf1cf7819cfd223a3cc1897ef16228dcc2b34c504764b0c182f002b6c287f461777d86a9ab7ed60effb1b6919d048cbc41a6de886172fb1f3352ffcbfcb0d65beefb27dcfc0e1ccdbe37be55f09f6f36819f9d3327088cadcb7448e43a9e0d0e213c66109879f3f1c82d95f905ec815ea85abcd97e937b47962d1e3687b29e05be4fe7a2516e611a28bbd0b37d638d6a266f38cf92591d267e718a359ffec8632e7597b68189c207d1b13a4efb58786694c706682b4878661b216658835281d226482f4b5b0f4c3948df6fe3b728843db07a43c7ab025ce0f7ff79eded2fb3f37363241f789e35fc469b47f76ebda436689634cd0bd719dc286f1f52f08c1869fdd7d74e7f42013f47ff93ddf85724175727339fe96e363a376e227cb1cce57047282a5d349723f86bd7c0eb9cf2813f4e2f57a45d15c264865bf1c9aa03f99607b90b75c0431066682aa48d3459499e957a429405c92fb073b3f3a6c9a9c32882fb3098c15d6c86c39aa5b2d335ff1a55fb356661fb368de48e9d887fc35c1f6974b94e9afea437e4acb342e857dcc3e84e7ab02d9d005e3c1862e573e99600320e3c89739d61e34cb973fa3c8216f656fcd1839755ac67bfc15f40a7a05bd825e41afa057902ff1d6cb5ddeafea5f805e02d332b38b1d1d66155a256482ddfdb58b201a2e3346ea783c9dcbc627828d1f270d70c8c687a9c28a7ed3bc0a3b7aeea58e639a1252a765408a4154ee9b39fd3fbb642257ae448cc13ec0031cbcf2f429c13bd32f30db948de54ed5c2c60fa58ed466c6648b514a29a38c314a39250d369d4cb160e9c71c819a10ca320335e1522dc9f4a5a494650a560033490f99bee90524acf4628220fd6e07762e99313dd388192355ab48a3d332dad39f3b9d096c28b3fcd024caf1b31cb51a4c58ac0613b60613d6b3be22bed00cb72bd6a00f638515610d83fd4263c786a64c53305ed6b4458eaf2c71cd225555363465ba837e6d820de5d05cc51af4a1ac70615ba85d13ac5dd8500e652a87e6d31a4cd86e26925254a63468465daf4c3f6c57a6b40613364872780126ac9c53ebb29735e6ecde20bfc81946575c963e465128f926d7114161931f5dc276e51ec518e7d08e0f14534632f1992978cd95aa09259db962d0d388dc1fa7c44db0e1943f5ffdd233c99c3b139c497a10c01136c98c9152636526fdd2dfddddadc404dbceef7fa108cbcd2431471c1ce1caf27a2b4ab07347c70b1b6a53673ed165b942045bb5883f63d5115fba444a669179c1fa850d6d1f8947221588c042a786fb4d24128944a2c7ee0d11940016713e4e0c0be95a368c544c234526e893b3d90db321332694a3d16b5366fb919021121852832962d80d45f2e845d394270e8be4110e8b88706875cc0f3263b4ec3d62df3f6446968e8e0e8f9829c6f1fcc5175f642143ea4b9c09766a6221352b5f582345ea900d63cb86203f80d07003a805ac9a79b958b51d2c0d338686fc39310a0bdbdae4806039973d6773de724e1be71c5d21673bc5324de44d45a3ad1ddb26d7b433dab5734e33c7a8538eb39cd63393dcfcadbb6763c7664fdaee73ce894d6c3ac5de139373cec9f59c73ce196bcf66674c15551c328da07f46330ca3ae65ed3346d20cc48822e81f9d8a2c4045d5c6b3760446318ccec0a6e4089482259cb03547a01410c1450a3ae0852de508c444145315d694231013ae570b66060503c4448b89010040e3929dc61242466082032657408109508084ec0f323183ecffd51c0ee34e5d88d215a250032b308187043b1810147777b735877b3507e532f6114a0e40c65e5bc2878c7d577360d6b11c6ca0042a95ab3930093ef6a819234190310ccb820f1943650cc3300cdb6a0e8cd29f2822f7a42508398c4f5850489082127420fb5b54097ac8fe5f8227d91f842922fbcf2c91fd71287185eccf6388ecffc3045b64ff203c64073a410fb2bfa8e670af08552491448d24a6c8fe1a129cb32287a655100258e520fb674f00410c8c09f227875c76530c171a3646d005101240d4b3c21184600416d9818eb8c1088cc8de041f021152c85e8422a6c8fed60825b23baa066c9182096040850d92980213352e45f62851c89ecaeeeeeeeeb9e4c3c4ed0739a4310414300ca14511449c0066094cca4a3bf5f440eaf9312981c45784ab9403226c0fa98a247a34a020b280447744cb1e51441d22c86b620427c450f764045b10ab0a240414921811b1c30161842808d7b6022334136a14797c80443683112b11104f138cc06658f2a3ed70023a0311aeac8911ccd033d48312cc20440f508f138a98a1889d1d245c1b8249bf446d8825829881a7498c1cb06009ae172c810adf137ce08155c9510aa1254a2210aa014948680a1311845c53080d49c18410bcaad0d1b23fbd37f3cefe98fd8ec6e1a48fe50cc58a5348c18bec2698d47cd75e5ec186363f08bee6380517565cc186a8dc42f1580c6bacbbfb318f31a91ed8d3a738e61845f7c70d62041b462755b041f08f09562eac24c2e54843c4eecc04a58cb586886598a07ca98019034e503e8d1eacfc68e7ff8c4945ec59735531b79850e4cd1bbddc36f95b0e5dd366b2864393267a0c6322ec699c4de48d8f58ccd86f91373947d786126c187ff2e441c38c315868238f64c8a3d168f4a39f339037641efdac394650e4589dbee7d16fdb633735fa98318ec70f2d32232c511fbb4b70dcced77078747958c15a6d82950b7b337a77f9dbef90bf7d4e1e92472fda760cc9e1e8b5215984ca199e339030f86337f4dc4f33293cd0b3459770fa44187146e923818001f221e8913822091bf0a0822b86bac07cd045169cbbbb5309848cf9902463184a72808b216858cc188661188d34c570a171030428c8fe280e64ff0743d082ec1f7b7802cc0e6dc26a5042405bd907a06082211f9e1f865030844d1598e000882636566001f52084216c865ea81a54413f5a820b2ccd510a2dac909b48a145143a4fbc78820b0b7242e17d8f630a6d31c16e62c618a7478abb893987bc8802806273d7840da713aa84747950f782d8f1d2d5a54ca693551333864231632a17b3bdfcfe6929668ce8255dcd6eb5ccfc892f437a263f4159fe860561589053e12eba439738141fa23ab40717f228593ee6930906c2861e4485bb668cf7f21dcaf7f261646127abc92a95bde7ec4b37957dac29bdc328c2b6ce1c9aa0d074e2dd94bf4cf9462ff56629cb6f26329b4f2791dd93653791652fc9f23b8f521df33d3c5f1394f37112369c4338334f8c53d8c71ad2c79711a7b0f78c7d8cc5a9f832c747402a620f722ae60b4fcc82b0f23fd38f38ec1d0eab3922d668134eba276ce8411e3463a28f99ea111fa77ad09b7efa3edecfeb79d60b2d42582f4f4a5be04cab65680bb75a7485698bae5a7445e94a47cdb4158495ff0f8233082b7fb644a20edb640d3db9f9ad9353ab5320477f86fd98e0122b7ff32bca5ace329637da77667a65a8332ecc64dd79dba8b3ba556dc33f5e82ac6c1970fbafda8f58438e46598cc924d270185ddba6b5ccf6117b94e5b84a811cd9b7671f6b46388c41221c46bfdd5c6717c80483ea94d1bd73acfd8834b1e3dceb8fd8fa1169a2686e5d6cd125d4e46ca759cc32393b6ba758268a22919c2dc2324d34e222c7c9d9dc881b6d5ced6cb456ceb6d2b31fa9748aa7939c7d8a27ee942251f4b542a150572aa65272768aba9458f52c51a9b02758ebc7098b9544071bc2a2602fecf5840f1325562b29650625736541d993ac85450c93b3b1ac25676bc69c66b73ba558e659d65366ad438c114570bef427530645c54301b7c852ce7891258e2c9f2694f5435b412c168bc562a9542a954a455dda1393ba5c2e970a0acd899502f5244f2a1c5b148a3ac5324da552a95422eaa22eeaa22eeadab85abbcef3ece7dfd7537ed74475e88eaa07a44c5a412ea1178bc562b158aa7e51a9542a5513d64f8b0671b5f3582c168b65552a954af5a492c9743aa5a4a894bce5412ea1d7d06ab55aad56d88bd52f2c168bc5a23b54457be88a32299956abd56a754ac158180b63612c8c85b1f2fc8b5a810123958a1183a5c55b5a7aca16525e694cac0faa09e83faf219dd56ab55aadb097b7b0d72bc895e70bbd865660ac56abd52a85bd5ed80b7b6196161932feefc5337cc68c9e72c6f7f21defc95a596be52b10fc47a19c89fb781367f94f8b8cd56ab55aadf2fc1917cf98e1e2d2420b2ebce02fbcd053bec0ea20974ed67a81e03f0a65add64356c766d4ceabf2f4d1d1741e672d2d6b65590bcb5a346b7908ba6c2db8e0c2923cff05d50b9cbc1470b0ee903b79fe4bdd21b3962402c00100809e12009ace04e77bb9559a4ebfb0c0ef9f0ecab35d51a76534cd8a7088426538fcf7d174f2fc16341f9fdb651c2dd39a662dca85aaa3e66ef1a1455dd7ccd2aa56b54ae50a7510638cd17964ff7e183598992bea82125f0dd298b9414accbeaca0cb7be085d83830cfc810696417a394b2a38dec3264883494668961620d6d003e32f6f145fb7ab51f19dba4282e21fabed8345f1c0bdb8db9093aebad5017590882e0fae2871d747cd82104408882083f580f4480b558902487200d212674a0092198780089a01a2a601886f90083128228428b2754403802f603ed89122770028d6c61aa0be34094d2e5c7dea40f92b0c5c4a6df5e8c7d044a6218cdc10d44c0012c8a19e0805601045368a14541870718e10a203cf04512be18029b02c807095b8e403e4fe437a635172347a01598404a391b680537a094522c5b41502a47a015088d389148241a6d3d260e7cedaefd357eed6a778c78023602f938819123900f93ac32442bc2081727251e582d47a0152c891e821de4073800b4020fe4ce5c7204520116402a70bd400ac92679f3bca5bd7c42dea0af790e71325186290e1b4b1850f9848481bcd164c6b4765d1e035b5e56c6097a8481c90e13250c9ae4bed67740b3df60b46cc04ed1f7f35131de72cd35a73d372dc78d6493fe518ecdfe0eed6d906cb9db3794a1fcdabd9793e58dd91b7de56ee892478fa3b7d148f4ddcfc67c59f962c86a3fdf84f3bd4f99d82989616a6cd40fd890e3b09e27624bcc124d1126ce25306c63be440bb34245cc718a278020c792c89a28d8a2cb125d73b32ed1bd00b2b09f9b9b55474e761ce6dc24dd7fa2efeef0354ec4efbac781672688d339f64f93b540b17eac23292b8ed2860d15b47234428e404e44c9404e40c9a2f72158ecbb2c2ca6058e96f95e7e101b84cc188ef4b2fa40a2811c5ea0636b5dfc5863c631637c19565c1647c53355902aeed2f083f4ddae39e2cb1a24d6901fa5ec9120385fc61616a17cd88fd339a7c37249cdd15886f1c765e657758e90c082126e3ac0ce8b04a7035c4185236a8e9c1ec9b44211a200c4e4a1428b13d0d0a2e688094720f0a0e688e991481f9c8024015cd4943ea7267e8b8e65f9c2ca23999e6e0ac849eb17ff139023f6736a60a0c2a6503946f655652776bff260e763c1ce230850810e4f6a901ca087269050537ad33d728a410d1213133525ec446f224c44aab0c7308d097a868b0c913e3eda95401596f4a50fa310672dc7711298a0c354614d7ffa212d235599f5fe8909fa0f892ffede7f38d4349cb9cd307b4329c6b289cb27a40fa5da67f471f47c7a3b7f1c93fa907ef137dd30522c77628dcc3fba8488de47df5d9c39dab2107d0684fb915d9c2297c804fd4777c8f522004d58a992467cf60830e114fd9e1993e1147dcf144b95e9ca2554d8cfaa54c6b00d1e8348ac2e075b74991f310b156c4b1b13941fdd7718c99afc6e68247fbf611f6db00f8d3ce971b4bfcd7cb7e9fbd1d7fcdd66621bcc9de23007c72469da26658c9f12dfbeb46f7aadd690f21f4bdf7dc4a1ca6b3e22b622edbbff143fc5e6fb88f9e89f3848c7704a077dec6d2816b1ff6e486928f190b9f47d63d041147b785f837fc4a9efe37f8fa53e9cd241faef6d481fb6c168487f84f50de77bd8c71761f8a6f41fbe393d4ee789713a97b09f3efb534ad86157c1389dedcf141c4a7b43247d9b768ed58763efdf16871ac8f1b99aa37ef4d139e2748eb37e042d47bffe50acefddd048f6bea3db2ffd56baa1567a1bff12d6f1e130277fa4c6a47e1bffb6b11f27488ada7ce9ef940effef6ddcc6e2fa19866fea539b4a6b1065acde2983ea10879c1b9ccea50f4d9fbd3faaff86996ffa63d69ed29fedbd5fd20d8be48ff4a88f5306f5fe3deac6497a1ceddd9b1bb21c643e7dccad43e612ce4166ccabcdcc18be993db4a7f4eba7bc4ac9ded048f657b936d8a75c9beffbebd5f1e5b4f75eb297844313c6e9d29d39a48f434e9639457aef4bdff77b2c9446f2fcd2f5d1f8bdebe3fb7ed2d5f1e178a9fd1ae2b4bd2192948efef9368da30d86dbc321924cc13093f4d67ab58f43c2225a96a2288a53478bf80623196766ed238c8f0d3570e51b012b180d1b4ba01ebb21f6f3b795be9e576eac89b5510f030496ba086cb471b9f9225137d6cc19980fc000d9c8596d0a1b5f65aa2ce18dc94c349710fdb6d139e79cb2b3996533d61e37f3a5fc82a66cfab1dfd1d8d532e9fe2b5158f0a9d0eda37750ec3ac8658719810b73ceff17390e8be4c737a2cfb2cd0517eefbdffbf7defb3f995c29fe0ab3aef2bcf5e31c3d7ed964822c8742b2e47f9ce0a581fdbf1feb0eccdd1bfa8e51aa480efd715c3691424231655e68123999bba167aede50e6fad90d8364aeab37274f0848186864d1d55e74fdb19889ae6cecebefc0bee29c3cbaa18747f20c83e4d1b66108481868e44cc331fa7c79129342fbb7c8c0cea7617c22334a9edbfb861f9565192ac60a4bcba7607cfdeeebabfc56b7cf483ebaafd8077dfffa2a246c43b1e3fad9ab546b5352eaa59f4243cb932856a1f459b25f51b9998cef5ed61a543ec329ffeced7737e59ff25d949c726c93f2f6b7edbf3f9d4e26933be7decdc95e229948cf7da954a29444a2a45b499596ee09c709fe73f74bc1a1067ac8dd5bec13fc7fda12facbc031e860b1efeaa3e529be697912be6179fadba51f5b54300b658991c20e03e37446bdafe05066d4874872467ad275ca51096453e63de9292a7bef6a8ed1671909bb09879ed1ecdd3dcbb26fd26f9bac36231ffe248c63b6c8c0caccd13b7a8df61065ee23776f46efe3fbbe52e9db9ae3eef6ddb6fde8bdea387d09873297fefbde64fa28d971c8dd27f9bd71be5092bfe9fb6cba61ca6b7fba39c8cc7ddf8c7eb319fdf636f4fb52e94fa7938a4aa974baf64b4e38ce3dcff338ee8ebaff2e7d1c9db23de9c9670a737269fa73bfc39fc339d9bba167efe93599bcdf2667ba27d3cdc9270c0109c3f7d9ff6e7d8fef040b261c27bb87f7a6dfe1bde97332e9869e49ef373c92dd74c32039d92fcecc250c010903f7a41bd2c8dce3e8ef5a1c6794ee8648f2e613a4388ef008033d1ae881b2827a9851720e92b2823e90a5fc6e9930b0f01fef11652f1265da6b38c47118c0407b427415800384918107f704ebb2dd9452ea43a95319f88ff7685ac470285518d644a3997bcf4fa6578699214238846c1883e61c22e453fb91b225594da28c8d30e8c98d4d41286f1efde8b28d5eba46a38e4f2441dec8300ccb24883e932e7923fa2401ebc9a3ebf25a67e004bb250916a6a37c82d224d0c8f2a1f59efd0d0d07c31cfb9684816b82b51286a8b5953060d3c94bd334acb3189dc88043539eb4bbbb656b77c6860c4eb0ac1fceb9ab602e812277b20c0a0f3c603b3cc81b31c625398ba1f58bbb6461c308822e7b883276bef0e07d5b3de89feec99b977d74c11efb8dfb56715cd4b450a469b87fd85e345dad923762d6defb879e19a3fd64eedab8a31b51fde2a2eb13c466b6b0fe4d1f07f5ec2794ecb3b72de3fa41de9039ebc958cb7f6c6c30988d4c29b5a15d14762d9d58d8f82f2701e40d39613a8a542bb5a23e42a91e79034bad72fc1925cf0f89c0d8024b1191a57a6008cd182252adacddf964822d0c8a4c01b73f8298605d30a66bbae28d41073b9bc0d82245040ca11913532beac392dfb3dbbddb1bc4dc79d0f61f1b5078d09fc6a19d99914b6815349dac95378f453fcc5a389db3f72c9b42c2807df63363e2679f49216fc49cb5a64ea6573ee14264932b6c286513a48cd692099126fbf99207a2b9813cad9027145057d822e4f9314a20e4b964f6c4e8c20a4584fd414a1e505580e9226a4cc8f1e506a48cd62f3a4420cac0f4cbfc20d94f36452bc74a5b46b25a7228592d92c59a3071de0bc41a1303f265fe7440ecb1e207140f7986720357684c5085a8204df0f4996067032bc23edc0463648dac70b2246f5e7f74b994d225995b273284363286b9e63e97b8934c2f0c0d307acb1fd902c546c73f12956764c011a558228718a23f79f3644bd2eca9b7b7f74b663db39030f4d3ba237bece3744d28f246c7dc4f7f8632bd34f0903b303fb8b052933b52d5435ad3a86bb375a6504d7c942b0b7943fee4585db63016f759867d183feb8fd1e550debcd8b13b76c7d838667c6d46ac175b86bebfed97020c20ccc9618c2186f0480ee34b1c16117d67b1af07546a9420714a29a594fe0e3335f4951ce917614dd3344dd3348a95b8bbbbfbef3053e358498c2fd5e6cb12c73880f85366f917490c628205254fa008210b4ed41c71427e9448b2b91d812588b9c990116964c8686989342d2d2c2c91868525d6983162a452912695820123d2c080b1b21269565650a8488342a9a8441a15959494489392723a459ad3c9648a342653a914694a251229d29048b1c6a4f93e6b238db5b1c6a4f1bcae8b345d572bc7451a8e8b3526cdb68d469166341289228d48a4699146d3b22cd2641986451a0ca334d2501a6b4cf7ee48d33de79db146a491b1868c3572a4c4926cb2013644651c844089dc35d3022187a60c3393984768e1587801b5c0a549e16a893aca90625c402fca7c1f55b28c0c441ce2cb8773228e2f951b45220cfd52c62fd23216cf9e38412ebef6578a56a18b9410319931dc733ffa30befc85727737fdf94d8909b688896835c19ee9eef872d5ec61ee789209eab4173d34c1fed15ab98372531c3eeeeec99d021b8a56a295c8a74ecd082c438831c6e6dcdd29cadda7f8e6c18325083f208e1999a6114579c41af387879c9d82144f0a082bdf3553ce6274ac9b0631c618bbbd5b7a9bba7b668c5aaac7bac7a875db25b8da9dd22c882ccbb22ccbb2ba43d609c1cb3e6b8a655ab71034d10b5c7e1c6d94528db32622a66d1361de1c47bf526abda986ddce3277e642c05eebdea1b5c518e36a934d5d084a29a594fab643fd0855b6534c243a029689462391e43cd2c8ec5d5ae3ac8988c9e4894622ea2da234bb31e7706e4a99b351cd91592c8bb267b5a1b7f3ccdb5731fce3e508d1378ed3382ab99ecd299669224da4b1e66ab69c62999669994ab25e7345b10c0b61a24baa582f8cce09135d52c572ea214c185d52e5ed6ae9b1f2e79c302d3d46f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f04001084c27cf97f2c7893f6939cb7fdc09ab9b62be72efc9f3355f227291a8a714b90ac35c1a942879bee825b44366d768e4c33de124cfafacae898fc7792dfbebd9a4ee2e799bfae4a7534f796a1d9f76a95842d8d05f292aed982683fbd699abc964facc26f3e7c5fa6905b9da4767b6747474747466904be8e5e3e3e3e3e3a3a3a3a3a3a3b35992c9f41ad2993b53c5fa6905b9582c168bc552a9542a95aa5d3e73e5e3e3e3e3c3c467366161f4f57abd5e2c168bc552a9542a958f8f8f8f8fcf674a419558f247b664904baa582c168ba552a9542a55bb5eaea1a93377a66ab2582c168ba552a9542a95cbd52e57bb5254b895d425693d2bc944c8ebb0582c168ba5ea97a952a9542af9235b412e6f168bc562b1542a954aa582c1c2fdfd8444a1f88a43fe62491508fea350d6ca1eb962d278fa4bb2582c168bc5c268339685fa01c17f14cada9726645fa838d4a29a662df517f597bf02e191fcfd2c79f6491328c913af1bb5e9b0e77ddf1dde32ae7a6fbdcfde1049a6587a1dc5b3727e84fa9f20487b90567737088220182448101004c120dddd0db648adee6e10043d779325994c2a29a3d37f1030081804044170c727481452675bd3502821b971387acf4731964a38d446d6dd296d11572aa9d4c0f529961ec71c7dff361a8ddec4b9b7fd0887377cce0146c621277b5fbb76f5b0f7e8ad37dabe9ff6f7db8f6e28248fbadb6eaa8bd186a83c4a759847f4defbfa42f2e6617d6cb4dd70fb0fc7a083dd300ea5237c437a0fdf987ef438e668c338948efc4729a712572a6d5f1a71236ffb51a9866df4d51b89b6d18bb6f75048eebe35126aab3a606c7dcb6d28cf7e8c8d4b3844e5fa1f0e51f55137c697da1bbe11fd48348aa24d341abd77fd9612d8fafd38da3ef673c337fea3d196536f2864fbbe75e67ac30e67a30f478f836fdf3714527168bd38346f384492471f3fc4a1991bc92c123d0e2136912524938036d20d7964d217f298c95908c2c0f0c8dfc7094eafa3f4b3e748d997655ed7759d97e1194d9ad1b8d1a83b954a9a3591345bb2ddbbf75d7dd89fc9bebbfede0d6772963d8c03898159f0f74bf62894bd4a626096ecb91b7634909e7b99d12c7bd3e937cad9db3dbdde63eb3ebb210fea655ee6655ee665dee5bebbf6fd726ea4eb2ecbc5dc0361c1dc7f5e101be3595e09875970c823dbcfc9dd6bd9bbdd489fe11bd273f8c6f4d97797c80c35652657c19e722a7925afb3dd7b25afb359c66519b7753cf2f7526b99fbf4f1c3d8689941bd0692f7dff2d8fb183827bb8d1b613c6b5b6c7654f61a60262865c878fc40f08c182fe381b4fcc790d1f29847bf389521e381b07c0c252c38069ee9179f71ff8239ebbaeede70bf7de7e1306726e491297dd4a7fce84b3daa65ee372a6554c29fcae9c10cc2c0dc3be3751b0ee5bdff326ecbb35cfc31ee8c1e94e5f12b89f133be6b8a012c8f1f488c9f21e3ef0391f157c6fdbf0fa4e565fc7d252d3266601ccddd99258f5a83109e81f1b33c9019b4857751d20276c1f4ca887167b0844466f2f6a28e1bcd2c6bf79bac3d602648bff86779252d1fe3654d31e09fe5813c06d2823fc6b7b4cc78dc82523203db7ef1c7d8f60b4d31e0fe3f1019dff217c77e512203b76022333919c764b931ee13994112c42373e1c10f279871e1c10f26c8b2b5325bb02248de3c2fb9c94fee20983b6b290ebb1f4e9d3a757a32953c9008584f7ee248a693fd5a494ebda79608e8370471caebbe74c36afacd5a1bc4b337e5fd576b4d7941ba6ab21613014d26121110cc26128943a99c524e277bb25dd79dac7b75e7ac77c320d90b5d323d511a82a56fe9b01f8c3663593fdf8f09fa7f5cfda71ae964729f2f2590080882415a06353a95503f3ae1520ae964f2489fd9d377d7f4a76b632a0529913011300811900898b9caedf868b600434821041660082996b0c5b6ddd086bc9d2ce9a3c1a953a76f43e666d8ba926934c2b649f8a394528f888ba771294e4db51d5bfba8771caaf4f6de6f1da5b4faf07ecb4146c6212773bf7de79d77de7178a3efdd7ff6b9efaef41ec529d2d314e9bff73e6e76db708a84b9fffe7bee3b1bb24737af846fec73f8e6f49d4bee9eba648bfd54fd3b1c46ec2a299476b4e328ed28a51c0e9d76de945a8d5e4b3fd432473dafb58d06f76864b79131a97bd22dfd772baa65564829b1512a38e58432e110f5d9ee576eac33e4e4ee1d872eb9c32111978df36cb0b6b3b6b3b63375ddfbaf986cd7ad907ee5bafdecbf9b83cc24cfb32197bee47ddc0d6df070f77eb927dd6f66ee86161371e1b6581710b3f77e431bb2bfd775dd739d0b1712710989b8d09c25394d6cc8f1353bd385127e5c66ba50421429f3b484add6ae7e5bddbacd643a9548a65a6bfd5357bfdfbebefdb6fafeb6be57aad61ac9d56edfd36efb6fabe1564b58ada5533d5592c964aaa6fa5553ddbeae437de9b7d2f7599f31f8972aa5dfd7fde96facc561fdadbb371dedbef4f686362c92bd0f55327dccdd09e72073fdeec6ec75f4f59e7e746d4ef5bd5bbaa111efc32109e3b47767bd9fcd8763bddb7bb5ab9cecd3b4497ae348f7c3a1e7ee4998f3bebb5be9fbcee29bfecf07673b27976e7824379db3fb4ffda62d4ed3a33ed61a4edf3d7bfa7b977aded7fe537fdf4fab0f7f1ff66feadb70dc3e5af7b8a74d7a7faf716afbfeeefda6366c637ffb2fd5c37e383c921df34838061dacc537f5bdbea163c7154714c6e97c7a7f0f872a610ac6e96c7a3f61537b5c73b6db7bced4efdd1ede6c733d5bc3e1ec9f3d7d64bffbad2bbd0ffbdd7fd7c3dd95550709bb91fc751de626e8f5936ee5bebba5effec3da043defbb1bba8f0ffb16e2b8c77c6fa79df1bd9bef63f60f8748f2f79d96bd95b7deafdc385fbcc7d11de963fe4cafbd75ff8d9b6e8f64af7bef7e4fbab6bbf5bf1be24cebeedfb5f19e7bf7ce439cd971b3431c23dc118d366df71b8e641cd9b60b2379ebbcee43237682b6dab7f61dd7ca71ddd3efba8eeb7c6c5f5fcbd666abb6ab5b67ad114b6feafbed8d64fab5bb61ed3ad26ff8c6f41d4ee70ea73bfa1d67bbbab9577777df6c465e69dbac7b6fb9d2f527e138419cb6f4763734923b124d09875ec3c3a11bc1e9dae17487e304b98f951b52c44853e9f20b8f89adb9df36fbfebddb580f31f0face6e9ce738a4f4a39652ccc51be660b544dd4b2ad544fa9453e9e9db6baadefbe783bef5d1fdf6f6b90fdb749bbf7d7fcebbe14603e9bb6f8bb9c7b8eb947bc7a9ee3dd5fdf6f4bf54876db6df30f0cafedf467a4a3111aab2f886f41dbe31bd254255d992b09b4c2a35e5846bc9b92f71d66dc7b96fcfbdc525ce9ddb3a7777f711f7f48efefbbee9ce8c213d2d3dc5de7b2fab0e8b6987bbc7d1248f49367d77bfb7b73ee7e190aab2dda13df82061fb3dd9e2d1c7d1477bd0a71f0e73baeeededde5a4a4dcfddd29bae4d2927bff7756fb570e36ec8ddeeed0d31f0eab88dc31d56e5fa31cc197d05822a808197dbb40f53ec5055fb304507b27c7a92f6035b74d9606cdbf7f37e4f6f276374c2d59a452e8eea8d13ec7048c4fe37730c3a58ef9543cfb1ce2ccb7e07f6190ea54ba884ccd8e98256aaa20100000103160020200c0a078462b1581685a920741f14800d79a23e68529acc634916c4308c53c818640c10101110012019492300405760c1a75e65406bab5607f8b8903e4b9754f369aa78cd6a6526e41aee82ee4e6269bdea235dbe7b9207134899c4e47f8bf0928dd96704bf9a9000260d98d345a495d0d4661fdc45cb75f6b8a3d54c00791ed896121b8c13bd4b943f14158a805f7c4f7975cd69acfedad2aa54bd7e52e36b42852747bf240b29d80b0596a7a3a3e4fa59c1d641d55ca6e43da90b04e084d2f4165ab72e8b15554706e5944332075ce5feee98863afdfb0c136f3ee10dfb1fbd73d3705ccf9f47239dff3d07de5974bbdd74a9227d1216f2ce54d01bf6687c8c1247d2965d98e17ef5373cd7d7cb7c75ffcdbbcac8b57f82531e9e359f40dab190b8b080d3da6d211fa1e78b1cd173e0c2d51157e20d7cff036de747a76150c5aed31d69e215f2fe09a76ca3be96b2dd751e3c97c71137cf81b4c9fc658e6bac342ea79b0356261c3f82334710b24d406e391962bb4c29d96b77234cffd8eb9b3f41b24d07e4985cfe199720b5435c00c917179b49321a9fa3930d67c3c55576caf6f7da19664169361260bccf49d79f0070806b9934da22d36ada9efb2ae824bb428eaa379c45d1ced85d37743859f743026d13d18fcde50fe65752cbb437850cd0b263d3472e9f2680bb1bf3ee17b51b9eb9e598962f7483732d4570d906b8d94e89b8cb8cc29951893463d2bc46fc5d86538b708df1f2125a97fbdcf8cb3f57560388c006fb2e45f0d0c097fd54ea2cf1027763beae953b69a3862e05854ab478dbbe18b5b80d3376e0d83d7e015eb38c62cf9adbf83feeb178f719498909dce41bbc1361ec2a104b47cbfd82884e6ed3cb340906ca8e4a35098d2965466d73d25fbfadfa5130ebb606c20ef254c80a1a638346b572372478ee57fd9b56cd7bb74a43c98a9a92eb9c3072cac6733927dc8651b1174c32838a50dd8fef9a24ab20721a26d95a0c3e12a5f2979aaed63bd5020a37719ecf304ccc060ab302ad1e6700600ac5919c3a52ff0479db42637b9ddd3168b7b4ae31799938cce18f593a0bfdfbb3993edb7cd1d993048c889d2cee39a30d0ce816a7a68953688ee519299e917f99103181b68b93bdd0c0bb5a5c9f48c9eab9a963dbb93c8910c151712fb0cb3c848df91528e14c2f31d5ebed3d52c114efc386f3653cc35f0b6fceeb1bbfde27c15e2823119d0b63f012b5a3450ca67c7329950fb9cf971efec45e2274c691d5de24e9c8c18a9d53efd60709be4d61d757d657b080f1b06644083c21b6c51fa4966ae4d787e488dea4d4dfe7d85dd1c3d1158942e4751d11834f4e16f7d4f0a94b67c723f18808dee5d8479711a57404c450ff002a38a2c0246c50056b490c5dc0221f0294d06d60766ac9f353843d3e2e4cbef2f19292b850c9e3d929a18bfa78aba7682ec2c553faabb18d099643f7f4fc03e0365bf4b6e42f0e98c1abd52318bdc274c2f8bb59e8a26a1af2cb793da68cc884c9ebcdd63dd4f44da0933450ea370a79198d6f3cf8990af1a742c2bc12d1203f904edcf9ca52d39475f337f98fa7441c1d63af6253876c1bc697bc0f03c30c4a89996b98070a02e349a16471f7f228a1696bb4cb7c41dbdd226920c9c3e9ef5e8dc5294b5e99b1c3d35bea4d2c8159151aef21b6efd50cd4c6a2ea949bb7a26314b34a9063c7102ec18bfd65cbc3d04e8ca51c51f4fc00b68abd3457f02c7ebd4e10eac99555c6b72783fc6be383169cd1d5ff6c8beb1370055573c1e5ef3463da04d17f75172df1393b7372708193f9192f62dc76dcbf9207552cd0b2caba0f853c8fecc37048795dabd81d01e27a8f91bcb4ec121d0823222d0f31373464f079ec83852ace8b9187ef234feb6b144d7b4729d42846bce9e6d90823ae763f847a772090e12480ecf0821b927a249705aabc64df3c729fbfab6e7b36d06c42797dd342f5924222ea9055a80fe52dbfca67b5d1ddb99a546f651584ed1e445c00135c97b7e1ab456b8a67ddaf2947022d995f92efbe243a7aa0e2b10a5188d2bd84a0e4d5df06f46ef2a87fc0c7eff1b52e7cebfd77bda55c751dce63481cf93809fd8110e1dcb4888d1b9ca47ea11791463d384b99ac6b43ce5fc0ea8138dc17988da215eed6c0382e203e5524aa2ac6223684d0266656e8d059d0528e544781755d63f76f563c0502de9c154cb4b97a8010725e92546cfbc4c6d2b7abd8015998f72c569e2ba45faec919d4027eed4de6c7c8d4433557edfaaf21741732dfc5ca3346ebc04838dc290bb924e65f095241504b21929a86024dfff090ce9da43796c47aa922aa62b2501def9e2b1c01a01c09493d9cc828a4b5bb8879905fde74c67152b624b8d0c27206caf3924d82946d94db8fae1649279280bb7d186dbf8538f0d5bbc1b636116d10e2908db5ec0ec2533876fc13894c269c1d572280ed49097dbb04595c03e87c598cb34ac81d3be358456825c966cdb1604fd0f0b28cf738646de8da5e9eb7447757a563a2beeb38900b9a3d746a7da3733d19479169d912d2243030e764cf7e8470c1be71493d005377e6c320857010a84571808f9842bb338c30788a25fd139c8be6cb81a0b83e62b4a2cd513e7641025a02601bb01531bf42077769166ceab6bd4f6034764d875e344a904a2e3b56df6b601729a0c7e26510ada085a1682a828b9426c34a9b39bb90008ef19021151f1fa481db56737824cea9c9a85209fbb968a37f5030eb19c0f1dd187d620d93a5e57c416c903c1477f9288870841024f08475783a92f6304c80479047a89d62c5c1593ba173cf429f5ca2603a18c26f0556e1714ace4d18ab9923936e68ade840a246b9fe27d6959778bbfa890abc5e301ed1bb22b41175a8cceb304f18f5461c3f5e531a2993e6b72e0af74ba4066175d59891d82d4149190df1da7a9547ddd8aa0f5979652a2a0f5cd131f73fa63b135f7623ab5dfcdf77f1203e62d8a392d4b0824032c2e03cf1f265b0c36e1abdc604ae4bd621cf8a265bf820c5948f36c2488565f15eee144926af7a6f0d14f1c7e4183cdd0b8293c28905f5a5274ec298f198ecb2ab3f627480f2aad12fbb680fa30b8991ec3d28f642f2d08f0f0173fc0d3fe8ebc49b4a55386291be267333f87b6fbcfc2ba1ed8279a12f279b6d552c8788da077b37688f3fff3a772d1523ec76b870414c341c7603d527018bc2676f6e70a146eee2daff12194798b022f793cc5200cb6922a1c424a074b0086bed5ff092756b633809260341c83c75fc2f196f40675dcbf8f4501730ef381d213508386777d358121709eb826fd9a69fd48ba508f1d0677098d999a4addbf431d05eba19b29495765864c04c2d5e1d0c6f046e38f46d7d41bbb2978408f4fa1fe3186330833f49044fd16fda4049c60411370ccc0b9f981e2c634b51d8a72a1d7d8e1d97a6646e3b66985701855154c5402628dfa72a9527ef3218ff32adf584d934d643a8552ba6dc5a08b83aaeb39554b00a5179a159dd3d66bc48932e2a5b60c2aa7e179b7c1499e595fc77b429ff4de3c9fb879806973f8477d79eba9cc20245a404e25631836268e438d0519b3c5f4b542ec14ba5276c10e58a3e56c254191ad9b58b4e3827d07309f53462085a88fd78d1b6d25a9861b3440b15d63cc91611e07fcaa8c645c4cf7d6ed7bd2ea799578d050344ad9feba4cba28a457c8145be1e8a2d440469815ffb7f84457564ef8041fcdb8d308dca759a18216cdd8558c14ea988e68fe785531102e42a01959133b722ba4469376642772eac1652c749f88bfb15d1c912644853aee90470c44958e24137d6427c1369e9904a8d2ae7830c9171c15be022044a661a773f09b14ce16f72e43e5e78996cef13e2731b48c2ce52414c3fe03df40d7db0c50307912466e7c431b39985b0e5852887fac2b317096d3893917b585dca0e2e44bd8eb9d423626ab1a0e4633d89f928aca9395b59b522a7053504d05f48774561028650fe3e0d6d1b6c5f6b5748d52a16956ee4740fced6dc58284d31a8e9b64decfe27a938172fc7c5a19191115248ec2569b11643de148515364194c2bf03d21d63212b7687d0941011c33d0b85219e671b5e3232d591296587e3509a626380f74811b8c7f0a41e08db44b884507a0ac0fddab5ba34e2031426a463960a6db504cb1ca5e8ee19efad621b62a2914a0415100fbc7ec13a0fec97e13d85cd805c6e8c2a607153c9cfcd050aacea4cfbcb7bbceda8934e52017a0e3733e4da238892718578d9f0c4b9d6fe6e8c70695181dba7bb292a38bee99fd5a5d2de270281480aa597ff5b426cc14fae509225dd6d7f3986f8178bf788079ca1aa822b31967b6d78185ee7edcec36a9101380221faaffc7561783da6ddf4d3055092216fd3ea5811c0127bdb449498e2c64ea4f01e324d5a4a0dc2f92fd92e1705e8de6fa1d53aaf387cdfc83bd35b04188211b5cef012ac42415ff39c4bab5a40cab006dc026007f93441156e5a040c01007b8877ea0dd07c14303aa42a9bb10ef5cb21470aef8eb73000b87da01b1c84d1e541fef7470841c21a59152a47801cc7cdf6a79fa39932ac07fe9c2c74e7891e42f8467255eaef57c25745fbb201ea4c75fb85ffb6f76448a040dd348d6ecbd0bb01b27f4bda2b25142704079a9c92e78c1382486fe2af0d82394efdb40a41e7537fac87b161bf5113906d93ff75e87f881524798f1ea72bdbb091009710c41ae51f1682e7ba6b8ec91602da40b6742e4b46c08ff989459b1eba5654acd7fa937cfb9a3b2233f7187a73c86743ce417b8b7955c6ce8468ce79dc9cf661da474c778d2a12c049cc6c1b80a9dc911bb8c5c610ca0ceb979c850c4c17bb86011fd79bb3ba9e2328cc73721e1fe826ec2420c1fa23d3d925b8f87e352df303106f08b5903753434cd7f90a44baa5a3306a73128f6b8d5f61601b6041abb2e7139000565fcf431ae608780b02ffd841c9cd43e6461200722493d96153b2d0bda15b7a23b8bb820ce6e63a2ec98d8c458160ec730b253dabdc6538354245240adcde762b40baf396ab1651da451208151dade01f236a650afe14560e265d0542c85f3449d08b6dc8a2148e9a94e2826104cb4cc83ee2cb607a6135ff4e280706d4ef1c04dba2e2f4a811e1f2630d31b739e91d57de529558508be1253f93799fb9b2b3aaf46fb816eaf0ccbf59d70d31e64a9504c8408c7b23cb11550f43daeac96854975a96e6fd268df29398414c53714e7324201689dc5a25e0c33a43804d8ad9938bbc803037cb91b16c2d9ffe43e713f3df782e17e98a6b616879e4a5afef025441893dac9c95fd14f871cec5e4a57f5d814d8285a052889e23eb8bf0f818ed177a29cbe70d699a4f0628c86dd5b3b4ac82c3ce314080e333a2d1269816a077f9a8a129679a26e94e0b88836a8c6b8dcf5f92fc9d013717dabe2308f42776004139711782afc112106e2b1ae39724266d05d851e1c77a75febe6ef489d7a9006d858f7e3488f40dce4a9032673d61c941f39738427fe8039a873ac0622b2c53564d7e3b075602c00b200b96ddac1f2bb280d59c9bc11c3b300194e091c0cf93c31a8a094faf5e456624f5504c90d8612187fb2a693e6f28463172e759585fb7381493a785b78f872c6acf2c135f75641a92aaff1513d99e388015f30ccc2b4e8ef06c4c51e58e0cabac58448b58f72fd72fee8dd3eba5dead0a74786f572e26e281fb3de162bef2fe60c19093802da7984ec00fbd36b698479a0a768681208be00e9c5adba51b05c78b826e7645bbb17977b7f8749aeec266c832f59ac4be77146698b8f740e782055e6337be26186a37d8aed69c96339399fe4de90fe0fb5daab9bcdb62e516132eb8e305c3f5d1f4c7748e67a8282ff2646c4e4cc33cd9626118b81989164ff64f9a4cd1d62b295d99d75ec661c38e5fec26daa78345cff6b55f4266b6348fae940411d3a67f053064a631fcebf1c9ecca6ddaf4e302b372a4596ffa78ec92bbd53d10f70bfc465c8ce34f87ec1f85776b7ce5c77f7eb9c80a134a08629f511021da839546ac90d3ce6722fda4f4e837c0297bc76ae98856ab95b1c8be542634da04ae355707c6a9b41fd26790c4e26ffa97b9d2e4f927a99fc18ed81f2cb14fde921614980c00332c6972056cf223bd46e0b58bc89090b6610798d312e2fbf79c5a10a19378c15c0fb4804ebf9596c80a10aef8ee24b7055ccfc781049f6ecae385ae42c5771d10f4d003709dfe4e4f0a43d59511e0f86901347b270915e09dd51223c221eee8ba01d0be23d5033a4ec7c0cf733c6fd724b059774be2a7301e0f2276ca5c604767d804c14f0828e2045090d8ba38362ab218b9cb80ef50c508104e3b5e723c38c4dae08cbe603207f894fa63123fad713fc8b002d7332d442e4951c3c01924322f2c80d9ab5872e326f341d7012f781b7963eb1cc67a3b4260a30d38d2aee9b65b7475b801469cf951c5edf79408f61ba03a097c909a0cd06e029bbb26e433387da9e0b155bdeea55b7c6b2a29b46adc84ca2eaeb3ad91c9bd4108404d44de4202f34a5251c529b5c45a5b464e5eb96e4aacfae9b9f80555a3d93adaede0568a905f0455d1df6e04bfb9b0fca7d3c36cb504bd311a8dab59ca9ea1ff54c1c623da21dc0742945de7e9b6c59f835eec50d59986580b710a3a5b6246b7b5c858aac419e551b787ff07965315d08d0d142c19dd3688b5b487e6fb664c84a8c4d46fa05e9aa79ebe893df2672fed1ee53e7231e0cb4ee5a91f685d1960715c0544527342967e06a1439a4f2c7930a1e1667673183d1cb3486236480340c6423cad0680afb38c848c4ec7c0e99db76c2d67c7da9ad38f492424c88341e45ce13024d9bcce6c03fff8ed10d2835f298b13c870f82069f7630513b0804210c63e7ff5d18942a85bafb7339ca3037a3013a71e98ec72d3edfa7c97428ca5a8f34348e307abe50d09d55c679e3607dbfafc8bd601ebde2c1056c461779f8806cba172220f331807712d00f133f024abcccd06477701508c1ca2fca9f980b6823c3815075f520b6e58f1e050edca798bec4a13c5182a4b0bfb66b435b72ff608e238cc25ab0e07c007e811443fe5499789992883cd4ba7cf838f04f863ea66ac8f07042dcc081f205df4841c31c2cb3f9b47d617d3615cc06072e00eccbcb055577527e7d36f25403096e60d7673450f924a71a6bdab4eaa222a18dd7c0dbef054c082f9d9c2c039a43d449da1ea70f9046b3f12e0892abb6dbe77ad239660b88c95ecd6779db4172abbc5c9440fcc863c54889aa80d0ea75e9e533f40b8faf71cf1cc265cb8e5d25de54e3fd47b9178a77fd949ce7b665c02a7617221acb41b903dff88f1f26a9114a4f54dc66cc3651f36859e8aa971409e49041c2d16f3ce76379b09b709754ffe69dbe5653f35bf515b0feed52e46f5f34e8f27e70268ebffbffadb55f46645e7b7d407685cac116c146a80a8079a73e592b672740a1e0542f1279586ad149efb3c74b9bea20a8affab6ee260b4a9df824cf63e5c53f41eb2079691b12ecac1e17a00a8bfb34c64751f456d94b4b977e7fce578cb55519a6a28aabc366d8e4dd5cc9ad0ce3e4c3218080b2a1201887d12ddb1b0d1a572f2246e2f52d2a674d4c783e1f5f059c41a9f57f69f83467bd86f46af2d6704fc31c2baa6e75a93042e49750e88470088ab2d1b38a48ad18cf598ac09895a8b8ccebc9ec89a107e6670471b60b681adce6f31a2c868b1f78ca181ddee20357a4e31802b75dd01aeb72e239a8dd6ee6b9dd20ab2594ae211984e6a00fbf4d3e88c6f6e1f94997e9df69a115335646a01a5597f9edbb220d3731bc48cb55a4994482494decd5161c3ab562dea4791454d96feeabc8b92911e7a8609cc6f8dd2ae8546a424626d5d78ed561e32282300f9f9e337c166446a6ffd6ff5d8690d2eaafc07928a2c28aa3fbdd394be4e7e560a66307ea8baa56060e2e0971c583a97c083049e2856143d0a3a9afcd7bfad75a12a3486281b4693f778a187acaa2df992ba5e456f54d42f91b4ae699208f521a2015bde0cc562e236e071f70d06c89ad39c06a094e449ee799a6e6d8f7d9f5fbd4c40975781292ab2cf8f398d70176a99782acadb10dd40401dc10097b5c9595e17e91daf667e463461f220df470fb18f143b7f658813329dffb20db68dc2b52e30e13d9428403b2acaa60d58dca0b1b41361ba62ee669a23a1708d411e3673018da2e2d638e925c9f45b5838713c385428bd73fc3569ccb821fb047c942d6347df7e7c916b6b20ba8708acfe3baf5b6d27e6dcfc1f62cc462b4db53ce5c5f0a495f89a5f9338773dad09dc4eb292d305bd3d636bf4d6b53e81c220fecd301496537556ed3e191931f4b705721d73909fe674bded724bff659d8708daf2a671ac4b8abce6002f5ce8066b49f8d61d9c5b9174ae0608933f9c0c5cd890820e70498aafe81702c4e1b9a57991c82eb47789a797cd9d43d19ff873f9bd67e31ad35178f1d22a25e3725eddaea6739f25082892d0bfbc35c28857ec1a96b71e2a40828044e81fdd7b91282e2c1f16d264ac300b87c3893b923b3ac56cf01fb36d5f68987f2e3505a24a3fa929c0499d5cace0278ddd807c51b855e3f26c29de58cbcee9ee8b00a21fe255fa023e578e5c2699cd94b7dbef28af4b1c8946312a661e1650025a7efcde04f7eb0b5a543c14aeb7aca9a9cad633553b05081425304e1a931cc14b5e34763b809d4a52df1cc6eee1598354791e894cafc42e76dcf279c91d4931d6a9814f7094a5e6bd5080442c24deb76fb50acf1b568b4c69ab1b959a8b42ecaf5cc8a7cc74c37762ba71096c0793e1a4201c91c66120083c45a8b5cd5b8175bcdc2e932d1828c9a70ab899f6cb38d6a958955e22d0be1e34edbda9b08ef5400a49bde54743938a688d7c26175faaa4f84995c95e063a4300b076faf618b6e6bf07838fd305e83a7f02add93fabf6005079b090944e05e14310ab2cedd8d2af726e3dcf408b5c25b6c80c658498fcf0b9db82c4325e4181c2179acc4e85c75726cb093b4c4514a693b606848b5ec20f07db1fdae1ba818b1b0a6d70d1fe6f1165a5849a79154243ecf22eb4890a65c10fdad6570b9614a5e033225154337771808aabfa368de88c95b4574c9e8128fa3a82297c9d5989c62be37aa45ad08b5c2b84cc24358f56fe3313a5e539f49d3377be96ad92eb298db52cd84e7ec6c8e70ace8392fc96f3bcc127adc39145b12c27bdc3b996d90f87e6fd24619ca6bdbf0f2a8feba940bb963733763b6ce220bc7484d295f51ad772090566f40c923177574eb565d24a61bc19b02975b3824bc76ab9e25eb56c7280bf1adea882ce1d8142497831470cac04dbc4ee3b1c2d08a52c4240dc078b407b2578b01242ebe06c5de14cf803110c6b84170b42b865f0130829a647c211fb4f3f7d661eb2b1d5379c9fb638a3d63ec6fe2b67155ea1d6b4b080787dddbe172fea9b2935847cfbc1dea83ba84aa1e07eb36184e7a96047e74846293e00920c492c43aa0dc0312e6569df70c12880ba7ae38da4a285d6d31fef2e0be3c0965ba90a8a63877c78e2695dd83390bfa4ed9d9f9ead293102eb5f74efaf962fef1e4169c845473266a6dfbffa4d7586ab3130d5d8c39d2cd521b7497d574c7d3da15e52013af435c1d838e094ac4ecd30aab9699ec7a9b5124db87aa0504d1a28f389c24f56490c7e71dec9ed345a25355efdf2ee53e9c8e89ac379571c124a06d903a1df626dabccb2e61da7888842ddca8360c7440275d253a8ee67f2ed3fec42e3659efd3a37b45a7687aa91eb62c542cc0683c4d30ffc1d7d6a9661c8ec5a6951f8fb623fd00ed8b9ee30b9cd5f1c3422e6625b35f092566ffbea3fc942c5535baa4c0aca0645f7035f18d89017562faaeca24bb1039ffff6ba960f17084fae298692ad72ec3a1e955d2613efc62e70de4eb6029b360daf6206145e987572a86f07f21d6a661ee15c2a2df234f3fecbc74c7b475c977ad0eb389c24b588d6273df71aefc3e1a8f01b2907f0ff94c3fb5e24c8fb0203240ace2fe64e5e15ce020473f8a6680524f7ff5b0de36f4644870d03eae14daa13d3645e87c7ede5020f6b118ef78221b09e09ee079bdc04c8ad03a867955053254e1bea64ed732abb146ce9c902e547bcd26d0447bad2ef4a0bbe2aa50f5a10a3f67553f0ba29b09face8756d09048097301a8e06212ec462629ca0450011a584d5eb2ea9875da0de8194b4c0014a635af516e596dbb5c816c7f46e21f601baa1f852c96ee263e88529f616909db310d559a240dd565d962a225d652dca9f83f48473107749c41a376899ddc66e257940477db488d15e9330bfbd7ccb3ac088790d7d4ece94de090652e0f31974ee46c436e476580092ea34bb63443715aae71b89202b35aaea372d7846613eec5b304fa03e4a8d4de2b7f90222298383172833bdb7540893b788f4857b695f5527157277627610734f75b7d1b31ce90074c20140e7499467438120a6dd653404d988f3b0b702ae448089b655be805cbe8f5e47e0a254de51374126bf991178394d8896149de08bee05746463ec98038cd4462fc0a7e8390fd8979951f82e53a35d3c65d684156ec364dbebc356cad299c3d89fb537f05b7dc2398844ce6763178814d84d48c3f6b88da9f3daa8dbb31d9bdafad77549a0a5968ec5894727caa6f194cd26fa2a8d61d8e9ac5274000d5650512215b1a4861bf740b4d92c646901ec7642ecfacc0220a82ffece4b4abb218d66597daedc72905c7aa3c12b6b6fc7cfa37c22b1ff31e8729e6b618cdf1a83f1060b26b238f16c6e84a1e60e266abfcbc3e122103b7040b9270214a5a7c29e3b586a28f1d7443f3b5c91664556c982ee982066182f98f2e43ebf99a9dde64180569087a2023317fe2ab06d5e3f631100ee344e158e2788673c978033f4172f956dc716072b7405fc2facb0f6428d75fe588cacf418298bf159b0fb803a1a254d19a8885e52bede96f29d78a816dbdf1be24c4d9b2288bcf6ababd0d9df86486b83de6032e52a944e64c493a3ba3c653f8a9539764b1bb0f787b0ee31bbfc3130f7f977e2867073779ea14490297ef7237e24a2c25f1bd006b12a04cbafd8769c71dbb64d501a6e5bc4806c5d07150da4fe61d68034730dd8a05c47bcb8860238942827d9d54ef083a2b406740f59be5648e229d37baae03b7c2456a9cbb5f1d4ede703e12537cc6f51e5bbb478b1a2c10426d6af225d8e2356eefac526b1f760416fadba7f92aefb8018defaddea8eae968254d9927baf087d3db9eb6b911359ea4ed4a701218e3f476a235468e8883253b05cceb4a923cbdce35606316798314083d1215e060fb7cbfc4e88f815e7f39e61ef476a469e7047ee6b39de100b83bd69a7ea98c8757b029b34a0632181304fa50cade7990b62864a18382517bb11a9af4c4bba0120c4700bae15051400004281debbb4d09c8bcf39795ff8b41376a7cf06e89da3a262a3c3d84304ab7866c679d10c5cac97a86c2c232e064df89ff00e846c28b077d775483569e050ea7a8b48182bc73769fbf52bb7af6615f20b2fde2e74e61cbc33ead473eb47ca0a0d7398ce6c54bd10c1d822c94280a0bbe58f1aa3c2996ec09ccecd9bfebd16be130243e7598d5288cc8d7b5b77348dc94138433c6c36b289001470548bed68f8fa0dc7a4f03206ae64d1b1ce24423a6a6a4dd73da94c8a3eb0de493464c9746ef8133a1078179535666cb7a52f3c347c880ed55539bff157debdf1d152a902e6a43c60d0bc9a23603d5b43e050db5616aaaa2ff24c88ba16100a4ed7efad9aaca3fe385bdd31776e66e97e255f047a6051e243cf15a2ee81e46aad9637aa014caad61e4aa26b7cab66f5d7f8346a5e90b7b982ca94144d96b1e7153b040e53ef6abc71a30e749a2c338af64e4c4089389640bb1b6a5f795e0322f86f17d96255c1ee671f67453875b4f650fa922265eb16cef72a947a20d325c34d0d19670a3c801b63b8f06f49298da17f666fe833c285173f294f2d547a5fec8a856d0d5339c2c4ce7c01e6fdb11c33f2abf7d617840a871e9320df81682fd27c41cb463d823ceb0088f949e25568fa0498527596e01075a9c294195d695fbae2755046ee5bd91f1c200b04159a3ece2efa73dd79567de02b3cb281ef91f159ef934f5187162c3a10e19a394e62d1ae3e46974c76dfcaa880b017360a1bcb9faf6c08f73342a0700c2d6ad6ad071ac808146e622877e73a2e1a225c83516584489b012331395dcdd3206478e59aa553d1b3508e56cbc66c5a5f46166bbbce1315ce1d4fb32afbf9363dd0ac9b5d413abd5b127bc4d325e38398a189045efe53708ff35a703f60f08f73927f802762e2c1ac512db1f5acf9d68a27757b585f87f50c98b7f237cedbbf9d03b1eed7d5f914a016a981d33d7204c9af2b2d8d306420dc4ca04f96e5be9c2636f5f9a85703fe6f4adb42921744cc93e60cf1a1753e538342b020c49d85bd3afe4c2909163948f382b37d36feec7110f15aa26076a893041eb22dcb31656f638941d400a48670c4a16b49c89cfb76f402214c978e73a6fb2d5f03cc6c937d19545825bba0b7204ea730833557993ec87aaeda443ff6a14b61d6f7f773c6a1371134ebc1925aa9a208c7867a5bfb9081b4234366899019acafe1647f05e18165f1654acacf3425838ccfc9faee4ce3bb97d2b8acbc9a604084ee14baf7808364d4427524df9c2057e6dcf2ecddcc1848cf5c71e39a6841c9a675ff8f32feae7b09ed342df2f46ebb18678e4d742f2d63ed48bafebf92fecd20238793bf6caad08bfaee7e66ac5c208267729f1201f76ed3cfbbfb3f106c82feeaeb9c905f960827499f851d83a17824c500d1c256d0740a4dc47ba41b525f4a340d991a11558c0160077a725f9d532eec5b50fd5ef3cb5c768586e9f42aba2d83309bbb91760bc0d89da8575af011cdf262d02a0d7b4e26d916ee2cd105a81a20d1cb8f5827ef4e2936ef45e5963a5bf86bb5f333ba7c5f003040ed3809319b52293415111c3949c8244d7063f986d1c399cbd9790ede1567a7cf27503c677d15266322cad1a6ceb61d1dcac33d7da90c36f81a5debc4540c61801b34bfdb1af505148c37cac65ebf7b92080f1b8698efcea1d9b8e215c39968d713743a88a1dc9f616c2574352895d50ab52f8972eab35d21fca110e3f52c43bb1d024db288dd75a8931bd688320bed130b8d31198368f0e8d2d2145b45c4980bb6f2eae2df5eec6e01276f6269e7c94978c3e71537c586b90abdbca281a9ba4053faec7819f89b40ac880cb010d72b317e22c735cc88bd24e001d150d451eb77ffa5d4fd91322d4cbe7426971baa2cf417100455fc88f95e5939ab71cbdf26adb1d13d385ee8a9746ce8d7e1762d1a920b78b330c117fb8a6efa327423d327c5a0fabc715d262d855158d92306dba45348496721c868efe9cc6f32e064ed12d401f751acd863085d70443365ebfa8b9fc7634da656857de1401411a20d9c6b5f99b6ef3b882c1ef45609e492261eb0ae54947c2619e2774fac151eadc1af845c0c6a22154a092d018fa325e845384c6614f8ea66420be00aab30d626c81fe85d916720ab8b1823531a6cbec5d0b5b5d1c29d87b0d1cee85a0eba8d98f0924c8b5666cd962dce234817d4418b8ee7525107bb78119624e4ff84d02e4b9547544c81f9ededa75996e366562abccb5670f313966acc48d551fec41d093e0039b479004b76176206a2c921e61e01612d7fa12e6aa48f84b8f4464d8ad42577b17d3a43dcd273fa4d1da242e6028d90ddf79b6822f9aba501264e6e4132076f5f9e3245b7934e303daf40f16e649791045a23a2dea75e188bfe62223cbed9f6f4485bc0cadeebe913513fcee98ad27dd994097a1539d19181f39be402e8df3ce5b81130440b297177bf0180250b164e4a872d576754c37f8f340b9b5a2d8c21fade3daffeb045845732e867d4636403405452c6f81bf20a2c4b79cdcbccb47aad4cff4d3c0666705bea4f1511f6f1c47eb03f51cd6dce3abdd63d68ff4bb4306df9e35779f344075a8f2936c88d193d58bd619f6f8a15e4c68c1e54cf796c971b7e935fd58d993e68bd536c961b952adf1c2be81b139d8adebfd3af7a734e07452f4dfa6eb180de5eefa5a267a06fe83b86977eb35f71cd6f7a13bab0f21a0aeffc01bb3583ba03003a771ec9b368e28c4f03386563af0b5536ea2ed0c7de39c9b63b93d2f5f750f538e2b5dd26d293bc276825e19e74144b01c6b308c5510e575782f140c12e0c1ca86cd719d9af0806d373fba7dc049cc6548aa7123814e7361eaab930609ea69ceb070cc0c7126112c7165753f7ac61f54ba150da9d0789d6540d04a55581d4c352c0ef0eac4b07bcb46c6fc170653ca9633130fd6f411564d59e06cb3050fb483eae3dc27caa7203707beb1c7122d694fd9bd5798c90201ffbf9ea543abeeb2e30b70e41a018f374d692f663d218c97bdab3baa7aa76a4f2affae830170f18bf802ec6800f13a41c0d13dc3d368a5a5f20541a8707cee62c169886bc73f8a0124e488440b00f7f0ee03c4ff335e228b6c06b665b63a419f3a72240b14eb5318228923beeb6618424eb20d81bf6c77428a95b63e38e527593b96ecbc238d57352e5d07f4063c30fcc85bb65f60580a73e01fefd85e8c00bf33b8f8c6cbf984766ecca3c493ce1cfd2efe7ebd6c3f2588a08522c48d6037c021713aa880d7ffd302bd8e6261fee75e6004a4361007b55eeb3ba8d6678dee2fc9dd0c61b3547cc33dadbcecba6f78c4d972ba9be8cb7cea3cd6878939b0d9f70cb58b855f27a32d5649fdbf0279bf48f7cb5659b0bfae822a4485c693fa2887b25d42563dd2a831d6a01f22bc858156630be840a2cf792e15086982aa86adcdc0f8c4ae0c181c3224b7b50fd6f87888f4a5e326d0433386773536d8bfce21c87149d91896b4975fe2357415498c353ca263fed9ad6fc1b8a43cb89ea10092767b7e57fd303a3f1c7f6a944f564529fccb83502c01846dd8aa8c6a60da62728d9a0faa3e365bd82d2bd9c812cdc910c8a0a51748d0427b36de5c261bbf1316bb4a981c0413b1ea5b281a2b4737da003091004f1ed1239e2ebac17445e40584078043b6a0781665637b707a47a6c6610e55501260182f374110aede099dd12b340d79fad918009f5001ccbaf1c7b6aa4dd05f3c290c8247337dbbfa92109778d851ba5a82763dd2acffd7d2b6f972f823c66d63c7da6af0fedca244d9777ce2f550e9c22ae3e496ae2a42991980e8c07091aeea791df2f9d72dedf3c568f0d156d0bc9a8a7f92c638160b1aa0fac018eaf9fd15a534eadc4e6681e960eb3356848568fe5d787e4c4748c83adbf1ed69b723bbfbe3f19a91fa11c68305a8350307627b1e23d66e7a4e79f4a575f265d8f4c354958fea6da0348048a815d8a1bddedc8504b56ea234c4d633721f0b3cf72bada25532eed18f3e1379c2814b906a55c68e23213db54ef8154ff5a3a7c6c94a56249cfe03040893f39e5491e5bd1bfea20e1ad2eaffb73e0b3091120e9913338618f93e6ef2182e9f42e451d43a085683853c25917cc539d52776a5a224cd873782d794f921ad20c64ee2b9496cd443a05809b2c0fa6e24a983e74219cf1b3773f48e72835ae1acc00de47da586e2738c7e1882aec4e415e77560668d9d1e619a8291123effe0bee6b5aff05a0ed7cf61dcf5fdfa9c8341387bad5ab88714ef3140aaa416646084e3ecc4cd5a8a02dde9aa6adcf23f0da912a6e56f8996cef7e9bf3152c142835987aef421458f2ee6fbfadccf0861903db5c7c372a52c86c964721e2ea1899e91c83fe27f0f7586210f78ef0037dee70f72a1c9e604e712e34ebbb4aa504e3ba5141f1036f77ec4a6b7c136bf28af0d7cdd947207c7d563285f573523cc0511f9d6b096bb602957589f9dc8ed8264e68ca20340652fee6fa3487c98f5b44a7c5d1991c06203b6c90fab30bad414dcaaa6ecdb35a5af1d4cabe400834692240b45a0c85eeec8ffe0e7071c5dbe13424cd4bc8ba0777ccadbfaf4b26e5414ddc21b82f7cf3da2eb2fe5ca384e152800785f0dba4dbce0824b06f43c109730a20456c8db01ffaaae2091af81b1ec8ddd95af26747791c8fefe0ed2a0fd1d4defd29a98fc8324f65699c9b1bb51acd05543bc55134519ddd66ceaf77f43644a4fa0a5bbe64070735b658dad268d0ba5efc6927f9e098db68bcea94f1f456b4f087a5087e0b6302062ed980ce00a602194da1b5c830280dcddd9726c9c56aa6682b87444682dadef4bc5f4f9f8608c6e3f8e7ca44c2b921443eea6704b6e88165becdb150947c219646e76c6c167d2a1a190210b741d790bf426ee30b7e8b919f91e33b2ebd9418bc9136418649f7b41afd02a01e0179bb8a53e79d84a6c81f9a98e5672ab63f015a04b60315f7732f0ab60c6b01a35090418bb0ad13ff701fe4c41e3b3b3543364250b30c83ff9655f9c25a083dca079ce5486c9073a8b235faa96f4682d3ecbabe9025ffd82aadad1c1caed5c0df094d70a7b511652ced3f729b3d3944d3c341fa8d29b7be476b84a3d1ac66a92ee79cce469464baaf1889d58fb765ac54e020f8fb34682b92e9034b43fb85160a8cdf522c2a7170da3e7059f03265c269d980c74d593d548d042ec904bc53a3abc71d2caa9e089ff0b517d7ce11f6927c044ce8f7369802d1cae9137886147e0842599648d7ec8bfc461f6783dbae5dfe8fc2cb250d68fd9fce081813c79a37b1414895c459b28e8a1e057234a7b7615434e82e6c1e71f1d43ce350dd91e9d1b9c2d6546e7db11848ea941b44859e9fc7f4256ff708bd80d6f481c498df58794b228eb2c2dc939419692ef4ca92788b7e936129e4b011bfc6a3ba35a3ae7b57460addd408a432827fc4b576f5a818a7f720ee587b324f59e78052287aaa0a432afc72010494670301876589700728a5860237ffac34a4411c4b31828a0a83b409227e01b504fd50a41e680d689aac73e4c914339a07dcef2101fb4f2eb6b7f7ff86e1262c3982371ec6780f4167ccc62f6685b3be66ab87253de0484c90183d769c60344d452c510d653bd1831b9d4d9234fea688ee262e6c37ec5d1f6146e8c3becee841f54c1ddb80d3ee0c6a1e6e341c05dc185b8bfe28f5f53de0582f6b601da68a7a0da1a1c1834f0757b9d4bec8e4df3d9a87e5b57e03ed5985b01c583f6f3193b3a5ed43078a5750613fb3410936983b387644f7512936987738cd9a390d62580b0958d442f47520a49bbb1c6282094c68deedc8ed07375e8b5cd64176b5978b057ad3dc74834bd60763a9ecd9a579c34f74d10b90b459011a4ad623b33a93d8348ccc9eeaba1a92abab53ef7b7f4a0277379b579a656ff994a221df34dac4a0ecd367433d8c7286202a97fbcd23642215f50ac50de9ca2b637e2eb571e09f090e94dc75a8c750f7386c1293d5047798b4fb5a8a0b8c5358bcf14b2a1f657d07ae1125a92f63d747d5d68790c324fe71052eb3dda03d952514f135aa0feba7a4071d2b6615ac7bacc1232e9fb1bb21f045747a973296486f44635f083fe612af13edd514ef08d75abf80e2e3f31104c906f06c440f1f74fb096c2ea9d1fe186f415fc885b084c18b476d5ba70fdef549bb9f20f769839522b04a02c16b895090ed08f8ce977ed008d271bb52696e134141f62e9b1afc440ade304e19e26b2cc9945a92c5bef0229f5043d65053f491a1afbc5a86a4f5ea4611429c9c57a96572a3ba5f0a5912494e112d4ba95889be5e567d7a8b8c0e135adfc23b5409ea22aff04973a702b46c86ea733a824752838792ea0e7f9eeda375e439a8fdbb33de8935da62e40951d42b3e3c13c49837025c9d2adc3b9b4ee717c6ed67b44695529f8ceb6519f56adbfd484e25de812dc494a3b70f3def9043a50b02f3f857b57e2f8e8bdf1e4d93f707de17c109e09936d144f4b6159d2191e4a52fc9f050afeef0b8e42aff3e95a7b19879c6b7c27eb51fc1cf6f4bc2890f84209266d21fa76f1403495d3d108acd29cb4f56f78c851b8b3975cc896ca518ca7b908086a99b4738f047f1ee01bba97220aabc3648c4c5aae46905900892bf8a33ef61d010f5cd87c2a527aa40b71263eba965dbfe2bb985bbdc4bcfad42739619031a5da332c568478cebe30c62d3140603da2c4d22926ad7d448201618ca676e21c4f60bd9013609e515f7bff885e030f1a4b2ca346754729c62e8d3998aba6f638a350c62aebbafb30fabf5821e6a3c8a690ee0a7a0f8791256c4d5f431a684a1a59f292cb01cdc95b7c2c07f888f0efa3806b498bbb64c170a5057e00d38d3695b7080dc405c5eaf8f68ae2666447af30a6cd482664d3c182f885d8f18619737439c5e96593f269e50e2157cbec8b459e861b72bd4b63deb2b7b8fce0eb6f5c1c2c192acd58c166588c28d27c2d2a72c5c8e7cd87e4319022fd5cb1dabf868bec6640b1fb00659e227845d6d743cd511d93a336681b5013ff4f14451bb3986c2e422da8767bc4319c0a2427f22b6b1bfdb6e16931ffd012474a9ccc7112b76305d856180044a213e7840fa1eb4824ad7c3f68e17df9ab3bd8c33dba08b9689fbbecfeee38ac0b54e8bb7ab035ae14178d3061ff49b0fb24d0214fdb582342c08042db0e20a563353f618094005a4fcdf4a4e49fb1e3b217a4764becd2f7a2d8392907298cd33938318d35529577801725f660c0a88beb06dfd2adf471c9349d4df1fa9c16ce51595038794fa7511d1378662aa95df405173fd4c6c32d2e397fdb8bab2d7d2aacc6f4750ef786b6a8f1b41ae10671c464516b8167d1ce3992ac8a7828546a38517c01014c98e0db637a9c581675f4ed835d766e5fa12542c6c6fe7da3d2db436cd7d53c9d3735c7be313957e2924760b4a29feca253582e1e78705a3d7098e56aac78b47b896fd9083c64bb736b6716fa6b4906e650551b531b6247be7b50d152a59a79a56bdb7eea876123978f26d8e18870e665c8af5eeae32293193d2dae6b4765a7383210cee84576e6f6965827bd445e8768d96d8dc72fd9e48ee23c3bfe4c856258ca6356ef1ee8ed0102aaf7191001b13a4de583c7c84d110364afe28aa4993d0fee8c5545adf288771e4ca263b9aaa24eafac76eeb501c6c95c73e9383dae7cf6ba86b51989fbc3ec0192083c7ceb5927b59076a3d62ce661fb1fb3f0b1ae6150a15fada5ac2759c2b8a09d3a08385b236c7d188f87c6aab59d46ee4243f15c422bd740ef08e45f6b32fbbcb62ff6a410d5bf2dd6ce47f73da6794c38c73394890cdf5feb58b3d18f255336477f870ab659096c35ecb7d4d576682cc1937c2b20f8eac0309d497d4f7af519294ec01c40e5095658c3d72ad69f69f3cc5d551e4b97ef8d707d8b411dca793a1cf8ec80da172f5ea4b70c4eacf3c4c9d5e6997a29c776a04a0a20929290a3aa0da98eb69a5f6e939b32c557fe1422c8142d93e0d2707ec4d0647e17b5b9f41c944c9c34de5c35133eb3e734d2359558c633c819bca284091cf5cc1783687d6e9aa5a148d0200b7dca5308e4b0fa4abba9f35984060d65db23061ae9061ddf52ed16d97af437d2811a323905085db0d6fc949a7163a2dd03a5c076fbe616d86847edfe4fa3b8cf39d61875daa1b794f9b88f9a03afbfe8391907566fd2e20c79bd03a9ec956dbdddc263a893d9ea39f65a79a803c4a14084ed281e49941cfb215fe9743b4a13b92f2d4b701cee43b770a8710ab6883c0b3166c736291c050bbf70d0280188e0c0dc6189aaff09987b3be3ce8181c0de2ee164b3751496c83b04c3cf654b008a2f66dc4351975d607395a0c98ed6ac9c2d6a5105f4d490bd711ebe4202e84249130f88512d673e049ec025390ceeb443a160d90a12e548ab693df150813dbbb60c3888857af233d687a35692c4d7aea0a4b78352f5b98c3865abf28268d89bd62ddcea7786aeeca31edd6688df26373a140980ff817088f4e05443747a40a9bebafb99c9e7dd2dedda2a89148f95ad376d9ed3f1ec6e329680f7881574ed71d3a20944a4b2fb1b95b443d2402afa1eb4e7f0f85c6c371a4856be53c77331df4c84571949a5296d77bb106b4eee9ef8c4abcf5961f8f67a396bba5f0d98931c76596aefe379e69f61a706ba4132ec2c89370cc7f12366c2ecd5d62f1b6af16de01333c02d0b84738cbdd26c9393de5106acbc02330ad033619d8a5fe060412d648c8e9312fc25b9338272943ac1a524e8ce697a9a61a2b1a4c2aff66c693652f3d81c70783999784c9a2bac2bd0c3017e4e3e74c41cc019e36fd18ae750b92177e70a62fe239d46712c5f384a281902cc18a7c06c5aca3fc144ecf893651f7d8eeb9dc6214982b5170f1fc26f21363baeaed873490bda3b031e59599e03374e33a3dcb14f29d6fd9253fff92280d6a886f954ae501e6f5f6827831c96e2d04dd8fda042c1b8a47e145e8627c79bdc04e567d32b64725345179e52796eb00dd79981e583922a109e005e20b1f9580afff01a9862c4ce5c9b8e776cd22ad4fa659e58a0038a61648f35512383a2cf0a1f07babb039d832e1ac25efcdfeb10ceb602efff594c74bc63fa6652edbe0944186e32164e003e65e171bfcb4f3244b0c61d43fd8030a781ea77e91715e52ad46bb7b12de2be5cc38f114df0eac9a88dfe18cacd3aa968141ab7c648380703545ca9bb0e3400c9820f4e0f7b57b00487fd0447f18435a9a1327a8cae06e43d527679dccaa1264c88b5500ba32b81c5fc4b5d0fa10832ecf596c7d10559db5154a327317688e33b47c05ed8b49828080598a7734e3116474fc9b98b438486fb6a307eff5429c211ff33729d3db5d9498daea99233e984e0b6391b90101ceeba3b60af265338bcb66357972adfdb6a14bfa5000a19ea1e4378b900d75ed8f584c58b19efc7ffd35a408556b2b798e7f50dd13c207a20e468a58ae90155a18cbd10ef365dd154e562506b742b4926a3fd01611971ea0080458e8939b65db0c0c2115c2f86fc5ddcaf4e5322fb80ed613c99901dcd00c28e73a0770721103cc0e601c6482af5dce0e3c18a0fc1ca1392673c94570d0f3906b92b6a523eaa546702fc3aed4b1d6ba5da998e56d9ee9d02a1c4166e1f2ba67f841b16604d3710db944227c1954fc26f38063176b4cc7a681bcc3a33aa81ae7107a6148206cb37bfb0e30feb436c5ec8dfbdff738438d0f7fac0141cda486450121411c5199119c707a794744706f1f798b73792d446ec8cd14151cc9cb4564007e074512c3a7994486542fe0c4cfb7a91ed32f460d60200f131b8cd2344f86d1ee83279b893f7a2b379bbf74b45caa18b9afacc07cb28e62f4d1f9b0baab8d416756c23185a35e2fbe73000576677ac2b73fa48654c83d4b3c5691d1eedd8b121b143dd84bed6a59b3204a41524e6b2a3aed69e960051dc0813060d849a07308e9d4f16e166991d1aa83c85fb9533be10d6e3ad26e1abff2d57dda724a1039cc19b83fdb0db15d058a5b8cda4f6fa48e64468938fa0a338d6b67cfa4946e5c8a16568600a6a33ebe2251be49d4b0f3dea3fcfd5f20b02165b2784bf630bb0c10aec157a36e96c9a5bb5418888c123b4af00e77fbb1e0da196c3e29323a6ccb8a25507224ef9d22dd78647fce0521a8034674e201110f127928573f2666ef0e12d6ab545477b0135167d387a6168d89370e14849285647ee42cb30ba8ed3de798304ca0d8ddc3fc71168c40d29707a8c6dc306c595e75f733a87579e2541fdb74732daa80921393d0db753bd1527acec21b889906230ef681505ea1a24a88016b1ed7a0694c578041e021653a4f2110a371ca53055c288d4d208549abfa093bd5cd0a5a846ac1e4ce53a93565d2026ea5bab6bebc759831715203e417b00e684fb4f3861ac40e7bd30d5bea172377961b603846c0e5dc66ddd0c789ec3399f1c06f0480cceaceababfdc7679705ad5b4f3addae42834171697f2d9cc1705bd66148ed5463c69a195d478f749e00c274fd64fd20ac14eb7d9f3f2d69537a7f0e719421f91290dfb83b4b600c7064312b80b1b1d1dadb8ec6dc8ddfef4adce74cd467d862a4b81fe3dfec469358ce7824092b4f1110ec84124d3f83c2a44c9e938bd6643ea3f90c8a1407e28038532067059425dca205e014e1ed14a6a4dfc0a29382987b5687baeff3885c314ddc515ccdc4e0c0141adf28dcb9acd0aa5cdd18c7aad6587e483dfad0cf21702fed9e6125a3ce982197dd3332471fee64901ae93c59cc9ee1f55355f1c0e540593a21cf2b663a1b35a27c25568d05f73e51da21af59ec3c938a3c842daa0ed3176ea0682c8ae2e26ba96bcae4ec23cf217d0e294a72b091d39937cfc80cbdbfa71f5184f65b3c308c81d5f48117b23413b983f7cad29b1e2956ec16247235967fff838363f4ca7a563c744ddd170d5c232fc96b8e98d798293b2a81014cbbd836a9c651d2ae6d487cec298007e3292c74641271c92e4ac5c6dad1174cfc52da4bf2d107178b050b5231e1c3bf4f25017e3622bb922dee5aed86ce426c3989cc7807510f53b614726ba4c50493c1ba91d28b9bbf8aab9db433877ac3281be12949f6e3e473a50a851dea4f2589c80798c75c6788201387bc0f0d54815d8766ea2494c19dd2e280d6aa36d9583065a06faf386cca4348770594dd6d2a81eac2190f5a85f5c8b6906a1545f10d617bbe30631cde2a1df3ce5036d8d2e60a916498eb4d31267c564a087adb6942391c373d1d9b371614349cd7a1e19e35e79aca64284ee87e25b89de8fec17180a6bcb76c3ad5aaa1a8cff5420cd83acc4a53940db41ed2d8d2d85a98a963a6333456d01b9a018a7a57638596598baa0dc695ccce18754e45ab37768b95390c975ec166b6eac70d72bfc0c0544762775e763d8da2daf2e0357db6005d66dfc03be771022bcf7bb804c088a753c0ed23b3981686c6f8892cd759338f351e51bbaed4389e044bd1cda2b8586a989e6c5af6ac4cccbfac8109ebf5bc3b2c5be181e3b0bab9795c481a609007efa17d2810c96ec629321cbd11d19e016ffd1c67ce6b741c78898f017506e6ac6508db53f20071b3ec4c1703b3bb9ade0d4ae753bc0a8b69c2329db8b739c6257b059e160f12f881f0913ccecf18d9c88656a80fcba824c8c6a6666b22ab1516ffacc2414f73fecb20496d9a3272326f631ecdc657a59591dd35d8f2f1c0cbdc391a60b8a607262d0102e1900eea884c3c0c294cd5c47205fe2735a2517c6360ca4b37da2ffb7cd81d37f1844dd822a2cf03afe842941a6dcc49833164a051f0c5c058744dc9e8df3ac9f65b828f169f256f630a47eb8c578ffeb61a91d750eee4be03a3f4c7c6e837d1583d18e9d3f2e9ed5a2d80003c02744a21899296fa940a518094b168e0379db323fca36e637ce1290be68d5e6fdf80d5f8b5e9d6652a37223e42d4f1f24ee954392dd6345baed2b6de110586519a7e501c0075dab882898d30fd2d105b54cb4816d5e572c0f568b0986e133b988a3944fe320c0d97f8cbc524286a7ca5abc8894220f35aa272193ca0cd2dadd01f2795b110c4dc5f83a5bdcf6ab7a35bde1a3aa92314977884240685aaf1e0201790de5dcd735de1fc68dbad7cdb6e0fd34090ab3ae4cb8bf2c65218cf520d8096cc01d1114be822fa39bdbd1dcc1a209d709d9582e27c8eae9d3fa0c9332f3d20a30ae2afea4007607fa8fdca46c786d82a126f62c8f326480110d4ac20fa24b57e36bbe661090337052931f57bd73d8a70a119c4d555b1269dac5a58c8a9b26e6e6d00b2c19a01a9b508b9a32f3541381073051dd09413304f61894c3046dcb919f440fcd20b9c2873796904c6d20087edcc097dc960c8c0b16ac292a1530f014d8b35d86bcbb333d87380ae6350c6d99f424beee3a17a9502a617d9905d099c2ffb80811461fafed82c56d05b4cd9cdccacba916c07817f4a2575d4ab6a75722817966baac508dade1e6b8639a8f8d8eaa382956bac929b64d8390f549aabf971a4bda2ae39ec8ee842eb35995115862c36eb9e26c2803f7505c84318cdad2ba4c8e605e87b5bda35b565876315b006b1e7cb9776846c79e067043b56fb324ed41496c95f328882e75e3f2e96cae3f416f604123b9a65ddffe799ed4992377707d3a158dd76cb0622f98947d61dd5ee99ceee096a90d3fb61c73e93e5389590ba57df48da2380428ccc45632488707eb69a35a8536f8768f3452b2952b31a6423ec61be4590cb169e6904f9c5ce258ba63220da0c0fb4c80687731d2706b2778ac14733911ebadb0a68f6f02adbb22e1f383238f4fb793bcd08a71a921a5c1047dd3f67504238a60d77b5e747c62360554a24aa45a83df26dab07d097b0fdfb48539ce5dc470f4ee63fa1ad98c16470eb44069162b1141202e10b22d89067401cd7c54bac942f38e81a8bed5910c57721d0019f9c715be670b2c0a496af1ef9489ab0cd2263a3c5e99437735cc43213eae77e72d11afdd2c751dc42f1f952bfe64609adc998fda890ba769c5ab4c49759d540ed5ea901be116bdfe11888ba1f65e6004673cd5429e2834b840608c9f43d03deec8356e8d5ec24c855b5243af3c2ac10ee3c32a7329b99171fe49c44286141dd975ea480227143c817a9a67f1e6137acf0ce807a1a71855a300a447f996ea92bf0deac15d4cdaaafdf19f63cbb8883cbe92cda2e16fd4fec42cef6c0ab176fb6e35d3a1b1904107c1a1ce4116ba4aedd1a25a7a3dd0d6d631a250ace02b4840a23c6ac73cee6fa8c8613d46a61ee15e5194b42efd83fc30162574378cbcbb67e20b39a51a23ccbb86114926aeefb835098c1b9b2fccc51ba267885c50ac5c26dd980a540e0868937882172a9066ce102856ea47d305fa2bd37429ec0cdaba3652ddce47fede58814d112f1f6e4a0ff70f6e3fcbd2be8f1f2ddaca6facc6232fa5688a9ee5c5a1483c0677e368ee3407ceb34957a5dba428b11123f64465215e6a3f4ca33341491fae1ec00651ccce2d575d2e09157aa060d29d924307a4de2bcd35921ee88d8e14e5a78f8aa8177a896fe247b00fb68f30f5f3b92fb7240d4615a1f54c80f9f4d25451df61ed60721ec677f417aa7b49d9bfdcf7acb9fbca2a54940ff768c0401f81f1508a4cd6d3b2ed0b6aabe874f0293f5b60b9e685bbb82a3efdab4ba7ce3f407b41d5a04f0eb04a11e1afb8a6138c1e8e46f4f2b1a7556c43124d1eb3f3dd816dea9109cbd4308d0adbcd945fd83920b2fa53969f84ac677b40fd6a3b31cad2cf5cc9a0b2a87b4e69fe16e312df6985f0aaef9ba84b9aec1ba0de6c599999202564c22cdbd898b27d6dd38d3bd0f1892ef61c7e00e42eb9716c45575256678a164a62550fbb023d6be8e6dec00f711ed76a277e0512844b74befb77f0317644c7c0e6a6fff6af57eeb640bf6fdeddf5438df9d755b6d609657a485e2a07d52093843be3619ccef602b765a04a4f10c7c8a0e5bfd00d7463dea4d3d5d7adbf2944a146784c059be71a274422b6f3c2301b0148c081e4899338874c9692f72b052d96c4d93e1390b9cc7456fb1c4daa2788875865adf460031b50b0fcc11c22989cc192b23b2e3709c83c0422a5d9e7202c346bf01d95656eb30c274fe258b579a4bb9dadc631f4516e660973d6cc1d8161409f81f1887d5770c461e3495a0a46a55e120bac1ccfc21aad0c4ace2fdbd399410fc7af3871ff1a97a76da23781e2e6fe9ea2a02440bf70ede82569e8c7a1ab04735bffe7042ec839a59e59d530d3e97a8f04c7a44cc461c41aed6960147a599192cac7c96fc33324a30c5b909b894eba4486ffeb143b7ba548b8b0497f68c1bf13f6bdde8d96234c409f84d4288f3b57b930571dad601e204f7b34668e9e26362de50f6b2c5c9fafde1ce5c5914071ed4d613f30c5148ea4bfff27490c9bfe07bbeade50d115264464628583e105f785f0a776c7b803fce92741b321ae96f0f07bf41a505f8207d7d0d7cffe042d0504bdd786e3bbb15a1d6ad65202895c93da9c5aa3f1ba3a2a50252c2eaa7513601e9c9c10dc06d34a156642e922545218c4089073573275ad39c28c5b9e6512b43906c9950d528f1a06de3569e565b0e101fb22a4e37b8c3a577e1ec129f22495a81d26cf49a3b0f64c08983dabca5a01acfab05bfa9e24b22d41991c3dca043cf26578db1e504f77a6a6b80468cb63620b0dab2b598b16c2fbb84470cbcb4db236b8085416361ce07d52b80e0000ba655aad5bf850502d156d6f97ad800af44f01284a17cb2c6277fe93700714b1576ff02231c2d614665bf99ed5b2c1a29c2250d31ea1e52ca51a3d593217e130d37632abdfbd40cffe452ad561f7920940f2ed6dcaeda64cd857d3567f35d1f45d9e0b49758061be39a93877e15aa39c79ada1fea5104bc3ff3a23482beba3f59bfdb5edeb01a50336971fd518fdc88b59868b97c2e6c06fbf9d07d351bfeb5b3c18055281db5df404c1c17995888fbd4dce09822c40ffd5f0e588a598d070c834a673263c7bce922e6227c266e5761fb205909168bd09f436ada1a3a1dd171e828ae2fb2afd22e15805f9fd5e072edde6208afce066a642a0b4e9620a7b548d8ac70711ba5da86e341ae9a30d56443527f420990198ce87daa0ae674489c753f1eae7526a0e008ab7ffbc062424ace4cc24990518835b73aed071bcc48d1068c80d8dc04b66f1746402e0ee46eab251a1fb82df96908cc2d9a171368d851e5c2d9a5eaf829e3960c787b42573c0ebb20523ac51b982ea832f7d2a46a9eef3dd2330d56ae49062d49616cadc8f26b0005191e5459623caf1d57b04224cfb8134333c898f06a1fe992ed9c937c1202399838ff80d148a534fb4e381b4cef44c9d8ecf7a08ba5f4f7b798fb6acf6474d8ed1393d3acb1feb0441f11d8daf7c14150886634468ee6d619281d036c11eb437282be10ec3fe35a15f270a84ccdb305830b3afea3ef8194389469f5e18032c5fbfeed844b2f844a5411aae8c91663c6156e3aa7eebbc5d69cb7c415465f0f9d32f05fc936a35d0d7e4b82e7e3b18aaee0f1e60651936c78a9d2310f691d41b86e1855bba726d55e9960f141f859386853affd07072d3e7eb740bda16322df09badcd992e8617ff69a896fc4de9e83cc9f099d99b9bd5ea8957f1eb8c9bea08b42464e2da27e2bc6d2c282b80c5d08e195e921f89fee2429afb18415fd8286c499f3b2e0ede440772c80273d6b8ec998c76331367054a1114d933ba96db6994c51c19cb06433dbda51d741bd13aa92f24f20b38e892c8d15c62b4e2791436e403f082c81a6b8c0d558b57aa53793492ce77aec5a118dde8607cab614fa9547ddfd28ce7949672bc808a0b743a0b5b8a0ef1eec90bd7110ec87506e75f332dd29cec5c7f6b2da8f2986da8f2b1d936acc0c39d4aec269250ab4e4b424d456c91762c2ce720a8ba1c70d5b4815729d8d59e4834828742ef8c4edb20d5793ee0a41f6918f9b96f8012115af661a833cf1c4ae954e56c95b191228bc61d9f7a18cf41b3bc1710886c13ce731c4e9cafe0cbe3597fc6dad2293b4fbfe1fdeee34e60aa99864f02e3c5470ae3caa1374fcd01f06de438327054258dc2c6c2f59f9665f060621dc9dc20449a5dde95435aad88a7447d01fd136271ffdce167adc86ca67945dfba5aeadff05f2b9234e52b989afccad703da8f7e64666de178cc27c0a57bb5e2ee6e3e88371304c00d97f952fb251a99b192aa58052fecd569d8d9510a2c247e8c634a99410ff77ba090e53a8f0d1d712a1be38230d7471788d0a6f749c56b4bb8170bcad854c99475045adffa396893019318b13f5b3811248465b77e3faf51d4cbe2742b71561c7a7688a72be6fb48be0b41f37a92634e00fb091216bdc10f63f6292b0f6a4bca8e268909372f3592a8978e1d624c0f89a8e9bb4625aec131bfd9f2c644c6f88f081981c68af5d1279469c1802f110a2e1bdf760722f6c9b696621916cf13d50ee85b051753fe194278578c8f2a141ca4fcf843cf2e1c20921a8ab10cac21712a6c8072575ea7627b7f67f397b91c17ea4f08f6eb6982aa64eb3246b86eb1543ceec1dec2cca229688e49e74fb560f04e7524bb617e87e6569c7753d83dac080062bd46eec830bbe3ecef358a507907b8c3fe0278ffd28c4586491239a827728bc35932af688a4761bd1c18d0cc7d9d6b1a060e0116d41ff24d745fa629575a0fde62801cae27d48e34d2e3e924c7f0227ba3f7e7d25fdeb312e7bbca6183789101b4ae7c40bf18d695b1073247d571a8110b10f43435ad4b64a58eb3d8d8c41dadd459f131dcd611c9e7ce4949a49427f8ba60837735b852c3f5fd6a9230b4ce7d3132c6ffc16fcc92ed3b331e3b84cc14aa2460b77cd75393f7452a12b8b8ecacce5adf11856713d17cb7305f50c0308d8c6ce5d4d44c028641d8b15a8a3a2c7528a98fb56b9baa0066b7a095afb6e48bb8ae504ecb96d582001f05aaa6f53c0ca687a8285b91df987cb4f1aea87e47d57773cbc13dce3a31acf94e998cd8392e0cb23fbe2d8aecbd89d0a6353adc7d63fa1227a16d78d2e77335e51c4555229aa8272562a77257962a10b52205515ff2ca0b54ca1fa429f8d8fb8b9d5c95c114c22709d0443f3e10f963012812f9fad93b9b2f79f28a05116c21981ff0c56dfdcb35849e1cd624bd81c35c687db1cd6eaf5e1364018f48ee309b93cdfec9f23da5b84fc8b8524b44551a271a0f69fe838c6511bd0fbe0047be91118f45688f88112b52c4b6abf71a79565a5f46b29ada1d3cffc745be5a810b2e4e27410770a09029c91d65a43cf8dd35ee55499a3d56f858a46c554d3a2c18adbd3b6aa54fbac15d39a929fab5c4b9fd969ab7aaacfd0e2b7928aa62aa962c302cb4873228052193f3bf98c511a329f9c6f8c101fd7ba3bc54cce3e704734374d6a6e4e772ba43aed6b15622914a73e4e100d957e55b9e8848a7db2ab5a19fd407e9b7ee824162bb46d55e85c994dddb23ae1ac53ece249125f7ac98e03bd3ee32985c63f427998d39e58a57dabb7ed6bf3c293f9efd0a4a3ece2979c04dc7aa7c7d89dfd8c647855c21a6837b1d6c2b3aacfbf37bd672c4e35333766180c50ae4210b2b069c764a0019e0174eb7ebdbdada91880bd8ef613516d41267219b7c67e0be9fdcc69e8600a590ba3580e6eb65ebb38605e5f7aecf0dfe679e80f0d578b95fba35658134253d93e337e8cb30432c4b1410817805aa3906c6fab7bda302ef00ed66a79ada4c3568092d50c0f9c79654074846fb4e363d4bbf8f2085ac4dffd80ae0d98a4f8a3f5da67b9c1c5fba4ecbf13e0c6ba08e871346cb981d078a34e55175c844d78ebc486daec0190c45a43922c75122686de5928f8d3fef60e941e16dee6ebbc055a97a0b8fe159726c916c198628b714f5afcc492c0380d57508eb7e5cf8b9531808ac9ed053ee176a00d4d6b678f8e0c052116e4639c8ee7eaeb347200edb1d431e46fa85b438bddf756659f49ad25297bc567dd7ac8c48f35e5c613a2d4765794a9daf8daf40e4b4e8669b66294b62e6cae63e97dfcc25143c18fd02edfbd833e44f45c35816a21694ccaaca9277dd2655c8670c89ecfa61043fee73a6cdc411123de06968233c7468269ce29f937a0bc56dc7dd72945e2e873577c3d091e25a1d7de3406b2506b2466a1ad01e6826700608545ff16d99aaf8f9761a2c8c0c3f8a267f862e420fd64561761f1562fd9eea78c8a08876ab761f9d9d2b89abbf22c20b7f74f114ab4f6f01a92965cbbd65971063be820238b2c6dd137403b8db6061afee943331eb7c91afe354bd0a2aafcf2e1b0e4c7827cc9cba67afb20831dac63c34d9fd5fb209fe6c628f3c45b654f62773bcd2c56b5fd29a48a6d60b682f00692c3ad47c719462afa6f0879b667e6be3fdc71adcb240c1fede0c2a1a633c439c971f37c045ea70b21a8742c5234d2d7af1f6b4a7afbc139899190bef1eeccf50a82cf425376a6c9ad91d8915a41badb33fb04e42322a4b6ef815ee716672a51f6f2212130114fb5c1bf5c33d39cf90a6a9a0d3cb7e1a244ec3904d6ccbc16b4d8836c5bfaa42a81c3711e739bb2c4a1f78edc00aef5c86a25c20f1e0f31a106d75e6300f3237a3733f8282819f5a832359ffb1ee90b25321ae41a6c37f5ce3542121f8367d4dadfa7550aeee9bc416d3e4c1a745fd7ef5e31d0b220f515e4decad23c63a0af2dc397513d7fdd49cf75bc38280d456ff4f44a9a50e43f67de8f1e98f8215deae4e1ff0991cc18aa9e8624e916e593ffc9dc50d76758f44e1545fd4a39f5a0512827d2ca4b9dcb604481c264c5949352f94b79d2578d15d7f79352b1b950d90b438f5eeb5798fe30630d8fcdd2e9eb543c2f457308123d6acb82ca9508a77010e650576bdfbaa16a15fede3494777ecd5c7309c120441ff9e095c8e71121401f8aa2855f35a34476e0f8c6494eb058aa32319d292958422799792a100d13aac30436437773646036d79ac61d5c21c3c60afd37b5eeb7107a9eea44712a242132d3550fde04ca6eb9864485f4ae8dd85afd8eef28b2e823b18aa7dbeb6f8d8f593b28676495f3e76cc5449837ff2e7cc38623118b4731795a5c3e80a4d924b05cfba59f7deb85b98cdcaa2f7592f6e0b0a803a10a23dc2f400a53828a0cbd1a1555416982fd27bf59998465ad42770d8578ae2bfc0de6fabc754dfa69a8dfd747861338e3d821f12936a73ecb4c7b3a435086c34be6b0354f69db26c184090ee31c96c78ac682e3f9d542e572eb3e7801359889071f1080bebd162cf36a075fb52e2d56b1abf62ed4250dea898ad8667659ba21e51c754968208986dd05ae1924fc752aef93c2f19e3394a59fa6be4f90bae1a3393e5b92129118b87c4e9a85d91ad68aa2a6d8e1af13f25192c1b6c6405369e54002d0d404bd7775f3981f889ded5ac71229169d288a34d60574bbc0e02d3fd8661862b324a92f88ad74ee3c2516156f64178c9eb704def822f35296a36505c204c1d6f8d7ec1671e385106fa62cb47101d65884be5d1f8472ca073ce6b742d98e2086ff7cf38bd0abfb1982fa82d78075f94b9b7b049818b86cef0accf1e9c00277bea42e3e13febefd08b21967aafdd9b12edec9bac11fe158931850a756df515b381f7ca488ea11e7f5192aba45261374a21ef44bd42867d48b4d343404caf9d68b56609ad1a4c57bc2664fd0a02322619f61778d150cd3eed563dc441c07ae42728e62836b3657a09b43e73b9bd886bf69a39b499af07048f6d033c78319f59f49934f616c1357f4fd2d69ad91464468652fadeceeeede24b708a9088c08d1895aafd2e084736a3ead5869a873d29b74483a966e1f8c76177dbd3dcf9f8b58cf8d40c8455e456e449535f69e88f5d0a821edde88daf3e89c1363bdd9e1d9f8369e8d3fc46efb4afa130683c6d8343e65430e54062c5a9eb8c15a17d6fe8dd05ba3429f4d0634f23f0d706185bc86172397e343aff8eaab4500822008822091d37bc3e24944cf7bc35622d56d65ade66a0eafa91810f2cc057ac4f8cf82eee2355ac8ba220d807ef506fe3ef38bb581a77e89a228da404de9eb877d79465f3fecfb485f3fec48de1b78b391e2bd81355823b15b63f3ea309ebe991e187295761181f746c8a1ee843ca33bd6e1230b86e867597751837e2f348bdb237f77a12fb64746a04c06a23010f5cce108f4976f8d7a08cae887d1d783e083a00a21089a1795a1b0c8dcca3f797be8816e586f7f704d922ed3659a2a8becebad3850626bfe66cbcefc704309c97e133561a653c7500f83b1a68bdad3a537dd06ccb365c331d3062ae4f22297ba536f0fdfe5a1deeadb70683debfa614faf36c4cbab86f786a63aab2f57691b692345bfdcaaef27eb5dc48257885eb921de08e8dbf06ac3dbbda1a9acb1fbc706eba171ab66f786463f5d99d5d643a3b234567dec447dfa10d7db985356c6ca14a6655ff409831163b2f61569abeb197de287fdfc99052842902bdc50802204b1c26635342d023c337eb395644c0673a16abcbc171931b7054676055af695206bb1dde447df647d2fbe40970c44d509334dd374c46b32a66c1d8ac65d19632c1db125cde911fba2affcfbe91aab882de92b5f4cb13877048447384744a65a0682ebebcc141545105f26298aa21d614ce13c73443daa56fc6aa50aa5c8da48b78f26bc9174bdbd7d3d5ed9cf566ad7bfaa3bf912b5236a67aa8a34190cc691c516576bad5dd9d3a5b105cce9185f2e49d4e5a22f8a5aa16cb4b231cc1386d4ca86908aa295186988a2285aa1e6be56282a01fbf9ca7e3ef3c3851ca040092bd4b600e3420e5070856b0144d18b14e51aef5d1bd121d42f65dfc887b736f0e1a1beeeeb144dd4bdf4decbbdf74a39ca51144539cad34a0a5483de63a46521ed36004355eeb97aa35f2bfabb518f0fefbdef46118efe0e5957049d3dfcdeab5674685d2bfa7bf72a6dce9cabeac715d75f0b7aac286b8e754613e5e30ce96b877d1fe96b875d1f5dbe2ae9a73bd321dda156522e8c5fc883ef5e08ba40b7468fd61d76e654d31f8522026f4c928ef4c539bc4858b202ea771567e3d9aad157c5e164f4954b301fd9c0539688f59ac98d94766d5cfe5edbe5d3fbc4a00dfcc9b2ad04fe62e556026985d7dd8b2fc5d830068773c30d25252424231b56138522f9324953f4e7d2459e1df64a4ab62cc076fd730f1d7aa742edf27031be3c5c0cdbaed85e0bb76c23b2554376a3b17c6d447fda06fcabfae9abaf95941c51d841d36c9802e746172a07b1c3830f3ef82009492b21b1765a12129220820882848484a4b29a8c7de67ce69b1466ca2455483be42963320909094926d9308a6014e1eaa236c4402a8a22385d4882200982848424088e092e04e5b792cadadc4af2e5424d988b84796825d125ebba798af2df26ffde4259f3104553343d4f14e672b95ca2e812e53c5d951e456f25b97a522bc914f5dee572c138e72c49b922025fa877b9e561824548cf738d2278b8137aadc487476a4204ddc8da5b0b41d646519499264c86925e69a6c343b73193a1fbe8d0adbdfa797088b48da45f09b2361f1e826c741f1c8e80a40c49d26f04492c0ec2409566ca4cd31445534445fe81d308b9e6d53753f891241262d5203f38dcbf0701387abe77faf3589ca3287de5d8d4318fac6c5d4520403ace607db16cfc7bc97a1e1c6e11f455a5af233492be706cacafe9f9d2a9f53c3848fa62991e61a43f9bbab03823581af27d849f63c8deb0475c7b0821f809ed07879523d80e1f7695dee561de7b1c4e890f30537963658cd117096208018e33e1709e879998903f73a29e8989a2094a87d1c61e029bbb38045e7ce4514949553d496fac76a18178a1477474f867a55a7dc8d5dae44baf39cfb9b98b03b101e271263eec7aab2f1f36b4f822ad70a6290483c16030cf9ccf7c3e7c5fd57671fc8c39bb469e59e76ff487b09b67acc91b4baaa64cbdcd21e0423f6ea31f67028111cde1707cd8186b449e1d8a8b3b4d48863097902a6b32199a3226bb7879431df38b643194e5801117bf5840bc58e16c32a7c6c6bab046beb15e5c3e00317217b7960346746401f1426f32276f1ce0e22307c2c5880662a357381c1f5cd52a2a6422767d55ce595f44705eced54a553d192a1f1fbe622b3ee7e9d74a85af54ef27ebaad2c5990898731411b1f3afbe88d86faaec73b533d62bd5be54396b321486a2288a882bef693a94908a83ff4a3859644289aaaaaa88d838e45316b11e6712cd103c41b89a88a888a8aa8a0a1f88789c30032740b1526d0b3027ccc00934c834e905d5bdf6d67cb3c615254939acd000bf2a5babaf226007babd7d641f67f234a4af96675feb6279d0f334744e7f347f7a662af567da4387af90b5cf68eca10884bc3ab421befa87904ac54191b52e28c2223614fd1ddf5a9be8f736437a13e91faed610b6d6652f59cdf236c6ba73c9dcbe6dff1eccf090d18fe6f0b6521a0c74fb6a3190b5d02d86421a5f4b2d8df2eb0f5509d4f711a87edffde39e0854fa71265757db4294de8b1f59d3a14c96773fbdc3f2f6f44bfa73fcca9ace04df5fab7381a08bbe720cb1f31f4789d8d111fb0e9129625fcd331a7d15b1a3634ef535c4be47ec485fd2f331af2c22f6d59774fc9c7af665d21660791bfa83204892ac1f42aa2236b6c756f46cdde717b29515726b5d45fc10a22be8fe50696bf276fd43353db5d8df058122f6f36732e6304d1a038e5d715cefb806bc37a4771cedab52ce2ced62e47b15e6c9488755b2e225e91643e9bd012fdde34bbff7d2ef7bd2b3bc0cb8fc5e5ea468da68c211d57ae990875c2ffd1e9fde09b17499da962ebfba632f5da5499195ec8397de838f922829ba38a2b0141ddfc84ed685634fd29fe45e7d56bad3b1f56ee4c7d2ee851046d0eae03fbbbe2c495092aee2327c1046af6ff5f0127389a82f0664b718af95ebed76b91d5f7c9ec91c1301c7a13c5003643c8be7a129312f8a9beeb4cf5ffadb167f996c945edf8a7d53bb04dd1ab435f7b6b35a9b8d29912d7acac25cc5b1789b7e1e5bc26acca6eeb4dfb9049b0167d3f05ab1f4ac3dc6467d36a637f2741eae582b52e9e3e5b8bfabedf39854cd9638a57fb7068dd603b7b49eb85b7b6b5b46cd966030606b972654aac978767d6ab51042f820445b8baf51dd81ee8dabfdc563acaf18fb9d46fdc96e8deaf4d582c33d1cc7e8736c675d0f87cd604fd957742821dd69f7047297c22bd22caddd31add2e6cf0ecfd12ec6bef0dfaf187bda90779a3aace5c45a5ec65b63d606378dcd35cb3906e35515c7e0ab3d61331e7bbb561bad67b36b9b734e32bd79f315d2177327f4734ee8a273ceb9f85ccb65378be688809f921b1eb69f95524ebb9a1aa2b99a934cbbadd254ce89cd1ea22f9676216c510b8ec66997e3d15a6b1c36a3b5abb41336433ae7c48ebf6750b3b8e79e7bb45def7958b3f2d380ab4f1a0bdcdc3b14953cb5d63857c8a3bc734d9f3018b2fa45fa49fb15321232d2a08dbea68eb1e32bddf455017d72ef3de1b43b8d053d6349e7eee2c56d0dd735e817da857e11b593d65aab3d8901f51b848cc11873e65cabae2731de4ff0af07e13b848b7172e2c44948d3fc6077af6f24ef3ed61f6c2ba594b234ab134d4a6bd59cd1c92e964f7db51d1d6a3dd801a22bd5b552d58bde50ab6cc1c15c8467ee6a5574a873d25db61eacd23b8c9cbfa233dd4462a0816997999a055e914b59a918659b36bd834379a009d99d86d6a5d17a13550e85233907d91b158c52cde3afd6832db1ee30f9093af6104d65af0df70ebb61b7fb0e2f64eaca696af4ec5a6bd4a8b0e160c6bac758f22aceb1f6e0cd4734c799bc53fd38112dbd5cedf98bb36bd5d74abddeae3bf8c349818f2b1567d7da5ea52c6d53bd99978fe738949caba0d5aebf56aa1d1d5fbfde96f59d08aadfc1559b3ebeb72b246b48d676f0f8c8348c0fa4fdf36a2d92fd3894475e1aa590b22d1ad552321f4da2b6658b1b838c697a41d8b130b22dda9b2c0ae6836531dbd9ebafc982ec78e8979a55f96b6acbf25a8334fb21311fad5d120b82af0dd97e259592a69204a9add0ad01556bad6dcebafc59d3a515551c932c0ac62e96c7de8123ec4714e98be559db6458f683c1609fecf1ecc7150fb1b48b49b1218ce9c5a4d8f1d1ea8b41f683be6af68345d1643c35204929a5ec478ed6729b0402176cbba567b173d8cf153d9062f7c0895d37fbf33c43208826234ee8d27c749193ce492b9cbcac420e2925fc95bfd0592d95c066b8c3ce7d6557dbf592bedabe97c46243c6e09d639a39ddb9af87fb829ab2082f59dcb20afb72cfb1a1d5e2293b954d9037ae66236569fb4a7d492c76fc331f04e4cb4b2da56459d8bf1e1ff14ed2065478a92f06f5a69e3e36801dea8b077678a30a69054bdbf092586c9aaf0de95047f70685129558d25f292548edad01d50be3aed6b32f7c65d7821bde311897b462cbc76b837d3e5af062ad4adfac4956d14ae2f520be9e24ecf7c862534a2defa51224162231d090af950e650d90bf64677a335f1f9f7c5c59b155e7c0817cc543ef5c7d31796fd8cde8beef1e5bf3c1e16aabaf270a9bc5492554e0d06515f1d680a8f5c03dad67c73d31b0e1a5810d0f377c7bf250a36e3c70bb78a156c6d82184ce08b79f531f44b10fb09f2b7a60861ff0903e08b205b09f2b7cd0434a8b6a25cf74cc297dd9b7ab7eca4f9694bfb85356b5a53cc6cace44e247a7ac9c237cf5b3fa8251eb0e14a966697be62aaa200822d803d8cf153d64ccce15ef9ee3c557df6b94d7dbf86d5ea5b9264e5d546b542bbdd581a228a2b7d12d3d4bdbb6630f45573ea3b0b1cb19c330911a9d9e1d932f4cd3c8306b92bea05f19b76df5a4ae0906836aa9af9d9b648175b1f758f02cedf56a1affb1aedcb6657bb647f8c836b63a46e0d82aad19e17694aff562fa7a9b5d79b7e0c8b1d9b18ef8dac066f1ce059df76733eb723bd61acfaccb47fce554b0af7696b68d709bb9b7f159dae5746cf8cbe9e881077850851f00d927fbb9e207516c287c40865dddc507820a76c97eaef841bc35f0d9b51615030d99056ec9d2f03d7c74fc8ba5bd6ba313f5753b49d4638b97acb9a54f9fbf58d48c348687e227eb71f16a16b86d03b2f594bac31e0fdfd963dd4f5fecaee5802db84d1454f78784caccc7bc942fb090af9496e2aaaab61757c89d77b82fb62fd7048321ab91476af878a0a32485074cec761d74d084dd1ec4153bd8e2ba26180cf876a57e188ccb31f1341f3dbcfdb46b82c160577167a88f436102095a40c3a1d4c00a1e8481c6f3c7aa8f43693934341a6304a820904f2247122dcf92521ac08727a594524a29a58cfa790c20e57befbdf75e7cefbdf7de8b524a29a594504a29a594f24929a594523e8774524a29a5942f3713c69a4d41653c986c7b111854c8cfa53f7fc04303de1afa9a6dfae403467700731c2d3430aff12ac01d7f13fdeacd7ddc44ba87921d3dd2efa164db5bfd120675c708faeb61feec791f309827d14203a393a03e696d043dbc845eb428498300f3247224d1323bc0d240a306cf3d576c768c85c1606ae01e2b089083ec5040a0a191040ecc344dd3344d13354dd3344dd33f904263d2496800093f38010f7e74610551d0a07e79123992b840902040f1851518010662a0313d074627216130180c0683f9075268607412d35b3b65e5c7847d32610db6444dbac18811f1f6f62a8d06c4aebc7db8ba03f7385a68dcd7f65ee32f790bb81d830cdccfbf7b9f440b8dab93886ee5e7c397961131c01a04f749586badb5d6dadf7bff81141af739aeb6d6da4f67f20eedbdf7de6badb58f36c9c301f5712835a000102c0d349ee6616e074465a72a68d58343bb880e9e984e5c618311582e04f57165789812d94a40091d3ad0b19f2b70f0c4cefbb902073a2a00b6c85749c00e4dc653ff62bca83d623deccdd74a6685e8d34a281d99d6f55a762b919ba82d7c2e08d15d4692a43f4daadeacea92f55a6badfd10019187bc86483967c8a4555629a7a5b9b46293b90d8f0d8f7b777bdaa868f37ad2d94b248b77c7dc8e1d9b1d328afdd8d082191c4383f1bdf7627c30be182ec66e31468b6a25f1b3de5a2fbe93939393ca5e1020942c0894b24909250be258107dc5c8e29c9914d75a9149d171ef312976fbc17ee416352885375d7c76b2d93102c7332334e7d9b5542b11f9ac7ee5adb97cbdee45b48a33697a565a37898a9eb98a6e8f157b1ed31e22ec791da4cf5bfda479acf1237d553970204b1de33eda79fa3147dd4fd88ca93becf9e91306c3619ac422c8d3a4a394d24e34297511931263d3c449b19363196ac1c1880031881d623d905482a474ba2325c4a49b2e526fa2438f18929747790b2fcea66c959c0b1445517b8c9205c906630666a68820ce3a6caa297d8ab516a210f422cda6801e0f3128d21ccbe4d42e3d5ad54193801d18d064d0c738bbe35c28875b70341f0d086c02760f1eb7632ba0c48d0b6c467478db94f713c32a361c41614c38f767eac8b1161c2d36d8844ed4646bcd873b83563419c12a5a6badbde98bb55766736b21228f2dba9387bf26f7cc999dc3bf77bfa61eae6e5c70d625350bdc38087b3c47e5d2a34909ab6887d1bdc1a6cc45c3cbc17d71afac075f1b0d724c384ab3200dd6a015638c23ddb8e0a08b589a8758156b3eb2435169d9e5ccf1a1c9b0d087782ab2aa1c94d1af79f9cb5e628c71548f7f59cd85399db3f8f571ce9cabaa52cd02370c8231c658be05d9928917455571815e046b7ac8caad04bfd254e8b2617ddd33f15a901d1b17d88c0ac5d3a706658d0b97e6420b21259b51e82fa82673ad145248d1a9d59c4d0a1b6765a7a8187e0d790bc14f476bba62ddc1af6f315a70c478d6b1cfb163c3734a5b491c999610426831c3f8e921de36ebb629a6ded4cfcb181fe35914f12c6e1be53ca5218fba136f4366c83117295e7e362632676350244443d87a768c3b622bc66a65a4972ffe2c1767967c6541545e938117c24f081d840fc26b5e77e2b1958f7b12eb4efcc4f336626dadb511cf472af6d41b7a7b090f21bcbcb572e00004fd85f538937a17d6e3743c1c021f628835b4faaa1014638c31d288040f1cc96e1817b9e9dc2664081d88f0504d4604e39c73ce39e79c0b71cd3df7dc8b21f25841041d4486b09048e4369aa5bdc839b769cdb9fc13e74264e336ce422ee6759b288a44acfb900635194c8ff738a6f3d0848fb16b8dde498c288aa24863039a12633f0e45537203079f59984a2aa9a492a5b51c9452f946df2e97f5d2ab34395188460d7a24cf9e759597519df274cad359e59cf2866da7fa0b9fce5bca208d29a59432a919bde82af5067afd94f252bed13b267493d467c597d64ae90ba594ca8bad15ba356cbd1024a5945242f8d392ceaafe2ccda19579b430a7d6fc64d9ab384671f3d14a66130caad71d7908dfe09a6033a624fd7128313b147849cb4b5fa56ba25a40d867fd3cb32cab3456c6cacee446f3d135716fdf7cd8bf5bc33a1d1246292d69bd0dd1295f0b6e130ad87cc2f160b136685547efbd17df4b2ffd84f78c7eb6cb13b8b1df7a35fdd65a6badb516c1065f83afc1d7a6141d093a0827149149d2e17c225e389fd81182208869e79873cc39e61c738e39c79c6357771ac4601458648c31c61893e06d3c703567ce55f53bce6e53477d1d846f8fdd3b9fb8f3092641f9c6c3dd550f8a4bd957e3d178341e9a8bc6da35b6b95cec9070e190d88868f7215cd6b8c33653b08e524eda5a9b928e0c467cb065f8f4787ab81adf8d2e342fa594524a29a43bf075361b9fd67ceca6ab889b96947038292917c60dff92120e278525561d198c3bf76d3c7c38d6b468415252389c9292bfaa328ffd1e2184556cc91277fdc512e70361153bdecf997355fdb7474a4c89913911a66b50a926c3be98d98cfae7f8514d869d10c28e7c1a84f36f9240c9e65fd31d76f887bdf7debbe13512285e88cd807eb130c6589ceff88ee2c8604c078f1dacb1ea88457cf39055232a32c6586433186b2ccec8d8646133c647cbae16f2eff5f90ead472342ab027a43e2d55369c54785cbce5a9120f61b1d760385642d74d4a195a4c3cb9974619031c618638c3128b95f1b375058271264a363e30267ddb4d9016fcfd236b41b1e3b3e449833e7aafa4b52645c2012cee45d5afa66252b9205122e2585c32929f9ab2a67b6d9416996b61dd49b7bfaf8a81009b2d121adbd461e7f6d786c9a232a3243e66c727eb3e36c44531d26a594253f7b5962b4a46475ce39ab373b248c3e59b75ab43524f6fb15b71009d28810b74062072c2288c47e2f6ec1e6a59472b363a5511145b2909708174402e551e14cdeb5a822888f942870b028a9625fafc77e32070ee4954645a302ba10936c8b2dcda04285434949e1704a4a7ef7a8707abee3ab2f912c76b49b1d2241a894526e763018f185b01abe30f29e9287e4fae73aa834abfe09a9208d6bc1c1a4e8dce9dc64536cdcc81cd157db8c0978dd1309a99c4a0b0e169f0b1c93e2a9c03d1db23d1d3b9ea56977d9cd1e4a9d66021209a9d814d0a26288179f6a3885c930299e0ef95a4746e419132e6c0f5b837ea1617b3132d90b179a83a591cbd91453b329aa73ceb129a4a89bf60a2347445f7387e82b431acd615394945c241c5d2cef416c0a1910427db1bcf71e156c0a46c5100ee54ad8f0ebd6afac6dd0acc7f59c967edc7bfa711763e23dc97a5c46059b824d81c548db64c1ec2b01aafc8cc760bc0959ee8fcdc0e181f1fe8ec37ebfdaa69c85025b7ba178feb23ca28b852ec820841042811b752e6014e337c783feb23c76bc8b287596b633c626c614fe41c0fd84a0852e1f317ad25775511e193fa234465f34d5994b06535d44c368d1f465d2273524044108eb130623d6960fb9d94a529a0ca99ee3507ca8a8beaa063992be28a594626b4b76c55ab11863b794520a4f9816586881851658d8c8daf6d78a75c57834af0dfb0e96f64568a1c58ab5e9af16b6461e1b6ab930912148af8e6414cc3db3aa9b734a684ee7e284626b9074403873c5b6895b6bc1d11e617b645aec0bcee7d88d3d4ab8165df02221d6f398549a1b643fa7a6870cfbd19988afc707fbd3f18f9e1782cda8ba033d4a794877d8744250c79eb1180d4623e4b3d2588f73191b92fa903953c239e7524a7674cec9471da295c29c73ce092184eb214414b1e5d22e5b8041b019d6ea1b0f4a286b406b454c08f6f8604108f1219a0cf827a17b0f5f88a763201d5b3190a88e16dbd9f2400d64cb01be46106ef1b47059b4206c3f0d83d043b41278d1c740c3d3d7e3435ef1ede1b8a721485f9c16ffb6d31d88deea2684106cc6a33bf6f48c6a21180cd689510bc160a8b4272b449fcdae8d79f80a2d895d05cc98a145afe22cd54c741482c18012c2e7ac0a9a0f1d3798155d134c321d55b826628cb001714d5016a37199a47c7db826d8a18746c458b399c46bacaa99c467d82b2b5f634dcf5ca8338a1323458756d2242bbb2668cb6dd5033822c394520a5d46b642b1da48b7203af67369c52763902643aab8776be043169641a87cf12d089494c669e311cec4c57ba3eea88f8034d552b3fd768abbbada353f0860db49f3929533d6b32b041c4ae62e67493f4fccfa796246b3f380667864705b342de283ba05692551fe6a41e02fd9824c52fb110e25332532ec2a13615ee133d6f39840cad291a49fc704ebc3f66c93ba63b57cd3b107a9238301e908a9858043799ee789c2f344e1791ef634878d6069d8f2d19a56a20073b105893c6e9b967082a345f7de1af70f8e9131ce5674316e325e8cf85e1786dc8170c6d873ba19e7e5a15646d9b4d86632da687b4acbd25986fad40707902522204b30c6d8c49f40b0be31adf82c01c409bd049b0cc8648c2d719790d82d2a9f1dcac489168464785b382d5a166c47cd80b412c880c44778a13f57fef47bf3ef2f93cef70fd2d78a95f44f3e9a7f1bd21d0afdd123b8e1d51d7c08929dc980445be7e12b5ca1f67c8c314e80da9d78faea6c965ef545ed782df9fc80cba5cb64d96612e5ebb317ebcec48441871ead8bda7643d0dcf135f2f3a66d258cb5b3035902c81240965882735b4642764e504ae9bd114f9c134d06cba756668c9d3827d88915f5614840aeea2be31ab996e82c7ce2b9c0f1682a607b72229ef8535fce0905b0fa36e79c1b3d33733ec4821a8c9da7d6753fbfb14442a8beb20e1b5e74b372e0c0253dd94607fe69ac599e1d7587bef6d0e076f364b2fd7ccf6f3e43ae6acfca7a9a4926d9ce461b7488e983bd29d1aa9649767c55e5ac8402e82b4ac54d6bce997355b5b9dbd4272c8a0b149e27b216b7650d7916c58cf48d69451f3f823419f351c5b95b033fb230842cc8b41ec84395f6712893743129d88f1a103e2ae09e5d5aecd18274b6188debdc5f5f802177e6e176a76287ece78a20a860d766739371a799a51c94872cfa6c834e6b5aec2a803e3a1c832c258d7ccbdd470bbad63c49c90dec2e424b4bf683c18087134232c85555fd55538a5c55f92f4f28aaf9448cd2ab9cab5c5dc555f792d5c1555549d5a52b495596aa1b27ea124d32579f1ef52e6fba8f5e0c799a0c86ba4c5148d657052afd342ff3308f7a97373de93ed231c6c860401fd0071c13d1a96062d2ab939dec64273be569724c4439a2f2af8b0e18197b76289ab3a9d2643091c4281cb14b39724db8265c134f6af207b6d64ed05a8ca79d62ecf72b468d3e59576ec1f1709e1e519ea2e951c639eb2bc6b6f9e1931329638bc4e2115a706c74c88d0b2468312d3844826c7460f2e51e7339e662aed272267afe453dba179198e8517425912ca20c864539badfecd8ecd8ecd8ec683da412248557472d38ee2f9773ee2f3c3a39f68d978bbcd6e574cc0b853250dafb9b7fb1aebc5b70449728bacf17e972c997e76b8493f2f12f18e91775a3e685541a195dae7921af7a1a7dc5d8f7534663f649ca913e6133a01306e3da0ae92b9ecef9326c32d1038bcd4ab09f2b80d003e87aacc693fd344dd334d94f9d1cdb426661ac555c94d3cc2f567beba6099ff9b84e599dfb678a5ea7c99e9a4e594c5da545f77ec25c97639bd11ceb48fd627938c32272618c66699b62f99215614bd90f06c3da1eeaa6fa829f9b76a9d98fa9c91e77ceb90b39f9724e3827e86dc161cf713c2ece37ff5e7cf12fe931a8278389a87c2a83a1f415634397c7267b6f84efc9c9c989bcc239e72628a185b779b363b3637ace50863294a1cd64756abed63e67e853fe045d667f7f49b7d045e2f4cb5a0d45f632d55f52b6d7eacd8ecd8ecd8ecd8e9689c91090bcce25ff9e6333eb82f05eccbc480e1c880c06740883811806621888612086b98ac340c756a7622c06031d638e217cef3157699833e8416111e6193f826e65e66114bbb089492cb3885996b9ea9f465df4c45cd691be38186aeed58a0c0644d9e9105a6b4d6af7ecc70fa905078b82f9906c442f4597ec542bbd48ab9f0e857ad5178b88149dbe9efa45dfbb899efd603fd80ff6436af10cb0b5d63827272d381eced323e23089d5fc5e959865d9c9c949d339b3e801179d73ce59f9502925a5929e4379484872d80ce974cc7925b489b1dd4624e45265268c464a8d7c06237f99e474f9262965e89e9c5439d3a8102ebcf7b228ee998fcbb68835c676efbdf7be77edbbb3fe41d1e373c41a3ecee45688eaf8a3cab7c927b887bad347e543e97b2d389e674a4129a58e4e289ee7a18726fbff6bfd9f688d32d2bd6032bef47dca44174cbeb4a272959172fea45fc344652a91911201040000243668cbd2afe1858b918d4848a5c960a8cb24e5085fab211a6395dfae14ae8bce39e9de9a6c8f31e6d8068a0efcb3d9d39a48908d0ef72494325eda4711f9daf4c5e875f5deb7d786df6ef41ce176ada690aeb2dca2b6d6ece4d0161c94439f1e10a52da6504a29a5a716b255b3b4194f4eaa1c73501f92e7714f8e51c6bf28677ca27c424a8919425fd1a13f525ff7b447f3c190a0b2be4ab0be38565f291a2ba18f2d8fd1178b028c02c4624bea972a6cb8fef3a09000e09a3f0f4a001ef2e741114089c96bb06e623d8f4989f53c2602b09ec7240016002c12cb06eb792243426b4b5f4f8f2d7f7da5bcd01787b3a588fe969a8ca42e52923247158a5bd65921c8c51823b35a0d22a3d8f26d78d8ac84a8442dda67357468040000009315000030100a858342f1784498e4dadd01140012829a4a6e549608d4280a620a21638c010246440000000064340100212dd91f2871efb40445a5a50e7d40ab9f9c3a9621a5dc0d18b915a418a7e35b30409a17004c36b880ff37a612f9fe95aa9704470a5afcad7dadb9ce4dd7f3bf93a43027689bdaf0f94de5947e8d2f1e4c60753e77c507cdd9cba66ea0f7829a1fe588123ea597b40d352b01a01378725f0998321c34f41b384743675e39f4b62d7715e0fbe6e1826275ee4d913de234690522234e712b86b570f85c9838ae4dad6ed9e22ca49538ed87954428ea875a2b7947fd01e5cf12f7b81b847ddaa8698ae29490faae8cab026ac75bc48ad34132b8c1cabb562f71ea4d896f2a8862f28d6b4a03b3162c88c65e9e89a9bfffd2bd5d7d8290198cc7ce6d64798e6cdca03aba779365897245d8578b8ab4e717e96e7c324d4c163865a069e4afa8e357c1af98eed5a4590cdbc41bd24514d203ea2cc0fbaa0d41179fe02174e929d75b2f22e03962d0e994b7b7904136a01574530a191cc00fe611638d0bd9a96fe1d3ec2f929b36135cbc61a3bcc77c3ed0f96cc5f9c380c77c8edfd6ab81c037cf37272ec68d90d2974c7711ec5ad3c5e8c9f0a98b2a496484008c967b9df52eb08555fc62503fc4282ed66544f03a02a2d90f5b064335d2386e026820e8340925e5ebe4d48e0a34f936ea09bc7579ae61635ae3d2274ac8274a61a62814747cccf8e094fb0d90e06c821820b0a7acc4c811a603339ae5a52b420a2e1fb917822a94919c0cbc13041c5e60db6fb24fb4ab5a339ec84ae8eb8c913595eb8b3cd1d4e206fe2e0d04f93ff0b95308bcd9137cf29ad736e8d1db7390b323d0d2134d08d181f1a2ed7023c74c71f07ebf9cac6a07fdcb88430dd1775698ec940a6c75671a7819c85d6d47417bb5fe7421d737da1dab09d8d809015849ea87273fa475e599f38b01be9323b1b888b836df938c9eeab0a0cface8b3ae546951f4fbadbd3ab6c53feac931d3b70c6f495a4f1248a6e881e2b399c5bfd83e7d3a3d73d1ff95b0735c61d1bc4f8cd675cb2e929ddcb711127f9d50587635fae128e83a9ab780c4d566b3562dd461229d4e3aabeb54544ee0189472f02c985d59a7768801c7ea3ac99b8e9b71075c3e19b9916f15f6060897b94214cde3c7a154548a708a7a12e9f3c157a127b0e6c9585459ae3c842141400e33cb455c3c9a90501afbe1a614e554573534a85f5eb4831c10bfce6a63e89cd3e9d604cf3419fb0c4fc704b481237ad24af5529fccb369143f8a7f2e5853bac1f26fe71e686888e2d4e8222eedd0b93c17d4bc77782e709fced9d6aa0a4ff7ee7e5230ed6e6a4b95d838ccc354d62ad334289522c6d776931d3954604f9d429597a2d13d75bd8abfbba39f5774525bf9d606bf3119b416a8662055917bb20b4032895f0685c1e7c09455871d852b9a7b79504f0864024d5beb3608eeb90b7b27c28b5307e9974c7e04430b837bdb56b8c915d87b255d0cebcde5b8560f1e7af8f722099f337b27b74160beafa7f32bb352c2063bd19bb9698b779439c4dea63510f8986528bf14f12665b6d63d88832600b117615fd132a806e59ea6bf55b40537478871b7f82cc62c84bb25601a901adf6e537b3efa2a1ae96c74036a915600d6ba8d4267ec0c00d17db048b01c913d0b557d37ff8685489924c059d05f7e3345814ca8f447e1d1f60028d653dd6e45f3a70c200b68bc06776e9641ce3ef7a0a158d90b167784427313781e956bd5c35feee82222c3ef49dc566b34853f16912aef380ae406fcf4d1cc41e412934c3dd426ac958ccff108c7b3d328301fc1118d1975bce4aa7f710a6e013cb32e02e2061d9b656d992408c1f93760f33149c89c60743e641300344e7eceb86a8b7c4c061a7192c7efcec644c0cea969209492db322d8c27f4d5da07cb95f72b0e5701719fc7039ca462c19d8bd5f41cd3294ba70abef429e992b0cb8558ac92ec7203adb7dd9eb11d54c0637c6bfddeec9430a4406847f63b8e4fcdd2e49ee9a89624c7b822a5d6890da80fb3635262738b83a7be594a70dd484ac12a809960bcb130f354145c62db955f57111c8d2082794db9e8e87df3165b89e77b0b9258ca30f7eb6f6ace7140b554dabcd8edca58bb47e49b361f222df628cdb25f9a0b35ad103a6d4ca384805a7c1f726155b9a5950eabb451c4cedf512b7db6c8f7a3865446170eee47571f45b4efeadda281774bc54da540734cb24c46f7efcce25926c36b76b35ad214a8dac3d9a1437453aac881580711ba0f70ae93681cd83c03254725c26061d30dff3783657f4e7abe4275c8f97335fe615ff236d0ea892430ec22646af2925e3962a55116fa922ead79e6576a77e14dc86c7fcf7af8d4aebb8eebd68121e095a1b3eb40ba96ffe02829238458111bd593f13a5eda5b8e80d1ddc1ce6ab654bb64db26a23c4049059b3142a066d15ffaf1ec96fb2674e42fdad3a7debf820100a18627138dd52328dc85e16773e32cdfaf306194e55c8f6b4008a70e3d94365fe4fd10d83be46c6b12843424d50b9c0e6eff241f1f32b8429d70b30a6361df388f88177e4fe4b97217f3fde1fb8a4209b59ddd8878242ac63dd2c99a6cad44ff2fdcbf4b7dda6e272e409e79678eb99d317023a487eda09b43f358d871b1da41448380e76a88e07fae1069c6de95e70e000336880df405399f1a7c10beb75e7103901772d4052c551a7ee9326fb541fe2206e9605546671e627727add9c7dd7cfd87ed7d00a1afc8397afa9aaa2594fc787ad3a503e48d44d0074a0b277068184645aa544a105be7866c9a23f73b33f949704b106b2266012252bc197fba74c61bdab140203d5c85207d3355e71971f941453aff6cbfc4ce1c0b288277709eac6b7a6e7c605c3445d7ec0ae7673cd1a5989848a023191bf4d5686754a1c1d7b2ec68d08cc97516d13aa00db84845bfc48e8b05e2da1bae4a0c8b12f69347c64b21477782b3a03191a5563647509612998dea7f8bf98c0904c464111a0a6258c93a5f2ad53128023136fff830695bbaeb6454047687fe834c68ce43a7e14ae93443b3082f9888c182797439079c468fab565da236d4589e18531798a778f031734a208a19271d4dd3599c951fb7e8ea88cea31c8713d861d4f69ab69a28683ff057b9297cb9fbe0225dfa59184960c7366bd74ba1eef1ca027c9f63087588fe308598d203f80178fbf2415720368299ffed94899871b4618eb2c181cb69bd8e0ac5657a7bb8251d1db420b1d28cbe08c7ba1c9fdfed9f856e737e5d038433154ba94a2fd91df0d36f74be6bfa9df8ed1d1c1060172f7712218cb1616e27e678e7dcd92b55717e670457c1b9c143b866885fe1091051e3bd6c391360b655111023f8ad154a395ee4de906a7a88a7623730b475ba8bf9a6701aa56738a24e625c16c5355e98ee076c100e1555444586d62318659367e4200eb8684bb064510161206b4a300ea53709390c4a90b2c9318f72b87257a8c7254474de6033f646ecb3367441929ced57bf4789cd5053db486388d2d0c4e9fdcd3eca2941c4369d4a5012e706940b3db66fd6d51b88fe671d03063e14d895aa7959731cdd9ceddafbb58a3dd32d16e1f9026aa02dd23b53fc7d2eaf57bb4a7817d203c66a69473a2a69fd27062eae68ac4040920756fe68baae622eb038cdbe93ca5c48346fac22c43980088103f9ef45a976520e2a8e4c66ddbf3dd08e172c016ac5650d5db05ca7554a6b5ce92287a0d702b971b9bc6bcdbbd679d70764233161a7d026afed9ad4b79992f550be69b0d8e2e46f7333f3dd28924f373f81e8420de1ac27e330e62000300a55c6b7b5c8bbec682bbcdcb8dc12a0c8e7b9431f6908c64b6b2377bd311ae274ce54ee22f596c33c34f3c49db8bec07fdb090993d8338496fbef7f843c0538c5ed724ff6c4b227e83a7e5611121d80380a4bbbb469f654149d384d5174a9b53940bb1a2572737f6b87f900d33c70f149790a0846633d4d9a704cd0c497b26ca935394a79ef87f46ebba7c7e208432e82449bd60f1e4589a814353ed046571ba774fd041369ad0eef92c138a02d36c56de78d8d923e524c0133e9ffed9757f4a25606cd51ce54e67c0b0b41a26612898e38af9c9c517fa4bcc5a2eb4c892b623ab3a05b6dbdd4aca5f40a89ea408f8ceb45322bd1b126255b68fc8c9a3f5252f239f205730839a3e904f1fc92e21a3f82d21cc852e307a3f66b169bad118a59d752b85ffc85b7cb3d4973d9da1c84cb31771409bba0e42c7710a9849ab010ad37e23bce2c9726d02547e1f69b205f729e0886494142159f8148e3dcc2a3f4fb082a6d04172f77a7cb9ac9653a08acae43acbef92d0cff5b1e10d38c54bb589b7ba37529515a7c2aeb32507e19fd3ac67fdf9eaff0420d83d51bae150bee0eeac2bdfe06bd586060212cc3bf6b23e505f399380fc2f1181e9783f2f6ec1c030dbfdb6a878752b9b68816e99c88119f1aaa3b36fbb4092facaf9c7d5985a64700b00c9d067fc937d967465e3b5c47430dfd1cfca8bc3e12be1330c8974902f64b498bcdc688f2622a3e36f6cbe291cec393b0afa4802b8af920e491010e9a0126fc42b45e199be63c70b627dcc60c3dfa9f3c144a9748fc4630121aaa0bce818a178f2f6d8d2538681aaf382f8b9bb31589f25a88b5f4c54d3938f57bfe196ea99a631613abdb784aa24d1a996603f148078c4c2a62f12aca529518687a074a342a20161e86e89fcf2a84a3c4df302d6e492453016c77c765828dac36a7a26df925c1f48770a7249bb1568b3da1d8c40a2603f253f2f17b8f7aab515cd9b58448bed3dcf6d670b28e5a2eaee2688fe840ae59e6a4a96d61402dc63825c63741242d870654c45d450dfe1887751713602f002f9761116582248c9fff057e3f6cad673d92ad038090593a00657b344565acdbe7491d4eb9400090bbe42da30936209c3035339987e3e5163cd7c748886f6a1a27af116a6bd58b55154200a296ea7b670b25edf3cb7de32580eb9db5511b1ffaf72b2478e3f58f4dd1985a6b63d2fc4bd22cd24e886ff6846bc724803cd876f3767bab01f155e7d85e3d78e77de3c6a4aa5f85eea76824b6aba27276c38e73633df2280cc497087a85a686ca8bc29b7e8d8bfb4bd6f0af20790f21df5746e2fa6a1fc5001be6e1e8cdbf2f7c6800512c3772ebf025be77ab8bbb13569eda77f17e0fdc11d81dedc03a819ace8aad3bfbd03f2dbf5b0dc0824e9f8b752e7a7acf48a14b5a25abb94fcc783da012e76c19711dcfbd106f0ead63aed77e6a1ff0813314cca4c616f4fa7e0fd2e0b98cf6ff1ee8861223bc4f739d0366198887f4c600b099f4ade1fd9cfad18ce23d921ea8077459f70211b314cca3782698ac6bbb8fd658a4fcc6653359a86e16381d1336f1bd95bffa65499073de28671588bef6ee4caa62f58c25cae42ee25d89559edbbe18538646cd17f5adc201d8a2390b942ca53ca75c533b52205457208d1de14ca81fc4f8cfcd618c110c07749c42412d3ab96c742d04958f7b0abad2d622c92d8dd3a1953d78c1d2216aea0adde641cadc097399c771e6be7c904d1c0723b2724522c2e1f2919d4c1620573a397d8e128d2bfcec57e7dbc4ae3d0e1c782b7fafae0f2ac123dfeb8b75fd086535dd1ede96ecdae77462e89f81cb631a3a2f758fed4ccab444813f65c7e93071d7739ae615668683e5435ae258db20a6923007b4465875ba6766e0f8d918dcb55d8024160c529bfe63b854e0b6e05069346877240cc070a0fb4ad47168138628b7dd5dc480b460e460220f94db4c29ef649675929a5a118dd85a40b9c08936ad8674f111e1ac86a9dcfa5d2c89e340baea475c22a3468b3223f527bfaea7a5066b656b4a7a00e3b0900708516bd0f0737ed857e9901e57c66eb04e1e92e2da5127a8183ce33335547e70a4945e97549ccdf25f09afa3f9a7ff6e61d7e0d7bbc13837d58a1d8fd17e728062fb843963df924c2656338923997c1dc1c97664a2d5a1efd19426b27e8ad0dfbdc49cb91a2d653e6dcc57ffb856ff66ef4349da5530fc3ad8701e4fd45f6829fdb29ad2ee7fab72cb877afe72f519f8fdff0c3e4819e5fdc0c69b4ef55ffb3ec643c891cd052bd1e7227d6b5d8afba31598e1e1002b7f46fa1e6090190b67238556c6a00365690c836b52c4225f4692c2afc1ef9a9a79a5729df72adb9a8d8d360a1173a238f0b81f0cee0bed55bde85acec05b42740c687dcf3a509f4c78be689aaa6118a7f5f83d5ccd81237e3f7fa64cc4ed9110e6be5db605f10916cdd36921d1e8581ea16fafa33e376dcfbe0f0b2dfe36dda2fd92338367f18fe27b5ca708752897a1fb0d3d65e6fb8b0e7472639b704815430767aae22bee4e065365801b3ef3c6bf5b46e0538abd0f4da1c30e4208b9a940ebbe4352a2065084b4d517aa329674aca15749bf4be902369db5571c1b27576c129ced957ac235257d129bde471f98ccaa6f85e41944d9be3e710ba573d776e79c10a87f14eceb619ebce7ecd8a04099a742e1f79f7b9abc1922a83e67b75c5e6cb4c49ace1133e7dfdf35f6f40d6212aa35687d0dcae93f67f85a30fbc650090bb6c700707c7c61db6d2b5df67776e2c863bcb1b20b1c2055bf1af0713503109f1d90986fc6d218d11a14abca1267bc3abd68afb831accb63fc456a9c3339567bcc8903f9fcab8063fc700c890df20f16938f666e330ba33c47cc3490dbf611f2911b3f53e92df41f6cf85bf09e8bf9efc3c496410c7118d910f44bb6e485473701247cae0c77e18c11872e0dc2f014cdf08892288ac7f866c82ee37e045e1b6953ebab4bd6af615325050c5d85aaaf131257385141f609bf8a1704f5027319ebe044bbd1288043dc381fe876d09fa36f42f8e6d9e30e11e0e5512f725f936bd99a2846c935843040207299c80c94d1994b662d329de56033e6886e5bebccad7c23d862082b91a9e98213911d0b4c29aed3c959564af0f8e8f45cc613cd01451729a3979d067a2c5476ca22d9bb81c41a3a00ca2b97016ed0f052f28ff085a62c42e3ca325a8648d603374c6f826a9e9da88794780d43ab1ca467e74883e099d27d752a38550be2c002809dd38c6c0c71e063024d7ae904e13683577ff082e356a61f6fa4eb97e86442fe03c0192feb63300b79c08132145e85e165f60b9a4e288c7868ff64d0befd82ac7cc4e10444d279bd508ea38fcd19ec7708bfe5c6620cf2f39d430c21b31d5de761f3165fe74173231d282bde9f06f7375510cf682e4435258580a9c7c0010f46efea29e09a4a7e9a0570e3424bd4fccb738032cbc3c6e6e2afd92e6346c472636c9c81a162a68a4b896f1858759eefa9194ef62d9f697de5c39cd028b800a8cbc0200fb3c693f7dde5d4e8c56c08661f62f8e0cc6be6304a670a7a79c34435bc70d14268d0bb9659782853d7e67a911661aec89bfdc67d9fecbac7c1b56d2ddbd5f54025785cbb7eb1b47fd9d5a089b73ab4a97d57e4b9283062cd6e8c1c8c70266bdacf665db6fda79645fea384fe74e754548b12bbaef3f6614d9dcf9849c15a0dc3408420c502934378221a8a8ca196def96b211710519636c5ae3cdd4afefefbdca456afd590fdc0af6cd7fe1774e0c97ba72556b7fe103b8065187becd103cb862f9db90d969b09836d61b9e67fc70fcb1b333872987b919b83caa1543a6063f93921356f8e65eb63d91d0d6360b27d4196756d6f1125d348fd4a0473b6047318b74ee1959e1d7dd24b5ed52898491edaa99ca369a53e4529984d48301383b95a69307bee60869a9a132cb558207b1f9f6818aec4a7634a42da8133b00d5a929c4d544ac81ba05992adea2e42443e05f691dbd5c1e9eb81af1734e8d3566650e96767d190e162266c50600aee7899ec4fe0139d69624e39fe0e3ecca637a597211fae73d806dd79928df4ac53448c59ee2d6a425dccee9cba7b413316deb5c74f84d9860aacb05803ec58b98fc64fb3aad7ab10fd27733032892452a97766674b234862e6e16425048df6832918928335bdefc783a55f1a2f82426ad39b44f77be47d68a0c9ca0a5e4adc589b686cd31ca8c56425b6d18fb3158b280da591766cd56b32978d8366cd0532b1cf70e84c5e5c5fce0b417af7e1a6e3a8ff7106c237755499923806c56a53586835ded30df2773fd682bac9d21416c5fd0898df5b2cbde8042bdc4d0f1b047a5a7c0c2f75099003d7146ef37ba9501acece34c376541f31cf15eac8bcc0c02bac434be1f1f436198c453d3171e569a2d6fe04fc95f377c81700e321c3df76cbf5aa7da108cb97a37238d844ffa635ab865a05fe94cedbd59546bc6bb816dc3ca1609059cce555739090b19532c118d34f9477df572d02dda2c405832cc710c823cf7eb33cd90cb226fb19fcef0b0d8a320c2f48b06e473e40b6c49665de8f7480d9f51e2c796fad1c1191227f7c672e92bc7743b80ac71d4fb91e029d71bf50e931402feda29868a072c3049ef6ce5e154ba312059389c5e578d0ce0e53fa47ca1f71b93ea10798e99eb423be3e92ada7af73cc72ab506cfa6d949d999b30ace5ee9d38f2ac0e7c8b0500132cb99d3d6d5ccc556e5328d8b815e4b25a37d95e5876c0e9fb422a8552afbc501ea3eea2286049d6ee49ef1b4e4a1e7a3b4fecda930bb5091aa546228160c3d045b3a9bc6b6c800ae5b197249c9429428ae56708349422301825bb3140fd3426603346bd3d25ad423ed083a04d201697d581f6184787f03b1d138c66e6b688d3069f7a6395ca060c9aef326b6a2669f5261e33893f29c355fefe110a3888fe3b2ed16e2a0017b7454e106edc624d2d9c6e4b6f596485e36c35aa77c084c523ba1fcd25d6f870f8c6a093f6ba476fcedb0d30ee797f326f8d43f80e08d973f11357ebcda3a6799b742f3405673f1fd752706f6d180b66a2ea9c6304381fad4cba629bff9d982dc609850a190f51253dc0b19812d051191e20a9ec76220e76c90b4c4ffcf17036e0895aea405c9860d03778e2f9cbf7c68a53360477103728d0536944566e7ad65ba2e86f3cdec444da6c89395af660ba6018a553da67afd294f21ad851624521cc6476ad346b709e76acd78abd95c4ad14a59e793e29e73c860fa8bad28663c6be6ca03e713aaf9410580b811a5abaef2723759bc2c0804b4b9109be703af3333006af20c16f3ca88727bcce1ae0f206912b896e70e0f3f95a9cd2562e2923e09dc6a322ea2c4e0e9fe01edd26c07483e8c67e2dbdbadefeef089b9ae1a69b370a703002508025817fe30e0ef332820436335e4ed0853f2472b9d9cb025cb135a03c7ea384da3c34611e396411909e9d50fe0959ffd03ef1d5fca6173c1fc2159ac1a97c80b1f1cb36cf53f297e8b9afc505531be4e2088f8f9c8385b78d850d492c642eebf309f53b9030e5bbe710b95ba483ed81ad543e57cb5ac92863e56f895bd6623373de04a3b97ac046d444dc8bda03791b4f4be707d9f8142a49d1f9e28f08710ed6881ac86d2d22becec5f6e5e82ff49b4ca0603d699d62e85d690dddfa286dc7626cf57694e5595d83724935789877dcce0cf2b4445601c941970c2212377a66c62f4df1525763c30aca30b266cb160e3b6a117f10ae52598e7b697b1f843508534fa775e8c940963de5cf35292dd9c131e08d3dc560dd058cca898db6807266b76f6651a86d0f075547b4c2937871602691bcefcb8313e47b2471c92d43c6715d525d8c5bb16cfdfa4cbd0be58fa5dbd7c7c0ae557e093313a04ec706f685107ed044fd44a9fed4a76078f2e0316ae020af8cdfc76f31406e1ec5029ba4b4070a34056757aa14a32501e80b8b9e067f0981ecd1ffbd07cf0119d17f85604f512a06c702f9842783990fde268636f7dcbcf4fd592f9b8375e89fb5c13cbc6cc808c0ed738b46d78c40b8355111bf6c260c511a590a5959aac9e9c1a91211653f8fa0959023c80cbd670faae3c668074ae3c1d0420de651476a11c8dfc9e34b258c87ffdf8805bd9b3b1a31427a82e3375314565d02a6330625cd98fad738d5b98cf158695b2a950a65ff7214e331cee8a6aac692d23cb1c791474ae5944e0391dbaf02ca6a37257d98804b4cb7d624cd3565e1e01d05ee2c6d2ded6dbfc42de3c13d8b8dc99864aa9da03105119b208cdf676b6f2d3a50dc3a4b1e43669571495960fe1352eced63ea66ef32c63176787b0d457c1737f7828a78b46cf8f9a3823a37f7786be1d59c8786edbd18ff28c9d454e1a8607b6cb1f0fa3680b5b9971e6c85753f9bbc81c53f013c4c2cc2835a195e2e40173b46c4581c66748480a340451dd70226472349d5c10946d58213c94b4d6617f66ca2497fb29cc1b4564458796aeee4694570f433d7f8d1aa52158937516e0ef9fb02d4a8238a81dbb513d9249cd00681908c656275070cec5c1b0a42c67feb05d9bfb364c643cdf96709567a3bd2bcacbb2b8300b2a45d9403c120e8724d24e4a786390fb8277de4ec58af842050ed85d07308dee097320ea1f009c0a659464333bdc1d270772dd57d821838acf23b869d5458f3a016eb28c4e98b0bbad7dfcff576ff5051f84f6f01c6aceb03e90b4ff4439d699fad4a15bed7551e5174f1c04cf9f49e4f2af4f3a7d79c99da122953812e9000992a99e867c176818f7b8ea4fe23bbbdacac3060b4cc41173adaaa29fec1d3c970c40270f0d5229c09dcd0a09d63f7128798baaa38145347e252e9cbc784ae9130e80d25ad7dab38529bc96bbe200f5123d5993d28e33543bb4562ab37718a1f28b512af02a1b5dafb3ecd1405323f9adce14cfef055421a27e1ad4a23b779184bd6193fbe2c4da78434e30c0fecaedf65e76648fb10cfb02b4d3f1fe69f02c082113bce24a6ae996289903cc20eac2aae2f506888d11950abb77ebde98d50bf349c183f93a6e9137fb5cf99964e1dec6c2a92b7f4695aeb92767b6510bd7612950653136805d9719db6a9248afb79830f83c0d9f5d4bc9c12a669fac18df63d801bf42d36c8875a839592d3b4635285673004bee48d0c8356a02f3c276c9e3e3b0b69b8b4734db490cf5057b43e593f96bbc563df5c5426267836533b13a0c7f73caddc6f051b1efac8f1bede171a53399599d0322d741590279ac4bd15d2ce7ca8ea65cfa4f0494c3b80ec82666fe6e799e369011799647e7e9efc52b3e4a9aed04e0e40d2d6037a18af319ebfd322264b6a9b88d81dc72bfd69cdfc66cb4edb12599cf48b78bc9e9ef8ce1e0ff44836833ff093c6af3f1981442e1a7a6fa62b43d25588ede8aa1a0ad3906fa0aff43e5a4561fc83f7989c06bb8cc14672e36cf7394ad9766514460c1b09f3962bc8698e3fb734c1057dab5b6a209df6825eef645992767c025595353eb481de1e51a36da05c8a1acff36a744fcd21de716fdbf09f2f1167bebecfa9bd27a0925d20b865c6f4e7cb9f48e0d85d9b89a3ffa70fd09d3838be4d90238c0f8f7f027474a2d7483b9a3c4fdadf52333b75fc9cc48d3dcb15809ae97c910f259d7c3420128c7c45f4ee999a963bf59d8b532544135f71860c41e32b76028448bf7d54352d5624a309a2f03ef02db5676d5ea76ab63eed65c07df53da33d9a7c604dd15e2cb43ff1f880480261b87c79c55c5689ac762048230bf11f9e2450ccf01b87e5e52498446cdf5b22b5c57ce676e86b64618325636bd283ad5b553d827d9d19e980b0d6bef752050106f46663fb6b76cb6b79a9ca5cd5785988d08ecef6a8139956f16c29bda7443a1719918d3f5be2e23c80256f5a24f540cae906ebdba5aba843007b7d11c5e053bdfa118a8daebfb336e14d91ead334139cfcfafef94e466952bc0b59ca4e396f57e6b9bab00786d2e0ee9df1ae96e113de2f6c7d0effca529da6b0997b0f340897f316d943047373040240e1caa70d3406d4be0d8719a2cfdc76c5e928ff6c845d33d16b1d1d05408721d5ec58449a9c1da28f06dd74ba0d863e24ba6aa0fe0b6730ecdd3ed590301351fe0150f160125f803efd6aba3a9553dbdcfe40ad6ad247bd0c42632e9937d5e7ab233ef7b6ee8555c894aff251f304cc8b3c9670f5a9ca79526f45f6184eb8ce30a03a9b78477903600a9382a172c9dcd70d48ba54dc3f13fbc035cc4b5d86f15aa5753b29ab18575b0a35b1a3b8ca3107ac5e9ad2b15b0d5234a5aeaacc1a954cbbd09c629f34bd5db1a01587712b40ecc619ea4ac600a3ec173980344349087c32f1dae7a0e202c042815c3ce3572a1c76de70ef3269b9879411893cd5e90fd53d94a61d85325729117c9278982e7a09edc621ce97d0d16bd29ba2e887959a414521de0b5e3309cf106b250983598da50729523effc2b8cd01ec8dd846f03212b8a5613896a5821791ca6614c6a5346f467053f88c509a0a1e77457185e9555bc5a8b3360cb6d96868ed4916e45a23e5f42334801ee484820200f1ba89d1b6d9f6c71b6ebf15346591a882744074ee88c7f9b46886bc8585956595332bbeb9eef8b0775cae08e0f90a9e93de3fab7c06d6e22a89ede2edac8331ff4470aed3d80a2b3747260ec7e8c9b4d7c75e46d72e8e14bbcef8ae7a4d2022526ecaad30973cd221ce87632972939ef3f0cf17e547f66548e6dbe80dae37e42ad4f08660d5c62d0d11b3a636620158aa73c8782a6b2aeb36a5a67aff75625d33b26d6947b61d53b7df289124ec6ccdcc9ce40648e218b3d89ba42583d52bd67f512b4a84a95330ec0abfbb5f7cb75c1e4075e0f7cf155c1549e2b298b1364f14370a7d7dd6ea5bc8ea68c5388d12f2d4fd24c2a12497bd3316011964bc6431c89c00e6821c0ea121fcb0208d0bcb18df21223eaa051f0027a297ceccef0b3970edcf4b934a622bdaf7b6514be115a47f5a70b36010808cf92933c635ffb1015c5a2a48d568459f637408498cc8c77a289d413cbbda45143db64b044c21e5f7c292fc4ea2cbad45cc94aa9079831da807e3b50c9744eec26106162602839885c961c0b4b95c4788bfb64ef9d93b6ea1c4edff05f9b49e09cdadd6c8217e2932adc31d83f9ba8dec5cc9795b5f5ac495c09fb459d16b6610483f402b08f028fc1420760190785b4200c4d81f2ad6dd2b7108042f9640acf5c4082d6e265eb34747d2db2e43289c51394d4a5591d4fa773767a0603af2af7134ff540cbd8e454ca0d6949292324900dd54292f25f3717a4937e93a5d427d7a2b459f7be5758e90d8f3a581fc9b5f93a5fea089d2393de1b43653ed19ecbf3c799d691a9ba118d8b4c51910e55c79da601a8b3b3d272e69002d54ce16ec5c99f2e6ebd082f31aa3ce9a0690fc21d71f83ce8088de89b7c5092623bd6ca3f5a1c68addccdbbf3840331bf3b5f64e66274dbfebee1701d6c91f8559d73b266729f643335d18b845968c0b0db0a5cbda4c2fc36ac826da38f7f66adfde65a6f7667aa2e2a83da3b050117c9c44054821378fb2c2a962995ea85d4eb0f5d8ff4ecaf2913671bd94e9ecfc096e9761219211c00e31f390353887c1424033fd3c4cca2052e7249c8a10ec35e358f0ce7197197962c469927c2033fe7d7459e7599ab0686721c8f7fd0e842ad3c606acd3253203d2190cc83553b19cbe91740f399365afd1563465d6a5a9345f961518fcaeb2bcb3941958009990111ac7494359005b1225535979db57a7a9b4bfc3b0481cceb5a0e8f83bacf9407f0492a4df064a206af93da215bbcf5645a939533177e82d0fa7eabd37f2814ca8d9a48e8bccd06d6fc2f4c72d68a3f671b23dc31d2b60bb58da65302c6d84a635f5da68ce9c7487c7d25a09baa5b4ebb8f2feb4c9526188a194215ce31f0c453a9d2e591b25ac98aa819b954ee4e00a5be9afae51f049d3b8896bcb40344c2590211e6d729fb4db0fcb71f968248d58962ba5ab7f940d84864ada1146fa85e325cfacb6a2dda44c9acf785ccf42d3465a21926ed23fb7a21cb5d158c83819f2e6c8282bd13b61c6f1166997db26d2eddc7b3fd5576b9934d8393710265b843a9fa4a2705f3ddafff9a5817ed6890a34ad0ad57372157d32cc54746e3de4c99fd10c05ac834e38452a3aeb9ec4452bcda2c7345a1f15736021bc09461b760a4218746673342651baf26739831b4a1c7651f7b9dc49bd8bc2a48f2d3a683f119d2fff47dda4a27e14339d68776c757af0f5e16309eebf4b81bee1b7a6883eeabc8b3a51e24ff43f87c668aea5cff7f820f90eef546569d1b458942c2a99cd687f7a9c9a6603ada53811d153512c1feb55bca9417d6e6421ea0a12bdf920ee4509fe34312f6fa81c0a5346eb4c2f72e2a7a99f8314409a717ecae4efa766522513a94339af067b216d3291891bd34f63938b8b130250dbf3164309b37fb70e0ee848973b9e01953dc3722da482d2a498c0eda179bedac053b9fe1ca6bce5bb928bc741d75246012c91132767b14579d1cfdf14a04cc24ddaf44e086f45013df4e04380b84b9247d1b3ab9b7235facb9372072fcc243b711e2c4851a7f67cc11ce3ea6595007e2b3b616465e78f3b96bed3646795f44d96e9cf3352e5266f3d9dd372a0418b9d514f29aa383b863fc517e95056820f84e2616691219d7a01509e930de717ba3049c16105f0810403c6e21e99e1011f53c3384158d1a4eafc0916effbe23261d4f2c9e021726b142edac2bbbeb891f86dd88bef569d91bd378c45031dd28da415df61e660cada264e85f5c30758309b8041b93b87c85795e8acbe9cbe32254578fec35baed2c735be00278a183c691f4a1c56afeedc7aff9581794dc4eb999600887d43bbdb7cbb1b87d777d12ee2aa8c5b7bff066629757fde2a531912dfe6f7c9f8b765212b239889202ced7c2db3f91e3f955764a0d8d18f64b414d7541f22622ba971af4fad271280ea5b6b42095a17583b959d13e7def7957fc1846424f2f9ac90decd13c978c2962f3668b090c70e7460980340d376a8835cd0e75e214ceb99a15fe35b4ac74c3bc2b2c9ecb079cdf4ef35c860dec5469883c1a44cef62261bd9550bd81d738551de2b07c1a0b9567051bccaf32ca6f11aeccde2618cb65a6b43c2f9fa454f84dea40d6d296a25483d907bdea5bb2342c4f5ec8a8e28f3815580654f4337e3fe82e5a2519702528f60c62a10f230c2075418aa0e5ed5a4074146b00ac1559a74b073024c3342517f1f3aa6e9346c7f8cf9fbd13705ecf8f68ad86ed2c5f7533ec806d74353ce652aee1c35913fb864b7ce3377cbdce88a8855787393eb02758420c1fe332c4ad70496c8e3a02f259092cf54e8a77ec8e259479b6def35c77ae60b9b334e6e642cc4809a05bd6b0a0db4cd615a3b992c039a94c8a43c46136d7f0e955ed9c009bae9c2dd39d9349a448768fbe813f4844e24ca7cab47f8373b6160cf230ffb6aba179f111e8e14b8cf0160b2bde2c0310af550a147e24e51bce86ddfda9c849941a671e2fb27d7373316816bba800fad607f79f54ac0464246d28c8032cc1ab4cc137422ba85ab316993f1fbac610e4c8cb00abe726bd44cbc738503799b5699070b88d5152495f0c2a114c55ce9795009554d107484aeb6db15cc51f7f08bef78d99a327cd01339c6c61dbe0794e6c59b903949735aebfc09808d1acb99b9fbee63baf699a881b81bf32e889a37af3edbe624c40c09ad71b4778fc1ae2e8030d6b9145170d98a079ea3ebbd183830ca9fffd7ec4bf1b31c63370dd0f8cd690a0a6aed98466faeb55bf9d7fd0340315f6947ba7d3288e6172551308e226aee472018d2dbb53ef9e2f440185d0f0481a46db819087c611c66be67ed1948e59b752867444886700d0664f06fde271133f35976294fafcd275e92e6e3e664bed08da5221f0b9adea8d5fb68a056fcd30b0f6dab4ad8655334d2641f84c71790116b0077c979f33083c316dd8c5aa2402467ad179ef00da599934b8235fb1989bed229cc55754d47bbd3e7ffa820a0fa5455de9f1e3206aa45b1fdbaacdd59bf23ef47c46c4b68904116799f5f6890bba07e4203214c4dfe80073870b3c16ab217a15c524e29e5c70b03f7888e4b3b4fa8118ee49765e507a47ac71033a2e6ba5589be25edfafbd0f0a7678eed8c99819a90cd0554365821b0b23070c66979a777c8f80d502011c689307364344e58b828184da20ef2f92f64467d742ad2b5badbe66ea52def35ee3222e69d2335259e57926dc5138e02e83bdf29c722801389c44b4613244f68e0aa055cf04245bccb4111394377869cb744c2844e3b41414d62a8d6f1be3b79209f13ae41f9d43bdb38287d8269f62059089e2c3a9817b3246f67492c4de39d476acb926070d56589b550c09a381c4995f388cf45817bb1b4db1124c10516d089939b2b81fc9ce4f802649070d377affd2fbe8bb4634b67bdc4947fad4a48a8253d0d34dac7e58ba492fc630605347ca86b7f2a8586cd84400075a80d5613fa222bb9df5234e6b2cbe524c9512a5409b9049ef5cb06a326389cecd3e7e7b70e7664374d2ec86c36b10c85a8f455b9c15fd194e836cdf4149c4cf5945c7dab22b7160b7546133ece7574c4c2b9d9ba852b161ad1def6ef53a8e3beb091e184dde87ac7c43e24c6cdedb7f5276cf33ced77335bf78dd842c1cfdd5a917044458945dd47551b56d0a0ba1d0af8c4ba81be5c805aaffbb1275289c9b45e2ef41fead48ff596a31de3995611cc9446d8acfb26b47a56dff71c78f05be27e98b6b0ac283410be5077ed7bc8d2707cda9cf0fc64cbb0fbdfb7a70b2677d2b8eacfb270d9f704eef33ad4822b1d31485922b9800d138e7c26ad18775a648055f48cd37da7960bbbcebecb3383364f4c4d7f34b0eaf26d10ec3c8a27489aff3e5bcb9e7a57524dd634f43b811fbf4ffaceb1a87d43ff90d2556a5adf8cd1b53df29e655ff4fe366d91210fab0b45dbf5211b978c000d039a4c62c60c096afe8ce4ae95a1ee06520ada6289286c3ad31a60ffe5d7caa8cb807214d8396b60d1082460066370fe0df489285b81abfe3d5cbeba391f88166e9148a3a4d710f2fe49f70795445a843e39edb842865eef9a4a82f0df7fe0284df565bcaecceb977985d7ea594aaa871dec1320d540f799d1fa22c1ce12f008c18f7384146aa8a57206afbb3375e37d1d24205542051f754c10f120ca23d633339b7a9e46e06809c6cdd3dace0c7bda10dddb190a48240904f3aee8dbbf40669152a8066fb175518133823f44f7d90fb5c0eb829a67fd459af8800fece42a4a75a6c736597e15070effc244e56402bea1f977340d53e15f610913165a12db993bfefaed605dfe29cbbab10edcce171a07d6ea5f456ff69c1485be64a446cc082bfd3ca55000cc47c307876bf02ddd59bc4886d5f5899b8fddbee557994a05f3e287bb8e966217adb517037d5ef3f22a2e26c0ac8fcc7e63e9a14d020d1eeca25ef6be705e0aeca04ba3291097bdb04428a6d05971ec972270a4e7e46ef795d920c0f0696f8a128048103bb64817fc2bd420265cd11d4fff2e50ca162c0476e068592a946828bf4faa86f2384bffc9d59ac2dbc4ed121a8a0de51bef578455ff9f4d699514a6202cdd82404935ab65fd636aac12430b9bbd94d0035db4aa08a34f6ba68ba986d850b1e0cbc4b79b55bd087eabb1df647d676f4a549c8a54fe7be1f0510109b4f6220bd8e46944220b863d3a894fae17899c2ccd56b8d89aaaa7d66c88afb90370294ed24048e28df1bae82cdc02bb717ff9d304bcc07138cdc8abecb346df8392313f86aec7e1375ee15b0c5e32c9d2866334cb032073ae5951017d6319fff072e558335a200894a9a50d099d914c541fc9d6a0a618c392f618f63b04835434eedd00bc6c4222d8b5e5c27c863b89e5f28395542608daad51c1a2f157ef8178c91498aeedefd98a6cb57c5c053f05af72c3468b56f749eb00686a1668592ca53c7751dbac176475ed978c2925b66a232e2a0b995752b53538b1ac2efc3ec6803d20dc37e66b0690880e7c0898cd9f3681feaa05e3efbe3028416b2fd80a68d69e2208245ff0a5bdfa7b6b3352ccc7bc7e992778b524ac2ad9a39ef327e903288c82b9212a73ae4c952096c71a9795266051c463e985606adc8d5307bd3adf13287fc4a46bef2d5659ec9c09c83add7a00d56d405e2f1cc07d87e9f0f1f10a81b9278ba107dce20270c51d50a0865c1c5ffeef887062c56396788c863d33139673233d17e58f4a9dab32198e9aedee39e9a6c36ed007f0c3d65cf389037b0c98a02c24738dacb4295f2315cad40435c408d57b1bf87895463c8014c4698b99a1331b3132f44b7055fe532126c3ce670ec7ef4812028340bdc4327a88531b154f0ebf78c94ff8ae1097fe9cdd146058925766d940b59c3d5b991e9a321aecf86a0f52eb5b173d6be2e8b931dbd6d68616ac65ea52e69ccdc2fd6185a73b11d6c9d995029194595fc390d3899b1cd51c7a9352ffe63de24d76a012a96bf9f37c9ea978d2c770592bec379f5a7bf33f597ff5fc54d1eec322249b3fccda8439e1d2529c02104233f984d04c44d1eda324debcdaaca742c2f5158ca3d9741d691e1c012a2e5ffdcf054065bc572650db16631d1d6c42005f6fca545c96c343687b8800fa21504dd9b84549ed3563af6a3dc71199fb7615475b77ac762fc613f28c6d56157ad1c3741feb84d0ab5081db807a19db564b5ab3549145c040df2bc45a0b3705c5c427fe72daa67490847dc304556aaee5734693b0335e3f039703a2892233c02d366524f80d9ebaa65c514df97da4aafbea4e180ed3b56f7a4196dc8f4a59a09d56e03bb00a04635afd31c5265a3bd0a964a58b9f554d029a76dfc50b7d6c2065407d5ee194302954d82d9a5e53e87db713681ff1b97db315f4541f09171dec898a103e55df286fa9ea947685af54bb3f755dc1893a378af6e013a07ed850bbd2d3e444ead867a569f8a493f34d1de5e4dd48ce967310ca6ff5e1c331073015d7decd8f22c809a10ae97a53320562a9dcff173300a32ca3b328a573f74a87bad76cc91d65c0f59de7445f568b75d53f4677f5e92ff9ead426630726a87d5df9274431e14ac429fddeabfd0ae7360a74aa39c1bed63095584754d9f67a279664c0ee78f31e98982a0502c86a9cefdaf475377a26a4c01d6b581080b5664d162f6e83668ef73a6453b624d762c6927ed730cc07d35522f9121fe4bb45b7f974ad26ae52933659eb1ace4c8c55e227ccb61f9d564152e61b08bf463ab0f866a49151357d16561b2979571cc97ff7ec911a9131f2f4b35eae2e6eec34a338f55e6727d8e912c8a959d4e54eead6d3e5e0ac6f48f5ae8e8140fad1f5daab839186d9e48aea2887e01c32e48681734b51bc3856d547468456f03f947f0dcb424d3943c55da3465b07347f5456c61ce13b0f6e04a975ea07acbc0a687e60132ec6755bcb2d9eb8a9504097485b7ff214b67f0a52543007aa2988e8ffd0866323030e95026e2c2585ad9fab2481496a0350d9c8e8c5eac3806af044a21c543342bf28491beaf5f63cc2366741611c4cf13a415cee019e39223b067cb70ca6b5c950f549c844b6e67a8338e0dbacf931dc2f30f0fded2d27765fb5380be10b55094d713bb29059f3a126ec4bce59ff7926dc3388069beb1231ac79c862bff82988983fe846f9bf8e33ace9e03a50841396cf996f7a0559045f08fb0ca1ee66545ccd234e8712120343d232eb62e5d53c3eddf424be17c4c4ed7e7e9c5cf309f62a4bab41c1dad99c0be19878a1946405c38a409af8c40ec95bd9f4923ce3db4637b2703e5874f90d9a11f2d76987bbf54d57452d0f344056a861e459e58de599e636ccb60707debfbf082a48fe400d37fdb69c7e44e4d0a8e6ecff9e4f0ce44009c3681b43cccc7eb824e7d507a241ce02c98279526b264e82ae3eec19643f9dc98baa2cb1d4b0d4a906a229a85c9a80751d3965a059e348d1a14b8e233ea98504318295e75f1a5b1a6ada4b5b0ced697c2685e8c1cb0c4dc367c50ee36e2ffd8e25f5e39a93aff9c779d2adb53a9799abbdb23d9f48ffef37e7582d1de8bd2b198b7f8cd111b450836f402f377c93a33b10f97fac0d5fd869cfeb8d793ac2b85cb302528dc31571cc488271fd91857d176a52290b8509eb7c8df25678d03f71ab6291b2b34d2249682c54dde54e0189a86b2f7b0f0f175144f5876644dba0c25f1f16fe88959cfa2bad3d4487fb669cab18cfbe5e969120551c40a1c4950b0ebc1e1179326ea37cdfc70c001a075fcf9b0cf4f11d49c05a58c1d39768dbe19f8c70937c2fb17445f8073ce2551c44e0fc36be79bf528d29614d00af094afc2b10ec628ab71bc312884740c75e6e322dc3f69e6a23c8ab8a3ef7b8858f4173305443521816feae31528024dc955dafa74b5d35dd8c678fdb3ef9592f5eac3d10b08799104833e1bc7c57976e46673bc28872a8ff08f3691a6944e607f6ff498bdc6454a86a568df7a0ed15b7c494a117c2eead4173ca7f4430166dfd7892f294c18d19bf9f6a16ff7c6e41fc143d50534689c243ba973e33cd1410e071a759b05aed2aac6b04e52b708d33075dc86877c204f2bdc02350013ea54d1fbf392c501b52465db4e845a812d8b7b0d0d16b153df66a02c1434294308c2c33b9ec679a92e0ccbcfd85d0de0172f881fbbad0147716890534ae48e0a90be8a871fb26513bec76970ebd11bdb6f5273a21209f8e9df9b19b68a1015f4d360a43befdd312dbea12ca6a76733568a5d582bc184da966e4f59408d8e06721ac6e9ae2bb146a1533453b011355729d0981d2c883c52dfc31863c65db896b7857c2c681bbbde75d8739f06622866b36fa0703bfb466c102b0a688834de3b85a2859d2b190ff1a452d8f924d869b4561c0c718e4d5b6b35fb39d664886bca19aeee8e1cf5d2c59608d253de0133ec8a549b8f24173e1c69f399104ee8a6927f8eb1b22edd444de5fc17b76238cf0b21b308cf185f753ccf5b23e70722ed70654a768dd72585b81d4482f918fd394b08d91d4d376823be6cdb109133123afb81eb76a4af9f35f811b3d1034d60f46e1b0f996d3d7786a4bebb7f246485688620afb19e087a428769301098e02d36a6b93271822125032589506a22c0c1f32f71da06f82ab32ebdc5e2c087970c647dceab51ba6b0a4ac47fa97126a37cdb3b5bbd3eab8343f6d798c39681abcc312a32d2c0f42bda613f1159da7b8c8f2969e0b3721cc0eddce774fe43a11f1f876f1127b23af4493f619fef24b43085acf7f04260fd53029d6ea7c71a295ad31e6be64595f645f7c76ef229066e0430659fe64320660aa8a5e9c1cf1a3daa16cbbef177196a918e239959f2447be8425019290f48a031ae479327919833b1c2e5c502806a53e9bd7051653e4705f1a683012c05f8a5fa09df38e21ab8229be06506eca1dffc0104b7362884ef1a6dc106f221408f32871765d21998ce67362961f3ca7c00f070f9112741eab69714343cf122920d65b9f1cf5ff1c4ca4e0756f8051b1711a0361e6db83e045c3cd9cefac5369bb6850389ccf04acf57ea47631b5b19e454c63f5f0ea34510265b5b4afa00565875268a1f386c5b4272dc8c122d5ff11b9b8263a2ca31bb8e776533b26633407583e6406e6723cef5e9cb9da31a8b7e3f0087f52af1c88e7d92606f6d860ffaa507857b24775eaa7e1d90bb0804078bf0091a2126bf2fd0ea9655a7a3ca4f46273483d1eef4bf8af1bbbe1ebabca1043504f57ece37fccc59bee3e4fd4e3e9fb08e785c8451c9e2de77dc265a388e47436f849b431481e14db432e72233270aaf8d528c8adcdfce7746bad1073044a79787d8130492b4cc7244ac5590947b98355ca703eac5a699b9bbd4bb771dd06f02567498f70bbf222d35cde3183bb1f3b8e0dfc9c44ae03089ee58fc38e8e78248fba3cf94da55c683073a411b7e90b969b50ed1b3c785678c637f438299b6f6e098f897f53196461c4bb6afb52099c9dba4a5d29f45ee4cf1569549c33c133586e4d84ba4342c9bb1d2c642371630816f2ccc0e70b76285016f2c59010c90db83a318df2748b2ebf630a4a3d6263d3c1c3e94c9c21a20e006a52d8735401f4a8a381900d7945c8169480a9ab167f08ca473a6ed127a869459bc9af178ad808a8b4665634f9bc6127f0241627ece8ff6161cece7e5c4c887ba0194d151e3e77b3ab3ee5c8f1848494f5b0cae58e4c49116c0c7edabe114075c8e336af6eb648ae6aa718e2baeb12c98eb6bbecd4c69ae3c99f75c9595319648df0c3d3b91f97c8b87b7050516509597ecb73c99a1d94b9eab36bc8332f6d39eb1c75c5c5b4748d5a923a55f55d9a93d1664a403e656307431ac7e37451ce07089ab3b14c111e53e703265113caec363c5850a3e577b070d3ca00c81d15784042f1cba18ab4ec32552698664716eba09aae43040796a065759194541facb9d1d5cc593ff3d2701da857d338dcabfbac799d3ea6b0c6c6e595befd3a81521700b9e305cacb342266d4e5b232fb3c211644498728ad1028b0a9393e341c62749501103723ff25f27378fc932af1c809285ed4918b1fb5ecd8366876ef4c3b6d9ed006f57336e7f5a6cf5c988f06b34d69d413133af4025e3e2f394835d36dddaea233fab61440df58e5c8422f050bddf80b7d5435c2b1a80967ac088e92a87558a966dd94cd56ff82275bfbc2eb7214132eaf68b3742534518b685912649b020395e3127a3c1709d7ad9a89888dfd41814273c8ebf0c51eb76fd96ca3185d478c0b7216236bd0a394ac869bd9b403b6f91abf29db087668b3a9b5aae6bad6976b048eae7b264029c8a4832f2f5ec98ba5a4bf95045a5de0aa5cd5531e5d872a0f397bbbe88710c90096304ace22dda8b08074e5a1723a87caaaa38236be99c7f5f4d0296f81fc441cd9b22c9aea39da6aac2a5dbc066e1116dfa691d814e89385d248e0215653faafe3f47e994365e0acabf532202ff058493497de9ef3c6519e770af7f09cc928a65241b749c1e0a55eee50164cba724f795c3a2fdedf7426ea003699f8293855153cb7062ad74ee9f114a7dece7b4ca724c80cdaaa4e46b549321c2aba86228e0582ccbeb65f2bc3eacc03aebdffd997cad3b6b3981f9bd63099d84759b734ee22697ceb0e03e1d96e585b3c7065a4b15ef6f29e6774d35291d413640747261fcf9c0d7bcae1c15f78c2e23242d7856f6beeaa9d9915e6174dd9630288bd7325a6e89aa5f9e2476a1ae7306d119869ba823c2327d6be40f70ba0032d6ebdfc1649013217a79004a24de2a9042b749280f00c4885b6a051eba0656675b4a3d96f2dc57775ba6fa4320e2a9f18e1135e49fecf703c085daf8c91341c2f8fe2ddda0cb0c37133cbf21857dd18727fa33d8ab250e38d76af85658ee81e9e16487985419b77515f2b36275eb19f611de820175ac93584f5eb9890cb5374318bd19a68aea7c70136f22a0e10439933e565b8b32a5d6287efac688dfa958cb66e745a1ea35363c25b6ea7fec95370db100550693a62aebf8214ed7f6e49dc8896209e6fabe34b70d3c41f4212aaa628a40317af227d4369272aec452322e226235ec73398c349c6ea7f108a8d030a1ca02f1564a158e6e1392dc0a8f1d0838321e94986eb2af8ed0ed3e11907db528bd98c99bc18704f194a214c857f1ca3e2163008600a10d7f014b5166f6b39054ea0acd88e7b385132f79d7d1fe3ddce707cc247b42ba787f44a2361da04898210e3e7effa7585f5c9390d230c49cae5452e2ada75f17b56e559781ed92ba438562076b5f90f8521f93550a43aa6c82af3ff3210f0d83759058fdf3ebbcb29adc28e55c5181ec1d6cce41409f743df30b7a80285256da24dfd8c6eb29087a7a3baeb017dfb2177a0e5266f475703c236be20848d8624c59452187f19d81855a33b31ed6062a928ccdbef93b159a9dfcf89912b9a679cde60eec35073f699981b6c508eb9730b71f79174ded861a1ab37c7ce91af51afad09a669e9863e261d9e0999708a6b4d9c336aae553c12a17f6eef5e17f5a20a8ea164ac2d5ed55d7e1b28002d9d557e8eb847692487198fef522f763eff00861578d14e87d170385d0f37cba2af0b181b61d7cf52c209e39155d551143cfc93a08201e0aec096c44ff6552e425a27063732e95f12508d01f63ef340a67a7b9b41473fcd730b5bb1a879003ff7db2547b66232868113eb2e3e4d05d21fc50dffa49ce4361d03a429aed57bdcbf0a71e398d028b68fe4b0895f0474fc19aef9bce1dc373251a97ed1ce9a914639031a64c153dd883ad9be982c1ba818c0319990893381786ea47c45217cd41b0197e9cb205821085fde01a677e74d7c184a76b49418453be0edc6e3e4ed7421c0c9104e5de9bd153c22666434e13c754d2c523c8c873cbffb6a2d75b518c40cc72f3dd36514bba36a32ac561bc4faf1a5ec024ab91b2dc1ae63d32a72d35c690d5a5ba24e9c8a92ba781e0961ec806f815f83a25602735d99fb42c8b4759202dcaa6627804bee3713d8c3744f15cfc8fd65d3f66e505e578b9f19a960841285792732cf49a41cdce682fe087323966b5348bde8934586d3119b946af9261ce248094e60408b28a3c3d4b11fc297456ceea3bf1918127da86eb527faeff59f86a093a68cb6737ed6c15822f20bef01b1c6b2a80d5614f3640e8554ab23df1e0ad9994331ad3c89abade2749458d62be912f98fa9bfeb8d7c5525d29b34b3c89c5f4d401567c36962e391d763192839f21af7c5b8ecde6a2b0b4f383ed2f9c1d6042cb5eb00c40ac9855a2a2259e7dca7d97f9dec0d222caf78e316554a05bca0d9a4d2fd48e83d29df7e50e80651d3b593409aa2c31d3a0c4b5d42ecb299997893b29018f7b7b0abf815d6667dc7caecd9f60fa300e03544d151352b4a2afb00d6f95196a4a614f18a031ae7bbdef11ff2a6123ac0f833a1bfc559995a582658dcdfc2ebf0ec351c852dc0453e2cfb384d277a2a01a45847c32806180542e0fd932b9329c59a4824e36e55250c43382b57586ce688ddc381fdc62c3f3ade1201e04292ca0a8544df456759dd2b6a2606f8bb0625fff9065df2e4c683584e1aa98edca9ad6889869672253dc72c2a0a99e006bf1c8cd1039a5cd1b2ef3a55a5f93723c474463455fa66f5ee44123118c08e0105857a8e03d3c8ce2b68a236fbd1d139489108e904c8a9da687d88c8bcae557e427318028bd1c000c1728a92d923a274101304fdb4a8b5cab5f5c01a95c6a788331744b2cd4816d491b0a839672f47d727104bb8b951ddbda5e13b2e6235fdf79ee7bb4a6e0e4d3ab11e085bbe5f6590a5193992e91e46326be6944737edca20c8f05f7d3926319c6a3b39275863dbdef6262bbcfb92e9f7c28f2ed730efa65fa549e821f7ec06a9b909bbf47af7c5f3acf31ec96a859d1d887771fdda4648abd5a636cc47a97e0cd5ffdd324e109f8b5930fc328ed84de88db398c151626115364a633e5fac8cf0c03d5e9cf13ddb6986a359b4c07b257aa6fd238d166b655ba4c7770c18abf5a6de9050535c4de63be976bf8ccb11bf1f5897c834d5b95e4f79068ada74651cfe0b97dcb1ebf928e9460166ff71b8656726ac2eb7e319e5d3358cdc0d3af046005aaf11239fc820c435e70f398efc103b31fb11cc359d5613ef11a8233c0331b58fe3425479dca0ccf1e1938968b3ace920273aaa4fdcd295c6b30d12dc62216a11506dee5d42dc781427d98340e96c9b0886855634481dcda6a9a69d33ae51742e244e76c4e73aa2ba595a2c5bf0b04df5eb6be7e0cb1d1c27e8358f2e237dbb077fd166e5431e1fb9122746af47b41ff630618d525bcf93fe68e148d2efe7ee8fadf62240fe828c40aeace8b196a0ed80c59cfd0aa8e082978a8a08bf061d7ae3d89fa324e1dda0785602595947e28329707b063426e880bb158a1100198ddc3ce0bb8ee81262b3c37645ec2650bcff1537ba516126b5919be596e85885011a4afc60b18530da5db27aa7b52863f84c35f90611da51698fc2dd2dc8b4d060ce807943887868796c0d47d7b8d8fa0a5a5b22031470d1dec1ca9a575d05f5c2042fbe0ae93adf12f9317e48406f69a7add64e16562bf48a201cf12011697e314ed914da30c16e68e37a98fb73b8baa9d7c7dc24284c1cc283faf4ea271ed2fee77750eb1267388648dc6489352bd61e941a07513c56b0bf48cfe181765d4dc5c749c600f4d10b396a69c9375496563c2d62011f0044d6182a91a0aa648c26f7191ddf159a878f53754c2d988004d11903be7dc82cff833790520cf7861289fb625e89a5b44448caf31420eaaa50dc592e080b1f5c496f2002b1c373110c3b38b91917a6354d0fe93386648c15242421062596ca40501b151e9fa4d0dd06d2f572c4f5fddbea3a00c9f9b0672f746473772e05be012328ee1e8060709f108f1877052c071738c3f03b6e553c7caecbe182ae1270ae4c14abb547e0fde87383bd6e68d2112adf473e365fca59ee51a1a442f1abc99b46995f6cc1289062e1297630b54a60eece1d1b246582d26c8d75628068ce041540175d17389ee1553aeaeb9d70e785c97aeaf2dcc2f2edc04bfdb8f3c384ae0097a47c106d0b5636f27a90268860b3b6ee8c4b593123c69b13b9e472cb91b21035d780469dee7418500385322a4f9a80e82eed844b133375b93546ed4fc19044af7a0fdd0b9351edd396f0ac2238d5b2a997620c4dc635faf5e258a24c3d99b11e25811b0f7b8b2dcba685bb59cc600b3c2f440984288f692a2d035a84e011c40c1c791425b4c592b1be5e94b968a81c42085181aa3a429b2b742b20b4a2a310b627e84d5040ad9ea4c5815a6c80f9d8021603150e369221725a0f7ecd5c0b89d456d60ab640c09727d35eba899b8dfd14a8480d00ebc46fac63ec5fe50dc14bd483d3a60dc78d1a12330900b66a650efe7e9f853b9f3a53088009ed49a84fbca3e3ca66597a06853e8af562107da9eec4208e74e7fd085be54c92d1cdab154decc2d350df2220465df743e3821d1aa85ff7471a6187e4aab6c5a5a6c06960006e846db4d5705260771601c48872c5220532d4a03b7a5fd4587b793e50affb2cebacf3d51251eb8c69f931d6e159c2723a4591f2addc9769beee50fcc1921f40d2260a108c8be3c522eaef6c38a9a0cab2eecca7596f5f245d18a9a2d0c2704445b22f2a86ef86b056ae1ddfa197aecce4b772e55e7c8d871e66964c2b17c6aab56312b7ae1a5474a57c245c545263757ac8f8c79afea74d7f52790ac7daa002b15eb94b11aeb56b587eb9ef17249b4b4843845e2ede491bdff5985e405e791d02659de1928e941c204ac0b8b3add73f73a98eaf732c738982d5d7a90bfae1c8630e4ce3435960c9b1343ebd67f6a1d1779ffe6ee1d08554f70ad6f8546fa8850ba3e28437846fa857dedf26b25b8f09f995c9bd0b2e4a52090d82acc18e1889e2cbfe9bae2e52e2259f58c9e2dfeda8f1f5627cf4dd08a0bda1cc1e9de9c29257266d5d0344b89f58dac00fce230df2d585c5b07fe8d08993bd611a8888e0f46aeee4c0ae494f39f82469be7713ac8cd8a9c3d73cae11de62364e08987345b29402a1f474fe104b4bf7f16914f84392635d1a477a3d5a36727e6a362dfaeef7f3fd7a467b2a7569a94739a6e69cdb31bcfeba8853a4de2dac712fd7d7b235b28a850d0199f158a33ef05428a93c580fc64b92e0c691fa1bd3ec514f91d24349987215a51dab0b98ddfb4f05e30b304b58d080299b92e31a7bb76c842523229e157589a7bb9eb266f39228797126f2949158e672649064086d3c26828c080bf21684d5e59fade81afd64da3656c4db47793976edccf2573e1eebe34cd8eae97144e284edcd5e6e41f73288ed8ee233adf51cbdc17e6df5895cbcb7c71b05e58e048c42d3594b5d1ab10d6a3569536ea346a46dfc0db27a8d117ed793c8f54b407011b34787a75ac278868600baf803e60761f7b4241ed88f2779206db70bc3b7d3305f0f2aafb3bdea9be36cfa70aaf26f6b12be12b80bac67635e47eec8ecf5b5dd3cf75f823e968009fc6c8c446478ecebc30d25045fb9c7208e171c451c97df97cecd2e9600b8abed86da240da11df30fb8af183bec6f76de7e624305d2215ee319654c601a2f1e3b23db7b1dd34108dc6f2887383512a8e468c8d621a159560cabcae47f577ea9c1b53680cdecca2f4b64ebd4e00b35230b34a254574657f41b95a4485702cfdb21dff3c6e9ef4d99ba75590b9aacfbe8cec03e0676769f50256c471d576425e184d3e3e66a38170447855253a0eda6695a40a4f11894fc43b6966e6caad4e8df6374c511aec2d9b1605503821a3d6078a66a1d9507012f35354ef8c853422ef953ff8b702a4e0f2f2a5d2723840dfed5aec990d61f8521b48341d21a5e847e54699d8361f95ee2bb99015f424461acbe286dc1673f508b20e09428acaad6af093b4586717d896190424571fdb70aca8e263e6b7d26fc3cf9b61ab360aa090ca1a4538da3ea32594c556132cae0c295433897f54cd0313a321956cbafeb1970f0c42c1a542d549fd2468efda835f579c8c07efe2d599c832b6a7cdb3db767c90005567a231f5c81a66a0255efde002e56c39eedba79e656ab6a27f5bf10df4127c01df57d048acc03763ab97fad006f00065cc48e3fc3161929ddbb379283ab11c52493fb43f6cfd07b8146f6df970e8e171516a4659604d3727c4922478c8cf97bda65de91bd4c08511df0919efcf5a9eec0bb380d77091bb0770d7ee772290130d4a74ec3149c26cbf2194429343ee98ea69a27fc946bd13c572d9b2b47b4d37fe3b314cd7e34ffbd858f968cd74d49b5aa83239fc709203b2dac6e0aa71fb28b91bb30f2e2e46ea0c9933b60bd70474985213fa35289ed83a434046b123c156595d717f49f010b6c95902a970e55421467767f5d05d35a13f26de7eaebd39113bdaff98f953e4aa7a24221c3fc4140887ed54d574d0450a030e1bf0cf5ec4ca70ffa18e0fb664797e1922c2e4343873497a933a055ba0f0b5764577400c6bbb61c8df34666ba577d84e67138df98e4115915d52adf68aeda71231bedbb54eca82a5920f264fddaa0bddb223af28d4a29407427b2bb7eb39e568d86a4098feecbe5041e1866991378288bc107fdca7c0311ce457ac299f9138a4423d8ce14aa06f04e11ce1e015e6b0760bb75c2e91faa0839c564be1bbdc16085defbe4ac43f04be70941e8ed10f02e426880d4f32fb4700e96c4a2229fa5f7091d07ef744377e3e2f4d6ea8a2d3658d41786cf737e3d2838fdc1731060d60a8c168d9352866839f1b966d2f49e5192f4fdd40cd952f942aab7de3d72cde299c7460b533d922702b44d3f83075bd67eea47de0e5f9b33fe2c6c523d9fda2b5e11aaf533eb8c21518a286d67b4f1ae0b192dfee6c8e08f776adce38efc9d00a1b68285252eb91b4861b10a70e73dd7658013b08e4621bbaa6ee24400bc45aa000eab79458af2ba0bd408d21bfae34d7b607c004a06a3a98097e7d72774701d2abf921cc06e060058d7837cfd15bc351a073c3980a1adfcdc9ab391909e5df1522c3ff391d4461469c2a4f3bea65af0d69fca969d1efec2ed05e0fa73a1f76010929920ea8e8d8a6f85df983e3ae476c32d80a3a756a062dd4ef3c503407f77b5ffe50209ee6e1c68d964da5a9dc2ad34ce3db4c485ca6dacdc5a490ba9f3b88dd9bb681c71919714c0e4f260d14302fc50d8f204985313935c4efd36f33dd5b196c79f764f19ff40fb24ac019b83e109924b21691eef25c2a56f7535b81e7f80f3ad3706f0b3364e2a0e4c474836d72ebe770403822f35381af9969adb35ae06df776b63ff2e602f5a238c127c3635d44156d708635cb8a70cff74caf8874f192340a21e18e6365b0041b89a2c6abe846b71e27ed472506c8b834a198f162d43b9aed0882b25cf27bc3d7b01bc2b07f93b8419d3136d96331ee1862a78f15933e4ee7cb8b81ee36fb26bf823351daa31d803dd31971b8fc628218e8f142658a60aa9cede7cc44c1951ef98eea66e0f74c7c0663e127080368954e25a4499e685ef98f4d35303e05c05da245e240ca4748489a2c78a261b7a1890088e35decb0d1cc92ec798ad632db85e16cd956a5e922a75c03314300ca516ee3bb83956b0dc38738e3572ef3a792ee66ae38b05c419ed3a311413ce0898228ece19d45f71725a33807f6d3b47c4a69f3981ada0838a5ae79d4f6e9e1f07fbc431e007ba2810ef5c2d0f20820f911e085158482d651de746bca6c6878f07e43cbfbde52d85e50f5954379fe5488e4b81739c45123cd9487f93ae2c8e4ae59ebf3e3ab5489aa7a5831b55ba5c01273d68223bb88a7f86cbad335c7aca48ac961494a00f915118382f1a17ef34fe0803aeb778333f68a25f50d2bd290e1d9987262c8d6abe8db255c4f0b0acb2f9c43a0b878dcbbef742f182503fab150197e35b51fb18e551d14175f86e6219f67b4d20162b8bf9b4ad6d5258854037f063fd61c5fdc8a25e913115f499af968aa4014098ee0804a13c55e85c7b01628eb5614fd935ed0af1392ae6ceb289efd715473e5b423ec56d1afe85acd2e76065a4a6d35cbf7359b76c6962866ddc3dfff33aeb5345ad859c5ec47f451f5663b0a26d73060cf781015335f7c4ac76aa3a1fb68d8b8d39cdf28e96f5131cf45b18700ac5736b57a551099683edc385808728b0d9617ddfe141652c00918f69d274883045e90c963ac0bb428bfcc3b8d7b29ef2cdc199cf199ac32e30cd85f8299773d00476210e020f49da73d8348c62e92292e61c7cac2d0f9fba5366605d8d2533f313077f70f325805561cc73b653a7acc7998ed37f6602e0b4a50eedcdd5da00b45972fb133031a63e385f7fd28ae5d1039cae9556a2970e18aee8c17a21dcd36b7fa904115b56974e60d78684904778c6fcbd4ffa43c8bfaee8f9ec8db29a60427e266fe24fe0af9c9836f495849f4710f21e27c80c483869925103a6252dba89b725a1d6659bad1935b0cb6bcff1a0e059c06f9e8a6017272ea36c1d2cb52a4b3c4b5ecd5464e747768549dfc7d91634d1895a4dae36668b4450184b825fd4a9ca61d03add78dd57b47907ca2e1e23b0648c225fbce9b0ac49067fc8fb27d2a6028e5d715d41f7c2b76676ce9d475931d4b80080434b4e582ce0e207e281edbec8811e793c8a786c151bf21023ad85bd92a3a5e3d5639ef53f01597ff30fa31d73a71d1faeb42c9f245b18151a884de5e6fffcb30fd42622d7b1707d6981128cd6560a15bbaf795e14fbfebb9145ebd9a2172db8402fb3b2a73f6b66e94414e0fe1a6ed3b6ea8d345b396cfeee0f4f58766df749727096c1754cec27f28ca0fafa4a170dcf1a7e0b6a3ce6764026d81592a9bd73a0bd35161487f310f0003e47a5cfa2b919c1a24d129bc43f9ea12dcf7a4d0a85b98a448c368382872c0d646890a1811c0de4b03a665406a0a3cb19def25d8f927daa51e37b947af342a507ef28a5c7179782084830390273a0d5c5a2f08adc01b50782ca00c44322b4548ecc790c6fca705e7dba1de07612cba9787a857633bf5733ae5263e29e33434b60c0856664b1d7ffef5383d164c99933d1f65fdd5f0b66322b135fc8453e7b2f49867f9af013c996e23798af8a1fd5b052a42cbf912e135afdea31beffe1da2f0489159c1c41f061efa387dc9efa66028ade130528a927b1aa4d21a7c942d35c08625d3741f65381a66e6105750d2c6d3b6d76b5a3a335b6682b072eb23d6ab114ec85c5fcd5f79c392588b3ade826a2be4de62b4b944ea35434ec09ef2c33e7d6bebd17b10603d153514aeff1706a302db44a4af1fd4e3da0531fde58d1cfa350210903f7e77d6dced6081d09fa10809fdfa6302c6b47e218551c04e6644124e8a4beb43115845ca1613af476cac1becd36667807f7cd693fa12f61eab7276690fac0b8a9b835f7694ce2e7ebf9042d4d69f9af3aa10d14ea91b91d360d99f9d245c2e8c53df59d4caca1c8d28c869cbfefd7c30fb6af9029981d44a150d744f4f9b9c5647c428f66d6422af461d113efcccea1ad9d7e4ac96e687b9e79e597ee3bc652a72b1a4ca5671e95d9875cbc8343b71c1e2e20497a25dca6f6b443d79a68cf3f000cfbb718a2ff05315868afd459015b3ea5357bd02e7abff469ea6ec8a0a23625d0a6cb8b9122fad5147eafd7e306845f289a25c181801a05d16f5f74cb81f4aff6cb9e0a54972cdaec467fcd39ee8c122fa1ff6e7cdeb69e86d2d9286fb65c0ca2109c98ba7f988c81d8c938755be02b3e4a56d12df9e29e998e781531f2049a4eaf7a635f056994a004641263b7d5f988e7799a0181afa3e5c5f8a9c5a4fbac6b84bbc40bd27cb3ce57bb0d412ee39a7c003cb9e0e8753986fc38430d1dfb19ba1c36379162a72b01e0ef933699eb1c6d6090e4fa6f3d605f01437be65c6794944cd48227063c61e435f28b60716b8139a6b702251082ed6d2639c7375fb70276ae1560779cae025d7c96892fd46509648c881c8a4e6c88c0ee22178f76809dbac3af51dcdb601aeaee910972c94557044d76b19c0d68493d062626f58a8b3b1b20034c7c9c982689f54c8c253241fbf41b312cb6e19271c2d43a3729d9e92bf1a0832ea44d5cff20c91c775ac4a4ddb18d5e628c9772418c46c928e6a4ab10fbd398e26b95d328a5637937ac86d3229eca5e5ec90830628a9f84f80bb3769dcf36cef1d2007d9c8115de09238dbfcc7c6376e57e76cbea3d9a6a0261a27edf4f20e9ad1cd1ca081ea4d6e77d6461e54b6547a2d8a1e8dc5f8aa010a3172cb048b993958a9d8e0462fc7a1006c5a87df697cf73e393289ee30fcf624251021f9cc185a4c8d9d08f7588096504d0067b1b0a378ada94337af5f0fac87663722aa764e0554c7b3811853e957edaf4d7a0ce9d75dc3086b02e23a89881af2dc22052d9d31f672a72a7ed5a8ce4ff8849a9d8e9c1b80b552aec7abbac928ab15c08af0b30778520d5341693b3def3e273a92b0515d3e373bd51c610f0994ac8077832698d55fabeb19a7382facacd92bbae4d116bb582c501eec2a43ff10c3c861270715de32c77687884fccb633af262ffb76931ee1aad21de625803da455d2cf30c8adb5f9fa50785fc4217252f3568bef3bdccaa1acebaab7457e6f048ebd0d57e0c87ae11717510c994c5cf27d275b76091cc77c51b15b0870bb6353f329ec69dfc2f48e70c638d3d4488e50aa3b41f73085e49b3ad4bda3572dee29c9d6a6a7357aac6c948303ad93f1d60b3dbbf779d07bf9c8df15dfc05e842860144a8622e491b770a95696f386d0f9c5eca6f3fb3f08a5cf81c9cc64ae45d38cf2cc5c8390c0d6606a1d99c97e3c58f84bf01ff77c9e6128697d889b6843ce2ee6f4b17b8e35f92965007f9231b842f1574ad77a44b15f313ceddf483f093e125aaebbb8267692ff0f0c1d41164e734d5d5e53f801865a9c3d15ff963c9601d3023b222272bcccd74633eb7c8c6a044d92cd801823351b3788c13822832a097e9782c763ec2a5d57b00d008e65d8977029a47efabd81603934868981b2f2708864d3f6e3711518eec2c0ce9757ee829b5138ef68586df391e338be81c45dc0688d392412abd8c00a61ed81650abd334ba6c312c9bc217c0d2e70cd5bb8dab1c060fa2c901cdc73f77214b16e1aac5f2a06883d253d9053fa8befa6dafcffffa5f36948ee037bf904af8d7efd1e1badf4ab8a887dbdf3f9a4138fe2d4447525e3fda2a400c268a4481b5f5f1dc769bc7e0f87489c9f695109d6ed5fcbaca22ba65984d87c20f1a753cf2e226e33528227ab308a592113490202498f363cb4e8ad9504b666b27e4f26647c900e23d02aef39939fba3f44fcad0cfbb3153f734027d06134725d46518a1832e0a6dbab071f2ece65fbcaefad2fc68bf9f1165e1079e7dfb3b97119369a6301d81ce4e10752a08fc031c88aa218f81d24933a40d9918423cf582bfc2310129cc787d492a415023c44c85f517b2a898eb14d90d34a63cd0fdad2d06a5839ecac7c76abc63f0a8be765808682cb36c5a528522fc4ba4de7afeed472f766f317c5240a5d9bf1c3b4c4181a6e9d2fac526676bdb9f6b53e5c60985c49e746483cb7e71ae61cb5721f247c20dc115e7a0d6c83699dff836c8e6cbab924617768119ceab0691f13d3756d40a7f83742957ec306e3bbc23218469e9a9f81266c16e93ea528380f54c1cf9fff002c6bb18f8f2d532aa019f7f5045d6e742e7d7fee747546ea1577369c16e0e41ef242d017ac43dcecd465404482dbdf9432ae11da22291c6be4346cb1cc4a7c50ac39ccd354b8f1b38dba7f62a4edd9037065c0ef4b0c4505a8b6f2c294d0996d28c5154f5c6a374da83f83f698cca182f5521ecc2941ec61cfea73226e98d8b181313d76782683cba7c312e2729e86085f9f4001743469e935afb92dff309176bc1219dd44ab74616b5580737a98e58455d31443bd3f449e184af11c88c7bc5d031bb5b27566c218d2870bd01b042a0e8868329e6d45f84d9e1ba2a72ddd82d42d3156c1cb946fd5144bb382a1eeb1c2122a849cac6ebab9389b58e14543ab9d4e8f26b41cd3d03a74dec64563bbc2bc974ee418feeb5271a73c92e616e27e670d8db3abaf38a3297533866772a14a40f7f5e0986f820a4125466e99d25e744211d7b26937f57e3bbf0e581ebad763a0206e02083559fd8bc7b273bfc419eb7ecbfcf791dabc804f146773c2c61fe8e58552e6616a00b9eeec1a81384dc73a09811bd5f504407e44cf8241849054555653aa1c84745551418543539445075c0f7781a61ab31cadc949d2830da1831d3b9e83782e1b837bbdc13e811f42b97bd2ac40beb3bdb58f45832b5b26f2c9a71e84278684a1aefe16983105f479ab70f9d527fe1d751e9acf33c35a8dcba9ecedea27c97e8c63f1d946080796bf3697e123c77813c4719d50ba35c7985029811f7dbf301033e5200eb3b4fbbe875f1a6e3197b5fbb3b89c417175415e86d8a00ad768a077ef2026742104b2901ba22406776c832fd42f5f7b01b01e2e3fea8fea94d9685dc45924ac5c141e68cda6467f6596721ce32e5aaf2ff104b56077edd8dbf8ae3ba7c4c0c5ce2eb667d781ed95bd41966638bcf7cbc8de2fbc4478250ea4ef459f61df26a1711f15918d5ebdd942e17ac8faa6913a04a8f0bc0c00680f5b9409ec3c1edfdfeed46e7776c0ead78fe07ce91c5af42ad6595dd636dd25a2cb0890ef47009d01c83ed54d3d837b9f5e01dca3b6f7817895488bc8714116ed8e8f80d250cf95f544768b766ce1f5a659d11083f516207e394479feaf29efa6df2bdc07545de1190baf49c18cbcdadd401d8dddbbc4ebc1e6ed9d76c61b3cff961b91075d200964dd5a2eaf1923d28d2ac0c1962d17d81b46991fca6a53c99143e8b6e205a7cdfbd1df5fea86cbdd55b7b4a469f0ae66f810940073b45e839da504f25ec7b8158acc5f0306a2a76920bfdd7441250be90cb5cb24fdbf4073adab293d61a7dfab3b464e4291b3ea6ecc6e7742d1f1699a397a81f59eda805829f18b5197a5c49af0ffdaa2b31ffd01e6a21d766ce8f77db34a3979affea4cddbcd82e1e35a3d9041b759432f23454e363b5a34ac1b4a00328eac0d45b0819c12f9f1b03b122fd6662b8b6747a344655e8fb639239e092a930e861988669d050c1bba6fa807a81eeb370e5a4142f7e54361d66c469a84e8ef2438bdc60f48a5d279ed1b2ec69393320053a7b03cb0f35c9a575839b58676566d4a48c79bfad7474e431f3a2c7794e690815c9776923853f5c347e303b3e94067f6a41976c0f63640128fbb9c4535192375d59df22e588d3b4344b06ae8377982f9de295d1cb246b012b1cb7445619d44e036a17366d5b3090ba4a07593a4d1e9f8a47dc4be0d8e28c1aa5ad9b1855ab88745859792efad76484fb5c489374c01b0e69d4578165078ef55ce12a949c9acef73a851e55b3167a03ca3e63899c5c37499b4465434412b2b7dc5b6e29a54c4906be067f073b06d12396d8d1db3bc618638ced8e1ddba0d027f87f8dd22f65aa91e94b0c090ff8973692c57470d4469a98803a265b9043111d6b39860e34e8ae0d831a9bdc690b0d4ce47eba446904b99b92a090228adc0f97ec152840824bae143d80a4075722c2a1328a42048e232abc3072d4742913f6ce277870c3912838e7e649172d394cadda9a4e9db4430cd3a9294aeac8145b44698a1dafb85c2b2f563b3342f065891d229f99a5176421f26172bf7293d3821c8ab8616ad1a0d2859316549250094886490b742002628a49be84131d62521347c45dd9605a4c7124f757a197d2a09da4133154da49c629a81f9e8831a589885533118b498a542c0a18a4b03264763ee1270d86c839445ef1871fbbd341e4f57a15c910432847e06f2f24824e2c6d8b114d1041279987748ef89b6cd7e528eabe80ed3ac698713543ffeefabd935846ff31a48f53f7e971cd23be1a5b64fd2aa5cf8fd467ccda61350b189312f7a0c157ef3c31852dc295dec24a124a69adb516e5cccbdee5c3a23cb3e859f2acbba23c9f7e9017e5e8c13c3f28ca28ed1691acfdf91b7d8ecee9311f2017e7d92d87a01272a053da256ed5da819f13936449322a29d532f92a440ca368738b544ac8719df83872f4f9ee0e0e0f57851584220fd7fffbcf69654d589b7536b36c9bf3db49c772cf2d72be7a9acbe50324292cca20b8196c5251391f6f653e3e3d2ed85357ac9e1e9f1e1f1dae3f94f567d03eb4e0da64b3dc43b8444eb11b854b5465b90e757fc66ac6f3a48430202017aa7b165552ca949a7adeb445a058fe9418c6226d8274fd3f9859e082f21a266bf729364b7c22d59035b6c8fc556b8354c3c946498b2091cca369e4ade853925cb75192e47a9c4ad337969494661e37f91acbbe7ccebb514766aec5da16c15f7af188baeca6b5da050c674bf942a65fd1dce13a9c753aa5c17e50cb05637f3bbab48cfbb1883cb19e584faca73b94fddc88f84fbd305324dbfdf8ee7e3759e9ed27bcf504d64f26cc7fb4867900a6ce8aa90c577bf8e4e936fc9193562432ed274f5837ad2788b8c0a22d02ad784a3a979096e2572f2bc6a50f28d3fe7e1231ed2712519d7d7ad280f2079f644449b1dc6dede4dc2edd7363ee0704146fb0e004049d808072708732271688363084880b5c1bb5512399dbcc361e42d6fa288223a804135250c147171c41259890820a45808070049560420a2ae4e076fe80725682ff682fb588f4c125201c26f0608108083ab1523d116793f3c192d09932c1e5e65949ed945d31b8b9e9808c3b946573db88b86deba4971856da171929a8b082100f1faddea2b7901255656fe1c47ab130e7cb349f92a1cc96ab5f380977e0b1a813bfde3077c8fee4625afc677ec996b2a58c29e3b61a4e16db28a9e1e42d89bd8a922fb992ff5459ea15ebe6735abef4c54a8b61b8f4e15db16e3ea715e6765eb16e3ea765a3c486892b29ddd5dbb896eb311b25359c7e7862fe406339da28a9b12566b3589843abd66d8d57f7ba97ee39aefbc6d30331f783534c88375a2dc9c50ee631f2d7ca5c6bc7357f3816a01351c661d822401464de70cfbc613debe63b05155610e2e1e3bdf45b6963b8f44d484185158478f818e3b60929a8b082100f1f3d402c96092908ddb4763e38a5d5e3ead99e3c613a4195c85556b4311c911ae7d8707b70e5f637cef9d6e7b4fc87b6952d0f62fd56dac63172e9c3a6db397efcfed8f381c4316380e2c3f8f2c6c711ffe3e7c468b17c281b30339038664cb612e5712c4ab5205968e14da5505d0ad5f5e8133498e59c734e39256a7ea89fb2bfc26d6e0f7fbe6fa977fcb9f20845eebd78c853af75b8e21ef27ba452b8478b4031ea35199b19a7699efc6a9edbfc20b7a8ce9b1eadb09b34d623d623d623d623d6638919fcb990677e7aac5a6766eacc8c8ac6ab54f3695495a752d5aafa5a594fc363cda854aa1955ad5555e1cc4ccfad3275557dac64eef7d4998a7b3ede089a41f3af2e1f8cf56c800522492e4034c4074df577b723fb0cb52da35ef75c576fe57cc4a4ebd08fb1187def74745c0a453b8ec5da66743783ae83f5c07a603db09e0bebe9baaea3f4530de002cbd49bb427e55d4a611d75f504d119a59424a0e6cb9eaef64f6fc3b5db55c5a5e4a2e29ae29a38887b7a1d96699fca3c087924feeca185d627e571592a7b992b1e8258cb7efbaffe76f110ff1ca77a7a2a1eca7a64578f663bb4ac8168eea8ef855c7f6a9007d603eb81f5c07a603d45a8e69c74423cfab51e5c605c847808f58075af799d500f9810a52f04e322d4033e650ab9640a63419e37c3eb21d4a3c6eb57d4d1b8a4a22ac42356c9f4857808f18854327d211e714aa62fc4234aa62fe43f144798b7e806cb54fb524f69b066b4116b35a306cf80319a19d57c1b0f0613b647191dc3c9828739373c20f7eb976708fbc094dcb98b6488bf7e75f2a1d7828742aa88844fbecd091b7c3883ecca1f1c93bff8de395c1f017e77403ec717105720414c8585101e605e1d3217b2f61fb57267f601940b33f919fcac89b81cf1941dadacd5aa79304a29e5e3104d19e3cc44ad0c6f11b24605d73db674e9f187a4bb7728a4725de518b190f33f29a55c4d6ece395b06f6930f3b06c43c045f42af422ebeec2d291b2eec2ccbb2ee96347a4321a394f1e1c76c764f59dd4b438ae18c734e192b919a8fe828a9a474526eca0aa108527a9379e385fb7abd8af4d77e6f8422777ed6b13bebc6d2e6a0924ecc79cb5f7627a03f5c79283ec755d7de56af7af199bd36a085ce8d25fee1cab59d066b650823b83047a20d86b3c5fdb1c132c54313d7a146e2f261076a57552aec4678764210804e003c0c801c0f70dee6c6c60c168d1a3534ab1919d50078764210804e00720080bdc7f1c0c68d4d0d1aac193534ab1919952b0de07a43fdf27b870afb174ed590c771007cb8fdf73ffabafef2d643103e5072256fbdfc490457e6dd8da490ee9c93356302a02cecfa5aff8183e0ad17ce7b37ac771a5b8dcd667b6d336c8da5b14ba28e733219ec25d2fd9cc984f523f92a0fcc7fc8fd3bb12db93f04ecfd02c0fd3aaf16fe2a08f8bb1fe08f1500faeacfa1af2ab91f00f873e58fbe98723fa62f0f27c1c12ff7007f2c1bf8bb373446a54aeeaf91bdfa69bce0929c0cc682658739c5ca9e247faccf9970fef4e544d1628489162339c779da46092b1f4a081f627782104209258452ca78bb2184b13f5696527e5cc4cea4bb48b68c755fb2f69fc5ad9b7f91b6fa972c7e16f723f22f31d65a3ffe8e5a63ec62abff507cfb9af656dbb4cf5f7ee60dc5f7f78fdde590de6a4dda2c8bbf23239ab033f49fed354d6e5e670fa2a0fdf6d11bf2686d7668df42675f94e96b4d61d1d6f3c8c29c123cc61863b5495ce787eccfa5d67b59ac7f586bc6d918331a792009de5ce28d5e12bf02693fbb57d56015685678067f2be3a4144e8a37765ca7b9f8d05b5bd9d6b67500b9ff27f74704e4fe09a5e4fe8d8707f248ff10aeb85f432ad9493fe9770e92e0b95b4cee079554780ebf6d2e4e6323770072ffe402b3c41ce449c18f50336824b8820b17b12f4ec09298600a30be88410a1c98ba643a0869a2a20c1f7670c28909b8c8721012657081254a64612204114c1491e1700497314950c044f1c28823213aa6e062c911182b7a8022bb21c8045070440a131643ac6088cc06aa2444033c7851c5952852c00394d89481269abc1c1501430737d410441a0589824b145a74b9f28351093224428a928011b3041035c0f00512599420b208d3d4440d98b20f0851e22206263f0cc1d445936c86299cdc2005521457f8942058204182234a629e9e803012928015901103199ed4c0c49523416820020642281991850a80c83c10c1100242192490e289873161bc640802c58a952426f04288271e3223428a7e10b32504626021a2091d64317cc04a0e947c50f2e203530683101e2a478e5001156378e08bacc803aea0400a2f5e638ef840f69a4004897569428a284370798d1122450b7a300289d3135d8469268448303d2801032563ae98610733a06011e3022a62208687322a500328548e8cac60410a74102448154a65c8b083172b53c40491f1218c327008c3c3ab8c1c0419120302cc17d891172041060452011aaca060891094a08a12f42948982527b61c016182299c082384014ac038c9628b2e4e98c608228b1072440507225022850b198e5030420060c4e94a1024703a32a585083283912f8878419519a4f8b2839019d0508694232d596c58e245080c579ea822cc0ec0204911420c136e6025071e9488a99243972008a862cb6bcc92151469226d90250c2d4250e408930e5ca6911bc298000c16287ae861a99708a192444597264937d030b21e94cc0086a631ae608283a2d7eb0a1a8c481241920d2818454bc610a206482c512287a42df48b294d9260624b1450a26c7103211640f2822dc0e0220c185ca80d82c42c940c299696805902860ceaa405089a7859818509ba40d2346419420c097658c28b2bbcf002032988e28a0c61d45082221a8820900a580b580003244fe010a50b0ae4a00b2f72a8d2258a105c4030aa68e294c5abe989305a8670a2871c40a9e2431522b22c608715188591021b94a8c116418a44602446162550810e3cf8a045103244e902851196d7103121d6c88820b86802050a2c289620b20b27312f38cac2440916599ae0181bbc404a11466c5802832b454a926220e60a11351809c104b7dc8083123d7079ca418a95a21a3ca0850d488800065dd8500328e5cb13276cf0a50b2d49d040480198280204465f54318514ba04b11062c41364852a8e8001858b112cb1830ca2c21a2612b761fd5c52014228d257a5ff7ceb5a9e1ec59fcc40f42f0310f2c4eaf56d7b190062c4866bd4a9ab0cc430b1638c317a2c364c628931c6189bc3e28d05684a8d4dedde349b628c31c6f62b31c618637b538c31c6fe18db9ba2a4f2f57abd86b45c39d313164e38538c31c618db63d2616c8bc5628c31c68e58628c31c6d834c618636c6faab16927c618636c77dc3e31c6183dd6ee4d31c6181d4b8c31c618db9b628c31c6d8d34a8c31065f23b5d1079ff20fbdc47ecb3c8c0ee4e3adf942f1068e9a69acee041df3c182a7aeea6b79296d032e6b3d1f9deb056ace55bd7398cb867d3afe8bc29e33755c208956b6fff1060abb90c46704ea23d0382841152f0574e005fc423d0abf70bf0341b1c3aea8d9a31f0186d477ff41d8c549f4a7f008af0b1500952ccaeb3c9696f399140b23ad9fccdc4de6be9ccced648ec35ffdecad77b3e2eacbe9ffc3270fc9fac22cb2ee402881aa5db5b5e664edb9306e670dd5d9ae9e567326b9f7976e37ed7277c3f8d3a46b16995a361f66d97c4dd3bca9699a96414de62abffe50f654010db90f4270f335c242a0ebb98db24d55fb5766d50650e17c2b0e6ee7fb30cbf0d73fed0fb894bfa22679a8fb21ab83fe7deb55fa5f873fb8a4699aca43691b57513242ae7130763007c5eb75de388b53efcf35ec54ea61a78c32cb1f8805c4cab2efbaaeeb5c447049c77cfa032ee5a159bdeeadb5288f7b2020200e8350c6d5991fe44273d3aa0b66d72d15b01c51f8eb8ca2f11f50eeefb7f16a78349e2533b3fa7b83db1935935633322a9bfaba69b0e358ef9bd618ead88a53fed2efbd25f84fe7b8b09ca4fdb75adc67d787d570adae00d8b89774d2ab933ac96b9e183be67cc6b9a5549665339b2964fa538a52e67ef39c6559f6506e8f4ab9dc362ffb5a2ddc887cf27ce80dcd9773ce29b506cccd9b1e8b4654e5f9b3429ee96e2bb7756e4a3deb80de8ad95076429665866b1d6361ce107df9b66e77abadfadb50cab3cfb6cafd0e2dd3be7bce5ff33cb56d9bb6695ced8af2fac8e557efdbc9157e287843f5b9b795db7e4756bffb8da39d07398e7bcb59bcd5cf6a26e914f2efa350ff595cd4a3aef70d15d9984251879afcecbd6671d2b7d49b165ae97d19b723be26b7bfbf63fb9bf23a9437c4ad7deb65ae39aa270e52ce1f921f5fc628fd395fd8262a6a9223a543fedd1977f47d1a893a31562c44454f64f971fbfedeb40c12e1ee840d0f416fc51cce5badb56be1dbb7b6efeeeeeeee2eda71221ecb1b5c3292d44c4679dbbe17b20624f3bea2fc6ddeb7f3acabf2946797fe8351705cfc290cbdabb2ed6414deb687b2027921dbef85ec01e91752545b23dac9b5e264b9da90fcfe21f9ac2a71b55e61b05ddc5d0ef5c703dcf8fdf11b322d0e5307e1b2f0a65ad0e54a74534a2985f31b52a1177929a55d67cda66c30aa84d9779c55ca38247e6123a636a3d977cd3268210a53bafb20a594b2e99c61fe9c90ce49a76c17f49c5576cb870ca831ce8fb2bb7b4a28a07c6be1436f4d29e94b2f6440e77c2c373efca0285b05012e9e80324bd84a923ec4524a292184524ae9020b21fc0cc287199dff01941ab38c62222e4f1ca5d8dbfd4fb7b18ddca494524a29a594669ca49452ca715c4ccba59452fa284e72f25e95aa29fd996512627f9a84b39e4922056fc05997936661a2ac358ca66d36725d8c31462e072a8cdb9fea74b420bcb1ca7033ddddddeddd3eb35ad1d034cdcc8aa686a6a6a66635235353a3ba353535a91a545753538382dc0ce0fbcbdad4ed76093fc6087f29c3ff31ee1791be989256b924fb31ee776be56a13d68f716b95dfdc17f726f539a96ec7cd55c940293f76cfd9dddd447146664675676666666668a06690b02f24b55218ad24810fe3421add61e23f5dc748b47be22f26b9538afdbfb834f8932956afa2dce436a594514a2923b5d65a2ba594524a29abd69aa6d5aa4929a394524a29a394d55fc6eaba816372aebb94ee70db2cd77528940f90ebaeb87ba94aa59a2a95b55beeed562e3d02c1815b3a4529ee72583756142a956aede4b82d958acb215353934a7de62c9c91a87b210f0b8845e33432332b9a9999d58a86a6a666068bf55e6ad4b059ad68686a6ae08c1929b8b3c3730e0d1ab7c6eabb2192bbe849eea2278a9ce4c60eb7103de48151b27b3794524a2965ff00792411b8b4820f904b72dd10df74396e6c441b366cd8a014d7a803ff8b972ff7e3decbaa8675938366b5aaa1c9e13424abcbc1ea723496dea2717363c3bd3de6b87278b033717070240e4ec4c1c1c1c1711c9cc6c1c1c18135356ad8dcdcd8f0c027070e84ff9e777360586d6e6cb40d285f0c1b37371e743a6c7439a68d9b07e3e234740f705c7a6cc8827b442b0f032027009da1bea2dce57e97b3a9e772aff75fdc7e10e416bdb59ff1aca751c3a6e6ffffbd4140411d472c7417fad546ecf4397dfa9c1e03df4db6393b3b3785ea38d7e63ec3ecee293b72dc5fff9179ffee96f9eb759723c8bbcefad4e70f714fffb397d511b0faac5ab99d65feab3b647a676766932effd9deb929e3755679df7b76a772a9bfabbf7767a73f76ac9b958e0ef773656f1407e76fb0f338cf7a4164fe5cb766da0eaff591d7524a2041997e7fc9fd02026119e22f2853fc05598b9be3fe8358be1da1c8851f04a142f49f0e8726a18f1d12f309d4891ea84891e76f1a26824a993ad10315589e953ad7d3881f1bac7e30c4f5b795660f2109ae8abf6f83dda4e0d6aff1d1bc72c52314b98e03eb31f87677ffc531c4316350e83163f21011fed198a8df883163babb718bf0e488266238a289185c3ed37b2dd618238b89751304cbe1036a9f6f20a534081683c99923e58f9c3c1471ed2e0275fc67a83864ffee819575bc204f11176e48aad70f97b5c1f2806ee68424ec40123a432823646fbc368a3a6ea4b299d15ffc67e52d9b195887e719f67bc97f62f66f261d64a779f257bc612426e170c388b5820548e41b38b8fc402ba268c95101fe3352b69160fe6353b98c87ecdf51fc27db2103415641208b91a51c16733fdcef8280e57ebd94594ef1462beaf8bbac5c1b7ff31f5cb2331e136f2179cb3a4743f3b2cb51f31676333ee57dae9c7a9ab71e912bdbf75e8a3afe4b4ffc07cf97d0604782e17e8dc4a2c19df9af9174ac7ee68322f4166e231b42f186cdcdbb8c0a5ffcb5eca73c20ef5cd962fa7dd45a64a7aa578ddb2346308225ea95999935c571dc0fd5d457cb719cd534ab751b0862542fd36d322a0ee66eab28eff79f0e853ae2388ee338c975208849b985d25a42832691416388fb51188541125c1bcc065d6283e119492c2cee672396fdbf1949d946cc95290cf23885cd486a2d59d2ea4ce49b36b89d65d5b2b72cc418ab53e7e9b972f4be4e5282cb45f1ac7ec30449976413e20d162a0bfe4efe4112f7c65b2148a5b46c4ba552196abb5acd34140a85aa194dea6b261daad3bada659dedb8ee76a9aeebbeeb6a0b7fae5433711d7fd4c6ca70cd6ab693d36add14aadbb1ee33448165688594a79ca1155262b905b75936c4730b9e87b6af70abb16e36c397fecd727cc9dbb6e1fa1a867562b9757402f3c18143c6f316e8e6dec453d5221c92a39fb296afe1f37461940c210bee47dfbec32b6f7f2e99276e21e6f9d6bbab86b15b9879e221892be6fcb654413c722347e23f44bc355532332b9a9aacc6a3f1bc19194f055b4eff217253a88eb35b24d22feb5de6f278c3919090be46ea23f7ea48d1880b1bf89c969da432ca967c12e492d2156ff41497abf5f13a2ceaf803b95c2c893fd675d8945c595dc5f195c4fddc916abd978524002897be53d506a04e7361059146b2bf5455553c4af94d02a3ccfce78323730fdb0038b2c3285991756f412693fedd310e6fd5c870b8dcce997b0d0a04e43fdec499e07026aea8f3465e3948e7f7bed83b6f5283fbc9238f78e52dff20f78aa30e6cf59f16661e923f1fbe852dff4a03fed4bf2c4882f673beddb6ef7edb220bf26c18d2802dea3900429d8b6fd4a1af23660db3200f5de5c65cbb3774dd8a97c3a0bbbce5ff320dabccac5c33bc1a8fc65b79339dc672ba1de79c71f6fcfef98d7dbce553c78db75c32aa9bea38bbcd1db3979a09ccb04f33f19fda4ac91b514a1fbf1124e52b07d55607611cacf5ac1b6347c8a5b54304445b3b40d403d2637e00e521f9dd9262114a703f376a02e94eadf7b2589f3bc9feb39b70b8df751ca6f28b452b272785eab8d6e60d26b693fb06f5df8ddc3fc28d99effe194fc6defe0a26a5a558d9bfd64eeebaefbaf78124d4ef7ee5d77fb4ef62ce7d4ecb1575baf65fda9d8e1c8ae405bf1cfbd5fb727245fdd7e52ce3fef32cf310fea8fe23f273ff73216732f8e340ceb0ed9850a97e2e4e2a39f5b0cb91a29fa5fe2b7a9287ea0fcda72a9584adafe614fe50ded7e5efd610fc25ec66ea7f7ee346f8b37df71984d0003b2dc29d6e23fbb733e7fc8c665996d1f923a7b5adeb4bd89aadf95aae18429e1c556b4096b39d45d994bd2aebe393adeaa6501d07b4b90381e3dbf10102721d1cb4c8baef24598bb5b7da16b7f31639ef0c76969aa62a124293fb8326cdfa41d2fd362548c24d769ab4830051e4fa9faa88f7b972631b18e479ddef031b58fee0a5e3266f4a902728561bd84e9297a4a42c27b7bc596adcbc1f309679dfb4f883b1a9ba1bdeeab6cdbc84526d3f7b98bb4fa13a1aabdc0de73758cf714999dd1a89ebf49cd67e7b5996b93c22b8043463326665d758cb8c8ebca31ba0b4a834ee3884da319a1200280043150000200c0a078542a168308d3351531f14000c7ca2466e509a08644190a330088220438c3104004000200000631063640402046bfe893123e32a9c2fb4a74f2eb2769b351aa1f27b2a01abf765c94066222f6aa0922a7a2a11c524af0c4b4a9da9c27156cb3410324db4ee3b9b52e09a667a929b92eaf886fe950c550d36f82aa2ffc5034e304070ec7798ea24ce3796bc7d404efff58be84bcbd040a6ac5b6deec077d63f882a869507249930435fb6068af8e3d8cb821b07180be490dff80845b1c6028916897623a883124ec6c871b562484fccf57717aeb317c0521df88d7b29cd3ffd8a19b6a8228a13eaa05668a8bbb42e680b0d0c6958e18408d9c40cd015746d3c423dfacfe2881431b800c722933027efabfbc03ea32c8e30e032ae21bd8b218d6459da154d66d0895558092e4beb036cde196848b9afef59c43e4630b190601b431cde1a1838abe21d731a2ed8e3f1babcb0ec9b91bcbacc6a555f420acd1f97bc752d7b8461a8817168d04b3e62657f70b3fe73a58acfc981669c22155fb323e8c5c22f7f1ebc42a622456940ed726c629650a6ee919112a449df2fdd1a9bff24fa3f80992917937a9f1ddc45279a7d6284cf190a208380943bab64001b4d9f4e0180aa189ecbe5c8b706f729116bf543f55c00d6d3479f635917b2487d3c66b4e419395ab17785cf9b049c481ca77259ca1758b9e30339ac39d65241050668b8a3778c2ab5d327d9a7ce313a9e2cf062e42c55c8162a6767a98e0aa5c5c79657a4733c7a4b6aa008917856dc9c5c28ff30f708d5c115378fe908e2a96e12935a57cca5218d0415de0af56456fdb8dafc5fe6f612a6f27c2a4dc106348a04fcd2bb03a03c99006562b7de007e322430f17a7efe0956052a41a8a60c3a20cc876f642bf6db6fbdc87ee8225ee2f00fcbc1a2b317a3911490e2853c9b5d1c7bde11204aabe77792eb42ea737de51b6009ff30fd4e269a309b9290bf6312e13fff2e99246f1c463e3a1475da3683001e0314f68c654d62a3443dbc312a01de80b0380e781d8f1578a6057be8f99b11572bfdc02b70eba3c0556fa01b1f1fb80d54091a8c91d005428a9ea8796a26b157eca38d3191f7686236d1db0075e83b3c93310177f58a02e5b8d8ca8aaa0c140ab4f5798710856b3644c42959c62a1a8b34cb806cd868da76dcf047c24106bcfbbae385ae640b15e69e012020b244fe8f07393adeb431a9c013d90c4954775effc45be8c86d8a8cb700c83bf7ef7229af3244fe41b9b16151df0638af39661c339c3ca448cd30969a752b043150ba58d07235413c8efc9df3dc1b045c8837a599c31098fe1a92b8fa8f014c95243ba9aa352f67a0b54f0f8907ec0e986db4b6d2891be7313154c8e5c96bf1ac2d8e84b2a835d5f594113b00b706b282ef94adc4a5c57feb41fed5e96919edb9483a0494fd94e4b2ac14ef9e738eae402202c174329b18614962f9f112d55b22237a7afa97771757afe41e7a7091edcc1ca04ecd1b7aebb623aff462d6e4f850fc595423761268aa21e16201e1d1a2a0ee4dcf67f2f93c5672e23ada29338c5dca9ffc7fdb82e72865d7e699636a6aa57aea55e918b1bf79462297829d4df1ff0f7cc787493286ae0bce7bc70af020f0f52d616e5eb5ac3ba0228e413a12778dc210098c9d5bae0446b58e30c0dca470c7333ebcdd4157d97f1665e0b0ee0ab5ad016c3e1491b9421a098388265292071008fed2280884a963a8319cdfdfa3f13819722a927a4390b3114eefacd000b4095b39233ba0c8f3f65f133607c84e40302a3e47b785a1c8e3fbcec9ba0c60ea52245ca07b01accd312501e75fb8aef166492089f40b0330383d2e287a12de2237f85984a8611ab03d4281e386e5c16ca3b13cb11c6a5a2df5f77ec531a5e0e9d3641965a8c96ee1dbc24d73e77435a4411022af1d02faf6f18184926f35dbca2c044759ecd4f3d74ed531c107500403081d11e185c5e0323ab5f7914919e2071ed32ba1e0072e2ddf8def33df6854ea38cc88ee01b3c4efca3b20fdece5792552e4a96103f3e0f8c53ad18ae23435a0107c7efd10cefb3a016ff4d65ae3df82f68f4bc4cc7ccff54133f86c900df6771fb4a7e91a04062b8fc1c6c892be0d56804f7d08e2687f4fb22fc072c1fdf5ee75a2595c005ecf6f0d3b2a554c92513d44c50bdedb2c2279dba1c0f65e8fed0d670bb7bf1acc9f4f57b4462823af917d8a2ae736a761989e01c5b20e29a5ff8880e7f55c538a78e8f5b001f359b5e52e3fc6054796e4c59e3cd8d95697bd9ab2953dcd8a44865d191c2b32e9f88ba889654f8bdd824e297fc42e6025d22adb6ff105d17e54b8caacded6610e989ee0ba8fc19f224ad9c39f3788a0594bb6a713194cd2762494f8e15903ebde6a63150aabe63954105a667d5bd97bde6eac1ee4a783952d2d457174041c9a85d2e95e0ea5b8c9479afe0203a0371bf4735820cbe09d0ac7120df94c2ea32287f2dd31fef596bd6b407517cacc1cca8f2c2c2aeb0dc66e71e650e21ea2a69f8409930d69a23c5880a44b278984c0a027770e0ce1289da1f552064211e6fe2f019d32610f08c40361917ff00eaf447cde5891083ae6f143578f6ae6616f43489c6e41c47e82b0259a774ca76e156b573a04e77ba3d8cd41f31aba06d38cc95a667c025cf4811905b68b5193ef3b534d6eba667f93d7f17393045b256a4e6297bc166f2807c426a528a3a73d13ff3ec449361d3bb6a4ecd7115df505cea1a93901aa08a34e90d19c1db5c56f1c2b6698a5921d3655aa10f17594310c456a19f8c93cf4addd02bf6ceee61028a7482164085685467da6d1e1ec2ad53ca5f30c1cef07f797f5bb2a855912b16926883837b448523d203f32a525a38c257ed4590495198706155bb09ec28a8c33d934820bad116009a0349a91928244b6f245c9b49ceb0bbed528a5731ac1bca2cdebc05788690cb4cfad6f1a39844c40fabdd0f1fa8c7485e770a606e91eec8162b5f63e69d2e8bf619e42dc0ee5f687e74e234d499d4a7ab52958ca90d7bf8518d2a947c6ce40bd5353debf8c28d1815e2f3ea3ef083f72e3bef62022d805c27e22dc1816bab144e337399fc8ed6b92627708f0749054facd2007516da4fd44a44d330c3ed710e35f8686922ffe600d5242df7581a5cd491ae981b990672c47e052ef1367aa867a74c6a699083271a108b90dd79730007492e6e92a9e4f97b3a1f03d66a49e8b5de36f43b7fd087ac50ae2525bb1a1868543dfca54eca25986a8177aa69dee721d5266d1ea3e204774adbf6cb6060bfa572151df852844999991aa8ae4bfb8ae9c19c1714177d82dbdc40bdb90766f9194f6fefda468b8e45175a53b3fc573acb341c374d02c6d71207d350a71a06402a6c2936261a192927d9e7f61c15989641997f68548b8a9a5cf86c5646567ee16a96144b5be763294ead165a3b029cdc35abc23798c44d78a30d9d3d74eaf4d7bb6ee0e24653780d3c42feb10e1ee6b4925ed543d74c6afac73f5811be0c1880897ba44bc46bfcf03cabdafd5c031f858e3048ad3d392ef41b371ff5e218a5d9e4e20756b7286735e00488169e067836d56e233a2986bb0c985e363cfce76e8ee653f6d962c514aba1edc0fbc46926834c2896f12fb4d03328e950ca553a5148c0c05c44cbaed167a740d2be76c86db04fb3a0c81273d401bebde71086257230111e7f3b3d05e4ed0cace565c11aef8d173822c863f863f47f4e8e9132eeea174bbe57486e73c699d84be524d152c10c8289c2368d6218dc9d68df6593ee185bf65d32b11d07a715f24c7cb201d2df32d49ebddb81908bfe0d2b139d24c7806bd48b79b6aaa5fd5b3cab46d262c2be82e041e123b49f7d593cc14a55086724aa164587e38ee373fe028b6773cc02f5ba24f13f89d2481067b4416d0ae2f2df61443de44f13e06ae85f07722cb2353db1dea23110e67440144927acd030462a5b5abbe1ee01c3700aac9606177a2fc0832a28683ef2de9386d89d208ac8b608bf3093b09f332fb2749bf6e5bf1173f4ea4bf898a60e7d5cd12708eb480fdbb4391b79127e26b08ceaaf29e055eaaae84b5444f9a51f22da6ba784d0064bced24d903cd2b29a47025febd76acd82cd484c3c8955780b7a3456de15a465319751a9e7311e95d1f6acbd568b0610b44d4e68a45ca434a2abd80f41ebd992a6df2a77d05e5d891b245c7a32012c039fc1c93e7680083296ee32c5cc0887e9c4fa2670d007ea98f24c3835e487172636ae4eaef6b1270176dc2c2378137eecaf8fdfcac72ddac615b815ab6115779e579bf69e7f53665abdaa75385dc53cf734399e53ea1d8a50bb8dd756d2874b2b117b84d1360cf3e1468b229c333607347a50a1907d82032398218448b7c657e6146aca52a4b6e3f10db8e432c2dc7e8f95e288174a2ba2ed69a96238c1675cb14745323f021a1211f68df31da7d6fe69f4d498f6149a355713e0abdf438c4a7ac47b28cbb85366be8c41960f5292c148566ee5b22eeabc53d04db4cc019da80e4de588e2b1b94135bc0a4479a97cacc8f00051a395966e27a205446d91f913e678791bc1ab9b9ba2b5186bd52214a0006f719575aedd6da89f2e17d21706b84f0c0f4fc1d69c574b3887a68855440a048613a28760fb17d558dfb21a76ff066dc4baa5b4a196953368faf73374017aaff1f8ad9a5611050b9ddf8d5a5dfabb4cfe70eb3aec89b0c9f505c3d3d97a421243d3a86a618b9791616d2ab2c58303e017b6e5e0902ecf010e795093a02b1e4bcc2b2531c3c56ead68575e705ba5a6b38e66753e46c8af4677036fafa514e88cfedd8060ae28cfb8d347046d6bbf929f91251d416cdfd6b64d9aa7add94179c5f914c3113136b6495a53cac780e59f0efb9eaad0b7d93214327f93620150a6085c474fb6e648223dfe3644446522fcdf08037e9bdbf5406ac4f7ffca8089d6a605c3d863f3ab99e993b828b881941201c170fca60da2c7064fe57bd3666cad6f49a11718b6c3ebfe4dd6253787bc696d33b448a93c69bf7d132e138ec9b62e0673e718230d54a29cd2f6decfc8417add8b88153938eb872a10340cb4ba415876de1d82e678633e8306bd745d767fca63cbd6a07ef39714bf96203295056c868260773f571d9eea7bf2070ef226f846fc5acffd464e7656921dac84432b5c3b353104b0fd733971fbf982e26e365af8e650921492036504aa18cd29401ca2fe3b9c8eaba7d9d6560998a2c89427f89c13ef30f1321d8176c3fbf65f087dd4c3d2af92a4107e64e2805c8df8ef55a101d174334662329eac55e8a8dacc4aa3442ba63ba008e87000db0000b8f7f117825d6ade3a3080dfe052994010859d4df6bd3cbd3be646fadc72837be8d04fc6a29104f70b7ba633c74fa00a660350d1271d8bae84f4ca55dc50637c71caed4b6c4d7854402da3260e9aec5927b45c3dcac30e9466d05a441bdbd26de337c50abd7b0bde221deeb30bd306d9ec5e51e7689b95fc5c6b0ae5cc29579deaffbf6496245752a827eceebe4a2a9faf3e68507e8d8a51a90ac6dc5966ad0c75d5d8317255f4874531486c791bcbd601953e53d7f5d0bfa44902e1d45e6acaf76ffa77a4b5dc863e807f17f120680913acd0a1471bf3a29c45134a4094b3bbfa1f9f1d5cd4908135e5b1f93a671ec23e7b84597f4dd381e5c5f1f6f220e79b140fe127c552bc9f1514f6f46113e9be7bc161650c41fac794caa609c0f1c3030d12b0cdc4043b9008a1ca27a8f60834f604485219eccd973d069ba368c77f5b6641667176912175b055664b4de527ad732ddfa191e8893772088e61c0492113b23fab1a92afff811a0554b86c984cf09fbbdf820cd1b5072b68433d4703e15fb33256c63aeb16ae88745fd034667cd6d53041a2c205deb1355ccbb0b6497f4936bb11d1ae7c8fff38a1eb995607c02c30a20ac8daf8ec999a387f7177e4a005d28bc7474ada3b4b4762d4cebd2c6572eb816a7bd01b329b56991d97de01cc4987a7c1aa683d11af35dccfccac1740442210d701792ddbe7dc6aa949d714183324d0d9084cc2cfca74afe412cc486161bdb0e873746ccdffd634b352ed45edf5d9efbd6d008467e0c20778bbf0d484dacab2ae406a57b80657ed30d63c3c381d8bac1f0c87848405d0382606451d9254594a1ed7c546adc82117b766b0f2f40b151d943f22246d78a43cbc824631964360155bf42b2d114d763c8ba5d5186bd288bc82a7e9fd6963444e2a1b8474579ab463e560803079d8d20f88f09184cb9110708ebdea25d824d5cfe45d1a1d227e7ec272d582b6af28ecd4654ee09eba8bcaedba99ccbf2b659044a235e7b754254f09f51b92504e050aa03236c4db0f97f9860764096487deefc7900598e67799df3d3d49fff78e3069c789d8eb7b9016cab8936a341c7c32ae7aab6e78734dc0a814fd4823cca0dba96c564db1827e30709941dd3022c8b8aa7915a612e9f0528533d6c9e3ec0a6ee94fb6035c7ac672916e29da853d66a9480694702563498beb5cb622eb681b67b272083761528b6ac2276681f9476d10b049c924f069a356e77dde68ddf86a7a45571085305e6aad607bfcc6db6a0fe732f9fe8012e3c01555bdafbaba247a6aeb78118c284370ceae08f10826cb16d7f55d8ae450597438eb70fbea50200f70baa6b7b8f100494da10ced4572f8fad69cfd8686fa2f7e47e617d3d13c6e03d81d985fef0625f77872db1a921004059e2886a3bd50d63c05a6d9c60feb50eb9fffa9b48db80cd0767c238150e8274f3f35d2d875073a7fbef524219868d29a8c70797a16773716962832c8127f061d233bc4cda01b356e0b4d40073605100c9abcfb403823bce6ce8f0f0bee5eca727da268d44609534872872a33fdb7d0a0400b1c88e5b05201ac8fb4e32a25db0291626eae68716a52fcd396c84b8e6197a27d5236a85e9751ee59156461bdfbf4ac41a264f643b7f2b036f361ae983996cd6759c4efb11d193d56b7965e09a030b01d04e1f72652811bc7e3f9421a2437488948141c398cbbd067fa65212cdb43235f19279c6cd6c399624b9faf45205722e4cdaa61f289a79f3dfef286232d004e752a54e07ebb573cab46507615f54396a3837d0a84a2169037e4a2e83691fd8f5d63396dca30e85dde67b02f39d1335b7fc1f6666c95f73c3f1867c55cf34ec8334189cdfd8e947e5bcc56124f9b4c28fe78c3c05ef1dcc6547889d4947e4721d6041ee6e81d3191ee8f169fe4be04306c564521d1d8b692e2d77cb6b45f0bc1df676cbb620f5c465a59530e5adac77e5d569e36855e0a00101cdafdc69fd78cac42b682756cc2df7eaf35404d50572c5eeee7e0330f0758f8d6e6cb17ef30217187732c694e31e3f58ae66732ce30d621cb117067230c5db923484a192647533add8e1d962d08b36bf5a4128d05aff8e57abf05ea7ec3b611d023604b19aa65cfdab53bab284de18cb184d90945952e2b6f56d9e81e5ea46526458e12352d52a12208405b27afb5c7b38ceab1de8bd86bac46b9cb23c8636b2b04c640954a41a7866cbf4e748c48bb4761c952c9e5d474388f21698042798b3bbf0198d51866087b5e6f895b0e17465f9ce7618049e4a6011a47f792cee7a3d6ca8f2cff800fbab4fb91d536b8c8c0c35f7e3ce99885cb8745b574d00b1dca3e4b856d847c9f830e89764181387fbc76f90bb529ecbc5f4cc851109d28b137b95b3a6b18dabb209488dc3b71dad9da463b7d9d6b7d2086cac17ff68e074b313b42ce09a966bd0fe745fc5c186be092d229f8e4278242c999c9a4282bb5e74939dd384f926db13761e2daf4bb32cd13cdc5d962d1db86f091bf393e8911a9d21e845dda99a00bb287785280dbbdf90cf32a5c3031bfbeb7f8941ac14740d188ce988348644ad2a43c0b557e54935ac7a3f73ee0547db9aa73edeeb1524678b45eaba3c29a56d441514dfa959b310b5f124dc4880bd16965f041874df1e60a39e2172d642d3ec63d3bb45df557821af7939df57f6399528dea98a84a6aac5b715ca57473130374ad8f5b0727939116253ec570a6684963fade08608714e67c373124f84e9de01ce2bd3604c44821db1bde4d62a70a33b36bebe1bbafcf7d73540f95d0a2d34ac39dd647969d63061f04bc777c663571971b3ab6f51c88e83fc5219f3628a073bc39d87a51b4874d616a41e93054671c01d9c372f91e8a4db40333f9f645c0529ba975e094b04ae448f3aeb90f093304537a84393ed1915dda0558def96badb283af479464ebb8ae549a5280bca38e652c711356b131830ed15ed67cd763f77cf13bd43ec855e4e0ce1577db6fd4a426bcd23963ecec90984e49e21be4f2f58e48215804f6dd92529c7c68d4769b19bc93fd462927f1753ca8f6a65f2872908899d4f131d060baab92a16cf311b0fbb8dba224c9ca9049f9d6506b8bae59338c87808f6ce88a9904f0458507ea6a33437274b075e508782f300a9270f08340adc1a3e91cf15f66758accdee91cee5822441d7f98eba72dd53a80cd616e44fd64e47a3972660e31432f35365b6919297d9715193d25c3b301f39cf979257a1209ddf4de2802d3b129da1142d228afa5cda021c36e49e3e560efc42071f0c9039bbc4f81aa4144e97f7cb6fbd219f1f6ec50824d4d870535330064f9810e060a13c07b54d82c0302351155c8458b67848a9c1b91a00e51a3e7790ec102f1b7adf7cb923398761947ac629154fe3db45768d60e90c0cfc6725489591fedfb0c8b12c36eb64b2de909e3115f9f2d1199469bd4b237ebfe0aa984533a4800e78154fb067dfdd4f6eb451f07905d64db88c8e9912316930491345b2e8f301f791d37e95699b4fd3f47f4ef448e5021369348054a4ad0045c788fadb39b3d919880466a0d482c56b98faabefcc90409cd58a7b86115d22d3d0361199897fc501d36c1f82c388a38382e612774e44b3c4bc166d6164f4ba3cb74f70e05742cee89141ca2177dc824d8d5e2224e7cdd73ce06f463c0b01a435fe8de18f3374f0fae1425282eec6f03776481a6102e904d4ce2a4a79a6e2f67a81d1305f4710fe389c4ea4e78edaee6be679eeefd8897787de295d1b150ebfa91227afc8811d2c67b8ee40f8c70be09f6862a9f966bbd517e8416c00ec22f660d6860fd8a68cc01a4ea9805c121b55354617022a8658fb85e651509c1c6dd9cf400e997738666c13640ae21fc661506c58045561f30cf091cdbd0d41b5b7cb2cfc4ed8c810928d0405a71ba4112d510120e058f717c386e40482829dc4ee2473b79094177765b7230113001d43567da9c83a860795b41eb7ec45c3a639405a70c47a52e56df074b40f35b4c0c357de9343eb67ce5e5d4a836d981fb780661b9a2e0ff1ac33d6edb4642336f32c6567206402fcca2f33f454e2465fc25e86522d7f7eb6861f942c57b397b7d5832ad296e9ed82e3fbee22c37832fc3730e16521684f655e440f19bfbca313f5c44159208bac5937a5bceba2658f9761ea811d02e8036d0241a64c6a24b6f8661213ba6edd0cd329bb8a58f267a912b337e6d9d7c7d2ce61821c05faf0bb30016e05532bf62bd2cadaf4ebccac78e3f96e9675ae99d47d91496267fb78c23fc0da7a05401133efb7c4e8ddeb7b4de4908c135e1c42acd502da1ea951cdad5844841d3298fd054a3808852874da6416aa0ca493b3368cb25d15a4d2b9975d40d7db40c94048deb9ee544ce810cb622eba0d36dc5abd164312ce5a19e17cf1a27d428b7036b1414acf0254943792bd2c6204c77cf20121abca192a33d2009575bca3d327ec1e310610a6d4a01871779c31a05a9cba8d41f35f217b1d0bf7e825b95c571be03023b340476ce101b5a00aff7c24bb372bcd308fabeef56a0b511defc0dd9d7408f2e947eb65556d8a0ecaa045a341f0c64e7bb70ade975766b7706b8e5e7c0098abb367c3d16d21fc6739dbe5924ad2d6f2928749c7099c61703ab1512c4ee732e522dbc413170988b2353e3c76e809ec60c428330cd2b49257b811e940979f77c72a316c890678c2f6f220268b75be4bea46a86fd9bfb956a1076056fec12f72b770fe315ec3e0a6d00c9f08d1ab519d0f8799d11050cdc4d4fc091a422537504d452e01678e81e29eb84e90e813eadc56aa4b2b52d2860f71bb6523b6f21b62355d7564cbe0ac8ec11370543cf55361b79f7ef7810f57064424dd4662315ce1460cea3dcd1faa323a09ac14432bcf23a9588230c04dc436d4687bf18b3ca80e6fd31c9a5f151f99b6799c55a6c0bf5c6218d531bd94e138d083098d1f4d0b3e9c56c4c52c97dae1c1b07b2a0b1cd917a34127b006712550cc62631aed5406bd607f7bc8e62d6d47285faa5cb4fcc747d298fce9ebbc524e4647da5e8f048bfc40da5310173f9c1bed06349e881c2b51e82a0b4552a7eec189cbab6fca3338b4c92c185cbb379603d77a6d07c90cb0f661aeac456f234a449e31e9edd673d620bf1d4bb3319bcf4480b511aeb9840c14e79f21bc4b572201e3f61525c29c2da87d0e93d7fa2423af48080b7b89c3c90c07c88b2ec8c0a227e2d8ae1a3b50e20cfb5ef54fb6077bb46981c97fb0770d8520751edfd26b28e348751669e6a2c8e53b41ccb5ecbe8080efc882505a55d49f3c58a95893b2b49238e4fb38c15fab09a4300978d62ea6b1dfdedfcca4c92e6c552eaf1ef776e50f1cd264479e1e38d019da2b44deb34d869b872d6344698806cc8f71d324d8024494a74c5c269acb5531665c048bdabf525d1538f9299057b5fba04e4a8d32ab4a51b3d1532be439449343a35545aca8d3ccf637115c29d9818646f989212cf741ca4da6d1060aca7803381324d60d302fde0c43bb4afefaedafbca097e0dd498ce4c32ab4688895a6b0e8204fe4da7cc6d267cdbf25e2b0b311b25ad25280a0fa57dae5815deef70e9bad88c4377f3afc6ec07a12eca7c73204d351bf65bd67b52280f20606e320f8f4cc3709448832936e09ef7cb2124dcf2829e2c2418e0e004ccd3022888f574f21eb33e379d15c56f317df1f209116076c98d6d9b475a151eda87df73d5aa1db0304a405b50bf6a493c8a8183b28efc586371005d11b1eb6ea06d89f7a53e818207fc03051edf76f203771f27565346131ecf1cce5855d1d7ef89bec973e6e3ba1928f776bc01ee362872dd6d18b27a580bbf5b2e801818c1f91f8ef7a8e66ea151a4fe8df8f9026df95b956eba1c4ffc38d9bf0019a7c0105de53383cafd7d9fd370cba7df64a280df72c76e870eaac1fd7791b080d043a33f731081ffa25a4c10735ec993e0dc15e7f2dab136fc7e05cf220e76934755a4958089417b258f35d1d41124d0f7dda9b9628c8c31e8e9e4fbcb5a372439bb5a2893304b6c0a7118e36cb4fee0b94ede4703e0975fd2ad0956981fb92323f3fc439415b1e463acc00ccb2d189eb34e4b914844e2e46c3b3758a7546514a18b08d2a6571e295ed96caeb89b4607b0cc9b75ba418729e11257a0c3165a34cb31765bbf81d3ea5827f25473c0217ba396c53064d654b2c80958ebd563294768d30cc27690888725684f6dfb9f3910c6f91dd11a97472f05b2ad2bd3b10f3dee802b458bb3f5e3d29a924ddcb927d83add34fb63f4df39dd9b00007595fb7c33acc4b503d7ffa2ebeabc5f9c0b68f0901e79985c13e54b5349c9d0c6cc47ba90c5220af2a713e74e1adb097d8131c264fec3a7b209bb96f45bbe02e74c3fb3ff262ba852ca2dff943745a3ce2951795d2b0350419f070248b63cbf3fdd921144d9afe9644ff63c3aae3c73f6e3eff9e58720b8b07b74215531dc3f917e65a3c8fba48dade45dc3c92adc97ef326e3dccd91cd9c4824ff5baf4901ce12307c2b6f12a005869a8f522ade63d04432f99714ab03a883d6005d07b8144aafe4bfc5901d29d697134ae5007175d75466a6ce5df8217841e863007439fcda359df4fde36ffa412af7b32875cb2476fbcf42ab21faee57802bb59aab5ad5b9075e49e0325cb200090a422f185bfd1d532c2f79dde7f8ef5bc9bd1f0192e870c86d8ad266ff57e1366fedcaa80f01a243d48b5409a2085b1d6d6e40200c960e9a33ec7946182982b85a944319f978b590618b90287a9705da6e745488b04a7ba4a5f83b31cc2725bab763e832550a40d20006df0300001802009c5b3f9e746809ea9d5b08b95428fdbf89804ef085c1bf7196c1bc6d44b2b27afa5efecb102ef21579f90997e1ae262b60a7123de9f0c11baa64242e5d8ea5ecd83323eabb1a5e0e1ec60a7c39b0af6693732028c5a9fae25bf37fc351af7fedf096e9e035391eae1e0484c6a14e5db1e2b9f8da71bad6d8f8663a23163e0f31128ba15e7cd391e08b2ea37dbb520752f2951a56e81ccefb02801b40b80d99bb60439be15a4f7d468e4177d1b8a5d7b54cff24a12d39ff2b911196218b5cd29eb379d0b1592082f2037b62222e2f2cb400397a10c7c8f683e0def6bba3d5b4b43f5e1f6cb5c7e55f6a8774b8a208528b45e760ff8fd5e0103e2042261a2f92233234ada07c27111975bd9fd71d6c483d9eb5f270f0ff1c8362aeac0a4ee12d2e209a83a978afc9931f38a554a8faa7ee2e82df8fbd14a80d926c0fc4cf49fdc45a0467d652a4d547bf6381df3a761f77ada35e1ced07ef8b3c127863c26a0c5ef1e84970c11ed7a894e2ae2963e49148edf972f19e3fb5572417c8221edf3d57d10121c8dde94de26bd19e98c2d4c635a56ec6357fb3862f71856094863089c4d1234ed400fb7dd1aa12925b0e68bf847f804da8dc830571090577020e5a55e04ef7181547c530038043e1c01c37c3c407183caafbd69860f6b589ba6254db8177608f122e7bce1540d30e24e856b45aeaec50d769205b59214a814103cc5485e5b45c44509a4d91b4e39e9cf8a5e45081c94f36b517ce33f42792af9db968cb8438322e31caa0874f3731dfd34bd38ae9c14036c9d7aad342465c91b5c011a45c4e242c9348cb8e99704c8f3451f7d5cf4ae7ad07783e7ace6ffbb2a0cd7c29f163537f288a45c59e349b33d1358ab8d490b062cef81ef1119df73a3de3c97b55973a453f5b4e3b811f5a317aad4b38f5653938f4acf54b40fb34ce8f72aa22339915b0f5b3ca4f17650b1e80e8261304a062271612bb61a2fdb04cd40fbc736ba8e0ea674a3c13eee12a8c2c1d80138468a45b58833d815d4a6d6d5065daff69578923463859c571034b6e92ccafea6289611d2cf78dd16df58f828f0ace4b068d82a08cf717704257fb0bb63335738d9c11c04a1239e32af3bd25441b8038443d95fc3ebccc59fd8893a220d2b6570ce3498575e1a03478eddabf63e90e0bd18f4b3d0d4083735b91189b111faa936f1289840e8ec531c0b406a627cd8943e4fc0843713fb5ca183b323d8b5009875f06d35e3796d348c34258ad217c96018538d326d01764061b135fb2357f92cc08ca27210d33c89dfd62699c597a0d308b65f661a05081cc43aec6b4aac764049dcbc19801fe3a2b0253442200e81bd249c205d0cee81306c0f49a34eeabe798238af425116a5d47e6e0fabf8c2bc1f48a98d6f7c6db0e4d5944cdd0c683cc2d0c093a382c6fe5173d88729e299dc2f21a30c8fce6ea67f2958d223df78780f885a45f697489f214c4af5d4838c3ff2e16d2acb9f7a9ff27880f1f4f7ad8b2001c173954f6e2b09981a2e1934d842de62c947e185e1dca414912a41d1e90e1b091cf995f025427553528ed868a542072a8040fa76eaff12d6c2e349e3059525cb883c554f1a1594ae7d5d6bc712fdcc210c8fd8eba8aa9135ad2ec506dc955ca08b7687b606cfc5ac98f8df990b131916766ebb00a2e7694e90472591627407439912a2392d95c9ded261442a2a264c4a22db0d8bf423e3accde97ea751d0404a25f742e221cf3befa54c6c186c66a1addc05b2bfe045c169b4c63f3fbc80948abeb8e8f413b6df78d134131e710d3c41b00f6ac56f6e24b1e0451e0e1f4e7dc0ce837f200f543441fcd151f871c3b0ae92475af0cd5fdae2860ec096d6a2c6e0e6999a960db1873a3bda775c2f568ff6b9f27e43ae83aefa6bc9aff26dac3b3ec765beb1735b20053fb0004d8c94e058661f4dd58cc903c4858ad113b227e651fec20c5fe6b08ebbb3523ebe0cc91302ca929c05b6c84c13afe3dbb0a7a2d61657f9c26de8a0c6acf9bf1229503a49d305ef44788ecf4f18d9f94a5ee5ef7696287e76b16b9df1b42c95777159c1e112d1040692b00826885d56643a868ee59ee258e0a7a4b125b5cb79a82791d23bd71216d2fd2bd8444f49e5fb174d639e0f6386999f2c2fe878e3a204ca11f9d33eb9e89745077c585eb6f4b5ae110caa8954fb48c09ea30903ee4b35b8e5789bc8eacf8fcd8d83f8830aace73e78a1b2c3279d0beccc6506fb92e7c0ff40f4c50bc766401a575eb16b7dae80e26ee01d0782073c9679bb2a15ab7b4017c0cb0b3a261aeac73e8162f0ee82681da8fa2f068fdf529fed2987151a99342118301ac0065934095fc04217075ad3c1e1b2d03197623d0aa742e305907a21667c6aae99e66ee2a713481bb04aa5605ab5ea92d89ef7885c3f9361103bb4d1826e77e819e3db654da41d5ac908a9030cbc0e7005c0cff5105bd066c40e4b3953025561244f3ce1c87301c4fa437bdb62bb7732ea1d25c665691e7da44c5d3904194ddb9eaff4a66fb9e197d210a9ce3308c76a694d3312245458970e53e7006c8ea7b095c28155c88fec5c65793e02610ead4f3eb4d0f0aefdc5f8f545b760def6e9ce0015c7170275301a8e0c97002101e7f9455fa61e442d10db68a73ef87e0cca377a92f945ed0884d2ee02e18dc82cc59c9da1f718975c93812cfefa4c8af8c3250532021b75ffb666ea560d12a8d4fb7b15607938018d13e72f12f5cf1ff17ec72d40594cba5a0e204f414d4156661f9701f4b4286f63f84dd5321d0189cfca8e71789b6b816ae8ed4a1098c701e40644548857deabfa5b9a6e5396a0fb33ae18e9373400fe2557a89cbbb6ca6afb601be5e013ebeaec19e16b7d50c04fea88e51d3868c5ddda5dde33328f47596669f6d6acb80f7eaad67650fba1dc90a8850e6ce8e38b2b81f2f45fa24ae95972a425626fb76a5a25cc21eba375d085f3ef8cd1bb0b73cb3b6a538a20db77dcffc57282e9abd75cdb9db7d361e878cad92691b0d1f4e6733fc02e4f48408ba1038f449394af64e9674be81632cdc1d2327176b0ee1eebfc32b04404285e2c8fbe6ca50f931ec8d953d60d34eb50bdad7b3886dacb2ac19859b4d579c11b2c2ba8c727357e525ff428f70dbc76bb182e13961675061001a7634a02a90266cd162b0b3cdf9e854e0c20774316c503a284212e351deda620d6a24992527899f4a05c2c46f6ed9684bb65da1c52f4a899cac7fe913a32c0581160f4fd0bc3eb9a0079c1b99ae694bc637917f56c15e28c00d6dd8b590baf00512a6f2a4069043669afba91d518562a594bd8acea37c3d042680bb352823a67931533919124dce9c5b8c61b458f6919c22c438fd98d5c3bed55736be4bc44df32f6a12be668e0865692245b29d52ddae7803b0ace59148a95af7480ba0b953619e3504996ea4e10031c685583d7c68f7183648eaa6c8d8d0327849545102198fdcc11a0218fb7b57760b885fabd287855c87eecc8452cb6ecdcfc641e2b867360b68b766c679b76678ee17879cdd55a10d13970c12ceed50e01b0c5c334b4613aae69a2ef728352254dc69c434b81d43a8fc59cadb55f9a74fc66dd68dcb1ceb5888264c1b79469f3bab5a702a1b68c2d857d9bdc22d51f73a2d68c4581f462dc16a5c5a5aa41b64f489b196ad76daa41a6701cc3d4ea2410c2c9ce5ac731aaa6d904efc9b397d10283956ebf0efe95ebeb1ba306b18c1f9d513495107636583b8ac06cf2251295a1f444d3daba2dbf2c0c62988242a246c73b43608281e2f019907f10508821e8441ab33f60b83c0006a5640246b44a433d601135bc8e1f40e1e434cc95358e720b5bea8c641985692a297c483d12d809976b1816fc0cf4ff05a487bd868671b65d2e450b21e2c111481a60df339695f0d929e6a42c856e822c577d71a74f8086e7ba81f65a2e070962e627e850d04e11610a2ec9c5066387a97550488033e20467acd79061745d90496f2609546c52ceeeba7fcf97cb03609d381c6c74908f2d2f4c227d4afcf532d91bee1159a505777098fc8be5a83f2ce04a9df03542c2665c479aaaff4ae2a584c0da01f0027ce89006fea8efdf88144400095563ce1e451b9d8cd074196a55157456517b710a9cdaa6619a3e44cb13583ec9fc4425aad59b3a30510af4a23260b4c54808cf87a608d5146fc1d9c7c03885ce24e03986228a65b411a91c493bbf468eb1172968de63f2c54bb6236519cb0cebb072615d8ce098c18dbeb03c114fc2f3f959829d76fe33f355ce630bcfb9ee0bd0806e723d0356230a867772b16e64e26f8035fbd3c8c2b08937d4149326bf94c49ecef2e550de6987099e91c69cb95d76f5e7b54c896c5f46ad8819bb6558148e61618dc14ec7ab7a197cc6090a2cd16a4aa8ea3f3aaa9191871e9b01ce6fb67332c6f4e92430d663c6d07274446f7f6b6c51b0f0149bdc822a5e41598f142412cd7d41ca2bcd614aef8c760ed1453fb9216ac2e3bec6255540d4f7304969052d45ea6ffbf8b869a4cde7ab422af845a0f4eacca4bb6a587103b6cd3c63abe6544e9ddb4a6df143c746602bbe779a3f6734da2441d38842a552cb2872b25b186afbb15801003d72638f534d0e15584d220bea96e21c272a4d8467753927cd8feb72f93650c6eb0c1792a8457ad1f9fb84fd0af4154f1c8517be2c9b758e7d9765ac82e16a80544088285244f5bdd0535de1ec80421313fd183c33f0c2c5b5c183aa8745e53b5ed3b218ce1ae44c35a594f4f43fe8dde58206194ff519498967780d96bf82ede6705cb44bb980044f80e914315ffdda8927e1df68b309db627786fd7d2852453c7c26d790cfc8939bda982b097de9c373266b252541c5b2bf68077990fd1e59ada4ba431fc71c94dd202a91b7ebb81f68c107646f0499f518c3b1ddeb10f0934d4d8b2e0818d224cf19d262db2b2b74e00746425d32bb90afaf36d69752f8cb0f2ffe2a2c04b6d133e5c6ce7f2e98023aaf5959f0b10f253e37ac6fd6e11d6a7288207bdbf5c4ca0d0a74801b22f811427d0a245cae47d7cce9c137e346f7d3b3b8ba0503d0a71eb0a165f393279b914ef6a79b723cbf13b79e4a0cbe5d99644d748c0719fcef0efff594c6e074d45ad6e8cb422db4e0ade446539973f421117bb1eb7cb8b4e8897a46871923a0f39f1090a543b82533f17355390262e0fa4d179b879294d1ce32a83e215c6c0e70b7cc0b142de00429d272613427634ef88244ceae8adf5f4de8ee1739a91173a97c0ad8bf24242e7b14f08040dd7c80b3b4f7d205d49945e182951806471c5500c3f242c27a5b36a757c87c40590c138bcfadd3eec4ac3725afa4ced9d1d30a7cd5bef0bc08996c0022a00f5be25b7554bd35e4dc67ff1d26c328fa9e921b95988847a1b84d7f3be2921237f7a5ee51c6f0d4e61af3a316f206c062667a3a5fa28b0e8d332f622f36eba28cdd60704a308ca336390ff0bbfd06ec89d8b8f8695b8465519af1050834bc60b0f28089c6fcce51d7fae3ffcb1f145c58731928826b108b34306353b3306f3097666d46bc84aee8dd03aa581c0f2bf76c1e4132bbffdd75aa79df01509ce8c44544325cad4cd8c01fd0b08d5522fa32f7f01143e0014906556bf809ba509cc2e35a827360c924d7ee888ad66c6716fecf923a8a45433632bb8d68c48033c4aacaf4ebb73f0cc6000d67201e0d56522144687c10bf24440e9a738203f96c735ff97380cab1f399a13100d71184e3f72be4d4084d969142771249f587dda1127719e4f029fd6cd8f9ce9c7e5d00a6cd7ebfea5708684461c40f2ca14e1d92302e3761384d07e06647b2c3b331d8ee8283f3f8ca71f87f3f7d5473fa93337b224e5aee8d9bb1a10212316a187e181658c4f61e9da0468a4b3634e80902fdfd9ec6de2040f5c8f299a2f7ebe997f0e2f6606e61d20afd5b997883ee8fe6d28b745e45c6e2834303a877cfa4e7a8d03ece6a679950fa5e56b538f8cd758ae8b023d8afcfdcfbf2a195c2c89369232003338ba82f3e3f49d97a37066b4d8db8a5ba32fa36f3a88d461ebc4e49473c5605e729e70737e4188fd39779c949621b35bff92c316e083c8fd2f22320f0517e26588178fe16ce181fbb068e5bf8515e3e00437e820c84a336a2387ba900d9f7abf888e8e1197829707ff8068ab0060da2a2d4430d07cb100bcfc547b52d0b72925dd33e9ef402dfec2817fc3a53c260421babccaea051f1716c82486bceb98759bd37fd134bc30602238ae109038005b19af9043e5bc6218d63818d4527a3e22ab6b030271b630223e097e08de88203f8e16b25318cb3da2da10c938a70366d4b45517191f2e88ed254673dea67848bc2ff873b78f57ad296831caf6dfcdfd875bcab36e81214899875941b2f7bf9d6d6330b910501e687a834efb70c3715d332c1779fc0520cf20fd311d9656b7e27e24cacccc201613b759522be981e3bebb21fa310e2fa4a884351b7a580364702d958376d8ca837348171bba8fc2e13c9069d84da8d63831a8c6017b2e636b562bdcd4d293f6c271f8595fff0c79889e349f2e4180c9599c6574e1551ad4ff81079c5aac7055a92dfb03fb0e362f33502db2ec8b5767449034eb63ebf72652298e0987c232d38bcab0b95fcc06c481f7c6c1593841736b840dcfa599a2994e012404d313da97810d858225d152f51db76fb3704b4356c3b15c5af8154231edc04f31f7867d989cbff3dcb02d56722a53053b2c7b34955a845e6fd74d2c051b99c932d5610cc9bb5a22cc40fcbfe0a9e46295ed6fc7422b4a843fb4555b2274df6ea90f73f754617e0d91512a7a94dc0d7492e4ebb2eb9bbabcd321952db99154c41913643c57a86500f1e994244946b626468d99a3aaa517d5339e681d71c1dfed6104a3073a4c8006dff672f519ae6a0192656eff591b7e2a8ba0c10845c34a8d8974ba08ddbe43ab31fe86be60214778a53e8b69f929e278653987b65f544db5a08f5334eab7e5be619dcb6bcf6b7539a0858f6d21c22f0d92dd890c67488dada2d868ab1d172261f4dc704ee70960b2dbea56103d0827332ef1581ecbf216180b3eb387cec4532ded0e541256c7800b4e1761e6b84485cb64abefe3e5e05937e3f28d42a6f8db1eaecc265a02dd06945be38d0bbf3d28cb2d2f3b38048587c91d8b4317e4e09216c23ba93047ebcaad31008eb9245ba39a4f3446c1e57dfb9f373a435dccb8535cebaaac4cc86f394bcc649af5bc74407543df598bb88383eb398c960d81f8b0e7866931032e3feb81be9971090ef05bc65b53ee46e5f37287df797b2e3621b9cd193d1f68638b780c67813bd7e83efbb15c873984bf7557efc02103d7db929b1b035c92ad51cd71724d295b97dc4c89e5c45c1fb94bec4ea67623aebc99c4d3af1f8cbdd6727d90409c5cad272246000c47b8f6cd92eef6071093547e17e95b8edb983ae65d000d3db99948376b575f6d03bc4a64f309434821b090a2dfefc6cde3df6ae97a3fb7063ff9f542d5220db09c92c49b45b23970c839f35e04a88ddec42bc5750755b3dbc4780a28c31f7d8f86c94c238f091ee94d98f77105e00d0084dfebc7c54c48db53170023623c999a34eca65cf34c34c23b9338791610a853fe1f6ec1efe516fc3f6ec1cf1bdc82fff671656622b4d7aed45f9af465c4e0a13fc7987ebeb1e133d5ae471af8e0601eb7d7a17a5c42180b8ec1d03e2200fcb7e395752a458900d0288ff183f779e4109bb7cf1c44babca6d802cbceaeaf1451f3e4f5a715f6e9f79f6472ab7c0ac1d1b78dd833ae7cf04db1a0599d199096bfbf432c51e81c98ba8a7f54f3c78b6b1dc04e8cea31a92e89434184623b17fba507d2d3681c21bedb977772d8d99e2606cdbb9521d319f9af920f3575b568791b92ad81aece5912e89da4eae04c4e57d9e4a89774a5c4aafae53f923d0260a921524748e43a6598db89a5950b008f541efe55e81ce5f29497002b6c87628000729a47067c8f13f5c5b56ce34197a53ac90f4e4ddf07c752f8196bc29f06ea19ed3e62d531e09418c957ec34dc586f24cbc050c0599b2ed391e84e6ce3ee06e25c2f6b86e64830330787e2d7a3a4580fd30fa3a7be8b3175a899937f32f17b9307645445ea302db19729d62bdad0007fefe6ba18d90dd1d39513c596d31905b8b93da631f669f892262f1c949f382ee6aed52ddd59a919e7470659e0ee896fcc9c191ae81bc1426bb8202af1138b0bcfe30d26f731dd0ada8f94df8ce501a2354e5397e7781f15a2ac68b47dfd848eb27f77d05d383001010cf7d22302c268f4ec4bb3dd90048515d656e7a0ddfa68344f57e214671cb06103c030d8eaea3ce51b3ae0c4fa6e2836ac04b49922bd14b6554db6454df0383ab299ffd829eb4073a5ee6cab03843dc491e88db118538f7a07121820527b909423c21c2431ca8ec4bd2d0b37d56d9c0f8065d1ded90f3ab19043711f641898ed3f261b861b01e80b13c5f4cf9c39e2b1aa47d96598a0f7802c9da208e9547b21dd0d80a970a218fdd1e7465403e377feda0f777c03bdc49e40c5d87b5ce6038e6c1e63966e0afdcbb421d539e784439172d4e0c6ecdcd240de1017bb91c4b34918109b6f3c3033f334902f8487432057578da466da361c5923ff76384fcd066eef48aa699491bbecede64c5860612cb3a9f578cecc49f007b8edf3635d507147074d06684e5fb658c5146ad188cc20c73557627142113b9afbec446a1ff76380e71cbcd637aac71e6ec214ac84b8e72e51009ac850aaed727a34d3ee713a4df49e8d51134c4154fb81bb25bdd1e9039ca9b1e606f8ee804540e3c6c82ce192f98d683792c97932f190e7a3d15a1fb62ba90242ed2601e968912c5a8e7727a5f3d57b9a27d6385706053e9ed2d89b04da1f914f773449ef657c3fd46d53d650ad9b63f63b59167557c753186b850a7dca431b0f7a531c6b3966412f068f95d7d0ebe1b045141785af02028ef557888f1f53e11a869796e66e224fa8c00723228ad398718aad5c6e5ad543e774613b51cec77a2c0461f5dd5943dacdecb5d08d0fd4d8b76d4420e29d861e563c5198da34f406a45c33a8e786a1ed921299805e2fd14c87efe9df489cbdca020a4495687a79f693c14494e206aac142f370278b66601240d24aaf05cfbacb44a2cecd980babf1c164c4a978b89dc2d3cd847e22cfa194d6c74811c331be6478d1cf176d5ceafb56e282639cab315418bb6531a1a0a544b4aff5c21a583e7c371d0bda431eb00927be6999e8edee83691eca86aac97283bec07442cc48a4d96b0cbe4f03ef4308022221eeee877a2e6a7b90e8d5632c6494812a887b3ac77ab2a1a5016e6ae060da6bfb2593ef77aa146cb59c4878d86b5a4393f322b03b79483683a32724f13c99c214a98e8e9f308701db62800df7acba61999bbc78f100d7096bdc189844f2e13cd1be641730ab5685515890a6ddf6c5ec7da01ae1d07c73789b8e1e896bd726d31cbc3b7b6bee590249a79bf55f6b919a06799c4ee60a49328529c0ddd07fbdbdbd80793c6235fb07436334d11101cf67fe54c5b1af1a5dc17a00b29402d396286d8395bce34f4805dca5a49713deca5526255a520d438df16c90b78badf6a8d051f342c2de508dbe2aacf8773f4ff1c20a303e5b37afbf7940c43ffe3ad0371e097e993ec6e519949b92138c10de0e258048105323bb188a2a3ff948ac5da778f3e459e0ebe70c42be5d52f07e0a8322173e6e84d02b468deed2c3f2fcb2620238b90c258ee0875a0008c00435c9e4ea6d57799c3bac4dd163d78ff8515f7b9143adf5ab2843108606de97ccdf3cc68ffc46247b6f16d9ec91416ed00bf3a69fdcf9b15407bbaaada981eddf94f712a18d3686c06ada8d628041c7d4eb3e93466a7361d18d7a6fea21480aaa5b5c6f6f374b8e42c45eb605666479a0091c5ead8c1b3633dc65ae67e6c1b22567ef6bffbe7a50dde4c87d106db4d073d96f990939a72f77cfaa18dbed1a9a514d2f99f136d7d2f71e0253f6f102a32d92d61fa10d8b3cb6566b06354227c94087237dab0528f8abec1af90b4603e1415fd50e5e2e8ec2f69bd17df0606140ca9e3e06004c8c7efae791ec7e75732e1b55f7b7dbc2a9ee584dd19bc68d68820526014d937fbceef8d937817f133febbebe03d92ffbe32931cafdf37e0bda34aaec7cc961661301e42de9760d2174d17e1b07aab90f33ffd031564a1d081ee606df80da811a969b46f2eff3b63691f80a595e7c22a166173e40581f31f9291c9cda93d3b13c5b3c1d006a3ffabc5f4b40a5d00448a170a78727a8c584ab0856f8500a50c486eefb1f03017a8060785e7c3d0821d142b7a962a60d6fab0835cc7ebfd49f82cd156b9ff275d5f65d665e6a57287c0c87c5a1ff1e5ab11480694a5d6583f53d2269c6f27321f9389db4b1275795d15e475bf5c81bcec2e600c27d5009ea07a1cf62ab784ce1d8e697c4a816c76d14ede9b68404ef697ea3807f91f9f28f9629438b594a9b48e50cd81923d34762dc206d19dccd62224ec6179b5e9476db6f521c8b0d9818b12cbf6d808e8270976458e782a178ae822bf4b05125f38f7cdeec44c328f7497c58f97d49a598819bf1eedc86e71e34c92340088828b9d978ae721e71cf30faf6255058b12db72b0f3fb4c378800573271fce2777e1dc5739c7142653abe4ae0ee916ad887919fdbba0fca2859e52aaef6c4d35dc3d1a43888a34149c79f688e15cab819be2f18031381f2b159a821148e0cbbe28b4b11a4b522b98a8595f7c70ffa305810f7a382c601a084d10f4c67ca9ffa2a51490f421e18de27299907d144750c03fbec141667d4573e23098cb21766e90145ed9ba51b4e7634bf74203e53dfcdf9019f5bad21188768850dbd153e011a8d0a3348373ac9c652415b6b673586fc34ef7a06d2095748dde4043a6ec6cc30a8688a44adb5fa7d01d3af8deea7027f64a7f1e5185f549257dec5413a1a7af83e80a00105e2b35c630f170f111a2d10ff9c0ef1787b7e3c2ef37823b4a26b58f368000009d67e828038beb1dd9f54294455058b909e84206423d75474cf911db2a118d72c04ff520a5d860a00449088111aace0984246e6f483aca0734d37a906dd0d1c76c406121ac5c1ea2adc7ebb31043e8ddb291698e81f12c60d1a5e96de0bd2f30268456f35e1b89025abcf42c391f7735121bdd5042bee59193ba428ba524afdcbdde69455f11e6bd765fbca828b16955b800d8b8037e3ccbadc960cfb1f36ce9723cb068a056baf62dcd7898eacc4dee2d1efec537b79408e4bf5c42398656da4d725f3b4fe36e6b3ecae3858176574305b3bb1c0b4558ded2ba78b0353fc13924b4a126e498c82df3e50bb6d54c8b18686ad90e9bd785645afca4977697f356595748185752d1d631cb79594ecc013cbcc96b9687926008b1fec4e6690932d654408b1730a390c835aa9f64912a326d5764dafcf76b5edfdffc9b6ca91626049ad8e5861e5e92fd1cf5524e1c66ae243dc8233c59858de6a7091118f6cd9d17ba3dd2de5c9b707eeccf089b3e0e1eeb0865e15586e774d0b9ed30a430b68706a29fc80c70f234cb2190770a968a23ace08602088a1162c8e24348043fe8695511a15312e52d76c475d87ec127ec4f17154e878821588371e886656ef2a83cef50b66b4c4981c32a879e7a4b9d04a9761ce53f798af68f0f5cc54409dd7da936ff226adf5556844c8ff1f434f09a31e10a34a396199c670364ae30e719f29716c8b0adb91fa0bbf8272a405aca99460205f01e6c89b3ec5886f1fb403628ac2a711fc86f6fd9e748e8ba29c1b581bf26f022a4fe2c9246a01ff94ea4d56a2d4d7ca2308ece96192402b43d8ed3b7aa0fc974e49c6905e17ab6be776671146aba8aafc6dfb35ad067c7e7457c93c275d31e78dd87dd9990121615146296075d8b5bf55784d498780cf9c096757ef445d62fe2e15890a6a665f36fd1386c84918c6e417f52a07797a01008838b3aa2c9c48590d1987beccc4a669c1eb0ca0e272a1ac53c52fc2565092ccb38d377c6d7baad01e3b019c6f5b797ac88c1b976bdcd1ccbe21c6a16ab08bd6cb02c50b9c6b6433d3b8abce66bf9887f992cfc106fe0a176e4b221414855c71c718165e6a51f1113f9beb2a09dfda7f05feaae3bc3c979673f1de585649f3953dac28b865b00aef36b0ac155d6bf8b8c37ee86c464a75ab7551b8f83c867ec429151a8f8268adfc12755680018f0b990e0821d9bb1bfd08ecc2f465ce3aa8f0e356148fe736053f132ab114c37f13db79ae8d761bf69a0f0522cb1ca7ebf9c10e40422b6d12f3805de7c40554779ea1d62926f4c860a2d999ebadb36bc851f1806b180cb957cf3e4102718782a829fe920d382ba4e3f603b11680e4ba82e187eb393f2793bc7d18b8d998b162b63eef6567cf32e333e3df5e825a6188fdbd7ab1da82551f0dfda9f574d4fa4f32a25eb5324d4d5d42215e07e5044d553c91f185ea4a7276764fe3c4fd245d00ddda565cf749a20229389e65e003c54efbd55de81db224eb916406d066b9f82072747767e3248df91873d42911b4527174edfedcdf5b24a621a43ae2f06f3db316f7ba9d321d2324b45b8279671492499217319690a509accf2de828d25fb2d932bef9318f5344db826398ff58f1a248728f3eef2429e4003fdae4f9c691736e261242f3de77062b1872e0ce3f748c4eac8be874093085987f363846cd99e348aaa8b190e024cb05c258b4bebf839e772e2a83c3e113c3ab8484f44e66ac3762b4cb9274fb80d4a4aec69627df79b313a84b39493be8ab12058e9b3ac39fa33586494eda340e9869a919dc3c5fe02d9ea54c04742efa6dfd8e96dcec1d30d75ea69e7b7b37a7cc37c8f1e9d4766be8579a09a713b9d121bf7d29bab707e0c2806ea798483084b17fee6c3cd327f483ba24bc9cef2b516b2036f2eeb7d633c1b9ee16b2b915a2683160c426b1b17af515be1a195a67ddc4d5149b1542fd7edd62f02025348f091d409b3870fcf50626b198e92be7ce18755099ae3b429231631dad024ad0c32b4dd38006954ea3e817436c68daf344cf88692d9788810eccaf67ecc860a207d172f25b64245344f60aeb604ab65820e6c8c5f53190d221265b23b4221af0d942dab0b53609bd7cb44fa9baaa4e25a27710c0c41b6c5913f425319b1e7acba3c9fab9a45e4f5a5ea894c21d9130f5f8333a809c177a54972a1e81347fa26dc28ece2cf0059783cdde0addd2b617986341db6b9ca1c330db8a1eea85cc4408d9e6ac9099c686f0e26502fe4cac3afb330c816b8547808e6d6c726880e1effcddc1e24c961573ff3be3a0f072822172970b533c03714dad7885287b260314cb8a99319c2a595b8a6a831bd4fa18a94be76dbb375e3e7b4dcbc0f0324bb19d1578c1021901d28c52b5b6891dd01610c4d807d44f48fed640ce9f4487df09f810b45befdb660a3dde25ccf4dfd53774575051b4fab0dcb95f53161dfb1ed1336defe35af78b6240ccc44afd46bafe390ffb0fdcb1698cb4167433fb433b5210a4d4ead02f1a13b677c13dd69d438d3b2a69cf98d555f9ccf7654eceef736e0e625b3442aae859177a09a7aec800a503955e55b9d8922dbc91966a946c24a7c8ada938096e41839cc71669cec204267635cb9b5eb26885357e601a040b2ba04ef4268ebb31638a6bf101cb403442366a596c541372bc5970e1afe72a4692a41c9be434b5ea3505ed0c393cd3a3d40f846583b811b3ff732eb1d1fddba5ea777ebafd9773ca1945fbc4c95bde6e59bc999d8a7380fd1bb07f90e3dae2288b28890a638260c12a647b68e3ca28fe5e84bc25f13dd07918c74f7071179141fab1231e26bcd8e4b9b1bb6f2753b00b7d80cb196b3a4ca1a92025c08c076f40829f99b86d90b74c3c5952b6d12aaf12509ab2b3b86a252b2284644c8bd9035d36855d0c4dbc453be38f27cc38fca8b0a61abcccda586d654cd502573ea5d5a15c67dc0e13abd2ed37f6c40905186d0686e908bccd8ac21e4e6a42a7d72141261d526a99d12d761a693af5d47a5583655a92e3784d64b3cc436b0de3c6a9f8bf30df4665b4d5454ff2684866393208851249334fc11dce5263e006d770fc2e5c0a90fe3602063375fbbfb596141cbd40c0710334753b1139a6201e05a62c5f94d8568700852961a6956e105678c1160f65afab02f1c80f3b94b7b260878d9f26eb0bf39bc6e2083ac49f51fb5cabb49e7e111f667fe7a3629b2778b784932373f411b62ef4635dfcdc003e4706413eaef5f73faf02cd21ea3574db5c456d5cac6004e7abc0d06ffa89c3e32e712c02c5d3a26b9e3e07b84b99a936dc82c8c1089ba7996af052a0f214e73dd6df3ee7a49dd90a55910d1b7dbedbba64c2d80813d1e7b2730de4d46786bd2122b2aa7e1f4cdd008b9bf1fee4c46bd881da6d048799e2726ddcdc772a158f9acb701ef9fe5b9ee699a26a8555280833fb2a7b730519f559cd89e23e82bc9d4c4258ed9c70f0a22e73099162f89a96b6903358f5563139a31d77657bad8e328b3bf601540b6b8ccf8719c9d99e91077fa95d29ef284d037a15011ce309430888175d4765014df89c6518f32ad85f102f646df376d0234272a7e8bc9c5579e8cb95b9a1a9645ef2abb4099205d50d3dac0c235c06af174e2a01a561d66767d1851da4213c914fddf16e7a1bca26dae153aad8416540d2f19705de15ac54c40188d7bd733e915a507f560db112bb1ea9bad2cb8818f10a469122c7f0546919328506ae1be4afc173fbdf7d82db13d0372bc991cf08a81c03111df3421a88381c05a21a16b33d6106ce879bd03accc41e14fbb6e575140b4c7349498c06de5920f07d66ebdd5736aa77807d158cb22cc9acf5d61d161cfce9d07f46781089c37cb7c5de8d6c118b950a8029c3cc102ab143835afd13b4f6664ac458a3d99275dc4f5ddaed9e6012d73e114d5d84f8fae8ef50a7fc8d412c61139104533d4928a1acb7f8c4084e3d98d6dc91be39ab82ccbdd53d2343d322fa764bb5cd56b0050fc22f5287f19dbcbafdb05a543c46f5fcfbc342bffeb9fa0992b01ff8c30786f5f3124e64d414517a7198ecf1c92794bf5672308a090547723f7ebf62a9b6e62006916b6fe59aa2ff6c6b4ba973095afe5df0cc31c9ce1eaf0f172c819764f3e1e2149baa168c5d9794461414d5cb1ce2c2c0cf8079d04476ea26bafb6c0cf73aa4d8be622eb085a031f2ad86e45a85091f9de7cd9d623289e46b7392e6275c528be87036036e8e7d880ea1a04aac30df90266e56fed5cdafb67b993701799fa00ed18a8ae002ef4e8907b903bc44c74b913c70235b307fc035423de63bef6779b237ab22da57ad063d80610fd0f20ae69c0f1b4e8c619d85c01ed39afe388d859da1bf0160fe863d544dcdcb7ceac619200bd9836deb4b2a27a1e202b56720bfe881dcbec096ca1b5b2c85851134ccef51471c5fada903173c20990d9cc10ff5c8e83a0ce08ad0c9d0ba9f4dee063221152adb2941f2b63123c9edf1d860a09df4c80779fbff949ca1e8fc1032a7fca107ce59fd7b209c6dda334628e3cc535bafdbf3c1fc84ddaa5fafb8800aceae416ea3ebf080482f35a478666734cb07ca9e00681784f85affd07224674fa26d291fd8a1bfd41cc165636aae1770b9709458a0117b2f5b5b2ef2a19d801d46a8fbf5e35b3535c75885d54b68cdb8b023c8614ba08cf5e812c72b901c0fd230059b7e22e407d74b9f29b01a09d0cc09b06683bc0103c84c4a86a488750d487e673fd569868ec575a748ab0fdf7b93f3d9111d303ff34ecdd0dd48c962d56fc6dd94af21fc56a8ac4317f09ed4a14c0feccbbbf09f8bff312208d8f84d7bae1f44ea4cada8faeffa27befca17105e7ed30ac46dd9f8619cb4c22845f729ecff0f603bc70f2c65d32b4c98d9154d2a11a00bc01df0c7090748e2e4951ce03f58c661c5b92b95bcd13cedb69f5ffd84abd9f72338ac0da677be9b801cee8cbc3bfb05f0ef0a24294062a59aa90ffeca768af31b73a6cd3e4210689d714222acbf4566a01ae03f9501d4504423a46a4cc5b2fa3749d3d2757307d45e08c4d803fac9ea8e5820da59a503d58d23d2cc8d3208e47738e08f35e329cf511e6b5e8d43cf2332a9839f684e4821ea3f646e0d431c3e00703000439b243dbdb756b41770b0987a7688ffbed0914b210319201d1a5949c8de7b6fb9b794322519ec086808a908b3f4052b453bbb065383a23981d63b540de763ae7da191ae02c09cfd4612c9b02fab14a3184fc7667d6e328527887836288ec898b1ccf3119f5e29a794f2f29060cbc2115a1778b0708476a5e9e4a9c287c74e3aad1c25e141b219a16539820532e0f1c1114daa2001cfb6e4080d0c9e2488a00b7153128fb8e198639c33c61899a1e0628c31c628654f39e5945386a7e6c110f0e3053ec68e3176ec18638c5ec418638c912ff37031c61863646e792347e1b8cf021c23f9e81c77cd5d923c24bbccb7ac9991729774c419950dbc1e383cf3903746238cbb249d877c796be20cbb8e0679ce928a077d67243f45a0e3a5a88a2df884430bcf93266ce71cd6b5a739fd4e2e2f17ebe2625d3c7771f18eba8bcbf86c94a142350dd278b4ccf989e3ae8fee3b79f46e1a6c1dc2f88af1f1e7088971aacf79e5fce49c9f381932fc85c89225329ce3eee56547e98b6fb21f91929b6a57faa6c9adb34f97968f33994c764e51da9cb39fe92b62dd887c1c7b8964b6d4994c44c8df7cc60f6d249a150b20ede6cc64cce9651603d39887c3692e9d9b1e8ea473e254ac3d03a9a4b2194c41e94207938f742db9c05e3e1e73665925cdd78459e55753e3f2041527a8af1fd48a612048515516912d7b3266511fa911facd92dae8d9dd440c8ceb0b29c8d7344261fce4d8cbe58647d843c9f3d2e7c5438944122d1e4a2443c422607aca73d8516278287764b07c710df21bd66ae386d5aa56162656f94e7d2b4ff9fd904851840867791857d57019245bf255e383711a1ff60228c2c2f88baf56156605733f9a5a25912fa09f5f23d6104a1f154ccfec54f261563736a8fae2f7afbe2432891ca144e253fc35aeea2302829d87b94beee5b294abbe94d3a0f165ff7d3ecf9f3ab98c2fc6c95f1c85ba27c73c1e8efc09757ab991b55afbd23c8c55e44b3e9142323eec0b827df1cd4ffd23e37bb1e2f292f1b5708f8ccfc623199fe9bf20d89046c657fa2f08afaafad1fdc9eb8718f893f731764e97621e8e8bf419c62b8434613cea79b1951fa20fe5ab8bf2a194ccd2a994413ffa064c4e205f2d2f3872fee877c427223dd6260f273fe1d94bec1e7bc7ec9c009e7d63bf1165d85b6dba33ceb0df7456fac29aa7f92f447df5ad9f91a8748e485a95253898269e48d0801f16369c4f5b867a4f156cb5c6bbf9e6739bdb746a641a99dfdd4f30cd002427c7437620ce695d7b9e77936681aed36280ebd0006506d7b1a1a85901306a96cc51025c0788eb28c075a6ebcca28ee279f0b099bc4ebb3ac9ebe8b49229ddea22aef23a7ce57518cbeb741247f13acce475b8c9eb78ec27cfe96c3a3ace48ba255d2b1d5ee27558c9ebf804ba25533af1caeb442cafa3334347c775e8964cd2d1a1e331dd9a3e3a56c7a4a3a3e3b3a85d3508701c3f9c8703b80c3b780c3efc460f1e387e87b80ce0da8d6fefdc0eef72701b3ab803c03f1c1c86005ea300bebac153364e6300aee2229f59e3a8164b87005c6aa0f11c6eeac117d0c39d3f0df6d78303f916e0d15bc037952cc07b78356b88b773433efee96a16106f9f43beb8808f081b8f8123f57bf0fa3d5cd58f1e7c01de832fe01ae11e6ec83d7ef8c17df8e2e7fcc01e4ece5df28387fc413ce78b712688fbf08547de078f1e8e0f7ed34484e4e4f8f0c5ffe18b3b847cf183e47c4484788c33391ebd20395f904ffaf0c91f3e29e46b2c0dc6da12c4739c7d7a0faef385421c734ab9203348909c20df9ce2a337857c4370395f909caf484e4e8e0bc9b942b0d717a200bfe99c8f9d931e0e900be4e3204e84fc2037e44b247b05b8904b847c05d01e68901b1ef920ceec395f189d7cce0f1e0ea0011ed6e0000f651ee0e107010f5311f0b0e5a7879a043ce49f392ee312f838cab003f1c52813812f4619087c0ff8d81d20f3ec0df861003c721c88dfc8205f023c0747c639990f8873dcc9cc04387f464f81dc21a2934fc091108af80478f470124027026e589f871bda1fa803ec70c37d74510f1ed771ee10d9ea240078943ae4b0e3febd31c00d6ba4ab003e04f0c1e1b2eb866be31ac0953537acad1b5ad69d3e3302b8a1d57143d4db10e5a907e0a3de3eb2355db348b63849cab4d770696e8e0b8019c671c34ac3278022ec0cdc0c3ec3a52f439d63c087e4073fc277fc70a560d0b9ccc30125085222fb0981ba287519da1543bba8df7015c9164f89e9a2481d862e8ad4ef2da2feb5df48ddc60d51d43bea9c9174c916238932d4a9af5cd46bb8943c7518976c4d20ca24d9d221ca50c7f2d45545d469145589a8a419322952977193a68f4bb66694394d9f97e9e3e2d372a74b7ac9338f475692204d4df7e1a4dc475188e0e5a4410be8951598a6d620a09708b65324de431ad21e1d5fb09427822f914543044b1e0aa421b26264072a51ae4ec734ea73081ac42c9dd2200e829320d04c1f220c03bf226c514a49697c45a2ae0b1db0a0ca24474720f839fa16aa44cf45cf2e54d0333bf541f5d86a45e322149115da6a5031c6183967d97d32be8e8e303e7a49c5099e7819a91370cc68e28a0de473962c59b2c0a0c41cb7d0e8a86996e7ece273f20d4ddef98c4fc60b8e2d796ec22995e62c793e9f4acce32179644e6fe4a4ccb2a913cfe5ac61f7d64326c27a9fe6f593ef79c939cdc329d512b7e679e92b62ea36cfb3a68efb4d16e99c080876be8811fb1e8e7679e83e2dc619ae1e4e268738f1e9bb0b2c283e318d80085178011684056d80080bc282544cb0202c887f8880b020c98caa162599a5947d8511cc94254b1698182a4ef084e49e341f038a2540f13c27b30b58ba6c16c2e7f6fafe3e0c06c9d2c9587b38937fc42810e108b9bdbc4033af956bbbfc86e8be3d7a3c44f70dc5778c5eb7115a1b07e331180fdc4773c331c618976c38e8f0f968502ed99cd2d9517a6b4a60431be33b96dea03b5aa963dcbdd8b50d86da576fc49c5e1a3a92329f3ee263172322e5111ddf7fe002210fcc177410a822d44d7c01212187c6054843d0500184bf80e7c3ee9b8a21809639ea31b4c5a9caf3173fb2a3f3285b277f71294aee01955755de5505b1fee23e587fb91f90e2032f6edd07970f9c62dc233bba17b73ee474ad94e922424efe723d70baadca3199543ef08e16e71d2d1e77bc78683bf71c1577986a831d8f79f298065b3e6b4d9ff685309f61eef5c4018d07438634c8ce116d44af7d61c4c251c11d3d3b0d1f3ce4000d712226f9768a4464f18fec8b75d3d97788d97ee45bb543fb918f1e0f39bdb1ef3e4e8848898d699048163dfb10d9e28ea40c378ba322b2139183f2eccc2131bfbc9c900c13d8f6107bd59867c9845dfd6685c732f36dcecae6b3937d2e37a94954ada15a168b86c49976cc4310acd5ce595353c343e24c0c38b0d2e38e11e6ec39b1efb5782d8d246cb684e5399d9bb3622ebb99c0c5189ada20a845086638a48723c39a9b18d8e9e9c022b66d45429acd8861529a24365dca7989c88b83f4c1831004c0a1e646d64829312a65110cc3b08ca5ccb2eb9f3d350883a39ed8c3b9c1031bd6f4a959b2b31255efe9da0675342b8479a20a06e6959b5dacd5f9bb946b7f67d90dfb8a8c4cc298c7e66caf7443ec0a524a29598b4f9ecbb42cab9f47b0a22a26817020dd350de2fafa6c4ea22554f97845143c8ffa78450dac3c877549963f936e6f6457314cabdcf479d96fa47482469a2c867da59b851abf18f9350df45cd3bc4e4a89554a51b0c55002cb4bc4bf809431b2c33b4949373538344bfad15151111191942d5bb66c59eb0e93524a6f104334382f8d8e06d97f4c6069567d461be9f54e41d28f694691b0196da8532e5e52a4973dcc1d51ca481e54e2d144cdd9712e35f0f286754af74d2ecbfc374ed3ba6f729db4c26645ab7102483942b0287c7414ce33e6c9b62c337a7ae3450f1d543b78b65d8d47fb3424118b22ec278f45d12ccc5a14ca1d13ea568e949895cf91ad7aa5b1181969485aa331b120189f8d05f580e7467accd3ddeeacf55423300fefa878c8cfbac83b8ca432136e525df3e3260d528ed2511ae4cb4ca28836fd3d4bd853f5d01a19211d191d7190110caa5e157bc83d288e22ceb4d7f00e23c19cca4863ec248f4f3ef56963890d1d300166198f3eca127ba059e1118caf031a14126dfabb41182fac2c55c1867cf43e366260419c2147cde206bdb0f2aa3c2171a65de899ad743ee03cbb4cb043d07ce630adce9e6a9605cb79f6855ce4a657e764cd6ac66dded9e6bdd5e7b6af0234e1e615a099be7d15a0096b7d3ae5d6f2089cc9bd6e6a1a4776adb23705ebec9ce90b4dd154f24c1e3dcfe4cd909d8826a25f08ad8b1ed7d9130ac6634a3c8bd0b9f655544b7943ed0a534a9965db067ec76d58456d1703a78dcf805027ba7b8a860041c38718912e2fa7407ad83cf206314427e17100d11007c8d82c229ce5c3138f16409c698faf62150fbeb5c12457820d2b0d59448315b639dfbc9b56df343ff298d76ddb36c77cdb5cfae6db17b9f6a847e6b68dd3368d931d6b1eaaa4c7c79c1deb3a6e6e1e55ed20fdce29deacaee3648742a1b480d134f6a8ddd9a0d49c72d56e9839f3c5b6af61109e4b0fa72439f6887096dfbc7e4210e12c4f44fdea4114e99ddf2e917a39d6f1d508311367da8360be447080d5b9566d4e518b689ae69b7685c8bcfe569d08b95d22e4638e82e1381b6180d90c2c2a1144b2e70cc8e71b6a4e247b26423ef70ca7b363db86615fa43f030b8bddd9bdb22d7e6cfdaad7b9945e8378997131254f29354dca1b5fbfcd2cf32a65cbe45966fa4e51a67ae9ab0e8875d6fac3f4591de23167b0661806645e21c93c626a7144c334d89ce4081a8e87061b88065b4a9a1e38be80c0f80bab6cd5faaaaffaa2d1612bca3a0af4394f35082436ac60373737d71f8c05db96d92cbbb5634dd3b4b885f53594f4aed65a6b2a865f0d2f3b26862536f31b8cd2a22320983caf66cc7c3dcf6f9aab37ac2e1c766b8648992eb10744880ac857fd60cf3cbb324dd8ce659ab02123dd3881e52b48482f247e1935d85ca5c1b6820aa309d2b39fbc35a0d5ce7c489129e42b45f8b7ad7ddb980aaa8bb060fc17efc5b0c4462b5135bb606cb0cad6acb0eff14acd23df9079dd82e5df3e22ec17d1dc88fdc83942670da641f64dd3aec43e7a3ceecbe61b88b05f84dd88e51bd8b3cf39876caeddcac04a1e4cc0a6672ebf6cd6ce9e347031cdab67f2b30cfb2cfbcc43982ccbbe5e21b82fc440d5b4b05df7a97e749e771e1f094c64d779a7b9d61e4e473d1ceade37bdfb24b779f4b44de3e87daa1fec9a6b57084df54362af7dec51d7ac14b02fe37a1e9920a81fe83c603b70e2c0cb70032f3d84a1189093084fdee8770c61ca37c75ca59442ad7ccf2b563e7e1a9d442304de166c48abd02acd8ab7062c2c7badf3a5735256cc6586b94480eac7a456489039e6ee730616a17415f5234f6d8441937d34fb28cf9f5f7fb77bf51830cb7a5ed58f9f5735fdc8d38461f91621a28117c288acd90d896433b0b02c1b055c1c80edd8025b3947fbfc36ced12e23091bc6a250ba8f2a580d08f1e0c239daca48c2d66a2dc6629772eed0e01cedcd7ee4f986dc021bfa77a338477b12a8ee6e77fbdcec22174b5a4ceafc555ae2f764d7f1e07c5679a57420d14a1e70dc5d66e666173bdf261099dd70469f5be4da6298662b9739f6f1cdbe4e7ec1ab8732f222cc45f8ab11fa582ac61aa2ccc7990b22d13727bfd0c84f0f703e6f58ab58ee68c3da7537b2987ffd84903e437e99b536cf3cf3ae5b9c67dc17c3d78d2c76bfaec1da8de57ef5187e6c8db3f4d0b93aca0a28989b4d73e941b0732824edf687dcf3e3ea81618addd0fd86f2fc8d7ca1f886569f8065da5b509b6028be7d720ebe917a3847ff58e9b15f190b6abcb1b6c56587a9e401f1a61b6e6e830babaa7ee46b8feea633ccde48a1cf3ea42ccbb41d5af4b28a6518a6c2fcc807215be8b548437410b27583c4af20b5c42a5b3c4b8293387b685cf942c1f2336f5edd1bb32f7bd33c34775bde1d6905d14fe7da5508689f57955d8e986a76c106fdf49f9f1e1ef9a6e2f5f179cc2246aac7384344e6edd2434023203c72e38c8a1d731c155f22d95722d97740543fc06f965ae8ae6b87d5a9f10daa1d5c66c9f292db0bb604d3a1b653b558372b77e41c59f3c490e0d89c59d716d5d9aa6955b5c3129510af1d17980f01a259f231cf91647d441b97c79c871cd9c2d1329863e08a091bd63c56834367d9678e6a168ecf9ca6665a8936353efbacfa6810335981020a0a965d06e162ecfc748eb1182936f98b6a92fc740a466cd12248892d948d8c283c45f849a93c8d82508c51b628400a4a787adfd434d825c6a1f9e6d66a2d9d124a4ab169d4e09c39a2e09a9b1b0f6f1a9c5e5353235bbc23368bb358ead428dae0054b3dac5952fdd6cc5963438f0d6b242dea61bfc8fc9016fdfcaab0edf416d999dd65819b1e63c2d58b088f1a8f09bdb4616dee1211f93403ab37b27aea3f5d36bf986576c71ad11234b79f3ef587b9ddb146643d5de3e7ad81d413eb15dd89331d54e351477146daf0856d42ca155dfef0587dbc25a238237d7efcece1dc2c6c0f5fb9a2cd74e9ab2922cb04c432d560d5e46b20459bcc615cd1a67a4b50caf5692620530da613a9844679be06151cbc84996207c6156764ca15f432bb3590e28c741b7e6cd0cbecbe2add7e5e3a37397689fa4d67b7fe4c356950a65e2917162c7b9872ad5e1a17b86b64ab9c13667e21cc1751cd3d9d30b19c52ca29a594936edbb66d524a29a59432ab5c6bcdb22aa59c524a29a59c52ca29a594534aa9691bd7759e572a994c16b3d6526bb7ad6a5d27a594f1155a186c606383f3969a4b9dc9eb6cad3162944adeb9984ca89a1baf539f4c2dd6a5e5e5e4e2f2f2723ac5882163c68c548ac6cbcbe91423860c193366a0502924cb37b4919999999999999999999999f9aa54303012060606e6240305822026ba0213dd78c590524e29a59c56c6a965cc191e0e4aa582e9a2468d155dad5673b592bd5af16ab55aa55234542a18981a35562b1b36dcbf8f860a86615452ca29a59493e33e2ad8be3ff86b4829a794529e561e0e1796af0dff2e0c9c755c9052761d6f80080bd202c652daeef47961fbb2bd46b166580c2b19ab192b546ab55aad563462ac56abd5aa5986920e214cd63230270c001fbdf37030c99894fcd8bcddcc47ff9c605959d7f50c1ffdabc2865d8d3e93c81c33b0ecdd737277cb898532edf9d5bfbee608b2eccd51ce2c37a8dca07283ca0d2a37a8dca07283ca0d2a37a8dca07283ca0d2a351c7db55fdcd14636a441e03db29a735146ee59aa95b9a5accec59e9327c7f94df764f639e7dc9e0c0142e1275428dc84befa06e56b6f4f1ac318db5e0d5669b3da1ad6f5a7626f51f15d42ddba8b7398cb7779a44c75ecbb3d52a6c61d160a76fad5c252ebd52f916cb578f55b245bd4abdf23d9c27c7ef53b45b4e97c106d34a7dfe569015477e9f9ead8f5f9ea7d77a4d89daf3e47b0e18d9e0f980fd4edbdae6ef9ee4bca54ef8a6ca8f22955b14df4614a887a3cc04f09355861786c98f249f9a47ea24de7d5533188369a574f01a57c6ccaf5291f276c37e7d52f4f9794a9d795c30b7b85640b0649ca54975ffdbe6090eed15718a45bf4f50996739626291134199990f0a4988ae24c957e5dd7c4e315c5996b64c3ad88475503125fbd069e68331d47514b8de7da36417aa8f2994171464a0f4d47decdc2d29d94129175771aacac6b4404ab87a925be7a4a68aa7c4cbe7da5bbd338b8466c4cb428541c94b6a018a87cf53025f437a6f8eaa1cae7862bceb4c97dab415fddf4853448de97f7d56f9366957cc22035abe4d7755159b0e1f6e175511c3bd1a6c6d71a5f7ac286d7354d53a287735aa2c17af269b0faa9a7c17a9d60c353cfc9e7d4235bbca3fafc4c470d56e7cf84d4a0e9e84dd07c4317f1752bb2c257f7b2930c44f56661397a3d523d71a64a71f2d551af6863f22a69f0d5c3194a7cf5193dd1463a47bbe9f558fdbcd5390d86af2158f4d53757add66e2ed4ab7aaaa74e1c7c78eaf9ea3206a43853dd861f8bd4a3c69b6ed157975ff559fabcefab735a9723c9ca20e430485fbd08ff75459bfe0a7385af4478f06fd7e34c751e389ebb4baccf5a6f93d415f6beee7535585d730f0bb63dbcaeaf1e63ea15a286a315155c8c0963c850c2dcb46f4799a03fbd4ab3306a2562f9b9332952124cc94fc790882dba844825b6402983146db89f537c7ed22528f1132b020cfa45516ca1b80fe9127e9e1a9c3c3438316f55fd90bf43bd2c7673fafa68705699b64a0e27aa1f1b52a756ac5869109c2145a23b718679c7746ae5c443b3a6db00045b647e88922d1f2145fae93aaed8902251a46675156aa55949d5a7532ccdca7c3ab6d32c9e66519f588f9266613fd813cd6a9f8e45d12c55378b60b79dde7a8ad1539ba0a03091846699364cd3b4397976a7780a5db638cf328e6298e79dfbe05d1fb84b43edd47a6231a30d4bbf6949e34cbc553ebaf671a88aa31fc2c6a12a88fee350154ebca12aa4a8b28661bbf90b398cb3145b09b7013b63948f5af838e48413f4e468c21076708037ca1749f8ae82434456868852f01c77ddd4070f509e653cf3511c1a8ae24347d23f5b7cd63374e577b4d3299da659d1083cf8067e761ccd9246cfae03df205d070b3ec421c5c412d960caf73d31d1ed71088a0d629aa5ea1be36198b021aae70a17352ec65894736c551cf16b8880c6886597f27962d89c92cb32c7bef8cc4b66b21dfc11911ee3ccac12063952867d48b3721ae41ffc40a826f0fded3d8434c8b3e7c7e0850de311941c211c8317164a100d6494f444a90c54ea26f5a1288661ecd2624b5ec76d5a8d1813593299aa093485356f9a6e3259d962264d13462bb2b3d5a2dc411a1ada1c94aa42dad6924cb1d6a90516e7d72c8be09d532408aac08635341d73bc31f304bbb0431ac421e52bacf91a59e3f46f831fa5c49e5d05b66b4f7777ff708cf970b15926cee74be6d133dac4af75db9c9ddbeae4e6dc6657b5ba75edc9d5fb2362d6ce9e369e3f5c1c806547a5c006c1b0393195f4232f6fc80f848e1e78477c551d4f29a5d479363798028b84dd31813a08d5e040035eb18c43e8a3c7a3a6d60ae2f8f913aa6b90c08615359fb0cdca32ac72b37628cf47837d136b8742a150d8ad19977d45707ac4bfc1e14e1ce617382bcfde9ec33f413aa0c0531a21078ebe6f163664250d6a40c543c9100ff4a01bb36b21f613549d9d75c03f54f340834302b7bb572c0c914a8ce7cd82e52eba99941dcf8d1b9d754951bad1d1d9adacf370b848b6ba242dd361c7931dc9d0511a7bf4cbdbf13831c337e63482514457e18c5a5e7a799e42f1ede10c4fc1686f20d9ca80a44c7bb5a83003faf606ca8abac84e41a1302141c130f19488aebc82b06bbb1a9f01c956694a5015d795522664ca883a9eaca8d4f168dbc6b1a5876b1de8ce53e7e88a4ec38a2922c380b977d09d162ebc401af2e2c85ab1a88f435e0865f12207368b172f80822d7d1cf2a2c7a5898d11c60b126c6a8b5311eca90a172a76460f5ca4b0319a7092022e5081a7050b3be38b29ac6582152e46d8978f43549ab434c1da8f4354a278c2d68f43549e38a9c07a1f87a8acc06504544410830995225a9ab0dac721a424242b521869e7055c8c094f3fdf1e637c4286f4e78957422953ca93ba83289f4fdbdb81775cd4f6837d5ed8902ae901c377f6c8d6e6431bf5d3db8fe4d8a51004cf3dbd1e359e9aa09f6f8c3392d927da60de252abebd24146da89bbe60c1b75a7ea4e7136de46c115ae295c4e52109c2f2dd02d45d6921ea9d4fa88a0ba8c6b7fcc8564769997623a0294155aebc5ee8e7ed68533d7ac71b3496327336b2d431af470d9f92509ca1eefd90458cd4ef3883b926330601c7dd25e6cd87878da73e630a3473fac553ea3328da48a72d444fa977946e997e76a20d911096d7155715ea26a0a774f399e28b6f24be3d6c21e28933edd82774c505a4b9b21a6ffa91adcc688a09a88a29e88ac985c5f4aa484c423c311ebbd94a09cb1ed24f7ea059468e33537294a79f13144c68beecc0d28f435388de5fae98e26489293e9805b8c14b8c7b020b28b6ce5396b8420a46358f79a9c61552f8f13c1cacc62eb408810b98c8a2840a7e3226be4882ed64d8028c9fce61188669e00a12a88024084646c8206b411694f0188e0843146220250a5dd882093f7df370260d26dc38fa313ac282d15802141e7382d130828213383ce65914c2bc5842e9bb222da23c01cb4fd3132c62f1081fc23ce631083430b7458f3d61076f8a6243eb34782cc663180a75c5886ec76cd6351ac157263c2baaf55aa38c8c6699141688e0850aa218525e90c4c5083f272924688152f42285090aec932217294748624242508b142590a0f464c74a7942128f8a2493142a4a744525295d3001d7e365c193c47642550154455067b340010934a1242e0b1794a0e630e4dab280a204590e46d0b2e88109b01c8ee0aa5914410439100108093e395491b4c5097280b27385278722f00c65812589263924e1c990134690c4939f1c84802c6a0a495d64f9d0fa0a49f7d1823a62c066611e62d46aa10b242cac8d8f435d50d1a204eb1f87baa0811576f571a88b244e4dd8d4c7212eb0f0d2635b3e0e71110597cd3e0e7191454b09ec8c8f435c10c1250c6bfa38c4051330ecfc38c44510c8059094893f87a64879978f43435bfcfc383465094fd3022f4dc1863434a52d6c91f91d4ecb10c7c7cfb1b7432de2611a94492cff08a2c1269a828b31e125fae925e762d5762247980f3b6ef1687764abe5b600d5fec8f3b3e5e3a582ddb8ee44245ba61e7982d22ce9af183bae2453901514923d329d8a505344d6468208a25cd1266e2568f2339c41e5a7cf403ab22f34882dbb135f80a24d8c9f76043fdd88d8320925f1d3811a9c517c55d8d02454f2e92628cd32f9e4d126212933dd411abb63bf979fef45c98bcfcb122f3d2f495e788464cb85c8a5c8e5c805c98abb243df8b2f3d3d924f473ba40e969708906a794d2e463ea6970baa9c7d4235bb14353cfcf17a09f2f40cd9a3ffd258a66c52129497efa4b50b3bc9ffe52f432a55b1cd4f3c2a45971a8080bd04f0f5f9e08fd642548f9f085e8e78bd1cf170ad4acd02414d4acd0da1d9350b3a6b744d12c39859f411fb630f9393ddce6d1bf00fdf60ab7d777b4b1058df0e506370b1b879480f4357ee72f91d7768a182949604e948f606a666666250d36fd69b0a9e9b9ee981ad1a34b8b4edf4e8de8916cd1262e2a44a1a89eab945912a5cc08ac8db12351c0c5983075f4ed5c9c3489cf8ff634d8b29b1c6dca914e9a95a8e9b9597ac2869b4fea492a4aaaa841b05345cd8aa9574aa8c1a61ea65edf45fac3cd876f30c1b74f1ed9a29bcff69323c902bd7cfba664fb912dda14a8c14e117da78852518ab0a1f173f391410a1bbd99fda6a4c1ed67f339b2edf2c32d65032ec6843658f98c062cec26bb6b64db654bd9b17331521a9d8b71869d9f9d166d5aa3010b5b791a8c49d260e63c3d3024c180a5c1cc638c31d280859d3142315424815f7c46e5b39828842d1fc608c55cf199a7aca84db050404dc1aff0598a0b9ff98c19d8167771f94499ccabb57c5db215c3e3aecfc0a46853dd940473848d0d720c4f8ccfc71059e6e16956928c5af199c7564aa8e5a987db934d28dc889ed29e5412620b06189294f099570f879e4ea7d3c9c5c52485063d3b058aad139094c9fc449588ac938bba247d5121d93a39fbb66da6a28f36a6d872716a9db918dfe9b35d47031636a3010b8b752f1fefe06294507a637e3ac61743748a29ca8911923299a3aeb0618c4f8c8f928c8968f4bc4961df9af8cc431924de43199ee75006299e8732143d773f529e69043d0b4919a01fc4259e5d349478761baf68e3bd0da1670f6d40d13c8c2912a2e17aa6f17aa6d1f31cd2f0790e69fc8c200612cfbebda2cdf6ec3176a2cd4b0c9e672b3ef3d88a118a32314988b1c118257c0643d2b6f32921d98a118a71356b9514f383c85a8541533142b275025a2535ebe4ea55189175fa410433530fbde3e5da000418923e73976f552465b213906cad90a48cab59ab2be2e90727a0a72348d92f251467b237dd15519cc9dc8629ec2a29da9c3e731b3bd1667ee63000451b199fb90c51b4317906942483f4314c2489f16930f350e68a50a6e8b3166e95e4d348c43091510f6decb498e855fda04e839e3a024a4b5adc48fd252e3f9fc5a3efee4dbb7c3c750712294a9d6b1e4ecb9782d232996f1e0e5f2e25e4e1a4a0349839b1a10b3145cd12821243141325f3939368133f9ba5cda759262622cbd4c4f6c587ddcf67ce715f6732492999062cece66974e3ed6a1fe7b4477b451bce33df9488aceec7b79e68d379e74404330f2912da13ca226a4fb4d13c3c39f98cf67ce69cf66ddefd348b16113b27907c7b5644527872b281607ce6a129e93319a8f8ccc355d267ae7d3208c59922fc27273142dc0593e24c961212caf29a17e19450b461cfb83bb54ffb2cab91146732c7a1c466ec618cd0676e83159782c9ca63abce7b4e76d957faceb3cf3688991efc25618df5215b2d3da2c6a8f4ed9495450b5591000000005314002028140c884402915838249635517d14000c89a2486c589f4ac3208829658c318000000000080080c8cc0c012001573354200a96e330070e3e4e609e1debf746848aad11d53085029a9606485cf099bea0eba609fb91637a0ea70b5bef55d5c3c8f49a83e0172d3997e222e8b418470c393836269d31ad974f01315e3d5ebba8e2c22b13bfa914f062208a692ff142731a56b03f597cb42f1c8bb3438c58d335d7c18e073689b641c6bb309323f092b83b57a9f12b38465c65d8d6084e2cc910c9fbc3877459814afc0faf6264fd99867d23d5e4978d6562ab50266ed4929bfe872afcc1c3d42510ebf39f79f8bda03fdeeb476501e8cf18ac6b31a21c7478ea8cb76975533810551ea71f404d648afb0a565e409282ee5b0aada09fabd0a2e4bc44427faa9affa867470deec993a99ac1011caa5d71072ab0f7cbc6ceb74bb9995f65b13332fc13e0e5959671488300ce489ec1477eec56754098eb86d5e1ad08e0d2df9ab2ff07e00fc053807f2b23f02f74207e80a050dd7503e746ed6bc9dacbcedae4422afce1b89f41e82b595669afaeff25da15a93f8877362ffb4a81a7a8a27737b9e40f9ed7e38a14813ee38a3b6f5d03c8b32e637984b5673dc3508b3758bc259eaf4f5b8c26669060231ea18650581b673316e4147ccdd16c70165722077e0ac326c74b527c563614dc069ac15ae10abc2380d10bd9ee73f3d1d46b7651b1e4868738a343b6f47a8a559767af3216dbe308fbd7bf1542e00884c1a9258e6e1d7469c5ecc107725ca49e04abbf37f330a98e2ad01f77c0b414c5f1a651f4f4559b3330a678e2c20752da9cb95fedc3840c706a67c22d29faf136320054ff56090480e4b3c17abb7d0999b8a9df5b867c50df2af56ebba7f6bb1793aedf53ca71d372613b7d494f6626227595fcf3c9843a3fe19c10d6f1c249c788b51098862f33abc01d87597fd049d3d16bfc8fc69fb819f484bc7562524806e0939f72970b941900356fe74ccce5f39366db5d8b9a13f79a0474952cba7d2e4c57b1c315aae8368ba2e04f270d383b65174a2155b283793cc1aae0430aea83bf3321b2bf1855772593e76a1bbad4b25ce0c4b64146a64657c46fd8d27c7b25549c549c8910e065d078e7c6664cad75c8667b8a737f921d51aaa4baa834f7df5f48a52e4b1e149a5e091f1e77e7cf4ab13aaaa462f1cd3f5757ed6ccbc6ac20d05e224f537ce1b5f3ea38b1da442e983562e862926189d0cbcab2dde692388fd66b457bcd6d33ebde1bbde7fa7eaeef0fb4af7e63cd84a71e7d80426cf53485244d58aff448f7db44cb4b7b2d2d9f300a5625b1d5d22d54bfa0849d99a44fbb4c03bdf9c32f35e7de73275cf2eabbcdda14518cb4170e91d5ecabaa1199559a01de3919c5071c05f1ce142f54924a96fd9e9dd090c1974c77a24dc9ce3c4f07238dcc7037c91d77ed4c2500bc68e228d48c7e692f549c22194b1811bc106efc634fa9d44f9e9bb536daa2ef62f33d4d295cb6823b085bab2380ab50993b98aa91527ea20b4d2e4f676a8d78324f2a666d5ee390d9e0189cbf63c2eb373543a5b7531206409cc5359a9857525a6b589a57b24b8e28c34171761849c2c3ef80da60bf6d7ffc7611f6f9b72c776c00c9cb51f572e76a14a2317cd350ba6cd03f9daaf599f96fd895f4680d672912b265658bb406810bfe4b4363f4b76e704125854c245ab7af1b46c4c63f92e2bdc11539507ed97c50ca4879a67be56a525973ef4e4ade2299a948183180bed50d995b5846d23aacf9101a06f823050968c6990fef8628117bf31ba6eff5a07a08146edc78e8514c767272874790e86fe9c61df381e254b4753c2978b5b2bff1bff04db74cff17dcd5b0fad4d27666235814780f86e330aabee8e37d24e443525ab510992226069d9a8d79c777db8d1423e3e2206fe6617d74e2056df0d689cea2f6d1b0f317099be84455fe93b833542cdfe169a371bcf7777bdcec82094e38a037bb75f5d3ead0ce8db0a4634132a0b1bf925c9684677a7b53a95c8266546e1da48a96b1c22606a7b78453ac42d8c7cd3b8afc7412fa9d3720809664020e8092241e25ea55422f04cabc0ceac69bd7b17f0f9caebac4ccd96f9a5639e3074ad870c400186df64b5f071c0e6154a4feca8065281dbce4d2d93b1d7af522c178d35c816c5cc20409208e7c35444a31f320860d208cecc52741f34f2c6fd6cde3cd876c649706df046e11655f741f850aafcbed80fb8c95768dc1dfb1ec2395707e256f46c18eed810624cf081f8db9e82d8c04359fd20c35a3b04941fb9151076809a6790203f6fb4c9f42d33ad5342c292487ea7d26155e5b831add2c2c482047eb074b9bfa96c634aaa95892680e530ecb37752d8d6994538365890ae020fd6ec526854960ffce9f5949871b9e6c8fed9b9dde708997365aea130acdac0c8f06d2ac462a8a71e8f7563665ec01d63405ab48adce59a732c1da199323d8b04b1de4eb4bc6f712fcd8192e3ea157e59d973cb152d173e2e265f1d8f6ae2a3377c8b92178dacb34f670eab0e204252f486ee0532b21dfb58c2357808388322e422c109a08e624f1b6195647f25195e6671ffbdb93314147d5223a094873ad0f31ef29431e19e063534897d966eae87c5802980afa5619fc9fb76302b0342f18d599138641c646cc8937b9e5dbc89739c4aab23cea83e3b61d735fee205d26f7d031326f6fefcc1f1b9adbae7037f4f2f5f5b143b1db1b001dd0f253c66b4722b40837fc9afe750f1bc4e9bd4d223787ad5c04339008ab99089fed25783262ce8ac35058b0b2f9fe17b86f4214842d5230e837694e123dafddda4198f9f0cb6593ecbd42f3d6e73b4e074bd37c055fbd5d624334f542e738f2cbf7dff0af61a467034ea62a748643b121a73cb46296c580ed55d9419113d18345938692450a7e2ceb05bf7415d4d3c80e5ccf3e99ef16ed45eb431ca90b59cbae63bd354dc2eaf820cc62af95a338f9c72badf7f0da2c46c14ddd8ebedbe510328a12abf21d6a764becf6487a90670a12078dc3e620aef0648da42a80a9d95d04909f41102eca55217530214fc51a8eb61090c0804faaebcea6ea5023c1119e8ff619ac8b083cd7f57e49f5b7a2918145ef10102bdd36ed87981cd25463a29cc59028c1f19440814d739cecef6a24a83e8d6fc6406a01a5bea47771a38a13243c97b9ca21765884ab88e98eea66f251c4d39ba5dfae290b3762b4280f44c30f24b37b997a34d59b9d03ec063bbc55df6f6c981d5b0a667b52e44e064ce4cf8f30f1c74c2a146c2f74197d8937ef59d9da9dbbad932b3f34a68538f1adc96730e4f03d459c4f46242b247cb3322e6c2538db50390dc9e672ac0250b09f5a3de086d81290eeda6f769c440aa0bbcd00fa5e50703880e44eed5ac248a643d05cb624a870068053679b0c72e09ba6dec1cf20bc6e97acb261338ae66a88dfd1721dbe830ccad71878556c3d5c6c077c88d8c33544147c1c021fa21d09de1bc393896fa23a8380b587b9bcc39a32bcd155570737e140a815bf27ee24ad9e0603802c2cb65cc49b137c393140b5d9b900349dab62da9f797e78bf2ff39e6cde8f811d8ce768a35d5f2cec310a9ac24cf18efff8da4b2db35f822f92d4ca95c1884ab140338cb1d25cd446f20ec58dfd704c60d7b38cc44612f08d0630ee2d70943495a8a48690428081f9e05051323c2c016e64a02828f77e5558edf69a742bb9e7f612b645baf1ade07d212be13422d1d3789aac812a75dc1a0462073989ddb491d6351ae8206828fbfd154588ec7926290080bf4b2d89aebacab03f21eb39100f7b48334adbaa3d703041a61b304c224101b1169d2fed4e4b3c051bf5c93d3f25af7153dd08bda667e8385f8f04bc32a7c00701d442b97dd5c79ed58417b6ef5d1b33194874e27dbd8b86a9a65ae67ff5f4f4d6d7610ca18bea119d2c2876598869bf4e3bc27d3b443222ff2870cec71da0745fb700ff277f34c2553020eacb755f64b8df5bc0a1c5bd182d46ee4e78ba026e9975fa9976d185b3b0e7495243d62827405b402694e3cebc74f2cb41b139484f71c56858cb2a256b878aca18fb90b01b7d7bbadc13d464afae185a967ca7614a1a12f3bff6c0cb8d256446ca9c81b0d76b1630a6e20f948d2b4185a7437efe088a284426264238b125a559ce375c7aceb2cc6d06bcc51c0924835331258b131440cac2468c78399ccc086879fc84ca85559f1f0cb6213b8eb18c4ad824090084a8088be72c0832abbdb3c9576744ed633c62f90d3953cea592e0e5ca7978c920a07596ce2583cf6345abc57ecf4c8168eb97cafd96d84fb5f9125996072c64b98eaac754fe675a2a35da288caca743d4e942a9fadb3a3d34a959083942157261848f5790b03deb6919a6cd11de8134e345432fb2049b06126b05169152fa9e3462b1687997f4bd5c970d4683bfbb4d8014f9f0385da4b86315eb4ef9b396e00dbbac7bd268c9b5137b348ea8ce6fac06516d2018fa487d588aba6dc8026c482521e397a341b4db073c74175a2cee19f2368c58455d70d5ffecbfeb84e0bd31fac5dab052ecae70046695ac6850d6dcb0d854c336dc4256d440401e45ec4c63e51e7b5d53088dbfae8a032c58bc363b4ac65c06d2fd2224332dd188f73f7d15a71539fe2cd049c9aa4b5c2502c99be086079ade0590993ff90343ca45bb987e8557067ea886b1b8bec2165bc31769c025fcecf5765cc39f8ab164cac05cb8bdb4b68a58cef2199c17b7709f89fcb52e94dc9462cadeb7ec7639c2975c91b1d2f3fd488e8130373736d09515c621c31b5661030ab1a123ebdfb28024e95a62cdbd13ec2cd69ad445e9e8c012b546d63088e95cad1feeac41b671da4f1c80614aab20b0e7a2edac87d9bf1735bf09ba7ef32a54cf1a3577afbda5686662a168e31426020c371164726ae4593b639bedaa9c5ee92294fe2ed051eb3e3561ade66b35cdb2d363b17447772d67a8a092c1176bca7c5ce1d0a220e0651cd64d765c499e185a8d80c107b7b02434e36e2f394344172298dcdaa31a6336f82acee40a2fdb3376f661707704044d2707b46a1744c038b825e67e94d88bc49e0f103c8172a01e07d7cbb29d336d5b6c3166ce04c7038df965616393b17672a3de11376ff9934d28ce287fbd68508db8a958fde157065cba0e4f7d9bf4547f9c4a306858ad437d3f3638c5f7adc0fe92a7886aeae0882ba6f4917ad2c790bb58172c484b034339c2c9cb07b376b3be379064b5e28e98bc4b2b56da5746ab327c7513ecce4fc2f32814f5e7aae8d9f557b4f71c499b75b3afa2242435bd2872d52461972a35e3b039f536d49cf69e27b9ebf5ebd5b0ef26dfa948bbd3967495c0ac5cb186bd85c9acfb53a5dbca64ad998c42a3f4a364f64fa37b743629900186dfcdb91bef7226012dbdd8934666f8e4d88b980f7e51c5f69da86e8047a1bd9eaaf6852bf83b9f9e766998689ec215df1ceb62325c201c737bad8d1e8cbbf74441731a8a4104c1a4edd31c7abdd94cba07b824ae7c824e6c4988925136ad6599454ce73f81d84c72149ed1369717bccd9e65c9d43bba6fc84618e77a8bed7ea817a537bf63a767c801345245bbfb393288b058dfaa75882cd726f000587fad6546bf66b1139113ab1960d6fecc145862e938457208852ab22b723790a868961fcb07eea2208395f0c413640809d3885fdf382b01fbafe6b8ee0ec9d4a0de6eb3e609590166d09244db4f95b259ce10faa4356d41823d5fb47adb669a9f10777caccd3887da901ef405ba92262795176c0865e10c5c9a99a637d55a14ea807a671d551945d8c3ff53fb16838482ae8a597b96eedb631dda6f06bce448b11afb30c6b23cbc0f380868bbd34d0d5cca335f77cc77f74a68f92f21accacab12811376e75aebe82cba1ebe3df7c6e627837acf45887ce9d0a273835d28308a8c77bd59b5089130bd40ecf24265efba7c7edd95e5cf6ef45ccf51ea847e2ea75e46583e6d7ab3bbd13d16feb3096ebd988f90f7d37833ab1c431bd1ef7efd3e12555a2b339908b05ab83fcc8e0273c91cacd1e2ecf4f0c78fa8bddf228a9e7da823418f883538329ca37f5d8658f4d356fa38dcc19611c91226620403e9d4d805844c04eec14d52af77e80332cbe525fbbbe266acbd6d831660f0ce4d06e10c7030f4117fd8aea78fd4635658136958c7b1a10724aa95a513188708a4eb58da7a46150d4b5ed5924b807b0b3a654c6b4fef8b4c9c1ca5b123dfa6554aa6c29c7b55399558ac651b95d63540ca0ca551316019e872c5b7be4f84c52f4b42b0c954e196bb38d0933fab92b8c2ed03aeff63c7f171b128fa6d2c019c46a52a329bab741d80d2e9425175f6bb7c58332c6c6fc5e5ab5c2c9cfee811e29725ad4aded731404e66913a244f262e301e4206a8156f13600dad87ee058a94261dc6430a90212e4c8b829ec95eacd02ec185d807d1d2aa4c499d0f1e337e8bc0061608e0f6f42d28af8396f658b70eb0628221dca21b4e86c338598c9fdc1dd2255f7ebdc30e2d941eadbd7a6f278b04a33d98c02b842efa2637a23815f1251dc8dba11cf7e17798165bd724727be4bbb4b5d197e61cf0bcd3c5688e3eb140f94b734e3db223dfbb5829dfcc81a12b8bcc45857d76f6bb5599cc1a526972e9d1770157ec2cb0838a476a54171b1028b5af5b5b74e85e15931a1a42073f25edf8000f85983d9251e72558f2cb2b9f95f1198f1733dbb7d5dab7f10dbe7c00a80b522872b21af4799279518b4f5ae7212a50332ac9a05456aee085f101dd9ba384bdd7966a3ec0f8b6aff7fc901ae4c288d2b4b5a23461a042a73904fe9d56c227a3ff738d0e5471657c83a3fef16f16248ed7086e3c64f08aecddbb826e2f1b503264bae148f06154dd1f96a9c01c15259c1de5cc54bb8e0fa0c9051ea9cd3b34dc03a122232fc874c883d318011f7504f1542cb20605fa0e167edd705ca18dcfd472515a0e86c4edbdc408ddb24654d8e4b0ef1ac07263c063ef16d53ba74c47f4de83c73e6cc7a21500c2410083fe4118aa7df06c9a074e27c591fc80d1126afeec24571a90243f7972b1a7e6c5c31c84c1cd94d0a9157e2db5366ab960b30eb01b9d40bcc7d95905d3f8b70186df067c62e54294ea3dc571fb1ba7b59a5bc2ea8bfb51382e9f34d2b426613997ff15f969178192f4fc286ecb79c1147268bc7d3312db2240056ce8e0859b9e2cb8498964c42bc128c274316e576680fd6ba59fc1251cd6402080a029a6312eb60a328688701cacf528caf239afbcb2a46264faf7009028c2fc9c4a1e483a2d1855c79ea0a8cc9a9c3d78a4aa775119cd798595716419e0831dc9eb649f9bfb4aa45aeda0b2aed2809267cc29b0193821cb46df2346f7343366b572d38d13324466c23044de8aec3f5828c3f6b933ed01ee81769cca6f4ae8c4c426353c1d1a9efa74a2640c0855c3ca195561d4fdb9a642372b2199162797defa3e83c276f5154223d81367a72a6b929ee4de0b8beb2e5be9209de131331182315f30d57b6466ab2bae33c947ddabae4fe270f6881af04170237ed807e319d221272a90a4c7a86099a8492053892b24280880b111f4432f9c3a3d49b8e0ec8201bfae8901ce424c02358846602991a8a4c18eb9c4db82725b036df851aecfa0c5e5e58e7ba1f8fe2d78e224c46b9a9ad584f2c7a2ad511f1fcd3c4cc94e013369bb769331bb5a3969db799994d8da6f28d89f5049e1339d917c8419dcb2aca1541bdb7d6fcc8f67644a9221cf18f7222c25ff48d81a9237ec46654515aebbfe3b9d682c5a49c6a8ca726722ed2aec40901419146192b7441159427c3110951f0ff402ba557b2ab18172c6919932f68ae1c78f3677e9f1f1c50260829e4fb3a4598e3f87a86793339248ec1a431e7d9937c0a1210314a805b8e3057df4f67c38b2e7e36be5cef8d6fc0451fb9fbe0bfa6d8f90c9b3375e64b71682f6ae50bd84a10618912e44e65e00b008870f9d92ebe620506bb60f1828e20358502c7a92f9402691fb1c77fd46e6c62a610a607413cc6d4ef1e1fc98157a835f0ff997826704af0408fb8cc5f4910a20f0abc1f80f909e33a8a3915e1ac0939d476e5a199cd4c9b11708162a668e9191524408d4e572ded8c3ee386df86fe0379fce6dc52a62ea32ca78a41adaa7ba4d9380ed73bcfa80895c12002cfb09fdc0d6a3d4dcca8f11109a10209575312689a5803fd7b5106b4baa7fa4b165a8ab589374f8690c61078fe14f4f22e21fcf7351707b18f60b7131bce1a2efb71b192d752bc4d30d567f5238a24e675b84ccf44ad1c23edb9ae3e8f722e02f2dd5c54725750741eef02b46ee410a17ac32081d9bf1cc572d748731cb2412a966afc08d951cb5602080485b672a27de8f30090d684a06887c92bc2400072e9d6f470c50140c399d7f31bb757f78190353c08d4eee8bd56ca7fd1e2f1b079e6aabab0af4a180832777e8303829d8ba2cd14bc40af1bf97de08273a6b00522cbafdd18ffb5437b292cee41fcf60114bb1d40aa26dbf1e1d4bbab201d85d705ba171d7e139f65288d3cdebeae745d41ab0af345f33d406e0de5378b92b4a3fc75c9a4bc18fcae09a10aae06a47acb120b209ba5ecae162d4314ed0c82ab408e5e493f5d26c8070acda5fc9dd022609536ce2bf77cec9df5032e376c39730ad6beb2b979747dba3554db17cc5257db49c77da6021a0bb157860287b3857cbf39ff7980d2f60ae184d18f65534f0ba7a3272c9f681f62c5e236de6421cd1b583f0562cb95d6151631529895188969cebec2f7600a17db7bb2e108bfce5c5ae803c3b5cfa1fb7c29b39b5ab2d3250b823a732d6a3565607406696570a1919749a3a13f9c8e77d74d2f3f9c36fd5fb5b18ca39566cffa908942eb70174d8edd603ce3335664c5fa997625896a392579b4129be65ea75f056d465d1c6be34002dd02e4ca0b39b4b8cccbc5f6d6c7558b9a65fbb1adb5e6c9e1ec05952fcde1f886acf97027fde52dd8beb664ceb4bc0a707f5c8e729fa054ec96a5ec83154694183e989576f0b505735840e1bc1e01c461612ca92d9fe4535e6f86fb5d7ec20e6f6f0bbf99a49a7d07958e7f70e465d57826527b578233614d6359151b991fbfca9b6a126eb5c723d9b565a258ea5fe9e2c002dcaf8aa6609f0bab7bc4008773a3ea41d5caa86a794a959c253448ae669862712a816c66d353050599b3d14d8310166e1b774b29b6c49290e790e65afa5b52326ae2a8da7bc91318ac7d624d015f108912a2be1f9f8ecb881d9b535e16ac3ad0681725ab07759dbbbfc83497c8712443e455520a9209ed0a383b0354cfa0e0021307d26a2efdfea7cfc812b5f7d0a76d2c3f7dd0ecb2ea66a5214cb9913e835a9e5d706e77c9de31207bcb2c1913a16fa2740ec8c71b884b69dcfa65b878c212dc96f1abab2379b8380d12803717416a4750803015b670377a1a18c1b26a91a40d41adb2187a16d75ef5a9c9fd7b25b0e34afed06dc092719dd75e4459561788d475261a46b765c2c2ad7c12446c7b70e44f307f7987f09fc8982417a4b38aa441c23e1d3385f9c48995dfd88467001401ce4119dbcbfb745a98a14bed76865baa18a724e1b56b764c8b91115d800b00fddf1a01949be723d9f1eaf6c214fcc1483a59ac1b89732f46d343612309e32e294e00e8f57b5813145f409c31e980ca1c9e9a2457e945956a58b70e230e5db6dcbe9459226215cd205b5ce1021fc8ee97ae999842daff6538bf01183fdd58b20f1d02a3b0a950c8e1c4112b96136be8ed381f9c3c8b6ee16dbd781174f642f26945f92f2799016837f4c4ba011f8f82143397664ba310777d759c5f6e169747e7c5db557a171f48f7864906866f54111845e7e98c5008ae08cef0ec96e4958b123f905f4a8959fe3f0f65cf068e2997b9b115a030b268efa6be0e741066ee05c6aa44c015602ef038cd62a698fac3653bb1270705fca687fa3317b011b886588515fcb382d6820d819f5e0a29053277cbf2b98669187341988fb14a07a66eb94f051b746ce9735014b818b4a0b465a0ad82c25dce94596fac7250296d554a94fab54ca967497e490babba7d6ca48d7091e81007e508bf179a166c32149422bef70aecf31bf7279eb98d797b52bc09585c34c3b5bca296e3666f367e1eafc714c05110644e2f6c41a24ffc98683ad7797e714799ba7a54d28dafb2010cda1b5559bacfabab8a91358f33fc511642c7cd403a449a95a7bbe8e40ee80e4cebe39f1af111c2ee3f350a574844d3dd72e42478ebe261dfee1f8889e21888d92e5b99c55d69c02ae143270f05aa844860f7f52889fa0f306fc2580f545dfbba9e229fa0fbf9aad089292cccd29b974d85051bfaeac61e8e17f7c20549d61343b1109757ee996e4ad0951ac51241aed803cfdced22f28667faeead3c59469168233766f02b4b5aba3f9b642eca59d1b18dd9d9f1c3ed901e5d26c6bf044c379a0e7ad3eb23eda18aa38f30d078b3d5260cf49b9b6b14ff19b702d180ebb90ab73e32e12897c8d229acf47f266c9c7fff03389813eefd7b5feec0bdbda25e13ea72f38f87876054150796319f683616a364abb4fa2bb17c4fb507cbedf81784c13ec5310c1ef8ba8d3963eac7891efb906f857fc63ceb555eee457b855639c39f2df54377d44879eef0287c1e936670dba20a25f6063a38c6fa392d0b285e278799e4abdcd4b725452f12d71073778903d8f11f33c0ec5613a57dad1c4f4f9bfec3a4f5e700dd3325bd7a49fca389f3d74fe7867bf33a0369f767124af7bed6ee1061e12cdc7e82b9a74a5c8de3f65584c1c65137e68873c72790757331db91cd80681c043b62acfff3192f13cf9c0c9bfae65c8200089f7b8392c086a3cacd6d8ed2c22af82af33203eda35a08193604d10adc0f8abec788c61d8b7f5f9ec67e46a5c7e49dabca1b774314c799e3b5baeeddda2769229fb45fc3bcd5f51b3d246909cc10c1e0a67e2e8844d61c17333ae1b4094a228fef8d973186669d1597de0c5d58035109d2a9cb8042d1175884412912d63c1b9bc98626664cae7a85eaa154d48b4c96ea73dab87dea77d093d989a5a5841a564a2af06cf1728ed5df3ca6eaa902203193ff26326eaa959218527cdf15d7a0ffea920e7f21edc14063195de3538f4522e05d86c57c6460fb91adf2cf348e3408563fe53f0a53a6325be4e93530c867aa4dc79f435fa9f5c789562a958c96ba53c073487eb0283bc715a9638a263e633ee91f98e7141d5b4d08823ee535227855b0be0c99addbe8879f2892fa3e56e50bed0cc4f7a1c87c6fb00dcf93ff631e37104fd5c26f9927c9f7b799d8c21858463f1fc83b19a5f255c23ad6c407e2551236aa715e8883bf099d700bff9cc7de02d4d242efa5af92813c7ea38b2732378ebcbd2544e807eb52dceaa2d62430b68fe883708b0b4f36dcc2337995d89d7521110c036f8d7c20a0451da2687513168b80aa81c4152b6d688515cdb27b4b7c1f06661d1a408e5f77a5ade2d17f9a46cd7b5ad60d6239b7e548dea8cacbb26ee76ed289b067cfb22ef74a15ebd7aa0d1f3b05dc8e33c22d698c401048ed32edfe29828ea6ddba06dda113ba434fe8873e062579eebc22792df8703053c1821108d3fb20a4d057dc1419c6845402c27c9993777ad62d60ee0250403af1e77e6d2065a9858985694b70c3f1af00b09182bdba7c41ff0ba54bec584aa41d5cfa9c0bdf91bb6a7a5244bb31b05e68bb0582993637a2af5874f014959d29f1942b29fea84947ed01f5600dcb7b1b39cda9c616505240eac88abd2201ad4ad1507349b829ea969064d0aa09e8771729250c59b6c6a3b296628c7f0028a0937a23911e60c3c3373a37a5cdd8b157c1aa4c69c8b40996353f54283f8b86a8c8312007ea4b379daa0b7709ad25d30886e8150a934167dff3847e9824c82c03a8dbeef3e729ae8d9b500459070c8a79a6b33b9519a437ea7e15102caf5a3656c8e9563bc1bc4edce21c01010f28037ef9a62f9dca9dbcfbd8ba28ea644a59a8a56fa28dc2b7c1d5bfaa94de30e17c054ec1554785f093bd1e3587bb7cd0e20562a7a8fc3cdf291a2c50fbdc4ca35441d58e07cbb29ea2aff1e6c199f9594ab728895bdc73d4d0573d0104072bc06e071501c1f474003fbda0e395a6448b50ce9c9091b5ce863d1dec1a55cd793612e3902aaa5297d5e0ed06ccc6fd53889fd435068ab2e6bd336f3478275e3d0af10be3509a3a0d2a3d5380dd0e7a9c41308f064834165df1c1b8011995537fa7ce97644c3f5c5c310b26468dcb90bccfc2dcaeb7c0627458a8ce7dcdb1f7740e4c3e2f094067be444f114340ef346c0bc1f6c96afe5b4c34811c76d18794eb28b37c8885db80eb4379880029e6a80a73a42ca13359b434de86ff28e026d8fd81221bb851a192920c708387d412f5bb1569ee42f85a11ca7a7addd541d1b087d9380f57dce6638a0f7d1672fa2bec93a213f2d3488827b0cc24a1effe10e2622617cca83cfbcc5923a5fb12ef5b5cc446ecd05a47412471175fa546632247ecb1097b0c83575c61b7604ad18787f6ab771b65d9a0811628e05f7e03262e47f22c1b422ca00525250f9cf518dc85d94be56c33b430cb2dedf87246c33e28b60c993b84a9b47711b1895e8fbc16b40d331d9ba75bea327f6c35c39ac75fc47dabbd7ee14b7285a8637bfd47afd68a6c24426f35e02c835f79783882d130abc6b40ef6237b002a47c46867dfcbbf30ecd1e4309a236330f70d11e66af451a5d6312d3dcae9fb098e189222559c00a85e2876b6a77ab5a7df34ac5574d5b17ee693fcdb9523dd1d5208a4672ce419215d3bf2a2fc8fa38d64c7b0de239566c8fcd14235764eb696b4d50c45b394a01d052ebb4b9b6cf8b272a8cbf30632d436c32d0f1187171c7ea6ebf520644609f3b09e424a36afdf661ae818abc993d72be18afea381a1a468c1f470a8a344d697da9954a2bd543ffb9001b4c5bef1d307cb409c6719bfa4433dd2d362b3d3cbb21195d163ffbe0f4a324e3c9ea6f8c13e54bb78d0e774c22006b3e62d69e8eb387e7815acaf2015f010daa4c0146294e9029cd4202469ba88266220dd523bdf50f7f4a7d3919d9d8379a26591309672bad29cd21413a4d442f39d2b9d8018eb931837b2e43cc7adb53e480b5535c28a74341c0c2d918c49fb55873b673842c2298dde6f8b9575112925b0ccdb0f2b74bfb08ccd6656d299bb61e51d3c6eaa51781ebc2d0caf8669148133fd6a652862591e73e861476db04f802fe94394791572433f5d53828262819eb4966f7785cc12f8321b8c95988c17353c6bcc456dd9e77c4b499443bf05a905ace783810a60f5b30af2a150496f85ae26ba2f7da1e399c05780c1a8d0829dc3ef5bbaec472f5db5f6cbf205e35b19dc5b52c3b375b21444648a0aa38572f261e5c099b1166e0f4e232534babcb0588c0361b6a9e2ccc3a0b7e0440796b67df93549fdd4f99ea5a557de0de1d2c303e6dc524220a67265c18619a89cf229d8c176ab111cfb4affb555557c63ea39e0d5c15463dca3b73b374ee143c9857fb6c378673c2bf12e987e42ab396078f16841795475e7ff7ab84a4f1aad0d3c13cb463b4cf3c8529ef7a80dfc538398f9326a84bfca54fdc2880d527769c5f37c9b3317613f48939468f397456f5dd694726f221e544bd69e44f3ee2d1c58bac765af4cfb88bc235f31b48bac05ac981b62156e94d059df188654f264aec0a3fe654e08f046d08df523c0622142b871b08052e42180bfa837abf67078b9644fc955738c487e500a959e6f179a959a8c08b1c5eae3fe6800e616157695c04296da4f1f065279721e92d569fde2443f784b9c603553bd80cdb412d88c581113430336d369fea435b292737a4e04c9f0e10a7e44cae99b86f23f984102b5535c88900c66cfb557cc3d935e394394f78ab3f5a222be79e035e2f00cb09336288f27f0b349f73ccff526b0a299c1f49d0af9be3d97a9273330aa05bd943747bcf91501000d675ef0d7c340b471876a2e8e1422c89ea157128a7e4f6a439ddc9623973ef64471fd241dac44b5bf461089d1b08ebd028e73720e3a3455217ec4add21565a8b6607d09ac1786fad02e974b7075958792a9da266b6cc1e8dd568b997410a9eb79d2b508b8b6f9c1a70837eff04e900daadea3f78bd73768ec06628fad90a55b5d4c012fd5cba3b9e48be7f7db004478ed819bc76a79602a0d66202aa23d19188800a64a4c6d7a9a29b05d9d625eaa7e7d293e0e376ce3ba625e2a3d184b374c575a0d0342b2081f6fc44b699951695950844c324e065e2adc2a6bd481234eed94ef920ac5a4188c1251efab4a432e33913bcb4b096290ed8daabe617c7cea1ebeeb3d2f5598a6a351589f71b9bf7d8e4f5eaa74a07e2c97ff9ecca6cc8ce488cef9bbed1087f791d64cc16540211294e24c0019f2a34e7ba4a4891f347a6d216bcc67d5ae0f19407c3e52c13d8cd6282d3abf37d15a2ca2bfbde2a466b51ede19a17c6bd2e95797e2c93694b0f94b0cf015ed612512189cbebec76ed220b43bc3762bc2dad6b2d30b683c64078958a1f4c8ec881bc3f8a85e91834165310fe4c099e16e87682dfe80f3a67580fd6ca326b4aa23a519c63815ca5ab509923ec10eedd7736933e088b0d426d5d75bb4cb31ad6aa345f8f5bcf79c8537dd3cd6dd41199161e44a8f7e58bccb2f3f1407d8e8aaba16f8cb9ca788a85c8a2beb9b27ce534d859527f043b4f09bf77b0b2c45ba5aad4ed17e24a98c8c57f19f08bdadcdde950382faf08d448ef6e58873a5e03ce6c9613c946320c501bb4994c581d4a2bf231cccff2dca67d2241ba0471328d4edf966b72541fccc09c8c774b03e0e5553b907e257b3a19c56b8d2acaeae4eab2e502b774b9cc0de81b20d5f46cef5d07adb16ae3a1976c0d2c7521f57921cdf6182bbe84cacce045affb8927476afacb340e255b7a6ec0225dd62953ffd4c833b9ea12b0104b4999e54d17ae0fea37efba6386fd1b11338e2b1201508925434de3573a24c1771b846b10435266ae9c2704d81aaebc05fb84535a6e278699abc24e13922b955c52c3b49a252daaed2d2fca970ae5c0a2dff344f15588188d1a7104240dbf3e1911bcde618181f00a4fb3b57450452d3b5f4f6c087466f2db7e33f714887f014d6d6190a8fb6acb347104d132c971a9aa86e0a4130c8902b5ffe7b76529d4328c8b385c9ae54ae13530207eb30133b9fca05e748e1876ec7d8e332b8b048b6715751a8a75f885914573259ac90e6d1abbc4f4086b3139aef8a9008f5730c566f58a1f536072fad4a919598a8a48c12abcf5a3eac7eca751f2e4d84c458804be3364515a9e72bbbddbbc1fc59964d2c691876e61c2ae073c15472832927ab00f107e722f621db0f436b3b944f5b5ee940752b75c8debaefed89f2a8ff90fe2a647586b2b6475fdd66a8e7c997c58116c0c00651aa2ef301c23b6f845c93360382611594c38e4ed6feb79198c20d31c8fb58ab9b9a8a5885dd776647110e80ef01f8cc63e0af56e483831fbba468a92188e5f7bf988fa0385f29f0ee58c836b0409de16db6654e98971cc24c78229f8ece46e16e39003dcfc0f708b0bd7c0a818ecc837945d1e3d94951f764e84dded151154b8719d8c971f9106f487002d124a793356a96198eb6b32c03b4604a531f10bbedabbc6e3d7c9e71e89fd14315dc3b72c5b94e16bcd59349dbf12ab27cbe7208b4305554e2464918728082f9904ef8263e10092dfc2eee2071cd6766ad63dcd7b2052f81a9e75e9679828ac45b7622022f3108ab9f2e949f730701a4009a0ab1f1899bd78e880a94d238516f5419b3b037a0be592ae101c193228f61baea6996c9c967c6163137e052a7cf8fa9eadd04c912b33eff3df5b0fa089b8f02e6568d305c7a3ef2c7d9781228b63853cad4ccd52facbfa6137580b6801467491f20935a6c211229c1a2739eaceae49a6b342141f83465a6c9bc5c2a94ba3ec164fd69692a9c1eede9f54d872081c735bec8f6fa07034ef53568897eb04a590407163040022381d45b8d5e165afa573943a0baedcc4f1b0cec213142ed7195a20ff74abde5dba222238e79ca3e1cb87a85b286b8d43deb0bcc03506aacd0704b756f3ed3424e42d093de055dfba8fd07eda14073c10c16bdca6cd26d87cc24ba18d4a7ee3d46ba597a6999dce4f17467106b6a305801016ba60b6761b1edc22f9169ddd961a92864b979f4b26322c1953c34cf6d76d2ea6935df905875776207a462aa1d939b0b5e6c39547f7a3b210b54e96a9d42c13c7a49579211c7d622dc9d8d153983136e797c65f717d475471c560232c9d0d68f517bb941bd47c19a945a5212e071908bae6030c7d958234ed7db6bad3a910b6c5de5d28160faef55f6daa9e05346f19dd2733e0c2524c53b659156ca7e70f1979b44e10461649068d49de37acad24d09a5710ee9eb648a5adc8563f3594e40280857f1de1369d86de3883dd9bc60095c190aa6b0098d3aad8039792995cd58d9b6e001d2b85cb883c7b83ad14242cb1721a05cf5a8827f17fa8743179b1876b2e7e3b88a359e8180adeb05e45c6370915040993b0746bf78297a1ca045460440557382c27a05347c2828835c7c2dbc5d8e4092793109c2ba9b558bd163888f024dbbad9835ffaac0c4091e146424f99a0a1d2bac397464e55ab9d2ca8801704c5569b573888ed35bad27a29776989c558ce5699e4e0f39d50f53f5560e07fe4965aeef5334da1f6f695e586597b7f9a955b74e3307ab92561a8524737a1297d463a43fb8e0a1663b054c313900d40037d7789dfff0c40fe5854f3a927ba09d2060a27d5b4818e1c361d7fe69bc95d069889cb80289414b1565db155133fd7e871c1d8575622d46d79f7b09254778eee0f80a685e5af861afd4a3d0cc1881cec70e52e86e90734ba515d51d6123e72d8b5431ccf9a7d9c9503ed4fcd6613ee012ead7a78de0cbb83008b9536505d3b8032cf9bc2d6b86994dc70aebf3943b4365fcc0339ee6abf55eb081c150e18d58dd73a64c235fac9164dc5ffce8025439dd9c39259c80eb1d8ed67f89dc936b888fd64d3f089efedcbab7e663681b40dea308fd75e964e681b1ea7927317f1e2b5397de05632253583ce4e01f4c3c599740701c82eae080d668383ba74f777fc742ba0825a8c7dee01bc5c68e47230e0f42ecc4d1759cf1458f31de333be15177fd1f884143839fe1de30fbbf294f5963e1a1b021f2b2c76f4f50a27be138247cc2c7d47ab826fd7b3c269479ac64c84f0df345a88c73eae1d297b85574c0389a765c73b7da39c97cb39afed0c694009391e6c7f2b0b0894727a1b1d90d7b05ee5b8024a3a642d726a163a391fa02a25ed180659f79f4747bee448b4d08a42378eb2a7943a6ede66e148aba1b4130f9eeaf078aa318d95faf9a3d087f905c7aa3686b6371ad3c48a033d126b894fc5a60d0744afc553ae0c826e6fbb4172bab747bc56ca4d66fb55782b18a4e147f6fbccb71c21990d2d4997b46695bf948acf95bd6c831cf80c3e9ba774bbd89e8284ecec3e961739fc99c0ee2e112ebbf5dc43c023fdf9aab87a3aab3af85671db7870a4d72fdd081297673dccb0a1da99c97296874bfdb5b2abb073d4dceab39a3a7060e9a130aa9e3f70bd8c86fe6260fdc6be88b923553d94783475424b035135bb543fa330c610c21f0bbb747e8fcf3b346a622e7850f9719e0dfafeffffc6b9f1a12ff26d91b280cceaba8d28bb31cead50c83bc9589f13251cd87bdfa6a1db5cbe509ddf01d125835efcb65156220128a3caefe5292f1928ceba1c69aeddc846952adc62b940543a1113f281c24bb894e332b93a588e47a8d66b03c1a91d583e3da0393041c8a5038715f632894b34dec5f63b61a71997fd33bda08aa95b8d7672b52b930473f648d1576dd985a50f075c42d24cd39d9b0912532f4e01b885ee00e7a4e379754817e5a13d7643f29a2d58a0119797e3c7db39c474a8c2201e81d584fe7ea3702b4c64d1859ba1b0540abbd3dce58c020a2e419afdf8c7604ce27e5d6ace3786eee88ac3e834910cdcd23759f7fa57b98d20e1f1f961a1ac26a53e8035e25b7ee4466a186a415432ff46e244a1130bedd422c2a40d202631a5e81e33150e7d530bd1a6206019a746959aa444d51559aaae3a81cf566928d85ae22d1ee1942ae55cdd5a20105edff1f2c2935200b1c2e53952a992cd9d6c4133f9f7ee798d49029ca54c1f4c0546899189bcc4bcd0d74204d2c2639062efe142fcca34bfd2495f217a3ee2815dfcdaae17fa39d73166cd66dfc89be144fc2ab1c1ca9589011839d3cef2d744b43dadb493585ebb3ee160b7798197a30649388db0d2c6fc474024e52595297f72a4b76a9429e1964590634d442acff2683f5f54a9b83a0c81c8f861838e3088c7918e05ba027c61ec579e084b550c7a0c0f5de01268d7d7c2ebdeec9075370a1fe2629694fe7c0573a7c93b9b8fed6f34e2a20d8af1c22d378ecfd650aa2830bfe0f337bbc865e43632e4c43f4ae6c99b71053bcedf274bf900382818829b6ce86bbe1485a4b201b1adee2fb4d3e6f94960c385e3312b9cf4dc5e7f77e398d850ddabd76be2d0baa5c3baf608f165ec070ee6f29d438d3b359611f482eca35667771e420d8c104a3672b8f706b8e81a6a2822921ec9e16cabcd164fab451ce92bb5e6b0d6548b34697014ad8605dffc86dafb1d81bf392c1627f3714d8500ba6c7fea7e901a034be957fa061e31ddf76e4bc7c98e584bf0fb3e7d10be6f0c35efb938d0136085cbdbba8d6d25cc554b1a1c409983581c545006863620f3d7fe5fab54ba858613b067d14f307fddc89f12f86b7a71f4748063d151431e6d71782a8200121e4237c0de11b884855f943fa2a58673c874370ab5120156b63575796afccbc9204708bd5e3d1602bef771605ec788d24607872aa9826e281db13dd19a4e3616578c19e38cafd137f8ae45596d411010d238a610e616a322c2c00c5bbaa769be6b2a8fa00cfcce171117034480a413e851ef3aaf3d99b35ef6b7e7e28085d7d844f9ce016bb2a8c4baedc8d92007a6cc0821603a50fa7aa558300b8d6345e6e24f37c449da52ed8dcf9d78d0aee143f4b00ca959ae095f8ed8cc304704601377464125078893488f4c94bbcdeaac3b81ff77dc921653c05e7810ad05aa595934eda2affcd442733b4be76bcf5171883109ccc51d11a8d354b1c1384380aa88062595cbff8970b884de2cd8600fe18b33780b4a0c54f466ae441d97675326a47b8764dda6b0b66712a144118d5531bf6f89dec49f54145ecc428da6dcc0d0e295564fd3fabaf65dc8e3e6fd30174b240e84a28746ef070539e1344a66f9759a34b10d53d0f0a7780fe9f372bf0637966baeb6e0996353914e01dd3391ddff56a48ee2c323ff439c64c5482cc5eb367fa811f7373311a64ae5b3fe2085b8466aee195dbcbe1fd95e8d386e6537a1ddecc537b47ff4b65f274cce73aa67e24c5a0c4eae83ac06795ae3bfc6c393e7d1403330c0d48ddb6ba58157665375e37110f3160924e50f28e0520b078506456628ee1bc1c5417f88394312e53d165ff54c3555cc454f56b72b9e43657322ffeb7608b8832db5db0c8832523b1c67aade6cbb43c150e0bed5ca6b003c113bd723346572559c07fa5475dc2295d3dcf01a914588731f9c1dacffd8f5e267acd7758d6f6d59f51dfdb9635075ad64eef8e4369fff1c35362643e0fbcfd98a0e3d508598d6b9d2c1e23e958a2016993607c8db6e3a4098ce5aa50e5600eb7339630c370540de1255378a87903bb4d5287610db0725d822d3c64b495c8af369eb68b1b248a65a11d0dde54ef4bcdcc05b4a3f1a2a9cbf49bbdeba85e66bfbd93b5b4657065f9f6dd8cacae22b55de95220cc6d494e5db4f9422139ccc61d9639508764c0f1da40e84337cbe0174e19230a0f0a89ba0c2d739fae070c651db144bd7a3696a2db67244b7c70ccae73173664c8e6d32de60ddfca48d0b2e4dcaaaa00d2f58af2a98fa33b3c8a8f59e256af880d78a0e5302eec2756c29e2b7ef49e562ba3ff8a936475b5cf88138313be800b5038e8b957ea40d30f0c93d011fb3f51eb0f4128ac2c6f9e063407d69e159d462e1c26e814f8232add8ed28f2134cfde9826382638e41bb2bd15fb3413bd0e9f5e877d4dec0b38fafe2ccc0a878633cde468bb964869d32ff2e5e1444c6f195d123ce642273dd453685dcd38a928c10d38846853fa799639a40d8a3039da5899ad8cbb040d5d3e7a367e62c4873ad4eb015645a3298111403515f044a78c5236d70983d70efb0465c4e00d4d0368e926b2f61cce10a200fdc1e401b1509a103152312ef9a815afe21a931f9c8d3455c957a6ad6f629f152e49c68c7c923b66a692e7ed39f87887cc3a7a474c31f4c38af0346988d01fef73568848bcefa4267bdd3e2571e1a85ab47c7a28ccaf1840ef3cea8898331cd24538dd68ff604a427f540752a548c0fff5ea6647165d748e72388b78db6f91f4155c5551527cc700a0ea52269b2acec74a53c499318427dc898afbbaaeb21a4d972089536f6da650caed00cd2d93658c7a9e5e141c5243d88bd781e5afa982f3f0b6bfc0f68175f89c31875e7970d43511d3b034188d1461228609e23b50763b87f7bbca5079cc5e9bb60b44f5d85186a8909e02427dba609e296fb01d2934879cde4d27fea1d4141b1598d3388775a4643f8a50909b0026b875911e5311cb19eafdf141c05a7e6a6a302ddbfc7c2ab8a40c3d3818a519b2fa69f266d76b97e737480bcdc66ab73d5061197275e14c350b9c59e3cc0b62c0f323759b16443ac5f6f59002807e2df36e13eb21b985369670792a9c508d4d3fe4f7ecc5e1ee4cc4d301fa02b54911e99fa7f9f5a926af563940fee5034b3bb5f0c119aa3921b56be25c1d0ec83390a570150319ccc1b00623574723adefba7609ed0a2f01244fc7c489395c67033a447a4bf816378724df91d42f2a62346add80a2c263729f2f5b043275825eab4869e0925b778d71246b431e32b45ab40bcc0e3925b7bdba2abe339e146875298ea83d21d76feb034dbe2f63e880d5cad0581be4925b170dae1f732376466409ce88acf36e3b5113d609f2ad31be99ddfc23607a45b9eae65b69a7f806409fb4fc42228153c3bdaa351aadfc2c9e4f145858a05e61e2d3024e2062a1dc0181e9b7ae7e433202cef4276d75c4d798cf04b1a793678df3622b690b0bd45bcb60bda22caeae9614abf736b5b9a7455127e1e219a403eca741af523ee67a7a19285002035094693d06d5dfe3409b4588740675e084c13aff151fbc9ccebf455b97b0b52e65621d22523763c7fd8591c862412084c06930cff13b230742f683c69e7434ac856c58fa9f0f1645f74cce9e1760ef0202f69d89d39535cfec4b21bdda931f8ffe807f99d0fe2f4b23b3002f635af480f1ac664778c5e1d91f1b281fa74b871a5fe426cd401bf658e85e2ab4be24c8939c220a796170933116407fe5279c67edf4bf13edeba41ff64fb717afa51284ae716f69844afb75448e5bc586fd40b52aa75e8d351f60d87968c71089c2976903fc47d32301cfc416fd359ded58f64311e1b16764d876719146adc200228d8f36093bf4ce74d66e686ab712de9fa6584017981cf16480104bd4e50d5980f405f4bc47c946a282056e7795ce46c8a4909777845270d98865588dfc84855440d0a7c0c126c807a15c0c2c7155d27311d21f45d2496bd0f9bac785c90d3debb5388c804b37f3c54a0b426bec337163c5442124f9ad38fb408cd1e953b022be3052c5fae0f227c504a43c378d4fcbbe05210f94ba717981f61b7f547d7d0a342eec40476abdd66778238bebd1038af2c6d68e3c33cee4b1628962b5f13f9c6d1e1992c3c78887c56474dca7e241c787203f0b375d200edf9656e79e86d2e1eee20b6715bdd95f459c4922dd071d4f0d477c6a30a629a272c9b805db9170f3d5dcf94e1346d1ca6f1a449f0484dfb7009ff46836c622e67e5cc41d0ec619932141a977aabd5ea20745caa7dbb9a1e20a55f9bdfd0613b66e0873d9ac2b4984065f300bd7e27ce7a5371f50ca8f8acc9a0f307b4e576573a37e2936f6013eec4bc343502c125db29d142f25264879c88c0106d682c2e45a554fad3b12ab5bfa285221ea1c6f33a4e2825c3ae9707fdb309db964ae68067dafd468a81e9aaaf633fe0d8d06415bcb566674ac6d6dad59130b4900ed510089c95204a3480be51ddbbc286de7339e3be2e9e64d517324d8530639c5686b8c06c92946523885f6bdc732c56dd018971460c0da33708a501601484bc1b0acf6205b0e93d66b08fe207fe98379956bb0bde029b313302ac7f73190ff87363c0b793aac57357648a2d40d93b36117c47e2f8de5e9ee4a5d6c875ab2208c74eefe280308ca66f18acb2b38e29592a5ecd5308db1c58568063f27d19e0124f805880f6c558362b27b39072ae28d62d8ad7d7102964b0cbf2ab1c4de234b3c2a1358db6f6885eb9d8ca2cd8b13fe2ec989602adcd7f0d64010c2b067839be21b03ba57bfd754f88e675a7c641ef2b8a2fd6c97b9c43683ce82fac49e915a22c8c6befe91def503248f5301111aeaf64b9c33f14d58230060edf888113b48598a83ca51d0d1544787c5f41c63417868d1bde72e62aa0bbf6c12d3e13359bd89097a8d92b5c490804e7bfb226bbc5a0f907321ef430eca93fd56c0e1fb99e0cd72be82a639e90ce4fa02298bb99a811f759f5624e5a891988b14899a39a42f968e64dad025b42252dda81d51aae4665574c6ed30f33083f2d30738e486528d4610ccd583c614485f51c7cf3e264804329c87ab497d31fff8c08ad9976f501382f7a3b08fc8c6b7220e4fc84e8fb10eea11807f400d6226182cc516b873b20a91848f242b9b40e9dd7110f1f738876b0bd7ee85e751af82d13490562fe1746e35337b680f820d60c90873d5ecbec393dfd53477cc1e8ae04ff4c44bececfccdf94c823955acd3553bcb0dafb8c1ca8f23ee77f3f841c8e6e3d2b907efee4b70443ff912b317210bfd824b29ad4c447e1751d6e2a1892f010d3a14c939d68d90f7e270d3c3931a52702ef01a500ca9047d26383a69e1f29884540a90970846b15031217762f87150e4d983f7c5cdf9c95c32f8cc283799305596c2aade9bfe958835e79bca506a538c86ebb7436dd5d55dedf208ce456d0e000cdd3c9b06927607d1693eb14f1f8871e17f9bccf926588b920e64662a580d613454872c9a338ee7ad83bc5dae85fb8389f3a7ec982084fb7c4d7290705db20254c9e18924e2fe0e6cbf7c6eee183308021e0eea18f09109fd0e00f029eaada757ec03dd93a198a7c18f0c58a48926696ddee3dcd5af39911c9636529d87d179f9e1a0bfbd9539c22bd1628ff78d3d1745ee121e87fdb1e808d9983b4cd8aaf02358c5ca143ad7a6eed6c80e26f544025648ffb20d8426de3b89d0fd9d7e8e388ff912f1718e00809a0ded0b553b803ff091c1c4f26ae3b0f88f67fc3d46f18662ea38f4cff7b70d4a23b0ae198e3b64cd07a33ad55030ce82e97b9f13eab26d50bb79a646b0bcb950adc0856cf6ea8102c2036368608205a5b37ab42141778dad7bba2eff293ee7d04a9928d42a522cc1580367f60cbea560a8381a8c3893ff10c795850248b4c7ed417dc0f20c6b1a14f8de7fff197a66b161d1359b16b0824e973048a1512e5881fb8a5f80a7c41542895c603ebb23956ea652ffb1e468f4fd4ddad58744b9fde965f9d5b06ae96ab19f6167847e2e0e579bbe87fbd1dfd6c7b773871eb5e3da731eb6fc9f8f3b07e71d02e866799b7571ffa96d8231f659cb4d051fecf38d7c2b75a3c80e1094a5dd1a6b0698a793c0739af2407ce59bfdd0e648df58a696970c5c8ae98ea0000e274921fb58227d6f416085569bb91b16200fef07ebbe5bbf5408db8a70adf0f9e73cdaef46aad5af31c181fa448daa3eb0b67f0a2a725fa73422510037e41d5d4ef4444d6cb1622d4adaec65fb83521b88e743dac8283d31269dd4db018403b049ad50342be5aec080697598ab386b1f00394a590fd78fcc21ae922e6ac6c258cc8e1d8378d469599f8adb1a45e678ac2c36172ba531538d7da52013a539538bb5c596d2d44a1be556d12832ad746966897874296e7225566b48d904f26c58d56640291d7d4ed5a62d12d6292d4c920025b1a66e5196ba4304aeda7b30a0e57ace963375f978b64d589cf95facec0fc97c6dfb2285cd0c7c349ac96dbc3cba93c36ca00ef486458431a5d330c2c718ee42c4b415882af666ee938f10988d00f148d01fc688f01f4bfaceec6c020cdb8c87066e7f9112377d0cd48692277e24570be28a89a7a245875249838dd76c506ddcafc77032e7260ef8baa4cef392bb9f5e13dd3980099c1ab5e93aa007ddd7a80220b0febaa6691aef116f34b47f92f5f5ec7277f661e43a9c04d643d1a3caf59df355f25c6d8b865b9a29e10b842fcf858ff908bf8ca23f6cd2883b35ed8c73a2e1f321740a1699636c1d543bf793e0c7ebf0b249a5f488efe8a6dd82882187e7852ec142ff380c9ff9014b9cf560ca9f958a9fb5d39b9346b6cb3aa75076391c9fea249071d04cbca4e260bbbafc2ff79707dcb845a65e64478ec592912b48250ad179f072778ae318d82d4737a8e51e6fd132542909e92404b44e6772824e8f17f12181ceaf6d4ede4a608bfc2c231d10f661bb5cdf8a1d59cb3c0e4f10873c5490feeae709e8da47c0dc990c8698056c3b1690c70c403f7290ba7fdc619ade70ec0c67076f4ec26cac26ba69c8443d4cc6c72434662d5c415b1b0dfe4ab4d6eb29f6b3551cb4c7a9cb92f4eb9acd410cec0563cfa7ea30fd70d3f7e50772584a9b15c9fd78b4a7e53e473d62e903631607bfd8efd60026f5688965ea863b968359b6d4a34039276125673ccef6524103cbc850caa00e1fa3065cddcaf1726addf7e39c648facd483819dac8ea47e6daafaf462935c69d2033e6a13bff4ea8304f9c5b8c7a84a7d2d789fa0710b2296b3d07f386bd46cbd4e2decb5ea7717695cd48a55eb22f82769f96aa9a840655beffab5e5ad06dca26a613f40f3fb29fa0ea666bdc335cb7427cbfabc71bc8495c56256d21400665195fc56e63272259ae65cdcb11cb2ac26eca579b73f4b9b172f8fb2b3c8e0fed0f699e88d7b88d9bced31b5709c1de8fe6dfe4382106b894bc20d8a1f8ae9414026573e60c4c1c910ee291d611a2adb9be36d38185c0f7ab7f2eb95a92de70d2777d895df67fc02678b0f8ac58f616c7abed0c4afef46770d2d75978a8ccafca56c3d4671d92ac63a83ab845997b63b7c872026e9397e6f59398deb7e4ab816e9d6df9f0b6039ee3ba894320e8edce1b1496a731fa2ebcbcfd1afbcb1033212758a39f405e8af2651fa77b674ff992ba164ec5e7c2c702931fb5515abb0ac1b4259f99f7076dba01d25dc0a1441626c78e227aa4cc6790a0f0e464d6cbb2752d5029ccaac69885ccd2370a517ab4715af57de3abf0ee225698ba9064548c65b937ae798b6cdeb2ef4f49f0ae7cffb01c9d42fad9c46f9e288bf7c8c2b5a436d77537aac7783900f33b5eecefe6c512fd48c37ca977cb5c4286ebcc0b534f9f7c283eb305bf481df6f0f57856835067d9bbbe787332783b4d55be5e18599bafadd48ef6c362b0bfc34020918880bb21fe99572f06b3a293d608ea05fd736f1b6d07c874fc1ac18969459fca06ae2bbb5e462507f7f5c6c0c065d4a3e3a9630548e8cffcf8ac25c85d2d282324724290b74f9fc1ea4121235e611e3bcf60c4b320b5f8ac9d8a36bb24acaad56723acbd5bf00a42f800f24a73520bc5b3951d0be910bf11d18dc9ccf3c65fc955f99780e395f2f205c52a83de0f09bb892f327019d4d8589e5abccc6d0db8cd24fe1f0488bf18212b952f7211729bd131a87c610bd840a764ac05b1b3cfa464dda0e786bc7a5e588f74a9b86faddcd68bd8735b32b5a00cdbbf8112d355bd456696c1c85d6222b17ca58c7992760787be0af5de4f1233eeb6e5389c0803e7327156f60cda8d8ee2492b35bc5971a91b5b26b672d8039ed4406785972a8d5857981e537d40fe23226ba7206db13e426cc41cf4e35c8fc64cdae05607a6448009137f17a41a550f2e4dcff28375bb91182ff944b313fc0d7f29db53a0cf841c82109411d1b71474795d0ebd5ad7f28b8429b1efb137521e6159b489589a01dea988e2c895c7202f58fe307daa09a702e43350a1a9c01f9e318abde69f426e5272228495be7da83b9d25a45d9c195d5d0c86c1932155f2ff0036a3256059f2142e64087852fb3781ab69ba395203da12c5e3eb2a3cff697b1643f90d7f1050e138ee7f4dcc384fd4b1e1f42af514c428c3fd97b830e348d80dce0987ec4745a1bfcb1d53a791b80e416232c497e77c98a0494c2512a91afba6029d6d3cb5a901138115ba1c2cb1a5911f74c97368a47bf989f0f0501485fda589c76660cebe61c558aaa1a742a4539a47fcafbc2e3603d9bb68c8229c141d368d67b79358721bbc7ce011f0a094debabe3c7efeb6a9ea081c021784a4874823154d390876d78ded7c6368fe52e0b066fceb83da54e3993eda3df1757a17f23b43a0bb04ab533b0ad81f1a88acf7154dc8d6f7a56c7003b27cc1c32842008dd516b37841e6ef719feed7834c55fb513e2452af5320075fc35f064e7003144e1b3e0ae9d19c6716c2ed54ef770f3264c1cad1ba237daee33d27d077cc7cc28e91ee1143ea02b06b59ae29a884a6355d4de34ff239b0969c180937e7467dbc3767285064bc715a559acef04e5e6a70c59aa2acf3b6876b534fa2fb1e539207e797f2d8eb3fcfbbbf657da41ca11fdbf4dba3f00393fc3c184c76252ef0d3506432dfc70ae8539088ff98c9a5113d1633eba06a29fa3fbfd365120d450e49efc069ce8d4063f4293a20718a9ee4c9b49a3075fb01677d585e2e76e0dc62476a7e1bf965b6410d634f5cfa626f251f07051aadf472934b79e53452a6daff67b9b9fed9f1fc4f8216cafcec13070437c151ab7c37494c63f8308b96e8976256b3e98a046b8d2e1ad637f74135a29b377f2f202caef85c4ce0dc76717dd3a1ce727fbd29a54d3652dac10be44c3985df8efc2b18fdd17d30aab84642c28aece0799d24e2ff00377841753f45ac6f22934f7ae19893a0ad9d37aa80a45a8ee9d6f29b93f9a38974136bd9ca6dac2a3e9560c3445e953d8d404f4b8997ab953d3b53bd334b9214fe1c83b93f90dbf80e1ec9334220ba297c38931650aa9f87534e9001568aa379815f36ffffa31df45d3e500664a4e3421601bca9eb698296bd95d329dad918e181e68421eafd63b6b5dbbf4fb65554495c745e86628817d1514e0e949730249aec7b54dbc96a6182fa54ccab9969277aec66fe606cdc34b78cf1b3103976ca77c1ce57f98be9814c7645537df8098d2f5681936919c555ec0c767ab1482472e1e80e0a06ae8e600958625dcc028d5241375bfaa808a4eab16dcb212f3cf994a971fefa16b2a4780c6576906c64538711a710030b3740d85ce2f679cecc652cac4546db72d0c32d11bc3ade5f519ddbb01b1fd220c7f26ba7f53fdcbeb334aa3f601bc75ba7d565b670269629a0516fa1215761f5a0f2b9b11997b230a94489a911fff2332f8c5689a876e24a8bc0bc19a7d4d6daad04b1b74c3782d31c7fd155b5683ea37ee5abc007032190d626adfd1377c0135fa58b74d3268dea4340fb5790f8f04f6fc97762044b049c9a28f23622e482cb19650e1f7b5af645941623e0caa09c3451850af213fda1c4c0eaab0d9f5b55bba345f1dd16691c18ea564336c6165b316bdf0c0aee0f2a2bddb043cd8807640195fb91b4d6daa16363a04b3e9dfb3113b0344f52220b3816b1d6b28e545c8fa461bd5b3528f361a25e08d0ea1f945626cbc0dfe7c11688ac1a5cfa46613c3355ccda643c9f4c103b030344467b34600ef64ebfec870b16e61341664bc5a5dc567d19bc885c35df925c6092123be236de696f79268e1195511022501a21a6a12f022064d9358cd72a5e4262f0ed99988551ca2321184220d3a43f03720bbb8c73c8eab0acb9897ce0652cfdcc38337e1264ff8685a501ff4a9485abcad723af5a81a0fa0e95d6071d50d51d055daf433583df61513f9c2e399d53194d601e8866654c5561e6f109b69c94d72a0da6f090ee53ac00274bcde1edaa5b1428433db059265729115425bf9c56a4c223dbdd27e8467d9e3e35d02455ca51ee9f8e5391d3509a221fc814bce2f0bde2aa9020b491430b77fcef47a8fae8dae92f9885da01d496a3a6aeaa830210c3f61d9fcb2a343d851a57b7b95ec258d92bbbd4a9680c64a1244aba1ee561941cc3ec895ee8e326cc15d3c3d98a34fbe2374266f2091dde17db4f4f6ca2e7625441138c5b8373f3f5cda4bedb17410daf835d28419e9f0057eceae14ff4bc97cc42c58898c19c96e1cba836169ca114ee41fe41c4545cf83fee8dda225b04eb45fa7f68cbe21021c2b7debaf679c416a142df1d12471360db069d88a528c6691834602ef342cade1b054451e9652b9869afe26d0e83226f0378507a991b9a0a63e4b48da84933155b19c1239ee3413e68125b136ce12a01dcc626d5d4fc3d0c6aa1c423d8f2e7971f501d4eb189a7a25f370ea2eb9210fc5d097d7e88f83203a5e7b32a021dbb36cfbe3a1cd69154e6773c4c59cf7a163ce9b28a76d3124eae3d5a8d060da2d8a6b5692181fa76bd2a7704170ecf447e17e7b7064921de0a1327ce63e38c0b47d0a67d7f8f3a346669ef6900e79b8a0e05c3693915693fa4ad67741a96ab9185728840ccb447fcc0a2aa02588c419b85ef1087022efa2d3c9abfadc970e653b23531ba7baf2146d96a0c57c3f705d2987e2e015e2fde291e17b0e953c32e04ab84b85fa3be589e77d8b16e78d1215d8b927a51c2555caa5c4e0986052181b59715f14394ab996218c5620288b6339031f1568682cb2e68683092ce124e5a131c7bed06e99c9e84ef34ca87da5496a22c4b604b6448041cd5721f75b0301b6aa26bf912f60ebc2cc077b59fac0c187c611ad9eeebcc529340a21d6f70cc1656f16540e0068f7bd564991fa7291e5bb7085a2b12149c25367bc0e71867be1d3cea22e2651bd35501f10050dea81f7d490c6a42f45919b84a32fcb6eddbae834a70dea2b06896aecf812e0df163d505a327e73832d6e138eb70e0de88aaff542846f132668dc878ea27d3baa860908883af4435892da467f7812e8a690e7d11a094e96f8c84c8f66c8282bad18c17a610e2aa6e73bb39f26fb76024f56d58cba5c09342664825f653405a2de257c0a775cecd05cdfb6d270e12c50fc781aa76e0a8a83cef18bff34111aede5ff155e1a69298e935e15d43e4768dd5599ddd909d2de61a1be60040f00bea18dfe6b0f7984aa92aaefb55e90aee036d71d4a50b611b0041c55ac805e77dfcf3e10a028a4b58c5b280e62839dcdf1069aa81b7143a42cdccf66b46f0a013d4f393b5a744c4669f7b2c0e3054100b0bb0ee7b01381192c60194db1b3f594261fcbcebb485707726ec12e391754ae2b9da486b6da60afb5d9fb34e32af6a8e8e6d930fb8a47efc456537ff9fd163bc32ee0a4c64f7e4c3015287c1570b9ecf2d17631ae44e07a3d0172625cb2bd8f4e1135dbd6831a562f755fd251eb5260d49aa158b175fca07cc19cc671a8d58d9c40809638e7f662fbaf38832ffcae4f0ffee62988c76435b820daeff3f3a60714e95ea04ca5415c435fd5c86bad21027a46fb67a7e160bd3da10b24bb9def223b62577c57c037afdfe5c02e9a18bcd8fe9f8330d53dd58b962b615ebde5f359b3880856b82597ca311dd6364f947840eecbba9ec0333b3828c04510f89470678199207316eeb74c2d4c86e2cde91e4ec5ff1960b25f2b830f4efe81e743ba25c2169a8e66eae8ca8484e06a3c69ec67e6d836373048c4995868483f39ba2ea311f3bd3477115a7541b372390c8b59f1ded4e78feb5622bfb1eb4c44adbb40ca3a985830ebb001d5a00bb1647cd639464cdb228e73cab5bc61874b99d758ced895eda19d8bf9e95c15a9580ae57239cd4ce3cd4d694dc8bad6b7beab126b3f4123fe3465cba0be979f4ca55cccf5d7d7c9cecea2022264b00e5ddb613a16b7ef10eb87fa58da18eb152376ff3412f952136ace0f524160d05dab881c2ad4fb092c82828aec5a7ecbde5a150fd8468e7f9caa726b086cd339635aefb3a4e2bd71b949e7ffb04df477be201d1b2160eb606f1f17cbcdb4406f8bb37f0fdb3d109d54da98753f8202b113c51db7b77c66d527b397da4fade4926721e34bd609f4cfee6a09c8b2da2d1e6dcf9964179c9b1b415e2634a817ef59c55db439705a2dd2a0a203cd9c5490eb6c9b0b6c90563c681827d8937549ba374bb0db2d6ea030c96e8f38f65bbf702f0b2dd0a430722ed8f7e7f74e26b26a3c5b0a06866740ddc3c95c8e16555d0dff51037127e8d6eb7eec2a20ce709cf366f4e79aa7f897d4f97ea5013e51fb1f66c53b0295cb08a44f7e4ee115ef0df9b8a9fa3257e8617edcb270137a10ce5c34f3e2338733f65810cbc2e8c6f038b1b44ccd588f8e46a99c552c3c070d7696fb11497097e2c9460e937a727fe0ced8083296e332bd8ebd35203e083f765b24a759d35ce0f6943910859a770daf21ee2ab41a9bcea5fe8035a47fe9fb756c513d98d5fbc9b6d2bc32be4cb361cc5e82dd8f87ddaecc505ad831564c2de31d37bbc060cba80741cd3217945f596e4b38ca517656316ad5dd237f0dc3e42b00a24cc986ed0564b5a3101abf4eb00cad77aeae11a6e3d99ce43653cf8989f6a0f2714bec9bbcf4e67bbb33ee6259c76d14d409ce6414b0d3473e818a79b2cc5e8f7f815e73f7983d8725a9db633940b73fa99aa5aa3b30d75c4ae7d30d9a5a5c6601930713f7ad8ed88dd74947dc8afeb1c25e91068aec5f1e19ec78082def51c38f5e2c38c943c809fea071559266cce384581148993d909c66072cf3d033a7033e8a6e42d3f36b0cbf8648396d3ef9f2c4e8877b9dde88af45174a517da687a0f052fe092cb6dcba6fb774302908088fdc804fb16b05c54f285078bad653cdaf23fdc75bbad4ae283f3e8eae366dbd6b7183236aaf1f3347dad3ab262bfda3ead201989f7b57feb442fbb869efbec9a55a560046ae586f2a97444082671525d1ba066f735da5b9b63d0ea360fe7faf9316af87920fb5f70323dae78537f854f4ad1fcaa03081d0c4d1b44eedbee6e1652cb8053a2d4ca0f5635595502e2a46b136038429b8c5c2aa9977443e4870e03bad4d2d5d630a85ab55a3a88bb268d6b7432e11b146c7a5f96a7dd728cd5f89d14633dcbf07ec9204eaa8cbbe572056aa9a0ef1b3b2742fb0fa03f603a4aee5adca5f20e386fd68cd55b17abe11f18fa08560425bae68cebea85efdcfb3e52bb025fd04a9dadd9c29efe7bbdf78a5727b6c442a32534b1ddbd6d496ecb6b6f79632252903e80ba50ba40bac06cc473d50ab70109163a0f9281c34457194b68a59f56766cd40bffe0f88593fdeb380bef7a6e82920f43b658314bfffe8fda694d3597c70356cdb62b1dc4848a222963fee3f2a2c0e22d851de28117f71468e4c40f674c012993e1c43513df714903021d94a543d376330c85665fc90f188e08ff28cccfd77ba53fcee1cbab329035ff52324f47dea8550cff22ad52b1141107cfaa00a07b1e069f317f7a80f4a6125e287badfa5207d90fbeffb1ef59482283c8738ee9bb253873d3c655ee4adf1c907c24bcafdf376c0cb3e746d4c2196fbc743d9537382795f29a5b41be39882fd1e7c0e85598e59eef5533888c8ecfca12e4b7e2a892583240af5f2513888486220d4a7503888a280fc84f36590f98795dc7102a5bffc355940d8bb2c20d49f4ef886e6b174e5de59a66e6891c33afe92af4aeaae449f747db11c7a779ae2e95a9d2facccac1fa1fef92d796616fdfef414037941a8f75e892874fa0f4b17f21ee5ddd3a58f7a25220f8b62960da7f71ee8e4e120228a81bc4779d8fa8bfba06f829c689dd816b9837ebfa84c7225d068b4293722f44e0f7329177989e3d6c4b4a4947464f361c6e4d8f39bca2073ca7628fd0ab068ced90d468a0aa5b4d6a62b559aac745dd7791e1ab52a683099b70a1a4679d5e144238bbc9ab70a1a43c8ab9e5e0b9a867af04d010d9d1eb4e84329bf062177a40791e75ccaf648da5cc8f2795a00c19427258fd4cb39e79c9c0c603efd696c61657754c8f2bdda837baf07eae5f7791fee8cc2630b4086fd9cd7df63fae8e91f7247ffb8935b82c153b993d761bf3d64389f4b43f638ca25cbc791db479d11969b4a39f13893472bdddd5d762c6350f6e126fbcb00e6eaf2345a1d323b82b9ed977d986d54ec4310994c81d498dc31bd096708b98009317c6085c8082dacbbbb53ea5426512ae7eabaa420e7d456895a81f528df184c4a605049b24d9162548be28436d4640a4dd9ed8a95a6a531ba503aa2e2e4eb3ea20dccecf22451b293d2bdff1e7c4ec88c4d190b45b0e38c4d59cc1d96b2f63f0c27b6a1d502eb39ac13e54b4f01f150a81490796a54ab05f6f45ffbec54ea7d1ae57f721781ed4e4c6121fef2e731023bdae730a59c13e44b8b3ffd938fc35e87a77778747a74d83c1da2f0e8cfe2461ea9c362c141e0a75e89f881d2e67938b03ccba5f22543fa635046bdc4216d4900124e16bf6469490012a2742833776d872b5b126d54d71c7c9c33a196fa5622d2eb5e71507dfa41fdfe4ac4cf41bfac795913b36cf0ef1f42bf622418091251a63680fa1ae67b414440feaa77fce32feeb90fb31a50df1f087c1a44f4e1a0987f12fa4874de5f1cebc33f00d507ff0629aefcc53d888394884a4415264afafaaa1f755e8a2aec538435c37bcfa261be27566c63442c1ab2e7bd878b78ffe18c840888beea91b0bec748286675cffa5498d5e1131e5239141e42bf9fc8c3720901dd7b78034ab217440444dfddfd1d2761797feea5bfdc41ee8fe49312960d14a83efd1810a5943ec549589e7ee59e62d92f8c412087640ef9c4f28525a9499b347f71dcbf10ab3496f7f56df030507d6701d197a27798c34566d1894895a3089eb52b1ecf3be7b0876587eedf94045de6dcdd391f478ea3dc7b1dd2aee3bee3be4827a9e7755d877bec5ed2ee69f7947b493b0584cbf3698df2499774e952ba5c1dba6060fb471b9a1d6d7bf7c83e856d9d9e8de4dd537af744e5cfc13e79f9ab20953be47760e5f2d7815c3d819ee70f059e3e1005821feac422a9120d29a5f4a314b79c5d37e7a4a0e7469f748d769416e6854e9f4e29a5547e9613bbcb59b914cc3961f29cb5dd51681031e79c52da6491ecb4b6bbd396d6d199754533b650297be8083ee91a53d46335362876f4d85196f43da9e6a3c76c465ee4d9d5d7d86c79ec9a3cc6c5fc45ff34cbf444cbf454cbf46bbc3c7e37141032fdd1f3787a41a63f764d3fdfcd5f4fecc8c56e993e17a3b645b32347cbf4a9c768a72c73401bcaa3c792523432be3997d8cfd21b57597665d0ac2021d3ef9875fab30d2b60e439a717df51763cd6ecd45b4e1a0aec286dd30476a443cee4477ee4477e94fb670aecd8b159023b97965869ab62050879bef4ec2ad48181ed38aa845a2bc5deec6ab2446a4112f2ea8ba349619e28796459e5c624bb6459850968d8b98507f64e07682e32bd6cc45ff36f44987e947ca80d48acb061821898808818088914ebf82b05a47b927552905190c7f0491e794e9047796482dc95208f92899647792b628333aa88918510a2388138491000368a88410c84c858c2429cff0e53628411b880c20a95279ac4f93a0eeb418d1c58a1c610cc407a82e8042a7ad0c5121334390115e2fc1f8749329a78c2065c1c618829ec409c4fc461048862850645008293245811e71b719812d9154a4235228258029338bd69133e155ab044138804ca14faa0f62e2fa69022828b0244820825513441d1148232ccb0c2065e283141954220d4595cf19674162c682a05c9892cb809cc94208115319011c500c90918e4962c919c78b2c6f785c005267840b931840763dfc24061888e895d59186bb358630913bb9ac91289b67402a3ec0418ec8e1d3c9a60e5cb8e0a1624640a4e45e8808956c4fc25a6b0c9126989a2fc6589b4040ab6d08101820d6c10cc80414bcc7a9655cc78419319443142d8ceb28a192c9842984102ceca14ac34a18a130e898984094e2c109ad189c40f28480399d4220a149c617482275a5c912236454ec0cce70aad0a3676e0848b32446e3291b993109a9854a86ca004c735814ae6baccfda0886e04527cdd0890684e48339086c0c44509aa18a20ad1756eb24422811a48244042ed62e49e8a8a44adb5561a861494133630c2892c3c1a46955b12e428a75431e3097f1d30cb2ab72cb22acb2a372f3822609840f07e06d41e440181365c4006164458e1822a3a2773befd2c53538a4f8e3a2218537c411b01911511884090374cc1b96e2b462a8861a568c5030bcbf25c5d0df34ccb00c27c11e0f0cbcdecef9282937368d8c4c2abfc204af65af61f7fc8a3ec5de864afb5de196d6ab57175e816c666c35fa5f1b5883342cbf48cf186a13ef4622b75a9554ad488a2b9b7789c759fee2a0481e594fa2c0c6ad1f70c04794461d1660fa594274b592bed6696f573f77a07e55e4f3351f0549d949c7bb89a415377af776453fa02da18e1f9cb613cd877eb90bf64ee2ef39cbb3be5a60c78430a29675618c26ca795ebbc13ea03532c2adbe2f202132333b3a2a961d9c8ccc8a87023e6c60dcccdbffce5a0b864f9dc0924ac26712ca84933f36254d2ac491c0de5058a2653936270cbcad96a499b2a4b99c5f460643c5ae0c2619939ccc747066726079524032325894a9233871ec91e3a933d2e05460b30721ff9f8f8501c21286d920849f74b9a12c6d1381a6744a3525229a9943ae4c10218194773588c4ac96152f4acabc2977ccf7be538e558c1934d72c7cc19332b742d843a3a01087978421ddccdf1af1c619863070bd57b28e7b0ee24ffe423e4a680fcf840c1ce6f99b13432ab554ccb9ef974ca53ca8799bda11d3c74e4d14a4a2136994fa70590725610c1c7932d0000f4c2ab49f5071206b354875087381a0eb27c6a83598259ca5dc5aa524154c82bc8d0c8fd234793a14d53c8c81e090017409df0f5d7769241c2544adc19b9a5125644b05e644f6ee12a25152a49a574230a3b7b662513c3cdbcec91304db479ccbe530f3c8f761ccdd569763e7deaee3c50e0ee1e95d246b1f3c1c9e3899def7528dd4fa31214119cbabbd3155849e70bdc9d52eaee945277a7947e2c2e30333537626456352dd4cae5e5e5592adce0d8504a9dd65a5b75add6b4e8ba4ed6994a5da80b6e79ee920242a54b9f76e1d49a29086887e339eed4678d6d515bb6703929b9b83c0ef7aa91776b51adddaaad2db496962b2787bfb0a854392056c3be56705a650d3fc1ceaf2d95a668ea05d2861d713005c48f38acd6662cc70a94aa202baeb5140d4f29a5b516e446767c52a2c29e50b2e8a3cce44f5082524e4f0556fe689bf8a46b6c69da7d580d6b5d4029cb5f4d8b0bcc0d944d4cc73975ca751c751b99191a970e3077837de240d98332d0e6a895ec8d1aea5cd7c2754ebde36edc7837f2b99f9d57abf3439dbcaefa043947a2422eb2626473cc02d69b69cbb03e373b0e578f06d52d6addc2da5fc38ead44b30567a90b0e81b25a55a92026f86e1ec7595c58f5011ddafcbc2d36d6ab1a1df64c923d5df48e634ea8c3e664398fe31fe7c6dfd8bc0af5e55df2c45c0c498958964fc1af7504ea4e59589ec7206e052a368f5c14991a5899e78c5c1373461df68f5c11d76d45c5c432466a099c3e5d7eceffdf781b30f2f731416676fdbc302f5ddc930edb276571c5648febfbb9aa9483c715cee3d1dee0d1e354c03678ecfcc2bd74f91717aeb58b1dd8512e4de1847aa7251634a5dc6ff3fd944aefcc0fbf9b26b35afde8e5d5cbb4301eedc5e36ae6c73efa990222e38468a6584e86b95887fd29336c4ff9f01ed1bc47f337f068696853ba6db0ec108f358f625d996baecc2395d1d51d5d7986ca643f50983bba5eee0f93e362b9dfe5fe305b92925c79ac49ce543beaf78b831a0899ec99474e448719e548d34eca33099446e4b6c2284bc95c520ad480e91db7604ee390c2b338e30ba9f1f9de61125b8b1b9452be66f7dc73a0a738e7e26b296f10767e83f1497715b8953bfaadec91f3069f9cd327ed39c715a51e766125974610754adb29472bad5cad7808ce29a5b48a2a3cb9e3e4814cb9231ec8e43450d94e57dd3dd751a74eb90e01d4adf4ab9dc909767aad778ab329cfdb0d527429e67881339de40ef9aa270f7872e9eb814e0f5884789280228fd22693a592a4c2832aa93cea38e20ba45ca1209106931a247144ae3050a4de4cf623a464973b5c12b4dcd4cfa048473c5141c18e56a747c3266de61184f94196a38e5c7be4fae38f5c59c82ac83508b9be47441bb9be5d45912b5211644824590d8c5022d7e71123d7f7a94846a49154eb1a4db9d65a6bad2d7891e97bb7214a90e9775656272c753252106283abb59ed184aa3c90327d0a849332ae54b1a40512142b70c20f52b5d65a2b151a41a631c8242d84600291104738c208b1aa20d733cac8b5e65a6bad398460471d1d28b83c1b988293ec0929304d3193c22c06579a908aa00121891878c06404264b3168c184240413c088a107638049b4ec80074ae8c2da6459850769bc44c1be6459a5074b7455b8a0659a65953180e04ad467438d366cb57a66418aa55d75926308169c43b3c99c4d5aad774ea793f7420c50ffa777ba5cff88cc507da0de915b3431c9f54aae5e5791962891845c3f86de7130726a062e8912e4893df9198809c3599ba2817b9b0e576734b93a94471d7e23ecf8b9b2c2aca3c3faed841ffca83c1dd637c28e3cb928096e297b77677f1ac54af6a74a6334ec469323c5c6c86eb3bb2d76052c420a6296470ac648a764ffa61dcb9ffba0bf435920437fc91d5aebd05f9e8a44f961eb724354c82e539f9c144e4a2d940203ebf22317c50573459c94919341f6cf61043bea14392c7cb7ae1f57383f7ece8fe18f3a21c681c39cdbe334ad5c98a37135ae8833923db6de9148414821fb73537ae7c5614a44179f5ecf491d7a171d5e156c767243d347cbfb73495c17fd5c1313e6329f957b393d9697d33e4debfdbbc8612eae8b7ee186260fae89f99a346ff1e836c8aec2238745f6ef58f0c8cd20fba73c3c722fc8fe2087476e05d9ffab78e44c40f1c84991fd4f5c920a52d891362773d573df511a569bfce55c1a438ca184a529b4d6b4e6d19aa7c2f706760429cd2cd7ebb0654c798ef396615d9b4579ce245833cd39abf9ffe68f86798f3c75d834cc8ffce53f5b38effaf9abde51fdc478f4ee2dd37f712e068f56068fab0f1f8f3a3778e4c9ce84b1cb8e1c4665fef25fbdce0d976557018f9e0d1eed51d0903b93124fd2a87314cae0f1e9c7e0715564b9219937c44471aeeaba2ead39ec878d7cd157438752b15e8f4c7558972cfbb76279faa061e619b8a5ef192b1d764fe9ee12a4d4bdfbd1e3569472553a953d2567c5275d172757079c3a7c7dca79ba79391e8dad5c666005cc1317c09061b92cabb4c1022f63d50612b9cbb24a1b429d46d10d2d82f388095be1d4e471caa6cb7c5465c1c1fc71d56ea443ff1d3a6cad6177e82e918b4387926987a321ff59e4b0ef57df14692acf5976d83442be441e972e53b9c353a6238605fffba09e14d8a288c544107b33651421264a9168761e69ff47c1bef33f26297aaafff3c0914eda2c5052dfa921534ce1a0242288a7ec4e5b91bf7ca89643874e24a5043b4ea9e4596f167d5b8422e3932e2c869d7406fc31a67a3f7259d61610f3e01eb9a3ff43e56fa67ab46151dfedb444addcab9cf4214169650fb8f37d67d4ed809751bf1a808421000332033d6840f238ad010539c3514621f70b9153c8331c2711479e0a82f2062064be3a4806e48efeefe4729e4ea73e9d288a85be4ff32077340b363b73066e0f9347ab7113324a36727fcb3672efe0030b43eafb7320f2de9db9937962eaeb8522b3628a6228b21753d89bd9d1cb766826552a79a4b9e7f79dbf39c1965c0a08573393a67475383bd3940c61763c931a4af760129cd63b4f7aa762ec4ffad5b30b999d4addb22c9b054a37648a1d0e4a22cee94fbce6b40edbf138bda896215bec993029a70f8a82950f240f72bf9c120b1e37c2d6efdea75563a86e4d1d766b0d3baa9a72ab6eaa2667ea37d23bfd401cc912e675dfef237b288fdcb25b7e919b0b2dba67e6b0910e1b081fb983059be5b26c31f308f3171de6f1974a0d27aceaa66a6259d264631e934f3e4bce2cb14aee98df796620aa3c5fbeec9107f86cdee6a394521e404941eb29f8a46ba4dd6afae87058237b26ce217754d4444954f7a7793a9d7c708ec6a60f8e2ef942eef4ada520c3fa304f8b9452fd5405b2cab0fea8c33b7d7ddaa47766bde384d27ae749ef784f8b60f0a8a357351566c134208d4d500c3b8eb4c8003e1dd6f72b2486fba3796c9061e8857dbba16e1cc5dd9f5cc99572c89ef9f543577221704727afe35027af7bd4c9eb38d4c9eb38d4c9eb38d4e7ad2a618e0a02a95fa77458dfbbe24ed9cdf7a4e77d373937923deda37bd9b7e9a3c3b468f2a85fbfa3207b26a62f903bead7ff3850ce3f15853d5b38b0f406f3e2d2dd644216eef4a3471386322f1f58fade4731302f2edd51d782c75fa9f0682d883f8e16d14e0713cbd3332f65c115f75fc76ab3acfa99af4f552077e81732ac5f67302df257fdefbcd3a38a74e491c66a3c8fc6dad56a3543bf62aa2477d4262c7d4ff25a7dcfdad57f65323232323232329a320f654f2befbbfa1c0efeaaef79ab955452caf514851d69514cc9c87694a4e4032696a5d7728dc6640e5322d6a7430ea3a2b4d5a7b4a735d93373a54b2ebdc21a272c860fcef3ac5dadfe431d1f4e5bfc51fd7c2e15a465b34eeb34baa9d1f05ad8caddd44dddd44d2f2eece8198da7d8cc3e3d931c760209f364b2a704d28792c3589ee2d1230af1e8d55a3496377b9179d2546f241b86991d32dac1b32baefee7f9e880976b7d69247b529e67ed8aca78704e31ebddd0e20e5fd86f8a1d3d996784849d62fe92c99ef9ab12c853cc8be2146322d3ff62a75867cfb376b5c2c9e3c4c9238f27f3177d4f265bdd161b0cc3ceeb357fd14f1565fa9ecc613bd01cd669c817fdd5ca5a4fd652f084b0485027e88f530799fe97b2a14515769abf287dee361a9207fdd60dac7f9f5e49b6621d489c52364851f532f503be4faf6cf6a9c7386c9dd80f04b98bcaf57e4bd8b19bbaa97746c9a4aad23699243ed15e9c4c165017c4ba418a5e8759f3adbfa618d462f7b39b7fa518bb32f4e4c67ad7e4e27584ddd3c791c9a3878e136c2d1604351c84a1480a53fa0acf8f5a1e67139e187c6c35b4ac490806981fd43bd2b674458dd93f404939e0d0dd6f8d269bc85d297e484936242a61e40f4c1ef3fb06a1f9c8e4317fd6666d4619234f9a3c7f2a09606842818a6c4ea14b5060238f33291585136459a9cfd8d06dd63ba38c429ecf22a24333e99d0e4a935a631e4027362700096accfc81e9c3318d14fb79be910ee71f993e68536d8bc6952b576a000a0186ab97747bfe373aba8774c997fc76eab32758d1c117052bfd5fa7804c1957df3d074f32ccec79728794a1ab184a477192ec180a8765dfce65ac21250b7068a98694832679a38229d3645985093639012b9164d0946db24492c111f953b17e3e25be42cd07fa1e07115116fd9f1fd48dfa5e89f83aa8079fc3a365f951a78a524c3d37bbfff117f7c30d521482837c1e95d49805f4c5c0ff7e62a21e4496e3ab9dbb7ae1ae7adc950b97060097a6854ba37369785c1a162ecd8e4ba3e3d2ac70698e2ecdebd2285d1a1c9726e7d2e05c1ad7ad89f9abff6f4deb7b295d007f65847ca11f5f21225e1422c28a52b630522ba40b2385411e636864205fe89734376ebdb716f9abffe656a32aabb93792582d911b06d48a3ce2d90f13c715388e6ebc4cc9a042cc8e36339b273587a9f0364f3a6c9bda4ac97a1e6d6e5c29d2cc2214010a34a2ccd270c2d6e0a0f98b16c1ca6e32ebf0bed7dcbfb176e6261d768cacc366d2613780f534ffa51a60f337300be8c67c420a2488d15c1610cdd77c0d0e92413843a47925e247c384f5fc34c90525ace7b11e359ee1a0d1e41cdd50c1083bc6c8b0cc61377fe3476fb4313187dd603cb3ab235879f2bf52bc71a5582fcca5b952b4b93194886b319438622a6c970a426bae1469ae14698eece359ee161ea064a681a6e8620a4f701c31dbbba5aca5cb889c3099ec40643e8e22664e67944e2793368fba984fe6d094328da6add2dea9484449e4fa3af48e5c82e319ebb01ef1577ddc8495484d5cd19202322d0e26769c33224b188a95484dd032a76261826d422805e6b0c2327d28700ddbbd4462824ae65efe89e34e2f330abc6008381a0642045340a008621c575896b872054965225fcb0b9bbdb0dccfecfd111dee0e1d562234652ce9e0423cc54a24268a32e74d2772c97b22bdc342bdcca7399b349a654149bd14c11fe7d5e9e1fd389d304f08ecc8e3e3affae015e2affa3432fbb9660f03d59fa4da6589e484a55a1f07c9c35ccacd71f3a58a4f051e589ffd2de50dc2938f844fba3c1c52d8511eadc0882558e4495d4b3c161c52582135485800e40c72870a41064f7690a7b4fd90302138dc0191fcd93ee02ac7d59713d82e4b242666797c1db848b1354b24269c50a24a29c7d95b7c2de7e468e6169e5d652ae58e96fec4e7b3a5d3e9a392ec1d31a94f7f222f69138124e78dc04b29695359a7a4799e770513249aaa3882e94876c42c2909264c61306152431a5a021148ccfc253d940d74565d7395e32a8c1ad625cb2a48576092b650c2e5b6c514b22d8866c040d1f2046b38fb746aa951c8d7ac331e4cb033093bd43bf5bbce7e00c2cbb30e1109e5117491de0e78d96f8b75e63039c6e4b1cebe539e31b96d268a469b605b5bd82977b060b34ea71fe9d0833af42347e6dde11ae990498adee9bd3924f36982ec538a268cb0de4f267348270c2b8f7ccaba6790b0d085c81e3a80ec63cb78caa33c62c166a93b0b94ef3b35a4c5ef51771ecd29d3d6e190dce19f0243874d26e4cbdf07904bc0f3e129f31735c08f900e5996588f05df0c93f93fdcdddd79dce93b1edd3df497f4bcd5aabb714b7fb5926ebf7d3c3f7ca44ecb0fab0cb99fb3625a41d0e5a04cbf1bcb577d548e5cff7f04c0016c9e9d6b12d5af5a90617d8186ecaf7365fd16103046e055d2615e651169e3aad0e12aad95b634d95396484355bc0c61bf2c91866a5a7479d471e29086a21862c2042dcfff78dcec0766a3a08923f27c3997e4c9c3937d78faee60a443c924a5fe047ffe1187713f6bf303f1e779286b4fab95f7dff1641e87799eb5ab556834a54c91de398bb899397c64faf074389f6589953ff2d4ae4a1023ca9cab2558886003e248ef8c3af2fc69d4e1acf96b823de7120f3af43b66f5cfdc78d65ef36ba08099b5595212d16187de1972d2301b1e6a57f2945dd43bb336a5e4d9ffd323cfafb7c7d5e970b60e1dce1da6d831cc93e52f73c3ac96a66c72c9a5ff0e05df0cc2ce972d492d989244e464b504cb12ac0e111d7e6a1df69cf98b07a72c9196402553b03d296c0e1346206a7d182a66c9773c9df4abbf060a4bb19cac391da8cb2d6d96729809e5f69913f93ebd23918a64b93f86dee9e1ea577f436171c02c5360b8167cf23bb42a6995cc24ddf3f6e958816d4979d2a54b141e95784e054901691f927483cfeadc81ce6350eec2702faef08a00c294ae880e69092294b84289f8a4cb660973b5f37d3108f109c2ce9f5eab4f6125d62177b8661f8196abc702c5ea903d33cf20c741f4413c83ec3b8883589ece5bccadbfeadb771ce48f047c8ac22a1cc48291a4debf533dcbd777dbf22c3fa4e559548fc4beea87a8dee55d3012969f16acf32ae92f1f9d1e6cd0af5f7f84a86c8a7449128a9118f11726e22fb94463acce31ab1be24f3112222096a78fc4bebf86d0f7778c8405c9a4f9abbe7fea413c87fc555f8ae38ca570d82fcc077f0988299e2fc4ac14fd476808fae00fe19fa20f3e907fea7d9ac96129ccea5ef54d0e0331abfbd44bb1b26056f72c2fc5caeaf08f7df0a5d8a4c3cae4b3c95ff5596ec768b6b03dc33dd4617d9620ec387b6809fcd14b4d5bea7e32f57ddfddd3a3504afa4fb748f73e7e5157a66ae8efb8a67d4bdc1d03d1d9ddddbdead4653fe1654f90f668f87e82299a5345be57f1c0a6f84a5685e791bf5a6ecffcd53fd97bbfb389d290079d7aadcca60e5b825c7dfad1ffc0d3f5282cee2e923aec9e32da5a6458966ff9ee19f5ea79b999624c4fbce63427eea49ba4e84c3e2b4db8993af41f9ba9873a9475485dc84614c4f2acefdbc86116b33e0ce5e5a568bf9fca3aac42fcf5e3af6e91220bcbdb1fd2f22a8c04232102527dcb23092202b2af52c5543889cbabde6220966fc141442a8c24b4cf823d7f893431db36dc46ab36accf2bfd427b2ee36a090be609632a234dc588a83e0f3ab985b2145b2896376958eea5147b268af3e6d883e95713d963237730cd261c37b0e3bc19cd9bec9141661bb963b6cab0631b11fd2083cc3d86dcd14f03fdb6b5cddfebbadb543ae49a8a47d15432876ba0184686d6a1432264d8969f4794eb3a1504fc540ddfa3fe43a540b05335744f67911477e7d70f36537f1b7553d923b327c53c3b67decc5b68ce79f39a6a0dae6c1aecd6129a699442b21e6aafaf20c3b60db75187a9302c87dbc8ae96b0bd6373184b101150cbbf4dd55031eba78d6c344256aaeeed88bf7a08244432c8ecaf219010391ea1b4b4b47c0b4e8264d65a5ec6922099b26f1925d312173c8dfc155361d98269bf30dfbeea47795ba2c273e62feb2fc7de6cc96711d8363f58ca1cc7f1b8591c18c91e96ece9ccadbeb05c646e6a91b991875e3153033b6d144fa31af73a45f626f3705fc510aa3c31842198d210b947dd9fd3fde89f7ec8f7278c840889f71f1e82e4f4282c45f7fef43edd61960da8ff1e08f51f0e22ea3e48ba0784faef3f91be8e1756149a18bf4c0e6c7d29e2d0a8388a89fd53a943eea3d058b1b3884ba9c08e3a3a0eb381e37e091dabeb8c7a6766eee7154c999b6a348cb534a78cb30ba5cccda5cc4d2b99ebe4acf58eec0194a5ccfd8cf2d371dca7626064973c243e1d3a1dca23a1d3a37e1c76fa7e210e43b5bc12f1047e0b0e6a791023493dea835cfec3488880528f7a242c7f7a2522121824dfb7e0088285f2f2484022a0ef5b5e88c35e30cb9f882912b1bc077a79f0bb9f22cb1f09cc7fdf1eb601fc970702ffe5fd91103906fa1ee69180fff248883a0c0483bf47f282756416c42eff61960daa7751bd0b0bc87ecbdb6f79caf22d37a574755c206aa644f45930cbfff4e0a7c06739063a3dc80242fd8f2b2110f3501ec29612fc25797440255d7347f8d0cfe775783ccf5623febab349bfeacb211dd85132e5c8ecc9f3c2fb52ac91fa3bf4ce4824d35fadac752cbdfa54ca71400031d261fd1b3eb023cf9c1cce40189962479ea1f6e1f9019322153068b33b29b24723b90810347bdff2bf2bc4f7e0682417f1613665206686f2814fcaeffb79fd8b65eadffbf4d712871dd607e2e14aa50e6a69c751a9434aeff6a043071e75c8eeee80f2093b28bd7b1e74d8de819977c54308963ea177b4c9f527ad093072e81db0e688880e4cf5757a38c9f57fb4011a36c5fa524789a23c8a15268f1614e39bad23d8feafdb9b5229dd55a094e4795426eb29bd473d520e98e4f930405645a024914922d138b3cb73e11522fcd77f453ae019ca07c27fdd202562587f421cfebc145fe92f10c4b287dc8777082522bdb3681675d82efd3ddf3f074e722bcb2a3c9892270f47ee182bf4c09e7cce29353ff22093327d943b2dcb241f64cdd71e64521e9514e522353f47254579e2c63535ef1d75d854024853dc72bf8d6b67be3f8142b69325d213b6ec42cb54bea44b6374481f7cb94134df3fd3b86dfd02fd84709648505cc9df7f94c72d0809eb21f9a24f3dd38622d36f27246c2ef98b3ea5f4712c81cd247f7d3b6097c424d3efa9d43b63fdd3d351498c39bbe890a63ea5ba2f0461bd9729ee02d1347866cd504f782a29c99f0c80fd50e0cb0da2799987b932d93e8512f33efdd337d9a323ab5439f52925f9a29f7a29c1e6543695ed599ab0b0f8cc69517c144521cb2ed2776961515263a9995a8dde615930c6e89dee894cbfadf44ed702fbd9b0ac5699ba8ab0375922cda86499fa11d209c3f6c3bc8e133bf62dd3d5ed5b3d85f9197fa12b4c9bb07498dba83cb692a525c8148a0c96bd18e329ef5373a943ead5facdc486a52fb344826229d3a6dd6e6d73286c9952b15e1972a1be79131e655899aac15ba9773a04481ce40efc6e14991518621ef56d8bb1d23b5792d6580ac0d21335f7a5c9d421d5e94194c77ef283a70667ea9d3a46a7807ce083ef799e973d7cfaaa045ed59faeea53aa996a52e990aa700fb1dc6e2202bbf33d95b948f7a7a71c1e93644fa66800bdf7e91df08b00d17972b7480dc2fda9bbe32cd27da521e57dd2384fefd3f344435287347c5fbfe2a9d4b1e81394b210a4d91559223d71bb9125d26c8a8cf2d8185d64511b838d2ed868425a820ad8a329044c63df6a6da559138d4aad77c699948b8c6090bd18d34af49d64fa72ec279946c9a34d96634bc9f457365a83734fbddea9315788c87b225eeca7b94930112ae676937e39a1f5930ee967c1ea3dab7634ef48a410c4328dc9544ac374245293a64c7fa849a6454df2e8b44c5f5639838a3c7a944ceb779cc792b49b5097d9d40cf4e5b68ac0854dfc5a5a5240bcef547d96140d3deb268d69d667bdd3b7bed24234168bc568227d1fea9d8e0599be37913d3353cffb540a88e779b2dee48b7ead3908828decf54d878fc84ca178a87887162964237207fd97cbc30b2c62344aa04e7822e8c8137694b721feac212fdfff8283e60870202699469021be7ce3a0191c3491a02226e981428cf924d208e2cbcbd490fe2056fd242f2f45d690d5cffc0a07cd22ae10418498a4b5d0028933c4979fc14149a614b0183a81f88289b897c1418ec5172b281293482a2898c10fc4184ce47595f6e976779b3563ac19a42d732f6d99c353a843da432b1b3563089949f72eab1982229571835c9b7873e8e6a443ba8652aef8c9a47548270bf80253dfa72795dea998356b1d46f9dc0426744ab9d9711665da4f5340fd30578a2f578a2e341d50ac2dcfff1a9c9ed7e0c4416776dfcf86d09cee75e6fd2840c274a40df35d90b01f1fbd435b06f91d86f27d7fff5559e7cf7781fa359fe606b6e671d66c7098b3e633d97363d2eeb8a5378285c91269891a799cb37abd3c67b26766f92350879349e69eabdd7f9d9c3fd09973b4ebfc027538b9d994cd3267b32124cc07f99ab227083003216133169bb33a82747acff29d7778f4feafc743bd3878995e201d3a9c32c887f2fd8fc33eaca393672a48e71892605fc72c0c6d315034b560cb2d25cb7f1f703fc9587a87e370119bef7310c4f47e4749b0239ee110819472e766f6b19c23d993fac7a9eff7fb9b59079145d031b247758f3b2577a4f09f5477ac4174a80f34651eea5011ff99a1dc789bcb02aa799bb7c1413eaabcc076630676b4999dfebb712b957ef54bf174bd2c53275c8f686af0833ce21a07c471ff87a3096b63836f6a374572c6cc723fbe211b65a50965a543555387aa25d518df04ddc6608a6ea2e4be29ca3db39283306af3088d9bd5dbef6666756f68374e6e6635b11a19985fe65be69663de490d93cdcc867663646363f39382dc9c6194306e393803470dcf648f2ad7dc09c50ba4c024831005d7cdec5744b03730c652e8d7c8644feadb0919762fe54ecdd05833a331923dfe2cbf92c91eef6d661fcc8f354cf5c82626e684eafb6b8654df2f3fd6782d3fd6cc5cdebb3833b9a3fd6f6237b36c632f31b9c3314c91dc814a4229a196504c1765a5c33e3add544baa2587a96caa25956a49a50243f6ccdcbf52b2a81f5536148e1b237f51d9d80fd3a505cf626435883cc6c83c39852e38909b75d83635342b50616d9e7438de70e01a91a906d87c0d6601d57409b07872136b5e8978e36fe0a06902216eb09a59bffabb9a59ee77d23b9e7d30a2811e32c0439111033b5cc00215d08102139000910840e0013938a0010cc0610143140094801b6cf841c0016a30000d059841880c4180c44000b1957d060083007ef8e809000f6ce7851e2e00a0051d1e2cecc03757c70a395ee18c56c351e4b01fbe1f87119ea9967ca896248f7eefbf9ceb7a9cfb1fde9cc771713ec70dff7571bc8e9be357b8afbf7785bfb93ade2f4bfee10addb0fc77736f88df046f2e287e0ddedc94f839a8ba5676edcd65116dac439578e3e486866f663733235768032f8491582c161339f03e5c205e03d787cfc0d5c0f7708d7c919b81e7e1f6f018b8457ebc3cfc052e067e873b7e05ee05de027787a7c0adc0eb702df012b814f8095c1d3e0257024fe44ee01f7023f010b844de01f7019fc385c033e03ae01b7073f8055c063c0eb701af80bb801f7271f8045c053cd01df236dc04fc8debfa1b2ed023e0daf03ff786afe122e00f707f9e865bc31be01ee067b8347c01ae015e863bc30bb905782057860f72853c012e90ffe1fec770837ceb12e0c51bc3fbdcd6e72b3e0cd7e70770f3ffb830bc00ee00bee7fe781f5700cf737b3e00d7c7ef5c9e87dd007c8fbbf32f5cd803e0f67817ee0baf7301f02d5c179e85abf33c6e0b8f2f0bbfe3f2f87bf1dfdc1def17cc35563a8462299ef5ce7833cb5dd3746b989ab0239e8d354cf9867653bb2902e2da0d5c5beb179a7633bb99dd38c13387f9f0fd98866b0ed3c0f7e32287f5f0fdd8c86119f8e6e1bbc8f7f88d81efc74b0edbe1fb3193c32ef0fdb8c96116f87e7c735805bebf1573980edfdf92398c02dfdf1a72d804bebf35739804bebf45731891ef6fd51c1681ef6f15390c02dfdf3272d803bebf6573580edfdf3a729803bebf95d4526a2db5985a4dad9b2be692b9865c3317cd557315b98c5c36d7912bc9a5e45a7231b99a5c379c188e0c67c861e2f7e3cc1cd6c24242cc3644a2d413e189adefc7a1e1d4708a708c706c383849384a384b384c384d38b79c584ece50ce2c879653cb29ca3172180bdf9f63cb397218c69e88bf3f27c9613abe3f47c9612b7c7fce92c3727c7f0e93c35edf9fd3947373188eefc7117358cef7e390390ce7fb710c39ccf5fd38660efb6fbff1eefe3a3ceef4b2e8dff8df7825e287c1b03446724703d5fc0d0e9253848074136bde2f10cddfc041928c9a48e3d9ff4b5d283fbc0f17cf300dd7701136c2367c8493b0125ec24cb809df5ab196ac35d49ab568ad5aaba865d4b239a095d4526a2db5985a4dad5b4c3634a3d58a8c6c47494aae251793abc975c389e1c87086fc8543c3a9e114e118e1d8708e7092709470967098709a706e39b11c59ce50ce2c879653cb29ca31cab1e524e528e52ce530e534e5dc70c470c8700ce1d34be902ea73b4902ff4ff1572c00b912426feb7aecc137fc038b3a37a64e4777cb3c0e35be7fb6b93c35af8fe7a731800de85eff1fddc90c35ef87e6ee6b09d877df37c3f57e4b0007c3f67e4b09eefe76c0ef3f1fddc91c37e384c00dfcf29390c861fc0b7cff7734d0ecbdfcfdd1c2612e0fb3b99c362f8fe6ec86140bebf9b392cc8f7773487c9f0fd5dcd6142bebf2b72d80cdfdf1939ac00dfdfd91c46c3f777470e33c0f777490eabe1fb3b25871de0fbbb258721e0fb3b2687fd7c7fd7e4301bbebfbb39ec864fc037d0f77b430e53c0f77b33870df97e8fe6b0057cbf5773180edfef15398c01dfef1939ac01dfefd91c868323c389b96eae2617936bc9a5e44a721db96c2e235791abe6a2b966ae2197cc156bdd5a4d2da6d6524ba995d43af257cbd6326a15b55ab4d6ac35d492b562f8869b305ec24a38091f611b36c24518d3f04ce680bb92c9167cb831466e8c066eccac871b43cbc08da9f170638a8adc18a3f1c6d83070638e76b8314917b8314a16b8314b15b8314c3adc98260adc98db04ae4c4c02574646e4ca0c45e0cacc207065680fb832b51cae4c9103ae8c5103ae0c03ae0c0e5766015766c89559ba324c324d09b832b71bee4ccc863b23fbb9334308b833b303dc195a0d77a666803b5344c39d312ac09d99e1ce08b93332dc99207706c89d89e1ce10e0ce887795baab7c57433e77351bc05dd160b8ab9a00eeaae8c75d19f9b8ab9ebb0ac05df1dc15ec06a71ea8146db486510d115224020000000001a314002028140c084542a1482c9e69c29e7b14800a86aa50705496cab22448621432c81062080080001918111899a16d00e3a27020421000ebea78bc1894cc21a6cf3eebbe01aab0b2992d6fd09561a3f1de133a9935ce6c1ec054b6f795f941d6912d8da016431dfc2632dd19b0390c5e72c34e59f295ce1a16365d3a2a65269901867639924c2bec378637b15042c64a7daf713a0361f46120408c45a4566660afd4756dcf84c862cfb784cecf71d350b20913ec9c3e83390a2f976bec8351fd06451920747715480249ab61db31b5f264806cdf0aa5014b767ace1c103a7dcab2d993423b6fd5deb7a2ff79cd187cf343240ce18f3068683090e1c93041d44661e616d9c371256dd95ad71db513baf5e4db7fa1d07d774b11e2b80e1ddf2babbb7213edeb1034d98e8c9c7d6dc6a3cf2879c85ae3cabd3cd289eaa3a5380bc40406cf0b05da10c0508d81051b2255ada0f11f302026791bc44fc8e9e19e4887ff73044a844a3dae4fe7696a7c41a186c019f1eddd057056eda8bd165d7c65afe644a0a2f3f15dbafdfb2c2c508e9e60f2941180c7a869e654cec4633073d4dfff2c4b0036d48ef2163d50978e10588c5aac7e603b28d7fd544495c28a29a36b08e01026bc7e139521d1bf7d8fab668bf0a4a4425fa4206c4b4f071ad8c1d2d804e33ef15230bceeb5086cab314f049511cbee070674ee96df525cd9dab1303b203beb01ba979d36ed400f48c0c35bff9c53966ed8f57ed2375342f6895a23537533d1ae179820f685632f206baf399b7010c8344be448f21c72d739d885e1f777602406e41acbf4003d431e48b1204e02849ec8f7dc3f5297606d68e6a7bd72930611ba14385d6c72f25e486504c2f52aa00704c1b5eba4020208f2976468b5577624cc85d35792c5a4a6daa0b8800630f8bb2c5d6b948e230f09f1619b826314763fceae9205c220e682cafaffa9f1b2da4829d469b670121c47c5f97d8bc1e02cfe948123576c5f13a61d3522b8c91b4f4a3b3c1d2d386a7d40a39cc56fdbae79eeefe9beb08c27ac78b51482572d643782cdd4dc11f6cd3cb11264097823e148f6b5eb2290a54d9a5a042e676621d90e390510576e0bba440bf64948a1b66949e60cd058e3ba37df8d7007a89b14979f69875ce5a65fcb11060e8aae9f1096aa00b11c4b5547483558d0fe90af27a643a6fe93832f7618f172b7519eedc96fa6b8879c28b4d5cac8dc3611835f817419f854b4ba39bad7ca9ea9f1219ae9d64d47b26ac58cec4216cffaa8e5393242d54b318b81cb85f7c2c183e743d5b55597179c8b5539332b98a03a603969e0e748a276701c764c3b5735291a4750fad9022e512de626bf376cc38b999eb6c09bafc97343955ed3fab8109ff8a4093ef590f2c77ca7fddad4c3cb2a03fdf18c3b10b7c550ba9aa9c7a5ae81989ea1d031e8c84e9d02434c05291644e49ce6cb34f66f9eb12341500815390445388983e72c5c7abe91eb1fd3940a6f65a0f2fc090d0ba0e045f34a273ca53f029aa6fcf536f95e580a55a36d2dc3b7a363c248770ce6bfcad111415f6ce1b99ee179b17fa2b6666f533b7e559a686535514d4f7230185dd0841fa14d2c7b9cf01272eda06a878b9578c37a00a3cd784172f7a01993a88368b996cb51e4cd98927ad38a81ab03b480c98cf7b37e68333de1ed019de302a31e7ebd122bf06f35275ce5981107c7044c79d317350255e484793e3d0839c66bbd2b0bfd571745165d0477add144307d268a4f56f74f9ca1f25c8bdb20c5760f2858d1d60069f383b8b3b58b7600d611c0491a64071282032611de34194b435a88c51ff576e09799143f200544dbb09221bca6e0e8e8f24cac782b263ef399a42e06ffd429b92e4054a82bc10305c217c3ee4944b42235b20f67c3139f1f0ec43bf690f8c94c50ffb9168e36d568c7dd96f7a7ffdc2c9c04348817c5686196ec78ab4e23c06e12bfe45ed9e98c10ebf67816ccc030ad2912a405794f21f48b6e8f4cc20a091666e9d7d7142177d99429407944858c7ec4f92ef261611d2a2d610c5d743b61602d4f5b8ceb4fe79455bfb80f9c8ae060fd9ae2e22a66b08c00397df7e6335769757ef8980c82425309fcd167c91db1d5b7b1c6dcdb57ce3dc048af46567b0efec453ee0fbe1a235c857cbf8efa740d25d112752b9018a1664dfd1ad49fc42065bc79a047a0243915e5d45544f46139b2cf4379568cc7b023fc07e3fd970d52119b655258c2bdc8c54a0f10842c558728800ce146256812f49ad3072c38b5f8b3d88996bccfd360e205a40f5ba8e861a5a6b54ccad40d790feb321e2ece247d15a92c48eb10fd055593f8b9c24deee61414555d2e7eb731c1745549a32baa998d1d7095572acddce2047635670809a53e00347e3f955ed9416fef6bd3589ab9228c8cd59ca4fd9a46bc01dfb385f3056e5a087dde148635e5da1471d843abf4c903fb17667619e16786022abc89425c189a221680c66e2d0914dbb3c410201e30369e1c01cbd7345104b8888bbf2b019ba4dda45ada0d8ebfe4503eff97743955cbb4775840feb0eed06b308d4c1dbd19a84532fedf86b7b068f480c4fafa277fe92da155ead48d2cd732baec6d314237df03863c8f32bb650171f037f44c2016c4e7057372adaad2db9f99d5c8a0f7f70f6ba83f4c79281d449f4ef79caa769227233fc5aa7b1f0598639b9451dfdca4f8cce42acb838fff867d35f8d75f45b2b7cdc7092ab6aebff75e76dd53f2bd48e437c3d0b5da4d194bcf6c8ad3d8d7d17a321b9975987d517dac4c96df7e81a711ce49f82f3f986bdc9bbdbe29645d2ee6607898dbbfbe0f2240a13b8f9a82002e18f278ffcbf120b8d9151b849e9e947e37f188eabc67c77b2d6cf7ed6aa2bc095b87eddbce521167f57a413666a86278e86c28752187a767dc45da999571645e96323137ffec3b6cbc85b9bdd17a32ecab44f3ee2e54e82279f0ee6d14adddb3036dd8856e42afda55f581ea7bcb2f6b8f8a82c4f25dbc9652e0eeedf3c3b5f27e574e82077d5f2fc50569c58c1e34fd00e9db45fb2bcc85a1a8f2498d063b4f0c2435de8405c1c21052d1c5851ada90a416c88731d3bcb0a8ca609aee4d0e0e88a414bd16c9b50ef486403704b870afeca00037f5f585b17206b11553b92477849f625da15f913a5886262151b7d74994ef5480e88a19245a7b1d186b7ef317e3c6850b110ed05a87217bb7b84d091cb0ebbbb94b3dfe36b36c581c80a039c2b7a96a7d9e6a8e01e42d10104a7fb126a73d788b0c223c41c82da42606959f4645909344a29d9ac38ca6b1c34417fd61b09bbbf634f5a034b3271f6d8a8a5b7467be936ebfae354663d3fe0edfbc93763a9873f4261767b07bb11e2ad7470a5b69b3acd1dcd1c756080fb79a07118b0fb19b4ad78f9cde0dad55541e3ae6dd051113e83bd3cebf1d733c09d49641836f9d4bcaf4572a3c656dbc0cf5ae080297df8699f0c1d4260c543a438c556b5d78911cf44140ad60d2e4d298075c9b33677db63cb62f7f63850e5c561f665d4ff7dea13952d5ffc2fa2e8f0d9c34fd50154971a38bb871b06ab6e84b3017c73d3d89136bc6a212951e80a8084df018e1f1e5f4dbc6414482a9af062a9dfd46cb38a505f4d843f76f7e9650027bd9dc9764a58565f6c357c86b8a8477d9abcde4471a3adc92a208cc7e335df7c5569fda8c4869bbe493597c290f1b6d3f7896331fbffc84d31f52b689ff94ab5a5169c8ec2d089e6fc66ca88b2bbb00d70b1146d0f5660eea36d28ebc37fd4db4f71dec453e280059c522c610e727be41108d5ce1d302a9c534ecfedc08d7861c238ddb8b538e9b794d1696f25ab792d0cd8ca72724d8aae924d115286ada288739b6ec572d42967b963b8eb181d60c1c035d91f6af97dd86563e3ac5206eeb4bdd57cbf632642aa0e64e0b00d5383afc15ed5864dcfb18038b0c084380086faaece46e203e01aa120258dc9b096c128b3f903c86ef2fc7ba8957ef564e55273aba93cc31d78643d0b190877525c61ca702ec54828025f53c9507ec05187c7f94f7566d43807c62a9a5a054f1bfb70295ab3e353a7570e6cfcb5e32368f600bb02b1920005d7c4dd79807b1616f2f1a0b4d2ff4f94d1a4c4da1d22903856d8d5c84b5777caf41cce3910d1ae9bd164cb5d9daf7f4a1758a60452935be84da4ac5ed577b9b00627ec0e006a1c35b9204710afb47cdd51a4bf69eaa4753a4ba75d45d8db16ae7b56a37458adb47cdd908af365eeb4b4bb4ae7dbcf29a7303566cbcd787967855f7a83b3711a5ed2b358337ecb1a2ee55736d928b5b33aad91a842017427522567e0329e511d21a629a354f45fd4dd0a7654571ee59597a8767ceace115650e8de124195b6613d0c421b0eafe7ecf4e2fedfdc96272755ea68b64a61611d39299df971b39d4e0e1c36abc06f518b05138b90eb59854c20c167997fe90cf9494c5eb289e27358aab6b317be8ca276f1121277111b5fac5e38eb77203f78d0c460e653737d90e8290c3ecb778859ed5ace654344645cea7f0b1292297426152601e8588456171280883c2c59f60ec09823b61302766dec4c29a189c891a63c2e24b24b6842fce95f04e12d245a21f24d2f7083f4764af11dd31e2b845fc5304e912810e11c21dc29e21b22b84fd08116f10cc0982be40447a80e07d3ee4030d87e0d67f40220de0602fa11565a9edd74e0d62a115250ba64a5b66a38588b1222d1aed42ad0c595c32ce191b39691d6abc542cf02b00e249e1d670bb3acf4f5a4869a7aaa750389e6898ec3ab5af2a1211cd7bbff5ce9eab5623a2be3fd4dcadd0969ce22059958da7a772e0be49d817bd1cd267097d23ad45b9cd60bfa82450be17e80b0dea3b0c0c87e4bca90c412f9021974257de6bccfd8a72586c989a6466b0783db51284288789be2523e7518ec6940eb6e22255573ebe42673fe272a6deda27df7529cb6bf2d705d049ce5e875cba12342ee7345400f7cf7e5fb1a356749ae8b22d048a7504db2229fde7b86cf24f69e36d3657f45927a94cd33a55cd96fdba6adaaa54aca955a896d984c82bf192591990a2725dc9e04dd82a913b7c0f8392738d0f30ae1a2eb81c6e54e072d7c06de391f7340870b233d738e05792811c6e246b2650f9d56461ceabb912b73b71bb82951f65687f24b98040c56e1c7d00665e8a8c2e8d25bd4ccb657ddf6e0cf100ebed9292d5982eac645e47931e974d5ba6639c9c9697e819ec3c609328195fb18332f1d78ecaafcc89ab0ebfdfabf7b19bd2729321408d2a006bcf79651e62eb93258e5c6bc99860afa460a5f981e37c4375dfdee90fda7d8999eb566d424bc4384b9075ff0ecb14a1140a17145846b23b8a07086a76a5e955bca75c5e9d3b12e389cc042d7fbb1a220560e67e9aebcd422f0b7cb8494fc9e92d3041535702a97a6bfd25c222084324286d21fb72d4314760bd265355d4076bd2fcb2bd0b732bf11e37877e14d10613aba06cbe95f9d1cab393eda9735930073320adadb2f8ec769c16dd9904d9e83d31bef9d5c47794855bbfd25333c7d0ab89dcbd21af479a15ed59cbcd61dfb2a939f6c058fc39e3f5ffdeb555a1c3637c3195eb7930d6badf77205b4bebee20427682dbd74dd161f4b9e4e27c48268ef1ae437240c22ce5d16e8160c68c48358f75889fcf9be083d4cec0d5944c3f1b991f9ba06f7ee3b83f8fe78ae414935b5962b537e00d9b9f7c827571ba2e5a0452d1414731c3d628ae09888f062486fdd5abd438142fd02afd2a6ef5c0caaa4973e231260e299a7f58614b5b72e0ad2ee06bac3c350eb71d872efeb8f90d99dc902bdea47fc3b7ca35164a0224fb95fda4ef5fdda39732bedd5839eb4b0adb8daea334327d9df635d0d814885a4197daf76b7f3af504c2f2349409c353e369c2bcd38862a7b9cd719dc60eb2873986eba6d398e39211578a40dc800ecf993788f6f109f6bbad4d36cd0915d169be892f04670f5262aaf7b73512c0c677b26007f869eff9eca4fbc838bcf41233bf6f26fcc48d3223dce6320e7ca8c77a992f2be24a659f4d1bf401c4565b1af1887fa100235cc5b9eb9850e82b42363ef4ab3d3186c2be86f61041c78ebc19dba7cc708f728284f851f2d5057e02b2795ad682e7f20b112fc1011a617933c181bee1d865c651dde0ba171b621b24aa624634f3068e062730fe2ec3e41130368f23bcc8decba6dff746969d3097f62486051df98e641fbad99887e1ea8ea268c2531909a858ad034c0d78aa0c5c36c36c2397fae594113043c281b231975fb301ca41379df3b438d56da317b74202f132b5296b04353d038fa0c2242ef6ece7d0260ff0bda32de3e67a0fdff58085800ae820845243b972560e0a40c9cadb6c76f9514db9c12b310936c0646cc7c2446196c32a1f63553d88c9e01ae03eaf0f7118b66b13b3499483f4e67b112823a27327483d52a28b17b815f6038657fab887395ee89ec5230d5790e77683171650cfc370e4f10461d5241cbad65979d8657b359d0523907e994931d3d7639fcbbb283b5534b7bc2b51b948bd9e5bbda34205c88f2b3da8a1478d359987233fdf112378cf117d4e0f1d0a6db93740d2a1bdfc06a9305daa30e226c0e2a876d6faf30937811d7986ddcc4175915c35182197549edacf40454f66e98d022412cdf68a3ac2027ffaf0f72df74e88b79b26672753367a655526b1c7cc81b16e318ac0ac910494b722a45a9a9b7a0b0c590cf7390c92c6cd2eec8a042551382317b6f05706e04e2b36f9581e3fcdcc563ce8c566134518d486f25112b31274e45ea29bc520d28c26fa0923bf131ad6fcd4c3885a8ec14970c3cf53f99498a04959d07ad25be3b68ffaeb3528970fc45fab86c40e790eaf436e52815bb7084deb17109aa4851f492ff1b40b45d6f85000e98a54260f8dd063aafb9c225471094f976051486106cf8e8aa2c961c06745259e68256c24f9a8cd38c9baaf75010aec59391b3abdb4feb692f809542a1922d31e4bf06f4a7633d689be76a9009f67fe01072b758f2c1c89458fa2e7b91fb46a14f178450d435ac89f40ece8ade4205b82e82d4ec043205cef359db064508fa2349d34f5e0bcbd34be6ea28762aca471fea39650a5cc558dbd17a0bb903eb5e6649bb5638b6217906022fa5dedbc8ae1f32fb7cd209df25a0199fb9657ad9df9b12738d0cdad503f3b8d897affa4bb3e2401b2303f1db9704f1f2ff4eac5dca2a9ee747678c0587839656b7fa4ff942d86cb8a2ba478ae581be02862b7574c243eb2f7ebb118fe86aa42f530447753adbcca6b9932423ed9a8f5f2219e1b55beb22b33323f1d84bcfe319a1b15ce85014a677013da29942e966ae18c68a186495c41a0a0ecc7367d4e03f103c6e3ffae56a86d3f52f72ddea99afff85b2889ade978ad111445dfdb30141ba66be45bec1d224221653e3db7c57e062a4f5e8483c430bafa8552f52ec73ec364aacf6e1fc2fa07740743028f71c93c0516dc72c4a23faceb3c38952ed39c601d05b0ecef8eb0ff69dfccad296049e6ace7e0e00eb46b7b5b23ea7986610d151b3441ea1b57430b30e71cfc106371e94381f948c1ff3989e2b58376c0ecb320bcf28450c181858ac39e4ca151ee974f4a288df38217c86cd364005043e07a1ecdc2fadefa3939164a007f905d07682af9074d0dd3e6aea464a960d2e78729aa8ad90984b5d0a1138b527626b47c710206fa2603b58f5f701b4d4de2da80036bcc547700408c22f6bc408575060b71443e7aa8585cd789c4a2fa7e9fcdda061d439c76fba9be0d9cd0b6fc8731986cc8ae8146ba044c04d943af11817834c318df0c23714cf2b111099ce40b8084f79578d17cabac8d8468cae4ebca601f1a2eacd1fa3c85a3155b63f92cf319e14a5e6b0c078e373936a77013804f7e76391294524a65cc9394c32ba3dc4c971a8fc7e5bc00aa32fb0b623606f77e0b83415087baf4414925d9d8d68e4c1dccfe3a68d74836acee586adc70b47ff3594b08b8e792d9bbb6388c5d3bc513ccf9b6b406dd98a95d1697df4b6db83d487d067a3b6559b11d497dc8976001c44c83ec55c8f6e59202c57e33a2e27f40fee8b660e04c589bc189f7c8b57e01e89e3f7044f3855b830ce252c7a02384092a4f782b5c407a111c67471f8b47fc4e1b0d5aeb58c3fe8e7889f8f84fac97d12ea61e61b34dc65b953931d328549cea98fe0f1a88bd7ea9dac0b5ad7ef121956115382ace743121fd96add0cdf1b4ae92ab005af06715a177a2f2e2f9a7d63d399454e1d852110a73effdff4f42d14afabf653185d2f64efc6083076fd489bdf9844720bf2bbb38b2fb84482d7a04928ecfad5070bd2c0e6d9a1ee7511a235e4196686b5a7ee9e3dee593af8296156e3b3c56883a909fef755664960788b7e0b642444d7ef18f25626bb298dca447556732dbca645332c10366d456eced4b433b51e46642054f12f23a0e780900cd22083ad4fb7444540c17c5a077323625f090808c02a8d6df1c1a64b236aaeb03f8f8dfa73a18e1183d38aaef72b0185daea25cddf3945a4b898ab335f3d267af5a6b5841434b2780d48145de482b059825b53d7bf033fd60494029c9c4561ad536aaa9bd907abcd6712150e7e9195f6f97b863b91ea191ba58114485b86ce2e66f87136035b2590e223d75d7aa2545d860b01f3c6e87dc0d2a611ebc9b4b11b65edf028eed0cf390130ee89c7f9472dd206983c1a99c955d4139102d15d39fb6a10d29b3c15ab628177c2cdc96d2b812c93e383fb76752b179cd0804b1e4c12f0bf39c9dc032c3420c9651e85a05fc5dbf299d9ecb150030be739e68675dab9341de3311bab7ef78b31a264cc95348637b5b2d4a4e965621f86e41d2c33f829378ab1453f94d54d908c6cb4eb9a4297a20964774e8ff1becafd75cf6d42d2c63b806d2f95d0d091f727e41889935863d017839605d494324fb8b63ad6603946601621916903a706b5f6f81bf2f5c4fff6cae22c43fcb79288925965a23b963086798db71c458f4a80a3e0c5686d5bcc71c328116242b7ccf82abf74753526ad21514a7698b46bd6f8ae1de968f8cfb04785e84392b7004df54e94c4ce00aa60921ba56b50bd2a78a62ef8fc3ecaacf98c9196d8f8e24d56479fffa425e029edbc60340627999c4d121fbcdb4b36a286b2bd79db8a7c6aafdd92983f59b48f6c78fbc496e94a593bb44f52fe97e7fa1832351d8a8d7c5095c4a1852ebc9d505df4b080ab48761989b7591ebe42161d3e5efb6548b421b79de85387f9945533d5cbe6b0fc1ad89d4ca214c308b73ed1dd4ac3ec79d23ffec511438c2884e95b10507de6e094e411ad162ad66b2ea21cd383296ccbc8ad6ce83f174dc7fa0e552ee0a03b4fe336d496482f68bbce96cbd9fd612215fd452c636d94b631da5fb9806087c6394e2fd63b80853b419e30a0c872759341c27d5b25969941e7b2fbb840e987aa5a78ffbbc38c5713562fe2b431ef38dc7d3175b01a9524dc8163cd30eff66caa1dc7a13f4c5c95ace03b6cc5426183ed6ee34da4bf4851bbba4dfcd85a4b4a2387564d6225b7c15b8d5ba3623f0b3c9ff7f95f19fa9a2b22872f341b86d5ed0f21769e6925c542693945a2327baba42bc0aaef5da406b9fb7f79935c858832dcece1f89d6fc56d10874feaf46ac973443054e3a3fca9e7cb3b9dafb5df13f1d9e1fdbef48a13a8b2474e83c892cfe73c330d9a2ef630df7c70f949b4282962cbc5f0efcc88bbdf3bf2af5a0adebfe8063abcede4bbc18dccce1430269603a31d5c82b906a0bace1959210c01a28b2538a3286bb25362dd5a7be17fcf72a47eeafc650061118cc2e1bdbee2cc856d46913a85a5067abb8540a08ccc9b8d88f4745bc7449c24a6cb9945b77c64c0a60027a7ac6ddab7513641aa81f119d048a992d23c128dfadcffac1c49ee354608f5e497c7d894d593780c6a31e4b8e6bec2c13df824eca1482bd529f2b6a7c884b9e3e32e2656d79d5324abefb105e931e94ab15b603fd1da1069de8c087fe0e3184de879e4f80bb7b3aa837b0421aba668952558301de807b46943b2014499d41f97c9a3aaf1e64d66fea00ed4f4c60cb437ce7132a9d493fc3ba8b130c2bc974b8a65c3d38f85b0178f71493dd86c3a229ae46deb293dd736dee1a40e5bf95c15ea00eb57d46b4d25f0af1885ea9a688a517a204a74d9c088b169147e7fe1ef59d57274d1a13f352e18af99e0c26ad9e3105c42e86c385f5ea038c8cf1579607d447410c17bf5cf30cd324eccd1258e7b1ca3f7dffe4d764dc72024a78849cb41d1cd1dd7edd4b0a972c338b66941167a1e00a3438ef6771fc7f695dfebf2056bfd6d50cc1e4da5831d522149d6246c156f2169023de4dd919896196537a5eb124cefb6c6ac5bfabe77425d6e8e798649d1fd8a0e7b0d36bbe326a6699c4fbae07ac82226272b1018ce490d14748feb664cb0e5e0f8d52ca854aacd042523ab973b6d4d3a5a6a115d78cb747a7109de1e3d3d663b2cba664adc12cde7efb1c16b1f506269a6bb47b4e0ed22a66453fbc12ac5e289790874fe496b5903e84eb93da7c71667291dcd9aa194f83c43e30d29cb9097702f3f842cf3eed8527f01bd09609743528f82e4aab4333e5515443582b82cdd8ee3fc89f61635e54cd1d8789c0663d9b41dd900bfe7fe251e40d54941c28856563b2866ef222599342f4cd3ebe157d0314378070cf29f2e1ae7112d765ce09b8cf5a767b1a8dd7d9cd13365a6c7b890394645f0b685287e884e2abd1c7b06145971ce7b2a9adae89aa8870193c5a379d0ed9a630605746304731cd3c952c5acba8717bcc2ec64e40bea6ea53c291b62ad3f6ea0900613731e8e2af0d814041e905921b4180098b17ab3ed28f4b29a5b7bd88c0b0f218fda82284dc6d70d68641f0dc437bc770a234bb86e369e7f7447b1fb330ebf727cfa88d89960674935d204d7c203878a15d8c760d152e0cb524d0faf1b09e9022430fa8d53fb4a058e3eb2f111b5478a650b83788effc04dbe6f931f74906dd7b6eb2335383aa787b57525c96b1e8cc1843d0af4dc5688ccf643cb007e4c7b7eed39c93eab68b261a728e6b4ef1da3ba5328995f569e8a99a62b98614b1265a273e0a03a6893c9af16a76959841c82a3ac1002f209f4d0603896f327330cd337a8e1033c9b3b38565251317eaccde59d682906cd615d8d6aebf4ab33cb58b86a8fc64c90358d4137bc49c54007da1b45b19ba5938dc21ad7b59e8e8111a4f2df29821a2c1db491ae666cff52147fc48e4d35a66d05a6714fa001d69da3c15245d1cd2d464f2681440f153d4dcf293271d1ea33be28c1b2c8f177f6871d7a95adbabb4e5a155b61261e354f0571c8ac96f2db520869a68e6fac715cc297720bd3adf0689ee8f181563d7a38682b1698258c940a2ea920222504bd2fc1df04cf82520488b734f0419aebf46a6eeed221be05ab2013e21e5cebd99b185b9c2b8be72efcb9b1038593fe06e03a1b604253f7673f4f48ddda216f8055727b91fd9f57b3b078d422daf058b9d4676ee216efdd9299e41660b00e6e5d1b82145b1b0f30f6453dae25a3c77553ecdb0d3ab1b79425c395d54baf47b5d7dfa3837e5d4a231ea25adcad0c6b4d55bfaa31119d83f060a4325ce78f454657845cb6b94363d18e3bdf10954eedf18478580b465e4f811ced7684b6cae21859270b26754909518cbeae497699c4fc8f42bba8f0f4afb7e3c370f1fb3175da9069675ba61ac872c8066d8ee45f3a6d0c95556dafe398994946fa7728894cf79c80c4460aad07406acc37783bf6f39944f28abf37558fdd053e9c8cd4b20a521cd350923162137e71bd18b44f126bef96baf849cffe28c867860c7838594162cb2a37b661884f65325a40880857f171652049f9e90d6ff84ebf3633e390aedf2c9eecbec0ef40f4e4a197dd0fd88485ee1808dbe96920d51b08f4a95787a790efe986100088118a9ceee84ad7c9f17d541317b5d79006545e5d1ea698c020fc5c26fc54848537fdfd2ba66a30d17b65e54a55e8072a63de1dba00c63bcc2dccfdfaa357adda62ee6d42b9b8972a1a8d522cdf33a0fcaa55e374fc2aa6cc0f79fd1efd4304b7eb581d40a4154202b26a92578ef2329b908004f78aeb534323e5ac921609983d4a9c7eade2ee8c818081b78b53d6e48a11f6d6bf36bc466688da900adfb75418cb2acbb32f5c1e668ff871619b06d000a7349b99df526b1f31dd6e1011d61235bedd294b6344f239f5ba789cf05f439647c3a733b739e96cd8efd42f6785362e6f73bf03f6f5cebc54807f57d8c6b667689d367bfc121b4fbb7af90772867f17983680a50f50a214b2a58edc24be6c9e99f13f2c44259e09ebb9ca2b9f67193120360f78895aaf29fe61c6c21855e370938b07f163f566f934800ad8e1e945d0863670d35f2e6bd678667dfa082a2dd4455b7dc79b4d546aaa14105de80630bc9d754d02ad769e68e9338d3538c14c2ae555c8d6d8cd0499bc0bef1c78548e54f5428199e50a9ac6fe86c50090d9ba46c020f85a849639607bb74b895964afcde622c0901320466ba2483205960f49f8c6567a7330e9d909094be64622fa1a64e06c3699074a92614ac247a409b08a8efa3d7a22edc3ebf7af67526a9c8f7e10534c5a33d2e6dc3217981de4460c8e4be8758dad1592ee00d84a37ba5018e77b10e2a2c2e4b33ce0dd7dda6df318c0a72085e49ba071748cb5ded0cafc8a4031d0b96b7aa5fdc74b61cbe9d45ea98ee47cc500ea23087d492b0e7fc273de35f1e982789902d2f6cdaadc87b015d32ac29b5af5c3853bcd8ecc804b6985fc62bced70740719720eae3fe22faba5042fa2abcd914882ac8cdb29516916870bbefd799110a365fde34c0ec03332a0eb68f92eba1a10857b1e2a8517a191b354af3d2b802094df462c135891f378e33732c2d37dcae6c96e0293b3457546b4aa5c692ecc71e9f257ea86117b2233bb9979edecdae79bc6002b6e6f0cc2151e75f11dcc148581040a5208cc21c7a71b00fdf70565010807d81fe80cdc77aea5a1c3c68d1cc6a8f974c7a8a34c666769fd4c797152caa503e61f17dd0b31aa1a62e4382c1b2e1788754022968d4bd7fc165c76dc2daade7828b1c90ce8c21155a7b301cddc7a7f6425942af93aafd0d9c6860edd8446fd0fef38d4e465df128d4862986f4b99357eef86d4400fcba9d04949602a1043d940d76e4ece86ccd83d1f826fdea0efa8c0966c7fe7075ce7c022dffba217570e20324fc7be6d7639b53ae41e4725a22a4781c8c0cdb6b352dac342ead5e2714c426606879dbea5c283f85033704c6471282a64a6a6f62a46143376e24d4361dddffeec5a86803b259f048ddd69d76750689ff6380557d12e5fc24dd1e6aebd9836dda5e6cc5a604497c6b413aa0e04691e8d4ea474ddfa90396b225070a299c3b912668338a509840ec1e14a5cf0314e19e859d4fc449490231d8bb7538f2b3098b335578c630fa7c44b785b6b98d5964bd3f711e2b9efa8220a1a3e68106477877c3766eb0e077460fd038944a7e02eb778cac877b42d18b38b3af98706e741e829601b0eac2470d155ce9dcf6e262034b52d364ea0d68c6e14fae982d5d683bacff5b6628163f345b5b50dffbf0869721d1c7802cfa9a2c01fb06654bcf1459f5f557a8382f05209d314d06ae41a32012219af16442b702bd2994a04677ac2cf7fc0cca401c44df685a193126cdb1388de287de05f32d0d2dacdb8336e36fc2a0631c0159ec99f1859a4e934ba9cb84c2305657893170107b905bf3f8f4e8824184d380a03a5d7af529491597c5d85dd59d5cada6b7d4e879caa6e4792b3074be86574af8f9d8937fdb45d0ef56bb10da75451581f1873f84df207a416127919e228b38b00b56f0f98f55ca89794562f86dbb7e5ec4f8e8e9b71ad72768465f7db18f88e56315ecf69e6b3f39972b2e89832e58fb8cef48138b23e09da0fc185acc1db0778a9b24ce674b9c1bc4738c35fe24c1cfd1a95f4ec0d1dadead6b5316e72ddc8ed5fd31c16ae4cb67e9b7fb35d5c63b906d540afee3ba58134b3437f94514cbaa4e492e9dbb56548e668be224db545a0b9be4bc6c0263483fe56921e8e94586bcd8fdd6727bb28117fe892d048dcc9ba1fbcd5a4280d7b45f1b6e17e255b216a403e0f47ff3683556a82b438bc5b3071dbf4cbfce8dc3f1d5db4b87f169021389c32a1c05166f307f3629220423729b637f4169b4dfce16043d1bbb490d20e62b3bd0b34f990a2e36dfdea130f277a0acf08f7668afc920958ad4c18e07f83f83d12a28ab0c14e82dbb66030b9d4140933d7c55b7588b263a545df5983e334509f0a766061d77f67ae93f8e18d9ee83e5aef564b4a39f6957f337f4694418c5808b3835e6616008dd0545eaa61cd063f30a013aa9e16af98b1678bee4dfdfa1804703a7c8c5920fef4cd121221ed7368e389b3334688aee410d30485a8a4db929712ae65e2286c643dd2e87acf2850e5def513a9c166283b00cca4832ba59b867e1947a7c01c17fe0155d19894a1cfd10eb6959f3581fb32f01b569ff89a5d4a7fa508dc67b740455b5c98bd633d20ce8fcb9e3f51a8152c8dceeae670e3c847b24af50a934b1611fa1cb9b5f829081aa7b13d0988c6970982296ae661e0ec74f3b3252ef6df05a5fdb0b5bba8420e08304339ebbc7084c8cb70e11fe19d7540e1fdbba44891b3be4ee42e74d284e5f87c76f93851343bc62f6a62eb47ff1263c8a6f1ddeed6e99b07524100077efe146006eded90c1231434251001fc1d9488ebe8d017c50ec7a6205afc15f7b4a021a995dd95056e47622e653e4f3ec71df090a834a0a8f0424085c065afbcf6f9ca4bab0361d276f1735b999b9ed3066c0a0fa87acd91935270bc3207c4e59abe4aaf0dbf6f3686fe5a16d1b3cf854a30ce3ec14e9905dac0a3f1a06830ec1348d8e1ac9db4f05ccd1349e367211f3e8f21d539df08102a550f6837a8b0aa267527f95e893b28e2c7327d0614fe045fad4dbe3e708058c5675c4e740a883985157c618ead001985f6085babf244c28fb7a705efd7c3954a3abffbf70fb90d82bf982925703e7b21f38c80b98490b88f7854e2c1c13e060ce069efc258cac96c50f853aa2c46bb6099a3b42de255b067cb7979ef844a6a551158ade7bbcf522cdc8ad6a7f79b83339646362c021360a52cdfb4bc5c6431d950c932f7bb46eb31ddb54c485f0ccf7f8df58a67b614d77eace47c658fd18dc76cf165634f4a25cf395416e8f3c70758698b71b07853bc76e3b920b8f1377969fee9e1d43cd8251535c22f683c3c2bfcdc255495fda79143d0b7aa61cacf6b0804c4926fe1e0c6961ef251ef776208b20193b43edba7ab8842e055bf43a398fd87ba3f0a2c4e19501a7f7f4213321929bac4781ce9e204237cfc6e2589a5040d5b5b4f5941ccb3c0548c4564f7d69ba6181a0aaf2721a83b8647176304670a029cf06b376703a44937cd8a6324140c558ffa0dfcd0236eae6fac1650c299f9cb8eb73e2c333848ee228c9c52674a7aeb5c9d491c6a3ccf9d843a60d96e6e1ca8caf524abfd5ad7a0777f4955ce0cf4d019f1eef3d941486e06d60e7889d490366a552714844f1543a0ab01b261b38ac1d1439fc6540c99fb23d72d7fb7b1322a54cdc11ec6eb72b758ae862955481974647adb60cc399279446663925b8a49f38219aaeb4181a6b3adb3bcbfe1e6fb98101823f9246f688f0c40317f728266121ee865b2e0a4632aca78c2bb5a6c10a2deafd1a4124d252908086ae74b35564ecb7ecbc2999196ced3271334d58aca54ee4cca08a8f72200adf09b538d56610ce8d74ae655e7c996defa7607d202c26db404c4a4a4529de5e1cd05a799a3c82e11d0432577ffa3af3dfe3bf277af879660b411681068a18365fb46d361bcc3f4b2c6df8bbb40599d67fa68f27b145011b529ec085b043ce86bde429a989ded1375c2144aaa6bad75a352fdd7a062568be8fb6c3977e8e551fe7961ca4d1fb614f512213b5e8a683a808cdff534f5440bb11c1daac4b4e17b47b1dbbb7478562a68e15ca8f8a5a99f89f65fb9976d3f9a763e61cdc486062ea24826a3aec0d0dce041f61032468cb87af110891c7434fc8f2853ee2a30843409b85f11fc4760a1d3fb2a1e42342ef68ca1aff51aab189a2cd68058346199f36fa5d4331c5d6419b53e97e4815dbb7a53b7022d217dcb6612299eb81124a072fd1cd6cd469f023e1c05d4f3855e21b933d255f2a2908f230959f9be711960a63c5fd6c3aa22ce931c0923d911bcf2b51ecd421e0fbc88d4c2657c8735cd61657d851291459fd840c9aaeb0daf544f401ba4f809af43b4dc66c6278007eeb42182d41e872ad1e0f45228bc345fbff47d92a7e47462c038d7ecb505ab823dca76728d64ed81d21260986f7480ad58864ebf884a243ab64f294661c48be2cb0a05f3e923cf7e58ca062ef6eef72403693bbbd4751ee614f5642d7f5713ed85ceaf3d8ecf6c55277d0cf1649cc4a4c50ab193923fbe67c418270afdb349880948f148f3e7068064f30f18cdf162bf19bc0549e6af387a7f8838b29f0771dd3c086f16725675dc78af8473ad5891cb71ccc22a5f45ec15da090e337bdfde393652bcddf50ea9386bd775b17f8cd9d07c0f185439ccc139ebd85f0c349b222b40a0fe5d374bf5e0a4b8652d65d424b63e42356130c15bd62c379913afdf4c1ebb77f31e7f0d870202456d8ba4dfb131005ebdd12e24c3568fd651ad926558e2031aeab13a9932dac51f0d8222e1ea48d9ef951310c1a85725755757d7f246cb38b1ea8e49d0a14268417795d724540253d19947de37fb6e7a18d209382b1205b25ddac4287823f9658509ee3a7a0ab8cabcc21a5984fc09b91628c302659ec11914dae321acc1409a747a6a169aba6981fc4c2d5c7a362b87e6eab10bbe169f6fb937a7717c6ce75779c8eb7742c09f547e29ac809385220425066e3075adc28cc0c53302c87ca4fb8d39cd32b51c5845fcd821d8555949656286a1adfe1dd55877edee1b53b4df0c3a589083950ad25d8adb84f1a554c66972e1af8f296e141eb22cbed9283358e68a3ff682cc4c52c37194f83fc73cb442a2555afea3be50c903820a4a342102bec93b42d92b2b0ca43bff550e98bc96987b9020766f6648293d6e269cff8501dbea752a2cece0b475ca55c6f31f2b9df72f9ade4c31153d37c061ab88396793ff33a873a1ac43c25df59a0395821ab49287a97ac4afcc3aa766a0d57c667722a0072dac7186e54f9ccaec8c8e47410f27d9e2a61436baa24f3e28989c9145628f219d8579a857ae9a8cf6f726f17564a131a5a2c89334936d9ff1eb7d2e92ebba9306b2c8a5f2b89e7e2684ba854463856c436ea3a34e4a6d29160ad18cffdd341f5773f789788a4950237c47ea074f96e4a038da775b214efe6339b37b3ed60fbc2ae2915d0a2838972569d51e67c653b307acb6a789ff90edb7fb855ad024eae0d69432ef1fe069aa07d198934d66d8292e01f6b21be80346c7999fe6b476df7078a30f185d15d612a0bc89182df530d6cc57d1b1b847f34613bdd08d8f17b4f932f7c610e140b1daff00144c959995f2f7eb79319549556d420914d7588c15d6e913074dc77fa42065ddc4f6e1a977fabb288743c4fa820b6fe03b5b9fbcb6a618806965a2b1052e12be0184abe3a444e88353ec8b39e38b2f0b7f896a7018fe1737d922801d1c3f0c0954f160101dc96d5659c785e20281d3649fc2ef831eaecc7eb4e2cd787c87237e96d93a529f1957ce607711401d315a46e15f207dda1c533f032371c77ea2f8c6127312616bb04461c459bfa63c6f732f37f74e5cc47c9538b9822f4b3689e821acd7074e6d4f2f5c44015d5fbc15374f60b11c59f6e2f2520ca0a3ba1bdd5b898ea65942b035406881da9f9723b560020067fa21e3e9a821531cf19c1350b3ed089ba298dcc1a18f598764349f2e35e0ad85601be70d2ac723944a5b9703948a42834702c7f118adef7c5b54c90d8fd94ae53ea11dee70d0f82fdd9153123f708845c15257a4053927125141332f5e57578a69fb9a506afb61d18d2e33250d5f75942d65d56ed35e82a368e735f839084869fd8f1fd9d4622477e6cc9c108a9861d21bdcb912aac874c223150eb4ea68e3a55d2c6854339c2ec226afea43aad98bac79a19fc3053b6fcd056b3b1cf160f0dc3ec7158eab05f0d3d67e9b064387006c4e86b51ae88f8e265f6eb920e8669e547534965261ad0a9bebb81d1289aa131f486e89c9a3d2642ed4bff43f7a588f5389ff20e32b1e39ee169443190da33a86a4147870995bf6c36c9002915d94446c038d74ca900d1cdc1bc84c73bcbc2f765bdc976d895c6442e14957e69467dfd890254ce36257981d477ba8bb2a9a34d439769acd21b5c4eaf33c4ee6620b44db2555cd3e4af18d7f7700a701e737eee25fa2274b2400a8fdfd38378bd8dc41f8f82c71f3a702433776de27a99fd2b93d4cdd5a0100a24ceba43717c60ad0fec4df56a66e3c10789597493a27226cfe3ae0ac09cec4845b85abe5e65172ba67d7e427749c1cf6900aa93c198be2cc24b6ddaba97dd6cba39bf537daf2123f6c888c1d779e8caafa52a71f70c565f3f9ae212d9359c5a4ba7e0ec1ad0eb2856303d95483a664ecf781671d4a2d8f2231702fa63d3e719094ffcb17db62f8c564cc26d82a6a6067cfbdc23c2c1bb09085ce1e606fc182760b6138c9fe48c4eb31d22b2c1075491a2b0389be94b5094aa356ff2b11de4fd04e1cd0314a3347f859a0e126b44e57bf2ae714965ba198474c6a28fc2aaf9389eaa5dd6bbe088c7c5104e1582093dfd021a4140e784e1bf8b88604ace0533c8a9b48c1105d1a35a11cc5254906c289a5e429db54c1dc7645d874a0809f68c1266cb08422911064150fd444bd522547d46a0b69089c8662f39d369c40d861d127932c33b04fec86b6cc03e973b20af238ac368fe85cb2939ae1e4892cfb58d4d4fac6eb14c0de4f5387138b11469d6007556adab75102b2a6bc69fef3240172f55d2060a014eef5a449d025b05efcd69b161a8b10ca96f3c575d8d7860a060d950b7e6e4f802582af28a8463745649c89ef54f037228418559599dbcd61e37d140c2bb5abb470b4138d28b7d3ae6d65ab6b9068a7b88d3bb58c7cdd879e9a818262e2b2df93a8dd44da88103b87753ff99ac4cc8f8392d0f333e9f652cb83bd16af08c74bfeae6f9f36fc51b1f23672301c882a600429e7a55e193be5d6042b995bd5f05c486d40f80ad5e53be4efdf935ab1fae4cb0f9fd3e35d2e8a448da0b412fa0493714bffc56a40ad790d3fa8c9ab37f17330d116dbc5f248fc54a84a2028d4463b125b7df7410db77bf78b709775e1b27e0ff753bfd5bfa4b0f86d63808316469086acd30c823baab811427e22fcd2efbde447983536ded47f548c28f9a99b53c20f5ca6426249ea89077bf7f138211857f139f6fecc345c91c5dd77be219c021a1f90d7fe7c089666716c99e50574242bd11e808e185f4b87f8b0f406a45f0073fb4b0a3aa58975f333cbc75d510512bdea9cab9189cb40166aa727aa88d4647a56edb033bcbfa4f39ccdf16ff2536aef9be46d517d0f92b5a11a36b72c8c36adc6e14cbcd1ce05635f42afc257c3e4045a15a46331cdc308762d76387faa570e921c208f2311d32b8d3901c32cb8b9e0124c866bdab4be0aabbe833fbec2e2b0b8a6f6229d74a8a835fc28164e513ab4b7f461849abe0a55f67c0216aec32473c999cf2a9ef1f0a41029a560b004ef5f5a285753796956aec0976e4869543a59a91e9c01a2a18104f4e764d9d79bb6f3c750db3ac9102dcb6a4b5689e0a3e7b99c79c1d238fa52cdf4f39a9daa284b20efa838fd373f87cdad9671b7e3ecae839dafc950c94ca19abd209e208902c803799a9eb1a1c26142f63304e3dbb209f8b85138de597a4bee98ae70005e098bca4439382e3428e25c544ef607bfd9cc9fc72b452c2b1a8ad25dcf7e2fc272c584ef57ad126dbe1a43588394ace5ebd87accbf3f268a705d8e77994b8478812451111880ac90afb64b4bcd51ef7efcff3dda319da44ad8bad8f54e1e0643a5762c3c9be5383d85b6b469ad26b872ee7999742e20b02844777ed403802b7a6e589e3f2b9bf2146317d48f43945665a79ef912763019ce5bb47770808b65472cc02dce0d574e7287500c3bb5c2089a64593d6e332e88fd03e0e68c5a835eb8130885d4e1f08f70bdc87b6027fa6bb80778cd1faa8f3c43906b795d4473c0630c70b586076c04eb4840e7c3c3215f60dc8de743ac8f64d003cc89b0cd8062398c794441ffc18aace5b6433e33f80cab63ede2647c3a4f3a9ab204705ea7e16eafce9be62e311be983da96941e13a6df018a0ea1089a332de9237241e2118d6f34bd40bf5a32cd046ec93bc15c8daac03165ab23b318b4446787e17d2ceae7dae98737ecfd12342495325f86b64a02722ce41d42e4bb5a201c4edc44d9f25334bb581336fd9c22a43eb6acdbc4ab18d3139dd4495bdf19f9b62e0767298f45c8f448501e5d9d39f78c44f347644939bcb3b0ad481c015beb190dd0f92832d8c083635de5a7cbf75b987cc6160ca46fd03466204c3fb5d2e4062489f3b6b6e2f310b9789e495454cee3fdf6b0c94a45ca96f4e4bc1435b0188165f10813c9f60ee4142bb8617a92ec1d8ed335a4f8e1e8ee4fa3137347551222a8a6302a4ea700dbc18c57cf6ddc541a1394aadc48f374ea94f9413cd321c957ac5da01905a4a5f3b687a3d5a01fe605fa4c58b2768c00e2e0e54ffeab63bf844b2b374881d5a8e413571a094b4fa4b9fa3f21ba666d2109f00ba1750ddc4851f9ac4f0c5e96abcd06501df5504c093272f9e51b144466f5739f5f88de432c4666e98673baeb13906d7671e72c42b6bfbe4f9bac64ccfd9721363ca0ed31858e20c51dd131b04c84d5ea80145ddf3fe32e6be3da4c5b0416a701c5eb24009e18fe7ab23b16d552f56708bc916a3ef2d032b98950427fefdcc4c9b3a49a643395e5ceeaeb0e01a47b59e77ce212fbb31a9ca46d0bb76bde975d0b69f76152b90c2456905abf81976599e5ec9a16fbe2e4d1c465f8482fe725b7a1c1fd7d35dce3feddda94000d253efbda7f0d817b70fcea19983cacc256591e3638f0aae8902151b4021d3227ee12e5188ff74f87b27388ed1645d337c58d21c3161309204dc54cc1c8cafcf654608fe74fd85de3f9b0a9e842328a60735f85fa99ff4fa0e569b2e73192fb0e2a96cf0ec0c918978ee0405f5426b41115e0c2d80c5ca29b4b1602c96eeb3ecbe6ae0863a9d2d3430885da8b69b0d7a2991b6f579afb8d427cd042b0259933a4d1147afaf945ccea741060a05f61cbada96f256140a455c56da999def374916c97cc92ca1bb6be1e8f8e99ad77473d786da30d033c5409c84560f28cd396ea402592b12c9e722fe412bbe3a2560ada8584c69c22182a1d717d4cfbc0e3e47d8c722fa9a41eef2286177676ddd511688cea7968f9eaf459e881ae43a94062e9132228e4641ba80670029c689197968933ffb4c176797615493c57c3fdd1a9c768240f612df1a94b26045d7e21060c58916aa733027e527f66179efa706555e03a1ddf40cd580de1338b61971643921ba24e1cfacad92e9622a97a516934c2c5b70b444030e83e27eec13eb640143b26cc9f86b9d3b516e0b591135a196671668b4fd195c22756f856561d969542762247cab7e965a6fc29614e3414b0b0f88391aa0789c9ded0de82d824dbf1214937361cf96b715863757566fe2c08c7f4036a3328efe4d2589347748a54588b917bc084e086a642191d50dd1ac3c645989486c6cba42e464ee4d4f0fe5dd1ebd16db13a33a0d35f758ad9cae7af8b0ce8f65a5cfabb5a5f19d365b696f797863fbb66db614debc8cbdffae7ff7de02a561c3506e147c7b41e19a3a12eaba7c6d2ad88f6d360054a72dce5422c8d1d542acd5117ef6760c3c631a073c48332189400e3b2e372d80ebc152c06e9e3ef7919dc034460a76b6e8dd448e3edd247a90babcf6a472f374a495823caabaa9e1111e12a9defc5a6ad24fd4cc0ea229b4b4344b30c23f8cac8a91f531465b7c8c24bbd0ea3e5829b9d06ae9c1b2d3fc543b84771e6983f8ff189aaef718e0b40f06e720bdb1344759b8bb54a8ca630af8056687bfd42666f9f5e4aea6a9193c375253e647bc3bc3f81ecc7f0fbe4390ec9febb20e803f289fae6ccf019e32ef36d6fd82a1a099935bb701fe0e83c11b7405345b354926f603319e888966aee5475875d9253677381332560db1d24e9eed0c241080035d7724f758641877897f256d6ea65b31c2378cdcd546f06f01ad6bfe46cd8ae6cccc6096979b845cd785b0665d65f94946e9384bcd343c733a883a09aeba05bac843644efdb5ac229e20639fad7d9f75b11947c44925bd9787b7ecd571273aab3794a997c1515964a774e7bf1252617924f3ff86f7d753a6c60238df23cf8ec556829b8f40997d04be983372937a985759c4ed62fe67e47c173c753be6c6f9f9279054a4f886195bec986131c613d77d4bb16e2db74cc337226794bef78010e8fb27cdd4125a2b2d4200dd79bf6011f3c8d5d9a031016aaafd36fa8454fa284bb6383977df766d7256ecfa012158e2aeaa28d19485bd23e8edbf5867fec0544e1b49e1c06aee3ce530b5808fa01b9d6342aa0799b5253b4e38eeb43c383d3426e4ae779dc0a1a11d87af5aadfefca10c30c0a79fa50c3e5e516ea9e4073f170c1edb4ff22a7132202e187c6c5983f7552bd5713b1232a9ca431564df80f21b7c5db39570cb959a3c64a103379c01c63e97320778cac143c3aec21f9d632e86bb6a5555b1b5dfe2058022ae3c31a8c5818385390ad84c7317b6ee2fcdd34e3b4e886e0e09cad6abc93c3155c123153b2f262750c715067dc4729acc9bb3a1110013dc64308ce3bfc70ca253bf80400e061ac562b465216c2b8c5617f66d4794e34d51e0e7100d5f0356969e78531fc8f7e59ab131e83fe1ae3515d524a8070ea765a55786f83254939da5a3c1a13598ed88915c30935a5c5b3598195b5cde665e377c2609a4d7f3c7d03364a86f87301c784a278a4b6bd9964e33dc8bb6c5d84368888ac0859f12e229e9787f599cab2b3f97b6d24327bd1fe004fdf2dafdb9af4bf31269c95726abf11f477f6718e2b26940a32440db46b4f9c4271d8495d42ba39e9ff188984654ede58acf8147dbfb0687a438525d11af4c1b1ae4ee8d0d7b5856f26502fcba8163a49b0d0c69f94cca1f6981612ed472559d2b44263024398d30b9df35f996342484a33a2cdae2414a63abfbe7ce85deee71d6e157408cce123dd73432a27795a089adc37868c33976539be0cf80889b44a41f271b88d38767b7543ed9a28ae924ed075a43b9815e7aa574065bce49197c39bb0caad4860bd55877b4aad538a385d7ca9a50c8c3fcc380bfb0a264c1f120f659daa9a36efd06a7d834579c6d58559ef52b09da0609bc6a50dd80a4571c61aabf99b4380d5e1641ff0b68656c9f54d967f95d0593be81652a1156ef34f9bd236b306cc5430d6f91ad7b81b4bc9a5e41fdad5342f6a917aba749e11f5d4103863be2028f52ddcc7d22ac02a8409c10e71e98cda1b7d0cca1e1297297c9581c7495ceb8bfb08f592aa5492d9885caffec394b7fd767b5d3262b0b262c9274a430ab18b0c33ebcf4f9196a43885da6cd0ffb04ba3b9fd9e7217ae356f2681d2efd1e1e4caa8642731de09497b4b72963224f5a83cd7120d33ba9c6714548f04aac7040d2562939ae1186586a57f22234ff4e48a2b443b9a09989a5b63c2287963353782d1ca14ce6af314444b44e2ab9d956a8345b48448b689a299f12757ccae8befa018420116e121c9052dc64b30d5f81686a16df5968da2ebdf351e3f39437ab7a4aabdeeaa380a229130b26d6040d5fbf78d7a00818dca4e3db6556bf183ae5293d9e6abdb7ecf5cd67de70d98226e7e3e67576b2fc94f18599a95d6db21c66cdb3e17ca9eb8ee04799c6e9b25bf426f76b2985ed615c1e55c92802bdfc94d2c9e45a29990fca52387372c94a6ff8b464dc95b58b4368ab82665f61727cdc9f4edf4cce065bb7da7367d21527b1a922b4211433d6743f51e206dd18f15b912aab7d0af342284c89f2ec28309c4778bb776cfcf9767d403852a9634bd7155323e09277ee3ca9e030b1b820f1a85325b2a61c7145f28337094e096a9da9b0a91a0c26b9d1692f2ee749dcd25612226c5673c78d690a04a3af4d8959c38e205ea1c54be0685935d4bc606cb33cb1f90e907b22ef2115f6606a577d7e6609e2a51a9a27959a2331face552a0635bdd07626d55b62c8db129789d50e5d3624adcba08e1b26ad8b8b46f4387dc4828f8de720d1401c2f754ea45e9e98e59d816ea33b93b56ad78f62ecdc844949b638aa39e83403e8e54f6dbe7daa5f4d353188c150eda4b8106e084154d8f794036d43f31345c7e1d59405f460f045efd88e99d962c5b12215e699c0f92a3fc26a9c04a8ab390122ac468a6aade00e1efe8710fb13179f8177b02d5c9cb6106956cdb7d2a8c07af174fe24f6441d9c4efa1f98d7bad7d3c206f86d582f819ae988917edb29446575100d90915f5cd43f6498c61df45a2c1ada548629d06f3cf9bb49d4fc1794c5c70155071acc026de88ab9d82a8ccb735e4270c269709c0453de0fe8e4780ca876412b8460ff42171989236936f4fb718613d5008df7e44f9a6b72584a21154e09e412e64c4218e52766c80ac4e39a04f854fcbb302813044f4a9c93f6dbc41a65f9af04e39674cebc23cda9185dcba29527647d24903b97db32a176724e8036d4f39079a6cb5b15ed9df6462362b94b0ddd9b89b21386a19bccce0ec47c0ccc9f62f58ba54764d9bd94bb3025700ecc6fad91c6bec4017700a0592714d08c8dba6c7aebc1167aad23fef8485712dba4ba926eed54af93eaa85f908a84691f6340cf72a77363788e935b1314d5fe823e87e9c1a80c8e691d4aa5aae5163fbc6c7bcea37b59288c76cc528df69c032545e7420a84f5599e4dbee05058ed605904e25c6b00dfad95d208def8e52d76baacd64848c96cdec469a633109ba376020739b8bbb1ca3f723df6f4e4922fc9a45d3339dcecd679f0d6aa1b493aac40691bcf6d2e3a6bc1d6f9b4b5db860f7857a0729d1524cf8119cc591fd59eef10fd2229a919bfabd680caf5764741889158903c91ebf366272f44a3d6fef86e6849e0f171289b78c9468c3d5df2703b5c637f0bbef2a097f24aa5b4f5ab5136ce9843c08996551399eb759a8936f249612b03aded3330293721a07994bd9bdac5b067357a46fb5a28bc6606e4c9ba6f28ab066e197e785ef8416208efc49872a89d5f30633ca68db0dc223062884566df8c5a6a04a4c9e5a19376a447f21d62580b37695742c280aff3692a26f2d587b06063d73df891fc813963dffea49a4db5a90a6f35b5994554fc53a74d3bbad2288a1f930e85bbfe48b0f2ccb8f955fb34a63da9c77486b3172c219d77a2c57d02bc75e0d45f43ef0682c108cd576678452d686d1fa06367b205f7c15b2e4850dde79b04cf0b3a9fb54dcf40e72211beb44a543f5c3664aeaa8147dc2217e03c674ae038d4a8f22a0e97c5ef407967e444de3361f08fc9319ac1be4380c95e744ded40f8c8da44700d9f86813ad2bdd7084e361088cee6756ae35b9d10f205ce4b17a06cb5262be08bb1070652f91b519a7d03cff4aa61f040ea37a8fbc64f4bc4c5a52e64affcdd993fed4b3134389b9916231c12202e4c0e0ffe88f88f09140e42a99b6c0c89f3c8a4dd47143ae61aa376614bf66adeb27232b01f63515b4c841189d43777333f8a1104a6e3c462a27919a73cceccc9cd271bef1761e9ba943ae9963d5047673183a0fa957c9199cb4d48eb72602ca76530511b5e177afde840ba1ad6a1719853168c538057909430189518d55a8dad35222174e119421e259ee1331640c49863cc83e14085a2ac8478a14a49ff790cfc7a382b8113fb64b16384ba721d06da22f61184b9cf4ed7e37745f9138649df108eef25f4f40a21fee276204f8a312e1da8f9d2872dd6ac3604123c209a09901e5078be04bc1042d6b5886cddc276730de0ee22ce8f353509c433c7e88a560e68aed1e891c3363cbae14bf47217aa1493c168deb4016458fca9bd59d243b9dfc80c29213bfb722cbd7e19ef7771c0d3be21d602f279536f70f5e939cafe3919f324e0a435e2e5b44118bc47c0a787c4e1538f7bb593723785185614cbc48d2461dd0ae25a8a98179d8a8723b4940e6a40a9c3bdc83064bf0b73db2fa7a1e56c878fbd3c04ac3e453d43c41d65fc307e9540674d124f6b06588e3ffe31e4d4f3540d0673dc98952baeb92bc194aacb4bdfe67a861b61e5e3da15942553d28dc4a515c8a515e753956710f135b156d118875d10deea12bf520de5e6971d2c77d1c06e9948a4f0572a85fb0e036e6d07f3e2acfe379f41df7088e6b312933ba35e8b4a62843cd29453ff3461c98072ee05f7f2943154cfd7e3eeb74848a4fa7a6701123c4e33745b94b95b1c03f9f5c02a64b9d4ebf2310c135966f0d7cd737aa210420a95f72651f8873d168c0eb2d20a5f0151b31023e69dd8936b07a65f0f17753938993de58ccc1554e57d65b49af37eaa2210f72daa25bfce3ceae7a9335fed79d3e75163de26ddde2e2fb7f1dacaabed80329546541e039036886b0ba936fdccd2b64bb401c363a0d3a4dee4b443be3a8f108ef22b5e8643250001bc99846dd261a5c73c844a3f4109da13063d96af54534c7a3075b40475ff9457a726c934ce4c8d9a7e9c7f40c631c5c369c50020d8478a3b99d67706f236e1b63d70627c23570b554631453b69ca249f91ec3d44fcfb2fd0285aea385cdceef0709c54a0823b4ce24d538f989cb0236376ff1cf446381a6b32e9efe01f99d9db1f6720b80346b99be39f99877c19df549c16daee34780e78840d2eb90c2277a519ffeb850b37518c3a8b507170c6dc44d047e923e5a592c01d1c6783f87ea129c9f81aeda0c1272fad0cee6439e16b889a03721d5a8cc7a97fc8c125b034d75c961040b03ac241a99f900e8b8fec1b43ffba0461ff9bb5ce0a3f4cc709ae56246fd84402494100d051091545c23dc5a685b5c5bd5e730230db88986a882bf9238ad597a11270541113c17925b0d3afd6ebca56072a8a220659a47c5483d5c7093a7f5ef555d61c5d68db7330ea3a278c121aaf32ac18ebb869fafe3efd58056c32df06c5a25a760b73066d291976e0dc3b04b2f5cf55fd00ee6ca34f8e112d6c5d2c9603efd7bea54cdefbd2fcd349df2b2c14631ede55e759913f5ffe0240923a8ca66d3e962d42379230421d600ae69f564175d21b27bf335c97311399be4a89d88ee8fce8403b7a012cdf97bca0477268644a3af6eeaa270d77250933afbd4558e90cb958f534d47231d520ed9566b3a07ef3f4d5b09fc4b02dc1fe1dd0ebf693ee07ac4ce8e18edb367dfb21d9ee5ab74dbba5419aade8ab4bd339b034a960dab7cefdc265c575a37e4e5b45bd6345f063ba8d1f372317ea4f9a1cd471d243502868193ce1a3492f02ebcbe0cc95e779eb3eb87e9e5e4d0541f9284a1dac1e1da55aa348fd24b7a5d0af7252222a425c1b54acddcc12dff9b492fdd37ef73d003d0ef834845f63cd500ba41d9a46fd8f52edd1e3cd32e6f039e5e9c9891271495ba161c984cd81ad520f036731ba83e3be4105dd568345514071d7ec4add8e252e4211258b0031d01610e1bf77ee19f52d65565b0ad45df739d136e7f2a37acc9a50ceb322b7af45c0b09d514ae7055cd822b0c0407533d2007c46501044ea02bd103568edca0352a2aa3b3904b7120e9967bde4b42be7987ed3c18e90a6ec9568ca5452294f3219cba15a476186322f053b95a75bbfa401233bb1d0905399402e0cb47c464470f438fc6d00469401110a683107f2f7bba0eca4610af5d4f701b2e46494d04d2b102b858654c4e7199ba8b3006fb8123562a800e80c902b975fd8264b128c5172119e8662ec1450179afe5e9fc8b13239c73221776e3a291cd786b99e27e36cea9390746da78cf8715640da3cb62dfc1071380825b2e72a7155372f8fead1d3f4fd698eb8684a1a899c0ad4562b5879f643dc0449eb0cf28412cb5619bbaf3c3ab2a1f94c00fb0f760494343ff6201ec29caa8732a43461a1d501dd81537d71960ceaf80463449282e282ce99171f0ce9eda6772fe5eee3481521e4cb680602ec8f03c12f46ee83dd578df0342fc0ca885b8d016a3377a7d0ec6c325a76b39c4eef5305091cfc4766302f366d2e0533511cd4ff7863de662452cbb1cb561af7700d4417891204304604d8da32c43cc2214d2e3ea47ec7411a6368d607e1f2f1c0b63c0e1fe3c828dce05a77a0e1afad0505214d0502871e8f99884aca5862afc5f39ebabf477124fd9f1a74ab44fcd12d9c1277965312af1ec215ebe1fa2c9e3dd2b38385a0df7fad73ae8d143a18272df288f67df3403745139b232829083a9bc9e316d34707b9a720c1512622cf961e8bd45ce569794fb081a4aa1d13f7ce7021639a9b507c029fb7fc0bba3579fcd941d20f737e938b5196cbd172d3aa0c015de7bd43c45c697bcf16adf125f22ecb933cd8c84b801b2e9d9973a00271e93fc5469f7927999174728851eead693020f469a8d011b16f0426652c1b1b3424344d49526924e73fbe02b93e7e83588fed24ea32eae500e20843b150435d9767ecc759d13d3826e53f604625bbcbede5ef9b949b0b583e450cd39c6687fa81960a7bc01306b2a2eaa3b16a1ff097e696054e247edcdc45527a9339a6d8a8373f5afee248aec8fa72582ede5b741111382c9d0450f18d533520b72d22367e193e6ae3a258087c765d3ceaa82f153b40110c020ec5f4a2d270b82418c2391319239c9943631fc66f8263eca6dd06a54f6691a1ca3be65b6d07121373441339062491cf10519ffead58909d47f2dfea57a997cc6e31b36e1231ff18750c484de7ed6a2b8fb42a8ef90fda59b405d1e020ca88c101df8699ab9549497bb96bf432bc6ba562d1ff738f2d31643a4e2f0ccda51bc6ad3024f79c342df39ba200981100b5bcbd98d84ebfc5dc519827357abbc4912cb9d8d77634d00375e08ee5c3eba32f3c62146d9b4549270f0115a454b68c386d929f80fde8721275fea18bf8c226395ff14126216162e3f14458c57a5901160f72477502878c2b7b5ed12671d14ffc8a088e4bf9befd0bbb1c9dbb6275f67a8ad0d604ef3f3c7489e8c07817cc4df98315f27668901f2d779a7c34b7ab612712291437ee4a8336107ee6cca424ca764fc25974c92ddf4e680c09fc40554657ca639830c5e6ca4c5af85e41affb9b67c43057325db0aeebf6856822c63f731afccd0ca7744b5766b1c99dc97ec629c45d2b68479852db75a35125878b12a188e31f36d266f083da1dc1ee6c23b21c45aff2de412409bbeb9e8294667cd9935420de172974660c99a7eabde36dc6dc29e03728ef0f8a9694ba2b50339205f528fa3fe3382cbea433abe34998ef70d50710ff8e24934a8c35811f3f73ec373fab472eb32bcf2cc7a501a66798226fa86859642a6d35665d0e68b99273ea80e88a09973c21062882df29b32eaf9f5ca3f2ca93c55b06ece69999e3185566e891667cb5cd3050b806ca67891c94a30cd174628a45dce7b4183ea1479bae330de56ca2735b35dacad8ec1ad20ededbee7d9aa8f192722717d90a14433ec80d33d02173cda513b8d2636a4d8342f04909345697ddfb22bf40a332dd74654ee818d840cceb400d8af430bb31a8183522e5ce4e8198d82e29b13345fd9c84bdf1e6d226254b180ae88a849a6d89e51e98391e0a32f6a26374af28c66ddc44b5a1c37fd9585d6a75675a5b4bc1c26befd6b4900d259d394e0bca5ec3b37a2b301e748c0cc1fdacbc8bf8df17b792b37dfdda8fe01ad8ca0999bb74226a3a565c98e5d0f595f0c0f842129c2bceb70f3b004836f2fb09d57d3f49c6300e3eb1b5388f8af236801049659b1dfab00c03cce03b1a715e373f58966eb2a510187baf4f051dc30e270907225433a45542590b63e27340557c292f798e0c85532b79a1c6089dfc9a37d912d2d7efeba9cd8a1304f93df0b69904fe07bac6c6ee70306865d0880357d117b624271fb18496f98b9ebcab6ca7115ae010488a3ed4453a2fc26c23c9ccdab2cdb3ce6e59038cd46b13414cbbc3403304fa281a147ebc3945fc81241f276fafe8f1f96afc074d3b09f38d90c3eeea744a90b911b39fb8bf8d7006ee47079aa31cebda10ccd78ec166cc1175632651bb55c9a2ad6e774673661029eb986115cb39a4bda9708776180efa317a928d299f91ee387e9565790b6a00430c61484b654459e120701f60a03211579dc4fbd1f2f851faefa4ae3751e0bf84bbbd4d8993e9d9a644628f3d81a9ab31de9b22215078648490e266164d11be72909f9ab345e9e5b3fd02539c648fbe618ae70b4237502200c876a275aa96c098205cb4fa84b5514be63cec66550358bb62d3bac5af7e3544edbac8d6185f40a4a5535d940339255ee3c35b7f78b68f5e0099d37e3eda13eaef17b4984f611c1836f0cbde495b8d0f22514c6da47486cfa4270472a12e3acd1e1959b3c99fe28ee7b1ef3c1968be0d5dca964331604a8510558aedf6e63f845faf8da2e0f2a44f6659be4f3685657d5fac8295a52e74c44260763b92c3486fd942bd3ee628c56717b3c096e6b6098aad14a558e70687cb37309f7a47f8bff8c202108a0bfa0abca6cc660d5d9abf21466b449288afa7049d73056371fab93e27558c095f75a040f49e187832b59a9f5300e39dc7955c72b831bfc85012ed77974f300f77ab699f8f7cbbbe7e356e5b56f393ddafa3780d83fbbff2555cef3d17377f8d3f07d3584217817955a11938f8b8ffd20440ce09e0ed746901377e53d918f185be7b9c171438c3360f925f877ffc5ab46cac5ecd3ac8e82914a5fa45e1c9e06dda09dbc1f5ce1de6f52aeb5f92b0730b4c0325c1b02df088bfa77ee55e9d078ab7324167b18f70b72fb7fa61de070fee220bdc4716b7fdc46d3d749cb525dd33f81543031118384293f142901251444e37f4bea2457dbbf916c15914fdde879035c012204ebc4b6f4e75855c42c4a0292eaecaf142a349e42f76e1d71a1487385e135b0fb94bdde05e4ef43520d746aa4f2e49a20178b2fbcdb2e174ecb433252fd8d48ae07544341899b17694e1148237aa1005494388a926bc8b0c828fcab67c5a7c361b615af2917187572b48ed8100136000c9946c2def8232ff73729137652adcdd5445b38543ccea8078d3915a567b9a39993e30ea89298fe331d6bb1f4ffba2c2b56d19b1b091f38dd98380b456e40b9acf9bbe7c57b69eb05227f67b4373f781ef0d92fbe3406194a64b018dcfbef1a2ec01781f29ddf3f6430336c6541423cd74990c76f2699f4b3cf3885753773861e002a42d0d74cf5e108d2efedcf09fc65121d095040d7d7786044c539002a4553c650916ef76dcbf2752a93a43e28400012cbd53509869e83f25fa2389b4195388612459be202525f75da4d8a5bd414e35c67a3b3f1f8a0d4e515c66ce1e4cfaba6f178379b9e695945023ada2ec81abddde807c510e3c337a0e518c97cd6c862f22f826620cd863f949d6020054c394f88e985fbc33659ea396c3d3f49acab3802d146aa79b6256e9b0b75fe1379048ce49deedbf7bc254b42fd9fdba40ea375d858c8e5cbc44d3fd404ad6a659b36c9e66a0dad757c9e4fa3bf0026ce7593bb7311ea973bcb0c23ea4566aa0be1362fc8b713d083588d3228ee5a71131bd2dcc4111a9aff1ecd96ed88b9545a6132bdbbfd23abd11d4e38058b70f503d18d53dac4ae9dfb9cf4d012553a63e81540f4dbef27451124da3e70cb585a6dbbde08f1531c78ff1faa35a9be629c665ef28bcb5dff727ee388a9f625990ac78f7de31e5dbbe708b2cce5280b23be0f36106b7e04047b7b8371e34231ed57dddd958cb37ebf4bc8ede64cd43f77533e27b0c684c94a11546246d5f3d50c1a7b33f2fbaa6b27e23d402b8559797f787e98d58807204a1ce95fc5dd5cfe92149a14e1e32a77b7ad2bdf36e763e79e327425f6a47d0d14b6ef8b11e259e379f6e7f8cc6f68583615b136784af024d815cd58615906d722260d8700781465223595bf6d269d43165a339c53865eaeba72f640c315ef758addf1d4cc4304230bd0b2e9a63ec33b11f2f5ae25c6fb217be1aeab09bf9fe3697a34756d9bae0944863ba5cbab718b7a75eff41a88ca49c2862bff2fd19b44f7963867abfeec535ff758c131a95b2cf2453a1e812f2bb5a5a53a32dc265d47542ada9e528b9f0c7926487928830777848e42ea0afa8b799bd52d008ea096f8333c08873d83ac71e22e2beaaecfc986f8b51a9ba44c4c8b883fca7f7c366a28c140e407a44c58c57e99a5c68fe8107745212882d285f0cf21c460e5988eebe3570e3e450a427f38efb8e1cb5c3f687af92591644fd66f76640d28c26d87f2ee163d6d0291c6cce42aebae2967223eb70cd4005d2dda39f960f5e6a31db929ca3e197eb04c5371f7c3ffe4a1ad5b19b7ce492c438811ae9abf330c00462c4cfcb361957de73a8a9e1c3a05ddeb4c2ee88e6320c1e3a3b9daffe79d9603b83defffb84e94d2058b1a4a431caa3be318bd2950229d4490f7dc08e841c470749144637f36fb934df21418ab621ef53a29ddd13d227245ba8b78a6998d6d321f72109fe50922e47ce260807b44294571ad21a3904da0d16cb06feea6b7f0e207b8607615038003ca34eb7135c14ea03106ffdba6ec630e73ca5a2e146175409715deac4da64d1142b3b3d02dc195f57425784b2f2792b04f6d3adf83d616612bab58b1b2b413c81e11fb0c25c47009e8407c03faf27c8a802958227cb1fe833afe625797e425238f071411bb19bbc212244dd79445f3035111ec0d2f897f4a284da63661527e7d87114f9d0829851b861d2caa55e225c4a163b913bd9bd7a021cfae16873cb22cf47f93660b2c980463817069de15e6becf3228fcae6f386081470e1ed8467319c2bf78ca2fe947dda014c185b56228f019a4107b72c721ff1daf7c13dd501bc32ebe9fc1f029dbbb441adf29fd4914b98ad84b6f5f0332aa61b769962149ea61381bbf1a082e1adabe66395994c80acdc22c54c40eae11125491f7eb0b82309e2e96ae7a8b1d306b12884c7517edf20b471b12e1e03f9e313cc14c011d067a32a2953da5b02a6ec370c39b5e93dab223a1b72b64dd93a08cb8532ff77ed028650c1c188b7f88710e230686eb3a5af354ce3971ae18aaafce001610dd737ca5161d27c38f10030093e835b9288abe07de26d7b8af3460bcd868030735e1cbb8e0ff587dc4a80973b0492c35e184d1cf7c43c845e9c8ac7db306217cde1e72fa84c76bca8c2b778c9b750641475cb4aaaa4fbda023ec8cb1045d85715cc5b0cefb4489764ad2419a33b5d3c61b0c970338f7415f0d1de2b1c800b8d716e40e0934f1c1213844be8d657b8f8c757c0b38385708bf22c1a9c4d215a89901ba26577efd0cc18c2867f5272723ca679eec58a4e2b098300d32a92171f0fc1a46e8b48bb675bf7253b2977d7da5d49e76986ca8d89a4f7d0cb204c582726dd6440ccdd3aea76830ab359a22596848fc482db8b516050db2d445d24ab991e9ab0f2d9e6f70182eceb9eac360b6b4270377ac8eb5691a446d5e6f41194ebdd964aa829c950fd333ef0da4ecaacf0597e0c30b0461ffd3eeab422b8b8ed538009c5e62fe7c5acba9b9ab16767c91e8c0b1353f0a39d49f8c71e83695ddacfb2fc95c5c6b3b96a22d99300dfd84a6c96b238b6d2bd014268170cf4c18f34d3e6d04759ebf59c09c1c712a4f093f1f9c441786963e7470030148242dc2babdae12a5f3cae393fdcf3d44185fcef878c924978570de6d7d0bccd1cee977c4ad2cf7543de52c4990c28e354eaf8207d421a409384895b39ff87a26efb2ce156d03e8d8914951cbda75530d1d6f7162cd9e26983209101ef308a94cf79dd111dae7a31d4fb3397f315f559512d35b3c0426a541d22f41bb45432e622c4b903e054e998ac0c773d7deb2ac07da78053fdcaa8eafe733c6bc4e952b7691c6e14b538f9cfcb27937b0279cd859b2934433f41c479728016dadb85ba720e307cfd12f6b4e2f93882b137ed16cb25e9258b8cfe4836f313435a6a373be781e9ab11b390198ead97c983e663094492eb3c7872950cc1c66b2f2ed4f7be73a503d2b4e1e66aaac0a24109b7d33bbbe190f36e8e331e6d78f4d2ab4ededa2f72365e72eb06ca0629505e158294f3b9c38fa5e33e94f203c632cd6a9027515b0dd3eaf06cb4066b1b15845052aa3d5c886c0d1911bdd94341ea55a8f7cdec482bbeef41e0fb7d185505fa54a201f9aa10e0fbb6f081175da07662dc836979a89183e6e1a017cbbf2b6f2cbd0b0b1d49f13237698eaa5ec0818b74898f073a594f7120a876b49a854ee234f21b76078491a745591d64ae71f6a280e125f4201d0ec485d4e3306b6b227fafb1fa4d8b5a99171fc50b6d5a42c652167d4f691b172dc27c3d2e612b3d37b595182d2ba0b4a7484b398c340458bb9dd9d2333f43b49f68e98f0e3e4c364aa31e0b482ead8f0b422e53e5ef384d2e5b0251aecf2e42f0eecf8827706535bf1d2c2ad1c4189859abf9a767cf01988102e0109be6d75317897298a62f3da8d8483d62501c2e1b0d868435695e61f92c3993cf249312bda3438e9bd024585a64621d4162e3234a75d2665ff49e3e6add0159c17d2ec33bdb17761f4c498aa2dc3f390d88e7386b551dd253a6e158ca8399149f789993c439359c8544508f88759f9f6e0a18001d509b6e00bcb8314121fd95549737736a9378bcc8648c226b25897c8130592c5856849f268118efcba78be481578baa83959883a726589b7d0e497cf004541f11401e65ef1831852e8a9ff4a032a6c966eddbab1b4e708f0271bf97de1028f25ad46730bcda765ca28b2106b2a7d76590d4c7c15a096db8b2eb5bb2341d35e375ff7d4737f1b3006024444fc4731916016759050ebab457fc8eef7ff7bb61312b59c301d7ac41f51561d28fe110f6e7f89abb5fadd2ce696fdde9028bceb9ca5c5a1063eddce0601af5a720979e19ac82732316415143a95fc6d1b28d6668c92632cfafdd25d0960ad04605fc875f8fa8359393ead3c7bd994326908e52cacf54aa32dfd3db443061d250eb39569400482fd8ad1e2c6e87389fdb195576e6932f38d6ade7591d66bfae89d11a61f4bc579eb498e418c1918745bfa9abb072eccf88e5a38bd3c622e529762d3e4833abca98b2d65f3a8378775f70566da09e28fca970afcef9d54d062c5304ea363ba5592010b34a0756c79e4fb4bf5fa9a2fcce53415dc71e4ce73312afc656b43630a736dd4d429e9033a11febe533086cb510ee9950010c0244728e3c9b51ea32091b60ab8f3dff9550b9d59c2822dfdf4a42f6de7b4b29b79449a6030a900a150a1f468f8529831aec64d8de282972d84ab303e2862b165a510d3572d84a393b208805d7adb08bf96b7e68af006cb0d97fd8b0cafe61cdf66b21e223ad433f07e9ba8ba76708cdcb4d3fcc327d9d256e1863148bbbc286a24afd4366daab306e09b638922553fa44a694894c8fc8f43ba443642ab55c1cfab592318629fd21d4726c2f63b97ded7fec6befaf75d83e1087697cb00576e3b6ef6b12c6b8217dcaf4e993663da73b3c5ccfabf9f2594fc4e8d7d8c5dc2d1b5cb7c26efa4827a5d90a0a48769acd2eb2c9899bca394e5c9b23f967835989931d09ca30cf18375cb19eb8f21b0d29a64451a306328a91e3ef64c9d96071e53b95440e3a0db5d23c71cb5df26f8cee2f9d70cd80db59b610cab284c597dcd559b6386549b964f96b44b5505f7bd66421b11b6b6224f5b5af3fb7f81c06026ab2c485188a2c3db593cc6f3ff10f90eab9a82ca7f669bf3d92f81c66c27d7c1c9f098fb73d10d24ae2c81fef3b0ce4616bc12cb555fc8964533df74c647e7b24dc77df6126b0900701de778fb9effef6794ca211aac140f18828e94888868826dd8f2e7dfe6124c2acec9bc06c8e302bc347826e7cc3529f7131f3314ae2c87f2020a4ede3d20c068a4f1828ca442d6d4b9b131755f2531f5dd23e56f695d5427d7f568691d47716122f625409a346512c064bfdcc23fddcd75ed33ef53fdaa7847eb49fc1402e2471e46bd88f88b40f5d48732216c5d991147a8a127aa2383eba64b33d7914f70de33e944235ef4e1247fe0321fd687f1f08e987e6352102c0666a3050cda7fe6220a41aec4b180379127612613358e6434f9281b56cca52aa58141f096a02a34b12474a169208d33ec234560baa97f91fd5cba8927e547f319024c23229858fb6efa961db879268c34c907eb8df8e3c2824145051c510130eb37ebcef36cc42e27df71e0642621dd9fe000d4342a3843083031c588ac56040420ee3fe86ed3bccd2bec3ac23de772fdf470e6ec39ce492c4d243144c4c5f623158c338cce4860dc7b4d730ebc84f2dee00829472739143f9946912d521e57e3e2329873596a51423a31c94322acbe7be59e494e56bd34b967368c6248e9c5a6ec3365894334da6db94e19a40d411ff88832eb86bfe1117d8b8fef31dc7e0a00b2fc0e0608c21babbe330fb171c8c31c0907dce18668ee185e8b027475cc00d3564a5cc19d7cbcd6484d30d6ec7856211c51ffc1668861789d33545189194c37bc3b836379311560c60c43c0137677737cda45dcd39e39c394e6efcf9b1bbbbbbbb632bab32e0b2d933b7a4d0af6f2e6870e70e3766198d3b3cf4bb329b2fb3496b27ff5d07078f7e591cd93fe6ecd093ff65e6452f6eac5d8fb876574f77f7e8ee45425cbb6bd22c739732d5314f77c91885c8fb17ee48ec9f750ee6ccc1a96387fb39fc9df9918d1d700a9739e77c1feea2c9f379821c99734e7c67099d829b1ce67c50841239fbd51791829c3d38a5899c7d179143ce5eea68baa10573fcd54d4c3e72d8ca5953ce888811c194b3ecde5eed7c91830678c0a20921d6a856ccc062da9b2324bbd1c61da26827cf4b71b002e34316ab41b0d1c32442461395b2030f120649990f3e786c4e891289c0004a52294c3c0e6568512d652495a154c6d2aa0b4fae7632716bee2e4a20c5a5ab12588181a8a5c971dac97ab94f2ba8ef12e538bd8298e3344fbef2f5b28b126cd1c0d3a1dc5bc620cab60b1a48a1444ca8d9947bba7422cbbf915966b5888d91e5f53580e29821b45082dd10a1d8c18c2658f7db071473f8027643434181750f4696e16576d1934f42d45dd23f4cc84eb367df4389bb69cf72f221675dad363bb1a0b84be4abbf4cc1812a650c61850da060fef58b58e29598f4c52a0a78725f70c1416f8b4b7103197558018ee33aa2308519414d8c3adc109ec444233433d4e409051639e208481fc96d2e3868c6e57233d9a004398c42371db5eac00d57158aae931dbb63c76e4a69ec7e3e757b0caaa3648cd925b667cf09950667ddd51d637b0f5cf76b4aef965fcb2876f498024e7677c7efeeeeee2902ae55689dd5cada6e9cf3d9d6e8f20bae5bd8ce9e1de377f7b74eec627f6c01275fae6acd3e1c6e7fb893af9452ba8cb30352cadb3a2f5b254e667708d2e32010eb2efbcdccb9673e1cec7f50c68cbe3277a7594e507c8aa175e6ef906ec9f0252d53ba92835784b8f2350d87d9ef0023777ffd92fb29762e73665a5a594669e65870d65d518cd6a1220e91fb7144b9f1c38e8a31fa55cd1f07fb718cb938dab87115bbf13d3029a53d3b3c4fb166a96635db866c1b11dc397138b3cc7e37c392beed577d2ba3b2f78fdd9d7ddd19c5386e70e5873e767a66ade99a0e4e1274dfaca894598d83f3a994f2c61ff15be70ca1186bd9ffe4c6ff40891b9f8873f9317cd6ea1fdcf7c720d4cfe3e6d5f9c78f609ee1da285a0e7e8c44526e96bc7d1657e4ead359a27b77848767672704b70fbfb7adb36091ab4f2b65cbe16e1ded35da4462f0032a566a8ccb11571287fc6cb635aba13475c6ca68775371a9cef3ba14a7daae2663672a0dadc96ce60d8923e6c8b1d2919a53c626d2b92f585a6f92dd10dd8fe0acbbbaef748f71b675e4c82b1c9ee763bb9a35ceb49e4fb5dac675292f73aaee76f2e33227d3d17495a6939fad996699c3d1c96f666e9583bbc1c1d2919278b6ce7cff28dd250bb86e8150c514367eb7003cd6906466a3180b4984651f611916ea60d9b37c5459be2a1b5920c356e2f48fce52760ec0cca928a5945a6b6d5118ab1cbfda23bcc8a2c4e5f8d4c6bf3a50d972fc2c892326951cffc61eb82871452ac7f7b6d67e36fe4521c7a60e3491dd5a2b03982bb67807199d61891d873f932398ad8d292e624c4a897d3a6223ade31f8ae05662b12d9a80f56bfb10486e1f5dcd4d2b77d8a7717cd222377eb83809285f3e8de3be93798ab48e2f99c14bba9dc3869a4170cde393db5ef02537930f5af2f6adfcc6fd01f07463535c5a2de5248ee3efef33643a806019894d72f418e68a1ba31c840293fdbd31ae7f04b3d4b494a397ecbf7ac10d1b8a7bff25ee9a5ac5a12be51a73a1288f41453dd5da54bfd65a3fe4d9a0b2dd70f842debe7e5995bf49a09bb2c561132b59866eaa1427c9f28c77c72804336e3863f689cbbe5b524a29a58c5c8d35d6586394517e11d3cec12cd7e0524ecf468c92f6d97dc7fb5ebbb88883ee60961b74d91e676ae61e9249f9d3c1a74eb3643dbb7b76cb4c6632935996cd0cd7c8960fb7b117391889da3bc0048a4f3f2f8ad3bd03489867606e187d082a8cbbbac1d09bdf5fe7a08f31433662ae8c6f23e67a7c0aa5907cff6c6e57d4c8c8fea57d6bf3abb3ce39ada5f4ad90dad50c71e7afa0298935cbcf9a04eb2eeb27b1396b1df934b4806c3b5b47be9d0fca973d1ccb47e67e2905c0148414333c4073300111c5b5a1250d252d917afbcc6636b339e77c8f39f6db2b1dd710f3ecd8c3874b7128434dce60411c87e53fb3e39e1c64dccf67a89143b0cb53ee6a95a371e277ebc45f6d5132c30339ec2625ae8d1b5e2f950a70e7dd4a293b32191113c10a1307a0ba4bc76164be7e7c925fdf872022bebc7188fa47ea7ffc28a1041144c058878e999c7d3893b79c7db8e5eb0d913985fdc8c1fa32f5bbaf56c9f555f55951dc306e5fbff386c8ec3da8dc2341405c161477abef44db97c433228383f525b0628a650db36ecdbdc9562b165e70b03eeb1dac5ffd48fbd089b4291389ea911c9138f52fab059957fd8f8cf640f3b7fadaab708fc4a9bf03038f13b54efd1efdf2211aa77eddc1c1f9be1c3964647672cd163b1707abadf56dadef6d71fdc3e8b18ecceffc235f46c9f342dbb1737a95524e3ab36c4a49a5ac3ea79d2d07e79452caed3a4597539b19b5e03783297fab9ba59dcadf3a4e6efc69b54cdbe6c649aef36ef3eeeaeffcb7eeffef6da94e6ddc96fa7f25ce899c2771da29abcf29a59cd99c524e97f289ad22ceb0b5e40445adb3ee9add3a339b825651edfbd32f04734eeed6545458e024c697f1cbc1049a990a9c644ea693289c48e9444a27d4099d73cec982289ccc4c054e3227d349144e3c21b8e87266b45a6de33a959674c54ab47265ba96894a490e7e63549ecf0c0d0552794ba262508c45285188c8280e5589473435599219a06cbae92e191c8ca12561782126c9170e57147f377004299245cc314879463d0a70a163ce0e8f9292b6149bbedc1f1b4797a4cef36ce7dd7bc3792b377aa909adb20793c6cc1432a0e172e997a62a27d052850b1b596ac6b832b999aa58996983a9cad1115538d0441521eeb57168a78730d9204c9511786006636031c9034a96e70358e4b095b43497179eaa3cc91f8af90053ae3fdd7542ae2e19468c0f24e181a53b27135f260c261360ecd818b0e155119830ca99053383eeae6ecdea68051953182b02232d72f693e9e805464ce8d0a146110336987e28d2c1da1c5944b93182a1951740d8641185c3053fd42859b941c506506846906443a58da1191124d5f80084cc1651344519b85928cd38a15292a962289525e972d183b744a44201944e8ba754144ec98ba7c40b84d84440d42911d583a6c511a74314ab14db86a4d42dda125484a8905da2ca0f3e24b0b2841519f0e16268092e443e5abc2cf1a5089f2c96183384cf164346443ff86c5992386dff83c14cd24de5ee220d2d425fcc4041814cd29d2c90697a8106d2908109aecddd451a5044dc2d77176944615123872ed6c8329df87097dc715766e377dca7defba6bd94c18803e8a5bb2410e8171843ff986d976cd6f399d90269d41b22b3c4ad33eed76a1cfaaa8ffa0855c8f31ba49f793eb7a580d4771b87bef7f9cc7fa1bbf9ce90e7b5f6887c59cb2d91feaf85155f9c519d45ceaec8a87f596e77d169e56aa53947c54e13471b143c6ce19aa8a22bea21851da23040c490962d6650a7405a434688034861a412b2872fe893115011539f504a69105ad5d24d54a6c8613b752942c5095550ac526998a83041e56ab999a814514ca5881db4cc47c1092e891be49b9b2989189c80f3a2559a4de9b1535ec76d9aada19991b9aa1c2b1c376c3ab861e9f81d1ee02ff7f78f0f3ef088d42c9f6b79f414c7836653a63810b84db333154296e2c0158e1b3635343415de90e5733835c5d9947c6e8408a8b2f0c0273e0d43ee7c4b098ad30a0a940d94282558501efcd60f357181a21daea0c1c61a691851a558a305a935ce489ae2660d2f86a050ba0692132a56fed6e4008b1f96bc7832c61731a2e062c150baab5b736fc64508281651300a6c4d02881568994ac8a4216b54208db29965138a932ccbb21920aecccd94040f39fe9dab9c25b143ce8260adac65469b8325a6bb26b6310bb17d03d7ee6ab0ed1230cba694598c38acfed650d17ac8b22ccb683044520dae88b28124bc6831489d08b0a840a2e004776b9068c10e52ca237106dce7fea17d7f03fa07fd950aee1724c8fdb07efd093dbad1c80ee857cf9c734abb49ab24bf29a5940bc8f4231572affc9e9e9da5091659feff02b27c2f5aac4cd13df775d755c15da9ef3fe22ed5f7ff44317470028314d12187f1a8c582786ba66753caacfa521c973598694a66373516369a5139a546633c8a4772b5e291002338e5964bd480b7a7e2900fce72f8b7dc1d37407077647f9e1dfda38dfc57d3385926674f19da5b4195a7ccc13dda7bb37597f4183f5b2ba394f2043fbc6374777737826bf9a25974f90d2342034ea69456b0289639e6216e4e99e16e9d397b882e5be62634c6a4212a08b41f660dd2289a6908fd30822e9a0d8ae0414341160fc801cacb165ec2a0c19509823574f0d61812a2b57811228c249650e3a9897a450d2a3835445085460927a2f801075fa021544150031926033862c4a658e2891c9acec87c50434a55a3082388a04fec7c2b8bb28217f0f0e0b7fe0df0841529c2a062832435a0c8928d6003501a04291d1efcd6df3f410bbc6861811754a640a33e11c68c6d4b9834a2fc4724b65412acdece39e7444229cff93593c60b1251542d371312557278bf09aeb9dede1f89f61cf614b516b35ae83a8ee39e89fcee1b56412f1747eddecca318d4f65c69938b3b5f22fd70aff9036918c862d0579ae6619e0df3d0d80ddd3329d261a4ecb91c38bc6117240e7dabe1ed91582648b40d5ffb4d7a7eb3517b24f637ed2d66b98659ee340ac5a11c6ddcf884a31707bd222eeb89eb422d04e55e85e0e27f38ad937d905bbe7c736751595954e29f1efc30243c8a9cd83206261f89cb77cc9a482410025ad094148349cc9af8c8f65afc52b9e58bf523df3110527c20895bf60fc7c94c82606b29066d1f98bdcdb22ccb223824d5b0b9e2e6f48760d64de3937b36bd5ffa10f2e582c4993f52b98b70bf2371e63f10d28ffff62effc74e8b813090c4402de50c6fb4b8e5c7ca7efb0cb35a906f1f89ff862d66c271b5165161e6f94b6290bf56503f73ced96268cffc2093c9c6847b560bf6e5236043fa79ed6362711cca8a38fb4de86bff43b5fa1603d9af0fa4bdcd961bae5831c60814bf6bb3e57af69cbb3ce79b554ef6195bc0d5ff205bf96282649f893fc784a5693c40e8f7c490c45fbd642508fda6944279295a23870d26d39a5124a864ea23d3ef03441c23b875ce973f1d90fc0e378165f4332e73fe117cdc72907a19e6d991c40d5b9982556b7fee7ffc39fb13dbcb2d776531363d8b712c1fcc92df3956703f3f0adadb39e2bad533c6d7bfcbeb7845bf73322b479611fbf52b66dd9a2c2d5ead7270e5115d72d84a3df283c822a72cff88fc9f2f593a9076d0478e5f9f7e37f9674ca54f643ec5ac9eb93d21501de0bac501e9951228db23216a47bea6affac70879feb7e6e7b84bcaf0b374c9a738e6c41c75e4ce71307e7c95120c2c2c6e2f1f89f68e993813a41f7fed99c8dfec67a586edd76a1b56a547363887c9a798097da41fcaa4bec4ac888f64b056021d742b7172b4e181607422e6835eae7c6f1e0727eb899b7d679ef9d917bd4cc1752b74a8fee1dd3841981c32b96315395291e37334c789ebc9a7de011a967a4e7e4462fed9a189504f7bce6bf454d8c463b5e0bdea7fb2bfcf65a00b6e7d96fc86ad58125f07eb372c47ec7e971cde5c7fd6af47527807fadeef90fd8d2d777b4ef535ec765eae6a86a3f95ad67cb5a1721caa9d64751df771a87e94523f12d58f4af52397fa714a18ab58c9554bae1d2767a89fa47ef48478e6eacf7c7148e2d497a99fe388bb04cfe060adef55716511f952611657592d78af7a24deab52cf84bef7489864f58fc8d7fd5abf688add93cb7dcbc1c9fd77bfb0bf686fdda1a86b5a8250a02505545233c7895b13aaf9342ad7986797da86cd98bbe8539d4ffa4567064069f4af4d4c9f5ac7dfeb77a514377e68677c9252fc2597e437c929d24952915e6415f924af4828894546492d336693674cbee8d3d3139025f9d2b0388ebf96262e4e6078e9a27dc92ea39edc1b62e3810ff4893ed1a76d481b13ce39673f14dadd3db3c63d250f735a1e1ac75669250f0df64fe92054916328876a4a8250454bec2e305268667366d14a916d93e7901b39fbc8f99c33da39e7c491336c3324eac718638c31c618638c71d639c7cca1d6914ce88d4ca3b531c624219b82ce9b84fa077df90ec6aacb7f01c178982cbfddc58432284b6cedbdab1598ec4fb4e4531cf450fa78a6324a30fea24512e7c95dd91f85490a5282929d2e49a14d53a813d16793a9937c699a53d68ebe1c6847de109b9c61ce03208ee28dfc6a72170edac571a80f0cdc5012492277c97f69551cc7dfb5a38d88db3991d13b1c705ca5b97f4636ee963bef40ccb51fbfcc58ebe77dfc648ede0a137b2b4cdcd52f02d9779824f47e7646e811f975ace79efbee6b39c8fdfc4007b9cf61c6bd0e729f61eb207793b967a1fec43f0edec820a46cfecc382e7b40dcd066eeb95fa1c7411d6d5cff18c4c1c8e108ec1059c9f58d849c48581c7213e87b4e92c02149a9033ec06892529ed18abbc24825270dc5e02e2a3153a629b864fa0af09784d17825d32af251d6d58f48e7faf2bb9187e46b091d52338f2937298b5f6e70f81ec4cadf3f2213ad439ffed7afe88188439f66e1a122d30f7b442832fd10271eb50efdd41a77be90a04cc5263b147f7950e3640f058c94303e454c04e32f183a7271faf1887e5c72d77c311e14464c98d8a54e995cbf9829d5b2a74f57ab7f90ca78d44edf24874d5c90d6ae9c3a0729a516d7d0eff17be3aee956a2b86e85b528bba432b3477ee4477ee455dc8afb15776549585c8b2fb92bce6ec995ba580123771726e1d22fb7d2715dec9e9b7ee447d2332233f7dd713804a2d34e31592c6a88ca8c9a510efa9d56dc8a9596026a51183b3bdf6a28177089424b0684c6c8c10343784b60400b2b2e0e476ca1c1215689b47832438464690a33a0cc08a20a2129c61942db96338010221a89314980051351a2165a589924d0e20a0f28b028c41ec2ac76be75e394c3dfe1c8c8220c0e95034e9604597891c224450a2208b999a47822ebc8cd24c506a4fdfe8ab3f851f3a153331b64cee69c73ce39a70757eead59dd3ca77d604d0866076dd6d262d6acad1f8b7efc4c8bede0f7d1f3e7a6fb470391ce42ee11777ee49ae370e84f43cd99866d90d9e2e960c52c8a7da257275cb7a05c9e22ee8aef60e7803b3038f8a402184d5c7a3a36eec9c96915f1978f9ffe41c3049a34cfddb9ab96410ccbf5c789ad96bbc2beab8937b0e360ccf1a666b5521e4d06541447d99bc26e8ac28a2d8ae20439ec2efe956691931d66e2866076db394e6cf99ab0f668f03c310f1e6eebc40d881b72e390027185f8dd5176c4b1c58d1fb6f26c1d1a94dc905be290066f8519ce1d77ff9cebee3e8c644f6d90597ee733c7305921d43343203f3f0896a23cbfc65f0e739bdaeed7b9c8fd707b99ef87c15f77e67b6436d79da15f4dc3924c7d4ca1eb7db7baf936995a6badb5dad8d4c84c192c53f336d806996b70f7057170ceedc356221244666666e66564645432aaaff38c6a66e65bdd3838ffc6f79b6a7b990fefa652cd5cd536f3a966be1a666666becee008dcb7b9d2fb3d418a6cdbc515dc7170c7d155cd5fdd5c99fbf970f0feb6cd601aaacccac17977dc35b9577d354c21def6d3fbf91fb3102fe696bbbaf7f0fceeebcf7ecc3c9fed81b86bc349e4b49827d3b781663a79f070e78ca764c0f5fbf4d727d27876eceef86dbfc7e717de1cb5f73b5ffbdac1ae8d7b7f627772177035c4afa1ce582c16443f0829be1310a6431cd32487f1fd06274f3d462838db044740fef47800cebaab49466f9226b93d21637293181fc05d7f05052185fef19decc09a64270f439a40939c84869ae737993ba06e88b101dcc775075cd7df9e53b17ce26b5fc364f9441c81afc173fd8a8dc4f9f1230e9be469e50f89d9f200e27adf7df6f100e2f200e2cab71e0d42bc1f12f3f63d8ec304b752916b08b2f7db6fdddddd5db7b76d9bf78d6d90d9fb3a1b9f4b7d3acc108b6d347c4c6dddf6c1e847037d6df52db0d2af94d24a354dcbbe523a3dd788b86e4597d3878ffee1d5cadebcef36cee6cd05488e3e9afb362d3ec5d341708867b075fc71bce03638ef0c5626c972366897c40934b3219e2b5ffc5f5725c66ce5b0c6831cdefcc8612bcf9c6c420e7d405194e71679cebf50c420cf5f45c9f3ff03b9994040c615a4a982c113607c706c48a1b7594b3077176a082dc1c92e4e6078131729a5635f72294472e825142864dcf05f5ef96a49293f172dc1c9cf98e0223f04929bc7afaffc411f3d67927c293408b195d376e46b2a81522639287766d28cd9d4f5ba0f1f9cb199e4cd988332cfa424f9ba32b4da27b138a8543f29971c94bf7d928b83586613cb549a611c9a312fc344524ae9711511378c43b19964eb9d1f7e12986d1cd241c60d67529634324fe5677188064729984a9e1f0f1ce44fa8ce0a2ec5d5d8f80b39c3a1f649b29cfa98ad96edf7b80759aefdf63ee599bba7b294a73219999ab9297b7f4797ab00fb4554f87e5cf85e80418619400ef3782eb89ef5bec73d96fccef339d5ab986231d567efaa2c3bee72556fbfb94db571aa8faa8faaaca3891907587237f485336fbf7d13185cc0a8f16dfe857fe353e1cda9d4dfb0a909fdb5cf3c219ef76d5df6edf9bce3bad1e078c569341cad70116300825c93dd13e2ab2bb2671f9ddcf073401ed0b18f9d940f32aeb6a49edcb093413cd12537d3135c320072333d31e5e626e3d577c9e1ca762b5b7304d7ad702ae5f846a92f03aa4fb86350f9e2e9092879d3bae811d1de71e8233b8f0e6c72bfd7f1bbfee142b70ba10cb24aee6ae49e14df521cda6cba93b41687da5bdb3a6e9ffb5a061fd5b1384e7ceb09b1d8937250113b0781e8869e1495c0b82be4f12b397e0c67929391f7d1dd9fc218c62f79ce8e01124e56e4ec33196415231d03249cb0e4ccaf441972b2c446def7d872e5f768ba12b3e474a71e4c777e354ef146c6a49393939393939314e3d47a1fae0a8e139f47be26ac888e28f2bb1c6e08aa50448bfb1287fee4c349a973cfa889e5df63cb65cd8f39ec5a9f4305f7731407a2cdd13d361991461306c18d36bbf2dfe3e1da1e8772224b6c1d0c27b944ec5aa46391d8931c941fa51492314f8d1bba8b7157d44183fb3d926ecb212fc2765f19c376c51d6cdc29b31ed7f27c032041699dcea135005250e374ce7088b55c8652ae1ea713c4a509e2de08e272b95f2788bbe57edbe90471ab4e1057cbad13c4b542b823baba09b9be17f58f25f9921f027fc299c8a9a31bee7030c410c21077887d2ed5e9047155a9ef4e27884b939b88f63138587f7a444240e37a433cfb3c4b7143277222a129ee0a1d4a51fd1abdb890f7f55d8abb3a56f6f79bc02a2bc39f65f84746e681e6abbe09ac7e084fdcd089f2fc0cfb8ed3a51f950010c6f5af1f0360674ac541498fb22c6a1d599f0ef9530e35a1226da7e9867428473a44a550220e6a7e6145088abfb8583f90bb681687669466c475778cb11ccaa22f541c477e8c922f8fdd33d51bb7d18d6e74a3945afad172eeeeeebec59f1ba7699ab669b2c885a6b85771f0e893521c24a2e260ebe8862ee45086a615ebde946e6aa595fd1b1b0c7772c8d311132047207a8cdf0eda18b1f5ef5086dbb49303b6be045ba49452fe4beab3a3cfd1f7239be6b5713b6e2e89ba94810b6550393ea7434ea12cbff93487a2a6946f0e3928a1244e7ca11c632cc7289dfa294a71304ea21cff93c1ad61e62cc866cc6d1cd085ecdf59be848ad1f1cca07010a3680cca56ed3b2a47cf23962c633b0dcedebe6f0f9edc9d23f9d6d50bd9bff154e2a6984a3426ade0babbcb88424d383621ddfe303615750160433a387792bcb0e24b96fff1b37c598953c695efd92b454024022aae1436931630d97112cf1458e5242b1abc498c35140dc5ec0f5c7d8fd52fa7880cb02a29801942a5e5aefadde3dbc1faae307e7157c53ec5c8e7b56fa3225fbf773c0aa1074f80ef9df72b0e766814e4b56f23d8d76f2321af7d1ba5f0d50b91d7b013190df98abd6800df3f817cbf15c0f7773fbeffe6f8fe9ad5f7af707cffcd8defef39e1fb83f07c7f91d7f7abe0fafe235ef82eb82bb40aa8007812be3f89bbc29cd7f9fe25237c3f90083113827c0805004a094332522e91ea9b7eea1b7c9cef10840f21890796d677e8dff23b9cdfd987dddb7c87dbd77cbf7d9aef8f5ddc1586f83ff80effbfeff0e63bf8fe28c65da18e677d034d9891ef27c087c2e747311c5f8e03bcf679475ef5c918e0693e9b4f4955e157df1759fd4e111c03008243ad88cc0a87401e47919da7c14a6e911d34322da88afc8d03ac7c7010920d65be870702c0218e5ffdb8e1015672af4f8f0f42c281430f2a101cfef81e45766c911d1e3c8e223870e030c7df2882e3c60721fdc0a15191efe1b353e477f8f4d8f920240f7088e30590038737fec7af5af091b13e342aef73f8acb092ce27c7cac8e7695a90f179550b3b3cf820240f87397e001a0e570fe4b98f838910d23c09588985c97c10d209301e1c72afc13ccd0676c2cbc044e091798f050e87de6bb0af47b82038082924e175b0121bdafc082368cfb96ad5f911b0921be48390341c92f0152ba95a7dfd0858893d01872358988b84d7609a8643d55798563f08e9854323d8bb828c007b11b0923b8208dabfeabb9e6341a58343129e27888d0da24323130487aae78278dc0721918043a320afc3824d90a76181049d0f4292c1a1f727a870c83dcfdfefa68083904214c2d6e3602536059b0f4232c1070eaf8c0a2785160e09f03629b47cd8bccc0a178732af4ae15306b84270105268421882c509000e557f4b48a5707088f33c42f82024150e4ba8283c0facc41200873c6c0a0128e15529a87048f3a914f00e4148aa202414706894c20740088f14be258447eb83904ac0a1ea0390fa12feae60c2fb10826385f8102283439abf4264ee07219980432321ef63051c211fc20a38217c10920d0e65de041cdef7f1350518c2c24aac45e1831a9a2136343d1f6025774846c1062ba91987364f33e4673e25351ba95043040721850408bfef002bb11f745093cdcc7cf0e1f083ef002bb9443e1a1ccedaf3d910d667acc40e0942a219424333338466e683907a706834e43b20c21af219910e581f84347148f373e6b3afc14a6a362a802480cd46443eb0445090446c7028bf062be932de2108c9a6e6839008804323228f42013ec0a191d0c388fc8795dcbc4310d207df0721390e6dde250e6b5e7e8f1c001001fc3881e7e532c147004ae8f1ddfccea7e349f800a0f3e54498911fe1bb79113e1d8ff381217c2038ccc8f3f86ebef5e9f80f3efc7d0f2461467010d20eec01f62adf0d362ac0b33e1d05b092fb737cddafbeed717cf66f7cf46dbeee6bbeed693efb331f7d99affb6b3fd56117fa36ec501cecd73e8b87b04b71b0dfe70bf2453ed813f982fc900ff642be2044b93f850f8669183890204c9e5fe54248055064f9c92170589a41f68ff690058a8cdc117b4ca649f66f0559b8e4cea225f7df3497dc3fdf00317e47a12b9fc715195042ba7b1fd2f59c88bc20620b1ba3c549dc1004631673ce2862929558e4d44bade452cabc33e79cfd146fc26e7e8f37895e629ed96c2263c4128944f91dec70e3f748970017bd64d9fc08703b38205c3b6601b71abafddde2bac3e48672b0bf894b95a3293483be7851c222a710458501a3c94a1587e2424f5fb428c5a238458c938f9dd8534b6e2507fba34a7a42765a47c56ae2f6e3e4ee584ddcfe2cf69c724a2ed2965eb318f184926901d7b3684e1113e504c6152b72484201f3b4a4858a17794c4c17a7a42b514a8692a1088f2b2e985b3caeb8337694a9f895098ea39f0ef4eb9cb4d277a7f4e7277168e3a4f1eba7dd38eb9c9cce5a3070c192b59f5900d1a58bf267cea2537dea2b6945e2b810a5e804f238e39a80c38d4e398c354b2a23b8563a499cf97311eaabf458d07e3acdfed146eafc6c88d9e2b01dec2a965ea8703caab8f1edeaa1b4326ef4da9b9f3db63f3d06a18c32c6490217d73f8773b266985e65e1845a5ab98b7e26ffb3644d2daba9e460248104f779405d12bcb8fe9fa7ddf9c0fe4143cc12e7c448532c2331bca1e599ca4a966fc541575de124109baf7c97b775e4ec8fd2d9abae75e473734e2febb24b69adb55aabdd6debb8ee76359e97dad9c97150e2165c55d79d7d7f326c4af2de3bef957ee3ed1ba99acd2abdc65a6bad9f6219b91142207b97ac93e59185e285b46c7ce7c4a1fc96f1a1e24728b799aea892b77fa8acbd3ff7db16c31c396a1fca845a8e1fb5c8233d9e9067fb22d752a673d07ad65e01eeeaacbdf627687fb3acb6d0344e0bfb4bd6721cd43e7e3ba083da673cf2a57958d336acadb2f4887cdeb88f316e5bdc7ad3b22eb86ecd077dc997c3c30d8150098ab2c7b2ff1298ff47e988c5ebd5fd095918a5f3e7c268964d6c44e9d712477ee12a703d3753121adc969b090934f2eac6a3bb096074bf5ef367bf7c2e48c8c2ec6b5f3f210babdf5f78c38fc760f6b5cf09cf8fd08699b367f9c4a29c6189c31b283e52bff3cf85d91f217d96cf9629a64195336c6463b13cc3ac82eb2ad3395823e5ab5be270befc6c9879e296fdfe3db25ba77b9c808b38f40d6ecea00277e6568a22a50237cbad1485284710624c54589971d594fd6fdcffe61a0763962944598a20f2a297f7e85e022ebe0dac786c451b84f9907c7c1eef028da6ec9fe32f09f32e6cf9526e610c702320dd6e565a690e8c085535166396f99dc12e91efb2664fa270da73ab819320ae73536274d39ac45872da3e39467bb2e4e42e192546bb240e96e498faa4ead02f0a45a36a0f146a0c85aa1b6823ec87aa29a3662490b31a255fde38f3fd6726a3dce50dcef7997dac724cbfb427d95fbb42716c9df97966356f9a8dfd23fba6294e54bc5479ba02854546c928f9aab1985097a62f4e60bc84791203156bf2e0871af31b3ab60d65ffd84a376e64a1fe313f3e8dd8041cae14ca472e3a4683feb449f2d02eeac5419f4f1ac7719aa4bb66ccc131da357568502e353da10135a35f5b6c134243c8169bc18d1f6e313aa6eb93ec1fa740a834ed56553d2b99a21900000002c314002020140c8844027150301e1637c13d14000e88963e7c54160cc320ca410a21630c2184106008316460406686b6011f8deb80cafd2f2b5ca4e439c16314d9fc011747c2b2ba0e11fca35ab938ad4cf3ee0b0c0742f380a1701c0c66f6cfe310fd813059532e59a12640bddfdf244164b82d5fafe8c107fc84ae051ba86f952a75b692a07914447b182dc892d00caa35b8d7737ec0fc179a8651c161314d6e87e9cfa586a7dc456e650ec400dcf85b9b95ff3d62cd708eac948d3ab660be82ea529de872b823bf41e382846828dcd014e4e38d8ce16c49ecf387c5b6bcaef2f144e35dacc8bb92c68066e6a47ff8324b6b978d35cbf01605cb335b0b7538b892b0dfde4c328155fecc5971eaa20728afaf92c2710816b4068fe4c1be834eb7b90d25bc2b838b9765273362d337a011e73ee3ee91fab4f781b7ca6e04393341798b430e26c2122d9c03efd554534d9afaf03cbeb69e7aa32c6a9956f294ec83f70ae9dd3c1b57932e5d811a4155c777d05710c7e9b714eb6b0543c2dbe7ff72f36728a7db3a527c4c2b568fd4a5a60c16a4ed5d7fb21c396a8048640fa623bc9ee28bfeb7537c188204582a290cc647e6b2b6bb858d46c3c5f82528402bd08ac9ad99d7928a66fb1719597ce4a81df8de204282040805af07a62edf2d1c78a8a5c061889d0f277599dcc29618d38cdbf15587f1a0f3cfc9824c210699f8b4b9cfffa482a474840a8159e16f9172a5c4cf5e41d488d681ef8a2e062a2a7d9952f088a019118684ae1dbe3a5dd596242dde499dfbfb79bd1eb194797c80ff5d18c65c416fc61725bcb232c7b1e5032ae1d66ec70b128c6caee4d3a828bbc231c5ae243be86b7dcd881dac0efed42fc854918f1d1f7ca8ab9e4fecbf871f5e0042917dad898a224ae55dde60c890c6d60b6e57940fbc78b12d0982976d05cdd6f1c00d166c21aecb549f855ee4b11c4c30ac78762397cb8bf78c6939a20d2f9bdf87e21e6a9b7bcf0e2e7d4f2f7b7b42ae0c28e485ed97c6ad7776c3a67ff2de9ddca809324c4731d89bce4fe53129820fd309b163b3b528d64eda38a29240b2cf6fe1b011ef94256c45ddc036a2c741b53ce6cfa16cebceebf8a3374c7f853d6edfae08f1219c50be1d6f46a9c1fd87506a3080c3b113492b0b932cb10aa580da02682a69a49c7898870732c9b3805558f81a21d9910fc1d7f9a3d10875bf4f4a0a923728572042c728fcfa2ee29cfd713fdd1aafd59afe5ffcd9d37a663aafeed4769ccdb3d5592aef263d4a9a5ba5ab9129433b4391b136c65844259ef6673d6757f18132aa6eb2ab0b7581d621d42505ef612892cfa08ea20c04ad1bba1c4e7bdf58ba8e6b1f929189e0eb7baad7e5d910e767048762bab637d77935810093c2cd6e51a40cb878408297e225789bb8f9b39ed5607b8929ac2b8652360c8ad9600bdf5eda2a7507f3806d73ad0893a5372290bac027cf009d9efdcabb138e4d2ac2ce9201867ef446cabfc81912feddbadceb56c524e81855531a7a9804b8b060ea68a5f437c1ec627ea38376f607372aaaac27f5cac02df9ce068c984cbcb96bac10e341be7888d5de483dd102bd1b7b3c51201334849d28c56aa2411eb9945bc2f9e090297a5044e0ed71420aa9d487bb212029251953bfad6c12f1851a7b8a144ef48316d8d939cd8cb27f629e3f068b871f140fbafa269012b169bed6ffdf11104c5bc45b728518d8b39945e8a148d7e541896ac0a7f966c1a869b165905ab1239701319b869866450ccc882112a7860bad65e3f3376fa0b16b42d3f3f4adbfab5097cf18760e46c5b2aeabfa1afea2d09b00c634703d5917c7c48f289acb059c21eafd65b4e16fb4505c86c7b6192096cb555d145d450e2cfaba1a07479f2696cd1fc7515ab7935e7eb4690b0706bc2ddff79886c8b972cf39b03c6dccdae29214982762fb4ee50edc6f62500716688e2e07ef86222c6c4053e2b00f49d6f537b30a5a6d8fbe92a5071d34037722b52f67727f5b5036ca2e98c4cb6c5fc4e2c805ddb6752c04286aba52e9651e8305d286cd504e8be4a91bdba09f91d7f8af432c9a951055aa890084bc753185ebaf3074921bda71644eeacb9bf53622f8711ebb13c172d6ad589214e040b4cd5fc4246c64102498d734c080456740b755029dfbddcf6d2a1d66a3ffa5000b38a0c5eb5621bcad127b0e0383e8d48262e6d1923e14db32ab665014bab2f420f4c3f3b4cc60316926adc1a411edb72b2a6fc48a0cc3934ee0a38d054206b47fc2bb1a507e985b25209a4d354de42d0d18e86b4ee73678eee2f7799b72d096c153cac872391c4d2bc509d50815652a858557e4d65a42b55edb65df0dad3c865841540787474dc77ce5bb80613841ac6f81b43377db125bda46cd7e3618e099b8ee6e2e7df015bfc048db755203735a747528d771a8c8664f241fa8a0168924a987a715a799c4e671665fe1671359d3a06c1005ef497985a7dd1ca5ad5845f972381010e40dd0f493654ef41624a27a689743d936a6415f657dd7954c8eeee7046f505a4a51f1ef2b5af20812926b92a01b0a5c3c03d2384a7cf9dd31dc180e967973148f0d72f1e4804a6110400ac91d0069a91ed6c0486b4042d82338525c75a0df841764da1db4e5b86110034a74d8951091d00205c8adac323a35f7c5bac92d45ee27287c82efa8ac3cf9d1d1c4442addf8885e365d491ed59c83e9bea3d522879beb1d271665262b9574341cf5f0a0f7629e7587dc7bd09078e39061e1ca86c82e0a7f45d8d04551d963586a3b6dc666fff5c01b1facbd6a43acefd8685263667556ee0e345b23fcb72aee6db482d20e62f5d14a72e274e0c069983e0a24cd885d28ca80c6348df799edeafaac31683ce7828d3bce38a983b5c1814e54efa6f90ef72c4fa4914fdec6e4be85cc0bbb707a80f706b65e4a7bdf61c9bb35cbd8b3df628a6bed40b3deed85b6e74f7db521a75ed12e8d66dddea2f2b525fc4d60bd03eb05c4bdeb78b450538f9122175ece8455a1a00da529a79b2cc4169a3464429ef9fd1209344603ce0d03b726fca8d9ad2e5e73b54a2af52f01a5eeacffe9fe440e85825d476cc12b4dee9140a01a9303bdd98d50eaf06d965d1810a8ef48f1d5aed585a1c076c2ccafa804c66ebc5c03d94462884a4dd4fc5862d61e5fa8f442ab68fa9297518365aca2c5712bd4010eb8d58a94263c6ce76b642a5c485458167be4a7c18a52d187837d3ddc386a067fc62bc4cf88f049df985e4f5164c8642f1c7fe9f49a2d77f635ae65a7ccd1ddadbc6b345df0dbad9787ed29435a929e210e93cd9f526cc121b86d2cc6a3dd35b648e441c8044d2c6a3a0f4c46a74269f62ffa69a185d0ea6f3649cdd0c32d0e360cbfca0375b4ff4995052fd58e796688687d1958c18f8cd604333a15b929d83e6d4374aed197d445f44880743da184ca3bea89e9debd6e51cf5a83c7608ac0cb48d0872cf158b90f0a6697078884a241a9e52a56e1683034b10941074d240dfb38adc73d4dc6c7d2b64f6953dc4ab879caa93e4c937d4adbbea53d71a326f9c034edbbb482db34d9f81414ed5126924182c3b5b07991295a81dbc1381c977901917602cc126d61840f983ef3d074c649042b639f984537c30d64deff0e37b1af00de497eb7d1457728d91ab796f64bc6127ea7b01f20ec5fb9abf0cb50c00256274d65d9eed4783072b18ee4ed6116d425bb1223114d959b3ac519b59c120452e305a23103a7e1ed0ba50c94460a442306a66b6e1f5d18388d1418d3d8deee97bd9a8cf261030faeeb16bc55aaa21c66d776b0c9910ece0ae435db96c78a002f8fa23c65f89cf3796c7f7dba617de357dbfac519a8984fe850e6d548952b3f2ecea83dfc6e3b119a02bcdf787d84e565c3cdc8d4c8c5e9c5c5195582ffd770b4b57f5deee21c70d8c0898c222bace671c98e4f04ad70b150a3083d87e4b82e77de58fa394365f31f25a2e51f999465eea1862e747ee224e92a55d986f4139712aab2b64dc48a02c130b248015a027dd30fbe62972580b0a6d8401b40667e68327a84a0e0e8c9f374ae83867e021bcc3255b927d4524cf31cd98f549ae34805ecc1a8c76c1cb32c9a7b770784979383ff9add91eca753da072fc2a7a989d20f46ad9a15d51271919c31cf4ee42072d7124d02b65e04e900323a8b1a092ff82ea46f44703565596543dc4024889ffaea20acf9c404c2dc8d1612dd276b38f37c9e23cefd95aad19b51f4af100f85883f3fe7339260ba34bd35c7f3014655e6d6178c54f0acb9c8ea2813eb71391d091b57dc5370e039609e69819aae4e9009587a180b418fc9b983997ef45ed824b9811e8ab2e29a3c2c513bc501db432584bc5f00292e2b5c05c601bce72cc0219b8cd8690e4d706181169d3d2f6d48bfddf1dc0fe8155cefff2bced8482a9fbd8245ef602ac638aa30cee4f85a8169adf1fce349500277b7eda5342d750feb8c9f644ad33afd42cb73df68b89bfb8928946d36c933057069553d8f9bac04a7fed716bfb899c51dedd760d1cf8836a206c013d8707e2ca7356c968248cbaa14daa56e97f22f8f46dfbd52fc613ae9ed1077b923ddb308b91049753a0f29c55356a049939a8308ef74636effaf250b5df14896632893684fae089e7ca9c3d98288ebeaa2da876a25c9d2778f5c1e8ee62a021f73263c117f459cd67120d13fbe5eae05c5ce2c4a55dd6fea30204c661d37dac55f2eab9dae39a85144dac1f295e8c8c4c5d94cb6985d23b650dec63b43cd5da22994cf0d4d865b8e332f138482ace00ed062ac2ae541753fc2dc19610259f57e2f945a9be47bcba3efb014e3143a8fc424177e4a8c493824c048e8e7ba7f539acd6d19206939caa18f369258644c145aef2433340f726810e948e53eae8f1830feea522dc522e1f31190aa97cb82449e24c34447919c8da6aea9ae36a2ed665d6d6129f071663821ee9d21ee699a9f98dab8c530c367ab0f5d8f2bf6e0d2132c9326008398465021f29b54dc3e9909ba179ed45cca1878d411b5f67e903f59fd96cdc3f19af0eed487ed21a4b0850c2f4b4c5a414b002077f1730e5516010f12124e719dfe66e08da3640c39241e88c92eb7a080a0875385f12270d55ffcc261449e6c81f8ae0e83cf1f731f2d2b0d4547adaaf2f00ca4578bc1e4605abcd49cb1fac4a7785762a6bf478f0ea1161afc3934d3161b5c52ee2fe342c5e3a2d0e2bec0705d6cc76d760bafa32902022dd20784f7f34d37f23ed0c4c65f8f2ce91b6f2cdfd20ce7bdac9fbfd0a97339db5cb954cb92d37da588c211d4e990b1039a6d8f190676c340a893e43ce7b5a3bb5ec7044d91e6a7beed263c50650a07b76490c67994ccc5ba221858e45544315b3d6f5be2583efaf22df6ff978aaebbc87e9643c5be8358a0b0de8231e807d7526110c24c9255d612228a8666c2effbd945d550891b0a8d40e0016eee80e3a8c03abff0ce34b5e49f4b3aece14c14e5cc1c14dea12b8bfc835835e0e6b3bab129341792710a5110b101e5682ba1b92f1217df8993bed21191ad03fd3d63e59fe2be51d02b53a95e43e82182b425e32c7529e3168cc7055e82c60dfea844634eff60e45f1b6d7127cdbaa989a47edc0a7f5f1e2c7eec440ae32bd55e5c202ded5554dd85d62236420e1818cddb296be330828350becd1c85a621eae2071609fab7df6f3b2645cfd596848362ef6ed054aa194f05e9c74d5be2cc81dd1f32b9194f97511523137940bfbb11d0504da29f4fad5465e28e3913147eac0aecb9413c81a040406b1f8ad5ef2a2d50a8d9a164a2cb3241f35f7b82599fd1f995cf39d67fe30114a68d155547ab68bf8b6164e8c10e19830065c163a85527a6958657206116cef344b3ecd0942cd0f33f18bbbe3f0dab92097855a0edeb2a7d107f98f582b9c0aa8a1275cdf706cece0ad094cf79a13c71aaee10f406c7a62ae1fff716c2651def6688a53f2ca20faf6ea0476fc750a534f58a1a662905df7bd5c9b333544581b4a284127c2ad4b20ac23f209d8a4449e8f955373c6c718f63d6f398e097242263a1fa14c7f542468b16b771fcae81a62ea103cdc23337729ecf770778cd524d7a1ad6e3fa3edb8aaae77388a87a0c43321a646ad239d89dcd1c613f104d12591f1669e07b61868daef17a93a20a2dad379890b77d8c00ca6225bee289f31b8824386b4c9c18ec8276fb067368cace84d605c8b5f2be5318c8c975bce771d39525178360446ea7497d6a3b0a0ca4ef8bac50e876cc2e011a546e9854f1496d7cf8fdc7370947ff81b1783f3c767752c3f45f09bd83d1d6216cf6ec138ba7b6e1ed47608a4cb5a99f26fdef009544781d8e937c2c0ec7b514f84bc8e95f5b9b76976e936ff19d1d1533545f336d0bd6fc0b613a897366baad6841c3961da216447812b736b0e9d7fa4f12cdb4abff3e4b5b41e0f37b2b0f416f6870fa1fad8818b3d0e82bf24dbe37b3e460a69a4c1121feb5f656e8005419f61b683042adad4131230253803c7182b442d7b5caef72c4b2e3213de4b7da704f50165ff050dbc71680c5e11b7eab82378d745cd24dd5f2279fdbe68e2ad0df3cdf3545b81f703f785666f9b69465c953b9f6da76c53bfbfd1db9f93b07c2d16eac37f11b4cc0385efc41d6ffec8528f991d35c4af2feb84b7f3abad14ba9c425958890ce5144ff07454dcc771d8683df02f468957b41ffa8b47a67ada5a72843fd83e275879ae58593b869923de235274a30c23959faf07343bb096b722d71b9a7c7c9b5a4f4924b8e73d5f1089bd18c6f7876e84f9e2b8f4d5968b713f728e8d7109ce74e52814cfb0fa73fbe2c92c57f153ba9310727710bfa9b8aabec793f4431746bf4b3c1de9048905b837cacd37a53b119704dcf840bd864953a0b72c850075694a8c56e211212223da7b2f34e0b78b2621f65513accafa5cc425f12767478a06896d6471648d3dce6c496489aac784cb6441aedaa398b47368a898b15c3f703e631b8e6370a9aeecb4890240f92c3e708026f0170709e9f77c8dfd2ebd2e9eefa6272b42046966dea5c9f3959888ad832e018b31ed0cca6c57fafbcfd206348a72fe35ad39a595cabd45b7b8cf10b1e0f7c16d200ed042b8bd915377cfabd641a89b46822846bf77482fef009736615913a7955741c61cce24c8d297d4c1af13eb01a18799120391e3162f0a6344aea9e54cef15050f8bb83b3d4234c0285018f125579905895abdfd87984fb541b5d21b5aa96c642578e599ae4450485aa3ec39513b5b8ce730bc3abb5487d4ba4eeed88736d69c5a2bed59368da7a825ae579cc4711aa26113939c5905d2363258503c6b5166ea326742f119b6f58a1855697009bfb8c6d48ef844f7096898d0bbf9fddc46b3a09aa9d4747437a1fed9f8d147ed0b209c6981974686e173491c57b07a884d57104258ee06806a7a27068286cef87701b6e7367039c45d021fe8e0fdfa9e5b594c6654be05d7c96e93876c383a3162b6a1846fe7e184c85cf1197e77b930b21cf93b796a2dd53c24c21384023271b0d4f5c9a2a1ba8280a15df9f40c9b653d189e3e9e8bfd1424cb6fa29013871f48064eebdfa1531b5229e422f11ecee3c5c60ab0bb226236a6151b32e6f4ab9918fa16b3de19dffd7d7cb6b85448248901dc44c94526c4ba879d99c9763b68ef407afc615c61253b110b2f0bb0e50d7bd02926765246a8ea282026f2e4d0bdf2f2456362cf0b859a20ecae53a17a905a239b26cb505440af683ace6b6f138e8ce447fde12dc702ac0e95c476c9313be4ded43e9e72a71e48b0224e5fd914893a0bca02c040d53bb3c5b504c4001716261a30e6f200a2eccea93eff9f4c245fcaf7f840a767ffbcd5904e18ec0b2c8ef03843f492bcd2c68ee83742d4fa8d9129617422454a294fec3ba38730fe4423a94c1330d0cdc1419294c0866561b294bcc5870ab1afcca990d26a9f1e9a1da36ec556dec945782c92d7c708303175b858b44db2b530a107456ea60040d905e4d94511a220c5e46b6749f18d797b3d0c64511e618fe1525a0510fd56e7cd57e3f7c8b26a6dda68941ef03e0bdbcad0d60bb4c80fc24ffc54e892401665fe19ecd9128d1d6af3aee77a52af51ba4cbc3eb03c25d1fc73ae20478c6a7760100da002bb055de2057cf0538ff5e2c19999c207296ac88c82648fa405515ea3a57f32761f84de7e59e9031d81996c3d55b8ad8a0b841b68da03f9bf7421d359762eab36db4e7dc4d9e77c12d81a91a2d1b8095385d0ad784001a04f3e958115089a95c6bb33b5ac3a0ce039634be223ac473392772a44cad698d2199fa53b5a4962529904342acc98fc0eef25e24463874f17a6e4573375e67a99c921f12ebe296920a608c2837691ae4d1876febcf0eaa740bfac5fd2d789a97d6a9c68a402a36dc17fb30a4b05a22464d08a25b84bc8e4ac9024827e965be8dc178f0d8b7b0fa59921f8e1660fda1f9efebf29d81c889e2091468396ee909046f78c45d7c1c24bfe6acdfe47c7a702101de8a5ed3fa96c0514ce16cfb4f4924c3902deaca64c026a9864e7fa66f140b960299156ce4619b837447be72a68c19f7d6f8dd29958cc3c8366c5c343b6ff38be69b841f77a4f9b5901e90c56743a2cccbcb39a8d920eca1225e846e613bdcadf99cfba65f0fb87adad9515de8d96c483f2c5ecb143fb12d179461ebee56683070b72c16feea4e3a6130e040f145dcd6899a8e61be7ace84bf405e03a5549f3724dccd089e6892962e89d326976231cd34ef7e33c83f46a7453f4c2cba65b2859662e62201a2c52c0cf028af03985ec5e15f17dd505c04dd143512c83d88e0d6d21cae007c2057bcbb06e61836da1a7d28ae2f67433b7809ae0c2dc73eaa9b38dee20382bdb48f821d36c2e8950b019ef73581e805c5405315585ac32ab601fdc20bcea04136bf71b1d94bf61c42a0e14fc00c38fddeadaa8d65902a28be57c50fa99d62dcd814c524498017d2919d52ee4e82ae0dcdd054efb37a86409ee5d7d296f65ed51ae1faa6c252da7c6171f44ddcc65647b6e0244e1a3ee0a3cbce9e0e1ef9e8d06f93fe12b5a730f0c0c168eb9461e173465c082e314e3210beac0c188914dd506cc0eae22800c5e68ab0a8bd38bfe803b291e4131f4e05ff0988e01390017a77e7354aa3a0ab61c0369be56c8efb86e64997b5048705e69bbb92513694b8484d067bf621039dfd350ee35209e475d4cd869f33ba65c014a796b6ae4890b4be2e7208f3a1232e5007cbcdad25669f5e9d2d03086a09e533400402e44912c9376a28992d68abea97186299160418e6dd714a3843e3881770e9c81c5536ccafd4a333acfdbbfb54615bed7d1f8044e26dfa25c50b5712223b27410182de62d3c4075e0aa0737f642b29127de086a0c25bf3294877a21c4d0f45686ee4d9481f2af7b36ce34590c9e1e6274a580f0bbc2f4d67c7e57db3286fe6edc1bd130f16a0f199a466f0efd779a60fa82cd2fb4cf5b6cf981a2a10e016ec03d67ca758c81f87f4e4683c4377e6bbd005b50512c3d36be6e3edae099228affe2fd205ab2c3ace097125374d9b26eec49ad68e948720e2399c48331adc0feae28bfd4020b4ec78db14126d248caec2ba9dc93c033e56bd95a2d632468b1d92a76ebcab8b1f8a92a9e375f9f7e43d40979ad0757478ac1d0d6def5a91cc08de37db330cf24e725e4e189b03e9fff9007297aa975b8d1389ef8ee0ab2daf2d524c3a104fe9bfcca2f88776b8b9e4aa59a28bb0c1c79b0bc837bb2dc4b66121facddcbc502e93b392c603710bb64c274179c5607765e20f9a27f3ff44d982351ae9f1944c1785b5d44ee46e917c55683f1ef781ed786139b2f2edba6ea9843c4d033d12de250a7abee201f8cf3dd364b8c9541a5d2494d8a1bbc6a591498b02b43bece59465d0873e8a64ed8a24d0448905559c0d3cbf31d2b292e8179f054ff5e175ca54358876b7abb125f4997a59cea9a009ce38cea75420f2aa37ef9b4fc1d3ca9492e3f551e744d73b874f6327e6ce0e3af5aed43f2a0a65cdb0856ed15d99160f9a8723f7dc4f9335578bbde0311bc48782d4d26fd6b692d1dd01c2490d193645f3516ac92ad6025a0e83361eb70c9ab368aebae20abadc05de21141b8fbae547953f2ecef6186401adba0766708302a08e7c4d24ef021b65f38583d2fc94d7573956f4d9e6486c8cfa68b9903d062bbde16c2feb5cddd39184855a0bca5bd274664d7e0b1b227a2ee9dee68e5246eb1066494cb4250054f59f81356e8ede2f5ca8bebdf1cce52710c5abe86c950c7f1a6e286fcef92b78617ea75f0631735274d7eb83ede365002b0b92f2de1a055e1ee7fe750b368eaa3fafae05355d525e1ebbca35b22e4a90a8f41e155d5a7d7f45c98b9ef5282b69b9797891445377c2d35f9556d2c2e2784586b8ec26e1be7085397690f856040facac1b6c28ebe75879fe8a1b539c6061ae413f30f5ae4538dbf56f6baeb4bd99c17b5810aed5c8ff97bdadae1a3917e14099475866634d82a360f6202efd24a9565b14b09704f492b318f9cdfea8bface30ae10e7c11fa8b49c71c87b9bc8e57433688974b70cdc9482c5dcc2609384995fd62102cffa4497f37f6b0b10f6f64fc86da61f5c3240fbbdae361d29b99eefa26647cee1906e8be5db03788de527bdafb5d6e20f6f4d3a0849c2319b55fcac00fe87dc481a9d4d77e9049f143351e5851a3d2650285f704d70319b223cb6ae5b20bc3342aeea4be93996ec5f9e069d36eb57fd4857bfb586a35763059a47da181890da13c82b66d68dcfe7ff4c9e3229bd63bfa509d028eacf99fb94faae9b1295bd101c111254b3ff39ba81c4c032a60e95c59bcaa23e929f5bcac4352f618cf3efe9dc96f70406cff4298cc862dfc54acd98197d4c0ded317fcd694f184957b43b48ca76889cceeafbf328a4c49ec78c2a414d8f6bd8fad63beafa951f539401e658b3bb8f0e74e9a1eecf29ec4c47548b4d9dfc4b56aa3050b9fa12112407f018e211479087f0c4d3632b1954218d5627cccc312be8af286dc3dbea501e8f5f9edf13ef87189485b7e09b4af2f2e05f947c1e25a4937dc22289a37aa19a04ff10ef398af886b2f05c3cd4b55027b278d925a3fad635bab34caa722d9de7500502cb3affca5fd7d1341a9a325f0ffd24ad42df161a8dbc1ce029d64ddfe0963d805b210371170abbcd01f1e5acce13ad3616a6ff6a7de3f5b33a1b8f100d3c9082cfa3c89c9b2160d55c93919b2967a329c56f3b378559390e0607b71ef4a4ccb82d1b05bc197bd53c8c55dc19823cf034c6e497685620388fa402fb9209579721fc8becc8d82ee3e8f911594b2ce26e835bea02228dd85179bccc59bb6f62075ecc98899eea35a90abc5da9baf904904539b3d7c76243ce3ac5ba6199fd34aa677b81983d8bf75ad443b20da408826e4889bdf8ab03e066ffc56a4a806a3b0d2bf33e706553455699f43b3b83c67b53ed8af4f76d4318b661705cce297b877db475eabba93ebf342978304e3767e878b0ec6784df83d326861fd7ee09f4fef2ae5dd521b00674e02cb5b209e5cec8b0ff9810a02f39553d6559550258a07ac75ab04e78356714e6a659ead2b68ff33b69e6725ec44518f420e7e16e615833518420290f7e346f7e76c5239d211fe70681d7d81426f9ba84e14ae5f0d75c5ef79af02a9135f4504d5f0ce569688b588431ee84f586f1866fa06da0008f0b74f089d4c7d49d158ffea2b2c412faf671ce9ba3165226087fe34bbe27b4c413ba304a9477ccaa3a8113587591f98a26cfb468262e362358e515e484ab336a444ef60ac42b1a98907c1ceb56c8a1f12abdd06723925ca5daa5229925110f5d17d58898b6a3f1b038e92b748bc4e6b6cb6883dd4429f29ab6452821814b90fc7917566ac2faad273e2fcc853f457429f57a23bab7c8c539e0518ada96192a5ea043978851c63d3e9a87585dcb5e4a4239d2798b7f286470905448338dd1903cd896a1559013a2dc5ff8b61ad1a0b4308569b05b48f99c731c1698372b4ea4086e70ba07a5f44e30db410fdfcf4698e110066a93c2ce9e9d2075fdd1fab25dfb019188244b0a0641a3e8d66aad2757cd92a93c50d0f9ace4c484c39a74d20e74f617d02440b1c6f10654aeb6a83b2ce1e6bcb88380c3c2f6a81b7761d07a5ad6931242f054173a10a67ded6953d24b7b4bcb12e933803aab6628ee27532730a49cccd017ce6ed0ed001e309c1941071c91ca2ce2f35da0944ab7f027a5ac14384b3aae43a0054e9c32057a3e922c5ffb0de6e856fd032fe2339b735c3b863172816cfa3e86f08de5057d49b4caf155bb6efcfd50a26bb4e56498a98d3bbbc8f7bbd366a8eaf49dbf089525efdc616cf7fa708569aa4a9b355760c5198fc7fadeeaeba1c30dc44bacea2aeba71ea216d97c8dec995ad86c91ee814a85867bd42b6b90b250b290b15164bd294c707f99f0b2930650ae8daa5dad3a73de14785f4f4149b2259c0631b25a11f683b238f9ff827c410f5f1883ef3c55fea8f0ae49d9e4cf1ac47a310f7e98d322570e2851779633ca38f338dc48b00e1d373edad5446019b716c5758c094d64c414e519888f6225707943e574687f64959fec49d50dab95d365692ddd6c76c85961d042cecd2bb658369774ea735481e8f26d598c867f8f93226321b327f7fcbd23e6909c6dba8ee079adc03a5abf9abb2fa4e302795403543e61a18c92363d53eb47de65454a0e9c90b84e1ce40feee220c3417276381f963429266f1da1d211723b30b17fa087d37af35b13814e08e645ca5e33317e445dc7a8f75fadc33b8f09d30676ec0bc5fa1e162b71480afc62d34b24f1e6f69578a233b233e63524dd0eb723eb85ca9f20ff6162f20703f5602caedf532668c2c53afab79a73ab93da7215ed144b84738d19b27e57beb642f97477a944e1e03230704e0f8eb978ab7c1052af265aedca95d153da565c904a20bc2a9b41ac668f5ce750b33e072e7c4b30ad753a352f790245ead043ba3899ebfb627054fbb3c4e785d24418ab6a37541577a4462506276683b35878d908d93e36b54298140fb5c3c3d383fa804cea811145ca9d3284b8f038a5ce01ca7888ff0c20fc344f41e46d511333871c37cec7475e37f01fa6eb30413ad719c04df1bb8cc7343c53087b027c734962de7f2ed6fac94802c77a9284c517a59ced1301e3d94feb0e00d8addbd7399f94eae49467aecdc6d2b9c489f9e2be174ec2a9aeef1aa46541c2e5ca985fe9d53fb5ccddaf61d8942e113368dbb30344bc9060cb53244e8f2f1854f0b7e55accce6c0871884aac85ca20a984b0c38e1124cf448eb5a511936c04475b6bb464624863e2a72368c268f7c01d5b1d2e0e01a115fac79f73877ca1439548448afe39a7a4e312c9f5b8005de4f8373df0771d4109856cfc4cf6e7587ae6cf8447adf594a21cd07706e8cb6f3be73606bebe041ed946a7b8c1425255357bd9042afc01259e31f1594c225d4f90d5d0c2d65dde7d88b2499653fc5aacda382217fd80d2baf1a18c50ba4a8738514dadbd452313528e08095c2401ccd33d51e81f5bb3930fd66a6c283fe8216d6669e476fd52b6a3cd205b6d67695055eb9d716d828dfddb27514dbe2bedd0fecd21f551f4411e20debdb74a577570c522161332ff80f115d1afaeef36ca9ed6bd6b5c161d7aaa075970e80b29848557056d3fd186d2ce37c97223da069077a14756d2989e7151cc4143d2b9117d0fcf25c1e1400810a4a54377505887d521e15aa5884c4ea38681c6217ef6c3ac091f2731e1a027c623806681ec50a1e35aad4638050194f33a999d138d79d4613a427e5b013a1e1093ab43c5671ffc0f67931e95f9b9147357ec29e266487b5e42571804910c50c7c41fd5c24c5069931f81a4cf9a1d732a3c601cfc6aa9698a56be036f787e4869fcda1ae25f04c166d2fd141da998d37723c05abe7f1b315bdda403b068932dc070823f7b272158eed6ba89c410ee22c243dd60d9399908e75fd0a7b483f05ea6e12998a513d3e57b7280056f1a98a92985daa1f77b760ec14b067bf910ad9667535cc0c57b6be402d9b55d905ecdb22eb7b0cf2a640e237b5af396fcd3d9c1b21c7e744d3d05bdf002089a0f6b0f7157731a1198e999cf092e7afd568ba1b05243a09c5518d61a8e2373f4853b644e8758a29abfe06595b06e5872f0450fccdcd052d9a1559d187c8440b5df06234744a5d3a4715943c74a733e88d99340ab9a774a7e7f157124f5f13ed8bdc9dd6de6ef98484876057ac221dd15b23ffb8338f1bf7be4f5a835405245c109863912a67b54c7d9f7a7e5183abcd0f2fc1466866aee8f911838a4fdc41bb3c5df16bdc44a587e8eef2be53feb77a58236010096b4b0e7b9b952d822824be471ba605ec4f914bc536ad9a9c8238839491ebe5bf42f9313f71a81ade08293f127573dbaf58e184cddfa9a4adc66c83e4c94335740b40f13352690a6ea43d9fd196c79fc28d4ec05bb25caf319d0db611825309e09ca2f8246fb1275a26fe8d8ce77099378b72616394e5333551ad39649d044785a551dcb851b3f5a23dc4962af506481c1d7b8b0012bbb82c7a47f853a7a49f34d36a14972bb94396360fffe29bf39fbe0e01f0386662fe3612133c48a2ca0aba55060b43825d53377ff0bd91097629792472db9f0fdcac1e515e9a045721531d5783abcf99ce0a585b01a010752e89896a6002f5e56c4525b7c8039e55c053f6ab257b2db89b254726b87646f539e2de632e11c7180773f8a89963a55de06f7792d3a75bbfcef8e52e91f1e5a14616e6db16e65ce0a3ab0e8dcbcf3a2dfd2f9c46c582b9823f8e53ca6e79e3ecd8bbd6fa141982d9dba3d046e12197b153d75c8d9e8f1f09d970e43fa57cc666210fd0ddd5e2cf90d2e5c07c67490f36a56c55126271b1eb8e92bff348fcd04d942c7de68b55010be4cec13ba80369105b3c5a963914f62234a8d1eacdbb8330aee36e9cc665bc949a5a69d39cec5047cdea6c5b23c79743e7dcb3f9808b4241ea14f7a001448c51c5e51f9e5abc928e35a58836bcf79787089881dfcab5a6031758efd68f76ddb2a1330449dc565e9c42ecfe22332d5c0ca1cbd0317b0971bbcc6c2b93999634b5fe97bdd1b893d3b38cd73242c462d364e23c1fa488a7b1249525ae60e870ea9e703fbbc0e001eeb5b5b24dbf3588c58743eb45a9dc1aada15dffe18a99bcd62a79901319f94e7ead2082597b27965167d7fbc73e4832c4cd920cb882abadfbc016e02d9c014092e109e4fcfbcd850a10a9d938691795fcd1b82a20df4558c0abd47bd3b63376fad2c0951b8366d05858fd0c49e85642579b0ec27591c384e3f0892e16748ddeba3eb97d40932dac22b5515978e92081f6ddd4833d20a82264bd147f415c1c2d39f8ca00d5876ea0b439f48861104a0fe8826f4b26f4069350c61ad35a99a54a74c262c2931938e8ee980cf0375836a32e862103564424755ae7ce9c06d25b36a428235440a707ce355d4c005e3772cda02097df8c6c22c4f7b0697d14674ee104714cf068c87982fd7fd8e335f755d202a42568b5d3924ead02b9fabe8b53f64d62490731fb81349394e37a26eff433d74169731b97eebfc3f3e7703d6d67de385872540aaf5bc58529ae8ac625fe9fc7e70bc3f14d149a5add23b2685a3f22503525c6e3e6f5650d40832600cb1a094e074a304ac62d9d33eb0fd24106bf7e02005c27422210d51cf2e5445df9e2d62b06af91580fe7938d02783ef6f4b72799406cea679e640a8f96b6c816519b890a18aa6eee8a404fa62a083d337b93fb011c4053fce627b895212a7b5d37bfce2104302206e87b3b0abdf47e4a9dce478cc8192077f76c84808425b8bf21b48094962c49df84b39d3fd1df0bc7d54811ccc6c0229bcb366daf840f9b4a8dd99f591bf494665024b3d8e78935db2ce8b0124e42c29e4ba75247e67128ef6251f25702d462970c1ab89dc3866861ef67d9fdcf274754cf8192efd7954e8cc54a48c268bdc5c9223c15ecfe39b5a4838ae57fa585c03bc8022a87c0d9b4ff1bfefc98445c66c0c9e87c7b72622bd953abd283214e812f6a898aed0ec677d8ec841279b9201e6b070ce2ee2da4bc525ac2d605bde8e2f9fa1bcfd78a3b449a458babab5059e341a16627ad30a88019846c7c13bfb228542ba01329571432ebb3af0d51d59196cc1c2e58a3b6084cad51405b6528ded5b5f922ef306d9173c1c7d535984f85487b3396d84f2e5014ccffb131267281e9a078a23ad80abda35a227a9486cd049991c67972470c2cd13ac6156384e8a0591bbb0841e2b8c17ceaef50501516cdbdb332b683a35ac9b765c603b8a3aea105a77c4d9fe9b186f9664c9aa3f90b3665d0d6567c68fc0e2b328f5b2c2eecd644936a469778e0a6408b1429142070bc6b2aa9cab41a873884b854a2c0f07c532de1a9137dfe361dfd95fe72ac615edfb06b03d9fdcaad117a30a9f277863c2745d2d6c2755cc8c3f59069fb0ed6abc5a5171f6fb7b154284d0f35e805209e709277cf1d08dce3232fa00f93a18343508c18b42a914e6b4e9446fdcb11639b5955f44548d463f4af6692dc4c1e3f1319df90c3690ca56f921d95c0058bb392c65b18bade3865f044d99fe76b93e438bb46327ebb73962745ac168ee0598225bfbf31f9b844ee114deba85c2693b64f741f2f4ab4e7b9a231a7f036df1684fa99b11854ab65a7f8b1d27c68ab3ead757dd7c7a0beec22ab6c525d6507e95a5b4a70c38b96acf5c47d6674c173bd65598b5c488a75354d4f239e02d677ad5d6e03005a0d8ad2ada19e71ad88a29d96c0b1a097c29bdd8c859cb3968a77034df40b6266691ac758e097e3425088d3eee0971218a1583837fa283a2b13e2630cf7a2f38326f478ffb5d4fcb4e2c5994101ffc678c88dd68e8c9cc10d77a94de2d09b74e75832cff256dc802fb75a28e532e95dea01b842069a145c603c48ccaa1508159f21a89e3387c88a625dde0a355c6411d515c57caa3bf652588a7f484715aedb0a812028e1d00590e3a690c3d4c13557d7e27be0490cf0afb90a214a4956e1b3ecc317c51e3a043fb85de41c821a53b3bed4eb6de2a61315bdd46ffa522cb674958083b8a4194dccc07720efceec93c73f87da2b22e5ac0861bb618065ce1abdcbff9ad8a8a49038965888cb5c420d330e81987ca8d3e7374c165c456d772fba10132849af596f00741e47455403695a37b984b943d36575dad22fa9cdd4a03808776604b1ae64dbb538ebbcc1e3ab07223fb2c87597d1a66ebc52f9ab5444ceb7e1720df60e04f2ae6543bb64ec6b13282abdc003c845735facabd4394bb5c9745c4691ed2500b30ff6b64dd07b1e7e9a4b80d0a52d1789e8332014fdef6866eed806218d0caec8a9ae6eca0ac134ad8b6f53a23883d722619c057c20d69e05020cac447e2ff32a7849a9811ca372a30ce566ef795ac7c13520590df9c63412d5fb3471ca3defe18344e99f6eebd16777e92b7e7403076625768be9851d5a4d858181c0a8dff246646fe034ae156044f61c215d91896f34fa0a7cdc82aa53bc43a540e8997ac72ad00055dd4c5f1783f8b33cfea4740e3ec4512b00c5cc4c3527aa89f92b358c797f11c7d294b21d94b1f7060e5fc318ee15e12eea1492c82cc541cdd469a4709d76442b85458ce0f89e92a0c9c422061c10ec6297aca9165f99e6560865503cb332b740fcc346cb0ed0d426ed393f089c2aa50f1f3c59a0f543889a1d7b966759c25b3b75084bd4584239096eb551e66d4c207e664ae946c63152e90a5d473f5ac7529842f3867c8f96a8dcbc6a6a4088470beb090a572230d765cebfde684d9ab5cde541a1f1695bd450f02d5928f12b9552987c282f83c12d2c686d1aa5266fd0e1324f97c2c43566f50ce0ca8c3178d5d8ec1f2fb93c0bc811aba529f28277d5440195749e24097c487bbd29598dd548de8eaeb9aae3cf5ae134cfc053227a8482dd458dde3d3aeb24e395ddfdbf25949a4f21128769b747f457a9bdc2a92fcd859e6130f515d0bcf7d568638651ed8eb9f4f2e550c67c05f0dab80bf963e48e9eb2259481031568ccf4f5a86c32f31eda920138bbce589bcd6fb9591ec1eaaa13773f1c5aa72a3ca462a953e453d3fa975ec926aa9e69dafa20481caf58e076142ce9bbdda21795d4c6af5b54c64e8be275628995d0e301a738a42eaf759da06dbf851e3917baf202bcb7a1cece07c26f4e095094330e74d722c988c0392ba0e974e8bad17146eca46a5c3c7ef374073d20abf434f1fd175179b3d215d285fc1b409f4e5b5546b533a96a43abc73232ab9ae4c768d0a94e350d8ad3bc049b74911cec4cfaf426d8f4a6b9593d6b3e1876bc6544acc2aae2ab486b04ac4be28e2ec90ad56abc14b32601b425d1235551c5abc89322cf105857891da5042b32e8ed1a84006515ad223f4552dc9d5a68f2ef58c8865982b785a0a391694502bad0180bcff3f5ed4e54912211a8a4eeabad881efd6d271622720452d4fdba4c4c47ecf4fc746a892745c0b07cdc515e4709ba2d173226a65124d2dc8f8d5c6d93c418468be4fb60e1d8a64cec678a4b56de075688ca042ee70cc4ac5187cd72e91aae0548f22d6a0af4fbc5a58ca001c9bb546ffc271d2a66cb3e80f328f04d77e47c9ad09550b28025132705751b4a1781358fd24c28588b38d9630ebd0e6569d76d699da2600bf81e4f25cf5e8a1d1b865b3abcbd724a859bccce97ec170241db9f128b97fdc7359f3cdebdebe2750b5b67d827d263016970aae77133b3505616d3af60ea72a97d04413f2536d231612eb7837c97aa3a62319e04ee8eb6d938dd347a283fc0f4341626a63c71c2d03ca6b05022d17ba16a7acf298365f07ba6d071da7f9ea1b267a7026026c84e553bb0c271fb3dfebbe13877e789ba81dd7211724c12f665ab005e97876b54162a23a2d3dee0d2f6fca6030a73da1aefae2e1da3a4d057ada5ec7c82eb322b061e240ada2aa42b92f167cb5bfb550af0b02aaeb832023bd921a52b8649922ac94c664d7f9483b813de1a4fda0fc0bf94d257d778bb10879eb38eba2d217ca42c4450c5b298b8fc7fc07b9a1f7fb157a5add4ab12da56757ee9242e67c404e29dce7326c7d59bda7a780961039fcd3e6bafdb44faffb2bca79d808d84c01a8ddd2992405c470ae98c2cd1cda0694d0e66eb8b8a2d05f08658f1f31a1822db29f861890620cd7671aeb115253a30ba6ca9fbb549b1ab43105a55d59c4aaf3a4e2c4e2d8b93c9ca2b79ce84060092eec4d461a9bb5d2eee4c87916817b050cb1af9c593560a55e3e899217cc3eee82cc4bf6a2f7e982a659adcca130c1a0fc303c57799a869168d069f819f4ef5bcad42a12068d0714411d191c6397deac0536d4ec7bf86529b36877bb41aea33d3e650fb38da7010bac97c6d794498141f4b587e02718497890a7b788b24b4f3d86a3989bfb419c85f5c8dbaac9d5c98975e33c4b8647ca89d47b093d083202af02279dbf713c2d82285e4c0edbfab24a4d145deb5015fbc7134ad0cf5a08b0687a5b434c9740d1936e4c00143071b3464e070c3060d1c6ad0b081430d1b3470b84143860e1b6a60c83ab4b9118a981231288f32fd58cdda9345bff7932365b44269bcf3d7407a7def657cd0b456772d70ec537a1010a964817f7f5e44b56aa1dbbfa0cde82e1731d73afebe2949a76693bd2645e377a5e841b04c83d448fe650157c048a1df6beee2628383d8c08b2e81bd734ab31551eb30058d581912ad09a4332ae4d14d4211fbe73b1d2699418f72818b123a00cd542f4e9852bcb831e00aa3051b27cbb4526b12beead53b793715cc781951b46d29d6d2cc1954582cb33b45bf735e2969dec600d2eb998eeaff590e7d32faf8d3c2d9a67358a48a70112b205ad62ca3716664c5fe21c6238a510ca651e0a915020667464cabd8093c54628843287e85cf68577a2e86e92f8d6d20f367ac2774ba047f9fe6efc0821e7f830d8ace153e36c627e9fcf3dd92785ce87466f094c80f169d7803673d51f7d2151ab2e3a8d398d6a622b97ae69aeb05ce48a7ec22b5916fc5db7149211df96e58d5c6f5f10d5a4c0faa1154004953814bc0162f9884215529bb838aba1b44546d96713f2495ddd222da26bda1ad896c970f9462c5080d57d46847fbd17281cf0f36fb1d251a05d0de33b4732424362510f1a4342ce6ff9c68dd314a65d44ac078ab87d10ad5607ff215c156eac01ab145b3f8063457b8841f91083cdcd46f2c023bd34540e859be1534b33d462f89d6b4315e86c224e290887630e9889d1dff65bf73d2cd6012edec237fdda5dd9a5fffbb750fc238973cb2c1edf262898e4017902fe0c2090c8cf9bb49ee22641e99433f351d1421d79fdd1b098fe295f17a5f8fb6e8f4aacd926935eb587f7c83c3595c71c94014086248128046fd7116e6d7dafd27e00336ad5706bcfa2533c5ac97f0b9123d08fd4e43910de6ca089834c6fcda72597b89054b0e5cb347abf6290e5f5860a19ea0a9c1a92168d18265cce1e997e7e13b9e00994f1bb975e468fbe702af435c4d3710354354abb46347362481b8c6b7b5ce292753bd5a359a5653df42602688b3ec99e4f5e72f24f1a0503dfcf5976947665989e812908cb6efc495feb1efaf19736ac9add1a2e19ddf8f36e9f8a0e5f7a73747fe878f29722c5f86094b8852050d2f1ba7ad25dcc9f74a958d7f89c6c6f88fbcb669830013dfcdfd895abe2f4ba9b5880a062cfbd6a94276eb2be64d81afb86e7136be0301aecc52502d57c97d68a1c7dbd76320ec41c80d3b241b77b59c417f190b31b6b72ce54b117f1828b825564252573f39a3f28c54b62e41ae1e652980f40a6af99f0531f6cbdab57c7e6bbf96fbeeeca596beb14d8f15731d84e257422458be2c2434c06e56fcb52e8b1e19804bb72119570afc29deac2ee074a4de71a37e1be7272e8243ab141e5e820249a5652319d00aa90ac99bd1ce15157589027cec452182650419ce5c2b99e01f6b604fcc09458a6f2a986c8d32ad69b3c45833e275826e5d389d2c250769a2bfa9cc1e4a8cad40826a5aa59020c6a9110d862eb78c670abf16eda5c971bda714a81f922b29fa8a24cb73a0be27fb12cc5442f8f516c9d3bcc91b73568f2e87ed7e5506b18c1800e6fe58eae1de022e564d9cbe25d3adfa6755a683a9219f20865014c35bae6bed2451a990cb7de2f2816ebc7477f6d2785677d552dc922aff84591631d36cf120ca245cc1ff11d81ed6d57d8ac487c78fba5096663c80ba7f7d5a3d8c6235e839b94e76c3e6062aa0d73a27bfd5df44e7f7d08d4ab587c193e74e720347af5a571fd10f024d364a48115413c25206283e5ef377855a20cf8ffa01aa0882a01853e019c5f663a3c5029dded948848398db60acf9f02fca6696788609ad96df0cee43e5c96f0a52f2b8314353240a7b09d400602b04d3f06e868155f357ee0f058b43e732632d20053d418ca2084b8433e2704e9201162be0f3517e2365e3084ca47b631ce0ef3e8e48f1da8370875c1355a3a20a798772ac908cda1a3ea5c2fa6e92ee67c9bbb616e1801ba5e9527ee396fd9fca12613f08679d42a2562e20d2843173b34d2b318e440639f6c3edfa052d01d148428430ea7fab8ca5218ae94995505364a0a00bbae083234e7954f5a64c634e4904bccbd6e449797659bdb49ffb184d076357252fff6154158deaf4ebc55de270543d1dd1257432404efc3b1aacb4bfb10c97d7406a83377658d28911c6c4f6f6af48fd87168ecc0616ed3a3cd1f1d42e9b9ad88ea7f88a8b0e489ac640b2c8977770b059174c733b4a9a316f3a576283ce6b398ddb1280032cb3b4a9d6362adcce6188b438cf079eee93fd0a460aef8ca7489d6f8d5874017a7e11fe9b250ad3044b1392b085d37468c4d418640781e57ad6a442611c3bfc28580ad6540a3676e4b4efbf7cef78b43a33ac5653bc638701f3f9215424c63ec800a5074f46840efdc0d5226a0920cb9eccef87426993b8818402379bf12ae1982d0cbcf45020e9a5a42a5c358e48c4ebc141991538201b73519510114729863c3554cb28719d9202564f2a2cee0ae17167c2d8ab0097294bce0fdb75f429367863c74af7da8e6607a7c03d36d2e561728f42143b345b969c655b906464cfee6c9c4dd9849dc51d05ca2c037b529796e2fcf7f5641f37a90651f11b84c3f930f3f80355d1b4e436c520fa85d19785b247c5615b268f51e593f504ffc21f40b1e8fa5dfa1086b267335a09cf42ae367ceddca88252a096085b5800e2b453d295d8905d4da9b52fc51456ae336df35a8e821df14eb32ab9bc6917a712c8ff809d235b4ec9b5d4a5a075728620ef57aa91e0f1a9dd2ef656fb6b6af300b7c3543ef24cd59d6b7d1478ee64d1a62f60740aa5c534f6caffdc0041ed2e71aae5a32e4dace2c87e3128114549912bf9ac4a1d775643cdd2d8509882a304796966aa78958ba106235e62c4715fd6eb6706301d5495b7eb2315b4144723c79982637098a77c96da21602b100c1b99b3fb804f07224beab1847fd36f32b30e9f8b08f3d9d80549fe2218dda3000e2d0c21e0cfab100b33bc01befa6d989a43382608d89c6e0069b61647eb985ef738848e5ad928bf750cf7016d06fdcd6aaa2816f3c5a29fd519ab31e8640e673c9982070b4957e33c7db1376334db16e1fd08b3396afda5e337c8c60a9634b38c58de06451b997fbbb6b93c6864b42869578abf27ba01f27a274515dea6f59dbbe441cfaffe91f2ed41c64de69a9cb46364a0fe58e033919376445fa500640999ace6e3d2bd0f290aec7cc949ba7b881a0a15e44c080f77463c226b8652e49ebeb9654a062ab05ad2e7577a7cc259bacef5ca5439730415bab336f4853558b293b3fbc8bd7c43b7109f20af3abaebd2d0da45779972e397ba5b0ca9bfec7ebee0b0fb0c5e438033695e4f690029c24d041f9101a3c3dcb5feb02b9ecc015c4b13ad71dae63b5614bf69ee61b2950ef1dbe0f20ba6ce7588880a0339d38fcc3d449e319249ccc7de2f4df4d0a3831817a28ad6526a9bebdc44e6e8bebef8661fc22484e51d91bb2385ac528c192ce356c43774b44acace77e6f62564ff3b15b9150b9cde87c36c00ceb45805ccfda320b72668ab4597088efdc87bb7baf4aa71947cab0846bee4614f749e1f6c220e5b6a68a7c9747b5451af74f7ce8838f025023c48cd13697e65122fbe04bed5473e06007904745ba317ec05e64cba5086284ac3faf458ac89ae41fd9482f636821b4f3082b053eba39e0a6d216acaececd6bfff041dd5826d16ee3919b9a1fb026b51b7cb25f6e234449c013da48c34b48ac55911d10c1a3b9a7c0b581252ea99629a7ff9e4cc60be2f80871c063da2b57a12631e5cb40e943aff0da999f489205fc780e60c8f9724bd21ec1a22aec7df6b508c01087af63c870496302bbaed39a1aa7a09451a168c0bcaf557e37671849afa1a36cc6589490f03300d8f0c7b185033be874193edfc193cbdc95107bb7d6d9b5ba7a4ccea7aeaa17a295551efecb4e32f7a30cee0b9dc1a3b2dfa68b7c685dfaad4b2f078a377c0faf55c553895b4c57a136f55321f414f974fead2560b2c312baa116baaa61484a4856483ce23bdcf2a91eab801dece8d4330f55e17b5d43ab85863809b841817188c24f6527c6218c0ac7d548b34c9337a7671f7f796d1f57ebf0b1d0fada7f19b4c5c59507c8dfbf83ca65eea33224e40630da157b42dd1b565c3f962489f276a5a41c46f931c8ceb984098d46457425a68c5cd05219d4a78088ea6fefcfb6defab221a89b3a8f6a48918d5aad851f9846cb9eb7b1d31f4159cb7bb13511e1173d503adc6a8e13f02c2aaf72015c6c864398db807c928eda12f9de887b75a58a543ee438cb6448ab7bfcf75534219ab6a6140c937e4142aa6ec0000e27ce8eba6ec38fefec92fa7dfbb7b8d0b43939e9e7bc51eed9e06496e1546c5bc7527946884b42468132e2e90fcf614faec5200168d0c6ddd75714389963b150174d19f6caf2e67bda707530ea86c9b10e39ed9e908b68e7c1b84465a1f82e65fb106be0a6b4898a83ad93a11510c6c73b0708c319281a9b0afbd16f47841883698494a79df141c9f2e81af1e5b42f2f37b5d5c1053812bac735d7598b486294aeee1cbf11d38a2dda30f37f8c0706db52ff71e02c9f3ce603164fbd8d6f0076b34a88df94b2ffc1e4244509b69ab6cec3ed8bdc8367c0171bcddc204dcedb7ad510c7a346abe9a3e7b5fb7b73c5a34ce79c01997de386e8aa4ff521cbee15f234c4ef6acb659f0cd555eeb5d23840347aeabcdeaea36c8c0cdc705e5266e033040a1ed571d59b15815db244e20f10f3fd1db137955d32d2d238c6c1b863a28c75c7035db2720a7ee5dcc8eb07797593b3cc50144888456f7f6f6989fd06a63e6acc0d04312c7dae1c2fe62bb62b12ba9dab2b09bdece0903ecbd2e9e23983b130a5cafdfe332488bf212233daf270e0141a966922341cc87e82af4e592312cfff432ff79f17c7ef0ebdee1fe313035e9ba76f745c7093a1ef27d3f461974ae886be551f35324e70cf35ed7ca6019bd6e3a576071afbe17a3b2faaf35cc7eccc734a144cfddba1cebfe3c035184a83b0bfa13ecca3a5aac3c959d04de09b5543d7b44ecc3da164bf44c7e3369040dcc42d7e9e0735f21fabf0e37b782c75ab92b4e360f938c79f4e750bef4a697a892cd81a01765d6e8251ff03f7c488e9c25ade6ea1ea2f730ab05188a2719d0ec1e6d8338d1367350f0ff8609acc6f8fe3e672c28a823a03ec69d834942970e26dc21c8b3053787842990b038330337fa5e22ce7c596064cd3454cdc420e7e0a15b0cc2ce4524f6f94cc47a936b398947b05743f89f6baa8f4d3086aad595f48afb8f3bcbff3168b4345229e04834e308ab7d3468e60ddf6b396e7e1e68c04b4c588d2fac9d1db30772e01a02b383c3d1aca03a112f3f13c4726d895590b009d79d61ececc403cc38bd7b488a005d27b1dadea5bd1d2411039f64895534a26e13471fd4ff5fa9c3d5c817c3f304ac19a2d4f4dd58ec5bfc299db42922955d19f1bc8abbc51dd67f151bf7f37a16a59b9279f88ca18fe80bcfbf05a31abced37f3d0a80f2bca996b21f240ebf8e08f883189ca65342360ff115e20f06ff16b1049453fdfd640b6eecfba9052789ab9a500c7121cf708b77342e2a740a6458fecc34b1dc144f0a7b310c15d37348ce35dd7fadd79c976c8b675c3a88eccbe11a7a9368f15399077a81b942b481b253b7324d6db6c4057242afb5f0c37cf2f899d392a20f13bd54d4056c47df29d0559f7e4eae533a6a35a787192db66712c2d3baccb04355a6daa421988692a878d55c363e31bdbd014fa7f61a6388ff7c394366f2c19dc403e3d7d7c9169ddc36c5d6dcc4f62cb1249fd184977aa4bfc756de8248b077a39ba41dd51643b9e60f919444dbcbad87beffca7df2782fe77b56163c38305a676d9fe317724c414506e5404db15dc1381473e7ad11f8cce6819371985c72e5c6f49282007e869e3b1e5356eebab892e85782c5654c6c2fb5cd8ddb68280944d747addbd1155af1fd953e354f9314a955e7fd5cf324681d39a5b963e6fd2cd17499bc71228680ad074f08d989e63937f387b08d3048b206917159ca71d68a63ff92fc8e2d478aa65841ce48b2471b30999f2bcfba624f6ed33a2ef18550276e36323b72427c52c6cf2373a4d358e43720009d28867c2e9d7b7032a2187d053637e9dab200f0954d3458ca2425bd59cd2969015e2e22a82f0759953ce6e118c4969a2b5c83b35ecb20d92c33ffa9b394d2f425fdf669d90d13c320ed6e712e4ab670d933cc26a91dfc2709b4eb2f8e976703453a0af924240fc526277b0317365fe3d1ff568a1d58ec013c99f87e5d5ea7e26428320354723674f27e362f96c133904a89761a8c19ad5adb9b35fb10637aa5cf126eb4298bbd28ef9c7cf05d245141e14e01e9e4d05dcbb54d94c127bafbe375f96eeae7b330f9f3d45b1fc140f8b4a5dbdb1a3c6e1da5f61d1fd4f409f78f70b5361e45732e5eb2dc80726de91970be39a4c9d0a2fbf2e21b23e51c550b4ae79844ae66766c1c402ab4aa0c18246dd1dc3de0efa1be25bc66504d32dff9f01d221dfbb2f03ba3f8daccd75e42b48f92228882d63cb3fb2ddeadb3337e462b93e183d9070a1593a7c68cccb8d530b4bb1a78b9a34c40c543da2c8f35c86d1bf5f3eab0b2e9a974d310c775f6efef1f0cba103f56ffa3f8be572835a2c72fea07af1e17add8cf9e8ec52b2eb06dffc0553cac8aa65ff61fbcd06c1aa7e47443565c784125c90754f3dd1cf18b94cdd6e622ac95036d54c590133c6704c482a6895dbce5b3089a6d81e02eb1ad1a987c44c5e08e8e31cd80f80e50334f04844c1da98d8b753b6285737c54da38a1fd1278ca44d8383e62ec480501bc15306ddc9a86ef33e4fa047c5fc83034ee5a1567dd40c653397da852db80e9734df0c912784dfe516f7ad43082b84e8d653b63d35e26b01a7190e7354014fbade4935adb24ff22b487fb394cdab9f9e82d642c448ec6865d93b4c7f8462d320f04b1a72cad011029d26d7d89126582878ee6c1577de348f772b94edf9afeeb282d091c8c5dce01ba1e7c26d0b04d90ece231f78a62da17d763cb9fad152468dcc8a5ca8057cfd6ecf08e68b5b142d059bcfb2ca9347c889d0c2a20f08cccd39aeb516d79731a4f628a2284bca93875581c0d49bd5e3a7e205341ccb8679ffdac9e3474132b62d351097e5c6ab1bf6d6f4212238d4798e166aadbb6c0391f10ddd7a228eb511adf26a2567fc6202f38065459a608bce65789f01d2a14dd3d66c14d7ef4af540a1d776aabb6a864269969b6059bfcc715748da418e955d0f975e707367d79c26886391572d3ad9c6c6269d4fd72f48bfeb2cb4d0b43d8c7a4149c4931128e4e658bd4e49553f95db6e12aff278f8d4fa7adeaced202ae1cab2961f0b6605084cd816dda4ee5771c6d6957a0ed7aeacc0a95b90f95d055bcb24c0d71dd693f661ce3492fc9c73c615a67b535f57b6d505ed8dc0e8ece8ded3236800e2553b162dad06de90db3a78c37d182232f9968676868f8a4c8d4ce3c5ae628a2c86a797feaffc3f2af0fce7bf7e2980b2ad45a83ff899f713e83d6e2d5630560103fd75eab67964a65b038b1b5a74fd6952fc34065bb133dc75f82231d4810f4e91a8e2eb7b081b48effde17dc79de67b71febef134961ffb25a88614f3ae19282c20b83f9ff224cb4dfdf9f95e2a2e6ca5eeb7c6ca2a0b64fc74684af442bcf7d6874ce8d51e3f4612f9b91abfa0aae092f8bef03b0bce633f22fe90f882ba8dabc124129f3cc4fdb11a1b5c46cb88535bf1c7b991e1f596cc188d8f0219e1770f66556e3c48a4e6f8c12f3a07fe1f02a441b240261a7292f0787208c000a1b52b4a9aa85de9ac19019bb11be9e805ebdf6b967a5ef7cc20a4098711f13723ef251237f2cc6c9746d1c6241e425076a3586568e1895f94dc2961fcd88ae4908d263210073d36ba8b5f1a09e0b48b6db1565c0371068ecd40f650db9952694d301a08f1459e5c6fee5cf8eaccdb6167939f8a580939293cf2da5707ea73e572f244b1d88f6e3a31caaa9c96ac9098102432eb2e7d46a780c629c4a08cdf770f88d7390beb803d6cf033b0da60e32a6a33b87cbc88d913ec338237caf291c128c8bfb8fe18d7168d84294ebd755ff5406916ee038d8b292724b307a21dbe7f706ff6540a072d4e248e0cc123c96b9add46fa43295f359869cb7e73d3d2c5c679ee5ddba03259e2d609a3a212fe67c0feb2103f38be9d89ee7c99693081b29366056a132d63fa515829af32e196fd87b44988764c385968093d0813132235e1e5f8aa86713a79542427764e3540f31d9bacd8bb8b76764585a7bf1ca8971ac16825bca58316130e6f9fd5f25c09064fc30b09e1c9c2b25fbec4c0a57cfedf96c787dc9e0ea52527fd6c0af59c08cdd7d907cfcd55eb67876f51af37334d1b224f2242fadc87cdeed24513e5cd15734063b5440d85a7ad23d95d796373b5d81b00aa3bc021fd3871b906880db6828bde9dd5dd92711e94f0a427010be8d4ee56029454efef13f10667ea918a102585e4ffd80cc338151574e7f2081c33efa3cd185a0b0f97006ad0db631095694988dd621ca0038a9a8c9de47ccbee50d7997ecd50104732e8b63079a2cdfab5031ebef3ccc3914d7011f0a0594cd3d605f30af7a7b17232bb765d3244edb89b128679f4e34458814d38348e2a20fecaedec04d6618788ad74026252015dadc450a205ebcd908a682b1f9dc9cab64ee33aa11cc0ffa8137a351be2dd01989a46b3ae2ef197e8cbaf3bb7de29d700bc28b817da80d55299afff36d909c9e93ddd41b10f2e543bbca872f8624d1c9a3737119b09199575f5413732e8db876346c1c5e6705deec4f4671a4816435588a3d5b54a947327c29425d099a88ac456836ca73f1c3f8fe58cc74493805f0ec531f6610d8c5d86d8b7cb14ca40880ace9779186ac533fd4ce3bab963c079c63c9cd338ec71f1e160676f98af699b52fa690639b7ceea417a192346d602029234eaa6784cbb7fbe9b6a0baaff6bcf3e2369e107a7e0a515f01caa0117867a4c1db38db9e4373918e1e5dbec4c38eab67ca8d1f7945e9d60c5b67caa2ac5045bff230442db1a9c81867ba219b5853c545556a9ab6a01c53cb7804ce54968aab6ac6483879d46513cfda1302c647f79126cbcb85d000252cf65dd4e0a915f7962e8a910bd1b4b880bfba697e3f792dee898120a5f6775e9fe581059f7ca6289031f2d62d4d89fa6b817c62e43ee11f4354834ae68d5dbb7e665851e0aad8712dbea68453da6bacf47ff38e56be3c74cd6a6753ae78d75207bf72d50856a44e356614034c8b7d587da0d7e82d34dbb39b927a782593fb7f6ae93b30fc6f59ac31a69498cab5fbe9c5d04a4febf95c6ba0675c852ef2ab6e2b5051da2caeaaa70cecaab4a9c62f1b81b9f7ebd354f02c690053baccb15d92fd3636375eea5ab4e99b013766834270b5effedc84b220639caf9f513e9a3ab8dd640d1f9e93db2ba44e02f33e7cd93b43bf9efeaf647148b6fe9973276f6e249501502769c4cca0025f6496b19dcf4fb0b0ba57742cf0f01630bc436c3c2236d01deab9ab29f834962ead8d7a4a19ee28b1208770c892b0878e753f8084fd125ba7e1672d936eb7a29ac7a6cf3e1c82836777cdd74cb915ac0fd125a143b7bef75fa2cf35474951c1ee9115a10d564c8752befd19421e138315003afaef9a92381aa3f73bfec854516fd311ee25fbc20f3b448c0562c16f9cd291534713ded166a0b688d83f11c19be1ea558b828fa511ca5dc9f59c5f2d025cae5afdfb99ad5ef54fb3c56bad6fae04c7dccd09a7f2834e3b7745ee6675c9ddf2b4a2b05d4cc6801ef000f6882c0ede2676a3cc036c3fad94c53419de784a5ca3e1dc11ddb7628bbf3dc24491f2f26d22bc262f4e5c4b008e4f28dc985c5299abc0e2f6ca2d0b0c1dbb1a4ba9c7680e6fd540a43c1ab20b94d3687e32d317f10a372be9950146e5fde19bdcd16bb31155d428264859e55efee77edbf59fa87a52e63bc7e738af4f167e22b7d3ddd25180cf579249166019326c6bd3cb5485c1ada50d0e0e4b381356c45fcf8e18eda90971d4e79051d6cb79b2a7175aa9eda1283db7349d3027720614558f0ae72db9cacecf1ba3901da224a166b8c6f984bcef8c8312adab7f35cb5f329429d1e38bedd4735203b9a82473394596875bb75d0df7b0fee2309f72793d46fab4627b7b0535e7fead3b37cf71fa81321a4f3d6bd74f7052b5cfe14af5956a80b3af23f1b5203dc8eec32b85f8750eedf01fb4ded9c6fb2c6b5bc8b8ceb5f49823c40d92b1830f61d9bc1f473325d8374b6b270da10419dcd10861847253a5a38b9199976788b8e06d1b8b585914ef37e334ddbea05e2b77334dca464a280af1ae31a3a55293ad7cb5dd90a1b02851817c32f2a595d5af0dd68d277cb82d0927901e53e196297a6b9c037efa9c7986d1aafcb166525fb94aec0cd3e80b9d5034d873482d64e78ffcc84b53e02a809231b168746067d862c99f41ef2518de479b442a21814bff60d9d49d56bea6cef6ce95704496f7689d29e56e61ab7c38f1ea020577d7c95cfcb2f3206b05839dc194b53a9f6227d4608835a27171cae57b0f84869ba5351e53b0940ea5de66308a12c4e3d949e2b390f1a664ceba555f0630d6d4cea585d6d7e294359287985d0db717391ad76e3df68fa09f71e0b54f1643ebead915956c160c22649592d0675927cb0b3b975ffa86a709081df45d16c274d47ebb6309a41e5b0a880a14d72cb688e534cc8a0f42db33bcf83b7be99df28cca1bf077921f601a184b42a52a37aad4c8979c2f3293c463a1f32b4c8da71d6b064dfd71f4659cf7472bbf5c4579625674ed51218028f9aea2abc2ed7a5ae9cbd33139ea4b8912ff640cce7b3f59c276df3c88d7d8be4d59c3ff38ce8ce7fa31c74647988bf276cc4ad465f0f2828bc89663f2e7286ce34c2974d30eb9751c9233374e92ae76a2014dcb1eab293b8c8566554bd9ef812feb126c7241749f194fad7b6b3a0dd75df534c89ab51d1ce2a81aedce2c82671d48f16c2e204abb10840da053bdf2e0cd069851166d42188829f9205b7ddc109d179e4fc463ad5da7a1087044aba25fdc73715f41a12c13039ff7712320cb93fd460255cd1418851c5110abeb2e56c38c9adc0f9d570a656c2d3f403260b696264599a19ec234ff5eed3249f89b485cdbb9cde35842c4c0d365f2559f6a62e13fabd8943ad4bfd062f73761cee515770cc238f3a83012bf9405b26abca1fc22015891ae141662de2a6d334b9e3e06c28442ceafd13f2eb7b598ee06eedfeb2593e154ae00e0eb8ad10a3f1c6531668f0f7fbcd1d7ae0812e31eaf0198976c2667c6cb7f8096c29da99a718df07b37e86dab16af4baa39b58c8e3c20dd54ee8a4edc9371ece6a3b81be366d547c39102aa81fc9481190c3a72e1ef1fe000cdd0d9c573c49eb8bd863f65afa6174a0ff57935b3d4ac50425418af48e3ec1c2df998df9f3b421676cf63554840e301125cf42fd0b22a769dfb7868b739537723b8f86ce8ba3d531554a78c869d21db89e5d5e922d6bc418400db931cf57e0038fa738f443c68d0618947bf74a3445e0f8d476d9db2c2d3ad58368648a725139b861c6a17f1c52b0fe2dbb36c0f134e4dd4885e7f7b70f5048fa93fcdf99d38f4c4cd67aefd1729d59d9b1c35df793bcf29e176105331bd8f48fd16eeba6089969ce7163f66090d0e6883a68aac1c09dc70f907232e694b6d8971e22299df6355eee76357228da3525f0a8125d8047c1c6dcc1882e4bac948b9ed041f35dc706809ec6b1d4fe8723107580ee39846af61d0743bad6d0013f79456e8a0456880b4faa99dc96f1160ed80c8983944c1c85e609d20e585cff84afecfa6c348673afb7c1c1e230d05db8d0ea9939bb66d8f590ee2bd581592a564b3258a1d0edbfd7ef2bdf5fefdd89ec6ed16d9ff1af160f9b0cf48c5b61d5fb6e88b1b6264d67c2e58ed38139a5896e0e43d29ddf436d77f51782b68cfbafcbfa941d09ca15909171a3d18aeb0b437515e8509fa50200e010f604dff297da946042c5a11ba7e28ee101dd3d8cbf80f3578e381434806075e457f836d346b24c6f0f929e90264d213e5f435b3bc242ea4667093f97f0e1654481b8c3f5d2e7412168968426ebe4ab9cc3d5c6ed09c5122a3f541c6f42222617a5a238fd1e565b1f9eaf5424e6586e2a887b37767e2862215bd852486d4c796784381417052e84c09a9bb9a8d48787663869e15017beb470a80a474a3854852b255caac291123e75e1490b87ba70a5844755f852c2a36e029cf80d4b4323f0eb6b4f386a85c24207100e8c581afc692f3445b9d1d475fb96ccf46543c700107f7365bb3e1782fd17fa15229412414029ee3274b45231792151a099d96fcc0fab001a13e0c9f4cf03ce189d43d26c111a00cc68a9fd26575c569533fa4c6f95af3b6d7a81146655f40e341f7aa51f9174652747f30294bec5b22955dc8be4e71848eb6963642d8b3e0d49eab6cd1e7e47df7cd43658cee935ee12253e9b3d08dd11455a62ee2b8379320ce5b1c9a931d70dde220974ea771efa8f26703bce46b01569b0fef5854593d5444dd4c4fc45ca2b4c83dd3d6b31b7990aeecf3b8ea28eda5bbeeba4726d5381540f3b96f1d7ba71bb840f64d7d9bafe71020a232b5d06e45002d77d2e80b384c5868d23618a6b2b6624f829322e874c87eee564bd41d198ae5d93f18b8a9d892446e739926ee067096c9fbe566f5227993e0d61389181f12a936014ad9b42236a7721cc8371b585700eea18d16cf0b6149b7a2e922926882ccacf2a2afa096563715d3cfca31d9aff49b8cabb72c4a1cf0efa820cd4bc19f85c782c5fb6e45f9cf1bafd9f3366427160822394487b70a2397c82987e2fddb4f2ae6fbd27a991d4e35c03f13c5a52bd78181c1bec843741ed14a16b3887f2fe541cd59da844915bfe5c2355750c7095e2a4e964542fa7fc94f59d581652fc8a7f264e2444c3a21600ce6b3cd1f122d3491f1374ef1a415f7a237b992fcacbdf8d6611fbb36011fcc105cac619e1c07396525b4befa466477de3fe4bed8fe68b40389b312c0775fbf8252a9dd5f53d9e726d5b2466d3800e5cbca2d1e7582a6c9c66d7eccd643207b17285c41f3955ec1b1da52ff2809a582c3385d01c6f9ee4a4e844f223dab60bd1e03d06a82105775f467c137a9f11cc0848fe91c90f78028fb9ddc16584229c75f5e5ebbe75edacfb1a9fce2340d0dc58e184cca6a15a9f89bbdd869c6679ca9a7a877eab8b09cca99a9d142f143700eca6243a776e34217437eb3450c810cdd6658ddae97fa5efaec3f5a0c30a615dbc62586daa1809529993a344ec788d934bca7cc132d5413b4b8273815ef374ce34aa670c71093ae7e099e19861671a98e23ca1da097acb526e9dc53b2ce738798697a167689614648da8dd847bd00ab37bcab6cd1544a6e2e1e9a414d77d4186e79705c71b2a4953f07349cf840af366c9cee48a429fba8f25b827ef23a4264a8f980df1a8ffec828535cd9ccc57a31554899d65332e16744ae25ecc18ec2fea1192281acf8f9b2e74a6674281e6193a2ef1117187f9478a33e1ebd22737d1bc6cb1f738e2b6da2d4438f3a7c5c8e67e4c6b1ec900d6f970165118e6c200628fe2f87f57e7c2f97d3681c1cf1e5b6ed75968ce3ad9edec0153dbf903b917c6f3dd1aeff81c77fefc04e3ab8ecc4863fdc82fa2cb82b5688290d81326ef716bced01d318a4f83498dcac0063561ddb963e4d0fe9394e69c8e283212c2b55251fb0609d10848e528562c9b87aaa2b71700db64bd09c54b1e4c6afc560cc3dcef764724bd0cd294bc5d5fce31926330900994000b7bb10c9c5819b4e414f233687b4d2dec4c0197872e99e9a420a5030fb5abbca72d368c476b0ab8c7cc3a55d54f2b333ee56d90780f6415227b0860b760c9ce60c61daefe6461b7b70b74f10add57c5183868f4b60f4b2f31bfb31cfdcff64cb0672a651fac98b0bbbd369b6a309289a3d354968dbb76a3a35bbe9ddfae82a21fd12db76e24a16ad24aeabb24f163caf5f4eddda9002e24ec3f505a18dc474a22a66028998c257715697ab78c97aa5cad70beaa715b271daa7fdb6fb7b4aa8363dd0ad7549f9456162dda5ac8f96aed8f925f2c9a8c4a27c10ef7ddc0c58397783f45575bb664e5f4dbfc7690a42d596764e985e4d580c0326ba7d1b5573c9069bbaca4611da989f96660ba00085522fdfe597c8a3ed124b65f1f535edabb99834e13547a25531ecfd08591847bf5e69519617b3f8ec344bf5fc13508984864ab95e634d81712a00cfdfdb41a27684440592f3b7b6841ce47047be9a0441564aabfff07811a6b281511b5d13713ee2019df77a3cf7473a9141077f0c9e110833253909e76dc5094b522c384a767eac9d2090fd6d48248078532efa0b01c49a6757385c0b0981de33e304927c34f5da2aeab3c78ac6b6ca59f950ff1aa068da4d1b17e37030ab2c9414fa2a4d8313bd89016734b489b48f0465fab75f4295e613f072d58d364a34d0610a1622ee25e40e85161168de6112a61f4d8d5c69d11c1a06d9ef21a54805e0df03603b38cd450dfbee60cdb3f1a5cbf4d4ee6c1548a92a3cb2e0b364292dde6051bebcec7b50ea7a339e21fa344ff54b125959062501b3a0caa534c2b35edea28e7e3a836c016fcd75d3927971d1bdb540d334e01332b9d8e0ba57ef9108aaf8d9caf196f2ec31349b50159069a15de9f165fa74237c8a68798913966c2bf35a1f8c8b951391d8846f56ec66bd087fd0d47d8aea174ed55c689accf593c0e19d6a57ea60e6723a74cc4af3f92b4c51590a8447a05c271149db0c20e22fd9598611d70fef8337821bd1bae8e184eb139936ad4fe295bfef5434bb9c1d77793270d67e295dd376aa6265b834e5eb7389bb4fcb7e3ad2b73c3c0d467a3ac86cf3fc3d7d0b0ff829d1f916c666bb6525c9ab2479c03940a8d4c5d11fe35008a40493740050fa9c1e103f59a1d1876c714576b0d9e325895abd6c16fba1c3448013f1d8144c5b730c42ade7ca7ad16210688f22d88bbf8ef4f40fb926cc7457a795cb7eb7109300550f7bea94c0354427fb4669b03aa925803bc92d4f54687ac01403d5e49dc05de362057048babe1d30ea014255ea0f0e738432d805933192d17b59dc1466b1ef1aea14b8dee76e32503a923a2fd07d6e0c3fc5c5ce1e657b76cc17ac2a0651b93f7b70bc5470cc5ab350b5f562900ff0074209d0e28351c042d81e87214cb5d1c0394d1034aae72895c3052b29a0ea5f16852a53ac96d48aaf458324b0b1aa515d5e8d1644661a93f04bfad4661c4394587d40632804c7db7331e020000c41de60883e543ee7412d4be2f7d6abe68e1d38f3fc8eb898e0d953631696def6e5bee2da54c32052f086908ca081d8c0a46a55a7974b6a66cb2a1c7c55bfeab998c3773d17321333c227f094999199aa1d2746688a6e0835b7f9c11a293869ec7853c31fbd122343bb8334213d64e67846684fc353f945d1a3e71e9cf34eba6891e86bac6b19170a6f9eb0af0ef4ad38e64b8e05ddd1b012c82b081952a9cf0f112d392b2f617d45ef457e719d8306e90e2879ea32f68082336af6469c20626bee4f14aa5147539b55a467fc73cf1e1e606d88dcb87036c1d8e3f16c9f26db86d1b4f9645793a113367c22412d7a43fedcfef518f038677b63cfc1de6accbd3e9743adda7dac693378dce39e54febb389ce46082ab83308ea3bdb7efa3f61a9bf4f71c0d9a228fcf3c33da5920374ae587beb96e338cfc39ee78df2ede93b9edc85520593a394cafaeda207baaef139e50136ffd3cb203cd9bf1d3ab2299fbe7b9e2cc3f1c722d925b53cd9432535dbfa320c47253ea95333e82cd7ef388dd2a159346da556638910c67045f88e45c41521ac12f314c73cfd98ef2f084f8ef998a7e1f44e1ef557fb4b7a545c3cc9a7396ee910b54f433ae462b56f3195dccb900e512a9e8286dd8f09ef50c574686ca61d17ebc3e0e2fca0229da3334c762be66b7357627e5ce5981ffdc84527dab88ff91ac27b0ac0af6e91b84c3814994bae32b43a403ec7e098af7131e6650ff994c76b5c5b5ce322d7929ba86e1c31d98942b7e262fd11c6b827a69f18dc75be7bcb89aa30d74526b986f021fc30f1d77c1898ee0541a6ea8d7a7905f5d25f2719f3527e07c213912b685fbf019d837e7d07f4ebf455841f2dec7fbc3954dff2557f0a678bf2b5d086f23f7c11421913d63f85de10b7b3e534db594f7e3deccbe7a89c8886864627724ff22b7ee45abc737415e2623542451bca7568dbf2a1529b081bca65ccfb15191627a24642f824326f3288bf6c96258e320a8a53a15c69d06cd5efa0118eb8346cfc7ca7434314f65feb53246ac55f1f965c51f54aae5aead2213a44a9f4f0231e7df04727b24ff1128b83b818026e1743f88d09e66870b9f8abcb8489f0633351fa33612e74aaff21edf9e8c7437b8e06d7881017eb2b913988110ac5c5a009732194d775524dfb2517eb8b104e2fdeaa4339e6c766722c2ef32b2ed677a11ac2098f36e74c0dcf2f4f5cf9344fe367de893a87a4d962b3cc95f96e1891cf7110c21d196a9f1359228a6170b17e8db7e148c8972da05efe24f2d7f7f5dd8a17758e06827ab944668a47efb97c6b84ab708a083f13d20865c224d28b0989926c442a0cbed5fa983011707b8b7ea55dabcb86dff0a1db280c9daf7da7751c0e6ed17d19caa2f9d45fac8979ccbf7f310f9e3c8bfcb55d915a340ce4e2c3c85a19417832ddb64f851d526beffc8eba8864c2643ee6bdeef432a1ecd6fc55b8d556c1f810f817548514e62668ca84a6cbc5ed4fa71accf942d775322be5f9f7bb6d3b55cac5e8886aa15b2897941116190a25efc54b649640fe1ab797402e6aaf6d7894f9be7ced99d892e7abbeb3b6f354a16b6aff20a8ed18218cebfde83f4ee5e62e132683fc67c2625e7b6f22c55fdb7dd56b4059fbe94259d33e26dce42ce8843f1c94c230780473d7b309fb92b7f7e9c2a43661cadadf2f084fbeaf62bab85d4c1da9c92c1d99617e09cdf3755279aabe880a2f9119068f92c7c546247ec145ed95c8acfdc75971b71f21e976288f66cdbe869ab4f69cdbc3f8f86bfbe6c40ff0cf869e85417d675942298fb2887ed1161916d9246baf21f1b44e6be2afd4172691a0a7755a91d7a42e8a9f87d082eebbbe7de2de47e7f0dce5ee61f0d7fcee7f74df7dd775636b91bb2fb693e11257722be5cea20452eee467bdc850baa84bad35cd5a4c975cec3c17bb6f0bd35994b892479caf38feeac01c1f1d9841f99d676fd364f92c22ba771f2e76b65bf2b5203cf983f84bc3f47df8cb7ed7fdaa6b3a0d89ae25703b4b1256b28ddc59920872dab00b936d38101172c77e84a24b5d941c0753a386ece10454be00033593f96bfbf974896271a4a3242db32d79725db24f2ce38ca6b5f782366e6d9d4960c9f3df4952d6bc2d3f5a9926b9c87dd93826cd880423eec819811c53c51c1314d989cb0f15a4ce4bd0156fe63374d4391cd5a473f80849dcf9a8a2d9f2b7f4cbf50199e426b9dfc8c8c8a8685a7b2f088ea8a22d4ebd50254ab9647feeebf139a9bec5b5bef69d731cf3f0dc54964750725efcd59c1109439763f2d7882ae2e2af11ece2af9133cafe1abd2df228cffcd5a08e223e434772a949916fe991623495803a8795cee1aece31abb5f782e0ff28725f5cf44702ef19297065f4097804a54b937cb20a325cba04724cb3e5ff43a0d00d02adbd1704ff93b27f47e337ab3c821af8155f8fbbe2b296d0bcbd4e2a6f98a905fa1b5e32ab91d996633a49a14bfef24959409c037962d48c86930a257f4b927ec9f2a91787cda2252879164dd887c55bfef4cb94f94c232679b4481329d72679b44833492927a1934bb648935a248b346176ce26ac63e08b364ffcc946f0e2dab0ade589db628c5258c7a40879ce74deba357fb638e777a8820c52d2d9dfd28682ae6b58dacfe789d1d05f7e95a93dcbdaadd65a6badb5d64debfa3d6466b9e04f7f883fc53b55b43fe11dfafe1a1e229fc33bf3e5fb966ecab26cead559fe36bc8683ee345cc6555ec47dc75fabf7f692dd3dffbcb1340dcd3b0831ef337ab364e111741b78b435f078f10882781465f0e852e1114726e5f5998747b0c3e38b9c9442ddd3cfc2a3edb781c7db5f038f603f88c7ef9fc1a3d84fa3a75fa627cb5f853b2ef6c7842e9bb309d3d1dd7fb12ccb0f8fe0f8a378c2a3ab9fc3234e082108218d9cb5eca6339ab03f97b1dc93d2d16e1cf4850994e9bf30619c73d1b0493d8c32a60c4c94e21f7b890bb79fd99a9a509e3f81ea17c159dc712bcad303ad127e14b34c5842d8b3d50a7bb6c4701576e388e15eb525730f9394b9bf5a32f729a4cc3d2ae4fe33ca9c2c737f83044ee47e04ee6bb80700f798fb30ecc9fd3365ee45087bb642087b723421f7ac1a2118f66ccd843d5b343c9f308747fbf6a70c0f8c6b5020e5fa36d5eb9c3fb355dfda10057714732dba5fbdaf47708679efebcb21493461c22244c207b8584f5f4fa8aebf16dac52640f207887b12bffa9e475dfc70bbd8758c88bfbea7f1323fda55ccab7efccc61ea2defabe7791eb636d9c3dacb1b26a1e1e821d52ae4bb3a20b05ca13e98690d4cc32cd730fb2ed249808e8d9c8e8e8d5d9edf5d808ec9157cebd68b9dc31b871c696ef58bca19abfd6c6aca1b1e2b6e79c2284fd87ec32da911d714996c45536373a3434777e2eca655776985342a325b17e6479cb961ee53a954cc4e4c77614296e32130af7a7fd57d19bcb3fafb3b310ff32fb837ddf178c495353b018b8158a7ff989075c24986c4fcea9324a063497454bfc23b3b313c3124d62ebd0ceed8eae7b384ac9e75c209e8d8ca355b138fdbd3c913ebe93ae2ca6e3f6df3979e8a1599c00b8eadbdb7730b850f7f5d98efef98d5fc2f325bfe9fb4d2a54229259443928a8b3d61a7d3cbd0e6d3490834e3ca221496444caeccfb87471b33ebf008cae018acc2b3392b65b50997cb86b39b56dde511b343ea62e3e81922ae4f952432ebcc1ff4e4daefb8438bc79adc3c342037cf57628fd4e4f97476937f1a1abbc4c4616013704201a528390c07c7cb977e3f721891d99a6fb55caf4495c89b38944a4425c9add4599e0dc36ccdb75ebee496cd25c3a4b50293b6c985922405943e471c2699883cc0b77f24d0e8bacc83666bca26a5d4b3d69b220a954cbf7e942517f060250f2077135e88b2d1f4dfb64f6747e77d280f9a306b641464146414646485666bbeb5f782a0906cbeb544266c1255a2099b48d6de6bedbd20f8a25889802811459aadf9404c40444144414441484548b402292d2d252d25310149a6f9dd655dccc3f395f94ae42f2b4df2fc5ae4af1a797e9df94bc9619d504f21c44403aa323924a12cf258b954d90bbce4b11ee5f957a6fee8bc7271a210c5bd2e7371ca7a3816ef68d0f84b83c60d479e2c3bd3083b2623f3dd382a51bd61bd5265c26ae5be7ffd4ac44afdea65bebbf7fafd917a995f85acef3c5cb9fbc7780cca8d52a111d58fa9f78709815c6c04e6efcb5049e56a85fa18bc6466954b9810097d1690fbf52b368282919175d14514a010da7aec4f9e0f94e707e5e95db62de1367371e3b275d9945cf4e2e2dc64409b11d086b4056942db2422caf367b6cb5d02917a987ec6b9e164ad68b6b4a0ca0464042403220287ae10518ffdc91329572b2ecea74b1356936ad16ccdaf4b382ebaf4207881f2dc925ae82980e8c902c83d45942b5b928bf3b5242155226b94e75ba3cf2ec5388c05d466f3e1934a5641863ba96491841daeedf1978fbfe87727cebeecc2f147b07b361ffe9adeb474d59266d536df93cf2d332f37d5ec8dc83a611e9e4f20cdfcc7c999ef23080da01a2679be384fdced2c5d86721979bee7f9c7c605fd766c5f109973a6369b434831a349ee2988c83d051143b94b75727b4bf326a56cef73fc6befeec4bdf597f75d3f1ededb16b6a6a6a6a6f0148ed762af3e0c44b1c66e5a7597526a6afe795cca1c6e6e5caeca335d3e81e3ad686a6c6e6e4e9cddb42a9fe81a4b63d191d3ad8d67baeca2dd7d864edcc61a672b6d2459868d8d28529ee9f2884e870e9806db6016c69ddedfc66138cd85ddf2fe18349ee992065dd78cb2dedc2c17ee7fdf80d4a35ebeec1cf2ded44d75ee7521cb05d57fbf80d5a34216cb05d57f3f64f5a8b033cb0598ff7e88cca31ee6bff780cca39e27b35c8079d52f0006b33c1566751ff33cb105c8609607f30bb80f8339c001d5df5f40ea655e06730066756ff73baabfdfe121a91d984f09f151e19d2a43540ff33d5b30309f80be31afc23d5b31b85d85ed550fa38209427da72fe24aa87475118ea7f32a8593a94d04c8267982942b781df5a4b5feaa1a7d1dd9e4a3cdb78d82ff9474881d42b17515fca9f50f0131b3ca94527a4555bcc4b54d4e147d2a7bc2aa6c43a80a94fe10d9c361d92d0e03b6e3c22a9452492925f2534507271b11334f8cfbaebf1ff3756453f5e19e862a3a3859c944a16ab4074ff62d4663c84062e4d7c2ccf3b7f9cddfb8b0ca12dfe69cb6a22c5ee2f4a9bb667df313348b5bd8a1f5070780d49fdd040e49f9ebc1b3fdc4a3670f3b5beb6dafbd9c8f80ba8467843ecd9d47aad9a01eb55a9dac1f599bded9b861baa36723f29bfe463f5441864b718f3975e417fbadb3f50c9d9474c3b2c55a37eadffcba6d8fa5496ad9bf73c8157ae62432dbce41ff07edd931e7a472a226ae357b2d4236752e5790525be23fbc274bac339b9ab2ff5ce25d53531e777a7ab29f50e9562595eed3718991e10303a4583b414495a4d84ef74006455d6231a4aac4da5518bd3398c861281683941440c5e08e9e8792e2d575cd18ceb273d67d3c61c9a7a37cb23f9eb46c9227d675fbd7a3be5b5b6b3d9db2d082699c11aa52b2fc1aa55fb60a758e4a6390e553a4ce315ffe14ea1cda4b1f9a2a25bbdcb64d7e3dac37c5bee58975dfc7fdc006494141de2468ca265064172e59aeb4c852fe49d63960f278c2b29ab515415e01e59916f947d52ccb5adffa9df9c88a41141b428dc3855848de6c4668f684de4cca19a114cc8852b3cea1bd7c4d52a26e18986f87c7c545f766de10fb27303ac0139356145102a41887677862fd25a063331ef2c4c0292e9759b3ff8c942efbcf20cd6c71183743e58a2c3b910ef238b321c1c00666e47146cb0c51f6a7530a551b64197a5d661e974942943bba5075e5fa1718bd596ec18c902bbb50e37017921370111f79a1dbec66eda93b755de5427fc24b12b3980da593a15827e371e1ecc0123ff889d950ee50450c852761748975339ee542d60682621cb6012e1cd1e5547c1a5c1a93299ef2f331ed6538457b239876e3ad223e985e7459713ff7c0885c71107704b3db2a32d002f3a1e989d1f0b12afe3a685efed49b653d1a1962a0ec7e1e69b234238f3634d77590c2ca9dc5cb184d3a202b340ef903e813e47b9578002dcaafee5867e68a71469eccaad9b1f46014b0c551ae79c40171fcd55947962b2777fe54a18402af872da8d88244e7032ec468e2c606f9d53d8b0c4e18752773ce3947b1fe9c5f23a5ac61084c5cfa3ee9fce1fa4b3266378836ae9b895303d230e1c36c045db25de170697e65bd2e3904185cfbb26eafd97049cd46ead3e734f91d17befd06274cc6b81696c825356fd888f6f3250f6d07ba7271d27c8dbfe68b2b2b43b872e96b3f565c5ffe58a9fb20536c44becf12482672b0c2bb97f2bb29a7a39af5e3f4f47b9c70779e5d4ac6e8565cebeca1bde4c9947eb51cad9f3337b16767ff1ccb18b952d7b22954902445d16f6fb7ed7bdb9408a2cb170d824a6a4ee2ca9be3aff9f4a47d75593b9148244b394876f89fc209788bc3b2490e08fa920472e27a766bad3692b934979e6ee19a618cc18473f2014dd3344ddb6eb02e18c3e7e7863cfe910c6cf2fc9e5e4891e7afc07957598e587044258ff73ba059a0a1982189d6a59c7adf3c6d16c569a0ff560d683ad30b47b100e8cb195b986cc1c5f6e5851eacf4e0e0065a7ab8c424524e72461ec1ad0ba333907c9a6c30860d2cf86781197904b38b3bbed8420697232766eca00af01f893290760045892b663060420a2d4c3f5292c0011659be3401022d3d304203104114e144172642c003095c61c696258abac842872ac820b2830f6e40060e3d686146155e784ef08359d11832083241146330110228a6b86188288c88811631da8c1b9481c5d21363006111c6931d3871344490121fd86249e767072678a0b2431541558081840880609a155d79e2072d5f6c33339e10c3878619962abce041d00c335cd1248355ca5b17d979aa5cd154250b2a64800446cca9a0810bb21811021a388122e6ef5ac0baed20d75a8fb832e8a2943d1c9d2083598e8270824a0d6658c83043fe80c309baf44cca0a5214216332814c16933908811355a6608ad1e020ca0f320cc56e00828889580c9a0962ed8414cda5c90ba4ded28109c58a1f9c88c5e01921e110f3df711b40108b212629e6b85d056bc30c475d624e8ae074c002054cb1183e15c4445741fe1423ca8e3c6206298e88c560030431eb2ac8974cc0d89e34b121686699e2402c7d199250a824811485c88633264cc32208273db11e8c88c9a0469e2cab0d5c40208d68a302a23c825108e5d18234a28dd613e3fe6e36f4a10127a6fd8f8d711cb6af4d2429e4fe80b40e72e3292cfa3b2d8b6540fb0c6cf445a7ffd3673516b23dc509e8d8868fe8ba060aa11c3463e57696287ab2404194050a267f9a21de13dbbe67ff940d87469478a61f93fb037223379e9201faa2d3675393777753534cfb29daf7b70003c4347ac59ceeeeee3ebd8694d78860c3952ee9d3d0bb72e763185c1174b33b89e7d9322b71cfb9dd7b8ec0353799bdca12fff92c17b8b74f84b35bf5d93ef4b1dfb3a5c5be51f81fc16a715f6a639df56cd8b1b9e17715fc2b0252c8937e9bfdef1ced1243d6754d15fbdd65af4adb7088acf5d6ae569bbdb063b6c3b255a81ba03624f261ef89f4ab308311253373df5d324f8c27e6dbdfd9f2f7421fef6f7a70759a292b8975a3a0d58e7561c74ee108e64a43ed039242ee34af7ef46d175659e2daac734efaa138bcc4eb7f0b94648b879fae6be82561ca9daa30157447d197666be2b009005702d7e2549cbbbbfb295c0202e1e64ef4578d9f363c9647e31179e037f3c97c4817b5f434e88e2df3251c78b43678290078a904dcc2209188477b038ff749c023a8fa11f0f835aa07001e5d2a3ce6e0cc103fe611caf569e0252211804200e2e9c9f541c04f835944e0ac460c50727d8a349f2ea91e44a2f1334834f018832cd797c1aa25d5920a8f31086189fa42afa3228ff27cce86a353c9f3372e3c2a506e00f004407a53baee860f4032340565ab5d72ff0d1f6e4d514a29bde1c3b65acdaeb59e1da2a101bbbee1c375efad77bfd5fd1b3edcf1e61dde61175762947c9a2c310d23206badb5d67e3be7e48ecdd45d60d881f9fad247e661befe0b1356e3eb2391097374b858bfaba19ab299577d4c38f2ec8801bf0331cb4767f07b74069f27cb84e3afc2d1e6d5cf84a3cc330f8633218defeffe4cc8936fa8a4661a3802f204d5cb8463cf4618b2ea73e6bd38c76b841dc3f117ccfdd4fdeffb7e07732fd652a8cfc3c9381668e5558819d4cef68a263f9560ee429fee69f898f75d373d89bb8ecea7df0f1432c79dbe1d9be7c95c3dff80b832fd3fbdccf2e3fedb5183cc340af4bb9046a3405f0b57f204fa12bc69badc9fb0e722a6177b348aa0a12f4818820421481042fbaed14299bb236188ab699aa67918c43b6aafcddf8f9ee9ce0a35f284f9148f19c89af630dfa99e04216ebba83222285f973e51aa972adc8d03068f30644dac912bb0204f9873a2be1a1e33888bf345eee7b370fa098ed67353478d31641f8d63fe084a977ebbd85ea6328f6d644316909bb7bf79c356bb52fbe9e4acfd3c640bf4ed7f3a3bb6e721f30839dcfe896f441b978ec6389d87101122fa8f3535d2a517f1fd5d2a95ea537f3dbed7c2ef6d28afa436d4b49fd33e554d4d75dfde8ed2d1a652a86f14aef6c465f976fbb2c451714a5223baaea95ca6ffa3611f9640a8948d01ea5ad15a340cf5f3350b340c85e508ba4571b738c6c47cb8bb357679945deece6688bbca49a854e222a55f43ca8501c90bee2881beebfa5a58b5222f79681944a62f9bc81596581d46d03948d02f20b942f7f4650e9d637bfa9a6c16e40a1d967d82f6b446d6fe84471532d5281efb894c93c8209d4366fa547bab7926d29ea073de7b6f27bd54ca4314cae7d4e409a9f79c09f3f7dec94326d1d9f2c9e549763c793cfd0ed477fded40e928b92f33cc4f981b8e4b66d6914c19c5e37b1dd9e4fd9c3adb9289ed0c15d7b60b0997df69e128bb64ee3be98d168f721b2ff8234ede369aad977e933d789341236c72e8f4a3a49237497463fbdfe451deb66ddb7e943331469e6c3c06b9c9f2bb55d6b41737980ffc9d16baa0b8da23b1f86d095989f632f707a466adf3d9cd69a5233e8c2090e5737824f2f1f0ac3d80ca1cc7a9c1022e0910877652f63f39b1f4e4c96c5642f61f4579827f5777d15f88cc05da883728a46082f6f2ebf165894f5952496d962fa467ab62ed3b36c45b2ced6dd6b0102bee23c9eab5425ffef7f3fdf8175f1c659b9f67d8ac308d8e1a9b77490610100f8038633652fb3634b2d55abf47e78a6f9aee122a8f5c53babb697777d31674519a491a57dc98cc6bb26709dce18e6de485343e702f8d37018bbba2f7d280790bf064d5c7b49156ad54abd4f750a9fe7eea79728ec3bc2a8481c198f6773fb0032c68c014134340c903c8cd841042b9d66f87a4e2a29443515cb1116535f37f0a8dcf712983e49085d198016b884866ebc80c8db0674b0ac92028ee945090cc1f654e6129c545d941fe6a8ee6584c0ef9dcef6e643a52f644a5a87f5e2a3c62935be7c7f6fd279bbbf014f6689ca12cdf6e61eb681cf23f7059f569aeddf3e5038abc20537b89e2f1b2e0d570c796c9957f4470e9987c7c9e3c99410e3572670943280725a52698b80e59b858810e6570e14206113740ea9a7af0a56ba21b6b7ead62e3f772b550c99cded5704fa7762aa778dfd9b861828b80fe958b4e021977bc2e216efb448d3c99c5832ed1f83805857b628855e1fe48c7a0061ff464c97da59d4347369d944c22b04071d1c621f16b5fbf1d3cea6fdf199172d2efefd1dda9f614ef6f9abe398c59f0965b9c43821a27778af7d5fb1b87791a0bde72178e8673644a66b82f7145d82cc445224dc45f441a6663ab4b46d074d9affffdd51888ffa4df16b77f7475d760d60f2c5d676cc963cb68240e77043d2093fddcae4f709470d597ff4566e3e607775432c7895d3caa914a2b0c6017f08b2bbf7357adebaf05c7aeb1a9a9c9662533f787808a1b07e36c13a75d134fb97198fd66c15b92ba701ae7d428ba9fc9c8411e7b66236e3cfc408a8cedc8d87c1bc858b2c1e7cb131ea4e0c90c9ae4a0b4440e1e10128a128573373a1d21b928dffd64c4bd6f27a3bcbdfc93d13c21f9ab57f7e61a1e3851ac3ffe92f9645481b2f82fb8f373154b1c653177154a70c9dd746510723f4f6e3ccafa93b7bfe1c31d6b510f1032d7a571c83fc9fc257f6a11027a8b5cdfd5699f820ddbef480187bb11350ef9dbd78f070899b3df0384cc613a6b1cf27980902ddef0d83f8f54a0194e39fde974e42df936bb4e462ecaaf27a36a548bc014d295a3a32e88f2d8327a44a783253f9b9ede869b9c271bb612cf1ad66a38cec72c67f9d31a4d7c07a62c2d3d19e30915b3289dc50b1744912f316bbecc3ef8e0031f00f5d3e789b11ab35cf88977aa341e329f62567fc7b4df995f31abf194ed3b569f27e60e86357aa2e4c6ed35f06f411f21cd6f877c723366b9e03150de1cc5fd8cb4427a92822d4b67702183337abe10bd904964c2b6777db9a30d796276c23cc0130b7962da6f3f44fb0def5499bfd3b3d53d4a3f79bcdd973b8ad37d0b2b42686c62d614ca13f31f45e7019c2dd1cb0c59f63f121319e4e0458b1c668e9b8005ed1d243d3d237d0bf0e4ed6dbfd6daa6d5efa161ed6787ef9273b595cd2150b8c1fd221bcaf5dff1578e8f09b3f782e08b3e84526c87d4a75f3b771ffe37c74693dbd856213066a9f67e5072325e26294dc0a2bb3b4362d1a37d008c2cf2d848dd1952be7cf9a251eb6a212cf8984d6a50c592a963719136d5e939b68c05a3bbba77f6c3c2e96f6ca4041b773f29a5b47fa3dbcfee42d126bce170cde9bbb79ba6f3f45ca8d3a390dc1570e551483642bff11157b6989b78a41cd6347cc312057fee087a9eec6230f3b94e3c27f36b64b85a7ffd5abf7e1657e66a84cfeca6e71f8ffa40da48bfffb4daf7d870bbb8f1e4da93be4825172ea2e4b1919c5425bcca4a5d2db5d780747f15e3cb161a91fd833ef73de8733377e778879a36e5f4ab7bda68d65cef140922222f8a17c584d9fd5c57b7913ceaeeeef3c760b2fdd4ec9cdfa3f3c4f3ebf63e85fb1a87712fffb9964dfa3dc796798da3fb79290499621a70a6e5804b3f0b8864cda72f99ae07ca687abcb93d6044248692093aa09e7780fbd0c87ccd5b9efe5f14ff6598e343883bd2d038c7854ae68fef3620fdfed46bc8828b32a439359ab80f860a5637cbaa0319479f8b4c189d2fbd115c5aa382cb922c896bf4dcf7624a763cdedc8fe38de08e384b4552a46cd92dbb3b8f0cc860205da02c652eca1416b07148f93d6606677bd848724569569ab66d9bb51c783a79377c30f2408fe6fb746489936ff470c7f752d2fdc8a9bbf1ed492165f9b767c2524b28c81f53b3942cf75f204e082b30f25d3fdaee777588d37f435fee9487ae5b1626a13e3beccf917147dcb191840cf197b74a923ec45f49641e2d1128d406180f15b04513173bfbdf19e40a4850038d2b6af862a93ba3c9eabe0e9bec230d0f77b44c50b2801283834f6a87181c7cbe7ca9a1434abdbafbd71c7f1f5cafa768300dcba68c070f74f1622df779c8578288586eb2f428a5476eb2fc19d4704304355001e4e960421732318a9051990e17045f74b516af76eed9645a6badf5ce70e7538aad50a103a5ff1a563740f0178c1df2e8caf261d46ff7954258b0d09653e69730dfc7c7d6e656fbbc20c9dd4958c1d5e19a38603c917d0736d9cb52d248ef59ea760d2ce5fa1d9a50451fa940d9ff79f01a4871450e4053cc40ca144f40d11804b7afd875e3a2cb4529494042c725c11d6d3b095e60d4dddd2d739c0342122a043adcd1cad972b69c2d67cbd97e97727006d18dcbc58b83e3a274c9581734e4f177808124a51402018a3b4aa1217ff5500266cc761ee3863c4a2026222a5e0959b4cd2269c9070c21264a59284def9f3df7730f94f278ffe80b0846e9c205445166abc6cffd2f50d0c417b3268cb2007fb823c884c90b2a84a22c315d0165aadc597af0441e9f0a298edc7ba28154775d9d1445ff1918dc51fe94b155bd52a4ccb193e88f1dc41d6dfd765897f3f8b2cb04f7cba3abc6d539beec7f2306a1bda8844e1475450c15a21900000000f313002030100c8643229150382215cbab7d1400098d9e4086501648b320c96118849031c41800000140001991119a992608973f31f399d7afd1177f736610b44c9dac9fc2fef589614e9146bd6cccad9e2dda689b3d12a949783cc042495026bfe114031899ac033f8c497e3270f8454604da32586981da396319c8043120108a12a6939ce3b16518bce02f4e107c67fea8beee22b260a52e37f0a05d90605d459c2e031d36fbb32e2bdc2d3cc053e924b0cf7bb81c9d1319d83d42087d117f3033540a32eccd702d426f28bb28efe290899c3e4f5c75f7c10d1d2ba4721c83214720051993b6cb52c363e92924306a7d727cac8c70281224639d09550d851bd07d0274f579c117640b60dbbf05349cdcd87d71f3c080a24cbcf8049a24ee3112900e88048f77ca100515fcad10f7b9ca1b789b2f3cd0840add371af23150feaf52576bb23177059762fd521f6cadcf628f41777f375394c0e27b592a68f9f7b04c431717c144971aefc879a2b69955324d0ce1c1c5c53d43fa7c03acc3d93c7280382dde9cff116fadff723507452044a42f825026eb8d5dc037a75fa6f366081138e717053dbf1ab13a4b39abd33bb9a829802683f58efab217ea0536f1c6c4f0c1affc537e1f1613c870fd805751e98790e80432deee0c323c3aaa3219ea12fe5fe4575650516bee442273a2b31905b463d1164b482ff8e6aea13bedf2b2d6045190030217ea964bb0f3c74f5642c9567e08228613d6920b3dae5090ea90cbbfae601b0bf9b3f28d5eb2a1e72ea83304f4ec6194a252f3da2baa2d82e4b04000a9a77c500a62d1d35b15a5e781aa6357290a02b31c703a59a2cac0b8ec888117124b92eb8754ff6cb3bffac2a58a4a4094e5b481db23ecb86769566422e1c784f6ac056b621002226664681268ea41fd19326e7070d5febce3652b67c6c7f1e2e70bccc68a24178870f4f829023e47884fc56e653ed20c3502fcbbd44d553a82421f46eff0da03178265a34a4bcca71be167060427a1ae806b46d845dc825bb2d2894f659f4ea926099dd26e57404f82c9332bdebca30e6c9cc65d770cd88171658e1a9745934b4b37b0638719bd43af362b228564e5e768e4432e0b88a6c2d0cf29ec0908b94aa20261d1879f2352e3ae927bc70d72061a7b5b9dca1425a3e6ad68a31df72e31f5a4f1b2ed1345ab398796b0a84153275f02ced716b37d06693eae93a0d41312ae044ca00787bd7dacc2166ee83ed0f3cc27a16415f07fe52d427ee78eed95594d2b8bf75e9fcfe150e36605d9bc2bbfd59bd737fe022ecd7107abe70ad44ecc3c0f77736ce84d30a50530121f877110dc8a3206706d38bd69660a0eebad91312a1a4c8f7d986d2641a8d0c81644931378aa4aaead1aee80e44a21bb31262a46c00d218422b02d1066e21a91e85219449e8352121e1346e1fb6e2f3c5c00527ba9f63c8a529c75d8dea9ef6b0583692b0e1c641f138507cda24e0fad80b88cb3e76752ce0ef620e1485f23deee88ed8b302e6ad53d34258094ea08b0303fc09b55315632e54993fe35767376a510d1514b3ed253994bdbba53decd876169372f2e543cc871030711285a74dd3070bd440e6c05fa03842216add6a4d6a9e84900f000c709473b11f98bdbc6ded3c1a43abc3c6f049a3311019d351d8943a57ee27f4e123b76497e6850c3780c829e5490315980074531a6350120d6a7b6b6b00e8d45bae72c570089f95b01df7ec64e1b9aad9af5d54b74919a93a6bbe7896802d26519fc00ab9f57f174dfda0fe31f0380bce32bc94635c90b666d1bf4b1698127442847dc4dd57028529e12b63df80e35b8c53e6f5446177616b17e4c7a112514cb955fcacebe7c03b441efe44994bd0f6fd096a3bdc0a0ab4e94647c5a79d57aad6bc95ca425c8fcfbf9222e7a74c281e9557d442986312b7245deec90c1df9aabd5b6c3b51ae89e8995e37d94fddeca22e413854a4cd9441285b70ee3942962b18a769fd746bc137b29b24afa1994abab7c1359ef3600853cfc8c0609d57ce270a9810595248cdb7761cd7ce0dad78a7ed9f827b2f53c4de994a4b12ec5e46bd86ef6bb9a58c033d9c7d040c24b951b9bdfda37f329a3c69980ce1850f04cc600ccaa51808009f09cfca768c2b451be50b3a07c2f57d2d44494c6eeef4d9ea083afc5d8bf38a1d43d5fc53fa8b29ef19ea3086c8ed10fd82023b18f7b04962bb5b14cca40d320f739975b172a982030e19521c722b5b3f8fa06d1965bd55dbc3ab03e3f819d4dcb6dd360ec10e675812085c6316473f93ebf5281952ab6d49c34608e5dd430678d6f98df47d0ada531722a996d18c27114a7f7522220996b549cc8c4db5801b90cdbfc640ac4f75aa71c7527f120ca65baf25310152b672ae7446bde25471aecc0a79c4591c00f44d6b9bb32e53c294e3346614899bb55ebf2ae0d4402a830529158ab31fbee580236e9a0ffa20e7a4328cf0aed3fa0f9b55f97bf357a0b0fac238e098858112d1de994e27e41320d4400a09bde1ff59c8aad08e51baf1d607b9665c43ee125b668a5fa612007bc048a5affbc64cdf118d4f5b608bd12204f4fb48bfed47b3bf47c9413eb6f5d4309ab6daad3acfed9f99d8328629434fcaf7c9feb9e232ea0833e0aac78e9dd8f85dc3cfc9781f65f517ae247a4a43150ac3711ed9be7c1dc0f888a5971e5c4881a88a05921aef3470b48444f9fe0d70e1270e7fea98ce217ac4680e89fe91c864534cd30a0a08858cb4da4d18a81a23590bbf52595acb6a739d5a5b6a6b109d202c8cad68c07852bdb9615175fb80b80cc41970a069db8adf5bf1c5b81724cd33b82de62d9d7843c0574d4e9cc1e35d5da0ae79d21f176f50ae3e4dc868c5338ab9a00649c17a8dd50daf7646ccd142e123302457b78c85964129772288b67f5ea6881c59868785e24cd7e2da54d35a007edf48cb17a7b405f732b5728d647600da92bbd1c6ea289d65ec5c670ac933981970ba16f79ab5f3a0ad55666338e82ca5f80ee09445a3282510ee20c906761291f7add6f8d69a4c34d407cce462d8e3429204c2917a642860c9c34631fa209396a8bb4d192d00fa4166fec8b6b069848a8cb451b09f6672c637d26156716755ba22b89b33a2b8dcc2a55d6259aede558d306c81e75ea95d87d9692ea567bc6177767bddf629989af979910f35201fcda8345ad03b74fa931b521981e770d66811c68c1de9611ca809c4117d0873d105bf4c5a842cb691904ea58a469d8e97b09ef000e243dc78a4ae6829d8c753996f4fe5a310d218a53897be3cc2801d8500c1c1762516b87062acebd23c683729df6c773a8498dfc9241a04f53860b47d416b535c6fcba4404f772506fab89032e6b692be7fba05aad9cf0b784c60cc6cdf94112e1dea024c2d7699e5e6e252a394a307fb98fbae66b89a504ba024f647f43b6c37980654429f6aff33179c06f1963d0e09b8e5a2277c964c4ca791fa516f562bf06da4830114d1616fdfd4e5ce9257d5d5c9f8fbc930922cc8b9b86fd13acf04905362bd5ccb590f058eaf7fc250a81d82003621b4470f6c4b6370488481e6238093395bf465acdf3431133c514bc2f0a769cf92529fb0ca5de868ee3b0678e22922454b172e1ec5c76c528fe802e7908945773219b328e6251982116b41f72042be8e581f8a6536c50d4f934b40d01a13b118ea7fcde3cd52ee80b442b1542d96fb67574f4049ebb3595906856eab2450287e3400a12f2b8fdbbf26bfc4e700b19ec67ce357c2a3d0bcb513c4e9e03883b43fbf1eb96c78aedf5512d70e3fc4cea45519bc37577fff8f439de72814156c3839fc37b3f7242d7ea50a9e7ef799396631dff0948ad2ece2b764168f5ee3f16eecba0e61af09ef9bac64601667fd5ef6fdd7fbc0226b825d10aef7dfe9034aac7d443ce77d18d188280debe035f0fcc190440e2bd32dedb93e4878806ab707601765c870161e66ceaf25f7aa25b0ac9aab38ff191581b2bcf8bd34f3cad6a4661e1b9c4b9110aa53fb7ed12c2f040672bc6e0a76adbd01a8883c9b63de5a22ebf566f8888a852be7bec2ed50887d5208869b3182ae291ebd374b19d2e44da8488246c256871438ea54ed450fe62c39d8f92afbb0a9b79d57f82862691b5aa23525d8aa5c02406bbd8f6cd1d2947267dd01b1188e81265baf2a3376881f7403632976db1f87d5ff127d34d3dff046b62117048e35030900a6648a107eca027f1962e76f03fb9332778b4859e2d7fd763d84dbd9b43d9bccdb720902f69525e36283819ec4ab50be0c853e801159e59d3617c40e7a6f8c01a8867bff93180f65f7cedfe1d7c3e2b3b451cf7012f886b170896bdcdd1b8ac8ff95d308b318989d0baf0da22343b04253fc3e37f262594d7ef7e941713494c0cc1d9844267c46a92697d9c9b47ef637cd85b423ced047644b81fee61cc5d220b88761cda20a0a859eee6f938b40222ca962c30a83f9256d4d0e6afe98da0a80658f6dd470acd0356d53ff1eb6613803ba53124e184c520ffc883b7d96d71db9b01e76b9846ff41539151220c0b123fa23932012b9627c424ed5e04ca148b4a2070f28c50a4132d00e9e06d89441aed8640c5832f67b74d7ec4f1a8ca34160a3f4db68b8d5cd9aab32e802b4e22c9594ad55bd102a07e25dca11b1f3052193c5a80c6f482e5d9128ee11ab92ca17b308b04e186930c375f7a35cf61cb3dd6cce9a3735351fe15fe5b7526573e00a35c7137fe11f076007f2c1c5a186117a6b9d35cc062b08a753f3ba1179af1344a97621c47f9b5da00b2f562b0dfefa157c2ee0843f891c3b788e624dc92d6d0db34c1cb58e2c453c6438d68c8c630515840a453082b283d5c315172608077427e2028f7fa9917259206d992d4ff5400aa634fa75302ff0354a81301be53c10a5a25630fbe42701b43d758eab9df8ab41720b64f2b723e0b5515d1f1a3fb59e6e31ecd671eff90d74fecb54d1bc2c9ec81f1f8669228de5855810f920e7a5185769bcb5bf5a180706aed8a6894a4b94abe6c2a9f32090658d2ebe035088957e50f26d29f3abb24b67a9eb9d5cba49958dd79a014076f7867e4eccdc5d108c98a5f2079b855ed4fbf8074b252af1bba71047d9c5ed55ab82fa571ffeae144815518464f404d44f50480eee8bf50e84d3f5a008f3eca0b1be179b139bcae52ff43121e4d72fc24b12fff08d95be6615744cd73219098b3367632bb942a321479c819ad06dbcd208398ecb96c113e18022c1f9b0f67f2318e7619a551b2a0d7eacf8e2e292a4f40ce82405ce6e76b55af4535ace95939e4c332d452a064a29c90a3b126bbaed214934208aad343e5fac06894de47809006656edab29792a843b2c4af89ffaec58403506b57d525d26b78a0b4447230dbf0bca2f7d680f19f5061768eeee1d204c861778a3125815426d360a8502ee649e7ada94a71376686cf3404a4b89175ec02fa8848fc3fcc19c5a29b3ecc8560c207c13f3941749a8a4a62e3a935ec1bbbb1f6c41d00fbd37bdb80d861f468e78a05e08328c1585a3625fbb5c0b88ede9a2ae0ed8a042694b5e451d938440a12839e381bdc8d3ba015569f420416d4dfe9554c56c167c4f3d11a0040389b67229ce416da8f117b1b43278d1cc306011fe8faf7ce385150a2daee21047d94fb6de5042a62f56667bf6c7d936c7c133bb5b6c1b61ab2c08176271f395fdd2fc09ef93888c2d6cb2d9cb096e7ebb8dd9e499bee7baccc74711cc15e6ded023ccfa8e530c8652e2d7a98e148f8e8c0adf629c4558f842ac07b122d1e731d9317a068a1f3333b2bb356de457b3243229e468adc169610fc1fcc1a6cd8f0f8dff47b3b307871041b39ddb068811e4e0f217f565680d7069bb430fe5eb0e0e67fb17c306bac70386c9b5ff51309b1041fad634a098f9e9aa33c64815ca43114e21d306e4a7b3daf9b6273c4689b58507ecd21c3c1a16d849a8eb04e6f4056375697c8aa0dff3d26b88e4aaeceec56f9cb9a0942f0ac222dab143cb91a56840de0e5b1886489b5c17ccb62083aa17069d953afc3050e9ef4e87e5c908c4dccc2f8c37541d908d532b5bdce095e32c870184e317031a4386f4dcfe8c2f43ccee34106170cb8ad0e6900ccee55734f669a2cb6b9b5aa739e36e4311d1af630298829f23857075701a8699e751c1a610a6bab69f5819cacaa56375224d1ab67d7f2f1a917ce510a92012a041791495cddd1e7f9e6c6efd8f7b1a81213fca253bd03064707a44a4a206fd4eb34c028dbfc14155c614bde9dc3c5f8dfe3588881068ed97cb39e97b38308e1138f65d616301cd5fbf053bafa17440a7829279ca127b666c227ad69336cdfae1015dd7c9756e10af4bcae165b52b784b8e3c217fdf600738ebf0a02d694bceeb0b4879f8d81907e114ddbcb37cf6275e742bd8700e31c4de05e920a2ba18e90e350ebb6e12905504ab17e8d3e5a1df9d0de52d0e590d9d3ed3d4e0e364ad213bd2a4c618144e5e0ac83684cb23321c93feae26d1236b28603e46f20fa370736e8f7852805c19ef31c4ee44fde53ec03b5c404c7fec220cfc7e266581a61f7f504de2ff32df6a6ca274df78531976479c2b36f803405468aacc2dcdc902531fb0bbed69d656db2a532209dbb55256017dcba36e76c6233511776f815808d4b94bc8b8f1d6622314a06d39943b535b1e6e635b1c33bcc42272de7c548abc113ee46cb1ca10c3d4510ea6887d7134297d51c667d087d5e215ed10d4679d060e79a81b14fce999165589030fb3074c89e89cdb072d34ed2f1d0fa5df95669a7aed194ba255240266f3fd63e01705b19fdcae01ae241390e2c0951b0b1fd1adc4ce79ad1ef69890754eb7ea391d691d880eec3a7c1c4c087feb7653107bcf4a495a809460ebb100a9ed05af4c430c0755047627d4ec85188b80c5d318a52581b45375b6e001fe8daaaf3002fe60c97356042761b576dfe0d81a7163671010c9781acb3a7b9ea9427d7b12c558eb4d58cc619142202ac776d81ab401c15bebe1657e059dd0e7f5c6b249722270a7397cefcb8f010406a1eaacf849e2c4ca162db1ff3c088a05eb925ab8115ec38e119ba2e00ef34e77cad7918c611a145b3843543d1597bde7b25242653b4cf18fbabdb5e119642e7f0c81e15ff83f3ad78cc21bcfafc486f46cdc44b6d66f37568580f44a24fd55659a04d7451164708647c6f4686e79095b9f954293fc619b5c683de549de51a231e9d4a530d66aeb192d36246603954ae8b30019b50c683c2bbdd32374ac1932a468e9c8f0c3eee25d0c4adcc9748f9c56403c3c60547bd91a9d455306ea59114cd98514e8100360392720d1884a9d77448b21cef2c85e44c0721dedf4f41161afe5e9b2cb94bc760659e05739c6d212ea4542638596c686588be5612ff7d69915824392d3b01399fe93dcb97fea012b0aaa04b00a4a253c5bb2ffbc741f9d28a79236de0edffc045edb93387078ac77e0a7be936b64fe440527f7c97bda9c0b3c6d09578059553cc3196b09b3d1b30469c4b3eabfa1172f2c34d7338e837faa0e70b6e72bd70568f8a3bec615fd7aa553ff083d47555a40485746d7b5e3ea5c1a7e7da04eb9150c19b7a6903b7e095b00ed83a2b947c5ec02f08ca24d53a7088d87b13f9af97466e2d50b53d26c515387a8a7c852968d4ffd486199297486ec6e6185cef24e52ab4c2ad44a65f4db7971e733c262ebbcd10de25288504e121d7be2f3a5406ecbb56336be878e40e8e49e55391d8edacb325297f73529456d74cf99b416f87a1f92fab82c4536634daa1aa7a08702082e4681939af4428bbcdea84309e3f88dd02562e16d249fc49fbff267181f4f6d8053c579c5897065decce608f146327eb7427074184553176b5dc352e51d0027b36938a356b0324e4ae184e61d85338cda3c77165183ba72a0f66050bead6df3d2f7c5e0d3cd212bef7b3f24054341d2f74641a464e446746ef47f48d31e70cc427e6b69e37dafd000dfa4045fefcf23e1e7c6ba875ff70519ec1d70830a07d943089d414df54611182c35791ca236961b4eb5e52a3b17fb5c96b9fed07b2fcf3cd78e96139399b096d1f16ad2c71957645b0e94e8d9b87182f16c7f927534e70105338a521427486d0b25f251e5796607a0172e91a5196bf3c44274e20d5bf4226b54e5ba4b6c4e30d7062d27fb9baa4f432857ec1a490e84ad36f75caf8cdf7f0c81f394732e6935126f955c9de3cd86f2619a938aed2b42325dca63b8a38b702d3cfd768117b2c2a6300c437777558b0873f5799673404aefc503de01afaadfc9dfd87645bef7990381c6b545b7d236c43580a21680895822628db0e4229c2c922a2b613508e7414f3770e693435b253fcc4b3e14a76d13fe97d062edfd138449598a6949b88b414f391218417ca12ce42d730c6fb61a0088945b12039686c8eaeefe810e98685cf89b59aec5983b9c3b717589d1ab54b4787a1291c6435f07ec769501bda72d588b93f6c2507e5d88b280944d8fe5fdf0b1cf1943113c058416e72dd7764a35666ac96c7ec7f6578bf7c78a0091bc37d4d12c3d9dd36bfc38dfbdefdc4e3577ea8aa08a22519c5eb4ef674fecd2be50843ff4bd421a592c9e978400e39ac34b724a3644c4c39ce14b6cee209f14e45299fb0bdd29c0ff7a24b6d7579ad2104818973d27a5fcc9c708d1e62b37fc0f26d7772645618c2454b300eff86fb8e709f4f331ca69d186ef3d2ce025d2ba6075897ed74799a219d41a3d610ccdcb42043b37fdbe424103c66237490c57e851816bfbf1502e63c2113f401305b924c88f328eb28abd4bc33eb83c5975367167110c83544915124895a4f888709854156606b36d42418840c2a69f7159d0b40d7edee30bf49f10fdee62062e8586d7a133305359b15f1063cf98e0701e14cce0ef0535ce556161ba5ca68d4e51cc4fd0f441926843ab9ce5937377da89c4bb90650e2835211dfa8ecbef5b397f312eac18353106d4a2e6092e8a131685026f4d295f1a0ef219e00bb9e85f6246e34d0266f8df35ba7d3c80c55a3172b1949638a0c7500d6c3a6d6b08d23e11fb81b551fc69a24498f8c18ea17e9bd91c8a1ca26235e94c11681b54dda7358c14e48af74af447bcef11adca939755ba9ce6047878af72b77884fe3dd670af8ceb8fc0182ad6bd3c424d797967c26477cd2898ee67ffb174ed475c84819e83b5e0f3d514932bf67eeb85f7fe2359d6cb213c37a71274eb770af392b16359170e82717ba328f2e225c0df246ac4ce1c25ce792a0a29d908d6a4116c240e78f35c3903fb71688b64f68cc27d976a37954fd2ce91febeb0780f376fa85437a0993a4698ea448404422935fff5f84a339c9455bb02d3c7b43d69889ed9cd82df29305466ef6dade3663fa957b0ff071baec0910f678ef338090472c3002687cf22ab5aaede5268926145f8843bc2da89559822cf988edc8cf9463770293d618d9f95708b0c64873ab69441b835688bbba822e6ea8c3d99a7035a7e57cee8a9c132da0871544b5af5b16390ad8484356eac2dd2c3288abdc5adcc4d24dc0f5a8b504c57a01a4ebaad8ab0c1ce4e16c5f64a5010f31b5f915a41e8a0f065031ee2af75de130f9423553c7ee482273c3c14187fecf0590342976daa522b6c60158a737093754917a0ab56beed57112533152a7cb757fd67ed62c011569c584a4f72282a13a4a04e7e94010b1acfa167ca8ec859da271a96653c53044dbe65238b7f6fdca4df5fbc798d0c076e86542bc46a5db7522e8274523afc29689d48f1161a7d7b7345561aaf6863f6416acde2c3859690b70c45445e93e3d54efb74768533af2821af1df05c63620b07bec492cca29d7d5aabce008c777b8545038302a65cbf09d9985201a73c4966540a4aebf7c6dcacfa89611cdbd8dcb0966ea9d30b03e2f486dc59be198bee293f8a6361a51ee3fcdd4855fc462e25263ea61d623e5fe544617c12604e757f48318b954880b9e29440967dc85c40824550cfd739a463b1d75ac24ef4a8a4d898834cab4a03c2074d5e4e9d116da1672482a92e9a3606f240f73efbd58f909ca2cee76ed09c7a062fa81de24cf61ab38a632cdb48c9e00e843df25c9203af2cb417aa1bd0e95b7303e4d0ea96778484dcc070abc230a6369223954c20d10188ff367568650665f0ec2749b2584993cccf14d6ba8b6550268d46d9a95fa72c791a928904bd018ce27745d4c397ae4231b2d691f3df526b72b8103310428202816b7d5a63072fbdd0452cbe17d1985db5cc2de2e869da7d06e16a208ac34c616a4589487676e7ddf71fc54e28f0e2b9f2200ca889adcf2211d1407c4e1b8159ecf1f32d4e50bdc923ee5dbfbc91385c778e93d83ad4896163e5b9844a54757101f15ab2403648d22651a40a2cd9b26ed1b30b07214c03a99aed0f117f01838464520f4de57f37be852d210db4b83c13098b8f73a67f9c6c14099209b11ce2e30f2281c89d5df1053428a97784cfe4d59f15d34387407e68f84c36955b6e4c28a44fca6f07060b97f74c37b3e36a0b80fb5b921e84d860aaacf347663d588328a1def31f2dc94f4d08328b7beb096da2d78b112f7b3699401e94406f880abb7ddb00124ad3f54d6ce5e8d3dac7bb732f6bc114295fc56493fbd35c2404b045a14dbc7da441dbe5cb9dc8bedc44653d6ac6728fe80e8e98f99003cc384a57c2c1ac1e573ffe8ebf7d589dd77575c47f363d485198682e274bd468c0186ccb4e3c2d6e297f7a2857bf55aa3e846e146c5348f84e5a4cd490d2e0a09bfb829a746ecb3fcdf6e86678cb14e8d2ffa39736709765ee65f9f75c90a6b33558003b50549a9db7a9e7b02f6225e683c297d3cceabfe4ec2af0a5b4fc826130c847c8aab55572cf11fd7afd786046a871e32bd42b864b76286da6bd454d9bdb7ee84af7f39850228d3953e17821ac5720a8810d799042535bebbe763bf706954696af8bc77bce571c2414c0ad3a62b27fd59685f429e509ba9acd360dfc5657d01cb2b3989a304a16977f4ddcf96aaf12521c904754199231bc0b42acccb88eaa0d8b04ec9e6c49838e39ab93f36673a96fb4897cc90f0ba74ff5fb5ed55db247f346e61fefd982ac32103e6fc86887787603f542085e93c083704e2bc0982301e65e6120d347b0e4da19656778895be4d2b36a44cfa940abe70cb43691a6beb33512c6152c1ba5d912168a0c1d5599b2d06178f5ba6e6b7b01721598c4f94e6ec4a4ccf6b5e2603cb2106cb73819d084ab6d9817b1c11888a5d310e8e658d68489c1efd42b3afbafc379eae812cdcabf51629457f691011331a2930c3defb608ddbea2a3b0c7d56b0ecaa1998c26f67f18aae477d368867f0c40ad85c9dba023c8d262203955d606d38d2af62159acee5a8f579dd617c08a003a142838305e91157ce962051b8d10bb13221d69f4445d0afa6a5e4a482a132748982ca9626d3e9d16bb5f7d2e07a0d416ddb2b42c56ed405b526776277d31cd0919c6289d8a351abb04eea2d5a22203ff0959e82c60bffd51362129023aa883d7ac959ea6cc4ed2601629f2460b73a7d6661f2ea722e3a48893c7ec8709d97a90b1a0cfd42f51daca500e3ceedf19b1cb87c646953531149e781378a81d60f2cff01cedc95ff0215afdf940e4fc038b05297f1c14c9423bfeb06d80f9089bc0e43104540516e51f21cf799a1f71d615bf90dfaf895b6846388bc9b5506343fb2de1b5e0cd0c90c82a05c5f4f8875364a3cc249c83864f9708c283fdac413b91b00605ce8da06eaeda981b37f5a4209c4d8bd0291a9dc005840f28548f243d82b1201bb46feea2cd23a8520f66b205ba864848fb24ed7f22d648f29947393379387ffb34ce9d11399c170072b4ad288e6c3540c5b80a8b11312f384633f190ac158a7aef65a7124a959260db9ff0f1ceb30007b89e58ce0faac3008ec9476a331d8f945fd54d243784e7c0a915ec5c6f3acefa80d96cb87d05a78dd6813dd7c20fd19a680340c38aa3f1f65df495331a1638421557e1966472bce569993e3ad7d9cd6350ac146ad923eaf26983644968b7215e1dab99a03f4cbfc186f09fa60c5240a2e4a7cef4430017c9481ea26289b089f3cd6ca06a926ea2ccec756e3d11044b5f47a9586052eec4c3441d79bedc1f42bd1c49705769e4c53883f8614065c4f170d61c04181f38ceb2e97e334c92684895c815647a5889cc1aa19d3480765fb6b809036b7f236e24acf959e577a5ee9bdd2eb4a8f2b3d577a5fe979a5e74a7a5e1f7a386d6d718159038267ac6ab5dc18633bcfafc3e9181f840606337ac2fcd1cc06a9ef04a80ef59ff84f841e575ee099537049531d442ea54f0a9e75ce6d87dd2cd9fed4eb2909a403020b7b1a2fd15433fec110cb5a0e4168942aa636d3a0d16a2fb7c22c28c0a615d2e2b25143bcb14df79f4c58fc04b3f3e07214baa8d2f59de2a08fae8cfd81203e1f6ebbddf0c00ad7c96c8f6db0562ce246f558ad0e778bdc18ac75abc3dde2c660acb0a0b72bb271bf99b6d8f0670595beb925883b4bba81de556b979bb5ee2608c9fd65da3636fc58ac2e779b1b854ed956bc1381ecabcb137fb4d316baf243b362e35c64108bd16aecfef00b4029fc9d01f85e11d26781517fffd79de89b0496cb8cadaa36a16341533e035e97d04a4e635c5404ca971c5286091a9b8b97f4f834248930b9ab388a3600e0d4b4fa65d0278bc6a96bcd071352c071be8cb51683453bbd48c364e8a57c2fd679ad708d191ed0b17205f8c9a34052b7180761c155e6ac7f0ed2d29efbb27c5ff0df2e48c91d519c85f8e17bbd6b1698644ff2e210ac37bae4e0fecc1268136011307e7b68da2a42947954a843e69e5585e986ce85902c0a24709b289aa815516f5e8cc84eb338f390239e12c0be03a6002b27c0d345240217a92b32145012d1e538a2a4de72ccf50da0e64446cb5431428ef24cc0a02a2029638f04feea44cbf8212b62e0f772aa18f7d108dcc49099112dcf9a05a1a4d713afd77618755a87ba84ceaff15f8a64d2badf750e66b9018eeb45040905e4ce65553a42b8c73902520b607639e0618f842a9f77107465a8449530b7471a87feda3e10fcbf32c836fc28f8aa8a8d69b0c574b8c7acf8a9eeafc80f320260292d7bc0ce86b9ec81fbf537e93dfa513deb06a6f73b057735792353575a15fbeda7e4fe01ccaf107c4af6cae8645c7356a85d36b557ba317cb6359e50f76389117240fb696e7ca8c411038dc3149ff0532904e5853655deab8a3edc289463506ae0a3f99d68ad2f11d45dd0676e5ae9004499a980f04080e73cc93fe7f814c45033ad5192e7f1f25bf8278640389e7da261a683b2be03d32dad0a4ae6a0549649a8cec7b02c80ea16930842e0c167c9740a4b82a168c0bb6a6e27a9bcbc3a514edb7fe799fe9f95d033d466c54674fa0ce92702b2fbd86a2e3607948557b061cea3dc8ae75e98f2b2d5679c1083ce8278f1a343c799f7c8ba2fe1c7170818c88503cceb988f3217c968f7361f6d669e4b4a1b0af29995f6638db0283f81a91e3126178d32f2a318cb1b53dfc3da335744d471c27e4fb05fc35ab70f3ca5efa08f09e6335da4d8ba4d30f26379e2e47072515c3863a4632df4f8412d2441ac82c05a71cb2b9a09a03ecac9b07a5cc448735a934e86652b2136c73f61c8874d236952c5b28a9e1b3355a4f8c15ebc99dab1ca62b49f886dcf1e002c8c1eeb9caff07ef65642fe1f0a5bda422b5d1c35ae002b1d5efa12345c157a681ae758f5a4f3c87106946bb4e46bba353ad7c448de02d821d27910d214bbc9eb7316c926415760078899f1ed3bf4c703c5a53dc3e6e008f97fe9169d05fae3830e80832222152919d387f692ef7e0588e5c62266c0078d431867fd9951710b0caea668dc33a4174cc915eca79d0f965a9d3cdbe88e510b0670a1039c2a24514a50f00b0d25e51df134ef7046a0fcf4075fd32f3f7309b930739212ae6bc2505125a5f6286c8fe7990f6c29b605d435eba46984cdf213502d0a070d14f0aa68761625604aef788edce95add0aae7ae120d5be1dcbd77dae86e6ffcf52328b58f50cd0f464004821644c91a7e4638ca9d5cb1a3971534575bf0b99582305d8a9046f2200cca10ce14777ebe60362c62e0a65e0617fc25c0681bfa9a0e2a1f13fb521cf6ae3463be2d023e0720305a42712e53ecb3d45506bf6498d3e4a4874e6b612d83161af87dcd66929ee7886997f8233843e4048b707450c6c1656a24ef24cdb12704680c06c8d5628516c036d26baad78a36713d003531b36b998dc78125554c9990a472ca7139d4bad352468bcc0927fd0871cbba9cd6a977aa16325a364d1ed59c25b8e2afb45911ef663cc78cfe2856239bfb485a839de4724451a8e3a9394d78daeea1a9306d2c251eab473cd4c0bba8c884da352bb7b061c192f74c527b1a17bb88711b7256a1aa79ab699694b135563786dd8020206d4b244d5b155e8c15234a7f544346055b943024356d4634eb7b4feec613f7e6d9d2c1a1189a943aa251191734d91c98e888427a57d077fd6e1e5c3a83baf7ffba375fa6a9247f015bc16477e42244d43c07611476dd05bb3fb3f3ed98ceba6a17e07e9bdf845e552d8a631ab48536060cb7dd48280812d33a0b46051b06507d656186220191aa75a91aec2d2171d442ee48c4cf5e72bf524b96997e64bbef5adb6e9d44683d580448782d2cc61540e800187993e99ef48f4fa756f111b3292865e1e01a32d5ef862064a9c571a16df3fc67d7c562b51532a03bb67390923a364ec92c8b6c2d04b940c07097feead2e8271eb2cd313ee7c581d5ea493881e7dbb899e371abf405c10242bb242721b945a1abe3041617937f7d78e1a27de81ae46ea3dff4b446afefa41e835cd2fcf8138f6c64983c031f5bb7fab077da8343c005859c234c88f77cd8c250726bdc77bf24ff5849e79702103093905bddf36e44a3c349028865dd50aad4aa61bebed8fb23160a34b567cde7687009ceb067db719723d4975698fdd637d74ffb0323aa2b9dfd2e76fef9c7f9a392b14474e12d922e66cbc230f31f038072d01e856cec0b08b0c401208564e24c46c39524e9de39d18fcbbdafde5ec6a9ba3b98bec8e147bc25f22cbd508483ceb8a58c8340193328e51195471e57a0d5717993ce8137b4270f974a3306188fe86ce26aef57d2c6569c21c6a8c9e91e5ad8572a1081000f764bedd877e49def87c1149c7d49df0ac614270e808a2de337c995d6a346057cee0505d47fd4829f6691b91646f7b21f1b3704aef3667222462c8469b424064d1c627ff6f2eb5fa6ed900bd373eef8fe9ac0bdef6abf7f883779dbf405aa68bc586ed8b58ed9078d9cd5673b0276a164608314c8db416913c2acbb87521730b69cf091d10598e2424b103e5d85691a8474b6ebff63d7e0f00754b0614801aeb0f1b7bb98884d779b417a73b5594c6ecba221576925887f31e112bd4f8e485e65932a7ea624ae81863d615426bce8529105342e7cd10f1024d06bae2abaf1ad54af10466d184ae9693c9204f66aa3d67126b58034d62123495dbd329ca01064507225164856dd2ea956ec3f49a44af58442f4526bd01a8d4b7a92c3dc9342789c93a0fc89a0764cd03b2e64159e74159f380ac7940d63c50d63c206b1e94350fca2a0fc88a3c18c0aa74c2c1ac567af119aede0b77ef87abf787abf7c3d5fbe1eafd70f7fe70f77eb87a3f5cbd1fe2ea7f5f5cbeefdedf79cffa818459acdab8fa627194d9f2a78f6713b757fca271521acb273ef76cef3d0b284f328886e4b1f5baa7cf400b44eb01f9a0b583a18c8bba20d8c0e013b2471545cd82f1a1fae4d6787911c43b7800f7675a3208131ae4651a2dc1f0e4b686c5a06ae2d08883909332f64a8c0e3b21bafb73a8c177c7ea764b39296a1dce64eaa3d2cc2b3023539761342985b7e152fdb187ac7069ffdffb9733dfa555cafdc91f805014abeeef8e87fa84f4b875ff540177f53eab2eea0b015ee9ab54aec0f8977d7e0e0f882478e1e32d9333921ed112698cd1936767165288513a54d1fae358a02c98496232492103e742aa7a792da14feee90d94ef78a26833a8f91a55b8f0328f650170ab0eff4f5780d557b8e287147d5619cabd95733a8c671ed58cc0d0d106ccc5529fce6361e379e79f1ef28913b7047275a3c0bf69233b7514204227314f1b3b726b45cfb2421bb8f5fd277e9b240a4544aaf2fa1d227e7d2101369a90df8cbb10ff83d024bd4731072831356c2116554e34de69342760194213a2b10580bc66501d79a81662cec48ebd8e5096c7fa3863d01c4225a95dc63d72b5faa1b9643990741484ade64b8ad2e81123f593f70d1738f7f46b6f922fb9c66c9b34bf38826476272a0cb2a19e7fa8404ea2643cf09d353c21759f02bc7c1fae07c563c06fa3c99640ebddbf44763c0a84f01932cb4e99578cc4c469c8fd598a42d7b4c4b3dba2c4635f07f16fabfed90f7ea8858c3bd89146947ac962112c364e90508b103d4769a636701716193a6d1b7c7e87bf648b167b3a86dc14a8bbafd7108c3210f76c33256d056af790d86233943189cf5e3fa170f708b9a057cdff0eda542d1060d724ee6407947341197d81d033cc0653932ff84d32dd9c51ce729d852eef7f32f79c5c2066aa68af2985934255e1507cdd25d449ed3e8f2930086b2e530e96bea4c3cd4f7c31a0e3b806f4ac0753a96dd3ef66ce3dc8257517ff836ad21fc827028bdd9a1d7cbd1a04b5ca401ddd225cbafc17ac75a0711471c103a28f1f26e9bb32e44412d86f9487c154f3f57ec9b907ea0a2b2b6e6950b98030e248e532cc2a11a4229187aea5e81a9bcb4b9f024e9aeeb006af73083226e84bf0d094c2ee04cf9c5483049e9792dd00df903bc1dff3cd9a3c1a24560528aaa3167691493399f818de6a5089ed1e5f81cdeb8117b1dcba725c308d3433014ddaf10ddf4c4372b9c5c29883f643133c49292f1e4c51837830030fe24038fb602054cc69a9d0942b2c323f1c0dea23e13036aefc6070279e238cc1e035ffe098bfd6898c8ad297e83901e18c598e6483bd305448a93c7c786e01650947c84d1784641ab57fe4ac50f31e18a81de89d9b20bd2b9502fc3a57c633a2b717cec4ea933deddaa8a5a9523cd492126aa79819e61042a821132856ae4e32d3841783856c766f79aafd4d871399c7725a4729116db4ea5035ec0161d9640c53658cefe2e75f523b1c1152a58d8c6e92edae878a13b17af3acec268c7b5a31e5ad66079815a773169f3d8408e3ea5ec34a500377370284434fe2a73d916141c2c478d4dd7c8c976fc29f26e6e7875a80346dd630f1bf1008db5c8c59b786fbd3c4c84f38f237f8698938b61504af1fb60d5a31620e2dcf3562e41335c1da254634c22e2e6035d61aee2c8f091039c9e853dc85ac6d201e03274d21f6525cc30259d5f9a53044b496168802aded96ee2867a244d39a2f22cc3f5a35785548e41d3e11413ce791ed2390d105175d34ab176451e74f9d1f1c79f7062422ad1f9d7af62333fa0ff65c4e33bef56b811f05cb1ff0028a6b39fd94598f4b8fe2581e4516854c70f8bd4391e68d354814e8f2a32ba88072fe6e6822a625c33a7e3b3aa2dea61174e9ca95061d80b60dfd785ea6c188b0cf65ca58840e083c3d547aede6243a1780903fd6b80cc4aded69ae7618a58e8f770499589199b7346be6d235c91a3e89eed8529d4dbc528f490cf4c82a7f4037050d22c1ba4e87d47c9f686f3df69c82c9f1309b264d98e494c7e13bb6abbc4f3e2131c6855285179b82e0237e785e9c0d5674e9a97cf3a0d5cf54324d164519e24c86d46f2e69d5a04ffd2138042e7765cd677596ae16d5c9a47b1ec07b847740f279ce81d72feed92215af141dbf5f0eed6d79266d561bc608d03c5b9ae156d4284b3ef198da83e69d774392e59b1e96f5687cb43487d19c55e9dc9de2abcf1d47f45e83ed8db5f0e167534d9dad4e60ea863b0f4ed5084ae09397ea6adf9bf621cbce2f46e8b402506d25013ad465d56e0fc40a933fc68aebea2d2d13ef9173b2d35f5f7573cbb5a57cfe5a26d278a032e72e782723d64c951a91aa7bebd9a6badd848526107539acc87d8cdb17b00c35d82c6d1001a40ddb34682bd5727a8b85fa030ba3fffc0417e90fa4b20b6b06eb60d4d71f89637e4ad0d3a943dd5a0db7ab935c3a758ebbdf94f20ce676172707eb386d17f70b70285f0ef4c3a457c6cc6c563180c63b0d4e274ca29a7121d8be8cbbba6e3bc4bcaddc5c5a39f0a68eb96b4aebd2079662c337f69c09913d141a0d19235f0119b6066c975714406e23004119b075bf1323fa5122479c0590804c1981ce0ea3df65deb86e305792c2b85f81936ad322daed83a1609730a44bfee79bcbe672cb4cd3709a8083ba0b1c520745b45ed806b0fe17b68c13bf63aa128febcaccd9f4073367871afd1357d394b2a1403496c096daf8aa5e1b05d3cc3a2001c2150a74540d0d963e65c9c3f49bd39f2d12f4baa976c898d39921de7dbeba178147d656f273d1ca9d35e64072d48a15904801afb85e63d3a7dc18e728309e3e1da6770d16d7cd67623a1000c3eade88e67bb019595f3b83ac33efd5ec31765f5ca9f2e8fe16f9b9d26aaa73340c4998431d1d973cb94929c88114f3c4ed686915b4add03ffb74e4ce26ee6ef6070c5343900e0e859920d9d9981fadd3fc2ee30763a8713cb8b9fa2ee747f20c7e5016703351672138b2ac14175000b9d88ae3b49d0b8c2115c0ca6016245683323c36135e13611f3bc88428a2b81da263efdbd8d9db4aa3de2d07cd9453dcce1302f2ae0d39c620a888bd830b3fbca1fdaae5bd15fa8d36efd4ee0ffe41ee4068694ad32339f48c78fbdd0ececf7830066f0c3f02c2b70742f9ba3cf3f609b76831b91db1412ff496f6bdc1b07d3f40ba829bc2a74a7fb026893b8cb9b68f6cc66d5b1eaea6ca4ae18f3a66284658999d8f188071cc7091b40127d7aaef880197367c144154ab6309e24e9b7597704cf1628d2a47d2a57cf4797db049e3b9a01bf5bc60a25fe6897d668bbd205d3b3e9ac4387d8773aa299bf12bf4d1e8c1bc84643e2118cc4e71d36911fd85dca8a258e4cb35f753b5b33564fd0c01007886e98eadd70eb1299cfbc14f7e60b2e47a60846a6b11c639b78b1b0a06a95e48aa8e71f58b34363032ae1cbcdc00486862e9a101fdb3cd18d93d34199cc053d161016af742b57e1aa0c502006227209e639a8786bc86de35bb1e95993fe8996ebb1fedcbd9083890af4d9e9d376734251caa3991c6774113858043989270f08d499385dc9c3f036750bfc95efabaad9535daac52b935f91bf203e1f6c8741d82fc9878874629ce703cc95a13d6721016f0090df771ce678c03930172f4036196ca09af213ff742e77311961a19c532a7117409f13660da2f3f3449283c0361c209b1e7113717a80e77ed6434ca72f7990ad1c43e61180c32686694e072b7c2ddd248bb6f65c9c85cedad5fc275b689458893e40e5f4c9b1f7d14142a97e6fb90568c261f70c348a2d731579130755382b5113ab2369977cbbb642f561e2bb16cfe240ced2e282f7ec7c3471d9e7d04da0cc10c6952784c490349c8efeddd4e52c3a8c9cd25c4f03ded3086efa94afd83537763c2416547d57f429af2c1841d11ee0d6319656d0a21ebd484225382268f28deb6e375929c1f1d6bf8eec4efe96d7672972f533caa5902cb4ca41b8fabd9a4e3c5f4b28dac1cfd37b6d372f7e324036e45fe76033aef2fe613bae432b077efe3f5f8e9d46ce7caa95ae464acd0280f7c3cc20a1e6a8a25b417b881d76e47d1a319c273c21079d2bc914f6b967cea2735916dacb2dec6b048333fb6f57b913daa226649ef756bf58f940c70a92bdbd795c4fe925ab6c21c0e5775827a815c46915bb0add8e03c33ea472c5707cf76f1e5c729a29c493d1bdfc7a9402389d12386381d86fe3228cee0a26c3761fe184114cc23e101479dad3965602e6596d1b8bf1783d032c2e75c7f5ce191802693c5ec8e0cf721291b95d258b12f84db549a71275a58a09e294239c0280cbef7d9c61a1139707c1b122de53e7987d9b7f2dc2e31b512cde74efdd60e94c81263347afb3eea2d9505f874897aade9592727aa20104026407e3f57d7cf1d8daea6aedd47192427b2bebac8b80c4c708db47870e3bbd9ebf8bc14b01cad21db592205216dc199b3064cdb6a988be6e78877abda8a2ffd9d2aa707c79ae952635f7caadad709d27563f41f3b6b7eb097253e2d38eaa9cf9df80c82f5331df54ba28ef2438f3fe2d5d31df86881677ee488cdf8b8545aa63be51f31000b4e987a12d9ecfa17e625d0d7f215ad2d0c54274f802e48a71132a2d374b2caf8ec06a4939f816c96164daadc0cbd9c81b7e716ba7fa4ec77810bfa418f30702bc3c1d4853e96649977ed27ec4ff35aaf97fa32e32d0439dae3089a3977cd27868d27341316c6297618513980861a55cc3132bf456596422a129dc2ce2ae56872cb8c7519c4ddab5d6c17dd7bc2ab49810288a1c257bb6bbad781036603e6e692966477e485e42e61856839c1538500f6d123f6ab8646ae3e502f80b7acfcca2c93c690c6fdbf8d49cd51835b82ab162dafd9a1be94afef409cea1d274f2a4d223155a105a5092a69f89028ee5fc739c92952dbbe7e5be7c69dbca5122971b4e8fdaae24b4c19abaf8a629589d6e07a54484531d67e5d3d45436ebce32621a7f068f530f903bd2afb031bbe5b85e17385b7e86f22b97dd79f49753deb827593732470d05b42a769dab2c271b2c22a5c6193ea2b943039b573d484b8f8d4f089b30d50983826710434907dde7b6b93ab113020d7e6e8945c7f772013218c2e275eb2637acac706ba02857411c161c5fd21c7fdec8842e2f6adbe40f623d82d3f1c2a86a9b4341664ee8cf7a2e31fb9efe5b372fd3463a58ac5f7de99385733e6d5c61d7a52c8ed9aa2e9404fac005b472fbd2f6c31c476359292e29508b355509b9f06a55a5d4c10015c8a653f1e5409b209237ee3b9cf797cb5bef9f36bf0b97b24b659bee7a49c7800884a180b6003ff7e07920222a9d2a311494422d314000c32dcce4151e94b01309ec9e56311047a1e248d86e384389354029eef12175cd27dca133a4bd3cb0581916cc9907a7aeda63ac3c683bb7d41ca69abb304536e9b10a20051f4e91f2ba94edb6d9f44b9f3598194e8862cc3afa374cee84e5e216196274de5bb63ca2167ccaf1fa2e6272d5631e469e25f2364b547f7996febd8b1ee3a767ba77b1ae55a98902a0388edf5e1281536b5706c7efd8006d9c764bcc64729d8f0f34f2da3dabd4ec2c328d7a98179163ca21a349cb03aaae11916c08098a694412d4124d85b7088ebda9daa7958669b105fdadba74bce1ccec1cd156809ff84124f291652d0ca0d33c690a40c0163ac6e7e5d066c342fd66241d2ebb37daf46fe63d74ba438e7c929c880a2772eba68d92b5cdc986d161588214409569c75f6fbf4b1ab6d9b10ee6c6d2d300996ec4552937f6730b514be2d09e5200694cba830aa99c007d8ded9d3073f705ec5ce25ecc839c05b2b160e29d8ef5671b54a81ecf6f5a5a88af8824a47a43dab66694c8ac9b5ff426393f926ec9b13913527470085e4b7f042f612527e8f103b4c6347a395eb1c40517b21a455a4a488dd1290f878f3baf75e9c91eac7792d1996ab2e72df636fa41cda449da4d9a00483d135112a8fb7751675d19c0295e821bf3409d4f5695790a972e227839594dfc27ce662712648a014945113c8f34985750eaf1e24994da7f2676194c91fa755d2cc6111bfc08e8d904b934568b414b9a7535b33df1c18373e87154b7b6a706b9714120d37508c40069d1ec8dadc89117fda4daacc95a4eefd81265031330ada549efb2c0aee5121dcc31fcc003bb45b9d82d23b7d54ecd5c4f2537fe34b4573f021357052352862cdc91955e820ea1a514d483c299e80d06827b6aeb473339265a311b002ea91ea0e32637b858a2b116acc56064f60202c7a67e242c1d224f8aa2c39d9ea59b8e6b4ff6a3090eac2393e4102e9599df2f4ed4f03714f305c455593ffa970be306cfa2a7cd2aa08b6206254d0e678a75584a08c31fd1d437100b847e0f70fbcff4e6df3c0cb9ac4f987f04a0572421fe8946447a275aa363082446c120068d802daa436f287ca329c08deb13400a2b35a2300a5041c59824583546669703f7e2f71c1b5cd0f8036ffc4e44030d2f8a5db927b78b955d0f80a25999cd5bc86e3366bcd5fb2b15a5849a692d3f4e05cf07ab7cb7ddd559cdabf8ce590473dd9b5665c619e1c954e8691cec616ad2c71c8e340cecaa944c9e7437c7245f3ed9d50130b70aac5beb1e03f604f952449144f09ed8bfc7cb0516afb47476b3c35c8d5dfe60cb5c209e3a67b35160181fda6a4c34419b3d5a4648ca0366ca5aad15605c5d1682c9f28fc6a4d5c45d374c656b46b7665a66c51761cdd1b223b5ed0a84d1b9bd37fbf83a429fbf846e0d22e350e18815a95de013d67d87c611eaba6ecee849d97af0ceb9738973feb8b82f17ccefe00362d849a170ade0545201c0accbd5937bfe5e1067d6eb96cd32cf9b2d62c7598f389feaa561af02fc6c49f9947a15dd7d4560d5bdb0f279ab1c619b7b59f14590ec2cc4dd52bcfb658c620b23cdd98e1b95b5c7e9df184201b7b54e763900224bda97e141b13191b8e96a76638d5b8d9a6f9a72e08f3d697fc37654d22eca311caaeb22f33614b88e795f91c721500a922d8d370bebfc66094f2844b1ee03a6f1e8ee76dde266843cd5911670fee20d8c4a5a380554efe2fb51b27380ad7ca4146c03d90d57ede9c811ade0e314039eaf6d7fccb460c7cf9daf9ac9b97a74904e0ef6a697c31ec5efb8878adff3968f401fbef879ce2dcad20411804e09801011cb65bdb5faa047823172f7aaa805c1bc5df704d49c4f6eed7aba5a087869a62a49f432f8d9b433d9ac7a3263c165d105a567d87eb8d48d6e76de2fcf64b1829c5b8720c000c8420f638ccf33a843017ff4152f474e2ce8a7f52999b664a80e081618ac20307ffdeace50a242866ad5df5f838c41f5b3d8816f8fb744126200bc383f7c8988e9ef2a1dfc9bbfb035e798420520159bfb5a97eba6e0c80225a0df7b764b8792d19c162be09b22b093e3f19797b681281642aa64194ba3ec41b838dcfa5c77fd9e9821a72a132297fc70039691c1762ad373fd6779d0649d9631fb6030765068ec7ad4f1c21b1669177cde3c3446973f1e700c0afd7e27b0f0d8155bd983aa3255c299c73aed8de1f14a8bef9d2747652a10bb4889e607331ee06db04d82cabd81114310e9aca5c7882c6c80cf7078f05a949a618b3c9abc20d764c917cf29e6857451a4498a4856acaaaeeb302978c19e1318cfa099c8376d0e17d22f7a21f446f586c3e7450c69c80dda80188d59b4cb31e89ded101c3ea152b2dc1e4646263de5293613551a83c9863e4b6742537a648deb2436c263932b25077f38924afb4a6e5d2c41ae09d0d4c200dd3f5166b41e6d1a30b51c0074256a70076e7514972a8a9c487fce3c586c8e06dd590e9e982110929238607e32738830ce271c1400e93013fcc6ec4b8fc88b0f20ca021310646d0db47dc66e453a8ecb7a8c1d91c49b8608dbb9184a48c929d44b5ee3871a1adb11c7e778383a1dd7ae87018c643402601a643ebe5c268f773032cac33540332a2dee276a2afbe4769ceda4806843bf75a6420d2113e1d01e009b847f60fdd385e8397f9fe5e6146054cb0ebc13c614338886345749419cddefc18d262d32de37000876cf0fe986df392477030b6556e206530095ea14eda1bd223844f08a45c4b6e2d361b4f3d8c4ab25fdc16ce6b6c4e5fb66a1eeff3a80eaa06302a2bfb826ee23091baa11965380505792e2adcca2a05f5143de8dab2a5fbc60626dcb22b418ab7702bc22d758282ba47a6aedcd2110200692fe4d04b73115d60a7dc17d1fa04c5e92e94edb8bdeda2453a596c0e48eeea7d5a1ba6c91e8dcfd692bfbe81822096dd8c6ece35a3cc286f5b73ffc20125693b70a171965568b8c93adaef04dfb8667b2700fd3d5d6f44a69b0ed4e01ca0b703833bca003de6083a1b718a513b57ac37926080157b10c0d588dc84f22d9dce3225a03e14f66f9aa0c662602fa31730fbdee868a838abbae2c466cb14cfafcc81b18a4d711a07dbf391c025a9927766df7eb2022cd6b4814322507c3c70fd8b94fdff5573bd33a696f62fb8da6899b9fe45c50dc819fd90f0dc5a8d48ac9e09fd1d60f8cbc77719a8963c1d69b39e2557eaaf165ed10da60dbff697609e8ae4fdf66eb6c064f9d9a740d9bfa8a59136dfd79febfc6912ec2f5ccf7359461154889d908106b21c42e4ec23394a22a6af954460f0325a3d14369b21e1aae26160e177e2a7ce241b984e70bc85db565f3d88b123cc5880563fbd3f3f55557fd13dd04487ace35f5337b6cfe5e4531a74c67774cb9ad34646503123e1e036d26f6ec97559100911b7b0ec7fd4519b7ee74778b7344af96848c2e45d8b470fae2adc467d2751293cdc6cc775e02b093d267fb89f52de48628b75b864a97da136bb4ca8f76c72cbc44f72e4763cd49fd9fb3e2c605ebfa229191bbe067ac4aa7fb3a2950aa602a7cd9be927430732ec8ab2b438784cc7fb59ee46f3d50324b52f3d61950716ebe6e735cd11b977e69612d84b45456e3cea2e835bd283b9d3cf7039c02f7c395a2c01bdd3119e19bd96bd37e5818e2b2ebd091b71a89ecbab95f4ebddc77bb31cfa51a33efb4115a1c048a3110dc0839be7b961bafd05042142742f0c0dee004d749ac19c233727de7138542eeeb34ba5d5dd809fe586ff3a412e8c7a9785c87c7fda720ee11f8b85a80a4d20ce06d2165e5c2c836d413af174d1c28b5936e60265215f01e7e249307d545875434b1602dbfee2832538e993ccf0f8c4e1bf5accd08ef28227c59c7ff298afac999e0683b13b9995c4f078cc8f80dce518821eb58f5ee64f02de36e99cf68fd027dde032c1a3a7e8213aee99e59cd765e98891f0b154896070894d42275bb14489222e7a24dd7b77ede2bb07e92b94529aaf29648d40063f7ee4dadb99cd0d071939550cd3203091468571e00decfdbcc6f3050dcefa33c2bd153fd9cb78c718b9d943028ab490fba408d7fc10871bd3fdafcd4b3f66ac97bf872ef59bf5cc5645984c85dcc2ff268bb90ea61909341420a14e22da69145ec6b1654ded3d0dea7de148b662ed601c169067f083c05602aa54bdcc224818a33d5bfbb493087660f34fdf5cdd7a8b4945881e781208b2cec1b2a21a4a8f504b5e529d514cd187f0f0b9228d70c8ffaf7501188677f11b0e4531860434644040e4464b29788c86d3f1058c57a8ccaf845429b5900f69e5ada3f3269bbb4acdff6766066be386559d7c835367dbb670356c6e8fa304c711abefa1ae8dd7ccaaab807f268af3298ea86387ce2aa80f2fe95c623a1cc1c5065fdbebcdb433ca1dece1c8ee70904c2e1c7afb4a53a1856557fcba2e5262a02fded1313a44e7254733fca078777ca0401ad8dbac0ca75c71d73d49025536793b92d353cc3d13facba68f9c6378bf6db5f38b63f23a2d393f9ab78d62bb3497b444eeeb705d53b600e590c46ee55f4f554b69c132ca6a6d88702c1ea737eea3bcb09694f2a4a494bbc36d8903969dcc1b63831047a6b0ec9b40bf0d7c197977b41aa056936b6664164df15ca44bfa3e54781f56e4384fb65f087e8d0484eaf7fc6bbcfbddc53e55e8300cb8d422b5e2a2c6d4ff817853fc828faeab4933025f634ace1104cff99b6045e36cc31698e18bd29b17c4827d4d8412e6c10b1eff49e5a66ea55c30346176726a0eb78c0a460d671d086a054ce00181bb30d1d83339148efc78701566a710d79776dd634e21c816a15f7ced515c793133e5e9d2758d15c59e71bab8ad2e06b2f2584bc48727bba30db95a4369ec158a3dd96368a60d906a66f971c4e441ac8828cea7706b519718b26c0801f13a4f8ea1f6193d5db621d00f3d4b769db7b025e0184b8111ac75bf4d76fb90a10474cb7acf7bcf47630bd6d654ae07b059d5c832cd84d6bd3f6e8312083115e1607358b148152dcdbef29e87b769df46d2aefb2c63dce2aacb7f8b2f1d1a552ce2f98958d12d3d31943707b986d46348b3c3ada822d0518a03b329af3bc2b7ba8ba3e9f0e54926cf8736e87268499d30cd7febdf11958cc45f1ad7bac1c363b39b93568de5c58a8ffdf3129066451629aa8514451ffc370995bd781982f5e994e0bb62644742808cce5bc073e3ca85fc557d5052311b9924fbe74b76d71ce5835dac8a548bcbaf35d4a6ec3fc1a35b7d908290354838bd02264ab73bfd534bdb036cd7640e4340ba05454789952fdf4542bd6cc115005c2fcd2b97707b7caabda6237b23527305ff7bd65f304d85a31c2d717b8b071dd22cee6347a1e89138967552ea27955b58a4c68abaa9ad04892a81b10f3cf993e470e7510aceb307a4dcc5acbd33a3ba3904f5340976af1d7db438d988dd610a7c9e4b63c27088e5c2fb6a93cf01a098fddce243d309eadcac1a7ad7d4b1a69bf8be07d3f29333cae5262d245158e9ebf6215edc96e9d36a45e5343845b30afd106a73f3af0d9592f7e19a7027627b4864d2ca17827d9cfc5e1e40cb8467ed0ea2f04ec34fdf9dd73d0c01b684ff9cacf935a4efff28374d152c2c73130583cc6c88fc3391da78bcd3941ea200ce95252c7f3e7c363710cad250e68c8b273b812cf60ed3fee8151676810994229a53f696ca75b8c58db065120b86cdc537259431c9d7fe33652a63078bc5904c39fc5bb48dcdee7c3b8e324d2f6d8555458341104a14184e99855cb77a1b0a1d3565e5579ae72c36365f19691d10be00838659202084ba42246ddb80302cb5228c1149c5414a5dff688828b41597cf809afbef3ad2cd75578605b60d564ef955dc87d76bc39abdccb1e3b4a8cc7b5b6e2cfb6a751d6157dd58d7b7d584074615e174b5d2764deb87a062756c71cd66d09c016b9464ebba735a2b39deb2d5f384bef12a5c386f0d6de696163b7001eceb85a78a312f9870eebe18ea4d9e4c9a23ad4c6e5eafab08b91cb47bdf4c50d4a0c4331b134a9448d9f32858b4900bed55730d01ea0c03e25216c2be843ac327b3b8b0a4ced81fc20532ca9f694013dfd2a393935b5dedaa6d6a5235a7ccc0fc0b2c33a990fa70a304b813fb78007177e3200eaf2ea92a0b0e8585c133d12fe37262df58febd184b59b00452ffa0e0b469cdf425f036d7d68e2846177a8ab9e56f7695a86f014bbd40a551a2cd73d4f1cc94a1f439aeb0f140d2fb29066a36ddbd12aa92befa14600c654cde8ef1cb4c52be85e93160caaab0ee78e1076cfe3dfc73fec4771dec200b47de0c44ee85ce2bf170397680249b844dfd86558bd1ead0d9587e5b65123cfaf73d1ec25c67ad1b3c61f4f38fb6d960bcb482c9c514531f3adcb2f5f0cc91280fd920090a36ea7e526a038c866aafb163399e7b90cbbddb07b9a16897ca3440e04d789d1003dd8e093bfdefae836a0502d1a6a2367ff8a496687eae4160f64bdfaa02bb2eeb5ee627f11ea360fd14ac4dbce3fe4d9d1b492caacbcccdeca6d2574b06626c013f57374b314d96746d2e20d17e85a56e211ef90b1b3c139879252b69dca557c6c2ff93691afeb4576f0f821233916a5bf4416e027aacceba10bee95690222c0acd5b0a936778b257103165202d259889cd9d90116057e96450b4ae356a65ad6941e92d133cb5c63170731414dd65f6f4b78ad04346c25bf88cc2cc3e7e0086cf8ed0e355623cd5872a5c2f0c039071049aa85f551cba45bf542c039b322ccaf42ebf850fd28fca1263763ebfe53663a3f749f8295df1db4bf7956a9ecbaf16fa6a0b3e37096f12f118b5cc465b5581757b2722681ccd46175aa2a47cde469144a7389b05190b51f641445ba7a3024a8ab24b7f2766d179529260d22f1ebfd1a9c2c8d0e01a4550892748f349389b069846eff1daa9910fb1910f7c4768bd040026e5e3fc78b2607a2435e3239a969b94925e5a36f8915b0eea1fab53124afdccfb0478fac3c778ac83369271b245eb3e5fdd2538b6b6a0fa6121b0de85805ff35c656efd5136033c58d12dc0151db5475eb85e857840b090ff99b898c03f368ecc0a7e16f7cf91a6c48619d5033a0cbb56f748755c802363561bc6d7e9271c9a179a0fb3fd823d7f8902972eb2a84941318b6efe00614cc123457f01d4cee96c0881e83dd866d809e36401e503cd25b9c1e84afa371a0151777e79ec8f0b7cbc49f2f322bcf04435e7dde7e325757838cd60b15a67b0c8152a1ee33e19efd64e4281e2a98a53bb4317b7b0e200f78f100e724a878b202f40ea720f6c8612986c3338ab3388412cb3e46e953bc7f5fd6acfd0aa395e5dce83a37ce7eef015c0f961fdd429f2fccfab59086a5f467ab236f92aebbc1c2c86b361ec1dd6960ed6ef435fd65abb398345acd5db80ac766bbf9a4ac1230d1cb73da482cf6c41c703cc776cee281c5d0b1d473821737b7137981de3f9909b9694630afca1366907fb4098185c75abf63716f73b7a63951a8b3b3fcb1a5bf1326a721bb2bcb3bbd8b3b71ac2ad475a843667ad7483f4cc78827783544e63d8fb615daba56cf1caf86745001de0718cc1d5cc87538d96f0df4f7939a693a875b4a84f11ec2652fe9d13ef379a933258a8cfc4b1168b01732271fb0dde330a1e3ede4fb8952e9756a0b3c5f933607e6fb44283018d609b1a2fdc034bea98dba435aa6e93daa0345fbb29a65640916726c5765a2d1a5696967800b5f2605ac0c865e7f3b3d3a67f47b2a5b182ee86bbcf16c7127c4daea165c5f728be8fd9b769f8991e5643433a48fec75a96ed93e136fdbdd0d9bb44b11b5eb1a2921c48ffc90022718c6e69609f95c8a19a0b5c0c41ac24975bac83879a20d592308c6b4b1439b235c302a27f31591f4187dea036cdd0c465da043ac6a587f54a23e978912ec6320ecf620e8cf9b25ee09f3b88b92d98825485d4121ce7c45e441c468b75abd2964607fe2088763a123b766ccb19811c488c3d9f6e832ac068f48b0f00c6ebe1a521276bf3b674a8722982d6d6fd1377270e9d5357b44d11fe28aee789e16cd6c0a6cca854bed278950d0d4a1e318782d926b36d825460a158c7f6ec7d4787d39bf1821b21e9440c212cce280fcb8dc188759ea5e6b48b450d53fe8e2eda8528cbd8555cad6f0eccf9bb6e7eb5ef65a48b9f0a974df47b7d92cd94d0317aa30b9cf850f0a69e4375301542ca5600f25a873dd0d9268b8984f8b37baff3da852a727c7c97eb555145ab507aea91d17a9462a1ce1e9508c9b15029edd16e8fa9625626a4235ef733706d883c110f49e4dce2d7071a50e884278ce2d9ff03037f00aa21140ad8b7cb3804bc458afc82fb6071810b3fa0c0c6cf71a38a16e129eefcee5005ef98df5d50bda36ec82cfa4d16ffe119a8d61cad760143514d5565437781e5d33ff6c9ee43d704760009cd3ae6dc7c931940b1d850c9220a5c446ae97a5d6a1c36b84c4446b651e6cce3abe45c48199dceb241d0cd035dd024289c009fcfb04986671d4a8db99de2eb01b712afc900882e4809831c9f0707f2972a26c1444c02362623ec72fe7ca632f126cf31a676c6566a4594c397a3f447ac8c55089533cf0f0e8d8220d8228cfaf811fd0439ed5f65c1810ec53149173312e07f45e4ebc4e4e9967b3948a41692649a42164381a73f9939eb61bad6d7524ef8ce178848c46de58771ac17b5f42395484b632aaf4e3d20b4370ffdb4b15278f834ffa3a0e384f7ea9d089e5ccbe574201b44ac40ea36a4ef5294327001ff9780854a82e7bf64d0d6e196f2b5fd4e7a0f4ce30be5fc99c622c0c4c0110767d78704b61758820a703dc0ff96998849d31e08b45bb6230f745fbdbc6496679bb7474dcf69cd249e8f4037d0a277a7d856ad7477ed06853aab269a303a723ff1e3f24e3e252d37868f0a504da616553d82d3bcb73b467d648b7087dc8b3d3a90eae60e3b40e8d1efd55bc9f9a5fae3995e2b6d108947e5c5845bd801f97ca522464cb5dc6e6da6d134d4a281a63101f77d8cc40390b765e12422496550a592a3521750cd2b06e3c76ce8a6499b54efb32839a87274406b32bfdea8c20282f8e0d9831c957e21d1d9fadfdb8e342f2906512fc942b5b5ce54ee4b9dc52ce2f586967c6549cfd07bdbc3dc7ad4c3188d8c5d9552211847265c50a869303a5727aa888e7381c97402fef5d786f1c23490447111a685e4dbdc6f17396dceef76cd8fac1f1c933d098b094d694655e11e4fcb4e82efdc443fe5045c5a4aa06be6cd84e7a8c90346568d756b37a76deb61c0e58f672db5775a2ee24c1cdcfe08d4fa985cfb6e346869ded1b55dbddb9df3232d86a17d42e9606345d6a5943d10a0350984525b9af684f252d55a6fdc7411ebb2010eee8fceaef4520f6d0d080e6c8e6391a632c0e6ca8a2acbf6f841b1f2564c51cdf543ccbdc0e5137ab528a143f7857bb781f1cf002aaa0f5dac192c44c57040a7236cd3eaae1eacc5a94c88a7fce5175cb213d80074c882f12267cf864cc5b2cd594524a90caf59d841341cfea653ec7f41de1c798921ae152ea5b218958f61babaf9ff6bf09ea3fc992c26d7e24ad1993503e6af2ad7f4e8194ca501d8f129a4fbdff4c5210d02a6b48c40fe8058646431a429a84259729c9f311c39bcacb96ecd51931b9daa25e79739f4e3e6727eb299b1bb1addde9ecd3c9255a2949b362c007382097c9e9f10e5347cd1e9ac322857b0b428b0f73c3845a424010ee17a766cfc1c47daacc2825829040bbf15042a4833a5df744f84e14458b4d01302ef8abdce1de1ed9e3fd5776a5e3be79da1831c46d098dea12cf672d1f8c10afa151d29918bd2c415f6652807e2e5a7f76e80bf0bb81091dac329f4b4423f566f482b6dcad07559f1c0eea0551400a17c09c811a48d7e7bc8eb1fb6b2eba77e03199872f847764a9e6733534ef690d9080ff408f0ebe19e2fed193fa46ba49aa7f05d2e146a55f9737ff45f48bfed122062e46095f88bbe8887ef90d49f4e1a9cc5c2f8b4f7ac4f7d1c907e642527cfa0f5f8a189f94d40c187b340ccbcb7c2cf3ea60f809443d9f10a121443c182b09e5f837452a8fbb81a49a853a0d15d7d57a922bf942054f01297f6121602c0425b7f5481aa43219bf4dbcb30250a8efff1f92d3f32ceecd06d29d79af70cf96e4f1d8511499e23cc6894ebaf26e6a5452df9e4f9a9be55e8d1a93d4a83dea5e4788bb354b6cf0fc1a9ddf0842f23dfdd13d8a30af198f7fee6cc796969285a5dd815030a8ca48d053151afb9e0ca8f9b492ddb21f13cfa0ce55cc44684bb9b918dc872332d1924893d9e2549646396e1ccbc8ebfb3dde16f195e205a4c5a845d7cb00bb40781259b288174442fc1c774b1bba2ffaab2cac18648992f1ccd119496df951c88f012397cec0598dde7615871cc6c0fe8840aad050a221768bca7a232b9fe80f02bb90f6982743afbdac1e35365fa98e51eaf44496a4d33049c86031a9dea875d30d6594d0789d965f86e0a2e61c18d036c3bd19ba5eea09ea50e04d432953762fea15531d3559d823336e482798b70c68b03300880000886e2b81f6cc624a831ffbad315746a2af3dfe05e3a868d5ddeb558896defb626b794322529034e08bb085208ee9209b1bb6e0c2855e1489353cf72479a179496bf8fd32de0f843226d1144d336b9d573e02a957a97aefbc9f2f8fda57a168861fe7b79172f61313f615ec24f01decb7c8f9877110e617dcccb84439c0cf9de9b38a7521f036277a59e056277a9de0355f8471c7976e00f79a4523d4ebba8c2fb181ce5133925a9e4542af51324a20269a783451576bfb1805fea59bed4b77c0cf8a53ee665de03bfd47befe23ff04bfdf72f9e057ea970c7d401663d0c2af3d4c5d39f46fe7af1d4fb8979daf294e5e9f7f461bc702133ff5520cd1f987a1698fa18507aaa7b9cf6d45c81e3cc1c0e478994f16f1b903ccaa9bf5dc3f25ff7314f04e67dcb637f7d2ca18eec7bd67f5df829c0fb98e7e17d4cb8e384e577bef0eb9e08cc6b097978acf0eb421dd924f242ec2e26b08b9779182fc45df47fc7098f98ff7ec7090fef637ec7098f17ef3d2bdc71c283f530c21d1feea2cffa2fdc71c2e37b56b84343b873b493e32efa2f92887e944594154aa7312176177e09c354c9850c11229926e357813fe411d6eeaf80dab6ddd46f620cebe70b65d9840a7cf238899a50c12c6f93f3e6cc5df43f90f5de138111818144605b731f4804c60289c062c009f374e8c858a1174e2a79ce30c55df9b5507f2ead1aa605a7ef9efbd27117fd19c629eb190fe051ccd4a9f6f4677840d7847e7ad9f5a976ad375b6abb3d48dbfe4d7adbfb227a3fa59003a663873f68e41bfad0f1002e004a22e51733c035cc097198e0512eed7c7701b60d0cd233e62efa960bd22e0aa4451ac3a3b83d45f96b0b71347d54289e5e5c304387a0086248b6da1f3659037fc0a35cca408208d9e99a188f06afb4280e6c37742ccb97394614d71ff5327cc0a2bf869cde1ff58f1aa2fdfd9126a3c24f01f6ef7ff279d4f7af5af8c99087fdfbf62fea3709db9c8bc103ec5d0c13a6bd043b7ff283ccfc71cf43fbd3773ff3053ff9439c6c3fe4f4da0f71d2fd10ed4fefe027c38f0b799c5e0b3ff9b02de4719ffe101a7e32fc16512fba0b45b302fc6dafbd847d9ba6d13f7d8f21fef7254ca2502d5493229444a0fe0faf5225fb77a7a3864d9ac6623077f72a55605da54a952a28008a4093fa367895a6fc434ec94de403cdcec76440f798728a9c32e50894e6d07fa16b5499feb6529bc49ca7bfbdd3f1e98457f6c720611d7ae8b9cbfe0d3f1dfb5f0c1266c31d273c7ec2ee7f3d26ecfe84ddfbfd4386dc50f48a68a10df59fdfa35f767bd0d6609398930874bb30bfc3cf85dc61045c6822734aa008264e98b4306a82053e593621e49391b26c8288a17cbb4636c102992af7e326b1fa9201588631daa386311a7e3d268cfe84d170c7490c72f6983af3a7165bcb1a2c6c521299f300483e6c4747464645454423067226610072c0934936f27964239720e2414f6c12f95432974c2642fde2e49c48a6aca9a9b492f89e1719c1e40c3853a8c5b9b443f7186511bb72729efcd9833ce2e9031e1fea989126b79216fb451b50f40cc0f7dbf80bc703e0fb6900d23535be3f48d7d098f132bec6f535e2c7f89ef9fed9d335287cb74e08c1ff86f1fde2dbc5f74fa13914f3cdfafef904e6fb2794ae79f9fe69349f98472ddf2cdffd33a96bf0f74fa5b934a970df1baa67f2e67e3f8e8ebf68fe868db70100690000aa00d2e0aefe1a201030488bfd3340212df6cb007740119c3270ce66c089046c8153497f08ce252df683e0fc797032e97f01ce206690cc07cea17904383d703e01671138a1b8807305cea32985059c485392fa53e0a4024e267036750cec13d8b34602e2e884a32c92479ea50ce713368c704f2bc91136b1f1b5da08bba79774d3e853948db331051ebd08cca45c037d6ea604f4479b15ba66fc319372d8e47ed750fa14b4c9b1044cdf05aac36316dd8a430783bc41775ab8d5bf470b4ce99eb23a355ad8b255b745eaa0a5395aec1bea84325c7184878508f2287a7987ba4550502c8845c4f2de6af7f4be62f5b07ec5f5b0582e2d2fffc2f22d2c2d302c600b4cf8b900f3aa6701e6a545c502ba7c0be8e2c20a776866ad42215c8f6a47480f12ae67944c3d5c0feb715a88bf58210dac984f4685c3f2b205af6c2c20101a587e94492c2190205d0384e5c79955214b28694875a9ef680022a487eb51b13c4ee3e095969045055259c3512f43a93d06c714934c62c1fb13386ae1ec219a3d4439886c6c609a9b22060ff8f348696b62e0c11df00a8e93b3c9508964c5d20b15f86b05c5162738c3a3249a4d450a031cd279657ce2f80944a1266b06d2e8074efcf8e0c39c53ccc9c1c9215a2127076705fa72e6f9ab21f74d6e9b44a1b64749140ab5a15e6e1bcadd7d3ad52c0de5db0751eeee1beaef76effb751ba44883c3266ff3044416b1ed01d95fd6777094c93f64b20b2af057aec73ba93c01fed38f58c391c9f51d861198d6170e6d95453b6593fb1594714dff293201bf880506f2288d5644983b011eb1d7a24dd23489c043041e2210414af9389f71c09c16e5afd0a2cc6951d67cfd14fce8cb5c6905390aded5e32538074708f86964def3686c69a971401e3cdad87072bcb98804b84915fd5543cf06a1a21058768dbc225f91373902c941e892e53ce78527b9bbdc2f0965a9a3e02088201c346a290a0ea4b49c3638c8fd384f7267af762cc82b9ad4f7ce0579459ef567c7c3090da5ccbb6c76400417e4511ead3ca86200fb807d489244d6b7dfc38738e1314476b36e46c58e1e7ae83144f61822bdf69a284f20ea9cb5d21f5fa7d6b9c2f5561f252528509c10c97b3a695af855a4f0bdf3745a2541c315818194268090650164d904103f36aac04e64fd390ac4d24e870d5bbc1ac0e3e7ae79d189a445d944d3b4f6511a116120043a902571916594a522923c7992244937eb66386de307742ac1329e2b3b88672d1c89f4df7075294b8a944de41f984be015c65cbdb749f7feea42b16eb683c17f9c99d3341947475568f6d46251e19554c7c170880e905314838e11037c1c396006a41fb3a21f1a0fe6c565d5c2a2c22ba98edb282084a9482c7664364bd2d3b3c48708cc3c05a1d9d3e39554c76d2718ce01728a62d03192c1875684c846e68b6179302f2eab1616155e4975dca6a16e9d470c191922fa268a08a9564b354954799e0706cf0b1e173c323c1f4f0c0f8bc7e381e179e171e159f1b4f0b0f0a87830cf0a4f8aa7e3e178361e14cfe5d178a638e239426d8eda5c5aebd6de6b51d46b7b3d692fdd9eee448231bba453d5c4550b8b0aafa43a2e061d2306f83872c00c48230d49370059daf1919a3dc9a43a6e3bd1d0dcd8d8c070885ec83922a6d9935865ab16198b4c25c3b215594ad6c938d9263bc950b22bb33b42669229d632ef0e9a3d55994c2693c96432994c2693c96432994c26939d64329995a14e1435edcf1345518afa79d2aea596d2d3b5d49e50a8d3adb3d812a59adb7a51307eccf13f1600fc5112853fca24e44f592803652f83217b21732193917db218194be6c960642f3217d94ad6226391f5e0e3f3c3cf0f104040430405193134940411d11245454e18194d7174d40324a48945922cc9518f43e7d75a47f9add5a2b45ac31b50da4f79834ed76a45698e428552d6d0bc56a73bd94ffeede10db72d509ffac956a04b00cdf7f457b321385328d85a2c2abc92eab84d43dd2a917ed0a039b1c9d61cc0e9c74b7f44d51fb9fb632a4bacfdc8b2fdb8e27e7ce97ef4523fc6acfc28837f7ca1faf1597e0c5b7e6cad7e9c71f9517cf95106cc8f34bc1f6db07ea489f95185ef471c323fd6b8f8d1e6c58f3793b67c01a2ae0b9005cb80319e177e0c284364812ad0d0dcd8d8c0705ec003e414c5a063c4001f2da003666001471a926e98372820049c45624766497a7af0d9c0f9c3cfcf04026888a02023868692983788e68dfe191eac6d54dba8a6c979baf7e5a4278a43e713ea711a154a59e3d61923d8c5dc8eb4e7a0d2aeb45b7936b79291eeee757a1136ea2da56c49e70df9efeeb4a607e09cb4361ffd68d8637bd4b6811fedba97b0f7b96d8fd3d73b70f31f361cf8d1104715d8fbeb4a577df7478193ebd1b02d94a826a8afe037ffe6f928f09ba19430da2eff1823df8100cf1f5f6b3ac552ee95262a19aeb744e6ee53e00117718ffa1388fa2d852458b678aaf659a8f5bb7aaaa7adfb2d051edcb5eadbcfae037dccb0812f8ec03e68a64184a860f8371a5a14faea9aa1c5f631830c92a60a3cc449f743563ef54358be0b53a10c79b084aa504c82ef49cce32c4a3d4e7748781a85b3e8ed7720c0b509f8874db6ef33bfc5cf7f6d38672df6b448916400d3f0a38308f19b83d4fc629c8b66d19c4191227976510e13b08f195c3e1ac0331ce7516e59246f0090fba791bc915ec30f2f4a2c7b3897b84e1db1252108543869821415fc800537960508565e78a4b9f3e88f5bf4b0d773494a2b6e307483288c28e900a50a169c0d2870ff88fb67d29190cc4ce693208db3842de916718f782eb916db251282a016142105500e3f27d09a3084a1cd69b5da0b9e8b99c6c63b80f30a776620bbd213d9dd7d09ec7def0d470de6ae4483bdff9648238724a400b34c51e980f113ab18d440f582232c8ef02acb284018228f9f04849fdce203202419025ec9320a107880c05b96517ec094c77ff1074b3f88096d7e9a94d28bb3bb7b8ebbbb534a414aa9e6d4bad35a29cdeede6ab1bdbbb57ed9dadd3853da27cec1cf7386dd7d726942a2f5e4d56a577e8e0052c8127bfe21c5f98b3ad913aaa236ba71957aa5cea1babedad53a54ea6a2c1c8c57389745d2289f50f385699b7901d52ee7f461b8bbbb1002cf977f8209f03c82e7d3ff29d8f3fc14d76d1bc7d116a5fbb6752869aba6d55a6b3d597094395d14aad65aebc59b8ad3b854b7b2625964cda3bbfb76e486565569e1b60ccc01dc307390f6db35eea194215d71bebd103922cb9823e413d93249c0d35d7a2b9a16ba1031b9665269a542b432a9b452215a9930a1b5aea032a19a11288c30b9468a30328b3082aac288bbf59e591ad6212298acb80c517fb20bacda95b556bb2d940526ebe9e6a0e162a8d2d183b4f09e542714b699403f9364f92ee400668f0c8e7ca55edb50e0b66d0ad060a71088bb82f0047dc8855a6c3fc2859037faa110d1774371d75f2b30f9277086ed45147876d2c671d25f29981c5a111565a3dc1c8f99596743d3d1d0bc90d3713087c947819e8bfe42c1a4bf4e303984839280ef55b170d2dba779c8f35b07f99a3dee9afd4a7541f390470f9a3eb9df87041e54875cb48065c8f320d183824e288107f9eb05af5423ad5747c0d49b57ce1d0c81eb1e1e3ce1ac684235673d3d28416a0e11155d91441ea7d17c22cfa32925cfb93499a614b52c4f6ebe1c1b499eb37d60642872f7b4fb3b0505b97baed3d1ad32f75ba783e3f2b65d71246f3d10226f8fea746c18f5a74e076a06f9f41249c7494ec9f7b54ec7a5da2a6b52640d090559b3a2080f8c34295f373d2c0144148359ccc40e96208bac586204a300ec6028fbab4b203bc212443158ffe46e9eac10bd1d007d03968842871448017485104c50021128ecc13081c7cfefaf29834a41caf429fd5b0511993e8e5245159952249490695121041b524090e97bef625e91c17c228fdc1432a0e203995222f08869f2b89242897ca7d880677dee4a074f78c04707588800e90803b3d9d1068c1875e0e7a8043c1009cd8e90d000d25114244753f4301d61b1c30e28988e9836302405068eec78e2480a1e8eec7082488a101cd9818323294c30db110592144e663b72002445114976e820e62e1f5c1fc4be24a2fd89c562476ac0c32c656bf00449aeef2c328c020111185502171460cdc910b8135211611512ab2d30ca899512523c80352c5445389565941a14a1c5881a54911329168bed5095e8c9b5d65a7fca1ab0a028d7ef95104a8ca04509e6b28ca2c4095ea0c4101e02a630317124d32ca34c81228ff8b50fc452b0c407cf902c65ba7518c7a42a55ea7ec7f278a6361b51f07dfae011cc3255aadf897955c883f5de7be10e4b158e9228c78072d6cf29d516031281792011588c0e958de8ddeb85a3c71ac5d4d591b9086537dc1d478b6e83365b1dd4b5c2164201ecec02656ea47e42e42f3a2bea1a7a744467ee4f8fe69c3de5be2739c1b6bf85fa25611de4af460ae90c860eb8f36dcd7a0aa5f48909a545a3301c6f8c70c4628c979d8e99c7e99628b6c496d8125bad274459e0d6d324a54973eb717a6b8132cfcead704eb9c18447aa01792381995bf22685dc4f95e48dc458d6a59f99096992143ccea5bc8409d7e9983f4b7aa6cfec49bab33be1e752f81d7e0dc3a7e1883becbf94e6a44b2f0d1b690a55127190d4e212131ac95f74e62ece9b61fff97dc4141a82617e7611c953c9cc4ccb5a3bd36ad518f367c9d77781482cf494166f6ea4ac71f3dbe4acb5744a18bd34e952902acdf76ffdccdf3933a7b7e6ccf48ff1b283c1c31a5a7f730c14c2166e166b27d59999f938b4c48f21de9f9969cdb45a4b4e1c94274541080505f103c4e4c795f812f771251e124fea9aced9912435556a0f5dd662bbcf94a82c29b9775223f98fd265178324e2310052ecc689f8389d927a8a26791e82acd1f4eb7f2d740d3f1ab240f30da9ace1de7a6fb57ef2e6e0d8ba69d99f748277e786d3dddd9f823678be2db0c9cd6f960e6000214d7257e77b0352267735046ca04af4ef537a9dd67ac3bdf7ed0d6bf0bfd9521664c6c16948937aa874e00f998482127c69849f3f8d772199a144972815ca449bba2656652d9a44a9d0251748959a70f82880f74570268c01ce8fc1c184e74b14c0fb159c5904658e01ca3c03cace9fda16fc290d8378ee991307a7fe74d635a75367838e195b6388bfe3d6905b3f3b1d4954892eb5488532b5d8546375764228fbeecb3c694f69b1931aa945edb5ca842a5126dad462accaeaacf65425d5bb8104770713d2a4169b26d1a872d0a4252f3efc85dba57d1fb5842c4c4937d44c9350f7dbd153b2a6d91f8bc4735e586a49d463d33db448f2e9fee9e7240c2df4cb0428e1210441fef8e1b763669186474405288fd20807cd8f3377f8ede83ca750b1b97f3a28c78f8dcd516e221fb46813e4bd187bde3f150a72f98e754dfdd46f96bbbfb2b5d6ba62b195e59d856543d5253a93a4203de121a1d135763ec99129d1148af1622693bf3c8f0906fbf565aae5eddb5066179766b15cba533039c09727df22d95fe6bd4f3d0c389b2693164d2d3ec803e4ffffb7c9ad56acfca0847d16b4e17bd9adc4d58336345aa42d936936c552bf4d2e054e1d303030dfafbebe7d99cf7edfea03a90bb20cfd6d057e37ac56ab4fad522bb0be05bf0f07cfa3b5fed6596f572b6b57a9effb0aa6acfdefb3df0ab4c1f3f7bfb14008d820658d15183601b3b57117d501014aedd7ef77f918975adbe5c11b6aad35aca1bd7701dbf3c2c98452c94308350135210494dc4bb31f265d3381a864fa4d044dc9f4675323c934888c84ad72b25b8523119fbc7a0b8e739412850ee0ff2a784421d78ff98ff5328f41aad8f254a6e5472f3f28765e03850fe0cfe5bdff5ae8ec859f4bc802cd1d4a592346e6efffbfdf58e083de129845c36f91fe17ca8e15baf0a556f62b0a4ab08541c5c5d3174f9f3e8dae89f9fa2cef61fe65f5f473bac6e5e9378c17a06cd105285b94f19a70cbcfadbe07c684413ca75832bf80d90365667de0ec5232b3be5f8132d7ae85d4af566110cfa9ff6aa7be97ba26c582f17ec7ccac2fe677ccfc3d4e4fa6ae49c0e782fd76f90f1469d0b0401c1ecc8b0b98d3225d852bb4b86a6a91766c32b548bd2d704b38e2c9941f40c3a645fa2b600e9c15727478b4482965123b2bb078a958a9c7647a668a0e946c317ab0e907658d1f1162044620c0a38de7f9396e30611b7993429e9f43de749e8ff32f577c8722c0adef981d64918c8d2702a424db9dbf6366293281fb4f7f92b9431c3ccf4721099ea14d8843a44193638524601d37729f46f37568a460ffb195bd65826d9360a5c161038e136549943d1c71b27d99c7dbe4032804fdf1622ab16cc31a6ad84e501b1a3e8c5a6b9552ca3ba994524aa9a3ce916628b64929fd0ee9fc16999c63f256bd0c93b7eb925779db38bc92eab8bce5ad65c5b9bcc078ac986f7321e3e2850b34cf5fe571677e7b0bb6eddeeeee7697d9a9c03377774bf795379552dea6f2e640732771ef59f764f92f66d86ad77f2e908f74853d84ed768dd3d098a72cb3fc9ef402b256292badb45229a594a07b75f7bc5a64d581160c442570f880060e722c4106051e097006be1271a9126cb2e06a0e383970581eea3d00da9336cdbc216988ad97f15698133b40f326658d53a794527797f54777f7eaeeeed49dce4ac5a96a345e5c562d2c2abc92eab84d43dd22b118921e9caae6719b8692218a2ad0d0e4306263a78a2dcfe5a958c6086a5226ac24ea5e168c633c2ffc3f699a466356836ab5547b12820fe3850b992f86e5c1bcb8ac5a92f4f4f4e0e3f3c3cf0f104040430405193134940411d11245454e18194d7174d40324242c9292844e557bbc92eab84d43dd18748c64308244b3278fdb4ea86b4f1475a2284a51274dd372d8d824e154359954c76d324451051a9a1b1b1b180ed10b466ab0d250b7d210ab11b6ce39e79c73ce69ad0d6fd828b5d66ef752bb6df4743a713325cd9e70c4b03c981797550b8b0aafa43aae482c7664364bd2d3d3838fcf0f3f3f41cc947a347ba2f1e2b26a6151e19554c76d27d42d128b2199b9cc7ba4d9938dcc17c3f2605e5c562d2c2abc92eab8edf4c3cf0f1040404304051d316341108e189607f3e2b26a6151e19554c71589c58ecc66497a7a7af0f1f9e1e727082020d63c2541b3271a0fe6c565d5c2a2c22ba98edb4e4562b123b359929e9e25b31f70cd0d3678109cb93ce79cf3decbddbbc5265be3f74b6604d3971979188f57a9027362df080dccc9fdf1e2da12752f0bc632de1f8152cdd6396532994c2693c96432994c2613c25424163b329b25e9e9e9c1c7e7879f1f20808086080a326268280922a2258a8a9c30329a22631305b50d6491ace1326b5f63b9c6fcfdc707f9724997bf24f20420441e4fef9d8e4c0b831a885acfb4dd5b17ac457632d97e9985ace11fa532ff3aab415d7344bf662c55245e9764af42d969ad196916d9fd2915da949d66216f6691bbbcce6acc5f4e1de4cdcf25957c69eff74756f6d145f6fb238cecdeaa505abca006ca8cd8c0eecf2eec54a5e45ae42eaf46d98f5a74a32e6ad1fdbb17e0feb18b564bb451596cb235d29e6c276764c10b4cd82c9229f4b76880a791bba49277a76316c91a4d3ff9f9bff653c3711ed19f0ea2323aa3b116279306ea9f5934c326d6b3a1c450a651b70596fd4339100513283aa9d47f3d1e859f1514c5601aea3ffb55fbe8d7630b3f1bf6e0be86b247f879d8847b0943bd167e1d3639bd8469d75dd30852727bd95d733e0a14c215b973d8d8e0b8ab43197cc8a3d8fdd9366e0b400cd3f7ffad4122b00912816df2c8870c33cc943c804652914c3124a8d335a2c191236b3a3c1af4de5d9a0cfb988186d9af3d8efdfae34dda5f22b00a1281dd17dda53d119805bf1bdec0a3bebfbb34ec2eed6d8841c2ec7bb8b3e3b94b23021b456dbc19e5839a3e4b807e8a9ee8d78b1e8944111f26a1a11564247896c8a8d3d590e0f9c9daef74cd14ca1a11799c3289c4054c90b597a16b50c8dafc7197f65593cd2077b978f06cedefc5d8a6ca70fdf1970512425f8369ef5a58c344aa5336d97a5102f76c8d603281fb471b04d09c42d97dd65649a96bfadda9a5d2a25b26bbd462a705a63fdaa56c7dac528bfeb3f6182fc09b4fab94fdad120b08fc1e64e393e74c0a9eb327d9df89ba86be5542ba5c5e7933ad0c40d6c9a964771742bafc4f2aec41a30dcaee4176488aecd6c76d516e22bb2fb5e81e246bf88b54b4d03ca9fb9007b5e85aecfeb0c9d61cc164c2af5fbf7e5d8925e4d3a61dce252d70ff38978ca6d20b80f0389594bae65940e0f1668ad41d53c2d946deccc8f57168a8f5a5ec17eae45a773bbadc343ae0cedc6fb40a40d6a84f63051895bdabd3abdabfbf3ebbc3fd29b4db9fc2a7271d19b7d100a3c2938dac51bf5584bf16b4b7af556b6bad154bf0f42b48b42d115b0f8dbca99f43a6205fb700f64701106024408e190dccfe68802c3fc6da8cf3a204deec072c9005b241d8207b64a75821eb639fd8226b64a5d821fbd335a3fd406ebbc432b11fe82e06090bc20659202db0ff68817237929cc91a1fa54b41424348af194b474031ca4da94f23796ca53c93377366da447bab3d0902434ae4030defcdb0f9da423ae4ae7efba30d2d07eaa738794e5c4c67f2d84836b44183dcc55a82bba7674ce0f963cfecd29602fbdb8b1278ab49a7296753b10a3c7aac3bc8e2f76a117890374a6a92bc9991edd7257933fd45ad0ed9da1cea12b2b53feff96be5bbaeebde67e89f0a3d6f0d6107eb528734ac4beeb2efcf5495b4ca94eddb9611b82849c77f7635490a1e3ba8a8593821b794c05f0be1775bb4ff692ff39dac2af0d7a4d38f35e974c1693f05e6ccb183b2fd27b27d1f39feaa3a907286e3b5cf92af0ae4c99b599b00f3e8b1f2e8716fadfd0ae4af1a04e9b27f526d1528a912d5a4f179c8f64771ac47d9fecf5879a08516a826c91af6452a5ec2ac80091b926d5daa4944c06ddfa5871b42ca175c21d42d451042cc59f344022285f8ebce1990eea734f4668f4713059630091b6974c0d23e4e07b13dee9aac2660212dce9f34b93b083428420b17002159324bc2405a8c718465a7a30bc2a35c02d23512c95b4382fee6ed80e5bfd00a01d60973e64c6a4fefd39f41f7ce592c460fb0ecba22622777709be519f206757a0e941caea1122e84f183e5dfd79c7e8e8f1774649881864b374a25534c43bd5c9ff4eb4362c209ee07c8672cc75d54b24a20bb2060fbe39c4d24ad2e09cb1fe70c075d1e6cfdb2b5cd396d10a3c0f7afbba6b4321c25150d14a3c03794ee9a3d9bfa257b3271799c4cb8918cbd24cf20f2e6fb537ba894d922d7cfe1d1af9aa0284c0822e3c815db645913753d4c10b22debd70be4fa5276aa055c516548816b7d4ff417fd205cce13df08db94319168685e14268b9ac6ce4a6b0b06f029cb284d4668d2248456130f9ad0d86a6d9540f841e203265600844fcf95298153e2083c4924144650b246b8006eda415315344d36681a8a59a28ba54b111e3d4f94791a3436fe55cedba20c8d30b4ead1d17171e75e7c84634e8bfd04bb3ce1695eb839e151a82c5fb2e49e2f0a4c21b246ff09e0042414a3272dce237ac88eddd354722f99f9a4add3e1b9bb5ff05993e52cf071da41d64f10fc625cc8c078d9e978f1308ed4624f29477302f2e684ef17b2894c60a5cbd12529d80678fed216b4c7e889e6868284baa889fac9921f5607669e4eb9f9eee15e7af7d2e94de8492f42e091cea8129fade7bbbbbb5f7aef0deb92caa4474995d51953938b18c81b9f39ca7d247231b8907b7ae414a92269f1a8c53e9292023cd2d918e49b2a29c2d3018f74e64ca9263cf3a333cdfce7c9b4d8dd1bb5d82b9ff21fe99d4f99744d53241a100d6a9245eea74347f4d327fd5409f5b9d32952d7487121e870147820f77b53d7c840b202cffcd8487d14dec00805570aaf82cc00c081a46b68bac695744d006abebffe30e99ad7f757a0aeb1e91a017cffe6027164ca7948eebd41422dd280f37180361e00e08c5701b4f1298033de410180f36d401bff02677c0d68e30300ce781870a099c685036c3d0040fb2a80ad4f01b42f3b1770a079865d14f6d0dc71bf7eede83bf8d170077d193fdf3f01379c1fa4738dc76918648be10d19329ed2194f6584367805676c978349028b2acc1b369e8236fe82366c7c77337e763a549837ee6ff7de2082a3c58be3b2d33163c65fd0c6df00472279c6cb4ec78cb08974d808fb498d508579e386e34e38ddb65e76b6f5136c6d276e762acca0b7a8748c196a92d4211a1101000020009315000028100c0643028158240d6361780f14800b79a046744e970a63518ec3308c8218cb1103880106008800c8d0d04403e1a4b7c526eb722558ba2e62efda67a563cf65a89dfa358934ee27a84f0bea3e46d05e37fe21b4962b3e359f5665127c65f92b8794f20e42a4cf3abafcf07587011b4f507765ad2cc166037cf89c0c04f2b47ce904f79d2652fb2391a9ac6a4140cc0374d70fc87e8f1d9fda0a1467deafba2fba6b7de5be086cffea4e7378873dc4ca80b0c886e3bc751f69b35a7769d926cd9be8c3bca3821e83bbf70f56e2c4cbc3f3db6e6941761081ba3f1dcca92c7fc3624115e604a6b08fd506f437052fc83e4ac61816ab6f3e56bb7813f21caad608267c1595907bdeb87508f5453f1fa305f740af64fbdd0301badfdee7657e4d5ad764a40aae06b0f79858d61edb8f10068e060ac827f7deda1c123e08eb13a96aa2ddab5077aa16f4a1c36a94fdb6d02c1241da2874bfd0710663696dce262e4aba9e2e5792872bca6fbf154ebae30462d11caaf431865410a18b9163c1bfe717775eabb86d1f8b1da29f96e96f561cbb3816c295b9d64f81170f176c916492192536249c4421c3fc94b2bc6a896f43a5a8a8410287e169070f232290af1f1c2676aa946f869c7350bf4a0ca2747323186ca913b4461831300d68e3843393897a75fb436f16699b003c4cd55e1ce8ef2d1393a7e79d97d3e820f8e012bbc30b89dfde941cab6e778b78c72cb35a01c47ebdfbf4add652770dcc2da9eafb713c275b2e1bcde330bd7c7b24102e252036ddcb834e7d876f154826c77e26478102b7cd35381d3cc2a940f0ed9eca96718bc5fadc25db1cbebfeb1500ffd84888ed8ad7ca82ffedf31a1da877993b3fba0810c5adc8bbde205756e233ba7242906f0ab9768b2cec1dad488216735184a8298db86b1fd182551e45bedeaf19e4ee3a3baabfa0cc75bbb9daaa8e80b1e7620468ab7a1d2c35a0620d0e2c0686d5572ba16a5ab103d8ff2fc55ab7e7f87fc809cc04cb894b09ac65aff91311eb359dacd45c6e816e177fbee9c42f1f17bf3a22871ace5ebbcc5f6aaad2d59790249bff3cf150012549d82aa2abf00b0e793951e538b95e05bfe861308dd85211760cc36ee5aa6438ecd9c92e654e75001cdae40d8be13866b6a4dfdb4b88d20c903b9754d02eb76e5cd70fe60727d3472f33919909cffcdcc140a3fa69842a612686a3e68318ff34267579afe11acd14ed0b6bb28e0241436abe9e219fbbce1a9b964d7ce3b1142b407befb7791501afe578adc61c605bb65734b242069bb41c61614bef453cf3c2f3b95e20e014d7a55644d78f9cff2e805af9396d2acc4695df0a6dd3fd89d27c6dd48bfc6ed5bbdaedc87e44e443e3dd5f8c5a67f384b571fa0c5458a162109cd62f0fce96db4f58d6a09970397dd537cd454949b169c9844b9ae25be2386b57916e2e159f2369f0e1d7833e9236016c6d7c8b0116deaf59a25b250ed4f7ff71ec3410ae353c9412e2f51fae5a491a9a5b4e2fc013937f6867d473f1fc2b46cdbb8a69224833c5eba31a2b3ac911efe8093fae2283a79a2b8b9bc8cdcfcc782720470f616cd60094295b9409a227253d2c99fc12b3001651e689b4e845ef204ecdba4629253d6184fe1b3d97b008d2791627e587dff48a399b0f2778a056f6296179f4fd942a5ee5d28213b8840bd4682e01477c3dc2c200b10743b4a552a461474a004fc00ea8ca3a27d064ad68fe495107a092b7bfd74153e1aa104e1e1ac9404e81fbca6b7f4ef4a019c806c682c9349d17a155394fe804e827d7fd17f9c44f9e8ecb616c059843f4861e44e5bf44e216bbb52db995e0ce52312b53270a292cfbbbe65575c4055ab78a446f032ac7e8a6eba63c8d6874ff5705b8bdb06c00a89a3cff011258facb3a49e0c8b57c3af04457cbb8a407b81a8a86461bec40a62eabd58441196c6e45af41b0379d1890dc065e0520eae6362834f4299b46745abe606dfa30472a463b55b7251a02ab7e4c93f24d93cc02ae6a804466243a201e67bc44c3f02c20f90e20dc21e0638f593340af13e5219c1a2a9480d1b31cb1dc14b21ad7f57aee928d1c6f61b2e1cbf01cc19913de7e4bf96ba17dd6473be1eb9cd32e4eedd0469653245f11a9c057d8f00c99922e7526e15a3e54112e579dd2b4feb36bd290599b362891d3d9d02e0e95d179dca672f212b128fc3f98ca392ac62d3fb59aa6a0c899f18c6b43cdc341479ca008992892f621931acfda271cd3e16fd4ea249cd854291edab523665776b459788ef4061124d83a1205d906d7a077b1acb8f5b38805450e323f6714f7039d8366c8ed06d45e5cebed3adbf86656e0abce3d47837ae367906c86d82a739363713d0b5e5df3b4e5c0870e4be68a71177f39571e78bacfea53e6e042f47146058434d970381f2fb48428837a464cd0de45174e6d88f80e4eae4a21dd0856e00718f5c440bd3c7a66971154587df5ada008b7dea33ddddebdf49f6d1f8fbed5d0f988ba429c8e5274ce0f4c115ce51e524213e982b8e179950d456cc50e31d8582e95b2b9b41ebd81c5a50080562b24bb96b52d34cfc595fca119f21a2b4d44efdf966a8e6114ece1a600aa5c5690fc7a1344d006589119a91b085301e60b928e75e9f13b86c6175679c2517dd5033c687c6ffac82a0f1434559fbd4f2fb4a303652f9b22b88fbbb33671a7c2aea1dde870ad48bd89a1996f1f47ad1e2d4533c375a4203248eaebaf890c7d4cc7a115313075533a7114902b279afcbccec10ef32a2de5877aed0fe676bd436e6fdac55c19714cfc0cf2b23939e54645b133bb4d644720a10670275948a1594b7ce0b3c6882f27cafc4b0714a44364c63cc7ac9fc3bc503661710700df7f7215d9dbcd1dc350da64e576c4096b8f8e7ca0507e1cd82d1bfc337c06e9ee154aaaf299e97d86311a899d47f09528d6ed205a3b9b31ce4e39b1c80b8cb1675748cb99340d732348f891cba326e0c467688e7a5882b937928b8e333d2f24d49f902e17ac10ea14ca75969dcd8a8ae1ae18065ef2093e4632dadbed3e259f9236bcdbff983f2b3f37202705118c636027c65d04f42644df98272855f6ab24777d329615522caa03a048fa7bb0ece945562c80ff29fa4b4aaaf3cc18ca62e3a436b83120a8e2c4b3332c65911d7050ac1e81d1a7971634aa7e2eb81bad7c41c3e61da694856ac2260dd3d0959337499c523c24fd29ad2b12421d857798c204d02d593657c4b57ab61f488ca4b3987f212e02f1fe13c6eae3d4907e1ef91afbc9c9d3d39c14852327e6cf74e0fab969a5b2a53afaf8b3154402e98454ea80b7280d21102eced0facb1cd06cc37334ee99f910930c8114caaadfdb80d5baafa94710d15f002444a794a76cea52893c0c4a0e9d6510ca92204bf0168ab557d612db22ea65c489f852ce924f870cb16409971b3778de7ab29808841c5a0c781233cf63b131a5d01752879f61a639f2dd94b351e5a3b63d47ff89490bd7c280861a27b97fd58103399921bd55295c3207835cd72e57b294adcfc98e9faa156b914f7fdfcb871fac40e22af018da5b84a6461b586bb7ad6c7e675f85f523bfb771f3bd7132dc6526d9f3f881bb54b0354a342dcd4f34c8b245838f47625ad4585a80f5d4d541c9f75e2a14cb42f3722c97ad5d43391787a166eeffb449735c3b586396cdcdf8ab64cd3ca56350735cdd63585d2fd830cfe4c7e2d1e5750fa528011c570ca5a40747e4cba0e0b05202d80130c302179bc9e4455a3b1126e264c2263e4567e07fcaaa8d0b70040f17c68997ba012872f072654b41c91b04becb438ab22a181b9447b741c893b67270378982a265fface043e86ea37a28aca1583fe06f6d4c789701fd7c90e0448bc9ae1da46b2a2a076c873a154f67f5d511dc77b10e1b818672db773159b370acb4ea4efe97c90cc299afa9d3d6a0b844c83c11e79e2103ffe887214453c8fdca296d43c8fb8a7e8977b681a10899b5dd50c7d789a3e0d6a314ad777b57549b4b1ac2282d5c606c8e7187e3b4fe641faf6fe6fad08460b57fcfb9e2956d0ab12f8df6755024f036ce3a960f630705e7e0888e78695ad0b0e4d0c462ad512e1c46fc5bc0864f2a501a56bbb1eaa6f4ba146677524f8bf8e43912ae4989e48da91b0fc08bfad9f120682998b5ce6f820d7528f3d0d59bcfb55aab6d904776f8a71be720da6b97713b6675967d231c531069b42ddcc03dd81786a1c1ab90c32777c85f35fe1acb274d9f7e6cbde1076ec12190b7d8014aff263f7aa28a565f6432a59dc098e177b291da23bada2eb1be068a8d3a065bc40e1c7f0f3ef0f36f94e35d01e2077ca614976af6c0a4f9600b172e146efadb631454a1ba5d8c338e9acf56c0e8d0736d7e3171fbdead3ea9a0ae95252857c289c26d86cf6ed10191862613833443b722d3f528499621aa7ad68a0438416e19947382a01a58f45f281f65599a993f8ec2cafa4ce4df6729711fa043ae8c766081d35e41edca0c9e01aa3640dff1ae67c4a2167f9e0c11744339723d4727b6c344b3c360c7a74064c297d68bde75d8a397730d990023323fe2969038d141ea80049e9e0d627aba6a6a8760e7a6cdde0c3b6c8be5bb89d9acc01a7d719256178352a0955b3e8afe44efe85ebd272905685b426ba87089f7368bef12159fa18d15e519ca639e697c055aab864dd0a802b35bb7b837fb28669220c0e05fa8e86f51fd5ab188ea7a65650b151820c6e10401f9309f7beb201255280bc16f6908cdf091577b6a62b4e5ee69f71a086934906f9d036acd6b7693421f86f39aadbd000273810bca5da56731b2ebd9a12337d7688d10f121f14803d01adb431cadb5178b5e09a8e821af5446dccc455cad6b72699cce56dd9c3791ddb26c02acda6951d49645bce6a936c21b7d6824def2ab719e007307363dcbe39932499fcce2f4d0102220f57ecbd6ef34a930717a7cbf47f9be4c2e854eff53b867b54e8eebc9e8933d50f75a02b43558f8120b90cbaf4b428e035a35b81c44bbcd93e316d5803122f10139ee3fa13c59c7ef37403aeda6b3b3bca2448124a7f80220a11c6f15660fac6a7db7fccc5d6352c969e8a756e97a8dfc8a928bb5e52c709519f1eb4484a81973e1102158d95158859bd0ffb09d3f6f79a6bcec70f497012c52aedd0c14623174fc827a3093cf856611492c52f602cd3695bb9dd911d5a07655e43be73bb5b6a2f076e5d4fd294827831b42d40aed36b13b1c0bec3967b2a1202aba7ba50b3491a18b8b747de28bcbc328ac8c71a33f6e087d9e1b2c08adf084c111bb34dd6d72f2d9442c2a150e6f497929d99f0c83a493c654e4230a5fe14aaaa990e01e58d013cfec7ee73073ccc16d6749263c0497ef467b7b7845c2314e5e8cd8f8457ba7940593021acbac0140bc4cd9a5db6e405167c7139046c43163f706796d75d2541f0dee762271432a33a80375fa06a8ab3a457b16698eb00a7af1c79964a1e8ccc3232e9535b1ff158b04df43bbbdbe72c4f4ac99c9e1ea589ac3f64ff8ce0c484c46fa30cb2e53f3b782eb0e292e384d20ca0659d160270bc2b7110561fea8c55d31d46aa1cdd8944e5629a9c15c77306b9dac12e2d009b6d8816a25d3f491852a10bb740cd93e279535ccd1e8980a0fb9eb1e82e8bb6a049c7d625320d533100fe4004ea4e40196c3aa36ce7e04de55995542bdc7c9d29b41cccdb0092896e716d6148ab913d99c8954b3fd967bd417416858918e3fe306a638f4ba4a7eb9696937af444b7b18f387db6c89d0d0d68aad3466d236c96b04b001152f63ca467f26b84e717819e340aadeaeeda561c17b901f301fdac366beac9ca5b69685c478e85d5a932de9de1a14fe67f03672244c5c466edeaaa11c9b1aaf476617d22a235fbce1244f207196e972dc9ebcc98a49d89441511094630839612485cfb1112803deb35c39816bf521fa8077a39b7d066a42dcc28290646d4afddef69cdfa22ffd7162cf7880b23549c03e7705b9094f98b8504ad09be76d6ef47140ad92d4c0219114682905e4827d922cf9a0cf3d8c2f0b87e6e8b4f18b4781e5cf00158e45db244f6d64fe900dc544527f3e2a9730082fe8a1f157e568e0dd9bb89463b2b35cb2fc48c950d4950c87696af7940f42e4799ac93c0ff6e510b5273af1cf75569295303a177bedb63985d440da3fb866b1a8d1fd483baf786a1eb548ad996d0d4055940fff39765916c3d94d81914ca68474bc3885db4788b81082a330496a3d31ceb19026346cb6b614efd663698ba51c27f303b62580c201dfb6942ff5931cc0fb88a95a3fe6f00bad0fa1bce7a022106902fe34a70404f6e979699f88f845319f221d06c36b7e9c7e0e5246cd7024b68be0089c9e508abd68756fa2bd604279be10a9a5d696b3ce201a16f25ad4009b9e6abc140c4a1c1e74902d61821f0ae3a1d5302d820b7883475661693ab5782645fd910588abe7239ab32b29787a3f6aa0499b2c1f6267a72c2c39395bc05369fd680c4e574bdccf46ff91e838e814561ecdb193662bc9411feb6d1cfb2437f8a83281e8f33a5bb34e5197fc9af9e8bcec9a0bb6588e3789d65e2e948f344f258f4723a601208519a4d5a16e598eafcb54c4bcd602c3425e13895fa7bd95e8e6a48a98b8244a9963bb0b2c6b957509d2532cb919d09dc82a29ecca9d3241e42fa20e9794c944e24b931711e32fcb6f8d323601daa01b9d02faaa048bb721563d72004f8b44af35ca5ab5e6cfe18456a4281d4aaf5990ee5f6f93f5245d263eeb0ff632f5d8b2e036615cdd64ecff9dab65428e8a9086ccff70c4dcb36a0c194d4f2202e1840095ac20d6ddc932f4323ac32af6efacc956464afb05cc735e9d749f7994d3ddaabe0243c09dec75b623c150c17a6f1b017b71350639210745f5f3349efa23b58f064a971950cc6633564d4a08a93a579fd157131f01f2c217d78efad748313de5a424c643f36122e03aaa2db54893d9a37ac665be651f4573fe1af37316df8b5aea0a1fbd95d10b54a11809a4b64de1af7dc1dd19682f2b9bc943b2c9b63c73120396d54c7d97160c9c2ed3b7872cc863be7a08ae3fb10857652dfed85349dd792ab1a29a5002abe29d7821b1e053bcad9d334038adb27310ccee408095b27f42c92bb7265756dd933b937d32bfb27c53c2d96ef686210043c08010fe75b42ab90593002b782df0ec8d6e30d407c4eaa2527f9b41c3a4b2c525834f0816fbff6da9907b9bdfd1c3bb8713e6ed905870454719897a9790d9886fceeac3a394daa6a108e303f172912b69d707c430e8342c26199fb7bfb4ff80d1770407700397d0135c61bc796c8d5fdc3c351c0adca8f012f4ce284bd3c89ec47c3adf113ef765f1ffa0031dd73f0a9712dfb0fae1b8008de6268afa13c035a1d26fb7a5225f98b8ec77c856eaf10f98feab2720513762b756f6cc467f28188abf0d03d9cc9d2ac2b8c853c5930d83a8987558b927f5aabd86cec310732292b96c070de9987804cb8d0ec3112f85b3d136c85a7382d24a6611d921a6831363163ea2477a7919ae1d8be216b39cf0fe852925ebb5d7952aeb0f7938f95123bb9236b01eb6fe255ebae52a11b2e9d7dab9aba9d275fac1ede44ccb8e5498a6f16a729b235d980329dabc0db34537cada7ea9eda38b6f89a651b24c54489b265ca64594e69a698263bb92af5901434e720072803278bd3f18a12b01d5f5d86f0c482523547193474f7ded087c95a83075a5bf4c34d28ceebb074bfe09e1943279d9a06273f8e0dc5346f92757d02173bd99021e79976cb023dfa70b72dc92297a1dbb6b936c50d74ce2511c2a52d1ee74c84e36981aafd307fbe35b11c21a65299c40bb2dc7900bd3fbc5cc96fb147e02850c89c369d6ba615af8f7ba41319760b73084f781f553658ff2c3283a303fc551e43e96d14fd21fcce51ae5dea934a3d782b72fdf6b99f87289beb65ac918119857abc4dcd61a851f64cc86d358fcb1054e3daf8b2be1407222b5595d1cfbd567472b205e820f4b4fc0dabf1ed5fed33598f8136fcbff67bbae9b210124610f632d2a3bca5c63af2cf6ac9bdef68121b2270b5ac71834d598a7130cd64d6c562c9d32d4927196c1ff9ee4d107141f5992041970f49439e364c48cf120ab23cbfcff39f1af97a2a955643fc189a70eeb24521beb029a3688cac646b1d1e769e047fc4d4ace673e1872499648176d0d1dfda638834bc2b977d6b1c7f1170afb99349b6b15100547272a47f45726e2936dd233da4304b0e74f0cc6ccaa400783858c5ff7d7d32729c48523efb58e19ccc36718ced40c8010a2e3dff29db2c18a64dec018c31b11f41a2654743328e78b4544c2c26a24be192844763f0c9f37720c7bc2887e95838c68c838d0b69866bbe14c0f157aa193ced4a337d67c980b9a655af80f2c58da85ee33ab69e1cca75a31b35171566ec35f44701cdbe6ee17d484652266bfe0c2289f5cea4f0e4f832807f3841c6c24e6d561a78b0dfbdbb52b0f99559eaeb003c9e091392a4ea6d76d5d351b7284000e2961e2f534f0ac0f19f858a15e8db7eac6338099d7e49db44bb9b34843f82bb4031b27171642400d46c7e2ce3716ee8d38669c5cfd788c5b7a72280c8124392cb7b124cbb1fa4140bf1e4ae617b88d05ef8dfcba8616171dcf12bfdc1a5dfaaeafe801bdb5f9132f4cb089dd32e20202ab8cdc4d9268ccc2d3bc6c535478068843345ffe3eef2090ff2b8e59be9ae45eb93df55329ef6e39a67b013ae0041db3251833d103c3587cd2c200b7d328c324913820054c3e37a8c1659f3040ae8dcd4ccd031960cc54661f2c2a2b28826f8f079125207252c5e9316b1ecd3b1afbc0660667c648d8d8df649991d0004f7f224e8cb8295eda85703497e1640d3a1279df64d53b924472b2819dfb0408c3f94b4e39b661987eaa95cf6da367ed5d9c1643ca3f15c90a0eb092eb94c404b21772faba447d1ce4fd553c255ea501be6cbf25da5d347e371c6e98a2fe46be87d5897bafe4662e746f0a4afcd7f8ffc2a4aede72abea31b4433c356a6d40012b698d9c3979aad091ce8223424c80edf88850dddde2278e623668bb7a42eacaf5bfc5956ffcde8762664c2d813c6421bf1796c08cf538fe076ba10f5b642b3810561d6001cbd9623ad78452caed5a5b73883d4a22f4ecc41c02d150d714cfb784f633720d21ed79805a458bf327dfdc5c2ab66a35f4cdd6887f73fd8528489b16550390755c37cb058c689457c51b4c35cc9c2585d8602ea7145b074703f5ea92e1970d3ccfae4e14dcb8622cc84c440c0175914110d29f7a9228ebad2deadc6e51ceadda5f22f6a352b075d1bf6902abeffce2f31bcd469c12531e921a486d49a93651e9d729a811a52de0c9b65e7804befa154af575c3f5025d51c499dc935fba6e2d55a02692abe369863265374a1d02d9edd0b55651fef608034ef7b09b0e90ad839289a7a5587623f791dac19610274e50efdbad45bf02883a9a2ecd468031294fe25df008612825c9b1ac66d6e75ebbe543696fd9d4f1c2c03c02b51ef80365716d04df6ed9eda8cdbd89265430a5ebfad086813d82c63bb41c39e9a15deb3ba65b64c520a1f035a25b1a27c75f0610f5ed2ff416ce77616029d8ba6f73bda522ed0c05ab94370812a9eb0d23b8014057e1f0d69d4c10596da613bbaeb47c86ab7b5e1619fc0e128d2ee385253206e8bf7371a0beddf50afdefd05a7e8f81247c32b1e1b160e0c7f926ad886826f3ead1784fbc03d239ac1becb22179babaf71752ed7cb46b00dc4cb388cd159a7b086d5e3da333382b9c3ebc89aee174be7df20e0fcac85a02e1683976eb62bbaed44e6564701aa3177c4ea090efb929880aebbe2f088af7d23a2eb9652b97fc46c9ba8584418df89aee77d83a18fb1ee171ba5c72185505e0385dce0fcc542c3f0029e16a101316916fe8984a5304d78ed30f738a496cc04366250fc958203196e18a445bf596da399e304bb8835a2cca5a57b8bb1f22217013196d899b3d018f7b6aad52bdd4ae839dd1a398f2f943cd2d07d87d1b7cd2d089af3eb2334d31871965baf7d49767f2b9e7654bffc16c1e2934328984fd96162f0089daec00556c7fc7008b16710b329196801dfa3ab2e48f2d0b0e4f8972958d788c1a703764f885152de48e0ea16872516c00a81e79a24b555f217a24912e711bcd69c489ab8ec43ab6c6ca53c38f7a6e655cfb32897d65af07a3753e081885a9a64cb86a2cc3f9386bd370169ca5bf8ef2366fc27dbb8cd4733c4c8908b2f5310096a78baa81a1818aaf1ca11995964454cceab65e7108426e89a8909558d971cca625a72b258a82d5e78abf89d633b7ba1174f7fd87f5b625b7242d213cb9c5bf8445ace0266ed1823d4b47199aa37331362ccc42410e97ec28056bb4b8f97c52470d3e25930300b1189dcc94d6a0ced707e2b36ae49d72f5cbc050908d26a073fce2a423199e05095448c2b5c278ee30f1fb03a35d5ed21170024ddcb9b5fc67c1d09193e32f71353f5f38dcfa82a02f0c59508f01548b5ac067de7e8b21d30deae233acaaa885392c6572a2f97c85bf24a6ba092bb6f0ed053568c293cc4abf32dadf7a6ccc79b7989ebe4005c763f9df3f9e369a2ba66ab0aa52be5120593263e6738053b81418135aedf1f82d53ce19aa8c47ade590dfc8ab48f48959c045f7d8d97ed64b29662401c15d782bcd22399b590cbb88214565b02f0c3d07d4191dbc2d112a16ee959c38082ffcaf468698a22686564b2cec815b6daec485c79c471755bc431a9a84ef170530ca99317affb2f235e218f8afe23d41ea60b3d270b28a9c8bb6fd9a9571a8d69b803c90fb4b5477836eeb726d04d8f9d43127c498ddeecf0e30b3e947c530e01cb022eaab03ab0cb6f4427d9f9b9818561381ab7c47135361232a8e75b14cc166fd449c80f811b6df8815ff478346552e7e2281ed87d0915f387854b680aca2dbb682a28c3ab9a3e565f439e649a0f1cf051fe8d5d7892b236d8e890e7e3faa330696be297fef87947c9f6cb671261766eaeaae63770f67270cfbc92e7277db8d7be2d04e806f09ce8cc712b568a3a743bf9aa76c7078badc79bc43a2dee5864258e47097a3d7fafe60babfebac688e9b4b86c63b288ccaf7703f8d3a11a77b0016e7d1c434d3b7da539d49dc1a72367837987a41639d10daa54fdea9d8df70115c54d8a4d23841cacc329b10604d2773b29131f1ae176d565096def96c863b20a728f12839cd62626dcc681679f9359297a825cea4575856b5bbc4335515f43f2a53fd8e2a4ccbdbb954613b574dcbb7764d50113a6509e79f5645a79ad125aab3964b127fc2645134cda0da0d7effffead94a4229631fd7359c88e7d525f1043000688d3ef853bfdddcd09339e42cc64eda212e08da5ddd96e0fa6221062ab0ba67e70abeb7ee71bb1f575c1b2984555d25e127b507ac9eef5d570beeaaf207c03698266857b1156ce36f03d2b25dc50d3cdca82a598092a09b87f93a6a57d40cdcb62de1a02838bba2b96ff0f6a2207a445020dbbbcc5dc9cf1d8d3349a43e5b15121786d2a52c7573257631847e5600232f60cbcf48d1e1f74478708931c13843f523243235f1e9319f7a6c9d6432d9e061b346207c822a4175ce244edb5c2d6646e57d706dbb27dadc356dafb15a96c2a7e729266e566fdac8768dc534bd60830f601c76a3e3b3bed6678d8eca4ddab49a6ac3b3e3a21258d681ece8ba9ea90cd8f9a3bfa5e687324cc85f131e2a801689bc914e09ec4fd105f33389b755760dd208fcef3ec92957220d2fabd5e7b941fc382ab678445e731d1fe8ca112d8c18650f65e110a310254645195ba6f18a5c2863f908007d301950f0a9b4d59ac471734baf11e469216353d35ac8ba27ff506de9ed1879524c434ec664e8cc61ee43a8f417683e0b299df998ad91db25e67b52f116a71f242560cc7e62bfdf132323124b9a18ba258d97e7970f249191ba5b1839588d6d073b13456d4cb7bda6e0d4d5ffdf29c8f261288a1b9a06e0d537dba5cde85ee4af8e20ca9607f598d4a3e749bb604ed6532d3c0e9f764805ea2612ae1c87054afacb98e03c28f5731535659952cf9c476159e4d533e79159168df5ce7950d7ace868e3e2e042eb359fd19a96d07bcd65f067ed60ed86fb4f2107434a50bb3187e42adfda0a9de7bd731048a9258a995c51ef9c8790b250d43be711ae6621d2cdca757be638e683c5757bce71a4c7592cb6c83e34280144cfdc184368fb4baf397084d339b112048e64a2e9e93b4f64efd9e06c7f8c63ebfe206b882adb6c69044966eb873252f2d5c7331e6497efc3f7e465184577ec7ce3f8f4c15b67a8607cb48605914cac5eea5d182cca396e5932a220472b219d2ce41a2b45c48e899ebadf5b8d8c8e0b960e39d00fc393dc6ca4aec6995de364eac0d25f30587d0858fee61d3cac5e706e93e60105576fae985dbb1fcddec4de211956209ae5ae47af4cd806bd9bc25ec92f013c3bf2f868e84453074dba58237cbc737c06e4fa4845fd832d2ee7b1200476f3c8e4fa12f703fbca7f578081e962f8cdf170b5fadea02c2401e1a516f60579df6e1f0aaa8e34e8912a2b27bb95dcee1ac4a68fb7b729e60e66b3f4ea9dc41b0dd4c4129b13bbcd592eeffe960632df7281544bfb60adf1f2b15610c2f01cd47f13326cba3cfe8a8f010cb926cf8879405ebeddb9fc3673efd47ca7e69d35eed4e8a6e7890350a6cdf19aecc5637e8b3fd227664ffbc399bf45cfe91bb7e63df1c83f77c04130175f0909ee1d1e031909c6a707c24388c7461e8e2db9d685c3ec4c7ffbd67b1b5248a96bc5d919b04c745c81ab35529b147084e4d9cc653e584690439c85e30f63d8f379472ce2e0f8af64db727ad46a93bdfe60d71aed71393bb26579a4e467075b3980418329568875843441b8729fc20f059c106f13bca5b93922ae84ed27fc918d746b3075bbda21ae5e3339a30d1756c5e26178bd47e18f82e9bd1ba2b5ccf0ad996d55eac75b4c686d0c8b96b6ef5d69587e38a7dfcae1848df16a3bd02acee0e79fe5255689f33a20b4ea6accbd171c84d16036d35c8346eee85d4c56a5e4077c2a6033a6c0135e5e6fcf614cad85a3bce6b66b05db719c3b0407101cabddb80a771d68d0917db153f04f00cf961c1e9a74d1d089862ea651322be707245c0e32430e1821f3009c6ab4ca7801cf8d6e5ce8be62d589272717a6de29f82790cf661ebf1a3a6ad65543a7d4186a93c90b98badeb5ec84fa0047251e18c896eba45bf5349293a87d2ce89ec2efc25c3672f269b44bc36e1a7668d805d6b232f62e4a73df72df7c83c27453cbf90c56807539afeb2f0728f908d857f82724c76e0ebe1abad5d055a38ed7609a52860f94b96dfc483ef175de0bd8753d0557a96cbd49c4cefe6bc4b4ea33846922fb287cbf821fe1b8f6f3f2d6dcb1e6ce9a77aec62a1d993e68e275b083339a6a56fb7cc0acc260a6fee131003fb487092e53637a0b6970ab8a22f869bbfd13453f661c587e498a0c374aa2adde37f1c62f8f5b49f44b2ff63f4b4adf3c8c1e5b8b0a8febded67e1c4e3cb21c7bc31c553da9584e16cace8d6eebc3d3faac44e4cb6614e5fe12bb0b5b67ec571d1ed4e8bbf01c68dc466c88ea8e6755d58fc87ffcc0600503d4db7e413c66bbb8ef82967e15e0b595974f935d1a76d2f03d08aaeaf7e126e78d633c133724470c9bf805299f89cc922b8ecc3ca290cfc446c91147c56a1edf0a8263974740460082d14be023c0612b0f67ec9c8151cc70cf72cf3c3ba8cfd61251574f7ee2272226892a41631bc4179c6b3b27bf6dee3b35efae71a734cea1d763a4367b5fdfc080bb317bda1bd0753d0526193a193b7e8e883b2a8bf2d928d2405d72aee6f4f008e2b1c98137fbdc796e26328752cb04b284bdf51b3f435d7f7187c33e39d51d10c1903ec53c0642ead3aef2efc2dc36f3f36bb85be3ce9a776ab84bd6b39af5acb27e592ce83bac155b7c7d8435b8ecdf4967bc91bbd8630bbf3ee94c0f5c5db9fb24be12df844fe22bf14d7806ee922dbf57b787d7d3f1f8de74fc3c61f1ffdc6bdcf49b71bd6c9eb8f877ee356ebe6ffb115d4e24c1fa116c372d0e09502233f85b8501381f993e01250a45b150b7ab9aa51b8263a6353ac9de72e2a1c1c124617b5f9dd78dce05e0ee686c9c3db9017d04ab1e10c3a1b90460a28664c423e404126aeeef2f45c8c50b3413901880d1644ac6bee7ddc0175625704168d316aea746f4b90d3e6ef92a212b1161608c83011a63455e07d9da8269bb0bff0971b4cbc96b1aa1b82ca656eecf9199e739f699935af76ebb6f3e6a6d5554c0e26546fad05e61afd4bff0f2f6fd48f75717355fa57755026c5cd79a0e3d51dd61d909d61c538bf5b852952d7cc80355e03a114a7ab5c2f3b7efa5cfc437d19bf04c7813bd89cf807db2e5f772f3f8323bafa5f8c460a10e261e6131bd1f1b1d4b202c5b92a0a8a27558f41db4d529ea52c91fa13c34edd06c87a69d3498465aa695c654c7f2d232ebca222134400b7eff624d081c3ee455d5e3ebfdd9bfbec282a944781c7529fa6bb3ef2661b82d427fb597d5dbef99bd8617cbeb22ced5d58b891112aa2f81198920f5eb34183e6947182c97fd83f4f25f9ace29b05147b8f2a8d86f46f774d3cc14456e73941fe7c872651c32ae2c57c62db310e9918dc4f564e3223db991589f88d9075316761992d33c2be3f18b31d18f2da365ea4694a54c4485f12813109b4aca54f0624f99c29731061414443c002552a64a4005a4e06b0b4c99b2596380066710330aad4333abbf49268b0f2b97c37a8801395faf08dadb8d922cedd7b4bf743675519e4cfe8f5803b0b21f02af7a9a4ea063d736ce8409f3c412ff2de0d4cdb95a865c9c4c10fae1df737106f2191681e8fedc85824553015f13fe782095958375e60eda942543c88e0c9f930d2c5c130fefa907e0ae2ae3d90f51535739b05c89bb4720713424051234f19a827eb9831902bf8ef9e7c08141d1fde86bd127a9e94ffdee1b033ef6c0509c6474437e7490fcd8d03040850cb11709f957624c409219aa5c1fbc114e019c76b9f26ce6d65143c72b4f503964b536e66e1ca3551f5bfb48db6b44a4d0b1a4eb5a8c45d4a08e26b574662934fa65b2193b74777506da7a9bf1b91704bdb4f1f48dbdce06bdfe66fcaeb7fed82c75e13e78769cff99da11bdb57839ad730e8dad7d3f3a374d582063b41ff17772698181295ac527b00d4912d9b8677abc886cb056a9e94692025e5a40d651c2410f201be31c8f668082d70d78799768ec9706062f77e5c247e0c1fc5a771669369e6968b08a8ef95ad01af8f523f138779c2e00f143630a0542b3c88c7d9026a768b2a59220ee5dd9a7e60995262aad86d18c54d3be61d03524bb07e0bace6745ebf38d8720b0d89ad0e94e06888c766a01c4dfc1acd74c34c6595757aacb448e06ff9b13519e834371608e095ca97c00fa9070f9a3a2656c60de04d9e5160d322cb09f61a601af03e88c116fdf89932de89aa81e4c4f6bfd4c7b35d8b448a1a6509ccc07aa0c8f3feac50d16bee3d8356012e332136e3602d1b0bdba2c476a95de13c55a0e456708c466446ffc246650d0bf7975f1e25ef182c17c21b68dafbac7b5f350723867c68742283cabfda53645220285e7993cb5d42be15ebeb44fb9e20098a940a5e5ba97b88068bf31d21c937228021dd83ddf72806f4dafada517d80cbb2a1ad616a0c8c34c8dcf43b874a6529b8a59b352305d7ba5904cac922438eae232ff51005d5b51feae1da666800ac486a30149daa42be6ff4c67adfa15d4f36951991bdeb543a955502f73415560d2d4656c90585abe3d2e8f5f5087f47ef6f26d841a3923c9394275b8702182aade207e31754c714875c40e000be0410d8bb2b6ef278027c6667f914140c440b2f171208dd46fea3b0bf61484e845a6ae778c34a49cad5a857c371d46c296dd6a1fa088261d2d72ed386a6487229386cf4b766d6547a40993c5e889e498fb6420225e023e70b087bb257dc3f88825c527e43b961c566fef1162186b04e2034ddfe6c46cc94b56786f23268a277e387faf3a1437e7a0e6e9aa89b0e02211d8eb4ed8841871d0dd6bb4b95f2a53cebc8454a60d661e945e7b0eaf4b12e4f72e11e1ca000aec951d39dc192cc0bd10aaea3eed2c8de0e279be0e6806099f63af1cf65815c7eeb0cbc4f0135e5aceea48d7673c7c9230d13a7b63c917a81491aba6c6a95deb6612d1ba4518ea1d192f19d856b7730eafd2233d585cf50c9008af9eaa0438a76f33be977736610262c6c7b92b80b0b79d69313d50bcb128c8c3c006afafae125a0d2e7324eac164b15a7114b50b45256cfb9c9ddb05682352156039170f30275ac54b8a9c7d57d1026b1467286aef638ee62962a953f764f35217bf1959fbf8de20bda8464abe2a1b1fb443a5dd8ac976725cf5f46d610cbd169b5520c5e7e39e35612fe26b51f62dc74e8c4af1700249727356c7a35b98f1819ea6290605df832459761d87900414346c73b1317a0182083d402b3427945cbb70a6fd175c553fff527780b3540f0862d470f08ba0ff0b996df435829a85cb4d88a209aeb211ae51310823be275e782a059dae0490276ec90851815ab2e154f8f4d040d88f00be474ec989bfe5b5646dbf0e9ed6d5adf508d28952fd8709b56ff8b9918c7193c65f4c3a7830c282e8970e39607576edb8269a125b553f20e6228287d43ab777014f916166da2d30f9fade050b3337da80dbe26d78e90c57f1ce6cd1be22146cf8635f27cb36b79ece5c0e1488ad849c475d1e59032a91b7fcb9cf8270be7fcaf6cf547d193e79f0e8e0a53dd62fdc1c2de186b990950cc56364f3fb41387914ea13306f20ebec0e435a080de480f59309e555d629bcdb88731391e901a3c6f89bfd6219bafd83fb93b462a3f8e083b9f4c4e2f099310305b695d07b2beb1488905fa0e7d7f9bed84bdb5fa1ae61a593fc2407d5ab360b80c0d2726452118ad5df256a52f89a121f1a4b21ea7d9126d580cf21ed579cd50462d190f7f1190800534e342e2bcf751d9fce487c31f6a73d801ab2643ac264afcb4193d4c1ce4493aff4ba9cdc09a901552d5cbe1bbd2143e09621cb9e010642eab986dd1119d6ace80a01514e806cf78755a387f329e65f58b9a96b6f58811d4158d443ae722621f50b06cc17fb90402a47231c7743da495d7c6146781bf72741742c9f11a39792bc99236bbb23e56bd624c52e02f93d4d668200349a516afdc3a236fbf6fa2709f371c05e5ca19ed40fc30607aeea624e94500ec5deb793b3a1e6023e39be2bf4902b14a354d45c8c1f90e4b2ba511b8aa37c507fe4dbb6b51b439df3b96f433784cae19acb6dfa58c5ddc5e84c7a16b525293f8334cd59445a0df25542b3c19de38d090db860191e3b403e6fd2d198b1ef205a982ae69407c72a2d6269e8449f0ab005a0cd6e30a362e24ab209802d4227181311ca95c65365811902518046540e9228d0426ee0cb6016906e7d517bf2d291c8d9deb735530cc3858621c07af1d090fd43dc6da8ef32024f350bfc4c066985f490715c44e5ce0dc6c1f2d919630b0a0211cf4dbdfeb50dbe75a9a7a3fb2a8f8bedd073b7e948299cd107d34655c1518c3d68315ee688aceacb0cdf4719b994d61fa26d9f8725bdb8a1e5387ca649262201de892103e2d3a38e930dbc8e9653f6891e5b5a3a5c145c4f9c12fbb433502aaa921f5434526a7ba9ecf1c7d88c70dcb3873bb9048e381af96d8a5d54e101438339673ae82dbf31797881c6826d9cbd986ac74f7f2d76f4913291c6ffe4b5106f1c34d740da01a348faf744afa65c826cf5fc23bd82f570ea0a4aa8656adcee40ac53afd9380c399f8341815789201bc97a89b911a31545c854bd5f4207da1d421135e5efaa5fa65e5e44228e660908577dcb47592f5ba90bc39a8e702851799995c3d1669e06b8efbd205b7e88fe6537cee1d26824ec23ad6a233fc12b6851cb41c832dc38968805a8cbdeb182f886c3b6b0e9fa5bc1fe93ca8b2517c73a32137029c04577b13dcd7687cc7e494caf56eb19e18d6d4c47f991407f021ccfe642aa1b8d5c4fc60213ceac231ede9a69570d986d61ee0919f72199606b3b9b1f3ea9fb83f5fa246063e47154fa243d02099d35a01535d51c0a27fe83bda56bab302fe26daf77966d723b8066232e475227ab8018ae24d387b12782491d82f00432f3135733451a8852b2337e8535f95a0bebf2a81c7b28e22fb6c3a2783c9068681da6e27184d33d1cd7398002fad3a793cf4575ef41b8f924617e2d7a4b92a60f460337d19138a24164abaa4d9a3b05b030616d32371f100c8f388233f81f5d06b48e2354307f25b2eac2693729e36b717d0779501c55f5e671326f084140f2898eaa7dd20efb270f4df36a75ad0a1da25b4dc48f09bcfbf60fca8404be6cdcad4d2e51c707ea673b8c430a1bf7ba569ba28c8021ae89c8bf13185381f11c4e07f75aedd58b0efbbf580ce0bc9e67763a345754806951fd1d9b644c2694eb25ee26a7953e6fb0859a206d5256b318b4de2330c5af8cc7faa28e004e6c8b62e7b18d16d0ac7c206b7fe8d956893973d1c3add8e3572fef0fc4d7b9ec62f4cfeff6e742645605026a18071ab74ac41c86756f818fbc15aebd952a92901f6fe11a85be5e2c39ba4af4d339f2e72d5da3d4f70e666b9efbcdc8c7c9696bc32b32763fb992bc91ebdcde3bda46d61085a65ddbdba91abf2ca13bd9d9e84f0135f107dbf02c8825a23273f29e74bb012e974e5734640a10c56e591295e285cd8ef2db158fb11b9db701ba09e6fbb79328748066dd381e44ba155fbf58f1874444beb241f223f2eaa8a5e0e9e7473692423e49d57d134c5d805ffedeb79079b76f9dcbaf7fa7924bf723ec3d920bf72db9441b09fab8ba402cc38018e79685f78f08c57530f359e796c9623a593217742503d4bfe85291fe3710b955a058f2aecb63d5e617dd3a098f1e19812e94bb692561ff28e32c90e815635a09d06d33ae181b77af95767c941c85fd6b37cfd3b415beef5f4da61fd1bbfe0babf907e5d7f3aa0c6514509b1bfe0b7db0f1a1da1d3b7927bf2a45e9f9d649a954e59307f28c3e997a51e707524ac78a28c3e20d592640f88929584cadd8d3e07267f07fae4ab38ff245789a9315ea54fbfe38be41e22b53ef6a4c1ec048f83d71d000c90f9d5813a0b68dee17493f81e1f0ce88a4511b9dc81042beaf60df6a8c14f53e7414acbe7459458d01fd2494c6d4dd62fe32c0648d94df7038ed48877bcb00134e1daf0c27314d9f63e9f3c062ddb51dcf09d820cfe0fe21bf347f973416f31c1b305a5a22319e57c94dcd2d2e47533cb41cde4ad4cd0de37ee124f0bb48be2eccab57bb39a5a6ce558a965e9da6e1209269494dada75e848c57865f48881782aef44d24c4ca45c23ccc35fc8bd76f4baec8c113e52a858cb8edc96234447ced1bf808d8b4e6d4fa9139ba9ebd7685ca5fa05604101c55dcdde43df3fa89bab1be1e9d8710e65c5197bca642094cf5f909746fee8a5a1079942aca42522bce84755b53e6e38dc8af5083c42ed5c4f0f30ac9f0ffec1efe21b3d437415998d7dd99a6bad0966343b882d87b3a03d65093bbc6d0face1bcf00de70eb9779db84f0450fcceb32ab3aeaa74971833a4376f66435f32f85fa5b3c0d933f8adb03ad333fafafbfbddeb9000a8fc34f949e19e74de33f856c6bdec55ff42264b169d790131d3795e935c3d093a3fb04d7339cf8f88d0384632421461dcb12ac29ba98fed26f3843ebeae5ea3ec26393c05b98cc01e4deb2abd325acd56d3300e05e7f14e1fac0bbfd8d068778c58664ec493e6c28e3fdbbd54026f00b341d55e1e8fc36224217e41c41f7124c68ff296583994b1115019817a6c101aea9a79eaccfb0f53ce50933f1c3037ddcdf9df88277422c088bf787eca8d1c529666ecaf950501a8da4d4077bd2073eb053801da60ca5c0f4e605dfc863abcf85758fcb3707a2a806b15ff7b124b8714260968e43fa5980825c4d4ae0c6ceac494c8f75ec131f10e1ba54098c37f2ae57443a2699ecafee9257e1af7e0dfcc86f226e284cd2d95fef3e1af985f36a355797df2678c600104f6c9572a3b03d2f5bcdf5d8e7233f9469ce76e6f6ac3740b22e4d668daab1064b4727aca5c4866845e590737d217fe414be75a90c275eeb4824c7f9581cd6021d23b4c4434256363beaf0d6cf5e69bd4a83a545fe746940795429369f46df062f9091cb15a0645fc7cdf35f2c5ffa96c66e4e4df3cd4e379cc804d48dca506efe11e1bd1fa083dbdf0814c1e04db0280165589944fed6dc9602d1757c7db0cae629019945f6efbd5117be0517d7a6d32abc182989446278e27dc61f2f15be5daa4d186eeac717cc7c59b991a292e428ce89b54d8ec2dbba933020eeb4691ae16da9e8c8f41131d774200d0412e416e5941d044b86e66a9f91c6263c9c5b047ec7192d2c7e4e4fc5a80b08cd1d2a90b9e2266e45d1d226b7c89b7c83edcccd040492f9e43efaebe36d60cd1f106b92bdd64cc278f7c5f633a3638b4a278fc1d0267d7ff51080b3081a894cc04357ae1a9af24a44e93ad3debf87a33adbe72278d7ddcfb7ec0b0af15b7040981eeb3f4de95197352aeeb5d4d43f31b7c5293356cc2ec9ea6c9d61160a546ce7f2874128501d9b0015b6a888aac12c4f5869e35cdeda204f23c71285b13b3d698880ee047f322df4dc0851892a83f944d8860295d919d061908b549fdd9c6ed458a6c2d82ae3a26adfd349d8c5051541ad3814aa9cb36258a212a9554359953eab0b0b2a965a73711e5b820d383b7191e3cf9f2206cdfb036f0e74e27ff72f166dfc023139db8382e96cfbb7c6bae85714ed525ed7b5e9063f39593d6aa1ac4cdfaceae88e46267855656e5dfa80f02a4a7855d7dcdaba1c4b17389969a91c16f9f7d164200a0492051e0f124b43497a7501bc848f064a3a5bba89b55877abc95d12f955471bdcfe2f8e8868996d85046ef59cf9f7a2499efb359e00988b13540dd05bfab12a82dcc71f6c94e4d2dbb5023466bfa969d2c8d6311c376da973724fe2e5e2a022abb213defb4f5badf49438b2b72ccab7e1741d3d3ff64f684b4f32144e90ac106e9d9eee0b5a1b3f55d5d2f86bf9358986910e9e52b4455502ccf98b3e84ed4f507b10823c250397626601c5e7ef10a6102e2e69c865631757e6ff042e6bd33c817487d14062e8c2fb3ff33b433e81c11eb45d841e8b7f3210f7f401baebb097f167c8cb0f19b3399e1bd16961946cc600b4027094fc5918fc022464de3c6a9f63d8a8d008ce85c3643588d5ddc0a7a9e4251e5c0965f78de5c2af2a1d630a2feebbd2a2c56c743dbaa14623669e4bd84aac10765a0920a0e8e24a0783165f3d7a4dfeeb9c118331548cd6085dd6a1657f914b673a43d382a5c94a1533100c969833211b2cce2f7d4c0e8a2b6ee43e48d7ebde490fa558268c32350b3f37d879e4df06280e1e5209dd02d6228ae1aea0b6a2ba1be722a5b87e54e8e040716c8acb74a05cd0fd828591d64cc8a212222bb48cbb33287d61859900038e28aba3aefa8127d37b331e230c89e950724a320a41d57473ac560ceca8be6d860eb3847570bb218fa4832b8383f1d07c6185cffdf4fbd050cc5bc3772627aa0c6c41dab08aa0d0e6606795c0f9312f8a3454ec4174b923aa4806453b5ba290516b975354f0f7b028fbc1837d4b112aca56a0ef542537e27a097388f30c19e73e0fa5fb5a7d4fc442e37ac9fc100f2c69202e8b0761a81ce2663b996f6537bfd80db0f1def2f6e53cc108a93a878012c09d22e99bfb6e8d6c6014e73bb5a0355255d69157168e366ff6f9dd84a3f91211bbc43578054f8d06aa242e00ebb4ef82810dd9f9f035525e62a06a0f455669a50cb20aa648a0a0a193a64281e0cdcec8e1bf508a5150e8c151876dc17ed5cfde5be063a408588ce1b234cde7e1c70cea13f3a9e91b0244dd6a07566b216101e78fd5d4e2f12e9a25d24c292311f001a348c5499ac580f765a158dc9ccde2b6ec9c2652ba639a7ee2239871e58c823f091b79a35fa9c7507bd62958388e10dc034d8a0aff79bdf919148efd6a943e37af41d02b77d6878120a5407d20ac5f564d3bd56b4b424379570b30c67b9bc76c0dbafa38e0c9dad206ba459710a77d939ad932c89bd9ada06a659b2ddeccabf256411d2201bcf18fc70f6bb7086eee165938051474c0add2e2a7ca88d09322f89dd192d10a9e3812e1b4520aa531abf09a9dd70cd45ce25ed875d875dd7c57fdf601bc9995aa874837b6e362b06ed6a451ecbc7c4e2153315d1b7e8ab006b63b625bf07d3d61e542c1d8d93a1e29f59eb779842fe0f8d53ba9f2050adbf83f55d4a8a2afc2bec688af909d3be772ecac5d7def4db22d562754957bcefe38374333fcca04001d4643a8de12952cc63118ed831af16c5302a8ab1ba86d6a50df16db9bbaef1c9acec01aecea33edcb3935d44ef725d36215acbbfefee97589f24e885746fc17c30823df55662e0b8a8aa5cf7b61a50d4c2d4a01de0b64fb861f5f25c7e6f650dd7594ae53261d5fca1dd0c3697eea9c17169600caa1a4f4720890c99bcb0c881a3914568814794e35ba664d406b1ca5a98482a9636ac5f87a48f8275a582814c580fa7de9196b85d04f99b88f6973f5444ee47426e9f43f7b039cbac09a562c2164d781443dcbc12abc25ef8cf9720199a543940b26f252cc24080edf93d2b9ad0b6946d23beb2c2c4aec216eae43972d4281a903ed104bcd4d329565f33c5b4394cbb05798003a042f92a5614d9c88c6312c2ec9f9191984cffd259aa02fa7514221eae4b4cdd99df5bc65d28e427c822c53ea9124a8632c294a68894b8f9997f1a659a11add9f28f4a067aabebb2b2f6155924ec76e4002f48879390a1bbe4097e639dceb78584dde6c7a1c6e2273bc45385373af6a407c5aa38854ac4dabc52c1ec31cef84ed9b9b9f78a0e72417d433386ad13b54e513c74a2d7c03a536abe3e0d60e0a36bed58a0c57beca67455b21f23d6fa6eabe63d742a39b8db660c02a4ffd2109f9deadc315d2f46ed6947e7a77783c6a9f1e96f4fd17904b8adcee813c2edcfd46baff928d13a26d0d6e70f012fb6c2c558f7b75498b19258b5a54895ed89ef5b0952132a5ede6ef052a0c39d332a3feba6881ebdab30b14646638c944f10b4a8a23fc2acca560eaf703a8be92aab7a374ad7a20493a559ee033e5d7179a3420ab667c23b92e090946356e54413d8a3f9f994d4951664902f087a7289a6526cccc3427d25a329223b7ef7cb5396146589679f0b8b0f9995420d86e42e1be8ab86b5542fda258a22112c38386ece17dff317f24dfcef2391f6fbacdb7eed273bf5eba5078f1adc3cc217213f9f8fbb44be1f7b76807d2fc356a8f12a3af3b4840f82e90f955b6ebd0ba01dfe48fe93182cf46b5a49a8319ae2a1e3d2f976544ca9e49904786e083557c3fe746744a55168afe2b995307b9f3a959cf67aef865143f5ebfe92529fbbb13ba7e4c62df270744817b8dd421bdefb22ccdc022caf0b3e623c0ddb3f26d2540fab3960b928c1dee616aa0943a661d0a00c0d617e829ca59274176ba3b03e376093d4779a3f5e31510f21b22f42e0a78584ab30ff9f46209a7e12ac47365a20e32b3bfb7ffc3021102cec3da550c45cfc3eab4dd773a75f6776fd784dc7c7a3d429c530752ec8665a440c484e5c1006173d9206fe3ced1f346176b0a96471c8f37dac4d9003fcb276e847edee027e111cc48cccb170ca3180eaae9eb064c16cfaf8b95c60688856c923a5fdfdbefa2a36091efc7389c874386fdf96cf074c0a219df3c8c2ee4b7dbbef903c812284a8c1def0e0cd0217a02e7d090a303d7a5b90e60fbd02075997c215d9120a01d96617a41789bc9d444b2ca31f7c02115e3c07d64bbfa66c31ffbf03d87b01d808b6c4aac10ac4144633f0c127254e09314c72b70e591a6bfb3fae21bf1398e2460846e693e940ff6e955fc81c995fbf7dc44024396a20bf9456db6b7178a73e7d6b517a76126a315adedf207f48c3f23c87f715a4774dcb888518cb737328bee0029630b4c2221641a88ecab53c13d53e4a49cd99a523cf084a39c44718a9c39e77abc75cc52518e258000908b4140d1e95155572f9fd10e4da92bfb20fcd5f05b1da861a0ed2d4d8db360064cfac216d9f6c3e852c8445889b7c0c75baad55da3d0bbc6bab11c864a4bd861ac1b2ce33b60a1297901c8e320c7065d915214dc0dbfa353ccf8c9079d627cbff24acd9d606c5a083d99bb4297ce9c8ac03b6702f6336acbcc78229d4e6b8ebf970445b6f13770f67ea19e1e331652135ea579fa83c0d19310a8f1c56410d86270b3c3f34e3d56d6f1b0e729d777719fd100970bc5aca1739e2fe874338448da3ed8ec3b420232e5bbb7e2047af4a1fd2c9a784ccc3bf9efed071d620a73f642e2c10a100cf2fd7a95cabb30683c3d35f01eede3f664be3f233cdb5f9c9ba4532a76ff9c116bc739697b59be0de5d853d373f6abbe6693f6cbe8a3c585663630933bab2c9cb62d1990791a73e9c930a8bcdcd964afd4a8070101ce5036e5c51015f37e763f4fe054f519d52b3af08939a0e1737eb8d1bd0430d64697e8e9eaa766a64176ad72d9c368cd9e43bbf5413b962827988180f7d1d7eaee639f025c6d90c9d38e9a8984edb54f0db9cd130cd04d8e8cad9501b337eb06af41e8f1cf8dca1c6cdaa51e4899483b2d540020a840aef48abb28f921b5fd0a8cc5a7a22705086d2801dbb142c341db6525d9883f0b29a9ec79e25e3f4a91320dafc1c8a89482f14882978dfea24f9a704b90745149931708339d30bacef9dc424315219ebb52473ba00cbb4a2cc3cbbf740bb26eb769b098841f2fa01c12e7ee19fc6bafbba694b5174fa1b158d773f7d3fc43371f40f35926267208d9f358a88f713ef006ec416f56cb48f8d8188ef2482bae7c70b714e67f9f68ea11181a5030eabf0f89076870baef388a7114a4ef1d8e9f6888e1bffecf83c58b8ddfe7f1fb5f4b5b598898affa272e74e756b1d5131cddff09e4c2156d636821abc50228b70e50fc8949de795717c6ad8e32f3666d2d0594c1028be824bf9480438a807266120e81e2f677e16588ba225742039163b980d7068a2319bc84f99e4a5aea44dfb6708016660d4b081fdca35e50aef2023e0d8a377650d676b567f0da3bf88f85b00911076559dd6363b52950ee26ff84e024c4bbf008d85420a60d1d0c072666d15280a29f61860ef73b191d1b9dc353d7da79da1b63763a9684d340a16f816b17fd27e8a6afccd8d9a83629f99f6fdebf92d2bec7429aa5da89b964627271891f98fbc60e6f935ff871ee2d3a691dd96c231130a15e448c34474c0fb22984cc09e95d857e417407b613d713551277c1c2b946e2fe8b49a0ec7bb7722cadd239f3ed34ef3ecefe9d6d1f0e5ff772f762bc7d766fcd5d3eb3f1dd8ca01b0a280470b6932ccde6630e2f9dd3d212a7cda07e1ab8f63218f4422c717bd26b945add588c9944804f4309ea331f0c2a4340cfc462e3e921913d3c30b2634cd845d09a2201e23b8408676af8d8c9e266a7c42d6d262d1e200442211b6876d4b9ef7efb0ae2ce18eb50522ebda62b10e76e8c59a8e549a5d89ff9f3d526354a27186f92828d830a6280739eca68b99421c7c69b041ec415724f940c8fcbdbc0d6964c9b4e24d353685c2fb1bfbd60d8638f8e37591d7ab3a723c7f04b2300a3aa968137a00e8cd4e9a73aa086d2a71ee6c17572bb66cce65d77968037077999338c56ece3f3b1f9d37b27a4109b89771ba8b22694817fba7d3589ae022b51da7dc814475d50d2f25db0b183d77cad673415467f5ae84b5dd488923483d7fed4fc27c6528ad1aadb30a6e5741604adda09e0bb17c9b9c5f2aa694a489f8f5ddd65fbb5a9b5a19eb90bf5fb42bc82d2e58253f4782e5240e7bd21f85b2bc8b082e94e88d7aa17fc488dfdd74f17bcbf3bd1ee77bf900f6ad306bd471318b240ffe8ab8b8de8c63c7c4d0ca54b585c06885973c1579a78e0af4c4b2d1f3a5170cf2ff88a3c528f182a6a4e4d70f109aceda3703ea2d0480f5b4621e6962bd11b92280f4513bf1b8421d77279b1f699b00b9d4cbcbd339394e78558a678ebce52e973180e0cb5f69e49055fca9d348d517963f062c2847c992566b0e258152b0f7660331a5b5539f201ca8400e14fa3c606bcc6b17cfa3b8235d99e81488eb80d7d693eec6a1650de61da495bc6677710bd88ed397fff89df8019e824f311cc46f1b563b24dedf6f9904652b3c036cb8aca9e50aa0b069adc24a819ae7b9ff3919fae778c1209dd9cf033a3856fb247b58fa7290134a70cf347befd96592005b30742d5d6da30220cfd9ef302a9edec22bd2c6108c66ddd5332ac241e895e6da402bbae0793acc3ffe8836e488ae41d4026c5e84fe89b30d48410ddec5208f5163d193d3f53567e0c970d29fddbe8c0f5dc6b5889dc64950062c8d6121ef77a8df466bd0744328ad684af186efc6b503740638dde679ad9075a888e82ba319389396f153c7a06d3e40228ec3edc8829368801892f7c8a4a4fcb64a6838b3eef293b6b93044388c36519903d1585ca869e2698883dcd7e0e736b82503674a41a4db114a29159d2a969c6c4960d5d4968f35056497825fc0b62fe386ff41df154ccde7e9f1608deef5eae44f92d6c0653bd02157f01dc92b3e263989c973076c62eabedf5482de9b6894e07343a5504b43c0a714183603f9a772681691ca06177c4858f0364112aa0202cd0686608f6ef6c2317c71ecb9420c14ce9b613ef37737c38498582c9096e678a6931b63f221ac51a88151049989cfc5e26cf5ff5a985da4765eb9b9aba0935b9aeaa111bf0c0fab80197143fea65fc72b8a20c92ef3e1e95f2f113964c62045d927ef5f8e6d6ecdfe1c1a61d76594b733aaa0d2aa5faf37d34b5419614747d3331019919ad44cb61e9249a64f1963a31961eb73f3fa241dd0b6458efc32ed027ad32001af542f88bbab901090bb050ff3209ae60261800af87a2b48781f1be9e217e73b312f65330199c986f0b410c96084e649927277a5821ca4fc0331d35e5e01cd2f9571e01be71f6e139ccf2955b7022e40aaa0b41231ecb04990b9faa8130f98b85fddf9d0104135d1404d345600c2a957224f54597bf6204f1c1c21ace37f53610a894f7d31b6157a926032ba6f10f196fb234ec92f83c9cd4cbf6564fb87a25373110262e8b1e1f0668039e15d3b87daaf56fffb89d8818e510ceaa04544f699ca41269f05f390dffc5a35bfaa793e1c855ab26e9ee94142d177b21907f16f1aca278622b8ea5cb3ef17e54581ae544affbe98657c34527a33593ccf329a87cccc376934032f810123119b9614706a022ca15c9e123ab099bf403d4360b851d9a1c9934e0d0e036623bf58c84ab038aea1a0f0d7b7a35eb1443d85bbde344d60673d47586833a43049d7936aca593c56912f442743ce9ba38c3f9edb0beabc760e53016774506254fc9066e1d806bf571b59e717df00b1ee9bd68f91ceda0f5e5e545055fc8230389403da48c1917014673d5003702619021c2081b164935cefafd5047804e60881b7f80e53feabb962d78fb45a987f49e78095bf405962e43a480f41fb99e1b5f011bf083c0aeb0c15f0f601104dbe20e704e82fcdfad678f62f63a6e6361ccf9fbf958af7bff86d3836b969e4b698c2b17ac5af258779ba0eb3471df7bf1ed86bc1dbafdd0e14e90b34d350cd01c9756cdb02e2678329ac523bf59aab524921ca61b583d5326c1d6be6866cd1ea0deced545f4483e5fd25cedc7a1e3d6d9c25c9419b52912d525d1c7a59e86dee1e6005727e8ccc3978cf9273f636c57ce75f014ffa255c29f68c2adc6b7d653986b064e5a7e9465e948d732a3d74204f3b5aae9c1814ceb47b15acb23e18aa8d6988fefe35a7e4cfc59e7b2d2de629f88a5eb3e603d2af9710711245d87e6a8da59f5dce253bc5e32db106e94a2d52d1b7b484aa9d4f4a602322a3462d11cd901ebf187b29b08cb62c603de9485b035a7b7cc88538408646033505409f3dea700264ea5c95cd20bdfb0e5f068ec36048f207c39e20c5a15f80e01b646e49299f186c2f3f17887911b72b338c07e6624754e7e03a1bbe95c6b627da6418a4869d3bc07c090dab8d810fb844114eea05d018380a33efbc47ea4fe2e60af20d909fdd3f47f1c6733ed55a14fa1c7ab05c6a5dde27880610484178df3bf7303b8d853e422c01a063613fc2f9d0be43f03ea428e765d3050ba9a0e453711f16fb08caec595276a9f8736024819a0896e708dbc4c207de2da0baf7d146f735f29db8a73098ea78b195740d82a541017424438c8c8586a40170d7e6bbc39bc1da0b0d785e753e5f6adc9bdf74a6b726f2965923268074d07dc0655c4d440777bd666b8d98c72066badd5fdabb5566f159b7ae5d81d8577ec2986911846621899734eeb3fc3e674ee5cadb6d6397b6cad3fb5be7aea9cfee274e95ac75add69adb5babbbb0c30540ca18e90a9577b39b0c3a7af029e7305e76514d622cc79de9c9ca2cb28d445a1bcd3e9240ed5564d6bfb753edb00bbb451f9e4d1b5e53f34c4e1d13ff03d345dfe3160a0a91e3377ede9b96b336a5207eb3884e9f49960d8d50c2de190d3a10b869cb461ea0ea554d6f6cc5431af9f3c545b617d592c23e638ea5f7b264489437ae64f3471c849bb87cad7eb872acf84551f9aae72de86a6cfbc6941a6d618b7d65ad52a96aa74ea5a6f686d4e159a7e053bcf7e39b7db4dd3e766063c3a1e61adcd51410e143950e440a1e9779f1385a68f3f278a4c766269bdea3b73ce69abb5d6666bad2dadb5f6f3e657476bad9d9352fae3ce9f1a7f3d9c9cdf75e56c02394e2c2db927165bafc5be3329a5b8524aadb5d65a4b5a6b73aab0d64e4a29b555acb5768635c55e7be9f50077ba270e45e97827796f8c17642e256a4da7cbedb5578a6b9f68b1578bbd5abe6b6d5bec96bb858ba53366559341183415b798e40dedc5f2e4c9b54fa8d8fbe4c9b54fa8d86befb54fecb597cab54f7cb6eeab505bb5016b474be5b68a70dbf649f1cc9e6f299571299e63052a66cf27e90ed2ca57ef3b061639a5fa2f4fa9554a7c127ec74c195da98ccc0c4da855af12a913d1488fd4c88bd17c6b65e5b30d40803d7fc4279daa117113fa893d1f8b3d9f01f3a8d41efbf2433ff2a39b1dc1ef83ba739cf86278ef3ba71e1fef8627e6533319a023094f68fa25ecf8d123c8f741dd7504529ba9ad984f840a8b19694e0a34fd92c6448765ea6991de7b67be204da757d88df970d4641b80351eb501a1c6a0e9d713123e12bf58ad3e1ce0af3e107c9fbec663793266602034e6cd21d47c08d0db08420f983ea7ce66a3351c23212161a135fcc3307cfa35043f2e1e6af413d7dd6cb7b761242c1d12878445e806e4b13e1cddb33e107c733266743d6c388fe31bb1d6f48022d11a8ec9e9c3d11b175ac33117fd00e7f1a3dd61a47fcad11b173c72e9093f1e5e19070747c60c8e3cfd3c9dec3e7991cbd8f6f30c6bf30cef677c38eccff840f039edabdbf3f5e4f1d89d1ed01bad91125faf568ee454bce5d4038f326bf85fd9fe788c6d2762bbcc7bb8f9d174f91f559fcaa3fa72b5752aa5e2c0a6634ac4540024d000a09919dd063a016c40b1f547c2b5b9a8369d95f376674471ef00ee9d5c76bcc89065635da464df5f15b560df7f12896cdf7f21b162dfeff19d594b22c4beff23c3be0f746b1f1062df9a12d9a6624d0628d87af15aafa8eea1351994844d47b86cee2df7331f0e2e0b9702ce88118f91dae67e7504cae65ee635c77d4f03388ee3381b45be6cfbaa0f8775a24896cd3df7a91a13319c2089224236f75a0b07030c9b9b6273351858b0b90f3f1c9ccd131cd3e66c645e90a25f206235c330758999a58cccc9b6af652d7021896d3fafbae8620645009b0b4d889c404c630b111c5ac0b2add5984b6d3b6b2d54196285b6d6be008bcf5a6b6d7953e674d9bf4b1b9bdcdc630d6673bf426273ff5c4d080b6a438cd8dc95cdf5ccc9c9c04ba61f8e3b806d6fc049382a0306d698c41a5b3ce3860fe03471938164e4260b0de70431b09028baa1d1608345c6ba01151fa8c9d26473832d70586999d5c850438ca4d591110dd013b318b325334036231a2d61a880071999154d754518377061865b93198c8040226b12e208d3172fc880ae2c5971a1698919806a342a8a002531c32e40edaeebba6e89db5d4249d7625e1401a2156121483abc05a9db92d46d99755b68dd161ba9044907c4c5c96907241c9012332cc4916b719622599474576ab047281db1a4a728026262068324404d14d556082309500a906a2c202902a485a90035cc5e74d5552ee6882cb427596eaa1db2c840054683436246a055496656d032505253689d84027d693345b250a1250a2f5abe38a18549860a8df7d4a2e50b15171db382ea07cd29494dd12926334d34cd9e5a6a3d245133e26b4a1449bae2ad890573d15e565f1e0cc985b78092c2786b6e9f6d1517b52764b468bba796da14648e19906c4e9a286dfca5e755b418e33fedf93154ac983e74fbe3afd1a48d98fea500338f62632736ce63e94b6cfc355274f7a527e59fbbf4a2a25c83a4bbb7b1d1b46ba2e8249f394d69e322cc8d45f7bbeecb196591cc162e9a2efca5e36701a11dc991307e95e8b3dac29f124f9f2739893fc7047a6efc81f06d3b7ad274e1cfa9a249d8f103bf0b993e73e327a913d4e3931148cc9deff1d325e68ef7f8e915d3670574077cfcd405d465bed33dd6f869acc680f24c8a45c514d760e32eb2d8f869166a453fd621fc2e5e0a34fe86d8185bfcdd57c344d3cfdd9723fc9a10e850f49cc4f88b1736d64e62cd12a17eea75d44f8db3b674f8afacd0397b93b3a2f728f1fb2cd29dedb4b482747fa215b19317754a297d5764fb389f5055e8fafe27db4befd74be6e7556b74d05f152f12924bc0b4e7d78468da73fce1f36376e9813d573ff5b3ce0f7ac69e32eccf7b69d3a700bbfeb571b935489a367952e561ddfa7e54ff3e0a3f6af4a4ee4f01618411c60db68f285018e43cb37572de68d9303d5f9b1238188d134bbe5a72a8a9638b6badd5d65aabb5a7d3e974aab5d65a6bad5c47bbaee3b8aed66a6badb5d66a6badb6d65a6dad15e3132a67cffbbe39e7e994ed0cf79611fd39fd72ce9e73e5b462cffb3ef0e569ec692c23f37defa54070d5d3d201d4614aab625229952a26464666868666b5aa51a9626264646666686862c458d9d8b05895c562b1626662b474909999a1a189b1aab1b161dddce05c1c1c1c8b835371707070701c0787e2e0e0e0ac563536362cd6cd0d0e8e0c193366fcafbc9a1acf864559363636ac1b1c19335e1c3525bade002679e6284dfadee64197da53aa23559aa2cb8a54912a15af94d699906e97fa8427593c1962852a3fc460d7caf665620643f6bd47c840b6ef5dd5a6ccb0bf3d6b5364bbd4ff84c8a949d6440bb8fe1379d1175ae4a636e7d1de06b2fd6cdd392de32d8b231c6fd0e1b66fff73e8bbcf9cf6c9ef41a0ad632af2ccc9f39df49cb49131455f9bef70f19deeebf7f56dcb484d72b2dab14c81b64bfba8cf4eb6683f1c1cf7dc13ed24ce23dab6044fda9e0d988dfa9ffacd3d3fd4153d19336b5b4774e94df46314e6e57ab46ba542a3093d77e94d4d1837616f2c57388f25e9348c6db575c4f867c516e3b2849e8d31f658f5ebc52dd05f7da0086442db2b2412fad2eecc494a6f598d68910bbafcfdca216556ab22f41f200404837e2773cb88b6329a2e7f7b978608ae46bee3458a9af88e13968fbbca76b5a3cc9539496b1105da97860ab4ff4ff59e2aabb2ca4361f46bd1bc6d7a336934d86beb9ad866f8bd89bdfad2374b1dcb39bb79ad6898b2c5b6654693d5aa43de38496b1de78d93eec5a0cb2e7bac9dfee49e5a605064ef388e409724ebfe6c40d5f9f11dfcc276a11148d0d55e72b6ac84610399e32bb0f316a959d2b7e8ca9cb4b66d1f8441df2fafcc075d5e59d155a2a534ed59eb810b1b7bd67a986da7718fb1d6abd57f75dab65dc7793f1c1e89b6ffa97bee7fdc45a24dfd943fd35a4716d176b1b4412a4739dfdee83f358ba8718aa7fff94ee38d104d975eaef5ddb7687f1ac20c63fbf56cee3bc98d7faf134e697bcb8876d924b368e3c6ae2ba4a379655722f69d3cb8b61ccaab0e7defefd36695a028bd26596decfa8050fc6965b8a05f42fb6a6f4567508f7def75e2b904fa31f9129aab15a774c1a0b100bb70398ea3180083065e7459420a2921c0b22c4ee0c9408b196ce7c21516b25420382dbbece92169977336afd47a38aaffaa349d3d6b2208b3f59e351180e9626ef2c67b745c39e94d1f3f4203bd933aafd94d8ce9f29fb1a2636caf3192b0112dbb437dc8e99a6f9374f6398e83cdddf8ad97bb95b363ce74dd59b99c6e5a1a32396ff634c2b6e612442598ad6d25507737e64c97a5404e05e6b4651372627b8a7373b13d45d67cdf73dbb838e93856f47c9a9a3409e5d1b5528e7a3f290f18bee6e2af1a4bacf558d2b19c496ca756e6cc1b4b6a821ed458d2116cff1315c1f6770a82ed762c2993ed5fc7d94465bea39d1451a05bb335b91896b0c23427075e94ec1054c62466a52e6cfa3ad3676e2c2e74b1eb780314995aafeed4ad739c2d57ea4e6b9dd9d2f1da7a6db52b983912a528e54394584ceb3d6b474c2e30fe48c9061183289cb5d67659acdc5ce1a18887298e72080116cea60b143bece0c40e5d6ceeef15008022c500766061736fa980c2a4622e8e52736ef766505a7882c4b637744670ee6ed71525c14728107ca02b3a9140062e86af24b90e280153074512eb80216cdc5251754092edd640d054833ba00a927d826409d293a31b1c6082251718e0926f017364a557ae3db56c01e3ade451095d4e4a77788f93f9655ef54332e3508c2b5af5310f941de527b746a9cfa9d4833077ea897615cb27418ba930f4be8aa058f6d85ecf78a347c67ae3d3c844d64f48d5a31a9fbe7dd5abde3a8b8e3d603fbce56f43440b01d570a38863c1abbbbbbb1299560e77139fdeffb1f8ddfd27ad9def5f79266c45ddef7ceb3f7de6757b44ced6add320bb79f85b51c7dddd4927dddd6bcd9917076bbd5aeb75de79113049fbf3a9f5a739d5565bed77b6daea95029cadd756af34c8d5c3397d68d7838049de9a0430a0038b807d41388901c0ae7ddf76106ecea7cf320014b8fb5614f49043d1161adcb396030b4a30c5a104d90b8a83950e2c0f0eb19d9596d8b6b5051abb81e9a502af94b9b1cb9b1c1d1b37ecb4d3cb6d97f38b0ab8e0d9e50cb324896ddfdac7da28866d7f65b4c5b6ff640d53b6fd179316b6fd9e1f26406cfb4036bcb0ed0b0dd920c4b64f020cdbd69a5cb1edf798b51b86d8f669cc06366697f400439051d1121220095aa274995c61b31dd9aa4811b169f1395b82f8573db2ff19e9b2bc61e3e6857ca75c8d30c43df7372c9d69fae59c511b2fce9f7b72e67041501eba771c268410f439e88b404bf0a79dd8c9f0986fbf136d882f3bb242b03ff7fd6d4344afcad79e7f455b5fdba0c9121a6692e8195e18e955152a21f40c134bb48c10315c74ee41a64a0e2926fadbb34643125510dadbb34603119514fa6403992ffac445ea0b8dc12cc9228ae6f6accd109e67c52002e8c2760b02a6c20d2fa4b001cc7e158378932e3015646e80d9717a07a5b6e2ace249132dc0aa3853500398165a1349db5fa767fb2b0186e2a9c17bad30214416581565acc0ea15491c6de2529bfb1c72380885617ffb29cc5a3f051f4f8f7a6c471d24e9a7f7510885a1de8e43882c00767a1985a17eb5eaa9ad11a8b63811260cf51db08043c87eae41464b3f8514f038545bdcd3ef8005fcfe3af0e8409af0773f02f6a71df51d321c42a7cfa820534640a13ea16c94476ad4010b2535f2e8375a1d4938b2fdfa320ac39fc711ea1864089105c0f0cb28ac7b3b0aa130ee6dd840e3efac5bd0070d83d26a8bc3df8d2c218c290c857a0a43a1be7e0a29a0467aab2dee6be5e8526dd9aff6fd75d8771c14e631eaa74e69578ff910bceb05e3adbab4851600115d527a99ee526dd5efee7b07367d6f8d13081d6d9898efd057aa3fd43a6badb5d62a525b6bb56e5d48bd077e9e6116b50fbab32bffec44716b71f6a8f9bea6e6cb5fc5ee5b51a268fb397ff9e9e7ba79d8f0e08c43a674a7cf3f2a8893bf10e704a24db4c30743ef432f7c4f7f5f8f301cbfb0c7076483ef7963f9a386dff77d1feb83f03dd0f3f2dbe9c37ad5835eae15bcf1bc5a6b8fd8fe51c11b96e8836ece7bf0f573a29daeea7df8856108e4531fd630280cc3f07f6a48c2063d30f4beef77ea3f71f5e5f8beeffbbeef0bdffbaa9681361fc883e66bde86e6c3ef6b6a80d488e08fe3cf9815f43dcd7f5e0d9fc8c38450d814d5377635fc4e04c72ff5def7e1b07ea29d2ebc81ec39bdefc3e158e295e8e3f41f0fceb73c6f87f204a2ed3dfd1c3e6843714ed737e6ffc459fea8294f83558bdd839ef760f54016a86b0ccf53e52c53bff27bf00b6bf83131c499a711651e0465de9b91a9aa30fc7e3e183e1886ddfe38d8f49f8860e5365f38eeadd2a6cf7d0ef3e6b86efc218edd98837bee6dd771dfcd6ed2d8a67f9936fd0f47bd9fa31bbf7e39e87341d6ef5b13e8ae220a74d3fa459e39397722d106bf70ecfe134b1bf48da9fff19fda89de875c97c227aa3e71be6a2cb9f1870affe3aa3135faf6c409c3ea696a484eb6f72ba48d2d04687ef59c98c3fbd4672a762d1e4ea76ff1a06d97f1a7445650f7f4bb9196348f826f1e359f1f87f3033f1e60a6d413c1cfe20c1f0cc33c3f4f85a0d453d04bfd7cf0a70a1bc8ce4fbf0f78783f774a836349b43d8f077d2f259e40b4e98763e6a727f3f3591f6c1e313f770cd57f9fe97485ff4d577e1abeab38ee0422d558e69fbeb3536399df0420b1fdc3f7f73fd5870a5b3f08beb30fba733e8168a7c6395d610c911594fafca991c7c883be170404cb203bf5a907c56a1d0c02c11efb8b09c792c6be9807c792c6760cf8e1ffb8c5a13f977aa7de13bd8add049aa37b4f25fa08b2657e7e4132ef8974bc5af451b7cc7be3a5cf4366cc2cfd319f5f4664e9cf2f6342d018e49544b19dc7203c64e791c7fcafe665441adb74ee70c78834b63f1e34bffa1a9a077ff5fe05d1fcea734ee54f89d9bd95f8fdfc42a0f9d55812edd5aa0c82fff49fc80af29ee6bda7412adaf8c1cf9312d1b3f6836dcf6c3af2e866f7aa0c7e27e6487562e8d92050e79448412d8a65903dbbe93dcd58d24d73bf1cdd4f27333896767b793c7d27d62f077ef04f621e41f06b8540d30e14cb13f2ce0f4f7df83cbeee274d8da5efd47b9f59ffc2c3a6b7bacfcf12a7b7f2a780ecefc3fdcd2f47dedfff388eef4191d5bdeaf3b3ba4f7d58766350eac3eeb518860f82af43b14c7da95363508c67b1b42a0c3f3f28b2c04e64c97ccc779f5722cdc71067fefbb248f32b317f8c995c8a253806d13c0bfcd47f5f821fbe1659e01894faefe7c7f8b24af4667ee66388ded3cc783f4da0dbfb502c65c620d5b3bef21b83523f3ffc1c23ea30257edf89fa63c4ee5562eae717942a89be39370886c0c1a6df0f5a42dddd8882ef16144d7f72ad23eda37bee4fe27c2cd2ed311a67c5f207a753d0e9e41b2596f81bed09c45ee7a1c43c96166fd4177efd94c8e3f4fede7fe38f7ff9515fcae6407d238f53cefaf4e91cf9bff7443d9641f6d30f47aa0c73e41e1bf5df6b31f55a9c5e4e8d650af5c391bdb75f8ed40fffdea242efb388fa4e1fa0442fc7f7de784205d9de7fe374d21bcb3cce47a14e38c82ee7fff04d4bd813a7a043fe8096e107d483a86f3c620884de6fee33fe1ca0881f25e2c86349048447f7fab593f9b10fba518f12ed74e507c512e7387d414e85ccd0ff7dfe3aa44d3f3f04c03f3d16bfb1044271798200b80307ea830038f2a0ff870abb0b72e7d1e3f456fe50fc9147baf307dd6711e7c8df61b13c05a13e9fc61f75773f9f5e3adf004ef4f9bdc2babbe377d25f50fbc1c90ee7a4d45213e8f6afcffd8f6f73f462cb0aa27f9ffae8461434501271e309f77fdc7dc713eea390da773c81fe8f6f53fa76f4d10538c8b0e08ce86084d8440b530b921b1607f0423667aeacebfe0fe48eb1d8da11b3edfe5e90b8c71bb702bf502fea9a812e5fb4ea4c78d54197af6bbb515c31a0ae7b34c75d71d204d63110caea54c1dd17670de7460d00cdcdaeae81567233c4bb615c4b682049ca9d4b0a0da8ebe8ed761bd2faa66faf5bcf50e559e13a6ffa48c764394597acad936d86903c7328b7e793b13dcbd59e74eaf8744cd1de5508f7fdba73234bc6ceaa0ed9f7ccc9039842d317a18bc0e9710a275c7952e8fe747afca711d716f7a7116bea34062f9ac090628217dbdcfbe6c0056d67d5d22a0f8971a5d1e8d7d1a3d526dc908e0902ddda49f23e698dbab1d4c9e5bc716379e346e378937376498ba0c6a9b34b5a44474699a08374a2c326d9a3daf2ff466b4404d3317508899e886bcbfbec8d137ccf7a6310cfbe7f23809fc720f9934a7b64f445808a4061df48d6d6f46acb3e46fd69d6166754de995d122bc65a1bd1d992ff4a2fd9a6a5ca33619549c78a36cdc8fafb0ffac783eed3bfe36a466b0111bbd4fbd6198201d483d2287aacf13f16ea2e2c5cab6a1626fc28fbd2d1429793e9252ba2956861b48303d3e7ce806837a521b0d81fafeb05d7437a022f2029542f0ea88aac88efec983ef54ab99673a27dc84719c976abe9f2de6c379b4de9968ff2d1cd9691bc59ea6857cf28739683ed7946d4833b7a48668dfaf5bd59e5398d5e6cfc00935db1e7cdbcd89193d593b2ebe56e77470f69d7fff1264ed6e99a4197de2cb6eba76e9e51ca8bef5ccfa8f26427db7372b4eb9167b46b4eda3569d7e7625cec72322ee6cdbc594a49ffa82810d447e0954bb5ae2cae8bc8e5a4e0ba77a9409773f6e58dd207ca2ee7cc877a508f76eef017616e4d941419b25f1ccc1a7f803fe95cd137a525a6db74a235e8cf60eef0252aa34ec307127a2ee0535d50743997fcebd2d2d28e1d4b4b4b3b969696260b3a06a5e8d485047c016e14c24226e444975466c354663ff85f99baa850b1357591e32daa230505ea41e56a6cdef333d21ad469d8809464a3224566b9f71f02425f745a837e156f48994c2693bd349661990c17a14b2a7352df3b9a16ac825198d220425d87065e996acf0e0460d203179096fc8147c75b14572f5cfc0616b73a449049f70b11b32f576e72746cdcc8c08e1e95a77bfdd3e904d1d1e081081decc3690b9c51b7722e35d12b1d285e0c9f0cf4684ce845c6481a2377d09c91af8e928e40da2519db3446871479a40e8d91218d22b8cb5deaa2015e4decd88f74396f5c12e92d262a7326a507ca8bfe12937397bb55270cfae22e77ad6b4893e52e772f8d1866d3bc5e93906d0695ba94e68fcfaa92caf3c2c36e65c2da6c3621219bcd2664b3d958a0cb695baaff433d705ac366b30909d96c36219bcd966ba5b46225277439673f0df039539100b58494a4842e6f12521212d22c09b5845a4a424231e11e540f75118131751a514a1e9ee933ab349834a9d6b50217b6db55e22e77af8e0bf4abe7a266f0638552a16f982fb41f4a63051a0d088846a301d16834265d4eda17279b56a4cbc551ed72e5ca152656c8c20a152a4b9ee05643362f4a230722ac12959b141b94ed94ba16af4ec8d9c2ab02f80adbd594d58b882b58b878d161d38f02c4a67fa7f077626ed92244807a60af5c8ec6142e5cf8cef4a93fc265b229d7e94cd1619d27f8e44ac2bfce3aee07eff1358f784d970e0eba9cb7cbd4642bf19d3a7dec439172a95c228ab6cfdbad61b6af110b0a961fc0ec89c5072e587c30228a21372eb2d2ae444ca5ddf75acf77885a46e8f232fd709256d1205c71fa0e91fdf995f452995f50f73297a9b6301499ded366a48bdd45c99eb62348bbccb75d7fb5a7ed88d12ee9b6df75dd13594c6467ea322d55dcd9ac04025718aa83c5adad77ec7175a93b767d1c25ac7a681cb1ae2357e709cf658356f29db2a78746a371401d108d4603a2d1689dc35c55f46a4f5c238411484f14a171b7309f437556e035914eaeaabd7af6b33b3acc858326ad40d9faa74ad1f66f805093ed7f630825dbdffacc06d9758c792cd03da99f1933a3f30637aab4e4fac267b3d9cf9cfd6ce2d9cf260d1cb4175aff7ed94c78490705141c3c50404701a79f4f5aa0f29cc6a0d9aa3f0d007b0044d1f6b9b7b0fa3d80d058fd21bc69b2b0df510f401417bb63100817e778ab7e0eaba608fddbbb37b7b9746b5d11a08ab6631109ba9f39e54b9cd355835edbe1dbdd7b7dd43ac5ce3b4a5b55f4fcf998d617cc18ccdad47e1478da1a1248ecbc67cd8899d1e98b4a290a2c60f062430d4b47b81778b102a7b9219ab20984ac5093c20a2ab07851f1c4eef6ac5181250c6c64841630e182054c2538e20517b980d2161958b182165808f12b2de04064d6a808e342e2059bbe02b0674d0b1f36b8674d0b27572cd02483152cb684e9f203cc1ffbebff2420129850a2331a107597124de8e564dbbdba90d4a12e96860cd5fe58b94de8a1cbd15882398f924056122a4c078c2ea75218dff19dfab585756a804f349e547a803d39703b3462561754f9d8d5a4ef5fa35d4e25eb2d27334ad4664cb599129b65072e6c464db61a8e86044103145b11b04ca17802a916050cacc0aa38b7e8024667e8e1871a868065eb5971002000a20a0fb02ad2102801cbd70bd9134e7041e4600258eea64081049bb3208a4802cba72850fc80f2ac38c17811032b60559c2e38012c67cf8a02f8e22507236055a4301401cb019ea9a804cd1865358568060000002001a315000020100c088522915014a689268c0f14800c7188426e52381a8623418ec33008821806328618048c014401828c52366403980969f055d0e3f422f42027216e65593d900d1915e9498e863093c76fb43146057df32006757c3fe2ff1780ad5c2cec58f95f59ea5030d6caf9759a8085d1c4671d21c36be5a5ab08616eedbf1f0ebf082508fa549c527e03b9010799b61a9b8bc8ce0b4a1f0a9675cd8b113f42518d27081c91ad4795676894cab8ba98ab11bcd650c82fd9828efb263bade1ae1167f423ebba0a72cac5b67a90e4ef32a4318c05592298751d232e58594073a25e80db4bdda5b64bf834ab20d900a6fef8664112201f9fb80e183dbc9651beb414dd5b59ce37b1dc6ef754c2ad9bf01ef2dadfaaabfa8e6fc7d406bd3468bee0f617b7f6310418443cf654d88c058f3edc657feb309d8d1e11eddd1d12f514bc165a0e58646fd21e9d201bce90ab0d6f9e0268493636d8b1573a559d379a89f851cd2f9a6646b3cef9e482d4834ab2aa7c008f359dc71ffcb8218562cc5bfa437eae15b48013d93a7ef95672d921c7822f89bd2315d21bc9ee5655d68254b1fb1301936373697003c0113a975efde615b434545552bb6fa1ab1dbd3cad9366554d32155ac3bbbfde0a3d9f0add7275c10d2fc1916c2f1e9d3f4876377e15788c9d8179852a2996adb0750e8b4bb861dd276bfddb58d1427f4dc5dfc8d8d0719dbdf7b8d2096f3f2476c8b40aea8eeeed7ae909008c6c7a42609945be9198c7a3471751302a6cad801303d23f26fd3b2436b9a7b239a4917193b4120493f04a295ab351f16b7c7183c40a94084195bf24094594bda3a11f2b3edef197117f1603fd0cebe12346806fc26641588de045d06dec943cb898b432d5d0fceee54d7ce52c1d24cd90fda14654c4d57a03b27a352f5d185794531d98fcc129574c486a1031c86cbf58ae399596702bcec955507d722dc54645481a28341d2415588dc15d70bf5a6c74ff224f913f8ee6bbc82d10947e573daff92765aaad4dddccdc880849bdfd7921a33f26250d9a85a471b3d5eb1f4b4ac92890db32daf8abb565e56beea71af348c1f8febe3a68af5a350d534d8e109b007d58150018f33c1ead6ebc325882d0128cd07054f8183f1ae0e940011ff3fd2df43fda418881dda91009133d912f24cb617c33fa89c87dafb584484950bed81e7d903d4e6c5ca4a324c217e7aa42e9ba848dd386dd87fddaa9c4445954db003081e1bdbb55fff201d030b5a19a7d68c8322c16e768d8564fcd66a74861c31574b4206c9be4be638dab6695184dc4253fba4a756b26bb9f16f9b3acd3b52431978cee9c0a29896d1e26428f5bd6761e18a5e90ac6661af50beb98fde4909e15a1d8f6aa41722c8b69b597ad75ba3ddb0b2314c16801b19336255870827f523bb2e4e823539dd12ada6443e95f63179eaa0f5e44156b2d1153e7b1e9b9ff835d3ddb8949ae7c388a0414862c3fc1bcf9eb1398a7060eed99bc85b685615fb668b4f120eff5ee3a045d2bc4e5ee3c921180b20579029056ff2b57a4287a8433226939a75e8a1364ec822f5dd37d1f8982d67a61d212c9082b4ea0606bc7fb780b92cf7065340040330bc4f031be3ca8f0caf139e0b8208c227d4df909bde7612020095d528b6c13ab238c85ffb3c72e0d89a8fff4631772743f1c1dc06a0ce62fd0b99c7561f95efd7e5d12d170ba45740398ae575247393ef30e8d4299bfe146e2bac74e8b15f8414bdb494312b021de76b8a6da88573b91bcaa09912c6e6420cc09b08289096d1c1f268e30d642f38dd56b3739cdbc606fd263e87d0543302454d7910df1c64efcf05278127b24ed63ae7a53de9134c71aac276c844052922001b60b2ac488eff304e3e551576b8d50763522e3517c7559ea99bac638c03efc4e234b258f985263be6299af4b14e777a61e4b714b3d7cdac4091affb2c08238471a0ce3401500216a28e72dc014f9285292931940013e0fc51eb9aa48848e647d17d949571242673b7ec4447d467fc48c04bb9885e3db3e3a49659123c32a3e277d2e60f19bb2626f8a3c701f65aa4db48778d991997545ba8144a050350d9f650731b30003a218a9089c19772b69a9318dcb15819e405ae46940751cd22355e6d830390249cafc32d699cf11ca7c5af334ab6ffa1f92a2c696dd8760cf5e2b37f02249001d89a4104c52c5f499ef9642336c22f12e697b2d202e415cb25b47b8faa371eb1e76a7c9820c3e4c8506429a72d4dbb5ae795b932cf334dfcc6caf7cf0cc2a4c74ccd53665fa98e1d0b5821d7565f6375d9b01125d774232f31a9f3aa349433ba234a6f067e161ae10f5c5cbc3d6acf115306c4edff1872fd4e233465ca0d3b6ce003d1c53b78352f29cf3a7814ccbf07e1c01edf76d7ac0fe508d8b514d14929751088b3e4096a4b15b58fa35d6fbfe45f1ecf69993b2afdea93c04ecd8292e8c4fca72645f1e956b8cff5ce47408c146f1aed80afbbb8be67d4c5d9e5f90956e965f73dfd49dd3a8736a9c4c8b90b832d44e1eb9d3eeed6d424f9b787e5dfc4bc2383b47d24e1728657941ed793f96c440a357e2fa2eebe9fdedd247f60c8179c3060d49c89fdcb3b6d240ca2d10a5d4473d30b13e4e8d720c5f03385a0cf9174c2e458339dd9058613773dd06b8f885b76bf7c9102fae825bd85da27ec85054a2bd30784177d83916bb807ed5a03c59873f01532e30a5ad4739f44dace4a3a6a1aebc24fe0678940c54b62bf46053bb83b3264c0c2c5b4e9c79b6d06ddbfb3d87bcd91647295a912cd78b1d89800add38954b53652b9e5054796564d9a213b24df92e80cbc4ab4aed8b6d25eefa085687f13663a347a7ea8169034c6b4c953f110614408f725bb90ffa7458ba0d06a39880f001c6aba0ed41b5877fee1e8a41748bebfa3bfa88aceb7138c587aad5dd140a806436ac5c0e1ce808c5a33bf2230a9b501472f0224fa083411b44e024b9308e5882bf1b0ec7d186025691c9c9130728002bd1524331893bc141ace38c1b7d04d17e095da4fbc182068bba071e20a0996fd8f9a1bb85d45412e7a072379384fd6c0813a5f80ba4ce67c02a61e7ced18230d5ed9b373c804244d7cfc7adf53f0de84e18fefba302716e097d0dee686252353fd01421a0d4987e2e3f5cf1b886b06e26c20ac94b2404eb1cdbfa5d7df5707c7324c54f1a1a7a0d01958a50464d86452b11f171ab80f7142db587d7b6052e53f56f1f3d3aaf45eddf00f0d4614e64f20db8808d5e3e8a1b2ed266b4c25889d3b75d2c4a428a41200d603ae53d170c289c028b2d85e2ea77ec8cc33d5e61b72b3891f78aa6b8e9ba1e3982449e7d2966987622339f65ea181b81986dc257c3543a7d6aca873e44625c52676dde01924642e27b3b9316695db14dda187c8c3ba3dd7cc6b7df175333ebbcaab53c42e06319883b91e4aed098e0e26678b3767b7563b7c03daf057ca5d51ee2e9a67dff2579cf0ebaec6c6b9da524328f1cee6ada08dca8176fc81f2ebdff308ed5b7fa47cf80de727ff6598ae2ac6298bd6d0e51706a0f3c1708c355f3d66d94c3d6146d84eaa2a3e850c59a663336d42961b0b0181017ff2280ba38655785a8d0306e4ff870c6f2c5cd7a9f8a68f4acd5805bec0d7809bdfb2383945c2f43f650e8014abdcf2b3f85720cecefd60264c81b4a821914a160bba1166b4ee6b82c4ceddd02fd08037bda34923c62901353c22cfdf74273173bd138c6f837d12e4e58457813732ae6bdb2438978c56a74b55be760c590d1a8a87484f89666a72db50d8b37608c9baac43e3824f9305e6e620da604342ce4ebd98cd6d2e03269997b7189d35983e7e4b02edbe510184d543a9dce5293157d8393ceb7071a8b4ae4bb0e60b56e92ac25da2b0d676d5a274df5b94c6423d202dd8f6e333abd08925c64f8da3b920a2b7c8b1a7c54daf77223cb0797ceda0052d7dcfe00b26d63de70155f2548c44f779c1e953d28bd821ada6bd42e7b133b23bbd0cf7dce2291c41fdc68819e4858861ca6646f98fd539d9886292f6c983d4c7de96404235ad9d9ecde46f6a998f0177ba86afe347a40cdba05120d63b4adcf9e0dc7a99f33b6302b7f212fce10e212a65e8985107635bd3f38bf2af198ae225fc415d2d62abe46446fa76ff8677886738430b305bbc9ed2a6b07875d1c919812da8235d54b5d187be660809ec661e0038b476c25ee3e06c28983f5338304cc40a0e434205407181450829d666fe68cfeed17f438ef64b08cb65a68fb179918096e3677ce3c4fa768b28ea931c1ee95563f13ae56b1f2c2dab378e2382824962c4e82ea239ee08b163d6b8c46ea04977a5ff1c80552cf944c760ff979310fe482cfafa7d35eaf264b0b03d45ff8c8dcdfdceb878153d4d8a956d126903541638f925dda36420a085dd4a2e5401965762dd6da93d91572fee97510b1b6d0f99a72ec00d18fcd07e1202e0b235d9445e4401964742d56db9329bbde2e18e2b88ecbeab8dd3405b3844fe4feb84abb4db739a08237d70e5fedba3221a441cd523f9e8469ca5821258d2aaa15c675045045d9b62b30f13abceea92145add5e88223f2f5a2523e7867214c8cf59168bc9e66928414d941acb370ec4efc5f5f6d06486edd11c2cc6970eafaf334e1051466701c22268cec002f9d85c25520903fbe5a1af9078f06ff30bab46fb94338a265685da5c25521a045d4c5e02b147b2ff47df4b7bc0ae0218c883efb2c6f2c4d88167779f6c3ed3068b53fe7d69d3de52083871fd42c092bbde6b8f4a325b1f4e1fd6a8f1a977891b7e7507f6196b34faf9832bf68952e81dfb9c6e877f47260dde0767569cf1eb21f959c16042716f89fdd52905745f5daca78489875da103d5444e2083262723dacd88b816b5abda6f02c2f6a52ba6a7e8ec376ac239196e0ceafc8a614691538d65abbf7d0b5f81cf4af960420d4daed16d3bb2b3a1f28452835bc74977ad3fdaaf73593ce0cd49803a7ee0c920716b3ccdf665f2390d1d6a9d081a52e18800570c8ed10e198fbac1b31c96cb59899e9a5f6a0cee5faa1f70a1e6edc0b5ad8850c043ce2b5d3a40be8a719ec5a20e6bbd2e12949bafc9732a0702909e3862dde6d8c8a868ebc3b56721d3105af497870971804b40dc7d2a1a4dbfc32406be5dc0cd4982ca014d5da611aba279d649260e602bf1158685944409dc46e8c50a53042edc7995470844f16c459a4796272433e5ebb48820be8ef02ba7f066e43fb82cc7a42910bb927afeac9d5ff1b25a067714a88756e7262acbf4e850dd083ea1fb67de2133613791ac4c6ab9974066ee3f528ed821172927141a1a8f961da67398e1dd2cd59dee2ad6cfa49e5209cf06448c920840ad15777b35382dffa41f6add15929e2e0044c3e7fa8e0e00b4e70cb1141f16cad6dcdc4b02ba969dea89771252acb6afec939f9266d1812d774ab7adf9dbf045b34dc422a048279d8e697d9327c813407d3309c0bf77439b286f4b1b23400a5ccd767430e369900a4b8de8724122b912e751bb93da902cd061effbd5fd4e2db5025d6865acfef8a9f1a9a8d41e52c328c7c9e24d619b58938c775315f20268cc4a31b586fe1588d42a09adf1368cb5cec1043a982b6404538ba78c796ebdea65e0d4f9b661377d8422ab0eaf45e6e3880fd1e2cb2a561dc0044502c0245c34efaa5eb567b64418743b83b348b9ff6e4ff46002f850f14216c311d2bf750b1b2618ac7e794e07f9ce52567c80fb88b9b40b7bca5a40c3aca5d11d8981ec354c4afc15f581051e076f1cdb8f701cfa9513f38d7515e83fc94dac25d3f0b9fc0b0628b758cef05f9a44bae129ef47ae6bb0ce13a3e070e3816629329416c3144cb342292926b81191d4206470d43f2df6c29deda31866abe35055cbca3a09a4693de4b896a00891e3650b7456a661472f503d222fa178b80fd676c8502dbc6ccc089dbc9ec79db5158f8c627a9b7192a9c8858550c604af7d4e8072d1b96c80ec1860f5050aaa5bbb51d95a92eb58d5168a0fbbdec5de552333628366424006cd4db75bd813ad7a10883c8988a135725b8a928e04649f68d2aedd080a01a5e36808341ab7348aa5de1c6d84f8f8647011e8b1e4a5845e25a2067300f1b23a6b64da8ecbba5ca8bf68eab24d67b3f130edbd000a2e39c7dfadb8edd6fd5ad7015691eb12ea5ae97ee526fb8dfac2525c4d30cc58dee79ce897133c4c7f85002b7c1f7cdb9f4231e9b25b9cc6b7e63dbd77d91fc0a879341fcda266f49f8a2c90d95d5b316ab96fb284d85de1e0c3f9627fbf389a49ebc1bb2f5713540ce711253dd0f8e72115d6ba09907d2dbe4d5895a1df1a0e491b96249093339e8858a2c56955df82eda7672b20c85c3d76b3dc4cc693195a11cdd6b676dfa28a26a20fe2d9ef28b9c3bfc383cc055a6cd8a2e863aff8f2ecd051973fcd28a5f484065b23f98b3f0035af38fef141aec70b7ee98fd6b63f52c5fdb02e9a8af5dc172ead926deef8bcfd519df415b3b198682d4dc077249b5905775e6d6c89c64d9e90f31ca7195727c8ed370dd3b68e78eb72e18d6a3837413c0117f3757ef47072c4f653d50a20a1ab489385b3ca5769864517b59516bcd3a0a15cbc2e49ea0b8f02e5d501e3acfa79ac1de86b1539235e395ce3f1446602307087f9286e5c10c8a7bd81b3638bef098cec5de1b4c7b10d1a196d14e28ddeac47aa2ccf8e172d4f580d27b96782cf31ed10b255e301026466c4b7dd3c87bc77c905d2de4cb502669ca4b3bb4e9f4361fa07fc90f123f51ae2b68bcecc75b6a14dccf141fc12958611d501da28f727f6984086c7eb2fa9e2edd6f3508a889112d96c172454744cef7a42f60f34d1f210f08b90c117a8ffa82fb48e7632045f93c422f751904895dc4f635114022b79c32d01947452ce29b56fbc1ffd1af8cf106b38631a36d10be8536e8065ebb242699fb24d4924e6916e0b8067a7c83e3504bf736825ab0c824ffd6d5d0fd5962ade8cd66ce818db9af643c3878a1825234f7161988c421857f26b22eb60a7e56f126bdf9b34d7f1e2f2956fc39c0c6e73e816b589ec00b4b3f5b2a13960ee6aec8d67135946a0434890b434541527776149b13bc68027c7ac87e450e3ce5f9b2ecf7cf6e4957f48279da3c60da8bcab90b7e2be3f20884fff04bc48bcfbfa50ccf275531f23da082efcc799ff3376d08703dff5ab3a45303d7ba1d87e6d0edbe1b022a9e9ba1ce6643942b8ebcfed50ad733c5e4b3faae8050cbc957029a75f2c8222b46d4c7643a77a8427ad24495296a9801ef7f90fb28080063391296ec18df4324412a1f932672b10a3430ae5b258b2245478f4cf405ca4056145f8e1132f92099c0f0136856a150841ad9cdbdc0381da5642e812c9842bc502c8f2c3330e19e33b0007208a7fa56e7726e5028ab3613b913ef03ba21badb89cf3e50d4cb474eef76749676ad8fa7e53bf582eaf9b54b408bd7a0497fe80ebb8f55b2aa8bf8433ac90f1f5d893b1382555d567eff657a91853b18b7c8a0984897bbd46a0a5af70742ef92d3ae5aaf27eea05e58d5c98dd10e31254938911ecc53e0693cc2040544e2b108399454e7af29d539af0078aed7c74e3cf7332e74c008a91725a92dd60e3a7ddb23930a077439f066c445802cd93463b6f7b4e9beef5350b92cb76d25f47ab9329aebb6e5a9cdf34f5504b3fecdbf90ac894bcb11a82fcf10fbfd85cfa43e658bb7e4c7835bb20bfc3ab09a04274408ccaf1ed56e687f4ffdfbc955bd722635caae581a1f47de28a95d5b91c34284c6cbaad1bc4605240749c8f1bc0b024743e393173fc4fc311c4c9306503bd6b5affffb0dfe0ea4a573a749fa5d944d92ddcdb113b6210b27adaf8006761d2f43935ddcb4958f34b6018a42ee01e4c6bfc91ec302fe861711a3a1e55e5554ad1aad8e7e1622f3dca9a85a2800f18f3ff51cba2b1bf92bf07ad54902230b5d513a5f98fde1c418bc0716437189a052b4c068aa7191552eb097b304fac080e29426f9bec0701760d40e6b57bebcc3a31e5f345f3d766f83076e3c6e87ec4e3581010e086866f56d8210a05e780b48b494b1db3159c0133c8ec9d406188abff2e4a7b9ff7ae9af4d2ec9b828a8ef0cfe5e187564adf205540c6720274ea721093bed859bb7b7f04ecf5a2028ae7730828b14711b6c212ba96d6f7c4d6aecda5e4ff3ce769be849f226ece115fba7fca60e73f802b52a46df1149936269527c398d5ae940cdaf66bc24eacfbcf6954d2a87bb472a18e8fe337b2715518f0f64e66e27c2c10e2a9784fd1ab0129640e984cd011b9559504f834b8dd0003a018b050e44026ed2b2cc83302c7cd74fae859cf7b6e950982df05d022a8c4e8cfc9d0b8e5e7ebd61973ff4a09b625a3597328176168ce7874af8ad49711dba1bdabfe1d76a5690ae1032d1f8080c3b65dcbce7e678c034542491b4cb1084e15123b4303bbaaa60c24aaf171d5075bfe12386018f6bdb45679c3e24a14907b382877f47d15ef6ef55b4f270c9bf7e823787b70d5691ad0eb88bef5079a6391344d897a0291bedbda21596d432fb82d16cb612c59cfeb16c831f10fc53e3ce6d4e2c078dcfb374a54918eeb252cabc3da3d4d702767de163e8f84b7708c5bb2c7c6567c07d8a95f97d7f9c39ef5fe7cc498a4e19337a5a470e56855d935ab83993abfcaa8e6c3739d06f73eadac6b0b65e0d0fb9008db2d62058f2b20e6c283ceffc4beef2e980f801f84e1ea154a736ff73f75e4c4d8e64c269fe03b86aba4fe37cfca6b5e09785c386ddf055bc35f99e7c1aa75da0918e1074f1ceb684d5d291bcf7d3344c93a5c1d680980a861525f74713714d3a2cef488a6855eae983513e356c66935c0a55f197ed52ef5c9333b0216f92236c27cafd48bb164d781883e240271581aabddc36298bd1c3ec98057c622680ec7b545a43e68b0801eadf0324192af2ea89591c9c2d4c2be3450483a51a18a0380269cd84621244aa437c76c94b71502a75f460e496a13a55408fafb77abb6d27ec12db8153406d897ddff2a519bed9ccd99de38097da82f996f4d8862ad368f91adea11120a1c1a9582d048009c34bda798d443edee9a3e191851752eb17f730a0c51c0e6f370aabf11dbf05b8e66e4e095a66f9f96e77f0f657d04d8f247c97e868b027d6b62d117838ef89fa31281cfaadc319097c0f4573206c20c8d22ddfbd24666022f3cafb9381c04e609924be3f6af4197c62d377222b2542858d8f674c457086d4ff1526a1afdccf38be631cf5fdb92fda83368bd6dddc039280fa173cc934a79b57ad1cd1f0d878d54b082a05e83477127f206074017a1e4ddb36f7bf48b20a7eb223e57febb57671417b14b0f42e205a705ec9a47b57656f0e71170099c0dcc177b1f09f58c062567536627e8d356b65a0f276a7a016cb3af88e1f070854765243631ea2c0ce2f5f48b16209544625602e1dc47b1d164d90acea281e0127c497fdc1b03f29fba3f3c889b1415ddfe74e2afb0ab44b14a20c7986de7f7eb71672d7df0232b5ece43bdba349b6d6497adee9ce64e658401b1c27dcaa2f1d4dabe152d4609397d4aa91b36174e3aa63532f668b734be5f430b9e9dd8d1e8611a01f213b5e41221bb8ed6e4a4bc752cf5af3418f2ff798d5cc595782395477d0ab303b91ceb4f6d0770a8a228089bb72be6878a9883adea4b5eb3788bc6b124fc9134e19c7cf6e04bea32929cb2be7f2f95d7a1289e4ed1c82a698777fc0b00fa012142c05e1dd09044027137c99915b6319a01bf5b1131e6e83df3d00e94c4ee1e82f775743067d05cd3cc6173497eba57e6ff88b1c1d6eda7a7b77f2ac551fffec5477d3895956870c3a18952db35f9b5d05787dbdf22160564035f996829b879fea8fc9151f18e70b02eb4254be8382ee845b73b4ff618f004c5ab3f711bdab619cffae9b911a2ebcde9761d802462a0597653d0d3661267e3cf70d80d255a18ea8a5d751f7327ea162b52712a785ba51bb41288735e243f12013fbf49dc71ab10a6f3bf449f36c09e6986e08532dde1cada150bebed0edf39bd5f35436eed9a54311850bbcc346cfcb6d192c8f10599e445f3ad859c3e6031acc025c9b4211d61963de5ac558b699acdee43af6cebad9b0af031e4ab923f202fcd145856e5d4faa023c599ceee0f94953811cb7ff6e010d62a92388810379803b0b417709c968e720dfaafd05b04afbd599476fecfcb3732b1140af6f5bd182d24720f39cf9174fcf9f91552fb0a091d197f425fc51cf60b9b8c4263c526c209b46031f31c9d2f391669285f6c7ec23caf7da04ccc9e1bde038fc80cb7a4a6079c3cdd35f9ba91acd0cbbe4cbb070532633b6275ed42e8ec71eb61c9a4c0e77ffeeeb98bdde5fcdc62a35e00102dddf16696db0fedaf7731197e3473bfedbda2c10c89840d84a3b566095e36854a740db09905afcca5aa37a81eaf9f4ce259159381c7235c3583397a6621e27d8c5ce62dc8a43ba641da02d1b750f39e7484af0e1a79a4bb45a88feb4a51199726ee14fe99a2b0a899bbf66b36502a3179cd292b87b07be2aa791120e69604e831c97c33dfc62cc360a2e4fcf443508e44703d1647314bc92faf81871ac5751daa48a0fd7c5dd8125eb7cbb3224c3cdaec8ec3b976b27d4b86f00eaf006dd1e57124a0fbaab37b8332b9f0654bccd1549f7834dd4716bafb5bb7a91da039d68dcab5bfb242a982a5dcbab5da23beb0c98d5c5881ab413543953c47086e032f42c20e6ef66c686c5e0ab1ba7706c085a0860b62c70b7c0ea41fc80c9b70ad2b992da10fa112bb094296b5c44945ed0c187d8b058d9d1e7c41583acd62801c607cbecdd1b0d2bbd978dfb3dd5a608d07ec41728bc8ed571e9897bcd97166719976c6cd6bcb3b8d609caee9073203970a9b218575f8b41da548241abe1a324fa05db08779a1b9b42158642673f54a05fd31e5c00ac5734933ee730e866f95f6c7146871a69a9e92b04211f706f3a8c57cf25335ca5bb8336a885af3c0b3e76b91184b890febfdcc584217e5fe432dd0b4ad090729374df0e4ee3faa508c5842e76c0759c54848020144c72a5d55439b2bf3ecb01c14b4e670f072bacb5c70c690fb374f625e1e2e02eaf7333bb1fcd30cbc42417098dfaabfef599526e5cb40ef22c998b52b158182b99a9d0183b080fa63c5177f7d62c2ad6b2591bf5d84577db205dd1a8202fe2e9d44dd70ba4d05c8ee2b81ccae3aea04cc527d87ad03707412ad2a18cca742c0577c328e4171ce32c581df50c76c7da1b094841b9325f17ab552cb3c0b67c19c7612ea428d76acb3d08e66931433f585ed36f1e232945f50e02808a44bfb1406ff772774d465135c2adf28cc245fc9c48ddba57f573cf1f3231e506b0f6e91fb4c3a58c62f8f930e3835aab242091cda1cdcde64b0a79d25b8dde1ea4483f8c0d3ea517c438220d918d4d9f809a3f70efedb02ffdc741c4e80ed03424bd5ba30b8e68014dfa682da16e70b130f0d223020f0c0e7145785b8427c9e897429d8d9f816896f6c087416dfa1a9a1cbee520437d582dc0c27b452dd5b936f0d96bdcceff821c947719e68731bd25d8dab5de6c7ce961a0a4fb35c53a6a4fb2597ff32bd8420a433895f4638163f0e5a53131248ee3d29b2fc0963572710d947f927c17f1e4c47a9331d646ae86eb66d325eda50bee13df2e315b677e1ed2f3fe642e7924c20f4517832339fe0b02bf13b4cf72a2bce346bdcf561584dfcd4b576fd256c605ae2dc254f78c7af183f8a5783ee63c769c6a93da401fd831ada4479abd0b6de8d55cc0a355eaa7fb363ca32cf6f5d3080cb4c77519a4321205bddb2f1144ea7acd07aa7aa8a52a13796ecd49f9726ea48f2baa6da420160bd48a0701a3193b93d048cff93c4cedd134f6ed29098d2de3b9fe7e4335ed34c03ac3b798851c14ec2a27c0ead9dde7fb37bb2d88a17c287998351f23ede626db5c9fec4e4068d5970be07dbaa2ef71b54a39ff16cfd040d7cc178b6f111d051c03fe2f96f354d3096ed5000cef038da09a5caf03b50411cd6b3e5780f2cf28f23ce0c5680fda19b18a71593a72ed81c2c0a84a0ea3feec2afa20e1b65265ad9a3dafb9dd15a6b3c3b8b669fc8b2e99d55a6a90674060f02613eeb2c0a96f51bee40526a90cef2c70f0194a8a524923e702d1ac5a595f1c7f2585f1cb40faefdebe3759add38f36889c93a2bacb1c0f4bbc0338e73427d1269533e0716a6f6bb13387f395ae85561ce7a8292bcb36f8001a65c4e5f7398c901e7b7256db787af8aec80caa5b24211ff9ace03d07e92a3e83f07b1b6755faf26626c4b64cc63215a81906a948f33d5646d655ea8a62caad80f5ccdb0c505aa81026dc00bb0c0817c9208b7cfb50b89cc7147a2fe8bb71ef3785499632dfb083cb631f49c6ba0351c79b90fe0dd7978e425adc47e60590f2607093f1181684887d37d1630f3574c9c8cacd6d9a2da36998db0f2f4ad63cb175a607e9e0f73f085468a3aeb18817b64d3c702fcb80a063f1ea6a8c4c3d408504b5e7a1a215b8d66edcf4bd3bac290661a8ab3c074d0954df10e81dc00c272ffcfd75005543670dba305286c27c4beaa6c7ba94276a73b140b4862997fe136d9452c3f16a5932d9e0f50398f9f8e51e5dcb6d7d82ca2640f7570419ebb3d1fb5a1e4a191905e110b9be7ec148b0a115cc0b85c5ea5f94e801a8e189caa022bb3234c096e106c5a940846134110822c645ee99615c9893140769f4e58a6d648e3144437167e83786c9c4fb11d00f8c18888c7161dae411985688180d4416c9e74106f9433f0c5eae93b359df1e02723016849728e0ae0ba6652e0f85e15c0b21c619ece3023e3ed27ca9c1e95294280a4cc6467dc6c9e376ec9738042ca29706d35fbe821730f9440ee6b593d812eb963c7b6e261a9915a64904153bf708f63b36c466b2c3a2cc08918078fa40f47a45ee3cc377708809280917071ca6f31db41e0475f03e4674c6ccc0dfdcccf22159ac9e9f259ed924e897a92f774027b59a6c1872ba605b146ffc602850b605ddabac97800451b22059fae3549e8d10929ec8eefc87572f97d2265f342c7e77c96cb4d541da4e9c375859b2e5dd4d5a6f4b5fd9ca9596cc84f38d1eda0d4d8eb5b8fe1525d35cce75bb38384b09045af27592dd52e840585b563dfeac96420402f03048da46107c49bd2d6fe6d30deba74802143b92b05444945e36ccd48a6a612b1528efa3dfab05c5a2ce95b4801b6379e36f6f4e6bba406b2b8a775d780da3065d04b2cb1f7a041d7e104c973c1ef14cae8bd5bd79cf114fab77331a98ef61f01cf12314b81020ecfbca45af2949cf275d26359f752b85240895f61b623f8c4455e97fa04a8e7ab07ad17753bcb28b89f11572c7799698a3a9b2fb27c022fe501007385ec1c02d1360dce9c86682553887ddfd1422403fb4e36415054ffff22d5b99359e72550e82fbc6fab6a7ecfde6561f5910357e72fd31ab5e427cdb1fbd158d2bdb5873803bcaa1f252df5e6f153fc639730c7a79e23e4d685bf0d48483427c18a2554a4e773c6aa32663711ec1ac057050388c3adb446794b6ab989245ac0bd532f9839c41d4ccde94d4a631492596bd2c5b05a00161c7c0f1864bb7f68d9a06e705019cd7975374bbd1c82a29976f322f68fc5b90a210682edfe59f77ba53d6d0d8e6a464e3097966cf480dbc6dbc74d72665a8e3b6d4e3f49a6d334634a30e1041bc6fbe76437b03201e696075e54afd505d3e08107329e3cc55361d1e904aee2c4110dca31f87d026df9937c559bb2246b5e7b2e4b945e1cac4e4d19a05821d4924f7315c4a8abe685c98d633078b97c7f6d2157554620b9720c16c8ddd7f6aba042193e514209ac2a2ce933ed91f17588e29890165005dbed91ccc001451ae29118d08551fbccb883a6a388581f4b381e238c097aee4b8eac3fff80de561ff995b4c2bda127726376cdfd04778cb6840c9ca004558559039eb44cc2ed4689ae8354309591ca8f3dd6af59998458ae9c6f8b1a4447533801b9f55de366e6d4a3051406200fe9d7bc3236784404b5f387dd100e4ca653e848302c64e8e87cce6fdd6ee2d85e515f415672d1504cb86f5d3b7fbbeddcce4099f98497dfd446024f3891841d3fa1e656933847a545e48b153c2029c7c11d3f9fe49f4bf0972c176bfa29629de9562e385ae2ac0b61b561df3f82d15ffec4a9c310c01e333bb606d013ca3dac8b58af69240bf882b56d9fa33e7f965ba4c0e7b04af87087012d1e39bcf9ab84ed71deaf0aeb2ed270a2a36805c768e81f06863816105701f41f1aa3af61f93b46c26e82debd8d35fab3c58dbe705f7feb571f613a63bdd8e0e3cd399207f74c3761f3aedc8f000aafa557530f427f16413f510212a7647621e071ebcb09920caffa8c05208f0cf76bc711caf0fe0de8896a29a6632c998061776da4f65636cf65b51742020d043bc15240a0e359d588b0186d47813f04ffb5951a62010b662f9ecf72fc3b5dc8341930bd4fdd573e2f01e3248bef1783891d3509a6e8aca660c7699f2fba430988b09ff76506a18854d4593b152b7ad3bda530339ebf9cd5915c82c8fa662279701993762f639149013b04fea4ab06b50e894dc47b7a1aeb867e69251b1b81d56a4890aadfbcc84aed1d02f12b4c0bc0cfa14180b974e88eb4e64530bdee451ebebf5c3f2dc93b5e888d6469b64361106a01c32cf93c0aaf68d10e6a01c8da065cf2c56002e19b60be86b100f45ea3cf43f6e43f1c21db26d0859807675b483567c0fa037bb3d42f052e730a0b0c990b47e34a6f53d92e4f32903ffd4b126da3c315f15e9542f1a4d2851f6e1a7b99d37499f0d186685b51abc4cfdcb9be8d15b4a102c7f423d1e696a6e0e49b85e3349b2166d1451aa9a590288b0a003bb29c9409580fb0363a34ccf15e1e254c9240392a6c4e7d820be8e2420ed7dbed25287dc131a21191e339b1cdac307a0d41017331a6f2b4a9943682a0da0990c730ea377cb8fdb5ae5c905b6da29eb64860808b5ba6977a40573990377577bf1d8cefa50327c9b1f3d58a6c51ad4eb893cc9c9870a82808e37ed90fde433821447b1e9b9492c01f2c308b76df9401cf3c217d4ddef7faa9148af9fec08a0326e67e44cdc4c195ed4045b1b40a5aa2170065af523bc0cd8408495255b9fde213e64350604d39590123034686ac22ad6723680fe245f5db1a00d7558f3ec729c286be212a97a6cc96da27e435168a6e9d7bc950071735f46f1f59075c812fbe0fd9324cac2c1328fdac61fcb7b3dae51162df2edc32c59a4c9f40c3ec11048d64addedb1bcedcbd1e2843091c43a049d51dc8cbbc64be0148daddb7b6d154bca4898cd401a45822c842d7c7c76c81923196b2302fe53f8b54a4103c2d342bdb5470edf66a7e8198724abb9ba27d078d703b3e6d22c55e75ecc884d6d4edcd070ab180b0817f0860202fe88438516a774415213c4736e48f5dbcb328e4f3a574bd15ae9497c67405e52354d0be18be9b61d20f52aa462a2e50d3d3f7e018bf20183c70b8601bb434c456c397d2543f512b879acf655adf6f19833f2a4961f310385af9078fc9edcc9ff999f483a8a39007b2e21aa2355bd4c65902e500fadeac94bb5fa350ca41d700e3350895281619765ba7bde20410cafc62a37d10bea8efc32da07f08dfe78e7cd8099e3425b48a1366cec7fef1271a7af4bc211b3861313043b284c24bac96d5ca864d2fadf7d2578811291971376801dd31d4a1a5f9b11a315bf45a2aee7d1e3354f6d9134b9fd13b17ebdf0dcf559474d1bfc6c1fd4e0bcc03a42369d7842767071b596c77e2a0b2eed9d6ff82f0412729164e76da3369ef79adb8e397d39952070e742b219a37e072b13f117c00ec8bdae242585044d548a4baa84369601ef1a21a96207056911753f33160ebe2e6aa41409d7a55aaf04b69681bc06e12e11d35dfc6533e4eba3745b52d1c66ebceba74d7d417069dfffc4e14058000718b42b291fea420829571a2c831c26625e36aeaf6dc071a2643e7ce87b566fc30c1735b80a4e764e0d780688c9de6ca8e76fb4010fc67c1deddc8d80d3be1a18a063a93636a87f9e8b1d651ab06df8b98bd4549d38e099d1735b2839e5834d25f12a55a49dcfb83bca4a05b14fbda35782ae42af1c346125abb6c38c06c4551d0c5d9e38d539242892de0e450aa5edfe3662f61fd459cfd2e52883420fd0cfea8de54f2441ad94271269ce10ec7c2d5e0f3674f4ef8faf97d7412032b96329423fd79a21066d95fc47e78b584d7de89ad97590f838609330a4d6c6403747e930a7ec7053c6a7831268eb31ba4d01ab3cd5583d46c91457032577d7b64583fe9d555506c45ae2fa6332f58e386353a7922d1c28602f4c7b1a8b445d860187608cd635d95cb068adf8ac30e4b2681eb3017d2425bd7f3ed680b54508e4a79351362b7c83d1fa148f4f8aedd8da82079c03125bdc5d390183cce7f52f9260936c646450ef0f444d97e3f5c38d353852a8161d86571f6f51e42054afbe759f6c2605a1685906224b89e7d5484afeb247a2ec790665a0ae381eb5c8d8031818918702f14d924a01a9a21ab81b649482e1d17c0beb447084856018daeb60bd293c4ab17b2b489d6d970391d75b7e96c1d3d4d37cf1380c80c3032e34271a35bd83a237c8e9d64eb94944b8fe2579b8862a1a5069f6d1da3d2f7b0aa21408f53e440708dd6d71d6fea69af8636910a1ba0d290f506eb33bf281dd03ca3ee9d7d7613d2418499310b2240e7d11826e6d9a8ebdaa43518a38e375aa162b48036d1525c3ea63441f4d489191b4f503f41e08e970b8bde000ed10e44c2a749b1cdffa91942113f5a1f069ae2fe53f2006bc8ce17afd47ff6fe5fe1f1fa4af5f012cb1e858d71b465751afe7123fa02485036cc8e9522165a402de274b8d6a2294dab816f5da981b421484be77c07c8c02282c9ad29542d41b329fa41910f5aa0a9a09dbe037acc2c316910970b3438f2710758de2e0436e0f8cb1af0fef2d1d38da6598a390cdd062f5e30e9c64cc2f3bcb013603e230b5425c323790a3c9e1311a9bc67be2015a235524c86cae76111ef33e7f8e74b5efd0c03747ba6532dfcd1ad16f691972c19fb93e7112c3edbc7e975e60d4e4ae82e0393f711d0e3f73c82c20e44da291c81ae64c3a4700c2edc0ae7850bb41b4de670c9f9e7f798620f6a87c1bd4e506cad93c87c4c673755a99f44d6419daccb33baa9ecd3a5072213d4b13aa5abce5ba59b4c71b63f2ae5333707f8c755900daad2e6654c69a4c676a2ba0310e63e745dd4c7a8e4e39fc9ab31accd2ed1418da3dce711ac60f4ce5d0b0dbd71002a325f9422637711c7c424448d7e8e56a2986feb11ae03b914bae975e6e1866840282e330169351032d0815fb982294bc84c5df2fa065a067aa012f341be15e29d9658eaacfac2d698073bb62978a6947dd016a0bf250626fa578d9fcb4d605fbbf9aa1c029a3c174cae34b7978e786a73b2a14eb8206117c4c2a1bbb64c505e323f3ba39401122f3aa4400388fc1add056f07266c6c4c04c4241392951841252f06979c781f8937f2eff0f2060e4d4cd833b5e4680deb032082f91e20dccf22205949fb20cc7163f0efc91702f39004c0fc0c6180e7220f034a9fce6c0f3ac5ab1bd27c24c43c387a3d8229cac53ee723c07304c00988cdaa5687e2f11b2dbee7ee9bcc6e5e67705edc6d6abdd84c85dd3d96c48153a360c99ea49f4f065edc4f5b3e9ddd5ff994b58abf07cd9e4d93d1b9d96344ea3b37949f4825226545c3f36ccebb62acdc9b8fc3c68750173b33b3f11aef81fbb6942ff1e24c1d22976bf5792fbe8a14d07d9ad8d8e7484aa66c3030b5db02d82ae043d1201dabae4cd4546c1d1899473990129e409b44ab31cfbd8317810def864d12a96f9aac5ccf3dd91d76d2de557cb3200388e3a687bf8eb1885324732b914c786cc1ab0cb61e4ef3bc22c1eec1009eaca1b325599458e2c26a29d77328d046e0014e6a3632c949948af3e2d25a59543071081fce973684c37ca302f960905876ec7140d2c2150fd41681be7629340ecd320400511e9158a89543966ff9f0e54877d63c72051983d4aa015a3cc3195830585bf759f0a5596600cc437682c1fe378df1a830311da8b6a66a7f8091452ef4ae5fa054bc35b038e1e2dc8397e7bcde6e733bbf387f9ebf22e4bee8cd4e19f49937be1303dfae259c8745a09b8f7951cca167dae375a01742b0dad87b1882cf9d3eda0de5daaed7c3c81df7a44e2dbda14ca1c8791c60314f4eea6f1d7b51df6234d60a6208186d586d5788832e29b7a6f247f6b47d87bec4f45bc2102f9018e08cef493036174b62f07d82974585a54771f973f0faf8ce55ba4d5072787e1c5a2692ffcfaa1bdf1d3c75f816c07150fcf8561660262766811f95da9dd3e07c69baf18bf49871b5f8b720a968644fffa30a9173fc01596b99da2834c79ccd1248ba5c551164344f454c8654acc45ceb70bef05e425eb210055d89555d2d7128d83bdd30e96aabc04474fe4cbfc0dacabe2d81e8ea3b023ad268872bda7b3db8494c2b9428143e86e3521a0019258b3b09559ee1c6dbe645a0ff786707be61b933026d461cdcc1acf162ffe2adc116ad6106d2a8aeda500a54ba3ce9459d15c8ad76ca4cf12b3305833760914f13e323e7495eee2405c908c658f03c0eb8091d61238202fb8e3125bd69321001ee14811d1af65ecc3d32e569dc02892f9ec7bb04531a6801846b60631b050a5ba29db9cbbef1991a2cf367baf979557780ff60df1f1bba2d3aae49f09c71212d5f0711f4858161d003d0ebe34581dc8125326c5796971bcacaa82801e3ec1cd88497dbb2241d02fc6c7d664f7dd3f26f8dd27a67b98d5dbd9eb00d69bc7a921be8ba311534bc39195a12b0ccfa9934616c1ec143af875bb186c5c0b8ffdb03c29ec18d356f73dd4d236cf61eb826b627a3c6074e1669f9349776e3ce7365aa4ab62f1e9a61e5326a17fa707c5daa13092624bfd4b8e4c6e77f5ff2cd8f4ed88c3eeef04b8358e4c0bbe895ac7ec8f037293445a5b13a9d65c47b35e0e92aba3c391aec96edd63efffb5e1412aafa5d78de7f925a994e4335b9bae0a62498b9349cfd9f26a9519f13eaa2dfe698e3265a8283754e516f75e05bcec45dcc32d32ca62fe6f8b5bef4c8d03088f1625bde0289294ed8ce1b1846e4ee5f1c1a8f0b82b69e4fc837e94a807bed68f6d66d9c85aabcd10847c02c373195bdea9000e21ee9c938bd74c28144fda619a96b06a45bca0773bc4b43b43731cf7ff72bf5ef7b8060df70dfebb469494b7e0b5cc999f00adc23bce913098636055ebca232fa85e7553894bad84e891218f06f60c2b3507cbc9a5dea28e28110bd8466ecbd17e40fe1e08117733ea35b59e86ff592116eb16d8aa2a38f48f994b187027d1c52a90708d3a8c49777e49258ccbb07f0b656d80feec8ac8eb9e6383a2dbb7412ae928e19980c3e1a4313682a722c28cb87ba5e0160136cfe8ba082e1e621379b5f14a0857349950325e0f530caecb314595eacdf1ea4f55a91eb0cd95d76015f8c1396fd0abaf2b5e2f37b86d5589f3b2df604d61bc5507f329fa89377a497141df362669afba960e370ddaf5ba686b57ff6ca490c9fa281a0021419fe17fea5e23814687adfe32b305176f77d2e7b0f852e7d2ed87d36f41e7f6f31c011a0a490de60740759067ffe04c0548b1d7554a5922e3e629802f27b933a233fe481d889edf3441fb6dfac3ec53eed64f5556f647f0e7693a31b0d978ba0d5a8ad41f1d0a3e2f0ae8f8eafbcdf8fa7e80a2e567b3fe13d05c1ca4e94ee6f1b6314e4d972611f2588215425e1831440f8567e2103da97329058014621639964e258cf57893889ef11402e89555a39f7f1affc0c79282f25134012d2e1ba6bb009749fc6b8b703a5331c623fdf4284bc48ca92d603f9ff2e70e72a8e83fe893a4c38c3b1608006f1443faa82b75ec27511471a581841fb49807e3dcf43ef815ca57ad9a606e5875e9aea59c8f69999501ab956edc7f9e2c20bf0bd142ff7c091f6f8a7bd2875ce26b431b61cfd0c2357655e8b405f6e0a4c2cc94feb1c44c4378d55ce53ac09fff5c8c0f3601424809b196cb1e64868ef68c04594892c93e1120893de22b62f88dd833941928d2de61c0c9b82753fea1afea14ce373bb14212c7d258dd29d59f80edefd8481e44c8873ab8b1f5ca29a395ca3c1c2b1e8da8c536dc1c52d23ffbcdcacd23b08fb75281630ce926fcfc91dbc12910d0c0d48585bc951b8e81cb6ceb31fd51b3978d8211916eb0f78c17df5f35edcf5aa759a72df326f1e0b205d40ba58cf0abfa3608810bb464d23c0c0bdc93ea97d5d41358106618fb736594fa27210d63da45396b1cf887722be7a94718e2ac0071551351548ba25427f31916e6d1bb63b3f72163887f11e1c65bb951553da5b52fc6add6e62902e3a519e86898230d74749a50d7ee441a334f888feec49354014956e90488d93d83323d977066881094bc89702727c87c7fb451ca7fa3d5df0e7571c6185ef0a9ff09684062847ba1179491871dec80971f4763f51297f0b462942827a5deb80fe06e9d74c50771b9855a4ac73973f6da51d84e3f295fe283ce4f4de7c4de782b3f0ba0203d2fa8a75b5937b3415449c99bc0ab44e381c2c4edccc04089b1f7280707549ff4144a00dff86df0321e5421cc30c575f02359398efc9234959d812143df5856ebbf93f34e20fe0eba1963a592948d9caa7b491fd9c81040649cc068d880c11b00711f105b5b9c50d7f2eea5fa2b42a16dd94e810437408ced686940ee5b23450c19ed46db11cbdc5dda3776300d729913224946cee72949b8b76ee59b8512e9c9ab505c532c949268d194c9d2a9888a4f9a92484fccad7123fea76087b1a58a781bb0b469385d5a6a611d2fe8b03e0316c492748a225c5dbf24b6760113da3d6d6b18bd3ff2b85dcb23c5c88b495bdf0c117699535b06fe9506f432628d7b2e7b08fd4522d35577c9eadc639b56766843645f2a66c05942b930c75720e10c0b925bb2f7904a387a33a8b274ce7c58a2e656bb02b12320efad4fdfd16491654817f3b7c8ded29b2aff985896431657a8e9c7ce832422501b60bcb98baae363d7017c1ba8184e5d48ef2db5aea99c10c052f7d23ff7d742b52d41ec74891944d0dd34b6d61a14f61fb2323827ec6045957f1eaef86713b06b6b44016bbf6da03ef71cb08e5fe96b01655b7e168e721396b26b369707f8f5700c619245fa60167d42e4f830310edf67c859b8712325a0a08500200b9abaf5f3105bb1e496c00e13b50b44f0716631af6d70bd6c865350a4bb9209ae2a685bad195906f6f2a7558ad06144f38a90d8a9de976df74378efb5c349810ad18cb9c7c5df3a2c162c68881e3201016588d68a6aaad5a7eba87a7a35f8845b67bebc6444b282f11f64c70c8e24da6284340c4cda52645b05628781a8df575b06795bcf23222f1bc2962a149f4b0092409133bc1cb365fa1a911ef819f547798be6997c7ca1a9990b27b30203f5e6b91c0b38be2e5e7f0e795a7eefd0cb67761b52a2220cbda019129877f5602f1fb5c6181f7fd39fd5885dec90716277ad3d8c84b8f92367d63251a7b8899faccc7e4f207fc54b5da60d55aac197a8806c833376491f7ceedcd2a4af6de4a639691c0968388dd78af42e43eeb3c52f2cca8ca7989b05d1d1107ac68c2fec6f39c1d2e188ad3877226668900b25e771781d89a79d7cbeeb2c399ea74b37a3cb60a9d89d939822ebac810796729d8cca51235c4873288f2e246f28f41f3cf33d027d403964969f1aa55acbb77fb1351a4739d90887e798af1882580f39b8e72a09f7b1ffa59d3a1dafa10972c0c9cbed3a45ea1b4feb4f5a8e5e4c25eeb24f49ada306af971430ac84026486893da58305c449d34e24cc0d1da7242a6fe0f4be8d912059af724577ceddc99d149b8762776a284f2ed5d608830829fd0aa9f76e10e6a8da6bb987fe353045cbcaac4db1c6c812637ba699dd1e348f2b6d9796b109c7b9e2b9370573daac45b49ced941849a0c5ae9d00ae75ff4c3cc811728b0d95b4537e6beabec228ccfad92389d48ac1a0a964f0d3ff678c179ef58bbcb1fc275d365d7bccdd212c80e542195fddf219ecaf6a3eaa9ec1b523d6fc2cdd7796a265198042c7324896529f4cdb8c2008b68953cac1e220c913241a8258676b63ebc48b8f26b8a3ea4fb3fa899e828fb8bda032f081d83d2a4b028ff09b99827b7f548d65e82135bf8c2c965286c704377ba058614bb814a56868c0e18430958a516ec25d159f57d8bec85447b1faaa968aaab1a364ffed6fe6db48bd55183c9fddcef83ec9e46c40ae32b5404362eab455f6e7e17c2dfc714c4ed098bc9eb1ad8ee2d43016d86002f4d830f98ac1320346b4019d34fa46b96a5dfc28239bb86832c32dbee252088b61e47402ab39df2ddf45c3d00c339852810a967faffe9c4e2f34703fb24e8673c2c3ab80b258eaf983b4f7f440e39e921b1db012775a7c128e7a0a849affd9db7877c0278a6cd333907ae4cd449d192d2ffaa6a40c5584ebf939e41dc0c895259c543f04c1d9d4d7f2396c05136cdab03080ccd15b4a3d9d5fd6d0c0f0101d7d5deb6f7966f56cefe15fc722003a90b9121b54ef9163dd1a13c6dff0553f4f72cd2adc547391344ad358530b48160e540ba7fd713bea404d7139b7086040566ef5e341ccf299e9611600e1575e151b2acc5631f8812d9419ed57ff9443b30380ce26f30dc6b0019616766cd21fd6b97812086111c1711f850c0b149d9ebff607864f7f9696566e5bb4a74a5a41fca9355d7f1c14f4d423e58dd10747696562ac2457b8b400f6cf0f7d68519e7250e3ad523fa42d445e5b2377ceae92766b65015846c569d94dd1f546c8c35715d76dd4b06c3af71b129c1793c925c3e841e988b9f455afd535d001e208e92f2485b5edd4097308ec60f2c90d69ff563f94f9a7c700c69f6623aa28e8aa4e5c9d814d506407d88040a08097d8657da94442fc00896044b6750395dac08fcc836fd7805187030e0737dd63b7bb009a98927654186cfbfe0327a43c983070f0bde0fb0ed993fa5f20667e77407239d4e6717da75cceb12a169bb228024d6cba1d2b6c7f07f70264e936ec8b286e543f0d02b65c7253db755346881db600908c1cdb74b5307379eca4c4b659a02916f16ccacf6960cf8ad8aab9ccd08869d9ccadc9a7996c79abe2f69b70dcf3ad3f077b95aab0b5d5e69e235160671474f5c05126ca5ba6246071bfaaecc0cbcc48f6b52e493f63a982b67c882adef506541b9b9f1a0c3f7e5d6671139ad265b88d9dae569305e55e1edb31bfb9b2050e02ca9a6d9935f68b1ab0d5781a0acc1256d2653164ccd74db5318ceaa0a13b5d1c43f11534e4e6e59044755089d1a8d62774c1a3b70ca66ee5c38c6ac2168925caff92a6d6ae7bbdf73e91194880e71013273433303c05ba724167155c21587f2567e3e6754e93d2b0830afaf78fc755f8da2b07677ed32a8ef6fae5bde53e93fecc61ab4e6e89cc2619a7b0dd9db7eaf8dbc8f2dce0cc90aad3878293834f1645e0004d2e0c59c1e3272fa0d14b5cc8eceacad07c8af460d5d973a286114fea5caf7a1e28a69005d3d06d843e19d4d2733ceb4e58cdf1dec8d6ea133627cdaa417ff03251be926763a296c6f6b25a11e49f7a2be3f4e5b011e4fcc35ec274bccb37d325ff4245c6e6d6ec107a6d4ca391fd484030844c2570e3e3a41d832181eafcfb6079537f419fd9d7ba21b8e74e042c8c5d77098c387b7b9c7d47595dbd68bb42911652dcbc2266f6ae69d245eae7998082a0238888dbff2350871bcaff2a48ee5aa1f39ebe0f7bc3c81150e507ee329084928fc74d14cbb8f7f1a0f73c366e050010af682de815283cc246b191052ea49ba656f03e4df37a5fe420653048b2408fc5a343eb524c65095a6c9c689aec20c8ab95de4baeafd780261d67a748efeb32eb2e4053a7360009c9190e388e1e59f4118a4ec610ca02840fcae9a9200a3e2cc1588c67a4b582aa8e015bfb522ca216d4197170519264bd6d25946ff8b792db5a1725dbbe24e9525dd0c0c73996939292e7be2b74074a89fd37a78677af59167f612c5de4f4fc86a9c384ddcd49ddbb0aaef7454765070661ba3d1d93741423efcc6bdb1a3ed2b89454838bb5a9a3bb7359e866046f34319d3cdbee2d33665e0f2bd9cff09bfae98ea5facf8fab02097207a7e4a919318d2f56ad11931907366a2e565b936a15c2ae5c99c21f1b15269d831052d9ce3feaa47780c63ccd5e273ee8389fce31b0065fa9dd0e0b328e5b55acf308a04797df7a29f302e19033b44143164848283ca35244f2380ce67ad25ee9f0533a1022067311f7a17c76f8f56b7f2234fa63c5e658833e09ba95210ba6a851311c03e4b12ff91df1cceec66cc625798f8a90451ba5f0debaa4e6dfab16ff4b8bfbc978dad0af896e1067e40c8361d7ee57306572bcccf3bf4ad85349bb20129d3579ce6a6bfa878e0576fd7285c94e06278d200eeb985447ba259216417ecf8b811da2dcd162cb4b3cf5dac7ee0da829e7cafd3bff2435cc697a3045c40c6b9586895a38fdc52cdd4fc842120ab8698e3d3f2371cfb9dbf374db8abf236b1c6b8eb4ae5bb91f1eda41e5b23f8e0833011343dec3ea345ba066ae2e9b9cc5226994b4d188c83dc15e02aeb05de90dad035b13ed7b0a58b7924974d245043a1a3f4679613583c08dd6983f4280887a71d0c7d75f79f0e24504a376b8abed0ee46ead8d085479129b238c3201a02c991bd0452ef2b04571cdd5de96796d3d4757a93aad4a080cc81274cbaa7a6ee8e11794727fc1afda4049516ff7db5de64a2b14580f3e1eeec4b8006c031681a4c4e78e49c860024b84ef8c1542ec62b88f3ead38e80da1812e2c846011a94d7641ea95313f750477fab771906b85e2eacc4ad5fe393254ebf3f3acec8c283bd3c64b929db34157e3bb82ab83ae4df0586a9e0e541426584db7b85a1df32948711bf40abb490baba937478514ab0d3a8575bac555574ff391134891dcc493de679bff7e285773292b95be5f1b8c6d4b92c66974362f895e506a329499f4e0041335041ea590a6765f4d9a29c1a1770cbacce0a62ae3a3e2f4615ad45e2a73ff69e7ab46402fd665f950dff9615d78488963d634762013b8101993760121b89e88642c7950b78aa9abeafcc92762947d5297b9e4f5342921bf801f9897bb4736c03976ff36ca2f9146b47a39557435bd8774f568d202736a397e91f19cb96b339ea65e1400ad8d73a79efdb9e59a3b94137c6b26a9e996a24f387f36df8feebfa04a8c50d5852944c2cad6fd4f9be6f10f0c1adee03ea89c2e059bf2c546c98d114b15ac9d32b0d9c052c5b2f8af935199e407f27daa723fed13137cbd0113bf6ad76bbc8eaf52c36259000b9c811f5e87c0ff924a837e00375301009c2d26a44ae70b7f8bc03f30abfe23d190e777e2c822f26aead3f838ce36d576291964ed648af2c59cc1a12b64a73c7205cac69290f4992ed6af159338bec9a13a0a86eec5ea99298105bca465a16447563ada474a03825861aed434c3bb3f770837e205663a6b2bfb3d34131b36a9ec9df2511efcbc412d892b11a43100b780951fbed464a39d1fee1a55c52deab8c2a4f1f7c4f6949381552568e84911931aa8b28f351fd2cbd7deacbbaa99018f82af15ae3d384ba03776c88b41d45189e58085a867f19ffec1e733d4f3074010db9931c86a0e9667c2014aaf1965fae75667e4776eff551cc9899a9560221ff3a7ced61b03d71b26d211dde0614bee19f69b85217faf3870c5d7d11af1c7c09b23d14dbad9250ad12d7300e97c50e70d357b5ea0c82ba87e18fd9ab69da17d878b61b644e870b35ae8452f628013cc197c5542510e278b1a532cb56cb48c13e94644e036dfe138b38ac414158a91c8ad88ab3365a743be8922f229e74076690acd58598a5e254cb2665755bd503e4132d60743bece57eef2fb4df9bf23c080aa0cb9a8b25a14b4213295a6db0b1945814c76ad356d84067a8f263f54341d898292e9046deaee4d3adc5da4eabe092955be6ac206a89eff4b06d635dfc1a78fb175eb7323f86f43d63f272fec48df3b8353176064cd44004bd2fa37cdc78be2f4f47160c7109cf15ca9ec621da51c93cf144d48492ceeed98b9ac9404d0140839f186eab17020fd94ea6d4cb975b13c95f56d0680ce35e415d2422503523a332087989d3e38cd710e3dca1552a1f825b884ca2076c07b47c1e4277f7251de5f5e77d92ad97182a7bd8acb0436bf9bd081dc4eb28b361575e39377df9b0974cc3e298a6c8fbd7bbf8ab0e72689a31ca6d7d82905c35c1ceb6a9f73a11410ca4473c84fcf084a74b5e29d056d1a679aa3996a292ec08afc6ddef7f9df328d33c5162cec36281c467e60b247a1b478cfad789c07ce6fa0661c67051b349aa83e0242c1ae81682271b00ce8c0d7027cac6aaf7161a8521cf8529db33beb6e0adb916d5939b842b523d04de00914b6b8eedcf9949f4c1fba87054bb964ad04cb685e7c481cdb2f7061b7877854c56e0e057f622294fdc89e3412f7d6b1023ba802a9ce7dca9a30e11a098da8a5ada873dbf7256064a42fbb7d15a7eb5fe88f15ab0a38400c7a1cbb6284f04996f21392a554b0198d0a504184b718b1c5b840804a0e842e02ba64094a5e408cc25107b9321708807f14c49900df8cd5193ba838fa5863869ae0694daef1e535c04aab4088243a65d176f4039b91cbed57e79d11fbf56eceb0bd82c811e4eaf5a46bfa11e66a40dd33b49f9dcea0369d735ca6f72e21522629a59432bf044a04a3043fbe5f307b3daee5baaee3eab594fcc49cf373af661a42eef75e7b35ddc17cf28edad89447e5a27beec2f300c460899d3b6934e23af759776c09358c4035d11d0d9839951739e023c1e3482b1b2c7e76d76790900e345436a9cf20a11b4e2034d620f4424d6b7b7d0609b142a19597561779aae4aec573ceafb8de3a81b0b5fad09cc9fb44d57b4bf75e5bf18b2d68b5585f8cf125d99d5b77b4c604104037cd2d130c4f8f35f5ccabc1efe1244976dd87eea00498a2a9cf9e6a6553ce4992c4d3c39387f330c7ebd8563af90ec337dffa869c0826f64d68040a938b1125e9081c486490181a41488c353c9aeedde85e9099ee795ef9a47ba516bcab4186c2caa7e3683a77a373fc725cd0099d0bf21274c40ea451180e828c00e2fd31bed10b80711163c74548d131172d4450c1f34bca9c606f746db7ccba25c2b505a85b6b8106c8987971346cf9a9224b4247bfbcbe28e276435c4142d642bf9cd66083d69aa4e50c0ba50a2cf0e8e1b544496c86243c62b4272c54718d80355661f1a0220b12028b0a3caad43e2f415d5a1e0ff4cbf6ffb55ff41944e506a3852d4305184bb68c0e98d93a4a4d0c3b78a0ca95cd7f22f9a02a5bfaffdf649955d3a4d56c3c9adc783859c5385325091951aa90a1b16ddc675015a22e2c7e7345887efb0c42824a1779ea476ede8833ca6e79ce6d67299307e3e89667287303d887c1fcaaa0a85fbc2027ca622070c943b75be6684d5eefc06c31bff4ab5b5e397765df4cd4ccb2c5fcca37ccfcca4074bb33956ef99c59ca8cd2fed06c04b145ce893ae637989f30d7a13bac0dfec8bdfb44420c0b7ddf120dbef3879b37dcdcc08a387ace8e8ee65c3e39bd5cf39b130cdb5a6a1f1449e8cf69a9a33b309839945fbe2f8e4eb9e8e2820b48244ee2aaaf7a1de48ec19b89a223fe2513420ecc250a500aaa7a4f9157c37e2fa3904fd12adf47c21726f5d5144a4a4a571df5d3f613fa845233222026944e61ea46b5012daf1cb238822462801c82b8f8182165f11971229cccc708e733a27d3ec68ff9bdf7de7b6de9f21f81b636b179cad633b05b90c7a246515f7ab0d41395d2e228b1d7c5812ea6628bb346472cdbc2bfc5e7130d356bd40e7a74a209417910304d94177184972f6294e8649ce8354c1e70d239b168d9c087a9c10e3347940890707e2acfadecca23902671ddcbf278377ba39a684fa82271382050c2e2ba21b6386bab1fdb795a7eb6921ecfc58987d2da99a5d99a4dccaf1f28cfe292a5aaacd4d494178dab1332c49ae8ea85125c84848686ca94e944445de6840990929b9017abba13c278628bb3b6caaf1e185862e4b0c559fbdb8ad572e1189d087feb7293812a818ccc9a280be6247fcb2c60f9dbdf7030f037cc697a44c05223822dcedaea5f7ad6645b75585b0543d3a2ada21535542d4e0a2b7a420942680a616857c8075e75477c5b5ef529248eeeb01d2f914a235de2f92f46c580511d9836212a95ea75c8538b2d5296aa42a953aa957ea3471980a2ed1e91ca6c91b27c7ca02a8253a17c50f5ca334befaf3b05d17951782ea0d82e5edcf0629fbe6c18526c91b26825c088815221868c106c91b24652060d8e934d5333660b5199998192691a6634423e5ff86a9ca28c3d5c8dae0421738ccd06ca862d52169d26ca6b4ffb592fb39033558f8f59e3a331c3466ed94a80334c04632c368e39a074498001138602797053eb8fcb31c7609d3d2a506da593ce496ba5738a34d5da2375da39e79c74560a060c1820272ca06a3b166f09479f1e08a48e8f74cbafd799a877c55bedec740ab5fc5a9a79e42b50f5c557d4c02eb09956b045528dcb86498b19326cb106d64965b7fc966a5a35f420ec97d7b82c4fcd946ab2dc8a353563b734af6eea17ac81d5d074664f2f4d08914a928c34239535b01a18a924c92eb0919ae01709d380710c8f980ac62fdcc30bbf26ca72540a5bc424695677f05877a68cc42ffcc2240d0cb58f5374877daa01a6ab14ad283016670925e1d4c5616310609d22a5fea4a5f23ce5f1638dc31627397b263ad5b462b538bee921e1d46868d7c61826d8aa182a8ab305ad29eccb6f89ab0320616e7350d8d6c692c8f2c5062b769018f4856db92dd518b6d5258cb1aeadabd6b9049d336bb6da6aabbd3a4f5d33ce696dabc2dd11d20fd5e683ca33afd805d467e9fae93afa2c619875ddd53aefb374c93a7739eb619c6f028e748c17307b55c011ca475c7b21983aa695eb0a8ab4db7c507be5bda786f0bc8262fda072093c68f31cf3077f841df3b0637072295db10ea3cfd2e5a47331f37bf3bc36f76d2e0ffbf30c5a2e5e9ee90d41bc3619fc11f60731382f684ac19600e57a3be1489224f72637b949156979be4d52b2dc222567435cb4d01efaca70a2b0e84cd75a16ba686d628b94bc0da1d22d0acbcc09948b0305bbf012f84f32d4a674ca7d641406b413164db2875016f490894ab2adf46abfdc44bac92c9587d20c2142abc663b715e527339692c2785419aa55a1a8b6ed35433464238b846eb31a462d51e1b22c4510a12c4b11cab224dae22c6be4e7efc1f264b6618bb354e9a0dde910d1d0fbe051c3fc5b05233f39cab2c559bed0cf7e888915aa3bb31faa3baaafb182d32a928a9249e954d40d3a3c5f6dcdde53988bb5d06182f3e77fd415afca9f3f93408749ce9f5f477112aa3b624ae785103d22581d25c5825a3ad2746475c5e1404ad4e995abc8f272f059d397bada593ad214348dc0cfea20e9cf7e27d91667f971e0058fad7b31c658ebd288a7527d869607cba660fcb226cb37b68d403c569f130e5bc436cc9a714aea8e75619ae51971cb71cdf251495b13e6fa73fe9c3fffbf77b9c52e171ef188f1bd185f57cb9b2244922550001e61ca75cddd7d6cefbdf6fe4d063cdc7b6d77efbd95e6d86bedb573d6f0de7b278a8e68071ee46e414a929144df7cb1fe8bf5d37299d7fa9be0abbfc9bdf84718e3cffa7ed64dfefecdba23715c898431c6e0bd9f7513fcfae2c78f39e5f93f5fdde47fe6e0fb1dd3fba0a594ebba8eab99d2129da1d69c3e1ef139c2df64641fd3c7968218d04660ee1abf6da2abcd0f2551ae1275e8602034a7f211ff74680e5733af2312d8c4c62a209306c0c9fe4f079c443af6de8b7f8431feacffff34779ecfd4e451e1e89363e0f1519fd7746fc660fe7c69ad2a6bea46259a9d63444feafda07d7473ce5e8facb1e53994721b3ecfff20d8fe01413f38f9e89783b6d767d010abe3a0211490f05c9f9a85e68c182bc498f9c972c59c600a1a9aba532d4ddda93cdc577774d7397fd6af75d6f9b91e7844346788f59039aa778c05ac189ff882c40b171974cba2c0b50cfd95314920e0c54993da0a5d56d0c26d67f981e5011744804fc057ba13c48cc162bc74197d068921a180d9229dcd59c991bb729b8f30b6d793d9ed71817a410a5c6ea22c1fcd1ccb2d1d4d94e53d3eb8abd5687e40bd5bea317b2d5da0e6ea8160710fdaa7772fc7b487eeb60ba573de209603a13e74f2226fc1112ec71cc8e5984f5e24ca0481fce59817895231e52916a594524a29e5947ff4f27fd066f2cc6daae51981fa7cdca68236235cfe1cc8e54f244a0589649008066d2a3802f599d3e71ef1a1b65a202ee76a87e3cbbed5c59320960709f58962833990a73e369717b9a00d0647a0fc3910caa35c10c8e49917a1fc799128160492c1220fd214cb47e5262d805d790f3e51ac2df23e39e5bd52be2a0189a5a29ad0c6c8483c9b283033470c1699ccca9a6c11d348376ec5b1b856b722e7ea565f7effd69086ad7585e326a353a4144571a96117ad34805cf6087b4f602e46b560afbdf5f59f5080a7743155a17431e524855dfd82784aef7858c5c81c336c11933132169391646c450515afd70bd672c9b6f8ae96abf56a8defea5eddeb5ddfea605dd775ff26d8e2ff7ff7ff5df7df79f1b21a1a8ac562e48c46db22a6cd68b3d8ac468bc56833920b975aad6683c57ed8228ec162b01a8c8cd56a3198cd246412ea5cdd58c5169fd562b15c2d97abf5ac6ec4b4532c45ab996a6ff69e6017a35af849f0f99435137a744a62443af940e24e63b8eef4a4f3504c3c17a7d2c50b94132f44488df0f578d1e0db3dfc3496700b06ca081831502bc4d05a06ce2b85391934a820686aaed4ccc0c9c00c1a58d0f84e4f7c354e45356c9cbad8b099c2e6064e0d372cc071c10200a06a0098f5027d01a7c24b283125f0073000a71d027073821b0cb66090011019e0403dc111e20085262fa61ca82ed3e6d07162c2e630853832d00182113996e45862b3b158ac16292b628b5846ca481659ca582c19d99acd66b49a4d055bc4b69aad36abdd6cb399ad46fb988c12df7bef78eff5c6dbd5bcd6f546cbd3d9ba9a3776356ff458ded8d5acc9fae0b8b6e88d5d0da88bd8257aa337c2620ff35ede18fb98373e4c4699851429441061abd1acb062f67acd4a18e7e24659a9658bb8949532d9ace45c9cab9471e32a4666d9222663642c2623c9d88a6391321fb68865a48c244b19c7e2583252bfc5165b3cb2246eb1ded692401f140f5b0c7b99ba63ed996e75517eadb3d6f973fefb209ed2a3f5ed80f65f793ffccda3652da33b309893cc1ccbed25a2db1bbdc5b6a8656f9b28cb7f467760f0a998395f45981a8d365155b6a86396eb98b6527934f9379bf3e7fcffffb5d7a596fded6f5a6631936af2682e58b7dbad5b6dd9e2af447de36edc8dbbdd3a994c46be8090c18208014c46be8090c18278c16418865a814b368e1acbb08c8e32d46a359bed66668bf866bbd96cab1b57e36a379b4d269391caf175db227e8daf5136c25e32d96b2495a4db2a465ad9222663642c26234937d28d8cadc67184c5a48c3a541947584ccaa8436c1cc7d3150122ef948ba97ec3ebf104730cda549bca69afa00d18c8949d81fb5ca24d28a9e1ec34357cfed5f0f9d79a2d11555bddb1b61d8e8bd556c3f0a9cf7fa75e0f0b5ed89613d526ea6d694dbf9a140665dd952d2d4ff5796ee3fef4e7369db31d474bd883dc29cfa5dc391c442bd36dff17b55dd51d91c3ea8e586b3b1a6806d1a6f4f7f9b116017591c6852eda1f1042983b1d7ffe63eebce0cf4fe10d67c0e4d9a17f16bc8a2f8afe64fa3fc75c9c43501b2da2674a94b462add1b02bbaa332a139cf2f286e0b82f92d0afd3945fd3f7f4177d42766cef34731e9cf2b288640fd957c3fd5d4710b8aba47018a7586fedcf6f0eb4fff5c57acfebca716d5f0e96da8865f1950c6c97317609dd5b00a1fc23cd16924d922b5cd94b42a10b5d59da26f135513cdf26cb01655d3f37aa60654aa630d9f73b97b8ff4b93a9911c57e5e892a0fb7a6af45fd791deb8e138e7a3f2e176dd7e09d61e67386790244bad66058c3e7357c4ebbc847fc39cd472ad5b9236ab0dac07a0116fb769b9e61b5b613c21257cc707691866dd7a669f61096a04dd3ec39dbe4e86153dee13286084a1ecc5ee384ce4dfb29b1c5ef069762ec935f4e85b2e0ee01352432030603c60cd570f61428ee13cb0a4b7418cf5ff4896585327d7a13a0bdeb13cb0a5e3a2ebdd741ed14b4c087cda965711fcd8308a93b934891c913640e99a24f2e7612983c434a46ec123e27f4a6d937be0f8af0f49121d6b1a91208f6cf93378006f5f3f9a00de59cb282d88001734029a87a61e79209d534f92d05a97165de7a6050800f569f93d3c967b9c720c4b4906c550f57551cf404a915e03167fde79653e48033ad622aa5c524d3313fe107f9d7c3ae9cf2ae411735e8996326fd45551f81306ccc7549e752a7d20fe2d52d97205980971eb28c1cd822881c9668a0c8038f04f390dff03f3202590c4950117249c184de4095167e01c923e1824e028521aafc2869a5a09564a19a422ab03c65f99cb2aecf2025a4b0c235be66a86a757b00136a38b915359da4d67b739e4aa95407b83b98db7b2f78cbabafe08a5444a932e11017fab8540eb8ce77da3737288dd6a84d9c37bdda2cdafaffffffc7506688396729cc48391a11e2565ba54aa5c2f0b9783167f1fdc6c75346fb7d7b8f3d96c34cefe36b2d27859b96c7476767f9b870a1702855868846dfd837e289d26c37ba624d2e6e55999285248f51187dd171dafab7fa85d2c13a50345252284684a892a2ee6386cfa7f7c1e432a55fd9e534ec4f822d4d4d7d8e8c8cd4fa31e06b2b9db3d65aebbc5ad49f13d72885dff7fded777e9efbfb3ac0c0fefefbe606f3fe709cabbb9773756336e5f65a6b2de7dad45a7be91b81f5e9c2d6dac93f042bacb0e9c5cf7aad2b196d3b4de9ec9cb0188f48a32b58a4c7d75a5dfb9a6ccdbb4fa5e3898e273a6c408019aee256e76a677340d99667def34c5953684d4a2ec634f772f9d61fd6f611aecf83b82cf3d9769aeea89d7ab8c4202ea3ec5b8d548dbf685c52dc8586e9158a7da76cd21d9f9f96c5500d4a7ad45c3450c4a07169e2c4e6fa0cb23206c60956a4d8c28a153296f89042d82595f5a8840d9af5a444331300100083160000200c0a060502711c88d26096e40314000d59723a6c503e2e8e0542c1381c46511044411c82300cc2300882338421869451f60c5432b44a52010004d5a5a99a47120d6b26d859bc974829dae373c394e11bbb227d1edc0a3b569664840a5967f64a3119466f83a469794528258e2c60492f431b1fae3a7369693178f75f085196852d3ea0779fe6e22eeac563ce10cba943026252b4eb2cbea4444f234a92ea1125716502864ac3b1deea7edb80c876b8e87f269606671e465a6d938843bc65b417cbeff0594303c63945d8ff564e470aa358b0e28d360bc108c88bf1bf73c0fd6c24b4840315f7beedaefe0ebccff50234d9ac9a6432289446b6cef06385b7f3721efc2dd2b88e449e937fc59ecd977c6375f1b46ff4a54bf69f6710769e26d74900f6c339f4e86a6d30986396c30a5062f757f4daaed15890d21fb7782d04b218dc1f96606d7245a195200a9ff0d3a277d5ee41b60798f973ca3162e3802b4b784af104c5c0be47bd1c8c0dbad3ba4cedd378c8c2e7ae07a3a7c33c9779eb0f3499bf14c7700bc14da007eb701b2a178be0ceb28b4530bf8731763b8615ff1434c349962831be724fd2a81390fbcf4a5589f0f617fe35daa74ec97429b1870c5b13bb6ded713a32502913afc9cb19912a3a2d55bd84ed4e067412c1b57545209e21f58afc204437d0644432c7454d6262fd9748310527a659ce1a04b16d0f3fab40e4aa75483c8c638052ad4a051ad474ed90039c34373bef12a8164a6a765b5df47a077349671ac271bc76a0c088424d7f10c518a1022d9802dba3bc93880c6861cc1c3e70b9b8b752d9970c511a6f91cff5b347d11f1fced1190606633563858c836511229d7515cba5137cb02462d43793fc191cd62a102446905f311b6eb6369000cf1abcbbd4c425608d0ac888b993d7c1422f5fe7fca2e5b5bcbd1343106ccd18f0f5bd9f8d8830ee3495674058f380ecb897bdeaaa8f451af54d168074754b8f03d21dfecaa4689630cf6673f1107e9a8ea3ce0f904e3439ed82e40229060a1537b0b94af14c8e686d5b08d93cb95ffdca619910c948aa68983e548d2d98d9f6a4b8d5bca27bc90bb621cc1610150205dd36974114f59b230d298678c8aebf9b1c8b40a9e12b37a825957ce889c143454d7f45042e2c1dda91fbb3872d5675fb5ae50e491e57448c5d0edb191d4db14c70294372170b1d748e1f476ad9894a43b7ddfc6bc4e48a6061981be515972ae865f1ee803128235262701a1c0f181c14967182c50afc4d4d2b289bc586b0b6758a22cec72d9d3670557507e20943d3ccdaa666c04cda9d876391270ad79501dc5e7c72d58580bb184649b045394d3e93baa82f26860ce8404cd387b2b741a0f985270a13ededa39dfd67ae40fd12bc6e1460a019266ebcd5f78d771650de38f4fa74c617bfc5afc181bef862e891c89e4d23fc52fd8e5d34087ff4d80744c32dbf5cd0b75b61463485a2d1727db799867dc9782dbf870c6d134dc4563a38418f7088f9928711e983ccc4db5f8c20abf03c4706fe6613d31ac4095dcf9f7bb8b9489eba82493a5bc7e750f529654b82b5535918be80e4d0c603de5a6373adbed34e877ea96213d168d1abf585cd11030c81b4b6d70b03d8cb7c26029ad55901d700ea8d6de73ac24cd281f0c2b0031d93629d43b8b0c59e98100db075263e9296db4a2a0b35a44308d6d2292da9fe5c156f0b3b1223b380a04d2630bb249192d02e94948abe163455f302595ad034c3c28b14159edb443038d0949aee49be837566087f0ccc6d82be66597b351a886e2823485df346f7e393015b560cacde6a2952a557f28f8d08e6de06f4b807b684a90451ac27ce4bd607b61039d4562c4df912e6c1730117102a2b3e0ea1d081f45563c2ac81edcf791758d0691e3c36097a9ce45db644de6b3e466856925fcb07b033e85fa51734352671c413d0eab49f6544aabd2232ed2bc830cc7036a5ab31bfab16d416838d7925ab16be191d741274b71410d94480a8aa93205efe189f2519364572ef4cf36ba2d22daea51fc307124758ba4f9d4ccfe11619ea9ec0fd2df3a649c27d81d9592755dc64054e5355cf2b740b250d0b7d99cf1a7e015b79ed2c0b35683f50d949260716bf8c8bb181729f5a99ece47bc50e12d5d83f0305d9e9656adf8eb570b1f438842a736b5478e99b51da90a3f1318f36a4421c2140f5db1f867d046a50a6696e5019c40fa11d5b0080cad0838ea511ab3d0b4d066c2d928ed6334a41f4fe2ee014e9f6bbeb0292b01a47bae99e38eaea3c6606680386e3c8c16cbce5cba8c9e431fd4f0090a93e226b41da638ae380c44abbc7a9729f5dc20e4b5d166e3d9600ea54dc67b234ad66cb976987d22c04dbb41d747ea8a2f670170073daa4d12986563d06b18a1d8218cb797407a4e3fe47c11e0b81d226b606e592b5b098736be2a97383e076cd5cf63011823b72f49cc934432364ab95ffe20ca424139f6b9a7949d7906fcf59e874f5a524abd9c855a6b9303e0a250481765e4af907992c0523df3eab85d647b3c123602bf63a2cf13396fafb530ab7ba9e42b501f5b95b451044ee79aa835a4ee140b4337ea647a48f721b82b86628a902e88fdfa022e043df56332443ac6fda14e421809ad8fb425e7dabf2b504b4f045ed841b983a0390b78944bb650d92aa8187b2ed0197c4d0e2f29822411b7a13fb2e8e1e3c3b2da4dc9cd6bc461feb8ef83471f06bc4d42aafbc85b8ad27e798111f6728d98ce3a4768c6a4e786dff6cab084172b068c9a814f6c8790c8517be09b46f64ea7c4abecade6caf5ab18ec02936f060ae81752dc9c9c06103e483dfc64216c10aa8f6d943c080c78c2690837cc0722ece95422558c8069de45cbeb93a660b88e271e5f9c5a2c933bcc2c458386bcb1eac0b6496b6b6484a1cfd52db03f860a857a27813834d0248c77a9cd964a5ea83849a7c2ef236722ec40059c88904564ff708c52b9a0ac62b115654b577b70499bc26de6cce447b0dbad17a80948829730d916559ea240c131ae990014a983ad037966ca94c1f3c4d1be95a117941e1b124be5b9fd68bc281b3495e8126580dd8d274bb0ae4b71709d3e799b8b59fa758e4ae2a71b9e39a2ceb39802a20c0bd798153fdc418230b01b3355064da4e55b70717e8f179747a04a33c52ac3eff8450946a92a2c88b48aca024e6179b3d5825a82f9a0639665680449dfb123ad047d1d98361e45628805623e92d3c24e1f14f078bedc340c482f54d753bb9968447d90cbaa0bc5397711634a21b57eeeb411305b518a1b66e3fa8078dc458bd48d81844f24e99f79f56577849f99e6eb1dc1a8f2236e5750cdaf11b01f5a1451f7527ecc513e498a467d771cf993ff9c65addf2afe22e5e3e8d269b055ad43662853f2a0e09824264d40f1b2b968b32135733be559f2838161af794746cbf7495b2b753b4b819e8df4b16952d881ddfcc507f7217d228e28796fe95e82ac14f88f0e0a1846e36f630ab40afec592574493c929c30af449ebfb3cada7da22adc19e12a4ce074e2314415ade5a435610040326021378257de660492f77d3c0e1e567f0732d987f77e0f333b93828da46b769ff4627144388e2c3d97754f03102aab43d19215f7a9a7b000a3d8ead62614292c0cc3e274e110d33991aecb3f81042e4da67de76ce387e5a0f1d6115ed8221c4b8843064fcb255147028f148f68ceb5f5df06468ca3244ae25bb097d7a0eb9e5e3e05f53d109032b937ebcc191f6e9d95410bf13e00a51de6e9a5543b628dac003d95448a4233cc38f35dd15e96517072da8d199ff68cef852621b3b36b3884081770b9c3359ddac94776d150ef8ba28bea4114d3b87441cc60a2d746c0165d544a5b6ac830ed61e618174a79d9d078e3bd73e2b8d61879b16c344563e07b739b05f431de024ce14ef985e21f4445c5d449fda328bc2a691abbf8bc8995dc0eb398b09376c5b9bae80dad6425c6b2313a92359f36c319936c6dd672da2829599a5d3fa29fbcaa2899331f3cb7ce2cbac53b389960317576755693aef3598f7032d3895e776335027fe5716a64a601fe65e6703135674e0bd328a4c0cb7dfdf181e9a857374a151036c6253ff082a7c78b1513b48a929137cdd2a0ef7d8e131ac7e3b84aefd60b733604bad136d32117427b5d6c29dbcf893d980c37b559083c824c43756419e83136a96a4b08bc8c3f02d97af2eb15cda2a6d209f91c8f2dd2b65fa0eecf7fe57a1010dd75d984392f094ec6b667cdc94ed27ac9b40f5bf8076c7279bc66a7d30d467557fd06ed6a20d61d16187afdc0fca57d2c662bf7da6371b9224a158841567dfbf3d88299808a9115d4b288424b72fa7f64e43a609f0b8d4232afb5385ca0f5e6ba188040f99d00350fd0d9fdfdba55e876940767b6f5be507667d58331c6c33d6e3ec218219e2252c715782b785401068f0a766fdceef191fb73a7da355121b5b1033e6de8a4c0b3a6606cb16b4d5af5dd4c51f0ffcb1a11cfb478648b3e6d3eec0b318e669e6fb769438dee20f0d71d1883e369a251bd3ae57b0f06f8f75cb5d7d59492ac72577408d8a19e13e85a99058b1e39a45ae95bf65a455c21dab92bb45358c29bfdb09c87240e8b2b27832e3bfff1de482b24284a61b80871d9b9206b1940161644f722ca4386cb4030d0868f4a2dc89e5859793d75521b482002cb08479975c1a312aa6670f19dc29d848b7091cec865d89c90da38017c9c3232013ecfa954203a6dca00c9cf9d9d2ddf3de1a17b99d5a7bf0ae77ee7ce2915c7bdce6b5f206038377bb20600cbb161c00c15415366a8751076130a166198d9900908bffca0068d52576469b9facbd1b364c3f5aa5a3e2753f8723c691f72ab31110d20de0e0f5a1b654f7605a221383aef8c827ae5a43422689336e201238506f1943a2e1bd2706d05ad6908798e26dce988b8a5b183d3eec3141289a3c665e0d2b0205f59b66b79b15cc2a16181d14bd2d0f85b576296f3ef852c9f561a4c28583b7502f72844696de010cb7914ac1dda7a9e930cef0a1fd59a8235ef09bfc7d90859e9aa018a6b536bf20c163096066b9dd16a2830cdf2ac0f4b8e5659bbbd3a68a9914be5c295c74ec8158a220ef40a9c07184518e3189820524e599b79439d3cd88a58f3883adc6dbcc2aa3fb0a0e70381145b0cbb26268e56249aece38eb3e675edd5e6e54e83fcc7f6d6f9f09b650f981801d3fa97918ff11fc73f60dd6a5912c2e7dfb1ac67ad72ef16bc98616bda13600b107c6d8c9d15e8a16720d3317c4bf48fe9d6e6cff5fdeb22756a8f8b36a98a0a25fef131f9aedfa87dd940cfc80dfc23df540f8f73c92d15db4e92e79cccd23e7d2a46f3a5f0bcb15cbd9aa689be0a4bf1478c23baa67620cc194b3409cbc3c34d3a9c7f8e84fba13848c308c657c1438268d42091d8f860d5022aa97d8c97da6ada3ec9d94cd5719a71b1ba6184a6a01a25a9536851e3790e679bf8a2980c383bef4f2267e0574be9fad3e7106901fa51b0a5090b2386cc01610e29d9a28a2710b45a6e486b476c01aa2795603df27e7a92ee020050f7147293194981d46b36f4e731e6e47712f6f4e14d5f093c4835b31ba2b504ad8637ff4defb33247bbbc349db6bae23e723b6a07bd8684e8cb628ca3462df9cf1ce2b5b679f656195666d3992d3b0d0c280e9d91246b4e31088446e5d5f5f22cf2380d2160d12794f61580ff150854a636b96110a90e6eb97e7d99f0aed4239d1ab060899e1be8c172c0dc3fb3816522299f13c07cf3d05666ba00e42a0774a43c687b66de87972f3c98582c290f8b60056f5815c0f3fb4b2380aba142019c9db1f4eca7a91d5bb185fb73fddb12ade8de6065ee00ebc441b0350ab4b78345f77bafd51a28498ac8c494b78bb725c7bc0337939c3f378091cb9a853c0b6ac3625ed077d2d7ef40b57f78f11338684591e60809ebb1a57575641802d0d6d75492d9983fe01c38d811fa02d120248e0980dd8445da35e17ba62f4cca830d4c028a3d0f955049fb86e641ba19b421a7e5bd7139eb9c65ff7e16707bcad13993d5f8168992d67c2a42ce8b85d2f042ce09bf2878c6c121052b505e66db01a366b5fe72109e488b7e5165a071921ec6185e961042f4ca47f56d77d03bbbd8da52ffc39600eb080db81f64354cb2b1e6a9ecc355e0d2b157744205b052d6bf47a097ce67f4f8a2d48b89fd9e7cbb681f311c1086d38b872953a0538365541dc7d9f8fb37af08016e4e0e40f08b09f759a3afdb67943ae82ff5029ffd950e0f34a109e33d1c7eb1a343163ceb7491013126fae524b38765ecddaf7ad8b6e9d2c415c2b3398eba5d9625e318ad19d336b72c430fe7c3e837f1c7c15e6d170be7e53e8cfea00e9fdef1d1b772b845d3ba3cba83f1171f3d7c294b8223da334cdb1c5976d51ffae12027602ff8dc5771e840139a1adae1e8171f1d662953d2115b32a69e5cd96476ee794629076938daa75bae345a1f9d45165ee0958031b19d0e87f137b8bb3699c61177cfff08ba77ddbfd01ddacc99ea92b4db35d57c632849bc902be751f80954a12a089ee1764120a6b10b82c8a48a502cd95278ce317ef7f50a9c0d8c5bf06110e8c2b55ecf0ab8f33099027e1f365bc8cbe36505f8f1f0bc2077e3715d9515e0a13fba9dbee0143078f340ef4d1ddb5741d629c0caba006b69908a851f18469fbede83c5980031f4ca0db5732e6441e97105ff5183620d28d061111a3d526a771431f00b7b960f00ac15b869956596086e01173f3c2be0f4785901171f372fe4f5b059215f1e972dc0cfe37305797dbcac80cfc3b2851c7cf8ac803bfd981d0ec4421b28e9ca300799b6c2fc51306803818ade8f96c03bfc8e192596ee8ad9a9912f704bb86981a389772a744bd879a123093617704bf4b9a07bc226054e12362d7463e227054e249ea9c03dd14e850e6c22f1db9f4a85abbcd77cd5e44a5ec7c8b75653676b9b98d6dc414b06d579421ef3f0032160fa26e21b9b4e8e75eb6cf05ccaa0bd57ed033f1c6417ec0d5f7d2986293451d1e33f0c7ea3a3439767c81ca34dcedccda1b1a79301427fea611d9baac2800fe2c7e8f8c0922c12c76c993337b9a5874493a4e44d459ce23c93e57c05d087a9a084be41c66d6d725f85bb2b5538be10847b5b53d83390eb5477ec38c570e83ffc02628bb90f9a9e275d040c696664fbaa50137c5695bf1816988e59ad6a7520dac572eb2a15b70a42cc3a2c35fab17815579f309d7346e308fefed00182204c230f180e2d2c68a9cdee244d07eb85cfa777fb50ea457adeea231fc58db9be4c5164b2e65de09fee03f4424888ea42606b86699b23cbc54e291f981310c6472c8b267a797487f13f3e3e7beecf2493dcb1108f32e55714c931a40856ddc7c82ec28dbc736ac2d5607fb85db6239a923f1a0d1f63edc8dd692eba98f91fd2f134d1af72e5235380c291677f3b93dbd4cebcf0a05c36c7ab1d7f18ccaba16cb047a6d4937ccb603722bb338c735bac5899dec2f5c67a4250104789ee61531508951c144703fad0b2ef1bd64a1fba7827d135da59de7188a0b54d8fa3a51f5be9a75286c66596602b17f66d9ce7189138c5543f9560e02b322c62daedf3aa5ec90de0e3fd4dee0e12b0342497fc61ce7acc8ea40a1a8e4a98b5ee756b62be512b882b087c4b28cbd941b2ef6345f233988d7c12b2e8e79c6bda78a82a6a8d13b734be368ba59c304473ff98bcb11b71d11f664e08d842d75eac8c626ba5d9be6a54c959ff3163e99d5806b8d585de0cb901e8065568692794db49494ab575cf14d527a3880b5ae96de57db32d3821a1c115ca10a1670402321d46feb8a9d728be712b55ba1bc61a5b5e18c77626581469cb39f6852262ee70eb8d7109736b45bb3033a41640645f12bddb58dada14ee3365d1ed7587d08268c3e8ec1a7925031526e354930cba87e743addd7b2c12db91297d101bfd32ddf323287c66c8dddb54dfecbcf3eb8ef539d51531273031043da9fc1499a585189845cb785c4cc716da011b9c1b7df8c7c98732d4f35162716d48d6a02860672a867633d5c1c0390a6b8f99b8d45c453277c286fda485f18eaf4644c7fcb9e64b410d15ea3b808dad73a5f14fbffb5716d57a9a9ee7212773a450447af359be47c542066bfbd02049f3f8859cca7418ccfb2b7e5a77020012985568394001cfab5b676fc6a77e75646b2540c0785611c208d34961854c3d05b98f3a427d74deaecfe0c974571293abd3c664bca25b468933cd6c911bc74fa941cbbd61dfb3fda41a7c185ea2a9ae0ced20fa8d8fcfb6fb3165480427a041beb12713cd09ad4d0d0aed8efb290e9abb89c082d3c3673b1db9b39055d2b12d79a646eec3f774724ab1f591b327614a0cf134652bb43f58a3da71dcc6df9fc94a081af4c994f22447df8b450dd6b7625f99073f6956d2df96523946e25dc73337dc73df38384a7a18d6ec1d4e7e80d097a6aec0da1b937ff45a0192b1dea662c840863d18b50fa12baca18ec9de0af07a11ff5095c22f85d64789004c1002a36487992e9aa0fcbf96123e91bdba7961d9a4c7d94b5ed53e198a514492ffe6d70e5e4f0d2162c1bcd8db7777e1d94a5dc1c69b88df85b9098607d8be341e81bf34004190ad03c72e5d71bc2531965e7a118e50f7d7d7bf2a28eb3f57eefc30fec447e195f2fd064ba19d477ed311bfed41c6d602dbf87a284109c7327f0571c811805a1685464433a512d01f7d1cd03b88f839fcf75d1b6c68ec407176370ff7516ebb1cdc7680c488dc9da51c73bd28706e2dd961f3b518c48fba22f833ca66febec093383a92e3ea68eb262dcf9b28a3965e47d62a601d0312a17b6b1b930c1449e623582e502bbb35742a3046379a56ee9801853e9d7d22c3e4231b5d1396024f987f8f1aab62d15ca784fb3be9c20b9d8581399873360657e38d096c6c17eb3c60b6a32c959b4243bbfc8d1a6a23f91d5b0874d94c00034901b8b6cc7b34b510ebb1c06dde6e7930086120fe5ff631503b725e94ea6904512f22b54b10d90cc605ba71d9427e4a5545b44fa829b84498507c37f147361580b06c7a2dc4db54f33a2a81df17a21d4ac03d1b83935170665f295a6e7f303d90b123e40ff948dadcf4a650cc06b4b7c1abcacbecf984b520971130370dd3a2ee9a15b885821e012647757165138f999ba428a83c0bdd96273404c6924e6257e3c4ad9074506b38e3780dbf7fe88100c31fbfa4fee412115d0477063fc3841f2a860ff7734504dc8fc23c51e7eb0c12e312493eb0c157e98aa2d6bc908865b80970f1d1236eebab4fc6aa7ca95ae65a4b8e35d069a2ab60734b24147f350c3e99b36c90f1a55027f07a12ddd3443ca6d8d6d5083fe00e4699183482a84b30ec6bce0759c02aa247945424fe9e92f494aada27b53e768bd6357d5364ebc5e63312ecd442742942e0790d5efc3f13eb84270e996d9e046085627a15cc09368fcf7805b75d09a9ccac6ccbca7359bce9cbc982b4c5bf3290283865dc8b846d03041f01d82139b577d71bffcf5d405e867235d148a14c515ef09fe31b63628cb3726a3089983685dcbf50d676fe388355e1149db754106a7a607775548fd4453e4868c81be0a0db001920a8f30274524b030c65336d80c0f2a189f6f01040205b59fb6d1919669b919c565aa67dc34d3f0697643868188d50d544c93761b47844455715cf2a71e343380d6ab14f26eeee7411bb9a33b9e00947994aaca5bda2a044818613e59dc0c736a117486d50b4820542db60ee14af25742a5b189d853cd2177d08784b0d4955089be5e948f123ec3b644a19a8a44ec37cdfc1868aa144173f0d4977b99e3bc65a5ba4dbcda8159a1b2f7182676a0b1521deebf0a6bad3bff3e1f5bbd87a318d2e9e04f6c5b82daa5c75134c18d7d1a7a2ea72e0ee3094c60597620c3f5abcd14339cc977df4fe140e8d358403f22384a4b42d7cae70b8cc7d4de217696683450a4794047a226aa35b7189503c57432959015d4bb037a086edc15ab436e4b91e7bcf2cd939a34811c7954d9592f9b559cc245268b818b4d0be34e132bdd0204bb433b19769421a33da0cfc128c3a24c9ae1a9822281748fd8cbef769c51d1314e8ff2741079b2071109c459f248ed963dfa936ea91f2df35bc50bf706ea6f0ecc7f5dd40de220a1bdf61de4a2c50fee4bdafd18be2d6f2737ee6b52240304d54443dea93a65c270cfe8644b23f27a95ddc3a7acefb9a739f304195b29416df7339bbf27c38bcfdd5a3687d0c2322e77889d0115f59a5f07eb6cc564b59e1447f2b51947d2d617226c17db21d3f62753556c02f07dd70bb387c44e0714ff39780a007ea4130ae15884995228410d1ec5a0c832f17ec4aeb822e45317ec239e22389cd26ee4eb06b28ff749dbe524d5c723675c39de37e70e4cfc16a11ba4fa07b1b4c72ec5f29afcbdfab2d7a60608c634521937479eaefb44d790383ab7cf4c01fd00152234a2c6b617c347f8e88ed33e3938c4c3af3a38340adb2c0bdaa136e66ef971a1c5130873845c5bea0aaecc2f5df4809da0ed81e8fe7169f728dafcce8fb13dd87373e281537eaf5907d60d3efed9bd41cea8f42fcddea97016aa728355e6a13cf16e18c033f3b62144d19e1f54c9389dc745fdad0de857a7e52fee7e395afa165b0557fe086e699f82ae677e7aedae872f3c9a151ec8696db992c5b47f4cc7b8c35ebe9346a6d06a2eb517ce6c138c383d5c0e220c5d0325b72498c5084a8f800aee28dc796c921b767b52a8a6ff1b6af4edd6f642396488dc80ad8f8f18f1d94858d23a62de18b1d458a5fc0e096c03ca9c6e7f61b05819d2912295108ee339563b64ba74c9da0146df8c9529763b0e56339272393b37fe2b85138b4f7bd45ca4dbc32e02d1fb9c40a25350d4c27d424e01544d7bc8ffff116e699987d1109bd9d5bad51c5ffcc0ba20a7b9fa1d7cb32a422175dc6d11250cc5df35d4bca2946a8914175e5ede89fa2587d6e28fa34ccdef308beeddc275fb76bbd1ebcfcf9dc45d4c6302b7829e4786b33ae2a6c6dd1c2ecf0d4b17ab99d220c4e04d03c3e5a6fd347fb56b1ee492047c2b4ece1b93d351a12813c84990fdf7e728c9719f86c9b5658f8e505b93c4dd935267f39564b353957ffdd6a2c8478c9b4ac2916fa9a7faf83a59eb8864f200cf56d022e8907ca61a8273d580ec67e070823ce250668a11529d9617ccacb082b5dd4ff04dba28270222beca58405fc8f808600834b8c09a975662daf0531cb504d85ddf7217d3f6f694d104547292a92917b5ed76baa4517369950efa15efc1c5e06433cf0f44dfe105f8c80304097250c7b80a8d4085d67df1fca07fd6c469e572aedd2e83db7114559e9eeaccf12558801be1770057f90ca46af1a8cc21a760cc65b0845b4835248502781e1237fc3a0e12cb85ca757fc3f00ed11c7729fca6ee0dcd8b08e9ab8dddbc370b821eb5819156da44802223814448d8fc1cb82d090c9a03078c540376d2da4c7ff7af92ab9d6b253686e44e82bd8a8066e5697f61ae79a04c43dd9de4510e850238d1d15f7331ee25ecbd1b2d0a5dc3e9561b8eee12cb051d2956cdac188b44ded4efbd6ce027b50eadc148a82b6ec05e724a84dccf6057473aa18d58744ded2095f29df1125ac8c6c0cd5884a11f6faf01cf7616029b98d52e5fec5b23bcdea6150f96350d67c6e5ba7bea65ce719cb8b510751658f336c58012f50d6d80366c56fcd1b6050c7c24b9818e6570dc12bb96350ac2982fb16126912d37847d00dc6e92a02627b0ca8e4a5f6bc14e9f380287080d0de28311d647dfaf3716677dc09979eab1601d33ef90e2810c9652c58be515714ef6b0c6c8ab4fa9ce7bde3217f8e09a37bb2502f1415aeabb7d2d67be5a8cdd73bfc2a528de71dd19a31e38ca5144eb17c02faab909dfa968fd08125d638f340e8bf022cf4c000d163ace5c93e34f84f8800573eec5db3f364a497261be45614c409620a6a60ac6326a9239189b00589de08109630de3bff70111c5bdfb6fee5469028fe168d4c587af6326159f156ed5b8d85395a5be15fedff8088c572a1bc066188771edbb03ea4935e64d0a924986e1f81e5ca358419464112a0321000dfa41c74ad8fdb2f03e8f4de3ad2756e4eb508ceb1d1065971fded747896b3535d317a79a60f049a848ab8f12fd28bea3b2c6b87da832761f3cd1b52bc97f1f0d6985e7fc3b69153109e74e66f4a19a6c58608003109283289278e1f38a0498cf3872e8c72f7673815a7c0d48218e0a51873ca55e434915be3dc3a1241c449c2c589d498189c93f561353e33b5c5ef99acb48268b2af16858a1854eb4e92ec6abe9536ce05130bc0687c30bd02c6127308b76362f48105874d0633f47b5f4d728d6ecc2411da64012576d63adc72e84d906384aa76207f01bfd5ae83d062f4c62df8f4197f2fb4860550af1b88753c32139cf7ccf2b40cfd750b2f92a1e6897e8a45cf50eb1d326cd72dd4ae20eafe344c5209ac7c4847b541f45b190e3110bc89fa2412d7a75327ebfee611fc71781c08469ee0b47db161b8b066a4500d2454eb888b43fca8e89d9ce0368fb08c427534b652f6672df636d8ede10efb7c17ebb203f92c04e206187395a198ff04c5f1e2229427e365bd8da7986aa82db5d60ada27c8096e0fb6bf1e734226c17134d1f95b18f2ab1b110821420fa15a58b729d383d4e2d006b5d1d48a7a4d6c7b3e76c006001c9cc571dd84091c7dc6c17d5bfda754dffcc456f982ca80403c4e767b1a2ecb4473fc93f5c825af0f6db85f47090b6fb28e9aff60b4ca4e5c306727c1ec03e02dab69ef760ee08f4b7ac45061fa9a7377d67c99de6c236aec7514ec85cb9b5d19544b43d01f8fc2c9a759b176df04ea1cdce14e681c3b45f65ac2885811a9da8d36ead0f196c01a577ba58220c354d897dca64df74e604a4bf539e3bc952b07d683b94148ff924dc06553136ab2fccefaaec382e462cf18c9c57519b900d57b1c2211a80b45ed3eaaa71093f160b80dab7d5e5bd3f77def393854800476b096462dc2ab523dc8009f2563b061db5589058bcd0e7558508246f92b9a48c5f796cc7f293004682175379331a23686f2d7218043f648ac412bdbb6b21692aa13bce3789c6a1b2bcbf1582accc822c489fc33613319745226085d8f45e08bfa7956d362dce8c49de01590cfe0e98758d9fc703bf5813031dc56ea12aef5c0fc0d7320213aafcc8f90a1ba478f0dad4d912fadba5ee42be8f5f01551d3daeba55b85e59216d53c47f943d4690fdde0351e9ffa362072cb5e9e178aa359fb3d49ab315e793dbe01cda341fcd545b36cc259c82e15018b89d7fd130da50f5daca11e2f373071d79ecda85b37b8ab000420fabfe089bb3bb5c921f28bf43707fc47396aaa631e5c92f7771e76df3806331444a5bd0de59435348df44033b0dc1a65a12bb63da79ebbc2ecb610b37dfe54c53aa961368356e1fdd94007670fccb07d36e20d3cb594b4011da1a930eb699bb35ee14993ea2abbd48191aecb188cee065f6565a83689a361f6fafb1f0ac299fa38e264d489b0abb83d4859ddc796d18be15cf7ab1858fac442ec12527e8ad5c0ae809f47c523c79b83fdb462424b03811cc639cf7cf61cdda0b53c85273a52d5f5de5ab30ad309139027e9adc4e1b504c4365780aaf5a1fe1f5ac8bc16f6506a0e1788e009a0ce44dac66a05f159c19a850669f9f4f69614172f4092d0355183014bd4fafd270b91546dd710cef167011a15cea157e1b70c50e2713861f67d0456765b26644e408b87eb900be827bb9435013f2aa0bc82bfcb933cdb8279570ad8824bf696492d2b6acb744a5476f35082a1c8874be923550d47342ffa8621020eeb445f53814b4cb41230b4a5f3fae7a17ac6b45f1703ea0119ec909c673285774d809e43233f604e44e4cef5eb4283e581d3318779ddc9fc004d68c7d85b893dc0e13066b871658cc8318e27ab95d4fe8314efcf803fcf4353238b155c32008a41ad590b89aaa3c8668d1ac44eec5bedd9388e198bc842f78dd3def36f59364c79c5f449b7e09efe6f9b118023a5ce7fa419eff46bf8700a54b73d3e084ed2ca1bc49a3d72c5722a1601ad453a77ee1a2d4b80764d6b163d41855f6c90b12b87c4863ce0cc0b4a2974f493d32a7978bbd6f378b4ae529300a550de2df3eee87cae633ab084f6c50b2232339d37ec8dfb73f3f9cdccb13101b7bac739b6f06d83faa111a56b57efe543814a5f1a5ac7f1ab68bf5365b6f62f582ac1cc5517d8cc5810b6d4e278a19008358f04ddc3895a5f0545a16e40cb401ded72fb8c636457123a73b27112e8b1458bbc19506608c967c1f5457f85efff5dedfc87fd08c9c3b56e19d0bf3bb0080fdb27997f116979d7c13b808a664f77921fb2d3fb644e1be04504be85ae8ac5c6cc1a46c8536b62aa9a1874f4f768c5b1048115b5482a606100f7903714191408f995d38296a74dde3b94a5dc4dae57c0708eef38ce68e23c5fa3c7cbefa3d7dd43ee5bf388b26bf76708c6d3d42ac35721cbe32a88d00fdfee73f0ec422c9c754e177382007cdaf92687777da00098185ea655dd67d753f3ef793bd559b5a7e6d4df53a3674bad9deeb83a29cf996b98156ca5f64c430d82ea4c13da8aa5bd8fc4f60ec2dbfbf86eba7f019bdd74efbf6f8a723eca6c4eed15ad9d931ed991134d1023cd0738c3fe29cfcbe2cbab5f5f6ea5921a6c1ab57f6f86728fd35653c1fbe84eee13a2bb7a94d83fc3dd9d4a3270d01d1bd98727e6bfc39beb14a30e762e6233c3878f5cd9aa3481e87a5812f343b9e8b09386410832b2bb028d21b6a281e271ccdee5d126ccdc5b24d8d6c8fecd19073ddd2071870a33b2ab5c578091fd9f705f8fe27feda5cdb0872eb2e70e926eb6c8ae69854413965676e8d26539ed8321b12708bead3b76875406d1c6b193a149470826218e0c2237e292f02131ab417262d0c57e13299fbdafd8e1fd10f951faee815fb1373fdd1d2c760d2b4f789bc836f65b1935f0d32f898e53033b78a2d933bfc31e0ed8e03087c6e6d0fe59629488e178634424875eabd8c8111448c0c615e56f502885aa47c75414ce85ed82f04354a7143c818c51a3f7c0976d22e093bd7503e217e5abec14e016808da0268b5ad88f39849f36c63e938f0a15a961778621fce9b57f95c9f94200e21ec23d823cd78026aab75f301c1e473716cedc684232c84b520c3877035ed1fa302d3225a62ee07527361b219c03fed9df58631d8113e813a473cbb8af822fdea10a0d7cb96ed6eb27b7ed0b970aa678875568f0f0ba59af3fb9b7c581760a3178990a15bcc1e5f4317b94d0ab9d120da286e78a46a387cd8b3f97664ab0442d274dac649caa0e0ea9469d391d87d8dfb788efe810914a25d972a8831962ea3d47f8cac206ba8821a3d6f469efef8179e3c187c2d23c563a1becc2183944c9dbefe1ad55f653854cd308605538284d9b0f37b9bf05db5d3edd4a560d340c691e54702302351a4174f9844c014e020de8722f379e8f9d2bbbe6b50e73985fa06f27deec5d3c0d0e1db2c33decbc08c6f62fe3d27fba56825019c5771b39d1134235215cf4aa12f2c63ab46d93a115958dd4efd14622e01677431fddbb811118a80258414d712bce4f15688737ee43f188e85fff6dc50fbf235f5b75bf295a606c1e5c5c1a27238e2ec47a9176bd224307f5f83ad0b7656702526b31b5b0b53f80386dba0d9752daad9c9463b879ccd95d5c9805348096e71c8380a3bb8c752f3cc018f3fc514b2733c8c42a4d10c31daab39f2299cc5ab2eccee352c2e2219313d635de6ca097e55abac101f5c837ea35afc14be0a2ba8147d6a020a46064b62ba1e71ae4cfdcc6241e584cca15be7d3de6900c9d33c0886363e23398bea6baf811e5a4a3265cbb2a420a19e84cb6965c8a86cfde1edaa3be46f2cd8a6919cdd3ce41b1b0cdbfdd0ec011e0f8e9106ed91182b0de76a3f1e927b25d2af2db80a7f903861f8ea4720e5caf8acd433b4da6a0bcabde2e0035ece75366020dce04b242c7a938ad28c86a4df64383b5d416c07ca796d8486275fde3f6d5f43e08462966cbb5f6149f551f8ea4d5424226cfbf39a971abad5db2ddeb7045b8acec8b2fd09161780accb6e1b493cc2273b4ae1575dc0737cdbb7f088d94ee646d0575da0f58bcccccc4d48e2f955d2c22e335873900c30a25102462e75f31ee1ae0e9d9ba5b3a0b19bbb4a1c97d19ec92128f535ee9701622a3feb6f9ebc3cba32f8568bff1566fc5c30f9c234a3a2796baae0bc07cf15ee4c59f1cf8216983b89cf181da34dcc259c52691e9bc5f4f5980b41cde45217cdfad365f467d8239ac9fed6dfe272274aa1ff7232501f365d27cc969829aaaaf9d7d6d069d971e8bb59438be2a11f8cb549531a85eacc0fe86fa262b912a9887d2d706946168323a9b55a759813a0548d61c570e7c5c1e3dacbbba9e0ed59de3515db708c1a77e4155a571d803a5df0d4a11d8b2af4d40311e67c125aca1674674d989aa180d6a9dd893408d181450709b648902afc72942418794d2a8de30c95c8e0254903b72d5c19d2f645341bec4c321454c961e695c90e932e92ff2006a596e8cc6f93688b2cec34f351649599633460554d237488c3d0e990b1dac2eb867cf019859c3b5a71609fab6cf0a518ad323e3bf8360238a4f468a8b0a18c296b822ef6457e363c2167ad10266d5f43019351f4a0a940095af37ea484b933880c9c5466ec56f42b3f0476bbd2a13c88418ea5415f2fab9935911535f099b202acbd8f18d7865f0479d9cae9b49dec7fd9d14f0ed778c7182f7e48cdc78303b41b6de9b8d41e42c66fef9c5114bc8ae8131119cdecae67a14a7b8bc07f30e3a2fa3c1c1b6dfc57af48f475782828f4721957c2ece8f36577711e414531f0e85589095f96e52bd4fa05c1b01e916c8ce13e7c1005920f47962894b280901c053f9cdf651f9a8406c552cdd4336fd3f13dbbb08be326945909750218b8a5eb0e52a661d0834096280bd6cac20b9316584882eaecc519a2f3144b18667ce1c781ceb7787738718ae318822707e549342b400485249ac643d89ddefcc7b274408ead4e7ec414016b8976e98c20ed3370c4569a606a01bba7b789091d767c5cff85b7330589ef06c6afaf145d8f711fa247b61baa8c9beebffb183ad07e395c656ebfddf6a21c26adfa9c5f70bf95f87e2f00796512aba8d8fb606eb27c72e60057c04242b069c4f6be8dc8ba594a415f8f99fc49eac49a27a3039699afff0492cd61c29fd7dfa2dff317d3d2297796ee81e00a1b318b235561ba7285b26e92aef878bcbf2210e01652cb4d3b8f59104bbc2ea59ac3a06f72457d8e4958af0948bd2acf72e34453d1af57f0fcb63cbe323d850582c19b4097d62e6a142a5819de40a505dec4ad96f39cf5538114fc8498b087ea11b47a4161633207428ef71591228ae7bfc582bd2b82477574cef99576f9f6764f02119d4454ce73ce0ed0f744d89bc4c1e13a1c5cd3fcac8fae4f96f9c01313e0fd73435808778905491161311429f681164d8a1ee4c9008f42fb251112b4da69946d5101616f0584a93c5df5d11c247d6a06012a3a329023d313050223010693e6a2885c878e284260c16c7543639da98c22614d9beccaea5c3fcd0f36b0b403bf7fcadc222017afd7b2a370138a097c6d5c625c541338cb0387ddb7def6da841cf8bfc630638f240add3ed1e9ed9414eaac7288200b18a91f2f02fd128dd00c3c88c1c2123dd296bd0f8bf165f8d2d2630bf0dcf87dad2032111c626fa5be91bdf2775dd0577bb76f29e7ee48e76e7b4055322bfa96ce90f7ccf70425be306913c80c264a98147a1000601486595917dd73d55e48e93bd54337adcca48b586bdefec81bb2c29acfd4a35b9e1aa9dcbc99424d2b964d1d0010a72e39fdf04be1be4da33b23514076fa793e2f38045a4eee06aab94b67f0c407f643d0b83edf4244020ce33e9391832327d2003cc7150a1d5301a6caa2df3c32ddb0a4333d607f8eb5549e9af950c4ae31b485dc162c082a9476651bf77e3bd5eb867b5b1145a8dd7bce7591de455f97fdb856b82e5feb1a1930174bf9e67eaf3d7d58fcfae8729662100dd240ee26c149969500c6f0491f38925b61e86367091db9e02cb25b09f5efdeac98cfd8406dbce4796d06342e52b36753483cd9bd80e049aeac45816d9c82598d566bedf3d848353a9e69f69947f193c7182f6e1c6943927bf57ac89fdfd89340b1c0894045fd43e21551a24419263c8227fec85ba24587d0103752903883600547e15a0cdb980a32aa21bd3e76f7bf961d1a35ded09333865c0d42abec804dd5b0897239efd9c5e35f7e7673586c8307332935b6497e6658fa8850921b844ef16a274841ebadd02866e353146e0c2046ca0e92dee1794eb035a276ba3541058c96a3aa836e327e31ef19c000c842612956a9caeca95c1a3ba5bec5ce91e951f21b8a0c518d17e50e7330ca59b537bc8b18bcae6de513666a39eca7ffce8c7afb7e2191e32e3a916eb467637b9a5942949193b0a490af70953f52fb70a8e5f5d1c1e8e577934f223cdf610f7f3c0c2765e44f262ac09c78d51ba1575e82035bfcafc6081ad89b15e7a3adfa74af20311221996cfa48776b5478364c21f14e1f951355fde0c449c83cd114f48391a12c2f155723c112219c6e17d00c7e3f86e262142248b112192e1d85e9521224432a10fe0f0a2e88f62be131c378aee9777e21ae003e92fc69863128ed1c7077b127a441303e851c210ee18d3b0f051300568dad21fc432b40bbed34cdb1ce83805793dfcee85e66ff3c47a4538fa1c9726498ef7cf81a4718ea7343b7e3e0d12faf3e94f1d4035524aa943870e1d34d26d64fdada2b0d9e605f434407c1faa76d87451e5f578e8af9f977f737df01e6277293feecd11df9f2b85583747ccd2e28469fee63b4f75e7c2435591167a76dc1cf10ea61ba6d0cff3fccfa548de52eaaf9bdd7c77736fbc1d4dfdeda81991ab7761f52d3c843d3c2bee7730c19daee197cf33b41ba4d0cb8f99cd3648e2e77c8e97733ebe134c919c74e236559f6d649d0ceea858dffdb062f36ac8710311dbc03adfc954576b174c12b18ed739dd6e8b119e276b53b3d962e3647306fcd1813f38f0a759888f65de052f3f46c97c0b5e666194ccf778d9f278328f7a185faa5ad7d343d3f3307cd0bf5ec807f9165a787d0eaed7cf07f91eafca9027f2425e55dbf15435165435dcdf05dd183ee7d22c5d9a21c01d8bad8de1875c211f746972ae0a0ff16892845c1a19cdcc5b6d234bc2fd42a3d96226889c17a2629d1712c39018bc26307836b3215e131a1c7e7ec80ff19a10f17e84d0cc10714e846216138a5084f124e44428c8e7958d2cb51272a3200014fa79221a4dea4fc875219d9b818a732e9017725b6886e62f1b99b7fa6bb533b49c1b31908be3290e204fbf8d0cceccd8d024b8937321fef9c6f903b8ca8f4791bcd5412e4dceffe47841e4e0f3423e07d7ffbc907f09f19ab07ebc26b6ab71f99ccf969632c2fd3af7464a7f38c7bb29a2d91b39399e8dac0636e6b38dec850fea8e0bfcc9f9feaea9abb54be7fbbb2dfd1af2fd9d52bb5cf8fe6ed6c9e04fcfcf7cbec1313e62be98564cccc35ea1e214cee7c62a2a91a75ff53c37c8133b619e221179f87a225e93efa12a080b5bd81922d6792310bf90f33ccfc2bb70e7903babe896fc162eecefc7773c77e742dce3cd22b8c3738910c9300b37e29d3ba5e84fbe8efc1cf93f2e0ffe9a5ac09694f2bbc0f25b5eae41c0f23f8f490c2cdf870767e4afe0c957c1938f4305770f2fc6b694e7e588bdf79f9742f27f6e5ec7df7870061eef5d1f6e3ee220f76bf3f742fcf7e63ac13caecd07b934f2857c907f5d1ae90501431a53c840a84990ffc04e13570845e1fff3afe731b359a78600cf9bc2661b998d52bb6a683c9b59bb20c4d24609e8d2b8f7427b0123096b33b391bd2c61e9671b590e3efff3adcac1f542be5538bcfec76bd25c5421f4fa56e110e485784d20ad8b22b02114e4839c7521ce719d601c37d31ce0fe999b6f646e9e4a31377768e09651a44c4304dcfff242cb53497525db3c612a81f38c0d520a671b5990fbba9d17425055437cead14809a43f9b9e179c6d68b86d643e38745e08f978af0b85ba987a2921a245924cc8e505792bc885421d928ed30b7da18021a309331823bbc2104b13a840a209303041139c3041134e7046138a9ad0cdee96ffb9777bb7e73802767777d30e04b15d4e3aa5a45b9515e53b6ee08f2d69fb8e1bf067fe905750d057eb3dad1b9d5ed08cf0474a2e764141fdc9a0a89242d7b9fb6c772925908bd3dee7eedeeedddd32fdc1efce818694dd4dd978a1aa54f73c3c86991caa43715d979a2877771e5c92e145664db6c7a4a4a464d409bfe9a81b37dfe09c54feaa4b171ba22007bbd50b55a5bacbc14c0ed5a1b8ae4b71aa22b30328187883c65c9cf84eb81ecf7186bdf09b77491793d200f6ef4e46a29efbcac16f150485dfe432505130f6aa7a13eecc2252a5d4d3cd0423b44c7f7f4e928accf0011667a4b164021770bf450277cf6e26a400bbbbf0f98be55b94b0f4c10a54d8ccfa7a581d5291f6347e8b1433ce39ad8f81e7ff97051b44a03d52a6e41294c012062cb12c010b962d4f60f93e83a8041de00904d63c7a7919da25f17c52c6a684212846b01829010a099e94c004133f58827581a4841814fde088050423d40b7a2ceb1fe7d3d9605c40042e3a68821374d085e90a98cc93a51862b9c20433505c31c588a6a837af73aab130b3dd49c1f2dbc848b705fe44f88383e5774eede2e203db4edeacd16cee6a5d4d0b2cbf0ba72060293b31b0944a70a707169b3b25b0fcae08eec82b3514e6af49a32f9f45f3d7ac39ccf60ace35357f754ede922f7dd66e9842d4eb6ade5249b1fdb9ab61d915b54bbe7c9aa259a5abdbb6d55a2b7c1666367271f35abf9b5bacf56badb5d6ca7973bb74a8d6aff5bdd65ae753ad0e63c5fcfa3048b5bf46982040982e7085d102d75ae9cf59ddea56b7ba552965e52a57396ee3b6cd6fd7c56b12eeb977ae56ce721fd4b30b4787faab8ff2e6537ff55535b030b5d675b973776f776f2f6360087b3724a57cd91788385d6615c52bbee58011d705a3ba218ce29e300a95ba51a0bebbddf7f5817b0e1861bf999b8ff23ad4fbe5bccc0123ec5fb33f7dcf1c30c29b97e9f464a511da9184657956b584e57a3ab151d8650db8b3a586bcb57da706e4d99afae412792e25ead6f6a3c23d9e6059f389e5dea4970ef5b77ddfd9854b049a6a409eedb735e0cef6d5cb330a787b2afd6db1fe8ee0ce369ffaebd2049042b4c85b3f6636774f30480d2345bbb8df1e2609a60af803f1f63062c01ff95bf75484e7cfd94637bad1cd09104620e63e49c4156256add6426751dab7ebd2dfd65ec7c2ccfaf6dd97a6df09ae1b85e16d8361da845084fd530f85e00f0ef667f28310dd6a0536f53eb58802c367fd64c22895ea55aa5984550f3fa82deb27cf12e0f9530908f480c8e33f7f4a9946aa9fb5d54f2f6761b7cf73ca349a526611dce97f40049a4a409e7e9f25804840ad3e75395cbbcf1d0da77ededcd1f06c32049e1c908227078cf0e440119e292f636008cfdc0de149239e4537cf1aa6f3d24f5d20e27cee53577583cacbf3299e9cc764d6f0f674fba0f62a2fbfbd7caa5f2fef5f5f6e4db7bce27a2166ed48c2fee0f5d09fab96b0fef24e25b8d3bf2aaa3ca8d5d3d0d284b58881297d99a794522333a61943b3301862d17205670bf8ee04eec8018cee113fae95c5eaa494124277e936a0bd70f7c056ff0bf0f5403480f23d42b31eb8d3dfe31ea54b9772a27ca2ea265da2ea466710a4141b74d46f70db36d443196bba72357a4c4bb499cce7bb40faab3a38c090fe82d742031cb5a8a91161afc9b03f4b0b142742dd23e8a9a284a71b68e932c61353aa0988e8d233bb94042e3bc470610d2d9220c3f2e78e21481d240c614102166c6580661cad1185065c1841250742b22e81a594584a29e511ae602035220d0d0d8d60095356a81e74c1831f3f805cc8ca500196f26b194d58be6595c1042cff8d60032cff332304587e4f0fb07c1f690614b0c4d2840596478882e512135a24131c5ccb182a41ac8c121861648b190b082bb082cb7f5f6031d433d4458f920b2c5ab2701a184af33bcf4200f1f17ac6b001ab219b83eb3ec7f5211f32b034a2261c5b80212d04329cc5494585cd3e84c3f371c5c61d57768be7c94ef8c38323158aef317fe1f8f88ee449ac8f3336922a08245b0d17b1fd45fbaccf01e675bc5c1a1c5e7ec7eff09a746838c9845ede89104be6469ba7e3b693b7e2b36e3fbdec17144abdeacafe5232edcab5bf94ccdb76e5f8b9939abc7cd39aacbe97bc157b668384cde1d174ef81d5df7899c7e1d1749e0d44ab7f790fbc7ccccf3c93144e3db4fd759e4d122ce76521228781886d2060f537be550878f9980ff255ed58b638bb912be1f833dfcb5c9af843b049a8678b30a024110323569045e8c6e71e1c619310148af18e780bc6c68742f276acbfe83592d75254d12f282464a3c5e68e61d91637823338732338732338732338732338cb700667b20a37824b1d7443e544d52f4bc8b0d3a0c6844c88e7c9b2e00f0fde84fc3f9d54cc7e61b3ccca0c9b927921f0cd4ea86009853ad8752a4b2b4e9264b0610138c67fc2f2e38560e0b96199c2d3cb426026292ce58b8c0854bcea06ade839b70937a89af18ba6d0880a8d8842512669646df506074e683dba7b7577f76fffa0943c5070d323a59c1142086972680fb46a4a17dbe5a45bb52c944fcf0a23a028aeab3a33540daa74ca82dc721c97a2421bf7af88d4d64776a4421b84843455b4ffc18b8a6a4542faf00d2e1491789c202255a488b47a912f2e6459d2b94ab72026151a92153f5a0890ea4cca28b0e0454a2951aa2254ce10c440f0033c777c11046799274b5880e00458fec69a73eec093fe9c73ce392995a9c1218388f664092c69434f60f9f3fbe69c733a610c3c5578ce39e79c32ae2964c192076db0004b1b4e60421ce23346e7851490bc58e3c91a56ac81461720b03183290c4d6104587ebf38c51fc346e749066a8c00cb67a9a105cbff4f0a44a4bc783a2209246dcc9ea69400c9149c60a6d81b1862d9010f3e0cb1ec60c99d707c2ed0a9084e70867f01275129c95f6ed4bfb444a3cd663219ce363ad96ca3936dcfa5f4179f690519e89048ef804f1a4f32504a297d02d11a4db03104050cc410a2750598521c98524a29a552862155520241430a2144c1882894118526a431c352fac4109c31851ed4e09081b30e102c873c418a27b0018530b8d8000d29676c8182881b4e58158658b448eac1104b10acf8d052b380fe1f4d10dbe0af9e9e207f4def0aef0afbd463720a834527a5132585227891c41152c00222cc30966ab02d514125890b8ab0851345465f84515530c676041b582c677c71861216ddc42d65ad1e4d12fffa46fc6b93592375da1f79c0fd17461d7410a7fa8b52244b7fd67659191655cd57fdbc56e565d5d75a3bbeeab95a3fc851b5d2f9716e8442a15e5e5ede487737cb2658f52f2a959320f27413e6eaa36eedefd7e8204e5ec90b8576f098c2ca7719967ff794d28eb60a21298d51a8d6dfb64df59dcaa349d2af7a23fdaa7782519daaeb54ea72ef04735e3442e4a952dc7c952d2060411337d8c108a2d862cae4428d2352be002307568a38821735054f2011e1193b8867a800bf6088e50c249e20194722902541892c9eb002055c9c306a82043ca8520411b21350349e0793ce4921f0831e5c71c414626461c3a88b0dcc202376840b981082f9c5925ff23bbc921d1c0d61253f86152946b0fe3cca0e576ca66075f81d7cfcc0660906f6f7010327104182d1aef85d13bc82828d4a98947872a9043606f915a2b10e0f554574f0246d872b673fa0606bb0d89481450b5cec58431e35e01df0eec25be0fd7b4abb5a78ff366a57cffbb79476f1bcb3f0fe1da55d3bef3a9ff33fde5bef1f9fdaf5bdfb785fe15d85f78fb5a676f578ffc8d42eeffdb6ebdf6fde3fd2dac5e3fde39576d9bc7f9cb5ab86e677bceb78ff98d42ed67b8e771cef3331ef37de61a4c422d5a7de25f0fe43f82b02ef6f83bf20f0fe47fcf580e7e1336462c067e8d4c3e7964de07327e5cf4df3e173cf10f0590e1de0b377c9e1b33f19e0b373c1e1b33b15e0b36f21c067afddf0d99b6cf8ec4c03f8ec5904f0d9976af8ec60d0f0d96909f8ec57927cf659003ebb1292cf2e3bf2d9ab30f2d99366f8ec5214f9ec48327c762b00f8ec31a1cf4e057ff6a3a0cf3e2586cf6e04c3679742e4b3170df9ec51803e3bece7b31309f9ec433e9fbbcbeb733fb93e3797209fdb0988eb85cf5dabc0e766a2c0e75e62f2b9a5f40b4a2aed0474f9b84b2bd8b3945260ff2ab0cb5e8044593e71f5809ffb021eaa8a28e083da879425eff02ab99907ace4e30de27f0022880bc485b0f5c3dde1a3ef7097bc922bc4c44b962c5125bfc34395921d963cbc3e4a96fc5c1297f830cad22db94b68962cd9c1dddddddd5d72c1fe4b76804b2e845ed0921bdfa362659676d5f04a9e0689005ec90be095bc0eef2f97daa5c3bb92f7974ced5ac0fb775dfc1f6e1327423f2cd1e177f82517f6b783a7c34f550d40bc9297aa0128f9580508ef0351a83004fb831012800fbd2a3f7c90ff70a350f24a76f0b213bcc3c79be30e4b3e46d930c60dc7254a94e8b0c30562c34abe554574f84e87abc385f00854f2539544c9435511251fd43d6b1794755c6769577dff66eaa6aef516275fd2e14a2c97325cc24e64e302ae02ae925b7bdaf5bd005d39f0f347c075e10f705bf81c6ecf1be0f23c0e97852fc0dd79025c9dbfe1e6bc0df7c70fe0b65e00f77b1aee0a9fe4e27c006e8f4772bd3f72ef1bb9ff33dc9b2f7279bc0cd7e601706b5ee8d23cbe3b3ee8eaf8182eeb61b8399ec8c5f143eecc035d99ffb9312fe4de789f0bf3af6bdf755f3ec85d3d90abfa176eea2b7025f014b811f87c19f03e5c077c0f97879fc06dc033b910780bdc077c02ae118855f81aae11887d7c025e3ec9914416b809b882fd112087b0ff01ba60ff1c0c808313f62fc016ec4f801b9ab0bf0d03c882fd05e05fc3f5a7e1c2fe925cff005cd81f12ff2355607f23d77f86eb5f44062bd81f0017f62774fdf185fd055dff18609082fd890c018261ff1f22ec2f6408fbfb5cd8dfebc2fe5c17f617e4fa03b9b0bf172eecaf024cd89f024bd89fc9f521d3b0ff0492b07f0fee04ecd1545cb87d0477fc5bb8dd739be7360bb7776eebdcceb9fde3f6507ffead1b3f2e373add887363ad3fff1e3736f5e7efddfb372ef1b89116afd4dc4873e38e1b65feac1b73dc88e3c6197f19ff981ba9f4e7374ee9cfdffabfdc28a5bf5814a3dc28811b87bce51f813b84b7fc21701f708f78cbdf01b7076ff937e032e0d6506173cd91fe6840c0027878407ffe36633cc13e10e34487fe238c11c509433acc38630a38435995d9ef97490d864dd6fffde503e1f432931aec1e1b2f83b21ec0581dca291386b4584af9d0a753ff5cfda7bf0fd3691482393e5c5ff573d70bbb61adacfecd9393c9d7b021841feeb71d04f9794ecf87e941b1fe5169a33438c1d40b42cab6022a204714eb7f9f587f19973c76951e31ece8b2ba5debad1add7dc28d763115bb63bbfb3c72ff1b176225398bb42c5814cd700b15d52a13387e74f5cb22f61d7aaff206ec85d82b8e2a7f4e62f9830a9bbaf17126e68ff84b87c762b172588b63f55dd7415512e983a45988c9753f6f1763335eae3962bccc822d988f1e0e0f6605f3376e76883b3ae5ecb974238b232c627471c538d4c972cc82634b98141cf10b7a8dc0e8f9f4272511b83387c09d2938572c7728110567ab040c67c0b13fe1fc71d9b033b19056d42431a41531e1ecf33e43e08fff7c22f0073a0ea6e460b30fc647da952da415c9f0fc21787ecfef3d290d3c3d4b121a78c28c43f32750ba6d946e1ba5ae2024a6af78446f10154f8f68d0707fcd67895d538dc4120e9c65a211dd10f605faab7a2bd2873edf7a2bd29eb4bbbdfc03f71baa7e906f57043984a07ce0a134d99ef3aab7e2530f0a842d87d65b30d383b00528342f14eaa7f1cff227a594524a9f081f21ea7dc049953040200518a4e0054fbe10f2a0482f8af668dc4be2a98800618c4334000c5a124a4680886d6cdf3737c1f32bdcd9c93deec19638de44b8c75f40071960e37b96f77798020fca1b1e3635343b74b072e0989189b901635f56aa54c7a1ea46a7f46e29a3d04929259d28cb92927b29b3521a597deadd3dd81fef95fd79db07797785682fc592ef24e83ce5533ef52cd3524cf26805478f5e66126bfd1991d5ff8606367eab8cc878ac88a44a515495f865e5452bfdd1fcf5641feccfdd0c6570162dab57519611ffc9ba177f58b1eed1daa0f39ba5aa489681fdf99d926ed56f9e568aa88c483c63708793aa549752a954125bb8e337a78a58231257b8f30293f22ba5941d8451c5a8607f7332f9b09433ef373f8e9a1c39628e39938ac19192c9919a51b166582c964ccc0d160bc6b258ac17d64ac562b17c70324ec671d1598fb13b469793a6aa1bf951fc1c28ec9c54d22a534738fe262363594cb6d69aaab19a1ad6d758395074100a5bbfeb4ed5982b67735445dcddfe2a950385952f352fef2f2a2335d85a18981beedbe6eefe5ea6cfc4a3478a84a3076fa2f0c30aecaecba162a30d30e2f41775308c1e9216a6898185dfb90f841042086184d055333894a24ab9f22dba6ae507b5138f5104394d74394d44f76eaf3a55d98588284a141ca54c29383ae1259030cc02439a942db8cb69c2e6b88494b3029beb15dc5fafb4cb91ba1e51919fc23de4ad4e7995d65b521f531f531fe9775b58dab4297dd95fa4aa14379fd2344d7b493e1cbfaa284d511a3b1447fbe977ddb4e3a7babbcf123792f849beaef374fa6b8fbb352d65a3c8b090ce2ab290b284bb772933dcbd4ba9e1ee71ba2d6cfc5afd5f1585ca62e9c7cfd1c2e60f6f342a1a9597e4c35ebf6bedbc0d5e096f85c1d91ea5d3037fb8df9c30f7b905bcfdd72ecea349f261550dfe1d7769b897df79349c97e4c3dc739ca75373dd838e2203679b27e836601b43da115ca20f6d818ec4239431acc2f17bda055f3045b4238e9ebee888295243518c700662717487d5231c83ba6d96b01d63ecc15b311a4518f8fde4f16b357e0f317f35cc5bf01b478f4849b0a2d905edd8ddb5c6eebb7d74824c8704b675486023091a771bbc8e6daeb02e858a1fb5aba778015f92c95bfe4d833ff47d32012bf2273035e6d0194f5aca98b11b3fc6dc47d113621eb52b6257ad9ea4f9cba374cbfdd53d9042833ec4841a4567c0b40c95819d69084ed8db0b3f9acdae4c5aa57254abf8d41a76083609d1e4e0011ad701b38f9d988067d1594dd8ccc239c2f6ac6b27e02ba2503030b98f706036f711dc890d9382fbb728dd43a8c934842e889643f21b534ae79431d76ed29f4f9f3eddbd5d763b8c31ca15843bddb0a18c4f9f3e5d464229e58aaa8a00113755912e821042082774afa3f417bb1be6c4c5060ba408649d9c4bbffac869105f8de471c64ef530fecbf791bf9c4bb7e2df88f63a52e489df48fe721ac496d73012545e76233453e76527028e4b282ffb174ddbbcec3ec03d9b5ef62cb0752f3b1548eed45f7c1b14dc2b6c10d2a8615cfa156bdea23010411646e8a1284f44a9f80df357c38a1afe10863d9cdc88312de85cc0e202172f38c1c697170cb11082d2b619a103666b1da0e33814c775b0e3d68010c215a8d8a89c1042082184f5f316747777dfa6808ab25dc64a1b61f74d16856393addf64b76fb2f49becfc262b5337e8a44c94843bf02b8410be854d57c8c184104a192b13e32367e7104208218412fa48296b0f8639451173184a5fe10690260987fd23ce18c0eeb565819d334aa3e6bc1dc7d5212ac7753a6038f98473ef5dc721319f882ac449a74c35c7f4e260836f44d02b43100d47e4101f227c2447040c32bd19638c1d0a725d773fee7f8a875d6a25654febea40c9309141d58d4e8e8b52373a259cc90d1523aa6e7422019d1491decb4c118e27505ce54620a7dc2a8aa342deeaca71dd7316eeb435a2680e015bfd5feb2f4b878571025f91297ab10916133016a1fa47e27064ca8962e3fb1351855254e2094542713ca14828f4369e502494882514ea0111dbc013500111710f70a7ffc50429217e80324407e9df246ef7a0d0bc318382e16eec18c25b1f8b86803b9d52a95236f81902eec42eb5f291b1332a1f7fa56074dc56cf2b22d98a0473311ce23b2f57cecb1615999022135264426262f281734462f2d70660abff494d04b85f095cc40c5c4e14db0dc161d410f0074219e287803fb068e6a8917ae00bf51f0bf690bf545e0402fcfa51d01569dc1de207181dadfb2307eccf65000504c7db370cfcb6f9dd94b2a5945246c8ad24852fa228e8135185502e23ef0210f0001e1ccb4bc3111c36950d3e4486a07981f4f47073e55e9444b084a260d243c3209372407684cdada8176fc8b933bf4325b9698ec5e2e04f9c7066557d6450a5892d2621c34466c6c75fa89eaff597a5c3c2e038045bfdb108f88ab49804134de08e553027035b372aa723d1fca34d8bb448eb700f6d99919dec0fce20cdd84005d6c90afa7bce21f8e32f918688e28c5ebf44823f36516018d290680143da08a6604be384edfa1c2d6e9fb9272f34b8e3f3c9cb10dce15e30b2f3890c8d76648fb29cc18b1741c4f9047b86b48a6990c4974970f601474f3ac1433d8720163cbd2c672077cc1c4915c406cac0472365346ad7942bd80643ec5dc89c260225ec3e9d6822d0824202838663d81fcad8aa1aa2c71444231a9b88eed65de2e84c61a7f7e9d86f667334c2d148290819f4807eb5a00cfd925d5ca7a6464626c3ff7a7c20cd0818604833c2087b7c181c83fd6bf42011364bdc9149081dc49191bec929e7f4640f0fe0e10436d62aadf55714016c350f4c3c4c96c93259261f261f261f2658ab081bbbb819116511ae5c2583ce85606f013b6dc1d7c32b38aafc0a7e7fc513c02370160316193a7db52ca7680477fa5b300b270e2a8ccb1740c0f225134c0638a92a36d7236ab5c2c4c402b6d51d18c92c68b488222ce159c002904551b720ced5d28a70929244548200c88a6830268c02804512978419236c0d8658c288bd30c4124693b5b422a6501dc4705ae38c229e30858bda441a2388a143d8a8448881e54f4b2995c21946a4a0249105142f2c1a48c444170d11975a8960f0b05a2bc3aa99330a99832116252b6ec870b4a919f9ab93926450b320867d8f756b98c0726da5bf08838558c86086fd1b897f23f11abaef006a7fdcdbfe389ea78a94c47d9c538e585082f522cf61fdc50f57b08c8c97650c4b22fc74e386979d09cf92c0b444ab025beb6537c25cf06a15db4296846405a71a8697d270aa3135618ef37294e1380557f88493c2a0cd64944ea31edcc3e9581c0ebb2bf278ed2417f0c302bf2881005b2e99d0904588aa0038c1532ac9198e8ea14a05f0e55380cff209027c9651dcf0594e6143dff87e5703be7818c067f944009fa5086af82c95a0a16382005f1196e4b38b1180cf7e04249f9d0947dace00be229291cf8e83193e3b16453e7b0f646898eff723e02b2e01e0b32f21f4d95590fd89a05f6981af1e8ae1739f01c3e75683c8677f32a45fb480af8ee5eee2e7730721b7183e9f5b09fea4be9bf6fadc2e707dee19e4c6019056b1015ffdf4c2e786d247b4f0b997e8e921c0971f79cb732c8385cf51cbcee77806d6e9eeebd845d422e773b402f7c729e0cb67de729ce802dcd109dc5109f872a7fa8deaf139468182211b100ddc4f01e835b00c1e48e04bca98c01ff8b33dcd67a84424c80e96d101831b85fb55802f89037fe00b55fbf6f1572d80972b01bc1bbc7c231b8097ab00bc6c6bf068804c28a3245eae01f0b245e2a18cb0ff112fdf5427235eae3378d9164172c2fe3278f9c6eb0c005eae425eb6d80bf2f28dd7a318bc5c61f0b225e265d6102fdf6c4f405eae3f5eb642bccc7ac2fe3e319abf36dacbcbd5e5651b840684e65f5ff072b52e782df478f9066f433c5eae76e74867e64efea248def2cff172fde165dbf2326b09fb7fb3eac3cbd5aee065ab028e976f30854999bf26530f2fdf785e665da337baf172e5216536522665d86792a36afe9a345ebe61b1ac95358797ab9df164bc7c8333ea868f675939454e8941c9c858a2a1664f4f31b7f10d9411ea062824540c75e4603818304ea8249e9090e04e6c6c6fe36e5567350995a92e559a47f128f5e88a24a458ed76977aaa4cd4a20aab434a4a3427d49896faa88f54b73b2eb66db1c9b6a40da94b17b813b7a1ad89cd682bda604b4bb7715d4ac3a9c624851428242c3359522c8a4570a77147298c56a147b4680b13b8c3d4c693530dce8ec09dc69d4c0a833693651c8c037722aa0677505a38980cb82731355067e45c61fbe56dfc42d586c047bd30fc944c0d0e104a16791c48f42a18367ed7549397990c407a1d7560fb6bd86b3e2899d3b037eae9051c3fa3b2e8419961670a08fc69225ac02e30cc41308c28336cfc1be20298682460c2b6bdbddd614e0eac0d3dce62c1242fb87fd63d7cc14ec9cf8ea5c36fc26fbee0f9451a1349b8b62b3b1810621d2ce34b272ccd0c930837104e30ec0ff6e761875970ae38eb60f974e2e9e550613d3ab984b1bb5dd5f352150d4e66f8566d2528c2f33b2881f820a05f4260ded2aab5acfc5fcfcb8bbc35ffe53dd62e27dd2a8aeb52aad58b8591e12e466606470e968e1d3435363c6efe6effb8eb918a323cbf870a490bc72afa9b1d4ec44979acd6580c09a993a2bb1552426e47f3d67c98db2d49918484b452410c9b3b58076b57947e09f989047f1c1be998dab5f2aac4264aa90a4fe98fa79452fa4ee93fa594de3ca5de534ae97d4a6b9e524a699e521e4f29a5364f29eb29a534c753bae329a554c7538ae329a554e629a594c62c34e629a5947e4ca2f129a594caa794524a29f7f4c6d3d4534a29a59452fbaba794524ab7a7f4e529a52fa32a427156f87abc0a3ff3c38ad6e7630515703ca41e5eccdfc4bcbfe1ddbf81a949d1cc9a6635339a99e561a35443f3c2cac1cab1da61850e225a63d572d45438aaccac89ce66b3d4ccd631a596a15d8c157588058371d10a3b51ac5ae5b85a6dd65467747603954aa51a2b35ee6c5dd9dac16c1ba54adb6d6c6bcb15ed7a4b3bf9cbe7e7d3da42aec3bcd5317d7c49a55fbeaa49b17a79d42e9c5fbd5401049244adcfb209bc7a3905fe7cbf7a39d42f0983c164d1ca871a104852717df6359ee0cf4d967ec958ac29b625c665a95d3c820081a45290cf1e0618f0e726f54bce66b2d96c350308249b807cf61ae0d53b12fca1f9556d55732aabf7a276edf8d5fb11106812bdf0d993c0abf728f0c7e65f13067b82f910cc615bda55a305024d2a2e7cee25d4e04f8e2bfd9ab11818b12cb1a659bb70680181a6520b9f7b0b25f8a323d6af399b21cd9256df54dac5fad5b713106836f57cee16e055ccafbe89fa356bb58e526b293d05afbe87da55d980409488e7736ca30bfc9961ea1785c16a30a795cc102010a5c2c2e75804bcfab8047fe8af682ca614bb120303affc571fa780405429f2cc9dcff10678f5510af873e3571f8dfa456747b3d8aa7b9dcfb10478f5510908449b84e817ad5d8870149cb37a0a40a08d28feea7f6817f7ab67027fb69a65b2a15f1bcc5bf3c7ea9140a08d4ae4991f1b9281e0d5ebf46b8bd1d02ed4affe08fc91bffaaf5d2fbfc2671f78f52befb3e3d5ab008136251cf8d3bffadaaf6df6b25d30bffa0881b6a6c833edaf7e055591950c4b98bf3a246fcdef21612a4849250275565c52c6fcd575b2939d944a11a88b059172e62f8e939ce4a46c8a405d0744ca9abfb85a67b2461481b8a61788f0e46231580c16835189409c920b54f0e460b1584c290271545a509af90b55abcd6a73367f3645208ea86736e1899a796b7eadb359238a40a8261e2298bf50b1182c068bc1a8442094120b54f044c16031582ca6148150547694f0acb5daac36abcdf07cda148150443ab409cfa7357fd5d98cd666b436a335a208549b7288f0acb1182c068bc1a844a0aab4c5fc556b6cfea614812a95b882129ebfcdfcb5d56ab7da36c3f3716ed7d414812a51e49992c8db9af06796d73c4984e7fbf7e203a9b3b282a78287d3c3f3565e6705cf57e166c50316eb60f371aeea6b1dd14d8d47add611e1f93d68523b664d34b31db359139eefd974355c4c89868bede0625cece6e07070308e4a0e0e868383ad38184705cf7f1d28568d23ca51c3515bd538223cff26a6d65953cc6c35abb3263c9fc7cc26838a29c5a0622b54ac7a31253cdf865247c1a8a06028180a4605cfafb931bb5a4311a5862acbd61a8a08cfa7a9c24a9c7da9ce9aea6ce6b3263cbfe368b61853aa3556635e63782ae1f91d6a87f49f1f69fdcdc61546e5330b8627153c7f63b16c57a4a35b69ab55a208c4cd22cf7c16cb6eb54a84a712cced9a6adc2c027565409ef97388e51d9319706772333c9fa59aa1b1f5727260656398c4e459da156d4c6a17ea5faf9f1f95e22c5ef95212e6adf9b26330d854cdd01d537ff3eded9a3a98bfba2ddd9adfc5765cf084754c70677ee39c1cd81457c3f3b91ab785736ad7f6f33b24871d12ec9090f0fc98d430c8ae95f25891bf3a26e845b55acb62fd841b0c22629efe8ec95f1d6cf5cf8e09311d9391c7dbcb95372621c16edf3f57af9f8f62b2b9ca2b7a41c858454e4a76ccb63ba62e477ac79cb95279fdd4df7c9fdb5dba31e7a1e6bf6eaca25bf3ebfc9ebfcdce8929b3de65c76464c33edfbf65aac8858e45f0c003543a8b0a3a4b672122e285e6d38f41e2cf5b3b48fc0e8cec5670ff4b0a6c841746e9cec4ad6088a5eb58a4310e4e843bf1a5089036ac7faefdd50a1d62271d03a2c6a8b4cc76554d512a433300200082028315000028100e0704e2904824ced34c9a3e14800d779248725c1a0b646990e420c48c41c810400801002000223233430300447929521f7f27b62e95cbc23d10808e96da37eadfff254b85e6c8881868b72b352108cef9e0430bfa35f15529cd0bedc00162a45470e37f2266518a1da101933a57083c29fbd1b89a837fb5c00f885993da36e08b0d96ee0f9b355e525721719e0397b6f81f105f926a82d01e2a20c648911bf7f77f37a4c2cc1adc640edc9b0d907f540c0138cc85b39f196691d58dd8e04b8e5a5ecc5dac0ce1324a9a3ae2cdb81c6b495914c102b57dc5e8928616516ed198f6ef69c2b03f227a10d328e1e54ecf786ae08c93c0096f12584861b62474bae4b86459c42b77748ec474d15af93638391a93c6394862a1491d456602e2d334ec51613daf555ddcb02ecab44436e56e0ac291c8ddef2277657c3d9b23f9cff8e29e38564220ba6a0a882eaf5ec7fda44b1e2d68e00f79eaa9a7b63d63d740593ef0fbbce3fdbbde8f7e80a08c12097e343678fd9aeecf8807a20cae2c05a520b8e790bbee01900a36744137c0afffd17d89d8f537ba0f1f9f602b1142e98db0f6ad2ecf6a90eef3f6c99106edc6819713aabaff5b9969d2fed3d41c20bc0725869a2848aed29e7b71ada6030826425269c510fa1edd5f8b960b398aff5d3647119b73ac2f3c3db4a51e9ca75ebf89d9e9c88d550eea9eac45a1fd41a359104e1b093ee65b6d22c3b728f33192eeddafa4311a9451d052fbaa4bf1cb2e1ab8037ba2b9fa8c7bae8ee12aac05c2e03840fc00ea68f280bcee2cedb2bdd3e602409fa4d042b024e23ccaa207fd6645a0df15b95614944b542843ea89a190b67d0905c30683d5cf0039c8ab5b6a009f4a503ab7b177fd4e0b738bc6080cb4b3f71aba8aa2aba2d5d0f6a0747183b04631ad60222daed93c927f3eea8450573dca223c2cb706d64bd9f550767e81a12c58817a1e2a32e6c6be1cc8657b28edd5dd275ecbc28f5a120bcaed84eb0dba87fa5ee7478d9abf025a7f4ea68ce674a5ce4d99ea487b915edcc268dc0eb5337e043f5130f713d020abb7f3bef0c7c586f91e1cd21754a06cd396f26acdb1347ff9472dcad96e582e4332a008c7111c0e6e832c18d27337a6f8b94528431378dbddcfe7680f184de73510ee0c938ee62817a1a859464d1e5e98cd973fd881c2bb2351260aa7beb11730d54bb3d69a75fe6a339c8eb49dc7a4e6d2ee09c641cee9bbb96bec40064bd92500747db9750dbf341ee8b96dc5d8425146a6331dbb0c6debb75f8795e3d5e09a31875e4b4bc2db2c165a6ebd81cf392052479714e4256db8ee05f23270a4abba8bd823230a4f9fa6c3b4cec57660a392043a84a009f4f039400e7269faadb09e5e76e3e5358f3d4ee831de461f9779f0c1cf6023010707cffe3291720cc5164daf13e01d4570f6b02a78f0acd20daa196d56ddb0a8afd402eb21a500a6588fc0fcf45876f12700803a39b7d5cfda5019131e09cfc2e47898a19d26250cc60497667c1848fa3228ea73dbaae4d3513754e46201f5f00feb777bc5cbbc00d800cf1c89c17778a91779cb1b789319241e9698ac6ac9dda63eab7dc3f695ca94b5b5aa635f8b01af6de65fb5d024b80ed8798768ffe5f728d9a0bea15054e9b88c9655ecaeb05548f8f596d58fc634a9b6325b5799ebbcb13ad7134ffadef6f1445f7196906e7fcd4b8eb1aa2ed036ee704b2ef065e8e22733b1179b55b59c78906a921250c08af0623880d7ee62f1a7466b0134502a9c1c97216bd09e1e124640b7ed881f993954402fcc98a5608c59cf0795a165976749759e6625b57d2c4f5d8b35d7ef163566be4f35d0a556afd354df6534ac82ced5bb23263c088be9675aadd5b07fb72bba10d6c83425c15274ac219b5bca74eaa55515a220240f7f83b3ee0b2db4edfb590ddbf454709fd96931b5bbd635d718b477b453d25b8a2cb4baa80e61b90efd830e883f9703b1b1563b4be51012d79eaea03352074633ef34c3e1363bd7c121d3f9462a06343c01b37beefe8738b6628cf315ca89b48f2391226ae5d95345d9d879645143971e9feef12a73ee12b41ac22f96d9abde959a36e1b5020c3db78a472d28e8ce9295739ec2eda7ef1e2e7444a3363b5944cf09bcc3785c86cb4f93827f95f3af728d6c0f7da15ea2f11ad3f0a9c61221349dcdd903c4e6090f40cbdb09ba3b3a1fda0f02b01b8302a3cfc4fc0cf75b0b3f4dcfe350617b8844cba399b0a345a759145030f45a6433e62938e5917cd4661d485dac55a644421e25004975c4e2c1acd132ee382057cb204ee9e824ac7ce4bd0c3868e1936e9528f4d19b38d4b3b43bac5340327755ddbbab49749db97f7c59252221bb3a0c823b9682074c446773d8752bfb44bb10d977b452018ef7451bd1ec879e40f6ddf2672d07cc87aaba06615a41a55fb95a5de6270a021154f8840e647064a69f02977599a660003e7c9a702c118ad5ace0d5718e68c597e0bc3b9ee9fa1ce634bf7d397ee92e57bae504ffbc698c4c46cb03479469d86832e7e8eec860861a02e0bb1fb33b2180cc887a4b02b05fb201a7a609ea2ff3fca5813293602ac33fce79c57393d8f0a38caedf63ad84d5b44ec5eb82b6c883e344ffd7f0d27a2f35c262fa6197f6951d3a6f985fb2a2fc98fdc5912e281be77998ecd8f7dcdd7902b18f77bd098059a4fb1ef9cdc09bda7c1c20c4d42d83c68d166f3336335aea0a535ce41670e69569a2f5a675f06c7a4e7698ff9c0af32428ae65dc39b6202f47407838912ccdd213327b0b4be4a194c2a9f514ce9b9edb099c4125f83dbe1c39d433affe12cf2dbfb3865553dc0702f583c192591113a09ce4219990ae23337565b6be0cd695c9ba325a57a6aea3e6cb2c31838820221d99d629d37a655ab70ceb9769dd32f4faec64c8437d062935179e8e9967d205bf688f949618d70e49b11ca41c8e007e6cd12c842b0b6255b25103f252b06516e71a161bc479cec759e7f19d566ae42c8bb71f81fad738fd2e91177a300004c21f7f4d2d33de9ded19676d9ea626f4a8160f03444d146018a21f4d9cc34d4d17279f74806adee168687ddf3908fe2951cd301086e1dca383ce07d178fe41e71dfc7bd40ed504ad86a7a4735fd7700eee3fd9d9d1988bb76dd150ec67569be5fc8f193b8672eaf6aad328f9e74e3309ff1e5f872a8774c353d2b1af2b3307f79f6ceb68ccc5dbb66828f6335bcc72fec75c1d4339757bd56994fc737d99847f8fa9439543bae129e9d8d7f59683fb4ff6743486f2a7d011967750ea0c461da24723792295fc172cefe4efb974f85cbcf95e1f8d4e65e23e33bf53195b73b2d1b1d1ab0e719d26c344597e7768eb18da9c57d3d4943739f00126dee1c47759f939a73946bd44c94104e06e3b5cc060512f4eab910bfec66978a524a699360e922999d9b16110e251cc904fe29e433caef3348b8975198b3f3e28f5ab84c05e1eeffde3c3531a2c0044def4bd5fdb292e50e49ab28333fdc5058c8c51f674c847b8c09103ca1c9f000cdc0ac99b0e90e41ded9dbf201501941c4473cc81308a544bdeb10026ef7bef820f490ad0e4e0de93d00493023899dc7b17964952802707f79ec4ad989400cae46e58a3bbdfe8740351de8033c36a390829efffe822d5ebac932371fde3fee2ee9abc4fb0363dc48118f726fc93bd0e507d31d998c34bd9f4698eadc84959a47bc128776546469d9b960c19f04ae82a0f2c2ebbea7b3571e6cf7dd04ebe239f906d9f4699ceb1a11e26847f89aaf4e357c9758ddcb7934fc0008f55da8f72320120a9f728d0998e32e916223d7658255fce347772d06930a18c38d8615fc3d08c40b836d643049a86181c18021e3c722c92ae68d083eb6a85c1c8d4091b21da879af72e4c689477c011bc138747e5825a575360b9f797e9ab3e485968d0baabe891a9013a18fc667a51750a86e9c2cc26f1357041c9dba172df91536405018094251a37db2d6a81b790062e8a3396fd43b9230c42947cb966c186aeb8f30158845be7ca32a22521b86163e980aeef4550ccbfce7c2a1d725b112c91c0d0b8143e0eeb6e169a9167dcc365a50a042feef1ebda2f4d614740ae5fa503067e3197150120796e0bc9b8732814a2d47d82cf72d5651cf01f1da0c5a6f183315716e6b625b4eda0127debca257605dbfb128b84aef7e8a4aff80471ec830d2d9a6a0cd502900622f9fdacea7543977e1c1dc121e77cd2ee78e297cce9a17444d38b58fe90d77010dab24d1b79f51cfda30f2a81dd6cbe2791e555f58ca0de6ea3b1f83548e94f6f5c936e83af0f13909b6355028c126e6763b05b9b5cdf4e2b03061e264f4b5d31a5e222a19481886e2f31dde144348307cfdae847283f58e497a6f5d9b415416149226faa597333ec6a2c7a708de30da89aef5846affdb49ae240454ee05058cb1b280863cc607be510916ab6dcf316d6666e77db32ed1b5c5d23dfe078aa73aee3290e37c3ef5a73bf161cfcd5d136f9c756c25ca36ae4f3262f1845126a988a23f2dc09decd3e72a8f4f0496333814e1e434f1c69a579b179d0459ece56beadc25dcecc98b4321e884a69c0bbd4611ea8c7e7a32cff59abdaf6409ff14c1bc9b637c6b42d393842ef62d39d01a5e38b19879a689410af1860d018cf61d7842ef8e8e1ff13ff873843686f4121dc4ab1fbbb87c7ca3893162c3120e4c525247584c2ff2c600b335b8bfc0cce086179b042fe87a8c7b121a7ffa6d11547ebb530d6a2f4ade20060c5814c48364dd389fa114eaf2f0c32543044a7abdcc36e08e96a8157e80e9541b8dde76148fcf17110bb513ea09b67b0ef0f3c9dc9c374ff2ce23ae21478805c9014cd1002103a801e9c15f3d882e71677ac34319809dcfbdffa5c616d9280fa33c3c514ea723e02a7bd1ad27daf24975ee5779f99f561f69d3116dbd41884bb32ee9f8331ea21ba049078e5394576688ebb29219c3ae91eb59b3cebc408ed6f223d7bc59a0aabab79e2936eee84a7d7ba35f613f52695efd8bb0cdfbcc5a02b4b566be8e5fb0c42d4bf656ba9376bfdac366dbb8af9d4a97e4422f9e9285a3ce35bf45889b16394c0ba321588c35991b5ebf7182618d9e9326a42247a463c238fc471270a3c49e237272dafa765d54bd162e0973229fa3f44a0a5cd8b52719ad4d926c8e2ce68c0b7fb5a786cb2d980c0bdcee2e1feebcfa2696a98428333308cb74f8427c4e64bf7903cd4beac08fe245ead3dfc5d7ba67832da6dff2b97f9c810ddea13191bbbedd5f3b9a2c4a1bc105f12ef520ab5ba74229edaf9307d065a5e77f60cf65e15b16628c9d6552c10c319ddacbbe1ce47b36f3e0b244aac7b3e21c195b4f838d9a003ec4576c381da2a9d3204fa5ea7eb449ec2a2c990b6fa709006138cde7a7bc5a14fafeb7af40cef19c6f3f06cd90d409b800c59976e080b3954681a4a977c395bc7ec9099efd0aa3dbd153e77fc85b7f117ab1e0f859368dd59b27e07a867ccad1eab16fe292726461fee293cc7129ea6f3d267d7d0b34a60f20dd153555de45279a42786960ab89e488359933cf2b50602164f8bc2606c7af3a59348730b319ab04d59b6d986f70e51d099b0401adc954aea8424f065ec951f97ad216b5695a382f670955351090b1c6661c7b32f63130f3e4d9b51232e258778e98fb7813fb79d17945cd8cf45119328b414a66f1332672e27bc7fc1922102e00da7b507daa71c2f2e2ca41a652117993e2373bca933677fe540a08bde23b81f995436ab2b0ce92d75849170274e317b01bcb1b0ee1ef0e47251c6929b15812eb654694cd139f0e949348400f5372c073d91c35abf96868e686efb68f0b59c881d5bbf155daad5923e67c4fe2005ddaf20cdc3bc4b026a789a9cef8b0281ff01f3e3428998609cc8f07ddd772058da115f9a1d4994fc3307bb37eeeae47622df88fd7f7e6023f79462dfe864cb3ad7b56648c0c3a0f61d70b5493c0afd1c70f413d4bf4a3b30282d84d8a8120cbe7c3569d62109aa4ef6be30ee61e7dbc71bd79437092c99b640f117cb839f5bc2ce5c19841a09dae03f637fb1dca612af8e3743a03d061721501e8485ad9195203c1ac96ef611b265742313508a209e1148104104398c2f86b2b523fc911f6a714c2b6c30250c7fc25706b5c139c006d1836b709d7377997d50828c7520ea93c82f5789014b29a11c28a9f09e7959f168b94d0b42a200d3f496884d33514aaa4f793f831e0b9be92ff8d6cc7faa0a0f1c314aa6c4d2cd376c724f0aae2495859cbc1db93f78ebb2dab1ccf9d7f7e04e2fe6b47e562729423281279e259b12d42fd4c22ff28554398b57fd78ecc74c5aa9aacec82c6548a2e7b596533bfb57b36750a1aaaac0375d7527913a2151b63dd47408b669b2270d6c0964ead2e4eca3ff6940137081a1c8b80abe4034bdb994e34f0a24944e12328dc0e7efe2d936ade32dda2427b9f4fb644899c21514b516ddf9965a945b316505766c356e4dfc43bc0d408d6f4d8dd94030e5979797a2e183ddafcce9512ea553760238c614ddc5d581ae2555a1ac5cba07d77371d9950c590b21883eb76764ac2c909d3471bfc8eb4bf4f681c0ae671d09122fc9755bfd7c397fd75b4a60bd88b67af2fdcd1849655aab4d47d9f6dc808ca302e7d160e47577e6ec396b861fb9982adb679264c6b70de038e4b5c87004d88fd59b336e70e5ed533b5f485186ee13311436b521604f231c242fd6d4de001d85dcfa61a711eec5a19e4ac6f363a15156c1e2e0e38b5e590776658b97459c5c77b7395fb6578723999a26f53c3d0588ac363e6074f08279702915711f117fdf5b4951ed7bce3c16c401b00a991ce13f4fb152d781e1a11c3ff1c47947d50ed731881e5485cadf2a14683c2bb7142e876cbf72d449b028d566fa14911acb4f1f2038128ca29c243293447bcf2b11848e904b8a8ca9d966216a37228950485cb2e428182be048ca6eec6ebbf25d145b7ab2190dda64330dc3420bb7466e65b36846dd1572fd26390f343899b0e69e29e7f94724f6ac1cf8e5fed3816239b00f62fb7a20a4cf2be292609e0a929cf45a6dc971b98ffb89e641ba93200a534003a5880668c6f6cf1755518f31435886f548f5437ed11f23486c9707382d4988e16050a3267dd58f73edde690915b970da8a25dca7ed9dd60828824156e7075351c13fe5e093f1682aaf92d27cacdbfaf7930837b36ea1f6defb121d583ab2ff6c8e0537cfdb1d14095dceb732f446ee17b48805b338e639afb48832f3688e184f9c181ef3c8c6b138c45d069050ddad80c2f11e874fa5e64fe5d803207addc5adf8308f7d2859eec69aea0d7fa87c4513345134a7886b65408740e33981905577d5e202dad4e546a077c8b5377944a7a74825fbe20a8a3439f1957696dec7cabb59781fcbde67f57bac7d97a5efb2f25d96becbc2f759fa2e0bdf67e9bbacf567fd3e903962137c94b404933a9c2e411bbf0e7347a71207272a316e45530160ed985ea60b43f6c3e756a87fe73472a0e034b74e5cda45954872fbdcd4b4fd012c473958fc182b03f43c60273ba7b7137122361d7c6f6fd16a22d176c94a416a2f8cf66a42bef945ff9f42a73d7d05d00f0998c5d1d6ebeec506f3bd34acd9443db81ee0690b49a79874ad70accece50e1a252ec2f0cb797e14f84d3215a1b1d4d22966a6aaa282b4b357caab901180424c522632a216d727835dd420e43a263084e9c3230368a1755090f1c52389bcd46fdd448117a1bf7edc2e05d4f1d6a89432d7a15dc13febc8cb419459696cc829682168396a4960f77540cd3cc09cf495e7adc69acf950c069fa3a2c753cd529b15b1fcf253298ddb7836389d77601d4d64b835aba3f8bcbe00896268111c33bc23d6b8567f50549007fb59c6872b3d68846a7910ac27e9c12c54493b68476fa3bec344bc6754e35dffb639256cfd84ea46b4e0c4223323a0842917f0fb9022d37ea97d6af849f4020d77fa3f0e2ca9e574e484061b551155884a2c3c6aa6e71abb75495a7e7481cb3b5d970186665cd2bfa8fcc5afc005a293637fec4908a5850dd4f831ca244790002928484246ad5259ddad0f2c6c447f0628e06e6f5f83896e4a9cb07799d6c5001f2492c295c1fc9f6cf06eeb75063351cc5ead4927474ba6a07e852b2fbad9c478a2a4cb00e420dd38a97d816b14e28aa77a766bd3270cb3bbfd394d3baf62bb60776404a04f4a900ab353e8be294d6a9fd6c4e3dcebb0ac8dfdd009141802e6289aaebcdde61cca6918d7b4cca64d1c7b77390568a2e30025b03beb82a1461e1808a5048e5aa1622de71daa9f31768106feceaf1f00bd205d80f1e24a79ea5dc4bd0da17ef129ecde24ab85f1b708ab5bd54e3b1fd1cb3560a2030f7a7c08926ed9fc5cd106e6b5715083b1c48f28af5131116dd4ae46c8ecc12b19953f3a835129deb96fe61302b976832cb02d6b8dc71be556b0f86ed27aecb4ab7d19b105e6c666ed3f7c3707a581152a773cc31c6ed86aa30a80b8ef39a38160c58b34df427c0fdcb2d2ddf61fa9cc52fa0566c821c903839d11dd36df67e4f1b57f44f64516d5376442b904f7e2b3317ebee7ee06bbcb21f61886a38dd512030c4aff30c8a9160439168cdb1a358c155178580cd6ef4335c142dd8fa88c892fd116015c09ea031306c9821f62aafaae96a7fabbbd8600a17c2814b67bc01fa1ac50d4767ce290cfcdfd713111c414078b7526f5993a3cafdf66453680fd8cb4f393f32f8a1e7d33a0c3ec657ca5862a5badf9c925b9bada08f81f4b1bdbb792b29fb3ec3e239cb959a42140750ff064385ada9da70513a3b005d84c5bfe004c961a881a28a9c32ddb1a4c0df1ac67581f4b2992a615f819ea3b5828ff9a5dee9a0230cab6c967a4f0088e9ae5b72c2b203ba75ce1ca7e95ca7749c8fcee050f4a8ca6e6cb8d453cb68626a0665867811d3376b623a6f45743cd9f1c55e8d9b934af202ffadeb17389e2252b0f82406cbed18a138b150b2cbf1d7f6f6b66f4c1f02b6d9f6b60597ed90f676db066cd423e4f111dc03b764867e6f3b28189c094bae9b533f67e22e958b51078d7071808abe2d1cbe79f80057528ecbd0f3856c4ab5933ee243a4d328fc8906dff4dd42d0eb85c7eac78d1c7cebd88997e1b1a67d392f94665968d8f7f04bad88abb52330cbf5eab44529ae58055dcd6fef82d7ab124dfcddd2da7c805927a48e73732863a05d9f2cd8078e1adfca11f93b53562296ea67aa420235940e008da02c77d83802fb9f11cba499114f1fcf5de9d720b6f1b0123d1c9ac24c78d1d906b76049e8306bf500133d3567136049e9913ebc4892c35024e47588156b0ae429da2da846a40b65123be1482a8ca9f89067f5b5b34894f8edea425924b0dbc7c263ab5ce2190554cb822b76a6dbc963ff06cbd072ec62b888206bfe617d44b5c18c5d569e2c2140b9cdbd9fc858aabbf446c0d58a682d6bed6095170ebe9cde1a2dfc8dc6c809aff550ab107411a9b0d0730c435f7094ed5dc8fb83bc27a1b901d4941524054bd801d28eb3aa992c750226ca2b4f53dba10fec8295273fddd966221853bcbe708bab255882ec3769e85685f81295b4094d1c2d31c45c582da5af1d4bd90723d6f93473552e19c16bc1f7fe27963953739d88cd6998c9c71c519c8971a737427c06f3f94956d78b882333ba8680b4f2580230fc092520d7832b3d23113329829b82891b15543126829e2a322243e756e18632aeaae2327970d07acc3600e8b9fa2b38a241210d0c1f2b7563983ffbb754361078adefd2773a0520b5032abbc56851e8f587b36e9f3198aba8d03c51ee48cef544363394050afdc2b53fe7d6755170bc4b86caf45f462024e6493eef1947a7420c5cce593a45c8fff3300c4f7cf876688a7967356c6c4f0d1f4f12fae5212eca4c742ea3bbb5297a894458c222047014bc8640d6f7ceafeba977b5a1c28b50c4e6f1943ac253e7615f89be934719f66129f7c3d5042dcc38c989c7469eee0477a0dff55f0a833764e5f722eec1f40e45445fa477194e01644b5fe15bd4ac59981fea4813468b025e516d541e3c48c5cfa36bef4a6de498adfca0363175f63bcb8fdd713e4236bd8f5f16f5075ad82dbff6f73ede5f6e355437e4b99717e58021b34989b86a65c10a1eb24f0fc89eaf733e77ef24f80c1827a92b72652966c3cf6c95884e5039d2c26fd2b069c905c362e2ddd4e2f6adbbc99ba7a024e34ca1c25f141ce20a3f846dc0c3f07ae7e13ca9305f7fddb5c50684eab03e930fd9ce35464bf468e086865a51b0bd36f545e3487cc9602b69da7b2c26dda052847937aaa53d552a318734c88fc5d4b70a13d52c653dcdd28b5c02f1454a3d6b6e04606150ed77bca8614c80c8e933c2cf4d52e8690d5664155cc147cf3dca49bfad8a0ca10ae969b720439732784257089ebda73979c03356b36e0f26d872f1c16cf2b82ded0b7ca23c52c00f61a5f650df4188fad2f2abe1972ed6492fc7edf935c311f9962ad4e1f31384d495ea9072ef86307003c0502357f95b39fb3398d9c962f50053e4c32a9f950b035ee5d206231e0183a415b424596846480d4ce72339205224b25e25a558235ee86887866805c2f48b5de450eae680a7a47d167895a0c84a5510dd68312a1270395263faed76a3149c6fd66a36b870e94f6ae0d5be3afe884e8537f044a74a3c8750f5cbeead4bd550be86ec887b27298bc02914ee8755dd334ee5b65524f95817a9b15b7e7d2f4efc7ccecb61649738dfb0e7a837916996af01420e0094e971f1f7f2ee9e326037ba5a10edd2e886839a2b984631aaff8a5a344ed46ef48f5f93d30eeb6336d0a673290b5e8a907c9274ae55dfe6d6bbe4d804a098a9d30389a824e18ca6db729107275e6b51ab16dac451c7b9f699a203c6d055d138312e20be1baf021375deeacf7248bf34b57803dcd8022480d5841ebd3d1bf3c086153d6ea9248944f199fdc6e24cf923570df05452c7bb66dbe7afb67a38b9e3ece5d3abcf0e3088478f631cfd94dc783471202577019361aec8180e1ae821ab6c23ccada2139d787b9e620900829287d9ade7960196318143e11a44ef4ddbde0f88b96bebdd77edfa81bc8cc77104b8c4cc069d2e0db9a1bcd24d5405cf5de7f74e29128217ff5c20ec06a7eb5cd7e9ede30f9cd40e656e159fef2b502270590c6a49a3e75c6914f6c0b647f8514827e6229fca02ed5d8e857e9ac5db74e92c3e777214512a0945b9665a29e937d4bfaa8d312046e733345c88217247aa21d3291f169e2adb2f2543772ca79a275263497aeb07a37aefcd339f48f7c33c4a37dc25a830e050c16f131d7b2641cf0cd70e0abb4e359b740ceffaf1b202f5eb2d49e7178f8e0e61e9a64825e2dac5a1a0ed333073a99b9613305a8f456ec41780f4d5021db01d52a9a7254f81cd00a3cc8694c367c0052c981744e26a13770db82b906103d79f7be8535a57412555914c188b0f2f828f4f5e40b1a8d618b37f3034fbd4f2998bad8b0190aa5191da84a58b1d5c30688bf797c6cceb4145eb0d358d29cdf4af616f8900d3ff2deac9dea2604a5ad20686ace4294ecef0f9ab47863a51ca7503e3c5cb880d21c54c1fe3c917e10d39733ef02373aa44259bee775de0d42639390ec298dbb97ce5015330c070d2b0c69f49390173b4483f6661696ed53884ad91c5faf1e894cff19ea6849be1df0336559704598e89282d7b28e8eb10fbff8e73a78817ebee5fa3169e9efaf02840cc9df0de1786a52ab778d66ed3eac92c4319dec4ecac6ab7a28eaec6fd82a750c1ee2cd9047987d43536282f27a2272507009904c99d83977824d3f07ff448d15cb7f707a8d8ef3c6610b33e8a380a5ea718138974ae80485218e754a21f34e9dc977c7cbabb28e243e1bf957bca2334278a68f06ccdb1043c99965f26691a8c8ecc98f25e50ab9399ebfdc3716840e036ce027cc3e9685c9cdf2c9ee51de72aafaf513631eb98b50f8063a36f60cff1c5e1387be53d17894c5351ebdea86af28954a50d8bf59ebfca75825a594f031168efc0afed18e19c85ad81e588b9799fafe904d1356026bbbd59f56ee00dc6842e362cad2d27e1bbc956f747cfa01bbc36f8bec609b178aa962d86b7c54455a3c4e65ad8d52aa45d06c41329f8d082349e088eebfef028d7205ba08c5233c32ad66823c339c7532fc487ccf229b4df3f79c870c6b9fae56d583e7a9ef213bb06b531d8a5f9a86eb4dab4bd911fe805a2b9552d15953bb6bedc43dde253282ff7781bf030863ead0fa2a3ed54b96d317ae44949efb03e8e33f82a19b6b5d3c91a8f9aaef3336af892c312abbbb73469c67b161e7292c5978948f84a4f20d1e42a19960b30c3cc1eaf1d691867772987370d987a46236206da0e6f497a935d205fb4a1d41ba07fdf0fd58fe0ea9360bdccb84858186b1482fe2217a6680a45373845af1be69ee2c86d0b62ee9491abc5cf5ca62bd365bb86fd12fc4cfeff7df7c987f6c1276d2fd81fbe26439fb9203dbf1611f7bf7dfbc047f7e98b307b17b311cc42f26b9ec0d8c548cf0f8de04590948c6ebf301af01ccfe5c0d1c5fe40eb603422133af4fe6178f8476e8cc8720e5829e33ff6e9339ff9e8e9dcadc3b6b099fc38e7f168677f94f4851212c7b7f3e03511d353d2abd88a515d9167019573e84abbddc804dad78582d760c9cb208871dd1ced7392dce3fc5c978a5c3bed683bd76848677643201233110c09c3be38e0cba435c215c2878f13b45dcf282c5c63ad91c8a965a87c2f17ea077f59330ea1ca456250750f896894b0b441bc2a1aad0170af4e984fc79f8b14e830e4a618f80632c262b2b744201ebcee0fb8c8ff6d1447a90c0cfe8ef97f48d035a1abf58cba7cae71afc712f74d5f4c5826b17489713fc4b21844147282c61eb12e6609603d7b26efffdb4134505a707c23cc1e064a432242cf34184a73519e222aac47425bd79a3bd934339736ad59c7455d9673ff8e7b28519bf9332e054e42e7fbc7aa66f6ae8dd39cbdf015b6ede186a76d3c9f86716a283506393275f4512e9fb15443f70d37fd1e7f0b3660517027c152590921a7ed9b8671322b102ee19e6256db2a22a5acc0b83e946e4ef6a007f570970048c717546ec8a751efa61ad66693f208f932f48279440650021ecf1f04913fdcf88a20ca25c3cf17edb7adcf79a512fc2af74aecd8ea7bd03cb788e41b86a4e7d7c10ea40021eaa6be8c512fe13f26623735430bccfbb7e0bc98c5481078cdc6b73bd72e8c3d7fd26fed2c61a6c47b923df00c66a23e0faa3d49e88580eec8a5d4fc34772468903cb8786776850ad020805571b3a8b3ca371a3c5c12f8a059880219391f5742c2c0ff7c13fae74ef3ecfd5f1dae6dde5175a00e157cb14f1259bfcb466d5e979fcb3527cab04aea88148044e75e07b78c18689e81a7cf2dd2caf878c02a4be02280fa8c8d61d0e1f2401595662556e99148f1d9a57a96477ff8aa6a685aa51d27350cf4ac39d7e40748152c9340d53dd75e4420a6bb399da81dce0e08dd4e91c698044d5cac1faf2e06571a605998b7df3af0d5fd842f792f817eb8c60cb573def5c1dee760eea0138152724e7f9e373d3a592cd3a4ec0d8a1c6333ba8da2f2d4fdf40b7e5c689e09142eb8662ed3479a8ee20c4580f85eaa1aa9ae538529b3dc95ea7bc0ce66679b2bcf921912e8c95ce56db759c29a3cb758320c299f86f74e30336dd3a617ca441b567405e39e19e7f985b08b8581f7946a63341c33d78b459a014e443c0a718d5859bd51f7387399d70c03dd9a30df9a8a5ba960d81b54be24831ed71059728b810cbdb8f90a024877dac226888f430abb2a59637be1202be834f14ca9e3c339a9c277d6af09471382f6708153a4eeed1f2c821c287ca702ce61473619752cc772be0dfe14f703dce621d5e479284b114afd4bf15f4a746a7a8c669008c0fb38a1b3f3aba46d532595061510016c912c3828f060b5808d4cff583484af6f534a0fadc656d54389bc6843b1345a20c8aec6686b36df2ff87e51e127f3fd3ab7e4aa50809825298b9fa3e06ce4e4c9a21f5207259ee29d9045250dbd07dbf4e5af9122490fd5a130dc4cf78463c6f315a84f2786cb5530ebf02102fb0bb30103d49f38bfa40fce497b3c08bdb5b44c6073b25ea61ed8a8467b6ea385e6a7e90a695d55967ea4acc3a8eb405cad7224406731c361a2d1b3ffb1afcffaec637f901864a9923fee4877e466915e87bc505633c1692948385f0059bd290f2c785c5e0bb1a8009d507365eb5e1b2a219bb109a59af833c9a009621d174c9b6229d2a06d5a43088a182120026539ec986950fa53b4ebe090247c2ab1ccae74739a7d9ecadb675bebbd4ffe8b781ee4beaf41eac7d8b072e38efb010172187eb1f483378720c1d82564fb322634b23d35798874ec10988e7851f6fd8dbd45c9f5114b1edae0bf6f0b88cde1475e8877c4e4894c8526b64617dc1162a135a08019fa00ffed1fdca347b9a6da90b99da0079bed41a883272a8c0abaf4ef988bbf2347ae6b823a6d03d65a54d0e3555e0a134c6e499d71cfcbf630ff4419872b685cf7f657680efd10582c751f3a1e1f270873e8177217490fddc4e69910c71b17c64f0976aed206a68e595adb5d7810db0c2252c6b1810000681d9059be4a8896e392e922f7cba7d270b9ef05f8a30633b70a834d8cb9b6860110641ff06065af4e70e490b209da80d7366b5f999f49ec6558010165b7127a85f2edfe33e5cd814e4823903be2475d489c56f87fd7c53d59e211c8d8a3010f823e400cda642123118cbfd8a2f3b0b650671287029684051d28527346086d2d072e8ca5f6b14dbeb9f9c4f80f66875db8a467d6824e1f0557e01cf0b0313b6657474f12af743bc0cfc776162a4d3433e67cfced89b897bda0f233f26c4276c0735745dd03fb847abcd079c7cac4cd873b724408c0216359f292280155c1b5709b49689731d1d895aad28c8a18fb1c857a86c65b8ce77ee6b99030e1ff88c1290c9faaabc870e330e11def1f2f33e3c862c3d3240fe56d1647706b3c7d903b1a10a83724f1bc7105c44002dcec783d6c7151611406929b551c9177c27efe178551788c5de29d33ee0c6edf37752dc12da05a48a20bb226d121c514279de45add3c151bbd04192db74884a9ab48a9b1791a02ebac02f0703fe80f6e065253a1ed43b7d2686cdb626796605c9fc0961718e8cfac2e612d5d0a0bb0e4294f9918fddcc25225b24a6477630ac4a6adb06c2a659c17e40f5a0902e3036977ca800f3c95462de81284ca4ea3de78beda931d21abc61ad86d53c9c442c5cbfe39da2d37bb3841204f030ad834edaa7f53945340d8bd947e558113d7eec970d76ee5a752e87aae594e9702ea64d390a739a33fd5e9b0264250b396da6f853b41197940d5d308db7984db9283f1671d334e2b84a6c5c59a6b0f3ce48b9cc13217bc7b4ef2836fd5c2a727877785e37b14d8c5a2d1938dfe9f56eec04751c9223ca0b5cb4bf4b14d7b4006c9f889e54896282c2d21ec40e840ecfdec458835f8bd9f42a2b181b356580dec7c385667130aa0928f07ce70a03efb0f7ea68654698a05d3a7fce1a38a92714f2bb7f40f80c73aef96c09fcc2fb1589eb9a250cb7054c4d0bb6dbb13080a7c1bd106af8042dda52c651fe314fab1dbb00b57a5719f90c0f3cd00b82fd0c36a823912d0ceca41a0a87761ca6d2e4ccc01d0ad324dc2e7df0cffc74d85276b2ace8c12342d8b942434b7839862b0b240c74fd7642bb0bc02a5bd887af78914acd07a52cc5bae8757c6657949cd7d3aa8ac45d35d306c482fc54b375b6d293046391dab7a30ec446c69309c68f4b7a708c520f2c5478cb7a734d496bbc242a547969e2fe5df8661e604ac4c6e43f0fe7ffae186abd2d8793203fca7f555348b47333b731d9e5f700204fa2ad2cada192d142cff6f77d37367b801183537ea065847420fa80e6b14050df2a87bbeb10b119d30cc87134edb89a13a9b200a05dcecc351e0b049b862490b845fb0d14cad0837d40347a3b2808a3ec1b6f93d0870d47f76a83b7dda7c9ca3d825c461e7fdf068d8bd2a5d7a759fca1ef30c06293664a73a48e2a0ca82867c18349475e679efe0c9dc1bfdfc99cb8a58e8cfa6e4130957edcd89107959f995929864811dea36ae6772e34a61346695cecad7ea371f37c0290ced62c62a4a3918e0ff0a9c2e140ef566be2103d4953a5228818871107ba2cc5a4437cd254938c0c410f129516deae3b03df04d3e60a1e86887031ff42c9c090d478a812c5148c054ef8aab9d34f558264848a7bd2f7796a3cc0d7f04d851c3bffd0acf10a4a0b853e73a3d5509fc3822067742a26a86f2c9e7aed7092cdf74c8d2cb2abb13e3c72f4dc6911b596604887ff689e671b0e6d887a80a0002ada40a62e6b49246fd548e1bc8ee9f5d4d00ae602998eefb71d6ed72178b08c8f3d897dfa4ecd7505f6cd1970b29a0f2a4af3073b10a0b9a6543059fa180b6f91e05e8d413a0f6257d24a255acfe1d955e18f35b1722ae951b9528959fa386fc35af67032652bf0ca0e788877f422306deb687a1a4877da9544c41343004d40a9d422c0b2cc7101ba1b0e3adbd0a8a6227de26bb9210c126c43bdda2edb480ebcbd4186c4976ad4e90011877be0435870a757703deb1caa3b4ddfd783377ac50f8594ae7af3942419501364b9182e640dfcdf577b74e499a1d11c5fffe376b033dc4dd22b03b34601c42b6c253d873396d9c421134701350be45363002cbecc1b7ffeab911211e5092c1082efc824b51b2a1a1a7b1260d44f59a9ba05ed6d39d883f2043ef15413c7cf58844b60ce94409816367b540f0ee4f656a94e666d63b3417d72836576f671f427a4f867ee8cd115b9f770288cfbc832d6f3cf882ff0cc9bb4e85cc40c26d4478e34d500fba9554b82e2351200b362509bfa8eaedaaf03a8236cb1f6648301bebaa430a90121b4cee88570838d2b9cda10b425179c4ac12435f1533c2db071472566d09b88c473b33bb9da65bd777738adc03b81a0d49798e773bdf03b1251802457b5625886bb292e2eab56582bc37aa503057746fd4bb3459f889bcf03313855d0367f95ff445fc07fa669f4b30ea66713077b10292e6a67b03dbef099a8aee53dd056cb62c76550e9b70110790651aa1b0b5297b5feb35cf38c3126b317c98d17031606fef1a1d9e8e117f2549e99a78677268b49c592b03c298c376705a5207ab4094afc44e6ef6036a1588bb593fb7f00de2d308002ae6447713d2693b9dfad5b8296802181a864f14ebe4ddb622373169d373bac601652ada8544a40be0c9ba37af1daf10a47459249c587eda54e22f8a0a4791c1bfe80fbc92d50d5941a38a19ed1e24fc2b56196c2466fe0ae8d2f0c1790a509a21019da3497b9ea518e05e1bd796d0dd2b95d2d2d28d37482cd0f5709507016035554d2d2394732a14e2e444dcf00ec968bdee5b9a4ea2ccb24ca051262ea65ecb9ab36b9bba1ebf3ee99070074f3fadc0f234faaeeab49af5ef48ff743daf30eeb58dd6297d82db734ab4ac460986015b6eac5616681ac9c15ef527e74ab294c0fa921cffd0b3ae004772523303d22fa433cde708a07200c466d7932af550dbe01794daf2075b0e931d7b94d552500415361b41e602c20a00051b27183f43fad79fa3454eedaaf213e18e0d60f5ae1c0c774fc0085cc9597ee03a4538fcc0fe23af43c836b2bd69583f3badd99d9684d63ea38d24c37e862d57830ff7c655d544dc40fa155a01cef294ccd4186ac986a9351f8a13fbeb2308e8407b50e49e14a11dd211852bb823773f77ed595c660883898ad87f194f0541125ad59281cce757775dac1c5810478071766decf58302369c320da8f612572f1b74780c6b6ea6401660bf1b091e89bfa0a3b1cbda740fb4d8e8586030f20f1d208f37d103688f4ae672b9e255e95c16906a0a7261f47632b7254991df1b3f46293cf2ca1f19609db578942c1935309ad9b7af388558a1cf85aec93e1fb6e67d1dd1ee0400bf6f708378d149faebb74ccdfa95e9fee0c17bf24cea5ff57af112af9a2e3ca44b0d1a8722b42c886a7f06d5aed343fc0b275c0e6aef3b0b296f2f4a00e22357c6c1078770fd1498db930d1c18a0e7e46eb23d8148c05a68f36f739cb263a5f1daa0161feeb87a03bea9c9d72de5b6a4435ca8c7e0b591532b8c6300abeb927b9d2a91ab4686aa6f5a072a0858a575aa5285430473462808e0146c6d2081a7a0d9c46d8f4b4be14ae701a9b8923f1ea6320f9396a350b07ec405dcdba2119c310528bdeef162dc1e7c58cb5688c778cc01c76f7f94ea5936f3606ad2e5d2f8a640b89d684c520724e9d8290537b59471b3e02b0d887ce7864c94fe7ff32205588b7cc611d1410511f87b3e85ee315515448e75f3002ac93cb765f6611c4507795e59f666106e1ba7da4419e5a4a7e4ab21dc94282c036a1473e526bcd913bc400b1faa9af4f70af1951c19a81650a727e24c66af06a53a4abd6cbc05706b50046c5075064a5fefee33b4d638c9faddc22bcc9c4c43e80d8a4fe7ef92362f46e650e739c6afcb29b0a5d11d203e224625ce2353ea48a76a842e12dfe5150ef678da9cd22d6c2443a25c9b0781ae10fb7fd187ae65891eb9fe8917063e0f4f0f96dd7aeb14b1834e077ab3a1c15c7966abf8505ee78c526ea68cd05b2d52c1fb39b46875947a026b1a89cce6953d2f60370f6285bbaf775949075d01b8b1f05d0054384bf9e85d4a305293a610a2a345e95dacad1782f9465c5f5b6b7589a8619348a5cc5cc7772432aa79abe8a9b8caee515b4837e75f8724e0706a658a38390027e5500fc60c2f1ef884f77208b3a19a9b47c16e21ad7d922dfee062be5044336871de4c985a943dc2085b2ebef9453ee91738247aaa4c2e2c3081f0398b88b57ae7b6fae4c8a71e21b7fe6b75ed5803b339a8c5477f952d046222e08bc2855d911eba73620d1775a327fd1498e0de1f6f81bb892f0fd16a10c578bf8547c17ac7300d4d73a8715e70b9c5fc87a8f604a54e0cee58cd5168ac7fb0575c44d75706b922740095d1dae1164ee799529a232ebb98772643a0b559dffe3a75200abaeaad936f54fff8650b711f5b1e14ffc1d06dcca2c70cbbc26404acccf153f53d335603f87c99013f7bf1879dd6ce30f83d39917526d79b79bb6c47346a604f850fa201233bcac232575ffa5a91cbb68d9db1bc15d7f60c30782e87d10d60cec840080c7a85816f08d1354fb264a98864e5240b9c1982a830835f4c17bd1f7fa5ddd772ab9821cf192431b79579a6bd33efe612d5300670d27c12863b9fbe17d9afb58bb79a71f3b010c30f57c5549df74186345be1f6e95f55b41ae1dfeb663e56c2eb81f908c7f812dc3fd1e3da7a358a42710c300810cf71465e9d03e2524c9ec418b2fb71a36c0301c6b8aa1980084ce9a21f747f5668d069cf0bcd7f3f7ba5546865db599d5ece889f4ad453ba0efea6faf9ec59f66f46a40e0b6d2cc4637bca5ef2f9547ecf2dd2988bea43b3628cc4fabb196193e80c696227b554244400c843e0d7ce986f8c7bc08108dccba03b581924406bcace1500229abe52395dca8d6379274dbe0fbe765207d9a4da6351fdfa5677996ab1ecf7ad18e6dfd5afc39899317d76f26aa7f31c9ebd8d15f2792cb72c44e85f2e8b43b64098a78ed399d1880ef32b88e5be629de0b3079e5f331193413d6f39cf00842f57810f34e4e42e4919290a58a29b34cf73f559614cee23a7b41d56fc77e7f1dc82d65b38676eff03a5e51970637e4f6c258069a8dd9029b7b6ce73e71a31e53ffd51b8f5e896ba3bb706605d7981485984aaea9f358452209b109663824a4e785c60285493f9fd1b134275a7b8ee3459e1fb70404af731fc9f1d63e00de31c1677b28ead6229ae72c04977af6af4a49e21c07c83a4a8c0a939872ca846b149a2fbc494f9abd82fb9ff68e27f69b9b8b939f819f613dc1b8b6ebae864381573ca0afa1d8dc0d4f71b3c6efb3048dd6b14e99253079b9e0892741531993e2e34a8b1e93f50d4b5fba3601ce9c1ea3a8bead477a77366ff03a0e9b2bb994ab70e36faddd3edd6ef02bc8fbcce4d16c6bcca063152814f2ea4365e8c46876791b2104d9de964e18c7be25cd572a4315504d8cd9b1f5e986ad9e2eb059169ce0402e0af316cc4fd6caf322401f0b8396928866bbd13750362194cc7d659a312695057bda66019b60f872752b99387647376e9d368060cb0ce8ce1cfb0ffcb88f9a15fca45d7d31ae15279163513de85d1d724c716196fa561de9a7ae22953f49876311234c15e6904c4af0687a9192270211e4367c27d5551c0b2f2f51a2a64294d8998f36f84f6417541b72626615e1b159c714541078081fbe2fcb87d156be6ddd45d9d227c9d4b52a31995e4265a8337e547af430081f74f6dbd549928f36bc59756fa0a8d35568b6fab4933ca9a6c19a08c87713eaf2fd3cbf7a49f31fcd1d9f9d19b2fdf7efefac95b4f5f7ffdf5ad674fbf7ffeeac9974fbf7ffee6a9b7cfbf7ffaeab9d7cfbf3ff50eb89d84a4843059c2b0d78ea2dad6aab556f34fb03d5641673d2708a9bc916edd8d122ff2a39662943f2f8a24fda3471372785778b910b27f86837d7bd9aab555d88c38d5429a511a5b33398ac8c5a72082dec3103141d6af797711c23ba44a2359fdf86ac9478456f273b4fc7edf495e7510941dd8879474193c84e5982b9fbec1952eee33e585c26003d5f54256271f728fd8d86f321b53568830fcf298ca9872770d87f4660893ceb6ee069337903f8c5b8cbd51b78f4500cb8b2995795ef0744ddede846edc0b5277e3f65863125297e93e895f76beffe29ad745c215a3f27eb7707ddbeb00f8399da1faf168c2e124d97a03260ed63475f1d220a216d73a56d58e3db9dad0ea19af42a4b2add9bc8f16f96567feecba01774bad856fb2e027d7f5a11d3f04dd50f46614ec02978eb0afe35f10c3a9895a9844c1505264a0a0917fc1036933d4383966232aec8604b87945d8fda8d221403bbc21c589923fd53240f5f9bb0f09a370d5fb5088c761c701bc818ba5a77adedbbe5c4673cbb47a67bd1d45bb6fabad644253167311653468a7b341830e096ab010750a3f7acb2cb814286243eb389ad272d205710f85a1901d9a50c92d2b582d1ec47dcd4af7f4756832e34676c69e52c20fb62c0db6b2ef516d6adc8b871020423eba3853ec7a58a385cb51dd7e1b52528bbb509ba112eb03bf8bac4ce7fb22b20e9d61973c8170797d7b48a1ab73647593b4ce06e42be7ec72cd020e8f5405290c7a3fc9e4c023e04feaf7f0b0b570cd2e08a604159e0da83ca10a8ce5ffbfd5958f7542c57ace6e87e339fbb2eb1e96f1a64df20c9021f9f040fe5101121610be13c8fb7b5213a47adc887aabba27fbfbc2630639a1d55912642e6ce64ddfa74592cf32f7f100695941c8e214853a5b85a60f38c74e483d0f1a280b531c48cafbf712c1cbf954277026a52d9041371e3063da71bb4c483641dd7764c1e4bd2010e44e5eda836949782e559d6b86e79a6067278e1f960fe9fd1389c901e9c992d2ef6bbc735ae30b3d95a91759efb156c83725b7fb54eb972b677781a850e31a43bfcd037080ef0aac175d50aafdaac5c5177d27b7be32965aa80493f593c448695356a3f49c2cc649f18d3b8ee2ea5a71df60376fe615fbe91222e762292508b98f5fa32c1789aad4fa6d0b112ce1b22629f47c10ec11aaa8a72c190c36aa46a50f7353c4c194d18d4a4a09a927c022e7e9be763d8730a93ab73901ce1bcc381b1b047946ca28e7dd9e1a81fe60e32c1a5af45c8244770afcfd0a7ef4074bade1cb2f73ebaf58271d0b6128274b4d92cdfb6a1c28cb3a20d4726c458176d3523c7d6fd3f47ced0db8e5da370616050f6291b9cc1e928c97968f4c66e6531ab89a94688df6c9503d8f960f7f80bdeb107e114aa8e09a8f99c7e58a748d0959f2d10df7df0426c124de734f0ce9b72e91d0dc265fee3c17f88d4e350668a841ce51043fd39f860088e9047e3f1622f9000ea1f72b465adfe6b3bcff8e10ae54b8a4e2aaee0c42802c5e875900b0f9887f4503175607b51471816bf3f4636e1eede6077061ec57543e1a0227c9e62ee2c5cf5ccc201afdf15214187084308dc0992c37bc680ddb083159ddf37161a175d285d0107aa378ba84460cae3e88866634109db3e82442dc7ed5f38f37c8e680a5dec6575de0341a7cadfe9bef33b9bd6e4e70d08c34d8a6edc452d4019b00bd118a56e9d55fa650834f6a9e83502b88d9184053ed7bcbcf436332025ee00120ab3e3c2f317cb02654abb7817f16f0aaf7df6edb5c7b39b93b1f32c19192d61f2daea4c59fa15483f143467a9b5c907434bf177d0649ad8b1369dc8b12f9290aa26ac8944024b52c38f377ac207f702c1b955a6c933fa54dbef5d609a181ed91c4d91bc00af598fc45492cf8ce7e94f790647501730fe6f2842e7b637df61865f08d926be7a95c93d778502a705abf9e474e9967d59074c92e9a5855941d7b91e88d1921c100256ccc3a7e01fd06c35556eaed5aedc544fde5d9532184d11919a8c149c25fd37a54ec808f6c30b6ef3a067efd6076d8ff0bcf7b2b385277119e0e64cf8d92970f8964e36e7caf1b1721cbf09c61cb4364f559582ed162d684e8f2d6a23b68146aa0bdc0038f89b6c05dc604547b527530bce3731a4587803f77daacecca574ebf59a2a45e8623fd55efc920ab93356a83c5eeb0add0925b405c3faff045af70e3d635fa86bb3bf8820e653254ca12009976d36d99fe2a1e6bd09930e040a49beb41e6f93e157f4e32a63e95741a262892be9cac7d9dd98d0c18d89541cae5e2d49efb083802a568c337345888f05cb2cedf61cdbcaf947e5f75caa9159bb14eb23ec9af1f2e6cd31eb33e4fd6cb40f1cab32383c0020a8875a12cf7a14165f9d26b72ca37b30b329aed9ac6a6c113071cc3b554964a90f51147ff99bd0f9ad7e2733556bffcbce549f9b61487d50a037eb0525dc79880ce62760ce9c04d8818530a21b66de3adf4cead08105dcc240e3d8177de4f2f3de529c011cc1009dda8da100fea22121e1cedb67a529c6ce9e622d09f5a57f21827e2d11a9a867338a89290fb7920f5a1c6b74689100a72a7041f70b908f2b710f91d8c51d10c2c32f618b29add0633b1ce1df9ccb68f96bbe7a165117062059aab5952149ed5d761f19a49e042cde7e1c5c463f4207c59923883d3da4f6c54e157a3e2a726408a879d8e55cb6d98866abad44ae46537f054806f37f9f9c9e52a182a840e963545a58c73af0d448a751a70a35d55a768c62abc547cfad18dfe5a308717d5395c111df3bbb801c304817fa84005b4a8892691bdabbb6398e23d7aaa55ab5a075eabfadd4c6d496558e074cdd8287a05386c1749168efa3635ac18e425923593eece5c682cb8443e36c2f9bb5b1e725801803ec047313585f852d90ca56e64a10602b615f130c6e742dedf2143907b8c2307a04dc209745e06043ea4e75bb579cfee16cfc33c08d8055f3f17422e6043ac447183e185080426e60a62da5daf6952b7ecf543ea7ce80353161204d316e62d84192c0b891e883c11e8e7b5a4bbb3d413cd834814f448daea0cb52c00b62ce0b0e46455b2b988e5ab8c3ee9aa407f26e52d2ce1d54806cecbac63ec1d581a2bae749426665292a4f9d53800ff36ec2f666e65136250d3f3fa4d660b03d407e37e13ab743ebcf86b9092323ba166549af3831312a0fd00d4e3e2f83ea90ff058e117987342f04320cc214608b7388f87747d9404bf444f05e2e2c5d498e68720bffa60d37358f42b4d854e7ebc473012f9fe0a19a41c2fb044a22693c7fea0f8cdd293cc63688cf0c1514d18e80ec0f53519ef68ba6076419a91613e00a19acaf9df9645da054393604c5d59b63da98e6277c8334fe8217b8048043a09aabd0be35a08be89306fda4063f728fe7006373cfedc4a5b8a614d24841d1c93d430d8b24ee870b2978f136672d727b00c3ef7a05f820491185ad04ebbf821aeb462e13a44a7a9ca6c393c4ed974156f5ed96d16ef5b2e79d91fbbeff1079be77108b80e0b1e31b0740dbfb2bcc1411400e1b8b700de76fc254d428103b98fd735fe6f4a6f3bf3611afd04efcaef00be5eb588def6900f9e483e44e2dafd47ae708917b7583727ee7c342dc676e9e67934b59f73eabfc7366055e1b5a527a9e7990858297fe55cdfc7e9eaa9e4b8ed4eedcb3aa136e6dabeb48512b92dcf1e6e0e06683bc5d4e416a46cbebb4c74101116b758865cc3eb3219012b5cd4215392684e6641e6e762ca927713aa1bfd436067c86cad18aa58f1e9e44668de47cd79fd50ef642548d747c0a79aa7e3113ed0ad8be2bf42dc6d233634c6d441ab18a917036e27b1429e29d00a76da945dd3900c31f2e4652d6a51165852e73662291117dcf036f50d1cce5f82beea3b80105c65537beb6b0f834c64c865b0cbaaf01f8802434779f79d84560c644630948dec8364725fbb63102128df2dba9558562b30f79e46416c54dc93d9a6415f9fab5907093b2bbccfea6fe1862f7c9e940d246bd8548b93ffb46e7de30d53c1fe50864ffd896d909083176852c4f1c0099c476cf89aee3e88fae4b3fa69bf777c4bd0605ee919408eae02fe8c6c3efc053c615542a6fb5616d18f3cf4896d30d45b25f7124d0f74cbf779eac403f641b410d3f0b9198363e70c4aad5f1af783224da30e3eea2da2f3b960a2863214cbf153ac2231f4aebe8318be1018149182f8f7005cf605eed0112141deef6818308c6ac919185c27a7f45e8ab42ac4afcb6455a5c22cd81b56e5ba88ec869de9a077690928ddfc56f14f2e68a96b173c45cd8d046d3e811eeadfa7dc72fbf35cf918ee9a6c4485a1e1d92feada9ab9fb4c6efac9e4aef6a78ea6865f5d40eae70604289ab4c0e3f143b8d41d7d2447ec6e5577c9c8b95d3a77a7b8cb4943a06bdd79fc620c3aaf98b55fd2409fde2e8021bada2cbbfcc2168da135628ad5ec0a3c3b76acea8581a6424824c0a2925f26e3d1d5db183794fd1198087651af2021b4f3614cf33b59c94bfb5cc4263eb3317e683e3231a534bd8aa53b66f3134df5e94dcf2f0bd80d65f7fcdda6ee70765f9703b9d2b0963cdd5dc0c01483c4d4a3e82e46e904ea1c70715380904dc34a13fa7ae3aa552f84121bcc86bf3afda8a96291788676c70b05340eeccc07bbac466e85808f9a9f4ae05fefe96baeb378a72d30678ab91c770371ba0681ce04724b955ae91e489cfbecdbaac35171091c5de3a40178148c0feaacb77b5b5abf0d9b74a6237df56c08a8d3c1869a3aeaf5272ac6207c00f1db896fca4e9ca71b4f68a231b3a574f3813581188070cd5e8ef59ae404915a7c1cac34ad09b9ea2504011472224e14cfff1b9b370ec5206e366c0b058d775167dfaed0f0968c56dd0041502525c8f4481470c20379c853974ca6d27f70d53906268c3a18dd02ecb2a61ca84bd66dec431a0a7f40460e3ec33fe341e25307abeac09bde500c34c09996f7800c5d69db11f3c199da0097f9fcc41b0b54a0f1db3996b7baa01b6a6db5a9bcd08b5bd46a185a27e01ec0456db6b78439fdf6a079593ec7deac894bdfd15b17aa24ede2b7ef6b7f94b7fad9e9d443649f7c5313f40215026debdcea02a0770d0b1eba148dc68a3eacfe9627b369666284e3753e34ffba6148b538a768c8bce6deff039058c4b780718d9b0751efe8d69813c5203273a7a8a71cd7500e90cdecb951c18f6704eeb78306db3ed9671513a7f97b5932b98c5579c35e059f2552c26196dd29eb820fbd2b6b82a0771c5e78db6f4c1e64df47a42bba135812f89a41414cbdde04984c6ca7c04fca517f934db422b0576c3c390fced62c5bc4d1040b54d9d6907a8136c47884df89ae7730eb52d839206dbc00416a089be98ddb4b091c1117bc83c5f299adf5bff6156b2077b24f6cb0812d19775b68703fc50bc2684a08bdd21056d21fd4cfabd9ad627af37e7c547179226c1b34d871538d98f04023ff7101c0aa463bfa5dd7189467a480b069e016fc25a407ced5e4de819fbf075824754ad966241742b82a2d242140e1a7b86a847b916d0707bcf077b2ccf784f3e7c91d80bcdddb4223663702269bf70a761afe7f97f267ae67dde60a470dcab61bc1f74aa9d10c528df1593ce139970160ea05d07f4d487364460c10e4c0e3fad55fb178d236f8e1b4a4b22bd181d8415b78bce9770e0c313c2bbbc51090c46d158b85412b83b704581a0bef6f5cb49978c155fb08a3589f68328d3a4164ac1d61c4d1e85e4f5fdd05d6dc31490c13f01bb8fce72502f5ab4b18d25ab5fcbc7662a8ce19bf101c19aff7fe8be562f2e526543173b60554394bd38c02597f4645504c5b2ae33edcc2bb5e7a5c6b2822767fe1397408bfbb92687e04daf8983efe6ffac060c37c195ed46c780312dcf9ecc0d07bc162702a9a7502a6c097cb8d142115bdcaa8b3c917e89ab6a11903714e9c85821e6310b8fafa990a2c60d7baec57e73a95061d1c9b4b40d0ba5f9d12c628a9e597ee02551d63ce70481aa0c11ad2be2f53a84a4bd0ff9d13d65ec256bc477305f3a80f9112dd962cc6b14c2a502373ab02efa11961018a23a78d08a9170be4c7f7acdcae0373eb3da43f9b10511090e51194d066901288b7893eee3ae1774b845d3696f48fe82309f633b0722827d0161ea96559364fe7a2771fc893f1b089238b58f2c1aebdfa5f27cdf014ad089775c0d1ca96fd8ea98007a74c8a6d65600a628de4aa9a44806a750a681194ac0b19f3fb9c0d289d64f0f4cb44ef6c1596a3e50d28ae0867b19eadc545dec5d27c3029b3e7d5ded7712d3171282dc2800f27bd00208782516064b467aa0b70be80119e33491b16883b5d28414de6a5c9e2bbc3842b8135247347d7cbdd9decb2c649e896701d2aac742829c4dca12cb6ae35100e265579f926f92298212f3de820f9100b0c1ad67ef6000486c11447411ee1606f947c2788cb813a1f215f264f74ee5767bcb72de8c34cbc82ee19f552f0c13f189ffff63e18b9c9772a38c9fde04b8a3dc3cc11f51912671d06e50356b98488716f9f104632de5cb9a5fefd597de6ff9c9209266033f1c5c4a9d6a0311d2f28ce29a9cc9791af062c6eed17e9fd0e6a66261e6e7538eda6688e7a162b45dcfa4bc8b83337581db8d4459897f5c12ff2d61478fda498bd8f9ba35c926c79129b2329421ea098974efb35dcb76b8ed687a9653b7482c7efb0918c998e41818250b31650836950a6a38c83305a4590ac83aeb1b30fe109502738d31afc8c7250f8a908c9166cc000f2469559548a2a2801845c8e4c1fd0f83d3236d3f6bb209ab5297ba3de59e83e429709862e9947824dee24a88317934b7cffb232a34df9f47eddf68336c037d7255497191b232e5fd00f07e382c7b9fe127c5a9502a812c6454257e491d505aaa916d228f1b2179f85ed2cb91b759d50de3aee59c76b3bbac2da26cdfa35676538b49948da2122a3ff95fbe1671b29dc90e94b40fd732d74f04a2aa1f1061d5058cdedb74a92544fb708fd96f87c83b13be20ff95a1b27ef2c8c9893c10c76ec730f3e3f5699604483d10f64700d92580e64e1c67411db0c73e2f3d242a708fd860808d5940178ba9938c86e184a4e33d3eb5a73dc5272de8d2c2d25a1406964e969bb1cda417671a9b7dcc0f9933b41e2703bdfa018b3b882a0499cf8af620e9bf369f05aff1f76191c3518832ce7a9993e96febd2ed07c91b4d0717aa11d4b5d673f180a8e68596ccd7e3061f92e0ac60e1eb923c6f254aabda92f89c73b612f296359769c75692647ba4dd51465e29c55f655cfa628d27a99c332cd049f072fd8288f218f4ace7727302a36a9be6036110ec2d818748e2be60b34a5294e33f31cbff4448c577c5ba9aaa42674f3c6622f2acf5f6c95333f154b72c828b42281094a282fd526f9b7135cf46563d80ebc6f82eececde787bd7f0ec4a89d0ac406b6f711302f47306fdf073466d6070a37fd469eda76f408f269e1e7ae4089801042f4f936483e08c6ef8e5d2841811626386a18de7cecd95f0fe3b87c00ebd0ce9b0fee891ee9a2901ee27559af687b7ee59a1a30bcdfbc203a0311db8fb715829f7c58e55062f3a30f5e7c4656560feec83fc20b411fda1247e4b59ec6c1494094d85ac19c85689307cd79e35a554ff9ca824d2e938e076c3831a8119e0fba4f1cdfe50effb9ebd1c5462f467d02222fb439d8993408a936df018c2b123be8486e209c43c5038253cc8c7a94d63a6a7a24f9d88655c368f50a2cda8147002757e010b0c9b33291d8742e1925cd0887b0d695b4af7083239734f9cb1e04f033607f3476c11e20b182d5cbc349690d84773c0bc5421f1a5482502ad89a3606ee5f025a50493917673b0d30892c933458d725e89339fc18d463712c7c54252748880fd47637d65851a8c782e23634ca10b0e080901b70a9dc81fb4b6c7154af8ae450269cf96295375c2988f4bc425f8683b4cd7f07939d2adc5e3b9fe686f3d104bfb38f1eea9bd0048f16cd7ab5f97d3ba0969d3d5d70baea9c9561f0c1f37fab02ab0ab5441d82a19c30e853ac971d590328d1f2754e5ea30c703d1f68cec40853f6321887fda5c53f90a551cd41644d1daf2a6b5a2ae46b38d8ee2a735e740fd983410717f67f6251d0512afa4be51a05c49d8377cd0b33fdfe799a4dc13010fc795ee0c3b153aaf10a7a55917e4a29dace858d5d3e8dea32676900135fe2971924f0768ee509fc8dab5a812c0e77c8072f6e01d7d20cc2638da1bb02fabbc7c13e47cd5453612163a14c34c186a22520e6771ca0111e462173eb2ab4e24d592e2e60b04a34f55d9d20122e885df83ac3b711f7742db72103c6c8b0fac5ab04b76259025618fb2ac754d3f7c9ce9b894c591822b87b76246e8b7619ca039443a741ddb06ce07dab0e09cc8cd2a2461e42633f5127526a94f47c13e547cd24453a32d44d103f097a603d642011394e75adb4962b05104d230c3295c021644db6d1b950652103d9f34a670a7ea89c634b77764f33527a67fee52b8cde45145ede39e2a5bd983c26d04b390b97cd586f0840c80445cbd6aede0e022d5e0490b97effe21c51eb5ca0439a98eb76fd6d8d80008ab805fb798682f412d940ba865b4428cce5990a33c389651a2fc702b47475ab81590323f7f57ad9780401b68371388503ee31d5675f92a0dce7333a5f5fb7bcfa4177bf8e8094121825b65f8d564c9fb18dab1f9e29cd8110e0a40b2eb7874d3f8a732bb1edbe42d44c848458c1386f6a3eeb7848f38ab606ec09f7c545d6d4641c1bcaa8531983952be6bd92eaa15c6df44d8f72cc25efb3306cad65aed98c7fa399f8d84b1770958422e241fe4b87c83934dcb21df0a4198678c02967f114b433ec9903cb728946a0cabaf8df0552982ed022a6a3cf3f5df233c1d8c574181d752ce295ad05a7cf93113c84e38c698b60e438f4dfc3c29ffa171e65fa7455533966f24af9fbc238d7e6d4f9cfcdcefc3596738f4ae47c8077d3c4411eaada747c08220bd3e3d7243b65758b4f7786c9938358c4e594d9292331ca90a1c385bd7d1c03250b44e9825fb6c969f0d2cc064aa1cffa6584e034fb3df279a360a0b352ab1622744cfb7fbd819851241df2fc6b3e59eaf07f1f6729660da49de3cb6c93f4a7d7c91cca883d47dac072f7579125756c026731dd7777fbc3485e51477944ddf581e59d896d252547269ca72d490260e7cc24e0393caebc2a5897b000df1366db7e51e152cfd5cdb8666630c3ba055804e2f2fc09cb1e3a521cd19c97d21bf7f3e10abebb73c2077910dd913736fc916725e4d12f2e8425be0c9483c9bfe28de951445fb3f6b5d1ed0f74e4e22c7396b98468379e12e4c67cf10b3b620f82e5d27aa6c90a580e729174df8bcfcbd24c5d62005b85874df179dc98a4bf80e65dd708f9dbc99367c0ceda0f5f600e005b6a3923e81f2a2f6bf02f389a6e6e9ab2a4131c5294706fe2d5aecb0a0a9234f8859143eb3f0a900fc2804cf6e6b80be17a86ea366a571c337facec17a57ab3764f90b50b3fd6ae7fc5aac4ee7e9aad4808faf8117f0e59c5ac27d8795a89fd0a25b8d2d9ef2fc06c9f8e773a2d09bdb39a85966d2037ae37165af1b21d8e831049c03cfe659c05116d458991cbbda61bcfae8c22f14aee7445a7504fc2afdf55dc4d13bd5a6fa5f47eb487358f1d1e16005ef43771ec35f982b7ecbd80075b1a16523ccb30047400f4ed00ec064ae2560a1a067c6564c95f4ec56e05c27ee3b1b0ba8d3465f9065a650470b8f95b9bd8f92a4355e48e3587588c2eb3d61900ebc2515daad207c7d1ec1a22d59ab20ba423bcd5031ade32945c30903a4e072a04cccf4a6966c3b818a3e8f92178c3f5f88fde680c75d4ed499390a4d9747286b761b541205580aca20f210fdc3f296aae4188a21c82a6344f41ef11e364f3e61a981df13edc32daf993bdb4b677b72de596522699029d08cb091709f6e518ad53dbc67c2e1ed9af45b62319c8617b42ea7ba750eb9ddf9c331082ec7340ba5f70c15734beddda240bc826348e7c05740fa7d9e505a1e19e6bcdf47796ef7b279369e3e8e8339f510ecccfe8b3d6cc425d6f646b74e4984553fc8f0bc7cf74431db733bdff78df8b7841ba373d67ea28e54e3f3ee7b98db77389dea7f1a3f832ff5b388a33e19509430ff371618bfbf16e9bf74750d97bef2ebef7de3bbbdfbdf773eebdab7bf11d69beddb790dbdddb9dbef3be0babb49e901bbec03d6d4f883f3741fa1c583729da97b2481acd3c6f71de333a0e9913627af7259d82e9efc5f8fbb6edbb79e98e27f0386341b4753a7b8f8a014296bd7720609900b96540fc64eafd49a3941ee5edb96dfbae28df9ff34ddf2f64b1d24397fb1e8226f93b11bc1f1e1ae94218b890c7b66dbf85b248c6e312e12e3705e8347012f9744d1afbaf2944dfd8afe08c02ce20179fb48dfd0d9c407ee44844640be647693665ad33f3cfbcfd75fbdb6f3179d33add6fa73f82e23a2e94de8f24e4f6bc97de4b0fd5469ef724b88a7baf47f63e01ed7d4eeb74ef799ee779de7b9e870a3d211ecaf3501e0abf45fd18f32811bc203161129951efcd66cc84a7a3dcdddddddddd3d8777829f40103c21defd94f7a3001bd879babb7bcb7d82e009f1e9be6d81fd29e84706e85c829e4de00972d61b16c9e105a16112996b08c30b48d36960dfbd70dd6c7d983b40e747b3185db2bd7dda7215f73dc13fd97e3b6d92edcf32dafe0cd33addafa46c9ee12ab73209cc778467976cbb233fc3e3e9af6d2fc8294c22332a1cef9ffe9e401964f6c217b62d781c612421fb17d95e0a8db7ff82ab52f7fe0d65942018bc841a6fbf0379b44dce5cd50869844132432f0420a1b2a552b6efade4a2ed0e1160023be36cdb9663db36d376c3f41b104bb2aa93e0bcf733819d73a45276366788c31342dfe70d2f051a524aa54ccaa44c26bb187fb325655bc8e574ed16a98647c6914dbaf9b66df79adec324f2c76692f9f722e5d1d9e7e105a1c9b268471198e3d169a0ec6981147c018401890c3857a06dec53a06facfce62a069ff9ecfb680d2fc80c2590fc71bfb247539f3992ec415fc479117f339fdd997b7dc685a31f696192f007a5bcea4cdad3009b35c19975aec9b4e53101734ed98c39c6a921f3e3cf7cf0f313d03d3acf1e79fe07e08c398d7d1b60bbd310f136b37533e66d3f7fec661657713f697841ba3089cc5e3876329e90edb93089f4998b76f4996cdbe286a3bf29dcb62d09cdf78fa0f27dcd14dea2a3eff215cd2011e7c5ef71bbfdf93da7e95bc80c4d53f2e4d9e9001283f4914d7810912335192a9a4bae5dd0077b426698444aa02019248364d0fc51fbf948a8ed6ced7b5e10ade372ba695ffc8f7d311cdbc1027c39e96a1d9974f284dcf7205745912ecf4be1beffe8cd7b319eb9cfe40f2881c06ec662b1fbdd8ffe5d287d8270a004923f3b9ec045bcd53addd99754fb9cd691607f469494a595edcb9e23587fcea68527bf5ba786334bdbd89fe08cb9687f071669dfbdb4ce7dfb7fe3464cccec1b8e31e8c8a92434fb1f4165bf7fffe6f1feec467feca2e987116c0a8d70a10472d1ca9f6d0b1ea54fb6d2c755a9973fd6ca5cb4394ee30fbb312c9bd9d98c878b5606e7f874bc2cdbe77874a6fa13a44f039c42df2f8833577ee434f6c1b4b5d66e333c4efbf6fd680b32431c76a0cc5d4f57e3e1fc08131c7dcff37ee6297a7892e57b2ccfdf01058fb8b725b249a632783f5cc8c56ec714d85b481f7daf4ee42ad3d3f9ba361c3176c105eb2e17bb1fe70bd63a528a2c3dcf01f3bd97ab529a17a634ed354d0b3b300728c3db2b7f350d7dd8161b6f18f1ffdc79f497d4431fe2da6facc0e39cf9d2cc5547bec2ae1a292c6baf7de758ab5bd23ade075ae784fad3e93b70449d3c5066d3c934875c149a2f2b4ef3b233a96da8b5324cba17e3f9cd7ff1e8bb7c45ee599ca80a3cce574efa15fe99e4af23f28c2c05ff6bfa6bbed83758f038936490793e99b309f4e3aa7102654a8196260d7dbb19e17102a5fa490a1de44bf3d6d01be605a1c96e25b5044642b39c3f99bed31f17e9bc021b992fc37cb9329d3323fe2f2bae226a9d2badd3bdf75df71a387ae128a7cb45dad98efed315c4a7509221181e3d2953fa54c85529772b43ae5292afbd9c497226c99924a71557cda3d7f1e57021777927b87daa94c5c5271268f3975b71988b94c869e8d3a3eff2156569c5002bb96a26b54e7dfa138cd6f137325fd2e71c3c82caaf65d7a6e84128cbf7973f933c0153f5e7a76a485f3a7d8e3a954047aeaa99e2fff7614ce7cbd7c2d4a43f93647772f7ed86456865f92fc9ee0ef09fe13ca23d063f6001b6468e68a1911962f7ef6850e7dfc3f71787d4c51bb8c65ff1fd48a881d6a00af41b04e2620d7fd4a74feb0f9e5ce9bcd19a6680a6d24aafa952a6948e3899e2b848bfbbe9534a29ad956a9aec075806a2c237efc5b8418bb72eb4222e760dc32f6e1da9d3fdd7fbe509b8d6c13940cc946bd34ffbdcc86530a6a7a690bae83c441d8ed38231e4640ce4e4114836d2effd08247b395c8d1fdb48c7f4352600593eea246b745f5328c3b1bf7b1f33061c0790ed6310059eda28869cff72b858bfa6b22080205a0787d669227d6a1359e629bde7fcceb2894a9396b88a888b55fcff3e1a253ca6fae5cf9f61aa654f520040c872264b1e59de64f9ea9bfaa34d96a3b7bdc9e459869f04457822877c49f99aa0b4d2f31b94aff9f425ef9523d8804d9f9a8f846e1ea6e60c4517ebd70dac71b1ca7cf59e769a6bbfc11107c7c3cc998512650b33759c17842653ef046badb5d3a5363529ad0ccef151510b7fc8dcf3ebdb2afb31caa33862166a6d3035bfbb3376953fca637ca89aa66955abf5ab875a0d02d75a6bad55d3ea089472cb7c00e3d455e34f2cb7ec0796dd9354bac4f12cdb666b1afa94be53fab76de8ef7882e9370f1d3934d32742e53cd51a36d09d5382c1f58e2570cb7c78e596f9309439efbe2e9d85f636458fdb61991cefc323a775c838a345a9a46966f26492e5f454505a4a72f1032f8d0c220c1811292101164354a03c41bdc0c1dfbf0eb1c66a55d32ad601fe20b7cc6565071847164b18476e99eb0b17ce14b547d3344d6b2da66c4ef444f1f38dc48fd6aac2897c004193b70205b74a4c192e28c10e540c5d21c309ede8c3628a165f5c451031744ff0840c3045e84006463011c62a2140513e4551ab10496c096201d29208907e68c2fa40850939c45e375072420c1098200c9103b020b9b0c860882d624c68b3245a0879a14589a12ead12ece089ecab0b0e40af1a80c0041bc85e5f4ca8c1d26b4904b12a3c3431a10b2015b84c6085167826b7ac8b5717433580e5f1717eee66abb52e6b65aaed2285b55d5ed0035017303c78f1ea42860f4b5cec00e342081d8020c1b8484207203700e2e2091e807831a406af9bdc3221a0d30d335bb55a654e6639c8da444749333ff8e69639b9411e711054e0ff2101891e234cd025064d58a94225ac0007ca0f0a8ea0444b8af8699915556a706ce49661e1419eb9655638218301e49621312577b9654364f9b4aa69758b171df4ecf045139f9f7ac596987605148a3f2c8331920fb58a2d39e061cba38c4c0b594c6e99162ac836b74c8b57163159708ddc32295d84b0965b262507d80b0621b74c8a183486c0a9dc32570f3584302ab7cc356548144b34b72c0ad7c52eef4b0fca09265d17b293143b705e2c7958ec6002ea94b80062eb6288530a4304174966ca8107fbe5b539f141b3c1eb0afd541b20591810465bf0d0801b18d5c049036cd092896146100df0c225db819311340069e95bc1494b1605073215b4668a789c80f2e5cb95227ee84189a1d90315cd022524b01265298c1e88a8cc18100991456c054147566810c612da92971f986859e10227ba68c2e4656700861158e48004508aa67841c4a30409bef8c20352bef0008cd0c745c933d1344dd3b67c69c2e384043d3003882f5410450a585a8b0b914c9433961c600b12378a40c0858c2f8b3058491633c0b10515980b0ebc2d53d0303112e3f4431326272646583ea8c203415c8664946cf183238ba01b4c5c00c6c7c40634b2a8828d66334c8ac4004149092bd011022545430050b265875416586ebcc0071b379051e38612b6d82200215062e444c701b450e22b0281163ddc506294824ec9164b7c4cb41823c5a4288bb0a8898e2c70f840c90b90985112562e4636946c198386122c5c8cf05620450894e412645faa907d11e24b131e3954ad56adf24cb9011058ec20c6183ae8c1fca26ae18982871e0cf1a089104956d01e33b898d9b0c5880c2aa828217b410f13498684908c8b0eb229b78c0bd2152c332aacc822092996701ddd24aafcbf9488ee8f1f07470bb667f8ab04a9835c727da6c48a1b6411c4911322aa70dd028fdcb227b1217e72cb8488e516e4963d09937f89a5ac7d6ba112cb5a2883e70d7c799ca1d56a65193e55b747b5afe1a8d5d0487dcf9daf7deda9083dc0f6b5d048fd998d6832aed2b42c61943580f31111b2fcb1861f76d1592dc0e3f5d1315ffe93d73d4ed06627cdfdd3d4e48fd3ccf9a6cf3873bce1bb4743e913058f3208f7e7dd90c35de8004a337d39ca1bd2cdb523fa6340ac6db5de9f2bc0f0d98119b4522c4843d75a0d8c102c80d24312d554820e4b62ac2dbc74dbbc13e6735cdb7cf9077d1b8332b260ed98be06ef0104605853e6f3b0b80d3481ed9d70ad168e35e0a48898c094691e915afd4dc897e597e5d3af616894b2d91961edc77ba4edac317ca6bb793ae09a43f54873ad3b591a91c185f4d370d4004f6b61df79ab944b604ebaa00c1e72e82fa6a8e04c44703497dc300450ac052c8eca1f58e0828245c1fe620a8bab578e382288c5695984a088c5d98e080c122c6171b7932209252cee76154c11a93b8dc516222d7674cc8055abd8e24b128b823a66e0ee617060f2f439732b432e36a17d7ee9c5fd72b9bb7cadb5d0a384ee4a1870a56cc465c8a3c9ea0412da3252f270dc365a8bdfb7064ff185b6d1de876bbf030b1e71d6dee7476a6f240316e81e2ec89bd6b9af3dd6341f382ed064f9bd2306523ed5ea532c83680feacfa7df55ce39e72cc27386dd0bbe6aef1d50707b42eaec4ebaee50962f19e434f2fdc845293f01b97f34803c81decdee9a34f2b57fd93a6e18ea70b1861368fab89834573ea090500485e3cd419bf664c1e34c8acd2557554b655a51eb6c5ab48e897b93e93570e4c251d2d7465fd7c2acb8982dc541e6ae1dd2176c4efcbd58f3e590c9b267ae682cb6430adc547ef773d58577bc4628cc456985c6e8ab87be640e998ebeb27cfaa2548af752ba972b2fac9994f6b48d34e234e6aa2cae9ad6483f7df9340c2da375b637fdd6bffd05475318769e03faa9d63f97bc20fdf4fd9358f0a5a54d5c94613e572438b44e0e72459328ed610459d222b2b768d25c512c4d235f4b96cfc54bedc9f23b8fc6da46fe8e20ea4fd2532117a5ec3f32f3fca51aa6ba73b1d5e4757c39b04cc7e375fc742f6539fa2c4b2995602e4a1924024df9da6d3571556f30c03d85d436d2affd0591d06cffe650128529177255bba4f384222e1ed1dc4ddf01f4bda9f7fc59ad911ab16d3acc7131c8cdfd31d89c64661c3c96f019356296f33bd0ebeebedf55d30b9574bfc3c3eade87746183dd8156a6dfbd0fbfe08d0bb0f41153e3e2fd9aa2afbd092eca57a5683846eb5ca06d965aa7d61e792363681dfa36749730774918ed992f6b4f960d933ac090d0fe22cb26372ec0e31d3b4bee95cfee5c29e169c1827c7a9678c08616eb033c32727e07f6a459752fbf2bd8b97b09990a4ed3df320f470723270fe73bbae05a87959a6c39e94b972ee7eae3708460846516d9633ea53fc12b6fe6d350b682be1c8c93e928664a5d9cb2556ba52edbc6fd65b565670839be9f93a1af92dcddddddddddddddddddddddddfd5f58c9a449635fce4eea694d1c37be0fdec6cb1999af41e3e5e3b82a06a3fef4f27d9800448521445c75eb4a04151512827be79d8b3269aec2b7612887c070c8e7430bc23b08b405dc3211b8f2975b26029fccd16e0343780a6e2f02f85f412922fc05eb6be07d13a83d079abe034fa79898af51e3674099b761e33ff083bf017e8f03bcf113c4f129707e0eb07308efc3656e5339ec3f28959cc6e6105ecaa6086f5fe608672a1cf1f470bcb44b8121bccc384230c2a3944bdbe7f8711281f0e3bc9253360728330829104000e173a400428ecff11e662ef1f98384665fc2730543d3f8272db55260d3ab751b58730ef004ff1428955cc401ca1ba07ff63fb06f03f419d07d6440af013a903f71d17e0ce841a04701dde542a00fb968bf03bd097fb915d0612e5a0b7a16a729babe348d5cb57da6b7a39986b47e6fa61a1a714adddda9d322bf5df091fb92085a3220926aed524b60eba1e012944a760b93e4a2955fe73571b2b3a560eade0de491e3628cdc1105965fed731dd3c9a49cd43a3f128c5ee14983c7c8d6866cedb59e8381c13d0f71680cf732c9554a4badb37db3591193a9b559a1f9f40c524ab9c477a494d765fbbd57debf2ede1f5ebe2f1bfcda467c01a699cf01a9a467e8004fabe8fd2b99649fabef62143c7bf779a59a77399917aed034fe1d172fd987f4d2b5bd34c3b65dab3d09b2a2f96cb37abbbabbbbbbbb57a9c574940face00ac6656d1d1964fee10968551df297095af4c7df73725bdbf85713e070e83557f762fc852fdef08269585d33ac411e15dc2ebafc5ae5c72b08df577ee22aea9a567d7ee69d330026f86a6bc9489c2c25095f96defdb28b5cec0c4628f7cbed8cec46dcf470d34387f2bcd309851231bedf7d3937558eb8a9226537c7c90dc04c301e9860b3c33e31aac12fd8c391d684c1212c008ca4de62aef26dc9b4642bda9236a42dcc66b41d6dce0975ee9aabc65e16a7f12da6d51081e96fdbb66dd2b308b0cd374b388b965e7103681df99b7dbb34575cb8c5b67044e52d3657d68b4dda62bdc8fe1636697c8b5998bb62631b2d657f2e0abc116d587a8bb58efcbc64dfb8e46c5aa8fc61f3166e60c02de6a23f8d173c755a8701dbfbe7c8b0472fa055d5cb5b38d62859fa3cd9b972249ac6bf04d9bf4a769762dc622723579dbab8ea6eb12d6632559ffa5381dac60a2cc9cba153dd01c8feeef2267cb5b57c0950f6865109ca0ee4c16054aee4d185bca7ade4e164bb9f2467414f28df2ce102380e1ee0f1cb2e9764186f59d85ccd206965c95a6b6d6e0976163428cadcec245212102329b4922ca20ee632cbe4ac5933c828d967481ececf8e9f76f3051ee5926de2256cef6f7b5a8b81000de4d2bb19f986520bae911bb6842b6f60fd719a272e06d528ae98201a7cb2d397fe6a43ab4e482d361625c8fd74288333d93b41fe0e26f0789ad500e17133ca8e82f7a3db663c1965d736fbd44361bef65c6b9b918bcef9c625fb5329e9a5f43473d1a987c266349bb3a1142edc64e1464329db09e9843457a6b7ada3790d41ab6a00a96a04d1a2d780229babef5e8c371990ab2a0e2dcaf7af1144952c7fac0125fb9694fd6de4f1840425fbd75a6be5218f35924e48d9bf46d25c7d509ac6fffffb30ae31d43592b28703c8e307e58365ff5ed99df5b5e6bd187fadec47e419b2e7490af73ebcbd08388b0b776a606d4f5fb582d507ac3f3e82a454320dc74d36c1fbc950660c4086471757a05f3f02f33da421a4610a117f1ae6d330d5375adfe1f7e5662d9961d294262a80f202a19e18105a6eaedc5cb9b97273e5e6cacd959b2b37576eaedc5cb9b97273a505259686904ad09382a0ac819b8fa0945a5062c94bf6d3f3a5880f287846a6333703f6b08209188b93dd0c2867008b818b25033a97315832e04e6f118225f333e04e0d2f66603163d9d8a941ce58325f430844b066de06b85383f7704613ac29618d91c6d7789e1cf33ca8e7c9a7e7c9def3e4ee7932f73cd9f43c797b9e7c9f27dbe7c9daf3e4fa3c993e4fae610b438935f31c0ab0ff0cd8f908f269c4c8e609f43ace1425cfdface4f9162ca2a00c48bbdab011f60ca6e15507ae5b9092454ea72de032ab2fbd39ebd349bfd6494323f43d07f10f6b5fb391fa32557efb701a7ed2a50c63045cb74082a321a02117093d20982c259635450334cbf716acd5fa020b4e83c00cb6afe1ed7e5a3ae989527a9af629c8bdfcc1c9aebd13acac3fe98972940af9e7e67dcf4b00ae18d5b8b53f85e3f6d745cdc8f6dd778a09719fb8af6f7aeeaf7782f71ceda414ffeb5f9fd340fb0e12711acd6d38c4458d07f8cad0878bdac90793d0d413727f8e32597b0fccd17daf4374713e76d5164a79b37c9b8dc8af32d42ed5feb3a67daee12866196aae9decb0d0217fcc2cbfc1115ab543bc616fc49d2bcab0d34a33ecd890e77338e011e33c9f85b94a11b17fff863b6dc3d410fb3cac5b64ae7858468c913929b6cd7c4eb60c7f784ea279be0b45797e1157e1e859c91f925e7055cba210e5f93dc24ead2346905babd487abc62e02e2aa51cc33d5f44d70d5b592672ccb503e1131c66d53b303f6f062cfb21b1eb0e7fe5815af2a5c373ce099db4e1f2ee79c523b2242015a8043982248b62e6cce39430664d8b951057f9ee1bd28d09f4052f45180471c7c0293c3bfef86072c6f78c03777928bf2539f75d488d9e70c533f349cb6f1f7ecc37df80d1b3410b31b034eca218c86d841fe523f4c228644c82d23424683981091831a542528080dca120ac82d0bd262976419941d48c82d8312ebdb397143888d466e5911b310a698d36b1b7f2260d9cb2d33a24977113ac89fcc08275266842b7f2eca546e991144f973518232236410e343a769ad1cdf99ee6f17ecee77b793b2bbdd6f9dea7ed7c9ea9dd009917fdf878fdb731d785db4767bbbbd0fffbe2edcc2eb5e90fb32ec17524386e41b666018c2f17af58143d22fc3cdf2ed7b9eb90dd0d3b2a75e2073f5cd19e6ea7ebd3ff762fc7d5bb5328a05a5cfac3ff87eb57ef52b4feb9bab66d5ce224e4eae0dcb15c8a4a9ac1b6660e992412ed6f782c0f2471924879ec89ebc64417441e28723f99cf7dd3df71130bd17d2e0bd8906d477e17d2ea4a1fbfba690862944babf4f83e9f274ef3d91eebda7ef853b5368e8bd09f55dd8754fbfebfebe27d336da775df75d58030d3e7026cdfc147d1e160a4cd1100991ee51f7e3bc47f1b01e9f42ec2368dfbdf7238e07ba70c8a499f34768716f7a9087650279582fc1146696ad9d229366be299c33c0f0806671a36c99b8076590f409020af201bb37819e7c09d630893ce2128664a7fb2e945ed879ef7db3ba1fe5fc0e6cc96a4f86336da37db3c618b61ad222b2ea7789db3aaae37cf4471c1e4b3895820846e67fee3015244b198a4ff3f85987bfabe61652e4fa63bb14b91b968df453f7ae942ee05e8cbfef5f1467c3165087e8e64cdddb7597eed65dabddd46bb1ff7abbbbec3893778f70e771759359862814aa6ad7b30c4fa793e6597bb30c3d2ffb6bd5d4d96b157591e6d6e91144c9ed9d3acee49d382efbcbe7a6181ca577ce09e6f9d9c89c94522ae794f539da9586b4a911355a82454f006ec8a628409001050f4c808458020b1ca0d0c2a0a2c68c8c97e82229bc145df1822e3aa031d07870c585590e5a98002305e80a14d810104de0882c443f44f1812853dc2a34b832c3206a01b6b9b5384901137c736b7172827facc58994ac25293520294c03c058e235788063726b71028412f8945b8b939e2270aa56aba64505528089a208d7171ea051e61500182919028a15656c112233779a4bc86a2ed9a39337b5d6aa2d691bffad49d67ab29492d33acf3544e0da84d7a12a247bd4da5557db60c163956d5f65d548f3d1a27b6c699d1a46f6a0a1f681bed1d22acd8616fd5b1e6a37b4cdd45a5af07cbfffb1f0fc5ae7a6a04647f61bd9eb8f29570593dc7cb9efb6a15f61d361d9c3d1c1bee6f2ffee7bef2d73b7249b7ed45c1ee82ccd3557f762cde5a61f67a4f73c719d94ee276becb2dc2e787da2b828b921ec054629a59cbb908bad8129cc293e6839234b694dc100fdfa354cc1004d210599e9a3d039c4400af5ab04533845b8befc1645988c6b1d630d1890ab9cc668118d42612f9a25bb8b36a1c96478881005a241340a75513af3d122c610fcb58e4b693df99af7c3cb9fbcd12baf62a9601046eab23605ede5ff6490f23803bfbf8ce53ca475ecd00abdba256c5c64df7e6c19bc8e34da448ae9b76dfb9ecb32bd1005da803617f5a13d2e7a0d9bf60ca1409b6b13a240148802d58069de41518730fe54c8e13235b55699c74aa552691df936725fa103a53cbebb1b49af86b76d3ce31a140563ac6943459a0c75840292fae165dc5d4305835a14551f8e42a15028d4a3c42ef058674452f022cbaf1d53ea58134a5c24aeb49aab75ae4be6d294f86b3670a1e93794d69289a9b3b9ba17e33a73c0e93b14ea04b68b1e15fc79c4a8130a0814b85df434ad045a15cda5b950272018a34e60fd012b507d02561358a3b888da26e66216a4b60193e4a20ce5de4fcbee4a24b6972b8e4b49d334fe202ce1ee3ce3297814efcb8a288aa81ca618818915d59c7f4ee8e7eade278252daf70d50444e8ea6c9b42e5a6b9ad46477b78efc0640ee17c1eed15d3c573b0b6802ca10ac1a342118b0ee4f7141177c047f8e52da69dd3d651fc0111e71708e56adfd017a62a1e0ba852a805e3e2fd913495e603e806c2d135aa965ddc55621598daa91ac6182ce770f8513173c7e96262071a3eee1cf0013dcfed85cacfd6a02101f52e0f1c1b13a89926feb483a6be552bd542f2a18d5c86a30988f7bedcf932017371c9ca04b4fa55a152414cc320d65f09caa91c70e641a4eadc52ab3a6695f3b5b0b8edad7fab48646e8d36c84be0c7dece2e7a258051e51f3042ed81fd53af2270e3664d6e52ab746f6c836e16f856ccc76b12f4b743bae0a3c4aa2eccf7d3b60f93554f0edb82ef4442ee64bca826e50c1575b9a34fef762fc7daf2dfdcd122eb246ae2a41af646b47f6b7437696345734fec382a5a86291b25b97a624fdea5801d6945c74ef7958f7f444f09f5efb53b833450b89a0de0b77683cea7762b42d4cad703abdf7db1612f1be46b8d3bdf73bdc9f9e87459f06d8a20c70880a4fa117f6a4b921126d33030596990060a8b5b6860aa64040eae33dc059b4e70398005f70b3b40fa4c0a3a6942d50f6d7f10496da52cf5c591feb7a6b447be6aa5941403e990a65b7ae49e3456009735105772b645f3554b07c93c9ba800469da130b694f0d46eb4a9500dfef3c6a43d675b10e156029d3945c950a22ff6619e2048179accb457fb10b1ee72b48fbfb5a98d2e1e2e5bee3c2ba46fb7a3f72713687402993a10e2b5806f5ac28bf8ab29c6932d024945e694341ad23b52de00d0bc66e79b4aed1bab016cbae25bb36c4c5ceb2dbe087e71b5a24eb6a1b7f1106587a80c99537c8960f38730564c62a2d32573404d709a6507aac2bfb77afce8aabac7559976bb321db3c55064e9231d9922f294a9252ca2abb674584faa6b2bfd4d22b2dfb7de9454b2e791699ab796735496099c77b5bc7efbd354960c7315305a75670968c65291bc23847349149e09b455ac1e34b59ec35cb4358846c7ff36f2f35c4fbce4402104425d6629960982b1bee4c21727ffb1dfbdd7bb8b3fd7ddfd9e9c254fd49d34ba670e786a9154eef7daa86444e210d532891ae69d8def45c6a05fbf789d8b0befd66d190c816160953351cb2d54d5683c0e317699dea2af9b1b691609c02bd92588a8ab264212281041e35353266050c96b01712786c1896cfbd922c90342ebd18bd20fbbb20d636fed26128e2a2e704a640d3f87b21823146111a8bc5700db86e01074529ed5b0b1f956b641d14ae78424b699a88f3028f9a58971c4d76b7b33850b2b40e4cd5bfcfc3ea9e87c5b50fbf59c2a348845392830c8c58dcfb982b8ec8fd2edc11abb0ee0399ab7b939de59fe31f1698f36e1cd99ad65af5ba4d60cea409d2463542d833f53c1460f710e7457923087c6ae10d6c96067a6eef041c1d707db94ab3e2aa2a8aa2b5da0fd01354e5d17cfb028331213341134c0cdd60d63120436658424405a40e63d4f5e38a640fefc95e46124eebf837573813d724813fc823cebd17e7a35afb4b2f058b1464c4401fe523f38c33720cf48dc4d047b9befc18be8618e8a3d815c3288f6de4375f60a7b118903abb54dcbe970557f5bce0c2926c82a494fd6fb380e4480dadbc99befbee46abb6f6eedd3b81666e33853c5cc4c10177366aa1022c486002f70ba55a6b723340d3f8ff35326241e6202b5756659d93e30306194c20a1c1c46a8eacd7d61c51f0fcf1e79cab6b6ff8f35bc7c32ff09813cb929393a3c93423b86e61054a278039d1738220a4eeeeeeee1988f0c8c1e9dcdddddda7114769350a40d723ad4b5dd29a54a4aa94fd6957a32d2d0332697ce6fbbfb9b2f1fdcf2a9a9c8d4ce995f2658f2d7f36c04ac1bad436fe3360459a34b34953c7689a2411341b6a4880671eeb120dd05931a064d9a06003992bdc348e42e5b1633bf203365c318535f35ccd1158fe0cb863e367be8f6a40fd6004ab7d84b1c16437daa94176d1c39a62fa1a709cdc3003d614fbd54bcffc08e66ad43a60f6b7015630b2572fb2e370816dfccc8f45e6cc88082cb5a7a00c355b1be0ce14223131bf63e377a61091f9987027e6657e87c6d7f829a7e4d9b10156d971a76fd6cece1422367e26dc99791b610a7fb3766c7c0a03a1e4a74ee10a92e7e5a363810b53355c41ce30c1237dc61972db5ec8cc47669ee19105c8b000f6a47130ade35ff46af6acc4f03226114bc67944f64722b3d72cb367ae6c194de3ff011f1db2df1f228cc848e4388f30b26170fc8067586535f6041ec5ec3eff82154c4daa4693c69f0628632a128e16a6e110202eba37041ec5202d6f7080c76a6442328171d5ac46d5a86aa0ccb5fafcccb4504e2387d6ac080c3e4f62f07fa1f5d3491d669b15c9c9992bba75dc166e81c79ebd00c3f6feb2a7752619d9c3c8eee406f96b1857e5cc55e768b55babf61380256796b3dda206a8742d5586452b15d50000009000b3140000301008074462b1683c98679aa63e14800a85a2466e4c1d8bd32487711032c818020c01801002000010012222a30477a81c02289dc2c21340938b65c1c8513a0ab36633fdcd2eacd4ed8a14049942bc417836b9cb2ebefdae51d58aedc14fee08d04028b42f8920e247559246d425512767c73f9ab4ec0f1d6d0c9c112ccbc835cbe46818c7603ed2d60856c288a8cc91d0c754c07b7ec405dae1703e965760ffe64111cdde3577b21be48945f9f1208884ec84a20b1d242a902e6231cfafc0639481f3ea30e440f016f5ba80826fd01b4316289c0ab7ffeda3fa26de71cae6ebdac627ae980038343a7936f53a5f178780c2051fc2c77774668f86ecc2bdac394d8003379358804d4502f2d8cd47c325029df2c89bc7e2063c6d250e60292db7ebb3b41a752cb993c72e07f808bda210705a8059ef5375bbfd2d2250bf2662b07b526436ec668cae820d6603dc5fbd69d8e8b548cfa259cd15bc9712be3fdf91570234d6de2377fc56cb107acd55afe4cdafd79179898d9ec43bb1f5ca42f7dee5687750cb47b2cd3c68e878fdac94ac1dbfb1494155fe1f837bc1fc5914f53b6e16fb71f3268a1561c6c59609920cebb22b051efdb6a827076d83cfab7f173619118e192d5d3316f84d83ffe5fe9e99fa4bba3741f7b0f48fb9965dac39cc08b6b72653a1fd610d62442cb1b294719f3d4332b030fdd12eaf0c0308ecc2ce6fc8d24c5a3b7554ba95625b3583deeaef4653051c73fa9ce6145006445eac5ed31092cd88dca22528ed0ac96aa8fb18e1956054dfae8629bf8797057a37ba4d606eda92d14d2d088b4da1588d3e781b9bdccf4491702bf57934d767313874f415d38771453cc207f4d975ca62e4f7b7452487b8422f4267baacad9ccee75a3a956311bed3a6c6101c6895d75d6bbfec9bb075a32ebcb6980cac33c02d9cdf2f3362f62f55e75074e523fd7609a77749483b2f99a352ddcbbea4f7fc1e2e3f983921677d17eaceff09a2f79376e9c3635c180020f7e937c67526e8477ad491b6f0a85e36abec7c8981760e7c4988b184713ba3e3c63e2a9d806b9f761d53c7dd12930ac0b3e6885c172f971231bbe823b9684d3ab183bea5c07f31c7f43bae1bd1a2e65e8d9ec47fd1ef25e2c5eeaa359cb46dcd81ca85e312cb11b1e88262cbd19e637b6e29801b4c9ddff035b27116350aa5e88a0dcb5d657c0aef59f04a7d4068afc6f718d469b022e3b3696508398274c17be9370f4dc24dbfc173e8cf2e643af888ee20bbf694977e7a094db64b3f060216b083bba5dec948844ca98e40fb2ec70ccd8a6ee761a40744efabaf0590c875d9330b031a16589f54ac974b10491b6d0ac6cb07e386c0d925b52521dc9bdd458cc3f2780ab56792983b98213ceb4ad8d8feeee7cf2a1c161d6ceb155b948cbbf69ae2973953df9cb71c4513e84739446e934d225781b2ca4a84468a0f5fc2f042a7af4c3795e2309be58d710df69bc17df3ff6b6ba0f0d176c40a1db2319ba09b4c0cb4c34585c454b96a53291357802c487707f9373db26498d598698b998e4b98459e5c3578ace592301290e411823e0b3ba4e5dd37c192ac447ad8aec7534ffcab8926554b15d71f076fcd38e6b0e28ef468ff9706ba0ab0cf16af4dfd4a431eebf37c9959da5ac69b140594678021641d2e86c00ca406f608f57314b98646f8f65a71b1bf9e1cb60a588f627ca5c5698dc212f118879629698d1a702b8bb823e16300b30d8fd3e587fe207c127b8e10519f8849a51daf6bcee26bef4741517c0075fe39a5b479855fcd251d6b2ef6f0b4c8f367edc4ec260e1907430b5c91fd424b2b3de536e61c7c7b6e2c9f9328f06cd93105ef50200624e3ed2353b69de34ea89d4d4996a77a85174c6afa46e085ba3d8662408ad717cd19812f35e2bcf1d2148cd39ad53c1e573c0af8b65d3ad4d32af4acc51242ffeca5c35c53a4bfbe1832d92709004094182b090ee02b3b95ea8be22a28c824147cb6088cba3cc6d5c9d665b6a6d50d980866067b25c08c70fc2bc8b0acf660ad62e01c3dd328bd365a4529286d10e4795b20a0f72301f1d4129ad2de1580fc9be08b93cbcc8663dd14d6e8fdce93fad0d794eb019522b559306bd873d53283246a3ec594a6a50c62179bda52930ba537d834ca2df7f5a93789b80f5438553b68959e638c72c821843665959c5fe375dc2fa698c8831c8a94e66297679bc97932827a76bdc22e053303be19161a2468ef45c950a984eabdd87d74e975fa79d7bd53616082e05247c46ff8a8f81a8bb4d6fbd79d742a2cec02ea3270e2e3a169143b275887a61b12b0f88c857c2e71ec8c8a5d2c2253339bcd6c9481fa4613646e4a304f24838d1f91beffd1448ac58d00594fbaf24f9501e59b5a5b877b0cce5e567b13c46fd21b2f687b9b34678e081102751d7abb81c781f463e60c03885092946880e2f3ea7c60f440a997296b0fd30a79e7c9da912087f1ab330c92a479ab920c5ce3df35169108e4e810fd680804b9160f64d5d43a9555928640efb44c4e4b166a2f329cbcd11930593f0e4416dae72a7ac3c04f2c8d5c75904906abcf5d99a158ca82bab9298260c381e9a54d239f97f2b1fcc93cd404c35f74167cc06f277a48aa99997c4b6b2632093546ffaece213492408f28b3ad3a0072d443d4adde8e491aa4a591278c17fba36b12ef39dba8d333ea62af41e7a8cbeb78c9eeca1d5253706f3e0d404ec1b917fc8d6605789d4fbf1046bd5646a601e1204d5d19e8963dc04a8bc62b0a055268da983945005cdad4bdb123ca2891d60e84de085392d6b8e81a43261bdab170e21a1c3b71d277d2a2a4deb9cc68903ff24b7e1f2300e091325e5f27244ca719c47aa0131b5ca51517fbde1dee3ca31f3e5e68a5c1af03198693271d4881aeddec7d588eecf6520a79b1fa42c3bba5efe8966c52842bbec5e3be9a0156c8860e70c72d0b0fff3aa5c89049c88deb9f2429b608497668015bc6e018008fe2901daaeb651e0953c9a6bb21a9db9d114b865afb6399501f90ee885772f829cc1e3b257044e26950932166c994155e3876ea1e9e066c3cb4446786261698370df3b6eaf40b1f23fb04b3ba906726cfee1c0dcd12a94d2eb8f3477709b5391598bbacbff24f1db5f192b1e1c26a705cebc317709a6a3e83931826cd15d33f6daa70fed407e9bc450e30580117dc27f9ef66c1610bc879753119f49ffed43e501498bbe3179372dacb73b6e560663aecd84fc1b9614a7ae62d95e230e05b8e118658ce53449cbbadf7820e08520e82fa7338ba036509853342dcc6ae49ada822673dad5edadbef0d2ceb671f1e3856fd641cb3f8481acbd147743d97131f10af14c7729713715171ede75886037933f7de6560814448bd7b16ea53c1dc7bc01a5c6cfe80a9c9673656d0c106da6f36319436d339af17168f883a47238168d9dd1219301e5fd54c5b257b9c98fc20c61467a51f0f0592ed03ae857c7fcef7aef7ea57efc5b56fe6ac211c282bea9edc07c3c0560d6daab3e2b8d4707ce5907234de7b041b11f2fe45e1d25d304a233f2971f0a35c7d5f108961acc09eba64b740e4833d34c5065b84dd71545213bb1fe6c541dacc70f5022d06b6b12e0c4f9b5f7b21242b38813f355042a6b4a6a91f59d6f94f8a4f31561646522fbffcbf599b9f6a44c38d5315b84ce9cc6ed5e729b37dec39800b4bb89476a87e3e3b4587258107081e0473511a3665cf97c6cebdb761ea803a44940428f68b90ad3b2491132a8519281eda997c63751369db05309ee792335222df662feff5014edde5b018c02b19649c038331f6802a267c73df309251d87b901fe03e446b3a642156791a0684b42dc0826280eafbb4c280be12717c1c8344491f394e2e85111e666c86a815536c9eb9a7c45c5082a1abae5a69046724cb74f3533ab71434d682648e390a99022424c8af05c13612c7a613d812e9851295f6d2b93a073e9fc0bf224f053e888f510a8a51c4b1e1764da09fc63bcfbefbe45fe6839e7b1227b25a12b6a2ac94fb4b59fbd9b61d9c6af1e952265d1b3d9f45b6bd3e041c4e195c9295591444c6c88001afb8db547fd07e46fb70d0e6c3c290d628f3def35529515e0d4d0035508a08d2eb057aa61e497aa868f0ed26e2f71f37c15f5c6eb08ff70cf2a6db0b8f467ba402755d757b86385a0245c1683273ee75d7c675a3666da51a52879e581a3e067b48148b3ec1880852995e7e0ff8ffc9f4c0e4ded58b0a846ee57c0af6c4b6bdef33b629c7fc310ddb286825544f07c44f4e2bab4ce4aed7703314d2380f6a340a877213a51a7d0d6f72f416107797f07c981054ff33a0ea7320b210f9cbc0647aecff2542977873f44cad258e7709fcc05c1264a94bbe48a77e066a00355c5ecd27ea7449361c1460862b708214309068da836afd61ac811b7e1e1be2e3447cef4f35b41103144440c6dcd30094c0dabd61b863b4aae7a4d25a5aab0806f40798aada7bad09ff7b4a3b015214c72c4802849c01c6bab3ff303a97505dcb4101f19bf7db83b7770f319a171a4f58c597e9167f03bbb8604d370b32a36f12af8d2b8d13e53fcc98fd7fcdb02a98a5f6451b39e0dd2035dabf0eccbc03d660aa1e8ac085e5f2014dfa14d94bbb2c2339c15fd25130cd633893d6975b0cfb4ef32b95e2c57be0af4b9bea5960cf81882dd1d2a6a8d1b2b6962f5cc9541d3c6715b501c6401082278742fe106e468d96e7fcae039c778fe6553f52e3c54cdd9a0daa504ee170550caa53e9defd1b640268d822b891f048a4acd57aa13264b137d92f487e711c57e45a286304d2fc155a17e36cd9ec22b98364a27b2ae1a88d0a786b376ccb4cff14e0ae280a2c55e7232b74294f896db7a8b1fd15839f1a46458ced836ef8fafc90abc47ff571b9b92f68b80a2cc3905b13ceaa5fa17ce0d86cb33bdde1aa336db9e36b8c86f735f5574347c3a4c75f86b24520dce5b9c2df9f3b56bea99ad2bb8449aae782b025947f52548eabc02f0010fd69c23eac8302057d8f217f6d3942dfb81713f0fb70e93ca1517692e421230562e02c2c32d932ed7007a0046757d070ee50168d0e4af096e1d01ff9f2939d3eead6d84bdbecda5d37ca1b1c76c2e7388521f1801e1dd6985b876e99592398686b0fba22dad5078f4dfe00ede07e4a0c58d1cc3b82c9f41234a70d1f9a957053c1eabd0af06ec8fa0848f17582feb3737ad27f8a7593421ee9d0bb2aede4bb603c138107407f8b458fd1d0a503718d6d3559c59c77ec224df53fa7e9bd512640df750c583b6a73b77b8efe088ecc1ed064aa8c5db0a445f010c20d42bd0f544d712e550112e99640e2d697d6299c1943163e3276ff27c878c89768fec34e96863092e3ed797fdd5977fea236003fd52848c211242c71f2fac1542c0f49e980e30f1fe74d4576d627a7aab4edd333b5b45c56943fb69f8c277f52cfa351ee1702cc7549f1d21b0df2a283dcaffa2f3aa69645499a76c036ab51c35024ae839f848c927e91c0d9f67f1f0c77c1b9986619fc52d8a6c9812d7430c5a0bd3163383f48ba9c79969a29581a7e60c658d5a32a3b34c9ec4224cf6cc28346ea420234920a5e064a628e9f67ae25825e2ee304f0c6ff818324c2c1e274072b8948a843262c2efa6a1a9a1ffaed2b119af8f1dfafb700853ae3ab9e54fbab2ff79e0707e8a0a72deca34570b0a7f7a38e16022785a24aaa6ccf99dfb25f28b5bdf6489c79c2c413fb805818124d5382cca1cce2be47a6deb13ec947a382b2ad18e08a6544efb1132c309d239ab73618ce7862e73de06d8ff1af02603f700f216f5267e6eeb6df670ed5d2a4f86a5defd053932078c8bb2f278080b8128a01c7dd0136cd26433e26d19e5cfdfb984ad26ba6bdf0f14e13128ba53b6ac54d94e2e0a67386158962b21270fa4a4574567482eca61a6215803dcf4b8605a0b3ee36436e09b563f5bb65f3578828540fedc837cacc354315078199e7869d214fa66e32b25476fcd7aa667195186b2602ad6c5b807c1fcd6ca3ea16a9991f9fb0b429a01f6b5f2e2d42ea8441c384c82e08fd3a271fab6471e9b0a04a6bd969fe7222cb1a2f512cac4a7a1eea9e594c2f94642ea06c7c4c17d10e44d82d4a66fa6bb39e5c5d1c9335d55d60c115d398e91f6c8f149510014cdf6c5d2da8169eadfd6fd15e72ae902769e9d3d7218fc3a7e47ea85f6792d0965a8b17f784e24df7b3d501c99186e1063a14df7561f9eb3813d14ca21a07714e32915347d635e6d7c34bdaf2bbd604e3eec5b431b06c6969cffa5d00fad51ca3c6240d3ad97d3fd8db09ee466d1d809768b98bda39377f0131887c9d439cf196408f5066cd0329fd822a19c16432e2222ae144b76e33d0335082c147566966e5c4e8d62d08e760dbc8808665ad275f9ff2042ca21bde98cb4f815f9c0f644b8219cb9bdf6e2ae6811805a548e65644025885773aa783a861ab7ec761cd112051d1a68c0bcf9aba5b908fc947d64151baad001a72e7c39078272d8b6ab0ef2c8d0309e56ec101fc4db0a25b67bb0f57a9c6515a0f8679dcbf30e25c6f48e0c0c9f6bc9c7f04e5b764609396a1677d5847a422f1dcc6214f72a45d2d10726744e568cbe44a8713ac12df123f4fbca2fd62a781a9e5c941fb42857db45955ea3ed7bf739b408d97271d23fc462e15d73aa73231b382b339cf838606df8dd3662a067d5dc011fc2da95f4dedecfe06b5c0c48cad1d5c8a804b37969b979e6d6d3b847dc8573bb43ad67c1d9848a8e2f1362b9635d7a945e91bdf5eb3c0e88cf794367969da579099a13cde543ab3dc7e0667d1dd05570fcea0906efbe6af40446e2a19011063cfec211ff67e66957b13fcc45818572263006bb6fee47e1e24b418bf7be446a28a8c9e85c1659bb3590719f24d574ac3a02604f214d03fcb828856deb051b980c7dfab1d31d52aeb33b3b002f5ab0f2f68fff746093ce2187734d70a81629358628551d9dc99c323670c17f6656201ec8a8343f072d4d5a58253622fc7d61625bce644912aefcd56d1e0683cb9f5992e907fc0b836d41a78a8d37cb708510a4d11026db6815991d7416f172bdefe88f231485c2f58cacda2324d9e8d3a6a508849688b8f5d6ac6f449aa397c13e63cff40732d61b9397f0ac2ee030705c26b6ac5b27c707c059b3c1d2b934f4aa61cae8306e788015cc6a908561436aa58615330d2e07c0573e3d9f5470fbcd879322114f1fdf21fcaaf258b4800f02f8cedfe3a4fe3be2a95fb6b3ffe60617f89779e1660abcd171c0bf1e019341655bcebc7959d266af11a03045ec871a29debec967ccf23dbb2a3491bdc436fb358b334dd1deefd349bcd028e696a5b9d2a894f134205da346784b9fcb0a881442cc51e4d06b01d92ce1cfa57d106ceaf877b84d8f713b7caa0eb0e273ef755c36789c0d10e2a42d419c807941c74cafecfae17c6675df1ce1cf3569e954eb1cc9cbcc45d3bea49c8b0586157748d04e8c6c138f82465b4a733885bf1e81a8d35fd58ba8ccd1e68d0e6ce65cb55de00892ac14efadd415b50564c9f2e1268667abcf5cfd582e9e4ce923dac1a16854ee2dbada72da3a2440bc494158eecbd52aa57aa573995b2a3013c13b40742e051055dbe48c2e0ede899b7c402e59013dcf1c7001baaf2e6904ccedb063d9e7fba096701459f8326089eead8b9c3943dffa008b624b691f2eb360ab7bfa9eaf3e9a3f7fed8ed592a1be6d0c0034a10149c4416ea066b787e91f7e80235d25b3ef3967b60b584c67933b858c999c98c9a1fc30dcec7f846c3d36346e3b7caacc18677419c19613a076d5331b2f3130a9f4d2aff612e904571e042743ed964fef1ed8cad3c13380601f69d1da3d32d33f10430f34999896a343b40caac604213d18025b31f5ab68d35a980b72f226593f85bf466c9fae612f0d8c0bcceebe1d14a780946ebe7115d04e3a0018c456ef8c9f9e99fbae35fe71884e3425cb7c83bfb004f42843c484a52e892e2694428d4c1c57d3f6ca6e329ce6a62a03ecc46c72bc7269b7a39549bc2e8281fa677eeb0a3608437f6a071c3869837d85899b86c0a89f69c19ee02f45bbac0e5a6f644c81529776900b610b078e8621198087a42008d3afcbf35a6de13b56b7677bcfc42e9ee5895568db84744229cbc01fc2e84144cf7eb71ce36a7d458946b003b1f19824e841beaaf35581070c0a106395782b711469abb3c166a94a63ec3654ed673723a1bf3d406e53df787392985f4ee1ed5966611e0ca3c4d59029a6222f3977f8b3c30475a51fe7fc4245d5ba057f379bcbbf709d7f3e7cb116ea722669abee0b822dfedd05c6552b265a7a2a6f57e9e97797e4727adcc54d0a8bf90d1ced33476020441e2eeb1e2ddba413d1e7b526a0563bc04792a7de82755f6f9bffed1a9966f465701988134189ffe13e6fc58daed97205e23015a3f0218638eb824d7fc0a020b05ad63fb418dff931b0f156003d45b386291d1cdb60ef4b3d2d000bdd0609741bee945925508499b894ba6a6418804774966a1f03494a0f7ec9e1edf1d21865d2f25d3d1d841bfc66bac5d568cf5c8b411e87309de56be08fade1fff95f41f98d78798e3b5728db5617dba7f7378ffb1e053c5929e192e9a5ab703b482a26908aa76b1e4b159f64e8dddcbfd43773fe3d52d4732aa50768070d16966276ea1b95a4eb49e6a1169af5aeb9c1f6d9a5dd97e787f7ae3a5aa83bb97de5de643f6af3493bd0f89e01aff995e4c2a98c8c9a6dffd138a31945618caa5d20107426eb8e3c2c2ad331dd81af212790e7a2f4a2f90ae01752592457872387b702d0593c38b531bf0eae6cd72af1cc6f4befbaebc86e0cc0b0d4aef148f6cbf93df0a7e53fdb6f190a2e9b69f08fb8251f99a5894cfb22dbf8be6511104dc16b44e953bf384210cc0be85a2c74ffaf03c988dcefcaf943265425940d6e722dd235c8543bffee0ac3b09b59241f5e0be019253dee8099350ed93550407f9fea247046b70d748df5da8d6f6c0ca8838584d7a5e885c890049d08ac95df13b2087e7ff0c0f19c13c2c42cce4b0e5ed3229471562809a63a2c0099e48d62532a69b2c0d34b8d748f1477c3a321ca2accad291e07227378160fda0624bbbd48f97411ec49a107aad88d159abfac1880615c365905edd26529ac89dd50b744d5767abb254808be809adb66f38472876f4a060c563f0d4603dd882405cd5ae4e7d0611f737817b8c83874ab6c5177e641b149d61700bf1859b5825d7bb320177d2d8f36fad8e287b3f66189ec006d0fe19b59d3d7a945d1680e423556eb490becc354643be52aac3a5a88c202632f5cc1fd00661289438a6bcbc58842daf60b837f3901a86caa61f5af5be7ae6b8db5ecadd40787cf66d1d2a45523f01a3c2af085dbb2a3f9dd97a93329ac5bcea595b75fd9b4ddf75de9816f311d99cd166db42246afdd29c7f77c3e3d0d1dc0e91fd76cce51fbe499b4a933c21e882b32765e8ffc87158a277138eca73a213d1820f5ac7b7264696c06cd941ceeba21bbb547c7ddd8e3c313d396403a650c4d17b3853e6befbf61d79aecbfe7720692e75daa67ca7daedea95d96ecdf16ad351c7d37e04e36b893ea40a35dbbf08217acb2aa831d4a1658fa8652414b5059c6223df8c0f0f3bf650f91d3d73268101e0fcfbed7292a40a80b13768c14952443538944a70888b6d085e08c2b68991c8f0ef2091c815bc9b055d17880489912e41176415106a41cec9b8332537b9f4223f7b9ad8a937c4cedba8c6a9318cae7b5a1cc0ed6f06385d51750e78f2c7a9f8afd944b14d63aec3d9177f9e28028562e09a31551d2386b5e782861951280814984bb0549a2285e89558d844764317531495b261a2684f77a717a01a7b8048974546c4d1cabacca30a7bb27961ad977dd46a713da3f969b54ae75e6832b1a5590ad32e52c6ad2d6a8613d8c6d8c35f33f3df66389741f2db4cecf50c121173f084e651ebdd5679dc06b2c69000d7b183fe26439e117804b289ff081a37306690beb955ddcb6c6547cc3b4fbc790d152c07408767bb8cc0ca65ee1f74cf33bea57b9ed0c42bf13753408efdd6be2a5f3ab08ac3119751889fa0f77ca7a4898d5d84c928984c24bb95ca05b8a0cfc8392ace8875ea343b903e99716dc9ceb6bc036550988581828a2272adc6a1cc3562dff671f7b3fb8754ce818439e61eeac9d3b7ee85b9c616656b03cd08c87812ca0c4b0dcd0a14bad61dcbc27e157d015a1443f2970e0bdf2189bb2c0a8b95b8807544b5976770d42fa306b1efddd238fe4e92f80c1d234a7aa9fafcab0d31cbcca5cd08f89dbf29d336d77e9fe7d20b4a69ce3ab1aa5c0f1f49d408d328157ac0811881937c46e45641ee18e62e1d9a47507d7dc382408237a2866d601adfe75e9806565e98f9bc8b9e0aac97044c448035441ececd2315787107b8536aa4cbdb3156b080c1efe3731b02a6420739480a8463a9eb0d041399d40d3751f6ea40c484700c5635da2cfdac77a792d31f1f45036e198284e787125c17c720c557fd97fb26d015270b95a593e7e3b4d97cfece714a90e3ceb01b1f856fda6df419cf9070c1e62ad3a7d4bbf4cecd50f0ad531519a6ba21dc3cad65575ed6881b66a2ebc90261c82eb72e031b430b6fbdc9636cea7a4f500cbfd760c1d11b6af7850a9a3fa2c5c71979325bcb4e390e2dca889126c20ad508652c851f83fd4927acc365bdb5850080fd57ae1d4395b63cc69584f5faeeadd5b1c1049159a03b1636166422acd6b7c5588cb1cb4491f16eba5709270ac7dc7961c92105bbc183ebe9feab7833f6856208dfa22ab8bcd2309932f9f3b542558e7fc65703435136766d63893e34036b083be5c1e87f65b6eb3d8488579540af29f4c798d7e4af71109a41b1a097203491931283dd81b881b569702d809ef13066fd8cd9936d96bbedffc242b8f1f190f51a3ba205c1fdf670877d39b1ba50438536fc66d44b9fc98aa8f342991b959079caecec1f8521d97f2a2acc6bec08697842dba4f2c4554091d6c4a3b332ee042c8971020fce78f52680b1db09a971a780a9869a6ebb639d9f5f2fa4443e6a0e424320ba338436734930723e8051728a69c4aa530e4f6cedcda806e906a9e4597a33a34f9a988fa082fa807629b4a6f2535ccac5a5b0d560ec05344c75563ba7739325771c910ce3391ca6fa10a90524976a9a68c598cc94dfbc217550bfd3d45dac34b2920655217a42f66ba12c8e9cdc3402aef7ded87f744a8cbdd24d5699c5d346a42900e4196434b292a3787d6ae0897f75b9c1e1dd11054a515e68064831d0f389e2b2b8755219563f1e24a284a4d939cc704f34f5dd1af86d9a8d3ef52f8f22c38879070ff9252c7eae8c40f68b6aec61176226590a626e27c57e8f211de83d5c8e12bb6e57e8ddf81647571729b15577c1552940113741993ff32b880a9c50495f54109ab1125fbb7774e5a9d675e91fca57db6a2590e90b5a0036d9e129a33e7121509806b6bf9ccabe2c358ae714dd43b1e122ae2b6aefbced5390bed58f8ea18bef081386f68e85d55081c0c8b1ac81bafa9352097d5b1abfe6c04b9bc81a33c66b7b78b43d5307938447fb9553105f9ee29149b5ed534afd558ed51ddbb02cc6bd3decbd996b465ae2106ff5ed33547c4dc8b553b42ccbe3d86f41d988a73b2ab25bce244e59d45cc47938e7131134b08568aac6e2b6064d2ff2eb4330be5c20431c934c1f0a34a12ad5c3096cc42ab3c9a8ac03539246c28c50c7db7535935f2b0f20fcf4d327126290a289bc0cd0d33eaa7dba05aa86cb81884fa8fdf8a28dd250782434a23855e97a35474020d349a36774ae7e4f5d9e50ac4316978186e1a8a26c514eefa6405d30356ca514c91e98b67021850ecd645522e514ed15db612284b8587306c589d50866bb31dde524fd118154f5c49d6443ea08b21897d8d09301cef498618b078f39ae6c6fb580e6b88e404d851e57bcf9b97ee2e34a8c00c895f495de100e26337d5a92895ea729668f01c60cd2eb44ae048b0224576c12c1e5a863524ed53e9bd8e7240a55efc5faf0ce98cb855edcf27ce375f1970ee777929a9f27c35d8057c0a9dc89afe654f7aba951f1cb4ab805eb82d0ec1094a5b0864f411b0a987955e0325e2ac9480c212da8ed7cf899f32a155e284d3966c7a82499c1736619c4fde1a8c1b38112f872020cb282d637ad328624cdf56e2cb052c57fa4711674b12323a34c2fd816e9fcc819a41519ef755e87af0ec481cec63730dc8be3842f60caa9b046bef4157ccb2dff1c36185b464821ea266afa38721eaf4c0395b1c252ccc30270ce5e75b36237494b31492b5041e0f9089bb0ed49412797539f28c5dd4ea5c7694dc0027069d05ad3ffc450aa148f7849d62abd32170536ed0ace24d1baec1c34ba58827e959c64df2c7cc4d9b21c7e27a9175ce07664475a5a4d8895a2b5a422608f20b2f2d36db78f254bf02b479d207deec039f963f7716609f25eab97ed914358d07cb90192c30437e4b0d2f22407a766faf256011a944f35355d4a78086b35785e466cf16191852e587ba70103ea48a8096dd138d34a1cb6e96912db1c84e223e2948e69701ff0ec2c0b632541dbf0f14603f44127aeea05b84ef1a3d9e791deec4b587dee064cefbe532d82d1a409f33d218742a1bf75ab5df32512ce076bd399c216573e4465f2a815986fe42c755ba398d15317e9aef989ee65ca0d8bb5bea41ff88fb690632d6abfd8869a1237d4c8504e16b05655719fb414045c99754383038b926f02d840807a41a5373bcdb3958014c9b6395457fa203ac1482ee2d826fc5f9685aa135e087e8d57c7de749fefcf2070ca9a6d8da057df11dc65fa18bccf0ea908bbc4b0ee75c63c1af54814a07812bce6d8920be8050f1a543c6ef50c27fa68756f3fed970c2a6be397f87a08bc0a42ef564754af6f7dfe250613cbe444d3631c65819edb75c10f402bdbc91aa2d1e1a6ef3a834292c9455f650968c1e2af68718ff31c2e60b3e27c35c997fbfd89fcb04afb6562ab9199abb7f0b11b5a11a5b322ca083edb682fd4d5cf2ce9671c0bfad1751b0951bd6be2f2655fb1525c9cf2c973c254af2d9a5438a9076057540a6dda45932c3b383a17382658cc54a3cf911d179fd7c18adc092ca5dbfdff30268712af7a232b611a73c2178bbbe9bd305c1c0db107638d7bbaec0f0c537277164dc254fc0e7ca01b986ce011919cfb744e094c6de61f1ca8019c30e41ba8afe07a34c3c848114bafd89ab9b5b408097a8255f6cf32b9d2bc4e82312a1005145b0550ee08a27ca456bb933d88e9e31e6b7481d19f5b515d7ca916930b705db0d142056ceb9b6a61ecdb0ab770aa705f9fd1fc01ab936b210c045a8cd581151b94a05c00955f67219f96d24a21a5cf867a325c80fc6a3c522d12ddd417df57464c6929999e8ae71de8a4d73ff7464acaf94a34462cdc3235b67de0fa1659c6f97c943cfa04349c5f01cca4242d2b88206d087df0d484da0c66a6158f411cda80957925b2a02212f274a92cd1297b563f1606ef05d171f572ad3b21fdc4e68aaf2b0fd146655dec7cb4b6c73b2fe9a0d40364584c26c9f146108d526142caec7f9a8229aa42a246995f17bd30ab6130464719513ef7c0d38371d140bc2b75f6de7a2b176efaa1faca6208adb3adccebd1703da5666af23390216aeecf0b451f5845de51db600781a5a62523912d903e55bc36b0e10445664187f0833f6b45044ac3535dfd553342f49a4e31751413e58e9b205583365a2bb34453c2f0d70f9f844389786474d7c90e5f0220b48783198eb4748958460f97d45e5ed55500d99c3a214e5f985ad429c9681407c60606a536c802b83021ab380c50e68a61a2a6f6aa646e96948700072755041394c5cd41398f7550aaaeb2169edb934782f9531084fd93556e81b41f2e5ea4c31600a8e0c49c3a899541961e646640a2ca7aa79d2ccd2f13015ce3923e0f1749c6200f6ea28285e779aa77932b9f2e1964c22f66bf81cea3f68f138ab058a056e056dafdac2d87ad4f0daf33acf0b7ea02a90250c572485c3ef050ad8c2ec60ee1d32b56db80b896711bd2ee0db08a8e8260282efdd042e9a8505b6560da57f89d0693411006b8b773bd43ae11b12f750b7ecfbeef782e50a59c9401966ce035650ef9c0e2f858dd33cd344ce1e226733ea63afa949d871292049ace2c59abc1fb0ca58d5a3ce66d4299eb689172c89b28043652d680a0beaa516cbba864c7de0954008e358b7cb0f099124ff6af14c0f515cb8fcd0eb919fcc40d0054648c0c0ccdf324db24015b70063b3979b2fccd2ad9e32ea8b2af0936c21e5d44c7a164e7440ef5e03f2412eec5218ae1a269b74b8ef99cb8dcc75e4235a1442368caa86bcb0b1cfdba3932258e5ac4e8457c7de5d727c6596786d5a0bb8dbd45fec6c3b06023c3ebc1bcdc6ccb667250a9af030097a7c389debc45cb7f6e6a7970ae39be3b60df6cfcc79308d2c0209fb78936f79f9d7280562640170d62073d3fbff81ccdf18501ef0b89bf12bb9a1f6e70a05e4cc05a08900ce3d1583cbf821f03e0dd37236d5c9bf2977fdff17eb1e1447b1558e24e42480e668d8ae03b0ee4c335cb65fbb102d506af29a915cfa694c33b9b187254e520eccbab3768c771bb5f6a8f3a730209f53d5cbc91b9bf803574f0694740a148c1847a54c7b0a8d1352a645e11f22034561ba5aab7903c26e22d99fb0510916f232c62e9b3fbff444d3cf36e4901660e0647d14404ceed354d7ad48d4df57aa4229afe8342bf512440057fa304a1c695c4eb16017f94184225daef07b9771433f6fa5bcb48d82e5ad899dc6a1d39dd4a0732f4503a61240dc6dab69663ecbe6a8ad12ce0996947fd25a5e5a42673a2a36525b1cde6dcf4756b638cb6cf2e2b8aef1fa71ca33c410926f0f2071185e6642e7970353f0257d91cb16d546dfdcbe7de680b4e5a92fda68c6fda8a785211e905dc80fc7612e83d0d6215406ffd25e5f242bf25b202be96e05f728fdde40d32b4dd91fce291c50e6d0311fe45130851010f9a6220d8235605168c98f0b55e080c4dbc314e3b78ebed0ed029d375506ae0296ab4c95d6c1ab366bf05d305def6953efd40a3284fe692632745247095cd62db28b7296744c24912bb395afeb9edfca043cd71b0808eec10644423e9b3fad08aec6029ac13d00ea90a7ea493e06e234b0941b502baa6c6e256ebe24487debf14c61971a46fe7fdf61305dce3e019c7a7d975ddfed913b75a8a145aa5aa1c3d318dfe837035e84faafe53dd68858289b9661156add0648b45a2784a474094c818e19821ffc9f3d459953fb9364d548a005c656c771cab979da89a27c717374a92f7d5aa72628ce813f9db783cd9f81a4a6e6e74bab281d12e24f48b0d5bfa3a65aa483823dddfa95891cf49caab1252b253066e808904d53ce752a215ecd92583f246469a72cf3f9a680a4b72cac0491092b06eaef6e87019519550f1ecfaf239467af62ac1fd528271bb4b912534a3db5669b93cd0592b7979ddd317187f3c28351688bdcdca904335982c557ab714fe7860602f7882cc8e095728ebbd556be9555d5e5f0a07233fb4a5170136f58744998f61a2f9d506e5e7720e86e17123c5e37e8c5312a0e7d8f643377d2dfa736722387abfb7f92f32f448eb99f8722075dfa3f14437f51c07ae9caa66b9aa43f494072fa785ec95827b3a7b2e64e47b3ea5d9ee1f899b53810f1f3d0e1ed4075dcca1c668cc093181d892369c3a38e4aae2a304e1e3a159836b062c213000f701c964dec9fcb6327d031ccd0a16c8c59ce3c67114a2be6e03bc438f81886af8afbe9fb8137278958738200c667a240adb8bf720d4e776ab523942c4882dd576654ce816e16441134d213eb5a04789f8fcbd5bd4829b91bf0b222e15d5db9d047d69d551a4a8685837da044ea0f05b1952d8f8b0a2b3aac6a95cc2f857b843d110cfcd91394d8f17995da66e94b3cbc4b084e42053229fc4a7f375935bd499bf110a4c8400fbf1317617ba1c946825943ddde66f340032549fdf12074b134ea82b4565d23ac743feade49c9628544bde2779e59cc1ac27259f6e7b485d757876965a930113dac77ea3eb41b7d38fe82786c4688b8ea64fafbacfad97d912d7756d50638f0d277317a50235d2cde6ebabb4b8e73ff61ab9581632a57064b6a93a8834cf488ba1d0b4c1ca5e996980f87b8e489914338da064b7299a106bce888badd8a985206399d08298bb64249d621faaf2ff3509e5838d19d813ee7f63d0620eac9afb0f0fb482178f640da3e6602d185893a7649a2a64f7eda434f8ac76f6e56860ea43094989a34f69a0c3eeda01c1814f35123db05c88d6d427b70c0adefd084f10959df9e7241a35c9b1bba2349fca2be4c58add76721b24b0d3972a88d61715974ac4e0a0533708c72e0612d4e56ac4931b9ec640191d1e9bb780effa2a78be6b5f8e367ffa674e2c3a1be4ce7dfeddb2a33470fe1c8448cee7ba9d67aff9b784dc91dd44fd2cbd9a09139cdfa0ffce18e521aca3ca0e56576d472214a30d6d7f0d94cd366d66fa2ba269a024e28f908d86694db4704049ff0d1055a831a24260ac8ea98839d59961ff8939803d824c1136b9050a5b92a3796188429fc65109c7292a023748989f043b2abfd137c68d50d027b1ad0ac56e053fe8ed550c6e57c7a7f9a7a165c41e9d7efcda8e2ae8103bcaf73359a2baa8267969d30146067172b3497d09b151470bbd5951616336a71bba795432e9b6f074983e9808dc8af5bf4ac6d2a83d3d41a7ae3af78f1fdfe280085cfa5746dbed508c13cff71bf2776b1b9432127a19d6552c6e50e12fb16575287614f865b450b5b81522afd379d8a9f844de57a0b4d1d5d98d56fe655857b1b8958a1f49ab5495ce214a13a4f3053245c79fd1a2dae21684f81c2d55694d7f8861417a1a7e1ebc8118f7ead11e5018a0dc616795792b1a1d5013e0d5ddb45f0a1fd785e328fa8789386050044ba30ac3a0a8249b02fdb97e6e7e6c87f8c5b77cd1428c1b20d947b812ae8749217d2ea9c4e45210ff67305bb9eea1017482113dcc62d37516ae40b10e5d25361597831dc60b6af6d93713ab12a6cb4b105c692ac85a1187e85aa172d8750933d9fc294bfad541cb897b2ae90d22157b17737c3f9a24b5cd1e86482ddc24c050e87d3dcf1141e900556ecbc34723c6d3bd2a951528f60168a1fe6ecfeeed4cf35cc00dc3aaa72b15cba2dcdebb05751a05fa122b61c29c4d8cd7ba841e42203d52af93426eddee45ec4a2b242ec19f39b5828bd7701390cfeb63dabe300688993b6733e4b9d43c203f08548ac641ae2b6b00ea9e4cbb318b37dece5f9b8906c2cd16d7f7ba868042c193ebc72a108cd8b46b2ba6b6730112cf7b245e04d714a378975ff6c8f1929c89629ba27b81955d520c740110ed130a2cb88e2c15bfcb286f38f9ca6e4cae2bce083ca04d225b20fc26047730f7105ede3b7dbb9e445457e2387441ca68bce565e9db4068e7a22eff3e8e25ed52ff75c4afb3473c90ef616dfbb2372077c6a4882291d75f3d0a317dc837d50122c9a34877a1c914e28709d6817e0fb51771e1319301cd43b7574e9c9f73abefa7748a77012bdb893f0a37e268e2fd0dac77bd4eb203217554e8478b59f3a2f031432573c0cb6e1dcf43c5bef015fae73511e6a16e88b80b87f58d32ca5e3187931618cf7d59847a6aa1291c9cdda238f223a79c7e7b9047790b27e2fae2b8b39706fc84f2ffff1e05de980d40568b345daa1b3b00ad4f28a241e20d2fa93293a1f9a3a9d46470daf18e23668f4fdd78326928a196d78c444bde020d1743143cb19430ea71fc3947e957d81620ccb6eeb117933077c20668119a35fad369158ceb0d08295ea3c25b62d1a12383b5967f3849fce9e14e9095cd4281dbfb534a806ab9a16e7b410a1a0a9d3f9701262e305df99d05637a586a5d97533a62605a9e8b0cc1ea0d66c74e4a1f423ade640423bd9a8241a5003646fb584a34a48a59111c6f12a336db6914e0a2e4dc1f87d7399eddee3cab54055c84aafbec284c330cc15c1aae1406828c55047d5e5fba4f6a86e0aff9ecffaec57be51673030156b90f191d4c776610de82af0c5edfbdd925894ab1249344a92a83f93f78c1324cab8cf665325d5e2a3181eeae3c6cf9c0d6f0cb6c7b2a396753634eeb1c567787e554043c16fe2189b54ca7cc1baabe6e3ab1a5abdd5dc9be15ff08288911976d4a5bbb2407304910e9d01bb277489f7eeca0810481e6feba81ec6ec4ce2b4ed6ef32de104324302b063dc9337794915f6a1f9ed051873d04c436d642843b2bc901a8cf151f09d4162c672618bc5d88ef62b2301568d5293048b7a23e6b7bea33789dca604503d07266db3d63f193b3cd13b39c95c37db9e721c55c22adda0a98b2fe5f7533d7e40bce3eec7cdd3301a6ccc587523cdf2fa0d94c9c549bea3067ebfb2101422d928ef5eb23f109ae1ff4e380ad3b4acb6fa24195237a7a4b6c39ccbfe3922c73dca5adc602a95fc8ce3102e0378c32b1e0e163249a14bcc290933685ea8f0c3cb97ecd8370ca5fcb2850f6a9a29577ab5a5cf624fdc9b38162cc9c4529106a6ea2cbee5c27a3ae2b07c37c20b47cc3ba9f7caf91edb62f28b172875d5f05dfb6d417a936078cb46998f848f3885df5052698087b7911729e2e1ecda98df600d9761006ac6323e0238d6727e9cd7adb5a0c519405e9f48aab1259fff10a2408b381aa0902a5f2f9969dbec3e1c0c4b70435863d51a1edad606c655bdd545cdd4d65236283c4e57288e785b6086f2a917759d87ab12dfdc96a02a1bd5599f78768b45549ec09c4ccc570fa72027fef4c1197e34cfa0eb6955cf9e193d67a24cc808530ca860be391c406d9115c07178c979596038295bb8b61dcec2413a7e261cec89b4469feaa4c6a032d79b66f9a7e75f07946963a9ea36df4264cafc9174ca713a4db0d7610a16e75751d756dd86e10588124be023c80050727b8aaea87e16b0bde7154c8c39006d5f89d6620ad0225c25835bb8542941cddd8665cf6d7e26430fcacdff7cd299b5ca1fcc5a09129fafdcaf4538460b806925af4f100820f3a0d87d126ab188b70f540d7ae19f44689c7aaf0205718cd69c0b4c4e515f89efbe1aa22b32c409a832082af46f5bce56fbc48dd6338b85824530c1c0c04f86404bcb33f9337a9fe6a3da6500d51b504aa9e1cc8fdaee169176c30ba00b98e853ce8a971204cc85bf84cc21ad9392a3788cd5c83c2ca53b036a3cdfbbe6798b030ad490cc998b3913789e43ec0463b53a8436d47731cb02051daf53344c12232bed1fee7f48f877616b4ed3c3b9e9df41acea1a8b80811530ac031ad051f15d951c065402ad58b12ed8e4becb0640caa9c4dd37e3bed0b05481820aebe08e6157f89d4b5b42ab15b58de6c61050991d6b4c6071cf1452dbb14481e462554d08d4d010b192c0f6997f7f57bc1eaaae7ae4aba69bd4e232af66cd2769781cfee3dc6e2e74dc41cb91f03f93e161bac773ff5561b67fabb1fbb0db2a5fd8cef7d0ff1d56c5f4670b262f2105e6ce23a8813c1fbcc23fa8b4560aec8cfcd284e30fa9f76a96ea0c60633e04c84a9e1f3014e28b24da02c949cd4137c071666484c859610cf43199224012afbb6509bd4e7008ad10ce0f43484a93abf8081930ecc74ad05987a990f439d5f22777a77855c4244aca314653c016753d001955eac58c0b2e515812710873fc1f57df167b44ff3c24c95dfe69141fe8e24ff8b87ef629d4d99897de88efd7e2e669f43efcd5bd2c4c94368d5901ff9b8e4e45dbc315ece378bd4511c80702ba8da1728b7b5d8b81e4d552b4e6ff50e5cc75bdfeee51677eb7a93cab9a82ebb36e38a56895c5e36296f03fbee35810f05eebd5f8c996179e798f4fe2953b1e64599e0be846c96a98da0a5fc3fafc9cd3e991bf86c327cae3067223860ce4ccc7c3ccb1cd79c4228a2b283813b184fc1c32ba889c92e001f197fbcf166eb736f14a26e9c6074ac33920d538c30aa6fe8c16491d2ec2208016550c392a2d0df2673c9438a7f7ba4058c3fd34da7c026b92569f202e01cc7236bbc8ad9424ca3e196cf326c8db44902a5ea60434f16c80006572283c02f29ade7176a2d48e7eca860152fa29afd3427e7051ff88f7cd1383e448ea332f362fd5a17cc9f31d0e206a70f3357e5d591b66b2f04e34e5524135794eb3846a9921dbdf256d17fc9cc156689f78b1e8a24e36c216c3108bded63bd3aae37ee61ee6b2f72f0a1fd3e609a73575469d5321a34d49c9fc9079209af4e30c36a19472f6c0ea018828db75133d7c5294d12902f8ce313658806c2f334c7696d1ad5c7c3f3f4829636c1f574c673d8a64577f8dbf54e880f230b0c291b94a84f4061c3c97654a75c89134745aa94e62c8d87daf5c41fc981cec4f4807f96da9b8a222f25fc2ef766526f053b986aaf3e3d6e6ef955ef26c35389e04444ee956b6cc5d91e54536b75685db1bdae4b8f13daf7408b6e6c5df39a10c879396b95c66e0b1c4b825b42a16e47a0925d8401b1327c3436ab24265e33ba4e8addb5469d38b24045266f7fdea62d6579e4325aba3e82187d704f7c3b436635a87f8184b90d6263d5ee0709278734451d40f886c8d6342464eb9fa3df8326447ea5348ae8957ac6f706757803842fbd7d2e04be539811f00ab52f6a3ae662682d57f9163c05abcd0fdc8c3542fc931fc91f55530a75db1bc528357b82e682670ccfb7f1f001933d0870407ddfe9e70de13e40076d2fb6631448a58afacfbdabf244151b95a5d681f0aae1323e8eb750410b1ca2f3f970b6b2f068e0cc9652b4e1f3b68ffe7c484f9a9d2b9ce4c2a8d74734df800d95c0dda2f739add32b886efd59ab3d2961833b63a292bcc24669b39a2d47c2f119d12485ba9bf7e2baf2360c58dca10db214249b8cbb4fd430fd8bf808ec8bc92be945633a278301d0cc8e505b7eacdec1994e1d8e1ad529ed48e0331937bd635430d8fa2e2863539eb0b8c05e0ccb22d3570c72465b1f3eb44764ee0f14c057ef09f47c255494c693d663410a006cafd2800d2ee8bdc4aca745eb88428a78a0308afe2168aa5744479495ce9151e5756b62228965a707958d9cd6d4511a095c6d0095e60c84894ce9d0f05e81955d9bb0b64ab1cfe0fb0a446405efe244d6066baa8e340d55e818e53dce9693367ddab88bd48a704e4169e2cf78747b61ee784284749755c75886f7abb3d412382fbc1cf7e3a76ce713e5dd5947717e0bdb8946a15751bae729bfcac102037a19943965cd56cacc3d22415a9bc1222265f8d2dda9b2047d2e82bc664bfa257fd5c328782dbd0a6a60e988c332f7c440a649ab820c3d3ff1f1113090ec5eb30b9117d45b52e211a1f2b0edc8474d0248603cd8f96a018b5465b67db28b2d7ede5799cc534cd498a29a2d0e6cdc49646da5454cf7500dcb6355bb2d710b997bca1c403408a0ee255c80500e195da2f2a5255a998b1b6036c036a4dc3bcd367abd1550d2934cbe75c597bab1cf00cbcffa85e77548d7289de50db88b3f349c3cadce0fdb966ad7394b3593eab3486e5e50868eed4eaa636d42b3152d3040f3ff4205b0d603b5628f7219d5330ace211d8f7239da6d441c25fed0143a99c941f3af4c693090a2add1a3bd40358ebef5d0612ad9135592eeb8ec6ae567a08943cf1257397f1d4c363b56a4b66d2e9953a22e63f5adbcac15ab73a09eb2f3f4aea93e7b7cd644b0a97e3808bf9b83a8d0a7f39087ae01c23f18a03430e32186792ff6788791b7c7d361c6ef3e9e8b31ebccd6ce86306544066d888565eb2ac82bd7e38650712199e9237b062e92c8b67dba904f48c27617c4b1aa6191288d5567bb880017d5d9bc57f555cc0400549c565264df8a419e979ff041bdad00cbebaef1a8bb0b50098fa7a59def8d92675fb4f8ec09855ca5208ed6b2a49eb995b2899307c8e17b9667e007454701b2e3b2bd03979dbff8fa47440b74d25bfd4240ece1e34e32519a54a0083b57920a5900a72028a798c02835edcf698e311a67b033a79d50d20a6e2117dfbc08657eff9926f669f72aa85221f749dbc92967c7ca3a3838dcb42a6db97f28a755c93a5fd906f308088e8140883cb543a2670c46731e32133c5ec47eb4013e9f83873e7f4fdc87aad7b8fea307252ad424c2969c67ace27cc702babe0175b4ec50ca4c648d7b4b77541471ca82775a1b384f9800e55a60ce21ccd111b9739648d436655ddee32f041901cd7265df9004f33274b5bc8e9e08738c2329dc2f27a133015988c1e9f987cbc7b9c750be730df5f883ed6182eae0ecf372a5804a5071289829e97ac6a2f570859cc72187e0ec0d15a713e61097701da86449f7ace1e5308d2b2de3b8d1d542faf310e89afddf1f4ed1a937f338a1ced3c4ff747efc648c1272dd45fe6ee1eb130c609fe0fc9d7ad1d07a3dbdb1811bcfdfaffc7cce4cbc8f1a973958b22ed088221be2e30db12c8decd927848d212e12bdcc3a7c69b460396441d2712f60bd3e93a0e937a3cdb933de889e717b87d186254feedc7ec26e4282441095847f258f7932740d89acbbead72222c8ad05397ceb9c672933be35292c5a8e1c060b83097a601411c0a7b85d1f95f09ea1fa150855036f40d2504550d9151aceaeaf7bb92f38a7a87945d258def95535d1a2a43ecaadfb9abe0745c39a10b12215d7efd5d44f87a77132a513dc786bd703a34bd4537388f8575339ef0ff96546336a37b35505f59acd592f334368a45b70c22650af19d122002cea2f9024729c302cea08e1ac348ce2f4e23159b7bbd5dbac67d4945990d01bd1c716d0b4b76dcbbff8348a9041da312d0b3b56126e852f5ed85e753af80da31bfa44ad582e77c720d0c5bb5c05d97d9a6da81fe66a292ed4b7d5a9f4645512dd19e90d12d89d19fc8be1198b1cacf86193fd225b3f8b5d51980f9d1532e2ace1baad7b7690e99ce378c80873b8ee015e70ab2310c8ef61671661000b8e302b613b5c0f67213209c53af708532301b623864c4ddae168613480b94fb44be6e21158c86d064bac1d0dc9d8abb0e1434bc6c3f194971160344e8b6725d9ad2f1be20ee231f20ad9253865f468d13b280f341929738184070c993b14d60fba13ca7837c2e3ae107559a522e50dc00f7af8d7910264f67ca980779397f30be224a350fa49a13d4835e738164c2f6ed6c5d412c09cd62a0e8a96f344c4d183a8dc992871c34cc495aeee23602da6cdc18d297b4f62b8133b40aa7185854a6015f0cdeaffeb9c4b39c5f4a1ec73990f9eacdaeda935ea024c6f7b69039c1d6856ec7a51fef29f3a54f8cc52e9a2da55a9e9658c6614154152ed981a06cc57750a2c368ca1e97e2a1e002d30c2a7a757d0f8223395a870f002fd0326fc271ca0b4d15d6cd173a80d63e6e185c28151783cde227c2c787962699082ed184def0f3d2ee8b84a2449e922856700a65cd9178b605c9b24e501b88e64a0fe45cc8ee1259f606f20a04bc4dcc5b8560356400961b1e2ea4b48ecebfcf469ab71064e7098f843fd9d5692543e6d25adbc3515e93512a750afccf5654043d9ca3f927e3d1417a6fe584744044307d22292ceb8a571ca3484713bbb20efec17552605877885d8101f0b618989db59b03611be30ba555315165580b63f46d4fae3b0d92004b68d9cadd4c440fc898adca2421ef617bfbbb7e2f697a8310a31a711358afadac360fc601c48a58ed41eea0e059862b73f685a900bac7a0dc7818d02e9e4cacd4d6577b28af21451d961fba4d3c50891ac5ec5ed864bc63fef4a898b529238e01d5728dd5f144c728020a49e3fca31e4c6f93a52e619dcd0bc48a99ea3a3985f2352152bc09409308bd2fc9452cda2320a3a2eb42b17db8841bc4068386712e132658aa863d3dd5036c60458194042fba25cb4eaf0490d357f49b8b612117f4a7e5099eca480876080fb34dd481aa174133e459bd3640da3d209d79dadb1e16bca87cc2c30a966bded620f8f50564cb13b22fb49a63554c73df985e639ef5edda5b522a354eb87bac9493bc6925b702e4194f73090d12bd80a324e69437e4dfaac86703e71d63adf8604135b8875689bf8e62c23f510f1b84193069b7a7fa72bb8a908f2d0ddf653046f957ca9d42809f1dfc9405f2699b77e0579019af04be69003f13ae1d0f217e8dd96c576c35b31903e7df190e2fd12ee1718031e289ed741608231b3535793e6f268c552c298f75aaf56a9eb30597e8a3b50d455d0ed23c1c218a3618ce425c4e1f13ca09600e28afa43ed684a2b1531bc15305155ae344a6b15321fa38c87a764995f64fef7e9f54f1b06d9d909006c9bab3b64cf9a9cfab43c07a54cdc1355b1f3b727a59ce60f5eff1aa90e50e4d0c7c5f26b6b88d79beba9514a1c3b27934517e1e87e02bd101f136fc4b05c81f4b137210f10e3240e872ab9223c6948bf55a4f30450f3a0f3107ac6da2d6fa42155998234fad2b1427721a82044625f4d9575ba8585c57a190a6e2cc5ca4509a0080228e01323cad4d396f5aa635203162341854b3f651edd4e2639fd81baedcfdc5673a605553902a233c3387a1772dba60120b9f48fe6e530c94da062b7513f96388957ac0911b66b815aec711997c30d0024d9cced1f0ea5c4bf90e8b51c65ee9598c43624c375364684ad69946869da2b265acf5f80229ee6c21f77053cf2b2bf9bd353ee174e4bf4418505c30d30e292b3f397f45f3826680a9a7f7bef2051ae0b3864e05177b43a8015fafcdca811d2bb7f950851ec3af56750e5a0c38cc10c4c78751759c07e6346e16bfc1cfcdd86734f284a5a90832b351c2ddbd2395213d43fa312d551931d8dcdb4d8339df158ca650e45e6e907bf4c1a1d08199f83ae59c609a0047467b22706a9a3a9255630fdc1c8d351bd296642832d4b097b2d0b020d33ef5094fbd762700f8a2ae23991be6251b84de697a2c905f066581d781ed2cd4749dc31554a47fda0f93a289af10f35e652e87fe1163c2990f7fa3197505913459d95606ce11b4cb000b28c4214a0441f3710a516cb5032883157c1fc3941b81bed4a72602106118e8a75541ffc8c19abef1f89af29a0367a55481c76aad695463d8eaa92b9420da86206810967309198b9ab31ff900d3b49d0c1cd00e6ee261a65386ccba94b00425349b67c7cae63a6c75b9b09e0d23afcb80840966b1ef4b9e61b26b5442803523c0473799253888517ac24cbec497849be0c81cf08298ec7b8648acdb4a8190a5838e2305398d5d1ceceda7724e5e3e56f745b34470eb82ba988f9884267dc2072726c0e84029bcaf922007358d002d498a35852479aaf411e005bac6218fc2f4232384686fbc6bd76f97f62ee2d75a08128014028a22480ff2f0b40f42b9395fd2161149cc433aff79195d83e343bbee01f5a31c8eda51f2d0f48ad873d3895a91ba0dc510a4b27cb05e92de87b16a8a42ec0b22e1777c448442466f162e9da4c9f97cb03fbf7d16b411aad565258741ae49c5172d600cfd660987e0b651ce92ffc0df8bc25290d1fa64373dce021f49ed07dd0cc86e0f1fede0ec6d43432064af5ef2fa1853eaadfb20203d43b9f5e7a67f1a2a816bb3cdc62279e13bf0077ac5f0414a7d1140b900666bde6a77cc15d191dbcb7147778dd4073ef8abbe0209955676908a17d34395f0ce9690c9533929efa6aff70c83cbbe0e965f2e60a10d8d9cd8481563200d9ec6e03320839eb8194b65c637c3a590025147d1de26b22f44bd7d3f15770eb76fdb7edfb3a789094039ef383153b5ccc8d1e6691419c63931e3ece1f24d27bd8307084da24ee3390d80f7689ebc7abc4c4bfc898dba89133b32a3f63ca79a92878196ac30cf0114b46399ac3436e2032710aa3c25d3a4981122072c9ba92c2830768ee42897576e90c2e294f2c53d36390e5d3d9a52ddc39b98e6135dc1186731926552928be66896506db80258e09cb1e0fafb420b8342dbff64973767bd90b6bb3c38d855cfe6b3ae07ba04cb216c55787899c8a6d8213a82741c52474a24e40ddcbff4957d54c3d7116d3221bf0e863209e6d512547ecd7959d19b62329576873128c849cb9b3a1061f0ec448689bed43605789d4632e422bab784a097ad0b420b42a7c0df72f1034896d2265d7573c9ef7fc34c8711d920a24d2abcd99295748258cd1238278d9c487887459ad5241f3878bfe20eb6ec430dc5909c082482765b48f36000895cc5c2647896ffe5d965979766f576844cd6f3d281a0a5844c21bd875d63d7caf050369fd7a267233e706da976fb749518cfcdda598df90118bb2f3c8e80fe04332d6e8ccf88098835aa5060600a1c2cf53f1861edf98f7a9f1c5cfc4c44fb154e05b14487f9b72a790946d53579b61f94831ad848fc99a8551971fd3793cf50640e2e6a07726fea9d04a817b3a2d1c1a305678f69eaae6df246b06a2291eff857028c42b1a1a1acf2f626b0a862d2172b7767012a19689e8e6400ff7df4ae484915e6d8a5cec5dfdfd4718d1ae74cd614649edf74027b776583330e38dab308fa714c0fc57baf757eccc45ba99a88ee54067a41a4a9a0d0cf0c3e0648d5a3e46194f1ab83a4733fa3aa4594d55e3021d3d0b80e64852cee7dfdc868d4d4b5a6fc34a15edfdafac7bd63f765ab7d331c194934052fd4c5d41358a786d90a039564c041b72c4824220938e50610f540880cb6d40ae54482918a87bbaf1f02bc8f314cc242530048225a9e70009f21b33b411d4af8a2a9843ad708ad0ebc8461c8bbaf175d187c4673249e5a84b74945298e72780ce08548a3c1dd1154a167c2422a6d9ee5997f8f021933feaf87fb9ae1de42edd79a94f2df54b96227d763984723902ab65e7255e46a576b7cb0b6db105fe2d817b6a3138a29748570bedc7f524bde2143b49a29f08e567bc541b20f849608aa20081a67a568cbc6e0eb6c821fe44de8b9e76282ec83a8d0eb8c60ea4ad2de521b45cf0cc9e0f1ba1b083d935b3be0238beeb48c574f8024003badabf008c116e8d3a1e61920d38bc6276d0449575df05cdba3009d56c0254ec39639c68afbe0d2684646cda5c6bfc8eb8e4f300bcd119dc8dcc2e44e2b7402b07c33edc0d8043ccae8bc277fe95f65ecbc4ecede2eb215d51264c8073560667264c198802867b814cb8bab9a88d4b14e62756d94bd12d5a41b7488dc64f337be2b4ef49810a5509b9a3faecde68e1e4f6ad680233cd219fd303cbe33018f0d41c1bb344ec3b8b991f2581e38fa21ef4314d4ae7f0d4a1253d20cfd394419453065bec9d42823dd8239d93a33203f3135229472e359e0f14d9a5502f593cda5b59aedbee9126fb756d3353ef593966c40902e2525181d2ab858c66130963d8c5ca7ffc02f44bdc0e33f10161e285333d9cc5fdf6689dba8bb477ecb2ade55c28e4c4a976b1ee15c9bb00cc850ef4dfd5ae52af83497ed3bbe20230814afea61d61794cb2385ed55773f838be1c504b7738610d8228e6913dfd7b2b05033ce3bf54972d0560ef3cc1ee1df8f75e1111f367f6a7b965390c23efef874dfd935ec6ca240a0bbc6c527dc5693ae8f7c12405b88281b78c899355f2e61963aa9ba9d23b84dc6d80bee6483fd7c86c3d50b72098a5f66b623015904eb9da051ec87023d58351cfc8e06dac3333c510458b241989545b985fc75e6186ab2245e05ce22dcbd2fad62ae1e558c10a43d2f304f740dd44f76714a0941ae0582680293cde36f33579caaec218bc155b1ab598f437a0fb378b787691ad4045197dc240f7d7f1235484a4e8d5181489193a21fe5b208ba4ad9fe6c2d824b2c669e17fab3dbf15ca3b3a59e72382877eeeb8b5358044d1873c1a969620b1226b6df8b80855db63c108519077ff79bf7baf35818872816300b742881dc323f87e9bf9151c0dacf44abae5a6a56616ff9f7ca8654d53d31974cd682608438fdb48a9662406106fe0a769d238f9d0c824a5774560aaff126b133f4a357cc9231ff9c0e85f824f5cde24f2309e0190692c4035625afa504f5cc2f5c816cef2b9e8e911ce37600b668ae8dd97b4fbf842a7a33f30b6f7a02294cffcb08eee356ad84346f94077b5aaaabbe448b6e90291cff4d8a5ae79294228df3de416c0102883404cf81f9d63c51dd7f5a223b4f31e5cf148ca795cfe2b9eff3e6715cb887edcd2e8b06507f833babd845d3356eb460c634acef09aa31ed476505a022205a4a0f7aa770affdee047cc24d151e5c091564aa48456f6d8f21f5a91b087079d6abd260449ab13b8fd8042cd4c4cbe86058175c28b1e77aedbce2ce0d26fa6fc9fea0e2a4b4b09850b8080e679ac5110b5250d8b4cb273babc0b78360142edbf621455a7f9903a23fb33754e8c4528bc7e6d7488c03c7c7a658e34be1ed4ad81b0d07f728027ed205253384cf5576752046a63594640e90b19a054e8d772a77e310ed4561e938c6423c705175f5302284ba9ba59f93481b14bda5208ef5628afe5b7e8d7d7b96e28d9be4652cb2f433d44aa05d80699791ba057d141300476f1b54e60db105a0ecae1580a38628b2ad681907b3df955ec2778f932aca95b21c00398508702905b07038f981251b08812827ea8d6aabfbb1916f6c253e91581068369c91880dd52fb643394dbdd637a7baf68652f4d9cd5d0d535b7b43a7a1b7b888394ebfa5f4c97b01ef1bc6b8f7274c3a174dd9679c1025b08b057659bf6a66d8d0babb1563d00e7e980602526f52a145fffc6d7de8190fb68b25a00dfe8fd85b90a60f88347ed24a0fa45a2a23bdd8a68c51123429457d27f638cbb786cb0c267e665d4394cda117d13ed834c8ce2be439f8bcfc520778cc8614b69328f2f86869817fb43cf4c4efae2ddb565156ae26cdce72fcdfd620163c05042750b1937996bcbb5acbe1001215670b2f2b5176a602867d834650894c620c77198feb37e2767852578cd35471bb0e01459be2844c58ec9fee50df28fb250bf73798f341d090ada43bcd892da8d804011be2327ff579f2f4d0e0be5143913a83827a293f011c16e17150aa1aa5d8fb9036d09ea674374eb86e7ccdf28348dff28cee47bd07a5ad9540b19279879ab07ca8d21428b27b880c587bd3190d17854598c3618e7abeb1e4c1cbd1a456bfd7028da41b3b3f986ec871d86f1020c46bc0af0e0240dbb6c3c6eff190b333f58ef1512c8c76b6cf34abdc79d477ce30fe9d11783d656c212d84f4cf81213cbae413dc9ddc6d65990236e2890b290114c3d129272fce5e42c333045bc83c08551b18c88aa9c6d40c667443f77d6595777e59b7f7c3995453b3fffbba07287011338543cb92c17f3d10f9e7b022b7843a3cf7853e96a91b4fabdbaa304e0cb34398dba7f0ba1ac211b24ba03a0f95f8e8f388ff1c109a6588f9a4ff7715f9b17e18ee0111426cc85f7d877822c3ce0778e6104ca7513b4c044136a84f68957bfb1b2d07f2f6eb72e820d0bc134cb4c6767ac7d0030ab4eb12cd9ba447aa7ca0cceea0c62bd0698e2f3599d770903d8a38ce72ba20c3cba504081a11bcc5e62efd610ad18ee6675429a64f331ee7153291bb9034f2a870da93fa819a8a88db618c3b52f8b91282369315d48a703eb4be6dd9fc45534633e2745f085508d60ca27b6668129932046d93707b59114236128e835c78d39526c838122683f677b353cddfd22dc09b6b307a68452074db7d32db3815422ba5f8bb9773166c8803eb00ffcffba1a1080e57df2b12d056784e8869a7094f967d129e4394cb5a378baf7e8a910002061822e7269c772a35d39486f04fc2e20c2570a82d5166c43ff614cc8033106355c8cff7b343d1829b050b04a277b82e88d14decc6420489dcfb414c654e0bea9e7dd904ce491750b769b7bd271c94a21ea55031592564279dfc0329418ab7b0303576f310741994d433e614199c6543e7f63acf35d6d5098b22eb3336394f326b67dddc1bded7c452119deccdb99916197f2377523f00ea0eb33f7291a0c9d0cedc851466f65b0a36b66c6d13cd812a684f780d54fe43a4e4c575c6415ba2b5cb0a5eab207c53768d521aa8f99221b41097f0b498a3b004bf46bdb0e2df08573352859d81c7443467df67ceb99e847e34e5573d6c565c713e21279361f74ce436a31737b0649aa6821b9fa88fdb34e80544e65333a41637703f24140e3e82dad8486b30cb4b84322d0e4ceebe3d06ca726281ca81472739f65417d03012f6f1bf4b463822a185200aaf55f6ed5a30bd9c429b5b2051ffba7aba44de0f39f1f31872d8272e08be4d54bc86a347f594e7f0e959d22100e7276a94a18e0f6abef0da308cd78171a18e42784ce5f3296e9d3332382ef70e9d4230d5d36e60c44704f2e4a728932e171ac3e5c83b45942d75748849d29a01877bec756e4b55d3200ffba262f9fe8e6435fcad532ec7d1e254b37093d91b0858266a3c631979277caee42c396a46ac485f4c172287bbcbad5e6b270b95aa47c25ee36578a1f3da9c23cbedf7fd9d504fd27d09aa7113ed97993c4a7ddc0e769451478a79b5ae614280184bafa60fb1624553cad08b0bdac40cbe38a309602a533dfca2258a5a9a8354161df316a644ef395a30679bc9e14b7ddcc4edab072f75e47e646d3b37d4b7624072d2b542eada8908207b62e47c56a77e50b4a57278a6eaf87e92b8b6aaaaab195e5977a73c17e051018b2684cbea30bf1305012861a3827c876ab6e7155fb2351115cf7c301d448929553025d8a57da748d034d9eabc57b61c82d42dd33ac27848c4e267fce2e58d0aa4aa79eedd60ff3a88b00da972e167c3a031a1c066c5c30542a520730327d79eacfa1c1627f5d5324c6b21cb3220c49738e953617e9750262a53182e45006dfd1092918320cf442a6d6c40f00287a1fe5140fa47975d520eee10b6a0a32e583f7b51783fbc03fa234b4f7de5b4a29b74c4906af06ae06a10659a3af49929aa669da67051e4158ff0d7d0607730e9641b0044e127dcd7efa7af5197996c0bcf291f66af1061e4c99be7bb7d91fe9cb4bf4354920f8025f207d81d68216b420bd44b65902411b5e540a4eab28a592ca7b5ff831dbbdc87151ee5a554de8e40c4a50deab864fd7f29177b20e4ac7d3f974b1ee49f7ea7aeabd1883e0bf486369ac7b3106c199ae1bc7fa33040dcb778797f7d1229aa087128d77791aef2d1f4a9236d2cc3b3556cbbbbc8be8c3e55b78f0214314193517eb8edaab003ab57ef7350c41c3320dfdb5be1270bfcd6cebc92f4767bbd6fd97d0c70e4108e307a59796acd9f1d184d9e1723f0a7809fc96106647cbc33c8ce803e65bbe875247239c3e21cc8e1a4fe36b88d307667b1a5fe36142981d007898078038614498ed6b88da093563ba04b3893278097c509c3444cdd4795b6ca0ef5c35954aa5ba5497ea525d4a0bacb1ba96a3ba2478d45c3eda5e6ba97c0e37afbcbfc6f2d2472ce2d820f82b2adeabccd28a0a187aa96b4dd2f6ea56421c72c09bbc517f7bb5b460ecbd5440d05192c751a29625979790044b800529e1b06b8dde178e221e58a3f736a8c0a3c82594a50ee9b758d10745f2bc118676e3097ef9a83b978f70c8e176ad496aa1a89696bf96354b3724c1cd56bceeb5845ed25893d4dddbb57437c62dd7ef5a35ac227bfd118f9d2bfb6d6911bb56f66f75d7f059f11a2d21b5d6edd67b5b7062ceed6e97a6d280753aa15a3c37ac20ab9d54cee9e472d9f4b4cd24dd3bbd5b6bfdfa6914a9a7134a13c205766aa7161ea5eb09653c14d94577819469c93631a8f2145558a1e37446c1d1399d52a6393bd539cb3627570ae7743ab138279d9c41c6da61edc87698d4aa7365cdd7e33ac0aeb530e40796f4a3df614aa6610ecfed4deb575aa9ad1f133a6bdfd2b8a8fe48f335406a1f13ea770853c506d8dcdfdfb976a569edc58486862685d345717da66aae266c36993a33c7357b266beedce9dd56ebb66e6b92bc87817bd05f0c762a90d8aa944c66e3083c5bad4e4dd56d5d28401a38d4b26104f71c22657c22d131ae028dbc6691a9ba05388088851ba28b80db9235dd57c8187f2d2ee8a461ac7bc44776aaa66aaab64db5737dae7b5b98a1525570857a6badb5d6f9b5860bf06722f7b5251c218fe0976f8481c75be9b5563563544ee8e40c3dc071cdb5d95076b2c4deddddb5697f7748290c8f3707a1f30ca6f0d8280976dd4d7c622e7a0902fba85f86d314ce5312bc655973bf1f9c29a40082feb3bec4e18a0e8594e997a819d3e30d732b19e592dc4272479192322b6894aae74daa57a12765a35c5405961f8eaf089e736a5a6be22891905bfbc096a59439f9e96364cd69e209ea28408c94916f001e3c8229c8008f379ffca673eb90358d6a01ecbf176310fc51348174355ae858ffbd18779fa4b740159e27938bda0b321d75dac1f28774563649d8ed87b00daf94711b4b70ff783315af6c802c6154a472473dbac926e9ce100e891fc6e29743cb37f419eed119e7e373412064eb472bd62f8ab96cb656dd64773e286e32d0e6141ce051bac6de9ed3a67d074892941f008720aff8809419fbc4fde0832c432ea142c121d1ba668cfde1ee0fe7334916f620882f0d2638233dda4c9ef2a0ef219a747d668c3f3602442256e40649da6432c61f1c5d3636c81afb791db73de733492cbff2e3e57c5a93b4695b0b4f15b11512b756f6df4c3e6a232df2078963db203b90eca314633bdd8b41f1b49d681879c918ff2a6fbdad49aaa619139ba40ade96e9b6fe417c63637dd91fab44922ccabae47d293529779053c4d18a91dd2a713b457671b4575894d502b443c8fed5a2462bb34fd81f29e34282c74d969a651b8cd468b1010f929095e0f179cc2481479a041ebf7e1400b2f22c8f452098ce7c648720456e8bf09a311b0862fc32ddab526d55e53b2ef2f0875b72f9966779ebf21772a7bf10b2bf4b0bcb4a68235bf01ba46c0201be5eff2088b1b441caf8bb5abfb5f2f6c4456e834a98e50bfea110873c803f0e73c816fc4115de7e36998b9cc6b6a05e482ee44808723441303627bfc936d9ed4c29be8212458cb8b1d65ad97d31f8abd9c454f9160abdd4127649c525f4d14bc6407286c6793d4dbe25fcf8028c262526bee761c60853102526ba779796169a19d1ab84b2f4b343a12c6da173afb2b9f8a86613f9c78a0042c0238d01097d4b4b48728155dee5c7b796529a3b1595775151117da87ce87dac3c8bb5945a4ae7addb76eba4d4f32ceddafb44e9221b2f8c81c5f5052d82244d93290c54138af0282a97359d5045f8536affd5719dcaca4a284b5ad82a9a1575d8bce8ff019023edfd092047d3fa8763aac8dbb3149a09c2d62decac5a2941672db601b5a594524a298397baef3e1a1206eeb91f51e07e542177ab8ed53dd185b274044ea9613d855d6a295b18eb090e305613e417fc3b19c891944dc80a44ea89ec5dea9048ca73e1e99652b89217c2ece8de7baffb1e4a5d1752d80eefbbf7440a83e98749113f11a6df1367316335e5e69e13a9ac13e90fdee1defefc7bef953de0968bdcebb8b05bcd98aaea56432489b2644d8334aa8a5563072b22b27fc7a411605f761d4fee1bda53147522a90c456528944c65bfbbf73b6e53adbad5dcbad5f696e33e9c25392f765d074109996cccda8ef9c84f37fd45939907691994ec6fa5fcfff7bf17e37fed27c94b3333221108c6bec5d1fe4ab6df59399a6fa9385221538e6aadd4cecf7af4deef98ac198002c490ff019097057c00c97a2905b803dc2cdb185b1e72c6c3061db449bfbb630f86ff321fd9273eaab158ec5e1c95096406a5dddd578aafd2f6b49af2039e4fefbdb576d1692b685f5e02cffce1b837f75e792578ef8c66c3ed0d354d6b10cc013601d7096edb0d0a92508152a0948f1cf402f580724038a016880968053a72ed0c4b094a6126c8513db9280b89b10832060a0c9417988bec8f8d341642622730c803bc240a70093ce40aa950be3c8252a0d4174eb2312f64cd4cb1fc0882921df424fb83a490a025b286be3f088996352cc89a9bfd4143648df62a3f82b8c80eca42e21f415480a2001919414540a96f05b68823c822c662208843e288b1385e90088252a8140a94b29ded6c922a8bc562d9d9f79aa40a83853277ae28d4a366adac49b271b15c2c174b7b99bb864d924f37edecde7bef97e376db6802d390e6eed6530dc2bab7da6f8585c02e19949235dffb83563e9a818448d28bcb8fa02149b8fc0822f2bd403adb77837c2f3bbba70f257e27177da76cc99031fe3f806865213e979d81522c2cedf2dbd7938f3e938bb43c7ea63cd653febed58cf94ea813ea8402418c572fd8f7827d2f98679b602c4222e0bbb8fc8bcb9f6e09fccfe423cc04293a4d12ce42c6e031b2fff80101e3e4c5898b93132146ad26091be998d724611e2c59e128564b804330fe5ed91fa4034abd80ac8f27da18a813471be3c41b616096958fae9de5647f906a03a526e9e539ee3b97d04b7636492050caceec2c75efc41894da5c5cb67f0967e927890a41c634c541c7f4fb0b644cff185409b98ff003b0073ac84d93c84d99c85d83dce2e83510500a94e23889236590489920489914587c851ffa8a5cb8207867ba006b8030520539d2be2f5716dc6fd85903af054170db2a1555989153051743d4efca51fd76cffdb50604f6a761bd955a9bc20142d378b8fb4c1723ee5ca021067af0808235916646268147dc5a4ce341e9cd0f16f7f6b8f7e2173c6d60803ba37ca4390cdcdb4ae4f4a5ee7b7c2031cb184f112f0cdded7054392b1d17b1668cead640d6c3479e05d03939d4d02d5b5a1daf8d6c92f40129cbb751d0a49f3163936c668c8348602386c83ec83268a800ebe043ca1b60e04dec11042c4b2dc412288aa03295c6bf60172e59adc1dad0a304019b05e4b0596852b3917d95c91e382a94a70448d3eef546e10c3c52d56b6a1f8bc160af97cbd56addabfaa9335923ab4f3d52772a4f65527b6a131aab4054d5447572706a9057ab57b29fd6c4d6a1aa16a9aaa736e98d356d35b0b9c6194d55502ef3512ac7a1a0e669e2f86c02c9fe5776aa533eadfbe3edd033ed54a7f2155d0c49e264cd00b2bf3ff11f5953ef8fa093c1892e4b79a74cb2468d915d96923e353807686749c697a54309411b2cc0a348e44e5679fe9065d903274ef24b13f6b759a29d8875ca65b3283eb22e7399cbb60d47b5a302224203e9a299442767701293561451032e879c3cb16d3adde303ecdad4444c8899decb1aa7d92ec75955ceaa1aa176adb2caee9eb5e5cf5a6bad32c65ff492fd09a0657f9ae5155c08017402ae2291fbe04a070441902b882260ab152bf6c51198ceab498b67b53255934e7ba111fcee3ad4b6b7f1ed2f0e3dcb3b0c2bdd4ef69fb3399bb31933eba8d75ad01497ed9df5aac9544dd5544d9aa7759e5c752b59f33e9a14f0d2ca8742981d21960f7d0f25951066878a0a8b0b0bcbb788d307e63ecbb7bcbccbbfb4dc955f61f1b6b829a0f756563e659640292ba7d3e904da4edd296565c5bbb6a442ff0bc72e77fdea7ba3a732ce1b61e0ae43a15ee5968f6a351d61ad2629f4db4651a10e85422f55d3247577655a55d3ed561d925eb13a14ead5aa6129f00ce1e48404090c491794de7b7bfefe7d59e37792feefdf1c5f7e2b287d5993614c5d9bf6a47931a1a1a1b13e742e41f075ec580100344c442eb406829aa65120648765a7af19e35d4f53da1fa5d40919e3ef2ceaf5cf0fc747a58f68f80529630ff973a034f46bb7e7b6cd6da3c17e3fed6e59a9b672515b7777597be5a2dc9ac872571e672b259425d32479a20f26baf7d7c1fb5b6a94ea8636b9383588c0579572912c7122133c2669422163fc954c71c56cddd4a7e323eda66eeaa66abd49bdb0cc7e64139baa299dd49c335553aea5288147e98ae5da12028f34250aecdfac19a0c3c64574564609664f386396822293c6644d96325a4852a963fcb58861217930041b5b71aaaaa65c24a40ea94ba46cee55fd7442482939c975af7ad5dce77144bcb76104d3a7d408ae79bcf47ede275e2ee546381279f422d9473792fdbb8c266560c66cd1249ba921010e815190fd65bb0f4b68243411a4cfcacab9faf007fc63efc46cc7ea43e0e6fb34d472573d1b46f046432ff70753047bcf7d0d24f00d977be59a244f5c62b5f5138e0910b8619cd82f93ace99894b9f92149adc59bfa898bba73809be51ba04166c0037234e5ece5d3ab496a6d5eeedacab95c6eeb9dc91de3b64eb5e3e2e17c050910abd6da5d43cfee55af3d18eebdd7b282d8d817f6a5439bd45a6b2db7fd9d28a8b015227d7c92eefc8f3579bd74509fdb03ade59d4980d79aa4dd9412c008dca94e512134459b7e539474a29333b44c4ef83801e504847b657cc05aa61a27371b69064704ffa5dabd54abd7aa76b856add80d206b6a5702fc294760cf2161b82b1f5510b4b6de2477d68ebb1d87c2113ca6cfe9022192d61feb91ab9349df4823b47d6215e2559a9aaaa99a8ac5786c9b8b5342698f4e8e21b0d6841d14b400e3278f334fa790a3f94b3089c17e47edd30fc77daafd536d25656c1228a5140533f0fcceddbb56cda773f9d3c77b3cd633baa0d16aaf76eff4bed5dead7af26e5ce7699e37bd3dc975de97a2a5a44cef14e9c92f4c01cd78292947b27c102bcb108721cf51d15454a6b78aab5c247f06c581b809ca0ccacf8ba707c6f3e271758eaa6fb27c2dd5289f3f997e9101e982e4718166c645f2db7d4e4da355ab757ad7f639358dd26a356ba7b7d568add6debb711ac74d6fcede6de3b8aef33eedfba6f7c7759ef77d2929a00681bcc6d8eb50c86b95156d65657aafc870bcb2a5c5932e2fa00682d31b0c752a2b2b5e87234b96cfc292a3c5e5457b7999de2f3705a66f0a0c04f22882dca2c35c249f6500d66dd7eefdda2d657777df1a262b6bde276d44c1f46d44c1f54519aeefa591fddf3658154f4c1a0d4dd32ce10a9a28b79bfb70f48703d348f1831779942f005cb0898f8b288cf6e088a107fdf9913f343fe091c2261259d395e298344d03d2c8fae1d0969cf144ee1918606dd2507a53bb15c77192933dba677a1cc7719c362ff5b8b045c6f8b7cc961a462041206f90a38a0006f48deb131ba2a360a67285be95a3fa34d39792fe9423fb74863d421b943ca0023a1ac904e468be832fca89b238d29cebb6deb7716eeb3a6ebb3b52c6c5c3b5e70312b01878988260604703913e92c6a07282898c9b5a2b16a62b664ba4c05922c5cd9224b18f022603fc94eebb1f81bb57a07fbf451b9a48b4c3c74bab64ff8a520358c2ae486518ec48f6df9101ffa2739166c6f8cc09ff4c184130a0da20010711d091834397301f1fd1d760b0186afde1ca784175612530a8b3a104c679bc35769a3d40154e99527eb0ab72a12df7081bc5891fd844f944cd2df649cad088e1b19a7ca829a827b09505d995c0f5d61e2eb2b1f55e1c5575794c306255f444294afa8dbf07f195ef788aca6e3f39ea4f334564949c31de163c279a948f288e8fb4d3e954ab555516149aa6c3db2a0a02d6a1672d6734756d9541da3aa7ad72c62065fcb5a903a5379adb19c7d1d0bc94526edbb66d311cb771db0df38cbe0206832169edfce83c26ea449240ef1b48a44e404a06587fd0c8b64bf3dea554393a9c7739b07bef6bb3df4be7be5e3d701cc7711dd61cbb4ae2b31b1578a43fd4c7b5ca5ba54d9008a0ef4fc790355c23808a350931e4a80e51fd7062255271aaeaa57a7dddb66d5dbc602f8e7b75ddab7b752f6ef3ac8f0f75b95cf9be70a77cdd7ba9be2609bff0ebbbee3df1fb52c259e23e54070bd980fe63c0c60aae9e9904dc6fb55aad56ab455b2dcfe3d568ab0c4ae2e4f7ac230e43f7ffd64927571871f63ec1ec864161ffeef66e17afc43c9d4451144d51176542716e288bf25015d591f7de7b294a24ea165194524a29a5946a934e22b659c002cf3c8ab26bef798cbfc6b9c6e05c98b3229cc1c859915d83c1a23c6585ac91d9da0803cf1fb926b2b7a40c0e1e298a537139148542dda4382f05d65a2b6d576aadb5d63640646d15dd0bab3b94760f4a9ff69035607633b27f9aa6dd39653d54789432d167517ac420958209ffa093ae2a6bed63e86005ef9fd2047034345a9f5ce0666a04ae8e1703ae8dcb5a8b011eb31db318ae9c715bd7e5ac7454a128405452dab4a5943e8f704da31a95966a56a3fef36597c9a61aea6399a49454d29e99e9992470c65ec85bf6ef80f410a56105bc68db614bfe06f4dbb799daccc133112a655e09f088b3e7509e89c578d48a4ddc12275494527abdb384c9e0264b496aff6aa54d6055d6dab5259df5dc2e8fa2a6b3d96c8643e63a9ba1b3d99c5571047d76a5bc9f8c91a4dc429ed9026b333a58fb6062d8fed2ee400d36af9c52061992742b10f5072543caf8156919ed43458110540999ce9e80671a4b6369300dd3f7c2f426c274157774cf953a11a6c518bc1e4a363a668c57139d69b4d20aead134cd6a76feedd6640d2bace0b1262e72edcb028f7ff38fb74fd514914dac381ef30595c55ce42f6b5a2b82dbab358994f10f8d186b92ecaf4d2d89ac9199c6480ca0504852f8b4353e6d3d6d3d6dbd0d100c856cfa5dc99de28afc55faaa148e0b54c5cfeb059b79407a7e98c8a2c434914847d439bdf7e290247553742fdcbdb0acf962af0e266bbaecdff5f848eb66dd4ff7aa28fbd3bd94e01647ca438385b56e11a6473beb623547cbe37d614e0952c67f9a7ce436cb2e08f7d3e174aa6ed51de9b4e6663e1a3925f873ce45e194d05aa7c2dda93375dd8f05a2a2640dfdf691105e8564af2fc85e8fd85435e7327191d3bb754d54dd6bc67817bbb0fbea5ed4755fd9ab10427e86984e1585638e9bf86876af4c531ed3afcd77b95a7914f528caafecff0a1dc167b0e224ad18020b56329705e8a7d6978eca6d9576208d206ccc8cd72586b51f6724a082944590228c03faedf8e5086c9c4c0bb0cbb40077c581c3043617c4fece2fbf6211d8bf2350e78f366cf8ab521d291cd00fe753dda66c4e85529fd893c5a9337fadde98613124e9beacf94cb37ffdb1a64a46f62abb95de999469327efc746cc6f897ab2cef00cf6ed645a93299b52ea82a3a390312a2e0e095240707ab262196bbbbbbbbbb53f7588c878ef3a0f46b800c0bb6dc55ef4fb2e60594aca1ed271eef446c522341258f9f47cebf6552060b7c8231827b868de322203f31384ca04f32e3a0e2d8aa5025832e8c3dc543d6041965cc4f17902407622626260c654cfa29e627dfa97102dc2df32978f829c4f2ace828a593ce8f8227a59452ba5d90eb4e978b8697052c7097c7cb02161866cb5e8b209778044c5b6e9fdec09338fda99235da5b24dc8e8b6e20475c1229724e8a24dd102ac8a3a70449766ec79f4be2b31b420935499959af9062c810d9a50c0e9dc757f25206854c45ed002a3c82fe8cac3d0eed92359d03854ce787539b09e2ff6bbd49a9b838d94acb356654abb5d65ae5bdb36728bff6c497c8955f4d514a2bad3417e6cac9f7df46114cbb6b58838cd93c3efd701009d56a43ce81731102a7d150e8c386908c651abc1fef836cccd42063b99f7bfa4de0b6387ae26b3de41a4a71d4be1373e01250f28294006f3fd2a484561cb53c1209556a6d288503f37470ee409a66adb5b4d2f95aa85d0d671befb1ae6aaab54d02e89d20ab56f59146552b93c9643299cecc8c480482a2998e0111478e50f2c14302c6e0c28cd2cbf330938202468989ee5f4426ac7d2213c4be7c4d39f8aaaaa2dddddedb30049287a7274b180fcf8d2c613c37b95f777adf6255c99ba969c6e4405da40213b83ecedbb8ac6255b1ac5c7bc44542f0d82dd1b25cf402fda842b660e83a06abacbf43322cba4615f28b8ae3adf9135fcaac5253f59a6cde8bb14c5465a2faa3a8fdde0fc708001d7ad8c9ddc391dca2fd6a5fab9aa67d875d6badf5d6dfe1e55d7e07f05bbe869f45526e6d6a79f07770f997dfa1e5c1af219853fc83e9b7c0cbbbbc05c06ff9fe605a94e1e55dbe8a3bc06fa93c1f7595947117cec055664f40fad4a6da377c096b903c3546f060e5b25f9ff48d8b5226df5a50f5a7ca5c247dbea840dae4222732c6bf8a51c9f8b13f6655d6a62aabd464325daaba49e1d8155781081bc09ad2eea63db5d6eaa294525a2ba594525a002623d8b5e3ee57d16e1dadf53bee7620052948c17bc10b5eb06e6205c16b2f8afba67871a56eeaaaeeebf6dc9c8b735b97c95ddd9652ce56ab355b2d516bb674b00f39058c08224a3e78f02024297dcf030c114bf8e009253a445e95ac91d9bb295913622796c8fe294de0f11ed1c973c7455be0e992b317c646cdd624dd8b3108fe8b44ad992e70f73b789ff23b7cdf3d8c0cdea7bc05be0e7287ac6e6a871d52defb1dbaff9e4a29a54d1258ca929761644879ef2dd0fda7438a7853239dd94802b738de237446837dedfd79c8d7d53d671569a0e298812c5b4a29bb069f97a8e44d77e6bc54440200000553150000200c0a86c30181583c2ed8f5561f14000d6a7a4e7a543c9a08c4418ec3280819648c31060063000122404244580dd11854192e065812155c86e2898cf2be5eb7a861768fca1b921183262839a67f06ed84b55bba4c20ded11a4daf6915b3445f91d245332dedf8d9493a83b74192da0ceeef6f8c2e0e40018993c695061d05ee1878ac108aaccea168f9fe238a4ea040eae9589c700d94b50e074ada848ca330aab7548905f2c22a166cc728b43fd05c8c5549771ade9f25dc2adb7f3326784d2baf77e71415afe5da8f71bb023284fe716a7f66d2697edee2a33822559b3776d4f1a2314dc6d0db3f1b85b2dc5dcc8a750a0daec1b5c0101de58fbc7d5e5466d615cfb2082f2adad8458c685416dbf685d1e55376ed5d7313fcf0a1466559d9d05adfaf6352d94675c959149509b00e2515c6404dcb00ebbd2fabaf474663866ed1cc2fbb2b1a77879dcec73afacba6053575defdaaa03badfe5f13e0864bb06190b5f58c1850dc1109abe87f7808f78f048527879025a49e9aecd812c0fcebe8b7a1645529071792024a50373b00b438d60395fa2418ab4544911a099acae2f489223a8a10e784407822290e0a02460b671c61a23c9e0655922e86f59d51c66e87d46864f5c3946cd529ff5d64b02c719adeaef807097556fce86a0391d5d37729a6afd0f00705e8025a5bfb3ff8ee1c3a8afe6685b4b4a8c1277bd3bdf7993a488cf1edd22f7ce700ca5706e2ed4bec8445377954a459ed82516cb3c927d439c28dacc02b0003d0ffaa1597e4cfb11b2cd22a3061274689bbd6311783a0ad87653082bb5a61b2ca489ca719104aa37ce83e734fe56ef022e84177135aed2f571e13d545cd8dbd13633d8da4e143a027a20f05487300a92619e2aba581ccaef2a32efb1801940759bf37d0a59b873b36eddde748d17b4bcac58c99ccd33caa951efb09c43418486546e27b613a8f81ca161f4544b94cb9e0eb51e13c0b492afe20c9ae1788ffe4ba00cbce52544b5e8a40b42ab7682a1eba60497b2d60fd39c275bf4351c85f251c049300715935dbaf6020f7c34b54f5f6a69fc4bb487a3cad46ff6edadb6551bf158e014049ba60fb41c2ed43c8a23a00a0f51eafa742386513a5406f0661aba0701e445276aca3dcc1c8909c3d5f45ace69742c7e63dae687cb70a77b987448809ebc81532ca02c13b3dbfcdf0f06b1edd6f74bc38a5108820db3889ea97df0a944d47fcc9de2e1de092e1596540cda9d82321baa465ccc8c59ae3e31ac198cc70728fa6a3677935af05d5b52a1e16d6dc6a75d4d0f9b931b24669670f0ae584ae4ec22271c6580d750a753c872bca436286d6c4dabd1829671985467a40e95a8bef86297a212a200f5df2c2c4632e603d63e22308c96c80946186ec17895c6211ec2889aa3264b28ec2f901069dcd5144c102a0e607cd2453acac5c60caac4c872c74ca26a7e3111b7e0adcd91271270f6380be9317d76fa0e79ef125d938c64a51de532efb3d67b05278dc6472b3a66c262ee9aab3163827ae7a8cd43c5e8d0680fee026878cbe0786f1fb27fcd1a0a34ccc19454be78eac2f9695bc44ff44caf9a7a5aa4d4be062a0a04cc6daec271eedd40e2fedfa91f23fb8bb6d7a9bb7d12a3875833c4c3dbdc3c58e8a279d186c18e36e24ec2eb756e6c92eb771338624688cc66ae541d2b5f0bed208d2070e0bacf3c296a50e923cc8fd5e0b4d0724a4d00a879b890fd4ac1baac59d583d9925bbcec3dada29c965be0a3e7dca6a853ff98abfe933dd524d20bec2a6763dc875fe44dd1a4b5cdadfa0344c8047cfc0bfa8daee5de6a4359742000733c01e92a070504b2414e2e60d8b9c76dd968056e0d011c0b6cdd37bef8fdb5dee15b4edc008fdb800203cb1889069e3a121707eadccc97b511ca68c1125ad31622adac513c5b899721b234e62c631828fc33b468cbd028f1183f414b5bac97ae8a6ffbfb494022537f529f0e48db53646848a5dc0458e11c02fbd1e39aef1eb1988bee33ade4c13e98aaf2e227eb60143111be4e0907d4b0eb14841cc601d02dd2fcca2cc4b20071406ad5c40847e14ea860420f8394c1bdbbbfd87cc06d27fd1ff272c8b9e8ccd078dfe24b67852f0973d49c01e5647d0e0b46d35ae9ca28a0455fe2112045b0dc5d3ee2db748e40c415f3cd6796a78e8708b49dc391230301fe1c1832cbbc60fb6ae18b294172f3fecefca7502e41d0b9c78ac2a762c7e9ce134c7e92e5791a6d2e966f971cf966a141aa30cc726339e4032584af567458d0c7a8d4fe7712031387ff4456fd1f1cd2e11f94fedfaa3101037bda7ef93b92a21bc852a436c3457caeb14f496535a5db91db2e0ea404d210505bb849b9de5b17709a0a6851e40190145f55ce8de443277322be4e974eb29418dce240b29a1789dbc2d860d037ee4714c2b5e8720b7327a781dfa9c10f6c434850488474f156c82ce6d01b5369d3a8df03af9b32ab058aa0bf4f3cd3246f1cd8c9a636eb8be87df066df4318803e9c49e15ecb6d6b114e1752cb2dd0ad809258329105e47ec119ddf4ff6eeaba503862c9fdac105d5f850b939e62e92defe69439eecba01883076094bd65490f84cee4e7cbdeb987cf3ae4360bcebf0a93b0997e420394ea1e075cea90afd3266a84f9776a2678cb0bec0f1191505aaf549a09f76f7ac7b3f94dafcfa9910b4309b3be4dc31c36e9de0bd76cedd690196ee7e80bb7ed10182a7dc2cba36fbe134923e2bbf20b92a2a1228b7adec47e9d3c7acc9d5d8284ab191af961cb45dee2edb8e94c951c179831a57e86fcbf5ea17da32f319002843644bc904032085d0824d995ff6ee0462e6734768fde2e3ce806cd2542f4e914d6d81fb83fa0e9db38ba4c39e57e3bca8b7a8d30b7906e658f5f4c4d0eb99d04c0c7522df2d6d16a9f8d59fa7f883ff0998ee903f4a8b01cea1a68e5c6435ba5098b7a7320404b9cbfb62d365a7021b50e5f28499ee111bba9d4d463c792b2eab1c756757761f7bddee0e28db85fd1f8ef6ce17a21f6075ce673f33c38ec3a0673c612b1640d06825335963961654873415bcb59c513d4d9ce43570127675720147781592351b58ff23970fd83b08277905aa28578206070e63c58d48092564f9e40cc662f8b59b8261c22c47a7113119a00cd572900e98ab40252fc1c138f638ed207d449a849c71369ce3dcfe3266cf9e319506e947bb07b933feab710eb38e0f648e82e6250efe7306fae682dac33d0fa8141636031110580bdd94a4be6d12d3284e42208694af78df07a03e44d91626d99d44d9c40515ab8115838f03690949812194d9bf1a527882c741160da055456dc7ad0c1ca724b3ac96a605b9b74069006a168198ac0d917c84231e3f9bb82f108ad9e1a1188f0a8d275b18207de7f68a4e5b2e31436c00318a392ab2091c2046cd9c33e79456d4e107c53f19bb2579f806c6c1567e6f2fc43ecbe51422730562803b2598194518fa5887209d0245e94ecbd25f48c0f87c336f932f90908722e1d77462a3e06d6d87efabd0a3cdb047287be7b16cbbfb1b7aa4b012199b7dbcda0b69057e276898b358cb951d66bd20660824f0891301a0c5745a0f055abfc0ed4507ae07be98fe11972d51d8a84bd5fecac087ec0c1150b61dd2735fcc0d63e1c1357b0797a4a121c809d4cec23f4c306ac1960939a0f0bd3c05c053bea40ad9783f315806b64f14aebe356a20345b8d40bab234a39fbd78e1ea21ebb0ead0a34b1ba3499c6eafdd674e17e4db55c0f6378f11707975163904226c127602c23ea039dac4ed7fb04af0e1cb2ad15acd43e5d9939b098f06932efc583e87befb47f40f1d790aea4cdca5c3a27b0ac848fc414966ea51188b484dd86bd7c30ffc6a5d5bf2107332d4b67ac8657ad4c1e349838a318986d6d814954ead3926ed584edd09ac1bbbcc2340cf76c565796458a955c29539bfd380a5fda0efac3120a769ec38352a0c0075ffbe9b76319d8278e5e1ecd80689950471e00be029f39a5d790ab082b3fecefba30c483f8844cf799539df4ca97cb82a0544c5de42e647bd30ee4605be9cca88a1b0bc02885d5e29f05057e6eb5aae98c07b14195fb606ab5d1cb02b92e187c8adcf83eca710cfe8bceadec5bdb23159d744dda2644d549a57242ed112d5db15d28c3e36262ad4be1e574a0ffe8da5335fc04ba100865293405e640bb75d7b712eca2ed1f9e3a4aef662fa204afd533e33eaf1ef0152b43a2145299852dd7a878fa0e048369c16f28ce35d2b301295000d26415d550e2a49ddd6796a5876b3c30735022f0adb42a67bfc397deb62304488e3b7dd78258ee1e7dd3ad2b689467c19d2acf0b20fa8975f1bbfea28af6a38d04997fc1e0f2d72e6d37f609532ceb74ba1ce0dbb47602ff6d687e19a642bd45c5800253322500b66794f7cb5fda4143e743e6577ab15f7ab0f2b511229ccb37612f9e56b4b19e1f2a1b3f57e288700942eb75b21d6e8d3fd8ece3845bbbb65d911da1f7bd5e3c8ebd5f11540bbfd5f145fb93d7afec53c5c3b60d1d8dc37e84a2fc8bde68b96d05a0a87c00c5fe784bd14d7269ef2e4eedcebe5160d15990de0a9e4d2df62ddf476596a4d2a81035d1b712883ef80bc2854df6f9454eac87e477fb03d7e39ce29005553ad85a6dfa5d940853f5376c16fc07c05a1f502124f5ad446d84b73715982516d0f1c99742ada41531fd3a0423f22b8884babc6cd45087264e0c6af3b0f8601dad4a772e97d1095951e1f7f18a1fab4de84657e18e432ff4af13a3957ebbe693327c10de0c21320ea17dab109cbd421028f6110140ca75f2830349fa809c1c1b1d2c89f9fa55e9a8961ddb7e1a3e83a62630203f7282897f35e895cb9cc147b6eb6a944d7f7431795db8579a9a089b5b264d9819b22727c6f26062322735b0b45f5b9668b5c09c915da4b529bf0881c281bb998eca05af6397a42306228dc8c394c2087568e54a9e001f5417cdf6abd6d8605d097a9b13feee2d8c5433318072d4a37ad2630f22644f2b47ac2ef370f5a044f4e5992a9228f378cd7b7e389d395033a4417403461410f738d91144df98272766536b868d7f9c160c163e5d2b13d7f58318d1eace18733a15b173c56183c7f6c54af96b3dcb43a33f43b9f83ccfb1807ba7c9a4cf2c9255f02f58433a40f11b8d8d2954cdca2708b2913e380a6e52fbabad94d11d657fbbc2961eddf29f3925cf0474bd596bc13795244030a5f83abc3e83fc93ac3fc3fa049359735aa5432996cd6f7df5cb241f4711c7a671a2978ad411dc5e6c9ce4d20595f59f72dfc4aa293c0f3831ec448140583caada00f0cb10411840a673ebc846c16ad78bc86b40640fb12d03b43a088a2105ca9dba1c40c17fd78012ff35990fd53966b1d56d6f1cdfe9bb548614e2c51a5eaca7afe603a95bd8ce572722f231741b75fd025b53746f7574cad687a3368f619a1f542c412303320f28f203ada00e72a4f66e760a1a8a9cc6356dec10960dd0bcf1dc57059bf2d06b4f866a9625d903d40e01ca2655ca6c3c71272dff6eb8c33de79c389eb6c1269ceea770fb11a769483d58d9d84bed749d7720f4ad128f2f52ba4966b77114daed9b9f82fec6321c010059b3215c4e7e2b02cf9fabca74c5c484e111c4adda63b59762804b3f8a4a8a9f500d295729a56444219da83b2b4dbeb7c744f3a88d0c931ef2142bf2b98920869718e50f69921aa49501eb547766483c21f98eff135a8780d62d4acc8bb1ca9ff343fd3d1cae03042736f8107ec4270fb87e0c65d2670308a648614c2e618b930cb8ff7ca7de4bd0db22186787e6a2d26a91c344883330a26d0c7cde771bf26505f8548a4ef6ed713310e7e058f28d19ec8c5087c9de3fed29ce8ec248d902355e2d30dc52235a2c298fc6e6f9006f72f0e988b7b94f5801e89e8d8c8272285553fc64f09293500c25dcf71e58f04d7bc4ebd74d4603dcdfb0b5e75f68fa03ef3766290929436130e34d2e0831087e17fbd49e6b534e17f3522c394e88b4583b391ac0b5d49f75823be4868531e0dbe73d00810d6497d8a6ae6e8dcba84147d4920dfa9382bb0d6cfe6e66c164300bc39adc8aa110fe318d305124489d2d13d85c44aad90d85960d9a52671058da088cbbfbbc92921a0fd1fe98c091ab1fb8fb684b04208715a1e2bfbbcd24ad45b2507c676a72bf33443ab6e3ec8fc430f2b61eb115f0999cec92fc1808918f52b1925c72c6fa2714f684be8d518b47fe18f0260721c4a2370d66a86b4887f2d3885ccca3ca38f984c14de32c0454ce63561e327911c232695b8527a94e40c268e88e911680763f4f8188433b1487614a6cfaf491379bf2955493f394555676e8354a3e580bb997c5787813000fc6f218312726d3f661d2b8384ca9d2318a1b23f8aa8838daa1e3b24157133564f1693edb591fc87624d5944238ea00dcf34973f52e4a81a326a6f3dd3ca675c3ce33043a3c9940553eb0a460aa0b8e82c1b2c367553595447393a8d8bf6a4b26063c6c41dc4548c685cebcd0f33bfa92c4b479700b794651a435cf47bfe884bbe2c30075cefb8309b3c3beed3986357cf227bda18ded69accdc0d876bb42fb8f5d397035a2cda5b81d95546bbb0556a26b137102ecb025a409267b1cfdacb9a490d0b3326ee4793e3deb9f3ad41c96a3e33d9e4d03980021e39df42e3fb42d5ec5a37f9889424944f0f36026cae6a979099500f5840716bec771b5f7c3db33f7bb9ab22db33c20f524555327cd3ff909d290d4151037bd69f43bd9aef1587206b125c8da143a850df22c7448a81bb19fee69cdd746d0ae2174d11d43a60960d3cd37a6ec60e208fabef7068007e5387433215ec979d8b14b62828ca34ae667d4d603406a9f008ad9ea0c43e2422b2a77e75a9a9def30f1ea248cba57029346999cf524d153efb79f3fed3493ca81a741ef72b918b2b089e97177670338df8c397226fa04c6994f05e327efb7368e4277572bbf21d595dca851736222cc6300745f0229a650a634a779060ee711035fc558c2cfb95b22ac9fca7845cd3518b8d2206bbff04940ca1d3a8666a55cdcfa0badec4843fafb99c67bb9449a5e5da51634d3fa695770b71274301013cc4f7c3a0101dd2ea993199fb8ad16d881817c54abb60757e2a4430858666cbbb944ed093be87aea4c8fe5af8d105993ed0156e4e4e3829e59130337842a8d53f60ba2a07b29a69225a72a28a95109fcf85b4274a126f3d8718557da6fc216079a2c48b261a03df6a8391220b64cdf2c4c12c868c1ab9cd604f723b6da80f1581b710dec06c8cf4d09fa421a4215f9c3af3a5546276a8e3e7806613b913d57afa1ba9663778af9007c6105e3b09736c42d7e362c053f0063a04e84f01be6c068cea958119b0e2c24806b8310da8afd5330d6499fc6c7c9a458b24225fb7cac2532c04855b4fd57373adc72025961e4aeb0c1ae39c1d1b6c3b640a22a85126547e981006d77d7901f64a996a91984d60ec27ec667b19cc8d6def8730df384c5103bad2b33db5012692a18fa28df52365b5423e499f0fbd991886a03a6705d8970b623a93d969721ad5f38594941e8c80cdbefb62a2f7202274ad6514f223e6322d19c8ef0fce6f8af3c723e3afbc15d2dccb396d3c533bf746229b7239295d898f59791855fb570247cdf63800a9389a1b7939cb3281c0355aeac26c8e878da19cb534db3d095c16befd4d752f16101bea2081d2bd8f24f6082b23a69822d424be2b450bbd25b005d65a82279ed69b5d0991edae15979232ff277fcaa1911a31fc1c9e5810a8d0bf935915473795b8e4d00ceadbf74725f6c8944ea37de630e7488889d9e49aa23228a4bd5ee0a8197c2be3165f0c81b1e856df32338ef9c6cafb28877229b88edf166302dd5c838fbc5eb5a96df3cc636fc5473b3bc1f3071d93e070b6454a221a6acffc955cfd647ea288bb68d0303d1bf0a13ad149d8426528c2d16f59012414c1538f14214b2ca90f92493f59b877e60d4cda032d8005032dffeb9f6e14e75571e4736eca3da1eead67f1072a9caecc86224aa7356c0e500b6dc80b1560088339f1b2b9ed6e77e0926310239f32d0839613bdb0c58df6794e8b7ddd5d234cf6badafbcfa84f45686531734058f5578c8e1978823da195361a521af561ce7b4a30a8c1a8ccbe31c77e17e90710acc4fc1aa2f04094ff1bcac2842cac70568c41cd86f6f39e8a1b17342cda0c54525a530eec471f9985e58343c33249398f59364827e3a07686f4323c453382ec12a3129d4268a6bc0de30a55665c43656d8242211c11a45e124afe712be862463ba194e49d5cfe26e9b286fdb2d4988254d2a08d2c68ab4ae21cdfb28559f84a429dcfc40f9e65a2e896f93e8b23b371ecb1f499fe237041c615ec84a8425a2ea304b737697c8bbf338c799bafa0950f6b9f139441198a5ea8bbe5427bab2b5b8a2cd7746cfe038d61ff047cc19e803b72239434a5fdce9d8b8e93e183694587f31176d554e07a1e2fbbac1279524e349b4f82fad43647f03238c2d241babbb4fcd2a008a11d6acc5594fa0127947a92bbba510e34a6f38798eb7d5c6c88df7b35bf34429d7aadfc50643e2b0cd2ac7b9e89ec78d32a0496628747adc871611ce460a247145750adc6409ccfc438a41aa13b4b6b374c75b1c4493071ccb3768e23f15816e523e29f225bb178a5933525ce7c1cef306528b09cdc5fc5a9393a16d84702c301b85030201d64dba859f1aec68c34614fb0c0dec0b744ff284e41c514db02c728d052f1fdda8792f9bdb8f6efec31a43753011fb8f8920e4f2b372d5ed0aa7b9a9262df40ffe1095b662a08ab95df0d8d9beaa01152233276d419c37ba8ff521ae1bf2a854fb834d5b8f7352ac4b73c632f457dad6edd4eb5d90e1eb0fe9e6b01221daa16440860054732c1c052035b0388606f6270a1d4bef140113c5c4318ad09d8dc0cfcc4446225e5b795b3adde3b20164f253c74a2d978b773ca4ced6161c5d69b03826e1ce89df84b20e3e32cdd13a4821d878367fc8557db1f0086792a0297a46e7ea6f3586be1a9530b4f462f406df4e9a1324cbbf1024045c7a8fced8249bb9a7b63f4e9a95ec3538e408a74b636be6b9c52b0d982de74c3f417fd065f5c705b30715c042d220e815ecfa06f354fbe931f3454d8affe75c50d77e9e3844733e9dd8d734956f9b47dbaeea509082e395a32d739a287798959fbb796b8ae26585bf62f5ce5ec750508367b780498b4f3e13df38ba15f9c38e77acffe4755a1a4fc0ad8e6a95b4b3bacc69b7b2e3a84b738060a5be9efd65080722dcd20c17eb83e112b449ea7747b3fffa85ea3209fc27601bf856734e1c337f2034e057c72ea6df929eb8982c724155b700d3ef50f5fbd3c2f7f68f21f827ab95847506d65786e211781ad689caf25ac22baa045faa833100f5b8855f30f0d6926a8ffcbe920e2e63280db8448fd0af1a09f1dbbe4533b8763c5ccfa9e9d6d4ddbd3e476e79e0fb2f805848fb9d847d87a1d9dc56206264fd723ffd31c47ad29f2d06fa19d02aa65a32a44a7ee814b41368d49a1a422ee5b6c3a1c8733a101f9c5e6309ca5f36470e94d3253c9abb473362900e656114650d9b8abef5d9f8eb110a991261385a0b031eb1eee5f24da6a0396a4aa59a126406ce917da3f1d12cea13a14eeffc1bb7f81a02c0991172b2e9f78c966f9c45621187b304a5f2305707a34440a7d25c6e8e173e87729c4d01dfae91ac9a1c63f2c769a297fa732c88dcb10344b39e07099aa96fac061636033422568f4cf7cd8ba1d2636a4b3d7ad8071fc9838456bd66065904c5f46372cdc7f628593c5c6a080e320b43dc0cb1142779fbed0ff0595b161ca03c8067912f009ef8b7a7ec38653420e729d8e66343588a0abed2b895b055ad663aba6c2f7b9cb617a70138b8e251173521ebeef7cf43bd04e5479b645f6b5890dbfd27a7a726405a622c7fd01e601292931230d4f2bdfe4ba1d9818bb05f9f7b2b17a9126139bc82cf8b1f92bcb387f1e7dfbd7bf49e0becb263b0f9c0d7ad60057c260a2e058dd52b05e5396b3e4f5e223d2ac9c461810d8ba1f58f0c2324668139a030d75ac4c0a52115111979620252c6c4c2b3c72f0325a8a4ca41128f144dcea183ff2393fccfb20cb012b2990f6d68e42590bb8569d8c1b971aec1110b030465bbe090a365281f5dc542552d117f03c51c072b4a8325662b3f40ce5006e52c8140030f4ddfc1e8b0e5a09d87d60e81599d0b737176b3b5afba144c808472f6eb45037f7e7686d1b72167acf74d9738efbaff8b60a2151f2792368969ee54558263027c0bbeb0b8a1ee85fcf1ea06803ae389eac1249cab2bffc459b4ea206e6b72015c59daf0180187a2321c0b1b6ede650b5668aa922c52488cbc9c823cdb4eedeb446e82d961745b9e4b34cbe287d11ffad66f25f566cb98d53d9ff1701e452fdf081f92a3d57222506740f9ce2322459afec26f265b11ed3612000f75638633fa873902e6eb1ce4157c0247d350a37b0604a5a6a2e80bd3a0eaa1b05128455c9b4b3aa36383700dccd6702e6c3dd8773ba4497359e4cffe915c7416bd13f3f863ccaa48d73e0132cd6a48059d84374792628dc37164396e775876d1e812726cbe2791c2b2c9b803046181ecf1df559146567ea04533e47715d83bf45803091d096a1b65628cbb0f6891e47a003aadb52766b0bfa37fa28f74aed14c0bdb2543c57222150db0287e3687f5d1d127169104b11b862c329ae44289e6e38cb996c2f3eb3316c80ed66d96a95fb0c831abb2504ee221d9e25a8be02d8f799a72896ac0098d892ecc698f75619eff77854a48099084bedffcd6d48a210ded20c743512ad033b46ad38a33a47e104f314f36a2436703f20d95a73c0c8e04bc2caed8ac068b5865cb65047caa127c67934b0003a79748ac8074249ee9d56ae7c12dcde0200a28107a08cd52f68c9ebc8dad4d8c22a1f5624f46537c7c3702dd6d821a6392b74892ff7d41e0743cd98c7484d6fe79ecb79f98827d873e06a928fe064717fb434c791e5b71e01895509a8458e13ff779334ff45b0de52d1865d091abca1f198bf9ad91adccdac70ea51db7bad5707073d4ebde87919ad32092d866d141c2e616943063e02443163806b45e06bae9d369a53cce10838213ad8921cbb29744996a33c12271ea4c7de9df81e5504e4cf65dd9fd10835534467e4de8f2e4759421bf12981272676ebb521c94d41fc5bc4a4b0891de0ac26e578285f64c21f79c35f6d152dd361d8deb098d8a8a9c5c80c3c1d40a6b760e2bac0a170a0a0c24abb6886add8cb11954d89b97ac6bd29b8287fc2677d71fd020e8aa20729a7fea5ef792c65cb624376638a5ad17c420f7a1d012ba5293016c69df989f45ac4656387fa177f83b69c56a4ddb6288415dc18c1052a7b933c644e1949e1cdbfa12d36a10f32b95e9e016588263ac5d104f4f814b3c32387b0f8f9532ee4e9ba8972180f8dd101bc79984245c9e70e305ad80d6b673802812cc733885363c8855f8c6fef576a0c6c02eb3706f711abef2131bb152151bc94839259f15abfa285da4470346058f3d12a206bf1db2a00f105160b57e132d5d6d39631e1610b5bc438aec2923078e5e40063ec73e0cb9ab63cf84cdbf8e54a314cae08f9db0a6e46b17d3fa7bbcb0e09433b122e8d2b64c67315014395c86159b133c5642a22b27a9e4ae902828e1037bde26888cf2f2c79126e5adc4300173c45a886ea72c856e465172689322cdcea2e26a41858c558aa4f11125feaa03e4b8784f1ba86ad375f9dad605d180c20a238ac8471a1e924d47737887e4ff96b6ae3a0250d0e59a5c46ef85852c9b07925013b46186780a650438f1d2924dff3d00d0025bf1e308d22a21740adaee6f310888abe663efa54966c73f5d453c5651a0909fde6051caee34ec235b0f2ef8fedbec5470c23c1d28b77caf928ef260309d3b637c1628ad7daa380413cbeca90cbf9d80cde80fa0763dbaa91f0329f2d3cf8377b26cbbafb404ff75cac79364488c1fb9a7c77de8be18ca797cb49952c0feb693ea1a625e3997a1352375ede97e74a756a47b37f957f3641d00f71377de8b8a715b001db20210eebb97f11a5e430f130761d65ef02f9d893325426213121eba871d0c124368a9bf784688966c1384ea38557c2d265401a09f78afadebe6dc93be54f5cd41c959fe9242fa1c14aa28e8ca82ef2440758152701b46746090c5476dbae33f43d87381b975ff3bad4b0f05d187f3fbf7e25e00576c46efd3aa2c3923afa0a20da1125f1924f01609dbf4f4ed4304d714531cdf0569c5766b604e86dafccdcc2b8318b805cb52851113345fc582aa777eb6111a1340aea2f5dd885bbfa58181520f5e2bc8594fb43d42d635c2a5c8d31b049507db14583aeffc0ad3bba67cd003b093bc91b2f41198c601496ed4721cd1f595c9bf15061614d4e0e3d68aec51115170966d56cf0a7f92adb2a725de541b35f18b77e8f073ea2b0bb94c99e2e29834f4ca6cbfac02f14f3f6a1b02aff861dd4af1b68c56ef2378a39fdd45d025849893604fb58470507f7ed66f7d795f0137553abb10d1705d6b734dd85504faf9d96ea04c48af631e1357dc56be490e0dd00f6157ba3b823a0437924e34ae1c2bf81a62a619bce860984aa64458c1e8a9953506966c83059ac5f29451380753c2e9fe3b7029f58a56b25698d5db089e189a56fcf19f157dd9bb328bc7a29bbf200287474db6c957d2442865e6d01b8f4513442e12706de8a8910b1f9009a17e7792ef70a695f5b08b0b229ea8e4a0c4ed0daff006fc3893293cfb48aa87a6b177aec21020c247d46cd8b4a8c37b930bba23cb410b5527bcc6b38dd3681ef26b15619c849bdf3342bf1934ac1e99a39395851be6d9dbfe867fe7a7e5f3ac5ce79544cc57a8fdf674e9bc5f59b1f85247d2ec06a12c5def23fcd99629a55c3992fad2f3ed7ac33f8059378e949a66c56008551e4e9830e50efebe4b4dcee95dacb3630824b2daa92173b8d53e0a8422cef7267df3a2c1270b2e8317553768d8b2011041ae23276b146eb1f09781e942c1fb8204b2722633b0f60878c4c745b204a52802af754c1a218fea2a9f962d98d300d1be7a9b3aca6deac92da5fc01cdad056bfaa8a337672f6fdb9b3237aba8d2dd5762a797d69197752078984fdd8c7fd904183c44cc6ee1fe0906b495de59072f902c8eab58c29b1a7df8da2eeef5dfdfb3446e8af7bab6148e2ef48b56db9ceb1b4e50df762f3e86305a468ef2639df8daf03677fa0f4256c3943fcd1e79ff81ab22bfa10d492355fe16dcda9ae2e482c1625bba09a02c10dd8056dbca529642de4c2d0fcf3403b1cd06e8ab23496d05c04667850658cab20f6186916f4ae306be0f1720df4fa7ee577adb58703885a06cc50e42902ebe223e6a757674c16f1e0cabcb0f8b263f45458f41a645ead985574b45ca3760b4a416bb8984794aafadf70915e0259b7838b5bca47409968da640db43e2454728e1d38b023cdaa0f5a1e020b167549427603188cbc273daf57497ac40c51b17d881172fd24382394583974b264a22dda0d479b061eb1826da8f97385905263469f1ad86d52f6e8b18201f6e1238f050338a4d9330ca4ec7bc834df6eeff83de48d7ef2987a7d1fe6563a6a2b86fba9261285baccbe3fee51e7308e307dfb85c7e910d08dccf8a797459f8d95a0ef2115ab11fe49f5a55f812e96e38338d8518a8f97e82647167c70c0c59457ff8952f05da6adc887d8428e9a6d85e277a0a14d32ce10fe44789af2c7d42ab1a9054a9c7009d22b344e5a3f79d52eda1ec9741968b67ece52acc8cfc872ea719def49c98066c4adb80eb36dd9f18cd72809e1016bb37554f7440a873ad34fdae50b971e79e80ee82f3574ff2093cdd40c0d214ab8b9233600253b4665ac969e9a9515db952d657d427778795f21b7e761b3162c7d1852ca5ed7e8159910eb5217648ac6da4e4fa9540652df52c3c8bfad80b06625b6229f682f03c4050b5021809f11af1584b4424935b112dcbd63ad092d2b07ed4b3b0e1a65050291278d14629ee98641e4b6611067e3e74980963435071cb1636e28c6a34258e211368db7458ea724027c65510d3ba8caa0bb686398e974d0b69ecb266b15b30795227c0c832e659e2fff3ade844eac1c96311b42ca6a58d6d65206951ed7c7d9d16ca3a023dbfb1af1c3aff0119d759674356156c8728f2bea9f18d803aed69f4c05f6428a397b9a0a5124c48c3a90283ea5983ab2f1d09400c50ea72dc3aae6891208c5a399566bd0126cf984427900f61ab85d552837aec72ff74c48adae454a21f7891a889b7cf4a594c09f31f66123265e54ce90cfc1e7612d4c84a74200979083c78f656cd86b3b97b9bbeb4e4a688afc997ff30844d0d43549f11caf68db999f9107dc42f79d3fbe9a5153ef941781a1ba5d44e189b4d14ad083f1d09089f39ca8c472df1e2286add6a06cb426cbd38a50a219c9f5af57a0f3b835de6d7323beec522e315e005316004bb45345dd2d6251ccdd441be8478a802c5881dbe9256179fc6831f9807baaaeda15132d6b97da68b4e8b95215e8b5321c1ee2379f0ab9409b21bfbfc5a5bdb4bf35d0397a55707d87d634f26cda178202d9cc24992502d18bfc359cc1e459ae44c2444cc4fda283f0c84406e23c0bb6019378e54a019a97046e2f20ff2788f4114a7134cc464e1c60429e4cfc0d95f5e578685e21c38a321e1c1b62d5914cfb07b8136d2e61a022abb2ea93675516ba82c1890c86a61d85e427ff29d3f2643d5044781e54aa051e6ec3befbdf83ba550b241830c2440bdfe5f7314fba541ea5a5bba2f2ad9d8e9b1e9b97029a218c46738798a2b7260d3f8f3903f0bde0401943b28418a2106636b0aefde864f1b52bcc095d9517cfab77285f83e515f34673987b3050e17c3d88c228ba901fdc986c7123983ea6a5b9accc0515975b8aa1c565b011942f70062c1c0016f07c1673bf8138048133febb58eb6a36a7b78769cbb84edacdc9118122241241245c4c71955ee2738dc457d13d380b24f2e1064cb090c414ae343d0f23c835517c25714b0bc29c076affbf7a9250bd48b9dcc36e0e87e2ecae5006753c6106c630eb94f4c91037a833b31a020aad472ead40521474952404e962ac426393a538aeaeb8f70878bd74de715c2fa304e230cf0b8e2d019130c3a7ce59f4f07d2b54a87edb484a922899fa0c2671cdd1d33c4ce95c931f35e667d498ca6868d916a0105d505656c81b204bd05faa3adb4bfadca01de2464f2790438c950f99ca8d4db3f297f9fdd74f77f49964151d54b3ef3f84fd6197b07d26f5dd9663c9fc4f9f49e92e08102e965d5ee8c2af544c3285e3397891187a7f1f285f4be82d34b43f7f59808fae53cfeea077dbfafa03690825799f5665e2b5a6639c0debec3d472b1a3ca12165e729d4b1de835a5896440d3366a549bc0876e3e5b478313e81f381d4c26834221d5875f53264b7d8921efe5e930192e8f5d7e62d095b20241716f0785b433adc84d8f3abe02a333274f1b8071d5fae9cde078de76b27f0ad0984554bc8f814821efacd8a49db0bcb51e1de495f1a5cce76c0b580b1d5499dd1057c55270ee2f10584d3e6c0fe65736af4140ffe0d2b557681a32172e36ba27821a6b3e215164383d5aab81e2463ce1f42ff0bd17ded8ca22f8721603c4c0b18e92b906c0612bd68a8929c556804915289b1f22642fca26a44386dbc5c4e98fa4593db0ae1f9827c9b91bde77d1b459045d1dd4b58eec510b76aa5c8df7d56568022b6d6eea4937d229cce6a14c2c5d3d88d190ff2c8caf766b63f3284853177e5322b2d73d82d49235c5e0640bb95090acc15c4539d3dad4193211a21b3bbae7b682869ca07b855c3639b1d63f857370cb11c3b381cccd027c165bd972f787da50aa2c020e0f52ebd10f66274769c880ce0243bf113cb45111273a9086b06ac311cf650dc824104685799a0390085db8380da6b8417030938760701a028e238917e40e1f546b43c8fd45f906838c3c3d240f17147f6f7d1b083b7df5fa0e4510d27eee25e0d69c0f7aa0a45b3122141818b54f43c16de2904064e76e41df5fc3c76ee926aa80b8cf3e63b38b24b60628a558a4374ad7f6284247153da6ae7d11a0fe6b321f7729feffab455003b20d808c76abb0919dfe02114949480bd98b3fc88e0b55ed6ab5901688704108a7b9f4eddb0f3fde570601af781833ea0ea07163e04dfb07f58c84079511744387b4c3a2bc78f9b74241efd1ea7999f16de4e4a2edd6bdd6c1d80a82d1617c27204a09557d7c31c13f086bf08f22bf3f01546fa5016776cb5702c20b3a36e2b7d279269d770471134b60a3845608d4e86d3b0a0a58e298a9b1da3f0f90cce87495feb23b74cf42d5355aa5ece936ba1d9383970e632e7682630d1f2358cd274b4d1f6262281fa527c2fa363ab415d56e44a438a8b4d89c1e226e49b6e7ff1fdfafc83cd50407c08ef9632312db6a42aadf2616a6594756854d7c38e887b8b8a9e3bc34d204c2e71e39593191a68e0fdcbc66d524316919ec27bc8a72a213bbfd09ce5e1552c53121e740bcbc8429430b9275cd5c81875435b8cf57434b9e8413a930222d84cf9288c3c622c4ffe0245ff868078170969faf7a7a6889b001ade13d70a14dc3122a50615a70b457f00d2206bef5a6c37106cbdb6e014f02bcb380ecf602dfb7ee4c1e0df1b5950b5cd6ec59bba7a9cce23b1d59099daeedfce37c55105c948975a036c5aff42ed2c04b991f45198de1d507dc3df99edbb6c693ffb43aa3f050118c8d878d686cc607be75c10f02cba2b77e8a4b13dff3500a158eda48ce5fa9e9948e35b048c37ecd89211c71f6d492b4b2f9a9c4befac0cc03d6cc6fa67e4a704790d8948a17b710ee85ce85eb5397227909fb27df3ea9af00f59237cab8c656865804d9b52f344bc5f4777eb0e9170a6a0fb390093baa0e96241bf5011487b66efc5498b6e2454b1f58c0e206eec4e098428b8987ea4eb1096141eb961818f716ce955ba53d3f8b57aa2f9e5d90a839cc9aaa57d9aedfd62aad7f662373cdc33648151873ece8df0b7e8b726cdc8b11f687041003f4e82aef2f28d4804ed097f37432e5346b32c5871c6fb31357d0c96b11362ea35db73e4204c541d73f51e85d38e404ba646648d976ea26374beb7fa3faccac86d6033a1c50816af238c84cc571ca5594475932ac8618f1596116e2e7e3e127329878a25cf8b44cbf005c203782c239e6fac4080022291e122cfe178ce8434fcd3ac14ee8949d0e223ad1cef8a6dda2ee788460422a63baaddfe950638051a3d9b92772bdd1db101d0eff330291a68a278224ac93a545b4b846d529b49495837ce2d48540e3549223594033c4be592924d9ca318d4cd5026803d1d7eb65f95a33528842564309883d85f82dbf83097b58a57512c500a90ae2396344c2e7d3c77fa461f34158a79ae8678ab443791cfb793b67694005bdd7159ca6fbeb84b43b7e2023143b2bc3cdb401252466d50b1522ef92fb7197b6cb1c771cf3d9ba71ffae3c679a2129d82d2b611589f27ec36bf0d3a516e972910a89e5ab9d13f8d2a3b182df152ed0b2a6152e0a7bae0c7829b8c4398109e12e65407b1b6a0e0537fe00fbf052a1c11f002116ba82823865136901df2b7340363cf5cccc2632b7647c53aa474557cb64afa76f96a684eab4bce356ab7a46f0626226da8bc46ae0db1130edb4c1d7f6b13f0150650f1f543b9b84a294e9b4b6ba674401907f69c8364e8a9fd418f89d10d53d2ce5b409bf556a3e49f43b10f28e196bb9245158eef8f1220abb059c8c566c5f8dd89d49d9ae1fb435134280990720de1e9866fa39321eff354dc1ad1a9ecf5773640628c390d775482d5cde2818e77d2e1ee9056e00f72f26363a3d0e2ab8ed3879d29e52150b31361e0d3833ad9ae60cf08865face30dde73d2a0035ca8edf5a1d334a7b7cbac2985206d6a1ad296ad8dace65baf8069f3dab2f2692825a6cd4f52a82a3558fe8d7219ff607e887c3e8fc20d9c7e85effa38fa2179e11074df17c8fb8e2b5813fe38cf8b6078575b51263cdd1ddf102726e531696e7fc08023c8f7c712a8dd286c1d303592c1fd6a7593c3a7ce1a787c045b00a7262c686dc2ef9f60093492a7523d5cfc1c07acb5a771f9997972b1bc86851e1e419b9ddd06ac746fb94f51fa56cefb0ec5874bdb93302dd0ede7b91a640f3483c70eb4320edae09409c5331d34a22b78e1a47eb38d77e119a9c7a5d3adc185ead6c8096ac9899f23f1411a0b53ba393156db157c3f27b88511dda9acd811fc75851c4e2aa00e14544c55e0d581de74e8b575a0414c21c944e9381d9049a0e831c065fcb3f84790d09b111598838d9770047b03a6edd27464f6430c3d1d6619415a801facc6ad3b149061582102f570018195c6c39e4a9c9bd3619cb3f230894a5d28bac23104b7092e8e74e99aa99e1fc3c9a15d216a682925d0cc266d6fbe018284b288df27e888b554fedc7f10c8177f7c0bf0023678386f5ce97343e4f1e15e3ac21e3a86bd81e2f865e2469f38a32d2e31011c0aa4d78434ebbb3e0724f846bd5787d98d3bb6046491ed518d9b331a3a2ccca4de4a68b25ef9f73f5617e9fc2e723f8efb66836a893cd53f2dd129e43a268e404518402679eea779b5599e549ebfc8a9abe1d51c653663d7361a10f4602876c97f1ce99ed3a6df9db039e5d284f7b08d9da26db8d1840a2c52cf74bbf45e82752eb926ff3f8041438ad6bf196c9bef2b70091d7e04f193c84a4d8987ba5fcad8f14840e10768f62e5eb3af38c564d0c48befc7d2e6f14a4ba0fb307e9b76f7f2a35049349282ebd7475588c2d96d231b8efd01785f646faa50765eed27d6e38b4a2fd9592a5a7add68d1b3c2baff2b13ab40af698707709b4fde083dd7c38fc70bee15a1086e94f8716f4d032d87c1f6da0c7fd92f1ed205fc5ee40fdd569ee1977ffb8a081a76b78283ac716b691cb8381ae49a97b067359b6f019a4fd53bd04e541379b02b43a3360157e3615e031ab915d1be38817389d376eadd7e52a6562b5c301eb609b59ff55983386ef1536906a5552ff3bf0de0c364a8fbf26f494387af142d2f6e256a0b5cf993759fd1141f649a0586696703f16837fc530017f967d0fdf1e3f00bfb5c82661dff24340786285c896b618a316f2f740a2d0b0b9da15a3918e9e735ee651f5ed814c40332e2823f1916dbc236ba76b4d0ff1fa05fccd902ff48f0aa8111f807155723477fabb7578ad3e85ff8ac018831039249e433c4d06c9c2f45933960fb7d24987b97cba4a3862baf98481efa7beea19c96d0de80dbc5cbd9a87100581b54405f6f53f5da9b254bca8bf1a4bd2b12502b2c91ec01000748102c021a1050c043a10b48781b289834bce6703ca95b7ebe5449c0f1c47547ab79d212e901032adb6eb83a894d98e37158571dc0d614099397c223407fee07b0e76970a01274a8ecb97830c2ed83241f6077b72a8a5ba9854b31390479d73b4ebb4aa8a0c439e686036074b87f6329290b4df0d1e434abb22306a963a31ffa63551e1324ba90739034a3fc39c7d748c451bfbc5107bd97d144d255abf79207572ee6b3e1433195936286a10d1e11ec80381701b7a282674bd66a50d1d283331a27802bdd57e17382866e4c7a7c3e58d212f8529e9f46209573f75fa5cf4e6dd35907f53ab5b21b1ddb208c84107b4ee40005c1cbe28c183fe894c68112dacebe47d325042099eb05453ad6a8e599342944a8f508dea18e3e55ca8c18095596ad82e9451a4170cc8cff887b03dbcb18ca6877a6de60a37f5560788e978099d24672192fba8038269eaa3253e4d70db6a44484b6817b76193b01e6e371439d76d116095a104563adae18e001e86be4980a3bfa0354dc6bf7ffd76b383e77913f00e0bb84cfa71da11545f33f23b9d97e138d6e65e2bd7d3bbaa7a87baa1c05e05816210252ea7240e858b5de33140279d9bf024d099cf2579727afda8c9a2343fc4ac3f56a737d8f076c70b9733f7e1b91980474b03cba91bc7a60d7c05dc4fedd5aaca7507092bd206d57fc97231a2c7a9b019851bebc4032062b1b5dffe29cc6db9b145f5701ad439d3dbc801f13bc0603101e34644abf16ec80479c638e77968e6418edec371932e153ecb6bd7cece0c901b36a9d792799f4425f192a09da8e1e19215d76671bfbcad556dd7c726ea78f7c44908a3a030968e749a51a3d2dacc3b5eea44124b398a5863cab73969ae3a9588db6418f3c6c4d76a166bd76cdf37a059ff4bac3f87cb6ddbbfc231cc5017101bb0024a27afd992652bf059f33bf2f3037acfc206c88721b9dddf3181190c3ac812567c107eef18afe71fedb1c508911a9994a791156ce161721a1837eec75661f21bb2484686b19991b46845fdd73b7bce70ae30a463ff58c989200dbbae1f5fad014a54cc109bf58f42267551a1f695e56c6997f058dfa0b495483ee723e01159c0b3a46d1c219286e66add52e22bbd506c75881676fa8cdb3d7322dd7b9e84d93dd7025e535eec3410b1dec4081cc7cd3cb9174d18a5d415d9f9991396f2fb1493e951ff5fca0bf8a718b1500d14e6c3670413e0ea21841682934702f4ddacbe402cb99b63da8f7cc387d47ecf8c35e3239cca022f9e80c22119979de0e6066dec1a33dddcfebd439b337b66b70c016d54c318b7211949bc77fe212b237c324e53d73a1faf76862818e7cc089d6fa9cb71c13ce7bfa48706a8e1054efa38cbafb7c392dca69fe3ed39aeca2f08f1aaf5d6f09bf093439803ea5aa6c8b0105a7aeaf507707992560b570d2cc9d102667397ba95662e976cf06e694bd5ae70d96159b51ccad0225e9aa46fc37d028eea7232ca21bdef4c7849db546799ffa1f2f58d33088d2e9a7176d4589746865541206864309d4e090ee14b533d2250b2a7fd9d84f9b184e16a653cf93ff028f2ce805822f0863a191122d5488912bd026d4b72db630305906b2ff0b734e35a724b9a2cade11196f03b610b0fe9227864805ccb7cc50d3dfda4591092ce1b205c5496a58ab6d933dabb6cddad9cd0ca848ba681849b7670b01f0225cdb36d10a8b05d8721ab44ed4e89d67b0f965d8aaf843952381de82d8b2e2c86d5fbafadbf6164065d9a9edc2cfca84c6bd3cc16182045493072c06c7228b90bbd4b453a22df9a6cbc1ca27e1bc4a59c1163d921f604017bc24db500a05b6ae801595f776a11f67ffeff2aa206a28ff673510e1aafcf19cffaf5c56c35e4745a807ead146313cf15b694a06c66e8fc139b1acfd3fcbb87d3e9fcf0dff959d9da6331ad6854f7f85622cc6a6e8cc4c9436ae8b1ad9151520351b51f1e36abd864995264acbbe008b580424150cad6f96770f3889386ad32515ef592a1eeb5aafa3688bc386672314e341e4ccb932a9806db33ad5a1227f86e0ebfe02ad3310cb31efa66a0f65649e47a6f7a337965178c0baacf6d01f0b93697bf4e6354569eb77e7d57cfc3e980bc35bd7b6447e4da09289fd5fd7e0b84147e5436b05d82e03edb3d69e5da6a4842f7739e76197bea9ed1638155b8120d50d5bbbef6b53fdf855aab51748586a1ff3ad0a569c699147b8c1b86ccbba510873b179ac7de9544db382c48e2a462b56080da9cd9b58241b23dbd7c1eceada3c539b35fb42c5e26f7ec0aca91bdac522af7befe090b77d3966be3551e3b20ec02235970413698a51fdb20e68a86882746b8cf69e8c08cabf9d4471e06c7e10df808768b64c45972ed623196c0144348fbdc6178a3a04a5e25e23a2a7523aa143236c1428fabdced1c5856e9a2ba97fa408c3ba88b3158f2669c23fa6a5d679d4b2c3177502c189ddeca20c28c15bb3c3ce3bb35255f3b4dce981f47254680d1b5e4eb20f83c1dd605ccce8188dfa24bb9c2e477df4eb99394afd2a13c194213e04952c9995475300d90d973d215be11650e90e0083d78f6fbdd641b48e731f8e14e6d1efef19be7eb8d0648a9cb8ce543920ec9803bfc73ed522509d224d14a380e04e4d6930a91f03e05be548c8ab993f596a358553670550ec2d0b2e5ed0d3be32bc21b4d4ae5d2c79d21ef9c02ef1371737991d1631e417d133efc8e77ac6ae52a9f3ee2713fe428dc412682c081de0d28417e4544ba214395330c70fffe10db494148198b2989fbd5c446be9e9a20a6382c0709cc30ded770ae60053cca092d7849380c241248df3f18d8fdf16b039b4da5c51d2049a3f24c6e294192fc8e8223a8c47bda9a3c2fa82f1a91b7b8eafb2167fd72c60ad6b4e4cab354467bdec2fc8fd68d9c8c3bd6b1f4b1b616166f75e843f7ce4603066fc47d0f857a6bffb5d50ce0c87ca7f240e7fe0a07d2b9fde735a0315165bd30b7234646fb70e1083a2ad44d2421c89f5bc0962133a20dfa7a284054fce7ae90f0e1caa7a72794fe3d66f974b884f7cec4355eb6a45e0873a81598a135c76965fbdc3dca786c13f09c7e37b883e6af2913595a7de62be1f2b7c158a71910a3928d49343d73659602d7228f90329f05483f70e662ad8b570b40f3e689fce7a5041197e6a9289931dd8187ddb39aaf28616f1fd12f040730635a17257537f01efd23e58cd66c5dce2ee1210b408af507b6fff26fdd94b39f01606b9ab98447fbae447bd7e79850b8ef79a323ee52e91d9d156da52f7a71cd369171b86556f2803636c7465110390f732d05f0cf95a241ca69b7b5009ff8587912cda3278513dd0e1ba50d9192e564bb174ccf3fa750c6bca63fd5cafc73ec1c0173e4c330409ac20fee7163694553686b6e5b6959fbb546bd2e031a7a42ea8bceb5eb35889b98cbaa0a4bc0159f65c2faaa1b9ca50f9420a3574085cc800c99b6b18a8969e53e25c22f39b0fa5af7dd7e0c5c9cf6414c73d2f99c08cde61e608fa3834a7fd02c9fb90c501792faeed5e4a3451efc66e4eefd1010e620644a1fec0a8e8db653d714292e55d3f95b08da2bd491efa61dee3217aa9cdf761593a7fbed3bdfd9b22ac7f4a2f8b773ab168cda079cf9dd59446cde1471334a69eb5b2bfdb4fe451381757f4d9f94485ee72b22caca81fdd800bd8be9bdc0ecd93f0e2f0eb574217b11933102b38808729045fc49149054870db8aec1eba49284a5074100d6d368e00eaac315438374c8344dcea87f5eff4b39c33900baf8357252825a8aa8c5ef9e8819ff7e98cee1bc4484197532306d7a9b93fc1561a6a5c103d586935c34396b53987cf20c11dd53796a33b8348aaf13733a9896a9fc95edb7909bf35c8f17fc64268d6200fff085defecb7aecea8ebccea14d5765141d607536f83aa21c52d018dd6335c6fd097e66610baf6bd4cc0cdcc636d697d7256cfc00ec492823c427ba8811ea858722592df5504a972fadab716206abb2ca84c760dcf8b09000ee9288e452989ee2c81baa9d8111976b149d8a5a0cdadc7b2e3433ea881b2010176a23c825d98b4f6a8a7eb91d79285ba1cca826afe8788bc0539c5e205a17fc167743787d242d7ab94b7b5b86bd7b5221abe9fd3576a3792b32a8cd601af4ed1fddd5838be36c04c105d896b5c4812ac29b67abddab5861ec581bba146d581e812161bdeb80842bd29431d3165d41153454cf7d0bdff9a2b384e916856ae62e888df06b953ef7e1de0a9281e0d8431cfef4ac4607c33b065eeb28d186d736b61e5892d1814eeae0aecd8fc8fb13acba860fe99aa2a6619f804f4bbb0e457647b5e0378bf481d84840f3d1838a18b1f8c32637114c612876a52ec13c376a8972c966a37436832b5de134544a0cbdd9a53f980e3a937a9ceedd93e3f27497d1c7f3ec150d43bf2f9e92e105fa791447944de02d23976907e1cf1dab5c4e8e4616a17b6362b731aa857e4fd86b17367a11a37e30839a90513e51228ebcd350cd4dc166f96a58fe0f7d5d30d395c23e279f52fefc49e8c260566ea772025a1822951de00478adaaa4c888e79f4f7de646d8969d635bab9b070c2ac151c7f4d2583457e347e8448052775a25558d94035af8337932a17c1994e42262dfb27c8fbb8a4b74a0eadd60f4a5985f77f4f785ed86506ae720ed2d7ee6a489bda47a93d233ef4b5c4fa33926e185139f98bbd3c458d0c1efe1ed92e756d9f56d78c73593e6200a5fd2e5597373f3b2b501dae3d1fbfd5f679dff9d06dc31dd0c50fc2707316d94713be63536b0f790c176e535982cfb827f0748f722b5e9645f0a92fe86078c55356a65cb17c6e62fca189589d929e226dd7f94245e7dc655c7575e231bd812b2f2bda0ed976006b161a07905e0498484ac96e5351d12b91087c2e88906e6a8f887359356fcdf973b567e74156de347694bdcfc49ed9a6e9994e3ae781d74fd8d63b79304d63bcef33f0d0a33e7e02cac014c932f43f4eed26cd1aa80ffd4c039a13f3998e8e957fa69b1742dfdc3fc95ccd7a0228d4e10fa62a079431c1304a889ec8fedc4298494667789e44c65e7f982501ee35ea2e58c069badcdc6c16cf924fc8eb89b4d3d62bb2f02f8261cdae6c305b39480f9aa9f12fe7d6a62996af1ad532ad52508bd75e1e3085aea2751a08ea28aefb5af9e8b2584ffcf36fe1787da95c814389e17976e3124118a11599a77c70609470de56b3f56e14522ca2befcbe1d439d094b886fc1f5798b5b8817cdbc14b89bf8ee9f5552e1585463db320567e41349cb7ae4f196a88f997a5aa86000cdca9f5cecde1b6d7205b350217acb33c1bcce62327b58e68d850e7ae43616e018fb66cd2d63e66e26f82f11b53ae10dff27d2f29eff7a5d04b2dc7f9cc3030da91c39ae2764078ff5dbe221a8d6e2bdcf60d619c05701f9dc9f5fa8f62299251a11a2853790d7e1cfb452edff732ad00f923cfa84034c9614294111aa3b5e602dc05227fd2b553340117663792dee3ee603664e9eca631c6610fad3910e87c488a41f27e704895047292d8952a8d725c0b6010f936cf493d6be002997cb0c99cd2cb23f73d31f3e991a611fbabb7019c7b1fd61bdb68b5b18fbfafedb1818377c37ee9f984ba5b20653454dccffd78ec70bc27afd70c27a2dd52b854fcb794f11263ae1208d4163c03c08298d3e454fc161336bf50bdddd593750731fdb111c556d055f598923fd45737de6dbc32366a85082c33c339974a994138d8ee9e22945a6d01d4ff36ba275439bfc75c530cd9427affdb7f88f9a358ea9af1d8001586b5ca500f39b48dcc2809cbd281fccc804ba23e319fafa76b23aaaee0e3de7c64219027e0a2508a257d27b3032cbe3141e086a96e3df950b8ef032c322b343905d39eb49cad6022767904f920dd4ab42dbd587de305c56485e00f57bb0828e80f12296860139074e20d5cebd69c58fb3872c5634c7f3fce6064074425ddca5ea2928beaa3e37a1fd7a465b4cc2630ad78c65c09f6515a23017d25809230b21390e1cb8a2043ea240d2f0b2a33e7fbc4a7df8f294f81c31a50927c889b02167b35e372ab49c00026e62bae049150cf216180a18ad05a3a0a1d943073b72793264c937d01bc31ed961007e4ddcb38e1c947c4827795d2b3d2cce731395c66699abc829b15952ee0e558479ddfc761bc99331c28a8ea8a2e3a167020240a73310628c7168fc327c7f0f0444345b2190f662729f2a385608bbd72b752f636ee3b75a9498fb8d58abc6eeddfa81029111b056284287cf897c038f53ac5b5e129c8dd734f6a174adc4f81f0c7ed6894f00bba4189ced47f111451ecd1b66fff3bfa31a91d9953bc9fa70e8656176cdeee30d36e0de408a3280270d42f410d16a160fa8e48a79895624f29dfece2ee6ae1fe5c0f04c63c0322706905d43ae7fd5cbaa85db946e074f27f6f5dc095a8eb16a975262e6ce0221569d0ac54c09a692275c8a6c8f05db52a574f4e1f8aa28c7c3b22228a5b7f46b86da89512a337ff9041f1f50f49ea1ac41a687598532630bb2cfc9c71ff141e09ec2fd66d5aa60628afba6361a375cb2a5758acd8fdec892b1b9657bf627ce9efefa3f55761d6a429ef0b1efacdc06a3027d1aa082e8c3b9fed27c44803dc5abae1b962eaa1e92267fc4a86604e97da56649a8e05e7f53f770ed5d9d58f47ffd32a15907573e4442d49bcd99375267eb38d00deeef8a40223cc991e4cfdf9c456affcd49c4aa87cee39e4738f7cdf77ccdd4c71bc9267562f96489dcf5f86480176ef536c2750400508e3d8c6eed97079ade0ed269a79ef64c2f86d07c92245e4808b344c47976798faa3dfd9cd4f6010d51ac979f63cf36f5c2c7efd3d17883e8d09c00e933e3a60d0e09e34477fe5a13ea9f523c3380f2af1feb3da7be6b0f1a2152999592a2b54670be03f4f2cb26be1bbdfe30ce0b90f11652ba7803fcde7f611f2dcda813edcdc2b4dd5e1fe9f2bea0078bb074bece6e238c46b5464775792680b42913d74e893278a304f54d743e8bb4b2b76d020a6d35d18d40691fbc37d5a292208d87244b93475529dcfa4f32090384e1534935889050bbe93adf17fa04d420219d0aefd7211fc353d88b5c349f100b1f74772ae248e2352339f96007693d4bb09eba6fb972965e24dac95d6ec39e379a338fb1335a55d022358b55da75a6f34c319476c2d1de53e220c3f68c4474ebacaa506b54cc817905285c992309bcd922af8f0259e660e6cf2e3516216ce0deb900c3485d3a309d193ae8b218bc363179a4c9ea971404b0ba2a0bcfddeab4d34b8518c44f8c274bae5bef670d0f8f63921a18c03bf89e66b212623932235f8a15247c24154b1092aa0aa466aaf634ea4533a9a4dbb7083d33a1a2598ca0d7919fcd3ddd5907ebab98c02e0de75ab43139b80b4c4009bd4061647f6ebd4099505a5308f742cd358c6fa40cb55e42b6f9ed50ba45b53d7617abfe1824d99260afad00b62fe2fd080266dc7fb2d5d3035e605177202fcd3959018458d89fd50274552a3fcbf7519f6b496a0ee79b127e965634686014736883914ba039004ed014d30b96f62b4f80d35b77af9e6d7d53e9342293ad6f06b77d674db6bb408dc53bc94d6f600c2aa2de52b93066769cfae7e4dd86a4e7168002eb98d6ac2a5a55abe4a25443915531bbfe2bfaa682552355b96d5faeb9cdff21b81a5124d73bc7f315f0218cfdb181062064d3e4ec2a4012f2dd659c9c6f15cc863da4eb1698c18b61a61a36e47292a4e673f95868d2a21d3f0236b767d725ac4c66186fb896082bccc3ebdaefb8beb157d72f68b8b297348f799a3c8c2b6b9db39e4076d9c4fb819cf3aec84147b32bc312aad2c3cbdfb4e768f03c71bb6ea0bb8ce606f30aa7b436f37b5205f6f7ebba02990c6fe36f9eee50c70bcf463e27345b06bb36251e34f961b29b01552075f497e7165d6693440bd948630c2815b71069337dddba19955bf08bb19c4275c71da9c8ed21eaab3d1bd1e86b45ca30d8efeb83028635bc2f374ec6c68534e5c069cb38f00c0410033ae7c5635c301816a7036902b06c327b48b2adfd54d2124995e030aaaa252c33661150b117f7744f3263896aeaf441c3ce6f8f11c579f5c3003800eb0709e0081e88729994dffd066331e4b97c9ae5ae784c401af11f85b4bdf7de524a29654a322b062f061506b8f678141c9a5e3ee37d6732994623ea52f1ac1cec61b57e8e247141824b43c51829a5af97bfa28d9b96c0a155c5bb24fbbb929c6f0b91e14ab13ed97fe6e09055cd6f287b12584811159d60ad1aca42d1569ab60a40f679f5b89ab462731f39f09aa2e02b63563e037afb78ff781fc9fe55a8d6ae5181bc1f7d5a9cbd9466527a3754f048e499543e7cef08631189e4fdc797e9dac0d1c35dd596cf683370ab55afb64d63f9b47e801c6ccd3930622ad5ead5a4c7c503e44c9ce53fddddddfde33e8f1852c28bd30ed7428b9311181cba022df43513a638b54bd28060830d36d860837de3dd8819041d741074d0c18ed17a314ed59c2a9fe9d7c7eaf19948452b4af69703b9cb99385581f94ca82285ca4b85c91439546992fda98a14d1a66b989faf5c45a9ab5ce52a3a677bf47956ef2b57a9bc84545e2bcff2fd85352ca576c99856791291a6877ce52f49b3f2282fd23321b9a67a37b4aef3de8677147f425bd648224db7b8771faa29d9af94ae5d4ec41887999f237a96cf19b13c2ead744bcbef741fe3459df7ed78bff23bddb3fc5df996d7c1f2e93092837ff43a545ef4315ec7caa703ffe85bbe3f7a30f3d341f42c8f4394d3f22bbfa3f231708c7ee5dbc1dfa2f22b25fc54657b992387f57d20e5edb992ab9c2563dc5d0efacb93f81127fc4793f68ab81a492be91b5891dba562f90cfd99a97295ab6a55896d3c36279d0003cdf9d3b139a76c9229d5316c2f12f448d59cb4afee4e030a51aed9bdfeb9d3b77f1c20ec12c4f842d848e4ee915fa3741cf428707fddb30208701863a42f6253a628c5409b169492dcbdbd2448fd99b6b8f7436c495c6f5ff7cb0753ee9fd4e551a033934422d5cab3a26e7f50aa5d4dbbda9d01064c7f381bfd2534c741d769d40c078ea99b6775a748a5542e263c403e5a49563e5b2ad53454e0ee05c1f175c40c5904310619ba86471bda29120cbfb2e328b4f950a560904a6202f38b1e52339b966a3a8358a33f884a915b86548af3a2055274e0b4a3b680e7c9edeebe30d88d93ee271a484a89b1e72288b7043888a720fbf711220d5845a4f921dab8106d3cba07402830813404dc5bc4d06b2013e0b061edde23fb93dea6f661c3e4508461dbd140024bd06130873dccd6b7216f29661f4098fe59e7d7b0172918e7c6c1380404077ec080068688c0b06b5bc352344d8b5adc9e466ee9ae2b6ddc9783f49938c345f03aa812417f98d479c92fd9df036317d2051e8c3aba79d6a1a37bef75887ef430fd3930fded30fa445f8dbc8182c31a124cc3f40783d37929905a80018056b71bf4edc3b47b9393bc4030d475dd48d48d4428c0318754e814d6c8bff6b59a58d3755dd775df8d442351c7d5785ec76d9acf0fd091ce2f165ce421093eaf98929e17501537b0f686442299482692c94432914c4d60961c9aacb5d69a5e883437c04c2653f69c83e326ca3c014b0f0701340187b7051bc1414f60b01b9e550fcb1a818b317291abe1441e27f26a644d4d0d1874d619d74277f09a7d8da331ea4363523ac7717f1de444decb18bfd633b7755d0febc54468e37102c762ab5b4041508ec47e604f5c1d2f89445ac9349ac09734e7e448349ac04e1c0c7210d6249b9ec061b7aeab8344d067b19e28e3da13970ee090348a02eeffc9dd32c61fdbafb57d303a5818ef5b4f3450b45f8e50f6686a255e572a9976801d7461082c5a62f296d4beee569cb57a6070a2777f2e502bce3640844ee5008f565d7bad09c7b65a2d4deb612589f9b06d6d8ca0f6349c66fba8440752849c7654d511a7ad946b0b0c734ea939e8312a9145fb0430c321680740801a2f4bc11b84527a2dbdb6852608a133bb331db41833dd18b3314629a5f4da6b5b70029d3a3c2bbbe40704417009fe21ca3808fa100cd32fa819b2e7a69c70b0b1001b82a24dcb6439ee6d7191071f4841e24212e301c2fce15a6608963924a5d0341b20c5d9263304d3214370cb0cc13537d93a924824e284883316cc70648cffbd18af208214f0b050a7ad0614cdb484d521020e63cc9bc1021cc69857039c68234494f10dfc9019c145cc4227080e4df2fa0c73319be9509ed91e0954f7de78a397db5ddb3c66c30a1c7e88811c15b080ec82e1324aa9d52b0428d6a48a24539a44616d5bcf74bab76ddbb66d3b821409c40edf2b0509f66e6c52aa2022917a96450e3b7563f349a303035d43fbdceb1d94ce6c06eeefb5b84382527a2dbd5608b34d9bdd999d6ddab5d75edb02eddaaa5d5b6db5754a4aed16d6ce74a6a4d65a6bdd6a9dd564d74af406ba63a8439a04451343486d449b9ee098bb90546323a0d32a21b821b2ffe66510647f8e7e397a70b0861485ec94d6f6e03535b6dedbc3b2ee3d018323499829992df951222382508db576ed28fa38c22a2b2c2da2afc5646201c1957f151209637c6f1439e91314a2789d424c8704e1244272d3c9faf3831ead8b2a2c7824ba9134f1848275b9bfae8bb1f362f47bebe671310526e4189282bf8611b00b4cc02e5081ef8b9480ef5baf06cf75094c818851667e1017b0b9d6bf80cdf3b5978105ce80acef7d5f0e1fccfcb62fc7c18dcb61b338d4cdf5b3396c96a8e6e0e4207b256305d63e6cd6f65a69cb5be902bd654d86105cf34d926740a4e919c418ff1933565821460caf07be5fa8b98262f303386cd79c0ece6863a7124a3ec083ecdf4a228de66ad76c97d7002afafa4d1ca87703fd60401a204b4640bb60fa4b22932907bf5152bfb06132ccae87ca45838df86a57a53cab1ea1ce4944d4994e8d398c33edab76b94dbbdca6dd5a6baddad56ea53ad6ae7aaadb2438c16145c9862c0124afd5349f578c91467a2975a104783a28e3e28cb0c65ced7ac95a0a13a124411d05d64ea6cba552a97e3cd9a9240d0e1587a3d61abc8c23a6458fccc5c47466826404ae7949010edbe592342e6f060b707b37bc1ae0b05533238932fe341d83b6a28583259d842bca9882e017cec1f94148774b97cb45e90605888a4ad6b21e5af9b4948ee229ef99798f8a423941499a9b9be8d3fdb07c6efa8b680333bde845441f22f613b2bfa905d886985330b900d79f72136d7cdbb6267003e8bfb4709764645aeaee6da151865a3605ae5fd8ae8cc37c151c2491b620cd66783b68df0ead92311ebd1b20aa652d6b998fd3b80fef42d62859a3648d6a59a35ad62859a35a26539179ea895050cb82a4ac51b23ac567a84c26b376a5aa421663d4a286425d7c3baec348e0fbf23dafc92e1f3f02c2a83d5aa59a16a4ddcd49adb3e9cbc4c2e11d1aba52eecc67e45b296bb52a70860b8220cbe72ed134dc4e648060db40702703046b39c440300622030453192078ca00c12e0304cb0e63af1fabe00ec7190cf18523b00b45e0fba2170ee3ac57ae7ac4d2936481f2b3ec965d188e05cdcde5074f10d1050a750ac11444b299f6611cfaa1f36edc194ac09c77e305223822208c9b1b84b2b0424785a383d383e1e8dc6bcf893a1920b8e6106b0f53011f483940e56d0b796cdf7d1b5e3d0670dff6f7a77783f6db17daacbdf470b8dfcc04d36e8b35fac08fabba510013188e1081ab4b04034c85603958a96d5f03d7a520055fd22b684684fd07791f14148bc160af5705aa401186baa96813ed1013a7c14d9ca64ff1898d526596c781ac4ad2c45392233f3ed9f6c07275d519cafb3a4a059a5f585f7504d8052af0cca1f6a829077d5455e5a92b1f075b0ea2fae505ed011c5221cab3528d820819c275b9f0053ae24a12052ef25083d70b62304821e1c2ee7598c77c267bb8131f72f7208792fd6f6cef1d068339cc610e3bd15802cb68733fec1229d31cba4c460afc0e138a3631dfa7e91e1ec569763cc66310820346b0d6bbf0295e90a4e1429f7dd15fe36c2bc5ce7b0d3c9d3c2669bc177259a93deebd6f8716e18828a71dd2c9c9487d1e27ae3bef064ee77d366e704a385e39dab0026ce231073d96c2121c7abc42688819271d43e71d07dd648497c36036dc6b408492e7bb77438818e34fcad1d381dd273e63613098a6f95821511615440089547d80e7d740226512c9da554f125c05b13bc618e34f4e46598a3f6b2c0104414a691114cacde39fee99b058d45a25bd21de4a5ff8811373b0fda6f667dc3808a3f3e69ea0043c28c1870634088a45931780ec830c0888b10825be3c9349e4d2f200001de4bae770e6646812ea183dcff33cdb719c271279224fe495228053b2d152fa90e4397c97926b1d26c00d1134c9b870cda21b654cde47ef6588bef0738ca7a228a3c9f8e8674ac918d1674add307284f550cc97482f58854a9a96efef5836fd8f2909f8c7c736bfe87d22d19c9d272a5d4086217a1bbec2f23ed8a021079c9c128e120422e0a083dcfbb79474827821cac2e0c214b3c8563c6c05256aaa4ed1cb1a821b2c19caa94f60b01bad879544f30d0a43b44bd06a0105f94c3cf2e3307fe22e2af2be2ba5eec9fb767ac96947cfe0347a5169a7837e0005d869470f81450874701acd562bdac000146da4057f060b87de72a0d38b46eeba0f01d01fb6803f4efa5ed725072ab94bc6f8cfcea7f01a647f571261f0ef1215d9df6f106bc418e3edac3f91524e9cecda579b776354dae9d3e839973430ddde779f8eeebdc79f0e2339dd7b3abcffa0f4cfc8456d9672b8c0a1ab248df7ddcfcf7954de771ff610ab87f7dd0deaad2fbc5bcb6136a4262573b2f34acdc4633ca69b0651a6c6e8ba0a61c066cc67fa836e141d83a37e601802f7d3067270c614dcdf2fca030833bffb78e2e1650c8e88964699ba8c7157cf869ac5801ce6375bad1cc7b96b611a5a51c68bc418534c4ca9f4f2a282bdc504f66a796b8626f199d96ab56adddc0509edb56227eeb1bb3f76b479f1a649814472130a70d028b70a382f4248d6ae7aee084ef0d30314638c96dbc028e39cc45e0e41b063d034ed8216a40105c639043b6e0329d844d3f470879096740ca0e81612c9c07beae170c3bdbdea540d411a50e051ae5ad594acbac7b768b590702a0a6ca7b4b6c129a990adf7b270939521989ccd1ed2891ccafeb28994c92932688bdd9d4aa552a9d44f2a95ea940edcaa87498f4cff0a1d3c0972dad9212385c8a9fb1dd2074a9c3c98142b62b4a1d94bb06853e2220b98ac53cd72181c06aebbeb7354cba189e3b86de3b66dd356600e46e9803e5dca6d2ab904026ce4be8bde7bc992e9d712bd6f83d5fe76af46dd080683c136587bf4a352052660ee0bdba753d166fb311269e811609d82750ad629584ac26c1421bc75ed03a6ffc2ee07d3a14f396c04236f24ee46d204a5242cdfa0fbc4673409933009e338d68bc9ca90e4b1b98c1ecd9aa939532a17131e201fad242b8b73a37bb469cbe331eec3c16863550f8831d81fb1460cb68858c36d6c08a28c7f68b91cc65813075f4c665370a0c030f7086b5529985e604282a7b525203a57cb93ad8f9bad0592fded8f58c30370050e3b35e59c499a4ecd24ca6762af82606abf4b2c39e3441bd7aa774375e9263c4167bc839e5ad1982058eb124cbfb0066daffd0e9b66aa4035a654a5e99f2e225559a9ca4a5556aab2529595aaac542a657d58954d15b1299a5aa4d27b6308118931ca285128140a85aaa8966779966f87e55bbeaaaaab1437dab6e7a44ba7a9acacc450c11cc7719aa6715a0d365c4ab96d52cadb45cf86edebc75282516929c168a352e799455224ba176312298785e5b5524e4bcb732e31845c5ec6c728c19062c888f1315c3a203ec6afaca8689ca6a2c550c11cc7715a8c185ebd7f6d48fad8ebb652c86d5d4b299e58fcb2b0b0b0b0b05816161616db29541e2a0e0020b58260ad344c297c8161eac75b4b24156a6654f73a89cfa0b94010d4583ed5075d17a39472f42a4f430c098843c83dbf26dad09aa19a4e89adb7ae9ab4f8d32504a152e88c0e757428a42d158c9fc6682c4692c1ab71022679dfaa063f2e511e96cf650283126564515edc0c5e1c277aefc3aaed3898e25e3433578ad9d3e13e93cf399170534c1054dd1fbb86fc2e9140d527e0804424e28ce59e2392fdca6b356e9be9749d83b01713e674423239a594e46181c3f4b2c59d5f88e79cd286b1027aefa41f4be1cd34663c09bc55e6f95f8c4f6be5590dd518638cb55d860c982170f859fecf70bfd6d4d4b07cba5891524a29a59452ca8e31ca643227a61c584692bd0c63197369a400733a58f8586ba544a204c684f7981479e06348c86967870a5f18e124fa1d9dc5134ea30f71f66206a79004452a892557b429612b5880612f94c3e02ff2915dbaa28ce148f4bbeeb1a4197d47ca368726ecb59452761804e5b65a02010ea54bd218a11286034bdebebeadd3d2b741d2ed6d69fbd671d0419a439309cfdc5ff8ee6ddf4854ca116dea37dd22c6f81b31e2021724f124398c32e992ae1f078160303a8c5ef439a22f27ca18ed83a91f5eaf7e3841d45c1bc044ea4fdee783c77c3988e0f0660ac418ff1cd275a9cbe5b2b6674588f31838c04d030a2ca1c00e05b6392469a4196966fa5e46dc0e50f175e5ffdab7eceedb311265ccb7d37d221b5c8103d5fcf0d2800253ef26fe56ba9ffd6c485b92f5068dde0d5b9e6fc303f7f6edaf3398050e6dca89546aa65ce5a0bda92a84043b2b6a96d692ab9ec0617b81c38e75a59da9c409ac9872dad152b84ed16190ffb2021cda94bc76fe8b1338b43345a23685c304873d6453d18600d1664a1a5ca4635648cc26615f36e62a0e8542a15028144ad2dc3b438160afb489642a99b0e972e190a24430fde588bea3288ac225d28c2870e82c1084e9c7cfe3d495ba177d4ef7a2ef17a93cfe7644aff23b31462598f64a30fd2dcfe3c4cd145679eff23b8c1ebbb0bc37572f1f4f2ee349bf83cbbf7c3a44eff2a4cfe575c478191f4f261850d88bb161c23c4e3c529c0f9f894a3c9002ab9234555687648c75e16779d77c491a19afb13cf67e144386cb37bd29f0fc4d54c2997103ccf2f8abe58931ab7210002cdcfa71d075f0bee573bc6f61f1be7e39a3b721bdae144fe164e11c010755463d5054385134d79f434e57794ad9aa0ded405312b41143b82e87bd4a22d2d81f76e5c53cb3a4434419fffad1e99a61030c633f0e0d8536d55af8402691431e5982114b4dd54ccd5414d3355d93073307d306b55f887481ef8755166de644f9ccf53a7727b23fea0898aaa95a53d68725c090e5a128eb635b16c826b137e533b407f5315d9c3321faaee4759fba27d1f7d8543c797655efe72a077db0a9a020fe07959e85f855d0342a9f7596b3f04731fa5e20fab0b320bb00724851dd57801c52148e4dc9989e3d78bebc63d3758516b11dc4991e744c08143543a166a83b9bd15981240d2de2fe480295a2a8554f2a956225710112f1d8dc003d34d513673da82c8793fb736b0e2fa5d40996ffff4f3b0715387c49678e5a8d18cd7be7fce8de5ee700094582608f535e4a59140a8d947647fbd6ebb84dbbd6ebb80d04afe908a694526a499f23edcd64d2e847ba74d6cab35251d75c40298d34ded46e19340ef1848f5fc42e602aa5979f4974de5856ad3880e812105e0ee266ebb7f4cac0cdddf5ef6b4166aba5c9081c73fd82e81ca30c13a93f9966b831e260f9485164c85aab594db3f1b5c8452e7231c678638c97e39ee32217b9c8c518e3b5deb9f65dd234ab69d63ea769d6daf0db5ab7a6b5d67db5bff2ca2bafbcf7729f6d2002ac70488201b17c5a3f40a91c49ad1f1289f4d3020628a57c69f98cbf04bd407939f2f2f3027b79f2e27a6192fde57469b9b45c5a2ead9683fee3a0d7dad2fa5a801cbc02c3b8fce41597560b4a5a60f27d91fdbfa192121694b08024ce5c165e5c92ec2b74116dfa5f90bc148934541563fc1b89172091a6a5155b5adcd7052ebd70d8d262a1489c19f5b0d08a36dc6809167ef288c80a41d146fb91128a449bed5f5ad1c6a240db8e90bdc5489c21755b5a3e431590024fdd872d4f64af39751f722d3f5186ee7d4e2fe69c73ce39e79c734ec1f3399756e8d2a2cfd9aef3eac5f6726921f1e2f299d0a5f57284fef80c5deb05c8a545bb518fcfb4b0464bc49916222dad119196d948092e2d15215be97e0bab85c86ccd0f5b6653cba14b2bfb5d218b96960a45662ab45c5a2f2ded5b2148f5d2a24f55d1469b6f4bb724512b28c81eb938828ae3d97e442540740ea94a7bbdb4b23f0b2e672189cfd097d64beba505c65a888c846a6d82d29a6cca72ae2005cb196b2ab576d53312ea828b3c2899726475e4075584bafa49f1d499cecfbd37e6164449fc28c204846bf65ef43a4810a902074d3889b8799dde6bbd0bc4f641dccc44f7d867362a4a8267ae76bd1a649a803d0371810e23d715b2fd98483d2d31d17d0e91d77d3b1ed39f0e0d3ef3836d2082c0dcb5dc0d2f4d887024f7dbd96fe7a5e146ace17f4b364419b7b1f3f2056e948e83de11f455e94cc7ae7a443a3031791a18fff4bf97698c9146dac4490d3243709dd1bf6b6a35011763d46452b4201c9aa6699aed1b2da84f2b2fdaaa86bb07470f39248d8b8ca0580b4ad69552ccd12a0747a4767db8d539e0dc3818a4dd6df369a9386784524a614ba802c86967870a3c5c9cbcdfe1413c3819e9c774721c95b1ce9bfd0b826a7fb7edbb12a6947a05faa536df86aad99ff7524a67ad3c2b152542dbd0944da88738e7947405388c423dc8198890b27dc41864e81aa85e55179d6d11c8d1c34b68b3abd5a609f5c071429e1426b8f75e6de33aaed336aeeb388ff3bece9837d1ebe0bef35e94237a8f13792621745cf7c94be7bddaac019d8aa8a48dd8f5346404000000000153150000180c060482c1804834269aad637b14000c6382487258381a49844910c43808a218638c32001003000106102022212b00f8db66f517e275de0fa85bb501ababf2bf914dc96a985aa021a7f1f1773ae5f5b44ee3cc4fbbca2bb3ac5218c6c5a2e5b7c0f3387a0e61046969588408ec2ccf244a3d08ef5604a6607153fec40e09fc441c8cbe66d44c4aa8169a134a6608f72a4da0834cd6ecead735a951038200eff1bae794b652e54efc0093619a8e5f9cf9599702d5e5a884dff8ab7a726d709e8e062c6ecd2964fbcab98b061927900ad8b4b73df82719247e41a19b87bbad6b7e1d6ea8ce61a140766811aba6c1df25f4eae688a6a78d7490a260b4f233812512a2ba939d3798b9fcc9b98f6a731d33558953505dda82266d237d12e33e5ef06ac1c1d07ae2d34971d3d77c9c62dbff74c5a1162596cf52334432c4f0080557a1a51aa233433e8b07194e584589568203c027aa2183b767dfd8ab41271a24aa06734e34bc17245938d18112b15ea7fce7563c0009a058b674c28cde843511a25f5759008292fa5024180a7e7e626bce7f640cdbe0611ddb4fed141e3b71250adb2689a2f2f8e498c00729fa019df1bcd8b5ad50245d46fe38f63160a2ff3efbb1cf82cebf15d11a7d1716df020394a3f07561ddc3f36ee6997b661a1e7079adfc0b8aef01c77d70df4fdd1651040f1e4c80db5e6fa323d56b494d45031c99a7d45b80ec310e970606df99c42ade7b4c9b7601b8ca0614f6a743795ada26b22ec2b1700bc7340698b7554e4262900a7565bfe8ee9a2cbec9910d2487494a9f9d16075666f2687d193ef5853a484ebd22a30cd2325ad7145e095e30853b0499f5d1c54760d6e4b16d1f3583f2b52e03d361bfc1539128719fb379b715c5747ea35213d986d224e6cc96655bc0d18a3b8975635d9cf34227eec70c553a4cf870ac9763a897e95446e5b33f9751b5f63240c6d8943cd3671ac11f654ce490f2fbb16370fed3bdaf2cd44036ccaae75a4017389ff4550439273dac59ff4bff3ed1cbbc87b6a82d09b3a4fd53d1f7f1ef2424eba3d06112409ae68cb03c43bcd961af3aebd2b87c74760e2563e6375e87a0267bd9b22ae2a1012b4cb07c1243411989f2ccc2563dc9a871489a6812e30e78310b50414211c51f9f59c178e9894ba3551d18b2481dbfd40cea30dbb374ff1b120c50c15c511c6528db4f3c499bd0a6561129abc0d6712b7c52d1c406efdd223c8c5111014016a64bfa858e8ed3a93e2d1fc48b62c5c1b19a16fa329e622e2143d6f1b3907f7f280662dd9d53de8268a229c436dcc748962c7556e71461768f945594a5358d14787d2e766a0f83f5b3015d28802e60c9017e1a58c9e741601949692c45fba41811b1f4058d202ab7f33907231c7d434c94f1728793854b5ba348eb49142f0494191992789304dcf6cfeb2ba8cc334cb43a6eba47e67121155c9817fbade0cd21896ec920a137b2194874024e824fa122416bbdb53163b0f4749c42c49d52a9c99d9c04264f4e49d6da8848f8ff14985ab02099131253cefa908355c26ff022c06d2e503cd79101acac70815c3145c3c96de0c4695c0598e2f0cc611b8e7e7a7b7da8d7c77abd289cda7250cf4e65eb41b9a730a94a4f94e361962f3a7b54bbe5622ef1adbee4de2b818056c6ae3282ef48d921bb0403192adcf0bb657febca626129ab5c16440753129f45176659e0c6e626a9edcf5706c4e38493c4109504fb1edc2963979952fe746dcdfa9b74af9c598d572f5ed070fd94934650402ba6b06901a8d60a4284294a8f00a1d687153a396bdfbe1a4ef51e864a232dcc60c7504aa8017bedc8dd48e01f88db8f5a55454702626aab3deaf14d8283f5075c01ff0ca84844a873ce9588010e8f46470ceca4051465b560444a68984a84b94ec4f42bed39ae68127cf74f3bdcff22282dbf25cc18a1f4d0596cb0116f8206905916ca8159719b5a7ab4a170eeee387cba37af6686c91845a35bcd72c2fb6ef80b47de2821bdce5a33b174fd5afc75c611093bcf6f1a838869d06af7129ab28646cd3ff95590e12bf0809bd35cbc6d284988046848eb902c18f2ea6be567167f3c372e05013a6b184fb9763d4d2d8ebe825dd65f2d52847179618a14a9288b8b0308eb49ed996ccc1835bd9e9ae588282fc369ac23733587c232ad1c5280a822df94719d5c139c1b4a2dc4fb4dfd93e2e1fbd11366cd8892108eba2c79c057e454823df1d4ee60c16230f20f7082016e778f05c6e33580a66265277e0bcee17696881c748383b1b7126483c373b4da5ffef28f853c662f8e6aed2313efe334777a1f2125690c38d1b289b5e4035a995c92f228ba9fa994f78e8d4351ab6a6cba9062b952992b5d09c3996c661cedba4baaa4bb977bf7569720aca4d3474346bd335adecd993cfc389e5a85b776076164fc0f5948d3720f97be0ae81c24f163e51121fd3ed9f75c16453ac2391f104a30b536085d1e852d12f465811a832d32877e9d1a41047b7dfad91e412f85f1503b0c161bbc63d804406315292e5eb1a136adcdd6fd146262e4b8d9bd337e70803e1cb16cfefcb5682420ab940b0e97131ed8d0289ac5e8fe34fe238902deda4011a8c995ea54c328f21040d7d5d2484d5e3aede24d336ea0a44f09546f94d693e3df91662cf03f6d083b2a36401b75571cd70d548230c274aab6f16adfb0ddacd29f24ef8aff70cb087fe03c29a4609b21a8db022aed55201b72a562f0c8702d61d597dddda25d38c2bc920534f5099c35a854fcc3e70882ccb80026cde794b78daef72bb3ccdec1806c2e86e010227cd67388f142d8ec6bc1aa6506956f6b8beb9df63c8d8b6baeacb9f20885da7f811247d11923ab1304f5b404d8b9591693aea9e3ca7d555bc62fdd8e7098f19b6fde2883f6b1610ca351a4a33e31c4f1ff0ac28c4a5088a6f8d90ce1385cbd44666d946426fd9c36486437b1a3f2c65ee69edb8aa9232ca0008cfd3e4c3cd5b1e7a5a4fa85cb029e17da3e89af16b5ac52184d6f834f52f79f4e6ce4e820d6f57465a5d4e7e69708c1f0f4cf3d36274827c1a4ec316838305644594440b8c48a3ec820a645ac8483feb9c3b8c8ffd5d8a9724a46a1b5518f846f9880565b7e06bbd2ca84e24f3d8719e2db14e4a9a8dc222ed0c342b75f3a1ad0ea58bd081d29d7f3860bcc846e85ac13dbd22c04bd7a978327461c8ee19fb3ac58f51ea88e05c25444f3e8dc9a083dde4e33265bf0a82f967f596cf410f3a7d5f828bc03222d5305f1f4c5254ba83036f5410b175f4dd4dead643daf4838311601fc42b6138fe7d7c63966faeb9865504823b4068e4311d34c9bd1941424052b50192888fe761019933d85b9c0cb0d76e4f1978c204a750ef40aea9c06de2441dc9f8baea3e7b353b3853f003973571ebacac136e2b6f0072c94f220266faccd1fcb942638a7e2a04174c77352e12b90b762d89fd164c6210c27dc18b6c5fa23beec364a74f876207088e0e9d33ab45da61faf8ef1a2c7424ebbe84a889b74f79a741020254511db2f494e343e758d6501025c7a473cbd794320cc4b12a30051cc43db3cc136f0c1d81fe8745260078447a2dad8ba6454234230ea3bd83991a1cf82437321955b4acd4d964fd7235a51bae5e9115db53916d3ac3c6c49678e6c30a11b762e6d114306adbd692b6fcdb2d79b14547f50fc813e056fac38170dffa1696705e0d980c7d9cef8ce6e28892672eab810eadbe2678da5bcb7e4c95b032315750c230ac56f8b358940228e5f47db34b9e25b458b10e8d56b15c688b433d5d1e861fc0237a18e766a46531ac8cecc1f9ad502832ed4d1c04a44262b04c940c91a3ec20bdc2a91cab45f051d8341bac453521b663840e8b04914dff0729ebcc0148369524b735bcc1824f800b7cfa20974f82b45d8bc1f4807fc70c1e0cd0904394fc838c600e173573cbbf165ba56b2e4079168cf86a1a16c4f9bc9b8706ffbdcd6c7794bb93264b179cc8bfb7a1e03a4be79cb8602755bf63a8b1809dacb43190f48dafdb3815733d368e9242958a40b05ed424c9f56b8490300c960daea976092bddfc14a0ba0b76b429f9fd5aaa70835b10ee2b67064f8a1ecfa70f296e27252bfba5cf7ce7c56fdd27d179edc1ea9133d7238ef3658b679cfe548dcefb9c60c0d1164d01e9c3fe8540b7a0d4a4c746ab70a7662caac1b155ac9be195bd7d4befbe377d2aa4aa16dc69006472dd54e2e0518e5fa13e7d0d22281db0722b1a7ff7825f442d7eacd4023acc8d2a3c41c6406e05d96d440dac2f37e71b8604d336a93b78da71cdbfe332333ad6cf787201a992d1652c6829d73e7dc2ed8b64829343d010437e9a8d77b09d964006074d05091b9d00c9ec88d1e76655261923c360a38352b1e2201b01c051aa396601846c2dedf75b81087c5f931629cdb30827df3cb37dd5a82a61702dbf6a369f60877f4a0412a4a65d9fed683aec87d648065df1edd3a1637f4f3a77b6cf55702cab2095d43d5aba9811f85a87b2c2861ef57cc1296914c4b8857fc272e053d170f2a7a18b7692cec7bc30a73eba8d4885253d651ad7035c05db9cbe591b58285b5245546909c6f44ffd1e9c5a0edf55a512c7b9e6d9ae878263046d10e4006c9b7f052cde72aec7a7cfce951bb246e94113a99730238ab39771ce0b10f1cd90c5e03ee8eb1873b7491a78893231e531c5097eb0d28657d36c4c0e306d9755ca910d914143af090145dc18b36adc58e665619195a2bf1e0080e17148871fa197edd54caebb7a890dc38508d256e846b4850a3af575e3637b4123f75ad1cd73cabb4c316e08bc54d3f44b6c0269b3da7f2c803a03ea495b8b152bee0f64261e42bec02884d691cb3ab71fcce489736e0a3a6a5fea1d81bed35a07b01a3713320abbd6da22fc14e05d8085e08f67c0b200db8ca1a879f06b2af3771c1f3182e745d687ef01538c00ff67cc95f097a6f6def45120cdf1d8e0c2623b54220a3037974236ce1a2801862ea3560e4efd8b9e7ad6b80208d7690721a7577fb0e7c8c15d17e576d3c483662b884039d2b33f69e69be2c09da1b63ef4a514bb61ecbaa3b855fdd40ad9bdd4782c048b84163ba6487df6213225fd281443dfc90b5814966a1e0ef37a859a36f57bac006396b698d39283f1acd46bc1c0e2076fd7e17d49acee585bf66e6a59485bb13935d52b66590c8d90aa91014ea0b3b10bdb74996833b8d3c6daea5e8850f96c088b1794aea42256669457b9de71e7ba93eb48e56fcf14068cd71d2e99f9134826f0e704bb72ab9f7f7925cb6f902cad25e1c7dcb01b0329f0b5ca3d3d37cdb37654e39256a0d4bee0691e60762e00f638a86c2c71f0df949b0aa085eefd5f63c6b43a412c972a0bc81aa6ce2153a1047f6e7820dca1ac2215048c79f55d990eb6111a970c800a6d3ee2e5abf3ad38f79dede029154047ecdb3a9a6248b04b54919785dd0f817154e682e7ac2569eeac23258aec681946b90aa5abd92d25bdf0bce9f4371e1d03e53aec2b7dc8f9507e42a6ee7939e9bacb654b972ddf3831d7d9bd7d10dae1a098721701e90c66fc1368015683658706f241663390499bfa39d00e481a1ed9787601b464049f1c184000fa9ca38d26c47f92ec9110b1fa22ee648156782ee236cc961d239f2c85277310c91734a2315356fe8600a95b68e44ffc926b3f5d2fb75938077bbdce4dd15bc8afa00a7331f61f50fd7b3290290b826d97a02ea8fa06e8008cd8c9e6c7d354b0b0895809be6f9f5bd622687c633001eb5e25eaf6c7c56d9b5147522fa99a92fd04d636b334fa24f799108a04fc95ecc9c82919799741fd7811427484d2aeb295a4aa9aa13caeb632a379153e01c065368abe87db73e007a4988862402cf5866261130505244a00374f1e445ba7edea980c686c2acc2127f03393da3893e2005de8bfce2a196421ee43b88a2c43b515e420b97de14718277724229921003669eb297f92dd619f94b741eb057fb4afc325fccfcbb13631fa30ad10778695dedc548bec6e4ee441235d1b393037ac70925355ad5d8deb24aa79d938b10e4f058f336ff55806a72d2b1f0324b01003953382d053deeb3429ed24077721cd0602f782e108ed89d0aa23d28e606c3a0cae7bf2a71f0b40afb0183fe57a0446e968d47c822dc051ba24c046ae5fb5fe1e151f61700f502fa15f948a55d7e860e0e907046d70db062cbed9a12114d6d7007150cff9ac0f624c740bcd7d94789df5281ba9a5e215e83d08a790bb7e5bfba9109c387ebe0b1d1ed9e3f018d533064b0dae350dcb6c63fe13d770cf43a5d87bfdb1d3742d2236a7122f3708edd578b338885b00e7fdca039b046782bd5d790aed9d3a6d70476a3a91eaacdf7488e630081728b257ad89f5643d0e505daf59750e8d520524c9625851f3ddeb65205914754db9239427a4298de2092a432322090b2fc0d140c2b8e6e3fb5655450e9cdef6b140d6eacac1d16160d32897489f2c1bb1f24fb8082c88105a523e0b0532279aff4b1cd16b3e12c877a7e612a55019ebda6d0936794da5c1fa044c5e4bd908d64c2153f36a16ecd99debd4c419c5b979db19fe751fd17a2f3c25496c5e722da074144a7f7ae782a3d2811c83835ac5f1f3f88cba80f84389a93e26f40796e2cd7e597f8c78fba710c5c57110b103e074fd430a075e3268482e84c04f3d608cfe5ef70b73a5855eb085a89f8466969ac21a67a24f933d9ca83a7eeb60ec52b95e33ef875efac605cbd21fdcd95c43068acdb12846aad52e3fd641d89e0cd65cdb5858be74860c9c13a1c99ec1223ee2ec685f2b52f43388936508897422c08653f9dbe41d4e8a03068902a132cf0ba7bc33b4813e10d9c38e54e3f08d79386bf66704363c8604b23c82a9367630602916fc9bd448a76d2a9af1769ebf50d0deae613a3c2ed98221da945d2e9864b43efa54b5751780d678896bd04893ecc59112686791dcc8f444e58333e84f1821905880b3dc3cda28209846b90e959c09932017595711848c8751ac16a607c4e679b30c10d1559cfa4242d0ba7085c21a1b49e8056fc2a815cccdd39f20a8ad8d97a091fa0c39f35243bf2be3e46ee0326e208677048af5c39b68bb344533208bbd0768c3060cb9568825cbb11f1b510525eb80c1d2d5ed997dbfa2d236efe51b1de7a40f5396f8f1e65b7024f161efbbad25ef3a39e613c863ec321db0c634954851c135626d033ff997fe5a50b1d3be8de36669d6232865f3bfbe32e3d49eb8bd0643cab4d543787c55a63a84851550e8fc130ff41f77b6866c2e8a13e8d0701829c2e143845659c8ade5c1328b75058c6420d4c15c6e6d9d2e84441a88d04d6ca48c77d332feabb87dac70be96340887a904caef261dc10af17a20bfa21f540a4b3b23a26c93b9711ccf02f2760886d4d0483235161b563ee0c505dbd49ab55bf3340016f4df921153f39bb9bdfe8ebf5a300148fa008e8a4b4fcaf85b2786e736d1cc6a8c7330fa6a6c7bf30fe4546791d46cd53a16cd93abcc74bd99c4dd9c62d1ff9306f693e932fecf7dd1f883c2ae876535a2b359f7945c8afd8cadb09d5d1718539479b89920e0fd2831bbb0ea8053fdc44887cbcdcbf75aec1b6bef5594fb8a28f8e8a745812ac56feb13572fee5511fc8708d3ae431e19aea9ae30902abc60355bfb143f906eadfdacd4adea2faf69e45929ba538274b74d8de9ea240a499db28a309a575a9ad7c0f300c661d096a1ecc13af40bc6bc946881368c161b0cf981a007a30ba42a7c284c8ebe6f0dac298315a0f7fdf32c19651c2f51081e841e79b8b73a0f5a9e70aa235302a1fe15f9bf244b0534cecdc8f32849e2ec49d4e736118860b849de499004e6f3763ad6e1320047cc356770cc0dbee805442bc8fa842391521221db5453a63f681a04dae1787060a88b2a2ddb83d60c9cc121541e483df0ba8fe7ea4d7e32ab7da20313a77c4537a64f3d055cb1df6c22d602eb7b95c61e5c1a3f238873e63206715be3b336e29a05aff00aa16cab88087fc754a44c68ffaedb9e55ba605ad0eb0d7d217eee1b164e68cc7745415430463389bf8ded6818b0825c89c206295d281025c7fd689fc066c5ae927c3093a3f659bd00fafbf9acbec3e4cc2fc9af6896e74052d354f924b3c395ecc8aea596c569c54ef37b500e4cad4448042ae521427f9021a8724e719adc1f100e917ae0af25c6f5b2bbbd762523b47acefd00afbf6b59d4af65baed563e3040d48fd804b5d20c27f0fa2b482de4972b4511d9f6565720a8890e2ff2d3b162b253c0203d84fd2896eacc4a8228ac68df89e472b517410cf3320aa3c2eb82a43fc1c0658a2fd5970730d47dce2d8f1f703041e52e88f4b4863b719932bc9de5385920c60e519cfde5c0ae2a83f9799cbac4aaf0e3ed277519605647187aab9ea0562a93a6b52c4e5b1c70d9d546a3880d05fdf18125c660e81ac524afe3a7b900360cc0d88a5a0278704f2bf67f0242843819e089b903a72f74f4816b357525ec4352c7d876620141d3c51df926b7234eecd6cc1d4d94e9aa82382d1c2bff801d216481e375f803ecb44129b17711feae76491227f02f14495d70e91f42051c79a804c83e14ed3c8a3cdcd055db24e304d8525301c6c310b6a0d063775653e9ff6db306b0f22ac50f72ed81b32e4db0aaf933a6bb6d06b92f76c59d249d783086b3d5346680d9f240d44f6b6f5b57be63b7b118ec62c3ecc6cc2ce311c41493753928b115505fbc51ad958f2fa5406301f0103c834b821ae0b7e439ffe2ae2285c3eda8e25adea25c337a3ce86428189df40f08d1fb0f3a4edd15cbdf51aca859030d368f836e123d496261667c31587981c93f6230c8148e3088b13232d8d9311c41b2c0451c6a905e1ac3e2bd3bac0c1e3da31962a0ea82356a8070c450830d2c847f7a0c3572ce34dde872cdf0f3163f35e4193818b5b174de618ec26bb621c9b2f2b95bf873cee97840ad30e7cc23207d59a866c8aabfed617ea753cc448ab9b598c2a592671bfe16859c3170b8c45c9e78a7796cb0e0f600404b8d160befa94a2e27aa082559a5e46a53a9407da5870070db0a37557e9e9a7c17dfc21789b6e00f1ded2c0198012add2ca69dab5ce91cd1beb4eb6c2221c650578a2dc205ef6f78133bbfb88f6d8a811dbba1e329dc06696a8437375ed8ee242b402e5e3f30167463f80e54a5dc1be3641af95b055975bdc843c8137a75ac42098caf236e0d72433d9009b6794c48cddd7c7b8685a444043acb2a6c2e3e76510ee9f92235de43e7523e80a2ecd2819d77d0d75cf5a9b2c0a484a9c361b72c5bd6730d53f0b3b1462f75b90f59009855bb52d13d75923330c6b6290c891b5f7a758c2afa6dd93a74b28a0b99c4e24a990e4e47ae6a532cb173af7312b063a915248ad09ea9bbf84f33a16e929323c11b91bec202e36d386f82d2b87d6da1dd42ba9ccfc775004d7f12efcb2ec9894be3bd51ea3a693883e94ec844e8b9e1b98540f37d489e49ae22589f33eb856f7776e700f6fe85377ffa7cafe15932a6758d9827b10b98912c397c9b89ca79d192dfeac8b2da954aa51084b37700f9c7a782df7abf2d82953b3c059e1194df19c9193f7f6d25652e8cf2cf70079129e00a73acd2d5ff41eb2badeccf31e5ce794e1a3c0cff568311077f153451f4832345b24e2b527789337619fd40f0c6a750e2bd5b9c715d73d6666b37fe06309560fdb37279a1346903ea1cfd6f804146c10870a5c386a7af93490e9acd5cf17d322004c240fd5e4c65256a833275289946f1d28144a3cfb183e69760cadc8c45cb100449a1ddd92633af45e4c9321f38bfa41931c25657681860e0b463e864bba7b675b9ffb852cfda7c4d627f7f9d0de29b805c7ca891c64c8fd21c568a78c48179ea0d6fdfe139e250674ad49ece5709993857a78c86db2ef615e6aab5423730e0d1135d8809c3cde7b84a3e648fe68f2913d8860182363a38cedcc382a572159a64d3d8af4271a9907ff2bd0ded025f9a1f3dc90d826b1493a519037eca4a5c838079fe1fc3dee6e66b72649a763ddb0d8a676d7c13995b80ba97e26eaddb07968b9520038eca2e0b07e596083ab2de21657f2c1fc6374c709dabdf67eac2377424076871ebd46f058dfbbd0fb317ba46cf50ff1170b4e7e14a545549db8029b99a29d4a3e51e045bb5f7179d739c37628e664713e5bc8ff7eac18880185efc40c600ccc15462e2e5a22d405e9c2fd7e93c847671f9eb71f1340942267ac2dba3bffec83c58fc19ffdb9f4d7e1f0133c1aa39ad26dd27ee081f758145e4209e6a3bcea2c1844e28598cef15fa6f37e16960f601d1fd3256c013116bfa061e7b43447c99aa0442d96416b7755d249a4dc71540f1c3b85c2982b6445c567e579175dc0fb57bfc8ff3f8d20103418d840184f37e978276f12a24816a007c02a7e319b59717d7899ff2dc9a2e5401a89828da32222cec7a57aea1bf39c702ffba1feb14e40dd6d8a82fc1fa2c0785134aca93bbda13b4fb256929417002f460252e1b2f4bd0eb96245175f365d5095e5a3a362a00f8ff5bd89b24c299a63467a493192f24ef4ac3af87c79916c5154b0f572a2d3b6e0c2b77d6bbd456185e2205ce7f4a120ab1510cbceb614b00605e2d28e0d3fa09865dcd5e54eb411d3344c6db63470be653d3f156e3786d0b2692c84788b52a566d06b8400438e58c94e0685ba13650b4e020481e396cb6f58047ed9998650ec8f6fe8a97ba82c0d11d13ae20e7af01f6397acced2a1d9786d223a2b010e080b6307fbb2617824fba9ce83da9eccf9756cd6e0dd12f21e7c05f3479721947dc5ae4dcb07c68ed51e7061fc64c986db9b99773011aade0cc38695bbdf008509fe76b6009e298a9fc758639fc5311bd6538c5613018a0c84a9953d67158e64449b5c466269129adac176e964070dfb619807e0610087c2d486448078e648c9c9b91e6b29adc11699bf5fd626b618d76481de787f62497d7cae8fb2a016ec46039667cd194cb7cbf4355961e1b52e9401b0308c7f547eaa33d06364e53070d108a2664e4d664c63ff23ffa3cec049ce8f45864cf50d80e0610221e16570e55641806f2ce3218df6ea3ecb216830f367861aa73a6c58ffa986a4d59e05292310423a63ffbaba6b8a066e57b96da86c089794b661da777297b5ef531a15338e7c712eed920687ea7a9a9506d65f7940c0e4861369d67a418bec68b2fd14386cdba522152030af3335c3022ff4e49943bdb1dcf3161c929c610e62523377eef338cd0c20973842a91189c2e08780578224fef7637235d3469671d121439001dc7239a11055f4ed62d2d1bb44912c61c17d225e9ef26fc5a37d1f0b96ede60289a716709680780a5012b79fb5f83b26990e23487f84db12eab607fd0a832d0ac757ed0c61099b85d28a2af18a779f98fa87a20911ed753cd20ccc30c0d56307722f5d2ee0b3b9fd8b3cb5ab4852fc20498d5cbd6ac13b3df4b68b4e378ec5965a445c0c8d240a3a7d33461701511c98f6fd770371d40d0302ae70ded9e2ee7ac7a880c1adeb26be1ab8c8d380b355978fa9207eb0793d2306f1feba0f3857752142f69609aaa944eabba4ee10a47c24403e6cc482d71b78a027879ff5061eff7cd2628f0fbace12989cd8b156163a775153caf124f40d4249dffcace3bb2f501ce333c94d8964af0bf6cc9b23e2d4bdfc9a26f6986d639b3991ed2536060d3c96b25e4188cef8f7dae6c0459242f8afcb4068fc227b0f7265dacc7378f2fd9515b040cb2a86d7b7b7149d2a06ef2dd010a244290b8e877499d05656fdb45e4108be6ec9555b5d37221f70ccb9340266433eab91e3c791a32470715e508fa29eec7feb00145477a9a3d28d773daf3c5a14ce00e351af50ca4a135db0faff082fe4b05864c1c4665639236bf4c9204aa83855f8f65717c2020043655e84ed373e0903046acb3df7fabf5ed4f4164dd523b7da0f64e5bde8bba38ed94bed492f060fad25b65b9de8b874ad1fb1640d8db7c37a5bd0a91664525fd55d7470306e355aacba7477335f3b0597cc61dc8d30221860516fae9c81c2d2d18a590e493246e636ed21f51aa54b5ecf2feb8d8c52577172dfac5e3ad943e0042bb6f81f67e24e5c4ab5e6ee9932cb976c1f7bd081a13bdfd9a5c2136bdc16e448e483d42c0bea896d4e543375a6144863f0184d0ff7b6b735277ada1a1f22b66a33c793c6dc98abdfdfdd2429e9ae0eea616c9670f4de0d4d45ad52aedbdbb4f12b99c70f31d3d5a7b0158087aa5b9976541d3a32d3b6e311f37aea4417a97610aee8e0be9edaf46cdb0e716284123ed0eec435adbf911a6c3323d5cb0ce05fd679a435d7444ce24b0657817c17548bc540f6a425a8a98753df559738b204ae10177cefaead21ddcf78b666885cae10b54808e59f61eff806680b327a9663dc1208b67d5440c05eb95c513af42e117a1b72f60231f4be5d2e648017b407872cdac22ee49a02b7cc42b6619085f8c23e80a33b92976c6c39321c621a9e7e6c1a0c190d8712200672bdf9bfd05d5c87784e9fb0d7388736d7b69ba6c357dab6865b0882bbe1fbd035d99196640f5bb9a9bab08a240aae6114c678eecbda0ab51845d0e7c3eea5998bd090e74f4e3435e750b7a4bdcc03969bc8dfe633c7da268c895706fd0d272cec0af072b4fe16040ad7b96d72c597240813c111aed4cd5e7c746044bde83738c374c8c3334b6bd6d56369ae4b892276a25645c24cad62f2102ec92100f1c3a8ab28a8a4df05937c308a4ee198c0259fa13f4ba70ecfd4486c984bbed89c7ca688d7e41258b0bd6b8cb7ed62b302a705d9e0777f138717a18484f1a04d8de201e245785400a2821a66e9c09e40970b7c3d71b5395dc1c79a73cce75bd1b902ae220b2e3c13f9464d605c1f676412ec4de8e19f12cb63856504a1eee0f05e135a719e84858ce522aecf98121c89d502abbbd69ea749f2f1f17bf51bcb8d61909448198455c8a4de8f7e25d5d48311a4a073c587097c6fea734d53d8ee2a2f51fd8ca2c21bbc2603a33eebc0e144fa1409aae58b25d0ab751a48b909924b24d4b9ea5b0430999065625de1745e98b228fe40829a72ac21182f67a8c3455c856af2e6e98bc8c89790d0ad0694cc14a70278fc3b6e8cbe05743625a3dd6136dcdb78a765a34ed7d9c3130df6f8af1ebfdf53cef22e050287cc902aa066c033abf3a0aad92480f90da344f312ae7597240d71caa8e7ca758ef25213a31692413928cd7956a7b2d6480e4f6db33d8d6e0181f4b93f9b7b62797bc957f8cca6231ef8408134c1b6056421a032cf108c8995fad5289b2512a7326ae2cf0b6cdaeaceb2322a4b50dbfc50270800d224fb89c3f4d1b68065a20c5d725c3683aa1b3d9f895011c0ad249948ad74153f036deec843111f6e8882cfdb95da6a1f6ee8549d81b3dd75013b283283946040d9514d705fc83cdc22c488a9f9295eb2b5de5cc38958e7fcc267c5f40916949356a804858107f3a951c4cd2471734c78171e92e5229200fe14081291dc5539c010413fe4e59b7d33062a5e0a6b6121aad3d9fd29f4a04a4fdee94baae9a4145eb05291406f109a87e558c07a995e8a0b7766f88e615e597c9f0a25f72846ed28026491c751931675f359ed1ac338583dcdde04a7134609545cb4dacd1ba24d66b0f146018ec989a3459e0b516e3a35970c2831cdd4419040a77b9046a3be3f711fb5d6bea1f912f30112030483b323b1a010e1d06f723b9a2784575bfc0515fa2c1b35a0c768fe8564ed523180705b3b3c84484f3291a0b10b4edcbf632ee09cf873574ec39a8b0eaf6c7bc80e8fc8963693b62ef3856003414b532accee84f739d0324b058cdb4f6e9820139147b2165882d90feebe3d8dcf5f09d68d2bcc14f4b45f30e32100276438b8fc2d0e67f4870742092ef6028d35a7a35704be93af56c96434ca49f276ef87f211762ec00e62216136c4a98f922c898dcdf8798fb3a205338492dbce32f4801521a30867f4fdab33b2f448adbf02b31e31bd44cfcb68e677385477ad8f57a0cfa4a3b22489df3f12a6d90bd14baf8cca415015cbf8e9522a99132f5d243f1dbc0748acf6f1e95b3f649cc6bf16217813f42e1ecef0f193ab2b00868ad4ab4286902bd9812a686124c838cc63f70e7474f814c3024ca80d90bce29187d8f39fee56bb153e083541593f601261aafe81a404a17e95fc5eb9119c3de1d013fd6baf85cd0e2235651e9e1ec4c8017fe482287132343d78bd334f18294e26043b772d70a205b6ecee377b4dfe6f0c18466f1458df11f270697ffc490f88442a42241a8ea760624e858b28df513d5d9349f75efe227f87c2e8b9c6a5a61dd8e88c0cf123be50893bc87060ffbdd7a06ae711c94484deabb0ddea99e24c233b7e86ba832f872ae4564d26bce524364e16b9ff060a8818bbe799f6dfe025c1aa3eb4e255f06b233ed39038105e47e163d2c3c270a448942496e2fee29363eabb1e1cc8ef16c0b7b226472e6c8101a66e922296a90c235d4a8f83b5f02c91abbd2d19f9ffc10a0aab19b47c39e5d94a5b20422bb84272caaf000161b837650bc99d1f45ef9f235218911105807dc5d679cdd0b2fd24c5e320778bf9d087ffe5da6c2607ad16a5445030405edb5be0304c2fa89e4982f04712b506aa2ae8f1cc4b5a653891b176fa4792b8c85e81b4764606078577085ed5b18f9e97a48808e915214232321ad53dddf1f2ef9801920e394581977be4de63ad5d9b401078255b012dd84f1047aa299a07155d8934f633f7578ff79988fd550ff9d9a50605df42da5fe9456dcf1e2a3bbd2105157093a6fe3e9859410db65ff81112f517f68ae0f93f451cc02bc932d6d80bf343d29a098c507aa16c0002496c966615dc4f5558d764c1c04aed62726db50269240d5e1d023ccbcfaa1905d10d48e32507104dee0b3bcc37ca155669fb1dd18c351be270bbc5aa0583affd6509e0c7f472f371315786aa887ed8240995c404d500f60934af82fa65cf441fc85fb02c8ab486370d71a2c1550f9f4a772923532d4381e181e29da02c5a0f35f804de6718ebe717c3e5b38189c60e22eb531ce01e010b0276832de96d40c38985754cd6195e10a2a20bf4239ade85616cf49c0ce280f907a748b028e933549615d5b02c690372c8baa97f461b8b06e7f7ebfd5eb1b780df5ac3ec26b6038e452907d696caf621512596f402c9621812caf3307d1c48b95696248b44b39024f42d504d3022456ea120bc5d95441a9f951af873093248cfb46119cac967b45b11ced2d98acbd9cad87f93080b50f55a0f7bef4b9f59ce935b5521b902276494fcf4afe532a67902124849b51f9e552bceb4cd52089d43b50cc9305180c427c6ac7b0435e765b8d65401a46cb0ae98cb335bd6145ec2aecfc7148e132aa88b6e42b14acacc4ec8cb65431f951a930614b884fba2d0c3a88b2cf6902830242dc7c466ac367629965014fe3f10897b0628630b0133f84d5edcc03f1fb4415a7d9ebd0607a674d18a3b0118d0874d4e0e15c54274363cab0a13604291bf3cb4d1ffbe08f2ab0cf706f7ee8af5b66b4cf19801dc66a6f471ac72ec59747ee6daacd1e61d4014d4fbeda2aa00941daeb1d4892450b18cc76f302fec0d4dac79a82372d8e82fb551e7c9c908dae2726ccd851c530b81ac1bdd5fb8239428e56e40734fadf033f1f48f49545d6c6e448075f58f0381dc01158ac2279db4bda7b748662285836561833137318ceb319af41e3a9b49fff59549971c1512684c3a6409e5c4d525860d0b4a3b46e16616a12df47c94d64c8ec8c29925b49da50c79e022d7c87f6695c1cf507d9e35e7f12ca84c7c8292da8f10e5ac4d8825066a3ed09f3e99e28f5282f0d86f060c78fd3c1870f0f00e23b60d4c2510a94bb528dec8263cdca1cf38e4e410a31af1c207f682ebe8a635777e379f2971aab71a9a0a09c1636ca3c9595e93a2273893f7154567ef974260b0184a7ceb5c947a8f677487aaddad5fb034fc1d1b12462c907f1ee2399723598186ea688169a6059b0f298b1ee79a1237022e19f315492266828f4ccdabc351133ea89ed23cc627c50bcb294f01e9f81f2c544476f32ca9804811cbe107125b841993d6743a003c218794abd85a1b8da7218303ba62fb3d6e97d89914db6bf05d2e2b3a98c0f19edc09fc0251eb484ac99ce1ed7e140320f586a1dd4e0fb1fe02e66a5866f2e5848da7281e1eb8a7c34c649356240fad58c0d0c882f3ef15bb72123b1deb3b5a0f3bd417ff672b5bfaca0effccfb152bf6ba861ddeb0092a820063ccfcba60a7c874f552e0ac260ecc11aaf2d26159117c19cb02b1de14fe31a67b1eb422cd81b2d4b4e01303196750730d835bac6e2e95188d3bc5e4d07f6e47a08981dc144f4b8101eec8a91892e2bbebcba9b6498d24065e12e4c0556ff3f4102dab231bdc097b2540b626dce1068094568ba1647576584f1528716fab1e73015c5cc289ca09d95ef819bbaae3d6eeec73ca3c0c04f6477e515d7e36dee90c1af688f9d4ed80fbf076e988748f7d257f487991eac5bea6a906a6d556b6aaf8283b8f4f2e72a7994e7cd8f8bfaec649916b34d8e3c04cbaf49d719e85fa294b9350db941e9baff3474a26ae1e33eeb8b6855730a1c8c46d438dc57b618aa9279266488e0f0a7d757c7e5c52e8e1890119825ea33842aaef2ceb78538cc26f918a89243f4aba14974016932c21ab39a73af668d1fc79d31415828550e896ef3b52e69be04ee46ab75fe052509eab769b4bed361c070cba0f6fb0087f3ed74049ab8894dd4aa7f883fc5bdc564d48b8563efc2f460ad112987daf98f4391779f68e85c63e1c63475ed4a9775e9beb6d2b6cc281bad2b13b961ab3fc7f58bc890d0c4cebbc0e44776eaa4f1fc0b64f35a71260ca892bb35430c8c476572913d7261edb64435c599ea3447a7f5b42de6b5070f611562dbb23b1a2ef8dcb75c68f768581dd334251f4b6803dc5fb6c4c28632586d47cf58cdc87377c4488838094085ba2392b74229bc1f25c4e46441eda020b4ba290bbe2320d40a880470f2e0ba29203f0f3bbeec855555e4b990482e03306bf1e213c3d6a9d911313d45f9d44502178f9691e27c081b4ce3841f5f56d6ad01897ec28488baca7b4a320f8aa4402b9d9a2f3dcf65529b39da9893b0a54520258145a0a4f9088b56d722bf057a64bcbda610f0a569b3f6ea2c0bad29372422915fb6b2bd258989f20604a2bc09aa44522a59cca1b05cf517868da2880f723e21c4dd85b73449ccf61200bb8d9bc4b1afc0c233179af5076349183403ac2ca1a8a3b1fe926faa93bca4b67f037eaad9e819e362b5966b7a51a0998a1318962e92b4d5404946460c42cf5c88a05f3898569d14a94a13c9157ded21876ce5a09fc028883c97d8e738a0a5aca51a9b79d7cab978062121667f0d820ebef562e12b4f494224f77b13c3706b69c7fae241c05ba99c473f152bc202b2522998b9ea1b48eafb5e8c57eb4211a428e1f9e3cbc8f0d0cc876ac08016cd2838e3601e4237b43aef964543b9066a103310db7534a4dc0049b644810769be2d9044bc3cc40dd303eaed46626bf786181454a79a81b54e561992fa264626996b1e4b04247219abb540cc76e1ac90810aff4f8b8272ca1b5877c594396855a6f0fdc6366d223f32e73627707c1d8e3e165a26d3d01cf0d084056c7b4ea7eac822e8d47826842463811ebe3ec3dcabff9bc79c5c2ef61e06176d8808843126928af2360dc4a1db153d0c693922ada0bf2cacf225ae12094fa3fb435e5ee6b7a974e08e1b7bae08bd0ecb1ddedbf6483912721285f8df93746affda5eff5cd4f0ef334887350de08158fca1a2ab036cac7212170e8348033086394a25a3db6e7a44f5946d9bf2dee258c5375d742c59ef37904300636580d0599934d9b8c08b81640e4acc12270c4d001f18a70d0901dce1110c9347b3b81099cc742a09a106c859ab47edd281b937bc7b6e84e6b45bca7d511f365149a583c256f12719be12c6c6620ae77977d260081b48e3cdf8cadf1ca58ce88f48468f1256031a806ce003322a77e76d1dcb29c03572c3c71db33bbfbe5fc583f41c64db13e0d6e4d9d54c48a60cf1c36a12dce38c91f8a32701b926c6dfc944ddb262a7a03b7ff4914577dad6cf64b30d9786068ea510a38f66efbf55e11cb3056f41dd7dd8e8f4d96c61332ebce71cef167a6d7d432e53a7c248f89055bbf2a54f1e710d9aaad8a08c941240726ffd365b3d0034e4a09b0b5e52ef4a35c2206e603a0f4ec2c59a0305aaff84a58d89fb485da8d48498ea960cb9e54b6aa35d921ca5c3077babb0e2ec4a3858aaaff76ee08daa408ba4bf3c463cf6650c1078ab7953c83323258bdacd4e14ab408d7dfa9cba997988508748fa544bf55605e89abe672f0138ba29ed8453bec120163df7b80f265d3ebd0a195ca8f0f3dc0095c2d5124a4e68bf53bdd60db04d1938cc0af00b2cb0848f3caaceea3afa94afd591f7f11a3646ac212ab339e0aad29df3809cf53c3623b49114a6f6235120a1bf2bf7f7a0559204df388a2b7c2405389191b0b202f80b48020b3a5360d1dcdaf8023877ac87e87beedf4799ff293d1952196406dfa786980c6d43ef00bcccf0ae85e633db1899f3c1bf136c32f50c7deaec1d2eee1213a28b3d716e893a7d08c20a863a1407b7bb452fcedea64801a513d7637710205f27f267aae27620c0f2a471b1ae2f8c145250c855e829d231a3db441c4212772d8136600b550c200c258882da9ee7f7ed5f1619600a9bd65dd51d042b02e796390e942d3b18dc2851c0468a403deeda06b0f1485b9d55856072ba1aa7ca8f3ef901160a9bb7fa0c8d08c7d6c663625392ddc8b2bf11f4f9e130e70e0e1d51fdb6da9f4d11e761d45f824bb0e807ce6224a1ac3a16a68801dfebae6d1cbf3208d2a83c1f677e4bbae0b719b3f5043ed4bbdb45af86717d5739b018aae00ee631b579cf89ac2143ef64f471b482669036bbd135b5d3a8ad6ec74407dd3656e03f93ea1a7e88f23bc0448150d9040208dd54704a79fd0353fe21090e3699bdac3afcef823b900ae3d9705696c001b31069cd2860057882798259c18d0e7ae54c81f844bc358aaf6d9aae77708659254d1edf3423391413048438e8b2d21a182d2006fc17c6a9a06e8742e9c9b5b5a0f4cd7607d80d9d46edeafd2bbcecf9337510806571ea1600bc0a3b1db2a8a3f1a67688ab9aeb4befde1eae12057992d228051a470e37b42352f35d756108d5d41704daed98a3d98ccb56eb1955153aeb28df462853ce36da7ac2d75c13ad5f67d00b41419d119a079cfd0c9df968cfe15d81a8bcc0912a5e30e97e6ab8bacdfc45375cc547588237885f4c129459db0839b6804e531d1bacb7610879d5dcd96057d857f47972c664fb6de2a0382b47fa93d2c7ed410493c84d1dab25d6bc0aaafb7cb795fd12caf91f828dac68418350091ca7187c7202223ca03ff70a843e77c22932c5299a8d7921f326682c3edfc10b367c5bca4044a282c705bab4598e3917753b2374787125a7c5fd28223ef617ae4435813da50b3db1072b0f937862202b1b7437fc236a766dd14cb503a409bed1b2d489eae1f29949fe784a356af9d4b638f9057a703ffc94bc9a15906a1c08af8a6095459e44623b24509c1d2880ad3eac8f1b5397003adc56d0c41c176f82dd185fb80969e8b977fa686c6331099f043ce9b13ae6a725adedc4a22ee8e67a18514341d9c5619b2c985ba73cbf97bc9059c56024e13e8db0020ac2caa014e152c3bd7aa01146399a4eec568c23807241be6822db2dabe9b90138244cd187223e464277624fe354ee487b8ecb6818a3ed75af04a7b3a970803dbf7903c911324c9e97b394f896e4ff48ee75d48a3c982d485c3b233a431cddd9f1cf8815632c9b6c675d10018a4dc19d5efd805de23408390c20b8948d7986e18f84cb7003eb98920eaecd1e4be6ced486717fb9d6a1465cfc786b985030d5247905449f25c2b1925e1267bf6f75d03b777ae6f5c446d37d12229996a86ecafece98692401d080aa10a2a14b0d150eb8f05e0142612c7ba92fb51487b608ffb9fb34d66340a8f3254e38155a279b7db1903182c8d68fbbb682de90d1a04dca16f10b830800e82d10f7112fd2bd3bd0a182c019b34e1f72fcae4e5703528be92f1275032e4fe56c58ff56cec3fbaf31ae1c707a888482b42b1c9f89f8c8137409c80277e7ba896d76c21991657eca19d4336a2998915a0b8303ae51c5eaa5cf7c3083b80aa70d0663e79765216ae5f985cc56046dfbe3811c7190cb816f7e31460cf249db5536cd946c45980ff045974a71a0967f70f842a3fc76134f86a12107ba3c186d94d808a8261ec434ede20ca560d8811341c148f0dc7cbee6b7a7db7f7c1c341b1ac3829eca9ad4b969414cacc09a822f568bf79e11c6c32a4216a54ae21e0c8c46a78d13747ffc933271a7cc17e5ca963d533a5dd672be8190d2db39ba8465e142c265756bcb52896e53fafee52e12f043ce19b109754e3138808aedac1e3805d491b1c46c025a14f0e7a2cbcdce4824c377d80164b7c69c4c9c820b026e1d1e553f43e9ff134ae114c79a9c3f83e59c037c31724dcc64584326a8469be890253223a9b52e43c6de4780902b8f4bdea829e6605fc460ee7de840e86afe8e38cd3ec6c228b0f55f9e25ab7d5f26bb36e7985986d4e3e16c09a8af955a94971432b41bdbe96c92281e46ad991012aa7d0fa5494b971f0dd1137ae83bec44c39b361290ac54c3d479210cb33a312c54c797ee64daecadc97a9bf6f3c74b09c0366d01a738f4ae8089e7e6338c28a1df3fd5f6e8c13263027ccc6c6a339f110443820560c3463ef1ac3eb80c881a3ae4bbe0c16eba3e57d94dbd2fea6f94f9a09214323103e55d70234825539dbce7d67f4e90a026f982b82ab3f5c72d3e8a62453a5bbebbcce79288cb086b3ceedcf0a0cd412d189ca4dca3c604ff014a6d362dc64637727a6fdf3a4708c8dcb8293b30005e103ce7680625ef1c8a2d19f9318f5294b16e667401735ff3bd21c6df7abc6ec93756bb977ce45453fcb526ea0b5e6bc0c3a8e0c43b5125bf2475caf82a1c4e92b39e5977a74c38c5e1ff37c66219ca9084b2a6ec835150bb0106b8d6e03ae0b840ea9b6c895fab9a31562abff90154f1a46edfb106855950a0f2a5552e3173a3efb5772f95ff13921ddda3b744a4e6746945d399134ff6f8b0fd7bab8f6d32cf8766decd9dd7a6a6d653e08a385a96f089eb200eeacda4c2e28ca76d12438332f406cc93361f9e504c0f8683d67e28c05791322479c8f53b4b19129d6cc3cdcd4968304af4fa0bdb92c8c18d93ab605b43886cc32187383c9404e4bfd8133971ca46d32fc5e251071b6b4e06e4aeb7a650bb2682b2b9384127848ce5911a14cdf71742c3b1c4968e6b31983a85d6fcee7e119ddb894ce673d45781da98db924a09141696222f57859c2f300f7a0f316771cd84a5420c786cadef25ee6df3371b6762d0a99e7cadcdf39eb23e8727928fed976b2294c9f3107e76bdaa785daffc97736d5d6ad83a7104609c4efbde479f2db3e53c238aa42fbfbbef0fde7db904691aea2289989a982c53b6bdd78a15b0159480abb207ce0c70bb55ca428d62321e4b78d5a7b82a85ae6f26c46ba13d160187b09ed8ae0821a6ea29eb021a226b93a0b264f2bcfa9f608fc2827ba0a43993c0bbd754e8f856b85ee14079d151909b2e900b49d25198d2af95bfc825f03ee1052ecdf381d39ea917b8c1d519bc3ba5b3c1fafb7a69d2b5663e2ebf0c4a9497fca7595ae97303ae051987d152c47a98c8975eb1eb7dff4cdce52bba8ec5eb68aecfeb946369df14cc807405d2e369bbc9a872ddb612b5baeefb8e34ce99af87fa51c7d2c33de8d6e9997375e88743c133eded419326237549794b547c4a5a22d776765adc4f49501d06d60a779f6507a3ee358d2650ad3b22b9f08ee149303038c6caa6225c322312c00ced250f8bf908335cb099c3f4d45fbd007807583b3b06352c54d86dd060530841014e572d80bc3f2fac4d867aaf892bb30b460ab0263d85e5663645dd6b1b47dac151cfffc4efbb08fa5150bc1bc80159fd0af9db5b6d98fdafd859c24d9809640d02b393e8e892d2025f2d6418c7d1630bfe3380dab7d016739607882b903c21717bed143f6f9aeb8d55d63c1b8a790dccd83b7e79cca96840facf2ab5655e35387b8a89180d90ed6625bd6bcdea75bdc381d36864dbccf7c62422d76e24a96dd43640597500da9922de3a4699a4ca25c12c0a9b9c4cd0fd47bb582876744dbba633528536ed68affa96d5647f744c5cdc592e893a784e83cded0422c7a3ff4d58473f4dc4a2283129958383a28c8d115d70e99380842f0e3ea1ad8f7688e99e0682349370c5535f030e33a3a43acd8d97419e5480d244c032c450d9d35c5f479e42de53c32802965fb21530a1b1066936a4a8d246cf1e430bc292029e0dce5af22c822c9f4a0241c60760645180eede7c9044010fa50f792466658fab98d4aafcb41a7e640276acd01c01e09962a6d3c61b27edbd84bc1a15e99630e987031a10c29d29da2468f2dd4bf255c088bcd055d31d98248fea314807b5e2629e1b39c874b0b3f3f4e2b69292b3da6fc2d7b090e4ff9fa7170ac6406c57f14e408826a0f0668d0edc87c95d2490833d839d7ab4353c63d13e05d30c4535df5c057d1286be5768eef903a2a77626d5f1d2ec61d5df32393b395aa437c887a7f68baef2289b5ea2165c9fe8aa768a8af2a380c30795613e0d4c7ca6f3cd5c5304405fa9131cf56e7033b5570356f5da0b964d15e5168870ece30c2e744c92227099c99e190ba0953952fd6f133ec00a5732e3ee06f2027699ecdf265594495c0e37b7a49878cd6a137be32e93502c4e36fbde42fc10fd6164464a8ba7317eae118e5c8994ab4c30d350341bc16c67d42ab2a5efc5a00da5a0f2e2f370132289efc906586648a2ec86568423c67f5d3d20ccc5268c8fe2fdef594bb3f283e3586c36e48eb0ca1751eae000d6a9bdad099f0bbae0349c3f0c6e7b6f5374ac2f5857374c0a531c98c85bb6275c4d7830dacaba15027112187624882fea46837f257d93038b266a0f4cb920e9e04aeb43ed65535a994aea39c6ff6b0d632436af283ba21c7b02d1f117ce6ae48d73645a1a19662bd69e57da869a2207c42f14c129bc39427e0e2ac7744d9040fbba4f9194e734d6f1cba556622bfd3c5207ab2dbe11d94cc15ebe8689e8fba9aa5a86a8e113ced3204ede87d737cf3c2b37cff0380db96ebc5b513df158fcabeab3007ccf395e17a21949a10ac1177b3b51c09ee3a926ccf772d385c47556b088b46428e30551199817505bfb31fe1916a672b9bf63dd83c1e67f31a768dc238eeda74d60337a91c6623bd93525d7e3c483f1bca991bde297cf475c22e22c828aa25e70f85027213c9fe112eb71199b8c8d72298caca5308b063e62c62f63b5c09acee5a7a38278566bda35ebf304264eea8c0100841170728aaffbb9898976a1d5b4acbb4c3bd1b752dbf274d7d0f90523fe559f1d10fadfc890794142412631bdd046a52db9eeea3ff624e7c1c0138b81996b2695fb8caacb8f88aba245619060eaea06f6bb65434e765a036ccf046e6c76cf206f135a8a94b1324584b116d04ff049dd68e50a34f80c788b59dc6b1a8da80c3148919c1d04f577a8f9d5a337edd5dc6632bf159e1556c838c1b686ecca0c99a698d5b04077cef7880809e3ba740e5e4e609dbb64211ce70c03a85369d552e3cf4c05d3dac3eb409774188f67457d71d56cbc41a5e8288a5279034d9420a2a63ec6eb9836d979e7cb0f290bae74817a9310cfe5cd62084228b85653678408a697884ca97c713beaa78a96b7a3e7805f4160646fa95e092e048f7a1ad2d6c4f34763cd2cbf647330e3979cfe70498cf5aab2f700d7dfb8267c65cc6f9478a7781a436dfa3bb0602eec3b9a40d520c71354733e0e1092b3b5c74f57db3f2e2fbc73bd9700e08d3b2ce2914435fc3ba50a157eb22b8c2a43a0ddcbe2217265ac4b5889194c51fc4ab6e6b1da5eee1a644e49a85b0e0bb6a805373aedf6e56230e6bc4cf381396a2c01e75462be4c9a4a4a9439d371ad5ff8d151972266b75cef037208bbdad4e74e72455ecf2d1d9d6c150c208ad557a868f99c7c1bf782c6cdefa80190066198bb6c37858338754bad9aa9f589ddf3f640860594e479d9b76d0b3177c22d0405c524c694a397e02dec86b4976d0c0ab00b97513afd251fca8860b8efd3ec504f52308d83e169a413d664ddb4c40bc0ab5b1669ace816dafc64b7211f3ade0404c99ee6c752d688867e4ed31c53078c19174bab653fb84f30edc4668c90f352989cc521ef219636adf6a36b3904284e85589e292ff84764aec745be6f7d8042d011616a76a22bbca3feaa0234b45816e3e25c8bd05c319471d231a84f631639060aea43f63a658eb61271c352f2ac0a869513fc38762c0566c0bd4c3b16aa02063f2e52010968d7628fd320a96747386aaffd35d6ea3ef5971bc2113683d36a3534719585e4c913c2a589fd4491f49f20b8a84f2c63b5d746a733bc0263dc9f7df2387ee4ff680a93952dd0f7b4bb1d414423bba70183982b09d1f9d9a075a56974b7a2234212c17e56455e6f242304b214d8f59d83b35f257d40a7b094a8835f3e0d3ede43aee96b9668db33948f737191740a820ca6aa4a9cb322e1d995e219f257d2197f5e19db4489b3279e360026ca8d8487dbe72021d64d707c05795ebbfd7babd5ebdb29c098a38d28b06555d7bc7383e4334df80c231a6654cfdf97ef573a96fb86a374d4d64504830699b2d1dcd15d97e880c5ab42b65fb397d4603f9bdf365234869f5171da5153b9e57d975989e9cf94c1f2b3cb2b0a75573b43d3787115014c668c8e6e9f931884966108aed3982bcd31944bf398318a8f00609246026d48474ec75ed4d90e7610d5d00ecab8ede9d17bf8415a0bd01a21b2b04c1052edbc7b1a49faed38f8a834070c3b96e87a6c2c801e9fb82d46da2caf01cc173e4f6d87d81eb6f2e4cf5ed9d33a635eb328cce89f2832d1f4d432746c692f852a91727a220701f5c2c53dc29ceecb812ab02abb7362d8f09c30545e0535fa9a8d5cdef9a591b61dd233415d2df3032ff7a13d95d4db030d9633f96ff8e1b3784a86fb554f2033fbc084e3f394a91dc7da6cee70e075195195e60c4058bbe435e48e4ad3eb5dd26a118f4aa82d109554894c5894c9e1f9672cb0f6b1f3b85fbc9776b0510188c86ae33738b523dcac7c1c822acc04bb0b4b184637136596938ef5341c843b3da3ba1984a1524069c0561f08aa1669aea55748a867445a496e7b02759cacafefa62a0aaf58a2e4e721e0ab701ec3eaa9b06d69a0dc30f84c2cf60e203e0c19f82bdd8213eb982ef380f1ce982e7f247b241121638f3fc81d30d3963dd90b6f3b91fd9cda0b1ebbcf76a01fd5189b38a9bb4a380dd935494a2267f8243abcf106076a3c0a1fd348466b9687e2d10a51aebdfbc182be1e441d1ff7072cf8c6524e8d86e3ebae237e70e05d75f7eb1de242c34394d64838ab098f5e4ac630ae54f34a8e1c646a42dc3ddb3b96550eb913c4d2f4e0c8aa558d5813d68b0352635fc3bd75f7aea65a21bacecfb440ffe18f88be2a288d02fe3b4fad230d33f40a56c76bd20a37f796166e9a19989177715ebad5e1122fe66dd6319aec725857b69b6ca946fd8445aecb339a97afa1324b0c19ab8c1608e695892898891d135d49eff013a6093139e3d861d4b39e046650665a6e29b5433905eb1a95966982c88d0e5c17efa0bc61e4b7b24c8ceb27a20bfe93de263bdaca34de80a7dd717eb871d805f7c9eeac1867df96fe17984279df50b5f9fdc50abff5581021ca9234b9f3eaf9f63fd3e092f83bb79a874e2550470df977089a51267ef5a7d7ec0c2f4eba251d26abc03df26e60bc25a968357e672fe5e84c9f56da8a68e4ec9e752a9cc41311142033ec36343ef43573e675f16009a4a1ff695d0a4a68a2a617f81debcd2dda17e49fbd48f98a68a4300339d5401980cc570bd1eb845fb09e1f5ff3cf95a3054ea4c160c5ecbc157e35139713d5aa1d41e225f1acc2d67a81340923e93ab49452316287a19ca510017d9ce02dd9cc8d38d161fd8ef8bc61760a5ad43db2d88ae13ed22ac3726a517972c40031557e93945d75d6ed4bc291ca7c55574ae035f127d305c1067501e8128fdf13bddd96d1883b83504e4030aabfe885d30145651071934dbdc5660d192412e4326ca329d41600842843330a27ee794a04e7f060d00e080c7363e078f574c2e90676b4346bacff3be5ee26e9b50f15ebe4f3fa4318d5ce7e1e6fdb117530192f5faff8bdab8dbde524a29934c01890891087908b6c48196dd94d2bef1dd784f8df28652ea39b8d15e31f82002d310e67e89966166e026387291ab22dbf0be300a45878676c07142e371e9c1a395d91d1b9b01dee9ee9ef5062a93d5d4eaeda0ebbe99c6d1349d9b065e059e2f5ae1a457ea54e5481926fbed40cf92769c287af5c8ae122ce024c735d752c4c576706c78a847e0818de7813b1c00fede6c0edcb15aa175f84f51885a921ab16c20046108a85a57bb1004cdbaefcc537e87b82217e8fedc7b6f53a92381e445725fafaf69dcf3bc9776a1025ca63415f832b535fb2db9429ea29776b9c8223bcb9bfdccee8ce6a97e5d988b2f8eebec77f6bbd0b2ee7361dbd090cefbf39776672e524aa9e5b9eff6feccfab2483e8adcb7b77699647b6f0e9d3fd99f5a520c24fb0a50806571122ce51e177d362fedca6297756356a7da5ae79df1b8389add19bdb31a34eb993b05ea7402c1973bab41f33e29726f2eebce66ac1a7467a3d19dd1f928140a359bd5eac2528215c828052ae2a2c7b58670f0536e59add55acb707cad67fca94c56f3648b96b22577b97fe1fefd1185dc37c4337c504a69e02183572a83b5b62374adee6efb7a5d9dd75471afea2e9754c3df1748909f5402a82be2e2e501ba3bdd4dc77291e404e6fce77b0cef215f254426ee7dd97a6fd7fd00dbba9b6b4eba5cd2e549d7cc13f8092cb374591715dd859a4d939245ffddcca118177b21c1fbcf3c8117e027ff1f7e72176a681d43340d027ac6df398a5ba8cb4d8aa1498d73a0977d340d273fd63352c668315a8c16a3d16292268447e972b9a44bba7ca40bf25d8216fce122872a822b168bdd6a802975483c5535f4f4111380e8b9582cd675a21c980eb6a960341a39761d2cdb4514ac384a80efd02908235a1d727144e3388c69d9abcd933fd7bda82785f50c169ecb8b8d23561ee57835cf95733ca5a308d83f46088f7568f4a4696a9e13da05ab82d6019b2a94d0b246ef7936ac75a157ab61ed46f66a23186c041bd99c9ef15c31af8919c4ac70a253f6894ed5982d6682148cc2b12a9187e8223ac549cfd593dd7379c78946b051cbc3f1945767e3576979fc72cdf19312ed4215a275c8a6b9a3f79a46f4f509f97d758821f2f8e5effb48a49127eab8eb636b320a1a79ca0c9a6bafbdf6babbb9aeebbaeededbdd4efaecbae62637b9c9711ce7b9cc67f643bb59ad569ed7f28425b8bbbb3b08dcfddddd8d236bd96ddbda8eb338aac033e3900898082cdea6add568b4d94c261bab4cac32b1755d419705c4a48913a1274339fee3d3c3936f5f9bf666da962bbcaffb1add1787e7a9695c560596b29b43c9356e71bcd8709589f7d24076efeddbdc8bddcfd3cecefd170b44374c15caa3845c7801c60d57001dc79de4ebec884a506badb56f59080a6e5ca5d66ae1b5028c802363c95c383cf03cafe49556565ebe182e2d2c2b2f5f0c9716161446803bdb2469e4893a6971ed2888b035a9147237f809cecb7f31c64f44e597f0e3b818e1b842fbb2572a954a5ecad312f5a8473d4a690a9d29b7f4122cc9929412fff5bac6650e8d336024975e827f05167d090ce242991b79e14864277bfd3ca4cca590f41e18a469d9eba629fd984ba003699afeb28f1c426099695d5c9147e94229a1dc3829a1a8a8cce4c37678643eaf148f0103965a6badb5d65a6bb5d2bdba6eea917a0427571cff02e7b1ba6875c13c65753c555d2ed7bd2c3210745dd775316a54806f28a4918712f6144bde3b4e24daf16ad72aabec6e8ec3f8fbfe51536745eb9e880d07c2fce05c47872a59c10ecd86035d47c7a6ae56ad556bd55ab556add56a9efc653b3cb207f930ee423810d9fd03be23bbe60b704fc9272eba48d42d2275db74f62167bd0881e5a394c03119a34f6938daf7e84e12928734c38c2b026b140193defb497950b98347cf2ca2f72a09a606942ffd0f94ff517af92a811fca7f220a4a7c7161f94d9a9625876438ca990f94529801510692fc10bdf7ab2e8fbf5a0da1e4d00a0f3989878f22a370f4a210a60612291c85de8bfe734caafc889fc0186a0db5865a43ada1d6504ba6a4744e826e3767cd93dfc82194921b17bd888b44e8c1db23fef21c1761eec271b58c68c9161d1a1ab236e5f562c509766060c89e519063f33cafbdc62824af5b44aa5efd7171865560b05ce9544d51bc92ebed2b278a7d99eb112ef0601d129de292e8d4f560de4a1e2b2cbbccdced3cd168d431912421d45abbf667bf4c6be7206bb5b59816ecdcdcb4623e383b46603dae1c6badb530503b72794adef48cec46ba546bab937068686805b22e6a58d6ddb6ad57a34ffe337ea4693ae798ae395d413fd951b2fb162f0ff2b9c945ea2b68077994326e87d605cfb4b2081da28e4c48c0f3e504f1ea9349588cebfbb8b7b74e97db968b3748d774855a4c176eb084ccc68fbc248a07b074d954bd7714031a55ecb05aade46aaa1acf8c80254552dbdc07b88c127fc0630f098d6d1b22c76f75b9d50e352808813fcbfbe3ea9b17943d2ece2c755e98a2cef0993474af47c50ea5a53c7256e0b16f403821af9dac97742117238ff6a9cde919087c8dc50c2dccbe5e73926ae8ac15c7ee54516be56ee5aea8e32e8d465b828f90501073c6a07c9f1294c08282310d02064104118495374104216f826012044f50ad3a32cc64e8992b49303578dffd0fa747e02478b4b223b0748c318e23704b1e7bf6d3c6130cf002e3483c5060e01195472067230c3c72f98505789c8185f9f5c7194aa09b04991f8120f583cc90ab618c8b1f13f0f849d28b2b079957390040f8f3005835b2b6b18ad42627c0f6666db248bd91ac2336476675649647967374765aaea9923c7ef2efe17c5c40319f99cc459211d8ff063b645d955a8be30a6282b5b62d103bdfce1c649e80fc69c10f023de3417ac69f24e1ab1100f736cb642f353d436309b602b9f7d6dd2291a8bbebbaae13891cc7c075e49503637d9e2742e2b2c3dd7befbd3b17767bae8b6b39fadab6472894f83f84c31ff048472494124e7109598e93ddfb7ec0a2910665b7213d1292d88cb2255d94eb3a3172d4ee73f290649c6f5311e8f99deb9c3d6648694f40e699c7e32939a5a3cc966fe1b5cc2862655ae316c6daa694524a29a594b65c517bbbc8945edb3c51a0ba240b6b9baa2e51fa5ea54d15cbd3b746a48a257cc14ff4e98f8dd2cfa104cf5c7328c19ec77a47a423789583cc01e8190a455e794774349aad1c87f14d56b0a375b5db01b948bb5ad8d15c84c13a9d6ec7f3fa2b7f2b2e91dea3a31557590153feda3e7b17f444df81dc7b7574c18ee2043d9e9360903fda57969214030c2b2101ec171c6822842cc3285e41d93e90ac726d63d743a68fc191d362e4a0c81449a63d8cc2f1caeeebb2accd5a9a67e977344a613d43bfc63b2117693714e462470bcaf4bb9aa73ed3ef803c35da8e46dfe7c663023d70b65f9f926ae883e56f9322f456c36b1b028f1f174d9f529817f92ee08238804084f40ccdc12ac9742753fa4dbfc665a7e322ed763a981178ec6099feb54d558ca75ffea62a4678b5e8137d172eb8162f32a52c178c4cffda7a8652fa75e6a91f7a6d15b1b0c7b0442ab10c5cb2256200946b7dafd483519d24d7ca515a7532a52a99524ae987c1d255bce451c6892b3ed7e7ea6325e44aeba141ae31c0c955acabe6810f7260c51362202832034ef605cfaa892a327d4a9f73e20499fe652121c9d4298f231c34b1824cbf99a87db5562f903092c1441399fee450f2bdf81d9e12e54a05b5914c0c31c308dd8b52dab46535b688ec6d5b93a3add654d52cb4c0b71c4a30cd028f6f032088a0051142d0e2eedc16a56f83b2ac914fcb40e35f1a10f07fc1812643182f0dc7457f224fc0f3d8b21cd6f48c0f9e61e76ab958835a5ed81ec0c8deb2ef1969eda565a7130cb243cf5ce00e215fdbf50b746b97766936b440f4dbb72ddbea5e18c76b05c47eaa5de2668923d33eb56eed48a4090c5c50647ee739a7f7e8af1f437f0de75740e6ca83c54f92e226f8331748f2881a8d5c762358269db36980c711b8028c4346fee3d363d4f82d9b4994285102a684cfce14d5f33cdac8f26d48176a963ffa01cbf7e68be746839ddc59e4fef101cade1c89349ea0ec92e5db8083ab56827678aa6930d8c9b2c8ed4016b55ef0441e9b4996924e9fa41e5e128264335410cf937c9c024c5f78c65596a3e83f50af336453456ddae59962a698a9679657f27cd3cd24e4aa2fc8e4e3829809c854a32c17f0208f265bcb054dc8a3c989497a8bab6b4bce0b4df6b837cfc481a61e1937af37b4de5423b55563d5c755a29d8a7345939a536175a7f650e92c432d2c96272d45443725f247538e0cc7194c642a838b252fb469cb23cc4d509e2d489a467ebda91f68152ea24ff3a51224490891270b80c873e4514ec6cd142b0599389065e885a5039c9165a81aa9384d9a8166046c21e4d5d634fe2d2f6a53037c7f6c71b5bc9a864bcd60a2c5f9a309499e3d392d3979bed0f234bdf2cb120acba3490673c1c444eb983fb620c926277a66fed892823cbd1c834b966fbaa0a9079c11eb99f91e9d2f4119b7a0525049a834845f58c75578a7f4e40a1dd10d1bc12decc2397962569e5f6f63bd1139110981fe32e65b5006175dab37d36341c2f2ea99590a6a4d95e85b7e579b0834c16aa0361d65228f2dae175acfb4b83ab0c5354fd3143331d1aad1cf37c59a46e6695a92a7690a1314793ecbd0548d4293f77d228c396ebee7a39b0c2ea68c1b0d1e3cb6b8627996825c123429e999f9b5a5d61697a76a9edf72c4534dd3414e9edff2f2944b9edf326b0172556dc9c9a296a729c613cb73da9ac8638b2ccf8e45d3412d8f2d3f79b6c0f234c53c359682649e1a4d4a728fa7ea2dcf27f268f291602928cf3729691aff9f3f4316038c1c082168ce39e79c734e1a3ef8fd4022c02a34bec67be2c9e32ac7fff980c709731ae2b13649993070ba4023789c309724780cb283c6cb7f2cf0386192f3c13ffe3fd69c193f561d193f569ea9ba81d61e3a25873cf5f2fef409ccfbd3db54c95a8df6d0d48c4681688d324179ff5e25391c7ce4cbc9eecef2fe5196cb356d5355e3639f8bd3358f782afc70e4b819e188b18cd087680ed221fa8406d11e90caa8cf8cc6002910486b2065426db409bd71911af1933f0e7704e77c3a3c620d70dac0599ba76f0873dcf73d4c84013b9b40cf2fa0e70f943906d8d945661228730d5006046d4601bb499635796b9bb6a989ff61f1bf1a7309e98f8b9e6b181bc53acb15702442e39dc403d527945f6514945946791aa7d84b134b8841ae1ec02b2cc1348491af5785c94c980e3e718fac098cc3452caef0235dad186009fa008f9225c15601ee1c83c1ae10547dba420df03861a695774aebcaca9f8cc01178c0caca977ec2563ec43f775c36346343fec47bda063f40b3277b1732251c2930337d97239eb2dfb943f92579735705660e37cb503ad1818e84601bdc154b572fc4a0767c220e9697c15fcc08b3a46ab52a7f33cbd738a5206699241e520757c932942a34afa8847367eacc159cc063d36c20c12612d9e8028f1336064165fa5e8d0c9ec77a06e646a0c1340e6846980df9ccea8e118a90c749eb9ccca8f42a6f7f934ea4bcd1f06dc66a1c2381eb73f314a33114b0e685d51783c34fd25a3b613b3595164fad694ad8e66c090ee4713299b6d2099bb039832a91197efab1c562b29b904f4f75526715c8e24802773892c0a46c859364600c0a159a46d62cea14e08b1178acb1779bcb6253c57155d6759d4c8f8b5e67abca841330c84481270964978b9e99b71efc52048e3d177df29f7feb19953cce5b9d5cb4aad679abf316ab6517f48cbf0d4062222d6a4398372713c7fbae7b51e7813526aab3e99a2d17672bbbad3d555663b19a006e9e3ac606518dd5d8bd2c36951778b5d64a0309586ca1790d4bb34c6cccfa74eb58231c41ba708356555992bed134f2db02f7c08a8f0631e8191424f846aa706caa6aadd51ad127ff0ed3d0c250c051c21546b06c60a3d9f28235c6e3a2cc2693559bdd81a9006661f5c72abba93b2e6ad127ff0a86adc276e8ac2f18ac569c16da880755dcf17db53e0ef07c19c2c8279245492af2d9f57b8c2828f30465e64a8047549ed4a5b52112ef3ee7a9ae3b5cecd0da19aa8bb4d6703a48a4f2e03e51e0392c10bde760cf5d3df3028cbb7abf96f27c0e5317c366c15de0f9f247cc926768c30358fa0ee71e4503d1244dad6756fdfe33f391f5c4785cd4c9af232e9c96919b22923564071d5cfc796a4ae9575048734070b8610136fcf041830c037091ae34617aed0ec776bf73d639a7955e84d7cfc91b98577f0e65e060f93d7fb22411978ec51319b96f2a4bd21d29df815c755b2c5a288e4643f268546f9ac67e0d82562db23371d5bca9ddd893bb230473f20a47eeca50a008223b105a905aa3d813980b45468495241e148551133ff93b7109bd464f48454846442d190c2db986231b10a2969c3deb975af747faa4d55eae137923124a09a7a8acb0b4b8c4f85e4c303128c898f1604843a6868d1be26906470b2c80334415be5338e9c8b1024a85d38b27f124de10df460aa793d8020b366a7c31e00a281d396670a4e02b3f782d237dd26a2fd789bc1109a584535456585a5c627c2f2698181464cc7830a42153c3c60d31f77b298c7aaa72ccec68c15e4eb4801b70001264e5fb77f0144bcbb7cb778cefeffbe5fb657fc77c97be5fbef0370adffddf34be656a7cbf9479cac6f78d6ff11bfc9ef1fd12c853a7c7f1fd9249d3a8f0dde5142c807bfc58f8151e07585b4ce14fa06c3185ef1aef143020927ad07cfa1b2403785621ec144ee14824872f7f470b3c421b33c09816c3f00610fc6ac4e020822c321f901b20a6c112c406380ab1901a20078e749001e9873bd0087f061882e13824cf78f90f8e483d689e11521921c7b160db8f16712d635809f40103a41303d260a2edc08032bcfcf098c0017cb3d80b5813c38748cf07bee0d2b29a18e0aae58501b8803b585632b480a8951d34b0803854503e5640b145fc29387eb0007e7dc2bf02881f937a50d10614c8f509bf0e107fe903a202d216f1a3907ae05cfac6f5257e12a907cda56f5cca01ce80a41e34d7909278f8885982d862c591ebf8234f9168439edf62fd8ed483cae4ba803c63b8bf61047e3706070f64b11f105c593a157c450adb1dba9d1d8ea2a493524a6bfd72adb5d6da1ed670a444aea44d30c9bd04095b1ec52548d0f21371091241795a8f919fe4720d452359fa1ff84be19024f287e0b0f48fc321d8238d5042981a563ee513b0f229610632b012262025032a610a2e55127d4982a10b850c7069c8a1ee771f137e3507b8c318aee1fc8942919c52e1719eea2641e3d29d5ed31ad2affb39c37136f68027bf651a061946ce2d734f1cc2008f1f65d9cc97379df33755ddd39f2fae7ccc1ba68af4f3854c15ca4f14f049a296a0f488489f48bc9609a9c08f9fe59311519e82f1bff43fb1746f885dfcaec0d741cea2a8fccaff50f9957048929b128e62ee5ee587cacf53f72a617b28c3081ce3291f51e07c8f65e4f3df53a59f3f5ff4d47d1470d4c14be0488447c9a3218c0c9de9c7d099863bc2c04ffd51704a0aa843cd387421481d28254f35e9470e65721cae99a2fb5dd8e3287b88237b28c72038b2676abb3e78f4b024ae101d5cdc00de41880b05e9bd341dc15224027ff0d84142380e245204860960f42e240c16578448d3c4d019c654826f04e22023023c3aea083c7f8632f37d5ac0b38490917ad3040715c31ca413b27dd31078070a35c3f1b2f2fcd8d04e10ec565f36996c36ab65db8fe2fc1135ae7ad457167d8ddbb8593373f04209485b1685230fafccbd046fcd5d1069cb5d28e5cb13fa825cad00cbcff1022cc31462d8822f4dc0341c256c0052c2c8aa83035b2c4762698bf5782f4927936c240523030d2ec3d1179884652a3e78ad802a8498683191c3dae2eb0f4121f183974d0d61e47b1078f0b219225958c05a363c7441d8d41fb2aa814d0d93f8f7f320a5007cba0fbc69cb3403816683dacd0658c0666dda9a6492a322ca846ae37c4beb8e1be17ab23f1312e451e6c4e451b6382846d993fde69c03e130f08861be985b6d4e97ad295bad9a8bf23520550d90277f1a2d7a4543c3020b2b59ab4da0860c086ba494b77ef946344dcb2156be5030c0d342da7ac66b562ea2bc3b2f0523304318fbf343182a67795226b61edce254c977b72989714048d945fe7ae897cbe572c997add46fbf84628a46f54ccba03ec9e74490e58fdd857416165d72c1715f2c265f9d831a5096c0f308996a9f20902ac99a27f95c10d804597e4b160ab2fcf981a6e142723d64c96529e7cbf7987c8ec3f8fb384e4a2992d207a692c562f5cbfefefe1a7aa6dd45254d72371c39fcfd6b14a74b97a7e61152942f5b90a55c21c762afd82bf68abd62af19fa0dcb15503dd3bfb312f35a669c3b79ba3739ccb9cb5fde8fee9254c8d3b43fa511decff7d9aca3c851d0d0b0c00208bebca4641bca294209f3724481e9fbcff74cd472743a9d1e93455eaea7317cc0fef254db4c070214568ba689b98cc9fa98809140843cb3c873499e3e459e13e8fe5e6b6d0eb2fc1d008108d77acccaf92ef3d4cdf3fdd682cc7de69cee24cf6ae96492e74bd88f2b4fa993e74b3945d37473d2f7989c727a73c43d9d241e720ab0f31d2515397cb07ccb1991a7e8e79b5e5ea74321fb90608af20416fdc8e599250a65093c256b4ec99a74720710bdf7354ea5c820111baf49338011a06ffda34062cb3acc5cbfca59aea09c657f397754c0a094caa0db57d068b323d9dd36a2c2873cce232d3f27fbcbd0a6b815218f382a05739f52c8cd426e1ae9cd1dc89474b9e8fd6c427251602ae4cc41f69f4c4c215a255f7df2ff94804262bf89b83b9ba1cc48e16c14beca7c9ff9ebc661d7cdf554facc537307529c3ef89942b8380ee3ef5f14a7ab675cc25096c0a3dffc66bdfa0d28709348323cbacb5d5385e264b31a9aa6bf297043310600d534f4e5fb8ddea8dfe8ec2a719fe4fbf7a967fa6d25245a0135d05122535263f96006373c349e211e19904f3a435905a612881cfb29a534e43c176029291de50d546b80f9b75f50a711cf0349b0b5379db4b968e5d49c23d0e931d48e19aa5fe80e5714c83cc9973f5f2f4fd52c7fe64853963f6912c6d271d293a54bf96d2b75dad840f235c39802d01d9a667ecfc8f72c7f88a7645e8680e7ce14451c6ea0a183c7961d79bd64f93e7cb234c2666c201aa402172fafdc7fe3881aab1711383468ca9fd406796af498ec22b7a746c7e1845a8a3cd227b96b114e1660043158d00d9dc512245493435d841c21998dcc13b1d11104f647f5008bbffac0516698f768d0e96982e8d0549d441a5084f91a5f811ebb3093e9f1f7347d7d1f8a79d1cb214fad56289428fe7f5f100d476ec8535d0cdddbba33c3a30b50ee7f79a198af3b1cfe5e44cd157dc171b18572ca0d47ee0b470e7f4b38bec8128ee28a4a38aeeecdc59ee18b2b7c695d1060f92e409e92306067af3f05bcb0b17d7c4ce0e82e0747dc85f2898bfd366481f832a8ff453c89005f89fdaba1e3788acb4de50c7ea081980fdcf8c10f563c58519aefd573df3220cc0fb195d004209a8da8c4a6c613b189593983ba85d6cce5937bbcb4dcdf3da90512a475904282dce572c7919baed297d64bcb5330362cc08f788aeba15da7eca269beaf58bdccc3a64ae6fbefce54ad421970871b0c237ff5446c14e0c2cbfc8f00fc2a002fc31f2ebccccb84435c7822363db47a9a1f6550eea053ee6f0a0cc57899c8fd7d83032e1c87f1f7fd8bd3a5068b81d3330dc2fc9019c283fcf971c22609f8375ee689d8d400617ed478f1c570888daff1446c740081e5b5798abef8fdd7c9e9fbefd07de2aa14be9f2bc2dd4c950adfcfb5381c57e1f87eee08f79aaa99efe7609c8ef3e8f87e4ec6f938f7c3d1a66a85efe76a1c1357b1f0fd5c13ee36552d7c3f17e42921e79e74aca902c0f777379d1157a5bebfc3e95c53a5fa8ff67d6133e569844f83c6cbdb9573c7062ce8c224a3117ebf0b932649573f08d60ea7a8acb0b4b8c4f85e4ce0871f8623cc83214c0ffae083e118f3f43f942f17403b344ffd34200d00b80a9a33c291938142387efd3160f571b1c16a022b1317fb5fc07a73b1ff03ab106859a035025a57ff0a6855409b02da998bfd18b4401d686dd6898bfd2ad006cd537f0ab44dfcd40f00d0d6e6a97f07687ffcd4df026865f3d4cf026879fcd4bf026861f3d48f02ed113ff5ebe8cfd13f03d6a17972e2a77e15c06a9ba7fe14c00ae4a7fe135867f3d42f82b5c74ffd1f6daa48e1f8bdf7d1326a446598eefa786a74a9e5fed6e9bf3b9e32cd8a54d9ad5d26ae2a82b2c404b4dc7f9bb80ac5ea5e620223b9ffc6ba4a5d6a9e1abfff689e829130a9f32e4cfa5d6c2e4dfa5d6e2e4e3cc5d520f77fb2963c72c7c5fee9b11ae3b5e5fe0b8e9795fb27385e2572ff0d7008fec18a1bd06c784021811036326f031cb2c28dcd900e5c9b24309487941c1b9930090cfdd15d432ef69f7ec044b2ecfe0bab01b64d05a9100d72b17f82413564286732e08b15f8db4358c3648c04fdb28b530b8f52f6f21191711c607828608147eca212e3239ea2410a699a53f6df6148d3c0c060730e320ccf1386e39a05d3f081312e7e1d6444880e269544a2d54b88f831326d645f08e54953633bc9d8955d9e82f9d124a3562f04ad5805f07ff9e025e94cd48ac07195eb7b600e328a2376d443dc0b251891d99070f080bdb8810d69e4bd68eca02c1289bc1f8d462ff246a1e8a2f45049ee4b295f061789208548be0c1fb027459ee807f03a92a910197cbc8cd0201ac07c51cda29f4e7dca905779a443cd1e38ce6491f722703c65912702c714b2c8f346f53930c80ae63ecdd51649e2df81b749425ffee7975ec8dd088157c42c4f51fc5e5244cc6d70481ae47147963b320736ed0b237986fb1e7845e03b018bbe732f394150f6bcb2dd300322c4534b70c880839cd2a6a30878bee86b5c34c3bd65510883334bd08f4c806f1c816f982af940a6aa699c03719005904934c9f72f6986194618797ed74b8870922f08040996493491d25129c0338c30b2cc63db240b73c0935becd47830cb27a51457b8bc1c5f60520c28e42fb07c9973086159259d6ea3f16041674e8ecf48ca230590364cd50e7d030f2071b3e9c0182bb0c9f105f69fb94931a080043cf610a987e9258f0ec8d64933bc1460b67414981964a643d8810f43361dd85f38b1a152d4a48055b0c22a07f3540e90a97dc08305ac6bb0fadcb52dae6706633b89225b813f57196bc387e92cc51d1255001f4d534318186cae5fc355f6ffe1a9175c1c025ec9180d33c847e560f92e65400d40e5945286a30e0481d2a7f427a53fe9c8458f420af1079cb5b6732e7477ef6e5b2bf5e958605b7b62b087460d6a26a5b49df69440f05ac676d75a6b7d3ae75bfcd55a29f6276af704e9b44332fdc9e3fa9c554ce7b8a7949278d0c939adb4abd4d24b3beeda3a7dee8cd4452291e845a14824128563c7514ae9a493930e044a2947a90cb9abc3a44b3c5ba7bbec999e9452aaba1c9d5eaad5fbeac0e6d802d3efa7593e9550e03ce7945765bfc3915e6b030d29f07c1a44cc95629b89b10866d311e730c70f96ffe10eff678c3ad8dc4fdf29a534c70d30a507681b4ae988fda98c1b2c69add888ad2f69d737e45ca422d971e1f851120f393f5029a596d24a29ad96da5a69a993dddfb03bfa33385b67d7fd7daf03ddbb900b4759be75ca04a5744896df9daad54afa94524b47e0b5fdb17e05b9907371ce9ea7fe183ee09ee2f798c37dea7062295078fc2c235f288479d5c9d177772abba02ececfde610e2bf09c7376cb29e79cf296e5fc415669109e488ec3736887a9aa61ce6fcd99d9c4888b9d47d488cad203f3d8b439e54c99defd716f6dbdf37279ca26a532ee08af5f360c976d86c1b9e69aec4f697f0484a0f2e823cf9f6110549e00c8bd426e39471672ff4a079be77ba0db5cb39cdfe09c303eecb3903dcf1f69f7cf0e1b00204c0fca62d54c73937a48162b07a402a8640dd7553de910c9000000004000c314000028100a86432291502820d15461f70114800c788c48825c1dcbb33088719442c8186088210000000000048646e300638405be2940a1ee31b8c1c48c19156a1e356979ddcc63dcc5681fd1b5bc1d52a9c504741784ef63f6a08c32d038896d122c56fce36af4f92b59dab03bba317d89ad11438f0efc9a852b450a72069b6ca0bdcaafbb2bb20195f3eb8844ead74ccc15194641e29c7006dd5fe02a0d3b2366eec1b8a6c4fa173ebd61b3eae360dcfd06b2f0bb731f1a6bbb60eafa641cde77c167aab1eabe420a31e6daaad5dd26de00e593752a9ea91387280cfd2db6c5b452b127a2f0c595b335e8944fcba5acb48beea289e30855577e5a09ca7733f881501b714dce4856d34cd191b2151546000345bb2f6bdf00b98de8d04b60f7d37014cd4d20530a1376d3334a392151f5d592e4c29762a81e208f1c4181253490ca9a91688e2037b2b10306ddb91ceeafe2ef336ffbdb4cb850219cb8fa17c4e025f9d888711b618426ff307b4f7eec8a1cf0b19d9d94bec091fd10892ee41eb641956737652786432fad9044b78a0d0157d1ed5a10844e9fe043dfb47dd2c69315120b6807841d9e00400946115a0a057307443dad9d845921378d4b423a6f677672ab4cd3b827de78b950601a93c818025d01ae4e90ccf83134e89670589cc893aa4696345b47dd954042d38bec3a007cce0e63f3a9c6bc7f12623346863bfb3badd6ff1ebc7d63a9614657f2a7bda0d3e6cef9ff466c0882aba412e3fc0486301191a86620a895f56361efb431c1a6bbe69961bd68d622aeccba7d94d17cf067148d0e39fb1ed1dbe65c3e99d74cf74c18c4e80089b327e530f483883de20da09577b7300c325ad3ff50140bad12fdd09a78ec81538b59b0dfc28a8e97f02c5257e5a4cd09f4a9fdbfeaaf4450efc450004c6220b25f8256797bb8d97690b01eb222d0bcc058ac0f5f5cd564853c85dc8b93dd944153be0cf2fdae68ffcb40f2a4a691229d2df47f3a40cb3adb4dfac0d3b7bcbf45d8a107c0a55a12690767b7caac237f10e5763fdbcfb3e63c29f06413be089221da79d5c411fd19d4450f724834e9e8796d7ddd89f90622db88c6b403732f057e610bf4abf750e7755ae1936bb32b042930f5528e638651bdb3b01af1fc0aae345f53a1d92c69f9f6623e90e041e5c23a0ce1b51580270538f00607a87c3bc304cc7b8499709880260cc1859880c2345949db94ffc9c9a0a404d7a04067485b8dd655c3a941125f30ba8b10a88438d98a5365a55e951fcea30a43b69cb9a618901f3ea0d7301e4db6dd265bdd12d7e96ea92cdc16202cea790190ca73dec0deeb11bda0da6638eba7cfa154fc472cb3910c14f3fad56810e0a8158ceb425d2628c5815030df20fd13a6922526e36559ae14f057f969fda6833ef07e65c63ffeb5913097c47f386b3bf877179a9b4353ba9ee0d5bf5d4537fc1b942ed27cdd788d7062258a87e730d57aae28f78c3e158ac040fe50838914dce2fc0613bd7a80035145d6271adb50132a14a8316cb2501f9bb4830a16b062bcc6b1d983e79b6372c6a4f49cbd3e81c76f424b866c61d3c9a5a3bf11e736866b0eaf1c38f98d3af5c031b9f9a40b98d8d3f54408d924512e2626aaf594c4889e8c98e86988302d202297857feaa145d74621342e1db62d15c910bb21578f341cea6d0ca7338fd7c744d860970ea97a1e21b7bed1974facca1e391d21cba5a7cb25e9a1cbadb6bdff0226111f1f191d463c9cf311b8064788c6da7b93ca10e8dae4137a7b6a04fd2826b530d1de995fef7062b2577f8fc240842cad7b09e7a790c6cc8f38d90b7d64f820dd42e471fb23c3bf73dc923431c266486a2ad6696d445bb2c9860780aa4afb7db8e3543832451de844eea124f3dba2c6e79706bfb2f56a602021e09e43ea24e3a286344651267ad7a53f812133dcd4ec504aff9bbdbbf56a8bcf04c508fa8c45679d3c51c1889c51a7d31f14351fa9ea90da1b7fdde5705dcb904e1318057c9453bbc99a577fd102dcfbd661c726c28cd7d6a5f36288c2d99119d6e5a12e59aa911f8caf1d00a11c58c74d46549c36fc59e01178a9b444bbb9637b687f9d7e36afd4f6ab60331b7286c040069a0d82d6e9db4bc107fe1fb3b4915cafa9b855d3b7642a6031d1756c7199c020072f4f9319a15a8423ea93372d0c9e71b1936c0cd98abf661559067a091453e6e83c1bf8cad8ddfed9abc62518e6c37110a01cd67075de4346e795461b3e1575069f7fe1df9d401f83c9587b6dd4db2352dfa1d3e78ec5e48496e94b2aa66c2d36b88593ad3b5dec01a0b3c16e223cd8bfb7496c4967796ffea5e537fe407427fb378f70894300ef0d6f58ce83562570842a0d02ca3fdfa168eed06ce7e9c3be06ea8aabc0f57dd70f761fa199134210fa95832ab3b2ceeaac1fc88d6d874916ed3b332c34717c9494be84a1061b454bdc74858e5f4f4086b3fb7d35db8dcf80ae4c4e7c236f9a0fa3491a0b060a05bae67d52c764b856a0491714f07c981956f26c4447cdd6c1b00139d927fb77bb774e14dbde5bf0c24a01c020a0aa1158b05c6a71a9e624ea46e213578cd34fa702f31a8b35a8dee879cb17b5acc0e1168f5d237d3ddd3ea59524ee5910628bf8f83cf54674a50663d58f8b3a5785876c61c9a8cbe4fc2a9c24bfb63a626b59644bc134bc851980108d70ae05f23237f70ed3f03a452a77ab00006a86c6f76f1a593471f3a88b981759d9681f127dc92c3b33db01ea0feacc7f9be296fd4a212ae68a9a4f095f90486d1d11949b046ed98069757c7f36bff6ee3ba19fb380d714c05a0b8f3c66482f30b272456c51c39de1286b043d501c16b42283f16a7d29246b093ba98ae78a146ace4bce173a91222a3990245c62cc00ac82185bd979239aa81c0ea36a3b32147ee0deb7aa26b657e7296da922ffc0661c26c1d1f334006e486ca50e9585297fa9937a3e5ba51d11ea29de1d009c0218f2505640d28ef389973b5d22cb47bf3a543ad650c7c0689c9ba79cd52e6b09c8e23300e879ddca61e142dd51bd15aad68199719bf233859fc40391d38de5d41a07ed891009382312633e77c83a2437c6ba1da2ac17871ac1b7215ae6fe85d2f2d18013db928131fc77892f9ba726599859d4c0ce128a93b01cc0f5300d112b122e375d6d9d228dd45988f763e38a4ffb7291e0e85e5700a6351c825253c4da021ebeba5433a0080d21c85b41e4d65d150b2f8a952bdb1959b2818ed9286c8a9743e88eb40250282bc4b49456b8619a570c9826553b78efde736e9fb69418ccce5529df63079f4d1c4c796868545a699150ece5e92da9c4c47f63a3e741828fb0d8edd2748b205b36bf0bb580b370ce93e69499210adabf04b37447490890fc47f0053668536642c80f9b9a07e01488ab9acc8fc6ab817da9acc1beb36bc3a84e31d2fcb48a0dae3956255566ef3e8426fa3002623e1f3f69a1bd34ff4537be2d7aa218a5f71c19c74342ba8eb76aa5525353803c849ffe823df93ae352d8c29c15e687f9e280a47cf442e4de46e0f036f01f3f81d688a67dbcc6777f1cdfdebbe9436504a49c3c500ea01430a10c5e5cbf4568e2d7e27166188477a0f7f334a4356c78d702ef09da87253018fa140b83c6e02110a44569d786a605138019d55db4b315335aab8005fab427b4e27207f8179fd7cfd90db03f1cd6b74fd8369b05b2a48857a3c5ed99011f957a6b9ca35803151587b07ad80c338ab9a496b9a833d022432e3be890bd4e6de2117bf61426d5d8bc2ce97d7e4fbd5945e2318657f7ed3cfcc254348b0d2b75abbb55f5f3f79062b88739b90dbf24eccab32997e8167785f161fe51dc58240b83ddad9880662ff2f4e5e7e4ff8e2c3c23694a42603fa5e0764c3f8ef894abce88eaaeb25c09a606d6191db39fd320f7d3f3a2be3162f83beaf24641144a0a539187d63e727bbdb607fdf2f2485dfb4317d0b6b60bd41a335a9c824c348ad8443865ee2c47b698ae18054d9da01bc5194fa81d5f0d705df2d679a718315078ee7761229c7e48710554b360eaed716e019f1b36035153060dc84957eb775004333f4561fe48d9630c0ba0bd099ea1e7a9ed29fb736bfaff4c76cda00bb5ba5f6ad4e208f35f30212ea5d475937d3bcf9c40cd570331755c05666f28b7cf774115bce403ad6b1c9ee684b5b870ef4755b0d3152253c66942ac711c3b3a1edb1cec4106d0c7ac654b00b8ba4f7450e8ca4c07f027695b82954e9460c1b9d3326c234ba592c2d131347e603fccc3f296e491c570f61c3a757c22ffe8e827ce88c767e4b0ad7a74c0c67bccb64639a70ad241655473bb78dff6180846fd9fd3c7828612591ae18f0ae501a9009ae227ef1b1a07ccc8ae3bc8dd26f5294f6fd8514c8a0e832056ea4a81eb69b0a0ddf30fdc6468139906c5923e3063aa14f42056271d02bc914c22c1871771b409783d89404dab2694b9fa7019b27d30dc7db39d827edc1e04ea5dbef17117b59e857230b2741aceedaf4d6e9aa2743ea71fe066ab07aee5c011388d651126c2627ac3aa38e3755cbf0614e5ce437812684cbf7f95504dc1568fefe15a2fd08628247c26e714ad90c529b4bfe0f12b22ba34e7ceb2eaa0eacceb0a9348e7501c7b2ed10815a5cce2eeee69607f50f048d7a50a470fd5571790d6aadfd30d3132335fac27774b2b0173d39e998f4b67958ab0502f6909032a33e2f9d1a935206d07397427909b21467312cee66cf4d7d9b7b1e5b96b825064b30aa890c6c0cb77dd3f1644b8a9cb6d1630ab6aebf6b06b13cad46d5e80d8ed85f077ba0ee7eb94cfbbc45b9c773ebf7d1f4db1267f37158c8ddb1e5e7c4785d07a180da99af34382288436bd29bdb48ca4caadc7847997cc59a32f11bf5e235102a4c251be5a36b925216e1155378626327255498df14807f7e432772d1d724173c87932c20388d3536e5539bb02f2b06a4aa9ceba754bbc4091e3c5b89791b1fe18611a358b50714a7eec37fe08c9237ac439896429e9af4e97707a594b6170a9527fd3b815b30658a6f05e257ea695739eb36608b140dabe8fb3df203a00d286b2aa174aa24ba22e6d0a071a232d8e9eeb1c461437e649b9b43f7287da09e8d3d9451608e7261614ba0fecf512f08936023af31dd7c5406079a7bf29c60203af6b85201d84723b782e603667571aa67123ce3bec25a8dcc98b99e54b604e9bd959510ac6004ba4b814a32557e19aabee14f9413707093d1498e7c53b64ba9ee306467e4a4c2eac5177b56486a7549fcd2971296aafb5a4ffc5db1fdad010b183dc855403559bd71ffaa205c15a0363bd35966747bef2aad4924425030e9046df31b738f567f1f3038c8ee75828e8c77251f014794e80f2227f9e256261a113ac6e597bab14e72f7ce217e3dd7c423d5efbeb80444e9416a7c0f2a08aae0526324d14cf7c65adc7db0764a1be785c3151f2031626440e8bb1a31b15ee9cca466085a88ae083f0429c291ff4dc46519f84714427c009e76af5fc6bf47005f50efcc2eac0ead918e75931472f4c11d402ae909d54a1ad713be532f8851b340c26976c9be1f60c2d26926cbf22f79eb94594219f44b4bc2fd26308d6608176422c5268185137391e3e0515db9e9227d3517907338abb42ed551480db5d04eb6cae7932e6b5f93a00b07640b9abb421b2d2626cea30549579433816d7814790f40d5a12d9609db1be8224b2073aedcef986c0f5a039dade364e4acb4c08d484484d8eb531bfbfa7f0113d1e7f18fa5a345e6358183c08511a8a1ad6068a8da10759607c75b8617c3a1630c25579292487b19420e92c744c4032f9e8a0e3e0b608a257520ed574a03a7e07b1205c7109186cca8dc3f4b3be8279da30b51308a9a003c976bb916a48b2f8f9e6ea1cdd88504c7418c8f00ff4ad0678acdd15e39a9bc8e5b68fcca2da478771a94d207051d25dcffee2afaa87d958db50c3ba1b645ad64feba53c79f40db6dc6ce42a435ebda309b37aef0878e65bec9130c8a6d63278a3d0105da19400942ee669054c003cb22cb76c1227c252bb89f14552b6caa3087e3ce24ed578b4410abbbeb1f546c7fb711a4484f286f0b5bbb36efec503b85737832fdb6eaffe361f208df26d951c0f706350dd90baf77b426eabdb8f1e9d26580b08548d0e58bf9b106fdaccdbd5aaf6ae6a084bdbd13c35a42cc9d613f867425ff7c99b1aca2183486e4f8d3b362d7cad2811ab0de5f473d48c1b700ed76401ed5e628fcaf7e02147a8a53f5f2b9121e3df84dec01e942ddecaab18cd181f160963e8d593c6b6300e43dd5d188a2779fc18302750594c01b3c26e4beb3da3986a8db35c5cb932726497eb93479c2ae29e41831f888d36e738346ddc548b8e5e6d540aa587b2c2f43fcff2b421924eeeb2766cdbe37117396e528613ba17b7cd5956a7f14195cf0e7634580a7bec350d5ef8967bdb8b8970cc75db6a3844988079a5a8122bb5c6d81b74921f6c67217ab6134c4f4d377da58bda1839c97de3935dc999ef67c28d48fcc9c174eab0a17867ae5ed0e92e618b81007f02a13a2aab76daa48466a216809a6f3b4d3bb2c85ff02107c4b5c102589b2457cc8a9598ad73611d836a64446700e47b8cf9301e710dfb6dfb1c6584dd0b558792f19b002ed8e3680d6bbfa66f863d05deabb98880f28d06d054fb46fff6753abfd2703d2331a9ff39adb2b8523124179515f2120fcf17222d405d62240ccff2310f46c4a68779862e46862cadb069a8c726fe7dd3a27348e281f2975dd4fb721c3b698368512d26a6c1fa7b4d197ed103dbf0332f79c327ac3b808f89350282db7b511d3f46ed5bf4a42cdd1bdbd43dacda11dadc2f6b946fdc4f68fc67f0a22901cba66388707fcc38c4553c4a607e53f610886e9358d69ad1bdba985a39ebc1e37cfa7e8b309d695364be425d4b305637599b705b4039e865eb4b7fe62c4f381b32ff0db64725455ee1bb21231ba060046cf685b4f5ea3b7d10c22d629ab8859d29e293b560aa2144b150d1e484f009a09319fefa53d057f38e3e3ad64441dd4b4d6ec9b3d2d6d298e4f858d88ebb46ca320564b569d0bc1b4c01a553f226611c1335133b84a41adbcae70ebfb237b6b87df042cf1cf0e3d2dd38c345b6f36fb32f383368e855b3addfb6c42ea00a0efb3df0e98b54bfef1ce1cf50c0528552013d31e116fdee9c6016b24e8f9b9cd2474a1839f7556ed911d956e0de183f096d5cc67ffaa3077f34771b179bd6d2efa3687fc7ab42c534f801f5a340985a44b9648c7eff11bf4b154563b7e019c845a9a11cfaf4ecfd7b569b098e4e14c4185b3291a09308a96080cd0d46a2ede6342672f6c45d1127b7390aaa943c681acb84e4e330471c9910cfbbf957dde3ce3694386aebbbe98cab83f7d5cfca5d2c9312ffa31a51cce4173acd6a9e0f09aafd36771bbcbd2d74472d90997bfa47e3da32d7c7cadd26d312fcc724e2c232f37e38a39bdc652cab46f7555765fb508f7e0393d233d51527afcbc0e6fd0da198167c76bdfb82dcb40aede9362f449f06e14337ea9d2ab08ba0f33a37790cff8b9db51b1ffac1b8b2ccf49172b34cd907316ec31fd75681e90d15a6a0120ede08552848a14a0218a42055fa463fdc6bba6f060b04a529c8187c3e02100a6b461f381e2fef625e06a92d40fdda7372fb4bc0b41835afe9942b624ea7a442c5c5659c5355cab5b1a11697b751f8ee5763d374f2b5d0bf57144b08107f5185ba9cbaa0c3ce2d4d7ab52a082bb18017ea25330045270da1f5cdbc11625854e51301fe4a9f455b829a64552888080cf3c975a6ba342168ea8c3c77428c02afd71df9da7eff37484c5f3b8a4a27c8f4ab85a02322c215976dcaf6ba13c92d00ed022d8afc3ae415a23bce67e139c8a1059aff28afa3a03eac90457780434615e0f9571c7ce95d21026d7ea1533a4e427305d293e68c2996b806605e806cc5a6970a6d5e0f34626c1a9dc9b2195f748e659537d50017d122fb200552bbfe8e643a9d7808b094052f022c41d52e4ece91c24a9f8f3ac48966b1404d2fb21c10d4c0cdb530c1a52c08060086caf8341b8ca195b2b45beb03aa927e2337a87559f51955c13b01f9949e90ef3fe781fded90813a34740a2ad7402a4658efc4e6a2230e991a5a7fb8dc892d12b4cf1e211007ddcb1f0b7bec10776b61e864210acdaaa8c513c94c132b3c1e12b3f7a43fc0008eb3435880a714893a47e9003519103e475180b3a48a649f6c14d1b497892a2cf5b29289258f363a41eacb8a109a7bb34885d23ea36c1a5a12a8f71268cfa048bdf44f47ab92a350a0ad2a587f0c570252c29856ccae89d334c2a09ce628ba5ed16093d8e72a07f55a5fe67c04589727b7425910d3a28a4bbdac4442a9a71d4d20f9672308e6bd2c4ab1accf90262a7b35918918611f945285ca590c4bbf9a26a4fcace788a862dc7d90a228c507d3a020611a0415b8a8b087bbbf2c96777819931c77ef093e1e22f75f1a54fa24e5585446a3ce2bc5aab84b2b23422bf07b00d243c90d0185ab899145e421a529dd51c23605e614748b72679886f7fffcc102c4fcda1a38f4cabb52ff34930e247d0969956e0375ce70ac0256c04d7cbe2d5a0720b0e15c1727c0c65fce7b367a48f8e92928fc6b693620fec84f1817cac87f2d1c1a8cb2777bf329e4d16603a965b725c1b0b4b5c40f54a6cc24b3ae7f24db8562aaf407b7aef81268900004ee353194bcac075487d85f0c079ceb607bce9f8cd23ffce599f0493494d1162708f0b40fafc1e5ced662256810530b74d9d14e7f5c5a5a9278e97a016a73db12b038da1a5fb3a1ed497459bd129b6e973e50a74e165b6ee64bda9ad45356f1ea813c63e2a3366613452962efc3c512e8f3715e1db324ccfd425980baac216fdf56642c8b4d27d0d41d680b88eecbba15ce208d418077074e82fc924eb7a18dd8308caaa4800340558c299845836ac0b3670257da1cb96e1c5a2cf16ac3ddafb16280ad0c40a6c9d05ef982b48289f3411209b280fd73c44a0b102265b987bd8a684bdbb4e6a26772106b3be3f644c6890dbadb9c45c85f24842222f451b570fa870a0af92daff7344a7c773af4db4538a03a2dbe26772652a914c4bc1dbbddd63dcd6e921fcb704488665205d4ef9005ff40cfac60026f3407bc672d356502a55d53fabd7036a9a154e69c52d8a5ad4b81d3a07652861db033dedb81cb74a3f675e0ee49f9298a20a55d2d332526d2541c740122b7710e162d490f8561db7a5bb6566990932292b5f6cc08eb92a11992c682aa037aef631d1870a9552c6e4bce9604aa410cbd3df58d5bf65308e5d25bee97737b7eafcae301e3e464bba3461eb0d2646992d96da3af6386186b79f33148274b279cb71b1bc55f207ce0ad1c2e8ff52bedddfcb01591fa414eb94d67b16140708aebe2fbec07195ece25a891d23b32f550901b367cca9a861aa374fc8fb8b80a8fa1a30dc5196e37dfe5e0bf91f39902cbab60db767420cdc040188c30bcd31c20d3e9bb3036a5c05d08a4f11fca3862be708e15113b82d52e6998fbf087196e79c4967ad97be2b8131cce5724559751c29d2ba0d744de3a597e25f7827b5b537135a7830ab4e9b910a848b1d1ff573b5aa371c4206c1e0e47a9784117cd790e0dcfe5c0db803e270bd199af3be5b73c61b7c041376cf4c67377a870231e3e7baeaca9fee0d85424af057623bf0084154c8f22c84d89d7607a1a8acca27b6252c6c5deed8ceedb5d5d4a684da4c24f7af40d772ce9be1472bc12754bc5915a016cf002020769e1d7d09b4e9bf8650b3a3158760e7da4b90d8b0195d8f383d3fbfd1940512e410f212221cb4bd8d024a2010c9405b78b7f73c202c872c8d32c1863614707741d27525d630da503ced56b591a7c6ef2c3a2a5b49a8686fa712df0dbda603f4807c9a997df102638c0d7a5daabbc6e6da0b36ed9d95059994509656b0109b109b3ac2b57c178ce3e2c034203964c697607f110f070b54e4a9a557b192078739a5a25ed7c5aa490c7439590c3242e0de1a24b01c1836c89d3cb2746dfb2020ac7fa5eaed6150efddd537591a01b9b0619c019d4fbabf09e4f4ad376b657052e3e6fd0695176b5c45d0be0ea67ddd01c2b087fe497737852fb88face464bc29a56914b1e7def6b7a828752fba244749cfa2ca4fd65348acef86215491cddca9858b44119e84949652512cb8c6dc4f4dd140378ce25863b83f1c9f3aaca6ac06cd8d1640bacd371416b1bee971d96649c509a4d8a3a999d29c989ba173953fd6f6176567f3137a3610b88b80db0b0d909e3caae405e5613be0d8ea3d3a5cc67aed517a37d8fd70b3a0204223970b1fead6b41830c556e4a9a1166a18eddeade8971beed0a08a9efbc753c323dbc9f596068960670257f95a30413474574a5f702df5683d7ecfa03e88b44395b14ed04488c205b7d7e245b1f38cd5aaae711bce435311ff08750c709e2ab0367846db3e2f0acae30d1720c4a71612146e225ac0de8b26f898c784095387695daa45911041e67f0869259afaf227e98599c382bd45b8018ef97442154d456f8d171f84b132dc99899cb85ba865356a36ba1c7c8f89783494b012c2a77812006c2342dedd1187c92c6d2ad46aca13d5271b234727f82893b6ae30bbcac1e7d95c01f727102f345056c5084cc6a09d1f8b4c492486f32549519c0fd6e1b21432649fe5c2701c6ecf1f72259239087f8d74e18571adc562393ffdd215510ff9564c2bda7cbc41796c5f728de86bed70feb7ac2992142219b72de49dbfa7899c81fb819ba1db30c16a61b897a29578b7cd41d389442c854b99e215cac9b8c812bd605459befd8b9eaf1772def3be835524b7d29a6758cfe0e8b1dabe2d0cb7c6239273df64b2fdc183707f9c154992c6b20c2080d0e7186c868041f71b1aff13a4783ab47db5db976b4bc4c1c4ed9ada04efb300fc9a021f690ea73d59794685b2cf7edeb6cc64745536450a7fc56747c991550a876d7c858bb31318dad14cee42ff9a826ba0ad92d9db4ff3a46c2ce53db00a45c01c93917750e54030d701b7613c5a7802bf993b716360b8447646a805384e05624214e2ea61d452e027d8c47cadb5efcf6b551b29c4e61490f2468e5683b5c3522f4465b2fe6639e7abfb0cc6a6789b9dff84b20d20cef687001d5194da45e5f8607ff9a31b70c17cc9bedfd6e5cbdf9230892cd6adc9d402198c25d503be2fdadcdcaed5c78fd4adce8b794f9004f3cfad7d7179e3f2ee938e831710004671aa62dea5dc8fc5124c18107413d31b5e28befb9388f532d435369cd1b5043465c388c33ead692e205b5c4c523e5c48efb8dfdf510aafeea96049b839a5a291c4301df5efac8895d2ec3a0d452b84f685d5a207d0c78638d2302296b005e64a101cca57db8ea9bfcdc1fcf036a73c5113142c64266e3d1fd760e30d27fccb763c958eb963df5271327327d6abb867a4a372fc5ff272a6c7dd6f20a205a3c5e06a85af30915ac22aad03b6495511a22f3c5286f16d6b79239e2433aa0e3d824b443bcf42f08606d8bf6194005ff1c37cc0275826e8019bc3a752a99cd6931d15c4ac69069a383fc4bcb34a431666092646960d17201432e94e1c9c760b43853fff61d3f86ef6548070bf8f3751b5e6b1d0984b1ae13fcf67708208a0dc8b7e2135dbd0010d4975f9a309307ac901fa475efeeddf4fd381debb656883e97515e21fa395aec1637fb1b4ce20841d6ade28863da672bbd15a5cef9e8b2504a7aae939e96abd80aefea2124dac15c255be7fd430946f7b5c375913f8574b721fb6fe415700e335e1112a74a25a5036882a97cdc12970d359a3436a5bef7f924c32dc50703aaa5d1a5fccebe8d07a0b7b46f09455dea72af2122d692c13faf2062a577bddc72b36d360750f141fc7aa709185142fdf7d06dca39a5497313a758d3aa84f6db12bb83c9c60d6a33a85c80e04dc0804125499db9c1e10e2b9ca46716c2087c2bdfa3a04aa739954480da2095d7b6b8e4dedec9a01ee1aa06a89faff6395cf58675498ba7a0e85c292399da259614090916a6761f04c52f0507a59d605ba54b05cc19bbb42e8ccf9bd0162958d941f10f295a92c3942d9ac989a4577247969736383429a4a0c2ce15993559e4c32fdecca60f96cde775b3a83bf43233e7ebe6d2f896b11426370718815e90b3b4fb386ac2749b70ffe53ddaea4214d34708574efbfd411d3391d8fe64d6c551ae474e9326c6af10fd9138a1cb35193ebc8622570e41990067950f0de4556044ce9b1c4d90ac04cad799d204558654ed1a57d33496ac2d45388f3916cb2bcde8d243c806be53aa5f35fe57f485822256ff122b0912c2c824483884192ccdb9ed9b058788f7dcfd1bdfdf9b63dda3899bcc3f01ee3b25503b2685da0bf7e4dd82eaa93bd5da08a34fe033e4a47a826bb0bb47263a6ffe48c56b21836da64ac9ccbafce7a6b0bbee1ffb1457c7c4d9a66254aa99fd76425c42805c327ce6f76925e8f5d1e7ac41989e9a6a80311b5c9673a65cb10bc6339491939406ed004a49164adb56c0d0533cdcac03b08d849a8be35f178358576c3c8d40bbc412a66b65caee2ef7f9330f135e149f42ff1af50bb89aa38a51040049d02a933932d1d7ee19c821dda844c79ef6a10855144f5193102709f651d8756f9bf21f267d5d730ad73ff3a3cad5be0629e04b815f8baa4b132043c3425cdf7db6aab9df61edabe48f17f53a27b4b5d00b3e5fae524021e63a56531bc4d1384d2840b896688095d517895886a6dc0c4dbc718fe830f31cf8437fe9a63426a9d3c4a081ce3bc63aaf57884f7642135ba40de1c7ead84ae262a5e708f61d826c6b090006853b3c79c48b4f0dcddcb129547dc78430225b1206d2264dcc4d14eef59e927f6ffda3baa912d631720a47001c0f8469f27205e4252c41778e8836b6102352a7e012a19033179be720e88bb6044a0e416e46447e74c31131aa7fe58ca1507b3407723a6a3ee57f349d24c30199c6d11da60b7c34448eee3be9747ac74e53a13ea386e504cf2aa4b32252c6675a4941cf33fb1c6376d50c3943619293eda0d7cce543a6275b3367d6c2c6a42b364e363a121dd998df19e470e02b725fb430b04d8742ed2e6ded5054ebcca810153b08c6f33fda508884e52e98df56c7d63cab0b142a5b527c339cf5d15330d2eb58a5c034440d4d47d9cde98d08fc60cdadf6e40898150a28c90021d0adbe9be394cbcb34234b751a105bb8c766d9de2d7ee8df06c0e455dd1f4b0d5fbe88ff13654b3e235116c730fac7d92bf85f8422198e348230690abb33ffbb7d5d0dfd2371cdf78861767c6bcc9665b59e8861209d96e240a2ac9d0b7e4d2d9cbb7ce9d62c0768889d9ac47cb24fbf4a13d5087d9df2fe1aebf65511eae29c8ca18f050853af294fef6d07042750cf158f73f3885e9397bf3e219abb61376506e733a77378e4de8b531696b941f43317eb362b8d13844c6337eaa31c2bc1a0fa7d998335c919925ac4db95b836a1006bba453422c341c9d4194450d2a593557e0d554ae7258df17bb55b9c762a3136a329cac2244e48e66e47f35636965c2ded5480a0f258ba3bc1bd6c8c260c88b8211b0502fef1cb61d1a04a845141c82e5802d08bc67bd45b5bc2795fc63b764bb8731ba0a018eff70eb5ef20118264afd64728f611df8517dfe322738e820fb655eccbea4c470a839922cf2913783e8eb2d0c1709b2e40d79191272f7fef02e2f113ac0f888bf03f8e30355d6894aca48cba0ff4972e105a2f5dd8e19fc025c54d2f97d3656a0c5086fed3ab8cc8e1af0e669fecd1afa00124745fc931259f22bedeabf5602848fe7142c7f064813d162f3e1f02c7c992939d4f6ee0f30a593b554b765d58bf8919594b0e4dd82579db2624a0e2e6b8012d414a1052a0bab973fb8b84911fc6d13a9a6db871fd9c7f3622ab811d343bb0628205191e013b3a40915b0c7e871a720cf53a6082d93e4d8810ec5bd8b115ba4e245038f6204f1455a2dba173809a5a34f5bd2db5a0f451d309211588409c45fee7426dedaa2b98c8994bf984a8f663973b40b5d94feb4007670b21c5a40932349b300df0db3c697c31774119ea29d665ec31157d6a5847f1618e4171014046efc2ec5caaa2a4004bcfebe73d7428d2d888691e244de2df5aed7a5da82cd10019494b53ee8ab7d48a60b83a8661208afc80960e2d6e9141d6a9b4fac460fbb5cc182ad40f2e90bdae1ebbb05df3c15412ef56730c401ee38b5a6c8b6ae6aafcd7f9aef4f3e370e6d5f0d294a4810608f5c41e3c557fb735ad7a532e588c4ff04f24648850d9eb14da2aa2f836faa0bd5c479cb45a1f9e22d66a8231fd8e216f4a83a039eb0195d26b90bc338335d9ec56719066770bbc5f9526f33f5ac6029a1491ff1c64cf18a8a2609e881780562ff622f2b7e89665a9e4aa2f087ada6f59fe7aa0bc3b731cb2f6c386b352c94621b9781c016826941d0b0931d4a3b70f5be96e68675aee91d32c6b9aaec5dafd2386f4f8ebf3fca456401cbc13c4e3bc840b750483fbd6065a512fa20f1b09fba8724c3b7b012d41bd43c5ba54e1235842b0d76ca822ab66f8d3edc99507809b2e8ceb465e179ca46104fde0e28453765864202b735166cde58255905c03ba5687388818cf76c5c8fbf31251cd2e67242967d9b35e20f09289c0550f956d4e21f523fc2e109623c71e6fb0318290e100bf0316e348e0bdf4149bd8a277a661122cac82706df9b1a7cd8e9d84efd54d6e4654c1f8636a67d6b178e0c06642a8a511db4d460ec89b76de62a5b914d75f85c7819ac1a466be6a480516bd844400147b701f93ea17bb627a2e3f42a7bfe7ea76c7f5463691d901003ec0f4a5f82774aa2e0b87e23531d5defd209a0fc155816dcd41995d0cf0d982719b1088898c42c52a2a9c118994790583290595a01c40cbb4f5c0d9437dbf22f7a61d8a22306a8a072950d3feb3128792811dc31e27d8854e7dd54d02479553163b6fea32851a9626626b55aaed8abd4e5f084269a8d228384099dc038d8cb024f890a4c54416512591f9c6808c682258def30352f7a889365c8d161269d3f9791df0494c345eff4d0d3abc20d1ef52476afc682f5839cf6386a81daaf6471d57a79525dc08b03fe82c7e3e7f957687f0bb2c5becf185b6e50d0b9dcbbca303124111e590779d43c8cb046211fcadf5f7957e2bb6ac8444c61da195d8aaa37bf916fb5f02a4b1ac0556f0af078104830e66de1d06c5e08c792c60eae2ae88c9901d8ed170fe3778a038ce11f68d11a9d1428bbed2180aa73a5755444231358055d9cd006572f31cb1d9be329046e38d28b0cfb7390a2c5bebe60fff4ed61e39d584e0ce8cff9dcaf711b67ddd95c0083440ed25da74cbe51a427799c48e90f45924a18e9df4f0bcd0a0d71b789268a84f9e8f5fd0010fe3a68a8ec303c40d7bd5d13906d460de30d49f01a670eba30a5578db870762bf6752febb1625a02f0c15615ad828d33ffc93160658a08a17ebc67fe54318bd48ce5e77d9801b8c525f734d765eee897f08992d8703695d9783e5a24f4bef45fe53a81a9da347fb1dc7093ecea6b4ba01093e228db4d0daf0a851cdf4d92d23f34fddf6bfdd07657910c39fc357d8593c2941542b8ef6b64bf62863b32897c9df26a35cbb51a5e1d517249d683a91c9b60150f2b2890573598669cc614e83b93460c26e3f001598416c56a9baf359758514e52eafab3710b513133872c18f148961179c28155df3bf68140d3d0a501d38df95e93a157353bda84dd9604810d1a09f5a7c5a558a46457a4119785be9f9e180da843747266bf46b199d97bbff93945ea2b3bd6a4465a073a8026b3ddd703ec7de066753e9d22a0889924cf8916c88ebcce12550501ffac0cec2ec8c012dc05546075cba05ef79116023df3185e9e76d15318519461b7a42ac5766c84942f47c9aff97905019a175268273fe80bd64b21417f48b6492f6a0240c8ede951193cedee0e9c21a79ad2f066b25e2317655e812082173bd572010c884a481a7904e11cdd1f6dc821890dd963facacff07efce5ced67dd25a54ab43808d0bcc493ad41d0bd1105dc6d785d4b7b6aa40ca16cd9ac78814a52e711554aa078ec078ccd9980bd84a1c2fe01442dce046412ba020443112bbd67f5ed6063f3935df7c8ea24d746bcee3ed8433893fbc2f6088100725d75f8365aff40cfa8a24e0dafe5ccfb1df186a922fc305c059c34a24739bf00b8000bbd706a8ce9b56a83655a5a50459a872a20b2e9c86bf795f46143a9a5a5cfd40b4c90fc02af7be1c05d1f0e6c714439e3f5a1b193c1b7ae0f065f3155bcf0819170a26e44c37c67d2875f2f9eeccc1ccee68ae468b4ed47743c36580492ec0b0b273fc8e6cc339ec2f2ead20bdcd68aa9d33c44f1beacbe661956546e7ff97690e3824cac5f0d0e61acfc90c3f0f35c3a387bca9558c9e94fb05709a528647790454226a5ec65c7a6c7a50d6bf204af0ce463b5198784a580fffd1f20eed9035008625519198733c2b7709560b1dd967a8211280bde8e83ca7b1a2f298699049485594dda878da701d0787cd788494338d7b040b30a41c6571750ae4b0bae959b011462d54eeec3d70abaa5bb5d69613fdb6451322b84f73e818a14d8e90af632ffc7d55295e594e6daf98592f437e1d981f035dc76593eb904d357582bd585e866127d27c4a1ba82be8fd9603dfb53e40a0e026f2d8b6a44126d972bfc9f823e2ef0285f6390e19e36c60e571d1b5c29f7e154413d31ec7a32f7001c95a5b9e280a78250ed71f6cd0024263029b93e27594fa4f8a6589a9a518a35c13e15f3432d9e2d023b1899f2ebbfc09158613db7bfa4805de1c616c61331fe4088616db28fcfcba31055854d120f2c192290846cf6198826f01577f90c8672fea01d6f43af22b7941d98da7f4dd4816e6156af7b2f171bcebec41b2ca10508dfd8802a48aca93f120722b08c0a5f09a9e75ee2dd9dba2cd0c84251f231661540afa64c0415f6c4a4e1c85ebc7f1a2dab020561cf44250b45416331e07e57860a3023f6943f7087726b6e9bb9c44ef243af021f035fc0851d74f677bea4163167be986372ec7d09d50a94666ee08f8715cb15776abb57ac507b265273ffa858c7bbd467feae79ac6d97640b1235d10dbca9e2145abd2b1564c1da17f382654bda569f731b93b8c4029233e4424a936acc797c39032098a12d0250bdcd2c962358671a0190cad2bb69f564f5d357cbd1864ee3c51e33d4e5d2860e560c3b8a4864b81792c388b2a0808c330c0ac089d0f2f916959b32657d2db17698f01efc57bc0abd69992736a0a9e980557d365a5ebad73b08c3469b0e95708c0f33d6801e5787c6546cdb156bfbe78f0ddc32e10e061480c0241b2ab4c16b74f51b7fd609ed90bd5b80d9e85751036d44545974917f59f604a7ea2c6c39a5058c30a25248cc4c6ca905e2c4b684df4d0564a89e3a37256a73969170875b6fcb1a4f3e53a3dc2550cf1f7529f897d2632e528e10915ef78f5345b4f686881e4ba1c0dee5bb3b87213aaedae21f8a3de02c49a504d1bde2be54c153166c3541a0910ce9ff102e145b2d9e5296640fb3a784798da00070be69a113800f1dc2892964e5df46c7c8e09bdca66074a0bf99b7ceed49c850a81b428254218e79d342bafe40487d21056aa556955a5901329d354b92406d5c0b8469f523ffe66ad0e17a0e2084bbaec6d6a0cedcc963e4d5e66622a74f30a94a15e8e1a0f78b44097deeaebb3faf86e3eca131856029aee07c1b9d31c6c076343c3994766eaa4739ac68bc21f942846315700d1688df26b3c9a68ec301ca001ba56d05f401c9a859fd42aa0da1400cb9056d9d60aee4384dc0fc69e49e9f8d5ce09f57d6a0fa893a7a783059de0cb3ca7294ec6a55cf30ece969ca765435ea6770fa87ded971125abe15234bca4c0389d0824adc8d627b5bf4072b6fb08c1005d4acd946c0f315bb49dbc34922ae1fb741ad024e6a17146a0aeb04a0aa2223072d218081ae14c8b64ac9d8f122c4455475b8bd224c8bfe2d2bfd022436863a01824947fc6f1d8abf1c64e8bef2e469cea7e05012780c9515fb6e4e50c7c7bb7193066741d4cc13414d07a7af4f6e546697129f3fb6b48b34066d1a709ff2d9a6dd66956d38dee648b903bc884f0397141ab41a8d4d10ee02bf4b89bfe263c6115a65fdf19e822ee9ff0f1aacb2bc190330104a425873b7434f4356d372aff070630c3788da38837cc84db9236e54f4f092b3192492678d4e3dbf677ce46bf73777b1dc684dca9dce69a4e91973e483f74750750cfb06dc65e142a6e33ab1636481d87b60f068c0ac5481ab2fde8c051b1e4034e05044813ae9f4ad1b6ef240a80a6dee611462c47c2a0277c8726dc65abbb95c0bd88c43ba10a86605783620b58cb04fc4d1cc740a398415e6de4f4d5b6dd375fdc85d29efe35af4fba5d59e61a8d4176ef3e48aeb71a6de21ed14e9d0bf40d7a519becf145edcee28a3bcb0ffec0dc3607844db7e83d86aa15b8174c4e2aeede525b6864446a1a50f24285c77efd9e6e8b3e5ba78003fe44003caf2b5d1e2222a565884ddb616e2e2df0dc24cf21fcfb2d2152c0c621399d99d1052716beb51617e350c66ccb9ebc864275687028f70847e1f024dbc252555028322e6a077b31d1e5cee5d81e20885249dc00a63d8bc08396c6e1e700a20724a0dc1733250741952617e68ac9722b054c4707639417e19925a1d3935f75c432754e511a2045fb537d23e94d20032945dd25512b7f4005c8f201c79949443a9802e3dc43f04cccebb0747a00a88a6a936c131c98e879b9781b24bc579eb5874b8c2a920258bcd8c367a486f16bacb53f50f9402814afef52ea5b4894b18a220e812cf4226bbc7ef4d5d22261b36c269eef404825fdd20384653d61b98cd5ad9220cd4263c376b50a8f6caf5acf84781e10d5053ab65de06e398692cc836e292b5864e12ad4c6cdb25a6eb9f89e514c13c6039e44b9a5412f5440d5d5e59605fb51fd8745bde512b14b5f465b7e0380cea0eb646a29242d5db4dcdbc8322971bc290fc4c6878f92cc8100d1f4b21c9ab22345b54bed3309f2dc2587b22600b925deb2ea54992dac76cee3640f322959dc3676c6eb907e2770708bfadf86350cf89ecdc56ee2873096c16a5de49fd08c8b9b4ce607220f3eb6f1fad8495da0b2758240baecca8d1690f5013395be115ac4c52461484ccdc0214e970682db908c67f0a54808aa0421dd5b54c70c5e0bcd21f82ead93dbddefc7b5f2a7e3a034ae3cbc21d9aaaae5afba54e2046d7b440e6df7f01fc012a65d2ad5923944203b2f1c686b20680e2a10c32dd504027a11680940383fed4564eea6c8edd988724392828831ff8655ab928c4455f802b7831d2498fc55a04d411c11789271434d8853ada5f662aa0f017e258646a925b98ffc4d304695076f69e8875ff88c735e259d0e92f58d94a7af33326caadf7ead1db90fe10260127e9323785ca3183680c916e28f9ec14d304760f1a6c4eb715e01b8e7867403859e8c6245da1f929bd2370850a08a1e841ba0bb7b762f621826974279d915ff56a064bcc7ae5bd76348383df19b61308a7d0fa3611f3244ffc7fda9920c921ef5fa123798319112ce3b21b269b6aed6bef63d3a6fcc5a34201cfad6673ecac0c0c3272ccc714ecc4d0d1faad58174af1b90722784b6441a14916dac92aaa441639dc1dce4685e22e6a71078510d87037530680f035f8e3323857555690fa68b3106079917771bedfb515725bad50686c142f3233ff19a8c020aada3178cd07e2d824d9897ac743a3de5fc64626e3490d241b50e1651409e6d7a1a1bb9047ad5fe8d7b0dc7831f023cc085af6f07e4007f4dabd97900c3ae328134a527602d3cc7ee3d1c405deec6981ae46511dd73997b1a2e21aab9704166ac684d773475c855404525638fdd7bc9f6ccbc2d01e86012b817abba60f0ee8a607165636903bed7be8fce32b2cea3bf1571305dad3cebf4a3d567b19980f093a6538285d56049a709db1ad3d29184962fe5d045f37e704c8f75a331a544dd9b06aae12093041ea302e2e7b504c8b88d521618881c58c9150c87c2794d7962279223e1c1bc828ca2b0fcbf92a0afa62ed68b98f80c5e9aeb7936aab445b795e1c7cb129d06ac012bc3b475d755bb369149b6cf1f3a59dbc791632cd7ae1478497be3b0482877d11c69ec81bec07a962a4a23d265a55d6bad7e214a7b48375c63210067a6a2c67ccfa2c2fd7712a4070cfc50729a5003e854ce993489c54dd0ba367550555462613a177921417972cd143c016ff5648222df2e18ea4a74612775dd4060dc2d8c36814c262eefe82428c15f2ce33f8d31594d1ab3d64eb55a28c6162994e3418fadeb6548ea77dce1083bb4b5a6146b2b76df3c7e7271515d512311c3626f40abd5736b22f3ede4e91dc19023f3d2b6f649598aeb87c9afd86eb51c084a9e19d4d7a5b80bb7041ccb38b27b4e7db5e65e5a3d2d28c34f03f7edcd97cab503e524888a410d3a4f6e33bb27d9135d0fbe7f28a20b17c03ba55d043c057a4101dd79565d9169487743d9d681870df742d1532a538a5293c98d121842961e286471185ade9268dcdc6ebf7e2013717f37d286f3e02cf1b82c9a3794f932ee93184c80f9e00bc4364b9deed645675f6b903cf2f4211502d0a2f67c915c91dd5beeb41c99694332be3cc49f76c74b477ea3b7e39c899fce682eef99d3668276fee85c113123eb607d4c183876b36c8ab77600c1a858295e5bc44f463ffb354e463473db73626644a20e97ee09dc5a860247ede93034aa1a8a6f13d746840257e80b37128e2b2677267e2dd68f2f3a1c66b6e5bd0d97df2e1db84d2f72cd158dc009466dddbc45291c5117e6a739eb09f348304907fbd0d577663f76b427ab79e23e051bcf42584eb24358a84af78b22098b9ae4f4b0879e82f966b1a4177763ce0c46f919b4b13bf33a5367489ca7fb460a1aefe2e8f68e9cde0628dcd50139f39f914a501c595099aecccc4e967c7217510b6580d50afcfa0ae75f9a211ff7adb861990c9c7f1ad995cc5e3091fa54aa788e32d37132028e4390d2d6ec8548f3b53ed6a239008a94eb0630917a9aa58e2dae3a03ab5d84ef81388a14031fa8493b53a30141f2f0e71f2015bceb846cd2bc235f2939e86edd290676951de775c32390269fb26d2f5de71da70da57ff2a1641fe28d9d2e3fc7d437ad14d6f5a078192aa23a729f23fb3cd560267ef40a0805996414b015efb94784e91879642141c9863762a08243a5e10e3b08a3f9fafb7824049ae0033bf8cf8af7b00e1210288cd902b0134cc1edca2e1d37fb462665bfecb7fb75f7d8f5d232474459e085a4005a28d66b9ff3b9e6885f1c59b18c256d5e5d9bc8b0be60e1226f3823de446f84c9ec43e14272313b8c353b42a0b4c64d4feee1d2e0f4af0e7c1920ecf3cb491c20168b10936758b54e019bd61e8096eb45c928d46984908220d7feb50ec2c92d819dce80e730dda5470c90f1e7fb2f36dc4060dd16978c06da10ac847ca8fc91eb122ba8543638894a88cbcccda5d11b27c6bc45836db7f2e84627e96c577dc1f049e9dbc15324eb03cab178467aabb779ad7180818033a38d9a77f867e4286de0629204af4330dd89841385678002094efb3139d3a3532b401416b210fa46a7925bdfa3b3293f7424f37848922513cd169adc32dd5d6dc9cc386d1d231056812d809f846e30383533ab306f5491d7bee821f8ebd91802724d85f545e024df308e1cca27a2ce7b0d3f93c8d9c2cbfa3ce4b4210f320db58b411c05484f6c481373f46c24740b06b9e132d523f7004af81c89f838619c848d2007bea0d96f03a9d6fc84079356a9b468043315c9bf70f61d59b87ea819d97a537bd9b2d7dfe499cd18ddef0fe299bc55b311691378fdc86b148eeb32cf09c38a45c4df5c8599bc08add4e764ecb36a1c9389fc294747f9f91fd255180b31a38545558221d1653f2453a0af8aa5fc9230a728509a2dda2c783c9dfae5788df5cbb8fe4a8b0611097a60519abf19420006e1e493c81a6be9a5f042eeaeb711a442169135c74cb0c2323252668965925868150ab807ba25d9c612e404ab775f079c913bf99267c764abf0e15893468fc43b48f632a9f54a47674de8936c92a892ac1a985651f7086e63f0a1cbd467cff8b43ac0c1ac5b4b2dd52f87a356e492083409cb94357e8f8de15cd3181377259c0cff976c8302fd879cb81ec98476f0a7b84b791108510ac7ef5c54edf678f3e8062b6d831bed6c3151c5820b0a52ce28854260ada5bb2f07fa1783d1b126f00ed223eb03a72c3edf40fa6f5033da1c13cbdb34002027ca3b8faa4a4ae9611ce958ac0a6e6c0425559c69ff18a448dd5842d764ee856171bd30f2bd7a4ec4a5e9d3b5412fdef2fa6d040f698e71a74dd9aed635034b537300705e0d14cc586d3cf12f4981724c8ec86f69b576a7b1ddd6dbae87c247e32ce880076f55bac86ba66265b4519056538e5e67da507829cb2b0a1301d533ccf8a4c0296489d14d1b5c2d5097f385e282773d124efcd35edd579b5dfc932eda3da8459c226eda59c2d70aed02b2654beb735cb5883b489198d6f94594bc0bf00e823f4407569772327dccabe2a132834995fc86f0980b3eabcd12ba23b55f4b8d66d3313751e15b8be13f56e719bcfa34aac5f1176b11fe92da451cd75c063bad783064db0adc96adee0bd94dfd71039289a540c47baf8f74f3b49d978ededed86dec87f9b396804d626f92596a6ea150d074d8ca566307ad0dc8fd9a18876e09840ac2b7cb29e97fbaa60f1e90a8cf4fa9e58cf57faf863a69da09ade76ce41afa9934e473abc7435eaf4b3b7f89139bf00750f41b716bd5df27a99791479402f6fad4356e60bd0900a65d4a885ac1c188002f1d0f861d5a5646a468d7b626069b551656ee46b134445234d88c63d8be945f851ddf2cca405166d5d40940a098ea900e51283f370afd049fbba90f514a41c74a59969f6349a49136e98f3aa2d0b808d4a09943d2cfc9f8692519b0cae0ea79fa158070863473f691bbdf16d6d52f04af8fbcd9c6cdee746ecfa31246211dba8cf9809602b6f8d2fb91e90051e81b211f0cc2cf923cfc0d33ae0fda2a7db94c2b22955510183515c8a314ad743aad3bdc8e00439db2e521dae3ce9f0f98bc4e5e5b03e84392fa5362ac1bcecf83ac8120942e557a08efe410efa18caab41011917313b90c08690cd24126f66d51d10ac4263ea1cdbc0adc0826b4ffc06510fd7403b54f5127457c9b1b97df0591c6286ef941b346051e7620c9420c2393de07c2c4271dd507b57d395ed3c649c14fc57908aa10a7dd19a810112ee0ba4519dd6d2c97233638699ea02c1dde3847e338e80fb823997420c7341174fae0a4c8cc35288c29739ece8d67c5a2a5088ecd7e358c86823caa7687c744264b942222c820e728743e9a3b78db07cef8dd1a130292403cf1d1e442dba8d332ac1108d545e901e44e245ca10d6277f35062ed5ede106b0d02fce4cbe85ae5e64578f0017ff9a0258d5a9041e798e6ad5afa2ff3f7bd447b2c301af7b407d68f6db885600055a65492cb64f2a71f2f72d8352973a962b30ceb184b75a23d3494e3573885126d68a22fb48edaf628264bb9ac86c580e956397bf22e2425b8b3b4e4b25a3e85520835413fdc7be6e403d405613a9d3a8893648e26fcb794d74a2fe40ce7e1d5b00945a84b8565fda904f681f7fbd19139ee36922df86ae689e5f8d35f8203d5a1687e28056433ccf147fd04d959fd144f704c1dba28d5ba73c1345d5078ab1461a6613f4b6709a6372e697a10a3c75dba924134d73721f3da674b49507b915271dea61683817e4bbfb535f5ec6728309b779024e11aab0aa2750701d133e1e9c9733efc90d69c0ce3f12b20e9f31b78b38fdda51b0a7c48738711cd57adbb182d67460cfc137510deb88e2249d9f04b09e59c2eac8a59f3743a7889df9fd5ff5e9d543e3b5b27c03060e4aa01edddb96dcabf0331f0942931c33a2bd06a8497d2bd28dca5092cfad3ea14bca0c941bb448073e5157a85a9d928ff27cb1c2f422f9450aa56b2ab39ba1a8404c7c05a8c4857f99d12265ebfe660ad727d7ae92943ebb0869004f2c4b52d61bced52119456d7c9aaecea0c37493dcaec3912b860b4f0da8349a08ad1030e651b60dbe3ff94ec0618c1db2b1028f51c735b84161449467f1cc20df208717e8cc26a2d93837da1ebb10e0ed754823300b823589709406c42d2c10b7775f8dee84baba9513dc16955efe5b9ab3ba8751f308bd5e459b0a36923ff0567ea19602e24cf598051002f33a12925e66947129d9fb029a3c1bb27d34495825135cd242448f8869adc5336ba6d2c8c1b26cd485528538345bf731a275d052d475fc3ec50652172f834fdae4a3d17c557c21e8805b89ed370193df438a989b23098d2333ff8a28b4241f56098aa9d3f703d3c429dfd02db18dfea39eaca772c9e404b50cf725c18f9aa5369bb75de6e0c6db431709a2239aee3b99ff4b21ad5bfae72d7b1113728e8cbf7a8ae17c57757dc86a80f840f2011c3c8d91408c350919caf2196459b35c161bca746a65999005310ce1285459753f034c5e6fb75112c48ff811cb0c9759715f6cbfcd876f7bc68fc84a6982a3ae7ff9f55e21a4e55b7b6e4a2b38e5a07112b64cdb18cdb50d2e82ccc06dce9d052b3079fa0a81c5f9efd71ae9fe1b2b19fd949382ae5ac659c31bcced304ddd1e87722668a17a536fd92e820053f6d14639331276ad286b942e72eae5db05a45e1154b5b159f8d75fc50ed4728fecb8764e591de14492b04fef8360c4f4867640990e716949121b08f439dac2f3100b6a026826f458841cc69ecada981d9eeead87e21d7580466b6866cc2b39e9a7f470224ef02436cb6d2dc65cb6e57104840973967540518c3bbe143307c39c6ed25d0e2c4c5e9959d9cd3a35ce216f0b84476b65b98697208d4abcdb2c00a8a34463408105d206c3932e8a81462625944b29e2a83a4eb5033b0163223d8a73753558e966cebb6ee858c40863250e7136b4beaf6809cc500133462ebe3c1b8a7e880b0f0bb7946835d412770dc07779e14789a1239738c56557e6a976a73d7104ac3e394307ef600aac74cc61da1dc62b682caf418da65a11c196201a580324ba21ff91e178759f8628b65ab328a266f2eee67638d0effaf6dba8d919a01071eb6e23ba5f79d50d30a9be18b9e25bade2e11f4a1564f488a92c29fdd6345c2e2913ec4e54b04558244f7c06d4178ce6d0c6af88b3b1dafab9ab5a64498990d58cb51901ab5d738a0764d423963378ae26b6f7ef3d2eccaff234f62f3df0f40b9f056d13d3317f4c991a0700dea40b1e3cec27555b60c04719e0c01e99558001a3bd335981935da61373eb721307e88f924e16b29bf2d823d111f1c49917ded8a426afa85002742ffc73777761d9ebbdb2ae19ff973eb7a3f93bc5c4b239e626d4d8e8625f2d2819fe15ed43397134dffe00fd11020409b8100ec542aafc63422e790f140db218bcf32765e4da4defacb91a39cef728c3236c85c877389697d9b6fc7eb9c54e6c30f1bb143be5dc74ab644a4617d0351b600e94dc7fca3896654ea19d5f740892a2ed8c3aed99cdd069d4c5356412200e48b21b5433e043d4ff60907ee809c73d147c0f46ecf5b076080c137ba8fe3b18da144e26f367a9e757750e462b2848fff4c2f65edc0a7a07e530e0e6088fbfd2139db7e1dd3605b4357691e9a01e1d85f3acee18e5e5f659776acee832970ff9af99ab62cff4c19e616b580481238eb1c3788232acf18ab01a43ec50dcff0e07f2c886025a79a419ba3903a7160cc033db68e1b3fe8165b69977e5950cfb9f3826caef7e8ab810614a11fbba2215f25176a02474d08bd7308eb4d634f3cdba53a25993ddeec35cf484fe5c39b936c16db708cb3a2e3a62b05705223928d9254788ec866b63370a463c0f4e20df69fb4511cd42c9c039a6d8eaca7637d9ec649a4ca6350479a8cf6400d54dfd71fa8dac405fbed05e12828b0af1d921de4b12c8128c36cbd98c158c5ec54975f12b7aa27c21598c00286137110dc526fbf51de19d2c9b370f83f552dff8fc10acedeb81a30d27f3842c33a381a041d2516d500b59dd1f53632ce4f94419523be5a5db0b1b6a21038ad5595d2c03acc8d6b437ade943c4ce92a4822d65cf4099f35e6b00b60ab13318c3501f36c426202b4bb8f8a6e0af03a9f62f4703d123248e5468395b92e9e29e0ac54bc1a6f0a5134db4f92119226bac8f7639e0a3048503efa796d48de53f211416e0afdff9ab57a5a58bd36c44ac07ee17961baae861a089f5f95b75ecc96cecd1216f0fccb8c15353d5bf9ac3d317355bb70b1f9efe497fc9bcbc0a2861b76097110b4f1f1f31fdb5f3f3e74c8217045ffa857606363051a6ee113264e88972f60de97fb2778d86c9c91371a22a221d2c0ac54989035c5dfa3a7465ed15704207668eec2789bb65045649f46bce65764612a6e5a15f770b0d501703d113f5e243cbb68fb632ec968059e1c0b05ac393a4c4c772840c153212af59b7a14f320534edf53f1e8e1c3a4510e5c228ba1bcc9072592a4360d9d442f30bbde1cb21b6c73313ee8837dfb5cc7aa69e21544ce4b9f05b0d50b2fbc42ea5e08aed77ae5b9066e0de150702574e5b8c36b0ad6d864d65e5ba8f8de1e96967541ba76a8ea362477a7a6364535c39974b2470a2a558ac5da20168e4918757a769403e21a3737379d384ea64864cf018533648dda2f4742e0f922a421119c4cc0be1ece7ca845673d81b9d62fc781ed621c695aa4c78091f7a080c79293ea1186857d0bd65bee2c7b929c71f8ee77a3e879f2086e447b2089c6ef9080b61cc4db2ada8b1abb01a11d54c772058f1eee730d3934b32a80f3e2c5e4a5d6bda063020e1f8ed65fb103749fc8ed5fe380f82786e1af1d6996e0703bc093249a9b3e65e37dfa2458b25a9dd5a2ce61afd088209390e82e46628c46bcd400935ff5d7fc9b8bc1ea830389c06ce12a02dd233ffc0427e5910e7b0e4b68ce302a582f735de1ddacfa05742f0a022c3aabe8d1eb17a58df4e15fddffffb6fffe37fe82531cb1415519e24cbdd0f0b61c8cc389d104ac0f56d5c39d10c2939a81a58d60ae981b56ecfd70f7b74febd0a8cfcc02d4c62e510059513796fd423402694b32b6d0a361858ffca24af8c1718a51a6e9aa46d44bfc64966e57ea02a1ba4d408cda90390f1908e028d3ab70240e9e8b511c1cd46d1d8bed14217d23e1b7c564bb50e32a20025640298aae230a40b16a71620fc22abd80812025b8070838df69cebd02af60430163d4a3bbe1e3feb0de92b6602b9d948eee3003329ab154bd56f1a826c267db9eddfed9244538b852547665b21626cbea5955d0b8eeff81da122e42723309cb62b01df4de3def404564d95bb5eecd46428913978cd407b2d173b5dbc940829a187d7888267a85921b66bfec16b36dce04af950b8a3fe1232db04e6e1e823a8b213d27c66bddfe2c2b5896f4bdbdbdcd64f9a6c54ea02b92695178f661d5b9c4a65657a075d9f0268191af4e64871763cf963713f3cdb6fef16a868d43a5a3b129516c4694d9c80840bb11822fa63c10c33b0c6347c3f2654a1390011d65498b5034956bb8d2bfd8b85883a46ba6069d5bda803803a34b3510d7bb50e4ba6aa654f1708e8b96fb06a3f6f1f60a92028e738772939185bf956bb0e6ac2a8c22c987cec42c3bf2c5bc33fb31ce2ab3b40868d89ac91316c8f7fdda9b332ff6c164f9bb59a3de2f442f6494e720d95b730afdb0b3c9c05663d3300e2c9334498e530bebcd315e1f06d6c41c296601fe40da9ed31da3b1c53bdb484f9d34943bc2fd4ea8a4a6997ae0a1b7b922c889363fd90683ab5dba62168842dec7a99464ad7b7e9023cd9b072be9399cbe604e9e5aac635ac6ecad69e1783b9cdc951d9a8a89d4a80a399b451c76b1be34e6973a8a4bdc4c92ba7b1d0070c0783cc76211591a7e21ac9f0edef5b578ae41fbbf963f12955626c8ec13b60bf31c3ca36b16da0607bced89c8c448158b0457f69612a5180de6b83a4a8fdd7aa9da832ad75efda8db7bb0c780af87eba0309ac698010127ae82d02c7b0a123ce8053bc6527130430926e84edf5472958ee475bd3958f6508f54491d4eaf1452ed8c69e34302b255264d08fcff497fd74e8d507d61984b05af278bfbe0ae0512dc9fbe41b5de20910ba38e90160e7aa9ac1a793951b2fa8e03b7933e0e58210f4c02438484f3fa2476fe47044311d2f827ca6b10aa2c5088de1761c4d6cd021349412386a2748c379256c689ccaa69dbd90045036c35d2257468f50ae25137be7d90df1e14e18e3d83e5c6b8fefd990b52bb073cbf93cf726fa33c3c2e88938e02af3c6cedaaf3cd70218e836e7f9d16eb3a14cfd28c2183e85a70bc23d347c1d190cb7cd60bd1e6dc202b590b2f38d061f50cd20696bed47395ae9d0594bec192366cdbce64a2246ea7bd1ccb6702d872c57c2c5a40122ad780d720c67c294ec01b2517f233b8e640abd596df631ade72fa4afb086cebac0eac7fd0fb90453ac80ba68c58731b8b1404a83aa4408f407c825f93382d9cb9362d886373c2e1b2533b1877f58c8301855800f8ff6b13a1a4f25e5cfe75ca3889692f0d508ab56862ef1e2a475ee52b064b0a88818c9add319ec5f9235f42eb25814ce3ca657c8b5e76a291ca9909bacbd1ef4d29b9e4ed8b5b2604946aa9ae1207ad410ba231089be4e4badbe0a798d301596905777f535a86b1afd8e71df4053c211aeead9b40deac70ef801ff8aedf77085a6992809c8e37f02c9b52e389cef3505789b26c22397c24160771f77c9a0cbe17bb99114208e2de5ce4015130711e58090cb27e7eeef1cd70b679ed04aea7867c2020386665fe5f7e6955f8373920926fa1c78945e4996955c42ed19a411e356461a420d1b7892f839cf2bbf3ec55b9e2d661301a74e8af69c24a2a2de7628ef1d357bdba136f58ef13a1ac8770b4edfee5e98ea68cc0bcea8ba9a0191afcd5e1a5e3112f82b8cb1442f46878721a1077fe56704ef118d55d19b11c42b76b18b6578ebe74557be5b7f7ff7626714149ced3052fdb9a4c653326c772fc42880aaf7de0effcd893494bef258abdeb1e1aa729c851d93512e4d44bd6e2b6c00b65c3869f1b1bb68326f858eb62810a3ac0e35d829f1c742652c41450234ad0047a26256f55ce663be21785797a7e4457e52cf434818a3a1c8f79b180dc1e0e8341714a9cea8ea281cae15205ddaf7586470262e3f067050938f99f3effe764c2435778e0b280420b2fc09fb93dc9b958d3f7faf707824ccc79b077171cf54fa8d0e00a0f05a31f4b1028ad3f56b95f233a2f02f162685fbb6d0dc36c235d8085e2223b62514ecff898ed16d07946b44b53c64f25d02c197657a3cbd27eb50bd405f49348593ab7af4e76315f66b0d45a65596da4abc29b509878e0129713d6cb69b64ca60292ddf8975fcf4886e7999162299012a03eb379fb9d0fce0d0c4377994181c0e1e270fb8dcbf0d7a7e053773ecaf3c04321feb2be88c63d852e1f44d597f0a736c68004db8027e37dd6170c030fa57ae139358552b7ca1ecdf37341ad1b39f5602e6c19bcc6a2c8cbbd8e994b39fa5eecd3efb12bd721f1c38101e4ecf7e71870b66495dcd65eb7c01586c2a8820f4582cf9e872ced4849ef15282f244e17b7b533f3bcb39f61d84535f07a78b43e45879c0fee99cd211d980875be35532f67bf419e8bf45c6999349141451e2e6602c3965289920e7e106b20cf0a874790e56a153c057c7d5768cce4f2bd298f2af304d7b100e9365ba77361021459dcd7115c2ecaf643e0379530c3db4a30d9344b28a8cbb9cb1b76bb3c209f5672a0d1a438224f711f277e38824e7ea6ccb6143800ec8cdf590d2252a76657cff040e3a128ecb8de4ce4604159f4551f469444beb3ce127ebb9f3d8b4a65a1a5100e910b1558890bb76c36e48673696b31a6a6f5beab3f4ac032dc8b2ec5de94fe2c3708a97ec3cf2714a46ce13efa6409d9a48c7787c50d93d9be33c066d84fe562d4d624bdf5447a309494d0da2b4f006024f46d3089a74ec72a16d5d2417cb571b8323cb012cea44d708cd52e21f8edaa0387083bc2f1f30869bcd6af4e855e304f978cf91284387bb8099295b7275d8a04ea99ead5a2fdaa7e845e646287af229e1c4081dbc50263643a2c42a5553fe12aefa258332136e177beb281b6ec42a2699c00ee798bdef3c30021bcabac4728a5ef2bba081815c7b4429b2a6976efa4e82198fd7d576d7c7038166f7838010973fbd118bf6ae02004393b21339800d131e81e4acf362abebf8c140d077ccfa7b3b37f8c309b4be40bb0b288b0112dcdea31726954b6215979881d29e821b5a8b565aac629b8ddb48c5b78b96e4fc4fd86928bc41f0648c1562a9e3450a14ba44af748465de74256d1dcd6477e91a474b5eb7f4453902114c548ebab60f665c86029dc76f534c40fcb95c6c45562a88452f174f81d4d81a2fc8027e58a0ff3c04c80b26c30702ee838c9397f987a069e9045c272a201139ece1c19d3d48f0c89702bd66a2396c0ad91ee4dfcc51e1db513ae874ae3f20dc900aafbdd36cfac6075839f9105bbab4ba325f1e1ccfb867bb4209e39aa9355f02309708155ecece0b2106e8e10813dece80dad53add212dee8c90435287e8e9af03130b1bc529a752354c3aee5ad4200d017311f70c53a1dca2fd0088d485423f69616d42ac7b3379f2d751535ce3a2126176f87c05e809af00295a3288910a040a5bdb42621b12c2cd552894d515215e951a7fed2d365b26c543c88db7a266eaeaf07ab8a3da6ba43144b079a4c8217da587fc2029fe9a335c4646ceb7c10e822ec11bfd1ec5dda4407ef897ce5994242af0188ce1374cf6e28acf0fe5c39c4e21509471d086bda4852bd4ad45fcce40702e3a9e9688b78285e997b88427533b3e2bde67966c06dd7eb0cfa3229efa643d0816446c7d061267eb9a0b13fb43238c3771c4cdec9e9de32bcd44a255a5f7680438832fda41d58fd89364f8bad6d7458f8658d63feb692b381fb15e9fa1b9db748dfc376e02dd874cbc84d022f6d0e367c8d8e3421b730586cf71e3f27e27ddd1387c34d000ec6758c396ed33eeacbebac6fdcf3e4b4f899bb1645f2ff7b389274a1b1de3402d6e282d31b91d97ce01163b6c5c1431951c349bb994923f7aaf264e89caa6bb50095f0b67186e30047b22137cbe25d8243e8b0a627d85d90ec6bb5d0763692ccdb7b04439cf714238774ec8b785434a2928797ece3570c43927dec523d38e16e003f792ca3ff583baedf2fddfe55ab51ed2a8cea5b6782ec7e1910cb1c93de0aea7a6fcb2ea9500c63835a3c8426d7e93098b0dbd1f9571c2ac5f820e149051f1b076150f01fd225aac3b6e1d66fb2e55532b40505d5afc6f842a04875d2d0c0cbbfb070b0a9761b1d17de4f20d39a5d1241f18e1bbeb87cf9b6a202f272aa489083a2e7d95a0d9f37ee0c452ac4207bb38984456bdbab6544805ba5465817c028112ca63c0538588532d248b8c566139d0448a1129320ea65163a8d42a8c8a28817dd293ca9f0c22e0f4aa6fe2992c7586de4864f771a3b624b68cddbf24c64fc56e258d4cb8862763e80f751ee3c213c9536ba37f38923ff5a719f22768b94fbc6e9216ac42e70ceafdbab6a8e0e022706c2862eb57aa8e16c8a3c727498fe1eb680c2d9bc7355f0ee193451fc53d98902650993921b190ad131dfa48dae085ff3f15a0a99e7bf402bf1a751095c4ec81c82ec6c0be37cf234211e321c19ab1241c651167b0bebf04eb2a971787cda2bad6ad3e6694aa01aeb392b05c101db3ad30f76cf33d77e120a4f3058299731e0607eb34e35bc953d953ce2f99ffe93b94e67af632a094b0867dc4dc796e901b26870fbc41705f4f11c61f7db023b4e3fa5f322dba5d69a92c05ea7376c52a5e06e30dae80d71b04ac50d9d68f02b159f48a2efebf53bf4628ca25809ef426de28cdf8cb138127fc95f2a445b491c2be193b7e11e4c29b50e1eb0a54a45b598ccf909f21c327bf7847392bdb5604c0b85c2f948a5701cc3b2024d6721d77b9f515c83b493e7bb40613375bb52ab1d9389b03dfbc1ee651a7edc5899ea6d06865ae7ae7c36ed05768e8dc5bb5c37929712b7a106ff32af77b8b6328df7541b45dec767c4e1d243a62941e45c1d6d358736ce22c3018bd1d23ca4cd969a2e8a3ee5ef31d3072a4b1e94bc844aba4298648824f2d897b63f8e124e0c29615a0242bda36860d125c2a0b48ab708bb1fbc2efda455c4a98cd6ec4b5631ef96c4ec681db19666aa5b530e1540de25f0acf64f646ed4309fc81e1169bde24b4ac04eaa5dbbd592050ab4a0712100b881da80d8dec03a8036aeac12382cad968adab1f416538f6dfb42f024692019d28a314fb103d630880505630e44a4f3c3c8c768175eff5b5e42edd2b4231be1ff5d4205159d444ecde9b6cb9a594322519b80b770be90b5f9d6b883d44c49e9855a7d5add723e2549f004e14ba475a4748d6f4d4ab03b1d31081f0178311c740b7aa872c6481e8a37ab651a05b75ab9665b5ea4075c757e7a321a71a95865cb55a2d6b6dc9a95edd48ebb02cd7a35ef1ab97fdaa5b97d5392757037287027d53bd86d189fbd8fdb0d0342eb8ace9ac1464972eac1478892c2f9d97c81284fe2ae2d45abd723ed5a76badb56ad7e8858af3e444d88a57bc62a51baae454266ab060a6d65a2b0c6a840f6db4b8c1871b845022e5a75f17dcd04627e654403eb4e1d1e3870d6b7840a424544612152825e9f2d353f7b66ac540124538a140871e72b802562bcc20d2b1fae0439b1eae37b8b0a244831a4a35dce0a70d49fcf497ee67e610b95c2e1cced8a2a6eb225ee1b6c802011fc6297250f1d3577318f1d3ddf5d35b394b7e7611e3a7924b8a1c39fc74aefb991176861a4e949841125c84910411684871b70064f9ea2832b4bc68022800971870b9e1abdb2530de281283054f6b68a154c61436e3b4b0f95afd22c5d1e4ebbd2d686163044e90800438ac01ced8cf49fd87d61a7cf55989e44088d8531b6d1c518209c6cf39e79cd3032d5670bce0ebd77bc98001add5b9ef76c48215aff8b087bd4f6bfcf415eca7fb8cbd11c613ece7057518a104a5c8491209585c96e6cc94236fa45b7bef6ae539595aa7bae45c7a3bd548a1060b3e7321944fe99a67b9d52bfb2417e9923743f246f670d96d3fd53cad7eb82e9b647cead1d49295868d76774629a594524a29f5ce689671dc09c143784a6f9e3ac718c8743d75b622f6c4a7ce6b8890e4f26ae54e73d8f99b30aa054b95dfa20f1f6e8cb921e5439ea7a47703cac7981b4ec878862d35ca470fb7336aab7c4a298d6cb868ece9e829a594da9a4d79ea94b2105dbd969e5aca807eb9c32e7b57deca799d409fa5441c5abb20d38782b4a8ab5b34bcdfd4b91fae2be250ef3182db460b9e7a09ad13c9f0a1e5664ebd62a1306ab3ea943263cb961a384971a4e404c6157b3c78ce43eee38b9655b32ff5d7fd2244714540e2024d284638090204423253c50940184762bf40028c7106e21a9c4020243a2e10c691c826c0982f0a07e34591a1f442a0a16f9f12e8e59ae1e542f20a72c5220ae8d2e5e9e5d3bfbcb87440f65d04040e86f34ea2cf5330c5d6c86239ebe4c789d8f3827fe12912263d869de0c1f7c79cc753f8d550bc88182aea22a32353d8734af058ffe2759e7f13d1871311873de4173cb309dde217372d40a2006bd673bc01171a3ee3bae50e3f1163a5144879f6b8854ec949adc32cc6c1873ce5999b28f0d39c82ccba13f831f0e342b722d3120c4b1a884dcf5c7ae74837c99cc98840b809fb70e22dad93f29077f07cf3eccc147bbe90b18719083371bf70f5946ad243ddea254dc44d9c8599584b33130c84afb4d0b357e6c25c449ce613e8f7d74d224e13d78d709207ba35c2961b79f06d1d4b6cb10535b84c199ac2258a2630d28041e11445132898c2d0e22455458aa62c5aa77b6e436956665de94beaa34720ad13c2ae87c1126197ebfb63a11322895cdfdf906ef14bb722a431d0ad6842b7f8e572fdfc52a9e8b263294e3e2e922bd8620b651cc9c069064b9070c0d17b087e1cdc2ce2b4f767dfce28d85ace5939ca3498a022d852a9d8c3a91422ceac2188ad18979873ce39e79c73cea239e706654e9db711c1e9bebce07294b8e3c2cf2750788a0c5ce0e1f511e0b87404386e7fe8d68e00c7b491e3ce2c50be3f6457686384e588c8c9f45896263b129cd34a9937f850f55950ecb1225871e9c7cf40441c20c18e18c201f44568e3669d741a4ae79137d3ad9d3c3a7e04382e557d00e4b8d4d33ef673f614681d9edc916ade2694b8dd74b2d1647a1eb9c347c4f8c241132b80459c39e7f4d93a506693beaf5492c83176089a4b52404a293d529652423961a33a2f9d022e8890745f6077c753df01b604220bb1672a808c1880382e7bf6b96ba971e93759a02eb0d01511c01b619a3dd7305d173e1650d040c4d940a88097d2c31c1eaaf9e20ee996f46e89c84d548bac954e1714a7df52707cc0f345161fc6579cf20c8b559ead4001830d18289a87cc04bf1250c5078ce5999b3e0c25bfd500e55af7838a81210315cf675b32fad56902be287aca3f259394975167c7b7d3076d9c1da194c40d647777774ba74fd2ab9015299d56915c5e6679e933b6ec0d4a27c7954c46df617bcc8ba797a0745aa57598062f6d48fb6111473acb85ea6fde6852fa0870682268a91927420baeed7ea68bf0e4d6da4456b3ea5389e905f164985fb4f23d715670514cad13d2296d511486f289aff8a2309f884556c374b337ae4e13998d5158b7a4774adc2b29ec975a67ba944e63ad1383740a9bdd8fb559ad12ccaa8fdca1b0992da3302969172f6d60b232fd3e096b9d70a29c84f0428a1951acac02b8ec208aca63e9a9d3367230839f3ea79d73ce27339cc78439e79c92841cecf094a6b07421c5cf2986a89cd560a3b1b91392bda41f479cd93f917c3b5b0d04d236cfd951fa40a923e07a68848280c56aab9a1462969f41cdacc607b6d802962227969ce0b205d28b47796842061198f23a8830c0eaec3dc4931cb73d7e8c8d51e5f96d7cda4a898dd1e4db8db88f00c7a5fe43bf90a723c28fc08050f8e94616d02d9f0faadcafbe00177c546e399ea72e4150e3f2f8f8fc4079d8c3722f65e79ccb2f8481e7a5f374cb0706577ac853427742a4b352984ed9833e64560aecd469d04b675a42eca87ba05bec42a1a23ccd0baf0aa85b4b2e91a6800b3048293d106fda99a3504282979fea4ed086913818b06f3eebfde4379f1445b9c377b5726f310f3f692c4d36127b33b1e3e37fd052b23c5779d65c569db0593e7d589f3cb333d12df611beb848da17f64b6306481ee96342f3d4274deb01d3344d73556b9ab3a6694f3fa5f44e85214d283389232210cdc53e8e624f7b0f1e363cf54973319086a27d3094368b241406329fb00ffab93694d6509ea7bce661236547dd2a92ecf249ee644b38ac4ff249d6279bf9d45f0c3c8be4cebd5f2d2ad2be4de37cf470a73791e4cd1306328f487ae624220e7bd8ecdddf3ca21f958a40fab03ed9a6d661a59c1fe5ec9aa73565475ce3c89cbdbe1181d426ec834beb30aa09b3d3a655136dca9abcfdacaf56df64b514f117aea4bcf685199467afb04f437d30fbc1da7b79cddbd35aebeeaab9ac527ab7578bea16f6c1cef2cb8ebaf51471b884f6eb160652df883ed8398e6fcbb39390c59dcc9a4b13d286acd396d689c1ba11fb9bb35b5fbdb2a11ef5290623175563b54ab55297ba85c5ab36f02a0e220e5758cd53853de5748b3d4723aab1c1e685b6bbbbe9eccffae8e1dae6192773b3c0e9a7af3ed2ea49666ee93954b65704047e4da7514e09f3d639fbc99764da4e2a589231da52cb129396d661c529ad482cb68a0f6516e6983f6be5ebf5cf3e78b83d9dbac572ca297d04015bbdfc588838d3656cbaf4e267b33aab3277fc7416ea1d8f282a15513494256422a269bec4949efcf02173f999552a5f2e5f13cb9c4b3fa7cfe95c6bde6777276e87d99ba4f308a3219ed0295d497152c14566e624b9238fd86804376e1371470ea171c7ee4aca253965b7ab635f1076f190642747ec62d71dc26908262a3e6c2cb263809412958e865e3ab3a41fe0630cd74d3ce1c9a3239e7d05322929f6b03c6872579ffa1839a577e40a585679d9c4b37cfddd54b0e4675212114b568a9d31ce3eca4b29c94972875db632e521768a1ebfb0b57c1d931d1b923b72886834b4faf849a388c3eed3245c71637207e5ec7d25ee6cce30bd147be49194d237bc7df2881f3d7a843c2ccb119e6e2865962daf29723c3f094b776324a620c104e57a485a9b4a35974493a7490875c7002133047a9610eea7cb0f3ff0f32bc25d62e01f9243a96f2d7d25deb04ba129dbe8490e35c92126a87cd8589a883b6d246f38f644efa327be978cd89bbe70e386d2c848ee7413f186fd8967ef254e588dd0c6b51f958e60e2e5d1a6daacbd77b5726fb53a86fa3a46821637ec981130239236e6588ecb4714c5a2d211439289678f0c6829331296aeed7ea20cccf4298de44ec75a1a65e1d256bef8e8c53c7729440f6b8c3748c2f2d1a3cf1d03a2d32fc6d674b9d42d661d7c543222cbf3770e88de2d7639e75724530aaf18f8bb8fabdb372377e66177bfd059e64d5a9b9b9b066e39a54fec912fb34c8b1127b35e91d47711873df342cb12d22f586fa79c750bc7e5b7ae79e6bd60dbadc78e8b381c7d18083f7513acb5591814838375a904d117a2ac4b940cf68bc818da088d2f996f94528f3146ea557b0a53f3b439ead6b3d0fa0cd132eb2e7762bcbe7095ab2f9bdcf9429b7d75fb7cba453f14b42f84a47b42bf4f53fac588c33a96dd5acb6ef905db5ed8ce705c7f815b87ce9871942f5964c6c145390af531370dfde970a30f915e3bb64a72a30f6120fcd58954cd6a5606fef630e8b36e054ab85673ce39e7b4c08d4a515eef324aef30289d8775f2525aa02df208291157699dece318b79d6d0cb347ce8fde41b9ec844cdfdc6efec21d03505f6823bb158d49c9596f3ee719917254caa7570489eb3319737541eedb6f6ed5a3417c36ea63a19c7e1ceab3321449bdf5ce65ec5fc6b0c826b9c5b5a4e80992149815a6a9a5539e50146ebaac3ebff0fbed6528720e372a45717a4eeb84c829dd524958b75eeb0280c30de5ab6308121fe541b85feb7eba2f461fe1e62d6486df1ce6dc373b21f59353ba25037f683d7ea5284cdf9e3120e5ecb68b70a61471a46b5f114fc268e4c894becce999b4e28533fc9c9f8c451cb912baa17cbda6444a64a310bda494520d3523c739e79c9c119caaf3e83cad83dab49ddb791e601790d090cfeb486a871be648d775a175e2e7bc6ee7e83051060314b7a9563eed8b7391e338cea35724d28eddcd71721cbd229267ebc4c8c35dd5caa675506da757424e8f1f3c9e4fb74c584086a5b5e486abd96c5369d8e4a4def526bbdf267797a022717d23d9a70743fd6ee61d652f431850af0450cf62cf0fa5a8571995d9b831368585805e17482963945f08147b89f4d14330baec5122bd9432c618e5d702768fbb1dadcc6136628c73b6a668fd10e38c31c648468c71c618e78c1e00a4b8d2639c3263032157338c255cb7e67767337731639c33c618e79c734629a78c5372b105895f84bbbc92367ed5ada25f752b469888d345b8cb73ddba11c7265c294131fa5065d33ae18f57c1d8d6e1209efc2a4a0f14c4deb8296de58bf64acdb758c4f3b2392b6395d8f215f823eeac644eeb8240c565e7eee7e85f5e74f8aa73fe88cccc7c91bf30e7bbae63c762e8bbee8bdd7af9c2cfa753b2498ca7fc7acd9d17ba0bf3655ebc1f5dae7f07e3b1e394c77841cf301f013a2ffc715fbcf3c2b8f49dbf78e18fef8e7ca4e6f1dda28fd4bcead60b8df4907e555ee42fc69795c116dd0bc1857943fbf844184e1f9f0883e9aff8eee31361b8e0d97e32f80a37b4effd42e369b0814d43528ae203cb88caeeeed84c50e092524a29257f2dc50986469006757db4b160c992454bf767001a6ec7be63f203ea922aa04840320423c9cccc352461669e41921ce6ae819452e64089945206a16469632ec00ca8e40c7132fec8e186bef32329674806bdae808103868c279aa8f24452969d094658e51943a58a0c162afed2e057f2a35212529492406a32361b1c248b870f6266a31b88628c3256a48fcef62a3187f606b356c610f36b48ba6c170d49220f66392e676dc71d55a384b8b143243f63926d9b51fa074a2efbf4b0bbbbc339a56ce570cf39a5742965c7c8ad1c2abbbbbb011071a2ebd861767faca818489fb187569f6e35f5e49c9339763f6fd2a3ef33a5fc8d4e3aabd4acc344495dd2593b63cb3b9a5df1ce86f21647cef191373fdb8d5c63ec618fcefa28f351c69ec99b0f6d335bbf6f66d587638fe69d0df265adceacd1aaf564fe4207435f4a004f8006c4743be20d453d8de9c04be7491b091da2435fd01bb0adfc744ed6eaa7b1a593e5e4a2dca151c9b5e956fbaaee6c5d0ad502afe7c54942e880170fa6abf17e5680f338de4cdfbc899a41cfec3e7ab8d275a6c7fb8510c665df6c56a76ca6b6ebd3167934d7caf1d5472b412befca9b6d052d189d3dc9cccccc2cd9b3ddf2a85cea4550763f43a86f96e37a87eb1be6a7d661276bedbd52ba7aa8eed4b79494cc65d24b985a6fea8628be786629191348508e52d7e57219a9a92e5dba201d3d31faf8f2849b7c7426ea629e50f18127e609951e8a960c7d949cccd20dc058c242ec3ab2e5cc208105124f5ba2c380d291822d4bf4d091822d4a6cd1d2e4820643ab89094b742296874d521a615889a1903905a14b972eb129d14ba83ca8f4a0021b1e547a7852024f0e150016486401c34a00582081054f4e8f968e9caa020051458c1e3c32195f42145065c402092c92f8cc2f0cdc677eb140e2b38c7d6ed672e6f766d39b2f73b4451ea10ea697d4526a9bec163b4532bd742b452ebdd4f292bbe5cec69c0f2657e30f636c29e32cb75a32454a151b93af973edc259b248dac94d6797d124965249fc8251f4c2e1d6293c2883d51c41d0dc81b695f0cc442c1c5cb2b5e56f1d26f78b8d248de48b7f6ded5cac8470ff7f5d26d122a2661d40b129fbf199372727075b8cac3d8b425b54ef4c1e44e8ef3c1e4661fc658520f37ac2e1e625569f4b2d68f080dd0ca673c080c2d51c8472abf21921aa0359e759237d2571e8d37e3d17c2cea2b0f0281663e16fd582acc388d53a7a1f1d50744f3d9d74c1038f333c426c91be9e4caa588235d5e8938d22318a5f76872c32a61232c5d0a4afe0c40c3e527471dd9a4db3e82b8b4e9a5ebf080a2109971d50734e33a9ceb7e588737e3ade48df4408c2b345e0463f02ac1a51edaa41662d7028d977193a4d0ccea35f34c730de5a8cd37ceb9cebb177f4979eafa857198188ff9c25026a659a6634d2fae22295cbb0ab501a4abea5075754b9620797882c8f78938d2262d8065a521de48c741ba74451c09ebaab4ceb44949493a986a84d8220f6631a330e488109105c825db3014ba7bb55a4191567a3beca8d6eeee9c1c1192dc2340d6e54b47a1cb4b9f2102e94f86583339a1107b6e5efa1006625d2ffd011f903dadb767bbbbd93aa5ce5e11eb3e6de352e7c0962a0c8642a79c5e7e90cdea96524a29a594527a4bc9e486d64a2ba594b6d229b570dbab7b2fcfb4d66ff662ea1816a6a2a20f6bddf279589f96644545513ecc8cb2273c3ccc8e3229d54ae5229441c960daa54b0ea5e04349d4e45b16c978289f2025f560a55d4ef150c25c32c9a6a10fa593dc42e3a17cd2e1e114222af2e1890fa7d17cb26a0f2713e184f9c0e5c3199b56be77783897be3d9c59e61309ba782a64d31ed2261dfb901efda0c45326be3da453e8921a1f52a60f6916f790367d7b48b7d4a11270f9b012e900a042a94945397c585f35ec27e9e4a88a5c925c86a0c47062994db4884aa1302d140c6b029056dd435cf4d6b4ab0bb109072d663e3e090d71c96149eb68ad1bd5dd3a50e997deba398b53f3d312a30fdb15f692976ea33e6202c6878dd44c744bf9dbb05ee2c106cfc3bfee87c7fdcfbdeee7a380bd56270c8087e0a11101f85c60081f12300a0fff1c0619c5072b5ccfe3ebc0e70070ef7e00f0c5d6b99e67e5439bf77e78e23d1bbc578211bce7f9aa042778cf41e87ebcace9dd3fe87e1c04129cf120b807dd0f084064972eff81db743f1f3cf71ea8de039f1eb86d22c67be0970452de038f4d98bc07ceea7e3c582d91e56d7c47f763c3f2c18a67794df7c3dae1abee6747eb6b7c00e26b5c47f75323c61570b5729aee67c5e37564791d3ed3fde8a0a17155f743f3fd4c0f2cf81997e97e66546ee34e04551ed3fda8ae142fe311cbcb384cf72313e3b7fb8969c1680183031818bf26781822351e8687271e86491b0f13c2c3c078aafb81e169f1f87065dc8bc5bd08b8f7c75f8f4bfc3dc0dfeb7749d35f5fed2083bfee3ffc1dc1157f9914f1d75fba9fcbe3fa9477dd4fea45072dfec5b9eee765a7f3adfbe93895f7a1cd7338cf717e63cfe970f45c0e44449dfa9b6bddcfe628949647a1dc763fa80fa0307acdb3ee47e3defab43834f1560c9b0dc980521f22fa396b5ecace5ecfa33d12d45a6badb5d65aed915a2b94ea13712acc0793bbbda6691d7b8f8853399fd8d37d7511925cf9d5394ad461a15bd52b7b75867244ee44b07a8c3a1388ad8c281e893d370ca4ba02df81f6f9b1a67f94899c741113464f1a0a1ff1111212130da575589c64619c74798a85b1dc5edf1b4cf860e3c6c931fa6a85c6d14b4ecafe6eab802557e1838d6b421f691dfe5837e4575dd791248bc3e561098831da27deb44760c7e34df431de8b6f498162dfa9232858a89b95b600a33722a52a73f4943e26b48e65fa4ec1f37832d23ad183e0e03b6af1edb12748fc185611673a4cc4c924bb05b241e08d38ec4b5896c62262bf299d253f8d045be41182f07a761f4e570427374c3dbd4090f2ec2084776836a5b4748bdd87d30d79562fa972c23a417e7b7b3f7baa294c6549393d47f76c562e901f0fe6d4d3502a078497194f436e24b111638f41cf512471e2396b9fa0748cab1863f783edf1c3ed4e48a4a2c457ef1f5d6ef6118a13487996f69e8da7651ef5a6b7d271456a81c126bd394e4a2d9d2c841b4f6ec05e6f3c312369d6287f74ff748ec79374c3a08ffe69b1f293eb135cd594527a4eebb0717d8d225e7a98e34e6a0d9899e79c331a41997e404840398508e640c30b3884d4182aaa5214d51328a9b5d65a93284193b4808618861671ac0145ca0d484460f522c9932447b00e5ce450c31363cc20a6851012708032075ce0c0731051bb4882c34cb2830eb5d65a85b6d88658c88d98c4a5e960e89a4185d448d2c51a9bd21667bc0c12a2061c8c5032c404920b94dc47a52dc0f8eda3d2165a7ce839168b6d4b45fb36e274958f1ee3ba20f22d3333f394733ab78c38f6a79bddb235cbac86ea7e48f0e28696e3ba971eb1e311b65e3c322e7fa18d8ddf1b616018863915cb68dec0f36761f0c151ebc88f4e3775943a4a41699de9fca55edfd15348bd934a92a924286eeae8773e951471da39a6cbfea9a46eb5f74c25c92f95944afaf65452ec891f304161660eeaa4b454850956a9b56c628b21488c21486fdc718cd1e3ff61b6521ae1c58fdd0a0dce0f0809c81e7db2e5f847ce89f5eadc5db5b22cd3e249a63a69b1345f4b3a2c2d916161a24d3bbe48023e469c2cb525cbb200c4ae4cc9686f4c2b2243acbca13e7e8b2be2d0317e768bd278292d1fc49ea6c468c518589ebaf54d2e1d79cab47d28267953bd3b22a80f75e40151c601d6a35ba75e887a05413d7f494ff9a917dea114faa78875b96e7823d4f9b913b2fa220a88d4e953dfa897da12bd9453b72cb5366a446e14cdd8486762ad13a6b47c656a6a9d30c565c6cacc4c0af4ada7b4d894536a0b0ac5a57534af9ec292626a9d8e5e3d95a575a8dc614a35b58ef62da05bd5ab4fcfc7e371fafdf861b79efd76b71b8dc59e17a2b384a89ebafd9077f0d4a9971a8a3835f3504311a716c0c90d67e84cac0027b899d3020871a387286e39690da9d55e5842549fb9fdf085cfbef791d18b8f628a3df3aba396628feaaba75043b18786e64ff0e0554811a7fa0094dceb727d686341b61342f8f8593fc1befd2d7a3dbc1cef47b7329a657106c98a31a46491f6e089557ae4fce0f15940f77d71592778309d3ecb3c3e4fb72a6a0985a55b00208ac3c56ebdce50be79f7cd2cc52eca1bbae4cd68d7f5d5599a765d7d85b67cf53bd43add57bf48574aef54a3bba475a292152b5f3d86d715a3e1c37bf4d5098b1f3ebc4c7cbd445f5db3196a26f6d52b5dfaea758caf583e8c58bec62c5f61f0a10dca93ce835a42619989cd2cc99da55675eeaa5aa777c4667b951f2e399840249589a770411c715c110391a4a000b1010b98891cb029354c1da4b8c205b6d739a001f6087e584204b8554e7a3bb43c110613d81e3bf103b86595ce4cdba1250a2c9ec0f6f8091a4024cd8cc576638f0c45b22e5d9efe7545114bcf9f11194de042c4e3d96b9adc302747ca3047f6aa7372ec16575eafd52d5ed550c19ca39232466f1dd5770c8b074450284992eb3cb475ec067d96629e8028a7abd0a04f8f40821bd6a20da975c23af4d389e48ef41a04d7a20a44ecd17c562022ceac41f0cde41bfb8535053f2b123fe717d615e8f869e48807ba35a7d3e62407d73e74706d181ed8228f4deed895f3e821ab479bbcd011b9f3a3b9a87762f740e276c79fd36071e061f57324e2b8c0c2131bcd214888c203930dd6d0c205b627c20d201430a062086c8f751004d843d440e83539e901d524456106884401474e590680048844c715507e740d293fbc0122c911020543544105d1143c5001b6c76c4c81061450bc200bb0bdf8c49318b859aebd49040c40e90149287220b40444d24a5c9b06850d182a0c162891034492e3a48a1b5430068f8d6b20129a78c90122895d9400e48c784152c749cf004ab8f1c2498f84225e8004b617c12dc5498f6590032423b0bdc8850ee07639e94528a6fc7004b607802ae00653e4644611142700b7184945164f4280483a295d885c678048649640f9c536c026c3494fee40448411d81e6b3902dc549cf480e81c538e7e0091e40831841ca0f4f6805a8b1f40250dca6fb601a44723031f8a9480ed512128c08d86939eb47284182fb03dbe320370b33a76d4b0c40e8ec0f6a2530e2092e6c9c60686170a2f7c48aa428714c076804151953988729898e24617af2ab814f104dae000c68ffd84b502154656d3340f126bb535b359952cd8582b0071194820ca3537c2df028b5d471208a42309dc220febd50c5d0f73be9fdc7075135b687d54a2f2a444a5e9a31295a5c7f9a8442589f7e24e4e5291125398c005566c01db256799735a6b3d487ceb417fe499fee87295a810f12cbf7e9c03fb901e8fbc7cc190530a40245d022c3b28a2c70e40240a40430008f8c20d2140240dc795357c005b890a8884999801f617857b6c51ee00d12fb4f80003a5032161264aa47081d38190d4b8202908503a929a28446c014ea058831e4024035002049a5f1476d9dc80cd0621bdfdacc79f4b2ed8ecfcf17443eda773979fecd4b3817a9d935267a694764b8f338e395177c2782af6a4522f2fb1e7e5a5eb624fd7715cece1b86d8b3ddb8642c51e144ad3628fa6451ccd469ce99a5bcf461ccd33a7b1c7faf41a7b5e5cf3197bb6cea7e69d5723901a7d683efdc5ab11673ae7651167fa8c4066f4e1598f461cad4b6864a23814f7c950b3a1b60d8592416d329ba3b6af08376b3532ff3a2ae5851e789491f931f3aa62fc42233334326564647090f1242a954aa552a9542a97919171253ca08c2391f9542a95caadbce90f8ab8ed7647e54241433a78b9646464645cc806948cdbd03292b1511ccdf10454a954ae8407547d4978a0600ba5a1284b78b8028c62bf178c043d11ba81500aaa70092306da12cce08a1180d1c4151cc0760fa05028948c0c0a15136364fe7419e755dda619c166afbfbcf895e9ba3c8c6f7c278c6f9afce9d6519e7c6bfbe787c2b1284ff3170f42fae99d6b5e10d237aaf32254861acd9bde7911ea1f7841f3eb2f681dedac779a6bde695f11548cb35319ef7ae731def5f829d7c788333b4f75be35f78211d539df64f743dfa76f5ec82750df620f438cfd07827eba66352f829af6c5c3e99a6f539b5f11948756e51a6a7aa18f9c2afb1579f98cf8e0cadd3c7ee7eca8187b849b735b1884f4dc97d5ea9d87f63bdf32ae7ae7fc51ee0009c52e34f0020d37e290638e2ea0ca6d60702803930481d63b4dfb52a81e5a0754b76ebf30fb19dfce99a0a73ee3094579413a2b05fb2887217b9474cdfbf17451ce5d3ed47cdbde4801f585d60895cbce882107551f921803a3ccf95bb4c08d2f294ebc5e4e3cf9ee4016f45de6c712627d3a0364e0cf3e5ae717d31c6cb3ed81b7df0b46e6db906d9d5e847a78e4ed27438d94524af915a93b7c5cb9d2a32dc25f8c3d42fb15619f43a8f542fb36b3cf5f8c3761f615a99f11ecf48bdf135be401c8094e19a4b94fd86a3df2edecf347822f1891ff81ed63c92f85969f0cf25f88dd9aec41cc40b605c49edef1638e5b3de86da80e14045667e7e82702d773b27e916176ce3967c489cc5d3e469cf8bd24076e545202c9a23ec6ae3409b9e449a533cb6fce965372d9e201ae538f1b7d814a66fa02a519cda8675ebd17a8db6e359d3f2ba5b65b967a946b56e90b95d6acbe5033cec69efe5969a53483924aa552a9542ae58483f117bf305dd7f9ed522fdded18e6297366470d19bd7f53940bc99c9979c4507dbaf48cf04be99b6bee5a4e7bd66a2f5fa86953d366d4bcc709f2b5cf461cea0330c1cd9c5f18680d6c20f664edd4230820ac56d1da18ef1cc6a9ff681d56cc27a4c5758b73ea9a07e3d96e715dbda3fceb85f3535f0c3fd367e4a2cef4483dcc3edeb8637978393d240f0672137db4f7003e1e2d003c8996b333dc6619cdb2d61c2e1cb034cd81830e5c14cdd124896af5246fa29d0388212e62f226da3986d001cb91bc597571ca1a060cd8132060489ce0ce8f4ab0a42930294a6053946cb0454e8c8955779006d3a450482e34484d96f1618c71c9e1c388258a6183105098e0e00b2a5b4c31e280e3a5ab56414b94288922040e3118c2054a4741ee504009071dae3851451a5d8057d5faa81487151ff351298ed787d79dd8b68f918a94b495736fcb9d2727078500e4705918226f180c400e316e7ef2ca74525a02a1bbbaaa951070f000c70e53261c422aeda3d21b713cb1b28146c3135bcda20a0d4c80d51b59fe7e547ac30a4d638b1e79482965a444b4c91ce3c39b8f1ede3cbbc6ec8535cff49b91267d137187164947523aa2f2fcc473772bcaa64572478b37d13da49aa3901a51a62e44c8e2b66f2a4406e38e0d0d8d873034adc33b236c78888ea77b001e179ef899d34525adda50af9e2377187cf1e94a2dc99be96174babec3c3b8c4aa5965a925b973c4f5d3c314d312538ebc99f4f3d5ca7d9a520f5c87f496fee275d7b5772ebbce3cf88460fc3acbeaf022d825406888076c0fbb47c0d00a6c0f614a186a817dfb05f5d3b7972b9769ce0f1e176028215689b1b814b3d09a7a6a9d30b594724a6d497159923b2b79333db5b45ad53859f6a34e820f0158488983910b1026e0a7473640d8b37d39d5ad57b7df4fc61a2265dbd05496c3b8d00ebfbe49aff3f65ea68f40832b3fcca1711b5f81c66d3e56751b8fe00a3a9c556d7c85ce6d5e7c06e99daff0e2366ef3cd00fa74caafc739cb53f90e4fc6575e8cd778339ea93ce54232ce39f55e585e04777811acf122487fb4189f71212195908c0b71fee23a3c56a5f158d5af47d0b2aa531e79236fa6cb782cc89be9339e06e4cd7ca9bc2e2647decc155e1ce69b81f317a7de0a9d5faf9e0a29efecc60de16804332e4bfda4b0bc78acea3cf266d66fc81c37c5945aca31416a2926c8768c962d82517e2c1532df7c85eaa8ea5bf5193cd6906d73d60a29f4b33777fd3591661e629d3d661a22947564f9d26e3d96f4cd355f6173fbcdf0a17c062d82d77332cd8b20b526608a4edd33055be4e17147ce0574ab4acf16893b31aa1077621c226badf1cad70e85ea1d191eb2518e0e97c663bc3ba7f1249cc7d07c2c1af3b12891ce69649665b47b98e00e913b5ce7dc57bd1b226f6a189750c8d1e1ce1085fa0c9c773e838cc7387bd9c7ce89701f2b731a9fde39fd88c87c2c15689c08cd379d73299dfb62ea8f188f95655a48f339dcfd70db47a4732094cb7804fb867ecdcbbebb1fd610cee31391ddf4ceb78f08e7349fe6d9b71e7fe631e7b1503e04ec3c16ea1b124199989a396eea29e59472ea32efdef09be566eba06e98add343a8d93af6069ad91754f61bcacb7ce3ae0518ef3e966de13acb7e51ac03a5b817e73c4808bff50744fe21348ef2eaa368328b7a4004bb6f8628d66798de71df0cd239a77122d3693e16ca693c8244a4b35034be828cd37c33442142e3313e830e97f115625ce5aa6f061a8ff108661efd8dc66315892185fecc87a8bc4890f82aa771d6101dce7a400475386b051ad7541ecae326d535198f719fa6f15899ab3c823a3c563633a3fa6650398dcfa862543432333a62dc7e44a4731e3fab433c173c0fc89b5a613c14e44dcde956f5ce894cef3e5646443a2bfb2eb802613d5a5fa74bbfae8f0040c205d58679b2c50bdc680517af8f5d7cb4620ba6e7828454e3d137116257eeb0d87778e47cf31536dff1cdc0f9e6fdcd603f167f608debfa5c71b9e1eab98fa5398b08ff10e95bdcc1712c9a83c5cd7c8273f39c970e0f1929c699888bd888c6371d313972875f21cfcfecd3800bed3e9db57744de4ca71ec3ba353d532182ed1b73d28bf280080ab17c876fcd711ecb376f4710c8f9038240ee030a023967399116bc8825d100721f500b5ec4925ce08e181e10c1fe84542ee32c0ddc9813218bfb93b1b20c88991032fae9213789b333caf7a875a65fa3fbe442f9e9829dd48acbced2be21ac1d9ef97624e24cef9c5c76ea9a5f8981baf6fdd897a6cb3e020deefc18266b088bb5c3bbcb9cd2b8ca85665cc65b72a7c6a7bbdc59f9f48de579e03b3c1baff1a4afbc8e33933b717a58f347624fcd4f5f792c1538f7c08970eec10714853a9074cee94764739b0fa8591ee73bbccd6bbc08aebc086e59045943643b17e3a15c8707e334def5991797f13ab7de0322282474fdc58552de79e66d424249500ee34242d7855e9c73a1940b75beb94fc778412ed063188f91268a937e822f1cca0b721da999e3f2746bce9963658890f4be481f01804415541ba6872d9b53ce3967ad52d618c2c0359d1a70a6d5c728e794934e293929a594524a8fdd629fb151682899ec514e568204154a9458c96928c978d8228f58024f474951e8d66742b79a7326ad40dc1ead16ad1495e5f2f09a4d9ba1cc4ad58d51dbf1f179c5d6b19a7de10a8794d9620d25992b6ef751698d29313b5cd447a53562b0c6123af0f0246f64d6b8a98f4a6b18ade0de8f4a6b10ad31e43c983ef41c6a438c52cee9d37bc9544e29254ffe7cce9f53c678d3f21e73ce39e9ca63cd07200673360a06955aedc2d4d81b125607f8e81e6572b95c74d25aa5741e62a2e7a26672d986b88342eb10b20fdfb575e3820b39ad960f0fcf09ddbb1099fcae6a5e7eb1c7e58d0eb4f2174b498c541499743c5d1d4f97cf68b5513b45a698258d2c50a85ed224da8e636c9184890cbcb0010a2532d040230bf98891e8196dbcd4ec758042082c48d810bbd2f42117a12145c84f648c6d1187154c50bc40075b803dc6193fac3260c30e2fb08113521c15812dc6b75fa66f57b50ef7cda9aa7c6863f3210f34da10809391d31969c40088001ee559f783fad5ea06afbdf62aa1c5c3a65b69308146467d138ffa26fe446a25e5bc78607d1341a358dfc4d8174343e8adff586f1dcfc65b677e1b1b4e2f309c9fdb6f15413e6388cfb0c85cfdb266681100af71c38e31cd96cbe5aae1e57259b9d34ccd640694fff13287069ecf6935d3b3af9ad8e8fb0505cc31cb638613ebc51a45bc44d6f7f4d477d8377858d5743f35e643ee29752b8616264f7dd5fdd0cb2e36a298611d57ec40ca53a7e97ee86a3527124f8c9852c692132de0d4011a37cc39277f3468dcb035c6539fd4675aac430a4a64d1061a390421871b20f556ebd82c51247162a3aaee87ca8430e7013eecf1a38418c62a62b8808a18738c4184d2186e2835c16820c3ca4f47a175a2521946fcf498181414cc0862dcf0436f2ba805366ca14214050e2c5a60c3705aa2d254f743a7f8518502c2d8a295a5862c5494a68065914307b09ffe72698e00b03009a1a407208a4800ce2b66b431e79c5a10376ccd137c094f9d6bed10460d3fa76f4f6354d6414d28c078499146ca065f54f1f3675a32a4dc4a63713c75da1a01d3959f3e271a472fd15ecbdd1e1e418929892d37b43d94bc48a3c7dab06075af1d5a424d58b294356132912a113e48137678a22f10a2552b2218518c68e95e1104334962f2ea9bf8a1bd4a393083890923e8d512fda8a446d287d7b7263c25eb4a6ba5334a2ecc4725299862ce90228d1c48c14555c4dd3e2a4d31a43ae3eaf8a834850f5e4c81848c94fbf251690a16c09ce0d68f4a53bc5a2aa881246fe24f964a55caf8f951290da6b9a48ba78f4a5d34b1f7f8a8d48594d7334bfa7ce92c19da55ebfa537cf1708c4c4dec162687c41dca246fd8ab5898dc8931f6c7b02f067b523906eb1657a00bcc6b80698f30b98372728241200b16195c16f50f51b4bdb97a7173d5a3344bdfe8e0f617daa5e727b963955c579efd8b67179185d9f0e0562ba73f1e8e634d94136a0b3beaa97552cfbe19b10a9c505cb058b10143e71f1d4a36ac755827ec6ee2b975c28ec173d84e3c4b7163e809f5c22ef9d609ed14760acb6485b1304c0b6ff9f121c384963401e3c376f2c587fd0485b2302713361fbba4752c119125b24496c812d9224b648f2c924d6247512f32573644999888f437843e691d7a44918ee8113d62a424a6310a48f9b1e046ec1181cb65c56eb18658d7b625625e7f2175c2407f2e48699db05fff923b36266fd857d757fd62eea6670b93370c037bd54093131e3072a463107bda3b10c3f80e48206cf0f2e5d3edc52cbf630ab996cca16e22f648e7796461ecb64aebc03c3b770c680774400ae12e4fbf0e4819b304a8eaa8546dd575490c19aa190100002000e314003028140c88842291482c1e09631e7e14800b859e44804e18cad328c87118420819420801220000002232b409003ccdafc4219f02b14d1a0f36d4410edf7983068824213ca2d100413cfcef8e31097632895c7edb6e627d04f13b4d637bef62e521e01c821f516394898a94d04c6b3a70eb0aba6be0dda8db612d9837ed1096477bd86303318ac65ad9df4e90a17e7a2c94ace5a2b27c62f6e313aada64ac153b2b841e1af8e3094f2603357c7732a61d33a170efbb473231d73ba5e249e57fd60c5adcc4a4fa9c10d09bb047689d4e203ad5552dd176b9df2f9576274874505b859010ac8477fdd93a73fa18a27a54835a0451b529f3cf5f39cd0857d46462030604ed86b8a9defffef3cd8888bc8fce1e1ff64a7412ed012fc46275d40c5919b7c008983be74db20eb6e51fdd2e9df1f146389babbc61a7cf481e33e0eb8f0da7c1e640322e0e753eaa3ade005d322482aa22d8ee732ca63d9492467763c2f1d69d853a57c448f6a6ef740db619964bc2f5c2d3aa9303e84e4600ef67a1daa4057046beb50d69e3a52998ff989f6049063503a6e5cd1bd08e353edc6bf2972e421ec34c1131b7efdefc879d27f6c1a010c77a80e8f871bf49ce649c64cb0cab3e7752d70b1562ce6f35b7a6ab178c7dbf868c05c2ff6700353ee8436b418fd9818b2e39fda06a5386e70822258142d8548e994f72ab407157a2003aca1c87a50c104585a8e1859782f5fe8a3a332fc98f53dc23335be17cfd984558b74d7e96890e31284df59e5eb9b3bf2e19d2de4bb18fba40417a007532fa30e3b448510c229d21be9a2f31907cfa3075d3b82a580d96c41ab1ac55d7b7d8119265ef12b04bfb55dd1d973f05f9d54d10bff6781ca3e50dadfb7a51737fe762ec75bf57590904db495e676b134e9d2e08b08c6244455342ab4837520ab3d9da77e659fdf68bbb0257cd5d21f8cb954b27f8aea07bc9f2aa6a872fbbf0ba1479f528616b1185ddc52b11bc2c5ff898412427010c4a03bf25c668e443a8fdb9a0699fba06464d92f240fc3ee05b1eb36053080ec1a2170852e6f8da17abee0848295a28ef7d0e25753dbf13e6fdaafd226d78530dd98ae7af0eddfa15d261ceb59f69fdab170201796e88d23e4dac002b50a2743e76d419c96ef98af3801a5aed68b689d7e83d49a307abec4a0c6279902eb20602674874a0eb6bf49b2c9a0a036a2cb848f9db9e901df289a1213ff80de9927d56185f9d391993a1b8247495a6eb77e6e1cc900f6174456f55c377b6a533da5a25d3fbd3dab769a091fecee0402c31a1d2263b520612c699b3289053bd407f616e837b4c83e4b53840208dac4b933be7b5cf6392949e5cee4dfd9e6ccabcc50b9ae2fbaed7d37012e06e7729f2a1b38c1b4e78d993ba898eb84ba649ee37a304025ca555ee759c0caa1b74bc709ce664370e262aed4c4d09d8fb8784644a564a6ca50b2c3a621d5fcb6d6123052b118097cbad255d7097c4ca9948e99d54b7fe8176be4969f9a8307b6117c6167120e9a42435aae279417e34f29dc4c5ceacdd7b59f498ff10293987cd7a70555e1ff19f0a039b5373d9915cbc01cf32e21f99a26947ec0aa5137a02d94885d66f88350e3198434cea9026a7a4c1e6e9be9c77daa15702f40a314d60d9f350946a606587d8c0fe0086cf806961dd6ee73d43f4c4c9fb81aad30e3dd3a19705e874a5286cf5ed40d874eeba21d1d52b2a31d1124aae0bfb6772c5b070fc738d4c417e347d8581e4fa2b8d3550206f0793a8809e6f238fa03849cc0f418aa4e317097da2e47faf279009efa2cb84b3e5d4e87fa31fa09344b57bd1b4935683409ef97453db0151cd208aa68ea075079accf6c68166380aaa9c441b3ce48afd9d38276f3eb18b09a0c15e0652a4bcdc4949772661b8c0190e896b20a1e28f154bb0deb1d8d940504546196762e79d087ff69b4abda56abc084f4ec2bad4968be2ac74195e7bf6c56c43cde4223d51eb1fd3250aa617f42e3c6631602e97390a0c20d6b09972cd5a006911ecb64d7ddb2b012ab0c74a8883ab706b53b15d15a02e6b31678089ea1314162788014a73b0cc40cdb2358594ded3d0f845ee30e4616f382c8f9e6cf14a760e9f889eacceee17a91e6ebfe026c8161d2d929e28db6841bb5cd93ac11c5d9e814a2e434d5674a790b29234f192ccf15765f4fafd0cccab0fb0e6ac29dcff74c1d7c5042f85459306505896e0cec17a8d1b57f72de94ffb065a0696c88040d349fc789f394eb6b6049cce4e2df1e136fccc59c21b505bd053642cc6251aefa9ef8ac97789c685579f3c35c29c3e3483a0f18a049e81860d56bd239fd40303e5d0a1e48e3f0646f18045dc41e403a7c562b9d5cd6eea69852fe079ab042ea9fc8bd69696352c3128ca2612814e1f765a4ca4e69cbee7a13201f87dfc6ca6003a9241cdc97be6466f8d51878cdfef5f7ebc197001cf0efe09ab3d5b84026f1e512eec2987a25ff909f11dd1369a35eba5baaaadc352efabda52a59857a9d460319d0b40fe6f1f2806c50f92cf5384fb8b57587d944d58dda839fdbce65079648bf4bb729dd7a49658cc37065e04fa7a9d25ca0eb0bb5cdbcae2b092fc7c299451d5423c67a56091932abfaa0e7e10d9c002be33fe41b0b210e7d3f9fc91b3497acf841cffbe21216a01673a494def49f6b9e186825658a273d68a3f4d9ca2a5fa621d0454d850a6d134173dcb8d6b564d3bdf2c7450da834503dd868a74230b1b54d8fa0d585fa50a69f1a039905670c3beffc144bfb8bddf0622e7d90ebb9f1596126670a4f72e4d97d5188eae38370fbb98b8255d25e2275c030d32ccac467ee4d2410249d7ae368c17ab1ef5f6f30368ff94b961700d533dca69ffa16499d737d51857bc07dd4941e1752d3640d811e784f6c1ac5d5881a08f7357c16006afc3e75ef084c9c9f67986d469368580ed728b64c20d18f1e215e075fda1cb35bf14d2ea8e5ad896731366cec648c8602b1d259fdbcf396114911d764a86658805ea5d2921f0a95aa826fde659b5b9f6e941bb8b77458bdeaf40e090df24c92762433245f594d6890a4de3a0240dc5b2104288e368de53761e5142c37749062953b51a18a6bb3753b6b377d79384e08b746d54926506cac8bab2fbe4be7255212f7e8483920d43d78aea12c3d6c3fedd1f5102360b7cf5c92db9038ba4a35456f45685520c80d27e45b076352ff706da7ccac9fbd9be1a990b81b9c9e8cce1893eb9ef1ffee2124d5db9626589f03b6483cac1e4d1d229dbc506a88fadb6625f71f6d7f7dabe3a300c50ffeeff936a17d42eadd586ad416369b0585abb16c2f71b8fa3e14ce8a9304faa251aafb257d11f9024814f8d15f384d8d881050eee1eedf57e9ecdb1ed50eab8a27dc088c234bfb06d010d7b2ce488fec22635bd32f40545ff8990097748320946a9d4b7819642c05ee980340d98c421d00a53b0c38b85f3e0fc97cc88c00534b809ddc2cd0e1ac6bce56b2618ae9ccf7869577a8e8eb90ed7f4ede01ff3f28e087a17f5db76a87e6ce05ad0c83fd2fc2f60bfa9afefa7521d8b669cb0c4d0cbe674a8134030cbaaa1761ab3184b6ebe91177d894b3c73ef4f22c548bd6350410c22ab3d5d2bd44834c093b0048ad736342564873ed728230400f6746b6dc77defad3a4ab3f28f6869c80bc830daa763097bb5a68b88e026aff64972aa3fbc590f98d33370e144a161404d7da924f6b19b42f70013ca092896de21e77daa6bffed565bbbfc8cee1254fb967028d4cd2646ccc903ff3846d38bbcb754991b982471f8c432938591808efbfbe885322a8977a5ed448d02c261e02233819dbab7ce020c5002965527007de7b2529925e015be0035e967cfd60657d4dbd8472c5f9343ca63ca0896a67dba36b466d2f65a4607aa62372be24288eb32bc694b50dc4f4ad420c2cff850f27c5c291008ab358e0ae06c9b455ddf4dcd48aa9bdfcdedaea86501cc5f3f209750c37a248a74f5843fa339fb39bf8fd5d337dc0b5619771d04ae157b43b788924d8a4c87346c4377d3dcbb0b59269b1fbb9bfb859651e157e85b29e4bf1dea03ae05fd36f3b5ac7e2b46d9005ed57a3312dfc7069b4cad91cabd814e2afb82bf4eb58ed5e2ac2c25cf10594f7712a908070d207b3a7cd190f58306bc92874c907b7360cd925f8eff95e85cbe661cd436d326597918a9bf1460fee3c0ecef96b798feabcd7e72d41159566d88fc91cd0f49c93f1c33ae15334158a1fd03ef29bd93f90ef84a3d95d9791059ff04e1209ca3489c73f0c1ded7decc98e64dd812c1847294591c50305941382cb91d7f8f34e301e55fbdf4f398b542e4ea0e2e2f7a890abbed703281620d0592dcaca6753e78980ab10f21338c2b7ccffd724da2462c1073fc189f1fae6af7f9fb9f749f60d8f585f7fc5f74e2cc9ce1a724e6199d487143eaac40cd0d2f3cefb9f3748ec7bba6f1dabac3e4faad03f200ae1d9ef924dcef8081cdf8905e30e7f42be24ccd8118a780d731148d41b86f10623a87cf15e4db2a234245b2dd40bd12b4aa6e17a8828bcb923f8d8ae56abd65516e0a4a5e48040e6ee5ca848edfbf20ac0fba732c6a3b4ff0c3cd7faafbb36804a515db48735ddc9af4505e4f3198dd4636a895b050311756792b07f608db6d74fd5bb814e8a49c1a3117d2cbaca052e46f032fe09d2553494c9802b22e110965539a8baff54b93bcc303916808d19abe0424a29273b14148059ce0c7bc837b36e2c080d63c20065e954bff001a62b86c5f661b0fc83dbd00a249216a2e0ecfb9a98a9c6a263677eea7418698360aa974eecb10502ee098b078ed22474d7c3a4009a71d545b03ec4b55538819d126a6508de96e545854fc27e5d4ffaf6668921dab7f9ea603c03b182bd64b8af86f018e0587d4aa1ffa1eebf42e4f5c3c74ab13b4c8ea1b7a82941aebdfdf8d5128934e39993b55fdd6de9abacc9b5e078e74cca9e07efec4091ba332565afb41b7a655c9cbeeb89ba0606d41e00943a7030870c3a2867fc02740d1a875eceb35ee6c870a9fe82958a67c46b9a12d6d476f29bdd37467d65e6de79c49b48c7df41222d79a4d5767c9128935e792f30d2cb7626dc477d9fa25c6aa826d6cec88463891a8dd8e74307b298dd4b863c25741bee433e19de8e6928c6e83ff72b7d230276dd79d74d7e1199b5987170faf4a27d4263e4ebc825b727255365dfe9559d137aa1b6ca75c82482e1ccf67cd45dd8cf4b58fa604bfb2035e609d8237b45013171dc0b3ad620316048016268bf62b49a0b810045a2e820f3196b8f562b107f6b0dff19bca89fd89f965875ff08c6c2f86d806d65b8d51b10168ffaa98cc5f862cb56dde864a36646d805ca11fed931b82497038ee77739e664a433fe8ca791828fc11367ce203c703854596be703152c40135e0f945c14eada1a655749c5f61cdf08f326c50c469be98e4a14cc4669db10babb25e392f9d9adad613ee0efdbaed9da61995c230c0d4b75f8e9edece2aa14b1f23382148939f93a670cdfacf1b4148ff3ff03f565d1a7a38db2a19891c65f5c7286d2daefa78007ee07f2620cc4a679aa3105f77a107bc227c6b987b847b3bb6d8e7f0dea3a099fcec70a00fc65af610f494fe3282886268c7feab5b9411436b193193fc1edc9b0b8feb829fb39872bb4b9f93d0ef45ebb36f76ade22afbc638e28112ca743036393633651957fee9b280a1ce1c60d5a2ea2ee9428c8e042f33916afa497d8fbc5109d9574358c8a73613798009bae3130dafa0a2dc49828a9f870ffdf6815cb34117fd034389c856ffcd69d76f919b0f371b1fb288165cc608a9ccc1232c71668f1a5f43cd8dbf0eac54113226ec28d807592bc54a8fa477d58e6c591fc80cb0b0e1cc560f49aaca8f4f81fb475ba6079666a51bccb87c71681c12333fefbeee1684c38be0412eb4b9870d6c59a3a1f1e963bf461ad024eab876683f6880a8a521ed085e3e842506d11be5850e144497ee5d7e33051381275b2771d360cf6e6f597f1c7269051d1463f28671a333a5418e8822b6da03dce8b932ce09f6b265515952d1a2f424c00bbd3baa9f0cc7f8dbafd67b75cd432d667033569f2c1d24fd26d8537619a5c4a18f0da0b5d91d353e44085cace1367fc78f6d0b85d6a69e61f60293f94775d544e9832b77619f08c104606abd32b26dd3bf1b02adc0cce117b9bff0eb9de1136adfcbf84dcfdedc1f685b63d45f31999e00742d47dd2b30edb312318c11e2ad0b92beb2dfaecf9b0f86a189788fe34b208d874579b6339a800e3ceb3cbd40e509ae5b12701984f9a59a5d64a4d67f14a9f6b640640c8d4a2836d3a0584e5743a07a482d008bdd761ffc3d5817afd8ede6a0c30eab56803a1ea002976253500407204f06b4e70bac88b958cf933ec048f496757b5bf2ac9e78535a01a4b286e977f5fc25811e122cf2dafaf611b3ae56a7eb549e8c05a77bb374a3986c16db412f5939f46857e14927014f620c3be98058b9f0e56bad9a741ccd143f7b344b454f05cc534b4be23a638f33c2404f3b3c0698e72fb193a0787822e69d6cd0b56d8e3780c2e42c9692b311c47d23215d71f95c1913f244ccb11d34ac69d2592eca1481e838bebe9b873ac8c15bef26c9673bfa4319be356334601ad69fa69775dda99330e38f51a0c28e73b60d3635cb32de90578ee0ddb37aec2207367ca6d91138087691a340fc4918325bc28b29635a2c0d5e5388afda4aaee4aaee7da7489aac7d12630dac18dc71ea697b5b443344d6f7aad9c8a039ae244aeb4cdcfa73ff5f133933851c159a19ac76ad4abff8fb7d588688cdc97e6753e18d17451f50c5777c4ae073ba2bf79162c318a83ca99cb1c23be3cfc58a07f47232489c06f0b205d5318572a9e8d68a0d7796abeb5e2b8ae59ad00ea1c4ec030c3ed928a342e1d213b668ca4bab545b5b49e9a893d645d0a289513f2f96189ab528a5afbded4de998dbe53c8f7f853fcecf45e910bd3b6241c37b3c02d05b68a4d7b9afe7aa6ff3edab969baa14085aae8a920d661da6ceefe38ff6d1479bcbbded3bebf5856989caec88b125692d84160028e592d5961e96abdf57ed2d78c5c143aad13a0aa032f2f9cc74accea45690482044a3d0a8ce16e42124ad8eed95285d1b6af460c4c5204b07df1dc79fc9e65ea5e3009f5ebb26019c11d127b380534ab50a035647dc19ca70a70284db077796dee450570977b223b0118c4b962f40c22f819d0b5cbb7434252aa7b28f0d54da5b1182c0d97d6b8e211c1672ab2444420643d19eeef35351f408ff34d5c0f18ba89c01fcf26fb57963c4fa70168d88a687ae41e4db5d4fe548046184cc2a1f1c0814b02032ca5e522e9c0b2b1e339453b6b83578b8dd15434ba6c8823d805641874bbbcf857d922abaf85a6219c4f207218e369a56270cc205974890e435075dbf68ee36c464232b8d2bd07aa23cd9cf3f791bdec75c28fdd3728f17d346dfb478908d67515772c9c885bb51142c9b697164d764a8b31cc2b180623ae3f3a506d1417aa14943750449a8c8bbb13b9af5629e772a0273e4cac737cbf2a5e1458e437a07d1c54920d470d63e00ae6f1d0f1c2d8d4cb18ef12fa0a35c9aa940eb525bbf7281fed42e9137cd43beaaaecda197c88442fabc93e5497d14d5b1590b4370e310e2d666974fb94c684ed07873d572639a48a1968daa6f6ad7824de26e555c2d1bee1d75cf4e9192f5dd6da38397545814081704e8b452d52a57b99b63721f37346144005ef2aebf00a3b347248e02b7c7e5c368afad75826ccadda52054a68e8ae882f94e1330f50b98096342aabc0d276e4a8edf523f7cf269a3226ffbee48ba9491f361c658693c6ca9d3086cd98cea6abe027a011fbd7612d795b28531bf874f74e035c6b71713cec8ebb2dabb3a4fcd3e5abf0fe32c8c7270e7c0c51358f3c1fb8dd377cc2d9e970e9fbfe89361593450089f62e406b116ac88cf815cd1393d8a894f899f9cebcbab3afaf38b9486617ad97ceaa77aad6e8234b6a295b8f67cc0754374b2b1c17f6042c4cfcd27c4e47d70b9625c2713f1f140d673bc93eb878262a148db4510b180fe994cc6ef3702da9403d3afa29eee51e7121d39354f6b95f38e913aa1e7541e0c294781b1d6678ad054b06de4c16a0813b43487b0b3e0360926065c552339ac2436fd834fd90efcf2b3ea30128733c32a03263186b827c0ac155f0b35a107cc5a9457418133f7802b21e51ac376c31a93f9d9f461f629cdfbb1b5409b73567fbd3a3e4908f0aa0811867ee922e813ed5a063b19138a9c8ea203cb229b27295e143925877899e9db99aff7f61eead1f68496b53d51adb29a3109e46d523907faf778ef3891a27a4c7ce7d23f32cdc77b32567591cffd74521b36e926ff2e2d3d802fa5eb9209ed8978f6f8e84c479879217fb14ac95e290e4c405166e9e6ce368ea79e68ca7a68d58565dc06ab8a43905fde3d2610605899481cc1ab662a202148ac591c117d732aac6689f71f36f07a6c6e53fb41797a8788f7fa43c7109a41d96b68deda7f999088eafb0e3f60b25ae6dce8b985a065ca2db71864eca1d95e6bb947771b8bfb9c821fc1cc0358c0d6f078830430747037a0a4b58c5dcf98c5cfcce0b964ec1ecda65b87230f8277e7b4d71d0162e0032602f6da0aff663e5cf72c0e46645099e6741523b0c8fad3e6d9ed04b49d29be092285f5ecc6bc9015b25522c2f942b6254d4d91920daf6631b797993d03095958223f6d95c121fae61bf88f055e6a7408a012efd7c731c0c2831e7ba6ca4e952a7780ddf05234477037e288881f1ea149c9d097d930879b325fcecd97cef85b8521bcf432672906ce58bd41d045a8529d99b8e5b772d5c38664422b706c003b9d8e978ca01aec69a9bfac44967a23cf3c45d9a154fd3980f00e1a6738b1ff4eaa524f300377fc30e73a4d8a3e17bcf6f5453d002e8391d13050b44305d520bcf7cb7a2f1d8f7ef2084104bf02271a3c4f35c8c56197edb85a61d00932595f2f80952242665b5a4b0a674949169a8cfbd553433ec8b84c87774cda7e5ce1a7e73de34cd772841e765680593b3ce25ff44bd96dca9cac29d8f4ad0bd667e4651d0b4da90ad53766d47248a0e2c551187a4e0baf8a5166eb4237ab01f4bd622c6a6710fda808445a1d73ac4e4e87b2a92a7028b82fa6177722f6a4dbf704ffe3b422cb4e90c25eae43060b639b2980b2d0cb0afa84a010cab80da34874089b51d44f84e78f8edfd7107517b80dd41f04dd81287773ed45feb1540d2e57228b640676b74636bad47c3a9ace751bbc437874a258b4368c8750701d987006b71544f38795bb55499458eb33b23597ad8ec114092cb167378288584b4047a833e1df168560e7bd0bced35be5a69fc9ca508edd26efd390993524a6e8013d435b99ed56c3213c2dc217268557b69182aa571df04ea9d1f1cbc6dd446c2f27ecba2e42f601aa2433901f4d18bc140495a2182d6b0f4acda769cf7f02f3c5e3e2b05026701f620eb0b594dfb4f941e68c3039693843b3e25e2536bd012b1bae142bdf9a839f6cd6df0b3ef8e3787d420155557def6889a0842ba3c8de26a205f74f9cfc7cb69f21bf48a00628b55e1dc90ddd597a96168ceaecf170103a0c9ffa8b41d5fe04f34479746f492b2bc59aff50371181d0685858a141d560c7b73561396eef8b5a84d12a1e8c01ed84d81932d5668232f31683db3c9810516650dccb10f61aa8064901cfb4d71e700aa884b28a9c3aa85f4892f5be2c2a6983cf86573f07c4464c798a0fb176c94a72c12a6e3a1da2760d2bef5751dec3ebaf7a187195725bd98137a974865f60bd37dca69a3c415508a4d031492c8af0d38a5dcdea2d53d0adcd4e531e0cc7304a5b817e993f8ed1af22435c7220f407d6c07dffab085dec9fcc1031089a9cecf8b81a633860cc40fb5e57908b7e95fb86518452a6ad52cb1913cd0f0684ef8087dc5b28956e6d8678ec144a7ff27a2f89cbac95456ffc7952cc476311c8a7386215aa9c2a00b8017ab8019686ef1199658c2043a77d9e8306699d808089a7e559fdfd774e69f5252f92a25eeb589eb5a776bcd570a9da75ff6821d3af23e7cd00d11ec1cd2aaadc01533ce90f1b9edfc7a117d3b3de69bad67f897ef629ef4949b5657fabebfaf5960cf8e8911451b2249b7721cd082a62d4ac4052d4314d97579b79f7b7c620ee8e9a761e63037ffed606b7409abb81f5dc54a0bd3d4a7bba9e75f9fa6cfb44e13b29a72c81bbb792fa8cf025f989ea847c94a3486bfd39893d34ad6557a8557db49dbfb52b4ac797dd45d7ff297bdbea8e7f4f128c186cdac8d5f7cc91969e0cf4be6468f76dacd611d6ec69e082c1f363a85556aef586f4272a57642fe6d68287729509e56a20f5e05da529228ca40eb2cd2e3a21e210ff4ae7eea4ebfb84be4e71f2f2d82f2cda8273b0ccff732b57f6ce486c8ada3918c2b2d257f6a2ef306669ee92d8620845dacc5eeb480a97b004cbf687da4744a448b821f102d854b342aeeacad9f53cc7e4b1f849adf2c22f81616e6567097eda3212b95f6f2862002c0695e092d47db57515f1370c63f4e8590e0b4a19f82f23f29379b06dff24c9b06ec524e97d0efd4812c2dc3a92e848e6e60d9f295bfbd73b5206286d937783807d0def12e8cdfccb44a173423f312b29e4aacc08d4ce3191806cf29f44c56b45ec0c9cf4e2ff6f40368db3372586eda91a0f388774892912b68309fd91cb7a71645e236ba01233c4610d8650543e46a0c08a57e07fb4d0271f427f1d3fcdd34f1c35dc71ae60d1f360f0c081c5dc69d8cfa77c92e6c2085b3babbefa4b90d661ee9ce316ad42098fa2595b44093351866ea2b05ee5c43ed5820e2398c7f6f9bdf1b9a33cd9503584362285ec2ef3d629bec2ec68e51a99733b6da759aee50e751725689adea4cf1d0a048df97ae847e7b7a797e03eb5492190ee94aad8d3caf912ff4422e72347f62e8a9e61a8eb50ae3719532b918a0a7f9caca0460e2ca6fa7f54dd36d52ab02d21e5ee081de184080ec4f7c52ff28312e840764bc2cf15806b0632e325266952351590c014d3d942221e23db88d788e75842a279cc794adf39df3b7a202955e799f1614d1b2d8445f57d8de53a108a7679f90d3a32200fd8f0ae0b2def41eccc4ed7a1ac75a96369c9dcfba34ddcc60a46fd3839ce0a95e1c630cadbfd574e4cb47f9384743f86a96fba4a798c34b9c5b669cd56d609218864093ac06e2f2a1400c0c0c32a97947f460882a75e863c6c6c0a22971010ff023b90a655a770f24c9f170952a613a7a5a0a04549543629cc687f8a75467bc80803075b757a76c32bbc454a293a9cd393f2ef394cd0f94203cd639182d0645069b418c9c09373099631d4eb4624885dfc4077d68076078cadd48652b8248a8c27ab2ee90f446f5bd1af6619ea70edf5d0289ab39e29091cf25f48815a8b5dec2e71b2a9c9ee3ef136fbcdcfbdbba602cb8146597ed940a904f5a0d7e485bb374754d7ce8515e949a15304d09d6c3038f35839f6271839985fc462bfe776478307b5525a4c45e4dbf3a049b81380bc14e9c0a019d6ac2c91b33f2f9a5294d35f991da19efd9546fb3aaf5a0c289e4ce711ceb96ebc3d131b4afb9b7a2beb8ec13f1c96845f5730db75f02a0119c222cadb4ea41557e1210d1fd4d16100054717bdecb0f1fda006c6c90a17554633b4316929a20e079d344749b0a26095eeb84a293d3441228436a13ca655b470601065caa44977e926adb270da146bdc92407364de277070b070f5f50f11ca4e12ff479ab540b3650a95579951335b9fb3c409d44eb409a2d6c659a38d1054190c52e0cb10feac4f9fbe41c332844f3d61ec5a662acc051036988763d71b9e223fbc5a1df1319182b8935299cf53e97be074194091331340bd90f7b98a957b213d731d0649a09c11150d882870706bf0c447c167c71360745755990c7339a7960d735d6369a6db0de157df5fe2019bb43e076cc5285caf2b02810408d205692701304674d0eebce835302e0563d5bd5f9978e9e794b585f708aef2bdf8dd2f3f8d911246f4249c9a14b24e0355551a60e04d74c91589dba72de2b4aa9ad0d409411617db9985e1f504569885fd7307948ef7f51fa4689ea3bbfc8d6d7cdf1ce0e08aceb5a28bc69fc5cffb85f8451ebecd379b113ff6866c6ef77c3b97c2bda6652d07904095b0baa1453b7f41383b07b92c22b7ba194d5efcc3097ba47f388cb51c58feff61a485f6a83ca99d3a4d3ed854fb01ec84a5bda15b5bd7059ec0252a8a5c1a4499df7785ab296ea2e2caaa0259055cdbfdffb607e0b9fc9ffe6033cac71410734b659dccb0966536dab7554d131b19a0d4656020266f554c8571d305b5187beac947f16af4cbbb44348b82cf433d4f3b41795e400119ff5172c27fa5e6552e6dd30a54bbeca7c93f47f0527d219896df772f1cc0026e20b5ecff3b2de49700da8a0bb4224ab9058c1585bb219632e55bbe099ac05389c7b855a84203ad7261c60b82aa8169e1d6ac15cb25ab4268e88b96159c9f53afe2f47d56a16dfd4f7b9a1121d8306ad7dcfe25fe0371856dd225c5f8b58bd9d38913b688b79ff3f120401cefe66d21004dfc98fcb197e84e69c2b38a82d6a4ed051b767e701d31ebb7b66ae5cdbf7836b6e7fbd10650a4881776402244a4395693170820e20228d5f9775fdd3873ce7fc002b7ab838c8f3f364b9c2021df114017691fe895bd336d4b7d68b37bb00371224ba206f2d4924b0900a3d65cd049eef9a9dc45aaa938e0f64a102d535f9c6a2c29299e86920d2ee9bb454cf084115589aa20b7e580fb288de84b60550dd3939da5695c9f393ddc54d3667661127a58729adf68381bb8a40c1fae7a194635e9be39c9e9df712d979c9c3d0eafc1c3b525092a16fab21b0eb75928123464e00851476264a89897a029d1077de3f39f6f9d8d1b4aa0246dc598fdd45c861d1ab4dabf22083bf8aab844c0232eb0020a1234160dc6a3ccb285ee8b8435dc8ae9e94176a94119226a111f17e9833d6b3bd697d398431fb0cde5022a2974f17f9b384ae6a5d02e22055c384251d8bb55d61e9e26a8f1aca5e092f0404b3c74a4f40027a48495637c1c113dcd0542c8716e5f8d06b2ef38372b9098aedc55d382f449613be2fabd10ec1c34c44b4050de1c265af460bd7319631dca0c0deeaf0cd8e1ee91deebe88ff09b60a437895d789d580a8399cb4cc8a081e3d836a1bde3735e8f1e417db1160b1dc2571dd264f5fe46e77b913e82a90fb80661364182520bcbff2bbf00f7f38799f6228a48a31f8bc6a431e07f40adc616a0e3d1975bb6deebaa560e5f44d89378588ead1f726bf403812a143d0d9a9ce58a8b22ed1be57cf56fb3fab11db9d16efccc0a6c24c01f57ff7e17bbc4df7d051c1f7567d2d3700f685326feeb3138ada41e3debe58d3344a134e3f5a6953ebb32a87942e33b689aa86cb86ddf1ae784b0c405c621fbe37420eaa8f9acbc7aa032c9c3c43097876a0d5dfb523e2422a25bd2cd5801f7eb192d77f589046605a549849cd8d7f2ca4b3be16860d317ebaed97c54b822d4394c37d6777f42f88bfca93d34a95eea4d06c4c966824d43a2ffc74ff4e4042089991f4744554c026e93237f8e82472b62ae7de720e4ffbf017b7155bfd38b1eef2b3126df50fd0aa30139d24bb66a7f98b9a13dae403b7bf86694c2fd037690cfdb803266fa267c7add2950a9bbef00ba0968c96b1fcad1ad7aad31675725107102740f8c0e4e7c20def20ee14042006cb6ab5e2773d5c0c41585712777a0cf460139b1cb3776fbef0d256f671fb3d9621fcb0bfd952da8c065e78ba8ef02b2effca13bfca47b7d59757eceb0cde99c2fa6b2fe25e0f1dac97788f4935951f24d7bdacb1c35e186517e2eb53636eabe19dd2e0c28ca786f545699e0e1f7bfef01c4d7fda121d2d2b3a2c0ab53ea8379f7d56a110cb3fc7422b38102051083860460acb290868b73ae5dd6d2bb0dd40972405a69d6e12ae914423931523727ed7b80a59d0151a97d6bb8c1606bc996d55f85e3c6d420f32bb5018719f2de79926d5ac1e6e5bad2151065e78b79f019294fb9ffc5d0e0a969ecc359013860b28d7c82d66fdfdbff3c596bad9d7925ae6c134ddc6523226c93a7c7c04c5b532d1453921b83875db21b50e1389529d9017a5677d80afd35474a6fb43e6f8574c96af92a62a02402786348bdc99bee2611bfa72605fd943e9a5d190d9816eba95ae39b3014165b468e24ee2cf7a64f10682093bf80724d7c89e9e032df096b29b314257643bee3fc16b1bdafedc3954b6470b9a9bf78920f086dba2dbb7ba0fdf36def4c6c661010fe69c0d4b3dea39697a2d235adfd7766c98c575cd35e4c3d2835443c568e92e2e41d17a7ba894a3d7cf3fa151dd1bd315e4009573b3dc88df60d12f0dd242bc5f808c0ed98b61ab090ffb4756b1fd5e4050b2a8f4ff544dc58c482630d06d41d37dfca3ea623ae7648fc9bf12b2fc515a7dd6d6c1cdfb89e4dff567d1dde92117310897479b460754c6e10c8d6cb4263ab7525e8d61faf2bbae03f7de742e76ed07e66678c242ada085e8321c6c6e39e6f5be2c37a54f449afd47cfe61ba131061e558c35c1981cd69b602663a835a8a50ab7c96b72e8fcd1888aced770bb9b7806b5e1cb64a4ee778d9f9d406aeb9f857b5b6365637b89c44e4bf51d4621947819f9cc8918f2bb821522b4ee239fd7b6ca76050305b28499415a997ae550e840672a4c423613e21c028606da059c75e23c95ebd8d0bde0926b4ab5e8bed57634401bdc9823f480017a54580876f7fb6ed58dd24dd7ca7494c01a9143de1ad6e644674905869cd7488bc28f7f7025feb2a42c02a331c9bdad0f25c7902a0225324b996c47138f7e2a4bc9ef8785202e6d1d0062afa9384ddda16295baaa6c841dbc18bdac15292c709db5bc566d7edfb671d9af6dcdb6dee1907377e4511c5e20c352a19999d04128065c45c2eaac909afa12a1f67b462e363fe1b804cff5d00076ccc3fffd33fc5f340819176c5759e748c717f64fc52638f10681ec285fed13d0ddb23d9b069814d2ff713660e588e6d5ea8b41014d179e81c1475dca0021482d1fc5afd9befeb007a9604be53b284b7ea157ae9d428be2a78c5d9945a047be4b92b8826ac9807f284684bda545209055cbd1fe0f88545771bbacd69e6bcc4d6b813575b15174bad32d676c80d34713204fe06b0066004a414345f88bb6f1d1dac3d9e7028d060ce7765be9388a966a9a1b996b93bb8081ab629553852e1e14ff611ae4e9b4c25b02e9c6b2ad823160f5f73c257330e7cc10b34ce3dc53c5d355632e55bdd1e81959f726cb225b61736555e059cd6b192164e9403ae277410ee5954b38e825bec398ca2cad6a9553b0237e1f25cc03ff7143db1ac64a320fdc9ab4323cc93a49fd2f79c23fc5b9e1dcf98255fd18728812b8428551baae5b96b322c8555db40361c2187b3354efe35996fb45e29ec91f6522c81b5ca4a637fd717e88aa66325c51fa33fcd7216045a1e3a997233d60e0eeae555642731d95e203fbcd22b7644cc49252b8d4f8a588c13cd8a2d1889196ab96b97eb2c9376540fa936a965d9c591a3d87309e59507fdc0607759a94be9cd2dcea2792fd18f9a73b737e93eeaeda4322277ed8b07253b228b7ec857c93c1d0e8fd002fa51a978a6d80b3fbc44da125322da9cc10af5ac4cf01c00a77d476b94498c163bb4b9c37141bf6f15e4839d106f3fee4c204b234d787d53cb6e264f428a41bd21bf228388e6a9061ca3df217754848e2889cf03c4641af379b0680a312a56f8c1c2cde43cc22f7cd0ca0f1a21b01ca73d525ec6b64d806b919f96d7b9244f89de500532f6f19c2b4268cf06355acd210e516bee43007394f4a7d50b8fda591fa2837086fee765079b4889cc9525847dcf8ae10790e7bf76f2794ea8bd0e7349b47e69afd02a46c940d0e686020480526d828225f17a4ab4810cfb8259978968d0fc77450f025ef864ba8910fcbd6e57010009e384c44e6a008429bfe55808a7eb1d533aba44e829681e97ebb3677ce42d81183b3e1e8f449c2da1a3d63ad74856f42786bf29f3194b92a2ab56f99f830abd788de15927e630821d2bfdf950a219252cffdd4d63878313779fc8c5bda8d36b0257ac7a73ec4d07650163bd61a0fd6b560a2af5f40cf9b831612c348ac23487d03609cd02f068a573910308734a811b8347e899959a81b56b83f9ded77b24a657d526832b252911718fc4dffebbbd7ed9db85a9a6b555220ce35470a3ebf5d34bfa999a3ff7317913e7c5d7734d931b28b358a9eae679bc084f5142426da75cf5c0cbd7f3a46362b8b8ea385cd10b2b915de2f5b382c3849355a17ec4d2b5c5af38565502d8802aa886279915bc19211cc51f3e67140c61ca97bbb27041b49355ca7c0c13d50ef232f666578d1430a467f81d5d33f83c8af845889d9547184e88ec575dd572377052c4b666ceda4ad82f69526b99020bf9c73be24c8fc7f31dbf6c309c3a840367c0336688ec9cd802baa88cf2261c6e373a4657a4160987b31cd22c547a235fab325f6737f24efad1c3b514c61806f30951f3e3fead506908574aaa0da4b3721093a66d87c1e539c52fa4f764c0d7db40d71b77e0b28b6bac488ccd936c82088a83865c71b975bd66d89073243334d1731079fe6c9cc26dac8928dfc5034b8ece5424f39670c0617a253555ea61739ad238e0765ac0f0e8a487f5aea5470afcad91b89f02770b195e4115d86583805ae119fa50326dbbe0c29698d948fef38b648f6016d6180ce22d85234a7f388d7a7291031a3fbf7183801d52fa1867064bd84763344ca01771bc99ec1492f774be359da2a51de95cb2821aeba8edd342c06beca3cf5c00b448f95deea16928ae7fcec9d4c6de7dd6978cb0a96a98e27492160d49c68364ee2a8c23269ac81c835ae7a4b3928ee50131331a501c1e6bd21ec8bf67dc02652909023f4e89a12db466050150b569e7609d20129d7322d8d03f6ab1f5e4e78f1049f20ad9f83d789c2ef75ba4801cdb13811ecf3d7c958da6c43f01b302f2fee4f524341cd48ca4c229f9a64019397fc4b7c96ea636af3385b985aa760444e1f881ef0fd4671edd538c42fa4e598fdd30277943677798c66680664619e8a7409d5f6a9a5ea30b20eee7011437063a3a6873cc22dfa8c5c50c8139f0147d805192cc83ccabd9b11f31fef820c270eeee9d14cbbe35aa9ef55887767f4ab0b7c82e3307917cb594f05149979ed289acedd2b01e9aa10ddb503c1cb5465562418099402763c6de2798c5828a523826b13713e014471ae9245c72fe40deec0a0e9c031afc947363de3d872962423c42a915923539dda4cc99370b1af066752a24379df8444c1eab5842c5687b93ab1bb687f8f31b2b7ad24cf9ae0959915036c8b3a25446c575ba384714c1481cefca4e1f79d1fe274bbeb46bbc904529acc19182de472ae5263d0fa20589ac4777b775a4a8bd37b03b2dfdfbd4cc87eb03921fdcabaf54c53c4a672e6b63cf4d711b1b8173a348b4aa118c53749bfd8a207752bfe353b7c1d59434c39f08ef473235c1d50389965b757237558bc823e910903f758fdbc6fed08d5d3f1788cbd272dbb172715c0a332c0a3b0ff1b6094e1d15462bf0293709f7fdc5cf21e16980027d285e63a1de9842a07c0811d19248920ffc6a66a0675513686526b645972d71235e1611d92355d00911e28450a5e2e519cd7e0960b5236cbc65615b8367409b26565714ab4bcda6c9230e1b7d93f37812d2160f114aea3038fc3bb37a6b2f21d1da5a5ffe11531c414ab1aae17c07f2395f4eaa12726e4d24090b5ea8d5bfc17cd7921d29071f8e86770c13b9d21aac447505c9102a675f9736dc9104268776589919aac2ad2c516ec2bbc029107940eb6cde51c654d0fa21d7d41052c182e966b46cb2fe00988d03e8b0043f2a22d2edd0c894300e8a5638c85dddd90db317187a2c21424f3c796a1d6ae0f6b9ef5576af0ed5663c5f32cb8784403dc5e042948ef870dfe81470b0d9eebd2ba6e1e67f2740fbd7cdff84eda151d09110f1821026b6d09727e8ee9e5e87e645a0dee9f056fd0082372ae83c914f57fef820067935150ec28802f43513880ff008f589d015e0fcad58227996a99347b4aca2cd0b8bba4bf7dcf1a8ec394ae99fbc661477de6c7a9fb133e3d7899454d3d7877a6d6086e6b5b1f3c7ebdc0cefa0b9215dfe1af6056171d1075b04147912c77be618efce9404696fa6181e0181f88582e0e979986591fcde6723e1fbc20d213a18e6286e429213220c1a64fa451f545510b31f5b38c5bc4d4f8bf578b95ef1e7db2e5d8a1aa780a2db988a3550e8dd0fee2b51121469a4006badf8a7ec465bb564e8a05de8d656903dea4d321b61277f288d846af9efcf6c3c76140e4591eefc934aa1b48a89e69e959440eb32e88bedc03293cc92e9dd5f4af491c5367a7bd57c56b26faf81b51a999ecb5d76eda16dbdaf2506101687191af888bd91291052e5aa7dd328c1d41e6a3d463079455a916598e09de0f71b89991de0a80d130e7e034738f9537a49f7c5074cebd5e74237082675cf68a6c5a0876d234dcab4202a8e108b82aa28e3ae14fd0a3f880b9643cbb07ae504da7acc246aa54ea442137b9a8a58107fe688c94f12509816093873d697879abaeadf88803873d044bc7d22f0dca59c460a9e70fda88a9482a1c9dd4a8212e1e2940d19217ee65b5f7f99d71147675eb8e9a12bb14dc4d4483b9c87f3e2f47b4c989e89f00b6688de97911204b05d86cd211f09230ae7f0447ad737381fa44d6bec3329a1f95c9bc713e610456d2a7e9ace49a2a1ea35efc1f7ae1314eb5f12ad1d6449994da29f07bf95d86c907f0a71e0aa0633b2218a856c459c478379aabcf900e257a5e00c26b80a320669223863a7a9882a2cb7f555edcb9436159e905c7b95c3311f695bdec1c14c6571e0619d4ccb2a91a1bb436fcd60369b1a15b5b46f7b18930e67feb904e8d393a6fef2fc555dbcb205ae39c07b655191730e939f9d540cab8e1cee72654c1de093d8c7a3da5e69de6fbd7598d9ae70b8924b5b04fa01f24c0bf2cb70fd35191017d41fe907e5446e817dc6dd91e05bcabb0b4c0197272fa0afb120b5b1e139a456c19615fed77ec91e36a8dccd014f581c2068c18d22705471fffb7859c8d29095afd40895d6c0ea1605532db814533d0a9c4d1cce454babf0fae4152b4d50d1c351673bce95c8bacd9c411d597fc21699f3386ef94e8d949cf2dbb69a54d06ac89859fc2019e59ff264b4e17f6ca410a10345b25f4099261295aa1ea5099aed44a485b9587c20466ea4037f6e56db3e4983320cc6a4ffaf3fc13fdcfcc55712645cef0834c77524d2164287c9916b23f1438ae6a93d11887c0cd64d5a675355693fbaec490b79555f10922c786264b030daaa0ff0a7f6f396f38ab34de6944846016d6f3a4f6d05dc1a216e36a3785e2680d50f50b108765d461004ec113284578c4144904db45e999c9b1a13f3ced2fb4d412fc1284f40d4e7be206a6764c31f94dd106922cfa07a421babe2f514b0a96195b2f0e44b62028ef114498aa74ec08d62bc01ae226e896922c0986e82e04bc821a6a39e7cfdc1c0cafeed2896e0058f7204dd4e9f52daac0b39258c6f284f551d4da346f402f74f2133e79d2f3a0f8131bb9f80825cce900070d73bbf15a9225e1ad8b4ca82480be9b1993100d34ed8576d193be3fcfc520032f3f9005a9cb63a12776970d50ffa48fa8ffbba0e39d3b2e5052875fdcf9c0b33d6664003e12f9a804cd59185057591ee91a428bb74445328569cd73e0ee516092d6a2e6a92d6892b5ef496ac76b2b9aaa66c37bf2b0522bbd6e5fdc7c014d0afc85df48743469e5d38b1583100237f5d2efce1c26b027c68f98a9930b66306f5febb17b7dacc1b254c977df2913aaf54b268d94b6c264aa69b45b5d0cbc9eab0853f7c45115206a317b430fcf52b7f0117b2f82a1fc24d308dd34b3e1602f2f18a81b5d44d87de42570904bb2e53c3db6e925c2872fe3c6f7db0f7146e60085508e7dbb10ed74bfcf340933bfe203513942f8e3f1a0c8db0171c7f5a2e2129e94fb55695457fb1e401f2b45ae25ef267102ffeb868fe81d49c145e6d572f87f1cef894a60fff6a1f10e448c6f3b29eb2a9e93c1acee48ff4c0a334830d038605ea4df5c6208150dd72e9109076d1b4b43060a2f471a361901395b926a1a00c61a18f544a6a621d33fbc1b692b3d2a4185793bc7b2ffea5f4a7423d377662eb7b58633486dcbdc0546c5e1d2f664391de59cb413ffae420069c4fdfa73ad924a6d22a20991532c1bc2c4a33a362422cb0a59cf6ab4e3eb1c575eafe689229c47645697e9a8f1b967fec08baf1b9a676c368b6c2c0f7b21d2e21e33c20b69ae1c52a1226216cec41138c513296a366caea6931278aa4b3fab2812fcafc0185b6cfe0fb7d671ff5eeb182801bc7acca5d0420bb182b0a21670d42d2e4de16cfe94dbc071d67b365d8792c85532becf6c773b72929c5dd6bb9168e6fb91b050d10a7393c8a35dd6bd98fc3793673c3e520ee98e29d038f3537cfe696694cdd1baf92f31ca7fac40aec3ec3cc77860a1e21f603b154c19afec0ccf20c61dc0dadc4ebacf16c2842b08b3806bd2fd409269d0c11f5f6bbf169648a94907f960125ee1038cb308e9561ba9756207e4edca298c0cbf9d5900d1c06c3184c79106c115b0c07411821d82b1fef15532138face1e70461aefbdfa07b448c3f655d48a1c0032399ba6cce3e41413861a96b1d9083a1857d6c973dda4d2e1af9037c0e1c6d70550bc0c030f30caa5f1710101969a26634761ecc59e447129965f92b7351d56a1ca957d43357423500d8a2d1fb4889af8de60fd294368101fae2d073049f141c607180fa13d428a4156a230632025264f800680da6237aa20b2c9c01d4b56ce335cb20a3bc822d3ecd0e8bd1aeb0028ad6defa59d9ade4bb35ecc05c6f790d67b79cd5f19a28ee4a91daeb820bbaa2fdfdf2d1f4c5bfe9da1bfadd864098abf095326d039b0894686c920e8f9043682d3cb2bce4546dbe15d4691686044cf56b597726ff4ecaca4ba6314118c43628646489c28ef835aaf468cff8abd0b901860fe1985f389a00fb497411d222d378c77bbc078b4791aa0713050fab7d3ccd81342ca6a0df247c17d58d23cf28ae8159304eb869371aa050d812e6960736048b83ec07a914d7718cf278b7c068a66d0129e263059f4b328966f539a81dd0135c423ae7cdf0b7ba1d938bf28a30633a19cf9cf78e746a1dd9cef4cb1ca9a1d3727c4c8e10376aadde6b89b1691cfbf08df1836a4bdd3ffdb0f37f9e43e784005261118722c58bc27da509db205871d2ce4ebcfc85b4e65c09b0c0fe85a4b6a44efc042b479b4b35e36154bc2260063b20683bb1650eeddbccc16ad504e60bad5d9c92d4edc8fa0fd8ec97d88872ff05a095c98e3c1b09e56032bc70ce03c9d43d4029721aebb8ebe7e3709a444df7354e245250ac15947eaa6e4a37497a3557c28d17b8055649fa0e697ce362d7c25b77c555823cfd752d1fc7d7e00b28be2b8180db588934981cb2b38a24868c935f20cc9a756c99812741386c128e90838ad450a4fad607fd8f20247f948d27d7a4aeb1a14a846d5a71c58c3de65bb1c742028a11a625266681239435e5343912ab0fb0bc681004a2dff0484b5e12fafab0ba1f232e792d80cf547212ee73a26507baf6428ddaf965739c659509e6bb5033deaa5215619d859abedb1e5f950f3f175f459f89966e4932af25991428984d65a019cd5804e6a5fc78eee5d1b3642c02720f5e63f5cbf862199470cbd337b184745f0952b897ffa2a13aebca9670346101aef83208a9dc78507e1e384f819942c2b52d9b666fffa0cd9fe3932d9321a8212d13a477d15a8f626506f389581dec688f253241152e3419b6addc8b71e740b88d16efd5110d49c6d3e10137fd29ac09fcc9c4bcfaad4d21d3eb79b627783e0974b60c6b596155c23dd0ec5f8f460b3aca2cd0a06f1a55d35c8de17283109662a95519ccaa8025dafe66cc8c7f49b8fee8cecf0b391ef5e3479cd78475864e20b4404a4391fad20964ff3d1ea8d71ba54088eae9a8d8fd039af57b822babb57aada52d1082742cdb4737631bb1ca82a9b94a7a178000fc69993bc5986c261cc8e807e959c0c7eab83aa40fdfc5fbefae0d88e548c3ef2865c85da3c66215fae3505b7d2687d41d8508b6abc427405a6c07048b35b5a9ca84b6b6e517eb69b0771afef1799869228bf5cdb9282baf4a360578696c1ee346fc6c0c2ae81670813370ae7799e8c9d49ace6f16324048c744cba0b7c9c464f41a79c6b4a24b7dcbadd149890faa1c5873a04f41a808835851d4793eebdb063089a6bf4e199f513d09c9df6c0794f6b1b21e766d3901b3d20e479bbad39813560f46d04d02815d4878f223558df0d5424bb24c3d53a0734d9422c43b9b8376d8a034c2d4fadfd40923106d2a5c36830ddd8a0ab1fef23b2395661a819c6e7516de828b65a4fa35c44dc4effdcf2ce1b9a0a51ffc0fba4fac38df64340249f3f1143c043434adda06b2d28b7ab7caae591e1627e15dd1146ad823443e26dba753aca6a337db493a2ed4213897844af4c32fcbe43eecab0e48c30f8112ef40e3fc6ce02f4449b19e00965425901b3f37b7fb86379e5696adebdeb281500cbd6d9a2b829199fd1a122811e2debc7db72e6f1daa78436d3f835b8354abc6b61b071ac8855c931e81e294a776000c92ab2b33d444f2e4eb73cc4b3a66529b6dec7330e3b21595c731effee27f52554321aeb655c425955a73bcc8d8bfa1d07fd4c8fefef4282ddd0a31143fd3e585fc2e236413cd0d1348c1990b3434e7701b5cc7dcab996641a61e7792e1aa06d20d7bbdc80f56c5793375425e3883886a3b03adccc30a9ec3e790d39c51b546852df7e574bf6246743061920a58cdd236cd66e9692c1b6b7a75365f9941a595c82e7caf1723f4230ea5a9fc68fb2a3b363b3959dca91e5b6ccbe7acc5a903d59fa8315992ef1950e8a30eef7e6f2a25c686dc4da30cf594d6e0df93a7268cc6aa0c8b72891def188323ca19c49ccd4127012ec13f4b7609bfd058481f10a80783b8adf0672a70e88270ce4ac15fe4f5ef1ca21c3620a21ac3c6b182094f3a0cf0589cfceea8d7a0bd686efb16d447f02f0b0d03f410d80b8c804223a2ca8898e71be342ecb150bd192f94291cea2094b8ea94aae3d09df2caa02c1bbe0f45133a92f56d0c76fd3e4121f208a96f224d7881c8fb35f3eb1cad5c7d3c7090a36b67bba9e1e45ff6a8a931408ea5c3c3e03bb10e2c7edae30736d32f0e61c9a707c448cb001e3cf7348cf365d75ea11143d7ae2383b743bd5cd928a15eacc77ec1d38865d9911e051361185b29634648ecfddef365a17b887417fb8df6ef08dba119558bacfecdfa187f156a15b305cc0ed57a35f539d2a4217b72caa071a6b7b86b9da44a7cbe63ccc5f1689ac242e808a33647a1b88835c888388a75522b9b19c935285ebcab2fc51662044c7b35bed43232ae81d24c0422c345ed2138d28d13d15526ebdc72d40185d7ffead962123319cd2fb8f8178bf2dbe8f5bd57c538fb75ae559aa1b3c3d00c33cfa2a1380f5aab76aee0d3fd7b22a68ac99c036680f9eeb49f4cc55b73b266f15233f309a4b3da474e8e6f3c2b69953e805efd1c00614d1715a6483e29cdceb49ace23348fd9d069b9eb8624d28fa35ad36ab66acce3485acadbf561d6587957f9ec67351444bbf631855471168d16ac50a7505d418f0bba74257c933a5e2c596705698eb2db321ef0bc72936802a16dbe828651d30887f41fba99081b1e008b9a4d7445762174128f6a249688b3a6a740097eb085101b1ea9201aee4782fb4cf19c0a19442715208508000c57662846233ef21002788e51b32c42c14db9c9ed8fbca513fdb7e0c3db195255f707a3a5712ce280a6cb34847f4c46e6bcae017104e8c9295e7fafe514fec82e0525d71c6fbcb8d4958b050ec1d2703558708a3bc8100cd541678ed5d7b3198bcfd848b084d17f02176771a31586aee3e71e233d64b683d3d309998587bb18b222cd5c2264a5f64b2776fc94e8050c383d67fc88139b71f8411fae930848e4d4c36137f765e184179016801ba4200d025d4c774fbd0f1b471615096158d2489a35f1b3d2088811a2778da9c1d254cbad9ed1aa7df2f2307f093e245995f134c24f87fd77ba7f753951ba29d7ad619e928a9ad88cc735eb45c9eeaf847a154dd20522497e5222cf0a401f1a05ae76bc67ab8c1ce4ae9b8ddbf1d3dac7eb640f614591d651ce3bb728c8950b47b881e724fb7f87366dad872e27621955d54b187132cc126a4b2bd9f3e80240bf2b1ab61dccc6810010c4cf806e454c1c97b49e69148968c39949930f9d7b75b97f082afb5d10ef661b635f86c3a1fa9feac439b43812f587714aa837320eb17368fab1f2bc1279d324e1f1035fa5d27dc7797b70f0ca99af853b92507d2eec74a93755b4260bd54057e56eeae2dd85777058010c8b5551828dbd4d91da9809f7a27a7a913097dc0799e7f21d07c440cb5e8f9bae2a3bf69faae66d33a91a33e976bf09d99a5f49cced374fc23d66177f8f2d2fbfa26f6e6cd5d72a2cd236f7d1f8220779635e0c5e430cc3f3d23b9bb6598045c1b80b4906780ea9ea0f7e5c02f76757972b01bf50cbc12b1e3eafd7abc0c8290e6b7a40a495ecb49f84a1357f6f5890ca3fc076f4d78eea8b9c72c4dff2ca3ad1940efac082d66d896bfd83697d000f9fc3112aa2cfc1f7bb4ba1526a52e9a494cd1f3bb39f6a93110a802a939f35249ebef67ad0bdeadb065b5f78d7b7f2572b01d7a96a2d456360f629d07978cef05e927e415319287aa278f584afb4f4a93df21b4289e6ae63ee87c364fdbd16cc7f15d0ccb90260f1177825b18046c6f6e07c0023751022879e58eac4d63937c0f61729c69163d46817907b1389dc50adef6a116b0780780b0b2c4ae304f41b5d57b44aa2cbbeae29ee4203369bae657ce5b309d097fd99ea707ae1244463684050d1da578a9f18a0f81260c738026b97de8040d229466e74b6d36d0ec350b3bcd9356406433f775e6179301e0c09bb375dcfd0c82114186c2a25b8006428421240295b829c403804db08a39b63e07e075d160405310e2e334a7ff40ca532a0f9402842c8478ee891b6e00355c962662bb74e610514f49bf1a81922a008552603d56fdbb84113c4cdfd5af59e4d3b1f03043146e352ebe9a337b8d220d54244cef0fe16e0c44041547547c45068055906b0e7f93704b0d11aeeb34e841fb9a2be65f14ca7a041c9e5646cacea8f57b646b3284f9dd7decef05f13ca3165d581105cf00aae58388b47c385845aab128decb90920ba0a9261cf36f843a14a188954e9badab7a44482c8fcef2253cb0ebb12b5fb27ddc8ab4f67510096a2ff9f9e39a3daa92f10b82f125e7b4260aafc7e9b70c253d8e7f9c913fa3773dda362f358bdb27efb6646be3b98ce499e868f77e37a8e3d73c92828743ae50ed8418e603777f29581e54e1d94d77fea7166891d15962ac6541f2edc022e065bc48912ffe0af884bdd58a8a728edf9320cacae852f3e09813d17eab3ddcbe52074132497c7b53e97f7bedcd6be29553a1e0e100a2ea20526fbd73c77885889415b1ed87b600705a732785d32716a37475a0f44dbebc62a2ccccadf55045aad6ce89d4c39f1a82549dcf18ef3d4d746bfaf4df5e68a5d1ba191e295efadbeed2bf3ae40c1b95d52d75f1c020db847dd5913b72c27a39cf9a5270158b9e8505d827d89eadb697c0a6c30655b7ccf717affc7f28771a33fee3bdd7827f810cd33defcfd34398d8f1b617074c5fe28653541d23c71351a0c34957fd2db64b7c4f61a7d849e729d8ba1af9e3a4bab4832b066c2709bea0dfd787aa9c8ca31ccf4b12b2f12d037575cf998805428f7e4f87d76355c0ebf0dab85ae103f6bb3cb72e5542a94ddc308d8be13abaf0a94d999d231de1f7ebf9e0c00c82e252223456b1efb7df10e5790c0a55f6eacb9ae74b6c75c82ba0b11f4064a2d846ff9c12447908a27ca2151693568b85a160b95a1f18806a2456bc2cc5c8956059f1cb099618c2a993c8c03299ca5ff9ccb223661356a1322608c1328db7d163fd18160fb0da171220072513e70587d4fc43b4fc010700e0568bec4802ae885c483dbe50ec7d765139d8c708e91d97455ddc59025baa5c5d100ed5bba9ea645208b8296633b2e9ffa0630a5bdf4203ee17d4a8ec2fde6aa2446514a91842e164fd64ade9cab81e122b6714d100619039cb0869fef9eef8b40b2425d22272bd67d1b66e8f2aee30a7520c24c31a42a6a1eb0628c3b9f8ca67819251e336f75dbddfa9cc763c5d21ed8f2c46cd57955a432aa15b3003c246b8d18d54592c91f107b936970542183e8b5150df7c7dedee1a92185d09f9c943cd34698b5f5a1a3c8be6e3d5df58eca1184cf96922403aca94f6a279d5a6e433a494747e5ef35ea2e9d84b5c4ead8441f99f2313ce13c360c78896965f9b211c8e118f3dd88c8ac69b3281724564537aac335cfe516c1ce68d4de2a00bc63de83cf81e563e90f5a3ef4e386efbbb55c5330559ff90f137350557d2a9559ef1649dc247088e897080041df087c74ac3a07c3a21fd55bd338f32512a15fe8f4fe5a38cf2287a1556212ad86968e99b7ca86b245f5a3bb24a8159ba024df9e0b761947039cfe7e272fad25a8b70875287a5c82e9271bd6b65dd79281f8699bb3ef07a6073a727f79293bbd9b8486b44242fd79ffe8d6d27fc556dfc2e7f6dfb5b70d8296be2418f999a92f1f16420dcffe1d71dbb5f80296de96073e12744471c300c6b418e0eb550f775d9360d45f7866521e9d1527df0d32a483cadd490bf3a290055ae7c62acb1dc441a4df8a9d1059d53dad215e109053747702b67fb7a22570f05c8f09c35983dea1387b8b413b900e49799102497ad7a377399132060bb59b5e05630b55def81638e6fa7054e0e5c371d4142cd884ec3c0d47016de0d9454ec53b20029c49f1b594cd75a52c5b7d57ddf6c0321fc27872847e66409d39c541fc012e0dfbc4c1374d2b2fe3a9b577d9010e65523ffc17cf654f34b6d5272e2e4637bf89742f97d6bd4901e5058ae91bc44359a3d4e01f8bc22257d6968bc346fdaf590dbaf4747983cc191219bed9ffc8e155184c66fa14753c8328c2f40f575767289067a1837a144adac2a6d3049759a5dbe11f94a809d7479a40d69884a327d999c17756326e7f60d2914f1206835fe5aa21f71d5e3915f77a4e741e1e43e7e6b9d9cfc6eb5293909040d73ad9fe8f6ffb3b883b64342a2f393d9c7f0bf01bfb5a50c1708dab6a1738ac6d3867a1b8289621b18a4e9a550ea4c03e0c570a4c74d2bdca5391dac4e8422535ba777682999572216867496f0a188f393ad408988c854d371f491e6820e9cff1e885ea9662954cd695c740572d4d27447072ef6e6d5774b58c6224f8ece8870c6d8bc54438889812ae4bd07af3202f748238c80df6829f6da7fa0ed746a142db0580a5222335da9dbc567bd705f59f312fc29bfc9e89e0c926e07bf2bf6f18867c5b7ae73a6b4d4d16b88ace5594f6ae32339c392d975a43f9c57e09159a8ef08e7ba00d47f9d043f658dce271603e623906679f907cc490dc7e9fcc017aa6114d7efbb4f38f6c567c416b0eb16be01db0b81fd7d2a40a972680a6fc1a887db77a42ccb9bc36302818d1f46bb69e4842aed1f5f00cfb37716ddbf1fb4508f155fe4c7e962af1bbff4eb5cc9746eebfc8fc2e27dce54490438ea53df536a5451f0864f4d1682e13d8c27c77a240f2746613de3ac297cb7639b5e980c534e24a8de52ca60d4a2a02465c74b5a88bc4b23d2ace3be8b2db87d40101bedba9c21d8a49f35d47d226c6a0bbdecf3f18ca6ab50160344fa06dd3002b3e8bb7929e83da8a8e3f0160dcdd77cd3213d657c9ca42d894521c9685f773f36d1f1b1ddf6cd5bf8b1d13260667c6cba237c6c1f1ba274c3f497fedd849c0997bd78c170348783a3e8eaa6184881143a6132ac3ef75480c15ecd31b828e901de2d9e8f4503ad0cd22d5f9198f523eee7c8fc112c7b7b64dbfcf9429148ecb0d0bf7a7c8081397eb15a5c47e17d1133ccd0d8c24fe636d461d46b9017912153e5c13787dc310d797ee55867da71ec970729ef73149bc496d317179c18c781ef35a47190b8833246e4ce30005846ba21e6f9629a772f42d4a6b8ee7806d314b247a8b2bc38e411d6a5ced764c3343b289eb51fd98f2314ce6b5991029b2045e024f2ca5bff24cbc1a59189277ec0c3f1e0e06325cc84b652ff206876fd73744e2267410c3ca2e2cb747d6a0806faf3fc5268a884c018471e64fee3d9945f1fd0026b922c88bf7574a20f60457e07027feb2947f7216d8b2652bf537be5a628f76b3ba723c2d563008c8db713488415eec5c0c968425aa6c31a8496aa4f2b5eb721f9f3e7e3d9c736bc8dfe7cf1bdd102ee62ecdd105f2000f273d8071e2d02fc00a3c01ecacdddaa833dc16e206e806c7435a03ab28df29163421bb1226e645ded38f1b973335b39672b1d02c4943963daaaf24a5a168d0504c96b75140ce9d5dbfea21b6c55b16ec9172afa9f228ac253e81f7f32cfdc7997598d00a30e0d804a46b343b83a9b78693f69695b47a54524656d0e0482dbad0f75abf237de11be9349ee626a92b324426de5eeed69c205b0764aa0961efc5b2169d351069c252f0e9b390b1334f9fd74bc64556a6ae4090826ba4d13d4ce7120495cfb2506d5a2ab74161eccc97aba68520268c955713440271342a098cf2b720b850aad483eb5610e3962bb35d8b04b55cc5152d2e9fbc346645fdcc9da8a03f439ba4b6adf3ddf41af6483ed363f0b31e7ce0503d80e53cd1514811aab81b19ed2c576082745a884784581747a71ac04bb7b54f11c5b5f6c67623a41f4bbc1517fb255fc6651c961685cfbecdc38c7317cc286701db71ce3acd28c3e63c359623a841973f94d7e7d85888d0ab69f09a1c344760199ccf82fef3e97d1d50f74240767696c0e883d31b634de78a9758c682e37cf1102573fa32a47797e1a8759745f6e168805b44da0e57e0f305cad801e450ea5ea484a5b87ce0021f2e67c8e4a387b0b19a6ad605a7704faf6dfd12d23ab071c4c6359860d3a34d5301dc0ed9bdb22ce71595874f74414f46d502da49797bdfdb731da300a37836515651b90a54607d032929f7cc4294284131eab49a7db55df83a4ca71734e23b1985e9ee85629ed602776aaa6a116586ca7ec90693a1cb4de4dc2b96115dc3117ab73cdfb04ff6ea45109edc5d4f3f861c54b09a79bc0fc1ec0de28559c2b7912628fadd493846eed593a412d30ed074b3c11646cb0f5045eb5b038cc96120cd8deaa33771c732b87fa7856e875abff240f3dbee77ecd24356cccc75c79c265441ad8e4017d90469e1730c8b880c2becf77db454220d6c8440966a1c57a0f9c4260153050a2eb43695cc5be92aa210996f3c020e31d17d258b1bd742cd08671962a0de48d0d0445c83882c725ad8bd56b37c45887b9805c25cf4aac93e44cefcf3c60d21c2cb9c935267250be9103ded41f9cc38845639f87583a06d2462fe603a9c2c81f835f1bfeb130456e8c72e87ce4eb943a464c5ecb5f9dc58655c574e65cc64f7284c7503e3c1871e65c48e5f2259543f42da9ec60562b7d1ddc3d573fb607d5309cb8eeeecbaeb6f26b3fd2737082d57567875027e6d16c7704a58704126ae7f20f4ae28e3637f05a5d1fa0032dccee27a1d920bbba3f31fe21783511455cd49b44281272bbe30d30e72b3dfd5f1a7756c6c0fc0315fad96d48353330e0e92abc77d26b16e6d255f51b566927720686b205fed2c80637c4a5178003d2f8e5dc53ec938d052bedb09dd60d7b051aa0d6810c884921c45788d94cc5bad9f4b6d8a45fe09678053903e267db3b0a73d90bc4514875a9469d621d14488db6448b3af704221198d8103984d855882129d5e02508697c97aae477055ab6796e7dfaaab4b05857dae58c4af80020e47a7b95df6ee7e2635cb764dd90ab1d6610e789db977ecf81bfec1cfcef0d7ca8da6c246634b30702e036b3961bed41bce25026a18e98c00b0e83925c02111d32cd5d2cebcb9f5daa58266ff651382e1f469046e99f4b8a2549820cf51917bdc09dbafa4a6640f6b220eff10ca240a25f0813721b5518a14800b5786bd33cf8e994b9284497453a90df4b4612bd455309418f7035cb3702b0e7d4b06c8a35bdbf8881c609c05da32dc7706a2286d76a64b26a514267beb8ce5b0daea7763b0f28711c8e103b7417148c711212f9d5ed4206898b3da36bfc985ea20c6b223eaca4c221a44aadf5e5bd0cc4de21faad94b26e953db8327276211d4cf806879c1dec0a6bc23e9ce05011c632acdc40276e3abb92b4bc8d86a37933f40889310cc528e87a599c69af31ceb54550c6ec8da65353b77738f570d49ced7a18d1eb61013e5fcb890cc3d8df2d8c02742985075635e30181c571570c4f076e571bc56a3adc95f894b03ae2a6007f31320d712fad3be69de100a5bdb9268143877b0865429f1325b95c94ab15b0b36db40afd0f67d1d977d0f4bd886b9d063dc1b1c984898e4a5f7d5d4428326aa143c63189d93ad1c1ebaf99fb4ee754ee8ca6bc61012f9d6a35f6070d471a027e2b2368648d60120d8fe09fd0413ca168b8574159c777b1ae16c3b4e98c04c390198d5f19a4a0393cefa6a3916d1000a4cd821ee9166b7909f26e285bc5fe1c031e1b919c3f9cfa39d2fa3b8b53565cd3a331b04417c6920c0ab123c90752b5686215e0208a3f6b8127882c612c05e7fe74582ceeb150f6072559a34e8a5fd0b5b118ce7893fd5a2c4ac4826f61e71c763f44720e6829cdbea97190b1b934a24497d7eb37cff6338c2c8db35b1f65a720674f0fdd738c1ed2468d32640530f4dae13a64fc6291f03da9f9033c64a462371f005dd75ac5f5e1123f2f6b009ae00fc33279b0557d8412ff90888e9fc50b09847d600dd2a91b0322792716d7977945857886ca1f76e284b6e78418f1d5ee02b465dfa6d7b7ebd8bd75e430fb56cb81bb9872f3147ce8c25dbbfc0582cc5d75b07f87f92dc6b70695dce6528a03ade3c25958ccd60aecb6b312675bcbe340bf7e109e9ca41e91c00437117c76b92d3b90f9af24b63d66e79e44d0ce2bd4157ff62248c4c26cf84260583e9d355dfcfbe5289244fc64355fce3132ea38e46ad382edfd7a0f13a2e11dda736dca61443f4096bd0ed6990783b782524798da98be52fd6f38a1bdc1c3b0c50d0068ec68dc572478715eefc8a5f802b99401b74d95d74ae19d785ce6daa39559e091568abf41a194c19de035c7335561facc1d0a40938aa84efee824371a5485409da1a9fc9e4be995335ef3fba52ba4cafd1faa505714f5a5c88eae509392ad04b039fdc4d3ec932cdbdc578dfad831b2083b69c595cd26b7aeb12c02a1c660b8605865b99728e6a858e8d5a4ecfdcdbce122862fdd7c411ddcd79ee9dc889ebd3f428bb0a29928e7040aeaae8650ed8f5b6003d6f797eef2167d42e10809184ccf0994a5b2e5886867655e72114f779262cd753c04b482a03b7a76f06c93fa78f3b0472287283efc453b8bf637a142b31c64b292868ffa4b7eca40101b41a7dd6a4bdbf520e8652180634b5c0ed22c0b826ba3311407f6b39332c8210893eddf6b199b8e6c90c3f0e8db2c164a7dca81eaa6c74891a0cfee165e4ead22b3fa89684572af4c739fcc16dff4d18b73ae507dad2429e12d5434e9cabd7f81dd2d48772a2cec0d420eb9cf198105e64d6cc90f42dd581d162273048d2a3ab2ceb8fd937dae37d2cb8c0adefb4780639eaff76a6b85904b09f9a311aaf257e63ef08585ef820ef7c7fe8acab272efd5f4b64a192b5d393054a351f3b0eefb894924a7523f9aa633c959a1f6a7f0d6abc9d487f9b8bdd3886f3377e418c6af6bb1a7de009bf77ea14d280a4c390e01a1d58ec1b9dfc049befe0a1c257af52a7a05cac6bb782323800be0e5cd670d13a07b2fb7c601451ded018072f85c6fc75f77270fd6c6819430025c3e2fa696b072b410027f090823821feb4f168e2e85976851e7e1ffb6aab156b429eefd8c788f8f078fd517084c694cb93b8ec72678ea147f979deada2866d5e7c0c53477733e710c9deed068f8a60c658dc5873bd7d24cd70b8f601920c423dba0193d2e5ed8c69919ed9fef399e41716744cb157d940d07186da87bfc05fa8a2f1c02d5af3d68cd1161ef65449eecf3e38666d03eab9112664e897e64b966e053acac8c1336667d02c0e0e66abb7b9ad09ea7468e0031365cf5cd220d254ce3bdac45317adad99ada7482ae0eaaefc633fbe608e61ae6dfe6d6b57ec645eeed44bb8d9c4a73938fbf480fcdd73ec56ba0776463367ae5bf32542ad8d8da148954b6953715c60ae8662624ff1f9bfcb8c40015c7b12bacbac6044220c61b9edcd249e542612acbc41d72e5a0fcbc67ae797eac80a5d73efed6f9174b87728fc8af01d079068aea4d4708ed2d63bdf95bc198c50e15815da3d533ba9dea1e0c9e2b6e0946a77184fb43cc67627891d70da3d95dc1073022c78ca3622b7245b1974be3218bfd76483e08bd70760f09d6886bbb28aee0e7a82e94ee4755e08f6d19d905d787dc1dc23e28e1ea7bd40b1a02c70669c004018242fa206b19dd7d8a628920fd71b047ad8f3e3150a72c6bd1a6699615219170618e473d4613a32234df9e41338d619eb02b43543ae739f39a7365b8c302b7ce1a98473ee76eeb839f65cce15549c35e587497650555a0a028c80fd24585bd66a7c12de4f6171d872163dc1a5af64e1acf354ce4a0edbf7e94ce5b4a0e931e3917d0d537a2ed90c4b5adab896b566dab288e45c2bd910455d3e5658feb23724e4e0c0985e1235bcc8674ec8a753d2ab969d0991e0b8a60013b78a2715f14dca92626588510167eb71db6f4715ccf534207a6b4cd59b217787c5c4e3f67a884c171529fb37b14f698af9213453b2d5de507e818ecbc9abbfda3fbcfad0d089373e3f063686826dbb40b4c9b7669105ae5f7d63838904f5b8cad77f9733fd19fad268529e3776b65cd9a153ffff6e82e07fa87a2535630a7a4b905ddc521ed9b87b3186b972e4c2447921c6b44be0ac05eae854a82a1bb2e24f68f8ed01a93583dfb6edf6e4f31baf4f46ff8795cfc1e97cdd7cf52397225b31076bac2285eb9cce4664775e8feb1162493b5a463172fd40471e41d39756e2df836ea7130d47f0f1823e8092febcd82371247efc4dee8bb0c20021bd1b92fa4bc25d11fa55d0602d140e3b7975a74840e833780ce11cf40e735bc22b3e3ecf2342027b880911c5a80fc301ef16d965be0a15534baaf34a2076b7640ff45bb3f0d7d8851e0942cfb5dece82e080ac2ab0df7cdda8b727ed7de85d82ff87075efcee7aafc22c3ce185ed17ad8ece773953d9957851ac63ffc212e2ae42eb5a40cd760e27a9b82b7488094b0a641bdfa6bc5b0b2607c9eb3e9c46e2c10bb08e71a4487d45286654a0dbe90bdbf169f3a101da6bb097b047788d7ef41f8419db77351eb6bdf1343bf095bc260ff4d31d0e882fa87a62e3b74f1f73813d9087a72521949d64ba379f80d75b39413684d2b3306ad5c13649254228be124f16e92baa98d30730d57c70716caca574b9db532a8a596f77ce0f2c22bbbe8535b1e291754dc385025f1a7bc2abc791b120ae1ce438db5fdc3189e9fc0e754f9bd3dcdf45fad56cfe233e6008ef9433c8fb924c4623e04b3392005c62a120840204453809f7850b46f83144710c75417d18b742c54cea80c60d8323dfd16ce1905da0154842bb34270d9ced711a5a8e8b86bc2ad648aef6c8b264bd790f42a40927fa4ff45ce7f16e1f290f82aa5113ca9c0ed354db5c85ab5d13905806ee455208ab4bbe57b6398804428d3f30615ded9f6580c71066df57ca8d581cce0849e3d067816322c0be4ca44e5ca5ff1094bb4eb08468738cda036a68b49127380528c229347ae23620b0623ebf4b638919550fa5a4a42774840656841ef47ec3c3b5d3e193e70cb35e6fa2445409baff1fba4154df9363959870429054f612668da4bf67f5f0308aebb39fc3ea3aa6a4e1325a4f7ca6218039bb269fe15c9a133cfd12165db35ee5132ea9f72427cf136a3b55288d44a8371b56efbb01c782b528ae755f324ad713dca7913b81b12e74dd8f6f11dc35e66c22f71e802f422d7cc81dc64d1dbf957c10797e8e38f587d22e92ef848c87083db281518b529061232e97c14cb3bfd584eff7d9182176d9462358c53d0a3c0bce4f91b77caedb5aa098f784a2c145074a18386d36bd288b2fd44d3cd35807addaf8524f3b3a3a2d655b125a2b9fae01711d4ff099251b176a19b45133ce1be9a7cc7e4a591d05569dd04c14b7df13d96163f85f041b94f6f4acecfb95dabd657cd99eb318d540c3aca809ad3e4c2847506d82eb5611d7b0dcee0da3f2270e4203fc7637b8a4a9f125ea4f7354e417845287b63f7bc1e63bc2f133ab28d1e4a54a35bcc1eba9ea867db79b396404d80fb249bcb8619a4bd46b3b7530dd03b5c1e24487f7a58314fbf5a5035276b113b7053be4a12b0aa7f0e1f78417ca63e48e4e68d874c5b0c9bbbb6979358dff7a834adebb2f346e22b43388af6073427baef804c27131fc9f5de5c27a1775c57054537ac30964d177c0902502707f3c7870c47a42078f5ffeaade4773103665aad344f13dcf5d4a9ba053ad1dc4612c83a8b03d056b1942ef192a0dbf318cfad31b41213d9a2dc889f0a64148574457c1378e26d74076b0f73f12b533cf55c4a3e711bd6a8cc6530d14a3f5b95a9f79c221d605452e7449a830260e9542f2a0828607524442f272bb51c239e8f08acb4469ba5af6a49f413517f39e14f869376f2ddd786d57f71fc4a787fce6b943708e3756e7a5e45a1005aa5220b8051744480d564f92ed62c5fb440f205ad875084e18dbe34166cdce5ebb66d04504d87833fe01cd7884b88ad52393c65ad1fab6fe11b9ad2066ab828a805117f4445358b4cfaa8f5b38ab6c67afff9d06d8fb79e28901effbf01cc54856d4b4e23b50eec0f74a9e14ecea2a7ae8b335aee1558de4f54c183a959441b79a5c8900d5ef00998700dac6b8b8a6d941219fd4d1feef0fe8148d5ea523bdcd175d1bcefd8097356f07684cda649ce99939f44baf50ffccd42a7afbd22f68ff932aa45af25701c561ee3e4752dcfc95512568a70642fbd44e047ae43b0a01c6c4c16bf31d702da45ffa324ac215add645fb3dd81cb3026d9584026f0774482a16cad2a1abf7c02c572a0865b6e3c60df5b8e25f063103446847cb37a0fd60550b83ebe0fc8cf34b2c759d6dc8f6186c8b710b0b542f6a8ea5b5dbcec6cbb3514571e3c36e79eaf5b4461b11ceea90ae94c3f2e94e6aefb5a47ebb1f596b5fbdb52f938579898cbec3d3f7308226374d6b1be22d7ebfa4d8107652cbb02e8eed9151f6891cf409fcc2d18f87994edb3fc423bc6a30bd3b5ee37f552f76b189ce944c6dcda316e46e945fea0c965d4b9d2281cf4b2fb68b16111c34ae919b711d62d103b00ba7961019095e88655df625458f2eb46a7cc727235173fb1b2995702c93389109cd45b50ff994051993eda5c48d6c0130c34475e4c3a15443aca8f8526877e9ae2f3ad5764a18e248ba57754c305d99f8b7be4dd11fbdeac99c01233fc72699f81765e1c57f1a28fc0eb220104d008b30d9cc917f05da7ac3fe4c28be73e117809524d26f54bb361969fb93258860d56501da2fff10c15a156a3dc4559865b1b6ec79a25c263e714fb5b764e136b8eb45b70bb2a16a2f2051dde59fe6fad6d12977548cae4ce191635f8e9e4a408cd51f9102e348094418d44f0304356529f66c4366d19189aba9f9df064ca865919d51709f7f055d27443a1e87f86ecfef4c4ce5462117a7315f1c9ac2656bc7e6f62db696b4b8f134184e75bef330b0811b202b937308794d1540757b954ecf6184ce8ad55205cfbabd13d86cee2d035de872f0428274be937233f01addd713293dfbbc10c87194f97269cc04f73051c926a51adbf8b0fb761b611041638898b6399a6a6ea4d335acdc1cc39b88510a91ad63bf71c77f11e18bf1a12389a56a83e84c341b354102ced767d6fbbeaffa96a947ca946872de0fdcbb889dc36f2ea8ee6a2376d8374d919786be7c95a851e09c5e807eaad5d3b4f169e4bd8822c3b7a53e811730f3b65bb89b03248d8dbad99bba1834bca10a113ffab4ceba25e8c5ca3a84cf3777245f4d4e728cfca0a11707ace9dc5b928459b6dd3eec1102550889a75072eb8e1a8aaf09dcf369d71a5468112a2577e80674421cd5f7656d37e0d176e7747e63c130707021581ae2d570edc81a800fd9a5b1784af2056005b10789f23a7ed39bfb160d19db235a15f2cbf688a852877474819b6fbe40db33ef381018ab92d724a0214e192accc0d1e0a13ecf9ec29b57a25aa485c7ceb4a121a2c04d7070c6955319810857050c35041b4231f7c94f386e6c172f0f9f78b0b9aa540fdaaf6a11f10106df41e880eeb13f7c860c7ca66871ec5edcbcb23542704fa30dba45d3012b2d27455f35ac953f0bd3885c5b86bc579ae6571aa745943ac60720c803be3bf61bca3d311c0d0a62c468858379b322987611e036085616731b23835c4f502a4d0071c75bd22f3a311e23148b88ab4d1da6ea346468decbde5de3b2e0a3e0a6d0a193b75d236d6855d06dc264f959ea39f24193b36d2ac33b7d09a2c29c3e27304090666ee2bc23c1586c58454882ea144abd08aca337bc2f9226acc07f74f1c3f18f165121d8638fec31806d22adb314d0b75280be34159d84f50c2944808d3a12c27b4e674ac85d4b1532852c73d46b7ed077e16babc86a30c3229673c688d49a4ef63c7693a522232764e5a196fb24b28c43e1582da7350c721987de6ec324230e6041eb6c50865163178f1b874684d76ec5b8a7e96544e898cd92991f118a10ef66d13c721797b168e43b670cc44212d4304b34b170c94063b2782d96bce441f4e66b24cfc1d60dffd14820dc8be7d935976db71e812166561181115a22cec272e70f616684d2602a12c2c4628bb17302ccbb1cd2e676ba5a0adaec0b2d82067e2489d640c7b86e15016f622d40bc55fd41b634308ec801a5de0294a89430ae92c9570220c9466faa0aca2d9c31591524a21596a405ac931c85351e8841f60b001fdfb2b8e45804c9ab499a134f234cb78d4b135b2c689c43e0b9570c74219fad62a6f90e413d4b7f612902a548461628905cb29e70ea5997f96b921313e988a3f7c80008fb20a0f5ad302652d818744d9a179be055a638308cfef68658974c3924cbb07c815e467a63b9367c837203ea4955681b2e625ad6df39c73ce12f04c1020c9f372ce399b66f921048629e54d5561a3de112868c1375207984f336cbcf00c89635edec89b14708008a1363207413c3c3c36b824d20d47f29c128b6c3ae698916326db228f37f254dde429e7a4333c2544509425d20d577a92b2666a2c4499fef6bd7706f905679d581a414fa6f39c3d4af12ca1b6c860185034f033cf58602b478b1ea580dddcd093133cce293a409225468f6aadd92e7b0a1c7eba514ab406a585d68c73cb92b28ca82d3e7a85039e61e63eb802cdf632cf73507e5c40e2a05f25c15c17059e3d436d9b4513a66d5e504a216a490a3cce284a17ab7d1bce20bf0835208f720c0d1382f5ab1771bd84603dcc8bb86698eaa12cea03aa0ee338850489319524d3a792a48052419f17630a28d3a77a523ea9d4115ae3a1504a3c5e0e7355e8c2cb61bed55016651951e03125949dc8d525a447bc902209f252e28851346807e61f0a0b4c3884451e305f893babc3fc0b77bebf1c86098c5f3fd231058443d4920f1ee78852caf429205a1365a9697e26a5999fd827b1bd8fd991287ecd62b55a73bedcc3c8208fe8910eef614c9b885a0a51584294d20f1e69910c45236a295394120a0bada9b4467639b3452136d719654e2e8880e79b42a12cda222dd2019e3f1501cf7f3ef8b6f88080c5b1c80b6e90a7787282a90d2c30fd8462333879e64b0b943c7b664f46ea39ca12a9a7084a964821d8926951dbcc2c94865e9c4b9445cf92021fd128f7e57d05bc9c9e76104aa96d2650d32ccd1fca5af1d0a229f412d2ae41a9c394e9375a44b1b49145740456327d1055a2596a5394d2114d4297645a44a7138a524229a194e692c4418f820e789c4b2922153de104f668d648810c407d25d8697f146269bddc0f64f0439e6f79c4fd40063ee4215f1137e70ea5a1435a42787e8852cb0558ae30730e102153c7c2cd55e3baf6b53500452f2da6ad20eb860cac0b849e1c0e688e7274f6bbb79a2c915e3fb9863ea7e2ec3971816f5a850aa4c50bccd933f1dc2109e9035932a5b6b6165087870cb387d20bd09af9a31f90cc6f5894907fb091451698b89427b501033c522525bad461cfb8ed33a5b4d4365aea2705a4034c3fa67ef2e444b0277650ea90f9a2c9949d138960cfb06727a2ddb43dcbb2ec994ed34cdc3498b833342ac18e61c7c41ab213695d4ba2ac632de947d3f0ec0cf1d06efad2ced0885d03a6ac04138904691a14ac78c233ca2593f8337f9a669c3f9938d4e76ec2699a394f7801d6ba63a79b0ed6edf20991511e67900d2fb0ec228a2d8cf0b88864077576867860f7aebd88cb137786fad84fe17412ce2ee421ca7346692399d434ad855666871a48c0ab2807912101afa2ac84480d98924b3bf6158f9c3f4981a98829b9a44b13793025172682530be5699a55cff4a13d9435690f769a643f459a65130bfda147e8924895286b9cf98ad488b26814ea6406214a1ea9162414a8ed5203d11a394b5094c5c92bcfd9482813900651569239d2209ca9fc4895a810157200939456e4525c84addf0a02833cf8a713c91288a2802cc8cf4f71045998a012935883d4c23544c106c4203f652e92e58be4221964e1c6404550bbccd9a90862cf36cb7a0257a8d9deae96666de540029e3932eee6c405c658495041a676868aa32caa4f6c1b0e86925b966072c541cbbc9dfb3bd84662217a6991bb832ead3eb208a1353b788019d7aadb3980da186248dbecc8252684805c35745ff4200b97f79d02bc3c71e8b2a03d60479fb6214dc3da318455d831a46d743871cc382df3529e213a3b86481c8d323dfb28b5cc3c431aa629d4c26f6608acc29c2c9ca77e66e6b7ccf4871c94d56f221c218fb3270579631ac206ead01771cdd9f3a0ce9c2e7ab0878b8ab8699aca16745a61df4ecea07ebf650b75bf3322281711e10038bb427fac28c1d8b76a5a6a2024856049eecb51468e734beed79b26fd69892508adf921bb8544ae5e08c5c511b94ea19d69640748488e5c3b350cc00443585ca9d7900021d8e00b176e9b1d19176071edd42075f0852bf51a6411ac70e137cdfd54280335401f8740a8017ab2907da2c04d0b5ad35322d960945ba96da8ab5f7da4a53fb7509b1787644317b97d50d44846aa6ca629d46037d643ee6b937267810201f2fcb54d4ae885b94fa13e89e3274ac971dcbbcbe14e5dd789d3288aad72a810e4813a9681d6c8f0e347f7f146eb348d9aa6efe307129e67000c3f8cda2688e689e39771d80a02cf9f792488eb79d43dc141ba3f203096516111579d464266b6455cb2b36fa9a3331625286338140641b9e250198080555492ba74a17e6f2a4485ada6e9158f0a2d8beafb30fca8b5ed29b5a736ccb2ecac08b2504f5f4f4570be8ae08e16fa7d1dcafa028ff288fe7414c69553130e1e6079d311adc94c55729bace4eeb648cc3e42eaa8ef29b9a7c8bdd93bb336c504180047a697238d4cbbe3e63754a65aa6b4ad139cd64e1f5739fb88ca59f6296d50cf2e51210ea5a4f1c210d3c21916309b76cd143b42e240620acc144f72bfbb1bf3410049f0b31324a68d668fb0f758688f4062d2d04f9a2b8ef649a6760a6aa7644a6758a7461c51a04dce8cdb8d213095925b1c6dfcab80152b56945fbfc7469e52c7066696f43ab9442ec063e6a36982c046b466bc4b72bfef1228f812212f91d431e525d232a9e3122171f4fb9ab4b94588e32a8f97283712d97d422471f4690978fef4cf77c46493333786c033cb0a8bd460a03ea492ece60acbbcd22667702c6185d6d09baed09a9a6e39e52c3aea166d15caa279de04c40f2e40e02d4b249e2f6cc0a62c9178ba40e2517a8127a925b46d54de194a6b95f6d45ab1ed9d7dad95d7562bc46c4a35d4aac353569d4dbb67779dff2b10db56e9a4947653ca9293d2b1d23925a5f607d3de9add5a250e0cb39f2c2c93f576ed6aabcdb06b6b865d16587bad9269ebb4d9e7b4199dac5befebad99ed1a463c04c1091eb39c437691efebbd3c34c9f7bbf7b22eebde7befa512803caa7e56906b15b922fd2421d7e31da6c8f5f6d30205c6d1945cefbdb70b2ba77befbd36721de2071d57329c7da08f93117c4dc4f83cf10363b4a2b2c38bea93a2480aa30ffb68b1030c279c385104837dbaf8514d21f47283085ca02cc1d041879416550e487a504f04b9e490a407fcc42895031226f0682084ca418a0ea7221e9cc3153c74357bf2e3653914e107ee09a3930878d89828ea506062828753a235f1b3e9c0c4275ba2c8549461af9911124a2393e4182dd1bea31d6e1151b6031d2c143d58117c72a00021e9b0841c729c50eac921c804394c242191200539e440b1741a488c9694aebdd65ed5119cca72ca94571038a607940e78234219815d9268c2141b2c3105c9862957b64ce14110a62ce11b8ee0b33ec332ca128a166891edad51462921f9b0039210187f061dfeb0ea5bca128a2125b27d5dca473c3c3c392041c98153ca120aa256cab80a8691e514a429aa2df097e514a41f20815db29c82d404972ff029cb2954764001d6b29c4205084b45285bfb3b23a1804116141070361404952621a0b2440ea8d840b5032a55523d54b09091e5941b28b5b8116013c36e137890a06077fe708a02abb0e3aa40593d77e01431753c16a47c912d75ac72bf0be50e60b66e194fd5324915c25c267c59c9f428354ed3748bc592390e950971fa14babc0b531ecc5f3ebb17a44be6b353a95eae3a8cea45467c818f3978bd49396c62d89d6210e6b9b307f3e057639fdca74a6dc3ca581809cb4bf08a3a300ce87748b0fcfc95f357e6c8ee74f0afee3145372dd64f17d36eb96f1b86d93b83b4a1f63c657e7a17822ec8fc74f08a3d64c4d3bd77077b78efee89c7e953285d1b18c2784ca8fa17a2be0ab1cb61fc95baeaa610d4818179f9364d1beaf8af97cb5f300ef357ea2fd55f2e5ddff5b0bc843b9aa6af0a7d8440f0910baa5161111e1e1e1e170e254ed3b4b7e429515687022c2fdf5da1b202ec170a4a7a41843445094997a650e1c14634650aa23661d7049a4c2a60d2e6e547ca924f673161d79348474ae4be8785d6c0e88e850264aafd8658786a9bee26d387bd62ec975a7b85743e3dfec1454c745545e36c132282cf4d22fa9348eac8b813f1be7d9c493d4e4891dbfbf61e9ed8038b6fa112d14d2772b4591e51d1044a965430b192475c832ca96032828c8fb095e652de514abce3d096131c83e9f6da8be46cdebe578c61be50356b1aef024e6b33945a064e111fb970154ad35f2591158147a965b6966021b9f4c4950a77e6910d920882ab067965896ba889263ec247f8dead507f863294d53add09a76d5e43b5a7f74c94fd806b8306be9c8931d467daa738b6506186698de9591682a6a74cefe13d251249dd3b2a854d229e73d458f8b2e95b168e1f7ead6076efd2854330134117b6e3f7e0ee8944bc73c7221122b86bc07d26620f6be0cb267104923551860f0b55e816284dfffb9aab59729fe18ed6cc842ac63eb4bc85248efe8c124a9be98229f429f42994420a3972dcf83e146a7a8147199c15c968aa8928a80c45f1c97c078f9939a350496b468c9b12933aa4a43219656559cafc9346fce4fe7604d66a9839f0f9c10957f79ddee1c85583dc2284ab1387b0b77c30f7d375723dcdba6f93032f1782f7bef37eface26bdf7e789df3e54d6345feeeef2d4f15883721fe3a28632b432ed23ce461598680b652d515673a7709b6db3fd1916a4a43b0ea544452db660807786768676bcc3f8b6f16c620d2f479deb56c2e96084cd85b491b25f8ff492d4c199c42a82dc36e4ceda8bec43594336968055a2500b354dea188b3a4dc34364888727ee0cf1f0688e128904c1f7c41f4dd3ef3eca232c4e2bd4007def039e289b8613274fd374dd7b10a9e19d58039119e47d8b09f2f1c4211b4a983f1f206a1aeee32492ae367a39026bb8ab304f607a4db412b6952c4e43e0af7b7c7aa339067aed55d3b4f19da5aab3d05eca91e58d9ee931e3b211579eca23754825c9f5a9a544ada5df4add4b6dc511779276abfe5471c338259af4d043ef70e4e5f12ba5c6d24b156826a9b308e5da537f2a92d6d244b466a4442dd4577a90c76642446b324e7bd631403b8fa492b56ff4f51bad956abfa1467d5eb4461363b8c7de35e4ec63cd3108a159ac3108a1e3cc4469c318462134c770df008d3ecb9901a35b288b1efbcc1bc54e296bcb0de511bd92c4d1a759a84df5a1748ab4e920548922a1a4d04a396e7c1f4a6909657513095156772ee8d39f4ea453244dff48e2e86e2c94d549fd6da9975a89b2fa9d0ef0487d727f4915e716ca6a2dddaf56a23c99ba64f4459c8876d86082a534dad157de5bbbbbbbbbbbbbda2872bfbb9b01567bcb561018ccba31acb1eebe5dbbda1d3f29d8e48c7cb98277d0d0060db0ec3a2878945054a035f2d5ee68010b7978504a29edfa197a23d34f15aa00a0c0d9c528bde2ddb6bcbbfbe7fec0657983e70d5b4ecb09aedf61efbd14716a380307b89e012aeca02c6b3371c4d6da7fa10af0787bfb1b3d4315d0b7ffed67b26ced574960d629ab2b02cf7f5207b8c2ccf7e00c33d7cc562d7e36da01d96e7a8fd4b9eda673a9a4a4de44109b79db502e48978b4d01fbe47aec93f40348db98ae7d944b3ca74ddbd13653e868c7d11571ac7873a33a0e6de1c7ed5c902ed55347a56e0a51db86faf6d4460388893aa914ca45569ad7d01469a04108367257bf9ed536af9ebbfa46eec2c20a481cf537b4c044a17e86412e40253580157f7420eb00ce566c01cb34d00ed449a16e3bd05e661ea914eab203ada8b3f5b8c141410bc60010a9e3878becf271957fb84c1b5a9808a03db9bab03d751edb53dbadc8c37494b8436fea74b463ef27b9ddf41628cbc49dc2d9134ea0a6a9dfbc1af443674792d18fa55d159b9c193b28d7f8cc695cce84d3b5d10871d19ba6b67a709fd21f0a34438be63462ab1c8d901a596e26bc61baea52d5420bcaaa4a33a991386924b4a6daf8cc4c4aa206a8a7515f236cc500f7cc6d883b433c689c86b8d397353ef39d3e8d197187bec6e93470542fdf258d012ff3d324fce964cceaf80d39e19c7853786dc665783c278863268a230ec5f1bb387e8638b26488632bc710c79b8cd336540b4ac3d332e248b1e47a501cb31871a45946fc8923dd92eb61c4f17b11c77ee57a18a2aade451c5947723d4a1c5bf5f3c4f10677224fe5aa98f42cd27beb3c42d2d43ba12445ae753a9138eaa5b77646e07b6742e9a22fec6f1bea84a4a997a24a4ca4451247cdab2160da437928abd6a0d3939339afc94cead8f23c2acf303ff188c05ae72b26721ed19c392a6d2f06797ede239af7984c4f893c2f63d0f23874b64744b9dae5f49f60d90de1d123caf31e11ad9151e022206c72663be100cf274860d9e57450f0c862d514ea93cddea4806521d4460c52a12fdb56daa235a38dfe8dce91a50efaa6379cc093b228cb0615bc357763082c0fd00dd1d714706e4e4fe0d98dd319814f1802a63f80c4d1363aa6c8277da3c5626959b018786b6e760c40853b540539f8f0b8627c9b5c8c706712a1c9143cae9d1a86b2c7f8890a6661bbbd2d92e951ccb1d5319817ef230265c0a925cbc86ca742740936a247d8e9156c0e51449928055bfdc87159fd8bcc397f3689b9b0bf857409b4dae93de83d91c876fa93484f847b5fb60d68ef326402a77bef817211679cee89a04589a05d5ab22711d4660e8f433d20dbe6b7e174da61c6c729647d2c0519d23628998f536812f1cc9e9f18323e4e19d4ea6d339d14b1ce0a62b199204d836d930bc321d0057cef3dba9fee12ce382ad46607ba80efdd47f7d3c34c9cc18a3a261b592c0511322468c98ecf0f50128b81dac6070602f26165069338e341964ce28c19bfec641cfc2bc663fe10b4ffa56b46e87dc67b9c7e9148f7d36788b8d53633ced1cf108974a77dd004f2d86e0f6adfe8e989601134893c3ad08a34ccd08099ed5f90aeee34e498aed31dd444b08777fc1ea76f27effdbe868b280b0761202c2384798cf0e5abef5ee8f253887a8685a08e8b0b4a46285d3142e992f1f2e97e7fbd605e2f7fa98e0a37942a9c3d13e80ba7900b8c54285d41fee2be1da5836f677018241ce29d564dc07289ebc314c1a8aa88a20c3e46d2f77b702791087dbf139b9b54044db37b931c37a3dd3e08ade16eacd42223a02021a2ed73c16eda661e5929ba29d244d67f3a0e4d61f658a1ac7a4d86e3388e8371d54153cb84d2e58ac902cfa96113c3660fadf1f97102e50851122122253427b466bc2162a24490a59ba59b204b9a0f6ac27ab49bb49b6ebaa90673187fdb80e2908d11417b22f4dcc5211edce98974ef7327826b671f561f57b967e502276d83b96054dbbf3085ba77ec6e4ffdf542cd9fa04914cea2a6a9ef3c14970aa50ba32825363933e2184b70bf851dddad42db608b401197fda461491da73c579fcfe60d703dfde8256523a52765408ca677946715b397d5e95e2ba5fdfe0c4b07861b4979ce4a958c92b4981e963c2f8db2393750073bc8e39e061670ae6f9dee38b4bbf0a10c94354ffbb55dfbcbf40c02d2658f4369949075b3c3c77cd3cc23cfc833cade52a55a157a812cc4407ea02069d2698352ad7104ee72ea7ccff99e99a335737e9b019a2f2054c9459572bf302cd334d3c6715d773a79dec5185b5c9b4e2cb9d3b8934da60c732a4a9bbe6df70c33f000aae0b1955918a350a95476eebb1940d2aacb0995f09c73ce39e79c73ce39e79c73ce100878004903c8620059b8a2d8e4cc5893329d5c03691bed2888d4c2d3b2c52160fa4c14b0eb027569df6c6b0a1e67bbecc106d43c8b68a8ac9c89fd339465199e3fd92cf29908984a4c14e8e948a96bcb38203ff43d403f414239a89164a03e42593f4a4c04749780095ae94989e9b2eb315d2671a7069776023ccf812f0bf9727f06f945ee3bbb9c9a74ab64350a151f8c7ac2449426584481018ee283094c677d8655c5a8512c88528226b0962552141c8ac0599648513ee08204df2c91a8d8f27ba92042bef7de7bfc41c1aacf06569a26c5041c53052be12e8a5411453f60274f309625121544ccb4302bbabbfb24a594b259df97659dad95ce70dd2dbbbb9aa4b46196dacd302cbbb55a294db27677d76e8e76ac96386bad73ce6f62ef86b2bbbb7b95c5a35e7bf5346d2775cc30f3e48aa8ed6abb7531796ddf1475b57da379269b0164d9926fdbd576356d19aeb65f6d6f1cc675f7e479adeacdd0d9759da4b66b77db15a328ca4bb15a28d6aad5c2975adf6861ab696816b62a76b5509b8b87bd9384f9805c593bc7b6ddfd7d184b29254c3757391b49b0d786163a250ecce1506f284bdee75ae029a7ada3b5d6aabaaf0b96b2dd19ad197bced91565ad6926cbbecfb31c67e5ef002123d775d65a6b378fab310353c55c8d1968594d612e9cb5d65a183064791b9ed0022c431966b2bcca5a185c8d19e4d15a6badb5d65a6badb596d64862662f4ad44842cec4c4a081ad590c4fdda9a6d59c73ce3967b5b79b0adc53e0be569c3d754a81db0877304e4d5c70a88446a5f09592355db806b4916d2fba452971ccd96da4db48779224c22cdd4ecc264d6c4da249b5496240a5adaf6c71c406d6cf26a50e7b9005e9832c4e89a3bef3cc23b8b5d2ce569c4636ac5ddbe46677db1f8aae9de2942c9b71d2b4327d9c9625176ef23bc1e8c0b2dfdfb44d77eef2386de35d5e0b77286b488b06786add0a9db11614784e9f157a3ab7387fa0e0f9d3edc40904349db8d02e93d87a02cf8deb5e3a18a793a702f2c30563d4d134125f7643a1527895511acbd2a0407699465713331113ab8bca033abdc07030df06838f6fc555a9b38a01c25152d3b6f87af0712ed1982cd3ac8420273799189c944cd2502ae4a492291065891fa0403132a9638616248e2752869c31e37dd36ab5b089c9c31366b819a9a3e78db9a36db69b6c686bda50a0a69108984b1305aa63b491a7112acb24a9348da61112782a914cf03cbd0dab2c4d044c29240af45a64fa2b990a234c2331065c7d31b42886090f528ad4154da89ca85614bdc008aa0bdc5922512194046fc9b244a202c9eb6bcd82e811112724ee89124e4f38e14101948a0287cf6ece8944050e33354f737a737227cf9bc9de8d1cd94bc109aff32e87c8deab8714c516d9331aca9e679444f68cbcc89e1447640f490a25646f0a25b2370513b2f75397e33d9fde7539a7aeeb3a2894724703257207c510b228d727b60dca4fdea050c9dbd1e701909ee8a199cc132c32f67bafb497e34cb637b2cd630e7b00ab007b59e58a4580cd22b7bc6af2387da0b0493491ad7d8693e041b6ff9064fb2b8145b6672d0144b66f2d3145b6bf59628b6cbf838924d95e87091e647b1f3f4a902d52135664fb20f64378e029b2a20705d922393185d648a4273d0455c18194c40b1f656f7a5bcc8af1c7b2d29af327ab1ffe9090c82200150441ca0e47d0a1892dae6a85161c9ceebdf716a08a29aa201d41050917e47ae9e48b5c4f802ea77ead5a0700040eba10c1132c28d2c1553322e48a4509b9d65a6bad03e872aae9ce5c9142be509844c94113219a10198183113f988113272670c245be6f753937092a8081429763391d32908111b95e005d4ef581008a38428a0c7af23d0e298ae8e1847c7fc30a114c04a0cbb959104d412222887c0f802ee762acc3aac75dfca0d65a2b4d9753ab0a853ccac44049be3158220a22dfb3ba9c7b0512f2fdbd8d2ee71a0108971a5d8ee56090c41012723d8d2ea7e2eb92efbdf7d6cc54551d5a22d7cb255fe4fa13ba9cfaa58084a22d8284b061881d5cd7ee90ef6d5d9125592d21e4fa2aee208a17282160090bf27d780437449600bc00887c7f6fcba87281109e0cb124dfcfe872ae0e5c2044bebf8c2ee7c65851854d140948018a8c22ab080154430826941c514285100ff9be75232425dfe3ecd089d1e55c2b39660756646e2411ca5746be484968d00215b4c028dfcb7439d7638295148230ca970547588025df8337075b9c085d71040727515cd91082104583795521b3821d6a561045beff824841be8fa9b5d6245831d55a6b5dc9c000e5fb8f8b201bf2fdd7e5dc252d304034c9f52f5d4e8da18206f1f0f0f0f0726566f2bd916f8e146e952bf962d141965be66bfa9cc008f9bede674052f23dfe807c90efef830cf23d4b07a41f809025120a9ec8f7382ac8f73b74906091ef7dd01a89940223f2fd8f1df23d1024152cc917098810cc9e9f24d02075efbd5755eb0998e8c108b9c644e96105a9272650cad75b629ae00453f23dee726e9623bafa3caa7424e1c812b9fef4717144aa83e245aee7928065c346252022d79bb01458b0c0f7de7b65b6b6872b46b57d3d0a95a25d25fe6c269e364e7baf6d532ed305a5927feb0607e76d83f3bf08a7a84816a95029d449ca191e6cd9c46aadb5564beb6d5c6dadb5565b6bad95752d65d548c2ce9b1a4948b9699a1559cd6a56b16b9bd40cbb364956b38a5ddba466d8b549406024c3b29b558c6b865d9b24ab59ad5992ac6615bbb649cdb06b935c8b65f55aac89bdd762496a766d92ac66b549939a25c96a56b16b9bd40cbb36490f3f584629edaa050101013596654744b367f250a2a9a424e716f40839261cf0ced1907b2f965d4d0b92350d3ba6596c5af98ac874ce9a94659966aa5cd63180e6fb8d6b9d1cd4661e1d8d01b8d1a2b92732da421d6a8fa21c1dcd4b6464c52a8e734b3632d1a28ee3ba9cec5c8e92af69e895b26f5c37b16cfbad8e1193b74b746699419028d0df2dd34aa65b481c944849931247bfe92a04154607c30367adb5d66abfafd60af3711c0cedd32e853ab9a85258adb5d6aeb5d2e66aadb59abefa4e21ccbbf0e338ee30dc878116e6dbea0d169ddbeb5bdb8ddcc5b54b4785286dad6ddb4dada803f3f108e1b6d03e7d9f8a39190c8cecbe10260cb17cc3cb6f90efbcbb84a7a342eda9109fce6d9be9f5321d3564f60009350dcf4f1051103b532d45c5a0f310d335ed58bba789e0ecd9aeeeee3689206632756b5a6babeed349a34d3b88f7eeeeeec60dd35ff7edeeee1fdd4d6df76dccc36ec8a4dd0b4da793e9a76b27d38dd156d3a4dda03426f13594fd6504bb4c6fd38d6097f6ce3aae6e6a2dedeeeeeeee6edadddddddd1747e2e8a9996e6790384c7dad3beba6f4989873358d5efb55dadddddddddddd4597a27c70ea8a17d915503613645d98b04841deacd0e00a29523e71850d04b0a9b42601d93e7b72e5064b0003e8e028b70d8da01818612af02c42cac1d192d1927c7f6f7a22073b80f95e1bca8103a57c9390c30a1702c00110f91efbbee6e1e1e101aa8debbffad72b9e34e10a0c7f35c615786cb57eb4ac8c52c9fe7639764a93ec6e4c2379cc916f9550983ab92546cee33c726792c9642a4185c9932a47dc8006f9524142159e7cabe4906f1523c8f7064de47b8327414248556cc95722596145be5656f07d2bc01f567df58911727d7f587a3afc61d5476b20451133146459d6a22d4e0a121db4a44dca103ed90a3f0099a4184102ac6627006a1a29058a11acd08394a3134801420e4ea464e1e1c8480956f0e1c80713ac00a4e508063aac700223cca4455b18553191a2c413aa1f609ce51429354082942b4220054baa0a295a9c404d391ac1eb6805c7e28b1b2a5a3333151e54262aed16c2b6daeaaa75a956d36af57df5ae13c2e180887a400cd436d3495110060ac24e9877f08bf92ae65cb85abd7bcc2a833978d014b3fa74489b979196ab7b0f76719fa292d71c3b4b9afa56df087675c7b28ecb06536859966119a6cd98d5b1cf307968904d904ab0b7624e1613b302bf556e86180bb1508785c81507912b069238ea05d004b631ffee637599db90e6d9e9c4f82a2624b27acc6d0d22f3c3879521ed31e176b999e5ef30e7f11de6bb1579c01c1477e8618e43bf83dd57a126e60ccbb0cb9d70aaf3509b2a05f28888cce99b9e488cb78d21f3930f7c14ea2791083eea1d3e8a3b3ac222a8cd2ce312f02177a083b9f8918e8fb6416901fa49924a7249cbe441819e96b69940415a308f0e7683e960a6cbe0de7147851dc6f81ceeae0a890cf190f9e94462dcbb4b4844e627d3410d87ca9814ffbc8e80b4e01f7c0423c9f5544bdbdcdc68b9d1727363758e348eeb4c22a89dbe752168df59f1d61e75192fe2dab6a34d8707e60383d4f2da4cb6af802ee073e781cf893b43a6cb10776288def14d220fd43b714746043511b4228fbe07f2a03f9dfeb479a1eaa797c78430609e618c5ac1fc85ff82f197cb513e800ce9c1aa9714d639795b747c00e178b450567da5411955015d05d42b4369aef802c1a4bf3d2d57bd11ecea5fef357c1969b94eefc1ae97270ed1809d0621591682737d873dd8f53a893d77d51bb9ab6966391cdc7c3fbd387111849c4a79f726ec060a522911ec64971d87d2199a4a51fac944c134c651347e61fcc2fc161d2d612a1e2a2d549d46e87299ef338f910abfa3c299546ae6a97fa999c708a76b9bb2034d220ef541e8072182a0266a42c2f4f416316926131309fa827481e22be634ae9d5e763498aef352dd45073c3dfdbe99cb0edc449d54ea0b4d31e20bc66988add7ccbf59e33468d8d0a1f942a2239c38f111117dd8957c8fafdce9badfbdbf918c78c2c799742d3cf97e0211614433c7a1da0c16521ecabad7b86f93a3b1f11a31a18d7f618deffb6ee3ab71302472facc65c29913f14e833bd885d265c3077e5e3e1b5126da24263b51c7468d6b349c44481cf7369c454c14ee64a20411d176ecdb313107e3b09087c4714fc308481cf735ec3169ee5bf220dfcb69805162916f9fbcf7a8f7fa5e9f88f77aaa3389e6119d1374a1d67e4a24e2bd3d3123e26a5d81ebfbd6868d1aef4efb76c2c57322b8bd473d8df7e8cf3c6b1b1ad6b16f5907baa052a95c5c8e851a973acd79a44e23ee0ca5ceb130ecf5347e0ac14d74a19e463d0d90477fe6fd996f36c298d708bfd308653e13823f219471318cf187ab87e18c9b64fe8a713026e6b3114a578d50ba6884d235134ad709a17489e1ea33fe7ac9f84be6317fc5f80bfcf710fbc01833626464ac5633680201a95c52a8ebbc6e38cccb61c80e877ea1c47850d6bd7709a7118c705a8109a7922a944df312624c74a94c918cc61862cbf0860aa56babd8f3b048843bbdc7759e37c34b5dc67be0cfc09781539e086e3264789e0c4fba304e81312a182f3231c0548c8631d6d96f93f3665c4638e3a950c6679703eae0bf205d58c6f16734c185c59d222e19f742e98281a5de033fa54a9d66b022a8dd471fdf07bd77da64c8a0e105e97ac5b8cc410dbfd536dc4fa857b1cfbd07fde93911d44417f03deff41e4a04adc803bf8f6784aacb0853c7e1cbbd10c66384df654218305c7d7ff90be63054aad48c50ba64c4c0aecb577fbdbe544c0a06cc4af5f2b9bcf0bda750c7a12714f63aee5404a348465d78b01af6fbdea494d8eb0b610cf517c3c6bb60ba9434d5625a835594ae4a69e85749e00f1771dac5a5f8b23bf71eddb97bdd390cded17581e6bd9d0862e071e826734cd7ad26d00cbaf77e9c49aa7b552e40da665e252077f64c1ea07b6d035f589d0b633ebbd9e9bc6ee877bf819e337d87398881a1746d5401dd5d9a7b56dbb488d3ad6b230b8c2375683aa60d12c7fdbd6bdacc0f4c9afb9b4a4d1e937582c70964354cd459695207f6fb2c6da60f92e6fe62e20492382e1026e69854a0f73250d6fd15370134812d0dd5ae56b6d33e1f3f50d08257407fb3fb19247564190402ef910c199036d3064973efbdbd17401398bab03a781f3197b9ec74624089114e2019d0081715e50beaac565d4cb80a890c61b2c3441e74fb42ef30e1e92f21ea30427c9770bb2a4cdda47d3064568552861934899aa6681e4da12d9c404d738300a1ac234b5d70d8e44ca62da874cc18aa8a542a4423000000006315002020100a874462a1582c0ba551691f14800f6fa04282509aca63599003310a2165083184004080001181991ada0601fd82634adc2824281203f473de42304f27d11339012eacda6bda324f075527db854560cd2a2dafd6ace87109a59fbc5d4644c52b48f0b9ebce3b084059fe1288dfda16b8b1e8d8267c4a0dc133135ff4abb014e23c32e9d45ff23fa2640984400bee8a8d9128a6cc1d82caf4ce3417545e2218fc336ae83a81188c6d94ce4e0dc1c279edcbb3e92c5618edaac168af66c644283548aa99c838aabed494cebc5f5540782f2707f1928eb3fc54744fb0b57c4e7faca1d6b72c86e4656c892019a8a38cf884415589ec814a06cf0a0d382bcc013752ff51c64ebe01cab45c3f8292154fe191ab0b94605c72adc1f08139bbc166d961e2bd6a5b4aa47a774f94f0dd4408b6bd595a29b68a30ca9eb51e8739667f81f2bf67f5617633dae1f3afaf4b871efddf351b20b578cad1eda0b933965a915d86c620d87d3c27c63aa7f06a1c0939d70428a358bb251832fe6acf840d47d56933019c0a21177a1cde1568ead435a2de0ebf8f6811afa61b28ade96fd4256e2ced26918f4bcb4b7a150c85a4f96815dcaff0a1626f4c547226131ebf6493554e9cf09ae507ac54c3bf53a7e33f54740d4b42d030cca261919468fc7b658fdde789209e8b2bd1913774feeadcc9fb51ed6362b9a3320d33b91ecd29603688994b3be4648c728f8007b948be7a66a06b3bf34f8b1a5ad5be075e86e670abf38fce4ebf8e681f2b891b8777069ad4471224663aa0bf1df263e4a9187c5df5b964a49bd43a4888ee7a70cc2c1d9132decc2e4ef97f04dac47eefa582452f575f1581b64bf048ea766e04d246340b32ec81c91b32d20478f1c5681951dd320d3d51f1cf3e416951453c6c40eee16220b49b3d9177fd292b94772f6504cf4d7c01e33b557229dec5ad4b517b7af946d2ee0e0681d91c799a91b815495597dfed5dfc1cd568f925ccaf0a33acbba12d1fda020d555248c090214c050229ef137189822c6cf2c8c9c612388a477c1df0e3450254694e8fc1dee0df771945c397bd7bc9a4590334f266ef45070a2bc4799c7484d8750cc7f82158ee9727b2a768f83ea2f45114bc82f422722bfff6bb3673477ddbd5d704edcd1cd42624b40e697c1b4b3a3adabe3ceb89e16358d8536204716e62daf3c2110f53b3fee5b33a46c91212813f96f75b6c05c7bde29068e3a5f28ee9ca4215d2dfa1a96f900a8d5b15a6a1ee834632ccfc2c9116764d70988ebf49c65d271af59b2d5971e75ae9cb796fd240061cb7c1fb21f09ed595ecef54dca0d29441732b7b64c1cd989bc1b1c148da8d9102cf6c9dd1835f4eed130cd573d56f2e4c34bd2ccecd37b8f32b0fc497d23ed200c30373b98e6a4d1f7b4fea77c28354d19bd8722af74e8df654173f7583a8ad011dd873e763d9a6bbe35696f50d9eab7e3e13c8bec6ecf4cac3bbac32ad96c6e54a4f542f5669b8927574e28cef24eb4b3cb1d5ca907ddee314a6a10b45ff1e7de2ef0b408dce0ec1d37d14b37c9f8ba36d2d62d70a8f62a420ad12e2aa3f7e0f50167001cbc536b9f7da5a06b093f89196b40085d5a432fb7fbc0e0852a259b20322ecad870095da9602f54d0475aea449442b8a7540f59803ee68880aeecf026927ae861628775f2342f2bfa6449d8d3bbef9f33d7a881d411445524397914a95c0f24d60be552265ef2b76b9b8d085d2421a0c78673d92414a0f75fc8128b7a5a0459de5ee38cfff42d7264a34dc1e260691c4fd3349a98043b62cac9c6e88d928c7680102105371e92165c0cb21caa201c46e90eab6a2194e2076e3f76e92d9cb33b99893586dbdaa7916f7dd167ac45b1a7fab370e1ad2c5f528331f1c775162084cc0a87ddfec7cd982215a6b26804365b067a9ea57466b988c358052357d1659cdbfde2410d36105643e6abba3d094abcae8421181bf92831028c50cca4b334667b08055af137f48c1c037078caa1f78e1bce7f1887fe64ac1dace0efc6d52f8130145cae140394648c1f659828ca9b02320fe6caa1a912391b635605c45225400b42a5ef72e279ed93284e0db4188d035dc1dbd0ccd000a07a5975d7f6dfffdf6453e0990693ee1ec91e4fbc59047c2d8a8af5a373dfe0058131d222c690ab0868d4a6f7495e4a133382d8f3e3014d24229cb45fb84238a2df2c811e6b7622ff615acf0f8c63297ec3b738104831462d497d3cbc0465f8fbcdd88827df6e25bc6393ca6b8df87c223e8c8a763b4fe49996367d495ba31868652b2ffb9f691b7afdbc5a8bb935f99bb8eb3bbd336b84a05fa8ba1446e98bd75ed0095abcd90fd95c75e906e9c6aed8e6e1080f5c2c603ea2b31abb49872f57dfb4dec30e48b9197833a6940135a2661d209d0e0e24f69457b507200bb06c4dc1be04a53f52e34cdd42267931647bbca22a40dc227ed7e42a98aea07fc213f64481df03a848d6065041ff2956feeda2d4be27f25ad5231f0622633e48a8ce7cd2ad4e20aec657e75091febef9f4594a52bd76b462b73e9c27e6e6c1f372fa5e6ac7605c00610bf4b607f55c8c8e59d97cdbbf73310ae897d89bff334fb63c55142b6728a7b8ed09c4c5f490f93f786e922df93b93b9a453eacc0b76c1323a3660d91b1fa10f096325cec6bc0c273361820517a0404803d7a98cfcb0e9dbc2d46961263c99e7e8ef37a6f23a71a3cc7ff3d4317e0802ef43bc7e2dcf7775c8154c180c795330f2f601a6e8bf9f430c61e389d36db628b829a860aa457f0b0e7193cdf5c44acba9b1ed4089557fc8b70c18bec098192252b2ced2f195904b14a121f4447a83c98614dd2202e2d2c4e58a10ce06b0f181dc80842ced673ea4878bc4b793fb6f953750bdda4591c1fc4e479cdfa33f94b4ecb622e3a24941dcc5931b64025f2e9523d926bd2146ba40213f98e0888e0e94998ad6360b7d4127d878d1cd01872fa448dd9466a303ac71472ae170b2d1c28e12fb07deb46c2cf46d2da822d616ab8dcb253efd62f2e97d88ccb95d13c1593b7b0bd1b2d37bfe88860f4d0fa92a762c57faf4ea3a17de0edfd73e799d0cd26d0f4fa6eb15d12a0f392689bac1b8f9338e6be46e9b02acd6d48424298736fe255daad5d2dfde3765c30d1a09ffbdde2a466fd2a05d83b3d5ce97afc3577354dd31714d8cb2b5a9bb98bee65d69ac1a9d13fd240935e42d48a57aa8a214bd2984e6d7440046627aced83d0601767d799b7476824118b9be3454a3f863db8fa252ab87859fca89a23018ad2b8ffb18dbd68d6aee574bd721f129b31feecf810ebe9d453ca54fe14c69dd4452c11481cb0626da7ea018035585fd51eb11391ffe679154925fcdbf639f9cf153cb6a6f3aae714fdb67d622544fe27fde8bac0a88c1bc305e400b8326f23af6159862470647e7ff0e755acbf2211929b7be8326a1d0cf5d01337e93d22aef00bd63da977b7a905650e43f815066f411088f7234d5e0cdb397f99778a5147fd405787bf8a3787dc5f71328dcc29aa1d84c3c27fccc110992201078264ac00e650feaabb52cf6ca22045425ee4a6cb284d0c422ab4ebe3873e535f290c94aa2d61d25b8637b5828a7f4479bfe07139c391196815632baa2a5c99f097160ec07e3b97dc312adc4bf9d2a619340baa0f1b9958bf20ed2ca8ea63135e3077ea171f681fa1c80fb2d7ad9f706948b22caf19281b7b999d3e5b29e17e608c6819d876885b00859fd81ee885b2d172f277edded648e22361a77411c7a211f1e660cd5ac40c2a7cc84f97e0c13da92b88b1ab8cadbca65c5e4bc478790c416a0159c15ee86a62747f4126f632db1a2f71f42dfed8429f02e9581e20dba38280a9a5d402cbd139b63aa5b124abdbfb041614ed6ad9bd5fe3fea28bc8337e7b7fa60b864f9c49e567a53359b172e8ef409b4ed0787891602818c81405bde68fbbb0a0c95bb5ac22efbf14d897891fe472ecc5098cb83c796d4f02a3d95b2a63ba2ba035a807f963418e1ca3e3a117707926fb579ee71ad942415e6d24570730c3e058f60879d99a47d0d6d4f6b04f9421282bf1e41cb6953d0a838370ba42e14559f32ddaf30a828db94bd9956b160e98af56aebdb02d5f6c84180a31a524a6d31dfe83bedada17bd0590e70df31f97bf572ba17e0fc650971ce86bdee28de19181ef3a3ea8ec288f74e10c2048cf18214e18d30c81829e0d243e8b9532ff38b3c5f5d2e35e82fd4bb22e9c5f234c53ded9014a1b09b75549b9fdb1a86c21bf5d1830a7c5dc851337def32153af699b38d48024e912c969782f530bd3296538f4ddec4bd0703573aa0f2671c365de12f97b4cec4a4b29793c7be99038df64cd6370d045efed2807c7a075747a84adbbf7b233683dfa900959805a1da6fe1fa4396cb864fc4e37fa8f62da5c8a0e33188e1f6093bdeb83c223d1debe91bd6b10f2aaf4c08af09647638b130b719340595e06c3541f6ad1f172931855b2a7cd84b0304c93effe1d9e014063c00c809089f31a90d7961ce422191a534e0d371e264f5e4b6bd295503ce5fbf6025357898efff21ca739dae1aef29e0b1c732b4946e94d4c57db1d0024e0815094e67f7732460d4a5ece0674960f2b3e529d50370a0c10f808100ff10823b06c1c8d2085f745ebdec7cb4c2858d02107c7425c28dff607d8d1965460b54b8d6f0472522c854153ae784451c67eccec0aefef0d6f81b52408d63202ff81261a8eb420ffe8c365f6573155669faee76b964065edb1570300a203ca1fc541a81c18c9ae97f8c190e0683611cedf632fc69c3b545b0320b82a1087140715c8415d0d4803115ee823ac205ccae1985e557031c087c4e183d08ce819072e16da8d33189c6b25842d68691061193c2f5c8e8bf5cb40383cbec5f441237815711771f34b07f590512dba74c310eec8687c79f6ce99c3b43a3278e6168c0eb69274ef8539f290a2ebb9faa2c5c0d5bd07ad9862edfd1042e844e84bafb8c3bece908592d4089aa365381c8825d176c2088da7e88d6bfee49ae73c0ae63daf2bb6b341230f64aea787c2c0fc01e97eef6b7090e0312ab59b4ef7618720dc5266dad0b7fb709fa20efaba616006080635f732bedd7ed0351abe15c19515b012b6c7f4e3fc4bed3872a17fe5874cadba4807004c577cb6374cc683a0404f2ab08d14cf24522b18e48cadf09766b1a7d69c120c37da772812f78dd57b45fb2beb470bbd2012d2e23031d4e81a2c8fa278381ed54a062f2aabea86ca3672632323e81cf6ec0e08ad0db115293dee081c0508f784f4ae2f4e7763b27c53312d03f8412eb4ffb6c9c1ef441d9e8d0aca2a4d022daf369c3a53e045a27fd1eb33557dce3874b917ae16a6559f63bdf2ea186c1a91de975aadcbb1251f1f4ab0b732a23e679375dd8f398c286fae1cdf61a02d7de1a00da5c940f35244710ca70c86582a8ed9f37f1d756784c8188477f20005363e10080a0c7590bb91aa3db5856b1b3ca33efacb48e9739c66506dcbf315f3c9877aa6f33e94dab09ce20e55b40e899fcf41c795236c3f0c86c7fa4c439d525aef85cb1489a2fad2faa5ef4741ccf5eb61ae43b3e470ef9258c613511e2dc41aa4bb85a027addf106a13a8241abfb0490e81a44199aa9352568017dca71df1986512be286b46e32b7cc0ce601dbcf3106a625f4a1df467fdbd52cbbb71b5d47d859ee403739938f5da80f42d45842d382352d85f2529860aeab45aa5235cf7eea910e586458e645cf97f834af6fd021883d62bec600f72ed6ad7c3909cc9f2cb2d016e256c8bba6cad365e8ba5a926b3690a61bfcb2005eac33a61fcdd0a47d69834870620db92f8528247ef39b0368ddbac509ac725ed1bdb5f801e73855b4342b27fbad3971851312176815481ae499e348a88690b595156f31e8ffea4c8539b404de85028aa814963985072034627698fa3b87b1975bc893eba49440e52208069bf613450dbbc610f253fdd1a63839c506d3f49aff0d66f1a7375c8531616e0954050ccdeb98e092c2d916a1b44dab82f62dc205717c288583ab40efc71959b9d095c0a93e85a2cd1821645245c60d93a3e1d0ab4e2416daa904a49c1fbf983eaea916eb3d3075e2a3efbe9571efcc6da265759a8b866a76ccd1da370f72c78e0536b0de3dd7b9122f477c6382b90ec37ea4740c5161cff3ec99f6facf5b2196959b67c7deabc4946bef553a317c92ed24b0bb76f146da23ac83fde5ab4ba35d73785b55100b39aa2b4b8d92229da926c02dc45c9caa2ee98eb911655a1b6d98e6cd4e483b60030795ff48664e9222440637ae06c55c14ba6f3426434ee276761945a77254af51badc37a19fb9b1ac0442dc756be51b354dd6e52613e646ac75ef7cac456a51182e9cf8ec55c1493bf3f4ec52792040dc246af54b8524f5c24a4b6c40a9f15e268672e9b6531ef726495b355ba35104fe804a6447d2f55ce89c45c24a9e851cca5ee93454b3434584dad10376c682e19a87a499483022dd8fede9330b1c17d04e228be075d6d69f80e1b0f04104a34e8e8958e1b88df0580df1af1b0dfbf5748681e6ce861940e63ca063cec7a4fd1133e2e9e841a6245e0681e466102785fbc372894bb03b51ddcacbfdb971ae806574bf7855f64b46a4515227f72a18b615d86f03d77c782872700f667071bfb221c52ef0fd04e032355ecde2a30222716272bdd0f63cbbc126fd0a2283ac8e5063df6a18eb198ab71f31430438b760c12400a36957fd6410eb2464607ce6079a5a6e68ab53085059a86078d81d0c02124f05948449ae5e081964675f16996e49d832ca4c4ab8ba984d36215cd4979e4789a7f35fcb3e8496158eb615564a5d7fc25466063b6cd232c88d3c502515479c9877bf1bbac02afb351e86c4a58a283e0926866249755a6fb43168dba1ac8f48b3e07c5d562c3e466bfdeb3d8a73668639d1315d99a8d4bbb50cbf802a5b929745144249ee0ca8f40ed469db8021f05c8528634f20aef442f812b196c811a117a7959a88ec8d698a787308e8abacdf81a5491fc439854cd54ff2452e576cc3166baab65887e3cd8fc9b231299f088daf2994b1529a502bb85370641d3f3967784a7e70506c2227c7159aa06aec3e8eb33d0f2db9f985f409e2578e0e1d3d7b11eaee9529e8e5d1d03d61eb9a3e8098484d543b554895046aff22c2cf177153006a98c8dd86becedc904c90e3c4435f7c40209a55eb0263c6db41b59619da67e5ca0e7bc030681cdd11b51d14b9b004cef65bbc7c43ff01ac6f5e6cb58e7094ad3dd750f9412285e593e8c997642dd4664403605ea60053d1597546c63922ae4130f738f31f5c500f583d26a86d6e28c9199b0b443e384b16c2e5b6c170a12a8f369a12e8a2e773c45b14a752d74e35613496b1b92425c396854d79878b249b63b9e067eab1b0da87be0849852ab9c405f92baced4bb97c00bb3807a509251bead6467afe018bc65d7beff41904c7b1ec98141742655a289044d2a551152a9c305dd9e44207a1eee534a02a7017565ca15ca69029abe066ce045c7db8861c16da434a088453414263631e58e527f07a94e22bd19124868f7ab6969b075389d7ededd54226765e739cece81379412d342673b105a8fbd2f9316d55de431197094d589ab908cc11114d06369689c1aac718a280508fd007f2de5a4247b998598f894567c3fbcda8751b97dc1945a7dfa29ab0d217efb55e4bbe581c3d7ba8ace3c11cb7fcdfee29deb705795c7cc23c78f44446488cd94ad923cbda241ab23409ae6559e7abb98d828a037f55d6f024e5e33237b1fd62918dfaf461c98fde26467be9d1f659d2f3fb5117ca971ec4d479a2d554cc8676a826481433c2e7e72cf8506374daf91e28e953fad9e16181f1d040042597220a07d41d241b2f56d920953f76397a7d1833b760acc1a442d6d0ae88c25958e083d86c737416b7465035b232546ae119689550fceb0902fb9bdb3d3919eebfaf3c5159fb30f37ff8f4a8a9125e04d6cbb05f7b3786f778afed1daefd9ba8ae175df0790ce911210ce283679c3c1c08a3594705544724161e23c00508ee21c8e0c9c2e8a3600ecd0458ba5c47eacc35416209b0fd5ac607f71a486fdd13a0a3beef801a6a458e7398a77355c33df48df0a037a541b69f0327a938300c93566ee88643d6e3acd018aa1fc117cbf3a5eb5e43d9dfaf4fe5b5348d8bcedd7720613380c8a58b14360e00d4790ae316f7e59ae45893a1140c8f45f9ad6f75890a9a9503795ae77c51674ffdcf823506b2c48cd4a2141a6b300a569b1ea9a47f563b52676d1c176e840dfc9a9d9219c10b952e8ac00e49a54905645f0128266c5489fc447686f2a3a0205c2246168fe7dd232eb971cd9b7677f554de4995c17647e649e3e6f6b44522366498fe32bf251a038db83255ccc61ab9e0004db90a6b78b7ecdaa317e1200b24200c1ad23cce28b0064685d5d3390e8d927d9a7041bb98f587a58b506c35440d77c613135321986fceb92b566d806e3bd79bdfd5de1c26945d97c39f0458d1cb1b6090977f36f632cbc5a187a5ca396cd6fe1681f8ab22e6d4094fa68dbea28d7ce3d21578ca0ae4bdd359167d2d7b4f43af95bfbf6b1f87815b8086dc606ba158f47463a9fa6935fa324a9bfdbcd961c122d744d0350f9ba824eb72675484de81c01ee84f2561759690fe5fe7d61954f219dbc2832ad1fdab300773d27ff6d4fa6a0b018bd0f9c3cbde52a0273316c4eeafa4f1f033d2c9a6767d8e60588004563bd8be14d4e0ee9edf5ebed5d67288258d6a4484b174af1dd2c311ced6dabf900e58abc0cd9337d994385f9ec1ba98b488194a534aec155993d5287c61d639235271dd50e8465f394eab49a7aeee0a3751d2861f0199e659d519e2e06e30b683185f221a4cc6a4ac6482270d584c5a0fb1f95d60a04f56e4537c1dfdaf04587893dd7307dfa4db2e8a7088c18c362539cd18e79782663dd849a9b40809f0f6ee6a8acfb03f8f77bc1916c5a0e01c6f0386f65e9675f35db96afdedd554d05e4474e5435572c62e823afc894d5850c894f352780fa75f161eeba5a12a2e6abad56a4e3bda768573a2e44e4d4bc6d584db1ca4407acac2a3c54d3c95ae8e05159f32e862bdd11ffd6d1e46004ae9e67c419466186dcb431d4093b31fcf677de1151fdb4d0f397a20dd7182b39f4b7a47c6ea0f3580fad3d67f0e7b38d93d285dc9d4b856ca4739e196d844298f3310e594479a95fb401d3a38fe61bf9dd206a303cf6af7a8c0e55fbd302ff1125b41be4bf50789a500698e23fb0afcf898d5d4066a0c786cc301f82586d1a73bc09bd089ab3dde2fc2f7fd24c2c97b5a707eef90042417c3fabbcad05ec42f9143e1c5225172b775aa2a84def827f0cd8fe3702ebf9b35278065837caea1ede4c46fdffb9808c8cfa9fd3489d6c8ad91061182baff03787a116f40ee87ece79d8721c25040a905a3d9b4e70fbaee914df7276c8be7c1c3167629a909436bd717cb9bfce11382e1512e8eda9ac53ecb3700bf3082cb736405c1074350c795ebd2979dc92371015e402df2656bbb003458162db40ee4533f3dd93a65777ae6c50edae9456b51c0d6842ed11ab6f05c12c43900e83ba959f2ddc97f1a352c26ea38ec9769f2f1373a4abd44a2c948f5c941d6b9d4a2c0ca9d59667291b8c18fd3918111ac6a92d54ea4eda7cffa0b4e6bc13adb04da33407f53281b443e0b6f048a0068ce669641a01f0bc31368fe864e985d76a124b032286293b21622722850c7ca49149989d0f0dd748c1a86bd3188d123be5cf781a3a567a822c7d7ea9895149fae27f846a862bac9a7221ea970476e69c5e2d0ab2aedd07079dda75c968d535db44e614adecbbc617ae6411c52c660a21a81861d44b5b982a7ac9d961496004a743b7db26a051b541f3b11a510af184240020bff7495adcfa239df36b28da5805510e20f5977fe0fecf1e19c5e8c3ed1368d4057171eb85318dbd1e2662538ba24845d889b65ba132fff166c95caac0a580102a7ccc05d99f87680ea8334352055741022d6ca21de5c7bbefb7694b5f39cd07714b8e079728be1dadd50ec56e33abeb94c0f3c0c7227583011ca09ad9995be8a86893e84fbfc2d0bbdf73f3a447a06762ce91ced3fbe3552a53f4a89a0655e018fd06315632d64540e9e8d99b8c02fd28ab51bc4833f19a3c7e36e5171e798d80d0aef70a84bdc4bd6fee6ee5dabe572e5def264d78f86f55d5681bd183705aae738554efd5a6eac73b82e95f8860dfa579babd7e5921f0e6258362edcbb263e1f67ea370e2db296958d1a9fb77c665a28c2e100be7e71aca40b3424cfb54d6ab00ddcc7acfb0f12d68050cc596a915ab0563b13d76105f55b3261c3058729b0871ef4a3a65636549918fb8631f13de9fe78a00e9c50c01c1c6097af56b6193c1bdcf62361746c9914475d92221f13ea0e74c4398042740470cb9cd67f5b56315bb0794059858233af823bf6222e1de3ef77187fb00410055c4f18cc719250381885bfa95184e2a6cf7c529452ead01bb8892fe85e9c32193a11a30ea2685b3add7c6b605432fdf222d25f00ff05fab676b2bd837f1bd47705045020277ccbd4e877f0ac62b96d8839bb49dc697aef148de76fa21109175b6d6904a5c04778cfbaee74f8651c10d4c62b3f612a67eb27e6c75e822d7a87d6aca06d3ab54b8c22e1864722e12630fb5f00c7cc2cbe53e88f66c83bf6a0b23bd9ddce15d46995e51476d2df587ecfb72aa571c949a153874848502a3b79e047deb52b113fa3d38b0c603dde66c33870a3930bd5a4ff1dcbbfa6242dfee2bda3f286623216cd866295939ee2cf26a76650742e8ae3b435644a9b90fb6f461f903ce4a5294111fcb3baef7d86423964e53ecd8b6e7688ac390176ee73111895e16c1535595e70667c7686ae80e76ab31fdb1dc5cd01f2d3059a731e4b33a9902a1fa32a646cd1d9f2e2fe00f2dba588c7c32b3400509a80ca5388fc308feb1e5ccefccbb513e093e7198fe02c6cd468797caed74cf9c3a78ebab3fe8896d40e0dafc818ea703dc31f5206e4cda8bfe46ff3ffbd79c813cf8dd67c6e1dfc5fcbd83bc586448d8bd1c20a3639e3b23de64034cbdb83909d1ff513c762c81427b34ffbb88c5bb855698f4027710f170702c33b5242ccedffa3d7f5dad702d8b7df84d57dcfa72f36035389769515bbb0b5add5e1733b3a549b0d0458a85cd880883990398676b557ad190c40c5d09b553b3b165a9635867ff309b9a582083e6ae013bf14f029add51926f9f5d512c448f82ce207789a3c5bb12d666218224ae9eebcb4ca2af59d5cd15a673634f2726c20a8d663a9ae08a8b6cea5be96c1e3c8f04805313b2e0eb4b54fb86b9578ff8a3148652952924082fed2f172da1d848ce500914c6aa768d86403c1d48b48a7948215db87ea3c2da7463a69268a6cff945a5850570530aefc0ed6131f96302f94d03e9b4255f73e1e95bc1f0905a7218c0315242394e6a2347b8c7f636cb7813efbb3fdad4adb0be902a09ee618f7d524843dd6e98efd92f0e6df4f0c1dd9affa89915ba2028abc9e9fa3f1f58737846b11b6c55582b35d63cfb689f20135a20cc887ded373fb187d502a2aed8c71dc4f7ecdb026a591ac1a87a1093838c9951682419425d2221373a162c60f07d20e6b78a5fd1f669025f217272fd1042f0045f9684d8ac15088908fd890db5ea96fb00c4368949385f1392acc18dac4beb83e32e06ab8dd455838ededa0313a6013ebb9ded9cdc32891a8bbc4707c1c3b380e6f235c79cd1d2dc3f09401720420bbe84694c13290db4341de54c68dad05814b7ba96f11e6585aeae59bb7a949009295631efe3e2d162016435e3e32c04c1ad1dad1b8e8eabcec260a7d0865fbab7c2fcd28b173e6d83e80b92f8db7de02448634bed61b34e07574649e8c6cc81cb6bca4b42e07c62d17fe568cc742ae2cb85d013839857346c46686da435a8fccb5afa63f1313fa25326a3b2a39635f1a410294797f45306058964654d0801a79eedc64c1cabadb54cc844c8b4af50cfec5922c3bbb7fc0e91adaf042d167d6f021b7a1e8335a1e9763f814217cc42933460d178526de09b6f459c13cb1105626b20f7d5a81596d51b1a703a31df3616acc9b51e48779d1fceb29cae003e0626d8533cbcfb56024bcdcce656774212b0e968328c88125dd0593b0d9aa1ebc76606fa78ccb8569bfd43d1e7e31e82bb3f755ac8e4dd27c4db0d2b45607881feebddbc6b87b160c057371a34763190acbd42e68ccd374d1e16e06f472bf940b990147a2a973139a9329d19f19ff7ed094727b3b49e5a656204dd2d2cd7088f97835d47853569161ae0246fdb592eeaae22af2d035d5e884f515f560afb860c6da17d1702be3704895394b6515a4ece2eee862d76bd38484c96f218b89ac907292e342737c7a5d79ae5d0709549286b277d13a1d12b9c39f6f04178ed488a25a674fb0b12921d4a46266152bc53cfbf59508d713b59d0711752f64ed0a28919a4e24840d90eb65d2bbad32dcfc0b475fd2236bcc24253856798b5caa257c13c1bf14fa0f83bfaa28ecaaece37ae341568493786dd4eb8d037db3dedb02df86c66e6775d301f5ed061f482eccae39aea2ddcaea380c58a5685e6fe0ae2f042103ffbc0b470b54e2ae441c4c0806d55be5346f48a438706960103c128f4c42c43c008ad115fc29bf050b494806d815e7f60a3851940d953787fe9fe214d4ad3605d52b3455288eeaf0c408d85ff93582692bbe87f7d8e2d5a633598d4fbb4107f6aa415bb1d1486ce011d88d6c647b092f7c31d21717f40941e7c2e43bb70d2040d734925f00bb05f929141e9dc53c2936af79d51d0aca82cb7ff097d953dd412ae5fd60c32030ce18a16e7110b3906bd883e159b9d5679897a26040714036ac2e3b746e931283df9171b4f66f3e52c9f4093a14fd0b3efd1baf9372b704292c64d18a0875dea3e3537c0dcd83accc22cc6db7f0d04890ecf6673010174655ae219a7867aa1d48032fbc67d4700b4ad77c2fe40be8f5821303a145e61f6598c2b181ed74bc8905e6e3d8540993c640c123fbbd273d8f81949b787f1988b3cf996ef6288786f86f60c0a888fa14413718e2dd9a760fe0668c668ae337c08c1e20019da1148a801fa36d324f8689f38926132cd2a1f08ea0fc224b3381ff02b25229725d41676f29d28e77d290f8d590d9ac8e64207c2339a8a6cccd497e25d7f67b64e0da69d61a737654099e09673d6c7f45e330dc063686a9b24cf44ef3ced2bb82f001263a0044d4643e82b3daf6ac02e7a3c88712bc3b7c3928cfbfea74ff2891a3a04c62c67c8d944bbedb5081b01c04f2010a9b6b5e74c6af0a108c7731e5405de87f76868d587f09ad179414bca77044921a03a283ce2cf412ee7d228c812fad7248990cbcff59ce1dbfa3b8cd2415a8ba35b1270603d9fff2c6801ad9ad98842b3871357168b16c264069a9fc912d3dfc11e1bfcde4bea5de357f551ce7329004bb9c1613e9a10659765cb40661ac7a5bc618d02935c675572c3b5ce39f9caf87f9d600d5dc950c799226f5c24a059c0740bd6daf395b07e30e51b4160e284382704871468ded74ac00a94cc5ff5bf456693da604cf2eab0ebd59cb3df1ac204be84d0f07375609d4a1f96c39b4a49098bc384a3358a2d9845ac7ba029dcd362c7d62fd5743c7dfbbba7b0ae6e2d258ca0ac1016ebf3b8c0a9f75dffb06d3709f64fe1da3f2f497224c4676e84b45c7db5fd8bdc41f0892e73ae790cc99c7d38b2fd27d6f04a8463fd8b4e739ca0c5a969a541aa2205f4341452e325b27f3a869e419c7c7749b33820366d2fee339e1d84bf47472802eedbb605867a9aa17af7881c6259d7b9bffb0f5f4f419b59c2bfe16829c1ad92274b5e1d4afc7896f5bca176a2caa4ddbfa42db5f1c548d0d45fe57d1b35790ccc66a19f18ab08853bf6faf81136914141278231660d2db216dd0338f18e0eb0c9774677c8bfddb34e68cdb0605ae604afdff8469d1e41370f066d2d151cff29c4e11a10f9c947222185c17aab7ea432c2b2e2f428c5913fc4b20523f81ff8812a7cc8ed6538700a439679f5978170b96c1fbf9f8a277bb76f77201a9d39a99cc3d3cf49e9a3d69333bda6ba51aa6c2c44440069994cbdb03efbeb28ef74132b6768741282c167f46ac2bbbf7db823f6659a08890ee87130e2d8290eabc84a8b46eda49523c5583d9c41bb088b7378192db1ea7b32cf10badd52dfe2ad5805459a3d73d6d945560f7050cc7e01e2f73e143ff45e898e0999073845d2a731edfdf90d88378e7e8b21ae672f904631b6dd3cfd9a225917a5cb035a8ce8560cbbc717e38988a1168ecbedbef7a11992d51ff32c12eb0cc6ad583d5ce1bec47e3bc8f78ee9022b1d75bcd228847e81b91d5924b870705f38a1f309ea4ee477f567ab13e3a2a9fffe619fc005dfc424b08e3edb0da028bd2c4c030104ad4f80b2a229bb460c82da2c0d39591357efc1e58891217d33dbcd8936be2b74e3da283091e2c691bc64224578a125a96b2c43a368425125aa011f8fbd89a08642b5a079b1cb1f59c2284011ebc497208bda0512c83867ce3e9f2d4e6085398d164d4aa01fbd8ec4427adc54ea153758effb7a1b462ca4e7805e5232b601b90be90671f874218d78b33adbcbab5680d9757756392035a0f62c2d790ce996a8af3df91c4e0cf94ccc2dac38418307610bf7d9eeb98afd7320168b90218dce9dea615469c2b06d70879745967cf3c904799b991f7f8fdede8b9ae250ac2c9188740ab73174c3386c352688ad96550b1280020d8f7395dacfb98e84b3ee343cfdf81bd840aa96034157b264cb5b6135d347ae036dee257e9147f608b8fcb041599387dae52eabe2836d91c2f2137c45005925d0e64431957932fca927cf5e9d8c25f12384ef5f2c320176bbe0fa5a8da580b48f265ad9062a3cef66e606dc9b85c9be367506d4214ec231669e0c56689f6f300245fc86b7ac3723e111328d6188252a33e21fd7e00506a42a8654752125b445fe0185b6575bb9a5cd0e336429a8e68f284f06291bda852425ed9d53a7ab7d4123d6f9211afea2709d67b94cc93de84273b090901ea7007693425f1ce634e25039e46632241366cd9468502136f307d337749972423f801bda7a5b44a1895d10b361eb162e83b0958bacacb22894412dc3d2fa60d93a37307f27d8a0f823eacf7ab7ef8009b98fb2f9d90a71e81354bba058a32e844187bd4fd3e40c40942d8eeef3ea2e79a86174cc339f9cb84473229d20b32cbecf6389c349a1e60e20da9c52de1d58ca2b9895c6009d470a4013464a460a36de00321c28276f4d69445688c3c6ad1de9906735c52b33c54646acbbb604413d13d30b7b55a299ce9913de96be23d96437cdf6658aaff78968a41c3be0ad196924b4dfb4e44b5591a58467bd1c6ac4d89c288b7ab0b37e7610db464a26c154ed6cfad8bfc691eb6501355f3400b61ce9774540414be58a90787fc2a5aa9a746f684967c18bffd9d6a9ea3ca4f68c23bda359af240e4650e8c1a13bd2198ea162dc1d747e6e3329b9a9a59186763ad99e32c4f1e83bb53d0f7f73067f839c3e48ad66b27950669698dd01090a26fd2dc2ce416224dc7349b0f71ca05778cb44d02b44c310f9985d3a03361abf03e485505455940fa9455e1b47bea217cf62654a127ab9e29febc14696b805aeab0af58aa29bb1de05b144ea96108763e712c5ab1607c7a7803393bbae1517dd67ab2039b0b4e34777c4ee8d58b6e96c52f60892f477c21e287c3a899524c7aa5b78ffe0bd892f364d285c869928f82ec28718cbf264f46ec0b8c962800bb976f864921b3e1c0692e2bb938a7057df4964290ae1198572ba9d43b782c88b83d6e3fa1fa79fcf2a06752ba524bbe5577e2324efb70a26175710506e9c72c4cde18626a1b1fbe33ea809a28a30e79baf17001b3cb93b9ac63db0d0b1f8fa6acc18f8acd66b2b4218738fed7e9eafa43c52a5c299f15a8ebc61882e9397966f12beb1f17aff21eb23e75683cdf204a648e780ef276cc2614e38e7913452b944109844fdd6187e83421fe3d8f8427356efafd8f02a0f82f6839b6903ea8a6342c6a27a3f49596d3547e4fc3e67b015f9acbff5404fa6a504cb45a702210bd0114b436d4fe89af3204750547d2949c1f1e9d9cdb321bdd0f6b1d4df37c3842855380d638a1b0aebcf405e8274bb40c9b01c0f09d6b4ae1857d69757523c0b8e10b1dfa1ac978c35c7e3558183a034b7bd2c48a142300fabd5a84ff222e97866e38f49619bfa4a48d64fa232d5bb8c12f1ff73a3b0eca4f9e39484f396c764b9e0a84b411f7d9314fd2a013b22dad01f09cd0a1382524fa2fe4c0023e341b31668c4cb842a0a8794e2308b1aa3aa3f48cbafa08b21f989f515da64751222e38940464188f7784fae83938d9b639045b17de563119cb65a568e22ac4d30246b3340b4dab44c0957bab5b0e485b073f9a77224881cb6df160adaf6c0310fc64373778858a891e82d0350ec7333a0433286a1522c6a770942fa7678f308c04cbd2dd6c6fed921d674a92bec4d00f111ba6995cebd0b33fb90443c35018c756d7c9adf5d7ee169382547be84f211c4c991f02072859fefaa0d5dab88c2ef0e395ccbaafcec794f658191e0b741565f62414891baac1694fdfe88c3aa4295fe94f98e39fce973c12c79e3437e4399d155494c91e3552db8423aad2bd809e20da4b592e996eb6e5fc93418e4306aa9ca9f7af26e05a8033a8db440c8cb1d45a262e4384e8a4e19d26c47daf376a949f02f154e6895d0a5e54e633253f0a72a0892ebb4d6b112641a85a8133e50e54618381f059cb697c4449a486527bcab39c91b92f9d0fd41d14b2b506dc80acc6eed00741459a96f39fc3e1530642e22e741180449998824092f150efc06a117ec3fa48ee68e9a6e8a04da730622acd3e10ae83dfbacdbcf2ed82298e2420f789a173bb3e864362ce29e68a8ebe682ac1819e24fabb4442b09570b9bd4e622330e4b1d120b8494d4f679af1e9274e508d24cc832ba451f5d46bca5260b2b0425e77381c8e2eda117eb43dc925b8e45a973280d79bf03e64395e960ec013a312ab059686141c0856e8cfa6503c036a7845fa68a2b5c67dc480a72183ca97434dbf908694ab84bf8353691aab9ac1589746afdce1c972de03b13c1052fb1baf35e3fd8c0cc137a4c0c21f77f92ac60c93c1ba60cc334b70b32a4cce9f07c255ffb2531c318d69fd722ede9a262aad8307166a4285e97b3d4d0fc347f3d080f09ebdaf7f234d3772c2da8f526b58bae240bd4f55e140e1fc6b73305bc7c0e57336b784da66ced8361814d768085d2668012bc886029980ac2f3989d7b63add697c8ca255e41dc3f3bb5090cbc4fb85239560d19ef01c8b81d1f8bd5c6791c8e0a21512c5ae2d19c768a1d7a3124016fd62e6d27f7f0ed5c3388ef5e41e0e1c4a82860f09f7dc1cf17b83298a09aa6dd1b329a0aedc8a6def5edadb808ce8ed27c0b4f0d84994408daa4b37d00d01ec531fc404a9cc44f674b49bcbc02361e53a1af0eb805efa02c006991515eecb0c2f9f9420a41f5740856670396e3f1db539cfa6d56f9ffe6dcdd588d7f6f724a2b706def2813a154c00880bab704e8e09dae68e7a08c8f5408f4b70e541748805e9aa83f277a050057fff12964fdf9a2da62f0e179b062469ce179caf0945bb101f92b5d175851d7a505fb9d34e3f91f709b51788dd9c426bcc58f3562a20bfa67783a87ff6fdaa4b19d1408f7860e6598fbe6dcb7e05dfa10c4fa74393926ac0ecbd0b16bcf40ae5358203eeb5870581bc9e37a051d8423d95459488966a9f27c09005ea1788608e0b5e854e004fd96a418b84f9961c0860e01c00339527614d099f493112211fdc421135d7780f6fb10cc3e5b3b309d52b4df365adbae018e011f0ab714313d4e52bc19f913977e3192da8ddf058722ec8e4b86f71221ec0920d38eec4318d918182184cce9366b2bfc287e5fb26e75a55541c4e1e05d178545d7a6ad67af288dcae4a621df1861b9e56c18948dfe7531ac117c7d29064385f2151cba9a3f90f5ff66dc4a4e64a8d877c124adca04f73f56dbed33b610a122a379cd07d856a955c1d3e0aa6faa913662a0ce22446eb5801283fc6dd74c18381a217c8799556a7b2ecee63ee4e37b9a10e0625c34b855879c5c8e24f07854b41878ca8c50ddec38361880d908d3cac62e2aa7e131c8612746f12e92d7eefcc2d3edd172eec9d35b7f411ae5e2a7765d3ac4f0b44e16570d4a916b9d66459b09a89b7aaa2027b95f6e1a11b3d7bd7d4e38c708f87d476dfdb934a8f8f5a99c224b238ced17cdd95ff50d21f9800e832a1f76d9f9fff7ecec940cbaec2494a33c32ea52fed172974158019f433776f97775bedbddf70c37c8d8cb6c8fa741aa0c13a52a2a946587435e4e6b3596f326f86d58e5cba94c3d66328c07fd0064506148dbfe8f62086cd9391c08240742c7116b65188884624fd806d648af82a4d180c3f545e53cb2300bd529a2dc0e78a5f5692c65607e2fbe5332146430c65a42079eb862726af92c85c16a59e61d4ba86a7c7d1791708c0b1b9d5f76a63d1893f16afdd959e6c4ba70307d078dcdecdc6746cf298e452c49a16c1beecce7879a5568256c2f86caa900c7d549ee98ad3d55a79891881915dc49d86760799b680a057082189d2583e9f5766cbb4fa7f85490d6e4d3609448617e6e2be3a9a7fae74b24f913f94835bb368b231fe39caf22d0c51527c123f78df37a96e2e1bf363221778bce916a3115cb94eb81b8003ff23efe347c1820b417ec494a16ca327d52a7ad2415bb650e7e11312cb3f0a273a78a5ccc978a7d7a0030a7d29eb2efd932bdeaa56c22312da8b23357be23ddd3251ab8098cc1f3829bbc15f71f81b03167e3585d274f4b870295e72b3a67befa8471c06d259636057a7fd21fd26b413f4bd076ffe3c0dffef1deb5555fe0b6b9dc01866e66b2ac4a119a02684474bbc65ccb1ddc5b82bba30dc8be9b854a7ac793d5e0e3651962f44da81ddae1bb4573a49cc0385aa56753ad61ba5a61eea9f2d2bd620273be68da02c6b8a8ce027ae4cd245e3df7bc84f7d4c1dad1112992fda2107ea68c81d4ae1a581852b22b8ca08dc6623c605f23032a4842af7c4996450ab2d698dda2d317461dcdc95c902758b63bf8bbadd2f7e9741b91f90a3ac6762eb3fffbcf59d1e3bccb528cd4477d6dd8c7222fb98f0b3ee2475271a13152b52e30c9c1a1438b464c5455ea1df8797575dc081c55b9653c244ce77d485af19d4ea5e341c75488bed5dae052bb19ee49be0d82ee6a74fb2d3211577eed127150a4c2257687a2de6347da9301919249232a6a0d0a0d20e5e73f08873faddd807c100ad45bcaa5016215f98fdc2137f54755282792de45b37f77d421a138c17a74600638539772fcbda017499673a06af6ccc0462978639c4d08d59f2654af1b7721887dd4b50dcc9384d3bc738b34b0ef4eaffa38cfed10c5fe8a647068c59fc3fcf65afa076fcf66f7640e7490b59375823e9aa45a041f6dc1ea1407eec8afb6fdc5428916720f360d7cfab1707260db006c0b9edda7a89c1dc02e0a26fc771b041e8308f61ec27e28272cc9de72303837d0e0655830b637f45df93dea25d2145961fd8012482d32d4e27d45ed5cdc9750c7f0f35705c63e4c5405910c3d1ac07e408c9e688024252226bd3e69debb05aed6ebcf681853835c859b745880c04cb6ec3adb29e7b1c93aa11904e88023c46992816cf9b73e8e4a97e72aff45573adab0ca90a937e7b67766890facd520b50d5c17a5b7ad4b61a8c5ea7d88ffe3294f10f24355c9ca73b2cc0c8e2e31b03e1480739b7d9f38750cd263a94415fa78d07539faf862522bb2b9c6ba8386b3b16e8fe1dcbdf578f6c15d116c39b18703650a3ef3194617dbc08205178e3927431b9b075deb907ae8b6dee5dd60f7cf3f1daaed72246f69c002eb6674b585394c8443a5ea25074d8b45dcf9b31ff6264ffeb8b017b58973e50ca93c8e2d32e0a405a03734d439e3fdc6b6eec8a30427fe13b8bc8a9bebb220af97a21ec8a3a3200419058a759596424ec473b1056f275339a837342f6754e2673f316f3ecfe74bcbccfb2dc2378e4bd98dae033683419ee53163d1c4913aaeccd2619f39966725c249bf3c3c771b1f4deaf6c31a2abe31feb203c2791731f6e2622cda8efa573ade394ab147e207b3666d123de74267d0227dd6f247886c6592d640432d683d7d30435ef8690ae7cce5431659a50d3e223de61f67a7d584cf41600f75aac1e1e23a81342ed061a6e4b25e260d9dae38693ac72694424c2a9a57b6b39516de0fbe06179562cbd362e78c3a39dea3856b58c728f05a3b2f6b8f4969810375210783e3da1598d7281156f7dd8c889bfe974bf0f6fa6a63ac84d69f8605dc6659ce0ace41a056c91f192c984b845719442534d1dc9401e1df10a3924c62affd09d890865ba48f28cb1b305e7c62a2c35e74dfe2d51b38d9a0e61e5fc795351749c1471dc853d744d766e01217e40ccb6e558f005a357507d0e2adc37aa4efc1c19bca040711e1b61c93a56563cb6e38967a23460b7044e2f20fe48a8fc23c2595ed1cdc59a3531a0349114c81501e1988b9c62aae564f8282bca07c45d9f2cbcea0a6f6cd36c6b13742d44f0254bba8e48f6338629b1adb87a1b6a54b7da1516850d183086ef24854d6cb337742eb1304cd20a0333eb02649c85de28acd904a65754214095721e19e4dd222a865ad62aba48aa31e62067e051fb8f4bb42b320b1725a94a699e08295574d11972324779605a1d03d98258a959dd32f318eed3b74e92a709539f1af4088052b80e922c021f09fb32bc42cc8e3747e2e21b1ac2977101f80e5219cf5ffff17a1bcbd38e41a8076924654dad44acb3d91122cb39ef28dd4407b2befe4332341be4354473cac902b3d69416fa3f53c34b12016690a91df54329d9a873129a691a275933f1afc1f3fe7a3ff9f4278c18c81ba6cd690b7b55cea40f3837ae03ef936d2b5792b1d47e52507deb780b5a0d303f009f05e3e8565b4234875c014fe4032d78d7cb0205e18b55645367ccf0d9a999aca766f8d768714ea1b36f936ba4adb54dd3256d0dff2ef0561c549180c63cf0d506b13b9d89f33a9cf042c04b5a184c9268b99583f785448a7d8fc9a490a3dc38147bc16d8d18797f1e40b48a41904b75d5dfc233e068c8d389aef42a6cf5f311d3829a2e4154f58f611dbd7faee6920be7efcb54063c33f7ecff15c259eb9c0db3d23b069a5292d1f60655c482a8d199354c81a18e94a9f2e5ff723caabbb120f249c36336f3fa0a5787c1c0b170867283ca6892228306f6ac7af173eb32a7dfceafdb252114f809ceb8bdfea492803d7fe62a5a8cc3d7c1069fb971ab4142d5bad0af3f94f96238e26d158400afb4caaa1fffd338cb3a0f4864e92b9851827fa4a6ad0b49776dece3049f6623ed37ced2b5d90d62e49f5ba2bcd744e3ccfd0088df3edeaf557433dbd0d799163b4381324cf34c6bdc46cfbcc75c369780848f0d1d03a1459c15e45b41a38fd3eca3afeed13416f45bf839ed0ce6600a21e858ac9d1c4b841229645bf860525a24fa6fb1b1c99e7e64c3b8012a1ce68f2e380c866886b857a2fc7720c61d81ea7cc09d198c047a2d0e51e0aa1ef83a4215194e6d05c83201807a9351629903f4998c15a29d1c9d454fb75342db3ebdd62a6a8e0ca73858672ec1f2829a088247cfa4be11b203be54ed61ee0c551098897ea54e19bdc19976972f96279eb9abb58d524572d6e836a04c721765b6c7c1b0e54dbc4d5658889bdf645db76ddf36a0940a09b4478bb0bb9bb70704cc392f5415291feffbe9ec86f8740c57eaf7f8b24fc3a673d83611aab129df57120aa5a67f250ff0571da7f1e1a90009ebd758b768a7c682c0c9d36d50573b2333f84a30a2079c052598584c07238f0322dc3134b5f36bd4fa141b48114fc7edaa4e267055070829c25ee87b735a16766ee66fe522750dae0eee91a08174b427a769350b9b59d2ae57928180698e03fd9b2ae96692e90490832f12a1ad27707c071d4531a02b824224fdb1306468c4a94103d33d23ea3d0d2ec5c6c07a7cd508159cab06978d386605b9fb63d7a28e32553bdf891a17f841a880d1bc850f5250622edc525d50bb101cf4221e8dae4578e1227fc6be09ed166c806e4b5f53b57f478841f175606d4c3f70c4ec67871c06dea0cd40c81e1908a90fdbcae19222d026d0461c80ac9215767b4943d7503d188554f1f8c3af6186b100d6e11cf868589e45a2e52513f730df59c9afd154dfcce1d4a72144a2915a853664b75e210eeedea77931144dc7254dd1619585f8f76de7b8e805021426f7162646b38fb86fa1ff45504827c978eefcd4c068f9d38c92722030674d0ca17f6e53ef90def4a5a82848d1200d5d8c42e5389cab9830dcb3936cf564add54ce47bc0373f863e1dc85b556a998733aa1aeb8d0ab92e8d8cea406dbb505128752b9dc5a4062baf0fe787d24f2797f0224f052b1041ce4caf44cd446cecd9c68e6111b43afd081c6f5fb71d34e8d36f2a8f91dfd127c9df514d681ed7a9e6989110f115d471d05019e27919b7e172f2e803abef38c1acd73c406331d602e1231146cb723eef322ce89171997bb3428ba7a37ae72e8807d9782647487a7ceb8f4edfcba4156e584b9ee40c04e23fee8190f6389d4233d3ad120a736ec3b53d508225911f3cd431f0699af00a79c3bf55119e4fa139f02133e9a8e0640b4258724f96bc8d23308a3d0626677d13b33da258906dc65c4192de0c13f3f48d0408eddbae4816b1dd60281f04f3d983706d6dc89475a145ed791db41bfb5e538778209e3e0716e97984dd0d551c6c19a5dbf4f861c75ca32335efc508f52e659e2ac6bc9fed345c493d3537e090b866fe1d2cbceb7e581c5fe478843ca19e45e8c1f359b6aadd715a8f5eae2e03a844229b107ce1a3ff621c82568e857c215e24c1685faa4cc8c4d1381b6846cbdbfe325c69f118d0377be13a5caffdeeb53ffc5ce2a5bded5c511e49f1b9b4566971ee4383642f844433ea0df00f53425cce70eef3a0fa61720ced3180d0fa41332d7032266e8e14dc403e007a394495c376b303cf7d7d8696d210db2d1f1cf8841ea15d4fb9941bd26d48a0b5904825a1f2fe37fbf4e21dfb053c3e0b21faf4af31a4e5072851405c50f7bd2f063867dc4eb92c79c87c1dfc30080ee2b2e92ba4ee1ada072e3dfb24875b4b983881ff0309db854cdd804529cc7836ab5f9ce39696c9bfcf714d5554d54b406500a997a55f1af7944e12061f2df401bd39d9e6d53c178e2a3f075214d2b98d695052e2142583ac62dca944ea0a74a08d701e374aaa7d8e48420b17e44c6221aafe60085cd4c17cb32e65099cda205ac53c110f847dcd2f327d0b158322cc5af8e0961149c397b9e73b4d1709cafd4401895a4f3779094d3ec6df84cff5042313ad759dccfee5ba6520aac6eacdc3fa2b9880d937e9e98b68cdfd9ec685dfe0d6277b3ba0a5d5e8d2b6122113bef2af0d92f18ab3d0fe882f1c015cd456ceaaadb459b0c16667f240afc16eaebdd8afdcfa72ef35e9f28bb0960143c86d81c320f54d0981f9013898d3ef85c3216cdd1ec5dcd89d611557f3ef0189c2a8adecc1ba492067161bf3abf9a64dd77a2ce468a6fedbf56fba4be4f746fda7efb8a96eb731e9d8be65415cf353936a3d7e244bb4ce7e0086989596447b54c879afadc88c5118ce3ad20c6334f58a184f620e9ede9d8b734f4902ca01454b36fc79df9092da18087fc0c1f40ec469d2e5bd31e4c360ae26aa2ee2bda9311a067dac299efe3777e93ec1ba1c8c45c5acdf1ae36b3b0cb98808f39548c7ab52ff2cdd65702bdb0f8c4529869ed642940ad0912c984065e1d0d69d7430f3a6683a7f78b057e01967ee0486d348945140d81f4b77c61c2c393d4a202b89603aaef32e08321c1cc0d6d75d8a17cc738eb80cce382278a169374f0e716337df38c1f69dbda2530e75a520a3ec60826d40364fc8c84ffeb7858a18874dd0bb6978681fbd14ec98ce247d1eeb536a75c09cc2d800b0761b6dbb5b4db6b973d6bbcfaa06fbb6b2e03c51f2a54e134665fc3e8c1c6a539476313487a96060184b428cdbb6f5b8bd83fc34043b799ad1a0d1dc9baf175b30768254b52a6b461fe5f640b685eae121f887c114a13e6afd78b7de3ce9436df70f654756b4fa32d50835e0e425de3ca18cb88144aaff308e09f57ab076880783baef055adb8c1a167782e28532735df38c92de259a6f7ae863926a56904e7ff6df2544ddaf1a853a338a8f41dc8ae500cbdb541ed950f2aaf672931b50531a8639672782832ab52aff6e1b892e1a44f8f653a301562f32cbc7ce65c6eacc9fb14e9e35f811e9f06d91eb0900cfe849579773c6e880adc5d91f963c06e0b2f2e8adb3558a6b289f235b1135bcb69cf3461d5f4cd0d7a58a39efd0b318427200e231da14acea0126b48390928292566c40432de6437aac3985cabcc9b4c0100bfca7dc4e560bb981cefc9a329a2c9e8af143ac58e7da723b1ae1671f6243f159c9e51dae8d3c4b9931b7426143e30e60385951bba573f15b0bf593050c671d206a10871d8272d38eba0cb1e3c40c10a1b54b060010d491555208a6003fa60a9ce587cf233da463709693fb96d5a5b5560e208acc966173d45c445c801f1860152bfe12d5cc44143d7d63ce5e79f0020031502dbccf473c2d62101780e974359c0d560b0d52640b1fbf86c5b6f608d274ce2ac97eeb456aeac23282f82e1358760d7750ee6f62c15db16ecaa0e5f52db3fd0248e2a7add542099c6c340f928903fd673bcdfdd07a567df9063446ea4b28f909dd6206d13927e515ef03a11f01d69f5c7c90b76f327f0b2879130723fb01523ca15b2265286cac7792d74d5ca0901a2f09ed1838d5ef732a3af6f4c2f3b7406c581121ebc5c50deb39eed19978bafc066418dca855e879d720c567c9eb7aa3aac26037a72e9b6a36cff13465891f7d9af8281fd9c45bd080bcdaa92e68a5e1db84063c36d1d503992a280e95d5795a07c9dd84401f19310362d0368a809629cf10864b887296813501a17f895cae235cc091e936e8fd594e4499ee3422323fd00fc9ef6e49d687d614efd909485c0a07c98c87128c463113a7fc8a06170482bbe25f27ab2429718f16e05d6729371f1626c8c9d34dca3ef73d889d574a19cddb6eaf7b9cbb2883d89194011149bd54ec65556c56f5bc6d2fa9c36372e6e68b352a822e150baf497d3273d6921ccc7af6b2080e4ca106ca839d3e2c76d05705880ff920f08830b435fa36613d4649a7721f57a0239dff5b35df9f5973f84ada3d8a3758729a44486acdc27f55d53e76384946439bd7574731e0894ea0391b0a6fb430bc130cb594662ca831be459e4c41ab8d1e2a32640fa881c4070e4a9fed4b6b105ff6942d4219e9555d164f660572f611dae10668b53fed97536b319d67566e43f81d73fd1751d0a4479ead63fbf489772eae8017e4ab365744efd038ffb0571a11063d6bf85a41ba11401ea3da21baa2254fce4a075c13ecf45295b1e1e1853c2ad0ca90c57495fed144a2b28413acb91a0774be6764410ad17efd01fdad4ddd98850271110390046a5f77556f6a64afd4ee6df1577ae51e1623345dba957ecb5ba63454a07fb6f38069def8e89fa9c478830fd08547fd544058c9142820524004660f04b2ee646e3a2aa8adfed8fd0f19587b80b8ccca8383dffe072935d3874e7e639d12fc594075bfcdd87898025646a9b9cb5b8481bffc08d894593b02b79639c0a8924ff7c744e4b872c6bc289cb18c9b3116aa6e9bad9dffa65f255aeedde90afc226e0a64ffb261cc8135308b60969373877aa9c9481f4384967c275beea2fa9ea786b23cd72386384aae326ab1ac11450c0b3460d7d0c85148abdc591b32ee84fba78486c57abda9e000e283047562b9adc50245ccecf8cf5191cbe97931011bcd025430f49d7fbfd6204fa42660d0d2d1adee701e81ff5a6ef46b7cc1e96fae9309bb0c10fe6e4bf206e3944fd85c90a71529d43cb6acea5643815c2bfa8347d6148e435570bfc83d754b5fcd32cbdbf33a2a0ad434fde62b09b71716d1d1564f6f6038bfde758d9344a5a01f149d605d2659f8ca37c7dfd036166fd344fbd460064caf33cb69947e7dfb7611b1b199b3217ffd1322cad73a7e0550e44934f2dc890826afd6611f8ada97158e06a7e66cc79bba8cfbc7cee65164d6d3fdf7824690b401ef5ed8a1fc865e002851820dab950e85bf26955ae671673af4c8d2942721503d566988fe8ee229b5377df4e463485b5a0220ccfc5d6186ec4c5ec778eb9d1b0ad8d0b89d5a84ab4e70f270b67b792cf0b0d4f5afc2e474fe283bfc8f84b1bc3a2daefec77b7a063dbc10bdf1949b09d5fe21156cc8a5c69b10b217437a86d31320ead7c4278559cf615f74d8e7cb71474f1aff696587b7407dd1af2ab0b8b263a7c694fae8e6fa6e3606c036abd621b2c90f6bf69c1582753c845055c171b8749bde56f6515219d76d17d73dd6a31a7354dd106056aae65dec90fb944500b58c8d115bb48052f3ef9f59a2304a3dcbd30f3ad41917ebac44d4555261ecb9bf2e6c0eda6bf2b390b120a8bb54568c2aedab1357b8af14ed37f1ef723ce331aea43a62f4907ccbb372751bd92854c4197129b381e7d9005e6eed85f343450fbd38ac01f30bf7e1b2f6672ea97be9311a7ca2481393a64a945096df928e8f899fffdf36de8990433145f3ac3bb5b909b7ae4e432fc02966cc2b0186d37d407d8b37cd6c838853fce51e12805df55766d81716e60ee8f679baab061b43961a40390805e67cd68e8f7078f90ef4712f5f1aec0249151fad89933676a729d5d710981dc0998fbeaf07e2d21b4b84800d484239af10965ee79d9557714b11585fb528caee4e4d21446a986a67dad8df725445e155ef8a652c71e5ae6f857b6692777ca44678b007bfdebcab8d264365b41174bd4b0071016e02d7e44d88abda4d741724bc30beaad26f470ae48684268e02abcb5efe428400080e160445dda883fdca5291d4d94bb8cb9c13f112dba99bc4c694612e09f81268fbb9e6afb18ddd16dd767f72a9a4b7feb8b9449254aad4c1aa8468b42f793e702433b86b1aeaaa7e2db647a69e45fa0dfb81882f6cd1887d53642e70686190b10581b55353f165b8c25a4545467f3cb64e0966ba292b14c4c19fe18e31a240441eeada3da227c30a7220bec0241f8b707d390c3990e95be3c58ecb05261db3f5ea3e5d30d408be36a8d964afd62b9d94eabd74e04eba1bf231ac1ddcbe6c36972c113962b537542e4b51628d5f8623750df22fc8b57348e741757011b3f27bada84c1bd1117be6ead55e9d210d8a0d3d40cd80304e434670710476e8cfe5db12212508d58821ea4335ad38f71e2e391c8b9374615c64c3820fa8fa33b0a8e0c84a68acfb842cb892f7f284b8081f023d93cff7111f5c5fc507543475739317a91e01434b590383179a1b951148ad004797dc4972f39e679498f626317a4853d0342d9c72faa2f54e6f88e2e399398bf026838835cf3db49118a2f4ca133fdf8a4e58d8ad49ad651b416239869f23ca326ac4c30617bd16177fc7f8ba816124247592074ac095b36fe252770f2145e3238d4288e4388b2e1ab3540788f27716881e4e80f1e97c659d1ba4a988cab6ba30fde028510b60a81899757c07bf70c467b02c22af1e271b6e36d2fe83447290ba36c0859e2fb846d8a828e5ece9209bd3f0d39e36c1bb153345999b3750d539a3c833978c90573b0f103daab471dcae8c5ee659a9b637a12813530fd091851f2b39e4bac7b361d93c9ec857266c2e3cdcd2602040f06193b6b56a4f06e955c1790fd44cacade5af946f561ca0fc81df40764b47348ad14f005ac53f48c64b1c10cf68fc2bc421290ca5c0ca51a55dfc69a59f5a16a2e745f6c85ab9a48f84ca2d096dfdb862f69cdc7e6c6f29b8f5d2451d889bcd846bb98113bc6486fcb7b396c1d347b0865dc397948b4ed16b8aef9bde2260bfa3d0190a32d4cfe998054da9f717e85712861c851d41b0916b5acd9891e411e2d2233ba22a8f13b20c41a188515dd5d7b4b27de1369569628268e363f139035ab2f78f777556aa89d30876810521769b76a4cd4e943a1877ea84da434f23b45b73033080614cd4a17a07a539a8b5c100649c70c260ac86351b2db24d900baceaf75ceae506a8a0baae081f865690098e82bf9b6a6947aa8bb0432616c9eea6ca0fbb4c4ace0e29f8a32d311914949dbf4ad844b68c662eba41514f0ac6763491b3423f099552e037c143ba25117434057d00e686f588f58bdb1f0cfc9d59a19270dc9783827842744aaf4400a8eb8a9a275642f281400ecb2a060efb11a57694b870b73090e254af73e627db5064e6cdaac8cf9198e3ba962aef89dc30268a5d4198343c84df57bfdd006310e8c642ee39ced6a370ed5b45165c4ace0b01c26e7fb106d282f3729075a101074d7aa014b625027db1765a1cd7716d1097a88c320f5c4940b787a7263048ef443c43d422ead99ab4178a85159e628da6e80459dd5d6550cb0a6a55752fab18146444be08e2d11a8061936477bee1b5432bc84ab18eabd1e78d8240818255e4e6f7eb10589644e25a8eb10182108eb6af16db440e72f1b1e34c6d74290baa557798c1b92dfaf8580f12d915248f0b8cc589e31804d1403858b9108bec9cd0c50f1407580b12f91ba10d9edf495f586443148765a940cbf3ff0d81f6f54e53292dc740023d40fbd779a145179db6f754ce9ee6246f9d292b97eca8c19a71426565522afbc709452af98bc57fc2e0b930079d1c0096781f0919265bf8b1f7f76ad957d3abc6a2564f43a74cf7d4801f4b8848458ab659451116d3a3a08c1e0371d25b8bf45a42182e7703a580df91075d30764d9839225e871d0fa3c5811f68af9710f4b0acedc9d75cb1da7660d3e2ef14ac9ab246bbe8f0c5391e7a16630938c82898caab2c235ecfde3b86e8df047456f2b5db3832e473ec37da351c69c987c19d1b8810bdd037d5980dd705327c44d4c3505fa261fe60aba8e03c1b8b2e9d5cf13dd8a77d1b273d1c58d09f0d991666ca8fbfc09efac037bb72805f1d8b90582e4ae54d146a26c826f7b1d97d96740fc0b28db8fc96317262b570fbf8ef0a49cc7e98b45be9aa0505391da73d3ef609659d351a9ef7575d13bab893051988accb4d7abee8d864576c576c3cc1b7397979464b07f6d18098cb22e387777c762521cb1d1328ab53810bc5998727ca9a65aa1aad7e94e5624b885032e6846d9786f4720ee5e1ab444d70c230f0091b55661b1d83224b2604acb712134e4222e599fe487381ed2041959c929b5a10d606b8339c3a145d2c336908eb16ac01c2cf5407ad0412e0c529d3e7ef3b40eaf031a4389fb33de4dfe0b75dc61bc3de89916c9b5bac6b3b2a14c4cabd243b428cfaecc2b389f9b210647e75ac84f86cd88c975a7b503cced62df6a0965f0334d6b0766f7d0996d46e1d6513783f33135d4ce423b7a59909bc3b885e0cc3ddde731418220856401ec7afadf2790295f97fd85a43be3861800397c5bab0876efd42eaffb30db404b90547b7a6376a1d095fa8f8a4be6aa960e22d1de7432634e4e897c9e0431981099df2cd24b427a590727e4169a0555a4b359edf549eb29550a4ec9c59476e5e5a065a5efdc8482aa5a9a0300255581ebcc48e01ef515675b8a7cedf446cb11cdb6eaf5d02e4d27df6c5be27c63a74d6069d7d9fee467f7571e62e93ccc6757d2c4c5f67716b309072868a7a458a323330ecf55d2802aed31b31ed47bb01b06738543d4ae927917747896f01f12a68de6ad72e2fb983a2651d433e8e62c93c8a88cda8ddc12f2f0934909a2656bde57e833a758a09eeb82454b2fb2b8008d3c79c06e63ba624ac4fab06e96ad46c27a61e84f92b5db0ae83ef0056b4a7b69e89a87f8e4b627e082a92aa7d471996b0385e2a54b0a9591ed4066b90459d0bd112baa07aca0f31ad0c4373f742a1c2dbe8053792a45b7a5a696631255efb25ce9c1e258d3c62af0a87d7167ab040294466618668236de1161f3c142799fcbde1f4c3908fecd21c3877d4741aea3dcaa83bf1cb1320935d48b427f932662219b6432d3992d903aba33241344cae7ccadf375e34ca9325e95f610ea17a4d29e46712dcd469f1f32cc4dd105652c0ecfc7b11177550a90c6c8518d486ec341b5e84936d24e0e4a7fb7e5b2e79dc91a4ec2d339393811647140c8e2e457461c298b99e170ad2a48e6a01a583c6ba80eb1d316a4037b026e598d5e50312d9432fd2e0389176ad399900009eb01246773a0049aa13d08e77f51263f313ef00b63079f4e998a8f31f66e4cc00aaca00934f15d578b72984254b707d48e5529671f6448cbd78f99a04edfef914ce0e3973907190a98d1d2cf74b6651f8a2142880e1ad13d0f7977fd465aeb26c8002756905a1fc9a52856a8d3e93c604f019f563c5d9ca1d8a7271a6e234783309cb2f5387a3e7a906b115f994b8a720a681a589354b969dcf5addec70e22740070a53c9844b64e31043babf7b58492744b37b7a084238e7819d081188aa4d95d52d4d04d47ed5fd81fef0502c0492d1514a2fe1e23a6557ca44e4a505cde5fe64b32d5072178fe8d8c36674becf90039215f958d1979477876322cae8281f777a9ce0c24494f0a9cd9210feed6bceb245688323fc43cb8e17084425ba470ed86d654d9beebc490ab5d59855dc1c7466175b27c1763bb49a0e9e3f8132c86f6ac58e214da2581185bcb0527e2ea592fecba56373023e585c33518e138d2e00e4bf2337562988e5a0d4c43187de7b06a0b55c1fc45c4f3828670317f8502070aec499a73e8b3569796470402c57e1eac8d5678b119c42aee3023add69a511d4f1c2296b44c70da027bfe1f11bf48efec3be3a9f454bde1aa9db52de4c608c2775b1f549f237a51aefaeeadff7cd6ac2e43360a7f500788310980bcf04974063a122cdb09d70fef772e57328b882cb71573a0223a6cd0d64e652d97465dbe1a185fbf42cc7d5a9391727c6a9f330e019d9563a83ded0f67b989e95b2d269734c8abebf383d7e4cee44a6c23bf234854afec3c6993595e0c7eda62eda537428426a165a3adeb378770d139c7abb50d8dcaecbb346f22e48113c35900d49396d0f467dda8beed6b1fc0b71a1442aab111e8b051e4dcc27d0340e0337636266da05ae6269dda97acad6162cce6b691b8c15f27657341c828a4df49aac0c5dbd170601b6987cb424496d329c64771938f309f2230291bb19f618684ba9d36e382f67458c7c1c9ad3542be1c0af5327688ebef0be37de469d454cb043c977e48be1ea78094e6f044de3aebbe21cae43e764c6daec42c3146adc8f0171e823c99366abe14b4ab1c543025856b483e43a230ba3e59ab7a74c9d651a8a916c72e6cc1d5289759bd618275acba0e815ff8ebe375a53abe69da34820de21270a2f5309f45e118c17abd33c33c49250834a1e432d62e54b4f8d366167ff8790eec86dfd25df9b8045c09ae429290cef010e31ecaa25f18a690328a7b0888a339d3e24086440e7595b93f11e8a2cc98cdf039c76c4dc9018e9199c87eccf94b5f60dda4fdd6136d8796adf8cff26e5300da93fb6ed3445165bd7c42a422718020a2fe782c08c496e86ade4596ed74e271ec946bea80a379f82de8b606a27722b7af3366ee5276d5336d2e6d8dcea639142547676cb4c74b1d41c96b6b7904fd876845203109c5899c26555a8909d29d7cebe32b0f49db60d98813803776e89944e5545fe6baf425544a66d50a24c8152c8e6641c5f04cc6313f75439e8faca1f321ebc8d1ba4992829a104e95327e47d168d501a21cdb7987862f49c84f4660b4d30de36cb75623b7a3b9fcbe61ca403ec1681f1fcb52ff527cd5c93fdc3ea328a35b170ff09690b9aeffe49a29c5ce11edbd287890f0c274dcf3efd4c38798ecb8efb1731a07a4e3224fdd597108eec59ecb2f71e6a97326ef52687d89f63f38a421db1dd0f4a3f8b52cf27759c78e56ffabb5343034e4d25617960bbaf93359f64d84947ff9511ee8e7fcc51b97d9a02289becf7c51adaf0ceade5ebfd211527da8f989ab683d24f4fe0850a0a653185260840a85e1f696ade945023657653524a196b0db8e696f77a2859ecc45d7aaf7bb41eca10ea61813da8b70447492c26f0456636572d96e9e5e993e3c87c1ddb92dc540695940800eec9ad87da402681b31fa99c5529f52268a48f7d6148d20f5316b7438bba6add866e05573c74eae24692d267a79b007f0e892352fca82b1dd214c4add11504686ba1da2b41f958a616ced43dcff65e8bcada86eb74fd3b06019f443c30ad27b67507fe059db8b9caae52840927580585d0292efd8d1b504ba7a41ed6dbb2dc2d2f818b519f6996657af0c73c2419fa3d84eded75cc918923405921dadcad4a6bccbc607cc73d2f899dadafc10a6e9266b911c093b9ae02aa0a7101283486990690c94e68f5e86d7bcca63fb4c2326fccb860bdc62c38ab561c0340d2b2ae1fc9d955cfb06086b0c7a3fc611635c8d4d8b17a1c4a105f2fd604ccd9558d7149eccea3387ce917c4cc2e3eea0653723e128875929b284975cfc78fff1936eb3009a570aeed03c337b36c6995abb7e5cbd5070f7cf065b2095afe4bbf0a8723d257b751c768add73826fab2c1ce559fc0138a4969db6cd6ffc26072094260cbdf5d00a65afda5fb4d8c664080bbfee92e5eb744ae802c8cfeaf9a839b20de91e13021b9e4f4d74e830d9c2be8c36968478356973930de5c10e7a662d1349d1b40b34812049d06ddb49ba1a685707f0221007a1a3b72d350ccebe1c9217e36bae0949042f9c77040a7efbb2592056aa9a0ef1ebd9dbbcb5bd69319f42be06956a18d430f945a0d3fc25aa06bfbf48843a6a19776f22fd7812843ab41b00f8410ffa50b35b97a4e16e60dfd813ad9557f0159fc945fc2c86466351486b7b77db724b29659232510b2c0bec0a9df7f9fd4d078e873c625885e8094658fdcd79c0a0e74b8c31ee3e1eef7319cb677552560b006578282eb583972484b0a7e39433c040e30c200c5d7c46106754a177348a5294ce28018f9831bad89e0e33cc6032a352f8004611343c6320cdf0595a220616a95611c4d015b76a6c59b9248726482c61a2082d5870822240e1f3537388e1a764bae249d7279c6c500413e88a45195c68197c690d2f5912e0a21f3e1e9682f0d0e4b0a8f7c564e4c0872132aa10c111193df8e1898ca5253e4b440822480f4d646001fa2943c9921f2382f80054860a8096caa08192203f04fd04d9a18c278408f253c69425417c6a5edc596dadb60b2daebcc400bff8bc2c31226f81821eea511194747d77e1010fb5a8b1c50c30d3164a84b1c5133c6c81c5cd220da0283a1d52604e47eba2b9872fa542505742a5f421fe2ad495aeca5bfa7fdc5797026f3a4a81513afe4c164cc1251cc310f934484a5ba9ccad3939c7dd1f0698469348772298904a5ca6232dca97394459cb43570ce5a73a6eabf146be2b95b7cc2186f287b46edeadbc3f227581270c80a611dd0ba4b8d44e7e7e67933e0e9b9f7d7c3e055b1ece1d9a29f096b4ee477599fdf9d267be05b5fc5af078c3d2f20750ade33e7c42d327347542d39796ded794e60968fa15d4d5daa7bf7913a4924a5a3f219bb6b45221c49c5a2df7af353a0f1dcd131c5f468f32bafb8cbe030e419a3669696dbc1ea760f9b1c79bb4bdb1e3e2666b541569e97181e3cbce658c51f544cba91af2503e5e3245f82dfc25dc00cfdf9e9e5207b3521a220531b702bc690af0befaad4c212328ecbaf8d55a6bad9e87b5ce3969cb43242708e1edc92b4f10c2f4e357df652710e1f7d0dfcb93c769fe6f7debf5d28f385e027b78b62edeba704a42c1d2142234e998547ba2f74daa31d19daa82467ec8b7cf43935c1bd391cefa43c6998d50bfb9bf26d7bdcd32caeda50a3d596f51e0ed69ccb106fedefbc76e37eae3b71d913a888d207a90a269166223881ea0d0f487c4aeceec89e98b446f6fc12d8dc00f242af2b20bf5a94fb2832413f13e9591c409f31ec9f7497674a605e71b8959b264c1c2f95ff9c120818c4cbdc5b4cd7b88155dcca1288ffb0b76e0e680ee62f776a8efc023545f0f39b027a637eae1143cbfebf29646fac68a7288fedeff6e076e0ba4391c7417d357fe95ff815d3632750d31cde53d44f7c4f446f5d685dbfb52e61ff0cc9205c875adbf5312f098402529c17db23da051747d100c0144266303d9754b9680eec9d2956a9c76f1b37feff6123ce2faeeefa9d194661ff0c6baeb6e8dea970cad22561226d8c9b3e20ee9fa9b6a09021f5d5f7a939e1a8945db0ee85b6b0fa76badd9c8a6b7d45baea146dbbc65d03d359a3e96351f714dfde3477f8b6a6d552277628d77a08b35744269617e73c7dd86973cb0f2c4a7e30cf57e89119424c61863e440cf6f5931621653b4738190578c9fb7d64a9a1838e0a8bcd1425f1e1061c9b4d6da786bc2a0c1a551b4640be80a1fe8961593262b50f4316b90cbeacbeee557266a95127d6c5f48fca489cf7ec2e45721e4d72862bd42cb8fb1f240cbd9519f5f02e88ee785942e2790771d77f87b640a0b30004d054b304e1d5a91d278922f6778c24eb8656cb1b40406238c8146136a383181113bd60b1d10218504155c27213a850eaad45a6bad37b5a12150984209255e40831e04618929042a6e70a7a022074aae9309ba32f48e48610ce95845cfd8b4a3d395296118419584a029091f5031440c72d8991f4bd2440e317842c887a53296eccc2f329ff494307cd09c8e53c2a07147f8e847972ad07c7fe40e2aa20f99ef0ff1664679d4ca914f2f9f681469c2e6cba7f9ffad16c6ad16c646e0ed4b1469ceeed723daa64af7e74380efdc9fd95ead53da5eadf36a73d6cdb781eadd29e95816f8fe48153c14c41df3e7df1fa20f2f8978337f7ab578038477e70dcd599c537edeb14987f395a28f31e2cc8bb025a9828c3bbc880e4694d197d1cfd0330b3d77bc46ef00714a7411b736b7d5daeab2036ed171ca107620021cac5c80b18e5386f0823586904437e7acbace5ce5ae10dddd1d67fad74c7dce293deac0dddddd6194d2c8e9e812f2691bb4e7db0285f449abdd2e87ea5a38aed2d9792e9b57acc840658557acd181638b1489373c70465ca545ecddb6b854a488fd547a6edfb2420aeb75ab60262b3a3e115b296e15a1da978ad425ba34976ef4e172a38fd41301b8b0380375d4227e90388bb4c8b55fc4e92c527f698916f92257b26e30e79c94524aeb56e7cc31aba3661ed94d474d4cc7ec612b0458fe7515e85f70631d5dcf9772477c39bb395b975a4a2d05adb594ceb89368ffac545ae9bdf7a2bc70c7c055ea5dcd790005c6489174af56abe36ca5df8652e3769cd35ba78be234e7c9ceb9ef3e4cadb5956ea8ce7ba9e171dc4bee7297bb4f1ed2fac34ffd4a6594de1030fde1e7ab62cab4c8188d21ea86a63786281492a757abc5cdd4b748a79a50470c27e79f665a5998a2bc581698be4b15e6c77fa56af7f1fbf834443a3d611b2eb044a19e6e4f4314e5b6a71c0a95e482f2895a6f87d3f73cefe3b1efa1cceea748fab72c9de4952727ea14bf3a5d52a39494560c330975f243f9b12faef8865084be62e5175ba8b0b1bef06182c18c8273bef4a4f3af0ff49cdf7ad2d38b223d997c8490839eef31ce70fda2255b588825df1182544804e165214a4121a24302d1b7640404aac95bda810838a00ecbcf92163ff466719ab0b8d405113fd6305aba52c48f233475e1c3103f8c00d4c5114224e1a88b27421475d144103fb038756105d08f24c436b7d5da5a8508a8545102a32a5a80c9a84206483460a2abf3e512354a21d10bcd7d273d6f21d4f8bf2e765e3f1ed577b12ca820c19511147d61c586465ca2efdf1df4ddd6d03c88a978458c2236d12242c45f4420c4cd0abfbf1db94c6a4b34a3882ac4bd31e9bb55a1a2efdda6d0f76344c0f7abd2bdb8a3d3a7dcec0e0cccc36424310ba11d9b5df363be164dd8fd243b1be8220283c4357ffb985c8990c81e7080050d235ad4b40385fb243bddf4bc4041183b4840c0f9b003a5e541308300c50e14aec7113bbba59f566f90d1924adfdf8a5ce631e1b2d4f6fb5b4f7b1bda9af47d19a0f9e32e153563e7c5b2c05fdca11fcf10d7eaed6fb9ee78c2a1be7f7f2e90be41fade9abebf35cd59ecfede9ef475d2f7b7a38d0671b6fd7def6feaef6f51a28f7a37257d59bf5f716b62cbdbd00b2b6f95aef58908bb7f2b92bebf3725f4bdab5a9bb0ab05be3514c459acd6a20fe99277cb0638062cd07722c58080e7cf84ddfb3224b833ef8b7dfb8de86380fd6d68c2ee4f24a48ef3008005af7ecfda6465979c5134df5816786f433074bfa9cba37e841ae5a02bf4f07ed441ba6c64ba5a80e5d35c0bef8d13f847ea661ad4e98e7a7f7fc3742cd2970511c67dd3efeb782c0878cb3623a131810f9078a2ed6cf94ed87df9f5084f35da4edcd16166d9f7874469f9cd6c37fad157c9c3fbad2b31371ae202da40ef7360c8bc7fbdd93267d461f53d257deb7d35bdad4c0ebbbf75d42a0ebb1fa30a558bb8e3fe20dedcdf386e9cc055ff8d1358ea6dc8c35b9526ec7eab85f13de2e1cd1ef0f03e073cec82f08e4efadedfdbd08f50e31c431d9bb36d28c2eefffd991ce0aae4b2386529077dbfbf5f99a40afeb756f1f0be0adc55a9854f7fb9c6c6c07b2229cd1b276a1bd2f727d29421e9fbcebdf4bf990618249a26e9d9a72fa5a455e6df387137d473206a1e406ad06af99c8ea3c0faf648b54e3a87e5d9648d271e9891055f31f47efc4408ab202eb43042524b08b0bde287d50fa200230946605d815d66e05285052d2740c14a072e481083205acee0a2872fb8a005a1ebb06ace9f33ce393f77f73a77477177d3f1c6dd5677a713c884c5b7f129a5b5d64a2975e9ee94babbbb7b4b4b2a0b41fac4b8ce1695c6b5c5a6e8ac484a76fbb6eb5daee350a84a27aae33aef7adfa68144a400f0f828936ac1b1032c3d3a6b4a5577f56dfdd613f875ddf28e4fb6b62c147e39d4cb54b7a926b5bfcd6ddbecf6133412e7a493c6a9e39108065978614807ce0062c0438f33a2b1d554fc19c543772b1e3a5df170f3593489d29844f3b274c4de4a13535caa1273556a62aa4ab54aae4a72ce7927510bb730ab65873cacdd5801deb6668528562cdaa9118d0e78ffd7b87f8eff0ab445279e7352774fa292a9114cb182f442d3d35b624a85df7e47f3baf1b4a2bea35dd7a1baa72890ab1cc7715f6374f73699e8c4d414638cf708a51733452b4a5568a55fb95a6b76252373dee8e97ad6976f79f97d75cb04a24118a686fefc9fef565c86baf1f3fdc965367ebe637119cdcf9f3497bd7e5eed2b6e536dad78b8e4e17c10ac55c0cae4e1fc076b93874e60b501d627b0be404b3b72f991e6321ad747c66bc5b07ed754250fe7a5d13c83629e404a6f27100bb4817e5569ebd0db9584f47c0cee542bd5a4e6e19cb3daff21298abaac5b02775df7f8035b4be06fc6da72ffd66a150fe78355e9fe5c2517e832f130c8c3c9ba3e3ae03d81805c56997893599bf78c5aebad55894241434257af2ae9495f6ec8d515d48b93b69dcb9922e0f89b4a461f37da7a4a55b6a58d292ef5c8c1f33c506a1a24b4aabc3069fb97e60c9cfae8a10958f0ae3f3b47db971b04fccda8f1d76b79fb174711f0be61eafbdddbaf45441f46367df3be7fc3ac40d1c7cdb4cb3622cd99ed5e490909e9e8c8c8a8a8a8cbf6898776d71f6defa7e47fd14315287f932e84eade997cc672293e63b992fcdb99781369455ed9124bfd613949f1d90b90ac22a95821a56cc9848c229fc8265b32914a5a7e472bf1ca8e58a490cf5e8826ccc7672f4833f86c0e1571d9f7b14aa412adc079b13c1a84b70b69c9229a33f77198fc4c041269fb2ca439934c0e93ff79df1b79631b48da0ad1d49f57fd71d59f99fc6385962f937725a2a2e5b7f2ae45317957a739933e3ee50bcb89c572d2f65f80e66c8617a2695779b7ae60f92d40da5e55de3845843467353e87e47b2f48dd0b927cd40b92b6bb85875e9c6c4817a5afa565e512638cf3e557be5a61bd7a59bd8346e2cbc78fe7e575dc63cdf7cec19e8fd1fb086e4ffb4fd0c8f4283d1e36c0f5a9fd6ae4b228e548be4ba9cd995fa14f2e63bd7c8a65f5d2e5e5cbcb96c7aad4cbbe2f921eb771f133c2d3fd0fa9e37c019dc99540a7027a15d097406f92afbaf2e4a16371987c2f3b928c10b04f34bc4af150522c95567d3cfc01ab1220216d03f51c29d3270f6596ffa581f422af181406974a94524a69a4946ac74344b7429548fa9cfe6a4d4929ad2c8cad92cb24923755ea56dcc97a5315d86b92a26da0da9bb010b8736f8a37ee4dde54e526821e18ad6ab845c7241f18ac9cc02a1d937c6a493e403133ac98463a9c40534ac7d022054068e11b6b4839e2c56a5d81e4b0a8e4c2154b363e9eba0617402e29462e4839a2c16b9461c48c144aaf1f2264a278721d11d4aac269660645c420c924e1a8069345532b094d2578d1c1514c0884602139c11001c42a8a171410e182458d154588961d00ada238024751e4926529081515472d53b294c12435c51106faac50e94084a703a7d4089674597c49d45055d43c289870540c75341f045d298250b4328cd88e8cb89f262eecc04908c8852940518470c18aa5288a70018ba72d9270e1282829873556e0c214b5a4102491840b3af831a18a0a001db338430b37c2d1733e1197d5a74fa34c6657907bb3cb7ed4db27917d3c947af7228141169e4aaf385bad1c32c09df476f880eb539eaff1704e1d9186391e4e3d3fa62755a393da484ed8d4b186ae7377f769757818abf1b04ef759dda5f4a2fb74f74d5503ff6dab74c64963a5b3d2b9d969b76d6edb0d8d38fcee4f279d17b5dd2df5f146be51758f8ac7b80455c26e72b32528a1448c314e3c77a0010f3cf0c0030f5262dcbcd6fc56ebcbf1d09fce1fff807897673ed27462d5f4440b16586a6005bbe838058bd0128c62411130c042829714e0948e53b0f8f0d4323a02171e12aa784868f251828434f49635a1212de5132d65142d6f94d568fb95f65801094e8e30064b4f7184202a03234d8d9890e1117eacbdd3b2304509b6583212c2c10f3bd60c6da1e0c10b6dadb5d6c264f19daaeb6f53584f4c949eac683ac50838d0f4edc743554ae0786adce089076dbfb6a6176664d1f9b0b6660068e040db3482d0360d2fb44583a6ad0dc7002245715c01820b9117f772dbb69d7106d0d3151d94105d09e28726239c145d6981104857961022c80a7eae5821441027419e0fad6d5a6bb3e8410f5cca11400e8b41418ea8bd8ca0074c2e69f4000cdcc22c988e592861c16f3473d2f7890d91cb681497d5affabe4dd19c591b237d3f35038cb2c921c2eedff83b7cd8e1c3109650de0e1ff0d4d3c68855c6ad09c345e055cd65332b1edebfbfa2cdd9ece8dea37cb4a2f120c27b6645dfdfb3231b9acbb6b4f171d97deee3f17e66c567477336bb17e32304c49d166e36d4fa6a70eaa5b9d990bef357204b73dc77e075013d87719c8d0fd186167de0e8fb363fd187ebfb364473f6f2f76d8ce68cf5d70605fada18a1efdb08a1af4d91be3647fa7eaa09ecf2ace76c68f1e67e2c0878957180825f320e2fcf7ab97a9727b2caaece25bb6626f2925d5d0e3dbcb0fbacec9a9901dbbbd8c761f5db33c0babcfdb8a3e3df1a78469bb3dabdf89bd17426ec864360f9de751f8f0b01dbbb3c91ed5d32f744ec0f69c947ace674fce23c61179a8e7a4b1a6dc2ee77333d72c02eb40eeff001db1d3ee0aa2313de49f4fc12e03b36347025f303bcfa02a3541ff7137471d9c6c627dedcaf19a3fbd4179a51034ba37e7e305019186954a6613ef7f1f37290d58f2b6a8922c27d1f0f978780324c30868bca33a0eecac7c3558f63a069be8b03473cbcdb0648dffb289487c4fd48451f41598d7a897a14ea6d7c6c7e3cbccf651b9a877745d3f7b70d4ddf5fd15ce67f7fe6c4b94b0ab018c5eb321a7a585a7eaee10a233d5f06467a661ae60eccc842efd84f24f0befef286f9918a6e61d3f363fc8c98a08fcc97fa1352f5fce8d3f3a4e8624de451c3fef3754881b9df576ad7d3a7f6ef3e07769a02f339aea545460604c330cba378e3e12b8376a28f1bb08e54a1bef7f30b107dd8772a9d9775b81c3d44fdec5eb9a16891f85469913993ad960c9ad346d3044df9436a8a4259a2cb835416785f3d93c54573e193a00e29f0d4b1f3cdb31fcff7d9edbd6e5c272d18258d33d582bfe7218682519bb4b5da3a346773a80ee1218b6df06cd57ce38da439a2886a382aa1a0fd65883ea4f62fe2b2d777067ed5b72f73548a4aa911e0fd9a798a724bed2432148941e9459b53b8d03447733ce43efe046313c63dd7e990026fbf43bb75d4f3a226220a9a7b6722fa58fab65fe13cd0dccf1c0157fbdce732efb977292eeb9ebbcfa190305724c7e0a173f4b9a8b9f95ce6a292e6b62e06048c031422f35d1e07fa2d8fc37c9797cf753e36b74184711f5f7a51bce13e16048c0394d4e3d0f2f471706979fa445a9e66d7f648a010593deb3311979fd9b56527feac8c6495f184713fa1105941f17e95a1703f3f21b28987dc7bbf8155cf4f880cfa0da4baa3de067e5aa808bca352c8b52ced1627cdb52c698efb8f20f5c06e7b14783ddc507fef67041c83cbea73a8f7746c01e38e8b174d18f72d46ded469f94ded457316c384717faf126eb5fec370c7f40f8a73230fb947652ff290e3b88f355ca6c185668675bf5c84d98f37fa4041dbf762575b6ba3edaba20401ab8a54441eaa88b4fdd6cc893e6238df7ce38da5d9756776ddecc47fb6b0e9fb564554377c61a05ad275b2d5fabf51a7cb3965b531462a91d23ba78c74733be7a4f5ce39e79c736e2be0c4429d3a29a5f3e59cf34529a59346d50ba8a44e38a448aadd620c299596da1ac3c999b158744a29fd226fa9ad2c0f5b0070c2941a7564dc7bf1666fa45c8d28d4c7433f4a524073e6a3832a4b962c597666b811e432541397792d460ff6f2625410ba4abef40549e1fd5d2e213838f9c8d4373eea1b7fe35d46db17a484eff1f6e3e991b7119c2f618946a3699cec6a025d4ba08b6907f82acdd98b16809c8fb7e5fb1eef8ff3b2df2fda87f37d3da80d74fc707a805f0fd0861e3d7a7c0a3d5240e175bc07e88ff37d287c0af986a951c84e6610a279667b1cdb9f90f79b90776893774c15845f35fdff9f23478e1c05e058e078b81f5c0b5c0e1700ee72ad56ab058220f85d4d4d4d0d0c0c0c4c4c4c4c0c013ef63b1e007ff33afe84bf1f00fa39f75bb8ffe33ecf7d16ee17e0be096ff3dfa7f0381f0df03dbe84bff128bcbfea530f7b1c3ff3f9773c55a19f127259ced0931491cb5478faa9282ef3f1f42d007e0e98f316f8ce7e3c167821890540499403de210f29ad25d6b2a305002d35971b171d2e27b8e4dc045c2297013786fb803bbbf7c357af56ac8b93c25542e1e5c64b092f2f2dedfae8aeab5daed7ebf57a1a84b7d77917adfb0ae47d2f05f2c6b848de2d174dfe04f24dde57025947de3802f9849a0c790681fc80bcb103720c79b71a901990f72f2013c93b54404e0002728ecb88e6876413f2be30e48d35cddb1c20ef96a6f94fe60d90f7d532df23effb42de58cb3c8e90bc5b5ae653b0f12ee47db58d2f21ef1b246fac6dfc0d2079b7b48d470187df4256e5ddfa915379639e0c7bb190774b8705c81beb3000795f1d827509e709f3f8a877be93de0e28f5f7d5ef60a89f733e32358fbac38347adb356cf75c9e6a9eae9094fff1e5d2b5c967afa17c9653d9efef5b93f2ec379fa570990cb6e3cfdcbc465293cfd1be4321c4fff367119ece9dfda1572998ea77f875c66c2d3bf4f5c8682fe485fcf2247bab4be0ae00ce075587e1f20f6307f97f24af8d4c7d3e3539f119ed4ff90ba84b751998002ece3c7037b1defe2c793028ebf616fdcb881e3c65bd048c4f1f1e3c1f13adee16cb5d66dc6ced499b7a091994596a987f927107d1da04bf1b0fe09a033795899d0f7271ed6c7017a9187f571401ff2b01279583f85fa30d09970230feb9b00fa9187f55100dd0a0febdb805ec5c3fa2ad0973cac5f02e84df57bd4ff3e9e99ec421e56ba5d83db91c21a1be08e5264c01d9968c02d7da4ce0537d5fbbaeecb65ddd5bdd7e5b6cc400280db856a769402823b326de9238572805b32f9744a29214de713ad3f4a5c969f724f7f329941b31b00b8a5c6f1b92a79c9364b5724bc42954af4cc072a585f676e604fd5db1bd9740d2c3d93778fee61e9155ec7ad00de3f1e01acf09df40600462d8015e693ddc3d22be449445fd0f7b98d93dab62d561a6ceec1d157e808cb3570d20e489aeeb8b4c38f137a572b0698ba6bb9f12d1f8f8d6ff98cf0d0fc0fa96f7c47a30feed322368939ffc4fbbe1fdeff77e0ff0c2875e7f29944e0f6379e6369fb736812e100cf279368db483d8ea4ed7b933be9c09bdc8a3b79485d2d574dd3d606ee1774cddba8e28aa2fda2e921976d7f3a7299ec845c56447f3241add0b44be2a189bea163d20e58747e0ec7db9f020616172f69072bdafe4d4a42c99eb4298acb62520a8434fdaecaeeac686ac5fef6d6cefcccdf7818b8e3131a86fa0c609fe65f42af9acba2cb665c4302e871631369b47d899fb64a55dbb74fa30f1c6ff376d53c740d1161fbdb557309b9864e00a387337be65d340fe90decb98fc7e620ae9fef94604f618fc247d8a7007b1cd8f780bd0bf631b07fbdf7fd30e161df75294f7e2d84cfbd05bb1970533df319dc52e71b703cc73d8723db23aef3ebcc0c46dd81fb866902b87be2133a3fec3beffb113e178246b86c64d3f6dd8a87ddc3aae8ee33d85d1fbfb14e05e0774ba73efaccb5efec376e69150abf7352f81dc3f91dbec62e1c835f5869c7ef56ec37d62d3c7e5f4dfbe8b357eddefcc600a84b2e0b9fb6f4ca84d5534bb3b0667df4aef6d15f8aba87799751f72ae47dbbee03e032d2f45d4bdde7e47dbb9fe58dbb97b996ba7f751fd3bdabfb1e797ff7387987dda790774c778f42de39fa45eb9e47de9789ee3e9637ee7ec78ba6e9bf6a733683c33a16ba0740dead2bbafb9bbc71f73af2bedd9f90f7edde84ee6179b74230d6e6ac6616754fbbc79177abfb99bc71f7b9ab69da759dabe612720d751b973f7e5c4e3529320348d45cee894742524d8a8aa0adcd3c8c70f7dee48af9785cf537d52b2d3f185c415cdb776db3eb47c665a6d33c9cc02c3d3f9e7804de2e9aa65fc2effbf45d3dec1055c8f1f45d3497cd3c7d974ff451c2d377fdb8ac84cf33709bb55dd4f1cce5fc16dc9eceb99bc901de70750933dfa93e9e99ef66408be3e367710089257cf8099125cc94d0e369eef3c70f866d86ccbdcb3ed5325b3c9940c778f6f680f7d5d4266f24ba86562c4fd769abb5d6ed6ef7627d37d048bc52b76babadb55efbdbdd365b374b8d669187f43f34f0be5452340f993ca4b529572a35bafbbd005d4344d77c2de0f84bc5433ab3715ed0f6bb984e89fb1d4bf0378323effcdb77ad1d4b304ae7cf600f4e0f8eb60f8247a6a6f9ef5e06dc52cbbc7f41eedbf8a86f483df3d1fcf4e40703cd5b9b8f4c6de3e9773597d13cfdefe3b961e3e3c76383e66f989a06064df3b3c8653439864bc565f4633e23525b8de30dfd967843dfe608dcbdcc77b4538a69d5a5392bb2b4346566f4dd2e25067ca94bdb0a6d2bc5326d3e7b93a2e9a7c0bd3169fadfaba6e97bf53bbf9dcae3c0a8955ce6aaf1afe24d4cd88aa6572a952d0af882090f59ba36d5ed6e979b3c28310248d437f7389290c98392206f9a33ba43a92fb96c63ea7c68ce3eda14a2377b583c74e2775d726d1fb91c7a48439c0d8cad60738acc59a74584d1ef4287a1e97745d094764af186b25097b62144e8d7a54ee985df9dd296817848e391109b5f4645fc0259d82b9337cc4b31d22e2eafe32e2e2f2e2e79d3df60c08f79ba7d4c0e7ef9eda36c75528529a51466f5aa17954ab57a1d5fbd8eb35230fff2147cf98e7afae5592c168bf530a09129bffa947a9ad2a7f629a55230a536407f7afa66def8ab51e6c753899ed4e8908756c8439b6bcde8c9c3bf4dafd737e91998bf4d6ecd65a9b77f85eed07d72eddf28452eb37f8d5cd67afb578acb3a9a26d7effa548b244c858179aa585c16937608d2f62dcd652edabe0db2b5a41d5aa0eddb21fbc4673ef74a0fdabe8de2331e40d6c76531e94748dbb73f9609cc0b959f01e4f4e457bf36cdd955b2d7ca0ab44a3cb4ff02a640156831687f3cb47682b605da261ed694ae92b62ff93add260f3f346ed4712c1edab761c296b66f93b67ee536b98c7b1e4618e65f6a2e7b79fb55c865306fbf0ecdd98db75f89e6ecdf862ed8e5a3cf9ef5f6c861f495345d5259a7771fd2db9fa81b398cfe0dd08b1c461f86b610f3929dc846df7ec503b715d2f6695ee0f621176803d52ee0ae45dafe0cb8eb935da5d0e0f27303efcb802c0fedc7d06ce3cbc76f7b91ef9b7ca7da05ac616afa14e5f23477543ae902ee9eee45bee4e861f73a4ebbee5db6eeb9dfbae77af0d1a97f79241128d127e888c51652bad845988769bd914dc37cccc7cf00ad5c6f981a264a86790a6e30f48321f52fdf6d9e7f2d709f8aa23e69d5db772c93367d56eff214dcb617704bfdf23030ef9f11a96f887917d0c8a65df60d53bbe42d754ca6af3361c0dde357f4cb7fab3722b36897a7affa17306a16b86f989abeea572ed9c8a65bfe86a95bbe3eb9ccfb161c752605efa7c016f670d2ed4fd908bcfdc9eefba4ed5b2c9c8ccf20a1be13d474827a1e4d60a9fdab06a24c07030588617d21ded42f800162589f0598be3f06eaad403586f9f56bfd5a2b06e24d05e236d0b53de8b22f5df6e30e2ad6bf1b788dea56ffbef4c1b08edd0446444d44434254bfbd7f2d7423c0db6bf265766def2f85a83ea949153ddf41dac4438a33654283785091d28904401e2e81fdbbf77c83d4dbfef49464fdeab713d64abecb5c433741c9013ddd3b1afc08d5f3e74f8984124d754dd288686d4a97c52413306169aa895ce6123293c4b07a56468203116856ecb090ac9884c082c90e9296fcf831e0e56364124d64f5503c6fe90f78f91821defb7befd23e0c08c55f0506a13f1ca4c1be7c18bcf79f5f10fbf283c17e313060f530445e1eb002810f9125ca0eccdf20f5263d8fd5ca301f034249c16428deafc078278c6a4f0c4c3f050e017528106542833cbcba9bf6270d720229908774cbb2099401de5e7322fa74c7265de432fff94d13ac0979489fc8557621cf34365b7d5c812ee4301a242c89a6dbc002d7e40c4d15d885bce621dd01d6e11e40e2b29d030303bcbd76a4d2a1195c0664888714889e3151d0e964f513ecc991c181bc3024c77334ebe9a424883745c41df42f4899c41b4a832605aa0e4ae9ee534e8f3f4123128c33d6c7b0b2d722acf35aadb94c88be0f39124e12124c103161a429752a9a3a91a65fed247219bd46d0b269ce281387d1a74039b2e0491fdc024bfaa00fb0ff964d15290710467afb2e7a1cc7d1ee5bdfe9ce2913ee7950c15d0462326bb5408fe2b0ed25e85d91342d7158bfa2abd56af5d45b21faa8addb42a124b554825b87f6bca72b441ffead998f1f6a1cb439c3912913876dbf01fd50200f73c0db7b149f4d276f0798b7f13bc83c4dccffef30d37af07770fd4b47531074d5073fff0dd075ff1fc713f9c7f1f7716424506e2672e36b32121c7fe391e4ff4fb2f3025d08003f839f5d445e8fe35f8fe3694057b501da789a2762e369be3e0dcdd76424aefa4976681e89ab661b88d4bccd2720eef8e009db3ebf4d4682c4e66d724d4eb263e393ec7cdcd970e4b893330826d979b156df490f0493ec3c1877e6648147ac9e7902800a6cf3f6deb6d160816b4c6890f72ddf5d4f829d6e8150e8779cd742e9ef07ebef5370f512ccfaaec02355f7642ddfe5250caa9741542f3fea1c5793c9fdd5b3587f3f1e56fd249a82fb8b6829f57d59fd7dc928c81daba7e0c6d1abd7992de0d6a15d5c72cbebcc6e7a4e35d65a6b964e404c521f8f534f8ea61f432969dcb6ff74fc15a28fda02728f41e99402bdf6f17cdb7be0eed131699320ca84021d81b75a63a2c0f4b7dfa1136d3a93eebbc9270f85bcf34d81e60cdf16fe9675a2707b0a3467f762dc6afd53201de97c0aaa340df2507737c03ba6b7ed3e6dce3cfae00c2803b6c01830468d54fe51ba2845434f9a44263e1e460f60e9712ac244440948fc18c389384e2174b1a6db3746a37ce9b663dbce966313f6a2632c9c301c5076a8bd490cb4ff6b8657b47fcc65333a0594540226ed4b4078d2114ce81dab54992bd2574e389d72a0958252cf120869fad2c97d4a7376d110e028ed6694840efc2de724ff9763099682ca01f4ca1b88069252c1f40465b8598d0f97cfd13d389a86faa99fbf71f44cfd487dfdd4d7d7e9024b9d62216ffadb7cfab564666e747c97ea2718a9c3a24bf6e24da4f916b81d54d2fe2e70fbd27630b43fcdd178083804d0f531b80cc3d8e84883e3bf3d1df3eec9d1f187443006257024e2a1a7dc68de60bdfccba773ef5502263a0641c7242384b4fc2e15583e114d43fcd76f1d3af5a9c7a9a76091974e3d98772bf59f37be915f3b95777cee57af33c1a85f608f0e8d5afdb4016e3fe6bfde0648f311747d17bf20f35f397aa84a8136c0ed552a30be0cf87a1a50e6fdfbe1f2f15ba0d433a98fff02772ab7e0f2f165523f03c609b63e82331fe3ca5b878e9fa23f2a8df9969fe04ea263bc9f01edcbe898ed5cec96de6e6494df7b1770f7e0b40c8901ab5235aa4fa5521f53aad44f559ec161fef7e349e5225bb0bec701e278aae367303fc67a061003608f870e468ecb455ed749cd6f35cf82ebd48033e800292273034ed7cce0b019ee7006b0c8cc65482bdafd67ce66d37c252524a3b86414978ce292119347a7159672726aef30424b394880637386739081770c6b8fd86533bf447a8a9f834a8cdf05c92831c618638c31c618639431c628a32f75f3bb09c220df2524fac7dceae40783ccd83df9059199e5617c1d49a4f480114a74fc17930e808e4941444eaecbb6fbd4f34bc70f86f9546fd3695e8142d26d3b7a9790aa3f1ecf528aacb1641115078a3950cc81620e1473a09803c51c28168b12c3ee40d40039900e070ab71d74a476fcb1072cdfbb7109a9498e25610e2de27fdda33ef5405c76b78de36aadb5561b36ed5ffdeb7d47dddd7dcff6a9afdf970ab271ef8146b6efc09efbdcd76ffbbaa968e07e7e37f30a5d4755debb4f9f3e7dfaf4e9f3f7abfbd9bd2a4533108ac1aff324f53b3d8a2bcbb66cd8a6ce5455b0e77eeab78f479532e2017d3b2051a3f21117728100a13b79f778e10d1a60ff5a6081a3a1c7dabfa09dd11debe52002ef88447756c84104bc57d02e21f5e9cf9ff8143cd2f1adb4bcb764161c266796bc4f2f04b8d3e12e9359c743b95483f4da09bb8b922ed66c4a73929a03f7adfc1ae8d360dfbf6e94dedfe8b66ddbd39b74022a5a46c7a42027ed1f9d37e7c9e4b0e9a24f35cd73690b4ae3b4d981680f52e614f270cee9445b94668d40b76ddb362ae596f7945b8b556bc68f6328167eec5deae3a46b5a42b1340a45350a0586152f84aaf7d489f71da5d1317ae8a8bc7b74783250fc8e46dc8ffba8bce76f514f1d34cc9796becf8e46da3f9efab3cb350ef3f7f0298bded128d6b2484c6972026514da14a27dadb416ed34c7418e32f0964ef1a594f82f928e3892b89c3bd0374a0a6a12694e6282249f357ef0850e5828dd27359ae0501f4fcdd2d25b471146c819410c48e013a483a6cfb5eac75a2b11b050aa447b40c320c204449891c4848a228688a2e96f313180c0b2375c004dd15488214d85e081a65f5b39b1488589213879328430c228821a6714d1423f9e8a02928c0e1c4d5758020446d21235806041121046086288a420928072d0f4670844a378898048d3a7224843d324254b68fafe35acb5b29a88f2040c4ad08225493bf5a6a16b55e95a6bad49482d6d1d3f4f7ad0f4b110344df2c129e907a4181ea29394527ab1175991fa9c53ceec60f09082abbb688f3e8b4a4b3189872b4556b4fbc73d7db457badd0a378a4be8ed357fffb1699b2618c743f9b14573998f3c9ab3f9e432fa4a4a48484747464645458ef4f30a7d979dfe6ad935ae2b21399150ae551ce6cfa4dd8af62b61c512d36e7d72642e54ddc9d375d26a37299549939a37f9927b9746650a194393e64f579c3c97a1ea85213a2cfce0fd3a2cbc30e4a2a1e5cbe050f830ddebd9ade8c0c2524a1672c0fb75d75344862adddddda3c7211e4a201e4a777777f7173c942cd0e480a50e79456a3967f5e96e4347287628434fd99aa913743403465ec68fc752b0e60c4c97f186fece408c7adbe466b7ed7e17c10c1871c2e53b612e3360c48b37d7437c5be46f4fffda6da3d606f947a6e691d9c8a669903f330df4af9e92be05f396b38baef3284c448fe2611c7299fc1865f6210fe3cb9f9791a63828d1f64addde82d56bade9fa75bbdb864423ede9eed7a11e569dd49ba6003e7efcf8548987d482483ca06b8fae18d0d5cea06bb6bfbfe7e366e9fa5b0d2c4d43cd13689e70058d3eb6576d89c75fa5ed327afdb86cbb969a5e3e5789d015fdd23149484927b1a4635212483a051d939268a26f159ff940b9a1e457e956b94b9587272d4c1fd9c71950f81f52cb5ec72fd2b5e21e85f41a35c154ba9a053ece07c4f07132e0e3249200261ed20752e221ada67e3ca4291f0f698af6aa39017efdbc6869bc682edb79fa291f971d99a91f97f178faa9a73da804cdb5a5494b95a21900000000a314002030140c07c422716030a087d2247b14000d83964e72521bccc32c49610c1963080104000000010100191a9a46010751aa955ee08f71cf558d18a41b68d123bdc808553a6fc108e42d4cb2b90c891b926198631668706e09ee5c5863284f281c125c424b93f0d34371a06652a2c485e8965b3cb9190656972485a2cc75fa4b560358a533eaa22307b33f8e3b9ef301668acb60516c68765c3ef9657d4f12071e556a48136ea20299b5feaf9cfe6ebf4442ba0a19d4589dab8462a5f6e68c2e7312e638d756e13a0b0cc789a93b53b85a80f1293bc67ee9046e66b11dd1e4cd695518fe4334250998f0b7be080a8f0cc8e894b0e88db2eb2bd660ddc1b6a05ae393a513e708f60edd58c10d68da577ace99950c36c015f83da600a92b505361930d4107197f84bb6674acde6b720ec51dd79b792cd73922364016acb793efa4e8510f1fe90a4a4f54c248e3ccccadf82fdf0b8bdcde5cd05e7a06b01bcfe51ee4711d588d6517e52ed1844a98dd377a27a05a9500439b3000dbdee3fccff79fae360f5e7921b0c2adcea17cfe34d00827e77ec938cc446f2c3a9cec29a72588e8f0e12bf84323f03bd65584fbf70f10f74543653e39b41c9338a816151c54e44b64f95e54aab92d24ac57842a3654f65e29386b5f26a9a046f7f5d6efb254e18438da757d96a05e6b52b7dd2e438bf6768f3700bdad054f3920a82d111a20cd7f4344e33ad0720d85b707a14d4c351e942e4a6fd4c64a062f8a847370332eed8e7d2d6fa6216b28e62eafb6001c1279f02f23a1558c232711b98e2ee2a509c3612a4297f8f4f0bcb644b99e5f82ddd7d23577cfd6e86254b13b7ec04ef95304adbb86022114e22767bab5aa548366fc384c5c5f51bce7931a81967eea48f35c9d89e8342f07a02971b68376d7db110151d27a5f6e9747973527952bd37e1517d73778f22e23d0ca5194c0ca51eb2d5db22fdbb81cb18639a09fd9426b9aa3a21bc2e0a8bd985dbb26e7a24c1e0954371f1801359b375f879d730d85fae09870a6420fc8876162b4052515f57367caf0c562c7c5c6f5608cb43fe7cbd02d5e9ccaf3a55da9cb973932e024661eef8fb1c66b623412a06ed753a4d33ab194e7312064035199f5e49f7a18f71291fb006013f3a78c3615a6952c391bfeb23308b4fdd9d74c23ba26b2a9d8c7c4734e4e895eed6809d15164954ed6b7535d3f3b2c8d81032bfd2edfe05345b6691b2a8a2dd7e05d274bf1b3b01d8a2c1893f2dcf5f2608847e6e73a0390da3a29061c929e65701b9bcb95fdc00baa78c28d9c67b489593024924adcd2c9a0870cc046811ec8de7419d5f6bff35712e244c881d925c01860ea731d4ca09ddc1cf4007f689f690c4dfe5dc416bf397ea5580f361845ff2eb52e4558582eab255a980cd9b3bc75308f13b8fa08a99ae975b6988ee6a1ebb7a988c7c6cf248b39a8ac6bab54bd779546141d4c4786d0091f8b81d86a7b2aaaf5413d0c1ea6859e3bf177c9182858e012c504e8c0dc48d6abf6b5de15c7a3ee04e2788542a754235fefa3cef293e21c8995cd6e82b436daf7f9ecaee43a54f403f49b548566d34c5044c711183fad28f549692e5e1a8dabdfc8adccba7b88eaf1b0dedc084ac620eddbbb3e152a61b68573874f8ca9413d9ad3743720c94634d8ae57ab3438a4e87198542d723a09d71f5452370527ab76c9d4fcb23c5fe4ef87002ae00b6eb814dcdaa4dfccd83772238a9669a8f4b83882a7fc8dc6b702dab0bebc03fc388bea7842cf5c28c1cfc9dbff7e19e89a3fb33afdee323815535224e46feada84fc2db8cfffd4a70a7de0132bd45825a08e6c3fd2ab4603b263b098d854283f8916e62b95c7d50653fc36cef17091665695b662a1719e0765583b82ee2b51c5ecf1ea1cbd6896c75e32c0d04d72da33afbfeca8cb8190e6647f2a470661c210e6f2b90cc64c46aad6cad4d21638312554bb3595c44397d849b8fae80710a06e675972d82b5647f061c7256a9c20ab8e4251908718a0f26bfaa6a588084b83ca63ed5ef7d7792e502df66283f426588984fb0a5b1e750facf4b79852d5dcc58c5d159971fe15d9af76fef1df51303006c2f78e1a4d8a1b9b6d186e2b2ad070ba06a66b21e792221dc8a147ba0c05c0860570a5290ce05d51bfaf55814185999e92e3a5abf2d236dda4c66ee41c88b35083880cd6f151284371fa306db4e43cca99d286c7d05ea55a49e156b09140ca37b597758f5db9a6f953a5230ce1d776fde04968711bea54018fd564ca7e64b99761ccc7b7a9d447c5d01d965b38ac76b1e9c8e936e3b6e363d0b25e29562a15ad6a535ebdda34113afcf4d71604949a25048c15f5011e7a86c3c968a3663d1d9a882134c721c310dc764cc155cde785712ca09c3c87b7b92737a59e0d9efbe25f06c2b822968430f88b5a91cf2cc3c7beea3a828760b1439e877c6793cf46116f105677bdd22572fc17204a2ad0bfa5c5f6848541698d5870d4cc164ebfc0826f5e585e55c93d2ff14d87edc0d8c2f524714c9a3161bdec850325c9195896b33f7a961da65c005e1a711d42d75f0b8c442cdbbbee41b849dc12e4cb13479b59518c41fb899ecdf76262670fadb2daba0eeaa6987b92d2c53a548e4042a58ae70b963798ce0f056f66f194997379e1eab7622b6319069ee6aa01846a95579e71d56752feaccee50f18d9c4c7149898a768b9ee755ba86c439a336a176599b501bc0488731f12457fd7a93168854544f4936ecc37c4bb24434f30467f7a2024c97634920dff8d1a76a445440a199778ec71f7e7cc34ca9479641de293df917b3245b5b85d88cc3176ebce4ac1c75d67527c482ca5e9b5cee6f4cf5b7dc6235e497c7c34f4df4c2fb8bd4747ec7b2502e9176316ff2c3ed324d1dc7872d719947ce8ce9fcafa7381a569cfac98174b17e2d25dd5c15e98c13f998f4ec3e4aa5bb3606a6e722c9ccc0288b8833e3a5152176519253c5a27acf670ab160fc0e117b0df0ddf81e02ec1a6c8d529fcf65f0d8106d0a497dcaa729a74681b130a35dc73379f6d2e8a73d415462ce400f130d5a1c07212156d942bfd1fa1050b0086bbe994f4b85b0c01796aa11d1453d64c312fcdde9ebfbdca615eabb3ba2aad3bad9b3a864243550771d66d879c5ba359eb72a123e7c50f97e1d0d0f9fd52e6a84d525b2f92f311b213e75bba699a9b6afc985cf867c30b6a77b40b16fab0e09f6e68ef098cd1f2215e839454d80be7b1a11140fdc7d27ac475981da850bcc3f435781ac321fe2dab2d729fe53c740e6c765c9acccb81e3c0288aebe197b7967f9117478285e2b387c3daae361d1692b92be3ea42dd3ad235c485fe307f5191f437eca6e82d83d9160f7cd63707c3778f7c6ae581d6b04044e3310a1fb923ad2bc24e6374867ab2ba73e1a0e31ae45e2df8b162a69840cbaeaecea4bd4ca6b8e5b86312e1095c64bac9d01842691e51b085b218d09a996c170f40b35c70c87c3aea29e731b6a97c719175e4b7d6078a935478cb170dd7bd007db40cde7a429d58419c65056b22bedfeeb058e7aebf179908ad5fdb94855c61cca4ea2416f5db87609c022378296fcc335a1b10fca502c1f1b3fb3385ea8f99a6af73277cbd1250fb1d1b3e529e02a4c504717ddc0aafd6ca0a51b9cd1feb9cc9660bf5da407a5b4b8bbbe4952f840f610aed0a3f4ceb024b32f4d39bc7145d12687d3f54d9fd35987ce6695361b229f77540453d42d1210998740be6d62c5f2c9ee15ddbe261ba377ce807eeccec33d11c1e9cb3f799185f872569eb7532d3e366d551a7c6b51c324010d367cc8879d0e8356239be8540bbe8c2d27b6d3939088cbc502d15f5097bf8fa91ee091b6e44728ffc6a9797f2f1b58daa01cfbaddbc1c7286831654bb5e760c2eae4b537c32f8979f7c59ad5470187184fed792a0484ff5828e0288f9965ad1047025257731c190035f89ac0e8dbeb9372d4bf89a11cd8f47634e41b2795ae2fabb4a1e129921852353e39a4e3a58e5d63bf2b6d6ce222c692e1e1c9dc413d3af7cf44806baee5e6ebed812504e0091cc550ee8289046240f613fccf94ebccf38b074d8cc6b9b75ecac2b201fc404d64501f4ed61d76e49fe543b8c7e82d9bd6a32d850f8981fed6e271453367624ea51a52b0f6731ca8a4a3996f17022bb16afd0b0b81da412a6709f0d1031cc4e200eb403e77647b6fead27aab84206a0f6730140468efcff2ca4ff39627e58d102ef1f7749ed41f857fbb712e3b57fe623dd10d7945aa36d98039cfefb3a60325cf4d1256953a88b0eee05843e10d69acbe43ca0bd066b6fb524a2b9c6346b164a9472fb6dc27e490e68c1d70b50d31321811b1217e175e5519c8dd852f2a265eebcfcd59f939241851ad7cf162e4841012f6d43f11531b571650e4283bf9e5add7b25f7dea27d41dfec74261b4ad961e8aec822a5411f16eee561fd9e3ad10023e7eb8949cc1686ac6b36cbbbe6998b06d91d0480f00e533b0e84c4b85e98c0982cfb18ca77e511aeff3d8d52ba1b192e841c57d0c7826d9e5636dc83b36d734d28a6b595c8aa4161ccb21571eb9d31cda2e83fc29fff6e1b768787c62c717b2b9453cc9c5d64b5106e72219f30df4e3d58704b5cbde1a9143535a6e2670506c732f302f34c7b811f60af3bfcdc413d190edb1af73b23671ef082d7474f2d5aa567915566a723c769b080042b0b8972a9a3291a744dc959a32ca7f61e325dfb581fb9189acb3ae981619b5d8b9e55b3c9522bf6e27c28978948814096f117a9015a990442903fbf0d3adb9a5eae01d598a58da0d4dc2ebf8894933d870edccea7e63f3f6d16bae229f592fc78741c6b57372652f35b5ce20041d16c077788edad2978f99bbaec1a3ec73672b5cc0e8bc1c1c06b819c834183cea2c7b13b9ad7d5109fda1d42e2baf397dcc427b711fba1ac6fda7043f69e6bd55d925303657bcf249674f636ea554a0a49463e7fbc5925004f7db0763e79a6483269193969795e66591ac1f2fe9a655423cb10d0fc6f52febda579fbd8972f624b374ef284392620f011adc19b78e21a4e1b6952d38b58c6cea6b5bf942b6086171bb889cda4ac78de03e09b2ad58e987c768ec71526eeea3b9077001fbd29e6da913025d84dffdc2b5a355bccce52c11ffa5e83d67d0a8100a703a3878c497b8b83a05ca17f73ca68d878694bd0f05434684d5044b64bda90d84b47ea37539b8cf20f12e90c031fcb2a3095abda3152abf69a594207d8e4a5c7397822154a3fb5cb22a70f32dff97c3e56e9aac233354103759ae0b3a9ae6d3d16a96343defff56e2100eb15b01422aaebad77d96aab923d1217c6d61dcfce8f6ed1ac8f7d62d91746f6f444fbb68f234ce27969d27dfb8991f6228d467c1f1b2b25836b26b7262d265114cdb803e243a078420ba798c511da6745dfbdb87299503bf6e0752cc1eab6322685e9b82a13b43e700c66d3c97bcbffda844e69fc2f9c4750b95259fd33420bc32e4c1b8573c75997ddd03f502dcc741d2ad22e511d89daa59cfa14b2eb2837d4aae537016081dd076193a8874f8951c764961e6e6437b24bf60581d12e6c8dc71564bf67566904d291c10576d24e9e5baf84e7e597003a18171463320c10f9909705ca5da6a6ddd5bbe5e1c0293d9430434258f3a6be563c7735b7aeb0568a80618ce35b43a8f8be104375b1c3b4c3cebcd06c72601032bc3f4710bd523cc6de830b475da15fbd5203f4b3c4787d5d14d91745e40c9c1e55e217cf5058ee037ebadd1dc84c3014f1b962bd3f3843d0b7a45cee88e667415139503652b0d7dc540236a598d667e360b659dcbbc6f8721a7bc711a5dbab08a8b2647a19df039ea8761ee3465483feb39228ad113ac5dbba415803fdc1440d13511fcceb12efcec516f4fef6974062c9f067835a1718c1ff19996c74126dce9d630a821e9ac3d51ed7759f2da643197e8ef1bb197265409be51b931857de13c7af1b4e82237061fe0685239ed9a0fe3d9d1fd5207bf9e336d56fde9890913fe9666d148cfc1c6c63459a30f111ad4cb9529555b2255eb84f7dbad42b0cd242e7377e5a0bee37a20053568d361cca640af5d038e4e931bbb3ad1acd0cbb4368e621fa4217cd0dd179a9e8e781d836fbb91d489266654b9b7cf236d9c85920f05733443e27b4e1b0710b534f05a3abab89458633148388b3cb1586a483999078f60d69b0dbe23e1e9b961a9e54752a9db5f9716d5cda804361467ca9b50d1b989f6ad110254c318a2d36fbbdba287078edce923f4b866692ffb53bc12bd7a0c3b1ac54f00b50d5b28d5475f4e9357a48f165900b302a0de88afecd1b6e203c69c660b9ea40d5458102a0ca2019fbf5516f1d266ef4b9445934c131e336a4108f8f4b16307594077848e678dfaa95617ac4ca0a56c169620e1e321fea9888b3cc555623a785c277346d1eb51d37ad247c97f59bf20d4aaa8a564cf4842904337871598eebf55a3415c6dc683e805e66c0badeb3b85bc9b0a26fd65ebd6aaa3e7df7ba7e72eb8e87d8785dc83370d5b9caddfcd47f53b801f70c7c90302ad984fabce8daf3ac8da70d7bebc61e32a0756319809445bfd477cbaaadb23790f3cae31bf0b695657531f2b1042b771b8fa079ef625c7b0c114a5c02a4f0785f55593ea2579b0dd25b78985290aab18386dfe0190972aebd8f9ecee957079bf1b92b2341073e1179e3224ca5a5369aff130755314c66722ad068b0410f3bc977941f9f33acbb5decfd2a6ce9d3777cb68a5864bb8d61765057ad2be2eda03dd2532c58b946eaed3d5a325efcd83bda36f895121c68048d4ce91c8dc161ad83d638d41ee02737003a05a01bcbc037003c21e774b80604776f2864c57b8b5b60aa39eb10c760648937ee508d34956bd82f6c9d49764a93b240633a5a3a6251038035e23ad29d33ffc2675fc08dca6ccc96db5794ef8eccc68ac5d882c94334d8703a2c77c32f8cc7191c4880e0a5edad5885dc88450ae84cfbfe04353282ba13b1187a6aa12997fdd1b96f3c1cab2939723e751e6e2b8a28f118b372251649daddd2f6a38cff038845d26277e7dddb3a1c46e4d22069983fce80df93eb0f3a05fed1d6a3ea37a113596c4af33a1f93ffce0cbc41aea8ca15c76ea62790fdc9e3711da43325a69c83df2df4d783ed22152c404eb5afcf51e5d96a9eb5e9527de995b03ada53720f1f5e5cd4a8189d2bfaf088d1389c9540141356a9e2afd552b7297f5c4ec67df2a69fb44001488745532cc7d35816dd6d36e0e81de8e16dd25deb72e0f688b651a2963d6e90b0be88192fb8e4adf5ab2a6e87a6264fd2d6b9a365731a86b29223f77a7bb98cbd2222d34c4538b5f5da7c9a40b68a50701f02b4cd36938737f45a3b936f7c88568570fb1aeaeba538b4fed368871c586b436cd782a82f2578efd1e0aabfe1ba50702cbec0cdeb671d18dd12ff24675acff41d4b757af1264febced42e877d2cc80ef3011bd7c3f5af7b3ae7e4fa310a41cd9af55cff97a36460fa7e1cd6a954a614e71ae603e5ea0a5103c3d5c663ea2d39f7c9b416789e141d8520b4cfd0a749d4185221ca5b8c020ff8948d87c1dbf08c25cc81d3cb7bb625f9f01944917905ac147a479141e02319a893c46d7082bd6bfd7d6ed6984520817e5df7216b4d4cee42d6948607cf62b6ce0ee430e06db679c1081a1922e807b7c03c05355a16ad59196570b0dce89d5374055954240127ca94685da9a4af6ba17237326282c1c0b1652dfa1122c101a5dc1bc5f495f8585b2d15e81b96db144310f45098cbeab25d046550873455852a219375b31466c95320c64b3253bbc87e540aec5b03c64bd224cc3cd50f37bde14b506dfffd4d707c93256c563a08c224093a3c8477d2119f78ce82ec466805bb3e601162a392776ba544ce3c004b34d10ae4a899220fdd8a797c5c55b6773a788d22f61914a9a30ebf28759cb565beebf995f16becca94d408d3730608526a5700a188231db51d30fbbfa35bcf521801c3b067e3b13e9694d68baf75315f2a37afe951b838cd34e96392df041e5173bb2c489bed745a576597e00edd72899f67d34138cbc28a2f87d480fabf017890ad9cde9521f4bb971954e1fe684b1361706a1a3482230c2a3e9b67e05464911534c915a2145393e98a7886e4c02e3e4914ac92c05bc5934af383543e4dfc15530a7b95a7e303bdf17917a1d198dc1553f6ec29a01fd1acfd06d8a4ceb650927ffb335ab5c64cb0423a7dddf6d26aff4b18e59637a2f5fd1c57ddce1f641aa0af290c190fd4a7d94873be9926b6de8675c0e26204a17400a3c88caab926d1d754db0eab1f6d6728d36ee36f5ff34fe9ccceb45a1c331d98f0dd95bf98a40e185818392b3f832b7aab63b624d106a122ae6982339d56544601faf0c593ebd28f1d002197c613f9e5850372a454bad8dd6bfac4ba3cb378852451775e384e372920278f004de0639e4b4c49380c8a6d73088ffaee25dab598e59d0a9fc953bde2b08d30852c834d5f6211b9ce11a8cfe2c91fa48d22376d8fac9b3f40328cc6b09364e8f0be24f3d83ac37e51456bec8d8c9aee06f1afd0b14eafe457b9512c8317524028cef918086be53a641b227acde538952727bad3f456ee16798d867e9618be36fa095381d390989621e871acbb7c3fc9f69ae6b4fdd462b1ca658187afa2e312a9611819bbd74f51eab2c50d50791c140a4e4a4a7cc148c44fb359693b244aa1ad442a7b2d2a72553a8b76a5f3b46e851af20dbdfd29dcfc91a5a14bd912f5091f06331f767844bb740d32281732540c4b6d033767c5d25b5597e2b2c6bc08dc8f464e4affbeac3d5bf7146d92b99bbda21ae8b72799e0ab2be635b8d9c998ddb95d69cc4d10b9b68c39a3a809d8f6e89a126a687b73d9a6b89645d23fc230485055ed3dd794e855c508d2c7d468ec2cf81dd87f1bcf49b26ec64cb05609d7db4bf4d1316468f069cedf74a68a28b40c1c44cfdd0daf3ac2873e707267a958fcd27bff5a19d07bd65293e43f31005d920fb4612a1fac6e6c9011d390f049ebdeebc79f1c4015650974e7954da66fdd03df0777b2c6f8189a8622be6f2051220c745d27abc32da5b12aeb619fb7279d54f04ca7f86216b582511afcb10c15a808b55f031cb20c130ac208321a6b9b24de2aa79b7becec07378ca44a68fbeba8596111d53452116847a7ec434b12441dd90bf89cc710c2067451dfee042afb8f3684241f8d31c380004d04fa40d988681f817906c0f0af28b0c35dc145e6f22b10dc2d1806b93fe991e87190b0269ee6d45432848729e37b2d19d7bf62285e3b2701e8f5d4d5a37f9b4aed4325590b3832a590cf1a62004e380da0c8aea95c7c98983371bb7e03c20dd89252cc216edf43aa8dfe46baad3ca6825885d189b3ac502c6e9cec45dd5c40cb48c1fdd14da411f26ed9735646e6b241dbd50c1250dc1f934019029e8c65aeafbcdbd6f819996ddfedcd5a2ad70d5d8ac614539bcb724944c497a35d96b6f088794fd308d4695d2ad0ec50cea8e639fd8cbd8fd98246e1fa2ba8ffa83615d6dfb77939044d6cbd8bf7bc36516936dc8e1dfc40385ac8e40e597849e4e88a8cbf8c5c6f8e0c0eee40bc8186281dcd26cee3a1793f00671a04df50442e2a84469ab1491ba7d2d62d8df14fcbb8690075c9b5fa70fef4ce5fede7c578c83f3390d58bc87a1fd95a4b56dbc9a64aca9ec81c4b8aaf7949807084db3d44934de8afc48730949435f47114d4512cd89c9a2b2d7c756acb1e40d9d0f26fed3d4f6249f3f3d869bcee987d8ddf636df16660ed293fdb6df287b5472bafc9a1bfcd235e9f548d54d2971715f5f3a832a99dbb748886104193cf8505a631482fd74144c87c1719fedb02aac8bbd93020cfe8d0ee9c7bbb970014d78d972e5b4fddd83b9a8cca4beae91eecdd741a80711d85d357d63318eb9487c58e61d9318e87e5ef569624744dd78f0277cd5ca7cddb95729dd9b230b7ebfbf382f3dd58a2b9c9ab19ed8df5b82002aba907ddc97ba3a7136094750e91ab787e764164e445ff13b0b74a7e883e9eb7d1430c123602a5f3ee40bf4abe8abe4bb4d8558cc5bb3195e1766fed21501f5dddf3493e9ac81ef91e9de5d7b5ca0ba3177fc31346685e6a1eb64407838819c38dc6f7ac69cdb5534c78de2ee646503e0c0c24f3b0f054dc04b24d9b3e6e02634a6c01841b141237ef79d1b71d357aa9d982a57e0bb9284f47c23748e4a8ee0587484d4aabb56d29e9833db0a964c832e8de3dad4638c04582e832866035e79dfde84565d8be58a68dec80d30f87a1ad8ac3d3081f6dd52dd35247e3a8489843a4506a1bb3d99858f845abec920cc31360c537ab5174204dcce06324f8419c187313403e734e83aed819a293a837525f7b4a8e06bf0543a9e6924ec3147b131294130b777e3abb3c819eaa665401f0855c97446726dd41f0d4f544a83b6f9b6d210f8db7d961e608e7cdfe2449c5459527ba876e76e72d5f2bdc558f3f3fab7e1beb9a4bcb9ba612791b403c8be7122a07757c630bb163175862d458a7fe868be1d0f434881d6c5339c7fccb90623584025b8c623fdc8b729e7972297353e8b32995c4699ccda9721295e1608041b723231a985ffff4bfccda49cec39b62f544737100e78033128e6108ff78fd259d331e8a3f49356cbe6503ba061e475acb9dad3c300701c9acfdf03b7350e68ab465467ff7d1d9c04071fd8143ba112aee2f0ffae9cefd77ebedce20b7d3f83b9afeb4fb771c17f31918fdf0ccabdb0abf42a4c5bef158b4c1e77a746a121facf288fe53de432de99bcb7e1636e2be25efa187e6d024b95eeeb76a1822c87c8b029fea4382b53e5e7e4bdce04032419dd782fa0a1278edd46698522228a0c75d8cb9a54ee2915df7e05d030f5ffa2025e7277e659cb880a2c7ee1d9dac38b6969f4726619bf8727512f33842c55c9ab4725fc188fc788f71f0a8302e346b29c20e6703d5ccfd473cacf737885ac5dd304301223183e9fd1704fce2b991075ee32d80563652971bee02b82d59ddc875aa20e39ae19194fe933ea316478c5fd976db9b2eb8a811df787d024ed42bb9e6c7f148a27ab64c1b5ec1d707b6e7f05c3527f945dbf3a17e39d0f5eca4846fe9c1d7726c233fb940ecd0060cbc87e149f3b9f6b105ff5ca06ac981b8084a1a13f1e986ca2754ef096dfacfac80abf67ca848e2951b7d6f77b7a56266b63880378991eb39b4731fdc7b13110d7450b3d8ac9479692e7e52887db42d2adb765b7d0edb1264c39bb3c10561b3199528617d8e81c422c07b5d7df3a423bb1c85e6e07a24d6fb84f8b606d5f1c5ef69ee437a52469fe74aa4dc2005b14ef4647a962f0709bbe6cfc41f3469cd0e1fe7131678beb530d79966e004d4164ee4005c57d5573414824ed8567e89cb241af5f50fec4f755e02d35878226aa0c17e6a6eeaa3e9fdd24e7b53b3714b979cc91662489977fa28110bd5a81a40ba0f91b0e71620697fdf9b81906fa1f6e9ae7eff2c8b70cd92b0147bf7a3d8ae61c3111640208fba9af54fe3e0c45fbf7386730f4eb4e69550a407ad1247fb6dcd6454fb7fc2a819cbad59917a9c9935f35ddc20eaf78ba8584b22a95d88ada05b04788b7e393662d4396c7ba12d41c187850357f51db61cd636621ad0d4835889b1562754623c2fc4b669b4138db649094d54e29779aac498508fadc4d86146f50b68ba42f3aac424eb89a1c1a77885c3e24d630b2c26d7c0fdad782a95ce571507b3246e912772758a97899c55013fc54b859033a17353b954abb053bcad2c5155dd53bc49581c5d4ef1b606e0a778c061531174a7587dd06aaac996f1b2f5fa45798a4503d229feccdce47e3cc59e255500488f4f00f030a30af3142fd192332e8aebc012188423bb816531c9a0ae42f86125452b5444c18bf32d417f852a68f0a1c7bd69c97cf79758a4643b4e152e9f9ce45a11caaaf69af203107f87609a23a77cfa8a14dfbda08651ad244021a7c1c0f6ba95a64504616343dbf207fe4e3660a84dc2454d15d10fd6ec1ceb6c0587c71dbb960193ec93a6da664b1f2cd9cf70f86366046c1af40462cc0640193cb7e89422368705fd45d22f48cd2235e0b998e4b8df2909cfb481f3219f9e377323c930bc300a68e8abc46b511dcad4bccadafb20fbed0e371117c1fff1e675c0848256e70b6ae129af4e3957505edebdb0604c750c262e23f9f3bb5f2b0dd6b2b2253d99b38406814497d3ff54ce736e1b3a67e57466a4eaf24b619e49b5a6eea1a1af0dabe3f7d6833c61d35716e7094805d471441d964134da542f3d3047a9468211d834b5dd806aac98f86e2dde4970edde4e2a8907b85e9bfe77ccf0ed555b95e28ea21a0d359bf6b6f8b47a9dc7075f050de596f4acb537e50bccbb7376bb2bf18a75d05d3bb29bb0f21404f5e469da2684de10149f3646c80be0ca6989859e9e915d3d602be796fe6060f52cd29ae2e7b57b314fb54eea06b38045d3ee3fdad38bd8e140fe47604ccae6d4b604f25d25ad96229429059813a42cc46df39807231c98f3ceb9e722526c6933d7c503011d42717de83b12077d6f49de501cb23f93c37c1da8ad9ebab4534933ef33bf44bca3c02b73883e7970d87819c86f9b5582771a3bd75bf65e2f57c3fb45c8f13eff293367e3c051fa23e1212b320b8dde051bcd40d428ef4c0e2085e74571c395ad1d785258891c28146170c9b80ebec734029b63e8dc98f936e7264a23ee961e859d44b449a26e567b617e0ee55dba02cecab913957ec2a4c6ca73c421230680739a13d1f32107816a8ec7b1de8ff473c808b6d9140787d8cc4765b626c4fce7662bb3a8054cd7eefb40da1efbedca7ecc1d16b45603e7e20c55b04bb06cfa503d4dc0559eae40a0dbc568909c6016aa9d5f9a489e59d9eca498b8777a12945e52a3ec244d4d95c2aa0bfbe7486069bebda379449700753812bb157902be93fcbe55d417fec8b3911155d72d532c1ad382027c8e7c0b666421e0594177773fcbef964c1c59bd76712f4e845c91dbf57269c14b8e78dd89cb5a70d65be3432beb79ba3c0fd9a18d503d3c6fa461369b2eb63dc6be7427fa4217d95a398167bf913031a2910b6436831c64c5388c36037e1af905bbfc80e9ec1d26a763703a5d227b7782bfc300b61d8cf04765f2ed1ca55f4f546513004794e17f68207244b291cd0dc98137a074fd0eb7b50577415b9e15c2d8c7d1b34a38f2f36d51e2f1d322e50cb79a986f0817c3bdf475448c799f401416907980bac66e514c45485499992f2a1ca4cd6f6aa1e38a878a0aba8d29c52d8794bede7547c04f8addf1fc55c49a664e9e1006ba22fb6fbe7c13b0006f46891b96932d7a3f5b1911940e3cd05e34adf4aa3b2d51fdc89378d665515078ab8e931d9c1e9b8cddd8abe4c5d438031f300a47c54b2c1d4583f7caf874ee9e61a22e98132162f2a4a9c4b95301e631ef05db441274365937fa38f1a41467e9ec1fe8ca19265979d440bb5d9e27eb1f4b676c84d157e185ce9e8c4f39cb46efe85b3e0329f3d3825ea0dbb4139f0ce0f13c3dbd77e9e7e0e9ad47fd37a466014dffbcdcd300ae5f45db2b13c3cc8944cac9ef6a3456cc7a054a053240f92715d66e0b5cfdc5557cc436195b4ffdca14e2ef83d38c02c620a97d241442e30c8b35e70963fc4e93af4dd6b231ece5a6cb40f0cdc97ca9b58bc7cc66a89401106505a9570eaf869eba125892cb472f781970c9df024497a69cb5db162eb9e6c5faf16b31c06a3711a05660ac4f98fa87de1dc1ecddc3caf7f414b891061e0c003be97f7e4bc976f7453a526e3e5dcffcd5c0e79ba17a97e7df5a93afeceab22d29461fc06a78a015649da9451507f1c6d35de89e7250d492af745fc0d4a79b30533de177d7db12f0dc7292170b98956dedee1244acc614ce0ac75bc9269433787f442122e402d800e2d2a0a4663f36fa17ea1df47d041f4dcff25c57bed031b73c11b013695bd28ced4943a66b5b27776c2dfbcf1d1d2a5ceb28a5dd52bafcc07f06468bb1faf31113983fc72ed061478c03c433982ec9734eff022155d643604a1c4f1c988e147493f9967582eb0727f4c33d2a85eade01bd28f04401dcc4518c0c57d8c45f7b6baade5aa9cecb276e46d399b5a2b34e2c17d001e28a7636d9c960a4cfa64274d93c0d52aa1f8f6bb7b799183e485413792ca982ba05fd969ad88e6a27ec13efc6c65147c888cb47414d98308593d0175e6604ea8c668c833515b503dbe15738c7e00ba9c02ffa3da11c4f35905723629eb2317c2fbbcc5299467c9fd68991be1b90612dc98e896a9552f1cfbbf8c7cb47a411df5b84ac2f77148433df6c314151e8d4e0a226150001047fa3c9f6c22cd49ad8dd28fc9ac59c9becd2c611c28da19d732f57fafc2bcecc1c2226134c33b8bf78a3f7767223e5615564b6dfd86988eaf541b1e9a7c10a163827988cd741d8321947c140013fc3e5ba017db6137a44daf4d9eb98c3121d39597a17e74327b6edd3c90923bdca3c657d12f0411f7bffde108c9a3735e4e58bf71e7ba82d4f5eb27d04427e5cc8eee4c0e4ea9d3986a299622fea24fd75cf7eca500be99b1574fc5b488e4ed897c6b80f33cd3956d7225947ad4397d7df06ae685ba690a15424f1cb8d0cd3a7b3674de6e40aec8895dcf388c6d006eb14b407369c321cc450700e0f254cb9946c058e6b4463d980bd957a4525f45c151c57131544752d8533874bc41c790591792cc7370f5c2e86ef0cb7d2cd5e0f1b174320e427cfc542983bec7c12f1a6796dd03a32680a596d41adf7654a98e5ca53c17463f741d6b06365acef864186a2b319eee88681568fd00776ef0dcefb5d1015c1f785c999109ab9c6172e3e210cb05436b7dd9f41db9a52651c5bee5f360d61557e0619230c0732d6d4f95880309c1ac5255ba0c01496af72dc022e3e1dd4d1c21607de91215b5253bde7909a575ef09028f59afacf29d509130a8d3d076264323a74cf585a2c69cdf1afb37696d2f955641a330ea3185621c45abc6c32d775d2c5460a813a8e0e63418a7a2c40528d6c27f082096c05a76141eee6d3a101603cf1a581bc9229acf619a85ada69434ee2927e416189b58647e2f2d0b7a56a9c6e7bd71ca30c5207fbf03e289f87aee2fe6f6d2c7626457fcac2a2c1d62715e0ba1609c0ca05abf4ce1bd39e0e0a40757141900a6c5bb4bcc3c3e3549c870f9e1549fb00006168032b36b9e4b7162a99bed16613e980c6ace5f700cacad0978091b3efe209ddea2a6f20b66bbdc6bdf9a827d236df9479a1a4708ae7d442345ff0d9743730f0f2ac2e75b3412074785767ccf331dede0d4c7cecfec249b6995fa12f407c03d3c48e3b7e64a788fe653fa9640af0bb632c750092beb4317297ee0496e069a4477c441d4cbc7410715ba02a5f3342cc0e6531d0cfa2f68362f7dc696b2740e57268031e8d87edcb9daff067ea25f1fc20f7c04720644f482698a994702a70f933711d7399b1350c48ec4f18ff89388acd0f9b828fe0e479fbcdcff23fdb650d3ff2122e34781217041bb4a2d5674416c2244dc0ae5beb10c072e23ffb194cdda2c045dd65392698a0ce958a568d9344239e901b5e2e8569d178a8a7bd631ea6db40ab43dc204798b45d34076fca301633905ffd408b24d3a304cea3aea7bbb3af0fa615e32bbc596dcd125d08b3ea20f7150ea552f1a6b5041aa22bfe9c23601e4a91beead48dc22fb9976da8c9582e214269ced43f4b95cf85e0327abe67d8e98db4889a50b23c7cd63c4f3bae7d684b9865e24b00522acf372dcc0f4ab388862b96dc1ad66387a6100c0949e8f788cc6b233ead658fc60c18f5f5d9800f243e777c89987e428d39173ef24327ad007e721704b4be26ceec77da4eebb17743aedbfd0e959f143f851c0972294771439b1a9d3aa543421208cb73d0737082a54a9255406c4e243ca75f095c5e8b839ae2ac2ec086030b4d84b352c4bf221c20f6e0885be3932605398a07d1854c3bbb704c9426ffbae0e9f68c7f61c68e4b8d9a6b63c2e79d23c82e1572318ec1fafe4c7ade93e1b7e90a03048f09dc5311c863381fca03d6dcf2e612dcc4205d97218c3f8244e7e6fe37ca8afa63b72697694cd29b9e085858ccc59dcc246e89667c29bfced600ba734732e0616bd9e09ab12c8eb6481330af2ee0e3460b15ac97cfcc990db329ee609ae784090905dfd1bb13b742742547f52fc18d916666f4217daacb1214b71801a01c683cd1d7e2c249b1244374d45520c0a503d8f06a569e246b24f3d90f47f008594a68811611cafbd33482eb2ff3d1abbef66d98070e87e78abc86bf53bb416b94654cf74bf0273d778b6792da2ba20680c43426b16d4857c0e69296248a4584b5f2b8a350f7dc087e283cc111418a5ed2d91c76dd72cf0d4ca4218ca9dbffa8c85767a2148ee095564e8d0d55fc3c676dc479345f7b165b3f57d704ca6e4ab95d7dc3d606ef0c2b97bfa4c2bc236128c1ac2a1ea991c28d3307931b0ae1858c46108c9546895d4db3bd53cff5e2992e3cfcae078a0960e2ca6467172cc577a95909e9aac96d2811d6a2951d7a047d4fcd2779673c664b726e591e4eb239187cb77b2acde664d53c17488f81698e35e2ed705d01b492d62643771c9947f76fbbab78559be55c05c5ca314a1ea7c629f9c67bb6966daf764c13ceba15143ad7977ad17da6bb936f550d7e91d237725765f2a129b8ad6bff4d3d0c9bb3768dbe06aa9a6f93be7f859ae129882f343fd0c36cd713ea3a1d786e2415ec6cb3066e96d76986361d1ab6198eb3bba1dd66e015b6ba82e01d5ad87cbe619273da145447904843fdb92383d5a4e034a999ba256f11ea2211198c8329fd545c69939a196544fa09678c327229a6d358982a426aece22f377e9232d8735d428ab5fd4a1f5fed88820ef968a5ba66a0bce61a5015d5950bc0adc2a93410572473df28ceaf3874dc4ad1089c17aea169bd22ab02f86badfe287766bd9c041491d1efba90c1cafccda7968d98ec7575f30486ab03e125131b6b164591ca2fc3d0977b8906e7911aa3e5b6a15cba92da255044344472019003d58ce9c760866936629d307a3350c05fc8f88ff04d70e54fd6f08e76a073a8949c569863bb14b73538d41761ada121bc7b8f458b6c3b13185ed31b81a8b919087ce0e9aece8aa0e5c82cea89853ef705aa6140a51eebdc15ed281d444da84f945b3b4c6ad6898313f9c9c05104480f9570f911cc79e5fbae4cd5e3caafbeea706970414fc2b73238e013a55591e29197112d96ca82cdd5d71e57ee766b2bf70ae60f01971827b1a30f6832e6aa2ca551944e0f0da9d43dc1b9e2c6e0c3181380c1e7059577aa1663929a846b1e1e18ed127e18e809932a6f6931db5d37d1fc0850636b9d0ef0ef90c9bc9a83190c378b567dc32ebf019a384e1f8cc322037d0c4fe0675631eab1bb2fdbb8d24843e5ce486d898a85e285a79fa2ad13d02e638c4c9db106006fe48752aa49e1763328c94709353ea5b64a16882f790c3280009a4b107ae9ba8fa652f382386e4b34c7e6df77f55dc35c4b221ab48cae8bf70fe6649374d956187ae5c29834222807600eed5cc0fae86cce3b51dcd2c6b9dd6df00d06cff4f4e3c57ee1263b1d0354afb32724948fc2f82a61b1a638fec4980b70a9b6d90f178ac47b251c3955752c13df5ab2a610cd435468a8802d43b4cb31e31f40cfaf57706d9f1d8437c0011ace60430c49580db38f11a901a13dad5e7398d8b1dc68cd80b48760e3377c5d08ec24574cbb7372c20056961db5cf4f7bccb124d464ad76e033b72b8f9b6d5ca69aa1f17a4605edf7378c5e2a1093fdd85221629c5f3ce95addd159c3629e0b9f629aa8415a116ff3c649d0aaaca45c91e162abe25b70802fc36f0e6401ef769881d1052a583da84468796069f169f934f04d830aa2cd51af608664eb3511f166bf6957c61f2fa8d9403eeb48c465c2adf9f79c8d44167f94e35301e4438447c8b5f0d6e65015423fe16852f7082b5231962ac093d3cdb1d735a9e47b1443017dbc9a16cabd1e06814680c9247efc8f899e9dea248f95c9aabd78d23227c02438b0b7b43ae56254b360731d10fe6a11364b193695dad8219aae904ba813f638639f4007373cdac4167ef60ed76705bf62716ee83a3044e153547de134db670b8a3a1fd15dc5dbe00ab28a5728d58286bb6df63bd73165bef87f20b1ec53474998cc8b5e70225f22a61cdafbf59205a925b0b21c6fdcafc6403ba38bafe0d3a474b32453bac1722b297803cff6dfc66510f5110236307901fa63d910d25deb3cc9b6542b070c975fb232cd568adb0ba0b2ad8d617343aab703750195ce0a29c1785e1772317deb1954442afa5aa5b36c48700ad5561d60f66ed817bd2dc5a6ba0e74f99bd6a78d37f1d29e2fa6adda6e9dc990c3ddcf5154d615b82fc57e41cea237af93a2d6cf5dedea54d43ae230ed7554f4de0b5817457f416d51abafe3a26ee4be7a3b13bda61cae6ee7a2b6ae807d49f40b721595ee7456b4eb1750b62cf8e5728b66424f6b0607a1dccc48dcc810cbab3fd1dbd5a9e8ef735f7d9d8b58458e57afd3a2bf53c0eab2a8afe82b7ad5db51f4d68d0074d2a057ada005bf4474e6a79468392b89c9bc6a252d794b93337f52ad757969cccc55546afd29bd20c542e752a9486192cb8c4ee34187bf645369982712b3d416c169b0b5edbfac27c8506854ccbb2b78175288f397a704d01ce38ec7e0eb8b58c134cb123502a41c596823123aa668c185f48c1592b382966483e158f32f7894971da91e607807c845f5347a1c0cc5a261622595c6c6f631e359914ab9a8c642ef44b0a14a21bea75964e841a063887447291af279c5b98493e32acdf398fe5dabfb07355e1a2f2db587093f9607f68242e0d9af308a1fd507215194a1ca63acba83a5aefb7d654e6994fea561c5c6b36b61c7a724729cf928e5dcb364590945ab491c61e8328ed5ab2c6c85b3418e3eaf3eb9d689c4b282dab93f5a117a8b7ec1451370f9af1dcf5506676adfdcff3099d200fd1c67d32c3e2c85547580d956b9195d1f09ef7ef078a3fc9ff807ee18de89cb422f28734df487e0c7cf2dc6c49dd00c1783147c2d2a58c8ee824d0c28ef5b9f84accc3bdd0d84a39f2b68d8c06452e39e24d47f034c460c98dfc51dcdd1f34b36a01bbe6f0877270abb4bf463bba8bd920d4ae2cf3460c2e9198dd0ad795f83b7962192ed93447664810cabfe24ce7708d237c50af49ce68746231ffe6f79d82be0388a6f801a2addc3005d87468b3cfc90b0cea943b46a764a197c13dbb6b432d3df112fa788f5525fe2a3f9f6363cff56c026e1c5d4ccfec5d5a3102fea0fe2034d21e86cf0adf289e17f9b3fabdbe2ca533786c6e4609bf404d2a2f108586af9ae7d949ab60e4e3992045ae41d067fc7f39e9a904f2c74df3fe5f093fd3aa8a4f071c09d456037eb3d62cba79d28f0baaa7c7860648d9aa93f908c540c81729722f542d38dbc15101a22c59b586bbf62620b6fb60eaaeddd95831d9654a6979e30c01f0f8c9d32c56df7918ddbb1231b02735cf4de5fa4b68d16a1964cb53399088e41cd548da08731eabbf3d8e6e9fd478ee9faff472b46333489e7621212689fcf7a7d1fbd0866bf1080f3709246e59c97859fcc2530a8de500e11b8497c15149ab1a95235c7ad38aa8a5510085b6b1d5f3f1a81ee07b798bb4eba9aa071029fcf383ce01f98faa9cbad00725eea4b8d5385c6aae9a30fe33249f3b0cf919d3474e855811b988197784e69c9adad9496fdbcc96eee9c6ed20482907b6dc4c463449ded32fb2f9e541c75b09b89e064585f93ee0b74c5e70bfebe53c4590d2f8113a8542eb3d3a3f7fe9df36bebf8f3afdd2d8ac775a2a6c46d38885988a23988958892f195bfc80a14d37566d2407e8e8cfecf25e1582d2e7c5545796d5b00ccacae90e96f92c9ffd935b5970b2a357eb6436cfedabd3fd3b4ee32510a99178b75f9558721e14ab6f0b317392ab68dedf123d673ba64697c77b73d2ccfdc312da0ed11a0a5f3819ce557c41c81d649b601ecb04a4bd7622028aa10fe8a0dfd283f79599fc892cd722ab3e5eb1815771f5acc83f6415bb679a45fe63538de12ae5a846c8bdb65fe661909fa1a318bcbab25d80c9fed6b17d8a0d13092821a54b987680c2f55833b96b4ec3b4b1b940b57357fbb841de46c2ddb33f784d51b2ca5b5140ba083e31c349d4955812686b86512e02f8a406cc1cd57b67ab3ccaea410d3ca4b3003594ba1393a3276b0b7ff52c5df6c6cd44da1a1ff26dea3e7969a797779418dad10bee01a267ef4e5a026484692282d2884ec022f43dc4c2d9498e60544a265b832d81fa283918d2d008908424082e3a700a091e6dca1361040270781105847c02d8236031640a85ac8c41243f3e9bdc0b3531f0617401ef6dfe0b52c736da281e28459ed06a5c86dc1177f282c171a6238d16a9764fa229aa4e2f5db1df2eea474d0926cdbcc7d7f1748da8e98c4bbeaa06658ebbc3c790a692e2cf32ad911a3474ce539c915b32e588674efc44a21fd450ff6147b827891474bb911612c9639b8320e7dcdb0ffc716a5d22be269439fbfc1f1609d6be069ba4bea6ba2f24d47aa3e7bcabfe57a8d51e2b737497e5c55d92908bc848fa3c43f737f31fa91e040ffbf81ff543e78e8e88c276e8dda32b4426981f0c390655928499502d4f777bc1e058083fbbdb9caf1169c4d29f8ceb33a4e24dbc052c69bbb922b1597abe87f88556d7480796f986087b9f634405dc2e713ecd21fb2940b1da90562928ba81bd93dca411fc1c7b0cf220a0c015e656aa1a8a050c7e5575b7d5851d5456f0c8051d52ba8319bed957a8574ac38ddeeb1172ecd44f87020d535ad4ac7075089bda86b9d5193c5cc4ee8fc9b5a327c3bca5f88c6fd96e6890ee9703a4dbcde9dec02014a8c6a041af4f803ae321bf6a420ff4b1c6242d44e75fdd3b0b64e30b3d73004d4b925442dee2c12103f2a72366ce22a98ca9ceee9421135080c0b9774793e2514874b2237d5771c7c4ed8d8ae41b9f3fcb5da972bc817f1f45c2b90f25c5640fb4f4195807ab63620315be4602ad9ddf410be8d8d8e00b75c9d6d0d47da5498568ca1a2f6c814b7a15777264a3d168e71d60e7009bd54910adef79c367a7eb39a67fc1beb990755ad804c67fc7d79e88e544f3228f1e4a6223f425fe87a8e5108b9b5ef81c762259ac3f1bf592f5e6d44f10f3dcd8298f6a5390fe1d7c1893e3f75445044966611169365c878c7fe6be8a24e111ddb4abbc8168837944a7f17a23d6c420b6c74b83b810308d7599bd53a98406a0449eb875f4f2263f60e4323b8ae1b795fc761a53f3c7c717eda41ba8e9d8d58c17b66b9acded34371e7775d353cdaf5975cdbc31b151a87565daf264cc8943a8577554c24792304d9ea42587131eb139fe371c3b602ce4ad3e38edfeaaecb7b248285ffc5ac5ef3c240c77ebca9a00fcc676e3b900425eff372f734e61ede7c11bba2b8173a24cb50c6ff95ff9576f9f8d98c75f40032777333e70876afb5c590ffa471d7e32f795615005e8e2bec1b1b46977062c0597fdaf1bfeeaa2b46022929a3224cbe1634ff27ab4fd1c6e21e152271f5355fa2d950b7c72c4cc08fbc46f1b7e1e73d828845bb934d57a13ce68cc22053f2cd14710fb3f729835b25774bcfe162e291ba2b8e1b4caab7137676e2fb60921d9ece6561e530a8d2c238611cc3369ba8602a9796b565f35e33ce65e9762fd402f008389cf284030b5f000ebb867e497f8fdcb9a4877ec9070b02405692ebea015a97c517b91df09fe6e8531dff0b3f0e0e4192f3f4f4cce00880c457e9e39e5406c8f4a529aac4145c77f72e4344f6e8de7b12cf5a23a029fb98509cc4839eeb31d7edfeac891e8b8eef1f327d4d0b921ebe28623cfe838f4c3494535158a524fda55db99f88ea31a51f7eece94713f844854e981a9160dc3a8bfe804fc0c8dacf2a385eec727be38fdc8f8b2c93edd4d1efc45c15e8dfc5765e23e723e098100c2ac6f377af122cb658af4538a0769b91925bc0350c042e02a0951d3707d40bcc794ba7b42c02b2e3ab8df04d2b8e405c9d3689e12cdb2a4b65228d25214e298f1bc3c7ed41970b661de2929f9e9d6e71b1e0b82b10857c891ffb64e268a699caf039a7215774a47b829c44575a923856040e4a3128dd15ba38d5566497040607a97e44044f01618e8c5cfa1bee7818f1daa9d29acc7f8ad405acb2cbe735ffbdfc385111db1df2df56e0cb097b99ac7782cca64908bc8a6db6da56f338e244e93c80a81561b46870f9951312b6ed74763bd01fda9123b09c10c11f67ac4f13e0dd13b6321693e584f1f19e547a81fb74b39c38bc32a036bdcc11676d39492593edd45934a715de5b1090ace223c64b4d3dfb7f4569e2112b57e347d08f3c04a90cfe27efb80c3b18b7b27cad068c0307133a11bd00fbd886747188edd43d246e10b0ae019bd27d70818aee4f29f7838d5c734a671191ee7ae0ba1af29f12a174c5ceda33b7dcb3dfb636d224a808f67fee633331d7f589e261df889599be33618ca106ccf964bc0ba2b7909df7098f86a04699166ff2dbc95b9576ded9e44ce6a0d9f4a6ac75a73f4b271f06af6fc946d8d3e08b588c79192466770645a40c553ecbcbdd02a423aadd343a328be142c24b990e239496bd2ba4fa79a4def82b01062901761c035d1f0fa0fbce725e6fd4017f4eb7bebf6409e0c47ee7203243460722419e0d3b32395d98958684118c072db6608fad188b41b17b3b17c7ae3239d2e11a36db716e15bbc1973397edd7459ebf0751a109a838909295f911e41891db3142e72d946f664b4cddb61eff0da7136e001ee102f135fa7850edf417ca95a0b4dcea6905c1fc38d0b6480f42391861701803b1c9453eb0cd63321b4317c6efbb812a7b2ddff72d97d084dfefa52ae015a7413ee8f0e07b96748ba4259edffceb1b4e232a6e801cf71843c640df22d57dd60b54fb3b4727575d73d86c650e57bef796b1698f858aa1863cf7566d998d1a6930127fea9a2216741482ecbed6ec3bd7b55772166ddeb54dfa04267b0ee965d9a55160798ba7d0b6d140e74c76bb8914a9d39499780a5f76ed1e161cc33f05b45ebb8c6749a46f0db15a53a1cea9c25149d5cf0092c1e359a5c7d3fe1fefb9c8b13b37804628939b29b95de6a608c62181d3f7f78979c7be722abb65618e9e17790dcacdce999499204b26350535fe7ab340f62c09d00815a99fa4df36d31a2c1b2bec5db47726a3329094cd2be9c3b24d4a35251d5471454479cc44f273173f4a0875cc4827513c61f355cd11f4260c215461e10fe203b3bef2cc98a2e853e1d6b12bb6be39f782f7d30e8a37fa128d72b3e881fce14d7dedf51b11092f4c5c74b0e60a6aef23afbd64851a2d86ed25be6cb1eb2fee5f955d3fafcd4d518816d94daebbb681f4ca85b19957a86af0920c5bf16acf938bf8ba4a0abb111abb1fec47dc56276e7142742c7d831e7b16b9d4c78e18081bcf2ffacbf1cea66b0101b39c7cab16c7e40eb38217222d9536e606eb2e4dc5c03f0eabfad0c320831bfbd60701ed1e37af4b310556142bf6f6ca0937092ab2f4c88e0f21ffdbf2d5498cd553af48fa4aea17beef970c2ddf650ad25f28296a19f8395d248c63c862dcec5b8eb1a1fb8d2fd3d1ded2266da4aac881b9ac507de45e859d41dfd97449050abaec2718da52f5637f8ca6e15891eca1ca83370f59017b67578cccd60267d9fa4fe360edf7bd46afb172bc985266d04d7985b337de1d4129a549edeeb2360eab0e375d3ff9952ad3e6e3c4a6b88eb45658ab4e826642b594262f792e074ca72cb6dc5f667c70a30088ec551e56acbd71b37f0315e25b55156a9bce1abd8c3956b35ab677aaa505486b7704683f6b7db8ca66e72ef44aa11ddafe2c93fa615a6851c7701b4db301635d571c5b4d8d24456ddff792e9aa5b05cde2b51d639935837105d97e01b3780e2c71240c63886010237015bedc39e77bb4fcfe4f3c703dd65f2fcdca1393e35ca2a224e8cdaa3d97b112591dba9775089f875fa832fe92f1c0eddddf9c7dd0818b2a33c0e01c5731a5bdaf6ba3574302faa18b6c5b7820f5c117403b875e9247efe2e224ecbebe35ffafe5ddaa7349c70a695f9a52b68641ef8dfbef0b73e9f27fc9373262b5aa85c3c4dc12b9a3bdd4f20d68ca35db04c70ce84aaef55dfb289ca5bf0873768adf8cd9b557c270f5a362b6e2f6177e3f90dc8dd105baeae4f5d5b1e4713e599ec9c90360324a0c3a5fb90352163dc7d4b584d0bc323d89e2308712995ba35ac7a0cdfc9a3baa7c5e7d691434665f4a98d3ac493b23ad67a92d28618b6605910c30a68785ae184baa750153741f2d40d989af951c089a9820a0ee82405c777bee186b7ba7d62de4f46be94651cdad3c7c548dc122a6c99fe59fcd48a3bda7634b7dc37b282954996fbf29795915463ad9183c056e3c752f0b5edb91f5175fb82bf0b243f41fbce38b05c95ff17979da0446d5875cf7a573ca620d408f7d7a1afc5668a0640effd0ddc43ba4edaa502a751eb2e853e5be53ccebdd0bed293c27de6c5ae765b8eb4fba22b1866c7fd6c3636dd42b7979bec475beaac10ae2b1afb2ad570eadfe98b5a774882fd72d700f7fdc0e29d3c9ddb7da568b30acfc853edecad5c0baaa0f5e75143d20107368b5032492fa26602eb29dab260aac6bb30e87fcf93e3e77793d56e9100e598be80ec21586c463c8b490ae9b5790c1fdc349c642f7dff4411f318f75833934a31f9cf996e4c222630b3b799ec02cc1d286574c60ed211c3c94a5e906fe3bc37c5b74c1b619df5b2792b865192e8ea20530d5e868f7b247b67ed374eafb8fe62837141e728ae8641628369abb31e80e69b32526d6c70da4fb5d85b4a9b90f0dfb3b75c0d7182083dd5fcba8de558eeb65d4e82528056fcbe44706746b8315997c544cb1d89ef5c40e7144c47c0ed531a9dc50a5a0c55ee942ea45610df27e24a05956ace6f43464710c7e528a9172adb1cc890f082917185735ccfcab754278a525d22c2c97c2a28469cefc923a65246af70bfa0e4a1fd5f8ed2efb32d1953f14ffd6a5c9c8d76f350076d16826b7822ac2606cc3bcc3e134b16552a1b9f220a9cb63d7cf16e651d334ff4fcbb66b219ec20a01ba1ff1f70efbc2ee6661ed8ebec2cfea809b74fb6b45edd28724c0f916f25a013410c45fc4b87e794acb0324d89fafe6060fed547f0e75e0c7c49510c1ea6ad71323558a17f9e4d1c110ef2bb3155c54065729a1e7720f45381a95a774855ec9d530d86d242fb5ed182bf32a25db9519b24a5ffd8ac3bf9770a75788a462117761092b55c99db18608ccaeb56a859850250afaa0e2f5d24b99e59b6a23bc588548964f65bcf8bc03965620000e23e814b83859e40c1eaa47481775921419c6bd7d073203d1b31c575a3bea34843a42700e965a58dd39485c72fc8285b2cda97bf588e9b3febf75cbb090ae35f9240fd7306d1e2d0a3d4b9335c1781533cd39da2eab044f8333792d1a502a86bde45558ed9f3bdecf497bae78036c33db2aed59ffdfb17468e6f86516ee9f7e15a708397effb4a67c1156a70ff6c008a1ad13fe0e5cdb8866a43762055f98bce3f7f6c5d667ecfbe3cab342fe91e5de91fce5f3e6e24787142e42e6260353301c7baa1e62dca52db8239e30e0f0481477104102536448639c901ed550e44732bbd3dc6912dd4f9a8b2df93557d805b1c461ad21297f5ccdb8bd950b887d444c0bb8ef57c72cde09a7a12ee646f93c3df32f50275249cf00bc068614c1c477e10c0ef2126404cb4100502764c0ee764158984f1650f1374a71220e180ae65d45c2b58dec38b804320d449e12e9bb38f7c7524ffcf4c1613d465263ccf95d4e23978ba1e1497df3c5ebfafb88353fb568bbbaf23fa6bfa344f2f8ca9e8fd23d92486c9b17d278e9fc71460a9bbee350a87f6317941b04158aa46ad646f31b5e64cbca1fb5926a5825ec44bbafb0d75fd761a807cdc37574b7efdd692020c9cd69fb9c3a8d38cf9a76990a22a0dc9b6c224c77475daf95150a9b1ebcd745bebea5c55d44f8527a5b240d4c38cd0a545359266742db3496ef48e0bc71e5bec406ef689c1502125bc3923de7d0e55924b7f059753e10299e95f6f9c3cb4122c3b8faf141b520b10199196dde4df32dfd9c760375b3ca939481102c228bd39368b9af0e379d952438ac8e20e74cc1c090b459d641e88cf5e4fd37fb37afa893a297415b913256fd661f3c9d44c3f908d1be4317777acd6b79a504de73d421a1ed10094bb6e9e56810af962ee8c60991fb7c275b2cf8b758c15202e13a31714d7a348651f228266be537bbb09eeef1a0d3e58c77d2cb67b9c44d7a32676cec063e0f3860e95d8c5eb90490171c1fb6698b2816aaafed10083a20520f4d3f74517700b3c31d592c109dba97c99e50e4bda35b31e4e63781f28950570162a184380c280c0c9810bf7c387bcdc8ca40aea0856cdff91e02c8ed8b4638d88baa9429575762d8c1357ddddad98d7bb7f7302c289e4642c387310e98be81b067fd088d9f992f8f14ca6b788979cf3062e5b9819a9d0edd21387306beca24e9dfabf58861e2ffe5b1432716f32e0f698961a543dc89e2f85a058408b88037ca42790d81aeb338e9be331c2017c935af22bb4d75522120f07c1672450da5d97f68065c1e9e7d28e64d46a3fc8262d8e413e3d01d54c8c04e879e5b2d399ab002229d48cd8acb03a1d6162bac2e5ee1bacac8cd484421ee1a9093986f9bd6821c8c426d82e8bc76b66df2d22e96200db2b9754be9d4e5485a67659ac3f40e88e491b89d6d5160a5712f6df0c691a28a0a004de098ae74961926d1a90e8fec64f685de380205621dfa2da5e9602a2251fa17fd968ade41685a40e16705a0e3df42f38daac2685be940909147399fd7b051327be64124daca7f9aae3000387cfebf3106f3688da870db57d561ae01c8ff8ef49f4141378b18072b9ee991c7a594854e4280a0c11e48302bb5edcf4538c9e3ff66be0afd85449c8259d048a90d52f24d905498c5b11e507bbc598a26901d13fd33670a71355e9067b9d08cbd64f7c70e1af666f7d17fbf22e9cd5fdd4bb1d977c95054be7a73c1532b9b53bdbd98eb16b9472153bf367b0a0c44fa57eb1b3f60a8c5c8a8d623680affc71e79b289310ba392d32712d731e89d3c6ef0e1b5ff9446e4ccaefb15b43baa1815f43582b199c59bf3f9a36d64bf453e04ce8ba83ab0c97d44948108f51da882381e85abde7ff26ab0bc7d0d3de7ca0a86d411b04f0ad27338e854ddd7c405e86fa8793e81e89c74cf61b2a3c0944cc9ba26832323b35a33f765316308670b70c236ef764f4962f93c74fd7f501293bed0041efc870a4d225c426d10f571fdfebf26c7f61fa57b5073006446669eca4cb39a61ab92c767c8069909def8390397e4f1910a06eb4b34ccc31bfa2e39db04ca859c59446f9db7b3e58973e86e795ff92537b0199c170a81b326f0bd88c8ac4b213f8cf1046fe6d0785b38e043f4048621b0d6b849461a83c51c98cae0d5a1ae855015d44f57d58712a61e071e46e2ea10c4a914e7950314b3309939aa2c7417b3d9ee523cb3c8720959d1f1fb9030b6c9e2be5d522e3d42522ee964689a4ce6ef97681e8ad7e714f534770a3f28afd002d5123358b0e0b9230276b3c9e74f71e2fa2403953eaed16fbe8c82e8e3721df479af948cccd4ff2a2a817faacf2d876a2d493181c286d963915d08d6e7dfd4e6a3b2b54806c7ca6299df9e28c2e01bfa745fec0d20787bcdcf2dfa2dfb9693256d96d178ed1a6d02431673eb5948cb7c34bbc1bdd0064670317f35d179538cfc3828462cf08b6cde7ab477e1f582df88221db1626ab1774ddc560725f867fbea1b0f3e6dd1e1e81a357be9276885a604bd43eb486fbfdf60099aaf10d050b2fbba2cb175570f22ce4c8228b685889adbd5148daafefcf996d7215ef10f7f11289c08de8b0d6b123d1b0b69f3d4b81cd3a971a5e43b9b1173d1709e35a1c04dae47d6578f5c15a91adaec852848990e47f3ef8dbf9819104a60ee44bfb4e14697154718c6d125fca2891ff110f1e2621c002208bc0b14f9ba985f54f3e5dde41df5453b4c3a06fe979fab73e4c26f98fc4ac4cd8d8c788cf2e57b0da45ffadd1045826d114f5fa4722d079e86277ca348f65ab1e74cf4b597819d78fccc3362d4a83f421df6338537ee96e919dbc61bb3fe0bda48c75a182fb48d2d666d66ba47ebae232cf461083d3ed2e74f996b77ccdebf7dd1320cff0312eda9edc5b238af3edfe7fc603afe2bcc6ae64d2327eea87187b5cab36f00f25c7e02392796cba22eb99b25bb2dd846a04c18a5454dbf08b9f6abfeb0835dc33257b980d9c38c06dd71ea416b19d5021e07b688a1c1623a005056f9936f925025b4b98a3f1c7333806cf6d744f78663bcd734a96cbc0a924d0328334ee35a5d0bf787f0e29819cad42414f8883ee0f747951055bd59a8eb06269b0c65b359f6cb8b740725d69ad8dbf3b24590adf21b7867101e97ca787f5e99ddcda2cbe926c39e956b05a08e6c8db0c79cef15d9e3e5d9f9eb18fa005c3b6b47eda20fba9ce46cca837ccdf54a5315ec18aae654d26a8d84c4688ec226115ed6e53bde8a1160e3711d5fb488f2022d55c0a4b45e19d43fe55391b9f57addfe69e2d6829a9c0612c89a6cb2e7e535171a2daf7c9c698234a264c4d8f0207bede3c0ba0d27027427a93fb69a320590a3eba0d34cfb177196e6863285f83c4b0f13d1b4cf297c4611ee60daaa013340d2f822b9db44990d1d1b94855add207204931c37827b3cd96d68cc14ddeaa25d6b6230b039e660be623559d657de1223b0a387b80ba082e6ac703927e74f419ea94778f7592ee3f4367a51d34c16105ac01e826ac4cf6dacf1086eacfb72399a92c33e2bc1ac421b5a742808c993995432725c8ef3c7315f8357389979182b46fd4b4b2b9bd872efdb5802164c2b97a8b77959b1823ebd4c155508ee5a136d287355cf45655f4a880669c6ae98a52c080de924f59969f1104e7cd99e010755034761e6396231625f54c790c9bd01bf1737e363ccd765098a94fc77e97130f4ce9b1c2e86be87173feffef41d919c7f6e2f0ab4b82b39b7e4c4be376917ed5448c79cf5ed7bd58166ebae189cdb2b255cf0f900a44d2a3180150e0d73158b77d8d96a3fa64bcbc346b78bcbd7cc0b3e7c4454d6366905182fde27a523f2da85e5e5489ed66405085087bca4cda09df6a8a53171fd3f5b0132057986642ecc5c0aeeae51e16c265cd24e3bd81e55dcfc81aeaf3e03fd41664be8705be655f1ceac66e867200a861d949cdce43c8d469bf39467539fddb794310f6b16a7c723e70cd198072fffa33d34c8eaf9b32ab87953e80cbff2f3d6a13c220146ea0c1404a97c0d441231d1a79396c76c672b2caca3153e2a4e1a4c1288122eb548dd876771077c787ffd26b7d9ac1097420cd1c7a30c70cd80e37e076e4d6f97d799e738c68aeafb3ec38fc12e40fb3400447217f12de765ea9a0e8c6f83d4e45960b505f0a6b1c368ba0a69f37276d05c822bf6c4dee66422ab272407abe8b3ae4e57f33c42503df376964410e93eac374ab3fe3bd92c5c8da23a4f79c2f5e70dc7d66147fe1b60976fde84b885f5d8aaab166aa42dfec536621f9cee76c60b0eaf70629393c77dc52c7ae480cd82f4538c22b242f99b04d15694fc2e33ef3bb3c15a5c5cd20d1175c71cd2c474b4252b5b0db9e5a29d5a23031f95c4407f7b5f84e2efeced098daa348048ba3301496481e1eb0bf32e9c2ba1ff35e333f2a455072c439a6a01fc250c3b8196c700cdc89647a35dbd6d01af0b452039ee502946e369cf16853d3b24d01d20ada0f65b21a805432b0320ed0e0a60e9d6f4de54b1591bfb0f7b3e10b6046b145e28160246f27c2fcaed7002b39750abebf6abf2878b804f1d411cf73c329fe5c3edf53ce70bbbcdddaad56f67ef03c29962e5030a0e6579ad56e397e57e5c528d258097b4a99630e770493f80d8856b9b007823967ca2d3068db3d4f4253cbfc93fdd5c7bd42e9510e396b2fd60a5a4eba6be1959618eea012e696a775054ecb948cb31066dedcbb210b153f1ebdba4a70abb795a842b324137918e5ef411d41200d7f1fd58bcf1d4ed796d3d0003b9245117c80cb1af84f83ce15477dba983f38ecc976f7d7a095ce9bfd279559ae57a4b3a5b498384de22c6b7057b0970249c479a5c003052fd40ed4778f6f0881b987e0a5c3486b0212039df8f522a8dc5228687978108241d6cdbbe83ae84a825bfed95234a84c30b076448e0e11224f2accf1f49a4992b15271698cd237566fbaf2061fadd729bd5e3d86af352a3b73d58dccd8171296c78cb26916f5ea232da438cccf7672a4a920bf179f45b3a934313446119ef286b8eb4873932d545ab97453292fc1f72cf9f360dbd3838c056a096aaaa75a16505f52a23127de6fb3134554785ce0b23f186c9b50920037dae68d9e816a01e117b7f950b45c2e1730c1272ab32df13c532fc4e91b1bba28e28f85dd026ab52b4447e0fd20010531c490f2568837e0ca164f90488369d06d0058f8842c57ba3e763d06fd14205f98e9e12ff209ee0aae9ae60c6ea43fc2b6c3e3472c927e8796620825a3551b1cc07ad8f96e25c2e70ca806c6ee7e6894b741fb5380a492809dbbac36d4614f4679e023c5918f393787d2d6f75ec5537f4473b57f878da2b2e9a0981f91d7e8c7b57ad6197df2986441256946e0b454ce59dea22cd8fb9700ef03b697dd17a8b6e042164434e4b4624d35da96e2938c0b84507e40490f30a93361533a3b9808c4ff618ed38baecd00ada596e77d1ad215d72745c2ba30179502e8818a66f2923ce3bf51bf6f5c4cd771c714d08c440949129b18d7bd830b2282d45e5074c9aaa36c8e92493408fcfebc5c689d80b37c41e55915f6616ad996c061b08f7c83b5fc70986bf1887cb47626acbde7418bc03e74f6502c162158b85f960998c273219516aa5794f21c91c35b1e01f6bcfffedb96bcb4cae01e880a77fd47ff0c890d8b0ede60c6dff49acdfb7108ef64aa0173e77bcaea6acd8bef3fe6931e1275efe3494706bf8b390e023d7f6870c7748599c20806440d89f1b1e5611d36aa5d1a2564d19238a0e455e4c9da70ea7f324a8d24cd11e8e92c3b160a942239a1f050ae833acd9ffae9b29c0d636d7e7d0904149f8e8e95d94f1ed621ad7a70a605adb45ab363a273113197884da6e928f43aae85654d255a402e36334d7861d64e9386845773fb338d03ce02fc3ab0ccae66c7bb85ab1036f66ce9c29510610bf47728cd9be306152abea4fe173ac9630888d57d4fc77267ecfe42857b6e66a8373f177212d2b1ad87ad825b1a2681c1a2e9a2134a3f260365f50d784f1d9f3afdf9c39d363731ea0b06a49afaddcbc8819875f6b832afb34270c8b7eed73fd2cd38ea9c962e2d7b66d51cdc6f0bd70a424866e191751245c380eb2cdd88ff89a4fd0bd8f0cb7cf6e73565335e22fbfbfd780d19edcf432de058fa152b6668b09338eb8cd9864cf855b0c9f0232b492fad8184fd83244424ff33d489ff371cb6683e9803814e60062e2dd9fd10a14331b2bf209d2c3ec5a93496f60c151a4c0fd8767be078a2418be9b35c5f49156e40e5db8b70118950425f270a1dac3aee53193968d06cfb11378552840f30849ec2359680891d575e7a9a8e213a69f8599e7ae950d6c5b1d660eb519144988f6ad56da47861c2526526dad7491f8303624d44318c7d1b0a742fe57fbc1906d741958d64c24a578464de6c845bb5c9bf8155dd34e2fa362011ba3d3dba6234368d97635c005361824cee0721990c0ff17a426839e25fb6c650622f548103d8ced1ae7d00000afffc3966c9501ea8d1958c1064f6b99f191dfa1b81b7488d52ceaafb41dd2e056b87c4634fe3b097c591db45fc500a567f0644e3b4b4fb5d66eaad2075d0d640118eb8a449973183b50a046a3dca9ecbdea895091970de2f6d89c05442ce345046078ff48480dfc2ad05e072603623be9b77d198f628ab1bde2fa66250ad1f85ee781210c4bdc48aa2027e014b457ebbf5c0a008865b50148c781d75f3cfe38070a06a1478938c7fe381ea71737cb57e593b11370787a87ab50e53db40989c4c43bd327116323c7724577ffb42ceb337d32d37c37d70def2e60b551bee367334c0bb72e8fe58da5b212d9b23e0cfdd2610fff07c27f9e20b931d7bdde2c8b5baf8b9981018e39d3f4580fee817cac3f58dd6a4fa8a53440a7bbe963ced6a073ff2bb613b6363dfd8add7063e2c94576a09faa9ba98931a7e7399a0d8be33f392b76d816d6a2b2f1eb4a95d8573fffd6c2dedf2f5bd3bfc3e3a9d3d060b7f61010b456bb697113cfc729dd125c47b793ae9495342eaa7a9deaefd7876abd2c8ea389fa9d8ea1cc16cd6ddfa6eb8ed5f9c8487df8f94180f537d6170ef297981e7dc92d3552001949191ecb0fde20afb00d860dfc14bc61e6bafc4bd0e94dd95a9865cbd5732230b1abb8d2dda71efa977a4eb872fb7872450f2d177945dd5dce45b14641f445915fe62f5acdedf4a240fe1cc744c31be8397b84c3517045616c2215bfdf8966974ad9f3d9cff2ce7e62116323052d6d4cbf50b73443fa2562f54e4e208c8db09f39c97b48612168e916344ce399bbd8c0e2e6b68b349dc1c10239323381b4217ff4ac45f9c08fc6fcb3a3bbbefbb2523919207e3166f56aef1bfc93f97da7e4d67824c5c150fd57ec6a25f25c6ba711be130588b8af6c9c77ee6ac5ae34945119b37bc698b2bf568a5d87bd98a6f955d46620a71e1a7d545518cf633413104acaed84dc5b3ab54e044e561ccc5da1bbcee71b2172763eb70f7a482facd2c0177181077b1186aea412642c292264b36a497ad9683c86ae6cb127dbc8c587400d6efa3d76dd237a285f1429b4b7dda9e88682908f911ed9e4bb8052711a146c5d7a0efacbebddf540f3b0fdf876dfa3cb78411f1421b6cdb03c928712d41ebd1b651f9b83794130862c1e0a0ea7dd2a3bdcd62be6135a79109c284c2d76419a2c35ca2338f267b62f42644a0d9676481e46f349f899e6805df7d95af1c21493fb5c9e511583747e123151d54179e77e8dea31576372c679abc89b400848b05ba86afb06b3cc3d022ebfe486a6cfc209e93454f7a8cb9236aabcb4ef7818624638d12b207d9aa4267645b382584a22bbfd9df157cd89fc6349608f3a4d874f6ccc32c0370e311bd9afd17b003db0fd70f923c9f4f559e056f6e24f8ff3d3c12970b949a4dbc9244f83c27c1f5f31c35f63ede2fd4f8bd32401a40101093fc3c3823fb4ff2fde7657aa563f1e07d309167612b0a09c1ce4742b3a433f7744e5e3c7a85e1166b8de10a77201122e1313359bf01764f5fcdb02113aac27f0c86498d7f2d267f350b69309bf9a0b46f2ba90e1f0878dc06b7f830cf12198660d699a2920d66f852d04815574aa46e126a0dd0a7cc14c95f4b631406faf01891ea2c907ff999fd6e10c3301e62ac08bba8cea4310b47835e294ae7e542a9bd1b5d71fc88fb1db197a7acf475f0490e280f4b0c9f89bfc59c55e573582cde2b14382775ce2e884db596f11693d6c852e91dbfe9dbc9274689d570742677239b6e8a1fbd0dad270e526535254117122143db4695b89f952c8e42ff9e6ca702f04f81ec5d9f801394b2e62fae16dd9940dcc28c50f7a13b8b8521f589215d555e4ee3488919d0287ca041fe293c904f3c34d21000f9dab14ee562677661934a43dd16ab898c2c78874d0d55ba654ec98080f0c058e9da5d0b99ee663614184ac2d5d14647974bd6fb69cabbcba6c30315ae0fd9c04fa40cd245539b598ae00e69b2410bd5923874aed4cdc4326d3dd2b3e6d3f28cdfef0c0be3937f9636cf722afd20ada3858f447a77b46e5ba3356faf83e58df63c17443720ba8a6b01ffff2d27929316f71d8a8ad14280b195b8d37503c1571ef31b18908e320b538ab89e57ede22af5aa840d4c36357dd28d8bbe9e7b83e40613502ba4c1819eb182305b23484ddaf046ca2528b26bf6ca749d21565b6a1f8aa190769288f0534255d264632877de6e37c4c81c5ce001682bcb3034d7e048f4961e05400221a35f8b06a9262a86fdf4da9e91d437291702abe4a0edc5fac8477e664a3ad6f8af492eec211a0546686f4758b34e0fe7eb775d54208ed5475f8ff59ec32c706aa74301b9fd3d3dabccb6ec4048f33713e5bdedf12e9f5d33e224ea96bcdfbbadeb6ea4c3877a1126d722a65025daea274a6d13c72a0fe597c27c061cab70279f1f7e992380e9ce95f7c4d1e50ab7c2bb3a854eae72eabadbfbe02bc87614cb6abbefd906113d47a9db14f6920408361ff480dc3fb7c4916be26e37a9796e7d4fb53ac521636958dd18fb2c1fab2707ce245c80ceb12e27f69027f675f9341126c937eaf81a7d429c74be437a53e120b96b3e422392ff80c9b1b392f0d5cbc5956913237d171ce429a35941cf093708eccb5c0af53bebb6e749418d0f9c3237b56c6859ce51ad79d20660802b3fc343c014907fa4669129818f8f4aee3a389922df60277015abe9720ed1dcaeec12d6e9a04faa3ed85ddb4b86584f2f738d8f762332fb920666135c792b38490f424c698c560ca53d064f061abbf78d0b1b7076efc45fc78d6cc38da952c4ac8eab7b18941b844864a20b2a75076a7c78843a7f0ee7d76bd9f0c74ad7c9988e8c8a7e53c5ee4060c162fa9eb11592c5e311ddea9b5a9b734017a92343cefbfd14b8a6c9ada2420afbf7afdd7fb1ff54698fcb0982d839bdf1c6c362fe86b0c5641aa7a647a7fa8b7b490f4f25478deffd42b7fc8073c3df88598151905a0307a9bdb2cfed2257fa22e870dbed16bbddeee42b01a5f565d53ff575e132c121b47cd7fe81918b9e37582cbd188fd32f5d8314264f8bbdf387ff309e643adefd990b5697b80841bd811fce8c68368c77ce73783934fbdf438d59be63f4319b3b624c9f80d3f48b7ae227ead9ee4082d20df6def1cadf04d48e6450056a5e795046819b83f9321b6a1643a9806dc838d6002d75e06ccb0722fe88074b2f00da49286373095aa709745d568701ea29eeccf0389a4e10d4ca72a9c9848b35e8279e0b3a58a5d20e1985598861060700f6cadd90a46d309499d642bfb8d9038c5ad9f2764a6713e46360a5478db1ad8c6c2ce78f8d8aa6c9b813e06fafbdef543cccf5f0f3d30bbca8af65c00d50d3d96013c31026aad6d5d5d40cac9db0699a3c2f9e90835cc10252e11e011e96b7dcbe0ccb81a7113f824a0fd814cbede70f3f60b7c1b2e13776888f2db8d30456bd507b4ba52d434c73aeb24dfd233427d8459978b6ac594bc08d40ac3478924b2dd642699524a29c105be05c40541aafebefd5d5a5f0a411f2c41b8fdeb71142e5c3e74f5c4a8bd2f2dba2c5b3d2e5f58d615a72c2b595f9cd11b63ee31f716c07a83dcdc8222a9a3773d6115811e89f4118290b643bae8573ada47283979388163d6a63a5a2b4917de5f75d4260190f38b47ce0d9e184eb0d0d1bbf2f8d0d1bbd6b698b040e7b6a5a3b716a40bd05cb18200a40b0cc4b5a356cd29a1a377955acae53ef73707b0215d84a6064b403301d80601d28507a20c1db55b3c38e0c818e174e2f4aa51a140eae85d498c205d84e607484817b6eb5faf4b1ae9020411878e5a9eb406e4c4119e283840d4a64e1b789e9c88c203e5045447ef8a824647ef9a5303274cc40fe922344538d2510b164493bbb922d2c5d5893774f4ea4e24e9e85d49a08ede75c668b6cbeae8dd299147d8768f96b0edf2b43a7a79a2938cc949542cc5b69b4e61db9512b774f44a61bd6360c863e5adc2b67b55281dbdd74a0bdb6e6f876e41cfb9f69c9b77fd7a51fbdabc60602c88bea8bdd0efd7a10d73ce69fb6e3571fdbcbab0ed7a303776050083784d2c7d753a0a55a716fa8814cb8715bed61ace08d4d15ad656d891dff1794dab40593932820d0552476de1ee8784af57bedc2c20d3d19bd813b3eb69d961458b1517e4f6ba852b966af53020c028a4a356bd60057b587e08793e211a1cc04747ad1557379832a1579a000e6674d4f67276e0ce061bfcb7c403088c461db55b57a26c55e53e9080084447ed2fb603736274bc2726adc00bf1878edaae9dcbe2d4cbe20584108274d4ae2bf0aac460830b0d117e2c9808f5cb4af815960bbab971a7605a88a936f4a02bd275f4ea46fc7e3c70d9198d2874f4eec05d155558d5758faed23daa2a62a15e55056dde55150a2b13af285c784b97478489080f24f224cc11b161881826a71b1dbd4ce29a83919bdea89bde26b9c71baba85253574a5c7b5aaeae7aabc4321dbdaa9572adee158f8e5eab9ea48a949e9638a6a3b737f2b0fa444aee68cb4b0a1dbd5bb31f942c59eeef72e53a7a7fb29c972b4d6ed7f5c2d1d1db453b72b2def57edd35c4efeacb0ebfde05bb61471dbd604e36bd2a5996d62a5b4669152da52a5a3ee482687414e7be462b54bcac54a161a5852f2b54545d11908e625d2ca7c2124f85263ba3a28ee29d4eb178e8faa271a4b4eb283e4acfde95274c57a8c8f0964ae828e6853f1eaf8a1693d338d451cc94a6507b3d987a3da4f492967a4941a4513b3a8a539eabc16aecd57083d4148aa5bc80bfab2f5aba2b197e5c7d21a2568d323a8a559eb3748d3bacd5eaca0a0beb4af7b0b28e7658593cf4b0b014615d15e96989417414f77652cd530187f1a7eeb6bc8c3a3a8ab74aec7e5cf807a6f887e502cf6a4a97578d8ee2ae995cef4a6dc16afd5abdc81e142aae9404d90ae5c90e285452180c87fde8e2513eca4a5a5ad8a7f6cbe57223e07a6cd6d5d54773941446b39aaf32d3bf5e679c75dfe86a5dd6d5091ffb7b83cd9cfb3928e77ea8966877d070fdd7e27bb5bf6097a96f593908dbb22ee7b2fe3a7bb00b34772ff3dc7a1dc56bd7c7182cecf18073b847e62d99c357778bee4ec643f27aa1f64b47619ecc39e731ae4999a9d3738647afd7cf3e368618631cc2d65aeb7bb9d7df26aaabaab4aad3cc933d9829a8d1d1fbd329eec1d7875824eaddb22cce3edf1da2ddb93febc3b0f7ecc5cb536f8efce9fbfbe5aaaa9eadae99d5303d7b9c73d641c43d2ca66100d7d7bdb93a5b6b2d8d6a4df8fad65a6badce78e7db1b6b57d0aeb579cd40a2ddb139e3eca3811afe7bb77a71d6f65cf9d74ac4b75e5c00c7c526f0d1510b26c20feeb9f1fcfbd1db0db1d72d34607dccdf9bcd15d8767508fdcbbc1629d0eae9f5ba5d29935eabd145f266f18aa298019bef8a7bbe70cfcce3f5e6fc8cb7a9598730694cd4fbaefba6d97644985d5e6e575247ad550b1dbd5151551dbd4c4c3174f42a297de9e8dded64e8e80d82d2510b0656a5a3d6cbeb858edadf4f4b47ad96965647ad55948eb668b1d5d1dbafa33b3b593a5afb5e3af7db97543a36d33f63e2a56b625ef6a2cf013582c8489974560d1f20e79c73bef7de7b771d11c5a0b1c5d543121f4e5048d891975448da7285049e1030beaca4ec42071b392260bd1aa68c98c0641c74b128243be8c06146d8900ea629bc37945f8059124358991a3fa6c472241142aa91c439e79cf3bdf7de7bd7c8c2a30a051b5855b250b8348654a9e1e35240861d9e74f1da0191f57b827203496b26312420d5d82c4c5d40487900646c1ce96cb234a16106930f6572803990680ea808856142c310233c700c99d2ddb4dfd1799bdff11b7c41a74b726daf06165ce8bd1074e403b1dd90ad1a600c221b92f4b69aa8a028d15d4e5c36921040820b419c00c583093f70fb0653188f6f70efbdf74512c3bdf7de7b6b9d35c3b4a192c79a0b04eab54eeb7b6b1b9ffbfee567262940bd779f5bd09cfb685c5801108f6d9a73ce39df7befddedde5be7b1cdc63dea77b04dfbec13f3da83be679f98e9350b45c2acc8504fd06104c76b7ceebb8fc894cfb9dfc12f6e7f57b0d4ed477d88d33759d32e2fe881cb3f760a1034b2703074d10bb87f410fdc3631d8553f7459010723ff82c0817e9b3f76ca932b39e060e4325c3810c50db7992706ce679e0e40cf3db86f3ad8a0e7e61e3b4ecda6b8e1000cf38f5d210a8a130e46d6c2813e066ec7862fb0fae6435c7d428e70fab16691bdf534e54fde62040c0743cc8185c248e160b42832a2c2815e973fd6061c0c9b89aa1ce1604cd0c355164da3041507e396f36a61d77e2e90d28a838175c0591bced018df862932b585d3a58885c3295645bb83ae5075bc8ef9837353c293f039668d1741c220c4c389f0dec7c0993e062ec79bf026cc9f9c1c9f63fee4d8d446f810e60d073f341fc2c7c099f03170a58f818b81b3de2c6d50e9cb1e8031ddb633a45f1c96d707722b7ee39853d67a705139d51fb20a8d9e971c0ee7de56fc4efa6cea8ffde9857bb48ecc8e56a4f1d6fae0dda9c2d0b5140c6c0aec41cd42474f23ff346259c4bc6e3475ca9cf29205d8f931d3029b22fb53977d683bcf789a125d71ea74e83965460adbf01975963d7a7aaa4a3dbbf5aba79546e55d365abf7a5a38ca68e39df39acd98176358c830fdf0c73c9923dbca754e5de6c1397e7bd1669f333d75fc4c79794a5de9dca3677a4ad98cfe4ccf28dcc33d1e63e38d024c781ddf81091df3e7e987a7831cf34783cc83bd8e8943fd774e595e3042e79ef4b319e79cf440c7b49927c7f4c0669ed0661e6ea2a71a9ea9d726de8961bf538725cccacf3d6714b6e99f6b3a3e8700fe98f7a0b499473f6d9fe3752ca931c0bbd4523a7aea6ce6c90961ff6c5964f38cb229b03fd31d303d66e633fd18efb2cfc5f5b2cfdda5bd3563a9ad23a9ad0c56bbe19c8ec7a45ae51f6d977d72fc69741e9dbab3e85c330fc6d69e60ff544fdda9c33dbb081be11e7df2704f48f5b13f972c8bfbf1aefdbd77ecd4fae714c10cca85613fd5ab3b75463b1ab08f9e5616470396639e2a9e00ac9faa6561c1c7feb43aaf70cfcdf6feece19e6c6280f641f047e555c2b6b3b774f2782ab69dbf1c18c8487df454cfa29b0db23f771fdf7fea9c984c28b22d440192c3d146bcd069b4ec51daee638f77a79a7930c6477877d2d0d118bb53876d98249b3a7aea3ef638e5a9c33d18a07dd200fa880a98dc209b47621e7170f6e8698254796d38fad521889f4df4ecddab730cd2d17b7bb5f26ed98cb9bf11e5edd2a1dff54ab0a5e3106500a6f4eb27f8c0b982e5c17eca51d6c985e95477741d3dd58ffdf8d5af5f4113a3e3087260cdd0c29a7175f5eb89c96191a9c2d2a57605e1bb33fad78f319260866e3de9a2c40cfafa1d19dd7a71c40d5d4920641fed411f03079a3f4fd78b907db4df668e77e140f3c697d0790bc0db0799e77a4b7280713f317009c02d92c010f9d8240006d81601af5fd205f6d704a2fb7f7707b8390d6686bae565cc9744bb1382a31fb558de7020fe883e06ce8a343705d8fea6832cfaec2deea603ec473f9a1e9079ec2d2e041c6e0f5e323437a0e06683db07fded83de02310ffad0ef9879b301e8430ffad0e480f5053ad8fc22f74772ccaf41c9d03c06510516d625a09666bef541e5e0505a50bd0fa57e348c1aa1b88eec72fb5b1f940f3ea830586bad41f008cf28cc4772e978a42b7feb3bc2353e218b5881dffa90cc3802f66bd8b6c2a6a0bde8d667e4087feb83a2fa2fbaf51dd1fa68f8f1112a1fedb41acb0209d128ce469224c9d90c090f9a27514595eb33b0f9eab00a38f36dfe85875da1b8c68c0051c6bef5a541bf3672d205e79ccce092d66723b0868c7471656406f79319b8652eeddaf202ddfa52a74fb32cecaf5916fc5b5fba74bffed6974efd4d24aa9802824e1df5f6e62ef8d451df5fecfc10db280803a402880c153884a20cf540a462478d8f76ff758382321d7feb2b8203d45afb8ae8f85a7bebfd4eec5b5f91123eea8dc4f1a32dbef5b121ce32a59fe65b9f10ab5f8118edc78c1983c48625ba1b9a70a0905448441dcae68b1b085a505f102402f5411004419d6ff63d85f9e4b7bea71bb016e6c2187f7d1bf6adc73dbc8443a71e85a76eb8ea663de6dd2fecf341d80f07e1226c64fd5d77bbab9dd6cecb8ecbfa6bafaa5e25f52ea9d7498d9abaa1d71a66f9f65e30e6a1f03b359c70ec659e8b838c3ef679a775195c2c1555a54a45711e46c5541999c1fde2388ee348e6bccef4cc45a3696832be3432a3259e3e32ea9dc68827826654a36b6a32be35b158896aab2a15555d1421825655a37b23b495aec2362c8637c4da821a0433be6038bbb9bf461c01067dec49e4b00de75197a806fbd897d05f36dac626e36b338204893197b38f7b780bff700d477dec4ba4d806824c1ffb9b251c100727e38b0382be44897befbd9783b1906f9df50de6f1782b57ffebbac575fd5ad7755dc11de6e48cb9a4f961188661a8aa5895a93b16aeebd7baaeebaaaa55aaaaaa6a18134913b90cf163b1582c16eb71d9fab5aeab6c5d63aa5aa5aaaa0a8ee40c8d88b21c7329e2afaa4c2693c9641f849d1cc331af5febb8e6755dd52a7554b3aaaae2efc7f5fbfd7e3f9a10b411359b1327c69b97b047fb60582c5cd7755dd52a5555d5bddbed76bbdf8febf7fbfd7e691a95a6699a92185554f59a0d8e8e37710ff7d4dc6eb71bc8fbe0f75b7fbbdd6eb75377aaaaaaaadead775db1f9e38de3e8476cf3be56cb341eedd9f3ac5399c71e5ca201791de4cd80bc19c823b7ec17fb5ad7758de59daaab66b43ad32aa9d5ac55598855bd33f25eeff42ef3f5877b3617f9cb3fd92ff60bf11ed3cb4b718f1895a6699a8a26d8d380ceb91c847d4099898e63cc4469b4d04471704c746707c54741141fac80848eee9ced893af6e2acc1cd756233f2f72b8155b4d6da12c4368b79e0de7bef309c73cef9de7befcd39d745d121394971d1e0025219127834d9157828eae255828fa0212249d6236916111dba7a880d01622349a737972b84748d9444b912a602094c09e0e23292831399a12121424f503892b21710c8f2bdf7de5b6806a10b04096f19e1e64092201d990a0253ca41170b92e302f99286f6511317dd45c79b7c5b0c095884291794642889da21089cf1a42b3ae282bbe870e42c05e84784a463e8898703ff9801ec02c2718f9a52d9e73ace973e1f3f070af2913719a2cde39c73cef9de7befcdfd2d66b4b7bff12028e0f101294d84b840c3470a462466201d75d1e90848195a61f5e168ca0fdc5efadbe94910240b8240218265481057b480d41cd112662a6a8c132b28e02e040cd756102849a89ce0d40308520640983140a464a1e2c40510c9935111d2e6555d8ddb38f8dd0af361e9924349d68fa6266157d8802129a5261e32b67a260c41410f0982a2a949892ac817103f7c70c1439466e82f259099c19744244aa9090a8ecc39e79cefbdf7de527c443ec0a0240ce689c90f214d6c20e941c406a3a4bd83eede5efe0602a28477f8f0d970e2a540442a694811a1a4985d53179ab8462852069cea0dedec19d80610d245dad163462a65c9863486c40416748f98bae8a00c39c1a205081c36869430c46be886fd9d00b55445d483912f1e5cfe101a84a65c0ba65aa937b482f0f1648b0c9e3523c61226526608b75ef3de06e69c7d50f53e1597252a19a8bca8c046783283c8931ce913de93a627534fa2829e420d8837bc1e2cf5d7e5f8c732c8aa4fa1176fd093de1a9c7173dc7600e125c39c679c9ba610d1d438df6ce07fe8fd0f65216cc23226fab0142296e1bf1e946d6baf99f9e7e50a6cabfa6199bf181363368ccd50187fffb15c218aa21df10c85f1f7ce40f6b70fcb9b2ca64bfdc1320330723f9bdae21e329cf1bd4df1fb8da52b00cb2f729acb90e4158ce1dd7baf55f3d38e08553a64a96460db10a49c054910cd411054816ac86b193e67aaa09f814c05a1054cd285a668c8a1e7c0bff54df980a7448bc53b42b725f0c559d66a9db34d6129c862b7fcdb47637ceb31c8f687206827571fc5416b61cdb7640a1f99d0c9c1b9b129512331a2862622044d9f9991a3288b6d3254f96a9d5f506948fd9bfb3edf8c330f571219df555512d62fe86d97785912462a9773ce5a4b298d229cc8990a3319d6ccb8a5c766a091794989112115461369d4d0bef531d93142c4b73e2643484cd598589560a2a566a4d168b49a1a265e374cc27066ba9ccee3964d8298a88db789aa33e6e4e4e4e8e834a1628ef8d6d784eb44931f7642dc80e00408c69d9d9d1d32831202084817b989561a01c9826d060b8f932f12d47ceb73720300c65b3a2983a2c4b7be29a214534b01207f6d82f14e4d89e08460e784597a133a39383736256a2446d4d04484b0cd6874882ac02cf18223822561749c523921088aa484ac938e132ad830b168945b8afc0c4326bc68e848899991231566038706d1cd0e239b213a4a30992aaa994cac6c9060a265a7b5d69a82315d7feb63520393309ace86081ebb10416cd04415f5262a8d99265486664db878904d7ed831dec8213a39e186cc49ba23e684851aa1132c37b8932f43dbc90d3b4027658af41411529e5a3ac2535335eed4145defb4292d1ffcd63795f5d1ee23d8023e59e25be2b464e95bdf12a325ba6f7d4ac094e8a0e4031f64b21efb0dac5d896f48fcd6a7c40bf641c99492ababc487858060d207c119200882e08f26a25087900677a8b114d284e11dba091dace7e8503dc91a94e42b4c122466bcf762cc138db4d6201855c453ce79185acd2c91c964a298e497646b4cb2823706b039e0e7d817f176154a5d498ffa2234fbd617d545c443823f01a933f7db8bbc040201f4e2b618e31133cc736dff9219d8b818b18ddb14d857f043476b3c7bf4454ebfe696851d710f8fcd047e36730aa2c5a2f56507fa46e2e5fa10a32d6aaaafb259dd30ba33624f00dc83e260d082a6f4511c9c9da8a28f5a8083a0d8d8826754f75e8ca3aea2bc447dd13db2d805586b1570ab751085e7a1bdcdef78100790531190d308a2f6fa014d4254469078b5d0e584a61774d3179ef7575fee2f3741109402b414ee28255ff6ad2fca298c41b4f65e33ebecbdf7de7befbdf7de7befbdf7de7befbdf7de7befbdf7de7b2fba818fbd05bef501c8e106669d55d4e8257428ae216ea4eb30a2e087944767ea4ffd460791fcd04d80e84e1d878efa5d87922123fcd60745a34a67ad7315adb5d63e1be11721dea5db5a6badb5d65aeb6c0408adb5d65a67adb5a761afb5d62a88ba8a25fdf6740a88dedffa527507df7b8d4714cbba89283cea5b1b06904b48f79acd209819d9863a67af71f634ecb3efb55c5321a4ffe8469a7c281e62987d829e62a1b7d6ca96430d84107eed67e4e86b6258da0f96f6675d0a217dac14a2abe1483f2bc30bf8482396b73b01f6b3d25e1e74001ff75c1eec555c1bf6b5ec53002b1fdb5800d62dc0bdfff6a3dca3376ec6caedc972460df7c4bd088e3e635b08e619c83fea01720485903e24fb17652338f379a96d8ad9ec87a017b1b517eb99ec8f250df3e0fc18085a52cfb62eb729fbb924ff588699272c6d987df815b198afc559cfb6977d3fe652fcbae4403813ee6d86f8321c16112dc6222f8b4d3a7c122a01b76028c205a6880ef95a2344bf48994fab293226c43db1582c261399b81451c59510522ecd0fdb9c6ddae5a75b61956aa824ecd80e5a2ad1d400000000b317000020100806c4912c0992344f7b7a14800a5d72545a462a1e0705b160288e6320866328864100046000844100c42006a1e47410006e8ffb422d49fc08312637e2f9ef1fc0b097c67243cd98517bdb757979380488d44fbbf2bfac67a49e2fd61c73c4f096281ef7e695377fa4502d8c90d91af4f16175627f59503ee554afdc088604a277fd4231aba136b6f69637d4817448e83360478e2681230eb51ff3d06bda109646a40ff044464e099225e80e5efba5e6b0e246c4204dc9b65ae99f1bbd2a268adc7fc1dc7394229717a940b2a944a917d6167b05dbeacb04a91603e49a6e44994c7f55c12837fbc94db18909cbcc5df348d64800fd7469e84af47d0e4b265b15aee96dbdf65106fd470bdb0aa8f537aa839eb7a9843be249d55f3588058f951aff61295f6527fc2fa2aff035885538e4cc491640fcc1dfcb376a73adfb1b30ffe5b2e675b86f830915313c1a2886fb0a1308cfafccff2b30e216372bfd475aa2c94c119cf64bf526615e83ebea53ebd40cfd609c9027d517b4a8a5e6b03e905a2af1511ed63cadee9ddba9f1cb6219bce23de497d3c447416002b438e32d0ac577daf2dacd63e3eb06ff1f7db3d2fa0a300be94bb95aa6e43d21791a438682ed65de976238454bc4b79521b7604bef3850d6c476c16d33edc24ac6784d300fb32342ff55297c9127f563007304f3efc57a180d853f46a7d12b8815e56ea80c095abc6ca08bf07eea123e261379e2e004e0af3a0673dd1ffe9bbfc793ec118d7b51f00790562ea69a474564e6a740dbd1763f608c70b8469ed074eeeee58d3a086f6317871d7ec1db6359a2dbd9461cf62b5fb87f09782308674d94a6e1f13d468fc1f449187c1c51a61e50e711bee1030b27fe322bd347070fc223582793f6a3a3fe07c446201ec1f43fdf4baedcfe1711cf0483218a803787e832123c39df2110db41cf49a81c62d9ee17546e83ac78958dc53b7bb46665315ee6ee73edaba69c84a46dcb18011e9f9018db036645e878c71fbc37c05f947909930f254320d1419d4d5ce38154171bd962910b481f2ed00fdde73920de0a2bbab775df212716a947f55c061cb08bca3272177493d3f558fc150a17a297cb4050c1a0b91d152894b909e6d54f9ee7ad5095eb373ca385cf4b1d0a20afcf5bb81e7944802a383c2d90a7209e846802f224c813104c409a066122e429084f009c454c70acd66d663202815e85c84cdee4a26d9926e5226b0f8bcedbf5e47762b8440ccdb4281c374d665125f8d5440c1187875089661238e33ee86c0665cf67be6ba2a7ea571cdce008a1743e70550beca003863934374ddf502b729eae08013ace2b009e1d29662fb60366c0555236416538a200d0b28086a8cae3844e09cbba78a2f4bce73b1ad156d96606d7478f77c22db57bb8a6d17ba5796ee7bfd4787f6c16e53add3f58442de85efc03a898a29928e26b6c54d5d1bfaddde8100d7ab93a99fba78d03b4b2448dd3cbed30bcbdeabd5efeaf3606ba0d4717bb353211a6e5c6417e0b6ce5dfaffcdb9d7fbff36fd7c2c5057ba5406633dba0695ad2835c4b42c34cb3c872761e213874cce033ae3998618712dc76bf02b956e657b530b58b1cfe395d247973b2c681c353be2088c42a1b4ad7c6cefccf8bb139538818a9661cddd7bca1bb1387fcd9df423bbc710eda7ba05effeac78e44cd8515b9eca9ac171e8494fe32a9f1c1fc162397b9a8dfc300039770d996bf595e1680fbef71084d3c3eff28f34fa2f4d498b18becd03338f7a98bb1138a8e31102d78166d0da3f0c1390307953ffe5bf2d952e1f62dd4f3d035b1db51aef4010b2cbba8f314ecee43a5710069d32585a9616e98c82a8e80e1e1509ab0bfa2a970c9b41626a6362e59ed416a6ce2b3dd1e8adadb78b0691da4e6263e9bed416a6c164e0376483485da727f994bba04223bd4a7052cc4a6202292f4dd3e8d10065a1bae7b3ec215e1512c0e2731c80129911ffa47da7326ab56cc79dcc7644e4d9ccf7d9becdce4e6729f4be6d4cc66b91f4b7ed6cc59fe7adfff710e4735da82404391dc115e39b0605f4b07ba60c4664b0c6f2d925b422b07312f60c74d8c98bd2b23b9eadb1d0c036ffe09561b0824ccdcdc35bc5b2e39d6a7b2d923e04f25802256f6617c71d492ac5cacf1c2e2dab3f29ea645ae3eb985432bc599ca1936d9e9d71b07714a83161737c1c13e8293c7b7a1b5282f062a97621cf52a39fa61a623ed41eb17ada6a13e21fca1530822cf174cc7707aa7ad8adb34ede3db96a8c7c9c3a27e254da4cb3a59014239f008485563fe4acf47f99b55a0afb902dc366651b411301a400562e022c22cc41a507fb30918c75a1eb44b32f5edb47990d9f52a07e6d1e47975b1a32ac7d1a726e3605f21cd82aea302dd37ee70f66b24453597d948131b9ab84ed27934c871c9597681f4221b89e16129182dd16d26f1b55cc230c209ee5b3659e915936713c333d06d38ba385a7472c9556581063b8cf88625932bd5bd73557cc8b4c211dc32c1148323fdaadc0f59e5c257bc305b7d6c7355756676b2ccfd8b2009fd5e6e5293ad84aefc319f991861c74ad4462efd3fb688538fd57093a2c10f68a54d2f1aacd1c7ee4c4787f603edba71d1fcd2ce47e52196cbe3a00e6687635997d78908f52a4e5093a1d2ac2e30d2a30c177dbd561f9b4db804fc43d645491c960de58048f035b28cf07b0717e830f956029f6aca1084f189b1963f8ac8d9d3ec780b17aee82c95c57a560e41083520c9b4ace80e535ed07bbe59bc05043d696e24a68c4d5f61544dbb256c347e979eee10d613fcf4ce10f69bbe83d4e1d79e6274481a21822b8ee24fd4bf722e685f2891e4581d0dbda8947cfe1e036b04e04b77f1e17edcac63607b075f94154d876f112ec59a3ba8ee33e6f5ad5924506c1373964cf91c106d08ebeed1891f81cd4700c2c5b5d7570caa9551c237b7d7a6dcb04a0426418ca169cfb39ecc16d56f8e8406165d1e553c2e6761a0efafd422166cee91e508d50e655afa575b43c0418995a8b9d038abf0d7f46c086f6580d6d93491fb096bdba802a10a2b5ea820f1215219b8dcd9c60a795a2cc0a968e84dc79e60e92d3484fe9c08176b10ac6d2916fac7cf9a59992c343424d13e190635c951319eacf8f8adbb07154bd28f437569ea4ab73a4f732e7877d482405d61d6e549677512626bc257a67ea7b512750898ec9f8388edbed13e37c3650889918bbdd7181bd25fef6241032ecd42c9fd77a536306b586113175b1f47082c1d2a8032caf53241c54756e599355f7ffcbb8c9aad8ffcc6b6ec9a39ce2ffcbfe3f9e5f77fadfb6be498b3f02db722fffaf3df09ef45fce5f7bf67addb96ff5e61e10b134b1188a95a583ff0e1014b99b58d6ca98cea207aca264fcfb6f39144a71b5bb20a916bba5661deede8d5918fc137743fbc1600af0b9e624af47eb737b83e4a24812dce01f519d4eb76c3de085a1ac1dc731f53adf344298bcc50fecae6baf5522903b5c98af35dfd6fbb903123dc28e52103b6129daaa4610b2155f10c7a1dbd56d193ee13313fe68ee30638081c2a863233f6d34802bac0eec83d7c1819c471e0029da0860727603f779ae15f6ee3b04df90202441f3405b051f4dd3026e4bf9582997cbe39eb6c875c7b69ad065ea3ea45803cf1cc16e52b2273c7e3421703f3284d2375831b9d0427941c7fda5fdbd17fb7aed64a549ff2a5437de9323dbf4391b43e178b6c4e03f053787c31dedde486f3ced8e34f77688e86fe9fb059ffa57cc8f84404cce6b712fe4cc5cb838feea377b16a522503311324bdb7013752311eecfb7640e97e406b824a0b4cbd2ed1f70f90c034ae2c37a5561b70dc742f74a6ed2d730933c64fdf7e73ec5c55aa3f79c738c822ef6e4c4a9c15ffab0ca9dd3c55fea3dc78a32f55460ebde5bdf60ebc4ba4bcfeba8e3128f50e6d894e0e52a1e155cad209426bb8abe2262c92d97baf3228342a0365e8f7ff6a23a4f112bdb57f87e2e0f0a88dde70d636203d1cb25e0e5827955f6482abe6263a08ba5a847a346054fb021eaf924795ceb71c3a3c8f2374b7ff2e6ab5520f1abce059dfdd750d2dddef7cd1f120f6dc86a690d23360cb37b559bfed680cf001992321008fa3a84924785f3b643ac2d84626361674f3ff3a09aa5b1c1848c4f711d65a5cd16cf21ed0c2570c59bd8e2b51c8e26abd03a3582a7994ae7c604bfb987edb35d93a8d771e651ea1b211e087def4b9a5213155e0644a3a3c27e36ae324a75d0d604958e4f09aeaf997e09c98bebdcfce32d99f07f69dab13f663cd9cb37a3f948bf4caa38b343566adb6a139661d14323dff528128dcbf735a6deb3036ae1467b69a0f9ae1b7093508c274d506ff5be92ca174b0b79d53b97dc413c9da2d3d2baad3688f2b55a1a3dab33ffbffee94da063bfa05020847a610d49bb05507c096f449d22d7d704c0dd8d271c10af2216a54c44c0d7f3b50c65dddecca13cb7c2b38b2b629d5ffeec4c6c2cc5fd05964707c2dcb81a53c309d42faaa20886117cced9eb237ba2f84540146048e05777ffe1261914def07f9dff33c1fde8d1fbfa561597fef2d6cb537c140cdce2178106a96f2cce732247c2a868baee75eca8a1570d3f68831672934008975aedd6535e299420d25bf618351d2fa307c4330a3c3f632e9c1d1f08d2023b9950c3682e8164791f8668c22e94d66d8647ddefd9eadc487eb34c3a77b990ad5b3e13b0da18308eb68e231d77606b7faf1fa5b6ec309f18e859ca6a59533677706d96a21bc6b3501d9fbefc55c467b679dfda25f2a676fa7ebeaf073cbf6abfae09dcb8e0dbd7c9fca7b658d4d1c653b14733f2bb84c1d292e0f1d801a82e2e1d9298fb02e366e3a18910b4c8163daa1c333527f1018ef7b1816cc2bffac0548c84de58c9f0f081c36abc14cb903d180a3b323b9c7d1f2ee828074fbe9dc0ce37a3f186d16baf45f4e29d9fdfe8d598538538b5a3994f33e95f3ef19367c423bffb17d5f584e562d425de5f1b87429cc6d2dd810681a0ffb4fd9a6d4f8a9fc024c5d6f180d83f3f2b4dd67128df7dae2bd73bd206544ec19bd854b87fa997087287917e638773be80a5a23fc62d16ff81d397180f58c665bbb424a3295b7756a13bf0c12d2ccd14cce58671f37275d56e7f83aa01d73bb67d6fb844e684d9b76725afd9af2baa5705ab390dd95bbf87a1c1515e2351bf564bb4753a080fa69f631b763407e5688f5aa33f754ef7bedfa49d02b6a65fc8890fd9cd3b65bfb65dfb4d8885291af121c9dc489e8e7398666f566395223d372cb08675e7a6e1cf1409f65f2b9b971eb5cc85b052fc93533bf2ff0b14c766be355ff9f05558bae41ed5f82ae74bf8391863e7432cdc9785623fe32fb8e680b4592678715e9af9c1bd97b33b5ab4313f60285e9c273904d620259cdaa836a59900217dcb22aff5b9182a1911a1bd6a5f9383be5f6f11f8273667063bfe078135f9c4e151cb6a5d63d08ede11ae38077c61464af840aaa51985b83acd3194456b29cd8584768a424b694ef60c5580da07f5fc1b557eb70d852e70e46a7ec2fdff5b9277f9d5b3d859e713b52f39956824edaf48f82a1a7fe21069d64e13821fc1243e6ef79d3541983aa9cfd844cd49c965ddec90acb424c88495d88fb259eda191a2359dbdf889cc3187fdce02f3ca86804ee8ab5acf7173099d6b02c842abda5eae394ca34587095aaf1c6034b537085abcbec716197fdc12b2d50ec889fc78ac06f0ee9171d5901166db205fe2f13606136d75c8fb0bd68521cae36c539dbed354c901c48d1a4e6b9ec99f02bde1b8396f144ba16d6ee65e0dcb6dffc4e3c157ad401424d1f669060757b096ed8a6b46766e1ed6750cbfb69b9f90a013561470052f27f032e4cdeb34805ce484cad5e7a2a80549d236677d0907cc8e0764b9c962523f74fbe02804d6e03f51f247136122a17a7596484a75d048e268a31d0cb5dadbbfb8b4cd2f1ac0056d31fddf5bb6e224229491de389c4bb92d57a6c18f956afedb33c967d3ef2579f32757536ca8333c4eb1f7a2748f40881b2e5d10c1d0176ba0857aebf1b97db941e6afa914422c526767c98fb0a60329d2bba62e24d0366bbe4e37fdb13aa0c6a8ad0c237f5038ae3c34256e57ea4f404efb6dab8df55eb99f62d88b91044f1ce7897505070335890e65703f3ea8c973144f92fb5b7167cc772c04ab6eb5a3854ab8778cca87c4b1c4b39a622e642e48ddc7557198b5aad176a3ddbbea021d9fd23c563278443636cb7a642b4fc40f3f9e8071b8364d7f37757f368a490383d903be7d672db021538a44860f064bae91f00d43f14eec002621ce617c178321a7ba967d33424fc201cdec2a5a3303f6bd8e5ba32201c2bc0c7abd6d9c08ec1e2ad0876420228e2653d1d58cc46bd37c2341ed3c41dd85c294d682e00cef89ddda072e1c2f75bd607d57e06dbabc5e68e04cc88f54cb3be648b4443fdd2f47d1a78e69dafd5161a6e4081013abc020b39e610d9ad455ea056ab9c234103c1e7708be0765772d82e67c6fb54b0803a379af00ea5c7169bcc2b1db25b1074f6529c8a92f2e531697ca00a35751a07c0f81c5df7ccffd4e64793c6f057e88616331d91560547641e2916cc703794aabdd67065c2de9ff8cc64f681cb1334d4231ddc41441721fac510d2d949e7017c4a00c04de734536311032d579eca03c487c795c60ae0df45e2840ff7743bb05d474a12e2fc2030ed7ea663b4d05a85e8f92cac732556bc0f4f4d552b0801062f6f3dcd27cb691051a24458e10bf381d23074fd80f18a8dd60226b20187cdcf14f3e32ab9e4b8522f29d03686e1c5acc51f2c4ae82d12fa8684df9f347c98731b4c326472ea6c9ce5b5d40b1990514279598a15f8ad155dccf96091458a2e3164e69779c90843f551681a79183529e2ca7b6ba17fe82c3ed65f29e646770a8c4ba95621be454d65c0b9cb56054eb95e5118d49cf44d0d5b7d08df9c57ab6051ced0acde3e388c066705fd474b25efc2aa6ee816e942c69d034494a6c397bf492fe7cc5457c69bb4854484e21a7e86accdc2597a98092313aa5115bb0a28727d1ce71ed4c583b40e2abf6f560dfd51d64f51e55f19496d538aa6c9f9a9892b3f7929a6ff7cd464974ee2d0ef2587b22cd68a39e1da7d6c5e8335e891627223208401107e0ef377ce94fce3ed253abf13fae146bc51c6c4bd884e31b2278c5886e154331b3b9f51981d4dc1126a70208a3ca781a289145de2f9cda337f14f993db17afd5909d6e53f2608ac1e7e080b2d30fdd59cc391032c6a83f2ce413a265403db96ce68ad3515c2a9f8ff94fbb694c34d54a0714a7e42ccfa0c12a86246e176b816a8418c21083f1bf6355d9496da06881045a42876e44fda61f7746cb79b3a300b19ec06ac043b005bb0eb6222ec641c80dd8d6522e7645755e26f57e462ce838b162d7ac586c8f9db8730b749039b2231c25d0edb336ace2d600decf40d72a2f6787903b4f0973c4dd37e4bf5530629cbccbc8cb4b0ff918dc752d2aa8006e669b5bc080e60fdd591746310e0f5d723d3ecbd7df2d36164ea30eada813762a1c6e385582b6743b937dd558cfc3d1d5a7e30e62c48e8c4e26438e09c9e32b1d790b01370afb9953c87cf9acc0d3b6678cdaf323cedb63153cb2896775a44336580b8a8e05d6b5500e673fd5ca445f8980250ed2dc64414d1991ab4944470193455ead75755a292f919a556456d3c70977fffa95157af631be78d94852a296206d03cc2784013078333c6488e2299ffdd66ff37aa6223c19da462a2b5ff858d83c6cfc1bb092778c6248014fe58171d1531be4278c0f9821603cb8f48e50d9e82046e24fea979df8d4c3e168f91e49f85f15c4b0a1236085ebfffa767672507b663f23de57e92778b7359323393e55fed368f1db819a3ca195f24aa9430b51ff522600667f0184c7f4129f59411f001409144448c3da41b2c3ff8e9982cb57a68b7d0ae45325fe01ab3314e7eaedd41d24a357559908aaa578b191975f7828cbec87839a9222d411c06a10a51157410e12ae42288f22720d3e11e48a74c65a9b81ca72778c23c5fe7d7fc494cf4f51561da494e5efa6e7d4e0089a6fdd8c4450e046145b4738314277b4e69524a46ebf2d5346297ab0588a04a4cd647224aa45cef2669ca1cf1cf234e446254a9ad00d49ee193df4bbabfd7a585e7c63e20fb0a8aef5bb17551b1749dc1c9bfb66f9ee1274b58ec8265e2cd288fb486bbf405a5a2ae2207b81af4772749a5bb2422b12de828e1f9abafa80e2d55492b630acfb76f3f6c610a2d3e7a9565b227df0277d853a4656a4570a1c7035647d0e512968e9e7b88333a1b60037d1adc0d0397aee6ad8f0aecef717f53c03b661d6e12775f16add8ada4d37b9e94f88a07cb726603d691819dfe7eafd050bb5295d330ae7b324bc5965074696f7c1bee4709d623a448d3d517ed15a7600034adc86a32e9dbc2f7a1f9e88527baabb0fbc019dec498808bed2e0e216c1b5151ee5c5bf0e94994a419742f038b39773a214aabe9b90620f90f87f2ba105d51f29d48530f750e29026418fae038c24cb7e129d2bf8d79998f0b4b70048b3b6c5e610356c7356744e5dc4c3fe67a3b19dc5cdf57a0b77de7aca6ad4d11e212489162a44039c40ae97798a0e170be3476e8dac599e8f1f1ff8a3a81bc7435702d7779bb439586b1581319b1d0574c70ccba8689175b714dfc959eed1a86613dbf07c71c5694d6cbe369e667b6f720c8c99dc8d1b1c460f2a68e2824dcc6e26deb1eb5c9d8aacaaf5c0e2a44283d8bdba2e5336973e0ddda6969c05a6bb45a4517aa7dd1c242bdfb06a3dddc254058fe68437f0008b65cbdf9c3ad46817b1b3fa63d4a4f534743d7d65d7d244aa69e79f842e4c728aa3ad5da317a84da03b251a1183d9d7f478bad46c147cf5d8e3eb46eed49eaa76c91484f6b13e1affe0968b1805a17d8335816d455cd6e9980d1a388350797ce662c190d89bf495a116b6b226461f5db21a03d461b424bad123b5a7cc03e7e86893e2022b43284676b7d131755496d41fbb2687b90b9a8459a4b8eb6b8a1f053ec31bf9e11d55d273fcfddfe680b477739b078c0d03e58d04985a6d579016c572ee147642c8439b6434553f284abf0e9366bfdf1543387d87246d233c76f092087b0d90c55c07293928a373392be273713073892efb7b9b212611cd6e663b2127bce39fafccd662ff640ed44e7a1d61b4e3a344a5ccc34b1651874c4dc3b96bf343118b044e7173741357c5a43c141f1d73611cdb7e1c6de6e4e9443d1105fd3b69a4296aba2f2e8c78c93f3c16c1e2dc965798a7243849b4e969303ea2344fb01551a15986e5b662a32f25b022ee72bb4f5b03525bf2671cede714ad62d64963a2eb099cbee5bc24d22560b3c6fff87c9b1ffe39797ae23b0d7288a036275585b887f58e62a3677802fc493a203165c17e8935babdc3ecab7093ae576ce7af805616b0972ccaeb78389663a9568733ca9a84a8a789371e9bf33dc3c3b66a15a988a441f9a893f1ef373cdba8f62e381f1aee775e5d1b1829afdbed6e15c093114a334428be656271514a2675367bfb33801929a9867c9fbaa56a16b22addbb3b5113f3ca2faec193f4d521155665bc3e63a6d8bac229666c50d3b5a4fd74a9d5572d98c982a07a96be110396cd1611001652bb9b62616ebf50fb10628fd91732a3720e83322000f10cf8eeae77a1211255b7c134412d454004fff1cfeeb204cffb20dda4236ec1708edeada2af7ff860e025d43c4940defe22079b0516213bac8cc3015521e8f3eca68819e2338e0bea797890702175d86754a332112b6b97ea80adeb7fcd8ee4ee64d3e6a912def9e70c279abc7da97a7a6a61c0157808b5e6d7cc51482f10508c543c4b062681c4689fa4922803abdacbaa8b1b6256aa9e56c81a18819289cd3be95bce0baa9c878031a94f1b907da908a646c498bdcb75c307f3a465fa010f75eeae118ab5c9485b5519cc8e57e66ca17ac24c539f7836f1c0de0f6b670187cec19d99098dc4c48f6d9d4610a1dbe1c08bb293a51141421cf7af2389d8e716dc034e450602a5b3ab02906ef8cfacb5967d29d9f3d990722091616f4c5195075b74dbe883261b99f8369de27789c2410fa41978c84b5ad86faf66e7da3395e83966877d4030496ca26868ab761252228757ae69e396644581cebcbc6f308c5806e6f058a126620929089c0169168d12a9e6ec9daa5f1bb9c99c1f01d621bb9ce1b8c5d25f05fb65c295e1ef62cf1152e41a7958e953916c0cbd0729afc496ce34373b6143ae771a4ec20e7d4e47bda12bf5586b80f6f2fb18faf644bc85a70e1b21b8795a194cd84d1b8ce4368b5a7223c7496b730b0ab411c04b21b543950e4b8e40b52e42bed8376e33adacd304537a21b55c2db0dc2f5ed86b8ef3528e06be81cbc404f6447528766e3499941c5c3e44ad5398dcc2d6646ac43dc4151cda488f91bdf5a2ded4064811b345d603a88cd04855a73b89b77a025d987d9ccd47c4f7ff8eb5bba1397eb0da658fe7ac7f652e83871730755b9ac42d5506152886132f2e1b1b948a41975948d8377d539f9f692c55f5158a9ee0308e656c331cb0b20b3cfbaa36ee470f7d67381233d94f193c626dfe1bc3e535e5064703906370b143c19c98f73229964fda7200a60df73cf5c4286be8cc471a1dd3b96e38d868d03da97d6f3b60f43aaeaf54b813e2682ad77f53a012ece273980c68ceb7ef33e5b28fe1fe3e10188049e51906d7d8a52fe01ee46b01768aeb3bf4235b55a58f92050a8aa9dd0707516dd1bfa32528b8e297387eaf98289d61120ea6f7114d44ee61ef4a0f45948f75ddd1348164333f3d048c8fa193004758f3c025599729ba9846a4e6d30be8b7b2a4b28928022f24f50bdb6a78278e85455ab614d0cc66e4432f12ec64abec544df43458de14a49a8c818524a296e7955a5e868cc880ad5e0e27ea081fac8a024268aee4d22b16b6ce33280a57652b9bbd7207c946f8267074880f0f408de55192d36cd90fc0807e59184c208cb7f9530745d2b2136adb366fc6019a3c16aee302aabe81f137a9431385e050a24916b4960ac98356b4cd27a3dccb1ca0cec35095532fd843a2f6e22929da897f2c8e7783bc1987ede1c7e9af039652b154d1269396e6ce931c1079a1bcdcd8fc3b36239efa42798dcfba6523086a0dda2911f45595ae6bb43e41ca6cb93d35ce65f1320b2b810483c29e3a3ca5f19ce49c6d708345d85b51bd69020652c66215ddb420dbd0d5fe9aea72e13754d76280f5414dad6db57b972079b93f9d44e59ff16676d66ec182b8db41c08f501327ca02ebcfc86540a99cd24f6d9d1416a863545e421e204049ad500ff3a422012a5f4bd8fa3b6c4a8be864aa803b3cc8eeb6bc4e6a4690b28433456b7f4af32b680e573c9bbffc198e021234b4d1364c482b270194aa9c829ca740e4d81845b57b5d96d4cebb6b7a84c60c214c0429d7fd51090884bfd81bce65233fad1239fe4ea8f7656311b23ebc67b074f83433065c968618638635548e8c0c2cbe12dd3590b1a614d9eebbd47dfea0b5cf8afc2102dfd879d15a150b3742a54666da94c3313298bec36bc9f17f504b0e6c4aefbf2d52965b96babecc9bf7de1fda17639da36115c4e49b9e7040449b450630b7af68d4edb83e6b3fed20f74373af5f46a284c4ae7ad9b0b36367d98a5144eebd74fa556e4c2576e2a6671b790845c335429fb8c3a921cfa7ff185cb02579ac583bd540b38f0bb6f9c4c3c812c604fdd8a29db41ee74fe326cb2e1faabc6857f453b6d63a47626df3ac9be96861b3c0369b8ddcb053a06b28b1a527c3003bd9874d0d30eda80490771af423b838f750d28a055565e53caac817771a6ae4bbc915ae3cc2d0a229895e4da723ccbbfe35e219dc98e86c5572fe90b96f3793814819a7d6e535f51dc11c49fc89161eb5d4197a4cf8c5a2bec838217ce813402e155b2b260880c6dfae570b45042425e093088d3a53ba2b8f658ce30b2833c1bb1ec38a5b4d3f28d8ebb50e21f817215c7b3f8d03cf6d35a4c02bb321c431516419a8018f29e448ed61c26d21f69ed57a2ffdf40ac8f81232775ea41a19e1dd5fc2585b0b41de66cfe55fde106a0c71f827f140eb5d9019ed8d5b261182670605753536cd5db6a411c210147a82416d6e4679cd822561a5942563349a23804840e04b98428ba6a811d931e0a330b1f1ceb949bc5bcce03c5c2136c5b55f26df9652d2519cda952ba878e484860a973e362dfba9050581461a18246e76ace57a1f128ec7198418b37df1d975655d4c37b8485c564b4bf435c84b5f0f3f6a3a2c3ef23d8f6f232afea000d4962443aebd4ba75b6508042c24fffd599056a95964aef3eb455a2ab2ef59128c925b3228ef2729ad4614c73e1e4f1d2ac163cc39ec16289506e079ac9241c00f317b9e5fdbdba10ae93aad6c7d1f3ab15365f7ff22c980bac0d154e9b8d1fe14607eb789f7d7dfa0adefb7a414633bf3e15ad4bede022e0693c5c180abe41b4fd3afef4e96e0570d7d0c791102005f0b1279771fc8878154d639c49cb09373b8733f7c4385939d4d17c0e68c19ba83a702212b4847c1b918fa1cd3eaaeb8475125d212d9b74b938bcd1849e02fc0f2c698c721d54f2a21fed88685f9f737de5e6e0b12d264ef08745e4e6ac22114e90f7d221007a8be2b1af9114a47cb1fd4ad0966c2aa3007108de68946129c92ec1be8bc7de5ad819e1714112797ac15a4b93b869134d3c959e44ed82239e01d4885641900f43c44ead74cc98ddc528a7b8497cfc439db413178ada18f53107bb28702d1378bb0e6435e4f908ea3f0ea338511a88e2c8da015bd772ad1364310a6326d1b181be477cfbf3c69580712385b5caa7c386b9b54601cd6f5fc9c4d19a3719623f3eaca041e8cc6cba0fada6a708c03be4719eabef29fdf83715cfcf2840b633f771d48ec824cd0dfc1a5a5681b47237a8ce384722703387781c60bd40887494785b5054a841f603c2c5bd1550779015127f1f39a8157cd1c315b75343f1dc1b9d982b55f4dd2d2b31c809e366e242f17774412aca3e233781d1f0adb7205840ac90e26c9530307687641a6bdb27133635a3de863f8db1c278e14cfcf9dd9aad3697fcf3a41746150edd7ea4728c52da708599d7dda72ac79cdaa6ebcf558e31b16d77cb93bfa8a431be6cdd6ac79af420d11fc466e2d3302109a5d8484f5d46da134ffe9db3c7ce438d443fc0aea6918fc33743ffb83b0d3ac6a84bd74ed89975499fd4175fd3d0203cb719faedffe9767dc836828dd7787dff24ed9fbffc7e6cc4e2bd429cbc17d6a4f83ae15617d19d8ae6ff90e799be8332c7d310acc9f2b3a45b87bcbad015dbb141f589cdf0ef02de9dd2c384f7055824f3f1ff14adc25a03e2823b91b5dd005ae53ae46b31a691a89aca3ca89ebcdfcca33cee09cad5eb6aaf4978c6ebedf06454a6b5641dc15ca8fbe8662a3ea518ab6286a40483d8210af0bcb88228be070aea2751928926a3fcefedd7ac2bdbfd75d9dd24b788fbfc2ed6f923fe03bd379b056cb2bf093762655e55326e9e10bb12ebe90c1003d1fa101d7f82b5c6f97583139b3f7d5cb8d79681542e6e12c0ac5159527d19eed2967a9fa54d378eea17b188015d9f51731ea7465c4ced306d394e7f75bfa22a6c1cbbd743de4aa9db0735e2bf2f9f7cd05f97d655a9df117aa3af3094d8a193f7eddc39172abc75b6ada8570d2a41ead81888ee706563023d083b310692bc37fe1c334f99737eb40b4d1cf350d7cfc001e9ec7810b3d1dc19369d3b63c06e6cdc0f094d3caf26d9380269d22add88b4677360dc6506af88324c29b15b26b8bbc472e1b44b8f398682460646c03f5280370c0440a382e0236a948a5801a9bb9ab109008185786dff678c6cda7010a919cf6079f2ea6ddb3a5f4dc10a41f5e9cf00deefaf9a2389171db4eedcce667941c8b3d7439b0b37dbb9edbcd8373eb1bd5df4658432ac0445f9642352afae189351197928148d4a02cfdd5f27d0813e2b09195068d38289ac87e951bebf0148042b1d3a8884cd814abc8d4be25cb07525850b92391673b0edf5e87d8b762a4b5a534a0cbbd28ea4603fd0341f30f1732cc20e80232a159d440242e46d53a328f7e3e6460e0761663f2441a06de99bd9635ba6c47a2c0bc5e9dfc91de1dc409712af638638b27a6a08a13d6d1a48421d9e2e682c7c807d2a8b96a666392cab9c19120ed1186624a19afb7542adc35b4884913dca231ca8fadb554df94b528b1b00aa461e2209cf67cd46a366bf5a9e479386e5e705d268ec2387246102e9a0095b0bdd1fa1a773781266ad75ca2894ced15da322d443032886dff68944db2d6a6e593255fbfeb00e2866afd66a9a09b02309d6acfd6145a48b82b4cdd395085b8d3d1586227669ea92ca202c1b5e2b1b5bda4bee51cfd66c0138d062d70390911bb02cfacf0f14b3f7c84919eb6d30fe3a932530eb9f1754c159d37247724a6a7a8608106b76bc784631183bd67a8cfa8f22ef85c79e484346bef320906cedebdb5242c99e30a8f1eadf18117b6d1f1183391d142c8baddaeeda2231b1b083e1196c14e42e6a59d198b6cc40975e0bf0453e0733755d62d967042e82d90cac6d6cd1b728df6bb9a7bd844ccc8165d4a3f97bbc8fcf36e0e1ac55b1cff11e795b3b9656dbd070225e3df0331e405e0382a16673835f0c2a8a75e8361a0b58c7607c4855cc0b2f70e7a61eb35453467f6ee329496911ac00c0226b08ca4625e99a7d22f2ec804794db70d342f975472aa4d015b986a7713e99d44ac2ef876dfc9398487eef0e9dd8da84113e4318590374c2c5dc60e2e767c88b3de91cfd4e2511529bd4c7634956349a550305bb1e65ac4184b7e68caf9ee83a574c0d34b5aeb168799b14e5a5c539b36bf0b694c5b1668f553d3a2b635274ec069a52ebf10b1217b1ff22f8be516628c2985264c852bc7416ac2ab06bac8c1adc026109a91d338d0db4b5c085cff666628278041b1854a9d15f1e245e470a75d0ac64cf54fe8a1fafea14465eb2dfd83eb674a3e9411ef17793adab3b5988f5bd0ff73ee29ab0cc9a1e753d152b5a83633554238457f0ee5b53722033dec41c7f7d3892312f6e10be07ebacab4c9fbab58d6735355344a5a46c5b1bf0b83f4abbd9a5fe6e019881a40ed71402de7d320403ec713141709b970a6885ec7d38358df9d69c096b4c6e79cc59d681d0ccea2328bd199b1e83e7aa208103b1ee4e7e359463e0027fac323332a32cbed6a14cba610e0480385147cd59a64bb0824dc7c1ee0270112aade3760e5b2218ac60bcab7b27485ca4180b32caa1ec350e38da396490c5f8390b7a9a7b8fdc20aada574808e7df0a5d109645542373c03075dd3e449e6b2a4e85130035524c0a500e9e23f5dd2b3049db73392b78c58f156f2b88844d0c8310b1a242732dd58109215ae4d1d0465d4636f928904151ece1531446b08a8abf9a11c416eb745e086796bb925cf00e438a1ce07bd1f1d1c80377a45f0e063e7c05c0e2ae199b49961eef270e9c5f1309c1e66ca7c4172ebb2c9cfabab0c1b8ed4e204416667acbd067364931d04bf63afb44531c7ef5709493fe709e331f668420700c4463cbad318caac7c37f05595edcd196e99d46db361048584f1d48f9601e23609e25831e1b9908a21ea7d14bc33da2e0082cf956e0a591fd95fef3db1dc74df026089a979399969bdfe6fabf09a4a7ff49cbd7ae06eeb182e01341452c883294ddee5a4531ca0497470c43c71658d16e1cbaae7f4cc573f1f585566bdcc98ee47cc40bef2e56b42b3e9874ed8629e83946d749745a8053be1117debde8d94197aa78afd5e820f072c2c650a380b38db98700c2ce3737afc93ef8d39f13bc5570e248a8f14595dd902576daba310c85296a4773bb5d3757be046da5b723c6e359209c13d76beec64edf3a7d44f3d19965784fb0a6a0e7f751bd559b8b54dd9bfa54f28022df43b2083e0762431d757362461b2218ea1d76600a4290394aa5f2499c5c62152d548a59949780680ba7cdb3679b4a7153ba17b5f3b62f71252844d96a0dbc980d8c3b164b2301a30438ff42fda8ff871c0dab451f10052e120856104b0dd3cef3ad2cca4ccdb653b7fd6edddaade8d7c26a88956461477326ba0ed5d85fd8904062c7c3369c4a4135b69528f53a2c87ca67eecabaa035672a6d36410842af8f9177d98edc10c913952671d42660a17c7635dc3ac33ed6cf1f96a0d68d4fa70ac88d01a27124bcda088eb4dbbc5d704443cac00651ea1841fb0d2f158b6a3e1e8b752b981826d83b653ceda04ec35086f65d73a98f4ddb16a4a55e55fdc664e1b4c9553582858ea15b8a7c3fad7b588c32d9719c8d30eec94d55710b1b6cd6418af91b822cd9f47a131097686a9ce335164671879d0f67ffb135e7a1c0b97f1651d16172d741aa82446e4f795f4dbe4ae184ea3fde038927f719bc6b32bc0b2d97806c6fb8791304c76471974a75c8402bf207ee7a6cee4159c7a5a11f7db4df4794f221ec888eb0ce6fc08919d23465799d850e6cfe1faa4f124b6e6087977570b7c55f5758e695eaa45e5b053431a0bf4fcbecd9b175455e4b2333340122c2a2ddd7a21b1bc4f78c198c44816188a106dd44abab91319ca8be7cce96ca8f5b5faf16b44343a4a8ae1a26ba7f9bf7398b76ac19f232c68538a9c8b416e13913f2be6306a3e614ae8cb3a7e7559773ffd74006652f727ede8245de34e25c8268e8555408b176ba37942c038a4556725b409819a7036bc54010534b2f57cb56c8b1321ba08f0af47bdb7bf80848ace1e7810d467412f2a2a4dec6e9e850abb559d80e701fec9ca1233d89a81a1dc2e535ea8006f786e3634b2e191be16724cda2bdf7de726f29a594494a193e07ec061b07326b6aa5472dbad4fa06bc82cf4b1fa01e444c3e403da84fa443344551d4084d022529350511297232051131a554434e5629d550aa1dc3864140c2430c5eb7c21139046b10903a8c01cec02e2f9f945569144b5b974a415954c71444a416a9a76aaa41954835615c5377a83a79e9575d61aa3a5453d6f6b03eb555a7a8536a0bbb0d7c825996655996651984f8de135604a332a122724666599665599665539b10420821c45886d955265db3ac8d732267a45dc919e94237898b3a0915c92084104288337c5bdae6c3dd29ee94ab95467f3986979397ded7aa2fd53574652bbea3883673b118be455efae82467a40dd3050bc28860221666c258188b85b13016c6c258988905bd52980933bd3c66c24c3ef311635d128391432fb5d56ad556a457ea5ea92b75a5703405b54e2da116aa65a4b55aad56ab183361ec3dcdd3e9745bb7d538b6eb5e5edc67663e567abbeee5c59d622cbbb0dbf7744ff7744fa7d36c8fd48a464c1c4ba3bff65a3bed3d65ddcb8b7bbc27acdaae5fe2ad5476dd4bbc5237c6d876b55aad56ad28ec285b61478f6131c66b57766557766557ad9eb627567bd6cc52ecf6ac2dda954e7cad3dd9138bc562b158180583c032e2adf032d50ae2e53d45f1b23d0813a9073dd822fee87bd332ef58b16c95ad62b68ad92acad3eaa563f76ead75e630631c669ad65adf34ebd8957ae95d6f96ad765b96ca9a6134db7b7ae911637cb15bec15679a6d88ff653eab9757ce10f044f76154678ca2a8c6b9b7eb5e5e4ed99ee449a8856a1969a55aaa56f438c59540a6940c4abd8c295535ad9e5413ab9aaa299a9a267ad01562a158a8c691e2b6ba171f0742c1689ae8f2a63a958bcbb5ddd16b3e38a8684da23b0015254e90f2b104027230b4448785ee4887640912212059c1d529b664caf4358b8463f4f0bf8962d1811695cede3e1c5c60ecba73fb3ce02b1db76974fb72f0eaf67d20dbedd30100394fd48b2d7a4f8cf308994862c99886992fad0fc60067c0c019311e3db6e00c924797293843c6a3b709ce60e1d19b0567b4f0783d7618ceb48dbbae118ff9d759e1db5b78cd6ae14d67e1893a2bc860ff5686be9d85375dc61bad0c9132ff5882f8f6e924cf258818cd3f9628be9de44d5fc11205cce630de8bc7b4c0e08573187c5a71ad53ef7a2effe2c5006ba2aff0e209d64477f1620bd6441f7932056ba28bbc36c19ad18a7ff4075bc19a66f12f623eb0069f5a2c0b5d614f4c186c710a1f3df33e79e4eb2197c441e90a9fe88a5bc119179f7a7e13064d45321127c1f0c5477d7c1ab6bec86a31992e3f1d52389a8d848fde2c5813659ef45ecc7b30efbdbcf4563c757cb759848bd63775cdb5a865ac23cb5ffcec8752b7fed19f0d056b46cff9d810d17d22d10aced09c5ecaf2977f31ad9813ace9d1c926a8fb625aa3131317a798d6b747a751e403675087abd5f7e8b9554c2bc604a2d5b75bcf67445db41e02a007c7090463998e24968ce986e9f9d274c5bbf0d3e5eaf2304314f599a8ba045600c21cc09051e3460c0e58e204ca4489baecce18a3944a4c18326adc88618913d669ce0a4c4a274001154cc98061810ea67ce8f19f4fa00211a0404ade4cf472a3009f0fbd8ca8cbaed7f3225a42a6645e449e0e2f432d99970fc830114f32d0cb4185310dceb4e830f366901cf182c66790f02002d043b2e476672ad84688140f41c0a486e8614ed1cb29754ac5208854925413292852494855e1c8cf111f8e88e0c8e9080d8e3871a40847a42cf1b3c40f4b9060092388582235648927967002921d900081a40824228091e252f51c710414522498a2c7116a606487035021a2424b9b8319e347f7751da414c25a2184a3cf1f85d06db00217282cf4075a8fd7f7f4c803fec01be983a24268ca498aece8edd1db07ce8899c5d320a889b2465f9d06619294c562511605920d6fe82579c01b1bc4024909d438d6d434edf776ddcb8b5b09f4ed314d7f200dd23f70264a69dbd45a104b33c19af6ea65ac201a91079237da1038d3de6e4d8d9361d68459933561d6f46d6d4eddca0ac7711c9727ea5e28374a27e5c5a998e9ae79852567da1190a4fb38d3f787a5e00cebfd6143a6b767514c5913f9a6c2a7bc48e9a260a6f7d17458bcad9e5cb50fac914efac7a64717bd4e149cd1423a8b09c8085ea044143bb8410a94e84113258ef0ddc3264a30196203c406880d101b2036406c80d800b1016203c40648b7a94d2b205216c1d231a713652667a04e741833461ae34cd3484d062f612f4306adf693a1c9d664885a294a4d06d9b0bbbbb16f1b3794b0a7b9847d8c1ffdd34a11d6e870f0af0b8335ed989b0186569241839aa6695a94776bef7c610d8c18dba6d36b65c3c33499682a55351b363c70363cd8f0d06aa552363c74d16f1502dbf8e83eb912c9530b4b2ab5d241168bdb1eba8d8f2ecad595e574124b3a25598245609d2c93a145221999ae13fd849cce8ca1870f1f97b351b55266d34307a3a63321bcd7365d27c39e5244ae3d36952fad0d94ce8679611b8ed89df19ab0263a9481a2dbddd938f7fb9a5346447367b3fb32932965c09433b6ce799b200351caee39298d40db79e955313c316e1931bd2a66f1cd2cbed9a561dbbc346cc31de6b24e5bd958288c6c850555048ae49429a6b454434e5643aaa1542c728a4488c8292d18854620468c18a5944db349ab4ebcd7bdae96f1b2f7c2328c319c655ab6711bc7b58cdc96699acec6719a4e97adb0acb0b0b48c2c2e5aa965c58b561a65302e2b9a0ef45a7462369a18ba8c5c5c5a4697bbbd74cffb34f6f6ed4487734e9c2f36e7f4e637edd67456bcbdd865adb598b5d35a6bed75edf4eb4aaae998f9b6e946c843092990844f3a6ae393975716e8cf6c8fc55fded65235ce3645d3480e48b5b5b6d6d6ea161364e1f2b656d3c89693cb907449c99bea2245ba44912e50a48b93974e3efae7b2848a96bca153e4cd9c42de74a576fee5614b248dc4542a39832d59c11a2d74dfd6f29137ad29db141b15f2e65bf1755e9756d5814b0a08bfa4c17f7008d4f412dbcbe23153e36ca92d65dab6ead7bf2d55ab7f5baa4ee1c8cb2d15595ab046b66c445c4cf2a65b522da996544baa25d5927ae92d2d432d2a79533b4eaf81608dcbb74b8afec0d39b529bd81f3555df54adb219a28bdda8875b13df4e297702426219329a26ca905b89239164b86e9d86ead46fce35dfdb349dcc3147aa95566c94d424dd37bfe5a7cd5027fae9525e2ddb24d1c52bca0b5e6c6b27dd90de5e923d5f431281319761fc51d4b7a653dfc87f14e86d6ad055bf016b885570cc3c29b1d7ddd8f1cc326fce39b1639a651ea59452ecb86699576badb5629b1d7498dbcbc4baa936b5de9e5aab78faaa8fcd0ebaead22f4dbb41d2720ed1e38b23f3cb4b198682b08694b9e6a4cb7b5ecb37645987c5e37cb17458fccd14251de766f19ac128de8f919a1a678547fa03def847857c747aca31c688b1fce1b07acc514d2353724652247086b653148433b5d2f8613b284a9ea09b2e47269733487ec09919e9338c3821409aea9c569d73711f2b1cd3918f1c7e3b962b3c52fb8b8baff0f615390717f44b0e2feee23d2fc4c0886ed0d152fdf651ae21561901c119edb2c5041f9dc5e1ca908ff407a489dc133883d5382b5c6699f4ce21bcf1cd6732051279df28e873b132faf1f573f9e384c0b546a7978e791f0eabdf415114f5d6e9e9079cb12e1d00f046c85b97426ffd02a2264863ddc50bd2b1d666085dbbcd50d6da3b28ea5b89234a7c8f50228991c819e19c46584c2f81e04b0cce64cd3f2af4d0e9095221909a204ee6d0e90f48233a0df2d03953e36c99b23267b2e1728af1cc32d8278cfdbad8832f5cd7b30cfef51e76d043037cfde3a3d7201f9d0e5961c1dc4040d663f114d248bf1733cd39e4a5694b99b0282c2aa64c912225caf871a697ce9938225c90bcb93850a9542a954aa552a9542a954aa552a9542a954aa552a9542a954aa552a9542a1b51d3a13eb0a6064e1d162f7bfac5c79d80e00c4b516f13854e7af42b0585eebb36159cc18241789abfedfaf9c1cd66884efa47b1a09f6ee24e47800143768c4d23290db64ae9356469ba9c5396f07575c38011a76629a494522aafe82713dd97f54caae190d7a7cb3c610dac69995a09879c5a69c57a751f975fa71a4906ebd569b8f2a55aa9ab1a8e98a356e2ee35fd0686b51968b075bb1a0d36cbc8329ae6d2269c1eb506c09f594e6d06ebf501366b250be5dda64f69b51b4ad84b2f613f1d7311d640ae143de64b2be19f4e6dc520b6b5b75779a83580ce9921f61a983d536a3f983aa61e9cb7e34837e0432fc187f9c78f87def398d6607f3a8e1a62154ef3cc7d60c73c063d741ab0e9a197ea4f2f553c1dca58a5045fca1ca34ae7f2d6932bde76976646bd3927cc538f524a63ded65a6b2d91de5a6badb5326f276aa258ac562bdb18b9b41ca2b78eb1d8da8d9bbde65a1d73975fbf32bdb0461d166f5d87c5575bbd89d2aa4baf7ab5cacf4c81600da440f575983d57e220501f09838892787a2c3e86c6a13ed2dbdd690effce375e980ff5c180c01be81e5ec7dc6db07156c7560558272fbf74f0e111abbc8039aeb5daad066880e8b3eb63b67b60a8759e99691a48a2e1baf5197a5e6a25fbb3345d7acf4f97de9944bd3aa9bde76bbe81e612f633c312f6325681a184dd90c87f33d35eaac00b9872799004ca0f5050f0ac1d61443205c913628cb285d81e349b734e5a8b1461adbd300735090cc3301e5a3214e57202b641428330312609c23e4018879c2411926d045c82285cc40a18e200e5b3874d98487df42ec24026a230310542d8b08658053ad4463032b1840913133e49aa60820aed874d94f09894076cd30208081121042554474032c40bd489a7bd022904e9eea513751da552093d14b9b5c990169254a1bbbba377476904dab165eceeee467df4ee289148228897fe329372441cb1238ba7294f1701c6880550b400c68bf9024ad474269c26e8be6e0745bdf4e3884a1cd9c1479fde0e8a9a319372cccc13bf3d1a01437903034480e108521c210ad091204e48084267544191cb24c9ca87cbefa52d3252538e41a5a34070c65b4e2f9d005148527cbfe9d52fefebf9cb2795316239837c40858c8bdca757963ca7b7788b7f1de45776f4cfcbc41825144fbd78fc781bd5349ebffb2e72c7227f1da945279361bc160ee3d9ebe1021927b1f046354ea7babb512c3c198ff1eac3c8788bb7707c69365ac8f895692193294c0b219d6a9cd3c7168af1e6b38007f83aa85fc683b006a645867286e4c197dfc283b0a6253e0bcf23c96415e46ced06e330319efdecc1acf044eee28d44dee22f8ea966e3258bbc6a0ce8799128cb1a30055397f417af532df25ae5551395aec53117c9938bd7e22e1e4bca5b791b2adde62e5e07ddc5e3de864ad7b98bb7bd0d952eba48e42e9ef6239f8fa29c6db058afd12c5efbfca014604096e9bffe3ab6feebafbf4ea53a55e3acb19d362a87442209107cca855c2981037ea6c8ccb737118756f8bcbc6aa517ad0e21a53644ae2b7a1768d4ef5c5e1d230008dd28f5d5e565be7ee5cdc65ddd855df8baa85f9b6b2ae8e26ff7621d47e59527aed975e9bd1effe6afe9903b4a7d0d5943de8b3b17ff7557d0bdadf67bbbae5d7cf4cfc5760afa728b100ebaaf65757ae92d2b97bfa6467d2d2b58e193a5404b71dec91b2e7ff139ef3ace37c79b778de8e2733524f54af1a593cba5fc442fafe8d7a6a57e689e4a2b3e5e595bf3646300751f5685e08c485da39e51c7d431ea1716a9d768cdfb5cfce59987bdaffbee5ff9e356f057ce6c9139a7166312d1db415194ce1c9fb031a8b4770118bfd39e75bc3efddb01e3af5f36429d75f8d2e97de9f7c63cf3ce741a0402e106091c618911a440048f253441c50638e4e4678810471821c4112f4022c4c4494930bb9f48c1c10f8050727a2283090516fc9873cee983227e099b223acc67a2b4d284f1b4566d8699a699569b814e194d331d576b6fa51a37356d6a37caecd266909c6bce695e43562e97b0a799bd36bbb4e916d64cc737c3305cca6694d8cc72a695209ca170063ad430ad3427acc159a665da0c3498e658cbb026036c1a1ae8582bd9d71c6730cbb22c8bf26e9a6bf96230629b73dcf44dd3328435990d09ba1dec9232a80fb6baaac0f045931eb01e3659e2e4000f9b2c996243fc0f5b714fd8684344f7333ac119d6e5d55dde44c96ae90fa5d88a7be2db6d88d4c351e56dfeaa471df27348b72e337c8ec33a4cb482336677badde9dbafd5b7cd1ffdf908a5cf7fd54939ac5f7ee59dcbadc3875a8efb241cf723e5b876ec95e1f7bc9452b66a152ca5c71863f476cc442062c7d93901534ba2441f213e10e2831ebf43f6a0072d275017bc410240c56f2728f4a0892d0c010b21b84110a2a0248806551c11e485064217657ca5940aa59e523a638cd1af135ba869e28416a43f6ce2c4109c587d742aa2d9f98baef9db011249fa4e74e8241c19f6c4f802862f3e9a7ae98eb1ce1793bf891d6a38e6f4ce19cb5f8f63ded750011d6ce284e9db599cf0c139e2b767e079fa77361f39d46060f1ce5ce49dbf16bf5e43c6b8f0d3ed603e1d73cd31e6d1d663eec203d6b7b3388ece3b7f3bdaa9a6633a56c25cc3b9310f730664ce7963d9859fceeb1c2b8ec30a06cd3b93386fc77c7a24ceb14f12977530c78e1df3ce31f661afd867d357b20b3f1d752cef64cee51d17cfd9254774970c4799a79fe513e596ccd3bf394bfe74f8c6d88b1a8ec626f09c570dc784e1d31c3b96a79cf978fab7fc7de0bb1fe7296730d73297bfe93c8d7d3d507ecffcf1f477a7a0eb5eadbe351dd8e5b3c35da7d3e5afe7356fef38ceb9cc798dee569cf3a66b5e863bd734cd3bed72f838ef5c8ee1b832066b4818ae761e34e141ea31ef9ed3a7c7791bd8bc3ace3bed18e698e3b0fa155fc91ee77df13bd726f6e969de799cd768cdfbb66c31cc6fe879eced7d38783635e8daa76b7e617e5df3341d9c3f1d1e73e899c3ebf21a7d79186869e084c3aa694f59c50e543ef606e2cb2a76a8828e22e704013118c223e1077ed8a4092700d5296260828eb3410bbaaaf2418f1fa8aad0848f268468a2044da4a00916a84ea06281ca886a072a25aa1fa888a08aa26a820a0a2a1e3cb4ea07909c826a884a081eaa21feeb5c0955c98a472b69f24309149312293ca0602aa14209159ec0bdba9a40a952a28f2ceb1cf01c78e8d3db31f310b6d765305adbdba7c3d301c07ba96ca1caf34c8fdf499a51ad5de746bd36ce6df1d583d5afa633809f2e1ec6fc0cbc5efce9beee657bad1de19c1bcd73e64bfa10d05447a4539252a28488129492391fc21a2154235d900ea853c283c7f6b089121e1a35e99c740a12302822074cf08962c90b73c9cfb9022dfc9cfe4276fd3adf01027e74970707a8e20756caec3993f810248990887bd824090ea0a055e88ce8681294900eba2b74b6874ff743571f36194a02483714e587fb8b21283ce12627fbdbef953ebd24f39cdf2e4d704eccc52865293accd78b55beb394b38894733ae6e69c9392a4973a2e51eda48db5135a25ebce0e1b87738c31ce1fcf8c894125efa0409a9661ce838d659ef957b6393fbc745788e9718ee9e600e508b939262cc72465feac5f380361e7fc7ae779e62b39f3986dcb5f96b98b67becdf28783f30e0af4169b7e5dddfee5fc90f343ce0fd5846d9ced3cf223959f75d7e8b853430e2fbd6be89719cee7915fcc3cf2a311f4ed50a4dee66113288400010504a0c7ad4987628a17c0c32650ac1ecbac6a36a4472d13c919e8c20f457d96ca0e8ac2bebca396be9e9d2b7ff1e69de86ef1d3fc459fcd9a59c0f005d67c3a9d4e93a046680e68ad34549846d063ecd65aa9f3c81d1959eb6dec513a751ee97df265bc52a15a1dc25aab8ccccd304c97f11a32dab81e3d948bc8214b27351d8a92f9bb5dccdfcb4f8a9af9ebc9414a49a308f67630d7e16794893470744ca3082c9377b0633234848821c9e44f3ee6a4fcc9c73482be7693658aa6cb74fa0308ce20f9cc1f861df3afe6c06a26617e9d62cf367f71181cd3699868108934a6d739e7c7233f1a417ff3ce7419c7ea5d317a81f195e9d46f95a5ea3b325f4d47f6d53b13cccb96cd3afd5ad5634cf1f4e69c984c0d396910f93a499ee6311ef6f8e2992c0d939ca1186b451e6551fe5e5e56f2e7c205ce28104d515a69cc5fe45c6aa5aa39c66a9cced4188b3ee130ea773c4f1d91cb24ebd86967ba335f574ddf9d91ead4b1e7c24f47fd72cda340b006fb4e36351dd9639f6921259f8ccec8b7d31022d2c07e390d93bc817fd108fa69e79cd36dcd34848806a077141357482189cf9ec55354bc0b0f9b38197a27449a487927451e7fcc31bde8f4740ba24554a7452a35d5cb57bccd390fbb9ea53f1ac7acc91ca0e892476ade4ee63a7ce4a4ccd1ae6b9a57c9e958c9f921d2905e7734cf78e4b3e858c99ffccc59f2275ff31cd3578f315797de173f8b3546997734cfbcf67f357fb327071deef7819c22feb3ce2377a4ebf0d5fbfa5fbb3958742ce710f9cf5e1d9f7ce91673abddfce598defabd7eaf7fd36fdf7baf432d477579657c123518b2ea377fb16652e6985ba73f60c011bdea885e3d07284748a451fdd6979e0b3f1d8ffcfaf1c81c53a79558bce61d16acb26017c358b69bbfa85dffb821eeadd5b12cf558a39f55f85a9daf79f4abcb68802f47c85fbf6af48ab759bf3ccc5b54730e1036e4296dc10d31e4a9144fa9c778f9878323c5cba85d9a7f393f441a5f6ceff287f30487f535db8f67c6bc53fd7a74ccad0643fcfaed008a997455f86488a752f0f0ccd79cf30fe7c967d9859f6e0705fae89a5bc72ecaf2c7333f9c27a5e83b5afea2d574641f04cdbf4dd3f2b7c352cff921d288f9cb1c7b0e90bcc139a6c768fdab0351ca8dc69b737e8806b099e61dd1693485122b253d564e744dea0d563058d180c7ca064ca4c0440bab134c3a27d531411227f811a404422042142b1128c1a3c35230420bab1d280e9ef0c08445a52082891026262622605202264598b0800912ee2f98189112634720386336160593824dc1a8c03db0104c04c635bd942b79b3e2a1632c39231d07991ac39e1b8435d15dfe8404a694ce19a448d475d396e6bdfc3a0d97d72bdb3a49ed3bd3a9cf09c4bd5d6a2abb679c93b697689632574aab5f6b31b6d6da1d8d6a77e121468fee9238dfd91c3b976354e9362350ce582d6a526adedd9b37e79c9a639a6d1ea594d2cdabb5d65a372f46902ef36b254ff4d46aa5520f59d6ed966304e92ee718c3242ee7c85ed31c670cf39ec7b139f6d29621acf92a0a3bd4b64cda9c7312f69ee7f20d5bd6197dcd50ce5cf9932bd4f42f87d5ef683cc427b4f989f0c58753734e890238331d7a9f244e3535cd0f78534f72c624712eaf48409a693ac99b2a5451006f6a0be0ccf4e9989e705a20343d01428dd3404d93552179d3404854a19f1dc4e6afbfe6e90d04c4b96e03d9a7d7899c0e054a942852a44c99f36ba09fb3337d126387eeab425f157a896b0c1fdae18be8ab183fdd77353a29a5a91435996aad3595b2d65a9bb577efbdedc5e8a1fbe42a460fddfd562b958aa668fa20eb8391758c1e3a68234695ae14db0748a37e83cee849f4e40aca77efbdf7bafccc7265c2a680259d33607e499128765d15895a4a0d0795f7a9637eb98febd6a7469201f3cb69c0ae0b7b1ae3072294daa95f1a8ea6ad95b2a78eb9dc7544c071b5127d4ae3855e43ea307ba8a43ee8eeeeeeeeee26755718bbbbadb5d6ee54976eab8ce163e3ba9b738552ca526bad2dd65a6b45ab953cc953ab954ac5f091e1c86ec86ee81e8d46236bdb664a60d8372f7246877743ce90e04d0e38836550ffb8bfd137e48deb803802f8b89f75abc17e3bf497f6ad777720ab9968b97cbf48e9f68133ba00b1d69c77daddbff367637ad32950a10a53ac70052c4c91052d6c818a2aa8d02a3e3f3bf0e8e183871e807e000922c40758236dc45c7f8035d26d44875acc15084a5b90360e1d9234d297bcb81459808f32d3562b9eb2a8646e543639ea98220100000000531540202818100a0563812448533952dc0314800a8194406854194ac4519423290aa3203084106208000022203023344400bc079fab15c1b8190d47f2efa9d1c9a4b66535c1727dc7b89aba75eadd449990a1590a8447a12eff6c341dc78fa15da0b70c6404e1641f62970fa40081a04aa427462bfa5494886e3305faf8618ac21c4f20bdfed506a76df753fa18009554e93922716c2da9cf3077392b02918dc7408490ef953dce5cb12d64319c31e96c949eae05d4e582c2390ca53364a27b072f1173a695a61bb134be112d7f42086fb8c24ce4c9eac10f1955620045d393f80bb9c45fc65cd69b57676509ead9fd19390b9007592d0d598ce7b98b3a5a83dc3b2cb654fb3bf030ad1b5a052154e932ad7bcd732b377ff0f7d389a9da373ea1d36166356a21ee4b72a53f5b85a06a78bebeb299428b3357070575ff4066db980dab4e278578edbac95e442daeaa3b639cb7d50487e6ee9fc3bd16bad08dc504f5cc973148323d168d2a080ce363d02ae153695a05904375b9b6b61dda26d5b8812674825c944ab1fcf4164a712fad8f78c08f4792eec2ef3fb164d8d54eba26cfbfcb2823aa542723b8e530e22d8fae12bbe282286c86d2423054697842ae92b61a6bfcd7d8dbf0d85c000fd23f9cc5e9e1ab5c82b2186011ddaf77250cf2a3b69ee363d0b329c1a73e4ce86482c6e2f26edcf024f132220d78d9aa1f6f062d06d6418648c2a5653750ac58f0f7304cc4bf8e855f66542d5a70d8cdab3443b5426d86e17e6aa6e89b765b1b5480a619a1f647950bf77560fdd6ce57cdd4f8d66f95ef5b2fb4597103a4482006833bdc9364dca389936b4cc16a173d8a7020122aec89f7ceca002e668a657ce8b877c217332b10d8b4e5d76ee4d5ecf791c0c81a35916d91dc507d6a698020dc54b062e16e874a8b726dd0e4b30346c1ac2511b7ecc2b5d920f7d9318263b20e0fbed6674de9d4c8e7963e2d19d2eb6d26e19ac2a0ac836f4a7eb041c95619b3594f35698139bbcc13a4a5394499967944c16588680a8b16f2c20bedf15ce3839663c5e7aaeae29a52ac5e8e9f318906825f3c364a112570d38835fba95214815a795021b1d87b0d8548fe3ced4b3479f1ba6e36b2b1523b11493673d9213cd04ab6d32e736ddacc69cea32b999b52fe65146ef01bcf86f567ad095be65ad638852c3cd928ca9bf3b46634035e401929bdcce11e19b581b8070f0a25725b8ddd26f13b9ec261f369bfa86a5fdce87bd4fc582e017f88c259f17b1b34bfbd5b44d778123283d58ebdf50ea8a039b83bdfdae18233bc2e3e5c2aa8f7dd7012d6242a254ce620c26e68ddba5b8fef8e05682b48b15756d51fde8f95af43329120f01a070d76b5cff3836aa5d9566e561731c774967d075a4bcb5c89b50ae591a9eb04dc137e88219821d4875bd5009918870fdd5018d7bd9f9323de148e70500306371c865665b9e1506550b4c454d66706a12224946a5398d234fcba1f616acf2dd2cd42b3a9943a24991f7c0730dd224a4cd2fcf28a6343125d2cbd49350ceb7255df9a0b422347fd3cf680a5fd691032d70b5c23fac4394583b6d66f2a677a1845b5a02a3f2da3ec46ad48371b51dda8f7a502b16e21309831b430ad0d080e2c0ffb8a0d400283425d0350cc3cd89ecf0cc04c7048e4043e73df59683f3d54b0ac7c4dc699652158763cbe8dbb2605d7c6b3245f0a42eb44a620f2d5001bff64309ee3f1957c6519580dc6be4f3b9a32f102b80b51ddcd44d5ad06d090e2e08a7ce3e5c2bb1f16fa0f57a1e3574b1c551632ac5983b22c105bdafefff861f2134e001cbd5bb17db6a3ad5ee9a00dac236982ed8b0d09328b82fd0786e686d6d0b1147c6a22eee11b8ea36333c88096384c154542000bec4c5e5a66c72edc8f5a9b77f0be03547dc2041512c64d24ead65787564b6136addfc72ebe163e05b04cbb73788a2e0045f6ee56edf1a13ed2c22ad95bc5a2308f11054605903b91cff3aa303323f82c2792b5f00170535a93d0b3474c16dea028330ad7b1a7e2e982f4b2fa13ba37dc806ab300eac910b81a2ddc30f755b5170be86e1e065a30ef061cc40019d0abc34557c7d43e440350e5f9b8910fa699d45904c5424693227128f0b674fec66459f8dd7d1d7df915de2931af0f0bb8b39e84bb3c389e4a88206f4de4053b241698bd8982b4835f15699e148f98593af81d5e4f85db193589197503ae4fd38589f1c757e5313c062b445009f723d6357f392cbb52818047e7fef0d514e1119166423522805ad0131f89024ac67194cff2698aa36353aac0343ccf56fa3f5ce12f741cb236a60a682840c8fb457804d95422e45540cd825d2861f9ff508785bbc761a8a967e0e095caa65915de6060a88e36490aa5f4eb25af49a57ea153fda646dd1ba13c52f1013b1ef45a67236d8c4c3655269531d46656ef7df469188c2cd4f37e56b31f29f3ffe66554c7a09d1a4dfbd9ff2d5034eeb782646484bf24d94a697fa11b98c762dc5fd74e21368e11e8a6e5bef5a9e71d2489aa734e9325e49f5e833ec8ec67494119232439fa02e4a65647ff436eaa0b512956f8848d72e52ea5a92346bf8ed0312a5b40964b0b3a8a7a1a223307310515ff65c900f575bd7ec10e999d6baa1a8ec46130524f0a0e149768adc132ff7b3645a6c69cb4aea2bb9f9c9da99f1637a03062b8010d9f43c0d5a5fb8a60c22d00f4f40387a7ef0d1b2620b5981d23fe018a0629fd8d6e43442a512336de51b7b69499186453c87dc3edfcdd61cd00158f9ff56510770e478729a0c2b9d4710618ec04fcf0cfb27198493465d9132c5b70927c2b7c421cb0e513cfe77572aec65d2162e2a6d153574fd88ae34e7f8b85c09d734d786dc91b11f12c82bc86f50d1f3a694543c2a6d772a5bd3b3dddb3fca0d3b0a8c75ee72307432bea04dfcffb28f155e200a49680ae43cbcc65e3afabf937b1cf2f05dc6ea3543c043c3687965de42b9ea8faaa5a07de9686722520061b4aa11e128d0fb7db9c5cf2ffe3c02639f16fcb6486d2357e777d7f73f2cb8e08bb757fcec6ef55224ca8c2dba8620c05d43716acf2c77926f5cc23299d3c60d739954bef45028cdd3965ea3279d9f5fe5753c4475c036a4e4353e0004381dba3f7fdb0c82f535753b79adfc24fc8a9f262f46dd26bf668d79ff0bc64f6aa060b090edbe315ea1204046b707930f3e1b1c4136375673a9458a83e2717882a4b4f675f5d75331086e832d7ac1c9441ce7f8207d65603c9f2b622e82e6f63f983494119dba6c36db731065cd1e15280334a48974d2bfac8addb20a4ee5f4256bc88b3d7c4201cb7e23558b9cef0a3ca021cb1bcd0e4539a2a96957ca63229350ad5a5a80ded3831f50907442204aa038356c8749497239d34de3e114d6a88a24cd8bbf708b4349580eb93c4bc9de425e8e6bc601438760038ea77460375b0a783102ba2197763f9861a764d702bc0db53b7b48f7d2d2120dbeb43ec18b5225ad0351d73f408d8e671d25224746b29aab7601d787a9c5d2b6fad73c8a844dc7e06b206338cc0ca073d5379bdc1cbb4d6dd15195c18cc0b8fc2253789a8093f943b69b3f26e363706f6324133f1da439129059c6fc9112080e85d42166d04594b37f39c67910ee97bed58d81bc31086849cc18fad518e45036621951a820e87580d778d931192ab03921296186d40290ab10f0709dda88368b2ab713e5e0469f367880a94d5bc8b116968716d0512326dac13b3501570659427fe29d22cf38a831a0332fe4672a36efdd274673efc690642815fde5f735fb0b826a05ee8449442d175d7c47575e5c6af10a0241edc5e5fd59f9e8001efb777ab91645626baeb36695271568cb0e8090ddee0feb3565113cc33528fa36f5db78b997aee0c4e30e43fdbb382ca160ebc55000ee98d0c17e4bacf82da2719d160e354ca86b283c259c5196d6c9809be4ba07472e2263a92cad16695473562add723a220c178a4740e251ef5671f66f141e1f0a536133f31c4ded8761ebcf7ff9f59cfe316b2c0053c740443d20ae1043d624bee0a1ae4dfc046f963b2ed38cabb68546e6bc4ceafacaf28a11c634eed60149628938e4b1daf025e01eda10db573d56223b8be4af69b3ec47ad2cbab4a1cc6602bafe4154ae5b80768ca1acfcc4d715bf189792b5a68d596ec0ffa30147561e4b036069d41a9153a859887fcd8e1ab79dc956654812b247139456a7cbf995c2c37d1955d4a9642bffa3387af0c5efd57527d39e8dd868466db38c1ab726a9dde42d0561e859e338b6191f0cb6c50ec5dd950cd3a53197574a8c494d618d8fcfd702a4d0b6fa9fd90a40673d2cb00202cff66130cf42a5d6e93cd5b6820251960e7bac0476ffb54c907b9831d81e4430c60a48e1d7f604688ee535d616cd035ffb09af84c0092e67db3be23c3570e8b91ad78f4b60e8fb12ffbcabad5d59fe7b94fecdc97d5bc461011140b7f7adff6615fa07e0569f49e3efa761628d6500026fc021092656e0cfed1b0fd2fc6d8a8ea0962a35e054b1c7cc95a723828d6c0831a19dae0255e7ad9acb160e2f12a4643d8965c06c19877248d875ee87810ed38a4adc953491964acbd02ed0568468106058f7713bcfd842328ead15de3f66d8ae0bcd3bbbcdb093f1fc482a6d7949868f2ab2ac067dd1b3b040fbc531be81623ca763c6b98e459282acfe287cb9104e7d916134de4d75ae5733a26ae8db95e1b8c50d0882489feb5bdc801352c0e092ea7e136d3f75374c44962c067163699b1a08070c8dbc1d597222bfb2ac978b22a64b915081efcc2f18d7bdfc2078c80498b3c5d295b7bc259f1d8fda4119108d8f8708c1be92365d90ad329f0e18176f07148f7000c7e0a6ea636fdf2fc875a49e2a562ea30ea35b1c746ac1c9ea3f13848c5499e568785429055f4c328d3824c6321ee4046e35a81ba8e6aa5fdf6aa27640ccd9a6d7ff953ae474b542961ae0709e903ba7cb12400c00b888ab6450eca3adab2b0c52155222d4918e8ec923eae22fac5c773410152aba671a3bce1cb444643b679752a2fae328458af8af0e14353567382a79c39c72e1c24765a686a039484d71ae29364715852f9c32bd5e69f1aa08e100f87dd87c3715dcc14abcb37c13672d5ea6533ec192025cc177586112ef1249e7d9f9f6157a103ff9802ef3b42c340c748f5b237ecf08f1c0dbb8a069426bb33233df69dd2f05d179bd83d66d235f1ed6550e5343cf6e0cb1ba622e7b07af86f92960a7376338523c2dfe69b5cc7306779c8bce05b77a57c86d54c74c99b00f9910a9d1b56a7d710b1a6860f58f3686f08a34d5b60d015d179a1f1180aeb3c7047e2e687b7a34683da07e0b5176209fccdbd9633cabedb810aa595d7183d63b2f351c26b6c8c8505aaf1a907f06cc27732741eb3ea4b9d81766b73568350c87637004455facc4e2be39c194e62d18171231333ce78339f72fe99e478ce549a99ea4ebf3b1bf52fe3604b062a110e43511334a2ecb21a8fbdf2c635546bcc6240bd9d56dee811cd415d29ec69004128d3021b17343cc39ac2d2f549b21022e9164d2701f962b9bf9a1ae57512e13e71d0dfd72c2223ea187e4b35fdccf4ecebb5c56c783ea46b495916597131e42ddcf61de068966bd4b9147802f3c5ada04295eaaaababaeb2c2ea6aab564387adad366fdbbce9c6ed9b6e6eb0096ea8ea90331c14f6a89a7d3d7c8eee0b1e2101c0b6b4652ebd3a8c1993db12f07f9c2739a18cb2f28ea91167add6f845bf3a7e49729927579130324fa159e897e7cb4599f1889139bd83d83223be707dd1f275299ce86a8a067bda38b5617972460c8e2dfc34ffe38ee42c277ace545795e8afc28e87d5dbc167906fe0e99fe207a67f35f3e67a8e5ffed60ccd844c09fff25e7310f5c269c6a70f490c644a86756544115ae2c2d2e2a15b42cbcdd3970df57cde793c257f456b7181c213783ff04f04295e5984b094427e9892d3c10df65194bae88caca5216b8842da104230c1bfb4e721d54ff0fb9e6ff409425abc01ea2a83beb70b12558ce2a01dc4608ee92ee0d505ad913750a851a714d06064a87700d1e8ea4558bac9092fa5b8b95b6ac88411cd43b66fad766a420ff9cb2a1829a173984a8e73112cfa1f5766d0680b7c7f67124cfb05fb362f7d200ee7939d031e00f28e69950f0012105252cbfc780c73b8858e2c0069b2f0fed2d2efe957464cbb5d3dadc855f67d0168d497f7cd3ac74a64f013d95ebf4570aacb6782eb836db7510bb27d1f46146fb12ac1423bdf02f3030221e002e72a16e46e6afe630d9cb70bf570a088f09b7e9a21d247cac2c85e919bcf9b18d2dff384e80db1f6c827ca1ebc3164a75fbf7e27756de41ab596685d770a139fdf76022b268e5572c9260868da0166999979001d43356177d5f8a165a3f4caf3b82acfb14f67ffd7b1018ea6bb598e5426bf30fca4e4f9593fc395c67cf646655af291ea0ef73f07735852801edbd7b25792775f7257d2c9f681319704beb53de785b085b3041d543a3a1781d4c9c83be47449bf904e91f811820c732158937fc6d47a398ec1d7245e84ce0286522e3e89c6d987983247e0cd11cef499442b0dbab6f529781cfbd08d4bab826947b9080e2679a4b56a3a676353d9a991464a2c674915ff601dda04e74bc9a087640f9b6b34997de65bb270d6089f8cb711cef9a1080c51840479ddf761b21632d2b3f44ed13f393088704cdbcdefb30ef3163154db488f3c3a80bef789d469db92d820344d896470945c80cbe0b90ef51ac4bdfd9b6151bbfde41e3e99d12275701671c8f1a5f2a08cc514356649f6f964270782743258d4133efcb071698d84e1d15097df0aa4edf708be6361b207cc4905315bcaf8d8f59c6d11d93abf28c1baf9e99f50d481070e985876a065e0bae8254d92b515f28b6519408b1f3bc800d4c91677c944f3bbcb23372cc47679e70954205ff2d9c3818cc92b7d62b2a3953b4571c7cd14be18b81d865352aa4911a2110a85fa395d8dcc4641234371e65792b7b630a2d088dcf1a0e7dda004fd5fd0eeedefacf7065ae18bc3f0796d2a47398078c2779676c37047bcba4f852320e68167323773839e58024421d4b721c4e61e7c49c6fca4ff6c1652ea0e46f3b4c116839b6caaa3ccdd485e063b184d0abf028267640d985fd12092cb842fa09a895f14ea8a5809372828fa0100fd6f076e5de7bafc611b3126bd54bf869c4cf6f69f6f8db376c7aeefd34fc18dcee0007ddbc95a1604c99dc8dcc18bae079b0bb1962801141100b4481c3dbc5c030720864c4f504f1e879f82b28f450f38d2c02b0d22e0d321edb84af4a972ee1568936827dd2e614d683031469ab3d1f49b07d29d6c6a6105173c7aeb764e72f21a1abeffdeab28897604317882964ca5f2f7402fd4ad21a0f9a096214884a50a698ea18ac3c32ee9fc9ac3281117652a06f26c0a1dadb87b5e2a30f160e2176358beb8a396693296c29fc85aac5a3cf8b0a80325e2313c8f732a9693f43f2fce3d71944b6d239b22d0ad9cf61974b96e8efb98eb716a8141c182fdc79746bc915bf704702cbf7a655d4c76f48064f0a420d8d913987b53359ffc046d01b7eca485b540ff47e4dac6e1fcbac219008d4f847994b69e0702e93250b535e1c32982a8501aaa014e0f4789c26054ce5213a41ebe4414e91ae2b39d44bca25b736dc0a6a5c007a2bc18a784198559a2a6f0a38e3fd6d0d54385e63c1d44d7c99d9007411ea47aedce6080d86a1d8071066407ef87c0364004fdbe837ea5eef216b148dabeee06ba9863b2025105b21c8135db92fad77e8814094d72437a7c6244c5042469a6b25ea40d5c6ec945944cdcc03f8fc1afc583fd0c49877c3d1a34ab5a3af1d0c2e69435300137583be092536ca998cded924d19505e793934d5381d3a042921103c5e74faf93e236e70de478e6cab0d21462fb18ed171eea2abb07a18bd03d10e21aebc788eef30ef6bbe3d65603bb2675ce8a536f4cffd3715c86a5f35ebfa59f976d61ff0e7b811ce1c5c40adf42df3aa01ec04f6a32b9ad391fdde06ebfd6ee6b0e455fa5a6ffeac9fd27a8c7a94cdc4b4638998ab0faf12d7662b2b1f59a3e937100aafbb121ebe5bcbb2170f08e8ca92e6d7d1b65ea93dce01ace0b049f71a13bd9c8098f1a8416f8483830f8524f6da1cfd9ee480a84348abed8065cc8199468845c07d83e4fe7e073006b5f38d841e5792961fb9498207f045e87e091ed03b9435db7aaa6e0b39d2c3cfb2e6127305f5817357b9e83764f6dd2766abc702d503a1d2e5a28f7fb904a75c9d909a229b5c23e94a5567cc26cdcf1247ee10f891dfd1abe0b0202148df3d650852da3cf061c48b1a175b71bfd2a0dad29d4dce4763e149a380dac8746db84af3369923fd8e419b201f91952d6e967383d86f89cf6ec6297d4cdb3be6e36bf9ef117f261592cd80c57d6d14ac162c98d886ccaa75d5e56a00bcbc866d231aa7493bf3111f0535e720c96d309aee3d1a66ccd5975299ffbd345f0cc97c9dde99620882adf2bfd15d44b32f8a18de521d9d3d6676f8bf667e9328c17e27e8af49f7f6f513b40c0bfe6b1a20c75ec7350bd62ebb1edf398684bbaef6ff98e6d2483f0b26a703b967596e297c0f3329560f74c226c26fcd202ae5e08837d994515b84d4291a126505c319f1d516b1de70950ba98dd0914e9f6b7e5c97da88e036a279f19eb93b7c41bd7f8c6eb743cc71f9024a9537829d01ad5ccb182159ccb76313631090196e4f137826ec9a2a6491e87603c16d4fe8a44f3b54a4a001c6d1147084e5c44ae51018dd0e2739b0cf5eeb9fb65d82507bcfcf368794959a8a46cfc96f0e873086640dc2e96f6df65a6ab120001540e5737470c50dcdc732e673343636dd85b550bed736b66b50cd710866201d7ab91c48eadb5cd1ccb6063d90e22042f789b3d6cca8e61ef99c449e78ffe452a34c2ff2c788b3d6b88c5f94685d62b1e5b01f92258f35d367f325e1ad5d75b297bdd3daba40733ebc360d4ec549dfcf3a26b5eb70b8e653bc56642222d09008e8309501d64a096831d59e4ded63ca49c82bd5bb21bdcb9ee9d9c63a7807efb5e83a9440ffbbaffbf3045c49d88129e3c1813d25cd034385fe7c0406d09f7884557c6fc933dcb4911e42cdfcf08ab9cb21c0b41cc8469412c12084de7a40e82bd809f0ae35d7821d60fdb5db0218f8d99d800586415839892ec06a6a67031b1a7927e0bf4f7745bbfb04e27ab89ffa05ac32f2f8d244fe3d24da11f09163ba05ee0a5ba4635850cf340a451d65f8b7fbb008396bb2a39d5600b6d1e06a488035065f7cd712259a5e885d3a9c95cf052b422f2c5d1d9acdbd578472645c99fa6fcd682f7f347b944e8c1b5c3d8ed6f8150de0b8e906b898c26fe0a42243a0fc1ec023b480162fe318c5361dfd1bf62e233a3640bc163d39e066aa4017bad0d8f7a0e1cd688a9c588d76ac16f716d07fdf0b7f1973f18b841d3ffb53a05039c206410fa75342e9bb4a361d15e00746468eef74af89df1abeb54d6daa709ae44f514d481b78b8c680ad96d579a1982511851f2b181c0deb20ac442bb9005e31aed3765494ad36ab06f02f2bca6fc5dd19f999350a8328cfd55272362c31938d03d9714f0dc38a8135f594efc1ad6d1191f7859b51c6e494953a0e290eef0c4673f2317a6f42415d7504efbe0c360459c3e8a7de9ea30dbd66fba2c9ae230be746165cb111a2d1303added306320e1bb047e5da80b4def5164fe56da12315e7f670961c41c69efa59e161afabbf4bdb066e38f5ae857c1ad3e095d5b2c5bd0368251c6a19041426db9b2401b4a5c0c9a45686d7ecf35413abf2ad62a7d6e3b08d5dcd15570cd755df7ba5b19a3d807727e5f58d7cf198c4c040d2041f225a561304bc52bd53c73a737602052b215788ca3f0a6ba70111faedf85daa987efda5950d38bc47c80465d91a9f8ad4092b899048b88b92629b2fcd5afd1aab98acccd05e0af7cd0f47289f2bbd589b7846d172147a697d46b795040c302f0471498a84f91d0eb11b1e1be50916de373676f1c06d12bd6a719c54cbdc1aebab25841c425d5255857f55f3da31856249ef4d22ac40a0e519d8e94c871225459d16e8994fec04e9196d81f3f058097392aff2f1fbfb0d13cdf7cb89799af05b02760c2eb06f96b402dd1cdc806af3389134da5fc0546883d48cce4a361997c9404a30ad919900f71ebdfe96466c202affaa06c655c3948ac748cedb90007bae6b9da1d622454c410fd3e78eb2f17c09684b89bde4700977d9f672cfa2b0d01997815592cd037f02fd1b7c8c0290d3521b11867bc08e8c91516d04321b59580b386f9bd0637941172336ce028d14f597f48ac6d5a246dcbf7398db8c10bab5c3cb8fbd40a1704ef2c35b71a1f115bb62d6ecce63909958084db749aa31eaceae3159c58416f2c32869de5368471755d689c1b8d4b145f52e8bda8845f2d4a33cf13631a7960f575e7769b81f3c69d7adca2715792ed9a7904c5a04bca71b24ea57c2c15f7703809fb9bede9ac63f3715b4dd72f166a37d912ef3b59142cabd1f2354bd7afddb5ac7d8361f9a736d7c6e1765764548e67e5d22b95023b0e39ceaf566c7698d95acb773a366b676cf4b9bbcb879c83f0505b2ce44e1ea6241db0d5b8bc98f30e0791d0f671290f9d00bf3f2393ab5a288a177b7d706f6e157dafae907841c0e2b5a17d39943cec9463a987e7ccc1b08905075e5198b28822cbf0cf40b4bd0c523155a8ab6210a595d96ce280b07df58e169d5894d6d9196500520f321942c058e9250430f2afca22f31e9217f076087ae483d81252f0c6cbc5a3e0279907142fb30c6a4a35a92733a5cfe71bb4ecc8a773e76600be459441e428e0235230e2ca1d2f3edf7b0e899b9b7a8606db7ef6161199ee822b87242ba603d6563362516ca9e893fa5effc4daa88589cdada56e05b23d454ddbca3cee56018c38116bd395225072c49617d45f07048890a8e8fa8d91cfe247143fa9eca024c3733f41c13e7a55947a448f63b54f2bc4467b8163aac428d07ddf6005c38d708aea6d02772fe1e0ff29b26de989dd014b23ebb2b2d3a83e72099d6bb4b70f46a27ce3bdf8cae50bb481614e532deb77c66e3991080528de336eb845631df172bf0708203892447a13964aa1c9e0ac9bbeb548e64d59fda3259a189dcd35c7429b012f3f762a464315abd380f6e1af4e784a4f041b6fe2e3cdee87b42c4f4d59b705bf9a1293cbe63d683cd29d3eb267965aecdc65db9ef892f6e940cf5bc146cc0675b5f94669473c44d16d08cd936e5bf7bdb1a7005001357d71b7dd1bb7a53a4ae7e5762f26d31f4b77c0c03d8ecad2647929dd7438642aa68ef5521582bbb1e3564aa01df49fbce18ae504090f977da606a04a855dcb190444b7e73f07eb2abc5e1e455defffe063bb882a0938528c8d5d3c2c150ba50236a05031d610583b5bb1d6a95fa8007954dac81a322931c8b559c0b750511966b82c549c008948aaa2d60657807587dce303d0e5d19bf95f01f202fae8e3dbf6385b985b65dd9d07f9e8e1bca17bdf12fc444892674181ec483f9741de1507c3f4645043f921550948275137332262c3a31627d81bc0fb8323c8c7ba536ff5911bc4065a038e66ff909886dd5030ccc2635078ec030640a8c81a0ad69a4fa2e72145ba203820101b8a55d0a76964195ef7b293558f13752f6299a5b7f30133aa96cac547bea1766c6200c28d864ef6e81d516584ef257470ebf8fa65108e20951d50c2cae40fa85822f2b79a15ab4ca2a23a1292f0615d519b370ece57ab9ed9a0dc02287755caf6511f7ed219f2c9fb02b88867218e20aa205e35ba25475388b52258cf5e1c34bad8ba9cf404b300d0058faf58e528fc6b30d0ce7b92e09642bda4140685dc626c0fb209f5b271b100549748d188d52af8f2653395982cbe69be862cee15543d6385165f95330991361f7b1505ba2f36052ad809f30492351c5dbf97e5ef527ad956d3805cb61830318f7db866876dbe9402c0e01f3c3807141013d40edd998e3c295ae88fdcf2862e0bdeccdf3aa27c132c17d3bb124eab242d498354a35534a68009c87ab03e5cccf6631db98f135cfeaec3c9046238b28f9b005692b0e6687c71a2738ab1506be946e6c5f0285c0e1f5622ef502b5dccfba1f523f0f8ca157c6c2a3bb54542ac8afacbb7e1bb15b253f93185d8267dd32c7790191e12c196bedcf476d32ddfd9e67b366692ac6ab5f6dbbf770b02d6df4eab6c923419fa89db94f3f9db13e6b69f8af334537d69c41ae846cf946b41444f50c04ed9fd599d85160aa059bf128e99277c4e4b00ec3deb87fe6d7a7897508cc7a36d01e64727eae42c58cb4c409795e69ec97acb72cc80451d90e2222e868a640d15b38e2c2638d7006799643f319c77c8723afcd9844ad235b2e311d613c48ce3de3d29adb67320d7cb79ba34dc7ac8265b0da041f1bd4c49dc6888d1db667a68e1760996c24c3edec4170c96396c3cb2ada5c8a1f8b64e6954da7a8fedc4021f05d2962d3a464d3a1b6ae80513ed6cc332c80c454076fee644aef142f1ee0c51d59c1b72d60f1e8ec18a2fca0cf2cd1f9f6faba0360163b492658ec7fff6dd7c780e9b8843f3c4e3ccc11d2ae67a6ec812e9172e3e9e5c5ba4dd9442029156dfbb78d9c0f2ee140653586b3ad6cb9f2860d2a2415f1e36035ca19058d530757c805f4443988df4a4f606706ec58389e42936ecbd15a12e49122ba59a2709ddca9a675ab499ce47f4baf674be6b3dae9f8e260eeeee4da2b8531a477b52ac49d2f36d389a637171e851d5d08ac10742dc973c2dc52d30c2ab27d10eba3d88fdf5a6cc774724d8e32a700bd7dad312780c7c61aff7f320d13b4632b9a66b8c1559ac75d32bfb71c4cfacc51e5795bce9518343b920a8903f69578fdeff76752bdd745731bf85de5531682af5ec789f64bbaa0a4b050381ce416326b5483ff49f12ceb5ed24f9724dad173dc59ab793176d29ced170ca06a1fe6b3a5a6ce49dfe323f65c81d8f629c6378760a8877467fe414b79b015ed3aa0bf0291c2d0aa462952b52109970cb2983d2c35f6b3b9786e85cc64f8cb7ec5c9ad241cffff9e24fc8e6794b6beb80b68a3e287346dbb7c05fb184266756bb1cff654071d461107f9fd78e1c8df4558a755677dff1aa2d27e53161f84a932c2527efcaef6e40c996703e2a0cff9de5af052994b7c0ecf9f32bafca0a9f822165401056a078f8a31388bbf253399693078a14be2be529d33003b00e7272ab8b71314a3fc9dc06a4fe575010116a62261baab44160472a7f0bc058dab679f246b2b53739e2becc2e81ffa2517ba20346c138bf031476ffe5c000d1ba0aa7da6ddd7e55d7c17c0e8608102cadd72e7d0bb0400146337b2ddb12ce5c8afedc00a0d94cde77732e141a77789cb334af156a9418f4eda816ffab7459c8318ab704937c8bfc8689e00abcd71d8762d1eca61e11d873f94d49a1ebea922d60e08279d4fece43b5fc27807ee0efc94833a00aeb6c674b89c7f7890f35a8c35ae7c5e59be8171040e94c8832450bb0218ead74eedc67f55da84587d838c3aa22910595aa9a8cb819ec965e7168eb54c50da92a9c09fc572a5057ab8a51c3fea870c085008dd316e785b86da84aadadcbd70e219a10e502a0aa7b9c7a5d0bced6284f1badb4846cd1464f62535fa991bb8233ad73b7eb54f124ab51d45a099b3181f08700abb5a5438b61a127f096466b1daf1fab5fae49869cf269ad2839741cf9e94498a0b5f54001a1a99d1c40b203ad7dc4acb4ae35d5b9c657e85a5ba39a5cc69ff62cf36a388af605b43cbc1aa0a0c7b426bb80a2ac931e2417315ab67ebf272b349ec727f43ae8548a33852d0b0b7a96e7fa0649dd50ffccd5aa6234ac47b626090184ffbd1bd1ae8ca3c8e540cccce36ce7eb9a62d977eb361d6af592cbe319d1fb29575eb379e8557805f5cf76e2c96ab4787324217dd50faf88f1e59efac53002845d799fbd20e6946049f8c8aa99aaba17b6e13bb8a2d6cf60a566c13871a5561c0d91fcc3f19f3c2e9e47d416dae1963f50671d67a4a0403c5d8f710436939282c396ce57f3eb8f94175dde98068b6ea566c5dda3f930793b5d5c3333c45ee5d2273db417be90c49ac74bc754fd066767cd1e5d296c054c6581201de6ca94c11eb66583f8a51aff25f5fd6d0bb5a1f06e42aa9efddf78515876754743b2f49540d79ec9d2a7d2bc5b72aed96814447db7a41d682dab4067aab1f1f82a3a60d32b72238ca6052c2d66d693104f60a47a30a4437da21834d54d24c354066fb8fc25a7eb304c7fdd5bfd91d4cfd4ad845c7873c04e3d149906502ddec80a77d5973851e996a38cf6428b8c6c4bd99b351f0382f47c19bc790484b062eb0e3eb8eef7626d47be3f6c1bcf95a0be4432fc1c80290f55a89c060fe577a59831a12b35358325c0a85650c77f988fede5adda0726a4340072ac99b1bae5519994c4795ce2e35a48a8e02b201acba68b4e5f6d9820c9d06b7858c696f75d98f7d786039b1ca2dd94955abb40dd6b2c3bea5661c4b8c948bec9e5974133a55c0620280ca6798980c6b0f8b6babdd163a635ea49746450267c817db7cf3fa6e727d8f38c03647a504fc8d3e107f88402e3a19bd9d7272a480e5ef4c6ba9b10fa7e1cc28337992f86b22e44f310918280ac4d2aa80bc390233d4439459982c4c1db5b47196fcfb5a5ea7fcb41982fee2ddb8e068ebf6ec96587f634a3b56d763bbca2b3d136e0fc8dde4f0bc7255f90557e18563e3896a35ed55d5aebf6d3018cd13b0c0f494043c54aec9f809595d39d673da7367d556d52a326f0a9e1f1f92293956fca4c224b3066784bb78f99910cfb4267979106e40a5056385c952c40b1d71a90ad954ac44ce6633c1c50c2b927296121b6e2880e1623ab2322776ed89b24f398d824f71e9710690090ccae9cd6baa26698e044b90d3881f6ab81142c7f25c28c42b6c707b24560b879df0f72de9561084cf28a3b21ec1175fa80cb5f13c28550a7d9359f4c2a3514c9a87098220383592f39a82bb2d714fb22f4c0ca3f1cacfe02bd89694da2bc42da0b0990813bea1b6d6e2a23dfb82ae4a9604c213c9ee32a3d6c96100033a567fab677d44bb5b42d107dd661269f6f9bb5cee8d494942b629ac64acbbe078bf0fcee787b53cfd1be14bce7e9dbe6d9d3075991ac5a02be600a76da40b7599546b6da4169de5146026f33db6d7c8a5f9752d072605c2a40058d2e7d00c292faf244b3fc59bc307660e5cd1e56109cea8aa28d1dbae4216b727619bd3a507f076f9294f38a0d545daceb75531629c5adea8ff2762ba2f3832326878a53e29fc7b5438a731601cb3aed7c68326195efdfa6dc34b109fb3516b8b9eac6363218f0771163a8708a18fd606809d7fb4e5106eed5b966847874dd16aae7bd34e1b078867aeb52a6dd38f5c0062e9cb5be5224fef4853054f732640783422473360228a5725fc870e2f43cd76dba33788d931f87ec3852185d50ac551f4932e835f2ac6bb351e8c6c49da2a313deddc0a3a68b142166993df9158361a750c23e3e6cd0b3200bac3648a0d7ccad9bc55ca2b006c28875124fd4324ea8c0b9fd70890b0b46528a2bb9ba2909a8197fbd5d8d4c18050c126f0d74d93a08a778e86510ec2ef419e208cd8778b64ed09ed86b3cd368250da7a15d50b84b230b2212277a9a8e4e16362d7e712fdfe2f983948b44d3899ad75b8d237864da3d6118279f8de9d84418414f056a20e0962e331fe7406c4c459c8ee0b46885377d87fb17dfef83c207f31e344031cd393bf5f143341b2cee717864c8eef604adaa5f885f418bd58942b22dc8406834f8f158f42016fb7a3deee1655019f68d5918c0f07d9fbdb10b5543c08fbf99d499a0217c7c70b2a7509aac8da6799da68cba00dc833330b43e2a6355b5e93942c62f658276e5f99e2e22261755b7faaab9bbffd53b86964f5269290cd2b374f671fc6ffca5871b07466379fc6bbac221006400a127e8cd942a7333066bfe73fe0317a83f11c20a7647abdfaf08d8bdcbef5cf6b73620083af294c60be617f9e04400a73458605802a6f02764af042a61a8ebbf5b2ead95b04a66af0e983e6d710813726488d1324538f2e1e0c66b60198b3a1dea39a2b3dc42f529b3556336953f831b526c13eb695c9ad7ad690255ce39a9f223840faf36d101062a608368bb8fe82394b29876363ee5ae1bc12e454ea6b27d8e5e8057593a1e334d6eea59b5cd9edd265aeee92246fa98c3c99dba9d37dbcdb913e3619da8a3e8e36711b98d3a4f348925fdfee73f92af5293513ef0bb710e42ffa2ea03fecac194395b84b73a5eb908b3402b5961652851b20ee32756cc4c6a82bd8170c8846b4421374b13bb51c3d964faba2b7109a4a9be35b7691c51b4427da620885d225210ab5281e4c4dc8e1f4a35f186a3eb95bb5d4e594ed6914cf152a774451ea032548f3bbfe29fd1af8d9da5996e25680990dceebcfb4d2110b56c870177b64b755f7be45d561d2365c90ff828e2e403fc20f137b2ab063cd0e203ef64f64c1725d2a8b25516adc07cbfc5aaa7a81c7d596f6a94abfeb52fbd651fe750a09a9d828084a195bb6d6d7113e04a2e3a9246803ba81351c62222bea116e4950365e4323436787fca7c168c22b9301d90912c7a8bcc5791cd25fb90f5d3740518f8bb031e38a3c0d1f6aba5702465107b8b2ae144e69cca1b8fbf0d85601f0e2e3470dd210e9df1c8ddca63147c712b6891ce9fb15d8e0ddc55bf4b2f633a4b64591b33ee31e99197eadfc593f244e760ad59966ccf170b8388128f7f6dce89da4a520aedeab88e6ace55a416deaab377b78d0921b351f415b34dc0d973abffa9ab2566fb0a1065ee7bf68558daf636f20ed53f369784b174573a4df931c53a8a0388b1e8e263778e7088167156808c6e025eef6d19811bfcd735ec335fd69c18f7ff79b97f313291dc13d86493571c2ed41fd9b9f7e4336d4b6fda127768aec4adaa46a2a1c0addc0662d2a19ff35924b16bf4de7437cd90950e644b9a6d18586aca6de7b61aed1798fc689c2f900c093ec293d23512ffac7e6232e70cf35ffd61f86bf525beb40a4a431bda0d681b18b698f6dd2ffa3051bd9a367244c670e0c1fa11e3cea68ec7cbfd11d8ab90fd44ac80c3d68519ee5199b1f600eaee6660843b76b86514baf62d6f3de271a39152b7bc043e20913e89e5896fe74309ad4bc1c12e749aa74e71be706a1f9667dc92bad6ee7ccd785e4c0e37d7177e783cd6fcdd5bcc7f2dc45118e1dd6c2951edb4ca597dab966e31da593645ad34bbf3ab2470efa12bca79ff987aa80ca5a2b2724ab517dba568d8b05f8886e9ed7a1027b08c3b6526e9acdbbba6f1bf7078ac3c59a4ca6843accdd14be17bb1dab646f9d585f23aa4c5b123d8f81e5e86b05a0ffade82bb9486db653865495a076cdfb842901cbd5415223a352fadae356e3373ca738ca30dc0eacce09a64efa5fecafebd61e1133b32000831ceefdce1d4091f143e27b12ce2ec8be640dfd30362f2cafd8c228a16816bcfc4f897bae75610c65f19d670c53f27aacfee30b7f0c1d2709c18ae27dcfda41852f483f2a5d7f0ff8d77f54f5468a45ec7056820c69936f4c370e0cc88f5eb0a03e7f18c85e102ac48940a834275397571360d78bbff4a051eff64c919871b0defd81a386c8ad0c29fd2508505f85a4c9cc471f103a37d64aff9ddd42716e210675bad9235698a0a17aa17f5844d4e9aa7db7b152509e682c2117b282dd11ecdb9efcf6c9dbc0cb3e58ac24b57a3a14c09b0f8fdf7d14800096cd0727efc4a7156672d38ff59046d72e1b0d06ee5a4ab0a96c0aa7dbc60ed192420f735ca9b014b2b96549ac0d806eb834e508bacb3eb9684a6e3e45e1c19b455662da03f0af1523578f3ea6307288349078c6ea74da3c586b2438778925a3a0de58021e20d1406ae61848d829790e8dcb64f6a9b939c26681d3fa6b4dfd623e59125302833137e986c1a9151754d00fe24569309294ccaa4115e0689fe4184280d64291151187d623a3ab154ea1b9b47d473da4d60121fb1e0dfc511bab19fbc71665880963a5e5dd77e97a52716c170f1c985fa79f70d5c3718c05d1c2be16f4788737ddc50f92d9128f784a2ab6db8ebccaa07a63d38c276064f16050e11a7def15cff9520801047efab28ca51bfc15dcc96158dc2ca6950c7415623ba5cc7c88a493ca57eaa5174ced1c861d8dbace6af6fef7ae2b829f78b37633966d1d91f45f4369019933a580ad8443225c2484f22c26324e942e05d9466221e495f2fe1492d25bc84ab37fc7f913737463b72b88e9e98982c5abab91e35bb3395b5bf57044eb22e11f8dd0853d352a0ebd3e0e6394096645d7fecdb3d127e3204a60226c38599ad35df3db76812b59817ec74b641322081897eb2701a27bff389a9d7b90b4284e8d008a7d63769eb3494c488987300281915ca5e83e249049334c9b8d759a08180ca2b3d10d61fc1210ea8b689e8f08d3612d0707e8b37e630883f7c6d83d66d81c95a496e412f5c3caccbc4dcbb4c7924b277516dad0ed67f6a9ba92c2468a1678b9c4a2d32214f049b9434d6e3540d8d840e9e13a1e2e0a832082756f011f0d1c211772eedb68d33fb33e3fa39cc6842c30ed425e6ebea8bc60a186273d6a011cf34dfc17e54857a795b3d821e5cc9e6b5acc3120b32a74116e9a2cbab1e8147380cccb62ad30106659b8cb2b316572ed112e03b388e41fdf44f470f9d6c7ddd866661be46d02158c7b38711c05d697261a763094dadcca2c99bf97a6fc31963283aa3b6c58cd02b2a01b3860d7eb0f3f5b7094b9e00634f3dd8151c5dff29c233c15277143a2672d0493589e57e4f6f74ec20f261fe9d0b72ec53839663ae6cbadefe7d0ff4a480ddcf3f9a872646f923d3fc64850f874ca6bb0e89687f5c5a24768518ee24d2f7ba9726ba10e99350e12d7750aeea1d812c0ffb9d10889487788f738b1208dd1ed620530d6e9a3ac44ee377410a5321bb435ba33e331442006cb2a2538d70fb32c968f748af150afe4316b0e926e2f720db6eb823e4f8c28a2417818cff3dfa2e580909dbc4d54479cd9aefff33744f0cb4ee79c1d5d427d1ea97da155e00c3fced8d3d9fc2be9569164fb8c4f66a3256f771ed8a5eab9f03096fe9f2155333a7efb2379bfbf354427375c8405f0d27ee115a8b283e82569f7055ccd4d7c77b073a599382ca94844f3f1db601ab2e9414d725f342af881cfeabda3726386359f1efcd177d1034ce37e450a327aaf840327b0909edc4fe07ab22c87a6633f060196c026ec9ffea085da1eaf8894415822b016a171f1d5bd7db48bc0048468835a38e4fd7d90b50e9d87686ea9a411f9bb0667b5c3e8f7c3b37046c1545f34e2d00c9353be360a9fb91cf8837fe8fd04506c297a4f0046ed08ffab561a583320bf960acb263190cb25b7ad702ed624012525e191f36ef0fdea4f458ec70b1620f45a9a303298b080c271784e6d9ddec71bc22bc0f3284eda955e7c46a3068345a02ed250caaa45337d9de03f05b7a7678addbaf9748979b2f29e225d96bbc0b5067fb918ad8e664e5a4d28719c7a9de7f1c42304784a2c340c93af14e0fc746af1dc34620b5cc389bdb26ed5a232c405d0683f7bdc291b4e4c6ed7fa885c15626e2cd4326b316910525bd987ec65b379733433cd223d7e16c96048e689d3a801a27a431a26e304997e10b30e5c36667d5a4a7c603ae296bb2e289e0d3345affd176dbeab9655a3acdbe225a127e6418c1695967378d8a2ac2fc08ca630465e5f4bf22a16f42420419c533c91648b0a37c12b2972f46f9595cceb857661a33ca1ab45edf37666ac62328e034d624bf45573228567c2f305114deaf9aa62e47ebf9c97987aed0478bf1c3bdf9c727cc45cf6879a353645a8bda67e384eeb7b71c6a043e8dfa3521e2d77f3a5ff1531ec874fe722feb5ba4f83874aae6405a53d42e4821600be6bcddc291442198b44d46399d1a2f9aee3968c1a9d4ea6a0a6ef698bde19bba547be431d969784524fd9d69bf137ebc5b24caedcaf2b4c4220d711deb5ec99e57c6b5d26a0056805c6353fc3dab83a99e0c1b63be602f0ab17a6588eb7aa5a8c49735224e231dd981719730480c847106e1e340c4bc0f251c6a6a0391e9f4f127da470c1a4bfcc350b70043e3123c4ffd3ba0780602b621a82ce9762431aafca6ec6124bd3667667fa07c5fce73ed5b4b7874a2f82934eb137315a2cdcd6f0d1d80f2772b4a3bca0ea2ba79550a4b58850f577afff946d6ee56048ec6d0ff65b7ab8f4576466fa0896ffc2999b50d95e8b2cae1ac7249abe7c474d3e3f0ae1fa2ebefa0275f2b44ee6c40e30c760ebedb5620e096262f3f639e2e85d303821f6765c589457521f3655d98ed8f113e314f96e4bfb65f4b802c2f66c68be34cb9fce5cfc54081997c2cda8b963d200ed672b52fc40058e51b3e366aade56c1fc95a7fd18e2d9f4361d0250ceb8b3c21c967a533f838393f18370bd519368c344e175fed147d052502a530e1b206a31e9df48bdc4b77bd1eaab26e27f3280a1e0df371390f7aeaf68b8f50ccb9377d040689b68494e7255a603041239e494db7492728584c78c7f6307520d64c67d47884497984f652477f16a72e9e2a76061124be6e2a5a1426e42f5c9c63906be7e76a134af2045979fe31449bcc1b46e6187ca6d502bcd7193a1d8025de582c820b60d4382b7c4998952d28efd97fa7aef6626f5369b63f939f395b0c60e9b1fdb209e9cb1f0959b0b394e5d36a23844cfa0ba3052b2255c740271d1513b1ed484d9fe17c2149e9958125e288a76f2b3f99a5b0bc8951a14f477e67a082186749275dc8118c7742a66b380e07e7126311f3af49d8b5810a42ce640d8d1bd458fb1bc72c030cc7f7a62a18b418de4ae9e9b13d79cadee9f3fd8f5438f5a2aa3494835f572947ee71002c732118dcb7f831cc9a2c661e911866763b03fa869b99352ef48ea2fd8359ffe803b6565142acda226f5bfc83887b226ee86945a3271ac6e4319eaedcd16d7abac2aedee2a9c5266bdb231517d5831803f604cefa1a2bc62a06df9f7943e593a74295d43da83e4fe2de36099bc62ae17b92108c6ad8c7ee56775429e7a7aba74fe0f1df084b604d4cf8f6440eb788a14342abba2205e6c8b1caa005f830e7ceecdbe1e108329cdc402ef108e8240b6e7e87d80ce7ec8d0da0cd3c95e9be70594e308acf9de0118e7be863247d42e7155af04a55d8435774164d1c8ab4037b88f6b8fae07d48dae3af4784daa63262d6b69d3bf05c6bd1087ac444f684faf55fec1cde0d764c185c21ae4078e6a7321fa2394b04bb0f2434e7a08b89a79015d21dae244e9d2c19dd61aacd8eb8d61d9df5b39aa27d428ff7b66f66ccbffd6a701fa2551881fbfba403bc6480247959f704c4010bd61f12d5906de87b25942782aee2f0ce5cd848dd8f6fc1b43560efc9941c8d78eff78441c07ebfab7841362f259f3dbe926cef50d64925fbe138c720a1e52f2cf00954d5cb89e9467feb956647a30b4cf0b53d514518c766bfae170af218ab449c15850bb7d4b36b404d2b156a9fe033ce727420e8d53467da936662e851a54b0cd3dfed32e8f3ca62d2007dd8bf09dc13dc656c88293704456938d5260a0221ea6c0e55ac16271f7eb786a708e42af57506856b2f65c5a3305e702e7cde49967a8a9fbd04760c0e5ca294ba679954d7df3ff6122b0eb6ed351b2c73fa1d0fc3b69ac574b3f1673e86c145f8f0f306c6950730fe1116ccd86d7cc534850f19e62e2c64f136e8aa1c1bd5ddadce6f71508a067069dd3a793c282ccfbad2852c781405338a0b45657141040994c0723fcdf6473d1f08ee9b7814152441f7f2c9d92b676e84d4ce8780b1f11fb0b4e771833ad32f5b9a78a1a160ecf9b588a60a074849097527989efd7f8e09fb36d38fc7a59cd86b3b881864454e163b8333d44f68e6e64ffcdcad46fddababa56046587d4d0bdac108ae4c238ab77c695f559af54da3faac0d30bbd4068054ba0514dd28e62795cf9e030be5f8e7d8b6fc2af5836a8e7e704c0bbcd092c4b96cfcc02352db2fa05cd628b9b9275740729e48cdf2758399173fdd2ef47d4631de8022f87106d73809eb5d7dc17cea0395893d5dfae6d5064cf640aebd3471854efd9f6318e36fc948c75d5062a9abe3e7d2541d2adbe59ed13fc6a36441885d342a635e2c825158f5f17d11682b9ab51d887261b84ed55510577584ceed16e09a23bf09e23fc4540774854eccc603deb9a9f1aee80bb6dd2ca801f086c14cf414c2ad456e06a1a5bce391abb0dde1df68da733e08430f5544caa8bfa38ae8178ebb60fc9822e43bf4dd4224f69c3657c41ce604ee98d1395669b109017bb90bb8295ee63a7722eeed855b3ad683e807231751abaed9b4424add97a02c80b4484bf11f748373ca59ced343f0d047fc5821063f3f38e599122754ac51e310022e4903adf91128a4f16785f1c9ac2d203a41e6eb2996267bd955b01ad494854bd5452ec1d30984ba0e2fe40fff7522c1f82511511edbdee55f1b39015152bd74cb4f2df02a48977826e9a80cd77775a4a8d9293bc8fa048aa7c7e55e2d97b374a5a5c7564c298721a656d195a2863f6a91a27ed47b73705ba252af06e794e47309545d750ed67f87a319812de21fe8f7c200bb3e02b9099c08811d3912802e396cb6cbfe28559a98854504e2f37b45d8ba64004ea5aff2715c7b42ca7f33e929b151980717192371ec72f29b0f4a2b2f267abab45c6813ca6472fdb0d4b0bacaaa326c0d2ac90f5a00954997042c287233724b3cb0bccf44482f96f5b8f1893e3c471c763dd21334b14eae1f8e64ea199053c0c4670d92067002773f40c93c11d2a5b52d4e6dd2b20e1b3aa5bc031086159332335f39be9ceccebcfcd269a58f5aa36560944508236590c5a42e9ee8af502ac3e5ae9d03d900da262ae0a4a7237b003c8014e96be6dd8e904c75c4cdb825d031c79044e87a61562878affa2a63a40b0926de5fc83627ae8739790fdde0e7d5505a361134e7a15272ef0271db331bbffe6b9e724a294ef67123f8b023bc78d81f857932dcf3589c0295c907b46cb9f0f706bb5d8eebeb8b8edb31c6476c224080e70cd7fec4be0eab2389be3b0676968de55b2364e50f83239bb39ee23b9dc011610ba7f3747b2a01204e5db83478a00a681db369989cb9f7d253673135ba6a747206080812860dc4ff85bb6907e2e203758aa0d71b75fcae04b444dfe111e4dd1d6867a5c00d178370f5b76b02f1f2196bc392efd96bd9685fd1f63a3ec9a9045f9bc5a2be24ff93d12cdff333271b51a0fe7ae08b10fb50650ade9d0164c41816e7e400505d8ce795a438032b8a5aa4a887bfede9da114802fc6835e68390cd5452a4de5987a1af9f6751b6186f7c5f272407cbaf1d5fd790817c70cbd8b60b0861e30ccf38443c487e5b607a9dc43e5c6c4470f9c7da67f643174c324378644bfd6f775dd1d999a2286a63689d85d9519b21b8d321b38ac0da5d6dfb8072733b576836e74183f209656c7e2ebee9aae4f2c54dcfce8aac5daef5e8d9e3fb6abee7ce956c7f2eb4e4d05f0498cc7526effe9abc562e0cdcc23e8f249cd4a7c43f8535a10fe061f7d8edfed51950a325983184b35b2d0db3f47366733a15b660dc9ac458ed712545965f6e5be5d41e57a277c383a2b1f6d01d43b5c806ddc173f7a112fb920c43867b35801ab6f1d4257410286b102c2880babb66cd82bdf4e23cc72ddd325f5bdbcd2d5e7dd3811d4b4c22138ecb28979f94ef6f33ec381fcf61416dc55994fa11a9b594d5af99b4c18330fdda7cf5d955515369984515246f02b10edd052f2da37df8c9b44e919e92e34a57e4ee6c31d11a596667541daa7f0849bf9915e48949fbea660bd5596d565c3b537879c972a1a455fedbda149cc8e1547f05595d6859125662b412217bc2a1a110063375b4a7dd3d496ca4150b4a50620f9bcb8acc3174da990da40799cf4d948d6c7293f45e62aff96d1af064e91b115e9e9cc935b319b7448ba06e989a4e7cf542ad76cfe40f51190c4d44f9b8cf932372bed1f7fcbff50ce0852211bca2d6d1e2a08b04629bc822e6230e8dc55cf72fc9028fe3892e5304215a4f02482c8e08bea9b3ad1145e236b74f4d26aed3bc149616d4d31416e498d1492467c02577b5c938e76fa1c8b38f248fb856c73a3ff439be19bb1abee98408b48b8a9c684628b50f3ffb967bb76ccac57fba9da16db7efbabddd2056973814b54cedab52dd3b7b31edd4dc4bc14ccecf6b54ec81d50259fbe202361fde38c04ab860d89ecd2b4066f4a9870e2de8afff57688fc7e2a3039e8c919313054dbbf3b7edd4ecdd5d8632e6088715e74a41299f88df1eb7ccf086e9e31469bb4dea7f4572b017129f54d3a2031f72bb53527bc490f3c239c2cf3b496008b6764f47ef661013a62396ba128ee90f5644b65256a6cd97e1c1a0e6c023256e06c668b5109656dd10258a79e989f4cd1d045d0e27e2a7039f698bb1927b1435a0b4cdd0c463a4e1d0db150dfbb61cd4e2b1d9ce996b54f45a55b5a5c42100beef40e62928f1c152b53ea5560b5515a84614133770b1835166d64b248f0f0068bc6168decf3f81a2d2de7c57823950135e9ea19be4de80cee17ebcf9abd1dacedcf7983f35e15d0357c1ac4cdf55e0d97434084ee6f399dda053929cf11297237775190e9a080a83d97b58c4e59f32c6dd4be94850510613292dd9b4bbfe4956cdfdb4e819fb3d7dce263a2d69ad73c88b278f0080b36a48666aba18350f447ec9f11ce02beafe4fd4986aa97bf450914bea0f9c36e37dde23a97142850e7c398f0aa08d52e15a6ce138ad354978294af22535da6833d4e4e60225a07bd078e23f611b054790fd62bca32ef286c0ad648924d589605ce516c48611c66a90ccb2a1c0c60a1d79bb91f4b3f5effe5370bda651b7219504f4f8a983c9c965ba034d2ec8111e3c1924305e010bdb93d926c21b01e6a48ae80ce3267e19d8691fd99adbe3c3108482a97004020b051b62151a7f4bfc6a2bbd0301eb43340cb1b90c80152af0f87c78e8e23b1b82695c35d96ee2c8475508347eedfcc83321fa43792974b9aca09ce123ae80ac96345ac04ac649263ab93f02058307df22f5cec806ea3781b7f732507c970dc9425107c87d67420776f556597fc9a83d98e998f4a890107e8bc9895adf8c1bdea195aaec70c235321b044442cc3cd9aa30156595b61df7a3aa281b83771631c4c139706544712a381bba1092d3aa8159aec5b5a04bdf575b24e19ca5fc9ca86734175c2c859121a3afed18be3a5fd58ca86b3437da2cf23461c6e38a5b14e2d42b181eb2af0a39349cab12ec2b79f25f48963d30a4112c2c60e75e3134ea8f53b3a35e81ba0116be1ba2a342e09dd672ac96ef6618d684667ad0c9582bd041e5227558c70c8b761cad196ea7079e37f62eff7405c4ce94adce06ad25a096e6630d9680069a4518fac54865d4c7715fd64d61d7564e1f8a2ce5d540c52d14f376ff9f564b16c17850feb8e31bd0caa4c5f98177f0fe894c1ac362e84564d11ee28d644928eecdde3de0bca531ee5336da7be280f602978499687081b9b31530c4c12654aab09754d6a08510c34110283a9e1bf33327ef919426fda0d7d5071575ffb1a9066d01f9f91da40ea44dad1a0a55b9b2fab4a075b620fc95e177531cccf569d1cbab8552e56484fd7379685f4beef9faf872abc19238e0e8e3fbe2f2fb73a96e4969680210213f430c29e7d0e07a5010d4f2675c697330224734e4baee276279bccbc1ce8af080261a543ab633121345ed84c0f3c2e9b0d6841b27c3c91d8db0d0076a0408bf09bb2318dc691846e9b2aac0910388f825fb7640fdb408db50dec72de0de58ebf1034a8cca074d226f49b32282c4239905afad8158e11085ae6cc6d68ac60e42074ccbdbbb2278ebe50412a9199b5765b9d060f2802ddb07074ca6409311f953483c25582ab1cab19d6f4d002040d76804d2cd6b6612d4e8d20d79ed359a75df13763856071577c904008b45bf1b3bff9f7479e35797f4ab5d23638544311e4ad0c7b2e2981b71af83d758e87886df2195229947ff8dfb48728f57ab572c6328d90e1cadcbc92bb1e7a6f201cdc9e38deda5b2e3ddaad4db7655f1f694b3c60055eb585ae13581038ca8c7301e5459ab781ea06f1d31cae7e672dae663633b83c8c3ea09e8c15c552f52886969f5aed4e601374dbed4ef9b685cd422c8102601314081fb5f0f7a5725b8a8f943654da366f939fd30236da6ffbbfbbb79429b713dc13a512387c7e4565c3071b55d9a6c19341d4b8e2b7fca417732adb643e7c53876cb3f1e19b54a60f3d04718625e9e50cc7cf31ce72e4c8f13894661ec7e39841c1f133a3cc467e5fd9438d2b8e1376b12133759099543ee49a0cd320c4329afc38643424e499528e9f79259ac7f1348fe3593964387c5c60c9c8dc908def31191b366cf8f2b37e0619e5cc339c84b3d18be3849f434646791793ca9c2ac2f47997f171bcaf958346e63864647e868d9ff13468d020c999548d08737c1916eb6dd8b021ab31ca66bc8d1a339e354366d6f28d52e30c55e10c635559a30267d86ab5c2903513dd731661c60f92c9d1073b7d7ef5e34361d8438ae7c7b08f791862e10fec639e8c3dcc93b08f7925d8c7cc94620f73baf86cbdd83265352bcc714ad80a67be1a11e6eb57f0e212df258b72b658e293e20709a7b0161106a573e0a3d972f5aa37aedcd022deb0cab63cf3feb0fc43f3fe268d0c96675a2d1b573646d80d992a2c9f7b91a9225345a68a4c15992a376c5cd9b8b2c1858d2d36c2b071021b5d6c78f12c343e9a2b54983846d41671c7c9bed699b1e36452d6b322f3d28d276e64c933942432bf9cf9ca99a7c18167687ee695687e66e66974d0bc8e70cc356a68f0bef0b46143ecf13c689ec836f169aa641bcd956ccb31e367b6c854b921fe0d256e54b961c5f4e214bd904ff35186669ee695669ea6c7cfcc946678fccc2cca1059ba64e18cf7d9b89ad9e238228df7b9971ba1ec861237aae41af15fb21b56728d986139427c24a5c7f3f8b27685293a99f91def84e675b0e000251eafe359e831a3217fc7cffc8e6781c78c269c91b063a6b46336f33a9e86e65def72c9c8f7182c0cc3d82bca99d5a55c23ba66689e95568e233e8dac0cad3065beb4f25b95f087e6459235e53734f8902c4b3164c588625235224cf27de49415bc98a70be6a39c19c6052baf5c9e617c2b9c7946565e9dbef0bc316391536e58ddb86135e3c529be4c0c29152323a3a2728d2825d78819071c7ae821889c677e02139351590ae665c437ac68aaf88dfc10263f39a5bcf2d6ec35f3f5b85a829cd15491c2f4b997272852d916d6906d53d94605fb5056a3a645ad0a73e669de474ed1b19a62d47adf9b6bc4a7a912da883f23f3d086e6ca29ce6ca94d71c3ea14bfbccab6ccc5966c0b23dbf209b2ad4be92544d27a5f9eb548cf2ec2907eb664a23bc6220c3ec9190ca5d97223ff07a6a8aa7c264bbdcf908d53b2d28962b122aff75749e3956828cd988d53a1cdf81edac0c0601f939131a298f9a5697e96d58830f3afe0e5c43031a22cca8963600f23f3fd643961e5c364aed16aac325a1561e656cb3c5b3568c8f0cc17241ca560a439db02935d5e4c2b1798e5c34ca91acc295387d7c7589551d92625dba4ca1aa20ce12fcb8729c51e36f3f0431989ff35f3c53c20c6ca71b26be62ba7caa8524a2955d610c2caa8192de5eb0ae72e33df28e525145badd6fbcaa80f65e39351ce59695ab9f2288567317d9e05e31cd63850d36262588b158629be3eca50cbf5af5772fdab3563cd945cfffa976b16656804a31685e9f32c3aa2307b45478a8edc3fdbf299ff6b322b8f2f28336cac828981c744853faecf2e9fab8b6fa4fad64719a2717f28ad77cd7c3f5b945eae7fcd7cc871cd0566eb5def7379097f7c287f8c1498aa2ed92686cb8b8b8c18e02ad6cc0713c499df27c600a6ca71b2ab8bab8b4b0c9797ec8aa91213508e8ff18d1c76e9c245e4c265e4c2850bb9650b172e5cb870d1718a5cb818a9111685e1c8c240ed8bda17b52f6a5fd4bea87d51fba2f645ed8bda17b52f6a5f88400421f0620422f05ca35685493eeb7d315558e496181a61f84d7c1a2420e20c636884e138614c9533c42116b5384ef82e15d698a93af1971d809df95f5562aebcaabcaabcaabcaab43e8797f067940a6df04f4d5151cd58c184e138f87b5060922047d5951c4190e0c435ba9c384795e3e0578d2e27165f2e3c9ba9122550db62a4c21848a20523556d8b0f04490549054d95a5931f0a4d953887e4287e90fc640ec9f0431c230a3f8fe3c8cae3487e903c86e42883e51a1765d8c3700c43320cc5d0c92a56ae963862253131b2fc3f574136c45cae876999af9898d9973fd3325b31b39898b14a88714a16e3cf9598ffd57a568cc8253361ada91c236ab5605998415338f664064ae780035e3a50e5d439bd8a0e489d5d58b1603eb2624aca13632cc3e23f09bf8c38483612da01e7c85e7cc13c767d28b4c3933123af333613da2156e41c634478bc926bc227724d386629f3b3624418872216a610158e8d303c82e131ef5f3aa0088fb32c314bac324e8536ac93f538637c25941253c439f09910d57b8ca887e3e4b1c600d3d703d6c36fde22cf5a1167172ee3c3d45c608a1ffe2bea25e535feab866cc33fbe6b8adff2fbfc4af42292916daea8161ef2f047fc79bd6633d7bf64e5e7d8cce722e21cdf875d531c67ac3a6133df28354ac935e3b3645e922c9fe885152b82bf9c6559be4ff4929f7ce5972cca9959a4e8e51c5f53e10ccaa8da0bccd712fee3e16bcb8bcb2b8cd7095ef9eac58133bf34f0aa408d395659952cd94b0c17e345c638a54b11a66fb43a5f5dc29fd7550f0ee0d0c0ab022d2fa7cfac19ad548951a30248fc240e42684a68871194cec1cc0627c014df5773b2484c7e7e1f346476b5b0cbd59279aec91fa8828b53767a155554394b0cf3571431db5eb320724a6d8ae98b316be0f818bff919fe383e4b168631a21a1126ecf3bf64bed78f1e2bf27ad797b228e78b9cbdb46431b20e2c84a8c56f3daa58b9f2045512260b462d6154d9fa9c6731a295df780449054d9d415782a482a6baa8994b28233fcbc41cc2c2587e51145b201fc7c89cf13986a310e1f865cea218be280bf30b51e550263415231263392b6185e113d699a388d8439830939874c203529ef0fd5c9dbe573c499f3a4a89a2288aa3388a631e49f1b32c7c310749651028f101aab3cce5d3196631cb82a642317b08e38b0281d27194e263ec18635c53a3943f876198652de42861ce0728c5c7f9c59c737e31677214c95114b318e65ccb398759cc39ccf9c59cc31fc91f5f891c5b2c31bf98b39859f945f2c76fc594c819105068d38ad5b298f9c59cc5fca2288a39b38298c9383849e220b0d8827df9394643028c4aa908c6a1582467b155240c479345ca8ab05a2ed68b9f63462c3ce4b1da1326f9aae23839b4b26a71612585e91babb45a5bc629b060c182050b162c58b060c182050b162c58b060c182050b162c58b060c182050b162c58b060c182c5799ce4bb58c56fa34f5ce2c4f959e450e938cc304f98ae2c8e934306b06a5398bef18913e7af4d61b64ecc92592d517a2e7ba630f1c3724d01e314bfb1cefca3162bc6ab6ce3228b32f101b51698becf9ffff38f5bb8f098c0c5390cc3aa2a5114c7711c499224c99a132c168be544cd892e5d5a4e98f8bd9533911866d613a57350fe9114186030c07e9c0a6dca1811f79a9a324682bbcd3883db8826ec1de7702c129be5588d091336a32142be8761187e089bc13cec4b180c068395ef30b01f65e43956c936df68459eb0d2719ce4150993953f5a85ae16cbaafc5cfeab7c57f9adf259ef1baf6225ac24227e391babe41afce528f3f5387d64fe71b472e20f65314cce604a092a54a850a142850a152a54a850a142850a152a54a850a142850a152a54a850a142850a152a54a85079184c9c99f9c6872962fec8549ae2cc57c2647ec2509561f8129f46cc8be3cc77e35b486888b1b7f1e2cc57e35bb9268c297ffc524696e56b20f3a2a964fcb208fe022396b2f2636f7e58ce609e1467fcf83232df0a612081797146638e321a1a7346a47cd8c3be7c998795a20ff6ac3236fe8c59eccb1953eccd1993063f9b6960a4c1cc6fccdef0a4f1e397339f8d995863f68667cc8f3466325f0ba708fbf2cb52062bc5d214611ef6658cf8e3fb6f788ae5986de6eb612f8a62cd03a61896ff82bd287bfd18cec87c292323f33846447c19d37c7366ce7853363e8c2cf6309987f9191f0e989799f946aa1366f682cd985e5fbe663ed84b2c5ffc51e61ba9ced1876394c1fc48d5844f9967c1664ce297e50a619cea884f998719613f9aa62c9f30325fcc4c1da960b2d257be1be55c218c1a044cf17d231591509495ef7a18590d0226aca43a63b117b04a50cb0a6198612800118ce0c454a1004420822c422eacb8a8e2628a8ba898d2c5e5ac76444ced889a07ba78a04b4c8c28c666b1982ce6455124aa1d618a628c07b6d48e20aa1d513b02a68c9a046a11a82d51ab42047f396994ca7f3d0c58ccb9159a188fe2935f449c8d52a314c639144792f5047f1965352b337fe8aa59bd8ac617bfc838463973ebc72fd29ad1b4def534e347395d33b73523b283fc714664478873188aa2388ee348922449b2582c168b5543c2cc1f6ed9d2a50b1266b9e32467a2954fb4f29948d48cd8428c3384d3abd0e2ea2c637c7c1b165b4224995b38f3fba29ce318922fcac62789c65164e11c819c31ce3197cc375a953099ccc33c0ce6c77c08f34a32af877925f3f5315f6251cc632b24cd227ec2602c18f263f80c6346b1d9ab4684f99af95c9f5dfffa20a13a5ae528e1c7c860c219cef05b10a3bc72f84519c6d41c108ae2388e2449922c168bc5aa39a0e60031c78a8c9f3f5634ce32ce312372cc62cea12cca88595aaca87c787dd054d0944bf6b3e51459ac99efe74a4a4a4a2aa88620a9201b849852f59a7a519de302a4826c588094540d5356e30a4a2b2cce9e84a8728d1055ae61b130cec92fca847438c52745a1b0c4302c13da01e7885ccef1b525d78ca11825fc590b676d0833bfcfcf51fc560fa595951255ac7a2881307d6316a9522a4b2995258b0fa56daad421db481fcaaa6c2bcb29a5114253423b084d91e1a58cf24246195595c54b1629b45871c5c596322adbc2aff5e01aabb278c92285162baeb8d8e243962c5268b1e28a8b2d423b08f9504a79c9525279c922c51519a554594396524a6807211db25859596511daa1b42aad942355b6893ffa706298c731570ccf6a9866364089cb6f85e1d77e307d6355f8f3aad20aab54bdaad40e6032b97e2cdff541f2abcacbcaebcaeb896c235f52bcb4645bd9faf0afaeb868952f29d70709493c7b19916ba6e41aabd79497112fab6c63e19755cd00f85de3cc17a5860093f5fe9a7200139fbeb16a0c7f9c321a61a544b655c936d8e9c3a74f8793fc2aa6bca664db2b4bb6f95e53c6aaaa33fc5188f05f46bcaa649b5751859433fc9795fc83877caf2aaed993f0cb97aa707cb95e7166e6737de3ac45fa6b0b4c06160b06cb31180c46041b9f050323638e3131b35a1964d4192a21e28499f9a29c30cf9285368461ec6164b120a9201b60415261d038b24211060bb78c5fd60c60326133dbde173425c26a44f1566ba4f2e1243f48c6679054cca83cc3998c2ca64a6883799cad87d9e2384435264c9c051127b68ae271c668e0c4b3128cd317a301cce3f458915188718bdf6a65980ec689df655a599d6489652f12cb44d3eaf48d5467eb4921666355aee971b6bec7497e8b8cb9621542998db2f1c72749724b2cc35c50925fd67a3099583f9ee478b29efc56141cd9360a5189b01a51ce512cadc8c7ae28a3d014eb3f9c290967be28e3b803d518ca5c98c56279eb85a646511cbfc4e2cc952e2789c571d67a65711cf283e4da044c92bc726228b3202129cac417838451ced1ab5a639864d0948c4c9054900d4153e6b364e6cc1725c88620293f71d054900d3466c47c6b562bc314adce201b4a2282a438e86280992b335a66b2cc5c054dcd3c3123c58c153357826cd0c2847d4d0bf13dc67c808c14f695449ce28da9280eb6788c088f13bbde6763090ea41c479cea9125b4117f86cc439b58f93ef3013cba388e7845ea14bf7601d337ce5c39451f07be1e5a4e51ca297e79a5c715073348a941071f84b072e54ad054900d545553acaa9ce273d0053603cfb60e6439fff42ab49071965e6618141c251361a24cb2be1563cacc60cd94cc9031637c51f0b75a3b50655beb7190308c11c13c4b06d32a3ddb84a6dc4ff285a85a32cf3966549e61c982b5320b8606e3194d97f0a76c955b68baf87a1091e4630fb49caf45162d8c384b0cabf56032b57e1c4f1d514fe325dbc83c13838c6cc3345d6a5726ec6b57a6af9499c2adcc92a932e3cb2de1cf8d2b260e5f8fd3576ef1c1a44e71c6cc83298e23fe159999af8739f3e17039cc8d2ba7e8bb11c67b711cf165a6ca17cb67cd7c3df2cc87c365a61ecfa64e91a64b9553fc1a064cdfb8a5cb2996563e06a7f82f9a2e1e10718a5f5ac962294569c5297261c5e96b85259499b34821aa8fc2f27156a57565cc82c5f7408b79658ab1582c2692b198e8fa58cc28238a315148089919a2187b99989711678832339f1015cbb432655656e20bed20b483d00e423b88e418575b4e8cc3e955642185cf63333326f631313131b18f89897d0c938ffcd6b770c6c89818f18cb162b1568c8b1c59b0d8c7624c33c634633e4818137b1913cc7b8c4c4c4cec67c4fc8c98697e902c0303f331e68c19b1f17d3364bec532636acc781a3364622cd18489f99818a9188c2cc8069c139b8932871929cfd7cc47be2bff381ba7c008c3308419c7cf423bc0e4fcca303139bf1e06f63039c30851598556d92a26b3b2ca2fb483d00e423b08ed305a9155b4f0e104e1f42aaeba903132261febc56f6164c166e3181b3f263e095b3fe3e382eb15c26231582c06fb2021ecf532a612060383bd3e06f631af272113fef23da6a48c817dcccc1734357e0c8cccc3c4c4bc8c2ce6cd570cdfe7c21ee6535be197b299d89af958a718cea658429464283425a4839010423a08f92044256b912fabf2359bf9a2b058423be0305f987c01eccb320cc9307c0fc370c60ac330c427ab2566162b7f9014cb17e403d3f89edf95737e312462cd9e84277e7f676121c6c9737a15585cc9c20a2b0b23b290c262b16a659833f94b9827dfc794673eec7a6101ee4ddcccc1aa6930c743dba1f1e0b0bb35c5d9aad6b92b2f75dddeab8fd8dd6a04d5b2af46578d44d5ed062a51f5af6593b8ae56850ce9e95e0d7453d485d247ee2e814de2b63474f75cdd5b83fb97be6bb0c561020e273886f8d2df96fed5bf5ffdba8fee17186c5b5688bbefe8a85ad53714dcd440c86934da07ef566f5ebd5bdebf6c92a7b9af6aad0675aad67def4d9d9eb7a6e81afcddeadf4d6eea6eda2a4ebbab6edf9be300601ebcc3e38e61f0e8ee3e376ffcdc6d697ab7af9bb379ba655fd7a666dd2a6da76ef77ff87834fdb92dade7ea5e4e0e90ce27a86797cbd9e1d13a3f3dba1adad35303d2d93f38fbd5edebe6826e8efb065926ddeee972de94d77375ef767b5b16080cbab8fdd3edce8611ee6fcbf6dc67d9b7e7eadedfb6dbeea6dd3e9aaaba6935fa717725376d14b92d0d5df7fbb45dc8dd5570b3c695efd7dd2baedd6f8afbb1ed0ea7db403747b79b727a76280f90deedfcf0f4689f5d6ec74717f463dba9f5fcf0e476745ab7fbd139a09d8e8eced1bd6eb0cda961e5c6dd954d5fdd56895c1698c4dd4300c1bddd68dac4b647fad543dc76af6bda046ad5485856c9c3a61c685850a5e6221316102da054cecaa2c80b9c6802721c00f6c503121d70d60baa8c0040a3f9e25f4ee0e30e34fc20b1b380e31f624d7920c2f34f088911a06a7cdc21bc408f073e3e9a50c410142079771b1608348400c49d490a2896a4a00bc7178832950429c559391a908120c850e2a2ab023ae02ad0e4ac18b24ca120832f4e9250ea1f59beb8b3747ead38f16c82225a932a82dc675044540a414a30be6d035f44e08bb38232a0abf2c1848f602460095fb1713ca546c8c6da848748a0a051c293023c07f9fd8081df1727dd1ab0048172f2908a2157c228240f8f8e9a40f8c00a4e1e40070f925841099eabf0148964ec70160c051822ea0810ce52810a3e34015b72bf620164dc80e30727693e1801a6cacac6575eaaeabd42eabe41164a1f11c18cd171ef12b5e4ac1fcb45177f606755617494c12c8fc1e30d0c835b3ce28f873a883c58b9d51ac51063d720d33c3b264114013b4b68f418123bc6781c6bb9cc8e310e7311c62c9c310ec91532ce98956f20614c6296671ca38599246b5e8fc59cc5292c629c5fd80519bb7cc4620e37c6be8c716e2dc934196752ccd8041963326312b0061887b975813164c1e01b18db6885f8079c319931ce210e67f1e5aa651806d2c22307e10fccca59dc095f39639b181b0680b85312098fb28b9e1780c5b0461c330e7d2c00fe027b76d3341d3b1671c629c0ad0c02c679cc39c4b807e7e01686e59c3329047f90b398b14e482b73b43cc0b1193399073ce61c58c421f67c94ff8545cf29e9bf840710baec02d88364208798c4220bc770489573eb1662a010e72c7e86b96af088314b47dce9a183f38b6c658c3166617cc3397b2024b12b8b61139ee520c6210e769519b7583807c93c328fbc23f4d0710c2673c631d10cc59c23e78c492ceeb08b035c8e198f18e607638c314d366295ae8c732d182b6312700be330631117e11d3928ebc86566e5118738e35c669688c331c4f80787b806bb300c632c8479e457c8c22d11678c6f189337720d2c663c8a38289738cc3c7018e62c661107e58c67f20bbb704bcc18e31bde915fac108b2d1163fcf31807082d1f6108230eb10b8b38b0cb752b4fa0e181371071ce64666d6cdad0298b30ce38638c719ce54037210aee52420afc4b08220c2d25c8b89ca089fee288255e6c7125d9169e1404077692a6c29182b0f203928c55424210be2e47ba16e448103c5a50a475e8040581232748c334e0c78b18073fb217b6798167605bfa0284edcb70dad2183c7096a6e49b2d43b037af03420855372ae8b1f4b01eafc10cafa291822f8d38f88b01700fddddddbdc66d69fad5288e94f2ea208a28968be512615a36962bdc01537221c9ac5543be5a40222c068b3012273a85b15046bc0a8001a24898cc728937b11d404744bd98c050f106c6855ca319978898f46181a81f4786c804208b2ff1880d0ca246f002085a5cc0e34da6471017b23813e200b10cc818c2155124d9e3488a8d982118c2222ec81095c3d50456035663052236802df7f582281fafabc812014c962b8c8d4ce20c35b8d01261c81d38a6c7053012e002010b292d2f3cc0e4720c22c30a128dec13ac5ea031d6bc88bc3c205110416005bdb04410455e28e2861ba68e9498ee88009e882a83bb030420c6138399e8088558396c2ebc5841e4ab0513fe18150977bc88bc20eac5328a25b58a688888bc5c45b024d4c712511a8837b61779a311235f25d14c8521a25ead221e391aa2c6d01c314902f91a854810800c9541d707ad22f2c5ca111be2e2404ce2d2a0860e0f666e80d00ac10892072ebc5a34564face7c7e88805135933e32db4b960e2071f84e562bdc49cd1880814048f34a16cbca1e36ae9c22022211cadd70dd78f0b429294b5568dc881c8015944140830e290318491878b035147cc4eb8e385285a0e0e77218e188e0098a9908313ec8ac4115aae58215184100288c2c293cbb4dbba25155030c10993254947474628ba01f5d478d0c1062f6600035f547002304400d2c16c2607ab6a0a29183004094422dc76d88095e4135626e080290c1042014154fdb0a4e6831cda010ca094f4850c317226a8200514c0b13204b821dd01117ab1a6e030f5e3d2e28a8829b7209b0635ca578ba5834602114061a34a928c60448408081b669061c6169f269038a288284d98fcd870d41039a0a5054c80fcb0b958e4036298401209d821071a0080002080b841491220421fc0f018a10cb217b1cba72087218291bd18b7e02d7216190bd715302b32073215d94a7e40884466127d9803dca3b563d411cb9135c836700d191ae38c2c834d112697e32bbb5aadcc628d59c421c6a4c762429ad08928710051e2111284c72c17b8600e11358e3096075bb82006b1236a0013a201a400a2c423ae1b2f1d380210e52a413421e451be24ac45a40544be42211caf318aa85695a81a28b8e0fa097f6001ac8ba8f14bd4089bc1220af6ce9c8872e180c92ca13167d441ca4699838717c41aa2626431b2104726a78543e6cb0b63082d20968f3026f4d112222a44b29343be4823a2c2929c116fca9d108b30f1e645640c8155023943be481fac06ac860b87eb06ab8470062f9033a1d50b6396a80e7ce2ef711dec106fb0185246c4214e28443c826940665613160d2bc96803069365388ab0300c73c80a5ba1eba5430c594b5833628e5e322c9285439658137344dcca11d2b8e0ea3136200ac60817644891a635e405b18b1766b8f72f6580a1c51507b468204b909784c314d190083f7ed8550529c8f9c08c69b14e304149922f1bb0a2033d6ed0a1e2218801bac8820a2c149000120cc8a179b043f0bdc16d5db0822e5c5c610506a844694105144c70a2244911223d786870c30a13519038a20516703b74b06b0f982e40f0e417f5a50c18bc00851334b8219305960c5480021288c0036eb061069c0a25345192c4888a0d64608a26a88a3cb005155830400127861082061802b0822e595c410127ac2421256aa3464432b12e22e0d2850630c0c40494200287016c14a7020a2734312212bad9c8c4a8d880067e38000e5236aac208464488846e3031d145c0858a0d4091012626a0c4038820800d525218c1e887d0eda7b663334346f42f22e00202283490010c303181071041001c6c1880942f7029a020420e8d8c318e188981f9808ea91a6870d244270103a001eac901ae2f61197906e3185906ad06884564223203304fde097530adc4094308ff468fac03d3b066c21c1887a801bee1a2316346688a313018333603cb51ea78c9b8582d929549721cc31a779f717f992e75ab39fdae690bccd928ab4bd7e00e77cc720521dd74cd305d2fb3c5c5e66bfe379aba6bfa6efa6ffa4250ad6e754ff73afd5612ad23cc5695fbd2f3d674f79cdee67ff8f89a1f3e7e4d793bd7029aadedbef43bf6ddf45fa85c0a341aed04a322276774dc47a1d9f881bbf77093b5c5dd96b6b6fb7d3530a77d437093f583c9925ad3d7dde8ffcbaeef6e167d9b9aad6b83ac6bb27c2c2547d7fdea774d560d5db7c9ca6497efbdbc75abbf63ff5b76f7b6fa757ff356ddf6c82b6e4b6b7bbadffee56c5daabaee728187bb6b05f7edaa7ab783edebee33ad168d74e21fb8bb07eedec1631104ed3c906fdba00e84a020a0a09f205b904f502da82788276827482728080808e807c806e4035403ea01e201da01d2010afa01faf9f9b1fdf8fcd47e7a7e787e767e747e826c40b61f9bcde663abd97a6c3cb61d9b8e2dc807c8e7c7c7e6e3e353f3e9f1e1f1d9f1d1f109aa01d57e6ab69a4fad56eba9f1d4766a3ab5a01ea09e9f1e5b8f4f4fada7a787a767a747a727880788e787c7c6e3c353e3e9e1e1e1d9e1d1e109da01daf9d9b1edf8ecd4767a76787676767476827480747e746c3a3e3a359d1e1d1e9d1d1d1d9d9cce93ce76771a37471deeb6b45f70cd797fbbddb2ba144e78ddd4bc6a5878161e00ff37af9b1700feffdf3770f799bb8b2f5efd4d89251b4cf10511e8ee39dc149bb8fbdf9696fef6ba595afadbbbdbeaff6bc9e6edf1d2f6ffdd6db566e96fe85653bd73f58f1f3f64eeeee95efd93bd29cac4ff9b0f3ef8573fba9974e9aa815edc6fe115eefe6e8654fcddf40de6fedd74f7de3788a465db96c8896d5b76c80ca7dc69b4b0c9dd596e86ac190e719bf7e1e3776a7eaf6c92a55fd9f4052a71ddfdc8cdec85bbbb2d2d97aa6fcbe6b4bbdb70a7e1ee1cb88b326238630755ddf44b6d4bb4f4abfe95fd259b1aa06e9dd6e0edf6aa4177232d3dba5555ebdcdd74f71877877198bb97d807774772136b31b11479e6fe37175d836cee77ecbf41f6d917f7a62ad0755b9a0ead46dbc171f70b95cbe9e101d2eda01c1a14c463d3e9f60ece8fd5d172c1de9bf2a0dad74d79bbcd6179add6e5a85ac7aa39ad1bccf91f3ededd5fde9ae126d6c15dd50bd0c04dace4ee35dcc441fc47bbdd3575f798fb0805d7705b1acafe7274bbc9742f5fb8fb0d375d0a775fb7fa3e7ee71e55836ccf7d9b77d39a7fdae89afe6e627fbbc501b593ebee2ef78cba3b0e375d08b7a5bdbf1de9eed83d7bcbb6edfe553fbad736f8eef657367df5bbeedf5681bff4df54b7eff3d6f47df5af6577af33e9ee3adc741cee2ee3a6d7dcdd895577ed6e621fea4d751aa8756e4bd3ed269c936e7374ad9ba3635555e740b5bacda5aabb8fa1e8ee99c61756a55f898a3a3da431021dca982c7f89f1508c8516f2b766514330d8bb582ff15f315996223eecb18c05d7e3ec8abd4b16830843e1bf6452a4f050f831883024e252e643a52c16fb57f95278e8250546820fb9b08c85d763177e16cacf43af5216a321c2ba7232b1660c80ca4fce180015be08a7096b7dd92a6552ca97faa1d7b76452621fc30fbd1ec7665133292cb410fe6b16154a89e187621fc64c30a3a26232165a08bf9c45859f3f540a3fbf645278e8f52e99141e727d299312830843af97c243e59759167b2c837d1823a22141fcd89b103eec5b3229ae26518662f85978bd8c85f225231f0fd560603ef12f2739636200547e0640892f7e7ea5f0287624bec78ec20f923fcce412594a4a8a94388ba115fe4081d242fef05bc02f3e1407409122f543e3c7f0430e5072fdf82dcca0c4f043e30c4a0be4bf66ae590bad99d40fe11f9f356b81c43fcec2f76f81c46b598b41cb6b64d46430beb7ccd0667c1f29a6f8ef83697cd117651625c4464a7f12aa2d292fb880f367d1fd86a988a2283ec69809fba0f8f08f10857c114a53fef10d7ffc20e1188e50468872b6583351c634ce9e40395d2439be380b7df9314bc6d482228a61188aa1288a62188e327f1c3312937f24a2748c7128cbb227a1fb38f389ed2b3e396bca4ffe28ca9ee03899f2ec0d4ff2fd7ccd9e4029c267eb5db327504ed68c89244999387b129e4cfe6e24e6cc515a383751d6c630f397652bfc19cab218700ca21429073c11e1648a419c39e0890867f81837091f972c6f9dd845a129a11dc4f109d97865aa4665e21fb5843fa315ae727ace213ec32c1badf84f852cf8a2ca0b1d4e17eb5def9fbde5ac9993ad6705d56043d0944b361a916ba6e49a307b8c4814ab38ce68956bc2aff160e6c73e4a651bff70ea8a289ee2ff5c853ff83dfb6c1c75c83557ba1c651baeb28280d7e0f7a567fef15b331ff0ccefebadb0e5cc335f58fb80e9c33ee49a271a22e1493e945c73e4858b5cd82ae3c710c0b86a744171e2e4ea74926b70a9e5a5e574c97c4ec6596ae02cb79c384bd191a36cc3277612da601b5680d7d870551ea5c6fc231599b3f8ae8e62fe28594663943ffb13e2670eca2c5a3207b906565e9df89d54655ba901c70a28a538f1e3328c135f29b3380ece1c7070e2137f59d3c27c75711cfcb5294cfc3ef2ca8967f8cb2e2faa98ab0f428eacb135bac6a7711c635fc66440b50f00f97872b997967b61b917d2bd54490102d308d2ca8ab4b2ca02e363245ba4d52885ab306915b658e28fa4d599b7545db5b21906084c9fccd49633ff0d2abf85a37bf9537455e4af99f7f0f59099bac23253e596d90d2a2964a6cefc4f3001d4d8b20508a8a685e9218be55381b830f1493aa903e959c65951ab659a3870f808f1873371cb1983336b9167315bba307d6616922a4b8c17afda1437ad56abd53a811752b6b400b3a08a2d5c6230519ec1a65aae1a9886cce73f9af13ed7629a2d9f49a335c3868dd1c66863b421835d993e73cab49265732adbb23a434d21ce70ca19be87e6d454f8a655b6b96361ba125d5c215931221b33d894158df7f0c7ccdfca3fa30b519eb51a60cabcafd525fcc143648c23b6311b471bb327ac28a518a5171fb187306597a96c0b6b59982fb66032397094256ec95ed83467cc623464a6cc679e38fe2467bed1cb19be4cd9c5c638e6318f7926838de1933125acf7a955e490796833d674720d14262c4a8c6cf302930293cab6a96ca319c32791b0de97dfc68cfc8cc7c7f1396e601c391ec72be5781c383e470e73eaa4b2e16b9d30d87b4c2ce66338727c3c3c3c3c3c3c3c3c3b3b3b3b3b3b3b3b3a3a3a3a3a3a3a3a3a3a3b41414141414141414141404040404040404040403f3f3f3f3f3f3f3f3f3f369bcd66b3d96c369b8f8f8f8f8f8f8f8f8f4fad56abd56ab55aadd6d3d3d3d3d3d3d3d3d3c3c3c3c3c3c3c3c3c3c3b3b3b3b3b3b3b3b3b3a3b31304f463f3a9f5f0ec2051f5dbb2bf9f91bbdfb8f3dc5ca14ab73b4797b67bdd3c287555f20bfed23545e2c4aa7be8ddae7b124155b648c856731a5d37f089e86d77ef55724409aa87dcb110129bc4bdb9e320770cb4b229d29bfed223ed86d2477edcb1cdc7ddb776511d5112919047f59010b7fd05dd95d5b92f30b8919c76c15fd3575af70a6cbb7b83b927f26ed7d5a8caf67e65bfddadee776ea728fb3efa6e8aeed549035da855ff9e6595da0da5d557f5b9d9774d1f18646259f5d774f72fbb0a599dd895695d62e3c4aab9d74fe3d176cdbb7befa034f0d9f757a3dd06dfe04ee7bef7b669eeb5eeb93ff675833adaaf5aef9c5669e87e35bbba2ff46efacf5bd39597baee09dc718f3be631dd2774dc5f76c5b4fd6393dc318ee31b771c823b06c1c695522032c12809378468881221498870484a909088704447960c518204e7e444a25d54b7d7cdc42a21010a02f9edd768088f5551a3bda6bc9548484be38e1ff7705d16b8e2802eba5b1d7ce2e27e4177136d55ffd235fd3d71d9d438cdf114d68b7b0ee7ba1a886360de55afe92f6d756e8afe2fb86ed7dd634c6eb2402af097eaf40e27e62aba7fae7672d922de9a3e6dffefd72ceeeeeba64f44fad543de75b7bbb71ab93b09c20083b7a628abdb43d08da4ea571371f71188c0ddd19465a25d54d70271dddda2a8c63d6dd4a8ddfb084d71eddec0146a3eb69e9eda8f87bb6f209412d436c2be40a856c7d3831ae9ce1645f56ec7de6ebb6d59a77727a9d982aa07eee866aac10786077b3a1648b4737a88081213743d9dd228a877efb4db7375abdb4ebf6bb6e0efd21762d2b1aaee55553b3dfb3e9476fafd63ddd7ea6e6bb6e0bbe9e7b8ee5ebfa763815bf7b2aa4b34740ebd4ffb5d59216f50c96a440489c9cee9a11d262dfb02d356e7ee21bc74b7b242dea79d8408121317755f564d3a9d5855d536355bf06f6ab6608d6e4db57a04d5ead7dd3ca856ffd2f6880812931dcbb640dcae6d52420489c91b04be4116b76b9b5e564d7a59d5bdddda0d0cba3c293ba7733837e8aedb5d59dd0e04ee0e04eadb0d8703ba1804ee0c90a1c9dc851ee4a5b97309db6e13a086700e9818ee341d8bfe568328bba68ffe8e65db2330dc3de7265ac692d2d2afe9bfe9eedf20704d7fc7fe2fe8ae671bd4e9d8f51c02c4b3b304dd4f2991d60fba2b7774c8593d774fddd4b9bbdb7696b4fbe876c301dd77ddba761fe96a70f70e306f4d7b2faeddc09c18ee4ecb9dc0dddd7f6ee66e3ccd01f1ece0dc7603d5dde3e909da76824041209e9da05e62890c2542dc9d8a0db8ab6d4ba46355f52cc0520a1bb4b82a1775f8007035d94835d6a00204dc75a788c2084a051f29d4e07a978296deab813950af14ee2e46f1af1b44fa1f6fbbdf7b35f055f5bcdddc5d27e71ec141775f72330596bb2d0daa7dd79d03d43f1482af7ce48410bc9a9736e9d0881d4426a415af8bfe8f1faf6b5d1a643041f59dc7f9f13ddae6a17ba3ec9ab377fbe67254565782929190f3e814f23efe094d4bf840093edcdde6c35354c28d0f11f585b71c9f8073a2e364097fd259d9d44d9b52946787a68383a36a1d7bc4dd3b70cf276822e5c05fb0491026633009c3dbcd6bb5faff84a6cf64eab7df94499049ebee44dc6472e34ffaf7bbf7ae4e6ccb03fe82bf7b2f13236ccbb67b8554bddd703821e86ef76e171c7247a2a485dbd2da9c9c9c34c7ddb1dfb2ae6e37ba91ceb73dd1fdb24950bd8b9c76922454efa2251b65852405a15b0d04feda9ebb834f369290750395007f6d115218ee5ef3bc87ca7dbb812dfb43a272f7740dd6b848004072e2ee4070de75bf6efab47f65d7d7eb76df4d1f299b248451f30bfed227fd63797b2541879aff27a1258135490042820eb779205ff33a1ebb57277d8404a9c815220e893e70b88b402ee68832f308e8eea31dcbb647afbba69a77b2445c346925427275ef89682f79f5af6589286139f0177479ed5944b7fa68b753b23ab143786b8ab69acdad4a5cdd6e5507a5dbbbf4886ef511922dee3aefa6502ff0b74940320449049050b99be29efcd0fff12eda6aa7d58945712612134c244b9084ee29a07073020aaa0ebe3abd7baf92233c1c79724487bb7b10378d70e17f83a64b4bbfd59c5e6a77138bdbbab4a9ddee1294aaeae0aa7fdfee57abbf73bf6a1d4dd5c135fd55eb9ef6bb796830674409234d9e020abf5748ddbff91bdd6aa0eb6e1ddb027fe7d0a674eb76bb7f6c92bbef70d3c8691a61ed360d3ed9eddfa0db0da2abee7d4f49c9085d8c6095020a7fb37facee0db2233c71dfb1ffee1a448d908c90c41c41c73d05141e4dff041468488438f9475bed045c82a638744d8dec967dda2b10127ce8369377bbbb1d6ba4e4dbad11ada8044edb2fdbf438bb05ee47f7bbdaa9c801454e965056b7f4b48db2ba27c2e4e8752e6d756e2ee87e9b7ebb7b6fba95cc22d35d37f0f7b3efeb560373dc2c72c5ae4e7bfdd32c42a506d1ddd3b9c1d309aa770f35d26d8f9b456096d074e969bad547af350a0ca2ac0e5d53236bca84d3ad06ea704d6eeaee75f3d01ddcc1274050203d5717a17af770ba27ef1a6475389efbc33de91f4f4f70af90bab8cdd3aebb7fb827fdc36d9ec6fdda74b7b23a20a8910fa046b277ab34e4426d26144dd7d408baa64ceefea5efd34687c4a0e54e669cc7511445310cc330c4243992238b1c4516c96291ac18864eb0a62c1087eea774a74bdffdebbd69ab7386a070a8dc6f346d4a51e06fbfaf06e2d9093efbbeaed6b59bb7df35454237ba1241a17ab7eac926799f761274afecefc7ea706fabdfa4a3edea7de465d524b7a5e9dcf497a373d3df939b678dbb83ae9be6f474fbfd17f842e86e378f97b6ef6e83e8ebb3c659c3fd6f40a006023510a871badb6ddd47d03535b26b3a62774c8cfc8cdcfdbe27d49bee24de9a9eba9dc45b53269d1e7a535daa029f88de96cd9da8debd932df2aedbdded51dabeee463a42770a0cea744a76cb0a11f2b451216f3a94618038d9e90e0808407600d101c486bbaf6ccadbedbf690ee7f5ffd876f7bb655f17d56c8672f724377fd47077276efef0c15d53fd63d1dda47baf5f5553a77751bd7b37ee8ddbee77ff74ab81aa0e3ed92ece9be6cc1fbc8db23d9ddeed1a7c74b7fb5df7df54bdb6fb5d53b7a56d5daaeee0b8bf7dbbd59a6e3777f3f4d19346a26a5dca638f3c6924bb297d7512269d7e93a05af6b7913c6924bc35dded11909f6ef551cbbe41dd7ed2ed27a25dd35190ddbf5409b8dba35dd351cd167cdae8faeab62f17745596cdbdc0add36957d54d6c0b046a1cbad1bd57f7655517e7c4f65c1cbbbaabbb55e04fbb38560da2ec0fb76b9bdade8ba64eb8ddd3416975a3b8decbb67b057705020cb26d1160906d793820a8d1bbee1f10d4680814d466c241b5bb89d5b9290a043542b78bb269bb813834059e1e746f17f763d155b740b62e45d714d784d34098f8d06d26406cfea6c6876e3371dd1e4ed77375516ae40d02dd740854fbae44edbb5bbddbdeab5bad438d5af6d5aaca0a418d80e8e4dc23b75bbbd196bddd74bbe94d737ff3a6433c3d412eeb4e81a96eb7ed46d7eda2463c3dc19eab8b8090a046ea5e57dd1302fcb545a851cfd5451b6585ac6c7abbada9eee974ab81a8de453f5adcdddd4de99bfed21688db2dabc3bd2caa995416d87375d17e359aa2ab16d27375d1cf0f1f4c9b154773073627eeb6d3b4bdbbff0f1fffb725de9aaea9feed76e95f57037feb56dd84ae5aa7db282b44000150e1879b3e522edbee159eb7a650eaca3eaab7faecfbee9be63edded82bbb4e73a6ee2eeda4d9f96ae0707c7e6660d8bbba3fbc90be9f4a8c0f3abeebdefba5b855af5bbfbd76a37c8a64dbb3d02020428e843b799f87083ed66d2b1aa8e3d92be6a1009badbbd3ab1403c3bc1770db23f5d939192210677dfeeca02dd8df4d33959535eda2a519540edd213ca6d77ba4b5f3609ba93f6e6e93789972261f2d33da12dabdb485bcda5bc3548e4c87ed9df46da61a2c384d7d4b6444c4a8894dc13ddbffd1afdf66be4be691321fb5d8d7872fc0db63b5b5cedf4aaaa757f9a3b53eeee34732788ebdeeb5fd3df7ed3df2a6f4ddd3fdd1dc7cd9d96bbd3dc60ced4d900bba23c3d411d1cdc7d899b3a3e9ca6aadbc9d57fc35bd3d76dd3ddefd87f1a94aa0677bfdfad027fac0e4dd177f7efd8efe95e3dc4c3e45d77aa5bcf1d26efba7f501a88dbaedeea4672a1b4937aee9575da49b6ae6589f0d654d7b244dcdd6e8f5255336177ab917e75a7bb6a60126f4d6f37de9a32e9d7c5a92c9b43b7aaa6b9761ffd581d909a2de803880fdd66d2b2690bc4b1ed5e616557dceb6a55035ddd12bdad7e5d0d4ca2e5406b3d6d74354ac2f9c1c451427bddcde305dd7f7bbcf4f71b08f5ea6f77ee175c7ff7de9bdd7b7f415eab7befef77da4994e0f0b8d33610ea7df765d5a4fd4b9576f089062a41d7d408baa64ce68d14e64d949b109c96020a2fabba37e89a329d8002cddd3d57abeea3e87e5397056ef4ddb4a7f4b49755dddfbff47d1b5dba4b751be8e2a06bca5483aefa9770db5dda40a0eefd12baa64c4bbfeea694b7631fdd6fcb0277fb5bb7eedd8efd55bf9bfe6e774f094afdedf608ddaa9a1ae9b9fa4d4237bab243aecab247b96012da6aa78da4b2ec91cab247e8cae6d625abd1d66960528f176457a2974db29b5277ddbb3d84b7a6506cfbba7b08bad70d54b25ffdba2acb02713f76fda55a15826e740db2c01f2bc449b768ef4d9ba8eae9ba5b6d370e08d4b7db5e53756571bf959726e95235173cbadd82767c7c785a170411bcddef9b3a296d9efe19b59bb7a64480bc2335d53fa2974d9172bb89aa79fb089456816e3a44e94d8770fad5436c3e3c7bb73d2526add36d23361f1edd4bb2f9f0b04e4a9b49ab433c3d4e1a69a7c74923e9f43869a4201e278d04c4e3a4917e789c34928dc74923f9f03869a41a8f9346eae171d2483c3c4e1a4987c7492305ed386924a01d278df4b3e3a4916c3b4e1ac967c74923d5769c3452cf8e9346e2d971d2483b3b4e1a29c84923013969a41f278d6473d2483e4e1aa9e6a4917a9c34128f9346da71d2483a4e1a69af3629b8594395d6d43e78e20322dc5175a744a0def45d376af441cd918edc9d3aed24a60739b85cae170d2ae772b95ee87edff4b7df26c7c571735c1d8be2aca9fee5b0298de6ea583427e7e602dfb75793c2bbeea67dc2ef9e92cbe57add6e1a88aebae5bdeb6e22323d28721aba7f4177b71eccd0d0ed0635f0df75b76d50c8eba647ce77bb38b3832adc69e84e552050ffba77ee5dddfb77bb0ff5a62ddb7b83fa9d7692770db242782bdb36d1eb12774f82ae4116c9893dc2b24abb657549e87edd60fbae4b94d0dda6ee1eb2b242d08dae4176c8dd4970df2ba449ad121c0e88db6f10f86385aca9ee095995242d61d2e99caa6a2250ba75f3dafd2372dfcd6bf5cbd3136ce26087bb27d96a4eaba96e3ad7252fdb73817a4d5ad9d475d35f2e98a4b22c129749b77bbb3d3a02f5a66a9a4b5dbd89b8bb91119c49c71e4193a8aa161254d9a4ddb26f12ab44c46df7cb32d92d8b844dd2ee26954dbadddabda64836ce1ac4d9aeee0171d2570dfe72a0deb4d54097a75522ba7d9f8854f5d4b92992bd89b81b08f5de6eaebbb2aede48403c3b415917af9baab7dbeba62acee5e91c0ee8a647f6ab75a90a0c0e6977daa477d1cb26e1e9a1fdd349abd1cb2641d7204be465936c944de2ee45457000e2a66c87bf1facee665137edbddfd3a53da7bf5142b71b940a43ff057c0dfeecfb2e4fabbb47376fd53d1d90fd1d5cd3776575cfbe8feeb47d3fc89600a58753a10717771e9a0e6da7896848099252d212763c05bb2d6de7d8f67577683a341e9c9f0e6da7e9d7546d371212c8dd95b8d9e3dd7db7c157efdd2fb96b10d7c4b4f4bbe7061fdd6a4eaffb77ee5f37f87b74d5afa6ede3406da69f1d5a8da683c3635522771fe2ee42dce4e16528aa85a3a25c887a45b94745798ef230ca6788721a68707fb9cbdda5dc0510e5aea82817a26888728f8a128047bde0ee6e82bb97e0e68e2cee4ebaedd9a1e9e0ac4e6c9bebb9bab74388ff9eab8bdcdd77ece0be7f6cd25ed9244aec6e35daa86e79c025afab8fa46fba1aad90aa7a4d891041a940e0b95ddd3b52e2ad69fb2621e180eefee9f5d569e08f1572bbe936caea9a787a824070ed063ee91f938e5573adaa5ff6c53de91f101f4ffaa74bdd356ddfa78ddbaece01e1e909fa68f7d193fefd58a59526096ff7917bbb1d61d2b1ea101074038169fbbab79fab9d7c283153c3abdb6dcbeafe6557f77f973eba5fdd063eed77d3df3da5175ac2b52c6e09dd3d375dd3ddb71b55d3e090dbd2dc37fda56a8eae75737efb75a1dcfd87bb631f8eeea676bb1b69ef9688ce4d7fb79bbb6e26f6bddddce0abdfa4ad5bb5aa8750a377abaa3e5ad9d46d37932477074a01e885808227b850fa68ef1dce85d240d7d5aaaec9dbe3a5dba9090feb49bb41f78daa7f7b600c0f4c79e088d3760ec943e9d4adb4c50ab648c01604d82288d35c28b5d52e12214e1e6ad5ed46d2220a538b02985ac4a045cd69eeebee57ab4b8f4343770e6dd7e0efc7ea7ee774a95655f67d22ba62e2ca862b2077a7f1d6f4a77b5a7a1c9acd0bdc5af7effabaec2f874488939abdd36e52164bb24882c51858a0008b1ab070b190b982892b9c5c017305698595154eac10abe8a28a1adc69dbd53d5d1b04fedebbdd7b57fdbbf46f705a1cda6fbf29fbae290e6df75e77a3ebc6a1edd83fffb604d5ea5497eef6ba734b8f43abd97172636343a3d5fc4d0d8f93a5df395daaa64d9e36e46f4bafbbd1a5c7e1adbf63815a476372d3f65fbd73e8badd5f77464fdbb1bf84bb59faed37c5edbd5bdab1bfe4a2ff7b13d12dbb5b79e96e7713ebaa5ac7baedde3171b30a1b1d20a3036474c008a7b94e4b4b8f437b591609c9df96961ec79df6a6501a891027dfa6ade6edf6dde03fabbe7e26f774df76ab2c9bc3b929101ba0e0df00056b7cac1a48fb0487db3928fd73b3e90b379d70b8e924829b4e25b8e904e5a61301dc74d2805309dc6c9280bbdb663c87cc4608bacdc43940012d5b3c05ea1c257727c14d2d50dcbdc7972f5fb4e4b40c71f707f27f6bd957b79b70de34876ed43d2b41371a54754f44e85e973001717e2bceae6d72f719496e5261c493edfad080683a38e8aa5b2a8e72922224478c8c6054542413d94000dc9636c513ee7f7bd35f2ee87e56624eb181ac4d8d294516f7efed6fd99d7800d100a3894b9089dc4587c203505c91a2c85d0a9b28c800f25b44914514556ef33ebe46f6b7d7d5ea1a857a7377cbea3e85288ea2088a02e87fc8fe6f299c1005e9eeee9be6703f649fc3a1fb0dde8a2c19c28142cadd715c1c746f1727bcb9fb1137a18069c007775b5aceed968500349fa6675fadfe5a76d76e20dbb63b88a6fa686f22596068ae0b4c53a85daa027f7a3b2d2d017fc1dceb7f37ef6fd8a4a72d01d3977d9f7555fd6efaf69cdca5a5a517b209e185369107e143f8bd77b89afff1c0f4c5bd5b15b201a66f8d4ed53adc8fff77ab3939bf5b76e5a537af1b6c9796969ef650b9bfb101a66fcda37b85d4c581525bada6bfd47dfd6bb0c57957b6ddfdaa754baafeb5eecaa65a0df276fbebca02d3f7758e7df6fda5bd77b82515b804f5a64bdfa6bbc7e69e7d7f064cdf366d9afd92aa9776aa02df540dfe7eefdd9fef7803176948917ef5903789bb5f960950b7baa41758546bbaddd0cda4d343bc34f7a6ae6e899a007f6d91d1bb935c9749c71e71d3df8f15e2ea5220abb4429aa4d58da4badb6555d44865d92324214f1b855a3530c96d5997a7875e373dc2a4df2455bfac92ab5b22d7656af5afddaf6e02fcb5453d571725ad4bdc55ffda7d34c4dd6d242217a891ec9765b26bda4112dc8dbaef4e7281da09ea896d5d95dde913db1eb52c91bdc2de2d1157bf7a48cb127181ba557237943eda297173c12425ed060693dc1fab032e69370fdd4f3b897e3712571fb9ba35c8aeebe9be6beaea96e8d4af46f5bb91003512d7dd2971df55a3ebe69d282b84888bea5de4baee6e79ab11f0d716a92c7bd4737511d4d0465921aeeb426d23aefbb62c503b01c5dd9d38c18924276aecfb377fbbf95bbb774ec0dcdda909319ad8e27f637b4e7f836ba20977a3ff06d99feea989013cddfc4d6736b1a38916cdd5e8aadd149501b6c28a112f8595279a3ec225b012c49d96eed276373dceb422d252309978826dbf0913528664254ce0d84d13e0c29d862659da124386bb2f2180256ceebe832a0bd4bfdbadca167787da4cfbd5aa5fc0dd5537aba06e4b03ea5f4ecbbebaddebe655d1f91ba685e15c70907bc12cc700ae818209f700cee11198f5100130fcc726bdcb4b7dbb7d219d07f23d3708fcd70d8e10819ebb19811abdd11c95a007d1ddfe9afeba4409224c25aa9490622a01b451f5cbd6fc6f94d56df4d9f76f4bd8a6ca74b7a5e1fc744f393fdd53bb5fa046350e4a77bbb51bf7d33d991030c21f4addaf4ed1fdfba5bfb483edbbb4b4a638dcaa754b10b881000e045cb9ff2d09205c2ed7cb3d4188cbe57ae156ad0271b82468c07f579db6bae9f7ca0a5152552dc4dde99346f2ee4e77ec9346f2fb972a11d16c760eea05eef697748ff33b4b35bfa45b7a777d59957d74bb3ab79f7d5fd56953dabebaf475736c0b7c37758986ce219e6e77931e42439974699b63dd67d1674f57f7f6bb4379eb5673a9ebb24028f575b5dad3e97db3fbd19eb6d3a3ab661f6a33edd5897db5fe1b77ebd2cd63dfdfe9ab1fdd2d8b03b5995ebfbb9ebcb56d757476cea7d96c57ebf47edd35fda55d9085aa496f762ee969a8ba53281dca5b53a876074978daca3e30f8e85ef556d15543b5efbaee377df64ddf892d7a9a0b0cfe5e53f786c95dd3dd46939e66e3b639f6d9f75d4ddbb4b4e6a1806cfbae2acbea975dd75f53269d6edfdf4d9eb69464e97770922c3d94ba9bd257b781ee6eff06dde8aadddd7bd39ba58d5bd9259b2782c444bf1fac2c5ab3a65a05be1b44d5209005fece7dcbeeda0dfc5dfa4bfbc7262dbd9bdaec5abd555dcd43b5ba6581bfadf43428cdc4beabd7a5a4a5bf1129294982e3444913a51dbba4a3aafadfedee76afecbf4f7bfdedf4376eaa7feb56254f5b2a522a9284e8084e29091192224449b8244a8c94842c41524a4aa244080e8968489225c0e0ef589c7fdd547dd4757fdddbe9ddb9dfed589c8deaf67dfd9b49ff7e3779dacaa68f9444a7d7fd6efaf43477c7f2d0ad3ab12b13ce9ab23a1cfd3d5dd07d77bb2cb00d026fa05aedb6bb09d5bfeaedb23d9d9b6aa79ba7fd2d4be469401b9c95fdedaafba1daddb47f33a56acdbbe96fb7bf57f65dfdbc95559f75ffa6dd4ddb89edfd8dabb23af6655be0ebd21e50b7bc352de144f2afd1d37eed7e5f97aafaf75ab7eea0ba5bd3dfb94fdfd57fc35b5335f7d3bc6fd9ddcebd929224af94b4044950b7937e83a781f0ae5b4ddf35f83aefa6e886527fbffa5f56a5b93b7dda4f5b92e982edebaeac6e0945b5767a77d5fbe70665bd974db23a2981da46c2ed42ba067bafde68cbee76ee6b3615785e55774e012a4df7bc356dd99567949dc857e92fa96acab4f42dfb4b9b49bf4bdfeea6bdfe767aa19c81956d756beaa6b4dfb987d2bfd70dfa507d3eedc65bd3b5d54d6008c2e7ee4b2fab262db5b4aa26771ace9ae6a85af74d69f0c97ede9ab6389b690db2bb7f7645800d775f5ada6e50eb76ee6d35f0ddf4770e078829dc7fcfae0f830f5f00d93fbdbe8f1fe51426eeeea40c0257dcdd6d70e001512468b09a7b0a016a50ef36faaaaad19465d26e5545d23aed8463d1a08b03ba2dce4ddb5e10f843535ceaea58dc667a5dbde3a5ee13db02d120b06d6a7bfacdfd744e56cdaaa813db0a71db0d04eab6098b065b8dc4ee96007f43daedea56eb561fb94155b71ab5ba97e4ea561f6d26fdbaeb92d7d54492bc6e7aa4dd2fcb8497ba2c1a4cda3cfd4b777bd432d948ef12253fa322aad6a52dfbba69910b4c7bee9111f0a75f37a7877efb75a192ac70c75574c01d73c01d6ba16203ee780a29dc711459a070c71ac8e2eec113ea896d8fd4ad5bb5101e1a1cc11d62d160126f4d99f49bd4ee9dbbea5669659340ade7064229413db1edd1e8022fdcdd3b709387c72d14a0276400281cb7f0039050d4113ddc8207aadc1a80c5e3283657411cb09982a3c8400514032a3d1c858c2c403a3a2085a30670f403645605bbf003876dc90257f8050dae7ca25c55c101903dd5aa66d0054b49a97aae3001c2308cd185a70b271ecb10c6ef7c51400b0be0b4daf92fc203f8608b8e083c41f054045a392a34b9820b1073446b2196051b601785f3c36f0bae6241d18d151400e129646c09810b182d3889ab2310c6489ac24eacc00b08333f27780a28aed8043945e12eca08a3c6495518f8054ba67ce094c4962cd34491073b3c71957b4cb8d201952daa64140a00e4c00a2fbd7c030853361003a6284f11b4b4018d0f12e62861ca8c8707286ca2801619093e964212245d3d90889418e402d4e38623ab71a67485c711265c8d2ef0c2774cb11db3f014c4ddfdcb972f5fbe7cf9f2450431a0b9e000363ddf000f576ef8420557bec40e585cc1c1f73e44951cb8c0adc08b170003a8de20862a1e030d270c5d11aae24f1f00820b0644b1e46a0e5cb06082091dd7338cf1147cbd3741000e6601299c7892086ca1c3005ef8e0442290b3e3600a2d2e020c52e450c3011e789029058a1b2a50e53d4290907298529c16e3010315bf731b156e7861053a7b07365b7461920d7159ee87a55a1033df31032a1c100108513eb3020e4a3086891d478f0aa418d90003dc8613a24f1732cc380da90d723812250597a1018a0ee4c004041e738107c200b92a51303521e0220a1f550eab82420f8d2b2b882a7f475e8916047f09e1121546039a7017d01248407c114454ab480242d48ae845b19ee880210626253889842a8221acd8e0245e871855c0c8c7fdb213ba8809225e454083272e1c5c3481003718112587202109ce2f32e0b057c20034250058021251618d9880076ce0e54abe02044308b92180a85cc30c2ac0273257b2119676871119546598201e62285a1f5f2dc1c48d1460d1c1538a28b20495cc16cc020b0e38620c2e8e3013252ab0830f0f8f7b3e40a4050d25bae01a5306c059aa31e55eda011821638a28ef420789ee354017cf12e5f5600322a85c891d212c80e551e3414c91be3664a0e73898f0830a1890227f2187da04608cd0e2c123588e44b1c0114f711e8022628a2a578188232e0d5022ca97b87a48a50829e1475014406801d07d48d58c866aa506ff31c4ab0a9b1c56ffd133b4f08362f39d2b35e30b525dfce6014756cc9e90c26b3cd8e165032a1dce810c8e08511490f2df3d490143110f7c074d4f035c4063023ed3411122183d78e11ab0c08114040425e136726c20891c017ce033c4400008922a9084cbb08830c5608391c71cb1b1a3c444178f35c18227702c8139ccc9082c1713a07979a38c09e0ace003ee7a410a426a844006de6a010d2f6ae0217bebe581075270a206670185413355840b9c84a2022439d470021fad9881012b1690fae843cf50b0010c2e2a41a3430f3500e06290950482f880021e46210118e070457bd843414f081260f1d0a4c586e000099eafbc2d6ce1ea3c3f5d1106f602e719288ad2113b30c7654060c88b2a40388602cb0b02146c8e7d988d0181275870dcfa78b3b07085e32354c19c1a193806210b8f1e51d43886f1b0d8ada081fb0a78743042d9c1fdca004414718102b85ba000395da098b81f21c5164828d9e2fe030bedb2e3e63e00b3690491877b0b4bb42000040bee4fb00001168f70df0d099baac4dc4f00412eaf000c7724194ab062a689fb081bf438508014f7a11eb0e0e1018abb9015c01704d2dd8702443c21d8c25da72895420336f710701848415b86bb072fe0020211a1fb068e45a7c506dc7b3c7962863204e0ae4384251f371ddc732ce58431c60ef71b5138213384cbbdc60a4f963ce8e13e63370de94285bb1943111ee00106ee3057356ce10013b8c798d8948005e85e8e01f3438b07eeaf0bfcf80a50717735a0870d2114e1de4202ca13113cc09d35c5da43141770676514680328813b694405af608cfb382596450dd97dac71c5163086dcc5a90248b9a2ca5dcc81e5e70729dc432462ad1b43b8874a6ea84610847b8e41f9820d38eeb90146d0288012ee7907c24672c33d7fb084950050b9631524801625bbe3268004e084803bbe410649b8b0dc31efc807af07773c94450a1955dcb10c0637f80871c72294246c34e1ee25c038701ab87b076c57a0c0c1ddad64414544c9dd8910a2013688ee4eb57f1420c1dda5c090c99273f715c61003034feebe02408302b8dc5d27c210377cee5e428d009030e2ee4738605737b87b911640e590ba7b900458f1040adcfd661260aae7ee359b265b9eb83bcd0315d035e1ee20e0d059a20177ef408b0f50a2dc5de6c557c509eece434a91cfe6ee343ed7cb0577c7513543101bdcfd468f1c804cb83b8d2eb01051e3ee325bc010c606dcdd746d710030dc1da6f7ab71ba3b6c05ac06a870f7b28a003ea6bbbf9e8891c3cadd5db9199a30dcbdf50b410b65b83b8b0051298880bb9353a84033b83ba963890b22ee3eb2b0440520771753102c42e3eee24a7365c8dd43196cc04ae8ee610e371f3e70f7d04633d2c1ddf3173c3c608abb671ea2806881bb67a5928b6de7d5691698c485da465234a8579eab75ab812bfb4b774ee756ddf268dca0c4c111ee9e6f10e2ee7e830f2003001001053851010e77c7103822e7312b4368e0ee610940a4065c51e34b0bdc3d9c9200228e683091e5c7ddb108043841c9d40c3f5871774c83097ad8b4a38f06b83bb64018a58a11ac58a1e7ee59860d6a2020041d401185bb872e40810a491881811e50e0eed909151db0c2d1c51538b87bb68209408906891218b9bbf8e30724013ce41b24dc3d1f21124104347c40030cdc3db471839614f04065a503ee4e1aa0005eb015b73282b87be6e2021ca090c143087edc5d3cc012ab875e14be2edc1d5df7eb6e271bb60cb9b720e5516c1882515073c729c05b602bb8890154895bcce0ee466e0ea0a65ba15c4c440419cc1aa09451032c9402e4815a8773daeb7801ece3ee98080d1ce8ecd0767074bb4955f50f13e12138c61d014004b9bb0fee329cee0e030c2d90d73d15c1f7bfae56ff8578be03dd9abaaff33f64bf6ed56706284d58468c1f2f70246cdcdd013320867af0a91bdc8f9c8908ae434a03df6a2e97ae3f3c341d9c1c8ab3d3f6cd0dd96fda3aa17ab7355b500627779e26dcede6e280ae0c1bc8604306d1e66f7ff3b8dd6e6b9a2839b142802e5050b799b829f07453a0e6ad2af097c6e02ae2ae731306d7711b65d7b47d812e30edb9edcefd36928db22b6ea7ed2ba506b64d9b562255efa4f648b7fb76bbdd744be4e3e3e3e3e3e353abd56ab55aad56abf5f4f4f4f4f4f4f4f4f4f0f0f0f0f0f0f0f0f0f0ecececececececececece8f0e8f0e8f0e8f0e8f0e8f0e8f0e8f0e8f0e8f00405050505050505050501010101010101010101fdfcfcfcfcfcfcfcfcfcd86c369bcd66b3d96c3e3e3e3e3e3e3e3e3e3eb55aad56abd56ab55a4f4f4f4f4f4f4f4f4f0f0f4fa5f3a8b46db0c6a11ee598526806600400000000d3130030381c140b86c3f1805898d46ced14000787b06a7a441708b32cc861ca18c3003100000000000000603411003bb009f881cdf5c9f9cc01e584428b6dc4a868b92c785e5d0b7d03c9d36afe363b0ef41b93f7f97d7edc28ce6504cea222ea5587a4d67d098d44ba0467a98507382852b74bd386dde2fec3f01470cb9e5b0e2e3fbb6a095fb5563c0042915d82fc1c3da803f77bccc5f9974431dda69e11728d024af61e7ee079076fd04b3b3dee4248ac20bd350a49710f6170807f3e24d626c3642deebfb3bde19a84027fba0335001ee14e046adc8b15bba3ec419df51de8f72ed3f10024fb0d432bfdde748bcbbf3f07cf79588b7d1b0ef06a9d7fbeffa6c2bac88f6fedc5a2bb5baa3b865393a34e6f00d8737a033714a5a3360c4a2c8642b792e3eac76c167070df9e4159af1a40918db014f52ce10c72f67d14a7c4ab734b2719e81efbfa7f467627b37e68322122e291011ff6e4168e0de9f42d2b8ac566287778c2ed2230e7de863e628a559f7aae7eea2348c4219cd34bbe917aeb44cab8798b4d60792828b32eb88a0d88c6fa9a83d9c4db972dbd1d8a32589b0c43b5b4b47a26145e3a07223f2bbf7afdd5744c1b6f686f7f80784c86c478757c49c6fb74b364ea3a9fae43853ae2b7ac0309e40d42d093c6a806c6aaa2d1bbfdcbd238333f89049844e56cc150aa8d275f3fe87e8be50a38b5dc76ff62019d1291e0bec06dfcd7d0d04b54d573db14e44aad3d4f4b66acde7731229e486edd830114a20a80cd485fd8ee73e3bc5f3a4272838be327120a4c5fa8a520defa11918dcb2a49d92c22c8d2f36febf1e100a9db2e05332b88494a7410a7c0520c769ff2bfb9b144a662015c0d5912c4d074169e54a0e1b48483c8b00e958f1154a35a5729cce94568c1a23c0099d468de0052208944d5b75ebc8b7a58a4d342b0b680a5564b4a2c6e52843a1f684f51cb0a3d0a423f9b7c8e5424528a8b53484ab1eb66f9010afc9171915cc30c9d4c03859839620383f6e08d10390ff7c41f20003e3e5003f53916f3cc91bab34d3826855fb566039e049a1e97c1e0d7c513f511b4ec70b4d62134252c322dc24d7ff95f7b561232eb7afcbc6557306afe61e3962f4ce8be12ccc1b04f32d219813c867153e7031ff94453436fa0f3442240d3a7081da26f0ff64923c04fb9fb310a5809a3ee15b7d163a67fc48a2c28a4080109cca3cb3f320a2dce019458ddaff6c2f0acd0b90440481133ace034c219a01ed1ccce00d9cebd3865b8e7a0dc1218dd3ec703781d6a61ea6466695045d0cc245e07863211c8d15b0161de1ee0b23f2e85f14bbc8e03e8a659cd22b71aced200861d723173315636712240ce1941bfe07bff0af7475ac6530f004edc98ee932fc57bc06d74f337c4d38ffd6e27c809401323f2e72026e779c4d265b6aae7f30afebe1facf0d5be5e8975316428e273e504e457f6ed82900fb840924ecb126d47fba8b2d7a28897e3b9ab94fe93b8da704602c9d74525cae2bf0b470894cbc0b7638bb198ce8767354aad04a790bb1e450de7a723eb5dc40c71a61c9e80d11b98e99726283d4a73dfcee2a88fe084c3363a02662c16c00d32cd9ae7b07747a4a835b2243eda76b8741c803e7b8606ca4ca6c160911d949e501dfdffdb5462e354576a5230aef66cc3e6ac50ffbff1699cebc5c44e01c5343cd82965835e3850f9a43628902c58c5c0c9aad5c52726f23f965ca39deac0d17b518d578c056a3383491d6992434d011e22e94e27b78a4f668a9f54c5443a98c32855b20c330f2a2251cf1c422ce4404414c0bfb8964f3771d3a8ba5910937b692fbe1071d1ff180df23eaddfbb97e1af4d35859f06826ee10c54aa7144c70a8a4c06b45e5bb5d2b2ad654db163e3b058cb80afc9b8636d17f6dd059f8b708331ecc17cdc3d8f42604571c5a04c724e6f27490f214ddca0970c9b0aa6d31005decd17f8adfcfc8171fef8e5cca92a916404d68c458d1742a5d28ae6b28adb852612a83d8814e94adbb9dbf8fe896390401468c6bc5fd375e474c075271f8ce6f023be3213a0de1011f8bb141b27dfa9c218be24b653ea13fb575b86a94568ce14d2dd2ba4c4bd3ecc25188b93b714c12db924becca202ce648773752a9c7305159cd208c85c86f7985d2d63707d9de4978c1d7aac38cb8340e28400d1d4004d5aeaa7e884a8db2e2360090e8d036810bd9abbaef47d1ea5c24ec2859b41b0e100a642362c3e0361f847c15bda016ba91eb6b172c0a372194ebe752410bb8a4f20327336312791a57df001edc452ffbdb99ad55abbb794f00ea8a60bff38181a5d54668ca2a9f3e243c2b385f30512b2fd7b0aca8d4a3ce787d802f827458450e7906d370896ee11ae4dc86c64d670306f0976224dbadb3435621e1f53930eb1beba4b2df6da8b0b236c3d696ee74577f22fb07b14d0f0dfd72b510c20ea62dfcf04cbe8b5d5dd740cd54fbe5d0024c0f4f8a82434fc26345e13050e20d431ff791941d1fe96583750e1c1c856920418c8e476e3d21dcb134449de9b3c3843a91be24b4567b352da5da9829b16f6479ac0b51312479bce5a735da236b51223bdc50740e9390c862537c000a4b3e43daa09ee8931a0158ca747b6b370da3b2ab0e4f1d0808f56953ee33464485e923adef02347e910a3620d808a4160fdd30ee35df6a04c53d460db975133dcc64155906a1b0ab139a79f15959fb97f8202de9deba1f32c59b64d9eddf84805f168127631044b23be11b6beef4e131793d53bf4f8fc395bdf5950b77254c37a370aed8eb01f29afda0d53fc2df8f5ffacfb901a516ce2733139fb9119d8854eba549c301439b2fcd1c1aeff2f612c07e77dc481010737840c2a603ac01d025d90764fb8d65bca64353434f7791f5ad8d055037a8386323a1427fe0554ae7118316fc158b73afb8402d5d2d136b4eccb1c2112016e55f810c6ec37b3849ad3f89370ce929bd535a57d03a2e5932562235f99e8f1de4afb23f5d25ec612969c50d3b366acaee7429b24bbade6d92bd8368af90db9495cbe13c2293f558bce95042ec047d7252bfa1cc47078be86b68439228b87c247386f8584b0c24ea756a9993b8fc8eb9a9b51179e723c996d9a5f85e6da008fc1cca0d8eb6381f3c2cd8bb30411b4da07efae024f9c5ddc87e94f509f6064475cf6509bad91d4379f8ed99836da4057ecf8f16f659132fd5f145e017cd4fab094b30272f200d48d02071c15c69716ea3168a2f9b333bfa854a522a68e277678c6897c402b4c1ed23a19c97702cedb55e5c92d4eeafe6358eccd4035c81458e87de100b9495a33a020dbf18bf944d4f0f10dc3d77bbd81ccb1cb6df26fac0a20107e4a886b348369e30d555a8852cd1870ed0319fd66beea5501d84d30c2221194181b8c18226d164d205138d70a35fbf55cc2728510906f83b5f72c1d6387c927e754754053a2c506bf62e572398df2a43bc7999728badae3c461b69b2508d95d285709132d1904e8a2ad83ccffc2d1253e2e69f13b6136b240dc55f3ed5c5377862a4070dca253fb1901cca9e4693817ba5aa3914d149f6d9ba662bec68fdb7b928d13b5c80ea573aad31e3674320d829c000bacae1230b1073d7a6134de672742732099ddbd26336ce10cc69487c5974d96c98d4522923260a4640415a58e39a9030d8e407ad15bc0a68f4b1428428beeb2b8f9c2e18e1d4ecd8e0ddf24ce3999e254a304f88154ba028175448523014793a67a9a7245f42e6b8cdb1d32481d9f172e9d73e21425caffa0db4dd18c4934617e9d795248f8ce4ebd560b6e95fb79ed39a964c0cfa35ed1b717e810c1dd206da5b8492c5b976b22e8732644c36b0c66ab684da48346f2e2ee83d29182bc3019c06be10cb9078718ca738a9d24b85be1d1abc36bc45f24743e0cbd8fa48c4988202216f9bd06af4714e1e79021895f8d509c4d47758a30404d30c2f2bddb63f8c82255cc9470d17f0eef0029400e003bbac196a6e3991918e658465b2333f918a9bb0a0a14491b96a802f077ca16d3092e84fd1fc4ccf433d20feb005ab12bfa8dfeb113531da026eceaec80420af96cb0b876e6206289a336a9c8fb37d63861aef7bc08586bd8ee48e4ba187bc74cf6c5aff28d182054259d09f017fb28dc6481e83fdd871591b5c67e3470381870348ef4f596774701eebfaad2442ff5b6a9f871a5b5838b4c003ad9992142808b6b251356ece725481fe642024360027043c21241ee05dc44d64442c85391bbb2f1819869eba06ba6466e466ae689bdcc560a4807f34fc1f62ffda5bc5a5f299b33ecd600b06d9fba785b37a73b9a82da1e00d27b976c9c6b878c43189a20604fa9529af5363e2110fcf03097661d3bf7d9d0ff47ab190188767187160643fd7eea63bcbac8bf1c1e60a819a5089a98294752cf4e01121103f51415d0e93ca360c055cfff2a3e248f45dacb3a91641e923f0337d4c2a0d4c034b635336ef0add826f161af8ee20b437d55feb063df4e89d828dab8c90053d3645725903dca86019517a992c1f57d9f1cc5237adac4ad9a2cb99d8625d5ab1b94fd85429ce494268227f92f111e6f3264aae486a6befb2c90f696baea55d42456a17a92b486293519929f66a4f825d8e0e420a5afcd336932826c0443357090984cdca7f11c56a207ec5e16b6e75711eb3f1d8cb8ee738fe77b23c193c5d97abfc59d0500657a8a8ba648dc96af3586e2144977dec32fd4e3fb98f4d8860f9221b5d7a1fb31513ba208fc75658f4151411cce58b2411c8de49bb9eb1085c9e86fdbd8fcfe3d73ca7139447671a6389567c51ad600bef826e8ebc1caaaedd69dd11e8abd97c6d2dac5cc177c53df8923c76271160d5be18755db41b9c0d4e90cc3ed40aaf7abf92407d73c5c1babea6efbf1a37e84746f1d787503308bd3af9b2cec96d4587d65f0f5e44fbaf5dcf612673c103f14e5bfa90d8f4967510c1dac67e9c8725acc94030c07261968b31585c6e46a451a484c4be6b8063648e396fe4105022c8f88ca6269b49b473524bc2f465f5bc8f2acac57e3c6b27ba6693a4e8b3ec28aa20119ed7883cd81a36b271c0bccdd99f7d37a0e2f4b6dcbbe261bd4727b592ac268085d1760154db473335430f5c552d03b6c6ccee0da6fd37e59269396b60df7fb54fc3fe17bb0287eff84ff0d532d52c6f93f703edb7ca192d40f2ec2826633db1ce95e62655f9a33d93980a3066f05492997d8dc127604ceea03d8b659a9ec48148d707da7be2b2a9daae37fd48d9e223a3f9600d31793c97f2288aaeae17248431368f460aa1ea0eb3fc16935d430aa02b20bd2fb54b67de60dff556550d1b062b00a1a3933e4e8183bdd0e9b5f9862651185bb7eddc63e804301432da5e8bbdc3e7ee8dbf4c32d1cac8707c839272be7c22535fe4cceca1469b0daf46db23dce6532dd14a45e4e21e1f90f55175d89f37275c3aa904425bc3b6337fa3dfedd63df8b67c8e0350ac847f081382b75f09ef812d08119dcc6549b5ed6a919546f781fd5f05b96e78c1a4296b82105e430cbc23260727788eaa22bf7ffc16ae5d1c51a065f1556963e52088627ae05c7be19c5056eedf1d30a101649cc929ff0675210e75d1b6e1c31e68d9d42071d5125ee6cf7938d53fb1e716428416f189d1c3357beb9fd55616383d2ab09338b2e53c421c22d4176ba9796afb1a6615f2411944908e6528d9c5be19369eeadd0730a9211ab55bb7992835126a6ee3f840b57fea32114a81d151388a410d808a67cc90732bdcdb1c1baadfd03ea6df4f2760afc0fb6e3c79fb1fd0ef3ff3c27db98d8fb46713d7c49d7b56339be68ca8918b2063f9fd31a9986afae62bc4a130d1a5b9a6f103f3bf1f3e2fc932084be3e760729c37be4c0b1bcb9f0c5f440618a5edf00b83e6f2536865e56589e3a46d89be3c0f17054287bd70c20ac9be2dcdf53ba15fac1d476ac2440a6cec0b8e9fe7779bd0f809949f19e3c9b70794f9b9f910395278fc8bff0570b32395464d849f983f1df6319ae2b6ac70cf9111ed8694f3266f7759c323b53713af4181e7eca9e294ee5025c7f60693733513cd8c00db3a55877c8f6b4e9ad37cc1043446a4cbef4aab596ef105972d5f1f1ba9ef8e085cc9d158ecc7c6f0ab7d1781b8d277998edc8c73bbddd1c36359abfa679e205d6a0a026c8c79419655d8c668f600c651a30f58ec18825f3f3a1819ec409ea80bb5afeb701e2e4215d537efdbb2f2a11ca6b575db33f8e51351f3421ee85e76ab88d5174d3c7e7a862f23ab916b9d91cab30315d0813fd45fd95fca9b6c4161d49a9fe16e96b01ec7772aeb69638e8116d4d45a4baaec1de94a723bd6bbe075f38d80958b3ee50bde9be96c2c2b1bb62775aca64011ecb00e5589804e114850f606dbb4e29474e7f9a3a839ba9987929a0301d2afd995f053077842d64fcbf40ed0649adf7756c9e9651a7d6e294b756c163270f208322074ca25617aa8268b9da27a3f285b2be42cd639a4102d4e16f85f7cf49b43074f2a5255c1177a4ab7178066442b1bb4b07a4088544e2aaf880a1ec9891864f05f7d90f48e1f349b11f3af073969d75641576399dec0a647b956ca4da28a6539de15cb79e8bd61ba564ba23ccf56ab958ad514ea73b43f2b404c4d452d23f4e49a1ba97efd573d17aa3944c7705f39d5a365e694ba9545728d7a9e7e3d5562199ea0866ba956cbcd62ca792dda16cbf928bd61b652ad515caf52af978bd594a24bb02d94e3513adb78ae954673857d785ee327acb53dcc8b32daeb673d9c8c716edda796b84558b8edaeba68d04a253f5e9daa9c07aa257db4e05d613bdda7622584bf5ea5aa9807aba5fdb4a04d612dd9a6622b09eead6b792c1b564bfa6950caea4bdba562aa896e8d7b793419564afa659620aa0344bd424e4ff819da366433463a1e5f290ad38227857cf0a5234b6c2e9878ee23c86af97a177c1119eeb581b51d323a528f72945e916370df9b7d70618eb8655a2d2c0e52df33d57926f61fe56d9c377f8fc2c474c28b1d022974a6d717e20a5c7d67c78b7087cbd47b746e404717381d826d744d84eca09c95932096eb5f59bd75dcf5fc59d9de7ea159e40b68ac2788c0c69748ebec261369a5ab55babcc287bd79a404a5a54812347269492276e7f434497dcb5a654b4e113edaaa564b9441fae503d8a8c13ec8130ce77939f153ef8f947daab051dba9e172aeeed1046c30dd02bbc257a87124b4a359a7c9c02ff60396e3e1ab1c4cf20ef51c8ecc1349cc151144b6aeceaedb6799cb28379aae9ee4eae524026ec7e1e52dbf45300103be6b84b1836872834312aa24afe45e8a4c06301070700709089deaedc00d4461cfa490b9f624e84d2c05b94dede8af0b596b6e2dab444ebb635e905636d70a1d7ac9a44dc558d54bd40a1804129f98f1a2230ebd9044a1ecfe1ef85ffe45549b0575ea3ea3b9bd2f3b9ba55cfe4ebaa49bee2b2dc5b9403097530eedb24aacb59824bd4498b7c661300a7ea6a335051da4b0654d8f9c8b9a05988b9e1fa463ec1193da13da1e928e4a617aa70e9847eaa82956243a56039412c4cfc0bbef6604f8b02f148b8e439e627793ccea5f6933d1fbd935ddd09abe1aa82e6ed9344e21ac5cb7ed385b1593746cd68857e710f52b1529e880ca8788cf3a289a5dcfaade3b0d31bebc512229cea5d078481573dd9e1debed283b0c89f4c30f8e7421c80e89d2acf8bc89b849ff36f2a9bfb994489f1f167d0d800841ea4e06a947485b56fb6e01f58a5d4da049bd5eb7d898dab8757a8c4096e8714a582603f96b6cc73fb2d6042b088cb30ee98b1911363c44961493e273db6ca7b88956fa42972709c77d0ddc0876808bf06ba6b99fedbd34d9a799b71053fd78682727488af049f975e240f65510745d63fe2f7f23793cd7ed292733f945f7e9596b22c825363b1b47b3260bd0280d54d76c0bd90387e842043b73ecde1d1c107c0cb3733717841ebde0b87b18cb6a26164474343b4871aee50d34da36ba84c80a9e0f6e6c14f8bb7d20d9015677f98a0199e218083aaa90ca1fae40dd36115b54c15ed6deb1eb280549a58b0bf55289613064882a982a493ce8b6e77424af73039de9dcc15d8ae5b030fb5a0cde110fb4dc39fd26b6edc2733248be7c3583398c1f2148ba58840af06c51f3d90aa6f9c34c400a3060384e28b90e215a5ff287125ad803d1b3b0bb4ea30d3202f4dbdbbf501303f53d16d45703d06cfcf680d1b3b79e6ea1570d08e623146517bbf15bf16378986bb32f1d729f3e7062920965472675f2a5543879d3d95d6b395fade2598ff66423d7d4f16052535bd2b302d01040ef36da10b02dee9409372944ddfd10f486731f6718900748d8cece73156846c614ecb71a772f9d6f5b36947caccbc433aec66a3e997d56a5e5050a074dd69046073efe83280f363db98cbaab0199be0c741a620be46df1fc56192ce04662aa6008dc280933fc8bec74591ca57df01f00ec4b7c4bf8bf61bd5c582a5f36f3e0fb331092377faf1ceebf2de00449f44c64312f219479d2332376a8a6f0b45a0d183a9a1ffad34c4d132b0f0f6793cdab694a36ca8fa9aa5828c53375d1f0195ecb2c213e6a8ed97c494dcd5174f88969cec7ea3fe70f1630d87e86353e1595326413178fb9233f2bd5f9d70b9b5a213efeaeb68308d3c75ec5a40de13ddb43f15b166eaf560f6f36b6b705572c4be615f075efc2ceffbaf8de4ad92992fb9e8c3c1f79e4aeac1e6caa22c9badc9670117e059e6360b80887be63a2723fac0d22fe83d94541a753ee17331e3fbbf1ce24b0d22d409c888c933ba00e2e4f4b099115785289bf06d39d593ebd27cac1466b9382c83e8815ebcc33a646b600c995de658856893fd9777d56b06c025db7ab3c090956422213d6b6d4cf513990e7eae89821089c890ec0c2880441d4d187f62caff93d505c496c4376b6e9473623d19c74d27cc7ed20f4966b7917fe4e6e55819c1ad2e2591367fb6bcf4339a791103cfae2c922b7ae72b7755e52365c12c5df19f92866c87933baa197da2204a392efc8b9e90b1dfa72520ab6924401fb185792676180f5116415b861ee4d19dc4f7a04513e79bbaddb6e28cda1044a5dec14d856e661e2cfb056fe2c4c3ae73b1b68ecd30e8af80dd425390f80748c5150b15d51c91d45f4a006a00c7c3df4bc2b4267fa208a20455c8c9979a1a9cae890435cd429dc72732776ede3fce299c27fa31078a8292c275ca5ffddb49e2837d1b2b6d395ee06cd453cf214c3a93af855b82fc88c28f8f7edc2dbab4b18d68f52067879b69281a64b24e4e25227cd2f40a31542ab770a86c9abc2c275b00d1af956e02f53e4cc647d1597e23d3c98ec89994c12662bb9d1d028c1a570ea42b6ff1f73d50f74ee1a2b0cf83974f52c7573d3ad15a34415b4b378e0193a0a5336fe86e8acc3839175a2659675e0e9769f47fc93fa399e40a2e7e7489f36f0a200f165ca90bae606cf9487f4343f21ad70c05a0f901cc861ac935b69a6a43b9b3ac2872c19dbd2c9996731cbbb8ad82ee82a47e14139b6f3f04f27af9be9c21d9a9a31ffa742c60ddcd9fdd3725e779fc9756a25ac18a0141fccaaeef2a04cfc05ef76886fc5523fdc9cc8a0213ac12dc17c37e2a09626eb5b24442adb3790843f9aaa4d23ae24bc1e310434c776689c2b0bf9a82e46f5ebedb2c8845209ccc7727ea4cc84de6ea630069860db0f983c02435971587fc8151ceb9b82a91604228b0ccad02ff23d3920dec8d1494858dbd635528b0ec5e98ec9dd3071ad5c5a80c1d7ba28d8d6c7cbafba1cc93d59586d19ecd6c141bdabaf9c2ea3853264416379de653d05d42df906e9677aa618d10d3bcad1f740b3ecd34f3c042fb494766832008e69bf18ad5aa27bf4427ce99595d62eaaabed829cb26b4933ab7f716be6e60c5e13251303faa01ccc18b3496d631055d98530a172991c3befd5c6a2d9606d5d2636d1a70e6549511dcb703f12f486151de2f8377cb41233bf07199aa3e4381ca1764f76bdb50fd0c8359d72ab19c94856e88907ebb98665850b9d0c85ae6636a2c2b3907e45c41222810d47782d69dd9013dc52214e461ef6ff0cab0abeca3a7cd64a99934ecb33140deb87e45d63e15121b4e42554b80a43375361060b92ebdeb2596abe5b4561c065c7cbba891f9f48e243e883b1691bd1eed8ad621657f25aa74b3cd9750cd09424bf148a8753ac6c94771c19b5101c834f36737c3d1d461d54c0e413097ed16501c4cb021c80585ff394bd39599e640b4193c4ca25f05365e6ece0246e25fe83751fe876816e57c4316b2e88026826b4c0da5f6b6a77e69e629d515ef029341bf69fe57bff65bd6f64a6fbe1a134a33c8ccb9f0a526d44520ce2316738e7f2206daaf27b01c71dd08015b0a9991c6b5cebb6b4ec53b9235acead35c1c82248c6a84ccbc62d021a84decad265e52da5c3aafa6fb1bf69da8622a254ef2e595bb47930fb8be3df0bff9f8e12181671fa8ff40559c119219ecd4de25706c60b4880d7092c3444da6cb10b83a2b0490d13c37881deaee23d8d7ca27b1a639d627e19b7cbc34ad26699e5f62c31501a64eba4fbcb41d5105da929a137a767f90c2d808d8bd7e83784caff6411b952e562c91cad256a905b5358fa7782fe28035094b5857d6ec6c539274fe6e525057b81a2585e7e3ef505ac90c7924da81b3515f5e2633b9d6968161daa225a45f74429722767797d9a5121af3f3c4f780cb49918ce690ce0b5adb17e5905e4ca09fe81378fdc8d349d35320dca366a8a3531fbccd6af4033241e5065fa60b845231f4dfabeb1d02bf153cf64fe9861274ce133141e9aef0742e6b692e6b3287be47ff18d45ec91aae5e78a8cac169560ccc4242c764122aec98575efe2621ffc341cf681c9d74fa6880fae782776a7e97ad2718e9ae0631c4768cff17b19eaed9eea522f25eee719b9b00cd5102808b61e509cd3c24b303395cf4f77b37ba56eb334db2de23d503bc75cc40082023f1941cd894ba08d9294fa99ad9d077a431c9e3d4dab310e9abd865d741276d364376e34cddcb8ffd60f4cd07167f28ed996d053892cecf1ceb8b6ad48c0cb8f5dd271bf1d79b91437b1cfe816cc16c45051545100b54a68d34d21fc4ff829dade58b4dbab336eb5c878b01ff86cf1d3bc60a1f2a57944405cc65070341ec1521c9337357b1100f7b53e4880bcbe1c2f11ddada23e1302ad6b899db03bb32291766274fcdac9be96e9302351e84bba7805541e5d93231f47d7459c25ed670aaef4bc4bf00040fbc77f432f8cfde28ada07a0092fd6b16753bacbb05f97f8ef6728cd2048bf4b865e7466eb8311fb6fb6f0f32e761b6ad6a5697c0e21fefc1dd0e353b0beb69e72fe336f6403b2293c7f274512357dfae6d3971472b80683ea439b943b8d1fd45969b83f35a2f7f6fec92a23c7ba58123b13182919110a88839115bc990ea5201dd9ff48e8abdf67bcb4757e8385383c8840adf2bef866a9a3729bf92b247385fc83d150dcf1c8f3d230388dc57c3e87f6f67b5652046df4175bfabc59a6d992ada91820d1a9dc0404faa365304a62fad00c7067bd9c75741a9f22544fa1fbeec6fc23f40c2e11bcb3d16f4114f64930d3680ea15d80259284d22fdf6b35d5f83347264176742e31248e3af5c1dee1b48b8b218a7cda2124e486ea2a6c594cc1ca6ea5d0a0f1fb0ffcd0cd6869695e8c112e3c818f202a0283aae71299fd81d5e61deb5de3bcb470ed0a65d099f3e083c0b6e6ded5689a6ff0e0445b3667db15c8e62b896a177e6e915fe065205702dd20b6216ae203c75ae88df41f5b9f5b0e0fd25fb11da7c6b1f74d0a566dfd76e1e1ff0e0370e32c43e97e47580fb2b8fbd7ed941635fd70decf276ad74518ae4f2136d7d5b7d1db95fbb106ae4ffa174a2987b0a423de4391332f362f738b5180c8fff79ab133990e07f3346227049f7127b8db22ae831f8685275f6cb2b13d5ea629496a2f4eb865db29227eba31f25802776ec18a8709da680baa502d9438286dfb48be22a037ad6edbd80c902fec198ad91d9fd43b299320ea39b6c82646425fc74e302eebebeb2388ed88d22bd7df960ee9b311c0effae65780c168c8e8221eb4826c30777e9b4300faedfe86dbccbeae3fb839d36ce538b465c5ca4c0b43700a04951cd9f4b931e699ba349c61f1527187a43af52b0a79f3e745b172d7edc51ac54479a961ddf91656be5f7612c4207421ea70a678d7726deeb2e42e4836d6960358480edfe554862027d5faa19ee8041efb89094258f031b741d825540e12a40d1a4ef30fa6a41a18e633e0f55dd01f6e5aa5430c40a73ff3578382841e276cc68abb371aad8eedfea425d5652de42e72251d1374124b9a48480e6d8b136b267a46389e0d4adaa1d086b71e6f23c7632d770b7a6e0f4f8f2f7e053b084df03944f4f581a9c8433877ec2551742eb740f059f0d5011db31dadd675d3330db1fe5a9cb94bc461c35f9c0a8aeee811f7c4b51473f028030a91e6fb0e2ce0a0ffae393b2679bfd6c5a45103f936c744ae8591df524bfc41eeae01857ca55bafc087966849e5e8b9759a3dfcd70bb9b0b413c743572c3b105f2b997a003275966c9a8df8248687f193c67a4dfa55789cae11da6bbd76ec71511e0b0278075d7ed11d9ddfbeecfc04b14bbfd0183a4a9642a2e7e1ee362e57ee6fac3a4618f08364200a511fdc46a3c2ab56f1673fec009ae2e4873cee80155f3f93b8f9a4bf20d2552bc602c1161d34a07ed9fe56429e906da20c5fc64486d38342e64d8da93d4ea337347e32afa2b4a24400772ae453fa2588c917c4f3bbe50d4d46aeea4a553c1a574f6d6b4fd21333e9b90ff482e3641b8d43ae274f0f54d94db59eba4aca07c7404920bdc79d6c6e724a3d891ae9f61605ee91ed4b2ef35a6c16ca7e18b089d35708439c9b1c9ef5493e8b9fc74eed47e80fca078b191b1967f14434fa29e8aa52ac5859ef3332e2aeee4599da63a63e76da6abfb1f2854edf94be556d24816c58b64769ce037959a5a32761de1c8eb6b991f7b0bdc4cb8dffd289691cb80fc41daffe79b41f80c482d1af7bf0ac4634720e9fa1cb8cc0873922c30d8be3f62dcde5b12e945b5447f47230ae2dcba2cca5e0aef617b9e22516079f58465910a976402bb0cac7a15a34f88360a8d4ecfead96dffb62bd959f963af91cb5b0fc2d5056f31fbc3eab05f6ba79f60f7bac1cb5fd795d77730d6af9712f57a6416dd5d16ec4630b05b8f93676193f930e7178244305f13d81a6220c7a0a750f7f4d0794c97a05fc9c758077ac7e4719f1abebde85a8e49fc0ae954bdf4fdae88a3bb8f0393ed2f5ad88f2971051896dcade57edd480133ea98fc4bbadc6ba27426889b33029f6a026398e635753c32649c429e7b90d53d603b4fac5f8fd86d2bffee25b5f8f377004c3107b5777f730fc7c7aadb94f8628a56e60e3f78d1861ad3b6c5366ab2907e6d1e99f741f45432b70d06473bdcf73236c915b4fcb81ba5123f27547d0d29cf78e886fd13b831818bf5cd99778b58ac2cf0dcdfd86e5244a618685cfeeb7bf6ec66f0e81228b82fa45ec441be46c25b66f212122720395860dc85ffd43d389d97589a55a4d1929bad9b7cbab1e030e4c57479d0c3fdd9646ee93a9722342d13e42f9f7a47d19b384b79676c4f8b07bee8bbb2bfaf3cd1cbc33be0af0fca39fd287f9bfc394ee47f61a1afe2f3f8332a6b5cb31c9b1b6efbb36b38d1929a7eec70fe48ddc17cedc2cace3eba3f44560509e5e47d63b1d9d100f7ff3663235447233f981e3bf5db346b6bf666ce5e0608f51ec7875cd9808499eb388c2a913c010df79d6455308c7c6a19af5e0f54d766ccfecebdcac54efb4748f335a41226656591ddd51eab63b18ed0c4e9586c046bdce91110c574053a4cb039cfff55dc2dd1fedf9598dabdc5e8dc92efa72f7aaab93860547727948372d17ed389e3cc893934f528d00a4567533f7541bde75d51374f1de6c878e86ac06631802a5b2ae1a58e2e1bd5468f922cf63638a1921b1f54f4bf01a15ad27948a91233f76231eb1a7b811751536c0680dbd0fc6ee61924648d0b2bc5b704a1376242111ee4973c57af61ca5eba0479a11263164673af979394662542d11fa6e3a62153b90851988cae16bd57cfa13ddf1a0fbd03b033c3c698e71615704ed7e233450a4e48ce4b386d965312512f54238a5c5264230bd0a9cdca0a864bd3d3bf4637dbf34dc29e53ba58e630c7f5a641cf003d6c0c85f78eb84b01de0b3225eec450698cb3d24eb5276853fe87d069fc2270b6452f0cfeae1998ac6bef93070f30179270e24a67436bc60f17211579c62ceb0933806959b9a8eb77aa07205da4483b96592480340e010f78f3a0ea34d09506e8099fd4b959c8bbaf638cb6fdb84600982e20d2832c0368650d9a6c0a8a3c1b1e8fe8704cb4e906b450d903e11baf2b421d6114f3203c446e5afb68e261e0e36604b1b5b48c712e2dd70b0c2be087bb6efc758a78f05961ac49e697aef1e811e780302198e1cad6d288ca196617f07a666d9b4ac1b86aacb272c54b14859e4dd584cf0d04386d484ebb394017a087587100665be201df52d1b0af6c19e11b9f1035ab52db8e0f32e418feadf6cd818419148c38268c3195c7a94b11075f806907b35d54596989dc829934373fb98123d108c9e1e04def5e3fa079ac71db3fd8632d7e90c46a4d95875c71e2a869b51fcaf73a0ef668a2d7413bc0af48f392b43c0cc688d60e421052461e3b49b78706c5e4a26230cfbbc3e15185a0a000507abb6b1a6a5250df97cfd6d3861c09276285be945c8e544a38027c5d9c34e55650cb1eae0c84aae8480257c784ae4aca58a7c4fc646b77aef6128fcf9b9208d7230bccc666ef24a3fb68f04f2f66c0d82c50a2d6dcc5923fd92bc2c7b2a6889ce86f7e477f0487cc6e73f390310f4c561014090fabc74c8c7ef11b6d3bc04bb1f5a5b7b62679057f8f855cf40f07d786a40438ce702ce649f8feb683abb02689fdaec22689db13f615c83d99a27aad0f1c3f2d5d3d3727ee5e3f2aa3f838241ebdab722b8a04119bf5dfb3abb3596d60b8d189af750cf5644bcb5e6edbba5716ee45415bb202ed0c9c4e09d316a0848325d3190ed99b420cf66bd9ea413143cf0d273e5c63c0d337286ed0a760e99b803679c63ae6b725f8b054a108bab184c0b6b00591c6c3d74d1295a961a77d432eea40347ebd0ca4ee3c185b00d509a60ee53db10f3a54562639ca38082698afcfb9e3486e9c0940c14f6fe69a17d72ac4dabc530badacb505edcc430358f09e8687ddb3404897f8fbaaa81c9175259fd4861d04ea4db0fc4e3c68ca86f425bbd6ea1cc422feb491a3d570604080174984260ae0414441952ba118d794aca2e4fb5a5c08e75866a5a23b9802c2ab5fe4159ed493f23ce3a0d96b29641d2791ce4b58040fd6a3b16aff23df2caa00d1808325a4a8b16d296cfd874ea6499d57842a503c7441fd7907cfe37291aba53619840f669dc875160ffb54676999c8aa6640858670227abefbdccc0ce28eba73aa954df8992656e2b3fab92aa3d17bcf08475242c77a287ab93a791dca35c6cefb1f443fd5264ec941959e8ec97201e6963cbc89403ca5d3e8e11d29ab8c2fe78a29c27f314b35f21397943c1400eac9d4a52c1a54349f6d57e5ccf60fc08ff281778b9f24fd776ed835d1e1124b9a18b487baccc9beb9fb4f7371945d5251357cc38a01ab55948d4c35208a20f24d9471dfe6bee83eea7490d5588a3bacf95b15fbec5288a7db7e70c12bcd7965871b8606a93bb67c84bab7cab455e0d2e33c0d97da497c49331ab98e0a6ab1a909169531ba00360b701403598e79d1f057934b2e62ef64efe38bb8580d779cdee738ffd9ebd8857700e0f88ff90214e0ee581ccd9cdcf8e1b7ab290331c74da9739b510342305eb83c13b9ed67f2f6cd913b68e6cf5478414038051267e2957845711945d9603addc4be182999ce82c149da8150d1557e4dccfed7d80a761ec03fac105f4052a34e3a289fa454f24687eeb7f3abdc3d4bfa0ab5174f5c14638ef5a2cb26f0ea797fb3dc16e734e5fbdea286c37a995d6266c8613d329524d782510a26792218e19caba00e6da5ed0d55362efc800e77c69ceacd4b89cefeceb34cf88f02cb8d3ef1a0b93990faedb582c6457215d83dcea692074c14c10d847f6a3a13567886b372b61e0679a9827d9923cafa4bee3e9872de0b27d03073c5a5fd788a43d968ee639eb1794dea3072c185214d34ab58ffd9574734da5440b1ee596611ab307131e5e8870c18065f25beb8f1486382646ada7c4661d4952f31b664249a51b59fa174c50d2e8c3bc7200df3ca47fdec0baf0dd6de7d282dac24b9c42d7042a9e07b0840a8676a2e7132669c674d9b6bb1c72ceaaa7a776877b1fda9873e150ac5b035e456f5882cb7931d439352e6ca61a20c3d0e63a39c01bae0a8786baece1d8d90a0b6b6834a6af4751b53c8ba592ee4aad93fcb2d16b066961aff5df75f7d1b48f9c7d28a5c50f9813f801c0f3161ecba2a6612f8a31ba45e4e6726954a196c60b05a4cccdfba0000815c2dc59e198e484f9e2beb0acf1c9169f39d5d628350eaae33bf2f0c4f342b01962c4bf9891d97df2bdbb016252a1499d50313f5df0b7e7e7b41b6da477517d81b9cddee9098607631bc0f553f2f77d1bd9e6300f28294e75caeca1a1f7fe860868b52ca864e2bc071114dcf84722edd43e4d600fdd54d029ae1c3353f8ed6b4e288d0fce1c12350100b420160982d89cb81486895161d94603f395a6a23ca0b16280408d7271169b8a7f548e0aace3229d4f63b9b551cd2b1ebb345398b09f77b52070c0e635b39661bc8fdfda998f4498b840471717550d92c447d54269dc41ef6de8da4a3e8fe0f19099a6eeb2986d1c5a748f969cc57829056f7723d03bf73159d4b0d25d0bfcba1a9bca3f08f5776549fda10f99468d9d7ffc531afca15168f8ea41d52229fd07b687fc603247b2b4f97ff51d33ca0cbaa75ecdc1cf0989a60029c142f23fa0fb6d2ada45df77d50d26fa52dd21d6f9d1a5b4629cb8a94b05d2222443b93b4c37e4bb91631c50a85336f5001ffbba5f91d28948e581270f540ef00f9e25f68f4b881cac3590dec4ee289f28f04857fda19973678739e5a51b3d83e01fe44893c3f8565598ab19869e6de533107e6c9deaaa1925490e8b51acd86f4d0ce2cf9938e6af8639685b726ebd6cf6f7d7f8a636915eaeced305b2d39cfd7fe532b714493b84fbd2d3c081173dfd423721cc3094cc47c4a7aa4b1840ff5b214f178d565061e1bc2aca86622d3dc686c839a395c33ffa83e74268b6f7bd34a303b5441d0b912a6f03fbae282623554d43499352a1d8fa0b5cd663d8aa90ef4de1dd5bc4c03a5a23a3d4acdafab732e79a78407fb9932ec464cd69a61ef94086c90d93e8f949a6fe48723b0872386dde8226264fce0cbd47bbc2dca190ae28661b4712125f1a0c05ef3dc107861d5a1bb8c6870fcc3711bda5207d533d5c4c81fa1038abb841609f676b86f7256133e71426f75def8f86c0da66220e2887c07c68407bdf9833221d419bfd3f03827243451f792b03365e24c61c0fea660b2b0a373c67fd48ebc1a7088da04d37460325182fb61a7b9ea5e1f26b66fb8739cee6136b138b2d4aadb294089bdfcc6ca1a3467b1f7bd2fbea506198ad01a46d3c6f62255ea2243bffbda21724c7b46ac50c21bfb160052c0bd403a2c82b969a048771c6b405afc5e96fc2855aa17ed3027225dec33d9256b4de23c5641d564508176651a89309a3433d8e267ec77e25d668f98444e49ce37e229c81e9453dc3ccca2e32e974213c82cd33f0b0f451002281d86157dd22beb5a414828858df46f22d88e28a2d1c5bdc47d94a17da36c302161c3ee549ed0e18ee106e0b4469cc926b92048421bea3b0e8ede51e1c6f26ec46b8289537fdbe8d22a68fd2d09902c4a02f2af68c4e66be4bcdea1262aa62ae0f89b0db734b00441a7600a380ea9820b0a01871c1b287b2f3acbd0f4330203975283ecf30035c4167eaa3f70601c49f5d87c83c29183bd2d49de08323ba6be36e26abc3927721c3f61e2f090dbcc446f9f658b78b97827384835143821b0b69098b520e24038a65eb30678b9ae3acceb268d684be855eff5b426b1a641c582067255fb75209b2646f7f9cc85e180dab9a176d4854af27211507135bc109e8613b0856fd0502ee2636783c4e500a81b737440000e910a052df96d66f67e152d1cc4bbcd09c83dd05a623830f4dc6d780a7d65ec980ab85e2da8d3055dcb77266123d974a665f9b6ba1d5afd34c50e5bce850a4c280ccea0358f34762af5c6f1d055b34406bbe511ae3cdb55ea384adbc0672a0031cc2bd734d27cc0eba53c9e8227a151588ee49474356b8e80788f46146345a96686bc0c1ab086e2dd60dba4c7e5a56b1f7b4763383ea2fb36c740bcd6806e145fa4d603ee4d4de189c3ba71ef3d933ccdd738a9aab868039525e49bee5de95e04d7f8d6a20b20f039eaf03c9066898f18c8db84f2ccdae10932a02711572ce6bf0e794897504297289eab2839c3132a320c392e8a0c10b3c316e6551e09e5f7d5c15d76666023f12f4eef75ae6e372d6ab77171a7acd5f2204b086a3d693fbd39d34dfc353e4c38c212402dfdaba0dd1f7f32df842439f5cc57c9ffbaac1f33e8b936bf4a8a2665035f488fd3db1c032b6412978c3fc408aad8d43b1a8dd2e6cf1efd0c6ea3080b9a8e81a66f5378ccffb4e571093d37da71ed687615d3cbd29e9a7714e47f97c48326796677de894f719dca88a2f84ad9fcd0218592e6b89e520bff803837a4a669c8f9b906562815935ff2050910a21b1cd502b6f22b46da1d4d8c292d32eab2017291ce6fb9888a62ab8a047cf1514cb987a48c3af48ebcd302fac09d429988d7f8a828514ac2bf477f8bea6aa56e32ce6c64f818aa2a96f6f22e7460a5477e6961a10214a0e98f308e61f433e65e952e779b678f2c02ce0146126d9bf8611025dbbae07064e4c75057f1c77c57bf13b5652e480a2b4867c4df0a2b29230a356df3116a2977df4e6b2b9ad656566f69d177c9982b06274098bd66b971a16f4d89e37dadce93e0e8337418ac4766cab5ed06cb17c3ee38f73c354937ef61fad1c985c182726e4a297d93ba14f86dc4fe2eb5175a9479826d4aecd6a2f20a9d2cbf659b17ca3bcdb368e91c9580cdbd2fa0d3eb9fb4076f3ea6780497d48016411df4337cb59ca85e902944c12f83a65c159c66770c673f3a170cf4c7aa33010fbd9fe19d038881ab38f78eecda047103f2f17b6725649fd951cc73ad4d663500029bd7bb2c5ac649713d6d12d20fe6c9e4d66b95c0653c8b14d2224d09ab8ef907d607306c394656d26586db416ca3073bd00689a75701658ce2a77223dc9bafb8f2269a462340717ea25e0810c615ad4e2ca802ec546b6c85aec6ad14042ce52653c03ed7996c2e3c24e7a6a8214657ddb22626e1545bc0902fcc0dde0a810a0eaf279a033e676352e8a9eddfbb5c045c26ca049bf6e36f416b5e225cf3ccac4c7cf8e0de6e08deef47afe8d5aeb82f1dc2d045f17c2fea156189a2ce569e11a16faf623e0353fb551ad0bd3dead7145547fb9d5eb95909e116c07fa59e802f31c1a0cca44cef6239d6fea4d9812ed4d2c5ef901f3930fb321c66a0db4b20c71ff47c3ad4ffd731bdbef8483fef9614a2ba2c96fa12980aef29ed7e0627fc5ed9175217241e555c0404913c8412644b994e53ae0e36efb1b3ad83c8dca478d5929475b52a16b356e481913018f489c4188db0b22e5729f95bd284efc974369ec094ae0958161d4fcaecd9bfd51ebcfd3f79a9ebca4f629e41e89e69240829288e8f10fe63ff77cf805f42a3cab35c7d4cb68a93eacc9a7b728769f290294b73724be9361bc697ffa3414ff5e5ffa8d2c98c4ebfa6f5cc7dcfa037de4921b215c065feaab2cb7988a8d69a9cdfdb79bbd66087d043693385b25557985a1cdccc258bc1bde77e8d3eea07b5617b84bfa6659724fa9d92b8b8ef149684fc900aa78d791f52e2d4edc4d2b9b7b82a6278705a7611b8ba5c0228ea721259185c021cade2fb766609f2afbd27462c312de60b5bbae44299d062c444fc4beb4e68ac8112d75240f47327ab9e65b1a2b79457e9534d77904dbddff65ef3d24297a2b5cba6f9a7ed7af39f807e4e1e557f2792f1168c64348197df735a62bf8e5b5b77293bca9a82fd1d359bbec961d97179eeed3c0785ff27632c3f9124f6c2085b1864065732711cd42853849701d00eafe97c2f44d632534c4728e85b2bd61e55568217318e99d853459d445aea770e323d9959d0a168a868815dd6eb1bf32bd6816b8b818b1a7ef93a03834e51eea1b71442ce8594bca22b4656965aa0609a37ab8b1411c184105a9815f0a87ef7a325167d047f0ad15f06386a3f590061806242b680c2d098321e6e97433125279a77daadcec353fe6657d4ce6c00712faf14d8851f9f5ba7130aa91cbbe05eb33469d18177dfb50d87365c2a420df0067e3375eef9cdc280a92fe20c16cb5f5d5e4d52ed6b448ec300ae54b589d5785382a74bc82cf932678da949e06ca80cc50f31b7afa9af5fb36add06492c433b1a9ea6aae3e6b832cdda243e485c27611b0cee6f9c2a3a3fa0449f8062e84ee4762f4b22dded84dde8735cec93ad14dfa374c1d41e12e0cbcfa2e25ad0165ee2141c088378f426f39d3f3524de114bfdee3f2897307bda74eff8881b18ac60dc1bb9e5b4bc7abf04541e682ccd52829ef098cdcd4a8c168649581d7c9b4a3c1f5041df1cfbbc6943a69d36bcacba09bb0a023809e69c309103aaa0768498461ed694b4f02a9954fee6e00bb10c9249878fb509aa9825342aef59ad461753067c960d4873498566c4efbd67ba7dd29d6e87f00c87374ad6d7e6825c8f4df8b2f4dd6f23d8cf14809faf0ae6866cd948989f5b435fe2f974b12416d086b10f5b43625ae56afc32eb549e8d77afc27988788401a14eae6315cf1b212b85f44518b8abd496d40920404914791461cc1449e977ad01038055bd1111c643a853bcce2cf49e82002251af6084f1fca8f4a9ebd03a28348500204455c708634b8754bf63c32c81ca44aa03001ac3d760648cc45053e44cdb665d6456006ca8193f7402740f18d1db031130412880389e2b0cc6ef408f28c13754c04231ad003f1989ed9308b0ebb7a54153135459b5e8b5ef959c94166aa7aed9384fe58e929ad0fe2be4e06957257abe6a5110f3321a251e7dc04a3e2f837128d38b46e769d6492e4b1d28a694878bbddf07ce9774478ad5a2d7c6bb04166ecca5d7eb85de1ebaa171ef99e300d9d1f754bfab1b96bec6e6b68866e714a7442cb34860e2ddc3ba71016756d3001e8e5c94318753f1c022c4695e6638ad0ae4051a172ec7e2d14b2c7242206cf99cb4132376bc5b281a394578433eef96f4ac100e3552f6246f64addc3aea3278234b6f70b9bc2753a565a03b46ff674c4f50e0f4aa41167d045e604fe9b64f244be88eee4781279078b829f1f84444ff1387863f0dc0e948f6310f5e8c82ec0b776cb1567447f08d1584b702d03b445a5ff4c03feb58fcbe6096900ebf4d665632ec361e1fae1d7957b82e0402bfb84da61bc16f1aca2e23817b19b7153ac24902bf5951fd86675010e3847ef186a110a9f2cf1d70f81396857b4938d9c14b45bfcbd4b811f18185caf165dc4c97f702fd7f79393c8c77fa0180d87159797d5700ef3bfe39df18d8f19fc17dd897981596fe76bc1c110fad6451be6ff824267d2cab87703bdd28019df4321ff99dfe67a1a79d17c90905ca79ae93da162b381580d074cb7f5e160cc42f7ff2e1b76e2460f374054a42e02d9c37a373c70bd87386ed6856277b8455dcfa02c756c8cb957a94f6e031a0ddb568a184b9c92d0dfa122ae3a69d43681b27a1f64a6fad9ff0b7fe5d9d7fe6000301c0a970f428623673d5cceb0b9b031d9f7d531131a2a5ca3a55f64ad94119d7d201fc83d76539428a2fdab897641d593772ea01724134c9cf310baa7b01397511285b8fd433069dcb7adba9db5fe506cf3ace6c8f9386f30829d3e2a650280befc2be5f82606681712f1da8be34aad8a7ea52df44b02eddbeb8cf8d0e9b709b93db97755fb57b813815959641f1b3a9e5ef007da51c7cd81f4497b3c5857ed5b7aa1a7752404c2715cca976f1d0d488938f19a78fb30d0ce2175f86f4e1d26b521b7929e63c253457445b53c529c3934d509e1a9a72715064bfb6e2b36c8af905c4241a819cceb16b98b60023d104303811b1c2740970a84495a896fe4ec5a380d1a2d2b1774b84528584b0ffad06deb46694ad7864f3b372a4f4f7b646436545eef012901f129c07635038aa56d70737f9f413d89d97fb52924a9444d68124baf791180b818814ee235e0b7be5a51d69f75ce20264b9b0f78e99e36b62966cd4d67b6264767b1cb51b56496dbbcc48195952ae23a367e1e77de92ba291e9e36e16c150062b1682ce454e86a47b755ab3c1f60e471835a83ef621e62cb8eda28c34dcdb11ae959a3a8bf00d058553829885517ab4b16b14c4645b14c69e5c827428150666a4f7c6393cb3d115c89e3af23361d586c654a41113c00805ab6f74fc1e232c5f9cca6fb62848b140a842d20974c67e41e14eea2097504fff9259b8522c109bd46d83b84c2ad668cb7296475baa0d624d24a14498fb08d1d6c7c77abe602e701815782d90888f89fa914fa6f7024da75afe468871102f75d85b211c36b48d60e85c41b8990c6cbbc113918b3435f367567c3d566671f90c7e0deb0afc0e8eeacb90e11a73dc6707ac6dd73ba70de6909d81c24f58392a2c960d27568cd67da3fb01a2fa0d3869d27b51ebfc0a40f598cd9c58b9720cb5e6b58303dc2845e2d7af7646315df0466636a756af3333c85924d42d7d7796acad9a3dcc7af16901da104c2c80c29d69ca5a0452287aba4a742b067340d737cbcc59c750ef32c8eaa9e2b42dea321533de695e1c1bfca426bc1e0b66da87680270c90a7102281740404c723a13d4b044b265292a4db82358ed136931d3fd2fef4085ddd0b3e1fb8357595c93d447922f43073c0d39f2dc4a6f5f74ba2b17c492f93162c8092c6c52df48c4468210dd0900c2179f105168e651b495f1c7d21049eaff4201c3d266c280ea5c65583bf0eaad920c342a92b6f4052607fefcfa92e059647cb790842a23b25757d1624b71f4d55523b8ff7c6b1b41bac79ab4ed6a4090f46d06f09c99c53d96216facf16adaa51143d62b496290583e8327fe2ae51ae2beffc0260488d97b46ce6abdb43f4e1e766245b4cfc2373329e3e2c05fc7e0d1843eb6374680857b080a261659e8bc23b63c7cadf97334e8c9374c774799d1cf8d0c6c02d4a8eee140de3b9a15dba4b18ece753b8e8592aa4d9e216145bbc6dfb7391d298652836a875517528705443329793c2ea1300692582b291d97692466e5a7755904befc967618d7569a098a5bc41499b2da2b87700e8b51d1206b6b05791c070a591af98a03e88cf9d0926a617f8fdfefb654ff02aa5916c976d59004619c1cd0df09ab4b3f78ac8ab18cf3ad7b0601f6095c501c43cd23ff967951a2a9cc3a78b7632982335776b71a0677fb9987a01026dc44cfc6241c6f4c36fde3e403b3286e0ced744842a2e743bc6e6cdac9d3c321502112e0d5a4f34347f10c74a774155a22b126600c9a0407d7905d80078fb42b43ad40fc84caef9c0da3dd2c343d6e6897d43588dd3a8ce5f09ae28859d63057f9b8ef9e39ea464cbf571255eecc157700ad2614ea8f4e45d6f679aab5bae34e376c1547f956705e091abaab233e5926c402c1786e86fc1d5221a02234e42e6cd4575d571b359f918e62dd67d8db0fd2ecc1c332fbb2c01678a0f0856173915ad45150e0b62e434d8174ec839077d7528d3352a60b6e41d407fbd3b63bdb420955ca148c550304faf626bd482d26b070d0106e82b49dafe9b7e1d2c47589c265bcf605a70532bbbfa7dce51af921e7f27bf23835a0fa8e78b44e4838f3933756afb696ad3f37bccc69ba8f73a9f40492e1665802d20d88503694cc464957aa123b2be9b592ea81386ee080f9aa620e17f16d7c16e5316b7facc91c6a4c5eb1e5f4f47a5fbd12fb9ad84b3d2c1aaa1dbb9d0be73fa63e299af3895d2af92a23881431ea4a7e9fe07cb76ab60cfcd9de86c36e2b0521b46beb02d5b2ce43cefe1339991ade949e9872b66455482ec278cafba5a5a2e8937147552b406c2da258ccc534560e4f7ad6a65bbcf03d91414e7fb13baef66ab583b16d91190d2aaa6e32c2547b855ff546b8601769f121f569aaa52e2e341ad8081ef616e1989ca019eaa9402c2d514a070f8236cc6b5189d2840e063008303cf73d529b40db8ace45670572cfe7309e2de6fa7610580ede5052a379178e54285932bcf28bd13c86cbd866bfdc56a15f21f91d1cfd5c2af7b738f2de4055a4020f4f603e6f76f3e8cee07b08c217bffa8c90b4b2949f297860450a9a86507f7ad7ad44ddd4fbe3ff7e2be2f52723fae0aa308146a04dfeabb1b3586bda1b5511aaf77da4ed414901c83f53a7bf1ad209c96c28c71a22fa4a4c951342d500a1bf5a32c46c44004b66ccd529e57fc42dbb920cce8853960e40a05cf94c9566c251e69a43a648922c304c8156647ae3212ff36b14c03cfc20abccc6555ba22c8db2bf96f34734e4ec73d18d0402a37bfb1b9247bcdbf6cafc7b1acff21d485bf5443f000eacebbe8a8986b29f329dab4e00fd486f80f39d84e8a373a7bbf3c4b530b7893197dbea98c5323cca6d058948e188a415b8ed5af6cad0a79c8522d17eac5b784892082e02888e27906efc0ca3fd42147c81d8c6b996895fc6d7ecae7c88d31a55e2b48b29a61a1a36d9d9f225aa24bbb1c4ca0b6eab44f3bf1466852cb3c9c902b8ad0cb7bdc7467823a4d55bc355d48282438f283e705bd5d9c223afbc93e90146af53dcb75a33d77b0f681e4b29a3f0a28179532c86031903133dab0039b0670a171b46ccc3fb6a53c3268c12b3dcdef1a6944bac1295b072f1c1647661a54815fb5389c3fa33886de6bdd254df8261756f6b563eb67c95221b541adbbca9a7e9e99c5ac492e6fe82460526204c412a29814acdd71d099b0a676a5bb531559f065058081f6fa84f5c7c4346dac08a45c9d9c125ef5c55a051dc5cb0d98f009b80a87433b5820c120037b1cc36ccb38a6d13440643e64c4f90d4979d947da628d881fc1ef14e5c00da6c927b6d2017145ad034a7046e83a8052db7304a2740041ad4dbb8326299237c2d8796905fc8e6413adf816861b1bf2123a94e8540a708a89c0e11136b9c5533b30e4a936a4c700db206ad493525a8465905a5c935ceba995905a58935ca22a89dc867c2bc7ffbffe06614d6da03c9d37be067883b32a3e1d29945cc37e272f84ae1343283038a5a1d5b20ef255302d199606edca097471a3c876d0fb6779857f7540890965247a4654382d5df5fbb98d94098480f3bc0f235d2120f51cb9d867197fc8e21087f9547ad3b1cd21c2e5f520fea9154388008fa83cb1245a5d5dda05e8211db0ed9b1936f123e8138b563510e776d6db5ee55f1d11814127288e59dd2ee29c0830c6a31ee43c656d848300ae882d15faa09713d6666a243e020194cc48a8d6db7c978681cfda4c3d73ca3622a525dd66aa1fbacd5b9fc9b33bdf907e3855faf9277204b7b996710d963a7eb0d57c271862ea94ca401faddf417c74e838535429d37f3146cdbffad64e82550b794f96377646ec899a9666b666b7faecc8e03d329ddf80c731b2626c54636d6c09a97d59cc9d1a02f3fe023be594f14d78a4ebaa1a1e474efcb113bb110938983a40df70ea6814e4624a10cdbee158547b33064a385d40fa7de158d40b62f128d6c2c54f94e0e574041fa10ad329c2c3ce74ad5cec93359a7aed43913ba1e961b7e96ce29bf1652efca3ee4dbbca929f6c0360c3336f1ac5258976a71ada10ea94182f16d4eee0089b6491c90228f0911eb54993ac1be681ad5da2369c89be7389d9d9177204f3dbd4fea1bc8eb9885690168a88ac29fea012db7a211478a1f8fd8e29f378fcce386fe51ddd1faca20cc5f7a746ed302e22e907efa712f8d060d54fdbb7a4292dec6f1ea5a2919702d8e1267fa328e59d8e93cf17134212f2e1c7b0cc27f0e905ed8b20229e3c0e325fc60ac97798259678866a0d552f821a42e600170641282937f1efcffc3715a2b15d1449e02c8752960d02005ec7efc31d68a3d841093af836d00f6675e615938304e4bd9146ee69df9ee6d42124f5e82486389c930fbe8cf521986e9ae92f55f43cf936920dc0cacadc4cb046830be82091e87f1fbf8f6a8e93d6b53171738043a717dd37efd302b0126a06a6dc9e7bcbe1108694f30fb04fb55d742a05200744e87880935ceb2195906a5893527a8865907ad893527a8865907a54935ccba195983d6a41a6515b44eec26d1c85315a24c44f56cbd005426375168c09bc99c42c9c01e9f8d14ae2a26d41b4356a431ee7b94acf15bac49748539c685c3e0900d53719110ccb6bcfb4945f26c033e8e015ba7ecc907bfaca903a58dd734458d8ea31a2a120aaa90eccf9e705424e5c79340dec247cbaf0394bbf502332fc89a2d154979df2396b016e37b8cacff2e1d1615099d19183142bdc7c122b3266e9df4dbb00654af1223f32e1a5e2915493521c082dfe5d73585e0687f2a9244098757ca89cd8c1cdb7dcb9c4b6f1142ff4f5ecb668466e89226127e584ff1b7da2eb00ab0c7411027ff291733cf4193e7d3ce9270a94812c04ae85c1f79ae3fad6a80811bbd7a6a2f2e47da1b84158012495511759ad254757505da85a54845a273964b1c19d798891084fa11cfa8b080442ae2563d444592942f97c1911d2b46a9c48bb25f0c25481cd8e4ec965f6875f31c4e9e00ecf22ad8eb73d75114c995d3d789761ca7820c97a4d57e6808fdd149b759222c76791945a28148b62e7d7d4dd72fcb2c11580115a69d31deaddebc2540e3e66cfe1e45f23658c27e2ac0339632201f1dcf25229ea628125179dc438d12e30edc34d74a7228c58061c1405246befc305f7c44ad1870d1ebae7c90c4c0f558b913452286abc0689e624e3f6236277bb33472c48c2ca75520c517a035052ee0256d2d4044e525a4a9cd7499ea855a6abb0f86bbb8e7697f7061edf0e09546eaada8252905fa66348140255633440bbc601791e55124339ac4004b258505b47ca6415eef4a723cb79054720b94cc007917da41bcda9b47bbf406947f042e20048922293ded7108b5a3b0e120074b2f6953e4605db61e41e372c91d01cd43f8892e30523622397492e47849f5e04b172f2747f4caba1b1e48e9770a2cbd8d9483458d32f334b272701a7a7f472b60dff5f09bdbdc27bf3acb31969e46df08e2b626f2d5e5e87a1d618eaf2b4a27735c048951b43d8ce6f07d6256cf600f96a85c6a7d4ffbc2ff5be85f2633bd71d0e8e73caf51b08b98af3669c9e70c635a07ad756f1600cf4fb7ac134a91d05c498e1a96e7a03d2c1fdb627e4e9777751c1fb80d11f72ada180c5773629b42b7f5ebe9ba116caab88ea8cbb7598fb24d060d0787aa000efdc958ca6d456e1cf1101ba37b92cab2613cf6117edbb100a2b0580dd7cc86860143a4b4b37dbb206984232ed3725ca5f0ad1686eb4554ea8c2a15d7bd06d7df01eecf737e3ce797e7d9eaa9dd6ecf3b4958ff3dea45cbd780c3ad81093243c6b26994ae2e29d732013e7af861196519d23f076049e3ad6a3b3d394103d4f28fe8832119f5b6fcfffe30f2e0fa13d40d89454a9230227b4a0f7594017209941e50eed5298cfcc971b08bce77b2453df1f2725426b16b73de3f8bac88243e374d041b17d6db40a2933ea2c76cba324c4a401f2481750292b1cc768dc273d247fc98cd4b5717a1c2e6a1cde9bfd7b4aa853379ed40482b556e5f2d7b45471aa0a1ed1d89cf360471217a6c04795742c87160a6eb68f5eb8161e31dcb37f4f22ce965cb652d09a6be47158b204ee2dcf6f2c37f90f6b9006803f68f70c2b1c772d263eb0e5c3008e6ca8b8657861842c31ca7caa8066cd1740fef2864d870386190e1cd5487d9290fb31abd913688cba94b0a75e543a0f6cb4ea77d54419017d0bbd250ce6f44a373a01c941f4cc25cb5929002a20091fd79ba791bfa0a212050b7a1ee705fbe45131caa3503df284593fc988a3ea122acceead9d412bcb185c2b6022d441d89fb9edf2194a8f60804b928109464f3dfd3557b42d6eeb59ab5ca36d0fec8ea59a76278b95ea8211a173114a32699539c66d2211444d92a01301b746e4f25a7e3a8b5e9e5f1129eecb6c61f05c33ff48c4144ba45e00393e2b4e23ad9ffe67c634a5bf6e9c48de5a022899f9b948460a991a87a189da526a30e1f4b904b4d23507cbe81ad2fb5bb1886ff6a229d2331b5ea0b587980dee45ae1656a3a06e0e003ea936fa4598ca676b3933c2999059020cd90b062d319fa58338be25853bb05e5fe2d22cddba013999560218c82d4e16e6aa620468495d4252bb8a93d0fc3131fd8a7c6de155107192676011fac646597f4d53f2c739053a35e05240d3bd8537bb6860b81d515a89d49488dafbc6dc65eed9d7d09f05d09ca402c483a00eb5a34ad939f7ff66f0ad30d366e1bb4962cca5ae7b83434d878fbad95eea6ce7cd405a174bfab39e61b69d582f85ff70f6b15dc8e59dcb003bf27e5523909fddf7320b1b200ff132707a450215591493d922aa404a07cd8b92bcfe3bd054acdae6e41f61f1e8b032ef4c604ea444c3e45f4e7a3e7bb606e27116c0df35a9f3f8b1a4458a4f04ddb3624358460085c355e9a26310e11c5e4d682e9c1e75247e742d7c5306eb23b48541942b14800e3553121bc201fb504b9f613aa1214095077d61de83bf147a7593b4edd5824059bd89b5567a22a7e6884d9bad88ba67c6c258602b632c896d2f9858f394a127288daa4fc82037141d2df83728b537a43a4e4ab6091375f96b98bd6880434064400b0540683f7368840ac78e19cccca8bf756b502796a0f7b64b58f9f7190c169e8ad5554ae01f3015ec27ad3a97ce91cca170de75e4740e16d36474ea198453f0947d7a6ae9339e5f0c0a943b740288790055ee9c3cc9fb5300e7683a6dcce047563814999bb01f804f51d56b34fd401adb4c3020003cbb291aa299e2d643692c1d5853a5de52ffc7bbc38458b21e7274e78e1b5e2526b6e0dc1a7e594502c8ba7c263e5d20497aba625349aa491821daac5a39f9b52c76beaa36f81065f043c8c2a748c6ef5c28893a0822f5d615750b2cb18da82d8c05adb4b83227ef874989cb3cc1e2fc2638b1daa7d2b77d7e20c2d2e8f2f8264c9e0967009bb927a227a114b9aad22af9232403cc1dda1defa8a21da5107390a551df9f19ee2e0791e18b47430b716deaecf107030bcabbcd42df09fc89003f4422c9eb7d00cf44b51b70dd3da1f3e6a9696688939d822138b900b399d39a49182515f7dc195e8492b1f982680dd63f69bdd51a93dfbd836c2ba7a05fef5c4ef078a993e9f5506798dd8edb5742a1c79a8bc9076f19d36cb7b862f842102db2aa12b3c42145179ee59c456dc18eef679f28adff289e31fd89d6c9f2386dfe12d1e13e56d4f34cc0c0869eec1c01e3063ed243e7c6b1b118553c01eef8507d3950a23b56242c45a86f2a6eb7e3b49a40fe39b777fbccfe85c63569b790c2642af9858bd4c119deae86dbc1e4efbce1b933fc96adfcb007cacdb6a954d7e318bb6554a1d8bd7609964d554b21848b8cad06d488a19304cd025b2c6f25d01803204ee719ea7d37b70c3f918a23cb0c8d71c8838826badff2b8f5d8c96ec43861067ff1cdc125a8243093558ee959f1dca4392170f86781bef902423887ae9d663b957fb8392ba755373b194a04384812708c3abbe1dc092317939227b89223a210ab38d3bc881a0067056a2847657f2cd0135bfa8aa8a22c39394e7d74b5a55fbd7f3d05d314fb761f867408aaa3162fc3197ae28dfdd5fd750cc84088fee5c8ab29520607e844377c49381ac0f120342be2bca6a485bd2fa339c3c5e86cba387c2fe688214d156a60d679ee04b6f7c0efa060a30541b07685973df3bbc84db0a8fef3f785f57205e4e196503ee81e41b1e931b43a30578b3fa5bdb0d11e95b8c96a0ac6562f1c5adb59cc6d30b33496ceb4281fb132732a9f16f4be10f151364d31398bcdbc5df948554e5e01f4ea0b476fa6caa7382785b2f0dcadac164870bbca55947f382d3b2420137f0910cdd1c9b7442b7ac80938a7c8f79ac6a41bf074c0982cb74e37dfc98c866785516cd58047204b6ef854dc2b56cb19bafd382ccaae5e2d224467f092145b5136be2c1ea1208925a2f65cb0a86d1431c8a3cd9f40c534494b3af8ac54305c8b661ddcc446f7dffb5fbc4cfe3e8af9c82bc89d84906bcd140de491d1a24eb138a3b331438f030c9082f2e6723a6764f496b5c2620d97e818969a651333a24ac1781e582ff185d9067b61c2a64f1eaceb6c8988569432c862dc32c5d210e542ba8b531882bb5ca5656e8e0c344a9e4248bcb26568f3dadb58cb8cb020ceac40e857b589314243e5761cc5ffb1d4ea8e3433d2b1c2c4d7b66239107a00d2ac8d13d1fcc412576d84244d3207df63b7f7982d55eac514663310213e3e2f5c89c9896054959a8ed6390daf762e0f720be89e13fbf019566698bd20f9672e7744fc142e108844153d928f81c4dd4efa90bc2460573781c95a3664047173eaa5ff4bfe462f6056d17ea797656eb21fe6613a2fd2f16f9bdb5b43458f2a24f81517079e0379dc49456b499be24fd6eaf01a5841142aa21868ff3ac48bc197830b15cd94c1f446da199a479543c802f08fa2100301b32e398f09e55fa95444cbe26c754643cf5443eeddd0e7642563f47bdc2068fc5dec009b84dd2bbd23fe8bfbd4b3743eb95cf800847b1450fb694c05d8aea41f6eadafa157c794f9658cd136ab9f48991c243dcda9a9a3f60beef2b38716ffa71a70cad1c2fd73fd7509664efb0cdfead0938301d2d4aa660a4daba9aefc17bd2beb5925f8805e1e107cb16ad0fdc39c97fc21f8ef32945ea9943eac7783f89319fa00bc52645b24ea583d8ed72fa2c1bb69ed860b6fe36276a6f60b0fae282c4784e04e8caa4822fb10b043c835415950bcf13bbe34af5e713661d695642ccdf2d5c595351c8115ff06f7487e9511b4abc44d99029ef60cfa04cf1f3a7222671b0687d127a43f3482ee9232ba9b08ad4be5f152174a617c38a34dd39487086467358686541072f1cf6c3e8a1a4dd20499f3c5612c01fae01148978d83fc5482c12e27b2a80d7c2d0a578725c797565a19a0187bef5062c86473fe783c54a45ec1914150f389910ccf2bd4b62655a9d68dfa40986fab217bd1bfcf6daffbddd1183cf3a30e2fb2430c539d1c7eee38c69e0101319e48d20c7c0038e3107a6fa0ded221cea0267a781a445ff8c89b1dd6b16988ae3c34245929c40fa16a7a23d3015317122b79ede077d270fd6fc35996b6680240dfd0f3a159f5d3adfa9b8b2e7ff54a1979b3b1e193d3a07b7168054b849d1508221ebf653dee3b845441343c271c811093f16342b5c608b5828844aeb699fef7230edb9b72ef00fe99936172375dacca97dda668320bfe122eaa2e6489536901c7664d4dcc4633ece5ff054c26b12b9bd06d2f15a888d8a0cc060420c2a8db30df24745e334962d79e62913adff036d36e3a4438a649c562938631eda2e3dbfb7f84813a75311e02cd61b2b35efa310371495205f76349ef2c890f2f509485481879e346653074995f139934357497f70eac5462506349521fec789dfdce40eef567a1dd79bc796c0ee4c7f7046cbba717798a9ce0632984423976e2c6d989ec04f0f65b8b5015117e6ea9a46638f224991320ccdcb87d1c35a3194d600951ac508a53da6882f0bf6a7bd666c83322e3e0f88c1b552a98cb03f11d14857639890f69866311e6f0e4c42d5652525c528a7d909c75a950358b983d450ae251f14958ae12f9e8dfdea3a14ff9dae7844c5009cdfe78280e88d2602e29c849c5a653c4d7fcf90c361f21993a02d0ff126661d8e41f77054c4bed052aa0bdbccb5080369e17254fbca854297a6372feca95aab05c0d654f9f4bdf0ca233404d4e4830e09037a86867ed522ad773e95375fd815a27e52d9e49290623479ceb618b39de0df0b7bb4b89cd10993a98b0f6eee6795d42bdbce9e714303ea9a3745e1886505c539a7a6dab1fd283784e284c96c8eb4c38514dc1a459cdcc7cfb36f32a79265026cfe081a68d7dbc47a3b3f6df15e0fe97491bebdf0a6b9874465d9e7393ff98b10a7e934fb3a07fe0fe96b74b72e778a1633ea975d2cd0d1710be10e2a6699dfbafc3d98c653efb322034c274bbe007cfb02636b47ad8bdf83d9fa8bd8c97b3af97b0cfd83e45c09feee739c8c985422fe3a82b0abddd278054d925323cf12a7ccb0cdeff710c9159538e39e56e3e5ba81a15b44419fdbe32b49885b293234f7270b05ffb32f81c77fccbf19f7535ecfeb7a9153a220143033498dc0ab1c0278d02874cd3bca658cdc5cdd2cb06fc825e16133847036476f9cb173b383ac80fe8c983bf9082471deb127cfe134688ba2ed791557a58ee1f0887406cc6995c683f05ea4a38cdef8c5e8690084a77d4625fad604c3d8f91e0aeefc3de70ea40b36e13f515710cad4ccb07a6fa6cffd22699eaf99cdfadd377812118ddb315cfffece6020618eaea66c5a9d8bc100f485a88fec0bc86b4176d63e686a1621d6d66bed35c160c4f60ce97512d4550e299be3927caf295f8be2069586d14ffefe83b2a0bcae88a7d9ae1b5df655cc0a6f2b1c3955a162530842c92a8d1e5ee99f10e4ed3d28be3d968bda2e5942bcb84432198eb0c3562dde58a13ac3294106109697f02225d4342d0728ed28bc94e0d3c61d318aea4b29409e554fb15bdb6924c212cc3de7c4189dae5646b0797d7114e14fa5144dd1c56d7f1463d5e36f7270fa66451399ceb7baf56b8b3f06900637554daada54db947cb6bc2421fa461b5e8645b782ef10828e33c362c9d6bdafde7a6a9c4a35f16d584adb423506e0567aef067b77d669340718b05059cbb30bc568d9991a6a254b34a980213587cdd4bbd2dc038a91492132f1fcf48c998e400ca303601cbe44171168337449dcba4e33d4c8ff88cd25b70a6de3bbdb15817b312b91393b6f50b7dd3ef2a568bcb7e7a0cb6fe4c58767379b9b006bd802d8fa7ef1474a9571f43a21af5bc460eb6c90d7479f1b31daae8a35cd8ce4257f6647f7002eb66cfa8a49b3909762eec5ea06aaeb5d3937e544d3116075a52b62420f6422b824d46ec2feb00567e24e64e2aba14d14b73a2035f1e683d8883d2fb9198c342b8a2f135376681bb64763bbbcc3488dc6a4ed2ef24e316527e243962dcf67e731043c6205da58dbae531048cd361d18e46b2683f0daba910b20117195bfa60cf7c410dcb139327312d954607e4dc46ea9145bcafd1fd9d6d2ee265d3f149c216dfe7fdcded8ec1f8bb66ad4c13f42abf53083ce32017739c08e843505930ada0a0e0bde7c8e12a0474bbe2506b05941c76ba7fb7b9ea7cd4a64a004a6a453c202ca04a827503839e491c314a31c463940c98127490f928c91a495a4851103e06040968e8f31cd137bb6b57b15d9afa616752f6c81de77d5b2dcf37f9e6d8de1fba0e34ab96a6f2acd2f87cd9e787a7c1f87ff727cad6387cdefb1f5367fd9ce31e7d90effed569e473b1ce92aa741dd1fd37bacc9d9cd762fb71e0d2aff47b96a37cfb32dcf9572d2f368b749fc45f56fd89a3cf1ab8dcdfbd9fb964eb4788274a3a0cd33870100c0c10e1c9c18e1c08343dff0811b88483f59e5a7d8a26eaa738b7268ded79474197c4e8bf9c9e77d8d8a9c9725e77de9a7781f88fbea976ad24f71deef9ee5f83e516c02a5e6fd5497c1cf8961eeced75fed53184aca86a8861d0e149beda3b82a4d61d8ec41a1566e02435ca98653a18d4db0944ab9c9e66f882d08d3e1a92f5b834f0d40dd11c79ec83fea9848a65f44bd77d2dd447a548307e9510d1d918ce946b2c391211c49e30811478ad4a431aae9007e3056a9973a3c33f6f2f69796ec9d99e4eeaa1413c9e1f1bc3d4ba826c8881f2323604646b48c8c38c04890ee48c21cd5624f844261f039cfd86e2a8fb27484f413afcdf359194789634f24dd664c8a3d915084a36389f4514b770e4f04bb5b156bbabb8d70cfc234f6498ce7d7694b371e9d667b7333513132615302ba4f7f5bad774c47458628d2a48877e895ca1ad6e9344d8c68724a7894565062a2c443c904eeafc9e61675946c614a1db4274c517e8aa5d35f9296ad0dc237647db47adfddedda11c94a911e91a0905044e22032860812ddf581b0f4546d9d168f88c43022d2349880868e86d10c777447eeff36918e33fd74feb650b1beec7430f4ffdb64062f6600bb6389fb22ea8d66207577835d96a14c576bb15b2c431832dcee58fa22ea3d49954a0df16234c4ca90537743e991103142ae0839c5c0c6046228e2633ac658eed59f683d0f7fe7a21173fefaaa71193f0bb4d9abb545fefa8aaded36af5f9fe5aad4e59adeacf56539ff3cafd7d4d41c71ee5dd79eaa8b62ff2ff4be3571e7a29d94dc6fee79d3e5b1ac02caf15105e93072e9421620c702ace8eeefb2dfcfb6286593317da2f2c953e3523e2b6f7ea55ee5a9ef5dfb37043505b44001593a661a63a9460a00522920484718fa18c120064f150c5dba391c18402f576bb3c9f360707ced2801613091f75834579a002e3e4a4047614209604211a0c7bbdea345f4828ef3dcf0e3e07024ecf0dcf1bc899342a15628d46a740034b01c40c9e8051ebc1046f7c2014641f80832c52808064641988c8204796cbb5796d647cbb0c753fa49d648208f364fd0e62bfd644dcff2be8b5595df1074ec02132e30e9ee58c2a45cffc340b420460b75d4424e470e4f7f03cc61802c2303e4e63e68c482162316aeb050c382afe08215c2d10a52563061947519654e645132201d2bc5a66f6213a64da2ac8979a18df95f22a18d41f15892dd96274bfe3771a56e9aa18bb2be892927fd1461efb56cf697d2bf085b6f7e919d8e831ed3d7e73aef0c5d1dfedbf2e9f53541a1d14802a323a391094d431333b69e7b9e8a86c6e36fdbacb4865f2de72deaf26f084a8fb11ca5830f8f4f904a4aac50bafb841ecd8831c3cdcc50001c8c0a90c5e32cbd0ffa046d96f7146dd088006610c00204c021c0080330c100f26800308c0430a66dbd78de389e2eafcddb6c9223bd65e7579ba784cd1e7b1f0890763118dd2cc6d3253e4d3c12400fddbda44702806114800008310a005077473cbbf9f258494a12ae76fa17d912f714662f4872ef893e83543863a48210231572e8ee00f44885385241480a3488dcfc4e91ab336f13f6428e92da6fd7b6acb7bcd93dcbab8dc1ecf5e65fe9271450941c3725a6d2f3e626f374bdf7dc83b1d583b1ac79dedcbc695b9507cf1d146ad5e1d9692978f728055005040e9404e2a51bcfd70848fd190191ddddaa119012460000d3f25aff6b71a437379d262300748fe7dfef562300e400a063defebbd508052f1dffb31b9e1d47371a0a8d5090ae1b82f63e10a76aab8f50f02ef64e9eb39b0d3884a90fbd1925f64e6cb68f928abd9313c6e88e2dfbd3a3137630c18f91095eba3bfe0db7adc8ded813b1421cbacdd9daa098474343431361b4f517c42313b27477f43cea6464426b64c2936e593a3232018551095fba5bb67e5402964cbf27ba4f347b4625d87483f33bc744de631eeb7b8c55ac97f2ae0976f7931e91208311096074b7cc8f6152a865258e9425212fe238a49fd7d717d2793c3b30b5b2d93e4a9e79e6cc3c398cb76a6beb83f0bc3a28d42a8542ad34ceb3a311c87437952a1e89accdaad10859ba23473d4c39cf2a71eebb2dd317f68c431f7ca8ca7dcb85984a15ff6e351ac1d5eddf65a1d7d7d4caa6f563bb17ccde78dedc46cdc6a8b17434a1478d803f56d031f644afaf25f9fa2a49fe87107fd83f6cfe98e96e273d5384328a00eb583a42faf1532c53980f1912350dd398dbec960b854c9e373799ad0d925c9d960b71aedfe5b0082a229469226ce9ee48842771a2502b2df644a9d47d6efe0e0ab5b2b181d91b3f5e7e20e96e9d9e19021e5a0c418a215019c20166842026ce6e0b7149be2479a631af5a96e7d157972deb66d8cf3a63d7d2a2d93d0bd3cf484c085608a1270841084215317fccebcfaed6e981eeaaf4afedf27f1e18ab959a26dde66a9dbb76f38052f7ff3e779fc3d9da9b43b0c37367a80609ecb9da87148d427ddb94548964f36d535238dc8064274908041600010442023aca929b381e922c9a9dd7b015724aa4e74d1ce9b3863f30e30742443cbb1f0c60868f33f8b8c287a987aab8c994bd1063ba031fc4a087aa987c80419bf7e8c11e507437cef4fb2eab62a6cefdb5d576afb0db03883d76b8b9070b3d00d343554c25f96d53b8fa42f273cb92eabcff72fcdfa40747f4209b4cb93e0fcee86e1e40c18327188738cffb52787042191994b93254c533b69b9bb217e2afd7b2489e298e553553c6a63bea01043daad0e349c71c5ae7fea3395feba6f9cda9c70a79cc9147961eaae2393cde8333e55aebd3b9d9a9f298c9838487197844000f23778cb903cb5015b7d6e531afde2fb22eeff1c83d08dacbc5becb38b4f75d7572259b7dfe25c598076ed3037de68e1a76e0c60eb0f4509589b38318ec88419bbeeb329db18365870e75ec5107143d54c54d60e8cfb2d964bab8d2f9e51fbc8ea23a9e74cbead411840c196ca252059c377b9ddc0b91f9820c13646c3c6f6ed8562dc6cdbf8ea9d351043a66408795ee1eaa62a25225564b73fd22df689e9fcde1accfa22349be5f54292765909ea163668e2fb104c27e0e2dddf1dad6cc1cf27e6b0e20ddfd1f472728470c2afdeee7e7301139b2c891a49bb54d104fcf270667771fc863c972b65a3c5f337274c4b38b434c8cc38a7b1ecdd8ff4eeec39d9e89a326729fff827215870b3af8d2f67acbdaead984e7ebbb950ebaee9e5eb7d579faab03520ee0e8ee38f3e43c0759704873203bdecf1e6dad7200e4da56c5419758aded307d79ace47993e4f5655738984077f7c5a9548994fab629a994e74d9c148e09399ebeb2b1f9b629291b98bd4965fc5ca61f7d2205490d610adbc0eccd1b366ec4d1717a7da2993d6f9ab8af6188ff5b336e4419421b73b491a58d1b66da283246cccc980e7477a4f9cf621a25d5d2fc5ecc8bd1645b69bcb0156257c5e7e6572dad4433ff77b9daaf5483cd4f5a9f18f3bc79adc7bccda50b7fb27b6d015b88f16228200c3fc20813657def04eba187fae37913c78b780f5ec485a4c9f3a824faf9f1288f488f79d4b317be378b68f843bc26ed2514116811818e0800600618140003e80b3fbeb8e28b27bed821047f84808c1078dd4ee35ec41fcf9b96fd16f5ae6db1c2f0f323252197f5483f92e4db9d8f3d7667a594c751f25ac7b2099638f44037c9237ef2169d5e70f1a2025e04e1c5932e43e8c245975817b0cb922e0b00011810740182211000f9801a1f20227e9f29ca4ff18bace988a37e8cd49f96a5c13f0b45173299ea8f9fe2b5a76aa108917e4a24cfd24f25923fbd366bf7bb2cfd14f34ed5bae99452c1664fcae6bbd7b55d88e9ee2eb874778ce1f9eaa2eb22081761ba3d2f5f2e94e06227d3f96d2a2e82fcdd824c473c555b80516d8145b545d7718b9d2d62757a8f1664a2165cb4b092c323b560d2ddd6470b8f116d340b6521a63b5edbcaa24b776791a5b3e8ba3d8b9def5659d434c962860b1c2dc405061d75fe5b3636307bc30a31476285788405998e1e163b60d1e522eff187afe8b962872b1270c58c074ae081ec81ea81177c1024a5fc6fc55822e577c51209bf47c1cf6eb64a2951279b431fe804bfb56a51ef40131f585185153d5811ad28a23a0c49dbaa3c54726859d3a59f72ace2882aaa74cce1c1a1020c152f2a3a2a945011e4546da538cca758ba96e4718bddb26d61c014774ca18129f289f3ac4b20a0d2eb2bc9311156f87da6d7b242213959d7e59a580a3ca44881143f483124c54c146644e125a84271c5e9312f0a20509001451728948082080a295090c0012f58060579112732c58bf894fc42b6f5fa0ada0b821c10c2811736e0c606b244956d557ae77b381b3035c7a99e70c113603cf17ae2478b10b480d11d652988f4f3adfffcdf62cdfb2d2daf65001af843035c340093deb2ac10737fffe609fe6585d83fc6c24432302603626420890cf864a0a69be354ac3b2fc7a99c90e2849026f468e28d2648d044144dec34a102137630f104132a0cf0a09fb3dbc9e594137767278562e9443a5d19747297a5295ec485bc880739a69e51a895c6bde7fd56a378941d9e9e90e4ea949815624c248561b3c74da5d40e6e22f99052c1668f6d55fa2dcc794f9bb8a934f3cc71d3cc3387942dbd9c47e7f7ac7fa55a1ae802bde97a6fe69993b1f6d9dbb279092cb1b4444d37ebb9e7b2f4d11db3b4200b0c5bcf73584d3a3964659912b3d4e42cb9d2ef025ffa025b2eb0d34db9bf9b941e637933db0bb0d0dd4ac040095847256abadbe624cac412479a2fa124b6742c250176ac376425e1dc5f4ac2214682f3ec0ee7d90e092e4858e997f56e9060d2b14c919831724418d5115b3a5a9b8fe8baa3fc663d224977944d8e00124f7fc19bffdbd25e5f51a895c679d608cf88231618d39d1f3f868229114cbb6c01222c80044b1b584680050a2c56ea0dbbcda31efd2e17cdf7fca590dcd61cf1bcd9a24574bec20ab851012c15b8a188378a10a3880a14f12a82060ad080022f0ac470058e0e6f26b9dbec25d2dcdc8467e79e87e57ccfda18b7fc6ec2267c3f56678c05fe05431b33cdfb2c3795be887a5303ff89a4578cb5f75813e77a858b2b563aae7e7e827e635d216102694c000313d099c04cc76b89dcbf4d2447c31fa847c41d4434d1ddd1e4784e980e112409e42181342460250ef1bedcc588ca75ce90430e91680e51f1efb2044856c644dce56a3fafe1a3b0187274562a1c9d20209d9cd37fb37ad524354d4eeaa9ac3861c587ee8e325b7ba563ca43b4d9271c0dbaffb71501383a0e55a152c5ab2a02572250c33da9863942a04c571504b66c10c8618832dd1d71381c623cbb21be0cf18ad3b62a8f10550826dd33082382000a2249f705020a10088895111b2246145340ac04981d300cc06e6026bc82f0aae2f5a40808455b90bceb3e3d229114f112294f2d1e414924250d09678a474853543dd251f273c8a237e7e93d5c9d9bab52d7fd4f2239c23d6d51ce7e353471fefa9a316dcd2f9a9b12aefefd22ebd884ed2bfbbbeef71409294a210c4178a53b4a2e8f19e532b2057294bca423965ccef384e3aaf43e38c242e84ea1502b1b98bd99db47b944b8605e585eae3bce7bc20f67749c3f0c01c974e4eab49eed5edf77f9b379aed02350c7f6c046611de047055393a849469f1d1f139febdb91d23defb9f999a434d13addb4f298f1176e9712fd48c7c1919e37711ecf1b140a8592138cb11c63daad481eedb59f9334ee51d956d8c7eac42caf8a913701cf08911a444510492122c107187494ac106bdce329dd84e4088d03c9231a9ef854a70782f37aaef315da18d136330e6d2cdb7a0a717d9e3aa3ab5a6f3689b16ab9f031e8dcbf10f739b41a472738ef6bda9d9cfd6ecb87208da9fb3885a369968c69476bbaa3cbff4e22a30e8f4e4b63ea2725f97ddeaea8abe94ce7866955b9c694542357182e697aea9aa0ca55e3b9ba3b7e2b8d96958e527a97af7db57628d1bff148fc948e3153cc63cd6c7d7cd2a2d6501513952a1ebfa6fb0babed569c05381bba7d43632b62abe98e46a663225f6db5947ee7aab4e48ab14cefd9ebd7e2b0fa7056185696282bed9111531c162ce6b0bc239e2f156b86e9ee38b98c265077fccf626fd61964ab3cb24cfcf0075a43e7eae491602e9da0e3c8236492881dfc2772554ac4fd571d3cae24900e4f4ff3d28da996ef3f2ba475f16a3b3e1aa93b6a40a2d003c0349edd0336d01debc449e1ea8545956ab0f9a552b9fe96425243eb2f9842524308fe68da17d6541530ddb14472eea9fc41850b2a4c50d1a8b8d0430c463d70d1c3aa3b66ecf95d9a0c35ad24ff63137493e45e92ec6b859fdee4fc7dcef6482965ccd4710cc170c5431f3cac80870bf030a53bc658eea727a6d213d28fa3fc143f68ca988e539648d143ca0ae2571e8fae6afd59ddca562943524c33bead51b888124594a2283274a34ed6c74ff186969648ee363fcb84a9ca23141a408941a9e98ef8feab5bad8258e9ac8aac5e103a432805424542a6ee8ed7d23beb6fd83d8f12e5ce4541ec422521d24fac79762f3b3b5c1fe3bfa10d3ffcc1a58cd52032826c5029c81d0047b439cefbd887c498f799565a5fef802bddd1c43dd108e80fa0138c8030508dbfec8d9f6209574b49bee2e9e1798242e1bccd3ce756f221b5ac37899c2496fe3fdc8f0b3e73f82ce19343cf1e3d51f4ecf4087922832b4f943c998926ec81f64127da226db5b0cd917b1d8ff23d524c74add6f2676934b6bac9eb77523cfee6b67bc1e6b553d32afda4d344c7f4ce22271e70929dfca0d023273c3bf0b10398ee538c3d91143f45cccdbf7e8aa598472dc9635eae33e34a4ba70f22edb0ea6e1e9e3178409eb873831d27563b2be83046c76aab05c30f2ab2ac29254f941c0a8529f761cb9bf8feb78a57fab51e91446fd297f59ee598ca7804f577bacc38e4a4737f6fb646a6ff56ede6f86fe89ed784084dee68724593294d00a023860e918e4dce0e72acc8e17266bae30b45282d69ca3c359cdee289a5161d42a1a8fc47333ed99294fe8f498e896ad86dcefd9c757e45f6e35e936efa1a3d2f6c7125120a15db50a8156bd6f91ee6ea7f0e2df716f4e9231c2eba3be3f8e014b9211387647e2ca9084589a53c9e37b265c1d05beecd4de806bc41806a072a2daa1c9500ba23aed666c72dea8f9f687e3d8efa6c7d220bdbae32e911132b980cc1644a47cfa3446e739ef3be57fa712a146a8513b9bff75b0df8c0a8015334006c000252605239d5a5663ac63285551e8ff8b9fae029ca589d5faaa1a4c255cb42a15ade0b918624572d4b52a95022572d2bb4b11bda9857ea4d6e42891d9e190cb3d4407072aa253758e2654913dd5d3a42fac10173738bfdbff961c9f17c779ac0f93906e70bb3b2c9c1f902e74b48c90c194a8f0c654486428dd0dd4e3acb218c1c8ac872d8e98ed26355e5dcfcdb65232efd14a9f453960488243f242965495e7840670c28010340203b63c04f191ca2c00196d3b298baf42143e2bc13487acbe2ff2646f090213187c75f5f8ddcffecf6377e1a12a1b834c27d7dc50c87ce6e40c1bcf2ad0d8a6136713c3eaddcb0d39dad876776833f774367367c89d7663658e96e1b76ba3b5e0b640358830fbaaa348e67d6008b355c3b1d8a0d28808401f78160b347c6bc96a5d25b99e2a73767bf29eef3cc47b868cfdaec88921a32354cd4f4504363e40646ae18c1c1c84cecb68c7dd210e313f7a5134f67d14bb7472cdd1d2bdd9e157722906e999d64707a65272327201d8f609650916731a6dca5262fd26d6ed9cce4848949777c7d35cda88ac451a4a80850772c559a6be8d9a25984d4ddaa8ca68c8a8605dd3dbb154d161af939a3210dc9fa4f60b3a7a704a63ecba7640536bfac34a5bbdbe66c2bc98d8c1405c9878ce4117f5a687df8ff3222615c9512f1ac053322b08ea5d2d421b2c3512f915c45a423f7190d61a2ad3440d11d1aa141a361c6e6589d9eb56036031cd8facca065869de8e1b9f1b82a9bc19b4c77c479863f3c3765c042063b54a9673204e9f8b215281b026608ac3feacdbf4376fa5acf8674770b8943889688ef739b15c251214cba1d16c30d71b63e31cc208620babb5aebc5e6a7bdbe62edf535f5faba803da05880ce0b9d2d204a8eba02b0c814102a60860c063d3218c6c860a0000c3634f7955a1fea833f2894d3445ac4a59bb86ceb741a1c3d6b13204702509025e04a4757493fb9e4a8749a9675291d4f8ef62043c00910e0650880e100651c60b236217f29087b211ebfc89f68e679fdce77cf2bf9a5955a1f827e48dc5fea590b86aa17f878e18aec8508bc700a32a6e3f43aed4d1c92544c5fb86dd314b96a6fb2204fb2202b642ed891b9e082ee3675e64214990ba10b60e682c721099b3d3a68de6459cfe5590b741fc8b316d460133635d81caad4ee50698fa4e2f985fce4955a1f5ab8226b61b630d3420a0610c3005e18a04a779458cb8fc3967569924b62f0968d72c912e722b52c259db15044c6c2938c051ab2157490ada0816c0528d90a455678215b4177e75aa9ad5976253365a33b3ab2aef50944447e76f4c3e8003365cc70d1ec497a6098656cce028c29c095ac003a590148c8082003024441001e022c19801d03706200b028bd498bf8555279e290749a388442492a8e6962d87ae227a789dcbbabd29f799b2eaba599004001bc9005808c007859005a5021052a0491a910aae0590a45c852b8234b810b003a4b818a149e74f792ce52284096420940b8c88048200302cb80cc90015161041900ba8e4f44bdcdb4e3b1143e2579ec4e8c7ffbea2dea9e37877880a0370f0d31a14a7f39a28d12dd6f6d96d2441c1f12b937553af3fd0d4ae43ed36f5ddb9aff596ceb574bb7cce344a494190a6664288091a190050a2b1400704208b21336d0dd419d9db0d3fd513762c4a39fa4d3c4eff1138dca87486bb1e3f73a37ea811f95a69b88f17b769a90850941990908c84ad84156821b59091628c1ebe85977aed607adf62ccd668dc8e6ff7cf5e3f3a08d484cf1088a4ed7e74cab4b9e8c043b3212329091d075f74f6724bc30827bd616651afef09ebd3c505a34f344d3b5b037b5bcc7999a6836821ad90856b211e40fa0b3114859b391751259ffcb7aa7785f5ad8fcfc9475e98f35fee8d21da7fd32cb8b9eb53efa83e88f27dd1d7dfe38a1085e14818722a4400430e27759feb53dd647fee3fb3874551a63f97f164bcf5a9008980831f811043fb8f881449b86240a25a998b2b5d7b316f4ac05b9d752f3be761f855a713c54f3ac053f7b5bda7b39dbdb65d8fc529f67d0d55225522ab5b281e2263765fa4aad6ce67dcd560d363fadd22f5b7b2f2b65935ad9e0f76cd07bf6de57c17481dc94f271d38e0d47b5fc18889bd68b4db042c1a95450ce8ecd6405e5ecdce7e6e7a97176bbb6a5e197067eb7c33bdeccd5a69eb338afafdcfc0e0c532a94522537a5766c3248b2d93e8a86af65e517caf53f7c8b2c38f3e4b46a29f719537c1ffc1be2799fa3dcfc8edbb22dd26299eed83c1014a7e67d3e5eb63ac787956e3e1ccffb3e08d320ecb147bb97fb20fb60017bf4e191ab4f74e7e7262c577b7c19ed8145665bf700ea3d50e88198eed8032cdcfc1daff454c31edc406dd6f0bccf0322784053c606655e50268832347aa4a147187a687a8cf2f8230f2df2c012f1bdd46326ae7a74b662a64a27f5fe3f5abf7eb7f2d8e1168f87b66269b3e9da3c96e0a1071e4f8cf050e111a4a31462c996f51f1e531cb94abf4ce72bf6f894f16cb5bcc75fad7fce1d5feee0401c9254520f0415eab63c4b19367bb84f457193939dfba952aeffd91e146af5b2750705f8c30e2ceca062070d76b450070bea58a20e9b3a8844991f6bf73daf1485a239d25b96e4712379b5f4889f4ad89b3f92e452c6580e7e33b34c8f6707fe83dc13d9a24a534478ae88f0cc64b6b0e693b1d24d264977d33a373ae0989ee7afaf7f9d08cf3ca2e30b1d5b383a649feae3900e524f90d2318717fa41732481f3dff421c273959aa3660e20728891834b9503ec9e33e6e1d07eb16ae5f021c2337beabf49532894e74d1c2e955ad9bc07862b9beda3c4d14529e320d9aa8330d46bb56cb5261d7489b127721f1d28e1dc4e6a0341154f0edec8810972b0440e94e4e0d42d758ce8389128597242fa9151ba4eccf359f9ceef482e71ec9db8131d2fe24e50f53d0d7739546935a582ca4d97e354a624a18e9b928444f3a568afaf389871f5c05103389270151c40ded0c11b69bcf18137a6bc218334b96697e98bb3f5d4a28e89ae7db5ac733cfe5ddeeee7ce453d49391ec7446e8f1b52b8a1841b366df0d1060fda88a20d1d3a5e696a592ecc16f4589daaf8d5ba262be6dd8f796ec24fb337eb837e2df79872f2afdd70867d45a156f74130d45c9355f417e4e6771e9db924e4a62824ae86b6d3b48cad37264b8f61d29163038eee188b8d2d6c4c894fd8b8b6b58697e69e35bb35ac346c7e6b00ad01a4f37fa31b7ce96e2837c0d2dd7d839d1bccb4983062b2e09615c3a43be674be46628274c7fa44f6b21c5335c474776335b8740c0c3d3f56037777b785b62863ebc191c617691091462b0def8e428468ab9f9fa0d5cf4f101a4ea0a183469033c29c61c41940feac7f218facb701183688d9c0c60c3ecc186386968e9946e96f3261951908a8411ca18de1d42056832361d80883459823c2dc8429d100b33ebb85dbcd365644b310213400a2c1cc0cce98010866e09a010d32c8810c9088a51229c66e3c3a5bd6b1f5361914033131a0c0280641c48006188481c1153058c1808617a0f102235e60039ea03f0bdb98d4a4e7692dab0d711a975e44e22772c11c2eb8800b72c014010c18606031b431f718cb7a72bedc84bfdb425be4d772ef2821427c7eb8e1bf2df8410b3ed082b005475a904277b7ece954edaaa809e6ead3db62c1976e16687916809505350d44197d7497b1c56d2d0374dd598677cf8ca76a0568e4d50aee0a90a8600f158c11ffafcdf7c1f9dde6dd167e3e3de92d9e50053d7da4804b47ccd5d9d109ce2f56a7f55280848c36c8f8d211086a7255ca714f460f6414d1a4fba876562ea4d3c3b3729da09f1ee93e3f9ea3f3e4890ac7756e847876b814921a522592ab5257a55fb47487ae2f5d7f4982823ebadaff2c56a1c04b4714c05000d4f15a47828220fdfad609c0589f13c0589e89545f9de004331d71e9affd481eabd3045e9c621380b67afe989b5426f031cac499e7185a7abe5463482f65a395a0a7040b20c11b24c842029b8e383d907ee2fdd3742f7578a1c24b125ea27819418cdc8f698dc9898e8a81de3b6fc6d8e0a83140d82042b7a34c4d2a459d3eca06096bfc608d3cd690630d34d638a37d899b7cde772f1898a28c0f51e911ea58a3238107dd6d020965b8ffc123debe68e27975f0901b8ca0699af66d30ad6bd0a06a68694705fd0405e9780c31c4a086901a6a2451a3a61d755f33e2282338f4c01b62cd44b54c0d01f892254bba4780401a5ebadbf3bcf747a8693c208da0349274b7d5be0d9629f7dab7c1b4cfd230401a24a0010434cce82e69247794c951953a08cebbfa50285c2dc528d48d191a0100eac9d9a6077a87e70e0ab5d158a6deccd7f6dcab43f4a393d9a0cb6cf024b3c1936e47e10409dd1d2839d872a1d07dd6bc49996cae6de279130707855281a3360a0a854269f5398e761a05a70662ace16c3d7c3bf00bb523bff1582ec43785c39123478e1c3952732487240cc0e1061b6a4072047fb64536363636cf9a3736cf9a2cbb42a164703cdda664425243b803c773ff3ee52c0e2b367bb84a89aef561e63a5fb655796cabd2ff66fd6f56edd332f5c19b1f85d14ffb3cbf6d0af7efb1429bc355eae4c158d62a75d94fcb53fbd617511786cd8fa35aec7ef8c3b5f489369a533514d97cdb14140a491197fa6f69457f535ec05cea05092f3578f17e8e4edc6d3eb1aac488414b250611621809638e309608634916c64cfc6a3f6b2f4bc6587ead945fe9e726495289e04b77144196ee6b5b52707eba9b486722902d826ac31618707483d1a5bb27088615ec604cb9f3c1f02fca74c72fbe48f9024bb7b55f4cb976feeb8b245908f8e8965a2a95ba5f69cf8fcd6b06d9c0ec8df69a17a7f0fd6c8b3498176e78c1c50b21aa6db5a417345dc474f1d21d87e46bf9b1cddef421144a52597519ea920208bc00810441ea03643a9630c96dde2a8dd5196b79ac4e99250a2533ec2bf5b6d999843ec0c30748e8228f2e34d0c5d6854d7724da26eba76732dd78546d1c174b70e103172e6c4146b685175bf4b0c5095a84916971450b2add1dadf50941536cbe3ce679f4958dfc47f37c51bb8a2592635ce77f3ad569686868a8fd6b7b3cc6bc96a67db555d36c4b2885a5601c215caa376ef2ac6591565960e9ce02288b202d87dc245dc5a54cc45cba74472e30e70214c50271e98eb3da0c0b2e58c0b008d21d63e12bc874bce2045764b9a2bbd6845557d4747ba08f1d0f70e9fa5f7829e701a04c410fd4bcebce0ef491435607b80e64e900ce3ae0568421dd58c105c4b14276c796752bdc8a2abe54a1255601547213a98a1a322a64d0b1ab54e3709e1a15413e2a7acb97ee8e5bb27cb7dac2a43bdb12a4a7d081b539d5e1b933853685499a384aa58abc2f90c2082974900288775ff4f7c6a3f062eaf0eca854f11805d85124e98e02484321a6e385424b08423125629cadf581a2a62307fac88fbd42e180976e8aad7300e4400db701325f932840d906bafc06acd81d6f5edbdac0cc743cbb27c4f4135c9e98d2fd04490b192d30d012765ce52f632d41320d1069c0851364e03390394102275a4ec426c4644d7439599c635ea5afa93d910531d17ccf396a8ba6db8cf3bbf2c7f07dbccd56cd7376ab31cf23c7a99ae861a28fee6b7d985fd1d36ecb5e88395b646262cb646295315104037960a04b77c7186fb5167b8c88949843200cc88ef3315064093696a0c012361eed5ececaf5392ec4cfd9ed5d33e767d5782bf5389c38f7b9fb93e98d965d334f2d4f8dfb1a5e30e56383ffa3ab6d7a5982b20089b17c275844ff0260fc0248342d72eef17c6517b0e102415a0e51914a88698e6aa618a7c4968e4ac0942075c44924912589ae23a659123348c0814497e61edb0c092bed4800c51ac71409b7f7e598fa115ffa082bf608efee58dd0832d1082ed10820234e8d391e8e5ac0cb2c50d3dd5185e50d2c23c0c2b9b74d5a432c2e54808cac025d2ac043055628628c589219d327327ad866dc8ab1b62258451020a3800fa0a0404ee4ac7579b5d3e48f69e61e130992527a2a97d2a7f49f2b3bb8a281ec8ad015201308c104b098c02a53c7dfb5dbfb804f2e311124c888b8828816110a908018aece98ad0db2d8c7a3047a90c00b999532566c66c52602428840188cbf66fa723cbd0d63ebcd08c022a04343008c2e20c082401108c8900dd1c610560c8187d8e9f8e32819a5c461d18f14e9a7183a0a4a8ccdcfad1ce2248498385d882e42c084482284b782f0a2bbdbce3c73701049bcea00d107105bba2b10b1d81ab13262e0bcbf4d2f5613e507c8616436181698fbe97587d707ed8b05af2311bf5ea4ee58e9dda46d12144572b8284cc710f45994a53b16d5cc504c777c3cbb96c5212cf4eca5331677cf9f43b065c262c2cd72ce795f2d8e478fa583b974c4df6d186c5cd371e220f74b7c90a345795ebf497e20f303978c2de83f4cf9210489e6839e33704b83a0db2d0f5aeb96d411575afbe80a66c2e657b574f4e64633bd5b56995416a2fbb7c7b725ce0ddfcff9f1160a7da9ae2dfb4050ac69ada24964ada771b6dabf7fed566473d6b45611b8d569c31cdafab29c67eda669e0173e101463aa7d61d5346dab2dcd5e9b3530a4453a353a0b74c49e3759f42b75d5771e90e64ec84584ee186399fe5b26e9c25f9e5aae8f534950a8ed8b50282e630dc42edc247381dd4db977316957092d2fd1f3288e3d91731eedb6dc7aaf85a5e3acd37aee79aad6948ed77e6ba6bbe33f98f87df65a549fa4ffbb3ee6b44c208fdce476bac31a32cef3c7b22dcc86e9c6a45a6afa6c0bd2f15d777ea9a6fc31158bd565ac195cc32cd31d6797ee38ad6473a7bbdf6702e9eea6587e79223bd7b54e045399a4bbb34a33cd8eee8e29fbfda779337b4099077079002867f8caa953f5001928a7930d4161871850c58fee2854e7b45eab9051c5872a33dd314f93cd5e5d7482dfa44206950ec450483ea633e8f53e92c802f570460f5a7a58a2071c321e76c0c3183c8080872a3cdc300508dd4dd4d91424aa4c3175479bb363225c0d5bd7ba12c9d597277794128de52d7b5272423d764daff53495d2b49a78bc34ff7553d89ad7b6400aee1a62eb596f62f799bacf3da6f3864dfe098b82738b9265888af418654a77e45850ca7c129c5fcca0bc000aac3b7a9cf79b4011b20ad3917b0f0c2f37c31ffc399b9d02a9564d74c7975356b61aeaeea1ce56dd910b5974a3af5c6d26f4a53be696d096f6110285a674cc8492740bcd04cde1003c1cc001073871400a4062004501b40350fcb9c18f113f36643f343e623a5ace7bfa728eb2becbf324fd14dd9443cf62d6fc2edf8c2f55e56a6d967e2ab562ac073fbb9972784eac10731cbdf158fa2258f8f9df094eef7e91bd1c655196e3d07e9dd90b3f8aad073e572251964f0f3ea31e13643d5c22f737b42d29e5b3a85722b5c7cb7a7cbaa3bde0a952af5af6c48f3844453e09e3c93f09d21d31917927085a4c9be09f2f27649c84619d34c976b8a33b7e987eee519b5de6d06ad2f3f6b5dacde70e11d881dba1059e327884e88e7fbffbbc979b541ee79dd5ae329e998ed89b96e5d8f376c84430cc76b6f40e9608a4b39d6f8785a639ae4a7ddb1414cadac0eccdb7c1740875f026707447f0b76d7ead0f5a0dfcee8ef43abdaf33e36fd2244bd6447677931a9d385a678aeee6a1339d263ade1d256c7e513e107f41c714f6994e8e96ee48ebfc7260310728cb99c970ca74cf3bc10c0707ecee327de130b921d3dd38eeb991ece64b0341f14d968e1c8f63dadd905af6e684ee1537bfbb13d4325511aa9cc8e48e8cc9144caa749c4c64e8ee9835a08bac014870f3bb06ac90a564909a22d5f9df99c3736285d897ec60490696e8605326b3d980cd8d0d094a62405f6e2a5d22b1efb26d0911622b6d7df7f3c955ad5703b1b2a8f453f6f3a6758a660000280053100000203858301c924a66f301d17d1400005dc49c54cd4696c789cc29648c21c60000000000000000c000287b4bbbf646a6a0db77e8ac574fb741fb4c581aadb6453d9f7dd35a3445814188d4fd87309763c28467ae107a8e6910039e25835cb72ac6fc3cfcbc28bf0b400beb2005cc7afa1fb52db99fb706ea7cc0c3958e61ecc31c08f746b5ffa18c439cd8540799cf07e1042d0eeaef5e23f9a12b1beba05b8f169d6089931c1a5eb6f639b3e11c6df33372ca3cf053bac7e084c609db5802a120e7b4625d38b1acf7ad74047537fe3cfa14ac04eddeff2ae8323125ad4f9c3ce97a7f76c3c6dfca060ae601714900fdaa77a0caad0089927af59442129f412b53b5dfedf275be7a0c75699b0d613810565c6b69ab506e35637dd8aa98e2c54180bafa91184b4e0a90aadae9bf09f65d20d04ee886d4bc515e6db6de97ecd0156989fe4f2f282567d1307dd0b9d66a11e7f5a435d20fb524908a9e5f97d8440980e885a8640d0db39c14a82c372812145f4daca50e2593ef1e9e4f3868bdf3b03d24e12ef02321f7449dc3514764370ccdd1428cd4c04a7c172d85dbe9c4151376c4f556eb88c733e0ba3576791d7d47b8f70399e5f714f0ffadfde4bfeef8452bff5ef88eb2e1627a824592882e769657882b4a5a362f01ef1f050cb7dd7812c599a1d0bc450c0fcec18082691a1f0daa58f77a77a481743d4fcab8d4a4902952b19f00fb39b849c1769d203c846442407b4e9d7418e7f7035dfbf1c7c6b5df201b8fc37f469003f2e55a6c863436013742d741dce05b6d8253744c2b4694760eb489cd8f5ac4a6f34755e70da9ba3a244957e69327435403225d1c37f1c241c98b3aebf36f5cfcf0ba8fe3f2c45082fddbbf51052ef4ca362eb068a9d0ea3a13f157b149da0940ef51e4d44efde96d6af48a10567a9facdd0b2233ec2de6f6d7e8042ddadf6b68f530d021544f29a181d3cc76af22a313885ae8b64f1c5631f31a2e06552ceea2326359b31485447c6853188d23046b0f82a171d6b5ea416d01abe013f004d15e96ac260c05cbf50af80427609c23625665fc89e2fdeebed34609fa79ee2608f85be1d113c53b755a163a8a805fdcac13c474df7c51020d3b7478bcd32c2b7827e0a3e955f409f10afd51c5451131bb8c4d6a49b0a037d1d54ef3fd9f9a017ab4f56ccf2ddac4ea215a8c77dde9d0d1d34a5b0cd954e773fb57f24d7f858ad1a603d361de91be987b24cdd7f65bfb482c0546a2e0cf7df62b2f53d5081ac5a05413987434e2b4625e3399a49bc0d8c6f3157764cc47a927a78a0be9908905dbd68402dc60274979292c1c7c1a53a20a1d2c7fa1feab644888ecc9fc799014378272dd3d96b82662dde3758197fd7c4fff304ea113a73f37a2eee1b1a70eca70aae4c17dfb4f1320aa93187bba2456a7442dde5c569dd8c68c39858f4cd92d82cee834489d3dcb011bc345f4898175794a296d0ff3464c05563152041216713d8327f0579b9d87389b2c0b3ea9fcc040f15b42c0d05e019040a53506002e508017500001cc8002a03f1e8f2a1bfa46f4fc320cd8c64a33051b78cb11e0bf11f1c153dc2d93e951810885109810156a522080ac222ea5037173db868d436c26e587159c070e798d830b12c1303988d97e1ce97dc088cf8bb4fedac31b1a5bd9b88bb84eca8ac6c66afb5265273cfa22e8f82c4c3b50c09c29b6e957975a6e52fc84c2701a17de2beaa8f88510d5da025c3769f2682d1340ec42b33a81d962e60e7cd21244637390c0faa3b6f9cc85b02fa96b8c05d06f842753bf1027dae5adf1fd3488705400a883857497ec6889ba67b02109918ab32d9fac2a58863b67fcf41efc504dc47d9f366dd8786e03844d2cb5477e35cbf082c3ed6d29f868842f4710957a066cf4ce4484b7d22c65208d5938a869f561a17deabbff9b0be5b8e6c0596a6016f9bd8b158532dda9feb460fece624b76fe8e577d4aade2fc4696338dfc80431cade9b88c9134fe115da9e597b92e50268b55248f3c711a5289badaaf583778c7383ae40e894695f7577a76d5d0bfb5d1bfa5cdef93fe88028f0137679a86609b8be4b67f19d337f2197d042fc7b2f0c5c7321449b6bae003d0e635092e190ca29c61836c15bf72c93986afb6968561dc0816809367843a6b17873d83ae959c9e4fd8c49cae84dadcc9888b2ff20e51209d1d63346c24dfdc998f9db487108d60fbbed4ba1c37c083645e0e0879cdb1428c7e8187bc464bb98b05d90c675ebf19349315f1dc6d91dfb7429a98e0b7bc9765181d198c5059677f75d8e229fc0c73ef5345f97f883e6931b8f615c34f04d5d705a26ccf5a8d75941d4005f277affd11f5a7e4df621ed8d115213e0b1a690068bec2090017d221def378537a577f896453901e32b08cf906c5c164062d1fefdc9edc38538143da37bc52fc98d018274277a8c977f1e8c539264bcd526f47646e8194c95c063927369e0bd39da75e5c9c93913b7f276d11981fd9620c1e2aaec6d925e13f1b4232bff62b75e36a756911f88a6b5b80f4b777d4b71e583c6fae9f3bd646dd6526a78944e8280ceb103dc99a944092a4e5928ba1ce3902c7c3246ae7a09d4e34f97d1547363c304671dc01298c582059493fbf1a60b93030e71264094b37694b57747b5a50af1377cfc448df774cb49c5da009d783fbb95c032fd9c1173be315ddc01f3a672b23c29c09c867185742c6c4cf3c16e7682d75b09525cad50a260ea55a67ef74c80056f3b7c84e4ecf10228f22c2612cd796e565d3ee169fd520b3896e30080cd2818d114df7d313c0f600562f32ac2578ad3c941bbf322ecf4d2581b07a53d433436e92e645555471f54bbdcc40b5011dbe848cda144adb9d08b88f3a14aa62d189bcef218dc45eb5d5aee888360891a3723aa961300d3d9e402a5fe8da7ada2c2d07f67729722660ed8d7f4c0f41d77a07e9c4247c9c468c7211d75170a11aaa255df63e2e588f49650b8249f0a73c84c4a5da0c8f853de17c761d85f366776e44fca06dfb0206b5337120a04a805462bbdb99aca3067fb715cccb3962a2fbbe1c585c5cd6e5f1f43b7687cc572e316cd408e7498e07a1f1e9aa7641eab9c945dc29b1e2da3d72569e822c9e7e93d700faa12c38c15a750eac5f21c6739d5c6f7a35f793456f8028405ebde0b76f996cc2ec0a3b6b4f86d737afc11239c4dde06ef61623fbdf9d1e2c81b018eb2eef01e250a5116e55376610e9a8f1c09e3a0008fde113d20ac6c3d2925bd042d77d57897e466f0e9532f05e34ea2c5dc17c15e1e02c942061a70a685c16a4ca1c052106d4218e33f25ec58fcc8443fbcdfda4981eec9c1ba694be4332c87eae674d004fc1267f97e24a073c6a379504b4500562b8f695017577699fdc9ca273b2cfdc85166a236d86752dea452c5ec48680f274a5cb50c6e3c2b0fa7c5d1c8cfab2c5d80ea9e342b029dc96c2c07db7ca3175cb03b4d9c879261620140e357f1c1601c91453091b85d7cff17f8fce48b94dd09a2b3adcb5fdd5c1881dde1c030544421dd75c8bf1c8bdd7b8b66eb98b684b179da1d2e8ecf8a079a38d488aac6207236cf8240ed1858f5c36e418cf949fc70918c7182d4e31628ae7971a8c61c545828923f55afab25a2d6631a3b56a8615174c7d749a54b56defd69479d58f4c0646757be8b87c76fb59154e9f9aa3c7b5e8fe706c8948cbc3ef599d58f3ace5022d9ae6cb40204a4842181f163f8f3b828be161e2019da7b635348f1c13a41ccacc9ccf993508133ae8f9e414ddde7025d572bde692e7c98c1a39acc94014ffb8b08b226801a52a1564a8463bb66f30a115844759fc0ad91eb45018e83e8e02c7038bdcda21fcdc2adb347c97c634c6ef9bfa156004317638b961dac77ca40ee3bc6f5ab85618e2f887393cb266cb8f95dda59f3cb03ab7cbe45dc84506e5105708206ec417ade4efef46129ad481f0d77eec59bea68652f7d5cd73555efe46cfa879781c1d68d198967d043c43ba399a9afac1efa26702e6363606e60b7453c08b0c86ade99cc11682f98400d4b9d81cc3bb2ab400145f863d7a315db40cebaceceffb98ec0fe85b55c670985d5a1a862e5c1bd81d39e1f4cee51ec1e5e81620e8ade4b5c54e662f1e789663bce3108dd1cbdb18648944b4f2a893078a3d7c6b76dedf193e8439eb9ffad62b48941925d578dad68a68dd11af3065bd40a7c02820287f113488d62d4fcb714218d5911453fd1bfcbb1f5376c075eda9c53d2294b58467ae779c8953db32bb797d37d03c7e5386a00a70eacc6d250e346191bcb6b3ffc14a7902586f7b4800320ef7cae5ab624e40c9b551a93441cc9b85d82202688891841a66a13666267ca5438dbb587794865b79e9b129619d97ec21429fbf8774854e1301d3bad4e5586f3ebf768e20e3dcf6ab4eb4f277ba76a1a286b3c081b65ab00164108512a6a913d777734eae84ec13f58df9060fd3681ae36f3245513b8064d1d4d4b4af1a7e44f0e5945c884728bf193a7e29093b09591e6dbb80bea877b4368297495f4f4e8f3d736cd4253bee267f58bee6b008bfea1dd964125f0e1ffe70fa166669bda2dfb080ff2a2c18052030b96293f2e9723f7e022255832ff2ef3bca53d461b17fc89a2f5c7589b2fa1a34b6457bc98ce1829cc2e0ee546873f0cf6fbaab55d1c414d4b582acac502857438d951bf6a30276238815fca3d2cd209d8a5fbb55ebd89205256895b935277a1d4a505869750fc1c5667324b77489811dbffd7d4c391cf2c09e49978e26fb1018d0c54019d33a70fa83463fbb8c9fffaaf136b62cdc80e7ab55d1071753e9bb152942e4a3d068329b3e1be8e7c05b11e4fd37d4e07f8f932e095de0faaa4a49727ae705720da68567b9286e8bd5548a3499d0197215bf927135ef1b0a3c518e93ba712837f44ee538fa8bcfc7cf4618da8be92a6b7aa5156320c6d3a49301b7d09c68736dd7b9e80d4ac0bbc25b6db21c5b8fce67ebd08caf43a11003fc127ab01a18a06e177a0e409377cb85adf0bd1835657af5e26a3ade958bda6c1b4156a4b357f3d3b0fa09226b13154bcf0178f74d8c9267d1a8ee1373c6968bf5176347896a052821dddc27e66e1549d99e1e59cf78c4c0dba3b7e0ae741aa14ee1b278d8628b1fbb7772e2e147674796b3f5da7f1b98c16e135b8d855a311008b354664e07f457ae63f2c973e42758da51eaa79712990c045e75fc8ce82df3c62979534db22eb4fc1979fed33d27b6859b7b41bb8a365f4254434cda5e20f3944ffd55187a74d338bfdf775e2a3a6cbdf0eaee88adb2c45ca13312f9db8f7ce0b07a4236b3591af3cf9743c43caca33a5caa1ab2304966e4a361a1428c4ae6c33dabaad85b9b486c8dd8d397a3b14d818cef2899d4e3cc142d35596bf31d1686642d9d3a946b3905418c397545db2b05886dad491bc1920bbc1428135f1721a50cdc2843444e8cfc0b69fac46c6761f548cbc98f749c1a4584e58899cbf9301b20ae1b67589949a944e006e95a12744df0147ca2cf1539381baeb41cdfebe2880521b9cb6afa82f34690071db4004fbc32f7077c0d975dcaecbe227c0b445692e4b95449659eaef4da711fb46c265832cc450561dd8a0cb494e5ba87de22509c28b5aa426daf66d9760eab81fb2d058d3a7c6b26c4e55e46b251e3db0d28c8715c4c698546545bb91429eca6cf6f53a74fe1dcc505312ba3314e149597e57272b82ade62bebcb1bd691aa7c2a5d9ac014b225c404df58216b3227511061214a07718b836e0ddbbcb2883728f151bbbafb76b5d21acf7ec88173ebcc68eb241ea85cda9e0a1812d2fa7df2dc9e9efe1fb9cf3f0407de1a6e921d7cc7dced0c0c1ee90def96f6bfb2407f6a0bafa4d8f1672e78bd9c4b3e8a18908392d740f9e6cd2d3549a1650fe017789a6440ea81d219edec28554514649539bb310924fe0e3d75b3330bf414b8fe4d177d8a25ae5fcbb22ecd464410fbeffd5e8f9c1ec37ff66cd33a3bdcc6076d1b29a25df640e5200ffbea8f72de7660cfc156dfe1a2616601c2df992c2e4afcd6f5333444b9e16207f0602cdefc667cb2578e88cda8f6e1cdebf76c8a793c3ac0ff93a31a4bb640e1956446f72399f93036daf3160f5aa50ce23e775f6b85a026470c1b9917989c528d8959bf60a598f0a57ae85779f8aadbdddc4cdd8a2d170a46bafbb650eb50cd98157c43e715a8bdb097c031592c10de033944c191277b7488cd130f3b25c75df178be2d3589c3dcec6134ba6944e3d521c74bd31440ba7b1db2b2e42a7935fe6061dbfa07af573356aa6db2c6a8ab8d9468e26d9d86cc08ac1ea3350e6232d6185472b191dbf126f601ee57d84b045e8182c11e08879741137028aaa6df376b601d03288b69929fcfdb091890b3e4e3b9b4403aad2e6f5c33cb138779de711764ac4b085ece66c3ee55e7f35e5179ab1b06625a878a02f0a2860406d81808696bdd40a3b39c6eae514be5e5887b0878a2962e10190b1b330598570fb5c361c5c75a5f60997e30e1ff70bb6376c4c769393479283540501f476f459a5912308920391797db5b43fa317329b636d8f89fd4c0a0fb8474e2afeb6103767f8ca72090c71abb77fe0c76fa36870b82b6f58407cbea1ba2eabe66c8c7c0c6610ad58dcab4e9e822e9be3105fbbd72169f86a407c7b4e81e0fb20f69421ccca3abc53697086171f59a71e2ab899facaa636a407ba997b3cde12e1ea11a9a200a3c2e581ddcda562224b034dce52a23e0a541de8d4e237118e9d75b3dd03dc4d150b4f37d864ec00c26d7f8390d4dc2866f2525c00bb56db00899e771e101dde498c15d44fe9e1c364cfb71bbb7d82761468842b9298fe92f31a795357b543d1aa4007e079a4d63bda794c4b84e7eb58f4d196f0a78dbeb11f2dedbacfca1e7efa224844cd376f9335de3642486d792bb20ddd52ec6e428006d60283c1ba936303c5602687451757bbe1f24675530f654d3db5c07a5b120a736d25fcf365cc0db3bdcfbd336dc6a2f7865a2f88a82bb2e6830858ee0d55956c860db08605a292f8fe37ab7e365d0df07823edd935efc5bfadfecfeeb174b37e36bb60e6090bc85452ac06ba21849405080756272244f5884f5874b2086e2a7afcad5e12d5a41bb9f03b94d5a7414dac9c04c5cfb81b994b46b29790d1a27b5c99ce257bf5bd76bbaa5f38622ee6b1a75f8012a27d7458cfb3ea48737fb61e1256c189dc2693b633e1fd2e360110bd8de7f8a6fde5e025ea4a29e2f3b2242f77d6f6503078ee48c0e0b70c8f0dc3a6561870b86c72e49aeb39c995404f823fa9b6f22dfe1ff321d459bfe4b7b781ce41c7e0c9b3c172748c2cd6094d9297a5e013b54ff4247e73ce51975edd5e4829e8c83dae3a3d01f5b2883186ad02c5fad8e2437157cb24bc74ee70e5eeb84388d5f452446cbf3a5e6c449355fde317fbd8f83daf8a9474d335b12f1ae8bf36699c684241c4bb4aafa2b3aed0d7b1baa886d5fdc1cd1bd931b20bec6ce98264a7baa3e616b3892f304e20625e3e275677e5177f0aec3cc63904bb53a841146947723aa5918ce4ff34fc1cd9f8160ba3132ee020d079419af94f30502a1cd21b53029baaf84151d423faaf83cc78aac3b1329e0a35cd6dfa6e16c01199c00a6a08de2ec86213f8388a3c860571f02c3d42d269ac4616931e15b88a55e2f108fe0dccdaea60b9d45b0fe81997f26be0411480f1444597f4612485bf02305ea0d575b0c84553bb522645e1f2a9b563bef632ce8f9c7587842806a430f1801f6ea386554f46ee03acac45c10bd8b3892b5e601fd0209bdf782e594a966790869676f7952d3843789f57128a8a174c22054820541a3573c03a711e7f4069d240c482224a81e031daecc3fe259063516b6b78bede3f1cda33f8fea95fc3e0835025f47a1032625a2dec60e22340d804167f4be6edcd68817102f0ca9cd87e24f631af887e3a99226fb2a526fb740d54e7e9518155372dca7f8db31828bc29381eecda0107072fc3cbcfbc56c773ca31f0f4821298be704d4fa2da64255689cdc415be86ea326735bd8b8d852dc911a31ff690b09295e7a6e250d8aaf29125ddbbc8060f38b81ac714a090b8a1061c223aed506cf48586335877f0a477a897ee48b7de59449e50157150420a07c0824c1dc8b49bb757627fb6c6c2e408e21c3fa17d88341cc6e1b92c90b7f9bab2b37071ba57ec4d121d9e010f5fce992bfa065b0d75a3cb6f85c204735007978a96f0d5b796eb0230a0f6feb191117bc911c25f8bbd5db928715d53844360663ac56a2e6de98618d31de5f37bd426ab9fa4346d44058088cb8dd4d9bf01971a73580c4c0ea3dd4783172746f403fb90216408566c72d4effab13e481b77e506173a67cd10fe288083b18f9374c14c0c0946bed69164bb963a60f0c079c7c4b4a1babf36d30213096c5ca7919ee6cc4ec0e307b0efa8666821aba1b5c32975559ebc63e1b665fd3c753b247ddc860bdd06e6537b50bd88a0c62234c0dd22b5b01218bc5641d9a992a378be15da51e18a4e77fb877042729575a8beec5a7ed31df2139a9db4d7aa8e32405d30dfc9760483cd1a55a8bcad3845c21aa4298b07057d4f086ddcffb254c4f42e86da704dac56a5031800fb89543d116c25b2ac4f42a5385898d4d5a6f256280608fe3b9e2375ce5167c138b3b71cb85a4547cc6dec8ecfb84e143210e8b06cc324c2d973bf9a2575ff3b3af90b7012c6ce1db2969b40768ea915815565faf033ca4c9166adea763649b0dca1ab76599bd006c2aec3caf998eb507bd46f5b1f1c36ef7aee90ff8b22daf6b645762add6250aaaf3a6b345a3ebb2930723684373f153b1c4cefea9aa03b676413eac30ee38d4c134d36a8fdbf5d7ad9e11a35f57299942f5453ffa6fbfbc7ad2420f89a809201546e43c4ffcffc6104cf5f2449873c8ca4ba22b10b7a8b45ddcc7970c29631b31420b9647f60a0520cd9cb111e218b1be827847053c1222c87598ed149fb8e1636b917e884b75b3cda613e86de86b253d03d99d26558ac11751e03e41bb72939497e65f65f726c63a8004f18a769eba47b61a739d3a1095bd354c586cd3f6453658da2b911b431cebc890a26b2745ebaca92720de18c6bf9070b3d9afdf98d6337e10d81ae99742c36c191a9f7afb5c4ee4187de12fb0a7826821297ec3dc843675d41832da87a924730d9694029b345a7748f779e15aef478cac6af737921824dcb012b6f9ed67e7aae49e838610774d33f4422112a6df4f3cff403493a1f1e487434f61b8b83baf6cfea7470a2188bd01a1541c5dcc0ad5d888ac0100ceacad159c6ca6a7f486915e3ba4262dc686d15c85d3e6b75be2a65cc3cc27a3e741d0fdd448527c9cb60fc6644e8e2c156c45f204b0ef8e975449f5b1a4983cc05f55fbc1309c238ccad80f1292de853361bba539004b3de706f73c30f6946d6b4e03f8c73018d7e3696573c2f29416dc83e1155828e76db4b20b6f462892f2875e2071833e34959dd507d469b2492168d62d0e8d2ff82dee2dd8c449094ecf926cc8346993bf9bc61f67240117829485c8971ef45ecabb7eac6cd26daaa37b4cac58141e38ab8b8705fb978dfd1c1d41664b4b81c1fcf4ed068477cf17bc182bc2b8de3f1a16f38e6fb76d92461695a5fd67ff581f06995a1e9f5a2eb2846673d6626601cdb46c0b541e9fa151b4493e4d74583126ddaf49eaddb4c1308a4e73cdec928bee94c1f889a20e9ef5aee141b89c0efda5a3f75c3b598f43893357c0dd6df18d4e62e6a04f77328e96d313a9868c8dadfe2ddf5413b9088527b491c4b782f02d73ac21fbbc62f9331d5b4f02f9d80f64432e331634b5df5028f3787b881d708bdd4703efdc810a1a08b2f7c8a85b099d1ce7de686a3741ac7f6dbc596e06ff288b95d2166eb4a334266edd8bc16eaae8964b249deeb1fef33ca78d5d0d59ddc9cd7bd99b6ccbf12f317ffd0a22ab91df977e555679f7ca48488cdc0fa71921ffb63e2ccf36908ee3f124c056d5fd6f4c4328fb152a480964c3a483f8b0ad3d8a738917004c1d10a85137709440b1e4aad05659872a6665491c811b0cff94c9c8ab4ff449649190256ddd9ba7ebb3b48d6a97ee5a84b4e172642e505d16e6ac81f29241a1eb353c07cbf353fd96bf656af5af0829aa19242102f4417add93705b734b6466c5d4c187dffa705597e3cfe62b1c6af3dd122306fd40256685f7933b40e3428b6433a0863cdda79badd241d1f5131f359a01c02b6df6ed166c3b2ceb298c3e21e17fed932678a4796d1111b39f96cd0b551ecd14fe6123252f7d4ed7fbe37886df674f7d772d138e0a26b979f83b91d9a59da2b44c45e69cb8f907daa71727c072eb0625e1d8cc6c47bde824c9d725bf0420b46eb9976476ffe45ee06e3f09ce949c3322989138e21ccd3dc7984a752cdedbbed02b465d3ba17b725752c9e3e86b9b94aaf93d873bb778f6829f4a23ac4690078cf8b368ff874c05b69b6a58d9d75b987cdb77c617b67ffc3bd36900e3c5aae3a168e64422c59f4e2206d00b851821bd98b40bbb9927607007c5e039ed3313643b27633349e05386ad7326975cdfc1da0eeb5aecf038975592655eb49ba4257c96a0527cf930dbcee9e78931d387a5437e8c4d4ff0e04b4aee891183ce2112a50afc81eceb31a5c7eb25d76945e23103ac369a40614cbb3a43995a956cd68dc584b44ab83c89b1220585ed86d27d53e15d2afb3e6658a2a05b36b97da99962141ef01d9ac503b9c69484227a8cd80cd6cbfb9cea9fa3294f9775e2cad63a75a5c0c24f0522085b14d6a620c8b63562c5d83c0cd4d087cc9f045d3b4db1e6e79ac9344de48a54763e0883a18d157a67b2bbb0c0ee5dd1d79ada0a74e7a153cfa0a381cb7545cd40b4bd1ed93e90421bab28f93ca5a45f7b23670342588372151b92fc657657f32e90ef77ea93d7801057fec4b481f807a4474320cb36605cf2a2eb78b9a68b4b4dc330bb9cd0a58657e5214cb59c1435712ec836a83236f85588f44602f89c4c11feee3c279b284dc03c925c2ecf5270e3b37c27ff56dd8535f008186f05aa843230ccb794ec430701bd33bcc9a30a59f192244c92af1e82e6bf22153a0641b73708f17fbe1ad24b39a9499d166ea658f57c10f075570df14c251aebb7b838835b0918e139904940d869279db68b65f54640e362254f3e33f00ebb03bc547955556ad74832e6649edaaa5033cc19d1148cf36cbc6362050ae01d6707f20e96ae53ca1c27fd4c310450d25d05549959806db0cc2172ce4a104e76063fa1c08d56d7d2449e37d52afe0f917c6e08d73153f6c3cd33bc0753564ec2d9481e6fc579c915841754b1eea700a2722271e48aec2427791605ebf55606e55362b3a683c1ca6cd9628f4c614e9fb319d634af569ae96882857bb9ebd8b4115dadf1117b4ed9d2c59ecc478f2526570db5efab59320433a3ca25016fc028de681b60108f3464f86f5d9f6b9381fa851f1c423e403457a01a7372c8c49c1f8076b6df0fde364cd4b018b1eef648be14e2b94fc22ce89b64e2d25ede5ca682db9b6349bd64fd87d11034fe419af0586ccbb384bbe58749a277bd4438817914529a0b402e19efc8685be154f5215838270ef989f64dba8d6710c7e7304afd7500fa13f1453982039c0569bcb080d395b76824f58c69c516a13772e989443d524ddee5d5dcf78dd17319207dc0cc7f64417f4f2558d4773d656a933fac4b2b1950bb32d91794093c9457bfbf1e591c3ba2409f0e10a220811e65cf96c39d8de891f9dd545cd7be1c5173a6f2ff431b6de8bd95390303d150a515cfe9ed9f6d1ca3e364e8db059a7e28391e8058c26e88d6a7966d4f52de52327785ab31a8d6843ec0111b8abc5cdd558838223c85c8267d9c0590c96a7e54d65a1b0d4c87f07d41fde8cf8dbb4343a674c222baee81f25f69eb1aa2abc5701d686e0a664f1c6b2fe85cdfaf1334317520ff18268cacc536f94240bbb70c2730d34a29c305172c4eb13525809441bae32123b90cf62ce8d4e926528dbeb46ae031772499c377a96782b58d023bcc53e66efd2c2f388cfb19c3e034083653e63d80285b46c991596675307bc5cb7706cfd51ca4fa423e052e5918880ca6609c5211b6bfa3e181e69aa3e5db954cb8018d6f096831e48760c108c2720657c14f74bf1c5782534045f96be8c8a8e4c7f56b74ba6c6df926e5abff63f9a4434fdbbd77a989d05e0662f60a6d981e262e2cb398fe246149e9dd5a94e4b180b6f75cc4a77a575f4002b80543f7f7fb86e431c14cc1f95bc6f42ba0beccec5eef92b2dd9dbeaa4c0becc9fb8e7cdd177e23d21d987201615df6b306d01a0ca90690e19bd559c2b4e30f0b9a182065fc71e5dbe1f8542ac4a7bd0375210ccffef34e23e7ee1797e742489b1e2873d89fe4d66d0d76c4b7ff4d4418a1fef36e730fa21e76d99504c3adf0c5ec0d7cacdf1ab84d41575477d4e923e2c96215a6d85c77707c2206450970fedd0b0a17ca06c211eab266132083b8c43ad03933f210499438e45d8454b1fdc4b854eb5894fee5faac63604c07280aeb872b4f0ec664d592050774c0353dc93707967310de28193b68bb1154799eb37f28d199505af3e959162255a6481278aa9383f6940cbaa6f4fd2bb0d6e06230f2207a1eb7d5f91c43824e99bb92018f3fe56a7e1e53981e2173dcc93f3d8401581a0594b1284938ec4ead61165c52967e9c80f6c1e2d4bc997565e2d9e249cfcb785a8dca77909db6e2e231ea27fd94d512cdedfa1066001f07cc4bd22caea4d6ae633113b3961761092878e35bf9209605ee6d0d6852b23b717ea1436db8d93afec11056134cdb83ebb109e9cce98f42eb690e6aa8ebb23cc2d9e64481ae3900ef19ac21208dfa3f6419768cf535490b36b0c713d040d96e1fc9e2368390a34baaae333f94e90e0ff7c7ba4e3ddf2534f61fa8af1e845935738bd6095a8803ff75580caaff5c8cf1e540b41af369131006f5f48b1013a5dd206e860e6537bbc35fc6ab827c000e46fe2cf5c6af5f4eda9a85cf772057baeec2e2aca16785850ed0e359512aa1e25fa3cd026b5c3eef1a89110a980aa5708f42e72c13903f278c3143a2d7f87f567ca1e7fb40b0a8aa68fbb7e184116d9053f483445c56221a9be17f73f501fec3785e86c8c75b677d483c613b370a459ac11829066d09ece0c22c3287a381f7b9abafd1c018afa361eb61a6b1ac1b21b229b2b01a2cf90a3c7a65ba726ccb207e20d9610320011d1b997f18dc63bc0281bf11e4dc3573510edf900f14eee1892b8f589adb71288f22be880501c2a5d0f185252bf0aec59b87a4438d4cddf350c5b16475ef82734b6a03ac3902dfb9c79e07c8f3bec53ce2acf73a566e739ceaddf0196b2458617543a0c99980dcd8c19ed49e07c36c639ad618b8b3d3f44634e964c978af285df8c912d909984b827297571f6937a1623c6d83f8f7cc7cf6490dd823a02bdf3593a0b6a587c469b1e7f6a4c296392f278632b54b1cb6de909f15f7e45da1866a28e5392542d9ce59b9374ff553fd7af5776b3ea0bcff35b2d65a9510bd91269ad38851b5bce6ea7a38d3fb0db944664292515282e85b05fdcabf0fa4849f878fcfe9be77fc65862bd0b04587483b38521256a7060f44cf75eacd01f377fc3250c38216714e24ebf03dc43bc04ebd5999a91808fcd9f21d6b34865e01c1b35dc2e0339d574670e4a9c9873aa1c28bd894af9b00b165257ca4178b796731b3c3c8163152ced0b7e885d3f87283ad0284611c9b60d731ab5a8b99bf7555317abf1becb5d03e498f90b41d50c1b1ce7ce7ecd971fe8554678bbf7008bb4ead6b4bdba9856f921438a454726d21c01a3fc86ecdd316a854a15bdf0834b1407362021cf941d8167f8654e7a9432ea272c009c3c76c5101186a7662f16a3724c868ba6692e016666c83af8fc2d423a0370f16c6c426f4f37fcbfa7cab1fcca20006d9a982f6cd449db555bb066b2a785c0f8478be62f94d38df7f01de34abf0a3eb208d6ed71c2e1a62ca37470289a2d54a8419827d5e7477bfe5b83d809be18a3529116d337efdb1cd1e89638c3de35b0efee2ae0957a072bb6bc4db8e1f6e39b84cc52b9d8ca646a69c42474c475793d49f2d4b932411dedff0b25aa02c10d5720f4e34eefd348fba02e2536a071d4cba1805dfd37f0d229fe0726d75d96ff47e4f4009f67d2c363e9138685e436e8514ee0f9f661871bc3f52686d55179ca417d36e69693a4dd1a701881bab4edd79ce1c51763285864d00b730474f880b1f642c2c93b582461c668493017a881ec120b6922009eb15c52fe65677ee3d5110d2e98596175727d427be9d6e6b63b4bbf3db2cabf6afe8023415a3d988715d8deb4bc4f32130ead91bbc6d0eb7e4d5882b9fc1d07bdf6f4fc46aff44743c7d45bff46c6668fecd996b52870bda0a47adadcfd57311568512972830b2a7763af3b4e8e9f0c5aca1063348bd59ee79f4009de46e75281437a4832744f2802fb94e462b9130a9315b70315228503388dc904976b0b7ada0d2f4e1a87e81713dd722e0c0a02bc82df5156a485bfe468dce9e7cf429ff1d37daf841282915fda248ebecc84e0904f45f179731a0e4a128b754f49f07973ca22003b32e8140513f63f87bb07392b66c4a3ab7fe96ae9844994f5f6217a586c7bae1c05376abb8f01e9ddedf4bd60a4a2a8005233d6cabde6b151e641873bc0165e1bc8e0ae8015a822fedbb5d0a81b2f0b92b8337b0c3477dad510df72459fc9e5acfbd0fcbd299dd31cef01ee35fc46bf42b75b66a4c9893f254d17db2ba6113e089278e4c05d60a2cb7352143a3b33b6f2562b30276d4457b0f08245c4381884be8f73db855b521f09b49663d9ecf891be393c72dbf34fae698a6e094070d266b6da594f88ffdcec1df478066a6155b08ea4a3631029fdfed8a5ac7bb878af868242282058b100c93c3b2ca6f83edd412ff9370beab5f2b34d53415b8086d6b96b6a9f0ff78445f05e072204b718111b3cbfe2c937782106fa71ba25125506420e1720f3e3a2313ca2a171001a94b8803eaed5e91e92e650b2058b5635bd5885efad62b6755f7686ebcecc811c090d7fa1e7ae72001bcbef0be7cbf50496bf475e9b0fe3ea9b421e95a25f91d41356b4179b195c7ae3e2ade650b644ccedd1444ee36d208050215e7bb24725ce82f417d829690a3351f44e8e6a8199a1cedfe1a2fafb437ee68aa8f3fcbfa2d08708bf1d0e80118c951c2dba8607d949c48288586fc4e0a436130084d6f97d7c6d22b70be013c8d17ee7835351202ac8cea7ae4c78d2096ba01be5ace292c61bdbe46d544cbfd499458156e0ebeebcb60acafc36a0ba80c04a301bc46fe0d3361f693d49137bad3a2ea72d246bd3f1d220f2865badb1d847de521e9e31d043c836a1e4612e45f146be8f20c42aa0deb766b2677152dc170962dc2e009c3464bf8f69d4dc7f21e50077959d3497b9d0f7fd2d692aa40eba1b63cef7ff71810fc8f79fc6236395b36f4de8a15d22efa74e492bd5dd66c01e8ecff7c7134c0fc120b1324f23446a3b83bcf1086680f43ac6f827a66562b7cccd93cfc68668fafe400ab6338e59bc0b8dc3b8788629dc703e1a19bcbc0ed1acbbf3882e4573b807ab559ba215996e047e6c3e6d1126fe38569081660ec0023c63b07d7c4897191a529fdf2c5d41f5b3053d094dfb80aa0b93792903234f4c46373be30137f03aadd888bbbd605dd5403514020dc3700ef3df39e291c9fe2422301cd01c3037d2577a7456ae4a546afa5eebebad2d7f8e606cd58373e483d1be21d48e4803e8eea7a9166f4a46329757c0e9a4021fe2fd0902c396abffa545a09fc68d7d5d8e798dec4e5e8013fee09ea98fcdf3c92c0283f14ef63f5ff23f426173d49c2e2330684e3f2da87584157b1b6e0203e29b7cd9fbd926a81c684fae20051c9db3dd669f291ac0bfe5ec760315acb2d55dbb87289117b9a95a038c549078f91752067c9bd928b44337b12d04f016c66affcb09b2fdddfc21744da654ed08a829f6a7a60b686a0237e40dec9384ad7ef18a31957e3183b7bdb305b5f7498ada400d0b80a2a3519ca3840aa69547ce78ca28637e82843c9ee43cef6cd5aeb789080871e7757f63a6bcc03e1a0fece844300df834dffa0de4bf99765fc4e1ebda91352e4888d218120fb7c700146d9de99b0352d4bbf3e3f739da1f7420bd95d70731141bab7179c7929bdc78d08cdfc9f60f16bb6d63d62f95c174908033e059895adfaae65380ba38f12e954e7d7c1ac4acd4f7a1f038f5502ddd806293fa96aebcf51b9701b45b664f185e014964c4c004085f8109971664e2a7a4a730854d0cc8cce163b7d50cf12453c49a86b845efeda4621ff63851582ebcbb7def1b78adc5773df09dc23e7fd73f093c257bb0af1ecabfd7b02edaa45b4e8d21ce14238146a46a9e6e139f67d8eb01bd4722a3c3b02c583e5c1e01f2b166eb1ff72ed166fff83873cf08fdc6aa5ac75e95949eb7fa45052e56e1cd49fd5cea78685c068c62e199bf56a4c34f0615e4fefc016e396d37d0fedb6889c21190fa9a92b8a48ac14592b9da00ae7a109299b04d3f8d54641d82951c913d93ff6c8c1d423088a8e42aff1a3d83f6683d07ad3470a29d0d9a896e6808bd68a04625bc0142233b43ce0fb4aaee0a6cccfbe2de12f60d1f3b8ce3ee70cccd29a980cac04ceaef119c12e79fdbd63a7e9022988c1a7948b707c399bcc8e4c9b9a8b46ba0cb0bb94675096c3d6f6cca0a8d301653eac68c8a8d8217ba67cd8d293bc686aba53606ca971edcb23ebfe61696210b27ead5a5fa2f991a9082bd8ddaa1a87007c954a9a5d5151e85fa7da2bfc577b12744165484a32c2824dd011797bbe85d19202655bc303e659a15c26c506d639e949f92a6dd47046b7a783e020f373ff3d61e1a6457c759cbb70e3b206b44a9501bc8a1a428b3128d729c1549e72fd5bff36f7a49eda42d92bb5feae3bec9b508e1d739d8efd6c13486d08703b05f6c30db754a66b4a45e2c3e2fd40b73c569f2979c3dfb971fae08fa14e2b1cf3dbc47a83cddc0aea77f2b2c4dcc3c4f99af2bd100e43e67a4fd4b719eb656c25ea1496e8854beffa97122cd3c69d930cf33c8e5665157ab1520b8e8e17e71adf8df55b60fa9f8880fb299d1dea26edb82295a7cae4bd5c724855dc8dc93fa4f00e6f8e7b0d02c802505780725bc4dce1100deefcfca883a8651534b4728fa347004991efa86495b6f8c1528aa910570c51756b9e1fc54c9598cd2190774e892c9d3f1b703ad40024f833f5319a5eda11f62948c0f0f9383394acec44d818ed59ad64cfc62e17de70b85fdf84775d47fb70424848b34e2bbf6593f3e6e321f87626dedcff01833c7c95b3f27b0425249f5a98c6dd597cf9bfd5ab6f6ef4b87de2e986fe49cb27f4e4f06fa3156f824fc274fefac3590cbe4bacfc65eab1167d506f4a24a8723873bd8b2be2ac0f17b601067567ad4bf23a67e700efcf5fc19875b14c78b0e8ba5695b8a761359217c67cc6d90273df0c70688bb27eb0ad79af947fb868a57b108cf1097e3d2231095de7c65c3ea7fb4aa5442d3524b568029b2cc52e884a9f52b1fe88c365b31815f443fcf76a481db304018d6b3e472f53d33f5bbd2dfb3c47e661fe774ae4d0a05c13821056f6c80aaf3d162755c707952d8763564f120d2a2de3e211aebcf8ccf0ce4c2ccb9dea0bb0b5835982a24b618229b5977404f88377ff8b35231ab5878d40f0c1854538929def8003d1cb617f5e69da7bba85d0efffc4b7f86db1313d2f1637c39b397f078f9c0f1b36ae290515aa56b94d94bf766e886aedb7131f991640d99fbc05fe6e94e2d6997ff7a68b73d662ef9b2ad34e17bdfa4ff00f7cf43d9bea33d07c2634f4d01316fda0e9450f159c0c42dc2bc58c9334af021a03a9f74a66e4dfd2ffd8f39353ce5028d2b396220054a208addeb6547460d69058c71a5a89431ab2e9056113e401a7565cba3557e2801aba216ae6c79a499383e2adf4c1a96e20869b87b21673e987bc33f18dd130972787cca9c4eaabd6d14aaf261e85470b5bf13885e55018784382f270175e6e3ae12060d633ab9922515ef1a2667a83fc14f897b63d847664fe596d4e55c9f7960283cec0ed35162163d8b9a5e4a8ba9a4f6c46178131d44cd1a9a1135a70331ab9369a1002a99d5ac01313bc0ecb39e85e759fe82cc632a262ff2e1194b2993be8875fca36d0716892f86c08ed5587682d056f9bdd8a4b25350c53969185a8113150e16b87ac375bbad83e4af2c0aa82b2e22d4f5c902cdc46c1ded7403506f34a54a13dfb95670087d01a14d10466b6d2bb7bb00a24ce0e0eeca962a210471804c2ba3891b2ae88d36dea5ef9bc37f15e9d91d26adf470624901c0e66484e158c2a34f126e7bf0eb51b82f49ba0d6620b05688903f383ee8c37bcdc51962eb6f4724bfb592988179525732f3b02a60c1da48baaae3b2c702f2efa531d5eca2ac3641d54495d53f2399fc7043f12ecea2ee433a3ea9930406a69731070d18bbb9b98f92587d34643ad46c7284e8607ad1b06e6a0fcc7b9ebfc3f1a3a6e1fd3be3810584656a277d1de47a180e66ebf77080cbe448fc7cec0aa7b9ecc79370faf21ec4cddbf63ead031b0ab6966b9640d8188bc27355c3a941ebbdb94079bd709e149bfac6f3de89398ab76515d5b63ba25348fb4b06e4378a11cbaa4e0ccd811dde97fb8accdf9ea40377fa1542a7768a0515bd4afe0be8c6de0c1b54d215851f14aa4c38d304c9a5ded5a7a394650e37050cb0fd26382686ff61496e919dd17072f177588eded98049cce47c7230a87ff5b94e063387caa82be58f994d1621fe902c04af19d056aeb078f59c53c515980e474811a94a51629ea1c448022906a395f80d3af32820d0d1bf741c3dd53ef67d3a8bf39ef63c65730998efd912a6900585ad6b5e0da43bcda8e184ba527388c2b0ece6e2fb7fef8d13c36c3fdcb954a8d339d308d9aee42bf57258259fcdec81973004b7a63dedcc123464df297570698a0b3bcde030a5ab17f4771e5e0b125d0e7ebf33a1ee7d7c0a824c0d1ab9fa3a63312192bcda6b466bea85554c70dfe718a03e128b8a6c55e0b2420a0238a08f698ebf4ab2d2c8d2ac85f68fdc6c3719e8071847bdc15c6f97d886ffe1438b689febe2bb2a60b932b76534c5ff7fec9f285b5d352c1860a959ac8255f03614d629d1c76cef31ef80a3f48bd636b18eb0e671a86afda40c1ba7a8558e7f3d11f204ea7e4246ef584cd7337fde0e3e4a2f08d82cd41d1e2bf853ecd2ac77e2ae88489df5f860b0a4b41aeb9034c3cb7b0495ab15741849f06548d5d5bdefaf2629c3f4abdded3ff2f4f1d77426dc522fcf7b7aafafc02239361d896625155b87461ba572c6432f98a6dd813c03ff685432567e0865bec92059a57cc8e5beca32ee62354f0794288a89c6abc81f787a77a7faef0ddd88ca4ccc840ac1a843cf5846b3a589c788190fb1f7e44c748aef8182ddf63c4d750f8125a48d41e108cf03f5f6f4e567b367ca2d22ed02e2b347c535fcfdbf5ec775400606760b0b6f74f7c2492eb0388be4caf5be336032ae9d0120793a6fff6eab157fd9a42241be67a634956ef79c676dd3d4fdf4ca4fc88c3d1c7920be8f6781c1a987d0fa69b98ca0c9ed1adc8af9b5ced4e89261fa30f9c9dba1de3e5ceab13c070e4beafb268c16a3a95c9dd8a3b30ed902669bb483c6e6671285e4c44a4a74d765cc9f28951bd62a831d0511d173744f296e652414ab858c467c5fb3a42cd4b3cc0c386d06ae004ae5ed2e41e34840b3ba51933051a3579baa7c5512f5c881c52ace6d1371b7951ae07be075777b760f62cc83d52e16474cbcff08c9e9276f18e15423005536f130079028429b2d0f1253314972c9ac6924b27b000b1a9779e86f8cc8674466a58360b4a2947edf4182fe43b091c7571df4c518b68417e4f154e957913f5a3d3c97fe8551f4cbba9452d790c77a02c0856eb9126c94f99309e4fd248c5d8b88f407c313129f94f9c5dd3bf6f2e4099e079599239693697a8a4f1c78e8194d946cf8e8c8862c046738acea1b8c2470eced5d5f06a23d2da6c8eb8e59658bfb1d46623b3e87d508684759126d428a939c5e7446bdbf865aed029df164b43c4dcb9ae48bc89bcf01bf82eb4f88590e7427a5a8b006d482804cb304c5600a46222303996993ed36ac7360122d0538e86d8a3156d0d7442e5817eae3a72fecf4f7a20089ebedb47d6e29bbbdf1064537829f2573427dfab98d8eaa161f5d3994ef938262a968df82bb1d1c139172af91dd25046091793bf1796a498ac3904f56dd0e33c8bdb2b8c4eac7686ae35aa9afac62dbc8a32ad47f32733a219e2a7aa8ac786e930619745ac125e53dd55c33c979dc24903e4bdf599e59eb606512ee4fd49d3eb39745e5212709966ad6cb69c57796f261b333e054016ee735390b839e6a57a649a36ba988bffcb8881c9e4a4c8d272673a4f4d41903328e05767c8dd2fbd5f7d840a8f30d9760737943b759f18230cdb569a95143ed88bb6a59f277beb726a746d407f84d51cdf7cdc8bf6aac1f1a41c6a3977c0b059593d6c8d11c7217efc7feb56d2849ab2aecf3639fde46a4b3fb1daae25ef2d84c72f997945aef4d113d62e319148f1554770a8b2aa8556f178a782b0e1455b0e69f088a226d83bdbe6a6bc36b8f08dadb328d191c326f79f24a5c979122f81fa4db7589e7ef2a5b37dc197443d90f3cbac851d03ac5b34a03c5963b99b51ee7ad282e129db390d449d06f95d99e26538fa68c8b98a1cd9b69dbecbc40cfdacb3f0cca29b6d5edc95dfd2ccc1e318f91d7af11cd35010d91bf8d1f314ff2ff64b957695a5e74126d09a46a25366b3300ce983bb373934557edc8fd4d45714f089a130208221993647df10830b4bf76c38ac049be218916567a88d452fdae54ffbc733bea4b42d0864de3e87c11cd8d047aefb0f3293c1207ca2fc9c016227fda11c4aa86c8d81474915f2a67efb1172446f8c4f9d1aa1b3d7c293192604e7a49c3ef5e977570e280ccd106672c2c7aa5abc1d2b15b26581510864f94e2e0fcb7dd866a42363511d32319cd1e383c0be55c82b72600a8c369f2da87e8238ac4f4c8186418d4eb6166b10668670bbcdd743d1e810882184442b9c8d38dda6e6fd852532b6849c4d42b1b32d88d403f17a54383cfcd6e65eab87f6373907d53e0f73eaaca3809d5f3215db09298a9aa823e16eed2e16eb196a04d5a789663aa5bc9ed602833c1a13a3d06969a659773e4cae1705d45299957b401aaa65ecb9a8cb79267a5ab2256d0d667747872edc57ccdac2891489fe75b930d602d8788d5c3b4fdedfcb227c3a2d4fe36a0b39fe603df1e3a3e3aacb057b212940635ce1660b1b3a26054a96b3e6bc142c92468d8f41ef138f5bbdf167cde3cfa21286a810a5887343b192a1f7364f582133fbee2bc386b5556f1f42d691986837c79f27415e1ac36cd19aa8584129824146c5d7c041b8ce091d2648a87c7572ddbbe55610544a82c6e2844d54ee7bacdc59b2fa7d3dc3d9c1fcb81dd4c73e73f5a5c483143ea0e87c03e391a9ff2ffd901626a2aa6356728d9b2719f65866485d03d56457fcdec5ef393e7d8f16b3b9212fb024bd55b6d1b644f6b3168512908e1b50c075a149110c5ff5e6500d25d5f64512f6f9d3186809594f08bbd560702b7a8c2cc74be59d5932d4f8d865d904b3d9239f4fba35441042a6f6e978e633a1500f8ceb801065225e4da52c85e84a91fa4adb3d8c672f3f8306026cb9d72ed2a7f201fde9cf8b9555875582f2e7d5ef28f37c56110cddc7e9bab307ae0661febece51655b8f6612027a0db10a50fc39d090889a038d394cae6fef4243693e9353df726f51c1da37cb3bebd7e6f5858437f66df31ca3042da1aefbeea6e331130ebddb9435188ea522311b85e6635b287875566be55574a0245293ee2b1f55a36cb206b19f5866933d26a7f3b68ba2fe8435e1993489b355662faa67c1e49b57ce5e371ea312631311d9e51be339850d5a2355011cd9fbe5935ce6742a930cbb507a6fcf9b5b2e2e1bf7f0684dc0a2b88bcc52f72a1418e307dbf5722d7494516bac66dd88d304ac1fe39e7f621790636961b2cb35c0882c0c514b96ab1373a9f2dfded895510f243fd2f9ad5199beddccc6d1adb9c49ccf4bc72685c65eaf883133302d7692391aa255b0832f9fa288f639909424c59c3c1979c61cf8bc5dfb03efaf821b29377bbdb0b70fc63a6bd988df5001915f2f145a1c630de88444e5c12fe073f7aee34427ed5e3be9be703f5d890cb9beeac504e9efa9212d97d9018e7358c17ea7bc3031288667681547ce996775eb5503d32edf62cd4f56e3d658ea170f7e97bf08584345f064439122fb8b201fd7e6db7be9e43a7b3b8efbb3cb5502cc7de6860adec4e1c15bd02050bd9307b848006bee3f9e27edf711b4036439635b19cf10325646e3472d67836430515be5e967201725e00b902a7c93921a65a806e64137e8a3b100b928156d341a18de3451534a6b7637129fbbb077066fb455b74a569f23b222f4950961ff1ad7b9825276f4af9022ce32070224b23eafb60d0d494ef628a9db74e2ee41f9fe464dfaf2916331990917381fd168dc2dcc04d839ef323e8a700eb621862532d3b81d535babd6c4bae23dae0d6f412e5e9765324b0416d6b73f5909111e0d3edf86422b7a51e5c709b02adef36ca50b9d5dee3d21354bc11febb448d9d02038acfb22add53507685542810621a5ce877b76956546d16ddd814604c2dc6bcaccff186a6a7acf50421b1336c4ed8db254b1d8b051b2cae50833823f5893ef3bd82f74596a68e484eb4fc903a949f59047404334771961a7a8549e361059e03449e759144509fec5cb9014ce2d2b92e90676eac5a3e8cf7663554e829b5b21878c6125213d19b733cca501771a3b2ddd0673870a882e3f835588bedfd8befcc0782f8bc88ab502c3428c6214210cc2976c62d28f95233f9c056f628f39b8238fb7b92afe9fbb68485f701e16559d9a31849f9b9eb8f399c0a34f1b010e1b105b02151f780d2b846732d65a7230333885a1e95308363743a2a5bf234f9a47a2a67a218f0da723c1b981c1569f737fdb5a0bd3442fe53f2fecebf9f145688e57a74417da40af87c2d452e37ecb3e883774fb30870ffdd0d6bd47014b4a0195fda91a44e21b2cca6765f78d2e528553831baa0e03bdaab7b3aca91cbeb562ef7de30e195d9d8b701786cbb0c2f3aceaaa78ac89a46b5c3ab91a91a0a0698a521d60ed09130426af810d389b3a77918d60dfed650bc98a37d48cef73288b75118e887e700818ca8d3bd920057dd1bb3937c433801ffb02e28459a44ba8787d39648c7aebf13260b118e7e2516192404757403b41d2732969ec51500032aa35dcc2d1634d104a471d18961af42a27ce32cf1e22bf04b015caca42ab066d955f7785d864128b95420b47a6833869ecfe8bee64481de508a4198dc0be6bdefe61af52c3c3c1cd8df0d52a9a44d533ba9d4551c00ccfb56300c206fb3912b60b573d6f4eee919494dcee36c7b6911e4f9993ca0e3298facf8af2ff5ff24c4c25e71f3faa2dfe4c850e40b831b221a2fa8e8799d04e74bd687225a437bfa409cd29614b59331b11a3f53cd23a5ea7d53bb9230c6c5932ce4f93d50be5fe414b54d07c38f2d0ec693d076137b8631695ccd9540b698993fe018d55e7f44ebb74f6f93626ac3d09d4c87d5e578ddddc23dfd537858a71426ddfc7dfa8b797b9bb39d0886bb12fd8f4dc8d499dac1cde7fbcc502d76bd7bfaff82ee4b2669150f12763fe3d53e38d0abc3826a92ca19bee9c2b1409d6e53f12b39d8c830540a704112374f94d9913ea4cbf0ffdec9bff9c5e98ee7ce03805ccf3f4fd315863c187fff496c219f9f665d7bb3886577a8b1901435028acedf72d6f5f21ff2333861af36a591bc34f444725c8e739d919b59b2a4f2256ed0626e3b058f23eba20a31f7adc557323e8a63787c457bb3c67b8e94c5ea3cfadf36fe6cb16eeba6e340b1d49def2c1278db820c2089dc1c98303be9d3ef5313ba274987dc4fcfef0666573d0d28336573a206a01c8eabec7524716acad60feed746e2bbe18b7f32e8cde249c76c115e24ed186c957cb452d4c68ae462b8b9b6a9e9441d2d5af033ef2f61a3d6471c06c1dd06723af7284b80985cf0b2ef2cf9742844fb84a5ff787487c91afe7f767bbe7c18a5182ef4f99784eea6e4b3291ebc4e104a8ca71a09e6e297d04d0208dc953008d743cece7121b60d63f15815ac7fab2dda6170c5784be28e93da6770b8e28c483794d6537cb586680cd91e646447972381b60d12b8d924133d21eeb9ffbfb5f7ad489113c3e0759aeb21c34bf370f3f034b5cff953cbbe533d3d5b780a35cc4dd1d53855f4cb68ef174113a4ae85bf69e1246ebae79fa9fc8fd33443b5bd09b2b6623fb4f27c52e7841c2aff86defb3f41aef7ccc48ed334999071047e080372f3844a680497448c5833aa69ea6e55bb8dd8d3ad7b55cc282fcda1e847483235494ebb099ee5d92dfac2dcab2865a6d49b61215b416c5c814ce4d481044b4eea47e5a0a56edac696c46b31fc08ac58e12556f43b779af83bf690f06e4f026a0533412417e241aa3dcc86f202131b679b188a51cecd18b78ed16604114ea8ca056331f7f96556d40cac94928bf47a20800d85218072d83d8fef8acf3edc8d68acf8d9b59aadae4a8ce2369c00c9a86f342a87b8d26195e73a30684d68e9c25da4bade565808ae06c73bdb551ef0c4cf932fe1833dd6a3fc5fb67619727a81db88f24633921a5a5895ae786e495f6c0769262fb98f9b6bda626688230fdfe2a2a85fcdf91c1d4710f06beca78462c3417f1999cd7b536cc724ca482fa42bdc0d6a5a55c8755f5b367914e61a73dbe966c94f9debcd31b39673f6106fb0b5d012d2ed0eda893d2d628ceda2c14ccd2e38e9d898e0037db928697a3169e8dd057188aebaa89a5b498b523ffdbaafb995eecde49d5866d708b1f785ce9e048ba2188c1ffdb67bf44337332d9c4373e55200eba2b5a59948127f250047e2f6d1c3dcbd2d15631a79057b650452c7c9744afb85ff539c011ec4bde030be29922dabe596880bce8fdae453e2ca7a256d95d602cc18bd32def8c8689a48294605a2c1767c20f8332fca9f15a7f635cd001e505176b81aa28bdc16e65910854177b0cef3aa8b5b77a8d3b0968b1b16ace08c3963106d036c01c241b0f70d07c2742f2ed88f0c4a01f01650221aa93c63084a9d88a2f36aed1b58e3169253a9b84ad7ca96f43189accb811b8aafb15dfd14def96f14bc98831cf7dc03e441dab8d7c4f16fa16807ddd06a31af28af6fc5b18355781375c6ccd1bf55b5335778d534229520be1a297f10c27f6ff1db50f4a1a45fd3be69ed0a6cab7ced89f42529bda1037858cdfd6f532e5fc08d8c26385e0da8452a7d815bb401a1a7f506e119b551491f5d9ef337def14e8a5dc4f034dde31d12acf7c637eb63f845467f428de28c99225aeab6159cb9f886471e656ab6ede01ad6857916093c988bbc7c7c91a15d9219fa2feb3c77ad3122495e2eaed34a73f092d7f4ba5da427930fa5cb10dee54494abdd3fafbea4d9201cf8e91cf87ed398e104d26f8c57e7af1b90f9cbee1d3b3946d7497286a0c29ffd5b32bcbf14d4918765c629823c54020e8cb28c2126ac28d99421d8eb0fff75eb8e995b7f78127111988314150102fb89f9d29a5ebe0c52ab629b71eddacc24e5044f869c01938a3729f762258f69a800e75ec68911407ee2469b4dd385c9942f35d1209ccbf083e1c5fe61cf3ada7a8f072e82b9b4b2a91624dbbd005d6454d7fb887b57c3bbe2bd400b9f63e3a70ddef8b86ab5354384739296ca3d04eff42de759006c2f476909ba9a31ae9a10adf1c9e86828b98bba0e60d2e98a287c2053c25f399e2291886219391f895001e5d0b8faba481ab8fd55cd6ef9477efaa30d2c9c82a6eacd23bbd9d348d210db680babb5965f46eaa92fd91b123a441e81510846938440b3f043fd5c59b47e3f0973b7d16fcfcd1f52fe4da420a75aeb96bdeba770a409f25a20a8df6bd3b75387e9530f3d16ad1f68cbdb3bbd609801662af8fed0a9534eb6931c20f6650c4d027d1df2be166d76c97dc287afdd7277b8bf4f4db7a9cf63ad73275e40516464f97707405c003ad6b3e8f9a822a333afbbf7bb079dd22a0d62bf35f33418aed1d44774241fe0b00dd7f7b95cd96655a5bcbfcfaa4ad0847391c49f424c03ee70da2d825442219a0c6f4f5ec1b19ced768f6bad1816787f7e7d9df33903f18ee0dd379afe61e7829a03ee227d136b9b34d73d791c8c2b18745ccceace1ef2fb33925df74cf0c35a01a805e1da0849f39ce0be9875a2716b74c24e8c4f9083ce2e40d6a8c79fc744c5854ef1a61cb92d10ecf6fb46c983d83d48a3836a0d006c5c1d94bb580230d6fb0059c9e0c597857729895a15ebe63d134bba8a9b2a30c46a49d68c2a8bda1492000a4c94ad8593029bb2316b495fa5aae169183a6c03929afcf0bf05b5fc1ea133cc2dfb60bb40bbc2e77fcd5f1dc138540ff76cd474ab617f98c4b906bee3723bf578df26cdfbde641d4be3ae7bdca2c8764a98b1cd6e25a3e0891782412ebbcd53619281596aced082811e33aaeff613f4b495fcd9e9c1e74c26694c0060f03494b9183e51f12a4464097af3b3e07e958159a50b7a0af8e2caf67b7021ce968bdfd120b42e781314ef2b804d051e9ba77aa7399ad6c9403127e4c78ce362532a76b850810c997537b2965ff775d742f8be3825a95655f5b06a3b3361e4e5b49030400ae6fa0565bf2db0e60165fc11d5b827ab85f385889774e23d8860ca171f4366d92f33ae2a62e536553743e5569d8771e4d53170402dd3c5b2e6a5cd313fda0cfaee08d34dfeea1cbfff22b5f097d4d377ef5fff55b8694a33af0498fdf49feb04ebf7b803df2b56f0f2fe8e2cf15e53b713a55e0be75944f13be1b0045a2049089c088e572cad060b8a82e6f6e6027c846a47e273d86d46f8ada053da611577c5c1ae340a4cc605d404fe6c0a92a6552458946597c6c1785d50bf0690af422c77c31ff18254ce4220317952ea0aae7465fe4f39709f8559b52df8b55be8064566a3b4a31e6bbefa29c1b5db825f4eecd45cf48490252c4d09dc1e7e09a1dd314860a71b7988b200cc6f798ac64caffc6cc814a78077b5f925e4141bb1a96622a944f50c8882e4c045d453c06eb1115576e6af8c16c6ef430e2d9872b37a7cae8b2ebcc37b62ad313765c5307e34fb98049e1aade16160933703402ee59a92e45713069f3ab9a25725fa4cc39ad90cd0d5d8e370d65ece03ce7f90f28232e06fcbfa804343c7780860421e2031509ac4f3b022a11b5b80cf9075a3c61be445a11a7dfe0c92bbf341295975f3ff6e330b4c89be1b82a88a3430a49465e07b14a9a2202fc5a8859b4bb05320fabbd039397f52cf361073d7ede594ec06cc5e22e5092d66a242e7bf9668d785fcf26a34706753825918e979cbbacc5aeba2ebbb64ff4067510ae1941e74f5be91bf37d51d7f9702440cfef9ef8a63424660fe399f96cd0dfb3590b2049b579901da763d1f46bb1896abd32ce06a031b19d2cf6b8ccebfbcf3800aff4120630796ad6939e47797cc200f694f8ef564df5f3a7f04404e9fab3c5aeb4ebe8b76938039c88d7de7185be33b0bf9c69e15b251d890376e521bfefee9bf7d980f56a56ab741b1c4fde33eedf83037523400a4de62a2645fe369a32e35067928539c91fbda4ef5d2b3840d45c0987920f1b85aeb25a47c27e04ebe833dde3a16c86f3ef95ec5aa11f2f9067748e563fbda078f2b22483e6e322df80634dd5905beffb8420f0b1cbe384a8e984439313cc75d6b9f4df37219d987d16562cfd549cd69608175088c9fc59ffd62667b28279688c16ecb0f5297a65deede595ae1fd68e1da6f8d27c765091e56741cc407a49ca802fd2237b7232500c806f50f941d61721a015858be1bd0d7afe7457f03f91166f64ef7a79af6269be9ea366c014e64a70e6ffe3e5ed5b8bc339f6f65cc410043ad35b88203f68e2e09e7527ed1898e45a71e9b1fd22d6ce0a0916924e8c51c4070fd2e503966b02c03cd13e08e19aac17758e145aea83257bf68bcdb994ce8948c0bb8a9eafa1c6e8c757e8f085bdebbc28d1ad083f546df4a6d54762ee69b77bfae6c2577f2b93aced1d5a3a867de497c984968c812f8fa8635068fe072ce0b1c41814cb2cb780a8d3c19d322fa2e11295920f1e620a1f9dec75f79966ad1b18dc58533e1d991e20d533caca2a7d40bc16c11e9a43b1fb13f49e05a98ee276d996be432b3b51cae3614af8632c818bb81889992e4e7f74dca46583d8874167e674d6e1fb6b3d3d430d18f66b95920447e7ff336d5d3ed80b8ffa8f7f502c097304914b39bdd00b759564a720e3162217c1c3771127d582c0b97439fc6ea2b9d6265e8677e12e42930e7fb7b92cd686ef3e2f94a1a4c84322764c494b396e8b608ba6b0377a6e0d6504dc4e0bc90d959dba6f9012d7e8e83a94c6257c199e67e5b6f9de0bc97fea8b671e93ae83aaa3088afb035ebc4f7a7def83fcb69de3f9add8b62e115204ccc2bb303af36be86fd1c050fc10ec17f1cbfdea9d0ee7502cf668e55403fe9c57de2b7920769f80fa48dfadb7c3e3784b8737b39801b743aa26c408d533048a608c90e8519399105062914e35446626ca188ef62ef650aa0f10cd7efc94854e2a205e55877b1f862c3cf6753e164a73417f7086a2e81e6c5fb1dcd5b080f22b4a58f7eb7ef10bcebe4a084afc210a7ed693bab77aa2be3aca5af77b44b84bfff1c81dcfcb2139b66d3890e60c03dd23e2fabb46c3f612b0bf91f2861f87504660ef746e862ffa2ed91fec685c56c89ea9c521f1c42aec5faff2ef7a871e50d913996b75118876565c71b6a48d9b835ffa5e5db0a9c57cbec0f48babb661bf4d599d31b46a39e443be1e9cc0dfb15bdd16122f4276aa01cf59be55ce65c97454334104988ec47334a880730ce4dcfc849cf6c15e33e97033c158724dcbb0fbbf24b60e721aea3926ab00d0320f69218ba32fb5243c2ac70e760f4740d7e09b34196c9291dcb6dfae22175dd4bf1e8b79df72db3b9d7fb263917bc9c4103dd80303f57c971168ae23a5ee2d48c6efadfc329c045520b63cc9d226928de03d61d7448293978c1d05f6491a5598a1a28edbcd11e473e44202b0c33f309418c7165ee57adebe0b295de8e362f313f58ffc996fcaa06b0582800349e552e774a4952ac3f13c9dce08de915f2ea08457b5dcb31cc64d2969555de0ef80989badd60ef7176513166cfdb646649714dacbcd6f2c462c54c36521f330fb92873aca87710a71c8e64e04a2798505eedaffb2866dd999c85c52aa0c88ec568bea512523841760e8195e09621186ddf83c6ff3f4e88db8dc74730d1033d8fe090c3b35d54389bc83f7a899121dd27409d621864a6ad9cbfd8e38ea9d4cd4713ac473896235e9aae5e4db787c566c9b62c2c2fd11ae6d655a7991ab5436afe2da336c45a8ea4117a8b19d8edee3612d2f5d9728aa199b630aa5f9fd73b6075db3fc70ad8e47780cb56a46c405ae41f73723fcb4a511ad095433ff02f4f3b1d257a24313a79272055e95f983245a0bf3080cf8789e893c83eae0596ad724cc7a5e1a0f9ee31135ff60588fed9c9d667915d5482d53bbab1df2c8c136853e01120f7d0667f9e289ac99d5f5d8d4dd0e9c94ad9fdf5cf9bccff7d49d0b36327c464fa3ac89ae29f63d6247100cdc6d8f3584a1165419fea726520008a1041cb7214f03223031d99a82039221ef8fdb0f03bfc2f9bf297b6c3f9b621fb763b4541628df17a1beba218a1986f5a59c2531ef8c3a837b67df1300f4331e39b26eb75662632999eb9e45cdbf3159f794405a97883404e1a7c095486652e545c7542d7f948a3e6ce75f17ec6a76be330b27dc6ef85acc378f2fb5f064b7717d7268c40c9a285276deff54339db1303ac5ae40756cae2a4fb05a999388209b2b0c0fef2c06290f6b14554a2c1a805e9a81aeb8ca8095045d7494bb1864b86205485a387a8e2f273a99f8a9e0b30938f3743329dd20c12e8d4751ec8192b567c7a47a62cc87b38176a22bf60c126c6b2872de4c5a6f2b3bce61baf7f8197e0598b0c331a69f32874b94d85f25582c7f909959b1ace6cabc35ad459e241d86e389e7b71cf4e97358c81fa3a40d79266006e7c4807749b4a6088e2d7a3203df39a679b6ea1d46ed530d5e482bac38c2e36f4d4055014106cbbe0a766456b973defb51968ccac69924b383c07f8490c0b0299dacf54efad1fe20f9a7e417967640fa6d61a33ae3b9c7c92baa79d573ef045122214638b6dd5edbb751f551f5141be6b8978bf8f80cc05606ea9e2fe5321474106a3b5cb8d9385cbe2484b100e6eb08c1160c2d962b68218b861d08f009114d7e5f120fd1d5c9197ffe97a41f822a4599d79fa9cf5deaf250aca38c44efa5ea6b91598c2d92e3fb171a0fad61025dd3c9a9332b35759dca7c56162e5b31840a255820d793ac0181fe5568d6a45498ef410548b9cb92a202bd310158c7c73f09711b24d4296c5cbc8ee078b775c2ea92b9b3d58c147a27b9b693ff8c970114b4aa86dd182e9dcadd60806af31337afcdbf389519da5186138b719f9134e073412d39d6fca82831a93aea31f540d767b5c5dcab80ca402b659d8e300c4414ea80fe265bc83868dce3964945e70b6b600b142cf4d2c46c156dfed1da6644b139e5b59418e6629a0565affe3b207b4b9002756744095ff421d7dfadc0b301ee706a71e6e0890b1f4886c87609d8794c6501fb5fc1b3e3acacf7f4ebf50836d2e154e56e81f0de851fbc240b0d8e013518c20dc485b1cb339a844c249fa363e1c6a04301f7e474cc2468ef5f9a9dbc67ebfaa4473fcab5832f341443ab6e1e42cd6526408eb3ba7887c3edc0818cce9b86728fee316662088acc1f35af8fdf3a0480c8222f5c738a897480ab7fdaec306e6c3a44cc8027923beec21134b5bcdd9c38828afd94f933fe1faa951e5c86a2a6f6e47e908cbda213f07fd12bb22136a8a2bdaadc96e3aead047a30250f646ee291ece405e20b850303900267c9543cfea91a6f18fc3d461aea9661535d9bc43801ef5feef85894f017c4d567521508704c18c4a9e2eca4f7162298ff2dbf70263158db93a31171e852996fafb3a52b2b211db6ec177bf196489704a0b3380aa5be3a12f5d65702f577f60b300571430a3b3f93fb3e62b457bab04d7d15aa8e5ef900362bbba4a3168de33f0972e0d0ce3650b9625c1e5adfd4ea790c06d2ed46b43e289f20fe1e6944b5af9df8c09c43d95677388459453e0bbc4bf5dbcb3f7d52ca61eb5a83254ec28119e19bd0ae8cdb0cc8f0369a9f69da99b08d8549a77c4233e2dda0ba73b8b628d1dfb7b65dafe727571c63a0bd9dcf940270add89051e76c63feae840ca8adba770a7713100d70584462e42cd65e5e283e4ddb65a81028d3e56970e2e0f4adc621774a13dc2138153fdb66dd66d853c223bc2bbe07d3908faf04f1f20a6fbd3c7b21eabc2f8a3771c481f16a8a530f6ede23542ec9391c71a106b8b2371eef86cd2f4070bc62994dc5ab96e833e624639c0b82612617ccd91a0bd13c0dddef0c432ed9040007a0c0a717fabbd4c8ba483efa98841b1d89ff13d3f9edf08e64dc3bc8617a025e8ff2da514b49200cf4258cb0670421ef5bce0afdda797bce532ef04bdec98dd9c0d6975a28d00b37a6e864e2afc8a954a8c8ecee51d41e0d08b6fecb6dfe76d22394ed129c61cef996e2aad661e1369c0d84dab2a279289d680305c9fab29e447a33fe57b7104d40a772d2acb69b54295e36bcb28a463babee3c837043d7d18f22c275d4fffb2b0b2e92ea2704bdd3a69f237b8fd4439a9b5709125735f863ce885fa05662a8296e2bb7d0986a5dd3bb8ec67f6c4f09a4745eb49e0e82eedda41e96bb071cdcbca420844d2ca840f1056581bfc55e6c05457194f1041faa35c64ae90e8394cfba6e10c71377c03d9183c1d6d5dbb5418d84c208387ea72575341faf139cf6e955d6d37c799bda88ee871b90a3fb21880cd6fa5686f9790238fe6ffc166eb487bbe90fd7011ba56223883dae9b6d1a8eea8dc533f182470d2c5c156e99c0804e4a3c935872822731a18a34e1fc7072fa11a1f09d88283bae2603e7991075820a5d4f7c22160732b7626aeee5f30afc730076aa0b2f38e53f6c328e98c1a947d9f293c756e1cc58b04742c740a90e12fd86f147ea1ef1c3b8eb74f054ade4aee461ef1d0e2fbaee60ed592987fd6120cd418bd24e165107e919b9067322d33d6a0d9afa0d6835c2c4831c0bd88c0e241b10ce266108b91db5a6a6f9ec1ebbdeb2c9dfb6c73aae3071071f2821067018ee00692782ae8de1f51073b7a6190828edf0446644ec42d72dcce4ae041aafccb75b61b53beedc2e5c2b9ab4dfa5cb22ff9bf4fb435c65af5e2909149e8f61f1599535e68dde7f05bfbc654347ad8993f62f404f77dd9a307f8acfd422f6e59fb8ec0b13fe93f1ed3dc2a945d39d30e6be0eacbc5f33ccb7561dede3706f799b197da4bdd1f61fca77b7855c114f34c3274ce994effd6167248754781de02e25e1efe1dc5810837734a1d508c9e352afa07a0fbfbdf73373822031ba4f12934f8e826bce83c1c9aaafc1e4fb9d3f1d11df8f77a7c34251a0f51bd916c7582994f601a38f6f5c2f22cd0c04029d91c50052ee19e9255c49614e7809e4176728739cf9498681ebff95f538b3fcb643a689e84dcb54261af33148657a18280214f7adc57ad9c7e02d9b61b5c2f2aa9430e670275b5490acdbc20aaabe088a480276a84150bc731a8a63727d0173a58a85c11edd88fa7b75832f85be829b26616c8c2f4b0327e5409ba4a8d689bb23b06280f66585ae7eccf26f1a2644f90b26fb4706e9909cb57295884fc233d187b795a4f3338e1b289bd23196006a7e4dd06eb4d49d2be8053aa9a458f1540d50f002d43e62dc3251e709afbc36b18943d71f6d966a3a6d3013a96f38b30d994f601484a5944e42451c7744b1fd167eb1241ee83a55ae38751bb7a19a84a841d263d4ce76b098c34de6469a75dc0ef2c37214689b6825eac4b598820f6546ea4174381187e3cb5afda660196a11bf002626d7e97bbdfc2e4b8231aebd4aa5d9142f82bcc94eadd2fc74d53a2e78e02583c656e59b46387f24b1d8807e8f1cee5b22d4d4dc404121646d474d5e01711ba051ccc2de28e70188bc760b718c4bbc90b74a100da3c8e0dcb4e7fbd2234564a360ccdf73478eb5f5adeb2c51c0554039c8eb31011b8a3b1afe3583857ee0b534be2fb2063f9a3712bc063228a821919b4ce6bc55b1966b0f7fde83b77f7d7899d820642306b00b1831c4fe0186f462768437f97d4fa3c70e4b1fb834ac6188947e96e519a171f14af7a876281ecc33b12df61ebff86ead196c37043115986d328206723df419f77057972785c2fef110c5d0c5d8d642e6c34cd0601a3a3ec262809839063648eef80badd190db47048ba905d6b2bd2572983afc043e2f86401e537751d8081b2a97056d7087af81ed6e1b0b080fe401566ba7ffc393cb1c8d06177f9a4d5b495c5226b5866042c8eb13dc6fa00156c9dd52ec1ae2432e00b9dbe605612c2bd962067e2d803256726ed1ded0607123d5a7e66701601f7a9e1e6cac1bbf57e3a5905e1c7b90bddead7bbbcb3e15b219be5dc0cf644bed62247d8ea208e90f27a012a2f87449eb98c36de47b2ec6e2971598cceab04220a601496db59cc222efbe4016ef43e4e5a8a581cc469194d357045a9adc4cc0384b738eaacb18100e420e230ec02a8e23d0ef53a9979f64f0ff273b62c4abf1d9f4fc6493ada9104b7d79063b3569126ac7d2a0ac3048dc9b08bed1012e0f7b68719c11bff233d7acedb885a304790433d032e675125615396de5d8b20a191a673f3673c06f786666a1e52d8a880c168e4be1b97243272b6f430879f9dd875aae4e7edf57706b79a53bc346300f61c5ae37f78564bd63be795f1a8fb4fab91a71b2d66f1d07680fcfc98d40585e8e323463b0cb182f07939c7272c836b229cadf1a7d212df9496abe409013efe2bf3a16fe7d7ccd36af9651f0cc000dd079eb984ec8009a6804e11fb17be55bff3ba53bff3dc91afe6345fff03f52569a791c01023b4314995bb3c4cdf678e5b497775d1fca5b81e54ee5123669a11ed0be43b0d07f2a9d805e68f83884484ab70617bc999d29781c3bb289e9b9d28e903480cab0452b009dbd79643271b3cafd3a2b109803ed23d2042dfe42a49c58bc1304af06e0c9187e998939c3d0e92ea15264477f5c6ccc66d990f8d74face478ddc1e22b63244e8a1bae160a1ce01d010e7ef5fb9319e60b6d5ca82555db966a0d0edd9864ad19caf3f96f65a00e74942c291edc947575c1eaeb02517d872827c7c8027d3663dc0905983462096b7f82dacc7519e98869f0baf71800919de328ef4de4b02c7f5186c508d1afca3c1f5b65d3bdb034298d9a239912c9df052659dad509e07624259a917b21bd1312ebebbd2595e01841e68c0330d8db914ef2233dd0f49fa037d70df0380dd6146b7b326428a70594a10f988c9685c2c6fd7aed1ca22aecea35a13ae1024c20d5a69e077b8a7df3c5c2dab4c548fd935c580af108dadb7f88747f5f903cabf8267718ed75b74e76569bac7932174457468ca4d9043a74599abba75d0481e0f888dde6beb0f6bd41a15a2384f9a724cab61e342414e9314264be643a00abb606471c0091365794dbbecd2272fa66ce0bf38246a760caa7c93d3b4f731dac4bcd35e8f4674336abaade333d162bc29e2f3f2519807f8ec2ad88c4844f484ca3ba016dc1e383c18381b7c3c3a5df29e6b71c372daf7cadd59301badf1f7cc48c8a8325eeb51d3546de6d396b51c850601d4e1a9d8616f6e526a2f0bf36da5a9b23b68689d5433f7eca94c336b71b22329df54bbc99af5643f1df1b7374d2f4ceab37cbbceda4602a83d6bb29ef1abe9125384ad9899d7de4c7d5bb840c471a9c1824174cdd5c0cb000dc53aa4721159424eba4c9a5ac9511fb3a719e37711f6902871f62ec51c2dc41214c1d0c04f0b6d0de117480b7fec66f55f4a9bf9f8dd24b3a90f17b1e3c7bf71ff461a8c16dcb96c05462e88b8d9f76daa290da09c54962b29b6151fb443658310569c5aa64728fecbf95e244c9f86a77b45d5ac67ea3fefea98a3d29562d5ae172da373d298746ab8bfab0af62c43b93f88a806ac715dfb72d0364c6c63a37d97ab6c42c6d20834c4b318c67bb56ebb2f55f8cb335fb9724f48332f97db7f2598500a02f0aa52662d65896460fe0ea7d766698734852fbef581e88122258f696890728729da935414710a9d0a7855ed9d068cfac25c912a405043f1c8a517de02207f22974eaab2ff006c5e217ed1353fcab65a848819804622783737c91ee1f37a2f9dd467ef5f6387fd513d397d3c0ecc5317da42b76077ca573229568eccfb150dc2cba060ac88bb8b6ff65c4ab7a43978c5ba01160c585840d34c17b2bb300068a1c8408780a301efa7f8bd192160fe8c908b3162235ca26a071d910489be48c5bc7cc7272f5a9f7761f4cef03f06e091d66b60e2d6828327d0c2384c603e8f247b07361ea10f9b6ec29ffa8bffbc4627c941b898d32f9ea11de2d99ff9242d5c885e76cdf6c09e452cbacd1ff62f648dbcfcf4fce29b6705a466fbe11b1b71b21272452b2b9488a4ba762b76764d1e61500e89e54218b7d43543a554b788600200f802c2d9400a23e3850f4e7b7fcd898be197af4df34bff35325ab74bbbc2009e61a1e3d0e05c6634ba744655ba0bfa09c91669fafe00e5df43c3c7fe8837a73848a827a1bf16abac68bb46301d1b17be8c152948d42e425221a84b63d1910e3e58f24a69b39350ad84c4e3e8e979c0ecc4f08afe1d350d2a8e8c4b11ec0a13191afe287d6cc591ae44071759b8bac06212d9fd6f303ff7c40aae7a2a78a2692f477169a652a0311c0678dcfb0186743b0c69e3b637f44c14b5e8978982a2583c39bdbb852364e3d3a23652920a65ca368600781b3dc30813ab3b0ed49aa5f11face91c08d58bf32d69a502294da5a071fc95ab8199873a2aeba39e43823f134e388209ae4e31ba371e79e93fa4dd768e15c59b4d390e798ed643e405edbe020edfb03c5e541949a0176f14b2d6c519beb22411f4cad5669723196368edca3cc7009224a0ed420242fef631dd5fd54fd9117832a37a95ac2791835ea5e7c210fe7580fe200f5c6b81620e70aecb7cac5d51badd6a810a77d45726788f902631991b97448e55639514bbce489135359460d4efd7491ef3d7c31cfef9361a0c17592c8c0bb64eeb7b0773bb1f49ee7acde52973cd57893b12318220a943330f2cb28003e58248802a5589756e18850e053cd67121e48b3bb334a11369d84960b3f7fab6b584895ef3763630feb2e481d946c631ffae89c3c54f25d73de8087bea896530a1d44f974a2411bf0b3a4809e49257b760081bc82e49bfd3aa1bb67160f4832bec30cb0cdb9ab115b90063f999783b8a7bc9ba5be973923c24557207df26709eac9f1b6a3ed452a96c5fe5c5561f1d8c786ea60a0f5b706fd1af7f03d5d5bd0aaf3860c1a7de7fce35106e94c5b38b3ac4c1967d3135a260de07839bb320210bffe0ada0c0a066ac0bf391181dd405fa813430d2cbfbee3830194855ccd3ad5a1f9c36615185a341801df021be7d0986c75e508443c46516e1257f4f368d26de760690898885d00ed0f71777b309cb2ee3ba79f2a30b085a63ee6b328e7645eabad7dbd3959c775c91d0fbcd5268fd80cae0a6710a8226dc90cc847c66f9e81880df2c389f179ba21baf5081e1017a6f72cb43610d25f36ad8d32dfe297a533bdc966e74d880049211a038ccc6474a99f1fe333f28df2ce4f259ffa6e3aa84f3c34295d2d51a41180cbd682db640b99bc49a8fb65204c3afa02de9744e796d484e6e95ce768a0134c6e336a08958024540c3ac767c2a9ba35f17482641990ebf228d6ef4a40017c275577dec7da01d696ea89fc2711b7bb7be1f71f1dd542297b238dc6e6217d30bb5314a6097ca52524a9a900715d760ddd8410b4ff2495c6fa4963c91c7564c01e78169d221cf952c64b1653ae5a46d4ee97a73e977a76801fab1fb17dba6db4146d806add212b87f2b8867f5a881c65242ad450611b39d48ee64c732cfcfed3cf3897409087f3f348c76bb61768f3c13a1f96cb5053e69dad9297fdd959c297df8002a0e021ff5799f24ac2f7a7c5a7ae0de0324878ad774ca1858a886e974ca6188435532e8978d044c669a2b965781e62f6b5994df51875a3a8a386d434c6894334186364ea2a4bf2c95601a659188dc292efd3055be5f2060e1065fee1320ad39f9dcf7f803f4a2875ffdce85a62826c5e3c4459ae355b28a328777e31d78f1d0b654ce033a5649e412a6a515deb4a19f43e7ff5cf29abe0f3350942a8ca9cc58cea208db18e48a07e900f68d747d688c065ca3364c6dd6ffc6a704e26c987bc2dca16956e59878722ac3a3f53e1dedb1cdee4ffe7369533109838cb32e9a701b99d1dae412782790baed9831a7412ecb6472c3ccc002ec75082a0e22a612abd7dbbe1c133d53d6bacaa0a7b81333591f3faf5cd20ec96feb3a0cd591291b9f0cd6d5e5b81780f2866bd78272a8fe7d3a8f166d40c097365af760d183ae8e4a7621ca6006803fae06bdc81a52d0e70abba313b1a5d40d692471b45b21125732498cd36efe7e8f8b1391538cf3258d6eaa9120baffca76d8b2c460969763b57674e110fbaf4856f7791d7c78e3131ecff67aa64e60ad94404084e4ad95c4d71de8b7fabf1b389381a250d7b99f29af5bf2727aebd31e2be1f0b1c2462dd0db3a20b1998f1d409ce1a15334cfced132be0a5a73a8e08f35d43752efb21072d6720af7b8e2cb8c64620852e1a31b2fafa2c2b3964c31344bc94e7bb23239b42d4cea514bd028d4248eb5f8c2e5621f263b08e75b62680225c4a5f032f857fa1807c5db90fd0a71ff2311c78683df6ff6fefd34040f317af0a16ace124bbb61be9d49648af37aacb9da3c2af852a90bcb4d72c383b1d8eb02b901369f77dd97b19b6c7cafdd0488ed19cf537b79a0b078f9ca5b9baa8c6d29ffaacbe65e1d439893d02e640482b0901c1afc48393b9b1e581d444330ca2893028db489c0edb8fe564417283859122b7d20b8dfc3faa7f1fee80d3cba49c7d2b09592ea5d112db36ae1d4e6d8abdffcf7e304047b89d0e951a5e595d6065ac427452b02c5a3518dc52ed9268fd5580f67596bd2c3512075badc168014aec086d6d38f8e6f300330cfb34bfb9f54fa85d631c1f6b3dede8230f70655434dd880f990a9d2a4c5851c26bebca8847f88b013ccd68c6e40bf8c62a67c599a106bf075b7e4f525238b447437194b8bf06d2814618c305a71ce5c29982da709c3a48e489f06484688cab0fee17cfbfebee8dbdfaeac9ae55f2d6d6fe242cb7df78da1500d8d9f99c1f769f6fe9a99d6adf20d5efe3925357cc9c3cf2b04530d35a25fa65e9586090f43e92bd5441b765d1914aca7b833b2d4da5f62bd88e9ed393a88378d2833f6f224f057040c3e37ba611c6784ec9154204544fa33dad097cc5e748c221b9f7ff9f6edbfde6b3ed22d4bc8c13d5575cfeb624ed0db4deed8878dfd72b55213bb8bf3c3823295faeedecee512a2cee2160c3be7ddf3f9ea04d01f096acb29de9b8ace90e8c8932afe2d0ebe97e341bd2161b23b4b8d2bf2b14c136f54d20c0e168159e3190462c1bc82cda740a2cbcf13641617713748223e0349f554acb3723bed0c70fab319c0232ec768947114265cb9318f1387e158d6e844be22136479e76f569903cf33ca79a2b719bd669ec235d6c2035ce89c82cd32341c3a3629e781d290ad71299244e1a3b4feb5c917aa788735a2e30e282cf1dd5acded54f092217f89decb9bf94b1e84cf19d30d98f39ac82baab7c825f7000db4f7dc8a482fe28413e753e6d88d7afd481218f8e57df81013b749aad946d055e815a78a2ed5e8f6b19e04fcaf6358f1398ee298ec3cb5c649a663e6970515ac626b16a3d329d00f3348781b8668b2ed506ff42dd2d2b7a4290d84d39f91c45a31de1b68068df42136007d200db9c991be0ef70f930c6b2e34b795d4b72a9c41927e4816171627162fd8e97e23e0bb375c1ffc86471b0db081ef4ea3d9b32752267ab6b8c25d0e6bacb2ddda76005345baaf3e93a053ba3dd5dfff423a1072ba3f9703b525f384ee24f5b19caf672d18ccd19cba25526818209e725b446571394ce77d30ad9f93f7871dbdfd7a08b1672277fdbf616de9cb73b458bda1b5133294b7805213d6bdc119aa7b732d3c9b9ecc0d4a68ca1d061eb02f2634f7afa7b05751af3eb056b1992ababd75ed9bbb04bd31b22222398f5a8944779113e20deb9c2253ed78aeac187f7de5f3f429dfcbb2a70de4fc007dc5900a9cc5b3b0032e01dd7288bc2247962f9a3065bc88f44ba3e3164959f6f576a3722ac68a9fdccc1697f25031298c5a08ea469d7730f03d3665a77dc432831146de3de052417df3bf08291c1b5dfbc100102eb7a13f5c00e0ec4e2e4b4d5dd0de7ff5c30ac1c83ab8a20442ae5db75dcdd41e84de2511cef75a8716f29de0f91f088d28ee0c708213cecbdc7254cf1ffaffbf1b54726c235017c5dfdd5968299dd570d3c67088b696d039a3ffbad8853d35cd5245552cd1e8a9851fdbe019ac81b9313de7c7e15cf85bd8d385f75f425d1b014cc213ac677b4c6f74620353cbd2f7ab9e60e3e2b3f9a1e19ff5869898128b639e10115e9dd219f032126fa30d11211a930587f52ec9748528da208df3b58807bf1022fb2f8004f8bd3196dc1f312c9d21132d5ac73fbed09d198d83b989361113f00172ac9a77cb029b94cb5596bdcef87234a62fc0dec4f789df3c41a744d6c723872b025c54c313430713b1fd70a15d679db85944f182629a67fab933864c9d7784260e57808edfeb8e9ef30f1c8437ff8d4e49131613e2f05e9a6aebdd7927d2b133ad5fc38b1741bfdd5c027f90f850569ed1fbe35873d00ccf8ebc4e026dc7beae6102af57ca0433300b45e84cacd7f705ce12f6a5baf8968566b52e95e0b1c6c6654b7a068c86aeda552bed86147aa90ff3aba67e813537b770b471c49b29d2dae67675046e08d212f6b889039180522bfe7a96be8bff0273eb15d4b85b104d17b24c40197355b99e0665efc23a4662d5745cbcf2e90fd439b749b111af54241f45ae374590f0b6184ee104f3569be268277d847fbead83fdc973f4313180894d2dd43431e9a08979c25f185b753ca7fa5d4d2ea8118f83e584ccfd677019f8dab0cd8e629da573c7b631ab12e1f842932d6cbb9a474154800decab19886eb2ae93177d1f870cdb3f7f631e8b1d4a830e136f610ba1422f37d364fe6ce4e288396cc7fe350713f27fa6cdb1cc7c874c3e8ab9198c0da4af8887f62f33933969754b03c5d9a706368a67de1d13c7279750f413c02884349e44d9b05e907ee982e5c5e362b8bbe661cded781cda9b89e90ab1f6cd348d113b5be591ef46eb1d876999e770cf5d0769f449ac687f7d0c9b91d6eaa4a17ec36935bdafb8a57184b4c0d0627811d077135b918e60969b75e6008827b0416388da43d47c6286318fa55e36a12d405532d994f3ea14287399b954a3bb941f5c8f02bf876de5db870588223d18647fc3143d4b381bf98258483c4f9fe39d658a1b5f502eea69dae2fa06916994320d4b562450b233103708bca124065c9feb98c066e3f2426d20b137a0ea0e181a2a5d553ecbac1d448ac9e9e7bfdc655c6f09ab545d35f222d0b26931747d4197ff50f5967f6617949958d9c3a69257e3a7a19c61954569e02451e91dd34a4688291e1bd2bac9217d702d966bf5433d6f95a7f85f810ed044d32585c43e226381a07d4b7a2cff468641fd4dd2cd0bd1b7301709873027f3c243bce2be152033832178897443a476a0cad92337c8b711201cb289724995cf3070000aed9c47352e2b00d4d1190b4d4205b8ce6670cfdc8c4be75bae778e58c9bc0173af3bc458321c5571f70cdcaac409bced61a3372a370df9828530223a7fa27fa823dd239ef04e3b4a1cdef8de9f67c18abe486983f91bced84156e60a44271c2eb3c79524d4611d8e0a2a5f0c38495deb7d61aab87d6191bc6146ef710d5cb9b69e9c937e74eae2ec3c1cd83429c655d3a5e7b64e1f928283f00f13bc773c7807889323a1833b2c888072c6e075c21bc4f9a3b1c6c6ece7845d73518b6b88662b70cf545476616e930bfe2be2be7389432af407fbcdc7b8a9758ae0fdba1f48e9956638b7445ef3a10375cee2b177f982564656962476dcc1c45dd3efff860d08be31c5b627b05f4538ea1458bd07f83e9e9dbec70deca7b8beffa440911ce91c6470981219c250e5d23c94812a869812bf5f24d45980108b79b504949999e99d9b1d79ef286e8766ca4f0a63d866f7dd0646fc0843ffb5d6f5a44eafb8f013df8501821d27db4f9b7257f072f161ff93c6455842ef1624b233f3b247fb7ae2349ff368d2e50eb50060ae08cc48206ed8a31a4035c9530cfcf451407902d499eb144c09005212af88e8dc1a0ced24eec1b5cbe7ef8f2b725e65507182fb01a6f338fb568050adb282873fc6d21b930f1057e6108bd0599d7fca0ee21af4ee2f93a62e42c79ec714851320c0213225b09b157d8392c5b4422418a048378b36cd63fbb1e578c71719885a2ca8fa086914317ea287cd69e6f13a32f52fc59f1df707771ebee460fb24634d2e4a511d81992fc112cf2e1fba79695d27d634640b90c2943d424179cd2481263addcd9ca32aac03390ced9df6b6d97da398bfb76f635552c24de1a51c21b5334b5365f6feec4aafc786c035e2225db6f40415d6cff3e6ed62ba36dd57b7e3c4c0f80f9925ce838157d037a7b47a53befbcebca1973562ed16d634f8e4f9b975eae7fff0b68850c37d8453f0c2994fc4efd82edad2fbe86da68b50d463dea26fb5b4840d8ac40b73cb13dcbd0dad481a607360b3d31d9e29b3fa732416a244753837f1061e042e4c341437b04fcedfd021f7f595034672920b892dd0178503523603774871729f8f8dcbee81e9085eeca8144e97a64d14ccec63e6c0c954303b821e6f8d0385cc00f0b635e468ab4008caa531060f8b11b850633fb1786d6f7bfb13ebcab0ea8b9ea4807d522bf558b84ebd55e179e33e7fca5dcd4b84a97ee8bfc648373a279a9c8d61b3620eff368fd2afda40347e4f6ead0065e0d46d7c6a55eae8f7d649fa965420ddf1d852633ebefafdd5cfceac2e486b2acafa30290a3fca8c51ee06573e7a0ef87a62d544601bee8b4b73467486f3671392b26c2154a2c681c44f00371cad0ccfc72742afb42ac2fa599f8e7bc62043e63af80d886d802c96a98a05563993da32fa643db532f9d6aa06b1cd45effe3fff3c2861306525cb17dad2b40060ac8c5e351abe7d8fc176ad1c7278afa9aeb393afe8485bc55bd1babd767f1b222e2e6470bafc57dfb14e9fede623aab15210e1ef24cceca6fce66735c2520e86f91cd060df5b84be20c9f90ab687461b96d471ca7a84ffc9bbb989c4dbad560367b53c6a6addf69163e24bbb281027c7d53a0c7a9566f970e090e15247edb693d326c85566a285faa0333027afc2694fd7231a7dc0f94dfda1edd790dddd42736ff958f7bd8bf527f541ec393c5a64fc946cdc2f5a7c746b893e8f698323d56b43bbc1ad60cd4b5897e161f4fcb7ff944c6a056710e4cb5b7c435d1abecb9b992affc46a7da01a6ea4b9bf1bd983e689d699b48d3e91060fbd73ff69e2738a431fd4c7dbeb81392756f34e91e672e62a848e5ef6d5bbcf18e753c336c013c4a7293216f3e3905527f3b00a70c46380ebd307b74d1791bc4319b5d30f46df41ab2a2c64afcc8474359f7f71fad85b31e3b7abd7e1f1726f3e8cc05aa9114f5aded3adb8646b71bb7cc4d57d589ae12762472139620098f365d09d49a7ba9859afe78dfc2633c8f3ef45dd0765b015b46fdcd347394be71a566f4a31cda52e8a7ca4816c22ab41156855ec1375b0f41860c876b492d9f948840fe0e31dc262081c6d3b5c1a1f0981bb22c29ba364f7d60c6c38db2beaf1c828dc0875c31aed30f75be8448dedb6384ae836dc1baa9d2a6814280dd41b8b0850a35ca229ed898f794d79f18696f8e1fbcee021d28ee4b439dac9e2b1d3973bc72cf242b75f1b63eb36e5b3125d7d27ac1a6f0fc3cff9a3eda9f9a1f3b57cdcbd3be51e47d20e5db2bb40e12da77bd261bf348fe584c8c2821e1e51e40e325696f7be6b20a4b8cf5000bcea0748507c27ab2f32d4f2ca942935fbbf9f91cb94d00824b909177391e8678958f6e47b3d1fdea6aa4c476d150367e207791137a43151acd69e329fee979247c637be493e66bb702e48a89bfdcc6921376f68bec654101296d0c5075666e06b4dcbb0821f133045b2eb80ca637f7ab7d0a4021c0d7aadc27732bb3a250ef18ee5138467f94343d931a268d3a0bef72846572b1a33d90fe37c3eb9e4af4523005114ad8949423892eb35ee800c13e89f9323caf024fd6452310913b2dd8b202e4ba47521675669149e02298c295f45f5e0e7779333bf5db3a44e96f9caf4e6c7063e73c417fc349f39e12e99c2b29fb3f44afcdfa312bba2ca096c4599de99f5e5ad2a474d4945415db70f506f39c581e09a1ff4dccea008bd4f80807d0539cd697fcaeaeb22d6a0b78182619e2a68df15008a74c61381bcce0bea0b3da332c480404d5b45187538d8015a8d11f5e5be36585a860903153d9f01dc4f028a56d431c0f0ff719b9aef76851c254b1edd8c4c2512ec1f92cac3e7c0a6595dba2a4f3f0b4cee1d24590fabfd9488fb6468443d053b1d15c1ae35f6a948fd26e3e0550f1c6d3a733469f080dbe8e3bd7218137bf6fa1f315800eb308d3f1dbec7a3d73ddced8ac393130daa514de948a799ebbe21a61b39d45d96c744d1a29521d9af10ca5668ffe640767a5b73a91b7a243bd7dddf062b75764bdde084de3f64f9728f658a3914f50b29bfdbe67abfc3c42f297e0ffe7fabc5af21258ea04c5b3668c7362ccad052e150678c584013b8d274278f9d917262496cdb0f03a5abdc6eeaedfb9eab432c8d9c354fbaaee60c0b9ca3eaa05ce2facf73d584bae89c2647deaf309e92f61fc9e07e6dbb0125b45fa871ac74f772a066bf26f8e4a662a810c5f0a0f0029071593eccae35ec2ebf77ed65dcbefbe95f721b3f2a9129adc84d44017f86ee12f6b9817af355d4b3bcc238a4249252e1ff4c780cffc0deb9c5224fbf3f3cd5700362db57f75e1faf9e9c986f235eae737ddfd385060b12af32d42b8f35daf44532407950605caec7c8ff40fe58dc360f37dcd84a8f455896cee7a3a4104891408310be000f8efe23fdb9647082f1cdebb864cba982cd7e33c6f44848ca2a4eacdc2aa519721eca79d701082f8cf0883ce3d644a8417c061067957acdfd4f6539214f2bc2ce3baddc7e1b9f41d97f4e07a3ac00b364beb2a68f6221e0f5c347296da8687f94fa9d4eb0dd0f77cfe0c6ca1fad0664e5b1165962263c9b0bc3d16c09bee04f7a200b2dbd8a7ac2aed9c4f35494e7a8a9eed9b007600fc78261ab018383b535dc7f31ee1ff83c1d5742685044ed81df9f627effb2704022a7a5f2c2ca51bf7d7b6ffbc81ea4bb8b1d0bc7fdddf79ff75fc11245b3032dda40cdfd56df70349b1ae64f4a74aea2dad5c3843eb1a5ec48aad8b393f82b9398f28898d4dd1b507b46e6a0da41b38a6fcfcef45b819495d570f96f20c9ee30322547449e6990054d71bea4fbf11bdd220a18faaab215096d476238afcbbd945835451a7811417a8c2d567cff7c390b90cd5f7e619f561f6f7a0d4f587afe07e78b81f50c44c6c212ce379f1ce7663a4130b8d1fd3a45bbf964b99f57d463cbfa70fc064c964dbac1c9bf5c6d4f7895faab47cfbaaee3ad582296ac5ad454a6311e463298075552c1ae28cde35229c306c21cad1b104ad9f23977dae5a58ea5c6bdd5ede96e97cf8d51c70ce2837503f092b1234767a855ae117461a0d058740af9a9c04e0bba1a03b58a563e8d65bfade3f24cbc8b774b5677fcab7ba15b89545956221f2618760cac89935f604f6d04c87d7c5d0cf508fe270d824cdfc5f229bb46cffb318e8e88143fbf6dd4d59b67ecec0a82801abf1de456e7eca679c2f735ec8ffc4524080fd6315ad75fc884af2d3cbcf92e1e0c77655c9b8fb4e6dedbe00f2ace6eead70c1e88ec41c2b692809510409b10ab2d0affd56abb151c9e7d31fbed3b0fdbd12a5b960073441039ebcbbf6c29b008c1f90ced7eb4e3cb50ae1a4f38a7369b0e5c8d931527f1d5e9040f88233edfc901bba5c5e63fc055bae27662b62f617fe5f11b2e764c99542d0ee0284601db30f79fec23e4f4767cdcb725deaeb93009c61dbbbd952a73fa2666237a51d86d0233d5190b0a408bc2034b070582658d1041f0f99ff33b978850db5aade7a0d94c44e5e387162d219ee34a16070bc757bdbcb598720633efb236a7f251a7e3db05f127b57a8b1b88913c00ac3bfde07e7dba210b79c706e0651e86290577a468eb007638922c5a12bdaba5c66c7d07183b8de0ef59f3ce97425996238438d98893b5bac550ecd9bba63d6a3b7728bcfe3147e652f51a5a7fa593cbff24878b25d1dbf9c2bb2b956b83e4318ee71e330cc0f954d8c3750ab1c70fa3bbaf75c1fea47c1d5624b84172e57ee9a3182c47406d2f123081f4f127928b18ef03d46084179072552ceffbddb9fdf4a0b77e67b6418d0f7e727cd696fd3682788f6e8da46b43538187453dfaa8e6609579a20b9f184f456332faa84c3e290f1835ed460189b31dcf064fdafb0fd5e92734731ae318a43f27464af8b9323ffdf22ec8055d7343e94211f9e71c352236dd7974d8a2403b2a530bc55f3be5e098a2eeb9e378db4a312120fb0aaf6d08362c04be3e17da3b89373ee2161c9ca8994b5acc4615138855010e27b17d2148af37db0ea1d67651670957f64e4ad7d3ba8a8e3f0287d0850f0e92b308be4338bf51081ceb046aeac69a561040cc481db8d531d450e45ad7ad9eb13a96a55f30d2b8bcb2a8fe9731bf82f82314fe5dbf8c246ea9145bca1d292169594b649ad61db0b40591a727e01f71a716b814f8af453ab81d47f9c9cb112b5e7a191d6b9fa45b097809eb094038b1c6110b980f01cada7a86629c50385032c3157668412b63d2b8b8139164d23c983370d6c2ec4577334ac3ffe2546a17b386b56882579c66f7459adcdf1c4a345c1856ab27509e501c5d6855bbf6472c293969d7fe88524a2f0c33505d68656f0b5f86a3d54c832aa8c8c1840e4fa0d45e948522ce91c3132714057a5f44d2a1505225b092c53fc4775a2972ef61cb0ecd99c102830fbe43ac1287bfcdb138e270d414f732ee3498557488a496982f5ca1f3278a4f9b2ed8305d70c31db53453845212677597a394d317ee5efaa462809c9c9c5d585f0acc1d159bd181bba36052b08bc582d56a49170825e42b0d1524e5c6920eee2928967228bd31978eb83b39e69b52143732164b76133e1a1fa57fdbf97789bffc77dfafb729547f4edf6a2b12cdb9f87ed78ab65bc321ba7a0d7d20ce8bae5a2a90b6c09c43599ae2cc54f4bb96e25415fdfe6bd1ef439b3fc9675f2a6d592c8d035f20cda15f7d4b957eca4c417025538139900a08e2c8e88a8a0ab4b792a3fd9af8301c0bc2f95fd0bb9abb4ae2d36ed07d32290ae8dfd6f815e504d7fb35bda591cfd616fe63bd6d3d5b49b4b2b8d32ab375e4423af746e3f1d9dae1ee1328fa61166529029dae284b3fa15664555820e3eeb5ef33ad5e4ba96ebd7e6e86907ea4106d5b29141cb04ea1ba15949394f44e694ae977ad98f14e887ee093ef830d81f4e670786d0e6718fdac7e2be6fa2048f7acc421bdfa6da5377f71ce6e9653abe11b9c7f57269b5baf1faa2d05415010adf32703da016817a4ddfdc6dd63983f647eb4d57c23fd063a8efce890b18ae61edcf7ca7d661465c812f7195a24b2806361a6fa0c3803ce20994112471c271d9c74f0d9ca19b68995824347403f45413f43525c4a54a8e0a729869ca4f0936b0e20e5ee65f85963f226898184618af89ac2836d01e1e5ca103f2041d3df27d6f2620d8254dbb186c3af637987e887db3d8eea3063dacedd71ce43650b397cf4bb0ad59276991462ccc2cde16b84757d29b5db6a09b570347c74da2955419a2ab8a1820754c04bd7227d2002fccbb977d16fbf2862dadad8b57f72f8e815c34c012985957b129bf7b57e652a7183894ed00774fe70edda9cb98456863893315022c63ddf9ec4afb1a8f5d356983d57582cd405664f6af7389e2ddc1d67f738550a07f79eb96382bb8bf0824f9dd7e449eda8e14e5974d70f778f4ba1e60e169d31fa9998f49739dc7081eb200011ee272e2610857a2a0b4f61e00b8f0418c0031411e804d584e58e5241acfbd6dc33599b8ffeafb9cf84a153709f6923b428264b94b8a37a7eacd77da6c81dc583dad119693a77541277d4974f647ca372dc51abd30b50402141e1dcb8a35437a1ade455a259123fec438ca4ff89f6c37e63178e868f76c6625582e512a867debcdcb7ae64f822495a1cec081cee6ebb36fca7e1fca2f3881394f5c4e7111d771f02348d68601ab172ea22635d41961e7f5bca53b5fdd1b6ae72ef82a30669783185a83187c860bf96edd75ab65fcbf66bd97e2d93edd7b2fdfab56cbf4c9651eea930ee5e372e65906921dc5d86b74c88cedd41d7425610a212f2011bfe5f93e12d0380cf205db8bb166ddd1fcafe6b3348933baedd205fdc5d16c4871964f7b819e4c85deb1765417c76ee1e82cf20d47d028183b4372d9b40ac7077205f6ebade26101ddc43dfcd64409cb80351e97d5f86310442e37a9c3fdac0b56b7f60e1de847f8869f387107afed85e770de78f97bbfb787e5cc639d9fc21e447ca3519d7d3c7163e7d34e1bbcadcbdc6a70f2372d04c1fafe9c3c7dda78f0f9ce21d5620ef429b2508a1e4dbf97672c48a223273841a82a238aaab042375e4cf7e58d1c360bb12a84837f4422f0605dd27938272ef22c75c14fe33d997d2e2a1e2ee477c8e1073a7ac1a133947a8f1215bdb23dadde9e961e1ee1fd6e919c0c9727a37d7b5cfd383e2d3ebe134e3da9c47645c0b45f8c02a56c02a746505bce95ab4adfdbe5dcdd516fd9ec9962bd5566b4b3f5ad534db21fae9b2d2cf385575ff733ff4ab75ccb8a6a988cb3feaa15892ab5ce99b9f1b6ddb5cd694ee32ac54db5d65207d0245a8557325c39aeb7dfa55ca64e9ae74b5ba856526a9a6d9fcb666ab5ff41bb75d5901c12a4c6ff30ea23961d5422d51ac766705fc1bad0669b0cab79b519a4ea21f08562b5a5df9536996e95ad66dd14f147f6852ddb05ad26fbc0413c2413347cdfdd3f913ed2e45bb4b164b27f19982c21f8bd5388c63b715b6c8311725ed8b83f44d02fab75ad73ebfc20f75785b2e3148e7c7edc83afee72cc2b7d9eaeca5b4c03f02e9ae53e8f7391431b9d2b408dde159e9505b9d512a8a3b3463aa63e9b5f27d1f5df5d0150f5ded5401a9f651c2f3ede8e8f0f0e432a4e1834a98d8ea4c14411c954cdb0f47b5dfc662695b05022da86d7596a345bbcb24607e1087b34351d0d5f1c39121a156705554f4c9136a6587a2407155569ad26cde3fe2b765bce93862dac5368816a1df4ec4b98d2f5e699cdb7477c35dc35b3f3b448bd0fc4fd25dfeae61962cc78eaf6554afc2b7f452bd6d9de5aa6f424bef8fce366b5b9de11db634d5b2af26be68ebdeb43257209056aa7fe8a76d754635ee5a91bae867abb3fb43b7b6474d69dc400dbfc1163700e394aee8ae9cb16e0572175fdc90e081004cac11866f10e1fe4611a12f8684c6280a14ef8c37add6d54eb4e4f7ed6a6e776b8977b45620fa51f94162b198ec94f533939d92ead725d5761ceb57c3303ff98138aa1a4681f28078479b9de0b36445a29ffe6cf81bbb70fe17b40eef5bd8c6ae8d5d1bbb76557ca1704914ed86851548015e5cb0b3010e3068000ab761e3071b367cb06143179474ba325382cedf1a4eb85316aedd96ec37beb230ac32d9877fb190fec161090b776f14dab084d9c860c86520c4dd7595e1b07c5de2b0d4315000d387c3128622418d2eee78c976edc3e0e88b3484b8adce3ed7b04c76ad6c97e496344eb0b51573b4adce60b0f2f0752993e1300d1fdc1d8d34c2d7e19f0470033265d4914cd3174300992ceedf14fad15dc9bc408692d12153e34eab2f20e3ee37dafeda0bac98d9c18c0ee0c881cd19709c71858e9d33c23380ce706263c6171b33846ccc406263c607333898b9c11ba717d8a006346494e1eece43918422262b4d467ba6219e20a306f719378a66dac051e9fc25e961a2e9f4b63d4c234d271b23021f886fb486a9ad89658de24db5ed56102477fb54820bb8b86aae2f1b3186701b317c44b106edab1f0bfd60b1b0a1a07d377609e1da9d016d5ab0450e0ddc9d66a64cf8abfd5a0fd980d102f7274e4aaaebb6b3276b7807e50b8d21d018814c143e4c4010a42bf0c361b2a3aa5fce8f76d75d71541f4581f2f480babcc52858bfdbecc3d93d4e4577ba71a5773a9cc559bd4ae15572c96432d98e14433cc6543086ebfc859feb4d872e88b95f000c369acc2f8c98628cc0fd6fae309ec8373088705918868dbb0b71c1670bb8ec7294e92a8a55a6ab0c0c19dcbf9f8dbf5b23deb7de5e32d94e7f2ec97d7f0c655fdc402041003e788c0080106a6cc604c0e7181d9f639ef81c53e4734c0c3ec7c8e0730c103ec77cf139a6c9e79814f81cb3039f4d3b7c3609f1d9b4e3130a263ea1e0c1671390cfa696cfa6187c365df1d994f3d99483cf26217c3625e1b369033e9bacf0d90486cfa618f86c8ac3e7140020724388101682d078b042510da8ac30a6e0756bc54092e08e282b50f90906dadeb6ceb43ad226a0ae8e275027144757c71392c8a012edd368122a03b802322a109a5e7c31bdd04d2f62985eace033406c4e6546e023f80205028a87bb0352f072d739096a48aa0719147cf150169a315190729dbf94073eeea91e3f5b8dbf4f49eef964d4459328da2ae5b4c46e46f7ebd56a0afd7e76ed0f507ea6d7b17ddfd26e68613024fd1b7371f176658b189430b1583c4c2c96256bce240102dc6fcebd2b6937a39fdeba8ab39f2f6fd1ae722e0e3399b36b2f5a24fb774868ae35aa35cead2a4d443f7a6f7b77c55ae2ec549adaae75d55c5f22c62fa550e8ee3229b4f5250227864450c331bdaffd8ce8a8402b61f4db61e9ecd01adec938477f97227e9d9d15de9666f75710d4da664c8ef606526c77cd3978e77ca1a537394cf091b86e6bf38774278ad5eaa7d9f2f58f28d6fc4c43b352ff8daec812671bfdb4d5235e812085329be527f1d656d7dcbe25fd44223f56dbb5384d84d630255fb45f921889e2189092ae22edee4f7831104e5b291bbb3676e5a4fc389a35dad8855dbf3776dd1ac4548bb0d0fda39d3896a38d61d77eec9a52f4e0ee40dbbe5c452176817897528e7415c92300822770dc5d026e801b54b041318117499b6338166211469638b350d63c14be766f84a4df6eddbb60b76da7ec5cf7d6bdabe6219e1e251c0bdfa63326aa9968ebdea5776f145e6c330e0a6ae19a7ebd70ac08696351ebbfbfeb91bead8dc5f0df157eb875effa5ad55749efde48877f1f0bce445bdba31c76e99bae452fbd75efaab7d512ebc6b1af555858bfe8957fd77e6a1ed2adcfb5bca4f5d6bdeb8d3226ca5ff3d01f6951fcd9bd91b6a28b59096322033bb8fbcc800beefee92ad2a7a9edda550dd3515791e877b3d91bddedfd994c4ad272d14fa8457e3c3d54972249b350eb66fc6d2f9e95faa3595d8168e0c619a96869b7c434b1da19ddadec8feef5b64466a52632840d6350a3a4ddde76ebb1ba3676856f7b22ecd27da877b722cd4ad8c6ae8d5d4219138971051419e084c82a2ae8244b518cbc42990e25561c01468a390125dcfd96434ab8c0fd4b05befcf005cb97c341a258653b07184934f9c6a2b6f84a6865bfeb9689a2bdd1747594f902582c520bc5f6c366120f9849284d249c8040988904f83a851081363c0263dc3d0cab9e95ff352bdbaf65fbb54c142d2eacb36b4b197e4a0c784db985d7300180c8dd842325a8a0dbf09aed81d7ec16bc66fbe035bb025eb34fe0353b075e5302f19a72c76b4a2a5e531e6004252e80281ec2f600f090e10c77285bdc6336b812b2478a841e59683443c06ac414f9707713aa38a104cfdd5d1566053ab846e5ee0e8405108ab8d3079ca065b66b334ddbb101272b7eb89fbca8c2e711eebb5bb1f8d5ddcc1d85863b8a8ce78e8ae26846061cedb258e1df5cd2873477d40bdc516744b14203ba107d8b6b86d1fdc5f0de6b6703741ae0ee930146306005f79c19375066cc14c5608404dc5d57c7eb53e2a8bef0c3655c7347e5a0881a14b1338b28c3bd88298ac0c02ca2745ae4d2f963b1f402b6dbca996ee120a98a409a43bff081409a93310b04690e888383a42aa22ba09b0aa4ac8abb560c6a01896a4a5dcc47ee8afccb24c2892b614a2292a39559b2ca6429984141026c70af371cc3e32385bf6d38b4450b148ae24ff8afdc87ff8962fd4050ac3844c25bd668497624911912d5fd0199c831fae55aa358539a6dc617db67ca960868eb7ab4757ddd5678876e2b57228c63e11d4a12c53ac2308e85ad4ad6a0fc4c493929b44044fa628b5d4238b60b2b1e1fe9b65eb755cb4baeda10d3bbea6c8bf86124c6aefcf7b60cf0863b5947bcdd6740300d90330008840d063022b3627d2944e14f20b6f804c2e70f6ab8bb53d67731dd1ad3eccde7f4eba32f865676f14aa746bf21a21f18186af2dfc8e6ea48e4cb27e2c30c3ee0e8c9cba8ff14474e081b660f1b50a20722f0877fb201aa0c1419b689d62ff650420f352c1cedbb98a04b08669724ba0cf164459facf4776122b3baa7bb2f3b512c893676a1c67047b9c01d25863b2a0cbdb1a88dbc92a3c0f882052b5081172940c109ba4099c01d5502771417eea82d5051e820c86681308e61c1ae3768404602b79230ff727679538a22813b4a0b774f392a0b771416eea811bccdee2811b8a342e08ebac21d050277d4077c6a81626a0983f2803bca8a14aa0a771fd255a40fe7c77269ad453568e97d5d524b75158968e3dbdaa1a5fbb5de160912a1d60ffdf66b2238fa2dcd8ef862dae70fc7fc9b5eabaad9efc379dbae2acaa21886714cbfb5d919c56f6da8f17172c373cad9d1aaed8f74f84042103ac011941e05e861c01044271bf8cca44e3704508534b841c31734a4618a49830ffe51bcf7c374fe922861cad234b3dc90c506a717d324540a05c289357050c01805b0618c2e409c727071ed85763a7cf1c542cea0e361b86df878fc11874951acb2574d2c3d7276dbee7cf07027c3dcddb95b21a7526d7571e860e022dd37f76db9863828f72e771415fae58e9ac21dd5e48e1a935bc28a4ffb81fb687bc271fe172e76bd2dd75b904df5c904029dbf67ca252d092d6b1d1e9e9e5c9512b6741f5ead7fd4fa4b9c53cb4cd7e6d432139194a59bae454452966ace956e9035e728de41dad697fe27b295483faec65e8798f6bbf05dbbb02aedfbb09f9d43ebe0a5dee17d9d5fc86f7ff82afd76b7daeab695a7a70473f8e272f4ab613afe6de7a8a67dd6397c71f48f740d53a4202a42f4c311c5baa3a2e1b65f665b498a033259c243791e578de8a79588c2fb5bb44457e9a504e90a74145620187685fbb5cee123d8c6aefd481bbbf43f9156baad91a69385f7f514afbbebf029dedc7d846975a0ac1b6da4e992ec92be0b7717f1cd067740ad0dbfa53b4a0a1a77941251b8fbb562585fe8471b0bef4f4e6d02b51e662dcaac05b983201305c124fae120d9379b1d91684d03d30b0abc8ce1d3cb1b3e8340f90ca2c6671027f80c62e53388273e8338f21944e833881a7c0641c408deb401408dc7011ab8f704cabd274470ef891fee3d81c4bd279ab8f7c491bb8b1006146e13c608dc260c2fdc268c32dc268c19b84d1871b88d189edb886164078f0f0020c6c73d3140ee8931724fcc927b6240f7c48cee89c9e29e181fdc13a300f7c424e19e180d8899c23d312570f71f36227c2af7be1ff7be17dcfb44f7be19dcfb7e70ef63807b1f05dcfbc44c1ed4f0c9030e7c76c9e1b34b083ebb08f1d905c786c60df7e9460e9f6e94e0c6e7ee3421f400610665b8cd0cd4709b19bce13665506e53e603b72903c46dca18719b329fdb94f1719b32446e53868adb94a9b94d19ec3665766e538607b72983800fb838f1c9a5c72797229f5c5e3eb958f1c9c546843000702f8c00dc0b93e35e9815dc0be30ae3827b61aa7b61b67b6178702f4c11ee8501e35e9828dc0b8385bb934013020822f49815e8c26705d2f00966874f3022f80433824f30457c8251e213cc8f4f302e9f605ef009e68a4f303a9f60b6f80473009f608af00926099f602ce0138c066a4410a1049b119430c23d2528e09e121b704f090fb8a7c416ee29f102f79468c3bd2f3adcfbf2c3bd2f1f0f9a1d3e46f049f9f4f9e1d367c7a70fcba74f524d4d08248400a406041a2d3eee6909724f0bcc3d2da17b5a4af7b4ece09e961fdcd362847b5a90704fcb13ee6921817b5ac0704fcb1aee6de1e1de9620ee6db9716f8b12f7b6ace0de96977b5baa7b5bb07b5b66706f0b17f7b60ce1de1606f8288184113c1d250881c13d21ef9e109c7b4274ee0901c2039a1adcbd1a78b85783e75e0d3fdcab61c88e1bb8f8bca1013e6fd880cf1bb4f079c3097cde3086cf1b64e0ee1ed0cc31e0f049c60e9f64d8f82443003ec9b8f149068f4f32583ec90072f70f26104ce31ef6dcc345dcc34cdcc330f7f0e8ee9e8f1a24525e83840faf41e2f31a2488dc3dc7ec1182f700c187a8009f62037c8a14f02936e15304814fd1043e45307c8a68f81471e073a4f1394e9f63007c8e487c8e29f81c877c8e517c8e339fe3f63966f1396ef16903801a11524e5016a8923a7970022c3230e08b251d6f0902ae1794947a967896469aceddb55002af256dce034ade77ed48450c0a6f22f68363692a3a0b6dceb90096e583b9005b6247296ce47c26a56421e50bcdb896034f0a096474fe5a20a27a2dc4e8f7b9d7c2072dbc9a786561792f9f27f40b99bca432c4241f7214a1421b9e4d2c0577b7712fc98897f4010d0aa52cd7085c55782e301fb55debdac145a5d206b072f9a82155f1ad90721c9d80b2c28fc1883ee30d3b72e29fbe7628ff4b57913e1047c562c540f0c559cdfbdaa7ad3466a2b6bb7739f95ff4f3d7e867164b4575ad456ba5b2adcb51464bbc2bf16ea5ab2eaf84551793f2e91bb28abf6409d5f6c9f07fef07fa604488505df558c34234e80b160b4a3eb05aa620fabdb8ebcd4d0edefb521dcec5e8774b0dc6e8a7e9f875d7d0e67edb52065dc16b55e0ea87e67258242b92de55d39d488e56eb6df5cdaeb7fdbaa49fce2a897eb326957e5640b00a58056f4abfd56a068274ac9fb726cbcf3fd2ecd6f8daaa0dc39bf314d500af091c9fb1452191325282c003500b98b922a5f431d94c7e48c39d98eb10aefe14512c89eaeb462b91308ed53c248a3528474b4ae1a04213ebf71dfa64ee850a4a8cdcf3f1c2f3d1c187c667865268e2f42385d07d8414487026485096ce794c8a685fab91e12d29012e0ae22df1f19490f12e9e12225cc90a3a7f40783d6466e68d7b3d48f4f4e0f5cc9cb26a1e8f073c9ea2130b3b68b83bfd700d7fe3a7b5fb298b47820f4fa7c63d491a49b070775ae9d1a7f78793e9c6226c63d7c6224c27e907e820e3e54440e77839d31d467b266fd5c451b54bde6aa4daaec2cf388ca36131498eb74aa1e01e0a573c895158808742170f854d592b0f05276409f350f840b4b7a053171c0a30c38435b3e321a1320f877477e91f9e1e21422801881a565a78aa2fee1a8a138b85ca89a74ae11a22f28900372b0f8177440a0fb1ab65ab40de91afe21d49f28e0c1d7972c4c98a866fa50a35e2002917dc5354dc5353dc534bee4fdc33e285bbbfad02d126b63aa3f543ec3aa561040419b4b6e209605cb495e59db0f24ef0e1ee4e593988e8b0d3c10b6a30c60949112759886ce15110094f174021c0dd4f29253d2b35ca03c7828893903764b5460a8cd33cc2dd08aac47334b185674218cf841d3c1356ee620882382dbb18a476938f7ba61bfdd6f6336abb36e32f73ac86716efd60d7ee8dc2dd1b6197eb8827a4c6dd91703f8110c4c7dd0b52e3bec40322e4ee3b71c9128e7dfe92d0bc1f4b783f8470ca5ab14498399dacb857c2ce5ddf4a75497f57db0ac783078f1e9546e3c183470f9dfbcb92c95c492d9894a125d9100b3f52926230998c95031ddecc0f7f7924b0e03a7f399678360b50792334c0fd6d9524ebdf5837f04640a2dbb1a78df94972fc7d4bd96947e913f0660ff76c3cb0e1e1ee94890438800d6aa5489524229cff059cff851cbec1b00be77fe1435d45cab588e915bbf516d3fa8f3416ab7515c97da648c9c7f28ea58b1c7391ae22e96238dad39e843d2d042fdcfd948a3916ab7fa6757f1b3a951e0827782004e17d5046ef1e67cb25c944990414dea90810d8e49b131bd8e632011198c0db5186fb6968e6ce5454149ffefde2872d01a06c5244b491a281edda21a83894524329a470dc532a9a1d4719e710a76edc5347c0783d52ee35f72e07783caeb8f4cb277890dfcf09068f460dd7f9f368a6f0689a60c2a301e39e3292f274ea8453aa486a480ec30ac5a371e2d134f1687c1c0a5d39d916c8db91c5dd3d45c4dd695243860cf17468e19e0e9dce9f9f705e8e2c74fe92f430c15c49ad58904b298a8cca0f12beb2d38d97c389ebfc9523a62df97472b0ec725e4a872f1f05332ed21629c4f94090ea5aa90e2bceb3d6cc1190eaf2b69b80335b13dc3f09ea71dfb1fc70b6fe1c06afa5598360cd9554fd88615be7fdb6b7c128bd7607d61a66851b5b5d3116ff374babc0926afa6918fd92885a44f45afa7db66f887e5ad4f4d35f2b69346c0b1f87b9d6f1b7fda19ff831fa695beab1ac5d6cf34841ba754f411cd57e0deac76247bbc94ca4adcdfbd6f161a1115947198b95bf9d4f2727c70636b08109e89398a6e9a63d930c573fc762c9c2efe200434d449a15c51a147e0d6ae03e96a37d7156c324ac12269a036477a212260a2587f630d5a3550bbb62f0d78ab55ad28f181662cc8228fe847abffea14b3e2831272108c509d8aae15ae99ebdc6e0d6bd0bdcfa2bcd367f6168c79badc4b5cffde01917b011f3828d8f8d22930dd41a39a02a4a59d40a65e93ebcb64a921cd852d8da6d254b80b64c19a4f1c9e003320853a485272723f74f8b62a5d5bfc5eaacd421933d7231c08c038411c18d7ca6f1725591216a34f138995869b8022e811fd408e247338d2fc41aa03161a004015074fe92e4cc316e1e863fe1e755b89335c7867eacae1743b1c4537443627d21ecc2d1f0d1557a71569bfcc559dd25398e56bba7ac58a20af71415ee9eba406a8a914625fcab14be7baa293506d76e4b144b977b4a0af7541429283a907a22fc18ae7120b5040ab8c0420553782a8842054ef88ff5a62ce084f3f4844a98a4c4ec1ee79eda800ecfee8d68ee290dd45d43f75413bb376221c5c4ce95744f6520b4b9145fee290c3ccde225bd7f5eb7de629f3152d8b257c93d15263fce5e8ce49e5a6248ac347b6fb48f89dadafe48ac9666c332caef72a9ebe7d8951d907bea028ecb98680754c7aa4ba32952300dd3f014f79405c0b88fe5d0677cd335e85a4cdb16487ffea21d2a3c547aa828a1b2840a132a2950f1a1c2c3c4628d349de6e96162b1787a98582c1e2616ab8709d76e4be3da6d41b97f94f1953a42b97ff46375e92ad28ff5d65d4328badec2168b753f1c6919e73ca435a943d14e81e284f64bb7ac855698ecf8ec5c5fbb1003ed5cc9b0b50b311014283c3d4e787a94f6caa774e2c3b353fa94bbc72961525a9e9ed2042a488183a0054d1a1ed01a189268683c4081236ab6446183660341506923c601f757c35d02ee2eeee0e9710387cc09777711926802072e5c76d061071fdc533db8a7baf080030f5b78704f71d9a265071ddc5339e090cac13d8583c7051bde82d3193738087a5cf8785c08c0e3c2b720c2dbc209162c1e0974208190bb7f2450799eb15fb8bbcf08fd90c5d6c28b164c5a88b45be64d577ae6260b28b2609285123d03448333c297e1677ae36b837baa861401dcdd8824add70feb67bb9ce5e45656979b5655398ae9077e2045422965e91afe740e6ddff6cd4eb4584767097d4275965024d482785f3cda2afed00fa7b3437765e97d431d9d1daaf3eb34eb553fed5521840f40ffb8a2dd9de6d12388a5c12a6c5538719f2100ed6686042a28400511546c2a5a70f78b29155a7ad11f6d6c032b6bf3ea69f6b15898c6f95f10c59fab9493ae527d6dddc5565ba48b6dfda28c8366b4cce010be0c3b14057a05a44d404b9dd02be00c0d20ecf53aa24ea805430ba4f3bff4c6224cd7302df28482492808d2af866fb1c7797fae4c3b3487823a545b0d83d1d77596a343ffb6f50d597576324eceacd42a22e12562a9d6252e6d765ffc2becda6552f87b0794ffb5abd077cb4cf1b6f2e17cab1f15fdc2bfb9af2bf9059135073bc106d126f336608303b9e26482fba7b1fd59cde50fcd98887efa3e2ee3d7d805fae972578a0449cd3d10fdb46e00e18fd5c5455314619af8c06316d000165710e03171c4ef72db291818c38230e18b48b9cf4ff6e028a919d31a0e1fbb724f84712c27b5b04b29fcf05a29b0f06f2e81c2dfd72249510a353edaba140a3f87c33bd4d2b550fc7415e9bbd85a6008cd9285864f9f40a159b2501c95b6df7fae85807e9ad2cf453f5b85edc49bc90ad2aaad0641aaf54ad76af8c39a1f888260895da08152ba62b1e8cac9686f30b2223da194d21928a540f4c31ad6dbded2b17b5f4ef07daddefca50577a754eb8bedd16e5bd1daaead2fa49de04097999c191e68ccb0b400c192253d064c1b3b39fb61e1dbaec5d1ac51161293c20f6d7dd53c2463d1b29e00eafcb517da6d7b4bbcd2a178af32ae7dcd43f95f5fcdffe5c832cfaa4c66bb9656864f2b052d0d06ce40d0666b170a053f16b8ba6df2858a36b9bbf6cbf8c9261f0e88445791401588246322504575c6b8f62a5d2bb502e6feb25860158af7b5bace72f856491de6da47412bb489cc766d1590b26afe9c12e7b37dafa2bb5c6bde3aad6df8d56a483ab5d6ee9986603889c509cb9bc320d55640b08aa674bf6eb5284e2c67d44acd432b9a43ab80f45ab028f61a1292b9202529066b158156c02a19e7f06d55f3d3f0f75f6c05fcd9d6f5887ef9c78c592c903ea9fa70547af738160bbcd8e63ee733ddad36be7855da15ceee713290e96dded9ea6c05fcdb26ebb81357165fc991383fabf7d69cea679908c509553ae02642e4efd6bf2fcda9a8586fba3eed975af41bed156f3adbbac97148f7a1885d443856732da994c15ea5f0feb4745881f40e6eec40e65a1ad21dc26427bc783becb003b9830a876abb7a1d66a0c3163ea384869fcb2b36b8e17e820116b2e672e822872372e821071a7210355d694c5e4ac31c82e0a0867b0e5faa290b0487965a30d710d190508a862c3f3878d91f0e44353f2be39c87bc1bc6e8e2860fdc0006875e6b84d6f00d3adc40a58a24395a1b1ee0440d6fd46083bb7f7963d7c9fb6206a8c989d28470e14e5866ace0308648030ceeae077073fa8b5d184b0973558a1201c002811d26b664f1e1ee3f8486cba71c50966620fd253ed31f91388602962c4f60d9c1001b9fa4209dbfc7e53ae6de55c2bcddef9ee8caf097cf1218ecb3e58c7ebb4d84c86789d644accf12188c86bf3ffc58a0dfe33013eda66bd18722567d381a16e911fa81dbe7dbde382afa5aac44f403797a4a1004b7c622c5207865a5026b58bfcd8ab41c27383115a559126f5a9128387efdac2bad86737418887e39d7d2ba845fb56bf5bef957f4fb4090ee661fce0d594715d5f4bb21ad7649522dd4fab1ba684fea8a63434117bbc2cf91fdc372d3f5665bb84dbebbba3fee07378737c231be6034632cc3494c718ca868128a6384d29511ca22315d19a1a28a5216b552657c623c42e52e63c586eaae42b876c99ad3381a1665615897703ec424288b48bf0c27c6ddedecabb1e17eb2d1713dbb127465c9952b1fd055d0e36a4c01febfaba46cbfc6bae697c96a7e59eeafecf34dd7cf389ac5e9ff0052d892c944d15623c06bafc6648c376857b8a76670f713161db26e3ddafdb92623eb6b9dad7d0ea1048fa5728fc5c43dd68f7bac24f75856dc6369f7585ddc6329c03d1618f7584deeb150e01ecb0cf7583b70afc90f770f32029019c49bd48790118e4861857b5284e19e146bb83786c6bd3141dc1bd3e3de9822f7c6dcdc1b83837b6382706fcc03dc1bd3847b633ce0de1831dc1bb34613cabd2612dc6b2ae25e53907b4d53dc6bc2ee357171af0909f79a9a70afc903ee35adc0bd261db8374511214180fcf0e1a1c0b887aac23d140bdc43b1e15e2ae55eaa0477b7a929818b1a9f5c10f1c9c5129f5c08f9e462c92717379f5ce87c7271009f5c7ca1d96133840410721ce13307067ce698c2678e14f8cc81864f1d279f3a88f8d4a1824f1d493e75c4e05307cea78e9d4f1d5a4c181244002ec48423454c884284cf2848f88c5285cf2860f88cb2039f4601f069e4e3d328e6d328fb340ac2a7d1123e8d46e0d3280d9f473a7c1ead7c1e45f17934fa3ce2e2f34889106ce61c2ac3e750199f4425f824c2f14904e49348e903113c200104a7f1f1c30b904f2f493ebd549f5eb24f2f04f0e9e5079f5e8ef0e965099f5e3ae0d3cb083cac6ba8a49478d2a2648806040000000000d31000304020160ac562b180583c29f01b1480015b9264b268461aa95118530819628c01002000020000001811038326cf4a8963671d8f61047dd8931adcdcca1d39038d160ec8ee2cfa12e3031b5d8c426fafe237d620a13a521e824cbc6159218dbd21fb32c9c49babe63bf8f1e1cac5d0e7cab9fcfe8774ccec79e4f76b3ee90ff732aa1ba8e76020e7ff5b4d386cc0dd79907f62746abbfc776c4ab946fbd5cf40fad7655b5bc23eb09919f9e355251bf1f4c429b3a3177f81059bdc0184e285bd505084081e2884f67affa15236ac49a8f3cb44f21e405c06817cc25e730a2705aef24e75ff8cc25fd63e169f8af6c63bff763f62c1cc5fe5faeadb6638fc7e5cefff006e116d2917de96daa4d0e7a9b39ea78e6e02af4b9a20a787155cec1675b43e8c885f77b5c4ef719f9cf9c2b9d7d68e2f1b61010ff18a672ee8395b7a80a8201552158a36febcfe932cb586c48607aeb9a5375de91b8b99fbf75e6754a23f07fa57631e48a3a71c74ffeb5c49f38bf4ed24120c7479a35e322e9cfe13c401987221abe16936716f9bb85b02bffb4a8e23cf5e3cbae1d006122583fb7cf42f9ad532520f6f6062ea3ed2baa3a8018a848212acdc6da613e430ccca7de62fce60aa181b024f145ca6eb98e830f7c546377d4d345158336b40c1e752ed9353802523c9fc28c5fc3cccd2303d082f046b6243c727317333d56c7d85c198602a0d30bb1157d3b9ced084dcd95cd9bdf476a6143b79b61942329f4bc03d0cc84c02c686a30b90d6ce9d91d01417c6a1f441134d215e3273d2ab01807197d427b7576edb43cea8ed3333f0f737f771a3848ec4a59ace76161b1c83aa347ac86bba487b064e76f1d99e7a9dd95178674bb78e6048da901c433286a471f2ee690e8d9452c7cd600c3f63f46472e6417007cdfb6267f54fba225b71ec0d24ad6fdeeff6878ebec73a3b129cfae41ff164f74eb9cb123beefda7b7981f0fc33300f283e4a1e7f6b22ce28acdbd03e8b6309114a5d727f5098cc3e071100d7998c67762133c56b59c1d3b8caf7b7b1c856af9482acee7c97504e4966dbff1923077476bac48ac7ea277654600fd513e5e7fe3b5cc0b48dac6014d98e0346a74fa05b586850285edb02a8b8447c8d22e6894bc1948953c2df8c36648fa7f9e82fac0bf68d477af7e059866aced377e9c4c38f2b2d128b9d23ce4865e5f24e9cafc436b77424cd8c6d83cafd316cbe1fdbd0a750fe043b50f94ba038efe5f9e25a0def07ccfc74f55cb22f92c4c150c1e764d56cfb8ec8afe5ec33dd80133cc18a797581256a55fb724c5a465aba58b4c6e5f2622f7501b0c717cdb0bbd9fdb1fffab48ca4c5540e568b73d7bc94cdc09fea139f45f6fa0ba684a47fdb6550b0d1def0d06467cb2f7afa3330c9f32ad5a1b396c0e3363816db87cd3372d34f431b8764dc3aea17e3bcc46706da0fbfb32fac890634abc2f912217c817cb35b70dcf6a562b807f01862bb3cc4597e43a73e32cac8b5c28b1fb2398023ed03f169219ab34684af28d04fbe7417d9a3555f49c2b2b18f18438c4ee14eb595604d4e57c8f79f66e8c5ba3fbb606d4d2e152189fb7475ad85e3466354f29f598e23507bddc710db9d36be40a7755844794265cf1267189cabcc16f2fa8cbc42d3e3fc17c1c37bdcbcaa92b45844352eb2af763524dabc188496b52f59f916fe333726d7d79cb5166aa7c96dd9bc16657eab67c801850ddc6788d7e042a22ca02b3a4fe9ea79b1dd36b7d6d23b115d6f57167c7588b62095e7cd41a62254138bb8a3e573b7b332a1648763faeeb39dbca49c9002211e8b07476d4cb7c479e36906a44cd2104cca48024585df2e32a157c5500b34f04c362428f35914b64715603b05cec24d6658d1fd1f3980339d51a0314407cc144889ee297c0cce7e4af9b0046145836e14616e57ab20c63a62d6bbd01df045c69bf173a4e658c20bf430544ceed86f2920e3a22ddebcaa4dcb8850dc4eb263c56daa000884b492b04f1c9daed1470655bd912130c8826cabb08bc610c79c0af957a6704797ac6e9b4579c74156cc37f98d0a82ed0c1a132f028d9be144c5482d94041d55bb67dbf0c786d2667bdf3eb0f2ac5046608db4f0f56da8cd3451aecb4e76e87ac6876077af68d2084eab291ffa1c0cce9c286cc2f14d0e00ae61f9ffe2ba4d28dbc4ce46e271e42e687c40b9ff02002ec8c93f829c87a2e80aeb13c17b2333b7ddb9cb1331b291760defcf94aa49edc9ff2490bc9ecf068c1fb10bac3ac989e30afd9b799c366d2cea9706ffbe282e024f5d3e9d71d5eb6b9d9dea4fa0b61b0f308992159e6cd544e1360ac3fd690bed1858f43495966e2c3311385f391285308f10fffa0df2335d9ebe2f508651abacaeee1b101712d43778ea7567473b2e1b9b91eedaa748a84306057b80d2416498f56104f1287f93cd1a3e03bbe069846f8fe48492819fb88bd4bdcaff733015996da7a3e0814c5c09aba0937b47f0a49dfb17f8217994c7a0c88befbe22038a00934f91df9b1aa930fcf7cd8f0025166f1648586808c5cf621419eafe1eec5ac1ca9ae0d805e3001e493fa8cdef5303c68c5f51f5d7a9e41503b2427007f222bd0af5775f77c24085cb27f858e007748b9f8356a1189b1975ef9b7fa430b707c59dac851dc68ec1eb5f5e8aadf73b16360d2016bbe7cee9f2049470c8e8cc804703f9e450fb26df38d6c615819d605889f0d684b803f9ad767b7da010d38aa687430ace6044a651b0e7e7d468462d8870587ccc68735dffd44d05003c03d2b0b9eca35f29dc27f633692febd06a0929205f748f2f2727536efcfdd23fe2cce9fb5b2b56175baba519b26e40a649e3bb5062894f1afcb7631c1bee5462909a9c0af433e978c0805c2862bf6971208388643918973314675555b2cf2a0b79e2cdb722bd5a99b7ca137af52f0f78822591eaffad96d2f08f176b970d3070d6c1c28660a92274cac83993dea895066c2bb6185b4eb5825a64e09cffd5b002d037b4ebe59774ba660a50459d0ffb13399546c562fa4b54f6f8c23a59937b930af83d8cd29b2d18dbd7d42c5c7b6149ec767072ce8e16d2b147572cb8a5e0b33efa84b940416a25e984ae1e6cae73d81efd59bc80c7a9652f2fbe1c7b9f236dceb736fe79531c8a3828dbdff13cc1fc01452a4d53f797f7978ee640ffb919fbbacc231ecd5c98ad602481a09aa9cb486a6a18d01a1bf40f69914721d2107ee1cf9d2a5c4e0936e375992ec354fba04cdd7fa2386d3dead855d29ae90e2773d736b1cbd3d1780e9d73e6ff3fe479b5bd862ee00fa89e263ba348b08d4f1937263b1ca579d5c94e4724d2ab23a2f1a3b02cd210474dd96e2df88440482e89f79b914e310548f1f84934dc848b5afd978b508b2dbb01bd1a8b6485f5f7dcdcc1e84346cfb6ad8f84cc0daa4a32bae41fa14fb661f54d5d78afb7d683a25eb9889dd98a4be7204c93890321447bcc1bc1eb45c9f87df10ec92c5b8121559bfdf18ceead18ecb26c5b4f07674d7e8307c44d13f8055a4ba143dc6804f8143f68e95fb98466ccc0ef689fd1e5a980d97b69f06881cfa6c36256c1abe18b3c8c1a721b6409ebebc9139d44b21737b18637d22a86dc4da9e51c5ecfca901e538fb197203b90e15d50d4088160c749789021404e85491f9739b92cf21d7d4104bb7dd7891d77bbbf8a0401a98c55bc9777957b424c19a0f7da93edd65c5300694d90d9fa12594e9b29c1dcc8aa720befcaca965fb83a8a8a59baeb91e0e3e8c7513e77b80874e4f23d2eb75d60f0263c0485c609067d272dec54b980309e33fd39184e2e07fe53f36ef259437c8eebf6844199407a4d3cd0376396a2cea1dc145c4aff369403cd38d27b93efc8bc6de19ece67a4636bc7f116072d04413139ba4d70a5065df01571074d7055b6ff57366987df88735d90fec45afb4100e1bbd82abdf3c5b9b891a88bd57e7d9277bd959c1cc5d46d7e9a3de348c7a11e651660c55d1d4a98eccd85771f0e1f9b8dd53cb6916c9001c13747eca48c133725d887eec5142b1d18fb2a795977bf55f2c47a08d4182f2beb951fb25d375c20c838061314ec2398e1269d2fa98287474ea0a2e35950ac7ba1352820cbaedca904beb7bf062afc36c473a95ba149022eb37ac2233355940c917ab17243159faf399e8f46c6a8421b4e564d9d8381315e0a2813c65478a4e8337913eb2cae2ab28321ed1d41ed9fa8cccf8859c96f82e65a488fa418266344d78ca041ee9bc45b3815d4de036b88a2ae814c0e603b2f02ceb61c39a81f0d274d14366b25f0b017b5cfc062f62fcfc2ec2ae0bcd703ce24ad119fddecd900e0e5531c91727d2934896df6fdf13801b90f8b6f08d8510eb2afa77f9c9aae26c915ed3c1d20bd934b90feee037582be90e6c647df08a018fa390524652ac525360b3686bba0c6376bc2106647b8a944077e5001edb23db51a1fefa94df2a0b0011fdbaade0fa0cc961742594e6fa05db85d88200e2a642746ecdea2c52cd1f14e24976bcada97b8c6114e8a728925057724110f9024f1c01138fb60077f455a6dd440e1682b09dad9026aa263ca238631cd2981a5a40db9c4a67c1e063aedaf4f16aaf7683c48b88f9b88fd9821380041f7ccce832cae80b074d392248fcdd0a484e73418d4b5a5036b976e8d5da8e917456033872dd10d20fb4b5a21a0103214931d2eeed5c27aeae410231d412d9216f1673b86176b931a043eeb82849e4c649e58583be9547d4322ac889bcdaad704b179f61eeb095cdb31a23c475645145f2bbea31063b9147193758d7c37cee7bff4f287d21eeb97144c9066b03abe78423b008bd4ad43212b84395cb45f2a96d44cb1e2cb40ff546750c18583230136392f8ecb7052df99c32d496d3feedcafcd446cbfd4dd5a867f4511cb3b57d4937a7ebaf9149b0fc5e4f090d51020b0b350a44adeb0f573419ece4b6a0b535efc3211698632c093733d318fc77eecf2e9c7564060d1f0bbfd85dd6244c1a0ced80ed433bbe2c4e92cc0f676c55902d98c18a44afb4d7855db836059a02865c42b4b68e573651a8c08908856b5082b877a8dd67e5d1bc2d6c8b69d82d6ca1adc102065cbc5a64f00d022935cc9e44f6b17c73abf7c35523489b61a8b9a015c019ea238bcfc1b7908e42dffbe4d5fe62b26f0035a0834a4c8cc6f803bc3750a97c3ec7953e2265a5effea0aaeda01100e3ce2b415bfa24fe9755860a89f1f1c1bd563ce7e18152bb3b4e76f44c3651768ef1ee8610e6dec7a9809a5b0bc4085e01bf8f177ac0f2a6ea66b35852febb7d6c68498403e789d97bed21c0823ce1823dcbfc234e84e328ac0d1d93d217e89efc68ec2c782072d56ec9ced64e83a4d074674ce3fcb0b50cd8654ffaaef12c2bfaeaef00f48620ad8d3f99fbdc67d6aa95abef6af4ea206d9721b920ffceae710df940e7e842e0f4cef1ddaa50ae1934e66f43dca3236fe2e116c01f17d3ad41f7c06c2567558d3c9b63e7f2531ce3ca853495592d105e15092076a06de8e29962c0c704371baf8fd2026760642459d7d8e49cdccf3b463153c52bc0fdb8601e728773575ad8501998411bd380258748f8d106d09deca6d8b5dca4365c0e308352e63f6159036d42a4d6731e38ea005b437e1adf314cbab326ee9d76799d18102f54b031db8369513cf73aa2b28a139d761d9563445a7bd6564d5f6bb592563ffbbcc0b1170337bf88a3c36a0c12ead9075e19871359b06b5e7c0eab43a334b4a07255850082304198dd301ac31f9656b39959d936657cf6cc9f0082e3549f679cc6c669ef6b8434b0075b0477e829d0bf34cf494925c5f0c91b8763a6098051ae1b0bc1a23665e848a1cd7a73384bca6654e5a753635d427e11de36f721f2f79c56d7b4fc4db1257e127c6f035bc983e115eda5616b95e85059828fc37cfc0e1849f9fd3ea6c7768aa7564389d4858a5648c265f3b874aad032465f30079548662f7914a072f2b195981f6473d7cb32300917d7f33df04f3e6c63467fb9c02818995f8c1b78234e2dcdf86517db96e98998fc7b364953c0f248cce38d344030ebb1fd7f51b6d9f8909448814891b409b58df7b804d1a9ea297a985e5a3dccfa9c97f97c0bb4d4c252c5e858c830da1f0259b8114c6c6c70b2a7e44c40742e9b9e2d312a1403528211747099d8ceedabdedf2dd1eb3601cd46f78db649b0237cef7b6fdea9c157f06b1028e92f64a99b94ca193a3b874d90ea30a34faf11b42d45db58b22e463e06b20982febd616f6fc84c9581db82c60e2dfd3fcd9f2a5e8a17ee435ef8c2dcbc12bc32989166364ef5ac3b698a7e4ff340fa08024eb412c2a02503cb73ef853a25852f6e080b2094a08c6f7a1b1c00b4cb42613170eba8b5a5d1e9b7d378b5218e88b119d6c0442196a981dc41ca90a315484a4a41a7f28fe6c12a50a7b2a3b89ceeae0dd412dfa55227c351182c73bbcb2bce88d4aaebe14082c1ef4e967b70b331eeea88679d9d01e54d43bd2e80640be120fd5f73a09652c533cf0d7454a0cc272bbaa67676749a741d31e30815430116bc9947c2b680d2e9cd5258503d6c1ead6ead820ba5946180761ab112fbcd58de4e0b68062e03b776a78f288d0972b5921ff1c26a37d02d9ef41952c80319312a337bfc81a63166cee040e501c84eb6966ac29df8b56ddf3d3a3e09cbae377b87d21b798eadaee6c32c36e915272e160b6ff3d8d77419fccc3e65cdc7bcfe86155c59e116517ce2ae93f5f0a32429936a03c9952ae68d16200ac779e04837e814ba59b97c41663fbf11f0916e03c50123d82b8a410f365d5f02abc0f5b5dca21a4dac25fbfa96b5a1574191dae80fe654b1a6da037c3b01098ba100c4c232c689479c0f9ea0622340912c9bb8d627bf600ad10d10b30e54401d1786d32a9de5fcec10168ca8ea64141086185f9ad0181f8feeb630c52c40c2bba5fa09c02fcbc0467239c05711311e18709017e69c9ebc630848e5a94b24261b9248475b140b950ac435f8be44a80de4f63be7e53f493eb8debf844e595d9530168436971c22f19a94210abcebcd17c4ae2d115150df61c4da1be26d39f2eae16bdcec59de4cef65f0722fd467a8452789e68e2fba421c05b4d9a00e7d416bdb0814753b873356d388ca7f4cb7f01d9699e5b4a6c2d9c8688805384c4be659740eee6613f67006054b6dfc019a142760e79fa1a73cea278281f67e1097b0a2bfbac7df6269237cbfb61055313bf0d78cca237eef26b30f14525c8642a3e07eeb8ca3f6e1686caa302b54f5d4af4b0aee084cd0561513dd73642e67cd2c61b209309e67c8b5b38d4d05327b0bcf06c33f094fcf8d79b2166e367692ef94d5a18da3a6dc9c185ec55336a0e1b70e7c30cd1de83ee92d488f1c9c5d0bd627c3242c2a8358f830b5943f82c395dfd4498bd9919f7092e97eb42672e8576abafe3d0e28004fc88e3a9be820d914fd31569ba5a4c7de820abee48faf25381bbe5df56960384b248748c1502e4caee6c9c5278990865d33176729560b283c2df36496af4714079d69e370d4e07b480ea8d1fd62f917ac2eaa45761dc5342470dc14a957345bee9cc20708ad4486be81446f0d69d72efcb3f726c563349251d75659f238e7572396a2a6185baf7aba55f3497d876a244961cc4794515f0e656396ee39ae03623ffd7289e4a3cef8d9404f41705966c81297f84f9e7c879af9b48caf665c04d918c1308d9ec014d20128fd363e22568834b1b61d3ed6638a3cf2179ec5fe43850dadf28cdc0a8897b72bd3522a79373a241e353453177e2eb4e203a18133c32393eed24c8abcb60703dbcff6af12a019bfd7c5440c30b9189e1f4aad6338f712fc05f31732aa60827a24696c7ab249c17fed3f66649c7e8973119242803af58d12a4f1b6030695829a3c244bcadef5776a95052bf3136f7d48b232f9c4d496915bdcb70633f39b6934501b64881a5c27b5f583699be0624cd38dc55b10a5750b7a4dc80befd3a30cb357eb1d342a5b9a798cebfb029f6b6da95d4a6cd0a6157e80dc733f4b942ad9e59c59b22d19f9b3d3900b1375d857cb3afb022690efb1df0d173637cfac7ac8187207a78d6b2014f8bede6062494a26fc3cbb470479ab20364b940fd701e7be6dde2d8285689adcb89147609e3dc404fded2313ce354dae199a0d8edb771e9d95ab6cbec3d320da7cb797b9886a6807e1909da0e86586aed5c1de7be0e89d60d419cbf9876de6074cf96305eb674e2017ac587a6ef0d6e3db850d097d6f0ad240845d7be1f50ef1cb4134eec1f6f98807e6ab7f6186ddd17ae7472befcb4be2a1800359c20c0f9ce9ed15c52e6a12e88c579ac9bf554ac6ca91c74c5f4a3036da0518cafc7920dc06059b7695d7287cbd814a1b318637d3b36818a755fd286e3e083316ede9d76cab0308c46d030b21932415e5bbccafab8649fd95aab3c98d2d4974514e5a99498d03e598f27f7b05d5110684e617c5776989df89521a5fc0e9e39cd0d519f34aaaa03c608f2eba8e3e3ace83cb1489ad22aaeed2e5157a863a3cd2c369b26f42b057f4abd914cd92ee7a7956f945edc8db7ec085865e6acb2e6b7a4ff73346a634508ccdebcd1c18e87cc18d406fa49081f002e17a335ffcf212d817a57f489c33413e4253063b9f439f8dfd69eaa1aa2c56a24940d7cb1897355a343476c777a6716a69bf7db93b8d4928821d4ac991545d50daf1294bb305d0fd34cd6502318e094f8ec4bd737e142dd4554c87d4bf5b818beecb0b2e8046bc5870b0f3f55426b9046e3c8c23dad4c11f519a4c93418fd858df045650b91235765f79b6f4b736ff1c5c308cd9dc530148eacad50150164c9ff743e9e47fd3d83ff8bf1c0cbc35328d674ddaa0cdd1c7c30cfe58bc7c238549d90f4a9c2e04e93e82dada2bba1ff8a61d7fa18bb1d1f002030d86511ea14b9b51ff1ec60c506ec6c728655ffabf3a1b063c99f3a878ccf1d05f6dcf775a083823a26cf780cad0dda46836ad0d6ca6d4b5cbdf43b3b036016a4f1482b32d603611bfd043a65de5213e0e088ea41e7ee6a5edb648aef94154236d1091676a5c16e0fd0436cb684edce4d824e837d75375c9b206dc59093ef2265b6ef75b5639afac7a5de080b716a35d1f5f40238e3800dd4e2a4775041829142fde376c0e782117a2e006e14c743e473f0e43633538550b77b3ffb30a64bd4ab1f1855f3b0a90a3dbc76defae00a4456d24a1923f52438026ced0060331c80d1bcf2cd0f6cb7414e6715c932d814d49020a90f00c61e8b16c0035388fdd66c2605de5fa5400968b5274bd568f23249ee279144238887b37e70a5453ddf7bc1359eed056e824b25b9b8315addec775fa1a98cbce35bac0557d9ab30425a7d60be1b3319fa19e0cd6435c90ec1695cb930ba4fc6f705d09d884671526f921b1f36ec97d46e2eef73e0d41c34d07e6ae01a0a7e70c6d1675dc3758effddaafc9de566b899b13ec164b478fed86a20e0b9f0bb7a2596160ba260ac7ac14ffe685f84af6c5233db0738e898f71ae28cff11954cb487dacee8d6abc2f32c41109542c3af13bee61f5ba9173d0acb22a665baa4823e7d5d7fd89d9d172319a37b9562bc64d6f754413036b2df982c69e479e5c5a198fa9f483b1c872653cf33975d7a2990da37d7bf2b89cb91115ed12a267ca53fbeb155098efdbaf546a63fce58993e2a779f4dfd42854e9bd1246f1428a1356e7d8edfaf2c2b755f3a1fb1cb6e124438508022062f338ac053e5775c20f5fb7366a07c7c8f23d5871ab1e9c481bf78b9822a6037cb557ca2b2637113f2922a0a9104dcf5dfd588394836b32a58500e46b3f8be861615521940491d6179b37464b925f75ee4af972c1c7b7fa9df1a70cfaa7278068e93216eedd59d5f9a65ba6b3ea4f15978ba29016ce44d113273361bf5e41c68ecf2c27e342fc73e8cc15b578d8d64a9fd3b0f34285019aec878114ec55b1f05f449ad1121f05195809f30ab9bf7280c871626a967d2ffd0ca3829e1c357710afc7acbab76396691655277e652c3fe09345263d2f2fd1d8d396faf5587fe7dffe6806b28bfae1b01f628ac122a974de12a8a56057d54a8e849cc8e26a62e6d781f4c7a0a98f08f6c4be2620e343cb56e2f895ae3cb2809e38c98788ed372d8e36c2c04a014a49350d15144ae47a29c9410dd767481fc891d6589992c9b561b42bcfc584a264c774b58d8019c0d0c3e27d9a0b7a06125a3cb200187db27b86de012880cd9f6222f269295a48fea712e3db33dd80ddf865f4e21cf9be25edff5e50183eae2a9e0279be1c3720f4ad5087cb187d0350bf8d6899fb54091b459473233c82c1e84e5d46c1add869e665669b4c03830a174d040165915b2c1bb8482e9629f0a9738f3d752ca4b0ae8eedd7aa75083db8bc66b7a4f40ad6aa5b74c77ffb1a8a02a93b17ad00b4761f4150d5343324ec4f8c91b2e66557c4363ef382e8bcbefe69ca113858ac7dfbbf1910486c40e9d83ffea0374ef47d5b6ddfc66029a400a569881b892ae72f030ca56332cf48d8c9a36f3d3a661c8ec64fb3a648e09cf46f4f348ed07ada78653f3a6a238d650a8765876950dc8a4166aef7513047ec73182a46b893296b8996d11b5146edcc4c422efea80e06e6c0b2a842385206b6e238bee21363ce9657f327fcb6fff7af68fa382e2af4a004bd4e154c12a3ba3104c7ff0d70665ecbfa17d9312de8d89a3919281308d309a407980851e713b5e25da6ddc3e55b5aee08fd0eeef85196b7c791b3a4f246847b042f555aa09bd08340f5357ef97bdfe85eb0e08fc6d6365ce5c4264694b98b76be0af36a12580237a271a710398a89876f6aac7a2346416179eb35509c6cd29939303767608ec6f541be6e741f291deaffab839b715fcfb9a60c035644502076adae9b2a06ddc2cf324992d4b74099f22d5d8f1ee818afe928c7477844b9b122694c04287afca10373adced8064975bdc83eec2a6296daf964f716913a697f9c1c3e5f36449fca8c3acae70a767caabe05c6892b0d7e21ab0362072e35dd6b24df13a089813c446442fd6f980f5fdfeb1f3e4824d6662a46fb89493423b88566233862c093848ac47d114e624e8470deaed0e20cddf2cceacc8f7ddc9ad14a254e7b4a547427d88a8651cc2c82ae20a9c5f706cfa4beeb5cfafc180cf2e94e7c77c37595ddd3a547dd7f8c006ef2db6f3c3c0ce98d2c3ac163289cccfae91e03b1e0a2647cd746731ba5e3dcfb3f0bc3e8fc1cf902d2774eca97ff4b9463efa21da3cd7ef0457f8e0f8bd3389e2db0f5efded200e1d2b008bf885ceda22feee1d44d92bd98a77ff28587dde6ab7f7c92f371c4c0cf6896d162e083af1fc3e340ffbb20acf70d90321770f0d20c60b920fad0b182059708ced77779f88c48e7072c7e36d613bee1683c2304992b1cbb3da2b8eac8bf355fdfd74eff78e217a7e683e651f0c79eed40ea7f7b1702f2effeb77b19ed1c9ef7aa7574d5717fda53cd7fe8f0d431bfa459d32d2ff36591562c4db6ad9bc7ebf0145b6e7fb8054faf39467b2ea060bdff461bfda2eb7767f4f89abd376cc57f0509b4a285c633f4f8dba031bca039eb5994427c7c0e8ea666d4fd7172b8b15efce2aeead6bb24835a746e6dff06de60849139582c1c797edff9f588ca79ceda10693322da9a7eccdd7fbe3fe77bbcc741b19776447f59808546bc86ed57f359d40f9f31e825542f5d10daa335b70bf1e4bbcedd8d033e355d0ff61673fe71fc0bc37b7ff1babb427f9dbfaea9e8d1cd804cbc86f82566b32d80e58c1f3153eef49bfd068e7c0bb61cfb6befabea2dcfc8e1dfc7a79c2fcef029f36367fc9ddbce6b6763dbeb6c543cb96a649fd896136352eb3bb1d77f4c474f69787ad8417cefd2e95e63c4193c8f712870fe50195b57729cb9b9df038e08d4d576380e608989ee0e87a92f9fafe9ce00679995a1edc6b7dc2e1a784b17df486bc616503ce075bd0cc0c3dd5c04183acc097676c80ba077cc08fe47456107b7eda81e773b28a301ea5dc80d6076bc870138514d9d0d1eb4cc01f03191198fca07fc0df1f81260a07a6f80d30c1cb140373d15e6d9c24416960666a89282ed3f4f3e247c8326d84fe32041254fb10114b9174ed1d01d48c4f4c6ca9f8c67dd2470cfdc418e66464fa8ff947afa4a28e3361a7fdfc4dd4fc3d4b4b393c89ef38faacdb383b84ff7a07645ab563e01edb49afe0e601bf3fdf0eda75f9d4cc7f9bc8ea74af146fd5b507d06983c737e2312a18e2f094c54cea7b7e8d0275a5de64b7d4a447c0e6ba6f124235b426bff98e7f851141fdfb3d7956a995184929e78f0d89a1e47ecbfd1e3f1522f299a4853408cb8d83db81171b506c54c70c8787ba256ca8c3ed4731ee183ffd73aae3ac24fa2165e47c9b3369a9b5e863fea7dd450f55fc838893b4e73cec6b051fac69614f02e843602c3649cd6d71f2f9789ff8ca52be64e0a8ef3298bb9b3b364bb4c2fdb89a70294eb9a1c859632385d94f505e5b137d5dbcd398b84ddbbbd314d7a2f22df811c306d06375b59f08711d1194edaa77291b103e372fa36c94261e23904dcd0fab01b5eeea0450975e019dba65dd2ce05c763e2de293ef10d94e438418ac7105b862f6b195ffd310338fdcc4b82e79adc107112153914ec0de3bda9e39da3644e5dd1c143a0d52809a1088ce2f0a7db760ed3ad176c6d559ac7eaedaa9e19dd5344c9c7892fce813a18f4b03177a6a6af5c9f41f62424f8f1810ba5be1912d721a4a945ee2e32531095940ed60154f4d61edcd6e299b4af8d112699d0c293797c442dd145dc64ed437d38ad87d0bc6e1a8b015064b09b3074dcede94002d35ac99474cf91203fc9a010608221b9e9b4b478dac3d3963aa76743f92f87705dc1a83d0a0ffbb2a5b1b282d6938e2b350564975f2c26958af8d78f4c916b692af38a8ae35045de1824c57a637240ac6a79ba879f792f15a281995a4476e1f50aa1b8a02bf118e87f3125cef75d52d9561632bd728c650381922519648ad2910e3d554d1ea6b79fb16989c5cbdcb61726321edbc613440fa2a559a93ec2266ecd20e10c9eb580d03e4091e373923d68c4ad37a995fb670e2b19d221dee5f048341c64d636a18d206e5b12094024e970533db5492e95712dd10d9670a6c85b7267f010417e1874106e0a590c415f593747deb9d4148959ba7dd7357370199ec5a2ca5b49ef80b5ca206b7431f1c8aba874902d372a4ef8017c6a02451c7ef717e1bd5b76027a840a547f155a1db6c426da1a1197b01f77831b14b9f286ef6b101c6d38b7829246d3b9f2897c9f45c6c06e68cdcff467918e7afe799d3de8feebaff7678d1975b74db4fbb55c065dd3a003fe2ad62c8eed6a1f2f4852656fc060b2149f1c4ac86644decc05cee1a22cc2dd8dbef4cdfc2b0ea55714e19e799d8b2fe192c8b99b5b30eba6e999262f2e3c09f21b4a87df4aba3babe7df73087fe27ba310ee17ee4c4aa1469e207a56bfba7ae6ee8c9706b9c0ccddce7e749da445112a46feae412b4b2b63a06835fb96b420bde827cfef221f23395cf9ac8403e5545e23d63233ea30ec311821af2816ffeba29ca0c1c02d1a021f30778b3300f7ca46a89963e3034a1e821e6cd82a40eee317f7041360979b9fefcf28163311683951080643848e93ef76fbe093bdea21bb8145a0ea0ad9fdbc299ba2a365f4330a3eac0c7fb7566edf01b073c67d2807852fa1f20700fe392598e6166710d56223f564d28c50ccf780acc9106889573734162624815e16debc24a2b7671220b6741eee74c276cbd938914c3b14e8617012724c00ee666741767c33e571e0d1754d50cfea33399977375b0a4ab95842561b19755919dc80f802a996e0c670844dc66dbf0d50dc806daf2da28411107864e636fd39014113c54245882c9b27bc3b705987fa64c2987a057b264b3663f9e3f9b00f135f0d21b651d88b141b0c89ac0c5dbfaad0d9f4649e69e3a6809ef5899ceb841fba0d62e2c4dd5a72c2b27d3f0f898d241edadc1c273efdf529302b961fcc24a66f411403081301ec7fa240980fd50f1431800a11d780b2aad635a03eba6b7c4b7445547f402eb8169db2e7f1380220468e0f18b253914459dff13066ea646405606c104152700e7bbda3bd8ae9006d6e2bcef7b911d2ed3638c396b6c6a7d4f1cdd317eddd727c22e6cb75a174418650c00b3cae44d933ce2b0ed862ae802d600940ea20dee03f8403330ee887fa595870d94a3da51a6b9a97b0e00671ccacf2c3d8c6f0a9a1ca97729fc88b9b497e24f06d2e342399fb8929fc009f68e4b0f4dfe1ae29e7cf3706fe5547203c9ff04587deb0d5b8c0a3a655c58ec4213f5b4e55df54ab74be0b7b1c2168213c6d9a2249f508e00fb0baa19c7186cb807fd45a102b375ace99023b2d69c692f3a7f8a5fcee93fe91e59dffdaa82a803d7c16fb010c1d6a0fd80e9fe431f95646824ae5b7da206bf04dbae101c5d2825aea36b20ebd00039eacff44811efe7ae1306b2c2160d3fdacc3fe38da91c8b5c1c2172d41b67186fa5789b42f21cbec462a8b4792fbd150f92ec7eff11188104170a2d276409460f8dc9b2727268cd7f40c28a982eeb83d3f0d3dccb15da096f577d9115b05db61bb6bf21b7ac1925b1bc8e9a5f5dda0c2ff5e6fe8d7a660a04a630cadc4fa38e6b25dcc60cc6338e9c41a6c6e17553e63b7849676cb30af4f3c701dbe919ced1fce84cf12112db393d256fd97c2ba697ef29681ef347bcdf527b55fb51b4b79585a0961f303e85cc86cd19909798dae3e98d54401cb1d77a240c66d6d4ebe5400acb271a5f97ecd258e247f7d0436af91803d097f6acddb1cc8d9c49f0958810cb40f1e9faffd9f5033aa8a894747cf494063040dff02c6f9cd96ad1e9755fb59d60f0dd9fb89d7a6e08898d8466c4e7c3202709216ef564f773a5bda2320d710a8de256db11d3d4af74ed55680731a9b074ff2e68f797480321db9795f68be48d5b62255f7d8abd8bf235b0a4b21833d1dbb23a7062075187e9bfa016ebc2ea36163f65b522af49655c65a16471bc85c16f0bf21948724631c9555d25e6449d1d08902f8dbf17a281ebba14292667e6d14f76f1218c6cdbc37603acf744750e2cbabc332a50f63ab630b02f1743050d2be0dfb52cbb4bc3175d27ba0b93e5003b3de5996e2baa2d8bc0b723421018008daecff5b9b5ee03a32e3b4db3e612bf9c10cf8a078bfbb0e4ab51fea8ee4c08653c79e7187f27525f6ffd1b2a1408140e834a876a709f3e37d34b805217e38c7e8e3c03300fbbde3923bfac1cbb475f95989fce9a06366763adfab1fa74b2f9392ce66df309c6ded4a7e995a3cc2b899c900de99e5086c402f657858b0af879f7896b7574ef0afc3267b7d0eda5fc330b30d862a9b138a0c8ea1f7d5ce2eb6f02b1d2e4cc7765f3c4cd12d94bafca388f8954e29939d104f08e5b04db34de0edad07c6be180fb517d74cdf94876ac76cc6a136c7ddabb29faa2d7e177ebe7d007751206f8accdea026b8612784f66221652f22dd8d51b548ad7569b3894ce2a8fe8c79eeee8bb3ff21d236ce0bf5867ae7ff6c7c88da6aa6fa1b16adecc666e92058d50759a13c7fc71cfe94c2a1740ded97fd10ad743de3b3ee07c33fc81dd8046fd6897c64cfa83653a56d9ae2fde0c4b7d77c37e536fcf8f8eb618fb30c4495f2f2cb2c8bd84ebcbecb7db8623c5bbaef835e61b1d56dbeb55f5f8e2ea385cdcf4d6eaf1f58e0ac864b166f6b4d6fb6e5bb6a31936f97b30b1769170700b9bd4278709ef19e64f4147f6881b87e5dbfadd7c75abeff58642d1bf9b6ae572294c9702e4a396e4b025888f39ff93e356ab87d1f3eed062ff37f6ac2c2899e6207142e80360f0fc2787ebd3dcaf6af84a198850214599bf51142b37046a43b48b023b9ac577fe8fa808e0169915c3d336f4c3b718f48b42c353b0916c79a90f836987696054fbd08345ddcdd77f19f6b5d323383d054df554c7c556fcadeb7d1df58e2e9a8f9318789f582a619b786687ba3f174df2c1d8437b4db23979a94ee1462761584f9cb4bbe78468c2b38fd0d18091f932371e1cf879cf89bba1a5b83c4effc6507ab8ca0e10146240915de6d55fdfaea794a556c9c160db8c1642bdfa78d177d1e404152de1631d18eff38fde80514339396d191b1083fc0f28a3867409115a0473d467d3fd91b855ed6714793dded1966b0de620f58ac917395dbe197f937ecb941a879aa5f2ade3ae8958f89ca31fe777eb5c1a138280ca669b08f5028903df33f169ba9d30ca6cffb765f73d0da4aa6bd73f8186b3c984caef09832cdce24f90e93c33c5d673169c304411a1374a388441c1bfa40c9d46f501c01e0b0de64d79fd6bbe2c33bcd88a0f6149b4f83810e363fc07b0d3705affb54b02753f60bf73612f7db983c0ceb20e717b94e4b466df48e42ba1eec6453968a32413d6004c3869b630e9701c19c6d8f4ba67a9bce6b3c1b47c28edf6d33df288d70fcd8d95cc26aaf7a5ebbd8708bc333b75fc3b3ec9aa688b57b568e7d1b041712b866f507bd8a59eff609be5057ece2ec9162432f8d8114bfa1bd42426325c959f929e2f79894bbe16ab133379252f51956d105d09907ffffda274adf1af809c23acbc7ec2e547758a03fa50e4d8eb64f404be8a3a369df9dd1507fc21a7b52c13deb7ec3ad52ab2986c7660f40c9bf73a8c42e6007ffdf8806c7f8151a4632c940f705cd5dc68c75774a65490b349a5e4563c53af52b34f3c9cb1335d78c38081fb667d9748839c50a58b5b30ee4f56f0bed9aeed6e012be160fd5750009ccaacfba58c78485e171c09d46f2d0218731019db0d6b9cf85bba83eb6ee0b8f536a2c70811d297d7622692b21d082e462fa8cb23bad8034d5ec151778cc991464c5555af2aa64087428b3da64bf94e96fa53480198746a337bdb057ef08d71d3e19803dce0d50b2b531e98b7feb5d8c3d20321bb104059e0c055010dc087dd9ee53c345f62357de12649f77feb2054cc82aae062734fe74ac20ce21c3ea24211690410994b022f9e8cc5177e87ff8d43489727f65e5aa04183e48b77d1cfe942bc4fea32996ba296496fa0fd3b547902df175ed81437d84020a28ac7d6c632145b0842ec1e9c1b1268a82ff79c90a1c26d322806f4ca4fb7b7e997dc2093cb34e73092bfd450ab6ecc136283a0b227b5b4f1bb93e3c51e5753bbb9480f9355e12ba2a8d06f5bb6d8edadf123ca1fa0b04c3e595c2ef086c687e43cfb9aa5f23f7da4a96ca0fc3ef086647c3891652f1a840643ce544b861d505b948220d8c127463fbcbfb8a4d617f91b737c69ac6efda71ab7c392d771efb0e49a928d0574fd3c499a143c4981110d8a00b32c491c942165dd04c66ebb9db51f0a435ca7544bacf93b30ca79137c93342acc6dd32ee0340993da5b43b6066def01f4261e63df6ae959c5ee483a1231348be80d3ca7aab849121023e43b485db30e5f849bbd2f683592711b3617367a7f77f8e2060772e3df683bfefbf1c4869d5ad4d88face17702404054cd37d4a59079aadbeebee659753fc849c7bc70b361fbea73353408df0798126f46b377fb10274d1970b37262ad4a5de70daf18a39af9be155509f5b6a3fc13f189af5eecff6a286a113cc355c757efa7f9c8ee27a7c4dbe73edb557a7682bda86524d48c06efbe41d909385e13450a37a584019edd54190eb9e813fe2f799ddaedd2fae11c73d6d563d5d8f3f083d4aa3b6b8cead5327bb3137425162e9943c9e873735f5ca8eaa94c9c21a08ca06800b00677c53558e1a9941ceac37c0e5ddb0b3da749f802b3f6abb7e9680dea5efb847630ee35edfef54cf7217618b18bb535a203593309fea86909f25e7fb52a657174fd887082d24c5891b9de5abc466a1867fd2576ba3c3345ff4c97341b743d2c170780f7b5609ac54c9842744feb487f296c73729a1b0e25aaf8698b1cdfb78f0d783cfc21fb9fde52a174d39963545d1529b6b2833f0ab0602e664b6cad6ddccdc5d9848fe84cee36e46650eadc2c7102a6b322332cc546d4beb770cbb3f854bad1ba8b1da8be1f1dd5c6a4ccc01edddf737055d2a4fc8a3fc6ecbec835fb59a6887917e0d731e59e441c63dff51af2c08bfa6f2e5d049ffd7875ac3ff4678fa7ca9fc603ad01721748dc786aca7da9267bd2de830dfe87fd81998c8bc6579b95f20bd37bc610a9a23d773ef26686d37eeedd778721a9e4a12f1cd3fd4e3bead359d44950691c8b8a87c730c26ce3b8d98e12dceb0634d7b126f022ff4fe7489805065575fd7bed6c07b6a1675a5c8bad8a23d580ca7625ddb826ec487a3e39ac0982c9f65b422f0c1e1f6045acb912f22573d6db9b16967549b7f8c90b50f485bcc463ad6d2fb6ad9a152f58f95ca9e8ab89999975e499a557b47c8e4202079cec9ab11ba71e8535710285e6f80448f05df304d3c44f6afd50f07c437dc32c4fdffb928aacbbc8255cab3a28887765698de058c0396bb23309cb1447bc576525cfaa1fd2025957fd09a2e67379f31952c75e4dd3b255ff878063de5665b54bd52304500450bee84412f8440aa0779b9d42d1e8439cff0bf7a6bcb790befa720c7562655194384bc505acc57e6dce379db50e4f7f1bac693eb415434c2f2bfff87bbec59d370ac0a20225afd3d8b1ec84013f7238d3780f94e0a68fa7a225b6aad2ce2b5cab79e0597aea9ad7028df8d2292ef333d0b1a5f996a43338e6a850d857048aaf9d25a10b65968713fa91602369fb627f6b9a7754e52aae3b73b523eb9d4bddc576aab02707f0016efa3bd098242db2e1e02a7bd45c985aaaa9a49f9939236fa98ee2f07f4fce901ee6ff44d35d3fdffde7eb2412bc5fd41c1ea8149967ee1a5f893ce7a11996fa767c948ddc258b5f0a2631e1051092bd053d5224655270899829b2b3d8257e94a53f259dcdd2cf3505f9a0a704ad5e020651cdff04e48d5a9b9188a533e8ef52f80d0002ae38c9a8dc8465eead50e512a1604b492eb05e63d04b6af08243e5670c12de673d1468b68e97949dfee7a5fd923d8a4241f7942ccca534ffa5cbb23fff44d107f6a2b02e27297be6fdd642a1ca4e9ac01c4e04fdba6c1e6238137fc037d8ae13e7661f5dde6c0435438720b5f2a672086104e7048ac21dcc41eb49bf7adde08501fb0b1fe8f545a11e97b24ec4742ce79eddb802c29a6eacd29a94dd775a90afe39f732fd146659e4a23eafcea5a8f34778650603723f1af12f6d64c998420164ad4d639aa8c03dc0196ad2b3b3a032ec7c18c5f78156fba0eee50105681f60237b200f40cffd015df7375dde7c9a94817b7d53d68ceab5f4e7da8b30ecdc569a42944633bbfca65ec3c754efe565729ca88996c81f6d938fa7ce2dfd799958e466f0dc6194c6bcda42b42e5083c192c9a97bb66a8f60b8d5259a4eecf71a19f8cb214ab105f6b80f9d23678a35a867e22bb4f96bed6cfef82fcf26db48e90b5700e42f78c16770a47d9abfeeeb793a87a05bf45c465539e3fe648b60d153a4d281117fd3d2bdb975a17d9af59b9c6b4ebfe82b99978528ce916838eef16b599101d6126e63ffc7d2016a43d967a129df2595b8e6b4a4ecef545526c97654777bb2821e20658e328d4ad4b506be0fcb5ca2113b086d3a5af666bb8923b2b4983cb37e91328b0fd447580303f6e72071a4cd89317700928872a1650a8195e6050a8fbd9f4e84be8bf6aa0dbd2d34c50af432b91ec41fb80369e15604f35b672d746e96d3fb010b02178c683ec0779829e83174832d4805b1defab92f9449aa963ce5fb9170f8feaeb1da45f4b11487f9adda5dc03d75e1e2f30ca817c0e07e9e0cdba9e14dd4afba7189ffcfd385e9242212823e0e4506acd1bc604a5a73eb15def23e15e96c688e008803fd4124fe499af3e1a3b918e9a135d5a8c62e62b7a3198b70293780d3be1f3d1cd8e791480fd67a79223445edc1f4f24e4aa254be0776dcf3679781140d14ce6a3b457a5af4c18a2db76c840ab3b096f401629843627a6964428f368672f06e216b0f9edca5a75696f8fe4f70961a63497815d2b9b1f56cd451fb401792e6a2f3add102e0be772328374b018e3823cd1285cf7f7e0f6a3c8c81220eca3297734a86880ac8d8a0a9e17f66c8c153eef8a595cdf738c8380e44008102c36e53856e35c20352bee4dfd8427fb1244d1f22d175809ed878ba35afadf45fc0334d306ae38c840df8352504fb32b30b87183b9519309eee053552a1914e77915885dd35823dc1ae26dfeeb6b43bbc7c52134fd8a588b56b5a5a45d576ad45848257fa70fa009442b38078142c378632a823b1f3d55829e8b6ea495cb5898441af7ee4f19979ed1c5dc1026e8b045a090cd1c8e2bc1fe15301481cdee0d5bc068f4c2298055ebab7f7fc9971ca4ad053c1482b2de87090a33da7293bfa1cdb8eb6fdc67954216333ab57db906e349439fcb8e4a36695feb09c92b2dd90e77fe8b6f9c5d1094cafb0a064061a53d474763d97a61e8f71b9494d6b8c34a213ba8edff9afe3885727c62ff2cadfce8f9263a6c31aadaea81e3551ed2601ba23cf609a7cc60dd18e7909246a90886b507ea7231cf983b58f47c4c17ae8c984987bb21991c352707f95c13c30b37e530deba5bb4c4c81ae0bf90adc015f7ed9d0b10fd9fe3cb63f9ec5bc1af233c78e23061b433e1865fde5f2b2d5b80035b3cace68d0c317ee64f308ffc88f337074db1dcec1322a84612f8024c1f68f293144721295a369dbd26ab91b574b7380f3c739ec232af3056b0c8de2fcf9e5177fa48a5a998b741e5ef599730e8ba3ed472534b518ee60f942a839f8bf173ffdd834bdf232c28f0fce7cc8e573bcae2bb93ed29e8ad4ef5bd0516c1b7878e4e47617a9efd44f9d7f89be391370b1646a28942d991c06d2ec4741be470a56fd8308e335616872eb9bc87ce68768b36136bc03472ffac34855123950bec0deb00ddbbec496ac009f5fce0f728276ff808f896576e46f8e9e81fc0e7243a2079331c6a7efd1ad77ae1e9cb4d73cf5fa8e11118850800e2402ffccd10d93a8f79c291e30f63de55ab6a99f9d23b2145df5c15e4ab1bb7b8d76d4843239ba1af706217e24ceea5a89d35265f0ec79718425b5ab97a95a132c8cdc6ea3a8e86df83eb6f9e314cefd5836b1f109d6848714b6d42da057aa451318202a2ec1e4c6645209b68a1a126b2b4ce5728bfc62365076bdf1f6463239dd5bef385e690ef5c66fa3e7d3a89041812c495ac10a2b5811001b838918104fb30c63cd36c66a1815ae4a97de64ac0eb41308cb4282fab0a773265c5b2f25f976a6780a11c37b3d6b90f10576277010357cdea65059d15e206d511be1842b626db23285d3a455f3f6a7c21fb309ebf07c0bbf4b9785807341ae3fb5e0997f71cd5eab81d6f3660f2b94c5505a0bb5ba362d0d94144ec514aeac49afe106e1b49cda109bd6a99ea242379be096176a9ce89ea02c2057b7fe82b4a78e22a67f41dafdee9c17d80944c6a1efd04f93c2499609b445cc2f71cc47c3948bc54bd81aba3f655931db7d113dc7b543dbcdd3a0d23dc5aecfa166e597dc17b8068404197d25847467ad86b1eeb5e7aa23b74a3130956e9379e9767c23f4ae24dfecb28a975f2fbe956b3134d5e48d2075297e7b996ae971c3c04e1b0041bd4d02448cf41df5ee10a955a26ec671b9c915321a3b5bee0a4244a61107638c893a8bc0d739f06291f5107b356f3d12a992a66d45811b18f79bf73e80f3a795d86b673a90de14d3ad01eec951d87d834dd63349f5e21c321a7cc091f349876356bd0cfa0e8edf7d9541944f545b6f5a93112fdf317d2efd7cd38df345d63e43546b0d4d53e0622a6f1d4b0b8eaf40816b8440734a01372863fd9ac9ea73fc5c7d09f5d219acd83105fcabf32ac68db1626e9abce608f35cc3d247e6e7dc7e55f8bc54727af9b498b7d9e769578d69797e897b4c5a1eedaf0c3f24568c3934420a8b31443ddacbf2783d36a75e0e17f760374f156178620917137cef7b0e70f9c668edc564db954f8519d6f0fd6e8b9c9ee0f23e97d6223e79424222e17cb7000a47af7267aca7b272aaeb88ab18c3a560dfc69a56f1dfb5aeb53bb798d317b88bbdf4a128754153c27a8d8ec07e33673a8734168f719a103b009f371ae27f987eb38de869e2fb3c5a2a777580ff896fd64e137e98c3e83fd49325734f5842a157e896c2a5e67c4f5407ee9efc56fe6956e7036dd2eafd1c374a682dd0a5a91e5600ca338f2fb40603e379da30bb80af11438bfb89c8ee7a3fa09ac7387596dfd51c378bee544288c8c444844b3085de144f02ad5ee5407e4a4c935cb7fb8788309845a42d6c10635a900f497bf76bae709e0f160add86771030373ee4f97062903b0ab6ea90e91b96fbdda3f4b2d1d8b8b147c6fb956538c21c2ed8382e92657754ec322b9504580e256825710fcdffe762770aa0183bade97a3c562a32166ec7d22e2df6873582ee275173871bafb40325455df7f2a264d61e01638a622e2d1572a59bccf8d2aad1bbb683ee89404d0095ec081ac96491b88bad80a1de34a5bd5ccc2e9c412d2f4e5046844bd3c0f710c65a416fe4f77a4ab95812699c5896743bf0345226c1a232978560f6f92a4d8cd04fea39bd22180f261a71ee4a1cfb9db72bc47eaadcc309814d2c213c484a8ae4a1a5ef008abe68113fcd453fb2bbc90aad9408c2cf928e408c3fb9ef2092a582e884a7635e7cda592e96bb7a86545800e176aa780324ed5cc73291610aa0764fc059f2a21f5cb91508aed58a26f08656566891291b3d97aaaddca8f91ae8417502778fd3139cf1480cea826ab43ebf2a71437b2a2307f85d8ec308c62cc19bed9806a5ae095afb5293b25c70b307d7a84c0d9a338ae3d4014f3b1d61f6e630a8237ae7bf4601d930d5f3a07a71194b9e326a2f7813b947a2c2384fa714455c4dd24c171f89d19c6fe1bb0f7d3c3214cc0ec71674c8673192971872df4400f71a1b9e1d6a792658c453c8d8cb5fef776c5181e665972f0bdbceea35dad503cc832d0d3cd451e3ed61359ee211af7e095dacfe723fa89808c0ca39bfa21adf87d0831102b04fe1d04f9af69b899e0032c4cb11209513aa565ce64a5e7f82c6cd641130feb830bd4674de33d8d43ad891a90afce85779916117ca548f6d0005b1ed834d11835f3ebe2f7e1835b17879cc07594e65ff75ce9a3494c88a83a7d4200d1b4c304c32358b8a66c6ab35f964a4f2246cfdf2cb88d70a2a318bcfc358ad7d402723e5d273a33cdef113bff309bed509fedb06ae8143b592bf43a0c982f007c9dcae326402d8ec8636fef138abaa78557b69520dd589a70b38c1bfedf06396adb1e435c688a2432981c19129cd9c882950f1c0beb5715ce1c74a5760e055f385ff6e334d67e945c85277d0818debb1f9ac4a6d2e9dc0869664391898cf792d9ac77408e645e9927fc0d69914f7bcab27abf75c5516cca66101ebe562d4e28f5838b373098e6f4411f6b850686664b8c16035b6529a4aaf130bba3af7b6af05da187c4ffcbc4690b634386124cf1c0b374ea4e6580a9cddcb5033d5203c4707f82379b582b51b4fb219a43d9929c09956eb058306bf23a98c4f53b3945ce114a0dba842e2c2053b544ae6525432c395c9dbe9962550eb18e191cc752090c26631b06ce69e5bc575ac38e76b470dbd36390cf6fec7193f7c7a28efa5fd706819a2d41d2589f2627beb4ae0ff22b2ad75349c62d93004b1b84c903bf0d00aff29ed9d6046e21220095613a70c1c4fcd9f5fcf20c2898d88a70126a872139755c38fa7e45a76019a250595378d1e779eb21aad174ee2ca642915b56657bc2b96ead4ef2d62b40b1a643a88fc4a9d42a826c686693cc6b4d064953f034a277d04f01fb430222ea6f1c49b482adf67916a8c94c4e198c0fb925868313c34403a9ec22f5faffc8e0df52ea01c9b343c1a8960ebc8359bf9dd823ae28541faf145976ded17b8d75f8d2b493632433260e72c74cbcc79cafc5b323b35499ae3d537c8b66ebc75a41e8ba598a3b98cf621547d5b331d25d0c7582c17778586bdbbd8557334620f0b01877b20e49f7e19e870a58295f2e8cb48e35efc9caf81e3ec0989b62f7cbbfef87d979ab39e9b8940153aab52695d578229f8e61cd7a03e3b81f313fd931229002320b44a75445ff960ed69f07570fb960e1cdb00c7f34189890f1da1410bf715fd2e4965fef5c3d2a183edee5deca37c97edbb6a213d99a8610d6c112d26338550a789c16069dd1831e23786cf66e2a4a0f1ebaae916001186bc658ba43a2693897f15e08989c0e67dbb2920a6c19be7991a09de668e24ead41a55c1d7ab02827c2b04c6f6c5b951a88b7093316737f21b6b52ec9a7abf0cb9f681486a4e4fe82cbbf18e61e68548a8a7a624b07cf9c51ead2ed072709d0801134b2f25a762ed1041bbfe65e92c19b70276d27bcaf3595844b54d924dc42267ec3d75d26a2c1e9feabb10a255c32cd80ea5644c88bea97ae82cc102c7e1592adfb96eda06597da65652e57da5d44a44a49764543585a322184fa743db2f6d564adf430f6e22599875128558623d00fc36047653e770b685ad52fa73c6b305865ddd7f77e89bc6ca6361a6aac50116e67689bc36fe0a73fbff52193da8bad338593602d31423a17f722b71dd446d806c4ce0926e9fa23ea609560d287244a5c62130c77145bcfafc5811eae476f2dc4bdf98dca7d8e68b72bf8287d602e40fd6230f4f9b683078705d7a59e6becd0943f0efbb9f15f1069b0e5b3dcab0ee23b6c605d45e1fcf78b8434f548afad8d017c97ab599739989c21fa6ce9dd8b882d8068df8af6297c36a5823abdade8889f2317764d9b78d735c2c2c3e0036fc225e9bcc490bd49c0e5cc29f5c2345e20bfd316a100445a377b921a9a2393a941b13ebbec2b729cad1ca67dd92bcf686ca40748c3392398e677102a614ab1d648ce98dfb00baa34bae02258bb8e1b2b47921819f211321b35a8d8258bb6b7fdf517ee37686c9d7a9a08604cf781a085481691e08835734ccd9505cb3186371d194a2dbcdf7b5901d04b16042503422b2545cc2b1f947074258f8923a8502b552e2ccdb7cc5073afd196a7b371f857734e1a6bb160d42871e2334eba8d30fa407a91d8d20b9148d8ed15da63951eab36a5e07f52881fc394bd79dd333e01c1e708a8552177def64f9cac1285439360e4fee7dfeb91685518be968cef8d1c1f045fcfcfe6922893d18eb42c910d642894ae2fd659f2db25373908af79f4976b6302c4c057d7da6fb3b8f7d31b2d8c84d1d1875c197bb4b48b358ec688384fb57483334c3dac7b017a0b93a4dcec967329393fd7158aeb5deb1e7373dcc48b29f5c5b4103914c4af662f45c4cc562b6ed079f13060164a2c9e61eb2ee8c5b6d74794510df1e74b0e10c14189a1524f233fadc336d160be3495e46570a41cb9fbc5637fe0ceb84b089220cade5416862fda4c5d324f1a8c1888722cfba155d218544a4b940b51f7b7bea6464d7df96f6e0fec147a6e714195cecbe7cd45b639f3307ac522615a9ba2bea1faaea58e73753d1fb2b8b9ebbc0a2ebe3d50503c8b12b0f4f90b5321b3d3d0c71a151175977310e53aef4defdbe26d7b7d67456a6d338f8116653ca1fada1f58e4b9348a4e042875096ebc062b4ad67259ba83d5c09c85e6dcf443acb2c52b159203af0a5b781aa6bb95504fb77948530230f7439ddd01d774a990e925c7f76de800baf6c685a219836ef8a1bc4abea0a218301af899a84172f601f49b61118677a5b07a4f79e58020374bf25fd571e6d71b1090544ffb1aac1bdc005766f7da02454d71888a28dc5a30a94d0afa5a16f6898b81d93ce01c88a2b2892886b823f16c4e8ca1de315696330d1eb7101a6bc527724e6ff2f6fc0df957a36739a1663b984f52092a150391c8b58e20a3164343830ab0f8e843f1861e337dc7f5040bbbe052d7dc67d6cd62d8a759275ef00616d3142ea3a90f6496d0702d82078396157b9a8b3e74aaf53fe13873c61d9f8dd7d73b371848134b41a6d6c50c0f0db485fd3d971ee99c5c9402041278433e3b03a094bed28575f92c1443590bd835052fcb1f56b2a49d4a662dc4516ac5f83177ece521dbee3b30c2c117ed00751d3a14c1a165667eb0841fe576b69497a9a1f2d7d40818f0ad1ef2401b82c16c874190f596a12c9b743df1523d4b62dc5f0334391fe03774371d7066bddfd4304c477d046a2ef05a4645fa4801fbb52016a2820a8edd4bbedbba36c7afa2be2e0a60ac8e79ca89f8b7550248e4e1133904bd050167740b12bd957e7c8fab15dea86bbb1e9c02d01a5533196f2581f50fc6b612aefed82593bde3e6c479b6865180fbf47622c9faf041976ca291c76ead7bbc34c8d9292d5f58b04ff14e64081314a3b68bfe16aa649d7d315c244ff604092d93647ce7517446e2b1879a2c83246e13b480c159b193f9a8b79f513935cfe7360948f1433adb6e9839d33f93702a7d9ff22add00ab41a0ff4f35827df22c3ed28ef98f45ccc189aac72c2fd45345ce817999e3f48defb81b267f769fe5e1e401b481f6ab21a65c1c80bcc8bf68bc9891c5bf86782762ea5d948ef007af3eec26df7ced5158722b7e1732c96f19cae559bc07d967868e1bc854920e76470e6945b99812b1944ed5173651b82ac2ea413a80e6f1d7899ce05a8e1f3137b200260c80a6a3c682b6495782c32f5546e1a24a7e6382aab8209ba9e60d3f3ddd835c5924bbe919ad5279537d4823ac5cc5c7e9e68364ff2a846450d53ad1fea9d8e37783a2b3791c4826c04f8160d1ebae25b043aa2807da63063cf26c8cebcbdfbe66dafbd56d9c7428381f3ed293060bfec782a62c49371217546b7233ef4827812f0156f150e0438bba0021ccd940e8236fdfee6d9421974499f03709937b7e97f5f93687d2965911f3f32d75a3600f230b69e2c62060b78b6da16c357139dd87fa7f804d26f9822ff9571ccb758c0edc6bb6600a92e405c822e5c61dfabfd9a825387240225a1bfb002e004462fc6ae686bc6e55136aeee7ac3987fb265bf7ccfbaf82ce2cce0decb7c1f03ef753bf4a407e52f60a15303797481013946b41a199c702cee4182c065ec1c7309856a031c462d02d2c21a2ab45b58fe711eaa024ff61b53f7bb6ee05141c03aa02a5f952e2f8b96c33149effbe0ab06070cb8dd959a03e7f0cf49b48e7f119ad2cc6e7ecd81ff2362c964d169c160c5a1d1b278456d3d299c451e9b8105b948a050240f6534a2e1689ead03d93dd50603716f1fcf292b733ed5334aeae27480813f05387edc9f51631b537ccaa3bd1432b3f2606593c80838d50c34cfb762c245d1cfea9c22af7976b3718f5bbbc2a0f966f69f8c28749492e676f38ad7e141e9611b025206ed908cbedad75d8f4e83211c1ea4016cf25df47a28e98afe8b75c2fd7dd65ead208fdd97e00bf9f367c3024d14988d4161302a499217d33c0b787fc31147879f8b276597b7e454d93f098f772048b05c1a257be12d964885e1e693781439b330cc68db6c994a6a3e53eba570ee3af10236ebeaf465e1f8d874fdaa1a0da49b12e5ac2abcaf0b2bda2546a9ed343662595f5c5a4630bab88368b2c03f680b8b6150fca38135bd2c08727295c1751fc3bce2f0eec8f43ccc000a111b652d3137245e8e4d4f1af5f86103e940b2b23616415af198987f8c5f37bd19075c5454282e4a2772e7082b84e87822c0866e5061c7a836ba8240652312a5d3e9971d1c01eb90edd10cfed13382486c96e738719bc604da0b944c3eb479b87e4fc4042b54b7a6719b9b89b0380e6014ff64efc0a74ea453484a53719ac90997cbb623ea6aa1171c19f92bfbce6b1abcacc071fd563277cfc8d4efc2c5706ef8f0bbff27a7776e647f1f8535b446ce46e7f8c316aa30c43d82e58c81bf0a12b1ff4683b149eb456f83cb7e68b7c71afdbc7e5d1e847aedfb1f431c8775ba99749b116623625c38ec05b97a0c0826ff362057b72c192caf4f60d8bae3085e676b74d4098267889864f0858722dcb8852b9117fc6f243a0fcd329a806d9084959c91c07871f29034b9e4ca91d5ab86450bd6091d9b46bcd5d827b077ccadc900215a0dfa1aea7051e0af341c046f10315c09359a9ef06f3c22a2f05db12c4cad1c987f52c6f01e282053dcb47899c309ea60a53bba1967268ffc519c2734a5d45a64f0cece29972bbc8eeb99c5e8d426104cc50d7e4bd4e445ba1a9d86165a0a2d6cb926989bc4fadfd36b1db3b90841cc0018e5f19706d9310c05cc38c96c6c5fe542b365062abe98c4cdba97a5caedae8c54890dc9c07d9a7858a6972699d89170c4058dcd0e285c80b81a3fb501ec0095132df80c347c87da3158cf581c813c721d74d8bb9cf9d00d2beebad590375b4eb237c25169e0fba5115aab3e051054e2e04f6f0e801a8e455704c330a571443747e706d41238f06f2df9a423dd72ee88d8bc00c9db68aac589ccbd94dfb18d05afe5860dbb753568446054ab8662996623e99153bd9594c820095a56726ea5ef524a267833862dcd29eec93195df3d9ad8506bb725b0f074731d5dd3633808f86a023917817681b56d4ec4b8422c5c41a997babde560b70415989ae9eda62f1e16db2f14a773bb4f794011e5703a7119904ad626ca7d0a00b2edb32f13ef5e841f18fc2bf12481bbdbdac4750383a7fd9e6f25d77e4124c980f16fa7a16d1a090e3c650052d093cc083d36ed6bdd422318bcfc800411cc49bffbd1fd31e370fbf2f8fe1ed5b4f04fdfe30c7a7739a488c2337166855cab9dbee0d60fa1dbd18a55a3d6e4f782c88735a5304b85b33063ca6a8a50365c676ed8e3f32e7d0db3fdd61bc8e521d7ba53822b8021a32305de1d191aceddb8ae35baa86cccfc9e975bb35e92d20c7ad12d93b71258644d88a8702ef46019663c1a1d8f45f134e448166a4920d7454ea81691e8a0ea963bb07d06a77edfb930ee3ab9e54ebe55718dcc9723fc2b656e98d0375b6e61a82920a185fd65d0ca3243b853a66a2436e765352a79043a07507cdf1ad5861cdc848190375f607748b6f49727cb6fe22c085fdc39d16c0df1cdabc2f648d6759b006f8812e44f54605636172bfe7c332f036bb94826e639bad09317a5f4950d3bffc28e05ce5630511e92ef15c550b25732286c339f5cd4b339251f94b4c7d6140e9ae9bac0b75b9c58e7686bc38459dc1b842f8f9adb46e52000cbe778695a8c763b764c093084ac41ff3a43507ceb6cc2752b0c10e158cc400b41cb1dabdeebf167bf6afbb8addb5154488c935c460a90aef7fe5e84d7d300e99bd3512cf193c41eef6756ee4f6ec0fd9de4b3924c20a655cfbabd5c5a3cab1f5875b8121edf3441eb184f231b7c5303c1d6f44dc1b0652d9ece5559127eeb896a6589cf37370ae1c66e28e7f494af3e7d2e3ecbff0df6a97e701ae9c381e28e009f342d76db3b18a5f653c176b3ece6800e65f5773da8649425279a3dab06a98557ce4835d3de4ac17ca4f0a2b02cbe387ef38ec86404030f83de4c0750c56c8a4402702431dee3a64871bbe7e4db4f581ad8abd7d436ad51ae49a473452b8c7c11b929ed3efbe6b1392159fe0833c3a641a2f7f0b373d4569893f3ade7612824f27320b8e323ad48f3cff46d982d552dde12bfe377554d99fe92f6b2aa6a810e2cc45337791a256b2ff5e7c1eefaa67ab72afd2209665b3e4ee849e818628796985e7194b7f8b66fb9e3ad23be316683768105c237f6d915534b7fdbb439844ed71740d85d4cf1e7c0fceb01fefd81e95059fb486f225966897b18d02cba011970a0a2e60032ede86be3657cceff49042211bccab7c9d53eef3cd7033ada5615cb9dd51f7b4ca8fcdcd63aed66f264ad6d489f0122c95eecc605125212429345cf758b2b2b442d6b340e94a703ffa80339d16df1c340c46c4ce6220389f2d9e15572e735b2276bc24d72c2efcb7269da624ccdac8446e737137f9bc8198cea3d5ffa413f0a41645786678a984cf3c0ec85cdfdee49d9764d602d3f0af780c27a4a7a9486939961083b181f442677f01d134daf431f9bc8286d74abe9d63f702cc5a6e820edcfb9515b5655c067607b0a366ad53a8264324a4ece5e45d00ce2f8a81ea3d55f490f1c411184e72ccd81bc8763450726e159714ad205a2c3bc8db08f7f5d9504951f29696855c8a1ba35cb38a807247215a4fe97113aef7b4db73941703a76070704da5d53346d41e26c57fe2f1de1ba7a55a3ceb1e65b06a171acc524f6b133d619c58b6d805a10054371b52ee8da5d33dda6e1ec850da70b95c29d2d3313fb5598f9c5e159c0dc5fa5e923e918ed452e992742b7ab310473e5e2ccfe3dc35a673ec3dd7891a78871e9ed2d80073c4000b44c14baf4e29a8ae21d33d9db969bba8228cb0dc985aefe76d7bf81aa10fb6aeb61042720105fc71bfb7f241eb4c8a63744aa9f4d52d1860120f42f38b4537b1e372cd36c728e7cee9f7f9184acbd74e69a9c3d3fc4b1f0dfeb50efbccd9572c25a0a040a36d744f860922c8b8b1032355bb71b0f741d307a497260b94c95eb655383f803842a44106b95677b8963671230c2876879c1b6287e0786ebd9f49ee1b86e4e8abde24658836271c35ddbbefe11ba3969afb890789b2dd146f91cc5ec1c3c6fdd31efd341be639fe8da13ca81fb766292fc9533555b1d835fbb051c5813d236863cbaf1ce8cf5df1cda3ed63b2840f41ce4c04342ddc5120e3b2440e949102d2ad227816b0a50d3e0badb39159ece46177b1be034de05385b803f690dad27351635857599e1a7e771bdd2b9b006b9b8e130b21946aa183bd3871486976010c3108e76dbd36e9528d884daf923d31ccb3b953a8625331cd7759676d6d25e8e7d8c3987b65fc50ce20ce5a6a74de8f48e2eb65579c9e87eeac58f8d4c7a065c1ac87e055cf75a140775cc1455f9e6d539d8a84d37f77591912c7a3dd88c61a923aa021b2543fc7fa4b876a935f3d8675123ad3b6eea7c0a85bb55dfc8182fdbbd28125d22481e3323a769ddb8e398feca7f4f6d8062eeec6edf047756eff6573ba7f4a6e0783e952640bcc129419665e345dc27b9d4b93de978855055220da55bf6a8431e10f852e2ee41daac2709965a83c589c33feaf2bbefe071ac7ea368370b89c1881898593a89c09c7454d9b415f608dbeeb20bb4553b88bac0a7a2e41c93f61150813c4bbdcb397e2def90020a08daa1c5e696146831afeaa7287fa15d75a90049d2090d478da473013e907d11d0b77e436625efc4284c69fec0e7a41f858a0fd850014ee1aa06ca4b5ad2405ae680cb7e6fe1f3327a5c82cc8b9c498f9ad052655224bccfae591ec615f48029102d1ab8a18278d761d6f27a00af85f932ba758a9919b664c757b0dad18f15cc66bc3977271b92a04252819c691578fe0186bb1f5d090baf4f21e013918f4835399616293feeb41760faf7c4b2e5d5a89cddd48d49ad941796ea0e0d796992fc88781f31fdcd89aafe402888cabcb30b9987d44829d41f29751af233b6ae54a0d5719d1c31041fbfaea9387546d4908a5899efb1dd0ad4a8a81a41fec7293a3a0814a9abda11bf00bea1a237f3ec4181c21591a49e9b0d80b4e9e08c5486d1be9d3f23aa0a72488b13ea3a612f7d073f5132aec63a66a0aafeac29b6591df76bb3a68eb0cc3492d683b3e709d8c18d042043131bd58a8fef78db26a37d158b371bbacaa9d78bb2e035a6a70d74df2b0de1864a391e3a383cf7d23ae88ece3e9bb0c607a80f5f98f1f053fb920ab74a719340d10521ae0e1a1085ccb53ad379e3c77aeeed7539c6d4f4d6a3a58767ca82fb9b9b709c8ad8baa98fec7e67c906734b13d6f15483e1c482e8cc610ddf16d3b7970e65d4ddbd6fdc6aaa7ff5715529c77a85c2d85beb77aad34c67959d9b4f77fe6d23bed55cb34920f91b9f4ce3c98a1b6c069941240bb7ba2b1351eeb3ab7f1ed3f7e5100363d9d0b3d6e8be3b94761674227f02394794158db8ff2583299662128c9c63fe31efb66204909a327a5796df2d7abd412572b33ef7f690cffb949e1bc3b3f3b00ed7fe0eaebb8a977ededf5c9b16bb9f8f325d458b8f4c6fff3fe5bfbc60c3d50c3b61813553c23941acc0d477ed45e2d51d1043f8ba77800ff1ff6879d7f8a88d41fc7008640e2fb15b5f22b88b9c791e26f1d09fb6ad544edf29c707f981ca9bf61be342ede5e41b41cdff3360f38a1934373c904e0a9ffd95f01d9c83e9c278fbd897431d2d378111c182856d0b4f21c64e9b4550e36516ad792070c08cbbc48f0566e83d878fd759b5c0309d653d6894729449f301a1f89930383e3188b48786cd4b609bc94164684f95086531a01d3c6a7f72c1bd27e66a4604ae178103bf860b1473e5e2315fc30fe22e8fcc6a9759ed6ff2e8a83b3a75a8c0c9eb482db5e3f43e06fc57239538a6c187cfa1e93bae8e3a0cf9e039655f446ad628bded924c06cfdb16b20ec7cda6478ce4cb38e7f90518cf2f68f03c9b59cc6ae7f884d3cde11e3f32b47c570101766cdd755041ed40f3b2a44c79334df150f353c842d2ef8025b3e51a424b411c5fa405313325c6e595c792c847f76cf99a98d3cc590af660bb94aac34b595b7e0d8588d135b79969238fba37aced9a036bbdbd65a30835411e1069201356798f5df80e8f8f0117f38df58d8bdbfe8685c0e0248c0bc9a84377168c85010e280bfead31fb48a2b44338efae345f45e36f3710b0c794ac88192c7c1fdeaa232fab590d2e33516f2e2cf1720715c352807a2649898bfe044a70731c5d9bb0f0a16f73aa66f2b106492b3aa41ac63cc7c4ea737961d3dd934c6e8a401bfff4a27d11e8cb5e53fa008ebf1dcb1b6806856bbc3dfec53c60dd15864f020a88a29bab4ec70b9a6116b01bbc8592bfacb9e6e5e43179bc7be919eab4b9276e35e85fe90802a08a8e4b882968cd02a0ba6876088c16c3e9ffe12521cc10a1265bba9a2f7322e04587ee8f76db172aea587116bef2b436a6e02e0d7524cd30bbe2b457f92b0cbdff64d81adb95e19d5b3a645eea078696abd2025b2283ebb442ba4d8c6007cdcaf4fc9e7e3cd460316c6c939cd17976ec3a18a0c7d2547966e3453631ff5e9aacdba5c67490253c14525594d7b0c7ca8f62fe830a65235fc2a832159c734a396a206c49a8a8872633744795e83625a2d28245369fb6772550e97aec0639b8440c87a46c1f8dac73729a22c85bbe65d28115102b675898e4324e660388bbbcab3dba53764871178822512685147f13a466ae1e1cedb318257b061c918c910747f04c2a7a6fa95a8edf2253c4a086526208aff5ad54956cf6c4310e4da6694b75ccf17ae162c73090548f42417db6892d269b810078e0ed0bea93e1195971c1272ad6416b811c67e94e2733bd2cc36e4597b60a7bc504719ccbcc2c588b10a893e76249c22d593ed33bc498252ea1c3b274f929e62e289fb57bd1c48c5bbd49584c0b983f71f08b886da860c089962c3e7093eae3ffe88980b03888ae4d72ffb3106900e08732b4a08e9bf032c84c48d198a638c9a8ca26202023e8754d689f55b6064a216692763eb44044ed6e0b6e4e6a391852210fc1ca61436f70c8b422a6a54a8d6feee581edde7ca25eb90b01382ccda60de743e158fc7dbc0e22c4d15477848465b735f29973d2e0217541665caea8f7d629fa7921fbea0135a4fb6f098f1ac09051563550a2aa71aff2c3c27d1bb5835bd686a577a70536a944919f860efc800f63a66336998c5d566ba36ad8a0352b32eea3da24d6e882ce318a0f2e4848cfc69a7d68aecde5737472d11e04c69daa8f6aebee7b16d060fe2bedce4ee4386568d025dfaf17364e9468e25a86a2378a770170778f6a856ba280870696c41a6287cd64aa89729d3b600c92012e493e28a770e19e49864e5b6d4dec31758659f0535d0562b78548065f9f9a9d780ed4c410cd887552c88f1607820a0722bcad1eab3d0fdfb167a511a7c784b01521a145a69c1e781a0749bed3acb68d09e5e85299dab4d107fabb1494a8f9962c339e49d1e8c4a45a78358d119d46197db9624093ae69e6c220122ae0997d88a15b262425b17eb9e2e3414c33adc4fed9b100356cd87b5862917d2f30d1abe4cea433658c405bf29d659e881e331f8d3137d9a90e084503f861927118d48d34a0926952e4abaa0a691c0c32c906ca3ff2480eb5878ffa9c6868a5c8b88c355afe78e9c93bb7603ca30731f6187a1637c93988eb621bac108c59b643115e82650c58e807e422cad6dc4004a92c45750b7786c02383086b3d22873be98548475ca7fc53b4758f410227db203a789483100dfa1cc284dd9725448d6ffae7828d2690cba24f01279c0528601ce9cd54d98e1e69c558210aca8f26fba3d348ccf62a4b4032ce682f47cf4703d24d69bf01ce15db6562264ff56a2f833517c0725b9ae67ffea9698f655c5947ea7f289ce6131778227a6ffb60c2724eeb043025f13b9a70154ccc45e38d196e8c2df581a25cd5266d4584822c3a962cc563ee08395ab86743f0a7030a31a31a42c0cc97aa421c3dac7ce33c13ae74e29ffbdcc8874b82e359576005e0b8c0417f4e3664662abc801b51d0601ad22e4407e05816d9a04f2555980ef2d5fcade4f08bcbd1147e9b3a7450ae5fdc430660c88bc8d9c533e63e485ad4c325c55fd538caac059f079f192c173a2dbbd939256e12ce09990d8a6824da0c4e13fceb5d539a51042cd15c0029f090ad957b2eca0bb4bfe4cb20e1987b5e65ec4dadd52608dc98ef2d0273bc07dcd3875c6f6c217dd8b6c3a68f4d62924a91c2116f8a8001810d64c67d3457e033d018eac1967d391833d67e5e1797582f01b7cd6e7ef694036971b92f4dcda8e21a0b5b38e0d6143522ac8873d7d024cfe98acb5eee4930fdd563f6ec95af4a4def440f22d3aa869620eba1e5d1c8ea3a4d29200055427dc33af8cf46274f888ae625136aa1b3e5c8aa083ccb1333b9ed35566736377a6659caeb57f1a0076a39e7d9b043d02499836e2508b50f9977508a15204ac18d70cf6b96d8bae7a2f7ff143652843120a83120305d4381b86e012ffcc8e60e829cf88d40625ccc51b5f5ce02e0aea3867c4485861855e5261a7420c6aadd7854faae91c7d3ce5b68cdd13f70fb79e0da63bdeaa64bd01e0e3243a1e68d84fb7cbd4144be5913e49177f11a334a785a16734897609d44ecae847854cfd06617d10f17053540aa7e80d816accb5026c8ff9bbddcd81e22d7d8ff5f3211439ce175123e7791653e6ef3f7a1ff4ef413c405cbc3d6c4d9d0224358243ea850f782f0c372b073e476be90fc2dbe505f567be63337fdb77059ee8bd032781af355ab65bd0f66a36bf5eaf65942424ae07cfddd0f009e856c4fc457c1aae74bdeb2d342338bd1b1ecbbc7b3e20b291fa1880e14db5f41961f50871322ff7f2ee8eee7b39f913378cbcfdc29dd51c5f46967b34455d3d31d2d79e646ecded59079a0a63a8aa6f72f5c7f3dab2b80669635b0e314504e5070d620ef889ad5eb1e3a5bcd51158db0d95d01cfc2b76e8a1b3545158c83a89cea4c373e3adf1d9cbb6de0e72077c08a9d6903fa397b5be308a5d3d4098b9d5b871b0ad6cc0b43565c190666efe4536395f4d755b3284dbd985363a78cb3833c9022a6d34d504cd0d44e183e1e4c42efe39d515cbb2bf9a6211ae324a3f9549bab10a01a0200b21540feadb22ebd34285c45777d81f57e765e8769496e3016b0957fd05d4f44bbee33b466a437b0e8136154bbde0fee0be375b6a180d3eb77744ac0fc9d514229edccc81394ca8323103293810687ae38a693963ead147274007275c6d08c336d2836b5990a46c6676c1a1b8cea4da09f7f2856a1385cabde6345e588024958ff997d161bd7b64aea4f887344a58a2e7770a6556cbe8fe9c3effa6b5b390b688cf0ddd969d9e551f30d350728b5a4b6f1ba3d6cd5ff1a708ba2cb8e85630b7be0f042742a31e4bbc117010777ca19deb146630817a7e6ec0c4172c98b11eb3919bfbb4b50a4cee01a26e3e04990dbf17c8010285f7e26c06fda8a9221f9bdbce7f343c32706e1df84e58649f9c3114818f41bc3874cbb9c6bd9a3b2a282a8fe56b9f3a536a94b3260b6cd10d67743856724beb7fbb6bdc0ee563b9feab52df2aff86a4be1cb281f607106d807a33cd5f920b409d102e58377314ceaa6cb54cc5da9017a7eaa76e62601ad8f275bc391a411e60ba06e1dc19b5f09de974fbf10ea5b42ae00b0434d37ff03f189685bb3a4f9bc24f706ac348da61806747c7d1ad9da77c58763859cca894b940a85d47f4817f940a324a0c21fd6880bc5ec75032c85a0ed06463e408d22901a7ecd4995bcb46bc2e94e87b098ebfe9eeb9e89123d64eece05ede4f51e9f9bfcc4d63ed9e4f1544922161460491c01a0bee3d627d04be76de34610eb9182bd628e2f0f9b742f675103ba4be214ff4a9810df1816d181423742999491f065afe206dcbed2a9710dc8c16240c674261d7187927610ae7a4ded9ca05e1cf973fac9d4b5af73002aa901932b9867b8c806cacd59f671decce839f8c717476644d754e0208d1cbce0d18bfa86c5b23158160ca784649e6c5783960b0ab8eb8e4110f505976da1960cc077841eb6cbde6c3944af516cf723a3c2c7176497d8f5d55b3290a78f9dcc4f45e253eafd511ea5e78ca347d9bde943bffef40d6a86d56674c8fb054b2d0ccf43169b86906c971a8f88751df8fd4de874bd295122db9561a24563bae7cd8edb9ff352b7122e528106aecd31d07a47083b4794b16814dba5bd217b0acc67153fd00a1c696c590490889a014d03e5b4788d7c5eb1dd9ffa6bd2282e2344b02a4a4e60321e77ccec1acba320bb6d1811bd8d6945a14baf2cfad70a5cee62816c5d3a2450b94103446373b07d746c78be8011a85884832dda356635cc63a888c80c0b693a99d6d35468d13d6fa6d0fe10540231978732c11ac87dac58b19a3cc7ba3527f8a61e6eb3479743d2a83152dcfb31fe916154a5f9182bf2bb21df69d85766fcbd0c8623b26824a5aba002406dd8e327019f64e65799dfdeb3ad219bcf036ff62de1b38d8a2ddbe7a4b40b0ff50b25714d67f6e671ec6c84b27ba8b42a2e725fb43fd9803b6591c67f7fdbf2eaf02ef33c61cb6b11ed877ad6c373fbf10ca3f7b92d4619acbea2e06ed304bf02a0f08344969ff77ef311f970fc9fb2f77a5c5c5b2d3dd89d2848c243e3c34b25f23ed68cc69df4dd41d47687a1b225c7f5fb7ffd7e3a86e678e8973e66e2f0d7583d5fd72eb896ecf479bf3462dd59689fb5a7f414c282f6829d6eb599e1b570391394d638d4bc603ad3201ca25272d640c62e04d701288295607ffd0d8c7bb8658cd53f5979138570473d6153858fa90ddf9315cd4844fed0cdd05895bf34f475b2691a6eeab89e019f101e6fa6fba9b7342d347f53e4f8d11759af5ec6d5b60a412f1d49f16ad8f69fef43ca6d0d9c84f6102a7565a6d5e90c97ced33f20360f71f7d525203ce4b79a3e6db4a3c727ea582c7d5b91cc9c236651a32017cbcda15f623c0d87f7614e6b888a7c0c78384af9432becc473b58d8ca8f8de87b8c69a57493c0a4c08319efb4313e7b91bd9d4bd12a38190d33f9534973a08d0301dd06b53e8fe54ddf03d596c3746d923a333ba58bf586f0ed731be218ea1b1689b77fa2f6973c5b101f152fa8f302cf037451d0808486393c3d06b98d62193a1766f4d9ec4e3843ae6f94c40da2c9ec0d6908a6db9bd9ebd3bcf9dff560e7795fe0ab2ab24ce3579847be7a8a8fdbf0cd96d41ddbb6fde64a76de6c9d3a73d59c3e6cf3330d561b2db720042592b29c17b781dc3f5b12918293b2133bd7d1f09d93e63f3f29f57d5661ae245c19047d834586b186eed742f3e1ea037b56d0145cbddbd630c6679c2cc40ae8b8e140c6706b9a77788fdb56f44b6b002211c7356119afd52cda04c6b92c5a613dccd349724dd0551cf45e29ca5e0262098fc4553ee142a26e93a0ed1ef94dd73eae94ad1006c84cdc98f23b01fa03c3e32d5413bc9c7628b0d8cd6f0803410dd0af627c2885b74624338c4e8f1fff9dd753c9c91a1825ac531057a78d0a5756bb2249333fda5f4f64ee0feaadfe1046f35b547f83f7946de6ad4c8d80f4bec8cc6776f8936b53cc11d45c5b954060987e43700afcb16f7337e6b29831302e2df4563c9e688b9c25cbdda5861a0fa021d6ebd7a81c92f4969d3428dba10e732b97e3f11e549bfdc25e4c4af925a0b4386c1512f53b7f4fae1787a7a0d5482952049c61a344a78dce1540158d1e2537cbc21abfa8b68efd47539e67c55c0890e784fed602c8155750134a3037e82d713a9f90407b4bac3828a0ce874ef50b5a1674ca36fc54bf630cb97b823fb8d24faf919e6db2061fe12df5db18d581bf4cd9b51e2175d523838408370f3eb93f5421346ec87ed9d529765502d02028625c6abf44cf9b795dfbf78cb74733ccb465c0274e90ccd6a1d7dd05a22954a3489ea721254bff7c4797a251a06b0217a3e29fe1d2944f447e0368511d125f4865f96c11699abcb7dc6ec5b9437c370ff0597981036292094df30bb54eb97d3faf3e5fe449d0259656342173c97e489448cf84136a86cd914cae24202a1c8f2da0b8161d46cbb9ef179bb38ff5ffc82e9951dac6482b09ee5d072c51bd56a38d0d51c827829b899053ecb7af42de639fd53dcb8a6020cfb6ae169fccccc5186782d1927a8b1d9c305481e52ea3a0df90166970e49f134b7ee85df19c164ad8a562e6cc0f6d304b6f02e6575f187094bf364511178491e08a419803cc199968203db4519f8aa5e0e8ef591a30599a2d4b233201724b9a5efd5840af0f40a446431b0013b9e8f62698d4851c81684747785aa944a8b02672715000f56c915782feec3cd7ea9f0e761cd75ffb8d85d8506ee77583d4614f86a3965837787e1fcc02ea96b4db7716cfe40b72d3cf2cd75eb3438cc4b8f9158c1dd141bf532104d0a7daf768a17225cdff66495f0b3a6494af3d20de7a2a8db44dc81bccff8189454900666461d648518470b69e1ebf747eddf8de0c95f3a352bcef325e04123be242dd237e08525c271885907ddeb61b00653ab536e10fdbcbd49aa94864ca835d7ea8e184b50ba9d7189ade50645b6373dc3d7eef8a375012b64e6e331be37d6e82f264b9e7ebe509d398ac71686d276c29a3464f95f048a0e8f04de6ccea8ff08824fa9c73b00d2a5048aba441689678f7e4e9c4c91762a82076f7500e13b7d9759f2107b893c23c021de13e17220906282dfa9fee71f64cb5238486a56d94efa51fbfff11452a21646c31dfcee3336d0a84649b0ae6d78d076d0c3c8b7db836288a9e02d1181cb576e6f632c4d161d8c06afd6562371c16d67225197a5fa5a71a05d3a91835c080eb5ad80d7c237a1eb1e48f6ffd414ebeb2e8b930f11fc1f321d9813252d565a950fbe0365a6c714ea2d2b901d5c36840bc1c890031cd39c47979df2e38d20ac592350b00c5f98330556ce0148462f975e669dd490d01383a0c7001ba7882658f21363c1961d655e60f42a3646cbbf32f5223e0bffa8664b335c0f241222c564711163d016432a925547401245b77257f625928c009a84b1597926fe49465544f53fe6cc851e3e3b96eb673855657b0b2f3194456044e97d323ee4fa3ff8f875e1b2ec3650164b5c399ccb9be118f2a08157e1d41207f929e7f284ff9f83bb8e1ed3b903119da92ad97d880c4fc394c7a96bffb32b2d3e39c63790851eb0efba3300deafbb4c185c04431321af6a813267a6756d4fe23145daeb4922748934d21a569a323613f1503980094b0f88f4eec736d7bab9a941dd4fb7c8add8db8a905e2ca6894f15ffa650a80c12210a3976a552b4d581f437eaea5dbce05e7eb81fcd5f1388c475b22fcfd45a78f7f240eeb3bab2b9739b88cb5dcd313d047941041cd02d2f8881351a6d5d028149cb9165f00f9ba95dec1b90d4f8f4214c833a189591c849e870cd774da39d80c359c475c31948dd24021f3d887dc5ccf3dfa32dc220bc56257723f0e50b8612d534c2d9d566a9e34d3904f80f4dea5a78fa19ed049ddd68e6dc1d804d7573c9e06aff4567e8153cff1fb06d4c794343f17e7d26fba6532abd7991d1766701c78bd8b4563690b4e43120487036b4c0ccfe37c00a82262ef2f15b6bd77fa88a7113394137602e96d80a7cbadf61eaf5923346240ec56331ad9a68f0388aaaa0e2b0c0b06092e47d02d50f6a4b994aeed9123ab811fe275d9c8110ca63527b5b7b4168dd212d693ebafaedd9f60b872fd84782ef21ab6eb9c19da54dd5f66df8f932b97c3d336f365f36d91f6a7312c768809761889432b2c2db6326f5655336b8b60c3c7b01dfd67ce12c67af36540202d180da833d20eb64ea977607f830e551f1c90260810b631ea692319eeef427aa0b60c12109f2167913e3e3750b936c4b93cbb218f9f452cffcfa6643043bd96bf582fc93f6675cf82ced4458833a92e0ef6b2d49a98898c1ecca1c19ede40008680ff11bdc513fb144aca19ec61a86eabf343e2f94e843cf9f3ea2bc0ea73d126c6db0e20ac41b94bb7258f832d25067110c4dc452f0d25dd8015d3c94121eb4ffe38f510d44c1642cf16ff94771e430656f87f92412203d2bd12bd0bcd6866294822c3beacc60a845be1729fb68e6ae7b4c5b46c0c5e3bc422c22ca574414ee18090743ac04725041afa4cdb86b851081f80732d4f53f1addc8d2be7af5477a355df7bfd05bf2032bcb200aef2f65dda5fe0da1f7db2348485f4232ef6f1b630e7a724a0fe635de18783858b5539fd07cf51fc5221237b04a721c391f5d6e36ecc3d344abebe428ebf0082dbf12987b2ff04688a86610c5a96012e2d4006f3ba981d72bf12ab6895a57061e5655a228a69e45e039a3cf9e7d270fc235f4ea883d1a535ec7d9a76cde0d5dee933c64dbff0e82b1a9c3cb3fa55689daa0f4aa50578351f3db60b08eb8a206163ffd238637a48cbc35cbcbf5deca62656f85194010be02b7e4502bcc38d819b307d3cfaef8ca4165c299c3b888a72d35d2cc801d4019d90ea5321d40ac3a02ba978de3613ca2572d2f9fe33cfa4dcbfcfd22e0d76a650d42c2eaf91afd67ddb4f7e40ecea1fdf54ef51011257eb8e64f0391185bd98554968bdc2bdf2f009c38f1c41bc342f9d2cc3466fbca0a68faaf47f644c30fd9c44115108ea3c3c33a37c7247fcc229e32705f3ac7c94c50884ebcc8efb6723c14cf4cbe0f150f55db46682c779d486c2c0439234a4cd89f1e51d819ae1e46d857daadba88f390a9210204675f949186c2f6623c1e02d845e4ae43ab3388f0cf2dba84f0e92b0c97627eec00ace0eb865c7adb53d730ad066c9bd495660265ebc237d80249786c07f640cb7e831a32f62e1f6b70c9adde3d9de53bca81737b19f8fb8e123fbd0c74aa3bb9687554d553a661155fa72ec8e3fce8a54f9fb0a430b12e5e9a0c364025b202f27a3332522f6aad16a164a07b6e207f24730ef6c574fd0e7b606f8749366208d810c3a8bd15a71e678f9d26a663a2fde6945dd065967d07542d83d0add882b365f146cd753cbd184675ccb1c2b0c1b9c3d1f11eed33d887b35f051faafb8c9e5cfcdd09894436195f0f07540f96e9f8148c18fc0a1f582bb58aacaaaa814156ec6b7ea7fc18e2f7e01904b2b8e20330eccaf797be19e7fcc4b8fdbf7ccd8868d3827a6420fce223e50dd7516bae81781d88a14eb8ad775827366139ea68afe2fa8dbcfda3ef06c9913ae092a4227e11c7be92bbc4862d3914a72f3cc2346c381e375aa0377e55146ac5f1c032d86b5cd5744f601c0b1a395dcfbe84e6cf95f345e2ec399ab63dc7f9feb516e81e2e2c5c54e29984fe44480e32ca2defe8b7502d73020ccec52c1c7b6419af3ab78a3ba3aba5dc6388500f30dcdf8ad1981143cbba40bfdcac5875de18fafc16ce39a7c9a786b5aba7e87da3c4f9c7001c60cc2a329a8a281cb082c3c4690dbea73d588a1a4b35c1a98c5c64a9b647893bf602e7ff2e12e445d2c30a53c61331e25ea2eb24db623c171dfae6ac790e9d027a244c2feb88e69729bc401c4fe85d15e674fc4db948c25a84fc10d78c3abf00e92e3f3d4e628149295116c7b55222fa5a02317d045f97b0e8d916f7183a2641b5b99641c920915a249a0f97a120374c80cbf5cb4a5e1d281ae0d34271fe0cd3d1606f9015b463c6166699e31cab47f693d50376dc6269df87c788a74f1087a7b1a1b12ed97ac476c48544758fab1c314a6b6ac70e899b0ea2173139061a60fa7f0a3d1a0cc01c6b6f8ad6aea95c458ef75fabf29d1e2882ec28a83c47e85688f02942af46b260042115dc734a0b267182a0248ffcd85aa8eac95731f0868f4cd62584afc762f009d56fb1dda6c38e8bdccd8d48aa9b0e8649ba3dcdb82f0a3130c23fddd6b84668a0c25ad415c3057bd9129fcdae4481343350e6b97a7a913cfc0ff238a8aed3d0f0702c50703862fd687e4c2cafb24cef5904caa72c39a083edb97d17e81ed718e3a9ca8a7d5481673081db70aeebe17163917d631743604ab7603dbbd9f28354d3eb09ad887b41b054e7a2badf524ab13978e3979253135b8d83499f97d26e32f97c48768396fc10ffd5b41deb7b2b6e3bd83daab60aefad3f04d6a31ab8ceeb982ae6d754b2c70a1e20aca403eedd06f0112e10c89aa403ffffffffffff0f72a1df9a5bbfa36c43324949d28a155957d4fd4e534a29a59464d2fe41ccdb7ffc36951357119311ebb042f48efc28566bc96141a89dbbf74fa3b590c66151bd8fab7b565d1a6ab3449c0187656f51659a5548b13acf1ec40d12269cf18605a5943c2974e816525b1243419ce18645cdfe6466526850fb31c2196d609368d2cd36bb99e343b45727e1e9a5da95350fce60c392875a19deb3fa7ceae341dc2039c2196b58b6919de9ef56ea0e9b1a16a590dae64a4537669d4aa552691d8638230dc97a6d7a57fb944d22ee3b2ab4e792fd16f1f9e00c342cc676679649b39468fa8c332c665cfd90419fc60d42332c09a1f3cb4de6ac31fd679461d9fdbdb4d61fc36558c9b0186e3cc618d24bc9f68c61515d297b9142c64ef2248625bb97255b88b89abc61d0ee344c4f4fa38a698ba6eb7d6cfdee2055e36058509d1d4a266d37d5793de30b8be1c9947febb7f713173141397f8326314551e3c2195e5850f1169f457bb7feff8c2e2cafbcce19b3ff8a70b507677061392b29cc5cfa9f8aabb6b0fc295a4853edd102b2f16d7334d76d70b773d50e79f6f57965fa6670461616b75f44f8ea8fc73f61a14f4dd1d8cedd0fcd90ed4f33e2aeeea5fe8c2b2c7b16cd68baeeddbc9482226448ae17ceb0c2a29a3fa566b5eb9c5959a9a4a008194282f2463aa30a0ba23cac6e9d35ad92af33a86012d38ca7a16f5ee2eebeb76a75cdba14abd933a6b02619d70ce75deff26a5a08d55a5d874e9f43d26c9c218505a5740c552dff594d7d86035f3c230acb2374fcac5c4edbe6fd378afc9021a724290cce80c2f2471da34cc76aa54a6c5c70c613969526af17775a1a673861514c83ec983ceafaacd3863163db8c656daf7957a8199551c68cc592939f756efb18ba36424212c40d928a8e652cb8cc78277b4a66f2a4214b95b13032bf2bc4f5c45b55c2f686c9104cc6b266c896265fbe0cbb29617bc3640d6470e762b6a6adc935c55bf3a8d39b495b7cd6bff186c91a464c82542a6f980c513cc6d288bdfbb756bb2ba4256cc6ac2d25c249e989b041dc2001a2c3184bdb6922c4a84ba95fa618cbdbf2753ae5b29409173716741063695499dc8e2523bfe74739256c30890d635997d039ec33cabd1106a9542ac25836294b4d8bafcf4a864ad89607aa23188b2f6ae5687d1e6dc7048c65bd15772737298f17572a71d0f18b65dd0dd94c713a676bd9178b9b71c57c99e838cad38b6515bae3460fad5208bd8451da043a78b1ac74d239264e7b3b07d777b1f0eb41755c998cd964aa8be5efa0396c768c7750371874e462e95499e9e668a17e75e5206e9094e8c0c5c2e655de3a49bd2bc7d324b75814fd4966e84f1d5aeab658d02cffdd5422fda3a884adcff66a8197c6d04df3a2bbb19b2d1e6f667f528ad3512a15944ac5f524c5880e5a2cfb27fd9d3368974cd32c96fd73a68f2275ae0621592c7a4b57319b6349573516ec6dda0f978d69dc53346e97baf70da5f5730e8b459ec85fa993f248ca49a9542ac6482ca1082192bbaf58d425c75dad876873a95283c4150b422b213ebb6dcecf722b16c4f76767d23928bdae352b96fba490fbe27fdbecb48ac5a8a3a9678c3287898f2a96e5e384e9d5d8606f2a167784d2b331cbd68da10b80a001a405424e091a6baea003150bf6fdb1f7d4c7c8f42a614b1152440809c9aed10217d4600d186cca11d64eb19cc25595693c29decf0e850e532ccf47cf31eb09f9dd5f76424729964efc9f997e77cccedf408d4aa552c913212466b8091da4586e75e7ca9372a1cb8546b1b0ad994abffe24853cf518748862517b3ee8f8eaf8712d9433040d27838e502cabf72ce2b945c7c6204a1c878d4aa55269126b1d5bd0018a45a54bdbca7b7cf89895b09d9890a4fc1b69fd093edb4334683271f9f4948faa4568b375a0c3138bae835c5da545cb6afc2709a40d18542a954ea4e91a7673edcbb9cce6ec93b237debc4cef4ad8887c8a1092378420b49423468aa87166c66841dc2039d1c189a5ed8c31c99dd0d63259453c08425626e8d8c492686ed3613fa7755d7235da35b1a8dbcc3547351f674f995894ed54233d7bd0e246985810916175d38aaa1661099b1a97588c1d85d6bad654daa312363f394923bd111c305a6241975aa93129a9a42aa54a2cc86eeff05a7b72c2d3031d945872d1a91ecbb3a951fa492cdddba8e96a7ec6fd24616e13d3fbd418a31d4d7bf489ad0f4ad31189e512134a66ecf5fd55572a1dc40d12387440624964ea8e771dba745e8f580e61a21e4aa8f676c8118b49f7ee06ed496afdb2114bf2fd4c99b47d77b5296153434c56a69c3480a001440d206dac01c4c8a141a562e4103153d0c188e551d9aaf5f1d5db774c528aa8a1feac0b3a16b1a459ea18f46678fd61f446e268c349ec0b3a14b198eba1e5bd7ccdcff4891889a38d34e848c4e29d0e2d456388b9da8c640f3a10b1dc75a2eaa3e6294c46f3061d8758124a456fcc0ecd26fe1236236843d049393161a3523150d06188a591f9f842fd474d1e4bd341211653b62b11195e843acd1a1f74106259954eaec56698c7ec6a338865b93775db202f9ed615c4a28ccabc266390eae7c771925264c141a5920647a5624662697060ea4147209644b45c9d85f4395fcf24a5881a958a494a1121293a00b1284d09a56b378aa7fdfc6149a9ccadb7a5dafa9a04d2060c801831397941a562c4e444191d7e58148d6ad7d39c6bf58d9118cac241471f963e7d4ee74a4f26775907954aa512474aa5a2c6482ca508c7917226ab8810c387e577a55a0857baeef6770fe206890e2ae8d8c3b26dc7d9cefa45f20ea40d1800592a95f46afd0d2a1512a3051d7a58d42165aac9d49ee37a7958ec551dd3de9dd68c080f4ba376fdb5be380f75562a241dc40d9222e8b8c3a2b7765a132decd5b5346e00044f528ca01d164b69b7f7cf314ea8084f929214481b30005284e5890869038d4ae587a4a02328954a077183e4888e3a98339b34663b75b3bc88766690ed42f70619df55c2766202c719b248de103264c8efc5a1830ecb619548716e9b7747ec5c43c71c96b437df3e86174daa55c2f6cadc000d379394943f49411172e26de890c3923a1b75aaa2cb4d3d435e489087c3e4848d4a65d95086bc32214272b60c1d7158d8edd979d396fa2b75946a411121266c2c950a8a3a3946504f071d70585a9dbbd5a7bcd8b0a220e878c3a2c7aceaede2567fe712b6214788e0902334a8541a143adcb0a03388cad65a666e4a4bd88870463031a26d580efa4a5b678d5e916d099b10929322a05ca5c25cd0c18685572e36556790d5cf98a4b4694a9127f2431635e485a4913ed0b1862517ab750eb62f9bdb29613376dab9477099073ad4b0a4a156cb26a5e263cd256c4448c7486aa552a9e41ea9542a1555a45249d6f1041d69589cff72e1f1374546a8840d077b72869c84b244f821473d1c2747d25a10374854a0030d8b2d73bb34b7722964ec0ccbbe398fdcfcbca7319b1bc40d1220e8308326349adc8ce765f296c1d52193de5ef71e51ea20c362cc594fb3faf27c1ba5630ccba67585b896f921d6ccd52186853955baa575c6bd6e991e1d6148f7552bb96aa3be2f61cb65234484a01a3ac0b0185ea710bddd6ea3e316e2821fe8f8c2b296fef0d4dee985c91f0942507250a9542a448e14d9206e90201d5e5856bbb23c3588d7d26e4d1d5d58ec936fe2476cbc55a2ebe0c2a28ebf9fe99e6469d92a6133c217c193c7c1490a0eccf82405055dc71616feb647e40ad1f84d112129f243d8e2306292d4941e01d20610a44780f8bd0e2d2ce96f9f10e9da2e324ad1d09185c5d659dae75d5542f4752cd0818505e54a8f4eada37123661d5758d628f3e596ac574a733e5da0c30a8b3b9f3e958f8a68524e481c063aaab0fc5ac91439224a84068bfc1092d317e8a0c2a2ed678fa9a76696b153a2630a8bf342bcfa0a29a4765309dbda490a8a0e292c7d56f3f0f639aba654c2242842ce5c471416c6549692c26c7d672c615b45f244bec4c8397943ed8c65a0030a8b27c3d7f5cafee4327c9282a2e309cbe2853c33fdf61013139441dc2089810e272c8de6091dd97313f16a131685094d233e3b958c5b3261f953dbe7888c1e2b84a8cb121675d8cff4d3b9f5be7dba2861b9f3cfbb6fa55ca9264a1296bcbd377fbe9794d953c28624246f1c41aff690b0a0bae1951442dc6b1d2b6153c70856e25850fadc5fc4d75b7eb084ed8eb09ca2295eabfa31b45ec28662a2d2f42405658db0209a54c6276d2163747200c7b29a5f0f35face35ec66074716eb65061fedfe59a32e65e193687ecae6cc514394e57a2d6ca56c7d2646d314220b4f963ea7de189ad9634d53c236e49cbca18e91b3934f49c3bb08eb97a16944dcc364256c7d76842485c8ea348c78ae75ee30d3607e6f099b494a112124b947481ee5e41849a381c9b64994fd8834292b61d3932f52448d368a2cce8667fda8755017a221b2aca3af544acb77253255c2a63830eb14220b5130643929d7a8376ed49d3d2c6123493b2949449ec8aa136131a70dfde44a6d3c75b6401d362a159493ef0de206c91b4358f8b0ffdcb151cc2625dafe89493a214bdf695ca9c626dbd1710de206090f4a329d5f1a32761e99599741dc2011c21b0b4ac9a84a5d0f27dff113ac5747711bfad6677e0ef2cb1d4f4386f098cbb62c61436913a8e52dd14aebea7b8a7c4ad8e23843d0342d7dc8faf1e8f9735e47801653555b3ddcb57ac89c95aa511d4bdef5db48088bf16568eda7f76a9f1b21220411c97276dd3bcab3edc6bf83b024a5ea6ad9a07498c9a41a4058f43e559d844ed24bcb26ab881a494891c346a5c241dc20593f58fad672ea3fa6892fa5378a0821821b1f2c8d1077ea599686ca34da9e1bcbf1266eee9a293636b83d5856a9e4ea10ae358c58311bc40d921ef060318f6b46cd3227f4e64bd89410923712470a0369030640e228d2824a258e22a78dc5206e902c3b581aa956d785b8c6483ba083059967344acff6f8383a343fc8c19266199494f267a2af3b8252e38d22e706954aa58262c484c438881b24aa8d74cc6c68ad5fed6c4ad84e3e450d342a26a95241a9a471032067ec24c5880e38e0002f8d591bdb50d798367accbe7da354aba784ed531113ff54a40645d2d846316282831b2c78ce42aad8df283a8d256c1bb0819963d432ce44f7cc696ab091d09ca632ea1873ca53c28636831aa86370fd35a9694ec8673208727c2d1ed4d53be8eb6e031a3c9ee5f5ecc7d8495fc2a64c70b0061edefaad9567f19052cae40633306ee92993598e50cddd40068b31c49fd0e3ab45bc56c2d6c66ae84a69d111e1dabc75d7460c96df5b6936fda17bda2d41615b18589fe9e95343b41afb89989c18b1c3411a0b5e2b6367ad215e3f54c266c4e444995916bd95d4ee21834bfda512364941bb172cc9f98809513aa72f623224912421292705e5ccd058545a467dcf49bacc9a54c246c4e46465a5921e0e206dac018488c9491a954a8a0b2a150fe20609125cb0f4d1848a963a359af8256ced821620abe23708fb2c7a2be14aa552413d4931628405bec655d111799bcd5e6685081c43865416468a523722f444c93c02690306404e4cd61b47d0bf60881122424e891c29822944961156b01cd25b4bbb7aa8e6f755b078365a88949df48d27ad1a2958304f2564a77b5d1fd3123612345b4b0f470d50b09cb54cf1f29ce4d367256c679b4264e19e60b1b37cc9535ac5e6884bd8524e9a052658d61cbfef84188da2df218bdb975ce7f4d1e5a8c932a512b636eec520dde55e6697c1a5b084cd0826276fd8f19289d69c2bde5ce8974bd84e52507641b778a5c30be13a895ec2964264790e74e14374ff4d8bd3a9ec1236384ede8e7b908b3a9fc60fe399fe9456095b09ca11232427268b645b00040d206d0069630d20e975c01ac40d923570693f6e0eeaabef5ee94ad84e4e4922319f22e46407954a0a915541393b0062ee0890942344488c0671836407b76c2b6557f545bb74991236206dc000481f0192c60d800069630d2024458490183139517c272946f04f4c520671832405468272e48484440286e40887c8054a60242643484c8644a08201128060041a10019010a07c00041ff8802a7248d20321e880a16c800324abf7424e524200c4031b888006cec4e444021930921060400217b080052250010a50e00313380d48600211300818910718c99f2c9213939443010768a0012be548051840e448910518c99790902414214428a080dc0a24e008264648b10002560f0307e83312445262000c1400850023188091fc1b1e10000909087ea49c9c140f04e0360080226f0841c9800f4389e38940f2811e1ce071ca08119344426244583d23e9517807c907ced8800e232171533df524242947780ee4d029d81d94a1e3899c223c0c0f80c831801ca198852f5ac0231616a800052620810840e0010e68000316a080042080000310c08f000020478e1c3972e4d0b123878e3372e868468e1cccc89123478e1c3972e4c8518c1c3972e418468e1cbfc891c3173972f422470e5ee4c89123472e7220e0023c7220e0024674872306902314b0f0430b7230c0178dc0852d72e4c8a1230bbd7045912f214139a9a0f0b8c5197ec89183872d18d08b36dec08b48f0a8050f5ae42099852c72e4d8851872e400c2805dec60c02db4c0805bf08001b650430e3450941a97bd76884c86b8a016877098c0043c5c418b39f068052b04b10a55e4c0411b3c52c1e314a6c8918301b218461c455a7044120f18f129428a0859a3182264074386b4407d1f72e4e0210af5351832a4053972f008054a8e1c3c4051e4c8ca9183c7279410351af1297f928a98a091925a9023070f4f143109a2069183871fb213399a136b3972f0e0c32672e4388ce39c9cb40025470e1e98b8448e33724eda4051a3155ac8713a20928ea0d4d001ea800f95f8038f465022478e1c391832e4481a3f049d1493206a88490c1e0942709023078f49a49c98184129724eda30392992834fc324c8c32104c5c4a48d1c3978ec213c96b1a0f137c7cc9cf250c6d2d79d8ed5b4cdc27547782463d1f449d1a79fee83582d32963d86ec12fac7bc76ac54d8c0e318cb2b6d4cd374d54565ae889037849c986c21781863b1fd9352e92b166351b9dca831d748a53ba5081ec4587aa5655b87d722642c552a276690e0318c45257464d2ac26dfaba384e0210c4c630c76abc14333ae062d353a9c966e116283c158b80d9fff734c1b3bbc36a8544edc103c80b1a026dac5c4670f32837eb1a4e5398dfacd649e4a34ecc0c3178b617f6f65a8d9462d3642e4a42405c1a3178bff1e94d0a2bdc9737eb2b4a0c283174b4a6b97aa444db3a78c312d018f5d2c9be6579d75cf5d7e74b11cbeafc453eeeabc672e96e5c77022d3d746f91f2e96368350a39496d99d5e5682c72d96a44ea51d646bce4ae94d82872d96e5868cb265544a77743eb92678d462599d52df203a276d29eb4bf0a0c5c209d54a6b7f3d4a87cb089123954a1b21720467b19c7a2ba38cca3ccfc64f5a70b258565393dddcad35942f168be69dfbc6e55e7dd21932e4481a950a0a0f582cb7fc4f2fcd73f48eec9c9c9323f078c562b9d431e9737f6a73ae580e5959a9a2fff3fcd58a458d52833efdb66194162b1647ab2f4def52d2d6b58ae59c59671f2d3dc7552e552c7c6fda983d1f83e93f154b32c3ccd47c9a95dfa362715c4e5d264fafff54a758d61d5d35aef40cba27532c279375f9cae637955029164de5b5e3a7ddfe8c48b1a4bff7615f4ce7d8a1512c88559b5f09255d57eca258ec3a13cd29c308ed6c28963d26b9a6e467907a5d502c6e88c8f7feeb2064fa89e53c99abf2bb43d7293db1bcba6dd36621ef52cc4e2c8dc8ddfa9c6bd2a40c2796c46567d4259e6c85a9073c36b124523beba071569e6e6962492b950de284f4243528130bf274cef04a692d6c574c2c6b89b6caed29219abbc4b29c13a5e24dfcf76496b84b6edeec33c79c8ac6d81b34cac955af71255252ca20bcb4c528031e9458923f2f329d97d25a994ad84e841c232428879d24c564088a09c263120bff2f237e4f89c9ab925854c2fe7b74f2509b94256c79ea8f20248d3533121e91586cd50d277a5ce3fb4e3578406249add2389fe17396d3f278c4620c4aa5d4b5f24eec2b881b244478386239e87bce7c99c9657c2b1512c346f068c4f2299dd35796476f192571338c5834b15af7aeadeaff97c7226e8db39936ea687b768e6dd63f4ae68e41b74b79286299e636e4aade6f193384938837a6db11377b51d22b228408221242e8da7c29cf95b01941e9c3e310c6e6d69a631032b3ac842d8e1423445e83c0c31078fc6d19aa935208366db2d3e4b26d5be3a1ad9526b5df724e6aac846dc839ab011a406800a48d3580bc006f37881b248b072196336731e2a5bf45b6f5071e8358d4626f5b9e6c64ec773ef010c4a287fb24434be53a6db397071e8158dc8c19e7366fccaad3d9071e805814dffe9559c6305597112307ffb01833eebfd0da284cca78f86179473d664c9defc3a2abb99ed5ea2ac5343e2c89ceccd094516aeab41778ec613963c5f37e83cef0530f8b2ab44a71daf407d5681e9646346ece32297fb14934f0c0c3a278d6e82ce25d8492b71878dc6159e7385a66a1633d5cb6c3e2c638ba212b4646cde900081a406600a48d3580b81b78d46159f65febaa47656b4a3a2ce99acdaf9a2bb73c27e571e06ae03187e57dcfaabc83f094b29a030f392cadd45178d0555ea2fc22426610071e7158562a7dfbee368c961c0e0bdff69fb446e3b7d2a6a781c71b96540619bf84e97dd4628f81871b964bc9a46293148d6e771b16e38fa7bbdb8c3234cb0c3cd8b09c947aef7db51d75371b061e6b588e4ae43d758bd5ce130c3cd4b01c470b2d1fb2450ba1b56be0918645572b476ab9abfb3faa848d446d6fc0030dcb51766c0aad593faae47186c53699a3f227ba630c7998616935bf4b597d9deaea1978946149e814ea56081dbae384830c0b4a5efeec08ed3d61a301048d8d83c71816535b434ae5aa4bfdb8071e62588cc2574c5d73f0f4561896ec369a879455b31b836141de8f92e1336355a75f584cb71b32fb67993e8b5e5836d91ea174d06f9e735d58369da36c6c1642cf4bb9b0a0a4169ddd93b0d9a8f1d8c27278cdb1b55d8d788bfc101293222496060f2d2c09ddb9c76590e29185a486187b4f2be5e48185c5db91a3b3bf313347f1b8826e1e1be54b4d7743d745a7d049ce6ed36bb50c3cacb0202f563db77e94d2e51a7c1232040729425cc03ae4c0a30a8b23367afca8a34ea3691e545812532e94962829b3143122784c617936ee43fb88774735917372d8a8542a9584a35259226a09c7f921784861e1831817a5538657322b0a4be6de1e4e9e7d2ea187c272dc6c8f92316e2ed71396764da7ec51dbf192871316766673924f6a4d37aa19cb4a481f21775b87d44acc580e29ccb42aed2d4745cb58927ba35327376d1b3dca5812269e7fd5c57d6c9d8cc5a0a1f38376dfb69e91b1a0a5db4f83d0f4f43196c4764cb47fa7de781a63597e36f129fe7453098bb1a45a2feb1a2f9e1f23c672991a93f9fcfa0e1ac6d2f928dd3194ba4f23250c57c44e4743b39bd9c7e6e076721ea74a8d2718cbb9416cbde977293db473d8018c25e952d9ab2a11ba941c0d3b7eb1f0b9995ed436357cb1b4ee3943dd64838c380f3b7ab1e041e5a56b6911db311d76f062f14f08d7ff39da96da186b37ecd8c5e29754cf6a5386cc13aa547c872e1635a6bdbb8e5af2743817cb31aaeef9559aa575838be530199717951a55866fb1a4b4682d7e5464797e6cd16a9d87d8b69dec899c4a152f454588bf4f6bb1d85194122d4b98b88f2a413931a854f268b1244b09df1452e6a6ba67b1e89a61c7b409e9a263b258eee05de62eb56488170b53ecf355b3b6c9a986768e32a95326dc657783859e2b9eb1df62af311bb623ec78c5e299e639792363a57c5db134a66bd6c36ed4bcab562ce713f39dce3b562c6cea8d8b12b24593b963150b5abc8ebb1fad533a77627272f23b54b158deafaf2a5e6d274f2a301579ad8da71946b54b3f3b4b5d68d2d5f151b1a8ddd32af5bcd26eeb3bc5c229f9d939536bad3f534e0e1b4bd8618a6559d562ba74bf739e24093b4ab130da5bb6c7501fe463282888e2488a45cfea636a73d50f1fa2bd61c72816d7a58cf5f2f720efb543148b4969a952ebbf30a9b73ed32dec08c592b86cd4a85b5ecd4941b1a4437a4ea1312b79a3edf8c47249977965e9dcc688ef0b3b3cb124d47970a163de85cb113bb1a87ee49994bfab737c716249af6e255b5f6a130b26de9bd24e0b7f5dd2c4620c6bfee93a7f36a59958f856f74a6dc38f7b1ec40d12931d9858b6d72e633cc890fbd02516758e6f27d5d9ce98bec312b7bc6746d1cc2c6f4d1a3b6729ea4aff698c6109db8e4a2c9f7eff9819659ef5204a2ca6f454a1a7677db3b563128bde27eb5db35dd7a676486259c94fa6b4abb8c992ad60472496e3e6ac0a8fa259bf5ac28606831d905898cd9ee95b8ad5e29e4aa5523938fae03822e908e8851d8f585097514ff52fa5122bb32316346d345ca598be994f0c3b1ab1a0437e8e1d3f44241dc11823168592aaa34dbee857af2aec58c4f2071d234f9e291d97a01c31e2abed821d8a5892b1eda31acfd1636d89587c553d3a4d06710d3a221664ffe7d55a873be1c9432c6a4e5274659c3e5342432ca7342fd9a5c3ef8eae108be94d9c92327cedfd86107db606d518d6dd4dee5e579594e17163de6b10cbf9f4d48acc53ab418ac404b128d3445ce8d357b283815044a379c779666cbee694d284701fadaaa33001624188adc9fcf9566a7ba9e41576fc61c157d43b9bd4fdb0dca64f668ee52274b5fab01cc7d4ebc384f8b0a0616fa3fd646ed1dac3f2be8e1febaa66436f3d2ce96a9569c4461fdf380f8b1d4496cc696436f31d0fcb2d374be529f11d0ef58cb7ef6233f219a2f935a5eacbb41d9645774c3df2747f4c6ba5b25787054d5af6e269f479cce8b0ca9dd8ba06518faf8d6d9317b3a9b5bf65b4e6b02c6b430ba9f15a094d0e0bfaa5d3c8383a8378b5093be2b0acf32617197578bc762a951d70584c1ec568333d23e3868d0a3bdeb024d478f68edf3c63329529ec70c362083d0dc294942363572a958a939861471b96cfe6fdc36492e2e4aa844dd1de2822a4971d6c588ea7b44e2b53b65def1a16dd53dfdf6cfff586d4b0d85ada3a662df63b7f695892f9f37542ae16b7523bd0b0ac4ef3a59491b14da8cfb098a5a91572f74b2b3dee30831f9f257f3aa8cab0a85634676d5faf3e3c325ceba619c76bbc6d3644db69799fcd946e19cb60c71896476bea18a1994f8878871896fb73f468aa67f793768421cfcf587397d16e315115af56b6846ace656a302c68509af39aeb9439a44c6a61c717164e4d8750e13f7faaf5c262d2192d34e444544759efe8c2a2ab099971b4900976706141eb3d5da9b426f3dc99b0630b8b5acb76ec0d8d69eab4430b8b614caa6aef9cbea49c85e57b4d3f9b3a84cc1516fc34db530dd99def0ecfa0941add7f3a66a52b2c96167e5a7714e3faa33bacb0249f4e4b99f15beeef75d8518585cfa6f455ed4e86b8c3b0830a8babfb95689335dba754217112c30be206898e33ec98c2722ed9495c2a1342b770871418d393394db5cd262ff3a7a3dc505ab776446149c5d3a8ad2eef4e9db13fec80c2b2abf2cf25e30bcd399c840c4147d8a8542a954ac549cc8c9fb024a37ae149b5582df3b7c3090b6e227568ac08f9fa366341cf2ae131a7cdd0b967865d9f269bb1271a64c35de8f039bbc67a4ce72e635967d13198fad9c97d2963b9f3c72c364f7fd666256361e47f0a1de2830b17321685dc15a6e4bd8d38fd3196a3ac0c4268f4af15bf3196748ead5ab7af1ad1be188ba35e54890e21b46629622c798a0e2ef6d27fb486b118c7f7334af99afd0b6331a97bfcd09da7842a188b9921ca63f011fa4b09184b7a664e84eea7d650fac5827ece60da42c6a8c2e48bc591a3730a3991a54ba8170bb6a1dd937bac3c1df16241472bcdad7fbb6a3abb589ad79e32ce4629d3c675b1a0be356d57bc8c2b948b2539df59678f8bcda771b19ca349b5c1c47d8be5d42722e5aef0d05adb62394aa973f62aad5bd65c8b45d171b559635a2cdeb996327bbf6ff32c16a38f9907d7fefa49592ceb142e9a3a9d0935c662e9fb37d6e998a3c9a7b0580ea5a23da6dc2afdc9572c46295db7bbffaf085db124d37487beab8790c1562ca667f8d237ad5f988c158bffa65ef6c94ae1fd2a16f3ca38ee4954cb9ecc19aa58d6599732cd623a09256a319c918a85cd31eba0c5a3db9f4b0d79218c8ac56c23b46754f2d95d5c72c629164667791d4af5bdcee30b82b8417272862916c4fd892d176af50b4de18c522c9bcc5accfc6c4398162916d47f7a2de5b75af973148b659fbf4b4b6dd0fd8962c1ecf7c534eaa8a55a43b1f459c9d3bae14d885041e1b966e6dcdba676ad6928d9294343538de6d02716dc75e82d791a3d8dcb130b3a8954e1a65787145727964cbf3ed531c6def71627963cdf7fc90f3791d36f62d936e58ede285c8ee935b1e09b3ac3bf1622efa432b1bca52e4255be3af1284c2cae6ca6ceee76bab6bac4c2cb88e74d2247b9505962b94f87cca8eb396abf124bae45c9f4bf3a95525162c14696ce9cca4d9ed224167554697676a5fb6592c4d2abbfcc42796a59628ac482cb1c5246ebbce64b9058fe8daeca94a84c9da5472c6a7552d9780c559b428e5816528f6a2da3e1463e8d5890a346758b721dc277462c6ae64eb7bddaa24abd88259d45ca5329e4acf056118ba2be1ee3cbcde71d4dc4924eb71f9d44cb935311b1987baedfec64d8faf4108b2ecb95ce78eda1f4698865ad3e289959284fee6321da8d39cf273d2116a36cd450235f6ea66e10cba37dc67534d9a6844e104b9b5f6f387dfb4ae31788a55dd5cdf8292096b564dea049bbfa8a7f58585d233b47b4956dce0fcb5b424a2935ba6e93f761493dbebddcead73c1f96d388955ad727f91ddec3f287bdf5bc6d39df981e16f4864c9ad456e7ea0e1b3760630d207be48c3c2c7f5ab11b55fd95cc5ea9542a79061e163cc5e895b2d33d6c2638e30ecb1f76aa79648e359bd90967d861615b860cd2f736be9aeab0a8ea5dcae0a756e6937430ee67a9baecbcdbeb896b162f4e65fa90499ec3124b2255eb243666d6a1514e2c7796d058766253bd36b1a86549d3b97a93b85e138b39d6f52bbdc95de933b19c1fa3d09e3b798e8f89e552f17a53c88df9a74b2cba96aa56271fa9aab6c462d817e28348fd61e7acc4826c692fcd14df34272596c6ded36929a54ac83989e59f0f9759e36916da94c4d249fb4e0d5d456231e68d1bc446ffaa2e21b120d3c7f0c1644ea5b97cc4b2ea866e1fcd20bba523964cc91b59ad972ffe462c6a4c7b22d474883d3162e93bbb96276a27565fc472d47753e6522ad9392a62416bb91aa4db9888e5d5ba6432a974ff8b11118bf25447d49e2955150fb11c464aa1b65aa477898658f6af39991f7fb285588845331de6579ff6fc3924c472eb9ff97ded1be6e1209664069deb3107e5ed12c4624eafdd75e80462d14406cfefa893523d20969314523eaac888affeb074267a42449ac620757e58dcaedd9c5169afabebc3e28b93a94c77ee8f51c78705753f57cf2983e9e8f6b09c5d7546cfef223ee7f4b0644a475f74e68eb65f1e16cc755e7daccfbaeac3c38230d9d349b43e7b7d7758509b456ad1f4d96139a9f196313cdffb7c75585e11326f997219577c7458d23ab558fbd3e52edf1c165ccad8f1fe837cfd9e1c16e4e327b9af6344292f0e8bf359f5079d2d1ec583c3c28794f652b90a9532f786e59cd1a67eba5278ccb961416356a3f4698e67af362cdabdc61ff1d3dd2d362c7990c9f47834f7cc5ac39269e97ca9f7852e931a96f4c9e650ee725b8ad2b0bcd137a857a9530b1d342c862cdd39e674567dec0c8b5ae85acd2f21266233c372caa8b59faf5686651dde1a357f5778d4c8b01c93c637f3b81b94d2c6b02864920da9344b88d1c4b02c959c9c98370f0d5a1816ec94ac8bfba0a47b0686250f2a4ce9cbf8b4cdbeb0986d6336776e467b796131e6f471c5e6fb91595d3007d1bbf3252e2c994969a659c83df7b7b0589a3b497fd1aa99d7c27212ba3bb3f6fde3290b8bf946568dd04934762c2c8f1a1125751663f715963575b3c7c67bd36d8545ad934c6265ba0a0b5a636e84faacbfa642f719ab94763b85057b9d54654e4a61b94ccb890e657ab68bc2b27c8ce7a29594b63206005058d04a7bd5c9971ab40e3f61695b556d663ba9d46900e08445bd2963c98e4e33965e2b295688eeed879419cb4296cb579bf7e5f4b60c3ed4444c3698ce9dac6988d0eeba84e68d4e198b9f7fb3d9270d2545c9473216b4de926feaea44664862c85814ed5ede7994569ea5f618d7c7e8bd988ea6ec7e69ca76cef2a95da5ae84cd8db1ecf3ef724deecdfc5c8c0599dbdb3e99d8c64f89b1b8d9c3be799632744e7d0c6379b3462d8d396e3bea7d08c3b9d9e45e5b6aa2b69a55a498d27aecbb77c33e82b1309aa3d2ff3164d0f80c7c006371e5891bb5c95fd6bcbf58d0f5ce764aeb7759225f2c69cd5321f4c5b68b34881b2446f0d18b652f752bde7e32ebbd0f5e2c99dccfdb30fda93b7453f0b18b65139def7b2a3ebb2b5d2c7816a69ff737a80e251fb95834cd332746bc54ffb684cd71b12c4c8eda16fa5b6f7d256c7d8b0519354ee8f4a0fdb5aa84cd6cb174abb50c15a3d163524bd8d0063e6ab12ce3eb4f5e2223a4fc28b458d0ea95de0825575fda3c8bc515b13bf7a685a7777cc86251760affcf60327b2c16467a6971eeea4c63bc840d16cb4a369f365579995453c28627e424255fb1a461d44bcb5d6aeb57c2c6e68ac51f195c099dd63e750c4a2b16659032e7e82fdc5ecbc48415cb2594c828a5f44bd8ccad62c974879c7e5d26a2a354b11cc5b52b1d1f71ae33a958f290fb6c7ad387c7d5e203158b2a5c456a102dfe758a058dc935460a13d2a3bc84ad4db1d852da7ad29a73568a051993dda9fd478a659da19bb30e31a6e4a8846d47f1c7d42ccfdd3d2877b90f5174269e494b4b63345bd5d598e6323ec26c937c846239ea8f4d3eda048a65d58ef91eb3b5964affc4627a293c761ead63c7d380b40183214688a811870b50500e1bca048d4aa5623e3cb1a76bb097cd6ff1205a4911a73e3fe88ae0a3130b4ad4c49abad0dee255c2462264ad3435d2488308ca3142a57242cae083138b711fcda52c25a39b2d6123b29b58581115235f063bf1ff64a56b62f9367574d29da3d4e0d01af8c8c48292ae63fce871bb8489251d7e5a7ae9d5cf881c297289052d764273ecec937b0c7c5862f9b3b810dbc1bca4e8c7e0a3128bfdedba528fd7df8e3e28b174aed36bb54a739cc8580d1f9358cea069f7a9af32e75ac2d69258ac53216afb7184af4c09dbea4562799530cf63326e6ec64a1812444c4c48de38212109808f472c9f988d0b2dba3275658219f0e108554488118a1c49808f4698e195980d1dfdfd95b03dca902739312131728898a91b3e1881ecd6edc8a69df3b8557fe97a37e86c6ab44639eb32f0b188c558b222eed49b7e7ac8102133a85414b1244f2879f5e9d63ebfd268e023110babdd56f87d2b4f234241c4b20b21e44709a951ee432cea16ae2bf5454cbc1c0db178f2e2b4a72afb4fed74e0a3108be3a22f65e7fc4bbe12b66ec3072116d5ebf22ce95ae36774100b9a649aeeea5c9fa53784a05c101f82583a5d9771971e4aec5ec2168805dd5a5f5747b52e27402c9c681de7f4dcdcabb6842d51f9f8c392129eddb5ca5c7fca55c2e67e587ad1da57e7b6d5bba612b664c3471f16fc9496792a3cad945a09db1a0a490a8a4909c99e8910122328ca87e52c4ea7d1eddbba73b58745efd2171d4f7cd4bd7a585cad3e6e275a3dff9f87a5ef24a5a6fd3452d546f1818705253f54e9c94deaa7e3e30ecb69b28332a951cf48d961414f07e15aca6785dc7530dcc98ec876dce98dd641feead99c0e8b31b5b50e9baf6afe3587c5385a6a4f2bbf478f2b87452d74daa0b3361ba447921e0e1f71583a93d15a5ebbc82c49d85ee0030e4b1a4a6c0c7652bbd07ac3924ba14a46a9a342ee46213182b23edcb02874ce3aeac61895baa684adfb48dec0471b163ce6bce9bfbbb3f565c382ae3e7b95779149843ed6b0a8a3663ad551ae37cb1bc7393939aa06e4564bf436666e86bbd996d9542ea73f65d8581a96847833d935a1e33521263a20e2030d4b22b5d660eaef3b3c7ec4c71996b665786808996d820f332c48d9d193fee12f754d62aa041f6558f6dfd6e5779edbe322c392d051937adb0a99343686a5dfa47ca3de58a594db62583e0fb759bd3eed7099302c9bafef67668ebeeef900c3824e793a0b339da53efd1e7c7c61e9ed75e7183caaa708796131ed7c96d431cb5cd7fae8c2e2781673efd8acff1f157c70615906d5f273ac18d7fad9c2a2cce5ef9a59ea6db1b5b0f47df721c32b9d369f5958dc8eb34a6eabdf5a21161644087de76bf2ea5ee3e30acbaf315a97cedffcbdf8093eacb01c42a38bf6d1f96683360a3eaab0a434947b47511f34735458be4deafd637972e9691f5358f04fdd7256c675f9ef430ae64cd16c8dbb71ea35fb4a3f5dff6e55545bc34714166567d4e6d33b25f5018565297d3ef3e7914297aeb9e0e3098bf97f62ffcd43b6e9954aff890f272c99c66cd261dfe23ac94f7a346359c9acb4f0d5f1c6bd45e9c18ce57e71954289cee4590b25c564084a4ba1c73216749b9efbf97eb96dca58f80f539ec9a31e25c4642c09a54ab30c13f74006b679a79add2a9b346b549598cc31fdcb2d8fb160ca5cce699dde540831197a186349948e21f69de76476a5b91ec558b64f4297d0e9b23efc22463021314969206dc00088491b950a3196f467591e1b3a2a947c18cb4a26cd9db1b4857c2f8c651d6fe4743346a551d92318aec86cd29875465537d3ea6a52fd2d602c9eccb56de2f4fd07f3178bf995ccc1420f5f2cadeba8a92ab4379657c2443844d44ed0a3178bbf615ee95542f657ca79b168ab217a4246cdb32533f4d8c592add242537cbccad12d0e3d74b1e0762be3aec6836b66e6d023178b42c6f28ccd41fc948f833af4c0c5b20b2953674f6fdfa1552a282928ff8610c56de8718b45cfbbf9b436ad73e6962d16b3a9870e6ae3970bbd16cb5a6526296e665a2c7face9f5d6e9d4e6b3c72c9647f7492d21576c6a942cd236d7ac9965671a4a75ce3c27af77e62ef488c582d8707a5294cf06b5562a439e08272726454a124aa5b24ee050420f582c481d1eccf3948796517b74106fa1c72b166ba45cf3ff0c1371ba6251b938a932fd5f66946ac5829a67ce302dc30ab3dd6babe6d6b03937a64d527bbff9c89c5fc592f299d1d8faa2939a1aef7aa862795c3cbe4cb34e375b2a966596cd195c66a8ea302a96c48fe9c7a8158fbe9e824d5b6b1b57cf34cba65db9b579c5ae69a542648a05dfa4f557be947ae42e61334224e149eab321e706954a299675da7aa9e3744cd083144b4ae75e8a9b8ebad695b019117292823264538a08c9c11b425cc03c8ac5945949971a8556e266512c6886d0a9f756eb98bd502c6a27539fc6d4c713428210373d40b1a41e548590edd227f51c542a67e8f189e5933a0bd91f7e1e5c26a588902345e8e189e51ed75267daf39ef53ab19c844c3a7869d2b06e0f4e2c6f0e35e56ba71ca4187a6c6231aee798ccbe3fadf6647a6862e964fee9eb9fe80d0e210a5fe07de69989a5173254b85aeda8a41c13cbfa31631237dba6f7bac4621032d7349c29b5224b2c6effebe83f2d43a3a712ab9cdec6186563565bc54ed5dc866a9cdbfb9458dee8a22773deeaf87812cb3207294bcc7f8534690f492ce9d0bbca56e66ae624342a951e9158f6794f522b2db337dc9058ce31eac8484dca84d679c4b206f1e8a5aee7bd85d2a8542a151447f43273295da92292384e52fa0a3d1ab1982d57c6dc7f2ee3cf8845d5253a3ccb983e374bd8d0e238e97e418f452c7b9cdd5b994b5fa7b087221683965aff66bd6486532296560bb1ef2e5577577f420f442cac969b54fd70ed269a2cf438c4722b2da366a735dd6a54c28622a40d65889094238658566d172de4cad810ad37484e4c488a9cbc1a6c27df417a1462514b8e52bb1f1fe39ceb5ff046e2688383b84102470f422c77f816baa4d070b93a8358d0324367542de6f3b63d04b18eb8c8bdccc7b87dc7eaa05dbc7ca53e79842fc2c6102338384941f9428f402cf6071b1d55bf9651fc8058d67cdffe59da7f580ead8f1dcd46e5b558c2a6454c86a051a9700f3f2cbfda98c4ee8577aa911e7af461e9bf64e89c5c8c9b7ef161d93edbb9942e33bf50f7b02453acd2f0c2446e9f7a58d6f93fca0e5b652e5b8f3c2c6694f12232d568bd71206cac01c48df4c0c3829666f7eedaea1e8577580ce662648cf5597554edb0b85a3c544917afe386755890db99c4fecbcffa3b4b22f4a0c3d2ab5399540bf951cc8343e8318745a1b30e6abfb2b5c88c0ee9218705d72e5fea09b5a1a4f0c8903f31c2dd230e0bfbb13cde689a13d196a41c36b224e518c938522e7bc0410dd574f79ebafaad31f77854711b73ee162a612b4949d1931423263ddeb02c84941ae58448e96a2659cbc1a3380e0dcca5082922a4c8119247711c2267449e480f372c46b53226a9e46a79d4e9d186c50c4abe909dd5adea4c0f362c8ff96825b6a783de6f10ca1a954a147aac6171e3b484961ee21d536a58782d4e4bd159fd6a152ae19422271d1df419394490a4471a9653477850ebf2a6d58f86e5fce1a7b35dafac103ac3b2dedcd27d9e49967cccb01c45cb3f3467abd57a191663cc9eed67fe547325c372dbe911bfa2d5547763584e5b9bc58e96502f5c312c7c8e2b56bcb3e8dc6918163eb3d8acb569f92016426230e801066b6f65c3688cece8baf78eecf260aec22f2c86f49c44d3ea4c4a985e58561b333548b197d1378a0841393992fe84c4fe0db59c5f030d3480a41ca141a572f2ca2448e58ddd2b9322a96667a8a1471796464b472f99a37d90b9071796cb3d96964a1b1752ddc272a72d2db2e5eb7ee5f5d0c2b29c0e1bef31757978e1f81b542a70fc89137a646169ed4b963635f6c0c2f28fb6d6fd981e57406c3cd3b9ce6aadec96485b91aadfd58e2e991e565870a157ca0f9a6476ef4c624ce85185452946752ed9f11e54588cb1a23b22b73d8b70f56250a9748f292c871b19b3cce76e49d552d0430a8b41cadca5ee4eb57679099b322142028710c5ab978324d11e515854afb24f9c560d6ded081f83933782c91a3da0b05842cec3ac145a8d9063207a3c6131c8556d9759838ccf19440f272c49e92b3cc73bcaeb4f8ea41c6ec672d21f5b0dad49b53695b0a53c0a89391cb4bdc18319cbfd193cdea4eddac9542a46881c09a058ccbc1a1f75d66c353a9f587ce525640e328afecff1c472d8fa3ab1f3e9c4a26a7ecff2aa3168f97062613e2ae5725229f5966f6261769596e539ea8f51ae894597311df376cc6e936762b9937dccc23f475cc831b1a4f3b61a59cdb52de4975858a9849baa972973905b62e1a45c7bf9bbbeeaf14a2cc8ea6a3299438965f5314dc91cd4beba9358f216aa4f9d5c29ae4a62d94de9d196e323baf4482c661e51552ecfe3c93824163e78d41a95beb6f21fb198364a31527dd399ef8825b532b3721d9531a2462ce8e7e4f2994b463d8c584cf61b1e4d45b9d78b5832198f52a7861e9315b1dc31b8dcf8ccaf344ec48247ad4be7e8cdcd65236249776c539ab13ec492d07ddde967e7c967432cca18b3497d2b2ec46297ebf1d14a99e9141362f15e5f73a37cdb68e2412c7c77d631b2eab4eeb02096cfdf5f55848ebe610ec492ba884b21f24fb79401b118428aed90faf747ca7f58f619617293c8d796ec8725e99f836bcaf8a744eec3628c52a9da9451ae76cc87e5e049c6942b8318d7da3d2ca94d7b5532662dd5b57a58ff795657dada3c2c060d7f32099155e62f1e96a5904168970d23326aefb03c5a85ce8e172f4667edb0a8fb59bdfa6e9929df3a2cea8dfcec4286c6782f1d16fe930afbf4d974b2770ecbbaf327d235556879e5b0a4856a6af5bda542ba7158102e3b64126d59f2a3705814fd4929253b856c5adfb02cfff2c4b77d4e35ed86453d739a45c86d58143a830e6ba3abde65c36299efefea57aa7c5dc3f2a98cb9f4c7dc8753d5b0a0ea75cecbe36fbfd2b0207f427daffed74fa161514fe7d29a36af29d31996c757870a3ffd5a6586e5127de3ab3d8f6ba80c8be2e4bade0efac977322cae0c9929a227e7d53986e5243b68572a743ca72e86e56c676718964c9e1a19942ac1b0a434989677ea7ca6c92f2cb9cc1cf37e68d9e9e5852577d9da3d5ebdfa3c7661a1262e84decf8505d33d5a7b9eb4bcb48505992e464a99fd29a58545216f3eede356cb0f6661e1f3ee861f511b5f266161594c888e9b5cbcc292aa514fb917adb0d826739cac7a6122f52a2cabd5f64995d2302d2a2ca7fe8a931e7593a65358fc4ebbeaa371f7258545257a5264b767a1c5282c7d14b2cd6c95d8ea100acb2ae6aa3c741262f44f587e9d3d5da72e00272c67a1e5680e79d9d16dc69249d75bdb5a48612a33166556356bfd5221c2652c6992aa654cb6fa674e19cb26575de4edefc958d620738a1975994b858c4593593386d3ba4d4ec7585a2d3c99fe3bcf51c7184bfaff9ebdd35fcb783196b430913dab9f6326c6e2be692144cfb8187b188b4a5bccd37c979055184bf2b4d2b06b528a3383b1a46d6bf3adecac4466c0584ca15ea22ee59ebf58fa2e39af47c667b87cb1304a7355f57795ccf762593b6cff5385eb282f165dacfcd135b7ba3cbb58f6a8756309adf3b975b1a8eea14727114f6ee66251d8b98f6ef97d225c2cbbf86426f42b99b3313f6eb1a4956890adbd4147a94bd8e2782290388a11131283821fb658b0f711af3d3e976e45ce10365e9904e9572645127fd462e954a69652dc5decc94b8e16cba765aed4ef93bdcc514e5a70968ac481923a8b36dbaadabe6894d958cd32f4d4ee7eacc9ec0f592c0a5365ae3a37c8dbc7241a6cac01248d1b005103c58f5830ae2a2eb73963eb22a3a11eb56444c610eae13c493182b058d8289514d2b59891a255c216c7498a195b07718384053f5eb1b4c957b4fadf6cb22502a40d1800a9545aa003c41fae58ce9b3a88d82e4bd848549133e41cb662d195f220b73609f71c562cb9f0dc8c7bfb61d45bc592ddc9cccc6196b0191bc20f552ccb49214d4b66d2d175667a383c154baf22746f7dbcd05178e975d0c61a408ab098e9c0c30f542ca891257f62f273922b94532c88d11bfe520bf1639b31f9618aa55159b9a1aacb479cf0e44729964d3665d6ac5d099b5aca0f522c89fed4a7c5bdafae55091b8949904aa55249b31f829090228b148f6239476919b5bc96c9750413444284748620ffc00f512c6a213f85bcaf1afd3a144be2b5124af67678f6068a25995d6dd8f0394eebffc462a86bb966af6ffad713ae464da2595edf3544e75c5a6ece1ebb13cb1f5ff73b3e6ec5e88ce107279636a594c9d59c1bc40d12921f9b583a1d3fcf394fa13754a91c1c248e6204122328260b3f34b1e06af4939642e45f7f463041a3a3f02313cb9aae5f9d89ff7c9eaa6062e985efdc86de97583a9d53e7e4395a5df73f2cb1182a33eb0f79d7d8ed8f4a2c2b59a63cc89895fea0ffa0c4d2eb98a6be37223baf7e4c62c9dd9312e7ae57ab4afd90844193ddc87cdd9e99d6c8519d4f52660effcf8f482c9f566da9e4bf350a1948acfa6db719c7c63679ad4bed3228ad4f6c50063f1eb1f81ff48ed4933fd76e137e386259a696d13909f5a8b4da88850f52e9a9b715cd362316a5bed05166ca70a1d92216c48b8f8c21fb3767fc4311cb61c5fae8d2e2d57e9d88b434d3b8becec6dad3d97a61ab5c95d6c1b71f88580ec27f74897d98da1f0b3f0eb19875fc7ed8129fb55e97c9f0c3100bee9ec3b44cb3aa4c7ba4086f43ce912298422cd8cbcd76a6418777152116432951ae3609b1b2fc12b6bd810f6241e429a1372bc7576c2a951f82585ed5b9b47efdf00c9d93a55239275fa92421427e0462596a9549bcbaf41ca40c22e107209695e63b3fcd7af5ca6d093ffeb0e8a5a5fa0ea14f8fb87e5896531f7757558e5277c8f9d187859739f7d73c1f16558d6bcfab41f88cea33093ff6b038a6bd46940899f0430feeabd35176cef9a9f7c18f3c783a082d2f6e3385876db3b573545ec63c6dd4d744cffbf3e30ecb99359db497babdf3f8c30ecbbf7baaa693bf4829d76161d3cb482947aa7ac9d061518b4eea7a63efe1c71c96ed7d5669a53ee2da92c3b286c9088f2fbaeab43fe2b01cde492b8fb254faad7ec06171544b7fdd1ebdde4ca9c68f372cb7d0352bf5d7a6bbdf0dcbe6ae4f47cd2acb4da90d4bb6312293ea8bd332870d8b2ea3874d99a1e3b6bc06bee33ee633abad66075dd1913965e6fb871a16def4d3e383b91632f5230d8be184145f3d3a28f9d50f342c6b4d97426b6816aeb612b63f2b6222648dc45c0f7e9c61f1c48ee63ef5d1a5d4fe871996d48c7417f16dd1a3ff28c3e26e0b8fab31f259c6dff8418636a8e6cd6cc7eeb606977a5abb68195d5346436e8ff0630ccbd994fc95197b84081d0ede2822e42405a55239f2430c87968b1d5d1896621a326a21ffef223fc070542f27eb4bbece7a233fbe60ebdcc66f53ddcf9871e3a68ca1e5e8c6ff75f0c30bcbdb397b38fff0d516fad185a5919fc306a1e1af7b2e2c6e1ea9dc7fb43e4e5b58ce1ab40621a558d7911696c7565c6dcb6c884f1696852a25437e7b8c2d2cb0ba7d9f3ef72b2c88c9959991da39e85658ec9e4ffa465c85c5a04a9a4b5f25aec3545896ed425caa328f513a85c5da20c4eb98dbd7cf258545f5519ee84ef7afc61585c5a4aabf4a6b416149ce7dce9d95d499f43f9eb06c67ee992f579de77f38613154df484dc273bfcd58d2322a351fdf5f9dcc58fa1c99f97412224eb58c05f32edb1c6bdc334a198b9da9225fce5c9a52321666a52aadc3f43b9e90b1183cebeecbbaf6173ac6a2b77c36dde41942c8180b9e457b899dd1cf9e622cba965c69b255c6df89b1ac6544cc88573d1b1fc6e2acd966d67f42ea5918cbab838bb56d9de16f3016455d7c3495982a293016c39672d1d020645c7fb19cfccc940615e253e98bc511df3264e64b91662f96b588aaececda2e3f5e2cbbe9dfcecdad51cb76b19c231f661e665f64af8b0525befa36b637a9cde762419ce7d8b6932e3b0b170b22559ffdd698c7ac5b2c6ed0fba8566fdc8e2d96348f6caf916db67e2d16bbbe5fcb68a6697b5a2c778c61756b2835be9ac5b2b99062be5ec9f9942c16b4874f8db3f1b24ab1588c31dfc9ee91bfdd81c572f864e27d7514eff62b9693b67ca9a276c5c2bad0efeca832acdb8a25e5a75488334f0058b1fc62466f92a1fb39a602b08a5eebd7e4339b52c592da461dae6a747c52b1f4be225f4793eba1624967cea75f576a999e626964beba8e37dfa12916657c7e78ad5476f7a5585629b39be84dba7c522c7876ddfd2b65a6ac46b1b0f94b98bb8e49bc92289694c8244ea967ea0f85623979e8601bdfe547790a0028963eb33e2b2df654f314804f2c88ad932796eb4f88b8ee18b3efd489e5ec3166ceba99dcb58913cb651e7f940c35b2b46913cb716b749992e1f3479326f22c4b8d9272cdc4c2d8c8ef184d881715138ba7a536d1b0bdbacc7489658fd93cadad50328ac912cbeb2ebef9efb5085daac4828ac7fa4ea234bf9628b120550a1553b9e23c6b124b9a5fc744b8d4215e92582ccfdf4c2a676448456241ccaa2add78b2ad82c492d41cc59a14754a8b1eb118eb34b80e21e25b77c4a2f6997a92d13c576fc492b7fa24b30cee326c462cdf48fdb8f3d332c668118ba9f1e36ad5c6b42a52c4f2ed9bb8172b322aa2442c7af693a74d5f86fa102296d4350b152f93f95e87586cf1b9aec3b80ef50db198ee336bd05d9bd32fc4b2bdd2ece144f67c4588c5a4b33307bbd1f2518358f690d2855e5d1f834a100bd25785befc729d9302b19c25dfbee9ed3f8500b12c2eb35bcad149e8d01f16fb3b5cc8fd26371d3f2ca9562b32dc2bb942de87e5123a3da51825a5ce7c58d4f664a3396b9dce7b583c215ee99c6eabf3ea6139a30995afe5e485340fcba929e3eab51e0fcbf533524b31e5b9c77387459132b986d4328ad48e1d16b7ed5ba833e1a39a5387c5cf9a42dfbee8b0e4ca67837934f9e09ac3823425b370dd742f5f0ecbf32a334da9dcb8290e8be67bea36546cbe101c1647a649194ce959fd79c362544fb54ae6fb1ce56e581835cfd4c1b3d6726fc3c2bcd459bc523b1b96948ffaa8b3f8e47afb1a96a53a99e3c97796d976352c692d368ffc34335b7b1a16a50e1be1da63f0133b1a96d73e4a0ff9f144643fc392d868abd110a7f775332c6915132b46c6cbb0dc59c346eb92f9d3c6c9b0e06965cebd53d5e7c7b09ce483cca132e7245562583e61ffb2b52236288561d1d577fea0c49b3813181633a6cd28b1939a85beb0585a654e7d511e55c70b4babde47da27fbbcbd0b8ba69da21d663784ce85a57fdd5cba1e4e6c7c0bcb3156de768990216a2d2cf7e8aad2163ae5db5958d4b92bcc7eee4dd35858cc2d6eeb542835275f61d983de8aca18b6456885e5d13ad878381dcd835d8525253c6330e97d26c7a6c2622bd11aa74b53a44c4f6171b5147a93d62b946a4961316751adbfb2b3843e0a4b1f3ad5989e32f33e005058122956eff8aff89902f084e5d54a6ba5ba54ca300a80139684e8583a8d1236fa6ec6b28a6688ae8d594a3533165c7cde28a3cbcb58b8f5ccffcddff8282b6331ca937d52eccce4cac958ce2ea1a555898c85d3a419b3a5fedb3cc6c2bc14f23c5b8c7f8c8db12cb5b3d8e6139d8d713196958cd97371253e6d9818cbb1c376c89ee99159c358f0ac4b37eba03247bd3016756a394db23b8bad82b19cf24908539a2b3c058c25d32152ead58f5246fd6251eb9c57fb2a8d1a4abe586c21f74a0a155e5aeac56254f27532b151e58f78b1a419bb4c9f679d5f67178b5198e9a8a514aef7a38b051da4de75ffe869e3b958925b72f4499d377e8c8b65e1274f9ada66e5ef2d169550b2499b966c7d6db1fca1a5bd9ce89c325a8b05a163bbd4502efc95b45894ef1a153a3b9b94b3587eed78a695f89759288b45315a9fd4f020c775b15816fe526650d1a5b46c61b12853baa6d4303207d9be6269c783d0a9b5d6f531eb8ae5d23be739c768ad5bad58cef95ed50b99f455cf8a05ed2e424621b4e6f4ab581223956cf9952a16b3ce79dd4d3a5728150b2a85f89c52e6d39a848ac5d6cdebb9447a8ac5e449cc8a959b624928a121f38a198d7b2996c367eda8b35a316f9362413e87794c3267bcada358b2fd24ea77f4899055140bafa4fe93afc435c61a8a855979eaf37c496daa8262b974d4b2525e536ba17e62598b1d1952d46f99a89e581452d89e6c2164d6463b1190e8a864ed2604b248180a85028130181006a4e977150013140030181426114603128120c89a771480044a503c583426201e18128e04647138180e85c1a050200c0683c180502810840bc1d622362220a81f29614b3a9e12b2c71e101e028790104c8447168cc4bde5d3673996e5cd5799203f93c5e5c5c25aa02e440bae85af1866ac40d400b5b9583bc5b7e80b02ef83f2d030a48404e235168c959110a484042196f8f6f3314f2808f540c7f83fba40de10160e89d1181ec2460c66befd04326273accbabaf3e99fe5f3696173aab83ba11156c043f1918f943144c160194872789a7980283d5640a8a25c299a0151890fb1b9dcbc023113899050136812b2ea13972115564177bd1b014a80d51c19660b78cc4c8360860ded6a1ed57db387b361ab5d56d0ab6024d4157da946e454d7db1a24fd956af29ec2a36155b49538999ad8293470cc5031a83c076044c358b9367fca5f32aa065343599e7f41437607369801dd282d3674ee13571e3876a3c6b97e527392835a8adcb21f3155638f8fa002fd7761d713299a88e7a337b7db92e1fc819aed0c691fc3bf6e4be903558671124d6229caee642f96be60711d2c0e0a8b4a33114264195b39d3a89b0bbdaca7eb4155097fc8361081b8b892733f33850328a811ab42593cee100af0dd40aca0404024be9f446d0ae66f1030d68d3cf827f2fbc398d4af5322e386c83d5ede923716dd7a73d31184b3508752e0b65ac40874e7796f00d4e4575d9493678d0a55bb1e6ab9c427a69313faa8839dae2ed610c8c93248e394023dac83d4f74c5f3fe0db1cfc4d06f171f8fb3d24466d309923895de810b6ffd848a3f42db8c1884b5122954907e572b358dbb93f7622371e61f693d5a69dfa83090ef2c4d79ccb385a4f2b3d03be7a40196786be55347d790cc04a77beab6e8fbbdd7f812f3b4aa1bafffaf8c4bf159b93ad5165b846bbd3e49893e42308838afddcfc521c6f4d9126231cf63ee2dc456c8981a0f2ccab3bb382bfc3cdca1f582232907b1f011aaf8296998d0005a4f33e8c6c661cbc28bd2bd403ca5c5dc149191be4226d3944e424b2b680cc1b6c096fe7e6484810e4608ff8539d24ebdf13b5c672525f8d458eadaeafb0be14015b7a575af82330631c54adfd8bb795c0e607eeee1becf3bd7157788b9657d0a4e81be3f91caa38a984df2eedbff4e264377d439c9735ae0213f5ed17c7a03a1b23e5f2a4e2a39f4a5d71592e25a2906a1e088b89268893a5a12a8002f6c5138481b9cabb39f5a4ca268109492223c1b01e58313dd3cddf4477b77dde9a99aa2bc0cda6d83dc40260c0ba60ea88d815e19b69298468bb8109b4980068261fb0c5d699a23e2683d6ab342cd18b7dee6dc93a3acab5a5b238d56ff45df1f9c489091f78349982b99ffa479afc57bc81660c0349b288abaca603764f8c1cc48d2dc1f3e29ccca8d444b02df4c59387e55dd6064fe548b1305fa845520f96137d48e2374c29c8f7479ca9ae9ac748c1d9407feec012b09d12c25014b17e571768f69fd15c0b37d7577a28b1a9ecf4578f66cad8a8005bd646c7ff0ac444aa011806af659f65597ca150e649b22631ddca2b9c134834e54b3ddeb5a7389f955b3ccdfb200b7e61f67a1b22bab020fbc43d979af0aa36c8670745e9afdde34976c9750611cdb5db8649f64d37a9a62da6c6bbdd0e4dd188de667b669f8a8daa5ae30a8f8cb5e99a98f4855c68d0c5ffb51b060085aca29a4e1ca59f67071aeafe42a9519535b009c3ed34d7eeed6cc873eb192712933d30a409f3ad1374fb92a20596ae5585da9bf43840bab467f736e8206b1a05a315013a7e33cec7c6f5402b329602a58a6fde857646a896cc095e96e2c76a39b2e1aab1b3d13514c19f5c4ee94bc265baaae6884f9a548ca88998872dfb3a3502228f68f090f66c18eb110b507aa495424db0d1a0d14fe329866cc574368806b7a4959239a9b273cc65f2aaed6733f1da7627ecc69b64ed1f49ab9593005b36146d3758a265326b023e226810c54d684cea1993cd9137e324cbd26db343f36ae1200d1d152ba3d73c5b936853f508cd999017115a9782ae3d13de802f4dba8e4bdb3c2269b06700cb088001f0003f87d43d128db28a80834000474213cb8077e0c8e8cc118a031892820c00730c3ff608c8f418dd7411a5f83371e06613c0c6abc0ed2f0b9ba0377fa3498e30e1a59d68dc9f276634fbb758996f3488ffaa170aed6293af806056c4003f20109fc0c41e1e0bd210bfecbacf13708fb6111d66b50c7d3208fefc11f8f83313e828337a087afc11b0fc08117208d5f928e60fe48c101b891a48ce05f38024d83d4900b8552694957d34a2dbf25580c2bb05a0bba885678712ffc1a5c198bb1406b525144a0cfc45f8f2b86d3f5bb044e8b2cac271cf0bdfe750440106d20e8b6da8f9b513fc4c01bd0e00d08f0009cf03008e335a8e36990e20318f001329275bb97973c588419ea26e8225aa12a87b02e180d8119f4c00c5591407d944bf2924485946aac1cae25892f18400728c003425003a801413751092f580776b0000f50c0136ca01ba4c3698447f5d08f868800ce04050a7908a1911bc9e00d06d000c2e0384872f55edb34b4a9f3f9b6f5d3422c0a2ed5a34e0ab1bc881210f4dd9f12ab3e52f45a111b7e0276dd097b9d751f792cabee3ab2fbb3750ad94d04cad0a39a4ac1079b255c0c3da0c86a33f139c9d7516786168b4566ae32f8f55ff0483a24674000720a84b215cca01dd2bbefff6f2924c27e291aab0029d111f494eafc1ad41060d2b272c5f5241f87a378dd0c7e1e2531d626dc986009b0f9aa6e2ec927238ce339e155c065b23128fd4cb4637e1e44e870b499800117eac94a3be3b64e6d956aadebbecfeba88dc72f7468e5752c2a24c7f14f5e62139c3458a10aa9d53e38137bd63f95ac3e88070fa3c3cf536e80b49ceb26a7f080ed9183f3540cfeec0c1f2e9a62619cde6dddb724b85d4cc969ab6587f99af7ff7ae4ec79f80644b5b7dd9998bb529cfeab069c1645e34629bfd6000ff5cfa846e8f07ae161a4a642a0ea73380aa4d06e860fbdb6c953914821e6671e672cdb4bccee6283dd93ea038b0e3f229238a82859860969f848943fa8427a058a0f3c1964a4e244e769001f33e61427f7ab1f3bc16e3627c6a7dd5d2948b4ee1f822730264fe45814e8ee75ed6b5531fe7ddbc8aeaee506cdbbb9f5c25067865250412807799fb3934886550cae31376b94f0ca20e0160de806023e702e3e6190a8f0c54d0bc99fbcac84a1ae2118e3efff7d3d424dc6bc025d0686f9de248c34c7afe0b41561a6533a96187c88470588288f0d7e8323375bfc7420529ca8bf0d82dae0ed845e3ec18e2cb9d2d73a58b8bcfe4e076a6e4b61c6d7e9d8130928263baf0d105e05d6d9e2ad814a2440b92c40af5e98b062995c3ff3345df0cabdd53883e39936431ef552237a80614f3049a351e11029a0963c6d2a89252860aff0e0a105046a899ff4c29b09a322a4520a49af528902118940a63b9d101fd667d7514a757923400f86951731b7737f9e53b1830cd307d3a5a8ed60869467e4ad55893010830325d3dd87dbee9e8eccccabb9cf201c758ccd64c69f0ffd186329d3c8f8bad150d6bb0d3b4c097f07747063ccd3d4fb8ac12fc5126fef6fdf78006d70aeeab7d245ec423bd088352a453b6bcb1d5cc933b3f76cd9a47111498b74ab721e292e5bf448ed51171a6cb19ae24da0b70152da3dddc45a394287f1627621a8cadae89435b5bbab67a3c5bced2d0b352a2f5670d42ee2bb22bb2d6b31597e911196074eccf3f36832a317b5f32a3061248f05320b5e20e48f06ff67c31a27f80d1c1380dea44d474be82f17104baee423de45583fc0e8d704be9099f5460438648cc512b1123d9aa6e2679200988b3e8c102a8f0c9197b2ff60bd3da492d7e8d884a0929f53ebcb7ec9873702bef61e2845942f2526a536669b05d9368c1a92400174192291fdd30c65487d965aa31d5d360df68c05fd0b7a6b70e5c2544abd48b459b7f494ec08d3e2cb320fe7b5ff00600384e6c2d71ea571259830977a82985bc23561c7c2316863cf0d4f0ff6f6fb25da8f46e100aec09c629c8c11591eb9c741f1db54821eea9090d4da42b16936bfec840ae239b82701e2d94487d442b2b7936a7ade560ee985e2a977304b87bdb48835432098f9cbe4dcebd91ce8518f8cf8eb8e54b2106626ec22ac516104e07809deff975dce4e413f4a4ea5c02ef75300d517e322ecc5b1faac85704219de1317e5c7e0a576d86e5d21bc7349cd52e5f5e2366b92a7f47a9e89b08a72eef1effe470081b9dc4a997febefb259315ff3dc1a2bc16d922def83174d6e3a1643a1a2c3d9ad9eb4f3731c1f2cdcc8a5f6e95d188e75ea3a2ec717a3f7f56e2a960a151f74ce570f6a466ecfab39536a2ff3a975b1deda4fe344764c30a34cab3707075ea770b4ffdfcbdfc91cb9d4708850299b8d82c6b081c5de77ac4ab3b725f5d531af107914bceac5946a537cc23b8e527f24dc9ba9b3f8234a6a18196fdfa413784f17a3931be29ceff74e3107273502ecf2469eee45fec180263b19f8e659bd68d36e6482c01ef5167ffeda0edc2f9e6fd54a4df6f9d0e7c1d445a1b108cc0e79cfc915d01e21aaadc97cae919ca203b6abb2286d3df3f39906e86c108c34ca364e9e6deaf24ef06f7a563ea2cbd91c330210b7f73c7ccabd8b00c3b0d8cfbfd91e3a5222c1b8d2f7ba6c2deebf48393966be136c1a3035efa9334c4f516fa273259b1e10bba7d42e30060bc6cbc0ddd28790f800e2ce23e80b408cf2e817e77074e09a442e3911f7af231ccf04b1c4f7470dd269c74d06ac880c2ff69ac298c901100606c59db520d882e581af69862b2a9746bbd2737789eaafa4f83ba46eabb5103dda3a4c34906c126b4ab09f697268ae57a7b00a7bd14f7572cdc9b561bcc289e4bdddb51ea3022c8c91ba6fc1c644650cc1ccb61f6b8c8d656b00fa64f5fde624a0f0abb974951e4e3f086b0de499a723dea87090e27b68b1d6bc3c7200338a8cad853e0a7d5eeacb63067bdf6d329888e423d28b1ae4cea2810ca010de581d7b9f6fc63afd491a3d4f5bb1dd7a60cf0da4a0f873f7a18c91f36da6c5098914e2c901d8507ececfdab7c889b79bbf0ace350339fdbbe3412725058a65e723971b3a1bb5106eb7221755a9b7c9d9b5970ee6d105a8fe36f8ee80d594cbb877287467b8d622f8eab126ad795a2b33f8ad1018381cf5b9675c02e444a39c2ac66b3859d654d3ebde4d28b3f82f6dee1860db0ed968196c3c0cbdc61ad8dbe915c9e979aef36f75a001dffaa3d1c1af17740d35cbe022d0e56a1958cf2c832a4e32de5943eec218d8a5a785563075a3053c219377d7a762dcf4eb14cd4e9602b1136dca39f56610e8aacc2a4f76edaf031165c533162890084e358fc98691934249023b16a4c7e92a093d09ade2792d07abf20c9cba490ee805aeefcda6272b258818da5e59270bb8fae6280796bbfbaab71df81f1f11832651acad8dd3ebaa3b62aa86a13a0800b0a9a08c5838393c2f40535752953ade819ca4ca2d9ac956c444b74493b7da039400be8d8303a0ed7508b60e0434a8535afc3184fc7fea8cee0ea790621b3648c8092a6b517ba0a138d6230ecd7be370737a4ee88149fba6fefddb19e3941c143865e01b6ca041041395c277c517716e266e7469143058dc0117f441a131c17ed1b7b83a6614c6ef4b5ee022eab5f50d1a848149214bd4f922e51dc33646d3289963ad70cc3953059b8758d0573966cc2fd2dabac419473094bc5ac0feb3e6ca910c8252ed70c571ad2bd28195ef60ecb46e722695b7922fe5c92cfa4c5e4d40dac0600760da1a716abaf43edf3b14a52a07a95d6a0dedb204b46906dafd24e360ef3870c870a8731f7ce5b0e34e92d0ac12ab117240dcc0880b18295038441fe8a277c4c99fb041b03092978cc0afd16fef4194dc65607e624173a4e99560bad9b0faed18e9e1ff49e372140629a9b0839e969fe1add64f8298bb2746831d5d024e5d22986364e3cd6f7ebdd0ff68afb398636d1855f6062d63f9c9507dc31f46da736d70d18b33fc663fcee08b466c193cec7787ac05106d701fb07a8b8a20fb806e9af960c96fd81e359837be71bb12d39a835e660f09bc942e40a530adefe3ab2a9ebb549b53dad7e3ce5d7efbe354aa09267cadf87e58036239e7314a98213a77063a70dd091da7d5f2b2254221a6a1099c6e6d00b9b798763d490be66ab7abd46df5b85b60e7f9d287d0f189aad7596d3adb01ae36c36ef4adddfd16615e98b25111b4fd187cb6b79dd092d9d87dd3f716958cdc5084da9ce5a7434f135ecbba93267c0ebb41c8b7d6e5d153f866b39e635643a023fd82ffe1a4605aecc62f7bf52d2aaa0767a87e0715c2e11328d7376ad9123078503c3ce42e746fd22b73c8267e7afa673e0db45c93c97c218621d01d52d3a66417563bda792f0b51c360874ff28d627e10b426c9a887985d98afbfcb41ba2e0f0e6148af029df7af9d519f1439dd8bb895a8b94516b513f4c4a4a4410e47cd051a3377df02fc6fc0617540ba33ddaf999ff8d3c0dd6e6dd32fe2999154c8a830d56ddebbe488c4dbdcbb6ec465e4cccd57eb1bce45abeb481b64fa964add0da3bbf88d6a9cd4347e4aa25239b5c9cc843179daea40cb5bc51bbb3d229d05c135d24959d5e2fa9afddec5dd426f56ad90951b2adbf711634b3a2e485a9e7d793e2a67a7e8ed1e53da7d24b8ba464c84d3fa06fe6c984d4a530461f0afb9219859a05a28aabeb54b6d50d0af16bd0cc2d981990e85d96acfac9ea3498b2e0d15c79515d2a822e6e1a35e369594ab784924ed1765bbdbc6865a76448c297044d2cee221502736333690d1be924012e9a045db30fac04d30e732cb56c1154e135551b631dcd4cadd108079800b47a22b19873e3e3adc7840e7b27bea2f2ca1bf1fc98f269a754c50c88b6e6a1f4124eec373890d8b2e106f7e13baaca032b51e830836021df841022a40011d90011710800972601f77104801099003cc0264b7437af36a3405c28d281a494b21d014894a64f7d39d249131e32a604c969667d2db20cb786a41e329341f83732bdb23e0769784136c0bb445049fb0c37a8d60bc44c20c1c5cd8d617690640f9a23a3292ebaa83494b369de7c407600a11929915103e27cd2f5294b022afca8f39a57fb999b31649975ff37663c114ea596915ba4301b9349e51853c9f4d492b93ea38ed94198ac7c5477ec50818fc088a94c62570ae4b668a62f00d2f01314e00f6db4abe3bd3800cb3d483b0606c10813a500b3449f35da929ee0a3e912d3f4b4ca1a11f4c3229988f8454375156b1c7479a5d97c005b9ecacebbb1d4e0b8e7d9940832ff29765a989ead901c24f888b017fb28e7987c442d7b82324bbfe195ffd944a96c85418f121d0518da685ccf14de99597062a02229ddae0b215b10b493d577b93470d1314ed2bde90e210965bd8a869b7791c913a32b4a119c86bfdb51f572cca450ae010dc3654647f36c5a7a8b91ba64eaf2ff66f1f52047762ea9da6979fc8beea1000683879c32e3d25c2d63da2628dd55932b921b3b8ff42c29747b1f034e1cc6315f9384f4f186cec32bcd9474c498f53d2ed423562eb8845ad264622943b7330527146dd51f3ca21e56a0d9bea97781b0a68949660f93592bb7481d9eacc7c59cea71539ee0ab30153a2bdf93f6c7c4c0ecad7254f9cebfc116e6347cb9945574fe00f5555074d159c9ef9025675a9bdd3ba1b8854bf99548a527c6c64051d36712099c648ab1c842c35ceb4fcbd2d7d8a22323157f44b4677c08e8b2a48272e248be12b5f92df9822e22907c4b2f9ee7d2aa4749aabc7ea9a549eb582d5e0256fca1140e740e97b37d005ab439edabe1d1a90ce12772be6e3b65e8a055ead476cc03239e8beb42c8cd740531fae9e3e7b13eae6bb7ae21d2a74899b3ef2cee055e085ce839b875fde0126eac2ea5b72c0a2db540967a1fe41344bbb551b048956dea0399c989c6e3254e6d707acfc338db6699acf48bc620464b3f2fe24049322eab80d0704ffd4d566762a8e08051284ffdbe57730dec63a21b55de1fc1576b15d602818dd6690c504a63645ea9ccbf011f9d5e8194503c917186ef8bade995225fa5a008afd8eb521e49f75831122dc441891410c38014c1e01a0149e8708bd5251f64d2678f80b01a7d2f06ac0091e62610fd58afa3aca2c389cc0b2de5a33fab00d75fa7023d17e11c2f3230297fff2824c44d2790f53aae892c2a50e52457533fb422e6c8b3ddb2ace21339c30687a841a17b0a4674c9d3d86365ec47839c79866667158117ba1dbda37264faa71efc8343954ffe8dcf88d11ddc4a2d5f7f357e73f9cbbf2420aaf7449aa17d79887bc894bb6194cb7ef785be76681e5b0d3ddaf5209b5ccefe22d3a0c170887c4aba70bdf592a6cbda704e48a2e87eb55fae5b38d469406bbd3ba18cb93deb2a247b90b23ee8f0b4cd3059a7e0bf82f25ac6178598f525b9891ab1d6ebbbe11154b375ff456d3b92d4ef60f72d573c6c69a9400095d15b9ea8b77d83f84ea3802f80ae75994e25096aedfddda1e98a24bca8700598a97c81f660773010ed25de38c05fc92ca7ed3e598962010613e165aef2ef041f0097b701ea59f53850172d415cd02cb029461316d0708d8d572c37d15d41906c06851e1d0d6b37a795646a9c5bef13fc5517eade8250b804f7d925c757d9eb941fc3b6e43e77b8f0b69ab020fbb380cd5f4b3dd894d8721003b06d8245362ae0a220a989e0ec55d22ef76ec46de6e790a9c358ca9a200f580c0258bc1ef7688e7e872e8be06c49554621614806347ff566ecc60ffe5f9a3efb44aeb9f5632c45fadd92a79cb277546ece392e0f5a8d81e34bad1fbd999bb04831d36f69b30eb2b008ccb0da6f10d0b54285909d48c6aa5bf14b7fa9b989c04293c63fe5285e40cce531c8a8d2353f59de22c86cd111e843535e1ce26f38f584323cc7b9ba26ea2bfbf0a1632989680708bbb0ccf31e19cc5182818e2045d0f7afe751fca704afc1a92f43acc8cbae680334571979143be08147908ca5986da23076f44064b0ad4608c0a609e3b445650051b07c14b9b08f5f700be7d7a96694f1cd2e5f51cc247383a1671916ab871dbd8d7f8980374583bf8f28f54ff04703cf2edffa845b7a02b0944a913c31480d92a3f1866344809fd6bacc8405d82248dd58d980fbb424423408370136844e7f67e425c47e5525c28f970edfe9ccc13b343fe10611d7ae27115b237415643e446740c0d080ccbef0f9b154569082de1e0b716397af17900902550a30c192eb624bcb0f0e90de2fe4c6f72c8d59524ac0333bac8f86779c964c9a0c5ab0d06cb15b7a5fb5c6b3f0e00e0e7b9e1d0294baf9a3b502df9963881fc1b4fc1ba43fe10ea605df6c57d16b0d55ba379f66b4a24d185faa8e651f03b5982405d61f08b74f92fcd3bbb8bd0006d2fd1e91e75587d8bee909e904657bc03b7b8d74c637705a9eb3da0148a132baf428f5ec8ee58b918a2fd4d8d80cdaede0c9a25b186368f76434310fb98f726fce938b13593d1c141b863feb9eecd1b1f66898450856aa9afe10e41049fdea089699321fea67d34db17f495c78b332e72830ef4a81e8e579d2b676a6e39df7e794c9e17c8a1eca66e8c898e7171d2feccf8bec321b7e2af84b5f81bae1a69833748b3abfc1774a52fd74ea7a76caf03aeac830a87a940d55088c3a87a9aa5580f6968877103741c31e5834a6537f3560cc2e232f3477b1ad30e433486b3ecccb78a6da1d7e084f189318d6187211ac31923c38c720dd11933342605fdc6ce8a71c1b28610f56a855fa6a56db136dc35b26197c942a1c515e333e3691a81ac2ff63ac285038db766b250d9e84a1f23991a2eee3cbca47d783cd5ecbeac27cee215632b4a7283bb821ce3b4052ea7bb7088e9d1ed97aa9e2895216793b3a35cd83ef6beffe99482210edb116df791b77b1f0253239216aa5d1267022e50443fb4a206e9c88f62a97c09564345c8893462a3187510844828421c84a1294a507cee0d32bdc98a0f1c517b224ee5ed22d20f508dc2b3501766017002d2390a3fc4e419b0b46879a3c100144e150b837016685c5aa4a2a408112a55c261f3219618040def3c0f141bc2281a33aea2febe190d8f3ca91b58490b39be36401a501cb069c32cad4c6143078935dde526b7331e2eec38266716051b6f2cf8d5ca411ca5875b7dae5837edab0185744e27c4741cb1ca02c7e4331815af6e9560b1d714cc3a96d76b970f60df429b74a59bef34fa5b5b3d96e3a009d7f11bbab0880ae6e1eb0a00c5f6ee6655d4e13e1848d859411fa48738ae8df70ba2914202f8aa7b81079eddc84af1eb88f6f20aa18e7addc6813594be364f4f761b1b9ca5e348be0f499d467057bb342b4b8ca41d180a7e3d5438f9bc6b843e2a8c552864265804ccd3bb74416a158c66176e32a8f752afb3cf0e8f30b7f7bc8a9b2e97deb98edeb4ca4852266a258548a0c1b139341b8c0d8783eaa4e5e36754f0c011fc32e3a945deb416b0a8d7e0415854b2a88502c5ab2864c4439e54cb8d23737b09512eb63c6a4a13e30bf158dfab9ce28b6c468008761484323bfe77682ecddc63a8de5b40253db99fd23f68f296662f37031253d7346368498cf29ea12d9b685bbd158d6309921ae0002ea0467eecf837615888f64778941c2c4ab3ba609e023827b07c06a2e69bba392864b3554782a0420b8152e2dd6c13300b36e91182e4dbeebd0b3d88f9d9fce2e9d29da1fc1ca29c1692ee3ff7542eab20d2b0239b4c1709b2c2c63477f07ff7cfc84551f4c7e56a4718109a00d64a36605817d0397314f09f1dacfb32c144242cacc5c551c9fea2d025bee5e69d979ead6a8acaf2cd1df57f573b66bfce31786ab9056910c529436dc845a202bdea26b2e038c044e3f6b9e98ef42ef13a3630383004fe8854b33102e800492400083e7ecce9fa7f774861885f48457a6c1175f10023bdafa0f003de49e779ae890e1b8bf29eb71cf5b10413191b134110a7908409a97b01a09385b472506caad8ee691ba997da42e6f1a5911fd64986282ecc7ce221727aed5c996612c242c0fd396fd623494288992cfe9058a255d71c06d91771b4cc89d51c2abb12d6a1d14f48d880b8e05db7931cd52868c704a40e24a06f034876bfa635239b4489e35fc3cf4f311f93bd97327f6a8d6f6badcf51961909f6cbbc31303097d711495bca08d681314b95c4f417075018a3813e313e738e4014b402aec28715c864fde8862bd8298ebb1653d71ce835f79b2c23ad72cb8b8826e88a84184aadb8cdaa71526ec56b566191be5dff1cce35bb4db1ef5b96a4cf4c9577fb191ffbc0b437721b481d1ac70bad49dbecaf570e272b4e3aebaadf2254d6a492cb592d869b41bc950154f78e1fa74398be78479bcb9063722039f67cdbc7414e5031c99f3bfeefdfaa2c4cbe721a273f89b020f193437b70331940852af11f56c6b959fc79fbee784d3b34ca36ceeb712bca58470d3d6db0e792245de08d0a4f40fdf016189cbb3efcc7ed05477dac35bdcccdcb0b2a94ae1158f044bf731d541f0793d63ce67251a0d920126c796a016f5567beff370fcfbebf5808b46ef2bbf7d36799eaf223b6573b5bd64cc358303d38cc6a382b745944bab4c1c471c96b76f5626e0042e9ba8122c058ddd1069ba7f4156f88796b647aaa8b46a79c40f6957f33dbc4006c6793e24edf14464aa53625a5d49a0d0b3608d2f634ceaa2adb3d693a83a1ee5f6a8b93e8c0080c0d9adb286cb2ee542f9e4c29f2cdeb22d1ccd1e916f3196b58db72405f7b7a5dfdee43df09b41ec9c72489a9dc29e79fb4f8563600d44a58131252ab36f1fcf269188e60831097f19915cebc2447061d540ee87c9b94b1a31f2debb803ac8140b51d826d0d39d50fe4816cd0ab034a4f96b4b72edabe4f7ae1f01e73ecc8ee7e87b0740442a1f87543238e235fc357048520491e1c22c71678adb017997be72a45184f3be27cbeac2d9b9325b401f668f28d87153f549e9ea20ec42160b0b82427ec8bd81e783e9b2dfea2b45cea886dab0f6bdbb7e1a80412af54bac1e447102cb6db24c85223fbb71894e6f09a0eb679dd5af6b1333b8d12b5b2010a87ae87d41dca6a04f0d7a02db81c53a993864f4fa1fa0499f16de38cb5d826a15dd9fa9edd009f747a01abe2628bb030d5bcb0ce5c0ce4d8ce871c6f06000d65897a4d860c621c728e2a6066499cc723d71650798d48295089a79a3263718ad0146a3d089ad6b5e1809b6cb4285fc0cd06d9fe66d2a52056bb0730bef3e3d79f281922ccbd46861b37301f1b09e4a11d7f9b9398fbc62d85a7089c0c551bf4141abc36da1859e61f4d875d65e81c5ff4a3e55672810677af69aaea86acad3f016d9aff60d025fd4b8882f428b99b7bf3fe7e0954fefa0548b5ca12c68b9abdded58209483373a083cc058805513767ce0c956b701f0184a3ae8fa3db2c0e39110b826494c8f19263bfe1a16a29d6cc3fc4b2bed15e325f051f3df80e814658eed6ff9e55a60473807066062d80ce1a7cdbd597ca8470d88f6a31304fb4fdc2838b832f4e81840b485817faa8d3837099263a00a0735ea17ec91e0d8c6a9e7899941a66d0dae8c6766f6fa3a6ae9a3a8604cff33c29923b79fde21b5079f16fc0c8749b2f02f2f2543d82cbd283ad2a08aec23769aea46fef42981ab2464134540c6e0778adfb5c128b03b88be472021a6c80210470b371171c49d91d668fc0821411b70b5abb68c2974ac5e521b9a304c6d505963c0cdb4e804ae12c5033693a4722765e713111cdcc6741c6aa1560cb5cecfda7d96a927e4f57b98e4cf0f4043fb4050fba059138e5adda5be1f56cfb8c6f135678a2411badf0e35a1d162edcd1a4974a3347a7177cc5df7cf11e2a362d5f385166f6408df509ee35802d6aeb0e6f0e718c7bbe534d4a998354c9c8c89899a8c1208d15e49b415023d8696eb183877a31de98b3636c813881082c0bd799be2de90f275e9cb3d9ac24cf84b05a72e7a6889a14650232b30c57eb943813928d1e1d1e70c40dea3cd771e1858eb6fac5a21e6751e0ecbcfa11e93f13a10f287be1c99a6f5a327588761153f8727d0e32268482857721a68bcd35e1042a4d49484d797d02a72b007ecb4c52d4a451fb41201a31780aee9518539e923859953bd06f08fe5964b4c3a1433c16953f273ba2dde305063590ed13fe44d79714575c5281e08ac8f3566901f0cce75525880258c0bd39cd26cf21da274fc088c93264dbae6835f3c7b9282416f4b0f5b9c5460f927bf4d6166bf90c7e871a95e0d9494843d26d52c871e46f2d60c94567070394153bc99100c1122841d6c1257cdce73e2176fe0fab525eea9367296e6033beacd6994a0bd2cbfaceb0c1f83977062e57906a9e6abc2472e4123bc84b56b4d1d7456013437d2f252fad8e443f98272cf344ea7955c1fc040b58500ae46c9393d378e3238f9ff87ee3e1254fc161c46229e96f981d30d9428f359630a95aa06f7107297df57e106c402c15278de9cf23bcf3ee9c3f3a45c5bbfad173bbb5f6caee230cc6111d0f9aaaa781d1496563fe694edd8438df738febefb90454fe6a790c0db03b338527f0d3942f175c19c0f5c2609fa62acf15ee14aa5b56a097c78bcd945d01b139c2806fde3bd92b81e87cd48251dc260e0f93ba795ff3d0e2faf4dc106956b8b5c10c3764837bac46e02b52e6a4a556fd39a382ec5e8498b7dc0e8a71189081dd430eb262f934d5b6747e032cd69d1e0c1491acb5e3d43a46a6518c1cceee7b5a8f49f25c86c07564e8cc14d857638431112067f0b9f5fe846e4f6c675eb958528f1081305a436d00f78f168c6be91139a0c67eaa63083722d3951cf0afe7a47ce76167ad704f727e47899c8cc61a7a7fd363d36eedf585823fda0b4179bc846810d0d932be3d56979ad0fbd2367b0e5c6650336ad8adf7b5caea927a3260ed53e632b2cc9d18d3fdb304fa9749710846302a44bb60ab8404e72a1a338dd359712b388e787eecd5a9191d67fad7ded4b2c6805f2b1f5e876ec63b895e4a1b0c2b8e3996429347f685a160ff018d37602526c6e3160391839efa17dec1447a7558d39d65595d87e889329e88328e6e023f01f97107d001d0c6163f389b501e94f013f454fe10f14c138a998d52ace1965113f38fcf2f71e64c719412f9eba54d8188c90a84a9c5ef09871bd49c4e602bc3821019d637e9b9eaf9f8eb081986e811ac3a7cc067c92858340e33a90f09d430c41b685af94037e619a96bdc5446d7acc6fdbcbd7a356e45b0ca1417f37f21038ae392cf4d689d393a43ea7acf21035acc4c382f15f603be67a3b8ba80384f75597d217b2ab18321394ad745d4ddce186e98726654ce269f9e4a16c0e1ef3623c353be2689fda4f3fce391c26bc410217987581b7db5aa7931e5bce58db22950d551c0663d027c8c87d467726a0f54e7b493d0c64b029e190e2d8ada52b659b5a3370000e7223d3fc8eb47ce7b7161408908888405925bc3932fe93515c62845c8a57c49065a124c20ae14fc6a7be0ad7ad3d90440232098d82a8f8fc0215fb7652cf779ed6529fc7fc4e9b53b23374f9661901fcd54e2dd55a8cffa600790f232ea513812e66382daf7e2af5038d615bb68e83051c5fe4420dfd8cec1521432a311095d2bc60204ad26387e300e014c422fb89387539b96f264701507101d9758de3d9a81e04849ea270562a8a2491c0893efc1b914fa491097510aee4619e5d50232b1c59a32fc4d1ae7cd098a33ee001103ba34e9400a126abcac9e6524cecb246897a216f2f6e27b5f1977c490ce5a3432a1a6eb25ca699e4c986eb2d713254efa72c2e4923d9a3869ca879376d1c00c068b1390b639c5d77010aebbf74f13649730f28732184069bbc6738392683e39466824e98008124133b2313210b54ab9a0321ab1171afc4a684cb828351ab84878710c901e943c5cbd3e66b71f57c1b2e5b49b2d65b8ffafbf988156a722f18ef8037506040f1a3a7a8d5f1e92f94d09d6182552bce4de9268b42a1a5049f079e965c8a29876a04bb54c18f8ff25def0d165e13467603b7afb2e1f2ebf738bdca4fcd182fc541418263dc362ad731d3c417c76f2499f7f67b7b4607d09ea6caaa31e18b59bced1341c1cc766f464d08e021c57e6cbd2079526ad23914c2823028709560f84372ebfca87cdef06c2896f99d88d3238bb94800f0491921dc03b41d01cf4225ba495b642d504927cfbaa996b508311caa3f32ac63ab2f820eba909469c36338e5cfc63e334352efc9cd518c58a250ce4d733655fd8b238d4dab53a8a1d65a94a3d95a532b2b122aa9dc538c50b4a38281012106b668f697bf746fe0ec8322e0306b8deb5eb1a1ecfe1dd6ce71801d636d83f6ebabef82217ef8cf1dfd2ed398511e596b8751ce3afee815bc1e2fc189fe39e848e7468e58918880e03632d6f2b9e1979e9df44c695e1f159a67d0ae4f711fa5914ba1b0c7d425a742ad6e8b372c3d2262b14b662c11495fa1ba5b9e35ab9b1dc84b883b3eca6e9d339f9f47da498e8795298b98ae07662895ab726ae81122de11e9b2978ef6c67e25398a8e4ba5f923c32fce782ef02514816c3868317d76acb83697b68ae9f43c46de1307fe8c28cb042922ec6ec87e20e70770c224da9380fe9793141ec490a6f4a8533eb2c2ba068643872245ed19f8f413a2a492a52b44d44919748550f7e622f13d486964075e2806f9580a70922c421a59f5ba0eb1f93b0a461ec62dcd4c00867b516c43231cc3a2977cb33290db7587832525875ccd416963aeb58b13e5eae83ed5a875f93fab067f700d81be3f08f57c91089347f79ae61aea21f9249a80c71ac4fa5dbe75ebd36c04239d6300610516c2c5064d63131c0279b1bd3008553384a7df4314e9bac7e8de32f3f0059a785cb8cad352e68e2cd5c8b6956cc305a1a700576eba866cb18ed54311b95f745ae5113503382938d301b179ab1f3adb85e5c246b37c56848011f435ba8372acace4c68dd109c39026e6244fe0a277078e70ffc0ffc0ffc0f0cf36f9a7253f41a70969bc07393ac8854f024073dc9911c492febc040e40a160b370b661d49d9647ecd61c7118610558bb7d1eefe9e4698a23dee96a49cead8c308b3876ce220e5971cd545987365143e67f97d7cb622cc9ebd8d539474228c9d3a634f21a334a93222ccd02c7bc78a7c085384ec3997df64bbba86303d9eedf8ca17c2605a97b2e9b0b4d28430a66789473e0fc2144288c94e5b49951584793b2cfb51b018be6a204c21480c71106c4018f5bb7c25aee50fe61ccd89ebb8d8f14f3f181de50951a1cbade5ec83e155228aa7c639594af2c11022724a3d71d2ec8c7b303b58958d8cbf5672a807d3c5aec9b70af360883a9fa2526c2c4d8207e345d2cfef29fad1237730ed9a68569cf5f7d80ee6e8aaea9fc8d5c10c424f18cb0f72ac8ca383214a4e4e6ed9e6608e69114246b927e5c5e4a054ea49df5589831955edbea48f1d720e0e664dc71945cafff715bdc1f440fdcf3f94e488dd60b230b1a5d223cabb6d305f3eb14e122e495dd860d4b56871b234ec8cacc1fc7ae29375d2996d6a30dc4c32d14d2feb290da6980a6b1d7e5a2363ac208908004128001a4cc1c457fc42667bf80c86ce312b799c3f6e143398f42bef3b2c1f3beccb6016d752fffd7cd635190ca3df8d62c231decbc7600c0be5d520470ce638f76d1fcd1306935b9ca507e60183313a3baac13678ffce170c756e5a5b298549d2f18279445fd2fc7cbce99d4b2573ed10a9b96096fdcd0db15dcb7f0b46096175fbc1ac05e356dcbfea9c6ceac259307da4e4f0a7df73238c05f346789c75627d458faf60d29d7ad78fad158cdeddf20f237aee8bab600639f5198edf436da582412f42d60a977f44d52998545c7f6246cfd4a85230a5f171145cdf51eb250ac6afb43d2be90205c36ee7309d81b8bf5c9e60ae693d8baf473b392798553d23b6f7cb5fd70453789cb3a452ae9c5b32818af4472ec19c2fa5989fea2f750c9560dccc7d2cc127493068aa7e8e8548308bb8b785c7c142fa8e60eafef865b9b2563288114cb993846efcafeb5e04a38497aa0f1193cb12c11441233b0eed7d1b6f0806b7b9eb8b7c9fb9108cf69bb9e127a1831f0473a7c9d925f5e488a70040309a7e0a6f59554e56fb8541eb524bcc9fc48c7d61fe49e720e46fffa1d50bb3443893f4695e183a6dde85d9272f1dc47ce059d1851975920f09b9917c47b93074793d984871ddca172c0c6e0704c085d1abff1e5efc6f61f6748d1da5a8976b7e5b9872f28c480e91ac77af05492ea6ae45da69619471c7368d33de8ff82ccca5222ea11d4e1fe7c8c238f12ff28f3cc85939b130cc64e81844c98185c1c31a85ae38194b9d571843acddcdfa3f87bc2b0cab9197e3e41879f66e853956e6a343553892342b4c32fe293f63bdf1be0a635e7665e491d4c9556190b1e8581b87536148fd9cb1b1934b928c8a5ca2566d720a73579830fbf9e64a5318f633c6fdd1eedef196c2e85052aeb0eb125d521876eeb43be318c9ca5198c6e2fc416d4c38504561080d2fd487e87c4e28cc96a912112dcb970714a6baca2d9978589efe84e953dccea7638fea8a27cc79e219b754affbdd0993a514353ae4f1ac4b72c20cfa63bcf549aba33761daf9c61d5b3ce5859a306d668b7fc8312d6f98098396dc9ba5799cf7c184217574f7240f6adabd8419a6ff4aadf9f75b2c618c9a14ae3a924a181ac589f9b841286198e065b9365ba2e593309875ccf55b12865c927148952f12c6b3898daba555c2789030e420a9fea2e41e61061f7c3e58b0988ee20853d85699e49f1a49b34698dbe5d4662a54cfcf08530e529d9f23fa4faf4598231d955d63eb93b8228cf5f218ea3412618aecbe0e268b8676b482240684a0023c2000220c8e53d68fa9f51d81008730469e79b12c29bc7e5c8bc04000431cbf46a2a56c54276d20085008f34ba83c59a2b27d5647a9820084783c4462c4c43c7ef42088bae3a1c26a6ff54510f69c46ca87eecfc70a9252506a0f040884b9a35fc683fc6b231e4018a75b32fac7b50fc2e50fe62c96ba3a42fbdf4156903488007e30973f18c97d91f3394320401f4cad8ef16bbdca23fd9b40003e185d43eca1cf6be5990d01093080066e83188ca0010d8081bf80c90d76408310900d98200502c00301f660c6dee87e2eca4e62bb82a4149c1608a00753e6a4fa88afffe85108900763f5475f1d5d2f8f1e0fa60db58c2558145b99dcc110af6fa7755f3b984384fccff5d82b7cb80e268b8cea7262495785e8608e9ed1597b3cc67d3f0753459c9b207ea923a3e46069300a03049083f172f89c1ebb1fa758881c408038181c36bc74ef90aa0910000e26ad10527564984f0e4941051ad00002bcc11cdf29673f8c8c8ce31524d5c059402a6840031af00302b8c17469a24904ad48cff509046883a9a15d92b476d960fadaf724f143cc9d2328045883215423577dedec91b71a0c2ae218ce65e9dd504080349841721b4fa10e6210810634e0b80e2ed1e05ecee670cfbf2cbf82241710e00ca65fcbbd1d24228019b0ea14a7c3227e8ac1b181bbc005db81063460073a88c1a7e09c6d400358b03408c169054014042883966f262c5ed6abc90ab2010d78410c68f00d68800460c00215b080061c204f10800ca6141bb53f9edc296a40038a0830067cb2262a578747bb1870f0285d4ec3803b30b1cbfbff9e0403af923db979bee4be808e8709496e4208034ede80012f60c10a6ad0007701af0d70c000ce1b30605c0d08e08557c33b496ef08262831b68000614f00001ba50ce3013ebca29c9325211d5304b312e25bd5db07d30a04011800b668c937e8bd8630549640b04d88221bcfe2bb936beff4f0cba06a4063190c1068a6c032648010808a005a383b88aad974188e7c982293bbb62781e3b099f14088005e387be8e5fad9d974208700553706c6715adae20e99415ccba697a711a03c7c05c09100254c1e839c5bead6c895c710250c1fc29b62633a2bd27dd04049882513e486587624ac11cb93c69d8fce4c9d20d08100543348b7d67f1ebf17b37c01210000ae6fa9c2dff5d4d9eec4f3097cbdbc734b73c6e911410c009478662c1c243323323aad66c1d665f037743500119d48092004d303cf858f13544cbbbc304435ac465281fd33ded7646327d2e4d22400025981fcd5af48ec5ee8cf1000224c1dcf6ed8d63a7ece86824183a77e8b4dcf93fe51ec114d24c6ca5b7b6fc680453083a295d575ad68b45503c7d3a22987ce6373d8c4e7e670886fdb4962096de7ca40a104008c65dbbd41644a31a864130669735862f0f5f3b45002098fcda3a23a5b4d5bf30d7d99e7fed4ca5b82f8c5f16af9dfe6b2cdd0b636e38be14f6365fe585a962c8fb8a97bd85bb309c45c7133ec7db8fe8c210e3b18eadb930557ccfbef21e17669473b8a485fe16665429a5f3f030563bb6307b90f49effb1bf836b61ca18a75c07939d724a0b43b4bd91bc0fb1149c85494ac5bdec3e3325b2305638aa90133d1e5f2cccde511a86440e0b633c6875e0f05718ce1d58766d8b49c35d619e8c90957676a13ddf0ac325bd9c996a8f31feb0c2944d52eeef0f12f39e55984c2457ee8410721c8f2a8cda8eeb1d44a66c785261d4911091bf424e750715e6c7f9ede748b3f1744e61fc08958f7ea643d8db14a6065211afb397c26ca76395d1d4689e4d0ac3679cf3ea7ee558668fc29ce63c5285e4da48b6284c3712c2e46a7cf9c80e85e1a3ba1f4fd5ed4f1a14a6ca8cbb99496182a43f619edcd032b6762c1b694f986f2754cf55d599df0943ce719751a7efde0f73c2ecc8efb37dd6c17a7813868bfa7e36296da5963561088dd16464933361c858c26560bb396932260cf1730e9d22126b227c09c35834aaf4907c428a2d610a17f6b42e663f565c09b3bdfba4a824318f9812e69fb3fd5991b868f024cc515e95b195b1b7be1e49fc10e6f3d56ff9faac1f3d8630967f64700da5c3a985a02c43f78627f3394210be4caf23e5c9741066d3eab309fdca218230543c780caa715c6a74208cf71f725df21910944fa354ae1e76237f304b0821dee998e5e57e30cdcceb8d87e0e0d307a356dc47b62ea39b321f8c6db11c7e3657cf760fe6897428da13a3ddad1e4cd32b2b71745f2fac7930c555e5da477b469be2e1c6a042bab4e1a8b27107431eb324f31adf73297630ade78fa349e13abf1a6238401d5095ac0d655ba24d0763dbe3f449f9df56953918552cc5f7ab143250530e4c5c928e162b9e38182b4feed686e56865c2a146491f8a45db49ae208946180ef006938c571c6de91ceba21bcc1887fb5d4d8f9f2c69c3ef9ead753c4f54d860f6bb64b1df3cfb37c81a8cfdd959afca27633e35f01627397ebae86ba461147325dee3d0a1c1947fd2735547eef2cf6054d70a3231713318bb415bc9c4d55d489581d5e9db47ddfd1baf200969600319f0e00064307b4adf5c46765eee188c33d3a76e41bc5f138349a52e7f4e2e699141612898a77851d2bf78e3c1904855c3896421fd8251ac24a47ee9054348921c557434b95f72802e1862be6195ad4c8c6a70c1142f5aaac670291c600bb6e3ec4a61f3bd168adc25251d26bd16c9c2f071b8496942e2818566e2872df94bfd197705a35f6fa38c72c7bde85ac16cff187cd66547322955b0ad2cd742e7fa97a8a088379824e9b35f53d872bbd42363dc7dba140cf12578dcf95bb03638281c200aa4aa8c4d82ff5e83a1a0c5afada89b4a97f2278c523f5db7f969e4ad86fe9dd7fab2be4d783ea4ad745339e41c8009a6e0288ada6479f0f05fc2f1ef2045e790d47628e1e4e9cdb3d844679360ee9db4615ea51e4b47028eff62eea6a8a49e47b0363e8aa78e44ce08af6789973571a10314c12067561321ba5ba5fb0044289cbf25b1eac6c8fa21d439d78710cf412442184faf798ec67bbc1784da71f898f8bfeb197f0020943da5fc1eea2af78b2b9bbe6f5975aaee7c6148c92da2db799bc4db8b3e4b4ee5387ed7c68b62d756ca33d740ebdd45e7571d923fbe8f82ba481e34869dcb8595d21c95a5608ec7055641622ac5254b836f716c758cb2e655a8b660f734e651c6f239856aa124178facbfd738b4304de742545f3b3e6316797e5d5fcadc364f165dcea8815b9474dd1a0bae42168f56919ef2b078ede26a1fc4ec5e31cadb713c67e407ba62e9ee9ee0eb51713dad2059639897b4d33b4d58f1f7e4776c5f76045761ce919eee8f43483a892a88d10f8970a1329053917968cf20ac45560fa2c2a91f954e6db51eca5318f284109b91d2b4774ca1348aa6b38e32ab52181c39ca39dd871439c828fd3e7c0e3ed151585ef2a1cad2279d4461cea132d668c6819b5b8128182014c6c919954b1ea2a70e0a834ae98e7c4ccf9e439fd8c124070f2a82ccb99e38bea70b8d45b4f64e18a45fdd752c27e43b9e60004eb497ae425073ad47eb26ca1fefb7cbe6acd304a2a7d5e7c8842185facf5956ec4e764c186592edc4079af70ebf8451c42eb767d496304c4acaabc378fd70254c161ffd747c90912053c29c1cf6e978b08e8aee240cdaa981c56c5937874ac2b0924e3e4f4689049e356374bc41d6b12161c829788f4a368bf32a05e905033ce21c7ef13be4b73fe488457bbced2dd7db082394e5c3c7a0d1ca88e2a3c66e5ad27b2ec2a052951cc8564a5751447f2b591dfea5d4de27c2f4ebb7597e1e440cc2b8ac84f4be790e6176fd97eebce15da621cc8ea41a4978a71066f95453a1f2c7cfa943083a2b2f48ca6dbc0da28e9c0ed5a1e5b2ba20fcd3cc7b903ebb1508e3c788141a7c0c08634e8e9c54dbebbbef1f9493ca22df9e2cc50f76b8df4c59484615efc33dbafb71563d72ca873bf3a25d5c72bdec1e4c1b7165d7fef13a8aeac19194e00d1f8eecb97940a5c5dcd4ef623d878741766d8716c92f4dce1d0a4982fb6e353c0b713b18c3735c99dc2aabbe0ea62cfed93e5ec6f5391db27c19e438fbd28ede39e4a937773737ff9783b173f0bc61596d72ca3898711eb3bffacf1febc1c16a2413ff401d7fde50486be319bd6e30a8850f2d19f12ca9b5e1c7da216ed9e59b0d26a99c2cd954ad93576b30e518d33e11cb991e3550fb7b227feab9224f8379a71aa3b2600034982786e78b1d34e5527f06737a0c3dca7a96cf8f37c3d054c6310ec9df3298c187d8af2269fb2b4e06d3458be9b00fe1ffee3118238bcf58c68be1cbe89bf084c11c7f735af2e41f59c0f0a4f353f5f20b65bdb3dd19d1a8bd60ba183953742423a4b60ba60e6fabf095e3c2285acaf6e12d181a6455e44b650e2ea505d2af5eb677d4b964c16c5b6ad31fa34b44c282a1d5442ae3b993d7320506b8825992a42393d0db50b78262eadf393e6891dbab600e26a9636d6db27ec60a9252b0031ad8800af785b43d139a82b1f55dcc75f42f348e14465a0e631bc3fa8b76144cdeef56eb6d211d83a1700e19e9c53dd2b49f6094f91ce751ce39e18a90e76c2e477ffd4d307985643aeadf1d0f638297a63b5cb2822418b0e0532083a51a24837d81d120063658d58101966012e98fd0198baaa4d0201dd840062f3030e0000324c0000930c06fe0821d010324c0801d3806565083b5000324c000068420030c90c15291c1bec08801946092af757496f62f65d38c0d900453aef4d1b7a53ccfcd152419005661002418643d48f63dc93140020c90000324c0001a688001126000034290810634a0010d6085018e608e7df8d937792f59358011cc78723807df5f5e25af200f0246570628021f1d54a52bafd669600310d0c05db06d002298a3db6b441a3137ef94160c300473925e499d9fbe87fb160c2004e39c554af9dbd2874483608894968cac35ebe1c0820180605e0f2139a6566ad0458202fcc214ca73a3f0b8e85fc90a9290c8060ae00b73ce203356bf62bb1dd80b53a7cba0cc66f45c6a2714801786959812a6c361b50b6305f11cd153c838a63328802e0c5142863b66154b7eb61614201766f3f3bd3c8df49fd32b485a41c74006be8202e0c2105cdac14b5a465ee70a926490028b42016e61aa9cfad2877c27f3fa0a9286190a80130a600b8347713c293c3994edc0200647030b380c38d08006902c0a508ba2a39021555661c941e48a9d759797e6133f2b481ab430e4e9180dbd10034250810303d38006008014059885e9ca1ae407e5cac2281fee725245ff1f5c44140b7383f058bb301e62a70d64c0026fff8004740c0580851987a34e212532ea9c6101068420030c1043015e61f29cf2fc08731b512d802b4c77e3df5be1b01a550ad00aa3a7b9787f7275b39102b0c20cae52bcbb5c56905483183c049c9750805598e2bcf5a48e7dfff0b32e50005518c3d61a05bb759cf35d4112394f142015e66029e460fb2b17695b4192d50858200308f03a2f0f3f14001586a924d5972b3d7f031ae00d8318c0c0060d68400d1ad000093040023b7818a88005201881061ad0000930a0ec06388208c4e053e082f643031f034844014e614a7b9f9f1ae3ea0905308551b2f3995aceb5725f290c11d9f6fe73496cbca430a4e31033b9d3280c9ed3b6ef3afe5d7888c22833735f11a19dd7344201426148491a49ce11bfc76e28140014c6778c36eaee234c265328c027cc59c7d27f44ce1f245f4152f6a0009e304f96e04025fcb25f7605494e0319940e0ad009330ee1c349c706d971423841febcd9936c58f70a92720405d8842147d8444c6ba4200555301041031a50004d1824ec27c75521be2c54804c187ccf723d90d2c619b482a4183c0c58a082241b78054a110a8009935545e7f078bfd2f397307ed01ad7a990cfd4b784e9d6a3c465985dac7c254c0fda7214efe8f68fa784d1772c6ae8445e89fa244c296d35f248ae23a64bc270296d5d42cb62871e096343d5cbfe97cec973481c92ff5aa9781e112a802424800fa413b00773946832312f5ec40af560f628165dfdea2c03290179309bf64843877139b58c07f3bc456964bf0d3f7c77308eef8d59fdd967745121017630accf5f6fba5af413af90803a981bb5564bf2d0c170717dedea2dfff736076366cd45dacb3edeb91c0c3da29b922d458ff08983e1372c1d46aa3cd91238984f625b5a7f74a8f45148c01bcc1865c718e3fd8a8e221b780d6a30680b097083c91e47ab9c43420d24a00d667bc9efca11b9c4ad1524917902d860facff1e372a3cbf1dc3598835cb66790e17755c80a926cc08217b0c005b909508331e2fc43242d57a6bc831aac551a4c691aa1722ccfc61eb7e3c07c900034987de5513c587d073dde064c90020e24e00c265d2bc995380cd6062c6084800d5810810634c0062ce00d9820051d4880198c1d0eb561e7cb6e562b48721eb0c0062c80c1d6a00ca6f151cf895b165beb0a9252b00317c840065be84a90003298e2a4ab9ef6b76c213830d21324600c86b89ca8725c5ffd6831985bbce1e448179b74e321016130cfcd84bf7790bdd31d020283d9f53d83947aa1813e3e015f3097bec3bf92d50a61424102bc6068107d2cfa6fdac1ba82a461840474e19c4a7699fb78ae5b41520e96062970ff149021015c3079d6daf0e0a22ba5c0ca0209d88239c9a590ae6a1bda578783024302b460b628c16b5692e8a9e9850464c15cff212a5dc638c4bc3b406a0f09c08269fa25f34aca2b983cafea56c3a3bebe3924c00ae6928eb69b0a6a123b5530e94a048d0b96a482517a6f3ac752e475255330ebac3e8e5e69f52f1d1c12200573f48a480f6ef352582f0151305a75c8d0f4318a52900028982be579cbd1e14f30b59a4c6984ade038ed843f2c775b37301b0b69600319f420014d307d84b9a87cb9723a478943029860ec8f5efd8f0db3d1684b309f954a774e58daf2dd9000259851fc90b0549e336126c110d1dfd27a0cebaec90726608135240009e671d41949638c3424e0082689aab10d3bee5888450d09308221d64ec655e1423424a0088608b992fbb5554a1d13c1dc219ae433717970e12118f55ec527f2830e9b9e19122004d3c57674d1dd967b520e8c21014130639cfb3de3ad6d7c27b1210140304defa38f9ca3c3a58c2f20e017e68e5d8e333a3d091f5790d48006b4e320041960c00e681002a3761c10a92f0c77622a8fa203ffcff7c21c433b4549d9f3c2942d57faa9cf29a8f4bb3065a5bbd020ab57f8e8c2e4f9ba758e920b73ee5648907aad0ce2b830e4d63e73fcddc2a4d928f3d1bcd7576e0b837607b3d3add3caa985212adab6e24d0bb38446ff8d1ba5ac55c91910300be3bdc553bdf49185e937a342a2fee3994f2c0c391bc4978ca4d3ed8185f9ab3b05edca7985d9e5a23eb0e8b74e5d616af0797774247fec5a618888fa603aa39bd45861b617558d1cb2c15cab3084e49692c36ed0dd685598c54d24e8e43d943f158614362e675cfd60755498c48245ec0cc7b167a7303fdc9caf643615265314213bed5cc8e05218e493e5ecf493c2d4c0a35e847f4761c65221b8bae4c8a05e5118462a392e472a16f386c2d87fd9a2cab3fd5f1614c6cb93fc84396517ddc70ee473e20973a66d8460e39522a413064b5ae559328828dd72c234118ee28f397c94b19b30834bed592a57ac64551386898cce0fa962d267c228a99e54e4d3aa6c4c18ede62704e9cdbcf0250c9e82de390a8991a296305d87e4f7dfaf7c965209934e4a8f73a30b25ccc0cb77f5d2586b9e933063cba9d69e5212c6cfb6f0b12ab7f73212a6c893b7a2786c18718484a9d7d2a274e8ccfae023cc57de395c7f0e963ae80833aefcda92e5d0638a8d3085f0174f613ba5136484218f7f449dd391f17011c6ce71ddf1ce3fc7a1220ca7fdd1a9e367f90d1361588b101a574c29cb134418cca2ce3c66e7c99e1cc2f83956e70adb10e64f6321c2e43cad7321cc5ddb595daa5159268430845422194467ef996410e6be498f099d5d5b24823048a36d9cd23bd281241086d46c997b8feffc08204cf963a5c5d0889c0ef20773e5e8f9a711bbfbfbc13c59dc7374148d71be0fc6fbcba858a936463f3e18acd24bd72da5f8fcf660b8fccd4923973fa44f0f86e9797d6c7a9164be3c98a3ee41a74e9d4dc2c38339575a474dcff2cadd1dccd1f05383c919e556cd0ea6c828957a86a7944eab83e9342292fa7779b68c0e86ff776dd47f9a91d71c0c153caee7cf64945a723845b4c7d21312075394fc5b47fa695e8383d12dc457caf13baa566f30adb57894746aa38c7283e92a8c8479bdc4f5db60b238898d68d9cc3e3698c3a79ebad7680d866f8bac16cf1e32911a8c1e3a0daa34182f6c866499d6c61634985348ab9fbb7b1f79673045c48b8bd56217323398b72d4a7cae71e80a0494c110b2c75dcac8d3f2545320800c861819578c9b47c44a29103006c34b3ada6d954be921314080188cb532dfd2285520200c8614641fc897dae7ddc160ced99c98b895bbba7ec1a86e21bf2cd9bee5d10ba69334e1547feb41b420a00bc6fdd0f750f52d4b084100170cffa1ab3d54454d3a37c00009d800044e83184800015b30648f3adbb1aa97e868c124413f654f777b336a16cc495566dd63e3f89760c168e9310a92ca43c0154cfd75eaa8c7bb53dccf3a0d944000015630cb686535f9602149af82b9e3f566b278a58a53c19053bae4e29e77000c089882713d7a4aa7b5121fbf523047fc95d4be12ec721a05935ffa489a34718e52a060c838d4c42f74c593c7f8000324c080e101067420030c70810c5ec08214b80b6470031ba400c90b087882c93f560676592a55bcba800027982bb79fc78a907168e0c7200634e840031a408317bc200532a84122a009a60c87765e951afed91524612310c004a3eb84f6efea7093ee14d4c04f0c605037e0c00a6ab02bc880b3800621c8403b0d2a47818025500310a004d39fa47d05492980410c88d011084882f1d5b5ce4a2e4f5cb482a46440082a70011870a0010da8410b62108315181602014840c0114cdda37f72edad918e4a03028c604aa65a6ef1f416d0200639288259525013b3991c8d010144303f48fdfdf921040cc1fb067525777b0b62108315a4c00587055584408010cc2727eab971f56410322020086633fff94b639e11342c0302806094f31cfbcfb15eee06030e4860053660010920c000093080011260000324c000064880012060400832c0801b447e61c8db2167ffd10ed2a52f0c92b916d3b0b61e5507e885a13d845c93ede2f4745e18c2477bd949ef96e72e4c939af91dba1577b12e8c2d252712f3d9729ee4c254eb392eccff21bd85ae6415e73bc02d8c63f9d304eb3789ebae2049ab70005b28ba93bb2fe58adfb5307a12b7d78be3b87b9bc2016861ee8be968a7b37b247f168648bb901fd22e0b2ad6d2681b0bd37712f9fcc8d724d5b0305a187764f9234a96fb0a53c87d8c1d489ca5495d619c4a0e5afe3edadc5698d24895ee5e921566cbedad22d9adc2106e62c45ab479f1c70a5215869810263df74bd8cfa7c278f11979cc93c7e71f54186b92a73da88ebfd43985b973a6f765e74d4a1d5398f365742fc75d0aa37b0c7520a91dbbd9a430696c3a2a0f2e9d7e1d85297efdf927159368a9288c1e972b48834a28ccfddddbb8e1ded60714c6bda8dbecd05179929f3078527f189d2557f89e18ae5de8e420219d583672be2c51e4843be9bf22dd8421ad2bb5758e922be534611075cf403adca794970973d7573b06d1aef3c530614ee1a1adef3336bbeb12a6b0f34022ad650993e388a974de21afac4a9841565edd8a73b1aca284b127ca51c74fd6185493303b0ad239c44927d7491286defb495524cc95637f83f01c1a0c09d396c76f71afb028e911864eaada79792c65768439f5efa4fbc8b8f3d408b3a5d889faa713428311a6fadeecaddcf0ef7f115ca7b71c37df2269400390080e075004729d5d62bf62123b8930f73bd4d69e499f538f08435d843febdcd6059730e4640ff9b2254c8d326abc1271f6522a619a127fec5adff1154a1872747fa6caa4aa3209b344fcd94b3179a948c21c2e27efb8d1f82b190953aa8c72fe0aa171242161c6af16a562ee8c898f30c5dbd8ea5e879c42471882ab3f8a32698439b6743b86aa7de131c2f0e9a139d2bae8d02dc2e47f95d1f5cd5ead08633ac89e114d84e13cc4c96a25efa521c2ec12546b5d3b8439079551b392eba90ce17cb80cc25f0833f0ba10e6a867744298c4aa246689db58681086efcbe14e4241985ae6d3b4e718611f1808438e8cbf550702c218179722b687faf6ff6086298d4fc28412dbfd6070ec51ab410a29b7de07933a5249099d0f6690f7d431063f613c7b306dadbee77390726f3d98322e6c664887ac771e4c73d96aeb49cb77c683513ff7350e3d5651be83213fc65253723215dbc118f972238f708e515c07b3d8942309b16e194c0743eaded6c9d3ce78e76094aad0a235194865e560b4c9d1b137360e061f8df686161d54858349552a7c46f99125f50de69736ffffd16b98bac1a00d426d6b461aa66d30bfff4b598c07e21736987327358f9b90d89735985cd3c2a5f0dcb152d4609c8c499d3d2d42b0a4c1a41971737f52c44fa2c1d466276e2138c6769ec1d4d93ea78cbe7c759ac15039b5d393f5c52fcb5074644b295f4906f3c50e0f17a1a1f73806e3dc65b750a933ec89188c1549c28e657db891309872d7a6e7778454c1604e5267e19b3a9e7ec1249f62794e7954b6f382d145ecbdee8251577e3b7ab24a765c308639d6b2ff88796dc1148f42c628a405a3594e59af615930ebabb687d90916cca0d723aa55c415895cc114d53e9b85f14615112b98572a875bce7e2519a40a062ff59b0915cc713cf75218cd6c0c3205e37fd07fe85e96752918ffe1875bd1cb157d14cc9db32ac9f145c50e05c3afc965eb1025749e60d4926958b5134c22b9dc2d7c9a6094c995ad7d33c1d49b79532125bbcb124c162988ece5ae7cac047368d6abbe051d0727c1a413222496e7cc8f0493e34871943f827127d24ddf76878e110c1feec245ca16c1e8297f12f128118c0dbb1bc565014330dfbca97d6789e0960508c1701f34373fdf985a16100453f0546625faf1c2b900201846c7a30395cdb8e42f4c793d39f09026560efac2e45172aaa0622fcca13f5dd97734db9017e6cc6d155b51db89ecc2949523f161f338447461e8ae1017cc8529784d050fd1f51e5c1822b5a578f4ca856f6130b11eb320afbe9e2d4c6b169d9bd7c2e8e3a0de3f460b63a84cf9d8360b43c79e779c43a4e4992ccc511ac70829e3e38985f9dd9264576cfa0d0be35e5fc658e2a8ddf40a439a947ca942ae303fd4f7a46321de48ad3088674d945769c9b2c2f47eda96ea2acc934c2f245263bc8d538519adc8787e7ca930540a9151ebc64ee751617c7cd136b25398c7f6472f66a2546f0a9334fc90f17cea4a97c230ff1d331da4304fbcdcc7d04761e82025bed11185197e84328792b34c1e0a934c6bbd5b5b8e7883c2188efb71e6fd0963f74c4de5e839a3b4270cba0d5cb6ec2b3bba13c6ecbc15fa27ce3bcc09b35caacbbfcd7ebe9b30839a64961d74e5753561ba18e2e9153ff7b2993044abec66197698473161860d1aa4cae5a55f2e61f6f0f03ad7c51226bbaf9c6f2476cd5209b3a34eed78d9331da484d16f22e29493307b32bb47d171f2a1248cfd12d342484f9e23611cf9b1f5742b5242c2e4482fc44a1e618cf5e821c3d26e8d98021c61ce13d2b89d8bd8444c01658fb5095e21620a60c49f41ec7010ba4598752c5c485b11e69bbc6967c9c65d4b8429e7753017ded129438429be8448163292903f84c93f44b6ffeae8784318c244b45e9ab6f10a61ee9caebfb532429843be88d721fa8746d920cc392d4d444710a68f5607e9fceddf4018bc42a38c62bd68840061cab063a4e4102cd27f3063db37c933dd670df38339e47ca7e396da751fcc38279d5c89388f9e0f8674313f9defc19095723d18d2a3dcffed20789e0753e8e9758d1c3c9845628ea7eddcc17815ccfd439cc61f3b18efc7a452bcc87dd7c11cab2a72a84acada743069a4ac06b1c347da7330c8e4a852a932b249cbc11c1fdc8b6e778fd47130d884f49165c2f2633898e274dea7b30a91f70d663191d01a6929a4d50d6690652655febc16d63698f751ead8e0db3ea96c307ece778e4fd760ca6b1de63188f97f5183393f3ef2ef68469f067350b390fb2dd172120d46472edb95d16730b67547f0b6b3f6d10ce6bc171da98b65307a6cc7abc617134132982552fc4848b89043c6605cb34ac15266058d88c19c7a921be747913b1706939e854a29447a990f0c860e8e7d32f0862ede17cc6a5ebfdf25393dce0ba69447252d6ed50573ecd19bdad9d7dc8a0ba64fe7a525e72885565b306d58063b2e133967a50593e5106c2c9b390e5965c1d8b223f3293ff44815168cd1355b39ee2b985e2d7b8e5fea37a9ac6054079572889ce2034755c1fc1e2fa37af76419a3a8606efc30d351c67b979f82a125db7b10998cdca5604629a2faebffe7f32898b45278a40e52c27aa0609a0821d3249a95759e60724b4fe943630fd2718251dc1c4a3f4cabb89b606a282622eb19e6a599608a20692b6b99494a2fc154daa11b445909a60acf21d597a50f71128ce136973b9dddbb8b04439609be1ec1101e66523db4faac463045cec152e8b7ba9c16c1343afa1a3d11cc915274fe7031a196211825d885ed76b5d44230c5d4914e5f3339190463a472dc1b21fa47140004839f383899ca59bcfc8529bf4ef4b7a02f0cd2359f7bc45e98371f79a989fc4ac80b536af50349a99a38d985792ed8e6a5e3ae90e8c2d4fb686d7fde76be5c18cf51e5f8b91d6fe570616c64db0f4294ca92bb85a923fe4fe5982d0c49fb6cdee2c3eaab16a668d8b967bca1d4450b53636ccdc2ec0fe3645c259a2f0ba3fa5a701cd5f29d5818928458687d20f9c2c2389626921d4409788569afbe533a69899c1f097085e93fcf8590f8931d3f12d00aa3f75eb213af2cff19096005b962deab304d6e75b47d6b445b15a6c965ed91bc92073b15869056263af6176f1915869071bf7bc8a730e5a892162cd64a8a4d61eeb0f0ef713e470697c2fca1b6515e5897baa430b68597ee4721bfb2a33035f6468e234f3faba23064774ac6b962594e4361967f60b99a9d525a40610a91a1cfebf909439ebda9740ee2bcf484d12b4908a5e3f9b2d80973a8f5e9f83cec2872c268a1536d7cb896876cc2ec3ed697454d183a5abe8c1f4c86db65c29011f24df98a09535e744b572e6186958199a5bc36cf1286341d75c23ac8cb2a6108693e1a78a789a82861ac4fd9bbfb6f9d69128694e63d5db5f9684918a5c36765d70e138d8459a662eb3a1ebe080943909249ff38ab446324e011c692afb20cce778431f294e5f851234a5e8d30553cc6ff25d9d3c703070960c4feb8c16d768ed3007511a690423acb78bdaa244f80220c26dbc81a5df8e94f4984d12dd794a4f55b9e8c12901424001186addbf9f23891d3d84318d2d4ea785ccf9d8636b041d9010d4240820418c21ccdd5752bf9e5aee80a924450086a000c12408816246010647c9dc28390410881a0010de840068a68600319e82101823079e898103957ee309f4098b5e2acc13d3ef10fbea0d8e0061a70810c5ec00292840400c28caeebdb5b24ab4a16fcc198e97ff7a7e60dfc60980cc72242b0bf08199790803e98ef622603cfad3b69f5c3021cf835a00112300d6840031a2001067480011260c00718208106342089eaa8b4ebe62262b148201087c3c150481486eb5701531508201834208f469218854365de01140003542c22362828101a160c0e1410081c0a0a03c280d0401c0682016120180804855c21226808b42700287841f6c3b01d0bcc63764bcdc8fe11e6ddc7250a8c79786bcab1db7b1e4c57ed62b3fab18b467c476e3acb4d080967724a37f50f9fefd9c7901577e50962849fa8d5e620264a442a7e2b0cb8d0b95739d809af7f81656c87c5f1a5a3db3007b7d3800c3cdf2a975db20da73bed259fabc6fa3bd9de6a533ba21f81fa0ed2611afef27c27569e00c2ee378323d0a29b8e24f2eee4f772d731042f5c3b71a2598bfbe31d24b77e022a6002e49a327666052ca21066f54653dcbe10d9aae9d884940f7b172d0b38426f5bc07e04222424c082884647ee01110b8ff5460a8021009de53cdda3d323696c6a4d4b10ba079f37f3e22a869a1001a6db76d07305284335991a464303555fc6502942b1daa5742d6bb51bb2859a617b2bec8a8488e6e85749e81e0a7ba50bc21d1d29ae540681d58a28ea2c6065b5b316bb7474f2d3c6c358110c452e5628ce16b5a649ad64bd652d9b9b385d50c67adec96e62efae17652154552b4e0624003337ad7d24907737eeadf88884b03e62f057cdacb85a55fd5fafa797044d3083dadb55980d1e083aae47e8bd5cf1ac2ce1080f6b1b4e0138b9018763aaef5ae7510d402ba07a1704a615eebbea7d0bd9bd8f379232bb9acbce79f1e318c0186bd80bda1d2dbf34ddca44d87fbbbeb700247194d53a6a33257b22832d6bd7126d36775271ba14f2988a43646281356a5c7044f8bc7cf41860008773da456f7c1d0b4c630e4bc1d2a520887ab305aba074fdb92d49ec0e6ba246a3f8f262dba52ae69f1eaa6601641aff91f2e44a2df72cd6e16e37cb395d78869f8e9f8c1535ce637ae81e054f6cb75913ade2e8c54708d4e8f2133798d163f41861aa134794ee4592ce1063d803da7a18a2570d33bfc130b658c50ee6804623ac2878c50526b6d74273fd89f434faaf98175051fa6301b55eb33661297589eefb2644400c9241a0fc9dd6c0a81aaf2542d28ef01b0f759324a59267a7c973fc9dc2e50763373ca60df23b22b0845654ac899a92782d30a0cf506228dcc615378eba1f73068d23ef22eab8352e83bca252fdaf9163d4a50ba257ade72d1bcd81636700d515b91be9c4ee6e461b5820b0fa824d362bdade87a12def168add8e643945019b61ad5d3eaaa3fd3d0738a4c52882eaf3724299d305789b87ddbc1ae6dc7c5d00328473ecccab033e2844f0c9e708d60a8e76c6c6d1f8a9941ed0b4406c8dc190459a016016296bb4652345550ee2ae28b346162a4302d8b34605e2711090c61dab0b6ecc121504c65eba63d4833cb43bc4f661acae9f2c0ea0cfbf84a42da283423b7208fb1fdb7111f03efac1e256a1026db353e5e5c32a5d4e064ecf238e93f1b0a9a54bf10b66811a4c7181a57d587fc99bcda26919e949ee4d14e74309e1303aa549184b701974e0f421a74bbe74754e80fe37884531a48170e077b15e93db17ca3756410049bc896bd4087729a5555023aec7410977930c0704a90076cc99351702d506526931b16ad053834da840c8c6afdd030078360850528186a397b8261dbd40a8ca9903fbd512d5c7422c642e44c45969c82d9f39731501c0a428084025c54d062224cfbb5b8d038b42c77ba206a997e54d94547ed8b08fcfc424b5acae54e142eb5c5d61234e1ba8197ff46afa0d72752a23c52225a02088ca27533a2ea06d100a4c984fc79a4fbcee002a066b256b096af74fe41e4dae758f7f3373d3368ea73711fde215ad83b447beed43a62977d18437f09443fff8e5becb68182962a57aef700a0e84720e2cbf29602d3bb8c2911574eb2c0f96754a702eeac47a56efdeca3d251f153e21e9773f1849fe13ed4f53a01e4b382c7abc7b32315b456a333c41d7278625ab83d958b4a24ffdd55dc8532bc403e9e1fa125edf934c4765cd33fcced471b783b7ec513939099be1f001007a3d82692d13f6056d17caeb510ab4db0ec9460357334114ac96c17d0d1269c27384a362726542b413f8c632cea233661d86557853239c7d032bf14a205dd902675f10a418c3ddb36fde84d60f85b9ab67234a6767c5767e562a42f9560fe068f069a654ef06f0fcd73f4d8212cc0d07a598cd0ca6e530bc57d648340a8145e5ec0721f5a7374d124b089cbc57c9e6ea1d08a31178d4b4cbfea1872f7554eae8aa07f9fe39dce8aeea727d2d97afdd4961be4074ccf9b87bd3c9b67ae3332a41da82001c8de85cc2864680ad531df6161e9e699a6028cd346e769b0165447e81f46f81206dafdd42635ca2c00182352ead06d28d4259e3244ac371088c0070d3369382b8e7d88965c662d07f0c029bd2885780cc941a840dc8971b74bdaf81c270667c60a28727dea1327b10257924a92d92f290e01207bf439c6502406b0ab95b1b144dc0a426b8066f37bd882494b90677e8b8681e459690259b2402aeaad41fec18eb6fc6f25e74234612bbbf2277257879d8371b15109338593cd0e0f7407da2af98c421948868403fde2890b565ea040b6c35005688cbe4b0d5f3297845a716a4d6e9fa2bf7c016e99de310c2624dfc864846c83e5ba14f158d5d79de49bcd530d072eeb836fa117582db540ce9d3a00eee805691b19299c10c5cf6ea3b57323cedc5ea54d769e3820532db77c496543e9e2af9c74fe21153568aa5296b226efa2ad5d3e1d6b5068b292965e725ca1bb45becbdf8ad7e8dbeb33e23ec795c6c47a57481b3c3d02cf26f8d7923e061e8123423e73e61db17821f305210d01b67c61e5ea56eb6102e62a2eaaedf2516ef3920511f05c24bf777b3411ef6e798d7d7eed0e5ad4b0062a87b780987ed79eed96dc7d8623e2393641ea5da692acf2705e654b46e74ddea5ff72e55bd695fdaade985e905e98dc3cbb94bd75bd55bea8d8ab72e8fc626f0f36efdd622ab69b177f90c60eb94ebbed6cdd1cdf2bb69728f60edba6639defbd9fb94774bf7421767b7ba37be37a05706af7ded9e5b0950c54797a0d9ddda2ad5b0907409bad8ba847535bac1757774bb74ef747d74d5e866b3ddee811429155d7b73780b75317509ea2aba8175b7773b7b6f79fd75d5e8b674cde9267579ea32d465eab6d46dea0665f7b503243dcdea9dccebd055b3abdd9bf978cfc5ce000ca1eeccdc5d9e34921a2598b237b6b767e2ad538315679499a046d3bc6b42ad9d98bce807710b3f01271842255314c461359397ccd3c6c32e005433aec874fe686238b151636bea4731b2474b32230ac296da19c1b326459a19977a256930e40568d10790053d88f529381a5d6c50738b0abd51f7f922d7b9bd44327b776744132967d951c8e1108a494724ca29f726ba43a2e0c36104fdd1f85a9e93a0c0ba9be235831517d3ae49e453f154b1dfc6205c3d7624ab8b908cc38fa1d19b91f7e23f1b7b3f28717ab606938ed9f6869c2cfd7591c81c8bc78724c802d2007c0cb3860f2b2302d388d190a4614ea94a70036a0c5de861c52e4178b27393982e3ecd639c49a523237280a0233f444347c0434303441366943899632aaa99335f86beaf9c9d99e347585092fa6b126231bcc70ca676e95201bf36416da94920baee4fb92fd34e443562a18505ed480abb3efe42bffb0a9ce9422d2e4696e449d7374d784e71bcc930a9e6e28bb14ef6807d80749026d7d3b2a17f9023c8103412a60d075181d06b298a56b2037dd71100ee36c6446439b2d84474ab5f4b3d3ac3f396f45e05aac51429e801aa30db8c4c5eea54a94d7b18a89a23ba6081f25328a9087ab8ae0609fc2a5078131ad6ed45ccedabbd6574b0f9b68bef3df2362f20453817c294f7711a7aa5ac0f847051e2b422fcee337536fe8c1663df9f54be3c75f6cd904e78ae3a9564e45eb1d9719d5ff95ab0e88e16312d9fa2d27c66f121537fcfa1950a1cd383781bac21da21006427f030181348ea64b7f7f4ce3a29daa70e70ebdf314da84a8d9573f4b902a7ca536b627f827d5caec45705c00bd801140e00f3159d5a337ff78b91008610c5877e6033b46873d44c3c49ed0641790e84c90969891555dba181ccd29cf97c16b0c628f59675640f2d4b35e85605940a2806fa0b820cb394b42135814c9606d62acec0191ccfd0fb7ca160c5026e815581ea1bd8824af15b1b02cf023304f4d1c08be4d358ff06064590f97640758ce0f8fd4d5d47dfa69029e6737f3d608d5dd20c268f92327e327ae8d1929a238024a027f04204e285ecfb05a3c09c0098003c01f81488e7fa9ccd0b01d4603d00b20046193fc62fae4c8575b0d404bc30a63427cd2cb2ee6b6298aa227a1c5a2b23652ac323bd8bddb40d95fb489231ed696b0702f611787934b0bea004ac587e2cb4b60f1f0acb4d8db91a486c031e319089f5eac8a106aca9ed71bb9fcc4d80371836f00c82cc7d0240d409580788175dff4f206cdc795e78354fb0e0a15687702a333720c75a632d8d5ab8e19f4b39a05695081c0a24b57b96347ba1cb7155803a27f234d8496ab6f598162fa97aae82d518af42ee663596163d8f4c06e05d14184d20aa5714b736e9b46a82009c804f2759baa27b0e0d171a78340b5e6827545100a50156e75fafb109d24c12c9472fd745303d1612836d437b02e7fa28e0294106aac0a3220551fbfc31cdbe569b5c2b34544d3401118cf72a2dbfacc4484f6e38936456b0ee7c889a9d862d4ff0582190236018188faf4094570d6c16714a128f98882b92e25fdafc23c88cf74afbe0cf1ba3d1fe18d6c896784e15273e77160450e3ffba6cf9fb84045f4412bb4d1c2a251ba2640408613f02f30ccf68ce69fad23a0bcf75d493f107a02361ed536c41b80c42fbc80621f364e771d5fbe763ac7516e91093a16e3368b065c766b01f9b6374adb6c7b7b9b649cf9355154c39d33ab9d2eda8d79bfafb46c5a264292501de00330370886d43510dfb1d99472ded6c3834eb7980d19e776bef8492fafdff3ebc1f36dcb03e864ecc44ac011deec3c090cf5178d982a2c870630a5af7e19873caf9035546e3b6df35d5d68c93bcdaa0f911d708c85de8ea88b2c5e1eee043641b8fdbd7e41791e7c8ef5eac38369a10bf798013274628953710b4352727e2b302103c341eeb5bb4db3306c052daff95e1c4fdbcd2111c7dfc2703155774aed5f9937b5d340d65a7aec9b62e3304324a5fba4a3b765b83e96a2cfaadd085e50d6c8e018d6e344a0c82867077aacb63230daaaf413c4d938b7aa19b6c76d4432dcea8d48fd19f99e64d472d80948d6dd1abe8efb8c4f72c8ede70ea744c6b88e39be4ecccbd34af49801ce567c06910d4d921404f02846d0dde9279d345945ee3c36060dfb433c21742212011a94c6503be0b23a55dad4ab7a37b393796aac78460442ba0fd96a33a1b6cd43ef39eb471eb35019257c292029bdebe9f1a0f8aef0b8d7b2404a8f1235c8d2fb24bcddbef1d63dd6b99dd30bbde78408c165e99277859e3f21a019aa1c4860a1b5d47d93447f335a1404bdc4533b7c1a7ea58cf4d0cb41f0cf9e256ef51cee665b9cae051ea0cb4b109b1df7b183b03539d97df0b25a2da2d1f2869b0efabeda0416d424875fdc288d7971cb2a4d1af41d9f3ef0eca361c9591a6abd4c60e1b5adcea0c3bc34bd2827a8a9ada428c000a2b0b71fa72c78ccf39a983c02e3a4641802e5cfee22de65157bbb46186c4dadd40187bfae38617e62df31f11f48bf5c7eb18371c8395965643c6eaa0eba40e39d94341e3f4c0987ce3d11a4c1cda08c9d61a9dda85993c4ab5a44849a19adc3522ea9f66a88d79db9aa4dea089712e03e641c85779f00b72b1b4794443243a496cc764b01c06938a7b2ec9a7904649896e3b06416c606f17ce2fcf0ab26679ebf9c502c5bcdf976fc78a45ce9c08669818cebe07f314be3ed78145b410f7542173465789327994d06798e7758d59fa38a2bb208e1dd321d98bda6b7111257a90e645ff50d26629e465c621aa8da2a8289ccaee0aa4a4097c47151e545102189f200aad1f269a5143da2cc12b71520fe2ae32d05889831560be84c603632be47f049f288e4c0f54daf3b72d57e49576b3f82d9e912ce1b7b5f824edf962fe8270855383df2b6f8c58b8e01cb3a385183219aac3c7e771ba3fc11174950f1dd09c70726e9086e2cc404fc43af88264b16e6b0a0d8b9d1ac037915abe80fc3673edf873227916fc02ebaa621c956e1d3a59f1abad86101566099c9134682223d537aa812b8eeb6dcb61deca71e3cd3697920f739a576b1b8b78888826fab4fa1ed48f995e91589bb153ce20f862ee3c2fce36271d2a614672e2ccae9739efb6ad8bcfd9f76c4576c2a6886ced4602d067abc9038b0e4295c30191e7027725536029295f7a2bace2ec287e1d3fa5b0ee082aa7a68be185cdbf24a04e421144772b777d5f37c18a6393016cad56c51d10780933fb8b73c5e13b5b8de768f0d96deba3f8d3deec81241192a786c7159477c9a80768d789f5d671b4e6f3f27ac2e6419448df8cb41e491365b621f35761f5a6123ba417b1f7cdf906187c2048ff75ae33fdd92009bf4c11e990603f2b4db30f51cec65faeb416729f00e190d46faa93085cedda2faed2e173a76cba0d7899d94f5ad1aa096c29d0ca02701cc68d426c6a8c40be28d902aa40c637ac859ca0d01c2fe426ff9b622ee9245592cd45fe2bb0389436b3675055062c79dd213bb71d06e2b57b303f5442866342989349b8c95bb26a08144ec628aee0db8c8aaaaf6b4c9dc3991c45fc67889675c1d3c8d0e7d50c77f14505d5360fb61f062a38e90d3aab5ad0f0a593e9dbaa7ada40ba8331ee8da8b7fcbd5a8c1f5e9cb51e96a7f3daa92b2cccac84ab4f4732020bc573ead62021fa73f86219f9227475711bab08c9b0c5967e10cb87d180eef90010d949a87589eb6aa7313220bd278137403338f8745c61da42aec64de35196e7f9fc796c5e93169f969f2e3d42d80ba01f38388dd357292b4e796ce073c4dfbe17f77b9dc2d78b774527a0faf5a0695e095d9892eaa5a8a8af9aab16354218d4e54a07509f809b5aabff96fc97ce1ca9f359b11077f5bf59d9f79b57614d9c3a09287066582d8ae95db69a04410b1344442e20a24f193f91efe28cb4f1b260e8fc947928e62ba5b7abac2127c2800358856c7dc91a2831c03ce542cc35864b3ded9a9fa12b6ad10c89c9b9cf286edf90891397a966612226e81cd19ca3895264d95cd921bf825bc4851308148974a20c2701d4d98213ce8cfbdf043a996b62c6beecabb85710f5e5bdd0a5ee3e491625f8a0e0dfa1ad416390a44df223c575448634195d68cb568eb7dd86822b1af542132e7ba763372e7d75889426bf69f9f0e2e25e793054113a11fa2092830c59d6ac276bf988a1bb9a5e9704cff65a042ce8f66a712a453cec007ed792cccf4bd3676ae881d027a216130eca1326eb368b33b56b539a05f9a445f5709d916092296869a80decd12bfcbb6c5b53e2dbc9607816516d78266b321ac979844008500d3805ee81c4c03b307430e4dcbf730c188fe27e707478297273d8500cb8c620e02c810d6cb4afe2014c0c870d620f8118638b1c2509fa930c6e2414993f8860679444efc190b032511a0227c1852012fc085612f002ce4c958c8227207148c963c36e1bbde1057d3c6c304f40eb373070212ced11099835168b12e1eb587a3c1f25460f6326181121b9939832320de7736406413fb650867d7e2f9d892643a1dfe1ec70af336f95a1a6bdce4a07e9d00e72ecdfb0fc78cb685e18742a2074d20e67e7d371d605f43f529d30679d8373be3995f3bc4136f4da3427ec591121a0bb9d3d85429fed618cadec0cc19d1fa8aa4823f57ca12008aac1a80102f6388b52905d6734b18ae81ee6a720f41c3d7fe72879608bee7e29c2d0eb70b46bc40e55fbfcf5b0b54d8051ebe9e3fb3309140de901dd6bf6c63623f40291816c58e416e87e02b6418ea29444171a8dda4cdb31f5c13d4e160c9d356a060d342d7eb3f2a94b6848352341422d5590e940928e6ca5e1c8e5b49530444427eca9fb4a00c64b9d3822a8ef04fa72fc28092f0142e675637ba6bee4e47fc821a91dc54b621db87e11bd141695907251d89e003204c72967020897437d2c487f94191d895816663207892f50f5c3c53069ff5583b82cc21fc877fc853142b002897777718c2c9a205b028d223fe2cd25b741321ec3312a688a651cd96bda10869846e372ee316602656142b4a27a2efa832c83748fe2c4acb634a371c1393146f56118773454f86261a3de881a1a029fbd213700921b347bfa0b2c3b27493844a2147b4428519cfde78a153870698bc9393581ea5c6c1cd234dcdfcf0712dabb8d784d700dd86439101778b4527f680586c35d502a7de44cfdb575a51dcdf4707720066aca2fb17f65f3082f69bf46c907b851498398c4aca980a205ab91fd023986a130ac00e0a975ae6c27506ae0aac428a954aacec2a00204069f5401fb28c7972783d69c658cd4ed003ee83edfcf1d74bd9c1001fea02380f4bb018a72ad4f094efe05d1b78209bd8c8eea88cd9f83a60d17ff41def2b8f8990a51f0a14756dc7a8a1f83ff4ec3624b2aa19604dcb0868cd765db24e644894812dd59294d1e42846d0fd0996ba8c4dfa24acd69997258866fdc108e7801d0bd06cf97af9237c185949fdfb347095f1e1fc5f7e13cfd60e3306568f5e034be7c988a627bb7b5a03a2a518b76ba0c1a93efaf28ffa18e197be41fcb8b515340bf952e03a15babc2e71f6081add9699a2180ab9a785285f12df2fe1e2f830e4f5f71d0b5d466cffbe5118bd9df1b99c8452b50942da03765d91b08de96b537ecc6b2d24861af7232bb696da9b8e0162d06a03edc743e8dea2089d329c4806b3f9143b3628fb887a07ce72847029a7940f683b59572284363afc1825aeefa546c7796f1ac6eab9e8a0d228e8cbc329381da2d233620aff87013ddd3f5fa1308e8501cdb6cb688702aa97276b8bffc7cb6b61326dc256b635835cdaad5f3a8408258229cbe53c07ed5c986e1c9824a444e891c635d8a402065517491648d7904332da6131a0136f8b5d423cfd9c7d777b9bbd548546b6e758d559b5ec5357528e2c10b5393e90d8f1e3ff142f4e4ad746e64a1fcea294816d42adaa5060d86101b479b66357c6408b5bca45dade32c506e9429dd0bc08c80bbb39d300c38f9f812fd4e3763f0f36914562be493185823ab9b0ad625b5091ea57411d5afcd13f783e130db6bf60486e6473ebf0e63654fd3083c54dafa1571f828e82513669f2ec7256cb41f956392e32ddc50e03dcddfce9ea13ce29285533a6f9b96a2530c2121da4036d785fdc56f868ca8bc78a520ce8f90664666edfdc0ce04288acb83ecf87347483a62f280fb67bb9237d609d61bb1fa9de7c2ea35b79aeaad7a47876c5dc2c6e9ab13db2b15765886d84d585103c3c954def2a77899d243c87a8211e439b36c36821a26110878f19bb03b043e56f00649bd6d451b26b862d751feaa89be512fe7f5718f7180b8da6d366eccc8838a028aec9051894469aa3e5447b4c956c24dba949865ceaff2c6bb8819bcff44960a0a58efdbe79dbc7655aff57bc5ae5856813228d1d5625064b72145407025dec3c7f0313c860ce3616c88c7d18d1fdf6af93d648c9ee133e40c1f63c7f8889ea747fa003dc63a18bbe19728de5a580957402ab81256429410a5fd0407037cab022e0945d30c2e30f44c07c0300cc3300cda01482723ea275a262953bd917049fbe029a594649229aaf3856eb3b7b8781306c0ec0d030cef0c990c6bccc0a48e3f1e3c83bed294819310b42575eaab774b64e0b425dddd1abd17b43406c6ac7582defc295e2c89810bbea321b7745222248581d3eda1b282aba8094960e02745d024727d8b9ebec00995938ac81b5276c90b4cfea8a671439267495de09365483c2b7181778fe973a6243fe6fc1698982c724e217b8ef1d7029727fda79c449e907d165813f1d34cd5c5ba1e0b9c274b5e810d292491df9ede222b704987a6ceceec243f55e0daba73104bae993915f80e66426e2ae96bf514d031e4a5c0df0449599d8d026b22eb96ac160aac6f7c513944ec20ee1338bf51294b595576d4098cc6a4ba82d7046eef47ab6b52a222ca043eb3ae77aaa4325f02972bd2bccb74106e2a810f19946a0b39bcb449e094dec58cfb691e3290c09b89a09e3976a4143c06ab7df7adda71ab640c7e84ab6f0473cdf96270e6f927e4fe536f1383fd53f2f482f2ccd80d8317ebd1d14b04af9230b82e0db223b7c6206382c1a690c94ac8d4a94cc0e04d4b4dd2a43653fc177c998ee8a8eee611f305af9aad74647ac1c9dcaf3fabf082f1be4b757d179c6735355d962ed85c9a3309a956dfd5e782f5bc96e28237299262a6102ce4c8df82d38d41e4d415296ac8db8253a1272515f9d335f2b5e04534a54fa243544db4d0453bb36024e99bd8953a485216ec05cdbba539787a1f0b26063f931137b38960c188084f4adf2ea7f2bc82d399fcd4c44da9992b185dfbb1f094a023de0a4668767eab9d7c7956b012e2e73821c65cdf2a38d77c6d916a5594425e4d1e940a465f8558c51715ec7607539fdc53b039a6d469d3712bafa6607b7563454c0b9aa3a5e0b54abd9668b67e9514ec5ede10743b0adef55424bd59535da260729db0a4269a864443c1a7491972c9fda849a0604f6672d141d8a59c4fb01dd3baf5588ca07b821fbdcea349fbe59d9de03fc8309d5382b61539c1a595143d65c9f4eb6d827d2ddb94538a0a71a309ee92e4cab66a67f94cb0f1236fceb969b3334cf063322b678fb14de8126c868918aa2b8778154bb0b1eb92dfa75025f8dfcf1b47a41025b82c3a94a687d41443d02418b3d19833ae95984912bc5a3271bb14963429126c7a7928ef8a41d40f0946a9f014235da8d0fd23b8983caafb49d09bbd23b8bceddcbe135522df08c6c642fc8ea0f47fc40836a96707b10a39e5a045b0a74549bbed76ef902238efcbcaa7b35a5f28117c90f62ad2434d731c119cda9299ea2be27e7e083e57bd07171982abf41ebe9f7d93ae0bc196e73fffe8e32989108c07ad5e291efaf941b095dba3d65e0ca11404e3ff9a4b734e4d6f03c18bf2e02f2242d40408c627572695eb1f3875d1204ff503377a59aac634fbed0327e27a8bf4732d11f9c08b1695175c62ce31b80776eba4077624fe991c15cf511e58d32a39b978e0925a69b97777403533c60edc48aaf209eeaa2953073e644e971444f0fbe9c0c94d1e938b6af091cd81bf8d3957abaf9d6b72e02dad23a7cbe97bb438b065a2c181add4f5a53a5ed0aebc8189eb254b6b2425a63a6ee072355489324badd769036b227a760b62036331a70b5a2dc8ec92b306b6b3a84f963fbf29c951031731c6dca7abe4a7a434f0266388219eff65484203a73e9f921efa33709ed3c3abfcd2a7df0c8c488a1062eecbc0e613a5b53c3d6a069181f3af1b9d2a2a92058d81c99fb2e717fb10e111031b3cf577163d0c6cb01211aa93fa2f0e065623c61c62a6da4bfb05d6bb42b254773bc9f5027b9dd72ef04125ddfd5791d5572eb079bbd1c34f5be03f9ace0949827237b5c0a6dd9861a636be995960c543e40aeb4875251638a1fb2ebe05afc0c62bd9d12afeab67053e9b55889ed4b847ae0aacd99806770d153cd95ba7f29e02fb976731433785ac9102d79f3541e5fcaaa489026b57212b9e5e51218302bb296fa6c79ec0e7d89afe39bdbfa8b813b8f4aaeb6b294de03c96aa18b4a5a47b26b0df7ed1f73693a8e54b605395573e253fa95f096cbe85a77852401238912176f03c22d7961480045e735547da1fd1fd8fc1e6afba96161983c9aa7942278fe9e58bc1060f33cb8c264a44c460cd3ff865ef87c1e56c7929054d31a52061704945758c5d9dd99f607021887bcac9fcd27980c1dbc7b4aa7f6dbd9c5ff0f9ebcc7f33462eb92fb8112abd66ab4f5ef15e70da75f725e478c1771cf11a99a7b2d9bbe0ce644af9e2eac9af75c1f9282d79335e69a473c1d5a58a3caa6d927071c167105da545d9e5b6b7603fe97a336dda828ffd262c45e224356bc14aac93a2b682789c169c69266517eef5599c0527e26dd0d4a641c650169cde50d5d593bce2c5824b23430c792c491fc182efa0469675cc2bd84fa362901b4ca5a87105232f5de50d31dd0ab67c4fd684245459ac59c1c490360795bea4254baf82b30a2106192fe69c52ad0a6ed3eba78b68db24d2a9e0f4e3be6fa729a5218d0aee56947ed091371ae953f0125325517e320557a12b7adf4e474b2a05f723443bc716f52a9182d315abf43ccbac4aa3604b445688c12dfef9a2604d08e9a6f25a48c20f0593bf6d7276fe0eb90705a35a2bc7f491bf3efa04a794ee90214fb031788879c334e8d53bc16fe6b6dc3a32a4d539c109adb5316766accc37c1870e9a36794a6bead6045bb75766522be798ce04bf571d6697f3fbb398e0839d59d273f74bee25385d9d94f45e8dea5b824fb50ec9eaed52502538b9c127e91825e587127c5a7ad795d06d4f27c1664a6c9b14950497a1d62a84c50e291a095635e44dab97eaf484042754aa8f353e8253eb3b29a62b933982bbd839a458d9da62b2115cbb47c95bf9a7828c60b25ede360d17c1987774eb8f22d8a034dcd293ddee26116cb06cda93aaa0e46b10c18dce88a94e08891d3b049f3244724dcc10ac057d5aa2975e8da5107c7674112dd512a216bdcfa3fdda41b0263bc8979833c95cad20f8c9494dbbfb3ce56a03c15bd29b629937640f5940b0db4954c8dd183f4ef60fdc5e66e7f8b771a364fdc0db56ce932f047df9d407be2c9be81c3dd976121fd889a369d54cb2c9d31ef89520c2275dce514f7a6093caecca8fa09fa63cf01b29c894f9c703f79f76f4fdff2fe6efc0a74a954f56b251526407ae724e2a996d291583eac09e9d342d2934a40bd18155b3a03249d38e1134076e37ec3a88305da72307feb472e4d3afaca41307de73a974a33588fc3a1cf8b4d1425f820eadf91b389d2d94474ea615d36e603f66affd966bf8db06367b07730d394e122d1bb8bf88e943661731770dac0799d93a79303fa51ad8e03fc27f4dcffe4c039f134789dce02979120d8c9550a6d267e07376483a5494bf976660b54d721a5367da6519d8f6ccf5ca37f164920c8cb75587b797c8791c032f297a5041796891a318d81042fe1129775fbb30b067afd12595cae93760e052142d49b896b4fe0bfc69e8b7c6161ddd0b5ca624b25a4c5d60d3eb2787fe8ef91a17d8a0420a522db345d3b6c0757f7aeb8eb4c065b6cc9e274b3734cd0217e298523a6a4c9d53140b9ca766bdf368138445afc07d6a9a4e31e6d1a3522b70655182bf264f0d12ad02ef2b2ae9db1c3a1e512a30c2437f69d34f81d7a8a93599764fbe14589139855665d38e4781094a089dea9d3c68a1c08ae88c5127895e143d81d1c13bd47c4fc5e4042ec8102a4bce2b3adb04aef25772ee18325487098ceadb324d3a4e3097c0eae9edf7e80950022331782c551d32783a014960edb36ae9ccc9b5b30940021f546eaea04a95eaf6185ca924628690bd63516370124ffdad697cf16431f8c827c1748d12b64962b0312cab4ecaa376c961f0373978e57f26e1a330b84939948e1083af2718ac45dab2d171b73bc0e035fd4a4c8929237bbfe0e48b29f9ff49a6ccf9823ba126c77cb97964d70b36a6959716cf0ad5f082338b31448e0eba3bb60b26fe48522ab787654d174c1211c1f6b55cf0ea9ec5ce74f89f70c1a5e062e941b847f3168c90394753aba42d1893346a5c2dc74c95ac055b2a5be8cf49d28253b5dba347335696e42cb8a0a2764487caa49705577a53f4f190fe3bb1e027e74e7bcaa4086d820523926d25849457f05f95c6a4a5a9cf2557f0b691c23b4d63ea5bc19dbee5fc2bb182af3e8da0761d94c8af82115b31692152052f71437e0c69fc64502a38694906114d4d9d205430ea2e6ebcbce942e99c82cd1837546ace27a2c7146c2c79f9ba544c13724ac1568dba8da89382dff05d8d172e3ae2a3e056549d55d9eaed2d0a2e67dd9eb421294f772898e02d16226332dd1a14bcfb958f127a54dd8b4698ba09d2dd2d6a895c0e3ea4d3df670896e9233b234bdb70838d2be4d843c9a107d63e59d2c1f3ea251dcb1c79c0b49db8ef85d2cfc822c10b34071e380df93958c9cbe4b8035f2fa9c67eff1c76e052db06cd0d3a877cf91c75e0f3b7a913225e7a5242746083c48d2021f5b5d83d07c6e49969ae38ba64a939e4c066298b962ce418724673c481ddf40edaa39aa49895030ebc896c6f956d3a39a6e47803dba66aba9a9b1b1613e4700397f9aae63922a8944f6764f9e004a1ca07a7064fea0339dac0b7da85bd5994a03d31482d3863c10d7c08600939d8c06e985f4e9e5f21f86f06a936dc60430a39d6c0c4503299f69494d098c9a1062e5f0e5df9374a47093923ebdd5803083e7ef419ba468e34986f1f32c7539adb33b27ebc1a6bf82055a573a08175cb8be4224bf3c11b6dacf1c60fd00739ce6006377fd24b95d44644ffe1c61a69a4d1df0629c5f0214719f814aa4ea787d29519e420039fd35dce18dac2418e31f0b9a7fe3d45ede0a532258718f81c74de56c8d4ba1e623891230c7c0aed9c7c6d3ad37f4891030c7c6fc4902a629e81c8f10536051bb3dca2eebe792fb0b1eca35b577bce910b458e2e7096f559c3f4735fe6cec8b2f2460e2e309641c81c838fcee944c5448e2d304a984e6b25416b798e5e22871698782b7a255528b12b0d1f6ae4c80293eb34fd456db5b43158e063f55a26bd4ebb529121c71538614af4ab7bf2bb9eacc0da47cd69397455e0ab7436e14174c897c91c54e0b743da78987e0aace8acdfb7bae831e7a5c09d67d985e93e0a8c34fd8ef71662e7eaa1c0995039869043f3f6839ec0c61c9537b132e8582327f0a631761226d52bc94f13381973905c26e4e5c80f13b89129e48d77dbd7b62f81cdb14a62a45191eb5702fb39afe74b7be531d33992c0e8f518e48aaa1c91750e24b05be72a4295f6188c6ef5a8f1f4c6e054a444896161133c5b0cce563572c62d75ff2b31b8d166f9e9df47897c2294d24f6d61be30f88bda31a83011330f06a3d094f5844c2160f0934fe76aa6f70bdea3c9cd79359d47f37cc109378ba7136b3508af175e1ea5e993a98617dce77429877e8d21b4b60b267d90db7551f7c4325db0a251b4a511a973cc4b2e18b59eb137c471c15b052b9119928eff965bb0417e56c8ce9c1b715b3039e25d486aa337cf5a70a9f7b53eba9b6c5320c0410bf66fb38bdca07365f9b3e05bc74688decbf31c248beb4efac45c009e802316ac464dde3d1252091cb0e0d63e620eba27e6e6fb0c385ec17f2595bc4ca718f2775770213da36d57bc15fc0711a38e055119496505ff5d6a4d2611d4242757c177088d5c317b0c1d93aae024673291e36e59d61a472ab83555329679f55a0a51c1fe5bb0ebe4962776e614fce78570d3da925b1953702f1a9e1ed2941c5529051bdd53c89734450aae62cc371a7257d71e0537d62316592d578a105170d263e85dd0f96ae2474b8123149c7db9d6e84e5b891a5266bb800314bc8ec689e2d92757868001c727f8119e2a2a07bd1b707882fbfa1eeb2455947bde093ef78d891cbae10427644cfdb46a2262fe2638a12257768d29f69aa3092689143d6f3fa57c9d6682cb31a8f68e12d318494c70233a6ed01ff53fe5ff12dcb88a4a59eb5b82915fd2d4739b3ea16b2538b1324dbb9d39e61e08fd8312ac464bfadd2448fc0d4d8217e16e6a39e7d4299592602547cd9bff46c41cb148f0233a77094dea676b59230dd3230625e8d182203c2afbb10624b8bcbaaff7af3d820d3a3b67499db1462b1c8ee0fb3679bcb2246358d8021c8d38739021652edd703082bd4f2aa8bfd469cd2b05c722d858b1dc3fd2a664d32b82cb6b95c34af5cef39a08f6c42a28bd31a7931ac4020e44b01d826a9041241d55ea21b80d8dd143f7890a3186e03afd8a0a5a45c78d771c701482cb9321aea5f897fb070e3808c1b5c4fea0a1c34ac77b10bc9650ad1739e23db136e010c439479b8e95750c04fb92bf9479d0b13257c28003108cbde86cdfba9f29df7f60ec73cc9f5c37e7a6710d871fca142d68129d31fd81d478630df7e1c61b6ca881868ff369bc95fc81a30fec470b223ef0f6bb1a4b4fb34e74f6c06d4eed98a457f4c0694c0b1559724c9a3979e092ea5ec490f2261d723cb05f4a26153ceb77e0cb4786473ecd22bfb403e31ba2e8a471720af25207ae3ae6edfe943747a50c071d0ef24c86e690691f9c1a20351e0666f42069f0a7c1c61b31e8e10215f4581c73684d04d59e3b38e4c0e43bcdbc23e346b63a17471c385d9245858ce8c15f8503f77a1be39d9ef8624938dec028e5956e1d93af664f0738dcc09be86e9b763a6ded3a8e36c000071bd8d2a642baaaa4ac556d0d5cc5135da39b995496fc0fc338d4c087a0eee717b4d8c6ff8cac32caa8c5910636568550b2be4fafca33b2b48c4f0d8332caf0e183130483030da6bd1c3d6b77720d367e7c1b69021c6760fc933cb7bce9e149e4c60f355ca0821e6efc0f337afc70e3cb28e3c70f37be87193dccb836dc60630061c061862f7268ac0c709481513925fe869c4565d3c9c089b9e4fe204fab4b63e0525fdcdc1ea915fae16ffc30c50538c4c08b891011f4ba6abcb000471818dd9362d9dee778908f35dc000367a7fd157307959d6f83940f4e0daea800c717b88b7be937521e871758cb482146dd495b4988a30b7c3699ab4ed856ae45896102071798b89f73d54d9b05c71618cda9a693444fd2eb734696e2d042e111433a9d459f8c5e8d1da00183f2061c596082c827bc36443469212cf092264e3a318921aa73053ebe5fa6241642468e15f8ee94a5d512342bdd2a709ff9224c945aa8880a9c5645ecd41f44852aa7c06e9ed893464adc37498189bb291ea26b8a8ac128b076d22c7a484a37f70705468be7d5cad021dbfb04c6bc6cf2c930a55248700b389cc09f36b9ba9ea993a6df04266bf09c646deafd424c00028e25b092264ffec871a3faa704b6b4b76385d812646db4f13ed8681f64158e24f0257b93ba5d15081c4860d2ad9f86a4e516553c06a75392a23b2ba5fff491e207328cd1e7b3fd9c2de535ad8719a709328ac176101237e8ea85d0103288c19ace9b7ae49f0ca219710419c3e0bf4442dcd28d38a6148230184b71572b88a44b2579910419c1e0b3377d8a1d2466061d185e6b6a8cf96cff718320e317aca9a4f1b2d65414ad8719a67c94410519be60a4fe7e75685a46196a05327ac168b9047d398bc640062f388b7875f94fb34d62659451ca479d25c8d805d7b5fd3da269da13a40bbe4a5269f85d0c19c8c805e3934aaefec8b738e91f3dcc28a3948f3a3c90810b3e68bd4b2ad364abde7a98d163076aa0d1c38c1e583e0a4741c62df8d8973f48d552113351810c5bf0513d644eac4e5af2050c64d482cd227314a134e46e510d2df88a6d51af2e52a6e467c16e6ad0fad3df651a9205a7217ed25d623285f0c4824bba1e7bcfb64fe50e2cd80f953f9ad0ff92d2fe0a4e65ef919d9bba72ee0a46d3a68a1ecbebb56e05ab1d4c6bc692413dd8ace024e52cb9d99e47c67a157c16eb903f2a37544955c15aa9d76ff732159cbe8fd6ba955c534ca2820ba946988e123c055f99f6d635e7d2b49c291819d3ffe2674592201a6bb0f13e4023066594e105324ac1e579909c62e8da242978f3a41f44e6890c9e1905a39ae2efd97753c88b824bdb1d5248c1fab3b550b0aee9bd23ed4f2f4840c156758e243b25fb88ef2758ef8f29ca4c98c88e7b82d35be953d74fa49b38199d604d4d0e9226e59c23d1139451861bc8e004a374c6a44cfbde049f6aecd2fa4a7b454b13559ba5c4cae0d94c70164a66c5f5d8256aec61468f32ca50031998e0afb7828841477efdd825d858ff13a4c9bd04820c4b7097714b978c71c592a7470c54d0630b116454823b95ca76f3e428c17ed0aba9be920ab19d04a3d299a5acd53d1b8f24f8fedad21b53ce0e4a6d063222c1feae8e25351ae69983049742cef311267d043f71fc949af4273c6d47b067a2ec844cf972096523b8d6b13079415a5b14d5e02b90c1085e7c47f2afe9641e25642c8233694975e78abac0076bb441022b3a90a1087e44d475d7a02b2a3f3f84f0292023119ccc3475a22506119c088f54b293e9108c8c755bba762b537b48a0061addc608d010fce9bedcf0e4bddd27295f20a3107c882749a52b47084e93a7fd51df4d25a91eace123065a2063109c10318724b6179a562c4d2043105cd09e4ec8ca91b5731e08fe547bdb86ef89849433b2a240062008ee1252a8b9998b866c1622e30fbc69168f5d79fa640c9e91755820c30f8c70178d9bede49b521ff89084a8b39492fc58e203a725afe7babea855da03af76428fa8ef17fdf5c00611da952e520a269407c653aece65aa4479101e181534e516fd1df85013347b9262be213b7057ab3776ea533cd581b77c59cbb64785acd3818b97deb7f3a4c898039f839936a58248d9ec44861c18bbec8ca3d27160b3ae4b9a680cc95c3870aa31445159a3fab86fe02dbbba5a27bba7d60d6ccea2c5f4bfa856b50d4c5a8f413bcf06beee834c59e93796b90626d5ede98ff7967935709721a67d926960a3460dd14797d0c05a884197929b3370294632ab7beb32e5e9901305e3596428a546e91c53283825d307b7fd78f97a030a3e8b4e72f7ec2973c77c820da1fb2f44fff3b18d2778df10112328d5d0a5e9045b3afa7324fdc1448ce1045f5dfe49d44b5d0e319be0bdeca38aca9b26386d422925bb35d73c99c8ba7d635025c704a3c6d6ff638e2be9be047b1b4904752247cf194b301a393dc653418e6e5689b5f7b3bda894e06b74dccc79a22e9c041b634e22e56ddbc44c125c4553a5af47876c2a8b041bd40813957bccf604094e861ea1377d1ec1e5dbceeea33a828b16fb63c468eea92b8de054f618d57a46304a66d122f8bfdb497a7245302a449294a73b87cc5622f82cd2b4eadb3b6c2c4470664164a4b4eb10ece98ab4963d4c6b5886605c47a874ab27357655086e4dc468764289ec2142b0d6ae294faa589e4283e0dffa3b8fbc05c197ae18dc6272f73b10ac78a552d91744574070394dc7f8a222e470ffc0c4a8f71916294810fa81dd184ab7e9d19fe286f481bd9035fdb87e7bbc950fecd968d22afa9fff92122c600f8cf2b47c9f22f3a64aaf61017ae0921297e81f2aac529507c63bbb0791738f9aa4c6039bd63ac7245a3705d1de81f38e95cbfc3fdf946a0726efc694573159072ea80cfad143493ffde8c0c8a8218920e29ec4dce6c0dda80aa64268d21c39b0779e9f374ad4b08038f01ab2c81aa99b9ae3c381516e96d79644ce90f537f093ce2b9508d11d217b46a661016ee04c62c42cc949c83c69342ca00d8c0896475f4ceffb33b1814bfbebfa2b663939bf06767412b3d148fa4474d4c0e49077fb94b7b7779506364531bd25ef4403eb212d37f37c64c89b33b013eb2ae7d04cda259a810fa6a92142779610b1332ca00cbc49eda43e6f0c19383f5dd264b94e4a311b03b7b14b6f8724d7449218383f1192822c57d38a8781d51d1952c4d366a8b2d13ef081bee2b0003030d6e95466254bf26aff02135d47c895d8bf5d322f709a72e70ed94f4e0efa2e70fa5da66f6495a5a0c2054684ab5f1276dac296649688efbd5ae022a41bbd49080d9adb2cf01d1eab62b0ec76495860d287d0499ab7ba48f50a9c8ee962caa6d1bb64d20a5cb0ce9aba61153cbd9a2d444fb73b1510f9efd2e5208350ad4d810b76b916e4b8e47e8d0f0b900296821215921610053e5ebbbb96360962211458f3effc0cb5ea61014f7044248ffb9af6960538c1f0d0eed87d63a326701fd1a359e6601fb38909aec5530ba2ce4c6eb78025f07a42fc5d439012f8d22d7d5224060dd5594012f8709341284f2a0b400231a668fc94478fc81c83f5e0a37e951eaf4a6b8c7e92f60a7631b88eab12b33f4b8ce368b41029e5ccf2866170d57c1274b583c23082d039c41f25841b0c2ecbd6bf9398b21c638051e5f5a4ea764231d0f10bc62ea70ba54cc51756ccc943baca0d29bde05ca3468fa35379d0c10b6c2f95e93c5d2165d32e76df8b4164754b9173bae0ce34d59d89d6d86f6764fdd044e8c805974247da889f3f8485e082cb2354d34d75b0fa112274dc82cba0833ee5b14f4fdfb6e0b43b87fc192af604752dd8b4bda0cd532aebec68c185143773525a6bb4c6cc82b1bc1edc42fefda98a2cd888e97eec94af98ba6251cca764a6281b16bcee9a9f473cbf4bd52bd8e47ed9d15ac52dc8158cc58f7cb1528e97a3c408a1a315a8124965c9aebb531356309a557692a388dc745ac5a6a9323c644a115505e39a3f9bc7c8b944d0a88146b7815281bd4557bfa8da222a4abfae2f4d9f4a7b8a3e6a47b22f0f915953acab59523ff5c74a6929bccd4b2dbfeb94d7523a48c176ca6af1c5474bcc33081da3787392c80cea3de5d2e810059bef675e91c2a2086529213c9212848e50e021a667ca11d7aa8d77038daa1e3128418f129414f430a347a5e0d3f06ee3dd38011bed03523a40c19e781072fd6b1d9fa8320c053a3cc19727a144d24a9e8e4ee496797bda54678f137cf6493555b936dc6043c726d88ef9e97ebbd194b2e8d004a36bb925d267649971061d99b0926e8e9e3ad665ab7d58010012746062f18a242b08e167ada087193430c3aa4b709a4f44db686faa35b564d06109468f4a9653ab0b838e4a7022a92ca9644a398f327550821d9de9b3a97b8a219626613a24c128bf68e25722547dae23127c4aaa7c93a20409466a0e7a820cd623189da7c73594d69455a2c3119ca66c2a42e64f216f4e4723d8fcbed947c9aecfdad7406ffcb0820e46306935448d1e3b6b124a3a16c1e660a2d2c93cf6ed271d8ae0db35547617991df329117ca76bfd9f7c26624204bb155fb2e48f9ba36b8760b426d5fda0d1c4842c0d3a0cc1a73f7d4bb2c4f385c8051d8560f2a52a0d0d32d907f30a3a08c125114d875892932ce828021d8360d3be6e8cd1af3d84f48c2c1f56b6063a04c18bac24cd26de66c531108cde5cddf3542aa80d083686483aa54d11b5ed1fb820736d67d1fe5e59e4073e980ae93507bf8997f781539d3e846421256a7ef9c058929efd2a46f7c0c49042cc2427e64df7f4809e6a4b2a962e79e062ad862599c52afb06f1c024ad3d7ae944eec067eb343a45cf5f59b303a7e4de7ee954d781312ff54a2fba1f74d081fbb698f775b1937aaa7ffcf8151039e898033f6a17dad64f6f1a4d8f18a8a0871374c881495faa529da8a44fdf38f09b2f97074b9a42ed6594618a1e74c081714d13f2043715e2e674bc81f588f7a934c5e86e313adcc096aa8b218eaedac0568eae623152ded0c1067ef2aeb75590b132660df4c60f32051d6b602bf333254b7c9149ed820e35b09a37e27d4c7fdb77a7812dcf753968487540071a3477b1ce182da5f654cd5a9b941fbee2f79f19749c8135994da9e9e4e425c121e8300313278f4c4ba23d45ccc90a0237117494813f3b13727f2d3e7c70a5470c4a10833fe820c3679741b4a9ae05668c41c718f87eaf5832350479ca2406de4d624ed2d29ddcf330f031a8ec8281915bb2e37566bfc078b77be652d96e42f5029ba964aadfbd0be91c4a763e991f2ef0319ebd8b16dd1618adc1da2a4f694d11d7029bb9429a8a9644a7a0cd021f3b44d5dc1025242bb1c08585db974e1bb6a7bb02a3448deeedf3244f6e0526483e4d6de94cb3b52a701da3692e13e9473b440715d8e8e997934eaa6fad2441c714d830db18f1e35a071ba50e29683d6697924e9efc828e28e49a2984360b21e9b7a1f0798e59b5e4c40d7fe3870f83838e2770229daa6e8fa9c3096ca96822be7787c8e80a414713584b1f4b42dfd6c1043e64fe9074b4bb94a16fa30dbe36742c811fbbda94cb4ff8279312f86cd93fc6932244484e1238d531e5deccdf2593ae03097c9a0c6229ff3c06a72fa8fdf86756abd318fcae88975de724fe6231d84a0d295695480c4eff93b6e02582ca21330c4eb8e80ea1d2688eba1106a34c475bb4bb44099560b0bf56baa2a409cd6d010663b253546ac97fc16b5604257aa164fabee0839806df9d98363fd20bd6da4b4373da286a7d5e3039554410f5d8b9416817bcbbe667c918316d8574c1dd250fd7169d5cf096459992db1d3fc7830bbebd7454b38ba342e5dc82bbcad6fa313bb56bb705376ab2c33dedd6d35a0b7efc74365d3bc293a7b4e035f965299114e27ece824d93f4ee95530c2a93b2e0723635d9926f2cdd632cb8cd418504ed65754284059b310955d16465ec0cbe8213a9c7bcd38daee07e77eb3b7f5e09a15670371aabbd32a5bc946305ff2793642dcf1383e456c1e5ef31a51b9e273b46158c6951b3d3d61c726252c1f825fd1854d0dcec182a18bdfaaa74a64207f529b8789353caff4f63b629f8133f117b7f4f575b0a36a79351639fa4e093e57831e858954ca546c1a47a11dbfacd508fe410055bd74159c6f554af9f8d1ca160dc745b289be03992aa6ae31fada146d5a3d1861b9b03147c75c8addc93ff04af66f235794c97cd523cc17ad67fe4a8e51bba57030d5c418e4edc19379d4551af914602e0093938c17a50f74f55a333b2d858c30d34dc071b3fce083936c18b6b26d1ffc819593fda4023f960e307f11f6998f36cfc3045841c9ae07ab456074ba24cf07ddb954b9f12138ce5182d8252d7f21d2fc1fd86074f7fa352d3b504272b5f8a3cf9df3c69a4d1597ac4a0043ece70838d4741c851094ed9fdbe7bee4ffa254a7021c88ce49db43526951c93783d4acecb3b046ffce047707e065596073924c1284befb14eff049df748b02dca930ea612fbaa83046b19262c7dcefcb6ed115c6c93a53b47529afb76045f974a869ce2d9d8441bc1f79a4e4af3ed7a7918c15a4d4c59c274aad0390c722c82cd9bdafdf36a3f3a0d9343118cfea5b4a782d54db2e4204722384fca549b57be94ed470497f2e9f3d26a77ebfb2198dcb95363d5e854b13604976d1f34b7430e21bf85e03d5eee7b06330b4984e0ff3f8aae5e0dd2f28360d35a34119d7d4f7229083694505716cb43c66c20386d37cdb01073008253f172d2a47a8399a7e4f843499d0a76fa69f20357aa92e74922c95415ef036777e04452ad693b444dd4b81db85bdbbc27ca4209b3ebc047f05ccd2f5a3a70514fbf8d0ca18359760eecbb6b121a72c7ebc9ca8117cd11237fc80ffd6b1c8a233b706035fe6da70a3965eafa06de63bafc39fb3e249d1bb818454adab798d224d9066e93ca9dd9ec4799101b58f7dd4eb9f135b039c64db943836ae026474a1e2c8269603d491042c7aaddf8a381b1bdd310a4e67e1edd19f878fa19beee41fbe8ccc08f5031dd86ec19d12f033faa729514afd4eac8c07b7dcebdebd4749b1903e7c1b62b3b481eb18c18b8e0292c977af7f4a030b01d51837e5f090cec87c79f186a17f12a5f606b633093a7e4053e6b2fe71449c9beb70b7c04cd79628af4e7738153df4c162496b6c09ff012a9ae6981d52ca9bc6388ffe9226764f928a5470c4aa007066481eb3c0b49ee792915f4a26000165039430aef13ff0a7cbc18feefda7e820156e03a28cb49c43d195005ee3e75529d92252dc1002ab07eab39e5b3f813bb5209064c814f77c1544c4f5630400a7cd6c689d1deb792c49831200a7cc50c42a71ced1c2a04052ec51c5b3f9ddbdd9aa8c08027f03b7a3f5e2396938c33c0097cd61e3d41e8cfdc15a9c981014d60f5753cc44aa78c3218c0047e828a56ddcf10f34c4ba83218a0040624813d4b66d5a9e4850148e06ad72ce40b25449e760c366e2c19cdc7524a217d041ec640838d10c080013c8a418c1e3c86f1a30d34d808c18f34d658c30512e0218c606c800730088f5fa491469be18b5e6080072f2cc063173ed06023042e80000f5dfc51630d358e1a6bb0a0013c72f1001eb8f82184ef410478dc020d364210011eb6381eb5e8c1831608e0310b59f0e0110b1f68b01182f71601193c6061011eaf501eae58008f56fc7834d06023042570000f56fcf8f169bc1bedc60f1f0de0b18a04f050452a527f1a64f040851b6bacd1868f367ce0031facc0003c4ee1c38710be0714e0610ae4510a37fe870f520821fdbb0f34d8088110d2bf0870f018050e1ea238e3479f21011ea160c3c78f04043626c0031417e0f1091f6aacc1001e9ee8041b3e68e30c4e6c42136ba41d3c32f1c30d351e088f091f1ae0718906f0b0044a038d334e252ac0831214e031090bf090c40f08f088c40f36de58a38d1df870000f48fc68630d377eac61021d3c1ee1030d3642d0c6f7a08d356810011e8ef0a1c61a68c420033c1af1831110e0b1081e3c14e183013c12f163070f44b40f06f038848f03f03004193c0a81001e8428008f41f0317848a2ea93f2bebf020f41302a5a925497f7e5110836a98bbbd72504083ef2d58bc6ac1653f6f0f8032b761f4f8e6f5af9ee073ea59259734506c941b6861b6c08a18d833cfac07b2e7929b4d7eec8d5073cf8c0a8673af32e399ed6da0327967ddc6e5c846ba9072eaa7ef5a44ddad355fec60f7482cc039f526d25adada9a44ecd030fecffa81a9944c4e30e6cc6ecd151f275ec537180871df8102986d0f9b779f1af03fb2bee7ea9273d955883f3c1830e5c46c92109d1146b47c7630eec776fb20cca3e7bc669a3ff870f21b4d16aa0e1762ee021077f2ff69b529b1df0884395a1071e70302575d32f3966edc60f34540083476bb0a08d357efcf873def851c6efa07eeca04560460f646ff4e841ca1b3dbcbca18610900f373a0d129451861aef861b9d46aa2a027481c71bb8aa728fa7cf2da52bb981750feab446dcdbc0aae520bc2fe488954e36b06a3a8a4d50bb962cb306cedbee5275686bd44929010f3530ba3282e93125ac94d6682391fab11fe091063e99f76bee789a37da2df04003ffe31f5f824ca292483a03ab9a4727d8c574a33d33f0272be7d02054f49c2c1e65e047887c91d4a5f4f49c0c9c0c49e8d13e216a5f19039b5d1fa6deb3ebdaa515fbcbe6c1bd0a031f3c27a52f42464bd38a117880810b993a4b5f4a216668bec005c92bba54752ff023e297975e5d60340615e5393c5ce043945e9a1cb49f8d108f2d30da7e2bdb8b540bdcf6480f5d62423b8d2a0b9cb2f3ac9326a75352c2051e586082125d59748e4c41b55760540c29a9a02d6b055662069dffeb23664a5681937ed29366fb5259192ab01723be04dbf414f88c13530e115f44a9500a8c0c65b6e952b288138c0217440e79aa153f236f063ca0c055fc3c425f88f1b34a86c713f84c4b2afd8d7bce9f5911783881b1d4a7da64c510bf727c706a7050e0d104b6f30565b24d2b72481713f06002fb9af2b386e686c063099c679668bf53151e4a60e2faa9144d49891b396764a5d13e88c5814712d89ce2668ba6926764211ffa061e48e024784e89db9736687a46d631d8f70c91dc744cb602a14fba61873176148309f227478b787d779333b288c1e4eb7cebd1a64753f7d1c630b8eb0ca6a6631421728c1106272bf5c7b89f538d57cec8f2d14629c1602dbe57fe3ae11959c0e0624ab94b622ea17caf33b2aaa061c72f88ba79b4bab74b690d1f3d3868f4c00f3b7cc1ff7dbccad3fe8cac1dbd60548ee9acdfa4c8b1dc4702021b3edc38adc62b2f78b3131de28de7269d9c9195be0d1fb90b4e73f0eb47b361c2b043175cd60912bb5bf4fdab33b272c105b9a7d6394ac4c70f340c0c3b70c1aaa6bce4f974a9f9688d53f2167c9946b0d73bdbb6a048ecb005572131d9abe6207ca3b56093484c29ff9f3a19738ed8410b3697683e19764ac48e5930b14ce8994ca32176c8824be5a35a7a92f67d0eed88052783ceadbaeece9fb12dc40e5870a63eda8698e5ada7a484d8f10a3ea53755b1cb3e234b0d34fe0710d070e3b41b75831daee05a2b6b05a513e2c5c7f7a07d402c0d34dc78c3d860472b38c941624e573982a70b1f76b082cbdb28923fe8dfb17f156c96e6cad194af0ade4406b9a9562b7c47a9e075553f7f3508155c5cbb8b59a28d8bbfa7602d24ddda27f263d66b0a762b9f6f6f921d2497a5e0df840475a12505a73d4946cb29a7ed1047c1c9647d2288720d726444c14e0adea3b932f5b3150aee5744505dba25da8382ab94ef8256d23d71f40946898955ce1e62bcda13ac0795b427e6c13a5876748211511ad3290b31abc909562c9a98daa0dd3a256d820da9a24648d2ccca9234c1e778521d236711294399e0a386a4d55b3998e07f376687ebe813e55ec2743aa9d051444bb029cb644611424b245a092ec72033c83a213d8d45097e2d73d0ee793a9ea48c324a31764c82b31c9e694c9fe52404c10e49ec8804974d07bdf6c88104d72543ae5d87a830f923b8f7b46229a6db11dc464d37823725df9390b7c1b455463039f2a824ad4d49cb17c1058f6c29ed8ac55b4b115ce7d115f9d184d43849041796fee347f5c939428860f3f2f23bab7a0836c85c49994fcc1a7618829394cdbdff4db7e9a8106cef9985dece494a758460837a50ea72ddfa488b9a61c7203821f2421251da7e4a1dc30e417025aff24070a9723e750e3b00c16736cdd5d94e56fd49e1b0e30f5cc6985cf74f33db327ee0d647ff484ee3a554826fd8d107de72c454596342725a75b0830fac29534ae6f66469b0630fece9f6915b67631976e8811555a7f62e6af795bb64d891073e57085da2dd967376d0ae3d6250821d786043d606d591edb8039fe3d9ea496d52dff0366280d490811a2d30a3470f337afc93608d18f488810a7a202576d8812bad7e6da9f4e66477471d187d6ae26731addfe574e073e706e1fd93938c493607d64dfa859894ccd4b0430eac6889b6412b7b901363c38e38f03fd23f3764111cd88e29bdbc267e69d8f1065ea4a6e5865c1eb4e705073bdcc08a4af2c694a7520bfd0b76b4a16c12534e1792f4851d6c60948e560dc9ad59b2f4c28e35f025936da50e16b2fa038ded118312a8b1430df95de49bd88e34ec3726ef3744a8dab0030d6c8c24ad6db3e876297960c719981882f214b45c33f0b984469012246fc5b70c9c96681f4f7c32f06a63d9d9ad6234618d8155d1edc95b317061223fa70ecb1b6c8481915d1736b1b31d60e042e68ceafa495fe05f92054f9b17f5dae4057e7cd2fe7b8e1564307581fb1259b3554ce2029b524ca5b2b583992c6d81892554cd357a957eb4c058854aca23bf879093055e5448428fb6bdcd712c709da36a5e89d9cdec2bb0fe6e41dd48adc0d908cf1aefba92955f0576b4646a85f0a9c0ef28172172041593ca4f810d95c9bc944c13c924053e9b66ff8a6e14b8cc39f89f9857c5288202132c06cb6d2572080f3d81493adb43de9f08962127b01152529325869ac0e851bb2b3f51954a4ce035a4dfad1eff1a7309fcb54beecd56e93125b0b7d136bb82674712f8dc2f296af65eefecec4002e3416fe9fa6cefeffb3178ebcdd71625e48fb71b833fbd7f3a4ae2c5e0a39f486e26d9724e3731d8f292277c9247116d0f834f7af29916353956dac2e0b6821c91747bccae7530f8d050b1369d8d483a0b0c36a79eee5bc839e4777fc1ee2525434aca085a5d5f30b23e7e86e8509ad2ed05e71d9a9457baac132e2f381996dfd22fbb0bae2467ca9dfd21a56a75c1c74bc29224ef949c930b563f8552e2dd1a348d0bae744704b35119317d0b46e5c97a97ee62d66a0bbe4b959212453dccd45a70f929a83b2f559f374a0b3ed6aec7539da2c9340b76cda3760eb92efe4816fcf875946859f2a5642cb85c2a6f093d163e4958302a8229992c423a1d7b05934be77b8919aaf395aee02e28dd6d3f229e0ac95670a1ad2f462db1823d35d12969d4697856c1fee9f4d21e4755f041d4681665632a98a0ef4ae70ded54a643057741a5a0a308e91693ee145c109e64e63cd24787ce149c758a9336678cc1f72b055fa1d994b6d14c953e52706b95c193d5370a46b9fe5db6308c3fa844cd6402e3b150240e89c30141200c6eea3d00b3140830282c240ec501a12c4c24b51e148003482a1e3a2e2c161a1a160e16100e120e0c8542815030100683c180302010060331a53112a3fb4421b4e90d6d43561a106c0879174a10c20842915f23cfe3901193e826aa7d081122ee21a64894ab9873c7d62bca81cb6e7cc2209466b86036f4378412d1a310e4a1508aac130913c23604934ef4364f091c17fa1e874a68c83c8e550487c81d3cca75da617bdc50ce1131d4bee745b9bf9297d075f14187bc460b0375a33fc64e3fbcbb29b0700df6bf9269890428d6276f83cec94d2c3a18bd04563f54e6b0af676b266ad4c6b5d2e18685c8f77b7278b885b5cd9d4c6ca504db47f542d2c5f1c2946eb11a90002b806454d890e2176089bcef6139dc3d0840c0d9a3cbc4eba78aae45bbfaad6a7a39aa8014c7a9a2da54509de4d8e36bb6b435506b95a576e1db1b006e77f7990178acc7d4755dde8c32193d417ac886cda1da3d888040ab1f9920061826fd450740097ce6f6a5abb1e7a55497822e1310e12d60b8810b5d8303bec1847a43abcd00c1c43cfc087eb01ec9ebafe0265d4b1fed2b38210e1b04b1cc820aa769846a05412a238dcab082d00a15e691cdcb727e956d84df47c0e68cc61e8d1dfb3d47b78ba8095fab768f66fa9eeb195034bd7bceed5dd4ab9f59d8bd84afda56cdcd42bf88b3517c08898ccdb43a2ade3dea629e33bc594ed3d7d54e9ebba77b6ffb781eb55c53c26fe70a2a1b06157f039eb43824ff8768a47c523dde04c3140c5f82e7d395e85de83c2d10f0bcb238291917777652a314cef02ef9960e6e6ff8c9d1dbb950d5cff5b87078947fc70e3ab968dd3abea85ae8b8b7f914c137dcb058fbe3ac512cf80e489591b4382a8ab36144f6725162a230ad7206d5de4374f186a71a567f2a17aea33f8a9a058494fb21e67f2a7689302e561b0e2ae40acd0d36ce57b415463deccf3c0c7b14760d0b39367261ab62e02ed84940d737b10f922aa2899d3cd9cac4a1649c02c561a81144abdd7567197280a02ec54d37d70d0167e366f873f37ec7017671a5cb7d8a1acc2c37bf07884c1111246fc351bcf1ff469aa56c36392a760f69be62e56810e6471bcf1d4ebaad8f9bf61ccd94ec916c2e3a689103c7e69c40ad457b9a8e06cc895a040b295ff1a4a4a9e9dc8b32d269b6a15ab2a7d5499382872680d21644fc1826cb99b9fd9a829914f6ce604dc19bb2c446940248219446ad1a857f2099eca978ba4245d07665f94aac9ec16f3ee356d0eaf1dcb8829e73a8a7c5df50a64a5d2fa5079216236daf0a2a1bd06625f89444d57805b4ec4d4cb0c0f634b506adeccf438ed37e9f01cba1901896aa8bc826d1ccbcd354b539b0810777b40655e74ff86a5b1e02148ac0f1478f029ce92e7807577c45074bb4dd951ba23197111e3b6d4b3be664525b39d5e1a98b4da7fa31a8ced02524a513e635680d4e60fc3d7cfcde9112b89e58efdde46249217a37bd42cb293890f01ecf838a5095b9bc4de79d8c393c694915f0c2cf509e9ea2e35d7eac38babfe780b92e07b4c6db16e075ee1e9b3b99757d008cee2194cf53f4dd7ecedea0e152a38e708bd076aaa836521f6f6e4619e1fc2e69b92b0023cd7f4df48f4b14cad5c374d7ea3c6274d6346b0f4c4a3c6a766f8e3f6d90e8d09ba95073af919849aa5fa960c0451ba9f96bed6971913b8a56624792e07d5aa2e1dfc87c4dec2b5ed2fb731a3cc9c3693337167c2b960f7270c5821c320681c0e780e0f10382bff024f6d74038e80f4f6ae125aa31cd043f977016c1c93a60af0fd70bec969339b39ba3a8e8936a8c0c1812fa14b1b574915882ec933a69953d70ea454a3de5aa3fd6ad43768d0b172fdb9bd4e95302a27569df98ccd24be7cfb4092bfd36a6d76e3bb61a1e3e2df30eb5a6ba14b5c1d7022dc445a9c5421c6f5ec886db90206a527298f4ac923a407bcda27627f6c1c4d3fba5fa170a25891aa9366ca46fbd40d734db4246a504e9405d6b6d46b88245996a182c91f6a7544f4dc6f9b66e9911d4d889c0e89fe4b02fceb6416d27ead9472d1051bf5b3b8487006e7aec80f59a00d67cbaa0e70809482c162942eba72776f5f194c1c6f906cfdef8a567206cde8068da443b8534379ee4e7ffff2ed5b3009d300f80412f40e5275e7a12ad989d16a81100a05303dd73b1bd39b18fed41644c2327ede8f8ffdab2c7084b9ef82f657ae2ad8292084d37dae30bded57f89c5c1ed9c742dd1675779680f52722d2c914904d6636f6587c21dd6a57425e7f5314f97c6009037b85c480b3250ef57d117e032d3db99f1e26f814114f57238f3a3e3bb68665c43ea80f48fd0a25542265611bd9fae64a8950df2d865b775bc20bd5a296d0db82e77716108736eaba557f2225f237be19c107710a8d054919ef830c72500d840daba77e6b22af810c797762fa241958e403b52c961929df05721ea8d9a823968fca77771ceed9972727455930e3ec7fc40ed20f0ce65fc805329effe43523a7b46a06a0aecd087dd2b03aa72a9620c12b85a497e19182c687aa980bb9b741d2c37d24a2fbb95303832f04b9fac643a03fdeb0f4938c745e10a99d52f14bcbfd3b4b11354bda71f83b367ce09753f8e93d256ae6a38fca01e2d0a6e27bc654427cf0a35146a6b41cdf83e6213274ebbf1dac8985f33c925facbc5576be691cc93bfe390d2d1d1a8b120e8b129d231d7afef0d1b79e4a6444387238b6ec61bf775ccc6baae54f0f09b9b6c91655a8ecae40a27eca275ee8805f3e06912df5616d1094e281e4ec0084aad0d0db1db845870d7dc811fd0e74ba0c13b86b456d3a00574da76315b35bfcc2058d78405c4ef659b5ccc8df2d906261964236b1cd0ef84d1f69127e228a561b1f1a1e6a72c02c9094d9729046287a9368e63ffc4f494dd8740dffaaabfc4b049c8fad55f55ffb3fea2473ff047ab7bb3c28f419f397db77d9afacbea374b7f859d580ff9cd4313576d1de32f31f4858792a0be74e6515e42abfcb26a078d7d1f1b0a845d603d61930fb0511fdba0c60a78c040db157b13b30984025413523449fbedfaa30a6b644096a026a63ef86407131120ae89391f2c5dd5eb2a73d6c15881ba35ee9df15d2d47dffeb6b220dbc8348979e3bb2bc1fd3c26bf4eeff253257775c69fb4f949a527832b516da46f931a2751a961e8d595bab753a5806a944e51d51ae0d528ddaa7ce1610a5046105de695bf009fa4bf3d134660506b14706dba1efd28408c5839ee191ee99f253138d453128cd1439714aeccb3fd82c879c53b0c5500db6da45e44eba8fc2daa33d6b0028b0bafa44dc38dc4166511dedadb4a5ec9e2a7f0031b1526f662fd39125e7fb110c40e9fd0adc4c60fd727d9a4360237f7918ebdacc9e5a4ed120bea8fe03619d64883c15edeaa9f2fdf21f653b29a274f245eb1132d9a546a1dbcc901596352e86b566944cf800c9c7bb2892ea0f7ae965f811a03022115622df13c733addcd3e9147a776b63d7652eaf5cda6697a59ce469f260781234dd0c0e6ee1804d5fe93ab58a2480e5f7ad51a84216d9480cf58a383b4f816c8713156d79ceec6d1b3b6a108a06dbc38dacd8944b30f75c60a4992d752744a312bca0f01864dd77bcc47ea0ecabdd80b61d9e6aa51ebbdc480495c5697c5ab958bd1d46f36d287026d30c9010541418cb8d3920f9a34cdd747dbc6a4579945cd5094b5b854a9285b7867c402fb03462ec63e13e656c7769cdd7dee0be2cbb59c5aadd3123b0e03d4f00fef51534061572383805ddcc32a8845548b518ab4c1ee539970c56c213c4b06200f60f57a83f2374ff063f3eeb7a6d928addfdc06619c543b1e6a26509f1b376d0f2db640a1223f4720df1d7f082432db639c0464b156d15c5a53f4ad6a35513fc439dac0c24dca0ed25a0e3b1827adffa09043cf07ee21717c0dc9c56b5e79c6d9d254b2ddc191e804bdb473145d4705137fa007ce2070f4d4a30b08eb50d5bd11b98f56e85f6c5ed417d0da1fdd5a5214536a67e67af009b5116132c882d6686f74db45e08ba49170e4932544f1c42a8dac34d563bc61eb71fdb24b551e5b659c50f81217af0e6b22adfb0b06ee0ae07eb04168a1af2c25bbd334acf35c8ade049253c8a118f46a970eaa6c3be7262c01c5134a69be3b89f169d90cca0d54812ccbd59c382d2715cde26f9afb0f99678c06f8c18b1a53fee6a97bed68bb823d914db07d18d43bd20f5f3ecaed8b3daf5aa52a132defa91c6dec5ca4e0f5d892a69a39b0514353cc83c567aa6018fc2d82ad546d6022fe0f9c8162c359ea29601bb955e8a18327430810c920922712d914c734d93424c223c28a083c6f9272e2e867de0e8e2557e80649ea202845eb7694092a18072b0f8455c12b50d071645d2225936d55515a1c1b45c6fb0e763d2964670f8139cd1464e674682fe3ad60601a8b125e86fcb79cfece40db53f0e3c652ddf0b26b23cd5ca11aaf19689868b40b02c7838ed5b020484b40168fb0ce90a5537019c2c2f64795900a369afda35dcc1a220c2834ea2ee293a892730583e258a08131038b58e5ef179c7232a095b41659cc829aeed44f8ecc6cdbb5983a957fbe6ced3c6e8988b059a248dc14203d1594c437006b82c76d9e0b85624038a3d44fb3b89013d83887c4a7fa21e2080025c7878bd16985ffc99d18498a373c801f08f4bb908c9ea5edb3fd276459a048f71074b658304c411bfa2a50762764263eaf0f53ff87b37f1815345e0c32ea3704471217ea4aaeb66ef3c00762f86a276c7eb013c1fdf4a05658dcc15c7bab7b7546b11d321dc8b2c5d79ba3693cccaa561dada05941b5a2689583574362ee2c6cf158a9571a8f35d49ceb935aa8111dc6430b61663012dda0f7c4ce22f48195fd5d813797232c1db9ef79339037c8a35170c028516f81e7958ce9929941d1e0536196db7f211c02313e80191d0422b1b3a195540a71f965baebc60d714c342f928769027ea24287c6b8da0d55d0b211ff636c2ceef03fdf04ff0331e3a3e73f2f5fc903a965623400742eff6f7722928ffb4000da3bba24e3ec30b3bb7a387e6af9333564e34f3e204f53a0bc7897aa3ecb31a6af0642524ffadafdd414011963761bd936329904b4b65e2ffdef1a9d59cdf41891a8dedde485e7bd8916ba38ae76a5590323927df5ac010b5836e94422c22bf57e56054fb5e3910b80fe2a2a648a5ea0ddc5cb8ac5ece999a32fb54d6594bda0ca65ee83e29861c4f546192dd9f6ee84059295e440ab1b3e142d0c332908aa78face80c877eacfa77793a7314b91795660025ea6f0cff98b7dd6ab37a0ce81ed50865ce868bf28fddb0b71a99bca4fb41af540966f4619de037d9a777356f2e15c29484fe72340e2af1b5cadd5875fefd8670ff876f88849e58d94e3bd2d1fcdd840fe807e16481d1e03fee75b721e2ea39a9ee0babeda53b69587413dc7654872022b7c94a89064bd1683ab25b0653dba6a7d0ed10182cbaf1aa337962d263a3b9a80b9e6f3515ca289813595bb6e4049b96ad0582f8e348c6ee508c4a6933a572ebd830ca505bb2ac8c7d64a64f51809be905c018538549a0fb291ba50f5349e4f38e08818bd57fed5ba74d9fa00d8a062b0a6225e3778409cd969eaed7e076f1344e8bb4d95f1c045bb84758020c4b806f51391af68318ba88b0762d9e33f10d7840d5f2d6d964003dfab8772a98415cbe1d312d27e179c561d169c298c64ab50215d4efc0aa06c02a13f1d641826c51e320883162a0b34f92984e82f53e8691a238a919e1873f52c976f630c82b1d72e29010c1a775fe287c1c5f74cdf5b11c4b42f9bf3da182a1c79408f1d1920f77ad6167025a9f561c59383e73618978d5c7ecf3d11a242b24fcc9c19b714938e7310fe02845cb68d28ebebddc783bd261c6b1dca7de002b0e83b46a1e79f1b2b75c4dd26f38867a0098f18db72354c5670ea9923e222dd335332fafffa3220a8a34e3b2ff84de076076b1694876bec50413e9d4abef21612aaa0a31fb291509ed43ccbbb6bc2a5713db695809660d6fd0a9fc1fc02dd6c58a85daed986045b6380096a1f9a2393682383b560bf00ee9f9757e329ae74bbd6057972ef6752ee0dd6355531f64d010090ffe1669400403356168d63dd53f276f64880444c76ac38a26977510f633818c459d6d45fc43c6ccb8129358c1aa606e5f8f5e035cada82a08a36b568ebae11d0f15421656a245c962af1ee3c59c397bc55dc6ecb9015ffc8cfe903befb5421e21573bbf6e497ad38a3af7c7c66c96cd4333290714bbb306147825f1922401969a740ac20e3800d67474c0329484540c42db40e5c9a86db44bca76a91703834ad20e8646399a637804e408aa01d9828e454d4c2b308711011633fc82b59cd1bfdacf1fb80088829aeb4c2f4006a899dcf44cca4d5030851583f36a0382c1ea4e00b8f4446b59b9169400b31d5e96af4e355fab1dfe45b7f1993eb7683ffea13918492b7ca7556a5742d78a673aa6ec1b7fe5a1a5b349e89931dc25614ba11c5caf9e1ec7ef66800293c18394914c59ff8f8e1efc8de432acfcb85ed099b273a6b8a0ce7f41d8fc970a319049908a8f8f52be850a623b408ac7ef01e5692da04628ef80009187021824e91ac11aa0802497d2775252086fcc9482a7c7940bee4829020a40a4245137ea420af2029fc265012240a740251814b819ea02aa44b874f46c83c3c0f66088e0556a1a2c02a283d705230145cb478777abdc873041809f94341d161bd1ed9e4498354d2a0512c721c866a8e18d5de379326b5c4bc4ce57775cefc9af6781ba758a41c4b9121b3e633205e65b440a2e595d41e66220973af23048bc625cd0871f5d6327ff54ba79261e1419cccd27617d032eab6a44152ea92097840bb45736dad1fbc04c917f0676113b7883af10f463474097a0a013bb22e2743bd773f667cde8ee1d7138be55660ec88b263abc1141f8f05e6b17d7921f69e4e248266ad42ef1ba9e8525e1cc4a78a31e5ed4cbca39bb05e3a858dc467f8df2f3ccce9af869ddbd934d1611c42d8561fea52135752a457be1a2ed46d7c80581ca59e13256c8f5dae7d01f0b988914148d4fb651813085dd0db1a28bc8475694f0f7503b5d2348936a09d873c03b6e9c34b945e8142f56c46e7a10b9651fa6e256cfa75930e5133a0ffedd51d7fc87ad1299bb8b5f0668694e1f67a14292a12b2e304ca4f1bac870bea86a53d09c9459d86304b40f1e1a256979b3b9a12a96a196ae0623c24ad6a6743c348d36217f42987fc488b768f38d0946534a551a53733afaf856714ac68134d2e4f6a748ce82bc428ef7792391a31decc44a8a61c35036bb5e5be212625587f4ed487921df0989864313576d06a1131820ef1d4a2e98626613f21499f7071905f65d83c0d1402cbc5d84eb0a783f284c95488c0064411274e1560e05739b96c3b047e741ba08eecb300a6d882df07167489a5acf32790a1a8ece46b218adbbad546195753531f4201ceddb22f5263f0b672dd42bb5d061ad1ad892758dbfd97710dbca31b9e58ef458cb058fd9c53c6258ad34f040e08534521aacdd1f31293c51698b039e0a827061dbaf69ebed0bed15a912a6a62627e1a304a3552e0cc32bcd4c18f5a53780255f533e54e91be95b0f166b4ac99bb262290b03297e1bf0fee77bc5bc1407ca98a523fd0eca75ad0cd94c467493a8cb04143ecc2928dcecba3227a61dc0cd354703dfbb898aec4a0ac597c591aa7a3eaac451ae0e60438640f2438b910c8092f145ff82f2c13171a45ac4255f965205d25d9417e7c3cde6abde548148d85ced59a63be31f3f12df0dedb742e3f30bc749e58cdc6255ada5b2f52faa8722d191f5d345655cd78c37478ba472e1ee19ceb3a7b56b0d7e60d35d518705b16a3fc06fc08a3dbac1593a0220f5396177aa39c3b8cf0993123a8acef5c3d9ca066aad2ffd6f461d47215a1f02778854c453cfd10bea05c7318bc41448d5b0be11e9d3050f942207cca4884eb2f38772bb8c42490df9ec9c717adebaddc13d7da822fc3311983902b0825beb71008e42b7f4b7bb376f34b160fe089f215047a6d96e532036b56288cb59ec2439a3fba457780e3e83e5aefb7513be87c99ea2b3c74178b22404a628de7a258ccfabd65b91d46242e255de97a4ed714b055f9b9a97063777d4f7defaec51b07d5e45d3591808442bb2268db138ff5064d5de5ab92727c186a8f5db3a02f68a2c05e9273d598b054911bfe419f74265e93f07a57f4b88f176444bf44870270bf1be51ffbad7be5d26ce4dab2bd82972f54b94b25e696cd3b8e2d8edb7117e613deb944a50689f10b1c5b31500aa1aaa2d3d9532c2475eae504b390fb478cc8d4517b7857f8e3612b09202f93361cfb55d566e99dbb9ea6164ba356203d121e079009aae2380d5c772005a104a3407c8531430bd8c6f16f85c33f11d13318771ac2bfa961b5cb1803bafe5b3789a8accbfc2560b67cf83011c75b0d2c3e5dc04e36a5c3511349c75b9dd21c4520f98c68b3ade8b02b743f3bcaa7c9bd837f353e75fccb554a0f03f21f25f6679795f1c63678b867e413105105061a982d18fc80f8c95ab7e5060c35aeba01ceb65b1cecb9d3f6ebb4041e6bc4d6c3af0b9cae154ddf6b6490d18aa8683589110dc1cd1985653e86a4ba95ee47c8591e275c72389fb2f10496b4a4d8088bcdd3fe66766dbf81815b8a66aac6e3f9818c2f20d149f0504d5857cc7441509f5fcd81e7a03077b4b97577a87a0344f182328b4cd4624437ff5008e6d9329f140ea84da2e96682b0f9e36b36cc367ede9b31bdd61f60dc86fc3633baf06673fe11723e338098e94defe159de1a319a88f3081f10f7d164f17c81201e49c002f1b857a56f06e4c2a3ec0a430f32e87227c02fcd521ab9df4509916b2d1195b1744fe36379f0f52d8b6fbb766f814b8c7b2e0598d160c4cd5fd4091a2db0a84545f0ca5fec66e6829403e06972147c109a4be63357edd473f509b69a8cc2bd5300f52e1f4305baac2c12be639276965be6f9f61f092583228c925721ce08996423f29bce2d50a8670000fd34fb99d35e7dd8d8d25d52b4794b753ea815c1c5820f29b681bc072ecac42a2a1b8a57b309201b20f694eef5aa325140f7c9c53ac5c638285a57a62beeb6a940864d875178e81454a4c39febf17bd742d59597c46b201a874ce3357907529dd7be6d4110b29e90b3a3aa778671cb499d418dea68c8c6a01bb5cbb0688b27049d909ae73e83bf98a6d1ba9caaa691458ebb801de100a26e1de1db95235f2f5220b6b19c64ecd043c48820309ed752399c6af4889a7ba8cde1b20b3910de738f0940dcbf72a5c11c7f556ca5d13999c7b3ab3fba4cd273218d87de11e8b7d89dfef642e89bfb322ed89dd59e6edfcc9dfe919fb9a4a6586a3270bdd7749e60db66008418f2c891f427d04d0f6f19e81384e94a90fdb15aafa7bbd4bbe3d0b97f33034d452546dc190db665a3171437351d0c657639527b5bc133fa1ce1ce3a7f192c479654309f020a63321198c70d46152400b55e3df5bd6f42ae3de1e121ba127c16403720ae00a7810505bd0c20088c5f002e03cd4dd6e4402423bf0da6c49a4d15598cae65c1f1c5b48f8e88aa3a1c728b566831b2b43388f97942e52f77e72cd6201c57ac4d6de9360f067e4b14cbe8099f4b85b254a9d7d8d534c3820d54cb80fd05f2e1910fe4066843bbdd136e8572650dbacc896185c255dd8ce8dbffbe4b7c0c5d55e73c997863c357c9932aa9931e028af97c5422bbd6c94dcca73e5ab0ff62f0cd7f5132ce2195afbb3959f229b2be1f9ba8fac3ba9bc04018639ccde0ee91614f95946c89b3d9e414c9411535b0362484cebacfb4e096e03a2ef62117ad52d821b185b9954c3f55517dc292e307cc995c862bf42318b922225216d39601f06456c16c3268fef828e76dd7b29c2bc65aa847daaba69519d0f89495e2746eaf9e2fa525314f79ece0045d6b32ee6ee7e90428df9b0e05f05213a14e95ab525b0abbf1bd818b58170c8f3d99dec43db92051ffa3dbf5ce44659ee4beb1419af24128014845ab737b52ae56d8416a291763b666484d3561c7a5743a0a0f59a8fd2fe3486f52cd36b179bac2c15925834f5fc939a3f1903463984eec490af812ad5e55467e49eabfe959b45ce6a87e8817f7e88bf7ebc7da59f266a070447542b9c325458f7b7a50a1e747becd0898e4172f9125bae641c8f0dbfedde824afa3f374f738e087e09374104b973a840b00b6973f6b7b467787c92deea2ddd2f0a95bcf289339c9cc1605799d508ab36476e4f304d71f1d436f4c9098bcbf89cbc773fb47bd2864f41c45818290e2baeaa8f150a4a8004d2b68a39a2e39b49dd10a2e7371c01a6dc434189a35c9bf7f3ca481164443c5f73e2025f386376f3dcf6a4ca9a9b9451926a0203c9b05be6d58b1d4fa7903948c7ad05b52ae7d8bed5539360a2c64fc14542fda9b088441845de5348849fea00c2642918588d813756472276a5c974bc280aad5b88e654ef5922a79ec1550adf89242cd1840fef0c5341fa1a01f7d47752b6cb53a8391ce25596e69365b13d2e93663e1d790498c9836e81fc575f686f2d3f46597060e4a013ec79b9f7c853ecce5993e98df105c1fc51e1c2e83eadac9cd05d9a84501717adcb714b927f61c8fa551d2d1dd2c92f29dcbec1710952fcdf203dc5a22e61725e0864b67becc800f79eff2166712ae665c6ee01b90c781dfdd2a879afa73f2de212f132c7dd830b3a324d8f950c014ddab5f513ef1b5c467e7eb02f50bf890f0eab380297e5503dd7da6657be7a05f660e0aac28306186a7f69a1d5d105b84ffa61ad165a0ea59ec403c9656273930c4af4abf65543fd0edb2bbc75eccb79cd419e038adeb218264faca500d90c7c20532285d397667eaa9235917880b606072ec34c0f7cf750a1a51a8bf434112f20c45ab8e3298aecc9f8b0b15801996d5e920b5bb8abb7faeca189bf2895c8d903199b5d8b4c51822733e6c6dc3e4d7d9bb93d5954357680158ca077bba248aa1455f58f28003d8eb7029735a65f8a1c7ac7547c78ab34ec9ac7024004a8aa8ffdec87f83da14f296dd0f3c2b950ead5da6264bcb8f2ad03704876a01c797f698aa216ade644a8173bb89dec882013ab0432d62443b1a753b86ca4e624f5b5a9ad14083ed0ae12a91d2d7ba9c994500664718444519a99580981e6481e0a4234cf807f855df2c8b4b8b9cf6d6d999f2a4923029cc968836a1972594124a265c8551c0abccb5aa9440d20339d6d00056888c41b7ecd1bcf8872bdb199a6c3a57965443371810c020fc090554341846d6fa5adc694815358b5416d1c9b6020069ad838400a9f10bdf1606b8a158e73f75ffd1db2cdd0966bcec51d6c03db7f5915e2751e820e06243597fbab2142fe8b26a01c0b34ddc2eb2ba661b1b3ed0584631e1d14d197e6d67993fe0418db573f5096276dfe2c5960af90d96a11680e26c92b5de7de3c6bd3a08aa6044bebebc6f4ec4478cc79608d888f4f7d41660ba65e96714c71acccd554d5e57b48d3a0a3469dcbc7b41e946197050308b0b0fb242936fab5b9574a8821e64afb76f6eb9e533d83d71ba38b15c6e9741deeeef261e493bc58c9695f51f43b2529c16560fb97787dd3b9a0f9f99e5423a8b6138e005da611bb0f40883bcee0ec54f20b9f0642fabea7fb3d9db2e8110f704c927182bc333209100aae2cb064416533addb35be76f5fe73057257d4876f22dda6b971106318a1b0b3ba25d7f4f439a333e3c57e5aeedc24fa4edbeef1a8ae0b8bdc78cec72cf84e51aa8cb158f9060881a740102efb31e7ca2e24d23ef3692d9c733d0e070df407b92d7a0722d1bccfa933b647451138aba66693ab5a197002c6fbbdc1d4b57f171bdb943c02f00d2f953b9bdfb5a41404774b4ecc17e3d3ca7715237bd02e0f085877311e5c1cd81b4a001111c98508c7fb0830c7d6c2f086e2e7ec7ba89e5371ad12ad31878bcc18c3fda65869ff4b026ddca14e8797672bb5fcd88260c7b41f3084fdc56375d7336b7802d7fae569a3e5e410e0414002000232c28f4701b25164379a66b4b182145177b28806b87f60708c88037a6b14659638c6523a5f8d12e67fec9c3d6d20d3ff73ba60a17b13d82cf68e76091d08412dad205d6087150de4e57ad7377370001bf3d142110d786b0b8f7650a7c5679df20831fbf1667c63b6c5e833bcaf863af162d32b21a2456023e15447c0a3960b024850330333333333333333333a3bf52bf8dffff636c516eb2ef3620640612209599999939e517c205fcf6635bd399894f67263e1d7409a20a480a0f0a6ee78929446b848f6367087ea78b5dc48f87d6e2118267f9d6728f479a24c8088293c7e766d5f10308be07d79c3972df03193f70634a9aebc6e5ccc7df95c9f0811f621d1b19d647c8e8816b7393ee038dccdba391113278e026d10c314df64d9b4645c8d8812373f5e993a64bd963f0042143075e46da8f2bb45848390608193970d2a6ab2398e4a011627690818314c8b881a3a216dd93bc8a830c1b7861829cc7642ef21fd940a741460ddc1ef8206bd7f4464ab73268e0e6987dc37fec6d697f170b0083d8c0808c1978a92eedeab591210327e639b1ff49460c9c0ef729667d985c9001032f0fc587363769564b72f05ee174e5d1a87a1ef8a654395ce147b21e85889df46204619cc08b1a374e184fd25ae1e78890c73ef848791459133858e1bd4628190bf7d1a3b60a27e56041ad625b44cbd8d852859bdec736e695c7a749852f217fe72f95ae4817e70b2f6a34133850516edbf461f26c6c31c729bc54e12996744b0831c2e430859fb9657e9046628c3162636b4be14f46d230f3691b5b67040e52b8b94cbaafc27d3ba78b13dcf8826a081ca370720eff23f59ce4dde31285b7398f3bddc7594a33571d3842e1c84a89bf774baf4b77e000851f2e4acac3f6984f60a12d669994493a7078c2efcca8511aa25530b7135e857091826434ed9c87e1e084572d6335639b834886d7c0b109577cb03977e5520d1c9a702666b35e8071e3040ce84c782d3e417b2c79606fdf7260823c1e747f9ffb28fc20360c3157c786210ca0fa828b131cc7253ceb4dad7f2ffb92c97258c249f2b17c2ae70ecb6922382ae1441f240ba721d8050725bcd03eaa1ecf8519101c93f046fb44642494849b3da8a7f81ec81109bfe7526bca1f3de14adb8203127e8ff7c5f1083fc9a61f7c5f49b86fbd1881026c182fbef0d3c505b8f0e286039cc0e1087f24d56b75e3c398336d84b39e3ea43f4f3ff2f459fb030723fcd8e43f3dbe1f5d6c1f8bf0c735659d613c42844611fe47ea911f8944d9bf89f02ee688e9246f0eb5220722fcf179ca10f2721cc2f174e6e3d6b4ebb18673c06108a73624958bf263935829849fc5e76c345a0e42f89b255aacb05aed23eb3806518270a22fd27c70a505bae04b7004c295ce83bff1b9319b1f5e8401082f04ebe81ad27f70ce63f7776ced07af5f7b90915d8dc72901a9b1b71fe0e883e7294597f470f0c13fd3cedc834b759939f6e08f3475c9657661e0d08373dd7d1624f23005a9e4c119f9b3183c630e3cb8315da650f37f954fd93bb839e2fc424e559b6348f1c061076f6343fb24fb20988497c051076f425a0e3d68b5d61c2470d0c1fb414879dcb93e82a90f8e39f895ba327ef345f10ccbc1e9c15606b909e3e087b09db279f44846ab1a6068a16ae080836f7942b3533a25e6ce1b7c8f90b3a71ca6b5730f37b83efae0d182ab86a70dbe8fbbf2dd0fc2fb829505071e9016003470b0c1eb711e661e5a1e6bbb8860a8805400f3c0b1065f354d5d84ceac0d1c6a78fc3d8ef01f4896230d4e1e664d99e12d1a98249a9369d09833303eb08bbe31461e5938cce0c677c7ab8f63488f7519bc9447217b1c1123e5b78d830c5e9e8d59c3c7233b8df018d008f5f5a907036e90e2108317176a837c5ab5a86c1738c2707c49df60f0c3b5e7f06969f39d66a5058e2ff861b9cc3d69f644eaadc0e10537e7ce3153a70fea1976c169f53c5723f9fba3e60b1c5c7042ade74d3e95c7d7291c5b705d7238edf2aa5cdf6bc11fd8df87c6a4b1297064c1574fa97cb482646ad7a0c081052ffb20fc9002c7151c2f916816da59426bace06b64b5ca8a1fa53c9a3c81a30a8efa48a366f51c0838a8e0f78fb7d56436ce079a0c704cc1574f1d9baaf375871f2d05673284d8f6bfd23e9089c0110567637765c859127040c1891ef9678b9a1e5c7abc170f4601c713dc8ee9bf7b2d6c4d8c392a38e90587137cffa1869a29dfc6568dc7839065c18107d0a04183c60a0c590078c0d104370f7d3cec089130c1b7ac21e7144e51702cc1a96c0f3e48a79ae6b70664c180a24a058712fcac937c5935b38516364c36802309fcd88731b1add563090712bc3cf0358d50977ce8e12d701cc1ebf4242169d57ef4af11504faf96cf302b492da9388ae0a8f8a6c550411b5b6b1be063303888e0f9f4403d5aeeecc16d6c6c710c41f9d598027008c193cb79e439698a6121dbd8521a6b068e20b8612c6ae40cc966d2a0d15ce000827767397a1ce1caaa35c6f10337591ea5aa5ff651f9581b5b5f70d1010674a1c506bee0e20460e0f08117a2b9e6b160d3a0a1048e1eb8e2e30ef36c612acce781db923a85109e1df8a9e436e72813967ea303a77cc54aeccf81933a84d9ec74c1819bc6f2860a5ae9432a37f0bee27f368f2636f07ad0a38a32c9fd34a5066ecae639dcde57a3a934f0a3a79c471ad2879d6370064e5c46899210b6328f93815b21657a33d23f248b811355b307d263b1c8546d4150e0051747035d5c200b06148103065ee561241f85be0fb182478b1b1c786ca1850d060821c62b8ac623862bce297d14669e2b37b42018a856b839524f76448a1f664b0c56f81721117c26de6359a87c1063154e88a5268979fca92c07093154e1ffe0529aecc195cdc9a9f03b468ccb3e4a7f31a6a8f03d798538cf1872cc6711629cc29b3cb4caeda9c3df078f2186293c0b93bfa42ce4f1307c4ae1e74c21ef9eedf615b6b1f55eac0d300804706390c21fd697c71c62875f1e1863146e4d96f071beec093144e19be698e9935078eb833ea930a13ae7b1a0f072d5e577c96bd7aff984a3f11b346795c852315e50208627fc3cb0dcdd9fff52e5f71181189d70aaa2fa7883d53138e1888795b8c82ed7a6a141430b0cace04c6013ce660d898d31347a9aad6b1043136e18911f6b8e983d48f03c608b1899f0d24a74b3083d88299f8dfd189870436cce937531e754951897f0376cb667e754ef6a896189f3e87325ab347725fc51f644f164ae6673c6a0c4b59d9132ae2d53d5d5af2995ec7b45a23a2f624cc2f791dc8d46388b8b1649f8aae933f4a74a24fcac31fa7388f41f230d0947b2bee6b753528bf908376f082934e4ec957fa023fcd4633b7b8fd6565989d108a7ee4355cd765d8f633118e1e40dc1734f5d8fec47c5588427777945f8e3fe8148fa4ff4716f12e146a648497945849b7b9083f838a887b0188670b53f65c6a679fa486b0e6214c2ed3489ec32de21a686106e1ef4209c8ae5b0b941b8f92de7ce13b425b54c338821882e6d0cc1626b38107eb220399b950f08cf5be5ffd268d6543ffee04d141953d7c89ecef683132bf75862979c440bfbe0af0499c80ae7c9e4e318c4e0839ba3c77bb81ef7e0786b8a394df841859cd783df115eb2d4da0fd35ff2e045c66facf7306ae9463cb8e152688ef97d1ce1e371072ffb072edd954db33d3b7817b5b3adfa78d0e38dce0531eae0a43cb692b246ef0531e8e00f636a788da231738ee6e0884f34b7f4919c5f1e72702c5cfa78a75849138b835766353eb67049248f8683a3f94f0383186f70e4cc37b95dca82186ef03c2acd6986d3d0d5a30d8ec498611a42a37bb2a420061bfcf1ca560861977f58a68dadb303c45883f7ade111cd7c52ac8e1962a8c1510bda11f30fd2c7fe34f8752b9a278fba6da28f062f6b5676985e4d21f967b036a65c3f0ee59bc15b1f4aa827eb94c43f6570ee42fce822d705ff1c3278d162920937daa539670ccea9cf6db8bab6d9470cfe45d0f4c17fa6bbec230c6e1ee4d82ed2ebe38f1e60f036d2a7c8101f4f92cb8d3270328f448435915b8bb0888113438f3efd52f63a9b6001033fa7b50d3df9c7dda31faff03c936695abd015fe8a6a8fb2438c98529a6020805638bda15e63975ff08904c00a535a4beb34acce4db37e74db121a32db390f2d6cd4382cd0028c06e37471811b278c08086015ce5f58c952cb51856fed438959ac7e62e5a4c2d9f6f0f158da0779fd820a3f85ad8b58296415af9cc2b799bb1fd3f023c921a6702ba4187da8757e9ed3a5f0eedf63ec339914de6c5d964d5e3956b4a370b4b37556736f715f14fe49f2e879a8d150b81d39061f595a41e10f6e738f731e8934577ec2111f75121f8f2d86f8e109e77a5b32870976c2b94b3f8ccbd82ec1454eb8197a98247767a42b71137ec4b8ea51901fcd216ac2b34a6a95aebf4c3892a3a4d58f0f34bec3849763ecfad28f44d573092787c817965c43e58e25fc61c46829e7a41934a612bebbff4545c775968c12c56944360937450c79fc9d25322c25093f8cc4aef47d24bc983179e5411e7c6407127e92c9eebb6d37993cc29388417da8227eb6239c9cc1fe47f73ed0781be1add824fb71d88f6e6584172d327ace70116ec8e13187ecd10704a00837fa507aa816325c784f229cb48fb12c5410e1d5d90fab7a3687707a23e7eb8dc810be4d8a957c985de522a4106e55f2ece38308219c29eba1cb85a4bf24198493e6830e8b1e86f18e20fc0e2b39c57c04c2d7f0d321cdcaa7cb00c2eb2ca129331bfb92fd07b75342f8a7b3fde0d468e51f8b364926dc873f250fb6c456e6833f98ccd46112eb0729efc18d4bcb3fa137e4b2560fbeca66da853063f3c983132115ed7b90e987321ebcd0e67d16be6617dfc1e998d17bd03d883539b58393529692854cebe0a50fbea47ad6c7792c1dfcc8f441f8a8ca39b82e3596dc559483bf1eac2cf6944dfa5c1cfc488bb1ba520e0ebe868a72519fc27c907b831ff2978f524cb307ebb9c1db58956c6abbbf52d7063f68ca615ea22a6b3a36389a8739848e9bf08ab1353892de7d3c0e57d192626af0627acaed69b434f8e38b593ea4081b3d6668f02a95e4cc57ae31fd67f0a67dbe724a48f9376670d3754930c9de25923278339a244cb21e454a17199ccc6ceae30bbd726b8dc11f45c6a09e43478e6189c18fd8a33673efdc7109833f5315d721f64a4883c18ba9b3f3fce02fb825e3834e75717dad171c4b96f17717624c77c1bbe8e9b242ca05bff27c7a892509600b6e4e3953f34948b19d09400bd56dbd9c57a847324f5799bccc4d2b02c8823fa18752c9c7c3141dc358f0c36b30956895248571022eb8888071000621802bb81ac32d6e3a6abbf3b0821333f3c0dcb30f3573a60ade740f93c45b4d05bfbe07f9d3b73a05efa2fa5f3c4596cba7143c0fe703ed61555170d4eb2452c84849d91a55e78b1570600100288400a0e087a514bdffa6436de5094e88a924dda7fffa459ce048cc6069520ab339a69be07ff060d9471d62ac0d33c14b1783fd78c74b70d25bfa6ca7d049e35582d3e3cabf8d2d14948075110248829787b1071e2a6b4ead3e90e06b9f99c64efea391f808be4dd43cf89ed708ae9a471e48fa615df8b408fe306d2d48c5985131480437a34ff27c1e5585b00dc18b357f89151af3a847d9d84241096a3c395813480b401f04200427a57f72c8e358c9e307c1c9833cfa98d2493b8f870182b33e13c6ff26e355f303e72f48688b9bbc21293ef0eb342bcf8fef81b7f5e1da57a23158080fbcf1f1f1f578d856a1911d38a1c652a7b15807cee590e347129b29979b032fa5cd9b33638a034ff3fbfae44a16c907dec04b1f76f4896c1fbaff459b420036f02247caee3e8aef5c750d5c49a925bd7da1c7bdd2c04f29c9e7d1e5f29852390327ffc55ce69195c7bfc9c00b9e3ed7f43831f0630c539962c347a58de0716a3cb6d0c286492f0400833d47f8285c1e5a5ee1e4f1e47513b5719bda15fecf49f9f7385274865be1654de96d36b1494392154efaf1484e32a5cf53de2afc9cabc73f4c935785efa1828f2fd548b43f154ef6d8f60d793c96743e50e19a87fb18ebff711639856f7d2979d77f9030b229fc41884b0fc36350d9be14de69b5786c7ac91f6248e14dd894b47e22212e19851bf2859c9456886f5114aed9fc98c5ce42e16d488996db6653f80f0ab76b4cec22dd2e3aff0937e6de1cef616924329e702425471ec73cb25349e984e7b73e2226d9197d104e78171b3252ca924df817b2d2fc4cd27c6a6bc2489dbf33c42533e15ab498fa4b0be21962c2999fbf10cd1e49085fc28faf14c57b94dd23f32ce176956ff6309570dd3dbd67e898c7121e257c93109fee3cd6df9f842b977e10bcbe8724fc7ca63e1ea9252312d9fc4584d9e4cf16594706241c4d2f6ed3f661e7173546d08516253023b871b8287b84df79e42d69eb4759e5be51630b72c200a34609b63841d11a41175af4cb7084a361d2e3458dc709c39c7fa2022dbe8edcb8800ab4f8c3818c46b8d6a13eea2ec3dc256d6c25256430c239cb219be7f06163cb2e123216e18f452a794899c743cbb38dadb32c38f0801a8a08198a70632799aab1ce9d63b5d189f02dc20f7d20a3492c5612908108a7d3c4d083143fd2ccbf8dad0d64c100ee43f8293dcc83cfa3fb1fe6db104e590a69b1e683cb63554621bc6895349845dac9679b10fe784542889cda769563021983f022f2674f361f2d6e700009204310454303e1e7c8f031b74a559e2c20bc4e59ce4731ff7ff0a6b5a77efe6386f77e7082664edb963b4590be0faefd054919b30f3eb8e19249beebbb4f17b30737a7654b85cc5d51357af0d29aab6466f9bb0ec98393925b7d184265fb94e0c19f97b8e853ef1dbcc8a32413da7bf031cd76f02267f5d6e7b40e9e7a67fa54a9a27970d2c149f9f3fdd053cae832e7e059a5f21c234239f81dd38f3a44aadf6717072f325d089e1a1c9cb58df9473efafca3cadee0b57c8f23edcd47997783b7927c181562a57a4f1b9c1c6d7c3cf00c3965910daef4b0a2074f392eb306ff926bca3771d143576af033ff65e989982ddd0739368a64a4c1c9f21f7fd63ece16520164a0c1c93d214506b9c8dae39cc149a98e791cb6524ae6318317cac7e390f3b95bb81f6570536e9ff99cd1f25b850cde66cdf0d3e162882a8fc14be6e3f17c9c6c7e4bc5e084c8a3ba6c32f28336c3e08498ecbc7ed083891bc1e09bc488325bde173c19914db16925fc6a5e7035a60f2c0fa4479343aa0b5e68856a9b903dae262e78d9a3398f738ea69932356e788145c6169ccae33c793cb4e88dd96bc14b992b260b2125d6a85416021959f0b35df609e9099d3f050432b0e0ab6cd096e4e12d3694710522bbe6946247f8898d2daa13a00d30880d84810c2ba08c2a3cca979344ef6c218b32a8e087ba0f355d4ef96205617471821a678b2fb8d0028c1a5bdc3828f0a20b2fba401953f047e2ef1b2d861e0d3e300232a4e0b77f2e51f7e077799c283841625a88f68182bf926ac3fdf82c744a798213cd07a16743e441e7e1047fd8c33c4c162ca73ccca18c2638dae3184952c41e5b763298e09cf6a035a63f1b5b4c43c612fc41c43c1ea787b86c8478073294e0ddf738ea627617601cc84882a6beb9e3a20519487052b74a96689a2378329acb635af9b8b86d6cc930823316f2c03b4c2c8213e5ea3be5a898208308016b309b8fd2a306be4f674852e663af99065ec9c576fff561867706defff8785c1365b37246065e1e0f5e7e183613035f2447f518c42ef766060cfcab1ebaaf70b6a7674254fb817c882b1c4f4125bb3c748f7b90563897473f4c39cb6c9a346185db79d8ab1524e63dd8ab705a635544a3075655abc2cbe0a366a92977ffa9704ef24056c3f8c7ee282adcd618bd534c1ea7f0259da53cd8209b37aba6f032ff7a1e4bc6aa8b6a29fcacc13a260dfd9b9992c21f479e9cfa7e1c21131c859f7d1c5af5e289c2abf6cc5e2f67bd7528dc8a8bb1c7bcc7a15603852f52d616b426dcf89ff062c56c518f9dc71fe2097ff3206cf4c822bbc75627fc2dd7fca3d59a07c089d6a4b24b6acf6fc2cd0c96da62fbd0841f2c5ec3c4f9f5e02d99f092ff202d8698f623b531e1a7da9b85b2774b8f2fe126cf29f8e087ad25bc98563bba27f74044ad84d777b691dffd3b5639004ab8e9e3b3c8ea3e08b1fe24fcd165fc5f4cddfe9a2309a772660cd1ebc72f93130937bce572befc03127ec83f88aaca9df3fa783cc2c91033e5f1a05b423ac611fea86b7dca337d8f479b4610fbbbc7a3ed9c6184b77962e69cc35aac345984a319ec3626250fd2268af0ffe3334c089244382ae97be4c3ac929683082fb3bf8714fb1fc9e7106efaa9ce3cfa1ea70bb621bcf3a4c92d7f47fbaa0be19d8cafc6f483cce39b09e18a858a792b5bfc0479107e44fbceaadd83ce694138271272e81093845007c2efa18fc2667df0d99301849b72c8101fd6ea6fd33f78c1a422a6fa20a507a71fbc103284bf7c4e31ceec839f075152247e201f7cf9614a452b3f4b37eec195d37c11838a7a702cc66497589e265398076742f2eca13b25edfff0e0e6c18fc223e53c52c9dc1d7cab904b635ede47edd9c18b6f1fa4fb61570737c2c769b97bb53e6274f0224afa60a28fbf6be6e0645a49e2a3eac8615272702a7fdd6fb771a82bcbbac427e170f4a872f2d78a06f086a26106e006bf72cc69260d15f3b40368837799926565a84bb4a82a18001b9c9e9041b23c5becbaacc189298fae320f3578e7e38a91c4a3c796471a7cededa154f09ae888a0c14b9595efbe538ec9de33f83dce10e5073dcc36213583ab311d3c69f88b96d000cae06af430644a6ff52164f06fc2c2d94fc6e06b3013b77c1d31b8290fe24b33e5cfe3f17884c18d6411c6c35fd4250f30389a72b2bb13959aeff1056fa687d1e1152ff811e5fe724ed754d574c14d163287cdf7e3ee70c14b9e23e5f1e61593ac5e172db8e263d236165d530cc9826b21a5cc63cbce232ec182f7e3107b24295c84f2d15770647bb4d1a11ab92f6d054736a465bb90ae823f0ccb2e992261f20fa6822be12e9b2b67aa973c053fb3656b0bfe43ed1c4be1db6c9fcbde63a3e067ad9210ddc9a2c540c149ab3aadfaf1c02cf80447cb56c2f80f23b8a64ef093ff207cce93aa43cb26783f3f50dfcae34f1961829fe97d2aead2a5ea12fc8dab1c238450095ea73c8ee6fe5d129c1f26cbc9273cb9e70e094e0cd15254538ee0cdadd6f83058b4481ac1df1c34560ac94e7bb222f8d353d987dd9ed3f92082d35d7d9d3547bfe00ec12d8f9dc716eec3f228044f25c5929f942b0f421504ff5444c2c9e714daa10100c1db7016ea3db96d1e4d5c18c00f9ceaf61fc67c317d3ec707beca667ff99052c7d9037f826769f549e156191e38bda6e2a37435e13fca0efcd7c81aca5ef2e07e101d789b1d39fba4f90c5f0e4c4bb93b67f4cf0d1c38d34136fd5f0815f1dfc0f3893d96ab9279919401d8c0e998ccc7b9938f1a7851eefa7f3ad6c796d0c0f798cd73f6e8f0bf9981b7f65d3f8ea9fcdf6c19f8a308c90062e0754a35f3f1c801c0c08d169e7cfc7914452df60a825458b5455f1ec0c2157eb6f790ba10bb7b4f2b3c33cfd9e39826ac70fb247dfb4f74159e56b8d274792e7c94aaf0c7f9d2d48a8fc322157ecd6cf4e50f3ee84b63810a55528945da6acabb38c0e21446834d9157b8448839fb44ad144e487d2e4dbe6a1e73b624c082144963bbc06214ae4c758f3632788859ba065888c24b1f29e5af74e6c394eb0d45912a192267ccd9d8aad5020b50f416587c62045878c2eda8289f70b5c8a3c9c63ad927b0e88489010b4e103965bfc46c6ca109b0d844185868a268d4c0221346e30421c002137e4dc766feb14ccae3125e8819621e2709675b371696f0c52b8f2b867545890a8b4ab8f279bc4135ab4b7c8205255ccfa62194c7e8410e9b04603109a7442ea98f64a347174bc2cd56ae592e620e7d2b169170d4ecb5cecd0724ca2199f70827d5d847844feaa39c61e1087fd0036be94c37c2cf308de623738f950c233c8d51e7513ef9abb98bf0267f748e756e23732e010b45f8a97fe89ed9f3ddb675018b44382115c2c4da0f1b5b551c30e78b0dd0a0f1e8e284a182f3052c10e1c96af8c1446bb294f6218ce1c9a2cda754808521bceb939096d63e5f6f21d2b2bfd498935a90302a8ca381c72928604108e726bccd864ee5213d42c062105e48e6b4e8d79b073d04e1e718491a7afc2ca604c2adc95929487ad78401e1fb0f3dbaa8f87ff0ce34fca0c7792cd37b3f78167ad05124aa4abbef83f7661262657b3ef896928758d94943f2f7e0899c54f058777eb61e3ccbf56e41734e1eb37970dbee356aaa6c554523c4f530a4f20ebe670c3db04c4172ce8e1d9c8aec19d2c7a98367f37fa92b74f0071192c875faf1e07eccc19f0df5e951f09490918323e9c783fe41b4345112077ff340a33eadfc5c0b076f2be70e957f9c57a28f3738dff711ea738c1b1ccbdc23311fc4b4c1b9b9f4d698cb917db0c19b9851eb2c8f47216fca1a1c1fa7d7983c839ac6450dcee51482c76ef1ce68498373ed9dc137fa487e2c68f0e325aa6c87ca19bc947012d2fe354d6f06af373c552e4f474d19dc3c8ada941072b8ee4106b752a898073fb4ada8198313da6452a79288c18dc89ed83912063f72b6452cf3516f8e80c189f083ab0ee1a3b4395ff0c2d945c8f8682f7852217bbe50d11643ba0bae5636690b413b0fd3cd052779a5f5586d6ed1ed2d3821e64d2e7e939ab6d68213dc6662d63e0b6eacf3501f7605f560c11ff964ab1ee641f2cab9829f65f38dc4369990ade05790891f8dd1b9625b05b7c355a464fa66f2a082231ba6636a264c3d0527a5987d2811535896a5e0d506ff415ca5cf1846c1ad19afb49ae3ea3f283876311bce37fbe47a8227290f2353d8c7bda44ef03588864d704246c904efed8357b2b1cec3602ec157e96e8db6397279a904b747561633e74ebf7d123c11979cc77122c11f8acf058d29634e161ec14dd1de525923385266533ef615c1cbe34cfef6dd11c10fd5fcd172ccb9c7a91b822396c731b312a2c86f42707ef4d17de4df9fce6241f0a3fde71a0d01821bad42bee81e5d7dd87ee0468d7868b128392a3e70d2a764ad193cfde21e38fd962ed335d279ca0392a805d79ee00e7c917591f7b174e06de474755e29f5872a077e4fda9c1d1f1c78999ad2c46c4f212537f0f3c69c5ff34bc8dddac0cb90145a34b78fecac819f428f3226695591200d9cb7b454ae5155f398819b9255b21cbc4a0fb5b145e6808e4ef89ea1dc6c72ac0ef73e6e78618e06ba205f6ca00a1d9cf033434a299aad7505061d9bf0cab77bec430d99993e5d902fc0a8d106461711401b41175ab0269cacec9b49f5dd9ecc8e4cf87f93c4be42c4e6dce32a011d98c073e893bfdf8b076fa0e3126e0c4bb36111d558c1165f7c410a011d96703552e51c6bdeb96264636b0537ce094c5009bfcc335f46f717e8a0c424fcf8c1f8a8bb7204f1f05b6971830323e882cc031d9220bbc2aa5fc798f3f56040160e98c0021a50011a34caa3c60a6e78c1c5e18223e1f9c46a3e19b73a1fa703127e284b6123743cc2b7137f79ff91fafddae108274c3ac5ce8acb7037c277970ce132683a18e154f8f82073943b16e1e68d69f5691f1d8a70a2d38f345df645b64f4722dc8c0951794b298f3aa50311be640f235ddf86f7d6790867338f242c8f47fdf3cea0c3107e66ac569bf437512c347414c2e90b9a21997f0c4d96a183109e5bb66baa8f6cadcb163a06e16579f264b944aa2f3a04e15469478dfa20d2bbc5c6569e1b5e84b181403831850a9624caec2ce77c8118b802a327d0010847424eeeda117a94796363ab86178fb21674fcc1b3b4ac29c7f4ced0e1072f5fa52cee6b51c98e3e385222b669baeb42071f9c921cb62115434c986d6c65c18107908e3d5c871ebc8f1e7c8ae84d0790068d3c78f29b520efeb10e3c78ddb26973cea91e1b3aeee0fa559dfa3846860e3b782159cb6485afcf9bb28e3a38162aab8f6492cf18b4b155e30b2ecc71c180156cd1c505ce08ce165aa0408b1b18a042071d7cd1cee51e41d231075fa3ad271f67700a1d72f05d3a5b45c44467ad90d0110727daab6863eb9cd00107c7873ea8de2cbec1510d5e176bf287dce30ca1c30dbe6f46f113fb3c61aa6c839f37c59e6cc1c20647b5677bd285d7e0e54bf1b1e3c7e1b45a3578e929ca0f62cf59bc9a063f0f34bf86e951ee71f6d0e0456b69c8e3fb18724b7906bf071f911a42aedc1b43207498c17fe9719e187e351a422a081d65703dcc36bc6ca71f772b840e3278663f0e5172cc3d4c510dc38ed03106cf66427d948bf6d14b1d62f024a22f5d24a4230c5e1e46bee8715afe199f071d6070b2b25448c6d495f3f82fc0c841c717c2d0e105b7a3ad63fafc47035914e8e882131682bf7fead6e8210a985507177c4b39ff67882629def0e23c6a8071b8d0228c1a37bec60d2fbe06e10d72bad08202070c2d5270ccd1020359f9e8d882ff69dd96c75f6bc197cd9dba376678c969169cd4357962b2346f12dad802e3d105b13a13410716fcb19567a42f9b902aaf200c2de4d07105cf7fbaaca387ff8f731ca041430d1d5670ae6a32575c92530db1434715bcca9432871f7c56f87850c1cfbd7943feacd9bba273e898829766ece65565e23d34248c30c85637a0430a8e6fd21ce6437becab151fa0230a6eca4a781ff738e7915b1472b6d8827051e36fa080eb6fa0e00cd001052ff37978bb4a2936453a9ee067b57f3bb9920df79519a2c309be4b4c412589848607812c1890c5033c0b0664d1802c18d0838e2678f5df9eaf2fbfe6f499e0b6975f4c51930ff2384bf0364358c7bca9a7c84af023848f1dfbb349f03c86f65c3d0e127ccfc3ecadf7ff181f47f04ca6325da8444d598de0c4ea1452140f69219f45f083a40b61c43df90491086ee50b9542bfb4cb6a43208fba6baa7c1021789fa145bebef2288a1404a763ee51c66c9dc74307084e321f64f3717794b6941f389add7f25f92be78ff9e090c713ad72aa66470f7c9bbfe429557cf48cf2c0dba8340966e30e9c0fa1722b830e1df8e314dfdede289aa5d2a061d5868e1c783d981cb2ed2b11a26fd58103efa5235aa53cea0a1d37f0de723ad1d075d8c08b9ecfb136d858694a470d9c90aad38f24c5b4102e1a785759dd225d5c2daa5930200b1a341005346828a2c0ba0e1d33f05b2698e6f70ab73efd698075c8c09b174b39c4349c74ae23066ee6c8137169d527783a60e08f63ea185afb7e85db294d76862b9ccd6fa132450f177d9dd10a7f3c0a96439d65440f7a4d2e66b0c275ab2c49eb3d36b6acbe20373cb00adf3f584d0cb5b1d273ac8419aaf025b3f99846aefcf51d61462abccd8354339729f58a3f03157e8e1ee5fcb3f94a5d730a27fdfcf8d3e7978c98628aa2518aa23183147eb758adfa7f925069c6289c3caea499f2f8643cda6d8419a2f0c4d3fcb007a9c43b653f98110a3f7bcb3d6a5bcc3a060abfc42a67c8c3f868326161c6279c091a628eae1fd8269d30c3135e12efacdc155e923f1598d109a7b2f5a8c948d983199c68346d44a948c583199b70abefb3ce2d6a0ad5787cc1c5e36668c2e951cab1a256fef1208f343332e1a88fa4d67c17240386a26006265c4b397adc16e52e4e8061ccb8843f4a69be7d46a3e45650c3ecc60c4bf8ed030f953dc8aaecaf8d2d2f1e5c097fe8d2296bce779a156650c2f31fc534953a6b63eb0b2fc200036f5815664cc2a9981252e5a07e1b6c2eb4205b189384af99c2d7f25869c59c2f5470380b3322416640e2689c04663ca26874608623fcf185cb83f01f676f473d30a3113318e19dd78c670e4b29aaddc28c45b8608622dcf08390ad6e1f8f3eccc6561717a041a30b2f12e1bc87d78acae3d2f6cbc616185f7871a301529881082f76a7149253d6c6623a9871085f24c51ef98fa7198670c644d37dfe1e0bc8820314c8a2060d6614c217cb9c3ed45656f2cd0c42b8bd31d9db3dce682fcf18841346bcebbaef5b43d0c656175e30116608a2720927ea51614620a834af98ee7651895a97d8fe26b1439e3003107e5dfd5fd2b0f161ff7ff07ea266cb1add835c793ff811fb72cae3f3f17cf77df053cfcaa64bd2e341fef0c10b9e329d56ccd9839799c7e361b4ec673df8e8c1b1ca434bc959b47ce8c983e369e224548f2a42fe81077fd2798718d51d7cb3cf21392cda46da0ece0f33fc53f378e81ed6c14f93d635876a8c907ad0c1efecb2217a62fa28f49883a715717ef946233a460eaebba4f4583fa1cc3671f0c7e93fa58d1e0ebe270d2113c5737fe70d7e90cca621a7c50dfe78642d04b510dc72a50dae241f57c874d8e07576da90b25a84c7acc1d7d4223fc851eda3a206ff2cf727f5b169f0d394b7cd0473d588a0c16f1f67b710cd3ec3233379741f7db0199c9c25aa215e633be532f8f39124f5584a06ff2c56fed174b4eb713b0637c47caa7dd1a28fb31583133cc5b8a4d986c10b2949d5f2ffd9f66070b4c2fb62c65667f80b5eeaba907f3b7d99e9055ffae6524586bb4975c10d3e2adbf61e48f69072c11189b616de913ae6b105d7828f7c70deb16ea2057f5652cc83c9ede3d764c1f91e674ee9535f112c78211d7a1cb36fd0b65cc14fcb9b7e2bb7b644ade0866069eedeadc15305b7bc454d62f2618fa482677990ec876e1e6a654ec1b38e9d225e2a54f448c171db1c6a62c3fbca1805c7abd5e2dbe4830f0205bff230254f36d1298f7c827fd992e4a10f3c2794cb2e694df0369a87185b66e1aa31611f7687a908932dc1bf9c2a9fdd1999234af05462878b3ef693182d5d3e538947b090e0675665cc8f23389631ca5d309fd7a88ce0585cf4a1bd4d564a11bcb5510d1a7d22f8f31ee23b1c82b36e97d7c71eba2d2304bf262df2a5faa07f942038214797bb20a799672038ee2999e71eab851e4b337ee0af4d889c3464c8cad10c1f38f7e38b19e1223d7072a8d75c8fc2e4d4290f1c55b5cc03bf16fb3b7bc60e3c1fab88a7dd26cbb70e3c9f8cd942983a0b0e3c80055a58000361ccc88173ef79a5366a78f5781cf8a53dff0dbcbabfb68f9d53b0946303bf8b2ea824efc402b260280e87c40181300882869c0be3130800182c240e0622a1682c4f767d07148003592820362c2c162426161418188505a250200c088502814020180a074281504014160e4bb5e603032aa4c10de1c855b8b926580d5be3ed2a3f4ef429b151ca449976672408728391edc5211e40d83d8a2d3a8e4e9d90a29c90f1921c1843e3dfe23b38a14ed27a94960d9b62a766be6d28e8aca873406b304db64ff6d95d6c6035541605cce0cab57a1f7f627fc225f5ab415b167fed0efde13dc362c54e12a9e09455542c52ff82000fbf5551e43f7b48100e8a29f94443eb5933c8bcd502df3450fe00c6da5b1f2107394fe3c2f7f7f4a83a63ec5992522c28ad0050f1eef0ff6933287b4778203d3a162d4bfd65504d0dace403757aea8890ffe8dcb358b57ead935a6f09a81245ba588289d9809408b913ad662865cdae37152466f08cfe6d2f7c982ad178c2ceddbb754e24087f90fab72e57667928a2f64a4beadf22c7267385da110f18b6809bda8c904c54939abd4e4eb2d5bf8dad71debf39487229f7a9d85b1f7f5be8445d26e6be4c695fa0fc6641f460988b88ab746c47d9480e2b0e1d0cd3c295102a0aeb7ea15f8cf13e0fdd78fd6548f2015ae643e87c6af238873dcb5f17a2012e00e2a329c43687970f3b181531decbc4ab29c6d169c757a31f0d10e6069f119cc5f688f77ddd3afe101962a26bfba9d6808e67186fbcacb89d6670e5a1ef68ef7bcb9cd0643f3aa173107e064d8eaa3630e6fd452cd62b2f000a22c748acac756a21cfbc5d6c0b3607e794810fb970507e7da5dcbf703084c69c72b3f0511dc3982c6aa589d871f26f1b2343d35f5bcfe0b08f1f837b985276eecacef7277f4a1800410f76b84e90271b5eca421e4ea0744eb052dc8ab14f165eafa5c611836a9c769a86110c6751ec114434bfac699c4eec811bc28272c963b8098b28730311bc725585234c202e8023d217223aaf364b19a8ee930ea4cb8d19ab3c355afff072a21c21395b76e460d312057561acabdf761c9ac29aafefb4a720b74b7f167ed0604a79926409ce90b23819e0b33f452a3223f0c3a7494018c1dda9e8c5d5dd0b691de1a6ab7208c99cf59dbd42f4e1a4dce76125a03a6741ebb010646b360cc171471f4e8603f62f3ed625573ec3c4e5602c358039ec0acf430ba1711e6e46205dc40969244c328e7b65ee4c1120bb86995c7adbfa46a7d8b1ab6a9bb04fa449a32335691022962ed6688b7ff1b912da6da93ee9eaef5bb1c26968c49c9f8d2d72fb2634c5813d03d21d4eac9c671186e490ebf057455b784e74d6efe9812d40a4fc8d79025c045c10909240a6a1b69c0dc8035a0243842f09795d6d234bc47edc0eba902be4901076669a73fe3595618142f2c085aaa21a54288ab2bd241a95b8127a549749f86146b624b5436891f2b89c3071673627a18d9217620d104c618ec03271a3f0c2fdff23fa661fd445059be985cb550882a2b0fd269f40e8a1984a23266f50ba3229f31a58e1145d466dcf5fc251fab8270b890f3994aa310dcaf4afb81586486796c8e37481dae0be6ce9b8e2f0f5c38ca767d7e2aa15ffb551de31dbcb89d85d74113c4d116dda0e5b73f8e91e19fbd71d439f3f548f34dc5ccabcb93089db9c3c22e05238dcfcbc8a973305f3a43f52629201b2dfe4b524ea952e17d30b8fd065e7239212760449d5b17207048a451f56c88275a8ec93500d034a63c01a0a6f7d3777d88921327764ca5f24adbeab322dfee9d35ab83010aa06834032a109e953274e0c243b3a0f00bad58794f96e8493a18ecc28f19609005e81b12ef7fa05d24d17f24644490e9c675111bb36064203122ea9a2b84053258d0f569638934ca51dd3b408d6abf24895317fe31f4abbe5bd5b46c152a5811afb88b4b50bdc33286d829c3e7c49fc620c2b5e58068d491fef9313352632b3c4f2a2e249220fe7105b3222e54411515614b39868c15195c1c844c18b9d25b09a304296601ee8e894edb721ccb6d2993b2a5d24879585d295d3fbc5c817c6eea74e392bd850590361cce19d00f2d01e26dbe628c33e3e3d82bb8f098ca26cef804465c9ffc6ef1f75b2c6cc7e3d1462c88baa454234b23fae589bcc6b6ef086760bff8b51970a5206552f20e20110ca629e0eaa63d8fb28167b33525a56b80b1dbae97c36c5f9f81e673bb47673d9c5802cadfc2b3da05ca6c915752c1e30f01e5be3de1828c29877488a673411c58073a381028b4eef14c958546fc2c20135109425db636817f12e3bd2d3c26946982534cacc5130787e6da52b7f7f4276c7d906d187d84168e98fc59986b3d466ef3fc1cf92429a18524ba55f130c2ad4cf69257a6d8c59979f8d384262a9b4d0093907e2bac8a1a8059a49e2b6f2ddc7094a77c4269fdb605138dbba51a29d20a561a6f8e9c5af6b46223e3cc691266e0dfc9ae6712a3bfbca36a0177b100ce009a74507869026927462f23829fc8194d466e770ad0177f9f0de087b538eea02fc6d3bfedf523430d5126f865a0580d59f2e5610cf2da5f19f2fe874f6f97b146b39d840489d304b3476fbfda43da24d428404b7c4634931a46a6aaa5c86062988a101cd00c1462108ac6a18575d3496956e521de2a31a83938b2985b92003344cf8ae26187f8713d7d12d890b787605074e3e021a04ebb5811ab0b59172324b815f2399231eae69b63d5d917241fdf600ce1b0a380653c795981fe75d810e6fc3a1f2324357a263acf063d82e3d049047bb95d16278a97de275b861243480339f1892de4ec6f938a4e9f80ee13bb30b89f1dc037a19c273e2f51f5e9143d7362501c9259d9af76fd0527b8fedecd82a36252af2412f628dacc81276581306639dea68f4152865b29938c0e8c86b24cc5aa7134266c88a7dab9f484bced5d2c9af41bddc44e8841d8935f9323c993048793c13a6c7d1fe17e22c0254ee916e60ee79101d591ee3ef30ccf62d753703b2ed78b8808e9b8fe7e552c5300bff2d332e25682d8d2131b7249d400fd018c8f7097d236ff8859158d24b557beb24a58612f7017f0a398abe7e0b8ef6a3d8e087015c818834432954c27edd6901b15a417d56ea3175c7b7922593aebbea9445d0b3c39ce147ce910058cd8cc7fcbda71a82241e7d06c24d5ca76151661ec7efc2170ae107c12bde1889ad211881521027c1452d6361c78021f93b5bb38a02ac990070eaa7225b21f88d19be289c3c92c759dc5243b913eb1678612fe358462b2a4135fb6b1b532ef330a88c3f0b1b18c0bd6fc892d540c4fc250ed73d066245397f94e8a22f30b3aa83cccfaaca5019d4a44ab6312d081ab85f8361c38e2c4ac893ce34d7fe1e5e941b1a131d6ef404d454df304585a162a1e08d0a777d497bde1ae83a43dd4157a177e83e432bfe2703bcbb7a20b522b227a18b882a55ea79a7aa677abdbabb4244b5c2686dd793aa3e0a65047d41f91cb4a20cee4062a3a259eae98c8b0a859aa1e0ded44503465b08556adc7ae73ae43a5bdd91ae5cbddafeaf3ebcbdba1eaf4ece0e62df4d37d441d3d7d639b5322c5413d0f7b4c2c13a19cc5cdb1613ad23f5444ff6d4369dc25c455569aae64612f58c951df786b1a644978b65dcd611c681ba9e88491467e395b5abde55212ae3e9e44d53164c0bd3b573633dc33a269f47f53035e03aa0d40a3c51e53cafc24328cec8456161256aaba5f8fdd0c5630f5cbea38db200b8977ccb32b481f6e2d4a924cae9a3629872d1f9272e2bae55e0a754ac376337693e7e33517e59cf316e7fb58ac8e5b3dc7ca7f52c4b62fa7be8c1e095b33ec41de3c5f17cfc175e649eabf7a719470dede5535848ec16a789019639956f667c1298cbd16ee7d8df64ea5904d3e9052ee2d12088308fe6e1630c0a785d4f1edcb46525a23209f4e4939cbb7fee4d22c9a764844ba2266c876c41cc8aa8dc3228e8708015506dc3e581d50f480db4036482bd0599b85ac10f1e402298a70092d0c65c7e8a10dcc146dc0486032e415a05208cb7e21630047805d602680611042dd501b121f07b7ac2d104e007240a6683f31f7019af117b9800a10f6fc4b402f481f7edb39a406dc3af7af309b4d8cce91c029f14248a6196410aa0c4698ad2e4846f12b6a36b74fb24f2a2dcbc0fc1b999b4f8d473c8110953187d90f8e6bbed8e753618198e5c980c999ae3057c3d1f43085267b6ca942ea87333ec96893adbda64b221cf6613663301a31818b5c2c1a28de4e9cc4a444db15e96f4a1dda86f6a52539b1b3621d93863a3366f866db4630e05da70b271d146946ea631c8103a7677e3b71ca57052da00cbcd3b73e69e334b89f60e24669b312230adbc938df568338d28c35b09c9290f0742377fe42c5d8e359c84d8ccdaaf997bf8d48b44166a6a71b4aab86071703208c060c29bc17bbcbfb95a6ab14a8665482700c92f9ee2cecb647266e4ee01e73dfe859d89d8ca911cc1e4cea00ed8b287f038c9998d4d6f26262b5fdd9c53c79010ebd6951025baa4c9604409dac7d033c634502313bac4174c1f2695f961b6edd3772c371f4774c74be9a8452463ab7071b3fa425f2a4e08fa48ac03f946e55a4c0858d3422c2107ca31051c7b136f1b6aa3122de08501cbb82d03c8cfff2ee13e0ee747281852df694b1a8020924b4351c4bdfbf457f001ad572a78ecae2e250f9517c356bb657f12dd7f65bcf48ea27ff3717f236da259dbe597ffe5f6873888e69ba52db5057a4be9ed11cb6ac7536741daf7cd3077cb2420e065dcf47a4dc6c08eeeae8d463b0cef0b2c81be4b38f8320b76f8e4d1c4a1cf44c44b38b9fa4caad5955bca240614da3072a6e0699a4984006bb69ddd0a7ac5018dee3fd3e03e5bce8d2b49d271a18c622c62ea627bf26f06b2c0de4c3fe5569aa9163904c55e085f40b15989d89e5774a1d6ac3613277651970c0e81cb4629ae908c808fa05166a451220c31ecd1e394f108c162190aa9518816fa69d56c75dec920050d300924558cc4992b6c02fdf649a6660df816649c0bef88a97622511d54ece9fd3a48f7891914c8fe5fd6c892f65d0ddf72c6a980cd5750d1f2765d416a576ace05299564c843e44f8a7792e9147fb63629d64da11c8f2f73de40a09605822f90af7e9c2c39599417e1cb2b6c44a8d59c669e709e99fb1b4096bf08556661c382cd3e70bfd91215e6385bae26aa52e0f28cc48c6ee16a2a8f0ae8ab64862a7c784638bce0a3ed5d090de6d9f2009277c9f7281a3ee36b35dc180e257ce05ef32387079dfc3bd4d46685000f37de32f5dc688c50c301c3b78458e082f90ef30524c78cb7b156a2825bfda5042fbc1fde036faabd4b14475073e8ef1330be51935055e1e1bbb4b27de23d9681e197c43cc17ec3195eb25c429238bd7b0f9037c7fb9edf8c5c32a0fd0c08d0718e701f5cf5bb04fc757c3ebc3c3c349c0717a477f84e1db6b3757b3df82634b0d63e0d3a8065f0b3d7d2a78ee002e1ce6b8e810ed33bccd0cb0cb48987e865216312be09073cb5af781ebc149e12bc4b1b31247e08fafa2533a41946383c2c193dc411172e7ce5fe5aa0e7927c1b8fbfdacc1ba618d2121e12ce030548f1b003f95ba18387f51d7dc12fbcff9f2485b730fe151757163b05c28d052ea54aa2f722917c65e400e6c075313b6641577940b73dd901859762342a8f95e84f9754cdd31fb6d8566f290504e7f6c791edd8392e5d5a77b13b89b88b6c2b78e5ce29f1c614f07b5dee45db781786d4fb8a3ad7bd6f55c5b9d7666b04ccc5e2fc7242865b21cb879a8075727d231b9f8ddbc011b99d499fdcca756962ae8b2fde0aa296f9691d4f13e30a45389d129515f033997ae56af8750f11ed70b0febc6601e62415c4ecfeaa9ad4aee523ca4614baa1c3b38864c304770aef9d6d5aa20abc069f054749053e1f6d2d5228a2fef36b01c946b170362d5ab0414b12b86a7ff746ce20cbb3150a673d0789be5c754d92d6794e174321ef63ce319aa47589050983e8504a6c2583c903499e542001a132aa639e3794891335596e2507bc5d8996233157bc1fb679f0dcb2bfb0eb96c5121628d948b3220bc2247c202c48d5716ca1647354366eefae48685cb0c84125a4e50a21148e8a0ca11f0908082af557ab3969a80e690126464948df9139a0e9710add1033be46947711b93bfd3110b526d69a8cae282210137244ee8705e59d2f915b250f7335ca512fba334f755bd01dcf71c30b1a71c02bac6ffcb0b5dd03a5e85232664ac23d948289dade01d194a04795c444ee934c7370f0bed9699c06d31185b060f756df8daada31a860d97886dbe7392a3493b61481c7fe78a4071eb8b1ce43e5fe043c33c43279ebc74bdad6dbee6ec4a8750d373a03f00ee5329421508effcaf122e2464321f3f9ca4104e57b79867a68ad0ce694ef1bbb411761ca77b1dce7ab2ca882545ffed36953b445cd06ccbd08139cae0a853915157d0754f852585973a4d64f2b50c3ca5da731e225faee35e6940387dde2f0aeb64411432d6991c249b594b13539ddcd40c14f443d61adcc416287d8b6424ad53cd3d26c6b26efb36696a896f76dd6046516d26381bb16ee6de1ebdfc210bceb7493670bd61d0b8348db60896f0bb97901ba18762c2d8c8523976f17d7a04b17147d6118b964e6afad1646aeb90c684d4fe1b8b113e7adc346ec8925b7765668dc9d12dc92d78037f0d0dc05b33529a7dcbf1692ff1eca40da66123d70ec6bc316534c0f1993bb686cf3cb8c7c63f4a455e4d2e68873c280e2bfbd814ff74e758d76e78176b2e73551fe2db6cae4d37cb02fcce613b9146b601e315dc8fc51a1bf14f545c5056a5b0d2cfb4f3ef59dd2cc08c74e7022d2a11a098c6dbbd5305f8dcc355f7a1cf8016fa93c7c80c7e3e9fca6d301054e201d8b1d5b42e9bd9f131f623bfbd939c5165ecab3c9894c79fa12d3c1103582272273ad7f78a5f58a6969a45da394eb0344090a1b7e4b1726e49710e576d62b79d655c0860cf8ecbce16cec8f208238749ba722195bccdadd636bbeb7c11c661606e77b49a88fe1517dda834545105e2c3a8b6e90f66d93d745b144038a047e46c758e7f295b8cf5e3dac51caaa90273e14417e1a55b64f2a27cb67fbff8045b97117abdf16dce1034fde6558a35491331b678f72a35834f5dfa788b19b36c4e2df5e2aedb74990d2a1ffd923f6883040acea6e88f62f6e04a0dc5ab5988aead19aa8817634623dbf1e493bd1b1d348f470a5530cdee1101add85162a5d7689eeb1caacd334d91bb82bc3db82c9c6887fd9f416d515b873ca55355c83122bd7e952004aac6e2e114a0e3f0a7346852685bea6d85edb8b7e1d61c0b6602cb6fd7b51cebcd57aac0fcf140e56eb91cf3c16815dce60400a62aaba007f153b1b338b2d3b6874e7a30d2f0df810d24ece117ccae9c5f3dbcd107f49dc3b9525a913cd54905d36896fd86d0e8b9cc10ebca8073700cc15252166336405ed03b1fe5520919a70467db8ddde77ba4f294599565acf003cd89806aa2d642fd7054c26539d34471a4e0afe43637431a06acf28563e029c837c48160a583553ece5f5d787e4e9c1cf44878146d6469636b24eb95c76a3909f42800a953dcc1004f3bdb87319223dd610fad4f4f35d03b3de156c57beb688675c560c681e7b9fe42595afca3c81376c604ac3ac4491265951681294e66c391bf16c9812db6c687b639e01c36f6b4e3609800f8b643575f7fd89743e3254cff51ac8a1cc1d9351c4e37ed8a4fddc40dea32acae7ff51cc7a742d55eb2fb1f8b6497aa080cd081fb24dc3528bf430343740ff7575319623898123442bb1395108e03ac5004d57b249a2305f35e977e6a35363c0c42a885b308a2bfe2cf9c60ef7b36ff00f317e00469271e030d46068c045020eeaebdf3e8d0edcd1f47712b7a83510e7a3756e14dbad61bc80e70d3aab95388ea6072d6bf84082725f0caae61748c41be76c872d9e89c104faec1db28ad1ba46ef7172499040a02e4a1129b0c5d49f8397f69410a7053f36a2468845ae41a9d19500a6c86c2a79d7923c49d9380679f28a177afe1db9f9ce6b305225a8202c221d83de4b1639c320afa45248191f0c119c2e108b3ae91fe548ffcd1a340c607dd4550772c8ae745943408b90d26962064db78e86767b608adf09567644a11c5e1351d883a64177eb581d5dbf32f2682b3b458c8624d2b236c23244bd9294c334cd4cd9e6244e9690301fb9c334b9a12c810a550c306377471a3a2a5d2914a266a9717f59dc215400f414a8416b67ebd96faefd0960cd2fa2d949d5237f88d590dc07ef0bbb9333aa72f8c4179394994bdba5cf5b5398949326f802404c4f2a2b297b5c4d9496cebcecbdaeccaea21232b854190f52ecd46c19ab1034b17d97009635115779f6193eb0944fd737a95672c635770c14a624162ae21cf0cb4bf3ce14cae00d4746f8573485c00a0490da33020023a343c3f12e2b6a1efa6056e5c8f8ab5b5d2a42ba8f66e3686c606cbefd7db6d0121ae8a2bd1b05b03bb33c9f74997ff2ba2c590622348b5b816e6e1ed4a5fec280714a0a260ce16801862bbefb33d6ffb45ff9db3461ce2d3fcd24a5f0359088c24cc14535ad1fac56ca1cbad5662f6a90e0e216abf71ef168116dc20b0102483dffb44addd7c3cbba1e5aae791484dc32066a96a9a66beb7de236f17d207eb9f8cde5e3fd365b7cfc8c6e9fe804107ce7e010f7c1d68f11a8d41a885e9eb03aa3f56309cc153670163afcfd6e058ff692952f69487935b0aa332624806a31943bee50e54eb80e3b112fed4a1dfa600404a2e43fa7322b20791c01554e1bd28559fbfd97b52266b5000c8a17a0ce4c93416d0c9079f36b8c186ee06b5eb266e1926e3b0cced82c4bfd7c6339b895425438c221109c095aafff79461e001376132cefc7b7df66a3041859670629d5184d673252d584eb1905b647766cdbfc72d00c54956bcf2e943d085093746b785711b4c4060a169b66b4ac310b0cbd5b0194f016c80bd620242d0eae6cfdccc09526f32f7e1086f3afc4fb3e28778ad222e6cab4a4a4696c90b900684d1e94114a26c952f69ea071a0a6d1d79f010556d96410fec1718bd2bb3b406c010cca5de736b36903606dd9d7611b7d07bb0a5961466b06863f45dc2b3135b95252046065f8f0602478b2f0f915104a120d44795ff4225c69ac51176aa563ed2390ec469b1abaa0972371d229c56b18debb1e88265c6bf09aaf74495dd14a52511532be852a854796cdd0075e5d88c93025f2880d68121b5b1d6ece2a53c8d6a8e796c1b34ee8398f5972f2497657cc814f091a8d076031b19420a6d743cb5e205fd64cd8c7c9fae864ee91f2e3f2a5237ed405fcae8b134af981ea985d5a3b70eacb3403ef47a1d14253b882e323961ab4ed5fb778ad8c77e6cf724dc9284d49f3ad49825b00cf663e3c8dadc0f09f22a973b448ac04b1312b5243b6662cf8afd52a80ffeee609d8f3cd0f913481ddbf5203c0409c29e162409e81b6cb8fe0021a6269cad359e76a3424e9317a9254a4884018c0a9ded8bff37c8edc849c76c2a2e0acfdb6643d79eab10f8bfc16d9dac101b860f1303040939dea2f6511c25b92ba0c759f21561e73edb6e83374c52d7f26eec92e37713295b14a9143938ebc5f10d515cf43be9da7c1fc6a625bc6dbb06231184adf818cca6da892891d82d284c04920ced850899e44975ab580cb60882f682712a2ffac264b683947cb005e04c71230d35661ca51ae6d01be4d5828bd3d1447f5a3a4545f61c77c042d28e4c77d408ccd10c210fce9f5cfe9944e4ea1e90fb82153034f8390d2ad3670b901109ca9cde7d5d204dba03fb4a42b879dad17b3470e13a9c8bbfaf9bed8aeba075e03630146c2dc54119529985b190ce7e292d07aafc65d33fd21fb6a3e81dcb83ee1dd5fe28816fa3c93afb46d80b0d084798fa41af0055baeb86913b644ce9c7badfd88badd33dcd95f4290d0f45ffdfbec0a37aa53f076b85c83389488ade83024e28648f9604027a6cadaaffa1e241a2602cdaca451ac5a8d1c0ee516bac5607aa40ac4c9ce98dddf3503e8ca793b2e04d7d07c5de43e2822e6fa945eac71226b0ee79f439f980b133d523513676605c8252c3723b20d15360717422cbdf171d052adec1404f571a58bd088804206181b2486d0e7d6789372026c7814b03b37d67126e3fc7de9ff7d1bbc8aea620403dbb3b7809f4e2d54116e61041b3d19daecc007826cd938660929b008eade8607f26bee9541634469521516641cbac2aee5031932e0c336e41daac68d9ecfe851b48ea4afcb82f657cda0e6595c57caf865f2ff7d210d0f56a0d5e71e877f9fdc1536ca1f5f4fd83995b9e96fa9b0f05da4218f6545b369d01f0ad2c2808ed2f28aa35f52f8ca8e05f5ba1317b9ed55d0eb9a5915b15941ba34a0e42d2d6611c2efe651de5a0853b55e21d377ba4eb25a8301de87194b887a8c74d915693a63fda02b41b304e65fc453f076c2addff8999f38d5f03219219f740d734e460637b5889a42ff783e57b48a2b154befb87dc527079280e6198ccef00465289da783c5efc7a4d20e4d8298c3689d08ed2bfaa2e6b1ffe110672de18f6e5119461dfab385be86333447619f2e1913f03ba166d038fa4f3c042f99c009387409d0fd851abe13b89c3502da44c8bcb1438d0549e0ace00a820504a110641381d37cce5b2019dd452748f9cb3432f312aad502aeaeb4d5c1f6603c818bff92328f53d25a13c755b3ca0083b9bab6017864e4a543270847a37cffea2ba7a83d4a886df2100788624d9047f440ce20020d32bc3ff5e382a7271ed4d3b233fad7c3438bb202249ee30207751ff1dd9e2921f7732e2c404062e379356b8c28842917428aa061089c40180f20e49dc02826642aae9269606d297762b770a6ec7cb62dc0b2593c81122b29bf6cb1950360ad841a66390df9eabfa63059264295778d3eac77db4470e609a288bc60b41f4a8bbda57f565fc630cdf88b00d7ef7196ed526b18dcdd2d9546cd146fa7fe73d9be9caffbf1f0fc217affe40de7d91f48c9513b92dd0f43bc726982ac54c0b0b502aab434ca4e11457d05141049e5a21c8c02b0d909a51f226187affcc8243962a2975c3947ce50e5105a4316155068f56548c482b5214fb518579fbcde7a0e6b96d3b7398d427fd466d3363cabfde8d856e3db3d92a0fe065f15cf02b55809c7e191c64fcc0b0be46aed077de1c9f4e670f2727fb3d5beb9dfea2c38b33600f041006bcb9ec6c496cf7cf0d4dd1409ac395d9b60f9d85bee7aa1a79e36c094666c7452c63f526bcc3d80d9b96ad51622f65c62e591359a12ad56697931bcf50d9d7d84f6606ad8acd7b024588d56c5a08d18776503148dd3627f3c3cc94e6742d20158e0d7f975ca44c8bd7794254941b98021be18b2d2f15c29982142d08417c55d1f7f7875173d7b29a15224764f58e4d0a8826371837cbcc2608b251560ad0b1c30c48c5d604edf9ecfa1786d13813c4045a03620e223c5f55ec0358fa00af9463da09c40f66c845b9630f506bb218d08045b2c7a598335eb5771ff8a89664ed4698a0d250860c57017e41002e521a2859cff6c5340f38cbb083c92c5af4079aa7af0a04d6fb42002af3464b74c6405a17e885332846207c8b77ef84f574b10411285ff3345225aa2c8e81abe705e2929a4390aa5b798685215dd4c21145712c20b97b50cda2ed8d5d98f8081baf526ab732c93bf86adfa9082ca423585186ae8e3dacf521b9510c242960b7910725dc892903042ee5921624302948d026e16847b0a3760b46439330f0f0f0f0f0f0f0f6f706b4968db1892209394924a6e3c99e26d4929c994644aa201daf7227b35fc45daf01769c35f88f106bf0a260a660ae8e694d51c3306a24d79e35bbc0e205acb312771cfa67e62a3a1b6caf1877d4d663fb431cc4fe5ab129a7feec33232b3f6c7b57c58935213fe1a6164a4031c7be8841eeb94a4dc3b3b3d5cee31cb43a71f6442d6a474bc535e900370e0e10ad9344528028e3bb4e7793e29fa66c61f2f1c05c8cb7639ecd075a9c435315b253e4543f76c8cad4395667a2162fef6a735be580062c00c2db40043035b54e002650065e0a0c30938e65038e4d0cba8860c93153c046884e10dd8420b1f38e2d05f8a9d49e4d216d999861a071cba6849f5b48632d714dbc840044c8eb151c46a8801c61538ded0cc46cca124a9145ac434d46a0311d0428b1a5f040e37f4f132ecffe71c37bdcc00638c1925f8e28b2ed4021b5b6c4460230311d88800a380a30d6df410632296841ccc67431fda638831f5645ae41fe05843abc174f40a498586da176294ad3dfac20b0570a8a1fd8b5fdadd44ce07d3d078cf04003be040437bb1795248d1945209318e337466f9634eaaac359a85861a0752031c66e84447ac7c412425ae7e19daec164d574c4964e8a37576fe470bb96534867ea286f0963a460c5d5072c34f66f998141386beff24c9d3d4893f5a30744a787cfb89cb3c26fd42977dc172cebc29c247bd90e4e42245c5a076a1b7982d942c39135753b8d04fca29222c754f26650bbae4941a2279d442937cf467f1340d224bb2d0e6bd4ca22dcc69fe170b5d442ffd0bdfaed2c815fa14b34cf848cc621e8715da6ce23ac54408be21aa429ba406b358154374c854e8b357448d3a97b46568048e29f441d44d26a614f37e34091c52e87c435297785984d60f1438a2d0c7cf62c963a65e781f0a5dcc9cd068328236a572c7f184f633b446430d55c0e1847ee3efcfe906ab3cb92229e0684223b1ba44343fd196c9467030a1ff770939c5ce27a083e0584233a3994152f8a0f363dc070e25341ed52c55c345129a981d2bb72d494842c5041c4868ab4fe65b5065157e81bc18034bc071842b6446cb3b40014c48c061842677ca21c9440d5a9c31022fb840781ce02802115af3f852393b2567353986d06e90a3624cb173616a5060021c42d86487c924729a100902dab356fa84181d430542422c33c8f7833a280d3283ca77c1858b91387cf0a8ec317ee3e841952d63a31c3c6877cfcd5ffb42432d8c1178170b581070eca0d11a296bcc162903870eda896b2a4c4e34079dd0d312964b069553a720a2060e1c74524e7ceccca4ce71311ccd0023396ed05ac8d13f899ce1b0412729ef054d53564a475ccc5881185c78e128f82ebec61d470d9aa01a13e3dd32838306a4a43cf5e98e865add0a386660454e0d5b399868a86d083864d05fe868a6442bf9c4a2197f3d0f17468652d9804597d93fd1adb292102f0d5170c5365ed1c7f292212e5cd1c6f0cd2534fa59650e0db5195f2055c2462bda9c25e3c47a76f64bace852f88826622c79d858457f3d7f21ffb344ce962a5a37195f249c4e2a9aebd2151ac206156d082969e69f9e0e397b8a4697fcd25c1df17367136c98a2cb9c2a4fcf748a6165b4518af6bc73b7af760ce71829ed6c90a26f534d161e64deb8308fa251d18f24aecf15459f33750c1d5783b94b42d16bd01fbe537bce912191d80045bb5fb96362afe7202d49feb0f1894e7952f2212159870d4f747e32bc85bd136d92a94b97b6f988ec2e273a29615535e86bd1fb6fa28d14f16318fd51a22835d147d15da57e29a7ffcd44eb99e35b3c638a91c7446f39c9259964061d3dbf44633a85fa76d6fc2eaa25fa929f10c37e961c8357893eac8baa8a311e3c5d4ab47dd9e3b924e9868d49b41eb36a257574ee0b5d20c9b021894ecfe5d22db21489bf42d73bf4e62521d1fc5588794212bad9c9473479b382ea333709ff3ba2b7cad14995b2ca0f2a8d68f3a726cd929f534aab850d46f4d163325529a7919416d178862da5c2fe569b47117d756ec9a8f325546412d1ccc6ac29090b2a2ca90511fdc7ec1339593a44eb3106b95749690d8d3144bf49c7e429c80f2d3153886672a7fcd71427449f3f9ff227914b6aca41742a73e916e42888b64bbd730812c2784c02d1492e95fc937e050b1b80e87d3f4589d9b08b2fbea8c05d61e30fada408bfd797c423cb1b7ee8633ffe7e94e0f7a1bde899b993f64ce15b3ef415a2b3a6ca90f2c3dc437b3977cc907221d8d043a7af2b89d3a81e57611e1ab96d7a942ed9ade48fa17868945b4bcea49741258cbc43ff49540e3ac61873de858bf1851887810d3bf47ffe39684ff620be44436d0535c428b3c0461d1a4bde15528fae12d8a043e77162489e5b0f6ccca1dfa4db212869ea7115b809e4d0ffc5b7f079f2647827b011875e3676543fdf9c3d35ec40b00187e6a4e8d6ea0d7deae925d1f21762f7620cedc0861b4ccf8a79b6a1d17e89979ba634630535c4400d6cb0a193d728295a5ac477c6796417d85843a7acb2c4f60ed15023ac862e93bcfe19cf3d5135330606340d9dee895a9245dfa2031b5b6c4860630b0c24e07f01e847b1818626650d115e32630535c4288688828d33345ab39eaa4ea5d9f268862ed5937b86d01aa729fdc246193a1127be42679e49ae36c8d08fee6865a231f888908d31747263865f195d0c6d65f30ced294bbb886c61230c9d9012f725f6a8143b250c2e34021b6068f4570c6d60e30b9dccef9b9de3261d6412a3b0e18526efac8e7ad03c494a36bad09bb545308c0f43035a6851890d2ef4b1f144fc93d201bc898d2d20731ebf30e33127b9b1c537600f1b5ae87cad424ffe53becefd2f000f1b59e862abe28276070b8dbfe7899e9025b6728556925e917965746766acd05ae44d7193971964b60a9db22c67b93d89e636a9d0864e139ed22253e8834c10ea13d332ce047931c602d8131b52e84788d39e3465a2d0e9903f9c483619f673283421c9089729c256a9ef85170e10c3c613da7c223189985427b497e36bae0a8fec7969425f22448289e9539a2513ba1c49fcc8e9e49a3ac2808d2534395e52dd915425595a850d25f4b13fe8064d6561e35701296c24a18f2242cee6a4fe417e24f41355b28ed2958d23f4714f865f2c913bd7dc3042571a4f6eac64a93c4c2cd0848d2234bbc9744fd774d221b2c5465160638b8d9ac0c6161b25818d2d362a021b5b6c1404362a10818d376c10a18927517f47641a6a5b6c25b131843ee9b09033960e62c6d2c2890d21341e4568c8d77b79cf7280185f7c718117e38b093c622308adfc6ca96c3e7225836603085d490d0d41b926213e51c0c60fda0fdb5fa692b42ed7fc182770302840ee011b3e584772de1c739e1e34c1748b76796689568db0c183642768ccc87ecac0c60efa0bc243f8563632c0802abaa183bed2cd7cc6ca2fac5d380d74c0460eda3ca17c72beb0290e1a8961fd4278aef406edf5c91cb13d558e1b43436d86175f10b3416cd8a0dfdc5151297274c511ffb051835c23e7ac1c43bb41833e67d80b29e5f84f6dd1504b402239c2878d1974e245538ee9c9b12de4ecb02183b63d2de8d8b214825eb28845234aa8e6f2cff2d67c16b038dd3a89b2784557aab334982e21e39559b8a28d49964412f17e4996452bdab84158999988bc04b360453f96179e327ab2584567d631ee84f1f5187216aa6853949d3fab6865d69851e38b1978a96852e72a8d9d0ab240459f7da278b5c5f9e88a218b53b4622a550ca1ef173dccc2146dc8967f338c454a626aa14515b228451bb38652ed2943438d579005291a19fc63f75e6b9cc5281af7687199628ed1ee31200b517471e3274f5a4e34d4b0025ea393105984a2919f644f65848a0a1a3e64018aaef36e8978d94ac6cf175af274e8e55faef2cc0691cf1cba14577a44cca46723874684a7dc1d92981034250e5d95f60ab1281e379be0d09af99bb824f768ba3734f2aa66f2f39f0e5a71439b59deb4eea9f84d6a4327f5ad4ff733e712b1a1cfa7276a5211314a6be87379c59c9ad28210a71abafc5a2dbb6d26433e0d9db9eff89e5910a3a1d77811eaa14b650b9da18f33327898bddc1c33b4f227db5b62484b192c43bf9257d74bc6890b91a1978fd13b8aaca8b142c6d068970c66b221abf562e82be40d91e730b4edb1224abb60d02f3439c51cb443968f92e285cef3e62e15329b78b10b5dc8cfe193f210628c1c17ba9c573e2adb6da18d4964bc8aaa26d14f5f48c265a4ea59684686d916110b8d8ad39b3aa449d1ccaed088c490132fb342e3598390182b7fe8bf0a5d9eb8eb7b890acd76aa145250d6c18253e854126d218f69d11c2929349b5762b4bc4987f3390aa6c50708000524c0135a8b257294dcf7099b75425772f4db540a95eed126741db354ec9d99d0a61cc5fdf4a5345a40802594dcc2ffb24b9212facff01b77469f8436bfc8474f991a4b7524741653bc98fcba6254f708cd5fce7d42668b11badc9ae76405e93e9b5284b62ae5514a3648842e89043f1171937f121942bb6d1e2c478742e8f325953e2ae711e29220349663e7247229ffa01f03080084dea3c6d62039a490dafb4117ba544dcf645329a53e0c1fb4e1437c311dbf22c4a01ef49373475f4e0bf9e4e1412bb2b4340711a2fc66078d5f5e10e235f306a9d1417f3994550eabe7a08b15b2c63995e3a0f3ac3d3204f752f2dd1bb4ada3640a23378789890ddacdea4e59218b10f91a341e75b453b508d3b9d1a0cb172733a662f61cff0c1aef4e22b865ad303902c8a0cd39860bf229138b2e4592d52958862961d1c659e593eb896bb1bea2b75442e205a53c665071453f17feb4b2a99224c35634ba3b25879c8415cdc791a3cbf20993a28c5520f26e2966ae1855b46142d8355d2afad24df720fc47279c50d106612a49b427b93153326520e3145df613e143bf24490c09b9820c442ca8a05962ac40414629fa1cf55d2f4e481efd438a4e6852151e3556599c47d177c6d8d93bb6fb89a2e844bf42c498722eed48287a119243851c178fa081a29f985fe545356912eb13cd9afabf5a5658d0ae0c4f741e746abd8a6dda82298c1a5fac08323ad17e852d6daa72b30519464106273a0d4931531279e793888c4d74c2f3cf42cc87d81baa418626fa70f19470799272cf973b838c4cf4e366498f6e5e1265d9d8e2b5ac0b323071d06ee25d927b892e825716b15a5264042dd1f7be8a0ed77a251a917d620c61bb7f43a344eb32b1cff3b509f3ca24bac8f99364b588c94356126df5e4b051241a89c65a3b8428d310368a90e8c325b99ba3f223da58fa2be9889f23ba4a7132a3e9a9117d5ed2ee3029618497187138f9395944a333c23c9f056141744534a79efe97aff54fc444b4d6496bc81ef3e6181a221af191295890dd215a511de3d462d64c863090618846e445f49953cb199142b4339f2b56dc144ae610a2cd2e1e46e4a457df4174b17a84070db2209a94b21a4f09d79c491988b6c3e8f5734b01449f448a7b4a792471faf387fe2d244f254e8e63c8f04317f445739719c94992fad0b6f8e8cd91f48e328d0f5d4510e626dedf432b1ae5544e65d143bbe6beda9784567c501e5aff0967fa5478e87388561419f39265f60e7d32cd41751cd9a1cde15386d88e6b396b75687df39f488ee9d0252d298c8cbb113f9ae6d04e929d8fec9a29fb91436fa62d77cf5adeaf3e0e7d653453cbff15c23232e0d024a173cc61cd2a28113241c61b5a373d324ecaa7d73d54820c3774d2fccf444cf4ea1cce1fc868439731cf299d4abf53ec65b0a1af701982704f1d1da38c3534674a9cc778212187ec63c00932d4d0a830af6d9a3c9872d3d005d116277a4ad1d0249d5208197333a855ced025df36113ddf5e0e6498a18ddf953ba7aa5611a232e43988cfd7a77299ce9561410619da121944d8a0c306c999316851e486ec21fbc94e4e0cad57ac67f74c593a7a183af3d011db73ddb50543b3a1739d53f6936e5fe8b443b0247762e5b4d80b8dccce945972b5ffb85db012c8e0826921630bfd8490c309195532aa163a4b2a84a6f8cd39a94643cd0b2e66a047637471bcf8e2a82b6464a1f7e095f258fcbfe8140b9dde08e233fb8f694dafd0f5aa4c38dfd20a9d1e4da662fe2cbba52af429680f3249cb494e16a9a086b8631529e8981e1a9a5b430c308620630abd596a954939a9925ced4086143a8ba753d2edf49890140535c4205d826486163ac88042334ac8111b25c7d2fa131a71551253e2a9202e4e684fb689533a7a3d254d131a79ea338191626d427f04194b68dc440c9f62cf4ae867f2450cb316da194e42a3ae2149c49d91d0f685d392375a1219b2476894e69cc276921dbf4d2334aa33e524634a4bc22274b979561e84564a9c08bd28159fab4a4c100b0ea1ff34f3b188ee298888101a2554d2781e2f376a178466354d68ea1c27e809844665848e31d9595734193f6873263797981e1ff4a54dce4a4abe6b3ad983362c58fbc9242b6388f0a0bda45f517662a74ace0edaf1b78e9dafb4f2373ae874789b65121fb17334078d6eb028223fc3012275a4ac92d5c2818c1ba4c38345923b96639836b04a3c3d62c7b8c904b10cadbc71734c460dfa983b5b56fd5d060dba1416a2b1a49e8230c0f01460c00b0ad040c60c9aa412929c94bdfa3387792043067dee17592a397de5ac1870c4a27189bdd62f423e23a5051cb0e8f5f27a24adf9bbb59281f417e078452751f3653f3e56458a3b030e5734d625e35b64b6d29d4443cda0196178591809d81770b4a2b18ab9373e7a6b86112bfaeeb0417ce4bdce2f59459b67dbf79455250bc9aaa2176bad0ebf705926e14885a5152ac5891aa2c7bb00c304af43e04045a36244b648fa533fe4148e5374593b66563dcf533669a86dc1618ad673cc98a232d253975b8a3e674a195e35778849478a46256542c9cd29fb3446178e8262a368e4426b8f8e906b84e1db00bc0b7088a29f1877454a1e1984e484a25392accf734c2923555074397ae584d9b0d06bd150628fbe98002ec727163911f2c40e8f86d298915609e0f044a3e5db674b473b640431a09dd8625e6408030e4edc26fa4b724a8eee20630e319a68df7d92577ec99189d6b26efb26971c3b781c986883c8159d8299e5cbd0251af1c947a80e2ae5529cc312bd856a27158448def1af447fed9664d6ab50a26f13655237c44ca291d57122a414f3b5bc92687d230915ad4ca87c950e2447243a75796df990a37b1621d1c6d3b9563956dbe4f3883e6f24cbcecd107f2758010e47f4ad93728913173c685023da2b2ddd25c2f9c70c35b05181087030c2ff4849ef59f28e8c51e38b2d46e0c50546e0c505ea9cc6164e630b2db4701ac7699c19c80bafc1b1884675a876914146b66ac760037028a28d3974c7b026938846678841cb48de5e13d6482d3810d1e5e8ab1c3d9679c13f441f622a632ecd3cce86687c4d93ec7e0add092a44a79d33b39ca49452cc09d16f4c31ea482df5d87910eda414477abe108316a920fad63cfbe67c125c444c96f2e842632a46d8ce2b4fba835c38ccafb54af95fa76ca11fb196bbaa2734140c7f1a5b1e5a303dc54a5eb932ca53077864a1936d2123ba9b328d1f0bbd448d331f41e28ce95c1c023caed0ca7ed2a9af19d7e2c70a9d2acbb313f5636638a304fe350c9a1835be0803d5a30aa6d4e472f263c8d0501ba3920aea3105529829392bf2904213f2e768228849c192360a5d049f49923265886128f4b923982935997d528ac7131a212321e5f844916f7938c1a3094d9024733a75855eced99d053c98d08e124188d4b87c9ae3b184f64b6f76159557426fb27f3246d1a1b145496836e82097af5246181109cd48b314fde462ca7972844e54782e9d496c5f05cd044705840a1e46209e18d11e56c28504f00c1e4568a3e9f8868a4468e24c90f35e9563653e061843e83bc92cca62ac3895230f21f4f1a5156244675ff462d8a5c023088669ea982d1a1322c6185fb085512e081e401883c70ffad22d29276fcb3d2b4de1e183ae42b6986e3abf87e936b6e084470fdaefccfa392733080f1ef45772c63da7a7d49d2484c70efae07ff1623ed5415b16c53463941e39e83a789e84ada467544e073c70d0e8eeef5c2104994b2578dca0ff53aa3709990ac2c306fdc44a2512b73584354fffe05183b6d46492cdf690d1471a34b1359a8ab36e041e33e853ee1713a66377cafdd5c14306edc5e599d6f8d7923bb61a8bbefb3cdc53fcac84a58b2e5c8dd0018b463bf5f5041dc1cd64960e1dafe84b365676488d713c270e1dae502b8705195278e6d0d18a3ec6d3159697c38a2eb56b0c22590a00e0d0b18a563be4a05490336632a98a2e06092a238fcb45472a3a31bab179c14477eea0a25377b150e163d4723c4fd107cdf1634c25739cf7d0146d6a1016636ef66ff4cce000e0a0a3148d889c32254b527964320cff2e66a00f3a48d1e8609dcf52236698d028da0da37166639268fadb193a44d1659325439a6ace734b051da1e882b058a6a478f4588d91a103148d8edf9ec96da9a562868e4fb456e571d4d43fc68f3cd1b6c6e9ffe4b8f2788da1a3135d1415838ac154e9c99ed3c1893e649f2715c722eeeb1fe8d844972f9899129741869cb459e8d044ab419586183b842c5aa358e8c804424f99f6157dd250834107265a51b91db2173fe85668a8f9257a9df114a654febd3ceab0441b2244fc6e52537d255aff1232e5ce123ae6130d35e71d7450a22b51b2933211a72b29d1505b1d744ca23725cdb2766ad39d241a6a92683d5e359a5684cd4185865a24bacea4de5971e213355fa0bc410724fa784b9a4197cc4156d018603ca2ab9c71720e7aae4c5f1a6a60180e3a1cd14c506119d7f93e568d37267813cc10e34760d7838e4634f9527c6bef91869ad7104305ff05239a1ca9334d5cfcca2dd25023566ad0b1887673680d224e76092b7eb11b1960c0c6165f021703035e50400b2d8800ead0a188f62abfe41c4e9f887f47f3e5927ca588a003119df7282509741ca251a9741c29c134c34e0c1d86682e6577ccd10b7d2a9dc0133a0ad127add7174394fece3184e834d6520e27456ee554c720fa8f9e2f3a458b17ca14801f7408a2499e933da836a5e3840270838e40981614e800846951818e3f749a5cac72e60e99e48661d1e107b3644ecfa0a71916fcd748351e055fa3a30f9d0e37a574ac5db47f68a8a9a2830f8dca99f164fe988e3d742277ce3929afb861f47a68f3759ee54e5995e39c873a72b2ec9b710474e0a12b397931fb9b4a89f93bf4a942aee6093713a2d7e03a74d8a1ddc897a1bf7f3647d5518726269349c850396b0a4a74e864c25c0cda4b73e8254efe146304cb174d72e862f65ea4d4d372d3c7a1fd32a159b307c1a1b768a5642839ebdc794327f9ff5d35e95c458f1b7af5399f2bb5cc39316de8644b6cd9fcde193f674317465a59525a53d0c95d439f75528fd231f732ae6ae8573c27dddd9ba29a34b421b6a256675d1d33d1d08686529d84521d4a7567e83c73a7aad06186b652f6c549b00ccd06eb8b99f927439b3b77f2eb498b31f93174fafe8ba1919647a8d60eff210585a1d9bc92aa93f534081118da8c15434624e80bbd8f100de2344f7cd3f14223bd555c36ea7ccc7b17faec49a6987424f924c48576645c95b0fa164cb157d6429fb3e36cb894b3d079ca0e55539164b43016fa1d9311b44fc6ad70afd04696386135e35e45d60afd8e90f7a4bf748544abd08889e6a353259d4d5fa8d0974cd627c25445cd32852ecb34e8d37ea13d2b526894d69c21e5bf28ffc928742664082621040a6d0a59a55f720e97b37c42bfd921491f59cac2864e68e545758855de49e59bd06b8a3a966487666b98d099ec16333fb910df25749623d973c994d0c867864a427549e84f4d8c142174895199143a90d0bf87b21c2182e5544147e8b5423ed349ad0e233496dc43cce5a93cad3a8ad084984290f0eb4944ac8ba711867f042c79d041844664664eb14dc91f9dd94b740ca191d1eb519e5384d05b89e78fa8c9a4856410baa4631e9d33983cfd11085d6faaf7860bd14474fca0d19d93ec988c5b55bcd81e3a7cd0e74eaa914ace9a89680fba343159d7248859065da18307bd5e90983aff6ade20a742c70efaed92fd25e45cce57b142870e9ae8232349ab92837e7e44e52037d6818376c44ccede9d21c3bd8e1bf42156653b6cd0674e5953e6988bdcb18e1a349f1b5ad9f26ac88fe9a04113d62ce2c8733b66d08e9e447d8f271a6a334ef061a8ed023a64d0e6deff0d614f983051d0c5171808e30b302630022fb858c1f11a6378f1261881d7a051016b030162d1c952c2622e5e9c20ba44818d2d36d208008bfe5fbb94d06b39cffe2b3a1d9496379daff72f2886177f5cd1080fb160e169322c1e81175cd0c8408dafc0b6a2099692d0b1e75f474859d1eba41421a60e20c02a1a19832c19b3b98820e5a38aae63d4f74cb921450a622a102015cd242d2f5d624a06714145a3a485e8173a6ebc89a7e88376c6a6088f254233459347466cec90b21bab1f010386408052b4d9536eec4f94146d4aa154c4128d00a3e882e82023a5205134faf22fc5d85c3223a1e8646c176d265a43e512289aa02e6e290613a152e913ad27b50af9f2e70b274f34da532cb95945a8ca74a2d54f5a548ca72432ce89bebcb4df42d6df8c6fa26b535af4f5ab89c6f3cabd456a55ce7d26daea2033c6f408139d5ece6a42f5e812fdc8593795a63b660659a2958fa1e4c5dce821a24a7416f3e8243c73c6c8214a742a421c97b85eddf93389d6946835a1f4fb67cf914473b919b3591646869c48347b1e83dca4a23b2707126d9fb6eccca355b13a8f68bc4b5b5a92a0470739a24979fa3d5b10a55b348d68b4bbc7a472181d63c430a2cf0c9d32245db592994574c1742f68550a1535a388fe227a0ee2b46ace299388ce6268b01063a798841c119d8e4156f52771cfd60fd18cc6ca6939e4eaceb921fa492545a24abc108d67c965cd721183e584e84275e624e3697fe60ca20b25b2460a1f3a9b1444fba2133d654f22a3c681e83af67b9f751810ad9ab064b12b6f12417fe8bda29888d9cdc762fcd068d36b1649585f69fbd07f2ea92364521135b504e043f3af7a9d91a45870f7d05e85ea5129d45dc7d543a784d4b8cad8e6a1499553c44ba2c9a249f170e999f19c2de90e6d18f9c14396b8b9233b34628484f0a62dab995a8736b586164be854901fa325f5054959015ca2004ae8940871d67341cb855c00952840121a9d3f584e737dcfa984842e24e127bbd7591dff113abf9420840ee531f9c8088d8fb470ed95a6742c8bd06f24edf124a80a40842e3f2ff9fc8987d068ea9e4f3a7c9e66ff86500021b4418a10163e8442284010ba98a921557c0c844eb9fc6b2c7d2d12827e8089385396820e0805f0419f34c7c827223de84cab6acc4146f60705e041abae39db53a6fc09a31db49644d6f87a3e294ed5413b22e72063ca9b265205c8419ba7f307f1c94b478e3c210e28000e3aa1e43ac58b7ddedd29c00dda5826824cd2bc0d3a77cf2e1205a841dbfd29a4f828132faf601480065df8c58bc57c96534e0f11059841a39ee4829c104ec2890f510019b461ba93f40ac9820a2aff118baef3b67c8ad02523665560d126e95ad65d9a37f28a762e357e6f66d2e0160db5306a9031a0f0e18ace4d43d0ec504db2a78f5674f9a2f65c4c7156743a88291d66397faca209c22a95d09d4badab0f557421f165e246980d1fa96892c7901e49e4594f96f9404523927f5f3661b249a7740d1fa768c782d2d9b47990e2da186af830451f72c5109390efbe9f82c347291aa5ca52ce512529daca0f398b5b1239150bf1318a4633cefc58507e88a231eb18ddce18f3a9e42314edbfe9ea31e95d00bcf0018afe4410c9e72bbe53d05c7d7ca24daf8e21553301171f9ee854b2fec9102fc7c5a4138de8554b1ae339a6d01d514e744a5b5f9c9ace31a7f0265a899fb2c41c160c68a1451847f7f0a189aefdb7c467e61025fa99683b2b97574a5aa14310136d882185f8ee8bc997ba44d2f425e71cdb6237b33a7c58a249912546d3e196ed9f4e7c54a215b1952c7e9279656428d1cfcbe49cb359774b7612ad78c8254c7c8cb39d93442f328ff09131168946364bce21944adaea42a27393e182d2bb3ea217cbb191aad7b235c5117da4a44d859cc455df3e1ad189204907fd97f43cc77c30a211a9d5d5aef2c7225af1b06cbaa694faa188465c97cec13b826ab1a07e24a22b4d9d135d15118d4ca93587b6e610bd8660ba459c95c82363884ea614c3988998698b3e0ad1acc8082244d7a72207f149cca8f820da31193c64cce8e14c2288f693f60bda1dbe625803d1ba494d95525736d91e10cde53ecf49b6475612fda1d1fa9da7e3c4cdd2c1f8f04393636ab13c5d392de94de05eccd0157cf4a109dea2dc3fc85d8b232f7e043e0351f0c1873e566c889b0aa2a1661f7b68e74cba7fb094af0461b81833ca6a7ce861bfa024a74eb93c341abe9276533af881874e2cb5778892d4537c68858f3b74662afc6b902f7a7eb3437f4274848855952a7cd4a1b5d2a264a6f0b8a9e220f8a0435f4a8952593b6638dfe6d00819b2e6a4abdb64b660e0430e9d4aea334245ccbf1163250e8d07eb11d3bf29965af8030ef7f18626c81c1e83e5e7b03e9202840f37b025e35cc65e8a79f0d18646c324219799f15d8cc00b2ec2b07bc1071bdacc1c454c57c1183e230c2ec8181f6b686499e72427e6ec99facff81a5fa437f7a1864654ff6810424c764ef691863e898a7af1a182867eb4c2568e9d64a4c5848f33343ba73a998e500b1f66687757e4f46f5a862e98e54a2b599317d506aef041864ee470f25f445c3ec6709c8c1fb46eec430c4df0cb3129b53ec2d0c6dc69498769e4030c6d5810ca2fb6cd44f95ff8f0429fa95af22b4ab0d4330a1f5d4833e814ceddbb0f2e3822478b1fb3de1ae1630b9d52b96c4105f9418b0e7df0a1855e26fa4ff4d53019b72c7c64a14fa56dc2fc471f58e89330d318445636b678c2c715bae416eb1b72966abc8b2e9c86185c7000cdf06185f64db589c81946fb8318868f2a74ad412d66f6d1905946808d021f5468c2b8e409b2a652aa58828f29f46b2a35695892cb3ad2d0b3314cc00593e0430a6dc50acd1a46ff1185de2d488d78da25cac60e121f50684d5a4b94d3d9fce44f6864189f7cda6304933ba1cba7a2673719cc74b609cd6ee6dc414499d0a4123a4da35f9f597e096d4e9ee2098f1e1ae62ba1ebd4377d25f249683be69057693284543948e84f5e720a494dcfb2e6089dcfc8edcac8d9f4334668bea4cfcaebc694a917a1f710e38928173ee28308cd9608d9a1fd4c87d287d08645bf6e99989a1a0ba15349f57b9c3783d0f7e5ac90dd0742632a47798d97d354f2833fa305211ff45b6eb224aa3de872ced54ecd1667c4833e78bcdc2bf9a12a2b3be824b75634d9491d741696f7627672d0e964c257f54270d069d5d894e3456ed0c58b1983c7cf6c9d6dd06b8a4d31872082b5a5066d858ca3dda5ca443b1af426ad4d37c6d8c70cdab1603a29f9116263fb90417f4994ce913a985a1c0b0f5834ca4f6829bf98577442889988a482e7841c57746ae2b299a956089bb5a22b1dbc738c14ef59b3ace86228d5a3e62937c26315fd66feab4a113d43ee8cf05045a3a72792f87a523247450b1ea9e867bfd2820c42ea6c9924111ea8307fae5c9623ff893fe0718a2ee78ad9fe1e61c1c314fd88d251437896a63c96a2fd0f2a4b959aa6c52039840729ba58da3af2aae690aa1c45a74509cd6f667988a2b718476786e885a25dbda02df1a4e86b388d30aae0018aae528a61cef39fca2bfa443b5e2da32fe99e68dc73ee0ded1ff31761824727fa32b55cf13563a2ab9ce843d65b3f3586ee3d0a1e9be8b36c0acd1db4268ba9133c34d15fcc399c88b9db158432d17c90a364322d3ab94a010f4cf491b453cbfc7a09f64d3797e4105d4bf49d44469016749aec180db5ad445f32fc249d924d5f630c30ae0b0f4a3452d42fddd3f2259dd0505b810ab84824f098449fe7babad57292e84465d038597b57747ea5e01189ce430797131f1b4b6cce3c20d178e5d01ae272f8e0f188de7ac3e7cdf70d22766c0f1e8ee82da378f966deb7886944172c2f7c45bf90e48519d1f6c994a26eb78be8325382f80c29a2b31cc763e82ce22fc744349bb22c660a1344b4399a56c9a7cafd35b5048f43343a7f7c5664cea51e433441c8b5e0922cb6e5268cc5834721d0a3e43de90b642ef02044674a4555e8d03fc16310cc85696c4bb0b0229334f33767abd6f6603a33be40697532f010446b3986ce73994ad3f740342296506d1a93889539207a49415bea8c9c3f7422cdf3524e914408a31f9adc2133f89970cbbfe943db2352e6b7cbf3c4c987763367bb7dbe2f69687be83b04f352e14354d1e8a14999e4e5f0d4300d6e1e7a399d4a786874c7880f1363c26ed21dfa28f99212526432070f3bf4e5f1a2b45d5b729cebd08b5011d473ad4329131dfa7822cb76eafca1f19f43ab31e7f698e25c9624ecc2cf1711505bc19780bbf00678c8a1095bca53fe240e1e71e87775c73f5aca030ebd7a6e92b73821fe346fe862e7d893e22955b1440f3774b1621016fe5494cb590682471bdacc18fd2433e991612c0ff060439b93deb2b04957498bb935f4a7a192757691a0c4440c2278a8a151b2e2a1af52b3443f0d9d8e514325af9c152df7050abe4605b4d0a208c1030d5d07091f4fe4f8199a9042be3b6fcc4bf898a1f1109de31bf2a1235ce8e051864694bcb8c162e84186d6fb734cc1abaf37788ca1d7a41554d6982f6f38d7430cade55a72d9a062e86a30a0c50e3cc2d0c8881d2f31b344887c0dc1030ced6739f127d6ae6b418f2ff421f4e7acef1e3b688c2f6ae8d1c88087179a038da6a8249165f2582c1288c3a1300e82181cdb1e00731308001838260e8562d1783c0e85dd0714000556301c46322e121c201a101c188985c2703010088602815020140e8682c160402c54b220a90750ec386e472a6aabeafa50d23831aa616191d6e96e4d392166cd79a1a9a40e8e8344c9a1f2dd5e6c7d119fc22020c62de6e276372b0ce63a91a585b50d4d787b24ecf877cb990642baec91219bd774fa128ad2a874537d90b5410e0669a0d6a0b0217e9e3876b91ece1b4c139990918b3e5e1a01b9a30176f9818a5f13a10d9bac4bbf6ad60d0b3741bc302414abb0d3f734a484adac51beaddf44b2754a24a8fd7d5b112b4dcdacc42916c4fbfb854ad8eb265f97089da8b4c689b9517a29905b344e041faf922df3be6e4234f2f96330878d796cf6e58ab32d8fccb73d5bba1cc197dd2f8ccc6649f6e014ccd477a3de545076a759a8ea2149c159d35bc40da68d0a4be05be8862f1ce4a752a01fbf6d9f3224563a8d4b40c5c05b1375538ca85d5a1ba0c2715cab1da79e08d1a4f4c4cc882070f8c57e3a02b3880ef265d6a7256eaa83547112a8185e9758cf9632c75ef7e356a9efa579973b185cdc68027fbaf913c5d41297129074062173f4589aaa465058e647680af0bc213df906e358f227578bfbfddb810e066cdbcd7520165689b08a4d0a2f2d0deb36ea685b3a6882601d22684a95b4099f35b63b551089971472ec59827b485051a47ef47355d2a73ef3e44f9e213010ddc62e8f024038871a4a0eaefd42a62508c39615ddd6cd8f1a70f883f6603b3fa09f50db054e9fe44bd8044bf3c73de01eae0f8068754750d98adeb374485f1850ea0b8f58e2a55f45a80778e683d929a3aa7b4059911cae67d65f71b1fafa30152e1bf83c2f04a5d2fe6d5595f754b1cba67066b11c4157d267e82ee806fff0f40d10dce8d2dc57aedaf2ce713c9c0492e8d81a6da84431ae9d413a301b94c32e3dc7092d8af0f4276b1b21dc2d1cd42244fa05419240e47117c756d67a479dbb7ff45546b0d08b5849430698e28455eab30dc96591d87e8b25c362ec62d6992df4564e9ce7a4a01575de356f0e0e430232d85d4ef107f2b15bb0a567c7cdf39f9663b433d79448299e30905e2a6fe12aff088455e1ad3d8126ba6aa39d7a59a3ea2509af36a14d74a76927e33c851b2f92e5c3957e64c1d39df94bf82f5ac55bf90e6cf6474b3a6f6704a0df3fdc57fe3f17a1ea87bdc6dd98f312cdce8ecddf6a41bd5364d87638ee11c9b951bd8d2464253c77f703d1dc74660b646f2c40642ff97530bc25631aa7f00273d21b0e96a25a2eb060d36c7910ddb59d2795a8a47a08a1a43028fd6debeb0764a86fa39c8e049fa9e483ed358dd868416cc12b4b0d10fcd51e2a77c61ad4a6b719ab685498e335060cadb8b1542498c860b03a07019c77fd3f7c784eaf916f31c083b561c3c2a4d901033870bf80682f78de86f4ca393c20cca1711b85a8f2a3b2111648041ff451d98ff34d077168e52f29816d41873ec18ee2e5a81a2850e6984db40a1bf339ab220493ff82864da4dbc8e7cbe7a1dc5c25aa2fbda50914de7d7b14f3ed2b25f36703196d70b7b8e262c79509fca843317cf03771ade9b69d03852bebd9f6078e66fc2771bab3df922a0e451905fb2f216c8803e177746364c27a2d452796c6fbfdfe322a66ff4a59f9a6665ce6587761d3241b64531bf0e04a859955acada6dc0ec8adecf14291af4835a000f1b7dcaf5ffc36a105c12412ffe68dbb8b88bd2a082e9c68607fc7d8c21a93914ed7db738552c37a59369fcbb79ec350ba5b19dd4af8f6edfea5035aff8b750858bb1ef326be57c9973241f42cc742b9e6896d9621ccc057d61548fc1071a8fe8b34b7fade00264297f510c62974af217078293edcfe522d5bf6ba978525edb810ca04cb01ffc2032f28ac908f87e6d4336cec40bb2c5e4fda21c1eb6fc1c36bcfc1e01ac1df6be789df73a5e09958940f4c97cddd7ac0455f17380cd7936e7cfca3837c7f1c3684f9cbd03e838a9228a59cb7dcf04a877eee97dce6fa71f8511d167689b484283626a99c617d2114aaacc90eeb4f0016c93942bc345e10cdb47cedc2376d4aedf15ebba71b2d14fe7f99aaa2430da088902694bbd0951b6bf5c8f23df10b74db639f61d46b1e2e4d6eed3f790eec3b3d92cdb6b5b01962a573a186146c873bce48a1670ac6c5b1b3d0b5e5fbc361506b36a80682a2156e278f98a9d0910a39a8d08d053afa8af0ab638ec682017a0062a4cc22ed4ecbc459f37b4a8549cf5aaf5845d29fe0b5785e096ee9cb8f83a786dceb30506a8692bb1f95a4f588ce7031502d0c89bf1b7ff992cdcb25c8eb3ba408904ebdb80decdab18c8d071138b954cdabaf99feed19685dc186153443161d92da43072ebf543b0ac17cff3fbc003e36ebf9e99af77c15a124f1666c789a65c4ea43861dacb7ff85bfe43ff9ff8dcfae1bc8ab80c942fdb5a9aef0b20c14ce6c8e39e0ac07f9c23abe0aa9aa7496b8f70efb3541c4a4e70d143b14e1345f156706b6047f94770a77ee9bd2deddf14f3c994c30b6be5928970a60fbecc07517a872443bc14fff7ccfdf4105cc7acd6cfba5ffa5a5f6d496de63d839e876ec23215a8d57b74a4a1f770740fa09094d200b4ecf89446af7c0fc96bf8a9d71b1de1f3c6e6433453c1c34981a87678b54604b1a373601cf6043e42278f8ab60582c1406a8b488a86b83793af5ca3494378c28e206eeed07bc5b70126d1b9447382b1e5b0b396167c5c323f6eca56b41b668ef381c58e97d8ac3772fcbe1db9f118fe15ae4220836434b3f46ba439b4ca85670f9a6797ab0246afd37a728b6ff8ddd2294584a79b6c691ec2a16f7c469bde28aa39579e1107b2408a86912315ac2066ca534e0e68e1e63df2f1b0713a43ede41e440aa8e4d5f64a724fcc470168dede661909d541c5122b40f828a5a68710f6dd543f7e279c1b4a281b3d62910558f577133cfc85a1c184d1d4834a41af039e5f318ca0471c34f65bf265e525be65fc641409780dfaad4a063c3d353c073f3801532be65009a217320a333fc17d02f38c47968c152fce5d9f8269d1c2dedbaf83521e28f54746894195b0bc1eb8954a3beb5f84bac90d6cc9a2a9b7ae18316e4f1ce82680823fdde5e8fd9a6cafa32bc5129919187e26111ab2480d60024780ad25af9a5134b368c1041f83e2319c69d4b1cb37d22c825fbeeadf561c541372c213faaf453cbee5a42a9d1786c8109dac898c459bfe62070c85fcc9b48960a134b90b9ef486ea9261063c1f410422c0408123a1b442b85e881cce45a049610641020a5dd91071504280853ab89c04e95cbe784618ad60849486e47b2046c8aa5f98014c45625558427f69042ab94084c2945b742ef538e746b095a99a2eac9622478f56ed852fc2428c0218464307d64ab69ac215c38c018025bc7956a43bca3f250da735d445f27de227916a31243bb949030819b0b10ca18a62b685772623b8762db36318667ca09d17e82f7f4107bb9d51fadbe2940fb1f2a9592afafa7bef390338e0e9e84b7ff5499d60a13dcd043211c328342acb138729bc8ac0861e9be0431c5c331a8a81597a49970b93a9d37214bd2cdb083c49fc71842bcf3da8dfb6c1877ac4bd6f92af45fbecef336691fbce7c2ae7447711bcb5245c4a0879a39022753abb10ff452144b38d1cc27501ac35c75615237912007f3b0420351a898a46c2d32cb2f09c914987750ab412334071895892786c93a082a3ea0a871f84b2aa7ea093b57dbb12b53b4865c310bc67fa80f75adc647894763b9639c280652608a1e5e35e467cd86d590e7358cb9c2f143580af6659e0803bb10aabf9f91ba74b73af4917c3b3551ea6fca084404a0247b12610b8729d92b07aec348db78b00a04a96fbe72e47206c2884b6024f5aac9effc0508e6fa91c48d9d004690184202ab72228d4bbb3e256c54c21f1a8da119b4183b422e268af373a9e011037ec56dfe239b12e181b39b4fc7a8493373fb68f6e9a5748ee8df4c5784587f6ecc84bb5bf31c3a7be367687e93060f22e18222d22e69c7240d3b8e1e80fd7f9a92c1a49b9552624a2091fedd614aff7af6ad02de3aba81cf088bc3e2e56cb48f60ea4abb78c848020cea4ad6cda683922a5e4b4428978bb11e11412e852670a1bb6f5a6b4a6a8ca01b0868cda4a1209f2207116073ae7aff78a1f7c1c92a804082c3723a1ba94fd1357093d742ef458490deb2a02705fdf58977f9201a8cacab9cfc5a40892952266229620e8fb671749468d3509d084e72b39ae33e3e97fa7044e500286367603345ab0613c30183821143fa546c67c98d75c95731f6e02917c62ec9bc93885721e96ca2b0b3e684c3328b6e3743c14e6396f1c598591760c886c978ff410b4f8319ee52b26711a950848bc8cc6b2485a5dd6db421baf58cf409e2d93064056e1d3dc35b89b037f9be5660293e88fa5183430c16d967f809b421e183985842769d0e9ff6e8d26724f009aba063b57157cdc82e57a42d99ac1e423283e7c81e7d983622acc34cdd9a315c6b889e465684b2cc9fa48c8cda646abbc1c563e1de6f2b72e3ee57e56393a627768c945f1a6162f29122ae3560d26f10bfa721760c1e8641f1c0b42ca7ae6ed04d600dd9b9889661e10e9be6e0fde9be0ac4942aa60d80e5a47f5fb04b1ac61305360c73eed7953e54f39106e564886f6e0ce9682ab224cda9a302047b83bbdd9205b7eec0ae5f2e8ccffa5cc5422b69449408da3870fb81ff94564239de6df6fee3e9ca05c4cfee87ecf9655c4dcf8c8036ed32157be99281f0374e71d2dfd6fe2cd62ebc6762a30a8ed697727ee0818e1672ca59d077a8980ecd6df160de88b92701f36165634aa18986c63f5191b83d2309602038386f3325e92028d760003d318688f0dbbe78d7d1f1c91a02ee8670af2d20cc3711c14acd75acd641f7d6a37e217784ba4ef31a8d185b6c6c16169b54b7e6504d76151a980a69af9ae183a1e83f47f1e0a2ac5debc23673a266360851407d2545002f7555e4e340015d5eabf8ec519be47c7bae9d3094f17d1648b891c08f832b251671c667584c794852a588a4989f6e703924f4eeaa871361228458832ad1aebdc821834cc213b5a751f95936a78051294e922d4a9f5018df50e3989982581a2053eb9457a9b40ad525cb79566e2ce91e8c4c00595aa473f5969b7b407ec27dbdd73e449a64c23e2142750df5affa950f1782f451d390e7499281146f6689699f099cdb7e5faaa5728962d6649b28beac8466067e91403878772869a788ce28f560d5f187b321ae653507c0e6044c3b8678d093ad775cc1c30f8cdd772b1c4d6f3e3423cb6d1793c8c4e0f00c7bb15c09d31104f8424bfc4196f4ab2a5113e93cacfd01521fc0bd5c228927df9806442cc205c380d864379b7ecb3bb4d77a61edcb84d85c745540c676c56ed57cf21f5775066014a08a5d9d7f234be218b6d7ee017145e32fe685a161a214ca4631e28a6067f3549217171c48506c8dee31909e8e54ab7789e4e8827d50593f3916b9e23b766c65295b0e503914e7a185f05cd3682d61a7b1869cbdbcc056206cd87037490e2db8cc3fdf64ff90113e1d9a16ce503c21b27008407266a143feaa32193be781b043762e2cab94e487016c2506752fe9ee745d0867321fdbde50c0f56dc9a0ce4d49c18f34c98770ab8c06a541945327576bd12ed3663bc36af068c6c8d48f71eec939d7f6e9ab1b8a308e642826d964ae5d27abbfb93758118851213de837e0e36b296138a101a804b2940b05e1251edbb5165216c766f550b915d988b1e6f21c107d8f46d8d7c055740f60d7f463b3e9bfe0b197e89a339e0114e698cbfb1f3a9545f1d801c6374e292c12fa55a31c03e94855078134817c4bd90332f52fd198d08abd46a82b4428d9a7cb4ca244043129f601b8ee896836f9445c565255624a77361e268937cd7a6022e0bbcb4caff85ad8a82327e4503bd368ccacb46b92a2a97ecc06764934b435318cee234ae39d256b5e9039ac8890e1c20c33dfd3a5dbd80aa5b81b01af2c8a17b8a60e7a0d2ba007f0b4c35c946738918cae775183b36b542649f083a563491d092224afbc2589eaf88c745f2e91c9842012ba917024798e4496961868721f099e2a51754e1abb880faa74930c7139a68c10723c6daba71e005982442da755f2506478bce35f5a90e4e54ccf7b2ceab18be831a986cdf1f6e8b1bd07a17c50c7434e7a0ef299f790d36d1227c49364058bef719c42063aa5ab87de3c58f5c0e5418ec7fd3d74f570c6e3d8fdb11de7b83a6054102f1ecceb8326430a30e47b0339fd262dbe1e0d3989ba3cc64dc4e3743d40aa6b87420709b8c06ac89ddb2851730bd6b466182f06e1803c1c5cadf4568bb183acf24580c28c7d04a95b78e99d3233670071a5e248b1caa70e5addaff92e3b3f3a24234034dfe19525669361f544ebb0e71362a03594d2ddf0d5c58ce966d46d462f5c50deb074d9adcb6ed0713a2a061a9227768616a06e1b79cf30114677858eac01f172056b70eae2dbf1b6f3a128c2658719c344a3354192642d6596ec8ac2495219e08815f5c929b83bab853fb942f04e6e19464fa154213c4be41ae2e0b3fdb3b8df4e2202cca11a605360ea20289106ae11080c340ce2bef8a9b8030ba624fcddbc92bf03ee1264193a41a98b07b90e30c2089a37ca68a20fc31431b316cc35c02261f7a3a14921530b5dfdfec568e5e66155e177b15ca4647aaca803d8739417546000472eb8914ccb559d80d71899f27e83f8891d5a51b4f89e0e8e46056880fb4aa482585cee629f764de49c9ac013e98ac3734528aace492ea7d255317260d100bff2912b329b284b7da01330e6263d76feee41fecedcf21408614b55ba770ee4513971ace73f7adcbbfe89c5af5cfeb180e33a328a1b16279b8bf9a815f154f0d8420ba6b057c93783fae1778cd40d221751fb50b1c41e448b5f405d03006a80b9016010519725d5442aef34c3cd77654f31e9aa32d6c16e938d9a7ff95c73af321feca56dca8095cc6784b28ab529c7bbf24859f9bd4ae1798a86df17111056d4296c124fa60156c2a652657503a9ff492b5866a704931450a17566418f4bdf104714f298a5c2d23a89814476a99a7449da20f17c22880225a1263194e649aa94ac4a7b12fe44ca73ac901883a4c89da65de1a1d8dff4974f3396424dbf4df58f64150e2a6cdd63b11a572aa2a73fecbbd066587afe742d7d5470eb972b06d4fc4fd7ae70a0f86e0194403aa1a71e6f12cbca82d4d51666131f5f05291b0f6aa5c5ac890c8afa27a85d056c390fac084205789c8c4a3656fb360e0dac166a915d948884542aa91851cc9af497be02395427b2427a3cc90e85fa8ffb301a95a77e50e95f0e64c9c4cb94f4ab3f4e716ba82a7581f7803f682d0146013894520fcf074b823cd2ac0eaffb8a55be934cb814e079864a0b411578e5a98efcb81c062ded932885396782a18b8cd0c429985dcc1b6ef2ff02172ac4c8758d6fa8dfddc7cb9c387508417f58c633730f5d25f03288c177f0cad94c8bfc0b6c31fcd910e610cec69f40f3574c7ae61dd11daed9cc48ccb8bc39ca8f3840173b40586be07f9b99b2f11b14f4a1c030f28634997f0c666a7c08b7475c406ffc708430d43d12722fd0e76440fdc1fb1d2e3db170e445ae08da3a398240d404c279876257285a99469448d4514863280a2587a25939d437486d9a2ae8d10ab06a277e3bb7b2582dec850e811846254b4995b62a4491be3f036accbe57c6afc60ca607e66d019917fc315866314e8b11e759d471f5687ad2ea5f5ae46513f79ac0697ae20e8dac531dc126131d82e36d4812ed0b1e526ff038ef0cbe33d5ac8967279494322077ba9df19802bdd80c9f22bf875c38a674516d91f5c464d75617e46fb4d37943afc799471489bf896ebcb09c27475416e8fcf697a7d57a04405825495d364ceb94a1acad6003269448b683a30f7ece280759c54a780325fc9038a82193090bd7702df524cb03b121baf6193299938e341f6f103c0a1038a5dd994643e0c84504d57760c46d5680b2a46176309f312310d162dd558cf0588d2475c458413cf0ab5bec01b2038ed18eb64579598d3131d8f2b16cc70838f4d1d3748c407ecdc3500b0e21cf4ec73ca7c77e610728098cc804d97795d2da905be09a1781f33ae1eafbda39ec337d967f101335447e941c0a40225743cb03d698ec6c9735ee55e4ccd9b50e86f577b096b31fc92a1da2f6fcf329a5cf1c77f62135c2cc69e71b3f7bb2f0553fb1e39c9d7dc399f29a0141a4337f4ad05e5fe1fc70487746ccf9ad6a9a1401732de0699315192fcf3b22e4c28d8a1a076078e2c8048792a05efd7a9286c7dd01d6818f9dc8dc2f326e065e288b48382cbdf5958dbffe7a69b4ba10c9da59c30eee5be2899dc46e16285cd66a882f31c82ad9d68560b4de412abe808618e6c09848dd9315f2a4bf305c0caa1801bd9af4d0555daec46ec0fe0914cc9e97d6d1fe482dee9483e721f2ed98a8663c00a896d4f48fa1fe385777eef90dd94a92a8aea8959a2d8d625f218cc36518e530a28610c0b8b36739f2d5c3902fc76f369f436a809d24f76b434eb04b64f11b1f9b58a549b962f5c5079ccb7307d47e4e29d5823feea5284802fa1c9f6dac5b8034f611703263a80dfdd16d6b3f2708037edcb18906697b6d6c4419c23e5c325cd7e0d6d85924370bfa3aa1f0ba2d7c2ed4f4e268a74ead5401e9007a3b6d541af48dda45da5f311ebfb84fe36d170079e671caae6de67e3d3c3a9a12f639f35e3a1ab573a71e2f381da5a3d070eb402a51a30c94f35de10cde1aae56d792e79f4864d44cc87a1200101f506805896f05ee80b5894992f1df3e9a244aa9690bb37e249a8bf61925f86d48751dfa08859f946a2a434b62b247542b31c9ee79c8997107ba070ffc448d4c75fb654263d5c1c5d48bea7ba98dfa0b8894abdaf81119b9a81c54bb90801aadb348d07a4254de36c7036c843a11fb3debd84e8b1f7ef0a4898a59317fc7190a22f82efed3ff97f7b9d78af6253dc172e902e6faf9aa0bb99c0449130ba1ba907cdf74d7403cd5941e0c621c14e62c54e95ebe488ea7ef7501ae0832e5f1b96054f3d4e913e4bc538186662eda8a09028acf3aaae205cb2d3f6afeaf71312974b630f01122e8b4bce79b6c46947613ce93e869fe33d87f72440a03645c70b86ea46fa1084f785a44c88f173da83bb4fece5d341e2f9a3a7ff71058f13508efb1ddc1eb9477ecb2d7d9b0a3a501b776fab7f62481626b1af45b4f6362d20e6827a80157d96d1cdb038a61064727d7ee8895db29b008aae6d83447ab2539ae02111d0b1089e8002f54a1a752a79ed606aacf40a08b885054c9edc592ad3aa0ce857dc48f7019992d604754d53c403b1e5afb2428161790b712f63c4f9b54d3e25c02a9c11d3e46dc614d63dc8b830f1f071b929e18d706f06142308ec6aab9b0862146605546269c31594ef92d1eff5ad258d210d92b7deb1c066540f7330fdc12f2bb8c9094d7f8870487147d96f10c901d4baf7e902e1d4d7603b8fb5e9dc228af3e73ddbe0f25650554d2a73aa2f3042b6a5a10f37cf321babeb46f4a68738bd7c17c78cfd67d6df08565842f1d4b7851b8a94403f8cf02a1554f21331bb92df5a2f8cf85e57e11b28a527b87994fb77e31d13d8721d2e5eeed34d77bf2dedc2e4dfdf74f99ea53b30a968edd04c735313dbf7f953ee44375b792f6fe24a860d13e5063bf10ae20a1324f823461c80daf9e56936c7b47a21f9ac0625de469feaca073d0a58cf419178c70ab5ae866867ae03f215024f9c22dc7e7220a56b91aabaa46848b9d9115c1135cec0084819b24b669fe633857e0501497166b8391e0321c0de4bd58b8e8660d179f7a2b69b1b7d2dcc8c0a93aa200fa08c1e9a94437cae0547f426c3f40bc86be1b72f5f42b603d628b95d39ec2a01e1af02009caee4f78fa4c8b68c13418bc216bdea02fefa41d740c19baf3087b96f79237edd2c2824a01a1c5b8715a2c9dd4b46a7e960c0194ff29d323f8fa63fcbe963084f480af51123a78a54b5f63c1fdc03722f804fd349fe3fae93ffd69985b5b0e6d8d24fc6342d927f67fda830f4d8211aa7546ec649be996c5f7c65608104a5bda31c2eb3cc49b083c66454e40e0794fc788cdf1445cae2ad717aa865f893cdcf0e1c3750d0876c2d00ceb64feee7e628a3cb23c4bc68823a103a6e71a0eeb49bd37be4e27b4d8cace7cfaadbec30e4bcfb4e5f14e63c77aa890a80d31b443bdfdf0cb22fbdb2dfa6be06d64c705b5f0c48bd713147d34a6de0d6029097efe6abdddbc86ef410157dc5d209658d9fbfc7ea5c8815603013a82e0f4a05669f6de31c03859758447b28b846d83952e9c1aface06fd0767886f5246ec7705bb0b93b140673c963e2d95cdda911ea4f46845b56c143488df76c4bbb89329521831e49d450143efc52b94625e0aa96ddd7f4a43c88616a66be8cc0a870d6f5eff9b27e95e0a00bbb212d15f6f566f2b8a4a676cd3bdb6a10cd7c04e069b262cd0bd8a69b5d08ba11e5857990485144b0f8f1f806735d900278e94ca363b0e9264140ad177230cc8a185cf62a457cc9bfe9820cd75a8e855c2dec5e3c2b567e0087d71e830e21f5ae65b7496e53c5cb06cc311f4a20c09b2771384159f34e603d6634913f15f898febba299d84988730b2bfd004d2c1de574a8bcb359cad78422b19ba5eea528095fefcfb99aeb93daf598b0f22111ff58e72ce5919652c0335e838142554833c2ff3a8c85241f5f6de7f90e37a04d6de211062e5a856c6734009bda6fc67bb01d09db3582a2517233cfc15a7fd749c33dbd6c863ef7e051368f7787fc087c15e4422231a9c1c3441925d5936c62563dd64c1c92b3614bcfec534cddefa5e5966213559ec7ce9b2c81eccf6f7b4c58d49a84272f59e361e4b4d24b15307addac65d879e25df2a95b1b7db975ad5dfeca0dbc9f9b46ac74c2bec643dae93e51a3fbf1975a40def506ad397898e0b92a72a8e55af5b236d5e4247dadefc9e3668659a8e2490e9a1c62f70d8d10c28207518126ee4aa15c93dffa83519a39d0d02a99fcccdcb538af3c8c37ad9556a403649b0ff924e657798167423904f68b298fc7d64c342e6626683738e4a64f512eb86fb1b9a29ba1827d250d43217142aba17962664b8396c4a0376e3e44fd984a10151ea5dde63dd8bc5c95bf11b2dcb8177ab3065bf8ce270ff9fe11f56fc55e11c0a3a269241b2d950b99d4dcf8f50a307618c3c1922dd67ea2c6451a272a7b28f006c9ff6328725624d7817c0873c411a18b0d87bea27ed7663438b38ccec4b087b11b3f74a96b8d8a236b367bf590b8f22ad3ddecff1e9d44c281220346ea2f0e25e0796343697f14b5598b0096781d873d3c438ed49f7b481a7853746141055997a5e24b41f1926914a1463640a5a4d9c57905135d49afd341cace552a740622cb2a82f84a8355f3d154ca930014f1f63f8aba8809e8225251883a53ad52f2ad98423801f3e58f12da67ab2f80c5c600aec6123aa9359c033e4677ac11e0ac3e379a76e80fd930c2895a10b82f5106f75b31ce035db43925b5ea2ac68078006d6e33918f09752a75323820187d0603653ab211c53a4b2e5f96e44af8ecbe657cbb49637a922e2a37f57b1c01caf42ef2bbd5999323639bc786ecc2b80384bdb0bdb4d5fa2f272cb5bdba4121aa94ad6d2af4ae48edb55599731c79a467daa8d89c4996018833bec627a05fb6e9e2576a7351065e84b0c1310698dfb18266890b89815c798362baada62911422a310c11fe0a5f2cd7b5b931b05f88f6a9dcc028e5743c92093103ec2d21851d761d6aa0ba3839a10833c14875fb5085db2d7f8b7d552b7dd5b99b8c3dd101bb72f0d35fa451f3856b08425c7c637f9661a5265f6b577ebf59a6075b4020b0d2e10161580c39aad306d083860d8d53825815d0254ca455ab7364908ce9e1b50e63098ef0803ab032650d8e198d8fc53e93a1a5a5fe1fc4c46b6ed1442650d952f5ee5aa8ba937ec45858d55ae1ceff44ea351c9919516ac0a5dadb20d2abaf60764bb8633a292558fbc46e9119676ddeadd256e478e0214688145094d41792de5d8cb4153cbb36ffe70c2a06daa4a840bcdff51d55462a5b5bd961339ad82ae368a25ac6cc54bc146dfbb44aa408a2de3e5b837cf688a283b21751b0fb15f4a6d6e1d3148ace6876ec82e34b5baf19920c5f521970131cbd9284dc0ef080b9449b9410706649ec5a6c73a87a3b4a3628ccc8d23ba346612af38bfb5cb1fdc47ec8f43859beb9bebd742fa1ac0faf79552e47c0a3ec7a3773da1a1f43362d7ef59895fd9accaab5116f346e3d0d98c0afbd0297c96100e086888cc0ef9fa31711bc59629e4f2317af42357bf97d5b500f530738871bbcfc130713ac1bbcb43f4dce650e05e0ee6419a8b3227804e106dd388262a5eb1f101dedfc08e36719f0d941b9f64924ff40f63d834b0db8d16ccdf833577246a38ffcf0eccb337f4875a4eb819314f77783ee8a8e23da71c927a6386c9d064539c3261a163c527bd2522993d9e4a365cb3f8b7fa64696f7ab1242c4d4f1ec14f595e8597d134841a362cf8e04fc6def6fee0ae626fb44eb399ee45ea6532ce896211a0a1faed716531dbcde3c98c332785a3946cb39705bca5a962f862395d5839694b82d5c19f814cb6abc15bfc3a91bfba51b80daed8d57f48c2af2cae346032a1e5ba000c555c86ab446cbc3c343c30b0ef8b4c953f8cdc5718374ea74b9b62c5fd0e017fd23c1b23c531aff13ff2f90750e8dbe2cc8fbfa71073520f0c175bb2a5a194e46127d9f359e4aa4b973ec64c4486aee98c96cb5e3808e4078c8674dc5001501e92acd3ebd7921eed3907ec5d01a62b3e916d440a3f582a1db28a068d87bda80a29f2ba147512755bf706e0e80c9b4a421bb91b6146fba20100debd239486a15096446c15a7f004c57db9a7dc83c296148ca24a2300bbd96473a6f07f9f3c6998879f7db18030bb6c7119a66a0d10d016f0e5b182c10894b91343598052bb665e9f22b84f990d5c1a619a8b895df11c15c6dfd51b099f95edd47d87a46d26ad350a4506637f146a8ade715003aa86271cf016af97b1ab0a27ee3b8b533beb1e6d33ddb21aa377d80ca536d3cad13de0c9db42fa8add3ea1846e0767c220165827ce3722149a0596e7a8abeb66d3c607ccb093841ac836d86766f14ddb1a5f39b139a558cc6923ede80044856ae413746209b78d92f3d188449c61563358c4e08499f1e89c1f8f2dc9d8a8d0cb792e20ac3b331327a97ce4435adc93d83c35b5199f3115217eff80f7efa60d0b99c6974195a730cc1611482c741643fcc24f02cb8af1deba893da11c099e40b0f8421e47f4c1fb018752621b93855f7881fdc1d494524c4c85d4ca6d052deb526380732bc495b9f5a971689866f69085a1e215b728538f668c5c334a35fa498ad0a560a99bed1f7faba6bc2ef60a1006687e34dc527a6dcf96a494f12fa2b31d061bb39525f22a68e771ae06c5af3d982a25edbb6bb5c71c5eb6480a830d2665f5661e81df31091f0b5db55fb7cd88388983499b7c6fea22861aec29b349a2960014778bff94a95b55928f66b360fd1769e09a2462c18c9fd270aac8e0738c3343705bc4ab9ddff16243707b9415a4120209f4fb485835e1c32a34ffc214622839761c6b31269e2d45274df063ea2ad8d946c634552dab13f6bec0e1fff4b026aced9a32b9fd975302db979cb391e225e138d6919cd67ee4934cb28736068e54d0aecd975cc440e5409b2f825f66ac87a9d42603585a186648e2f4f9918c8c5e703ccf636ae0686d1827a23055ba6fb5b73c36d2196ec3d16298d1884b433740d3646895c25a7ea4a9577c835dca19d88e4c453c4bd5306ccc794c89ca2a09cb84c23a23d0f6cc308dde34471c9fa018b39e41ceeb65133aa5a604a6af97c683676442419cdc961d3001ae2816f27fb4aeb9b5264d50039472fbe168d60c241b4634b34f3c2bf9195e5925009d34968c9d8558d9651c1c9aa0b1e5fa342eb6ba75b39112af205ebc115908c07b1cd88b82c08ddc5ef4c005122f47824de923ebbc7cd6abbb7570e1144a2a0e1928ca74d12c0f0f13b8fc21f6e3468fa7a9ceb7eca5f067abbd38f7cd1521ba6c83e7f6d6209dc46d6a8ad08615d17cfdb572d48f18160c9fade36a3506d31c9d3ab4702040471235d49e18d3f612f5fdd9cd036cc302fe59c4170b3460b25472ff000000000000000000c098d5946d51a5e9a624e402a80f858057a4ac8848b9093778cd3b7807efe01dbc832d460504390bf90a3c0b495ec7f13c5b42a25a30a71695c833bdfa51b360f41cd747be8ec3b35549002c18724a0cef9f90b38b7a05d3549af81244b58239cb05f578ede8efa982b14b522c7a5430b95f9e488ed76c3b5330a7648f24d9aeea722998a287a9193a12c78e82e9543aec473514ccedf9224dad85b2399f60debde853edb71b0f2718d3d3ca871dd6cf2fd90453f214a472c8293acd67692000138c6f919ff3e5079225b90453c7e77b93efbaf65782297f3a5965497b590a19418024183d8d5b78fa4830c7af152ec4fd0886d02a9f23cf8d60b0c88c96969036ef22983aa40e62caa58c9508e6f8ea6285b6698f780886100f9f24729c63f8ee000208c1a85f612e58dd447804c1a4399a123a403056f037c966d9425e7e60f2b07591a51adfaf0fcc217fba551792ff1e18b743c57f492edd260fcc3979ff63497660bc943c694142001d183e08f92484656d8a8400393085641f677abaf4142502e0c0a8bebb691621c00d4cae13ceee3d8a2f1721800d8c1d7f4708d767953eb5305da41016232f9d7d68619addaac91ea2d4f3b3c02d6461f02fd3b5900e46f2b13079dada894a291da4616172efaec9eee4b3f32bcc41df9e89a956ea0e5798e62cd9b4f5e5945b61d4d2cb7233d2972cac3077f2dcaa93ff0eb2ab30569f57fcfbf03c5215269b20293edde5eb3415e6387e5eb508d1b30515a68e72a8321f75ca71790a73c4fabbfcf9be9b98c2101e27f6f57176bb1406dd8e3e963c29ccd9638e887ed816a330470e3bda3c148549a33de7ae2f14a60b2613452e54c50d14c6d0ccb4b4147e8220c92677afef09e3c95c149b79f9d077c2e01e3e549670412bce0973b8fc2872ed5dc7de84e1b5ccf3634bdf7f68c294531fee5b454ddf4c18afb365c45131616c4f217a4729472fc9254cdef15896a8a3250c1f47ea5d1e2b610a36e99235d299659430ba755c792efac53e0943a4f0f92f9b8fb77492305aad870ee3e27e942e1286fe487b152f64b51f128acc64e9f4f9230c57b136dc7e3b3c8e3045e409ee7f37c2e8d166c8990723cc9d93dc7fc81d7d14da2dc214e6267faa993c63518439ba4ca4368b12d126c250fda15ff8e41de724224c71aaaa1a512bfa4398ece4d4e388863087b81c5369d25b14c22cb1d472cb5c7cca11c2e0a66f314e3b47e5d9208cbf9683a9becb6f9d09c228365f29baa3e8c03f65d8221086b1886f926b9d3f00616abdbda9911c86f90773aeccfcc9c1c5f1fc600ee257b454d607835cbb445dae9e330992cac4167c30f707cf8b1f1d6e93edc11c29e9a9ee63f2e47a3047e1953be7fb5fdb7930670fb6a39c113f79a7dbb0051e4c1fd7fa546424eb90c28504f4015bdcc160214e9944db0ee61042ca952ccb52751dcc66af7dd1b3d773a68361f5c38e3dc77330476fa313cfe5fee3908321c7fb78a392844e471ccc1d7b050ec6ba0b36361dead2bec158592a1f7f965b59dd60ca3904cb716cae69d8065399b47c7b8e193a1b8ce9336e5241fa33aa3518f7f4762b470d46cbff1c44928c3cf93418e4aa24564a231accf1f6747cf73398ca3fb263c5f3a86306739c3d2c4931bdc316653054e538e510f1f66793c16ce11f2b4cbac8378fc164391ecbe3436e3b6705b785184c216946927784c114d5ba237e98bfbe6c74d8020c0693c8aa74f70be6ec39ad7e687ac1f051ae52f3bb60705dc921b992336cc105aa2db660b4f071143a9248f9205a30c7510af1382f0be6fad877e663c114428fa78997cf17bb82d1caf36c07e9e85159618b2a18a524dde78a4d0f2a98627f9ef7587e1042f482a30b1a35c2e0a2055b5d1c615c5d608b29983a2d89fea7764f5e19cbc0165230e9770ec43feb778790ffa2020358c000beb07183015e5460000b18000464c89021e3bb602e4ce0c50a4e148cf3293cc4e6a582b7a40b5b40c1e061648b1dfe22ed07edb4b0c51362b08513cc71b494e9f1b209a68faaffd22bbe8794230c5b30c1641176eb83fae86205c7799fc2164b30a5d78966569f27156f610b2518d5264775093d09c7122e1d5fcecff3c15fd8020906b7dce61237fe2687d4d0a2f161ace08be783778b23e0164668f5d22fece5300b5b146171cb213ee272d406a0010710620b2298c6bf83b5101de70e72c2f0e2c300830b30bcb0d15e4020095b0c810f72847f095b08c1d8b29f3a4831e27b8e83c2164130845c28eb91ec41ee3811b6008241f4a3c71e22a8876b61c16317071729b0e1c50bbab06181ff06ac81d1802d7e90cf4618f71ce56ce103532e6b29bbc9d9256e41d8a207e68deb20625677fad82e40d88207468fe3f073d4d212f5293dd86207e6c8a3f0dcf519bb1cfb600b1df456793d871a72da29ed850d2f2a115be4e08ca83877b7c0c1163cbc8bebff28de4e6c71833b3dcf637bedeb0edec206a87cac4b926389752d901c99e67b103f8d69719a6019b29f6265167f7d9aef70ac7d95851e8844980db7e9b762d1c71bfee993443a0a2ceef99734dd9b2ed9739688f18a27c97c36afc8514dc8ce10c31584b41b31625cc444a7156787a8b86e072be838fe0829fce4f0744118b90a2a66b4f5aaa788aaf073f6b493c8b9e0a5025f978e5b2dbe24c941c5371f7a36a5f724e753289652557c5d7d1453bc17c97d3bb090214629f6f9702a3b342c5d52d0da7160f9be448c5190b324044b9ba81ea2289ac6c6e408c5f17e781d821030c1a18030c0e0a20b2c33c4004591cfa3f0f2b9fe937b8f88f1892c566ee5d4a3b36b952186275ebffc09ee91952648c4e844151e3b45ca3e5e2d12313841d6ddd9fb78e6e64d3c6baf9ebe42469489261ab5949649f51f57993032b363ff52f7ac9848774cc4729c4b98f7a6f4e3b4d812ead427ab88ee215e09a2c40b1f84e5a051a48841893b6e7a0a9e1ed60e22c6241af9b8d24935e4639504af1bf7a972d26d2691306e5df2e0eb3a9d4ba79f05a586189038942cc95348d80d1ff1e55cefde71a84b9f23f81c215de769a68b84188d38c7510e92e3b0ae3a8c60c205e9e0928a5b16615a671b97a022cca84a9de291dd4d2776d81e27c2e01dedc30f7e1271af14d8b8d1802ec44084213d8ea27df2bab00f740f428c4398f2c7f1357e62734c8c610872b023fec1c6c506310a61ac7871ba3b96da44b7c42084714e3eec9ed864cd8e1c84c93b274f79278f87d986114310669b8e363c47a417b704c230d926c16ec2b6e3d82e6cfc0d05445b29f97ecc3e738f72c4f88329fe6d3f0832f77f0186175c5420861fc8113fe6e2cb27461f4cb93d2877a9b9460c3e9c9d7371ab3d18267cc4978f9b1eac9f5ced0862e4c1349f7dc26989a758a38fa6c28339be465eec2cbd1c79773069a5f839a4761cf964566807b3f4f5a4d78e915120461dccb11fd54e7d48fa1a113a982ee8747ccad17a2c360793dc67c9dda15fd72487d6639bec0d1b5c601ccc95f4bc3d7cc7f695b5ba06c48083313652848c77f059d53718ff434f0e19953b4e5edc5841187f83861787460ac0385a10868d30ee1410c30d265bf370f696b315724c10a30da6ecd0a1ffec44ca4b712ffe461e5f64200c2e1480e6c5f105180f88c1064ff27ed9487684d30b2e6c58e00531d6f0d4bcbf7f2426710584918206c0e0052d70410c3598badfd7239329ab06a00107a4c1143472ce92474583a963d9b4bc547c7818e30c268dcbf6ee2fa0b9e8028c23410c339893b647e99f7797634f8c32940c03c420837962533fa7384b5b7d8c3198c385d4b18cd4623056eac0febdcb72f47261408c30d093e9361d421b030c6c94dcfd765fe85eaca1953588e1858dd105e3c21dc45c4e498bb185e3f373b1ed17701e03189021a36f68e16264c160fde551e7f1d6a5b586ee186260c134ed39525f89edaf1f85ae60ca418eccc3f48bfcfa5ac16254c11c4fde8f2a9dd3c85a16f05cdcd00052c114a62c59aa8fe4a5a618534024f476cc0a6693d730b848410c29ec9ef2256fbfcf3025b08209288001cfc50d0d6c1519c48882c78082d13edeeecb6515cc3a0610e7cb608897f3e3a43fd1bf4d3298e473ccf3ecf4bda96e30630ca693ce71d8b1b23b454ac1c10c319863fb4e57be130693dda889bb9de4e83cc060ae8abeab1c962f184c42655f4bd2a1730e2f1827769e4e1d077b92ad0d6674c17c2176f46817463f5433b860b2ea388c8ad0b7602c8fba1c68840833b460d6daaef22887ecd1e5c88229afccddd97eaef02158300769776aaaae17227805937a88a567f3cdb082219ee5884f7760216654c19436a6f2c707b9aa43501033a8602c3df5fe701f16a2650ac6a81017eefd713c340331430a861c4908fd81fd8c87c46146144cd9b36cf7e3efeb08ea0c28982accc22e5659434b04339e6014c9eaf97a632b29aea1559c60b41c767071cbefc3f5c68c2618527e0ff593759634da173398600e2687b4e913cb9f820777d1c571689413cc5882692d745acb1e77dfe76628a164e88c24cc4082e1c4e378d34143af30e308e66a95991c9d52c5fb6a689133c308a64ab3fc9a2c7f12db456246114ce3b169f97f882f920168c0011648c40c2218e268e4c95b1f42891943305a0829428ad50fac3f5012338460eac0232c9d981104b34ca9c4cf396fe7396b68bda06968e5c9600610cc9683a073f9ef8184687f60160d4f7aa3e92266f8c0dc711ea767a58898d1034378cae1722c9e2266f0c010f9eda179f5efe7750786d8a1fe29c2de47617288193a30577f102547e5c050792721aabf14dcf80c63060ecc51d6b162223fcaf560ccb881052430c306469509e99cb35343cb8b159ca940462d4ce9fa514efde40964d0c254f1f427ea429d5e9d0719b3305c4e99d2792be23f3c2b2490210b73db76d2f934378bd31d64c4c2d86e6a973dc751062ccc1e751ccce484f515a6d8a8b614cd3ac8dec5d1ef0517295030c87085a1e38f53a86b4fe31d5b4365b4c268e6db593cf0682ec038d86a0b325861ae28cb13a9a372105e19ab304c7bca1d56a4d3889e1a5a302813830c55185654a2ae471397acd7d0f2028ca3c617990a737798292968a586162a0ce5b1488ea867b1d50f858c5318274d0e2b64fb386ab5a630fcc7c5f071cbec3856186494c228973eda8c78ea511d5298a3dcd94356728cc2aa924c14c6f86cf9539a381466adbb1cbeae0285c9c2c2e688bb8f6fc7274cd9574c5e27f67ef784f9db43cdff8fd20973acdaf53957faf452e184f13df2502d7f30056014199b30777496ad9bfe41fc9a307f0e1ef677c6781c2513a68febf34be5fbad2d268c1de63d88be189b1f4d43c6254cd2b9c2c37fbb9f485ac27c7d49bc3a142b619eed18e99e2dfa3da1842942d9641246cb297cdc58f49fed2461f8f01ee4345bb3795924cca925e5384b7efc512f4898d2e3bdac7bf3c82492f108c36ccd95ec24c311c6358fe53efc3052b0310b321a61b624611eb4fb549c560623d0f7d8a2accbb190b108b357f88b1f5829431146f150de632b09d5eec948846132247a0e15958188c7fe2b5bfa8628e310e6d097a2e7f6c4bba840d128c2022bb49061887daba3560bbdce4146210c15dfa2030fc35f321b1c309341085390bcfc2562b993e90419833079059f903fab166408c26cba71339f1e739d0ce399068db3c3808c4098aa269be9cf7fc3c6175f94ca0084d1e3e4b5f89e5b848c3f9883e71ce7ee2865f8c19083079523afb3eae2f0820b13dc3826b0d907c37f59b66462b9cd8364f0c1e47156e914c1a33812eec13021f5616dd352f0482eda059f32f460ce1dedcb85856d6dee850d2e4a7140461e8c2b1397923eca56d1b5ec800c3c183b8e139f3e5fe6e7957107e374f03bdbef90610743e545c4d0dc0b651a59838c3a98d327eb841c78b75a44061d4c2355da390efa111e2f630ec63889f46178c8c1fcb97f54b2c4f6d14c461c4c79b267ad905d527c30f60132e060941e97c871f294cd426a68e51bccd3bfb16e39e560a708c8708329e6bbeee4fd6883d13d5be8ed20df7e2e185cdcb0d1051f6890c106a37dc6bfa5bcebc108038c722e630da61c4773ff9185d8e5b00c3598fbe3dcc1c769aa6d2784a08c341856d75f3b9e6029a686a501098471e359e0858d94830c3498feee63fa2297869d32ce60f4e47174c9afa67d4086190c12c383e9e05306d36f7eca7e8456eec96088eb28a47d0a0b790ca61c7ab4c82945ed8718cce75bf51fa47b5d1d0653de55a77e3af71c07180cd142656544a473ec17cc162fce5f4aecc3d40be6c9f591e3b2bc6c66174c1fe48bf97ab960dc8e2d983ec77d66a1d4b4afa30543487e168c6921d3276d2c18c2756d34dfb37bf0150cf1b2fc87ed68f66305739214274ac7510553c497fb38b73ae40a15cc1693a6927bd27e85c89882f14c353f64f76548c11c2a313cae6c3ad2be8c2898c3ccec38be7b4f1ee46540c1b4feb199ac764b84308d4fc87882d142eca495ee9d602c8f733f0a93cefe34c16cff5fc9d633a2e7996076eff65c8f3dfbe3976016cd9576d9cb15b7128cbfb3df1e73124cfe765f219dc7e13112ccb9720e739623987debd6ec423a6a690473189b92c8412f8279cefcb244e84430dbd47cb4581d543c1f82a94d23467ecfc9552e04e3fd66c7e6f484fc04c1609d7b1ecae54fec4906104c395927e1237a94e3fcc07c2be75ec9373dd207e6c0030b15297a74ae07c64ab9f915ef1e4ece03a3a6c7dcce1d3b30e89da79b6cd181397adce99e6b0e0c2339f8f051c9c681612375246597e31e3730e5c90e39bda465d8c01c9d526bf5d6b530b6deb430f54795132d751ca7ccc2fcc17efc1f6a779847168620d172b695b68f8d8529c79125c9c18785713a07d1d4c3fc0a634d5e54995859f5b22bcca9444ba7cb554ce55618d4b7b4a77527c713c20ae3441fa930ead3b955984ebf42b8bd760f535598e67ce3dfc3e754692a0c9b3fb1b3127e69820a73f493c2edcf851c484e61f6fa28c63afad8595398d45a721c6cc71eb7580a435ca98a36968314e6b01f7b0e2dae5b5f3c0a93b8e7dc56cea230e7c4f5a449db71421c0a837a740b2efe923a0714e69bbefcdfc1774a399f305545e7b5e0f184296fb59484be9fed3b61ca619d5396b42c7a4e9883f9283ab116e6c33761900b1d94e78ff352ae0973f5a5081fd599305dce13df225a7a0ec684c9524c979cf541bde312a7e41f6efc7558c220294cbbb6b784eaa884e953983191303bc1a58439fa3821d557b2f49193307e1c050f2356766012499854c27dbe6b0f257c91306f64d317fd0ed276903067eb87f74d0b0f628f30f9c78f9453e60873e4e71f1e3cc73d698421fd8ea7ed1861f8f012b9f4e0aad522cc95d633f75184394a845cdb750f3e1d893044f30a71443a1061a895ce716ea99a528f0087304577e93c5e663bb721cc7a1d4d8f648530eb74e471ec10c21cff477aa62231da1c8429ee3aa7ef485cb71484a13d36b34a92c33d2410c68f3f4bc6a47d460410e64995bce7c33b0bf10fe68fdd27a63a3f98c4a2aae558a454b73e9872da4e93d3c60783841046ae2ddf47d983e183cd5ee8ae1056e9c1f069e2e84af0d419953c98bf5b357f7cc2e267098007a3a478dc9ffda3aa7f097007a3fe05f9683aebf32f01ec609ed7df93cb2221894a803a98e3f83b4ff623c1723a9824e4a0c2caabe54fcfc16839dfdbf6450ea6b493ef903fbabcc7c114c2876ca9cfeceb8583f1e6f306737c713fee94fe5210c00de670971869c27c7bda60d68ee711125b27ad6c6892c7f16b30eea73bf71ed5608ab157f1f3360d8629a9d21b0f0da68b1f7a8a0a57f1d59ec110b32b49b3bd623a66304c9876d49d9741698b6e913f9a0cc64af10ae21f6330ef79fa143dda90481183293d9a7d14be72a3120643fcb7e50bab97f2e2040083c1a2cd99d5a85f30eb7fb4913ef2a05356bd60f0b760a9afa3325bb50b468baefa134644ff542e98e2b493c4c484bf44b76030c7a9fa0f7d7a3a238928271852b228d1e379770a6e13cc816aec79e49fb8b017130cf79a16526a42c77d2dc1683152e33d0aea361e02885282a9d358ac685c8af1619504b3c54fa1ad563fce7b6ed4088354a290600a4bcb3d194b1e414ad411cc6312cbbaf2c974878d60482e31c2c3a5c5c81e24aa0886f08fba6db299021b371ae05e70d1001932445144307b2441c672c87c3ef3c3b0c1011932720d3504a36709be5ad17639ee1082a1c3e4ed6d7f8360f675bd12fd38dcf71c100cee16bf83f3fc39320901f503d3e6071f8778faddeb7d609290fa9f731c6b47f5f6c090b331eaee761e9d583c30e6a84769970517503b30770ee22d5d2a51bd1c30b848004aa074608ecae72ce7df0e5a5e0abc30011704059503f3fb9c8f4974f8a3e0082303c745e1c03036a96e2698e430923730979bdec48d89bc9f05eac0a83241d9c0d87942b05fcb41b530e7be47a9420853261e440b53ae7ae8796d274ca559184ffd52f2bc33c9c25cea21215dbcd309140b83a6a499186d6d2d2e8d4a5818625afa0edd59bf8264000b18c0a7e0a0400664c8a05179a057985344a7cfaef482a65fac0005366c48205d618e362b3cf4b9ed5ac8817ca0569892c47964565773d1215618faf3855f8eeb2dc2a25518b2ed8ec712f25a5a23551853427a0e453a7cdc1fa5c23c35b13ea99af31d8c0a43e518aa91737d053a85f9a2ba1090294cdf973e8c1ffd961442a5305e8ebfabfd425ee71091c2d8ae8551bca05198fc2a664d7e94272ac78dffc2868ac2a02e3988f4101a5028cc417b904d35cf25ec07288c1ee7b0e3e439ab5fa04f985dc3d34e46aebeb92817c813068bec38c6428e4e18b4d2ee59a4fad4d1e584f9726d8b88acb409e3498894238d10a2676e77481366c9d973301dbe3c98b286561860acc06998c00b2e962913c62f9d94b303111366b124c1f4e2ae4c90037409d34692d5df71310a640943b8df5ff197ea1c5d953007ffee6a69b289c4094409e34dfcb8e6b52c4d050a3409e348e8ff1c6325d5a3650b2409f3fc7cb48458d2c0c2801100588122618c9437fcdd2d5aa7bdea090409738a337fb14225956a35b41e618e5a5feb3e9adcc44e0ec81146fdd0c7a27585c9351100d8801a610e3d451bc9b08ee6631a66046284d147d7e5c277a998498b304ca476fefca02d8728a294621f5243cbca079408b36e4b0e3b5fb0778f22820e610ef395d4c4262d7c28990319c21ceeef513a8fa35e290b61c8ca37a939e998e12142182cca7fcae6e791ff85ca40833069697a34a16e3c965c10e688316a93e621761805c29cdf96fde3b1c89c0c10860eb33edecfc37a747f3086b4f86db4bf84d47e30a975fa997f5697bd0fa60faea7fb64c73db6f9600a12d3efc1902ec13df04897e2133d9872ca397aa98a06ca83295b4578c7d68ec3ed82075394f4f76d359f78f51d0c954bae26690763fcabfecde76ccfb93a98b5de2a8795a31f9bbc407430f4a67ce8a0567f953e680ea608c9252efa5776ae1c0cda35971ee9e3af0b691ccc56d9935b479df348100ee6fefda05ee9c63d9a107a03933c1ab5df8675416e30a49e903bfc28525c09a161c3c986406d307cfce8b6ca75bf27ca06b3d9e7f8ace7301d44346cf81a4c39da7e9ba80f4605e3c6db700502a9c13011ed738e4d2687d260b4ebd9b89cbe180f743f68d8f0fc01a1c11c244ba5bae7166e1713f8777106730e76627ab2bc10611b5d48c0cc60ee388a8ea3a4c8efde6b6871e1822350198c9f27a5cfe929ec420e190cf3d9e14348e81c51aed1a5031a8329f85a85646ece8aa40b2e50402406f3e4d8dcb2488ec2c8594369786183aa8b2e56d0806f2fe24061307668698f36b235b42e0066203018d4c6d5dea36df38fe378405f30b748f2d0ee5144f1ce8d378109b8b811068d17dc08a31479c11042d6e32323471ec25d30ec55e867ddfe40ab5317003210174c21782cad8b30357d16b405730c198f746dece2fd1a5a5cf8dff8c214415a307a6487ae59ececf474109485523e3377b6b354681c1b34ec8bc482e123c9514b4a99466890aa0b045dc1b86ee1e3fd783eacfc8281ac608a2a7926a4e3cb7f175405d387e838b63a3331f9dc0b1bac06a282d13f8f8b47f5dfb58b1b61348d230c30a660baa096b7d7c2bc4aa886d649a178d9e1cbe760fe2a325014cc6a1fb78510b7671f47503007a296e2788a316b2e3dc14916732368759815c80986b3e41d87b50f2c5013ccd164957ddc9fa8d09860ae8e52f547f7414b30ebdcc5ced1c7f9b7626509a404a3d487a6e79c94404930c72e91a3655c47785006909060ca694bbd13d743d38eba33d011cc79bf3bae94a84cb3c7404630c67edcc17d799bceaa052a8229fda744c831725db0b2404430c7d9a93c8e52a12198a45afa3c924908e6b379f77d15d749a930b8b8d1823b2550104c61facbdf2db7e3acb9e815f8df5019326c090404538eb36529e4844e4e3b81bc7174b10213fc0ddd0dd00fcc3943c2e46446a38b2f52c0c5150084403e304ebb78fcf214a807a68f429c091f6ca7902b0f4c531fcbe37c25146807a68b9be51d5d987460f0f06ec6b3ec3fb75505ca81f143c27b78ce1a957429100ecc9d3c4827b1f2a59205c6d1c5026ebc05cc403730b78edb459eca0364039376dccf66b1db3e592a30a316a67c9e2fe5e02cd56a575a182e564ef73895a7c9c92c8cd9fbbb1fa28b245716861cb95f08b52a9344b458cc8085c1542c54d49f35b48c05335ef1e7b826d4f2e46c292bc20c5718ecdb420ab9225e3c0bfe462b8cbf923fc48dc759697871b4b1c278f92e8574ade7729219ab30eef58aa87a96c7bfd5d0a25285c1a3e9f5ec462c15476f9f545f2a21cc4085217885a41e824ee50e5f14669c62bbf83cb9ef363a630d2d53182ad75a77b41f9ffb430312184029cc512686a9458ccfe10c529845dca3db25f507d7868d1ba3307bf47c59ec43a4d5ee4595cd108539ec346b160e85c1bbe683c4ec7b10a51a5af86633406156c9619b4d4acdf884a9e311c99e4c2cccf0c4a71663425be7555298d1098384ab0f0d30b8e084397fea385744985e98b109f3999c6c5f49bae86205c72a4b1356ecb2e8551e924c2a444aad942af8c7295dca16c83bccc884693aca431fbd08f760c26c2fd1ed2935bd5b42332e619a141d6787de29d4796a681d6186250c16d6732813afa18546985109836ca9a48a170b0fc11a5a288719943044b9ff0f23679330de87e19103fb54d2510dadac0168c0013264a8618624cc1e63245cea5c95cc120943e8e710cda3089e3b88026640c2143f2ef2c57a26c5f511a61c55b0bfccabf095bf812581198e307baa509fa7340db4e0c040590b8e1b0b98d18852089752ba53610623d80ee4425c3a4f98b1883edd7ddf7f080127cc50c493e2f1b2c28c44182e96e7b9a7e6e5c8e306035a70dc902183063310614a396e73ad83df4ed17208b394b9c5e8f03006330c610e3eb4fc98a89c2a7d210c73a9f54cebc37489cef15d9419cc2084396de551fb951af3388328277ff1f3b35910e6145f2b7ff4396a68398de28319813085ef935fd9c83b3d01611e4f7561ab2347a1e3300733fe60d8a8ec683d6de3627e30c7c588719f392122d20783c9eadc440a9583af35b4de6db48d05bcdba040a12ac00c3edcf28c3d9843da79cfab1c5a0e827a30054f09d172c78f486b461e0cff73d66198a586da08c30b08e0c11c7ab9c7710a1121b504c18c3b983aac9063a4d4396ebb1dcc992775923bb80e5e0757b12b39e8603e89d0d5aa36d9213b0753c4ea0b963de7725e0e46c9e192912c84c68c38183d7cfa38dcf6e46fde0206c0810158400203a00008686460061cca8c3798fd42429e74f7cf699ee1063e9a9310e771ed35a30da69d7f30122b2b8d54434b6f0f33d8f089743c9798f38c3518236de24fba5f0dc68ffab5721c466c879c06f37b58d57144d674d0a2c164a9e641f4d0d1c2a4669cc1e4e9f34dbcce7efdb90e6698c1905a1e2e74b8172d0120a071807382b12c072d7ab237000303b82698c623564c3a3a9ff698600af9e71f1dec4efde5805b42991255615d5119c9dbbce3546127b78405a70443c6e5c6e7b0def134b34b825923072124448f438239e46b4fb48a8f1ce772057704e3bcaa86df87a838df9f114c6d39753e5de98ae0a4d073edec99e088604a9d3f08398ebf9e7e43307e8a0e1d21797cec92aae08420830b021e10b8a87dee51f0f9cbb91f9c0f4cfb3b937268a16fa91b07ae07a6d8816ce48f3fce1ef9450a7a4b703cb0dbc1962a92a418512c976b250b8f326c3bba713a306a47071d98256d2d079703f36705f9f05f4bb23e6787037387be1f9d9287f33fdf0d8c7912fb4ebb0c9c0d8c23ebd69e729ec8b56b61faa99cb56bc13b6f4c0b731cc761b330fcf489e7b46ec995928521bbe791a90fcd144f2c4c9fd5a3840e75e4dc020b436ea5aef8f6d8a5a2dd81bdc29c6dfdbeebd269c485d0c05c61d6eb099522841edde800d60a63664627bbac91aa6c5618e23c22e5bebcaf925761caf1f75a5ec897af8a2acc514893d8908da4b7a6c218fe5b15af23adb7890a733cc13a1649eb173d4e61b22c1e8794831ced4789290c6f23e5b186570ad386c78f9472470a43f08e733ef73874906c14e6bf8eb3b2924267bd44618ed4ccdd72750e62b15018cc3df4f408f1dbe310280cc1839fff9eb97c3157fb04a135c3baa324494472899c3ebf965ccd85e609739cd37cc4b4f868a61bb04e98f672aa3e304f1fb1a3140ce384219f449aafcaf238961cb04d98bde5c366e7a22f304d982bfbeec743f9579ae4179609b3852c9dbd8e364c985385fcd7396f1d471959609730c7bb64affd7b8a3a530004343e6096306dde9e5f05914d9510ab84ed651a9153d77b09b8e098c0aea00118184015188c1226c99e7235f737d9e39330c7da2fcbaefea91c25e1cd6ce7a4146eec348b84d135c4e28e7fdafe09244c21b5e3f45ab7dca1f808b378ad4ebcf4b83c9d39c2903a8e6f3d56eed27fa55137ac11a5c42a8976b5c84821faa92aecff1a5a7b238c2f82608c30b4fea7c8adba08f36b5b49da6e4fb192354598363e70d7b33fad8852db1e91c262883007398aecaed39b1d2275f7f8f78cb40feb8019c2581f4b9af170b74298a3891eac84f60961a8547a1da77c1065d30ed3ff5210e6f5993699348d2c1f23b04018cc738ccfd1e58bddd20061cc0ffb336352f607338284c830f5a8685ad153fc0539fdb2201ee607d3a73c39ea14d751bf5304eb83c1abf42a27755c128c0fe610b43775532edfd22fb8a10125d81e0c314ed3d3e7363d18dea223847413b63c7930c771f08e53d6120f061befa87adab98339ec09e2416d4dea388e1d4c1eea3bc5ab5ddaaf83218667c5b5a8b9e1d2c1d075e9ff92763469cec114f282e59b7230ab6795b9749d2c483e0ea61c7b7c747e3898f73bc8219efe06f34b99e428a4b81b0c3af3575d6b1bcc96bdbeaa1e76cbc90643f7e4e5d4d3db9ef91a8ce11f7eaeab90ce8f1a0c761de4b2e0a7c1fc3a971dce8c06b2dae3fa8fd233983dc85fdb6a159f3683a93b4e39858edb72342983d9653c7d54e397354206a3d8a76a93e8205cd763304a67b58f546a311873b4e63d66a8661f0673071d42881983c13caedfe16a55b68bf117ccafa2baea29f682b1ad62ffc8d7e7a647170c97334423480717cce5361f32553d295fb6608e2c92e51f450ba6c859e452d75cc7a364c154712a2eca7d48b3162c98f543e59492761c4b7f0543ee74207a177175b782397deef0a32fc3e3bb0ac6ec0b9e6b96438ef652c1f4a2174f5ee2071fef149e1c5968a560a834c9c1b78e48e46814ccf13d4523522f99af5030a5b06a6d1ffa047359c717795e7de2552798c23c3a8f4f22dc45b509a6cf08b17ad483ed3d99608e0f3ae894f3c30e3d720926aff496e2944a305fa5d0e53f2955c59260ce8ef6ee672a645e8904d364558ffb117142fe0806add8d1bf7860ddb911cc9fa7fe238f9fe32c17c1389ffbfe2e4a04b4f2c4896c12320473e5b434322142305c0e35f6a3e7ff0a49104cbb13daf253e8ec39020473e039d28f7beec8e23f3025c929e4263ece15f681c1d259258d8f1e98673d55229e86eb0479600ed2577e9e77600a9fa32a0b93dde3203a308a45eb943f96186ae5c0649e52e7aea96d48880363bd8bb9fba7f58e7203b3ae87753d9b0dccfd777596db5e3fb416a6f9b579bb8c8c28d2c2ecee9de27c6e16a610e52bf1dac9c2b06d967e2b6eb130c7c1d7a68795e338cb060b835a87d87e49d29db5579873ac62ad26952cfeae30eb579470eb358fe75618ff4227b7cf3fe40f5698c76276fcfc1da4b9d42acc17d623ca3a946e5baa3069e59e728f71de51a5c2a0f78178bed78f2407158650e11d9227ed10fe294c717624477b9bc2104267911cc78ba71486ab2cd13bf592742185d923071b7927aa511845429a7417bc42a5578a50a23059e750bcbc52d84a9708150a83c4fab72e9d58698f100a14860b9715359f3bec8f1e17ea13a6f5be8f9d6763ff2558284f1842ff79ca4c3f0f33e913aa13e699bf949053bc48284e98e320d84c969011111111efeeeeeeeeccccccccccaaaaaaaa8aaaace652000434042085da8449e6a38f23f7f0e2f5ac09f357fead68f72a13c6da34f90e22294c98837f7c6449df13d425a86494256c355095a0c49611bae4bfdc23845e9370247ecc2d4306312a942488ae78fbc9f7f5b48a84214fd6b71cf8bcdee80509f3458afb615979ce71af47983a791ca69fd582b6a11f28479823ee6457dd32e97eff467aa01a61a8dabdf0b8157f35308a11c68e14b9d62e3f947817515a508a304bcabb99933d0e391acf82038cab0d54220caddbe7f1b5e595cbf1376c74894221c21cc874aadeffc5cff94318352582e4929ca30a1bc26ca9911a5a36b60a61300bd1e1e15f4556534258271f1d6f3508c35c4c7d3c99a8fbd1305660e353c0451882305c4a1e8d57dcae453710868a7349dda3f9322f6d84610508e3a465f5af10724821eb42fde120b247c5f59a3668786183c6172bf08329ca638bea1c7b20d15243c3b0718346e142f5c11c87ba2129dbc495a93485e283695ece72daf0d4b2ef1e68507a307bc8d9e396fb2077b8d6d0e2e28b83300f86bbf0d1274ba778305b8a8dd189f62aadeb0e76304bba8971ad9f37afd6d0052ca00e26d17f0b4b316662ba557430cb847a88a2bd39a1e161bc09146b0ea614febb428e3a1d6ea95a283998a62fe59c53cc8a83a9d43b2d73be2f48c161dd53f98e3d272172a8376cb5a19e53eec38b2a3718d3426acfd9fc2778a822a2da602eab10f2295267c448b1c13c29d7d6b51e6b309d79f4edb97d8bd8a9516a306507afd4ea1f576930544e578df7aa1c47586830d55aa85e54a786960dc726d419ccdd213f76b0cbcbf999c12c72ba5d162f3f54190cfa913a9fc5cd62646b0f450673241693a320f93caefa5063307a10ba42ee4f1d68878bc1dcd17739f6dc764ab61e2a0ca654c96ffe3fb6b4456030e4897596d3d65dd4174c398a0739555a49177997174c3293aafda23b74c7c6a1ba60d40eff39c3a307a13e3814178c1f39cdcdc5f528c75c300daa2d9826eeee5eb6490d2d3068e027c098505a30bb9956f66d85fc49b54065c114a5a562562776deb861c3ce505830c7b3547793763fe51cf7c286a3d515888f3eec1829446a68d108c3868d1b250c6505f3efa795f8713c899cf34ec386df16aa0aa6ad9024e639ff5592555430fce5c4acbb58a82998efd268e7ca55234a0aa6d7b58f26d6768fad8aa828182a2287243139f92d85110505b3e77e91ef684a26d74f301e8f34a8c47086226128128803c2380ac22034730f73130000000c1a91c742c158341c4bb2ea0314800457281c48382e14201c1c14221e8906a2502014088603816020000a0642a160901ccf731ed50053456744eecb71fdfe283c69334f00b71b1efc7be8fa4c361d6e4621451e02331d47eaef91c860c022b7775379f0d4087f37bc3a929f0691469de313f9773f095580ab2d4ea20c0a50417a7acaa58403b9ea9710c7e058bf383c5c7180d0045c3434b820ba42ba79d500a333ad52750175e7233d477a671ec8e7411a2db6f53204991a5825890458bf07d2b7ae2a6ba1a39a21065efc45d5380fa34c0d0fc72ca0e5d68ecc902e2dac632594c1b4408416f41c37c4a7ca8f77088229dc55f092b3006096e2ab1bfe20080698a876b4fac709752786795b49210e6044a272f13db13c75a48b5de94ee2308c1925a054b2510b2f9b396ca53d002b921d8ad010ca709b1c96ef2e22f93c275827fed9905c9c71adb22decf5530a85bf9e0153f35b20081a9ebb0d52d917c55ae8fc8830ae402bb4dceafbd37cc4cb2b06eb35bb177e0d8a99c20dad56db6335e3ba509a8a3214199235ddeb450130fa3daa0ef045a134550187840398f563ef67098489d9dc50f4a68f8f7e121a5e6754945621a394ac85d25fed7532244b1bfb295acd58f5f2d01ff62fa3df8336cdca45f90e442c91a8191e04af2050e412e321a52c353b82b08e7bff92a235378ab1495ff7efca3590c903d8a34956ebc0942217dd27bd20d5412fa76e3fd6a09426702ec1a0dfee3524c4fd5d76c8ae4b5bb52fac00ffebdaac58c403647fb601ccd38ca330c85cc1d2dc1ad3f67d29d90d12b0f372a5fb2f4daa53f251213bf9a2e2a5f0c0f777bdfa68bb4db2870fc3b9a68b6d310f15b73106dd50574f0e70829c6ba2fe7813601649d81d862d0405798aa3c2ecf25697ec0dc7c2024139ce20b96c489b45d8725332a598d8c2f415d1ca112446044e963c982c19d1d21877b8970ab8470193f106b1e7f3499f0c5a45e3ba72b12abba4107c98c9d057883f58cf36e27ed54ae052994c16a2cb6560855942f5e4bb421c67c99eb34f35e44b11924fe135a7d842a5fbebe28862416881829045900f8e0a93aa30b97bff655f3bb470572bf16bfe652a0f880920ca8c1eee8bb3d1ef2222c012b134a4febb40400de945b08dea75e289a8e273b5bde93910d3a358ebdaa10f1d8db8fe927a3ebaf4ee655152e31e6811bc45383eb1792c0b30f038844836f38cecfab6295a9ab4f45ae5428aa76b387812c918405ec41d6d301fb0fa754c1df0284ba60b75285fe80c112b83c1aa59bc992b2f0df19b20f16105cb255256660ff42cb81201634aa45a4862bdcb3d5f0105a08fc5caf7dc36efe1e5031de0fceb4d581938d9ff46f7a12789512a49a290dfaad56cae251bd301395327017455dc18f5abe11b2e2e95fd5680dab6f20d84d0b858b0b0fdd0e2f06944b180cdfa49a3a131834630802c1d586e3c1de066807ddf3401d6040d3ae451eedb633f6ced7779d134d4f501e4098422400ab0c402bbbe15cd58f57f04705a50a7626eeb284c9f9ccf22598f8b8f7a17a450b7952d323d4bbe32633a64eee8d5f31cec76f016c77affbf806bbbb128a02a5c1df40d32a218d31e9d32b10b8f0a46d19001a01ca061a129372cb2d54058582c900b1057e28ac12859f33d3f0b5421d415df3ecf802828a800df0808c74d500500d070cd2b5fbd4d5a059f43741790a99f5070a127ca490b8d2806def257332cd1a23a895d0306e309360567333e02585220936959c0163df7267a4794090e04805bc042a075e87259b7ff6a54000d8c27e41d08349d6995eec17bf2d32112030c86777968a82beaee6a4471df97b5853dc26ae5cb19341bc810bdbf56d0fcd8b0e3f4f43f94dffaf54d39d5849aef9d5c62433a7756c784aa93ccb3a6ee523b34d4f4a3b0dd14d2b6f8a0ef1355ef71231d045aaa3927d1cb7074f6363bda9c3143a8addf3303705a547816f6ce9f0275c4026196927dea78fdd232fa1bcba7d71a4d41f8e48252895f6ac53474bb2b4d5d8a2b591545aa44113514ae2a35d5ad8a12d5a5b8925551a44a145143e1aa5253752d5765b9d2cad5a95c3165250ea94ff5148a2654c9136a955e40b3858454e1e9016cb4270db53baaa01bac0912cd20f21d92f88defa41d639cd9a23ebb72350911110ec99c10b5db6e4061f783cf9b39d484ccee6a2913c8fcdb51ec1ae2d106bfd3ab6e3885a243b1974dc63b5036724ec1d032581b56acdec0b44d2221c2b4142fd08fc71d17cf61ebbab3e48f55c330458238f99967e39fc27d2cb24c477dd4d0c7e1a3efdb602b75de9317aaea0f62a515056229d3db6a67a54c8ffdd4459e815625f587a254b13a6efb3d6232acf617135d92041ffd8eae48193cd3ba98fd4f9f78404e7179e5ff80c088dacbecb58eeb2f70e017f9ec004255d5c6e781d39ea6a43b08a349d6316cdf1bfc63a88ac434a094b13f639b1b227a0da5db5a8b9399ed3d7aaa6025ec0e4d8cae75ec3ade87ec850461c5afda53b20b18f01b5df4fa7ed6d475ecd10bc0e576e1bf15e5007617a019a7961c24f663c8708397f667b0541919e0fc4f2d703d6bffb5fc710fead1b85c7b51bc6db38bc3fbc5bbdcc9c79c2a342505228609e46498360c94329480c70d177d7a0db7409fb8143748b78aa9a7206cb98c8db38e134334e7680f4576091851692c31188e74c751acd031bfb5a4d6761db5ac82ed6773879e62d638845b0d42e1acf4d28805be93056910f6becbaf5195a4bba991aa513d8bc9f37d11c0fb44a31297b854ef8c4f9886807aaee2b06e37b0fa4dcef331a82c9c4cb3febf7ceebd64a3b4c3d8e541948cb1fef6ef1781b496cbb6a3a88ea87aa86924921d4c8ee988082d30488226cc9fd5b4e4ae3404c8bd7194dc36f0fb43f1312fe6b1b1dfd48ec78e3c233e95b1d4bcc5455b932083d0ec291d39d0bdfcbaa6b50d3ade66af3ae3a2b857e07d716f558a70198af61d81fae9378ae86ce62a2c49da146c9488b171ee9f086dca3e393192b5a42b4b8aa4b0bde51f90985bf6809818c9384984ddd71da52cf122422ed0f87e9e394aaf4e2eba88220dee224a9da985f9e82798f0c308ee7140b431b228596d615257834af58164745346d33a8b540f1280841424ff9159ab4918ba1f4bec8901d80131108d208b10b832f36c84e5a6dcf01f0071f7d9ed9e251b04f377625cf5cbf4fc78b5aebc6f8d6ab2a7fa56e5579f463cd764f1929915de9ce46e5f5ec5d2a7d7a06a4339fc03a2342ed0f5359f9b742ddead5b2fa97eb17bec3fe323a61f98acee92bb15930cf34bbd35d126241dbd64b4e107ae37c855e28e08763066cb50a41aa50b9977d66f7533918e213301e15e58fbf1312e1189da560082ab06a46438560faf9881e1f50660f9e3aa165489253341dfc75e006c58b76cc889414c73dc5d69577ae1d6c41b4764585d7a1e95ff18ef702ed9b2ffa77651cf7bf59be2db32d14325d04dbfdbc962e7c0d4b542817f81ddcc449086b0ee905d28b32f74d3b2b1293bdb57827de1c5c3c15f47b331471f5fff360544668c7437197e4d4f6ad8c3c2b4836c86c76452f1f983ac91a719200bb3269bba2df8a8fe66010bfedd6d64c317122fe9f67dd480a8cb02d5672ccd8f4aed5d71d8f1720bb05b4f35299664d0f16292b07c95b867e449b55eb9e88312e3c235ae1686e847b5ce75d3e9674b960f26385b387da43672780bdf595064972dea15d83568fca2e4eb1f383202861be16d06d91a02284208b5ea6b80ecee35bf99011c63519e138da2107628259d8d6da727e906c6e37717deaf9c123192cc0d6af301c9406c70f15d8dafa1e5afb70f950b5c09494d581aee1a8879cfc59c4551f87085224638472856c720a16955bce4f6cbd0d88472bdfccf8e93ac8d7361026d54b53eb329179e97b2f3b1f11227bcb08b1efdeba9a8b93ac92d1316c56a93cc9d335d42eaa47fe9a5a34885bcfa25e0b7726918f3e00890ab010439f7cd71eb741ff97295d5426de6b320bf467ad6035645d771af440699c6423480a58529153a54492a285275e03fc4e5b7c6225086c9c5f952568e0414ae4f630bd8b2b5861d7e2bc580e7b6875625056cf5b8df01478e3f73b9ce68150d2e89424453d660579bd92411c23091a12cba2ed434c9552bdd5c3333cdaa61bbb19a969f58a741337296032b8e2382aa210be0b995c4abb730bb25e374d1dd677d7377157ce2fdaa4df1f2d997e5c69fdaaf8bb9834f7ddf26933ca811dc378b5b6f45914f0deb5bc90c4ac7bc211c6c51427a4c17ba51a84cf3fd8e15b39ff59b525288007c522bce02f5101c15fe3d9b79284dfcbc1cc5fd804497d96bccd4c8eb811bf088a3ae954a84ee8c4c030ce690c26f41e95f8c3bd19cc651e88573ab18f88070e3c40cc65983c0beab6de963dc4b359432e6af033610408d9764b4ceeae0c37bce2205d0b1596101bb7a5c47f64e23de7d1444539f6bceac4a4408efc98d3d04c95e60f6e0013524c4294f3137514cd958a232af1eb76a34f4d26b26ac54d252c60ea33d78342a1fd13b80b76e5dfc552e7ec34150783b3b66830ec09583cb742e03b6d368c59fce35bff97653d8c0af916672df4a3815ef789391b16ddd9456326624f3e59964f51f4017c92f006c81e3c7ac6b59b23ee003a7e585d594034b21c0502ed73ac85dcbde136486d7d166e35e92bb54f6415408f299b234ce607547fabf1d326d1401d614cf8b465a1dd8dab6ac238d619afe0298e7061bd59c05d5d2c16b263dc22f9e91ea8bdff14209cf502f12695b4678634c61f9f19f6ed24a0980bf865643fd902354febb3bc0a5ce342df4ca1475c306d6154d61b73a34bb4f72126f9a3312d5901b294b7a46c0268d3c6051e670029ea0b01a7ab8c58b7709cc9bc4fb506f68cfa1ce29a7a8f203ae672d65847c3a7590a22650019031cc9be5c8340d33820af3befa2beb30aac8f1e22dc4bbf03bb7b941a2a0579256cefcd215d8f31ffa17593a8b749aefa4fb9303df28c6149b613955f9b82f6819b65a0afdfe6735d4a915a024d6dc0d8b320c0b345fdf87a1a5d8242327d561761faf00f4e8cce8ce0a7831664d8b7c405a6cad043dd3f121d2f0863a30aeabbee20c7c6ac24f1672f290cb565cd7f76c538ee031a84942d37bc95c7182d2b2cef92bbe165db0d50bb0892061a4910ebda48e5de0d82577d6c946777368d777ab0d181a2fe4f8011f8524a61914dbf601fd090496062b3365b6c366115d64a50c2debd6d970ff735b563e6082404bfdda87aa4c7d8b6d21369db1a61781414fba38999206d926f868cce260f3e4a4e8b73f0e0475ab7df5d842de177a4da16f18822b791ae3f5a1b79ac0575c5c23919e85ce8d506eb5c9746192c361b9e65ca34bf5c5ad99ab992ac7f6c3e033daf524da6b1f6709fd14995e33c6972d58e35de4e8ca45fb7d793dfaf8c1e35e027e6215cc42dba130ff3acd1e6714d5f9f5072a82a9ee2ccca558b77b1b4eaa6203d7a98294a085d0fabc153243c914a743c0cc092198b695e3c09fb329a0b5a4e233c6e786a34ae3a356c60e889f8b6448e4736d0179c96609ede424df6dfb25fd4a0acdcae3622285cb6377046fa24a571d7ba96ec72987da201bb6cfe74e79b68015e524a8ae76229af3f02712795a3088891711097fcb4a64100d11676a7fac4188cc2ec513324ab41ea3911683f5a715aaa3ea0679231b07f1e5306238e572f83a4a2ea0c220467f32067cf595775e250e1786a764ef851d0a22ca4376d1240ec9c7c497a2ad951d4157afc505896d9a5969cc65f3b3d522bcb1c0a605e1ae73eebc0346d0ee7b7def4834b170ac377b0391c1c264a2f0e37e9739cb34882295893e8bbcd6b83b1ccb308c2a5ccae8aef0d7d0a77c7619f0b1b75863b2bdc92bdc5bec4d0421546a167307cd5a20f39feedf70d0db25c475f41e93342670a09b4c37c03403b204011ef1628120e8875f898e1e6bdd373652c4b11ab5d059555351fec5e60c82374dc38cd18cf8291628fe4894d156ee311154b5a157df0ef6820c87b76b2f2d24cef676db146524ffafc6676d7c8a2ec936b7556f5a895193ec04aefda891a8b9d63f84d50fc41b2151e84987bf939a8cb66bdc7cef4586daf82e3b780e78bfbefdab827d1444327ea26e3be1c7b6c5931e5cad1e098031fbb63c1ccf7bb1232fb4b0052e9653cad4d15bd5e3427ec45f1bf916bd334e462f9f0667a415b0d858b0f451565f0d490fe7e1df53fe807329c6cd379649f3c21b7f4afd716bb18aa48be950cb94cf236fb10203a6749e6c416d16e1c55c9dce664acb992e302a5bdbd0b652286b12f3415e47a1ae523c0afeda01ae82213e3013bc423c7a38ba0ad482f244b252d11da67d9220c76385b44674cec5bca9bb97848b25796dae4af9896524b3108e2dd6ed00d7c289d57493874dd5d5501048b1afa2c261a7ef5a929316d8994a71b0e308765ae2736c46822961e71a04aa5e11bd66b23eee428d4b2b5308019260a504c2832e2750950b752ec78265822e3f0b1c3dc28b0b296f225550ae1ce8b72c3dd44735af620439b878cb4bde34ad384fee4eaf7117a1c2b406a9a88e619b7997223206b69ce6c700f9ec4576d425bd081cb7bb6bc507feffb1441ace94fde9c8112056790f01cfc943162b99d03a80fc4d4a4d4ba2690f49de42d6681fdf5d614d8913e1dc2243b55695a1393c6ea2ed3adf28539f57296fde3ad0dceba47be1e1701b56376afa91a27dbc4a080900f9b263107134d8c9ddc19cbf0dd4bb44d8ba1d67c03ee3e0edfbd1c348ec1fadd6f2dfce54c7bf83b13356c3ad9108c90903373bf6045c5b71da2e855c7d1d7ed51fbf1d89d59d76dd37ff5103cf6ac783868c3eb95c0724547a7b3f58b5c03b636ee8e22f796532c0996d4a9869c5a9f73a0ef99086f3b6e0d3d93bdcee6ed3f41699ebdd5509a22f7a06e0bf42a756a138bc51db98548b891a067b6d3bafc06e969e6298c3a87f2d92f372d682fdb36a20de906073a094d58546ebb56d2c43b01fc6a835f93ab29afccbcc9be48fabdcf617d5dd6fd87ab36426c1d662da22d73f8249a67c133bf1d20a94c0ed5bbbeb171c7f45d5495191f5494ed41848ffe468b84e8d455f27d6cbcde676a6d8a1332616b58f6a2a36ba583d5f6e654e1442a2f756720d4bd71106eee02e54572af4781a1366fcefd7e18f65815cd57b601249b2245aa12112fffa1b0a174b2a72f0f8358687bc3524819e2c216b22d8a024d1578bb1c478cd8cb4385ddfc329b654f97658adad0568f2e6e8bf00da4321668453510188313411af758a4e4414ac64ab6cf0c79a980f4ab4e1c2addb24faf73e0be83407c1befe121dcaabcaa24395bebb6e688d9ba2781ab3192caf3be95ba243f66cb93141ba46ca7a9092ecd458abd25ffb0e12e251f436f960cb0f35e4ddf359aeaae9e15214dcfa8c99a23dfcc1d2b71d00d19c003494717fe8bc308813efd0fe6580681299228128d401c264efb3f62b657a1b9e0fe18a5376ef68d4fc72f16bc3ed7e474ac763146aca026ec6fa2382226aef4cf4feb1b0898a2639bbfd62664e01672adfd10d942747109046e724408eacd77eefa210cdd3d90096a08e1cdbd1b5ed159eee8010c08b7538c14b6d7775b8fb77234a9093f01f5ab2b23196f3cfb3c49680a53ae31b23e623e14760c5f12bf56488f78a03e5f81a7e1f43747f8f5a8f067472f1781df93e98565c746092defecae82c188561b57b1840032ffc5bdead56e4bc85672b08d4abeec09688b94c469570cf4f270f405817990e8257a409efa60227b5c1f230e9b03c57c4e6b0f420ef181e36b604a7eecf7e3209f5487cc81c690879ecbf1e0d6e2eebb52359d0fb00d1c303767b4acdd0ae28f0f74d92b9ca2a97dd14c126133f1008db671cfdf2a78d859d821792b7cb2386640e5a708d75b7804b65357b78129655f181a6978a3296e4b352681e7f888efca94e8243411711593a53e2b7077b118e0b7bd5a86e39a0ca0783ce99db48205facf141bc58641063ae0e8caf7c325151e3ad91a436aca42894d469bc9a6485aa67756c819ec75791bb6fd37e0ba8e0975351effc9954a488de5971255928d0c06d8e9bcd0959de2c5cab555d87314686140f9f014c1472c8de66b1003530a922f9c6f823807c55f2b23cdb9986fcad91bd670946183d680deea0abc2706c3ab5ef032fb2750717e07d34b7917754484224eb50061c9f976f52b1d06133618841db7d67f0203deffdde917bba0b1ac7b76de7ad97a64d854529a8a4b5ca2f958016bee72715080b5e5b3dfa57a6889e40588f8131424706343ae455594216bb15f0a7d9240f4f0fcef891794b38e20f03351fbe5a099ef836b59a63fa2895b2cdb486c339d84be11a328f26a5f8f2b12a56aa862ec9603636c3eb941fa300075ed7aa6cc2d2cbd1c4ab0975da7026184849ac2d80565b0c1868ff02d148166a5affca9ddf3a2c2fc0b822754e65bcb2604335d490c312649812462ccfdbaae171fa4db4f6012f9a065898cac752ef38cfd05b54d750d37209979e13e34de30f7f9025d55306573d7fe960bb91411977d36b5328f027d7bb1b05a3e2496d5213794cf9aea1ac6aa5d4672a0ea0360822dc4a6062b3505942c8e1c40d60e6aaac648516296a32145d4e50b7c1c3842573368db9652b3806916626385694b61dbefd01dcb3d85863e97a07ca640b6edc667ba0dbcee1d112b22e1092423ac981127bc97d0facc68a2c4e77a03932134977807ba5e79507685ed19cd8a574af641c4e8f2b4d8dad2577a2f03cecb2dfb65aca1153df839d810f115cc650624b910749fdc7e98afc7c6a071296b4b8680c51179b533668c9e9a48f5a28e1ca3af25a13202097301710dffd374fe70e6c79f1b3865977d98daba9387d93b293640762a88f1b74b74aec0be38f63b5002557c819f3bbec13cd7bd3ccdfd653b686b36b23ee74e0b5f589c31a1c75eab6a30031d6090c33742843b21dd5b0decda1e4afebda5b18eabdfff6bf7350c12b799974cb4da78787c7be3c97b0b6f0b4a39709b4aa77bf99e4ea99e3b6fc27ca52b2162161bf6151441f85980c97c9dc1a17c8b7a1bded8aac4ad1e02a2e61d259f3c418be7f590446214aa4c80f88f33e796a90ebfac952aeddc9f38f2b86ae2c57985088689f89ec556dd0ef0d32c7f77e703dde127ad74cf8415c77851c46a80555341a6dfc857581844041fe32f252937142addae6cd5f7992abd6b0f6b5f57a07843c30b11899e241225f12b7e6b42450816fad4e1b4b14483077450c8c49a0544d9645d9ad88dd7bf4a2efdc4aee18946a8805a1135a569fb1850d9e1c36562e5e84174a4745c4976f406c5ed51abafb6363df320a7b92c7863a249a960f6daf860185f53a128d4b3920e71a1776523a0e26eba030d394d2ec890e9cc721b9e60a99d5e154641221cec5352e4e85b928a088434ae26125e75eaf1bb39cf39a9876f9207705293c6002ac2411fdbf23541793ac5da8e13ba362940b24faf88767dd6e28cf42d87d4a72a4efc8b523224de302030f8ba254c7e22e7a60489dcceb504bf728ccdf202c56af11ae4ada15e2577074453512452ce438469569086c088d3ca708a5232ae7bab8b05f1f5b11a4bb35aacdb388f7e87de549e1409df375e5264be418bcd7e5674d476d76e01f91ee50111c1c56575a9d2488fa7e0aebffe096936034c5788cfd23d35c06e52e5c955cad41cfacd427eea36631b374442a8ff23e362dc5929f2ab4e02abcdb057d5693246c7a720f30ecd6243bdde889a39f35247795ca76a6a8940d8e57df82f9361373c1ffba288ad7c8413e8446567afe9183ba0175ba432084138be444765ff2306bf32413261c08d0f5ac0a9da348deaea9883bda08b8999ecd59d37cf4e932a58f540dcf389f7251b72ca8b22f8470a823336aca6b18c3eff3b3a770bab40dfcd4be6618e3f54c504629b77df4af562059e0715e17c9505604cbfe1a60dda7921b87573ffed8030e1a8f81741d7dbdd6932dcb2a122a8ec889017eb7173f258994e804a12b7510c5b3e045c09d7576f4cdfaaab401b8204d547fdc6a45819ac52e59565b9007bb90e04c01c88d7e17185539822e4f2f08575f40a8c1d86f4581b222a77332bf285b1e6044b00ac998556350a3625cabb2372551c50adc4064029bcd0d3a3c78e03595c8d6631d955a7fbea54cc974a8819e0b83efcbc190e652f29ab612a47b8a7b7a431b16989d2652a1c204775c8bdbf09d343855273e2171b380b5c93d8d2e7c5c32dcdd55971861570d47091f18542d5956e28237c6c0c7fe3948896815eaf6ab9c9cc7ca0f90b79595f8b871dbeaef3b988be8384efacf7f59f86be2452ee45910c13709fde45fb18ade7631a9c651d0d0731748c2c009106cd090e897199592969b85007bb5e844ff1cbef2faf7624e237bfff131355ac1d9e704cd4194d0f4540ae6710af1cbf97ecb2ab8d35c7173b0674710ee252dd640c029f4b190e083d0a2eb2bb30237042b265c9b068d739ca838317a1fd300418a0812c6ffbfe6522fe59e67d1d05f406a42343c1f61c754e5a5e2a7e411d83d1351c617614fe98b0f79022611d178cb0c0485c11f2aa97d3b34a08ef3d4cb6a7cf73122a74e7ced77e1e0ae3e47fe49ee91ab5c6b50294608267c8f6a0bb3296933a51137b893448214b1ff2518dd02ea61ba9e02bc530a7394aa1ab8ff2172fd2177e62fe55ab0ad4e512e0a9ca2558448e9e8cf780b717ef416ee7841514e9942cd5cf3b4c6a206c2da0ac49cc34c3841d35531ed53540b354bd6a386f7118c87e37f115492c43566a7fc235d0ceb334e80797071c4bfd340151a6b952ea1e39fb969f28541dcbd25a356b856c21e4eff17443a403e71ce0bdefc14973fb3f62f0370c12f3ad8c75f688a3dc30435f3dfa512dbba7e6a9e25cba0bbb903c3e4a47409cb68bfde7b3b3eab2c97102e1dfba297db18667d9329899cb2e7dfc4d6098159b8bc07d23d9f04cc2fb779b44054ef9e8c68e08ecf200200930062a02dcc13d413440a2771b812e50cab0e583540891fe767dd856492fc6bae82698608031162f8fbd43cd71b0970c13b1a57046e7919570c57f84166e01ad6d0cff072ef2e3bab3dbfc649bc035f4cd7213d449cb478c7d62c7ce05ce58726bdca001afd3fc3c40569c3198515836c8f0423781958f578b645840acc16b8743fae41e7cda76e3b873e67f662fa3f3c3a41e76a474e548e803a620c83dac335f0a72052547069c376b7ed13f857499bc140422fe60418579239db89f67bc50017b055339fbaeb9911ca5393ac148736d201cf27ae884fed1eba0dfef35e0e5ba82e1aee1a5f05321c158c7f04de8bd908713a730825ac1ade1328015e0cd26658fd68380dd913ed7eeadf2468d5fa9c9f81304fc3a906f7b91465a01b4614160e403afc27e8fb41fe036303e760d43b7f53ea699026e0130814d008700b74c2e0012b55834b4a0cb84db1929cbfc8d7c30cc0e5a04b481e6871595b5e88dbf651aaf7e1f0c83fbbed7ba9eca88d39c95e266e2e21607641861ab840da44f403ec079f0c69ea0dc10bec040a01eb61508195d28d7ec105fd074c712934692c049a0cf2009fe257519bcf9d5b4dde78c16a53c3008cf6367384418081bfe535c0ec20e8629c36b872190553c338991a303c8718038aa4a113848458fe094b1c02ba3fe2e1aa32c6a14cb8b2491633b58779780857e6d868a66d830bced5d920fcff5f00857c0de0151f220d9781a7e710035c8ea6a6aff417d07495d673d025bc1ca8027ae2a4691b61e8ee73d81649b7bdcd997c86b175555005563e37b82c35f2b9317c7f3c977d5efe2c47d4690c2e7ac0ee5db35c309eb8e99dd4961757c6efab450878d39cefa2c35457e5b4ce792c2d4003a88f71d1607d1870ad568fb3059013870d317a474b7a04bafa2826a272ecb2d57177b2bf1900d098101cb3ebaf132aec702add330205ca7afbd4d03fa80fc170ad748bd20a3afcfd93dec522c34d0057c675a02094cbdb3fdb51900a4e2191e9c888f169000e7869a8c670ad1b3a1905142e1d15cf3262d2af363a88816937cca07976b57695c3d903bdebb44583dd09db040c835a40cda4fa850d153815810d8e8f661e8df9157044d5fa32b81caa06de03e98c17c2ed80d3413d80a54123700d0c1de2ea1ee05ea8221492553fc0f83378f2b053804608ac1436118dc8a005c295dfa4a482f5fb0cf78480c1a0d9004ea040807a002b606548e956020ed9015cfa74f77156f8fd4b72c123a0d0133842ccc689fcf400ab54b7840e08cc5be26a7d435f2cf590073e897add0d64871863bf2760e719b2b1493e2a61067d28c475c1adcf9c605300028036e342fe57474a3d1075bc2a672cfb3e5fddda4626c02026fb74e92dae3ec5c78ac4058a032d24f496e94a41aefbdb1fb7fbde09651811b221869f622713650a1837ae63ce164f74e3e68bf2d689827a6f3517d9e29046a2ea364bff5e235b7832af00c3ffaf86f783021b7ebcca41d4fca5ce1a2ef421e0a9ecdd7a0d51cd418570e0405a7db309e3990fe8e5155c26373865832be19f0002e13f14c649a22d001c7813d88fe12a11412d1b3b078b02c781aaa07df12dff8a774ef4f0dae38a1c8061a8b2b7e83520481beebb32eb536da4d75385697039d083e3cbf8b9ce08b87054fdd2f8363d7d8e9942b58f68ca340f81bf008cd1c26cb09af46dfb4e56dbcb8533fce49ea5ac8f6c313d3e60664086380194d060ecbd2404546dbb4d9afa46ea3928c336c07c047538c3e5b737d0ef089703fd42074281a9bfeb64de5370e564b7fb37437ffed50ea9771abae76a32260ca84b1e481834246666f21d0e2b5c8a3a71b4860d564def9cca3f47ce844b0930ae773ab354189b306c02dece43ae0b63eea9081b8a324835e71a9b916f2cbb799f1e384f5b0f4a6dc4999585ebb041250c453d8440f4a50bfdf5a73d771eaca869d6ff45d356b3c15eb896a597a73a05382c06fcbbf4e9a5a4195d77c7583f86573c60598d342592d820f7ca7959d24f685c94fe652a133432591b242b7f9c97dd0218df1b24ac5a514af62af8ff1d300121921554366596c2409ccd2cb0595a6c1e80a373a7b0c57b3b47efef57afb45d99a70db2f060c02b5f29060da88d9b328787e74edffc8731f73bf74b14b4366a901637de2d30ae2f9180250309fb534371a4be955acff8b901665c5d127b931a1b5c74428fb2dc50099abe2081de8c6b0319fc9d526a6c97aeec5a162367958a5f3525132df5430a732e06a8b1347ab53487edb9e4912b9f63617ab1de5f7312006e73537cf6e88425e94a1bd4fa2c6617aeca6f4116db88d69ba1c8823dc1555dea62b62b34ad6b674b14e90fb24c5ea6616fca482ae440dcce5d8f33434268d29c7f184219e735d9657fc4f7a832f79180984be20964574b5366a4209446967e01c90b2d523f9208613294d078d8fd5f5133b6f5e7d2f0ab7cac61720a51978636bc49a780c50181234d05a101884ad0fe51971983cb2274a8f7283b4c98ea8b193a4f0efd8b1a23313a78bd6324bb507a696c9c5b12a0e182594c2cc96157f7f77d6c15e4b7ba87cde754c2200a9847bb8e77431ae97eb68d1aca4f2f85eb2926239ee8d5f623b192a57bbc954e776d47f05a3df1d154879242f7b08d809eb203c6b223118e053af00fa3f4ce197044a8557a8037342b78e88e4c54c558b784d22d5b23bfb21a8ea82f0b3a66d406f76b517aa6b12e7ea0a35233987d494d54cc246876594c6d8b9ae896f57664b6a81e29f2d692b219fb7df4e8ed5cf1f69a385860779e3c530458d57c1dba2b70e0b77f072ae31ea704c5697e2aa5405b75ce51971b95c2a7ad3b773ef22baf65546ae9e06e34c574d2b4a7510056ffeec2c12625e2525338e13b3f901ac24429042182212e030efab18687c398b922b64724e24c1d49182ac7e340814462b2d9956636fb63e704f90fd06295a61af2ad917b30e3a3ba4db4fbe2a2cb30295107881b99268e48113d1addd90ea5c64e0f0c65944fb58e2c032268d89cca178b2cc00903520c75e81fd25f7cf9d2039c6ae330dd01528b62ba976b1b997564c424f94c92c313c88d86e6e683d96d59a7778466394c1b12c40c68d924f8c8140cb7aab15070371004fe9edad9111925b1dff765a8bd57fccea8e45a9599709f5b7dedbf179d7ed9136da0d5606473623ce9b509a7ec588cfc1cb48d5804606c080d39a2e29008c4203efa4874bd4378dd28a0e15d902667b56c89bf8c68204a883a8d00ba8fa80ba27acd2ff143ed84c5ee1712b25c2617afa0bcfe55df32e254aa439ffd9be1cf0210ead62fc4d7a6397142ce01e49badfabe9d7e37aa66c6df7893570d42a781ba69e5f7876b3de0e0dae35144a7eed2db970c798276c67ad5ef81b21f3814a2250fcc602f7429e74a8a533c59a41c91a662e46b3152ec4bf0c516a9c84536f214c7a57847bd3338a2c38cfc6491c89ed3823912960cb37b760d134159576e4b99a247ac059b0364c21b68f01d3028a00258e17ad254323b4ddeedf9ba28705bae04766f24f3b97b2e0fe41004cb635d221fa7d8a0d8e5dd241b32d88a033043eca759832481c9725233298b5d057278cf30fccf929ed800259c00d729c0956ad41f664c44cbe31345582591f66ee79a5d2dcbe32cc351868421b7c4e758b54af4152ff6ac07f0e98baa8f2ed7f5b514a647a1092490dde3f299b5d4e4a990e3d2438ab1dd51370183a4365bfb709c7ad5b42517f3f0e8e937a0a4b42ca06c91793582033cdcec727e08c3eab5be9b2eefb687329168d131ea19710391948d98aaacb28853d3ee9c09d3b9f35932c3716f0129680e5af428c5fa55d0765ec55aaeaf0ccd675a3640a17febfc731e0b5e7e4b32907fc159f5d7dc0cb23dd3150f2852226a5e631a6c1c684a706d2e19600eefe717f25dc6a0c3a1e3d01f44f71183669c4f68873e1fa46b9951a1a551c03c6ce7d893e6a2c6bdf24abc548683ba68cb6507f7675ed9b94ae8b92e46c11295994e2d9eb9270af8fda2fbc696d18aa255c9ad351388e2be524d1d9c6128ec7ce3ad32cf5d152168c90dd251cb7e71e25ee4514304b7a16c741064d4e911f45ca66353bb6e7a9b4159a6d2fc9b4657756acedaed3d7cf8a0bc9102fd99e6702404063886a43980d9f2b4327d259cca0f1cf190aa6560726476f342acd27cb51fe5eb1ce049eb76a3ab96e4192c429b8476440c0f140c774cf7cd1136c0a99cb1b37c970c6bacd2cfb3acf5950ac3cfbeea080069eab4e045d07f41a49e0403548c5048daabff589c2391c9567ac4252d5afe964707a2438dff23251ef46fc9b87ecd36394a43c604f407d9c369389e835a09194078603836c3a0e077e1f0cfe299528710cf0af624af069f581c54b508d4c8aade5d6a28c6ecc4461f46b09b17eac5fe4f6e87cbb454280e3a370581b9bc7f8ec04ed7c3355e2460ebcdf1520130b660f33701e6d445ab4dd544fb1f09a890a4c90cd02ca990f412e6314b56c725ef5ba3bb520c36b041b397a8ed6f7e7dcdabf49a465a58a7b2a2863122610d3788a2d667e435cb0b968bb75e5b3984e5ee2763942538b439c23472f011c857dc707bf010e08d7cc4c41978482c95c33a957cf2354332431bc4944df110561ce5986d581dec90b24a0cf42dc56828491836ac0ae3a7ee0ff56c084219287df999ea96ce67029b6baf62ab1939d00fd4405686f90958bff3bf5a71df7de038d42733bb49a5eb2a48473a0d16fe1fd7057da000eafb64293260b62c07ffffffffffffff7f3fa51fb2b79140a278a2a494523245a9a939bfc3654a49a694d2c12d3d67a463ddd29cfa21017402690281026d7573af3922293fb5fb29f2745cc7de439243a7a97475587b8aa921095f32bbb5f05f6d21e97dcb57ada896f5fbfb610949aaa9a6af50b3ef20a97d61a7b7fedd1524293262cb5dbfb3811c40123b75e49e3d2a6e77ce1fc91dfdb7bd6243c6f9fc48cfbcd89e29978e9dd9ccf691543eb75aea7e1ee683bc2c1fe99dab866c57f59d3b5533768f96cd9b3ffe3787c5ea919e43c656b7a5989b477aebbd7376ae159dc5bc8be75fb078a4cc5c471fe6d2861c7231ec1d49357de7eda1a3f828fa2e9ecdb5579b3c61ed488fa1624f9b4389da3b6aeb486725b63afd4df9d95c74a4c7ca6d764375efe63947ebfbe75ea3c6c49537ac1ce99dbe964b257bdeda6a98c1c6911833536ab585bf0b476be7debaedcaf5467aa7ed5bf8dab675232d66897a9fc34e3d4c39b16d2475f99ad79f7364bca8cc1a1172d938afac992fc796ff2c985d23699fdda30a99aa91dc6ad7cdac9edaf5f6692477dcc71bf3f78fed381aa91d297cab15730b3dd6f68cf41e4a85cdfab95febda0cc478dab9771989dfc273c848fd966aab4db3db35d43e862ba2bf9e7c5d84faca8dd0c3c59abc6224f6d8f4ade4739ae266982bc48691d8fbea8291d66137e57c66566d5f24a48da1b51e1dd78b848e21545dd7ad8bb4de2573ce3c1917e9e5c1f5dc3b63ceaa6b8bf48d8b59d35eaa85fae9f38cf0b34f37d7506b47b9f3f983cd82e942c773b14808d75a6ff79e355ad47bc5af1569b1c59ab1913a236f4acf569158d17bf1a2a5ca1967cdcc4b0b960ac6f8fc52a699bf64f00283cc97992e3733344c81bb07557191f3fafa54746fb92d62ce5f5829d26b96c77757e25a37b3186c14295b5f7333a5ae5a5b4a7991b999f102c606d306d9a04b5f2d5b65221272c57b1e7aac290f915c277a7775fba956a5b210c913157b66ee74958348e799c3b6e8301ec6b80c44c62cfe216deedb863c15aad3bebb78dacc1ce5807d48cbf0553a660ef5f63a5516b887e45e4b6f6745ec658a9887b4fc7bb8a166737538577987a4dd9a3a6e2bd6f97d56590784f6f0ea7be261e71c92539efcefa0a5ca38a486eebd5c6ebe4e99a95bd696c4dfc9729ff2f673bad7d69294fa3ad67616d192945f7f3baff68fe6e39d25bdf59a43ecdbad2c29175beabfdde3b26abdb11c6e3fed0d4b6287bb9753afadff5df44a4ac650735407f1ef59b4aea4cfcceda6d4e15652af760e1172a7f02c645692f676fbed5fdcced8ae92de233c9947335795c45c33b48baf9b8b4d25f93aa610626cdfee128b4a42ebac3bddb231e4faec298953f520fade8654d9f0663ead29e9ad7daede1f3d8514bdab01a31e6c29e9214fc656fbb4252539b5ce7ba8cfa21de5a0edfeed3ef8a8aa487945d10d25b93e27d7bd83eca741492c9bfdea3b8d3e49a8d235e7795d9e24f51873f4b8dcea2431a4ce419a98271f9fd3633949ad54327ac7595bffb037498cbd479b9fcbf5f3d2d524bdf7468a316ede87b965929e1bbd3fad4a7df7314c12f343b67c3957d8fe7a493ac82dc2d330dd5a92d0fe3bfb0c296afc0fb792a4cfedf9e61e5a8f9867104b49628baa946aeaaba1f43349c2954dd15a889ccad34fc14a92d86bca177eaa6e2489ed5acce834b7633d084962a88f5d262ab67059ea3e92dcc367d89e1f62ac1cea2feb48ca862adf7a54ddd4ff37927a39cfc63811eb0cca48eab6ec385f7f527791d40b1d5dabab484a657fea612be44c1b3d129b485acf54737e54ef9c75da5a8524e68ba16afdbc29769918302149652fe5d6c4ff601085ac9df32c487268356763cb7539908489faac528e310664ff583fd23b7fa265ac38b3fbf4c147eab687b11e749ae1ead6e0be9c0e6adc4d070e861a07c26a8dbb99d9a3196922dcc3cdce2ad57bcb31f4e956b6a2c07a24c4d071ca8feb570b17cb233d65ff1c991f5eb5bef0480edd1d913b1ddee176a4a38833791f393bcb5d474287e821b6a8cb747c1e948f1e3df2b32227236ab7b8bf280243c3e648cfd5357dc6eeed2ec44a0013a6b90d96e5c8982f1c47e247c63dea919fb7620c47c6bc91316e681b1ac3460bbc466aaed3add7563b6a2467d6efbd7bb6103f434e23639686d1e83d23a9976fb5a5075fae4cf66c46c69491312e301909b1e43d4f99ebfb8792c7484d21b6b89527bad54b35c26238f3223ad8ac9db8c7d1596875f772cf57ad30527b88eca16ae6188ce4faed71dfbf97af2dee49f88bd4cc8f56bb667fe5cfb1170973ed6aafddda45ec1f4021dc45e264dea99cbf513bb7b848ff8d9d43bbda798bb434177b479ece2adf6991d6b9c37e903aecdef17633c3dadc171a44f081b3480fa9d50f9d6bbe0d9d61915e5b6e8f182bc577dcf2156965b6d778bd6d56246f6ba9852e75ab488da965bede4a5f8ba9464542c8fcd858632ad551dd8fa748ead67a36ff86dc6b3329d22f624ef725274791f03bffdde25a8c0f1f8aa4d6da7dc850732af809d698a9f7aaec445a7cd8719deab063478f2a3791d82b96a711af5d4da6ae473013a999428ffccddf9babb344d2c590fd34b5eb9bab2a2b918e42ecdaf27348f5074e22f5f27577dc51b58e8f541989f4dc39ab3da5bdd88947f1118917eaa3dcef428ef0f784b082cc086c44c6a4c04524ec7fd70f5b0b129c9c20730255d4079eabf50f5145f0800d5e6ebac030f365028cf18e4908d88d4d981a0200b0614dd05c025c6e6cc2903000000e061506862fcacb0101d8d43816a6c95003068113b800c0850b1706de0105904d020044c2c5c666c50c1080ba512d860000d48d6a32d4c418c045800610a871313075632323a300170016302025a25d78fe1c55d43d5dfc35c368d2b81a9919669a4c73286fbecc8c7078d8999b9a2e365e646410383baccc014787024e0e3b7333c34c0b232383c0c1010c0dbbc500b665676e9a0c3461646410e05ad2e1ddb5eadc1752e94d4b42fd6ddd71a56f5bae6649eba8cb4507a9546c9e348ec69b6549ebcb164bf4368061348ea6691ccdda7c99b9f1321366c9d4382f33606864608763b97136348ea6008665676ebc74b151323208f02b09f51e75e83974256573a45e33a71ab779732ba9a1852c593fd458497ad6f9d5e36bb95f25a9b5acd669cb5d913542aaa466c7a9d695ba5f280fa7925c43e8bc750c17a392beed42aabdbfa7176f17cf2f3334eb7c4ada97ec2c6ea2ebe2b9c2d8e4056c8a3aaeee653eb794aec0a5a45c3ccfb9d78fcb96e6064c4a7a3e08196a47eee2e915f028e9308610b766cea66d346051d2e347baf9123f94d7b0a163e5d8435e8741e14fd4938ce9449b13dde435d14cb23191676f33ea57f978b29b63675d0cca04c624355e6cfdee7d9edbf625c9799762dbd052b624b9fffae7581e57496299fb0d559b1d765e5355604ad25be6eb47bda3ca83cc93fc663e3f62e4e72077e4db08d5236a7e164b921443abeab1556a21d58b23498e976ae7b5902b3ad5500e0cc9739ddd16b32f55defc11a4cd99d9fbac9d8daca9d4ba86f068738f123992f617bd7ccf75abcb6c8d24f7de7bb7db773db99091b4dcb2cf6a87d022893547847d14ab228931a58ab1c5ae1349aff998a8df91db316444125a8e9b3acb8e968fa20c1f925af66e72e25bad1de46c487ac48326a8a2830e53c61863883146449a490772091404e4308e03499873926a371240303108c4380c632008a2288a184208218410a308218410326264d40db36806b60fb9d042b1cf85de9d9bdb3d958d62f61ac029fd71a1756e58e49e76de1d385c2b243d8fc511abc6d0e6bb45ce053d7f03ebcad03157c9e33dc3ae8655b2a788764dc2b86023eeda3ccceb90a804aa551a5ee590644848d025f962f1e8c0f5fb0858109d3d97c1b4f0de8b2ef86df02d4d6fb8ea253ed19df785b08b4eed065b32480759c96f71159ab84d06a2bcce77c21f24da1604f9450c81861aef61b8c05e883879cc43360ea86d55236f6e8bc70107d38b28c54b58655bbc2c94fec83a058250c9cd83238bec06260a61244dbe6bf54a7fa24e897f6f9c0a6ef3d71565c936f98a294e0bd8c75d5c81057008c5d25bc0db6e25c053360a61b61fc65c4fea7b6956bf1b729bf3d898a8950e58dbf7218b1d6f91b5601bc39aa6588d696b802cb50507e6078fafa8d0e7481dea2f1407dfd6acac665c129a33f39978974426361597b99c23607a72f714284d18c3960faf571ba6df6c1d3bb26565e7c1676a738ca0dd55bb5595c01098fb35f94de05695195935887ff7219b13102fa8b2ea11987e0de9790f21b68f51ed1429a865c29760feb97ef24a8ec2e284d75f205492a5e6826aeccc85766dd90ae328ca48f437a982b82527041fa3715eb8ab5cd367e2c22892a25db476fb5fc7050d93128183b8b5a8f834c925da776b33e9a6ba9049f07cffbefe1dfc678c951619d082e66f1e2f33bccd81a9515c5b293ecaf2de43a0b193e594e4d73b819f3f3dbb1eb89d0a88948d924fb0cf993ee94f284db453659fe6aa2a02a12dd032faafca08e52fbe31e8a9164b671b0da6e5fb7ae39b50d089ff296b6d40037dfc39231f8daf1ef17757e460a5386ede16b828a276ecb5d5cc15995360d29b769ae463b6630a988b29e09c4d143896dba059ca697a2e6647f65db433f03cf100f310f336084d0fbb68f121f5f979a836e7a64ac9490fbd5d1694a82b7c5dac1a1f2e574080340b571b943a671c7fb208612f9460921aef1c0892749cf547af2c086924c00fd114929a1c7fb2b2b229e3f2bfad945cd24827108224f78019ca1693009e947d7bc95c0d540494b854d9893aed2812e5db9bf316236921737a606fdce3c231d3d2f51c5563d565b61fb9bc8dd68bfc669a6b81e783abd5c41b146a9ff7df6a949484d664a9d8172a667556201aedaa7c2362ec85654edf3f026b2b69a46e3003630507b196c5364958ad7bd8541b470ff89dc6f0c0f1dbc06c9205f5c11fc49188e09bd788aaa8309b94064be202ca235aa519bcf3560eddbbdeb2117194fbf3e41453ac930c6cd7d0a8de503a30f49b0485245a84c950740661a5d13650765c81a3f01325bff8ada9ae155bfeae1040a86b0983f1fdea5a7a1febc819073d22f039cc59667aa540f9094fc406ea8f595d8f8e515566554cf8b84c539e061b155a1869a3dede11863d27321fbafe54892ec05a973d929635882fccbe0ea452168ad37c83bb841742a048beba325f994009083fdee8925466a990dd9dc3da54027253273104d8f3c3205e2e97253f14f4029d6843eaf8fda626cdc41880fc0fa9023ef000a18121dca938f0aab9263988207da514b0edd2e48eaf7a5cb4b06376e44ba544bb25cafcc8e78f6e25d07625ad8ebfb19595b0f5ca4393215bcb5bfc5378d04624a1eb134e810463c741af4e4285596668629bea0d0dc34c44d2168e14fca44f439ffb5186b9d240ddde5f07a0fd0e8b717a9d6011f44fc43a80a20ac1e94a21a9aa638449e3bb68629029ef7c8bf90d26831371018b1ed224b8f3e23d0ad7c4a3dbe48d8e4b439c4c4e25277b0dea7aba17965dafbeda1b6d40ed31395ad0f25e36bda3f13b009e05557cc411e39374332c73be6859eb781eadbfd1fcbece553fbf58729eda8946864a0a164f32bd5efc5d823906b7f0c1f404df50639be89b451b81bd0e0816c8adf695f92bddaf6cba4128980b8c112f600ca1676290810f1381908aa147b0e6daf51b7260aae120715c595e22bc6bdb64d85d5a034bee11e0262338d8a8918cbcdd54de1b7f3dac8e07da040235b5dc72db6c5075ebab0e99de4a8329b5d17c66b4f3d1455a027a84e91e936e64842a5284e45e112eb92cd9892314b31e90d503e09d45a64431c509eae2b11332698d1a5e2114b7ce2b26ec0a47cb65893a39610c63889b94928bd880a39bf6e811f1fe2b07658b1f70279474ee4f7de8016db1575e06951b2710b8147f6551b6709a78c68ff5f499c011e098209d3d8b3a18673e04968bfb25a6b87c631e54e22267c961cd7b15fffaab5d385a9d2692222f320d1d56b8a39724f34fc7ea6032a79117e1e0062b585f3526906411bb4a42e124aa2a01c38e949c26363985e87cf0e24375bb5e7ab474050847d3311549420461d5e0713795b5b0851fdc2dfab322cd23bb51a0a8e2132533009aad5e6b2b99b40c5d0511eac836a8054fa291249f132ccc3a92fd5f1d02c70723cd6a1ef60d0099d0de09cfb1f17eda6cd1686343051cb619f8aed9d071a19538cd7885c81b24b78a12ad52562b509c1e3f7592e0408f8d58441e3d0a0cf0c5c65bcd8e348b10c0feb6119e9ae0acdc9985755cc92793ded212caa01749082d7eff5f2152f2c341015cfe5588380ba58319fcdd2348f6f0e11b69f6c080e4184b35d6c11924ab0e068e7acd2c15ef23f7ced68e1ceaecff99243aa0b4093c03fc63544116d4e512bd60f09bffc23edb9919da6a2f1d76f48ee0df7c79178a9a495f78b1820724bd19f930232042266a490d8acda1fcf6a56d87749a3564221d8b588eea63601606cd8b87c7f03ba979b69499f98e44a7d9bbace3ef5e240ad01213937960043facd69616509e05e379de488855f77291aa1523c5c65766a5840a38ac256de93ad64e423e951dd23f3b90122d2a6a1b7f2eb2c2eb2d0177dc22e01adec7cfd669218efc69055bfc7f161b5c0a38e0fbe72ff89a668306e0c86a01427cb1ed1be9a4ce7914f5c0b4415c467404f7e013a78d7a503f966aae841513c23d3a0e2e3f814055b1d6f517c6881845602e7d19fbf8d13ac59058170f5e73bd10bd0601afcca7b2b100b8411a9aad2c45ce841a433ba943572e26a24ffc314c7f71034642b8092a8a9fc54b8ef62b415e6583e77484293a7ab5042ccf7bca1e7e3343aa39bb37dc817853bd5d31ad10c08410e287b827249d5c678e89033997cf0049284877d750075e3fae2295435d26d3581a19ea43d1d4931cb597e06d49ad1afe2a22248580b4a6785240680900ab5efe80ba30b7c6918097682ae9296a3447e40f4071f0129c63558c1ed198cfcf0fc186ef62de2e0bddb25c8f136cfe3765c37e75d140f56a89ab69e784f762310da4bfe7081537378116e40887288c8852e9a8bbad37848e2b48a4139a019339d835a22c583008", + "0x3a65787472696e7369635f696e646578": "0x00000000", + "0x3a6772616e6470615f617574686f726974696573": "0x0110094f736c315addde86b7cd5adac7984cd10b1dc187364e92f7ac901a5447609f0100000000000000cee75bb8d02be946f52be595adfd9e4a8ce0343a9894c5e2471429193926765301000000000000005e7084c57d9f04eaa7c22a86d33757cdef9bbcb6607dab1a7c2262dd1293d7ce01000000000000009ee080484f0429022dda72f19bc76cd0b142689d2782c0a68682bba5c5fb156e0100000000000000", + "0x3d9cad2baf702e20b136f4c8900cd8024e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0x3db7a24cfdc9de785974746c14a99df94e7b9012096b41c4eb3aaf947f6ea429": "0x0400", + "0x3f1467a096bcd71a5b6a0c8155e208104e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x3fba98689ebed1138735e0e7a5a790ab4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x3fba98689ebed1138735e0e7a5a790abee99a84ccbfb4b82e714617e5e06f6f7": "0xd0070000", + "0x42b50b77ef717947e7043bb52127d6654e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x4da2c41eaffa8e1a791c5d65beeefd1f028685274e698e781f7f2766cba0cc8300000000": "0x1003000000010000000000000002000000abc3f086f5ac20eaab792c75933b2e196307835a61a955be82aa63bc0ff9617a0600000010ce68cabd54aaa5c1e9870f89645ee0f2b3cfafc58089b15387b1e87f59ec3d7e701aa8e4ebae70f627b5cca9726c5ac67133b9295eacdfd5f22a3e44297c4e3b866bd4b14f3f67a056b09c6834375bdc6d0b2d7ae387f8568f67afd1db9b8a1bacf21938aa46cda6a2eca3134629bfb201bf45cc62514672daeb4c55f6b2f332000000000000000000000000000000000000000100000000000000", + "0x4da2c41eaffa8e1a791c5d65beeefd1f4e5747352ae927817a9171156fb3da7f00000000": "0x00", + "0x4da2c41eaffa8e1a791c5d65beeefd1f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0x4da2c41eaffa8e1a791c5d65beeefd1f5762b52ec4f696c1235b20491a567f8500000000": "0x00", + "0x4da2c41eaffa8e1a791c5d65beeefd1fff4a51b74593c3708682038efe5323b5": "0x00000000", + "0x50e709b04947c0cd2f04727ef76e88f64e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x5c0d1176a568c1f92944340dbfed9e9c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b": "0x9ed7705e3c7da027ba0583a22a3212042f7e715d3c168ba14f1424e2bc111d00", + "0x5f27b51b5ec208ee9cb25b55d8728243308ce9615de0775a82f8a94dc3d285a1": "0x01", + "0x5f27b51b5ec208ee9cb25b55d87282434e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x5f3e4907f716ac89b6347d15ececedca0b6a45321efae92aea15e0740ec7afe7": "0x00000000", + "0x5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1": "0x0a000000", + "0x5f3e4907f716ac89b6347d15ececedca28dccb559b95c40168a1b2696581b5a7": "0x00000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe705e5f82ad672e896be4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b": "0x388f7ac281acf72b7782ada96bf0c0d3c09f9276c6f4b7c6271c375fa3a28716", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe70ad47afdd1ab6146118caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758": "0xb2858dfa47e91328dc2f41334228a288d19a853ce0e981cd0115c406f001225f", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe70ca9d64ddf2c4bc4afa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c": "0x18484954a9f3547cf962d6dec822c6353042b56776ec58316a5558d75e304f31", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe70dd959ae783e3505c005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f": "0xf628104fc1f6314effd92cd12cfdfb5ee5c913605174e76ec501797254c61d19", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc410675ed593218347060fc977d4c87a2318484954a9f3547cf962d6dec822c6353042b56776ec58316a5558d75e304f31": "0xfa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c0b00407a10f35a0b00407a10f35a0000", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc43c9981354ec1409d0ef80e92fad06bf6388f7ac281acf72b7782ada96bf0c0d3c09f9276c6f4b7c6271c375fa3a28716": "0xe4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b0b00407a10f35a0b00407a10f35a0000", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc488021e4d172831d344e0aa9a1b9bc22ab2858dfa47e91328dc2f41334228a288d19a853ce0e981cd0115c406f001225f": "0x18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb7580b00407a10f35a0b00407a10f35a0000", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc4b5b6969754a268a0612ebdf3fad88e97f628104fc1f6314effd92cd12cfdfb5ee5c913605174e76ec501797254c61d19": "0x005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f0b00407a10f35a0b00407a10f35a0000", + "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a000000005e5f82ad672e896be4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a00000000ad47afdd1ab6146118caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a00000000ca9d64ddf2c4bc4afa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a00000000dd959ae783e3505c005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca487df464e44a534ba6b0cbb32407b587": "0x0000000000", + "0x5f3e4907f716ac89b6347d15ececedca4e7b9012096b41c4eb3aaf947f6ea429": "0x0d00", + "0x5f3e4907f716ac89b6347d15ececedca5579297f4dfb9609e7e4c2ebab9ce40a": "0x10fa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324fe4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758", + "0x5f3e4907f716ac89b6347d15ececedca666fdcbb473985b3ac933d13f4acff8d": "0x00000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a000000005e5f82ad672e896be4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b": "0x0000", + "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a00000000ad47afdd1ab6146118caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758": "0x0000", + "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a00000000ca9d64ddf2c4bc4afa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c": "0x0000", + "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a00000000dd959ae783e3505c005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f": "0x0000", + "0x5f3e4907f716ac89b6347d15ececedca6ddc7809c6da9bb6093ee22e0fda4ba8": "0x04000000", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e169035e5f82ad672e896be4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b": "0x0000", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e16903ad47afdd1ab6146118caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758": "0x0000", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e16903ca9d64ddf2c4bc4afa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c": "0x0000", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e16903dd959ae783e3505c005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f": "0x0000", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a000000005e5f82ad672e896be4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a00000000ad47afdd1ab6146118caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a00000000ca9d64ddf2c4bc4afa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a00000000dd959ae783e3505c005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f": "0x0b00407a10f35a0b00407a10f35a00", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade985e5f82ad672e896be4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade98ad47afdd1ab6146118caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade98ca9d64ddf2c4bc4afa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade98dd959ae783e3505c005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f": "0x00", + "0x5f3e4907f716ac89b6347d15ececedcaa141c4fe67c2d11f4a10c6aca7a79a04b4def25cfda6ef3a00000000": "0x0000e941cc6b01000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcaad811cd65a470ddc5f1d628ff0550982b4def25cfda6ef3a00000000": "0x00000000", + "0x5f3e4907f716ac89b6347d15ececedcab49a2738eeb30896aacb8b3fb46471bd": "0x04000000", + "0x5f3e4907f716ac89b6347d15ececedcac0d39ff577af2cc6b67ac3641fa9c4e7": "0x01000000", + "0x5f3e4907f716ac89b6347d15ececedcac29a0310e1bb45d20cace77ccb62c97d": "0x00e1f505", + "0x5f3e4907f716ac89b6347d15ececedcaea07de2b8f010516dca3f7ef52f7ac5a": "0x040000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcaed441ceb81326c56263efbb60c95c2e4": "0x00000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3": "0x02", + "0x5f3e4907f716ac89b6347d15ececedcafab86d26e629e39b4903db94786fac74": "0xffffffffffffffff0000000000000000", + "0x5f9cc45b7a00c5899361e1c6099678dc4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", + "0x5f9cc45b7a00c5899361e1c6099678dc8a2d09463effcc78a22d75b9cb87dffc": "0x0000000000000000", + "0x5f9cc45b7a00c5899361e1c6099678dcd47cb8f5328af743ddfb361e7180e7fcbb1bdbcacd6ac9340000000000000000": "0x00000000", + "0x63f78c98723ddc9073523ef3beefda0c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x6a0da05ca59913bc38a8630590f2627c2a351b6a99a5b21324516e668bb86a57": "0x00", + "0x6a0da05ca59913bc38a8630590f2627c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x6ac983d82528bf1595ab26438ae5b2cf4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x6cf4040bbce30824850f1a4823d8c65f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x7474449cca95dc5d0c00e71735a6d17d4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0x74dd702da46f77d7acf77f5a48d4af7d4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b155e5f82ad672e896be4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b": "0xe4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b01005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f0118caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758e7f10262de5b000000407a10f35a0000", + "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b15ad47afdd1ab6146118caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758": "0x18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb75801e4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b00e7f10262de5b000000407a10f35a0000", + "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b15ca9d64ddf2c4bc4afa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c": "0xfa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c0001005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324fe7f10262de5b000000407a10f35a0000", + "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b15dd959ae783e3505c005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f": "0x005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f01fa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c01e4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1be7f10262de5b000000407a10f35a0000", + "0x74dd702da46f77d7acf77f5a48d4af7d7a6dc62e324093ba1331bf49fdb2f24a": "0x04000000", + "0x74dd702da46f77d7acf77f5a48d4af7de5c03730c8f59f00941607850b6633d8dec683721ac60452e7f10262de5b0000": "0x01fa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c0118caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758", + "0x7a6d38deaa01cb6e76ee69889f1696272be9a4e88368a2188d2b9100a9f3cd43": "0x00000000000000000000000000000000", + "0x7a6d38deaa01cb6e76ee69889f16962730256ea2c545a3e5e3744665ffb2ed28": "0x00020000", + "0x7a6d38deaa01cb6e76ee69889f1696273f0d64e1907361c689834a9c1cb0fbe0": "0x20000000", + "0x7a6d38deaa01cb6e76ee69889f16962749d67997de33812a1cc37310f765b82e": "0x00000000000000000000000000000000", + "0x7a6d38deaa01cb6e76ee69889f1696274e7b9012096b41c4eb3aaf947f6ea429": "0x0400", + "0x7a6d38deaa01cb6e76ee69889f169627ba93302f3b868c50785e6ade45c6a1d8": "0x10000000", + "0x94eadf0156a8ad5156507773d0471e4a16973e1142f5bd30d9464076794007db": "0x00", + "0x94eadf0156a8ad5156507773d0471e4a1e8de4295679f32032acb318db364135": "0x00", + "0x94eadf0156a8ad5156507773d0471e4a4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x94eadf0156a8ad5156507773d0471e4a64fb6e378f53d72f7859ad0e6b6d8810": "0x0000000000", + "0x94eadf0156a8ad5156507773d0471e4a9ce0310edffce7a01a96c2039f92dd10": "0x01000000", + "0x94eadf0156a8ad5156507773d0471e4ab8ebad86f546c7e0b135a4212aace339": "0x00", + "0xa2ce73642c549ae79c14f0a671cf45f94e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xb341e3a63e58a188839b242d17f8c9f82586833f834350b4d435d5fd269ecc8b": "0x1003000000010000000000000002000000", + "0xb341e3a63e58a188839b242d17f8c9f84e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xb341e3a63e58a188839b242d17f8c9f87a50c904b368210021127f9238883a6e": "0x10ce68cabd54aaa5c1e9870f89645ee0f2b3cfafc58089b15387b1e87f59ec3d7e701aa8e4ebae70f627b5cca9726c5ac67133b9295eacdfd5f22a3e44297c4e3b866bd4b14f3f67a056b09c6834375bdc6d0b2d7ae387f8568f67afd1db9b8a1bacf21938aa46cda6a2eca3134629bfb201bf45cc62514672daeb4c55f6b2f332", + "0xb341e3a63e58a188839b242d17f8c9f8b5cab3380174032968897a4c3ce57c0a": "0x00000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc69a0d9ba64d584162e7d1fc85d6d19ad1005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f": "0x047374616b696e672000407a10f35a0000000000000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6a1e0293801ecda3bccddad286cfce679fa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c": "0x047374616b696e672000407a10f35a0000000000000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6e39abd9d6d25130391c9ff6fc64a35ef18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758": "0x047374616b696e672000407a10f35a0000000000000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6f4c6172605184c65d6c162727408dc0be4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b": "0x047374616b696e672000407a10f35a0000000000000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x0040c7f9727de20d0000000000000000", + "0xca32a41f4b3ed515863dc0a38697f84e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xcd710b30bd2eab0352ddcc26417aa1944e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xcd710b30bd2eab0352ddcc26417aa1949f4993f016e2d2f8e5f43be7bb259486": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb35e5f82ad672e896be4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b": "0x5e7084c57d9f04eaa7c22a86d33757cdef9bbcb6607dab1a7c2262dd1293d7cee6b8162c3e767f8e61892f7fcd06d27041d806e5e0335c59dcdafa5c8e181c5bded28f03696a0c9f9dec223f3cbc44c4895d8b243ebe5cee12f9f02bf0c5043cacf21938aa46cda6a2eca3134629bfb201bf45cc62514672daeb4c55f6b2f332b2174a8685bb3c874484978b71c55b45c4057e290c57c0a076ba9aeb7b6618025ed9fdbd8dffeb5324935a7fafc536de96d62abee0a05d7eefa961c1cf3de266", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3ad47afdd1ab6146118caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758": "0xcee75bb8d02be946f52be595adfd9e4a8ce0343a9894c5e2471429193926765322371e9715d00b3a21c9a899ba3eafd11f5143b821b159b864025ba1eabdb631ce83a2b5c733f98b4018856a1fb0bdf0138dd883cc93a883f97de48b762d6b12701aa8e4ebae70f627b5cca9726c5ac67133b9295eacdfd5f22a3e44297c4e3bd815b1a9dc0077cdf10a4cd3bedc7dd0b5de4b873f9932ae8f8b9d147f43d3000e93248544c963f34bb9cde63c97f85ef7a1939d3c9075907b26edf368fe846e", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3ca9d64ddf2c4bc4afa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c": "0x9ee080484f0429022dda72f19bc76cd0b142689d2782c0a68682bba5c5fb156e585a72774ca9465ba0e7407e4e66d239febbe906cbf090169b6cfa15dd44e5779e3e67bfc0daed31db022fce484b2cf0d757e9aafded1988293da74301275b38ce68cabd54aaa5c1e9870f89645ee0f2b3cfafc58089b15387b1e87f59ec3d7e62f0e85adce6f9782769ae007691df98557e3a04452ac0be90309f88f513f55dca24971e2ec596d510c673f4f8d36d0a8a407b59ffd0643f621369973a335656", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3dd959ae783e3505c005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f": "0x094f736c315addde86b7cd5adac7984cd10b1dc187364e92f7ac901a5447609f006078f6e6a00db1f40097f0d07953008b04cda71ad831e70f37e93eb2b404314a611c52c43142e11767e4443eb56b908babae266b4f446271d11ffaaafbb16e866bd4b14f3f67a056b09c6834375bdc6d0b2d7ae387f8568f67afd1db9b8a1bca5ff4e343aa58559db1467ab84f5241f95baf8fd4bbc4d90856089e74d32669b691bfd2cd584abd1531b7deff6d0e34893960b59ae550348c33abd76af4cb49", + "0xcec5070d609dd3497f72bde07fc96ba04e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195005b6dcd704a27908696d6f6e804a611c52c43142e11767e4443eb56b908babae266b4f446271d11ffaaafbb16e": "0x005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19500a7d72b76c2ec9b06173676e8062f0e85adce6f9782769ae007691df98557e3a04452ac0be90309f88f513f55d": "0xfa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950110db7b3540f726061756469805ed9fdbd8dffeb5324935a7fafc536de96d62abee0a05d7eefa961c1cf3de266": "0xe4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195014a98987c6f4654c6261626580e6b8162c3e767f8e61892f7fcd06d27041d806e5e0335c59dcdafa5c8e181c5b": "0xe4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950270bb04a2a9e106e696d6f6e80ce83a2b5c733f98b4018856a1fb0bdf0138dd883cc93a883f97de48b762d6b12": "0x18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195031063675260bb8076261626580006078f6e6a00db1f40097f0d07953008b04cda71ad831e70f37e93eb2b40431": "0x005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950413ab9d61fa646a76772616e80094f736c315addde86b7cd5adac7984cd10b1dc187364e92f7ac901a5447609f": "0x005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19505404aed8a9c40e507061726180866bd4b14f3f67a056b09c6834375bdc6d0b2d7ae387f8568f67afd1db9b8a1b": "0x005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950597968238adfa9af6772616e80cee75bb8d02be946f52be595adfd9e4a8ce0343a9894c5e24714291939267653": "0x18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19505b639c79d4e8330c696d6f6e809e3e67bfc0daed31db022fce484b2cf0d757e9aafded1988293da74301275b38": "0xfa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195061ccbc794cd1e95c6175646980b691bfd2cd584abd1531b7deff6d0e34893960b59ae550348c33abd76af4cb49": "0x005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19507f0621f339620f26696d6f6e80ded28f03696a0c9f9dec223f3cbc44c4895d8b243ebe5cee12f9f02bf0c5043c": "0xe4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950949420096ce6b2176772616e805e7084c57d9f04eaa7c22a86d33757cdef9bbcb6607dab1a7c2262dd1293d7ce": "0xe4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509af54e7103657a4c7061726180701aa8e4ebae70f627b5cca9726c5ac67133b9295eacdfd5f22a3e44297c4e3b": "0x18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950a359a745f65c1e456261626580585a72774ca9465ba0e7407e4e66d239febbe906cbf090169b6cfa15dd44e577": "0xfa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950af162637344b36a96173676e80d815b1a9dc0077cdf10a4cd3bedc7dd0b5de4b873f9932ae8f8b9d147f43d300": "0x18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950b229c28236e354a26173676e80b2174a8685bb3c874484978b71c55b45c4057e290c57c0a076ba9aeb7b661802": "0xe4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950b6b8ce596a13561b7061726180acf21938aa46cda6a2eca3134629bfb201bf45cc62514672daeb4c55f6b2f332": "0xe4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950bee8d7df4d460d9d61756469800e93248544c963f34bb9cde63c97f85ef7a1939d3c9075907b26edf368fe846e": "0x18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950c02fd5bdeb0ec6f06175646980ca24971e2ec596d510c673f4f8d36d0a8a407b59ffd0643f621369973a335656": "0xfa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d9ebe2452f14a591626162658022371e9715d00b3a21c9a899ba3eafd11f5143b821b159b864025ba1eabdb631": "0x18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950e322099b0a5bb5836772616e809ee080484f0429022dda72f19bc76cd0b142689d2782c0a68682bba5c5fb156e": "0xfa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950e6ddf4dc42f9b1b66173676e80ca5ff4e343aa58559db1467ab84f5241f95baf8fd4bbc4d90856089e74d32669": "0x005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f8bc7112b190dae97061726180ce68cabd54aaa5c1e9870f89645ee0f2b3cfafc58089b15387b1e87f59ec3d7e": "0xfa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c", + "0xcec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903": "0x10005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f18caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758e4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1bfa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c", + "0xcec5070d609dd3497f72bde07fc96ba0e0cdd062e6eaf24295ad4ccfc41d4609": "0x10005203395fd92c2b411136466e88ef74dd6327c0a6f32b3be7e38d56a2e1324f094f736c315addde86b7cd5adac7984cd10b1dc187364e92f7ac901a5447609f006078f6e6a00db1f40097f0d07953008b04cda71ad831e70f37e93eb2b404314a611c52c43142e11767e4443eb56b908babae266b4f446271d11ffaaafbb16e866bd4b14f3f67a056b09c6834375bdc6d0b2d7ae387f8568f67afd1db9b8a1bca5ff4e343aa58559db1467ab84f5241f95baf8fd4bbc4d90856089e74d32669b691bfd2cd584abd1531b7deff6d0e34893960b59ae550348c33abd76af4cb4918caf23bb6b8cda7f3f90c1dc2b2f6c2b7143b13c956ef0a12dfe486e83cb758cee75bb8d02be946f52be595adfd9e4a8ce0343a9894c5e2471429193926765322371e9715d00b3a21c9a899ba3eafd11f5143b821b159b864025ba1eabdb631ce83a2b5c733f98b4018856a1fb0bdf0138dd883cc93a883f97de48b762d6b12701aa8e4ebae70f627b5cca9726c5ac67133b9295eacdfd5f22a3e44297c4e3bd815b1a9dc0077cdf10a4cd3bedc7dd0b5de4b873f9932ae8f8b9d147f43d3000e93248544c963f34bb9cde63c97f85ef7a1939d3c9075907b26edf368fe846ee4c1d81c7e8df384e1ae9667a668825c56e95b0f7d3b1ba2f7539d4c470abb1b5e7084c57d9f04eaa7c22a86d33757cdef9bbcb6607dab1a7c2262dd1293d7cee6b8162c3e767f8e61892f7fcd06d27041d806e5e0335c59dcdafa5c8e181c5bded28f03696a0c9f9dec223f3cbc44c4895d8b243ebe5cee12f9f02bf0c5043cacf21938aa46cda6a2eca3134629bfb201bf45cc62514672daeb4c55f6b2f332b2174a8685bb3c874484978b71c55b45c4057e290c57c0a076ba9aeb7b6618025ed9fdbd8dffeb5324935a7fafc536de96d62abee0a05d7eefa961c1cf3de266fa6a6474ec1a9234888f7b20d3978a706d386d0f16344765faa48cb376db331c9ee080484f0429022dda72f19bc76cd0b142689d2782c0a68682bba5c5fb156e585a72774ca9465ba0e7407e4e66d239febbe906cbf090169b6cfa15dd44e5779e3e67bfc0daed31db022fce484b2cf0d757e9aafded1988293da74301275b38ce68cabd54aaa5c1e9870f89645ee0f2b3cfafc58089b15387b1e87f59ec3d7e62f0e85adce6f9782769ae007691df98557e3a04452ac0be90309f88f513f55dca24971e2ec596d510c673f4f8d36d0a8a407b59ffd0643f621369973a335656", + "0xd57bce545fb382c34570e5dfbf338f5e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xd5c41b52a371aa36c9254ce34324f2a54e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xd5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xd8bbe27baf3aa64bb483afabc240f68e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xd8f314b7f4e6b095f0f8ee4656a448254e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0xede8e4fdc3c8b556f0ce2f77fc2575e34e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0xf0c365c3cf59d671eb72da0e7a4113c44e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xf5207f03cfdce586301014700e2c25934e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0xf5a4963e4efb097983d7a693b0c1ee454e7b9012096b41c4eb3aaf947f6ea429": "0x0100" + }, + "childrenDefault": {} + } + } +} diff --git a/polkadot/node/service/src/benchmarking.rs b/polkadot/node/service/src/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..6955bc6d96900a7f4c38b419dbb8b7c9e4d06656 --- /dev/null +++ b/polkadot/node/service/src/benchmarking.rs @@ -0,0 +1,443 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Code related to benchmarking a [`crate::Client`]. + +use polkadot_primitives::AccountId; +use sc_client_api::UsageProvider; +use sp_keyring::Sr25519Keyring; +use sp_runtime::OpaqueExtrinsic; + +use crate::*; + +macro_rules! identify_chain { + ( + $chain:expr, + $nonce:ident, + $current_block:ident, + $period:ident, + $genesis:ident, + $signer:ident, + $generic_code:expr $(,)* + ) => { + match $chain { + Chain::Polkadot => { + #[cfg(feature = "polkadot-native")] + { + use polkadot_runtime as runtime; + + let call = $generic_code; + + Ok(polkadot_sign_call(call, $nonce, $current_block, $period, $genesis, $signer)) + } + + #[cfg(not(feature = "polkadot-native"))] + { + Err("`polkadot-native` feature not enabled") + } + }, + Chain::Kusama => { + #[cfg(feature = "kusama-native")] + { + use kusama_runtime as runtime; + + let call = $generic_code; + + Ok(kusama_sign_call(call, $nonce, $current_block, $period, $genesis, $signer)) + } + + #[cfg(not(feature = "kusama-native"))] + { + Err("`kusama-native` feature not enabled") + } + }, + Chain::Rococo => { + #[cfg(feature = "rococo-native")] + { + use rococo_runtime as runtime; + + let call = $generic_code; + + Ok(rococo_sign_call(call, $nonce, $current_block, $period, $genesis, $signer)) + } + + #[cfg(not(feature = "rococo-native"))] + { + Err("`rococo-native` feature not enabled") + } + }, + Chain::Westend => { + #[cfg(feature = "westend-native")] + { + use westend_runtime as runtime; + + let call = $generic_code; + + Ok(westend_sign_call(call, $nonce, $current_block, $period, $genesis, $signer)) + } + + #[cfg(not(feature = "westend-native"))] + { + let _ = $nonce; + let _ = $current_block; + let _ = $period; + let _ = $genesis; + let _ = $signer; + + Err("`westend-native` feature not enabled") + } + }, + Chain::Unknown => Err("Unknown chain"), + } + }; +} + +/// Generates `System::Remark` extrinsics for the benchmarks. +/// +/// Note: Should only be used for benchmarking. +pub struct RemarkBuilder { + client: Arc, + chain: Chain, +} + +impl RemarkBuilder { + /// Creates a new [`Self`] from the given client. + pub fn new(client: Arc, chain: Chain) -> Self { + Self { client, chain } + } +} + +impl frame_benchmarking_cli::ExtrinsicBuilder for RemarkBuilder { + fn pallet(&self) -> &str { + "system" + } + + fn extrinsic(&self) -> &str { + "remark" + } + + fn build(&self, nonce: u32) -> std::result::Result { + let period = polkadot_runtime_common::BlockHashCount::get() + .checked_next_power_of_two() + .map(|c| c / 2) + .unwrap_or(2) as u64; + let genesis = self.client.usage_info().chain.best_hash; + let signer = Sr25519Keyring::Bob.pair(); + let current_block = 0; + + identify_chain! { + self.chain, + nonce, + current_block, + period, + genesis, + signer, + { + runtime::RuntimeCall::System( + runtime::SystemCall::remark { remark: vec![] } + ) + }, + } + } +} + +/// Generates `Balances::TransferKeepAlive` extrinsics for the benchmarks. +/// +/// Note: Should only be used for benchmarking. +pub struct TransferKeepAliveBuilder { + client: Arc, + dest: AccountId, + chain: Chain, +} + +impl TransferKeepAliveBuilder { + /// Creates a new [`Self`] from the given client and the arguments for the extrinsics. + pub fn new(client: Arc, dest: AccountId, chain: Chain) -> Self { + Self { client, dest, chain } + } +} + +impl frame_benchmarking_cli::ExtrinsicBuilder for TransferKeepAliveBuilder { + fn pallet(&self) -> &str { + "balances" + } + + fn extrinsic(&self) -> &str { + "transfer_keep_alive" + } + + fn build(&self, nonce: u32) -> std::result::Result { + let signer = Sr25519Keyring::Bob.pair(); + let period = polkadot_runtime_common::BlockHashCount::get() + .checked_next_power_of_two() + .map(|c| c / 2) + .unwrap_or(2) as u64; + let genesis = self.client.usage_info().chain.best_hash; + let current_block = 0; + let _dest = self.dest.clone(); + + identify_chain! { + self.chain, + nonce, + current_block, + period, + genesis, + signer, + { + runtime::RuntimeCall::Balances(runtime::BalancesCall::transfer_keep_alive { + dest: _dest.into(), + value: runtime::ExistentialDeposit::get(), + }) + }, + } + } +} + +#[cfg(feature = "polkadot-native")] +fn polkadot_sign_call( + call: polkadot_runtime::RuntimeCall, + nonce: u32, + current_block: u64, + period: u64, + genesis: sp_core::H256, + acc: sp_core::sr25519::Pair, +) -> OpaqueExtrinsic { + use codec::Encode; + use polkadot_runtime as runtime; + use sp_core::Pair; + + let extra: runtime::SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(sp_runtime::generic::Era::mortal( + period, + current_block, + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + polkadot_runtime_common::claims::PrevalidateAttests::::new(), + ); + + let payload = runtime::SignedPayload::from_raw( + call.clone(), + extra.clone(), + ( + (), + runtime::VERSION.spec_version, + runtime::VERSION.transaction_version, + genesis, + genesis, + (), + (), + (), + (), + ), + ); + + let signature = payload.using_encoded(|p| acc.sign(p)); + runtime::UncheckedExtrinsic::new_signed( + call, + sp_runtime::AccountId32::from(acc.public()).into(), + polkadot_core_primitives::Signature::Sr25519(signature.clone()), + extra, + ) + .into() +} + +#[cfg(feature = "westend-native")] +fn westend_sign_call( + call: westend_runtime::RuntimeCall, + nonce: u32, + current_block: u64, + period: u64, + genesis: sp_core::H256, + acc: sp_core::sr25519::Pair, +) -> OpaqueExtrinsic { + use codec::Encode; + use sp_core::Pair; + use westend_runtime as runtime; + + let extra: runtime::SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(sp_runtime::generic::Era::mortal( + period, + current_block, + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + ); + + let payload = runtime::SignedPayload::from_raw( + call.clone(), + extra.clone(), + ( + (), + runtime::VERSION.spec_version, + runtime::VERSION.transaction_version, + genesis, + genesis, + (), + (), + (), + ), + ); + + let signature = payload.using_encoded(|p| acc.sign(p)); + runtime::UncheckedExtrinsic::new_signed( + call, + sp_runtime::AccountId32::from(acc.public()).into(), + polkadot_core_primitives::Signature::Sr25519(signature.clone()), + extra, + ) + .into() +} + +#[cfg(feature = "kusama-native")] +fn kusama_sign_call( + call: kusama_runtime::RuntimeCall, + nonce: u32, + current_block: u64, + period: u64, + genesis: sp_core::H256, + acc: sp_core::sr25519::Pair, +) -> OpaqueExtrinsic { + use codec::Encode; + use kusama_runtime as runtime; + use sp_core::Pair; + + let extra: runtime::SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(sp_runtime::generic::Era::mortal( + period, + current_block, + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + ); + + let payload = runtime::SignedPayload::from_raw( + call.clone(), + extra.clone(), + ( + (), + runtime::VERSION.spec_version, + runtime::VERSION.transaction_version, + genesis, + genesis, + (), + (), + (), + ), + ); + + let signature = payload.using_encoded(|p| acc.sign(p)); + runtime::UncheckedExtrinsic::new_signed( + call, + sp_runtime::AccountId32::from(acc.public()).into(), + polkadot_core_primitives::Signature::Sr25519(signature.clone()), + extra, + ) + .into() +} + +#[cfg(feature = "rococo-native")] +fn rococo_sign_call( + call: rococo_runtime::RuntimeCall, + nonce: u32, + current_block: u64, + period: u64, + genesis: sp_core::H256, + acc: sp_core::sr25519::Pair, +) -> OpaqueExtrinsic { + use codec::Encode; + use rococo_runtime as runtime; + use sp_core::Pair; + + let extra: runtime::SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(sp_runtime::generic::Era::mortal( + period, + current_block, + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + ); + + let payload = runtime::SignedPayload::from_raw( + call.clone(), + extra.clone(), + ( + (), + runtime::VERSION.spec_version, + runtime::VERSION.transaction_version, + genesis, + genesis, + (), + (), + (), + ), + ); + + let signature = payload.using_encoded(|p| acc.sign(p)); + runtime::UncheckedExtrinsic::new_signed( + call, + sp_runtime::AccountId32::from(acc.public()).into(), + polkadot_core_primitives::Signature::Sr25519(signature.clone()), + extra, + ) + .into() +} + +/// Generates inherent data for benchmarking Polkadot, Kusama, Westend and Rococo. +/// +/// Not to be used outside of benchmarking since it returns mocked values. +pub fn benchmark_inherent_data( + header: polkadot_core_primitives::Header, +) -> std::result::Result { + use sp_inherents::InherentDataProvider; + let mut inherent_data = sp_inherents::InherentData::new(); + + // Assume that all runtimes have the `timestamp` pallet. + let d = std::time::Duration::from_millis(0); + let timestamp = sp_timestamp::InherentDataProvider::new(d.into()); + futures::executor::block_on(timestamp.provide_inherent_data(&mut inherent_data))?; + + let para_data = polkadot_primitives::InherentData { + bitfields: Vec::new(), + backed_candidates: Vec::new(), + disputes: Vec::new(), + parent_header: header, + }; + + inherent_data.put_data(polkadot_primitives::PARACHAINS_INHERENT_IDENTIFIER, ¶_data)?; + + Ok(inherent_data) +} diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs new file mode 100644 index 0000000000000000000000000000000000000000..1e5aaa807b8178989700902f0a7a80b1b1fe1d76 --- /dev/null +++ b/polkadot/node/service/src/chain_spec.rs @@ -0,0 +1,1981 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot chain configurations. + +use beefy_primitives::ecdsa_crypto::AuthorityId as BeefyId; +use grandpa::AuthorityId as GrandpaId; +#[cfg(feature = "kusama-native")] +use kusama_runtime as kusama; +#[cfg(feature = "kusama-native")] +use kusama_runtime_constants::currency::UNITS as KSM; +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +#[cfg(any( + feature = "polkadot-native", + feature = "kusama-native", + feature = "westend-native", +))] +use pallet_staking::Forcing; +use polkadot_primitives::{AccountId, AccountPublic, AssignmentId, ValidatorId}; +#[cfg(feature = "polkadot-native")] +use polkadot_runtime as polkadot; +#[cfg(feature = "polkadot-native")] +use polkadot_runtime_constants::currency::UNITS as DOT; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_consensus_babe::AuthorityId as BabeId; + +#[cfg(feature = "rococo-native")] +use rococo_runtime as rococo; +#[cfg(feature = "rococo-native")] +use rococo_runtime_constants::currency::UNITS as ROC; +use sc_chain_spec::ChainSpecExtension; +#[cfg(any( + feature = "polkadot-native", + feature = "kusama-native", + feature = "westend-native", + feature = "rococo-native" +))] +use sc_chain_spec::ChainType; +use serde::{Deserialize, Serialize}; +use sp_core::{sr25519, Pair, Public}; +use sp_runtime::traits::IdentifyAccount; +#[cfg(any( + feature = "polkadot-native", + feature = "kusama-native", + feature = "westend-native", +))] +use sp_runtime::Perbill; +#[cfg(any( + feature = "polkadot-native", + feature = "kusama-native", + feature = "westend-native", + feature = "rococo-native" +))] +use telemetry::TelemetryEndpoints; +#[cfg(feature = "westend-native")] +use westend_runtime as westend; +#[cfg(feature = "westend-native")] +use westend_runtime_constants::currency::UNITS as WND; + +#[cfg(feature = "kusama-native")] +const KUSAMA_STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; +#[cfg(feature = "westend-native")] +const WESTEND_STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; +#[cfg(feature = "rococo-native")] +const ROCOCO_STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; +#[cfg(feature = "rococo-native")] +const VERSI_STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; +#[cfg(any( + feature = "polkadot-native", + feature = "kusama-native", + feature = "westend-native", + feature = "rococo-native" +))] +const DEFAULT_PROTOCOL_ID: &str = "dot"; + +/// Node `ChainSpec` extensions. +/// +/// Additional parameters for some Substrate core modules, +/// customizable from the chain spec. +#[derive(Default, Clone, Serialize, Deserialize, ChainSpecExtension)] +#[serde(rename_all = "camelCase")] +pub struct Extensions { + /// Block numbers with known hashes. + pub fork_blocks: sc_client_api::ForkBlocks, + /// Known bad block hashes. + pub bad_blocks: sc_client_api::BadBlocks, + /// The light sync state. + /// + /// This value will be set by the `sync-state rpc` implementation. + pub light_sync_state: sc_sync_state_rpc::LightSyncStateExtension, +} + +/// The `ChainSpec` parameterized for the polkadot runtime. +#[cfg(feature = "polkadot-native")] +pub type PolkadotChainSpec = service::GenericChainSpec; + +// Dummy chain spec, in case when we don't have the native runtime. +pub type DummyChainSpec = service::GenericChainSpec<(), Extensions>; + +// Dummy chain spec, but that is fine when we don't have the native runtime. +#[cfg(not(feature = "polkadot-native"))] +pub type PolkadotChainSpec = DummyChainSpec; + +/// The `ChainSpec` parameterized for the kusama runtime. +#[cfg(feature = "kusama-native")] +pub type KusamaChainSpec = service::GenericChainSpec; + +/// The `ChainSpec` parameterized for the kusama runtime. +// Dummy chain spec, but that is fine when we don't have the native runtime. +#[cfg(not(feature = "kusama-native"))] +pub type KusamaChainSpec = DummyChainSpec; + +/// The `ChainSpec` parameterized for the westend runtime. +#[cfg(feature = "westend-native")] +pub type WestendChainSpec = service::GenericChainSpec; + +/// The `ChainSpec` parameterized for the westend runtime. +// Dummy chain spec, but that is fine when we don't have the native runtime. +#[cfg(not(feature = "westend-native"))] +pub type WestendChainSpec = DummyChainSpec; + +/// The `ChainSpec` parameterized for the rococo runtime. +#[cfg(feature = "rococo-native")] +pub type RococoChainSpec = service::GenericChainSpec; + +/// The `ChainSpec` parameterized for the `versi` runtime. +/// +/// As of now `Versi` will just be a clone of `Rococo`, until we need it to differ. +pub type VersiChainSpec = RococoChainSpec; + +/// The `ChainSpec` parameterized for the rococo runtime. +// Dummy chain spec, but that is fine when we don't have the native runtime. +#[cfg(not(feature = "rococo-native"))] +pub type RococoChainSpec = DummyChainSpec; + +/// Extension for the Rococo genesis config to support a custom changes to the genesis state. +#[derive(serde::Serialize, serde::Deserialize)] +#[cfg(feature = "rococo-native")] +pub struct RococoGenesisExt { + /// The runtime genesis config. + runtime_genesis_config: rococo::RuntimeGenesisConfig, + /// The session length in blocks. + /// + /// If `None` is supplied, the default value is used. + session_length_in_blocks: Option, +} + +#[cfg(feature = "rococo-native")] +impl sp_runtime::BuildStorage for RococoGenesisExt { + fn assimilate_storage(&self, storage: &mut sp_core::storage::Storage) -> Result<(), String> { + sp_state_machine::BasicExternalities::execute_with_storage(storage, || { + if let Some(length) = self.session_length_in_blocks.as_ref() { + rococo_runtime_constants::time::EpochDurationInBlocks::set(length); + } + }); + self.runtime_genesis_config.assimilate_storage(storage) + } +} + +pub fn polkadot_config() -> Result { + PolkadotChainSpec::from_json_bytes(&include_bytes!("../chain-specs/polkadot.json")[..]) +} + +pub fn kusama_config() -> Result { + KusamaChainSpec::from_json_bytes(&include_bytes!("../chain-specs/kusama.json")[..]) +} + +pub fn westend_config() -> Result { + WestendChainSpec::from_json_bytes(&include_bytes!("../chain-specs/westend.json")[..]) +} + +pub fn rococo_config() -> Result { + RococoChainSpec::from_json_bytes(&include_bytes!("../chain-specs/rococo.json")[..]) +} + +/// This is a temporary testnet that uses the same runtime as rococo. +pub fn wococo_config() -> Result { + RococoChainSpec::from_json_bytes(&include_bytes!("../chain-specs/wococo.json")[..]) +} + +/// The default parachains host configuration. +#[cfg(any( + feature = "rococo-native", + feature = "kusama-native", + feature = "westend-native", + feature = "polkadot-native" +))] +fn default_parachains_host_configuration( +) -> polkadot_runtime_parachains::configuration::HostConfiguration +{ + use polkadot_primitives::{MAX_CODE_SIZE, MAX_POV_SIZE}; + + polkadot_runtime_parachains::configuration::HostConfiguration { + validation_upgrade_cooldown: 2u32, + validation_upgrade_delay: 2, + code_retention_period: 1200, + max_code_size: MAX_CODE_SIZE, + max_pov_size: MAX_POV_SIZE, + max_head_data_size: 32 * 1024, + group_rotation_frequency: 20, + paras_availability_period: 4, + max_upward_queue_count: 8, + max_upward_queue_size: 1024 * 1024, + max_downward_message_size: 1024 * 1024, + max_upward_message_size: 50 * 1024, + max_upward_message_num_per_candidate: 5, + hrmp_sender_deposit: 0, + hrmp_recipient_deposit: 0, + hrmp_channel_max_capacity: 8, + hrmp_channel_max_total_size: 8 * 1024, + hrmp_max_parachain_inbound_channels: 4, + hrmp_channel_max_message_size: 1024 * 1024, + hrmp_max_parachain_outbound_channels: 4, + hrmp_max_message_num_per_candidate: 5, + dispute_period: 6, + no_show_slots: 2, + n_delay_tranches: 25, + needed_approvals: 2, + relay_vrf_modulo_samples: 2, + zeroth_delay_tranche_width: 0, + minimum_validation_upgrade_delay: 5, + ..Default::default() + } +} + +#[cfg(any( + feature = "rococo-native", + feature = "kusama-native", + feature = "westend-native", + feature = "polkadot-native" +))] +#[test] +fn default_parachains_host_configuration_is_consistent() { + default_parachains_host_configuration().panic_if_not_consistent(); +} + +#[cfg(feature = "polkadot-native")] +fn polkadot_session_keys( + babe: BabeId, + grandpa: GrandpaId, + im_online: ImOnlineId, + para_validator: ValidatorId, + para_assignment: AssignmentId, + authority_discovery: AuthorityDiscoveryId, +) -> polkadot::SessionKeys { + polkadot::SessionKeys { + babe, + grandpa, + im_online, + para_validator, + para_assignment, + authority_discovery, + } +} + +#[cfg(feature = "kusama-native")] +fn kusama_session_keys( + babe: BabeId, + grandpa: GrandpaId, + im_online: ImOnlineId, + para_validator: ValidatorId, + para_assignment: AssignmentId, + authority_discovery: AuthorityDiscoveryId, + beefy: BeefyId, +) -> kusama::SessionKeys { + kusama::SessionKeys { + babe, + grandpa, + im_online, + para_validator, + para_assignment, + authority_discovery, + beefy, + } +} + +#[cfg(feature = "westend-native")] +fn westend_session_keys( + babe: BabeId, + grandpa: GrandpaId, + im_online: ImOnlineId, + para_validator: ValidatorId, + para_assignment: AssignmentId, + authority_discovery: AuthorityDiscoveryId, + beefy: BeefyId, +) -> westend::SessionKeys { + westend::SessionKeys { + babe, + grandpa, + im_online, + para_validator, + para_assignment, + authority_discovery, + beefy, + } +} + +#[cfg(feature = "rococo-native")] +fn rococo_session_keys( + babe: BabeId, + grandpa: GrandpaId, + im_online: ImOnlineId, + para_validator: ValidatorId, + para_assignment: AssignmentId, + authority_discovery: AuthorityDiscoveryId, + beefy: BeefyId, +) -> rococo_runtime::SessionKeys { + rococo_runtime::SessionKeys { + babe, + grandpa, + im_online, + para_validator, + para_assignment, + authority_discovery, + beefy, + } +} + +#[cfg(feature = "westend-native")] +fn westend_staging_testnet_config_genesis(wasm_binary: &[u8]) -> westend::RuntimeGenesisConfig { + use hex_literal::hex; + use sp_core::crypto::UncheckedInto; + + // Following keys are used in genesis config for development chains. + // DO NOT use them in production chains as the secret seed is public. + // + // SECRET_SEED="slow awkward present example safe bundle science ocean cradle word tennis earn" + // subkey inspect -n polkadot "$SECRET_SEED" + let endowed_accounts = vec![ + // 15S75FkhCWEowEGfxWwVfrW3LQuy8w8PNhVmrzfsVhCMjUh1 + hex!["c416837e232d9603e83162ef4bda08e61580eeefe60fe92fc044aa508559ae42"].into(), + ]; + // SECRET=$SECRET_SEED ./scripts/prepare-test-net.sh 4 + let initial_authorities: Vec<( + AccountId, + AccountId, + BabeId, + GrandpaId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + BeefyId, + )> = vec![ + ( + //5EvydUTtHvt39Khac3mMxNPgzcfu49uPDzUs3TL7KEzyrwbw + hex!["7ecfd50629cdd246649959d88d490b31508db511487e111a52a392e6e458f518"].into(), + //5HQyX5gyy77m9QLXguAhiwjTArHYjYspeY98dYDu1JDetfZg + hex!["eca2cca09bdc66a7e6d8c3d9499a0be2ad4690061be8a9834972e17d13d2fe7e"].into(), + //5G13qYRudTyttwTJvHvnwp8StFtcfigyPnwfD4v7LNopsnX4 + hex!["ae27367cb77850fb195fe1f9c60b73210409e68c5ad953088070f7d8513d464c"] + .unchecked_into(), + //5Eb7wM65PNgtY6e33FEAzYtU5cRTXt6WQvZTnzaKQwkVcABk + hex!["6faae44b21c6f2681a7f60df708e9f79d340f7d441d28bd987fab8d05c6487e8"] + .unchecked_into(), + //5CdS2wGo4qdTQceVfEnbZH8vULeBrnGYCxSCxDna4tQSMV6y + hex!["18f5d55f138bfa8e0ea26ed6fa56817b247de3c2e2030a908c63fb37c146473f"] + .unchecked_into(), + //5FqMLAgygdX9UqzukDp15Uid9PAKdFAR621U7xtp5ut2NfrW + hex!["a6c1a5b501985a83cb1c37630c5b41e6b0a15b3675b2fd94694758e6cfa6794d"] + .unchecked_into(), + //5DhXAV75BKvF9o447ikWqLttyL2wHtLMFSX7GrsKF9Ny61Ta + hex!["485051748ab9c15732f19f3fbcf1fd00a6d9709635f084505107fbb059c33d2f"] + .unchecked_into(), + //5GNHfmrtWLTawnGCmc39rjAEiW97vKvE7DGePYe4am5JtE4i + hex!["be59ed75a72f7b47221ce081ba4262cf2e1ea7867e30e0b3781822f942b97677"] + .unchecked_into(), + //5DA6Z8RUF626stn94aTRBCeobDCYcFbU7Pdk4Tz1R9vA8B8F + hex!["0207e43990799e1d02b0507451e342a1240ff836ea769c57297589a5fd072ad8f4"] + .unchecked_into(), + ), + ( + //5DFpvDUdCgw54E3E357GR1PyJe3Ft9s7Qyp7wbELAoJH9RQa + hex!["34b7b3efd35fcc3c1926ca065381682b1af29b57dabbcd091042c6de1d541b7d"].into(), + //5DZSSsND5wCjngvyXv27qvF3yPzt3MCU8rWnqNy4imqZmjT8 + hex!["4226796fa792ac78875e023ff2e30e3c2cf79f0b7b3431254cd0f14a3007bc0e"].into(), + //5CPrgfRNDQvQSnLRdeCphP3ibj5PJW9ESbqj2fw29vBMNQNn + hex!["0e9b60f04be3bffe362eb2212ea99d2b909b052f4bff7c714e13c2416a797f5d"] + .unchecked_into(), + //5FXFsPReTUEYPRNKhbTdUathcWBsxTNsLbk2mTpYdKCJewjA + hex!["98f4d81cb383898c2c3d54dab28698c0f717c81b509cb32dc6905af3cc697b18"] + .unchecked_into(), + //5CDYSCJK91r8y2r1V4Ddrit4PFMEkwZXJe8mNBqGXJ4xWCWq + hex!["06bd7dd4ab4c808c7d09d9cb6bd27fbcd99ad8400e99212b335056c475c24031"] + .unchecked_into(), + //5CZjurB78XbSHf6SLkLhCdkqw52Zm7aBYUDdfkLqEDWJ9Zhj + hex!["162508accd470e379b04cb0c7c60b35a7d5357e84407a89ed2dd48db4b726960"] + .unchecked_into(), + //5DkAqCtSjUMVoJFauuGoAbSEgn2aFCRGziKJiLGpPwYgE1pS + hex!["4a559c028b69a7f784ce553393e547bec0aa530352157603396d515f9c83463b"] + .unchecked_into(), + //5GsBt9MhGwkg8Jfb1F9LAy2kcr88WNyNy4L5ezwbCr8NWKQU + hex!["d464908266c878acbf181bf8fda398b3aa3fd2d05508013e414aaece4cf0d702"] + .unchecked_into(), + //5DtJVkz8AHevEnpszy3X4dUcPvACW6x1qBMQZtFxjexLr5bq + hex!["02fdf30222d2cb88f2376d558d3de9cb83f9fde3aa4b2dd40c93e3104e3488bcd2"] + .unchecked_into(), + ), + ( + //5E2cob2jrXsBkTih56pizwSqENjE4siaVdXhaD6akLdDyVq7 + hex!["56e0f73c563d49ee4a3971c393e17c44eaa313dabad7fcf297dc3271d803f303"].into(), + //5D4rNYgP9uFNi5GMyDEXTfiaFLjXyDEEX2VvuqBVi3f1qgCh + hex!["2c58e5e1d5aef77774480cead4f6876b1a1a6261170166995184d7f86140572b"].into(), + //5Ea2D65KXqe625sz4uV1jjhSfuigVnkezC8VgEj9LXN7ERAk + hex!["6ed45cb7af613be5d88a2622921e18d147225165f24538af03b93f2a03ce6e13"] + .unchecked_into(), + //5G4kCbgqUhEyrRHCyFwFEkgBZXoYA8sbgsRxT9rY8Tp5Jj5F + hex!["b0f8d2b9e4e1eafd4dab6358e0b9d5380d78af27c094e69ae9d6d30ca300fd86"] + .unchecked_into(), + //5HVhFBLFTKSZK9fX6RktckWDTgYNoSd33fgonsEC8zfr4ddm + hex!["f03c3e184b2883eec9beaeb97f54321587e7476b228831ea0b5fc6da847ea975"] + .unchecked_into(), + //5CS7thd2n54WfqeKU3cjvZzK4z5p7zku1Zw97mSzXgPioAAs + hex!["1055100a283968271a0781450b389b9093231be809be1e48a305ebad2a90497e"] + .unchecked_into(), + //5DSaL4ZmSYarZSazhL5NQh7LT6pWhNRDcefk2QS9RxEXfsJe + hex!["3cea4ab74bab4adf176cf05a6e18c1599a7bc217d4c6c217275bfbe3b037a527"] + .unchecked_into(), + //5CaNLkYEbFYXZodXhd3UjV6RNLjFGNLiYafc8X5NooMkZiAq + hex!["169faa81aebfe74533518bda28567f2e2664014c8905aa07ea003336afda5a58"] + .unchecked_into(), + //5ERwhKiePayukzZStMuzGzRJGxGRFpwxYUXVarQpMSMrXzDS + hex!["03429d0d20f6ac5ca8b349f04d014f7b5b864acf382a744104d5d9a51108156c0f"] + .unchecked_into(), + ), + ( + //5H6j9ovzYk9opckVjvM9SvVfaK37ASTtPTzWeRfqk1tgLJUN + hex!["deb804ed2ed2bb696a3dd4ed7de4cd5c496528a2b204051c6ace385bacd66a3a"].into(), + //5DJ51tMW916mGwjMpfS1o9skcNt6Sb28YnZQXaKVg4h89agE + hex!["366da6a748afedb31f07902f2de36ab265beccee37762d3ae1f237de234d9c36"].into(), + //5CSPYDYoCDGSoSLgSp4EHkJ52YasZLHG2woqhPZkdbtNQpke + hex!["1089bc0cd60237d061872925e81d36c9d9205d250d5d8b542c8e08a8ecf1b911"] + .unchecked_into(), + //5ChfdrAqmLjCeDJvynbMjcxYLHYzPe8UWXd3HnX9JDThUMbn + hex!["1c309a70b4e274314b84c9a0a1f973c9c4fc084df5479ef686c54b1ae4950424"] + .unchecked_into(), + //5DnsMm24575xK2b2aGfmafiDxwCet6Mr4iiZQeDdWvi8CzuF + hex!["4c64868ba6d8ace235d3efb4c10d745a67cf3bdfeae23b264d7ea2f3439dec42"] + .unchecked_into(), + //5D8C3HHEp5E8fJsXRD56494F413CdRSR9QKGXe7v5ZEfymdj + hex!["2ee4d78f328db178c54f205ac809da12e291a33bcbd4f29f081ce7e74bdc5044"] + .unchecked_into(), + //5GxeTYCGmp1C3ZRLDkRWqJc6gB2GYmuqnygweuH3vsivMQq6 + hex!["d88e40e3c2c7a7c5abf96ffdd8f7b7bec8798cc277bc97e255881871ab73b529"] + .unchecked_into(), + //5DoGpsgSLcJsHa9B8V4PKjxegWAqDZttWfxicAd68prUX654 + hex!["4cb3863271b70daa38612acd5dae4f5afcb7c165fa277629e5150d2214df322a"] + .unchecked_into(), + //5G1KLjqFyMsPAodnjSRkwRFJztTTEzmZWxow2Q3ZSRCPdthM + hex!["03be5ec86d10a94db89c9b7a396d3c7742e3bec5f85159d4cf308cef505966ddf5"] + .unchecked_into(), + ), + ]; + + const ENDOWMENT: u128 = 1_000_000 * WND; + const STASH: u128 = 100 * WND; + + westend::RuntimeGenesisConfig { + system: westend::SystemConfig { code: wasm_binary.to_vec(), ..Default::default() }, + balances: westend::BalancesConfig { + balances: endowed_accounts + .iter() + .map(|k: &AccountId| (k.clone(), ENDOWMENT)) + .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) + .collect(), + }, + beefy: Default::default(), + indices: westend::IndicesConfig { indices: vec![] }, + session: westend::SessionConfig { + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + westend_session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + x.8.clone(), + ), + ) + }) + .collect::>(), + }, + staking: westend::StakingConfig { + validator_count: 50, + minimum_validator_count: 4, + stakers: initial_authorities + .iter() + .map(|x| (x.0.clone(), x.0.clone(), STASH, westend::StakerStatus::Validator)) + .collect(), + invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), + force_era: Forcing::ForceNone, + slash_reward_fraction: Perbill::from_percent(10), + ..Default::default() + }, + babe: westend::BabeConfig { + authorities: Default::default(), + epoch_config: Some(westend::BABE_GENESIS_EPOCH_CONFIG), + ..Default::default() + }, + grandpa: Default::default(), + im_online: Default::default(), + authority_discovery: westend::AuthorityDiscoveryConfig { + keys: vec![], + ..Default::default() + }, + vesting: westend::VestingConfig { vesting: vec![] }, + sudo: westend::SudoConfig { key: Some(endowed_accounts[0].clone()) }, + hrmp: Default::default(), + configuration: westend::ConfigurationConfig { + config: default_parachains_host_configuration(), + }, + paras: Default::default(), + registrar: westend_runtime::RegistrarConfig { + next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID, + ..Default::default() + }, + xcm_pallet: Default::default(), + nomination_pools: Default::default(), + assigned_slots: Default::default(), + } +} + +#[cfg(feature = "kusama-native")] +fn kusama_staging_testnet_config_genesis(wasm_binary: &[u8]) -> kusama::RuntimeGenesisConfig { + use hex_literal::hex; + use sp_core::crypto::UncheckedInto; + + // Following keys are used in genesis config for development chains. + // DO NOT use them in production chains as the secret seed is public. + // + // SECRET_SEED="explain impose opinion genius bar parrot erupt panther surround best expire + // album" subkey inspect -n kusama "$SECRET_SEED" + let endowed_accounts = vec![ + // FLN5cfhF7VCGJYefjPQJR2V6WwbfRmb9ozTwLAzBNeQQG6y + hex!["7a0fe424217ed176da7abf12e08198db0d0949298e1372c80a1930cb6dc21d3e"].into(), + ]; + + // SECRET=$SECRET_SEED ./scripts/prepare-test-net.sh 4 + let initial_authorities: Vec<( + AccountId, + AccountId, + BabeId, + GrandpaId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + BeefyId, + )> = vec![ + ( + //5D5EsvSJf3KR3WHeZNG8rETdW6homig1cGHezspFt1P4o7sL + hex!["2ca4a9582244a3356a0d96e59d71f7e4d12aa88bca6d46f360ef11f6487cab1f"].into(), + //5Ev6RixvmK62UQE2PW19MPdLsYT4Nomwj85HKPdbnRECbDYh + hex!["7e237806f642b7f45f70ec45fbc41034516c8e5561bae2a62cd287129e1d0712"].into(), + //5GbjzK1uYVo6v1SaYhTeK3dbYy2GN9X4K5iwRkHEQ9eLS3We + hex!["c89cb7afc47ec0b5aac5824e5338a62959c92978167d3f841491836746e70b3d"] + .unchecked_into(), + //5GFz3YFW8QzEUsWhRjJzvDP7e5X5tPf5U12vUw32R8oJVgqb + hex!["b98b200021a608148f9817aeb553596b6968a5aa61b6d320c522f520ecc9cf9c"] + .unchecked_into(), + //5GzaFD8YsqnP5FYe5ijA9M4LQvzU9TPJmnBGdpuoqEvR1gQC + hex!["da0690438c0dd7a9aa26e03c9f1deaa58ba2b88d0bec0954b06478632164a401"] + .unchecked_into(), + //5CkZPtNy61PtbJpLqnjNFmbi1qukGkFdqFr5GKduSEthJ1cd + hex!["1e6554d35f6f17a37176c71801426204d6df400a1869114e4f00564b35d31150"] + .unchecked_into(), + //5CodnwweaYA1zB4QhdP4YVYFWnuZHY6W7zkN1NCRqJ9wZhap + hex!["20bddf09b1d0a2d93bafeb87fe19eb5bd59950c174f23a141a6d99736a5e700d"] + .unchecked_into(), + //5E7TSvNAP6QeJNeckdvYvADpHsx7v6aHXtGoQv5R2N1V3hEB + hex!["5a91b2546f1aac1c388eb0739c83e42d9972884d74360200ce32b7595bc65a04"] + .unchecked_into(), + //5GsoKeoM2HmjXPsdCua4oPu3Ms1Jgu4HbSnB81Lisa2tBFZp + hex!["02fd1e7e8455ab888ad054bbec7bc19409e6b1a5bb0300feefc6b58e60efae7e85"] + .unchecked_into(), + ), + ( + //5HMtKQuL2GQ7YvLBTh3vqFJEpkZW19sQh2X2mcUzAwBAe885 + hex!["ea478deab0ebfbeab7342febc236a9f1af5129ca0083fa25e6b0cf6a998d8354"].into(), + //5EFD5pLC3w5NFEcmQ6rGw9dUZ6fTSjWJemsvJZuaj7Qmq2WT + hex!["607b4e88129804eca8cd6fa26cbe2dd36667130e2a061050b08d9015871f4263"].into(), + //5DFztsnvC9hN85j5AP116atcnzFhAxnbzPodEp1AsYq1LYXu + hex!["34d949c39fae5801ba328ac6d0ddc76e469b7d5a4372a4a0d94f6aad6f9c1600"] + .unchecked_into(), + //5EZJNJ4j1eEEwCWusg7nYsZxTYBwoTH2drszxRqgMBTgNxMW + hex!["6e47830dcfc1f2b53a1b5db3f76702fc2760c1cc119119aceb00a57ec6658465"] + .unchecked_into(), + //5Dts3SrgDQMY9XCzKeQrxYSTh5MphPek994qkDCDk5c4neeF + hex!["50f6ef6326cd61ac500f167493e435f1204ce1d66ad18024bc5810d09673785e"] + .unchecked_into(), + //5DMKT99825TvA8F1yCQvE1ZcKTqg8T8Ad1KEjN6EuVpz4E6w + hex!["38e7fb2f6a1dcec73d93b07a0dc7cff1f9a9cc32cde8eb1e6ea1782f5316b431"] + .unchecked_into(), + //5EestuSehdMsWsBZ1hXCVo5YQiYiTPJwtV281x5fjUVtaqtP + hex!["72889a7b6ada28c3bd05a5a7298437f01d6d3270559768d16275efaf11864c0a"] + .unchecked_into(), + //5FNd5EabUbcReXEPwY9aASJMwSqyiic9w1Qt23YxNXj3dzbi + hex!["925f03f6211c68377987b0f78cd02aa882ad1fa9cc00c01fe6ce68e14c23340d"] + .unchecked_into(), + //5DxhuqfovpooTn8yH7WJGFjYw3pQxSEN9y9kvYUiGguHAj9D + hex!["030e77039e470ccdec7fe23dbc41c66f1c187ec8345e8919d3dc1250d975c3ce82"] + .unchecked_into(), + ), + ( + //5DAiYTKQ5KxwLncfNoTAH58dXBk2oDcQxtAXyDwMdKGLpGeY + hex!["30d203d942c1d056245b51e466a50b684f172a37c1cdde678f5346a0b3dbcd52"].into(), + //5Dq778qqNiAsjdF4qLVdkSBR8SftJKU35nyeBnkztRgniVhV + hex!["4e194bbafeec45647b2679e6b615b2a879d2e74fe706921930509ab3c9dbb22d"].into(), + //5E6iENoE1tXJUd7PkopQ8uqejg6xhPpqAnsVjS3hAQHWK1tm + hex!["5a0037b6bfc5e879ba5ef480ac29c59a12873854159686899082f41950ffd472"] + .unchecked_into(), + //5F8Dtgoc5dCaLAGYtaDqQUDg91fPQUynd497Fvhor8SYMdXp + hex!["87638aef8ab75db093150a6677c0919292ff66fc17f9f006a71fd0618415e164"] + .unchecked_into(), + //5EKsYx6Wj1Qg7LLc12U2YRjRUFmHa4Q3rNSoGZaP1ofS54km + hex!["6409c85a1125fa456b9dc6e85408a6d931aa8e04f48511c87fc147d1c103e902"] + .unchecked_into(), + //5H3UQy1NhCUUq3getmSEG8R1capY7Uy8JtKJz68UABmD9UxS + hex!["dc3cab0f94fa974cba826984f23dd4dc77ade20f25d935af5f07b85518da8044"] + .unchecked_into(), + //5DstCjokShCt9NppNnAcjg2nS4M5PKY3etn2BoFkZzMhQJ3w + hex!["50379866eb62e5c8aac31133efc4a1723e964a8e30c93c3ce2e7758bd03eb776"] + .unchecked_into(), + //5E4SCbSqUWKC4NVRCkMkJEnXCaVRiNQbSHL4upRB1ffd1Mk1 + hex!["5843c339c39d2c308bfb1841cd10beecfa157580492db05b66db8553e8d6512c"] + .unchecked_into(), + //5HNoMQ1PL3m7eBhp24FZxZUBtz4eh3AiwWq8i8jXLCRpJHsu + hex!["03c81d4e72cbdb96a7e6aad76830ae783b0b4650dc19703dde96866d8894dc921f"] + .unchecked_into(), + ), + ( + //5FNnjg8hXcPVLKASA69bPbooatacxcWNqkQAyXZfFiXi7T8r + hex!["927f8b12a0fa7185077353d9f6b4fe6bc6cd9682bd498642fa3801280909711a"].into(), + //5GipjBdL3rbex9qyxMinZpJYQbobbwk1ctbZp6B2mh3H25c6 + hex!["ce03638cd1e8496793b0540ba23370034511ea5d08837deb17f6c4d905b8d017"].into(), + //5GByn4uRpwmPe4i4MA4PjTQ8HXuycdue8HMWDhZ7vbU4WR9R + hex!["b67d3ed42ab1fcf3fcd7dee99bd6963bc22058ee22bcfddddb776492e85bd76e"] + .unchecked_into(), + //5GnZZ1rs7RE1jwPiyw1kts4JqaxnML5SdsWMuHV9TqCcuPWj + hex!["d0dd492b1a33d2f06a9aa7213e1aaa41d8820a6b56e95cd2462129b446574014"] + .unchecked_into(), + //5GKEKSAa3gbitHhvu5gm4f7q942azCVGDNhrw3hnsGPEMzyg + hex!["bc04e9764e23330b9f4e6922aa6437f87f3dd17b8590825e824724ae89d4ac51"] + .unchecked_into(), + //5H6QLnsfU7sAQ5ZACs9bPivsn9CXrqqwxhq4KKyoquZb5mVW + hex!["de78b26966c08357d66f7f56e7dcac7e4beb16aa0b74939290a42b3f5949bc36"] + .unchecked_into(), + //5FUUeYiAvFfXfB5yZLNkis2ZDy9T3CBLBPC6SwXFriGEjH5f + hex!["96d61fe92a50a79944ea93e3afc0a95a328773878e774cf8c8fbe8eba81cd95c"] + .unchecked_into(), + //5DLkWtgJahWG99cMcQxtftW9W14oduySyQi6hdhav7w3BiKq + hex!["38791c68ee472b94105c66cf150387979c49175062a687d1a1509119cfdc9e0c"] + .unchecked_into(), + //5Cjm1c3Jwt5jp6AaN2XfnncgZcswAmyfJn1buHEUaPauXAKK + hex!["025185a88886008267d27797fc74e34241e3aa8da767fafc9dd3ae5a59546802bb"] + .unchecked_into(), + ), + ]; + + const ENDOWMENT: u128 = 1_000_000 * KSM; + const STASH: u128 = 100 * KSM; + + kusama::RuntimeGenesisConfig { + system: kusama::SystemConfig { code: wasm_binary.to_vec(), ..Default::default() }, + balances: kusama::BalancesConfig { + balances: endowed_accounts + .iter() + .map(|k: &AccountId| (k.clone(), ENDOWMENT)) + .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) + .collect(), + }, + beefy: Default::default(), + indices: kusama::IndicesConfig { indices: vec![] }, + session: kusama::SessionConfig { + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + kusama_session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + x.8.clone(), + ), + ) + }) + .collect::>(), + }, + staking: kusama::StakingConfig { + validator_count: 50, + minimum_validator_count: 4, + stakers: initial_authorities + .iter() + .map(|x| (x.0.clone(), x.0.clone(), STASH, kusama::StakerStatus::Validator)) + .collect(), + invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), + force_era: Forcing::ForceNone, + slash_reward_fraction: Perbill::from_percent(10), + ..Default::default() + }, + babe: kusama::BabeConfig { + authorities: Default::default(), + epoch_config: Some(kusama::BABE_GENESIS_EPOCH_CONFIG), + ..Default::default() + }, + grandpa: Default::default(), + im_online: Default::default(), + authority_discovery: kusama::AuthorityDiscoveryConfig { + keys: vec![], + ..Default::default() + }, + claims: kusama::ClaimsConfig { claims: vec![], vesting: vec![] }, + vesting: kusama::VestingConfig { vesting: vec![] }, + treasury: Default::default(), + hrmp: Default::default(), + configuration: kusama::ConfigurationConfig { + config: default_parachains_host_configuration(), + }, + paras: Default::default(), + xcm_pallet: Default::default(), + nomination_pools: Default::default(), + nis_counterpart_balances: Default::default(), + } +} + +#[cfg(feature = "rococo-native")] +fn rococo_staging_testnet_config_genesis( + wasm_binary: &[u8], +) -> rococo_runtime::RuntimeGenesisConfig { + use hex_literal::hex; + use sp_core::crypto::UncheckedInto; + + // subkey inspect "$SECRET" + let endowed_accounts = vec![ + // 5DwBmEFPXRESyEam5SsQF1zbWSCn2kCjyLW51hJHXe9vW4xs + hex!["52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649"].into(), + ]; + + // ./scripts/prepare-test-net.sh 8 + let initial_authorities: Vec<( + AccountId, + AccountId, + BabeId, + GrandpaId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + BeefyId, + )> = vec![ + ( + //5EHZkbp22djdbuMFH9qt1DVzSCvqi3zWpj6DAYfANa828oei + hex!["62475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a"].into(), + //5FeSEpi9UYYaWwXXb3tV88qtZkmSdB3mvgj3pXkxKyYLGhcd + hex!["9e6e781a76810fe93187af44c79272c290c2b9e2b8b92ee11466cd79d8023f50"].into(), + //5Fh6rDpMDhM363o1Z3Y9twtaCPfizGQWCi55BSykTQjGbP7H + hex!["a076ef1280d768051f21d060623da3ab5b56944d681d303ed2d4bf658c5bed35"] + .unchecked_into(), + //5CPd3zoV9Aaah4xWucuDivMHJ2nEEmpdi864nPTiyRZp4t87 + hex!["0e6d7d1afbcc6547b92995a394ba0daed07a2420be08220a5a1336c6731f0bfa"] + .unchecked_into(), + //5F7BEa1LGFksUihyatf3dCDYneB8pWzVyavnByCsm5nBgezi + hex!["86975a37211f8704e947a365b720f7a3e2757988eaa7d0f197e83dba355ef743"] + .unchecked_into(), + //5CP6oGfwqbEfML8efqm1tCZsUgRsJztp9L8ZkEUxA16W8PPz + hex!["0e07a51d3213842f8e9363ce8e444255990a225f87e80a3d651db7841e1a0205"] + .unchecked_into(), + //5HQdwiDh8Qtd5dSNWajNYpwDvoyNWWA16Y43aEkCNactFc2b + hex!["ec60e71fe4a567ef9fef99d4bbf37ffae70564b41aa6f94ef0317c13e0a5477b"] + .unchecked_into(), + //5HbSgM72xVuscsopsdeG3sCSCYdAeM1Tay9p79N6ky6vwDGq + hex!["f49eae66a0ac9f610316906ec8f1a0928e20d7059d76a5ca53cbcb5a9b50dd3c"] + .unchecked_into(), + //5DPSWdgw38Spu315r6LSvYCggeeieBAJtP5A1qzuzKhqmjVu + hex!["034f68c5661a41930c82f26a662276bf89f33467e1c850f2fb8ef687fe43d62276"] + .unchecked_into(), + ), + ( + //5DvH8oEjQPYhzCoQVo7WDU91qmQfLZvxe9wJcrojmJKebCmG + hex!["520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a"].into(), + //5ENZvCRzyXJJYup8bM6yEzb2kQHEb1NDpY2ZEyVGBkCfRdj3 + hex!["6618289af7ae8621981ffab34591e7a6486e12745dfa3fd3b0f7e6a3994c7b5b"].into(), + //5DLjSUfqZVNAADbwYLgRvHvdzXypiV1DAEaDMjcESKTcqMoM + hex!["38757d0de00a0c739e7d7984ef4bc01161bd61e198b7c01b618425c16bb5bd5f"] + .unchecked_into(), + //5HnDVBN9mD6mXyx8oryhDbJtezwNSj1VRXgLoYCBA6uEkiao + hex!["fcd5f87a6fd5707a25122a01b4dac0a8482259df7d42a9a096606df1320df08d"] + .unchecked_into(), + //5DhyXZiuB1LvqYKFgT5tRpgGsN3is2cM9QxgW7FikvakbAZP + hex!["48a910c0af90898f11bd57d37ceaea53c78994f8e1833a7ade483c9a84bde055"] + .unchecked_into(), + //5EPEWRecy2ApL5n18n3aHyU1956zXTRqaJpzDa9DoqiggNwF + hex!["669a10892119453e9feb4e3f1ee8e028916cc3240022920ad643846fbdbee816"] + .unchecked_into(), + //5ES3fw5X4bndSgLNmtPfSbM2J1kLqApVB2CCLS4CBpM1UxUZ + hex!["68bf52c482630a8d1511f2edd14f34127a7d7082219cccf7fd4c6ecdb535f80d"] + .unchecked_into(), + //5HeXbwb5PxtcRoopPZTp5CQun38atn2UudQ8p2AxR5BzoaXw + hex!["f6f8fe475130d21165446a02fb1dbce3a7bf36412e5d98f4f0473aed9252f349"] + .unchecked_into(), + //5F7nTtN8MyJV4UsXpjg7tHSnfANXZ5KRPJmkASc1ZSH2Xoa5 + hex!["03a90c2bb6d3b7000020f6152fe2e5002fa970fd1f42aafb6c8edda8dacc2ea77e"] + .unchecked_into(), + ), + ( + //5FPMzsezo1PRxYbVpJMWK7HNbR2kUxidsAAxH4BosHa4wd6S + hex!["92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f"].into(), + //5G6NQidFG7YiXsvV7hQTLGArir9tsYqD4JDxByhgxKvSKwRx + hex!["b235f57244230589523271c27b8a490922ffd7dccc83b044feaf22273c1dc735"].into(), + //5GpZhzAVg7SAtzLvaAC777pjquPEcNy1FbNUAG2nZvhmd6eY + hex!["d2644c1ab2c63a3ad8d40ad70d4b260969e3abfe6d7e6665f50dc9f6365c9d2a"] + .unchecked_into(), + //5HAes2RQYPbYKbLBfKb88f4zoXv6pPA6Ke8CjN7dob3GpmSP + hex!["e1b68fbd84333e31486c08e6153d9a1415b2e7e71b413702b7d64e9b631184a1"] + .unchecked_into(), + //5HTXBf36LXmkFWJLokNUK6fPxVpkr2ToUnB1pvaagdGu4c1T + hex!["ee93e26259decb89afcf17ef2aa0fa2db2e1042fb8f56ecfb24d19eae8629878"] + .unchecked_into(), + //5FtAGDZYJKXkhVhAxCQrXmaP7EE2mGbBMfmKDHjfYDgq2BiU + hex!["a8e61ffacafaf546283dc92d14d7cc70ea0151a5dd81fdf73ff5a2951f2b6037"] + .unchecked_into(), + //5CtK7JHv3h6UQZ44y54skxdwSVBRtuxwPE1FYm7UZVhg8rJV + hex!["244f3421b310c68646e99cdbf4963e02067601f57756b072a4b19431448c186e"] + .unchecked_into(), + //5D4r6YaB6F7A7nvMRHNFNF6zrR9g39bqDJFenrcaFmTCRwfa + hex!["2c57f81fd311c1ab53813c6817fe67f8947f8d39258252663b3384ab4195494d"] + .unchecked_into(), + //5EPoHj8uV4fFKQHYThc6Z9fDkU7B6ih2ncVzQuDdNFb8UyhF + hex!["039d065fe4f9234f0a4f13cc3ae585f2691e9c25afa469618abb6645111f607a53"] + .unchecked_into(), + ), + ( + //5DMNx7RoX6d7JQ38NEM7DWRcW2THu92LBYZEWvBRhJeqcWgR + hex!["38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404"].into(), + //5GGdKNDr9P47dpVnmtq3m8Tvowwf1ot1abw6tPsTYYFoKm2v + hex!["ba0898c1964196474c0be08d364cdf4e9e1d47088287f5235f70b0590dfe1704"].into(), + //5EjkyPCzR2SjhDZq8f7ufsw6TfkvgNRepjCRQFc4TcdXdaB1 + hex!["764186bc30fd5a02477f19948dc723d6d57ab174debd4f80ed6038ec960bfe21"] + .unchecked_into(), + //5DJV3zCBTJBLGNDCcdWrYxWDacSz84goGTa4pFeKVvehEBte + hex!["36be9069cdb4a8a07ecd51f257875150f0a8a1be44a10d9d98dabf10a030aef4"] + .unchecked_into(), + //5FHf8kpK4fPjEJeYcYon2gAPwEBubRvtwpzkUbhMWSweKPUY + hex!["8e95b9b5b4dc69790b67b566567ca8bf8cdef3a3a8bb65393c0d1d1c87cd2d2c"] + .unchecked_into(), + //5F9FsRjpecP9GonktmtFL3kjqNAMKjHVFjyjRdTPa4hbQRZA + hex!["882d72965e642677583b333b2d173ac94b5fd6c405c76184bb14293be748a13b"] + .unchecked_into(), + //5F1FZWZSj3JyTLs8sRBxU6QWyGLSL9BMRtmSKDmVEoiKFxSP + hex!["821271c99c958b9220f1771d9f5e29af969edfa865631dba31e1ab7bc0582b75"] + .unchecked_into(), + //5CtgRR74VypK4h154s369abs78hDUxZSJqcbWsfXvsjcHJNA + hex!["2496f28d887d84705c6dae98aee8bf90fc5ad10bb5545eca1de6b68425b70f7c"] + .unchecked_into(), + //5CPx6dsr11SCJHKFkcAQ9jpparS7FwXQBrrMznRo4Hqv1PXz + hex!["0307d29bbf6a5c4061c2157b44fda33b7bb4ec52a5a0305668c74688cedf288d58"] + .unchecked_into(), + ), + ( + //5C8AL1Zb4bVazgT3EgDxFgcow1L4SJjVu44XcLC9CrYqFN4N + hex!["02a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16"].into(), + //5FLYy3YKsAnooqE4hCudttAsoGKbVG3hYYBtVzwMjJQrevPa + hex!["90cab33f0bb501727faa8319f0845faef7d31008f178b65054b6629fe531b772"].into(), + //5Et3tfbVf1ByFThNAuUq5pBssdaPPskip5yob5GNyUFojXC7 + hex!["7c94715e5dd8ab54221b1b6b2bfa5666f593f28a92a18e28052531de1bd80813"] + .unchecked_into(), + //5EX1JBghGbQqWohTPU6msR9qZ2nYPhK9r3RTQ2oD1K8TCxaG + hex!["6c878e33b83c20324238d22240f735457b6fba544b383e70bb62a27b57380c81"] + .unchecked_into(), + //5GqL8RbVAuNXpDhjQi1KrS1MyNuKhvus2AbmQwRGjpuGZmFu + hex!["d2f9d537ffa59919a4028afdb627c14c14c97a1547e13e8e82203d2049b15b1a"] + .unchecked_into(), + //5EUNaBpX9mJgcmLQHyG5Pkms6tbDiKuLbeTEJS924Js9cA1N + hex!["6a8570b9c6408e54bacf123cc2bb1b0f087f9c149147d0005badba63a5a4ac01"] + .unchecked_into(), + //5CaZuueRVpMATZG4hkcrgDoF4WGixuz7zu83jeBdY3bgWGaG + hex!["16c69ea8d595e80b6736f44be1eaeeef2ac9c04a803cc4fd944364cb0d617a33"] + .unchecked_into(), + //5DABsdQCDUGuhzVGWe5xXzYQ9rtrVxRygW7RXf9Tsjsw1aGJ + hex!["306ac5c772fe858942f92b6e28bd82fb7dd8cdd25f9a4626c1b0eee075fcb531"] + .unchecked_into(), + //5H91T5mHhoCw9JJG4NjghDdQyhC6L7XcSuBWKD3q3TAhEVvQ + hex!["02fb0330356e63a35dd930bc74525edf28b3bf5eb44aab9e9e4962c8309aaba6a6"] + .unchecked_into(), + ), + ( + //5C8XbDXdMNKJrZSrQURwVCxdNdk8AzG6xgLggbzuA399bBBF + hex!["02ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864"].into(), + //5GsyzFP8qtF8tXPSsjhjxAeU1v7D1PZofuQKN9TdCc7Dp1JM + hex!["d4ffc4c05b47d1115ad200f7f86e307b20b46c50e1b72a912ec4f6f7db46b616"].into(), + //5GHWB8ZDzegLcMW7Gdd1BS6WHVwDdStfkkE4G7KjPjZNJBtD + hex!["bab3cccdcc34401e9b3971b96a662686cf755aa869a5c4b762199ce531b12c5b"] + .unchecked_into(), + //5GzDPGbUM9uH52ZEwydasTj8edokGUJ7vEpoFWp9FE1YNuFB + hex!["d9c056c98ca0e6b4eb7f5c58c007c1db7be0fe1f3776108f797dd4990d1ccc33"] + .unchecked_into(), + //5GWZbVkJEfWZ7fRca39YAQeqri2Z7pkeHyd7rUctUHyQifLp + hex!["c4a980da30939d5bb9e4a734d12bf81259ae286aa21fa4b65405347fa40eff35"] + .unchecked_into(), + //5CmLCFeSurRXXtwMmLcVo7sdJ9EqDguvJbuCYDcHkr3cpqyE + hex!["1efc23c0b51ad609ab670ecf45807e31acbd8e7e5cb7c07cf49ee42992d2867c"] + .unchecked_into(), + //5DnsSy8a8pfE2aFjKBDtKw7WM1V4nfE5sLzP15MNTka53GqS + hex!["4c64d3f06d28adeb36a892fdaccecace150bec891f04694448a60b74fa469c22"] + .unchecked_into(), + //5CZdFnyzZvKetZTeUwj5APAYskVJe4QFiTezo5dQNsrnehGd + hex!["160ea09c5717270e958a3da42673fa011613a9539b2e4ebcad8626bc117ca04a"] + .unchecked_into(), + //5HgoR9JJkdBusxKrrs3zgd3ToppgNoGj1rDyAJp4e7eZiYyT + hex!["020019a8bb188f8145d02fa855e9c36e9914457d37c500e03634b5223aa5702474"] + .unchecked_into(), + ), + ( + //5HinEonzr8MywkqedcpsmwpxKje2jqr9miEwuzyFXEBCvVXM + hex!["fa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00"].into(), + //5EHJbj6Td6ks5HDnyfN4ttTSi57osxcQsQexm7XpazdeqtV7 + hex!["62145d721967bd88622d08625f0f5681463c0f1b8bcd97eb3c2c53f7660fd513"].into(), + //5EeCsC58XgJ1DFaoYA1WktEpP27jvwGpKdxPMFjicpLeYu96 + hex!["720537e2c1c554654d73b3889c3ef4c3c2f95a65dd3f7c185ebe4afebed78372"] + .unchecked_into(), + //5DnEySxbnppWEyN8cCLqvGjAorGdLRg2VmkY96dbJ1LHFK8N + hex!["4bea0b37e0cce9bddd80835fa2bfd5606f5dcfb8388bbb10b10c483f0856cf14"] + .unchecked_into(), + //5E1Y1FJ7dVP7qtE3wm241pTm72rTMcDT5Jd8Czv7Pwp7N3AH + hex!["560d90ca51e9c9481b8a9810060e04d0708d246714960439f804e5c6f40ca651"] + .unchecked_into(), + //5CAC278tFCHAeHYqE51FTWYxHmeLcENSS1RG77EFRTvPZMJT + hex!["042f07fc5268f13c026bbe199d63e6ac77a0c2a780f71cda05cee5a6f1b3f11f"] + .unchecked_into(), + //5HjRTLWcQjZzN3JDvaj1UzjNSayg5ZD9ZGWMstaL7Ab2jjAa + hex!["fab485e87ed1537d089df521edf983a777c57065a702d7ed2b6a2926f31da74f"] + .unchecked_into(), + //5ELv74v7QcsS6FdzvG4vL2NnYDGWmRnJUSMKYwdyJD7Xcdi7 + hex!["64d59feddb3d00316a55906953fb3db8985797472bd2e6c7ea1ab730cc339d7f"] + .unchecked_into(), + //5FaUcPt4fPz93vBhcrCJqmDkjYZ7jCbzAF56QJoCmvPaKrmx + hex!["033f1a6d47fe86f88934e4b83b9fae903b92b5dcf4fec97d5e3e8bf4f39df03685"] + .unchecked_into(), + ), + ( + //5Ey3NQ3dfabaDc16NUv7wRLsFCMDFJSqZFzKVycAsWuUC6Di + hex!["8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47"].into(), + //5HiWsuSBqt8nS9pnggexXuHageUifVPKPHDE2arTKqhTp1dV + hex!["fa0388fa88f3f0cb43d583e2571fbc0edad57dff3a6fd89775451dd2c2b8ea00"].into(), + //5H168nKX2Yrfo3bxj7rkcg25326Uv3CCCnKUGK6uHdKMdPt8 + hex!["da6b2df18f0f9001a6dcf1d301b92534fe9b1f3ccfa10c49449fee93adaa8349"] + .unchecked_into(), + //5DrA2fZdzmNqT5j6DXNwVxPBjDV9jhkAqvjt6Us3bQHKy3cF + hex!["4ee66173993dd0db5d628c4c9cb61a27b76611ad3c3925947f0d0011ee2c5dcc"] + .unchecked_into(), + //5FNFDUGNLUtqg5LgrwYLNmBiGoP8KRxsvQpBkc7GQP6qaBUG + hex!["92156f54a114ee191415898f2da013d9db6a5362d6b36330d5fc23e27360ab66"] + .unchecked_into(), + //5Gx6YeNhynqn8qkda9QKpc9S7oDr4sBrfAu516d3sPpEt26F + hex!["d822d4088b20dca29a580a577a97d6f024bb24c9550bebdfd7d2d18e946a1c7d"] + .unchecked_into(), + //5DhDcHqwxoes5s89AyudGMjtZXx1nEgrk5P45X88oSTR3iyx + hex!["481538f8c2c011a76d7d57db11c2789a5e83b0f9680dc6d26211d2f9c021ae4c"] + .unchecked_into(), + //5DqAvikdpfRdk5rR35ZobZhqaC5bJXZcEuvzGtexAZP1hU3T + hex!["4e262811acdfe94528bfc3c65036080426a0e1301b9ada8d687a70ffcae99c26"] + .unchecked_into(), + //5E41Znrr2YtZu8bZp3nvRuLVHg3jFksfQ3tXuviLku4wsao7 + hex!["025e84e95ed043e387ddb8668176b42f8e2773ddd84f7f58a6d9bf436a4b527986"] + .unchecked_into(), + ), + ]; + + const ENDOWMENT: u128 = 1_000_000 * ROC; + const STASH: u128 = 100 * ROC; + + rococo_runtime::RuntimeGenesisConfig { + system: rococo_runtime::SystemConfig { code: wasm_binary.to_vec(), ..Default::default() }, + balances: rococo_runtime::BalancesConfig { + balances: endowed_accounts + .iter() + .map(|k: &AccountId| (k.clone(), ENDOWMENT)) + .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) + .collect(), + }, + beefy: Default::default(), + indices: rococo_runtime::IndicesConfig { indices: vec![] }, + session: rococo_runtime::SessionConfig { + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + rococo_session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + x.8.clone(), + ), + ) + }) + .collect::>(), + }, + phragmen_election: Default::default(), + babe: rococo_runtime::BabeConfig { + authorities: Default::default(), + epoch_config: Some(rococo_runtime::BABE_GENESIS_EPOCH_CONFIG), + ..Default::default() + }, + grandpa: Default::default(), + im_online: Default::default(), + democracy: rococo_runtime::DemocracyConfig::default(), + council: rococo::CouncilConfig { members: vec![], phantom: Default::default() }, + technical_committee: rococo::TechnicalCommitteeConfig { + members: vec![], + phantom: Default::default(), + }, + technical_membership: Default::default(), + treasury: Default::default(), + authority_discovery: rococo_runtime::AuthorityDiscoveryConfig { + keys: vec![], + ..Default::default() + }, + claims: rococo::ClaimsConfig { claims: vec![], vesting: vec![] }, + vesting: rococo::VestingConfig { vesting: vec![] }, + sudo: rococo_runtime::SudoConfig { key: Some(endowed_accounts[0].clone()) }, + paras: rococo_runtime::ParasConfig { paras: vec![], ..Default::default() }, + hrmp: Default::default(), + configuration: rococo_runtime::ConfigurationConfig { + config: default_parachains_host_configuration(), + }, + registrar: rococo_runtime::RegistrarConfig { + next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID, + ..Default::default() + }, + xcm_pallet: Default::default(), + nis_counterpart_balances: Default::default(), + assigned_slots: Default::default(), + } +} + +/// Returns the properties for the [`PolkadotChainSpec`]. +pub fn polkadot_chain_spec_properties() -> serde_json::map::Map { + serde_json::json!({ + "tokenDecimals": 10, + }) + .as_object() + .expect("Map given; qed") + .clone() +} + +/// Staging testnet config. +#[cfg(feature = "kusama-native")] +pub fn kusama_staging_testnet_config() -> Result { + let wasm_binary = kusama::WASM_BINARY.ok_or("Kusama development wasm not available")?; + let boot_nodes = vec![]; + + Ok(KusamaChainSpec::from_genesis( + "Kusama Staging Testnet", + "kusama_staging_testnet", + ChainType::Live, + move || kusama_staging_testnet_config_genesis(wasm_binary), + boot_nodes, + Some( + TelemetryEndpoints::new(vec![(KUSAMA_STAGING_TELEMETRY_URL.to_string(), 0)]) + .expect("Kusama Staging telemetry url is valid; qed"), + ), + Some(DEFAULT_PROTOCOL_ID), + None, + None, + Default::default(), + )) +} + +/// Westend staging testnet config. +#[cfg(feature = "westend-native")] +pub fn westend_staging_testnet_config() -> Result { + let wasm_binary = westend::WASM_BINARY.ok_or("Westend development wasm not available")?; + let boot_nodes = vec![]; + + Ok(WestendChainSpec::from_genesis( + "Westend Staging Testnet", + "westend_staging_testnet", + ChainType::Live, + move || westend_staging_testnet_config_genesis(wasm_binary), + boot_nodes, + Some( + TelemetryEndpoints::new(vec![(WESTEND_STAGING_TELEMETRY_URL.to_string(), 0)]) + .expect("Westend Staging telemetry url is valid; qed"), + ), + Some(DEFAULT_PROTOCOL_ID), + None, + None, + Default::default(), + )) +} + +/// Rococo staging testnet config. +#[cfg(feature = "rococo-native")] +pub fn rococo_staging_testnet_config() -> Result { + let wasm_binary = rococo::WASM_BINARY.ok_or("Rococo development wasm not available")?; + let boot_nodes = vec![]; + + Ok(RococoChainSpec::from_genesis( + "Rococo Staging Testnet", + "rococo_staging_testnet", + ChainType::Live, + move || RococoGenesisExt { + runtime_genesis_config: rococo_staging_testnet_config_genesis(wasm_binary), + session_length_in_blocks: None, + }, + boot_nodes, + Some( + TelemetryEndpoints::new(vec![(ROCOCO_STAGING_TELEMETRY_URL.to_string(), 0)]) + .expect("Rococo Staging telemetry url is valid; qed"), + ), + Some(DEFAULT_PROTOCOL_ID), + None, + None, + Default::default(), + )) +} + +pub fn versi_chain_spec_properties() -> serde_json::map::Map { + serde_json::json!({ + "ss58Format": 42, + "tokenDecimals": 12, + "tokenSymbol": "VRS", + }) + .as_object() + .expect("Map given; qed") + .clone() +} + +/// Versi staging testnet config. +#[cfg(feature = "rococo-native")] +pub fn versi_staging_testnet_config() -> Result { + let wasm_binary = rococo::WASM_BINARY.ok_or("Versi development wasm not available")?; + let boot_nodes = vec![]; + + Ok(RococoChainSpec::from_genesis( + "Versi Staging Testnet", + "versi_staging_testnet", + ChainType::Live, + move || RococoGenesisExt { + runtime_genesis_config: rococo_staging_testnet_config_genesis(wasm_binary), + session_length_in_blocks: Some(100), + }, + boot_nodes, + Some( + TelemetryEndpoints::new(vec![(VERSI_STAGING_TELEMETRY_URL.to_string(), 0)]) + .expect("Versi Staging telemetry url is valid; qed"), + ), + Some("versi"), + None, + Some(versi_chain_spec_properties()), + Default::default(), + )) +} + +/// Helper function to generate a crypto pair from seed +pub fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() +} + +/// 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, + BabeId, + GrandpaId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + BeefyId, +) { + let keys = get_authority_keys_from_seed_no_beefy(seed); + (keys.0, keys.1, keys.2, keys.3, keys.4, keys.5, keys.6, keys.7, get_from_seed::(seed)) +} + +/// Helper function to generate stash, controller and session key from seed +pub fn get_authority_keys_from_seed_no_beefy( + seed: &str, +) -> ( + AccountId, + AccountId, + BabeId, + GrandpaId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, +) { + ( + 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), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + ) +} + +#[cfg(any( + feature = "polkadot-native", + feature = "kusama-native", + feature = "westend-native", + feature = "rococo-native" +))] +fn testnet_accounts() -> Vec { + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), + ] +} + +/// Helper function to create polkadot `RuntimeGenesisConfig` for testing +#[cfg(feature = "polkadot-native")] +pub fn polkadot_testnet_genesis( + wasm_binary: &[u8], + initial_authorities: Vec<( + AccountId, + AccountId, + BabeId, + GrandpaId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + )>, + _root_key: AccountId, + endowed_accounts: Option>, +) -> polkadot::RuntimeGenesisConfig { + let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(testnet_accounts); + + const ENDOWMENT: u128 = 1_000_000 * DOT; + const STASH: u128 = 100 * DOT; + + polkadot::RuntimeGenesisConfig { + system: polkadot::SystemConfig { code: wasm_binary.to_vec(), ..Default::default() }, + indices: polkadot::IndicesConfig { indices: vec![] }, + balances: polkadot::BalancesConfig { + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), + }, + session: polkadot::SessionConfig { + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + polkadot_session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + ), + ) + }) + .collect::>(), + }, + staking: polkadot::StakingConfig { + minimum_validator_count: 1, + validator_count: initial_authorities.len() as u32, + stakers: initial_authorities + .iter() + .map(|x| (x.0.clone(), x.0.clone(), STASH, polkadot::StakerStatus::Validator)) + .collect(), + invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), + force_era: Forcing::NotForcing, + slash_reward_fraction: Perbill::from_percent(10), + ..Default::default() + }, + babe: polkadot::BabeConfig { + authorities: Default::default(), + epoch_config: Some(polkadot::BABE_GENESIS_EPOCH_CONFIG), + ..Default::default() + }, + grandpa: Default::default(), + im_online: Default::default(), + authority_discovery: polkadot::AuthorityDiscoveryConfig { + keys: vec![], + ..Default::default() + }, + claims: polkadot::ClaimsConfig { claims: vec![], vesting: vec![] }, + vesting: polkadot::VestingConfig { vesting: vec![] }, + treasury: Default::default(), + hrmp: Default::default(), + configuration: polkadot::ConfigurationConfig { + config: default_parachains_host_configuration(), + }, + paras: Default::default(), + xcm_pallet: Default::default(), + nomination_pools: Default::default(), + } +} + +/// Helper function to create kusama `RuntimeGenesisConfig` for testing +#[cfg(feature = "kusama-native")] +pub fn kusama_testnet_genesis( + wasm_binary: &[u8], + initial_authorities: Vec<( + AccountId, + AccountId, + BabeId, + GrandpaId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + BeefyId, + )>, + _root_key: AccountId, + endowed_accounts: Option>, +) -> kusama::RuntimeGenesisConfig { + let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(testnet_accounts); + + const ENDOWMENT: u128 = 1_000_000 * KSM; + const STASH: u128 = 100 * KSM; + + kusama::RuntimeGenesisConfig { + system: kusama::SystemConfig { code: wasm_binary.to_vec(), ..Default::default() }, + indices: kusama::IndicesConfig { indices: vec![] }, + balances: kusama::BalancesConfig { + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), + }, + beefy: Default::default(), + session: kusama::SessionConfig { + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + kusama_session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + x.8.clone(), + ), + ) + }) + .collect::>(), + }, + staking: kusama::StakingConfig { + minimum_validator_count: 1, + validator_count: initial_authorities.len() as u32, + stakers: initial_authorities + .iter() + .map(|x| (x.0.clone(), x.0.clone(), STASH, kusama::StakerStatus::Validator)) + .collect(), + invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), + force_era: Forcing::NotForcing, + slash_reward_fraction: Perbill::from_percent(10), + ..Default::default() + }, + babe: kusama::BabeConfig { + authorities: Default::default(), + epoch_config: Some(kusama::BABE_GENESIS_EPOCH_CONFIG), + ..Default::default() + }, + grandpa: Default::default(), + im_online: Default::default(), + authority_discovery: kusama::AuthorityDiscoveryConfig { + keys: vec![], + ..Default::default() + }, + claims: kusama::ClaimsConfig { claims: vec![], vesting: vec![] }, + vesting: kusama::VestingConfig { vesting: vec![] }, + treasury: Default::default(), + hrmp: Default::default(), + configuration: kusama::ConfigurationConfig { + config: default_parachains_host_configuration(), + }, + paras: Default::default(), + xcm_pallet: Default::default(), + nomination_pools: Default::default(), + nis_counterpart_balances: Default::default(), + } +} + +/// Helper function to create westend `RuntimeGenesisConfig` for testing +#[cfg(feature = "westend-native")] +pub fn westend_testnet_genesis( + wasm_binary: &[u8], + initial_authorities: Vec<( + AccountId, + AccountId, + BabeId, + GrandpaId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + BeefyId, + )>, + root_key: AccountId, + endowed_accounts: Option>, +) -> westend::RuntimeGenesisConfig { + let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(testnet_accounts); + + const ENDOWMENT: u128 = 1_000_000 * WND; + const STASH: u128 = 100 * WND; + + westend::RuntimeGenesisConfig { + system: westend::SystemConfig { code: wasm_binary.to_vec(), ..Default::default() }, + indices: westend::IndicesConfig { indices: vec![] }, + balances: westend::BalancesConfig { + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), + }, + beefy: Default::default(), + session: westend::SessionConfig { + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + westend_session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + x.8.clone(), + ), + ) + }) + .collect::>(), + }, + staking: westend::StakingConfig { + minimum_validator_count: 1, + validator_count: initial_authorities.len() as u32, + stakers: initial_authorities + .iter() + .map(|x| (x.0.clone(), x.0.clone(), STASH, westend::StakerStatus::Validator)) + .collect(), + invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), + force_era: Forcing::NotForcing, + slash_reward_fraction: Perbill::from_percent(10), + ..Default::default() + }, + babe: westend::BabeConfig { + authorities: Default::default(), + epoch_config: Some(westend::BABE_GENESIS_EPOCH_CONFIG), + ..Default::default() + }, + grandpa: Default::default(), + im_online: Default::default(), + authority_discovery: westend::AuthorityDiscoveryConfig { + keys: vec![], + ..Default::default() + }, + vesting: westend::VestingConfig { vesting: vec![] }, + sudo: westend::SudoConfig { key: Some(root_key) }, + hrmp: Default::default(), + configuration: westend::ConfigurationConfig { + config: default_parachains_host_configuration(), + }, + paras: Default::default(), + registrar: westend_runtime::RegistrarConfig { + next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID, + ..Default::default() + }, + xcm_pallet: Default::default(), + nomination_pools: Default::default(), + assigned_slots: Default::default(), + } +} + +/// Helper function to create rococo `RuntimeGenesisConfig` for testing +#[cfg(feature = "rococo-native")] +pub fn rococo_testnet_genesis( + wasm_binary: &[u8], + initial_authorities: Vec<( + AccountId, + AccountId, + BabeId, + GrandpaId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + BeefyId, + )>, + root_key: AccountId, + endowed_accounts: Option>, +) -> rococo_runtime::RuntimeGenesisConfig { + let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(testnet_accounts); + + const ENDOWMENT: u128 = 1_000_000 * ROC; + + rococo_runtime::RuntimeGenesisConfig { + system: rococo_runtime::SystemConfig { code: wasm_binary.to_vec(), ..Default::default() }, + beefy: Default::default(), + indices: rococo_runtime::IndicesConfig { indices: vec![] }, + balances: rococo_runtime::BalancesConfig { + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), + }, + session: rococo_runtime::SessionConfig { + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + rococo_session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + x.8.clone(), + ), + ) + }) + .collect::>(), + }, + babe: rococo_runtime::BabeConfig { + authorities: Default::default(), + epoch_config: Some(rococo_runtime::BABE_GENESIS_EPOCH_CONFIG), + ..Default::default() + }, + grandpa: Default::default(), + im_online: Default::default(), + phragmen_election: Default::default(), + democracy: rococo::DemocracyConfig::default(), + council: rococo::CouncilConfig { members: vec![], phantom: Default::default() }, + technical_committee: rococo::TechnicalCommitteeConfig { + members: vec![], + phantom: Default::default(), + }, + technical_membership: Default::default(), + treasury: Default::default(), + claims: rococo::ClaimsConfig { claims: vec![], vesting: vec![] }, + vesting: rococo::VestingConfig { vesting: vec![] }, + authority_discovery: rococo_runtime::AuthorityDiscoveryConfig { + keys: vec![], + ..Default::default() + }, + sudo: rococo_runtime::SudoConfig { key: Some(root_key.clone()) }, + hrmp: Default::default(), + configuration: rococo_runtime::ConfigurationConfig { + config: polkadot_runtime_parachains::configuration::HostConfiguration { + max_validators_per_core: Some(1), + ..default_parachains_host_configuration() + }, + }, + paras: rococo_runtime::ParasConfig { paras: vec![], ..Default::default() }, + registrar: rococo_runtime::RegistrarConfig { + next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID, + ..Default::default() + }, + xcm_pallet: Default::default(), + nis_counterpart_balances: Default::default(), + assigned_slots: Default::default(), + } +} + +#[cfg(feature = "polkadot-native")] +fn polkadot_development_config_genesis(wasm_binary: &[u8]) -> polkadot::RuntimeGenesisConfig { + polkadot_testnet_genesis( + wasm_binary, + vec![get_authority_keys_from_seed_no_beefy("Alice")], + get_account_id_from_seed::("Alice"), + None, + ) +} + +#[cfg(feature = "kusama-native")] +fn kusama_development_config_genesis(wasm_binary: &[u8]) -> kusama::RuntimeGenesisConfig { + kusama_testnet_genesis( + wasm_binary, + vec![get_authority_keys_from_seed("Alice")], + get_account_id_from_seed::("Alice"), + None, + ) +} + +#[cfg(feature = "westend-native")] +fn westend_development_config_genesis(wasm_binary: &[u8]) -> westend::RuntimeGenesisConfig { + westend_testnet_genesis( + wasm_binary, + vec![get_authority_keys_from_seed("Alice")], + get_account_id_from_seed::("Alice"), + None, + ) +} + +#[cfg(feature = "rococo-native")] +fn rococo_development_config_genesis(wasm_binary: &[u8]) -> rococo_runtime::RuntimeGenesisConfig { + rococo_testnet_genesis( + wasm_binary, + vec![get_authority_keys_from_seed("Alice")], + get_account_id_from_seed::("Alice"), + None, + ) +} + +/// Polkadot development config (single validator Alice) +#[cfg(feature = "polkadot-native")] +pub fn polkadot_development_config() -> Result { + let wasm_binary = polkadot::WASM_BINARY.ok_or("Polkadot development wasm not available")?; + + Ok(PolkadotChainSpec::from_genesis( + "Development", + "polkadot_dev", + ChainType::Development, + move || polkadot_development_config_genesis(wasm_binary), + vec![], + None, + Some(DEFAULT_PROTOCOL_ID), + None, + Some(polkadot_chain_spec_properties()), + Default::default(), + )) +} + +/// Kusama development config (single validator Alice) +#[cfg(feature = "kusama-native")] +pub fn kusama_development_config() -> Result { + let wasm_binary = kusama::WASM_BINARY.ok_or("Kusama development wasm not available")?; + + Ok(KusamaChainSpec::from_genesis( + "Development", + "kusama_dev", + ChainType::Development, + move || kusama_development_config_genesis(wasm_binary), + vec![], + None, + Some(DEFAULT_PROTOCOL_ID), + None, + None, + Default::default(), + )) +} + +/// Westend development config (single validator Alice) +#[cfg(feature = "westend-native")] +pub fn westend_development_config() -> Result { + let wasm_binary = westend::WASM_BINARY.ok_or("Westend development wasm not available")?; + + Ok(WestendChainSpec::from_genesis( + "Development", + "westend_dev", + ChainType::Development, + move || westend_development_config_genesis(wasm_binary), + vec![], + None, + Some(DEFAULT_PROTOCOL_ID), + None, + None, + Default::default(), + )) +} + +/// Rococo development config (single validator Alice) +#[cfg(feature = "rococo-native")] +pub fn rococo_development_config() -> Result { + let wasm_binary = rococo::WASM_BINARY.ok_or("Rococo development wasm not available")?; + + Ok(RococoChainSpec::from_genesis( + "Development", + "rococo_dev", + ChainType::Development, + move || RococoGenesisExt { + runtime_genesis_config: rococo_development_config_genesis(wasm_binary), + // Use 1 minute session length. + session_length_in_blocks: Some(10), + }, + vec![], + None, + Some(DEFAULT_PROTOCOL_ID), + None, + None, + Default::default(), + )) +} + +/// `Versi` development config (single validator Alice) +#[cfg(feature = "rococo-native")] +pub fn versi_development_config() -> Result { + let wasm_binary = rococo::WASM_BINARY.ok_or("Versi development wasm not available")?; + + Ok(RococoChainSpec::from_genesis( + "Development", + "versi_dev", + ChainType::Development, + move || RococoGenesisExt { + runtime_genesis_config: rococo_development_config_genesis(wasm_binary), + // Use 1 minute session length. + session_length_in_blocks: Some(10), + }, + vec![], + None, + Some("versi"), + None, + None, + Default::default(), + )) +} + +/// Wococo development config (single validator Alice) +#[cfg(feature = "rococo-native")] +pub fn wococo_development_config() -> Result { + const WOCOCO_DEV_PROTOCOL_ID: &str = "woco"; + let wasm_binary = rococo::WASM_BINARY.ok_or("Wococo development wasm not available")?; + + Ok(RococoChainSpec::from_genesis( + "Development", + "wococo_dev", + ChainType::Development, + move || RococoGenesisExt { + runtime_genesis_config: rococo_development_config_genesis(wasm_binary), + // Use 1 minute session length. + session_length_in_blocks: Some(10), + }, + vec![], + None, + Some(WOCOCO_DEV_PROTOCOL_ID), + None, + None, + Default::default(), + )) +} + +#[cfg(feature = "polkadot-native")] +fn polkadot_local_testnet_genesis(wasm_binary: &[u8]) -> polkadot::RuntimeGenesisConfig { + polkadot_testnet_genesis( + wasm_binary, + vec![ + get_authority_keys_from_seed_no_beefy("Alice"), + get_authority_keys_from_seed_no_beefy("Bob"), + ], + get_account_id_from_seed::("Alice"), + None, + ) +} + +/// Polkadot local testnet config (multivalidator Alice + Bob) +#[cfg(feature = "polkadot-native")] +pub fn polkadot_local_testnet_config() -> Result { + let wasm_binary = polkadot::WASM_BINARY.ok_or("Polkadot development wasm not available")?; + + Ok(PolkadotChainSpec::from_genesis( + "Local Testnet", + "local_testnet", + ChainType::Local, + move || polkadot_local_testnet_genesis(wasm_binary), + vec![], + None, + Some(DEFAULT_PROTOCOL_ID), + None, + Some(polkadot_chain_spec_properties()), + Default::default(), + )) +} + +#[cfg(feature = "kusama-native")] +fn kusama_local_testnet_genesis(wasm_binary: &[u8]) -> kusama::RuntimeGenesisConfig { + kusama_testnet_genesis( + wasm_binary, + vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")], + get_account_id_from_seed::("Alice"), + None, + ) +} + +/// Kusama local testnet config (multivalidator Alice + Bob) +#[cfg(feature = "kusama-native")] +pub fn kusama_local_testnet_config() -> Result { + let wasm_binary = kusama::WASM_BINARY.ok_or("Kusama development wasm not available")?; + + Ok(KusamaChainSpec::from_genesis( + "Kusama Local Testnet", + "kusama_local_testnet", + ChainType::Local, + move || kusama_local_testnet_genesis(wasm_binary), + vec![], + None, + Some(DEFAULT_PROTOCOL_ID), + None, + None, + Default::default(), + )) +} + +#[cfg(feature = "westend-native")] +fn westend_local_testnet_genesis(wasm_binary: &[u8]) -> westend::RuntimeGenesisConfig { + westend_testnet_genesis( + wasm_binary, + vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")], + get_account_id_from_seed::("Alice"), + None, + ) +} + +/// Westend local testnet config (multivalidator Alice + Bob) +#[cfg(feature = "westend-native")] +pub fn westend_local_testnet_config() -> Result { + let wasm_binary = westend::WASM_BINARY.ok_or("Westend development wasm not available")?; + + Ok(WestendChainSpec::from_genesis( + "Westend Local Testnet", + "westend_local_testnet", + ChainType::Local, + move || westend_local_testnet_genesis(wasm_binary), + vec![], + None, + Some(DEFAULT_PROTOCOL_ID), + None, + None, + Default::default(), + )) +} + +#[cfg(feature = "rococo-native")] +fn rococo_local_testnet_genesis(wasm_binary: &[u8]) -> rococo_runtime::RuntimeGenesisConfig { + rococo_testnet_genesis( + wasm_binary, + vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")], + get_account_id_from_seed::("Alice"), + None, + ) +} + +/// Rococo local testnet config (multivalidator Alice + Bob) +#[cfg(feature = "rococo-native")] +pub fn rococo_local_testnet_config() -> Result { + let wasm_binary = rococo::WASM_BINARY.ok_or("Rococo development wasm not available")?; + + Ok(RococoChainSpec::from_genesis( + "Rococo Local Testnet", + "rococo_local_testnet", + ChainType::Local, + move || RococoGenesisExt { + runtime_genesis_config: rococo_local_testnet_genesis(wasm_binary), + // Use 1 minute session length. + session_length_in_blocks: Some(10), + }, + vec![], + None, + Some(DEFAULT_PROTOCOL_ID), + None, + None, + Default::default(), + )) +} + +/// Wococo is a temporary testnet that uses almost the same runtime as rococo. +#[cfg(feature = "rococo-native")] +fn wococo_local_testnet_genesis(wasm_binary: &[u8]) -> rococo_runtime::RuntimeGenesisConfig { + rococo_testnet_genesis( + wasm_binary, + vec![ + get_authority_keys_from_seed("Alice"), + get_authority_keys_from_seed("Bob"), + get_authority_keys_from_seed("Charlie"), + get_authority_keys_from_seed("Dave"), + ], + get_account_id_from_seed::("Alice"), + None, + ) +} + +/// Wococo local testnet config (multivalidator Alice + Bob + Charlie + Dave) +#[cfg(feature = "rococo-native")] +pub fn wococo_local_testnet_config() -> Result { + let wasm_binary = rococo::WASM_BINARY.ok_or("Wococo development wasm not available")?; + + Ok(RococoChainSpec::from_genesis( + "Wococo Local Testnet", + "wococo_local_testnet", + ChainType::Local, + move || RococoGenesisExt { + runtime_genesis_config: wococo_local_testnet_genesis(wasm_binary), + // Use 1 minute session length. + session_length_in_blocks: Some(10), + }, + vec![], + None, + Some(DEFAULT_PROTOCOL_ID), + None, + None, + Default::default(), + )) +} + +/// `Versi` is a temporary testnet that uses the same runtime as rococo. +#[cfg(feature = "rococo-native")] +fn versi_local_testnet_genesis(wasm_binary: &[u8]) -> rococo_runtime::RuntimeGenesisConfig { + rococo_testnet_genesis( + wasm_binary, + vec![ + get_authority_keys_from_seed("Alice"), + get_authority_keys_from_seed("Bob"), + get_authority_keys_from_seed("Charlie"), + get_authority_keys_from_seed("Dave"), + ], + get_account_id_from_seed::("Alice"), + None, + ) +} + +/// `Versi` local testnet config (multivalidator Alice + Bob + Charlie + Dave) +#[cfg(feature = "rococo-native")] +pub fn versi_local_testnet_config() -> Result { + let wasm_binary = rococo::WASM_BINARY.ok_or("Versi development wasm not available")?; + + Ok(RococoChainSpec::from_genesis( + "Versi Local Testnet", + "versi_local_testnet", + ChainType::Local, + move || RococoGenesisExt { + runtime_genesis_config: versi_local_testnet_genesis(wasm_binary), + // Use 1 minute session length. + session_length_in_blocks: Some(10), + }, + vec![], + None, + Some("versi"), + None, + None, + Default::default(), + )) +} diff --git a/polkadot/node/service/src/fake_runtime_api.rs b/polkadot/node/service/src/fake_runtime_api.rs new file mode 100644 index 0000000000000000000000000000000000000000..d9553afa024b49fe68153500f7d1a2e102052c6c --- /dev/null +++ b/polkadot/node/service/src/fake_runtime_api.rs @@ -0,0 +1,399 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Provides "fake" runtime API implementations +//! +//! These are used to provide a type that implements these runtime APIs without requiring to import +//! the native runtimes. + +use beefy_primitives::ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}; +use grandpa_primitives::AuthorityId as GrandpaId; +use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; +use polkadot_primitives::{ + runtime_api, slashing, AccountId, AuthorityDiscoveryId, Balance, Block, BlockNumber, + CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, + DisputeState, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, + InboundHrmpMessage, Nonce, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, + ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, + ValidatorId, ValidatorIndex, ValidatorSignature, +}; +use sp_core::OpaqueMetadata; +use sp_runtime::{ + traits::Block as BlockT, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, +}; +use sp_version::RuntimeVersion; +use sp_weights::Weight; +use std::collections::BTreeMap; + +sp_api::decl_runtime_apis! { + /// This runtime API is only implemented for the test runtime! + pub trait GetLastTimestamp { + /// Returns the last timestamp of a runtime. + fn get_last_timestamp() -> u64; + } +} + +struct Runtime; + +sp_api::impl_runtime_apis! { + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + unimplemented!() + } + + fn execute_block(_: Block) { + unimplemented!() + } + + fn initialize_block(_: &::Header) { + unimplemented!() + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + unimplemented!() + } + + fn metadata_at_version(_: u32) -> Option { + unimplemented!() + } + + fn metadata_versions() -> Vec { + unimplemented!() + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic(_: ::Extrinsic) -> ApplyExtrinsicResult { + unimplemented!() + } + + fn finalize_block() -> ::Header { + unimplemented!() + } + + fn inherent_extrinsics(_: sp_inherents::InherentData) -> Vec<::Extrinsic> { + unimplemented!() + } + + fn check_inherents( + _: Block, + _: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { + unimplemented!() + } + } + + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + _: TransactionSource, + _: ::Extrinsic, + _: ::Hash, + ) -> TransactionValidity { + unimplemented!() + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(_: &::Header) { + unimplemented!() + } + } + + impl runtime_api::ParachainHost for Runtime { + fn validators() -> Vec { + unimplemented!() + } + + fn validator_groups() -> (Vec>, GroupRotationInfo) { + unimplemented!() + } + + fn availability_cores() -> Vec> { + unimplemented!() + } + + fn persisted_validation_data(_: ParaId, _: OccupiedCoreAssumption) + -> Option> { + unimplemented!() + } + + fn assumed_validation_data( + _: ParaId, + _: Hash, + ) -> Option<(PersistedValidationData, ValidationCodeHash)> { + unimplemented!() + } + + fn check_validation_outputs( + _: ParaId, + _: CandidateCommitments, + ) -> bool { + unimplemented!() + } + + fn session_index_for_child() -> SessionIndex { + unimplemented!() + } + + fn validation_code(_: ParaId, _: OccupiedCoreAssumption) + -> Option { + unimplemented!() + } + + fn candidate_pending_availability(_: ParaId) -> Option> { + unimplemented!() + } + + fn candidate_events() -> Vec> { + unimplemented!() + } + + fn session_info(_: SessionIndex) -> Option { + unimplemented!() + } + + fn session_executor_params(_: SessionIndex) -> Option { + unimplemented!() + } + + fn dmq_contents(_: ParaId) -> Vec> { + unimplemented!() + } + + fn inbound_hrmp_channels_contents( + _: ParaId + ) -> BTreeMap>> { + unimplemented!() + } + + fn validation_code_by_hash(_: ValidationCodeHash) -> Option { + unimplemented!() + } + + fn on_chain_votes() -> Option> { + unimplemented!() + } + + fn submit_pvf_check_statement( + _: PvfCheckStatement, + _: ValidatorSignature, + ) { + unimplemented!() + } + + fn pvfs_require_precheck() -> Vec { + unimplemented!() + } + + fn validation_code_hash(_: ParaId, _: OccupiedCoreAssumption) + -> Option + { + unimplemented!() + } + + fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState)> { + unimplemented!() + } + + fn unapplied_slashes( + ) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> { + unimplemented!() + } + + fn key_ownership_proof( + _: ValidatorId, + ) -> Option { + unimplemented!() + } + + fn submit_report_dispute_lost( + _: slashing::DisputeProof, + _: slashing::OpaqueKeyOwnershipProof, + ) -> Option<()> { + unimplemented!() + } + } + + impl beefy_primitives::BeefyApi for Runtime { + fn beefy_genesis() -> Option { + unimplemented!() + } + + fn validator_set() -> Option> { + unimplemented!() + } + + fn submit_report_equivocation_unsigned_extrinsic( + _: beefy_primitives::EquivocationProof< + BlockNumber, + BeefyId, + BeefySignature, + >, + _: beefy_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + unimplemented!() + } + + fn generate_key_ownership_proof( + _: beefy_primitives::ValidatorSetId, + _: BeefyId, + ) -> Option { + unimplemented!() + } + } + + impl sp_mmr_primitives::MmrApi for Runtime { + fn mmr_root() -> Result { + unimplemented!() + } + + fn mmr_leaf_count() -> Result { + unimplemented!() + } + + fn generate_proof( + _: Vec, + _: Option, + ) -> Result<(Vec, sp_mmr_primitives::Proof), sp_mmr_primitives::Error> { + unimplemented!() + } + + fn verify_proof(_: Vec, _: sp_mmr_primitives::Proof) + -> Result<(), sp_mmr_primitives::Error> + { + unimplemented!() + } + + fn verify_proof_stateless( + _: Hash, + _: Vec, + _: sp_mmr_primitives::Proof + ) -> Result<(), sp_mmr_primitives::Error> { + unimplemented!() + } + } + + impl grandpa_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> Vec<(GrandpaId, u64)> { + unimplemented!() + } + + fn current_set_id() -> grandpa_primitives::SetId { + unimplemented!() + } + + fn submit_report_equivocation_unsigned_extrinsic( + _: grandpa_primitives::EquivocationProof< + ::Hash, + sp_runtime::traits::NumberFor, + >, + _: grandpa_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + unimplemented!() + } + + fn generate_key_ownership_proof( + _: grandpa_primitives::SetId, + _: grandpa_primitives::AuthorityId, + ) -> Option { + unimplemented!() + } + } + + impl sp_consensus_babe::BabeApi for Runtime { + fn configuration() -> sp_consensus_babe::BabeConfiguration { + unimplemented!() + } + + fn current_epoch_start() -> sp_consensus_babe::Slot { + unimplemented!() + } + + fn current_epoch() -> sp_consensus_babe::Epoch { + unimplemented!() + } + + fn next_epoch() -> sp_consensus_babe::Epoch { + unimplemented!() + } + + fn generate_key_ownership_proof( + _: sp_consensus_babe::Slot, + _: sp_consensus_babe::AuthorityId, + ) -> Option { + unimplemented!() + } + + fn submit_report_equivocation_unsigned_extrinsic( + _: sp_consensus_babe::EquivocationProof<::Header>, + _: sp_consensus_babe::OpaqueKeyOwnershipProof, + ) -> Option<()> { + unimplemented!() + } + } + + impl sp_authority_discovery::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + unimplemented!() + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(_: Option>) -> Vec { + unimplemented!() + } + + fn decode_session_keys( + _: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + unimplemented!() + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(_: AccountId) -> Nonce { + unimplemented!() + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< + Block, + Balance, + > for Runtime { + fn query_info(_: ::Extrinsic, _: u32) -> RuntimeDispatchInfo { + unimplemented!() + } + fn query_fee_details(_: ::Extrinsic, _: u32) -> FeeDetails { + unimplemented!() + } + fn query_weight_to_fee(_: Weight) -> Balance { + unimplemented!() + } + fn query_length_to_fee(_: u32) -> Balance { + unimplemented!() + } + } + + impl crate::fake_runtime_api::GetLastTimestamp for Runtime { + fn get_last_timestamp() -> u64 { + unimplemented!() + } + } +} diff --git a/polkadot/node/service/src/grandpa_support.rs b/polkadot/node/service/src/grandpa_support.rs new file mode 100644 index 0000000000000000000000000000000000000000..3a767d9783f0dfcff13166a39220ab161533ff72 --- /dev/null +++ b/polkadot/node/service/src/grandpa_support.rs @@ -0,0 +1,343 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot-specific GRANDPA integration utilities. + +use std::sync::Arc; + +use sp_runtime::traits::{Block as BlockT, Header as _, NumberFor}; + +use crate::HeaderProvider; + +#[cfg(feature = "full-node")] +use polkadot_primitives::{Block, Hash}; + +/// Returns the block hash of the block at the given `target_number` by walking +/// backwards from the given `current_header`. +pub(super) fn walk_backwards_to_target_block( + backend: &HP, + target_number: NumberFor, + current_header: &Block::Header, +) -> Result<(Block::Hash, NumberFor), sp_blockchain::Error> +where + Block: BlockT, + HP: HeaderProvider, +{ + let mut target_hash = current_header.hash(); + let mut target_header = current_header.clone(); + + 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 Ok((target_hash, target_number)) + } + + target_hash = *target_header.parent_hash(); + target_header = backend + .header(target_hash)? + .expect("Header known to exist due to the existence of one of its descendants; qed"); + } +} + +/// A custom GRANDPA voting rule that "pauses" voting (i.e. keeps voting for the +/// same last finalized block) after a given block at height `N` has been +/// finalized and for a delay of `M` blocks, i.e. until the best block reaches +/// `N` + `M`, the voter will keep voting for block `N`. +#[derive(Clone)] +pub(crate) struct PauseAfterBlockFor(pub(crate) N, pub(crate) N); + +impl grandpa::VotingRule for PauseAfterBlockFor> +where + Block: BlockT, + B: sp_blockchain::HeaderBackend + 'static, +{ + fn restrict_vote( + &self, + backend: Arc, + base: &Block::Header, + best_target: &Block::Header, + current_target: &Block::Header, + ) -> grandpa::VotingRuleResult { + let aux = || { + // only restrict votes targeting a block higher than the block + // we've set for the pause + if *current_target.number() > self.0 { + // if we're past the pause period (i.e. `self.0 + self.1`) + // then we no longer need to restrict any votes + if *best_target.number() > self.0 + self.1 { + return None + } + + // if we've finalized the pause block, just keep returning it + // until best number increases enough to pass the condition above + if *base.number() >= self.0 { + return Some((base.hash(), *base.number())) + } + + // otherwise find the target header at the pause block + // to vote on + return walk_backwards_to_target_block(&*backend, self.0, current_target).ok() + } + + None + }; + + let target = aux(); + + Box::pin(async move { target }) + } +} + +/// GRANDPA hard forks due to borked migration of session keys after a runtime +/// upgrade (at #1491596), the signaled authority set changes were invalid +/// (blank keys) and were impossible to finalize. The authorities for these +/// intermediary pending changes are replaced with a static list comprised of +/// w3f validators and randomly selected validators from the latest session (at +/// #1500988). +#[cfg(feature = "full-node")] +pub(crate) fn kusama_hard_forks() -> Vec> { + use sp_core::crypto::Ss58Codec; + use std::str::FromStr; + + let forks = vec![ + (623, "01e94e1e7e9cf07b3b0bf4e1717fce7448e5563901c2ef2e3b8e9ecaeba088b1", 1492283), + (624, "ddc4323c5e8966844dfaa87e0c2f74ef6b43115f17bf8e4ff38845a62d02b9a9", 1492436), + (625, "38ba115b296663e424e32d7b1655cd795719cef4fd7d579271a6d01086cf1628", 1492586), + (626, "f3172b6b8497c10fc772f5dada4eeb1f4c4919c97de9de2e1a439444d5a057ff", 1492955), + (627, "b26526aea299e9d24af29fdacd5cf4751a663d24894e3d0a37833aa14c58424a", 1493338), + (628, "3980d024327d53b8d01ef0d198a052cd058dd579508d8ed6283fe3614e0a3694", 1493913), + (629, "31f22997a786c25ee677786373368cae6fd501fd1bc4b212b8e267235c88179d", 1495083), + (630, "1c65eb250cf54b466c64f1a4003d1415a7ee275e49615450c0e0525179857eef", 1497404), + (631, "9e44116467cc9d7e224e36487bf2cf571698cae16b25f54a7430f1278331fdd8", 1498598), + ]; + + let authorities = vec![ + "CwjLJ1zPWK5Ao9WChAFp7rWGEgN3AyXXjTRPrqgm5WwBpoS", + "Dp8FHpZTzvoKXztkfrUAkF6xNf6sjVU5ZLZ29NEGUazouou", + "DtK7YfkhNWU6wEPF1dShsFdhtosVAuJPLkoGhKhG1r5LjKq", + "FLnHYBuoyThzqJ45tdb8P6yMLdocM7ir27Pg1AnpYoygm1K", + "FWEfJ5UMghr52UopgYjawAg6hQg3ztbQek75pfeRtLVi8pB", + "ECoLHAu7HKWGTB9od82HAtequYj6hvNHigkGSB9g3ApxAwB", + "GL1Tg3Uppo8GYL9NjKj4dWKcS6tW98REop9G5hpu7HgFwTa", + "ExnjU5LZMktrgtQBE3An6FsQfvaKG1ukxPqwhJydgdgarmY", + "CagLpgCBu5qJqYF2tpFX6BnU4yHvMGSjc7r3Ed1jY3tMbQt", + "DsrtmMsD4ijh3n4uodxPoiW9NZ7v7no5wVvPVj8fL1dfrWB", + "HQB4EctrVR68ozZDyBiRJzLRAEGh1YKgCkAsFjJcegL9RQA", + "H2YTYbXTFkDY1cGnv164ecnDT3hsD2bQXtyiDbcQuXcQZUV", + "H5WL8jXmbkCoEcLfvqJkbLUeGrDFsJiMXkhhRWn3joct1tE", + "DpB37GDrJDYcmg2df2eqsrPKMay1u8hyZ6sQi2FuUiUeNLu", + "FR8yjKRA9MTjvFGK8kfzrdC23Fr6xd7rfBvZXSjAsmuxURE", + "DxHPty3B9fpj3duu6Gc6gCSCAvsydJHJEY5G3oVYT8S5BYJ", + "DbVKC8ZJjevrhqSnZyJMMvmPL7oPPL4ed1roxawYnHVgyin", + "DVJV81kab2J6oTyRJ9T3NCwW2DSrysbWCssvMcE6cwZHnAd", + "Fg4rDAyzoVzf39Zo8JFPo4W314ntNWNwm3shr4xKe8M1fJg", + "GUaNcnAruMVxHGTs7gGpSUpigRJboQYQBBQyPohkFcP6NMH", + "J4BMGF4W9yWiJz4pkhQW73X6QMGpKUzmPppVnqzBCqw5dQq", + "E1cR61L1tdDEop4WdWVqcq1H1x6VqsDpSHvFyUeC41uruVJ", + "GoWLzBsj1f23YtdDpyntnvN1LwXKhF5TEeZvBeTVxofgWGR", + "CwHwmbogSwtRbrkajVBNubPvWmHBGU4bhMido54M9CjuKZD", + "FLT63y9oVXJnyiWMAL4RvWxsQx21Vymw9961Z7NRFmSG7rw", + "FoQ2y6JuHuHTG4rHFL3f2hCxfJMvtrq8wwPWdv8tsdkcyA8", + "D7QQKqqs8ocGorRA12h4QoBSHDia1DkHeXT4eMfjWQ483QH", + "J6z7FP35F9DiiU985bhkDTS3WxyeTBeoo9MtLdLoD3GiWPj", + "EjapydCK25AagodRbDECavHAy8yQY1tmeRhwUXhVWx4cFPv", + "H8admATcRkGCrF1dTDDBCjQDsYjMkuPaN9YwR2mSCj4DWMQ", + "FtHMRU1fxsoswJjBvyCGvECepC7gP2X77QbNpyikYSqqR6k", + "DzY5gwr45GVRUFzRMmeg8iffpqYF47nm3XbJhmjG97FijaE", + "D3HKWAihSUmg8HrfeFrftSwNK7no261yA9RNr3LUUdsuzuJ", + "D82DwwGJGTcSvtB3SmNrZejnSertbPzpkYvDUp3ibScL3ne", + "FTPxLXLQvMDQYFA6VqNLGwWPKhemMYP791XVj8TmDpFuV3b", + "FzGfKmS7N8Z1tvCBU5JH1eBXZQ9pCtRNoMUnNVv38wZNq72", + "GDfm1MyLAQ7Rh8YPtF6FtMweV4hz91zzeDy2sSABNNqAbmg", + "DiVQbq7sozeKp7PXPM1HLFc2m7ih8oepKLRK99oBY3QZak1", + "HErWh7D2RzrjWWB2fTJfcAejD9MJpadeWWZM2Wnk7LiNWfG", + "Es4DbDauYZYyRJbr6VxrhdcM1iufP9GtdBYf3YtSEvdwNyb", + "EBgXT6FaVo4WsN2LmfnB2jnpDFf4zay3E492RGSn6v1tY99", + "Dr9Zg4fxZurexParztL9SezFeHsPwdP8uGgULeRMbk8DDHJ", + "JEnSTZJpLh91cSryptj57RtFxq9xXqf4U5wBH3qoP91ZZhN", + "DqtRkrmtPANa8wrYR7Ce2LxJxk2iNFtiCxv1cXbx54uqdTN", + "GaxmF53xbuTFKopVEseWiaCTa8fC6f99n4YfW8MGPSPYX3s", + "EiCesgkAaighBKMpwFSAUdvwE4mRjBjNmmd5fP6d4FG8DAx", + "HVbwWGUx7kCgUGap1Mfcs37g6JAZ5qsfsM7TsDRcSqvfxmd", + "G45bc8Ajrd6YSXav77gQwjjGoAsR2qiGd1aLzkMy7o1RLwd", + "Cqix2rD93Mdf7ytg8tBavAig2TvhXPgPZ2mejQvkq7qgRPq", + "GpodE2S5dPeVjzHB4Drm8R9rEwcQPtwAspXqCVz1ooFWf5K", + "CwfmfRmzPKLj3ntSCejuVwYmQ1F9iZWY4meQrAVoJ2G8Kce", + "Fhp5NPvutRCJ4Gx3G8vCYGaveGcU3KgTwfrn5Zr8sLSgwVx", + "GeYRRPkyi23wSF3cJGjq82117fKJZUbWsAGimUnzb5RPbB1", + "DzCJ4y5oT611dfKQwbBDVbtCfENTdMCjb4KGMU3Mq6nyUMu", + ]; + + let authorities = authorities + .into_iter() + .map(|address| { + ( + grandpa_primitives::AuthorityId::from_ss58check(address) + .expect("hard fork authority addresses are static and they should be carefully defined; qed."), + 1, + ) + }) + .collect::>(); + + forks + .into_iter() + .map(|(set_id, hash, number)| { + let hash = Hash::from_str(hash) + .expect("hard fork hashes are static and they should be carefully defined; qed."); + + grandpa::AuthoritySetHardFork { + set_id, + block: (hash, number), + authorities: authorities.clone(), + last_finalized: None, + } + }) + .collect() +} + +#[cfg(test)] +mod tests { + use consensus_common::BlockOrigin; + use grandpa::VotingRule; + use polkadot_test_client::{ + ClientBlockImportExt, DefaultTestClientBuilderExt, InitPolkadotBlockBuilder, + TestClientBuilder, TestClientBuilderExt, + }; + use sp_blockchain::HeaderBackend; + use sp_runtime::traits::Header; + use std::sync::Arc; + + #[test] + fn grandpa_pause_voting_rule_works() { + let _ = env_logger::try_init(); + + let client = Arc::new(TestClientBuilder::new().build()); + let mut hashes = vec![]; + hashes.push(client.info().genesis_hash); + + let mut push_blocks = { + let mut client = client.clone(); + + move |hashes: &mut Vec<_>, n| { + for _ in 0..n { + let block = client.init_polkadot_block_builder().build().unwrap().block; + hashes.push(block.header.hash()); + futures::executor::block_on(client.import(BlockOrigin::Own, block)).unwrap(); + } + } + }; + + let get_header = { + let client = client.clone(); + move |n| client.expect_header(n).unwrap() + }; + + // the rule should filter all votes after block #20 + // is finalized until block #50 is imported. + let voting_rule = super::PauseAfterBlockFor(20, 30); + + // add 10 blocks + push_blocks(&mut hashes, 10); + assert_eq!(client.info().best_number, 10); + + // we have not reached the pause block + // therefore nothing should be restricted + assert_eq!( + futures::executor::block_on(voting_rule.restrict_vote( + client.clone(), + &get_header(hashes[0]), + &get_header(hashes[10]), + &get_header(hashes[10]) + )), + None, + ); + + // add 15 more blocks + // best block: #25 + push_blocks(&mut hashes, 15); + + // we are targeting the pause block, + // the vote should not be restricted + assert_eq!( + futures::executor::block_on(voting_rule.restrict_vote( + client.clone(), + &get_header(hashes[10]), + &get_header(hashes[20]), + &get_header(hashes[20]) + )), + None, + ); + + // we are past the pause block, votes should + // be limited to the pause block. + let pause_block = get_header(hashes[20]); + assert_eq!( + futures::executor::block_on(voting_rule.restrict_vote( + client.clone(), + &get_header(hashes[10]), + &get_header(hashes[21]), + &get_header(hashes[21]) + )), + Some((pause_block.hash(), *pause_block.number())), + ); + + // we've finalized the pause block, so we'll keep + // restricting our votes to it. + assert_eq!( + futures::executor::block_on(voting_rule.restrict_vote( + client.clone(), + &pause_block, // #20 + &get_header(hashes[21]), + &get_header(hashes[21]), + )), + Some((pause_block.hash(), *pause_block.number())), + ); + + // add 30 more blocks + // best block: #55 + push_blocks(&mut hashes, 30); + + // we're at the last block of the pause, this block + // should still be considered in the pause period + assert_eq!( + futures::executor::block_on(voting_rule.restrict_vote( + client.clone(), + &pause_block, // #20 + &get_header(hashes[50]), + &get_header(hashes[50]), + )), + Some((pause_block.hash(), *pause_block.number())), + ); + + // we're past the pause period, no votes should be filtered + assert_eq!( + futures::executor::block_on(voting_rule.restrict_vote( + client.clone(), + &pause_block, // #20 + &get_header(hashes[51]), + &get_header(hashes[51]), + )), + None, + ); + } +} diff --git a/polkadot/node/service/src/lib.rs b/polkadot/node/service/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..95c887947c98f577ecc5bf144f90ccac1af5ebbf --- /dev/null +++ b/polkadot/node/service/src/lib.rs @@ -0,0 +1,1440 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot service. Specialized wrapper over substrate service. + +#![deny(unused_results)] + +pub mod benchmarking; +pub mod chain_spec; +mod fake_runtime_api; +mod grandpa_support; +mod parachains_db; +mod relay_chain_selection; + +#[cfg(feature = "full-node")] +pub mod overseer; +#[cfg(feature = "full-node")] +pub mod workers; + +#[cfg(feature = "full-node")] +pub use self::overseer::{OverseerGen, OverseerGenArgs, RealOverseerGen}; + +#[cfg(test)] +mod tests; + +#[cfg(feature = "full-node")] +use { + grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}, + gum::info, + polkadot_node_core_approval_voting::{ + self as approval_voting_subsystem, Config as ApprovalVotingConfig, + }, + polkadot_node_core_av_store::Config as AvailabilityConfig, + polkadot_node_core_av_store::Error as AvailabilityError, + polkadot_node_core_candidate_validation::Config as CandidateValidationConfig, + polkadot_node_core_chain_selection::{ + self as chain_selection_subsystem, Config as ChainSelectionConfig, + }, + polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig, + polkadot_node_network_protocol::{ + peer_set::PeerSetProtocolNames, request_response::ReqProtocolNames, + }, + sc_client_api::BlockBackend, + sc_transaction_pool_api::OffchainTransactionPoolFactory, + sp_core::traits::SpawnNamed, +}; + +use polkadot_node_subsystem_util::database::Database; + +#[cfg(feature = "full-node")] +pub use { + polkadot_overseer::{Handle, Overseer, OverseerConnector, OverseerHandle}, + polkadot_primitives::runtime_api::ParachainHost, + relay_chain_selection::SelectRelayChain, + sc_client_api::AuxStore, + sp_authority_discovery::AuthorityDiscoveryApi, + sp_blockchain::{HeaderBackend, HeaderMetadata}, + sp_consensus_babe::BabeApi, +}; + +#[cfg(feature = "full-node")] +use polkadot_node_subsystem::jaeger; + +use std::{path::PathBuf, sync::Arc, time::Duration}; + +use prometheus_endpoint::Registry; +#[cfg(feature = "full-node")] +use service::KeystoreContainer; +use service::RpcHandlers; +use telemetry::TelemetryWorker; +#[cfg(feature = "full-node")] +use telemetry::{Telemetry, TelemetryWorkerHandle}; + +pub use chain_spec::{KusamaChainSpec, PolkadotChainSpec, RococoChainSpec, WestendChainSpec}; +pub use consensus_common::{Proposal, SelectChain}; +use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE; +use mmr_gadget::MmrGadget; +pub use polkadot_primitives::{Block, BlockId, BlockNumber, CollatorPair, Hash, Id as ParaId}; +pub use sc_client_api::{Backend, CallExecutor}; +pub use sc_consensus::{BlockImport, LongestChain}; +pub use sc_executor::NativeExecutionDispatch; +use sc_executor::{HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY}; +pub use service::{ + config::{DatabaseSource, PrometheusConfig}, + ChainSpec, Configuration, Error as SubstrateServiceError, PruningMode, Role, RuntimeGenesis, + TFullBackend, TFullCallExecutor, TFullClient, TaskManager, TransactionPoolOptions, +}; +pub use sp_api::{ApiRef, ConstructRuntimeApi, Core as CoreApi, ProvideRuntimeApi, StateBackend}; +pub use sp_runtime::{ + generic, + traits::{self as runtime_traits, BlakeTwo256, Block as BlockT, Header as HeaderT, NumberFor}, +}; + +#[cfg(feature = "kusama-native")] +pub use {kusama_runtime, kusama_runtime_constants}; +#[cfg(feature = "polkadot-native")] +pub use {polkadot_runtime, polkadot_runtime_constants}; +#[cfg(feature = "rococo-native")] +pub use {rococo_runtime, rococo_runtime_constants}; +#[cfg(feature = "westend-native")] +pub use {westend_runtime, westend_runtime_constants}; + +pub use fake_runtime_api::{GetLastTimestamp, RuntimeApi}; + +#[cfg(feature = "full-node")] +pub type FullBackend = service::TFullBackend; + +#[cfg(feature = "full-node")] +pub type FullClient = service::TFullClient< + Block, + RuntimeApi, + WasmExecutor<(sp_io::SubstrateHostFunctions, frame_benchmarking::benchmarking::HostFunctions)>, +>; + +/// The minimum period of blocks on which justifications will be +/// imported and generated. +const GRANDPA_JUSTIFICATION_PERIOD: u32 = 512; + +/// Provides the header and block number for a hash. +/// +/// Decouples `sc_client_api::Backend` and `sp_blockchain::HeaderBackend`. +pub trait HeaderProvider: Send + Sync + 'static +where + Block: BlockT, + Error: std::fmt::Debug + Send + Sync + 'static, +{ + /// Obtain the header for a hash. + fn header( + &self, + hash: ::Hash, + ) -> Result::Header>, Error>; + /// Obtain the block number for a hash. + fn number( + &self, + hash: ::Hash, + ) -> Result::Header as HeaderT>::Number>, Error>; +} + +impl HeaderProvider for T +where + Block: BlockT, + T: sp_blockchain::HeaderBackend + 'static, +{ + fn header( + &self, + hash: Block::Hash, + ) -> sp_blockchain::Result::Header>> { + >::header(self, hash) + } + fn number( + &self, + hash: Block::Hash, + ) -> sp_blockchain::Result::Header as HeaderT>::Number>> { + >::number(self, hash) + } +} + +/// Decoupling the provider. +/// +/// Mandated since `trait HeaderProvider` can only be +/// implemented once for a generic `T`. +pub trait HeaderProviderProvider: Send + Sync + 'static +where + Block: BlockT, +{ + type Provider: HeaderProvider + 'static; + + fn header_provider(&self) -> &Self::Provider; +} + +impl HeaderProviderProvider for T +where + Block: BlockT, + T: sc_client_api::Backend + 'static, +{ + type Provider = >::Blockchain; + + fn header_provider(&self) -> &Self::Provider { + self.blockchain() + } +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + Io(#[from] std::io::Error), + + #[error(transparent)] + AddrFormatInvalid(#[from] std::net::AddrParseError), + + #[error(transparent)] + Sub(#[from] SubstrateServiceError), + + #[error(transparent)] + Blockchain(#[from] sp_blockchain::Error), + + #[error(transparent)] + Consensus(#[from] consensus_common::Error), + + #[error("Failed to create an overseer")] + Overseer(#[from] polkadot_overseer::SubsystemError), + + #[error(transparent)] + Prometheus(#[from] prometheus_endpoint::PrometheusError), + + #[error(transparent)] + Telemetry(#[from] telemetry::Error), + + #[error(transparent)] + Jaeger(#[from] polkadot_node_subsystem::jaeger::JaegerError), + + #[cfg(feature = "full-node")] + #[error(transparent)] + Availability(#[from] AvailabilityError), + + #[error("Authorities require the real overseer implementation")] + AuthoritiesRequireRealOverseer, + + #[cfg(feature = "full-node")] + #[error("Creating a custom database is required for validators")] + DatabasePathRequired, + + #[cfg(feature = "full-node")] + #[error("Expected at least one of polkadot, kusama, westend or rococo runtime feature")] + NoRuntime, + + #[cfg(feature = "full-node")] + #[error("Worker binaries not executable, prepare binary: {prep_worker_path:?}, execute binary: {exec_worker_path:?}")] + InvalidWorkerBinaries { prep_worker_path: PathBuf, exec_worker_path: PathBuf }, + + #[cfg(feature = "full-node")] + #[error("Worker binaries could not be found, make sure polkadot was built/installed correctly. If you ran with `cargo run`, please run `cargo build` first. Searched given workers path ({given_workers_path:?}), polkadot binary path ({current_exe_path:?}), and lib path (/usr/lib/polkadot), workers names: {workers_names:?}")] + MissingWorkerBinaries { + given_workers_path: Option, + current_exe_path: PathBuf, + workers_names: Option<(String, String)>, + }, + + #[cfg(feature = "full-node")] + #[error("Version of worker binary ({worker_version}) is different from node version ({node_version}), worker_path: {worker_path}. If you ran with `cargo run`, please run `cargo build` first, otherwise try to `cargo clean`. TESTING ONLY: this check can be disabled with --disable-worker-version-check")] + WorkerBinaryVersionMismatch { + worker_version: String, + node_version: String, + worker_path: PathBuf, + }, +} + +/// Identifies the variant of the chain. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Chain { + /// Polkadot. + Polkadot, + /// Kusama. + Kusama, + /// Rococo or one of its derivations. + Rococo, + /// Westend. + Westend, + /// Unknown chain? + Unknown, +} + +/// Can be called for a `Configuration` to identify which network the configuration targets. +pub trait IdentifyVariant { + /// Returns if this is a configuration for the `Polkadot` network. + fn is_polkadot(&self) -> bool; + + /// Returns if this is a configuration for the `Kusama` network. + fn is_kusama(&self) -> bool; + + /// Returns if this is a configuration for the `Westend` network. + fn is_westend(&self) -> bool; + + /// Returns if this is a configuration for the `Rococo` network. + fn is_rococo(&self) -> bool; + + /// Returns if this is a configuration for the `Wococo` test network. + fn is_wococo(&self) -> bool; + + /// Returns if this is a configuration for the `Versi` test network. + fn is_versi(&self) -> bool; + + /// Returns true if this configuration is for a development network. + fn is_dev(&self) -> bool; + + /// Identifies the variant of the chain. + fn identify_chain(&self) -> Chain; +} + +impl IdentifyVariant for Box { + fn is_polkadot(&self) -> bool { + self.id().starts_with("polkadot") || self.id().starts_with("dot") + } + fn is_kusama(&self) -> bool { + self.id().starts_with("kusama") || self.id().starts_with("ksm") + } + fn is_westend(&self) -> bool { + self.id().starts_with("westend") || self.id().starts_with("wnd") + } + fn is_rococo(&self) -> bool { + self.id().starts_with("rococo") || self.id().starts_with("rco") + } + fn is_wococo(&self) -> bool { + self.id().starts_with("wococo") || self.id().starts_with("wco") + } + fn is_versi(&self) -> bool { + self.id().starts_with("versi") || self.id().starts_with("vrs") + } + fn is_dev(&self) -> bool { + self.id().ends_with("dev") + } + fn identify_chain(&self) -> Chain { + if self.is_polkadot() { + Chain::Polkadot + } else if self.is_kusama() { + Chain::Kusama + } else if self.is_westend() { + Chain::Westend + } else if self.is_rococo() || self.is_versi() || self.is_wococo() { + Chain::Rococo + } else { + Chain::Unknown + } + } +} + +#[cfg(feature = "full-node")] +pub fn open_database(db_source: &DatabaseSource) -> Result, Error> { + let parachains_db = match db_source { + DatabaseSource::RocksDb { path, .. } => parachains_db::open_creating_rocksdb( + path.clone(), + parachains_db::CacheSizes::default(), + )?, + DatabaseSource::ParityDb { path, .. } => parachains_db::open_creating_paritydb( + path.parent().ok_or(Error::DatabasePathRequired)?.into(), + parachains_db::CacheSizes::default(), + )?, + DatabaseSource::Auto { paritydb_path, rocksdb_path, .. } => { + if paritydb_path.is_dir() && paritydb_path.exists() { + parachains_db::open_creating_paritydb( + paritydb_path.parent().ok_or(Error::DatabasePathRequired)?.into(), + parachains_db::CacheSizes::default(), + )? + } else { + parachains_db::open_creating_rocksdb( + rocksdb_path.clone(), + parachains_db::CacheSizes::default(), + )? + } + }, + DatabaseSource::Custom { .. } => { + unimplemented!("No polkadot subsystem db for custom source."); + }, + }; + Ok(parachains_db) +} + +/// Initialize the `Jeager` collector. The destination must listen +/// on the given address and port for `UDP` packets. +#[cfg(any(test, feature = "full-node"))] +fn jaeger_launch_collector_with_agent( + spawner: impl SpawnNamed, + config: &Configuration, + agent: Option, +) -> Result<(), Error> { + if let Some(agent) = agent { + let cfg = jaeger::JaegerConfig::builder() + .agent(agent) + .named(&config.network.node_name) + .build(); + + jaeger::Jaeger::new(cfg).launch(spawner)?; + } + Ok(()) +} + +#[cfg(feature = "full-node")] +type FullSelectChain = relay_chain_selection::SelectRelayChain; +#[cfg(feature = "full-node")] +type FullGrandpaBlockImport = + grandpa::GrandpaBlockImport; +#[cfg(feature = "full-node")] +type FullBeefyBlockImport = + beefy::import::BeefyBlockImport; + +#[cfg(feature = "full-node")] +struct Basics { + task_manager: TaskManager, + client: Arc, + backend: Arc, + keystore_container: KeystoreContainer, + telemetry: Option, +} + +#[cfg(feature = "full-node")] +fn new_partial_basics( + config: &mut Configuration, + jaeger_agent: Option, + telemetry_worker_handle: Option, +) -> Result { + let telemetry = config + .telemetry_endpoints + .clone() + .filter(|x| !x.is_empty()) + .map(move |endpoints| -> Result<_, telemetry::Error> { + let (worker, mut worker_handle) = if let Some(worker_handle) = telemetry_worker_handle { + (None, worker_handle) + } else { + let worker = TelemetryWorker::new(16)?; + let worker_handle = worker.handle(); + (Some(worker), worker_handle) + }; + let telemetry = worker_handle.new_telemetry(endpoints); + Ok((worker, telemetry)) + }) + .transpose()?; + + let heap_pages = config + .default_heap_pages + .map_or(DEFAULT_HEAP_ALLOC_STRATEGY, |h| HeapAllocStrategy::Static { extra_pages: h as _ }); + + let executor = WasmExecutor::builder() + .with_execution_method(config.wasm_method) + .with_onchain_heap_alloc_strategy(heap_pages) + .with_offchain_heap_alloc_strategy(heap_pages) + .with_max_runtime_instances(config.max_runtime_instances) + .with_runtime_cache_size(config.runtime_cache_size) + .build(); + + let (client, backend, keystore_container, task_manager) = + service::new_full_parts::( + &config, + telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), + executor, + )?; + let client = Arc::new(client); + + let telemetry = telemetry.map(|(worker, telemetry)| { + if let Some(worker) = worker { + task_manager.spawn_handle().spawn( + "telemetry", + Some("telemetry"), + Box::pin(worker.run()), + ); + } + telemetry + }); + + jaeger_launch_collector_with_agent(task_manager.spawn_handle(), &*config, jaeger_agent)?; + + Ok(Basics { task_manager, client, backend, keystore_container, telemetry }) +} + +#[cfg(feature = "full-node")] +fn new_partial( + config: &mut Configuration, + Basics { task_manager, backend, client, keystore_container, telemetry }: Basics, + select_chain: ChainSelection, +) -> Result< + service::PartialComponents< + FullClient, + FullBackend, + ChainSelection, + sc_consensus::DefaultImportQueue, + sc_transaction_pool::FullPool, + ( + impl Fn( + polkadot_rpc::DenyUnsafe, + polkadot_rpc::SubscriptionTaskExecutor, + ) -> Result, + ( + babe::BabeBlockImport< + Block, + FullClient, + FullBeefyBlockImport>, + >, + grandpa::LinkHalf, + babe::BabeLink, + beefy::BeefyVoterLinks, + ), + grandpa::SharedVoterState, + sp_consensus_babe::SlotDuration, + Option, + ), + >, + Error, +> +where + ChainSelection: 'static + SelectChain, +{ + let transaction_pool = sc_transaction_pool::BasicPool::new_full( + config.transaction_pool.clone(), + config.role.is_authority().into(), + config.prometheus_registry(), + task_manager.spawn_essential_handle(), + client.clone(), + ); + + let grandpa_hard_forks = if config.chain_spec.is_kusama() { + grandpa_support::kusama_hard_forks() + } else { + Vec::new() + }; + + let (grandpa_block_import, grandpa_link) = grandpa::block_import_with_authority_set_hard_forks( + client.clone(), + GRANDPA_JUSTIFICATION_PERIOD, + &(client.clone() as Arc<_>), + select_chain.clone(), + grandpa_hard_forks, + telemetry.as_ref().map(|x| x.handle()), + )?; + let justification_import = grandpa_block_import.clone(); + + let (beefy_block_import, beefy_voter_links, beefy_rpc_links) = + beefy::beefy_block_import_and_links( + grandpa_block_import, + backend.clone(), + client.clone(), + config.prometheus_registry().cloned(), + ); + + let babe_config = babe::configuration(&*client)?; + let (block_import, babe_link) = + babe::block_import(babe_config.clone(), beefy_block_import, client.clone())?; + + let slot_duration = babe_link.config().slot_duration(); + let (import_queue, babe_worker_handle) = babe::import_queue(babe::ImportQueueParams { + link: babe_link.clone(), + block_import: block_import.clone(), + justification_import: Some(Box::new(justification_import)), + client: client.clone(), + select_chain: select_chain.clone(), + create_inherent_data_providers: move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = + sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); + + Ok((slot, timestamp)) + }, + spawner: &task_manager.spawn_essential_handle(), + registry: config.prometheus_registry(), + telemetry: telemetry.as_ref().map(|x| x.handle()), + offchain_tx_pool_factory: OffchainTransactionPoolFactory::new(transaction_pool.clone()), + })?; + + let justification_stream = grandpa_link.justification_stream(); + let shared_authority_set = grandpa_link.shared_authority_set().clone(); + let shared_voter_state = grandpa::SharedVoterState::empty(); + let finality_proof_provider = GrandpaFinalityProofProvider::new_for_service( + backend.clone(), + Some(shared_authority_set.clone()), + ); + + let import_setup = (block_import, grandpa_link, babe_link, beefy_voter_links); + let rpc_setup = shared_voter_state.clone(); + + let rpc_extensions_builder = { + let client = client.clone(); + let keystore = keystore_container.keystore(); + let transaction_pool = transaction_pool.clone(); + let select_chain = select_chain.clone(); + let chain_spec = config.chain_spec.cloned_box(); + let backend = backend.clone(); + + move |deny_unsafe, + subscription_executor: polkadot_rpc::SubscriptionTaskExecutor| + -> Result { + let deps = polkadot_rpc::FullDeps { + client: client.clone(), + pool: transaction_pool.clone(), + select_chain: select_chain.clone(), + chain_spec: chain_spec.cloned_box(), + deny_unsafe, + babe: polkadot_rpc::BabeDeps { + babe_worker_handle: babe_worker_handle.clone(), + keystore: keystore.clone(), + }, + grandpa: polkadot_rpc::GrandpaDeps { + shared_voter_state: shared_voter_state.clone(), + shared_authority_set: shared_authority_set.clone(), + justification_stream: justification_stream.clone(), + subscription_executor: subscription_executor.clone(), + finality_provider: finality_proof_provider.clone(), + }, + beefy: polkadot_rpc::BeefyDeps { + beefy_finality_proof_stream: beefy_rpc_links.from_voter_justif_stream.clone(), + beefy_best_block_stream: beefy_rpc_links.from_voter_best_beefy_stream.clone(), + subscription_executor, + }, + backend: backend.clone(), + }; + + polkadot_rpc::create_full(deps).map_err(Into::into) + } + }; + + Ok(service::PartialComponents { + client, + backend, + task_manager, + keystore_container, + select_chain, + import_queue, + transaction_pool, + other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, telemetry), + }) +} + +#[cfg(feature = "full-node")] +pub struct NewFullParams { + pub is_parachain_node: IsParachainNode, + pub grandpa_pause: Option<(u32, u32)>, + pub enable_beefy: bool, + pub jaeger_agent: Option, + pub telemetry_worker_handle: Option, + /// The version of the node. TESTING ONLY: `None` can be passed to skip the node/worker version + /// check, both on startup and in the workers. + pub node_version: Option, + /// An optional path to a directory containing the workers. + pub workers_path: Option, + /// Optional custom names for the prepare and execute workers. + pub workers_names: Option<(String, String)>, + pub overseer_gen: OverseerGenerator, + pub overseer_message_channel_capacity_override: Option, + #[allow(dead_code)] + pub malus_finality_delay: Option, + pub hwbench: Option, +} + +#[cfg(feature = "full-node")] +pub struct NewFull { + pub task_manager: TaskManager, + pub client: Arc, + pub overseer_handle: Option, + pub network: Arc::Hash>>, + pub sync_service: Arc>, + pub rpc_handlers: RpcHandlers, + pub backend: Arc, +} + +/// Is this node running as in-process node for a parachain node? +#[cfg(feature = "full-node")] +#[derive(Clone)] +pub enum IsParachainNode { + /// This node is running as in-process node for a parachain collator. + Collator(CollatorPair), + /// This node is running as in-process node for a parachain full node. + FullNode, + /// This node is not running as in-process node for a parachain node, aka a normal relay chain + /// node. + No, +} + +#[cfg(feature = "full-node")] +impl std::fmt::Debug for IsParachainNode { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + use sp_core::Pair; + match self { + IsParachainNode::Collator(pair) => write!(fmt, "Collator({})", pair.public()), + IsParachainNode::FullNode => write!(fmt, "FullNode"), + IsParachainNode::No => write!(fmt, "No"), + } + } +} + +#[cfg(feature = "full-node")] +impl IsParachainNode { + /// Is this running alongside a collator? + fn is_collator(&self) -> bool { + matches!(self, Self::Collator(_)) + } + + /// Is this running alongside a full node? + fn is_full_node(&self) -> bool { + matches!(self, Self::FullNode) + } + + /// Is this node running alongside a relay chain node? + fn is_running_alongside_parachain_node(&self) -> bool { + self.is_collator() || self.is_full_node() + } +} + +pub const AVAILABILITY_CONFIG: AvailabilityConfig = AvailabilityConfig { + col_data: parachains_db::REAL_COLUMNS.col_availability_data, + col_meta: parachains_db::REAL_COLUMNS.col_availability_meta, +}; + +/// Create a new full node of arbitrary runtime and executor. +/// +/// This is an advanced feature and not recommended for general use. Generally, `build_full` is +/// a better choice. +/// +/// `workers_path` is used to get the path to the directory where auxiliary worker binaries reside. +/// If not specified, the main binary's directory is searched first, then `/usr/lib/polkadot` is +/// searched. If the path points to an executable rather then directory, that executable is used +/// both as preparation and execution worker (supposed to be used for tests only). +#[cfg(feature = "full-node")] +pub fn new_full( + mut config: Configuration, + NewFullParams { + is_parachain_node, + grandpa_pause, + enable_beefy, + jaeger_agent, + telemetry_worker_handle, + node_version, + workers_path, + workers_names, + overseer_gen, + overseer_message_channel_capacity_override, + malus_finality_delay: _malus_finality_delay, + hwbench, + }: NewFullParams, +) -> Result { + use polkadot_node_network_protocol::request_response::IncomingRequest; + use sc_network_common::sync::warp::WarpSyncParams; + + let is_offchain_indexing_enabled = config.offchain_worker.indexing_enabled; + let role = config.role.clone(); + let force_authoring = config.force_authoring; + let backoff_authoring_blocks = { + let mut backoff = sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default(); + + if config.chain_spec.is_rococo() || + config.chain_spec.is_wococo() || + config.chain_spec.is_versi() + { + // it's a testnet that's in flux, finality has stalled sometimes due + // to operational issues and it's annoying to slow down block + // production to 1 block per hour. + backoff.max_interval = 10; + } + + Some(backoff) + }; + + // Warn the user that BEEFY is still experimental for Polkadot. + if enable_beefy && config.chain_spec.is_polkadot() { + gum::warn!("BEEFY is still experimental, usage on Polkadot network is discouraged."); + } + + let disable_grandpa = config.disable_grandpa; + let name = config.network.node_name.clone(); + + let basics = new_partial_basics(&mut config, jaeger_agent, telemetry_worker_handle)?; + + let prometheus_registry = config.prometheus_registry().cloned(); + + let overseer_connector = OverseerConnector::default(); + let overseer_handle = Handle::new(overseer_connector.handle()); + + let chain_spec = config.chain_spec.cloned_box(); + + let keystore = basics.keystore_container.local_keystore(); + let auth_or_collator = role.is_authority() || is_parachain_node.is_collator(); + // We only need to enable the pvf checker when this is a validator. + let pvf_checker_enabled = role.is_authority(); + + let select_chain = if auth_or_collator { + let metrics = + polkadot_node_subsystem_util::metrics::Metrics::register(prometheus_registry.as_ref())?; + + SelectRelayChain::new_with_overseer( + basics.backend.clone(), + overseer_handle.clone(), + metrics, + Some(basics.task_manager.spawn_handle()), + ) + } else { + SelectRelayChain::new_longest_chain(basics.backend.clone()) + }; + + let service::PartialComponents::<_, _, SelectRelayChain<_>, _, _, _> { + client, + backend, + mut task_manager, + keystore_container, + select_chain, + import_queue, + transaction_pool, + other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry), + } = new_partial::>(&mut config, basics, select_chain)?; + + let shared_voter_state = rpc_setup; + let auth_disc_publish_non_global_ips = config.network.allow_non_globals_in_dht; + let mut net_config = sc_network::config::FullNetworkConfiguration::new(&config.network); + + let genesis_hash = client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"); + + // Note: GrandPa is pushed before the Polkadot-specific protocols. This doesn't change + // anything in terms of behaviour, but makes the logs more consistent with the other + // Substrate nodes. + let grandpa_protocol_name = grandpa::protocol_standard_name(&genesis_hash, &config.chain_spec); + net_config.add_notification_protocol(grandpa::grandpa_peers_set_config( + grandpa_protocol_name.clone(), + )); + + let beefy_gossip_proto_name = + beefy::gossip_protocol_name(&genesis_hash, config.chain_spec.fork_id()); + // `beefy_on_demand_justifications_handler` is given to `beefy-gadget` task to be run, + // while `beefy_req_resp_cfg` is added to `config.network.request_response_protocols`. + let (beefy_on_demand_justifications_handler, beefy_req_resp_cfg) = + beefy::communication::request_response::BeefyJustifsRequestHandler::new( + &genesis_hash, + config.chain_spec.fork_id(), + client.clone(), + prometheus_registry.clone(), + ); + if enable_beefy { + net_config.add_notification_protocol(beefy::communication::beefy_peers_set_config( + beefy_gossip_proto_name.clone(), + )); + net_config.add_request_response_protocol(beefy_req_resp_cfg); + } + + // validation/collation protocols are enabled only if `Overseer` is enabled + let peerset_protocol_names = + PeerSetProtocolNames::new(genesis_hash, config.chain_spec.fork_id()); + + // If this is a validator or running alongside a parachain node, we need to enable the + // networking protocols. + // + // Collators and parachain full nodes require the collator and validator networking to send + // collations and to be able to recover PoVs. + if role.is_authority() || is_parachain_node.is_running_alongside_parachain_node() { + use polkadot_network_bridge::{peer_sets_info, IsAuthority}; + let is_authority = if role.is_authority() { IsAuthority::Yes } else { IsAuthority::No }; + for config in peer_sets_info(is_authority, &peerset_protocol_names) { + net_config.add_notification_protocol(config); + } + } + + let req_protocol_names = ReqProtocolNames::new(&genesis_hash, config.chain_spec.fork_id()); + + let (pov_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); + net_config.add_request_response_protocol(cfg); + let (chunk_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); + net_config.add_request_response_protocol(cfg); + let (collation_req_v1_receiver, cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + net_config.add_request_response_protocol(cfg); + let (collation_req_vstaging_receiver, cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + net_config.add_request_response_protocol(cfg); + let (available_data_req_receiver, cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + net_config.add_request_response_protocol(cfg); + let (statement_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); + net_config.add_request_response_protocol(cfg); + let (candidate_req_vstaging_receiver, cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + net_config.add_request_response_protocol(cfg); + let (dispute_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); + net_config.add_request_response_protocol(cfg); + + let grandpa_hard_forks = if config.chain_spec.is_kusama() { + grandpa_support::kusama_hard_forks() + } else { + Vec::new() + }; + + let warp_sync = Arc::new(grandpa::warp_proof::NetworkProvider::new( + backend.clone(), + import_setup.1.shared_authority_set().clone(), + grandpa_hard_forks, + )); + + let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) = + service::build_network(service::BuildNetworkParams { + config: &config, + net_config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + block_announce_validator_builder: None, + warp_sync_params: Some(WarpSyncParams::WithProvider(warp_sync)), + })?; + + if config.offchain_worker.enabled { + use futures::FutureExt; + + task_manager.spawn_handle().spawn( + "offchain-workers-runner", + "offchain-work", + sc_offchain::OffchainWorkers::new(sc_offchain::OffchainWorkerOptions { + runtime_api_provider: client.clone(), + keystore: Some(keystore_container.keystore()), + offchain_db: backend.offchain_storage(), + transaction_pool: Some(OffchainTransactionPoolFactory::new( + transaction_pool.clone(), + )), + network_provider: network.clone(), + is_validator: role.is_authority(), + enable_http_requests: false, + custom_extensions: move |_| vec![], + }) + .run(client.clone(), task_manager.spawn_handle()) + .boxed(), + ); + } + + let parachains_db = open_database(&config.database)?; + + let approval_voting_config = ApprovalVotingConfig { + col_approval_data: parachains_db::REAL_COLUMNS.col_approval_data, + slot_duration_millis: slot_duration.as_millis() as u64, + }; + + let candidate_validation_config = if role.is_authority() { + let (prep_worker_path, exec_worker_path) = + workers::determine_workers_paths(workers_path, workers_names, node_version.clone())?; + log::info!("🚀 Using prepare-worker binary at: {:?}", prep_worker_path); + log::info!("🚀 Using execute-worker binary at: {:?}", exec_worker_path); + + Some(CandidateValidationConfig { + artifacts_cache_path: config + .database + .path() + .ok_or(Error::DatabasePathRequired)? + .join("pvf-artifacts"), + node_version, + prep_worker_path, + exec_worker_path, + }) + } else { + None + }; + + let chain_selection_config = ChainSelectionConfig { + col_data: parachains_db::REAL_COLUMNS.col_chain_selection_data, + stagnant_check_interval: Default::default(), + stagnant_check_mode: chain_selection_subsystem::StagnantCheckMode::PruneOnly, + }; + + let dispute_coordinator_config = DisputeCoordinatorConfig { + col_dispute_data: parachains_db::REAL_COLUMNS.col_dispute_coordinator_data, + }; + + let rpc_handlers = service::spawn_tasks(service::SpawnTasksParams { + config, + backend: backend.clone(), + client: client.clone(), + keystore: keystore_container.keystore(), + network: network.clone(), + sync_service: sync_service.clone(), + rpc_builder: Box::new(rpc_extensions_builder), + transaction_pool: transaction_pool.clone(), + task_manager: &mut task_manager, + system_rpc_tx, + tx_handler_controller, + telemetry: telemetry.as_mut(), + })?; + + if let Some(hwbench) = hwbench { + sc_sysinfo::print_hwbench(&hwbench); + if !SUBSTRATE_REFERENCE_HARDWARE.check_hardware(&hwbench) && role.is_authority() { + log::warn!( + "⚠️ The hardware does not meet the minimal requirements for role 'Authority' find out more at:\n\ + https://wiki.polkadot.network/docs/maintain-guides-how-to-validate-polkadot#reference-hardware" + ); + } + + if let Some(ref mut telemetry) = telemetry { + let telemetry_handle = telemetry.handle(); + task_manager.spawn_handle().spawn( + "telemetry_hwbench", + None, + sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench), + ); + } + } + + let (block_import, link_half, babe_link, beefy_links) = import_setup; + + let overseer_client = client.clone(); + let spawner = task_manager.spawn_handle(); + + let authority_discovery_service = + // We need the authority discovery if this node is either a validator or running alongside a parachain node. + // Parachains node require the authority discovery for finding relay chain validators for sending + // their PoVs or recovering PoVs. + if role.is_authority() || is_parachain_node.is_running_alongside_parachain_node() { + use futures::StreamExt; + use sc_network::{Event, NetworkEventStream}; + + let authority_discovery_role = if role.is_authority() { + sc_authority_discovery::Role::PublishAndDiscover(keystore_container.keystore()) + } else { + // don't publish our addresses when we're not an authority (collator, cumulus, ..) + sc_authority_discovery::Role::Discover + }; + let dht_event_stream = + network.event_stream("authority-discovery").filter_map(|e| async move { + match e { + Event::Dht(e) => Some(e), + _ => None, + } + }); + let (worker, service) = sc_authority_discovery::new_worker_and_service_with_config( + sc_authority_discovery::WorkerConfig { + publish_non_global_ips: auth_disc_publish_non_global_ips, + // Require that authority discovery records are signed. + strict_record_validation: true, + ..Default::default() + }, + client.clone(), + network.clone(), + Box::pin(dht_event_stream), + authority_discovery_role, + prometheus_registry.clone(), + ); + + task_manager.spawn_handle().spawn( + "authority-discovery-worker", + Some("authority-discovery"), + Box::pin(worker.run()), + ); + Some(service) + } else { + None + }; + + let overseer_handle = if let Some(authority_discovery_service) = authority_discovery_service { + let (overseer, overseer_handle) = overseer_gen + .generate::( + overseer_connector, + OverseerGenArgs { + keystore, + runtime_client: overseer_client.clone(), + parachains_db, + network_service: network.clone(), + sync_service: sync_service.clone(), + authority_discovery_service, + pov_req_receiver, + chunk_req_receiver, + collation_req_v1_receiver, + collation_req_vstaging_receiver, + available_data_req_receiver, + statement_req_receiver, + candidate_req_vstaging_receiver, + dispute_req_receiver, + registry: prometheus_registry.as_ref(), + spawner, + is_parachain_node, + approval_voting_config, + availability_config: AVAILABILITY_CONFIG, + candidate_validation_config, + chain_selection_config, + dispute_coordinator_config, + pvf_checker_enabled, + overseer_message_channel_capacity_override, + req_protocol_names, + peerset_protocol_names, + offchain_transaction_pool_factory: OffchainTransactionPoolFactory::new( + transaction_pool.clone(), + ), + }, + ) + .map_err(|e| { + gum::error!("Failed to init overseer: {}", e); + e + })?; + let handle = Handle::new(overseer_handle.clone()); + + { + let handle = handle.clone(); + task_manager.spawn_essential_handle().spawn_blocking( + "overseer", + None, + Box::pin(async move { + use futures::{pin_mut, select, FutureExt}; + + let forward = polkadot_overseer::forward_events(overseer_client, handle); + + let forward = forward.fuse(); + let overseer_fut = overseer.run().fuse(); + + pin_mut!(overseer_fut); + pin_mut!(forward); + + select! { + () = forward => (), + () = overseer_fut => (), + complete => (), + } + }), + ); + } + Some(handle) + } else { + assert!( + !auth_or_collator, + "Precondition congruence (false) is guaranteed by manual checking. qed" + ); + None + }; + + if role.is_authority() { + let proposer = sc_basic_authorship::ProposerFactory::new( + task_manager.spawn_handle(), + client.clone(), + transaction_pool.clone(), + prometheus_registry.as_ref(), + telemetry.as_ref().map(|x| x.handle()), + ); + + let client_clone = client.clone(); + let overseer_handle = + overseer_handle.as_ref().ok_or(Error::AuthoritiesRequireRealOverseer)?.clone(); + let slot_duration = babe_link.config().slot_duration(); + let babe_config = babe::BabeParams { + keystore: keystore_container.keystore(), + client: client.clone(), + select_chain, + block_import, + env: proposer, + sync_oracle: sync_service.clone(), + justification_sync_link: sync_service.clone(), + create_inherent_data_providers: move |parent, ()| { + let client_clone = client_clone.clone(); + let overseer_handle = overseer_handle.clone(); + + async move { + let parachain = + polkadot_node_core_parachains_inherent::ParachainsInherentDataProvider::new( + client_clone, + overseer_handle, + parent, + ); + + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = + sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); + + Ok((slot, timestamp, parachain)) + } + }, + force_authoring, + backoff_authoring_blocks, + babe_link, + block_proposal_slot_portion: babe::SlotProportion::new(2f32 / 3f32), + max_block_proposal_slot_portion: None, + telemetry: telemetry.as_ref().map(|x| x.handle()), + }; + + let babe = babe::start_babe(babe_config)?; + task_manager.spawn_essential_handle().spawn_blocking("babe", None, babe); + } + + // if the node isn't actively participating in consensus then it doesn't + // need a keystore, regardless of which protocol we use below. + let keystore_opt = if role.is_authority() { Some(keystore_container.keystore()) } else { None }; + + if enable_beefy { + let justifications_protocol_name = beefy_on_demand_justifications_handler.protocol_name(); + let network_params = beefy::BeefyNetworkParams { + network: network.clone(), + sync: sync_service.clone(), + gossip_protocol_name: beefy_gossip_proto_name, + justifications_protocol_name, + _phantom: core::marker::PhantomData::, + }; + let payload_provider = beefy_primitives::mmr::MmrRootProvider::new(client.clone()); + let beefy_params = beefy::BeefyParams { + client: client.clone(), + backend: backend.clone(), + payload_provider, + runtime: client.clone(), + key_store: keystore_opt.clone(), + network_params, + min_block_delta: if chain_spec.is_wococo() { 4 } else { 8 }, + prometheus_registry: prometheus_registry.clone(), + links: beefy_links, + on_demand_justifications_handler: beefy_on_demand_justifications_handler, + }; + + let gadget = beefy::start_beefy_gadget::<_, _, _, _, _, _, _>(beefy_params); + + // BEEFY is part of consensus, if it fails we'll bring the node down with it to make sure it + // is noticed. + task_manager + .spawn_essential_handle() + .spawn_blocking("beefy-gadget", None, gadget); + // When offchain indexing is enabled, MMR gadget should also run. + if is_offchain_indexing_enabled { + task_manager.spawn_essential_handle().spawn_blocking( + "mmr-gadget", + None, + MmrGadget::start( + client.clone(), + backend.clone(), + sp_mmr_primitives::INDEXING_PREFIX.to_vec(), + ), + ); + } + } + + let config = grandpa::Config { + // FIXME substrate#1578 make this available through chainspec + // Grandpa performance can be improved a bit by tuning this parameter, see: + // https://github.com/paritytech/polkadot/issues/5464 + gossip_duration: Duration::from_millis(1000), + justification_generation_period: GRANDPA_JUSTIFICATION_PERIOD, + name: Some(name), + observer_enabled: false, + keystore: keystore_opt, + local_role: role, + telemetry: telemetry.as_ref().map(|x| x.handle()), + protocol_name: grandpa_protocol_name, + }; + + let enable_grandpa = !disable_grandpa; + if enable_grandpa { + // start the full GRANDPA voter + // NOTE: unlike in substrate we are currently running the full + // GRANDPA voter protocol for all full nodes (regardless of whether + // they're validators or not). at this point the full voter should + // provide better guarantees of block and vote data availability than + // the observer. + + // add a custom voting rule to temporarily stop voting for new blocks + // after the given pause block is finalized and restarting after the + // given delay. + let mut builder = grandpa::VotingRulesBuilder::default(); + + #[cfg(not(feature = "malus"))] + let _malus_finality_delay = None; + + if let Some(delay) = _malus_finality_delay { + info!(?delay, "Enabling malus finality delay",); + builder = builder.add(grandpa::BeforeBestBlockBy(delay)); + }; + + let voting_rule = match grandpa_pause { + Some((block, delay)) => { + info!( + block_number = %block, + delay = %delay, + "GRANDPA scheduled voting pause set for block #{} with a duration of {} blocks.", + block, + delay, + ); + + builder.add(grandpa_support::PauseAfterBlockFor(block, delay)).build() + }, + None => builder.build(), + }; + + let grandpa_config = grandpa::GrandpaParams { + config, + link: link_half, + network: network.clone(), + sync: sync_service.clone(), + voting_rule, + prometheus_registry: prometheus_registry.clone(), + shared_voter_state, + telemetry: telemetry.as_ref().map(|x| x.handle()), + offchain_tx_pool_factory: OffchainTransactionPoolFactory::new(transaction_pool.clone()), + }; + + task_manager.spawn_essential_handle().spawn_blocking( + "grandpa-voter", + None, + grandpa::run_grandpa_voter(grandpa_config)?, + ); + } + + network_starter.start_network(); + + Ok(NewFull { + task_manager, + client, + overseer_handle, + network, + sync_service, + rpc_handlers, + backend, + }) +} + +#[cfg(feature = "full-node")] +macro_rules! chain_ops { + ($config:expr, $jaeger_agent:expr, $telemetry_worker_handle:expr) => {{ + let telemetry_worker_handle = $telemetry_worker_handle; + let jaeger_agent = $jaeger_agent; + let mut config = $config; + let basics = new_partial_basics(config, jaeger_agent, telemetry_worker_handle)?; + + use ::sc_consensus::LongestChain; + // use the longest chain selection, since there is no overseer available + let chain_selection = LongestChain::new(basics.backend.clone()); + + let service::PartialComponents { client, backend, import_queue, task_manager, .. } = + new_partial::>(&mut config, basics, chain_selection)?; + Ok((client, backend, import_queue, task_manager)) + }}; +} + +/// Builds a new object suitable for chain operations. +#[cfg(feature = "full-node")] +pub fn new_chain_ops( + config: &mut Configuration, + jaeger_agent: Option, +) -> Result<(Arc, Arc, sc_consensus::BasicQueue, TaskManager), Error> +{ + config.keystore = service::config::KeystoreConfig::InMemory; + + if config.chain_spec.is_rococo() || + config.chain_spec.is_wococo() || + config.chain_spec.is_versi() + { + chain_ops!(config, jaeger_agent, None) + } else if config.chain_spec.is_kusama() { + chain_ops!(config, jaeger_agent, None) + } else if config.chain_spec.is_westend() { + return chain_ops!(config, jaeger_agent, None) + } else { + chain_ops!(config, jaeger_agent, None) + } +} + +/// Build a full node. +/// +/// The actual "flavor", aka if it will use `Polkadot`, `Rococo` or `Kusama` is determined based on +/// [`IdentifyVariant`] using the chain spec. +#[cfg(feature = "full-node")] +pub fn build_full( + config: Configuration, + mut params: NewFullParams, +) -> Result { + let is_polkadot = config.chain_spec.is_polkadot(); + + params.overseer_message_channel_capacity_override = + params.overseer_message_channel_capacity_override.map(move |capacity| { + if is_polkadot { + gum::warn!("Channel capacity should _never_ be tampered with on polkadot!"); + } + capacity + }); + + new_full(config, params) +} + +/// Reverts the node state down to at most the last finalized block. +/// +/// In particular this reverts: +/// - `ApprovalVotingSubsystem` data in the parachains-db; +/// - `ChainSelectionSubsystem` data in the parachains-db; +/// - Low level Babe and Grandpa consensus data. +#[cfg(feature = "full-node")] +pub fn revert_backend( + client: Arc, + backend: Arc, + blocks: BlockNumber, + config: Configuration, +) -> Result<(), Error> { + let best_number = client.info().best_number; + let finalized = client.info().finalized_number; + let revertible = blocks.min(best_number - finalized); + + if revertible == 0 { + return Ok(()) + } + + let number = best_number - revertible; + let hash = client.block_hash_from_id(&BlockId::Number(number))?.ok_or( + sp_blockchain::Error::Backend(format!( + "Unexpected hash lookup failure for block number: {}", + number + )), + )?; + + let parachains_db = open_database(&config.database) + .map_err(|err| sp_blockchain::Error::Backend(err.to_string()))?; + + revert_approval_voting(parachains_db.clone(), hash)?; + revert_chain_selection(parachains_db, hash)?; + // Revert Substrate consensus related components + babe::revert(client.clone(), backend, blocks)?; + grandpa::revert(client, blocks)?; + + Ok(()) +} + +fn revert_chain_selection(db: Arc, hash: Hash) -> sp_blockchain::Result<()> { + let config = chain_selection_subsystem::Config { + col_data: parachains_db::REAL_COLUMNS.col_chain_selection_data, + stagnant_check_interval: chain_selection_subsystem::StagnantCheckInterval::never(), + stagnant_check_mode: chain_selection_subsystem::StagnantCheckMode::PruneOnly, + }; + + let chain_selection = chain_selection_subsystem::ChainSelectionSubsystem::new(config, db); + + chain_selection + .revert_to(hash) + .map_err(|err| sp_blockchain::Error::Backend(err.to_string())) +} + +fn revert_approval_voting(db: Arc, hash: Hash) -> sp_blockchain::Result<()> { + let config = approval_voting_subsystem::Config { + col_approval_data: parachains_db::REAL_COLUMNS.col_approval_data, + slot_duration_millis: Default::default(), + }; + + let approval_voting = approval_voting_subsystem::ApprovalVotingSubsystem::with_config( + config, + db, + Arc::new(sc_keystore::LocalKeystore::in_memory()), + Box::new(consensus_common::NoNetwork), + approval_voting_subsystem::Metrics::default(), + ); + + approval_voting + .revert_to(hash) + .map_err(|err| sp_blockchain::Error::Backend(err.to_string())) +} diff --git a/polkadot/node/service/src/overseer.rs b/polkadot/node/service/src/overseer.rs new file mode 100644 index 0000000000000000000000000000000000000000..cb6b80eb83c8206f7eada6dbcc8d5c60457debe6 --- /dev/null +++ b/polkadot/node/service/src/overseer.rs @@ -0,0 +1,408 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::{AuthorityDiscoveryApi, Block, Error, Hash, IsParachainNode, Registry}; +use polkadot_node_subsystem_types::DefaultSubsystemClient; +use sc_transaction_pool_api::OffchainTransactionPoolFactory; +use sp_core::traits::SpawnNamed; + +use lru::LruCache; +use polkadot_availability_distribution::IncomingRequestReceivers; +use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig; +use polkadot_node_core_av_store::Config as AvailabilityConfig; +use polkadot_node_core_candidate_validation::Config as CandidateValidationConfig; +use polkadot_node_core_chain_selection::Config as ChainSelectionConfig; +use polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig; +use polkadot_node_network_protocol::{ + peer_set::PeerSetProtocolNames, + request_response::{ + v1 as request_v1, vstaging as request_vstaging, IncomingRequestReceiver, ReqProtocolNames, + }, +}; +#[cfg(any(feature = "malus", test))] +pub use polkadot_overseer::{ + dummy::{dummy_overseer_builder, DummySubsystem}, + HeadSupportsParachains, +}; +use polkadot_overseer::{ + metrics::Metrics as OverseerMetrics, InitializedOverseerBuilder, MetricsTrait, Overseer, + OverseerConnector, OverseerHandle, SpawnGlue, +}; + +use polkadot_primitives::runtime_api::ParachainHost; +use sc_authority_discovery::Service as AuthorityDiscoveryService; +use sc_client_api::AuxStore; +use sc_keystore::LocalKeystore; +use sc_network::NetworkStateInfo; +use sp_api::ProvideRuntimeApi; +use sp_blockchain::HeaderBackend; +use sp_consensus_babe::BabeApi; +use std::sync::Arc; + +pub use polkadot_approval_distribution::ApprovalDistribution as ApprovalDistributionSubsystem; +pub use polkadot_availability_bitfield_distribution::BitfieldDistribution as BitfieldDistributionSubsystem; +pub use polkadot_availability_distribution::AvailabilityDistributionSubsystem; +pub use polkadot_availability_recovery::AvailabilityRecoverySubsystem; +pub use polkadot_collator_protocol::{CollatorProtocolSubsystem, ProtocolSide}; +pub use polkadot_dispute_distribution::DisputeDistributionSubsystem; +pub use polkadot_gossip_support::GossipSupport as GossipSupportSubsystem; +pub use polkadot_network_bridge::{ + Metrics as NetworkBridgeMetrics, NetworkBridgeRx as NetworkBridgeRxSubsystem, + NetworkBridgeTx as NetworkBridgeTxSubsystem, +}; +pub use polkadot_node_collation_generation::CollationGenerationSubsystem; +pub use polkadot_node_core_approval_voting::ApprovalVotingSubsystem; +pub use polkadot_node_core_av_store::AvailabilityStoreSubsystem; +pub use polkadot_node_core_backing::CandidateBackingSubsystem; +pub use polkadot_node_core_bitfield_signing::BitfieldSigningSubsystem; +pub use polkadot_node_core_candidate_validation::CandidateValidationSubsystem; +pub use polkadot_node_core_chain_api::ChainApiSubsystem; +pub use polkadot_node_core_chain_selection::ChainSelectionSubsystem; +pub use polkadot_node_core_dispute_coordinator::DisputeCoordinatorSubsystem; +pub use polkadot_node_core_prospective_parachains::ProspectiveParachainsSubsystem; +pub use polkadot_node_core_provisioner::ProvisionerSubsystem; +pub use polkadot_node_core_pvf_checker::PvfCheckerSubsystem; +pub use polkadot_node_core_runtime_api::RuntimeApiSubsystem; +use polkadot_node_subsystem_util::rand::{self, SeedableRng}; +pub use polkadot_statement_distribution::StatementDistributionSubsystem; + +/// Arguments passed for overseer construction. +pub struct OverseerGenArgs<'a, Spawner, RuntimeClient> +where + RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, + RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + Spawner: 'static + SpawnNamed + Clone + Unpin, +{ + /// The keystore to use for i.e. validator keys. + pub keystore: Arc, + /// Runtime client generic, providing the `ProvieRuntimeApi` trait besides others. + pub runtime_client: Arc, + /// The underlying key value store for the parachains. + pub parachains_db: Arc, + /// Underlying network service implementation. + pub network_service: Arc>, + /// Underlying syncing service implementation. + pub sync_service: Arc>, + /// Underlying authority discovery service. + pub authority_discovery_service: AuthorityDiscoveryService, + /// POV request receiver. + pub pov_req_receiver: IncomingRequestReceiver, + /// Erasure chunks request receiver. + pub chunk_req_receiver: IncomingRequestReceiver, + /// Collations request receiver for network protocol v1. + pub collation_req_v1_receiver: IncomingRequestReceiver, + /// Collations request receiver for network protocol vstaging. + pub collation_req_vstaging_receiver: + IncomingRequestReceiver, + /// Receiver for available data requests. + pub available_data_req_receiver: + IncomingRequestReceiver, + /// Receiver for incoming large statement requests. + pub statement_req_receiver: IncomingRequestReceiver, + /// Receiver for incoming candidate requests. + pub candidate_req_vstaging_receiver: + IncomingRequestReceiver, + /// Receiver for incoming disputes. + pub dispute_req_receiver: IncomingRequestReceiver, + /// Prometheus registry, commonly used for production systems, less so for test. + pub registry: Option<&'a Registry>, + /// Task spawner to be used throughout the overseer and the APIs it provides. + pub spawner: Spawner, + /// Determines the behavior of the collator. + pub is_parachain_node: IsParachainNode, + /// Configuration for the approval voting subsystem. + pub approval_voting_config: ApprovalVotingConfig, + /// Configuration for the availability store subsystem. + pub availability_config: AvailabilityConfig, + /// Configuration for the candidate validation subsystem. + pub candidate_validation_config: Option, + /// Configuration for the chain selection subsystem. + pub chain_selection_config: ChainSelectionConfig, + /// Configuration for the dispute coordinator subsystem. + pub dispute_coordinator_config: DisputeCoordinatorConfig, + /// Enable PVF pre-checking + pub pvf_checker_enabled: bool, + /// Overseer channel capacity override. + pub overseer_message_channel_capacity_override: Option, + /// Request-response protocol names source. + pub req_protocol_names: ReqProtocolNames, + /// [`PeerSet`] protocol names to protocols mapping. + pub peerset_protocol_names: PeerSetProtocolNames, + /// The offchain transaction pool factory. + pub offchain_transaction_pool_factory: OffchainTransactionPoolFactory, +} + +/// Obtain a prepared `OverseerBuilder`, that is initialized +/// with all default values. +pub fn prepared_overseer_builder( + OverseerGenArgs { + keystore, + runtime_client, + parachains_db, + network_service, + sync_service, + authority_discovery_service, + pov_req_receiver, + chunk_req_receiver, + collation_req_v1_receiver, + collation_req_vstaging_receiver, + available_data_req_receiver, + statement_req_receiver, + candidate_req_vstaging_receiver, + dispute_req_receiver, + registry, + spawner, + is_parachain_node, + approval_voting_config, + availability_config, + candidate_validation_config, + chain_selection_config, + dispute_coordinator_config, + pvf_checker_enabled, + overseer_message_channel_capacity_override, + req_protocol_names, + peerset_protocol_names, + offchain_transaction_pool_factory, + }: OverseerGenArgs, +) -> Result< + InitializedOverseerBuilder< + SpawnGlue, + Arc>, + CandidateValidationSubsystem, + PvfCheckerSubsystem, + CandidateBackingSubsystem, + StatementDistributionSubsystem, + AvailabilityDistributionSubsystem, + AvailabilityRecoverySubsystem, + BitfieldSigningSubsystem, + BitfieldDistributionSubsystem, + ProvisionerSubsystem, + RuntimeApiSubsystem>, + AvailabilityStoreSubsystem, + NetworkBridgeRxSubsystem< + Arc>, + AuthorityDiscoveryService, + >, + NetworkBridgeTxSubsystem< + Arc>, + AuthorityDiscoveryService, + >, + ChainApiSubsystem, + CollationGenerationSubsystem, + CollatorProtocolSubsystem, + ApprovalDistributionSubsystem, + ApprovalVotingSubsystem, + GossipSupportSubsystem, + DisputeCoordinatorSubsystem, + DisputeDistributionSubsystem, + ChainSelectionSubsystem, + ProspectiveParachainsSubsystem, + >, + Error, +> +where + RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, + RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + Spawner: 'static + SpawnNamed + Clone + Unpin, +{ + use polkadot_node_subsystem_util::metrics::Metrics; + + let metrics = ::register(registry)?; + + let spawner = SpawnGlue(spawner); + + let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?; + + let runtime_api_client = Arc::new(DefaultSubsystemClient::new( + runtime_client.clone(), + offchain_transaction_pool_factory, + )); + + let builder = Overseer::builder() + .network_bridge_tx(NetworkBridgeTxSubsystem::new( + network_service.clone(), + authority_discovery_service.clone(), + network_bridge_metrics.clone(), + req_protocol_names, + peerset_protocol_names.clone(), + )) + .network_bridge_rx(NetworkBridgeRxSubsystem::new( + network_service.clone(), + authority_discovery_service.clone(), + Box::new(sync_service.clone()), + network_bridge_metrics, + peerset_protocol_names, + )) + .availability_distribution(AvailabilityDistributionSubsystem::new( + keystore.clone(), + IncomingRequestReceivers { pov_req_receiver, chunk_req_receiver }, + Metrics::register(registry)?, + )) + .availability_recovery(AvailabilityRecoverySubsystem::with_chunks_if_pov_large( + available_data_req_receiver, + Metrics::register(registry)?, + )) + .availability_store(AvailabilityStoreSubsystem::new( + parachains_db.clone(), + availability_config, + Box::new(sync_service.clone()), + Metrics::register(registry)?, + )) + .bitfield_distribution(BitfieldDistributionSubsystem::new(Metrics::register(registry)?)) + .bitfield_signing(BitfieldSigningSubsystem::new( + keystore.clone(), + Metrics::register(registry)?, + )) + .candidate_backing(CandidateBackingSubsystem::new( + keystore.clone(), + Metrics::register(registry)?, + )) + .candidate_validation(CandidateValidationSubsystem::with_config( + candidate_validation_config, + Metrics::register(registry)?, // candidate-validation metrics + Metrics::register(registry)?, // validation host metrics + )) + .pvf_checker(PvfCheckerSubsystem::new( + pvf_checker_enabled, + keystore.clone(), + Metrics::register(registry)?, + )) + .chain_api(ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?)) + .collation_generation(CollationGenerationSubsystem::new(Metrics::register(registry)?)) + .collator_protocol({ + let side = match is_parachain_node { + IsParachainNode::Collator(collator_pair) => ProtocolSide::Collator { + peer_id: network_service.local_peer_id(), + collator_pair, + request_receiver_v1: collation_req_v1_receiver, + request_receiver_vstaging: collation_req_vstaging_receiver, + metrics: Metrics::register(registry)?, + }, + IsParachainNode::FullNode => ProtocolSide::None, + IsParachainNode::No => ProtocolSide::Validator { + keystore: keystore.clone(), + eviction_policy: Default::default(), + metrics: Metrics::register(registry)?, + }, + }; + CollatorProtocolSubsystem::new(side) + }) + .provisioner(ProvisionerSubsystem::new(Metrics::register(registry)?)) + .runtime_api(RuntimeApiSubsystem::new( + runtime_api_client.clone(), + Metrics::register(registry)?, + spawner.clone(), + )) + .statement_distribution(StatementDistributionSubsystem::new( + keystore.clone(), + statement_req_receiver, + candidate_req_vstaging_receiver, + Metrics::register(registry)?, + rand::rngs::StdRng::from_entropy(), + )) + .approval_distribution(ApprovalDistributionSubsystem::new(Metrics::register(registry)?)) + .approval_voting(ApprovalVotingSubsystem::with_config( + approval_voting_config, + parachains_db.clone(), + keystore.clone(), + Box::new(sync_service.clone()), + Metrics::register(registry)?, + )) + .gossip_support(GossipSupportSubsystem::new( + keystore.clone(), + authority_discovery_service.clone(), + Metrics::register(registry)?, + )) + .dispute_coordinator(DisputeCoordinatorSubsystem::new( + parachains_db.clone(), + dispute_coordinator_config, + keystore.clone(), + Metrics::register(registry)?, + )) + .dispute_distribution(DisputeDistributionSubsystem::new( + keystore.clone(), + dispute_req_receiver, + authority_discovery_service.clone(), + Metrics::register(registry)?, + )) + .chain_selection(ChainSelectionSubsystem::new(chain_selection_config, parachains_db)) + .prospective_parachains(ProspectiveParachainsSubsystem::new(Metrics::register(registry)?)) + .activation_external_listeners(Default::default()) + .span_per_active_leaf(Default::default()) + .active_leaves(Default::default()) + .supports_parachains(runtime_api_client) + .known_leaves(LruCache::new(KNOWN_LEAVES_CACHE_SIZE)) + .metrics(metrics) + .spawner(spawner); + + if let Some(capacity) = overseer_message_channel_capacity_override { + Ok(builder.message_channel_capacity(capacity)) + } else { + Ok(builder) + } +} + +/// Trait for the `fn` generating the overseer. +/// +/// Default behavior is to create an unmodified overseer, as `RealOverseerGen` +/// would do. +pub trait OverseerGen { + /// Overwrite the full generation of the overseer, including the subsystems. + fn generate( + &self, + connector: OverseerConnector, + args: OverseerGenArgs, + ) -> Result< + (Overseer, Arc>>, OverseerHandle), + Error, + > + where + RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, + RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + Spawner: 'static + SpawnNamed + Clone + Unpin, + { + let gen = RealOverseerGen; + RealOverseerGen::generate::(&gen, connector, args) + } + // It would be nice to make `create_subsystems` part of this trait, + // but the amount of generic arguments that would be required as + // as consequence make this rather annoying to implement and use. +} + +use polkadot_overseer::KNOWN_LEAVES_CACHE_SIZE; + +/// The regular set of subsystems. +pub struct RealOverseerGen; + +impl OverseerGen for RealOverseerGen { + fn generate( + &self, + connector: OverseerConnector, + args: OverseerGenArgs, + ) -> Result< + (Overseer, Arc>>, OverseerHandle), + Error, + > + where + RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, + RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + Spawner: 'static + SpawnNamed + Clone + Unpin, + { + prepared_overseer_builder(args)? + .build_with_connector(connector) + .map_err(|e| e.into()) + } +} diff --git a/polkadot/node/service/src/parachains_db/mod.rs b/polkadot/node/service/src/parachains_db/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..519afbe0ccd13b088ae7a0efb5aa3c7fa3f16905 --- /dev/null +++ b/polkadot/node/service/src/parachains_db/mod.rs @@ -0,0 +1,177 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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. + +//! A `RocksDB` instance for storing parachain data; availability data, and approvals. + +#[cfg(feature = "full-node")] +use { + polkadot_node_subsystem_util::database::Database, std::io, std::path::PathBuf, std::sync::Arc, +}; + +#[cfg(feature = "full-node")] +mod upgrade; + +const LOG_TARGET: &str = "parachain::db"; + +/// Column configuration per version. +#[cfg(any(test, feature = "full-node"))] +pub(crate) mod columns { + pub mod v0 { + pub const NUM_COLUMNS: u32 = 3; + } + + pub mod v1 { + pub const NUM_COLUMNS: u32 = 5; + } + + pub mod v2 { + pub const NUM_COLUMNS: u32 = 6; + + #[cfg(test)] + pub const COL_SESSION_WINDOW_DATA: u32 = 5; + } + + pub mod v3 { + pub const NUM_COLUMNS: u32 = 5; + pub const COL_AVAILABILITY_DATA: u32 = 0; + pub const COL_AVAILABILITY_META: u32 = 1; + pub const COL_APPROVAL_DATA: u32 = 2; + pub const COL_CHAIN_SELECTION_DATA: u32 = 3; + pub const COL_DISPUTE_COORDINATOR_DATA: u32 = 4; + + pub const ORDERED_COL: &[u32] = + &[COL_AVAILABILITY_META, COL_CHAIN_SELECTION_DATA, COL_DISPUTE_COORDINATOR_DATA]; + } +} + +/// Columns used by different subsystems. +#[cfg(any(test, feature = "full-node"))] +#[derive(Debug, Clone)] +pub struct ColumnsConfig { + /// The column used by the av-store for data. + pub col_availability_data: u32, + /// The column used by the av-store for meta information. + pub col_availability_meta: u32, + /// The column used by approval voting for data. + pub col_approval_data: u32, + /// The column used by chain selection for data. + pub col_chain_selection_data: u32, + /// The column used by dispute coordinator for data. + pub col_dispute_coordinator_data: u32, +} + +/// The real columns used by the parachains DB. +#[cfg(any(test, feature = "full-node"))] +pub const REAL_COLUMNS: ColumnsConfig = ColumnsConfig { + col_availability_data: columns::v3::COL_AVAILABILITY_DATA, + col_availability_meta: columns::v3::COL_AVAILABILITY_META, + col_approval_data: columns::v3::COL_APPROVAL_DATA, + col_chain_selection_data: columns::v3::COL_CHAIN_SELECTION_DATA, + col_dispute_coordinator_data: columns::v3::COL_DISPUTE_COORDINATOR_DATA, +}; + +#[derive(PartialEq)] +pub(crate) enum DatabaseKind { + ParityDB, + RocksDB, +} + +/// The cache size for each column, in megabytes. +#[derive(Debug, Clone)] +pub struct CacheSizes { + /// Cache used by availability data. + pub availability_data: usize, + /// Cache used by availability meta. + pub availability_meta: usize, + /// Cache used by approval data. + pub approval_data: usize, + /// Cache used by session window data + pub session_data: usize, +} + +impl Default for CacheSizes { + fn default() -> Self { + CacheSizes { + availability_data: 25, + availability_meta: 1, + approval_data: 5, + session_data: 1, + } + } +} + +#[cfg(feature = "full-node")] +pub(crate) fn other_io_error(err: String) -> io::Error { + io::Error::new(io::ErrorKind::Other, err) +} + +/// Open the database on disk, creating it if it doesn't exist. +#[cfg(feature = "full-node")] +pub fn open_creating_rocksdb( + root: PathBuf, + cache_sizes: CacheSizes, +) -> io::Result> { + use kvdb_rocksdb::{Database, DatabaseConfig}; + + let path = root.join("parachains").join("db"); + + let mut db_config = DatabaseConfig::with_columns(columns::v3::NUM_COLUMNS); + + let _ = db_config + .memory_budget + .insert(columns::v3::COL_AVAILABILITY_DATA, cache_sizes.availability_data); + let _ = db_config + .memory_budget + .insert(columns::v3::COL_AVAILABILITY_META, cache_sizes.availability_meta); + let _ = db_config + .memory_budget + .insert(columns::v3::COL_APPROVAL_DATA, cache_sizes.approval_data); + + let path_str = path + .to_str() + .ok_or_else(|| other_io_error(format!("Bad database path: {:?}", path)))?; + + std::fs::create_dir_all(&path_str)?; + upgrade::try_upgrade_db(&path, DatabaseKind::RocksDB)?; + let db = Database::open(&db_config, &path_str)?; + let db = polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter::new( + db, + columns::v3::ORDERED_COL, + ); + + Ok(Arc::new(db)) +} + +/// Open a parity db database. +#[cfg(feature = "full-node")] +pub fn open_creating_paritydb( + root: PathBuf, + _cache_sizes: CacheSizes, +) -> io::Result> { + let path = root.join("parachains"); + let path_str = path + .to_str() + .ok_or_else(|| other_io_error(format!("Bad database path: {:?}", path)))?; + + std::fs::create_dir_all(&path_str)?; + upgrade::try_upgrade_db(&path, DatabaseKind::ParityDB)?; + + let db = parity_db::Db::open_or_create(&upgrade::paritydb_version_3_config(&path)) + .map_err(|err| io::Error::new(io::ErrorKind::Other, format!("{:?}", err)))?; + + let db = polkadot_node_subsystem_util::database::paritydb_impl::DbAdapter::new( + db, + columns::v3::ORDERED_COL, + ); + Ok(Arc::new(db)) +} diff --git a/polkadot/node/service/src/parachains_db/upgrade.rs b/polkadot/node/service/src/parachains_db/upgrade.rs new file mode 100644 index 0000000000000000000000000000000000000000..54ef97afd71c6ffacb643a08e59709838974ae3e --- /dev/null +++ b/polkadot/node/service/src/parachains_db/upgrade.rs @@ -0,0 +1,405 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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. + +//! Migration code for the parachain's DB. + +#![cfg(feature = "full-node")] + +use super::{columns, other_io_error, DatabaseKind, LOG_TARGET}; +use std::{ + fs, io, + path::{Path, PathBuf}, + str::FromStr, +}; + +type Version = u32; + +/// Version file name. +const VERSION_FILE_NAME: &'static str = "parachain_db_version"; + +/// Current db version. +const CURRENT_VERSION: Version = 3; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("I/O error when reading/writing the version")] + Io(#[from] io::Error), + #[error("The version file format is incorrect")] + CorruptedVersionFile, + #[error("Parachains DB has a future version (expected {current:?}, found {got:?})")] + FutureVersion { current: Version, got: Version }, +} + +impl From for io::Error { + fn from(me: Error) -> io::Error { + match me { + Error::Io(e) => e, + _ => super::other_io_error(me.to_string()), + } + } +} + +/// Try upgrading parachain's database to the current version. +pub(crate) fn try_upgrade_db(db_path: &Path, db_kind: DatabaseKind) -> Result<(), Error> { + let is_empty = db_path.read_dir().map_or(true, |mut d| d.next().is_none()); + if !is_empty { + match get_db_version(db_path)? { + // 0 -> 1 migration + Some(0) => migrate_from_version_0_to_1(db_path, db_kind)?, + // 1 -> 2 migration + Some(1) => migrate_from_version_1_to_2(db_path, db_kind)?, + // 2 -> 3 migration + Some(2) => migrate_from_version_2_to_3(db_path, db_kind)?, + // Already at current version, do nothing. + Some(CURRENT_VERSION) => (), + // This is an arbitrary future version, we don't handle it. + Some(v) => return Err(Error::FutureVersion { current: CURRENT_VERSION, got: v }), + // No version file. For `RocksDB` we dont need to do anything. + None if db_kind == DatabaseKind::RocksDB => (), + // No version file. `ParityDB` did not previously have a version defined. + // We handle this as a `0 -> 1` migration. + None if db_kind == DatabaseKind::ParityDB => + migrate_from_version_0_to_1(db_path, db_kind)?, + None => unreachable!(), + } + } + + update_version(db_path) +} + +/// Reads current database version from the file at given path. +/// If the file does not exist returns `None`, otherwise the version stored in the file. +fn get_db_version(path: &Path) -> Result, Error> { + match fs::read_to_string(version_file_path(path)) { + Err(ref err) if err.kind() == io::ErrorKind::NotFound => Ok(None), + Err(err) => Err(err.into()), + Ok(content) => u32::from_str(&content) + .map(|v| Some(v)) + .map_err(|_| Error::CorruptedVersionFile), + } +} + +/// Writes current database version to the file. +/// Creates a new file if the version file does not exist yet. +fn update_version(path: &Path) -> Result<(), Error> { + fs::create_dir_all(path)?; + fs::write(version_file_path(path), CURRENT_VERSION.to_string()).map_err(Into::into) +} + +/// Returns the version file path. +fn version_file_path(path: &Path) -> PathBuf { + let mut file_path = path.to_owned(); + file_path.push(VERSION_FILE_NAME); + file_path +} + +fn migrate_from_version_0_to_1(path: &Path, db_kind: DatabaseKind) -> Result<(), Error> { + gum::info!(target: LOG_TARGET, "Migrating parachains db from version 0 to version 1 ..."); + + match db_kind { + DatabaseKind::ParityDB => paritydb_migrate_from_version_0_to_1(path), + DatabaseKind::RocksDB => rocksdb_migrate_from_version_0_to_1(path), + } + .and_then(|result| { + gum::info!(target: LOG_TARGET, "Migration complete! "); + Ok(result) + }) +} + +fn migrate_from_version_1_to_2(path: &Path, db_kind: DatabaseKind) -> Result<(), Error> { + gum::info!(target: LOG_TARGET, "Migrating parachains db from version 1 to version 2 ..."); + + match db_kind { + DatabaseKind::ParityDB => paritydb_migrate_from_version_1_to_2(path), + DatabaseKind::RocksDB => rocksdb_migrate_from_version_1_to_2(path), + } + .and_then(|result| { + gum::info!(target: LOG_TARGET, "Migration complete! "); + Ok(result) + }) +} + +fn migrate_from_version_2_to_3(path: &Path, db_kind: DatabaseKind) -> Result<(), Error> { + gum::info!(target: LOG_TARGET, "Migrating parachains db from version 2 to version 3 ..."); + match db_kind { + DatabaseKind::ParityDB => paritydb_migrate_from_version_2_to_3(path), + DatabaseKind::RocksDB => rocksdb_migrate_from_version_2_to_3(path), + } + .and_then(|result| { + gum::info!(target: LOG_TARGET, "Migration complete! "); + Ok(result) + }) +} + +/// Migration from version 0 to version 1: +/// * the number of columns has changed from 3 to 5; +fn rocksdb_migrate_from_version_0_to_1(path: &Path) -> Result<(), Error> { + use kvdb_rocksdb::{Database, DatabaseConfig}; + + let db_path = path + .to_str() + .ok_or_else(|| super::other_io_error("Invalid database path".into()))?; + let db_cfg = DatabaseConfig::with_columns(super::columns::v0::NUM_COLUMNS); + let mut db = Database::open(&db_cfg, db_path)?; + + db.add_column()?; + db.add_column()?; + + Ok(()) +} + +/// Migration from version 1 to version 2: +/// * the number of columns has changed from 5 to 6; +fn rocksdb_migrate_from_version_1_to_2(path: &Path) -> Result<(), Error> { + use kvdb_rocksdb::{Database, DatabaseConfig}; + + let db_path = path + .to_str() + .ok_or_else(|| super::other_io_error("Invalid database path".into()))?; + let db_cfg = DatabaseConfig::with_columns(super::columns::v1::NUM_COLUMNS); + let mut db = Database::open(&db_cfg, db_path)?; + + db.add_column()?; + + Ok(()) +} + +fn rocksdb_migrate_from_version_2_to_3(path: &Path) -> Result<(), Error> { + use kvdb_rocksdb::{Database, DatabaseConfig}; + + let db_path = path + .to_str() + .ok_or_else(|| super::other_io_error("Invalid database path".into()))?; + let db_cfg = DatabaseConfig::with_columns(super::columns::v2::NUM_COLUMNS); + let mut db = Database::open(&db_cfg, db_path)?; + + db.remove_last_column()?; + + Ok(()) +} + +// This currently clears columns which had their configs altered between versions. +// The columns to be changed are constrained by the `allowed_columns` vector. +fn paritydb_fix_columns( + path: &Path, + options: parity_db::Options, + allowed_columns: Vec, +) -> io::Result<()> { + // Figure out which columns to delete. This will be determined by inspecting + // the metadata file. + if let Some(metadata) = parity_db::Options::load_metadata(&path) + .map_err(|e| other_io_error(format!("Error reading metadata {:?}", e)))? + { + let columns_to_clear = metadata + .columns + .into_iter() + .enumerate() + .filter(|(idx, _)| allowed_columns.contains(&(*idx as u32))) + .filter_map(|(idx, opts)| { + let changed = opts != options.columns[idx]; + if changed { + gum::debug!( + target: LOG_TARGET, + "Column {} will be cleared. Old options: {:?}, New options: {:?}", + idx, + opts, + options.columns[idx] + ); + Some(idx) + } else { + None + } + }) + .collect::>(); + + if columns_to_clear.len() > 0 { + gum::debug!( + target: LOG_TARGET, + "Database column changes detected, need to cleanup {} columns.", + columns_to_clear.len() + ); + } + + for column in columns_to_clear { + gum::debug!(target: LOG_TARGET, "Clearing column {}", column,); + parity_db::clear_column(path, column.try_into().expect("Invalid column ID")) + .map_err(|e| other_io_error(format!("Error clearing column {:?}", e)))?; + } + + // Write the updated column options. + options + .write_metadata(path, &metadata.salt) + .map_err(|e| other_io_error(format!("Error writing metadata {:?}", e)))?; + } + + Ok(()) +} + +/// Database configuration for version 1. +pub(crate) fn paritydb_version_1_config(path: &Path) -> parity_db::Options { + let mut options = + parity_db::Options::with_columns(&path, super::columns::v1::NUM_COLUMNS as u8); + for i in columns::v3::ORDERED_COL { + options.columns[*i as usize].btree_index = true; + } + + options +} + +/// Database configuration for version 2. +pub(crate) fn paritydb_version_2_config(path: &Path) -> parity_db::Options { + let mut options = + parity_db::Options::with_columns(&path, super::columns::v2::NUM_COLUMNS as u8); + for i in columns::v3::ORDERED_COL { + options.columns[*i as usize].btree_index = true; + } + + options +} + +/// Database configuration for version 3. +pub(crate) fn paritydb_version_3_config(path: &Path) -> parity_db::Options { + let mut options = + parity_db::Options::with_columns(&path, super::columns::v3::NUM_COLUMNS as u8); + for i in columns::v3::ORDERED_COL { + options.columns[*i as usize].btree_index = true; + } + + options +} + +/// Migration from version 0 to version 1. +/// Cases covered: +/// - upgrading from v0.9.23 or earlier -> the `dispute coordinator column` was changed +/// - upgrading from v0.9.24+ -> this is a no op assuming the DB has been manually fixed as per +/// release notes +fn paritydb_migrate_from_version_0_to_1(path: &Path) -> Result<(), Error> { + // Delete the `dispute coordinator` column if needed (if column configuration is changed). + paritydb_fix_columns( + path, + paritydb_version_1_config(path), + vec![super::columns::v3::COL_DISPUTE_COORDINATOR_DATA], + )?; + + Ok(()) +} + +/// Migration from version 1 to version 2: +/// - add a new column for session information storage +fn paritydb_migrate_from_version_1_to_2(path: &Path) -> Result<(), Error> { + let mut options = paritydb_version_1_config(path); + + // Adds the session info column. + parity_db::Db::add_column(&mut options, Default::default()) + .map_err(|e| other_io_error(format!("Error adding column {:?}", e)))?; + + Ok(()) +} + +/// Migration from version 2 to version 3: +/// - drop the column used by `RollingSessionWindow` +fn paritydb_migrate_from_version_2_to_3(path: &Path) -> Result<(), Error> { + parity_db::Db::drop_last_column(&mut paritydb_version_2_config(path)) + .map_err(|e| other_io_error(format!("Error removing COL_SESSION_WINDOW_DATA {:?}", e)))?; + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::{ + columns::{v2::COL_SESSION_WINDOW_DATA, v3::*}, + *, + }; + + #[test] + fn test_rocksdb_migrate_1_to_2() { + use kvdb::{DBKey, DBOp}; + use kvdb_rocksdb::{Database, DatabaseConfig}; + use polkadot_node_subsystem_util::database::{ + kvdb_impl::DbAdapter, DBTransaction, KeyValueDB, + }; + + let db_dir = tempfile::tempdir().unwrap(); + let db_path = db_dir.path().to_str().unwrap(); + let db_cfg = DatabaseConfig::with_columns(super::columns::v1::NUM_COLUMNS); + let db = Database::open(&db_cfg, db_path).unwrap(); + assert_eq!(db.num_columns(), super::columns::v1::NUM_COLUMNS as u32); + + // We need to properly set db version for upgrade to work. + fs::write(version_file_path(db_dir.path()), "1").expect("Failed to write DB version"); + { + let db = DbAdapter::new(db, columns::v3::ORDERED_COL); + db.write(DBTransaction { + ops: vec![DBOp::Insert { + col: COL_DISPUTE_COORDINATOR_DATA, + key: DBKey::from_slice(b"1234"), + value: b"0xdeadb00b".to_vec(), + }], + }) + .unwrap(); + } + + try_upgrade_db(&db_dir.path(), DatabaseKind::RocksDB).unwrap(); + + let db_cfg = DatabaseConfig::with_columns(super::columns::v2::NUM_COLUMNS); + let db = Database::open(&db_cfg, db_path).unwrap(); + + assert_eq!(db.num_columns(), super::columns::v2::NUM_COLUMNS); + + let db = DbAdapter::new(db, columns::v3::ORDERED_COL); + + assert_eq!( + db.get(COL_DISPUTE_COORDINATOR_DATA, b"1234").unwrap(), + Some("0xdeadb00b".as_bytes().to_vec()) + ); + + // Test we can write the new column. + db.write(DBTransaction { + ops: vec![DBOp::Insert { + col: COL_SESSION_WINDOW_DATA, + key: DBKey::from_slice(b"1337"), + value: b"0xdeadb00b".to_vec(), + }], + }) + .unwrap(); + + // Read back data from new column. + assert_eq!( + db.get(COL_SESSION_WINDOW_DATA, b"1337").unwrap(), + Some("0xdeadb00b".as_bytes().to_vec()) + ); + } + + #[test] + fn test_rocksdb_migrate_2_to_3() { + use kvdb_rocksdb::{Database, DatabaseConfig}; + + let db_dir = tempfile::tempdir().unwrap(); + let db_path = db_dir.path().to_str().unwrap(); + let db_cfg = DatabaseConfig::with_columns(super::columns::v2::NUM_COLUMNS); + { + let db = Database::open(&db_cfg, db_path).unwrap(); + assert_eq!(db.num_columns(), super::columns::v2::NUM_COLUMNS as u32); + } + + // We need to properly set db version for upgrade to work. + fs::write(version_file_path(db_dir.path()), "2").expect("Failed to write DB version"); + + try_upgrade_db(&db_dir.path(), DatabaseKind::RocksDB).unwrap(); + + let db_cfg = DatabaseConfig::with_columns(super::columns::v3::NUM_COLUMNS); + let db = Database::open(&db_cfg, db_path).unwrap(); + + assert_eq!(db.num_columns(), super::columns::v3::NUM_COLUMNS); + } +} diff --git a/polkadot/node/service/src/relay_chain_selection.rs b/polkadot/node/service/src/relay_chain_selection.rs new file mode 100644 index 0000000000000000000000000000000000000000..189073783f0dc53eb06ceafe9015e9fd806b1f9e --- /dev/null +++ b/polkadot/node/service/src/relay_chain_selection.rs @@ -0,0 +1,588 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A [`SelectChain`] implementation designed for relay chains. +//! +//! This uses information about parachains to inform GRANDPA and BABE +//! about blocks which are safe to build on and blocks which are safe to +//! finalize. +//! +//! To learn more about chain-selection rules for Relay Chains, please see the +//! documentation on [chain-selection][chain-selection-guide] +//! in the implementers' guide. +//! +//! This is mostly a wrapper around a subsystem which implements the +//! chain-selection rule, which leaves the code to be very simple. +//! +//! However, this does apply the further finality constraints to the best +//! leaf returned from the chain selection subsystem by calling into other +//! subsystems which yield information about approvals and disputes. +//! +//! [chain-selection-guide]: https://w3f.github.io/parachain-implementers-guide/protocol-chain-selection.html + +#![cfg(feature = "full-node")] + +use super::{HeaderProvider, HeaderProviderProvider}; +use consensus_common::{Error as ConsensusError, SelectChain}; +use futures::channel::oneshot; +use polkadot_node_primitives::MAX_FINALITY_LAG as PRIMITIVES_MAX_FINALITY_LAG; +use polkadot_node_subsystem::messages::{ + ApprovalDistributionMessage, ApprovalVotingMessage, ChainSelectionMessage, + DisputeCoordinatorMessage, HighestApprovedAncestorBlock, +}; +use polkadot_node_subsystem_util::metrics::{self, prometheus}; +use polkadot_overseer::{AllMessages, Handle}; +use polkadot_primitives::{Block as PolkadotBlock, BlockNumber, Hash, Header as PolkadotHeader}; +use std::sync::Arc; + +pub use service::SpawnTaskHandle; + +/// The maximum amount of unfinalized blocks we are willing to allow due to approval checking +/// or disputes. +/// +/// This is a safety net that should be removed at some point in the future. +// In sync with `MAX_HEADS_LOOK_BACK` in `approval-voting` +// and `MAX_BATCH_SCRAPE_ANCESTORS` in `dispute-coordinator`. +const MAX_FINALITY_LAG: polkadot_primitives::BlockNumber = PRIMITIVES_MAX_FINALITY_LAG; + +const LOG_TARGET: &str = "parachain::chain-selection"; + +/// Prometheus metrics for chain-selection. +#[derive(Debug, Default, Clone)] +pub struct Metrics(Option); + +#[derive(Debug, Clone)] +struct MetricsInner { + approval_checking_finality_lag: prometheus::Gauge, + disputes_finality_lag: prometheus::Gauge, +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + approval_checking_finality_lag: prometheus::register( + prometheus::Gauge::with_opts( + prometheus::Opts::new( + "polkadot_parachain_approval_checking_finality_lag", + "How far behind the head of the chain the Approval Checking protocol wants to vote", + ) + )?, + registry, + )?, + disputes_finality_lag: prometheus::register( + prometheus::Gauge::with_opts( + prometheus::Opts::new( + "polkadot_parachain_disputes_finality_lag", + "How far behind the head of the chain the Disputes protocol wants to vote", + ) + )?, + registry, + )?, + }; + + Ok(Metrics(Some(metrics))) + } +} + +impl Metrics { + fn note_approval_checking_finality_lag(&self, lag: BlockNumber) { + if let Some(ref metrics) = self.0 { + metrics.approval_checking_finality_lag.set(lag as _); + } + } + + fn note_disputes_finality_lag(&self, lag: BlockNumber) { + if let Some(ref metrics) = self.0 { + metrics.disputes_finality_lag.set(lag as _); + } + } +} + +/// Determines whether the chain is a relay chain +/// and hence has to take approval votes and disputes +/// into account. +enum IsDisputesAwareWithOverseer> { + Yes(SelectRelayChainInner), + No, +} + +impl Clone for IsDisputesAwareWithOverseer +where + B: sc_client_api::Backend, + SelectRelayChainInner: Clone, +{ + fn clone(&self) -> Self { + match self { + Self::Yes(ref inner) => Self::Yes(inner.clone()), + Self::No => Self::No, + } + } +} + +/// A chain-selection implementation which provides safety for relay chains. +pub struct SelectRelayChain> { + longest_chain: sc_consensus::LongestChain, + selection: IsDisputesAwareWithOverseer, +} + +impl Clone for SelectRelayChain +where + B: sc_client_api::Backend, + SelectRelayChainInner: Clone, +{ + fn clone(&self) -> Self { + Self { longest_chain: self.longest_chain.clone(), selection: self.selection.clone() } + } +} + +impl SelectRelayChain +where + B: sc_client_api::Backend + 'static, +{ + /// Use the plain longest chain algorithm exclusively. + pub fn new_longest_chain(backend: Arc) -> Self { + gum::debug!(target: LOG_TARGET, "Using {} chain selection algorithm", "longest"); + + Self { + longest_chain: sc_consensus::LongestChain::new(backend.clone()), + selection: IsDisputesAwareWithOverseer::No, + } + } + + /// Create a new [`SelectRelayChain`] wrapping the given chain backend + /// and a handle to the overseer. + pub fn new_with_overseer( + backend: Arc, + overseer: Handle, + metrics: Metrics, + spawn_handle: Option, + ) -> Self { + gum::debug!(target: LOG_TARGET, "Using dispute aware relay-chain selection algorithm",); + + SelectRelayChain { + longest_chain: sc_consensus::LongestChain::new(backend.clone()), + selection: IsDisputesAwareWithOverseer::Yes(SelectRelayChainInner::new( + backend, + overseer, + metrics, + spawn_handle, + )), + } + } + + /// Allow access to the inner chain, for usage during the node setup. + pub fn as_longest_chain(&self) -> &sc_consensus::LongestChain { + &self.longest_chain + } +} + +#[async_trait::async_trait] +impl SelectChain for SelectRelayChain +where + B: sc_client_api::Backend + 'static, +{ + async fn leaves(&self) -> Result, ConsensusError> { + match self.selection { + IsDisputesAwareWithOverseer::Yes(ref selection) => selection.leaves().await, + IsDisputesAwareWithOverseer::No => self.longest_chain.leaves().await, + } + } + + async fn best_chain(&self) -> Result { + match self.selection { + IsDisputesAwareWithOverseer::Yes(ref selection) => selection.best_chain().await, + IsDisputesAwareWithOverseer::No => self.longest_chain.best_chain().await, + } + } + + async fn finality_target( + &self, + target_hash: Hash, + maybe_max_number: Option, + ) -> Result { + if let IsDisputesAwareWithOverseer::Yes(ref selection) = self.selection { + selection + .finality_target_with_longest_chain(target_hash, maybe_max_number) + .await + } else { + self.longest_chain.finality_target(target_hash, maybe_max_number).await + } + } +} + +/// A chain-selection implementation which provides safety for relay chains +/// but does not handle situations where the overseer is not yet connected. +pub struct SelectRelayChainInner { + backend: Arc, + overseer: OH, + metrics: Metrics, + spawn_handle: Option, +} + +impl SelectRelayChainInner +where + B: HeaderProviderProvider, + OH: OverseerHandleT, +{ + /// Create a new [`SelectRelayChainInner`] wrapping the given chain backend + /// and a handle to the overseer. + pub fn new( + backend: Arc, + overseer: OH, + metrics: Metrics, + spawn_handle: Option, + ) -> Self { + SelectRelayChainInner { backend, overseer, metrics, spawn_handle } + } + + fn block_header(&self, hash: Hash) -> Result { + match HeaderProvider::header(self.backend.header_provider(), hash) { + Ok(Some(header)) => Ok(header), + Ok(None) => + Err(ConsensusError::ChainLookup(format!("Missing header with hash {:?}", hash,))), + Err(e) => Err(ConsensusError::ChainLookup(format!( + "Lookup failed for header with hash {:?}: {:?}", + hash, e, + ))), + } + } + + fn block_number(&self, hash: Hash) -> Result { + match HeaderProvider::number(self.backend.header_provider(), hash) { + Ok(Some(number)) => Ok(number), + Ok(None) => + Err(ConsensusError::ChainLookup(format!("Missing number with hash {:?}", hash,))), + Err(e) => Err(ConsensusError::ChainLookup(format!( + "Lookup failed for number with hash {:?}: {:?}", + hash, e, + ))), + } + } +} + +impl Clone for SelectRelayChainInner +where + B: HeaderProviderProvider + Send + Sync, + OH: OverseerHandleT, +{ + fn clone(&self) -> Self { + SelectRelayChainInner { + backend: self.backend.clone(), + overseer: self.overseer.clone(), + metrics: self.metrics.clone(), + spawn_handle: self.spawn_handle.clone(), + } + } +} + +#[derive(thiserror::Error, Debug)] +enum Error { + // Oneshot for requesting leaves from chain selection got canceled - check errors in that + // subsystem. + #[error("Request for leaves from chain selection got canceled")] + LeavesCanceled(oneshot::Canceled), + #[error("Request for leaves from chain selection got canceled")] + BestLeafContainingCanceled(oneshot::Canceled), + // Requesting recent disputes oneshot got canceled. + #[error("Request for determining the undisputed chain from DisputeCoordinator got canceled")] + DetermineUndisputedChainCanceled(oneshot::Canceled), + #[error("Request approved ancestor from approval voting got canceled")] + ApprovedAncestorCanceled(oneshot::Canceled), + /// Chain selection returned empty leaves. + #[error("ChainSelection returned no leaves")] + EmptyLeaves, +} + +/// Decoupling trait for the overseer handle. +/// +/// Required for testing purposes. +#[async_trait::async_trait] +pub trait OverseerHandleT: Clone + Send + Sync { + async fn send_msg>(&mut self, msg: M, origin: &'static str); +} + +#[async_trait::async_trait] +impl OverseerHandleT for Handle { + async fn send_msg>(&mut self, msg: M, origin: &'static str) { + Handle::send_msg(self, msg, origin).await + } +} + +impl SelectRelayChainInner +where + B: HeaderProviderProvider, + OH: OverseerHandleT + 'static, +{ + /// Get all leaves of the chain, i.e. block hashes that are suitable to + /// build upon and have no suitable children. + async fn leaves(&self) -> Result, ConsensusError> { + let (tx, rx) = oneshot::channel(); + + self.overseer + .clone() + .send_msg(ChainSelectionMessage::Leaves(tx), std::any::type_name::()) + .await; + + let leaves = rx + .await + .map_err(Error::LeavesCanceled) + .map_err(|e| ConsensusError::Other(Box::new(e)))?; + + gum::trace!(target: LOG_TARGET, ?leaves, "Chain selection leaves"); + + Ok(leaves) + } + + /// Among all leaves, pick the one which is the best chain to build upon. + async fn best_chain(&self) -> Result { + // The Chain Selection subsystem is supposed to treat the finalized + // block as the best leaf in the case that there are no viable + // leaves, so this should not happen in practice. + let best_leaf = *self + .leaves() + .await? + .first() + .ok_or_else(|| ConsensusError::Other(Box::new(Error::EmptyLeaves)))?; + + gum::trace!(target: LOG_TARGET, ?best_leaf, "Best chain"); + + self.block_header(best_leaf) + } + + /// Get the best descendant of `target_hash` that we should attempt to + /// finalize next, if any. It is valid to return the `target_hash` if + /// no better block exists. + /// + /// This will search all leaves to find the best one containing the + /// given target hash, and then constrain to the given block number. + /// + /// It will also constrain the chain to only chains which are fully + /// approved, and chains which contain no disputes. + pub(crate) async fn finality_target_with_longest_chain( + &self, + target_hash: Hash, + maybe_max_number: Option, + ) -> Result { + let mut overseer = self.overseer.clone(); + + let subchain_head = { + let (tx, rx) = oneshot::channel(); + overseer + .send_msg( + ChainSelectionMessage::BestLeafContaining(target_hash, tx), + std::any::type_name::(), + ) + .await; + + let best = rx + .await + .map_err(Error::BestLeafContainingCanceled) + .map_err(|e| ConsensusError::Other(Box::new(e)))?; + + gum::trace!(target: LOG_TARGET, ?best, "Best leaf containing"); + + match best { + // No viable leaves containing the block. + None => return Ok(target_hash), + Some(best) => best, + } + }; + + let target_number = self.block_number(target_hash)?; + + // 1. Constrain the leaf according to `maybe_max_number`. + let subchain_head = match maybe_max_number { + None => subchain_head, + Some(max) => { + if max <= target_number { + if max < target_number { + gum::warn!( + LOG_TARGET, + max_number = max, + target_number, + "`finality_target` max number is less than target number", + ); + } + return Ok(target_hash) + } + // find the current number. + let subchain_header = self.block_header(subchain_head)?; + + if subchain_header.number <= max { + gum::trace!(target: LOG_TARGET, ?subchain_head, "Constrained sub-chain head",); + subchain_head + } else { + let (ancestor_hash, _) = + crate::grandpa_support::walk_backwards_to_target_block( + self.backend.header_provider(), + max, + &subchain_header, + ) + .map_err(|e| ConsensusError::ChainLookup(format!("{:?}", e)))?; + gum::trace!( + target: LOG_TARGET, + ?ancestor_hash, + "Grandpa walk backwards sub-chain head" + ); + ancestor_hash + } + }, + }; + + let initial_leaf = subchain_head; + let initial_leaf_number = self.block_number(initial_leaf)?; + + // 2. Constrain according to `ApprovedAncestor`. + let (subchain_head, subchain_number, subchain_block_descriptions) = { + let (tx, rx) = oneshot::channel(); + overseer + .send_msg( + ApprovalVotingMessage::ApprovedAncestor(subchain_head, target_number, tx), + std::any::type_name::(), + ) + .await; + + match rx + .await + .map_err(Error::ApprovedAncestorCanceled) + .map_err(|e| ConsensusError::Other(Box::new(e)))? + { + // No approved ancestors means target hash is maximal vote. + None => (target_hash, target_number, Vec::new()), + Some(HighestApprovedAncestorBlock { number, hash, descriptions }) => + (hash, number, descriptions), + } + }; + + gum::trace!(target: LOG_TARGET, ?subchain_head, "Ancestor approval restriction applied",); + + let lag = initial_leaf_number.saturating_sub(subchain_number); + self.metrics.note_approval_checking_finality_lag(lag); + + // Messages sent to `approval-distrbution` are known to have high `ToF`, we need to spawn a + // task for sending the message to not block here and delay finality. + if let Some(spawn_handle) = &self.spawn_handle { + let mut overseer_handle = self.overseer.clone(); + let lag_update_task = async move { + overseer_handle + .send_msg( + ApprovalDistributionMessage::ApprovalCheckingLagUpdate(lag), + std::any::type_name::(), + ) + .await; + }; + + spawn_handle.spawn( + "approval-checking-lag-update", + Some("relay-chain-selection"), + Box::pin(lag_update_task), + ); + } + + let (lag, subchain_head) = { + // Prevent sending flawed data to the dispute-coordinator. + if Some(subchain_block_descriptions.len() as _) != + subchain_number.checked_sub(target_number) + { + gum::error!( + LOG_TARGET, + present_block_descriptions = subchain_block_descriptions.len(), + target_number, + subchain_number, + "Mismatch of anticipated block descriptions and block number difference.", + ); + return Ok(target_hash) + } + // 3. Constrain according to disputes: + let (tx, rx) = oneshot::channel(); + overseer + .send_msg( + DisputeCoordinatorMessage::DetermineUndisputedChain { + base: (target_number, target_hash), + block_descriptions: subchain_block_descriptions, + tx, + }, + std::any::type_name::(), + ) + .await; + + // Try to fetch response from `dispute-coordinator`. If an error occurs we just log it + // and return `target_hash` as maximal vote. It is safer to contain this error here + // and not push it up the stack to cause additional issues in GRANDPA/BABE. + let (lag, subchain_head) = + match rx.await.map_err(Error::DetermineUndisputedChainCanceled) { + // If request succeded we will receive (block number, block hash). + Ok((subchain_number, subchain_head)) => { + // The total lag accounting for disputes. + let lag_disputes = initial_leaf_number.saturating_sub(subchain_number); + self.metrics.note_disputes_finality_lag(lag_disputes); + (lag_disputes, subchain_head) + }, + Err(e) => { + gum::error!( + target: LOG_TARGET, + error = ?e, + "Call to `DetermineUndisputedChain` failed", + ); + // We need to return a sane finality target. But, we are unable to ensure we + // are not finalizing something that is being disputed or has been concluded + // as invalid. We will be conservative here and not vote for finality above + // the ancestor passed in. + return Ok(target_hash) + }, + }; + (lag, subchain_head) + }; + + gum::trace!( + target: LOG_TARGET, + ?subchain_head, + "Disputed blocks in ancestry restriction applied", + ); + + // 4. Apply the maximum safeguard to the finality lag. + if lag > MAX_FINALITY_LAG { + // We need to constrain our vote as a safety net to + // ensure the network continues to finalize. + let safe_target = initial_leaf_number - MAX_FINALITY_LAG; + + if safe_target <= target_number { + gum::warn!(target: LOG_TARGET, ?target_hash, "Safeguard enforced finalization"); + // Minimal vote needs to be on the target number. + Ok(target_hash) + } else { + // Otherwise we're looking for a descendant. + let initial_leaf_header = self.block_header(initial_leaf)?; + let (forced_target, _) = crate::grandpa_support::walk_backwards_to_target_block( + self.backend.header_provider(), + safe_target, + &initial_leaf_header, + ) + .map_err(|e| ConsensusError::ChainLookup(format!("{:?}", e)))?; + + gum::warn!( + target: LOG_TARGET, + ?forced_target, + "Safeguard enforced finalization of child" + ); + + Ok(forced_target) + } + } else { + Ok(subchain_head) + } + } +} diff --git a/polkadot/node/service/src/tests.rs b/polkadot/node/service/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..86119662d9bc08e7ed33999e1b7c78cd0749e154 --- /dev/null +++ b/polkadot/node/service/src/tests.rs @@ -0,0 +1,767 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::{relay_chain_selection::*, *}; + +use futures::channel::oneshot::Receiver; +use polkadot_node_primitives::approval::VrfSignature; +use polkadot_node_subsystem::messages::{AllMessages, BlockDescription}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_node_subsystem_util::TimeoutExt; +use polkadot_test_client::Sr25519Keyring; +use sp_consensus_babe::{ + digests::{CompatibleDigestItem, PreDigest, SecondaryVRFPreDigest}, + VrfTranscript, +}; +use sp_core::{crypto::VrfSecret, testing::TaskExecutor}; +use sp_runtime::{testing::*, DigestItem}; +use std::{ + collections::{BTreeMap, HashMap, HashSet}, + iter::IntoIterator, +}; + +use assert_matches::assert_matches; +use std::{sync::Arc, time::Duration}; + +use futures::{channel::oneshot, prelude::*}; +use polkadot_node_subsystem::messages::{ + ApprovalVotingMessage, ChainSelectionMessage, DisputeCoordinatorMessage, + HighestApprovedAncestorBlock, +}; +use polkadot_primitives::{Block, BlockNumber, Hash, Header}; + +use polkadot_node_subsystem_test_helpers::TestSubsystemSender; +use polkadot_overseer::{SubsystemContext, SubsystemSender}; + +type VirtualOverseer = test_helpers::TestSubsystemContextHandle; + +#[async_trait::async_trait] +impl OverseerHandleT for TestSubsystemSender { + async fn send_msg>(&mut self, msg: M, _origin: &'static str) { + TestSubsystemSender::send_message(self, msg.into()).await; + } +} + +struct TestHarness { + virtual_overseer: VirtualOverseer, + case_vars: CaseVars, + /// The result of `fn finality_target` will be injected into the + /// harness scope via this channel. + finality_target_rx: Receiver>, +} + +#[derive(Default)] +struct HarnessConfig; + +fn test_harness>( + case_vars: CaseVars, + test: impl FnOnce(TestHarness) -> T, +) { + let _ = env_logger::builder() + .is_test(true) + .filter_level(log::LevelFilter::Trace) + .try_init(); + + let pool = TaskExecutor::new(); + let (mut context, virtual_overseer) = test_helpers::make_subsystem_context(pool); + + let (finality_target_tx, finality_target_rx) = oneshot::channel::>(); + + let select_relay_chain = SelectRelayChainInner::::new( + Arc::new(case_vars.chain.clone()), + context.sender().clone(), + Default::default(), + None, + ); + + let target_hash = case_vars.target_block; + let selection_process = async move { + let best = select_relay_chain + .finality_target_with_longest_chain(target_hash, None) + .await + .unwrap(); + finality_target_tx.send(Some(best)).unwrap(); + () + }; + + let test_fut = test(TestHarness { virtual_overseer, case_vars, finality_target_rx }); + + futures::pin_mut!(test_fut); + futures::pin_mut!(selection_process); + futures::executor::block_on(future::join( + async move { + let _overseer = test_fut.await; + }, + selection_process, + )); +} + +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { + let msg = overseer_recv_with_timeout(overseer, TIMEOUT) + .await + .expect(&format!("{:?} is enough to receive messages.", TIMEOUT)); + + gum::trace!("Received message:\n{:?}", &msg); + + msg +} +async fn overseer_recv_with_timeout( + overseer: &mut VirtualOverseer, + timeout: Duration, +) -> Option { + gum::trace!("Waiting for message..."); + overseer.recv().timeout(timeout).await +} + +const TIMEOUT: Duration = Duration::from_millis(2000); + +// used for generating assignments where the validity of the VRF doesn't matter. +fn garbage_vrf_signature() -> VrfSignature { + let transcript = VrfTranscript::new(b"test-garbage", &[]); + Sr25519Keyring::Alice.pair().vrf_sign(&transcript.into()) +} + +/// Representation of a local representation +/// to extract information for finalization target +/// extraction. +#[derive(Debug, Default, Clone)] +struct TestChainStorage { + blocks_by_hash: HashMap, + blocks_at_height: BTreeMap>, + disputed_blocks: HashSet, + approved_blocks: HashSet, + heads: HashSet, +} + +impl TestChainStorage { + /// Fill the [`HighestApprovedAncestor`] structure with mostly + /// correct data. + pub fn highest_approved_ancestors( + &self, + minimum_block_number: BlockNumber, + leaf: Hash, + ) -> Option { + let mut descriptions = Vec::new(); + let mut block_hash = leaf; + let mut highest_approved_ancestor = None; + + while let Some(block) = self.blocks_by_hash.get(&block_hash) { + if minimum_block_number >= block.number { + break + } + if !self.approved_blocks.contains(&block_hash) { + highest_approved_ancestor = None; + descriptions.clear(); + } else { + if highest_approved_ancestor.is_none() { + highest_approved_ancestor = Some((block_hash, block.number)); + } + descriptions.push(BlockDescription { + session: 1 as _, // dummy, not checked + block_hash, + candidates: vec![], // not relevant for any test cases + }); + } + block_hash = *block.parent_hash(); + } + + highest_approved_ancestor.map(|(hash, number)| HighestApprovedAncestorBlock { + hash, + number, + descriptions: descriptions.into_iter().rev().collect(), + }) + } + + /// Traverse backwards from leave down to block number. + fn undisputed_chain( + &self, + base_blocknumber: BlockNumber, + highest_approved_block_hash: Hash, + ) -> Option { + if self.disputed_blocks.is_empty() { + return Some(highest_approved_block_hash) + } + + let mut undisputed_chain = Some(highest_approved_block_hash); + let mut block_hash = highest_approved_block_hash; + while let Some(block) = self.blocks_by_hash.get(&block_hash) { + let next = block.parent_hash(); + if self.disputed_blocks.contains(&block_hash) { + undisputed_chain = Some(*next); + } + if block.number() == &base_blocknumber { + break + } + block_hash = *next; + } + undisputed_chain + } +} + +impl HeaderProvider for TestChainStorage { + fn header(&self, hash: Hash) -> sp_blockchain::Result> { + Ok(self.blocks_by_hash.get(&hash).cloned()) + } + fn number(&self, hash: Hash) -> sp_blockchain::Result> { + self.header(hash).map(|opt| opt.map(|h| h.number)) + } +} + +impl HeaderProviderProvider for TestChainStorage { + type Provider = Self; + fn header_provider(&self) -> &Self { + self + } +} + +#[derive(Debug, Clone)] +struct ChainBuilder(pub TestChainStorage); + +impl ChainBuilder { + const GENESIS_HASH: Hash = Hash::repeat_byte(0xff); + const GENESIS_PARENT_HASH: Hash = Hash::repeat_byte(0x00); + + pub fn new() -> Self { + let mut builder = Self(TestChainStorage::default()); + let _ = builder.add_block_inner(Self::GENESIS_HASH, Self::GENESIS_PARENT_HASH, 0); + builder + } + + pub fn add_block(&mut self, hash: Hash, parent_hash: Hash, number: u32) -> &mut Self { + assert!(number != 0, "cannot add duplicate genesis block"); + assert!(hash != Self::GENESIS_HASH, "cannot add block with genesis hash"); + assert!( + parent_hash != Self::GENESIS_PARENT_HASH, + "cannot add block with genesis parent hash" + ); + assert!(self.0.blocks_by_hash.len() < u8::MAX.into()); + self.add_block_inner(hash, parent_hash, number) + } + + fn add_block_inner(&mut self, hash: Hash, parent_hash: Hash, number: u32) -> &mut Self { + let header = ChainBuilder::make_header(parent_hash, number); + assert!( + self.0.blocks_by_hash.insert(hash, header).is_none(), + "block with hash {:?} already exists", + hash, + ); + self.0.blocks_at_height.entry(number).or_insert_with(Vec::new).push(hash); + self + } + + pub fn fast_forward_approved( + &mut self, + branch_tag: u8, + parent: Hash, + block_number: BlockNumber, + ) -> Hash { + let block = self.fast_forward(branch_tag, parent, block_number); + let _ = self.0.approved_blocks.insert(block); + block + } + + /// Add a relay chain block that contains a disputed parachain block. + /// For simplicity this is not modeled explicitly. + pub fn fast_forward_disputed( + &mut self, + branch_tag: u8, + parent: Hash, + block_number: BlockNumber, + ) -> Hash { + let block = self.fast_forward_approved(branch_tag, parent, block_number); + let _ = self.0.disputed_blocks.insert(block); + block + } + + pub fn fast_forward( + &mut self, + branch_tag: u8, + parent: Hash, + block_number: BlockNumber, + ) -> Hash { + let hash = Hash::repeat_byte((block_number as u8 | branch_tag) as u8); + let _ = self.add_block(hash, parent, block_number); + hash + } + + pub fn set_heads(&mut self, heads: impl IntoIterator) { + self.0.heads = heads.into_iter().collect(); + } + + pub fn init(self) -> TestChainStorage { + self.0 + } + + fn make_header(parent_hash: Hash, number: u32) -> Header { + let digest = { + let mut digest = Digest::default(); + let vrf_signature = garbage_vrf_signature(); + digest.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF( + SecondaryVRFPreDigest { + authority_index: 0, + slot: 1.into(), // slot, unused + vrf_signature, + }, + ))); + digest + }; + + Header { + digest, + extrinsics_root: Default::default(), + number, + state_root: Default::default(), + parent_hash, + } + } +} + +/// Generalized sequence of the test, based on +/// the messages being sent out by the `fn finality_target` +/// Depends on a particular `target_hash` +/// that is passed to `finality_target` block number. +async fn test_skeleton( + chain: &TestChainStorage, + virtual_overseer: &mut VirtualOverseer, + target_block_hash: Hash, + best_chain_containing_block: Option, + highest_approved_ancestor_block: Option, + undisputed_chain: Option, +) { + let undisputed_chain = undisputed_chain.map(|x| (chain.number(x).unwrap().unwrap(), x)); + + gum::trace!("best leaf response: {:?}", undisputed_chain); + assert_matches!( + overseer_recv( + virtual_overseer + ).await, + AllMessages::ChainSelection(ChainSelectionMessage::BestLeafContaining( + target_hash, + tx, + )) + => { + assert_eq!(target_block_hash, target_hash, "TestIntegrity: target hashes always match. qed"); + tx.send(best_chain_containing_block).unwrap(); + } + ); + + if best_chain_containing_block.is_none() { + return + } + + gum::trace!("approved ancestor response: {:?}", undisputed_chain); + assert_matches!( + overseer_recv( + virtual_overseer + ).await, + AllMessages::ApprovalVoting(ApprovalVotingMessage::ApprovedAncestor(_block_hash, _block_number, tx)) + => { + tx.send(highest_approved_ancestor_block.clone()).unwrap(); + } + ); + + gum::trace!("determine undisputed chain response: {:?}", undisputed_chain); + + let target_block_number = chain.number(target_block_hash).unwrap().unwrap(); + assert_matches!( + overseer_recv( + virtual_overseer + ).await, + AllMessages::DisputeCoordinator( + DisputeCoordinatorMessage::DetermineUndisputedChain { + base: _, + block_descriptions: _, + tx, + } + ) => { + tx.send(undisputed_chain.unwrap_or((target_block_number, target_block_hash))).unwrap(); + }); +} + +/// Straight forward test case, where the test is not +/// for integrity, but for different block relation structures. +fn run_specialized_test_w_harness CaseVars>(case_var_provider: F) { + test_harness(case_var_provider(), |test_harness| async move { + let TestHarness { + mut virtual_overseer, + finality_target_rx, + case_vars: + CaseVars { + chain, + target_block, + best_chain_containing_block, + highest_approved_ancestor_block, + undisputed_chain, + expected_finality_target_result, + }, + .. + } = test_harness; + + // Verify test integrity: the provided highest approved + // ancestor must match the chain derived one. + let highest_approved_ancestor_w_desc = best_chain_containing_block + .and_then(|best_chain_containing_block| { + chain.blocks_by_hash.get(&target_block).map(|target_block_header| { + let target_blocknumber = target_block_header.number; + let highest_approved_ancestor_w_desc = chain.highest_approved_ancestors( + target_blocknumber, + best_chain_containing_block, + ); + if let ( + Some(highest_approved_ancestor_w_desc), + Some(highest_approved_ancestor_block), + ) = (&highest_approved_ancestor_w_desc, highest_approved_ancestor_block) + { + assert_eq!( + highest_approved_ancestor_block, highest_approved_ancestor_w_desc.hash, + "TestCaseIntegrity: Provided and expected approved ancestor hash mismatch: {:?} vs {:?}", + highest_approved_ancestor_block, highest_approved_ancestor_w_desc.hash, + ); + + let expected = chain + .undisputed_chain(target_blocknumber, highest_approved_ancestor_block); + + assert_eq!( + expected, undisputed_chain, + "TestCaseIntegrity: Provided and anticipated undisputed chain mismatch: {:?} vs {:?}", + undisputed_chain, expected, + ); + } + highest_approved_ancestor_w_desc + }) + }) + .flatten(); + + test_skeleton( + &chain, + &mut virtual_overseer, + target_block, + best_chain_containing_block, + highest_approved_ancestor_w_desc, + undisputed_chain, + ) + .await; + + assert_matches!(finality_target_rx.await, + Ok( + finality_target_val, + ) => assert_eq!(expected_finality_target_result, finality_target_val)); + + virtual_overseer + }); +} + +/// All variables relevant for a test case. +#[derive(Clone, Debug)] +struct CaseVars { + /// Chain test _case_ definition. + chain: TestChainStorage, + + /// The target block to be finalized. + target_block: Hash, + + /// Response to the `target_block` request, must be a chain-head. + /// `None` if no such chain exists. + best_chain_containing_block: Option, + + /// Resulting best estimate, before considering + /// the disputed state of blocks. + highest_approved_ancestor_block: Option, + + /// Equal to the previous, unless there are disputes. + /// The backtracked version of this must _never_ + /// contain a disputed block. + undisputed_chain: Option, + + /// The returned value by `fn finality_target`. + expected_finality_target_result: Option, +} + +/// ```raw +/// genesis -- 0xA1 --- 0xA2 --- 0xA3 --- 0xA4(!avail) --- 0xA5(!avail) +/// \ +/// `- 0xB2 +/// ``` +fn chain_undisputed() -> CaseVars { + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + + let a1 = builder.fast_forward_approved(0xA0, head, 1); + let a2 = builder.fast_forward_approved(0xA0, a1, 2); + let a3 = builder.fast_forward_approved(0xA0, a2, 3); + let a4 = builder.fast_forward(0xA0, a3, 4); + let a5 = builder.fast_forward(0xA0, a4, 5); + + let b1 = builder.fast_forward_approved(0xB0, a1, 2); + let b2 = builder.fast_forward_approved(0xB0, b1, 3); + let b3 = builder.fast_forward_approved(0xB0, b2, 4); + + builder.set_heads(vec![a5, b3]); + + CaseVars { + chain: builder.init(), + target_block: a1, + best_chain_containing_block: Some(a5), + highest_approved_ancestor_block: Some(a3), + undisputed_chain: Some(a3), + expected_finality_target_result: Some(a3), + } +} + +/// ```raw +/// genesis -- 0xA1 --- 0xA2 --- 0xA3(disputed) --- 0xA4(!avail) --- 0xA5(!avail) +/// \ +/// `- 0xB2 +/// ``` +fn chain_0() -> CaseVars { + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + + let a1 = builder.fast_forward_approved(0xA0, head, 1); + let a2 = builder.fast_forward_approved(0xA0, a1, 2); + let a3 = builder.fast_forward_disputed(0xA0, a2, 3); + let a4 = builder.fast_forward(0xA0, a3, 4); + let a5 = builder.fast_forward(0xA0, a4, 5); + + let b1 = builder.fast_forward_approved(0xB0, a1, 2); + let b2 = builder.fast_forward_approved(0xB0, b1, 3); + let b3 = builder.fast_forward_approved(0xB0, b2, 4); + + builder.set_heads(vec![a5, b3]); + + CaseVars { + chain: builder.init(), + target_block: a1, + best_chain_containing_block: Some(a5), + highest_approved_ancestor_block: Some(a3), + undisputed_chain: Some(a2), + expected_finality_target_result: Some(a2), + } +} + +/// ```raw +/// genesis -- 0xA1 --- 0xA2(disputed) --- 0xA3 +/// \ +/// `- 0xB2 --- 0xB3(!available) +/// ``` +fn chain_1() -> CaseVars { + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + + let a1 = builder.fast_forward_approved(0xA0, head, 1); + let a2 = builder.fast_forward_disputed(0xA0, a1, 2); + let a3 = builder.fast_forward_approved(0xA0, a2, 3); + + let b2 = builder.fast_forward_approved(0xB0, a1, 2); + let b3 = builder.fast_forward(0xB0, b2, 3); + + builder.set_heads(vec![a3, b3]); + + CaseVars { + chain: builder.init(), + target_block: a1, + best_chain_containing_block: Some(b3), + highest_approved_ancestor_block: Some(b2), + undisputed_chain: Some(b2), + expected_finality_target_result: Some(b2), + } +} + +/// ```raw +/// genesis -- 0xA1 --- 0xA2(disputed) --- 0xA3 +/// \ +/// `- 0xB2 --- 0xB3 +/// ``` +fn chain_2() -> CaseVars { + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + + let a1 = builder.fast_forward_approved(0xA0, head, 1); + let a2 = builder.fast_forward_disputed(0xA0, a1, 2); + let a3 = builder.fast_forward_approved(0xA0, a2, 3); + + let b2 = builder.fast_forward_approved(0xB0, a1, 2); + let b3 = builder.fast_forward_approved(0xB0, b2, 3); + + builder.set_heads(vec![a3, b3]); + + CaseVars { + chain: builder.init(), + target_block: a3, + best_chain_containing_block: Some(a3), + highest_approved_ancestor_block: Some(a3), + undisputed_chain: Some(a1), + expected_finality_target_result: Some(a1), + } +} + +/// ```raw +/// genesis -- 0xA1 --- 0xA2 --- 0xA3(disputed) +/// \ +/// `- 0xB2 --- 0xB3 +/// ``` +fn chain_3() -> CaseVars { + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + + let a1 = builder.fast_forward_approved(0xA0, head, 1); + let a2 = builder.fast_forward_approved(0xA0, a1, 2); + let a3 = builder.fast_forward_disputed(0xA0, a2, 3); + + let b2 = builder.fast_forward_approved(0xB0, a1, 2); + let b3 = builder.fast_forward_approved(0xB0, b2, 3); + + builder.set_heads(vec![a3, b3]); + + CaseVars { + chain: builder.init(), + target_block: a2, + best_chain_containing_block: Some(a3), + highest_approved_ancestor_block: Some(a3), + undisputed_chain: Some(a2), + expected_finality_target_result: Some(a2), + } +} + +/// ```raw +/// genesis -- 0xA1 --- 0xA2 --- 0xA3(disputed) +/// \ +/// `- 0xB2 --- 0xB3 +/// +/// ? --- NEX(does_not_exist) +/// ``` +fn chain_4() -> CaseVars { + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + + let a1 = builder.fast_forward_approved(0xA0, head, 1); + let a2 = builder.fast_forward_approved(0xA0, a1, 2); + let a3 = builder.fast_forward_disputed(0xA0, a2, 3); + + let b2 = builder.fast_forward_approved(0xB0, a1, 2); + let b3 = builder.fast_forward_approved(0xB0, b2, 3); + + builder.set_heads(vec![a3, b3]); + + let does_not_exist = Hash::repeat_byte(0xCC); + CaseVars { + chain: builder.init(), + target_block: does_not_exist, + best_chain_containing_block: None, + highest_approved_ancestor_block: None, + undisputed_chain: None, + expected_finality_target_result: Some(does_not_exist), + } +} + +/// ```raw +/// genesis -- 0xA1 --- 0xA2 +/// ``` +fn chain_5() -> CaseVars { + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + + let a1 = builder.fast_forward_approved(0xA0, head, 1); + let a2 = builder.fast_forward_approved(0xA0, a1, 2); + + builder.set_heads(vec![a2]); + + CaseVars { + chain: builder.init(), + target_block: a2, + best_chain_containing_block: Some(a2), + highest_approved_ancestor_block: Some(a2), + undisputed_chain: Some(a2), + expected_finality_target_result: Some(a2), + } +} + +/// ```raw +/// genesis -- 0xB2 -- 0xD2 -- .. -- 0xD8 -- 0xC8(unapproved) -- .. -- 0xCF(unapproved) +/// ``` +fn chain_6() -> CaseVars { + let head: Hash = ChainBuilder::GENESIS_HASH; + let mut builder = ChainBuilder::new(); + + let b1 = builder.fast_forward_approved(0xB0, head, 1); + + let mut previous = b1; + let mut approved = b1; + for block_number in 2_u32..16 { + if block_number <= 8 { + previous = builder.fast_forward_approved(0xD0, previous, block_number as _); + approved = previous; + } else { + previous = builder.fast_forward(0xA0, previous, block_number as _); + } + } + let leaf = previous; + + builder.set_heads(vec![leaf]); + + let chain = builder.init(); + + gum::trace!(highest_approved = ?chain.highest_approved_ancestors(1, leaf)); + gum::trace!(undisputed = ?chain.undisputed_chain(1, approved)); + CaseVars { + chain, + target_block: b1, + best_chain_containing_block: Some(leaf), + highest_approved_ancestor_block: Some(approved), + undisputed_chain: Some(approved), + expected_finality_target_result: Some(approved), + } +} + +#[test] +fn chain_sel_undisputed() { + run_specialized_test_w_harness(chain_undisputed); +} + +#[test] +fn chain_sel_0() { + run_specialized_test_w_harness(chain_0); +} + +#[test] +fn chain_sel_1() { + run_specialized_test_w_harness(chain_1); +} + +#[test] +fn chain_sel_2() { + run_specialized_test_w_harness(chain_2); +} + +#[test] +fn chain_sel_3() { + run_specialized_test_w_harness(chain_3); +} + +#[test] +fn chain_sel_4_target_hash_value_not_contained() { + run_specialized_test_w_harness(chain_4); +} + +#[test] +fn chain_sel_5_best_is_target_hash() { + run_specialized_test_w_harness(chain_5); +} + +#[test] +fn chain_sel_6_approval_lag() { + run_specialized_test_w_harness(chain_6); +} diff --git a/polkadot/node/service/src/workers.rs b/polkadot/node/service/src/workers.rs new file mode 100644 index 0000000000000000000000000000000000000000..5f7cc1c2ed49acf0bf170843033f2c5cdbc73701 --- /dev/null +++ b/polkadot/node/service/src/workers.rs @@ -0,0 +1,520 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Utilities and tests for locating the PVF worker binaries. + +use super::Error; +use is_executable::IsExecutable; +use std::{path::PathBuf, process::Command}; + +#[cfg(test)] +use std::sync::{Mutex, OnceLock}; + +/// Override the workers polkadot binary directory path, used for testing. +#[cfg(test)] +fn workers_exe_path_override() -> &'static Mutex> { + static OVERRIDE: OnceLock>> = OnceLock::new(); + OVERRIDE.get_or_init(|| Mutex::new(None)) +} +/// Override the workers lib directory path, used for testing. +#[cfg(test)] +fn workers_lib_path_override() -> &'static Mutex> { + static OVERRIDE: OnceLock>> = OnceLock::new(); + OVERRIDE.get_or_init(|| Mutex::new(None)) +} + +/// Determines the final set of paths to use for the PVF workers. +/// +/// 1. Get the binaries from the workers path if it is passed in, or consider all possible +/// locations on the filesystem in order and get all sets of paths at which the binaries exist. +/// +/// 2. If no paths exist, error out. We can't proceed without workers. +/// +/// 3. Log a warning if more than one set of paths exists. Continue with the first set of paths. +/// +/// 4. Check if the returned paths are executable. If not it's evidence of a borked installation +/// so error out. +/// +/// 5. Do the version check, if mismatch error out. +/// +/// 6. At this point the final set of paths should be good to use. +pub fn determine_workers_paths( + given_workers_path: Option, + workers_names: Option<(String, String)>, + node_version: Option, +) -> Result<(PathBuf, PathBuf), Error> { + let mut workers_paths = list_workers_paths(given_workers_path.clone(), workers_names.clone())?; + if workers_paths.is_empty() { + let current_exe_path = get_exe_path()?; + return Err(Error::MissingWorkerBinaries { + given_workers_path, + current_exe_path, + workers_names, + }) + } else if workers_paths.len() > 1 { + log::warn!("multiple sets of worker binaries found ({:?})", workers_paths,); + } + + let (prep_worker_path, exec_worker_path) = workers_paths.swap_remove(0); + if !prep_worker_path.is_executable() || !exec_worker_path.is_executable() { + return Err(Error::InvalidWorkerBinaries { prep_worker_path, exec_worker_path }) + } + + // Do the version check. + if let Some(node_version) = node_version { + let worker_version = Command::new(&prep_worker_path).args(["--version"]).output()?.stdout; + let worker_version = std::str::from_utf8(&worker_version) + .expect("version is printed as a string; qed") + .trim() + .to_string(); + if worker_version != node_version { + return Err(Error::WorkerBinaryVersionMismatch { + worker_version, + node_version, + worker_path: prep_worker_path, + }) + } + let worker_version = Command::new(&exec_worker_path).args(["--version"]).output()?.stdout; + let worker_version = std::str::from_utf8(&worker_version) + .expect("version is printed as a string; qed") + .trim() + .to_string(); + if worker_version != node_version { + return Err(Error::WorkerBinaryVersionMismatch { + worker_version, + node_version, + worker_path: exec_worker_path, + }) + } + } else { + log::warn!("Skipping node/worker version checks. This could result in incorrect behavior in PVF workers."); + } + + Ok((prep_worker_path, exec_worker_path)) +} + +/// Get list of workers paths by considering the passed-in `given_workers_path` option, or possible +/// locations on the filesystem. See `new_full`. +fn list_workers_paths( + given_workers_path: Option, + workers_names: Option<(String, String)>, +) -> Result, Error> { + if let Some(path) = given_workers_path { + log::trace!("Using explicitly provided workers path {:?}", path); + + if path.is_executable() { + return Ok(vec![(path.clone(), path)]) + } + + let (prep_worker, exec_worker) = build_worker_paths(path, workers_names); + + // Check if both workers exist. Otherwise return an empty vector which results in an error. + return if prep_worker.exists() && exec_worker.exists() { + Ok(vec![(prep_worker, exec_worker)]) + } else { + Ok(vec![]) + } + } + + // Workers path not provided, check all possible valid locations. + + let mut workers_paths = vec![]; + + // Consider the polkadot binary directory. + { + let exe_path = get_exe_path()?; + + let (prep_worker, exec_worker) = + build_worker_paths(exe_path.clone(), workers_names.clone()); + + // Add to set if both workers exist. Warn on partial installs. + let (prep_worker_exists, exec_worker_exists) = (prep_worker.exists(), exec_worker.exists()); + if prep_worker_exists && exec_worker_exists { + log::trace!("Worker binaries found at current exe path: {:?}", exe_path); + workers_paths.push((prep_worker, exec_worker)); + } else if prep_worker_exists { + log::warn!("Worker binary found at {:?} but not {:?}", prep_worker, exec_worker); + } else if exec_worker_exists { + log::warn!("Worker binary found at {:?} but not {:?}", exec_worker, prep_worker); + } + } + + // Consider the /usr/lib/polkadot/ directory. + { + #[allow(unused_mut)] + let mut lib_path = PathBuf::from("/usr/lib/polkadot"); + #[cfg(test)] + if let Some(ref path_override) = *workers_lib_path_override().lock().unwrap() { + lib_path = path_override.clone(); + } + + let (prep_worker, exec_worker) = build_worker_paths(lib_path, workers_names); + + // Add to set if both workers exist. Warn on partial installs. + let (prep_worker_exists, exec_worker_exists) = (prep_worker.exists(), exec_worker.exists()); + if prep_worker_exists && exec_worker_exists { + log::trace!("Worker binaries found at /usr/lib/polkadot"); + workers_paths.push((prep_worker, exec_worker)); + } else if prep_worker_exists { + log::warn!("Worker binary found at {:?} but not {:?}", prep_worker, exec_worker); + } else if exec_worker_exists { + log::warn!("Worker binary found at {:?} but not {:?}", exec_worker, prep_worker); + } + } + + Ok(workers_paths) +} + +fn get_exe_path() -> Result { + let mut exe_path = std::env::current_exe()?; + let _ = exe_path.pop(); // executable file will always have a parent directory. + #[cfg(test)] + if let Some(ref path_override) = *workers_exe_path_override().lock().unwrap() { + exe_path = path_override.clone(); + } + Ok(exe_path) +} + +fn build_worker_paths( + worker_dir: PathBuf, + workers_names: Option<(String, String)>, +) -> (PathBuf, PathBuf) { + let (prep_worker_name, exec_worker_name) = workers_names.unwrap_or(( + polkadot_node_core_pvf::PREPARE_BINARY_NAME.to_string(), + polkadot_node_core_pvf::EXECUTE_BINARY_NAME.to_string(), + )); + + let mut prep_worker = worker_dir.clone(); + prep_worker.push(prep_worker_name); + let mut exec_worker = worker_dir; + exec_worker.push(exec_worker_name); + + (prep_worker, exec_worker) +} + +// Tests that set up a temporary directory tree according to what scenario we want to test and +// run worker detection. +#[cfg(test)] +mod tests { + use super::*; + + use assert_matches::assert_matches; + use serial_test::serial; + use std::{env::temp_dir, fs, os::unix::fs::PermissionsExt, path::Path}; + + const NODE_VERSION: &'static str = "v0.1.2"; + + /// Write a dummy executable to the path which satisfies the version check. + fn write_worker_exe(path: impl AsRef) -> Result<(), Box> { + let program = get_program(NODE_VERSION); + fs::write(&path, program)?; + Ok(fs::set_permissions(&path, fs::Permissions::from_mode(0o744))?) + } + + fn write_worker_exe_invalid_version( + path: impl AsRef, + version: &str, + ) -> Result<(), Box> { + let program = get_program(version); + fs::write(&path, program)?; + Ok(fs::set_permissions(&path, fs::Permissions::from_mode(0o744))?) + } + + fn get_program(version: &str) -> String { + format!( + "#!/bin/bash + +if [[ $# -ne 1 ]] ; then + echo \"unexpected number of arguments: $#\" + exit 1 +fi + +if [[ \"$1\" != \"--version\" ]] ; then + echo \"unexpected argument: $1\" + exit 1 +fi + +echo {} +", + version + ) + } + + /// Sets up an empty temp dir structure where the workers can be put by tests. Uses the temp dir + /// to override the standard locations where the node searches for the workers. + fn with_temp_dir_structure( + f: impl FnOnce(PathBuf, PathBuf) -> Result<(), Box>, + ) -> Result<(), Box> { + // Set up /usr/lib/polkadot and /usr/bin, both empty. + + let tempdir = temp_dir(); + let lib_path = tempdir.join("usr/lib/polkadot"); + let _ = fs::remove_dir_all(&lib_path); + fs::create_dir_all(&lib_path)?; + *workers_lib_path_override().lock()? = Some(lib_path); + + let exe_path = tempdir.join("usr/bin"); + let _ = fs::remove_dir_all(&exe_path); + fs::create_dir_all(&exe_path)?; + *workers_exe_path_override().lock()? = Some(exe_path.clone()); + + // Set up custom path at /usr/local/bin. + let custom_path = tempdir.join("usr/local/bin"); + let _ = fs::remove_dir_all(&custom_path); + fs::create_dir_all(&custom_path)?; + + f(tempdir, exe_path) + } + + #[test] + #[serial] + fn test_given_worker_path() { + with_temp_dir_structure(|tempdir, exe_path| { + let given_workers_path = tempdir.join("usr/local/bin"); + + // Try with provided workers path that has missing binaries. + assert_matches!( + determine_workers_paths(Some(given_workers_path.clone()), None, Some(NODE_VERSION.into())), + Err(Error::MissingWorkerBinaries { given_workers_path: Some(p1), current_exe_path: p2, workers_names: None }) if p1 == given_workers_path && p2 == exe_path + ); + + // Try with provided workers path that has non-executable binaries. + let prepare_worker_path = given_workers_path.join("polkadot-prepare-worker"); + write_worker_exe(&prepare_worker_path)?; + fs::set_permissions(&prepare_worker_path, fs::Permissions::from_mode(0o644))?; + let execute_worker_path = given_workers_path.join("polkadot-execute-worker"); + write_worker_exe(&execute_worker_path)?; + fs::set_permissions(&execute_worker_path, fs::Permissions::from_mode(0o644))?; + assert_matches!( + determine_workers_paths(Some(given_workers_path.clone()), None, Some(NODE_VERSION.into())), + Err(Error::InvalidWorkerBinaries { prep_worker_path: p1, exec_worker_path: p2 }) if p1 == prepare_worker_path && p2 == execute_worker_path + ); + + // Try with valid workers directory path that has executable binaries. + fs::set_permissions(&prepare_worker_path, fs::Permissions::from_mode(0o744))?; + fs::set_permissions(&execute_worker_path, fs::Permissions::from_mode(0o744))?; + assert_matches!( + determine_workers_paths(Some(given_workers_path), None, Some(NODE_VERSION.into())), + Ok((p1, p2)) if p1 == prepare_worker_path && p2 == execute_worker_path + ); + + // Try with valid provided workers path that is a binary file. + let given_workers_path = tempdir.join("usr/local/bin/puppet-worker"); + write_worker_exe(&given_workers_path)?; + assert_matches!( + determine_workers_paths(Some(given_workers_path.clone()), None, Some(NODE_VERSION.into())), + Ok((p1, p2)) if p1 == given_workers_path && p2 == given_workers_path + ); + + Ok(()) + }) + .unwrap(); + } + + #[test] + #[serial] + fn missing_workers_paths_throws_error() { + with_temp_dir_structure(|tempdir, exe_path| { + // Try with both binaries missing. + assert_matches!( + determine_workers_paths(None, None, Some(NODE_VERSION.into())), + Err(Error::MissingWorkerBinaries { given_workers_path: None, current_exe_path: p, workers_names: None }) if p == exe_path + ); + + // Try with only prep worker (at bin location). + let prepare_worker_path = tempdir.join("usr/bin/polkadot-prepare-worker"); + write_worker_exe(&prepare_worker_path)?; + assert_matches!( + determine_workers_paths(None, None, Some(NODE_VERSION.into())), + Err(Error::MissingWorkerBinaries { given_workers_path: None, current_exe_path: p, workers_names: None }) if p == exe_path + ); + + // Try with only exec worker (at bin location). + fs::remove_file(&prepare_worker_path)?; + let execute_worker_path = tempdir.join("usr/bin/polkadot-execute-worker"); + write_worker_exe(&execute_worker_path)?; + assert_matches!( + determine_workers_paths(None, None, Some(NODE_VERSION.into())), + Err(Error::MissingWorkerBinaries { given_workers_path: None, current_exe_path: p, workers_names: None }) if p == exe_path + ); + + // Try with only prep worker (at lib location). + fs::remove_file(&execute_worker_path)?; + let prepare_worker_path = tempdir.join("usr/lib/polkadot/polkadot-prepare-worker"); + write_worker_exe(&prepare_worker_path)?; + assert_matches!( + determine_workers_paths(None, None, Some(NODE_VERSION.into())), + Err(Error::MissingWorkerBinaries { given_workers_path: None, current_exe_path: p, workers_names: None }) if p == exe_path + ); + + // Try with only exec worker (at lib location). + fs::remove_file(&prepare_worker_path)?; + let execute_worker_path = tempdir.join("usr/lib/polkadot/polkadot-execute-worker"); + write_worker_exe(execute_worker_path)?; + assert_matches!( + determine_workers_paths(None, None, Some(NODE_VERSION.into())), + Err(Error::MissingWorkerBinaries { given_workers_path: None, current_exe_path: p, workers_names: None }) if p == exe_path + ); + + Ok(()) + }) + .unwrap() + } + + #[test] + #[serial] + fn should_find_workers_at_all_locations() { + with_temp_dir_structure(|tempdir, _| { + let prepare_worker_bin_path = tempdir.join("usr/bin/polkadot-prepare-worker"); + write_worker_exe(&prepare_worker_bin_path)?; + + let execute_worker_bin_path = tempdir.join("usr/bin/polkadot-execute-worker"); + write_worker_exe(&execute_worker_bin_path)?; + + let prepare_worker_lib_path = tempdir.join("usr/lib/polkadot/polkadot-prepare-worker"); + write_worker_exe(&prepare_worker_lib_path)?; + + let execute_worker_lib_path = tempdir.join("usr/lib/polkadot/polkadot-execute-worker"); + write_worker_exe(&execute_worker_lib_path)?; + + assert_matches!( + list_workers_paths(None, None), + Ok(v) if v == vec![(prepare_worker_bin_path, execute_worker_bin_path), (prepare_worker_lib_path, execute_worker_lib_path)] + ); + + Ok(()) + }) + .unwrap(); + } + + #[test] + #[serial] + fn should_find_workers_with_custom_names_at_all_locations() { + with_temp_dir_structure(|tempdir, _| { + let (prep_worker_name, exec_worker_name) = ("test-prepare", "test-execute"); + + let prepare_worker_bin_path = tempdir.join("usr/bin").join(prep_worker_name); + write_worker_exe(&prepare_worker_bin_path)?; + + let execute_worker_bin_path = tempdir.join("usr/bin").join(exec_worker_name); + write_worker_exe(&execute_worker_bin_path)?; + + let prepare_worker_lib_path = tempdir.join("usr/lib/polkadot").join(prep_worker_name); + write_worker_exe(&prepare_worker_lib_path)?; + + let execute_worker_lib_path = tempdir.join("usr/lib/polkadot").join(exec_worker_name); + write_worker_exe(&execute_worker_lib_path)?; + + assert_matches!( + list_workers_paths(None, Some((prep_worker_name.into(), exec_worker_name.into()))), + Ok(v) if v == vec![(prepare_worker_bin_path, execute_worker_bin_path), (prepare_worker_lib_path, execute_worker_lib_path)] + ); + + Ok(()) + }) + .unwrap(); + } + + #[test] + #[serial] + fn workers_version_mismatch_throws_error() { + let bad_version = "v9.9.9.9"; + + with_temp_dir_structure(|tempdir, _| { + // Workers at bin location return bad version. + let prepare_worker_bin_path = tempdir.join("usr/bin/polkadot-prepare-worker"); + let execute_worker_bin_path = tempdir.join("usr/bin/polkadot-execute-worker"); + write_worker_exe_invalid_version(&prepare_worker_bin_path, bad_version)?; + write_worker_exe(&execute_worker_bin_path)?; + assert_matches!( + determine_workers_paths(None, None, Some(NODE_VERSION.into())), + Err(Error::WorkerBinaryVersionMismatch { worker_version: v1, node_version: v2, worker_path: p }) if v1 == bad_version && v2 == NODE_VERSION && p == prepare_worker_bin_path + ); + + // Workers at lib location return bad version. + fs::remove_file(prepare_worker_bin_path)?; + fs::remove_file(execute_worker_bin_path)?; + let prepare_worker_lib_path = tempdir.join("usr/lib/polkadot/polkadot-prepare-worker"); + let execute_worker_lib_path = tempdir.join("usr/lib/polkadot/polkadot-execute-worker"); + write_worker_exe(&prepare_worker_lib_path)?; + write_worker_exe_invalid_version(&execute_worker_lib_path, bad_version)?; + assert_matches!( + determine_workers_paths(None, None, Some(NODE_VERSION.into())), + Err(Error::WorkerBinaryVersionMismatch { worker_version: v1, node_version: v2, worker_path: p }) if v1 == bad_version && v2 == NODE_VERSION && p == execute_worker_lib_path + ); + + // Workers at provided workers location return bad version. + let given_workers_path = tempdir.join("usr/local/bin"); + let prepare_worker_path = given_workers_path.join("polkadot-prepare-worker"); + let execute_worker_path = given_workers_path.join("polkadot-execute-worker"); + write_worker_exe_invalid_version(&prepare_worker_path, bad_version)?; + write_worker_exe_invalid_version(&execute_worker_path, bad_version)?; + assert_matches!( + determine_workers_paths(Some(given_workers_path), None, Some(NODE_VERSION.into())), + Err(Error::WorkerBinaryVersionMismatch { worker_version: v1, node_version: v2, worker_path: p }) if v1 == bad_version && v2 == NODE_VERSION && p == prepare_worker_path + ); + + // Given worker binary returns bad version. + let given_workers_path = tempdir.join("usr/local/bin/puppet-worker"); + write_worker_exe_invalid_version(&given_workers_path, bad_version)?; + assert_matches!( + determine_workers_paths(Some(given_workers_path.clone()), None, Some(NODE_VERSION.into())), + Err(Error::WorkerBinaryVersionMismatch { worker_version: v1, node_version: v2, worker_path: p }) if v1 == bad_version && v2 == NODE_VERSION && p == given_workers_path + ); + + Ok(()) + }) + .unwrap(); + } + + #[test] + #[serial] + fn should_find_valid_workers() { + // Test bin location. + with_temp_dir_structure(|tempdir, _| { + let prepare_worker_bin_path = tempdir.join("usr/bin/polkadot-prepare-worker"); + write_worker_exe(&prepare_worker_bin_path)?; + + let execute_worker_bin_path = tempdir.join("usr/bin/polkadot-execute-worker"); + write_worker_exe(&execute_worker_bin_path)?; + + assert_matches!( + determine_workers_paths(None, None, Some(NODE_VERSION.into())), + Ok((p1, p2)) if p1 == prepare_worker_bin_path && p2 == execute_worker_bin_path + ); + + Ok(()) + }) + .unwrap(); + + // Test lib location. + with_temp_dir_structure(|tempdir, _| { + let prepare_worker_lib_path = tempdir.join("usr/lib/polkadot/polkadot-prepare-worker"); + write_worker_exe(&prepare_worker_lib_path)?; + + let execute_worker_lib_path = tempdir.join("usr/lib/polkadot/polkadot-execute-worker"); + write_worker_exe(&execute_worker_lib_path)?; + + assert_matches!( + determine_workers_paths(None, None, Some(NODE_VERSION.into())), + Ok((p1, p2)) if p1 == prepare_worker_lib_path && p2 == execute_worker_lib_path + ); + + Ok(()) + }) + .unwrap(); + } +} diff --git a/polkadot/node/subsystem-test-helpers/Cargo.toml b/polkadot/node/subsystem-test-helpers/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..adb0587370ec7e7135db84e8bfb8b7db3dd0a01f --- /dev/null +++ b/polkadot/node/subsystem-test-helpers/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "polkadot-node-subsystem-test-helpers" +description = "Subsystem traits and message definitions" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +async-trait = "0.1.57" +futures = "0.3.21" +parking_lot = "0.12.0" +polkadot-node-subsystem = { path = "../subsystem" } +polkadot-node-subsystem-util = { path = "../subsystem-util" } +polkadot-primitives = { path = "../../primitives" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[dev-dependencies] +polkadot-overseer = { path = "../overseer" } diff --git a/polkadot/node/subsystem-test-helpers/src/lib.rs b/polkadot/node/subsystem-test-helpers/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..fb908278aa7da8008db092871ead3b2d5c0c37c0 --- /dev/null +++ b/polkadot/node/subsystem-test-helpers/src/lib.rs @@ -0,0 +1,490 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Utilities for testing subsystems. + +#![warn(missing_docs)] + +use polkadot_node_subsystem::{ + messages::AllMessages, overseer, FromOrchestra, OverseerSignal, SpawnGlue, SpawnedSubsystem, + SubsystemError, SubsystemResult, +}; +use polkadot_node_subsystem_util::TimeoutExt; + +use futures::{channel::mpsc, poll, prelude::*}; +use parking_lot::Mutex; +use sp_core::testing::TaskExecutor; + +use std::{ + convert::Infallible, + future::Future, + pin::Pin, + sync::Arc, + task::{Context, Poll, Waker}, + time::Duration, +}; + +/// Generally useful mock data providers for unit tests. +pub mod mock; + +enum SinkState { + Empty { read_waker: Option }, + Item { item: T, ready_waker: Option, flush_waker: Option }, +} + +/// The sink half of a single-item sink that does not resolve until the item has been read. +pub struct SingleItemSink(Arc>>); + +// Derive clone not possible, as it puts `Clone` constraint on `T` which is not sensible here. +impl Clone for SingleItemSink { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +/// The stream half of a single-item sink. +pub struct SingleItemStream(Arc>>); + +impl Sink for SingleItemSink { + type Error = Infallible; + + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + let mut state = self.0.lock(); + match *state { + SinkState::Empty { .. } => Poll::Ready(Ok(())), + SinkState::Item { ref mut ready_waker, .. } => { + *ready_waker = Some(cx.waker().clone()); + Poll::Pending + }, + } + } + + fn start_send(self: Pin<&mut Self>, item: T) -> Result<(), Infallible> { + let mut state = self.0.lock(); + + match *state { + SinkState::Empty { ref mut read_waker } => + if let Some(waker) = read_waker.take() { + waker.wake(); + }, + _ => panic!("start_send called outside of empty sink state ensured by poll_ready"), + } + + *state = SinkState::Item { item, ready_waker: None, flush_waker: None }; + + Ok(()) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + let mut state = self.0.lock(); + match *state { + SinkState::Empty { .. } => Poll::Ready(Ok(())), + SinkState::Item { ref mut flush_waker, .. } => { + *flush_waker = Some(cx.waker().clone()); + Poll::Pending + }, + } + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + self.poll_flush(cx) + } +} + +impl Stream for SingleItemStream { + type Item = T; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + let mut state = self.0.lock(); + + let read_waker = Some(cx.waker().clone()); + + match std::mem::replace(&mut *state, SinkState::Empty { read_waker }) { + SinkState::Empty { .. } => Poll::Pending, + SinkState::Item { item, ready_waker, flush_waker } => { + if let Some(waker) = ready_waker { + waker.wake(); + } + + if let Some(waker) = flush_waker { + waker.wake(); + } + + Poll::Ready(Some(item)) + }, + } + } +} + +/// Create a single-item Sink/Stream pair. +/// +/// The sink's send methods resolve at the point which the stream reads the item, +/// not when the item is buffered. +pub fn single_item_sink() -> (SingleItemSink, SingleItemStream) { + let inner = Arc::new(Mutex::new(SinkState::Empty { read_waker: None })); + (SingleItemSink(inner.clone()), SingleItemStream(inner)) +} + +/// A test subsystem sender. +#[derive(Clone)] +pub struct TestSubsystemSender { + tx: mpsc::UnboundedSender, +} + +/// Construct a sender/receiver pair. +pub fn sender_receiver() -> (TestSubsystemSender, mpsc::UnboundedReceiver) { + let (tx, rx) = mpsc::unbounded(); + (TestSubsystemSender { tx }, rx) +} + +#[async_trait::async_trait] +impl overseer::SubsystemSender for TestSubsystemSender +where + AllMessages: From, + OutgoingMessage: Send + 'static, +{ + async fn send_message(&mut self, msg: OutgoingMessage) { + self.tx.send(msg.into()).await.expect("test overseer no longer live"); + } + + async fn send_messages(&mut self, msgs: I) + where + I: IntoIterator + Send, + I::IntoIter: Send, + { + let mut iter = stream::iter(msgs.into_iter().map(|msg| Ok(msg.into()))); + self.tx.send_all(&mut iter).await.expect("test overseer no longer live"); + } + + fn send_unbounded_message(&mut self, msg: OutgoingMessage) { + self.tx.unbounded_send(msg.into()).expect("test overseer no longer live"); + } +} + +/// A test subsystem context. +pub struct TestSubsystemContext { + tx: TestSubsystemSender, + rx: mpsc::Receiver>, + spawn: S, +} + +#[async_trait::async_trait] +impl overseer::SubsystemContext for TestSubsystemContext +where + M: overseer::AssociateOutgoing + std::fmt::Debug + Send + 'static, + AllMessages: From<::OutgoingMessages>, + AllMessages: From, + Spawner: overseer::gen::Spawner + Send + 'static, +{ + type Message = M; + type Sender = TestSubsystemSender; + type Signal = OverseerSignal; + type OutgoingMessages = ::OutgoingMessages; + type Error = SubsystemError; + + async fn try_recv(&mut self) -> Result>, ()> { + match poll!(self.rx.next()) { + Poll::Ready(Some(msg)) => Ok(Some(msg)), + Poll::Ready(None) => Err(()), + Poll::Pending => Ok(None), + } + } + + async fn recv(&mut self) -> SubsystemResult> { + self.rx + .next() + .await + .ok_or_else(|| SubsystemError::Context("Receiving end closed".to_owned())) + } + + fn spawn( + &mut self, + name: &'static str, + s: Pin + Send>>, + ) -> SubsystemResult<()> { + self.spawn.spawn(name, None, s); + Ok(()) + } + + fn spawn_blocking( + &mut self, + name: &'static str, + s: Pin + Send>>, + ) -> SubsystemResult<()> { + self.spawn.spawn_blocking(name, None, s); + Ok(()) + } + + fn sender(&mut self) -> &mut TestSubsystemSender { + &mut self.tx + } +} + +/// A handle for interacting with the subsystem context. +pub struct TestSubsystemContextHandle { + /// Direct access to sender of messages. + /// + /// Useful for shared ownership situations (one can have multiple senders, but only one + /// receiver. + pub tx: mpsc::Sender>, + + /// Direct access to the receiver. + pub rx: mpsc::UnboundedReceiver, +} + +impl TestSubsystemContextHandle { + /// Fallback timeout value used to never block test execution + /// indefinitely. + pub const TIMEOUT: Duration = Duration::from_secs(120); + + /// Send a message or signal to the subsystem. This resolves at the point in time when the + /// subsystem has _read_ the message. + pub async fn send(&mut self, from_overseer: FromOrchestra) { + self.tx + .send(from_overseer) + .timeout(Self::TIMEOUT) + .await + .expect("`fn send` does not timeout") + .expect("Test subsystem no longer live"); + } + + /// Receive the next message from the subsystem. + pub async fn recv(&mut self) -> AllMessages { + self.try_recv() + .timeout(Self::TIMEOUT) + .await + .expect("`fn recv` does not timeout") + .expect("Test subsystem no longer live") + } + + /// Receive the next message from the subsystem, or `None` if the channel has been closed. + pub async fn try_recv(&mut self) -> Option { + self.rx + .next() + .timeout(Self::TIMEOUT) + .await + .expect("`try_recv` does not timeout") + } +} + +/// Make a test subsystem context with `buffer_size == 0`. This is used by most +/// of the tests. +pub fn make_subsystem_context( + spawner: S, +) -> (TestSubsystemContext>, TestSubsystemContextHandle) { + make_buffered_subsystem_context(spawner, 0) +} + +/// Make a test subsystem context with buffered overseer channel. Some tests (e.g. +/// `dispute-coordinator`) create too many parallel operations and deadlock unless +/// the channel is buffered. Usually `buffer_size=1` is enough. +pub fn make_buffered_subsystem_context( + spawner: S, + buffer_size: usize, +) -> (TestSubsystemContext>, TestSubsystemContextHandle) { + let (overseer_tx, overseer_rx) = mpsc::channel(buffer_size); + let (all_messages_tx, all_messages_rx) = mpsc::unbounded(); + + ( + TestSubsystemContext { + tx: TestSubsystemSender { tx: all_messages_tx }, + rx: overseer_rx, + spawn: SpawnGlue(spawner), + }, + TestSubsystemContextHandle { tx: overseer_tx, rx: all_messages_rx }, + ) +} + +/// Test a subsystem, mocking the overseer +/// +/// Pass in two async closures: one mocks the overseer, the other runs the test from the perspective +/// of a subsystem. +/// +/// Times out in 5 seconds. +pub fn subsystem_test_harness( + overseer_factory: OverseerFactory, + test_factory: TestFactory, +) where + OverseerFactory: FnOnce(TestSubsystemContextHandle) -> Overseer, + Overseer: Future, + TestFactory: FnOnce(TestSubsystemContext>) -> Test, + Test: Future, +{ + let pool = TaskExecutor::new(); + let (context, handle) = make_subsystem_context(pool); + let overseer = overseer_factory(handle); + let test = test_factory(context); + + futures::pin_mut!(overseer, test); + + futures::executor::block_on(async move { + future::join(overseer, test) + .timeout(Duration::from_secs(5)) + .await + .expect("test timed out instead of completing") + }); +} + +/// A forward subsystem that implements [`Subsystem`]. +/// +/// It forwards all communication from the overseer to the internal message +/// channel. +/// +/// This subsystem is useful for testing functionality that interacts with the overseer. +pub struct ForwardSubsystem(pub mpsc::Sender); + +impl overseer::Subsystem for ForwardSubsystem +where + M: overseer::AssociateOutgoing + std::fmt::Debug + Send + 'static, + Context: overseer::SubsystemContext< + Message = M, + Signal = OverseerSignal, + Error = SubsystemError, + OutgoingMessages = ::OutgoingMessages, + >, +{ + fn start(mut self, mut ctx: Context) -> SpawnedSubsystem { + let future = Box::pin(async move { + loop { + match ctx.recv().await { + Ok(FromOrchestra::Signal(OverseerSignal::Conclude)) => return Ok(()), + Ok(FromOrchestra::Communication { msg }) => { + let _ = self.0.send(msg).await; + }, + Err(_) => return Ok(()), + _ => (), + } + } + }); + + SpawnedSubsystem { name: "forward-subsystem", future } + } +} + +/// Asserts that two patterns match, yet only one +#[macro_export] +macro_rules! arbitrary_order { + ($rx:expr; $p1:pat => $e1:expr; $p2:pat => $e2:expr) => { + // If i.e. a enum has only two variants, `_` is unreachable. + match $rx { + $p1 => { + let __ret1 = { $e1 }; + let __ret2 = match $rx { + $p2 => $e2, + #[allow(unreachable_patterns)] + _ => unreachable!("first pattern matched, second pattern did not"), + }; + (__ret1, __ret2) + }, + $p2 => { + let __ret2 = { $e2 }; + let __ret1 = match $rx { + $p1 => $e1, + #[allow(unreachable_patterns)] + _ => unreachable!("second pattern matched, first pattern did not"), + }; + (__ret1, __ret2) + }, + #[allow(unreachable_patterns)] + _ => unreachable!("neither first nor second pattern matched"), + } + }; +} + +/// Future that yields the execution once and resolves +/// immediately after. +/// +/// Useful when one wants to poll the background task to completion +/// before sending messages to it in order to avoid races. +pub struct Yield(bool); + +impl Yield { + /// Returns new `Yield` future. + pub fn new() -> Self { + Self(false) + } +} + +impl Future for Yield { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + if !self.0 { + self.0 = true; + cx.waker().wake_by_ref(); + Poll::Pending + } else { + Poll::Ready(()) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use futures::executor::block_on; + use polkadot_node_subsystem::messages::CollatorProtocolMessage; + use polkadot_overseer::{dummy::dummy_overseer_builder, Handle, HeadSupportsParachains}; + use polkadot_primitives::Hash; + use sp_core::traits::SpawnNamed; + + struct AlwaysSupportsParachains; + + #[async_trait::async_trait] + impl HeadSupportsParachains for AlwaysSupportsParachains { + async fn head_supports_parachains(&self, _head: &Hash) -> bool { + true + } + } + + #[test] + fn forward_subsystem_works() { + let spawner = sp_core::testing::TaskExecutor::new(); + let (tx, rx) = mpsc::channel(2); + let (overseer, handle) = + dummy_overseer_builder(spawner.clone(), AlwaysSupportsParachains, None) + .unwrap() + .replace_collator_protocol(|_| ForwardSubsystem(tx)) + .build() + .unwrap(); + + let mut handle = Handle::new(handle); + + spawner.spawn("overseer", None, overseer.run().then(|_| async { () }).boxed()); + + block_on(handle.send_msg_anon(CollatorProtocolMessage::CollateOn(Default::default()))); + assert!(matches!( + block_on(rx.into_future()).0.unwrap(), + CollatorProtocolMessage::CollateOn(_) + )); + } + + #[test] + fn macro_arbitrary_order() { + let mut vals = vec![Some(15_usize), None]; + let (first, second) = arbitrary_order!(vals.pop().unwrap(); Some(fx) => fx; None => 0); + assert_eq!(first, 15_usize); + assert_eq!(second, 0_usize); + } + + #[test] + fn macro_arbitrary_order_swapped() { + let mut vals = vec![None, Some(11_usize)]; + let (first, second) = arbitrary_order!(vals.pop().unwrap(); Some(fx) => fx; None => 0); + assert_eq!(first, 11_usize); + assert_eq!(second, 0); + } +} diff --git a/polkadot/node/subsystem-test-helpers/src/mock.rs b/polkadot/node/subsystem-test-helpers/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..04695983d1d533a6bb57ed12dd60254e0a56d5cb --- /dev/null +++ b/polkadot/node/subsystem-test-helpers/src/mock.rs @@ -0,0 +1,42 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::sync::Arc; + +use sc_keystore::LocalKeystore; +use sp_application_crypto::AppCrypto; +use sp_keyring::Sr25519Keyring; +use sp_keystore::{Keystore, KeystorePtr}; + +use polkadot_primitives::{AuthorityDiscoveryId, ValidatorId}; + +/// Get mock keystore with `Ferdie` key. +pub fn make_ferdie_keystore() -> KeystorePtr { + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + Keystore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Ferdie.to_seed()), + ) + .expect("Insert key into keystore"); + Keystore::sr25519_generate_new( + &*keystore, + AuthorityDiscoveryId::ID, + Some(&Sr25519Keyring::Ferdie.to_seed()), + ) + .expect("Insert key into keystore"); + keystore +} diff --git a/polkadot/node/subsystem-types/Cargo.toml b/polkadot/node/subsystem-types/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..1fb9ac83b780e450e67609b0699216fbe0d5c789 --- /dev/null +++ b/polkadot/node/subsystem-types/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "polkadot-node-subsystem-types" +description = "Subsystem traits and message definitions" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +derive_more = "0.99.17" +futures = "0.3.21" +polkadot-primitives = { path = "../../primitives" } +polkadot-node-primitives = { path = "../primitives" } +polkadot-node-network-protocol = { path = "../network/protocol" } +polkadot-statement-table = { path = "../../statement-table" } +polkadot-node-jaeger = { path = "../jaeger" } +orchestra = "0.0.5" +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +smallvec = "1.8.0" +substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" } +thiserror = "1.0.31" +async-trait = "0.1.57" diff --git a/polkadot/node/subsystem-types/src/errors.rs b/polkadot/node/subsystem-types/src/errors.rs new file mode 100644 index 0000000000000000000000000000000000000000..44136362a69efa0ba316413cc9f78d834b5c3e9f --- /dev/null +++ b/polkadot/node/subsystem-types/src/errors.rs @@ -0,0 +1,166 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Error types for the subsystem requests. + +use crate::JaegerError; +use ::orchestra::OrchestraError as OverseerError; + +/// A description of an error causing the runtime API request to be unservable. +#[derive(thiserror::Error, Debug, Clone)] +pub enum RuntimeApiError { + /// The runtime API cannot be executed due to a runtime error. + #[error("The runtime API '{runtime_api_name}' cannot be executed: {source}")] + Execution { + /// The runtime API being called + runtime_api_name: &'static str, + /// The wrapped error. Marked as source for tracking the error chain. + #[source] + source: std::sync::Arc, + }, + + /// The runtime API request in question cannot be executed because the runtime at the requested + /// relay-parent is an old version. + #[error("The API is not supported by the runtime at the relay-parent")] + NotSupported { + /// The runtime API being called + runtime_api_name: &'static str, + }, +} + +/// A description of an error causing the chain API request to be unservable. +#[derive(Debug, Clone)] +pub struct ChainApiError { + msg: String, +} + +impl From<&str> for ChainApiError { + fn from(s: &str) -> Self { + s.to_owned().into() + } +} + +impl From for ChainApiError { + fn from(msg: String) -> Self { + Self { msg } + } +} + +impl core::fmt::Display for ChainApiError { + fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { + write!(f, "{}", self.msg) + } +} + +impl std::error::Error for ChainApiError {} + +/// An error that may happen during Availability Recovery process. +#[derive(PartialEq, Debug, Clone)] +pub enum RecoveryError { + /// A chunk is recovered but is invalid. + Invalid, + + /// A requested chunk is unavailable. + Unavailable, + + /// Erasure task channel closed, usually means node is shutting down. + ChannelClosed, +} + +impl std::fmt::Display for RecoveryError { + fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { + let msg = match self { + RecoveryError::Invalid => "Invalid", + RecoveryError::Unavailable => "Unavailable", + RecoveryError::ChannelClosed => "ChannelClosed", + }; + + write!(f, "{}", msg) + } +} + +impl std::error::Error for RecoveryError {} + +/// An error type that describes faults that may happen +/// +/// These are: +/// * Channels being closed +/// * Subsystems dying when they are not expected to +/// * Subsystems not dying when they are told to die +/// * etc. +#[derive(thiserror::Error, Debug)] +#[allow(missing_docs)] +pub enum SubsystemError { + #[error(transparent)] + NotifyCancellation(#[from] futures::channel::oneshot::Canceled), + + #[error(transparent)] + QueueError(#[from] futures::channel::mpsc::SendError), + + #[error(transparent)] + Io(#[from] std::io::Error), + + #[error(transparent)] + Infallible(#[from] std::convert::Infallible), + + #[error(transparent)] + Prometheus(#[from] substrate_prometheus_endpoint::PrometheusError), + + #[error(transparent)] + Jaeger(#[from] JaegerError), + + #[error("Failed to {0}")] + Context(String), + + #[error("Subsystem stalled: {0}")] + SubsystemStalled(&'static str), + + /// Generated by the `#[overseer(..)]` proc-macro + #[error(transparent)] + Generated(#[from] OverseerError), + + /// Per origin (or subsystem) annotations to wrap an error. + #[error("Error originated in {origin}")] + FromOrigin { + /// An additional annotation tag for the origin of `source`. + origin: &'static str, + /// The wrapped error. Marked as source for tracking the error chain. + #[source] + source: Box, + }, +} + +// impl AnnotateErrorOrigin for SubsystemError { +// fn with_origin(self, origin: &'static str) -> Self { +// Self::FromOrigin { +// origin, +// source: Box::new(self), +// } +// } +// } + +impl SubsystemError { + /// Adds a `str` as `origin` to the given error `err`. + pub fn with_origin( + origin: &'static str, + err: E, + ) -> Self { + Self::FromOrigin { origin, source: Box::new(err) } + } +} + +/// Ease the use of subsystem errors. +pub type SubsystemResult = Result; diff --git a/polkadot/node/subsystem-types/src/lib.rs b/polkadot/node/subsystem-types/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..f438a09592c1d22ad310c03b4b8386cb41b5a612 --- /dev/null +++ b/polkadot/node/subsystem-types/src/lib.rs @@ -0,0 +1,147 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Subsystem trait definitions and message types. +//! +//! Node-side logic for Polkadot is mostly comprised of Subsystems, which are discrete components +//! that communicate via message-passing. They are coordinated by an overseer, provided by a +//! separate crate. + +#![warn(missing_docs)] + +use std::{fmt, sync::Arc}; + +pub use polkadot_primitives::{BlockNumber, Hash}; +use smallvec::SmallVec; + +pub mod errors; +pub mod messages; + +mod runtime_client; +pub use runtime_client::{DefaultSubsystemClient, RuntimeApiSubsystemClient}; + +pub use jaeger::*; +pub use polkadot_node_jaeger as jaeger; + +/// How many slots are stack-reserved for active leaves updates +/// +/// If there are fewer than this number of slots, then we've wasted some stack space. +/// If there are greater than this number of slots, then we fall back to a heap vector. +const ACTIVE_LEAVES_SMALLVEC_CAPACITY: usize = 8; + +/// The status of an activated leaf. +#[derive(Clone, Debug, PartialEq)] +pub enum LeafStatus { + /// A leaf is fresh when it's the first time the leaf has been encountered. + /// Most leaves should be fresh. + Fresh, + /// A leaf is stale when it's encountered for a subsequent time. This will happen + /// when the chain is reverted or the fork-choice rule abandons some chain. + Stale, +} + +impl LeafStatus { + /// Returns a `bool` indicating fresh status. + pub fn is_fresh(&self) -> bool { + match *self { + LeafStatus::Fresh => true, + LeafStatus::Stale => false, + } + } + + /// Returns a `bool` indicating stale status. + pub fn is_stale(&self) -> bool { + match *self { + LeafStatus::Fresh => false, + LeafStatus::Stale => true, + } + } +} + +/// Activated leaf. +#[derive(Debug, Clone)] +pub struct ActivatedLeaf { + /// The block hash. + pub hash: Hash, + /// The block number. + pub number: BlockNumber, + /// The status of the leaf. + pub status: LeafStatus, + /// An associated [`jaeger::Span`]. + /// + /// NOTE: Each span should only be kept active as long as the leaf is considered active and + /// should be dropped when the leaf is deactivated. + pub span: Arc, +} + +/// Changes in the set of active leaves: the parachain heads which we care to work on. +/// +/// Note that the activated and deactivated fields indicate deltas, not complete sets. +#[derive(Clone, Default)] +pub struct ActiveLeavesUpdate { + /// New relay chain block of interest. + pub activated: Option, + /// Relay chain block hashes no longer of interest. + pub deactivated: SmallVec<[Hash; ACTIVE_LEAVES_SMALLVEC_CAPACITY]>, +} + +impl ActiveLeavesUpdate { + /// Create a `ActiveLeavesUpdate` with a single activated hash + pub fn start_work(activated: ActivatedLeaf) -> Self { + Self { activated: Some(activated), ..Default::default() } + } + + /// Create a `ActiveLeavesUpdate` with a single deactivated hash + pub fn stop_work(hash: Hash) -> Self { + Self { deactivated: [hash][..].into(), ..Default::default() } + } + + /// Is this update empty and doesn't contain any information? + pub fn is_empty(&self) -> bool { + self.activated.is_none() && self.deactivated.is_empty() + } +} + +impl PartialEq for ActiveLeavesUpdate { + /// Equality for `ActiveLeavesUpdate` doesn't imply bitwise equality. + /// + /// Instead, it means equality when `activated` and `deactivated` are considered as sets. + fn eq(&self, other: &Self) -> bool { + self.activated.as_ref().map(|a| a.hash) == other.activated.as_ref().map(|a| a.hash) && + self.deactivated.len() == other.deactivated.len() && + self.deactivated.iter().all(|a| other.deactivated.contains(a)) + } +} + +impl fmt::Debug for ActiveLeavesUpdate { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ActiveLeavesUpdate") + .field("activated", &self.activated) + .field("deactivated", &self.deactivated) + .finish() + } +} + +/// Signals sent by an overseer to a subsystem. +#[derive(PartialEq, Clone, Debug)] +pub enum OverseerSignal { + /// Subsystems should adjust their jobs to start and stop work on appropriate block hashes. + ActiveLeaves(ActiveLeavesUpdate), + /// `Subsystem` is informed of a finalized block by its block hash and number. + BlockFinalized(Hash, BlockNumber), + /// Conclude the work of the `Overseer` and all `Subsystem`s. + Conclude, +} diff --git a/polkadot/node/subsystem-types/src/messages.rs b/polkadot/node/subsystem-types/src/messages.rs new file mode 100644 index 0000000000000000000000000000000000000000..8adc39eed56db1b25880a96392dcbe97806755bb --- /dev/null +++ b/polkadot/node/subsystem-types/src/messages.rs @@ -0,0 +1,1133 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Message types for the overseer and subsystems. +//! +//! These messages are intended to define the protocol by which different subsystems communicate +//! with each other and signals that they receive from an overseer to coordinate their work. +//! This is intended for use with the `polkadot-overseer` crate. +//! +//! Subsystems' APIs are defined separately from their implementation, leading to easier mocking. + +use futures::channel::oneshot; +use sc_network::{Multiaddr, ReputationChange}; +use thiserror::Error; + +pub use sc_network::IfDisconnected; + +use polkadot_node_network_protocol::{ + self as net_protocol, peer_set::PeerSet, request_response::Requests, PeerId, +}; +use polkadot_node_primitives::{ + approval::{BlockApprovalMeta, IndirectAssignmentCert, IndirectSignedApprovalVote}, + AvailableData, BabeEpoch, BlockWeight, CandidateVotes, CollationGenerationConfig, + CollationSecondedSignal, DisputeMessage, DisputeStatus, ErasureChunk, PoV, + SignedDisputeStatement, SignedFullStatement, SignedFullStatementWithPVD, SubmitCollationParams, + ValidationResult, +}; +use polkadot_primitives::{ + slashing, vstaging as vstaging_primitives, AuthorityDiscoveryId, BackedCandidate, BlockNumber, + CandidateEvent, CandidateHash, CandidateIndex, CandidateReceipt, CollatorId, + CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupIndex, + GroupRotationInfo, Hash, Header as BlockHeader, Id as ParaId, InboundDownwardMessage, + InboundHrmpMessage, MultiDisputeStatementSet, OccupiedCoreAssumption, PersistedValidationData, + PvfCheckStatement, PvfExecTimeoutKind, SessionIndex, SessionInfo, SignedAvailabilityBitfield, + SignedAvailabilityBitfields, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, + ValidatorSignature, +}; +use polkadot_statement_table::v2::Misbehavior; +use std::{ + collections::{BTreeMap, HashMap, HashSet}, + sync::Arc, +}; + +/// Network events as transmitted to other subsystems, wrapped in their message types. +pub mod network_bridge_event; +pub use network_bridge_event::NetworkBridgeEvent; + +/// A request to the candidate backing subsystem to check whether +/// there exists vacant membership in some fragment tree. +#[derive(Debug, Copy, Clone)] +pub struct CanSecondRequest { + /// Para id of the candidate. + pub candidate_para_id: ParaId, + /// The relay-parent of the candidate. + pub candidate_relay_parent: Hash, + /// Hash of the candidate. + pub candidate_hash: CandidateHash, + /// Parent head data hash. + pub parent_head_data_hash: Hash, +} + +/// Messages received by the Candidate Backing subsystem. +#[derive(Debug)] +pub enum CandidateBackingMessage { + /// Requests a set of backable candidates attested by the subsystem. + /// + /// Each pair is (candidate_hash, candidate_relay_parent). + GetBackedCandidates(Vec<(CandidateHash, Hash)>, oneshot::Sender>), + /// Request the subsystem to check whether it's allowed to second given candidate. + /// The rule is to only fetch collations that are either built on top of the root + /// of some fragment tree or have a parent node which represents backed candidate. + /// + /// Always responses with `false` if async backing is disabled for candidate's relay + /// parent. + CanSecond(CanSecondRequest, oneshot::Sender), + /// Note that the Candidate Backing subsystem should second the given candidate in the context + /// of the given relay-parent (ref. by hash). This candidate must be validated. + Second(Hash, CandidateReceipt, PersistedValidationData, PoV), + /// Note a validator's statement about a particular candidate in the context of the given + /// relay-parent. Disagreements about validity must be escalated to a broader check by the + /// Disputes Subsystem, though that escalation is deferred until the approval voting stage to + /// guarantee availability. Agreements are simply tallied until a quorum is reached. + Statement(Hash, SignedFullStatementWithPVD), +} + +/// Blanket error for validation failing for internal reasons. +#[derive(Debug, Error)] +#[error("Validation failed with {0:?}")] +pub struct ValidationFailed(pub String); + +/// The outcome of the candidate-validation's PVF pre-check request. +#[derive(Debug, PartialEq)] +pub enum PreCheckOutcome { + /// The PVF has been compiled successfully within the given constraints. + Valid, + /// The PVF could not be compiled. This variant is used when the candidate-validation subsystem + /// can be sure that the PVF is invalid. To give a couple of examples: a PVF that cannot be + /// decompressed or that does not represent a structurally valid WebAssembly file. + Invalid, + /// This variant is used when the PVF cannot be compiled but for other reasons that are not + /// included into [`PreCheckOutcome::Invalid`]. This variant can indicate that the PVF in + /// question is invalid, however it is not necessary that PVF that received this judgement + /// is invalid. + /// + /// For example, if during compilation the preparation worker was killed we cannot be sure why + /// it happened: because the PVF was malicious made the worker to use too much memory or its + /// because the host machine is under severe memory pressure and it decided to kill the worker. + Failed, +} + +/// Messages received by the Validation subsystem. +/// +/// ## Validation Requests +/// +/// Validation requests made to the subsystem should return an error only on internal error. +/// Otherwise, they should return either `Ok(ValidationResult::Valid(_))` +/// or `Ok(ValidationResult::Invalid)`. +#[derive(Debug)] +pub enum CandidateValidationMessage { + /// Validate a candidate with provided parameters using relay-chain state. + /// + /// This will implicitly attempt to gather the `PersistedValidationData` and `ValidationCode` + /// from the runtime API of the chain, based on the `relay_parent` + /// of the `CandidateReceipt`. + /// + /// This will also perform checking of validation outputs against the acceptance criteria. + /// + /// If there is no state available which can provide this data or the core for + /// the para is not free at the relay-parent, an error is returned. + ValidateFromChainState( + CandidateReceipt, + Arc, + /// Execution timeout + PvfExecTimeoutKind, + oneshot::Sender>, + ), + /// Validate a candidate with provided, exhaustive parameters for validation. + /// + /// Explicitly provide the `PersistedValidationData` and `ValidationCode` so this can do full + /// validation without needing to access the state of the relay-chain. + /// + /// This request doesn't involve acceptance criteria checking, therefore only useful for the + /// cases where the validity of the candidate is established. This is the case for the typical + /// use-case: secondary checkers would use this request relying on the full prior checks + /// performed by the relay-chain. + ValidateFromExhaustive( + PersistedValidationData, + ValidationCode, + CandidateReceipt, + Arc, + /// Execution timeout + PvfExecTimeoutKind, + oneshot::Sender>, + ), + /// Try to compile the given validation code and send back + /// the outcome. + /// + /// The validation code is specified by the hash and will be queried from the runtime API at + /// the given relay-parent. + PreCheck( + // Relay-parent + Hash, + ValidationCodeHash, + oneshot::Sender, + ), +} + +/// Messages received by the Collator Protocol subsystem. +#[derive(Debug, derive_more::From)] +pub enum CollatorProtocolMessage { + /// Signal to the collator protocol that it should connect to validators with the expectation + /// of collating on the given para. This is only expected to be called once, early on, if at + /// all, and only by the Collation Generation subsystem. As such, it will overwrite the value + /// of the previous signal. + /// + /// This should be sent before any `DistributeCollation` message. + CollateOn(ParaId), + /// Provide a collation to distribute to validators with an optional result sender. + /// The second argument is the parent head-data hash. + /// + /// The result sender should be informed when at least one parachain validator seconded the + /// collation. It is also completely okay to just drop the sender. + DistributeCollation( + CandidateReceipt, + Hash, + PoV, + Option>, + ), + /// Report a collator as having provided an invalid collation. This should lead to disconnect + /// and blacklist of the collator. + ReportCollator(CollatorId), + /// Get a network bridge update. + #[from] + NetworkBridgeUpdate(NetworkBridgeEvent), + /// We recommended a particular candidate to be seconded, but it was invalid; penalize the + /// collator. + /// + /// The hash is the relay parent. + Invalid(Hash, CandidateReceipt), + /// The candidate we recommended to be seconded was validated successfully. + /// + /// The hash is the relay parent. + Seconded(Hash, SignedFullStatement), + /// The candidate received enough validity votes from the backing group. + Backed { + /// Candidate's para id. + para_id: ParaId, + /// Hash of the para head generated by candidate. + para_head: Hash, + }, +} + +impl Default for CollatorProtocolMessage { + fn default() -> Self { + Self::CollateOn(Default::default()) + } +} + +/// Messages received by the dispute coordinator subsystem. +/// +/// NOTE: Any response oneshots might get cancelled if the `DisputeCoordinator` was not yet +/// properly initialized for some reason. +#[derive(Debug)] +pub enum DisputeCoordinatorMessage { + /// Import statements by validators about a candidate. + /// + /// The subsystem will silently discard ancient statements or sets of only dispute-specific + /// statements for candidates that are previously unknown to the subsystem. The former is + /// simply because ancient data is not relevant and the latter is as a DoS prevention + /// mechanism. Both backing and approval statements already undergo anti-DoS procedures in + /// their respective subsystems, but statements cast specifically for disputes are not + /// necessarily relevant to any candidate the system is already aware of and thus present a DoS + /// vector. Our expectation is that nodes will notify each other of disputes over the network + /// by providing (at least) 2 conflicting statements, of which one is either a backing or + /// validation statement. + /// + /// This does not do any checking of the message signature. + ImportStatements { + /// The candidate receipt itself. + candidate_receipt: CandidateReceipt, + /// The session the candidate appears in. + session: SessionIndex, + /// Statements, with signatures checked, by validators participating in disputes. + /// + /// The validator index passed alongside each statement should correspond to the index + /// of the validator in the set. + statements: Vec<(SignedDisputeStatement, ValidatorIndex)>, + /// Inform the requester once we finished importing (if a sender was provided). + /// + /// This is: + /// - we discarded the votes because + /// - they were ancient or otherwise invalid (result: `InvalidImport`) + /// - or we were not able to recover availability for an unknown candidate (result: + /// `InvalidImport`) + /// - or were known already (in that case the result will still be `ValidImport`) + /// - or we recorded them because (`ValidImport`) + /// - we cast our own vote already on that dispute + /// - or we have approval votes on that candidate + /// - or other explicit votes on that candidate already recorded + /// - or recovered availability for the candidate + /// - or the imported statements are backing/approval votes, which are always accepted. + pending_confirmation: Option>, + }, + /// Fetch a list of all recent disputes the coordinator is aware of. + /// These are disputes which have occurred any time in recent sessions, + /// and which may have already concluded. + RecentDisputes(oneshot::Sender>), + /// Fetch a list of all active disputes that the coordinator is aware of. + /// These disputes are either not yet concluded or recently concluded. + ActiveDisputes(oneshot::Sender>), + /// Get candidate votes for a candidate. + QueryCandidateVotes( + Vec<(SessionIndex, CandidateHash)>, + oneshot::Sender>, + ), + /// Sign and issue local dispute votes. A value of `true` indicates validity, and `false` + /// invalidity. + IssueLocalStatement(SessionIndex, CandidateHash, CandidateReceipt, bool), + /// Determine the highest undisputed block within the given chain, based on where candidates + /// were included. If even the base block should not be finalized due to a dispute, + /// then `None` should be returned on the channel. + /// + /// The block descriptions begin counting upwards from the block after the given `base_number`. + /// The `base_number` is typically the number of the last finalized block but may be slightly + /// higher. This block is inevitably going to be finalized so it is not accounted for by this + /// function. + DetermineUndisputedChain { + /// The lowest possible block to vote on. + base: (BlockNumber, Hash), + /// Descriptions of all the blocks counting upwards from the block after the base number + block_descriptions: Vec, + /// The block to vote on, might be base in case there is no better. + tx: oneshot::Sender<(BlockNumber, Hash)>, + }, +} + +/// The result of `DisputeCoordinatorMessage::ImportStatements`. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum ImportStatementsResult { + /// Import was invalid (candidate was not available) and the sending peer should get banned. + InvalidImport, + /// Import was valid and can be confirmed to peer. + ValidImport, +} + +/// Messages going to the dispute distribution subsystem. +#[derive(Debug)] +pub enum DisputeDistributionMessage { + /// Tell dispute distribution to distribute an explicit dispute statement to + /// validators. + SendDispute(DisputeMessage), +} + +/// Messages received from other subsystems. +#[derive(Debug)] +pub enum NetworkBridgeRxMessage { + /// Inform the distribution subsystems about the new + /// gossip network topology formed. + /// + /// The only reason to have this here, is the availability of the + /// authority discovery service, otherwise, the `GossipSupport` + /// subsystem would make more sense. + NewGossipTopology { + /// The session info this gossip topology is concerned with. + session: SessionIndex, + /// Our validator index in the session, if any. + local_index: Option, + /// The canonical shuffling of validators for the session. + canonical_shuffling: Vec<(AuthorityDiscoveryId, ValidatorIndex)>, + /// The reverse mapping of `canonical_shuffling`: from validator index + /// to the index in `canonical_shuffling` + shuffled_indices: Vec, + }, + /// Inform the distribution subsystems about `AuthorityDiscoveryId` key rotations. + UpdatedAuthorityIds { + /// The `PeerId` of the peer that updated its `AuthorityDiscoveryId`s. + peer_id: PeerId, + /// The updated authority discovery keys of the peer. + authority_ids: HashSet, + }, +} + +/// Type of peer reporting +#[derive(Debug)] +pub enum ReportPeerMessage { + /// Single peer report about malicious actions which should be sent right away + Single(PeerId, ReputationChange), + /// Delayed report for other actions. + Batch(HashMap), +} + +/// Messages received from other subsystems by the network bridge subsystem. +#[derive(Debug)] +pub enum NetworkBridgeTxMessage { + /// Report a peer for their actions. + ReportPeer(ReportPeerMessage), + + /// Disconnect a peer from the given peer-set without affecting their reputation. + DisconnectPeer(PeerId, PeerSet), + + /// Send a message to one or more peers on the validation peer-set. + SendValidationMessage(Vec, net_protocol::VersionedValidationProtocol), + + /// Send a message to one or more peers on the collation peer-set. + SendCollationMessage(Vec, net_protocol::VersionedCollationProtocol), + + /// Send a batch of validation messages. + /// + /// NOTE: Messages will be processed in order (at least statement distribution relies on this). + SendValidationMessages(Vec<(Vec, net_protocol::VersionedValidationProtocol)>), + + /// Send a batch of collation messages. + /// + /// NOTE: Messages will be processed in order. + SendCollationMessages(Vec<(Vec, net_protocol::VersionedCollationProtocol)>), + + /// Send requests via substrate request/response. + /// Second parameter, tells what to do if we are not yet connected to the peer. + SendRequests(Vec, IfDisconnected), + + /// Connect to peers who represent the given `validator_ids`. + /// + /// Also ask the network to stay connected to these peers at least + /// until a new request is issued. + /// + /// Because it overrides the previous request, it must be ensured + /// that `validator_ids` include all peers the subsystems + /// are interested in (per `PeerSet`). + /// + /// A caller can learn about validator connections by listening to the + /// `PeerConnected` events from the network bridge. + ConnectToValidators { + /// Ids of the validators to connect to. + validator_ids: Vec, + /// The underlying protocol to use for this request. + peer_set: PeerSet, + /// Sends back the number of `AuthorityDiscoveryId`s which + /// authority discovery has failed to resolve. + failed: oneshot::Sender, + }, + /// Alternative to `ConnectToValidators` in case you already know the `Multiaddrs` you want to + /// be connected to. + ConnectToResolvedValidators { + /// Each entry corresponds to the addresses of an already resolved validator. + validator_addrs: Vec>, + /// The peer set we want the connection on. + peer_set: PeerSet, + }, +} + +/// Availability Distribution Message. +#[derive(Debug)] +pub enum AvailabilityDistributionMessage { + /// Instruct availability distribution to fetch a remote PoV. + /// + /// NOTE: The result of this fetch is not yet locally validated and could be bogus. + FetchPoV { + /// The relay parent giving the necessary context. + relay_parent: Hash, + /// Validator to fetch the PoV from. + from_validator: ValidatorIndex, + /// The id of the parachain that produced this PoV. + /// This field is only used to provide more context when logging errors + /// from the `AvailabilityDistribution` subsystem. + para_id: ParaId, + /// Candidate hash to fetch the PoV for. + candidate_hash: CandidateHash, + /// Expected hash of the PoV, a PoV not matching this hash will be rejected. + pov_hash: Hash, + /// Sender for getting back the result of this fetch. + /// + /// The sender will be canceled if the fetching failed for some reason. + tx: oneshot::Sender, + }, +} + +/// Availability Recovery Message. +#[derive(Debug, derive_more::From)] +pub enum AvailabilityRecoveryMessage { + /// Recover available data from validators on the network. + RecoverAvailableData( + CandidateReceipt, + SessionIndex, + Option, // Optional backing group to request from first. + oneshot::Sender>, + ), +} + +/// Bitfield distribution message. +#[derive(Debug, derive_more::From)] +pub enum BitfieldDistributionMessage { + /// Distribute a bitfield via gossip to other validators. + DistributeBitfield(Hash, SignedAvailabilityBitfield), + + /// Event from the network bridge. + #[from] + NetworkBridgeUpdate(NetworkBridgeEvent), +} + +/// Availability store subsystem message. +#[derive(Debug)] +pub enum AvailabilityStoreMessage { + /// Query a `AvailableData` from the AV store. + QueryAvailableData(CandidateHash, oneshot::Sender>), + + /// Query whether a `AvailableData` exists within the AV Store. + /// + /// This is useful in cases when existence + /// matters, but we don't want to necessarily pass around multiple + /// megabytes of data to get a single bit of information. + QueryDataAvailability(CandidateHash, oneshot::Sender), + + /// Query an `ErasureChunk` from the AV store by the candidate hash and validator index. + QueryChunk(CandidateHash, ValidatorIndex, oneshot::Sender>), + + /// Get the size of an `ErasureChunk` from the AV store by the candidate hash. + QueryChunkSize(CandidateHash, oneshot::Sender>), + + /// Query all chunks that we have for the given candidate hash. + QueryAllChunks(CandidateHash, oneshot::Sender>), + + /// Query whether an `ErasureChunk` exists within the AV Store. + /// + /// This is useful in cases like bitfield signing, when existence + /// matters, but we don't want to necessarily pass around large + /// quantities of data to get a single bit of information. + QueryChunkAvailability(CandidateHash, ValidatorIndex, oneshot::Sender), + + /// Store an `ErasureChunk` in the AV store. + /// + /// Return `Ok(())` if the store operation succeeded, `Err(())` if it failed. + StoreChunk { + /// A hash of the candidate this chunk belongs to. + candidate_hash: CandidateHash, + /// The chunk itself. + chunk: ErasureChunk, + /// Sending side of the channel to send result to. + tx: oneshot::Sender>, + }, + + /// Computes and checks the erasure root of `AvailableData` before storing all of its chunks in + /// the AV store. + /// + /// Return `Ok(())` if the store operation succeeded, `Err(StoreAvailableData)` if it failed. + StoreAvailableData { + /// A hash of the candidate this `available_data` belongs to. + candidate_hash: CandidateHash, + /// The number of validators in the session. + n_validators: u32, + /// The `AvailableData` itself. + available_data: AvailableData, + /// Erasure root we expect to get after chunking. + expected_erasure_root: Hash, + /// Sending side of the channel to send result to. + tx: oneshot::Sender>, + }, +} + +/// The error result type of a [`AvailabilityStoreMessage::StoreAvailableData`] request. +#[derive(Error, Debug, Clone, PartialEq, Eq)] +#[allow(missing_docs)] +pub enum StoreAvailableDataError { + #[error("The computed erasure root did not match expected one")] + InvalidErasureRoot, +} + +/// A response channel for the result of a chain API request. +pub type ChainApiResponseChannel = oneshot::Sender>; + +/// Chain API request subsystem message. +#[derive(Debug)] +pub enum ChainApiMessage { + /// Request the block number by hash. + /// Returns `None` if a block with the given hash is not present in the db. + BlockNumber(Hash, ChainApiResponseChannel>), + /// Request the block header by hash. + /// Returns `None` if a block with the given hash is not present in the db. + BlockHeader(Hash, ChainApiResponseChannel>), + /// Get the cumulative weight of the given block, by hash. + /// If the block or weight is unknown, this returns `None`. + /// + /// Note: this is the weight within the low-level fork-choice rule, + /// not the high-level one implemented in the chain-selection subsystem. + /// + /// Weight is used for comparing blocks in a fork-choice rule. + BlockWeight(Hash, ChainApiResponseChannel>), + /// Request the finalized block hash by number. + /// Returns `None` if a block with the given number is not present in the db. + /// Note: the caller must ensure the block is finalized. + FinalizedBlockHash(BlockNumber, ChainApiResponseChannel>), + /// Request the last finalized block number. + /// This request always succeeds. + FinalizedBlockNumber(ChainApiResponseChannel), + /// Request the `k` ancestor block hashes of a block with the given hash. + /// The response channel may return a `Vec` of size up to `k` + /// filled with ancestors hashes with the following order: + /// `parent`, `grandparent`, ... up to the hash of genesis block + /// with number 0, including it. + Ancestors { + /// The hash of the block in question. + hash: Hash, + /// The number of ancestors to request. + k: usize, + /// The response channel. + response_channel: ChainApiResponseChannel>, + }, +} + +/// Chain selection subsystem messages +#[derive(Debug)] +pub enum ChainSelectionMessage { + /// Signal to the chain selection subsystem that a specific block has been approved. + Approved(Hash), + /// Request the leaves in descending order by score. + Leaves(oneshot::Sender>), + /// Request the best leaf containing the given block in its ancestry. Return `None` if + /// there is no such leaf. + BestLeafContaining(Hash, oneshot::Sender>), + /// The passed blocks must be marked as reverted, and their children must be marked + /// as non-viable. + RevertBlocks(Vec<(BlockNumber, Hash)>), +} + +/// A sender for the result of a runtime API request. +pub type RuntimeApiSender = oneshot::Sender>; + +/// A request to the Runtime API subsystem. +#[derive(Debug)] +pub enum RuntimeApiRequest { + /// Get the version of the runtime API, if any. + Version(RuntimeApiSender), + /// Get the next, current and some previous authority discovery set deduplicated. + Authorities(RuntimeApiSender>), + /// Get the current validator set. + Validators(RuntimeApiSender>), + /// Get the validator groups and group rotation info. + ValidatorGroups(RuntimeApiSender<(Vec>, GroupRotationInfo)>), + /// Get information on all availability cores. + AvailabilityCores(RuntimeApiSender>), + /// Get the persisted validation data for a particular para, taking the given + /// `OccupiedCoreAssumption`, which will inform on how the validation data should be computed + /// if the para currently occupies a core. + PersistedValidationData( + ParaId, + OccupiedCoreAssumption, + RuntimeApiSender>, + ), + /// Get the persisted validation data for a particular para along with the current validation + /// code hash, matching the data hash against an expected one. + AssumedValidationData( + ParaId, + Hash, + RuntimeApiSender>, + ), + /// Sends back `true` if the validation outputs pass all acceptance criteria checks. + CheckValidationOutputs( + ParaId, + polkadot_primitives::CandidateCommitments, + RuntimeApiSender, + ), + /// Get the session index that a child of the block will have. + SessionIndexForChild(RuntimeApiSender), + /// Get the validation code for a para, taking the given `OccupiedCoreAssumption`, which + /// will inform on how the validation data should be computed if the para currently + /// occupies a core. + ValidationCode(ParaId, OccupiedCoreAssumption, RuntimeApiSender>), + /// Get validation code by its hash, either past, current or future code can be returned, as + /// long as state is still available. + ValidationCodeByHash(ValidationCodeHash, RuntimeApiSender>), + /// Get a the candidate pending availability for a particular parachain by parachain / core + /// index + CandidatePendingAvailability(ParaId, RuntimeApiSender>), + /// Get all events concerning candidates (backing, inclusion, time-out) in the parent of + /// the block in whose state this request is executed. + CandidateEvents(RuntimeApiSender>), + /// Get the execution environment parameter set by session index + SessionExecutorParams(SessionIndex, RuntimeApiSender>), + /// Get the session info for the given session, if stored. + SessionInfo(SessionIndex, RuntimeApiSender>), + /// Get all the pending inbound messages in the downward message queue for a para. + DmqContents(ParaId, RuntimeApiSender>>), + /// Get the contents of all channels addressed to the given recipient. Channels that have no + /// messages in them are also included. + InboundHrmpChannelsContents( + ParaId, + RuntimeApiSender>>>, + ), + /// Get information about the BABE epoch the block was included in. + CurrentBabeEpoch(RuntimeApiSender), + /// Get all disputes in relation to a relay parent. + FetchOnChainVotes(RuntimeApiSender>), + /// Submits a PVF pre-checking statement into the transaction pool. + SubmitPvfCheckStatement(PvfCheckStatement, ValidatorSignature, RuntimeApiSender<()>), + /// Returns code hashes of PVFs that require pre-checking by validators in the active set. + PvfsRequirePrecheck(RuntimeApiSender>), + /// Get the validation code used by the specified para, taking the given + /// `OccupiedCoreAssumption`, which will inform on how the validation data should be computed + /// if the para currently occupies a core. + ValidationCodeHash( + ParaId, + OccupiedCoreAssumption, + RuntimeApiSender>, + ), + /// Returns all on-chain disputes at given block number. Available in `v3`. + Disputes(RuntimeApiSender)>>), + /// Returns a list of validators that lost a past session dispute and need to be slashed. + /// `V5` + UnappliedSlashes( + RuntimeApiSender>, + ), + /// Returns a merkle proof of a validator session key. + /// `V5` + KeyOwnershipProof(ValidatorId, RuntimeApiSender>), + /// Submits an unsigned extrinsic to slash validator who lost a past session dispute. + /// `V5` + SubmitReportDisputeLost( + slashing::DisputeProof, + slashing::OpaqueKeyOwnershipProof, + RuntimeApiSender>, + ), + + /// Get the backing state of the given para. + /// This is a staging API that will not be available on production runtimes. + StagingParaBackingState(ParaId, RuntimeApiSender>), + /// Get candidate's acceptance limitations for asynchronous backing for a relay parent. + /// + /// If it's not supported by the Runtime, the async backing is said to be disabled. + StagingAsyncBackingParams(RuntimeApiSender), +} + +impl RuntimeApiRequest { + /// Runtime version requirements for each message + + /// `Disputes` + pub const DISPUTES_RUNTIME_REQUIREMENT: u32 = 3; + + /// `ExecutorParams` + pub const EXECUTOR_PARAMS_RUNTIME_REQUIREMENT: u32 = 4; + + /// `UnappliedSlashes` + pub const UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT: u32 = 5; + + /// `KeyOwnershipProof` + pub const KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT: u32 = 5; + + /// `SubmitReportDisputeLost` + pub const SUBMIT_REPORT_DISPUTE_LOST_RUNTIME_REQUIREMENT: u32 = 5; + + /// Minimum version for backing state, required for async backing. + /// + /// 99 for now, should be adjusted to VSTAGING/actual runtime version once released. + pub const STAGING_BACKING_STATE: u32 = 99; +} + +/// A message to the Runtime API subsystem. +#[derive(Debug)] +pub enum RuntimeApiMessage { + /// Make a request of the runtime API against the post-state of the given relay-parent. + Request(Hash, RuntimeApiRequest), +} + +/// Statement distribution message. +#[derive(Debug, derive_more::From)] +pub enum StatementDistributionMessage { + /// We have originated a signed statement in the context of + /// given relay-parent hash and it should be distributed to other validators. + Share(Hash, SignedFullStatementWithPVD), + /// The candidate received enough validity votes from the backing group. + /// + /// If the candidate is backed as a result of a local statement, this message MUST + /// be preceded by a `Share` message for that statement. This ensures that Statement + /// Distribution is always aware of full candidates prior to receiving the `Backed` + /// notification, even when the group size is 1 and the candidate is seconded locally. + Backed(CandidateHash), + /// Event from the network bridge. + #[from] + NetworkBridgeUpdate(NetworkBridgeEvent), +} + +/// This data becomes intrinsics or extrinsics which should be included in a future relay chain +/// block. +// It needs to be cloneable because multiple potential block authors can request copies. +#[derive(Debug, Clone)] +pub enum ProvisionableData { + /// This bitfield indicates the availability of various candidate blocks. + Bitfield(Hash, SignedAvailabilityBitfield), + /// The Candidate Backing subsystem believes that this candidate is valid, pending + /// availability. + BackedCandidate(CandidateReceipt), + /// Misbehavior reports are self-contained proofs of validator misbehavior. + MisbehaviorReport(Hash, ValidatorIndex, Misbehavior), + /// Disputes trigger a broad dispute resolution process. + Dispute(Hash, ValidatorSignature), +} + +/// Inherent data returned by the provisioner +#[derive(Debug, Clone)] +pub struct ProvisionerInherentData { + /// Signed bitfields. + pub bitfields: SignedAvailabilityBitfields, + /// Backed candidates. + pub backed_candidates: Vec, + /// Dispute statement sets. + pub disputes: MultiDisputeStatementSet, +} + +/// Message to the Provisioner. +/// +/// In all cases, the Hash is that of the relay parent. +#[derive(Debug)] +pub enum ProvisionerMessage { + /// This message allows external subsystems to request the set of bitfields and backed + /// candidates associated with a particular potential block hash. + /// + /// This is expected to be used by a proposer, to inject that information into the + /// `InherentData` where it can be assembled into the `ParaInherent`. + RequestInherentData(Hash, oneshot::Sender), + /// This data should become part of a relay chain block + ProvisionableData(Hash, ProvisionableData), +} + +/// Message to the Collation Generation subsystem. +#[derive(Debug)] +pub enum CollationGenerationMessage { + /// Initialize the collation generation subsystem + Initialize(CollationGenerationConfig), + /// Submit a collation to the subsystem. This will package it into a signed + /// [`CommittedCandidateReceipt`] and distribute along the network to validators. + /// + /// If sent before `Initialize`, this will be ignored. + SubmitCollation(SubmitCollationParams), +} + +/// The result type of [`ApprovalVotingMessage::CheckAndImportAssignment`] request. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum AssignmentCheckResult { + /// The vote was accepted and should be propagated onwards. + Accepted, + /// The vote was valid but duplicate and should not be propagated onwards. + AcceptedDuplicate, + /// The vote was valid but too far in the future to accept right now. + TooFarInFuture, + /// The vote was bad and should be ignored, reporting the peer who propagated it. + Bad(AssignmentCheckError), +} + +/// The error result type of [`ApprovalVotingMessage::CheckAndImportAssignment`] request. +#[derive(Error, Debug, Clone, PartialEq, Eq)] +#[allow(missing_docs)] +pub enum AssignmentCheckError { + #[error("Unknown block: {0:?}")] + UnknownBlock(Hash), + #[error("Unknown session index: {0}")] + UnknownSessionIndex(SessionIndex), + #[error("Invalid candidate index: {0}")] + InvalidCandidateIndex(CandidateIndex), + #[error("Invalid candidate {0}: {1:?}")] + InvalidCandidate(CandidateIndex, CandidateHash), + #[error("Invalid cert: {0:?}, reason: {1}")] + InvalidCert(ValidatorIndex, String), + #[error("Internal state mismatch: {0:?}, {1:?}")] + Internal(Hash, CandidateHash), +} + +/// The result type of [`ApprovalVotingMessage::CheckAndImportApproval`] request. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ApprovalCheckResult { + /// The vote was accepted and should be propagated onwards. + Accepted, + /// The vote was bad and should be ignored, reporting the peer who propagated it. + Bad(ApprovalCheckError), +} + +/// The error result type of [`ApprovalVotingMessage::CheckAndImportApproval`] request. +#[derive(Error, Debug, Clone, PartialEq, Eq)] +#[allow(missing_docs)] +pub enum ApprovalCheckError { + #[error("Unknown block: {0:?}")] + UnknownBlock(Hash), + #[error("Unknown session index: {0}")] + UnknownSessionIndex(SessionIndex), + #[error("Invalid candidate index: {0}")] + InvalidCandidateIndex(CandidateIndex), + #[error("Invalid validator index: {0:?}")] + InvalidValidatorIndex(ValidatorIndex), + #[error("Invalid candidate {0}: {1:?}")] + InvalidCandidate(CandidateIndex, CandidateHash), + #[error("Invalid signature: {0:?}")] + InvalidSignature(ValidatorIndex), + #[error("No assignment for {0:?}")] + NoAssignment(ValidatorIndex), + #[error("Internal state mismatch: {0:?}, {1:?}")] + Internal(Hash, CandidateHash), +} + +/// Describes a relay-chain block by the para-chain candidates +/// it includes. +#[derive(Clone, Debug)] +pub struct BlockDescription { + /// The relay-chain block hash. + pub block_hash: Hash, + /// The session index of this block. + pub session: SessionIndex, + /// The set of para-chain candidates. + pub candidates: Vec, +} + +/// Response type to `ApprovalVotingMessage::ApprovedAncestor`. +#[derive(Clone, Debug)] +pub struct HighestApprovedAncestorBlock { + /// The block hash of the highest viable ancestor. + pub hash: Hash, + /// The block number of the highest viable ancestor. + pub number: BlockNumber, + /// Block descriptions in the direct path between the + /// initially provided hash and the highest viable ancestor. + /// Primarily for use with `DetermineUndisputedChain`. + /// Must be sorted from lowest to highest block number. + pub descriptions: Vec, +} + +/// Message to the Approval Voting subsystem. +#[derive(Debug)] +pub enum ApprovalVotingMessage { + /// Check if the assignment is valid and can be accepted by our view of the protocol. + /// Should not be sent unless the block hash is known. + CheckAndImportAssignment( + IndirectAssignmentCert, + CandidateIndex, + oneshot::Sender, + ), + /// Check if the approval vote is valid and can be accepted by our view of the + /// protocol. + /// + /// Should not be sent unless the block hash within the indirect vote is known. + CheckAndImportApproval(IndirectSignedApprovalVote, oneshot::Sender), + /// Returns the highest possible ancestor hash of the provided block hash which is + /// acceptable to vote on finality for. + /// The `BlockNumber` provided is the number of the block's ancestor which is the + /// earliest possible vote. + /// + /// It can also return the same block hash, if that is acceptable to vote upon. + /// Return `None` if the input hash is unrecognized. + ApprovedAncestor(Hash, BlockNumber, oneshot::Sender>), + + /// Retrieve all available approval signatures for a candidate from approval-voting. + /// + /// This message involves a linear search for candidates on each relay chain fork and also + /// requires calling into `approval-distribution`: Calls should be infrequent and bounded. + GetApprovalSignaturesForCandidate( + CandidateHash, + oneshot::Sender>, + ), +} + +/// Message to the Approval Distribution subsystem. +#[derive(Debug, derive_more::From)] +pub enum ApprovalDistributionMessage { + /// Notify the `ApprovalDistribution` subsystem about new blocks + /// and the candidates contained within them. + NewBlocks(Vec), + /// Distribute an assignment cert from the local validator. The cert is assumed + /// to be valid, relevant, and for the given relay-parent and validator index. + DistributeAssignment(IndirectAssignmentCert, CandidateIndex), + /// Distribute an approval vote for the local validator. The approval vote is assumed to be + /// valid, relevant, and the corresponding approval already issued. + /// If not, the subsystem is free to drop the message. + DistributeApproval(IndirectSignedApprovalVote), + /// An update from the network bridge. + #[from] + NetworkBridgeUpdate(NetworkBridgeEvent), + + /// Get all approval signatures for all chains a candidate appeared in. + GetApprovalSignatures( + HashSet<(Hash, CandidateIndex)>, + oneshot::Sender>, + ), + /// Approval checking lag update measured in blocks. + ApprovalCheckingLagUpdate(BlockNumber), +} + +/// Message to the Gossip Support subsystem. +#[derive(Debug, derive_more::From)] +pub enum GossipSupportMessage { + /// Dummy constructor, so we can receive networking events. + #[from] + NetworkBridgeUpdate(NetworkBridgeEvent), +} + +/// Request introduction of a candidate into the prospective parachains subsystem. +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct IntroduceCandidateRequest { + /// The para-id of the candidate. + pub candidate_para: ParaId, + /// The candidate receipt itself. + pub candidate_receipt: CommittedCandidateReceipt, + /// The persisted validation data of the candidate. + pub persisted_validation_data: PersistedValidationData, +} + +/// A hypothetical candidate to be evaluated for frontier membership +/// in the prospective parachains subsystem. +/// +/// Hypothetical candidates are either complete or incomplete. +/// Complete candidates have already had their (potentially heavy) +/// candidate receipt fetched, while incomplete candidates are simply +/// claims about properties that a fetched candidate would have. +/// +/// Complete candidates can be evaluated more strictly than incomplete candidates. +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum HypotheticalCandidate { + /// A complete candidate. + Complete { + /// The hash of the candidate. + candidate_hash: CandidateHash, + /// The receipt of the candidate. + receipt: Arc, + /// The persisted validation data of the candidate. + persisted_validation_data: PersistedValidationData, + }, + /// An incomplete candidate. + Incomplete { + /// The claimed hash of the candidate. + candidate_hash: CandidateHash, + /// The claimed para-ID of the candidate. + candidate_para: ParaId, + /// The claimed head-data hash of the candidate. + parent_head_data_hash: Hash, + /// The claimed relay parent of the candidate. + candidate_relay_parent: Hash, + }, +} + +impl HypotheticalCandidate { + /// Get the `CandidateHash` of the hypothetical candidate. + pub fn candidate_hash(&self) -> CandidateHash { + match *self { + HypotheticalCandidate::Complete { candidate_hash, .. } => candidate_hash, + HypotheticalCandidate::Incomplete { candidate_hash, .. } => candidate_hash, + } + } + + /// Get the `ParaId` of the hypothetical candidate. + pub fn candidate_para(&self) -> ParaId { + match *self { + HypotheticalCandidate::Complete { ref receipt, .. } => receipt.descriptor().para_id, + HypotheticalCandidate::Incomplete { candidate_para, .. } => candidate_para, + } + } + + /// Get parent head data hash of the hypothetical candidate. + pub fn parent_head_data_hash(&self) -> Hash { + match *self { + HypotheticalCandidate::Complete { ref persisted_validation_data, .. } => + persisted_validation_data.parent_head.hash(), + HypotheticalCandidate::Incomplete { parent_head_data_hash, .. } => + parent_head_data_hash, + } + } + + /// Get candidate's relay parent. + pub fn relay_parent(&self) -> Hash { + match *self { + HypotheticalCandidate::Complete { ref receipt, .. } => + receipt.descriptor().relay_parent, + HypotheticalCandidate::Incomplete { candidate_relay_parent, .. } => + candidate_relay_parent, + } + } +} + +/// Request specifying which candidates are either already included +/// or might be included in the hypothetical frontier of fragment trees +/// under a given active leaf. +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct HypotheticalFrontierRequest { + /// Candidates, in arbitrary order, which should be checked for + /// possible membership in fragment trees. + pub candidates: Vec, + /// Either a specific fragment tree to check, otherwise all. + pub fragment_tree_relay_parent: Option, + /// Only return membership if all candidates in the path from the + /// root are backed. + pub backed_in_path_only: bool, +} + +/// A request for the persisted validation data stored in the prospective +/// parachains subsystem. +#[derive(Debug)] +pub struct ProspectiveValidationDataRequest { + /// The para-id of the candidate. + pub para_id: ParaId, + /// The relay-parent of the candidate. + pub candidate_relay_parent: Hash, + /// The parent head-data hash. + pub parent_head_data_hash: Hash, +} + +/// Indicates the relay-parents whose fragment tree a candidate +/// is present in and the depths of that tree the candidate is present in. +pub type FragmentTreeMembership = Vec<(Hash, Vec)>; + +/// Messages sent to the Prospective Parachains subsystem. +#[derive(Debug)] +pub enum ProspectiveParachainsMessage { + /// Inform the Prospective Parachains Subsystem of a new candidate. + /// + /// The response sender accepts the candidate membership, which is the existing + /// membership of the candidate if it was already known. + IntroduceCandidate(IntroduceCandidateRequest, oneshot::Sender), + /// Inform the Prospective Parachains Subsystem that a previously introduced candidate + /// has been seconded. This requires that the candidate was successfully introduced in + /// the past. + CandidateSeconded(ParaId, CandidateHash), + /// Inform the Prospective Parachains Subsystem that a previously introduced candidate + /// has been backed. This requires that the candidate was successfully introduced in + /// the past. + CandidateBacked(ParaId, CandidateHash), + /// Get a backable candidate hash along with its relay parent for the given parachain, + /// under the given relay-parent hash, which is a descendant of the given candidate hashes. + /// Returns `None` on the channel if no such candidate exists. + GetBackableCandidate( + Hash, + ParaId, + Vec, + oneshot::Sender>, + ), + /// Get the hypothetical frontier membership of candidates with the given properties + /// under the specified active leaves' fragment trees. + /// + /// For any candidate which is already known, this returns the depths the candidate + /// occupies. + GetHypotheticalFrontier( + HypotheticalFrontierRequest, + oneshot::Sender>, + ), + /// Get the membership of the candidate in all fragment trees. + GetTreeMembership(ParaId, CandidateHash, oneshot::Sender), + /// Get the minimum accepted relay-parent number for each para in the fragment tree + /// for the given relay-chain block hash. + /// + /// That is, if the block hash is known and is an active leaf, this returns the + /// minimum relay-parent block number in the same branch of the relay chain which + /// is accepted in the fragment tree for each para-id. + /// + /// If the block hash is not an active leaf, this will return an empty vector. + /// + /// Para-IDs which are omitted from this list can be assumed to have no + /// valid candidate relay-parents under the given relay-chain block hash. + /// + /// Para-IDs are returned in no particular order. + GetMinimumRelayParents(Hash, oneshot::Sender>), + /// Get the validation data of some prospective candidate. The candidate doesn't need + /// to be part of any fragment tree, but this only succeeds if the parent head-data and + /// relay-parent are part of some fragment tree. + GetProspectiveValidationData( + ProspectiveValidationDataRequest, + oneshot::Sender>, + ), +} diff --git a/polkadot/node/subsystem-types/src/messages/network_bridge_event.rs b/polkadot/node/subsystem-types/src/messages/network_bridge_event.rs new file mode 100644 index 0000000000000000000000000000000000000000..e6d7f64784ca0cffd1699fa59f7dcfce1cbd35a9 --- /dev/null +++ b/polkadot/node/subsystem-types/src/messages/network_bridge_event.rs @@ -0,0 +1,111 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use std::{collections::HashSet, convert::TryFrom}; + +pub use sc_network::{PeerId, ReputationChange}; + +use polkadot_node_network_protocol::{ + grid_topology::SessionGridTopology, peer_set::ProtocolVersion, ObservedRole, OurView, View, + WrongVariant, +}; +use polkadot_primitives::{AuthorityDiscoveryId, SessionIndex, ValidatorIndex}; + +/// A struct indicating new gossip topology. +#[derive(Debug, Clone, PartialEq)] +pub struct NewGossipTopology { + /// The session index this topology corresponds to. + pub session: SessionIndex, + /// The topology itself. + pub topology: SessionGridTopology, + /// The local validator index, if any. + pub local_index: Option, +} + +/// Events from network. +#[derive(Debug, Clone, PartialEq)] +pub enum NetworkBridgeEvent { + /// A peer has connected. + PeerConnected(PeerId, ObservedRole, ProtocolVersion, Option>), + + /// A peer has disconnected. + PeerDisconnected(PeerId), + + /// Our neighbors in the new gossip topology for the session. + /// We're not necessarily connected to all of them. + /// + /// This message is issued only on the validation peer set. + /// + /// Note, that the distribution subsystems need to handle the last + /// view update of the newly added gossip peers manually. + NewGossipTopology(NewGossipTopology), + + /// Peer has sent a message. + PeerMessage(PeerId, M), + + /// Peer's `View` has changed. + PeerViewChange(PeerId, View), + + /// Our view has changed. + OurViewChange(OurView), + + /// The authority discovery session key has been rotated. + UpdatedAuthorityIds(PeerId, HashSet), +} + +impl NetworkBridgeEvent { + /// Focus an overarching network-bridge event into some more specific variant. + /// + /// This tries to transform M in `PeerMessage` to a message type specific to a subsystem. + /// It is used to dispatch events coming from a peer set to the various subsystems that are + /// handled within that peer set. More concretely a `ValidationProtocol` will be transformed + /// for example into a `BitfieldDistributionMessage` in case of the `BitfieldDistribution` + /// constructor. + /// + /// Therefore a `NetworkBridgeEvent` will become for example a + /// `NetworkBridgeEvent`, with the more specific message type + /// `BitfieldDistributionMessage`. + /// + /// This acts as a call to `clone`, except in the case where the event is a message event, + /// in which case the clone can be expensive and it only clones if the message type can + /// be focused. + pub fn focus<'a, T>(&'a self) -> Result, WrongVariant> + where + T: 'a + Clone, + T: TryFrom<&'a M, Error = WrongVariant>, + { + Ok(match *self { + NetworkBridgeEvent::PeerMessage(ref peer, ref msg) => + NetworkBridgeEvent::PeerMessage(*peer, T::try_from(msg)?), + NetworkBridgeEvent::PeerConnected( + ref peer, + ref role, + ref version, + ref authority_id, + ) => NetworkBridgeEvent::PeerConnected(*peer, *role, *version, authority_id.clone()), + NetworkBridgeEvent::PeerDisconnected(ref peer) => + NetworkBridgeEvent::PeerDisconnected(*peer), + NetworkBridgeEvent::NewGossipTopology(ref topology) => + NetworkBridgeEvent::NewGossipTopology(topology.clone()), + NetworkBridgeEvent::PeerViewChange(ref peer, ref view) => + NetworkBridgeEvent::PeerViewChange(*peer, view.clone()), + NetworkBridgeEvent::OurViewChange(ref view) => + NetworkBridgeEvent::OurViewChange(view.clone()), + NetworkBridgeEvent::UpdatedAuthorityIds(ref peer, ref authority_ids) => + NetworkBridgeEvent::UpdatedAuthorityIds(*peer, authority_ids.clone()), + }) + } +} diff --git a/polkadot/node/subsystem-types/src/runtime_client.rs b/polkadot/node/subsystem-types/src/runtime_client.rs new file mode 100644 index 0000000000000000000000000000000000000000..312cc4eec6ce997ef0c5370097bf2146e4c473bc --- /dev/null +++ b/polkadot/node/subsystem-types/src/runtime_client.rs @@ -0,0 +1,491 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use async_trait::async_trait; +use polkadot_primitives::{ + runtime_api::ParachainHost, vstaging, Block, BlockNumber, CandidateCommitments, CandidateEvent, + CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, + GroupRotationInfo, Hash, Id, InboundDownwardMessage, InboundHrmpMessage, + OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, + SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, + ValidatorSignature, +}; +use sc_transaction_pool_api::OffchainTransactionPoolFactory; +use sp_api::{ApiError, ApiExt, ProvideRuntimeApi}; +use sp_authority_discovery::AuthorityDiscoveryApi; +use sp_consensus_babe::{BabeApi, Epoch}; +use std::{collections::BTreeMap, sync::Arc}; + +/// Exposes all runtime calls that are used by the runtime API subsystem. +#[async_trait] +pub trait RuntimeApiSubsystemClient { + /// Parachain host API version + async fn api_version_parachain_host(&self, at: Hash) -> Result, ApiError>; + + // === ParachainHost API === + + /// Get the current validators. + async fn validators(&self, at: Hash) -> Result, ApiError>; + + /// Returns the validator groups and rotation info localized based on the hypothetical child + /// of a block whose state this is invoked on. Note that `now` in the `GroupRotationInfo` + /// should be the successor of the number of the block. + async fn validator_groups( + &self, + at: Hash, + ) -> Result<(Vec>, GroupRotationInfo), ApiError>; + + /// Yields information on all availability cores as relevant to the child block. + /// Cores are either free or occupied. Free cores can have paras assigned to them. + async fn availability_cores( + &self, + at: Hash, + ) -> Result>, ApiError>; + + /// Yields the persisted validation data for the given `ParaId` along with an assumption that + /// should be used if the para currently occupies a core. + /// + /// Returns `None` if either the para is not registered or the assumption is `Freed` + /// and the para already occupies a core. + async fn persisted_validation_data( + &self, + at: Hash, + para_id: Id, + assumption: OccupiedCoreAssumption, + ) -> Result>, ApiError>; + + /// Returns the persisted validation data for the given `ParaId` along with the corresponding + /// validation code hash. Instead of accepting assumption about the para, matches the validation + /// data hash against an expected one and yields `None` if they're not equal. + async fn assumed_validation_data( + &self, + at: Hash, + para_id: Id, + expected_persisted_validation_data_hash: Hash, + ) -> Result, ValidationCodeHash)>, ApiError>; + + /// Checks if the given validation outputs pass the acceptance criteria. + async fn check_validation_outputs( + &self, + at: Hash, + para_id: Id, + outputs: CandidateCommitments, + ) -> Result; + + /// Returns the session index expected at a child of the block. + /// + /// This can be used to instantiate a `SigningContext`. + async fn session_index_for_child(&self, at: Hash) -> Result; + + /// Fetch the validation code used by a para, making the given `OccupiedCoreAssumption`. + /// + /// Returns `None` if either the para is not registered or the assumption is `Freed` + /// and the para already occupies a core. + async fn validation_code( + &self, + at: Hash, + para_id: Id, + assumption: OccupiedCoreAssumption, + ) -> Result, ApiError>; + + /// Get the receipt of a candidate pending availability. This returns `Some` for any paras + /// assigned to occupied cores in `availability_cores` and `None` otherwise. + async fn candidate_pending_availability( + &self, + at: Hash, + para_id: Id, + ) -> Result>, ApiError>; + + /// Get a vector of events concerning candidates that occurred within a block. + async fn candidate_events(&self, at: Hash) -> Result>, ApiError>; + + /// Get all the pending inbound messages in the downward message queue for a para. + async fn dmq_contents( + &self, + at: Hash, + recipient: Id, + ) -> Result>, ApiError>; + + /// Get the contents of all channels addressed to the given recipient. Channels that have no + /// messages in them are also included. + async fn inbound_hrmp_channels_contents( + &self, + at: Hash, + recipient: Id, + ) -> Result>>, ApiError>; + + /// Get the validation code from its hash. + async fn validation_code_by_hash( + &self, + at: Hash, + hash: ValidationCodeHash, + ) -> Result, ApiError>; + + /// Scrape dispute relevant from on-chain, backing votes and resolved disputes. + async fn on_chain_votes(&self, at: Hash) + -> Result>, ApiError>; + + /***** Added in v2 **** */ + + /// Get the session info for the given session, if stored. + /// + /// NOTE: This function is only available since parachain host version 2. + async fn session_info( + &self, + at: Hash, + index: SessionIndex, + ) -> Result, ApiError>; + + /// Submits a PVF pre-checking statement into the transaction pool. + /// + /// NOTE: This function is only available since parachain host version 2. + async fn submit_pvf_check_statement( + &self, + at: Hash, + stmt: PvfCheckStatement, + signature: ValidatorSignature, + ) -> Result<(), ApiError>; + + /// Returns code hashes of PVFs that require pre-checking by validators in the active set. + /// + /// NOTE: This function is only available since parachain host version 2. + async fn pvfs_require_precheck(&self, at: Hash) -> Result, ApiError>; + + /// Fetch the hash of the validation code used by a para, making the given + /// `OccupiedCoreAssumption`. + /// + /// NOTE: This function is only available since parachain host version 2. + async fn validation_code_hash( + &self, + at: Hash, + para_id: Id, + assumption: OccupiedCoreAssumption, + ) -> Result, ApiError>; + + /***** Added in v3 **** */ + + /// Returns all onchain disputes. + /// This is a staging method! Do not use on production runtimes! + async fn disputes( + &self, + at: Hash, + ) -> Result)>, ApiError>; + + /// Returns a list of validators that lost a past session dispute and need to be slashed. + /// + /// WARNING: This is a staging method! Do not use on production runtimes! + async fn unapplied_slashes( + &self, + at: Hash, + ) -> Result, ApiError>; + + /// Returns a merkle proof of a validator session key in a past session. + /// + /// WARNING: This is a staging method! Do not use on production runtimes! + async fn key_ownership_proof( + &self, + at: Hash, + validator_id: ValidatorId, + ) -> Result, ApiError>; + + /// Submits an unsigned extrinsic to slash validators who lost a dispute about + /// a candidate of a past session. + /// + /// WARNING: This is a staging method! Do not use on production runtimes! + async fn submit_report_dispute_lost( + &self, + at: Hash, + dispute_proof: vstaging::slashing::DisputeProof, + key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof, + ) -> Result, ApiError>; + + // === BABE API === + + /// Returns information regarding the current epoch. + async fn current_epoch(&self, at: Hash) -> Result; + + // === AuthorityDiscovery API === + + /// Retrieve authority identifiers of the current and next authority set. + async fn authorities( + &self, + at: Hash, + ) -> std::result::Result, ApiError>; + + /// Get the execution environment parameter set by parent hash, if stored + async fn session_executor_params( + &self, + at: Hash, + session_index: SessionIndex, + ) -> Result, ApiError>; + + // === Asynchronous backing API === + + /// Returns candidate's acceptance limitations for asynchronous backing for a relay parent. + async fn staging_async_backing_params( + &self, + at: Hash, + ) -> Result; + + /// Returns the state of parachain backing for a given para. + /// This is a staging method! Do not use on production runtimes! + async fn staging_para_backing_state( + &self, + at: Hash, + para_id: Id, + ) -> Result, ApiError>; +} + +/// Default implementation of [`RuntimeApiSubsystemClient`] using the client. +pub struct DefaultSubsystemClient { + client: Arc, + offchain_transaction_pool_factory: OffchainTransactionPoolFactory, +} + +impl DefaultSubsystemClient { + /// Create new instance. + pub fn new( + client: Arc, + offchain_transaction_pool_factory: OffchainTransactionPoolFactory, + ) -> Self { + Self { client, offchain_transaction_pool_factory } + } +} + +#[async_trait] +impl RuntimeApiSubsystemClient for DefaultSubsystemClient +where + Client: ProvideRuntimeApi + Send + Sync, + Client::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, +{ + async fn validators(&self, at: Hash) -> Result, ApiError> { + self.client.runtime_api().validators(at) + } + + async fn validator_groups( + &self, + at: Hash, + ) -> Result<(Vec>, GroupRotationInfo), ApiError> { + self.client.runtime_api().validator_groups(at) + } + + async fn availability_cores( + &self, + at: Hash, + ) -> Result>, ApiError> { + self.client.runtime_api().availability_cores(at) + } + + async fn persisted_validation_data( + &self, + at: Hash, + para_id: Id, + assumption: OccupiedCoreAssumption, + ) -> Result>, ApiError> { + self.client.runtime_api().persisted_validation_data(at, para_id, assumption) + } + + async fn assumed_validation_data( + &self, + at: Hash, + para_id: Id, + expected_persisted_validation_data_hash: Hash, + ) -> Result, ValidationCodeHash)>, ApiError> + { + self.client.runtime_api().assumed_validation_data( + at, + para_id, + expected_persisted_validation_data_hash, + ) + } + + async fn check_validation_outputs( + &self, + at: Hash, + para_id: Id, + outputs: CandidateCommitments, + ) -> Result { + self.client.runtime_api().check_validation_outputs(at, para_id, outputs) + } + + async fn session_index_for_child(&self, at: Hash) -> Result { + self.client.runtime_api().session_index_for_child(at) + } + + async fn validation_code( + &self, + at: Hash, + para_id: Id, + assumption: OccupiedCoreAssumption, + ) -> Result, ApiError> { + self.client.runtime_api().validation_code(at, para_id, assumption) + } + + async fn candidate_pending_availability( + &self, + at: Hash, + para_id: Id, + ) -> Result>, ApiError> { + self.client.runtime_api().candidate_pending_availability(at, para_id) + } + + async fn candidate_events(&self, at: Hash) -> Result>, ApiError> { + self.client.runtime_api().candidate_events(at) + } + + async fn dmq_contents( + &self, + at: Hash, + recipient: Id, + ) -> Result>, ApiError> { + self.client.runtime_api().dmq_contents(at, recipient) + } + + async fn inbound_hrmp_channels_contents( + &self, + at: Hash, + recipient: Id, + ) -> Result>>, ApiError> { + self.client.runtime_api().inbound_hrmp_channels_contents(at, recipient) + } + + async fn validation_code_by_hash( + &self, + at: Hash, + hash: ValidationCodeHash, + ) -> Result, ApiError> { + self.client.runtime_api().validation_code_by_hash(at, hash) + } + + async fn on_chain_votes( + &self, + at: Hash, + ) -> Result>, ApiError> { + self.client.runtime_api().on_chain_votes(at) + } + + async fn session_executor_params( + &self, + at: Hash, + session_index: SessionIndex, + ) -> Result, ApiError> { + self.client.runtime_api().session_executor_params(at, session_index) + } + + async fn session_info( + &self, + at: Hash, + index: SessionIndex, + ) -> Result, ApiError> { + self.client.runtime_api().session_info(at, index) + } + + async fn submit_pvf_check_statement( + &self, + at: Hash, + stmt: PvfCheckStatement, + signature: ValidatorSignature, + ) -> Result<(), ApiError> { + let mut runtime_api = self.client.runtime_api(); + + runtime_api.register_extension( + self.offchain_transaction_pool_factory.offchain_transaction_pool(at), + ); + + runtime_api.submit_pvf_check_statement(at, stmt, signature) + } + + async fn pvfs_require_precheck(&self, at: Hash) -> Result, ApiError> { + self.client.runtime_api().pvfs_require_precheck(at) + } + + async fn validation_code_hash( + &self, + at: Hash, + para_id: Id, + assumption: OccupiedCoreAssumption, + ) -> Result, ApiError> { + self.client.runtime_api().validation_code_hash(at, para_id, assumption) + } + + async fn current_epoch(&self, at: Hash) -> Result { + self.client.runtime_api().current_epoch(at) + } + + async fn authorities( + &self, + at: Hash, + ) -> std::result::Result, ApiError> { + self.client.runtime_api().authorities(at) + } + + async fn api_version_parachain_host(&self, at: Hash) -> Result, ApiError> { + self.client.runtime_api().api_version::>(at) + } + + async fn disputes( + &self, + at: Hash, + ) -> Result)>, ApiError> { + self.client.runtime_api().disputes(at) + } + + async fn unapplied_slashes( + &self, + at: Hash, + ) -> Result, ApiError> { + self.client.runtime_api().unapplied_slashes(at) + } + + async fn key_ownership_proof( + &self, + at: Hash, + validator_id: ValidatorId, + ) -> Result, ApiError> { + self.client.runtime_api().key_ownership_proof(at, validator_id) + } + + async fn submit_report_dispute_lost( + &self, + at: Hash, + dispute_proof: vstaging::slashing::DisputeProof, + key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof, + ) -> Result, ApiError> { + let mut runtime_api = self.client.runtime_api(); + + runtime_api.register_extension( + self.offchain_transaction_pool_factory.offchain_transaction_pool(at), + ); + + runtime_api.submit_report_dispute_lost(at, dispute_proof, key_ownership_proof) + } + + async fn staging_para_backing_state( + &self, + at: Hash, + para_id: Id, + ) -> Result, ApiError> { + self.client.runtime_api().staging_para_backing_state(at, para_id) + } + + /// Returns candidate's acceptance limitations for asynchronous backing for a relay parent. + async fn staging_async_backing_params( + &self, + at: Hash, + ) -> Result { + self.client.runtime_api().staging_async_backing_params(at) + } +} diff --git a/polkadot/node/subsystem-util/Cargo.toml b/polkadot/node/subsystem-util/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..8c4de01ab31497adb12a0474af156b8b0a45e7ad --- /dev/null +++ b/polkadot/node/subsystem-util/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "polkadot-node-subsystem-util" +description = "Subsystem traits and message definitions" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +async-trait = "0.1.57" +futures = "0.3.21" +futures-channel = "0.3.23" +itertools = "0.10" +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +parking_lot = "0.11.2" +pin-project = "1.0.9" +rand = "0.8.5" +thiserror = "1.0.31" +fatality = "0.0.6" +gum = { package = "tracing-gum", path = "../gum" } +derive_more = "0.99.17" +lru = "0.11.0" + +polkadot-node-subsystem = {path = "../subsystem" } +polkadot-node-jaeger = { path = "../jaeger" } +polkadot-node-metrics = { path = "../metrics" } +polkadot-node-network-protocol = { path = "../network/protocol" } +polkadot-primitives = { path = "../../primitives" } +polkadot-node-primitives = { path = "../primitives" } +polkadot-overseer = { path = "../overseer" } +metered = { package = "prioritized-metered-channel", version = "0.2.0" } + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } + +kvdb = "0.13.0" +parity-db = { version = "0.4.8"} + +[dev-dependencies] +assert_matches = "1.4.0" +env_logger = "0.9.0" +futures = { version = "0.3.21", features = ["thread-pool"] } +log = "0.4.17" +polkadot-node-subsystem-test-helpers = { path = "../subsystem-test-helpers" } +lazy_static = "1.4.0" +polkadot-primitives-test-helpers = { path = "../../primitives/test-helpers" } +kvdb-shared-tests = "0.11.0" +tempfile = "3.1.0" +kvdb-memorydb = "0.13.0" diff --git a/polkadot/node/subsystem-util/src/backing_implicit_view.rs b/polkadot/node/subsystem-util/src/backing_implicit_view.rs new file mode 100644 index 0000000000000000000000000000000000000000..adf7fbd54258f9b2102348174b0b1cc3cb69bdb1 --- /dev/null +++ b/polkadot/node/subsystem-util/src/backing_implicit_view.rs @@ -0,0 +1,739 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use futures::channel::oneshot; +use polkadot_node_subsystem::{ + errors::ChainApiError, + messages::{ChainApiMessage, ProspectiveParachainsMessage}, + SubsystemSender, +}; +use polkadot_primitives::vstaging::{BlockNumber, Hash, Id as ParaId}; + +use std::collections::HashMap; + +// Always aim to retain 1 block before the active leaves. +const MINIMUM_RETAIN_LENGTH: BlockNumber = 2; + +/// Handles the implicit view of the relay chain derived from the immediate view, which +/// is composed of active leaves, and the minimum relay-parents allowed for +/// candidates of various parachains at those leaves. +#[derive(Default, Clone)] +pub struct View { + leaves: HashMap, + block_info_storage: HashMap, +} + +// Minimum relay parents implicitly relative to a particular block. +#[derive(Debug, Clone)] +struct AllowedRelayParents { + // minimum relay parents can only be fetched for active leaves, + // so this will be empty for all blocks that haven't ever been + // witnessed as active leaves. + minimum_relay_parents: HashMap, + // Ancestry, in descending order, starting from the block hash itself down + // to and including the minimum of `minimum_relay_parents`. + allowed_relay_parents_contiguous: Vec, +} + +impl AllowedRelayParents { + fn allowed_relay_parents_for( + &self, + para_id: Option, + base_number: BlockNumber, + ) -> &[Hash] { + let para_id = match para_id { + None => return &self.allowed_relay_parents_contiguous[..], + Some(p) => p, + }; + + let para_min = match self.minimum_relay_parents.get(¶_id) { + Some(p) => *p, + None => return &[], + }; + + if base_number < para_min { + return &[] + } + + let diff = base_number - para_min; + + // difference of 0 should lead to slice len of 1 + let slice_len = ((diff + 1) as usize).min(self.allowed_relay_parents_contiguous.len()); + &self.allowed_relay_parents_contiguous[..slice_len] + } +} + +#[derive(Debug, Clone)] +struct ActiveLeafPruningInfo { + // The minimum block in the same branch of the relay-chain that should be + // preserved. + retain_minimum: BlockNumber, +} + +#[derive(Debug, Clone)] +struct BlockInfo { + block_number: BlockNumber, + // If this was previously an active leaf, this will be `Some` + // and is useful for understanding the views of peers in the network + // which may not be in perfect synchrony with our own view. + // + // If they are ahead of us in getting a new leaf, there's nothing we + // can do as it's an unrecognized block hash. But if they're behind us, + // it's useful for us to retain some information about previous leaves' + // implicit views so we can continue to send relevant messages to them + // until they catch up. + maybe_allowed_relay_parents: Option, + parent_hash: Hash, +} + +impl View { + /// Get an iterator over active leaves in the view. + pub fn leaves(&self) -> impl Iterator { + self.leaves.keys() + } + + /// Activate a leaf in the view. + /// This will request the minimum relay parents from the + /// Prospective Parachains subsystem for each leaf and will load headers in the ancestry of each + /// leaf in the view as needed. These are the 'implicit ancestors' of the leaf. + /// + /// To maximize reuse of outdated leaves, it's best to activate new leaves before + /// deactivating old ones. + /// + /// This returns a list of para-ids which are relevant to the leaf, + /// and the allowed relay parents for these paras under this leaf can be + /// queried with [`View::known_allowed_relay_parents_under`]. + /// + /// No-op for known leaves. + pub async fn activate_leaf( + &mut self, + sender: &mut Sender, + leaf_hash: Hash, + ) -> Result, FetchError> + where + Sender: SubsystemSender, + Sender: SubsystemSender, + { + if self.leaves.contains_key(&leaf_hash) { + return Err(FetchError::AlreadyKnown) + } + + let res = fetch_fresh_leaf_and_insert_ancestry( + leaf_hash, + &mut self.block_info_storage, + &mut *sender, + ) + .await; + + match res { + Ok(fetched) => { + // Retain at least `MINIMUM_RETAIN_LENGTH` blocks in storage. + // This helps to avoid Chain API calls when activating leaves in the + // same chain. + let retain_minimum = std::cmp::min( + fetched.minimum_ancestor_number, + fetched.leaf_number.saturating_sub(MINIMUM_RETAIN_LENGTH), + ); + + self.leaves.insert(leaf_hash, ActiveLeafPruningInfo { retain_minimum }); + + Ok(fetched.relevant_paras) + }, + Err(e) => Err(e), + } + } + + /// Deactivate a leaf in the view. This prunes any outdated implicit ancestors as well. + /// + /// Returns hashes of blocks pruned from storage. + pub fn deactivate_leaf(&mut self, leaf_hash: Hash) -> Vec { + let mut removed = Vec::new(); + + if self.leaves.remove(&leaf_hash).is_none() { + return removed + } + + // Prune everything before the minimum out of all leaves, + // pruning absolutely everything if there are no leaves (empty view) + // + // Pruning by block number does leave behind orphaned forks slightly longer + // but the memory overhead is negligible. + { + let minimum = self.leaves.values().map(|l| l.retain_minimum).min(); + + self.block_info_storage.retain(|hash, i| { + let keep = minimum.map_or(false, |m| i.block_number >= m); + if !keep { + removed.push(*hash); + } + keep + }); + + removed + } + } + + /// Get an iterator over all allowed relay-parents in the view with no particular order. + /// + /// **Important**: not all blocks are guaranteed to be allowed for some leaves, it may + /// happen that a block info is only kept in the view storage because of a retaining rule. + /// + /// For getting relay-parents that are valid for parachain candidates use + /// [`View::known_allowed_relay_parents_under`]. + pub fn all_allowed_relay_parents(&self) -> impl Iterator { + self.block_info_storage.keys() + } + + /// Get the known, allowed relay-parents that are valid for parachain candidates + /// which could be backed in a child of a given block for a given para ID. + /// + /// This is expressed as a contiguous slice of relay-chain block hashes which may + /// include the provided block hash itself. + /// + /// If `para_id` is `None`, this returns all valid relay-parents across all paras + /// for the leaf. + /// + /// `None` indicates that the block hash isn't part of the implicit view or that + /// there are no known allowed relay parents. + /// + /// This always returns `Some` for active leaves or for blocks that previously + /// were active leaves. + /// + /// This can return the empty slice, which indicates that no relay-parents are allowed + /// for the para, e.g. if the para is not scheduled at the given block hash. + pub fn known_allowed_relay_parents_under( + &self, + block_hash: &Hash, + para_id: Option, + ) -> Option<&[Hash]> { + let block_info = self.block_info_storage.get(block_hash)?; + block_info + .maybe_allowed_relay_parents + .as_ref() + .map(|mins| mins.allowed_relay_parents_for(para_id, block_info.block_number)) + } +} + +/// Errors when fetching a leaf and associated ancestry. +#[fatality::fatality] +pub enum FetchError { + /// Activated leaf is already present in view. + #[error("Leaf was already known")] + AlreadyKnown, + + /// Request to the prospective parachains subsystem failed. + #[error("The prospective parachains subsystem was unavailable")] + ProspectiveParachainsUnavailable, + + /// Failed to fetch the block header. + #[error("A block header was unavailable")] + BlockHeaderUnavailable(Hash, BlockHeaderUnavailableReason), + + /// A block header was unavailable due to a chain API error. + #[error("A block header was unavailable due to a chain API error")] + ChainApiError(Hash, ChainApiError), + + /// Request to the Chain API subsystem failed. + #[error("The chain API subsystem was unavailable")] + ChainApiUnavailable, +} + +/// Reasons a block header might have been unavailable. +#[derive(Debug)] +pub enum BlockHeaderUnavailableReason { + /// Block header simply unknown. + Unknown, + /// Internal Chain API error. + Internal(ChainApiError), + /// The subsystem was unavailable. + SubsystemUnavailable, +} + +struct FetchSummary { + minimum_ancestor_number: BlockNumber, + leaf_number: BlockNumber, + relevant_paras: Vec, +} + +async fn fetch_fresh_leaf_and_insert_ancestry( + leaf_hash: Hash, + block_info_storage: &mut HashMap, + sender: &mut Sender, +) -> Result +where + Sender: SubsystemSender, + Sender: SubsystemSender, +{ + let min_relay_parents_raw = { + let (tx, rx) = oneshot::channel(); + sender + .send_message(ProspectiveParachainsMessage::GetMinimumRelayParents(leaf_hash, tx)) + .await; + + match rx.await { + Ok(m) => m, + Err(_) => return Err(FetchError::ProspectiveParachainsUnavailable), + } + }; + + let leaf_header = { + let (tx, rx) = oneshot::channel(); + sender.send_message(ChainApiMessage::BlockHeader(leaf_hash, tx)).await; + + match rx.await { + Ok(Ok(Some(header))) => header, + Ok(Ok(None)) => + return Err(FetchError::BlockHeaderUnavailable( + leaf_hash, + BlockHeaderUnavailableReason::Unknown, + )), + Ok(Err(e)) => + return Err(FetchError::BlockHeaderUnavailable( + leaf_hash, + BlockHeaderUnavailableReason::Internal(e), + )), + Err(_) => + return Err(FetchError::BlockHeaderUnavailable( + leaf_hash, + BlockHeaderUnavailableReason::SubsystemUnavailable, + )), + } + }; + + let min_min = min_relay_parents_raw.iter().map(|x| x.1).min().unwrap_or(leaf_header.number); + let relevant_paras = min_relay_parents_raw.iter().map(|x| x.0).collect(); + let expected_ancestry_len = (leaf_header.number.saturating_sub(min_min) as usize) + 1; + + let ancestry = if leaf_header.number > 0 { + let mut next_ancestor_number = leaf_header.number - 1; + let mut next_ancestor_hash = leaf_header.parent_hash; + + let mut ancestry = Vec::with_capacity(expected_ancestry_len); + ancestry.push(leaf_hash); + + // Ensure all ancestors up to and including `min_min` are in the + // block storage. When views advance incrementally, everything + // should already be present. + while next_ancestor_number >= min_min { + let parent_hash = if let Some(info) = block_info_storage.get(&next_ancestor_hash) { + info.parent_hash + } else { + // load the header and insert into block storage. + let (tx, rx) = oneshot::channel(); + sender.send_message(ChainApiMessage::BlockHeader(next_ancestor_hash, tx)).await; + + let header = match rx.await { + Ok(Ok(Some(header))) => header, + Ok(Ok(None)) => + return Err(FetchError::BlockHeaderUnavailable( + next_ancestor_hash, + BlockHeaderUnavailableReason::Unknown, + )), + Ok(Err(e)) => + return Err(FetchError::BlockHeaderUnavailable( + next_ancestor_hash, + BlockHeaderUnavailableReason::Internal(e), + )), + Err(_) => + return Err(FetchError::BlockHeaderUnavailable( + next_ancestor_hash, + BlockHeaderUnavailableReason::SubsystemUnavailable, + )), + }; + + block_info_storage.insert( + next_ancestor_hash, + BlockInfo { + block_number: next_ancestor_number, + parent_hash: header.parent_hash, + maybe_allowed_relay_parents: None, + }, + ); + + header.parent_hash + }; + + ancestry.push(next_ancestor_hash); + if next_ancestor_number == 0 { + break + } + + next_ancestor_number -= 1; + next_ancestor_hash = parent_hash; + } + + ancestry + } else { + vec![leaf_hash] + }; + + let fetched_ancestry = FetchSummary { + minimum_ancestor_number: min_min, + leaf_number: leaf_header.number, + relevant_paras, + }; + + let allowed_relay_parents = AllowedRelayParents { + minimum_relay_parents: min_relay_parents_raw.iter().cloned().collect(), + allowed_relay_parents_contiguous: ancestry, + }; + + let leaf_block_info = BlockInfo { + parent_hash: leaf_header.parent_hash, + block_number: leaf_header.number, + maybe_allowed_relay_parents: Some(allowed_relay_parents), + }; + + block_info_storage.insert(leaf_hash, leaf_block_info); + + Ok(fetched_ancestry) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::TimeoutExt; + use assert_matches::assert_matches; + use futures::future::{join, FutureExt}; + use polkadot_node_subsystem::AllMessages; + use polkadot_node_subsystem_test_helpers::{ + make_subsystem_context, TestSubsystemContextHandle, + }; + use polkadot_overseer::SubsystemContext; + use polkadot_primitives::Header; + use sp_core::testing::TaskExecutor; + use std::time::Duration; + + const PARA_A: ParaId = ParaId::new(0); + const PARA_B: ParaId = ParaId::new(1); + const PARA_C: ParaId = ParaId::new(2); + + const GENESIS_HASH: Hash = Hash::repeat_byte(0xFF); + const GENESIS_NUMBER: BlockNumber = 0; + + // Chains A and B are forks of genesis. + + const CHAIN_A: &[Hash] = + &[Hash::repeat_byte(0x01), Hash::repeat_byte(0x02), Hash::repeat_byte(0x03)]; + + const CHAIN_B: &[Hash] = &[ + Hash::repeat_byte(0x04), + Hash::repeat_byte(0x05), + Hash::repeat_byte(0x06), + Hash::repeat_byte(0x07), + Hash::repeat_byte(0x08), + Hash::repeat_byte(0x09), + ]; + + type VirtualOverseer = TestSubsystemContextHandle; + + const TIMEOUT: Duration = Duration::from_secs(2); + + async fn overseer_recv(virtual_overseer: &mut VirtualOverseer) -> AllMessages { + virtual_overseer + .recv() + .timeout(TIMEOUT) + .await + .expect("overseer `recv` timed out") + } + + fn default_header() -> Header { + Header { + parent_hash: Hash::zero(), + number: 0, + state_root: Hash::zero(), + extrinsics_root: Hash::zero(), + digest: Default::default(), + } + } + + fn get_block_header(chain: &[Hash], hash: &Hash) -> Option

{ + let idx = chain.iter().position(|h| h == hash)?; + let parent_hash = idx.checked_sub(1).map(|i| chain[i]).unwrap_or(GENESIS_HASH); + let number = + if *hash == GENESIS_HASH { GENESIS_NUMBER } else { GENESIS_NUMBER + idx as u32 + 1 }; + Some(Header { parent_hash, number, ..default_header() }) + } + + async fn assert_block_header_requests( + virtual_overseer: &mut VirtualOverseer, + chain: &[Hash], + blocks: &[Hash], + ) { + for block in blocks.iter().rev() { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ChainApi( + ChainApiMessage::BlockHeader(hash, tx) + ) => { + assert_eq!(*block, hash, "unexpected block header request"); + let header = if block == &GENESIS_HASH { + Header { + number: GENESIS_NUMBER, + ..default_header() + } + } else { + get_block_header(chain, block).expect("unknown block") + }; + + tx.send(Ok(Some(header))).unwrap(); + } + ); + } + } + + async fn assert_min_relay_parents_request( + virtual_overseer: &mut VirtualOverseer, + leaf: &Hash, + response: Vec<(ParaId, u32)>, + ) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetMinimumRelayParents( + leaf_hash, + tx + ) + ) => { + assert_eq!(*leaf, leaf_hash, "received unexpected leaf hash"); + tx.send(response).unwrap(); + } + ); + } + + #[test] + fn construct_fresh_view() { + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = make_subsystem_context::(pool); + + let mut view = View::default(); + + // Chain B. + const PARA_A_MIN_PARENT: u32 = 4; + const PARA_B_MIN_PARENT: u32 = 3; + + let prospective_response = vec![(PARA_A, PARA_A_MIN_PARENT), (PARA_B, PARA_B_MIN_PARENT)]; + + let leaf = CHAIN_B.last().unwrap(); + let min_min_idx = (PARA_B_MIN_PARENT - GENESIS_NUMBER - 1) as usize; + + let fut = view.activate_leaf(ctx.sender(), *leaf).timeout(TIMEOUT).map(|res| { + let paras = res.expect("`activate_leaf` timed out").unwrap(); + assert_eq!(paras, vec![PARA_A, PARA_B]); + }); + let overseer_fut = async { + assert_min_relay_parents_request(&mut ctx_handle, leaf, prospective_response).await; + assert_block_header_requests(&mut ctx_handle, CHAIN_B, &CHAIN_B[min_min_idx..]).await; + }; + futures::executor::block_on(join(fut, overseer_fut)); + + for i in min_min_idx..(CHAIN_B.len() - 1) { + // No allowed relay parents constructed for ancestry. + assert!(view.known_allowed_relay_parents_under(&CHAIN_B[i], None).is_none()); + } + + let leaf_info = + view.block_info_storage.get(leaf).expect("block must be present in storage"); + assert_matches!( + leaf_info.maybe_allowed_relay_parents, + Some(ref allowed_relay_parents) => { + assert_eq!(allowed_relay_parents.minimum_relay_parents[&PARA_A], PARA_A_MIN_PARENT); + assert_eq!(allowed_relay_parents.minimum_relay_parents[&PARA_B], PARA_B_MIN_PARENT); + let expected_ancestry: Vec = + CHAIN_B[min_min_idx..].iter().rev().copied().collect(); + assert_eq!( + allowed_relay_parents.allowed_relay_parents_contiguous, + expected_ancestry + ); + } + ); + + // Suppose the whole test chain A is allowed up to genesis for para C. + const PARA_C_MIN_PARENT: u32 = 0; + let prospective_response = vec![(PARA_C, PARA_C_MIN_PARENT)]; + let leaf = CHAIN_A.last().unwrap(); + let blocks = [&[GENESIS_HASH], CHAIN_A].concat(); + + let fut = view.activate_leaf(ctx.sender(), *leaf).timeout(TIMEOUT).map(|res| { + let paras = res.expect("`activate_leaf` timed out").unwrap(); + assert_eq!(paras, vec![PARA_C]); + }); + let overseer_fut = async { + assert_min_relay_parents_request(&mut ctx_handle, leaf, prospective_response).await; + assert_block_header_requests(&mut ctx_handle, CHAIN_A, &blocks).await; + }; + futures::executor::block_on(join(fut, overseer_fut)); + + assert_eq!(view.leaves.len(), 2); + } + + #[test] + fn reuse_block_info_storage() { + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = make_subsystem_context::(pool); + + let mut view = View::default(); + + const PARA_A_MIN_PARENT: u32 = 1; + let leaf_a_number = 3; + let leaf_a = CHAIN_B[leaf_a_number - 1]; + let min_min_idx = (PARA_A_MIN_PARENT - GENESIS_NUMBER - 1) as usize; + + let prospective_response = vec![(PARA_A, PARA_A_MIN_PARENT)]; + + let fut = view.activate_leaf(ctx.sender(), leaf_a).timeout(TIMEOUT).map(|res| { + let paras = res.expect("`activate_leaf` timed out").unwrap(); + assert_eq!(paras, vec![PARA_A]); + }); + let overseer_fut = async { + assert_min_relay_parents_request(&mut ctx_handle, &leaf_a, prospective_response).await; + assert_block_header_requests( + &mut ctx_handle, + CHAIN_B, + &CHAIN_B[min_min_idx..leaf_a_number], + ) + .await; + }; + futures::executor::block_on(join(fut, overseer_fut)); + + // Blocks up to the 3rd are present in storage. + const PARA_B_MIN_PARENT: u32 = 2; + let leaf_b_number = 5; + let leaf_b = CHAIN_B[leaf_b_number - 1]; + + let prospective_response = vec![(PARA_B, PARA_B_MIN_PARENT)]; + + let fut = view.activate_leaf(ctx.sender(), leaf_b).timeout(TIMEOUT).map(|res| { + let paras = res.expect("`activate_leaf` timed out").unwrap(); + assert_eq!(paras, vec![PARA_B]); + }); + let overseer_fut = async { + assert_min_relay_parents_request(&mut ctx_handle, &leaf_b, prospective_response).await; + assert_block_header_requests( + &mut ctx_handle, + CHAIN_B, + &CHAIN_B[leaf_a_number..leaf_b_number], // Note the expected range. + ) + .await; + }; + futures::executor::block_on(join(fut, overseer_fut)); + + // Allowed relay parents for leaf A are preserved. + let leaf_a_info = + view.block_info_storage.get(&leaf_a).expect("block must be present in storage"); + assert_matches!( + leaf_a_info.maybe_allowed_relay_parents, + Some(ref allowed_relay_parents) => { + assert_eq!(allowed_relay_parents.minimum_relay_parents[&PARA_A], PARA_A_MIN_PARENT); + let expected_ancestry: Vec = + CHAIN_B[min_min_idx..leaf_a_number].iter().rev().copied().collect(); + let ancestry = view.known_allowed_relay_parents_under(&leaf_a, Some(PARA_A)).unwrap().to_vec(); + assert_eq!(ancestry, expected_ancestry); + } + ); + } + + #[test] + fn pruning() { + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = make_subsystem_context::(pool); + + let mut view = View::default(); + + const PARA_A_MIN_PARENT: u32 = 3; + let leaf_a = CHAIN_B.iter().rev().nth(1).unwrap(); + let leaf_a_idx = CHAIN_B.len() - 2; + let min_a_idx = (PARA_A_MIN_PARENT - GENESIS_NUMBER - 1) as usize; + + let prospective_response = vec![(PARA_A, PARA_A_MIN_PARENT)]; + + let fut = view + .activate_leaf(ctx.sender(), *leaf_a) + .timeout(TIMEOUT) + .map(|res| res.unwrap().unwrap()); + let overseer_fut = async { + assert_min_relay_parents_request(&mut ctx_handle, &leaf_a, prospective_response).await; + assert_block_header_requests( + &mut ctx_handle, + CHAIN_B, + &CHAIN_B[min_a_idx..=leaf_a_idx], + ) + .await; + }; + futures::executor::block_on(join(fut, overseer_fut)); + + // Also activate a leaf with a lesser minimum relay parent. + const PARA_B_MIN_PARENT: u32 = 2; + let leaf_b = CHAIN_B.last().unwrap(); + let min_b_idx = (PARA_B_MIN_PARENT - GENESIS_NUMBER - 1) as usize; + + let prospective_response = vec![(PARA_B, PARA_B_MIN_PARENT)]; + // Headers will be requested for the minimum block and the leaf. + let blocks = &[CHAIN_B[min_b_idx], *leaf_b]; + + let fut = view + .activate_leaf(ctx.sender(), *leaf_b) + .timeout(TIMEOUT) + .map(|res| res.expect("`activate_leaf` timed out").unwrap()); + let overseer_fut = async { + assert_min_relay_parents_request(&mut ctx_handle, &leaf_b, prospective_response).await; + assert_block_header_requests(&mut ctx_handle, CHAIN_B, blocks).await; + }; + futures::executor::block_on(join(fut, overseer_fut)); + + // Prune implicit ancestor (no-op). + let block_info_len = view.block_info_storage.len(); + view.deactivate_leaf(CHAIN_B[leaf_a_idx - 1]); + assert_eq!(block_info_len, view.block_info_storage.len()); + + // Prune a leaf with a greater minimum relay parent. + view.deactivate_leaf(*leaf_b); + for hash in CHAIN_B.iter().take(PARA_B_MIN_PARENT as usize) { + assert!(!view.block_info_storage.contains_key(hash)); + } + + // Prune the last leaf. + view.deactivate_leaf(*leaf_a); + assert!(view.block_info_storage.is_empty()); + } + + #[test] + fn genesis_ancestry() { + let pool = TaskExecutor::new(); + let (mut ctx, mut ctx_handle) = make_subsystem_context::(pool); + + let mut view = View::default(); + + const PARA_A_MIN_PARENT: u32 = 0; + + let prospective_response = vec![(PARA_A, PARA_A_MIN_PARENT)]; + let fut = view.activate_leaf(ctx.sender(), GENESIS_HASH).timeout(TIMEOUT).map(|res| { + let paras = res.expect("`activate_leaf` timed out").unwrap(); + assert_eq!(paras, vec![PARA_A]); + }); + let overseer_fut = async { + assert_min_relay_parents_request(&mut ctx_handle, &GENESIS_HASH, prospective_response) + .await; + assert_block_header_requests(&mut ctx_handle, &[GENESIS_HASH], &[GENESIS_HASH]).await; + }; + futures::executor::block_on(join(fut, overseer_fut)); + + assert_matches!( + view.known_allowed_relay_parents_under(&GENESIS_HASH, None), + Some(hashes) if !hashes.is_empty() + ); + } +} diff --git a/polkadot/node/subsystem-util/src/database.rs b/polkadot/node/subsystem-util/src/database.rs new file mode 100644 index 0000000000000000000000000000000000000000..be5110c4aaba779477290e47b3d73fefbd796abf --- /dev/null +++ b/polkadot/node/subsystem-util/src/database.rs @@ -0,0 +1,310 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Database trait for polkadot db. + +pub use kvdb::{DBKeyValue, DBTransaction, DBValue, KeyValueDB}; + +/// Database trait with ordered key capacity. +pub trait Database: KeyValueDB { + /// Check if column allows content iteration + /// and removal by prefix. + fn is_indexed_column(&self, col: u32) -> bool; +} + +/// Implementation for database supporting `KeyValueDB` already. +pub mod kvdb_impl { + use super::{DBKeyValue, DBTransaction, DBValue, Database, KeyValueDB}; + use kvdb::{DBOp, IoStats, IoStatsKind}; + use std::{collections::BTreeSet, io::Result}; + + /// Adapter implementing subsystem database + /// for `KeyValueDB`. + #[derive(Clone)] + pub struct DbAdapter { + db: D, + indexed_columns: BTreeSet, + } + + impl DbAdapter { + /// Instantiate new subsystem database, with + /// the columns that allow ordered iteration. + pub fn new(db: D, indexed_columns: &[u32]) -> Self { + DbAdapter { db, indexed_columns: indexed_columns.iter().cloned().collect() } + } + + fn ensure_is_indexed(&self, col: u32) { + debug_assert!( + self.is_indexed_column(col), + "Invalid configuration of database, column {} is not ordered.", + col + ); + } + + fn ensure_ops_indexing(&self, transaction: &DBTransaction) { + debug_assert!({ + let mut pass = true; + for op in &transaction.ops { + if let DBOp::DeletePrefix { col, .. } = op { + if !self.is_indexed_column(*col) { + pass = false; + break + } + } + } + pass + }) + } + } + + impl Database for DbAdapter { + fn is_indexed_column(&self, col: u32) -> bool { + self.indexed_columns.contains(&col) + } + } + + impl KeyValueDB for DbAdapter { + fn transaction(&self) -> DBTransaction { + self.db.transaction() + } + + fn get(&self, col: u32, key: &[u8]) -> Result> { + self.db.get(col, key) + } + + fn get_by_prefix(&self, col: u32, prefix: &[u8]) -> Result> { + self.ensure_is_indexed(col); + self.db.get_by_prefix(col, prefix) + } + + fn write(&self, transaction: DBTransaction) -> Result<()> { + self.ensure_ops_indexing(&transaction); + self.db.write(transaction) + } + + fn iter<'a>(&'a self, col: u32) -> Box> + 'a> { + self.ensure_is_indexed(col); + self.db.iter(col) + } + + fn iter_with_prefix<'a>( + &'a self, + col: u32, + prefix: &'a [u8], + ) -> Box> + 'a> { + self.ensure_is_indexed(col); + self.db.iter_with_prefix(col, prefix) + } + + fn io_stats(&self, kind: IoStatsKind) -> IoStats { + self.db.io_stats(kind) + } + + fn has_key(&self, col: u32, key: &[u8]) -> Result { + self.db.has_key(col, key) + } + + fn has_prefix(&self, col: u32, prefix: &[u8]) -> Result { + self.ensure_is_indexed(col); + self.db.has_prefix(col, prefix) + } + } +} + +/// Utilities for using parity-db database. +pub mod paritydb_impl { + use super::{DBKeyValue, DBTransaction, DBValue, Database, KeyValueDB}; + use kvdb::DBOp; + use parity_db::Db; + use parking_lot::Mutex; + use std::{collections::BTreeSet, io::Result, sync::Arc}; + + fn handle_err(result: parity_db::Result) -> T { + match result { + Ok(r) => r, + Err(e) => { + panic!("Critical database error: {:?}", e); + }, + } + } + + fn map_err(result: parity_db::Result) -> Result { + result.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{:?}", e))) + } + + /// Implementation of of `Database` for parity-db adapter. + pub struct DbAdapter { + db: Db, + indexed_columns: BTreeSet, + write_lock: Arc>, + } + + impl KeyValueDB for DbAdapter { + fn transaction(&self) -> DBTransaction { + DBTransaction::new() + } + + fn get(&self, col: u32, key: &[u8]) -> Result> { + map_err(self.db.get(col as u8, key)) + } + + fn get_by_prefix(&self, col: u32, prefix: &[u8]) -> Result> { + self.iter_with_prefix(col, prefix) + .next() + .transpose() + .map(|mb| mb.map(|(_, v)| v)) + } + + fn iter<'a>(&'a self, col: u32) -> Box> + 'a> { + let mut iter = match self.db.iter(col as u8) { + Ok(iter) => iter, + Err(e) => return Box::new(std::iter::once(map_err(Err(e)))), + }; + Box::new(std::iter::from_fn(move || { + iter.next().transpose().map(|r| map_err(r.map(|(k, v)| (k.into(), v)))) + })) + } + + fn iter_with_prefix<'a>( + &'a self, + col: u32, + prefix: &'a [u8], + ) -> Box> + 'a> { + if prefix.len() == 0 { + return self.iter(col) + } + let mut iter = match self.db.iter(col as u8) { + Ok(iter) => iter, + Err(e) => return Box::new(std::iter::once(map_err(Err(e)))), + }; + if let Err(e) = iter.seek(prefix) { + return Box::new(std::iter::once(map_err(Err(e)))) + } + Box::new(std::iter::from_fn(move || { + iter.next().transpose().and_then(|r| { + map_err(r.map(|(k, v)| k.starts_with(prefix).then(|| (k.into(), v)))) + .transpose() + }) + })) + } + + fn write(&self, transaction: DBTransaction) -> Result<()> { + let mut ops = transaction.ops.into_iter(); + // TODO using a key iterator or native delete here would be faster. + let mut current_prefix_iter: Option<(parity_db::BTreeIterator, u8, Vec)> = None; + let current_prefix_iter = &mut current_prefix_iter; + let transaction = std::iter::from_fn(move || loop { + if let Some((prefix_iter, col, prefix)) = current_prefix_iter { + if let Some((key, _value)) = handle_err(prefix_iter.next()) { + if key.starts_with(prefix) { + return Some((*col, key.to_vec(), None)) + } + } + *current_prefix_iter = None; + } + return match ops.next() { + None => None, + Some(DBOp::Insert { col, key, value }) => + Some((col as u8, key.to_vec(), Some(value))), + Some(DBOp::Delete { col, key }) => Some((col as u8, key.to_vec(), None)), + Some(DBOp::DeletePrefix { col, prefix }) => { + let col = col as u8; + let mut iter = handle_err(self.db.iter(col)); + handle_err(iter.seek(&prefix[..])); + *current_prefix_iter = Some((iter, col, prefix.to_vec())); + continue + }, + } + }); + + // Locking is required due to possible racy change of the content of a deleted prefix. + let _lock = self.write_lock.lock(); + map_err(self.db.commit(transaction)) + } + } + + impl Database for DbAdapter { + fn is_indexed_column(&self, col: u32) -> bool { + self.indexed_columns.contains(&col) + } + } + + impl DbAdapter { + /// Implementation of of `Database` for parity-db adapter. + pub fn new(db: Db, indexed_columns: &[u32]) -> Self { + let write_lock = Arc::new(Mutex::new(())); + DbAdapter { db, indexed_columns: indexed_columns.iter().cloned().collect(), write_lock } + } + } + + #[cfg(test)] + mod tests { + use super::*; + use kvdb_shared_tests as st; + use std::io; + use tempfile::Builder as TempfileBuilder; + + fn create(num_col: u32) -> io::Result<(DbAdapter, tempfile::TempDir)> { + let tempdir = TempfileBuilder::new().prefix("").tempdir()?; + let mut options = parity_db::Options::with_columns(tempdir.path(), num_col as u8); + for i in 0..num_col { + options.columns[i as usize].btree_index = true; + } + + let db = parity_db::Db::open_or_create(&options) + .map_err(|err| io::Error::new(io::ErrorKind::Other, format!("{:?}", err)))?; + + let db = DbAdapter::new(db, &[0]); + Ok((db, tempdir)) + } + + #[test] + fn put_and_get() -> io::Result<()> { + let (db, _temp_file) = create(1)?; + st::test_put_and_get(&db) + } + + #[test] + fn delete_and_get() -> io::Result<()> { + let (db, _temp_file) = create(1)?; + st::test_delete_and_get(&db) + } + + #[test] + fn delete_prefix() -> io::Result<()> { + let (db, _temp_file) = create(st::DELETE_PREFIX_NUM_COLUMNS)?; + st::test_delete_prefix(&db) + } + + #[test] + fn iter() -> io::Result<()> { + let (db, _temp_file) = create(1)?; + st::test_iter(&db) + } + + #[test] + fn iter_with_prefix() -> io::Result<()> { + let (db, _temp_file) = create(1)?; + st::test_iter_with_prefix(&db) + } + + #[test] + fn complex() -> io::Result<()> { + let (db, _temp_file) = create(1)?; + st::test_complex(&db) + } + } +} diff --git a/polkadot/node/subsystem-util/src/determine_new_blocks.rs b/polkadot/node/subsystem-util/src/determine_new_blocks.rs new file mode 100644 index 0000000000000000000000000000000000000000..9ffb5d9757f89f55f8a6c976eaca8b6faf59e719 --- /dev/null +++ b/polkadot/node/subsystem-util/src/determine_new_blocks.rs @@ -0,0 +1,601 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A utility for fetching all unknown blocks based on a new chain-head hash. + +use futures::{channel::oneshot, prelude::*}; +use polkadot_node_subsystem::{messages::ChainApiMessage, SubsystemSender}; +use polkadot_primitives::{BlockNumber, Hash, Header}; + +/// Given a new chain-head hash, this determines the hashes of all new blocks we should track +/// metadata for, given this head. +/// +/// This is guaranteed to be a subset of the (inclusive) ancestry of `head` determined as all +/// blocks above the lower bound or above the highest known block, whichever is higher. +/// This is formatted in descending order by block height. +/// +/// An implication of this is that if `head` itself is known or not above the lower bound, +/// then the returned list will be empty. +/// +/// This may be somewhat expensive when first recovering from major sync. +pub async fn determine_new_blocks( + sender: &mut Sender, + is_known: impl Fn(&Hash) -> Result, + head: Hash, + header: &Header, + lower_bound_number: BlockNumber, +) -> Result, E> +where + Sender: SubsystemSender, +{ + const ANCESTRY_STEP: usize = 4; + + let min_block_needed = lower_bound_number + 1; + + // Early exit if the block is in the DB or too early. + { + let already_known = is_known(&head)?; + + let before_relevant = header.number < min_block_needed; + + if already_known || before_relevant { + return Ok(Vec::new()) + } + } + + let mut ancestry = vec![(head, header.clone())]; + + // Early exit if the parent hash is in the DB or no further blocks + // are needed. + if is_known(&header.parent_hash)? || header.number == min_block_needed { + return Ok(ancestry) + } + + 'outer: loop { + let (last_hash, last_header) = ancestry + .last() + .expect("ancestry has length 1 at initialization and is only added to; qed"); + + assert!( + last_header.number > min_block_needed, + "Loop invariant: the last block in ancestry is checked to be \ + above the minimum before the loop, and at the end of each iteration; \ + qed" + ); + + let (tx, rx) = oneshot::channel(); + + // This is always non-zero as determined by the loop invariant + // above. + let ancestry_step = + std::cmp::min(ANCESTRY_STEP, (last_header.number - min_block_needed) as usize); + + let batch_hashes = if ancestry_step == 1 { + vec![last_header.parent_hash] + } else { + sender + .send_message( + ChainApiMessage::Ancestors { + hash: *last_hash, + k: ancestry_step, + response_channel: tx, + } + .into(), + ) + .await; + + // Continue past these errors. + match rx.await { + Err(_) | Ok(Err(_)) => break 'outer, + Ok(Ok(ancestors)) => ancestors, + } + }; + + let batch_headers = { + let (batch_senders, batch_receivers) = (0..batch_hashes.len()) + .map(|_| oneshot::channel()) + .unzip::<_, _, Vec<_>, Vec<_>>(); + + for (hash, batched_sender) in batch_hashes.iter().cloned().zip(batch_senders) { + sender + .send_message(ChainApiMessage::BlockHeader(hash, batched_sender).into()) + .await; + } + + let mut requests = futures::stream::FuturesOrdered::new(); + batch_receivers + .into_iter() + .map(|rx| async move { + match rx.await { + Err(_) | Ok(Err(_)) => None, + Ok(Ok(h)) => h, + } + }) + .for_each(|x| requests.push_back(x)); + + let batch_headers: Vec<_> = + requests.flat_map(|x: Option
| stream::iter(x)).collect().await; + + // Any failed header fetch of the batch will yield a `None` result that will + // be skipped. Any failure at this stage means we'll just ignore those blocks + // as the chain DB has failed us. + if batch_headers.len() != batch_hashes.len() { + break 'outer + } + batch_headers + }; + + for (hash, header) in batch_hashes.into_iter().zip(batch_headers) { + let is_known = is_known(&hash)?; + + let is_relevant = header.number >= min_block_needed; + let is_terminating = header.number == min_block_needed; + + if is_known || !is_relevant { + break 'outer + } + + ancestry.push((hash, header)); + + if is_terminating { + break 'outer + } + } + } + + Ok(ancestry) +} + +#[cfg(test)] +mod tests { + use super::*; + use assert_matches::assert_matches; + use polkadot_node_subsystem_test_helpers::make_subsystem_context; + use polkadot_overseer::{AllMessages, SubsystemContext}; + use sp_core::testing::TaskExecutor; + use std::collections::{HashMap, HashSet}; + + #[derive(Default)] + struct TestKnownBlocks { + blocks: HashSet, + } + + impl TestKnownBlocks { + fn insert(&mut self, hash: Hash) { + self.blocks.insert(hash); + } + + fn is_known(&self, hash: &Hash) -> Result { + Ok(self.blocks.contains(hash)) + } + } + + #[derive(Clone)] + struct TestChain { + start_number: BlockNumber, + headers: Vec
, + numbers: HashMap, + } + + impl TestChain { + fn new(start: BlockNumber, len: usize) -> Self { + assert!(len > 0, "len must be at least 1"); + + let base = Header { + digest: Default::default(), + extrinsics_root: Default::default(), + number: start, + state_root: Default::default(), + parent_hash: Default::default(), + }; + + let base_hash = base.hash(); + + let mut chain = TestChain { + start_number: start, + headers: vec![base], + numbers: vec![(base_hash, start)].into_iter().collect(), + }; + + for _ in 1..len { + chain.grow() + } + + chain + } + + fn grow(&mut self) { + let next = { + let last = self.headers.last().unwrap(); + Header { + digest: Default::default(), + extrinsics_root: Default::default(), + number: last.number + 1, + state_root: Default::default(), + parent_hash: last.hash(), + } + }; + + self.numbers.insert(next.hash(), next.number); + self.headers.push(next); + } + + fn header_by_number(&self, number: BlockNumber) -> Option<&Header> { + if number < self.start_number { + None + } else { + self.headers.get((number - self.start_number) as usize) + } + } + + fn header_by_hash(&self, hash: &Hash) -> Option<&Header> { + self.numbers.get(hash).and_then(|n| self.header_by_number(*n)) + } + + fn hash_by_number(&self, number: BlockNumber) -> Option { + self.header_by_number(number).map(|h| h.hash()) + } + + fn ancestry(&self, hash: &Hash, k: BlockNumber) -> Vec { + let n = match self.numbers.get(hash) { + None => return Vec::new(), + Some(&n) => n, + }; + + (0..k) + .map(|i| i + 1) + .filter_map(|i| self.header_by_number(n - i)) + .map(|h| h.hash()) + .collect() + } + } + + #[test] + fn determine_new_blocks_back_to_lower_bound() { + let pool = TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::<(), _>(pool.clone()); + + let known = TestKnownBlocks::default(); + + let chain = TestChain::new(10, 9); + + let head = chain.header_by_number(18).unwrap().clone(); + let head_hash = head.hash(); + let lower_bound_number = 12; + + // Finalized block should be omitted. The head provided to `determine_new_blocks` + // should be included. + let expected_ancestry = (13..=18) + .map(|n| chain.header_by_number(n).map(|h| (h.hash(), h.clone())).unwrap()) + .rev() + .collect::>(); + + let test_fut = Box::pin(async move { + let ancestry = determine_new_blocks( + ctx.sender(), + |h| known.is_known(h), + head_hash, + &head, + lower_bound_number, + ) + .await + .unwrap(); + + assert_eq!(ancestry, expected_ancestry); + }); + + let aux_fut = Box::pin(async move { + assert_matches!( + handle.recv().await, + AllMessages::ChainApi(ChainApiMessage::Ancestors { + hash: h, + k, + response_channel: tx, + }) => { + assert_eq!(h, head_hash); + assert_eq!(k, 4); + let _ = tx.send(Ok(chain.ancestry(&h, k as _))); + } + ); + + for _ in 0u32..4 { + assert_matches!( + handle.recv().await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(h, tx)) => { + let _ = tx.send(Ok(chain.header_by_hash(&h).map(|h| h.clone()))); + } + ); + } + + assert_matches!( + handle.recv().await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(h, tx)) => { + assert_eq!(h, chain.hash_by_number(13).unwrap()); + let _ = tx.send(Ok(chain.header_by_hash(&h).map(|h| h.clone()))); + } + ); + }); + + futures::executor::block_on(futures::future::join(test_fut, aux_fut)); + } + + #[test] + fn determine_new_blocks_back_to_known() { + let pool = TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::<(), _>(pool.clone()); + + let mut known = TestKnownBlocks::default(); + + let chain = TestChain::new(10, 9); + + let head = chain.header_by_number(18).unwrap().clone(); + let head_hash = head.hash(); + let lower_bound_number = 12; + let known_number = 15; + let known_hash = chain.hash_by_number(known_number).unwrap(); + + known.insert(known_hash); + + // Known block should be omitted. The head provided to `determine_new_blocks` + // should be included. + let expected_ancestry = (16..=18) + .map(|n| chain.header_by_number(n).map(|h| (h.hash(), h.clone())).unwrap()) + .rev() + .collect::>(); + + let test_fut = Box::pin(async move { + let ancestry = determine_new_blocks( + ctx.sender(), + |h| known.is_known(h), + head_hash, + &head, + lower_bound_number, + ) + .await + .unwrap(); + + assert_eq!(ancestry, expected_ancestry); + }); + + let aux_fut = Box::pin(async move { + assert_matches!( + handle.recv().await, + AllMessages::ChainApi(ChainApiMessage::Ancestors { + hash: h, + k, + response_channel: tx, + }) => { + assert_eq!(h, head_hash); + assert_eq!(k, 4); + let _ = tx.send(Ok(chain.ancestry(&h, k as _))); + } + ); + + for _ in 0u32..4 { + assert_matches!( + handle.recv().await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(h, tx)) => { + let _ = tx.send(Ok(chain.header_by_hash(&h).map(|h| h.clone()))); + } + ); + } + }); + + futures::executor::block_on(futures::future::join(test_fut, aux_fut)); + } + + #[test] + fn determine_new_blocks_already_known_is_empty() { + let pool = TaskExecutor::new(); + let (mut ctx, _handle) = make_subsystem_context::<(), _>(pool.clone()); + + let mut known = TestKnownBlocks::default(); + + let chain = TestChain::new(10, 9); + + let head = chain.header_by_number(18).unwrap().clone(); + let head_hash = head.hash(); + let lower_bound_number = 0; + + known.insert(head_hash); + + // Known block should be omitted. + let expected_ancestry = Vec::new(); + + let test_fut = Box::pin(async move { + let ancestry = determine_new_blocks( + ctx.sender(), + |h| known.is_known(h), + head_hash, + &head, + lower_bound_number, + ) + .await + .unwrap(); + + assert_eq!(ancestry, expected_ancestry); + }); + + futures::executor::block_on(test_fut); + } + + #[test] + fn determine_new_blocks_parent_known_is_fast() { + let pool = TaskExecutor::new(); + let (mut ctx, _handle) = make_subsystem_context::<(), _>(pool.clone()); + + let mut known = TestKnownBlocks::default(); + + let chain = TestChain::new(10, 9); + + let head = chain.header_by_number(18).unwrap().clone(); + let head_hash = head.hash(); + let lower_bound_number = 0; + let parent_hash = chain.hash_by_number(17).unwrap(); + + known.insert(parent_hash); + + // New block should be the only new one. + let expected_ancestry = vec![(head_hash, head.clone())]; + + let test_fut = Box::pin(async move { + let ancestry = determine_new_blocks( + ctx.sender(), + |h| known.is_known(h), + head_hash, + &head, + lower_bound_number, + ) + .await + .unwrap(); + + assert_eq!(ancestry, expected_ancestry); + }); + + futures::executor::block_on(test_fut); + } + + #[test] + fn determine_new_block_before_finality_is_empty() { + let pool = TaskExecutor::new(); + let (mut ctx, _handle) = make_subsystem_context::<(), _>(pool.clone()); + + let chain = TestChain::new(10, 9); + + let head = chain.header_by_number(18).unwrap().clone(); + let head_hash = head.hash(); + let parent_hash = chain.hash_by_number(17).unwrap(); + let mut known = TestKnownBlocks::default(); + + known.insert(parent_hash); + + let test_fut = Box::pin(async move { + let after_finality = + determine_new_blocks(ctx.sender(), |h| known.is_known(h), head_hash, &head, 17) + .await + .unwrap(); + + let at_finality = + determine_new_blocks(ctx.sender(), |h| known.is_known(h), head_hash, &head, 18) + .await + .unwrap(); + + let before_finality = + determine_new_blocks(ctx.sender(), |h| known.is_known(h), head_hash, &head, 19) + .await + .unwrap(); + + assert_eq!(after_finality, vec![(head_hash, head.clone())]); + + assert_eq!(at_finality, Vec::new()); + + assert_eq!(before_finality, Vec::new()); + }); + + futures::executor::block_on(test_fut); + } + + #[test] + fn determine_new_blocks_does_not_request_genesis() { + let pool = TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::<(), _>(pool.clone()); + + let chain = TestChain::new(1, 2); + + let head = chain.header_by_number(2).unwrap().clone(); + let head_hash = head.hash(); + let known = TestKnownBlocks::default(); + + let expected_ancestry = (1..=2) + .map(|n| chain.header_by_number(n).map(|h| (h.hash(), h.clone())).unwrap()) + .rev() + .collect::>(); + + let test_fut = Box::pin(async move { + let ancestry = + determine_new_blocks(ctx.sender(), |h| known.is_known(h), head_hash, &head, 0) + .await + .unwrap(); + + assert_eq!(ancestry, expected_ancestry); + }); + + let aux_fut = Box::pin(async move { + assert_matches!( + handle.recv().await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(h, tx)) => { + assert_eq!(h, chain.hash_by_number(1).unwrap()); + let _ = tx.send(Ok(chain.header_by_hash(&h).map(|h| h.clone()))); + } + ); + }); + + futures::executor::block_on(futures::future::join(test_fut, aux_fut)); + } + + #[test] + fn determine_new_blocks_does_not_request_genesis_even_in_multi_ancestry() { + let pool = TaskExecutor::new(); + let (mut ctx, mut handle) = make_subsystem_context::<(), _>(pool.clone()); + + let chain = TestChain::new(1, 3); + + let head = chain.header_by_number(3).unwrap().clone(); + let head_hash = head.hash(); + let known = TestKnownBlocks::default(); + + let expected_ancestry = (1..=3) + .map(|n| chain.header_by_number(n).map(|h| (h.hash(), h.clone())).unwrap()) + .rev() + .collect::>(); + + let test_fut = Box::pin(async move { + let ancestry = + determine_new_blocks(ctx.sender(), |h| known.is_known(h), head_hash, &head, 0) + .await + .unwrap(); + + assert_eq!(ancestry, expected_ancestry); + }); + + let aux_fut = Box::pin(async move { + assert_matches!( + handle.recv().await, + AllMessages::ChainApi(ChainApiMessage::Ancestors { + hash: h, + k, + response_channel: tx, + }) => { + assert_eq!(h, head_hash); + assert_eq!(k, 2); + + let _ = tx.send(Ok(chain.ancestry(&h, k as _))); + } + ); + + for _ in 0_u8..2 { + assert_matches!( + handle.recv().await, + AllMessages::ChainApi(ChainApiMessage::BlockHeader(h, tx)) => { + let _ = tx.send(Ok(chain.header_by_hash(&h).map(|h| h.clone()))); + } + ); + } + }); + + futures::executor::block_on(futures::future::join(test_fut, aux_fut)); + } +} diff --git a/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs b/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..6ab19fa660bd2fd05bc0cbb97745e1232b26a4e2 --- /dev/null +++ b/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs @@ -0,0 +1,14 @@ +// Copyright 2017-2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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. + +pub mod staging; diff --git a/polkadot/node/subsystem-util/src/inclusion_emulator/staging.rs b/polkadot/node/subsystem-util/src/inclusion_emulator/staging.rs new file mode 100644 index 0000000000000000000000000000000000000000..a4b85775981d952dddb56fddaf0f9115771ef431 --- /dev/null +++ b/polkadot/node/subsystem-util/src/inclusion_emulator/staging.rs @@ -0,0 +1,1450 @@ +// Copyright 2017-2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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. + +//! The implementation of the inclusion emulator for the 'staging' runtime version. +//! +//! # Overview +//! +//! A set of utilities for node-side code to emulate the logic the runtime uses for checking +//! parachain blocks in order to build prospective parachains that are produced ahead of the +//! relay chain. These utilities allow the node-side to predict, with high accuracy, what +//! the relay-chain will accept in the near future. +//! +//! This module has 2 key data types: [`Constraints`] and [`Fragment`]s. [`Constraints`] +//! exhaustively define the set of valid inputs and outputs to parachain execution. A [`Fragment`] +//! indicates a parachain block, anchored to the relay-chain at a particular relay-chain block, +//! known as the relay-parent. +//! +//! ## Fragment Validity +//! +//! Every relay-parent is implicitly associated with a unique set of [`Constraints`] that describe +//! the properties that must be true for a block to be included in a direct child of that block, +//! assuming there is no intermediate parachain block pending availability. +//! +//! However, the key factor that makes asynchronously-grown prospective chains +//! possible is the fact that the relay-chain accepts candidate blocks based on whether they +//! are valid under the constraints of the present moment, not based on whether they were +//! valid at the time of construction. +//! +//! As such, [`Fragment`]s are often, but not always constructed in such a way that they are +//! invalid at first and become valid later on, as the relay chain grows. +//! +//! # Usage +//! +//! It's expected that the users of this module will be building up trees of +//! [`Fragment`]s and consistently pruning and adding to the tree. +//! +//! ## Operating Constraints +//! +//! The *operating constraints* of a `Fragment` are the constraints with which that fragment +//! was intended to comply. The operating constraints are defined as the base constraints +//! of the relay-parent of the fragment modified by the cumulative modifications of all +//! fragments between the relay-parent and the current fragment. +//! +//! What the operating constraints are, in practice, is a prediction about the state of the +//! relay-chain in the future. The relay-chain is aware of some current state, and we want to +//! make an intelligent prediction about what might be accepted in the future based on +//! prior fragments that also exist off-chain. +//! +//! ## Fragment Trees +//! +//! As the relay-chain grows, some predictions come true and others come false. +//! And new predictions get made. These three changes correspond distinctly to the +//! 3 primary operations on fragment trees. +//! +//! A fragment tree is a mental model for thinking about a forking series of predictions +//! about a single parachain. There may be one or more fragment trees per parachain. +//! +//! In expectation, most parachains will have a plausibly-unique authorship method which means that +//! they should really be much closer to fragment-chains, maybe with an occasional fork. +//! +//! Avoiding fragment-tree blowup is beyond the scope of this module. +//! +//! ### Pruning Fragment Trees +//! +//! When the relay-chain advances, we want to compare the new constraints of that relay-parent to +//! the roots of the fragment trees we have. There are 3 cases: +//! +//! 1. The root fragment is still valid under the new constraints. In this case, we do nothing. This +//! is the "prediction still uncertain" case. +//! +//! 2. The root fragment is invalid under the new constraints because it has been subsumed by the +//! relay-chain. In this case, we can discard the root and split & re-root the fragment tree under +//! its descendents and compare to the new constraints again. This is the "prediction came true" +//! case. +//! +//! 3. The root fragment is invalid under the new constraints because a competing parachain block +//! has been included or it would never be accepted for some other reason. In this case we can +//! discard the entire fragment tree. This is the "prediction came false" case. +//! +//! This is all a bit of a simplification because it assumes that the relay-chain advances without +//! forks and is finalized instantly. In practice, the set of fragment-trees needs to be observable +//! from the perspective of a few different possible forks of the relay-chain and not pruned +//! too eagerly. +//! +//! Note that the fragments themselves don't need to change and the only thing we care about +//! is whether the predictions they represent are still valid. +//! +//! ### Extending Fragment Trees +//! +//! As predictions fade into the past, new ones should be stacked on top. +//! +//! Every new relay-chain block is an opportunity to make a new prediction about the future. +//! Higher-level logic should select the leaves of the fragment-trees to build upon or whether +//! to create a new fragment-tree. +//! +//! ### Code Upgrades +//! +//! Code upgrades are the main place where this emulation fails. The on-chain PVF upgrade scheduling +//! logic is very path-dependent and intricate so we just assume that code upgrades +//! can't be initiated and applied within a single fragment-tree. Fragment-trees aren't deep, +//! in practice and code upgrades are fairly rare. So what's likely to happen around code +//! upgrades is that the entire fragment-tree has to get discarded at some point. +//! +//! That means a few blocks of execution time lost, which is not a big deal for code upgrades +//! in practice at most once every few weeks. + +use polkadot_primitives::vstaging::{ + BlockNumber, CandidateCommitments, CollatorId, CollatorSignature, + Constraints as PrimitiveConstraints, Hash, HeadData, Id as ParaId, PersistedValidationData, + UpgradeRestriction, ValidationCodeHash, +}; +use std::{ + borrow::{Borrow, Cow}, + collections::HashMap, +}; + +/// Constraints on inbound HRMP channels. +#[derive(Debug, Clone, PartialEq)] +pub struct InboundHrmpLimitations { + /// An exhaustive set of all valid watermarks, sorted ascending + pub valid_watermarks: Vec, +} + +/// Constraints on outbound HRMP channels. +#[derive(Debug, Clone, PartialEq)] +pub struct OutboundHrmpChannelLimitations { + /// The maximum bytes that can be written to the channel. + pub bytes_remaining: usize, + /// The maximum messages that can be written to the channel. + pub messages_remaining: usize, +} + +/// Constraints on the actions that can be taken by a new parachain +/// block. These limitations are implicitly associated with some particular +/// parachain, which should be apparent from usage. +#[derive(Debug, Clone, PartialEq)] +pub struct Constraints { + /// The minimum relay-parent number accepted under these constraints. + pub min_relay_parent_number: BlockNumber, + /// The maximum Proof-of-Validity size allowed, in bytes. + pub max_pov_size: usize, + /// The maximum new validation code size allowed, in bytes. + pub max_code_size: usize, + /// The amount of UMP messages remaining. + pub ump_remaining: usize, + /// The amount of UMP bytes remaining. + pub ump_remaining_bytes: usize, + /// The maximum number of UMP messages allowed per candidate. + pub max_ump_num_per_candidate: usize, + /// Remaining DMP queue. Only includes sent-at block numbers. + pub dmp_remaining_messages: Vec, + /// The limitations of all registered inbound HRMP channels. + pub hrmp_inbound: InboundHrmpLimitations, + /// The limitations of all registered outbound HRMP channels. + pub hrmp_channels_out: HashMap, + /// The maximum number of HRMP messages allowed per candidate. + pub max_hrmp_num_per_candidate: usize, + /// The required parent head-data of the parachain. + pub required_parent: HeadData, + /// The expected validation-code-hash of this parachain. + pub validation_code_hash: ValidationCodeHash, + /// The code upgrade restriction signal as-of this parachain. + pub upgrade_restriction: Option, + /// The future validation code hash, if any, and at what relay-parent + /// number the upgrade would be minimally applied. + pub future_validation_code: Option<(BlockNumber, ValidationCodeHash)>, +} + +impl From for Constraints { + fn from(c: PrimitiveConstraints) -> Self { + Constraints { + min_relay_parent_number: c.min_relay_parent_number, + max_pov_size: c.max_pov_size as _, + max_code_size: c.max_code_size as _, + ump_remaining: c.ump_remaining as _, + ump_remaining_bytes: c.ump_remaining_bytes as _, + max_ump_num_per_candidate: c.max_ump_num_per_candidate as _, + dmp_remaining_messages: c.dmp_remaining_messages, + hrmp_inbound: InboundHrmpLimitations { + valid_watermarks: c.hrmp_inbound.valid_watermarks, + }, + hrmp_channels_out: c + .hrmp_channels_out + .into_iter() + .map(|(para_id, limits)| { + ( + para_id, + OutboundHrmpChannelLimitations { + bytes_remaining: limits.bytes_remaining as _, + messages_remaining: limits.messages_remaining as _, + }, + ) + }) + .collect(), + max_hrmp_num_per_candidate: c.max_hrmp_num_per_candidate as _, + required_parent: c.required_parent, + validation_code_hash: c.validation_code_hash, + upgrade_restriction: c.upgrade_restriction, + future_validation_code: c.future_validation_code, + } + } +} + +/// Kinds of errors that can occur when modifying constraints. +#[derive(Debug, Clone, PartialEq)] +pub enum ModificationError { + /// The HRMP watermark is not allowed. + DisallowedHrmpWatermark(BlockNumber), + /// No such HRMP outbound channel. + NoSuchHrmpChannel(ParaId), + /// Too many messages submitted to HRMP channel. + HrmpMessagesOverflow { + /// The ID of the recipient. + para_id: ParaId, + /// The amount of remaining messages in the capacity of the channel. + messages_remaining: usize, + /// The amount of messages submitted to the channel. + messages_submitted: usize, + }, + /// Too many bytes submitted to HRMP channel. + HrmpBytesOverflow { + /// The ID of the recipient. + para_id: ParaId, + /// The amount of remaining bytes in the capacity of the channel. + bytes_remaining: usize, + /// The amount of bytes submitted to the channel. + bytes_submitted: usize, + }, + /// Too many messages submitted to UMP. + UmpMessagesOverflow { + /// The amount of remaining messages in the capacity of UMP. + messages_remaining: usize, + /// The amount of messages submitted to UMP. + messages_submitted: usize, + }, + /// Too many bytes submitted to UMP. + UmpBytesOverflow { + /// The amount of remaining bytes in the capacity of UMP. + bytes_remaining: usize, + /// The amount of bytes submitted to UMP. + bytes_submitted: usize, + }, + /// Too many messages processed from DMP. + DmpMessagesUnderflow { + /// The amount of messages waiting to be processed from DMP. + messages_remaining: usize, + /// The amount of messages processed. + messages_processed: usize, + }, + /// No validation code upgrade to apply. + AppliedNonexistentCodeUpgrade, +} + +impl Constraints { + /// Check modifications against constraints. + pub fn check_modifications( + &self, + modifications: &ConstraintModifications, + ) -> Result<(), ModificationError> { + if let Some(HrmpWatermarkUpdate::Trunk(hrmp_watermark)) = modifications.hrmp_watermark { + // head updates are always valid. + if self.hrmp_inbound.valid_watermarks.iter().all(|w| w != &hrmp_watermark) { + return Err(ModificationError::DisallowedHrmpWatermark(hrmp_watermark)) + } + } + + for (id, outbound_hrmp_mod) in &modifications.outbound_hrmp { + if let Some(outbound) = self.hrmp_channels_out.get(&id) { + outbound.bytes_remaining.checked_sub(outbound_hrmp_mod.bytes_submitted).ok_or( + ModificationError::HrmpBytesOverflow { + para_id: *id, + bytes_remaining: outbound.bytes_remaining, + bytes_submitted: outbound_hrmp_mod.bytes_submitted, + }, + )?; + + outbound + .messages_remaining + .checked_sub(outbound_hrmp_mod.messages_submitted) + .ok_or(ModificationError::HrmpMessagesOverflow { + para_id: *id, + messages_remaining: outbound.messages_remaining, + messages_submitted: outbound_hrmp_mod.messages_submitted, + })?; + } else { + return Err(ModificationError::NoSuchHrmpChannel(*id)) + } + } + + self.ump_remaining.checked_sub(modifications.ump_messages_sent).ok_or( + ModificationError::UmpMessagesOverflow { + messages_remaining: self.ump_remaining, + messages_submitted: modifications.ump_messages_sent, + }, + )?; + + self.ump_remaining_bytes.checked_sub(modifications.ump_bytes_sent).ok_or( + ModificationError::UmpBytesOverflow { + bytes_remaining: self.ump_remaining_bytes, + bytes_submitted: modifications.ump_bytes_sent, + }, + )?; + + self.dmp_remaining_messages + .len() + .checked_sub(modifications.dmp_messages_processed) + .ok_or(ModificationError::DmpMessagesUnderflow { + messages_remaining: self.dmp_remaining_messages.len(), + messages_processed: modifications.dmp_messages_processed, + })?; + + if self.future_validation_code.is_none() && modifications.code_upgrade_applied { + return Err(ModificationError::AppliedNonexistentCodeUpgrade) + } + + Ok(()) + } + + /// Apply modifications to these constraints. If this succeeds, it passes + /// all sanity-checks. + pub fn apply_modifications( + &self, + modifications: &ConstraintModifications, + ) -> Result { + let mut new = self.clone(); + + if let Some(required_parent) = modifications.required_parent.as_ref() { + new.required_parent = required_parent.clone(); + } + + if let Some(ref hrmp_watermark) = modifications.hrmp_watermark { + match new.hrmp_inbound.valid_watermarks.binary_search(&hrmp_watermark.watermark()) { + Ok(pos) => { + // Exact match, so this is OK in all cases. + let _ = new.hrmp_inbound.valid_watermarks.drain(..pos + 1); + }, + Err(pos) => match hrmp_watermark { + HrmpWatermarkUpdate::Head(_) => { + // Updates to Head are always OK. + let _ = new.hrmp_inbound.valid_watermarks.drain(..pos); + }, + HrmpWatermarkUpdate::Trunk(n) => { + // Trunk update landing on disallowed watermark is not OK. + return Err(ModificationError::DisallowedHrmpWatermark(*n)) + }, + }, + } + } + + for (id, outbound_hrmp_mod) in &modifications.outbound_hrmp { + if let Some(outbound) = new.hrmp_channels_out.get_mut(&id) { + outbound.bytes_remaining = outbound + .bytes_remaining + .checked_sub(outbound_hrmp_mod.bytes_submitted) + .ok_or(ModificationError::HrmpBytesOverflow { + para_id: *id, + bytes_remaining: outbound.bytes_remaining, + bytes_submitted: outbound_hrmp_mod.bytes_submitted, + })?; + + outbound.messages_remaining = outbound + .messages_remaining + .checked_sub(outbound_hrmp_mod.messages_submitted) + .ok_or(ModificationError::HrmpMessagesOverflow { + para_id: *id, + messages_remaining: outbound.messages_remaining, + messages_submitted: outbound_hrmp_mod.messages_submitted, + })?; + } else { + return Err(ModificationError::NoSuchHrmpChannel(*id)) + } + } + + new.ump_remaining = new.ump_remaining.checked_sub(modifications.ump_messages_sent).ok_or( + ModificationError::UmpMessagesOverflow { + messages_remaining: new.ump_remaining, + messages_submitted: modifications.ump_messages_sent, + }, + )?; + + new.ump_remaining_bytes = new + .ump_remaining_bytes + .checked_sub(modifications.ump_bytes_sent) + .ok_or(ModificationError::UmpBytesOverflow { + bytes_remaining: new.ump_remaining_bytes, + bytes_submitted: modifications.ump_bytes_sent, + })?; + + if modifications.dmp_messages_processed > new.dmp_remaining_messages.len() { + return Err(ModificationError::DmpMessagesUnderflow { + messages_remaining: new.dmp_remaining_messages.len(), + messages_processed: modifications.dmp_messages_processed, + }) + } else { + new.dmp_remaining_messages = + new.dmp_remaining_messages[modifications.dmp_messages_processed..].to_vec(); + } + + if modifications.code_upgrade_applied { + new.validation_code_hash = new + .future_validation_code + .take() + .ok_or(ModificationError::AppliedNonexistentCodeUpgrade)? + .1; + } + + Ok(new) + } +} + +/// Information about a relay-chain block. +#[derive(Debug, Clone, PartialEq)] +pub struct RelayChainBlockInfo { + /// The hash of the relay-chain block. + pub hash: Hash, + /// The number of the relay-chain block. + pub number: BlockNumber, + /// The storage-root of the relay-chain block. + pub storage_root: Hash, +} + +/// An update to outbound HRMP channels. +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OutboundHrmpChannelModification { + /// The number of bytes submitted to the channel. + pub bytes_submitted: usize, + /// The number of messages submitted to the channel. + pub messages_submitted: usize, +} + +/// An update to the HRMP Watermark. +#[derive(Debug, Clone, PartialEq)] +pub enum HrmpWatermarkUpdate { + /// This is an update placing the watermark at the head of the chain, + /// which is always legal. + Head(BlockNumber), + /// This is an update placing the watermark behind the head of the + /// chain, which is only legal if it lands on a block where messages + /// were queued. + Trunk(BlockNumber), +} + +impl HrmpWatermarkUpdate { + fn watermark(&self) -> BlockNumber { + match *self { + HrmpWatermarkUpdate::Head(n) | HrmpWatermarkUpdate::Trunk(n) => n, + } + } +} + +/// Modifications to constraints as a result of prospective candidates. +#[derive(Debug, Clone, PartialEq)] +pub struct ConstraintModifications { + /// The required parent head to build upon. + pub required_parent: Option, + /// The new HRMP watermark + pub hrmp_watermark: Option, + /// Outbound HRMP channel modifications. + pub outbound_hrmp: HashMap, + /// The amount of UMP messages sent. + pub ump_messages_sent: usize, + /// The amount of UMP bytes sent. + pub ump_bytes_sent: usize, + /// The amount of DMP messages processed. + pub dmp_messages_processed: usize, + /// Whether a pending code upgrade has been applied. + pub code_upgrade_applied: bool, +} + +impl ConstraintModifications { + /// The 'identity' modifications: these can be applied to + /// any constraints and yield the exact same result. + pub fn identity() -> Self { + ConstraintModifications { + required_parent: None, + hrmp_watermark: None, + outbound_hrmp: HashMap::new(), + ump_messages_sent: 0, + ump_bytes_sent: 0, + dmp_messages_processed: 0, + code_upgrade_applied: false, + } + } + + /// Stack other modifications on top of these. + /// + /// This does no sanity-checking, so if `other` is garbage relative + /// to `self`, then the new value will be garbage as well. + /// + /// This is an addition which is not commutative. + pub fn stack(&mut self, other: &Self) { + if let Some(ref new_parent) = other.required_parent { + self.required_parent = Some(new_parent.clone()); + } + if let Some(ref new_hrmp_watermark) = other.hrmp_watermark { + self.hrmp_watermark = Some(new_hrmp_watermark.clone()); + } + + for (id, mods) in &other.outbound_hrmp { + let record = self.outbound_hrmp.entry(*id).or_default(); + record.messages_submitted += mods.messages_submitted; + record.bytes_submitted += mods.bytes_submitted; + } + + self.ump_messages_sent += other.ump_messages_sent; + self.ump_bytes_sent += other.ump_bytes_sent; + self.dmp_messages_processed += other.dmp_messages_processed; + self.code_upgrade_applied |= other.code_upgrade_applied; + } +} + +/// The prospective candidate. +/// +/// This comprises the key information that represent a candidate +/// without pinning it to a particular session. For example, everything +/// to do with the collator's signature and commitments are represented +/// here. But the erasure-root is not. This means that prospective candidates +/// are not correlated to any session in particular. +#[derive(Debug, Clone, PartialEq)] +pub struct ProspectiveCandidate<'a> { + /// The commitments to the output of the execution. + pub commitments: Cow<'a, CandidateCommitments>, + /// The collator that created the candidate. + pub collator: CollatorId, + /// The signature of the collator on the payload. + pub collator_signature: CollatorSignature, + /// The persisted validation data used to create the candidate. + pub persisted_validation_data: PersistedValidationData, + /// The hash of the PoV. + pub pov_hash: Hash, + /// The validation code hash used by the candidate. + pub validation_code_hash: ValidationCodeHash, +} + +impl<'a> ProspectiveCandidate<'a> { + fn into_owned(self) -> ProspectiveCandidate<'static> { + ProspectiveCandidate { commitments: Cow::Owned(self.commitments.into_owned()), ..self } + } + + /// Partially clone the prospective candidate, but borrow the + /// parts which are potentially heavy. + pub fn partial_clone(&self) -> ProspectiveCandidate { + ProspectiveCandidate { + commitments: Cow::Borrowed(self.commitments.borrow()), + collator: self.collator.clone(), + collator_signature: self.collator_signature.clone(), + persisted_validation_data: self.persisted_validation_data.clone(), + pov_hash: self.pov_hash, + validation_code_hash: self.validation_code_hash, + } + } +} + +#[cfg(test)] +impl ProspectiveCandidate<'static> { + fn commitments_mut(&mut self) -> &mut CandidateCommitments { + self.commitments.to_mut() + } +} + +/// Kinds of errors with the validity of a fragment. +#[derive(Debug, Clone, PartialEq)] +pub enum FragmentValidityError { + /// The validation code of the candidate doesn't match the + /// operating constraints. + /// + /// Expected, Got + ValidationCodeMismatch(ValidationCodeHash, ValidationCodeHash), + /// The persisted-validation-data doesn't match. + /// + /// Expected, Got + PersistedValidationDataMismatch(PersistedValidationData, PersistedValidationData), + /// The outputs of the candidate are invalid under the operating + /// constraints. + OutputsInvalid(ModificationError), + /// New validation code size too big. + /// + /// Max allowed, new. + CodeSizeTooLarge(usize, usize), + /// Relay parent too old. + /// + /// Min allowed, current. + RelayParentTooOld(BlockNumber, BlockNumber), + /// Para is required to process at least one DMP message from the queue. + DmpAdvancementRule, + /// Too many messages upward messages submitted. + UmpMessagesPerCandidateOverflow { + /// The amount of messages a single candidate can submit. + messages_allowed: usize, + /// The amount of messages sent to all HRMP channels. + messages_submitted: usize, + }, + /// Too many messages submitted to all HRMP channels. + HrmpMessagesPerCandidateOverflow { + /// The amount of messages a single candidate can submit. + messages_allowed: usize, + /// The amount of messages sent to all HRMP channels. + messages_submitted: usize, + }, + /// Code upgrade not allowed. + CodeUpgradeRestricted, + /// HRMP messages are not ascending or are duplicate. + /// + /// The `usize` is the index into the outbound HRMP messages of + /// the candidate. + HrmpMessagesDescendingOrDuplicate(usize), +} + +/// A parachain fragment, representing another prospective parachain block. +/// +/// This is a type which guarantees that the candidate is valid under the +/// operating constraints. +#[derive(Debug, Clone, PartialEq)] +pub struct Fragment<'a> { + /// The new relay-parent. + relay_parent: RelayChainBlockInfo, + /// The constraints this fragment is operating under. + operating_constraints: Constraints, + /// The core information about the prospective candidate. + candidate: ProspectiveCandidate<'a>, + /// Modifications to the constraints based on the outputs of + /// the candidate. + modifications: ConstraintModifications, +} + +impl<'a> Fragment<'a> { + /// Create a new fragment. + /// + /// This fails if the fragment isn't in line with the operating + /// constraints. That is, either its inputs or its outputs fail + /// checks against the constraints. + /// + /// This doesn't check that the collator signature is valid or + /// whether the PoV is small enough. + pub fn new( + relay_parent: RelayChainBlockInfo, + operating_constraints: Constraints, + candidate: ProspectiveCandidate<'a>, + ) -> Result { + let modifications = { + let commitments = &candidate.commitments; + ConstraintModifications { + required_parent: Some(commitments.head_data.clone()), + hrmp_watermark: Some({ + if commitments.hrmp_watermark == relay_parent.number { + HrmpWatermarkUpdate::Head(commitments.hrmp_watermark) + } else { + HrmpWatermarkUpdate::Trunk(commitments.hrmp_watermark) + } + }), + outbound_hrmp: { + let mut outbound_hrmp = HashMap::<_, OutboundHrmpChannelModification>::new(); + + let mut last_recipient = None::; + for (i, message) in commitments.horizontal_messages.iter().enumerate() { + if let Some(last) = last_recipient { + if last >= message.recipient { + return Err( + FragmentValidityError::HrmpMessagesDescendingOrDuplicate(i), + ) + } + } + + last_recipient = Some(message.recipient); + let record = outbound_hrmp.entry(message.recipient).or_default(); + + record.bytes_submitted += message.data.len(); + record.messages_submitted += 1; + } + + outbound_hrmp + }, + ump_messages_sent: commitments.upward_messages.len(), + ump_bytes_sent: commitments.upward_messages.iter().map(|msg| msg.len()).sum(), + dmp_messages_processed: commitments.processed_downward_messages as _, + code_upgrade_applied: operating_constraints + .future_validation_code + .map_or(false, |(at, _)| relay_parent.number >= at), + } + }; + + validate_against_constraints( + &operating_constraints, + &relay_parent, + &candidate, + &modifications, + )?; + + Ok(Fragment { relay_parent, operating_constraints, candidate, modifications }) + } + + /// Access the relay parent information. + pub fn relay_parent(&self) -> &RelayChainBlockInfo { + &self.relay_parent + } + + /// Access the operating constraints + pub fn operating_constraints(&self) -> &Constraints { + &self.operating_constraints + } + + /// Access the underlying prospective candidate. + pub fn candidate(&self) -> &ProspectiveCandidate<'a> { + &self.candidate + } + + /// Modifications to constraints based on the outputs of the candidate. + pub fn constraint_modifications(&self) -> &ConstraintModifications { + &self.modifications + } + + /// Convert the fragment into an owned variant. + pub fn into_owned(self) -> Fragment<'static> { + Fragment { candidate: self.candidate.into_owned(), ..self } + } + + /// Validate this fragment against some set of constraints + /// instead of the operating constraints. + pub fn validate_against_constraints( + &self, + constraints: &Constraints, + ) -> Result<(), FragmentValidityError> { + validate_against_constraints( + constraints, + &self.relay_parent, + &self.candidate, + &self.modifications, + ) + } +} + +fn validate_against_constraints( + constraints: &Constraints, + relay_parent: &RelayChainBlockInfo, + candidate: &ProspectiveCandidate, + modifications: &ConstraintModifications, +) -> Result<(), FragmentValidityError> { + let expected_pvd = PersistedValidationData { + parent_head: constraints.required_parent.clone(), + relay_parent_number: relay_parent.number, + relay_parent_storage_root: relay_parent.storage_root, + max_pov_size: constraints.max_pov_size as u32, + }; + + if expected_pvd != candidate.persisted_validation_data { + return Err(FragmentValidityError::PersistedValidationDataMismatch( + expected_pvd, + candidate.persisted_validation_data.clone(), + )) + } + + if constraints.validation_code_hash != candidate.validation_code_hash { + return Err(FragmentValidityError::ValidationCodeMismatch( + constraints.validation_code_hash, + candidate.validation_code_hash, + )) + } + + if relay_parent.number < constraints.min_relay_parent_number { + return Err(FragmentValidityError::RelayParentTooOld( + constraints.min_relay_parent_number, + relay_parent.number, + )) + } + + if candidate.commitments.new_validation_code.is_some() { + match constraints.upgrade_restriction { + None => {}, + Some(UpgradeRestriction::Present) => + return Err(FragmentValidityError::CodeUpgradeRestricted), + } + } + + let announced_code_size = candidate + .commitments + .new_validation_code + .as_ref() + .map_or(0, |code| code.0.len()); + + if announced_code_size > constraints.max_code_size { + return Err(FragmentValidityError::CodeSizeTooLarge( + constraints.max_code_size, + announced_code_size, + )) + } + + if modifications.dmp_messages_processed == 0 { + if constraints + .dmp_remaining_messages + .get(0) + .map_or(false, |&msg_sent_at| msg_sent_at <= relay_parent.number) + { + return Err(FragmentValidityError::DmpAdvancementRule) + } + } + + if candidate.commitments.horizontal_messages.len() > constraints.max_hrmp_num_per_candidate { + return Err(FragmentValidityError::HrmpMessagesPerCandidateOverflow { + messages_allowed: constraints.max_hrmp_num_per_candidate, + messages_submitted: candidate.commitments.horizontal_messages.len(), + }) + } + + if candidate.commitments.upward_messages.len() > constraints.max_ump_num_per_candidate { + return Err(FragmentValidityError::UmpMessagesPerCandidateOverflow { + messages_allowed: constraints.max_ump_num_per_candidate, + messages_submitted: candidate.commitments.upward_messages.len(), + }) + } + + constraints + .check_modifications(&modifications) + .map_err(FragmentValidityError::OutputsInvalid) +} + +#[cfg(test)] +mod tests { + use super::*; + use polkadot_primitives::vstaging::{ + CollatorPair, HorizontalMessages, OutboundHrmpMessage, ValidationCode, + }; + use sp_application_crypto::Pair; + + #[test] + fn stack_modifications() { + let para_a = ParaId::from(1u32); + let para_b = ParaId::from(2u32); + let para_c = ParaId::from(3u32); + + let a = ConstraintModifications { + required_parent: None, + hrmp_watermark: None, + outbound_hrmp: { + let mut map = HashMap::new(); + map.insert( + para_a, + OutboundHrmpChannelModification { bytes_submitted: 100, messages_submitted: 5 }, + ); + + map.insert( + para_b, + OutboundHrmpChannelModification { bytes_submitted: 100, messages_submitted: 5 }, + ); + + map + }, + ump_messages_sent: 6, + ump_bytes_sent: 1000, + dmp_messages_processed: 5, + code_upgrade_applied: true, + }; + + let b = ConstraintModifications { + required_parent: None, + hrmp_watermark: None, + outbound_hrmp: { + let mut map = HashMap::new(); + map.insert( + para_b, + OutboundHrmpChannelModification { bytes_submitted: 100, messages_submitted: 5 }, + ); + + map.insert( + para_c, + OutboundHrmpChannelModification { bytes_submitted: 100, messages_submitted: 5 }, + ); + + map + }, + ump_messages_sent: 6, + ump_bytes_sent: 1000, + dmp_messages_processed: 5, + code_upgrade_applied: true, + }; + + let mut c = a.clone(); + c.stack(&b); + + assert_eq!( + c, + ConstraintModifications { + required_parent: None, + hrmp_watermark: None, + outbound_hrmp: { + let mut map = HashMap::new(); + map.insert( + para_a, + OutboundHrmpChannelModification { + bytes_submitted: 100, + messages_submitted: 5, + }, + ); + + map.insert( + para_b, + OutboundHrmpChannelModification { + bytes_submitted: 200, + messages_submitted: 10, + }, + ); + + map.insert( + para_c, + OutboundHrmpChannelModification { + bytes_submitted: 100, + messages_submitted: 5, + }, + ); + + map + }, + ump_messages_sent: 12, + ump_bytes_sent: 2000, + dmp_messages_processed: 10, + code_upgrade_applied: true, + }, + ); + + let mut d = ConstraintModifications::identity(); + d.stack(&a); + d.stack(&b); + + assert_eq!(c, d); + } + + fn make_constraints() -> Constraints { + let para_a = ParaId::from(1u32); + let para_b = ParaId::from(2u32); + let para_c = ParaId::from(3u32); + + Constraints { + min_relay_parent_number: 5, + max_pov_size: 1000, + max_code_size: 1000, + ump_remaining: 10, + ump_remaining_bytes: 1024, + max_ump_num_per_candidate: 5, + dmp_remaining_messages: Vec::new(), + hrmp_inbound: InboundHrmpLimitations { valid_watermarks: vec![6, 8] }, + hrmp_channels_out: { + let mut map = HashMap::new(); + + map.insert( + para_a, + OutboundHrmpChannelLimitations { messages_remaining: 5, bytes_remaining: 512 }, + ); + + map.insert( + para_b, + OutboundHrmpChannelLimitations { + messages_remaining: 10, + bytes_remaining: 1024, + }, + ); + + map.insert( + para_c, + OutboundHrmpChannelLimitations { messages_remaining: 1, bytes_remaining: 128 }, + ); + + map + }, + max_hrmp_num_per_candidate: 5, + required_parent: HeadData::from(vec![1, 2, 3]), + validation_code_hash: ValidationCode(vec![4, 5, 6]).hash(), + upgrade_restriction: None, + future_validation_code: None, + } + } + + #[test] + fn constraints_disallowed_trunk_watermark() { + let constraints = make_constraints(); + let mut modifications = ConstraintModifications::identity(); + modifications.hrmp_watermark = Some(HrmpWatermarkUpdate::Trunk(7)); + + assert_eq!( + constraints.check_modifications(&modifications), + Err(ModificationError::DisallowedHrmpWatermark(7)), + ); + + assert_eq!( + constraints.apply_modifications(&modifications), + Err(ModificationError::DisallowedHrmpWatermark(7)), + ); + } + + #[test] + fn constraints_always_allow_head_watermark() { + let constraints = make_constraints(); + let mut modifications = ConstraintModifications::identity(); + modifications.hrmp_watermark = Some(HrmpWatermarkUpdate::Head(7)); + + assert!(constraints.check_modifications(&modifications).is_ok()); + + let new_constraints = constraints.apply_modifications(&modifications).unwrap(); + assert_eq!(new_constraints.hrmp_inbound.valid_watermarks, vec![8]); + } + + #[test] + fn constraints_no_such_hrmp_channel() { + let constraints = make_constraints(); + let mut modifications = ConstraintModifications::identity(); + let bad_para = ParaId::from(100u32); + modifications.outbound_hrmp.insert( + bad_para, + OutboundHrmpChannelModification { bytes_submitted: 0, messages_submitted: 0 }, + ); + + assert_eq!( + constraints.check_modifications(&modifications), + Err(ModificationError::NoSuchHrmpChannel(bad_para)), + ); + + assert_eq!( + constraints.apply_modifications(&modifications), + Err(ModificationError::NoSuchHrmpChannel(bad_para)), + ); + } + + #[test] + fn constraints_hrmp_messages_overflow() { + let constraints = make_constraints(); + let mut modifications = ConstraintModifications::identity(); + let para_a = ParaId::from(1u32); + modifications.outbound_hrmp.insert( + para_a, + OutboundHrmpChannelModification { bytes_submitted: 0, messages_submitted: 6 }, + ); + + assert_eq!( + constraints.check_modifications(&modifications), + Err(ModificationError::HrmpMessagesOverflow { + para_id: para_a, + messages_remaining: 5, + messages_submitted: 6, + }), + ); + + assert_eq!( + constraints.apply_modifications(&modifications), + Err(ModificationError::HrmpMessagesOverflow { + para_id: para_a, + messages_remaining: 5, + messages_submitted: 6, + }), + ); + } + + #[test] + fn constraints_hrmp_bytes_overflow() { + let constraints = make_constraints(); + let mut modifications = ConstraintModifications::identity(); + let para_a = ParaId::from(1u32); + modifications.outbound_hrmp.insert( + para_a, + OutboundHrmpChannelModification { bytes_submitted: 513, messages_submitted: 1 }, + ); + + assert_eq!( + constraints.check_modifications(&modifications), + Err(ModificationError::HrmpBytesOverflow { + para_id: para_a, + bytes_remaining: 512, + bytes_submitted: 513, + }), + ); + + assert_eq!( + constraints.apply_modifications(&modifications), + Err(ModificationError::HrmpBytesOverflow { + para_id: para_a, + bytes_remaining: 512, + bytes_submitted: 513, + }), + ); + } + + #[test] + fn constraints_ump_messages_overflow() { + let constraints = make_constraints(); + let mut modifications = ConstraintModifications::identity(); + modifications.ump_messages_sent = 11; + + assert_eq!( + constraints.check_modifications(&modifications), + Err(ModificationError::UmpMessagesOverflow { + messages_remaining: 10, + messages_submitted: 11, + }), + ); + + assert_eq!( + constraints.apply_modifications(&modifications), + Err(ModificationError::UmpMessagesOverflow { + messages_remaining: 10, + messages_submitted: 11, + }), + ); + } + + #[test] + fn constraints_ump_bytes_overflow() { + let constraints = make_constraints(); + let mut modifications = ConstraintModifications::identity(); + modifications.ump_bytes_sent = 1025; + + assert_eq!( + constraints.check_modifications(&modifications), + Err(ModificationError::UmpBytesOverflow { + bytes_remaining: 1024, + bytes_submitted: 1025, + }), + ); + + assert_eq!( + constraints.apply_modifications(&modifications), + Err(ModificationError::UmpBytesOverflow { + bytes_remaining: 1024, + bytes_submitted: 1025, + }), + ); + } + + #[test] + fn constraints_dmp_messages() { + let mut constraints = make_constraints(); + let mut modifications = ConstraintModifications::identity(); + assert!(constraints.check_modifications(&modifications).is_ok()); + assert!(constraints.apply_modifications(&modifications).is_ok()); + + modifications.dmp_messages_processed = 6; + + assert_eq!( + constraints.check_modifications(&modifications), + Err(ModificationError::DmpMessagesUnderflow { + messages_remaining: 0, + messages_processed: 6, + }), + ); + + assert_eq!( + constraints.apply_modifications(&modifications), + Err(ModificationError::DmpMessagesUnderflow { + messages_remaining: 0, + messages_processed: 6, + }), + ); + + constraints.dmp_remaining_messages = vec![1, 4, 8, 10]; + modifications.dmp_messages_processed = 2; + assert!(constraints.check_modifications(&modifications).is_ok()); + let constraints = constraints + .apply_modifications(&modifications) + .expect("modifications are valid"); + + assert_eq!(&constraints.dmp_remaining_messages, &[8, 10]); + } + + #[test] + fn constraints_nonexistent_code_upgrade() { + let constraints = make_constraints(); + let mut modifications = ConstraintModifications::identity(); + modifications.code_upgrade_applied = true; + + assert_eq!( + constraints.check_modifications(&modifications), + Err(ModificationError::AppliedNonexistentCodeUpgrade), + ); + + assert_eq!( + constraints.apply_modifications(&modifications), + Err(ModificationError::AppliedNonexistentCodeUpgrade), + ); + } + + fn make_candidate( + constraints: &Constraints, + relay_parent: &RelayChainBlockInfo, + ) -> ProspectiveCandidate<'static> { + let collator_pair = CollatorPair::generate().0; + let collator = collator_pair.public(); + + let sig = collator_pair.sign(b"blabla".as_slice()); + + ProspectiveCandidate { + commitments: Cow::Owned(CandidateCommitments { + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + head_data: HeadData::from(vec![1, 2, 3, 4, 5]), + processed_downward_messages: 0, + hrmp_watermark: relay_parent.number, + }), + collator, + collator_signature: sig, + persisted_validation_data: PersistedValidationData { + parent_head: constraints.required_parent.clone(), + relay_parent_number: relay_parent.number, + relay_parent_storage_root: relay_parent.storage_root, + max_pov_size: constraints.max_pov_size as u32, + }, + pov_hash: Hash::repeat_byte(1), + validation_code_hash: constraints.validation_code_hash, + } + } + + #[test] + fn fragment_validation_code_mismatch() { + let relay_parent = RelayChainBlockInfo { + number: 6, + hash: Hash::repeat_byte(0x0a), + storage_root: Hash::repeat_byte(0xff), + }; + + let constraints = make_constraints(); + let mut candidate = make_candidate(&constraints, &relay_parent); + + let expected_code = constraints.validation_code_hash; + let got_code = ValidationCode(vec![9, 9, 9]).hash(); + + candidate.validation_code_hash = got_code; + + assert_eq!( + Fragment::new(relay_parent, constraints, candidate), + Err(FragmentValidityError::ValidationCodeMismatch(expected_code, got_code,)), + ) + } + + #[test] + fn fragment_pvd_mismatch() { + let relay_parent = RelayChainBlockInfo { + number: 6, + hash: Hash::repeat_byte(0x0a), + storage_root: Hash::repeat_byte(0xff), + }; + + let relay_parent_b = RelayChainBlockInfo { + number: 6, + hash: Hash::repeat_byte(0x0b), + storage_root: Hash::repeat_byte(0xee), + }; + + let constraints = make_constraints(); + let candidate = make_candidate(&constraints, &relay_parent); + + let expected_pvd = PersistedValidationData { + parent_head: constraints.required_parent.clone(), + relay_parent_number: relay_parent_b.number, + relay_parent_storage_root: relay_parent_b.storage_root, + max_pov_size: constraints.max_pov_size as u32, + }; + + let got_pvd = candidate.persisted_validation_data.clone(); + + assert_eq!( + Fragment::new(relay_parent_b, constraints, candidate), + Err(FragmentValidityError::PersistedValidationDataMismatch(expected_pvd, got_pvd,)), + ); + } + + #[test] + fn fragment_code_size_too_large() { + let relay_parent = RelayChainBlockInfo { + number: 6, + hash: Hash::repeat_byte(0x0a), + storage_root: Hash::repeat_byte(0xff), + }; + + let constraints = make_constraints(); + let mut candidate = make_candidate(&constraints, &relay_parent); + + let max_code_size = constraints.max_code_size; + candidate.commitments_mut().new_validation_code = Some(vec![0; max_code_size + 1].into()); + + assert_eq!( + Fragment::new(relay_parent, constraints, candidate), + Err(FragmentValidityError::CodeSizeTooLarge(max_code_size, max_code_size + 1,)), + ); + } + + #[test] + fn fragment_relay_parent_too_old() { + let relay_parent = RelayChainBlockInfo { + number: 3, + hash: Hash::repeat_byte(0x0a), + storage_root: Hash::repeat_byte(0xff), + }; + + let constraints = make_constraints(); + let candidate = make_candidate(&constraints, &relay_parent); + + assert_eq!( + Fragment::new(relay_parent, constraints, candidate), + Err(FragmentValidityError::RelayParentTooOld(5, 3,)), + ); + } + + #[test] + fn fragment_hrmp_messages_overflow() { + let relay_parent = RelayChainBlockInfo { + number: 6, + hash: Hash::repeat_byte(0x0a), + storage_root: Hash::repeat_byte(0xff), + }; + + let constraints = make_constraints(); + let mut candidate = make_candidate(&constraints, &relay_parent); + + let max_hrmp = constraints.max_hrmp_num_per_candidate; + + candidate + .commitments_mut() + .horizontal_messages + .try_extend((0..max_hrmp + 1).map(|i| OutboundHrmpMessage { + recipient: ParaId::from(i as u32), + data: vec![1, 2, 3], + })) + .unwrap(); + + assert_eq!( + Fragment::new(relay_parent, constraints, candidate), + Err(FragmentValidityError::HrmpMessagesPerCandidateOverflow { + messages_allowed: max_hrmp, + messages_submitted: max_hrmp + 1, + }), + ); + } + + #[test] + fn fragment_dmp_advancement_rule() { + let relay_parent = RelayChainBlockInfo { + number: 6, + hash: Hash::repeat_byte(0x0a), + storage_root: Hash::repeat_byte(0xff), + }; + + let mut constraints = make_constraints(); + let mut candidate = make_candidate(&constraints, &relay_parent); + + // Empty dmp queue is ok. + assert!(Fragment::new(relay_parent.clone(), constraints.clone(), candidate.clone()).is_ok()); + // Unprocessed message that was sent later is ok. + constraints.dmp_remaining_messages = vec![relay_parent.number + 1]; + assert!(Fragment::new(relay_parent.clone(), constraints.clone(), candidate.clone()).is_ok()); + + for block_number in 0..=relay_parent.number { + constraints.dmp_remaining_messages = vec![block_number]; + + assert_eq!( + Fragment::new(relay_parent.clone(), constraints.clone(), candidate.clone()), + Err(FragmentValidityError::DmpAdvancementRule), + ); + } + + candidate.commitments.to_mut().processed_downward_messages = 1; + assert!(Fragment::new(relay_parent, constraints, candidate).is_ok()); + } + + #[test] + fn fragment_ump_messages_overflow() { + let relay_parent = RelayChainBlockInfo { + number: 6, + hash: Hash::repeat_byte(0x0a), + storage_root: Hash::repeat_byte(0xff), + }; + + let constraints = make_constraints(); + let mut candidate = make_candidate(&constraints, &relay_parent); + + let max_ump = constraints.max_ump_num_per_candidate; + + candidate + .commitments + .to_mut() + .upward_messages + .try_extend((0..max_ump + 1).map(|i| vec![i as u8])) + .unwrap(); + + assert_eq!( + Fragment::new(relay_parent, constraints, candidate), + Err(FragmentValidityError::UmpMessagesPerCandidateOverflow { + messages_allowed: max_ump, + messages_submitted: max_ump + 1, + }), + ); + } + + #[test] + fn fragment_code_upgrade_restricted() { + let relay_parent = RelayChainBlockInfo { + number: 6, + hash: Hash::repeat_byte(0x0a), + storage_root: Hash::repeat_byte(0xff), + }; + + let mut constraints = make_constraints(); + let mut candidate = make_candidate(&constraints, &relay_parent); + + constraints.upgrade_restriction = Some(UpgradeRestriction::Present); + candidate.commitments_mut().new_validation_code = Some(ValidationCode(vec![1, 2, 3])); + + assert_eq!( + Fragment::new(relay_parent, constraints, candidate), + Err(FragmentValidityError::CodeUpgradeRestricted), + ); + } + + #[test] + fn fragment_hrmp_messages_descending_or_duplicate() { + let relay_parent = RelayChainBlockInfo { + number: 6, + hash: Hash::repeat_byte(0x0a), + storage_root: Hash::repeat_byte(0xff), + }; + + let constraints = make_constraints(); + let mut candidate = make_candidate(&constraints, &relay_parent); + + candidate.commitments_mut().horizontal_messages = HorizontalMessages::truncate_from(vec![ + OutboundHrmpMessage { recipient: ParaId::from(0 as u32), data: vec![1, 2, 3] }, + OutboundHrmpMessage { recipient: ParaId::from(0 as u32), data: vec![4, 5, 6] }, + ]); + + assert_eq!( + Fragment::new(relay_parent.clone(), constraints.clone(), candidate.clone()), + Err(FragmentValidityError::HrmpMessagesDescendingOrDuplicate(1)), + ); + + candidate.commitments_mut().horizontal_messages = HorizontalMessages::truncate_from(vec![ + OutboundHrmpMessage { recipient: ParaId::from(1 as u32), data: vec![1, 2, 3] }, + OutboundHrmpMessage { recipient: ParaId::from(0 as u32), data: vec![4, 5, 6] }, + ]); + + assert_eq!( + Fragment::new(relay_parent, constraints, candidate), + Err(FragmentValidityError::HrmpMessagesDescendingOrDuplicate(1)), + ); + } +} diff --git a/polkadot/node/subsystem-util/src/lib.rs b/polkadot/node/subsystem-util/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..daee4a8350e5af321f9a040c2c943879588037bf --- /dev/null +++ b/polkadot/node/subsystem-util/src/lib.rs @@ -0,0 +1,442 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Utility module for subsystems +//! +//! Many subsystems have common interests such as canceling a bunch of spawned jobs, +//! or determining what their validator ID is. These common interests are factored into +//! this module. +//! +//! This crate also reexports Prometheus metric types which are expected to be implemented by +//! subsystems. + +#![warn(missing_docs)] + +use polkadot_node_subsystem::{ + errors::{RuntimeApiError, SubsystemError}, + messages::{RuntimeApiMessage, RuntimeApiRequest, RuntimeApiSender}, + overseer, SubsystemSender, +}; +use polkadot_primitives::{slashing, ExecutorParams}; + +pub use overseer::{ + gen::{OrchestraError as OverseerError, Timeout}, + Subsystem, TimeoutExt, +}; + +pub use polkadot_node_metrics::{metrics, Metronome}; + +use futures::channel::{mpsc, oneshot}; +use parity_scale_codec::Encode; + +use polkadot_primitives::{ + vstaging as vstaging_primitives, AuthorityDiscoveryId, CandidateEvent, CandidateHash, + CommittedCandidateReceipt, CoreState, EncodeAs, GroupIndex, GroupRotationInfo, Hash, + Id as ParaId, OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, + SessionIndex, SessionInfo, Signed, SigningContext, ValidationCode, ValidationCodeHash, + ValidatorId, ValidatorIndex, ValidatorSignature, +}; +pub use rand; +use sp_application_crypto::AppCrypto; +use sp_core::ByteArray; +use sp_keystore::{Error as KeystoreError, KeystorePtr}; +use std::time::Duration; +use thiserror::Error; + +pub use metered; +pub use polkadot_node_network_protocol::MIN_GOSSIP_PEERS; + +pub use determine_new_blocks::determine_new_blocks; + +/// These reexports are required so that external crates can use the `delegated_subsystem` macro +/// properly. +pub mod reexports { + pub use polkadot_overseer::gen::{SpawnedSubsystem, Spawner, Subsystem, SubsystemContext}; +} + +/// A utility for managing the implicit view of the relay-chain derived from active +/// leaves and the minimum allowed relay-parents that parachain candidates can have +/// and be backed in those leaves' children. +pub mod backing_implicit_view; +/// Database trait for subsystem. +pub mod database; +/// An emulator for node-side code to predict the results of on-chain parachain inclusion +/// and predict future constraints. +pub mod inclusion_emulator; +/// Convenient and efficient runtime info access. +pub mod runtime; + +/// Nested message sending +/// +/// Useful for having mostly synchronous code, with submodules spawning short lived asynchronous +/// tasks, sending messages back. +pub mod nesting_sender; + +pub mod reputation; + +mod determine_new_blocks; + +#[cfg(test)] +mod tests; + +/// Duration a job will wait after sending a stop signal before hard-aborting. +pub const JOB_GRACEFUL_STOP_DURATION: Duration = Duration::from_secs(1); +/// Capacity of channels to and from individual jobs +pub const JOB_CHANNEL_CAPACITY: usize = 64; + +/// Utility errors +#[derive(Debug, Error)] +pub enum Error { + /// Attempted to send or receive on a oneshot channel which had been canceled + #[error(transparent)] + Oneshot(#[from] oneshot::Canceled), + /// Attempted to send on a MPSC channel which has been canceled + #[error(transparent)] + Mpsc(#[from] mpsc::SendError), + /// A subsystem error + #[error(transparent)] + Subsystem(#[from] SubsystemError), + /// An error in the Runtime API. + #[error(transparent)] + RuntimeApi(#[from] RuntimeApiError), + /// The type system wants this even though it doesn't make sense + #[error(transparent)] + Infallible(#[from] std::convert::Infallible), + /// Attempted to convert from an `AllMessages` to a `FromJob`, and failed. + #[error("AllMessage not relevant to Job")] + SenderConversion(String), + /// The local node is not a validator. + #[error("Node is not a validator")] + NotAValidator, + /// Already forwarding errors to another sender + #[error("AlreadyForwarding")] + AlreadyForwarding, + /// Data that are supposed to be there a not there + #[error("Data are not available")] + DataNotAvailable, +} + +impl From for Error { + fn from(e: OverseerError) -> Self { + Self::from(SubsystemError::from(e)) + } +} + +/// A type alias for Runtime API receivers. +pub type RuntimeApiReceiver = oneshot::Receiver>; + +/// Request some data from the `RuntimeApi`. +pub async fn request_from_runtime( + parent: Hash, + sender: &mut Sender, + request_builder: RequestBuilder, +) -> RuntimeApiReceiver +where + RequestBuilder: FnOnce(RuntimeApiSender) -> RuntimeApiRequest, + Sender: SubsystemSender, +{ + let (tx, rx) = oneshot::channel(); + + sender + .send_message(RuntimeApiMessage::Request(parent, request_builder(tx)).into()) + .await; + + rx +} + +/// Construct specialized request functions for the runtime. +/// +/// These would otherwise get pretty repetitive. +macro_rules! specialize_requests { + // expand return type name for documentation purposes + (fn $func_name:ident( $( $param_name:ident : $param_ty:ty ),* ) -> $return_ty:ty ; $request_variant:ident;) => { + specialize_requests!{ + named stringify!($request_variant) ; fn $func_name( $( $param_name : $param_ty ),* ) -> $return_ty ; $request_variant; + } + }; + + // create a single specialized request function + (named $doc_name:expr ; fn $func_name:ident( $( $param_name:ident : $param_ty:ty ),* ) -> $return_ty:ty ; $request_variant:ident;) => { + #[doc = "Request `"] + #[doc = $doc_name] + #[doc = "` from the runtime"] + pub async fn $func_name ( + parent: Hash, + $( + $param_name: $param_ty, + )* + sender: &mut impl overseer::SubsystemSender, + ) -> RuntimeApiReceiver<$return_ty> + { + request_from_runtime(parent, sender, |tx| RuntimeApiRequest::$request_variant( + $( $param_name, )* tx + )).await + } + }; + + // recursive decompose + ( + fn $func_name:ident( $( $param_name:ident : $param_ty:ty ),* ) -> $return_ty:ty ; $request_variant:ident; + $( + fn $t_func_name:ident( $( $t_param_name:ident : $t_param_ty:ty ),* ) -> $t_return_ty:ty ; $t_request_variant:ident; + )+ + ) => { + specialize_requests!{ + fn $func_name( $( $param_name : $param_ty ),* ) -> $return_ty ; $request_variant ; + } + specialize_requests!{ + $( + fn $t_func_name( $( $t_param_name : $t_param_ty ),* ) -> $t_return_ty ; $t_request_variant ; + )+ + } + }; +} + +specialize_requests! { + fn request_runtime_api_version() -> u32; Version; + fn request_authorities() -> Vec; Authorities; + fn request_validators() -> Vec; Validators; + fn request_validator_groups() -> (Vec>, GroupRotationInfo); ValidatorGroups; + fn request_availability_cores() -> Vec; AvailabilityCores; + fn request_persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption) -> Option; PersistedValidationData; + fn request_assumed_validation_data(para_id: ParaId, expected_persisted_validation_data_hash: Hash) -> Option<(PersistedValidationData, ValidationCodeHash)>; AssumedValidationData; + fn request_session_index_for_child() -> SessionIndex; SessionIndexForChild; + fn request_validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption) -> Option; ValidationCode; + fn request_validation_code_by_hash(validation_code_hash: ValidationCodeHash) -> Option; ValidationCodeByHash; + fn request_candidate_pending_availability(para_id: ParaId) -> Option; CandidatePendingAvailability; + fn request_candidate_events() -> Vec; CandidateEvents; + fn request_session_info(index: SessionIndex) -> Option; SessionInfo; + fn request_validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option; ValidationCodeHash; + fn request_on_chain_votes() -> Option; FetchOnChainVotes; + fn request_session_executor_params(session_index: SessionIndex) -> Option;SessionExecutorParams; + fn request_unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>; UnappliedSlashes; + fn request_key_ownership_proof(validator_id: ValidatorId) -> Option; KeyOwnershipProof; + fn request_submit_report_dispute_lost(dp: slashing::DisputeProof, okop: slashing::OpaqueKeyOwnershipProof) -> Option<()>; SubmitReportDisputeLost; + + fn request_staging_async_backing_params() -> vstaging_primitives::AsyncBackingParams; StagingAsyncBackingParams; +} + +/// Requests executor parameters from the runtime effective at given relay-parent. First obtains +/// session index at the relay-parent, relying on the fact that it should be cached by the runtime +/// API caching layer even if the block itself has already been pruned. Then requests executor +/// parameters by session index. +/// Returns an error if failed to communicate to the runtime, or the parameters are not in the +/// storage, which should never happen. +/// Returns default execution parameters if the runtime doesn't yet support `SessionExecutorParams` +/// API call. +/// Otherwise, returns execution parameters returned by the runtime. +pub async fn executor_params_at_relay_parent( + relay_parent: Hash, + sender: &mut impl overseer::SubsystemSender, +) -> Result { + match request_session_index_for_child(relay_parent, sender).await.await { + Err(err) => { + // Failed to communicate with the runtime + Err(Error::Oneshot(err)) + }, + Ok(Err(err)) => { + // Runtime has failed to obtain a session index at the relay-parent. + Err(Error::RuntimeApi(err)) + }, + Ok(Ok(session_index)) => { + match request_session_executor_params(relay_parent, session_index, sender).await.await { + Err(err) => { + // Failed to communicate with the runtime + Err(Error::Oneshot(err)) + }, + Ok(Err(RuntimeApiError::NotSupported { .. })) => { + // Runtime doesn't yet support the api requested, should execute anyway + // with default set of parameters + Ok(ExecutorParams::default()) + }, + Ok(Err(err)) => { + // Runtime failed to execute the request + Err(Error::RuntimeApi(err)) + }, + Ok(Ok(None)) => { + // Storage doesn't contain a parameter set for the given session; should + // never happen + Err(Error::DataNotAvailable) + }, + Ok(Ok(Some(executor_params))) => Ok(executor_params), + } + }, + } +} + +/// From the given set of validators, find the first key we can sign with, if any. +pub fn signing_key<'a>( + validators: impl IntoIterator, + keystore: &KeystorePtr, +) -> Option { + signing_key_and_index(validators, keystore).map(|(k, _)| k) +} + +/// From the given set of validators, find the first key we can sign with, if any, and return it +/// along with the validator index. +pub fn signing_key_and_index<'a>( + validators: impl IntoIterator, + keystore: &KeystorePtr, +) -> Option<(ValidatorId, ValidatorIndex)> { + for (i, v) in validators.into_iter().enumerate() { + if keystore.has_keys(&[(v.to_raw_vec(), ValidatorId::ID)]) { + return Some((v.clone(), ValidatorIndex(i as _))) + } + } + None +} + +/// Sign the given data with the given validator ID. +/// +/// Returns `Ok(None)` if the private key that correponds to that validator ID is not found in the +/// given keystore. Returns an error if the key could not be used for signing. +pub fn sign( + keystore: &KeystorePtr, + key: &ValidatorId, + data: &[u8], +) -> Result, KeystoreError> { + let signature = keystore + .sr25519_sign(ValidatorId::ID, key.as_ref(), data)? + .map(|sig| sig.into()); + Ok(signature) +} + +/// Find the validator group the given validator index belongs to. +pub fn find_validator_group( + groups: &[Vec], + index: ValidatorIndex, +) -> Option { + groups.iter().enumerate().find_map(|(i, g)| { + if g.contains(&index) { + Some(GroupIndex(i as _)) + } else { + None + } + }) +} + +/// Choose a random subset of `min` elements. +/// But always include `is_priority` elements. +pub fn choose_random_subset bool>(is_priority: F, v: &mut Vec, min: usize) { + choose_random_subset_with_rng(is_priority, v, &mut rand::thread_rng(), min) +} + +/// Choose a random subset of `min` elements using a specific Random Generator `Rng` +/// But always include `is_priority` elements. +pub fn choose_random_subset_with_rng bool, R: rand::Rng>( + is_priority: F, + v: &mut Vec, + rng: &mut R, + min: usize, +) { + use rand::seq::SliceRandom as _; + + // partition the elements into priority first + // the returned index is when non_priority elements start + let i = itertools::partition(v.iter_mut(), is_priority); + + if i >= min || v.len() <= i { + v.truncate(i); + return + } + + v[i..].shuffle(rng); + + v.truncate(min); +} + +/// Returns a `bool` with a probability of `a / b` of being true. +pub fn gen_ratio(a: usize, b: usize) -> bool { + gen_ratio_rng(a, b, &mut rand::thread_rng()) +} + +/// Returns a `bool` with a probability of `a / b` of being true. +pub fn gen_ratio_rng(a: usize, b: usize, rng: &mut R) -> bool { + rng.gen_ratio(a as u32, b as u32) +} + +/// Local validator information +/// +/// It can be created if the local node is a validator in the context of a particular +/// relay chain block. +#[derive(Debug)] +pub struct Validator { + signing_context: SigningContext, + key: ValidatorId, + index: ValidatorIndex, +} + +impl Validator { + /// Get a struct representing this node's validator if this node is in fact a validator in the + /// context of the given block. + pub async fn new(parent: Hash, keystore: KeystorePtr, sender: &mut S) -> Result + where + S: SubsystemSender, + { + // Note: request_validators and request_session_index_for_child do not and cannot + // run concurrently: they both have a mutable handle to the same sender. + // However, each of them returns a oneshot::Receiver, and those are resolved concurrently. + let (validators, session_index) = futures::try_join!( + request_validators(parent, sender).await, + request_session_index_for_child(parent, sender).await, + )?; + + let signing_context = SigningContext { session_index: session_index?, parent_hash: parent }; + + let validators = validators?; + + Self::construct(&validators, signing_context, keystore) + } + + /// Construct a validator instance without performing runtime fetches. + /// + /// This can be useful if external code also needs the same data. + pub fn construct( + validators: &[ValidatorId], + signing_context: SigningContext, + keystore: KeystorePtr, + ) -> Result { + let (key, index) = + signing_key_and_index(validators, &keystore).ok_or(Error::NotAValidator)?; + + Ok(Validator { signing_context, key, index }) + } + + /// Get this validator's id. + pub fn id(&self) -> ValidatorId { + self.key.clone() + } + + /// Get this validator's local index. + pub fn index(&self) -> ValidatorIndex { + self.index + } + + /// Get the current signing context. + pub fn signing_context(&self) -> &SigningContext { + &self.signing_context + } + + /// Sign a payload with this validator + pub fn sign, RealPayload: Encode>( + &self, + keystore: KeystorePtr, + payload: Payload, + ) -> Result>, KeystoreError> { + Signed::sign(&keystore, payload, &self.signing_context, self.index, &self.key) + } +} diff --git a/polkadot/node/subsystem-util/src/nesting_sender.rs b/polkadot/node/subsystem-util/src/nesting_sender.rs new file mode 100644 index 0000000000000000000000000000000000000000..5d80dbf781019498b112b62de0cfc94cd1d04f5c --- /dev/null +++ b/polkadot/node/subsystem-util/src/nesting_sender.rs @@ -0,0 +1,208 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! ## Background +//! +//! Writing concurrent and even multithreaded by default is inconvenient and slow: No references +//! hence lots of needless cloning and data duplication, locks, mutexes, ... We should reach +//! for concurrency and parallelism when there is an actual need, not just because we can and it is +//! reasonably safe in Rust. +//! +//! I very much agree with many points in this blog post for example: +//! +//! +//! +//! Another very good post by Pierre (Tomaka): +//! +//! +//! +//! ## Architecture +//! +//! This module helps with this in part. It does not break the multithreaded by default approach, +//! but it breaks the `spawn everything` approach. So once you `spawn` you will still be +//! multithreaded by default, despite that for most tasks we spawn (which just wait for network or +//! some message to arrive), that is very much pointless and needless overhead. You will just spawn +//! less in the first place. +//! +//! By default your code is single threaded, except when actually needed: +//! - need to wait for long running synchronous IO (a threaded runtime is actually useful here) +//! - need to wait for some async event (message to arrive) +//! - need to do some hefty CPU bound processing (a thread is required here as well) +//! +//! and it is not acceptable to block the main task for waiting for the result, because we actually +//! really have other things to do or at least need to stay responsive just in case. +//! +//! With the types and traits in this module you can achieve exactly that: You write modules which +//! just execute logic and can call into the functions of other modules - yes we are calling normal +//! functions. For the case a module you are calling into requires an occasional background task, +//! you provide it with a `NestingSender` that it can pass to any spawned +//! tasks. +//! +//! This way you don't have to spawn a task for each module just for it to be able to handle +//! asynchronous events. The module relies on the using/enclosing code/module to forward it any +//! asynchronous messages in a structured way. +//! +//! What makes this architecture nice is the separation of concerns - at the top you only have to +//! provide a sender and dispatch received messages to the root module - it is completely +//! irrelevant how complex that module is, it might consist of child modules also having the need +//! to spawn and receive messages, which in turn do the same, still the root logic stays unchanged. +//! Everything is isolated to the level where it belongs, while we still keep a single task scope +//! in all non blocking/not CPU intensive parts, which allows us to share data via references for +//! example. +//! +//! Because the wrapping is optional and transparent to the lower modules, each module can also be +//! used at the top directly without any wrapping, e.g. for standalone use or for testing purposes. +//! +//! Checkout the documentation of [`NestingSender`][nesting_sender::NestingSender] below for a basic +//! usage example. For a real world usage I would like to point you to the dispute-distribution +//! subsystem which makes use of this architecture. +//! +//! ## Limitations +//! +//! Nothing is ever for free of course: Each level adds an indirect function call to message +//! sending. which should be cheap enough for most applications, but something to keep in mind. In +//! particular we avoided the use of of async traits, which would have required memory allocations +//! on each send. Also cloning of [`NestingSender`][nesting_sender::NestingSender] is more +//! expensive than cloning a plain mpsc::Sender, the overhead should be negligible though. +//! +//! Further limitations: Because everything is routed to the same channel, it is not possible with +//! this approach to put back pressure on only a single source (as all are the same). If a module +//! has a task that requires this, it indeed has to spawn a long running task which can do the +//! back-pressure on that message source or we make it its own subsystem. This is just one of the +//! situations that justifies the complexity of asynchrony. + +use std::{convert::identity, sync::Arc}; + +use futures::{channel::mpsc, SinkExt}; + +/// A message sender that supports sending nested messages. +/// +/// This sender wraps an `mpsc::Sender` and a conversion function for converting given messages of +/// type `Mnested` to the message type actually supported by the mpsc (`M`). +/// +/// Example: +/// +/// ```rust +/// # use polkadot_node_subsystem_util::nesting_sender::NestingSender; +/// +/// enum RootMessage { +/// Child1Message(ChildMessage), +/// Child2Message(OtherChildMessage), +/// SomeOwnMessage, +/// } +/// +/// enum ChildMessage { +/// TaskFinished(u32), +/// } +/// +/// enum OtherChildMessage { +/// QueryResult(bool), +/// } +/// +/// // We would then pass in a `NestingSender` to our child module of the following type: +/// type ChildSender = NestingSender; +/// +/// // Types in the child module can (and should) be generic over the root type: +/// struct ChildState { +/// tx: NestingSender, +/// } +/// +/// +/// // Create the root message sender: +/// +/// let (root_sender, receiver) = NestingSender::new_root(1); +/// // Get a sender for the child module based on that root sender: +/// let child_sender = NestingSender::new(root_sender.clone(), RootMessage::Child1Message); +/// // pass `child_sender` to child module ... +/// ``` +/// +/// `ChildMessage` could itself have a constructor with messages of a child of its own and can use +/// `NestingSender::new` with its own sender and a conversion function to provide a further nested +/// sender, suitable for the child module. +pub struct NestingSender { + sender: mpsc::Sender, + conversion: Arc M + 'static + Send + Sync>, +} + +impl NestingSender +where + M: 'static, +{ + /// Create a new "root" sender. + /// + /// This is a sender that directly passes messages to the internal mpsc. + /// + /// Params: The channel size of the created mpsc. + /// Returns: The newly constructed `NestingSender` and the corresponding mpsc receiver. + pub fn new_root(channel_size: usize) -> (Self, mpsc::Receiver) { + let (sender, receiver) = mpsc::channel(channel_size); + let s = Self { sender, conversion: Arc::new(identity) }; + (s, receiver) + } +} + +impl NestingSender +where + M: 'static, + Mnested: 'static, +{ + /// Create a new `NestingSender` which wraps a given "parent" sender. + /// + /// By passing in a necessary conversion from `Mnested` to `Mparent` (the `Mnested` of the + /// parent sender), we can construct a derived `NestingSender` from a + /// `NestingSender`. + /// + /// Resulting sender does the following conversion: + /// + /// ```text + /// Mnested -> Mparent -> M + /// Inputs: + /// F(Mparent) -> M (via parent) + /// F(Mnested) -> Mparent (via child_conversion) + /// Result: F(Mnested) -> M + /// ``` + pub fn new( + parent: NestingSender, + child_conversion: fn(Mnested) -> Mparent, + ) -> Self + where + Mparent: 'static, + { + let NestingSender { sender, conversion } = parent; + Self { sender, conversion: Arc::new(move |x| conversion(child_conversion(x))) } + } + + /// Send a message via the underlying mpsc. + /// + /// Necessary conversion is accomplished. + pub async fn send_message(&mut self, m: Mnested) -> Result<(), mpsc::SendError> { + // Flushing on an mpsc means to wait for the receiver to pick up the data - we don't want + // to wait for that. + self.sender.feed((self.conversion)(m)).await + } +} + +// Helper traits and implementations: + +impl Clone for NestingSender +where + M: 'static, + Mnested: 'static, +{ + fn clone(&self) -> Self { + Self { sender: self.sender.clone(), conversion: self.conversion.clone() } + } +} diff --git a/polkadot/node/subsystem-util/src/reputation.rs b/polkadot/node/subsystem-util/src/reputation.rs new file mode 100644 index 0000000000000000000000000000000000000000..89e3eb64df9bd8d47a8e9aabb701c8bca504f140 --- /dev/null +++ b/polkadot/node/subsystem-util/src/reputation.rs @@ -0,0 +1,117 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A utility abstraction to collect and send reputation changes. + +use polkadot_node_network_protocol::{PeerId, UnifiedReputationChange}; +use polkadot_node_subsystem::{ + messages::{NetworkBridgeTxMessage, ReportPeerMessage}, + overseer, +}; +use std::{collections::HashMap, time::Duration}; + +/// Default delay for sending reputation changes +pub const REPUTATION_CHANGE_INTERVAL: Duration = Duration::from_secs(30); + +type BatchReputationChange = HashMap; + +/// Collects reputation changes and sends them in one batch to relieve network channels +#[derive(Debug, Clone)] +pub struct ReputationAggregator { + send_immediately_if: fn(UnifiedReputationChange) -> bool, + by_peer: Option, +} + +impl Default for ReputationAggregator { + fn default() -> Self { + Self::new(|rep| matches!(rep, UnifiedReputationChange::Malicious(_))) + } +} + +impl ReputationAggregator { + /// New `ReputationAggregator` + /// + /// # Arguments + /// + /// * `send_immediately_if` - A function, takes `UnifiedReputationChange`, + /// results shows if we need to send the changes right away. + /// By default, it is used for sending `UnifiedReputationChange::Malicious` changes immediately + /// and for testing. + pub fn new(send_immediately_if: fn(UnifiedReputationChange) -> bool) -> Self { + Self { by_peer: Default::default(), send_immediately_if } + } + + /// Sends collected reputation changes in a batch, + /// removing them from inner state + pub async fn send( + &mut self, + sender: &mut impl overseer::SubsystemSender, + ) { + if let Some(by_peer) = self.by_peer.take() { + sender + .send_message(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Batch(by_peer))) + .await; + } + } + + /// Adds reputation change to inner state + /// or sends it right away if the change is dangerous + pub async fn modify( + &mut self, + sender: &mut impl overseer::SubsystemSender, + peer_id: PeerId, + rep: UnifiedReputationChange, + ) { + if (self.send_immediately_if)(rep) { + self.single_send(sender, peer_id, rep).await; + } else { + self.add(peer_id, rep); + } + } + + async fn single_send( + &self, + sender: &mut impl overseer::SubsystemSender, + peer_id: PeerId, + rep: UnifiedReputationChange, + ) { + sender + .send_message(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single( + peer_id, + rep.into(), + ))) + .await; + } + + fn add(&mut self, peer_id: PeerId, rep: UnifiedReputationChange) { + if self.by_peer.is_none() { + self.by_peer = Some(HashMap::new()); + } + if let Some(ref mut by_peer) = self.by_peer { + add_reputation(by_peer, peer_id, rep) + } + } +} + +/// Add a reputation change to an existing collection. +pub fn add_reputation( + acc: &mut BatchReputationChange, + peer_id: PeerId, + rep: UnifiedReputationChange, +) { + let cost = rep.cost_or_benefit(); + acc.entry(peer_id).and_modify(|v| *v = v.saturating_add(cost)).or_insert(cost); +} diff --git a/polkadot/node/subsystem-util/src/runtime/error.rs b/polkadot/node/subsystem-util/src/runtime/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..db3eacd68514124170bbdb972cc1e1cacbd03e00 --- /dev/null +++ b/polkadot/node/subsystem-util/src/runtime/error.rs @@ -0,0 +1,54 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +// + +//! Error handling related code and Error/Result definitions. + +use futures::channel::oneshot; + +use polkadot_node_subsystem::errors::RuntimeApiError; +use polkadot_primitives::SessionIndex; + +#[allow(missing_docs)] +#[fatality::fatality(splitable)] +pub enum Error { + /// Runtime API subsystem is down, which means we're shutting down. + #[fatal] + #[error("Runtime request got canceled")] + RuntimeRequestCanceled(oneshot::Canceled), + + /// Some request to the runtime failed. + /// For example if we prune a block we're requesting info about. + #[error("Runtime API error {0}")] + RuntimeRequest(RuntimeApiError), + + /// We tried fetching a session info which was not available. + #[error("There was no session with the given index {0}")] + NoSuchSession(SessionIndex), +} + +pub type Result = std::result::Result; + +/// Receive a response from a runtime request and convert errors. +pub(crate) async fn recv_runtime( + r: oneshot::Receiver>, +) -> Result { + let result = r + .await + .map_err(FatalError::RuntimeRequestCanceled)? + .map_err(JfyiError::RuntimeRequest)?; + Ok(result) +} diff --git a/polkadot/node/subsystem-util/src/runtime/mod.rs b/polkadot/node/subsystem-util/src/runtime/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..1f5641e3ea956c0379c79a2c686144336ff95030 --- /dev/null +++ b/polkadot/node/subsystem-util/src/runtime/mod.rs @@ -0,0 +1,458 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Convenient interface to runtime information. + +use std::num::NonZeroUsize; + +use lru::LruCache; + +use parity_scale_codec::Encode; +use sp_application_crypto::AppCrypto; +use sp_core::crypto::ByteArray; +use sp_keystore::{Keystore, KeystorePtr}; + +use polkadot_node_subsystem::{ + errors::RuntimeApiError, messages::RuntimeApiMessage, overseer, SubsystemSender, +}; +use polkadot_primitives::{ + vstaging, CandidateEvent, CandidateHash, CoreState, EncodeAs, GroupIndex, GroupRotationInfo, + Hash, IndexedVec, OccupiedCore, ScrapedOnChainVotes, SessionIndex, SessionInfo, Signed, + SigningContext, UncheckedSigned, ValidationCode, ValidationCodeHash, ValidatorId, + ValidatorIndex, +}; + +use crate::{ + request_availability_cores, request_candidate_events, request_key_ownership_proof, + request_on_chain_votes, request_session_index_for_child, request_session_info, + request_staging_async_backing_params, request_submit_report_dispute_lost, + request_unapplied_slashes, request_validation_code_by_hash, request_validator_groups, +}; + +/// Errors that can happen on runtime fetches. +mod error; + +use error::{recv_runtime, Result}; +pub use error::{Error, FatalError, JfyiError}; + +const LOG_TARGET: &'static str = "parachain::runtime-info"; + +/// Configuration for construction a `RuntimeInfo`. +pub struct Config { + /// Needed for retrieval of `ValidatorInfo` + /// + /// Pass `None` if you are not interested. + pub keystore: Option, + + /// How many sessions should we keep in the cache? + pub session_cache_lru_size: NonZeroUsize, +} + +/// Caching of session info. +/// +/// It should be ensured that a cached session stays live in the cache as long as we might need it. +pub struct RuntimeInfo { + /// Get the session index for a given relay parent. + /// + /// We query this up to a 100 times per block, so caching it here without roundtrips over the + /// overseer seems sensible. + session_index_cache: LruCache, + + /// Look up cached sessions by `SessionIndex`. + session_info_cache: LruCache, + + /// Key store for determining whether we are a validator and what `ValidatorIndex` we have. + keystore: Option, +} + +/// `SessionInfo` with additional useful data for validator nodes. +pub struct ExtendedSessionInfo { + /// Actual session info as fetched from the runtime. + pub session_info: SessionInfo, + /// Contains useful information about ourselves, in case this node is a validator. + pub validator_info: ValidatorInfo, +} + +/// Information about ourselves, in case we are an `Authority`. +/// +/// This data is derived from the `SessionInfo` and our key as found in the keystore. +pub struct ValidatorInfo { + /// The index this very validator has in `SessionInfo` vectors, if any. + pub our_index: Option, + /// The group we belong to, if any. + pub our_group: Option, +} + +impl Default for Config { + fn default() -> Self { + Self { + keystore: None, + // Usually we need to cache the current and the last session. + session_cache_lru_size: NonZeroUsize::new(2).expect("2 is larger than 0; qed"), + } + } +} + +impl RuntimeInfo { + /// Create a new `RuntimeInfo` for convenient runtime fetches. + pub fn new(keystore: Option) -> Self { + Self::new_with_config(Config { keystore, ..Default::default() }) + } + + /// Create with more elaborate configuration options. + pub fn new_with_config(cfg: Config) -> Self { + Self { + session_index_cache: LruCache::new( + cfg.session_cache_lru_size + .max(NonZeroUsize::new(10).expect("10 is larger than 0; qed")), + ), + session_info_cache: LruCache::new(cfg.session_cache_lru_size), + keystore: cfg.keystore, + } + } + + /// Returns the session index expected at any child of the `parent` block. + /// This does not return the session index for the `parent` block. + pub async fn get_session_index_for_child( + &mut self, + sender: &mut Sender, + parent: Hash, + ) -> Result + where + Sender: SubsystemSender, + { + match self.session_index_cache.get(&parent) { + Some(index) => Ok(*index), + None => { + let index = + recv_runtime(request_session_index_for_child(parent, sender).await).await?; + self.session_index_cache.put(parent, index); + Ok(index) + }, + } + } + + /// Get `ExtendedSessionInfo` by relay parent hash. + pub async fn get_session_info<'a, Sender>( + &'a mut self, + sender: &mut Sender, + relay_parent: Hash, + ) -> Result<&'a ExtendedSessionInfo> + where + Sender: SubsystemSender, + { + let session_index = self.get_session_index_for_child(sender, relay_parent).await?; + + self.get_session_info_by_index(sender, relay_parent, session_index).await + } + + /// Get `ExtendedSessionInfo` by session index. + /// + /// `request_session_info` still requires the parent to be passed in, so we take the parent + /// in addition to the `SessionIndex`. + pub async fn get_session_info_by_index<'a, Sender>( + &'a mut self, + sender: &mut Sender, + parent: Hash, + session_index: SessionIndex, + ) -> Result<&'a ExtendedSessionInfo> + where + Sender: SubsystemSender, + { + if !self.session_info_cache.contains(&session_index) { + let session_info = + recv_runtime(request_session_info(parent, session_index, sender).await) + .await? + .ok_or(JfyiError::NoSuchSession(session_index))?; + let validator_info = self.get_validator_info(&session_info)?; + + let full_info = ExtendedSessionInfo { session_info, validator_info }; + + self.session_info_cache.put(session_index, full_info); + } + Ok(self + .session_info_cache + .get(&session_index) + .expect("We just put the value there. qed.")) + } + + /// Convenience function for checking the signature of something signed. + pub async fn check_signature( + &mut self, + sender: &mut Sender, + relay_parent: Hash, + signed: UncheckedSigned, + ) -> Result< + std::result::Result, UncheckedSigned>, + > + where + Sender: SubsystemSender, + Payload: EncodeAs + Clone, + RealPayload: Encode + Clone, + { + let session_index = self.get_session_index_for_child(sender, relay_parent).await?; + let info = self.get_session_info_by_index(sender, relay_parent, session_index).await?; + Ok(check_signature(session_index, &info.session_info, relay_parent, signed)) + } + + /// Build `ValidatorInfo` for the current session. + /// + /// + /// Returns: `None` if not a parachain validator. + fn get_validator_info(&self, session_info: &SessionInfo) -> Result { + if let Some(our_index) = self.get_our_index(&session_info.validators) { + // Get our group index: + let our_group = + session_info.validator_groups.iter().enumerate().find_map(|(i, g)| { + g.iter().find_map(|v| { + if *v == our_index { + Some(GroupIndex(i as u32)) + } else { + None + } + }) + }); + let info = ValidatorInfo { our_index: Some(our_index), our_group }; + return Ok(info) + } + return Ok(ValidatorInfo { our_index: None, our_group: None }) + } + + /// Get our `ValidatorIndex`. + /// + /// Returns: None if we are not a validator. + fn get_our_index( + &self, + validators: &IndexedVec, + ) -> Option { + let keystore = self.keystore.as_ref()?; + for (i, v) in validators.iter().enumerate() { + if Keystore::has_keys(&**keystore, &[(v.to_raw_vec(), ValidatorId::ID)]) { + return Some(ValidatorIndex(i as u32)) + } + } + None + } +} + +/// Convenience function for quickly checking the signature on signed data. +pub fn check_signature( + session_index: SessionIndex, + session_info: &SessionInfo, + relay_parent: Hash, + signed: UncheckedSigned, +) -> std::result::Result, UncheckedSigned> +where + Payload: EncodeAs + Clone, + RealPayload: Encode + Clone, +{ + let signing_context = SigningContext { session_index, parent_hash: relay_parent }; + + session_info + .validators + .get(signed.unchecked_validator_index()) + .ok_or_else(|| signed.clone()) + .and_then(|v| signed.try_into_checked(&signing_context, v)) +} + +/// Request availability cores from the runtime. +pub async fn get_availability_cores( + sender: &mut Sender, + relay_parent: Hash, +) -> Result> +where + Sender: overseer::SubsystemSender, +{ + recv_runtime(request_availability_cores(relay_parent, sender).await).await +} + +/// Variant of `request_availability_cores` that only returns occupied ones. +pub async fn get_occupied_cores( + sender: &mut Sender, + relay_parent: Hash, +) -> Result> +where + Sender: overseer::SubsystemSender, +{ + let cores = get_availability_cores(sender, relay_parent).await?; + + Ok(cores + .into_iter() + .filter_map(|core_state| { + if let CoreState::Occupied(occupied) = core_state { + Some(occupied) + } else { + None + } + }) + .collect()) +} + +/// Get group rotation info based on the given `relay_parent`. +pub async fn get_group_rotation_info( + sender: &mut Sender, + relay_parent: Hash, +) -> Result +where + Sender: overseer::SubsystemSender, +{ + // We drop `groups` here as we don't need them, because of `RuntimeInfo`. Ideally we would not + // fetch them in the first place. + let (_, info) = recv_runtime(request_validator_groups(relay_parent, sender).await).await?; + Ok(info) +} + +/// Get `CandidateEvent`s for the given `relay_parent`. +pub async fn get_candidate_events( + sender: &mut Sender, + relay_parent: Hash, +) -> Result> +where + Sender: SubsystemSender, +{ + recv_runtime(request_candidate_events(relay_parent, sender).await).await +} + +/// Get on chain votes. +pub async fn get_on_chain_votes( + sender: &mut Sender, + relay_parent: Hash, +) -> Result> +where + Sender: SubsystemSender, +{ + recv_runtime(request_on_chain_votes(relay_parent, sender).await).await +} + +/// Fetch `ValidationCode` by hash from the runtime. +pub async fn get_validation_code_by_hash( + sender: &mut Sender, + relay_parent: Hash, + validation_code_hash: ValidationCodeHash, +) -> Result> +where + Sender: SubsystemSender, +{ + recv_runtime(request_validation_code_by_hash(relay_parent, validation_code_hash, sender).await) + .await +} + +/// Fetch a list of `PendingSlashes` from the runtime. +pub async fn get_unapplied_slashes( + sender: &mut Sender, + relay_parent: Hash, +) -> Result> +where + Sender: SubsystemSender, +{ + recv_runtime(request_unapplied_slashes(relay_parent, sender).await).await +} + +/// Generate validator key ownership proof. +/// +/// Note: The choice of `relay_parent` is important here, it needs to match +/// the desired session index of the validator set in question. +pub async fn key_ownership_proof( + sender: &mut Sender, + relay_parent: Hash, + validator_id: ValidatorId, +) -> Result> +where + Sender: SubsystemSender, +{ + recv_runtime(request_key_ownership_proof(relay_parent, validator_id, sender).await).await +} + +/// Submit a past-session dispute slashing report. +pub async fn submit_report_dispute_lost( + sender: &mut Sender, + relay_parent: Hash, + dispute_proof: vstaging::slashing::DisputeProof, + key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof, +) -> Result> +where + Sender: SubsystemSender, +{ + recv_runtime( + request_submit_report_dispute_lost( + relay_parent, + dispute_proof, + key_ownership_proof, + sender, + ) + .await, + ) + .await +} + +/// Prospective parachains mode of a relay parent. Defined by +/// the Runtime API version. +/// +/// Needed for the period of transition to asynchronous backing. +#[derive(Debug, Copy, Clone)] +pub enum ProspectiveParachainsMode { + /// Runtime API without support of `async_backing_params`: no prospective parachains. + Disabled, + /// vstaging runtime API: prospective parachains. + Enabled { + /// The maximum number of para blocks between the para head in a relay parent + /// and a new candidate. Restricts nodes from building arbitrary long chains + /// and spamming other validators. + max_candidate_depth: usize, + /// How many ancestors of a relay parent are allowed to build candidates on top + /// of. + allowed_ancestry_len: usize, + }, +} + +impl ProspectiveParachainsMode { + /// Returns `true` if mode is enabled, `false` otherwise. + pub fn is_enabled(&self) -> bool { + matches!(self, ProspectiveParachainsMode::Enabled { .. }) + } +} + +/// Requests prospective parachains mode for a given relay parent based on +/// the Runtime API version. +pub async fn prospective_parachains_mode( + sender: &mut Sender, + relay_parent: Hash, +) -> Result +where + Sender: SubsystemSender, +{ + let result = + recv_runtime(request_staging_async_backing_params(relay_parent, sender).await).await; + + if let Err(error::Error::RuntimeRequest(RuntimeApiError::NotSupported { runtime_api_name })) = + &result + { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + "Prospective parachains are disabled, {} is not supported by the current Runtime API", + runtime_api_name, + ); + + Ok(ProspectiveParachainsMode::Disabled) + } else { + let vstaging::AsyncBackingParams { max_candidate_depth, allowed_ancestry_len } = result?; + Ok(ProspectiveParachainsMode::Enabled { + max_candidate_depth: max_candidate_depth as _, + allowed_ancestry_len: allowed_ancestry_len as _, + }) + } +} diff --git a/polkadot/node/subsystem-util/src/tests.rs b/polkadot/node/subsystem-util/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..9ade95d4e894ca57dbf0e1da30bf628bc552d136 --- /dev/null +++ b/polkadot/node/subsystem-util/src/tests.rs @@ -0,0 +1,96 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![cfg(test)] + +use super::*; +use executor::block_on; +use futures::{channel::mpsc, executor, FutureExt, SinkExt, StreamExt}; +use polkadot_primitives_test_helpers::AlwaysZeroRng; +use std::{ + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, + time::Duration, +}; + +#[test] +fn tick_tack_metronome() { + let n = Arc::new(AtomicUsize::default()); + + let (tick, mut block) = mpsc::unbounded(); + + let metronome = { + let n = n.clone(); + let stream = Metronome::new(Duration::from_millis(137_u64)); + stream + .for_each(move |_res| { + let _ = n.fetch_add(1, Ordering::Relaxed); + let mut tick = tick.clone(); + async move { + tick.send(()).await.expect("Test helper channel works. qed"); + } + }) + .fuse() + }; + + let f2 = async move { + block.next().await; + assert_eq!(n.load(Ordering::Relaxed), 1_usize); + block.next().await; + assert_eq!(n.load(Ordering::Relaxed), 2_usize); + block.next().await; + assert_eq!(n.load(Ordering::Relaxed), 3_usize); + block.next().await; + assert_eq!(n.load(Ordering::Relaxed), 4_usize); + } + .fuse(); + + futures::pin_mut!(f2); + futures::pin_mut!(metronome); + + block_on(async move { + // futures::join!(metronome, f2) + futures::select!( + _ = metronome => unreachable!("Metronome never stops. qed"), + _ = f2 => (), + ) + }); +} + +#[test] +fn subset_generation_check() { + let mut values = (0_u8..=25).collect::>(); + // 12 even numbers exist + choose_random_subset::(|v| v & 0x01 == 0, &mut values, 12); + values.sort(); + for (idx, v) in dbg!(values).into_iter().enumerate() { + assert_eq!(v as usize, idx * 2); + } +} + +#[test] +fn subset_predefined_generation_check() { + let mut values = (0_u8..=25).collect::>(); + choose_random_subset_with_rng::(|_| false, &mut values, &mut AlwaysZeroRng, 12); + assert_eq!(values.len(), 12); + for (idx, v) in dbg!(values).into_iter().enumerate() { + // Since shuffle actually shuffles the indexes from 1..len, then + // our PRG that returns zeroes will shuffle 0 and 1, 1 and 2, ... len-2 and len-1 + assert_eq!(v as usize, idx + 1); + } +} diff --git a/polkadot/node/subsystem/Cargo.toml b/polkadot/node/subsystem/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..368a194091f53c7cfe9b9032d1d1a731348b513f --- /dev/null +++ b/polkadot/node/subsystem/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "polkadot-node-subsystem" +description = "Subsystem traits and message definitions and the generated overseer" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +polkadot-overseer = { path = "../overseer" } +polkadot-node-subsystem-types = { path = "../subsystem-types" } +polkadot-node-jaeger = { path = "../jaeger" } diff --git a/polkadot/node/subsystem/src/lib.rs b/polkadot/node/subsystem/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..df379f2d97b6ab9e2ac29608d64e145638e559b9 --- /dev/null +++ b/polkadot/node/subsystem/src/lib.rs @@ -0,0 +1,59 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Subsystem accumulation. +//! +//! Node-side types and generated overseer. + +#![deny(missing_docs)] +#![deny(unused_crate_dependencies)] + +pub use jaeger::*; +pub use polkadot_node_jaeger as jaeger; + +pub use polkadot_overseer::{self as overseer, *}; + +pub use polkadot_node_subsystem_types::{ + errors::{self, *}, + ActivatedLeaf, LeafStatus, +}; + +/// Re-export of all messages type, including the wrapper type. +pub mod messages { + pub use super::overseer::AllMessages; + // generated, empty message types + pub use super::overseer::messages::*; + // deliberately defined messages + pub use polkadot_node_subsystem_types::messages::*; +} + +/// A `Result` type that wraps [`SubsystemError`]. +/// +/// [`SubsystemError`]: struct.SubsystemError.html +pub type SubsystemResult = Result; + +// Simplify usage without having to do large scale modifications of all +// subsystems at once. + +/// Specialized message type originating from the overseer. +pub type FromOrchestra = polkadot_overseer::gen::FromOrchestra; + +/// Specialized subsystem instance type of subsystems consuming a particular message type. +pub type SubsystemInstance = + polkadot_overseer::gen::SubsystemInstance; + +/// Spawned subsystem. +pub type SpawnedSubsystem = polkadot_overseer::gen::SpawnedSubsystem; diff --git a/polkadot/node/test/client/Cargo.toml b/polkadot/node/test/client/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..aac46bd4b8fc93b79153007782ddc0fa70620407 --- /dev/null +++ b/polkadot/node/test/client/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "polkadot-test-client" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } + +# Polkadot dependencies +polkadot-test-runtime = { path = "../../../runtime/test-runtime" } +polkadot-test-service = { path = "../service" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-node-subsystem = { path = "../../subsystem" } + +# Substrate dependencies +substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-offchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[dev-dependencies] +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures = "0.3.21" + +[features] +runtime-benchmarks=["polkadot-test-runtime/runtime-benchmarks"] diff --git a/polkadot/node/test/client/src/block_builder.rs b/polkadot/node/test/client/src/block_builder.rs new file mode 100644 index 0000000000000000000000000000000000000000..0987cef55c1f1a2a377fdf62a947efb70eab4ef0 --- /dev/null +++ b/polkadot/node/test/client/src/block_builder.rs @@ -0,0 +1,159 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::{Client, FullBackend}; +use parity_scale_codec::{Decode, Encode}; +use polkadot_primitives::{Block, InherentData as ParachainsInherentData}; +use polkadot_test_runtime::UncheckedExtrinsic; +use polkadot_test_service::GetLastTimestamp; +use sc_block_builder::{BlockBuilder, BlockBuilderProvider}; +use sp_api::ProvideRuntimeApi; +use sp_consensus_babe::{ + digests::{PreDigest, SecondaryPlainPreDigest}, + BABE_ENGINE_ID, +}; +use sp_runtime::{traits::Block as BlockT, Digest, DigestItem}; +use sp_state_machine::BasicExternalities; + +/// An extension for the test client to initialize a Polkadot specific block builder. +pub trait InitPolkadotBlockBuilder { + /// Init a Polkadot specific block builder that works for the test runtime. + /// + /// This will automatically create and push the inherents for you to make the block valid for + /// the test runtime. + fn init_polkadot_block_builder( + &self, + ) -> sc_block_builder::BlockBuilder; + + /// Init a Polkadot specific block builder at a specific block that works for the test runtime. + /// + /// Same as [`InitPolkadotBlockBuilder::init_polkadot_block_builder`] besides that it takes a + /// [`BlockId`] to say which should be the parent block of the block that is being build. + fn init_polkadot_block_builder_at( + &self, + hash: ::Hash, + ) -> sc_block_builder::BlockBuilder; +} + +impl InitPolkadotBlockBuilder for Client { + fn init_polkadot_block_builder(&self) -> BlockBuilder { + let chain_info = self.chain_info(); + self.init_polkadot_block_builder_at(chain_info.best_hash) + } + + fn init_polkadot_block_builder_at( + &self, + hash: ::Hash, + ) -> BlockBuilder { + let last_timestamp = + self.runtime_api().get_last_timestamp(hash).expect("Get last timestamp"); + + // `MinimumPeriod` is a storage parameter type that requires externalities to access the + // value. + let minimum_period = BasicExternalities::new_empty() + .execute_with(|| polkadot_test_runtime::MinimumPeriod::get()); + + let timestamp = if last_timestamp == 0 { + std::time::SystemTime::now() + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .expect("Time is always after UNIX_EPOCH; qed") + .as_millis() as u64 + } else { + last_timestamp + minimum_period + }; + + // `SlotDuration` is a storage parameter type that requires externalities to access the + // value. + let slot_duration = BasicExternalities::new_empty() + .execute_with(|| polkadot_test_runtime::SlotDuration::get()); + + let slot = (timestamp / slot_duration).into(); + + let digest = Digest { + logs: vec![DigestItem::PreRuntime( + BABE_ENGINE_ID, + PreDigest::SecondaryPlain(SecondaryPlainPreDigest { slot, authority_index: 42 }) + .encode(), + )], + }; + + let mut block_builder = self + .new_block_at(hash, digest, false) + .expect("Creates new block builder for test runtime"); + + let mut inherent_data = sp_inherents::InherentData::new(); + + inherent_data + .put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) + .expect("Put timestamp inherent data"); + + let parent_header = self + .header(hash) + .expect("Get the parent block header") + .expect("The target block header must exist"); + + let parachains_inherent_data = ParachainsInherentData { + bitfields: Vec::new(), + backed_candidates: Vec::new(), + disputes: Vec::new(), + parent_header, + }; + + inherent_data + .put_data( + polkadot_primitives::PARACHAINS_INHERENT_IDENTIFIER, + ¶chains_inherent_data, + ) + .expect("Put parachains inherent data"); + + let inherents = block_builder.create_inherents(inherent_data).expect("Creates inherents"); + + inherents + .into_iter() + .for_each(|ext| block_builder.push(ext).expect("Pushes inherent")); + + block_builder + } +} + +/// Polkadot specific extensions for the [`BlockBuilder`]. +pub trait BlockBuilderExt { + /// Push a Polkadot test runtime specific extrinsic to the block. + /// + /// This will internally use the [`BlockBuilder::push`] method, but this method expects a opaque + /// extrinsic. So, we provide this wrapper which converts a test runtime specific extrinsic to a + /// opaque extrinsic and pushes it to the block. + /// + /// Returns the result of the application of the extrinsic. + fn push_polkadot_extrinsic( + &mut self, + ext: UncheckedExtrinsic, + ) -> Result<(), sp_blockchain::Error>; +} + +impl BlockBuilderExt for BlockBuilder<'_, Block, Client, FullBackend> { + fn push_polkadot_extrinsic( + &mut self, + ext: UncheckedExtrinsic, + ) -> Result<(), sp_blockchain::Error> { + let encoded = ext.encode(); + self.push( + Decode::decode(&mut &encoded[..]).expect( + "The runtime specific extrinsic always decodes to an opaque extrinsic; qed", + ), + ) + } +} diff --git a/polkadot/node/test/client/src/lib.rs b/polkadot/node/test/client/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..5d97ffcdf1da4d4ec42ead64f9b8e78d98227368 --- /dev/null +++ b/polkadot/node/test/client/src/lib.rs @@ -0,0 +1,132 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A Polkadot test client. +//! +//! This test client is using the Polkadot test runtime. + +mod block_builder; + +use polkadot_primitives::Block; +use sp_runtime::BuildStorage; +use std::sync::Arc; + +pub use block_builder::*; +pub use polkadot_test_runtime as runtime; +pub use polkadot_test_service::{ + construct_extrinsic, construct_transfer_extrinsic, Client, FullBackend, +}; +pub use substrate_test_client::*; + +/// Test client executor. +pub type Executor = client::LocalCallExecutor< + Block, + FullBackend, + WasmExecutor<(sp_io::SubstrateHostFunctions, frame_benchmarking::benchmarking::HostFunctions)>, +>; + +/// Test client builder for Polkadot. +pub type TestClientBuilder = + substrate_test_client::TestClientBuilder; + +/// `LongestChain` type for the test runtime/client. +pub type LongestChain = sc_consensus::LongestChain; + +/// Parameters of test-client builder with test-runtime. +#[derive(Default)] +pub struct GenesisParameters; + +impl substrate_test_client::GenesisInit for GenesisParameters { + fn genesis_storage(&self) -> Storage { + polkadot_test_service::chain_spec::polkadot_local_testnet_genesis() + .build_storage() + .expect("Builds test runtime genesis storage") + } +} + +/// A `test-runtime` extensions to `TestClientBuilder`. +pub trait TestClientBuilderExt: Sized { + /// Build the test client. + fn build(self) -> Client { + self.build_with_longest_chain().0 + } + + /// Build the test client and longest chain selector. + fn build_with_longest_chain(self) -> (Client, LongestChain); +} + +impl TestClientBuilderExt for TestClientBuilder { + fn build_with_longest_chain(self) -> (Client, LongestChain) { + let executor = WasmExecutor::builder().build(); + let executor = client::LocalCallExecutor::new( + self.backend().clone(), + executor.clone(), + Default::default(), + ExecutionExtensions::new(Default::default(), Arc::new(executor)), + ) + .unwrap(); + + self.build_with_executor(executor) + } +} + +/// A `TestClientBuilder` with default backend and executor. +pub trait DefaultTestClientBuilderExt: Sized { + /// Create new `TestClientBuilder` + fn new() -> Self; +} + +impl DefaultTestClientBuilderExt for TestClientBuilder { + fn new() -> Self { + Self::with_default_backend() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use sp_consensus::BlockOrigin; + + #[test] + fn ensure_test_client_can_build_and_import_block() { + let mut client = TestClientBuilder::new().build(); + + let block_builder = client.init_polkadot_block_builder(); + let block = block_builder.build().expect("Finalizes the block").block; + + futures::executor::block_on(client.import(BlockOrigin::Own, block)) + .expect("Imports the block"); + } + + #[test] + fn ensure_test_client_can_push_extrinsic() { + let mut client = TestClientBuilder::new().build(); + + let transfer = construct_transfer_extrinsic( + &client, + sp_keyring::Sr25519Keyring::Alice, + sp_keyring::Sr25519Keyring::Bob, + 1000, + ); + let mut block_builder = client.init_polkadot_block_builder(); + block_builder.push_polkadot_extrinsic(transfer).expect("Pushes extrinsic"); + + let block = block_builder.build().expect("Finalizes the block").block; + + futures::executor::block_on(client.import(BlockOrigin::Own, block)) + .expect("Imports the block"); + } +} diff --git a/polkadot/node/test/performance-test/Cargo.toml b/polkadot/node/test/performance-test/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..1bddc6b08702a71305c4e58aef6baf4f5eed6e2a --- /dev/null +++ b/polkadot/node/test/performance-test/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "polkadot-performance-test" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +thiserror = "1.0.31" +quote = "1.0.28" +env_logger = "0.9" +log = "0.4" + +polkadot-node-core-pvf-prepare-worker = { path = "../../core/pvf/prepare-worker" } +polkadot-erasure-coding = { path = "../../../erasure-coding" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-primitives = { path = "../../../primitives" } + +sc-executor-common = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-maybe-compressed-blob = { git = "https://github.com/paritytech/substrate", branch = "master" } + +kusama-runtime = { path = "../../../runtime/kusama" } + +[[bin]] +name = "gen-ref-constants" +path = "src/gen_ref_constants.rs" + +[features] +runtime-benchmarks = ["kusama-runtime/runtime-benchmarks"] diff --git a/polkadot/node/test/performance-test/build.rs b/polkadot/node/test/performance-test/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..304b24c3b85f45d0a8a37915499078b095e03965 --- /dev/null +++ b/polkadot/node/test/performance-test/build.rs @@ -0,0 +1,21 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +fn main() { + if let Ok(profile) = std::env::var("PROFILE") { + println!("cargo:rustc-cfg=build_type=\"{}\"", profile); + } +} diff --git a/polkadot/node/test/performance-test/src/constants.rs b/polkadot/node/test/performance-test/src/constants.rs new file mode 100644 index 0000000000000000000000000000000000000000..158646ffc6ecf71c5ca06ab8f6e36eb3599074fb --- /dev/null +++ b/polkadot/node/test/performance-test/src/constants.rs @@ -0,0 +1,22 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This file was automatically generated by `gen-ref-constants`. +//! Do not edit manually! + +use std::time::Duration; +pub const PVF_PREPARE_TIME_LIMIT: Duration = Duration::from_millis(4910u64); +pub const ERASURE_CODING_TIME_LIMIT: Duration = Duration::from_millis(466u64); diff --git a/polkadot/node/test/performance-test/src/gen_ref_constants.rs b/polkadot/node/test/performance-test/src/gen_ref_constants.rs new file mode 100644 index 0000000000000000000000000000000000000000..ba10ed215552da7d6b2960ab9680d1d25535e778 --- /dev/null +++ b/polkadot/node/test/performance-test/src/gen_ref_constants.rs @@ -0,0 +1,99 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Generate reference performance check results. + +use polkadot_performance_test::PerfCheckError; + +fn main() -> Result<(), PerfCheckError> { + #[cfg(build_type = "release")] + { + run::run() + } + #[cfg(not(build_type = "release"))] + { + Err(PerfCheckError::WrongBuildType) + } +} + +#[cfg(build_type = "release")] +mod run { + use polkadot_node_primitives::VALIDATION_CODE_BOMB_LIMIT; + use polkadot_performance_test::{ + measure_erasure_coding, measure_pvf_prepare, PerfCheckError, ERASURE_CODING_N_VALIDATORS, + }; + use std::{ + fs::OpenOptions, + io::{self, Write}, + time::Duration, + }; + + const WARM_UP_RUNS: usize = 16; + const FILE_HEADER: &str = include_str!("../../../../file_header.txt"); + const DOC_COMMENT: &str = "//! This file was automatically generated by `gen-ref-constants`.\n//! Do not edit manually!"; + const FILE_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/src/constants.rs"); + + fn save_constants(pvf_prepare: Duration, erasure_coding: Duration) -> io::Result<()> { + let mut output = + OpenOptions::new().truncate(true).create(true).write(true).open(FILE_PATH)?; + + writeln!(output, "{}\n\n{}\n", FILE_HEADER, DOC_COMMENT)?; + + let pvf_prepare_millis = pvf_prepare.as_millis() as u64; + let erasure_coding_millis = erasure_coding.as_millis() as u64; + + let token_stream = quote::quote! { + use std::time::Duration; + + pub const PVF_PREPARE_TIME_LIMIT: Duration = Duration::from_millis(#pvf_prepare_millis); + pub const ERASURE_CODING_TIME_LIMIT: Duration = Duration::from_millis(#erasure_coding_millis); + }; + + writeln!(output, "{}", token_stream.to_string())?; + Ok(()) + } + + pub fn run() -> Result<(), PerfCheckError> { + let _ = env_logger::builder().filter(None, log::LevelFilter::Info).try_init(); + + let wasm_code = + polkadot_performance_test::WASM_BINARY.ok_or(PerfCheckError::WasmBinaryMissing)?; + + log::info!("Running the benchmark, number of iterations: {}", WARM_UP_RUNS); + + let code = sp_maybe_compressed_blob::decompress(wasm_code, VALIDATION_CODE_BOMB_LIMIT) + .or(Err(PerfCheckError::CodeDecompressionFailed))?; + + let (pvf_prepare_time, erasure_coding_time) = (1..=WARM_UP_RUNS) + .map(|i| { + if i - 1 > 0 && (i - 1) % 5 == 0 { + log::info!("{} iterations done", i - 1); + } + ( + measure_pvf_prepare(code.as_ref()), + measure_erasure_coding(ERASURE_CODING_N_VALIDATORS, code.as_ref()), + ) + }) + .last() + .expect("`WARM_UP_RUNS` is greater than 1 and thus we have at least one element; qed"); + + save_constants(pvf_prepare_time?, erasure_coding_time?)?; + + log::info!("Successfully stored new reference values at {:?}. Make sure to format the file via `cargo +nightly fmt`", FILE_PATH); + + Ok(()) + } +} diff --git a/polkadot/node/test/performance-test/src/lib.rs b/polkadot/node/test/performance-test/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..15073912654a4dd8cb24bae532ab305b5aa453e3 --- /dev/null +++ b/polkadot/node/test/performance-test/src/lib.rs @@ -0,0 +1,89 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A Polkadot performance tests utilities. + +use polkadot_erasure_coding::{obtain_chunks, reconstruct}; +use polkadot_primitives::ExecutorParams; +use std::time::{Duration, Instant}; + +mod constants; + +pub use constants::*; +pub use polkadot_node_primitives::VALIDATION_CODE_BOMB_LIMIT; + +/// Value used for reference benchmark of erasure-coding. +pub const ERASURE_CODING_N_VALIDATORS: usize = 1024; + +pub use kusama_runtime::WASM_BINARY; + +#[allow(missing_docs)] +#[derive(thiserror::Error, Debug)] +pub enum PerfCheckError { + #[error("This subcommand is only available in release mode")] + WrongBuildType, + + #[error("No wasm code found for running the performance test")] + WasmBinaryMissing, + + #[error("Failed to decompress wasm code")] + CodeDecompressionFailed, + + #[error(transparent)] + Wasm(#[from] sc_executor_common::error::WasmError), + + #[error(transparent)] + ErasureCoding(#[from] polkadot_erasure_coding::Error), + + #[error(transparent)] + Io(#[from] std::io::Error), + + #[error( + "Performance check not passed: exceeded the {limit:?} time limit, elapsed: {elapsed:?}" + )] + TimeOut { elapsed: Duration, limit: Duration }, +} + +/// Measures the time it takes to compile arbitrary wasm code. +pub fn measure_pvf_prepare(wasm_code: &[u8]) -> Result { + let start = Instant::now(); + + let code = sp_maybe_compressed_blob::decompress(wasm_code, VALIDATION_CODE_BOMB_LIMIT) + .or(Err(PerfCheckError::CodeDecompressionFailed))?; + + // Recreate the pipeline from the pvf prepare worker. + let blob = polkadot_node_core_pvf_prepare_worker::prevalidate(code.as_ref()) + .map_err(PerfCheckError::from)?; + polkadot_node_core_pvf_prepare_worker::prepare(blob, &ExecutorParams::default()) + .map_err(PerfCheckError::from)?; + + Ok(start.elapsed()) +} + +/// Measure the time it takes to break arbitrary data into chunks and reconstruct it back. +pub fn measure_erasure_coding( + n_validators: usize, + data: &[u8], +) -> Result { + let start = Instant::now(); + + let chunks = obtain_chunks(n_validators, &data)?; + let indexed_chunks = chunks.iter().enumerate().map(|(i, chunk)| (chunk.as_slice(), i)); + + let _: Vec = reconstruct(n_validators, indexed_chunks)?; + + Ok(start.elapsed()) +} diff --git a/polkadot/node/test/service/Cargo.toml b/polkadot/node/test/service/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..8912e19306e03bef9f3a5a84c24844f1eb15b0cf --- /dev/null +++ b/polkadot/node/test/service/Cargo.toml @@ -0,0 +1,70 @@ +[package] +name = "polkadot-test-service" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +futures = "0.3.21" +hex = "0.4.3" +gum = { package = "tracing-gum", path = "../../gum" } +rand = "0.8.5" +tempfile = "3.2.0" +tokio = "1.24.2" + +# Polkadot dependencies +polkadot-overseer = { path = "../../overseer" } +polkadot-primitives = { path = "../../../primitives" } +polkadot-parachain = { path = "../../../parachain" } +polkadot-rpc = { path = "../../../rpc" } +polkadot-runtime-common = { path = "../../../runtime/common" } +polkadot-service = { path = "../../service" } +polkadot-node-subsystem = { path = "../../subsystem" } +polkadot-node-primitives = { path = "../../primitives" } +polkadot-test-runtime = { path = "../../../runtime/test-runtime" } +test-runtime-constants = { path = "../../../runtime/test-runtime/constants" } +polkadot-runtime-parachains = { path = "../../../runtime/parachains" } + +# Substrate dependencies +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" } +babe = { package = "sc-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master" } +babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master" } +consensus_common = { package = "sp-consensus", git = "https://github.com/paritytech/substrate", branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } +grandpa = { package = "sc-consensus-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" } +grandpa_primitives = { package = "sp-consensus-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" } +inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[dev-dependencies] +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +serde_json = "1.0.96" +substrate-test-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } +tokio = { version = "1.24.2", features = ["macros"] } + +[features] +runtime-metrics=["polkadot-test-runtime/runtime-metrics"] +runtime-benchmarks=[ + "polkadot-test-runtime/runtime-benchmarks", + "polkadot-service/runtime-benchmarks", +] diff --git a/polkadot/node/test/service/README.md b/polkadot/node/test/service/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2fdee46a7f932010eeab1c30a7766dfb4049fbc3 --- /dev/null +++ b/polkadot/node/test/service/README.md @@ -0,0 +1,9 @@ +# polkadot-test-service + +## Testing + +Before running `cargo test` in this crate, make sure the worker binaries are built first. This can be done with: + +```sh +cargo build --bin polkadot-execute-worker --bin polkadot-prepare-worker +``` diff --git a/polkadot/node/test/service/src/chain_spec.rs b/polkadot/node/test/service/src/chain_spec.rs new file mode 100644 index 0000000000000000000000000000000000000000..9aadd7d203c0d6ba6197a0b7c55c20172dcd6deb --- /dev/null +++ b/polkadot/node/test/service/src/chain_spec.rs @@ -0,0 +1,197 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Chain specifications for the test runtime. + +use babe_primitives::AuthorityId as BabeId; +use grandpa::AuthorityId as GrandpaId; +use pallet_staking::Forcing; +use polkadot_primitives::{AccountId, AssignmentId, ValidatorId, MAX_CODE_SIZE, MAX_POV_SIZE}; +use polkadot_service::chain_spec::{ + get_account_id_from_seed, get_from_seed, polkadot_chain_spec_properties, Extensions, +}; +use polkadot_test_runtime::BABE_GENESIS_EPOCH_CONFIG; +use sc_chain_spec::{ChainSpec, ChainType}; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_core::sr25519; +use sp_runtime::Perbill; +use test_runtime_constants::currency::DOTS; + +const DEFAULT_PROTOCOL_ID: &str = "dot"; + +/// The `ChainSpec` parameterized for polkadot test runtime. +pub type PolkadotChainSpec = + sc_service::GenericChainSpec; + +/// Local testnet config (multivalidator Alice + Bob) +pub fn polkadot_local_testnet_config() -> PolkadotChainSpec { + PolkadotChainSpec::from_genesis( + "Local Testnet", + "local_testnet", + ChainType::Local, + || polkadot_local_testnet_genesis(), + vec![], + None, + Some(DEFAULT_PROTOCOL_ID), + None, + Some(polkadot_chain_spec_properties()), + Default::default(), + ) +} + +/// Local testnet genesis config (multivalidator Alice + Bob) +pub fn polkadot_local_testnet_genesis() -> polkadot_test_runtime::RuntimeGenesisConfig { + polkadot_testnet_genesis( + vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")], + get_account_id_from_seed::("Alice"), + None, + ) +} + +/// Helper function to generate stash, controller and session key from seed +fn get_authority_keys_from_seed( + seed: &str, +) -> (AccountId, AccountId, BabeId, GrandpaId, ValidatorId, AssignmentId, AuthorityDiscoveryId) { + ( + 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), + get_from_seed::(seed), + get_from_seed::(seed), + ) +} + +fn testnet_accounts() -> Vec { + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), + ] +} + +/// Helper function to create polkadot `RuntimeGenesisConfig` for testing +fn polkadot_testnet_genesis( + initial_authorities: Vec<( + AccountId, + AccountId, + BabeId, + GrandpaId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + )>, + root_key: AccountId, + endowed_accounts: Option>, +) -> polkadot_test_runtime::RuntimeGenesisConfig { + use polkadot_test_runtime as runtime; + + let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(testnet_accounts); + + const ENDOWMENT: u128 = 1_000_000 * DOTS; + const STASH: u128 = 100 * DOTS; + + runtime::RuntimeGenesisConfig { + system: runtime::SystemConfig { + code: runtime::WASM_BINARY.expect("Wasm binary must be built for testing").to_vec(), + ..Default::default() + }, + indices: runtime::IndicesConfig { indices: vec![] }, + balances: runtime::BalancesConfig { + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), + }, + session: runtime::SessionConfig { + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + runtime::SessionKeys { + babe: x.2.clone(), + grandpa: x.3.clone(), + para_validator: x.4.clone(), + para_assignment: x.5.clone(), + authority_discovery: x.6.clone(), + }, + ) + }) + .collect::>(), + }, + staking: runtime::StakingConfig { + minimum_validator_count: 1, + validator_count: 2, + stakers: initial_authorities + .iter() + .map(|x| (x.0.clone(), x.0.clone(), STASH, runtime::StakerStatus::Validator)) + .collect(), + invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), + force_era: Forcing::NotForcing, + slash_reward_fraction: Perbill::from_percent(10), + ..Default::default() + }, + babe: runtime::BabeConfig { + authorities: vec![], + epoch_config: Some(BABE_GENESIS_EPOCH_CONFIG), + ..Default::default() + }, + grandpa: Default::default(), + authority_discovery: runtime::AuthorityDiscoveryConfig { + keys: vec![], + ..Default::default() + }, + claims: runtime::ClaimsConfig { claims: vec![], vesting: vec![] }, + vesting: runtime::VestingConfig { vesting: vec![] }, + sudo: runtime::SudoConfig { key: Some(root_key) }, + configuration: runtime::ConfigurationConfig { + config: polkadot_runtime_parachains::configuration::HostConfiguration { + validation_upgrade_cooldown: 10u32, + validation_upgrade_delay: 5, + code_retention_period: 1200, + max_code_size: MAX_CODE_SIZE, + max_pov_size: MAX_POV_SIZE, + max_head_data_size: 32 * 1024, + group_rotation_frequency: 20, + paras_availability_period: 4, + no_show_slots: 10, + minimum_validation_upgrade_delay: 5, + ..Default::default() + }, + }, + } +} + +/// Can be called for a `Configuration` to check if it is a configuration for the `Test` network. +pub trait IdentifyVariant { + /// Returns if this is a configuration for the `Test` network. + fn is_test(&self) -> bool; +} + +impl IdentifyVariant for Box { + fn is_test(&self) -> bool { + self.id().starts_with("test") + } +} diff --git a/polkadot/node/test/service/src/lib.rs b/polkadot/node/test/service/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..be2746daf32121651d7d5c1bbf395ff3e243976a --- /dev/null +++ b/polkadot/node/test/service/src/lib.rs @@ -0,0 +1,417 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot test service only. + +#![warn(missing_docs)] + +pub mod chain_spec; + +pub use chain_spec::*; +use futures::{future::Future, stream::StreamExt}; +use polkadot_node_primitives::{CollationGenerationConfig, CollatorFn}; +use polkadot_node_subsystem::messages::{CollationGenerationMessage, CollatorProtocolMessage}; +use polkadot_overseer::Handle; +use polkadot_primitives::{Balance, CollatorPair, HeadData, Id as ParaId, ValidationCode}; +use polkadot_runtime_common::BlockHashCount; +use polkadot_runtime_parachains::paras::{ParaGenesisArgs, ParaKind}; +use polkadot_service::{Error, FullClient, IsParachainNode, NewFull, PrometheusConfig}; +use polkadot_test_runtime::{ + ParasCall, ParasSudoWrapperCall, Runtime, SignedExtra, SignedPayload, SudoCall, + UncheckedExtrinsic, VERSION, +}; + +use sc_chain_spec::ChainSpec; +use sc_client_api::BlockchainEvents; +use sc_network::{ + config::{NetworkConfiguration, TransportConfig}, + multiaddr, NetworkStateInfo, +}; +use sc_service::{ + config::{ + DatabaseSource, KeystoreConfig, MultiaddrWithPeerId, WasmExecutionMethod, + WasmtimeInstantiationStrategy, + }, + BasePath, BlocksPruning, Configuration, Role, RpcHandlers, TaskManager, +}; +use sp_arithmetic::traits::SaturatedConversion; +use sp_blockchain::HeaderBackend; +use sp_keyring::Sr25519Keyring; +use sp_runtime::{codec::Encode, generic, traits::IdentifyAccount, MultiSigner}; +use sp_state_machine::BasicExternalities; +use std::{ + collections::HashSet, + net::{Ipv4Addr, SocketAddr}, + path::PathBuf, + sync::Arc, +}; +use substrate_test_client::{ + BlockchainEventsExt, RpcHandlersExt, RpcTransactionError, RpcTransactionOutput, +}; + +/// The client type being used by the test service. +pub type Client = FullClient; + +pub use polkadot_service::{FullBackend, GetLastTimestamp}; + +/// Create a new full node. +#[sc_tracing::logging::prefix_logs_with(config.network.node_name.as_str())] +pub fn new_full( + config: Configuration, + is_parachain_node: IsParachainNode, + workers_path: Option, +) -> Result { + let workers_path = Some(workers_path.unwrap_or_else(get_relative_workers_path_for_test)); + + polkadot_service::new_full( + config, + polkadot_service::NewFullParams { + is_parachain_node, + grandpa_pause: None, + enable_beefy: true, + jaeger_agent: None, + telemetry_worker_handle: None, + node_version: None, + workers_path, + workers_names: None, + overseer_gen: polkadot_service::RealOverseerGen, + overseer_message_channel_capacity_override: None, + malus_finality_delay: None, + hwbench: None, + }, + ) +} + +fn get_relative_workers_path_for_test() -> PathBuf { + // If no explicit worker path is passed in, we need to specify it ourselves as test binaries + // are in the "deps/" directory, one level below where the worker binaries are generated. + let mut exe_path = std::env::current_exe() + .expect("for test purposes it's reasonable to expect that this will not fail"); + let _ = exe_path.pop(); + let _ = exe_path.pop(); + exe_path +} + +/// Returns a prometheus config usable for testing. +pub fn test_prometheus_config(port: u16) -> PrometheusConfig { + PrometheusConfig::new_with_default_registry( + SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port), + "test-chain".to_string(), + ) +} + +/// Create a Polkadot `Configuration`. +/// +/// By default an in-memory socket will be used, therefore you need to provide boot +/// nodes if you want the future node to be connected to other nodes. +/// +/// The `storage_update_func` function will be executed in an externalities provided environment +/// and can be used to make adjustments to the runtime genesis storage. +pub fn node_config( + storage_update_func: impl Fn(), + tokio_handle: tokio::runtime::Handle, + key: Sr25519Keyring, + boot_nodes: Vec, + is_validator: bool, +) -> Configuration { + let base_path = BasePath::new_temp_dir().expect("could not create temporary directory"); + let root = base_path.path().join(key.to_string()); + let role = if is_validator { Role::Authority } else { Role::Full }; + let key_seed = key.to_seed(); + let mut spec = polkadot_local_testnet_config(); + let mut storage = spec.as_storage_builder().build_storage().expect("could not build storage"); + + BasicExternalities::execute_with_storage(&mut storage, storage_update_func); + spec.set_storage(storage); + + let mut network_config = NetworkConfiguration::new( + key_seed.to_string(), + "network/test/0.1", + Default::default(), + None, + ); + + network_config.boot_nodes = boot_nodes; + + network_config.allow_non_globals_in_dht = true; + + let addr: multiaddr::Multiaddr = multiaddr::Protocol::Memory(rand::random()).into(); + network_config.listen_addresses.push(addr.clone()); + + network_config.public_addresses.push(addr); + + network_config.transport = TransportConfig::MemoryOnly; + + Configuration { + impl_name: "polkadot-test-node".to_string(), + impl_version: "0.1".to_string(), + role, + tokio_handle, + transaction_pool: Default::default(), + network: network_config, + keystore: KeystoreConfig::InMemory, + database: DatabaseSource::RocksDb { path: root.join("db"), cache_size: 128 }, + trie_cache_maximum_size: Some(64 * 1024 * 1024), + state_pruning: Default::default(), + blocks_pruning: BlocksPruning::KeepFinalized, + chain_spec: Box::new(spec), + wasm_method: WasmExecutionMethod::Compiled { + instantiation_strategy: WasmtimeInstantiationStrategy::PoolingCopyOnWrite, + }, + wasm_runtime_overrides: Default::default(), + rpc_addr: Default::default(), + rpc_max_request_size: Default::default(), + rpc_max_response_size: Default::default(), + rpc_max_connections: Default::default(), + rpc_cors: None, + rpc_methods: Default::default(), + rpc_id_provider: None, + rpc_max_subs_per_conn: Default::default(), + rpc_port: 9944, + prometheus_config: None, + telemetry_endpoints: None, + default_heap_pages: None, + offchain_worker: Default::default(), + force_authoring: false, + disable_grandpa: false, + dev_key_seed: Some(key_seed), + tracing_targets: None, + tracing_receiver: Default::default(), + max_runtime_instances: 8, + runtime_cache_size: 2, + announce_block: true, + data_path: root, + base_path, + informant_output_format: Default::default(), + } +} + +/// Run a test validator node that uses the test runtime and specified `config`. +pub fn run_validator_node( + config: Configuration, + worker_program_path: Option, +) -> PolkadotTestNode { + let multiaddr = config.network.listen_addresses[0].clone(); + let NewFull { task_manager, client, network, rpc_handlers, overseer_handle, .. } = + new_full(config, IsParachainNode::No, worker_program_path) + .expect("could not create Polkadot test service"); + + let overseer_handle = overseer_handle.expect("test node must have an overseer handle"); + let peer_id = network.local_peer_id(); + let addr = MultiaddrWithPeerId { multiaddr, peer_id }; + + PolkadotTestNode { task_manager, client, overseer_handle, addr, rpc_handlers } +} + +/// Run a test collator node that uses the test runtime. +/// +/// The node will be using an in-memory socket, therefore you need to provide boot nodes if you +/// want it to be connected to other nodes. +/// +/// The `storage_update_func` function will be executed in an externalities provided environment +/// and can be used to make adjustments to the runtime genesis storage. +/// +/// # Note +/// +/// The collator functionality still needs to be registered at the node! This can be done using +/// [`PolkadotTestNode::register_collator`]. +pub fn run_collator_node( + tokio_handle: tokio::runtime::Handle, + key: Sr25519Keyring, + storage_update_func: impl Fn(), + boot_nodes: Vec, + collator_pair: CollatorPair, +) -> PolkadotTestNode { + let config = node_config(storage_update_func, tokio_handle, key, boot_nodes, false); + let multiaddr = config.network.listen_addresses[0].clone(); + let NewFull { task_manager, client, network, rpc_handlers, overseer_handle, .. } = + new_full(config, IsParachainNode::Collator(collator_pair), None) + .expect("could not create Polkadot test service"); + + let overseer_handle = overseer_handle.expect("test node must have an overseer handle"); + let peer_id = network.local_peer_id(); + let addr = MultiaddrWithPeerId { multiaddr, peer_id }; + + PolkadotTestNode { task_manager, client, overseer_handle, addr, rpc_handlers } +} + +/// A Polkadot test node instance used for testing. +pub struct PolkadotTestNode { + /// `TaskManager`'s instance. + pub task_manager: TaskManager, + /// Client's instance. + pub client: Arc, + /// A handle to Overseer. + pub overseer_handle: Handle, + /// The `MultiaddrWithPeerId` to this node. This is useful if you want to pass it as "boot + /// node" to other nodes. + pub addr: MultiaddrWithPeerId, + /// `RPCHandlers` to make RPC queries. + pub rpc_handlers: RpcHandlers, +} + +impl PolkadotTestNode { + /// Send a sudo call to this node. + async fn send_sudo( + &self, + call: impl Into, + caller: Sr25519Keyring, + nonce: u32, + ) -> Result<(), RpcTransactionError> { + let sudo = SudoCall::sudo { call: Box::new(call.into()) }; + + let extrinsic = construct_extrinsic(&self.client, sudo, caller, nonce); + self.rpc_handlers.send_transaction(extrinsic.into()).await.map(drop) + } + + /// Send an extrinsic to this node. + pub async fn send_extrinsic( + &self, + function: impl Into, + caller: Sr25519Keyring, + ) -> Result { + let extrinsic = construct_extrinsic(&self.client, function, caller, 0); + + self.rpc_handlers.send_transaction(extrinsic.into()).await + } + + /// Register a parachain at this relay chain. + pub async fn register_parachain( + &self, + id: ParaId, + validation_code: impl Into, + genesis_head: impl Into, + ) -> Result<(), RpcTransactionError> { + let validation_code: ValidationCode = validation_code.into(); + let call = ParasSudoWrapperCall::sudo_schedule_para_initialize { + id, + genesis: ParaGenesisArgs { + genesis_head: genesis_head.into(), + validation_code: validation_code.clone(), + para_kind: ParaKind::Parachain, + }, + }; + + self.send_sudo(call, Sr25519Keyring::Alice, 0).await?; + + // Bypass pvf-checking. + let call = ParasCall::add_trusted_validation_code { validation_code }; + self.send_sudo(call, Sr25519Keyring::Alice, 1).await + } + + /// Wait for `count` blocks to be imported in the node and then exit. This function will not + /// return if no blocks are ever created, thus you should restrict the maximum amount of time of + /// the test execution. + pub fn wait_for_blocks(&self, count: usize) -> impl Future { + self.client.wait_for_blocks(count) + } + + /// Wait for `count` blocks to be finalized and then exit. Similarly with `wait_for_blocks` this + /// function will not return if no block are ever finalized. + pub async fn wait_for_finalized_blocks(&self, count: usize) { + let mut import_notification_stream = self.client.finality_notification_stream(); + let mut blocks = HashSet::new(); + + while let Some(notification) = import_notification_stream.next().await { + blocks.insert(notification.hash); + if blocks.len() == count { + break + } + } + } + + /// Register the collator functionality in the overseer of this node. + pub async fn register_collator( + &mut self, + collator_key: CollatorPair, + para_id: ParaId, + collator: CollatorFn, + ) { + let config = + CollationGenerationConfig { key: collator_key, collator: Some(collator), para_id }; + + self.overseer_handle + .send_msg(CollationGenerationMessage::Initialize(config), "Collator") + .await; + + self.overseer_handle + .send_msg(CollatorProtocolMessage::CollateOn(para_id), "Collator") + .await; + } +} + +/// Construct an extrinsic that can be applied to the test runtime. +pub fn construct_extrinsic( + client: &Client, + function: impl Into, + caller: Sr25519Keyring, + nonce: u32, +) -> UncheckedExtrinsic { + let function = function.into(); + let current_block_hash = client.info().best_hash; + let current_block = client.info().best_number.saturated_into(); + let genesis_block = client.hash(0).unwrap().unwrap(); + let period = + BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; + let tip = 0; + let extra: SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(generic::Era::mortal(period, current_block)), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + ); + let raw_payload = SignedPayload::from_raw( + function.clone(), + extra.clone(), + ( + (), + VERSION.spec_version, + VERSION.transaction_version, + genesis_block, + current_block_hash, + (), + (), + (), + ), + ); + let signature = raw_payload.using_encoded(|e| caller.sign(e)); + UncheckedExtrinsic::new_signed( + function.clone(), + polkadot_test_runtime::Address::Id(caller.public().into()), + polkadot_primitives::Signature::Sr25519(signature.clone()), + extra.clone(), + ) +} + +/// Construct a transfer extrinsic. +pub fn construct_transfer_extrinsic( + client: &Client, + origin: sp_keyring::AccountKeyring, + dest: sp_keyring::AccountKeyring, + value: Balance, +) -> UncheckedExtrinsic { + let function = + polkadot_test_runtime::RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { + dest: MultiSigner::from(dest.public()).into_account().into(), + value, + }); + + construct_extrinsic(client, function, origin, 0) +} diff --git a/polkadot/node/test/service/tests/build-blocks.rs b/polkadot/node/test/service/tests/build-blocks.rs new file mode 100644 index 0000000000000000000000000000000000000000..b75fed60297ab902f30453ed8d8cfc5246e95a22 --- /dev/null +++ b/polkadot/node/test/service/tests/build-blocks.rs @@ -0,0 +1,57 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use futures::{future, pin_mut, select, FutureExt}; +use polkadot_test_service::*; +use sp_keyring::Sr25519Keyring; + +#[substrate_test_utils::test(flavor = "multi_thread")] +async fn ensure_test_service_build_blocks() { + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_colors(false); + builder.init().expect("Sets up logger"); + let alice_config = node_config( + || {}, + tokio::runtime::Handle::current(), + Sr25519Keyring::Alice, + Vec::new(), + true, + ); + let mut alice = run_validator_node(alice_config, None); + + let bob_config = node_config( + || {}, + tokio::runtime::Handle::current(), + Sr25519Keyring::Bob, + vec![alice.addr.clone()], + true, + ); + let mut bob = run_validator_node(bob_config, None); + + { + let t1 = future::join(alice.wait_for_blocks(3), bob.wait_for_blocks(3)).fuse(); + let t2 = alice.task_manager.future().fuse(); + let t3 = bob.task_manager.future().fuse(); + + pin_mut!(t1, t2, t3); + + select! { + _ = t1 => {}, + _ = t2 => panic!("service Alice failed"), + _ = t3 => panic!("service Bob failed"), + } + } +} diff --git a/polkadot/node/test/service/tests/call-function.rs b/polkadot/node/test/service/tests/call-function.rs new file mode 100644 index 0000000000000000000000000000000000000000..c3baefdb9c91a4b338ebe266bee51028def80189 --- /dev/null +++ b/polkadot/node/test/service/tests/call-function.rs @@ -0,0 +1,41 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_test_service::*; +use sp_keyring::Sr25519Keyring::{Alice, Bob, Charlie}; + +#[substrate_test_utils::test(flavor = "multi_thread")] +async fn call_function_actually_work() { + let alice_config = + node_config(|| {}, tokio::runtime::Handle::current(), Alice, Vec::new(), true); + + let alice = run_validator_node(alice_config, None); + + let function = + polkadot_test_runtime::RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { + dest: Charlie.to_account_id().into(), + value: 1, + }); + let output = alice.send_extrinsic(function, Bob).await.unwrap(); + + let res = output.result; + let json = serde_json::from_str::(res.as_str()).expect("valid JSON"); + let object = json.as_object().expect("JSON is an object"); + assert!(object.contains_key("jsonrpc"), "key jsonrpc exists"); + let result = object.get("result"); + let result = result.expect("key result exists"); + assert_eq!(result.as_str().map(|x| x.starts_with("0x")), Some(true), "result starts with 0x"); +} diff --git a/polkadot/node/zombienet-backchannel/Cargo.toml b/polkadot/node/zombienet-backchannel/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..1c032cc3f136ef2bdf79d7008ad56e1f600267df --- /dev/null +++ b/polkadot/node/zombienet-backchannel/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "zombienet-backchannel" +description = "Zombienet backchannel to notify test runner and coordinate with malus actors." +readme = "README.md" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +tokio = { version = "1.24.2", default-features = false, features = ["macros", "net", "rt-multi-thread", "sync"] } +url = "2.3.1" +tokio-tungstenite = "0.17" +futures-util = "0.3.23" +lazy_static = "1.4.0" +parity-scale-codec = { version = "3.6.1", features = ["derive"] } +reqwest = { version = "0.11", features = ["rustls-tls"], default-features = false } +thiserror = "1.0.31" +gum = { package = "tracing-gum", path = "../gum/" } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1" diff --git a/polkadot/node/zombienet-backchannel/src/errors.rs b/polkadot/node/zombienet-backchannel/src/errors.rs new file mode 100644 index 0000000000000000000000000000000000000000..df74dd477752096eca827dfaf0b4d7cdcc37cb6a --- /dev/null +++ b/polkadot/node/zombienet-backchannel/src/errors.rs @@ -0,0 +1,39 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot Zombienet Backchannel error definitions. + +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum BackchannelError { + #[error("Error connecting websocket server")] + CantConnectToWS, + + #[error("Backchannel not initialized yet")] + Uninitialized, + + #[error("Backchannel already initialized")] + AlreadyInitialized, + + #[error("Error sending new value to backchannel")] + SendItemFail, + + #[error("Invalid host for connection backchannel")] + InvalidHost, + + #[error("Invalid port for connection backchannel")] + InvalidPort, +} diff --git a/polkadot/node/zombienet-backchannel/src/lib.rs b/polkadot/node/zombienet-backchannel/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..fa9218d2d3502af7d55cfead12f5aebe1cb070ef --- /dev/null +++ b/polkadot/node/zombienet-backchannel/src/lib.rs @@ -0,0 +1,159 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Provides the possibility to coordination between malicious actors and +//! the zombienet test-runner, allowing to reference runtime's generated +//! values in the test specifications, through a bidirectional message passing +//! implemented as a `backchannel`. + +use futures_util::{SinkExt, StreamExt}; +use lazy_static::lazy_static; +use parity_scale_codec as codec; +use serde::{Deserialize, Serialize}; +use std::{env, sync::Mutex}; +use tokio::sync::broadcast; +use tokio_tungstenite::{connect_async, tungstenite::protocol::Message}; + +mod errors; +use errors::BackchannelError; + +lazy_static! { + pub static ref ZOMBIENET_BACKCHANNEL: Mutex> = Mutex::new(None); +} + +#[derive(Debug)] +pub struct ZombienetBackchannel { + broadcast_tx: broadcast::Sender, + ws_tx: broadcast::Sender, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct BackchannelItem { + key: String, + value: String, +} + +pub struct Broadcaster; + +pub const ZOMBIENET: &str = "🧟ZOMBIENET🧟"; + +impl Broadcaster { + /// Return a subscriber that will receive all message broadcasted by the zombienet backchannel + /// websocket server. + pub fn subscribe(&self) -> Result, BackchannelError> { + let mut zombienet_bkc = ZOMBIENET_BACKCHANNEL.lock().unwrap(); + let zombienet_bkc = zombienet_bkc.as_mut().ok_or(BackchannelError::Uninitialized)?; + let sender = zombienet_bkc.broadcast_tx.clone(); + Ok(sender.subscribe()) + } + + /// Provides a simple API to send a key/value to the zombienet websocket server. + pub async fn send( + &mut self, + key: &'static str, + val: impl codec::Encode, + ) -> Result<(), BackchannelError> { + let mut zombienet_bkc = ZOMBIENET_BACKCHANNEL.lock().unwrap(); + let zombienet_bkc = zombienet_bkc.as_mut().ok_or(BackchannelError::Uninitialized)?; + + let encoded = val.encode(); + let backchannel_item = BackchannelItem { + key: key.to_string(), + value: String::from_utf8_lossy(&encoded).to_string(), + }; + + let sender = zombienet_bkc.ws_tx.clone(); + sender.send(backchannel_item).map_err(|e| { + gum::error!(target: ZOMBIENET, "Error sending new item: {}", e); + BackchannelError::SendItemFail + })?; + + Ok(()) + } +} + +impl ZombienetBackchannel { + pub async fn init() -> Result<(), BackchannelError> { + let mut zombienet_bkc = ZOMBIENET_BACKCHANNEL.lock().unwrap(); + if zombienet_bkc.is_none() { + let backchannel_host = + env::var("BACKCHANNEL_HOST").unwrap_or_else(|_| "backchannel".to_string()); + let backchannel_port = + env::var("BACKCHANNEL_PORT").unwrap_or_else(|_| "3000".to_string()); + + // validate port + backchannel_port.parse::().map_err(|_| BackchannelError::InvalidPort)?; + // validate non empty string for host + if backchannel_host.trim().is_empty() { + return Err(BackchannelError::InvalidHost) + }; + + let ws_url = format!("ws://{}:{}/ws", backchannel_host, backchannel_port); + gum::debug!(target: ZOMBIENET, "Connecting to : {}", &ws_url); + let (ws_stream, _) = + connect_async(ws_url).await.map_err(|_| BackchannelError::CantConnectToWS)?; + let (mut write, mut read) = ws_stream.split(); + + let (tx, _rx) = broadcast::channel(256); + let (tx_relay, mut rx_relay) = broadcast::channel::(256); + + // receive from the ws and send to all subcribers + let tx1 = tx.clone(); + tokio::spawn(async move { + while let Some(Ok(Message::Text(text))) = read.next().await { + match serde_json::from_str::(&text) { + Ok(backchannel_item) => + if tx1.send(backchannel_item).is_err() { + gum::error!(target: ZOMBIENET, "Error sending through the channel"); + return + }, + Err(_) => { + gum::error!(target: ZOMBIENET, "Invalid payload received"); + }, + } + } + }); + + // receive from subscribers and relay to ws + tokio::spawn(async move { + while let Ok(item) = rx_relay.recv().await { + if write + .send(Message::Text(serde_json::to_string(&item).unwrap())) + .await + .is_err() + { + gum::error!(target: ZOMBIENET, "Error sending through ws"); + } + } + }); + + *zombienet_bkc = Some(ZombienetBackchannel { broadcast_tx: tx, ws_tx: tx_relay }); + return Ok(()) + } + + Err(BackchannelError::AlreadyInitialized) + } + + /// Ensure that the backchannel is initialized and return a broadcaster instance + /// allowing to subscribe or send new items. + pub fn broadcaster() -> Result { + if ZOMBIENET_BACKCHANNEL.lock().unwrap().is_some() { + Ok(Broadcaster {}) + } else { + Err(BackchannelError::Uninitialized) + } + } +} diff --git a/polkadot/parachain/Cargo.toml b/polkadot/parachain/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5d49042bc0cc8ede0baedb9c21cc9742c4e6ce53 --- /dev/null +++ b/polkadot/parachain/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "polkadot-parachain" +description = "Types and utilities for creating and working with parachains" +authors.workspace = true +edition.workspace = true +license.workspace = true +version.workspace = true + +[dependencies] +# note: special care is taken to avoid inclusion of `sp-io` externals when compiling +# this crate for WASM. This is critical to avoid forcing all parachain WASM into implementing +# various unnecessary Substrate-specific endpoints. +parity-scale-codec = { version = "3.6.1", default-features = false, features = [ "derive" ] } +scale-info = { version = "2.5.0", default-features = false, features = ["derive", "serde"] } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = ["serde"] } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = ["serde"] } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +polkadot-core-primitives = { path = "../core-primitives", default-features = false } +derive_more = "0.99.11" +bounded-collections = { version = "0.1.8", default-features = false, features = ["serde"] } + +# all optional crates. +serde = { version = "1.0.163", default-features = false, features = ["derive", "alloc"] } + +[features] +default = ["std"] +wasm-api = [] +std = [ + "bounded-collections/std", + "parity-scale-codec/std", + "scale-info/std", + "serde/std", + "sp-std/std", + "sp-runtime/std", + "sp-core/std", + "polkadot-core-primitives/std", + "frame-support/std", +] +runtime-benchmarks = [] diff --git a/polkadot/parachain/README.adoc b/polkadot/parachain/README.adoc new file mode 100644 index 0000000000000000000000000000000000000000..8650919e64ec45b9c3ceb5aee36bb3112c06a678 --- /dev/null +++ b/polkadot/parachain/README.adoc @@ -0,0 +1,5 @@ + += Polkadot Parachain + +placeholder +//TODO Write content :) (https://github.com/paritytech/polkadot/issues/159) diff --git a/polkadot/parachain/src/lib.rs b/polkadot/parachain/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..7bead2314839f4974494297952293e62f6fba061 --- /dev/null +++ b/polkadot/parachain/src/lib.rs @@ -0,0 +1,54 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![warn(unused_crate_dependencies)] + +//! Defines primitive types for creating or validating a parachain. +//! +//! When compiled with standard library support, this crate exports a `wasm` +//! module that can be used to validate parachain WASM. +//! +//! ## Parachain WASM +//! +//! Polkadot parachain WASM is in the form of a module which imports a memory +//! instance and exports a function `validate_block`. +//! +//! `validate` accepts as input two `i32` values, representing a pointer/length pair +//! respectively, that encodes [`ValidationParams`]. +//! +//! `validate` returns an `u64` which is a pointer to an `u8` array and its length. +//! The data in the array is expected to be a SCALE encoded [`ValidationResult`]. +//! +//! ASCII-diagram demonstrating the return data format: +//! +//! ```ignore +//! [pointer][length] +//! 32bit 32bit +//! ^~~ returned pointer & length +//! ``` +//! +//! The wasm-api (enabled only when `std` feature is not enabled and `wasm-api` feature is enabled) +//! provides utilities for setting up a parachain WASM module in Rust. + +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod primitives; + +#[cfg(all(not(feature = "std"), feature = "wasm-api"))] +mod wasm_api; + +#[cfg(all(not(feature = "std"), feature = "wasm-api"))] +pub use wasm_api::*; diff --git a/polkadot/parachain/src/primitives.rs b/polkadot/parachain/src/primitives.rs new file mode 100644 index 0000000000000000000000000000000000000000..5cea9d3bbf4e827a632a103132626a39c623c5c2 --- /dev/null +++ b/polkadot/parachain/src/primitives.rs @@ -0,0 +1,421 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Primitive types which are strictly necessary from a parachain-execution point +//! of view. + +use sp_std::vec::Vec; + +use bounded_collections::{BoundedVec, ConstU32}; +use frame_support::weights::Weight; +use parity_scale_codec::{CompactAs, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; +use serde::{Deserialize, Serialize}; +use sp_core::{bytes, RuntimeDebug, TypeId}; +use sp_runtime::traits::Hash as _; + +use polkadot_core_primitives::{Hash, OutboundHrmpMessage}; + +/// Block number type used by the relay chain. +pub use polkadot_core_primitives::BlockNumber as RelayChainBlockNumber; + +/// Parachain head data included in the chain. +#[derive( + PartialEq, + Eq, + Clone, + PartialOrd, + Ord, + Encode, + Decode, + RuntimeDebug, + derive_more::From, + TypeInfo, + Serialize, + Deserialize, +)] +#[cfg_attr(feature = "std", derive(Hash, Default))] +pub struct HeadData(#[serde(with = "bytes")] pub Vec); + +impl HeadData { + /// Returns the hash of this head data. + pub fn hash(&self) -> Hash { + sp_runtime::traits::BlakeTwo256::hash(&self.0) + } +} + +/// Parachain validation code. +#[derive( + PartialEq, + Eq, + Clone, + Encode, + Decode, + RuntimeDebug, + derive_more::From, + TypeInfo, + Serialize, + Deserialize, +)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct ValidationCode(#[serde(with = "bytes")] pub Vec); + +impl ValidationCode { + /// Get the blake2-256 hash of the validation code bytes. + pub fn hash(&self) -> ValidationCodeHash { + ValidationCodeHash(sp_runtime::traits::BlakeTwo256::hash(&self.0[..])) + } +} + +/// Unit type wrapper around [`type@Hash`] that represents the blake2-256 hash +/// of validation code in particular. +/// +/// This type is produced by [`ValidationCode::hash`]. +/// +/// This type makes it easy to enforce that a hash is a validation code hash on the type level. +#[derive(Clone, Copy, Encode, Decode, Hash, Eq, PartialEq, PartialOrd, Ord, TypeInfo)] +pub struct ValidationCodeHash(Hash); + +impl sp_std::fmt::Display for ValidationCodeHash { + fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { + self.0.fmt(f) + } +} + +impl sp_std::fmt::Debug for ValidationCodeHash { + fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { + write!(f, "{:?}", self.0) + } +} + +impl AsRef<[u8]> for ValidationCodeHash { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + +impl From for ValidationCodeHash { + fn from(hash: Hash) -> ValidationCodeHash { + ValidationCodeHash(hash) + } +} + +impl From<[u8; 32]> for ValidationCodeHash { + fn from(hash: [u8; 32]) -> ValidationCodeHash { + ValidationCodeHash(hash.into()) + } +} + +impl sp_std::fmt::LowerHex for ValidationCodeHash { + fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { + sp_std::fmt::LowerHex::fmt(&self.0, f) + } +} + +/// Parachain block data. +/// +/// Contains everything required to validate para-block, may contain block and witness data. +#[derive(PartialEq, Eq, Clone, Encode, Decode, derive_more::From, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct BlockData(#[cfg_attr(feature = "std", serde(with = "bytes"))] pub Vec); + +/// Unique identifier of a parachain. +#[derive( + Clone, + CompactAs, + Copy, + Decode, + Default, + Encode, + Eq, + Hash, + MaxEncodedLen, + Ord, + PartialEq, + PartialOrd, + RuntimeDebug, + serde::Serialize, + serde::Deserialize, + TypeInfo, +)] +#[cfg_attr(feature = "std", derive(derive_more::Display))] +pub struct Id(u32); + +impl TypeId for Id { + const TYPE_ID: [u8; 4] = *b"para"; +} + +impl From for u32 { + fn from(x: Id) -> Self { + x.0 + } +} + +impl From for Id { + fn from(x: u32) -> Self { + Id(x) + } +} + +impl From for Id { + fn from(x: usize) -> Self { + // can't panic, so need to truncate + let x = x.try_into().unwrap_or(u32::MAX); + Id(x) + } +} + +// When we added a second From impl for Id, type inference could no longer +// determine which impl should apply for things like `5.into()`. It therefore +// raised a bunch of errors in our test code, scattered throughout the +// various modules' tests, that there is no impl of `From` (`i32` being +// the default numeric type). +// +// We can't use `cfg(test)` here, because that configuration directive does not +// propagate between crates, which would fail to fix tests in crates other than +// this one. +// +// Instead, let's take advantage of the observation that what really matters for a +// ParaId within a test context is that it is unique and constant. I believe that +// there is no case where someone does `(-1).into()` anyway, but if they do, it +// never matters whether the actual contained ID is `-1` or `4294967295`. Nobody +// does arithmetic on a `ParaId`; doing so would be a bug. +impl From for Id { + fn from(x: i32) -> Self { + Id(x as u32) + } +} + +const USER_INDEX_START: u32 = 1000; +const PUBLIC_INDEX_START: u32 = 2000; + +/// The ID of the first user (non-system) parachain. +pub const LOWEST_USER_ID: Id = Id(USER_INDEX_START); + +/// The ID of the first publicly registerable parachain. +pub const LOWEST_PUBLIC_ID: Id = Id(PUBLIC_INDEX_START); + +impl Id { + /// Create an `Id`. + pub const fn new(id: u32) -> Self { + Self(id) + } +} + +/// Determine if a parachain is a system parachain or not. +pub trait IsSystem { + /// Returns `true` if a parachain is a system parachain, `false` otherwise. + fn is_system(&self) -> bool; +} + +impl IsSystem for Id { + fn is_system(&self) -> bool { + self.0 < USER_INDEX_START + } +} + +impl sp_std::ops::Add for Id { + type Output = Self; + + fn add(self, other: u32) -> Self { + Self(self.0 + other) + } +} + +impl sp_std::ops::Sub for Id { + type Output = Self; + + fn sub(self, other: u32) -> Self { + Self(self.0 - other) + } +} + +#[derive( + Clone, Copy, Default, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, TypeInfo, +)] +pub struct Sibling(pub Id); + +impl From for Sibling { + fn from(i: Id) -> Self { + Self(i) + } +} + +impl From for Id { + fn from(i: Sibling) -> Self { + i.0 + } +} + +impl AsRef for Sibling { + fn as_ref(&self) -> &Id { + &self.0 + } +} + +impl TypeId for Sibling { + const TYPE_ID: [u8; 4] = *b"sibl"; +} + +impl From for u32 { + fn from(x: Sibling) -> Self { + x.0.into() + } +} + +impl From for Sibling { + fn from(x: u32) -> Self { + Sibling(x.into()) + } +} + +impl IsSystem for Sibling { + fn is_system(&self) -> bool { + IsSystem::is_system(&self.0) + } +} + +/// A type that uniquely identifies an HRMP channel. An HRMP channel is established between two +/// paras. In text, we use the notation `(A, B)` to specify a channel between A and B. The channels +/// are unidirectional, meaning that `(A, B)` and `(B, A)` refer to different channels. The +/// convention is that we use the first item tuple for the sender and the second for the recipient. +/// Only one channel is allowed between two participants in one direction, i.e. there cannot be 2 +/// different channels identified by `(A, B)`. A channel with the same para id in sender and +/// recipient is invalid. That is, however, not enforced. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct HrmpChannelId { + /// The para that acts as the sender in this channel. + pub sender: Id, + /// The para that acts as the recipient in this channel. + pub recipient: Id, +} + +impl HrmpChannelId { + /// Returns true if the given id corresponds to either the sender or the recipient. + pub fn is_participant(&self, id: Id) -> bool { + id == self.sender || id == self.recipient + } +} + +/// A message from a parachain to its Relay Chain. +pub type UpwardMessage = Vec; + +/// Something that should be called when a downward message is received. +pub trait DmpMessageHandler { + /// Handle some incoming DMP messages (note these are individual XCM messages). + /// + /// Also, process messages up to some `max_weight`. + fn handle_dmp_messages( + iter: impl Iterator)>, + max_weight: Weight, + ) -> Weight; +} +impl DmpMessageHandler for () { + fn handle_dmp_messages( + iter: impl Iterator)>, + _max_weight: Weight, + ) -> Weight { + iter.for_each(drop); + Weight::zero() + } +} + +/// The aggregate XCMP message format. +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] +pub enum XcmpMessageFormat { + /// Encoded `VersionedXcm` messages, all concatenated. + ConcatenatedVersionedXcm, + /// Encoded `Vec` messages, all concatenated. + ConcatenatedEncodedBlob, + /// One or more channel control signals; these should be interpreted immediately upon receipt + /// from the relay-chain. + Signals, +} + +/// Something that should be called for each batch of messages received over XCMP. +pub trait XcmpMessageHandler { + /// Handle some incoming XCMP messages (note these are the big one-per-block aggregate + /// messages). + /// + /// Also, process messages up to some `max_weight`. + fn handle_xcmp_messages<'a, I: Iterator>( + iter: I, + max_weight: Weight, + ) -> Weight; +} +impl XcmpMessageHandler for () { + fn handle_xcmp_messages<'a, I: Iterator>( + iter: I, + _max_weight: Weight, + ) -> Weight { + for _ in iter {} + Weight::zero() + } +} + +/// Validation parameters for evaluating the parachain validity function. +// TODO: balance downloads (https://github.com/paritytech/polkadot/issues/220) +#[derive(PartialEq, Eq, Decode, Clone)] +#[cfg_attr(feature = "std", derive(Debug, Encode))] +pub struct ValidationParams { + /// Previous head-data. + pub parent_head: HeadData, + /// The collation body. + pub block_data: BlockData, + /// The current relay-chain block number. + pub relay_parent_number: RelayChainBlockNumber, + /// The relay-chain block's storage root. + pub relay_parent_storage_root: Hash, +} + +/// Maximum number of HRMP messages allowed per candidate. +/// +/// We also use this as a generous limit, which still prevents possible memory exhaustion, from +/// malicious parachains that may otherwise return a huge amount of messages in `ValidationResult`. +pub const MAX_HORIZONTAL_MESSAGE_NUM: u32 = 16 * 1024; +/// Maximum number of UMP messages allowed per candidate. +/// +/// We also use this as a generous limit, which still prevents possible memory exhaustion, from +/// malicious parachains that may otherwise return a huge amount of messages in `ValidationResult`. +pub const MAX_UPWARD_MESSAGE_NUM: u32 = 16 * 1024; + +pub type UpwardMessages = BoundedVec>; + +pub type HorizontalMessages = + BoundedVec, ConstU32>; + +/// The result of parachain validation. +// TODO: balance uploads (https://github.com/paritytech/polkadot/issues/220) +#[derive(PartialEq, Eq, Clone, Encode)] +#[cfg_attr(feature = "std", derive(Debug, Decode))] +pub struct ValidationResult { + /// New head data that should be included in the relay chain state. + pub head_data: HeadData, + /// An update to the validation code that should be scheduled in the relay chain. + pub new_validation_code: Option, + /// Upward messages send by the Parachain. + pub upward_messages: UpwardMessages, + /// Outbound horizontal messages sent by the parachain. + pub horizontal_messages: HorizontalMessages, + /// Number of downward messages that were processed by the Parachain. + /// + /// It is expected that the Parachain processes them from first to last. + pub processed_downward_messages: u32, + /// The mark which specifies the block number up to which all inbound HRMP messages are + /// processed. + pub hrmp_watermark: RelayChainBlockNumber, +} diff --git a/polkadot/parachain/src/wasm_api.rs b/polkadot/parachain/src/wasm_api.rs new file mode 100644 index 0000000000000000000000000000000000000000..981d276af75ca5e06cfb108045d51eeb8cd6e99e --- /dev/null +++ b/polkadot/parachain/src/wasm_api.rs @@ -0,0 +1,37 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Utilities for writing parachain WASM. + +/// Load the validation params from memory when implementing a Rust parachain. +/// +/// Offset and length must have been provided by the validation +/// function's entry point. +#[cfg(not(feature = "std"))] +pub unsafe fn load_params(params: *const u8, len: usize) -> crate::primitives::ValidationParams { + let mut slice = sp_std::slice::from_raw_parts(params, len); + + parity_scale_codec::Decode::decode(&mut slice).expect("Invalid input data") +} + +/// Allocate the validation result in memory, getting the return-pointer back. +/// +/// As described in the crate docs, this is a pointer to the appended length +/// of the vector. +#[cfg(not(feature = "std"))] +pub fn write_result(result: &crate::primitives::ValidationResult) -> u64 { + sp_core::to_substrate_wasm_fn_return_value(&result) +} diff --git a/polkadot/parachain/test-parachains/.gitignore b/polkadot/parachain/test-parachains/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2c96eb1b6517f2617f9ddeae9f07f5fd7bd7ddef --- /dev/null +++ b/polkadot/parachain/test-parachains/.gitignore @@ -0,0 +1,2 @@ +target/ +Cargo.lock diff --git a/polkadot/parachain/test-parachains/Cargo.toml b/polkadot/parachain/test-parachains/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..a3fa882e1f4c2325fce7575cded9f771d3d87660 --- /dev/null +++ b/polkadot/parachain/test-parachains/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "test-parachains" +description = "Integration tests using the test-parachains" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +publish = false + +[dependencies] +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } + +adder = { package = "test-parachain-adder", path = "adder" } +halt = { package = "test-parachain-halt", path = "halt" } + +[dev-dependencies] +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = ["std"] +std = ["adder/std", "halt/std"] diff --git a/polkadot/parachain/test-parachains/README.md b/polkadot/parachain/test-parachains/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2c708bd543185744506bf559baa18d83003bb7d3 --- /dev/null +++ b/polkadot/parachain/test-parachains/README.md @@ -0,0 +1,3 @@ +# Test Parachains + +Each parachain consists of three parts: a `#![no_std]` library with the main execution logic, a WASM crate which wraps this logic, and a collator node. diff --git a/polkadot/parachain/test-parachains/adder/Cargo.toml b/polkadot/parachain/test-parachains/adder/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..d2b2224328a7f29efff13f718baffa157a5edd02 --- /dev/null +++ b/polkadot/parachain/test-parachains/adder/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "test-parachain-adder" +description = "Test parachain which adds to a number as its state transition" +build = "build.rs" +edition.workspace = true +license.workspace = true +version.workspace = true +authors.workspace = true +publish = false + +[dependencies] +parachain = { package = "polkadot-parachain", path = "../../", default-features = false, features = [ "wasm-api" ] } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +dlmalloc = { version = "0.2.4", features = [ "global" ] } + +# We need to make sure the global allocator is disabled until we have support of full substrate externalities +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = [ "disable_allocator" ] } + +[build-dependencies] +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = [ "std" ] +std = [ + "parachain/std", + "sp-std/std", +] diff --git a/polkadot/parachain/test-parachains/adder/build.rs b/polkadot/parachain/test-parachains/adder/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..6bb34ead1b861fada1b2cc61c605b76a8732b486 --- /dev/null +++ b/polkadot/parachain/test-parachains/adder/build.rs @@ -0,0 +1,25 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .export_heap_base() + .disable_runtime_version_section_check() + .build() +} diff --git a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5d309cfa319532e4e5d49035a8023064935b3917 --- /dev/null +++ b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml @@ -0,0 +1,57 @@ +[package] +name = "test-parachain-adder-collator" +description = "Collator for the adder test parachain" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[[bin]] +name = "adder-collator" +path = "src/main.rs" + +[[bin]] +name = "adder_collator_puppet_worker" +path = "bin/puppet_worker.rs" +required-features = ["test-utils"] + +[dependencies] +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +clap = { version = "4.0.9", features = ["derive"] } +futures = "0.3.21" +futures-timer = "3.0.2" +log = "0.4.17" + +test-parachain-adder = { path = ".." } +polkadot-primitives = { path = "../../../../primitives" } +polkadot-cli = { path = "../../../../cli" } +polkadot-service = { path = "../../../../node/service", features = ["rococo-native"] } +polkadot-node-primitives = { path = "../../../../node/primitives" } +polkadot-node-subsystem = { path = "../../../../node/subsystem" } + +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +# This one is tricky. Even though it is not used directly by the collator, we still need it for the +# `puppet_worker` binary, which is required for the integration test. However, this shouldn't be +# a big problem since it is used transitively anyway. +polkadot-node-core-pvf = { path = "../../../../node/core/pvf", features = ["test-utils"], optional = true } + +[dev-dependencies] +polkadot-parachain = { path = "../../.." } +polkadot-test-service = { path = "../../../../node/test/service" } + +substrate-test-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +# For the puppet worker, depend on ourselves with the test-utils feature. +test-parachain-adder-collator = { path = ".", features = ["test-utils"] } + +tokio = { version = "1.24.2", features = ["macros"] } + +[features] +network-protocol-staging = ["polkadot-cli/network-protocol-staging"] +# This feature is used to export test code to other crates without putting it in the production build. +# This is also used by the `puppet_worker` binary. +test-utils = ["polkadot-node-core-pvf/test-utils"] diff --git a/polkadot/parachain/test-parachains/adder/collator/README.md b/polkadot/parachain/test-parachains/adder/collator/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a1378544c386f9fb3edb1f3be3e9675a4c61acc7 --- /dev/null +++ b/polkadot/parachain/test-parachains/adder/collator/README.md @@ -0,0 +1,25 @@ +# How to run this collator + +First, build Polkadot: + +```sh +cargo build --release +``` + +Then start two validators that will run for the relay chain: + +```sh +cargo run --release -- -d alice --chain rococo-local --validator --alice --port 50551 +cargo run --release -- -d bob --chain rococo-local --validator --bob --port 50552 +``` + +Next start the collator that will collate for the adder parachain: + +```sh +cargo run --release -p test-parachain-adder-collator -- --tmp --chain rococo-local --port 50553 +``` + +The last step is to register the parachain using polkadot-js. The parachain id is +100. The genesis state and the validation code are printed at startup by the collator. + +To do this automatically, run `scripts/adder-collator.sh`. diff --git a/polkadot/parachain/test-parachains/adder/collator/bin/puppet_worker.rs b/polkadot/parachain/test-parachains/adder/collator/bin/puppet_worker.rs new file mode 100644 index 0000000000000000000000000000000000000000..7f93519d845400684a8e3a044ea5ecac50566ac5 --- /dev/null +++ b/polkadot/parachain/test-parachains/adder/collator/bin/puppet_worker.rs @@ -0,0 +1,17 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +polkadot_node_core_pvf::decl_puppet_worker_main!(); diff --git a/polkadot/parachain/test-parachains/adder/collator/src/cli.rs b/polkadot/parachain/test-parachains/adder/collator/src/cli.rs new file mode 100644 index 0000000000000000000000000000000000000000..9a865d75b606663b00c51054418582c0280448e7 --- /dev/null +++ b/polkadot/parachain/test-parachains/adder/collator/src/cli.rs @@ -0,0 +1,108 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot CLI library. + +use clap::Parser; +use sc_cli::SubstrateCli; + +/// Sub-commands supported by the collator. +#[derive(Debug, Parser)] +pub enum Subcommand { + /// Export the genesis state of the parachain. + #[command(name = "export-genesis-state")] + ExportGenesisState(ExportGenesisStateCommand), + + /// Export the genesis wasm of the parachain. + #[command(name = "export-genesis-wasm")] + ExportGenesisWasm(ExportGenesisWasmCommand), +} + +/// Command for exporting the genesis state of the parachain +#[derive(Debug, Parser)] +pub struct ExportGenesisStateCommand {} + +/// Command for exporting the genesis wasm file. +#[derive(Debug, Parser)] +pub struct ExportGenesisWasmCommand {} + +#[allow(missing_docs)] +#[derive(Debug, Parser)] +#[group(skip)] +pub struct RunCmd { + #[allow(missing_docs)] + #[clap(flatten)] + pub base: sc_cli::RunCmd, + + /// Id of the parachain this collator collates for. + #[arg(long)] + pub parachain_id: Option, +} + +#[allow(missing_docs)] +#[derive(Debug, Parser)] +pub struct Cli { + #[command(subcommand)] + pub subcommand: Option, + + #[clap(flatten)] + pub run: RunCmd, +} + +impl SubstrateCli for Cli { + fn impl_name() -> String { + "Parity Polkadot".into() + } + + fn impl_version() -> String { + "0.0.0".into() + } + + fn description() -> String { + env!("CARGO_PKG_DESCRIPTION").into() + } + + fn author() -> String { + env!("CARGO_PKG_AUTHORS").into() + } + + fn support_url() -> String { + "https://github.com/paritytech/polkadot/issues/new".into() + } + + fn copyright_start_year() -> i32 { + 2017 + } + + fn executable_name() -> String { + "adder-collator".into() + } + + fn load_spec(&self, id: &str) -> std::result::Result, String> { + let id = if id.is_empty() { "rococo" } else { id }; + Ok(match id { + "rococo-staging" => + Box::new(polkadot_service::chain_spec::rococo_staging_testnet_config()?), + "rococo-local" => + Box::new(polkadot_service::chain_spec::rococo_local_testnet_config()?), + "rococo" => Box::new(polkadot_service::chain_spec::rococo_config()?), + path => { + let path = std::path::PathBuf::from(path); + Box::new(polkadot_service::RococoChainSpec::from_json_file(path)?) + }, + }) + } +} diff --git a/polkadot/parachain/test-parachains/adder/collator/src/lib.rs b/polkadot/parachain/test-parachains/adder/collator/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..1ac561dda2bad6b889976fa8ab3ce50c34d07ff4 --- /dev/null +++ b/polkadot/parachain/test-parachains/adder/collator/src/lib.rs @@ -0,0 +1,339 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Collator for the adder test parachain. + +use futures::channel::oneshot; +use futures_timer::Delay; +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_primitives::{ + Collation, CollationResult, CollationSecondedSignal, CollatorFn, MaybeCompressedPoV, PoV, + Statement, +}; +use polkadot_primitives::{CollatorId, CollatorPair}; +use sp_core::{traits::SpawnNamed, Pair}; +use std::{ + collections::HashMap, + sync::{ + atomic::{AtomicU32, Ordering}, + Arc, Mutex, + }, + time::Duration, +}; +use test_parachain_adder::{execute, hash_state, BlockData, HeadData}; + +/// The amount we add when producing a new block. +/// +/// This is a constant to make tests easily reproducible. +const ADD: u64 = 2; + +/// Calculates the head and state for the block with the given `number`. +fn calculate_head_and_state_for_number(number: u64) -> (HeadData, u64) { + let mut head = + HeadData { number: 0, parent_hash: Default::default(), post_state: hash_state(0) }; + + let mut state = 0u64; + + while head.number < number { + let block = BlockData { state, add: ADD }; + head = execute(head.hash(), head.clone(), &block).expect("Produces valid block"); + state = state.wrapping_add(ADD); + } + + (head, state) +} + +/// The state of the adder parachain. +struct State { + head_to_state: HashMap, u64>, + number_to_head: HashMap>, + /// Block number of the best block. + best_block: u64, +} + +impl State { + /// Init the genesis state. + fn genesis() -> Self { + let genesis_state = Arc::new(calculate_head_and_state_for_number(0).0); + + Self { + head_to_state: vec![(genesis_state.clone(), 0)].into_iter().collect(), + number_to_head: vec![(0, genesis_state)].into_iter().collect(), + best_block: 0, + } + } + + /// Advance the state and produce a new block based on the given `parent_head`. + /// + /// Returns the new [`BlockData`] and the new [`HeadData`]. + fn advance(&mut self, parent_head: HeadData) -> (BlockData, HeadData) { + self.best_block = parent_head.number; + + let block = BlockData { + state: self + .head_to_state + .get(&parent_head) + .copied() + .unwrap_or_else(|| calculate_head_and_state_for_number(parent_head.number).1), + add: ADD, + }; + + let new_head = + execute(parent_head.hash(), parent_head, &block).expect("Produces valid block"); + + let new_head_arc = Arc::new(new_head.clone()); + self.head_to_state.insert(new_head_arc.clone(), block.state.wrapping_add(ADD)); + self.number_to_head.insert(new_head.number, new_head_arc); + + (block, new_head) + } +} + +/// The collator of the adder parachain. +pub struct Collator { + state: Arc>, + key: CollatorPair, + seconded_collations: Arc, +} + +impl Collator { + /// Create a new collator instance with the state initialized as genesis. + pub fn new() -> Self { + Self { + state: Arc::new(Mutex::new(State::genesis())), + key: CollatorPair::generate().0, + seconded_collations: Arc::new(AtomicU32::new(0)), + } + } + + /// Get the SCALE encoded genesis head of the adder parachain. + pub fn genesis_head(&self) -> Vec { + self.state + .lock() + .unwrap() + .number_to_head + .get(&0) + .expect("Genesis header exists") + .encode() + } + + /// Get the validation code of the adder parachain. + pub fn validation_code(&self) -> &[u8] { + test_parachain_adder::wasm_binary_unwrap() + } + + /// Get the collator key. + pub fn collator_key(&self) -> CollatorPair { + self.key.clone() + } + + /// Get the collator id. + pub fn collator_id(&self) -> CollatorId { + self.key.public() + } + + /// Create the collation function. + /// + /// This collation function can be plugged into the overseer to generate collations for the + /// adder parachain. + pub fn create_collation_function( + &self, + spawner: impl SpawnNamed + Clone + 'static, + ) -> CollatorFn { + use futures::FutureExt as _; + + let state = self.state.clone(); + let seconded_collations = self.seconded_collations.clone(); + + Box::new(move |relay_parent, validation_data| { + let parent = HeadData::decode(&mut &validation_data.parent_head.0[..]) + .expect("Decodes parent head"); + + let (block_data, head_data) = state.lock().unwrap().advance(parent); + + log::info!( + "created a new collation on relay-parent({}): {:?}", + relay_parent, + block_data, + ); + + let pov = PoV { block_data: block_data.encode().into() }; + + let collation = Collation { + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + head_data: head_data.encode().into(), + proof_of_validity: MaybeCompressedPoV::Raw(pov.clone()), + processed_downward_messages: 0, + hrmp_watermark: validation_data.relay_parent_number, + }; + + let compressed_pov = polkadot_node_primitives::maybe_compress_pov(pov); + + let (result_sender, recv) = oneshot::channel::(); + let seconded_collations = seconded_collations.clone(); + spawner.spawn( + "adder-collator-seconded", + None, + async move { + if let Ok(res) = recv.await { + if !matches!( + res.statement.payload(), + Statement::Seconded(s) if s.descriptor.pov_hash == compressed_pov.hash(), + ) { + log::error!( + "Seconded statement should match our collation: {:?}", + res.statement.payload() + ); + std::process::exit(-1); + } + + seconded_collations.fetch_add(1, Ordering::Relaxed); + } + } + .boxed(), + ); + + async move { Some(CollationResult { collation, result_sender: Some(result_sender) }) } + .boxed() + }) + } + + /// Wait until `blocks` are built and enacted. + pub async fn wait_for_blocks(&self, blocks: u64) { + let start_block = self.state.lock().unwrap().best_block; + loop { + Delay::new(Duration::from_secs(1)).await; + + let current_block = self.state.lock().unwrap().best_block; + + if start_block + blocks <= current_block { + return + } + } + } + + /// Wait until `seconded` collations of this collator are seconded by a parachain validator. + /// + /// The internal counter isn't de-duplicating the collations when counting the number of + /// seconded collations. This means when one collation is seconded by X validators, we record X + /// seconded messages. + pub async fn wait_for_seconded_collations(&self, seconded: u32) { + let seconded_collations = self.seconded_collations.clone(); + loop { + Delay::new(Duration::from_secs(1)).await; + + if seconded <= seconded_collations.load(Ordering::Relaxed) { + return + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use futures::executor::block_on; + use polkadot_parachain::primitives::{ValidationParams, ValidationResult}; + use polkadot_primitives::PersistedValidationData; + + #[test] + fn collator_works() { + let spawner = sp_core::testing::TaskExecutor::new(); + let collator = Collator::new(); + let collation_function = collator.create_collation_function(spawner); + + for i in 0..5 { + let parent_head = + collator.state.lock().unwrap().number_to_head.get(&i).unwrap().clone(); + + let validation_data = PersistedValidationData { + parent_head: parent_head.encode().into(), + ..Default::default() + }; + + let collation = + block_on(collation_function(Default::default(), &validation_data)).unwrap(); + validate_collation(&collator, (*parent_head).clone(), collation.collation); + } + } + + fn validate_collation(collator: &Collator, parent_head: HeadData, collation: Collation) { + use polkadot_node_core_pvf::testing::validate_candidate; + + let block_data = match collation.proof_of_validity { + MaybeCompressedPoV::Raw(pov) => pov.block_data, + MaybeCompressedPoV::Compressed(_) => panic!("Only works with uncompressed povs"), + }; + + let ret_buf = validate_candidate( + collator.validation_code(), + &ValidationParams { + parent_head: parent_head.encode().into(), + block_data, + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + } + .encode(), + ) + .unwrap(); + let ret = ValidationResult::decode(&mut &ret_buf[..]).unwrap(); + + let new_head = HeadData::decode(&mut &ret.head_data.0[..]).unwrap(); + assert_eq!( + **collator + .state + .lock() + .unwrap() + .number_to_head + .get(&(parent_head.number + 1)) + .unwrap(), + new_head + ); + } + + #[test] + fn advance_to_state_when_parent_head_is_missing() { + let collator = Collator::new(); + + let mut head = calculate_head_and_state_for_number(10).0; + + for i in 1..10 { + head = collator.state.lock().unwrap().advance(head).1; + assert_eq!(10 + i, head.number); + } + + let collator = Collator::new(); + let mut second_head = collator + .state + .lock() + .unwrap() + .number_to_head + .get(&0) + .cloned() + .unwrap() + .as_ref() + .clone(); + + for _ in 1..20 { + second_head = collator.state.lock().unwrap().advance(second_head.clone()).1; + } + + assert_eq!(second_head, head); + } +} diff --git a/polkadot/parachain/test-parachains/adder/collator/src/main.rs b/polkadot/parachain/test-parachains/adder/collator/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..dfaa1973206c24b27f87cec591bd249c83754e43 --- /dev/null +++ b/polkadot/parachain/test-parachains/adder/collator/src/main.rs @@ -0,0 +1,117 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Collator for the adder test parachain. + +use polkadot_cli::{Error, Result}; +use polkadot_node_primitives::CollationGenerationConfig; +use polkadot_node_subsystem::messages::{CollationGenerationMessage, CollatorProtocolMessage}; +use polkadot_primitives::Id as ParaId; +use sc_cli::{Error as SubstrateCliError, SubstrateCli}; +use sp_core::hexdisplay::HexDisplay; +use test_parachain_adder_collator::Collator; + +/// The parachain ID to collate for in case it wasn't set explicitly through CLI. +const DEFAULT_PARA_ID: ParaId = ParaId::new(100); + +mod cli; +use cli::Cli; + +fn main() -> Result<()> { + let cli = Cli::from_args(); + + match cli.subcommand { + Some(cli::Subcommand::ExportGenesisState(_params)) => { + let collator = Collator::new(); + println!("0x{:?}", HexDisplay::from(&collator.genesis_head())); + + Ok::<_, Error>(()) + }, + Some(cli::Subcommand::ExportGenesisWasm(_params)) => { + let collator = Collator::new(); + println!("0x{:?}", HexDisplay::from(&collator.validation_code())); + + Ok(()) + }, + None => { + let runner = cli.create_runner(&cli.run.base).map_err(|e| { + SubstrateCliError::Application( + Box::new(e) as Box<(dyn 'static + Send + Sync + std::error::Error)> + ) + })?; + + runner.run_node_until_exit(|config| async move { + let collator = Collator::new(); + + let full_node = polkadot_service::build_full( + config, + polkadot_service::NewFullParams { + is_parachain_node: polkadot_service::IsParachainNode::Collator( + collator.collator_key(), + ), + grandpa_pause: None, + enable_beefy: false, + jaeger_agent: None, + telemetry_worker_handle: None, + + // Collators don't spawn PVF workers, so we can disable version checks. + node_version: None, + workers_path: None, + workers_names: None, + + overseer_gen: polkadot_service::RealOverseerGen, + overseer_message_channel_capacity_override: None, + malus_finality_delay: None, + hwbench: None, + }, + ) + .map_err(|e| e.to_string())?; + let mut overseer_handle = full_node + .overseer_handle + .expect("Overseer handle should be initialized for collators"); + + let genesis_head_hex = + format!("0x{:?}", HexDisplay::from(&collator.genesis_head())); + let validation_code_hex = + format!("0x{:?}", HexDisplay::from(&collator.validation_code())); + + let para_id = cli.run.parachain_id.map(ParaId::from).unwrap_or(DEFAULT_PARA_ID); + + log::info!("Running adder collator for parachain id: {}", para_id); + log::info!("Genesis state: {}", genesis_head_hex); + log::info!("Validation code: {}", validation_code_hex); + + let config = CollationGenerationConfig { + key: collator.collator_key(), + collator: Some( + collator.create_collation_function(full_node.task_manager.spawn_handle()), + ), + para_id, + }; + overseer_handle + .send_msg(CollationGenerationMessage::Initialize(config), "Collator") + .await; + + overseer_handle + .send_msg(CollatorProtocolMessage::CollateOn(para_id), "Collator") + .await; + + Ok(full_node.task_manager) + }) + }, + }?; + Ok(()) +} diff --git a/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs b/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs new file mode 100644 index 0000000000000000000000000000000000000000..b891b29db59c1b82cbc658f583274557329345fd --- /dev/null +++ b/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs @@ -0,0 +1,88 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Integration test that ensures that we can build and include parachain +//! blocks of the adder parachain. + +const PUPPET_EXE: &str = env!("CARGO_BIN_EXE_adder_collator_puppet_worker"); + +// If this test is failing, make sure to run all tests with the `real-overseer` feature being +// enabled. + +#[substrate_test_utils::test(flavor = "multi_thread")] +async fn collating_using_adder_collator() { + use polkadot_primitives::Id as ParaId; + use sp_keyring::AccountKeyring::*; + + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_colors(false); + builder.init().expect("Set up logger"); + + let para_id = ParaId::from(100); + + let alice_config = polkadot_test_service::node_config( + || {}, + tokio::runtime::Handle::current(), + Alice, + Vec::new(), + true, + ); + + // start alice + let alice = polkadot_test_service::run_validator_node(alice_config, Some(PUPPET_EXE.into())); + + let bob_config = polkadot_test_service::node_config( + || {}, + tokio::runtime::Handle::current(), + Bob, + vec![alice.addr.clone()], + true, + ); + + // start bob + let bob = polkadot_test_service::run_validator_node(bob_config, Some(PUPPET_EXE.into())); + + let collator = test_parachain_adder_collator::Collator::new(); + + // register parachain + alice + .register_parachain(para_id, collator.validation_code().to_vec(), collator.genesis_head()) + .await + .unwrap(); + + // run the collator node + let mut charlie = polkadot_test_service::run_collator_node( + tokio::runtime::Handle::current(), + Charlie, + || {}, + vec![alice.addr.clone(), bob.addr.clone()], + collator.collator_key(), + ); + + charlie + .register_collator( + collator.collator_key(), + para_id, + collator.create_collation_function(charlie.task_manager.spawn_handle()), + ) + .await; + + // Wait until the parachain has 4 blocks produced. + collator.wait_for_blocks(4).await; + + // Wait until the collator received `12` seconded statements for its collations. + collator.wait_for_seconded_collations(12).await; +} diff --git a/polkadot/parachain/test-parachains/adder/src/lib.rs b/polkadot/parachain/test-parachains/adder/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..4cf1ba8ac971df98142bc04d5deee1add1334fbd --- /dev/null +++ b/polkadot/parachain/test-parachains/adder/src/lib.rs @@ -0,0 +1,102 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Basic parachain that adds a number as part of its state. + +#![no_std] + +use parity_scale_codec::{Decode, Encode}; +use tiny_keccak::{Hasher as _, Keccak}; + +#[cfg(not(feature = "std"))] +mod wasm_validation; + +#[cfg(not(feature = "std"))] +#[global_allocator] +static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc; + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +fn keccak256(input: &[u8]) -> [u8; 32] { + let mut out = [0u8; 32]; + let mut keccak256 = Keccak::v256(); + keccak256.update(input); + keccak256.finalize(&mut out); + out +} + +/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. +#[cfg(feature = "std")] +pub fn wasm_binary_unwrap() -> &'static [u8] { + WASM_BINARY.expect( + "Development wasm binary is not available. Testing is only \ + supported with the flag disabled.", + ) +} + +/// Head data for this parachain. +#[derive(Default, Clone, Hash, Eq, PartialEq, Encode, Decode, Debug)] +pub struct HeadData { + /// Block number + pub number: u64, + /// parent block keccak256 + pub parent_hash: [u8; 32], + /// hash of post-execution state. + pub post_state: [u8; 32], +} + +impl HeadData { + pub fn hash(&self) -> [u8; 32] { + keccak256(&self.encode()) + } +} + +/// Block data for this parachain. +#[derive(Default, Clone, Encode, Decode, Debug)] +pub struct BlockData { + /// State to begin from. + pub state: u64, + /// Amount to add (wrapping) + pub add: u64, +} + +pub fn hash_state(state: u64) -> [u8; 32] { + keccak256(state.encode().as_slice()) +} + +/// Start state mismatched with parent header's state hash. +#[derive(Debug)] +pub struct StateMismatch; + +/// Execute a block body on top of given parent head, producing new parent head +/// if valid. +pub fn execute( + parent_hash: [u8; 32], + parent_head: HeadData, + block_data: &BlockData, +) -> Result { + assert_eq!(parent_hash, parent_head.hash()); + + if hash_state(block_data.state) != parent_head.post_state { + return Err(StateMismatch) + } + + let new_state = block_data.state.wrapping_add(block_data.add); + + Ok(HeadData { number: parent_head.number + 1, parent_hash, post_state: hash_state(new_state) }) +} diff --git a/polkadot/parachain/test-parachains/adder/src/wasm_validation.rs b/polkadot/parachain/test-parachains/adder/src/wasm_validation.rs new file mode 100644 index 0000000000000000000000000000000000000000..048330437cd7bb4b24e1dc4e1ae3d20c9ea18b65 --- /dev/null +++ b/polkadot/parachain/test-parachains/adder/src/wasm_validation.rs @@ -0,0 +1,47 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! WASM validation for adder parachain. + +use crate::{BlockData, HeadData}; +use core::panic; +use parachain::primitives::{HeadData as GenericHeadData, ValidationResult}; +use parity_scale_codec::{Decode, Encode}; +use sp_std::vec::Vec; + +#[no_mangle] +pub extern "C" fn validate_block(params: *const u8, len: usize) -> u64 { + let params = unsafe { parachain::load_params(params, len) }; + let parent_head = + HeadData::decode(&mut ¶ms.parent_head.0[..]).expect("invalid parent head format."); + + let block_data = + BlockData::decode(&mut ¶ms.block_data.0[..]).expect("invalid block data format."); + + let parent_hash = crate::keccak256(¶ms.parent_head.0[..]); + + let new_head = crate::execute(parent_hash, parent_head, &block_data).expect("Executes block"); + parachain::write_result(&ValidationResult { + head_data: GenericHeadData(new_head.encode()), + new_validation_code: None, + upward_messages: sp_std::vec::Vec::new().try_into().expect("empty vec fits into bounds"), + horizontal_messages: sp_std::vec::Vec::new() + .try_into() + .expect("empty vec fits into bounds"), + processed_downward_messages: 0, + hrmp_watermark: params.relay_parent_number, + }) +} diff --git a/polkadot/parachain/test-parachains/halt/Cargo.toml b/polkadot/parachain/test-parachains/halt/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..85ee5d99d891dc74cedc3f3930ddde0824bad263 --- /dev/null +++ b/polkadot/parachain/test-parachains/halt/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "test-parachain-halt" +description = "Test parachain which executes forever" +build = "build.rs" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] + +[build-dependencies] +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } +rustversion = "1.0.6" + +[features] +default = [ "std" ] +std = [] diff --git a/polkadot/parachain/test-parachains/halt/build.rs b/polkadot/parachain/test-parachains/halt/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..cb3370c150d409a836ff1c001c20fbfba3300fce --- /dev/null +++ b/polkadot/parachain/test-parachains/halt/build.rs @@ -0,0 +1,37 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .export_heap_base() + .disable_runtime_version_section_check() + .build(); + + enable_alloc_error_handler(); +} + +#[rustversion::before(1.68)] +fn enable_alloc_error_handler() { + if !cfg!(feature = "std") { + println!("cargo:rustc-cfg=enable_alloc_error_handler"); + } +} + +#[rustversion::since(1.68)] +fn enable_alloc_error_handler() {} diff --git a/polkadot/parachain/test-parachains/halt/src/lib.rs b/polkadot/parachain/test-parachains/halt/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..47e7d199f0bc0eeb6a5c50fae1a933a843ed1794 --- /dev/null +++ b/polkadot/parachain/test-parachains/halt/src/lib.rs @@ -0,0 +1,53 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Basic parachain that executes forever. + +#![no_std] +#![cfg_attr(enable_alloc_error_handler, feature(alloc_error_handler))] + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +#[cfg(feature = "std")] +/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. +pub fn wasm_binary_unwrap() -> &'static [u8] { + WASM_BINARY.expect( + "Development wasm binary is not available. Testing is only \ + supported with the flag disabled.", + ) +} + +#[cfg(not(feature = "std"))] +#[panic_handler] +#[no_mangle] +pub fn panic(_info: &core::panic::PanicInfo) -> ! { + core::arch::wasm32::unreachable(); +} + +#[cfg(enable_alloc_error_handler)] +#[alloc_error_handler] +#[no_mangle] +pub fn oom(_: core::alloc::Layout) -> ! { + core::intrinsics::abort(); +} + +#[cfg(not(feature = "std"))] +#[no_mangle] +pub extern "C" fn validate_block(_params: *const u8, _len: usize) -> u64 { + loop {} +} diff --git a/polkadot/parachain/test-parachains/src/lib.rs b/polkadot/parachain/test-parachains/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..6d34be4d1a1aa7593050f3c5b17437bad39b4aa4 --- /dev/null +++ b/polkadot/parachain/test-parachains/src/lib.rs @@ -0,0 +1,17 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Stub - the fundamental logic of this crate is the integration tests. diff --git a/polkadot/parachain/test-parachains/undying/Cargo.toml b/polkadot/parachain/test-parachains/undying/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..030032e7754d61cb2c7a1fd7c38577e86b730318 --- /dev/null +++ b/polkadot/parachain/test-parachains/undying/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "test-parachain-undying" +description = "Test parachain for zombienet integration tests" +build = "build.rs" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +parachain = { package = "polkadot-parachain", path = "../../", default-features = false, features = [ "wasm-api" ] } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +dlmalloc = { version = "0.2.4", features = [ "global" ] } +log = { version = "0.4.17", default-features = false } + +# We need to make sure the global allocator is disabled until we have support of full substrate externalities +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = [ "disable_allocator" ] } + +[build-dependencies] +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = [ "std" ] +std = [ + "parachain/std", + "sp-std/std", +] diff --git a/polkadot/parachain/test-parachains/undying/build.rs b/polkadot/parachain/test-parachains/undying/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..6bb34ead1b861fada1b2cc61c605b76a8732b486 --- /dev/null +++ b/polkadot/parachain/test-parachains/undying/build.rs @@ -0,0 +1,25 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .export_heap_base() + .disable_runtime_version_section_check() + .build() +} diff --git a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..b0118555506c978d46beaa56ec72838ab930a103 --- /dev/null +++ b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml @@ -0,0 +1,56 @@ +[package] +name = "test-parachain-undying-collator" +description = "Collator for the undying test parachain" +edition.workspace = true +license.workspace = true +version.workspace = true +authors.workspace = true +publish = false + +[[bin]] +name = "undying-collator" +path = "src/main.rs" + +[[bin]] +name = "undying_collator_puppet_worker" +path = "bin/puppet_worker.rs" +required-features = ["test-utils"] + +[dependencies] +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +clap = { version = "4.0.9", features = ["derive"] } +futures = "0.3.19" +futures-timer = "3.0.2" +log = "0.4.17" + +test-parachain-undying = { path = ".." } +polkadot-primitives = { path = "../../../../primitives" } +polkadot-cli = { path = "../../../../cli" } +polkadot-service = { path = "../../../../node/service", features = ["rococo-native"] } +polkadot-node-primitives = { path = "../../../../node/primitives" } +polkadot-node-subsystem = { path = "../../../../node/subsystem" } + +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +# This one is tricky. Even though it is not used directly by the collator, we still need it for the +# `puppet_worker` binary, which is required for the integration test. However, this shouldn't be +# a big problem since it is used transitively anyway. +polkadot-node-core-pvf = { path = "../../../../node/core/pvf", features = ["test-utils"], optional = true } + +[dev-dependencies] +polkadot-parachain = { path = "../../.." } +polkadot-test-service = { path = "../../../../node/test/service" } +# For the puppet worker, depend on ourselves with the test-utils feature. +test-parachain-undying-collator = { path = ".", features = ["test-utils"] } + +substrate-test-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } + +tokio = { version = "1.24.2", features = ["macros"] } + +[features] +# This feature is used to export test code to other crates without putting it in the production build. +# This is also used by the `puppet_worker` binary. +test-utils = ["polkadot-node-core-pvf/test-utils"] diff --git a/polkadot/parachain/test-parachains/undying/collator/bin/puppet_worker.rs b/polkadot/parachain/test-parachains/undying/collator/bin/puppet_worker.rs new file mode 100644 index 0000000000000000000000000000000000000000..7f93519d845400684a8e3a044ea5ecac50566ac5 --- /dev/null +++ b/polkadot/parachain/test-parachains/undying/collator/bin/puppet_worker.rs @@ -0,0 +1,17 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +polkadot_node_core_pvf::decl_puppet_worker_main!(); diff --git a/polkadot/parachain/test-parachains/undying/collator/src/cli.rs b/polkadot/parachain/test-parachains/undying/collator/src/cli.rs new file mode 100644 index 0000000000000000000000000000000000000000..ab37fe20eebb466ea50b3bae9b0f82fb19814016 --- /dev/null +++ b/polkadot/parachain/test-parachains/undying/collator/src/cli.rs @@ -0,0 +1,130 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot CLI library. + +use clap::Parser; +use sc_cli::SubstrateCli; + +/// Sub-commands supported by the collator. +#[derive(Debug, Parser)] +pub enum Subcommand { + /// Export the genesis state of the parachain. + #[command(name = "export-genesis-state")] + ExportGenesisState(ExportGenesisStateCommand), + + /// Export the genesis wasm of the parachain. + #[command(name = "export-genesis-wasm")] + ExportGenesisWasm(ExportGenesisWasmCommand), +} + +/// Command for exporting the genesis state of the parachain +#[derive(Debug, Parser)] +pub struct ExportGenesisStateCommand { + /// Id of the parachain this collator collates for. + #[arg(long, default_value_t = 100)] + pub parachain_id: u32, + + /// The target raw PoV size in bytes. Minimum value is 64. + #[arg(long, default_value_t = 1024)] + pub pov_size: usize, + + /// The PVF execution complexity. Actually specifies how many iterations/signatures + /// we compute per block. + #[arg(long, default_value_t = 1)] + pub pvf_complexity: u32, +} + +/// Command for exporting the genesis wasm file. +#[derive(Debug, Parser)] +pub struct ExportGenesisWasmCommand {} + +#[allow(missing_docs)] +#[derive(Debug, Parser)] +#[group(skip)] +pub struct RunCmd { + #[allow(missing_docs)] + #[clap(flatten)] + pub base: sc_cli::RunCmd, + + /// Id of the parachain this collator collates for. + #[arg(long, default_value_t = 2000)] + pub parachain_id: u32, + + /// The target raw PoV size in bytes. Minimum value is 64. + #[arg(long, default_value_t = 1024)] + pub pov_size: usize, + + /// The PVF execution complexity. Actually specifies how many iterations/signatures + /// we compute per block. + #[arg(long, default_value_t = 1)] + pub pvf_complexity: u32, +} + +#[allow(missing_docs)] +#[derive(Debug, Parser)] +pub struct Cli { + #[command(subcommand)] + pub subcommand: Option, + + #[clap(flatten)] + pub run: RunCmd, +} + +impl SubstrateCli for Cli { + fn impl_name() -> String { + "Parity Zombienet/Undying".into() + } + + fn impl_version() -> String { + env!("CARGO_PKG_VERSION").into() + } + + fn description() -> String { + env!("CARGO_PKG_DESCRIPTION").into() + } + + fn author() -> String { + env!("CARGO_PKG_AUTHORS").into() + } + + fn support_url() -> String { + "https://github.com/paritytech/polkadot/issues/new".into() + } + + fn copyright_start_year() -> i32 { + 2022 + } + + fn executable_name() -> String { + "undying-collator".into() + } + + fn load_spec(&self, id: &str) -> std::result::Result, String> { + let id = if id.is_empty() { "rococo" } else { id }; + Ok(match id { + "rococo-staging" => + Box::new(polkadot_service::chain_spec::rococo_staging_testnet_config()?), + "rococo-local" => + Box::new(polkadot_service::chain_spec::rococo_local_testnet_config()?), + "rococo" => Box::new(polkadot_service::chain_spec::rococo_config()?), + path => { + let path = std::path::PathBuf::from(path); + Box::new(polkadot_service::RococoChainSpec::from_json_file(path)?) + }, + }) + } +} diff --git a/polkadot/parachain/test-parachains/undying/collator/src/lib.rs b/polkadot/parachain/test-parachains/undying/collator/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..e0ecc6b0997d76c39afacc661f05c5be564137e1 --- /dev/null +++ b/polkadot/parachain/test-parachains/undying/collator/src/lib.rs @@ -0,0 +1,429 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Collator for the `Undying` test parachain. + +use futures::channel::oneshot; +use futures_timer::Delay; +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_primitives::{ + maybe_compress_pov, Collation, CollationResult, CollationSecondedSignal, CollatorFn, + MaybeCompressedPoV, PoV, Statement, +}; +use polkadot_primitives::{CollatorId, CollatorPair, Hash}; +use sp_core::Pair; +use std::{ + collections::HashMap, + sync::{ + atomic::{AtomicU32, Ordering}, + Arc, Mutex, + }, + time::Duration, +}; +use test_parachain_undying::{ + execute, hash_state, BlockData, GraveyardState, HeadData, StateMismatch, +}; + +/// Default PoV size which also drives state size. +const DEFAULT_POV_SIZE: usize = 1000; +/// Default PVF time complexity - 1 signature per block. +const DEFAULT_PVF_COMPLEXITY: u32 = 1; + +/// Calculates the head and state for the block with the given `number`. +fn calculate_head_and_state_for_number( + number: u64, + graveyard_size: usize, + pvf_complexity: u32, +) -> Result<(HeadData, GraveyardState), StateMismatch> { + let index = 0u64; + let mut graveyard = vec![0u8; graveyard_size * graveyard_size]; + let zombies = 0; + let seal = [0u8; 32]; + + // Ensure a larger compressed PoV. + graveyard.iter_mut().enumerate().for_each(|(i, grave)| { + *grave = i as u8; + }); + + let mut state = GraveyardState { index, graveyard, zombies, seal }; + let mut head = + HeadData { number: 0, parent_hash: Hash::default().into(), post_state: hash_state(&state) }; + + while head.number < number { + let block = BlockData { state, tombstones: 1_000, iterations: pvf_complexity }; + let (new_head, new_state) = execute(head.hash(), head.clone(), block)?; + head = new_head; + state = new_state; + } + + Ok((head, state)) +} + +/// The state of the undying parachain. +struct State { + // We need to keep these around until the including relay chain blocks are finalized. + // This is because disputes can trigger reverts up to last finalized block, so we + // want that state to collate on older relay chain heads. + head_to_state: HashMap, GraveyardState>, + number_to_head: HashMap>, + /// Block number of the best block. + best_block: u64, + /// PVF time complexity. + pvf_complexity: u32, + /// Defines the state size (Vec). Our PoV includes the entire state so this value will + /// drive the PoV size. + /// Important note: block execution heavily clones this state, so something like 300.000 is + /// the max value here, otherwise we'll get OOM during wasm execution. + /// TODO: Implement a static state, and use `ballast` to inflate the PoV size. This way + /// we can just discard the `ballast` before processing the block. + graveyard_size: usize, +} + +impl State { + /// Init the genesis state. + fn genesis(graveyard_size: usize, pvf_complexity: u32) -> Self { + let index = 0u64; + let mut graveyard = vec![0u8; graveyard_size * graveyard_size]; + let zombies = 0; + let seal = [0u8; 32]; + + // Ensure a larger compressed PoV. + graveyard.iter_mut().enumerate().for_each(|(i, grave)| { + *grave = i as u8; + }); + + let state = GraveyardState { index, graveyard, zombies, seal }; + + let head_data = + HeadData { number: 0, parent_hash: Default::default(), post_state: hash_state(&state) }; + let head_data = Arc::new(head_data); + + Self { + head_to_state: vec![(head_data.clone(), state.clone())].into_iter().collect(), + number_to_head: vec![(0, head_data)].into_iter().collect(), + best_block: 0, + pvf_complexity, + graveyard_size, + } + } + + /// Advance the state and produce a new block based on the given `parent_head`. + /// + /// Returns the new [`BlockData`] and the new [`HeadData`]. + fn advance(&mut self, parent_head: HeadData) -> Result<(BlockData, HeadData), StateMismatch> { + self.best_block = parent_head.number; + + let state = if let Some(state) = self + .number_to_head + .get(&self.best_block) + .and_then(|head_data| self.head_to_state.get(head_data).cloned()) + { + state + } else { + let (_, state) = calculate_head_and_state_for_number( + parent_head.number, + self.graveyard_size, + self.pvf_complexity, + )?; + state + }; + + // Start with prev state and transaction to execute (place 1000 tombstones). + let block = BlockData { state, tombstones: 1000, iterations: self.pvf_complexity }; + + let (new_head, new_state) = execute(parent_head.hash(), parent_head, block.clone())?; + + let new_head_arc = Arc::new(new_head.clone()); + + self.head_to_state.insert(new_head_arc.clone(), new_state); + self.number_to_head.insert(new_head.number, new_head_arc); + + Ok((block, new_head)) + } +} + +/// The collator of the undying parachain. +pub struct Collator { + state: Arc>, + key: CollatorPair, + seconded_collations: Arc, +} + +impl Default for Collator { + fn default() -> Self { + Self::new(DEFAULT_POV_SIZE, DEFAULT_PVF_COMPLEXITY) + } +} + +impl Collator { + /// Create a new collator instance with the state initialized from genesis and `pov_size` + /// parameter. The same parameter needs to be passed when exporting the genesis state. + pub fn new(pov_size: usize, pvf_complexity: u32) -> Self { + let graveyard_size = ((pov_size / std::mem::size_of::()) as f64).sqrt().ceil() as usize; + + log::info!( + "PoV target size: {} bytes. Graveyard size: ({} x {})", + pov_size, + graveyard_size, + graveyard_size + ); + + log::info!("PVF time complexity: {}", pvf_complexity); + + Self { + state: Arc::new(Mutex::new(State::genesis(graveyard_size, pvf_complexity))), + key: CollatorPair::generate().0, + seconded_collations: Arc::new(AtomicU32::new(0)), + } + } + + /// Get the SCALE encoded genesis head of the parachain. + pub fn genesis_head(&self) -> Vec { + self.state + .lock() + .unwrap() + .number_to_head + .get(&0) + .expect("Genesis header exists") + .encode() + } + + /// Get the validation code of the undying parachain. + pub fn validation_code(&self) -> &[u8] { + test_parachain_undying::wasm_binary_unwrap() + } + + /// Get the collator key. + pub fn collator_key(&self) -> CollatorPair { + self.key.clone() + } + + /// Get the collator id. + pub fn collator_id(&self) -> CollatorId { + self.key.public() + } + + /// Create the collation function. + /// + /// This collation function can be plugged into the overseer to generate collations for the + /// undying parachain. + pub fn create_collation_function( + &self, + spawner: impl SpawnNamed + Clone + 'static, + ) -> CollatorFn { + use futures::FutureExt as _; + + let state = self.state.clone(); + let seconded_collations = self.seconded_collations.clone(); + + Box::new(move |relay_parent, validation_data| { + let parent = match HeadData::decode(&mut &validation_data.parent_head.0[..]) { + Err(err) => { + log::error!("Requested to build on top of malformed head-data: {:?}", err); + return futures::future::ready(None).boxed() + }, + Ok(p) => p, + }; + + let (block_data, head_data) = match state.lock().unwrap().advance(parent.clone()) { + Err(err) => { + log::error!("Unable to build on top of {:?}: {:?}", parent, err); + return futures::future::ready(None).boxed() + }, + Ok(x) => x, + }; + + log::info!( + "created a new collation on relay-parent({}): {:?}", + relay_parent, + head_data, + ); + + // The pov is the actually the initial state and the transactions. + let pov = PoV { block_data: block_data.encode().into() }; + + let collation = Collation { + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + head_data: head_data.encode().into(), + proof_of_validity: MaybeCompressedPoV::Raw(pov.clone()), + processed_downward_messages: 0, + hrmp_watermark: validation_data.relay_parent_number, + }; + + log::info!("Raw PoV size for collation: {} bytes", pov.block_data.0.len(),); + let compressed_pov = maybe_compress_pov(pov); + + log::info!( + "Compressed PoV size for collation: {} bytes", + compressed_pov.block_data.0.len(), + ); + + let (result_sender, recv) = oneshot::channel::(); + let seconded_collations = seconded_collations.clone(); + spawner.spawn( + "undying-collator-seconded", + None, + async move { + if let Ok(res) = recv.await { + if !matches!( + res.statement.payload(), + Statement::Seconded(s) if s.descriptor.pov_hash == compressed_pov.hash(), + ) { + log::error!( + "Seconded statement should match our collation: {:?}", + res.statement.payload() + ); + } + + seconded_collations.fetch_add(1, Ordering::Relaxed); + } + } + .boxed(), + ); + + async move { Some(CollationResult { collation, result_sender: Some(result_sender) }) } + .boxed() + }) + } + + /// Wait until `blocks` are built and enacted. + pub async fn wait_for_blocks(&self, blocks: u64) { + let start_block = self.state.lock().unwrap().best_block; + loop { + Delay::new(Duration::from_secs(1)).await; + + let current_block = self.state.lock().unwrap().best_block; + + if start_block + blocks <= current_block { + return + } + } + } + + /// Wait until `seconded` collations of this collator are seconded by a parachain validator. + /// + /// The internal counter isn't de-duplicating the collations when counting the number of + /// seconded collations. This means when one collation is seconded by X validators, we record X + /// seconded messages. + pub async fn wait_for_seconded_collations(&self, seconded: u32) { + let seconded_collations = self.seconded_collations.clone(); + loop { + Delay::new(Duration::from_secs(1)).await; + + if seconded <= seconded_collations.load(Ordering::Relaxed) { + return + } + } + } +} + +use sp_core::traits::SpawnNamed; + +#[cfg(test)] +mod tests { + use super::*; + use futures::executor::block_on; + use polkadot_parachain::primitives::{ValidationParams, ValidationResult}; + use polkadot_primitives::{Hash, PersistedValidationData}; + + #[test] + fn collator_works() { + let spawner = sp_core::testing::TaskExecutor::new(); + let collator = Collator::new(1_000, 1); + let collation_function = collator.create_collation_function(spawner); + + for i in 0..5 { + let parent_head = + collator.state.lock().unwrap().number_to_head.get(&i).unwrap().clone(); + + let validation_data = PersistedValidationData { + parent_head: parent_head.encode().into(), + ..Default::default() + }; + + let collation = + block_on(collation_function(Default::default(), &validation_data)).unwrap(); + validate_collation(&collator, (*parent_head).clone(), collation.collation); + } + } + + fn validate_collation(collator: &Collator, parent_head: HeadData, collation: Collation) { + use polkadot_node_core_pvf::testing::validate_candidate; + + let block_data = match collation.proof_of_validity { + MaybeCompressedPoV::Raw(pov) => pov.block_data, + MaybeCompressedPoV::Compressed(_) => panic!("Only works with uncompressed povs"), + }; + + let ret_buf = validate_candidate( + collator.validation_code(), + &ValidationParams { + parent_head: parent_head.encode().into(), + block_data, + relay_parent_number: 1, + relay_parent_storage_root: Hash::zero(), + } + .encode(), + ) + .unwrap(); + let ret = ValidationResult::decode(&mut &ret_buf[..]).unwrap(); + + let new_head = HeadData::decode(&mut &ret.head_data.0[..]).unwrap(); + assert_eq!( + **collator + .state + .lock() + .unwrap() + .number_to_head + .get(&(parent_head.number + 1)) + .unwrap(), + new_head + ); + } + + #[test] + fn advance_to_state_when_parent_head_is_missing() { + let collator = Collator::new(1_000, 1); + let graveyard_size = collator.state.lock().unwrap().graveyard_size; + + let mut head = calculate_head_and_state_for_number(10, graveyard_size, 1).unwrap().0; + + for i in 1..10 { + head = collator.state.lock().unwrap().advance(head).unwrap().1; + assert_eq!(10 + i, head.number); + } + + let collator = Collator::new(1_000, 1); + let mut second_head = collator + .state + .lock() + .unwrap() + .number_to_head + .get(&0) + .cloned() + .unwrap() + .as_ref() + .clone(); + + for _ in 1..20 { + second_head = collator.state.lock().unwrap().advance(second_head.clone()).unwrap().1; + } + + assert_eq!(second_head, head); + } +} diff --git a/polkadot/parachain/test-parachains/undying/collator/src/main.rs b/polkadot/parachain/test-parachains/undying/collator/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..e564e221f01376ff8b573ec6a1fd1f2937156f77 --- /dev/null +++ b/polkadot/parachain/test-parachains/undying/collator/src/main.rs @@ -0,0 +1,117 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Collator for the `Undying` test parachain. + +use polkadot_cli::{Error, Result}; +use polkadot_node_primitives::CollationGenerationConfig; +use polkadot_node_subsystem::messages::{CollationGenerationMessage, CollatorProtocolMessage}; +use polkadot_primitives::Id as ParaId; +use sc_cli::{Error as SubstrateCliError, SubstrateCli}; +use sp_core::hexdisplay::HexDisplay; +use test_parachain_undying_collator::Collator; + +mod cli; +use cli::Cli; + +fn main() -> Result<()> { + let cli = Cli::from_args(); + + match cli.subcommand { + Some(cli::Subcommand::ExportGenesisState(params)) => { + // `pov_size` and `pvf_complexity` need to match the ones that we start the collator + // with. + let collator = Collator::new(params.pov_size, params.pvf_complexity); + println!("0x{:?}", HexDisplay::from(&collator.genesis_head())); + + Ok::<_, Error>(()) + }, + Some(cli::Subcommand::ExportGenesisWasm(_params)) => { + // We pass some dummy values for `pov_size` and `pvf_complexity` as these don't + // matter for `wasm` export. + println!("0x{:?}", HexDisplay::from(&Collator::default().validation_code())); + + Ok(()) + }, + None => { + let runner = cli.create_runner(&cli.run.base).map_err(|e| { + SubstrateCliError::Application( + Box::new(e) as Box<(dyn 'static + Send + Sync + std::error::Error)> + ) + })?; + + runner.run_node_until_exit(|config| async move { + let collator = Collator::new(cli.run.pov_size, cli.run.pvf_complexity); + + let full_node = polkadot_service::build_full( + config, + polkadot_service::NewFullParams { + is_parachain_node: polkadot_service::IsParachainNode::Collator( + collator.collator_key(), + ), + grandpa_pause: None, + enable_beefy: false, + jaeger_agent: None, + telemetry_worker_handle: None, + + // Collators don't spawn PVF workers, so we can disable version checks. + node_version: None, + workers_path: None, + workers_names: None, + + overseer_gen: polkadot_service::RealOverseerGen, + overseer_message_channel_capacity_override: None, + malus_finality_delay: None, + hwbench: None, + }, + ) + .map_err(|e| e.to_string())?; + let mut overseer_handle = full_node + .overseer_handle + .expect("Overseer handle should be initialized for collators"); + + let genesis_head_hex = + format!("0x{:?}", HexDisplay::from(&collator.genesis_head())); + let validation_code_hex = + format!("0x{:?}", HexDisplay::from(&collator.validation_code())); + + let para_id = ParaId::from(cli.run.parachain_id); + + log::info!("Running `Undying` collator for parachain id: {}", para_id); + log::info!("Genesis state: {}", genesis_head_hex); + log::info!("Validation code: {}", validation_code_hex); + + let config = CollationGenerationConfig { + key: collator.collator_key(), + collator: Some( + collator.create_collation_function(full_node.task_manager.spawn_handle()), + ), + para_id, + }; + overseer_handle + .send_msg(CollationGenerationMessage::Initialize(config), "Collator") + .await; + + overseer_handle + .send_msg(CollatorProtocolMessage::CollateOn(para_id), "Collator") + .await; + + Ok(full_node.task_manager) + }) + }, + }?; + Ok(()) +} diff --git a/polkadot/parachain/test-parachains/undying/collator/tests/integration.rs b/polkadot/parachain/test-parachains/undying/collator/tests/integration.rs new file mode 100644 index 0000000000000000000000000000000000000000..21d174fb06c7166cf77a2d494db05c762532fb21 --- /dev/null +++ b/polkadot/parachain/test-parachains/undying/collator/tests/integration.rs @@ -0,0 +1,87 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Integration test that ensures that we can build and include parachain +//! blocks of the `Undying` parachain. + +const PUPPET_EXE: &str = env!("CARGO_BIN_EXE_undying_collator_puppet_worker"); + +// If this test is failing, make sure to run all tests with the `real-overseer` feature being +// enabled. +#[substrate_test_utils::test(flavor = "multi_thread")] +async fn collating_using_undying_collator() { + use polkadot_primitives::Id as ParaId; + use sp_keyring::AccountKeyring::*; + + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_colors(false); + builder.init().expect("Set up logger"); + + let para_id = ParaId::from(100); + + let alice_config = polkadot_test_service::node_config( + || {}, + tokio::runtime::Handle::current(), + Alice, + Vec::new(), + true, + ); + + // start alice + let alice = polkadot_test_service::run_validator_node(alice_config, Some(PUPPET_EXE.into())); + + let bob_config = polkadot_test_service::node_config( + || {}, + tokio::runtime::Handle::current(), + Bob, + vec![alice.addr.clone()], + true, + ); + + // start bob + let bob = polkadot_test_service::run_validator_node(bob_config, Some(PUPPET_EXE.into())); + + let collator = test_parachain_undying_collator::Collator::new(1_000, 1); + + // register parachain + alice + .register_parachain(para_id, collator.validation_code().to_vec(), collator.genesis_head()) + .await + .unwrap(); + + // run the collator node + let mut charlie = polkadot_test_service::run_collator_node( + tokio::runtime::Handle::current(), + Charlie, + || {}, + vec![alice.addr.clone(), bob.addr.clone()], + collator.collator_key(), + ); + + charlie + .register_collator( + collator.collator_key(), + para_id, + collator.create_collation_function(charlie.task_manager.spawn_handle()), + ) + .await; + + // Wait until the parachain has 4 blocks produced. + collator.wait_for_blocks(4).await; + + // Wait until the collator received `12` seconded statements for its collations. + collator.wait_for_seconded_collations(12).await; +} diff --git a/polkadot/parachain/test-parachains/undying/src/lib.rs b/polkadot/parachain/test-parachains/undying/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..abd88726b7fcb42f30f19bee37623f662547a1bf --- /dev/null +++ b/polkadot/parachain/test-parachains/undying/src/lib.rs @@ -0,0 +1,158 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Basic parachain that adds a number as part of its state. + +#![no_std] + +use parity_scale_codec::{Decode, Encode}; +use sp_std::vec::Vec; +use tiny_keccak::{Hasher as _, Keccak}; + +#[cfg(not(feature = "std"))] +mod wasm_validation; + +#[cfg(not(feature = "std"))] +#[global_allocator] +static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc; +const LOG_TARGET: &str = "runtime::undying"; + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +fn keccak256(input: &[u8]) -> [u8; 32] { + let mut out = [0u8; 32]; + let mut keccak256 = Keccak::v256(); + keccak256.update(input); + keccak256.finalize(&mut out); + out +} + +/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. +#[cfg(feature = "std")] +pub fn wasm_binary_unwrap() -> &'static [u8] { + WASM_BINARY.expect( + "Development wasm binary is not available. Testing is only \ + supported with the flag disabled.", + ) +} + +/// Head data for this parachain. +#[derive(Default, Clone, Hash, Eq, PartialEq, Encode, Decode, Debug)] +pub struct HeadData { + /// Block number + pub number: u64, + /// parent block keccak256 + pub parent_hash: [u8; 32], + /// hash of post-execution state. + pub post_state: [u8; 32], +} + +impl HeadData { + pub fn hash(&self) -> [u8; 32] { + keccak256(&self.encode()) + } +} + +/// Block data for this parachain. +#[derive(Default, Clone, Encode, Decode, Debug)] +pub struct GraveyardState { + /// The grave index of the last placed tombstone. + pub index: u64, + /// We use a matrix where each element represents a grave. + /// The unsigned integer tracks the number of tombstones raised on + /// each grave. + pub graveyard: Vec, + // TODO: Add zombies. All of the graves produce zombies at a regular interval + // defined in blocks. The number of zombies produced scales with the tombstones. + // This would allow us to have a configurable and reproducible PVF execution time. + // However, PVF preparation time will likely rely on prebuild wasm binaries. + pub zombies: u64, + // Grave seal. + pub seal: [u8; 32], +} + +/// Block data for this parachain. +#[derive(Default, Clone, Encode, Decode, Debug)] +pub struct BlockData { + /// The state + pub state: GraveyardState, + /// The number of tombstones to erect per iteration. For each tombstone placed + /// a hash operation is performed as CPU burn. + pub tombstones: u64, + /// The number of iterations to perform. + pub iterations: u32, +} + +pub fn hash_state(state: &GraveyardState) -> [u8; 32] { + keccak256(state.encode().as_slice()) +} + +/// Executes all graveyard transactions in the block. +pub fn execute_transaction(mut block_data: BlockData) -> GraveyardState { + let graveyard_size = block_data.state.graveyard.len(); + + for _ in 0..block_data.iterations { + for _ in 0..block_data.tombstones { + block_data.state.graveyard[block_data.state.index as usize] = + block_data.state.graveyard[block_data.state.index as usize].wrapping_add(1); + + block_data.state.index = + ((block_data.state.index.saturating_add(1)) as usize % graveyard_size) as u64; + } + // Chain hash the seals and burn CPU. + block_data.state.seal = hash_state(&block_data.state); + } + + block_data.state +} + +/// Start state mismatched with parent header's state hash. +#[derive(Debug)] +pub struct StateMismatch; + +/// Execute a block body on top of given parent head, producing new parent head +/// and new state if valid. +pub fn execute( + parent_hash: [u8; 32], + parent_head: HeadData, + block_data: BlockData, +) -> Result<(HeadData, GraveyardState), StateMismatch> { + assert_eq!(parent_hash, parent_head.hash()); + + if hash_state(&block_data.state) != parent_head.post_state { + log::debug!( + target: LOG_TARGET, + "state has diff vs head: {:?} vs {:?}", + hash_state(&block_data.state), + parent_head.post_state, + ); + return Err(StateMismatch) + } + + // We need to clone the block data as the fn will mutate it's state. + let new_state = execute_transaction(block_data.clone()); + + Ok(( + HeadData { + number: parent_head.number + 1, + parent_hash, + post_state: hash_state(&new_state), + }, + new_state, + )) +} diff --git a/polkadot/parachain/test-parachains/undying/src/wasm_validation.rs b/polkadot/parachain/test-parachains/undying/src/wasm_validation.rs new file mode 100644 index 0000000000000000000000000000000000000000..de4a1d7e2329c8ff2c6540abf91f0f3d02a3ed35 --- /dev/null +++ b/polkadot/parachain/test-parachains/undying/src/wasm_validation.rs @@ -0,0 +1,47 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! WASM validation for the `Undying` parachain. + +use crate::{BlockData, HeadData}; +use parachain::primitives::{HeadData as GenericHeadData, ValidationResult}; +use parity_scale_codec::{Decode, Encode}; + +#[no_mangle] +pub extern "C" fn validate_block(params: *const u8, len: usize) -> u64 { + let params = unsafe { parachain::load_params(params, len) }; + let parent_head = + HeadData::decode(&mut ¶ms.parent_head.0[..]).expect("invalid parent head format."); + + let mut block_data = + BlockData::decode(&mut ¶ms.block_data.0[..]).expect("invalid block data format."); + + let parent_hash = crate::keccak256(¶ms.parent_head.0[..]); + + let (new_head, _) = + crate::execute(parent_hash, parent_head, block_data).expect("Executes block"); + + parachain::write_result(&ValidationResult { + head_data: GenericHeadData(new_head.encode()), + new_validation_code: None, + upward_messages: sp_std::vec::Vec::new().try_into().expect("empty vec fits within bounds"), + horizontal_messages: sp_std::vec::Vec::new() + .try_into() + .expect("empty vec fits within bounds"), + processed_downward_messages: 0, + hrmp_watermark: params.relay_parent_number, + }) +} diff --git a/polkadot/primitives/Cargo.toml b/polkadot/primitives/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..51c2bf8bea42aa864827e9ab9ae1668c46310527 --- /dev/null +++ b/polkadot/primitives/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "polkadot-primitives" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } +hex-literal = "0.4.1" +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["bit-vec", "derive"] } +scale-info = { version = "2.5.0", default-features = false, features = ["bit-vec", "derive", "serde"] } +serde = { version = "1.0.163", default-features = false, features = ["derive", "alloc"] } + +application-crypto = { package = "sp-application-crypto", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = ["serde"] } +inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +runtime_primitives = { package = "sp-runtime", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = ["serde"] } +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = ["serde"] } +sp-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = ["serde"] } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = ["serde"] } +sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +polkadot-core-primitives = { path = "../core-primitives", default-features = false } +polkadot-parachain = { path = "../parachain", default-features = false } + +[features] +default = ["std"] +std = [ + "application-crypto/std", + "parity-scale-codec/std", + "scale-info/std", + "primitives/std", + "inherents/std", + "sp-api/std", + "sp-authority-discovery/std", + "sp-consensus-slots/std", + "sp-keystore", + "sp-std/std", + "sp-io/std", + "sp-staking/std", + "sp-arithmetic/std", + "runtime_primitives/std", + "serde/std", + "polkadot-parachain/std", + "polkadot-core-primitives/std", + "bitvec/std", +] +runtime-benchmarks = [] diff --git a/polkadot/primitives/README.adoc b/polkadot/primitives/README.adoc new file mode 100644 index 0000000000000000000000000000000000000000..0e5c9412f002902a0a00970b08f746ffdfe5cc77 --- /dev/null +++ b/polkadot/primitives/README.adoc @@ -0,0 +1,5 @@ + += Polkadot primitives + +placeholder +//TODO Write content :) (https://github.com/paritytech/polkadot/issues/159) diff --git a/polkadot/primitives/src/lib.rs b/polkadot/primitives/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..3680cb857e66e441823422e5c7cb079d8f1279bb --- /dev/null +++ b/polkadot/primitives/src/lib.rs @@ -0,0 +1,64 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot types shared between the runtime and the Node-side code. + +#![warn(missing_docs)] +#![cfg_attr(not(feature = "std"), no_std)] + +// `v5` is currently the latest stable version of the runtime API. +pub mod v5; + +// The 'staging' version is special - it contains primitives which are +// still in development. Once they are considered stable, they will be +// moved to a new versioned module. +pub mod vstaging; + +// `runtime_api` contains the actual API implementation. It contains stable and +// unstable functions. +pub mod runtime_api; + +// Current primitives not requiring versioning are exported here. +// Primitives requiring versioning must not be exported and must be referred by an exact version. +pub use v5::{ + byzantine_threshold, check_candidate_backing, collator_signature_payload, metric_definitions, + slashing, supermajority_threshold, well_known_keys, AbridgedHostConfiguration, + AbridgedHrmpChannel, AccountId, AccountIndex, AccountPublic, ApprovalVote, AssignmentId, + AuthorityDiscoveryId, AvailabilityBitfield, BackedCandidate, Balance, BlakeTwo256, Block, + BlockId, BlockNumber, CandidateCommitments, CandidateDescriptor, CandidateEvent, CandidateHash, + CandidateIndex, CandidateReceipt, CheckedDisputeStatementSet, CheckedMultiDisputeStatementSet, + CollatorId, CollatorSignature, CommittedCandidateReceipt, CompactStatement, ConsensusLog, + CoreIndex, CoreOccupied, CoreState, DisputeState, DisputeStatement, DisputeStatementSet, + DownwardMessage, EncodeAs, ExecutorParam, ExecutorParams, ExecutorParamsHash, + ExplicitDisputeStatement, GroupIndex, GroupRotationInfo, Hash, HashT, HeadData, Header, + HrmpChannelId, Id, InboundDownwardMessage, InboundHrmpMessage, IndexedVec, InherentData, + InvalidDisputeStatementKind, Moment, MultiDisputeStatementSet, Nonce, OccupiedCore, + OccupiedCoreAssumption, OutboundHrmpMessage, ParathreadClaim, ParathreadEntry, + PersistedValidationData, PvfCheckStatement, PvfExecTimeoutKind, PvfPrepTimeoutKind, + RuntimeMetricLabel, RuntimeMetricLabelValue, RuntimeMetricLabelValues, RuntimeMetricLabels, + RuntimeMetricOp, RuntimeMetricUpdate, ScheduledCore, ScrapedOnChainVotes, SessionIndex, + SessionInfo, Signature, Signed, SignedAvailabilityBitfield, SignedAvailabilityBitfields, + SignedStatement, SigningContext, Slot, UncheckedSigned, UncheckedSignedAvailabilityBitfield, + UncheckedSignedAvailabilityBitfields, UncheckedSignedStatement, UpgradeGoAhead, + UpgradeRestriction, UpwardMessage, ValidDisputeStatementKind, ValidationCode, + ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, ValidityAttestation, + ValidityError, ASSIGNMENT_KEY_TYPE_ID, LOWEST_PUBLIC_ID, MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, + MAX_POV_SIZE, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, PARACHAINS_INHERENT_IDENTIFIER, + PARACHAIN_KEY_TYPE_ID, +}; + +#[cfg(feature = "std")] +pub use v5::{AssignmentPair, CollatorPair, ValidatorPair}; diff --git a/polkadot/primitives/src/runtime_api.rs b/polkadot/primitives/src/runtime_api.rs new file mode 100644 index 0000000000000000000000000000000000000000..483256fe20f3689639844fcbeade405ba21650eb --- /dev/null +++ b/polkadot/primitives/src/runtime_api.rs @@ -0,0 +1,254 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Runtime API module declares the `trait ParachainHost` which is part +//! of the Runtime API exposed from the Runtime to the Host. +//! +//! The functions in trait ParachainHost` can be part of the stable API +//! (which is versioned) or they can be staging (aka unstable/testing +//! functions). +//! +//! The separation outlined above is achieved with the versioned API feature +//! of `decl_runtime_apis!` and `impl_runtime_apis!`. Before moving on let's +//! see a quick example about how API versioning works. +//! +//! # Runtime API versioning crash course +//! +//! The versioning is achieved with the `api_version` attribute. It can be +//! placed on: +//! * trait declaration - represents the base version of the API. +//! * method declaration (inside a trait declaration) - represents a versioned method, which is not +//! available in the base version. +//! * trait implementation - represents which version of the API is being implemented. +//! +//! Let's see a quick example: +//! +//! ```rust(ignore) +//! sp_api::decl_runtime_apis! { +//! #[api_version(2)] +//! pub trait MyApi { +//! fn fn1(); +//! fn fn2(); +//! #[api_version(3)] +//! fn fn3(); +//! #[api_version(4)] +//! fn fn4(); +//! } +//! } +//! +//! struct Runtime {} +//! +//! sp_api::impl_runtime_apis! { +//! #[api_version(3)] +//! impl self::MyApi for Runtime { +//! fn fn1() {} +//! fn fn2() {} +//! fn fn3() {} +//! } +//! } +//! ``` +//! A new API named `MyApi` is declared with `decl_runtime_apis!`. The trait declaration +//! has got an `api_version` attribute which represents its base version - 2 in this case. +//! +//! The API has got three methods - `fn1`, `fn2`, `fn3` and `fn4`. `fn3` and `fn4` has got +//! an `api_version` attribute which makes them versioned methods. These methods do not exist +//! in the base version of the API. Behind the scenes the declaration above creates three +//! runtime APIs: +//! * `MyApiV2` with `fn1` and `fn2` +//! * `MyApiV3` with `fn1`, `fn2` and `fn3`. +//! * `MyApiV4` with `fn1`, `fn2`, `fn3` and `fn4`. +//! +//! Please note that `v4` contains all methods from `v3`, `v3` all methods from `v2` and so on. +//! +//! Back to our example. At the end runtime API is implemented for `struct Runtime` with +//! `impl_runtime_apis` macro. `api_version` attribute is attached to the `impl` block which +//! means that a version different from the base one is being implemented - in our case this +//! is `v3`. +//! +//! This version of the API contains three methods so the `impl` block has got definitions +//! for them. Note that `fn4` is not implemented as it is not part of this version of the API. +//! `impl_runtime_apis` generates a default implementation for it calling `unimplemented!()`. +//! +//! Hopefully this should be all you need to know in order to use versioned methods in the node. +//! For more details about how the API versioning works refer to `spi_api` +//! documentation [here](https://docs.substrate.io/rustdocs/latest/sp_api/macro.decl_runtime_apis.html). +//! +//! # How versioned methods are used for `ParachainHost` +//! +//! Let's introduce two types of `ParachainHost` API implementation: +//! * stable - used on stable production networks like Polkadot and Kusama. There is only one stable +//! API at a single point in time. +//! * staging - methods that are ready for production, but will be released on Rococo first. We can +//! batch together multiple changes and then release all of them to production, by making staging +//! production (bump base version). We can not change or remove any method in staging after a +//! release, as this would break Rococo. It should be ok to keep adding methods to staging across +//! several releases. For experimental methods, you have to keep them on a separate branch until +//! ready. +//! +//! The stable version of `ParachainHost` is indicated by the base version of the API. Any staging +//! method must use `api_version` attribute so that it is assigned to a specific version of a +//! staging API. This way in a single declaration one can see what's the stable version of +//! `ParachainHost` and what staging versions/functions are available. +//! +//! All stable API functions should use primitives from the latest version. +//! In the time of writing of this document - this is `v2`. So for example: +//! ```ignore +//! fn validators() -> Vec; +//! ``` +//! indicates a function from the stable `v2` API. +//! +//! All staging API functions should use primitives from `vstaging`. They should be clearly +//! separated from the stable primitives. + +use crate::{ + vstaging, BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash, + CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, + OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, + SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, ValidatorSignature, +}; +use parity_scale_codec::{Decode, Encode}; +use polkadot_core_primitives as pcp; +use polkadot_parachain::primitives as ppp; +use sp_std::{collections::btree_map::BTreeMap, prelude::*}; + +sp_api::decl_runtime_apis! { + /// The API for querying the state of parachains on-chain. + #[api_version(5)] + pub trait ParachainHost { + /// Get the current validators. + fn validators() -> Vec; + + /// Returns the validator groups and rotation info localized based on the hypothetical child + /// of a block whose state this is invoked on. Note that `now` in the `GroupRotationInfo` + /// should be the successor of the number of the block. + fn validator_groups() -> (Vec>, GroupRotationInfo); + + /// Yields information on all availability cores as relevant to the child block. + /// Cores are either free or occupied. Free cores can have paras assigned to them. + fn availability_cores() -> Vec>; + + /// Yields the persisted validation data for the given `ParaId` along with an assumption that + /// should be used if the para currently occupies a core. + /// + /// Returns `None` if either the para is not registered or the assumption is `Freed` + /// and the para already occupies a core. + fn persisted_validation_data(para_id: ppp::Id, assumption: OccupiedCoreAssumption) + -> Option>; + + /// Returns the persisted validation data for the given `ParaId` along with the corresponding + /// validation code hash. Instead of accepting assumption about the para, matches the validation + /// data hash against an expected one and yields `None` if they're not equal. + fn assumed_validation_data( + para_id: ppp::Id, + expected_persisted_validation_data_hash: pcp::v2::Hash, + ) -> Option<(PersistedValidationData, ppp::ValidationCodeHash)>; + + /// Checks if the given validation outputs pass the acceptance criteria. + fn check_validation_outputs(para_id: ppp::Id, outputs: CandidateCommitments) -> bool; + + /// Returns the session index expected at a child of the block. + /// + /// This can be used to instantiate a `SigningContext`. + fn session_index_for_child() -> SessionIndex; + + /// Fetch the validation code used by a para, making the given `OccupiedCoreAssumption`. + /// + /// Returns `None` if either the para is not registered or the assumption is `Freed` + /// and the para already occupies a core. + fn validation_code(para_id: ppp::Id, assumption: OccupiedCoreAssumption) + -> Option; + + /// Get the receipt of a candidate pending availability. This returns `Some` for any paras + /// assigned to occupied cores in `availability_cores` and `None` otherwise. + fn candidate_pending_availability(para_id: ppp::Id) -> Option>; + + /// Get a vector of events concerning candidates that occurred within a block. + fn candidate_events() -> Vec>; + + /// Get all the pending inbound messages in the downward message queue for a para. + fn dmq_contents( + recipient: ppp::Id, + ) -> Vec>; + + /// Get the contents of all channels addressed to the given recipient. Channels that have no + /// messages in them are also included. + fn inbound_hrmp_channels_contents(recipient: ppp::Id) -> BTreeMap>>; + + /// Get the validation code from its hash. + fn validation_code_by_hash(hash: ppp::ValidationCodeHash) -> Option; + + /// Scrape dispute relevant from on-chain, backing votes and resolved disputes. + fn on_chain_votes() -> Option>; + + /***** Added in v2 *****/ + + /// Get the session info for the given session, if stored. + /// + /// NOTE: This function is only available since parachain host version 2. + fn session_info(index: SessionIndex) -> Option; + + /// Submits a PVF pre-checking statement into the transaction pool. + /// + /// NOTE: This function is only available since parachain host version 2. + fn submit_pvf_check_statement(stmt: PvfCheckStatement, signature: ValidatorSignature); + + /// Returns code hashes of PVFs that require pre-checking by validators in the active set. + /// + /// NOTE: This function is only available since parachain host version 2. + fn pvfs_require_precheck() -> Vec; + + /// Fetch the hash of the validation code used by a para, making the given `OccupiedCoreAssumption`. + /// + /// NOTE: This function is only available since parachain host version 2. + fn validation_code_hash(para_id: ppp::Id, assumption: OccupiedCoreAssumption) + -> Option; + + /// Returns all onchain disputes. + fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState)>; + + /// Returns execution parameters for the session. + fn session_executor_params(session_index: SessionIndex) -> Option; + + /// Returns a list of validators that lost a past session dispute and need to be slashed. + /// NOTE: This function is only available since parachain host version 5. + fn unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>; + + /// Returns a merkle proof of a validator session key. + /// NOTE: This function is only available since parachain host version 5. + fn key_ownership_proof( + validator_id: ValidatorId, + ) -> Option; + + /// Submit an unsigned extrinsic to slash validators who lost a dispute about + /// a candidate of a past session. + /// NOTE: This function is only available since parachain host version 5. + fn submit_report_dispute_lost( + dispute_proof: vstaging::slashing::DisputeProof, + key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof, + ) -> Option<()>; + + /***** Asynchronous backing *****/ + + /// Returns the state of parachain backing for a given para. + /// This is a staging method! Do not use on production runtimes! + #[api_version(99)] + fn staging_para_backing_state(_: ppp::Id) -> Option>; + + /// Returns candidate's acceptance limitations for asynchronous backing for a relay parent. + #[api_version(99)] + fn staging_async_backing_params() -> vstaging::AsyncBackingParams; + } +} diff --git a/polkadot/primitives/src/v5/executor_params.rs b/polkadot/primitives/src/v5/executor_params.rs new file mode 100644 index 0000000000000000000000000000000000000000..6fbf3037fd6cd8c99780edda33763817dfb11941 --- /dev/null +++ b/polkadot/primitives/src/v5/executor_params.rs @@ -0,0 +1,153 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Abstract execution environment parameter set. +//! +//! Parameter set is encoded as an opaque vector which structure depends on the execution +//! environment itself (except for environment type/version which is always represented +//! by the first element of the vector). Decoding to a usable semantics structure is +//! done in `polkadot-node-core-pvf`. + +use crate::{BlakeTwo256, HashT as _, PvfExecTimeoutKind, PvfPrepTimeoutKind}; +use parity_scale_codec::{Decode, Encode}; +use polkadot_core_primitives::Hash; +use scale_info::TypeInfo; +use serde::{Deserialize, Serialize}; +use sp_std::{ops::Deref, time::Duration, vec, vec::Vec}; + +/// The different executor parameters for changing the execution environment semantics. +#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo, Serialize, Deserialize)] +pub enum ExecutorParam { + /// Maximum number of memory pages (64KiB bytes per page) the executor can allocate. + #[codec(index = 1)] + MaxMemoryPages(u32), + /// Wasm logical stack size limit (max. number of Wasm values on stack) + #[codec(index = 2)] + StackLogicalMax(u32), + /// Executor machine stack size limit, in bytes + #[codec(index = 3)] + StackNativeMax(u32), + /// Max. amount of memory the preparation worker is allowed to use during + /// pre-checking, in bytes + #[codec(index = 4)] + PrecheckingMaxMemory(u64), + /// PVF preparation timeouts, millisec + #[codec(index = 5)] + PvfPrepTimeout(PvfPrepTimeoutKind, u64), + /// PVF execution timeouts, millisec + #[codec(index = 6)] + PvfExecTimeout(PvfExecTimeoutKind, u64), + /// Enables WASM bulk memory proposal + #[codec(index = 7)] + WasmExtBulkMemory, +} + +/// Unit type wrapper around [`type@Hash`] that represents an execution parameter set hash. +/// +/// This type is produced by [`ExecutorParams::hash`]. +#[derive(Clone, Copy, Encode, Decode, Hash, Eq, PartialEq, PartialOrd, Ord, TypeInfo)] +pub struct ExecutorParamsHash(Hash); + +impl ExecutorParamsHash { + /// Create a new executor parameter hash from `H256` hash + pub fn from_hash(hash: Hash) -> Self { + Self(hash) + } +} + +impl sp_std::fmt::Display for ExecutorParamsHash { + fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { + self.0.fmt(f) + } +} + +impl sp_std::fmt::Debug for ExecutorParamsHash { + fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { + write!(f, "{:?}", self.0) + } +} + +impl sp_std::fmt::LowerHex for ExecutorParamsHash { + fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { + sp_std::fmt::LowerHex::fmt(&self.0, f) + } +} + +/// # Deterministically serialized execution environment semantics +/// Represents an arbitrary semantics of an arbitrary execution environment, so should be kept as +/// abstract as possible. +// ADR: For mandatory entries, mandatoriness should be enforced in code rather than separating them +// into individual fields of the structure. Thus, complex migrations shall be avoided when adding +// new entries and removing old ones. At the moment, there's no mandatory parameters defined. If +// they show up, they must be clearly documented as mandatory ones. +#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo, Serialize, Deserialize)] +pub struct ExecutorParams(Vec); + +impl ExecutorParams { + /// Creates a new, empty executor parameter set + pub fn new() -> Self { + ExecutorParams(vec![]) + } + + /// Returns hash of the set of execution environment parameters + pub fn hash(&self) -> ExecutorParamsHash { + ExecutorParamsHash(BlakeTwo256::hash(&self.encode())) + } + + /// Returns a PVF preparation timeout, if any + pub fn pvf_prep_timeout(&self, kind: PvfPrepTimeoutKind) -> Option { + for param in &self.0 { + if let ExecutorParam::PvfPrepTimeout(k, timeout) = param { + if kind == *k { + return Some(Duration::from_millis(*timeout)) + } + } + } + None + } + + /// Returns a PVF execution timeout, if any + pub fn pvf_exec_timeout(&self, kind: PvfExecTimeoutKind) -> Option { + for param in &self.0 { + if let ExecutorParam::PvfExecTimeout(k, timeout) = param { + if kind == *k { + return Some(Duration::from_millis(*timeout)) + } + } + } + None + } +} + +impl Deref for ExecutorParams { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From<&[ExecutorParam]> for ExecutorParams { + fn from(arr: &[ExecutorParam]) -> Self { + ExecutorParams(arr.to_vec()) + } +} + +impl Default for ExecutorParams { + fn default() -> Self { + ExecutorParams(vec![]) + } +} diff --git a/polkadot/primitives/src/v5/metrics.rs b/polkadot/primitives/src/v5/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..97f7678e437371c47a9fc7d31a58e2c52196e492 --- /dev/null +++ b/polkadot/primitives/src/v5/metrics.rs @@ -0,0 +1,195 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Runtime metric primitives. + +use parity_scale_codec::{Decode, Encode}; +use sp_std::prelude::*; + +/// Runtime metric operations. +#[derive(Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug))] +pub enum RuntimeMetricOp { + /// Increment a counter metric with labels by value. + IncrementCounterVec(u64, RuntimeMetricLabelValues), + /// Increment a counter metric by value. + IncrementCounter(u64), + /// Observe histogram value + ObserveHistogram(u128), +} + +/// Runtime metric update event. +#[derive(Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct RuntimeMetricUpdate { + /// The name of the metric. + pub metric_name: Vec, + /// The operation applied to the metric. + pub op: RuntimeMetricOp, +} + +fn vec_to_str<'a>(v: &'a Vec, default: &'static str) -> &'a str { + return sp_std::str::from_utf8(v).unwrap_or(default) +} + +impl RuntimeMetricLabels { + /// Returns a labels as `Vec<&str>`. + pub fn as_str_vec(&self) -> Vec<&str> { + self.0 + .iter() + .map(|label_vec| vec_to_str(&label_vec.0, "invalid_label")) + .collect() + } + + /// Return the inner values as vec. + pub fn clear(&mut self) { + self.0.clear(); + } +} + +impl From<&[&'static str]> for RuntimeMetricLabels { + fn from(v: &[&'static str]) -> RuntimeMetricLabels { + RuntimeMetricLabels( + v.iter().map(|label| RuntimeMetricLabel(label.as_bytes().to_vec())).collect(), + ) + } +} + +impl RuntimeMetricUpdate { + /// Returns the metric name. + pub fn metric_name(&self) -> &str { + vec_to_str(&self.metric_name, "invalid_metric_name") + } +} + +/// A set of metric labels. +#[derive(Clone, Default, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct RuntimeMetricLabels(Vec); + +/// A metric label. +#[derive(Clone, Default, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct RuntimeMetricLabel(Vec); + +/// A metric label value. +pub type RuntimeMetricLabelValue = RuntimeMetricLabel; + +/// A set of metric label values. +pub type RuntimeMetricLabelValues = RuntimeMetricLabels; + +/// Trait for converting Vec to `&str`. +pub trait AsStr { + /// Return a str reference. + fn as_str(&self) -> Option<&str>; +} + +impl AsStr for RuntimeMetricLabel { + fn as_str(&self) -> Option<&str> { + sp_std::str::from_utf8(&self.0).ok() + } +} + +impl From<&'static str> for RuntimeMetricLabel { + fn from(s: &'static str) -> Self { + Self(s.as_bytes().to_vec()) + } +} + +/// Contains all runtime metrics defined as constants. +pub mod metric_definitions { + /// `Counter` metric definition. + pub struct CounterDefinition { + /// The name of the metric. + pub name: &'static str, + /// The description of the metric. + pub description: &'static str, + } + + /// `CounterVec` metric definition. + pub struct CounterVecDefinition<'a> { + /// The name of the metric. + pub name: &'static str, + /// The description of the metric. + pub description: &'static str, + /// The label names of the metric. + pub labels: &'a [&'static str], + } + + /// `Histogram` metric definition + pub struct HistogramDefinition<'a> { + /// The name of the metric. + pub name: &'static str, + /// The description of the metric. + pub description: &'static str, + /// The buckets for the histogram + pub buckets: &'a [f64], + } + + /// Counts parachain inherent data weights. Use `before` and `after` labels to differentiate + /// between the weight before and after filtering. + pub const PARACHAIN_INHERENT_DATA_WEIGHT: CounterVecDefinition = CounterVecDefinition { + name: "polkadot_parachain_inherent_data_weight", + description: "Inherent data weight before and after filtering", + labels: &["when"], + }; + + /// Counts the number of bitfields processed in `process_inherent_data`. + pub const PARACHAIN_INHERENT_DATA_BITFIELDS_PROCESSED: CounterDefinition = CounterDefinition { + name: "polkadot_parachain_inherent_data_bitfields_processed", + description: "Counts the number of bitfields processed in `process_inherent_data`.", + }; + + /// Counts the `total`, `sanitized` and `included` number of parachain block candidates + /// in `process_inherent_data`. + pub const PARACHAIN_INHERENT_DATA_CANDIDATES_PROCESSED: CounterVecDefinition = + CounterVecDefinition { + name: "polkadot_parachain_inherent_data_candidates_processed", + description: + "Counts the number of parachain block candidates processed in `process_inherent_data`.", + labels: &["category"], + }; + + /// Counts the number of `imported`, `current` and `concluded_invalid` dispute statements sets + /// processed in `process_inherent_data`. The `current` label refers to the disputes statement + /// sets of the current session. + pub const PARACHAIN_INHERENT_DATA_DISPUTE_SETS_PROCESSED: CounterVecDefinition = + CounterVecDefinition { + name: "polkadot_parachain_inherent_data_dispute_sets_processed", + description: + "Counts the number of dispute statements sets processed in `process_inherent_data`.", + labels: &["category"], + }; + + /// Counts the number of `valid` and `invalid` bitfields signature checked in + /// `process_inherent_data`. + pub const PARACHAIN_CREATE_INHERENT_BITFIELDS_SIGNATURE_CHECKS: CounterVecDefinition = + CounterVecDefinition { + name: "polkadot_parachain_create_inherent_bitfields_signature_checks", + description: + "Counts the number of bitfields signature checked in `process_inherent_data`.", + labels: &["validity"], + }; + + /// Measures how much time does it take to verify a single validator signature of a dispute + /// statement + pub const PARACHAIN_VERIFY_DISPUTE_SIGNATURE: HistogramDefinition = + HistogramDefinition { + name: "polkadot_parachain_verify_dispute_signature", + description: "How much time does it take to verify a single validator signature of a dispute statement, in seconds", + buckets: &[0.0, 0.00005, 0.00006, 0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.3, 0.5, 1.0], + }; +} diff --git a/polkadot/primitives/src/v5/mod.rs b/polkadot/primitives/src/v5/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..59fb6c927b2df588cca6e442c00b977941597d76 --- /dev/null +++ b/polkadot/primitives/src/v5/mod.rs @@ -0,0 +1,1928 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! `V2` Primitives. + +use bitvec::vec::BitVec; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_std::{ + marker::PhantomData, + prelude::*, + slice::{Iter, IterMut}, + vec::IntoIter, +}; + +use application_crypto::KeyTypeId; +use inherents::InherentIdentifier; +use primitives::RuntimeDebug; +use runtime_primitives::traits::{AppVerify, Header as HeaderT}; +use sp_arithmetic::traits::{BaseArithmetic, Saturating}; + +pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT}; + +// Export some core primitives. +pub use polkadot_core_primitives::v2::{ + AccountId, AccountIndex, AccountPublic, Balance, Block, BlockId, BlockNumber, CandidateHash, + ChainId, DownwardMessage, Hash, Header, InboundDownwardMessage, InboundHrmpMessage, Moment, + Nonce, OutboundHrmpMessage, Remark, Signature, UncheckedExtrinsic, +}; + +// Export some polkadot-parachain primitives +pub use polkadot_parachain::primitives::{ + HeadData, HorizontalMessages, HrmpChannelId, Id, UpwardMessage, UpwardMessages, ValidationCode, + ValidationCodeHash, LOWEST_PUBLIC_ID, LOWEST_USER_ID, +}; + +use serde::{Deserialize, Serialize}; + +pub use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +pub use sp_consensus_slots::Slot; +pub use sp_staking::SessionIndex; + +/// Signed data. +mod signed; +pub use signed::{EncodeAs, Signed, UncheckedSigned}; + +pub mod slashing; + +mod metrics; +pub use metrics::{ + metric_definitions, RuntimeMetricLabel, RuntimeMetricLabelValue, RuntimeMetricLabelValues, + RuntimeMetricLabels, RuntimeMetricOp, RuntimeMetricUpdate, +}; + +/// The key type ID for a collator key. +pub const COLLATOR_KEY_TYPE_ID: KeyTypeId = KeyTypeId(*b"coll"); + +mod collator_app { + use application_crypto::{app_crypto, sr25519}; + app_crypto!(sr25519, super::COLLATOR_KEY_TYPE_ID); +} + +/// Identity that collators use. +pub type CollatorId = collator_app::Public; + +/// A Parachain collator keypair. +#[cfg(feature = "std")] +pub type CollatorPair = collator_app::Pair; + +/// Signature on candidate's block data by a collator. +pub type CollatorSignature = collator_app::Signature; + +/// The key type ID for a parachain validator key. +pub const PARACHAIN_KEY_TYPE_ID: KeyTypeId = KeyTypeId(*b"para"); + +mod validator_app { + use application_crypto::{app_crypto, sr25519}; + app_crypto!(sr25519, super::PARACHAIN_KEY_TYPE_ID); +} + +/// Identity that parachain validators use when signing validation messages. +/// +/// For now we assert that parachain validator set is exactly equivalent to the authority set, and +/// so we define it to be the same type as `SessionKey`. In the future it may have different crypto. +pub type ValidatorId = validator_app::Public; + +/// Trait required for type specific indices e.g. `ValidatorIndex` and `GroupIndex` +pub trait TypeIndex { + /// Returns the index associated to this value. + fn type_index(&self) -> usize; +} + +/// Index of the validator is used as a lightweight replacement of the `ValidatorId` when +/// appropriate. +#[derive(Eq, Ord, PartialEq, PartialOrd, Copy, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash))] +pub struct ValidatorIndex(pub u32); + +// We should really get https://github.com/paritytech/polkadot/issues/2403 going .. +impl From for ValidatorIndex { + fn from(n: u32) -> Self { + ValidatorIndex(n) + } +} + +impl TypeIndex for ValidatorIndex { + fn type_index(&self) -> usize { + self.0 as usize + } +} + +application_crypto::with_pair! { + /// A Parachain validator keypair. + pub type ValidatorPair = validator_app::Pair; +} + +/// Signature with which parachain validators sign blocks. +/// +/// For now we assert that parachain validator set is exactly equivalent to the authority set, and +/// so we define it to be the same type as `SessionKey`. In the future it may have different crypto. +pub type ValidatorSignature = validator_app::Signature; + +/// A declarations of storage keys where an external observer can find some interesting data. +pub mod well_known_keys { + use super::{HrmpChannelId, Id, WellKnownKey}; + use hex_literal::hex; + use parity_scale_codec::Encode as _; + use sp_io::hashing::twox_64; + use sp_std::prelude::*; + + // A note on generating these magic values below: + // + // The `StorageValue`, such as `ACTIVE_CONFIG` was obtained by calling: + // + // ActiveConfig::::hashed_key() + // + // The `StorageMap` values require `prefix`, and for example for `hrmp_egress_channel_index`, + // it could be obtained like: + // + // HrmpEgressChannelsIndex::::prefix_hash(); + // + + /// The current epoch index. + /// + /// The storage item should be access as a `u64` encoded value. + pub const EPOCH_INDEX: &[u8] = + &hex!["1cb6f36e027abb2091cfb5110ab5087f38316cbf8fa0da822a20ac1c55bf1be3"]; + + /// The current relay chain block randomness + /// + /// The storage item should be accessed as a `schnorrkel::Randomness` encoded value. + pub const CURRENT_BLOCK_RANDOMNESS: &[u8] = + &hex!["1cb6f36e027abb2091cfb5110ab5087fd077dfdb8adb10f78f10a5df8742c545"]; + + /// The randomness for one epoch ago + /// + /// The storage item should be accessed as a `schnorrkel::Randomness` encoded value. + pub const ONE_EPOCH_AGO_RANDOMNESS: &[u8] = + &hex!["1cb6f36e027abb2091cfb5110ab5087f7ce678799d3eff024253b90e84927cc6"]; + + /// The randomness for two epochs ago + /// + /// The storage item should be accessed as a `schnorrkel::Randomness` encoded value. + pub const TWO_EPOCHS_AGO_RANDOMNESS: &[u8] = + &hex!["1cb6f36e027abb2091cfb5110ab5087f7a414cb008e0e61e46722aa60abdd672"]; + + /// The current slot number. + /// + /// The storage entry should be accessed as a `Slot` encoded value. + pub const CURRENT_SLOT: &[u8] = + &hex!["1cb6f36e027abb2091cfb5110ab5087f06155b3cd9a8c9e5e9a23fd5dc13a5ed"]; + + /// The currently active host configuration. + /// + /// The storage entry should be accessed as an `AbridgedHostConfiguration` encoded value. + pub const ACTIVE_CONFIG: &[u8] = + &hex!["06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385"]; + + /// Hash of the committed head data for a given registered para. + /// + /// The storage entry stores wrapped `HeadData(Vec)`. + pub fn para_head(para_id: Id) -> Vec { + let prefix = hex!["cd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c3"]; + + para_id.using_encoded(|para_id: &[u8]| { + prefix + .as_ref() + .iter() + .chain(twox_64(para_id).iter()) + .chain(para_id.iter()) + .cloned() + .collect() + }) + } + + /// The upward message dispatch queue for the given para id. + /// + /// The storage entry stores a tuple of two values: + /// + /// - `count: u32`, the number of messages currently in the queue for given para, + /// - `total_size: u32`, the total size of all messages in the queue. + #[deprecated = "Use `relay_dispatch_queue_remaining_capacity` instead"] + pub fn relay_dispatch_queue_size(para_id: Id) -> Vec { + let prefix = hex!["f5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e"]; + + para_id.using_encoded(|para_id: &[u8]| { + prefix + .as_ref() + .iter() + .chain(twox_64(para_id).iter()) + .chain(para_id.iter()) + .cloned() + .collect() + }) + } + + /// Type safe version of `relay_dispatch_queue_size`. + #[deprecated = "Use `relay_dispatch_queue_remaining_capacity` instead"] + pub fn relay_dispatch_queue_size_typed(para: Id) -> WellKnownKey<(u32, u32)> { + #[allow(deprecated)] + relay_dispatch_queue_size(para).into() + } + + /// The upward message dispatch queue remaining capacity for the given para id. + /// + /// The storage entry stores a tuple of two values: + /// + /// - `count: u32`, the number of additional messages which may be enqueued for the given para, + /// - `total_size: u32`, the total size of additional messages which may be enqueued for the + /// given para. + pub fn relay_dispatch_queue_remaining_capacity(para_id: Id) -> WellKnownKey<(u32, u32)> { + (b":relay_dispatch_queue_remaining_capacity", para_id).encode().into() + } + + /// The HRMP channel for the given identifier. + /// + /// The storage entry should be accessed as an `AbridgedHrmpChannel` encoded value. + pub fn hrmp_channels(channel: HrmpChannelId) -> Vec { + let prefix = hex!["6a0da05ca59913bc38a8630590f2627cb6604cff828a6e3f579ca6c59ace013d"]; + + channel.using_encoded(|channel: &[u8]| { + prefix + .as_ref() + .iter() + .chain(twox_64(channel).iter()) + .chain(channel.iter()) + .cloned() + .collect() + }) + } + + /// The list of inbound channels for the given para. + /// + /// The storage entry stores a `Vec` + pub fn hrmp_ingress_channel_index(para_id: Id) -> Vec { + let prefix = hex!["6a0da05ca59913bc38a8630590f2627c1d3719f5b0b12c7105c073c507445948"]; + + para_id.using_encoded(|para_id: &[u8]| { + prefix + .as_ref() + .iter() + .chain(twox_64(para_id).iter()) + .chain(para_id.iter()) + .cloned() + .collect() + }) + } + + /// The list of outbound channels for the given para. + /// + /// The storage entry stores a `Vec` + pub fn hrmp_egress_channel_index(para_id: Id) -> Vec { + let prefix = hex!["6a0da05ca59913bc38a8630590f2627cf12b746dcf32e843354583c9702cc020"]; + + para_id.using_encoded(|para_id: &[u8]| { + prefix + .as_ref() + .iter() + .chain(twox_64(para_id).iter()) + .chain(para_id.iter()) + .cloned() + .collect() + }) + } + + /// The MQC head for the downward message queue of the given para. See more in the `Dmp` module. + /// + /// The storage entry stores a `Hash`. This is polkadot hash which is at the moment + /// `blake2b-256`. + pub fn dmq_mqc_head(para_id: Id) -> Vec { + let prefix = hex!["63f78c98723ddc9073523ef3beefda0c4d7fefc408aac59dbfe80a72ac8e3ce5"]; + + para_id.using_encoded(|para_id: &[u8]| { + prefix + .as_ref() + .iter() + .chain(twox_64(para_id).iter()) + .chain(para_id.iter()) + .cloned() + .collect() + }) + } + + /// The signal that indicates whether the parachain should go-ahead with the proposed validation + /// code upgrade. + /// + /// The storage entry stores a value of `UpgradeGoAhead` type. + pub fn upgrade_go_ahead_signal(para_id: Id) -> Vec { + let prefix = hex!["cd710b30bd2eab0352ddcc26417aa1949e94c040f5e73d9b7addd6cb603d15d3"]; + + para_id.using_encoded(|para_id: &[u8]| { + prefix + .as_ref() + .iter() + .chain(twox_64(para_id).iter()) + .chain(para_id.iter()) + .cloned() + .collect() + }) + } + + /// The signal that indicates whether the parachain is disallowed to signal an upgrade at this + /// relay-parent. + /// + /// The storage entry stores a value of `UpgradeRestriction` type. + pub fn upgrade_restriction_signal(para_id: Id) -> Vec { + let prefix = hex!["cd710b30bd2eab0352ddcc26417aa194f27bbb460270642b5bcaf032ea04d56a"]; + + para_id.using_encoded(|para_id: &[u8]| { + prefix + .as_ref() + .iter() + .chain(twox_64(para_id).iter()) + .chain(para_id.iter()) + .cloned() + .collect() + }) + } +} + +/// Unique identifier for the Parachains Inherent +pub const PARACHAINS_INHERENT_IDENTIFIER: InherentIdentifier = *b"parachn0"; + +/// The key type ID for parachain assignment key. +pub const ASSIGNMENT_KEY_TYPE_ID: KeyTypeId = KeyTypeId(*b"asgn"); + +/// Maximum compressed code size we support right now. +/// At the moment we have runtime upgrade on chain, which restricts scalability severely. If we want +/// to have bigger values, we should fix that first. +/// +/// Used for: +/// * initial genesis for the Parachains configuration +/// * checking updates to this stored runtime configuration do not exceed this limit +/// * when detecting a code decompression bomb in the client +// NOTE: This value is used in the runtime so be careful when changing it. +pub const MAX_CODE_SIZE: u32 = 3 * 1024 * 1024; + +/// Maximum head data size we support right now. +/// +/// Used for: +/// * initial genesis for the Parachains configuration +/// * checking updates to this stored runtime configuration do not exceed this limit +// NOTE: This value is used in the runtime so be careful when changing it. +pub const MAX_HEAD_DATA_SIZE: u32 = 1 * 1024 * 1024; + +/// Maximum PoV size we support right now. +/// +/// Used for: +/// * initial genesis for the Parachains configuration +/// * checking updates to this stored runtime configuration do not exceed this limit +/// * when detecting a PoV decompression bomb in the client +// NOTE: This value is used in the runtime so be careful when changing it. +pub const MAX_POV_SIZE: u32 = 5 * 1024 * 1024; + +/// Default queue size we use for the on-demand order book. +/// +/// Can be adjusted in configuration. +pub const ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE: u32 = 10_000; + +// The public key of a keypair used by a validator for determining assignments +/// to approve included parachain candidates. +mod assignment_app { + use application_crypto::{app_crypto, sr25519}; + app_crypto!(sr25519, super::ASSIGNMENT_KEY_TYPE_ID); +} + +/// The public key of a keypair used by a validator for determining assignments +/// to approve included parachain candidates. +pub type AssignmentId = assignment_app::Public; + +application_crypto::with_pair! { + /// The full keypair used by a validator for determining assignments to approve included + /// parachain candidates. + pub type AssignmentPair = assignment_app::Pair; +} + +/// The index of the candidate in the list of candidates fully included as-of the block. +pub type CandidateIndex = u32; + +/// Get a collator signature payload on a relay-parent, block-data combo. +pub fn collator_signature_payload>( + relay_parent: &H, + para_id: &Id, + persisted_validation_data_hash: &Hash, + pov_hash: &Hash, + validation_code_hash: &ValidationCodeHash, +) -> [u8; 132] { + // 32-byte hash length is protected in a test below. + let mut payload = [0u8; 132]; + + payload[0..32].copy_from_slice(relay_parent.as_ref()); + u32::from(*para_id).using_encoded(|s| payload[32..32 + s.len()].copy_from_slice(s)); + payload[36..68].copy_from_slice(persisted_validation_data_hash.as_ref()); + payload[68..100].copy_from_slice(pov_hash.as_ref()); + payload[100..132].copy_from_slice(validation_code_hash.as_ref()); + + payload +} + +fn check_collator_signature>( + relay_parent: &H, + para_id: &Id, + persisted_validation_data_hash: &Hash, + pov_hash: &Hash, + validation_code_hash: &ValidationCodeHash, + collator: &CollatorId, + signature: &CollatorSignature, +) -> Result<(), ()> { + let payload = collator_signature_payload( + relay_parent, + para_id, + persisted_validation_data_hash, + pov_hash, + validation_code_hash, + ); + + if signature.verify(&payload[..], collator) { + Ok(()) + } else { + Err(()) + } +} + +/// A unique descriptor of the candidate receipt. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct CandidateDescriptor { + /// The ID of the para this is a candidate for. + pub para_id: Id, + /// The hash of the relay-chain block this is executed in the context of. + pub relay_parent: H, + /// The collator's sr25519 public key. + pub collator: CollatorId, + /// The blake2-256 hash of the persisted validation data. This is extra data derived from + /// relay-chain state which may vary based on bitfields included before the candidate. + /// Thus it cannot be derived entirely from the relay-parent. + pub persisted_validation_data_hash: Hash, + /// The blake2-256 hash of the PoV. + pub pov_hash: Hash, + /// The root of a block's erasure encoding Merkle tree. + pub erasure_root: Hash, + /// Signature on blake2-256 of components of this receipt: + /// The parachain index, the relay parent, the validation data hash, and the `pov_hash`. + pub signature: CollatorSignature, + /// Hash of the para header that is being generated by this candidate. + pub para_head: Hash, + /// The blake2-256 hash of the validation code bytes. + pub validation_code_hash: ValidationCodeHash, +} + +impl> CandidateDescriptor { + /// Check the signature of the collator within this descriptor. + pub fn check_collator_signature(&self) -> Result<(), ()> { + check_collator_signature( + &self.relay_parent, + &self.para_id, + &self.persisted_validation_data_hash, + &self.pov_hash, + &self.validation_code_hash, + &self.collator, + &self.signature, + ) + } +} + +/// A candidate-receipt. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +pub struct CandidateReceipt { + /// The descriptor of the candidate. + pub descriptor: CandidateDescriptor, + /// The hash of the encoded commitments made as a result of candidate execution. + pub commitments_hash: Hash, +} + +impl CandidateReceipt { + /// Get a reference to the candidate descriptor. + pub fn descriptor(&self) -> &CandidateDescriptor { + &self.descriptor + } + + /// Computes the blake2-256 hash of the receipt. + pub fn hash(&self) -> CandidateHash + where + H: Encode, + { + CandidateHash(BlakeTwo256::hash_of(self)) + } +} + +/// All data pertaining to the execution of a para candidate. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +pub struct FullCandidateReceipt { + /// The inner candidate receipt. + pub inner: CandidateReceipt, + /// The validation data derived from the relay-chain state at that + /// point. The hash of the persisted validation data should + /// match the `persisted_validation_data_hash` in the descriptor + /// of the receipt. + pub validation_data: PersistedValidationData, +} + +/// A candidate-receipt with commitments directly included. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct CommittedCandidateReceipt { + /// The descriptor of the candidate. + pub descriptor: CandidateDescriptor, + /// The commitments of the candidate receipt. + pub commitments: CandidateCommitments, +} + +impl CommittedCandidateReceipt { + /// Get a reference to the candidate descriptor. + pub fn descriptor(&self) -> &CandidateDescriptor { + &self.descriptor + } +} + +impl CommittedCandidateReceipt { + /// Transforms this into a plain `CandidateReceipt`. + pub fn to_plain(&self) -> CandidateReceipt { + CandidateReceipt { + descriptor: self.descriptor.clone(), + commitments_hash: self.commitments.hash(), + } + } + + /// Computes the hash of the committed candidate receipt. + /// + /// This computes the canonical hash, not the hash of the directly encoded data. + /// Thus this is a shortcut for `candidate.to_plain().hash()`. + pub fn hash(&self) -> CandidateHash + where + H: Encode, + { + self.to_plain().hash() + } + + /// Does this committed candidate receipt corresponds to the given [`CandidateReceipt`]? + pub fn corresponds_to(&self, receipt: &CandidateReceipt) -> bool + where + H: PartialEq, + { + receipt.descriptor == self.descriptor && receipt.commitments_hash == self.commitments.hash() + } +} + +impl PartialOrd for CommittedCandidateReceipt { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for CommittedCandidateReceipt { + fn cmp(&self, other: &Self) -> sp_std::cmp::Ordering { + // TODO: compare signatures or something more sane + // https://github.com/paritytech/polkadot/issues/222 + self.descriptor() + .para_id + .cmp(&other.descriptor().para_id) + .then_with(|| self.commitments.head_data.cmp(&other.commitments.head_data)) + } +} + +/// The validation data provides information about how to create the inputs for validation of a +/// candidate. This information is derived from the chain state and will vary from para to para, +/// although some fields may be the same for every para. +/// +/// Since this data is used to form inputs to the validation function, it needs to be persisted by +/// the availability system to avoid dependence on availability of the relay-chain state. +/// +/// Furthermore, the validation data acts as a way to authorize the additional data the collator +/// needs to pass to the validation function. For example, the validation function can check whether +/// the incoming messages (e.g. downward messages) were actually sent by using the data provided in +/// the validation data using so called MQC heads. +/// +/// Since the commitments of the validation function are checked by the relay-chain, secondary +/// checkers can rely on the invariant that the relay-chain only includes para-blocks for which +/// these checks have already been done. As such, there is no need for the validation data used to +/// inform validators and collators about the checks the relay-chain will perform to be persisted by +/// the availability system. +/// +/// The `PersistedValidationData` should be relatively lightweight primarily because it is +/// constructed during inclusion for each candidate and therefore lies on the critical path of +/// inclusion. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Default))] +pub struct PersistedValidationData { + /// The parent head-data. + pub parent_head: HeadData, + /// The relay-chain block number this is in the context of. + pub relay_parent_number: N, + /// The relay-chain block storage root this is in the context of. + pub relay_parent_storage_root: H, + /// The maximum legal size of a POV block, in bytes. + pub max_pov_size: u32, +} + +impl PersistedValidationData { + /// Compute the blake2-256 hash of the persisted validation data. + pub fn hash(&self) -> Hash { + BlakeTwo256::hash_of(self) + } +} + +/// Commitments made in a `CandidateReceipt`. Many of these are outputs of validation. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Default, Hash))] +pub struct CandidateCommitments { + /// Messages destined to be interpreted by the Relay chain itself. + pub upward_messages: UpwardMessages, + /// Horizontal messages sent by the parachain. + pub horizontal_messages: HorizontalMessages, + /// New validation code. + pub new_validation_code: Option, + /// The head-data produced as a result of execution. + pub head_data: HeadData, + /// The number of messages processed from the DMQ. + pub processed_downward_messages: u32, + /// The mark which specifies the block number up to which all inbound HRMP messages are + /// processed. + pub hrmp_watermark: N, +} + +impl CandidateCommitments { + /// Compute the blake2-256 hash of the commitments. + pub fn hash(&self) -> Hash { + BlakeTwo256::hash_of(self) + } +} + +/// A bitfield concerning availability of backed candidates. +/// +/// Every bit refers to an availability core index. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct AvailabilityBitfield(pub BitVec); + +impl From> for AvailabilityBitfield { + fn from(inner: BitVec) -> Self { + AvailabilityBitfield(inner) + } +} + +/// A signed compact statement, suitable to be sent to the chain. +pub type SignedStatement = Signed; +/// A signed compact statement, with signature not yet checked. +pub type UncheckedSignedStatement = UncheckedSigned; + +/// A bitfield signed by a particular validator about the availability of pending candidates. +pub type SignedAvailabilityBitfield = Signed; +/// A signed bitfield with signature not yet checked. +pub type UncheckedSignedAvailabilityBitfield = UncheckedSigned; + +/// A set of signed availability bitfields. Should be sorted by validator index, ascending. +pub type SignedAvailabilityBitfields = Vec; +/// A set of unchecked signed availability bitfields. Should be sorted by validator index, +/// ascending. +pub type UncheckedSignedAvailabilityBitfields = Vec; + +/// A backed (or backable, depending on context) candidate. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct BackedCandidate { + /// The candidate referred to. + pub candidate: CommittedCandidateReceipt, + /// The validity votes themselves, expressed as signatures. + pub validity_votes: Vec, + /// The indices of the validators within the group, expressed as a bitfield. + pub validator_indices: BitVec, +} + +impl BackedCandidate { + /// Get a reference to the descriptor of the para. + pub fn descriptor(&self) -> &CandidateDescriptor { + &self.candidate.descriptor + } + + /// Compute this candidate's hash. + pub fn hash(&self) -> CandidateHash + where + H: Clone + Encode, + { + self.candidate.hash() + } + + /// Get this candidate's receipt. + pub fn receipt(&self) -> CandidateReceipt + where + H: Clone, + { + self.candidate.to_plain() + } +} + +/// Verify the backing of the given candidate. +/// +/// Provide a lookup from the index of a validator within the group assigned to this para, +/// as opposed to the index of the validator within the overall validator set, as well as +/// the number of validators in the group. +/// +/// Also provide the signing context. +/// +/// Returns either an error, indicating that one of the signatures was invalid or that the index +/// was out-of-bounds, or the number of signatures checked. +pub fn check_candidate_backing + Clone + Encode>( + backed: &BackedCandidate, + signing_context: &SigningContext, + group_len: usize, + validator_lookup: impl Fn(usize) -> Option, +) -> Result { + if backed.validator_indices.len() != group_len { + return Err(()) + } + + if backed.validity_votes.len() > group_len { + return Err(()) + } + + // this is known, even in runtime, to be blake2-256. + let hash = backed.candidate.hash(); + + let mut signed = 0; + for ((val_in_group_idx, _), attestation) in backed + .validator_indices + .iter() + .enumerate() + .filter(|(_, signed)| **signed) + .zip(backed.validity_votes.iter()) + { + let validator_id = validator_lookup(val_in_group_idx).ok_or(())?; + let payload = attestation.signed_payload(hash, signing_context); + let sig = attestation.signature(); + + if sig.verify(&payload[..], &validator_id) { + signed += 1; + } else { + return Err(()) + } + } + + if signed != backed.validity_votes.len() { + return Err(()) + } + + Ok(signed) +} + +/// The unique (during session) index of a core. +#[derive( + Encode, Decode, Default, PartialOrd, Ord, Eq, PartialEq, Clone, Copy, TypeInfo, RuntimeDebug, +)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct CoreIndex(pub u32); + +impl From for CoreIndex { + fn from(i: u32) -> CoreIndex { + CoreIndex(i) + } +} + +impl TypeIndex for CoreIndex { + fn type_index(&self) -> usize { + self.0 as usize + } +} + +/// The unique (during session) index of a validator group. +#[derive(Encode, Decode, Default, Clone, Copy, Debug, PartialEq, Eq, TypeInfo, PartialOrd, Ord)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct GroupIndex(pub u32); + +impl From for GroupIndex { + fn from(i: u32) -> GroupIndex { + GroupIndex(i) + } +} + +impl TypeIndex for GroupIndex { + fn type_index(&self) -> usize { + self.0 as usize + } +} + +/// A claim on authoring the next block for a given parathread (on-demand parachain). +#[derive(Clone, Encode, Decode, TypeInfo, PartialEq, RuntimeDebug)] +pub struct ParathreadClaim(pub Id, pub Option); + +/// An entry tracking a claim to ensure it does not pass the maximum number of retries. +#[derive(Clone, Encode, Decode, TypeInfo, PartialEq, RuntimeDebug)] +pub struct ParathreadEntry { + /// The claim. + pub claim: ParathreadClaim, + /// Number of retries + pub retries: u32, +} + +/// An assignment for a parachain scheduled to be backed and included in a relay chain block. +#[derive(Clone, Encode, Decode, PartialEq, TypeInfo, RuntimeDebug)] +pub struct Assignment { + /// Assignment's ParaId + pub para_id: Id, +} + +impl Assignment { + /// Create a new `Assignment`. + pub fn new(para_id: Id) -> Self { + Self { para_id } + } +} + +/// An entry tracking a paras +#[derive(Clone, Encode, Decode, TypeInfo, PartialEq, RuntimeDebug)] +pub struct ParasEntry { + /// The `Assignment` + pub assignment: Assignment, + /// The number of times the entry has timed out in availability. + pub availability_timeouts: u32, + /// The block height where this entry becomes invalid. + pub ttl: N, +} + +impl ParasEntry { + /// Return `Id` from the underlying `Assignment`. + pub fn para_id(&self) -> Id { + self.assignment.para_id + } + + /// Create a new `ParasEntry`. + pub fn new(assignment: Assignment, now: N) -> Self { + ParasEntry { assignment, availability_timeouts: 0, ttl: now } + } +} + +/// What is occupying a specific availability core. +#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub enum CoreOccupied { + /// The core is not occupied. + Free, + /// A paras. + Paras(ParasEntry), +} + +impl CoreOccupied { + /// Is core free? + pub fn is_free(&self) -> bool { + matches!(self, Self::Free) + } +} + +/// A helper data-type for tracking validator-group rotations. +#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct GroupRotationInfo { + /// The block number where the session started. + pub session_start_block: N, + /// How often groups rotate. 0 means never. + pub group_rotation_frequency: N, + /// The current block number. + pub now: N, +} + +impl GroupRotationInfo { + /// Returns the index of the group needed to validate the core at the given index, assuming + /// the given number of cores. + /// + /// `core_index` should be less than `cores`, which is capped at `u32::max()`. + pub fn group_for_core(&self, core_index: CoreIndex, cores: usize) -> GroupIndex { + if self.group_rotation_frequency == 0 { + return GroupIndex(core_index.0) + } + if cores == 0 { + return GroupIndex(0) + } + + let cores = sp_std::cmp::min(cores, u32::MAX as usize); + let blocks_since_start = self.now.saturating_sub(self.session_start_block); + let rotations = blocks_since_start / self.group_rotation_frequency; + + // g = c + r mod cores + + let idx = (core_index.0 as usize + rotations as usize) % cores; + GroupIndex(idx as u32) + } + + /// Returns the index of the group assigned to the given core. This does no checking or + /// whether the group index is in-bounds. + /// + /// `core_index` should be less than `cores`, which is capped at `u32::max()`. + pub fn core_for_group(&self, group_index: GroupIndex, cores: usize) -> CoreIndex { + if self.group_rotation_frequency == 0 { + return CoreIndex(group_index.0) + } + if cores == 0 { + return CoreIndex(0) + } + + let cores = sp_std::cmp::min(cores, u32::MAX as usize); + let blocks_since_start = self.now.saturating_sub(self.session_start_block); + let rotations = blocks_since_start / self.group_rotation_frequency; + let rotations = rotations % cores as u32; + + // g = c + r mod cores + // c = g - r mod cores + // x = x + cores mod cores + // c = (g + cores) - r mod cores + + let idx = (group_index.0 as usize + cores - rotations as usize) % cores; + CoreIndex(idx as u32) + } + + /// Create a new `GroupRotationInfo` with one further rotation applied. + pub fn bump_rotation(&self) -> Self { + GroupRotationInfo { + session_start_block: self.session_start_block, + group_rotation_frequency: self.group_rotation_frequency, + now: self.next_rotation_at(), + } + } +} + +impl GroupRotationInfo { + /// Returns the block number of the next rotation after the current block. If the current block + /// is 10 and the rotation frequency is 5, this should return 15. + pub fn next_rotation_at(&self) -> N { + let cycle_once = self.now + self.group_rotation_frequency; + cycle_once - + (cycle_once.saturating_sub(self.session_start_block) % self.group_rotation_frequency) + } + + /// Returns the block number of the last rotation before or including the current block. If the + /// current block is 10 and the rotation frequency is 5, this should return 10. + pub fn last_rotation_at(&self) -> N { + self.now - + (self.now.saturating_sub(self.session_start_block) % self.group_rotation_frequency) + } +} + +/// Information about a core which is currently occupied. +#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct OccupiedCore { + // NOTE: this has no ParaId as it can be deduced from the candidate descriptor. + /// If this core is freed by availability, this is the assignment that is next up on this + /// core, if any. None if there is nothing queued for this core. + pub next_up_on_available: Option, + /// The relay-chain block number this began occupying the core at. + pub occupied_since: N, + /// The relay-chain block this will time-out at, if any. + pub time_out_at: N, + /// If this core is freed by being timed-out, this is the assignment that is next up on this + /// core. None if there is nothing queued for this core or there is no possibility of timing + /// out. + pub next_up_on_time_out: Option, + /// A bitfield with 1 bit for each validator in the set. `1` bits mean that the corresponding + /// validators has attested to availability on-chain. A 2/3+ majority of `1` bits means that + /// this will be available. + pub availability: BitVec, + /// The group assigned to distribute availability pieces of this candidate. + pub group_responsible: GroupIndex, + /// The hash of the candidate occupying the core. + pub candidate_hash: CandidateHash, + /// The descriptor of the candidate occupying the core. + pub candidate_descriptor: CandidateDescriptor, +} + +impl OccupiedCore { + /// Get the Para currently occupying this core. + pub fn para_id(&self) -> Id { + self.candidate_descriptor.para_id + } +} + +/// Information about a core which is currently occupied. +#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct ScheduledCore { + /// The ID of a para scheduled. + pub para_id: Id, + /// DEPRECATED: see: https://github.com/paritytech/polkadot/issues/7575 + /// + /// Will be removed in a future version. + pub collator: Option, +} + +/// The state of a particular availability core. +#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub enum CoreState { + /// The core is currently occupied. + #[codec(index = 0)] + Occupied(OccupiedCore), + /// The core is currently free, with a para scheduled and given the opportunity + /// to occupy. + /// + /// If a particular Collator is required to author this block, that is also present in this + /// variant. + #[codec(index = 1)] + Scheduled(ScheduledCore), + /// The core is currently free and there is nothing scheduled. This can be the case for + /// parathread cores when there are no parathread blocks queued. Parachain cores will never be + /// left idle. + #[codec(index = 2)] + Free, +} + +impl CoreState { + /// If this core state has a `para_id`, return it. + pub fn para_id(&self) -> Option { + match self { + Self::Occupied(ref core) => Some(core.para_id()), + Self::Scheduled(core) => Some(core.para_id), + Self::Free => None, + } + } + + /// Is this core state `Self::Occupied`? + pub fn is_occupied(&self) -> bool { + matches!(self, Self::Occupied(_)) + } +} + +/// An assumption being made about the state of an occupied core. +#[derive(Clone, Copy, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq, Eq, Hash))] +pub enum OccupiedCoreAssumption { + /// The candidate occupying the core was made available and included to free the core. + #[codec(index = 0)] + Included, + /// The candidate occupying the core timed out and freed the core without advancing the para. + #[codec(index = 1)] + TimedOut, + /// The core was not occupied to begin with. + #[codec(index = 2)] + Free, +} + +/// An even concerning a candidate. +#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub enum CandidateEvent { + /// This candidate receipt was backed in the most recent block. + /// This includes the core index the candidate is now occupying. + #[codec(index = 0)] + CandidateBacked(CandidateReceipt, HeadData, CoreIndex, GroupIndex), + /// This candidate receipt was included and became a parablock at the most recent block. + /// This includes the core index the candidate was occupying as well as the group responsible + /// for backing the candidate. + #[codec(index = 1)] + CandidateIncluded(CandidateReceipt, HeadData, CoreIndex, GroupIndex), + /// This candidate receipt was not made available in time and timed out. + /// This includes the core index the candidate was occupying. + #[codec(index = 2)] + CandidateTimedOut(CandidateReceipt, HeadData, CoreIndex), +} + +/// Scraped runtime backing votes and resolved disputes. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct ScrapedOnChainVotes { + /// The session in which the block was included. + pub session: SessionIndex, + /// Set of backing validators for each candidate, represented by its candidate + /// receipt. + pub backing_validators_per_candidate: + Vec<(CandidateReceipt, Vec<(ValidatorIndex, ValidityAttestation)>)>, + /// On-chain-recorded set of disputes. + /// Note that the above `backing_validators` are + /// unrelated to the backers of the disputes candidates. + pub disputes: MultiDisputeStatementSet, +} + +/// A vote of approval on a candidate. +#[derive(Clone, RuntimeDebug)] +pub struct ApprovalVote(pub CandidateHash); + +impl ApprovalVote { + /// Yields the signing payload for this approval vote. + pub fn signing_payload(&self, session_index: SessionIndex) -> Vec { + const MAGIC: [u8; 4] = *b"APPR"; + + (MAGIC, &self.0, session_index).encode() + } +} + +/// Custom validity errors used in Polkadot while validating transactions. +#[repr(u8)] +pub enum ValidityError { + /// The Ethereum signature is invalid. + InvalidEthereumSignature = 0, + /// The signer has no claim. + SignerHasNoClaim = 1, + /// No permission to execute the call. + NoPermission = 2, + /// An invalid statement was made for a claim. + InvalidStatement = 3, +} + +impl From for u8 { + fn from(err: ValidityError) -> Self { + err as u8 + } +} + +/// Abridged version of `HostConfiguration` (from the `Configuration` parachains host runtime +/// module) meant to be used by a parachain or PDK such as cumulus. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct AbridgedHostConfiguration { + /// The maximum validation code size, in bytes. + pub max_code_size: u32, + /// The maximum head-data size, in bytes. + pub max_head_data_size: u32, + /// Total number of individual messages allowed in the parachain -> relay-chain message queue. + pub max_upward_queue_count: u32, + /// Total size of messages allowed in the parachain -> relay-chain message queue before which + /// no further messages may be added to it. If it exceeds this then the queue may contain only + /// a single message. + pub max_upward_queue_size: u32, + /// The maximum size of an upward message that can be sent by a candidate. + /// + /// This parameter affects the size upper bound of the `CandidateCommitments`. + pub max_upward_message_size: u32, + /// The maximum number of messages that a candidate can contain. + /// + /// This parameter affects the size upper bound of the `CandidateCommitments`. + pub max_upward_message_num_per_candidate: u32, + /// The maximum number of outbound HRMP messages can be sent by a candidate. + /// + /// This parameter affects the upper bound of size of `CandidateCommitments`. + pub hrmp_max_message_num_per_candidate: u32, + /// The minimum period, in blocks, between which parachains can update their validation code. + pub validation_upgrade_cooldown: BlockNumber, + /// The delay, in blocks, before a validation upgrade is applied. + pub validation_upgrade_delay: BlockNumber, + /// Asynchronous backing parameters. + pub async_backing_params: super::vstaging::AsyncBackingParams, +} + +/// Abridged version of `HrmpChannel` (from the `Hrmp` parachains host runtime module) meant to be +/// used by a parachain or PDK such as cumulus. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct AbridgedHrmpChannel { + /// The maximum number of messages that can be pending in the channel at once. + pub max_capacity: u32, + /// The maximum total size of the messages that can be pending in the channel at once. + pub max_total_size: u32, + /// The maximum message size that could be put into the channel. + pub max_message_size: u32, + /// The current number of messages pending in the channel. + /// Invariant: should be less or equal to `max_capacity`.s`. + pub msg_count: u32, + /// The total size in bytes of all message payloads in the channel. + /// Invariant: should be less or equal to `max_total_size`. + pub total_size: u32, + /// A head of the Message Queue Chain for this channel. Each link in this chain has a form: + /// `(prev_head, B, H(M))`, where + /// - `prev_head`: is the previous value of `mqc_head` or zero if none. + /// - `B`: is the [relay-chain] block number in which a message was appended + /// - `H(M)`: is the hash of the message being appended. + /// This value is initialized to a special value that consists of all zeroes which indicates + /// that no messages were previously added. + pub mqc_head: Option, +} + +/// A possible upgrade restriction that prevents a parachain from performing an upgrade. +#[derive(Copy, Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] +pub enum UpgradeRestriction { + /// There is an upgrade restriction and there are no details about its specifics nor how long + /// it could last. + #[codec(index = 0)] + Present, +} + +/// A struct that the relay-chain communicates to a parachain indicating what course of action the +/// parachain should take in the coordinated parachain validation code upgrade process. +/// +/// This data type appears in the last step of the upgrade process. After the parachain observes it +/// and reacts to it the upgrade process concludes. +#[derive(Copy, Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] +pub enum UpgradeGoAhead { + /// Abort the upgrade process. There is something wrong with the validation code previously + /// submitted by the parachain. This variant can also be used to prevent upgrades by the + /// governance should an emergency emerge. + /// + /// The expected reaction on this variant is that the parachain will admit this message and + /// remove all the data about the pending upgrade. Depending on the nature of the problem (to + /// be examined offchain for now), it can try to send another validation code or just retry + /// later. + #[codec(index = 0)] + Abort, + /// Apply the pending code change. The parablock that is built on a relay-parent that is + /// descendant of the relay-parent where the parachain observed this signal must use the + /// upgraded validation code. + #[codec(index = 1)] + GoAhead, +} + +/// Consensus engine id for polkadot v1 consensus engine. +pub const POLKADOT_ENGINE_ID: runtime_primitives::ConsensusEngineId = *b"POL1"; + +/// A consensus log item for polkadot validation. To be used with [`POLKADOT_ENGINE_ID`]. +#[derive(Decode, Encode, Clone, PartialEq, Eq)] +pub enum ConsensusLog { + /// A parachain upgraded its code. + #[codec(index = 1)] + ParaUpgradeCode(Id, ValidationCodeHash), + /// A parachain scheduled a code upgrade. + #[codec(index = 2)] + ParaScheduleUpgradeCode(Id, ValidationCodeHash, BlockNumber), + /// Governance requests to auto-approve every candidate included up to the given block + /// number in the current chain, inclusive. + #[codec(index = 3)] + ForceApprove(BlockNumber), + /// A signal to revert the block number in the same chain as the + /// header this digest is part of and all of its descendants. + /// + /// It is a no-op for a block to contain a revert digest targeting + /// its own number or a higher number. + /// + /// In practice, these are issued when on-chain logic has detected an + /// invalid parachain block within its own chain, due to a dispute. + #[codec(index = 4)] + Revert(BlockNumber), +} + +impl ConsensusLog { + /// Attempt to convert a reference to a generic digest item into a consensus log. + pub fn from_digest_item( + digest_item: &runtime_primitives::DigestItem, + ) -> Result, parity_scale_codec::Error> { + match digest_item { + runtime_primitives::DigestItem::Consensus(id, encoded) if id == &POLKADOT_ENGINE_ID => + Ok(Some(Self::decode(&mut &encoded[..])?)), + _ => Ok(None), + } + } +} + +impl From for runtime_primitives::DigestItem { + fn from(c: ConsensusLog) -> runtime_primitives::DigestItem { + Self::Consensus(POLKADOT_ENGINE_ID, c.encode()) + } +} + +/// A statement about a candidate, to be used within the dispute resolution process. +/// +/// Statements are either in favor of the candidate's validity or against it. +#[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug, TypeInfo)] +pub enum DisputeStatement { + /// A valid statement, of the given kind. + #[codec(index = 0)] + Valid(ValidDisputeStatementKind), + /// An invalid statement, of the given kind. + #[codec(index = 1)] + Invalid(InvalidDisputeStatementKind), +} + +impl DisputeStatement { + /// Get the payload data for this type of dispute statement. + pub fn payload_data(&self, candidate_hash: CandidateHash, session: SessionIndex) -> Vec { + match *self { + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit) => + ExplicitDisputeStatement { valid: true, candidate_hash, session }.signing_payload(), + DisputeStatement::Valid(ValidDisputeStatementKind::BackingSeconded( + inclusion_parent, + )) => CompactStatement::Seconded(candidate_hash).signing_payload(&SigningContext { + session_index: session, + parent_hash: inclusion_parent, + }), + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid(inclusion_parent)) => + CompactStatement::Valid(candidate_hash).signing_payload(&SigningContext { + session_index: session, + parent_hash: inclusion_parent, + }), + DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking) => + ApprovalVote(candidate_hash).signing_payload(session), + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit) => + ExplicitDisputeStatement { valid: false, candidate_hash, session }.signing_payload(), + } + } + + /// Check the signature on a dispute statement. + pub fn check_signature( + &self, + validator_public: &ValidatorId, + candidate_hash: CandidateHash, + session: SessionIndex, + validator_signature: &ValidatorSignature, + ) -> Result<(), ()> { + let payload = self.payload_data(candidate_hash, session); + + if validator_signature.verify(&payload[..], &validator_public) { + Ok(()) + } else { + Err(()) + } + } + + /// Whether the statement indicates validity. + pub fn indicates_validity(&self) -> bool { + match *self { + DisputeStatement::Valid(_) => true, + DisputeStatement::Invalid(_) => false, + } + } + + /// Whether the statement indicates invalidity. + pub fn indicates_invalidity(&self) -> bool { + match *self { + DisputeStatement::Valid(_) => false, + DisputeStatement::Invalid(_) => true, + } + } + + /// Statement is backing statement. + pub fn is_backing(&self) -> bool { + match *self { + Self::Valid(ValidDisputeStatementKind::BackingSeconded(_)) | + Self::Valid(ValidDisputeStatementKind::BackingValid(_)) => true, + Self::Valid(ValidDisputeStatementKind::Explicit) | + Self::Valid(ValidDisputeStatementKind::ApprovalChecking) | + Self::Invalid(_) => false, + } + } +} + +/// Different kinds of statements of validity on a candidate. +#[derive(Encode, Decode, Copy, Clone, PartialEq, RuntimeDebug, TypeInfo)] +pub enum ValidDisputeStatementKind { + /// An explicit statement issued as part of a dispute. + #[codec(index = 0)] + Explicit, + /// A seconded statement on a candidate from the backing phase. + #[codec(index = 1)] + BackingSeconded(Hash), + /// A valid statement on a candidate from the backing phase. + #[codec(index = 2)] + BackingValid(Hash), + /// An approval vote from the approval checking phase. + #[codec(index = 3)] + ApprovalChecking, +} + +/// Different kinds of statements of invalidity on a candidate. +#[derive(Encode, Decode, Copy, Clone, PartialEq, RuntimeDebug, TypeInfo)] +pub enum InvalidDisputeStatementKind { + /// An explicit statement issued as part of a dispute. + #[codec(index = 0)] + Explicit, +} + +/// An explicit statement on a candidate issued as part of a dispute. +#[derive(Clone, PartialEq, RuntimeDebug)] +pub struct ExplicitDisputeStatement { + /// Whether the candidate is valid + pub valid: bool, + /// The candidate hash. + pub candidate_hash: CandidateHash, + /// The session index of the candidate. + pub session: SessionIndex, +} + +impl ExplicitDisputeStatement { + /// Produce the payload used for signing this type of statement. + pub fn signing_payload(&self) -> Vec { + const MAGIC: [u8; 4] = *b"DISP"; + + (MAGIC, self.valid, self.candidate_hash, self.session).encode() + } +} + +/// A set of statements about a specific candidate. +#[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug, TypeInfo)] +pub struct DisputeStatementSet { + /// The candidate referenced by this set. + pub candidate_hash: CandidateHash, + /// The session index of the candidate. + pub session: SessionIndex, + /// Statements about the candidate. + pub statements: Vec<(DisputeStatement, ValidatorIndex, ValidatorSignature)>, +} + +impl From for DisputeStatementSet { + fn from(other: CheckedDisputeStatementSet) -> Self { + other.0 + } +} + +impl AsRef for DisputeStatementSet { + fn as_ref(&self) -> &DisputeStatementSet { + &self + } +} + +/// A set of dispute statements. +pub type MultiDisputeStatementSet = Vec; + +/// A _checked_ set of dispute statements. +#[derive(Clone, PartialEq, RuntimeDebug, Encode)] +pub struct CheckedDisputeStatementSet(DisputeStatementSet); + +impl AsRef for CheckedDisputeStatementSet { + fn as_ref(&self) -> &DisputeStatementSet { + &self.0 + } +} + +impl core::cmp::PartialEq for CheckedDisputeStatementSet { + fn eq(&self, other: &DisputeStatementSet) -> bool { + self.0.eq(other) + } +} + +impl CheckedDisputeStatementSet { + /// Convert from an unchecked, the verification of correctness of the `unchecked` statement set + /// _must_ be done before calling this function! + pub fn unchecked_from_unchecked(unchecked: DisputeStatementSet) -> Self { + Self(unchecked) + } +} + +/// A set of _checked_ dispute statements. +pub type CheckedMultiDisputeStatementSet = Vec; + +/// The entire state of a dispute. +#[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, TypeInfo)] +pub struct DisputeState { + /// A bitfield indicating all validators for the candidate. + pub validators_for: BitVec, // one bit per validator. + /// A bitfield indicating all validators against the candidate. + pub validators_against: BitVec, // one bit per validator. + /// The block number at which the dispute started on-chain. + pub start: N, + /// The block number at which the dispute concluded on-chain. + pub concluded_at: Option, +} + +/// Parachains inherent-data passed into the runtime by a block author +#[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug, TypeInfo)] +pub struct InherentData { + /// Signed bitfields by validators about availability. + pub bitfields: UncheckedSignedAvailabilityBitfields, + /// Backed candidates for inclusion in the block. + pub backed_candidates: Vec>, + /// Sets of dispute votes for inclusion, + pub disputes: MultiDisputeStatementSet, + /// The parent block header. Used for checking state proofs. + pub parent_header: HDR, +} + +/// An either implicit or explicit attestation to the validity of a parachain +/// candidate. +#[derive(Clone, Eq, PartialEq, Decode, Encode, RuntimeDebug, TypeInfo)] +pub enum ValidityAttestation { + /// Implicit validity attestation by issuing. + /// This corresponds to issuance of a `Candidate` statement. + #[codec(index = 1)] + Implicit(ValidatorSignature), + /// An explicit attestation. This corresponds to issuance of a + /// `Valid` statement. + #[codec(index = 2)] + Explicit(ValidatorSignature), +} + +impl ValidityAttestation { + /// Produce the underlying signed payload of the attestation, given the hash of the candidate, + /// which should be known in context. + pub fn to_compact_statement(&self, candidate_hash: CandidateHash) -> CompactStatement { + // Explicit and implicit map directly from + // `ValidityVote::Valid` and `ValidityVote::Issued`, and hence there is a + // `1:1` relationshow which enables the conversion. + match *self { + ValidityAttestation::Implicit(_) => CompactStatement::Seconded(candidate_hash), + ValidityAttestation::Explicit(_) => CompactStatement::Valid(candidate_hash), + } + } + + /// Get a reference to the signature. + pub fn signature(&self) -> &ValidatorSignature { + match *self { + ValidityAttestation::Implicit(ref sig) => sig, + ValidityAttestation::Explicit(ref sig) => sig, + } + } + + /// Produce the underlying signed payload of the attestation, given the hash of the candidate, + /// which should be known in context. + pub fn signed_payload( + &self, + candidate_hash: CandidateHash, + signing_context: &SigningContext, + ) -> Vec { + match *self { + ValidityAttestation::Implicit(_) => + (CompactStatement::Seconded(candidate_hash), signing_context).encode(), + ValidityAttestation::Explicit(_) => + (CompactStatement::Valid(candidate_hash), signing_context).encode(), + } + } +} + +/// A type returned by runtime with current session index and a parent hash. +#[derive(Clone, Eq, PartialEq, Default, Decode, Encode, RuntimeDebug)] +pub struct SigningContext { + /// Current session index. + pub session_index: sp_staking::SessionIndex, + /// Hash of the parent. + pub parent_hash: H, +} + +const BACKING_STATEMENT_MAGIC: [u8; 4] = *b"BKNG"; + +/// Statements that can be made about parachain candidates. These are the +/// actual values that are signed. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] +pub enum CompactStatement { + /// Proposal of a parachain candidate. + Seconded(CandidateHash), + /// State that a parachain candidate is valid. + Valid(CandidateHash), +} + +impl CompactStatement { + /// Yields the payload used for validator signatures on this kind + /// of statement. + pub fn signing_payload(&self, context: &SigningContext) -> Vec { + (self, context).encode() + } + + /// Get the underlying candidate hash this references. + pub fn candidate_hash(&self) -> &CandidateHash { + match *self { + CompactStatement::Seconded(ref h) | CompactStatement::Valid(ref h) => h, + } + } +} + +// Inner helper for codec on `CompactStatement`. +#[derive(Encode, Decode, TypeInfo)] +enum CompactStatementInner { + #[codec(index = 1)] + Seconded(CandidateHash), + #[codec(index = 2)] + Valid(CandidateHash), +} + +impl From for CompactStatementInner { + fn from(s: CompactStatement) -> Self { + match s { + CompactStatement::Seconded(h) => CompactStatementInner::Seconded(h), + CompactStatement::Valid(h) => CompactStatementInner::Valid(h), + } + } +} + +impl parity_scale_codec::Encode for CompactStatement { + fn size_hint(&self) -> usize { + // magic + discriminant + payload + 4 + 1 + 32 + } + + fn encode_to(&self, dest: &mut T) { + dest.write(&BACKING_STATEMENT_MAGIC); + CompactStatementInner::from(self.clone()).encode_to(dest) + } +} + +impl parity_scale_codec::Decode for CompactStatement { + fn decode( + input: &mut I, + ) -> Result { + let maybe_magic = <[u8; 4]>::decode(input)?; + if maybe_magic != BACKING_STATEMENT_MAGIC { + return Err(parity_scale_codec::Error::from("invalid magic string")) + } + + Ok(match CompactStatementInner::decode(input)? { + CompactStatementInner::Seconded(h) => CompactStatement::Seconded(h), + CompactStatementInner::Valid(h) => CompactStatement::Valid(h), + }) + } +} + +/// `IndexedVec` struct indexed by type specific indices. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct IndexedVec(Vec, PhantomData K>); + +impl Default for IndexedVec { + fn default() -> Self { + Self(vec![], PhantomData) + } +} + +impl From> for IndexedVec { + fn from(validators: Vec) -> Self { + Self(validators, PhantomData) + } +} + +impl FromIterator for IndexedVec { + fn from_iter>(iter: T) -> Self { + Self(Vec::from_iter(iter), PhantomData) + } +} + +impl IndexedVec +where + V: Clone, +{ + /// Returns a reference to an element indexed using `K`. + pub fn get(&self, index: K) -> Option<&V> + where + K: TypeIndex, + { + self.0.get(index.type_index()) + } + + /// Returns number of elements in vector. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Returns contained vector. + pub fn to_vec(&self) -> Vec { + self.0.clone() + } + + /// Returns an iterator over the underlying vector. + pub fn iter(&self) -> Iter<'_, V> { + self.0.iter() + } + + /// Returns a mutable iterator over the underlying vector. + pub fn iter_mut(&mut self) -> IterMut<'_, V> { + self.0.iter_mut() + } + + /// Creates a consuming iterator. + pub fn into_iter(self) -> IntoIter { + self.0.into_iter() + } + + /// Returns true if the underlying container is empty. + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + +/// The maximum number of validators `f` which may safely be faulty. +/// +/// The total number of validators is `n = 3f + e` where `e in { 1, 2, 3 }`. +pub const fn byzantine_threshold(n: usize) -> usize { + n.saturating_sub(1) / 3 +} + +/// The supermajority threshold of validators which represents a subset +/// guaranteed to have at least f+1 honest validators. +pub const fn supermajority_threshold(n: usize) -> usize { + n - byzantine_threshold(n) +} + +/// Information about validator sets of a session. +/// +/// NOTE: `SessionInfo` is frozen. Do not include new fields, consider creating a separate runtime +/// API. Reasoning and further outlook [here](https://github.com/paritytech/polkadot/issues/6586). +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct SessionInfo { + /****** New in v2 ****** */ + /// All the validators actively participating in parachain consensus. + /// Indices are into the broader validator set. + pub active_validator_indices: Vec, + /// A secure random seed for the session, gathered from BABE. + pub random_seed: [u8; 32], + /// The amount of sessions to keep for disputes. + pub dispute_period: SessionIndex, + + /****** Old fields ***** */ + /// Validators in canonical ordering. + /// + /// NOTE: There might be more authorities in the current session, than `validators` + /// participating in parachain consensus. See + /// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148). + /// + /// `SessionInfo::validators` will be limited to to `max_validators` when set. + pub validators: IndexedVec, + /// Validators' authority discovery keys for the session in canonical ordering. + /// + /// NOTE: The first `validators.len()` entries will match the corresponding validators in + /// `validators`, afterwards any remaining authorities can be found. This is any authorities + /// not participating in parachain consensus - see + /// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148) + pub discovery_keys: Vec, + /// The assignment keys for validators. + /// + /// NOTE: There might be more authorities in the current session, than validators participating + /// in parachain consensus. See + /// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148). + /// + /// Therefore: + /// ```ignore + /// assignment_keys.len() == validators.len() && validators.len() <= discovery_keys.len() + /// ``` + pub assignment_keys: Vec, + /// Validators in shuffled ordering - these are the validator groups as produced + /// by the `Scheduler` module for the session and are typically referred to by + /// `GroupIndex`. + pub validator_groups: IndexedVec>, + /// The number of availability cores used by the protocol during this session. + pub n_cores: u32, + /// The zeroth delay tranche width. + pub zeroth_delay_tranche_width: u32, + /// The number of samples we do of `relay_vrf_modulo`. + pub relay_vrf_modulo_samples: u32, + /// The number of delay tranches in total. + pub n_delay_tranches: u32, + /// How many slots (BABE / SASSAFRAS) must pass before an assignment is considered a + /// no-show. + pub no_show_slots: u32, + /// The number of validators needed to approve a block. + pub needed_approvals: u32, +} + +/// A statement from the specified validator whether the given validation code passes PVF +/// pre-checking or not anchored to the given session index. +#[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug, TypeInfo)] +pub struct PvfCheckStatement { + /// `true` if the subject passed pre-checking and `false` otherwise. + pub accept: bool, + /// The validation code hash that was checked. + pub subject: ValidationCodeHash, + /// The index of a session during which this statement is considered valid. + pub session_index: SessionIndex, + /// The index of the validator from which this statement originates. + pub validator_index: ValidatorIndex, +} + +impl PvfCheckStatement { + /// Produce the payload used for signing this type of statement. + /// + /// It is expected that it will be signed by the validator at `validator_index` in the + /// `session_index`. + pub fn signing_payload(&self) -> Vec { + const MAGIC: [u8; 4] = *b"VCPC"; // for "validation code pre-checking" + (MAGIC, self.accept, self.subject, self.session_index, self.validator_index).encode() + } +} + +/// A well-known and typed storage key. +/// +/// Allows for type-safe access to raw well-known storage keys. +pub struct WellKnownKey { + /// The raw storage key. + pub key: Vec, + _p: sp_std::marker::PhantomData, +} + +impl From> for WellKnownKey { + fn from(key: Vec) -> Self { + Self { key, _p: Default::default() } + } +} + +impl AsRef<[u8]> for WellKnownKey { + fn as_ref(&self) -> &[u8] { + self.key.as_ref() + } +} + +impl WellKnownKey { + /// Gets the value or `None` if it does not exist or decoding failed. + pub fn get(&self) -> Option { + sp_io::storage::get(&self.key) + .and_then(|raw| parity_scale_codec::DecodeAll::decode_all(&mut raw.as_ref()).ok()) + } +} + +impl WellKnownKey { + /// Sets the value. + pub fn set(&self, value: T) { + sp_io::storage::set(&self.key, &value.encode()); + } +} + +/// Type discriminator for PVF preparation timeouts +#[derive(Encode, Decode, TypeInfo, Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum PvfPrepTimeoutKind { + /// For prechecking requests, the time period after which the preparation worker is considered + /// unresponsive and will be killed. + Precheck, + + /// For execution and heads-up requests, the time period after which the preparation worker is + /// considered unresponsive and will be killed. More lenient than the timeout for prechecking + /// to prevent honest validators from timing out on valid PVFs. + Lenient, +} + +/// Type discriminator for PVF execution timeouts +#[derive(Encode, Decode, TypeInfo, Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum PvfExecTimeoutKind { + /// The amount of time to spend on execution during backing. + Backing, + + /// The amount of time to spend on execution during approval or disputes. + /// + /// This should be much longer than the backing execution timeout to ensure that in the + /// absence of extremely large disparities between hardware, blocks that pass backing are + /// considered executable by approval checkers or dispute participants. + Approval, +} + +pub mod executor_params; +pub use executor_params::{ExecutorParam, ExecutorParams, ExecutorParamsHash}; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn group_rotation_info_calculations() { + let info = + GroupRotationInfo { session_start_block: 10u32, now: 15, group_rotation_frequency: 5 }; + + assert_eq!(info.next_rotation_at(), 20); + assert_eq!(info.last_rotation_at(), 15); + } + + #[test] + fn group_for_core_is_core_for_group() { + for cores in 1..=256 { + for rotations in 0..(cores * 2) { + let info = GroupRotationInfo { + session_start_block: 0u32, + now: rotations, + group_rotation_frequency: 1, + }; + + for core in 0..cores { + let group = info.group_for_core(CoreIndex(core), cores as usize); + assert_eq!(info.core_for_group(group, cores as usize).0, core); + } + } + } + } + + #[test] + fn collator_signature_payload_is_valid() { + // if this fails, collator signature verification code has to be updated. + let h = Hash::default(); + assert_eq!(h.as_ref().len(), 32); + + let _payload = collator_signature_payload( + &Hash::repeat_byte(1), + &5u32.into(), + &Hash::repeat_byte(2), + &Hash::repeat_byte(3), + &Hash::repeat_byte(4).into(), + ); + } + + #[test] + fn test_byzantine_threshold() { + assert_eq!(byzantine_threshold(0), 0); + assert_eq!(byzantine_threshold(1), 0); + assert_eq!(byzantine_threshold(2), 0); + assert_eq!(byzantine_threshold(3), 0); + assert_eq!(byzantine_threshold(4), 1); + assert_eq!(byzantine_threshold(5), 1); + assert_eq!(byzantine_threshold(6), 1); + assert_eq!(byzantine_threshold(7), 2); + } + + #[test] + fn test_supermajority_threshold() { + assert_eq!(supermajority_threshold(0), 0); + assert_eq!(supermajority_threshold(1), 1); + assert_eq!(supermajority_threshold(2), 2); + assert_eq!(supermajority_threshold(3), 3); + assert_eq!(supermajority_threshold(4), 3); + assert_eq!(supermajority_threshold(5), 4); + assert_eq!(supermajority_threshold(6), 5); + assert_eq!(supermajority_threshold(7), 5); + } + + #[test] + fn balance_bigger_than_usize() { + let zero_b: Balance = 0; + let zero_u: usize = 0; + + assert!(zero_b.leading_zeros() >= zero_u.leading_zeros()); + } +} diff --git a/polkadot/primitives/src/v5/signed.rs b/polkadot/primitives/src/v5/signed.rs new file mode 100644 index 0000000000000000000000000000000000000000..96646d54cbbafbd9c1223a4fe43c5d48d70afaf9 --- /dev/null +++ b/polkadot/primitives/src/v5/signed.rs @@ -0,0 +1,367 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; + +#[cfg(feature = "std")] +use application_crypto::AppCrypto; +#[cfg(feature = "std")] +use sp_keystore::{Error as KeystoreError, KeystorePtr}; +use sp_std::prelude::Vec; + +use primitives::RuntimeDebug; +use runtime_primitives::traits::AppVerify; + +use super::{SigningContext, ValidatorId, ValidatorIndex, ValidatorSignature}; + +/// Signed data with signature already verified. +/// +/// NOTE: This type does not have an Encode/Decode instance, as this would cancel out our +/// valid signature guarantees. If you need to encode/decode you have to convert into an +/// `UncheckedSigned` first. +/// +/// `Signed` can easily be converted into `UncheckedSigned` and conversion back via `into_signed` +/// enforces a valid signature again. +#[derive(Clone, PartialEq, Eq, RuntimeDebug)] +pub struct Signed(UncheckedSigned); + +impl Signed { + /// Convert back to an unchecked type. + pub fn into_unchecked(self) -> UncheckedSigned { + self.0 + } +} + +/// Unchecked signed data, can be converted to `Signed` by checking the signature. +#[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo)] +pub struct UncheckedSigned { + /// The payload is part of the signed data. The rest is the signing context, + /// which is known both at signing and at validation. + payload: Payload, + /// The index of the validator signing this statement. + validator_index: ValidatorIndex, + /// The signature by the validator of the signed payload. + signature: ValidatorSignature, + /// This ensures the real payload is tracked at the typesystem level. + real_payload: sp_std::marker::PhantomData, +} + +impl, RealPayload: Encode> Signed { + /// Used to create a `Signed` from already existing parts. + /// + /// The signature is checked as part of the process. + #[cfg(feature = "std")] + pub fn new( + payload: Payload, + validator_index: ValidatorIndex, + signature: ValidatorSignature, + context: &SigningContext, + key: &ValidatorId, + ) -> Option { + let s = UncheckedSigned { + payload, + validator_index, + signature, + real_payload: std::marker::PhantomData, + }; + + s.check_signature(context, key).ok()?; + + Some(Self(s)) + } + + /// Create a new `Signed` by signing data. + #[cfg(feature = "std")] + pub fn sign( + keystore: &KeystorePtr, + payload: Payload, + context: &SigningContext, + validator_index: ValidatorIndex, + key: &ValidatorId, + ) -> Result, KeystoreError> { + let r = UncheckedSigned::sign(keystore, payload, context, validator_index, key)?; + Ok(r.map(Self)) + } + + /// Try to convert from `UncheckedSigned` by checking the signature. + pub fn try_from_unchecked( + unchecked: UncheckedSigned, + context: &SigningContext, + key: &ValidatorId, + ) -> Result> { + if unchecked.check_signature(context, key).is_ok() { + Ok(Self(unchecked)) + } else { + Err(unchecked) + } + } + + /// Get a reference to data as unchecked. + pub fn as_unchecked(&self) -> &UncheckedSigned { + &self.0 + } + + /// Immutably access the payload. + #[inline] + pub fn payload(&self) -> &Payload { + &self.0.payload + } + + /// Immutably access the validator index. + #[inline] + pub fn validator_index(&self) -> ValidatorIndex { + self.0.validator_index + } + + /// Immutably access the signature. + #[inline] + pub fn signature(&self) -> &ValidatorSignature { + &self.0.signature + } + + /// Discard signing data, get the payload + #[inline] + pub fn into_payload(self) -> Payload { + self.0.payload + } + + /// Convert `Payload` into `RealPayload`. + pub fn convert_payload(&self) -> Signed + where + for<'a> &'a Payload: Into, + { + Signed(self.0.unchecked_convert_payload()) + } + + /// Convert `Payload` into some claimed `SuperPayload` if the encoding matches. + /// + /// Succeeds if and only if the super-payload provided actually encodes as + /// the expected payload. + pub fn convert_to_superpayload( + self, + claimed: SuperPayload, + ) -> Result, (Self, SuperPayload)> + where + SuperPayload: EncodeAs, + { + if claimed.encode_as() == self.0.payload.encode_as() { + Ok(Signed(UncheckedSigned { + payload: claimed, + validator_index: self.0.validator_index, + signature: self.0.signature, + real_payload: sp_std::marker::PhantomData, + })) + } else { + Err((self, claimed)) + } + } + + /// Convert `Payload` into some converted `SuperPayload` if the encoding matches. + /// + /// This invokes the closure on the current payload, which is irreversible. + /// + /// Succeeds if and only if the super-payload provided actually encodes as + /// the expected payload. + pub fn convert_to_superpayload_with( + self, + convert: F, + ) -> Result, SuperPayload> + where + F: FnOnce(Payload) -> SuperPayload, + SuperPayload: EncodeAs, + { + let expected_encode_as = self.0.payload.encode_as(); + let converted = convert(self.0.payload); + if converted.encode_as() == expected_encode_as { + Ok(Signed(UncheckedSigned { + payload: converted, + validator_index: self.0.validator_index, + signature: self.0.signature, + real_payload: sp_std::marker::PhantomData, + })) + } else { + Err(converted) + } + } +} + +// We can't bound this on `Payload: Into` because that conversion consumes +// the payload, and we don't want that. We can't bound it on `Payload: AsRef` +// because there's no blanket impl of `AsRef for T`. In the end, we just invent our +// own trait which does what we need: EncodeAs. +impl, RealPayload: Encode> UncheckedSigned { + /// Used to create a `UncheckedSigned` from already existing parts. + /// + /// Signature is not checked here, hence `UncheckedSigned`. + #[cfg(feature = "std")] + pub fn new( + payload: Payload, + validator_index: ValidatorIndex, + signature: ValidatorSignature, + ) -> Self { + Self { payload, validator_index, signature, real_payload: std::marker::PhantomData } + } + + /// Check signature and convert to `Signed` if successful. + pub fn try_into_checked( + self, + context: &SigningContext, + key: &ValidatorId, + ) -> Result, Self> { + Signed::try_from_unchecked(self, context, key) + } + + /// Immutably access the payload. + #[inline] + pub fn unchecked_payload(&self) -> &Payload { + &self.payload + } + + /// Immutably access the validator index. + #[inline] + pub fn unchecked_validator_index(&self) -> ValidatorIndex { + self.validator_index + } + + /// Immutably access the signature. + #[inline] + pub fn unchecked_signature(&self) -> &ValidatorSignature { + &self.signature + } + + /// Discard signing data, get the payload + #[inline] + pub fn unchecked_into_payload(self) -> Payload { + self.payload + } + + /// Convert `Payload` into `RealPayload`. + pub fn unchecked_convert_payload(&self) -> UncheckedSigned + where + for<'a> &'a Payload: Into, + { + UncheckedSigned { + signature: self.signature.clone(), + validator_index: self.validator_index, + payload: (&self.payload).into(), + real_payload: sp_std::marker::PhantomData, + } + } + + fn payload_data(payload: &Payload, context: &SigningContext) -> Vec { + // equivalent to (`real_payload`, context).encode() + let mut out = payload.encode_as(); + out.extend(context.encode()); + out + } + + /// Sign this payload with the given context and key, storing the validator index. + #[cfg(feature = "std")] + fn sign( + keystore: &KeystorePtr, + payload: Payload, + context: &SigningContext, + validator_index: ValidatorIndex, + key: &ValidatorId, + ) -> Result, KeystoreError> { + let data = Self::payload_data(&payload, context); + let signature = + keystore.sr25519_sign(ValidatorId::ID, key.as_ref(), &data)?.map(|sig| Self { + payload, + validator_index, + signature: sig.into(), + real_payload: std::marker::PhantomData, + }); + Ok(signature) + } + + /// Validate the payload given the context and public key + /// without creating a `Signed` type. + pub fn check_signature( + &self, + context: &SigningContext, + key: &ValidatorId, + ) -> Result<(), ()> { + let data = Self::payload_data(&self.payload, context); + if self.signature.verify(data.as_slice(), key) { + Ok(()) + } else { + Err(()) + } + } + + /// Sign this payload with the given context and pair. + #[cfg(any(feature = "runtime-benchmarks", feature = "std"))] + pub fn benchmark_sign( + public: &super::ValidatorId, + payload: Payload, + context: &SigningContext, + validator_index: ValidatorIndex, + ) -> Self { + use application_crypto::RuntimeAppPublic; + let data = Self::payload_data(&payload, context); + let signature = public.sign(&data).unwrap(); + + Self { payload, validator_index, signature, real_payload: sp_std::marker::PhantomData } + } + + /// Immutably access the signature. + #[cfg(any(feature = "runtime-benchmarks", feature = "std"))] + pub fn benchmark_signature(&self) -> ValidatorSignature { + self.signature.clone() + } + + /// Set the signature. Only should be used for creating testing mocks. + #[cfg(feature = "std")] + pub fn set_signature(&mut self, signature: ValidatorSignature) { + self.signature = signature + } +} + +impl From> + for UncheckedSigned +{ + fn from(signed: Signed) -> Self { + signed.0 + } +} + +/// This helper trait ensures that we can encode `Statement` as `CompactStatement`, +/// and anything as itself. +/// +/// This resembles `parity_scale_codec::EncodeLike`, but it's distinct: +/// `EncodeLike` is a marker trait which asserts at the typesystem level that +/// one type's encoding is a valid encoding for another type. It doesn't +/// perform any type conversion when encoding. +/// +/// This trait, on the other hand, provides a method which can be used to +/// simultaneously convert and encode one type as another. +pub trait EncodeAs { + /// Convert Self into T, then encode T. + /// + /// This is useful when T is a subset of Self, reducing encoding costs; + /// its signature also means that we do not need to clone Self in order + /// to retain ownership, as we would if we were to do + /// `self.clone().into().encode()`. + fn encode_as(&self) -> Vec; +} + +impl EncodeAs for T { + fn encode_as(&self) -> Vec { + self.encode() + } +} diff --git a/polkadot/primitives/src/v5/slashing.rs b/polkadot/primitives/src/v5/slashing.rs new file mode 100644 index 0000000000000000000000000000000000000000..34424a00d23c8b5bd965beb970b6e98cf49056ee --- /dev/null +++ b/polkadot/primitives/src/v5/slashing.rs @@ -0,0 +1,104 @@ +// Copyright 2017-2023 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Primitives types used for dispute slashing. + +use crate::{CandidateHash, SessionIndex, ValidatorId, ValidatorIndex}; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; + +/// The kind of the dispute offence. +#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, TypeInfo, Debug)] +pub enum SlashingOffenceKind { + /// A severe offence when a validator backed an invalid block. + #[codec(index = 0)] + ForInvalid, + /// A minor offence when a validator disputed a valid block. + #[codec(index = 1)] + AgainstValid, +} + +/// Timeslots should uniquely identify offences and are used for the offence +/// deduplication. +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode, TypeInfo, Debug)] +pub struct DisputesTimeSlot { + // The order of the fields matters for `derive(Ord)`. + /// Session index when the candidate was backed/included. + pub session_index: SessionIndex, + /// Candidate hash of the disputed candidate. + pub candidate_hash: CandidateHash, +} + +impl DisputesTimeSlot { + /// Create a new instance of `Self`. + pub fn new(session_index: SessionIndex, candidate_hash: CandidateHash) -> Self { + Self { session_index, candidate_hash } + } +} + +/// We store most of the information about a lost dispute on chain. This struct +/// is required to identify and verify it. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug)] +pub struct DisputeProof { + /// Time slot when the dispute occured. + pub time_slot: DisputesTimeSlot, + /// The dispute outcome. + pub kind: SlashingOffenceKind, + /// The index of the validator who lost a dispute. + pub validator_index: ValidatorIndex, + /// The parachain session key of the validator. + pub validator_id: ValidatorId, +} + +/// Slashes that are waiting to be applied once we have validator key +/// identification. +#[derive(Encode, Decode, TypeInfo, Debug, Clone)] +pub struct PendingSlashes { + /// Indices and keys of the validators who lost a dispute and are pending + /// slashes. + pub keys: BTreeMap, + /// The dispute outcome. + pub kind: SlashingOffenceKind, +} + +// TODO: can we reuse this type between BABE, GRANDPA and disputes? +/// An opaque type used to represent the key ownership proof at the runtime API +/// boundary. The inner value is an encoded representation of the actual key +/// ownership proof which will be parameterized when defining the runtime. At +/// the runtime API boundary this type is unknown and as such we keep this +/// opaque representation, implementors of the runtime API will have to make +/// sure that all usages of `OpaqueKeyOwnershipProof` refer to the same type. +#[derive(Decode, Encode, PartialEq, Eq, Debug, Clone, TypeInfo)] +pub struct OpaqueKeyOwnershipProof(Vec); +impl OpaqueKeyOwnershipProof { + /// Create a new `OpaqueKeyOwnershipProof` using the given encoded + /// representation. + pub fn new(inner: Vec) -> OpaqueKeyOwnershipProof { + OpaqueKeyOwnershipProof(inner) + } + + /// Try to decode this `OpaqueKeyOwnershipProof` into the given concrete key + /// ownership proof type. + pub fn decode(self) -> Option { + Decode::decode(&mut &self.0[..]).ok() + } + + /// Length of the encoded proof. + pub fn len(&self) -> usize { + self.0.len() + } +} diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..ea341ee5b4fc973b587ecd0c23a415b5807c6350 --- /dev/null +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -0,0 +1,137 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Staging Primitives. + +// Put any primitives used by staging APIs functions here +pub use crate::v5::*; +use sp_std::prelude::*; + +use parity_scale_codec::{Decode, Encode}; +use primitives::RuntimeDebug; +use scale_info::TypeInfo; + +/// Useful type alias for Para IDs. +pub type ParaId = Id; + +/// Candidate's acceptance limitations for asynchronous backing per relay parent. +#[derive( + RuntimeDebug, + Copy, + Clone, + PartialEq, + Encode, + Decode, + TypeInfo, + serde::Serialize, + serde::Deserialize, +)] + +pub struct AsyncBackingParams { + /// The maximum number of para blocks between the para head in a relay parent + /// and a new candidate. Restricts nodes from building arbitrary long chains + /// and spamming other validators. + /// + /// When async backing is disabled, the only valid value is 0. + pub max_candidate_depth: u32, + /// How many ancestors of a relay parent are allowed to build candidates on top + /// of. + /// + /// When async backing is disabled, the only valid value is 0. + pub allowed_ancestry_len: u32, +} + +/// Constraints on inbound HRMP channels. +#[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] +pub struct InboundHrmpLimitations { + /// An exhaustive set of all valid watermarks, sorted ascending. + /// + /// It's only expected to contain block numbers at which messages were + /// previously sent to a para, excluding most recent head. + pub valid_watermarks: Vec, +} + +/// Constraints on outbound HRMP channels. +#[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] +pub struct OutboundHrmpChannelLimitations { + /// The maximum bytes that can be written to the channel. + pub bytes_remaining: u32, + /// The maximum messages that can be written to the channel. + pub messages_remaining: u32, +} + +/// Constraints on the actions that can be taken by a new parachain +/// block. These limitations are implicitly associated with some particular +/// parachain, which should be apparent from usage. +#[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] +pub struct Constraints { + /// The minimum relay-parent number accepted under these constraints. + pub min_relay_parent_number: N, + /// The maximum Proof-of-Validity size allowed, in bytes. + pub max_pov_size: u32, + /// The maximum new validation code size allowed, in bytes. + pub max_code_size: u32, + /// The amount of UMP messages remaining. + pub ump_remaining: u32, + /// The amount of UMP bytes remaining. + pub ump_remaining_bytes: u32, + /// The maximum number of UMP messages allowed per candidate. + pub max_ump_num_per_candidate: u32, + /// Remaining DMP queue. Only includes sent-at block numbers. + pub dmp_remaining_messages: Vec, + /// The limitations of all registered inbound HRMP channels. + pub hrmp_inbound: InboundHrmpLimitations, + /// The limitations of all registered outbound HRMP channels. + pub hrmp_channels_out: Vec<(ParaId, OutboundHrmpChannelLimitations)>, + /// The maximum number of HRMP messages allowed per candidate. + pub max_hrmp_num_per_candidate: u32, + /// The required parent head-data of the parachain. + pub required_parent: HeadData, + /// The expected validation-code-hash of this parachain. + pub validation_code_hash: ValidationCodeHash, + /// The code upgrade restriction signal as-of this parachain. + pub upgrade_restriction: Option, + /// The future validation code hash, if any, and at what relay-parent + /// number the upgrade would be minimally applied. + pub future_validation_code: Option<(N, ValidationCodeHash)>, +} + +/// A candidate pending availability. +#[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] +pub struct CandidatePendingAvailability { + /// The hash of the candidate. + pub candidate_hash: CandidateHash, + /// The candidate's descriptor. + pub descriptor: CandidateDescriptor, + /// The commitments of the candidate. + pub commitments: CandidateCommitments, + /// The candidate's relay parent's number. + pub relay_parent_number: N, + /// The maximum Proof-of-Validity size allowed, in bytes. + pub max_pov_size: u32, +} + +/// The per-parachain state of the backing system, including +/// state-machine constraints and candidates pending availability. +#[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] +pub struct BackingState { + /// The state-machine constraints of the parachain. + pub constraints: Constraints, + /// The candidates pending availability. These should be ordered, i.e. they should form + /// a sub-chain, where the first candidate builds on top of the required parent of the + /// constraints and each subsequent builds on top of the previous head-data. + pub pending_availability: Vec>, +} diff --git a/polkadot/primitives/test-helpers/Cargo.toml b/polkadot/primitives/test-helpers/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..b43bac1e8550158bd6adec38d2b020694e24147d --- /dev/null +++ b/polkadot/primitives/test-helpers/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "polkadot-primitives-test-helpers" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-application-crypto = { package = "sp-application-crypto", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["std"] } +polkadot-primitives = { path = "../" } +rand = "0.8.5" diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..8ee5f180d34290b8077f8b68eed73dadc81062dc --- /dev/null +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -0,0 +1,304 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![forbid(unused_crate_dependencies)] +#![forbid(unused_extern_crates)] + +//! A set of primitive constructors, to aid in crafting meaningful testcase while reducing +//! repetition. +//! +//! Note that `dummy_` prefixed values are meant to be fillers, that should not matter, and will +//! contain randomness based data. +use polkadot_primitives::{ + CandidateCommitments, CandidateDescriptor, CandidateReceipt, CollatorId, CollatorSignature, + CommittedCandidateReceipt, Hash, HeadData, Id as ParaId, PersistedValidationData, + ValidationCode, ValidationCodeHash, ValidatorId, +}; +pub use rand; +use sp_application_crypto::sr25519; +use sp_keyring::Sr25519Keyring; +use sp_runtime::generic::Digest; + +const MAX_POV_SIZE: u32 = 1_000_000; + +/// Creates a candidate receipt with filler data. +pub fn dummy_candidate_receipt>(relay_parent: H) -> CandidateReceipt { + CandidateReceipt:: { + commitments_hash: dummy_candidate_commitments(dummy_head_data()).hash(), + descriptor: dummy_candidate_descriptor(relay_parent), + } +} + +/// Creates a committed candidate receipt with filler data. +pub fn dummy_committed_candidate_receipt>( + relay_parent: H, +) -> CommittedCandidateReceipt { + CommittedCandidateReceipt:: { + descriptor: dummy_candidate_descriptor::(relay_parent), + commitments: dummy_candidate_commitments(dummy_head_data()), + } +} + +/// Create a candidate receipt with a bogus signature and filler data. Optionally set the commitment +/// hash with the `commitments` arg. +pub fn dummy_candidate_receipt_bad_sig( + relay_parent: Hash, + commitments: impl Into>, +) -> CandidateReceipt { + let commitments_hash = if let Some(commitments) = commitments.into() { + commitments + } else { + dummy_candidate_commitments(dummy_head_data()).hash() + }; + CandidateReceipt:: { + commitments_hash, + descriptor: dummy_candidate_descriptor_bad_sig(relay_parent), + } +} + +/// Create candidate commitments with filler data. +pub fn dummy_candidate_commitments(head_data: impl Into>) -> CandidateCommitments { + CandidateCommitments { + head_data: head_data.into().unwrap_or(dummy_head_data()), + upward_messages: vec![].try_into().expect("empty vec fits within bounds"), + new_validation_code: None, + horizontal_messages: vec![].try_into().expect("empty vec fits within bounds"), + processed_downward_messages: 0, + hrmp_watermark: 0_u32, + } +} + +/// Create meaningless dummy hash. +pub fn dummy_hash() -> Hash { + Hash::zero() +} + +/// Create meaningless dummy digest. +pub fn dummy_digest() -> Digest { + Digest::default() +} + +/// Create a candidate descriptor with a bogus signature and filler data. +pub fn dummy_candidate_descriptor_bad_sig(relay_parent: Hash) -> CandidateDescriptor { + let zeros = Hash::zero(); + CandidateDescriptor:: { + para_id: 0.into(), + relay_parent, + collator: dummy_collator(), + persisted_validation_data_hash: zeros, + pov_hash: zeros, + erasure_root: zeros, + signature: dummy_collator_signature(), + para_head: zeros, + validation_code_hash: dummy_validation_code().hash(), + } +} + +/// Create a candidate descriptor with filler data. +pub fn dummy_candidate_descriptor>(relay_parent: H) -> CandidateDescriptor { + let collator = sp_keyring::Sr25519Keyring::Ferdie; + let invalid = Hash::zero(); + let descriptor = make_valid_candidate_descriptor( + 1.into(), + relay_parent, + invalid, + invalid, + invalid, + invalid, + invalid, + collator, + ); + descriptor +} + +/// Create meaningless validation code. +pub fn dummy_validation_code() -> ValidationCode { + ValidationCode(vec![1, 2, 3]) +} + +/// Create meaningless head data. +pub fn dummy_head_data() -> HeadData { + HeadData(vec![]) +} + +/// Create a meaningless collator id. +pub fn dummy_collator() -> CollatorId { + CollatorId::from(sr25519::Public::from_raw([0; 32])) +} + +/// Create a meaningless validator id. +pub fn dummy_validator() -> ValidatorId { + ValidatorId::from(sr25519::Public::from_raw([0; 32])) +} + +/// Create a meaningless collator signature. +pub fn dummy_collator_signature() -> CollatorSignature { + CollatorSignature::from(sr25519::Signature([0u8; 64])) +} + +/// Create a meaningless persisted validation data. +pub fn dummy_pvd(parent_head: HeadData, relay_parent_number: u32) -> PersistedValidationData { + PersistedValidationData { + parent_head, + relay_parent_number, + max_pov_size: MAX_POV_SIZE, + relay_parent_storage_root: dummy_hash(), + } +} + +/// Create a meaningless candidate, returning its receipt and PVD. +pub fn make_candidate( + relay_parent_hash: Hash, + relay_parent_number: u32, + para_id: ParaId, + parent_head: HeadData, + head_data: HeadData, + validation_code_hash: ValidationCodeHash, +) -> (CommittedCandidateReceipt, PersistedValidationData) { + let pvd = dummy_pvd(parent_head, relay_parent_number); + let commitments = CandidateCommitments { + head_data, + horizontal_messages: Default::default(), + upward_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: relay_parent_number, + }; + + let mut candidate = + dummy_candidate_receipt_bad_sig(relay_parent_hash, Some(Default::default())); + candidate.commitments_hash = commitments.hash(); + candidate.descriptor.para_id = para_id; + candidate.descriptor.persisted_validation_data_hash = pvd.hash(); + candidate.descriptor.validation_code_hash = validation_code_hash; + let candidate = CommittedCandidateReceipt { descriptor: candidate.descriptor, commitments }; + + (candidate, pvd) +} + +/// Create a new candidate descriptor, and apply a valid signature +/// using the provided `collator` key. +pub fn make_valid_candidate_descriptor>( + para_id: ParaId, + relay_parent: H, + persisted_validation_data_hash: Hash, + pov_hash: Hash, + validation_code_hash: impl Into, + para_head: Hash, + erasure_root: Hash, + collator: Sr25519Keyring, +) -> CandidateDescriptor { + let validation_code_hash = validation_code_hash.into(); + let payload = polkadot_primitives::collator_signature_payload::( + &relay_parent, + ¶_id, + &persisted_validation_data_hash, + &pov_hash, + &validation_code_hash, + ); + + let signature = collator.sign(&payload).into(); + let descriptor = CandidateDescriptor { + para_id, + relay_parent, + collator: collator.public().into(), + persisted_validation_data_hash, + pov_hash, + erasure_root, + signature, + para_head, + validation_code_hash, + }; + + assert!(descriptor.check_collator_signature().is_ok()); + descriptor +} + +/// After manually modifying the candidate descriptor, resign with a defined collator key. +pub fn resign_candidate_descriptor_with_collator>( + descriptor: &mut CandidateDescriptor, + collator: Sr25519Keyring, +) { + descriptor.collator = collator.public().into(); + let payload = polkadot_primitives::collator_signature_payload::( + &descriptor.relay_parent, + &descriptor.para_id, + &descriptor.persisted_validation_data_hash, + &descriptor.pov_hash, + &descriptor.validation_code_hash, + ); + let signature = collator.sign(&payload).into(); + descriptor.signature = signature; +} + +/// Builder for `CandidateReceipt`. +pub struct TestCandidateBuilder { + pub para_id: ParaId, + pub pov_hash: Hash, + pub relay_parent: Hash, + pub commitments_hash: Hash, +} + +impl std::default::Default for TestCandidateBuilder { + fn default() -> Self { + let zeros = Hash::zero(); + Self { para_id: 0.into(), pov_hash: zeros, relay_parent: zeros, commitments_hash: zeros } + } +} + +impl TestCandidateBuilder { + /// Build a `CandidateReceipt`. + pub fn build(self) -> CandidateReceipt { + let mut descriptor = dummy_candidate_descriptor(self.relay_parent); + descriptor.para_id = self.para_id; + descriptor.pov_hash = self.pov_hash; + CandidateReceipt { descriptor, commitments_hash: self.commitments_hash } + } +} + +/// A special `Rng` that always returns zero for testing something that implied +/// to be random but should not be random in the tests +pub struct AlwaysZeroRng; + +impl Default for AlwaysZeroRng { + fn default() -> Self { + Self {} + } +} +impl rand::RngCore for AlwaysZeroRng { + fn next_u32(&mut self) -> u32 { + 0_u32 + } + + fn next_u64(&mut self) -> u64 { + 0_u64 + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + for element in dest.iter_mut() { + *element = 0_u8; + } + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> { + self.fill_bytes(dest); + Ok(()) + } +} + +pub fn dummy_signature() -> polkadot_primitives::ValidatorSignature { + sp_core::crypto::UncheckedFrom::unchecked_from([1u8; 64]) +} diff --git a/polkadot/roadmap/implementers-guide/.gitignore b/polkadot/roadmap/implementers-guide/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ac55c8234c362d417e4ffb085c44d30d3b3bd928 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/.gitignore @@ -0,0 +1,2 @@ +book/ +*.generated.svg diff --git a/polkadot/roadmap/implementers-guide/README.md b/polkadot/roadmap/implementers-guide/README.md new file mode 100644 index 0000000000000000000000000000000000000000..996041f176bb2cbce5446ac2e800fe3e155fb884 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/README.md @@ -0,0 +1,35 @@ +# The Polkadot Parachain Host Implementers' Guide + +The implementers' guide is compiled from several source files with [`mdBook`](https://github.com/rust-lang/mdBook). + +## Hosted build + +This is available [here](https://paritytech.github.io/polkadot/book/). + +## Local build + +To view it locally from the repo root: + +Ensure graphviz is installed: + +```sh +brew install graphviz # for macOS +sudo apt-get install graphviz # for Ubuntu/Debian +``` + +Then install and build the book: + +```sh +cargo install mdbook mdbook-linkcheck mdbook-graphviz mdbook-mermaid mdbook-last-changed +mdbook serve roadmap/implementers-guide +``` + +and in a second terminal window run: + +```sh +open http://localhost:3000 +``` + +## Specification + +See also the Polkadot specification [hosted](https://spec.polkadot.network/), and its [source](https://github.com/w3f/polkadot-spec). diff --git a/polkadot/roadmap/implementers-guide/book.toml b/polkadot/roadmap/implementers-guide/book.toml new file mode 100644 index 0000000000000000000000000000000000000000..0ced0e26f9a081ba034a9ed489132f3985fb240e --- /dev/null +++ b/polkadot/roadmap/implementers-guide/book.toml @@ -0,0 +1,22 @@ +[book] +authors = ["Rob Habermeier", "Peter Goodspeed-Niklaus"] +language = "en" +multilingual = false +src = "src" +title = "The Polkadot Parachain Host Implementers' Guide" + +[preprocessor.graphviz] +command = "mdbook-graphviz" +[preprocessor.mermaid] +command = "mdbook-mermaid" +[preprocessor.last-changed] +command = "mdbook-last-changed" +renderer = ["html"] + +[output.html] +additional-css = ["last-changed.css"] +additional-js = ["mermaid.min.js", "mermaid-init.js"] +# Repository URL used in the last-changed link. +git-repository-url = "https://github.com/paritytech/polkadot" + +[output.linkcheck] diff --git a/polkadot/roadmap/implementers-guide/last-changed.css b/polkadot/roadmap/implementers-guide/last-changed.css new file mode 100644 index 0000000000000000000000000000000000000000..744dc6efc7ec55819542b7e39700c78ad68a85f6 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/last-changed.css @@ -0,0 +1,7 @@ +footer { + font-size: 0.8em; + text-align: center; + margin-top: 50px; + border-top: 1px solid black; + padding: 5px 0; +} diff --git a/polkadot/roadmap/implementers-guide/mermaid-init.js b/polkadot/roadmap/implementers-guide/mermaid-init.js new file mode 100644 index 0000000000000000000000000000000000000000..313a6e8bc89d5bc210127f6713b54c4fd9cbe9ad --- /dev/null +++ b/polkadot/roadmap/implementers-guide/mermaid-init.js @@ -0,0 +1 @@ +mermaid.initialize({startOnLoad:true}); diff --git a/polkadot/roadmap/implementers-guide/mermaid.min.js b/polkadot/roadmap/implementers-guide/mermaid.min.js new file mode 100644 index 0000000000000000000000000000000000000000..8d71a81caf4197af52a9e8608980dac532ad45e4 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/mermaid.min.js @@ -0,0 +1,32 @@ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.mermaid=e():t.mermaid=e()}("undefined"!=typeof self?self:this,(function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=383)}([function(t,e,n){"use strict";n.r(e);var r=function(t,e){return te?1:t>=e?0:NaN},i=function(t){var e;return 1===t.length&&(e=t,t=function(t,n){return r(e(t),n)}),{left:function(e,n,r,i){for(null==r&&(r=0),null==i&&(i=e.length);r>>1;t(e[a],n)<0?r=a+1:i=a}return r},right:function(e,n,r,i){for(null==r&&(r=0),null==i&&(i=e.length);r>>1;t(e[a],n)>0?i=a:r=a+1}return r}}};var a=i(r),o=a.right,s=a.left,c=o,u=function(t,e){null==e&&(e=l);for(var n=0,r=t.length-1,i=t[0],a=new Array(r<0?0:r);nt?1:e>=t?0:NaN},d=function(t){return null===t?NaN:+t},p=function(t,e){var n,r,i=t.length,a=0,o=-1,s=0,c=0;if(null==e)for(;++o1)return c/(a-1)},g=function(t,e){var n=p(t,e);return n?Math.sqrt(n):n},y=function(t,e){var n,r,i,a=t.length,o=-1;if(null==e){for(;++o=n)for(r=i=n;++on&&(r=n),i=n)for(r=i=n;++on&&(r=n),i0)return[t];if((r=e0)for(t=Math.ceil(t/o),e=Math.floor(e/o),a=new Array(i=Math.ceil(e-t+1));++s=0?(a>=w?10:a>=E?5:a>=T?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(a>=w?10:a>=E?5:a>=T?2:1)}function A(t,e,n){var r=Math.abs(e-t)/Math.max(0,n),i=Math.pow(10,Math.floor(Math.log(r)/Math.LN10)),a=r/i;return a>=w?i*=10:a>=E?i*=5:a>=T&&(i*=2),eh;)f.pop(),--d;var p,g=new Array(d+1);for(i=0;i<=d;++i)(p=g[i]=[]).x0=i>0?f[i-1]:l,p.x1=i=1)return+n(t[r-1],r-1,t);var r,i=(r-1)*e,a=Math.floor(i),o=+n(t[a],a,t);return o+(+n(t[a+1],a+1,t)-o)*(i-a)}},N=function(t,e,n){return t=b.call(t,d).sort(r),Math.ceil((n-e)/(2*(D(t,.75)-D(t,.25))*Math.pow(t.length,-1/3)))},B=function(t,e,n){return Math.ceil((n-e)/(3.5*g(t)*Math.pow(t.length,-1/3)))},L=function(t,e){var n,r,i=t.length,a=-1;if(null==e){for(;++a=n)for(r=n;++ar&&(r=n)}else for(;++a=n)for(r=n;++ar&&(r=n);return r},F=function(t,e){var n,r=t.length,i=r,a=-1,o=0;if(null==e)for(;++a=0;)for(e=(r=t[i]).length;--e>=0;)n[--o]=r[e];return n},j=function(t,e){var n,r,i=t.length,a=-1;if(null==e){for(;++a=n)for(r=n;++an&&(r=n)}else for(;++a=n)for(r=n;++an&&(r=n);return r},R=function(t,e){for(var n=e.length,r=new Array(n);n--;)r[n]=t[e[n]];return r},Y=function(t,e){if(n=t.length){var n,i,a=0,o=0,s=t[o];for(null==e&&(e=r);++a=0&&(n=t.slice(r+1),t=t.slice(0,r)),t&&!e.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:n}}))}function ct(t,e){for(var n,r=0,i=t.length;r0)for(var n,r,i=new Array(n),a=0;ae?1:t>=e?0:NaN}var _t="http://www.w3.org/1999/xhtml",kt={svg:"http://www.w3.org/2000/svg",xhtml:_t,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},wt=function(t){var e=t+="",n=e.indexOf(":");return n>=0&&"xmlns"!==(e=t.slice(0,n))&&(t=t.slice(n+1)),kt.hasOwnProperty(e)?{space:kt[e],local:t}:t};function Et(t){return function(){this.removeAttribute(t)}}function Tt(t){return function(){this.removeAttributeNS(t.space,t.local)}}function Ct(t,e){return function(){this.setAttribute(t,e)}}function St(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function At(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttribute(t):this.setAttribute(t,n)}}function Mt(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,n)}}var Ot=function(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView};function Dt(t){return function(){this.style.removeProperty(t)}}function Nt(t,e,n){return function(){this.style.setProperty(t,e,n)}}function Bt(t,e,n){return function(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,n)}}function Lt(t,e){return t.style.getPropertyValue(e)||Ot(t).getComputedStyle(t,null).getPropertyValue(e)}function Ft(t){return function(){delete this[t]}}function Pt(t,e){return function(){this[t]=e}}function It(t,e){return function(){var n=e.apply(this,arguments);null==n?delete this[t]:this[t]=n}}function jt(t){return t.trim().split(/^|\s+/)}function Rt(t){return t.classList||new Yt(t)}function Yt(t){this._node=t,this._names=jt(t.getAttribute("class")||"")}function zt(t,e){for(var n=Rt(t),r=-1,i=e.length;++r=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};function Ht(){this.textContent=""}function Gt(t){return function(){this.textContent=t}}function qt(t){return function(){var e=t.apply(this,arguments);this.textContent=null==e?"":e}}function Xt(){this.innerHTML=""}function Zt(t){return function(){this.innerHTML=t}}function Jt(t){return function(){var e=t.apply(this,arguments);this.innerHTML=null==e?"":e}}function Qt(){this.nextSibling&&this.parentNode.appendChild(this)}function Kt(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function te(t){return function(){var e=this.ownerDocument,n=this.namespaceURI;return n===_t&&e.documentElement.namespaceURI===_t?e.createElement(t):e.createElementNS(n,t)}}function ee(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}var ne=function(t){var e=wt(t);return(e.local?ee:te)(e)};function re(){return null}function ie(){var t=this.parentNode;t&&t.removeChild(this)}function ae(){var t=this.cloneNode(!1),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function oe(){var t=this.cloneNode(!0),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}var se={},ce=null;"undefined"!=typeof document&&("onmouseenter"in document.documentElement||(se={mouseenter:"mouseover",mouseleave:"mouseout"}));function ue(t,e,n){return t=le(t,e,n),function(e){var n=e.relatedTarget;n&&(n===this||8&n.compareDocumentPosition(this))||t.call(this,e)}}function le(t,e,n){return function(r){var i=ce;ce=r;try{t.call(this,this.__data__,e,n)}finally{ce=i}}}function he(t){return t.trim().split(/^|\s+/).map((function(t){var e="",n=t.indexOf(".");return n>=0&&(e=t.slice(n+1),t=t.slice(0,n)),{type:t,name:e}}))}function fe(t){return function(){var e=this.__on;if(e){for(var n,r=0,i=-1,a=e.length;r=_&&(_=x+1);!(b=v[_])&&++_=0;)(r=i[a])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(t){function e(e,n){return e&&n?t(e.__data__,n.__data__):!e-!n}t||(t=xt);for(var n=this._groups,r=n.length,i=new Array(r),a=0;a1?this.each((null==e?Dt:"function"==typeof e?Bt:Nt)(t,e,null==n?"":n)):Lt(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?Ft:"function"==typeof e?It:Pt)(t,e)):this.node()[t]},classed:function(t,e){var n=jt(t+"");if(arguments.length<2){for(var r=Rt(this.node()),i=-1,a=n.length;++i>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===n?new qe(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===n?new qe(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=Le.exec(t))?new qe(e[1],e[2],e[3],1):(e=Fe.exec(t))?new qe(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=Pe.exec(t))?Ve(e[1],e[2],e[3],e[4]):(e=Ie.exec(t))?Ve(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=je.exec(t))?Qe(e[1],e[2]/100,e[3]/100,1):(e=Re.exec(t))?Qe(e[1],e[2]/100,e[3]/100,e[4]):Ye.hasOwnProperty(t)?We(Ye[t]):"transparent"===t?new qe(NaN,NaN,NaN,0):null}function We(t){return new qe(t>>16&255,t>>8&255,255&t,1)}function Ve(t,e,n,r){return r<=0&&(t=e=n=NaN),new qe(t,e,n,r)}function He(t){return t instanceof Me||(t=$e(t)),t?new qe((t=t.rgb()).r,t.g,t.b,t.opacity):new qe}function Ge(t,e,n,r){return 1===arguments.length?He(t):new qe(t,e,n,null==r?1:r)}function qe(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}function Xe(){return"#"+Je(this.r)+Je(this.g)+Je(this.b)}function Ze(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}function Je(t){return((t=Math.max(0,Math.min(255,Math.round(t)||0)))<16?"0":"")+t.toString(16)}function Qe(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new en(t,e,n,r)}function Ke(t){if(t instanceof en)return new en(t.h,t.s,t.l,t.opacity);if(t instanceof Me||(t=$e(t)),!t)return new en;if(t instanceof en)return t;var e=(t=t.rgb()).r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),a=Math.max(e,n,r),o=NaN,s=a-i,c=(a+i)/2;return s?(o=e===a?(n-r)/s+6*(n0&&c<1?0:o,new en(o,s,c,t.opacity)}function tn(t,e,n,r){return 1===arguments.length?Ke(t):new en(t,e,n,null==r?1:r)}function en(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}function nn(t,e,n){return 255*(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)}function rn(t,e,n,r,i){var a=t*t,o=a*t;return((1-3*t+3*a-o)*e+(4-6*a+3*o)*n+(1+3*t+3*a-3*o)*r+o*i)/6}Se(Me,$e,{copy:function(t){return Object.assign(new this.constructor,this,t)},displayable:function(){return this.rgb().displayable()},hex:ze,formatHex:ze,formatHsl:function(){return Ke(this).formatHsl()},formatRgb:Ue,toString:Ue}),Se(qe,Ge,Ae(Me,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new qe(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new qe(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Xe,formatHex:Xe,formatRgb:Ze,toString:Ze})),Se(en,tn,Ae(Me,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new en(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new en(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new qe(nn(t>=240?t-240:t+120,i,r),nn(t,i,r),nn(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"hsl(":"hsla(")+(this.h||0)+", "+100*(this.s||0)+"%, "+100*(this.l||0)+"%"+(1===t?")":", "+t+")")}}));var an=function(t){var e=t.length-1;return function(n){var r=n<=0?n=0:n>=1?(n=1,e-1):Math.floor(n*e),i=t[r],a=t[r+1],o=r>0?t[r-1]:2*i-a,s=r180||n<-180?n-360*Math.round(n/360):n):sn(isNaN(t)?e:t)}function ln(t){return 1==(t=+t)?hn:function(e,n){return n-e?function(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,function(r){return Math.pow(t+r*e,n)}}(e,n,t):sn(isNaN(e)?n:e)}}function hn(t,e){var n=e-t;return n?cn(t,n):sn(isNaN(t)?e:t)}var fn=function t(e){var n=ln(e);function r(t,e){var r=n((t=Ge(t)).r,(e=Ge(e)).r),i=n(t.g,e.g),a=n(t.b,e.b),o=hn(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=i(e),t.b=a(e),t.opacity=o(e),t+""}}return r.gamma=t,r}(1);function dn(t){return function(e){var n,r,i=e.length,a=new Array(i),o=new Array(i),s=new Array(i);for(n=0;na&&(i=e.slice(a,i),s[o]?s[o]+=i:s[++o]=i),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,c.push({i:o,x:_n(n,r)})),a=En.lastIndex;return a=0&&e._call.call(null,t),e=e._next;--Bn}function Hn(){In=(Pn=Rn.now())+jn,Bn=Ln=0;try{Vn()}finally{Bn=0,function(){var t,e,n=Tn,r=1/0;for(;n;)n._call?(r>n._time&&(r=n._time),t=n,n=n._next):(e=n._next,n._next=null,n=t?t._next=e:Tn=e);Cn=t,qn(r)}(),In=0}}function Gn(){var t=Rn.now(),e=t-Pn;e>1e3&&(jn-=e,Pn=t)}function qn(t){Bn||(Ln&&(Ln=clearTimeout(Ln)),t-In>24?(t<1/0&&(Ln=setTimeout(Hn,t-Rn.now()-jn)),Fn&&(Fn=clearInterval(Fn))):(Fn||(Pn=Rn.now(),Fn=setInterval(Gn,1e3)),Bn=1,Yn(Hn)))}$n.prototype=Wn.prototype={constructor:$n,restart:function(t,e,n){if("function"!=typeof t)throw new TypeError("callback is not a function");n=(null==n?zn():+n)+(null==e?0:+e),this._next||Cn===this||(Cn?Cn._next=this:Tn=this,Cn=this),this._call=t,this._time=n,qn()},stop:function(){this._call&&(this._call=null,this._time=1/0,qn())}};var Xn=function(t,e,n){var r=new $n;return e=null==e?0:+e,r.restart((function(n){r.stop(),t(n+e)}),e,n),r},Zn=lt("start","end","cancel","interrupt"),Jn=[],Qn=function(t,e,n,r,i,a){var o=t.__transition;if(o){if(n in o)return}else t.__transition={};!function(t,e,n){var r,i=t.__transition;function a(c){var u,l,h,f;if(1!==n.state)return s();for(u in i)if((f=i[u]).name===n.name){if(3===f.state)return Xn(a);4===f.state?(f.state=6,f.timer.stop(),f.on.call("interrupt",t,t.__data__,f.index,f.group),delete i[u]):+u0)throw new Error("too late; already scheduled");return n}function tr(t,e){var n=er(t,e);if(n.state>3)throw new Error("too late; already running");return n}function er(t,e){var n=t.__transition;if(!n||!(n=n[e]))throw new Error("transition not found");return n}var nr,rr,ir,ar,or=function(t,e){var n,r,i,a=t.__transition,o=!0;if(a){for(i in e=null==e?null:e+"",a)(n=a[i]).name===e?(r=n.state>2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",t,t.__data__,n.index,n.group),delete a[i]):o=!1;o&&delete t.__transition}},sr=180/Math.PI,cr={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1},ur=function(t,e,n,r,i,a){var o,s,c;return(o=Math.sqrt(t*t+e*e))&&(t/=o,e/=o),(c=t*n+e*r)&&(n-=t*c,r-=e*c),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,c/=s),t*r180?e+=360:e-t>180&&(t+=360),a.push({i:n.push(i(n)+"rotate(",null,r)-2,x:_n(t,e)})):e&&n.push(i(n)+"rotate("+e+r)}(a.rotate,o.rotate,s,c),function(t,e,n,a){t!==e?a.push({i:n.push(i(n)+"skewX(",null,r)-2,x:_n(t,e)}):e&&n.push(i(n)+"skewX("+e+r)}(a.skewX,o.skewX,s,c),function(t,e,n,r,a,o){if(t!==n||e!==r){var s=a.push(i(a)+"scale(",null,",",null,")");o.push({i:s-4,x:_n(t,n)},{i:s-2,x:_n(e,r)})}else 1===n&&1===r||a.push(i(a)+"scale("+n+","+r+")")}(a.scaleX,a.scaleY,o.scaleX,o.scaleY,s,c),a=o=null,function(t){for(var e,n=-1,r=c.length;++n=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?Kn:tr;return function(){var o=a(this,t),s=o.on;s!==r&&(i=(r=s).copy()).on(e,n),o.on=i}}var Br=_e.prototype.constructor;function Lr(t){return function(){this.style.removeProperty(t)}}function Fr(t,e,n){return function(r){this.style.setProperty(t,e.call(this,r),n)}}function Pr(t,e,n){var r,i;function a(){var a=e.apply(this,arguments);return a!==i&&(r=(i=a)&&Fr(t,a,n)),r}return a._value=e,a}function Ir(t){return function(e){this.textContent=t.call(this,e)}}function jr(t){var e,n;function r(){var r=t.apply(this,arguments);return r!==n&&(e=(n=r)&&Ir(r)),e}return r._value=t,r}var Rr=0;function Yr(t,e,n,r){this._groups=t,this._parents=e,this._name=n,this._id=r}function zr(t){return _e().transition(t)}function Ur(){return++Rr}var $r=_e.prototype;function Wr(t){return t*t*t}function Vr(t){return--t*t*t+1}function Hr(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}Yr.prototype=zr.prototype={constructor:Yr,select:function(t){var e=this._name,n=this._id;"function"!=typeof t&&(t=ft(t));for(var r=this._groups,i=r.length,a=new Array(i),o=0;o1&&n.name===e)return new Yr([[t]],Xr,e,+r);return null},Jr=function(t){return function(){return t}},Qr=function(t,e,n){this.target=t,this.type=e,this.selection=n};function Kr(){ce.stopImmediatePropagation()}var ti=function(){ce.preventDefault(),ce.stopImmediatePropagation()},ei={name:"drag"},ni={name:"space"},ri={name:"handle"},ii={name:"center"};function ai(t){return[+t[0],+t[1]]}function oi(t){return[ai(t[0]),ai(t[1])]}function si(t){return function(e){return Dn(e,ce.touches,t)}}var ci={name:"x",handles:["w","e"].map(yi),input:function(t,e){return null==t?null:[[+t[0],e[0][1]],[+t[1],e[1][1]]]},output:function(t){return t&&[t[0][0],t[1][0]]}},ui={name:"y",handles:["n","s"].map(yi),input:function(t,e){return null==t?null:[[e[0][0],+t[0]],[e[1][0],+t[1]]]},output:function(t){return t&&[t[0][1],t[1][1]]}},li={name:"xy",handles:["n","w","e","s","nw","ne","sw","se"].map(yi),input:function(t){return null==t?null:oi(t)},output:function(t){return t}},hi={overlay:"crosshair",selection:"move",n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},fi={e:"w",w:"e",nw:"ne",ne:"nw",se:"sw",sw:"se"},di={n:"s",s:"n",nw:"sw",ne:"se",se:"ne",sw:"nw"},pi={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},gi={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1};function yi(t){return{type:t}}function vi(){return!ce.ctrlKey&&!ce.button}function mi(){var t=this.ownerSVGElement||this;return t.hasAttribute("viewBox")?[[(t=t.viewBox.baseVal).x,t.y],[t.x+t.width,t.y+t.height]]:[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]}function bi(){return navigator.maxTouchPoints||"ontouchstart"in this}function xi(t){for(;!t.__brush;)if(!(t=t.parentNode))return;return t.__brush}function _i(t){return t[0][0]===t[1][0]||t[0][1]===t[1][1]}function ki(t){var e=t.__brush;return e?e.dim.output(e.selection):null}function wi(){return Ci(ci)}function Ei(){return Ci(ui)}var Ti=function(){return Ci(li)};function Ci(t){var e,n=mi,r=vi,i=bi,a=!0,o=lt("start","brush","end"),s=6;function c(e){var n=e.property("__brush",g).selectAll(".overlay").data([yi("overlay")]);n.enter().append("rect").attr("class","overlay").attr("pointer-events","all").attr("cursor",hi.overlay).merge(n).each((function(){var t=xi(this).extent;ke(this).attr("x",t[0][0]).attr("y",t[0][1]).attr("width",t[1][0]-t[0][0]).attr("height",t[1][1]-t[0][1])})),e.selectAll(".selection").data([yi("selection")]).enter().append("rect").attr("class","selection").attr("cursor",hi.selection).attr("fill","#777").attr("fill-opacity",.3).attr("stroke","#fff").attr("shape-rendering","crispEdges");var r=e.selectAll(".handle").data(t.handles,(function(t){return t.type}));r.exit().remove(),r.enter().append("rect").attr("class",(function(t){return"handle handle--"+t.type})).attr("cursor",(function(t){return hi[t.type]})),e.each(u).attr("fill","none").attr("pointer-events","all").on("mousedown.brush",f).filter(i).on("touchstart.brush",f).on("touchmove.brush",d).on("touchend.brush touchcancel.brush",p).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function u(){var t=ke(this),e=xi(this).selection;e?(t.selectAll(".selection").style("display",null).attr("x",e[0][0]).attr("y",e[0][1]).attr("width",e[1][0]-e[0][0]).attr("height",e[1][1]-e[0][1]),t.selectAll(".handle").style("display",null).attr("x",(function(t){return"e"===t.type[t.type.length-1]?e[1][0]-s/2:e[0][0]-s/2})).attr("y",(function(t){return"s"===t.type[0]?e[1][1]-s/2:e[0][1]-s/2})).attr("width",(function(t){return"n"===t.type||"s"===t.type?e[1][0]-e[0][0]+s:s})).attr("height",(function(t){return"e"===t.type||"w"===t.type?e[1][1]-e[0][1]+s:s}))):t.selectAll(".selection,.handle").style("display","none").attr("x",null).attr("y",null).attr("width",null).attr("height",null)}function l(t,e,n){return!n&&t.__brush.emitter||new h(t,e)}function h(t,e){this.that=t,this.args=e,this.state=t.__brush,this.active=0}function f(){if((!e||ce.touches)&&r.apply(this,arguments)){var n,i,o,s,c,h,f,d,p,g,y,v=this,m=ce.target.__data__.type,b="selection"===(a&&ce.metaKey?m="overlay":m)?ei:a&&ce.altKey?ii:ri,x=t===ui?null:pi[m],_=t===ci?null:gi[m],k=xi(v),w=k.extent,E=k.selection,T=w[0][0],C=w[0][1],S=w[1][0],A=w[1][1],M=0,O=0,D=x&&_&&a&&ce.shiftKey,N=ce.touches?si(ce.changedTouches[0].identifier):Nn,B=N(v),L=B,F=l(v,arguments,!0).beforestart();"overlay"===m?(E&&(p=!0),k.selection=E=[[n=t===ui?T:B[0],o=t===ci?C:B[1]],[c=t===ui?S:n,f=t===ci?A:o]]):(n=E[0][0],o=E[0][1],c=E[1][0],f=E[1][1]),i=n,s=o,h=c,d=f;var P=ke(v).attr("pointer-events","none"),I=P.selectAll(".overlay").attr("cursor",hi[m]);if(ce.touches)F.moved=R,F.ended=z;else{var j=ke(ce.view).on("mousemove.brush",R,!0).on("mouseup.brush",z,!0);a&&j.on("keydown.brush",U,!0).on("keyup.brush",$,!0),Te(ce.view)}Kr(),or(v),u.call(v),F.start()}function R(){var t=N(v);!D||g||y||(Math.abs(t[0]-L[0])>Math.abs(t[1]-L[1])?y=!0:g=!0),L=t,p=!0,ti(),Y()}function Y(){var t;switch(M=L[0]-B[0],O=L[1]-B[1],b){case ni:case ei:x&&(M=Math.max(T-n,Math.min(S-c,M)),i=n+M,h=c+M),_&&(O=Math.max(C-o,Math.min(A-f,O)),s=o+O,d=f+O);break;case ri:x<0?(M=Math.max(T-n,Math.min(S-n,M)),i=n+M,h=c):x>0&&(M=Math.max(T-c,Math.min(S-c,M)),i=n,h=c+M),_<0?(O=Math.max(C-o,Math.min(A-o,O)),s=o+O,d=f):_>0&&(O=Math.max(C-f,Math.min(A-f,O)),s=o,d=f+O);break;case ii:x&&(i=Math.max(T,Math.min(S,n-M*x)),h=Math.max(T,Math.min(S,c+M*x))),_&&(s=Math.max(C,Math.min(A,o-O*_)),d=Math.max(C,Math.min(A,f+O*_)))}h0&&(n=i-M),_<0?f=d-O:_>0&&(o=s-O),b=ni,I.attr("cursor",hi.selection),Y());break;default:return}ti()}function $(){switch(ce.keyCode){case 16:D&&(g=y=D=!1,Y());break;case 18:b===ii&&(x<0?c=h:x>0&&(n=i),_<0?f=d:_>0&&(o=s),b=ri,Y());break;case 32:b===ni&&(ce.altKey?(x&&(c=h-M*x,n=i+M*x),_&&(f=d-O*_,o=s+O*_),b=ii):(x<0?c=h:x>0&&(n=i),_<0?f=d:_>0&&(o=s),b=ri),I.attr("cursor",hi[m]),Y());break;default:return}ti()}}function d(){l(this,arguments).moved()}function p(){l(this,arguments).ended()}function g(){var e=this.__brush||{selection:null};return e.extent=oi(n.apply(this,arguments)),e.dim=t,e}return c.move=function(e,n){e.selection?e.on("start.brush",(function(){l(this,arguments).beforestart().start()})).on("interrupt.brush end.brush",(function(){l(this,arguments).end()})).tween("brush",(function(){var e=this,r=e.__brush,i=l(e,arguments),a=r.selection,o=t.input("function"==typeof n?n.apply(this,arguments):n,r.extent),s=An(a,o);function c(t){r.selection=1===t&&null===o?null:s(t),u.call(e),i.brush()}return null!==a&&null!==o?c:c(1)})):e.each((function(){var e=this,r=arguments,i=e.__brush,a=t.input("function"==typeof n?n.apply(e,r):n,i.extent),o=l(e,r).beforestart();or(e),i.selection=null===a?null:a,u.call(e),o.start().brush().end()}))},c.clear=function(t){c.move(t,null)},h.prototype={beforestart:function(){return 1==++this.active&&(this.state.emitter=this,this.starting=!0),this},start:function(){return this.starting?(this.starting=!1,this.emit("start")):this.emit("brush"),this},brush:function(){return this.emit("brush"),this},end:function(){return 0==--this.active&&(delete this.state.emitter,this.emit("end")),this},emit:function(e){pe(new Qr(c,e,t.output(this.state.selection)),o.apply,o,[e,this.that,this.args])}},c.extent=function(t){return arguments.length?(n="function"==typeof t?t:Jr(oi(t)),c):n},c.filter=function(t){return arguments.length?(r="function"==typeof t?t:Jr(!!t),c):r},c.touchable=function(t){return arguments.length?(i="function"==typeof t?t:Jr(!!t),c):i},c.handleSize=function(t){return arguments.length?(s=+t,c):s},c.keyModifiers=function(t){return arguments.length?(a=!!t,c):a},c.on=function(){var t=o.on.apply(o,arguments);return t===o?c:t},c}var Si=Math.cos,Ai=Math.sin,Mi=Math.PI,Oi=Mi/2,Di=2*Mi,Ni=Math.max;function Bi(t){return function(e,n){return t(e.source.value+e.target.value,n.source.value+n.target.value)}}var Li=function(){var t=0,e=null,n=null,r=null;function i(i){var a,o,s,c,u,l,h=i.length,f=[],d=k(h),p=[],g=[],y=g.groups=new Array(h),v=new Array(h*h);for(a=0,u=-1;++u1e-6)if(Math.abs(l*s-c*u)>1e-6&&i){var f=n-a,d=r-o,p=s*s+c*c,g=f*f+d*d,y=Math.sqrt(p),v=Math.sqrt(h),m=i*Math.tan((Ii-Math.acos((p+h-g)/(2*y*v)))/2),b=m/v,x=m/y;Math.abs(b-1)>1e-6&&(this._+="L"+(t+b*u)+","+(e+b*l)),this._+="A"+i+","+i+",0,0,"+ +(l*f>u*d)+","+(this._x1=t+x*s)+","+(this._y1=e+x*c)}else this._+="L"+(this._x1=t)+","+(this._y1=e);else;},arc:function(t,e,n,r,i,a){t=+t,e=+e,a=!!a;var o=(n=+n)*Math.cos(r),s=n*Math.sin(r),c=t+o,u=e+s,l=1^a,h=a?r-i:i-r;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+c+","+u:(Math.abs(this._x1-c)>1e-6||Math.abs(this._y1-u)>1e-6)&&(this._+="L"+c+","+u),n&&(h<0&&(h=h%ji+ji),h>Ri?this._+="A"+n+","+n+",0,1,"+l+","+(t-o)+","+(e-s)+"A"+n+","+n+",0,1,"+l+","+(this._x1=c)+","+(this._y1=u):h>1e-6&&(this._+="A"+n+","+n+",0,"+ +(h>=Ii)+","+l+","+(this._x1=t+n*Math.cos(i))+","+(this._y1=e+n*Math.sin(i))))},rect:function(t,e,n,r){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +n+"v"+ +r+"h"+-n+"Z"},toString:function(){return this._}};var Ui=zi;function $i(t){return t.source}function Wi(t){return t.target}function Vi(t){return t.radius}function Hi(t){return t.startAngle}function Gi(t){return t.endAngle}var qi=function(){var t=$i,e=Wi,n=Vi,r=Hi,i=Gi,a=null;function o(){var o,s=Fi.call(arguments),c=t.apply(this,s),u=e.apply(this,s),l=+n.apply(this,(s[0]=c,s)),h=r.apply(this,s)-Oi,f=i.apply(this,s)-Oi,d=l*Si(h),p=l*Ai(h),g=+n.apply(this,(s[0]=u,s)),y=r.apply(this,s)-Oi,v=i.apply(this,s)-Oi;if(a||(a=o=Ui()),a.moveTo(d,p),a.arc(0,0,l,h,f),h===y&&f===v||(a.quadraticCurveTo(0,0,g*Si(y),g*Ai(y)),a.arc(0,0,g,y,v)),a.quadraticCurveTo(0,0,d,p),a.closePath(),o)return a=null,o+""||null}return o.radius=function(t){return arguments.length?(n="function"==typeof t?t:Pi(+t),o):n},o.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:Pi(+t),o):r},o.endAngle=function(t){return arguments.length?(i="function"==typeof t?t:Pi(+t),o):i},o.source=function(e){return arguments.length?(t=e,o):t},o.target=function(t){return arguments.length?(e=t,o):e},o.context=function(t){return arguments.length?(a=null==t?null:t,o):a},o};function Xi(){}function Zi(t,e){var n=new Xi;if(t instanceof Xi)t.each((function(t,e){n.set(e,t)}));else if(Array.isArray(t)){var r,i=-1,a=t.length;if(null==e)for(;++i=r.length)return null!=t&&n.sort(t),null!=e?e(n):n;for(var c,u,l,h=-1,f=n.length,d=r[i++],p=Ji(),g=o();++hr.length)return n;var o,s=i[a-1];return null!=e&&a>=r.length?o=n.entries():(o=[],n.each((function(e,n){o.push({key:n,values:t(e,a)})}))),null!=s?o.sort((function(t,e){return s(t.key,e.key)})):o}(a(t,0,ea,na),0)},key:function(t){return r.push(t),n},sortKeys:function(t){return i[r.length-1]=t,n},sortValues:function(e){return t=e,n},rollup:function(t){return e=t,n}}};function Ki(){return{}}function ta(t,e,n){t[e]=n}function ea(){return Ji()}function na(t,e,n){t.set(e,n)}function ra(){}var ia=Ji.prototype;function aa(t,e){var n=new ra;if(t instanceof ra)t.each((function(t){n.add(t)}));else if(t){var r=-1,i=t.length;if(null==e)for(;++r6/29*(6/29)*(6/29)?Math.pow(t,1/3):t/(6/29*3*(6/29))+4/29}function va(t){return t>6/29?t*t*t:6/29*3*(6/29)*(t-4/29)}function ma(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function ba(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function xa(t){if(t instanceof wa)return new wa(t.h,t.c,t.l,t.opacity);if(t instanceof ga||(t=fa(t)),0===t.a&&0===t.b)return new wa(NaN,0r!=d>r&&n<(f-u)*(r-l)/(d-l)+u&&(i=-i)}return i}function Ia(t,e,n){var r,i,a,o;return function(t,e,n){return(e[0]-t[0])*(n[1]-t[1])==(n[0]-t[0])*(e[1]-t[1])}(t,e,n)&&(i=t[r=+(t[0]===e[0])],a=n[r],o=e[r],i<=a&&a<=o||o<=a&&a<=i)}var ja=function(){},Ra=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]],Ya=function(){var t=1,e=1,n=M,r=s;function i(t){var e=n(t);if(Array.isArray(e))e=e.slice().sort(Ba);else{var r=y(t),i=r[0],o=r[1];e=A(i,o,e),e=k(Math.floor(i/e)*e,Math.floor(o/e)*e,e)}return e.map((function(e){return a(t,e)}))}function a(n,i){var a=[],s=[];return function(n,r,i){var a,s,c,u,l,h,f=new Array,d=new Array;a=s=-1,u=n[0]>=r,Ra[u<<1].forEach(p);for(;++a=r,Ra[c|u<<1].forEach(p);Ra[u<<0].forEach(p);for(;++s=r,l=n[s*t]>=r,Ra[u<<1|l<<2].forEach(p);++a=r,h=l,l=n[s*t+a+1]>=r,Ra[c|u<<1|l<<2|h<<3].forEach(p);Ra[u|l<<3].forEach(p)}a=-1,l=n[s*t]>=r,Ra[l<<2].forEach(p);for(;++a=r,Ra[l<<2|h<<3].forEach(p);function p(t){var e,n,r=[t[0][0]+a,t[0][1]+s],c=[t[1][0]+a,t[1][1]+s],u=o(r),l=o(c);(e=d[u])?(n=f[l])?(delete d[e.end],delete f[n.start],e===n?(e.ring.push(c),i(e.ring)):f[e.start]=d[n.end]={start:e.start,end:n.end,ring:e.ring.concat(n.ring)}):(delete d[e.end],e.ring.push(c),d[e.end=l]=e):(e=f[l])?(n=d[u])?(delete f[e.start],delete d[n.end],e===n?(e.ring.push(c),i(e.ring)):f[n.start]=d[e.end]={start:n.start,end:e.end,ring:n.ring.concat(e.ring)}):(delete f[e.start],e.ring.unshift(r),f[e.start=u]=e):f[u]=d[l]={start:u,end:l,ring:[r,c]}}Ra[l<<3].forEach(p)}(n,i,(function(t){r(t,n,i),function(t){for(var e=0,n=t.length,r=t[n-1][1]*t[0][0]-t[n-1][0]*t[0][1];++e0?a.push([t]):s.push(t)})),s.forEach((function(t){for(var e,n=0,r=a.length;n0&&o0&&s0&&a>0))throw new Error("invalid size");return t=r,e=a,i},i.thresholds=function(t){return arguments.length?(n="function"==typeof t?t:Array.isArray(t)?La(Na.call(t)):La(t),i):n},i.smooth=function(t){return arguments.length?(r=t?s:ja,i):r===s},i};function za(t,e,n){for(var r=t.width,i=t.height,a=1+(n<<1),o=0;o=n&&(s>=a&&(c-=t.data[s-a+o*r]),e.data[s-n+o*r]=c/Math.min(s+1,r-1+a-s,a))}function Ua(t,e,n){for(var r=t.width,i=t.height,a=1+(n<<1),o=0;o=n&&(s>=a&&(c-=t.data[o+(s-a)*r]),e.data[o+(s-n)*r]=c/Math.min(s+1,i-1+a-s,a))}function $a(t){return t[0]}function Wa(t){return t[1]}function Va(){return 1}var Ha=function(){var t=$a,e=Wa,n=Va,r=960,i=500,a=20,o=2,s=3*a,c=r+2*s>>o,u=i+2*s>>o,l=La(20);function h(r){var i=new Float32Array(c*u),h=new Float32Array(c*u);r.forEach((function(r,a,l){var h=+t(r,a,l)+s>>o,f=+e(r,a,l)+s>>o,d=+n(r,a,l);h>=0&&h=0&&f>o),Ua({width:c,height:u,data:h},{width:c,height:u,data:i},a>>o),za({width:c,height:u,data:i},{width:c,height:u,data:h},a>>o),Ua({width:c,height:u,data:h},{width:c,height:u,data:i},a>>o),za({width:c,height:u,data:i},{width:c,height:u,data:h},a>>o),Ua({width:c,height:u,data:h},{width:c,height:u,data:i},a>>o);var d=l(i);if(!Array.isArray(d)){var p=L(i);d=A(0,p,d),(d=k(0,Math.floor(p/d)*d,d)).shift()}return Ya().thresholds(d).size([c,u])(i).map(f)}function f(t){return t.value*=Math.pow(2,-2*o),t.coordinates.forEach(d),t}function d(t){t.forEach(p)}function p(t){t.forEach(g)}function g(t){t[0]=t[0]*Math.pow(2,o)-s,t[1]=t[1]*Math.pow(2,o)-s}function y(){return c=r+2*(s=3*a)>>o,u=i+2*s>>o,h}return h.x=function(e){return arguments.length?(t="function"==typeof e?e:La(+e),h):t},h.y=function(t){return arguments.length?(e="function"==typeof t?t:La(+t),h):e},h.weight=function(t){return arguments.length?(n="function"==typeof t?t:La(+t),h):n},h.size=function(t){if(!arguments.length)return[r,i];var e=Math.ceil(t[0]),n=Math.ceil(t[1]);if(!(e>=0||e>=0))throw new Error("invalid size");return r=e,i=n,y()},h.cellSize=function(t){if(!arguments.length)return 1<=1))throw new Error("invalid cell size");return o=Math.floor(Math.log(t)/Math.LN2),y()},h.thresholds=function(t){return arguments.length?(l="function"==typeof t?t:Array.isArray(t)?La(Na.call(t)):La(t),h):l},h.bandwidth=function(t){if(!arguments.length)return Math.sqrt(a*(a+1));if(!((t=+t)>=0))throw new Error("invalid bandwidth");return a=Math.round((Math.sqrt(4*t*t+1)-1)/2),y()},h},Ga=function(t){return function(){return t}};function qa(t,e,n,r,i,a,o,s,c,u){this.target=t,this.type=e,this.subject=n,this.identifier=r,this.active=i,this.x=a,this.y=o,this.dx=s,this.dy=c,this._=u}function Xa(){return!ce.ctrlKey&&!ce.button}function Za(){return this.parentNode}function Ja(t){return null==t?{x:ce.x,y:ce.y}:t}function Qa(){return navigator.maxTouchPoints||"ontouchstart"in this}qa.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};var Ka=function(){var t,e,n,r,i=Xa,a=Za,o=Ja,s=Qa,c={},u=lt("start","drag","end"),l=0,h=0;function f(t){t.on("mousedown.drag",d).filter(s).on("touchstart.drag",y).on("touchmove.drag",v).on("touchend.drag touchcancel.drag",m).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function d(){if(!r&&i.apply(this,arguments)){var o=b("mouse",a.apply(this,arguments),Nn,this,arguments);o&&(ke(ce.view).on("mousemove.drag",p,!0).on("mouseup.drag",g,!0),Te(ce.view),we(),n=!1,t=ce.clientX,e=ce.clientY,o("start"))}}function p(){if(Ee(),!n){var r=ce.clientX-t,i=ce.clientY-e;n=r*r+i*i>h}c.mouse("drag")}function g(){ke(ce.view).on("mousemove.drag mouseup.drag",null),Ce(ce.view,n),Ee(),c.mouse("end")}function y(){if(i.apply(this,arguments)){var t,e,n=ce.changedTouches,r=a.apply(this,arguments),o=n.length;for(t=0;t9999?"+"+io(e,6):io(e,4))+"-"+io(t.getUTCMonth()+1,2)+"-"+io(t.getUTCDate(),2)+(a?"T"+io(n,2)+":"+io(r,2)+":"+io(i,2)+"."+io(a,3)+"Z":i?"T"+io(n,2)+":"+io(r,2)+":"+io(i,2)+"Z":r||n?"T"+io(n,2)+":"+io(r,2)+"Z":"")}var oo=function(t){var e=new RegExp('["'+t+"\n\r]"),n=t.charCodeAt(0);function r(t,e){var r,i=[],a=t.length,o=0,s=0,c=a<=0,u=!1;function l(){if(c)return eo;if(u)return u=!1,to;var e,r,i=o;if(34===t.charCodeAt(i)){for(;o++=a?c=!0:10===(r=t.charCodeAt(o++))?u=!0:13===r&&(u=!0,10===t.charCodeAt(o)&&++o),t.slice(i+1,e-1).replace(/""/g,'"')}for(;o=(a=(g+v)/2))?g=a:v=a,(l=n>=(o=(y+m)/2))?y=o:m=o,i=d,!(d=d[h=l<<1|u]))return i[h]=p,t;if(s=+t._x.call(null,d.data),c=+t._y.call(null,d.data),e===s&&n===c)return p.next=d,i?i[h]=p:t._root=p,t;do{i=i?i[h]=new Array(4):t._root=new Array(4),(u=e>=(a=(g+v)/2))?g=a:v=a,(l=n>=(o=(y+m)/2))?y=o:m=o}while((h=l<<1|u)==(f=(c>=o)<<1|s>=a));return i[f]=d,i[h]=p,t}var _s=function(t,e,n,r,i){this.node=t,this.x0=e,this.y0=n,this.x1=r,this.y1=i};function ks(t){return t[0]}function ws(t){return t[1]}function Es(t,e,n){var r=new Ts(null==e?ks:e,null==n?ws:n,NaN,NaN,NaN,NaN);return null==t?r:r.addAll(t)}function Ts(t,e,n,r,i,a){this._x=t,this._y=e,this._x0=n,this._y0=r,this._x1=i,this._y1=a,this._root=void 0}function Cs(t){for(var e={data:t.data},n=e;t=t.next;)n=n.next={data:t.data};return e}var Ss=Es.prototype=Ts.prototype;function As(t){return t.x+t.vx}function Ms(t){return t.y+t.vy}Ss.copy=function(){var t,e,n=new Ts(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return n;if(!r.length)return n._root=Cs(r),n;for(t=[{source:r,target:n._root=new Array(4)}];r=t.pop();)for(var i=0;i<4;++i)(e=r.source[i])&&(e.length?t.push({source:e,target:r.target[i]=new Array(4)}):r.target[i]=Cs(e));return n},Ss.add=function(t){var e=+this._x.call(null,t),n=+this._y.call(null,t);return xs(this.cover(e,n),e,n,t)},Ss.addAll=function(t){var e,n,r,i,a=t.length,o=new Array(a),s=new Array(a),c=1/0,u=1/0,l=-1/0,h=-1/0;for(n=0;nl&&(l=r),ih&&(h=i));if(c>l||u>h)return this;for(this.cover(c,u).cover(l,h),n=0;nt||t>=i||r>e||e>=a;)switch(s=(ef||(a=c.y0)>d||(o=c.x1)=v)<<1|t>=y)&&(c=p[p.length-1],p[p.length-1]=p[p.length-1-u],p[p.length-1-u]=c)}else{var m=t-+this._x.call(null,g.data),b=e-+this._y.call(null,g.data),x=m*m+b*b;if(x=(s=(p+y)/2))?p=s:y=s,(l=o>=(c=(g+v)/2))?g=c:v=c,e=d,!(d=d[h=l<<1|u]))return this;if(!d.length)break;(e[h+1&3]||e[h+2&3]||e[h+3&3])&&(n=e,f=h)}for(;d.data!==t;)if(r=d,!(d=d.next))return this;return(i=d.next)&&delete d.next,r?(i?r.next=i:delete r.next,this):e?(i?e[h]=i:delete e[h],(d=e[0]||e[1]||e[2]||e[3])&&d===(e[3]||e[2]||e[1]||e[0])&&!d.length&&(n?n[f]=d:this._root=d),this):(this._root=i,this)},Ss.removeAll=function(t){for(var e=0,n=t.length;ec+d||iu+d||as.index){var p=c-o.x-o.vx,g=u-o.y-o.vy,y=p*p+g*g;yt.r&&(t.r=t[e].r)}function s(){if(e){var r,i,a=e.length;for(n=new Array(a),r=0;r1?(null==n?s.remove(t):s.set(t,d(n)),e):s.get(t)},find:function(e,n,r){var i,a,o,s,c,u=0,l=t.length;for(null==r?r=1/0:r*=r,u=0;u1?(u.on(t,n),e):u.on(t)}}},js=function(){var t,e,n,r,i=ms(-30),a=1,o=1/0,s=.81;function c(r){var i,a=t.length,o=Es(t,Ls,Fs).visitAfter(l);for(n=r,i=0;i=o)){(t.data!==e||t.next)&&(0===l&&(d+=(l=bs())*l),0===h&&(d+=(h=bs())*h),d1?r[0]+r.slice(2):r,+t.slice(n+1)]},$s=function(t){return(t=Us(Math.abs(t)))?t[1]:NaN},Ws=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Vs(t){if(!(e=Ws.exec(t)))throw new Error("invalid format: "+t);var e;return new Hs({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function Hs(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}Vs.prototype=Hs.prototype,Hs.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};var Gs,qs,Xs,Zs,Js=function(t,e){var n=Us(t,e);if(!n)return t+"";var r=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")},Qs={"%":function(t,e){return(100*t).toFixed(e)},b:function(t){return Math.round(t).toString(2)},c:function(t){return t+""},d:function(t){return Math.round(t).toString(10)},e:function(t,e){return t.toExponential(e)},f:function(t,e){return t.toFixed(e)},g:function(t,e){return t.toPrecision(e)},o:function(t){return Math.round(t).toString(8)},p:function(t,e){return Js(100*t,e)},r:Js,s:function(t,e){var n=Us(t,e);if(!n)return t+"";var r=n[0],i=n[1],a=i-(Gs=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,o=r.length;return a===o?r:a>o?r+new Array(a-o+1).join("0"):a>0?r.slice(0,a)+"."+r.slice(a):"0."+new Array(1-a).join("0")+Us(t,Math.max(0,e+a-1))[0]},X:function(t){return Math.round(t).toString(16).toUpperCase()},x:function(t){return Math.round(t).toString(16)}},Ks=function(t){return t},tc=Array.prototype.map,ec=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"],nc=function(t){var e,n,r=void 0===t.grouping||void 0===t.thousands?Ks:(e=tc.call(t.grouping,Number),n=t.thousands+"",function(t,r){for(var i=t.length,a=[],o=0,s=e[0],c=0;i>0&&s>0&&(c+s+1>r&&(s=Math.max(1,r-c)),a.push(t.substring(i-=s,i+s)),!((c+=s+1)>r));)s=e[o=(o+1)%e.length];return a.reverse().join(n)}),i=void 0===t.currency?"":t.currency[0]+"",a=void 0===t.currency?"":t.currency[1]+"",o=void 0===t.decimal?".":t.decimal+"",s=void 0===t.numerals?Ks:function(t){return function(e){return e.replace(/[0-9]/g,(function(e){return t[+e]}))}}(tc.call(t.numerals,String)),c=void 0===t.percent?"%":t.percent+"",u=void 0===t.minus?"-":t.minus+"",l=void 0===t.nan?"NaN":t.nan+"";function h(t){var e=(t=Vs(t)).fill,n=t.align,h=t.sign,f=t.symbol,d=t.zero,p=t.width,g=t.comma,y=t.precision,v=t.trim,m=t.type;"n"===m?(g=!0,m="g"):Qs[m]||(void 0===y&&(y=12),v=!0,m="g"),(d||"0"===e&&"="===n)&&(d=!0,e="0",n="=");var b="$"===f?i:"#"===f&&/[boxX]/.test(m)?"0"+m.toLowerCase():"",x="$"===f?a:/[%p]/.test(m)?c:"",_=Qs[m],k=/[defgprs%]/.test(m);function w(t){var i,a,c,f=b,w=x;if("c"===m)w=_(t)+w,t="";else{var E=(t=+t)<0;if(t=isNaN(t)?l:_(Math.abs(t),y),v&&(t=function(t){t:for(var e,n=t.length,r=1,i=-1;r0&&(i=0)}return i>0?t.slice(0,i)+t.slice(e+1):t}(t)),E&&0==+t&&(E=!1),f=(E?"("===h?h:u:"-"===h||"("===h?"":h)+f,w=("s"===m?ec[8+Gs/3]:"")+w+(E&&"("===h?")":""),k)for(i=-1,a=t.length;++i(c=t.charCodeAt(i))||c>57){w=(46===c?o+t.slice(i+1):t.slice(i))+w,t=t.slice(0,i);break}}g&&!d&&(t=r(t,1/0));var T=f.length+t.length+w.length,C=T>1)+f+t+w+C.slice(T);break;default:t=C+f+t+w}return s(t)}return y=void 0===y?6:/[gprs]/.test(m)?Math.max(1,Math.min(21,y)):Math.max(0,Math.min(20,y)),w.toString=function(){return t+""},w}return{format:h,formatPrefix:function(t,e){var n=h(((t=Vs(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor($s(e)/3))),i=Math.pow(10,-r),a=ec[8+r/3];return function(t){return n(i*t)+a}}}};function rc(t){return qs=nc(t),Xs=qs.format,Zs=qs.formatPrefix,qs}rc({decimal:".",thousands:",",grouping:[3],currency:["$",""],minus:"-"});var ic=function(t){return Math.max(0,-$s(Math.abs(t)))},ac=function(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor($s(e)/3)))-$s(Math.abs(t)))},oc=function(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,$s(e)-$s(t))+1},sc=function(){return new cc};function cc(){this.reset()}cc.prototype={constructor:cc,reset:function(){this.s=this.t=0},add:function(t){lc(uc,t,this.t),lc(this,uc.s,this.s),this.s?this.t+=uc.t:this.s=uc.t},valueOf:function(){return this.s}};var uc=new cc;function lc(t,e,n){var r=t.s=e+n,i=r-e,a=r-i;t.t=e-a+(n-i)}var hc=Math.PI,fc=hc/2,dc=hc/4,pc=2*hc,gc=180/hc,yc=hc/180,vc=Math.abs,mc=Math.atan,bc=Math.atan2,xc=Math.cos,_c=Math.ceil,kc=Math.exp,wc=(Math.floor,Math.log),Ec=Math.pow,Tc=Math.sin,Cc=Math.sign||function(t){return t>0?1:t<0?-1:0},Sc=Math.sqrt,Ac=Math.tan;function Mc(t){return t>1?0:t<-1?hc:Math.acos(t)}function Oc(t){return t>1?fc:t<-1?-fc:Math.asin(t)}function Dc(t){return(t=Tc(t/2))*t}function Nc(){}function Bc(t,e){t&&Fc.hasOwnProperty(t.type)&&Fc[t.type](t,e)}var Lc={Feature:function(t,e){Bc(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,a=xc(e=(e*=yc)/2+dc),o=Tc(e),s=Uc*o,c=zc*a+s*xc(i),u=s*r*Tc(i);Wc.add(bc(u,c)),Yc=t,zc=a,Uc=o}var Jc=function(t){return Vc.reset(),$c(t,Hc),2*Vc};function Qc(t){return[bc(t[1],t[0]),Oc(t[2])]}function Kc(t){var e=t[0],n=t[1],r=xc(n);return[r*xc(e),r*Tc(e),Tc(n)]}function tu(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function eu(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function nu(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2]}function ru(t,e){return[t[0]*e,t[1]*e,t[2]*e]}function iu(t){var e=Sc(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e}var au,ou,su,cu,uu,lu,hu,fu,du,pu,gu=sc(),yu={point:vu,lineStart:bu,lineEnd:xu,polygonStart:function(){yu.point=_u,yu.lineStart=ku,yu.lineEnd=wu,gu.reset(),Hc.polygonStart()},polygonEnd:function(){Hc.polygonEnd(),yu.point=vu,yu.lineStart=bu,yu.lineEnd=xu,Wc<0?(au=-(su=180),ou=-(cu=90)):gu>1e-6?cu=90:gu<-1e-6&&(ou=-90),pu[0]=au,pu[1]=su},sphere:function(){au=-(su=180),ou=-(cu=90)}};function vu(t,e){du.push(pu=[au=t,su=t]),ecu&&(cu=e)}function mu(t,e){var n=Kc([t*yc,e*yc]);if(fu){var r=eu(fu,n),i=eu([r[1],-r[0],0],r);iu(i),i=Qc(i);var a,o=t-uu,s=o>0?1:-1,c=i[0]*gc*s,u=vc(o)>180;u^(s*uucu&&(cu=a):u^(s*uu<(c=(c+360)%360-180)&&ccu&&(cu=e)),u?tEu(au,su)&&(su=t):Eu(t,su)>Eu(au,su)&&(au=t):su>=au?(tsu&&(su=t)):t>uu?Eu(au,t)>Eu(au,su)&&(su=t):Eu(t,su)>Eu(au,su)&&(au=t)}else du.push(pu=[au=t,su=t]);ecu&&(cu=e),fu=n,uu=t}function bu(){yu.point=mu}function xu(){pu[0]=au,pu[1]=su,yu.point=vu,fu=null}function _u(t,e){if(fu){var n=t-uu;gu.add(vc(n)>180?n+(n>0?360:-360):n)}else lu=t,hu=e;Hc.point(t,e),mu(t,e)}function ku(){Hc.lineStart()}function wu(){_u(lu,hu),Hc.lineEnd(),vc(gu)>1e-6&&(au=-(su=180)),pu[0]=au,pu[1]=su,fu=null}function Eu(t,e){return(e-=t)<0?e+360:e}function Tu(t,e){return t[0]-e[0]}function Cu(t,e){return t[0]<=t[1]?t[0]<=e&&e<=t[1]:eEu(r[0],r[1])&&(r[1]=i[1]),Eu(i[0],r[1])>Eu(r[0],r[1])&&(r[0]=i[0])):a.push(r=i);for(o=-1/0,e=0,r=a[n=a.length-1];e<=n;r=i,++e)i=a[e],(s=Eu(r[1],i[0]))>o&&(o=s,au=i[0],su=r[1])}return du=pu=null,au===1/0||ou===1/0?[[NaN,NaN],[NaN,NaN]]:[[au,ou],[su,cu]]},Wu={sphere:Nc,point:Vu,lineStart:Gu,lineEnd:Zu,polygonStart:function(){Wu.lineStart=Ju,Wu.lineEnd=Qu},polygonEnd:function(){Wu.lineStart=Gu,Wu.lineEnd=Zu}};function Vu(t,e){t*=yc;var n=xc(e*=yc);Hu(n*xc(t),n*Tc(t),Tc(e))}function Hu(t,e,n){++Su,Mu+=(t-Mu)/Su,Ou+=(e-Ou)/Su,Du+=(n-Du)/Su}function Gu(){Wu.point=qu}function qu(t,e){t*=yc;var n=xc(e*=yc);Yu=n*xc(t),zu=n*Tc(t),Uu=Tc(e),Wu.point=Xu,Hu(Yu,zu,Uu)}function Xu(t,e){t*=yc;var n=xc(e*=yc),r=n*xc(t),i=n*Tc(t),a=Tc(e),o=bc(Sc((o=zu*a-Uu*i)*o+(o=Uu*r-Yu*a)*o+(o=Yu*i-zu*r)*o),Yu*r+zu*i+Uu*a);Au+=o,Nu+=o*(Yu+(Yu=r)),Bu+=o*(zu+(zu=i)),Lu+=o*(Uu+(Uu=a)),Hu(Yu,zu,Uu)}function Zu(){Wu.point=Vu}function Ju(){Wu.point=Ku}function Qu(){tl(ju,Ru),Wu.point=Vu}function Ku(t,e){ju=t,Ru=e,t*=yc,e*=yc,Wu.point=tl;var n=xc(e);Yu=n*xc(t),zu=n*Tc(t),Uu=Tc(e),Hu(Yu,zu,Uu)}function tl(t,e){t*=yc;var n=xc(e*=yc),r=n*xc(t),i=n*Tc(t),a=Tc(e),o=zu*a-Uu*i,s=Uu*r-Yu*a,c=Yu*i-zu*r,u=Sc(o*o+s*s+c*c),l=Oc(u),h=u&&-l/u;Fu+=h*o,Pu+=h*s,Iu+=h*c,Au+=l,Nu+=l*(Yu+(Yu=r)),Bu+=l*(zu+(zu=i)),Lu+=l*(Uu+(Uu=a)),Hu(Yu,zu,Uu)}var el=function(t){Su=Au=Mu=Ou=Du=Nu=Bu=Lu=Fu=Pu=Iu=0,$c(t,Wu);var e=Fu,n=Pu,r=Iu,i=e*e+n*n+r*r;return i<1e-12&&(e=Nu,n=Bu,r=Lu,Au<1e-6&&(e=Mu,n=Ou,r=Du),(i=e*e+n*n+r*r)<1e-12)?[NaN,NaN]:[bc(n,e)*gc,Oc(r/Sc(i))*gc]},nl=function(t){return function(){return t}},rl=function(t,e){function n(n,r){return n=t(n,r),e(n[0],n[1])}return t.invert&&e.invert&&(n.invert=function(n,r){return(n=e.invert(n,r))&&t.invert(n[0],n[1])}),n};function il(t,e){return[vc(t)>hc?t+Math.round(-t/pc)*pc:t,e]}function al(t,e,n){return(t%=pc)?e||n?rl(sl(t),cl(e,n)):sl(t):e||n?cl(e,n):il}function ol(t){return function(e,n){return[(e+=t)>hc?e-pc:e<-hc?e+pc:e,n]}}function sl(t){var e=ol(t);return e.invert=ol(-t),e}function cl(t,e){var n=xc(t),r=Tc(t),i=xc(e),a=Tc(e);function o(t,e){var o=xc(e),s=xc(t)*o,c=Tc(t)*o,u=Tc(e),l=u*n+s*r;return[bc(c*i-l*a,s*n-u*r),Oc(l*i+c*a)]}return o.invert=function(t,e){var o=xc(e),s=xc(t)*o,c=Tc(t)*o,u=Tc(e),l=u*i-c*a;return[bc(c*i+u*a,s*n+l*r),Oc(l*n-s*r)]},o}il.invert=il;var ul=function(t){function e(e){return(e=t(e[0]*yc,e[1]*yc))[0]*=gc,e[1]*=gc,e}return t=al(t[0]*yc,t[1]*yc,t.length>2?t[2]*yc:0),e.invert=function(e){return(e=t.invert(e[0]*yc,e[1]*yc))[0]*=gc,e[1]*=gc,e},e};function ll(t,e,n,r,i,a){if(n){var o=xc(e),s=Tc(e),c=r*n;null==i?(i=e+r*pc,a=e-c/2):(i=hl(o,i),a=hl(o,a),(r>0?ia)&&(i+=r*pc));for(var u,l=i;r>0?l>a:l1&&e.push(e.pop().concat(e.shift()))},result:function(){var n=e;return e=[],t=null,n}}},pl=function(t,e){return vc(t[0]-e[0])<1e-6&&vc(t[1]-e[1])<1e-6};function gl(t,e,n,r){this.x=t,this.z=e,this.o=n,this.e=r,this.v=!1,this.n=this.p=null}var yl=function(t,e,n,r,i){var a,o,s=[],c=[];if(t.forEach((function(t){if(!((e=t.length-1)<=0)){var e,n,r=t[0],o=t[e];if(pl(r,o)){for(i.lineStart(),a=0;a=0;--a)i.point((l=u[a])[0],l[1]);else r(f.x,f.p.x,-1,i);f=f.p}u=(f=f.o).z,d=!d}while(!f.v);i.lineEnd()}}};function vl(t){if(e=t.length){for(var e,n,r=0,i=t[0];++r=0?1:-1,T=E*w,C=T>hc,S=g*_;if(ml.add(bc(S*E*Tc(T),y*k+S*xc(T))),o+=C?w+E*pc:w,C^d>=n^b>=n){var A=eu(Kc(f),Kc(m));iu(A);var M=eu(a,A);iu(M);var O=(C^w>=0?-1:1)*Oc(M[2]);(r>O||r===O&&(A[0]||A[1]))&&(s+=C^w>=0?1:-1)}}return(o<-1e-6||o<1e-6&&ml<-1e-6)^1&s},_l=function(t,e,n,r){return function(i){var a,o,s,c=e(i),u=dl(),l=e(u),h=!1,f={point:d,lineStart:g,lineEnd:y,polygonStart:function(){f.point=v,f.lineStart=m,f.lineEnd=b,o=[],a=[]},polygonEnd:function(){f.point=d,f.lineStart=g,f.lineEnd=y,o=I(o);var t=xl(a,r);o.length?(h||(i.polygonStart(),h=!0),yl(o,wl,t,n,i)):t&&(h||(i.polygonStart(),h=!0),i.lineStart(),n(null,null,1,i),i.lineEnd()),h&&(i.polygonEnd(),h=!1),o=a=null},sphere:function(){i.polygonStart(),i.lineStart(),n(null,null,1,i),i.lineEnd(),i.polygonEnd()}};function d(e,n){t(e,n)&&i.point(e,n)}function p(t,e){c.point(t,e)}function g(){f.point=p,c.lineStart()}function y(){f.point=d,c.lineEnd()}function v(t,e){s.push([t,e]),l.point(t,e)}function m(){l.lineStart(),s=[]}function b(){v(s[0][0],s[0][1]),l.lineEnd();var t,e,n,r,c=l.clean(),f=u.result(),d=f.length;if(s.pop(),a.push(s),s=null,d)if(1&c){if((e=(n=f[0]).length-1)>0){for(h||(i.polygonStart(),h=!0),i.lineStart(),t=0;t1&&2&c&&f.push(f.pop().concat(f.shift())),o.push(f.filter(kl))}return f}};function kl(t){return t.length>1}function wl(t,e){return((t=t.x)[0]<0?t[1]-fc-1e-6:fc-t[1])-((e=e.x)[0]<0?e[1]-fc-1e-6:fc-e[1])}var El=_l((function(){return!0}),(function(t){var e,n=NaN,r=NaN,i=NaN;return{lineStart:function(){t.lineStart(),e=1},point:function(a,o){var s=a>0?hc:-hc,c=vc(a-n);vc(c-hc)<1e-6?(t.point(n,r=(r+o)/2>0?fc:-fc),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(s,r),t.point(a,r),e=0):i!==s&&c>=hc&&(vc(n-i)<1e-6&&(n-=1e-6*i),vc(a-s)<1e-6&&(a-=1e-6*s),r=function(t,e,n,r){var i,a,o=Tc(t-n);return vc(o)>1e-6?mc((Tc(e)*(a=xc(r))*Tc(n)-Tc(r)*(i=xc(e))*Tc(t))/(i*a*o)):(e+r)/2}(n,r,a,o),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(s,r),e=0),t.point(n=a,r=o),i=s},lineEnd:function(){t.lineEnd(),n=r=NaN},clean:function(){return 2-e}}}),(function(t,e,n,r){var i;if(null==t)i=n*fc,r.point(-hc,i),r.point(0,i),r.point(hc,i),r.point(hc,0),r.point(hc,-i),r.point(0,-i),r.point(-hc,-i),r.point(-hc,0),r.point(-hc,i);else if(vc(t[0]-e[0])>1e-6){var a=t[0]0,i=vc(e)>1e-6;function a(t,n){return xc(t)*xc(n)>e}function o(t,n,r){var i=[1,0,0],a=eu(Kc(t),Kc(n)),o=tu(a,a),s=a[0],c=o-s*s;if(!c)return!r&&t;var u=e*o/c,l=-e*s/c,h=eu(i,a),f=ru(i,u);nu(f,ru(a,l));var d=h,p=tu(f,d),g=tu(d,d),y=p*p-g*(tu(f,f)-1);if(!(y<0)){var v=Sc(y),m=ru(d,(-p-v)/g);if(nu(m,f),m=Qc(m),!r)return m;var b,x=t[0],_=n[0],k=t[1],w=n[1];_0^m[1]<(vc(m[0]-x)<1e-6?k:w):k<=m[1]&&m[1]<=w:E>hc^(x<=m[0]&&m[0]<=_)){var C=ru(d,(-p+v)/g);return nu(C,f),[m,Qc(C)]}}}function s(e,n){var i=r?t:hc-t,a=0;return e<-i?a|=1:e>i&&(a|=2),n<-i?a|=4:n>i&&(a|=8),a}return _l(a,(function(t){var e,n,c,u,l;return{lineStart:function(){u=c=!1,l=1},point:function(h,f){var d,p=[h,f],g=a(h,f),y=r?g?0:s(h,f):g?s(h+(h<0?hc:-hc),f):0;if(!e&&(u=c=g)&&t.lineStart(),g!==c&&(!(d=o(e,p))||pl(e,d)||pl(p,d))&&(p[0]+=1e-6,p[1]+=1e-6,g=a(p[0],p[1])),g!==c)l=0,g?(t.lineStart(),d=o(p,e),t.point(d[0],d[1])):(d=o(e,p),t.point(d[0],d[1]),t.lineEnd()),e=d;else if(i&&e&&r^g){var v;y&n||!(v=o(p,e,!0))||(l=0,r?(t.lineStart(),t.point(v[0][0],v[0][1]),t.point(v[1][0],v[1][1]),t.lineEnd()):(t.point(v[1][0],v[1][1]),t.lineEnd(),t.lineStart(),t.point(v[0][0],v[0][1])))}!g||e&&pl(e,p)||t.point(p[0],p[1]),e=p,c=g,n=y},lineEnd:function(){c&&t.lineEnd(),e=null},clean:function(){return l|(u&&c)<<1}}}),(function(e,r,i,a){ll(a,t,n,i,e,r)}),r?[0,-t]:[-hc,t-hc])};function Cl(t,e,n,r){function i(i,a){return t<=i&&i<=n&&e<=a&&a<=r}function a(i,a,s,u){var l=0,h=0;if(null==i||(l=o(i,s))!==(h=o(a,s))||c(i,a)<0^s>0)do{u.point(0===l||3===l?t:n,l>1?r:e)}while((l=(l+s+4)%4)!==h);else u.point(a[0],a[1])}function o(r,i){return vc(r[0]-t)<1e-6?i>0?0:3:vc(r[0]-n)<1e-6?i>0?2:1:vc(r[1]-e)<1e-6?i>0?1:0:i>0?3:2}function s(t,e){return c(t.x,e.x)}function c(t,e){var n=o(t,1),r=o(e,1);return n!==r?n-r:0===n?e[1]-t[1]:1===n?t[0]-e[0]:2===n?t[1]-e[1]:e[0]-t[0]}return function(o){var c,u,l,h,f,d,p,g,y,v,m,b=o,x=dl(),_={point:k,lineStart:function(){_.point=w,u&&u.push(l=[]);v=!0,y=!1,p=g=NaN},lineEnd:function(){c&&(w(h,f),d&&y&&x.rejoin(),c.push(x.result()));_.point=k,y&&b.lineEnd()},polygonStart:function(){b=x,c=[],u=[],m=!0},polygonEnd:function(){var e=function(){for(var e=0,n=0,i=u.length;nr&&(f-a)*(r-o)>(d-o)*(t-a)&&++e:d<=r&&(f-a)*(r-o)<(d-o)*(t-a)&&--e;return e}(),n=m&&e,i=(c=I(c)).length;(n||i)&&(o.polygonStart(),n&&(o.lineStart(),a(null,null,1,o),o.lineEnd()),i&&yl(c,s,e,a,o),o.polygonEnd());b=o,c=u=l=null}};function k(t,e){i(t,e)&&b.point(t,e)}function w(a,o){var s=i(a,o);if(u&&l.push([a,o]),v)h=a,f=o,d=s,v=!1,s&&(b.lineStart(),b.point(a,o));else if(s&&y)b.point(a,o);else{var c=[p=Math.max(-1e9,Math.min(1e9,p)),g=Math.max(-1e9,Math.min(1e9,g))],x=[a=Math.max(-1e9,Math.min(1e9,a)),o=Math.max(-1e9,Math.min(1e9,o))];!function(t,e,n,r,i,a){var o,s=t[0],c=t[1],u=0,l=1,h=e[0]-s,f=e[1]-c;if(o=n-s,h||!(o>0)){if(o/=h,h<0){if(o0){if(o>l)return;o>u&&(u=o)}if(o=i-s,h||!(o<0)){if(o/=h,h<0){if(o>l)return;o>u&&(u=o)}else if(h>0){if(o0)){if(o/=f,f<0){if(o0){if(o>l)return;o>u&&(u=o)}if(o=a-c,f||!(o<0)){if(o/=f,f<0){if(o>l)return;o>u&&(u=o)}else if(f>0){if(o0&&(t[0]=s+u*h,t[1]=c+u*f),l<1&&(e[0]=s+l*h,e[1]=c+l*f),!0}}}}}(c,x,t,e,n,r)?s&&(b.lineStart(),b.point(a,o),m=!1):(y||(b.lineStart(),b.point(c[0],c[1])),b.point(x[0],x[1]),s||b.lineEnd(),m=!1)}p=a,g=o,y=s}return _}}var Sl,Al,Ml,Ol=function(){var t,e,n,r=0,i=0,a=960,o=500;return n={stream:function(n){return t&&e===n?t:t=Cl(r,i,a,o)(e=n)},extent:function(s){return arguments.length?(r=+s[0][0],i=+s[0][1],a=+s[1][0],o=+s[1][1],t=e=null,n):[[r,i],[a,o]]}}},Dl=sc(),Nl={sphere:Nc,point:Nc,lineStart:function(){Nl.point=Ll,Nl.lineEnd=Bl},lineEnd:Nc,polygonStart:Nc,polygonEnd:Nc};function Bl(){Nl.point=Nl.lineEnd=Nc}function Ll(t,e){Sl=t*=yc,Al=Tc(e*=yc),Ml=xc(e),Nl.point=Fl}function Fl(t,e){t*=yc;var n=Tc(e*=yc),r=xc(e),i=vc(t-Sl),a=xc(i),o=r*Tc(i),s=Ml*n-Al*r*a,c=Al*n+Ml*r*a;Dl.add(bc(Sc(o*o+s*s),c)),Sl=t,Al=n,Ml=r}var Pl=function(t){return Dl.reset(),$c(t,Nl),+Dl},Il=[null,null],jl={type:"LineString",coordinates:Il},Rl=function(t,e){return Il[0]=t,Il[1]=e,Pl(jl)},Yl={Feature:function(t,e){return Ul(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++r0&&(i=Rl(t[a],t[a-1]))>0&&n<=i&&r<=i&&(n+r-i)*(1-Math.pow((n-r)/i,2))<1e-12*i)return!0;n=r}return!1}function Vl(t,e){return!!xl(t.map(Hl),Gl(e))}function Hl(t){return(t=t.map(Gl)).pop(),t}function Gl(t){return[t[0]*yc,t[1]*yc]}var ql=function(t,e){return(t&&Yl.hasOwnProperty(t.type)?Yl[t.type]:Ul)(t,e)};function Xl(t,e,n){var r=k(t,e-1e-6,n).concat(e);return function(t){return r.map((function(e){return[t,e]}))}}function Zl(t,e,n){var r=k(t,e-1e-6,n).concat(e);return function(t){return r.map((function(e){return[e,t]}))}}function Jl(){var t,e,n,r,i,a,o,s,c,u,l,h,f=10,d=f,p=90,g=360,y=2.5;function v(){return{type:"MultiLineString",coordinates:m()}}function m(){return k(_c(r/p)*p,n,p).map(l).concat(k(_c(s/g)*g,o,g).map(h)).concat(k(_c(e/f)*f,t,f).filter((function(t){return vc(t%p)>1e-6})).map(c)).concat(k(_c(a/d)*d,i,d).filter((function(t){return vc(t%g)>1e-6})).map(u))}return v.lines=function(){return m().map((function(t){return{type:"LineString",coordinates:t}}))},v.outline=function(){return{type:"Polygon",coordinates:[l(r).concat(h(o).slice(1),l(n).reverse().slice(1),h(s).reverse().slice(1))]}},v.extent=function(t){return arguments.length?v.extentMajor(t).extentMinor(t):v.extentMinor()},v.extentMajor=function(t){return arguments.length?(r=+t[0][0],n=+t[1][0],s=+t[0][1],o=+t[1][1],r>n&&(t=r,r=n,n=t),s>o&&(t=s,s=o,o=t),v.precision(y)):[[r,s],[n,o]]},v.extentMinor=function(n){return arguments.length?(e=+n[0][0],t=+n[1][0],a=+n[0][1],i=+n[1][1],e>t&&(n=e,e=t,t=n),a>i&&(n=a,a=i,i=n),v.precision(y)):[[e,a],[t,i]]},v.step=function(t){return arguments.length?v.stepMajor(t).stepMinor(t):v.stepMinor()},v.stepMajor=function(t){return arguments.length?(p=+t[0],g=+t[1],v):[p,g]},v.stepMinor=function(t){return arguments.length?(f=+t[0],d=+t[1],v):[f,d]},v.precision=function(f){return arguments.length?(y=+f,c=Xl(a,i,90),u=Zl(e,t,y),l=Xl(s,o,90),h=Zl(r,n,y),v):y},v.extentMajor([[-180,1e-6-90],[180,90-1e-6]]).extentMinor([[-180,-80-1e-6],[180,80+1e-6]])}function Ql(){return Jl()()}var Kl,th,eh,nh,rh=function(t,e){var n=t[0]*yc,r=t[1]*yc,i=e[0]*yc,a=e[1]*yc,o=xc(r),s=Tc(r),c=xc(a),u=Tc(a),l=o*xc(n),h=o*Tc(n),f=c*xc(i),d=c*Tc(i),p=2*Oc(Sc(Dc(a-r)+o*c*Dc(i-n))),g=Tc(p),y=p?function(t){var e=Tc(t*=p)/g,n=Tc(p-t)/g,r=n*l+e*f,i=n*h+e*d,a=n*s+e*u;return[bc(i,r)*gc,bc(a,Sc(r*r+i*i))*gc]}:function(){return[n*gc,r*gc]};return y.distance=p,y},ih=function(t){return t},ah=sc(),oh=sc(),sh={point:Nc,lineStart:Nc,lineEnd:Nc,polygonStart:function(){sh.lineStart=ch,sh.lineEnd=hh},polygonEnd:function(){sh.lineStart=sh.lineEnd=sh.point=Nc,ah.add(vc(oh)),oh.reset()},result:function(){var t=ah/2;return ah.reset(),t}};function ch(){sh.point=uh}function uh(t,e){sh.point=lh,Kl=eh=t,th=nh=e}function lh(t,e){oh.add(nh*t-eh*e),eh=t,nh=e}function hh(){lh(Kl,th)}var fh=sh,dh=1/0,ph=dh,gh=-dh,yh=gh;var vh,mh,bh,xh,_h={point:function(t,e){tgh&&(gh=t);eyh&&(yh=e)},lineStart:Nc,lineEnd:Nc,polygonStart:Nc,polygonEnd:Nc,result:function(){var t=[[dh,ph],[gh,yh]];return gh=yh=-(ph=dh=1/0),t}},kh=0,wh=0,Eh=0,Th=0,Ch=0,Sh=0,Ah=0,Mh=0,Oh=0,Dh={point:Nh,lineStart:Bh,lineEnd:Ph,polygonStart:function(){Dh.lineStart=Ih,Dh.lineEnd=jh},polygonEnd:function(){Dh.point=Nh,Dh.lineStart=Bh,Dh.lineEnd=Ph},result:function(){var t=Oh?[Ah/Oh,Mh/Oh]:Sh?[Th/Sh,Ch/Sh]:Eh?[kh/Eh,wh/Eh]:[NaN,NaN];return kh=wh=Eh=Th=Ch=Sh=Ah=Mh=Oh=0,t}};function Nh(t,e){kh+=t,wh+=e,++Eh}function Bh(){Dh.point=Lh}function Lh(t,e){Dh.point=Fh,Nh(bh=t,xh=e)}function Fh(t,e){var n=t-bh,r=e-xh,i=Sc(n*n+r*r);Th+=i*(bh+t)/2,Ch+=i*(xh+e)/2,Sh+=i,Nh(bh=t,xh=e)}function Ph(){Dh.point=Nh}function Ih(){Dh.point=Rh}function jh(){Yh(vh,mh)}function Rh(t,e){Dh.point=Yh,Nh(vh=bh=t,mh=xh=e)}function Yh(t,e){var n=t-bh,r=e-xh,i=Sc(n*n+r*r);Th+=i*(bh+t)/2,Ch+=i*(xh+e)/2,Sh+=i,Ah+=(i=xh*t-bh*e)*(bh+t),Mh+=i*(xh+e),Oh+=3*i,Nh(bh=t,xh=e)}var zh=Dh;function Uh(t){this._context=t}Uh.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(t,e){switch(this._point){case 0:this._context.moveTo(t,e),this._point=1;break;case 1:this._context.lineTo(t,e);break;default:this._context.moveTo(t+this._radius,e),this._context.arc(t,e,this._radius,0,pc)}},result:Nc};var $h,Wh,Vh,Hh,Gh,qh=sc(),Xh={point:Nc,lineStart:function(){Xh.point=Zh},lineEnd:function(){$h&&Jh(Wh,Vh),Xh.point=Nc},polygonStart:function(){$h=!0},polygonEnd:function(){$h=null},result:function(){var t=+qh;return qh.reset(),t}};function Zh(t,e){Xh.point=Jh,Wh=Hh=t,Vh=Gh=e}function Jh(t,e){Hh-=t,Gh-=e,qh.add(Sc(Hh*Hh+Gh*Gh)),Hh=t,Gh=e}var Qh=Xh;function Kh(){this._string=[]}function tf(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}Kh.prototype={_radius:4.5,_circle:tf(4.5),pointRadius:function(t){return(t=+t)!==this._radius&&(this._radius=t,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._string.push("Z"),this._point=NaN},point:function(t,e){switch(this._point){case 0:this._string.push("M",t,",",e),this._point=1;break;case 1:this._string.push("L",t,",",e);break;default:null==this._circle&&(this._circle=tf(this._radius)),this._string.push("M",t,",",e,this._circle)}},result:function(){if(this._string.length){var t=this._string.join("");return this._string=[],t}return null}};var ef=function(t,e){var n,r,i=4.5;function a(t){return t&&("function"==typeof i&&r.pointRadius(+i.apply(this,arguments)),$c(t,n(r))),r.result()}return a.area=function(t){return $c(t,n(fh)),fh.result()},a.measure=function(t){return $c(t,n(Qh)),Qh.result()},a.bounds=function(t){return $c(t,n(_h)),_h.result()},a.centroid=function(t){return $c(t,n(zh)),zh.result()},a.projection=function(e){return arguments.length?(n=null==e?(t=null,ih):(t=e).stream,a):t},a.context=function(t){return arguments.length?(r=null==t?(e=null,new Kh):new Uh(e=t),"function"!=typeof i&&r.pointRadius(i),a):e},a.pointRadius=function(t){return arguments.length?(i="function"==typeof t?t:(r.pointRadius(+t),+t),a):i},a.projection(t).context(e)},nf=function(t){return{stream:rf(t)}};function rf(t){return function(e){var n=new af;for(var r in t)n[r]=t[r];return n.stream=e,n}}function af(){}function of(t,e,n){var r=t.clipExtent&&t.clipExtent();return t.scale(150).translate([0,0]),null!=r&&t.clipExtent(null),$c(n,t.stream(_h)),e(_h.result()),null!=r&&t.clipExtent(r),t}function sf(t,e,n){return of(t,(function(n){var r=e[1][0]-e[0][0],i=e[1][1]-e[0][1],a=Math.min(r/(n[1][0]-n[0][0]),i/(n[1][1]-n[0][1])),o=+e[0][0]+(r-a*(n[1][0]+n[0][0]))/2,s=+e[0][1]+(i-a*(n[1][1]+n[0][1]))/2;t.scale(150*a).translate([o,s])}),n)}function cf(t,e,n){return sf(t,[[0,0],e],n)}function uf(t,e,n){return of(t,(function(n){var r=+e,i=r/(n[1][0]-n[0][0]),a=(r-i*(n[1][0]+n[0][0]))/2,o=-i*n[0][1];t.scale(150*i).translate([a,o])}),n)}function lf(t,e,n){return of(t,(function(n){var r=+e,i=r/(n[1][1]-n[0][1]),a=-i*n[0][0],o=(r-i*(n[1][1]+n[0][1]))/2;t.scale(150*i).translate([a,o])}),n)}af.prototype={constructor:af,point:function(t,e){this.stream.point(t,e)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var hf=xc(30*yc),ff=function(t,e){return+e?function(t,e){function n(r,i,a,o,s,c,u,l,h,f,d,p,g,y){var v=u-r,m=l-i,b=v*v+m*m;if(b>4*e&&g--){var x=o+f,_=s+d,k=c+p,w=Sc(x*x+_*_+k*k),E=Oc(k/=w),T=vc(vc(k)-1)<1e-6||vc(a-h)<1e-6?(a+h)/2:bc(_,x),C=t(T,E),S=C[0],A=C[1],M=S-r,O=A-i,D=m*M-v*O;(D*D/b>e||vc((v*M+m*O)/b-.5)>.3||o*f+s*d+c*p2?t[2]%360*yc:0,S()):[y*gc,v*gc,m*gc]},T.angle=function(t){return arguments.length?(b=t%360*yc,S()):b*gc},T.precision=function(t){return arguments.length?(o=ff(s,E=t*t),A()):Sc(E)},T.fitExtent=function(t,e){return sf(T,t,e)},T.fitSize=function(t,e){return cf(T,t,e)},T.fitWidth=function(t,e){return uf(T,t,e)},T.fitHeight=function(t,e){return lf(T,t,e)},function(){return e=t.apply(this,arguments),T.invert=e.invert&&C,S()}}function mf(t){var e=0,n=hc/3,r=vf(t),i=r(e,n);return i.parallels=function(t){return arguments.length?r(e=t[0]*yc,n=t[1]*yc):[e*gc,n*gc]},i}function bf(t,e){var n=Tc(t),r=(n+Tc(e))/2;if(vc(r)<1e-6)return function(t){var e=xc(t);function n(t,n){return[t*e,Tc(n)/e]}return n.invert=function(t,n){return[t/e,Oc(n*e)]},n}(t);var i=1+n*(2*r-n),a=Sc(i)/r;function o(t,e){var n=Sc(i-2*r*Tc(e))/r;return[n*Tc(t*=r),a-n*xc(t)]}return o.invert=function(t,e){var n=a-e;return[bc(t,vc(n))/r*Cc(n),Oc((i-(t*t+n*n)*r*r)/(2*r))]},o}var xf=function(){return mf(bf).scale(155.424).center([0,33.6442])},_f=function(){return xf().parallels([29.5,45.5]).scale(1070).translate([480,250]).rotate([96,0]).center([-.6,38.7])};var kf=function(){var t,e,n,r,i,a,o=_f(),s=xf().rotate([154,0]).center([-2,58.5]).parallels([55,65]),c=xf().rotate([157,0]).center([-3,19.9]).parallels([8,18]),u={point:function(t,e){a=[t,e]}};function l(t){var e=t[0],o=t[1];return a=null,n.point(e,o),a||(r.point(e,o),a)||(i.point(e,o),a)}function h(){return t=e=null,l}return l.invert=function(t){var e=o.scale(),n=o.translate(),r=(t[0]-n[0])/e,i=(t[1]-n[1])/e;return(i>=.12&&i<.234&&r>=-.425&&r<-.214?s:i>=.166&&i<.234&&r>=-.214&&r<-.115?c:o).invert(t)},l.stream=function(n){return t&&e===n?t:(r=[o.stream(e=n),s.stream(n),c.stream(n)],i=r.length,t={point:function(t,e){for(var n=-1;++n0?e<1e-6-fc&&(e=1e-6-fc):e>fc-1e-6&&(e=fc-1e-6);var n=i/Ec(Nf(e),r);return[n*Tc(r*t),i-n*xc(r*t)]}return a.invert=function(t,e){var n=i-e,a=Cc(r)*Sc(t*t+n*n);return[bc(t,vc(n))/r*Cc(n),2*mc(Ec(i/a,1/r))-fc]},a}var Lf=function(){return mf(Bf).scale(109.5).parallels([30,30])};function Ff(t,e){return[t,e]}Ff.invert=Ff;var Pf=function(){return yf(Ff).scale(152.63)};function If(t,e){var n=xc(t),r=t===e?Tc(t):(n-xc(e))/(e-t),i=n/r+t;if(vc(r)<1e-6)return Ff;function a(t,e){var n=i-e,a=r*t;return[n*Tc(a),i-n*xc(a)]}return a.invert=function(t,e){var n=i-e;return[bc(t,vc(n))/r*Cc(n),i-Cc(r)*Sc(t*t+n*n)]},a}var jf=function(){return mf(If).scale(131.154).center([0,13.9389])},Rf=1.340264,Yf=-.081106,zf=893e-6,Uf=.003796,$f=Sc(3)/2;function Wf(t,e){var n=Oc($f*Tc(e)),r=n*n,i=r*r*r;return[t*xc(n)/($f*(Rf+3*Yf*r+i*(7*zf+9*Uf*r))),n*(Rf+Yf*r+i*(zf+Uf*r))]}Wf.invert=function(t,e){for(var n,r=e,i=r*r,a=i*i*i,o=0;o<12&&(a=(i=(r-=n=(r*(Rf+Yf*i+a*(zf+Uf*i))-e)/(Rf+3*Yf*i+a*(7*zf+9*Uf*i)))*r)*i*i,!(vc(n)<1e-12));++o);return[$f*t*(Rf+3*Yf*i+a*(7*zf+9*Uf*i))/xc(r),Oc(Tc(r)/$f)]};var Vf=function(){return yf(Wf).scale(177.158)};function Hf(t,e){var n=xc(e),r=xc(t)*n;return[n*Tc(t)/r,Tc(e)/r]}Hf.invert=Ef(mc);var Gf=function(){return yf(Hf).scale(144.049).clipAngle(60)};function qf(t,e,n,r){return 1===t&&1===e&&0===n&&0===r?ih:rf({point:function(i,a){this.stream.point(i*t+n,a*e+r)}})}var Xf=function(){var t,e,n,r,i,a,o=1,s=0,c=0,u=1,l=1,h=ih,f=null,d=ih;function p(){return r=i=null,a}return a={stream:function(t){return r&&i===t?r:r=h(d(i=t))},postclip:function(r){return arguments.length?(d=r,f=t=e=n=null,p()):d},clipExtent:function(r){return arguments.length?(d=null==r?(f=t=e=n=null,ih):Cl(f=+r[0][0],t=+r[0][1],e=+r[1][0],n=+r[1][1]),p()):null==f?null:[[f,t],[e,n]]},scale:function(t){return arguments.length?(h=qf((o=+t)*u,o*l,s,c),p()):o},translate:function(t){return arguments.length?(h=qf(o*u,o*l,s=+t[0],c=+t[1]),p()):[s,c]},reflectX:function(t){return arguments.length?(h=qf(o*(u=t?-1:1),o*l,s,c),p()):u<0},reflectY:function(t){return arguments.length?(h=qf(o*u,o*(l=t?-1:1),s,c),p()):l<0},fitExtent:function(t,e){return sf(a,t,e)},fitSize:function(t,e){return cf(a,t,e)},fitWidth:function(t,e){return uf(a,t,e)},fitHeight:function(t,e){return lf(a,t,e)}}};function Zf(t,e){var n=e*e,r=n*n;return[t*(.8707-.131979*n+r*(r*(.003971*n-.001529*r)-.013791)),e*(1.007226+n*(.015085+r*(.028874*n-.044475-.005916*r)))]}Zf.invert=function(t,e){var n,r=e,i=25;do{var a=r*r,o=a*a;r-=n=(r*(1.007226+a*(.015085+o*(.028874*a-.044475-.005916*o)))-e)/(1.007226+a*(.045255+o*(.259866*a-.311325-.005916*11*o)))}while(vc(n)>1e-6&&--i>0);return[t/(.8707+(a=r*r)*(a*(a*a*a*(.003971-.001529*a)-.013791)-.131979)),r]};var Jf=function(){return yf(Zf).scale(175.295)};function Qf(t,e){return[xc(e)*Tc(t),Tc(e)]}Qf.invert=Ef(Oc);var Kf=function(){return yf(Qf).scale(249.5).clipAngle(90+1e-6)};function td(t,e){var n=xc(e),r=1+xc(t)*n;return[n*Tc(t)/r,Tc(e)/r]}td.invert=Ef((function(t){return 2*mc(t)}));var ed=function(){return yf(td).scale(250).clipAngle(142)};function nd(t,e){return[wc(Ac((fc+e)/2)),-t]}nd.invert=function(t,e){return[-e,2*mc(kc(t))-fc]};var rd=function(){var t=Df(nd),e=t.center,n=t.rotate;return t.center=function(t){return arguments.length?e([-t[1],t[0]]):[(t=e())[1],-t[0]]},t.rotate=function(t){return arguments.length?n([t[0],t[1],t.length>2?t[2]+90:90]):[(t=n())[0],t[1],t[2]-90]},n([0,0,90]).scale(159.155)};function id(t,e){return t.parent===e.parent?1:2}function ad(t,e){return t+e.x}function od(t,e){return Math.max(t,e.y)}var sd=function(){var t=id,e=1,n=1,r=!1;function i(i){var a,o=0;i.eachAfter((function(e){var n=e.children;n?(e.x=function(t){return t.reduce(ad,0)/t.length}(n),e.y=function(t){return 1+t.reduce(od,0)}(n)):(e.x=a?o+=t(e,a):0,e.y=0,a=e)}));var s=function(t){for(var e;e=t.children;)t=e[0];return t}(i),c=function(t){for(var e;e=t.children;)t=e[e.length-1];return t}(i),u=s.x-t(s,c)/2,l=c.x+t(c,s)/2;return i.eachAfter(r?function(t){t.x=(t.x-i.x)*e,t.y=(i.y-t.y)*n}:function(t){t.x=(t.x-u)/(l-u)*e,t.y=(1-(i.y?t.y/i.y:1))*n})}return i.separation=function(e){return arguments.length?(t=e,i):t},i.size=function(t){return arguments.length?(r=!1,e=+t[0],n=+t[1],i):r?null:[e,n]},i.nodeSize=function(t){return arguments.length?(r=!0,e=+t[0],n=+t[1],i):r?[e,n]:null},i};function cd(t){var e=0,n=t.children,r=n&&n.length;if(r)for(;--r>=0;)e+=n[r].value;else e=1;t.value=e}function ud(t,e){var n,r,i,a,o,s=new dd(t),c=+t.value&&(s.value=t.value),u=[s];for(null==e&&(e=ld);n=u.pop();)if(c&&(n.value=+n.data.value),(i=e(n.data))&&(o=i.length))for(n.children=new Array(o),a=o-1;a>=0;--a)u.push(r=n.children[a]=new dd(i[a])),r.parent=n,r.depth=n.depth+1;return s.eachBefore(fd)}function ld(t){return t.children}function hd(t){t.data=t.data.data}function fd(t){var e=0;do{t.height=e}while((t=t.parent)&&t.height<++e)}function dd(t){this.data=t,this.depth=this.height=0,this.parent=null}dd.prototype=ud.prototype={constructor:dd,count:function(){return this.eachAfter(cd)},each:function(t){var e,n,r,i,a=this,o=[a];do{for(e=o.reverse(),o=[];a=e.pop();)if(t(a),n=a.children)for(r=0,i=n.length;r=0;--n)i.push(e[n]);return this},sum:function(t){return this.eachAfter((function(e){for(var n=+t(e.data)||0,r=e.children,i=r&&r.length;--i>=0;)n+=r[i].value;e.value=n}))},sort:function(t){return this.eachBefore((function(e){e.children&&e.children.sort(t)}))},path:function(t){for(var e=this,n=function(t,e){if(t===e)return t;var n=t.ancestors(),r=e.ancestors(),i=null;t=n.pop(),e=r.pop();for(;t===e;)i=t,t=n.pop(),e=r.pop();return i}(e,t),r=[e];e!==n;)e=e.parent,r.push(e);for(var i=r.length;t!==n;)r.splice(i,0,t),t=t.parent;return r},ancestors:function(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e},descendants:function(){var t=[];return this.each((function(e){t.push(e)})),t},leaves:function(){var t=[];return this.eachBefore((function(e){e.children||t.push(e)})),t},links:function(){var t=this,e=[];return t.each((function(n){n!==t&&e.push({source:n.parent,target:n})})),e},copy:function(){return ud(this).eachBefore(hd)}};var pd=Array.prototype.slice;var gd=function(t){for(var e,n,r=0,i=(t=function(t){for(var e,n,r=t.length;r;)n=Math.random()*r--|0,e=t[r],t[r]=t[n],t[n]=e;return t}(pd.call(t))).length,a=[];r0&&n*n>r*r+i*i}function bd(t,e){for(var n=0;n(o*=o)?(r=(u+o-i)/(2*u),a=Math.sqrt(Math.max(0,o/u-r*r)),n.x=t.x-r*s-a*c,n.y=t.y-r*c+a*s):(r=(u+i-o)/(2*u),a=Math.sqrt(Math.max(0,i/u-r*r)),n.x=e.x+r*s-a*c,n.y=e.y+r*c+a*s)):(n.x=e.x+n.r,n.y=e.y)}function Ed(t,e){var n=t.r+e.r-1e-6,r=e.x-t.x,i=e.y-t.y;return n>0&&n*n>r*r+i*i}function Td(t){var e=t._,n=t.next._,r=e.r+n.r,i=(e.x*n.r+n.x*e.r)/r,a=(e.y*n.r+n.y*e.r)/r;return i*i+a*a}function Cd(t){this._=t,this.next=null,this.previous=null}function Sd(t){if(!(i=t.length))return 0;var e,n,r,i,a,o,s,c,u,l,h;if((e=t[0]).x=0,e.y=0,!(i>1))return e.r;if(n=t[1],e.x=-n.r,n.x=e.r,n.y=0,!(i>2))return e.r+n.r;wd(n,e,r=t[2]),e=new Cd(e),n=new Cd(n),r=new Cd(r),e.next=r.previous=n,n.next=e.previous=r,r.next=n.previous=e;t:for(s=3;s0)throw new Error("cycle");return a}return n.id=function(e){return arguments.length?(t=Od(e),n):t},n.parentId=function(t){return arguments.length?(e=Od(t),n):e},n};function Hd(t,e){return t.parent===e.parent?1:2}function Gd(t){var e=t.children;return e?e[0]:t.t}function qd(t){var e=t.children;return e?e[e.length-1]:t.t}function Xd(t,e,n){var r=n/(e.i-t.i);e.c-=r,e.s+=n,t.c+=r,e.z+=n,e.m+=n}function Zd(t,e,n){return t.a.parent===e.parent?t.a:n}function Jd(t,e){this._=t,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=e}Jd.prototype=Object.create(dd.prototype);var Qd=function(){var t=Hd,e=1,n=1,r=null;function i(i){var c=function(t){for(var e,n,r,i,a,o=new Jd(t,0),s=[o];e=s.pop();)if(r=e._.children)for(e.children=new Array(a=r.length),i=a-1;i>=0;--i)s.push(n=e.children[i]=new Jd(r[i],i)),n.parent=e;return(o.parent=new Jd(null,0)).children=[o],o}(i);if(c.eachAfter(a),c.parent.m=-c.z,c.eachBefore(o),r)i.eachBefore(s);else{var u=i,l=i,h=i;i.eachBefore((function(t){t.xl.x&&(l=t),t.depth>h.depth&&(h=t)}));var f=u===l?1:t(u,l)/2,d=f-u.x,p=e/(l.x+f+d),g=n/(h.depth||1);i.eachBefore((function(t){t.x=(t.x+d)*p,t.y=t.depth*g}))}return i}function a(e){var n=e.children,r=e.parent.children,i=e.i?r[e.i-1]:null;if(n){!function(t){for(var e,n=0,r=0,i=t.children,a=i.length;--a>=0;)(e=i[a]).z+=n,e.m+=n,n+=e.s+(r+=e.c)}(e);var a=(n[0].z+n[n.length-1].z)/2;i?(e.z=i.z+t(e._,i._),e.m=e.z-a):e.z=a}else i&&(e.z=i.z+t(e._,i._));e.parent.A=function(e,n,r){if(n){for(var i,a=e,o=e,s=n,c=a.parent.children[0],u=a.m,l=o.m,h=s.m,f=c.m;s=qd(s),a=Gd(a),s&&a;)c=Gd(c),(o=qd(o)).a=e,(i=s.z+h-a.z-u+t(s._,a._))>0&&(Xd(Zd(s,e,r),e,i),u+=i,l+=i),h+=s.m,u+=a.m,f+=c.m,l+=o.m;s&&!qd(o)&&(o.t=s,o.m+=h-l),a&&!Gd(c)&&(c.t=a,c.m+=u-f,r=e)}return r}(e,i,e.parent.A||r[0])}function o(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function s(t){t.x*=e,t.y=t.depth*n}return i.separation=function(e){return arguments.length?(t=e,i):t},i.size=function(t){return arguments.length?(r=!1,e=+t[0],n=+t[1],i):r?null:[e,n]},i.nodeSize=function(t){return arguments.length?(r=!0,e=+t[0],n=+t[1],i):r?[e,n]:null},i},Kd=function(t,e,n,r,i){for(var a,o=t.children,s=-1,c=o.length,u=t.value&&(i-n)/t.value;++sf&&(f=s),y=l*l*g,(d=Math.max(f/y,y/h))>p){l-=s;break}p=d}v.push(o={value:l,dice:c1?e:1)},n}(tp),rp=function(){var t=np,e=!1,n=1,r=1,i=[0],a=Dd,o=Dd,s=Dd,c=Dd,u=Dd;function l(t){return t.x0=t.y0=0,t.x1=n,t.y1=r,t.eachBefore(h),i=[0],e&&t.eachBefore(jd),t}function h(e){var n=i[e.depth],r=e.x0+n,l=e.y0+n,h=e.x1-n,f=e.y1-n;h=n-1){var l=s[e];return l.x0=i,l.y0=a,l.x1=o,void(l.y1=c)}var h=u[e],f=r/2+h,d=e+1,p=n-1;for(;d>>1;u[g]c-a){var m=(i*v+o*y)/r;t(e,d,y,i,a,m,c),t(d,n,v,m,a,o,c)}else{var b=(a*v+c*y)/r;t(e,d,y,i,a,o,b),t(d,n,v,i,b,o,c)}}(0,c,t.value,e,n,r,i)},ap=function(t,e,n,r,i){(1&t.depth?Kd:Rd)(t,e,n,r,i)},op=function t(e){function n(t,n,r,i,a){if((o=t._squarify)&&o.ratio===e)for(var o,s,c,u,l,h=-1,f=o.length,d=t.value;++h1?e:1)},n}(tp),sp=function(t){var e=t.length;return function(n){return t[Math.max(0,Math.min(e-1,Math.floor(n*e)))]}},cp=function(t,e){var n=un(+t,+e);return function(t){var e=n(t);return e-360*Math.floor(e/360)}},up=function(t,e){return t=+t,e=+e,function(n){return Math.round(t*(1-n)+e*n)}},lp=Math.SQRT2;function hp(t){return((t=Math.exp(t))+1/t)/2}var fp=function(t,e){var n,r,i=t[0],a=t[1],o=t[2],s=e[0],c=e[1],u=e[2],l=s-i,h=c-a,f=l*l+h*h;if(f<1e-12)r=Math.log(u/o)/lp,n=function(t){return[i+t*l,a+t*h,o*Math.exp(lp*t*r)]};else{var d=Math.sqrt(f),p=(u*u-o*o+4*f)/(2*o*2*d),g=(u*u-o*o-4*f)/(2*u*2*d),y=Math.log(Math.sqrt(p*p+1)-p),v=Math.log(Math.sqrt(g*g+1)-g);r=(v-y)/lp,n=function(t){var e,n=t*r,s=hp(y),c=o/(2*d)*(s*(e=lp*n+y,((e=Math.exp(2*e))-1)/(e+1))-function(t){return((t=Math.exp(t))-1/t)/2}(y));return[i+c*l,a+c*h,o*s/hp(lp*n+y)]}}return n.duration=1e3*r,n};function dp(t){return function(e,n){var r=t((e=tn(e)).h,(n=tn(n)).h),i=hn(e.s,n.s),a=hn(e.l,n.l),o=hn(e.opacity,n.opacity);return function(t){return e.h=r(t),e.s=i(t),e.l=a(t),e.opacity=o(t),e+""}}}var pp=dp(un),gp=dp(hn);function yp(t,e){var n=hn((t=pa(t)).l,(e=pa(e)).l),r=hn(t.a,e.a),i=hn(t.b,e.b),a=hn(t.opacity,e.opacity);return function(e){return t.l=n(e),t.a=r(e),t.b=i(e),t.opacity=a(e),t+""}}function vp(t){return function(e,n){var r=t((e=ka(e)).h,(n=ka(n)).h),i=hn(e.c,n.c),a=hn(e.l,n.l),o=hn(e.opacity,n.opacity);return function(t){return e.h=r(t),e.c=i(t),e.l=a(t),e.opacity=o(t),e+""}}}var mp=vp(un),bp=vp(hn);function xp(t){return function e(n){function r(e,r){var i=t((e=Oa(e)).h,(r=Oa(r)).h),a=hn(e.s,r.s),o=hn(e.l,r.l),s=hn(e.opacity,r.opacity);return function(t){return e.h=i(t),e.s=a(t),e.l=o(Math.pow(t,n)),e.opacity=s(t),e+""}}return n=+n,r.gamma=e,r}(1)}var _p=xp(un),kp=xp(hn);function wp(t,e){for(var n=0,r=e.length-1,i=e[0],a=new Array(r<0?0:r);n1&&(e=t[a[o-2]],n=t[a[o-1]],r=t[s],(n[0]-e[0])*(r[1]-e[1])-(n[1]-e[1])*(r[0]-e[0])<=0);)--o;a[o++]=s}return a.slice(0,o)}var Mp=function(t){if((n=t.length)<3)return null;var e,n,r=new Array(n),i=new Array(n);for(e=0;e=0;--e)u.push(t[r[a[e]][2]]);for(e=+s;es!=u>s&&o<(c-n)*(s-r)/(u-r)+n&&(l=!l),c=n,u=r;return l},Dp=function(t){for(var e,n,r=-1,i=t.length,a=t[i-1],o=a[0],s=a[1],c=0;++r1);return t+n*a*Math.sqrt(-2*Math.log(i)/i)}}return n.source=t,n}(Np),Fp=function t(e){function n(){var t=Lp.source(e).apply(this,arguments);return function(){return Math.exp(t())}}return n.source=t,n}(Np),Pp=function t(e){function n(t){return function(){for(var n=0,r=0;rr&&(e=n,n=r,r=e),function(t){return Math.max(n,Math.min(r,t))}}function tg(t,e,n){var r=t[0],i=t[1],a=e[0],o=e[1];return i2?eg:tg,i=a=null,h}function h(e){return isNaN(e=+e)?n:(i||(i=r(o.map(t),s,c)))(t(u(e)))}return h.invert=function(n){return u(e((a||(a=r(s,o.map(t),_n)))(n)))},h.domain=function(t){return arguments.length?(o=Up.call(t,Xp),u===Jp||(u=Kp(o)),l()):o.slice()},h.range=function(t){return arguments.length?(s=$p.call(t),l()):s.slice()},h.rangeRound=function(t){return s=$p.call(t),c=up,l()},h.clamp=function(t){return arguments.length?(u=t?Kp(o):Jp,h):u!==Jp},h.interpolate=function(t){return arguments.length?(c=t,l()):c},h.unknown=function(t){return arguments.length?(n=t,h):n},function(n,r){return t=n,e=r,l()}}function ig(t,e){return rg()(t,e)}var ag=function(t,e,n,r){var i,a=A(t,e,n);switch((r=Vs(null==r?",f":r)).type){case"s":var o=Math.max(Math.abs(t),Math.abs(e));return null!=r.precision||isNaN(i=ac(a,o))||(r.precision=i),Zs(r,o);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(i=oc(a,Math.max(Math.abs(t),Math.abs(e))))||(r.precision=i-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(i=ic(a))||(r.precision=i-2*("%"===r.type))}return Xs(r)};function og(t){var e=t.domain;return t.ticks=function(t){var n=e();return C(n[0],n[n.length-1],null==t?10:t)},t.tickFormat=function(t,n){var r=e();return ag(r[0],r[r.length-1],null==t?10:t,n)},t.nice=function(n){null==n&&(n=10);var r,i=e(),a=0,o=i.length-1,s=i[a],c=i[o];return c0?r=S(s=Math.floor(s/r)*r,c=Math.ceil(c/r)*r,n):r<0&&(r=S(s=Math.ceil(s*r)/r,c=Math.floor(c*r)/r,n)),r>0?(i[a]=Math.floor(s/r)*r,i[o]=Math.ceil(c/r)*r,e(i)):r<0&&(i[a]=Math.ceil(s*r)/r,i[o]=Math.floor(c*r)/r,e(i)),t},t}function sg(){var t=ig(Jp,Jp);return t.copy=function(){return ng(t,sg())},Rp.apply(t,arguments),og(t)}function cg(t){var e;function n(t){return isNaN(t=+t)?e:t}return n.invert=n,n.domain=n.range=function(e){return arguments.length?(t=Up.call(e,Xp),n):t.slice()},n.unknown=function(t){return arguments.length?(e=t,n):e},n.copy=function(){return cg(t).unknown(e)},t=arguments.length?Up.call(t,Xp):[0,1],og(n)}var ug=function(t,e){var n,r=0,i=(t=t.slice()).length-1,a=t[r],o=t[i];return o0){for(;fc)break;g.push(h)}}else for(;f=1;--l)if(!((h=u*l)c)break;g.push(h)}}else g=C(f,d,Math.min(d-f,p)).map(n);return r?g.reverse():g},r.tickFormat=function(t,i){if(null==i&&(i=10===a?".0e":","),"function"!=typeof i&&(i=Xs(i)),t===1/0)return i;null==t&&(t=10);var o=Math.max(1,a*t/r.ticks().length);return function(t){var r=t/n(Math.round(e(t)));return r*a0?i[r-1]:e[0],r=r?[i[r-1],n]:[i[o-1],i[o]]},o.unknown=function(e){return arguments.length?(t=e,o):o},o.thresholds=function(){return i.slice()},o.copy=function(){return Mg().domain([e,n]).range(a).unknown(t)},Rp.apply(og(o),arguments)}function Og(){var t,e=[.5],n=[0,1],r=1;function i(i){return i<=i?n[c(e,i,0,r)]:t}return i.domain=function(t){return arguments.length?(e=$p.call(t),r=Math.min(e.length,n.length-1),i):e.slice()},i.range=function(t){return arguments.length?(n=$p.call(t),r=Math.min(e.length,n.length-1),i):n.slice()},i.invertExtent=function(t){var r=n.indexOf(t);return[e[r-1],e[r]]},i.unknown=function(e){return arguments.length?(t=e,i):t},i.copy=function(){return Og().domain(e).range(n).unknown(t)},Rp.apply(i,arguments)}var Dg=new Date,Ng=new Date;function Bg(t,e,n,r){function i(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return i.floor=function(e){return t(e=new Date(+e)),e},i.ceil=function(n){return t(n=new Date(n-1)),e(n,1),t(n),n},i.round=function(t){var e=i(t),n=i.ceil(t);return t-e0))return s;do{s.push(o=new Date(+n)),e(n,a),t(n)}while(o=e)for(;t(e),!n(e);)e.setTime(e-1)}),(function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!n(t););else for(;--r>=0;)for(;e(t,1),!n(t););}))},n&&(i.count=function(e,r){return Dg.setTime(+e),Ng.setTime(+r),t(Dg),t(Ng),Math.floor(n(Dg,Ng))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(e){return r(e)%t==0}:function(e){return i.count(0,e)%t==0}):i:null}),i}var Lg=Bg((function(t){t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,e){t.setFullYear(t.getFullYear()+e)}),(function(t,e){return e.getFullYear()-t.getFullYear()}),(function(t){return t.getFullYear()}));Lg.every=function(t){return isFinite(t=Math.floor(t))&&t>0?Bg((function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,n){e.setFullYear(e.getFullYear()+n*t)})):null};var Fg=Lg,Pg=Lg.range,Ig=Bg((function(t){t.setDate(1),t.setHours(0,0,0,0)}),(function(t,e){t.setMonth(t.getMonth()+e)}),(function(t,e){return e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())}),(function(t){return t.getMonth()})),jg=Ig,Rg=Ig.range;function Yg(t){return Bg((function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+7*e)}),(function(t,e){return(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/6048e5}))}var zg=Yg(0),Ug=Yg(1),$g=Yg(2),Wg=Yg(3),Vg=Yg(4),Hg=Yg(5),Gg=Yg(6),qg=zg.range,Xg=Ug.range,Zg=$g.range,Jg=Wg.range,Qg=Vg.range,Kg=Hg.range,ty=Gg.range,ey=Bg((function(t){t.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+e)}),(function(t,e){return(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/864e5}),(function(t){return t.getDate()-1})),ny=ey,ry=ey.range,iy=Bg((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds()-6e4*t.getMinutes())}),(function(t,e){t.setTime(+t+36e5*e)}),(function(t,e){return(e-t)/36e5}),(function(t){return t.getHours()})),ay=iy,oy=iy.range,sy=Bg((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds())}),(function(t,e){t.setTime(+t+6e4*e)}),(function(t,e){return(e-t)/6e4}),(function(t){return t.getMinutes()})),cy=sy,uy=sy.range,ly=Bg((function(t){t.setTime(t-t.getMilliseconds())}),(function(t,e){t.setTime(+t+1e3*e)}),(function(t,e){return(e-t)/1e3}),(function(t){return t.getUTCSeconds()})),hy=ly,fy=ly.range,dy=Bg((function(){}),(function(t,e){t.setTime(+t+e)}),(function(t,e){return e-t}));dy.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?Bg((function(e){e.setTime(Math.floor(e/t)*t)}),(function(e,n){e.setTime(+e+n*t)}),(function(e,n){return(n-e)/t})):dy:null};var py=dy,gy=dy.range;function yy(t){return Bg((function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+7*e)}),(function(t,e){return(e-t)/6048e5}))}var vy=yy(0),my=yy(1),by=yy(2),xy=yy(3),_y=yy(4),ky=yy(5),wy=yy(6),Ey=vy.range,Ty=my.range,Cy=by.range,Sy=xy.range,Ay=_y.range,My=ky.range,Oy=wy.range,Dy=Bg((function(t){t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+e)}),(function(t,e){return(e-t)/864e5}),(function(t){return t.getUTCDate()-1})),Ny=Dy,By=Dy.range,Ly=Bg((function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)}),(function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()}),(function(t){return t.getUTCFullYear()}));Ly.every=function(t){return isFinite(t=Math.floor(t))&&t>0?Bg((function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,n){e.setUTCFullYear(e.getUTCFullYear()+n*t)})):null};var Fy=Ly,Py=Ly.range;function Iy(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function jy(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function Ry(t,e,n){return{y:t,m:e,d:n,H:0,M:0,S:0,L:0}}function Yy(t){var e=t.dateTime,n=t.date,r=t.time,i=t.periods,a=t.days,o=t.shortDays,s=t.months,c=t.shortMonths,u=Qy(i),l=Ky(i),h=Qy(a),f=Ky(a),d=Qy(o),p=Ky(o),g=Qy(s),y=Ky(s),v=Qy(c),m=Ky(c),b={a:function(t){return o[t.getDay()]},A:function(t){return a[t.getDay()]},b:function(t){return c[t.getMonth()]},B:function(t){return s[t.getMonth()]},c:null,d:xv,e:xv,f:Tv,H:_v,I:kv,j:wv,L:Ev,m:Cv,M:Sv,p:function(t){return i[+(t.getHours()>=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:em,s:nm,S:Av,u:Mv,U:Ov,V:Dv,w:Nv,W:Bv,x:null,X:null,y:Lv,Y:Fv,Z:Pv,"%":tm},x={a:function(t){return o[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return s[t.getUTCMonth()]},c:null,d:Iv,e:Iv,f:Uv,H:jv,I:Rv,j:Yv,L:zv,m:$v,M:Wv,p:function(t){return i[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:em,s:nm,S:Vv,u:Hv,U:Gv,V:qv,w:Xv,W:Zv,x:null,X:null,y:Jv,Y:Qv,Z:Kv,"%":tm},_={a:function(t,e,n){var r=d.exec(e.slice(n));return r?(t.w=p[r[0].toLowerCase()],n+r[0].length):-1},A:function(t,e,n){var r=h.exec(e.slice(n));return r?(t.w=f[r[0].toLowerCase()],n+r[0].length):-1},b:function(t,e,n){var r=v.exec(e.slice(n));return r?(t.m=m[r[0].toLowerCase()],n+r[0].length):-1},B:function(t,e,n){var r=g.exec(e.slice(n));return r?(t.m=y[r[0].toLowerCase()],n+r[0].length):-1},c:function(t,n,r){return E(t,e,n,r)},d:lv,e:lv,f:yv,H:fv,I:fv,j:hv,L:gv,m:uv,M:dv,p:function(t,e,n){var r=u.exec(e.slice(n));return r?(t.p=l[r[0].toLowerCase()],n+r[0].length):-1},q:cv,Q:mv,s:bv,S:pv,u:ev,U:nv,V:rv,w:tv,W:iv,x:function(t,e,r){return E(t,n,e,r)},X:function(t,e,n){return E(t,r,e,n)},y:ov,Y:av,Z:sv,"%":vv};function k(t,e){return function(n){var r,i,a,o=[],s=-1,c=0,u=t.length;for(n instanceof Date||(n=new Date(+n));++s53)return null;"w"in a||(a.w=1),"Z"in a?(i=(r=jy(Ry(a.y,0,1))).getUTCDay(),r=i>4||0===i?my.ceil(r):my(r),r=Ny.offset(r,7*(a.V-1)),a.y=r.getUTCFullYear(),a.m=r.getUTCMonth(),a.d=r.getUTCDate()+(a.w+6)%7):(i=(r=Iy(Ry(a.y,0,1))).getDay(),r=i>4||0===i?Ug.ceil(r):Ug(r),r=ny.offset(r,7*(a.V-1)),a.y=r.getFullYear(),a.m=r.getMonth(),a.d=r.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),i="Z"in a?jy(Ry(a.y,0,1)).getUTCDay():Iy(Ry(a.y,0,1)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,jy(a)):Iy(a)}}function E(t,e,n,r){for(var i,a,o=0,s=e.length,c=n.length;o=c)return-1;if(37===(i=e.charCodeAt(o++))){if(i=e.charAt(o++),!(a=_[i in Hy?e.charAt(o++):i])||(r=a(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return(b.x=k(n,b),b.X=k(r,b),b.c=k(e,b),x.x=k(n,x),x.X=k(r,x),x.c=k(e,x),{format:function(t){var e=k(t+="",b);return e.toString=function(){return t},e},parse:function(t){var e=w(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=k(t+="",x);return e.toString=function(){return t},e},utcParse:function(t){var e=w(t+="",!0);return e.toString=function(){return t},e}})}var zy,Uy,$y,Wy,Vy,Hy={"-":"",_:" ",0:"0"},Gy=/^\s*\d+/,qy=/^%/,Xy=/[\\^$*+?|[\]().{}]/g;function Zy(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",a=i.length;return r+(a68?1900:2e3),n+r[0].length):-1}function sv(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function cv(t,e,n){var r=Gy.exec(e.slice(n,n+1));return r?(t.q=3*r[0]-3,n+r[0].length):-1}function uv(t,e,n){var r=Gy.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function lv(t,e,n){var r=Gy.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function hv(t,e,n){var r=Gy.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function fv(t,e,n){var r=Gy.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function dv(t,e,n){var r=Gy.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function pv(t,e,n){var r=Gy.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function gv(t,e,n){var r=Gy.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function yv(t,e,n){var r=Gy.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function vv(t,e,n){var r=qy.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function mv(t,e,n){var r=Gy.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function bv(t,e,n){var r=Gy.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function xv(t,e){return Zy(t.getDate(),e,2)}function _v(t,e){return Zy(t.getHours(),e,2)}function kv(t,e){return Zy(t.getHours()%12||12,e,2)}function wv(t,e){return Zy(1+ny.count(Fg(t),t),e,3)}function Ev(t,e){return Zy(t.getMilliseconds(),e,3)}function Tv(t,e){return Ev(t,e)+"000"}function Cv(t,e){return Zy(t.getMonth()+1,e,2)}function Sv(t,e){return Zy(t.getMinutes(),e,2)}function Av(t,e){return Zy(t.getSeconds(),e,2)}function Mv(t){var e=t.getDay();return 0===e?7:e}function Ov(t,e){return Zy(zg.count(Fg(t)-1,t),e,2)}function Dv(t,e){var n=t.getDay();return t=n>=4||0===n?Vg(t):Vg.ceil(t),Zy(Vg.count(Fg(t),t)+(4===Fg(t).getDay()),e,2)}function Nv(t){return t.getDay()}function Bv(t,e){return Zy(Ug.count(Fg(t)-1,t),e,2)}function Lv(t,e){return Zy(t.getFullYear()%100,e,2)}function Fv(t,e){return Zy(t.getFullYear()%1e4,e,4)}function Pv(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Zy(e/60|0,"0",2)+Zy(e%60,"0",2)}function Iv(t,e){return Zy(t.getUTCDate(),e,2)}function jv(t,e){return Zy(t.getUTCHours(),e,2)}function Rv(t,e){return Zy(t.getUTCHours()%12||12,e,2)}function Yv(t,e){return Zy(1+Ny.count(Fy(t),t),e,3)}function zv(t,e){return Zy(t.getUTCMilliseconds(),e,3)}function Uv(t,e){return zv(t,e)+"000"}function $v(t,e){return Zy(t.getUTCMonth()+1,e,2)}function Wv(t,e){return Zy(t.getUTCMinutes(),e,2)}function Vv(t,e){return Zy(t.getUTCSeconds(),e,2)}function Hv(t){var e=t.getUTCDay();return 0===e?7:e}function Gv(t,e){return Zy(vy.count(Fy(t)-1,t),e,2)}function qv(t,e){var n=t.getUTCDay();return t=n>=4||0===n?_y(t):_y.ceil(t),Zy(_y.count(Fy(t),t)+(4===Fy(t).getUTCDay()),e,2)}function Xv(t){return t.getUTCDay()}function Zv(t,e){return Zy(my.count(Fy(t)-1,t),e,2)}function Jv(t,e){return Zy(t.getUTCFullYear()%100,e,2)}function Qv(t,e){return Zy(t.getUTCFullYear()%1e4,e,4)}function Kv(){return"+0000"}function tm(){return"%"}function em(t){return+t}function nm(t){return Math.floor(+t/1e3)}function rm(t){return zy=Yy(t),Uy=zy.format,$y=zy.parse,Wy=zy.utcFormat,Vy=zy.utcParse,zy}rm({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});function im(t){return new Date(t)}function am(t){return t instanceof Date?+t:+new Date(+t)}function om(t,e,n,r,a,o,s,c,u){var l=ig(Jp,Jp),h=l.invert,f=l.domain,d=u(".%L"),p=u(":%S"),g=u("%I:%M"),y=u("%I %p"),v=u("%a %d"),m=u("%b %d"),b=u("%B"),x=u("%Y"),_=[[s,1,1e3],[s,5,5e3],[s,15,15e3],[s,30,3e4],[o,1,6e4],[o,5,3e5],[o,15,9e5],[o,30,18e5],[a,1,36e5],[a,3,108e5],[a,6,216e5],[a,12,432e5],[r,1,864e5],[r,2,1728e5],[n,1,6048e5],[e,1,2592e6],[e,3,7776e6],[t,1,31536e6]];function k(i){return(s(i)1)&&(t-=Math.floor(t));var e=Math.abs(t-.5);return qb.h=360*t-100,qb.s=1.5-1.5*e,qb.l=.8-.9*e,qb+""},Zb=Ge(),Jb=Math.PI/3,Qb=2*Math.PI/3,Kb=function(t){var e;return t=(.5-t)*Math.PI,Zb.r=255*(e=Math.sin(t))*e,Zb.g=255*(e=Math.sin(t+Jb))*e,Zb.b=255*(e=Math.sin(t+Qb))*e,Zb+""},tx=function(t){return t=Math.max(0,Math.min(1,t)),"rgb("+Math.max(0,Math.min(255,Math.round(34.61+t*(1172.33-t*(10793.56-t*(33300.12-t*(38394.49-14825.05*t)))))))+", "+Math.max(0,Math.min(255,Math.round(23.31+t*(557.33+t*(1225.33-t*(3574.96-t*(1073.77+707.56*t)))))))+", "+Math.max(0,Math.min(255,Math.round(27.2+t*(3211.1-t*(15327.97-t*(27814-t*(22569.18-6838.66*t)))))))+")"};function ex(t){var e=t.length;return function(n){return t[Math.max(0,Math.min(e-1,Math.floor(n*e)))]}}var nx=ex(Nm("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")),rx=ex(Nm("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),ix=ex(Nm("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),ax=ex(Nm("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),ox=function(t){return ke(ne(t).call(document.documentElement))},sx=0;function cx(){return new ux}function ux(){this._="@"+(++sx).toString(36)}ux.prototype=cx.prototype={constructor:ux,get:function(t){for(var e=this._;!(e in t);)if(!(t=t.parentNode))return;return t[e]},set:function(t,e){return t[this._]=e},remove:function(t){return this._ in t&&delete t[this._]},toString:function(){return this._}};var lx=function(t){return"string"==typeof t?new be([document.querySelectorAll(t)],[document.documentElement]):new be([null==t?[]:t],me)},hx=function(t,e){null==e&&(e=Mn().touches);for(var n=0,r=e?e.length:0,i=new Array(r);n1?0:t<-1?xx:Math.acos(t)}function Ex(t){return t>=1?_x:t<=-1?-_x:Math.asin(t)}function Tx(t){return t.innerRadius}function Cx(t){return t.outerRadius}function Sx(t){return t.startAngle}function Ax(t){return t.endAngle}function Mx(t){return t&&t.padAngle}function Ox(t,e,n,r,i,a,o,s){var c=n-t,u=r-e,l=o-i,h=s-a,f=h*c-l*u;if(!(f*f<1e-12))return[t+(f=(l*(e-a)-h*(t-i))/f)*c,e+f*u]}function Dx(t,e,n,r,i,a,o){var s=t-n,c=e-r,u=(o?a:-a)/bx(s*s+c*c),l=u*c,h=-u*s,f=t+l,d=e+h,p=n+l,g=r+h,y=(f+p)/2,v=(d+g)/2,m=p-f,b=g-d,x=m*m+b*b,_=i-a,k=f*g-p*d,w=(b<0?-1:1)*bx(yx(0,_*_*x-k*k)),E=(k*b-m*w)/x,T=(-k*m-b*w)/x,C=(k*b+m*w)/x,S=(-k*m+b*w)/x,A=E-y,M=T-v,O=C-y,D=S-v;return A*A+M*M>O*O+D*D&&(E=C,T=S),{cx:E,cy:T,x01:-l,y01:-h,x11:E*(i/_-1),y11:T*(i/_-1)}}var Nx=function(){var t=Tx,e=Cx,n=fx(0),r=null,i=Sx,a=Ax,o=Mx,s=null;function c(){var c,u,l=+t.apply(this,arguments),h=+e.apply(this,arguments),f=i.apply(this,arguments)-_x,d=a.apply(this,arguments)-_x,p=dx(d-f),g=d>f;if(s||(s=c=Ui()),h1e-12)if(p>kx-1e-12)s.moveTo(h*gx(f),h*mx(f)),s.arc(0,0,h,f,d,!g),l>1e-12&&(s.moveTo(l*gx(d),l*mx(d)),s.arc(0,0,l,d,f,g));else{var y,v,m=f,b=d,x=f,_=d,k=p,w=p,E=o.apply(this,arguments)/2,T=E>1e-12&&(r?+r.apply(this,arguments):bx(l*l+h*h)),C=vx(dx(h-l)/2,+n.apply(this,arguments)),S=C,A=C;if(T>1e-12){var M=Ex(T/l*mx(E)),O=Ex(T/h*mx(E));(k-=2*M)>1e-12?(x+=M*=g?1:-1,_-=M):(k=0,x=_=(f+d)/2),(w-=2*O)>1e-12?(m+=O*=g?1:-1,b-=O):(w=0,m=b=(f+d)/2)}var D=h*gx(m),N=h*mx(m),B=l*gx(_),L=l*mx(_);if(C>1e-12){var F,P=h*gx(b),I=h*mx(b),j=l*gx(x),R=l*mx(x);if(p1e-12?A>1e-12?(y=Dx(j,R,D,N,h,A,g),v=Dx(P,I,B,L,h,A,g),s.moveTo(y.cx+y.x01,y.cy+y.y01),A1e-12&&k>1e-12?S>1e-12?(y=Dx(B,L,P,I,l,-S,g),v=Dx(D,N,j,R,l,-S,g),s.lineTo(y.cx+y.x01,y.cy+y.y01),S=l;--h)s.point(y[h],v[h]);s.lineEnd(),s.areaEnd()}g&&(y[u]=+t(f,u,c),v[u]=+n(f,u,c),s.point(e?+e(f,u,c):y[u],r?+r(f,u,c):v[u]))}if(d)return s=null,d+""||null}function u(){return Ix().defined(i).curve(o).context(a)}return c.x=function(n){return arguments.length?(t="function"==typeof n?n:fx(+n),e=null,c):t},c.x0=function(e){return arguments.length?(t="function"==typeof e?e:fx(+e),c):t},c.x1=function(t){return arguments.length?(e=null==t?null:"function"==typeof t?t:fx(+t),c):e},c.y=function(t){return arguments.length?(n="function"==typeof t?t:fx(+t),r=null,c):n},c.y0=function(t){return arguments.length?(n="function"==typeof t?t:fx(+t),c):n},c.y1=function(t){return arguments.length?(r=null==t?null:"function"==typeof t?t:fx(+t),c):r},c.lineX0=c.lineY0=function(){return u().x(t).y(n)},c.lineY1=function(){return u().x(t).y(r)},c.lineX1=function(){return u().x(e).y(n)},c.defined=function(t){return arguments.length?(i="function"==typeof t?t:fx(!!t),c):i},c.curve=function(t){return arguments.length?(o=t,null!=a&&(s=o(a)),c):o},c.context=function(t){return arguments.length?(null==t?a=s=null:s=o(a=t),c):a},c},Rx=function(t,e){return et?1:e>=t?0:NaN},Yx=function(t){return t},zx=function(){var t=Yx,e=Rx,n=null,r=fx(0),i=fx(kx),a=fx(0);function o(o){var s,c,u,l,h,f=o.length,d=0,p=new Array(f),g=new Array(f),y=+r.apply(this,arguments),v=Math.min(kx,Math.max(-kx,i.apply(this,arguments)-y)),m=Math.min(Math.abs(v)/f,a.apply(this,arguments)),b=m*(v<0?-1:1);for(s=0;s0&&(d+=h);for(null!=e?p.sort((function(t,n){return e(g[t],g[n])})):null!=n&&p.sort((function(t,e){return n(o[t],o[e])})),s=0,u=d?(v-f*b)/d:0;s0?h*u:0)+b,g[c]={data:o[c],index:s,value:h,startAngle:y,endAngle:l,padAngle:m};return g}return o.value=function(e){return arguments.length?(t="function"==typeof e?e:fx(+e),o):t},o.sortValues=function(t){return arguments.length?(e=t,n=null,o):e},o.sort=function(t){return arguments.length?(n=t,e=null,o):n},o.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:fx(+t),o):r},o.endAngle=function(t){return arguments.length?(i="function"==typeof t?t:fx(+t),o):i},o.padAngle=function(t){return arguments.length?(a="function"==typeof t?t:fx(+t),o):a},o},Ux=Wx(Lx);function $x(t){this._curve=t}function Wx(t){function e(e){return new $x(t(e))}return e._curve=t,e}function Vx(t){var e=t.curve;return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t.curve=function(t){return arguments.length?e(Wx(t)):e()._curve},t}$x.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(t,e){this._curve.point(e*Math.sin(t),e*-Math.cos(t))}};var Hx=function(){return Vx(Ix().curve(Ux))},Gx=function(){var t=jx().curve(Ux),e=t.curve,n=t.lineX0,r=t.lineX1,i=t.lineY0,a=t.lineY1;return t.angle=t.x,delete t.x,t.startAngle=t.x0,delete t.x0,t.endAngle=t.x1,delete t.x1,t.radius=t.y,delete t.y,t.innerRadius=t.y0,delete t.y0,t.outerRadius=t.y1,delete t.y1,t.lineStartAngle=function(){return Vx(n())},delete t.lineX0,t.lineEndAngle=function(){return Vx(r())},delete t.lineX1,t.lineInnerRadius=function(){return Vx(i())},delete t.lineY0,t.lineOuterRadius=function(){return Vx(a())},delete t.lineY1,t.curve=function(t){return arguments.length?e(Wx(t)):e()._curve},t},qx=function(t,e){return[(e=+e)*Math.cos(t-=Math.PI/2),e*Math.sin(t)]},Xx=Array.prototype.slice;function Zx(t){return t.source}function Jx(t){return t.target}function Qx(t){var e=Zx,n=Jx,r=Fx,i=Px,a=null;function o(){var o,s=Xx.call(arguments),c=e.apply(this,s),u=n.apply(this,s);if(a||(a=o=Ui()),t(a,+r.apply(this,(s[0]=c,s)),+i.apply(this,s),+r.apply(this,(s[0]=u,s)),+i.apply(this,s)),o)return a=null,o+""||null}return o.source=function(t){return arguments.length?(e=t,o):e},o.target=function(t){return arguments.length?(n=t,o):n},o.x=function(t){return arguments.length?(r="function"==typeof t?t:fx(+t),o):r},o.y=function(t){return arguments.length?(i="function"==typeof t?t:fx(+t),o):i},o.context=function(t){return arguments.length?(a=null==t?null:t,o):a},o}function Kx(t,e,n,r,i){t.moveTo(e,n),t.bezierCurveTo(e=(e+r)/2,n,e,i,r,i)}function t_(t,e,n,r,i){t.moveTo(e,n),t.bezierCurveTo(e,n=(n+i)/2,r,n,r,i)}function e_(t,e,n,r,i){var a=qx(e,n),o=qx(e,n=(n+i)/2),s=qx(r,n),c=qx(r,i);t.moveTo(a[0],a[1]),t.bezierCurveTo(o[0],o[1],s[0],s[1],c[0],c[1])}function n_(){return Qx(Kx)}function r_(){return Qx(t_)}function i_(){var t=Qx(e_);return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t}var a_={draw:function(t,e){var n=Math.sqrt(e/xx);t.moveTo(n,0),t.arc(0,0,n,0,kx)}},o_={draw:function(t,e){var n=Math.sqrt(e/5)/2;t.moveTo(-3*n,-n),t.lineTo(-n,-n),t.lineTo(-n,-3*n),t.lineTo(n,-3*n),t.lineTo(n,-n),t.lineTo(3*n,-n),t.lineTo(3*n,n),t.lineTo(n,n),t.lineTo(n,3*n),t.lineTo(-n,3*n),t.lineTo(-n,n),t.lineTo(-3*n,n),t.closePath()}},s_=Math.sqrt(1/3),c_=2*s_,u_={draw:function(t,e){var n=Math.sqrt(e/c_),r=n*s_;t.moveTo(0,-n),t.lineTo(r,0),t.lineTo(0,n),t.lineTo(-r,0),t.closePath()}},l_=Math.sin(xx/10)/Math.sin(7*xx/10),h_=Math.sin(kx/10)*l_,f_=-Math.cos(kx/10)*l_,d_={draw:function(t,e){var n=Math.sqrt(.8908130915292852*e),r=h_*n,i=f_*n;t.moveTo(0,-n),t.lineTo(r,i);for(var a=1;a<5;++a){var o=kx*a/5,s=Math.cos(o),c=Math.sin(o);t.lineTo(c*n,-s*n),t.lineTo(s*r-c*i,c*r+s*i)}t.closePath()}},p_={draw:function(t,e){var n=Math.sqrt(e),r=-n/2;t.rect(r,r,n,n)}},g_=Math.sqrt(3),y_={draw:function(t,e){var n=-Math.sqrt(e/(3*g_));t.moveTo(0,2*n),t.lineTo(-g_*n,-n),t.lineTo(g_*n,-n),t.closePath()}},v_=Math.sqrt(3)/2,m_=1/Math.sqrt(12),b_=3*(m_/2+1),x_={draw:function(t,e){var n=Math.sqrt(e/b_),r=n/2,i=n*m_,a=r,o=n*m_+n,s=-a,c=o;t.moveTo(r,i),t.lineTo(a,o),t.lineTo(s,c),t.lineTo(-.5*r-v_*i,v_*r+-.5*i),t.lineTo(-.5*a-v_*o,v_*a+-.5*o),t.lineTo(-.5*s-v_*c,v_*s+-.5*c),t.lineTo(-.5*r+v_*i,-.5*i-v_*r),t.lineTo(-.5*a+v_*o,-.5*o-v_*a),t.lineTo(-.5*s+v_*c,-.5*c-v_*s),t.closePath()}},__=[a_,o_,u_,p_,d_,y_,x_],k_=function(){var t=fx(a_),e=fx(64),n=null;function r(){var r;if(n||(n=r=Ui()),t.apply(this,arguments).draw(n,+e.apply(this,arguments)),r)return n=null,r+""||null}return r.type=function(e){return arguments.length?(t="function"==typeof e?e:fx(e),r):t},r.size=function(t){return arguments.length?(e="function"==typeof t?t:fx(+t),r):e},r.context=function(t){return arguments.length?(n=null==t?null:t,r):n},r},w_=function(){};function E_(t,e,n){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+n)/6)}function T_(t){this._context=t}T_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:E_(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:E_(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};var C_=function(t){return new T_(t)};function S_(t){this._context=t}S_.prototype={areaStart:w_,areaEnd:w_,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:E_(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};var A_=function(t){return new S_(t)};function M_(t){this._context=t}M_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:E_(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};var O_=function(t){return new M_(t)};function D_(t,e){this._basis=new T_(t),this._beta=e}D_.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,n=t.length-1;if(n>0)for(var r,i=t[0],a=e[0],o=t[n]-i,s=e[n]-a,c=-1;++c<=n;)r=c/n,this._basis.point(this._beta*t[c]+(1-this._beta)*(i+r*o),this._beta*e[c]+(1-this._beta)*(a+r*s));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};var N_=function t(e){function n(t){return 1===e?new T_(t):new D_(t,e)}return n.beta=function(e){return t(+e)},n}(.85);function B_(t,e,n){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-n),t._x2,t._y2)}function L_(t,e){this._context=t,this._k=(1-e)/6}L_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:B_(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:B_(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var F_=function t(e){function n(t){return new L_(t,e)}return n.tension=function(e){return t(+e)},n}(0);function P_(t,e){this._context=t,this._k=(1-e)/6}P_.prototype={areaStart:w_,areaEnd:w_,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:B_(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var I_=function t(e){function n(t){return new P_(t,e)}return n.tension=function(e){return t(+e)},n}(0);function j_(t,e){this._context=t,this._k=(1-e)/6}j_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:B_(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var R_=function t(e){function n(t){return new j_(t,e)}return n.tension=function(e){return t(+e)},n}(0);function Y_(t,e,n){var r=t._x1,i=t._y1,a=t._x2,o=t._y2;if(t._l01_a>1e-12){var s=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,c=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*s-t._x0*t._l12_2a+t._x2*t._l01_2a)/c,i=(i*s-t._y0*t._l12_2a+t._y2*t._l01_2a)/c}if(t._l23_a>1e-12){var u=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,l=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*u+t._x1*t._l23_2a-e*t._l12_2a)/l,o=(o*u+t._y1*t._l23_2a-n*t._l12_2a)/l}t._context.bezierCurveTo(r,i,a,o,t._x2,t._y2)}function z_(t,e){this._context=t,this._alpha=e}z_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Y_(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var U_=function t(e){function n(t){return e?new z_(t,e):new L_(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function $_(t,e){this._context=t,this._alpha=e}$_.prototype={areaStart:w_,areaEnd:w_,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Y_(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var W_=function t(e){function n(t){return e?new $_(t,e):new P_(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function V_(t,e){this._context=t,this._alpha=e}V_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Y_(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var H_=function t(e){function n(t){return e?new V_(t,e):new j_(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function G_(t){this._context=t}G_.prototype={areaStart:w_,areaEnd:w_,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}};var q_=function(t){return new G_(t)};function X_(t){return t<0?-1:1}function Z_(t,e,n){var r=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(r||i<0&&-0),o=(n-t._y1)/(i||r<0&&-0),s=(a*i+o*r)/(r+i);return(X_(a)+X_(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(s))||0}function J_(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e}function Q_(t,e,n){var r=t._x0,i=t._y0,a=t._x1,o=t._y1,s=(a-r)/3;t._context.bezierCurveTo(r+s,i+s*e,a-s,o-s*n,a,o)}function K_(t){this._context=t}function tk(t){this._context=new ek(t)}function ek(t){this._context=t}function nk(t){return new K_(t)}function rk(t){return new tk(t)}function ik(t){this._context=t}function ak(t){var e,n,r=t.length-1,i=new Array(r),a=new Array(r),o=new Array(r);for(i[0]=0,a[0]=2,o[0]=t[0]+2*t[1],e=1;e=0;--e)i[e]=(o[e]-i[e+1])/a[e];for(a[r-1]=(t[r]+i[r-1])/2,e=0;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var n=this._x*(1-this._t)+t*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,e)}}this._x=t,this._y=e}};var ck=function(t){return new sk(t,.5)};function uk(t){return new sk(t,0)}function lk(t){return new sk(t,1)}var hk=function(t,e){if((i=t.length)>1)for(var n,r,i,a=1,o=t[e[0]],s=o.length;a=0;)n[e]=e;return n};function dk(t,e){return t[e]}var pk=function(){var t=fx([]),e=fk,n=hk,r=dk;function i(i){var a,o,s=t.apply(this,arguments),c=i.length,u=s.length,l=new Array(u);for(a=0;a0){for(var n,r,i,a=0,o=t[0].length;a0)for(var n,r,i,a,o,s,c=0,u=t[e[0]].length;c0?(r[0]=a,r[1]=a+=i):i<0?(r[1]=o,r[0]=o+=i):(r[0]=0,r[1]=i)},vk=function(t,e){if((n=t.length)>0){for(var n,r=0,i=t[e[0]],a=i.length;r0&&(r=(n=t[e[0]]).length)>0){for(var n,r,i,a=0,o=1;oa&&(a=e,r=n);return r}var _k=function(t){var e=t.map(kk);return fk(t).sort((function(t,n){return e[t]-e[n]}))};function kk(t){for(var e,n=0,r=-1,i=t.length;++r0)){if(a/=f,f<0){if(a0){if(a>h)return;a>l&&(l=a)}if(a=r-c,f||!(a<0)){if(a/=f,f<0){if(a>h)return;a>l&&(l=a)}else if(f>0){if(a0)){if(a/=d,d<0){if(a0){if(a>h)return;a>l&&(l=a)}if(a=i-u,d||!(a<0)){if(a/=d,d<0){if(a>h)return;a>l&&(l=a)}else if(d>0){if(a0||h<1)||(l>0&&(t[0]=[c+l*f,u+l*d]),h<1&&(t[1]=[c+h*f,u+h*d]),!0)}}}}}function Uk(t,e,n,r,i){var a=t[1];if(a)return!0;var o,s,c=t[0],u=t.left,l=t.right,h=u[0],f=u[1],d=l[0],p=l[1],g=(h+d)/2,y=(f+p)/2;if(p===f){if(g=r)return;if(h>d){if(c){if(c[1]>=i)return}else c=[g,n];a=[g,i]}else{if(c){if(c[1]1)if(h>d){if(c){if(c[1]>=i)return}else c=[(n-s)/o,n];a=[(i-s)/o,i]}else{if(c){if(c[1]=r)return}else c=[e,o*e+s];a=[r,o*r+s]}else{if(c){if(c[0]=-lw)){var d=c*c+u*u,p=l*l+h*h,g=(h*d-u*p)/f,y=(c*p-l*d)/f,v=Gk.pop()||new qk;v.arc=t,v.site=i,v.x=g+o,v.y=(v.cy=y+s)+Math.sqrt(g*g+y*y),t.circle=v;for(var m=null,b=sw._;b;)if(v.yuw)s=s.L;else{if(!((i=a-iw(s,o))>uw)){r>-uw?(e=s.P,n=s):i>-uw?(e=s,n=s.N):e=n=s;break}if(!s.R){e=s;break}s=s.R}!function(t){ow[t.index]={site:t,halfedges:[]}}(t);var c=Kk(t);if(aw.insert(e,c),e||n){if(e===n)return Zk(e),n=Kk(e.site),aw.insert(c,n),c.edge=n.edge=jk(e.site,c.site),Xk(e),void Xk(n);if(n){Zk(e),Zk(n);var u=e.site,l=u[0],h=u[1],f=t[0]-l,d=t[1]-h,p=n.site,g=p[0]-l,y=p[1]-h,v=2*(f*y-d*g),m=f*f+d*d,b=g*g+y*y,x=[(y*m-d*b)/v+l,(f*b-g*m)/v+h];Yk(n.edge,u,p,x),c.edge=jk(u,t,null,x),n.edge=jk(t,p,null,x),Xk(e),Xk(n)}else c.edge=jk(e.site,c.site)}}function rw(t,e){var n=t.site,r=n[0],i=n[1],a=i-e;if(!a)return r;var o=t.P;if(!o)return-1/0;var s=(n=o.site)[0],c=n[1],u=c-e;if(!u)return s;var l=s-r,h=1/a-1/u,f=l/u;return h?(-f+Math.sqrt(f*f-2*h*(l*l/(-2*u)-c+u/2+i-a/2)))/h+r:(r+s)/2}function iw(t,e){var n=t.N;if(n)return rw(n,e);var r=t.site;return r[1]===e?r[0]:1/0}var aw,ow,sw,cw,uw=1e-6,lw=1e-12;function hw(t,e){return e[1]-t[1]||e[0]-t[0]}function fw(t,e){var n,r,i,a=t.sort(hw).pop();for(cw=[],ow=new Array(t.length),aw=new Ik,sw=new Ik;;)if(i=Hk,a&&(!i||a[1]uw||Math.abs(i[0][1]-i[1][1])>uw)||delete cw[a]}(o,s,c,u),function(t,e,n,r){var i,a,o,s,c,u,l,h,f,d,p,g,y=ow.length,v=!0;for(i=0;iuw||Math.abs(g-f)>uw)&&(c.splice(s,0,cw.push(Rk(o,d,Math.abs(p-t)uw?[t,Math.abs(h-t)uw?[Math.abs(f-r)uw?[n,Math.abs(h-n)uw?[Math.abs(f-e)=s)return null;var c=t-i.site[0],u=e-i.site[1],l=c*c+u*u;do{i=a.cells[r=o],o=null,i.halfedges.forEach((function(n){var r=a.edges[n],s=r.left;if(s!==i.site&&s||(s=r.right)){var c=t-s[0],u=e-s[1],h=c*c+u*u;hr?(r+i)/2:Math.min(0,r)||Math.max(0,i),o>a?(a+o)/2:Math.min(0,a)||Math.max(0,o))}var Sw=function(){var t,e,n=_w,r=kw,i=Cw,a=Ew,o=Tw,s=[0,1/0],c=[[-1/0,-1/0],[1/0,1/0]],u=250,l=fp,h=lt("start","zoom","end"),f=0;function d(t){t.property("__zoom",ww).on("wheel.zoom",x).on("mousedown.zoom",_).on("dblclick.zoom",k).filter(o).on("touchstart.zoom",w).on("touchmove.zoom",E).on("touchend.zoom touchcancel.zoom",T).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function p(t,e){return(e=Math.max(s[0],Math.min(s[1],e)))===t.k?t:new yw(e,t.x,t.y)}function g(t,e,n){var r=e[0]-n[0]*t.k,i=e[1]-n[1]*t.k;return r===t.x&&i===t.y?t:new yw(t.k,r,i)}function y(t){return[(+t[0][0]+ +t[1][0])/2,(+t[0][1]+ +t[1][1])/2]}function v(t,e,n){t.on("start.zoom",(function(){m(this,arguments).start()})).on("interrupt.zoom end.zoom",(function(){m(this,arguments).end()})).tween("zoom",(function(){var t=this,i=arguments,a=m(t,i),o=r.apply(t,i),s=null==n?y(o):"function"==typeof n?n.apply(t,i):n,c=Math.max(o[1][0]-o[0][0],o[1][1]-o[0][1]),u=t.__zoom,h="function"==typeof e?e.apply(t,i):e,f=l(u.invert(s).concat(c/u.k),h.invert(s).concat(c/h.k));return function(t){if(1===t)t=h;else{var e=f(t),n=c/e[2];t=new yw(n,s[0]-e[0]*n,s[1]-e[1]*n)}a.zoom(null,t)}}))}function m(t,e,n){return!n&&t.__zooming||new b(t,e)}function b(t,e){this.that=t,this.args=e,this.active=0,this.extent=r.apply(t,e),this.taps=0}function x(){if(n.apply(this,arguments)){var t=m(this,arguments),e=this.__zoom,r=Math.max(s[0],Math.min(s[1],e.k*Math.pow(2,a.apply(this,arguments)))),o=Nn(this);if(t.wheel)t.mouse[0][0]===o[0]&&t.mouse[0][1]===o[1]||(t.mouse[1]=e.invert(t.mouse[0]=o)),clearTimeout(t.wheel);else{if(e.k===r)return;t.mouse=[o,e.invert(o)],or(this),t.start()}xw(),t.wheel=setTimeout(u,150),t.zoom("mouse",i(g(p(e,r),t.mouse[0],t.mouse[1]),t.extent,c))}function u(){t.wheel=null,t.end()}}function _(){if(!e&&n.apply(this,arguments)){var t=m(this,arguments,!0),r=ke(ce.view).on("mousemove.zoom",u,!0).on("mouseup.zoom",l,!0),a=Nn(this),o=ce.clientX,s=ce.clientY;Te(ce.view),bw(),t.mouse=[a,this.__zoom.invert(a)],or(this),t.start()}function u(){if(xw(),!t.moved){var e=ce.clientX-o,n=ce.clientY-s;t.moved=e*e+n*n>f}t.zoom("mouse",i(g(t.that.__zoom,t.mouse[0]=Nn(t.that),t.mouse[1]),t.extent,c))}function l(){r.on("mousemove.zoom mouseup.zoom",null),Ce(ce.view,t.moved),xw(),t.end()}}function k(){if(n.apply(this,arguments)){var t=this.__zoom,e=Nn(this),a=t.invert(e),o=t.k*(ce.shiftKey?.5:2),s=i(g(p(t,o),e,a),r.apply(this,arguments),c);xw(),u>0?ke(this).transition().duration(u).call(v,s,e):ke(this).call(d.transform,s)}}function w(){if(n.apply(this,arguments)){var e,r,i,a,o=ce.touches,s=o.length,c=m(this,arguments,ce.changedTouches.length===s);for(bw(),r=0;rh&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},M={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),56;case 1:return this.begin("type_directive"),57;case 2:return this.popState(),this.begin("arg_directive"),14;case 3:return this.popState(),this.popState(),59;case 4:return 58;case 5:return 5;case 6:case 7:case 8:case 9:case 10:break;case 11:return this.begin("ID"),16;case 12:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),48;case 13:return this.popState(),this.popState(),this.begin("LINE"),18;case 14:return this.popState(),this.popState(),5;case 15:return this.begin("LINE"),27;case 16:return this.begin("LINE"),29;case 17:return this.begin("LINE"),30;case 18:return this.begin("LINE"),31;case 19:return this.begin("LINE"),36;case 20:return this.begin("LINE"),33;case 21:return this.begin("LINE"),35;case 22:return this.popState(),19;case 23:return 28;case 24:return 43;case 25:return 44;case 26:return 39;case 27:return 37;case 28:return this.begin("ID"),22;case 29:return this.begin("ID"),23;case 30:return 25;case 31:return 7;case 32:return 21;case 33:return 42;case 34:return 5;case 35:return e.yytext=e.yytext.trim(),48;case 36:return 51;case 37:return 52;case 38:return 49;case 39:return 50;case 40:return 53;case 41:return 54;case 42:return 55;case 43:return 46;case 44:return 47;case 45:return 5;case 46:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:participant\b)/i,/^(?:[^\->:\n,;]+?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:and\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\b)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+((?!(-x|--x))[\-]*[^\+\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{open_directive:{rules:[1,8],inclusive:!1},type_directive:{rules:[2,3,8],inclusive:!1},arg_directive:{rules:[3,4,8],inclusive:!1},ID:{rules:[7,8,12],inclusive:!1},ALIAS:{rules:[7,8,13,14],inclusive:!1},LINE:{rules:[7,8,22],inclusive:!1},INITIAL:{rules:[0,5,6,8,9,10,11,15,16,17,18,19,20,21,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],inclusive:!0}}};function O(){this.yy={}}return A.lexer=M,O.prototype=A,A.Parser=O,new O}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(19).readFileSync(n(20).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(14),n(7)(t))},function(t,e,n){var r=n(198);t.exports={Graph:r.Graph,json:n(301),alg:n(302),version:r.version}},function(t,e,n){var r;try{r={cloneDeep:n(313),constant:n(86),defaults:n(154),each:n(87),filter:n(128),find:n(314),flatten:n(156),forEach:n(126),forIn:n(319),has:n(93),isUndefined:n(139),last:n(320),map:n(140),mapValues:n(321),max:n(322),merge:n(324),min:n(329),minBy:n(330),now:n(331),pick:n(161),range:n(162),reduce:n(142),sortBy:n(338),uniqueId:n(163),values:n(147),zipObject:n(343)}}catch(t){}r||(r=window._),t.exports=r},function(t,e){var n=Array.isArray;t.exports=n},function(t,e,n){ +/** + * @license + * Copyright (c) 2012-2013 Chris Pettitt + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +t.exports={graphlib:n(311),dagre:n(153),intersect:n(368),render:n(370),util:n(12),version:n(382)}},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),t.webpackPolyfill=1),t}},function(t,e,n){"use strict";var r=n(4),i=n(17).Graph;function a(t,e,n,i){var a;do{a=r.uniqueId(i)}while(t.hasNode(a));return n.dummy=e,t.setNode(a,n),a}function o(t){return r.max(r.map(t.nodes(),(function(e){var n=t.node(e).rank;if(!r.isUndefined(n))return n})))}t.exports={addDummyNode:a,simplify:function(t){var e=(new i).setGraph(t.graph());return r.forEach(t.nodes(),(function(n){e.setNode(n,t.node(n))})),r.forEach(t.edges(),(function(n){var r=e.edge(n.v,n.w)||{weight:0,minlen:1},i=t.edge(n);e.setEdge(n.v,n.w,{weight:r.weight+i.weight,minlen:Math.max(r.minlen,i.minlen)})})),e},asNonCompoundGraph:function(t){var e=new i({multigraph:t.isMultigraph()}).setGraph(t.graph());return r.forEach(t.nodes(),(function(n){t.children(n).length||e.setNode(n,t.node(n))})),r.forEach(t.edges(),(function(n){e.setEdge(n,t.edge(n))})),e},successorWeights:function(t){var e=r.map(t.nodes(),(function(e){var n={};return r.forEach(t.outEdges(e),(function(e){n[e.w]=(n[e.w]||0)+t.edge(e).weight})),n}));return r.zipObject(t.nodes(),e)},predecessorWeights:function(t){var e=r.map(t.nodes(),(function(e){var n={};return r.forEach(t.inEdges(e),(function(e){n[e.v]=(n[e.v]||0)+t.edge(e).weight})),n}));return r.zipObject(t.nodes(),e)},intersectRect:function(t,e){var n,r,i=t.x,a=t.y,o=e.x-i,s=e.y-a,c=t.width/2,u=t.height/2;if(!o&&!s)throw new Error("Not possible to find intersection inside of the rectangle");Math.abs(s)*c>Math.abs(o)*u?(s<0&&(u=-u),n=u*o/s,r=u):(o<0&&(c=-c),n=c,r=c*s/o);return{x:i+n,y:a+r}},buildLayerMatrix:function(t){var e=r.map(r.range(o(t)+1),(function(){return[]}));return r.forEach(t.nodes(),(function(n){var i=t.node(n),a=i.rank;r.isUndefined(a)||(e[a][i.order]=n)})),e},normalizeRanks:function(t){var e=r.min(r.map(t.nodes(),(function(e){return t.node(e).rank})));r.forEach(t.nodes(),(function(n){var i=t.node(n);r.has(i,"rank")&&(i.rank-=e)}))},removeEmptyRanks:function(t){var e=r.min(r.map(t.nodes(),(function(e){return t.node(e).rank}))),n=[];r.forEach(t.nodes(),(function(r){var i=t.node(r).rank-e;n[i]||(n[i]=[]),n[i].push(r)}));var i=0,a=t.graph().nodeRankFactor;r.forEach(n,(function(e,n){r.isUndefined(e)&&n%a!=0?--i:i&&r.forEach(e,(function(e){t.node(e).rank+=i}))}))},addBorderNode:function(t,e,n,r){var i={width:0,height:0};arguments.length>=4&&(i.rank=n,i.order=r);return a(t,"border",i,e)},maxRank:o,partition:function(t,e){var n={lhs:[],rhs:[]};return r.forEach(t,(function(t){e(t)?n.lhs.push(t):n.rhs.push(t)})),n},time:function(t,e){var n=r.now();try{return e()}finally{console.log(t+" time: "+(r.now()-n)+"ms")}},notime:function(t,e){return e()}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(173),i=n(174),a=n(175),o={channel:r.default,lang:i.default,unit:a.default};e.default=o},function(t,e,n){var r;try{r={clone:n(199),constant:n(86),each:n(87),filter:n(128),has:n(93),isArray:n(5),isEmpty:n(276),isFunction:n(37),isUndefined:n(139),keys:n(30),map:n(140),reduce:n(142),size:n(279),transform:n(285),union:n(286),values:n(147)}}catch(t){}r||(r=window._),t.exports=r},function(t,e){t.exports=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},function(t,e,n){var r=n(43);t.exports={isSubgraph:function(t,e){return!!t.children(e).length},edgeToId:function(t){return a(t.v)+":"+a(t.w)+":"+a(t.name)},applyStyle:function(t,e){e&&t.attr("style",e)},applyClass:function(t,e,n){e&&t.attr("class",e).attr("class",n+" "+t.attr("class"))},applyTransition:function(t,e){var n=e.graph();if(r.isPlainObject(n)){var i=n.transition;if(r.isFunction(i))return i(t)}return t}};var i=/:/g;function a(t){return t?String(t).replace(i,"\\:"):""}},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,7],n=[1,6],r=[1,14],i=[1,25],a=[1,28],o=[1,26],s=[1,27],c=[1,29],u=[1,30],l=[1,31],h=[1,33],f=[1,34],d=[1,35],p=[10,19],g=[1,47],y=[1,48],v=[1,49],m=[1,50],b=[1,51],x=[1,52],_=[10,19,25,32,33,41,44,45,46,47,48,49],k=[10,19,23,25,32,33,37,41,44,45,46,47,48,49,66,67,68],w=[10,13,17,19],E=[41,66,67,68],T=[41,48,49,66,67,68],C=[41,44,45,46,47,66,67,68],S=[10,19,25],A=[1,81],M={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,directive:5,graphConfig:6,openDirective:7,typeDirective:8,closeDirective:9,NEWLINE:10,":":11,argDirective:12,open_directive:13,type_directive:14,arg_directive:15,close_directive:16,CLASS_DIAGRAM:17,statements:18,EOF:19,statement:20,className:21,alphaNumToken:22,GENERICTYPE:23,relationStatement:24,LABEL:25,classStatement:26,methodStatement:27,annotationStatement:28,clickStatement:29,cssClassStatement:30,CLASS:31,STYLE_SEPARATOR:32,STRUCT_START:33,members:34,STRUCT_STOP:35,ANNOTATION_START:36,ANNOTATION_END:37,MEMBER:38,SEPARATOR:39,relation:40,STR:41,relationType:42,lineType:43,AGGREGATION:44,EXTENSION:45,COMPOSITION:46,DEPENDENCY:47,LINE:48,DOTTED_LINE:49,CALLBACK:50,LINK:51,CSSCLASS:52,commentToken:53,textToken:54,graphCodeTokens:55,textNoTagsToken:56,TAGSTART:57,TAGEND:58,"==":59,"--":60,PCT:61,DEFAULT:62,SPACE:63,MINUS:64,keywords:65,UNICODE_TEXT:66,NUM:67,ALPHA:68,$accept:0,$end:1},terminals_:{2:"error",10:"NEWLINE",11:":",13:"open_directive",14:"type_directive",15:"arg_directive",16:"close_directive",17:"CLASS_DIAGRAM",19:"EOF",23:"GENERICTYPE",25:"LABEL",31:"CLASS",32:"STYLE_SEPARATOR",33:"STRUCT_START",35:"STRUCT_STOP",36:"ANNOTATION_START",37:"ANNOTATION_END",38:"MEMBER",39:"SEPARATOR",41:"STR",44:"AGGREGATION",45:"EXTENSION",46:"COMPOSITION",47:"DEPENDENCY",48:"LINE",49:"DOTTED_LINE",50:"CALLBACK",51:"LINK",52:"CSSCLASS",55:"graphCodeTokens",57:"TAGSTART",58:"TAGEND",59:"==",60:"--",61:"PCT",62:"DEFAULT",63:"SPACE",64:"MINUS",65:"keywords",66:"UNICODE_TEXT",67:"NUM",68:"ALPHA"},productions_:[0,[3,1],[3,2],[4,1],[5,4],[5,6],[7,1],[8,1],[12,1],[9,1],[6,4],[18,1],[18,2],[18,3],[21,1],[21,2],[21,3],[21,2],[20,1],[20,2],[20,1],[20,1],[20,1],[20,1],[20,1],[20,1],[26,2],[26,4],[26,5],[26,7],[28,4],[34,1],[34,2],[27,1],[27,2],[27,1],[27,1],[24,3],[24,4],[24,4],[24,5],[40,3],[40,2],[40,2],[40,1],[42,1],[42,1],[42,1],[42,1],[43,1],[43,1],[29,3],[29,4],[29,3],[29,4],[30,3],[53,1],[53,1],[54,1],[54,1],[54,1],[54,1],[54,1],[54,1],[54,1],[56,1],[56,1],[56,1],[56,1],[22,1],[22,1],[22,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 6:r.parseDirective("%%{","open_directive");break;case 7:r.parseDirective(a[s],"type_directive");break;case 8:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 9:r.parseDirective("}%%","close_directive","class");break;case 14:this.$=a[s];break;case 15:this.$=a[s-1]+a[s];break;case 16:this.$=a[s-2]+"~"+a[s-1]+a[s];break;case 17:this.$=a[s-1]+"~"+a[s];break;case 18:r.addRelation(a[s]);break;case 19:a[s-1].title=r.cleanupLabel(a[s]),r.addRelation(a[s-1]);break;case 26:r.addClass(a[s]);break;case 27:r.addClass(a[s-2]),r.setCssClass(a[s-2],a[s]);break;case 28:r.addClass(a[s-3]),r.addMembers(a[s-3],a[s-1]);break;case 29:r.addClass(a[s-5]),r.setCssClass(a[s-5],a[s-3]),r.addMembers(a[s-5],a[s-1]);break;case 30:r.addAnnotation(a[s],a[s-2]);break;case 31:this.$=[a[s]];break;case 32:a[s].push(a[s-1]),this.$=a[s];break;case 33:break;case 34:r.addMember(a[s-1],r.cleanupLabel(a[s]));break;case 35:case 36:break;case 37:this.$={id1:a[s-2],id2:a[s],relation:a[s-1],relationTitle1:"none",relationTitle2:"none"};break;case 38:this.$={id1:a[s-3],id2:a[s],relation:a[s-1],relationTitle1:a[s-2],relationTitle2:"none"};break;case 39:this.$={id1:a[s-3],id2:a[s],relation:a[s-2],relationTitle1:"none",relationTitle2:a[s-1]};break;case 40:this.$={id1:a[s-4],id2:a[s],relation:a[s-2],relationTitle1:a[s-3],relationTitle2:a[s-1]};break;case 41:this.$={type1:a[s-2],type2:a[s],lineType:a[s-1]};break;case 42:this.$={type1:"none",type2:a[s],lineType:a[s-1]};break;case 43:this.$={type1:a[s-1],type2:"none",lineType:a[s]};break;case 44:this.$={type1:"none",type2:"none",lineType:a[s]};break;case 45:this.$=r.relationType.AGGREGATION;break;case 46:this.$=r.relationType.EXTENSION;break;case 47:this.$=r.relationType.COMPOSITION;break;case 48:this.$=r.relationType.DEPENDENCY;break;case 49:this.$=r.lineType.LINE;break;case 50:this.$=r.lineType.DOTTED_LINE;break;case 51:this.$=a[s-2],r.setClickEvent(a[s-1],a[s],void 0);break;case 52:this.$=a[s-3],r.setClickEvent(a[s-2],a[s-1],a[s]);break;case 53:this.$=a[s-2],r.setLink(a[s-1],a[s],void 0);break;case 54:this.$=a[s-3],r.setLink(a[s-2],a[s-1],a[s]);break;case 55:r.setCssClass(a[s-1],a[s])}},table:[{3:1,4:2,5:3,6:4,7:5,13:e,17:n},{1:[3]},{1:[2,1]},{3:8,4:2,5:3,6:4,7:5,13:e,17:n},{1:[2,3]},{8:9,14:[1,10]},{10:[1,11]},{14:[2,6]},{1:[2,2]},{9:12,11:[1,13],16:r},t([11,16],[2,7]),{5:23,7:5,13:e,18:15,20:16,21:24,22:32,24:17,26:18,27:19,28:20,29:21,30:22,31:i,36:a,38:o,39:s,50:c,51:u,52:l,66:h,67:f,68:d},{10:[1,36]},{12:37,15:[1,38]},{10:[2,9]},{19:[1,39]},{10:[1,40],19:[2,11]},t(p,[2,18],{25:[1,41]}),t(p,[2,20]),t(p,[2,21]),t(p,[2,22]),t(p,[2,23]),t(p,[2,24]),t(p,[2,25]),t(p,[2,33],{40:42,42:45,43:46,25:[1,44],41:[1,43],44:g,45:y,46:v,47:m,48:b,49:x}),{21:53,22:32,66:h,67:f,68:d},t(p,[2,35]),t(p,[2,36]),{22:54,66:h,67:f,68:d},{21:55,22:32,66:h,67:f,68:d},{21:56,22:32,66:h,67:f,68:d},{41:[1,57]},t(_,[2,14],{22:32,21:58,23:[1,59],66:h,67:f,68:d}),t(k,[2,69]),t(k,[2,70]),t(k,[2,71]),t(w,[2,4]),{9:60,16:r},{16:[2,8]},{1:[2,10]},{5:23,7:5,13:e,18:61,19:[2,12],20:16,21:24,22:32,24:17,26:18,27:19,28:20,29:21,30:22,31:i,36:a,38:o,39:s,50:c,51:u,52:l,66:h,67:f,68:d},t(p,[2,19]),{21:62,22:32,41:[1,63],66:h,67:f,68:d},{40:64,42:45,43:46,44:g,45:y,46:v,47:m,48:b,49:x},t(p,[2,34]),{43:65,48:b,49:x},t(E,[2,44],{42:66,44:g,45:y,46:v,47:m}),t(T,[2,45]),t(T,[2,46]),t(T,[2,47]),t(T,[2,48]),t(C,[2,49]),t(C,[2,50]),t(p,[2,26],{32:[1,67],33:[1,68]}),{37:[1,69]},{41:[1,70]},{41:[1,71]},{22:72,66:h,67:f,68:d},t(_,[2,15]),t(_,[2,17],{22:32,21:73,66:h,67:f,68:d}),{10:[1,74]},{19:[2,13]},t(S,[2,37]),{21:75,22:32,66:h,67:f,68:d},{21:76,22:32,41:[1,77],66:h,67:f,68:d},t(E,[2,43],{42:78,44:g,45:y,46:v,47:m}),t(E,[2,42]),{22:79,66:h,67:f,68:d},{34:80,38:A},{21:82,22:32,66:h,67:f,68:d},t(p,[2,51],{41:[1,83]}),t(p,[2,53],{41:[1,84]}),t(p,[2,55]),t(_,[2,16]),t(w,[2,5]),t(S,[2,39]),t(S,[2,38]),{21:85,22:32,66:h,67:f,68:d},t(E,[2,41]),t(p,[2,27],{33:[1,86]}),{35:[1,87]},{34:88,35:[2,31],38:A},t(p,[2,30]),t(p,[2,52]),t(p,[2,54]),t(S,[2,40]),{34:89,38:A},t(p,[2,28]),{35:[2,32]},{35:[1,90]},t(p,[2,29])],defaultActions:{2:[2,1],4:[2,3],7:[2,6],8:[2,2],14:[2,9],38:[2,8],39:[2,10],61:[2,13],88:[2,32]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var v=p.yylloc;a.push(v);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var x,_,k,w,E,T,C,S,A,M={};;){if(k=n[n.length-1],this.defaultActions[k]?w=this.defaultActions[k]:(null==x&&(x=b()),w=o[k]&&o[k][x]),void 0===w||!w.length||!w[0]){var O="";for(T in A=[],o[k])this.terminals_[T]&&T>h&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},O={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),13;case 1:return this.begin("type_directive"),14;case 2:return this.popState(),this.begin("arg_directive"),11;case 3:return this.popState(),this.popState(),16;case 4:return 15;case 5:case 6:break;case 7:return 10;case 8:break;case 9:case 10:return 17;case 11:return this.begin("struct"),33;case 12:return"EOF_IN_STRUCT";case 13:return"OPEN_IN_STRUCT";case 14:return this.popState(),35;case 15:break;case 16:return"MEMBER";case 17:return 31;case 18:return 52;case 19:return 50;case 20:return 51;case 21:return 36;case 22:return 37;case 23:this.begin("generic");break;case 24:this.popState();break;case 25:return"GENERICTYPE";case 26:this.begin("string");break;case 27:this.popState();break;case 28:return"STR";case 29:case 30:return 45;case 31:case 32:return 47;case 33:return 46;case 34:return 44;case 35:return 48;case 36:return 49;case 37:return 25;case 38:return 32;case 39:return 64;case 40:return"DOT";case 41:return"PLUS";case 42:return 61;case 43:case 44:return"EQUALS";case 45:return 68;case 46:return"PUNCTUATION";case 47:return 67;case 48:return 66;case 49:return 63;case 50:return 19}},rules:[/^(?:%%\{)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:[{])/,/^(?:$)/,/^(?:[{])/,/^(?:[}])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:class\b)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:[~])/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:$)/],conditions:{string:{rules:[27,28],inclusive:!1},generic:{rules:[24,25],inclusive:!1},struct:{rules:[12,13,14,15,16],inclusive:!1},open_directive:{rules:[1],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,17,18,19,20,21,22,23,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50],inclusive:!0}}};function D(){this.yy={}}return M.lexer=O,D.prototype=M,M.Parser=D,new D}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(19).readFileSync(n(20).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(14),n(7)(t))},function(t,e){var n,r,i=t.exports={};function a(){throw new Error("setTimeout has not been defined")}function o(){throw new Error("clearTimeout has not been defined")}function s(t){if(n===setTimeout)return setTimeout(t,0);if((n===a||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:a}catch(t){n=a}try{r="function"==typeof clearTimeout?clearTimeout:o}catch(t){r=o}}();var c,u=[],l=!1,h=-1;function f(){l&&c&&(l=!1,c.length?u=c.concat(u):h=-1,u.length&&d())}function d(){if(!l){var t=s(f);l=!0;for(var e=u.length;e;){for(c=u,u=[];++h1)for(var n=1;n=0;r--){var i=t[r];"."===i?t.splice(r,1):".."===i?(t.splice(r,1),n++):n&&(t.splice(r,1),n--)}if(e)for(;n--;n)t.unshift("..");return t}function r(t,e){if(t.filter)return t.filter(e);for(var n=[],r=0;r=-1&&!i;a--){var o=a>=0?arguments[a]:t.cwd();if("string"!=typeof o)throw new TypeError("Arguments to path.resolve must be strings");o&&(e=o+"/"+e,i="/"===o.charAt(0))}return(i?"/":"")+(e=n(r(e.split("/"),(function(t){return!!t})),!i).join("/"))||"."},e.normalize=function(t){var a=e.isAbsolute(t),o="/"===i(t,-1);return(t=n(r(t.split("/"),(function(t){return!!t})),!a).join("/"))||a||(t="."),t&&o&&(t+="/"),(a?"/":"")+t},e.isAbsolute=function(t){return"/"===t.charAt(0)},e.join=function(){var t=Array.prototype.slice.call(arguments,0);return e.normalize(r(t,(function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t})).join("/"))},e.relative=function(t,n){function r(t){for(var e=0;e=0&&""===t[n];n--);return e>n?[]:t.slice(e,n-e+1)}t=e.resolve(t).substr(1),n=e.resolve(n).substr(1);for(var i=r(t.split("/")),a=r(n.split("/")),o=Math.min(i.length,a.length),s=o,c=0;c=1;--a)if(47===(e=t.charCodeAt(a))){if(!i){r=a;break}}else i=!1;return-1===r?n?"/":".":n&&1===r?"/":t.slice(0,r)},e.basename=function(t,e){var n=function(t){"string"!=typeof t&&(t+="");var e,n=0,r=-1,i=!0;for(e=t.length-1;e>=0;--e)if(47===t.charCodeAt(e)){if(!i){n=e+1;break}}else-1===r&&(i=!1,r=e+1);return-1===r?"":t.slice(n,r)}(t);return e&&n.substr(-1*e.length)===e&&(n=n.substr(0,n.length-e.length)),n},e.extname=function(t){"string"!=typeof t&&(t+="");for(var e=-1,n=0,r=-1,i=!0,a=0,o=t.length-1;o>=0;--o){var s=t.charCodeAt(o);if(47!==s)-1===r&&(i=!1,r=o+1),46===s?-1===e?e=o:1!==a&&(a=1):-1!==e&&(a=-1);else if(!i){n=o+1;break}}return-1===e||-1===r||0===a||1===a&&e===r-1&&e===n+1?"":t.slice(e,r)};var i="b"==="ab".substr(-1)?function(t,e,n){return t.substr(e,n)}:function(t,e,n){return e<0&&(e=t.length+e),t.substr(e,n)}}).call(this,n(14))},function(t,e){t.exports=function(t){return null!=t&&"object"==typeof t}},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,2],n=[1,3],r=[1,5],i=[1,7],a=[2,5],o=[1,15],s=[1,17],c=[1,19],u=[1,20],l=[1,21],h=[1,22],f=[1,28],d=[1,23],p=[1,24],g=[1,25],y=[1,26],v=[1,29],m=[1,32],b=[1,4,5,14,15,17,19,20,22,23,24,25,26,36,39],x=[1,4,5,12,13,14,15,17,19,20,22,23,24,25,26,36,39],_=[1,4,5,7,14,15,17,19,20,22,23,24,25,26,36,39],k=[4,5,14,15,17,19,20,22,23,24,25,26,36,39],w={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,directive:6,SD:7,document:8,line:9,statement:10,idStatement:11,DESCR:12,"--\x3e":13,HIDE_EMPTY:14,scale:15,WIDTH:16,COMPOSIT_STATE:17,STRUCT_START:18,STRUCT_STOP:19,STATE_DESCR:20,AS:21,ID:22,FORK:23,JOIN:24,CONCURRENT:25,note:26,notePosition:27,NOTE_TEXT:28,openDirective:29,typeDirective:30,closeDirective:31,":":32,argDirective:33,eol:34,";":35,EDGE_STATE:36,left_of:37,right_of:38,open_directive:39,type_directive:40,arg_directive:41,close_directive:42,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",7:"SD",12:"DESCR",13:"--\x3e",14:"HIDE_EMPTY",15:"scale",16:"WIDTH",17:"COMPOSIT_STATE",18:"STRUCT_START",19:"STRUCT_STOP",20:"STATE_DESCR",21:"AS",22:"ID",23:"FORK",24:"JOIN",25:"CONCURRENT",26:"note",28:"NOTE_TEXT",32:":",35:";",36:"EDGE_STATE",37:"left_of",38:"right_of",39:"open_directive",40:"type_directive",41:"arg_directive",42:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[9,1],[9,1],[10,1],[10,2],[10,3],[10,4],[10,1],[10,2],[10,1],[10,4],[10,3],[10,6],[10,1],[10,1],[10,1],[10,4],[10,4],[10,1],[6,3],[6,5],[34,1],[34,1],[11,1],[11,1],[27,1],[27,1],[29,1],[30,1],[33,1],[31,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 4:return r.setRootDoc(a[s]),a[s];case 5:this.$=[];break;case 6:"nl"!=a[s]&&(a[s-1].push(a[s]),this.$=a[s-1]);break;case 7:case 8:this.$=a[s];break;case 9:this.$="nl";break;case 10:this.$={stmt:"state",id:a[s],type:"default",description:""};break;case 11:this.$={stmt:"state",id:a[s-1],type:"default",description:r.trimColon(a[s])};break;case 12:this.$={stmt:"relation",state1:{stmt:"state",id:a[s-2],type:"default",description:""},state2:{stmt:"state",id:a[s],type:"default",description:""}};break;case 13:this.$={stmt:"relation",state1:{stmt:"state",id:a[s-3],type:"default",description:""},state2:{stmt:"state",id:a[s-1],type:"default",description:""},description:a[s].substr(1).trim()};break;case 17:this.$={stmt:"state",id:a[s-3],type:"default",description:"",doc:a[s-1]};break;case 18:var c=a[s],u=a[s-2].trim();if(a[s].match(":")){var l=a[s].split(":");c=l[0],u=[u,l[1]]}this.$={stmt:"state",id:c,type:"default",description:u};break;case 19:this.$={stmt:"state",id:a[s-3],type:"default",description:a[s-5],doc:a[s-1]};break;case 20:this.$={stmt:"state",id:a[s],type:"fork"};break;case 21:this.$={stmt:"state",id:a[s],type:"join"};break;case 22:this.$={stmt:"state",id:r.getDividerId(),type:"divider"};break;case 23:this.$={stmt:"state",id:a[s-1].trim(),note:{position:a[s-2].trim(),text:a[s].trim()}};break;case 30:case 31:this.$=a[s];break;case 34:r.parseDirective("%%{","open_directive");break;case 35:r.parseDirective(a[s],"type_directive");break;case 36:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 37:r.parseDirective("}%%","close_directive","state")}},table:[{3:1,4:e,5:n,6:4,7:r,29:6,39:i},{1:[3]},{3:8,4:e,5:n,6:4,7:r,29:6,39:i},{3:9,4:e,5:n,6:4,7:r,29:6,39:i},{3:10,4:e,5:n,6:4,7:r,29:6,39:i},t([1,4,5,14,15,17,20,22,23,24,25,26,36,39],a,{8:11}),{30:12,40:[1,13]},{40:[2,34]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{1:[2,4],4:o,5:s,6:27,9:14,10:16,11:18,14:c,15:u,17:l,20:h,22:f,23:d,24:p,25:g,26:y,29:6,36:v,39:i},{31:30,32:[1,31],42:m},t([32,42],[2,35]),t(b,[2,6]),{6:27,10:33,11:18,14:c,15:u,17:l,20:h,22:f,23:d,24:p,25:g,26:y,29:6,36:v,39:i},t(b,[2,8]),t(b,[2,9]),t(b,[2,10],{12:[1,34],13:[1,35]}),t(b,[2,14]),{16:[1,36]},t(b,[2,16],{18:[1,37]}),{21:[1,38]},t(b,[2,20]),t(b,[2,21]),t(b,[2,22]),{27:39,28:[1,40],37:[1,41],38:[1,42]},t(b,[2,25]),t(x,[2,30]),t(x,[2,31]),t(_,[2,26]),{33:43,41:[1,44]},t(_,[2,37]),t(b,[2,7]),t(b,[2,11]),{11:45,22:f,36:v},t(b,[2,15]),t(k,a,{8:46}),{22:[1,47]},{22:[1,48]},{21:[1,49]},{22:[2,32]},{22:[2,33]},{31:50,42:m},{42:[2,36]},t(b,[2,12],{12:[1,51]}),{4:o,5:s,6:27,9:14,10:16,11:18,14:c,15:u,17:l,19:[1,52],20:h,22:f,23:d,24:p,25:g,26:y,29:6,36:v,39:i},t(b,[2,18],{18:[1,53]}),{28:[1,54]},{22:[1,55]},t(_,[2,27]),t(b,[2,13]),t(b,[2,17]),t(k,a,{8:56}),t(b,[2,23]),t(b,[2,24]),{4:o,5:s,6:27,9:14,10:16,11:18,14:c,15:u,17:l,19:[1,57],20:h,22:f,23:d,24:p,25:g,26:y,29:6,36:v,39:i},t(b,[2,19])],defaultActions:{7:[2,34],8:[2,1],9:[2,2],10:[2,3],41:[2,32],42:[2,33],44:[2,36]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var v=p.yylloc;a.push(v);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var x,_,k,w,E,T,C,S,A,M={};;){if(k=n[n.length-1],this.defaultActions[k]?w=this.defaultActions[k]:(null==x&&(x=b()),w=o[k]&&o[k][x]),void 0===w||!w.length||!w[0]){var O="";for(T in A=[],o[k])this.terminals_[T]&&T>h&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},E={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),39;case 1:return this.begin("type_directive"),40;case 2:return this.popState(),this.begin("arg_directive"),32;case 3:return this.popState(),this.popState(),42;case 4:return 41;case 5:break;case 6:console.log("Crap after close");break;case 7:return 5;case 8:case 9:case 10:case 11:break;case 12:return this.pushState("SCALE"),15;case 13:return 16;case 14:this.popState();break;case 15:this.pushState("STATE");break;case 16:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),23;case 17:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),24;case 18:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),23;case 19:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),24;case 20:this.begin("STATE_STRING");break;case 21:return this.popState(),this.pushState("STATE_ID"),"AS";case 22:return this.popState(),"ID";case 23:this.popState();break;case 24:return"STATE_DESCR";case 25:return 17;case 26:this.popState();break;case 27:return this.popState(),this.pushState("struct"),18;case 28:return this.popState(),19;case 29:break;case 30:return this.begin("NOTE"),26;case 31:return this.popState(),this.pushState("NOTE_ID"),37;case 32:return this.popState(),this.pushState("NOTE_ID"),38;case 33:this.popState(),this.pushState("FLOATING_NOTE");break;case 34:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 35:break;case 36:return"NOTE_TEXT";case 37:return this.popState(),"ID";case 38:return this.popState(),this.pushState("NOTE_TEXT"),22;case 39:return this.popState(),e.yytext=e.yytext.substr(2).trim(),28;case 40:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),28;case 41:case 42:return 7;case 43:return 14;case 44:return 36;case 45:return 22;case 46:return e.yytext=e.yytext.trim(),12;case 47:return 13;case 48:return 25;case 49:return 5;case 50:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:\s*[^:;]+end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[9,10],inclusive:!1},close_directive:{rules:[9,10],inclusive:!1},arg_directive:{rules:[3,4,9,10],inclusive:!1},type_directive:{rules:[2,3,9,10],inclusive:!1},open_directive:{rules:[1,9,10],inclusive:!1},struct:{rules:[9,10,15,28,29,30,44,45,46,47,48],inclusive:!1},FLOATING_NOTE_ID:{rules:[37],inclusive:!1},FLOATING_NOTE:{rules:[34,35,36],inclusive:!1},NOTE_TEXT:{rules:[39,40],inclusive:!1},NOTE_ID:{rules:[38],inclusive:!1},NOTE:{rules:[31,32,33],inclusive:!1},SCALE:{rules:[13,14],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[22],inclusive:!1},STATE_STRING:{rules:[23,24],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[9,10,16,17,18,19,20,21,25,26,27],inclusive:!1},ID:{rules:[9,10],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,10,11,12,15,27,30,41,42,43,44,45,46,47,49,50],inclusive:!0}}};function T(){this.yy={}}return w.lexer=E,T.prototype=w,w.Parser=T,new T}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(19).readFileSync(n(20).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(14),n(7)(t))},function(t,e,n){(function(t){t.exports=function(){"use strict";var e,r;function i(){return e.apply(null,arguments)}function a(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function o(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function s(t){return void 0===t}function c(t){return"number"==typeof t||"[object Number]"===Object.prototype.toString.call(t)}function u(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function l(t,e){var n,r=[];for(n=0;n>>0,r=0;ryt(t)?(a=t+1,s-yt(t)):(a=t,s),{year:a,dayOfYear:o}}function Ft(t,e,n){var r,i,a=Bt(t.year(),e,n),o=Math.floor((t.dayOfYear()-a-1)/7)+1;return o<1?r=o+Pt(i=t.year()-1,e,n):o>Pt(t.year(),e,n)?(r=o-Pt(t.year(),e,n),i=t.year()+1):(i=t.year(),r=o),{week:r,year:i}}function Pt(t,e,n){var r=Bt(t,e,n),i=Bt(t+1,e,n);return(yt(t)-r+i)/7}function It(t,e){return t.slice(e,7).concat(t.slice(0,e))}W("w",["ww",2],"wo","week"),W("W",["WW",2],"Wo","isoWeek"),L("week","w"),L("isoWeek","W"),j("week",5),j("isoWeek",5),lt("w",Q),lt("ww",Q,q),lt("W",Q),lt("WW",Q,q),gt(["w","ww","W","WW"],(function(t,e,n,r){e[r.substr(0,1)]=w(t)})),W("d",0,"do","day"),W("dd",0,0,(function(t){return this.localeData().weekdaysMin(this,t)})),W("ddd",0,0,(function(t){return this.localeData().weekdaysShort(this,t)})),W("dddd",0,0,(function(t){return this.localeData().weekdays(this,t)})),W("e",0,0,"weekday"),W("E",0,0,"isoWeekday"),L("day","d"),L("weekday","e"),L("isoWeekday","E"),j("day",11),j("weekday",11),j("isoWeekday",11),lt("d",Q),lt("e",Q),lt("E",Q),lt("dd",(function(t,e){return e.weekdaysMinRegex(t)})),lt("ddd",(function(t,e){return e.weekdaysShortRegex(t)})),lt("dddd",(function(t,e){return e.weekdaysRegex(t)})),gt(["dd","ddd","dddd"],(function(t,e,n,r){var i=n._locale.weekdaysParse(t,r,n._strict);null!=i?e.d=i:p(n).invalidWeekday=t})),gt(["d","e","E"],(function(t,e,n,r){e[r]=w(t)}));var jt="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Rt="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Yt="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),zt=ct,Ut=ct,$t=ct;function Wt(){function t(t,e){return e.length-t.length}var e,n,r,i,a,o=[],s=[],c=[],u=[];for(e=0;e<7;e++)n=d([2e3,1]).day(e),r=this.weekdaysMin(n,""),i=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(r),s.push(i),c.push(a),u.push(r),u.push(i),u.push(a);for(o.sort(t),s.sort(t),c.sort(t),u.sort(t),e=0;e<7;e++)s[e]=ft(s[e]),c[e]=ft(c[e]),u[e]=ft(u[e]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+c.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Vt(){return this.hours()%12||12}function Ht(t,e){W(t,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)}))}function Gt(t,e){return e._meridiemParse}W("H",["HH",2],0,"hour"),W("h",["hh",2],0,Vt),W("k",["kk",2],0,(function(){return this.hours()||24})),W("hmm",0,0,(function(){return""+Vt.apply(this)+R(this.minutes(),2)})),W("hmmss",0,0,(function(){return""+Vt.apply(this)+R(this.minutes(),2)+R(this.seconds(),2)})),W("Hmm",0,0,(function(){return""+this.hours()+R(this.minutes(),2)})),W("Hmmss",0,0,(function(){return""+this.hours()+R(this.minutes(),2)+R(this.seconds(),2)})),Ht("a",!0),Ht("A",!1),L("hour","h"),j("hour",13),lt("a",Gt),lt("A",Gt),lt("H",Q),lt("h",Q),lt("k",Q),lt("HH",Q,q),lt("hh",Q,q),lt("kk",Q,q),lt("hmm",K),lt("hmmss",tt),lt("Hmm",K),lt("Hmmss",tt),pt(["H","HH"],3),pt(["k","kk"],(function(t,e,n){var r=w(t);e[3]=24===r?0:r})),pt(["a","A"],(function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t})),pt(["h","hh"],(function(t,e,n){e[3]=w(t),p(n).bigHour=!0})),pt("hmm",(function(t,e,n){var r=t.length-2;e[3]=w(t.substr(0,r)),e[4]=w(t.substr(r)),p(n).bigHour=!0})),pt("hmmss",(function(t,e,n){var r=t.length-4,i=t.length-2;e[3]=w(t.substr(0,r)),e[4]=w(t.substr(r,2)),e[5]=w(t.substr(i)),p(n).bigHour=!0})),pt("Hmm",(function(t,e,n){var r=t.length-2;e[3]=w(t.substr(0,r)),e[4]=w(t.substr(r))})),pt("Hmmss",(function(t,e,n){var r=t.length-4,i=t.length-2;e[3]=w(t.substr(0,r)),e[4]=w(t.substr(r,2)),e[5]=w(t.substr(i))}));var qt,Xt=xt("Hours",!0),Zt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Tt,monthsShort:Ct,week:{dow:0,doy:6},weekdays:jt,weekdaysMin:Yt,weekdaysShort:Rt,meridiemParse:/[ap]\.?m?\.?/i},Jt={},Qt={};function Kt(t){return t?t.toLowerCase().replace("_","-"):t}function te(e){var r=null;if(!Jt[e]&&void 0!==t&&t&&t.exports)try{r=qt._abbr,n(171)("./"+e),ee(r)}catch(e){}return Jt[e]}function ee(t,e){var n;return t&&((n=s(e)?re(t):ne(t,e))?qt=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+t+" not found. Did you forget to load it?")),qt._abbr}function ne(t,e){if(null===e)return delete Jt[t],null;var n,r=Zt;if(e.abbr=t,null!=Jt[t])M("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),r=Jt[t]._config;else if(null!=e.parentLocale)if(null!=Jt[e.parentLocale])r=Jt[e.parentLocale]._config;else{if(null==(n=te(e.parentLocale)))return Qt[e.parentLocale]||(Qt[e.parentLocale]=[]),Qt[e.parentLocale].push({name:t,config:e}),null;r=n._config}return Jt[t]=new N(D(r,e)),Qt[t]&&Qt[t].forEach((function(t){ne(t.name,t.config)})),ee(t),Jt[t]}function re(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return qt;if(!a(t)){if(e=te(t))return e;t=[t]}return function(t){for(var e,n,r,i,a=0;a=e&&E(i,n,!0)>=e-1)break;e--}a++}return qt}(t)}function ie(t){var e,n=t._a;return n&&-2===p(t).overflow&&(e=n[1]<0||11wt(n[0],n[1])?2:n[3]<0||24Pt(n,a,o)?p(t)._overflowWeeks=!0:null!=c?p(t)._overflowWeekday=!0:(s=Lt(n,r,i,a,o),t._a[0]=s.year,t._dayOfYear=s.dayOfYear)}(t),null!=t._dayOfYear&&(o=ae(t._a[0],r[0]),(t._dayOfYear>yt(o)||0===t._dayOfYear)&&(p(t)._overflowDayOfYear=!0),n=Nt(o,0,t._dayOfYear),t._a[1]=n.getUTCMonth(),t._a[2]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=s[e]=r[e];for(;e<7;e++)t._a[e]=s[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[3]&&0===t._a[4]&&0===t._a[5]&&0===t._a[6]&&(t._nextDay=!0,t._a[3]=0),t._d=(t._useUTC?Nt:function(t,e,n,r,i,a,o){var s;return t<100&&0<=t?(s=new Date(t+400,e,n,r,i,a,o),isFinite(s.getFullYear())&&s.setFullYear(t)):s=new Date(t,e,n,r,i,a,o),s}).apply(null,s),a=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[3]=24),t._w&&void 0!==t._w.d&&t._w.d!==a&&(p(t).weekdayMismatch=!0)}}var se=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ce=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ue=/Z|[+-]\d\d(?::?\d\d)?/,le=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],he=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],fe=/^\/?Date\((\-?\d+)/i;function de(t){var e,n,r,i,a,o,s=t._i,c=se.exec(s)||ce.exec(s);if(c){for(p(t).iso=!0,e=0,n=le.length;en.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},on.isLocal=function(){return!!this.isValid()&&!this._isUTC},on.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},on.isUtc=Be,on.isUTC=Be,on.zoneAbbr=function(){return this._isUTC?"UTC":""},on.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},on.dates=C("dates accessor is deprecated. Use date instead.",Ke),on.months=C("months accessor is deprecated. Use month instead",At),on.years=C("years accessor is deprecated. Use year instead",bt),on.zone=C("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",(function(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()})),on.isDSTShifted=C("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",(function(){if(!s(this._isDSTShifted))return this._isDSTShifted;var t={};if(m(t,this),(t=me(t))._a){var e=t._isUTC?d(t._a):xe(t._a);this._isDSTShifted=this.isValid()&&0h&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},qt={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),12;case 1:return this.begin("type_directive"),13;case 2:return this.popState(),this.begin("arg_directive"),10;case 3:return this.popState(),this.popState(),15;case 4:return 14;case 5:case 6:break;case 7:this.begin("string");break;case 8:this.popState();break;case 9:return"STR";case 10:return 75;case 11:return 84;case 12:return 76;case 13:return 90;case 14:return 77;case 15:return 78;case 16:return 79;case 17:case 18:return t.lex.firstGraph()&&this.begin("dir"),24;case 19:return 38;case 20:return 42;case 21:case 22:case 23:case 24:return 87;case 25:return this.popState(),25;case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 34:case 35:return this.popState(),26;case 36:return 91;case 37:return 99;case 38:return 47;case 39:return 96;case 40:return 46;case 41:return 20;case 42:return 92;case 43:return 110;case 44:case 45:case 46:return 70;case 47:case 48:case 49:return 69;case 50:return 51;case 51:return 52;case 52:return 53;case 53:return 54;case 54:return 55;case 55:return 56;case 56:return 57;case 57:return 58;case 58:return 97;case 59:return 100;case 60:return 111;case 61:return 108;case 62:return 101;case 63:case 64:return 109;case 65:return 102;case 66:return 61;case 67:return 81;case 68:return"SEP";case 69:return 80;case 70:return 95;case 71:return 63;case 72:return 62;case 73:return 65;case 74:return 64;case 75:return 106;case 76:return 107;case 77:return 71;case 78:return 49;case 79:return 50;case 80:return 40;case 81:return 41;case 82:return 59;case 83:return 60;case 84:return 117;case 85:return 21;case 86:return 22;case 87:return 23}},rules:[/^(?:%%\{)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:%%(?!\{)[^\n]*)/,/^(?:[^\}]%%[^\n]*)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:click\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\[)/,/^(?:\]\))/,/^(?:\[\[)/,/^(?:\]\])/,/^(?:\[\()/,/^(?:\)\])/,/^(?:-)/,/^(?:\.)/,/^(?:[\_])/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:[A-Za-z]+)/,/^(?:\\\])/,/^(?:\[\/)/,/^(?:\/\])/,/^(?:\[\\)/,/^(?:[!"#$%&'*+,-.`?\\_/])/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},vertex:{rules:[],inclusive:!1},dir:{rules:[25,26,27,28,29,30,31,32,33,34,35],inclusive:!1},string:{rules:[8,9],inclusive:!1},INITIAL:{rules:[0,5,6,7,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87],inclusive:!0}}};function Xt(){this.yy={}}return Gt.lexer=qt,Xt.prototype=Gt,Gt.Parser=Xt,new Xt}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(19).readFileSync(n(20).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(14),n(7)(t))},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,3],n=[1,5],r=[7,9,11,12,13,14,15,16,17,18,20,27,32],i=[1,15],a=[1,16],o=[1,17],s=[1,18],c=[1,19],u=[1,20],l=[1,21],h=[1,23],f=[1,25],d=[1,28],p=[5,7,9,11,12,13,14,15,16,17,18,20,27,32],g={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,gantt:5,document:6,EOF:7,line:8,SPACE:9,statement:10,NL:11,dateFormat:12,inclusiveEndDates:13,axisFormat:14,excludes:15,todayMarker:16,title:17,section:18,clickStatement:19,taskTxt:20,taskData:21,openDirective:22,typeDirective:23,closeDirective:24,":":25,argDirective:26,click:27,callbackname:28,callbackargs:29,href:30,clickStatementDebug:31,open_directive:32,type_directive:33,arg_directive:34,close_directive:35,$accept:0,$end:1},terminals_:{2:"error",5:"gantt",7:"EOF",9:"SPACE",11:"NL",12:"dateFormat",13:"inclusiveEndDates",14:"axisFormat",15:"excludes",16:"todayMarker",17:"title",18:"section",20:"taskTxt",21:"taskData",25:":",27:"click",28:"callbackname",29:"callbackargs",30:"href",32:"open_directive",33:"type_directive",34:"arg_directive",35:"close_directive"},productions_:[0,[3,2],[3,3],[6,0],[6,2],[8,2],[8,1],[8,1],[8,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,1],[4,4],[4,6],[19,2],[19,3],[19,3],[19,4],[19,3],[19,4],[19,2],[31,2],[31,3],[31,3],[31,4],[31,3],[31,4],[31,2],[22,1],[23,1],[26,1],[24,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 2:return a[s-1];case 3:this.$=[];break;case 4:a[s-1].push(a[s]),this.$=a[s-1];break;case 5:case 6:this.$=a[s];break;case 7:case 8:this.$=[];break;case 9:r.setDateFormat(a[s].substr(11)),this.$=a[s].substr(11);break;case 10:r.enableInclusiveEndDates(),this.$=a[s].substr(18);break;case 11:r.setAxisFormat(a[s].substr(11)),this.$=a[s].substr(11);break;case 12:r.setExcludes(a[s].substr(9)),this.$=a[s].substr(9);break;case 13:r.setTodayMarker(a[s].substr(12)),this.$=a[s].substr(12);break;case 14:r.setTitle(a[s].substr(6)),this.$=a[s].substr(6);break;case 15:r.addSection(a[s].substr(8)),this.$=a[s].substr(8);break;case 17:r.addTask(a[s-1],a[s]),this.$="task";break;case 21:this.$=a[s-1],r.setClickEvent(a[s-1],a[s],null);break;case 22:this.$=a[s-2],r.setClickEvent(a[s-2],a[s-1],a[s]);break;case 23:this.$=a[s-2],r.setClickEvent(a[s-2],a[s-1],null),r.setLink(a[s-2],a[s]);break;case 24:this.$=a[s-3],r.setClickEvent(a[s-3],a[s-2],a[s-1]),r.setLink(a[s-3],a[s]);break;case 25:this.$=a[s-2],r.setClickEvent(a[s-2],a[s],null),r.setLink(a[s-2],a[s-1]);break;case 26:this.$=a[s-3],r.setClickEvent(a[s-3],a[s-1],a[s]),r.setLink(a[s-3],a[s-2]);break;case 27:this.$=a[s-1],r.setLink(a[s-1],a[s]);break;case 28:case 34:this.$=a[s-1]+" "+a[s];break;case 29:case 30:case 32:this.$=a[s-2]+" "+a[s-1]+" "+a[s];break;case 31:case 33:this.$=a[s-3]+" "+a[s-2]+" "+a[s-1]+" "+a[s];break;case 35:r.parseDirective("%%{","open_directive");break;case 36:r.parseDirective(a[s],"type_directive");break;case 37:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 38:r.parseDirective("}%%","close_directive","gantt")}},table:[{3:1,4:2,5:e,22:4,32:n},{1:[3]},{3:6,4:2,5:e,22:4,32:n},t(r,[2,3],{6:7}),{23:8,33:[1,9]},{33:[2,35]},{1:[2,1]},{4:24,7:[1,10],8:11,9:[1,12],10:13,11:[1,14],12:i,13:a,14:o,15:s,16:c,17:u,18:l,19:22,20:h,22:4,27:f,32:n},{24:26,25:[1,27],35:d},t([25,35],[2,36]),t(r,[2,8],{1:[2,2]}),t(r,[2,4]),{4:24,10:29,12:i,13:a,14:o,15:s,16:c,17:u,18:l,19:22,20:h,22:4,27:f,32:n},t(r,[2,6]),t(r,[2,7]),t(r,[2,9]),t(r,[2,10]),t(r,[2,11]),t(r,[2,12]),t(r,[2,13]),t(r,[2,14]),t(r,[2,15]),t(r,[2,16]),{21:[1,30]},t(r,[2,18]),{28:[1,31],30:[1,32]},{11:[1,33]},{26:34,34:[1,35]},{11:[2,38]},t(r,[2,5]),t(r,[2,17]),t(r,[2,21],{29:[1,36],30:[1,37]}),t(r,[2,27],{28:[1,38]}),t(p,[2,19]),{24:39,35:d},{35:[2,37]},t(r,[2,22],{30:[1,40]}),t(r,[2,23]),t(r,[2,25],{29:[1,41]}),{11:[1,42]},t(r,[2,24]),t(r,[2,26]),t(p,[2,20])],defaultActions:{5:[2,35],6:[2,1],28:[2,38],35:[2,37]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var v=p.yylloc;a.push(v);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var x,_,k,w,E,T,C,S,A,M={};;){if(k=n[n.length-1],this.defaultActions[k]?w=this.defaultActions[k]:(null==x&&(x=b()),w=o[k]&&o[k][x]),void 0===w||!w.length||!w[0]){var O="";for(T in A=[],o[k])this.terminals_[T]&&T>h&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},y={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),32;case 1:return this.begin("type_directive"),33;case 2:return this.popState(),this.begin("arg_directive"),25;case 3:return this.popState(),this.popState(),35;case 4:return 34;case 5:case 6:case 7:break;case 8:return 11;case 9:case 10:case 11:break;case 12:this.begin("href");break;case 13:this.popState();break;case 14:return 30;case 15:this.begin("callbackname");break;case 16:this.popState();break;case 17:this.popState(),this.begin("callbackargs");break;case 18:return 28;case 19:this.popState();break;case 20:return 29;case 21:this.begin("click");break;case 22:this.popState();break;case 23:return 27;case 24:return 5;case 25:return 12;case 26:return 13;case 27:return 14;case 28:return 15;case 29:return 16;case 30:return"date";case 31:return 17;case 32:return 18;case 33:return 20;case 34:return 21;case 35:return 25;case 36:return 7;case 37:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},callbackargs:{rules:[19,20],inclusive:!1},callbackname:{rules:[16,17,18],inclusive:!1},href:{rules:[13,14],inclusive:!1},click:{rules:[22,23],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,12,15,21,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inclusive:!0}}};function v(){this.yy={}}return g.lexer=y,v.prototype=g,g.Parser=v,new v}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(19).readFileSync(n(20).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(14),n(7)(t))},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,2],n=[1,5],r=[6,9,11,17,18,19,21],i=[1,15],a=[1,16],o=[1,17],s=[1,21],c=[4,6,9,11,17,18,19,21],u={trace:function(){},yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,title:17,section:18,taskName:19,taskData:20,open_directive:21,type_directive:22,arg_directive:23,close_directive:24,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",17:"title",18:"section",19:"taskName",20:"taskData",21:"open_directive",22:"type_directive",23:"arg_directive",24:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,1],[10,2],[10,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 1:return a[s-1];case 3:this.$=[];break;case 4:a[s-1].push(a[s]),this.$=a[s-1];break;case 5:case 6:this.$=a[s];break;case 7:case 8:this.$=[];break;case 11:r.setTitle(a[s].substr(6)),this.$=a[s].substr(6);break;case 12:r.addSection(a[s].substr(8)),this.$=a[s].substr(8);break;case 13:r.addTask(a[s-1],a[s]),this.$="task";break;case 15:r.parseDirective("%%{","open_directive");break;case 16:r.parseDirective(a[s],"type_directive");break;case 17:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 18:r.parseDirective("}%%","close_directive","journey")}},table:[{3:1,4:e,7:3,12:4,21:n},{1:[3]},t(r,[2,3],{5:6}),{3:7,4:e,7:3,12:4,21:n},{13:8,22:[1,9]},{22:[2,15]},{6:[1,10],7:18,8:11,9:[1,12],10:13,11:[1,14],12:4,17:i,18:a,19:o,21:n},{1:[2,2]},{14:19,15:[1,20],24:s},t([15,24],[2,16]),t(r,[2,8],{1:[2,1]}),t(r,[2,4]),{7:18,10:22,12:4,17:i,18:a,19:o,21:n},t(r,[2,6]),t(r,[2,7]),t(r,[2,11]),t(r,[2,12]),{20:[1,23]},t(r,[2,14]),{11:[1,24]},{16:25,23:[1,26]},{11:[2,18]},t(r,[2,5]),t(r,[2,13]),t(c,[2,9]),{14:27,24:s},{24:[2,17]},{11:[1,28]},t(c,[2,10])],defaultActions:{5:[2,15],7:[2,2],21:[2,18],26:[2,17]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var v=p.yylloc;a.push(v);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var x,_,k,w,E,T,C,S,A,M={};;){if(k=n[n.length-1],this.defaultActions[k]?w=this.defaultActions[k]:(null==x&&(x=b()),w=o[k]&&o[k][x]),void 0===w||!w.length||!w[0]){var O="";for(T in A=[],o[k])this.terminals_[T]&&T>h&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},l={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),21;case 1:return this.begin("type_directive"),22;case 2:return this.popState(),this.begin("arg_directive"),15;case 3:return this.popState(),this.popState(),24;case 4:return 23;case 5:case 6:break;case 7:return 11;case 8:case 9:break;case 10:return 4;case 11:return 17;case 12:return 18;case 13:return 19;case 14:return 20;case 15:return 15;case 16:return 6;case 17:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{open_directive:{rules:[1],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,12,13,14,15,16,17],inclusive:!0}}};function h(){this.yy={}}return u.lexer=l,h.prototype=u,u.Parser=h,new h}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(19).readFileSync(n(20).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(14),n(7)(t))},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(9),i=n(15);e.default=function(t,e){return r.default.lang.round(i.default.parse(t)[e])}},function(t,e,n){var r=n(112),i=n(82),a=n(24);t.exports=function(t){return a(t)?r(t):i(t)}},function(t,e,n){var r;if(!r)try{r=n(0)}catch(t){}r||(r=window.d3),t.exports=r},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(9),i=n(15);e.default=function(t,e,n){var a=i.default.parse(t),o=a[e],s=r.default.channel.clamp[e](o+n);return o!==s&&(a[e]=s),i.default.stringify(a)}},function(t,e,n){var r=n(210),i=n(216);t.exports=function(t,e){var n=i(t,e);return r(n)?n:void 0}},function(t,e,n){var r=n(38),i=n(212),a=n(213),o=r?r.toStringTag:void 0;t.exports=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":o&&o in Object(t)?i(t):a(t)}},function(t,e){t.exports=function(t){return t}},function(t,e){t.exports=function(t,e){return t===e||t!=t&&e!=e}},function(t,e,n){var r=n(34),i=n(11);t.exports=function(t){if(!i(t))return!1;var e=r(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}},function(t,e,n){var r=n(16).Symbol;t.exports=r},function(t,e,n){(function(t){var r=n(16),i=n(232),a=e&&!e.nodeType&&e,o=a&&"object"==typeof t&&t&&!t.nodeType&&t,s=o&&o.exports===a?r.Buffer:void 0,c=(s?s.isBuffer:void 0)||i;t.exports=c}).call(this,n(7)(t))},function(t,e,n){var r=n(112),i=n(236),a=n(24);t.exports=function(t){return a(t)?r(t,!0):i(t)}},function(t,e,n){var r=n(241),i=n(77),a=n(242),o=n(121),s=n(243),c=n(34),u=n(110),l=u(r),h=u(i),f=u(a),d=u(o),p=u(s),g=c;(r&&"[object DataView]"!=g(new r(new ArrayBuffer(1)))||i&&"[object Map]"!=g(new i)||a&&"[object Promise]"!=g(a.resolve())||o&&"[object Set]"!=g(new o)||s&&"[object WeakMap]"!=g(new s))&&(g=function(t){var e=c(t),n="[object Object]"==e?t.constructor:void 0,r=n?u(n):"";if(r)switch(r){case l:return"[object DataView]";case h:return"[object Map]";case f:return"[object Promise]";case d:return"[object Set]";case p:return"[object WeakMap]"}return e}),t.exports=g},function(t,e,n){var r=n(34),i=n(21);t.exports=function(t){return"symbol"==typeof t||i(t)&&"[object Symbol]"==r(t)}},function(t,e,n){var r;try{r={defaults:n(154),each:n(87),isFunction:n(37),isPlainObject:n(158),pick:n(161),has:n(93),range:n(162),uniqueId:n(163)}}catch(t){}r||(r=window._),t.exports=r},function(t){t.exports=JSON.parse('{"name":"mermaid","version":"8.8.3","description":"Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.","main":"dist/mermaid.core.js","keywords":["diagram","markdown","flowchart","sequence diagram","gantt","class diagram","git graph"],"scripts":{"build:development":"webpack --progress --colors","build:production":"yarn build:development -p --config webpack.config.prod.babel.js","build":"yarn build:development && yarn build:production","postbuild":"documentation build src/mermaidAPI.js src/config.js --shallow -f md --markdown-toc false > docs/Setup.md","build:watch":"yarn build --watch","minify":"minify ./dist/mermaid.js > ./dist/mermaid.min.js","release":"yarn build","lint":"eslint src","e2e:depr":"yarn lint && jest e2e --config e2e/jest.config.js","cypress":"percy exec -- cypress run","e2e":"start-server-and-test dev http://localhost:9000/ cypress","e2e-upd":"yarn lint && jest e2e -u --config e2e/jest.config.js","dev":"webpack-dev-server --config webpack.config.e2e.js","test":"yarn lint && jest src/.*","test:watch":"jest --watch src","prepublishOnly":"yarn build && yarn test","prepare":"yarn build"},"repository":{"type":"git","url":"https://github.com/knsv/mermaid"},"author":"Knut Sveidqvist","license":"MIT","standard":{"ignore":["**/parser/*.js","dist/**/*.js","cypress/**/*.js"],"globals":["page"]},"dependencies":{"@braintree/sanitize-url":"^3.1.0","babel-eslint":"^10.1.0","d3":"^5.7.0","dagre":"^0.8.4","dagre-d3":"^0.6.4","entity-decode":"^2.0.2","graphlib":"^2.1.7","he":"^1.2.0","khroma":"^1.1.0","minify":"^4.1.1","moment-mini":"^2.22.1","stylis":"^3.5.2"},"devDependencies":{"@babel/core":"^7.2.2","@babel/preset-env":"^7.8.4","@babel/register":"^7.0.0","@percy/cypress":"*","babel-core":"7.0.0-bridge.0","babel-jest":"^24.9.0","babel-loader":"^8.0.4","coveralls":"^3.0.2","css-loader":"^2.0.1","css-to-string-loader":"^0.1.3","cypress":"4.0.1","documentation":"^12.0.1","eslint":"^6.3.0","eslint-config-prettier":"^6.3.0","eslint-plugin-prettier":"^3.1.0","husky":"^1.2.1","identity-obj-proxy":"^3.0.0","jest":"^24.9.0","jison":"^0.4.18","moment":"^2.23.0","node-sass":"^4.12.0","prettier":"^1.18.2","puppeteer":"^1.17.0","sass-loader":"^7.1.0","start-server-and-test":"^1.10.6","terser-webpack-plugin":"^2.2.2","webpack":"^4.41.2","webpack-bundle-analyzer":"^3.7.0","webpack-cli":"^3.1.2","webpack-dev-server":"^3.4.1","webpack-node-externals":"^1.7.2","yarn-upgrade-all":"^0.5.0"},"files":["dist"],"yarn-upgrade-all":{"ignore":["babel-core"]},"sideEffects":["**/*.css","**/*.scss"],"husky":{"hooks":{"pre-push":"yarn test"}}}')},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=new(n(176).default)({r:0,g:0,b:0,a:0},"transparent");e.default=r},function(t,e,n){var r=n(58),i=n(59);t.exports=function(t,e,n,a){var o=!n;n||(n={});for(var s=-1,c=e.length;++s-1&&t%1==0&&t-1}(s)?s:(n=s.match(a))?(e=n[0],r.test(e)?"about:blank":s):"about:blank"}}},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[2,3],n=[1,7],r=[7,12,15,17,19,20,21],i=[7,11,12,15,17,19,20,21],a=[2,20],o=[1,32],s={trace:function(){},yy:{},symbols_:{error:2,start:3,GG:4,":":5,document:6,EOF:7,DIR:8,options:9,body:10,OPT:11,NL:12,line:13,statement:14,COMMIT:15,commit_arg:16,BRANCH:17,ID:18,CHECKOUT:19,MERGE:20,RESET:21,reset_arg:22,STR:23,HEAD:24,reset_parents:25,CARET:26,$accept:0,$end:1},terminals_:{2:"error",4:"GG",5:":",7:"EOF",8:"DIR",11:"OPT",12:"NL",15:"COMMIT",17:"BRANCH",18:"ID",19:"CHECKOUT",20:"MERGE",21:"RESET",23:"STR",24:"HEAD",26:"CARET"},productions_:[0,[3,4],[3,5],[6,0],[6,2],[9,2],[9,1],[10,0],[10,2],[13,2],[13,1],[14,2],[14,2],[14,2],[14,2],[14,2],[16,0],[16,1],[22,2],[22,2],[25,0],[25,2]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 1:return a[s-1];case 2:return r.setDirection(a[s-3]),a[s-1];case 4:r.setOptions(a[s-1]),this.$=a[s];break;case 5:a[s-1]+=a[s],this.$=a[s-1];break;case 7:this.$=[];break;case 8:a[s-1].push(a[s]),this.$=a[s-1];break;case 9:this.$=a[s-1];break;case 11:r.commit(a[s]);break;case 12:r.branch(a[s]);break;case 13:r.checkout(a[s]);break;case 14:r.merge(a[s]);break;case 15:r.reset(a[s]);break;case 16:this.$="";break;case 17:this.$=a[s];break;case 18:this.$=a[s-1]+":"+a[s];break;case 19:this.$=a[s-1]+":"+r.count,r.count=0;break;case 20:r.count=0;break;case 21:r.count+=1}},table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3],8:[1,4]},{6:5,7:e,9:6,12:n},{5:[1,8]},{7:[1,9]},t(r,[2,7],{10:10,11:[1,11]}),t(i,[2,6]),{6:12,7:e,9:6,12:n},{1:[2,1]},{7:[2,4],12:[1,15],13:13,14:14,15:[1,16],17:[1,17],19:[1,18],20:[1,19],21:[1,20]},t(i,[2,5]),{7:[1,21]},t(r,[2,8]),{12:[1,22]},t(r,[2,10]),{12:[2,16],16:23,23:[1,24]},{18:[1,25]},{18:[1,26]},{18:[1,27]},{18:[1,30],22:28,24:[1,29]},{1:[2,2]},t(r,[2,9]),{12:[2,11]},{12:[2,17]},{12:[2,12]},{12:[2,13]},{12:[2,14]},{12:[2,15]},{12:a,25:31,26:o},{12:a,25:33,26:o},{12:[2,18]},{12:a,25:34,26:o},{12:[2,19]},{12:[2,21]}],defaultActions:{9:[2,1],21:[2,2],23:[2,11],24:[2,17],25:[2,12],26:[2,13],27:[2,14],28:[2,15],31:[2,18],33:[2,19],34:[2,21]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var v=p.yylloc;a.push(v);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var x,_,k,w,E,T,C,S,A,M={};;){if(k=n[n.length-1],this.defaultActions[k]?w=this.defaultActions[k]:(null==x&&(x=b()),w=o[k]&&o[k][x]),void 0===w||!w.length||!w[0]){var O="";for(T in A=[],o[k])this.terminals_[T]&&T>h&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},c={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return 12;case 1:case 2:case 3:break;case 4:return 4;case 5:return 15;case 6:return 17;case 7:return 20;case 8:return 21;case 9:return 19;case 10:case 11:return 8;case 12:return 5;case 13:return 26;case 14:this.begin("options");break;case 15:this.popState();break;case 16:return 11;case 17:this.begin("string");break;case 18:this.popState();break;case 19:return 23;case 20:return 18;case 21:return 7}},rules:[/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit\b)/i,/^(?:branch\b)/i,/^(?:merge\b)/i,/^(?:reset\b)/i,/^(?:checkout\b)/i,/^(?:LR\b)/i,/^(?:BT\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:end\r?\n)/i,/^(?:[^\n]+\r?\n)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[a-zA-Z][-_\.a-zA-Z0-9]*[-_a-zA-Z0-9])/i,/^(?:$)/i],conditions:{options:{rules:[15,16],inclusive:!1},string:{rules:[18,19],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,20,21],inclusive:!0}}};function u(){this.yy={}}return s.lexer=c,u.prototype=s,s.Parser=u,new u}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(19).readFileSync(n(20).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(14),n(7)(t))},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[6,9,10],n={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1]],performAction:function(t,e,n,r,i,a,o){a.length;switch(i){case 1:return r;case 4:break;case 6:r.setInfo(!0)}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},t(e,[2,3]),t(e,[2,4]),t(e,[2,5]),t(e,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var v=p.yylloc;a.push(v);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var x,_,k,w,E,T,C,S,A,M={};;){if(k=n[n.length-1],this.defaultActions[k]?w=this.defaultActions[k]:(null==x&&(x=b()),w=o[k]&&o[k][x]),void 0===w||!w.length||!w[0]){var O="";for(T in A=[],o[k])this.terminals_[T]&&T>h&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},r={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return 4;case 1:return 9;case 2:return"space";case 3:return 10;case 4:return 6;case 5:return"TXT"}},rules:[/^(?:info\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:showInfo\b)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5],inclusive:!0}}};function i(){this.yy={}}return n.lexer=r,i.prototype=n,n.Parser=i,new i}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(19).readFileSync(n(20).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(14),n(7)(t))},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,4],n=[1,5],r=[1,6],i=[1,7],a=[1,9],o=[1,10,12,19,20,21,22],s=[1,6,10,12,19,20,21,22],c=[19,20,21],u=[1,22],l=[6,19,20,21,22],h={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,directive:5,PIE:6,document:7,line:8,statement:9,txt:10,value:11,title:12,title_value:13,openDirective:14,typeDirective:15,closeDirective:16,":":17,argDirective:18,NEWLINE:19,";":20,EOF:21,open_directive:22,type_directive:23,arg_directive:24,close_directive:25,$accept:0,$end:1},terminals_:{2:"error",6:"PIE",10:"txt",11:"value",12:"title",13:"title_value",17:":",19:"NEWLINE",20:";",21:"EOF",22:"open_directive",23:"type_directive",24:"arg_directive",25:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[9,0],[9,2],[9,2],[9,1],[5,3],[5,5],[4,1],[4,1],[4,1],[14,1],[15,1],[18,1],[16,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 6:this.$=a[s-1];break;case 8:r.addSection(a[s-1],r.cleanupValue(a[s]));break;case 9:this.$=a[s].trim(),r.setTitle(this.$);break;case 16:r.parseDirective("%%{","open_directive");break;case 17:r.parseDirective(a[s],"type_directive");break;case 18:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 19:r.parseDirective("}%%","close_directive","pie")}},table:[{3:1,4:2,5:3,6:e,14:8,19:n,20:r,21:i,22:a},{1:[3]},{3:10,4:2,5:3,6:e,14:8,19:n,20:r,21:i,22:a},{3:11,4:2,5:3,6:e,14:8,19:n,20:r,21:i,22:a},t(o,[2,4],{7:12}),t(s,[2,13]),t(s,[2,14]),t(s,[2,15]),{15:13,23:[1,14]},{23:[2,16]},{1:[2,1]},{1:[2,2]},t(c,[2,7],{14:8,8:15,9:16,5:19,1:[2,3],10:[1,17],12:[1,18],22:a}),{16:20,17:[1,21],25:u},t([17,25],[2,17]),t(o,[2,5]),{4:23,19:n,20:r,21:i},{11:[1,24]},{13:[1,25]},t(c,[2,10]),t(l,[2,11]),{18:26,24:[1,27]},t(l,[2,19]),t(o,[2,6]),t(c,[2,8]),t(c,[2,9]),{16:28,25:u},{25:[2,18]},t(l,[2,12])],defaultActions:{9:[2,16],10:[2,1],11:[2,2],27:[2,18]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var v=p.yylloc;a.push(v);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var x,_,k,w,E,T,C,S,A,M={};;){if(k=n[n.length-1],this.defaultActions[k]?w=this.defaultActions[k]:(null==x&&(x=b()),w=o[k]&&o[k][x]),void 0===w||!w.length||!w[0]){var O="";for(T in A=[],o[k])this.terminals_[T]&&T>h&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},f={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),22;case 1:return this.begin("type_directive"),23;case 2:return this.popState(),this.begin("arg_directive"),17;case 3:return this.popState(),this.popState(),25;case 4:return 24;case 5:case 6:break;case 7:return 19;case 8:case 9:break;case 10:return this.begin("title"),12;case 11:return this.popState(),"title_value";case 12:this.begin("string");break;case 13:this.popState();break;case 14:return"txt";case 15:return 6;case 16:return"value";case 17:return 21}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:[\s]+)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:pie\b)/i,/^(?::[\s]*[\d]+(?:\.[\d]+)?)/i,/^(?:$)/i],conditions:{close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},title:{rules:[11],inclusive:!1},string:{rules:[13,14],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,12,15,16,17],inclusive:!0}}};function d(){this.yy={}}return h.lexer=f,d.prototype=h,h.Parser=d,new d}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(19).readFileSync(n(20).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(14),n(7)(t))},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,2],n=[1,5],r=[6,9,11,20,30],i=[1,17],a=[1,20],o=[1,24],s=[1,25],c=[1,26],u=[1,27],l=[20,27,28],h=[4,6,9,11,20,30],f=[23,24,25,26],d={trace:function(){},yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,entityName:17,relSpec:18,role:19,ALPHANUM:20,cardinality:21,relType:22,ZERO_OR_ONE:23,ZERO_OR_MORE:24,ONE_OR_MORE:25,ONLY_ONE:26,NON_IDENTIFYING:27,IDENTIFYING:28,WORD:29,open_directive:30,type_directive:31,arg_directive:32,close_directive:33,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",20:"ALPHANUM",23:"ZERO_OR_ONE",24:"ZERO_OR_MORE",25:"ONE_OR_MORE",26:"ONLY_ONE",27:"NON_IDENTIFYING",28:"IDENTIFYING",29:"WORD",30:"open_directive",31:"type_directive",32:"arg_directive",33:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,5],[10,1],[17,1],[18,3],[21,1],[21,1],[21,1],[21,1],[22,1],[22,1],[19,1],[19,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 1:break;case 3:this.$=[];break;case 4:a[s-1].push(a[s]),this.$=a[s-1];break;case 5:case 6:this.$=a[s];break;case 7:case 8:this.$=[];break;case 12:r.addEntity(a[s-4]),r.addEntity(a[s-2]),r.addRelationship(a[s-4],a[s],a[s-2],a[s-3]);break;case 13:r.addEntity(a[s]);break;case 14:this.$=a[s];break;case 15:this.$={cardA:a[s],relType:a[s-1],cardB:a[s-2]};break;case 16:this.$=r.Cardinality.ZERO_OR_ONE;break;case 17:this.$=r.Cardinality.ZERO_OR_MORE;break;case 18:this.$=r.Cardinality.ONE_OR_MORE;break;case 19:this.$=r.Cardinality.ONLY_ONE;break;case 20:this.$=r.Identification.NON_IDENTIFYING;break;case 21:this.$=r.Identification.IDENTIFYING;break;case 22:this.$=a[s].replace(/"/g,"");break;case 23:this.$=a[s];break;case 24:r.parseDirective("%%{","open_directive");break;case 25:r.parseDirective(a[s],"type_directive");break;case 26:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 27:r.parseDirective("}%%","close_directive","er")}},table:[{3:1,4:e,7:3,12:4,30:n},{1:[3]},t(r,[2,3],{5:6}),{3:7,4:e,7:3,12:4,30:n},{13:8,31:[1,9]},{31:[2,24]},{6:[1,10],7:15,8:11,9:[1,12],10:13,11:[1,14],12:4,17:16,20:i,30:n},{1:[2,2]},{14:18,15:[1,19],33:a},t([15,33],[2,25]),t(r,[2,8],{1:[2,1]}),t(r,[2,4]),{7:15,10:21,12:4,17:16,20:i,30:n},t(r,[2,6]),t(r,[2,7]),t(r,[2,11]),t(r,[2,13],{18:22,21:23,23:o,24:s,25:c,26:u}),t([6,9,11,15,20,23,24,25,26,30],[2,14]),{11:[1,28]},{16:29,32:[1,30]},{11:[2,27]},t(r,[2,5]),{17:31,20:i},{22:32,27:[1,33],28:[1,34]},t(l,[2,16]),t(l,[2,17]),t(l,[2,18]),t(l,[2,19]),t(h,[2,9]),{14:35,33:a},{33:[2,26]},{15:[1,36]},{21:37,23:o,24:s,25:c,26:u},t(f,[2,20]),t(f,[2,21]),{11:[1,38]},{19:39,20:[1,41],29:[1,40]},{20:[2,15]},t(h,[2,10]),t(r,[2,12]),t(r,[2,22]),t(r,[2,23])],defaultActions:{5:[2,24],7:[2,2],20:[2,27],30:[2,26],37:[2,15]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var v=p.yylloc;a.push(v);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var x,_,k,w,E,T,C,S,A,M={};;){if(k=n[n.length-1],this.defaultActions[k]?w=this.defaultActions[k]:(null==x&&(x=b()),w=o[k]&&o[k][x]),void 0===w||!w.length||!w[0]){var O="";for(T in A=[],o[k])this.terminals_[T]&&T>h&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},p={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),30;case 1:return this.begin("type_directive"),31;case 2:return this.popState(),this.begin("arg_directive"),15;case 3:return this.popState(),this.popState(),33;case 4:return 32;case 5:case 6:break;case 7:return 11;case 8:break;case 9:return 9;case 10:return 29;case 11:return 4;case 12:return 23;case 13:return 24;case 14:return 25;case 15:return 26;case 16:return 23;case 17:return 24;case 18:return 25;case 19:return 27;case 20:return 28;case 21:case 22:return 27;case 23:return 20;case 24:return e.yytext[0];case 25:return 6}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\|o\b)/i,/^(?:\}o\b)/i,/^(?:\}\|)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:[A-Za-z][A-Za-z0-9\-_]*)/i,/^(?:.)/i,/^(?:$)/i],conditions:{open_directive:{rules:[1],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],inclusive:!0}}};function g(){this.yy={}}return d.lexer=p,g.prototype=d,d.Parser=g,new g}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(19).readFileSync(n(20).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(14),n(7)(t))},function(t,e,n){"use strict";var r;Object.defineProperty(e,"__esModule",{value:!0}),function(t){t[t.ALL=0]="ALL",t[t.RGB=1]="RGB",t[t.HSL=2]="HSL"}(r||(r={})),e.TYPE=r},function(t,e,n){"use strict";var r=n(10);t.exports=i;function i(t){this._isDirected=!r.has(t,"directed")||t.directed,this._isMultigraph=!!r.has(t,"multigraph")&&t.multigraph,this._isCompound=!!r.has(t,"compound")&&t.compound,this._label=void 0,this._defaultNodeLabelFn=r.constant(void 0),this._defaultEdgeLabelFn=r.constant(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children["\0"]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}function a(t,e){t[e]?t[e]++:t[e]=1}function o(t,e){--t[e]||delete t[e]}function s(t,e,n,i){var a=""+e,o=""+n;if(!t&&a>o){var s=a;a=o,o=s}return a+""+o+""+(r.isUndefined(i)?"\0":i)}function c(t,e,n,r){var i=""+e,a=""+n;if(!t&&i>a){var o=i;i=a,a=o}var s={v:i,w:a};return r&&(s.name=r),s}function u(t,e){return s(t,e.v,e.w,e.name)}i.prototype._nodeCount=0,i.prototype._edgeCount=0,i.prototype.isDirected=function(){return this._isDirected},i.prototype.isMultigraph=function(){return this._isMultigraph},i.prototype.isCompound=function(){return this._isCompound},i.prototype.setGraph=function(t){return this._label=t,this},i.prototype.graph=function(){return this._label},i.prototype.setDefaultNodeLabel=function(t){return r.isFunction(t)||(t=r.constant(t)),this._defaultNodeLabelFn=t,this},i.prototype.nodeCount=function(){return this._nodeCount},i.prototype.nodes=function(){return r.keys(this._nodes)},i.prototype.sources=function(){var t=this;return r.filter(this.nodes(),(function(e){return r.isEmpty(t._in[e])}))},i.prototype.sinks=function(){var t=this;return r.filter(this.nodes(),(function(e){return r.isEmpty(t._out[e])}))},i.prototype.setNodes=function(t,e){var n=arguments,i=this;return r.each(t,(function(t){n.length>1?i.setNode(t,e):i.setNode(t)})),this},i.prototype.setNode=function(t,e){return r.has(this._nodes,t)?(arguments.length>1&&(this._nodes[t]=e),this):(this._nodes[t]=arguments.length>1?e:this._defaultNodeLabelFn(t),this._isCompound&&(this._parent[t]="\0",this._children[t]={},this._children["\0"][t]=!0),this._in[t]={},this._preds[t]={},this._out[t]={},this._sucs[t]={},++this._nodeCount,this)},i.prototype.node=function(t){return this._nodes[t]},i.prototype.hasNode=function(t){return r.has(this._nodes,t)},i.prototype.removeNode=function(t){var e=this;if(r.has(this._nodes,t)){var n=function(t){e.removeEdge(e._edgeObjs[t])};delete this._nodes[t],this._isCompound&&(this._removeFromParentsChildList(t),delete this._parent[t],r.each(this.children(t),(function(t){e.setParent(t)})),delete this._children[t]),r.each(r.keys(this._in[t]),n),delete this._in[t],delete this._preds[t],r.each(r.keys(this._out[t]),n),delete this._out[t],delete this._sucs[t],--this._nodeCount}return this},i.prototype.setParent=function(t,e){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(r.isUndefined(e))e="\0";else{for(var n=e+="";!r.isUndefined(n);n=this.parent(n))if(n===t)throw new Error("Setting "+e+" as parent of "+t+" would create a cycle");this.setNode(e)}return this.setNode(t),this._removeFromParentsChildList(t),this._parent[t]=e,this._children[e][t]=!0,this},i.prototype._removeFromParentsChildList=function(t){delete this._children[this._parent[t]][t]},i.prototype.parent=function(t){if(this._isCompound){var e=this._parent[t];if("\0"!==e)return e}},i.prototype.children=function(t){if(r.isUndefined(t)&&(t="\0"),this._isCompound){var e=this._children[t];if(e)return r.keys(e)}else{if("\0"===t)return this.nodes();if(this.hasNode(t))return[]}},i.prototype.predecessors=function(t){var e=this._preds[t];if(e)return r.keys(e)},i.prototype.successors=function(t){var e=this._sucs[t];if(e)return r.keys(e)},i.prototype.neighbors=function(t){var e=this.predecessors(t);if(e)return r.union(e,this.successors(t))},i.prototype.isLeaf=function(t){return 0===(this.isDirected()?this.successors(t):this.neighbors(t)).length},i.prototype.filterNodes=function(t){var e=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});e.setGraph(this.graph());var n=this;r.each(this._nodes,(function(n,r){t(r)&&e.setNode(r,n)})),r.each(this._edgeObjs,(function(t){e.hasNode(t.v)&&e.hasNode(t.w)&&e.setEdge(t,n.edge(t))}));var i={};return this._isCompound&&r.each(e.nodes(),(function(t){e.setParent(t,function t(r){var a=n.parent(r);return void 0===a||e.hasNode(a)?(i[r]=a,a):a in i?i[a]:t(a)}(t))})),e},i.prototype.setDefaultEdgeLabel=function(t){return r.isFunction(t)||(t=r.constant(t)),this._defaultEdgeLabelFn=t,this},i.prototype.edgeCount=function(){return this._edgeCount},i.prototype.edges=function(){return r.values(this._edgeObjs)},i.prototype.setPath=function(t,e){var n=this,i=arguments;return r.reduce(t,(function(t,r){return i.length>1?n.setEdge(t,r,e):n.setEdge(t,r),r})),this},i.prototype.setEdge=function(){var t,e,n,i,o=!1,u=arguments[0];"object"==typeof u&&null!==u&&"v"in u?(t=u.v,e=u.w,n=u.name,2===arguments.length&&(i=arguments[1],o=!0)):(t=u,e=arguments[1],n=arguments[3],arguments.length>2&&(i=arguments[2],o=!0)),t=""+t,e=""+e,r.isUndefined(n)||(n=""+n);var l=s(this._isDirected,t,e,n);if(r.has(this._edgeLabels,l))return o&&(this._edgeLabels[l]=i),this;if(!r.isUndefined(n)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(t),this.setNode(e),this._edgeLabels[l]=o?i:this._defaultEdgeLabelFn(t,e,n);var h=c(this._isDirected,t,e,n);return t=h.v,e=h.w,Object.freeze(h),this._edgeObjs[l]=h,a(this._preds[e],t),a(this._sucs[t],e),this._in[e][l]=h,this._out[t][l]=h,this._edgeCount++,this},i.prototype.edge=function(t,e,n){var r=1===arguments.length?u(this._isDirected,arguments[0]):s(this._isDirected,t,e,n);return this._edgeLabels[r]},i.prototype.hasEdge=function(t,e,n){var i=1===arguments.length?u(this._isDirected,arguments[0]):s(this._isDirected,t,e,n);return r.has(this._edgeLabels,i)},i.prototype.removeEdge=function(t,e,n){var r=1===arguments.length?u(this._isDirected,arguments[0]):s(this._isDirected,t,e,n),i=this._edgeObjs[r];return i&&(t=i.v,e=i.w,delete this._edgeLabels[r],delete this._edgeObjs[r],o(this._preds[e],t),o(this._sucs[t],e),delete this._in[e][r],delete this._out[t][r],this._edgeCount--),this},i.prototype.inEdges=function(t,e){var n=this._in[t];if(n){var i=r.values(n);return e?r.filter(i,(function(t){return t.v===e})):i}},i.prototype.outEdges=function(t,e){var n=this._out[t];if(n){var i=r.values(n);return e?r.filter(i,(function(t){return t.w===e})):i}},i.prototype.nodeEdges=function(t,e){var n=this.inEdges(t,e);if(n)return n.concat(this.outEdges(t,e))}},function(t,e,n){var r=n(33)(n(16),"Map");t.exports=r},function(t,e,n){var r=n(217),i=n(224),a=n(226),o=n(227),s=n(228);function c(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&t<=9007199254740991}},function(t,e,n){(function(t){var r=n(109),i=e&&!e.nodeType&&e,a=i&&"object"==typeof t&&t&&!t.nodeType&&t,o=a&&a.exports===i&&r.process,s=function(){try{var t=a&&a.require&&a.require("util").types;return t||o&&o.binding&&o.binding("util")}catch(t){}}();t.exports=s}).call(this,n(7)(t))},function(t,e,n){var r=n(62),i=n(234),a=Object.prototype.hasOwnProperty;t.exports=function(t){if(!r(t))return i(t);var e=[];for(var n in Object(t))a.call(t,n)&&"constructor"!=n&&e.push(n);return e}},function(t,e,n){var r=n(116),i=n(117),a=Object.prototype.propertyIsEnumerable,o=Object.getOwnPropertySymbols,s=o?function(t){return null==t?[]:(t=Object(t),r(o(t),(function(e){return a.call(t,e)})))}:i;t.exports=s},function(t,e){t.exports=function(t,e){for(var n=-1,r=e.length,i=t.length;++n0&&a(l)?n>1?t(l,n-1,a,o,s):r(s,l):o||(s[s.length]=l)}return s}},function(t,e,n){var r=n(42);t.exports=function(t,e,n){for(var i=-1,a=t.length;++i4,u=c?1:17,l=c?8:4,h=s?0:-1,f=c?255:15;return i.default.set({r:(r>>l*(h+3)&f)*u,g:(r>>l*(h+2)&f)*u,b:(r>>l*(h+1)&f)*u,a:s?(r&f)*u/255:1},t)}}},stringify:function(t){return t.a<1?"#"+a.DEC2HEX[Math.round(t.r)]+a.DEC2HEX[Math.round(t.g)]+a.DEC2HEX[Math.round(t.b)]+r.default.unit.frac2hex(t.a):"#"+a.DEC2HEX[Math.round(t.r)]+a.DEC2HEX[Math.round(t.g)]+a.DEC2HEX[Math.round(t.b)]}};e.default=o},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(9),i=n(45),a=n(15);e.default=function(t,e,n,o){void 0===o&&(o=1);var s=i.default.set({h:r.default.channel.clamp.h(t),s:r.default.channel.clamp.s(e),l:r.default.channel.clamp.l(n),a:r.default.channel.clamp.a(o)});return a.default.stringify(s)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(29);e.default=function(t){return r.default(t,"a")}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(9),i=n(15);e.default=function(t){var e=i.default.parse(t),n=e.r,a=e.g,o=e.b,s=.2126*r.default.channel.toLinear(n)+.7152*r.default.channel.toLinear(a)+.0722*r.default.channel.toLinear(o);return r.default.lang.round(s)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(102);e.default=function(t){return r.default(t)>=.5}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(32);e.default=function(t,e){return r.default(t,"a",e)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(32);e.default=function(t,e){return r.default(t,"a",-e)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(15),i=n(52);e.default=function(t,e){var n=r.default.parse(t),a={};for(var o in e)e[o]&&(a[o]=n[o]+e[o]);return i.default(t,a)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(15),i=n(51);e.default=function(t,e,n){void 0===n&&(n=50);var a=r.default.parse(t),o=a.r,s=a.g,c=a.b,u=a.a,l=r.default.parse(e),h=l.r,f=l.g,d=l.b,p=l.a,g=n/100,y=2*g-1,v=u-p,m=((y*v==-1?y:(y+v)/(1+y*v))+1)/2,b=1-m,x=o*m+h*b,_=s*m+f*b,k=c*m+d*b,w=u*g+p*(1-g);return i.default(x,_,k,w)}},function(t,e,n){var r=n(53),i=n(79),a=n(58),o=n(229),s=n(235),c=n(114),u=n(115),l=n(238),h=n(239),f=n(119),d=n(240),p=n(41),g=n(244),y=n(245),v=n(124),m=n(5),b=n(39),x=n(249),_=n(11),k=n(251),w=n(30),E={};E["[object Arguments]"]=E["[object Array]"]=E["[object ArrayBuffer]"]=E["[object DataView]"]=E["[object Boolean]"]=E["[object Date]"]=E["[object Float32Array]"]=E["[object Float64Array]"]=E["[object Int8Array]"]=E["[object Int16Array]"]=E["[object Int32Array]"]=E["[object Map]"]=E["[object Number]"]=E["[object Object]"]=E["[object RegExp]"]=E["[object Set]"]=E["[object String]"]=E["[object Symbol]"]=E["[object Uint8Array]"]=E["[object Uint8ClampedArray]"]=E["[object Uint16Array]"]=E["[object Uint32Array]"]=!0,E["[object Error]"]=E["[object Function]"]=E["[object WeakMap]"]=!1,t.exports=function t(e,n,T,C,S,A){var M,O=1&n,D=2&n,N=4&n;if(T&&(M=S?T(e,C,S,A):T(e)),void 0!==M)return M;if(!_(e))return e;var B=m(e);if(B){if(M=g(e),!O)return u(e,M)}else{var L=p(e),F="[object Function]"==L||"[object GeneratorFunction]"==L;if(b(e))return c(e,O);if("[object Object]"==L||"[object Arguments]"==L||F&&!S){if(M=D||F?{}:v(e),!O)return D?h(e,s(M,e)):l(e,o(M,e))}else{if(!E[L])return S?e:{};M=y(e,L,O)}}A||(A=new r);var P=A.get(e);if(P)return P;A.set(e,M),k(e)?e.forEach((function(r){M.add(t(r,n,T,r,e,A))})):x(e)&&e.forEach((function(r,i){M.set(i,t(r,n,T,i,e,A))}));var I=N?D?d:f:D?keysIn:w,j=B?void 0:I(e);return i(j||e,(function(r,i){j&&(r=e[i=r]),a(M,i,t(r,n,T,i,e,A))})),M}},function(t,e,n){(function(e){var n="object"==typeof e&&e&&e.Object===Object&&e;t.exports=n}).call(this,n(211))},function(t,e){var n=Function.prototype.toString;t.exports=function(t){if(null!=t){try{return n.call(t)}catch(t){}try{return t+""}catch(t){}}return""}},function(t,e,n){var r=n(33),i=function(){try{var t=r(Object,"defineProperty");return t({},"",{}),t}catch(t){}}();t.exports=i},function(t,e,n){var r=n(230),i=n(47),a=n(5),o=n(39),s=n(60),c=n(48),u=Object.prototype.hasOwnProperty;t.exports=function(t,e){var n=a(t),l=!n&&i(t),h=!n&&!l&&o(t),f=!n&&!l&&!h&&c(t),d=n||l||h||f,p=d?r(t.length,String):[],g=p.length;for(var y in t)!e&&!u.call(t,y)||d&&("length"==y||h&&("offset"==y||"parent"==y)||f&&("buffer"==y||"byteLength"==y||"byteOffset"==y)||s(y,g))||p.push(y);return p}},function(t,e){t.exports=function(t,e){return function(n){return t(e(n))}}},function(t,e,n){(function(t){var r=n(16),i=e&&!e.nodeType&&e,a=i&&"object"==typeof t&&t&&!t.nodeType&&t,o=a&&a.exports===i?r.Buffer:void 0,s=o?o.allocUnsafe:void 0;t.exports=function(t,e){if(e)return t.slice();var n=t.length,r=s?s(n):new t.constructor(n);return t.copy(r),r}}).call(this,n(7)(t))},function(t,e){t.exports=function(t,e){var n=-1,r=t.length;for(e||(e=Array(r));++nl))return!1;var f=c.get(t);if(f&&c.get(e))return f==e;var d=-1,p=!0,g=2&n?new r:void 0;for(c.set(t,e),c.set(e,t);++d0&&(a=c.removeMin(),(o=s[a]).distance!==Number.POSITIVE_INFINITY);)r(a).forEach(u);return s}(t,String(e),n||a,r||function(e){return t.outEdges(e)})};var a=r.constant(1)},function(t,e,n){var r=n(10);function i(){this._arr=[],this._keyIndices={}}t.exports=i,i.prototype.size=function(){return this._arr.length},i.prototype.keys=function(){return this._arr.map((function(t){return t.key}))},i.prototype.has=function(t){return r.has(this._keyIndices,t)},i.prototype.priority=function(t){var e=this._keyIndices[t];if(void 0!==e)return this._arr[e].priority},i.prototype.min=function(){if(0===this.size())throw new Error("Queue underflow");return this._arr[0].key},i.prototype.add=function(t,e){var n=this._keyIndices;if(t=String(t),!r.has(n,t)){var i=this._arr,a=i.length;return n[t]=a,i.push({key:t,priority:e}),this._decrease(a),!0}return!1},i.prototype.removeMin=function(){this._swap(0,this._arr.length-1);var t=this._arr.pop();return delete this._keyIndices[t.key],this._heapify(0),t.key},i.prototype.decrease=function(t,e){var n=this._keyIndices[t];if(e>this._arr[n].priority)throw new Error("New priority is greater than current priority. Key: "+t+" Old: "+this._arr[n].priority+" New: "+e);this._arr[n].priority=e,this._decrease(n)},i.prototype._heapify=function(t){var e=this._arr,n=2*t,r=n+1,i=t;n>1].priority2?e[2]:void 0;for(u&&a(e[0],e[1],u)&&(r=1);++n1&&o.sort((function(t,e){var r=t.x-n.x,i=t.y-n.y,a=Math.sqrt(r*r+i*i),o=e.x-n.x,s=e.y-n.y,c=Math.sqrt(o*o+s*s);return aMath.abs(o)*u?(s<0&&(u=-u),n=0===s?0:u*o/s,r=u):(o<0&&(c=-c),n=c,r=0===o?0:c*s/o);return{x:i+n,y:a+r}}},function(t,e,n){t.exports=function t(e){"use strict";var n=/^\0+/g,r=/[\0\r\f]/g,i=/: */g,a=/zoo|gra/,o=/([,: ])(transform)/g,s=/,+\s*(?![^(]*[)])/g,c=/ +\s*(?![^(]*[)])/g,u=/ *[\0] */g,l=/,\r+?/g,h=/([\t\r\n ])*\f?&/g,f=/:global\(((?:[^\(\)\[\]]*|\[.*\]|\([^\(\)]*\))*)\)/g,d=/\W+/g,p=/@(k\w+)\s*(\S*)\s*/,g=/::(place)/g,y=/:(read-only)/g,v=/\s+(?=[{\];=:>])/g,m=/([[}=:>])\s+/g,b=/(\{[^{]+?);(?=\})/g,x=/\s{2,}/g,_=/([^\(])(:+) */g,k=/[svh]\w+-[tblr]{2}/,w=/\(\s*(.*)\s*\)/g,E=/([\s\S]*?);/g,T=/-self|flex-/g,C=/[^]*?(:[rp][el]a[\w-]+)[^]*/,S=/stretch|:\s*\w+\-(?:conte|avail)/,A=/([^-])(image-set\()/,M="-webkit-",O="-moz-",D="-ms-",N=1,B=1,L=0,F=1,P=1,I=1,j=0,R=0,Y=0,z=[],U=[],$=0,W=null,V=0,H=1,G="",q="",X="";function Z(t,e,i,a,o){for(var s,c,l=0,h=0,f=0,d=0,v=0,m=0,b=0,x=0,k=0,E=0,T=0,C=0,S=0,A=0,O=0,D=0,j=0,U=0,W=0,Q=i.length,it=Q-1,at="",ot="",st="",ct="",ut="",lt="";O0&&(ot=ot.replace(r,"")),ot.trim().length>0)){switch(b){case 32:case 9:case 59:case 13:case 10:break;default:ot+=i.charAt(O)}b=59}if(1===j)switch(b){case 123:case 125:case 59:case 34:case 39:case 40:case 41:case 44:j=0;case 9:case 13:case 10:case 32:break;default:for(j=0,W=O,v=b,O--,b=59;W0&&(++O,b=v);case 123:W=Q}}switch(b){case 123:for(v=(ot=ot.trim()).charCodeAt(0),T=1,W=++O;O0&&(ot=ot.replace(r,"")),m=ot.charCodeAt(1)){case 100:case 109:case 115:case 45:s=e;break;default:s=z}if(W=(st=Z(e,s,st,m,o+1)).length,Y>0&&0===W&&(W=ot.length),$>0&&(c=nt(3,st,s=J(z,ot,U),e,B,N,W,m,o,a),ot=s.join(""),void 0!==c&&0===(W=(st=c.trim()).length)&&(m=0,st="")),W>0)switch(m){case 115:ot=ot.replace(w,et);case 100:case 109:case 45:st=ot+"{"+st+"}";break;case 107:st=(ot=ot.replace(p,"$1 $2"+(H>0?G:"")))+"{"+st+"}",st=1===P||2===P&&tt("@"+st,3)?"@"+M+st+"@"+st:"@"+st;break;default:st=ot+st,112===a&&(ct+=st,st="")}else st="";break;default:st=Z(e,J(e,ot,U),st,a,o+1)}ut+=st,C=0,j=0,A=0,D=0,U=0,S=0,ot="",st="",b=i.charCodeAt(++O);break;case 125:case 59:if((W=(ot=(D>0?ot.replace(r,""):ot).trim()).length)>1)switch(0===A&&(45===(v=ot.charCodeAt(0))||v>96&&v<123)&&(W=(ot=ot.replace(" ",":")).length),$>0&&void 0!==(c=nt(1,ot,e,t,B,N,ct.length,a,o,a))&&0===(W=(ot=c.trim()).length)&&(ot="\0\0"),v=ot.charCodeAt(0),m=ot.charCodeAt(1),v){case 0:break;case 64:if(105===m||99===m){lt+=ot+i.charAt(O);break}default:if(58===ot.charCodeAt(W-1))break;ct+=K(ot,v,m,ot.charCodeAt(2))}C=0,j=0,A=0,D=0,U=0,ot="",b=i.charCodeAt(++O)}}switch(b){case 13:case 10:if(h+d+f+l+R===0)switch(E){case 41:case 39:case 34:case 64:case 126:case 62:case 42:case 43:case 47:case 45:case 58:case 44:case 59:case 123:case 125:break;default:A>0&&(j=1)}47===h?h=0:F+C===0&&107!==a&&ot.length>0&&(D=1,ot+="\0"),$*V>0&&nt(0,ot,e,t,B,N,ct.length,a,o,a),N=1,B++;break;case 59:case 125:if(h+d+f+l===0){N++;break}default:switch(N++,at=i.charAt(O),b){case 9:case 32:if(d+l+h===0)switch(x){case 44:case 58:case 9:case 32:at="";break;default:32!==b&&(at=" ")}break;case 0:at="\\0";break;case 12:at="\\f";break;case 11:at="\\v";break;case 38:d+h+l===0&&F>0&&(U=1,D=1,at="\f"+at);break;case 108:if(d+h+l+L===0&&A>0)switch(O-A){case 2:112===x&&58===i.charCodeAt(O-3)&&(L=x);case 8:111===k&&(L=k)}break;case 58:d+h+l===0&&(A=O);break;case 44:h+f+d+l===0&&(D=1,at+="\r");break;case 34:case 39:0===h&&(d=d===b?0:0===d?b:d);break;case 91:d+h+f===0&&l++;break;case 93:d+h+f===0&&l--;break;case 41:d+h+l===0&&f--;break;case 40:if(d+h+l===0){if(0===C)switch(2*x+3*k){case 533:break;default:T=0,C=1}f++}break;case 64:h+f+d+l+A+S===0&&(S=1);break;case 42:case 47:if(d+l+f>0)break;switch(h){case 0:switch(2*b+3*i.charCodeAt(O+1)){case 235:h=47;break;case 220:W=O,h=42}break;case 42:47===b&&42===x&&W+2!==O&&(33===i.charCodeAt(W+2)&&(ct+=i.substring(W,O+1)),at="",h=0)}}if(0===h){if(F+d+l+S===0&&107!==a&&59!==b)switch(b){case 44:case 126:case 62:case 43:case 41:case 40:if(0===C){switch(x){case 9:case 32:case 10:case 13:at+="\0";break;default:at="\0"+at+(44===b?"":"\0")}D=1}else switch(b){case 40:A+7===O&&108===x&&(A=0),C=++T;break;case 41:0==(C=--T)&&(D=1,at+="\0")}break;case 9:case 32:switch(x){case 0:case 123:case 125:case 59:case 44:case 12:case 9:case 32:case 10:case 13:break;default:0===C&&(D=1,at+="\0")}}ot+=at,32!==b&&9!==b&&(E=b)}}k=x,x=b,O++}if(W=ct.length,Y>0&&0===W&&0===ut.length&&0===e[0].length==0&&(109!==a||1===e.length&&(F>0?q:X)===e[0])&&(W=e.join(",").length+2),W>0){if(s=0===F&&107!==a?function(t){for(var e,n,i=0,a=t.length,o=Array(a);i1)){if(f=c.charCodeAt(c.length-1),d=n.charCodeAt(0),e="",0!==l)switch(f){case 42:case 126:case 62:case 43:case 32:case 40:break;default:e=" "}switch(d){case 38:n=e+q;case 126:case 62:case 43:case 32:case 41:case 40:break;case 91:n=e+n+q;break;case 58:switch(2*n.charCodeAt(1)+3*n.charCodeAt(2)){case 530:if(I>0){n=e+n.substring(8,h-1);break}default:(l<1||s[l-1].length<1)&&(n=e+q+n)}break;case 44:e="";default:n=h>1&&n.indexOf(":")>0?e+n.replace(_,"$1"+q+"$2"):e+n+q}c+=n}o[i]=c.replace(r,"").trim()}return o}(e):e,$>0&&void 0!==(c=nt(2,ct,s,t,B,N,W,a,o,a))&&0===(ct=c).length)return lt+ct+ut;if(ct=s.join(",")+"{"+ct+"}",P*L!=0){switch(2!==P||tt(ct,2)||(L=0),L){case 111:ct=ct.replace(y,":-moz-$1")+ct;break;case 112:ct=ct.replace(g,"::-webkit-input-$1")+ct.replace(g,"::-moz-$1")+ct.replace(g,":-ms-input-$1")+ct}L=0}}return lt+ct+ut}function J(t,e,n){var r=e.trim().split(l),i=r,a=r.length,o=t.length;switch(o){case 0:case 1:for(var s=0,c=0===o?"":t[0]+" ";s0&&F>0)return i.replace(f,"$1").replace(h,"$1"+X);break;default:return t.trim()+i.replace(h,"$1"+t.trim())}default:if(n*F>0&&i.indexOf("\f")>0)return i.replace(h,(58===t.charCodeAt(0)?"":"$1")+t.trim())}return t+i}function K(t,e,n,r){var u,l=0,h=t+";",f=2*e+3*n+4*r;if(944===f)return function(t){var e=t.length,n=t.indexOf(":",9)+1,r=t.substring(0,n).trim(),i=t.substring(n,e-1).trim();switch(t.charCodeAt(9)*H){case 0:break;case 45:if(110!==t.charCodeAt(10))break;default:var a=i.split((i="",s)),o=0;for(n=0,e=a.length;o64&&h<90||h>96&&h<123||95===h||45===h&&45!==u.charCodeAt(1)))switch(isNaN(parseFloat(u))+(-1!==u.indexOf("("))){case 1:switch(u){case"infinite":case"alternate":case"backwards":case"running":case"normal":case"forwards":case"both":case"none":case"linear":case"ease":case"ease-in":case"ease-out":case"ease-in-out":case"paused":case"reverse":case"alternate-reverse":case"inherit":case"initial":case"unset":case"step-start":case"step-end":break;default:u+=G}}l[n++]=u}i+=(0===o?"":",")+l.join(" ")}}return i=r+i+";",1===P||2===P&&tt(i,1)?M+i+i:i}(h);if(0===P||2===P&&!tt(h,1))return h;switch(f){case 1015:return 97===h.charCodeAt(10)?M+h+h:h;case 951:return 116===h.charCodeAt(3)?M+h+h:h;case 963:return 110===h.charCodeAt(5)?M+h+h:h;case 1009:if(100!==h.charCodeAt(4))break;case 969:case 942:return M+h+h;case 978:return M+h+O+h+h;case 1019:case 983:return M+h+O+h+D+h+h;case 883:return 45===h.charCodeAt(8)?M+h+h:h.indexOf("image-set(",11)>0?h.replace(A,"$1-webkit-$2")+h:h;case 932:if(45===h.charCodeAt(4))switch(h.charCodeAt(5)){case 103:return M+"box-"+h.replace("-grow","")+M+h+D+h.replace("grow","positive")+h;case 115:return M+h+D+h.replace("shrink","negative")+h;case 98:return M+h+D+h.replace("basis","preferred-size")+h}return M+h+D+h+h;case 964:return M+h+D+"flex-"+h+h;case 1023:if(99!==h.charCodeAt(8))break;return u=h.substring(h.indexOf(":",15)).replace("flex-","").replace("space-between","justify"),M+"box-pack"+u+M+h+D+"flex-pack"+u+h;case 1005:return a.test(h)?h.replace(i,":"+M)+h.replace(i,":"+O)+h:h;case 1e3:switch(l=(u=h.substring(13).trim()).indexOf("-")+1,u.charCodeAt(0)+u.charCodeAt(l)){case 226:u=h.replace(k,"tb");break;case 232:u=h.replace(k,"tb-rl");break;case 220:u=h.replace(k,"lr");break;default:return h}return M+h+D+u+h;case 1017:if(-1===h.indexOf("sticky",9))return h;case 975:switch(l=(h=t).length-10,f=(u=(33===h.charCodeAt(l)?h.substring(0,l):h).substring(t.indexOf(":",7)+1).trim()).charCodeAt(0)+(0|u.charCodeAt(7))){case 203:if(u.charCodeAt(8)<111)break;case 115:h=h.replace(u,M+u)+";"+h;break;case 207:case 102:h=h.replace(u,M+(f>102?"inline-":"")+"box")+";"+h.replace(u,M+u)+";"+h.replace(u,D+u+"box")+";"+h}return h+";";case 938:if(45===h.charCodeAt(5))switch(h.charCodeAt(6)){case 105:return u=h.replace("-items",""),M+h+M+"box-"+u+D+"flex-"+u+h;case 115:return M+h+D+"flex-item-"+h.replace(T,"")+h;default:return M+h+D+"flex-line-pack"+h.replace("align-content","").replace(T,"")+h}break;case 973:case 989:if(45!==h.charCodeAt(3)||122===h.charCodeAt(4))break;case 931:case 953:if(!0===S.test(t))return 115===(u=t.substring(t.indexOf(":")+1)).charCodeAt(0)?K(t.replace("stretch","fill-available"),e,n,r).replace(":fill-available",":stretch"):h.replace(u,M+u)+h.replace(u,O+u.replace("fill-",""))+h;break;case 962:if(h=M+h+(102===h.charCodeAt(5)?D+h:"")+h,n+r===211&&105===h.charCodeAt(13)&&h.indexOf("transform",10)>0)return h.substring(0,h.indexOf(";",27)+1).replace(o,"$1-webkit-$2")+h}return h}function tt(t,e){var n=t.indexOf(1===e?":":"{"),r=t.substring(0,3!==e?n:10),i=t.substring(n+1,t.length-1);return W(2!==e?r:r.replace(C,"$1"),i,e)}function et(t,e){var n=K(e,e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2));return n!==e+";"?n.replace(E," or ($1)").substring(4):"("+e+")"}function nt(t,e,n,r,i,a,o,s,c,u){for(var l,h=0,f=e;h<$;++h)switch(l=U[h].call(at,t,f,n,r,i,a,o,s,c,u)){case void 0:case!1:case!0:case null:break;default:f=l}if(f!==e)return f}function rt(t,e,n,r){for(var i=e+1;i0&&(G=i.replace(d,91===a?"":"-")),a=1,1===F?X=i:q=i;var o,s=[X];$>0&&void 0!==(o=nt(-1,n,s,s,B,N,0,0,0,0))&&"string"==typeof o&&(n=o);var c=Z(z,s,n,0,0);return $>0&&void 0!==(o=nt(-2,c,s,s,B,N,c.length,0,0,0))&&"string"!=typeof(c=o)&&(a=0),G="",X="",q="",L=0,B=1,N=1,j*a==0?c:function(t){return t.replace(r,"").replace(v,"").replace(m,"$1").replace(b,"$1").replace(x," ")}(c)}return at.use=function t(e){switch(e){case void 0:case null:$=U.length=0;break;default:if("function"==typeof e)U[$++]=e;else if("object"==typeof e)for(var n=0,r=e.length;n=255?255:t<0?0:t},g:function(t){return t>=255?255:t<0?0:t},b:function(t){return t>=255?255:t<0?0:t},h:function(t){return t%360},s:function(t){return t>=100?100:t<0?0:t},l:function(t){return t>=100?100:t<0?0:t},a:function(t){return t>=1?1:t<0?0:t}},toLinear:function(t){var e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},hue2rgb:function(t,e,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?t+6*(e-t)*n:n<.5?e:n<2/3?t+(e-t)*(2/3-n)*6:t},hsl2rgb:function(t,e){var n=t.h,i=t.s,a=t.l;if(100===i)return 2.55*a;n/=360,i/=100;var o=(a/=100)<.5?a*(1+i):a+i-a*i,s=2*a-o;switch(e){case"r":return 255*r.hue2rgb(s,o,n+1/3);case"g":return 255*r.hue2rgb(s,o,n);case"b":return 255*r.hue2rgb(s,o,n-1/3)}},rgb2hsl:function(t,e){var n=t.r,r=t.g,i=t.b;n/=255,r/=255,i/=255;var a=Math.max(n,r,i),o=Math.min(n,r,i),s=(a+o)/2;if("l"===e)return 100*s;if(a===o)return 0;var c=a-o;if("s"===e)return 100*(s>.5?c/(2-a-o):c/(a+o));switch(a){case n:return 60*((r-i)/c+(r1?e:"0"+e},dec2hex:function(t){var e=Math.round(t).toString(16);return e.length>1?e:"0"+e}};e.default=r},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(9),i=n(75),a=n(177),o=function(){function t(t,e){this.color=e,this.changed=!1,this.data=t,this.type=new a.default}return t.prototype.set=function(t,e){return this.color=e,this.changed=!1,this.data=t,this.type.type=i.TYPE.ALL,this},t.prototype._ensureHSL=function(){void 0===this.data.h&&(this.data.h=r.default.channel.rgb2hsl(this.data,"h")),void 0===this.data.s&&(this.data.s=r.default.channel.rgb2hsl(this.data,"s")),void 0===this.data.l&&(this.data.l=r.default.channel.rgb2hsl(this.data,"l"))},t.prototype._ensureRGB=function(){void 0===this.data.r&&(this.data.r=r.default.channel.hsl2rgb(this.data,"r")),void 0===this.data.g&&(this.data.g=r.default.channel.hsl2rgb(this.data,"g")),void 0===this.data.b&&(this.data.b=r.default.channel.hsl2rgb(this.data,"b"))},Object.defineProperty(t.prototype,"r",{get:function(){return this.type.is(i.TYPE.HSL)||void 0===this.data.r?(this._ensureHSL(),r.default.channel.hsl2rgb(this.data,"r")):this.data.r},set:function(t){this.type.set(i.TYPE.RGB),this.changed=!0,this.data.r=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"g",{get:function(){return this.type.is(i.TYPE.HSL)||void 0===this.data.g?(this._ensureHSL(),r.default.channel.hsl2rgb(this.data,"g")):this.data.g},set:function(t){this.type.set(i.TYPE.RGB),this.changed=!0,this.data.g=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"b",{get:function(){return this.type.is(i.TYPE.HSL)||void 0===this.data.b?(this._ensureHSL(),r.default.channel.hsl2rgb(this.data,"b")):this.data.b},set:function(t){this.type.set(i.TYPE.RGB),this.changed=!0,this.data.b=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"h",{get:function(){return this.type.is(i.TYPE.RGB)||void 0===this.data.h?(this._ensureRGB(),r.default.channel.rgb2hsl(this.data,"h")):this.data.h},set:function(t){this.type.set(i.TYPE.HSL),this.changed=!0,this.data.h=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"s",{get:function(){return this.type.is(i.TYPE.RGB)||void 0===this.data.s?(this._ensureRGB(),r.default.channel.rgb2hsl(this.data,"s")):this.data.s},set:function(t){this.type.set(i.TYPE.HSL),this.changed=!0,this.data.s=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"l",{get:function(){return this.type.is(i.TYPE.RGB)||void 0===this.data.l?(this._ensureRGB(),r.default.channel.rgb2hsl(this.data,"l")):this.data.l},set:function(t){this.type.set(i.TYPE.HSL),this.changed=!0,this.data.l=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"a",{get:function(){return this.data.a},set:function(t){this.changed=!0,this.data.a=t},enumerable:!0,configurable:!0}),t}();e.default=o},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(75),i=function(){function t(){this.type=r.TYPE.ALL}return t.prototype.get=function(){return this.type},t.prototype.set=function(t){if(this.type&&this.type!==t)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=t},t.prototype.reset=function(){this.type=r.TYPE.ALL},t.prototype.is=function(t){return this.type===t},t}();e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(9),i={};e.DEC2HEX=i;for(var a=0;a<=255;a++)i[a]=r.default.unit.dec2hex(a)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(99),i={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:function(t){t=t.toLowerCase();var e=i.colors[t];if(e)return r.default.parse(e)},stringify:function(t){var e=r.default.stringify(t);for(var n in i.colors)if(i.colors[n]===e)return n}};e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(9),i=n(45),a={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:function(t){var e=t.charCodeAt(0);if(114===e||82===e){var n=t.match(a.re);if(n){var o=n[1],s=n[2],c=n[3],u=n[4],l=n[5],h=n[6],f=n[7],d=n[8];return i.default.set({r:r.default.channel.clamp.r(s?2.55*parseFloat(o):parseFloat(o)),g:r.default.channel.clamp.g(u?2.55*parseFloat(c):parseFloat(c)),b:r.default.channel.clamp.b(h?2.55*parseFloat(l):parseFloat(l)),a:f?r.default.channel.clamp.a(d?parseFloat(f)/100:parseFloat(f)):1},t)}}},stringify:function(t){return t.a<1?"rgba("+r.default.lang.round(t.r)+", "+r.default.lang.round(t.g)+", "+r.default.lang.round(t.b)+", "+r.default.lang.round(t.a)+")":"rgb("+r.default.lang.round(t.r)+", "+r.default.lang.round(t.g)+", "+r.default.lang.round(t.b)+")"}};e.default=a},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(9),i=n(45),a={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:function(t){var e=t.match(a.hueRe);if(e){var n=e[1];switch(e[2]){case"grad":return r.default.channel.clamp.h(.9*parseFloat(n));case"rad":return r.default.channel.clamp.h(180*parseFloat(n)/Math.PI);case"turn":return r.default.channel.clamp.h(360*parseFloat(n))}}return r.default.channel.clamp.h(parseFloat(t))},parse:function(t){var e=t.charCodeAt(0);if(104===e||72===e){var n=t.match(a.re);if(n){var o=n[1],s=n[2],c=n[3],u=n[4],l=n[5];return i.default.set({h:a._hue2deg(o),s:r.default.channel.clamp.s(parseFloat(s)),l:r.default.channel.clamp.l(parseFloat(c)),a:u?r.default.channel.clamp.a(l?parseFloat(u)/100:parseFloat(u)):1},t)}}},stringify:function(t){return t.a<1?"hsla("+r.default.lang.round(t.h)+", "+r.default.lang.round(t.s)+"%, "+r.default.lang.round(t.l)+"%, "+t.a+")":"hsl("+r.default.lang.round(t.h)+", "+r.default.lang.round(t.s)+"%, "+r.default.lang.round(t.l)+"%)"}};e.default=a},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(29);e.default=function(t){return r.default(t,"r")}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(29);e.default=function(t){return r.default(t,"g")}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(29);e.default=function(t){return r.default(t,"b")}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(29);e.default=function(t){return r.default(t,"h")}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(29);e.default=function(t){return r.default(t,"s")}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(29);e.default=function(t){return r.default(t,"l")}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(103);e.default=function(t){return!r.default(t)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(15);e.default=function(t){try{return r.default.parse(t),!0}catch(t){return!1}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(32);e.default=function(t,e){return r.default(t,"s",e)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(32);e.default=function(t,e){return r.default(t,"s",-e)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(32);e.default=function(t,e){return r.default(t,"l",e)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(32);e.default=function(t,e){return r.default(t,"l",-e)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(32);e.default=function(t){return r.default(t,"h",180)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(52);e.default=function(t){return r.default(t,{s:0})}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(15),i=n(107);e.default=function(t,e){void 0===e&&(e=100);var n=r.default.parse(t);return n.r=255-n.r,n.g=255-n.g,n.b=255-n.b,i.default(n,t,e)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(9),i=n(15),a=n(106);e.default=function(t,e){var n,o,s,c=i.default.parse(t),u={};for(var l in e)u[l]=(n=c[l],o=e[l],s=r.default.channel.max[l],o>0?(s-n)*o/100:n*o/100);return a.default(t,u)}},function(t,e,n){t.exports={Graph:n(76),version:n(300)}},function(t,e,n){var r=n(108);t.exports=function(t){return r(t,4)}},function(t,e){t.exports=function(){this.__data__=[],this.size=0}},function(t,e,n){var r=n(55),i=Array.prototype.splice;t.exports=function(t){var e=this.__data__,n=r(e,t);return!(n<0)&&(n==e.length-1?e.pop():i.call(e,n,1),--this.size,!0)}},function(t,e,n){var r=n(55);t.exports=function(t){var e=this.__data__,n=r(e,t);return n<0?void 0:e[n][1]}},function(t,e,n){var r=n(55);t.exports=function(t){return r(this.__data__,t)>-1}},function(t,e,n){var r=n(55);t.exports=function(t,e){var n=this.__data__,i=r(n,t);return i<0?(++this.size,n.push([t,e])):n[i][1]=e,this}},function(t,e,n){var r=n(54);t.exports=function(){this.__data__=new r,this.size=0}},function(t,e){t.exports=function(t){var e=this.__data__,n=e.delete(t);return this.size=e.size,n}},function(t,e){t.exports=function(t){return this.__data__.get(t)}},function(t,e){t.exports=function(t){return this.__data__.has(t)}},function(t,e,n){var r=n(54),i=n(77),a=n(78);t.exports=function(t,e){var n=this.__data__;if(n instanceof r){var o=n.__data__;if(!i||o.length<199)return o.push([t,e]),this.size=++n.size,this;n=this.__data__=new a(o)}return n.set(t,e),this.size=n.size,this}},function(t,e,n){var r=n(37),i=n(214),a=n(11),o=n(110),s=/^\[object .+?Constructor\]$/,c=Function.prototype,u=Object.prototype,l=c.toString,h=u.hasOwnProperty,f=RegExp("^"+l.call(h).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");t.exports=function(t){return!(!a(t)||i(t))&&(r(t)?f:s).test(o(t))}},function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e,n){var r=n(38),i=Object.prototype,a=i.hasOwnProperty,o=i.toString,s=r?r.toStringTag:void 0;t.exports=function(t){var e=a.call(t,s),n=t[s];try{t[s]=void 0;var r=!0}catch(t){}var i=o.call(t);return r&&(e?t[s]=n:delete t[s]),i}},function(t,e){var n=Object.prototype.toString;t.exports=function(t){return n.call(t)}},function(t,e,n){var r,i=n(215),a=(r=/[^.]+$/.exec(i&&i.keys&&i.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"";t.exports=function(t){return!!a&&a in t}},function(t,e,n){var r=n(16)["__core-js_shared__"];t.exports=r},function(t,e){t.exports=function(t,e){return null==t?void 0:t[e]}},function(t,e,n){var r=n(218),i=n(54),a=n(77);t.exports=function(){this.size=0,this.__data__={hash:new r,map:new(a||i),string:new r}}},function(t,e,n){var r=n(219),i=n(220),a=n(221),o=n(222),s=n(223);function c(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e0){if(++e>=800)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}},function(t,e,n){var r=n(131),i=n(292),a=n(296),o=n(132),s=n(297),c=n(90);t.exports=function(t,e,n){var u=-1,l=i,h=t.length,f=!0,d=[],p=d;if(n)f=!1,l=a;else if(h>=200){var g=e?null:s(t);if(g)return c(g);f=!1,l=o,p=new r}else p=e?[]:d;t:for(;++u-1}},function(t,e,n){var r=n(145),i=n(294),a=n(295);t.exports=function(t,e,n){return e==e?a(t,e,n):r(t,i,n)}},function(t,e){t.exports=function(t){return t!=t}},function(t,e){t.exports=function(t,e,n){for(var r=n-1,i=t.length;++r1||1===e.length&&t.hasEdge(e[0],e[0])}))}},function(t,e,n){var r=n(10);t.exports=function(t,e,n){return function(t,e,n){var r={},i=t.nodes();return i.forEach((function(t){r[t]={},r[t][t]={distance:0},i.forEach((function(e){t!==e&&(r[t][e]={distance:Number.POSITIVE_INFINITY})})),n(t).forEach((function(n){var i=n.v===t?n.w:n.v,a=e(n);r[t][i]={distance:a,predecessor:t}}))})),i.forEach((function(t){var e=r[t];i.forEach((function(n){var a=r[n];i.forEach((function(n){var r=a[t],i=e[n],o=a[n],s=r.distance+i.distance;s0;){if(n=c.removeMin(),r.has(s,n))o.setEdge(n,s[n]);else{if(l)throw new Error("Input graph is not connected: "+t);l=!0}t.nodeEdges(n).forEach(u)}return o}},function(t,e,n){var r;try{r=n(3)}catch(t){}r||(r=window.graphlib),t.exports=r},function(t,e,n){"use strict";var r=n(4),i=n(345),a=n(348),o=n(349),s=n(8).normalizeRanks,c=n(351),u=n(8).removeEmptyRanks,l=n(352),h=n(353),f=n(354),d=n(355),p=n(364),g=n(8),y=n(17).Graph;t.exports=function(t,e){var n=e&&e.debugTiming?g.time:g.notime;n("layout",(function(){var e=n(" buildLayoutGraph",(function(){return function(t){var e=new y({multigraph:!0,compound:!0}),n=C(t.graph());return e.setGraph(r.merge({},m,T(n,v),r.pick(n,b))),r.forEach(t.nodes(),(function(n){var i=C(t.node(n));e.setNode(n,r.defaults(T(i,x),_)),e.setParent(n,t.parent(n))})),r.forEach(t.edges(),(function(n){var i=C(t.edge(n));e.setEdge(n,r.merge({},w,T(i,k),r.pick(i,E)))})),e}(t)}));n(" runLayout",(function(){!function(t,e){e(" makeSpaceForEdgeLabels",(function(){!function(t){var e=t.graph();e.ranksep/=2,r.forEach(t.edges(),(function(n){var r=t.edge(n);r.minlen*=2,"c"!==r.labelpos.toLowerCase()&&("TB"===e.rankdir||"BT"===e.rankdir?r.width+=r.labeloffset:r.height+=r.labeloffset)}))}(t)})),e(" removeSelfEdges",(function(){!function(t){r.forEach(t.edges(),(function(e){if(e.v===e.w){var n=t.node(e.v);n.selfEdges||(n.selfEdges=[]),n.selfEdges.push({e:e,label:t.edge(e)}),t.removeEdge(e)}}))}(t)})),e(" acyclic",(function(){i.run(t)})),e(" nestingGraph.run",(function(){l.run(t)})),e(" rank",(function(){o(g.asNonCompoundGraph(t))})),e(" injectEdgeLabelProxies",(function(){!function(t){r.forEach(t.edges(),(function(e){var n=t.edge(e);if(n.width&&n.height){var r=t.node(e.v),i={rank:(t.node(e.w).rank-r.rank)/2+r.rank,e:e};g.addDummyNode(t,"edge-proxy",i,"_ep")}}))}(t)})),e(" removeEmptyRanks",(function(){u(t)})),e(" nestingGraph.cleanup",(function(){l.cleanup(t)})),e(" normalizeRanks",(function(){s(t)})),e(" assignRankMinMax",(function(){!function(t){var e=0;r.forEach(t.nodes(),(function(n){var i=t.node(n);i.borderTop&&(i.minRank=t.node(i.borderTop).rank,i.maxRank=t.node(i.borderBottom).rank,e=r.max(e,i.maxRank))})),t.graph().maxRank=e}(t)})),e(" removeEdgeLabelProxies",(function(){!function(t){r.forEach(t.nodes(),(function(e){var n=t.node(e);"edge-proxy"===n.dummy&&(t.edge(n.e).labelRank=n.rank,t.removeNode(e))}))}(t)})),e(" normalize.run",(function(){a.run(t)})),e(" parentDummyChains",(function(){c(t)})),e(" addBorderSegments",(function(){h(t)})),e(" order",(function(){d(t)})),e(" insertSelfEdges",(function(){!function(t){var e=g.buildLayerMatrix(t);r.forEach(e,(function(e){var n=0;r.forEach(e,(function(e,i){var a=t.node(e);a.order=i+n,r.forEach(a.selfEdges,(function(e){g.addDummyNode(t,"selfedge",{width:e.label.width,height:e.label.height,rank:a.rank,order:i+ ++n,e:e.e,label:e.label},"_se")})),delete a.selfEdges}))}))}(t)})),e(" adjustCoordinateSystem",(function(){f.adjust(t)})),e(" position",(function(){p(t)})),e(" positionSelfEdges",(function(){!function(t){r.forEach(t.nodes(),(function(e){var n=t.node(e);if("selfedge"===n.dummy){var r=t.node(n.e.v),i=r.x+r.width/2,a=r.y,o=n.x-i,s=r.height/2;t.setEdge(n.e,n.label),t.removeNode(e),n.label.points=[{x:i+2*o/3,y:a-s},{x:i+5*o/6,y:a-s},{x:i+o,y:a},{x:i+5*o/6,y:a+s},{x:i+2*o/3,y:a+s}],n.label.x=n.x,n.label.y=n.y}}))}(t)})),e(" removeBorderNodes",(function(){!function(t){r.forEach(t.nodes(),(function(e){if(t.children(e).length){var n=t.node(e),i=t.node(n.borderTop),a=t.node(n.borderBottom),o=t.node(r.last(n.borderLeft)),s=t.node(r.last(n.borderRight));n.width=Math.abs(s.x-o.x),n.height=Math.abs(a.y-i.y),n.x=o.x+n.width/2,n.y=i.y+n.height/2}})),r.forEach(t.nodes(),(function(e){"border"===t.node(e).dummy&&t.removeNode(e)}))}(t)})),e(" normalize.undo",(function(){a.undo(t)})),e(" fixupEdgeLabelCoords",(function(){!function(t){r.forEach(t.edges(),(function(e){var n=t.edge(e);if(r.has(n,"x"))switch("l"!==n.labelpos&&"r"!==n.labelpos||(n.width-=n.labeloffset),n.labelpos){case"l":n.x-=n.width/2+n.labeloffset;break;case"r":n.x+=n.width/2+n.labeloffset}}))}(t)})),e(" undoCoordinateSystem",(function(){f.undo(t)})),e(" translateGraph",(function(){!function(t){var e=Number.POSITIVE_INFINITY,n=0,i=Number.POSITIVE_INFINITY,a=0,o=t.graph(),s=o.marginx||0,c=o.marginy||0;function u(t){var r=t.x,o=t.y,s=t.width,c=t.height;e=Math.min(e,r-s/2),n=Math.max(n,r+s/2),i=Math.min(i,o-c/2),a=Math.max(a,o+c/2)}r.forEach(t.nodes(),(function(e){u(t.node(e))})),r.forEach(t.edges(),(function(e){var n=t.edge(e);r.has(n,"x")&&u(n)})),e-=s,i-=c,r.forEach(t.nodes(),(function(n){var r=t.node(n);r.x-=e,r.y-=i})),r.forEach(t.edges(),(function(n){var a=t.edge(n);r.forEach(a.points,(function(t){t.x-=e,t.y-=i})),r.has(a,"x")&&(a.x-=e),r.has(a,"y")&&(a.y-=i)})),o.width=n-e+s,o.height=a-i+c}(t)})),e(" assignNodeIntersects",(function(){!function(t){r.forEach(t.edges(),(function(e){var n,r,i=t.edge(e),a=t.node(e.v),o=t.node(e.w);i.points?(n=i.points[0],r=i.points[i.points.length-1]):(i.points=[],n=o,r=a),i.points.unshift(g.intersectRect(a,n)),i.points.push(g.intersectRect(o,r))}))}(t)})),e(" reversePoints",(function(){!function(t){r.forEach(t.edges(),(function(e){var n=t.edge(e);n.reversed&&n.points.reverse()}))}(t)})),e(" acyclic.undo",(function(){i.undo(t)}))}(e,n)})),n(" updateInputGraph",(function(){!function(t,e){r.forEach(t.nodes(),(function(n){var r=t.node(n),i=e.node(n);r&&(r.x=i.x,r.y=i.y,e.children(n).length&&(r.width=i.width,r.height=i.height))})),r.forEach(t.edges(),(function(n){var i=t.edge(n),a=e.edge(n);i.points=a.points,r.has(a,"x")&&(i.x=a.x,i.y=a.y)})),t.graph().width=e.graph().width,t.graph().height=e.graph().height}(t,e)}))}))};var v=["nodesep","edgesep","ranksep","marginx","marginy"],m={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},b=["acyclicer","ranker","rankdir","align"],x=["width","height"],_={width:0,height:0},k=["minlen","weight","width","height","labeloffset"],w={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},E=["labelpos"];function T(t,e){return r.mapValues(r.pick(t,e),Number)}function C(t){var e={};return r.forEach(t,(function(t,n){e[n.toLowerCase()]=t})),e}},function(t,e,n){var r=n(108);t.exports=function(t){return r(t,5)}},function(t,e,n){var r=n(315)(n(316));t.exports=r},function(t,e,n){var r=n(25),i=n(24),a=n(30);t.exports=function(t){return function(e,n,o){var s=Object(e);if(!i(e)){var c=r(n,3);e=a(e),n=function(t){return c(s[t],t,s)}}var u=t(e,n,o);return u>-1?s[c?e[u]:u]:void 0}}},function(t,e,n){var r=n(145),i=n(25),a=n(317),o=Math.max;t.exports=function(t,e,n){var s=null==t?0:t.length;if(!s)return-1;var c=null==n?0:a(n);return c<0&&(c=o(s+c,0)),r(t,i(e,3),c)}},function(t,e,n){var r=n(155);t.exports=function(t){var e=r(t),n=e%1;return e==e?n?e-n:e:0}},function(t,e,n){var r=n(11),i=n(42),a=/^\s+|\s+$/g,o=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,c=/^0o[0-7]+$/i,u=parseInt;t.exports=function(t){if("number"==typeof t)return t;if(i(t))return NaN;if(r(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=r(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(a,"");var n=s.test(t);return n||c.test(t)?u(t.slice(2),n?2:8):o.test(t)?NaN:+t}},function(t,e,n){var r=n(89),i=n(127),a=n(40);t.exports=function(t,e){return null==t?t:r(t,i(e),a)}},function(t,e){t.exports=function(t){var e=null==t?0:t.length;return e?t[e-1]:void 0}},function(t,e,n){var r=n(59),i=n(88),a=n(25);t.exports=function(t,e){var n={};return e=a(e,3),i(t,(function(t,i,a){r(n,i,e(t,i,a))})),n}},function(t,e,n){var r=n(95),i=n(323),a=n(35);t.exports=function(t){return t&&t.length?r(t,a,i):void 0}},function(t,e){t.exports=function(t,e){return t>e}},function(t,e,n){var r=n(325),i=n(328)((function(t,e,n){r(t,e,n)}));t.exports=i},function(t,e,n){var r=n(53),i=n(157),a=n(89),o=n(326),s=n(11),c=n(40),u=n(159);t.exports=function t(e,n,l,h,f){e!==n&&a(n,(function(a,c){if(f||(f=new r),s(a))o(e,n,c,l,t,h,f);else{var d=h?h(u(e,c),a,c+"",e,n,f):void 0;void 0===d&&(d=a),i(e,c,d)}}),c)}},function(t,e,n){var r=n(157),i=n(114),a=n(123),o=n(115),s=n(124),c=n(47),u=n(5),l=n(146),h=n(39),f=n(37),d=n(11),p=n(158),g=n(48),y=n(159),v=n(327);t.exports=function(t,e,n,m,b,x,_){var k=y(t,n),w=y(e,n),E=_.get(w);if(E)r(t,n,E);else{var T=x?x(k,w,n+"",t,e,_):void 0,C=void 0===T;if(C){var S=u(w),A=!S&&h(w),M=!S&&!A&&g(w);T=w,S||A||M?u(k)?T=k:l(k)?T=o(k):A?(C=!1,T=i(w,!0)):M?(C=!1,T=a(w,!0)):T=[]:p(w)||c(w)?(T=k,c(k)?T=v(k):d(k)&&!f(k)||(T=s(w))):C=!1}C&&(_.set(w,T),b(T,w,m,x,_),_.delete(w)),r(t,n,T)}}},function(t,e,n){var r=n(46),i=n(40);t.exports=function(t){return r(t,i(t))}},function(t,e,n){var r=n(67),i=n(68);t.exports=function(t){return r((function(e,n){var r=-1,a=n.length,o=a>1?n[a-1]:void 0,s=a>2?n[2]:void 0;for(o=t.length>3&&"function"==typeof o?(a--,o):void 0,s&&i(n[0],n[1],s)&&(o=a<3?void 0:o,a=1),e=Object(e);++r1&&o(t,e[0],e[1])?e=[]:n>2&&o(e[0],e[1],e[2])&&(e=[e[0]]),i(t,r(e,1),[])}));t.exports=s},function(t,e,n){var r=n(66),i=n(25),a=n(141),o=n(340),s=n(61),c=n(341),u=n(35);t.exports=function(t,e,n){var l=-1;e=r(e.length?e:[u],s(i));var h=a(t,(function(t,n,i){return{criteria:r(e,(function(e){return e(t)})),index:++l,value:t}}));return o(h,(function(t,e){return c(t,e,n)}))}},function(t,e){t.exports=function(t,e){var n=t.length;for(t.sort(e);n--;)t[n]=t[n].value;return t}},function(t,e,n){var r=n(342);t.exports=function(t,e,n){for(var i=-1,a=t.criteria,o=e.criteria,s=a.length,c=n.length;++i=c?u:u*("desc"==n[i]?-1:1)}return t.index-e.index}},function(t,e,n){var r=n(42);t.exports=function(t,e){if(t!==e){var n=void 0!==t,i=null===t,a=t==t,o=r(t),s=void 0!==e,c=null===e,u=e==e,l=r(e);if(!c&&!l&&!o&&t>e||o&&s&&u&&!c&&!l||i&&s&&u||!n&&u||!a)return 1;if(!i&&!o&&!l&&t0;--c)if(r=e[c].dequeue()){i=i.concat(s(t,e,n,r,!0));break}}return i}(n.graph,n.buckets,n.zeroIdx);return r.flatten(r.map(u,(function(e){return t.outEdges(e.v,e.w)})),!0)};var o=r.constant(1);function s(t,e,n,i,a){var o=a?[]:void 0;return r.forEach(t.inEdges(i.v),(function(r){var i=t.edge(r),s=t.node(r.v);a&&o.push({v:r.v,w:r.w}),s.out-=i,c(e,n,s)})),r.forEach(t.outEdges(i.v),(function(r){var i=t.edge(r),a=r.w,o=t.node(a);o.in-=i,c(e,n,o)})),t.removeNode(i.v),o}function c(t,e,n){n.out?n.in?t[n.out-n.in+e].enqueue(n):t[t.length-1].enqueue(n):t[0].enqueue(n)}},function(t,e){function n(){var t={};t._next=t._prev=t,this._sentinel=t}function r(t){t._prev._next=t._next,t._next._prev=t._prev,delete t._next,delete t._prev}function i(t,e){if("_next"!==t&&"_prev"!==t)return e}t.exports=n,n.prototype.dequeue=function(){var t=this._sentinel,e=t._prev;if(e!==t)return r(e),e},n.prototype.enqueue=function(t){var e=this._sentinel;t._prev&&t._next&&r(t),t._next=e._next,e._next._prev=t,e._next=t,t._prev=e},n.prototype.toString=function(){for(var t=[],e=this._sentinel,n=e._prev;n!==e;)t.push(JSON.stringify(n,i)),n=n._prev;return"["+t.join(", ")+"]"}},function(t,e,n){"use strict";var r=n(4),i=n(8);t.exports={run:function(t){t.graph().dummyChains=[],r.forEach(t.edges(),(function(e){!function(t,e){var n,r,a,o=e.v,s=t.node(o).rank,c=e.w,u=t.node(c).rank,l=e.name,h=t.edge(e),f=h.labelRank;if(u===s+1)return;for(t.removeEdge(e),a=0,++s;sc.lim&&(u=c,l=!0);var h=r.filter(e.edges(),(function(e){return l===m(t,t.node(e.v),u)&&l!==m(t,t.node(e.w),u)}));return r.minBy(h,(function(t){return a(e,t)}))}function v(t,e,n,i){var a=n.v,o=n.w;t.removeEdge(a,o),t.setEdge(i.v,i.w,{}),d(t),h(t,e),function(t,e){var n=r.find(t.nodes(),(function(t){return!e.node(t).parent})),i=s(t,n);i=i.slice(1),r.forEach(i,(function(n){var r=t.node(n).parent,i=e.edge(n,r),a=!1;i||(i=e.edge(r,n),a=!0),e.node(n).rank=e.node(r).rank+(a?i.minlen:-i.minlen)}))}(t,e)}function m(t,e,n){return n.low<=e.lim&&e.lim<=n.lim}t.exports=l,l.initLowLimValues=d,l.initCutValues=h,l.calcCutValue=f,l.leaveEdge=g,l.enterEdge=y,l.exchangeEdges=v},function(t,e,n){var r=n(4);t.exports=function(t){var e=function(t){var e={},n=0;function i(a){var o=n;r.forEach(t.children(a),i),e[a]={low:o,lim:n++}}return r.forEach(t.children(),i),e}(t);r.forEach(t.graph().dummyChains,(function(n){for(var r=t.node(n),i=r.edgeObj,a=function(t,e,n,r){var i,a,o=[],s=[],c=Math.min(e[n].low,e[r].low),u=Math.max(e[n].lim,e[r].lim);i=n;do{i=t.parent(i),o.push(i)}while(i&&(e[i].low>c||u>e[i].lim));a=i,i=r;for(;(i=t.parent(i))!==a;)s.push(i);return{path:o.concat(s.reverse()),lca:a}}(t,e,i.v,i.w),o=a.path,s=a.lca,c=0,u=o[c],l=!0;n!==i.w;){if(r=t.node(n),l){for(;(u=o[c])!==s&&t.node(u).maxRank=2),s=l.buildLayerMatrix(t);var y=a(t,s);y0;)e%2&&(n+=c[e+1]),c[e=e-1>>1]+=t.weight;u+=t.weight*n}))),u}t.exports=function(t,e){for(var n=0,r=1;r=t.barycenter)&&function(t,e){var n=0,r=0;t.weight&&(n+=t.barycenter*t.weight,r+=t.weight);e.weight&&(n+=e.barycenter*e.weight,r+=e.weight);t.vs=e.vs.concat(t.vs),t.barycenter=n/r,t.weight=r,t.i=Math.min(e.i,t.i),e.merged=!0}(t,e)}}function i(e){return function(n){n.in.push(e),0==--n.indegree&&t.push(n)}}for(;t.length;){var a=t.pop();e.push(a),r.forEach(a.in.reverse(),n(a)),r.forEach(a.out,i(a))}return r.map(r.filter(e,(function(t){return!t.merged})),(function(t){return r.pick(t,["vs","i","barycenter","weight"])}))}(r.filter(n,(function(t){return!t.indegree})))}},function(t,e,n){var r=n(4),i=n(8);function a(t,e,n){for(var i;e.length&&(i=r.last(e)).i<=n;)e.pop(),t.push(i.vs),n++;return n}t.exports=function(t,e){var n=i.partition(t,(function(t){return r.has(t,"barycenter")})),o=n.lhs,s=r.sortBy(n.rhs,(function(t){return-t.i})),c=[],u=0,l=0,h=0;o.sort((f=!!e,function(t,e){return t.barycentere.barycenter?1:f?e.i-t.i:t.i-e.i})),h=a(c,s,h),r.forEach(o,(function(t){h+=t.vs.length,c.push(t.vs),u+=t.barycenter*t.weight,l+=t.weight,h=a(c,s,h)}));var f;var d={vs:r.flatten(c,!0)};l&&(d.barycenter=u/l,d.weight=l);return d}},function(t,e,n){var r=n(4),i=n(17).Graph;t.exports=function(t,e,n){var a=function(t){var e;for(;t.hasNode(e=r.uniqueId("_root")););return e}(t),o=new i({compound:!0}).setGraph({root:a}).setDefaultNodeLabel((function(e){return t.node(e)}));return r.forEach(t.nodes(),(function(i){var s=t.node(i),c=t.parent(i);(s.rank===e||s.minRank<=e&&e<=s.maxRank)&&(o.setNode(i),o.setParent(i,c||a),r.forEach(t[n](i),(function(e){var n=e.v===i?e.w:e.v,a=o.edge(n,i),s=r.isUndefined(a)?0:a.weight;o.setEdge(n,i,{weight:t.edge(e).weight+s})})),r.has(s,"minRank")&&o.setNode(i,{borderLeft:s.borderLeft[e],borderRight:s.borderRight[e]}))})),o}},function(t,e,n){var r=n(4);t.exports=function(t,e,n){var i,a={};r.forEach(n,(function(n){for(var r,o,s=t.parent(n);s;){if((r=t.parent(s))?(o=a[r],a[r]=s):(o=i,i=s),o&&o!==s)return void e.setEdge(o,s);s=r}}))}},function(t,e,n){"use strict";var r=n(4),i=n(8),a=n(365).positionX;t.exports=function(t){(function(t){var e=i.buildLayerMatrix(t),n=t.graph().ranksep,a=0;r.forEach(e,(function(e){var i=r.max(r.map(e,(function(e){return t.node(e).height})));r.forEach(e,(function(e){t.node(e).y=a+i/2})),a+=i+n}))})(t=i.asNonCompoundGraph(t)),r.forEach(a(t),(function(e,n){t.node(n).x=e}))}},function(t,e,n){"use strict";var r=n(4),i=n(17).Graph,a=n(8);function o(t,e){var n={};return r.reduce(e,(function(e,i){var a=0,o=0,s=e.length,u=r.last(i);return r.forEach(i,(function(e,l){var h=function(t,e){if(t.node(e).dummy)return r.find(t.predecessors(e),(function(e){return t.node(e).dummy}))}(t,e),f=h?t.node(h).order:s;(h||e===u)&&(r.forEach(i.slice(o,l+1),(function(e){r.forEach(t.predecessors(e),(function(r){var i=t.node(r),o=i.order;!(os)&&c(n,e,u)}))}))}return r.reduce(e,(function(e,n){var a,o=-1,s=0;return r.forEach(n,(function(r,c){if("border"===t.node(r).dummy){var u=t.predecessors(r);u.length&&(a=t.node(u[0]).order,i(n,s,c,o,a),s=c,o=a)}i(n,s,n.length,a,e.length)})),n})),n}function c(t,e,n){if(e>n){var r=e;e=n,n=r}var i=t[e];i||(t[e]=i={}),i[n]=!0}function u(t,e,n){if(e>n){var i=e;e=n,n=i}return r.has(t[e],n)}function l(t,e,n,i){var a={},o={},s={};return r.forEach(e,(function(t){r.forEach(t,(function(t,e){a[t]=t,o[t]=t,s[t]=e}))})),r.forEach(e,(function(t){var e=-1;r.forEach(t,(function(t){var c=i(t);if(c.length)for(var l=((c=r.sortBy(c,(function(t){return s[t]}))).length-1)/2,h=Math.floor(l),f=Math.ceil(l);h<=f;++h){var d=c[h];o[t]===t&&e0}t.exports=function(t,e,r,i){var a,o,s,c,u,l,h,f,d,p,g,y,v;if(a=e.y-t.y,s=t.x-e.x,u=e.x*t.y-t.x*e.y,d=a*r.x+s*r.y+u,p=a*i.x+s*i.y+u,0!==d&&0!==p&&n(d,p))return;if(o=i.y-r.y,c=r.x-i.x,l=i.x*r.y-r.x*i.y,h=o*t.x+c*t.y+l,f=o*e.x+c*e.y+l,0!==h&&0!==f&&n(h,f))return;if(0===(g=a*c-o*s))return;return y=Math.abs(g/2),{x:(v=s*l-c*u)<0?(v-y)/g:(v+y)/g,y:(v=o*u-a*l)<0?(v-y)/g:(v+y)/g}}},function(t,e,n){var r=n(43),i=n(31),a=n(153).layout;t.exports=function(){var t=n(371),e=n(374),i=n(375),u=n(376),l=n(377),h=n(378),f=n(379),d=n(380),p=n(381),g=function(n,g){!function(t){t.nodes().forEach((function(e){var n=t.node(e);r.has(n,"label")||t.children(e).length||(n.label=e),r.has(n,"paddingX")&&r.defaults(n,{paddingLeft:n.paddingX,paddingRight:n.paddingX}),r.has(n,"paddingY")&&r.defaults(n,{paddingTop:n.paddingY,paddingBottom:n.paddingY}),r.has(n,"padding")&&r.defaults(n,{paddingLeft:n.padding,paddingRight:n.padding,paddingTop:n.padding,paddingBottom:n.padding}),r.defaults(n,o),r.each(["paddingLeft","paddingRight","paddingTop","paddingBottom"],(function(t){n[t]=Number(n[t])})),r.has(n,"width")&&(n._prevWidth=n.width),r.has(n,"height")&&(n._prevHeight=n.height)})),t.edges().forEach((function(e){var n=t.edge(e);r.has(n,"label")||(n.label=""),r.defaults(n,s)}))}(g);var y=c(n,"output"),v=c(y,"clusters"),m=c(y,"edgePaths"),b=i(c(y,"edgeLabels"),g),x=t(c(y,"nodes"),g,d);a(g),l(x,g),h(b,g),u(m,g,p);var _=e(v,g);f(_,g),function(t){r.each(t.nodes(),(function(e){var n=t.node(e);r.has(n,"_prevWidth")?n.width=n._prevWidth:delete n.width,r.has(n,"_prevHeight")?n.height=n._prevHeight:delete n.height,delete n._prevWidth,delete n._prevHeight}))}(g)};return g.createNodes=function(e){return arguments.length?(t=e,g):t},g.createClusters=function(t){return arguments.length?(e=t,g):e},g.createEdgeLabels=function(t){return arguments.length?(i=t,g):i},g.createEdgePaths=function(t){return arguments.length?(u=t,g):u},g.shapes=function(t){return arguments.length?(d=t,g):d},g.arrows=function(t){return arguments.length?(p=t,g):p},g};var o={paddingLeft:10,paddingRight:10,paddingTop:10,paddingBottom:10,rx:0,ry:0,shape:"rect"},s={arrowhead:"normal",curve:i.curveLinear};function c(t,e){var n=t.select("g."+e);return n.empty()&&(n=t.append("g").attr("class",e)),n}},function(t,e,n){"use strict";var r=n(43),i=n(97),a=n(12),o=n(31);t.exports=function(t,e,n){var s,c=e.nodes().filter((function(t){return!a.isSubgraph(e,t)})),u=t.selectAll("g.node").data(c,(function(t){return t})).classed("update",!0);u.exit().remove(),u.enter().append("g").attr("class","node").style("opacity",0),(u=t.selectAll("g.node")).each((function(t){var s=e.node(t),c=o.select(this);a.applyClass(c,s.class,(c.classed("update")?"update ":"")+"node"),c.select("g.label").remove();var u=c.append("g").attr("class","label"),l=i(u,s),h=n[s.shape],f=r.pick(l.node().getBBox(),"width","height");s.elem=this,s.id&&c.attr("id",s.id),s.labelId&&u.attr("id",s.labelId),r.has(s,"width")&&(f.width=s.width),r.has(s,"height")&&(f.height=s.height),f.width+=s.paddingLeft+s.paddingRight,f.height+=s.paddingTop+s.paddingBottom,u.attr("transform","translate("+(s.paddingLeft-s.paddingRight)/2+","+(s.paddingTop-s.paddingBottom)/2+")");var d=o.select(this);d.select(".label-container").remove();var p=h(d,f,s).classed("label-container",!0);a.applyStyle(p,s.style);var g=p.node().getBBox();s.width=g.width,s.height=g.height})),s=u.exit?u.exit():u.selectAll(null);return a.applyTransition(s,e).style("opacity",0).remove(),u}},function(t,e,n){var r=n(12);t.exports=function(t,e){for(var n=t.append("text"),i=function(t){for(var e,n="",r=!1,i=0;i0&&void 0!==arguments[0]?arguments[0]:"fatal";isNaN(t)&&(t=t.toLowerCase(),void 0!==h[t]&&(t=h[t])),f.trace=function(){},f.debug=function(){},f.info=function(){},f.warn=function(){},f.error=function(){},f.fatal=function(){},t<=h.fatal&&(f.fatal=console.error?console.error.bind(console,p("FATAL"),"color: orange"):console.log.bind(console,"",p("FATAL"))),t<=h.error&&(f.error=console.error?console.error.bind(console,p("ERROR"),"color: orange"):console.log.bind(console,"",p("ERROR"))),t<=h.warn&&(f.warn=console.warn?console.warn.bind(console,p("WARN"),"color: orange"):console.log.bind(console,"",p("WARN"))),t<=h.info&&(f.info=console.info?console.info.bind(console,p("INFO"),"color: lightblue"):console.log.bind(console,"",p("INFO"))),t<=h.debug&&(f.debug=console.debug?console.debug.bind(console,p("DEBUG"),"color: lightgreen"):console.log.bind(console,"",p("DEBUG")))},p=function(t){var e=l()().format("ss.SSS");return"%c".concat(e," : ").concat(t," : ")},g=n(70),y=function(t){for(var e="",n=0;n>=0;){if(!((n=t.indexOf("=0)){e+=t,n=-1;break}e+=t.substr(0,n),(n=(t=t.substr(n+1)).indexOf("<\/script>"))>=0&&(n+=9,t=t.substr(n))}return e},v=//gi,m=function(t){return t.replace(v,"#br#")},b=function(t){return t.replace(/#br#/g,"
")},x={getRows:function(t){if(!t)return 1;var e=m(t);return(e=e.replace(/\\n/g,"#br#")).split("#br#")},sanitizeText:function(t,e){var n=t,r=!0;if(!e.flowchart||!1!==e.flowchart.htmlLabels&&"false"!==e.flowchart.htmlLabels||(r=!1),r){var i=e.securityLevel;"antiscript"===i?n=y(n):"loose"!==i&&(n=(n=(n=m(n)).replace(//g,">")).replace(/=/g,"="),n=b(n))}return n},hasBreaks:function(t){return//gi.test(t)},splitBreaks:function(t){return t.split(//gi)},lineBreakRegex:v,removeScript:y};function _(t){return(_="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function k(t){return function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e1&&void 0!==arguments[1]?arguments[1]:null;try{var n=new RegExp("[%]{2}(?![{]".concat(T.source,")(?=[}][%]{2}).*\n"),"ig");t=t.trim().replace(n,"").replace(/'/gm,'"'),f.debug("Detecting diagram directive".concat(null!==e?" type:"+e:""," based on the text:").concat(t));for(var r,i=[];null!==(r=E.exec(t));)if(r.index===E.lastIndex&&E.lastIndex++,r&&!e||e&&r[1]&&r[1].match(e)||e&&r[2]&&r[2].match(e)){var a=r[1]?r[1]:r[2],o=r[3]?r[3].trim():r[4]?JSON.parse(r[4].trim()):null;i.push({type:a,args:o})}return 0===i.length&&i.push({type:t,args:null}),1===i.length?i[0]:i}catch(n){return f.error("ERROR: ".concat(n.message," - Unable to parse directive").concat(null!==e?" type:"+e:""," based on the text:").concat(t)),{type:null,args:null}}},A=function(t){return t=t.replace(E,"").replace(C,"\n"),f.debug("Detecting diagram type based on the text "+t),t.match(/^\s*sequenceDiagram/)?"sequence":t.match(/^\s*gantt/)?"gantt":t.match(/^\s*classDiagram-v2/)?"classDiagram":t.match(/^\s*classDiagram/)?"class":t.match(/^\s*stateDiagram-v2/)?"stateDiagram":t.match(/^\s*stateDiagram/)?"state":t.match(/^\s*gitGraph/)?"git":t.match(/^\s*flowchart/)?"flowchart-v2":t.match(/^\s*info/)?"info":t.match(/^\s*pie/)?"pie":t.match(/^\s*erDiagram/)?"er":t.match(/^\s*journey/)?"journey":"flowchart"},M=function(t,e){var n={};return function(){for(var r=arguments.length,i=new Array(r),a=0;a"},n),x.lineBreakRegex.test(t))return t;var r=t.split(" "),i=[],a="";return r.forEach((function(t,o){var s=Y("".concat(t," "),n),c=Y(a,n);if(s>e){var u=R(t,e,"-",n),l=u.hyphenatedStrings,h=u.remainingWord;i.push.apply(i,[a].concat(k(l))),a=h}else c+s>=e?(i.push(a),a=t):a=[a,t].filter(Boolean).join(" ");o+1===r.length&&i.push(a)})),i.filter((function(t){return""!==t})).join(n.joinWith)}),(function(t,e,n){return"".concat(t,"-").concat(e,"-").concat(n.fontSize,"-").concat(n.fontWeight,"-").concat(n.fontFamily,"-").concat(n.joinWith)})),R=M((function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"-",r=arguments.length>3?arguments[3]:void 0;r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},r);var i=t.split(""),a=[],o="";return i.forEach((function(t,s){var c="".concat(o).concat(t);if(Y(c,r)>=e){var u=s+1,l=i.length===u,h="".concat(c).concat(n);a.push(l?c:h),o=""}else o=c})),{hyphenatedStrings:a,remainingWord:o}}),(function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"-",r=arguments.length>3?arguments[3]:void 0;return"".concat(t,"-").concat(e,"-").concat(n,"-").concat(r.fontSize,"-").concat(r.fontWeight,"-").concat(r.fontFamily)})),Y=function(t,e){return e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial"},e),z(t,e).width},z=M((function(t,e){var n=e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial"},e),r=n.fontSize,i=n.fontFamily,a=n.fontWeight;if(!t)return{width:0,height:0};var o=["sans-serif",i],c=t.split(x.lineBreakRegex),u=[],l=Object(s.select)("body");if(!l.remove)return{width:0,height:0,lineHeight:0};for(var h=l.append("svg"),f=0,d=o;fu[1].height&&u[0].width>u[1].width&&u[0].lineHeight>u[1].lineHeight?0:1]}),(function(t,e){return"".concat(t,"-").concat(e.fontSize,"-").concat(e.fontWeight,"-").concat(e.fontFamily)})),U=function(t,e,n){var r=new Map;return r.set("height",t),n?(r.set("width","100%"),r.set("style","max-width: ".concat(e,"px;"))):r.set("width",e),r},$=function(t,e,n,r){!function(t,e){var n=!0,r=!1,i=void 0;try{for(var a,o=e[Symbol.iterator]();!(n=(a=o.next()).done);n=!0){var s=a.value;t.attr(s[0],s[1])}}catch(t){r=!0,i=t}finally{try{n||null==o.return||o.return()}finally{if(r)throw i}}}(t,U(e,n,r))},W={assignWithDepth:P,wrapLabel:j,calculateTextHeight:function(t,e){return e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:15},e),z(t,e).height},calculateTextWidth:Y,calculateTextDimensions:z,calculateSvgSizeAttrs:U,configureSvgSize:$,detectInit:function(t){var e=S(t,/(?:init\b)|(?:initialize\b)/),n={};if(Array.isArray(e)){var r=e.map((function(t){return t.args}));n=P(n,k(r))}else n=e.args;if(n){var i=A(t);["config"].forEach((function(t){void 0!==n[t]&&("flowchart-v2"===i&&(i="flowchart"),n[i]=n[t],delete n[t])}))}return n},detectDirective:S,detectType:A,isSubstringInArray:function(t,e){for(var n=0;n=1&&(i={x:t.x,y:t.y}),a>0&&a<1&&(i={x:(1-a)*e.x+a*t.x,y:(1-a)*e.y+a*t.y})}}e=t})),i}(t)},calcCardinalityPosition:function(t,e,n){var r;f.info("our points",e),e[0]!==n&&(e=e.reverse()),e.forEach((function(t){D(t,r),r=t}));var i,a=25;r=void 0,e.forEach((function(t){if(r&&!i){var e=D(t,r);if(e=1&&(i={x:t.x,y:t.y}),n>0&&n<1&&(i={x:(1-n)*r.x+n*t.x,y:(1-n)*r.y+n*t.y})}}r=t}));var o=t?10:5,s=Math.atan2(e[0].y-i.y,e[0].x-i.x),c={x:0,y:0};return c.x=Math.sin(s)*o+(e[0].x+i.x)/2,c.y=-Math.cos(s)*o+(e[0].y+i.y)/2,c},calcTerminalLabelPosition:function(t,e,n){var r,i=JSON.parse(JSON.stringify(n));f.info("our points",i),"start_left"!==e&&"start_right"!==e&&(i=i.reverse()),i.forEach((function(t){D(t,r),r=t}));var a,o=25;r=void 0,i.forEach((function(t){if(r&&!a){var e=D(t,r);if(e=1&&(a={x:t.x,y:t.y}),n>0&&n<1&&(a={x:(1-n)*r.x+n*t.x,y:(1-n)*r.y+n*t.y})}}r=t}));var s=10,c=Math.atan2(i[0].y-a.y,i[0].x-a.x),u={x:0,y:0};return u.x=Math.sin(c)*s+(i[0].x+a.x)/2,u.y=-Math.cos(c)*s+(i[0].y+a.y)/2,"start_left"===e&&(u.x=Math.sin(c+Math.PI)*s+(i[0].x+a.x)/2,u.y=-Math.cos(c+Math.PI)*s+(i[0].y+a.y)/2),"end_right"===e&&(u.x=Math.sin(c-Math.PI)*s+(i[0].x+a.x)/2-5,u.y=-Math.cos(c-Math.PI)*s+(i[0].y+a.y)/2-5),"end_left"===e&&(u.x=Math.sin(c)*s+(i[0].x+a.x)/2-5,u.y=-Math.cos(c)*s+(i[0].y+a.y)/2-5),u},formatUrl:function(t,e){var n=t.trim();if(n)return"loose"!==e.securityLevel?Object(g.sanitizeUrl)(n):n},getStylesFromArray:N,generateId:L,random:F,memoize:M,runFunc:function(t){for(var e,n=t.split("."),r=n.length-1,i=n[r],a=window,o=0;o1?s-1:0),u=1;u=0&&(n=!0)})),n},Gt=function(t,e){var n=[];return t.nodes.forEach((function(r,i){Ht(e,r)||n.push(t.nodes[i])})),{nodes:n}},qt={parseDirective:function(t,e,n){$o.parseDirective(this,t,e,n)},defaultConfig:function(){return pt.flowchart},addVertex:function(t,e,n,r,i){var a,o=t;void 0!==o&&0!==o.trim().length&&(void 0===Mt[o]&&(Mt[o]={id:o,domId:"flowchart-"+o+"-"+St,styles:[],classes:[]}),St++,void 0!==e?(At=xt(),'"'===(a=x.sanitizeText(e.trim(),At))[0]&&'"'===a[a.length-1]&&(a=a.substring(1,a.length-1)),Mt[o].text=a):void 0===Mt[o].text&&(Mt[o].text=t),void 0!==n&&(Mt[o].type=n),null!=r&&r.forEach((function(t){Mt[o].styles.push(t)})),null!=i&&i.forEach((function(t){Mt[o].classes.push(t)})))},lookUpDomId:jt,addLink:function(t,e,n,r){var i,a;for(i=0;i/)&&(Tt="LR"),Tt.match(/.*v/)&&(Tt="TB")},setClass:Yt,getTooltip:function(t){return Lt[t]},setClickEvent:function(t,e,n){t.split(",").forEach((function(t){!function(t,e){var n=jt(t);"loose"===xt().securityLevel&&void 0!==e&&void 0!==Mt[t]&&(Mt[t].haveCallback=!0,It.push((function(){var r=document.querySelector('[id="'.concat(n,'"]'));null!==r&&r.addEventListener("click",(function(){W.runFunc(e,t)}),!1)})))}(t,e)})),zt(t,n),Yt(t,"clickable")},setLink:function(t,e,n,r){t.split(",").forEach((function(t){void 0!==Mt[t]&&(Mt[t].link=W.formatUrl(e,At),Mt[t].linkTarget=r)})),zt(t,n),Yt(t,"clickable")},bindFunctions:function(t){It.forEach((function(e){e(t)}))},getDirection:function(){return Tt.trim()},getVertices:function(){return Mt},getEdges:function(){return Ot},getClasses:function(){return Dt},clear:function(t){Mt={},Dt={},Ot=[],(It=[]).push(Ut),Nt=[],Bt={},Ft=0,Lt=[],Pt=!0,Ct=t||"gen-1"},setGen:function(t){Ct=t||"gen-1"},defaultStyle:function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"},addSubGraph:function(t,e,n){var r=t.trim(),i=n;t===n&&n.match(/\s/)&&(r=void 0);var a,o,s,c=[];if(a=c.concat.apply(c,e),o={boolean:{},number:{},string:{}},s=[],c=a.filter((function(t){var e=Et(t);return""!==t.trim()&&(e in o?!o[e].hasOwnProperty(t)&&(o[e][t]=!0):!(s.indexOf(t)>=0)&&s.push(t))})),"gen-1"===Ct){f.warn("LOOKING UP");for(var u=0;u0&&function t(e,n){var r=Nt[n].nodes;if(!((Wt+=1)>2e3)){if(Vt[Wt]=n,Nt[n].id===e)return{result:!0,count:0};for(var i=0,a=1;i=0){var s=t(e,o);if(s.result)return{result:!0,count:a+s.count};a+=s.count}i+=1}return{result:!1,count:a}}}("none",Nt.length-1)},getSubGraphs:function(){return Nt},destructLink:function(t,e){var n,r=function(t){var e=t.trim(),n=e.slice(0,-1),r="arrow_open";switch(e.slice(-1)){case"x":r="arrow_cross","x"===e[0]&&(r="double_"+r,n=n.slice(1));break;case">":r="arrow_point","<"===e[0]&&(r="double_"+r,n=n.slice(1));break;case"o":r="arrow_circle","o"===e[0]&&(r="double_"+r,n=n.slice(1))}var i="normal",a=n.length-1;"="===n[0]&&(i="thick");var o=function(t,e){for(var n=e.length,r=0,i=0;in.height/2-a)){var o=a*a*(1-r*r/(i*i));0!=o&&(o=Math.sqrt(o)),o=a-o,t.y-n.y>0&&(o=-o),e.y+=o}return e},c}function fe(t,e,n,r){return t.insert("polygon",":first-child").attr("points",r.map((function(t){return t.x+","+t.y})).join(" ")).attr("transform","translate("+-e/2+","+n/2+")")}var de={addToRender:function(t){t.shapes().question=ee,t.shapes().hexagon=ne,t.shapes().stadium=ue,t.shapes().subroutine=le,t.shapes().cylinder=he,t.shapes().rect_left_inv_arrow=re,t.shapes().lean_right=ie,t.shapes().lean_left=ae,t.shapes().trapezoid=oe,t.shapes().inv_trapezoid=se,t.shapes().rect_right_inv_arrow=ce},addToRenderV2:function(t){t({question:ee}),t({hexagon:ne}),t({stadium:ue}),t({subroutine:le}),t({cylinder:he}),t({rect_left_inv_arrow:re}),t({lean_right:ie}),t({lean_left:ae}),t({trapezoid:oe}),t({inv_trapezoid:se}),t({rect_right_inv_arrow:ce})}},pe={},ge=function(t,e,n){var r=Object(s.select)('[id="'.concat(n,'"]'));Object.keys(t).forEach((function(n){var i=t[n],a="default";i.classes.length>0&&(a=i.classes.join(" "));var o,s=N(i.styles),c=void 0!==i.text?i.text:i.id;if(xt().flowchart.htmlLabels){var u={label:c.replace(/fa[lrsb]?:fa-[\w-]+/g,(function(t){return"")}))};(o=te()(r,u).node()).parentNode.removeChild(o)}else{var l=document.createElementNS("http://www.w3.org/2000/svg","text");l.setAttribute("style",s.labelStyle.replace("color:","fill:"));for(var h=c.split(x.lineBreakRegex),d=0;d').concat(a.text.replace(/fa[lrsb]?:fa-[\w-]+/g,(function(t){return"")})),"")):(l.labelType="text",l.label=a.text.replace(x.lineBreakRegex,"\n"),void 0===a.style&&(l.style=l.style||"stroke: #333; stroke-width: 1.5px;fill:none"),l.labelStyle=l.labelStyle.replace("color:","fill:"))),l.id=o,l.class=c+" "+u,l.minlen=a.length||1,e.setEdge(qt.lookUpDomId(a.start),qt.lookUpDomId(a.end),l,i)}))},ve=function(t){for(var e=Object.keys(t),n=0;n=0;h--)i=l[h],qt.addVertex(i.id,i.title,"group",void 0,i.classes);var d=qt.getVertices();f.warn("Get vertices",d);var p=qt.getEdges(),g=0;for(g=l.length-1;g>=0;g--){i=l[g],Object(s.selectAll)("cluster").append("text");for(var y=0;y"),f.info("vertexText"+i),function(t){var e,n,r=Object(s.select)(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),i=r.append("xhtml:div"),a=t.label,o=t.isNode?"nodeLabel":"edgeLabel";return i.html(''+a+""),e=i,(n=t.labelStyle)&&e.attr("style",n),i.style("display","inline-block"),i.style("white-space","nowrap"),i.attr("xmlns","http://www.w3.org/1999/xhtml"),r.node()}({isNode:r,label:i.replace(/fa[lrsb]?:fa-[\w-]+/g,(function(t){return"")})),labelStyle:e.replace("fill:","color:")});var a=document.createElementNS("http://www.w3.org/2000/svg","text");a.setAttribute("style",e.replace("color:","fill:"));var o=[];o="string"==typeof i?i.split(/\\n|\n|/gi):Array.isArray(i)?i:[];for(var c=0;c0)t(a,n,r,i);else{var o=n.node(a);f.info("cp ",a," to ",i," with parent ",e),r.setNode(a,o),i!==n.parent(a)&&(f.warn("Setting parent",a,n.parent(a)),r.setParent(a,n.parent(a))),e!==i&&a!==e?(f.debug("Setting parent",a,e),r.setParent(a,e)):(f.info("In copy ",e,"root",i,"data",n.node(e),i),f.debug("Not Setting parent for node=",a,"cluster!==rootId",e!==i,"node!==clusterId",a!==e));var s=n.edges(a);f.debug("Copying Edges",s),s.forEach((function(t){f.info("Edge",t);var a=n.edge(t.v,t.w,t.name);f.info("Edge data",a,i);try{!function(t,e){return f.info("Decendants of ",e," is ",Me[e]),f.info("Edge is ",t),t.v!==e&&(t.w!==e&&(Me[e]?(f.info("Here "),Me[e].indexOf(t.v)>=0||(!!De(t.v,e)||(!!De(t.w,e)||Me[e].indexOf(t.w)>=0))):(f.debug("Tilt, ",e,",not in decendants"),!1)))}(t,i)?f.info("Skipping copy of edge ",t.v,"--\x3e",t.w," rootId: ",i," clusterId:",e):(f.info("Copying as ",t.v,t.w,a,t.name),r.setEdge(t.v,t.w,a,t.name),f.info("newGraph edges ",r.edges(),r.edge(r.edges()[0])))}catch(t){f.error(t)}}))}f.debug("Removing node",a),n.removeNode(a)}))},Be=function t(e,n){f.trace("Searching",e);var r=n.children(e);if(f.trace("Searching children of id ",e,r),r.length<1)return f.trace("This is a valid node",e),e;for(var i=0;i ",a),a}},Le=function(t){return Ae[t]&&Ae[t].externalConnections&&Ae[t]?Ae[t].id:t},Fe=function(t,e){!t||e>10?f.debug("Opting out, no graph "):(f.debug("Opting in, graph "),t.nodes().forEach((function(e){t.children(e).length>0&&(f.warn("Cluster identified",e," Replacement id in edges: ",Be(e,t)),Me[e]=function t(e,n){for(var r=n.children(e),i=[].concat(r),a=0;a0?(f.debug("Cluster identified",e,Me),r.forEach((function(t){t.v!==e&&t.w!==e&&(De(t.v,e)^De(t.w,e)&&(f.warn("Edge: ",t," leaves cluster ",e),f.warn("Decendants of XXX ",e,": ",Me[e]),Ae[e].externalConnections=!0))}))):f.debug("Not a cluster ",e,Me)})),t.edges().forEach((function(e){var n=t.edge(e);f.warn("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e)),f.warn("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(t.edge(e)));var r=e.v,i=e.w;f.warn("Fix XXX",Ae,"ids:",e.v,e.w,"Translateing: ",Ae[e.v]," --- ",Ae[e.w]),(Ae[e.v]||Ae[e.w])&&(f.warn("Fixing and trixing - removing XXX",e.v,e.w,e.name),r=Le(e.v),i=Le(e.w),t.removeEdge(e.v,e.w,e.name),r!==e.v&&(n.fromCluster=e.v),i!==e.w&&(n.toCluster=e.w),f.warn("Fix Replacing with XXX",r,i,e.name),t.setEdge(r,i,n,e.name))})),f.warn("Adjusted Graph",H.a.json.write(t)),Pe(t,0),f.trace(Ae))},Pe=function t(e,n){if(f.warn("extractor - ",n,H.a.json.write(e),e.children("D")),n>10)f.error("Bailing out");else{for(var r=e.nodes(),i=!1,a=0;a0}if(i){f.debug("Nodes = ",r,n);for(var c=0;c0){f.warn("Cluster without external connections, without a parent and with children",u,n);var l=e.graph(),h=new H.a.Graph({multigraph:!0,compound:!0}).setGraph({rankdir:"TB"===l.rankdir?"LR":"TB",nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));f.warn("Old graph before copy",H.a.json.write(e)),Ne(u,e,h,u),e.setNode(u,{clusterNode:!0,id:u,clusterData:Ae[u].clusterData,labelText:Ae[u].labelText,graph:h}),f.warn("New graph after copy node: (",u,")",H.a.json.write(h)),f.debug("Old graph after copy",H.a.json.write(e))}else f.warn("Cluster ** ",u," **not meeting the criteria !externalConnections:",!Ae[u].externalConnections," no parent: ",!e.parent(u)," children ",e.children(u)&&e.children(u).length>0,e.children("D"),n),f.debug(Ae);else f.debug("Not a cluster",u,n)}r=e.nodes(),f.warn("New list of nodes",r);for(var d=0;d0}var Ue=function(t,e,n,r){var i,a,o,s,c,u,l,h,f,d,p,g,y;if(i=e.y-t.y,o=t.x-e.x,c=e.x*t.y-t.x*e.y,f=i*n.x+o*n.y+c,d=i*r.x+o*r.y+c,!(0!==f&&0!==d&&ze(f,d)||(a=r.y-n.y,s=n.x-r.x,u=r.x*n.y-n.x*r.y,l=a*t.x+s*t.y+u,h=a*e.x+s*e.y+u,0!==l&&0!==h&&ze(l,h)||0==(p=i*s-a*o))))return g=Math.abs(p/2),{x:(y=o*u-s*c)<0?(y-g)/p:(y+g)/p,y:(y=a*c-i*u)<0?(y-g)/p:(y+g)/p}},$e=function(t,e,n){var r=t.x,i=t.y,a=[],o=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach((function(t){o=Math.min(o,t.x),s=Math.min(s,t.y)})):(o=Math.min(o,e.x),s=Math.min(s,e.y));for(var c=r-t.width/2-o,u=i-t.height/2-s,l=0;l1&&a.sort((function(t,e){var r=t.x-n.x,i=t.y-n.y,a=Math.sqrt(r*r+i*i),o=e.x-n.x,s=e.y-n.y,c=Math.sqrt(o*o+s*s);return aMath.abs(o)*u?(s<0&&(u=-u),n=0===s?0:u*o/s,r=u):(o<0&&(c=-c),n=c,r=0===o?0:c*s/o),{x:i+n,y:a+r}},Ve={node:n.n(je).a,circle:Ye,ellipse:Re,polygon:$e,rect:We},He=function(t,e){var n=Te(t,e,"node "+e.classes,!0),r=n.shapeSvg,i=n.bbox,a=n.halfPadding;f.info("Classes = ",e.classes);var o=r.insert("rect",":first-child");return o.attr("rx",e.rx).attr("ry",e.ry).attr("x",-i.width/2-a).attr("y",-i.height/2-a).attr("width",i.width+e.padding).attr("height",i.height+e.padding),Ce(e,o),e.intersect=function(t){return Ve.rect(e,t)},r},Ge=[],qe={},Xe=0,Ze=[],Je=function(t){var e="",n=t;if(t.indexOf("~")>0){var r=t.split("~");n=r[0],e=r[1]}return{className:n,type:e}},Qe=function(t){var e=Je(t);void 0===qe[e.className]&&(qe[e.className]={id:e.className,type:e.type,cssClasses:[],methods:[],members:[],annotations:[],domId:"classid-"+e.className+"-"+Xe},Xe++)},Ke=function(t){for(var e=Object.keys(qe),n=0;n>")?r.annotations.push(i.substring(2,i.length-2)):i.indexOf(")")>0?r.methods.push(i):i&&r.members.push(i)}},en=function(t,e){t.split(",").forEach((function(t){var n=t;t[0].match(/\d/)&&(n="classid-"+n),void 0!==qe[n]&&qe[n].cssClasses.push(e)}))},nn=function(t,e,n){var r=xt(),i=t,a=Ke(i);"loose"===r.securityLevel&&void 0!==e&&void 0!==qe[i]&&(n&&(qe[i].tooltip=x.sanitizeText(n,r)),Ze.push((function(){var t=document.querySelector('[id="'.concat(a,'"]'));null!==t&&t.addEventListener("click",(function(){W.runFunc(e,a)}),!1)})))},rn={AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3},an=function(t){var e=Object(s.select)(".mermaidTooltip");null===(e._groups||e)[0][0]&&(e=Object(s.select)("body").append("div").attr("class","mermaidTooltip").style("opacity",0)),Object(s.select)(t).select("svg").selectAll("g.node").on("mouseover",(function(){var t=Object(s.select)(this);if(null!==t.attr("title")){var n=this.getBoundingClientRect();e.transition().duration(200).style("opacity",".9"),e.html(t.attr("title")).style("left",window.scrollX+n.left+(n.right-n.left)/2+"px").style("top",window.scrollY+n.top-14+document.body.scrollTop+"px"),t.classed("hover",!0)}})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0),Object(s.select)(this).classed("hover",!1)}))};Ze.push(an);var on={parseDirective:function(t,e,n){$o.parseDirective(this,t,e,n)},getConfig:function(){return xt().class},addClass:Qe,bindFunctions:function(t){Ze.forEach((function(e){e(t)}))},clear:function(){Ge=[],qe={},(Ze=[]).push(an)},getClass:function(t){return qe[t]},getClasses:function(){return qe},addAnnotation:function(t,e){var n=Je(t).className;qe[n].annotations.push(e)},getRelations:function(){return Ge},addRelation:function(t){f.debug("Adding relation: "+JSON.stringify(t)),Qe(t.id1),Qe(t.id2),t.id1=Je(t.id1).className,t.id2=Je(t.id2).className,Ge.push(t)},addMember:tn,addMembers:function(t,e){Array.isArray(e)&&(e.reverse(),e.forEach((function(e){return tn(t,e)})))},cleanupLabel:function(t){return":"===t.substring(0,1)?t.substr(1).trim():t.trim()},lineType:{LINE:0,DOTTED_LINE:1},relationType:rn,setClickEvent:function(t,e,n){t.split(",").forEach((function(t){nn(t,e,n),qe[t].haveCallback=!0})),en(t,"clickable")},setCssClass:en,setLink:function(t,e,n){var r=xt();t.split(",").forEach((function(t){var i=t;t[0].match(/\d/)&&(i="classid-"+i),void 0!==qe[i]&&(qe[i].link=W.formatUrl(e,r),n&&(qe[i].tooltip=x.sanitizeText(n,r)))})),en(t,"clickable")},lookUpDomId:Ke},sn=0,cn=function(t){var e=t.match(/(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+)/),n=t.match(/^([+|\-|~|#])?(\w+) *\( *(.*)\) *(\*|\$)? *(\w*[~|[\]]*\s*\w*~?)$/);return e&&!n?un(e):n?ln(n):hn(t)},un=function(t){var e="";try{e=(t[1]?t[1].trim():"")+(t[2]?t[2].trim():"")+(t[3]?dn(t[3].trim()):"")+" "+(t[4]?t[4].trim():"")}catch(n){e=t}return{displayText:e,cssStyle:""}},ln=function(t){var e="",n="";try{var r=t[1]?t[1].trim():"",i=t[2]?t[2].trim():"",a=t[3]?dn(t[3].trim()):"",o=t[4]?t[4].trim():"";n=r+i+"("+a+")"+(t[5]?" : "+dn(t[5]).trim():""),e=pn(o)}catch(e){n=t}return{displayText:n,cssStyle:e}},hn=function(t){var e="",n="",r="",i=t.indexOf("("),a=t.indexOf(")");if(i>1&&a>i&&a<=t.length){var o="",s="",c=t.substring(0,1);c.match(/\w/)?s=t.substring(0,i).trim():(c.match(/\+|-|~|#/)&&(o=c),s=t.substring(1,i).trim());var u=t.substring(i+1,a),l=t.substring(a+1,1);n=pn(l),e=o+s+"("+dn(u.trim())+")",a<"".length&&""!==(r=t.substring(a+2).trim())&&(r=" : "+dn(r))}else e=dn(t);return{displayText:e,cssStyle:n}},fn=function(t,e,n,r){var i=cn(e),a=t.append("tspan").attr("x",r.padding).text(i.displayText);""!==i.cssStyle&&a.attr("style",i.cssStyle),n||a.attr("dy",r.textHeight)},dn=function t(e){var n=e;return-1!=e.indexOf("~")?t(n=(n=n.replace("~","<")).replace("~",">")):n},pn=function(t){switch(t){case"*":return"font-style:italic;";case"$":return"text-decoration:underline;";default:return""}},gn=function(t,e,n){f.info("Rendering class "+e);var r,i=e.id,a={id:i,label:e.id,width:0,height:0},o=t.append("g").attr("id",Ke(i)).attr("class","classGroup");r=e.link?o.append("svg:a").attr("xlink:href",e.link).attr("target","_blank").append("text").attr("y",n.textHeight+n.padding).attr("x",0):o.append("text").attr("y",n.textHeight+n.padding).attr("x",0);var s=!0;e.annotations.forEach((function(t){var e=r.append("tspan").text("«"+t+"»");s||e.attr("dy",n.textHeight),s=!1}));var c=e.id;void 0!==e.type&&""!==e.type&&(c+="<"+e.type+">");var u=r.append("tspan").text(c).attr("class","title");s||u.attr("dy",n.textHeight);var l=r.node().getBBox().height,h=o.append("line").attr("x1",0).attr("y1",n.padding+l+n.dividerMargin/2).attr("y2",n.padding+l+n.dividerMargin/2),d=o.append("text").attr("x",n.padding).attr("y",l+n.dividerMargin+n.textHeight).attr("fill","white").attr("class","classText");s=!0,e.members.forEach((function(t){fn(d,t,s,n),s=!1}));var p=d.node().getBBox(),g=o.append("line").attr("x1",0).attr("y1",n.padding+l+n.dividerMargin+p.height).attr("y2",n.padding+l+n.dividerMargin+p.height),y=o.append("text").attr("x",n.padding).attr("y",l+2*n.dividerMargin+p.height+n.textHeight).attr("fill","white").attr("class","classText");s=!0,e.methods.forEach((function(t){fn(y,t,s,n),s=!1}));var v=o.node().getBBox(),m=" ";e.cssClasses.length>0&&(m+=e.cssClasses.join(" "));var b=o.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",v.width+2*n.padding).attr("height",v.height+n.padding+.5*n.dividerMargin).attr("class",m).node().getBBox().width;return r.node().childNodes.forEach((function(t){t.setAttribute("x",(b-t.getBBox().width)/2)})),e.tooltip&&r.insert("title").text(e.tooltip),h.attr("x2",b),g.attr("x2",b),a.width=b,a.height=v.height+n.padding+.5*n.dividerMargin,a},yn=function(t,e,n,r){var i=function(t){switch(t){case rn.AGGREGATION:return"aggregation";case rn.EXTENSION:return"extension";case rn.COMPOSITION:return"composition";case rn.DEPENDENCY:return"dependency"}};e.points=e.points.filter((function(t){return!Number.isNaN(t.y)}));var a,o,c=e.points,u=Object(s.line)().x((function(t){return t.x})).y((function(t){return t.y})).curve(s.curveBasis),l=t.append("path").attr("d",u(c)).attr("id","edge"+sn).attr("class","relation"),h="";r.arrowMarkerAbsolute&&(h=(h=(h=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search).replace(/\(/g,"\\(")).replace(/\)/g,"\\)")),1==n.relation.lineType&&l.attr("class","relation dashed-line"),"none"!==n.relation.type1&&l.attr("marker-start","url("+h+"#"+i(n.relation.type1)+"Start)"),"none"!==n.relation.type2&&l.attr("marker-end","url("+h+"#"+i(n.relation.type2)+"End)");var d,p,g,y,v=e.points.length,m=W.calcLabelPosition(e.points);if(a=m.x,o=m.y,v%2!=0&&v>1){var b=W.calcCardinalityPosition("none"!==n.relation.type1,e.points,e.points[0]),x=W.calcCardinalityPosition("none"!==n.relation.type2,e.points,e.points[v-1]);f.debug("cardinality_1_point "+JSON.stringify(b)),f.debug("cardinality_2_point "+JSON.stringify(x)),d=b.x,p=b.y,g=x.x,y=x.y}if(void 0!==n.title){var _=t.append("g").attr("class","classLabel"),k=_.append("text").attr("class","label").attr("x",a).attr("y",o).attr("fill","red").attr("text-anchor","middle").text(n.title);window.label=k;var w=k.node().getBBox();_.insert("rect",":first-child").attr("class","box").attr("x",w.x-r.padding/2).attr("y",w.y-r.padding/2).attr("width",w.width+r.padding).attr("height",w.height+r.padding)}(f.info("Rendering relation "+JSON.stringify(n)),void 0!==n.relationTitle1&&"none"!==n.relationTitle1)&&t.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",d).attr("y",p).attr("fill","black").attr("font-size","6").text(n.relationTitle1);void 0!==n.relationTitle2&&"none"!==n.relationTitle2&&t.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",g).attr("y",y).attr("fill","black").attr("font-size","6").text(n.relationTitle2);sn++},vn=function(t,e,n){var r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),i=70,a=10;"LR"===n&&(i=10,a=70);var o=r.append("rect").style("stroke","black").style("fill","black").attr("x",-1*i/2).attr("y",-1*a/2).attr("width",i).attr("height",a).attr("class","fork-join");return Ce(e,o),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(t){return Ve.rect(e,t)},r},mn={question:function(t,e){var n=Te(t,e,void 0,!0),r=n.shapeSvg,i=n.bbox,a=i.width+e.padding+(i.height+e.padding),o=[{x:a/2,y:0},{x:a,y:-a/2},{x:a/2,y:-a},{x:0,y:-a/2}];f.info("Question main (Circle)");var s=Se(r,a,a,o);return Ce(e,s),e.intersect=function(t){return f.warn("Intersect called"),Ve.polygon(e,o,t)},r},rect:function(t,e){var n=Te(t,e,"node "+e.classes,!0),r=n.shapeSvg,i=n.bbox,a=n.halfPadding;f.trace("Classes = ",e.classes);var o=r.insert("rect",":first-child");return o.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",-i.width/2-a).attr("y",-i.height/2-a).attr("width",i.width+e.padding).attr("height",i.height+e.padding),Ce(e,o),e.intersect=function(t){return Ve.rect(e,t)},r},rectWithTitle:function(t,e){var n;n=e.classes?"node "+e.classes:"node default";var r=t.insert("g").attr("class",n).attr("id",e.domId||e.id),i=r.insert("rect",":first-child"),a=r.insert("line"),o=r.insert("g").attr("class","label"),c=e.labelText.flat();f.info("Label text",c[0]);var u,l=o.node().appendChild(Ee(c[0],e.labelStyle,!0,!0));if(xt().flowchart.htmlLabels){var h=l.children[0],d=Object(s.select)(l);u=h.getBoundingClientRect(),d.attr("width",u.width),d.attr("height",u.height)}f.info("Text 2",c);var p=c.slice(1,c.length),g=l.getBBox(),y=o.node().appendChild(Ee(p.join("
"),e.labelStyle,!0,!0));if(xt().flowchart.htmlLabels){var v=y.children[0],m=Object(s.select)(y);u=v.getBoundingClientRect(),m.attr("width",u.width),m.attr("height",u.height)}var b=e.padding/2;return Object(s.select)(y).attr("transform","translate( "+(u.width>g.width?0:(g.width-u.width)/2)+", "+(g.height+b+5)+")"),Object(s.select)(l).attr("transform","translate( "+(u.widthe.height/2-s)){var i=s*s*(1-r*r/(o*o));0!=i&&(i=Math.sqrt(i)),i=s-i,t.y-e.y>0&&(i=-i),n.y+=i}return n},r},start:function(t,e){var n=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),r=n.insert("circle",":first-child");return r.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),Ce(e,r),e.intersect=function(t){return Ve.circle(e,7,t)},n},end:function(t,e){var n=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),r=n.insert("circle",":first-child"),i=n.insert("circle",":first-child");return i.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),r.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),Ce(e,i),e.intersect=function(t){return Ve.circle(e,7,t)},n},note:He,subroutine:function(t,e){var n=Te(t,e,void 0,!0),r=n.shapeSvg,i=n.bbox,a=i.width+e.padding,o=i.height+e.padding,s=Se(r,a,o,[{x:0,y:0},{x:a,y:0},{x:a,y:-o},{x:0,y:-o},{x:0,y:0},{x:-8,y:0},{x:a+8,y:0},{x:a+8,y:-o},{x:-8,y:-o},{x:-8,y:0}]);return Ce(e,s),e.intersect=function(t){return Ve.polygon(e,t)},r},fork:vn,join:vn,class_box:function(t,e){var n,r=e.padding/2;n=e.classes?"node "+e.classes:"node default";var i=t.insert("g").attr("class",n).attr("id",e.domId||e.id),a=i.insert("rect",":first-child"),o=i.insert("line"),c=i.insert("line"),u=0,l=4,h=i.insert("g").attr("class","label"),f=0,d=e.classData.annotations&&e.classData.annotations[0],p=e.classData.annotations[0]?"«"+e.classData.annotations[0]+"»":"",g=h.node().appendChild(Ee(p,e.labelStyle,!0,!0)),y=g.getBBox();if(xt().flowchart.htmlLabels){var v=g.children[0],m=Object(s.select)(g);y=v.getBoundingClientRect(),m.attr("width",y.width),m.attr("height",y.height)}e.classData.annotations[0]&&(l+=y.height+4,u+=y.width);var b=e.classData.id;void 0!==e.classData.type&&""!==e.classData.type&&(b+="<"+e.classData.type+">");var x=h.node().appendChild(Ee(b,e.labelStyle,!0,!0));Object(s.select)(x).attr("class","classTitle");var _=x.getBBox();if(xt().flowchart.htmlLabels){var k=x.children[0],w=Object(s.select)(x);_=k.getBoundingClientRect(),w.attr("width",_.width),w.attr("height",_.height)}l+=_.height+4,_.width>u&&(u=_.width);var E=[];e.classData.members.forEach((function(t){var n=cn(t).displayText,r=h.node().appendChild(Ee(n,e.labelStyle,!0,!0)),i=r.getBBox();if(xt().flowchart.htmlLabels){var a=r.children[0],o=Object(s.select)(r);i=a.getBoundingClientRect(),o.attr("width",i.width),o.attr("height",i.height)}i.width>u&&(u=i.width),l+=i.height+4,E.push(r)})),l+=8;var T=[];if(e.classData.methods.forEach((function(t){var n=cn(t).displayText,r=h.node().appendChild(Ee(n,e.labelStyle,!0,!0)),i=r.getBBox();if(xt().flowchart.htmlLabels){var a=r.children[0],o=Object(s.select)(r);i=a.getBoundingClientRect(),o.attr("width",i.width),o.attr("height",i.height)}i.width>u&&(u=i.width),l+=i.height+4,T.push(r)})),l+=8,d){var C=(u-y.width)/2;Object(s.select)(g).attr("transform","translate( "+(-1*u/2+C)+", "+-1*l/2+")"),f=y.height+4}var S=(u-_.width)/2;return Object(s.select)(x).attr("transform","translate( "+(-1*u/2+S)+", "+(-1*l/2+f)+")"),f+=_.height+4,o.attr("class","divider").attr("x1",-u/2-r).attr("x2",u/2+r).attr("y1",-l/2-r+8+f).attr("y2",-l/2-r+8+f),f+=8,E.forEach((function(t){Object(s.select)(t).attr("transform","translate( "+-u/2+", "+(-1*l/2+f+4)+")"),f+=_.height+4})),f+=8,c.attr("class","divider").attr("x1",-u/2-r).attr("x2",u/2+r).attr("y1",-l/2-r+8+f).attr("y2",-l/2-r+8+f),f+=8,T.forEach((function(t){Object(s.select)(t).attr("transform","translate( "+-u/2+", "+(-1*l/2+f)+")"),f+=_.height+4})),a.attr("class","outer title-state").attr("x",-u/2-r).attr("y",-l/2-r).attr("width",u+e.padding).attr("height",l+e.padding),Ce(e,a),e.intersect=function(t){return Ve.rect(e,t)},i}},bn={},xn=function(t){var e=bn[t.id];f.trace("Transforming node",t,"translate("+(t.x-t.width/2-5)+", "+(t.y-t.height/2-5)+")");t.clusterNode?e.attr("transform","translate("+(t.x-t.width/2-8)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")")},_n={rect:function(t,e){f.trace("Creating subgraph rect for ",e.id,e);var n=t.insert("g").attr("class","cluster"+(e.class?" "+e.class:"")).attr("id",e.id),r=n.insert("rect",":first-child"),i=n.insert("g").attr("class","cluster-label"),a=i.node().appendChild(Ee(e.labelText,e.labelStyle,void 0,!0)),o=a.getBBox();if(xt().flowchart.htmlLabels){var c=a.children[0],u=Object(s.select)(a);o=c.getBoundingClientRect(),u.attr("width",o.width),u.attr("height",o.height)}var l=0*e.padding,h=l/2;f.trace("Data ",e,JSON.stringify(e)),r.attr("rx",e.rx).attr("ry",e.ry).attr("x",e.x-e.width/2-h).attr("y",e.y-e.height/2-h).attr("width",e.width+l).attr("height",e.height+l),i.attr("transform","translate("+(e.x-o.width/2)+", "+(e.y-e.height/2-e.padding/3+3)+")");var d=r.node().getBBox();return e.width=d.width,e.height=d.height,e.intersect=function(t){return We(e,t)},n},roundedWithTitle:function(t,e){var n=t.insert("g").attr("class",e.classes).attr("id",e.id),r=n.insert("rect",":first-child"),i=n.insert("g").attr("class","cluster-label"),a=n.append("rect"),o=i.node().appendChild(Ee(e.labelText,e.labelStyle,void 0,!0)),c=o.getBBox();if(xt().flowchart.htmlLabels){var u=o.children[0],l=Object(s.select)(o);c=u.getBoundingClientRect(),l.attr("width",c.width),l.attr("height",c.height)}c=o.getBBox();var h=0*e.padding,f=h/2;r.attr("class","outer").attr("x",e.x-e.width/2-f).attr("y",e.y-e.height/2-f).attr("width",e.width+h).attr("height",e.height+h),a.attr("class","inner").attr("x",e.x-e.width/2-f).attr("y",e.y-e.height/2-f+c.height-1).attr("width",e.width+h).attr("height",e.height+h-c.height-3),i.attr("transform","translate("+(e.x-c.width/2)+", "+(e.y-e.height/2-e.padding/3+(xt().flowchart.htmlLabels?5:3))+")");var d=r.node().getBBox();return e.width=d.width,e.height=d.height,e.intersect=function(t){return We(e,t)},n},noteGroup:function(t,e){var n=t.insert("g").attr("class","note-cluster").attr("id",e.id),r=n.insert("rect",":first-child"),i=0*e.padding,a=i/2;r.attr("rx",e.rx).attr("ry",e.ry).attr("x",e.x-e.width/2-a).attr("y",e.y-e.height/2-a).attr("width",e.width+i).attr("height",e.height+i).attr("fill","none");var o=r.node().getBBox();return e.width=o.width,e.height=o.height,e.intersect=function(t){return We(e,t)},n},divider:function(t,e){var n=t.insert("g").attr("class",e.classes).attr("id",e.id),r=n.insert("rect",":first-child"),i=0*e.padding,a=i/2;r.attr("class","divider").attr("x",e.x-e.width/2-a).attr("y",e.y-e.height/2).attr("width",e.width+i).attr("height",e.height+i);var o=r.node().getBBox();return e.width=o.width,e.height=o.height,e.intersect=function(t){return We(e,t)},n}},kn={},wn={},En={},Tn=function(t,e){var n=t.x,r=t.y,i=Math.abs(e.x-n),a=Math.abs(e.y-r),o=t.width/2,s=t.height/2;return i>=o||a>=s},Cn=function(t,e,n){f.warn("intersection calc o:",e," i:",n,t);var r=t.x,i=t.y,a=Math.abs(r-n.x),o=t.width/2,s=n.xMath.abs(r-e.x)*c){var y=n.y0&&f.info("Recursive edges",n.edge(n.edges()[0]));var c=o.insert("g").attr("class","clusters"),u=o.insert("g").attr("class","edgePaths"),l=o.insert("g").attr("class","edgeLabels"),h=o.insert("g").attr("class","nodes");return n.nodes().forEach((function(e){var o=n.node(e);if(void 0!==i){var s=JSON.parse(JSON.stringify(i.clusterData));f.info("Setting data for cluster XXX (",e,") ",s,i),n.setNode(i.id,s),n.parent(e)||(f.warn("Setting parent",e,i.id),n.setParent(e,i.id,s))}if(f.info("(Insert) Node XXX"+e+": "+JSON.stringify(n.node(e))),o&&o.clusterNode){f.info("Cluster identified",e,o,n.node(e));var c=t(h,o.graph,r,n.node(e));Ce(o,c),function(t,e){bn[e.id]=t}(c,o),f.warn("Recursive render complete",c,o)}else n.children(e).length>0?(f.info("Cluster - the non recursive path XXX",e,o.id,o,n),f.info(Be(o.id,n)),Ae[o.id]={id:Be(o.id,n),node:o}):(f.info("Node - the non recursive path",e,o.id,o),function(t,e,n){var r,i;e.link?(r=t.insert("svg:a").attr("xlink:href",e.link).attr("target",e.linkTarget||"_blank"),i=mn[e.shape](r,e,n)):r=i=mn[e.shape](t,e,n),e.tooltip&&i.attr("title",e.tooltip),e.class&&i.attr("class","node default "+e.class),bn[e.id]=r,e.haveCallback&&bn[e.id].attr("class",bn[e.id].attr("class")+" clickable")}(h,n.node(e),a))})),n.edges().forEach((function(t){var e=n.edge(t.v,t.w,t.name);f.info("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(t)),f.info("Edge "+t.v+" -> "+t.w+": ",t," ",JSON.stringify(n.edge(t))),f.info("Fix",Ae,"ids:",t.v,t.w,"Translateing: ",Ae[t.v],Ae[t.w]),function(t,e){var n=Ee(e.label,e.labelStyle),r=t.insert("g").attr("class","edgeLabel"),i=r.insert("g").attr("class","label");i.node().appendChild(n);var a=n.getBBox();if(xt().flowchart.htmlLabels){var o=n.children[0],c=Object(s.select)(n);a=o.getBoundingClientRect(),c.attr("width",a.width),c.attr("height",a.height)}if(i.attr("transform","translate("+-a.width/2+", "+-a.height/2+")"),wn[e.id]=r,e.width=a.width,e.height=a.height,e.startLabelLeft){var u=Ee(e.startLabelLeft,e.labelStyle),l=t.insert("g").attr("class","edgeTerminals"),h=l.insert("g").attr("class","inner");h.node().appendChild(u);var f=u.getBBox();h.attr("transform","translate("+-f.width/2+", "+-f.height/2+")"),En[e.id]||(En[e.id]={}),En[e.id].startLeft=l}if(e.startLabelRight){var d=Ee(e.startLabelRight,e.labelStyle),p=t.insert("g").attr("class","edgeTerminals"),g=p.insert("g").attr("class","inner");p.node().appendChild(d),g.node().appendChild(d);var y=d.getBBox();g.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"),En[e.id]||(En[e.id]={}),En[e.id].startRight=p}if(e.endLabelLeft){var v=Ee(e.endLabelLeft,e.labelStyle),m=t.insert("g").attr("class","edgeTerminals"),b=m.insert("g").attr("class","inner");b.node().appendChild(v);var x=v.getBBox();b.attr("transform","translate("+-x.width/2+", "+-x.height/2+")"),m.node().appendChild(v),En[e.id]||(En[e.id]={}),En[e.id].endLeft=m}if(e.endLabelRight){var _=Ee(e.endLabelRight,e.labelStyle),k=t.insert("g").attr("class","edgeTerminals"),w=k.insert("g").attr("class","inner");w.node().appendChild(_);var E=_.getBBox();w.attr("transform","translate("+-E.width/2+", "+-E.height/2+")"),k.node().appendChild(_),En[e.id]||(En[e.id]={}),En[e.id].endRight=k}}(l,e)})),n.edges().forEach((function(t){f.info("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(t))})),f.info("#############################################"),f.info("### Layout ###"),f.info("#############################################"),f.info(n),_e.a.layout(n),f.info("Graph after layout:",H.a.json.write(n)),Ie(n).forEach((function(t){var e=n.node(t);f.info("Position "+t+": "+JSON.stringify(n.node(t))),f.info("Position "+t+": ("+e.x,","+e.y,") width: ",e.width," height: ",e.height),e&&e.clusterNode?xn(e):n.children(t).length>0?(!function(t,e){f.trace("Inserting cluster");var n=e.shape||"rect";kn[e.id]=_n[n](t,e)}(c,e),Ae[e.id].node=e):xn(e)})),n.edges().forEach((function(t){var e=n.edge(t);f.info("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(e),e);var i=function(t,e,n,r,i,a){var o=n.points,c=!1,u=a.node(e.v),l=a.node(e.w);if(l.intersect&&u.intersect&&((o=o.slice(1,n.points.length-1)).unshift(u.intersect(o[0])),f.info("Last point",o[o.length-1],l,l.intersect(o[o.length-1])),o.push(l.intersect(o[o.length-1]))),n.toCluster){var h;f.trace("edge",n),f.trace("to cluster",r[n.toCluster]),o=[];var d=!1;n.points.forEach((function(t){var e=r[n.toCluster].node;if(Tn(e,t)||d)d||o.push(t);else{f.trace("inside",n.toCluster,t,h);var i=Cn(e,h,t),a=!1;o.forEach((function(t){a=a||t.x===i.x&&t.y===i.y})),o.find((function(t){return t.x===i.x&&t.y===i.y}))?f.warn("no intersect",i,o):o.push(i),d=!0}h=t})),c=!0}if(n.fromCluster){f.trace("edge",n),f.warn("from cluster",r[n.fromCluster]);for(var p,g=[],y=!1,v=o.length-1;v>=0;v--){var m=o[v],b=r[n.fromCluster].node;if(Tn(b,m)||y)f.trace("Outside point",m),y||g.unshift(m);else{f.warn("inside",n.fromCluster,m,b);var x=Cn(b,p,m);g.unshift(x),y=!0}p=m}o=g,c=!0}var _,k=o.filter((function(t){return!Number.isNaN(t.y)})),w=Object(s.line)().x((function(t){return t.x})).y((function(t){return t.y})).curve(s.curveBasis);switch(n.thickness){case"normal":_="edge-thickness-normal";break;case"thick":_="edge-thickness-thick";break;default:_=""}switch(n.pattern){case"solid":_+=" edge-pattern-solid";break;case"dotted":_+=" edge-pattern-dotted";break;case"dashed":_+=" edge-pattern-dashed"}var E=t.append("path").attr("d",w(k)).attr("id",n.id).attr("class"," "+_+(n.classes?" "+n.classes:"")).attr("style",n.style),T="";switch(xt().state.arrowMarkerAbsolute&&(T=(T=(T=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search).replace(/\(/g,"\\(")).replace(/\)/g,"\\)")),f.info("arrowTypeStart",n.arrowTypeStart),f.info("arrowTypeEnd",n.arrowTypeEnd),n.arrowTypeStart){case"arrow_cross":E.attr("marker-start","url("+T+"#"+i+"-crossStart)");break;case"arrow_point":E.attr("marker-start","url("+T+"#"+i+"-pointStart)");break;case"arrow_barb":E.attr("marker-start","url("+T+"#"+i+"-barbStart)");break;case"arrow_circle":E.attr("marker-start","url("+T+"#"+i+"-circleStart)");break;case"aggregation":E.attr("marker-start","url("+T+"#"+i+"-aggregationStart)");break;case"extension":E.attr("marker-start","url("+T+"#"+i+"-extensionStart)");break;case"composition":E.attr("marker-start","url("+T+"#"+i+"-compositionStart)");break;case"dependency":E.attr("marker-start","url("+T+"#"+i+"-dependencyStart)")}switch(n.arrowTypeEnd){case"arrow_cross":E.attr("marker-end","url("+T+"#"+i+"-crossEnd)");break;case"arrow_point":E.attr("marker-end","url("+T+"#"+i+"-pointEnd)");break;case"arrow_barb":E.attr("marker-end","url("+T+"#"+i+"-barbEnd)");break;case"arrow_circle":E.attr("marker-end","url("+T+"#"+i+"-circleEnd)");break;case"aggregation":E.attr("marker-end","url("+T+"#"+i+"-aggregationEnd)");break;case"extension":E.attr("marker-end","url("+T+"#"+i+"-extensionEnd)");break;case"composition":E.attr("marker-end","url("+T+"#"+i+"-compositionEnd)");break;case"dependency":E.attr("marker-end","url("+T+"#"+i+"-dependencyEnd)")}var C={};return c&&(C.updatedPath=o),C.originalPath=n.points,C}(u,t,e,Ae,r,n);!function(t,e){f.info("Moving label",t.id,t.label,wn[t.id]);var n=e.updatedPath?e.updatedPath:e.originalPath;if(t.label){var r=wn[t.id],i=t.x,a=t.y;if(n){var o=W.calcLabelPosition(n);f.info("Moving label from (",i,",",a,") to (",o.x,",",o.y,")")}r.attr("transform","translate("+i+", "+a+")")}if(t.startLabelLeft){var s=En[t.id].startLeft,c=t.x,u=t.y;if(n){var l=W.calcTerminalLabelPosition(0,"start_left",n);c=l.x,u=l.y}s.attr("transform","translate("+c+", "+u+")")}if(t.startLabelRight){var h=En[t.id].startRight,d=t.x,p=t.y;if(n){var g=W.calcTerminalLabelPosition(0,"start_right",n);d=g.x,p=g.y}h.attr("transform","translate("+d+", "+p+")")}if(t.endLabelLeft){var y=En[t.id].endLeft,v=t.x,m=t.y;if(n){var b=W.calcTerminalLabelPosition(0,"end_left",n);v=b.x,m=b.y}y.attr("transform","translate("+v+", "+m+")")}if(t.endLabelRight){var x=En[t.id].endRight,_=t.x,k=t.y;if(n){var w=W.calcTerminalLabelPosition(0,"end_right",n);_=w.x,k=w.y}x.attr("transform","translate("+_+", "+k+")")}}(e,i)})),o},An=function(t,e,n,r,i){we(t,n,r,i),bn={},wn={},En={},kn={},Me={},Oe={},Ae={},f.warn("Graph at first:",H.a.json.write(e)),Fe(e),f.warn("Graph after:",H.a.json.write(e)),Sn(t,e,r)},Mn={},On=function(t,e,n){var r=Object(s.select)('[id="'.concat(n,'"]'));Object.keys(t).forEach((function(n){var i=t[n],a="default";i.classes.length>0&&(a=i.classes.join(" "));var o,s=N(i.styles),c=void 0!==i.text?i.text:i.id;if(xt().flowchart.htmlLabels){var u={label:c.replace(/fa[lrsb]?:fa-[\w-]+/g,(function(t){return"")}))};(o=te()(r,u).node()).parentNode.removeChild(o)}else{var l=document.createElementNS("http://www.w3.org/2000/svg","text");l.setAttribute("style",s.labelStyle.replace("color:","fill:"));for(var h=c.split(x.lineBreakRegex),d=0;d=0;h--)i=l[h],f.info("Subgraph - ",i),qt.addVertex(i.id,i.title,"group",void 0,i.classes);var d=qt.getVertices(),p=qt.getEdges();f.info(p);var g=0;for(g=l.length-1;g>=0;g--){i=l[g],Object(s.selectAll)("cluster").append("text");for(var y=0;y0)switch(e.valign){case"top":case"start":s=function(){return Math.round(e.y+e.textMargin)};break;case"middle":case"center":s=function(){return Math.round(e.y+(n+r+e.textMargin)/2)};break;case"bottom":case"end":s=function(){return Math.round(e.y+(n+r+2*e.textMargin)-e.textMargin)}}if(void 0!==e.anchor&&void 0!==e.textMargin&&void 0!==e.width)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="text-after-edge",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="text-before-edge",e.alignmentBaseline="middle"}for(var c=0;c0&&(r+=(l._groups||l)[0][0].getBBox().height,n=r),a.push(l)}return a},Pn=function(t,e){var n,r,i,a,o,s=t.append("polygon");return s.attr("points",(n=e.x,r=e.y,i=e.width,a=e.height,n+","+r+" "+(n+i)+","+r+" "+(n+i)+","+(r+a-(o=7))+" "+(n+i-1.2*o)+","+(r+a)+" "+n+","+(r+a))),s.attr("class","labelBox"),e.y=e.y+e.height/2,Fn(t,e),s},In=-1,jn=function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}},Rn=function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},Yn=function(){function t(t,e,n,i,a,o,s){r(e.append("text").attr("x",n+a/2).attr("y",i+o/2+5).style("text-anchor","middle").text(t),s)}function e(t,e,n,i,a,o,s,c){for(var u=c.actorFontSize,l=c.actorFontFamily,h=c.actorFontWeight,f=t.split(x.lineBreakRegex),d=0;d2&&void 0!==arguments[2]?arguments[2]:{text:void 0,wrap:void 0},r=arguments.length>3?arguments[3]:void 0;if(r===nr.ACTIVE_END){var i=Kn(t.actor);if(i<1){var a=new Error("Trying to inactivate an inactive participant ("+t.actor+")");throw a.hash={text:"->>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},a}}return Hn.push({from:t,to:e,message:n.text,wrap:void 0===n.wrap&&er()||!!n.wrap,type:r}),!0},er=function(){return Jn},nr={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23},rr=function(t,e,n){var r={actor:t,placement:e,message:n.text,wrap:void 0===n.wrap&&er()||!!n.wrap},i=[].concat(t,t);Gn.push(r),Hn.push({from:i[0],to:i[1],message:n.text,wrap:void 0===n.wrap&&er()||!!n.wrap,type:nr.NOTE,placement:e})},ir=function(t){qn=t.text,Xn=void 0===t.wrap&&er()||!!t.wrap},ar={addActor:Qn,addMessage:function(t,e,n,r){Hn.push({from:t,to:e,message:n.text,wrap:void 0===n.wrap&&er()||!!n.wrap,answer:r})},addSignal:tr,autoWrap:er,setWrap:function(t){Jn=t},enableSequenceNumbers:function(){Zn=!0},showSequenceNumbers:function(){return Zn},getMessages:function(){return Hn},getActors:function(){return Vn},getActor:function(t){return Vn[t]},getActorKeys:function(){return Object.keys(Vn)},getTitle:function(){return qn},parseDirective:function(t,e,n){$o.parseDirective(this,t,e,n)},getConfig:function(){return xt().sequence},getTitleWrapped:function(){return Xn},clear:function(){Vn={},Hn=[]},parseMessage:function(t){var e=t.trim(),n={text:e.replace(/^[:]?(?:no)?wrap:/,"").trim(),wrap:null===e.match(/^[:]?(?:no)?wrap:/)?x.hasBreaks(e)||void 0:null!==e.match(/^[:]?wrap:/)||null===e.match(/^[:]?nowrap:/)&&void 0};return f.debug("parseMessage:",n),n},LINETYPE:nr,ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},addNote:rr,setTitle:ir,apply:function t(e){if(e instanceof Array)e.forEach((function(e){t(e)}));else switch(e.type){case"addActor":Qn(e.actor,e.actor,e.description);break;case"activeStart":case"activeEnd":tr(e.actor,void 0,void 0,e.signalType);break;case"addNote":rr(e.actor,e.placement,e.text);break;case"addMessage":tr(e.from,e.to,e.msg,e.signalType);break;case"loopStart":tr(void 0,void 0,e.loopText,e.signalType);break;case"loopEnd":tr(void 0,void 0,void 0,e.signalType);break;case"rectStart":tr(void 0,void 0,e.color,e.signalType);break;case"rectEnd":tr(void 0,void 0,void 0,e.signalType);break;case"optStart":tr(void 0,void 0,e.optText,e.signalType);break;case"optEnd":tr(void 0,void 0,void 0,e.signalType);break;case"altStart":case"else":tr(void 0,void 0,e.altText,e.signalType);break;case"altEnd":tr(void 0,void 0,void 0,e.signalType);break;case"setTitle":ir(e.text);break;case"parStart":case"and":tr(void 0,void 0,e.parText,e.signalType);break;case"parEnd":tr(void 0,void 0,void 0,e.signalType)}}};Un.parser.yy=ar;var or={},sr={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:function(){return Math.max.apply(null,0===this.actors.length?[0]:this.actors.map((function(t){return t.height||0})))+(0===this.loops.length?0:this.loops.map((function(t){return t.height||0})).reduce((function(t,e){return t+e})))+(0===this.messages.length?0:this.messages.map((function(t){return t.height||0})).reduce((function(t,e){return t+e})))+(0===this.notes.length?0:this.notes.map((function(t){return t.height||0})).reduce((function(t,e){return t+e})))},clear:function(){this.actors=[],this.loops=[],this.messages=[],this.notes=[]},addActor:function(t){this.actors.push(t)},addLoop:function(t){this.loops.push(t)},addMessage:function(t){this.messages.push(t)},addNote:function(t){this.notes.push(t)},lastActor:function(){return this.actors[this.actors.length-1]},lastLoop:function(){return this.loops[this.loops.length-1]},lastMessage:function(){return this.messages[this.messages.length-1]},lastNote:function(){return this.notes[this.notes.length-1]},actors:[],loops:[],messages:[],notes:[]},init:function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,fr(Un.parser.yy.getConfig())},updateVal:function(t,e,n,r){void 0===t[e]?t[e]=n:t[e]=r(n,t[e])},updateBounds:function(t,e,n,r){var i=this,a=0;function o(o){return function(s){a++;var c=i.sequenceItems.length-a+1;i.updateVal(s,"starty",e-c*or.boxMargin,Math.min),i.updateVal(s,"stopy",r+c*or.boxMargin,Math.max),i.updateVal(sr.data,"startx",t-c*or.boxMargin,Math.min),i.updateVal(sr.data,"stopx",n+c*or.boxMargin,Math.max),"activation"!==o&&(i.updateVal(s,"startx",t-c*or.boxMargin,Math.min),i.updateVal(s,"stopx",n+c*or.boxMargin,Math.max),i.updateVal(sr.data,"starty",e-c*or.boxMargin,Math.min),i.updateVal(sr.data,"stopy",r+c*or.boxMargin,Math.max))}}this.sequenceItems.forEach(o()),this.activations.forEach(o("activation"))},insert:function(t,e,n,r){var i=Math.min(t,n),a=Math.max(t,n),o=Math.min(e,r),s=Math.max(e,r);this.updateVal(sr.data,"startx",i,Math.min),this.updateVal(sr.data,"starty",o,Math.min),this.updateVal(sr.data,"stopx",a,Math.max),this.updateVal(sr.data,"stopy",s,Math.max),this.updateBounds(i,o,a,s)},newActivation:function(t,e,n){var r=n[t.from.actor],i=dr(t.from.actor).length||0,a=r.x+r.width/2+(i-1)*or.activationWidth/2;this.activations.push({startx:a,starty:this.verticalPos+2,stopx:a+or.activationWidth,stopy:void 0,actor:t.from.actor,anchored:zn.anchorElement(e)})},endActivation:function(t){var e=this.activations.map((function(t){return t.actor})).lastIndexOf(t.from.actor);return this.activations.splice(e,1)[0]},createLoop:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{message:void 0,wrap:!1,width:void 0},e=arguments.length>1?arguments[1]:void 0;return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},newLoop:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{message:void 0,wrap:!1,width:void 0},e=arguments.length>1?arguments[1]:void 0;this.sequenceItems.push(this.createLoop(t,e))},endLoop:function(){return this.sequenceItems.pop()},addSectionToLoop:function(t){var e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:sr.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return{bounds:this.data,models:this.models}}},cr=function(t){return{fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}},ur=function(t){return{fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}},lr=function(t){return{fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight}},hr=function(t,e,n,r){for(var i=0,a=0,o=0;o0&&o.forEach((function(r){if(n=r,i.startx===i.stopx){var a=e[t.from],o=e[t.to];n.from=Math.min(a.x-i.width/2,a.x-a.width/2,n.from),n.to=Math.max(o.x+i.width/2,o.x+a.width/2,n.to),n.width=Math.max(n.width,Math.abs(n.to-n.from))-or.labelBoxWidth}else n.from=Math.min(i.startx,n.from),n.to=Math.max(i.stopx,n.to),n.width=Math.max(n.width,i.width)-or.labelBoxWidth})))})),sr.activations=[],f.debug("Loop type widths:",a),a},br={bounds:sr,drawActors:hr,setConf:fr,draw:function(t,e){or=xt().sequence,Un.parser.yy.clear(),Un.parser.yy.setWrap(or.wrap),Un.parser.parse(t+"\n"),sr.init(),f.debug("C:".concat(JSON.stringify(or,null,2)));var n=Object(s.select)('[id="'.concat(e,'"]')),r=Un.parser.yy.getActors(),i=Un.parser.yy.getActorKeys(),a=Un.parser.yy.getMessages(),o=Un.parser.yy.getTitle(),c=yr(r,a);or.height=vr(r,c),hr(n,r,i,0);var u=mr(a,r,c);zn.insertArrowHead(n),zn.insertArrowCrossHead(n),zn.insertSequenceNumber(n);var l=1;a.forEach((function(t){var e,i,a;switch(t.type){case Un.parser.yy.LINETYPE.NOTE:i=t.noteModel,function(t,e){sr.bumpVerticalPos(or.boxMargin),e.height=or.boxMargin,e.starty=sr.getVerticalPos();var n=zn.getNoteRect();n.x=e.startx,n.y=e.starty,n.width=e.width||or.width,n.class="note";var r=t.append("g"),i=zn.drawRect(r,n),a=zn.getTextObj();a.x=e.startx,a.y=e.starty,a.width=n.width,a.dy="1em",a.text=e.message,a.class="noteText",a.fontFamily=or.noteFontFamily,a.fontSize=or.noteFontSize,a.fontWeight=or.noteFontWeight,a.anchor=or.noteAlign,a.textMargin=or.noteMargin,a.valign=or.noteAlign,a.wrap=!0;var o=Fn(r,a),s=Math.round(o.map((function(t){return(t._groups||t)[0][0].getBBox().height})).reduce((function(t,e){return t+e})));i.attr("height",s+2*or.noteMargin),e.height+=s+2*or.noteMargin,sr.bumpVerticalPos(s+2*or.noteMargin),e.stopy=e.starty+s+2*or.noteMargin,e.stopx=e.startx+n.width,sr.insert(e.startx,e.starty,e.stopx,e.stopy),sr.models.addNote(e)}(n,i);break;case Un.parser.yy.LINETYPE.ACTIVE_START:sr.newActivation(t,n,r);break;case Un.parser.yy.LINETYPE.ACTIVE_END:!function(t,e){var r=sr.endActivation(t);r.starty+18>e&&(r.starty=e-6,e+=12),zn.drawActivation(n,r,e,or,dr(t.from.actor).length),sr.insert(r.startx,e-10,r.stopx,e)}(t,sr.getVerticalPos());break;case Un.parser.yy.LINETYPE.LOOP_START:gr(u,t,or.boxMargin,or.boxMargin+or.boxTextMargin,(function(t){return sr.newLoop(t)}));break;case Un.parser.yy.LINETYPE.LOOP_END:e=sr.endLoop(),zn.drawLoop(n,e,"loop",or),sr.bumpVerticalPos(e.stopy-sr.getVerticalPos()),sr.models.addLoop(e);break;case Un.parser.yy.LINETYPE.RECT_START:gr(u,t,or.boxMargin,or.boxMargin,(function(t){return sr.newLoop(void 0,t.message)}));break;case Un.parser.yy.LINETYPE.RECT_END:e=sr.endLoop(),zn.drawBackgroundRect(n,e),sr.models.addLoop(e),sr.bumpVerticalPos(e.stopy-sr.getVerticalPos());break;case Un.parser.yy.LINETYPE.OPT_START:gr(u,t,or.boxMargin,or.boxMargin+or.boxTextMargin,(function(t){return sr.newLoop(t)}));break;case Un.parser.yy.LINETYPE.OPT_END:e=sr.endLoop(),zn.drawLoop(n,e,"opt",or),sr.bumpVerticalPos(e.stopy-sr.getVerticalPos()),sr.models.addLoop(e);break;case Un.parser.yy.LINETYPE.ALT_START:gr(u,t,or.boxMargin,or.boxMargin+or.boxTextMargin,(function(t){return sr.newLoop(t)}));break;case Un.parser.yy.LINETYPE.ALT_ELSE:gr(u,t,or.boxMargin+or.boxTextMargin,or.boxMargin,(function(t){return sr.addSectionToLoop(t)}));break;case Un.parser.yy.LINETYPE.ALT_END:e=sr.endLoop(),zn.drawLoop(n,e,"alt",or),sr.bumpVerticalPos(e.stopy-sr.getVerticalPos()),sr.models.addLoop(e);break;case Un.parser.yy.LINETYPE.PAR_START:gr(u,t,or.boxMargin,or.boxMargin+or.boxTextMargin,(function(t){return sr.newLoop(t)}));break;case Un.parser.yy.LINETYPE.PAR_AND:gr(u,t,or.boxMargin+or.boxTextMargin,or.boxMargin,(function(t){return sr.addSectionToLoop(t)}));break;case Un.parser.yy.LINETYPE.PAR_END:e=sr.endLoop(),zn.drawLoop(n,e,"par",or),sr.bumpVerticalPos(e.stopy-sr.getVerticalPos()),sr.models.addLoop(e);break;default:try{(a=t.msgModel).starty=sr.getVerticalPos(),a.sequenceIndex=l,function(t,e){sr.bumpVerticalPos(10);var n=e.startx,r=e.stopx,i=e.starty,a=e.message,o=e.type,s=e.sequenceIndex,c=e.wrap,u=x.splitBreaks(a).length,l=W.calculateTextDimensions(a,cr(or)),h=l.height/u;e.height+=h,sr.bumpVerticalPos(h);var f=zn.getTextObj();f.x=n,f.y=i+10,f.width=r-n,f.class="messageText",f.dy="1em",f.text=a,f.fontFamily=or.messageFontFamily,f.fontSize=or.messageFontSize,f.fontWeight=or.messageFontWeight,f.anchor=or.messageAlign,f.valign=or.messageAlign,f.textMargin=or.wrapPadding,f.tspan=!1,f.wrap=c,Fn(t,f);var d,p,g=l.height-10,y=l.width;if(n===r){p=sr.getVerticalPos()+g,or.rightAngles?d=t.append("path").attr("d","M ".concat(n,",").concat(p," H ").concat(n+Math.max(or.width/2,y/2)," V ").concat(p+25," H ").concat(n)):(g+=or.boxMargin,p=sr.getVerticalPos()+g,d=t.append("path").attr("d","M "+n+","+p+" C "+(n+60)+","+(p-10)+" "+(n+60)+","+(p+30)+" "+n+","+(p+20))),g+=30;var v=Math.max(y/2,or.width/2);sr.insert(n-v,sr.getVerticalPos()-10+g,r+v,sr.getVerticalPos()+30+g)}else g+=or.boxMargin,p=sr.getVerticalPos()+g,(d=t.append("line")).attr("x1",n),d.attr("y1",p),d.attr("x2",r),d.attr("y2",p),sr.insert(n,p-10,r,p);o===Un.parser.yy.LINETYPE.DOTTED||o===Un.parser.yy.LINETYPE.DOTTED_CROSS||o===Un.parser.yy.LINETYPE.DOTTED_OPEN?(d.style("stroke-dasharray","3, 3"),d.attr("class","messageLine1")):d.attr("class","messageLine0");var m="";or.arrowMarkerAbsolute&&(m=(m=(m=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search).replace(/\(/g,"\\(")).replace(/\)/g,"\\)")),d.attr("stroke-width",2),d.attr("stroke","none"),d.style("fill","none"),o!==Un.parser.yy.LINETYPE.SOLID&&o!==Un.parser.yy.LINETYPE.DOTTED||d.attr("marker-end","url("+m+"#arrowhead)"),o!==Un.parser.yy.LINETYPE.SOLID_CROSS&&o!==Un.parser.yy.LINETYPE.DOTTED_CROSS||d.attr("marker-end","url("+m+"#crosshead)"),(ar.showSequenceNumbers()||or.showSequenceNumbers)&&(d.attr("marker-start","url("+m+"#sequencenumber)"),t.append("text").attr("x",n).attr("y",p+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("textLength","16px").attr("class","sequenceNumber").text(s)),sr.bumpVerticalPos(g),e.height+=g,e.stopy=e.starty+e.height,sr.insert(e.fromBounds,e.starty,e.toBounds,e.stopy)}(n,a),sr.models.addMessage(a)}catch(t){f.error("error while drawing message",t)}}[Un.parser.yy.LINETYPE.SOLID_OPEN,Un.parser.yy.LINETYPE.DOTTED_OPEN,Un.parser.yy.LINETYPE.SOLID,Un.parser.yy.LINETYPE.DOTTED,Un.parser.yy.LINETYPE.SOLID_CROSS,Un.parser.yy.LINETYPE.DOTTED_CROSS].includes(t.type)&&l++})),or.mirrorActors&&(sr.bumpVerticalPos(2*or.boxMargin),hr(n,r,i,sr.getVerticalPos()));var h=sr.getBounds().bounds;f.debug("For line height fix Querying: #"+e+" .actor-line"),Object(s.selectAll)("#"+e+" .actor-line").attr("y2",h.stopy);var d=h.stopy-h.starty+2*or.diagramMarginY;or.mirrorActors&&(d=d-or.boxMargin+or.bottomMarginAdj);var p=h.stopx-h.startx+2*or.diagramMarginX;o&&n.append("text").text(o).attr("x",(h.stopx-h.startx)/2-2*or.diagramMarginX).attr("y",-25),$(n,d,p,or.useMaxWidth);var g=o?40:0;n.attr("viewBox",h.startx-or.diagramMarginX+" -"+(or.diagramMarginY+g)+" "+p+" "+(d+g)),f.debug("models:",sr.models)}},xr=n(27),_r=n.n(xr);function kr(t){return function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e=6&&n.indexOf("weekends")>=0||(n.indexOf(t.format("dddd").toLowerCase())>=0||n.indexOf(t.format(e.trim()))>=0)},jr=function(t,e,n){if(n.length&&!t.manualEndTime){var r=l()(t.startTime,e,!0);r.add(1,"d");var i=l()(t.endTime,e,!0),a=Rr(r,i,e,n);t.endTime=i.toDate(),t.renderEndTime=a}},Rr=function(t,e,n,r){for(var i=!1,a=null;t<=e;)i||(a=e.toDate()),(i=Ir(t,n,r))&&e.add(1,"d"),t.add(1,"d");return a},Yr=function(t,e,n){n=n.trim();var r=/^after\s+([\d\w- ]+)/.exec(n.trim());if(null!==r){var i=null;if(r[1].split(" ").forEach((function(t){var e=Gr(t);void 0!==e&&(i?e.endTime>i.endTime&&(i=e):i=e)})),i)return i.endTime;var a=new Date;return a.setHours(0,0,0,0),a}var o=l()(n,e.trim(),!0);return o.isValid()?o.toDate():(f.debug("Invalid date:"+n),f.debug("With date format:"+e.trim()),new Date)},zr=function(t,e){if(null!==t)switch(t[2]){case"s":e.add(t[1],"seconds");break;case"m":e.add(t[1],"minutes");break;case"h":e.add(t[1],"hours");break;case"d":e.add(t[1],"days");break;case"w":e.add(t[1],"weeks")}return e.toDate()},Ur=function(t,e,n,r){r=r||!1,n=n.trim();var i=l()(n,e.trim(),!0);return i.isValid()?(r&&i.add(1,"d"),i.toDate()):zr(/^([\d]+)([wdhms])/.exec(n.trim()),l()(t))},$r=0,Wr=function(t){return void 0===t?"task"+($r+=1):t},Vr=[],Hr={},Gr=function(t){var e=Hr[t];return Vr[e]},qr=function(){for(var t=function(t){var e=Vr[t],n="";switch(Vr[t].raw.startTime.type){case"prevTaskEnd":var r=Gr(e.prevTaskId);e.startTime=r.endTime;break;case"getStartDate":(n=Yr(0,Tr,Vr[t].raw.startTime.startData))&&(Vr[t].startTime=n)}return Vr[t].startTime&&(Vr[t].endTime=Ur(Vr[t].startTime,Tr,Vr[t].raw.endTime.data,Fr),Vr[t].endTime&&(Vr[t].processed=!0,Vr[t].manualEndTime=l()(Vr[t].raw.endTime.data,"YYYY-MM-DD",!0).isValid(),jr(Vr[t],Tr,Ar))),Vr[t].processed},e=!0,n=0;nr?i=1:n0&&(e=t.classes.join(" "));for(var n=0,r=0;rn-e?n+a+1.5*ti.leftPadding>u?e+r-5:n+r+5:(n-e)/2+e+r})).attr("y",(function(t,r){return t.order*e+ti.barHeight/2+(ti.fontSize/2-2)+n})).attr("text-height",i).attr("class",(function(t){var e=o(t.startTime),n=o(t.endTime);t.milestone&&(n=e+i);var r=this.getBBox().width,a="";t.classes.length>0&&(a=t.classes.join(" "));for(var s=0,l=0;ln-e?n+r+1.5*ti.leftPadding>u?a+" taskTextOutsideLeft taskTextOutside"+s+" "+h:a+" taskTextOutsideRight taskTextOutside"+s+" "+h+" width-"+r:a+" taskText taskText"+s+" "+h+" width-"+r}))}(t,i,u,f,r,0,e),function(t,e){for(var n=[],r=0,i=0;i0&&a.setAttribute("dy","1em"),a.textContent=e[i],r.appendChild(a)}return r})).attr("x",10).attr("y",(function(i,a){if(!(a>0))return i[1]*t/2+e;for(var o=0;o "+t.w+": "+JSON.stringify(i.edge(t))),yn(r,i.edge(t),i.edge(t).relation,oi))}));var h=r.node().getBBox(),d=h.width+40,p=h.height+40;$(r,p,d,oi.useMaxWidth);var g="".concat(h.x-20," ").concat(h.y-20," ").concat(d," ").concat(p);f.debug("viewBox ".concat(g)),r.attr("viewBox",g)};ri.parser.yy=on;var li={dividerMargin:10,padding:5,textHeight:10},hi=function(t){Object.keys(t).forEach((function(e){li[e]=t[e]}))},fi=function(t,e){f.info("Drawing class"),on.clear(),ri.parser.parse(t);var n=xt().flowchart;f.info("config:",n);var r=n.nodeSpacing||50,i=n.rankSpacing||50,a=new H.a.Graph({multigraph:!0,compound:!0}).setGraph({rankdir:"TD",nodesep:r,ranksep:i,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}})),o=on.getClasses(),c=on.getRelations();f.info(c),function(t,e){var n=Object.keys(t);f.info("keys:",n),f.info(t),n.forEach((function(n){var r=t[n],i="";r.cssClasses.length>0&&(i=i+" "+r.cssClasses.join(" "));var a={labelStyle:""},o=void 0!==r.text?r.text:r.id,s="";switch(r.type){case"class":s="class_box";break;default:s="class_box"}e.setNode(r.id,{labelStyle:a.labelStyle,shape:s,labelText:o,classData:r,rx:0,ry:0,class:i,style:a.style,id:r.id,domId:r.domId,haveCallback:r.haveCallback,link:r.link,width:"group"===r.type?500:void 0,type:r.type,padding:xt().flowchart.padding}),f.info("setNode",{labelStyle:a.labelStyle,shape:s,labelText:o,rx:0,ry:0,class:i,style:a.style,id:r.id,width:"group"===r.type?500:void 0,type:r.type,padding:xt().flowchart.padding})}))}(o,a),function(t,e){var n=0;t.forEach((function(r){n++;var i={classes:"relation"};i.pattern=1==r.relation.lineType?"dashed":"solid",i.id="id"+n,"arrow_open"===r.type?i.arrowhead="none":i.arrowhead="normal",f.info(i,r),i.startLabelRight="none"===r.relationTitle1?"":r.relationTitle1,i.endLabelLeft="none"===r.relationTitle2?"":r.relationTitle2,i.arrowTypeStart=di(r.relation.type1),i.arrowTypeEnd=di(r.relation.type2);var a="",o="";if(void 0!==r.style){var c=N(r.style);a=c.style,o=c.labelStyle}else a="fill:none";i.style=a,i.labelStyle=o,void 0!==r.interpolate?i.curve=O(r.interpolate,s.curveLinear):void 0!==t.defaultInterpolate?i.curve=O(t.defaultInterpolate,s.curveLinear):i.curve=O(li.curve,s.curveLinear),r.text=r.title,void 0===r.text?void 0!==r.style&&(i.arrowheadStyle="fill: #333"):(i.arrowheadStyle="fill: #333",i.labelpos="c",xt().flowchart.htmlLabels,i.labelType="text",i.label=r.text.replace(x.lineBreakRegex,"\n"),void 0===r.style&&(i.style=i.style||"stroke: #333; stroke-width: 1.5px;fill:none"),i.labelStyle=i.labelStyle.replace("color:","fill:")),e.setEdge(r.id1,r.id2,i,n)}))}(c,a);var u=Object(s.select)('[id="'.concat(e,'"]'));u.attr("xmlns:xlink","http://www.w3.org/1999/xlink");var l=Object(s.select)("#"+e+" g");An(l,a,["aggregation","extension","composition","dependency"],"classDiagram",e);var h=u.node().getBBox(),d=h.width+16,p=h.height+16;if(f.debug("new ViewBox 0 0 ".concat(d," ").concat(p),"translate(".concat(8-a._label.marginx,", ").concat(8-a._label.marginy,")")),$(u,p,d,n.useMaxWidth),u.attr("viewBox","0 0 ".concat(d," ").concat(p)),u.select("g").attr("transform","translate(".concat(8-a._label.marginx,", ").concat(8-h.y,")")),!n.htmlLabels)for(var g=document.querySelectorAll('[id="'+e+'"] .edgeLabel .label'),y=0;y0&&o.length>0){var c={stmt:"state",id:L(),type:"divider",doc:yi(o)};i.push(yi(c)),n.doc=i}n.doc.forEach((function(e){return t(n,e,!0)}))}}({id:"root"},{id:"root",doc:vi},!0),{id:"root",doc:vi}},extract:function(t){var e;e=t.doc?t.doc:t,f.info(e),ki(),f.info("Extract",e),e.forEach((function(t){"state"===t.stmt&&_i(t.id,t.type,t.doc,t.description,t.note),"relation"===t.stmt&&wi(t.state1.id,t.state2.id,t.description)}))},trimColon:function(t){return t&&":"===t[0]?t.substr(1).trim():t.trim()}},Ai=n(22),Mi=n.n(Ai),Oi={},Di=function(t,e){Oi[t]=e},Ni=function(t,e){var n=t.append("text").attr("x",2*xt().state.padding).attr("y",xt().state.textHeight+1.3*xt().state.padding).attr("font-size",xt().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),r=n.height,i=t.append("text").attr("x",xt().state.padding).attr("y",r+.4*xt().state.padding+xt().state.dividerMargin+xt().state.textHeight).attr("class","state-description"),a=!0,o=!0;e.descriptions.forEach((function(t){a||(!function(t,e,n){var r=t.append("tspan").attr("x",2*xt().state.padding).text(e);n||r.attr("dy",xt().state.textHeight)}(i,t,o),o=!1),a=!1}));var s=t.append("line").attr("x1",xt().state.padding).attr("y1",xt().state.padding+r+xt().state.dividerMargin/2).attr("y2",xt().state.padding+r+xt().state.dividerMargin/2).attr("class","descr-divider"),c=i.node().getBBox(),u=Math.max(c.width,n.width);return s.attr("x2",u+3*xt().state.padding),t.insert("rect",":first-child").attr("x",xt().state.padding).attr("y",xt().state.padding).attr("width",u+2*xt().state.padding).attr("height",c.height+r+2*xt().state.padding).attr("rx",xt().state.radius),t},Bi=function(t,e,n){var r,i=xt().state.padding,a=2*xt().state.padding,o=t.node().getBBox(),s=o.width,c=o.x,u=t.append("text").attr("x",0).attr("y",xt().state.titleShift).attr("font-size",xt().state.fontSize).attr("class","state-title").text(e.id),l=u.node().getBBox().width+a,h=Math.max(l,s);h===s&&(h+=a);var f=t.node().getBBox();e.doc,r=c-i,l>s&&(r=(s-h)/2+i),Math.abs(c-f.x)s&&(r=c-(l-s)/2);var d=1-xt().state.textHeight;return t.insert("rect",":first-child").attr("x",r).attr("y",d).attr("class",n?"alt-composit":"composit").attr("width",h).attr("height",f.height+xt().state.textHeight+xt().state.titleShift+1).attr("rx","0"),u.attr("x",r+i),l<=s&&u.attr("x",c+(h-a)/2-l/2+i),t.insert("rect",":first-child").attr("x",r).attr("y",xt().state.titleShift-xt().state.textHeight-xt().state.padding).attr("width",h).attr("height",3*xt().state.textHeight).attr("rx",xt().state.radius),t.insert("rect",":first-child").attr("x",r).attr("y",xt().state.titleShift-xt().state.textHeight-xt().state.padding).attr("width",h).attr("height",f.height+3+2*xt().state.textHeight).attr("rx",xt().state.radius),t},Li=function(t,e){e.attr("class","state-note");var n=e.append("rect").attr("x",0).attr("y",xt().state.padding),r=function(t,e,n,r){var i=0,a=r.append("text");a.style("text-anchor","start"),a.attr("class","noteText");var o=t.replace(/\r\n/g,"
"),s=(o=o.replace(/\n/g,"
")).split(x.lineBreakRegex),c=1.25*xt().state.noteMargin,u=!0,l=!1,h=void 0;try{for(var f,d=s[Symbol.iterator]();!(u=(f=d.next()).done);u=!0){var p=f.value.trim();if(p.length>0){var g=a.append("tspan");if(g.text(p),0===c)c+=g.node().getBBox().height;i+=c,g.attr("x",e+xt().state.noteMargin),g.attr("y",n+i+1.25*xt().state.noteMargin)}}}catch(t){l=!0,h=t}finally{try{u||null==d.return||d.return()}finally{if(l)throw h}}return{textWidth:a.node().getBBox().width,textHeight:i}}(t,0,0,e.append("g")),i=r.textWidth,a=r.textHeight;return n.attr("height",a+2*xt().state.noteMargin),n.attr("width",i+2*xt().state.noteMargin),n},Fi=function(t,e){var n=e.id,r={id:n,label:e.id,width:0,height:0},i=t.append("g").attr("id",n).attr("class","stateGroup");"start"===e.type&&function(t){t.append("circle").attr("class","start-state").attr("r",xt().state.sizeUnit).attr("cx",xt().state.padding+xt().state.sizeUnit).attr("cy",xt().state.padding+xt().state.sizeUnit)}(i),"end"===e.type&&function(t){t.append("circle").attr("class","end-state-outer").attr("r",xt().state.sizeUnit+xt().state.miniPadding).attr("cx",xt().state.padding+xt().state.sizeUnit+xt().state.miniPadding).attr("cy",xt().state.padding+xt().state.sizeUnit+xt().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",xt().state.sizeUnit).attr("cx",xt().state.padding+xt().state.sizeUnit+2).attr("cy",xt().state.padding+xt().state.sizeUnit+2)}(i),"fork"!==e.type&&"join"!==e.type||function(t,e){var n=xt().state.forkWidth,r=xt().state.forkHeight;if(e.parentId){var i=n;n=r,r=i}t.append("rect").style("stroke","black").style("fill","black").attr("width",n).attr("height",r).attr("x",xt().state.padding).attr("y",xt().state.padding)}(i,e),"note"===e.type&&Li(e.note.text,i),"divider"===e.type&&function(t){t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",xt().state.textHeight).attr("class","divider").attr("x2",2*xt().state.textHeight).attr("y1",0).attr("y2",0)}(i),"default"===e.type&&0===e.descriptions.length&&function(t,e){var n=t.append("text").attr("x",2*xt().state.padding).attr("y",xt().state.textHeight+2*xt().state.padding).attr("font-size",xt().state.fontSize).attr("class","state-title").text(e.id),r=n.node().getBBox();t.insert("rect",":first-child").attr("x",xt().state.padding).attr("y",xt().state.padding).attr("width",r.width+2*xt().state.padding).attr("height",r.height+2*xt().state.padding).attr("rx",xt().state.radius)}(i,e),"default"===e.type&&e.descriptions.length>0&&Ni(i,e);var a=i.node().getBBox();return r.width=a.width+2*xt().state.padding,r.height=a.height+2*xt().state.padding,Di(n,r),r},Pi=0;Ai.parser.yy=Si;var Ii={},ji=function t(e,n,r,i){var a,o=new H.a.Graph({compound:!0,multigraph:!0}),c=!0;for(a=0;a "+t.w+": "+JSON.stringify(o.edge(t))),function(t,e,n){e.points=e.points.filter((function(t){return!Number.isNaN(t.y)}));var r=e.points,i=Object(s.line)().x((function(t){return t.x})).y((function(t){return t.y})).curve(s.curveBasis),a=t.append("path").attr("d",i(r)).attr("id","edge"+Pi).attr("class","transition"),o="";if(xt().state.arrowMarkerAbsolute&&(o=(o=(o=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search).replace(/\(/g,"\\(")).replace(/\)/g,"\\)")),a.attr("marker-end","url("+o+"#"+function(t){switch(t){case Si.relationType.AGGREGATION:return"aggregation";case Si.relationType.EXTENSION:return"extension";case Si.relationType.COMPOSITION:return"composition";case Si.relationType.DEPENDENCY:return"dependency"}}(Si.relationType.DEPENDENCY)+"End)"),void 0!==n.title){for(var c=t.append("g").attr("class","stateLabel"),u=W.calcLabelPosition(e.points),l=u.x,h=u.y,d=x.getRows(n.title),p=0,g=[],y=0,v=0,m=0;m<=d.length;m++){var b=c.append("text").attr("text-anchor","middle").text(d[m]).attr("x",l).attr("y",h+p),_=b.node().getBBox();if(y=Math.max(y,_.width),v=Math.min(v,_.x),f.info(_.x,l,h+p),0===p){var k=b.node().getBBox();p=k.height,f.info("Title height",p,h)}g.push(b)}var w=p*d.length;if(d.length>1){var E=(d.length-1)*p*.5;g.forEach((function(t,e){return t.attr("y",h+e*p-E)})),w=p*d.length}var T=c.node().getBBox();c.insert("rect",":first-child").attr("class","box").attr("x",l-y/2-xt().state.padding/2).attr("y",h-w/2-xt().state.padding/2-3.5).attr("width",y+xt().state.padding).attr("height",w+xt().state.padding),f.info(T)}Pi++}(n,o.edge(t),o.edge(t).relation))})),w=k.getBBox();var E={id:r||"root",label:r||"root",width:0,height:0};return E.width=w.width+2*gi.padding,E.height=w.height+2*gi.padding,f.debug("Doc rendered",E,o),E},Ri=function(){},Yi=function(t,e){gi=xt().state,Ai.parser.yy.clear(),Ai.parser.parse(t),f.debug("Rendering diagram "+t);var n=Object(s.select)("[id='".concat(e,"']"));n.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z"),new H.a.Graph({multigraph:!0,compound:!0,rankdir:"RL"}).setDefaultEdgeLabel((function(){return{}}));var r=Si.getRootDoc();ji(r,n,void 0,!1);var i=gi.padding,a=n.node().getBBox(),o=a.width+2*i,c=a.height+2*i;$(n,c,1.75*o,gi.useMaxWidth),n.attr("viewBox","".concat(a.x-gi.padding," ").concat(a.y-gi.padding," ")+o+" "+c)},zi={},Ui={},$i=function(t,e,n,r){if("root"!==n.id){var i="rect";!0===n.start&&(i="start"),!1===n.start&&(i="end"),"default"!==n.type&&(i=n.type),Ui[n.id]||(Ui[n.id]={id:n.id,shape:i,description:n.id,classes:"statediagram-state"}),n.description&&(Array.isArray(Ui[n.id].description)?(Ui[n.id].shape="rectWithTitle",Ui[n.id].description.push(n.description)):Ui[n.id].description.length>0?(Ui[n.id].shape="rectWithTitle",Ui[n.id].description===n.id?Ui[n.id].description=[n.description]:Ui[n.id].description=[Ui[n.id].description,n.description]):(Ui[n.id].shape="rect",Ui[n.id].description=n.description)),!Ui[n.id].type&&n.doc&&(f.info("Setting cluser for ",n.id),Ui[n.id].type="group",Ui[n.id].shape="divider"===n.type?"divider":"roundedWithTitle",Ui[n.id].classes=Ui[n.id].classes+" "+(r?"statediagram-cluster statediagram-cluster-alt":"statediagram-cluster"));var a={labelStyle:"",shape:Ui[n.id].shape,labelText:Ui[n.id].description,classes:Ui[n.id].classes,style:"",id:n.id,domId:"state-"+n.id+"-"+Wi,type:Ui[n.id].type,padding:15};if(n.note){var o={labelStyle:"",shape:"note",labelText:n.note.text,classes:"statediagram-note",style:"",id:n.id+"----note",domId:"state-"+n.id+"----note-"+Wi,type:Ui[n.id].type,padding:15},s={labelStyle:"",shape:"noteGroup",labelText:n.note.text,classes:Ui[n.id].classes,style:"",id:n.id+"----parent",domId:"state-"+n.id+"----parent-"+Wi,type:"group",padding:0};Wi++,t.setNode(n.id+"----parent",s),t.setNode(o.id,o),t.setNode(n.id,a),t.setParent(n.id,n.id+"----parent"),t.setParent(o.id,n.id+"----parent");var c=n.id,u=o.id;"left of"===n.note.position&&(c=o.id,u=n.id),t.setEdge(c,u,{arrowhead:"none",arrowType:"",style:"fill:none",labelStyle:"",classes:"transition note-edge",arrowheadStyle:"fill: #333",labelpos:"c",labelType:"text",thickness:"normal"})}else t.setNode(n.id,a)}e&&"root"!==e.id&&(f.info("Setting node ",n.id," to be child of its parent ",e.id),t.setParent(n.id,e.id)),n.doc&&(f.info("Adding nodes children "),Vi(t,n,n.doc,!r))},Wi=0,Vi=function(t,e,n,r){Wi=0,f.trace("items",n),n.forEach((function(n){if("state"===n.stmt||"default"===n.stmt)$i(t,e,n,r);else if("relation"===n.stmt){$i(t,e,n.state1,r),$i(t,e,n.state2,r);var i={id:"edge"+Wi,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:"fill:none",labelStyle:"",label:n.description,arrowheadStyle:"fill: #333",labelpos:"c",labelType:"text",thickness:"normal",classes:"transition"},a=n.state1.id,o=n.state2.id;t.setEdge(a,o,i,Wi),Wi++}}))},Hi=function(t){for(var e=Object.keys(t),n=0;ne.seq?t:e}),t[0]),n="";t.forEach((function(t){n+=t===e?"\t*":"\t|"}));var r,i,a,o=[n,e.id,e.seq];for(var s in Zi)Zi[s]===e.id&&o.push(s);if(f.debug(o.join(" ")),Array.isArray(e.parent)){var c=qi[e.parent[0]];ra(t,e,c),t.push(qi[e.parent[1]])}else{if(null==e.parent)return;var u=qi[e.parent];ra(t,e,u)}r=t,i=function(t){return t.id},a=Object.create(null),ia(t=r.reduce((function(t,e){var n=i(e);return a[n]||(a[n]=!0,t.push(e)),t}),[]))}var aa,oa=function(){var t=Object.keys(qi).map((function(t){return qi[t]}));return t.forEach((function(t){f.debug(t.id)})),t.sort((function(t,e){return e.seq-t.seq})),t},sa={setDirection:function(t){Qi=t},setOptions:function(t){f.debug("options str",t),t=(t=t&&t.trim())||"{}";try{na=JSON.parse(t)}catch(t){f.error("error while parsing gitGraph options",t.message)}},getOptions:function(){return na},commit:function(t){var e={id:ta(),message:t,seq:Ki++,parent:null==Xi?null:Xi.id};Xi=e,qi[e.id]=e,Zi[Ji]=e.id,f.debug("in pushCommit "+e.id)},branch:function(t){Zi[t]=null!=Xi?Xi.id:null,f.debug("in createBranch")},merge:function(t){var e=qi[Zi[Ji]],n=qi[Zi[t]];if(function(t,e){return t.seq>e.seq&&ea(e,t)}(e,n))f.debug("Already merged");else{if(ea(e,n))Zi[Ji]=Zi[t],Xi=qi[Zi[Ji]];else{var r={id:ta(),message:"merged branch "+t+" into "+Ji,seq:Ki++,parent:[null==Xi?null:Xi.id,Zi[t]]};Xi=r,qi[r.id]=r,Zi[Ji]=r.id}f.debug(Zi),f.debug("in mergeBranch")}},checkout:function(t){f.debug("in checkout");var e=Zi[Ji=t];Xi=qi[e]},reset:function(t){f.debug("in reset",t);var e=t.split(":")[0],n=parseInt(t.split(":")[1]),r="HEAD"===e?Xi:qi[Zi[e]];for(f.debug(r,n);n>0;)if(n--,!(r=qi[r.parent])){var i="Critical error - unique parent commit not found during reset";throw f.error(i),i}Xi=r,Zi[Ji]=r.id},prettyPrint:function(){f.debug(qi),ia([oa()[0]])},clear:function(){qi={},Zi={master:Xi=null},Ji="master",Ki=0},getBranchesAsObjArray:function(){var t=[];for(var e in Zi)t.push({name:e,commit:qi[Zi[e]]});return t},getBranches:function(){return Zi},getCommits:function(){return qi},getCommitsArray:oa,getCurrentBranch:function(){return Ji},getDirection:function(){return Qi},getHead:function(){return Xi}},ca=n(71),ua=n.n(ca),la={},ha={nodeSpacing:150,nodeFillColor:"yellow",nodeStrokeWidth:2,nodeStrokeColor:"grey",lineStrokeWidth:4,branchOffset:50,lineColor:"grey",leftMargin:50,branchColors:["#442f74","#983351","#609732","#AA9A39"],nodeRadius:10,nodeLabel:{width:75,height:100,x:-25,y:0}},fa={};function da(t,e,n,r){var i=O(r,s.curveBasis),a=ha.branchColors[n%ha.branchColors.length],o=Object(s.line)().x((function(t){return Math.round(t.x)})).y((function(t){return Math.round(t.y)})).curve(i);t.append("svg:path").attr("d",o(e)).style("stroke",a).style("stroke-width",ha.lineStrokeWidth).style("fill","none")}function pa(t,e){e=e||t.node().getBBox();var n=t.node().getCTM();return{left:n.e+e.x*n.a,top:n.f+e.y*n.d,width:e.width,height:e.height}}function ga(t,e,n,r,i){f.debug("svgDrawLineForCommits: ",e,n);var a=pa(t.select("#node-"+e+" circle")),o=pa(t.select("#node-"+n+" circle"));switch(r){case"LR":if(a.left-o.left>ha.nodeSpacing){var s={x:a.left-ha.nodeSpacing,y:o.top+o.height/2};da(t,[s,{x:o.left+o.width,y:o.top+o.height/2}],i,"linear"),da(t,[{x:a.left,y:a.top+a.height/2},{x:a.left-ha.nodeSpacing/2,y:a.top+a.height/2},{x:a.left-ha.nodeSpacing/2,y:s.y},s],i)}else da(t,[{x:a.left,y:a.top+a.height/2},{x:a.left-ha.nodeSpacing/2,y:a.top+a.height/2},{x:a.left-ha.nodeSpacing/2,y:o.top+o.height/2},{x:o.left+o.width,y:o.top+o.height/2}],i);break;case"BT":if(o.top-a.top>ha.nodeSpacing){var c={x:o.left+o.width/2,y:a.top+a.height+ha.nodeSpacing};da(t,[c,{x:o.left+o.width/2,y:o.top}],i,"linear"),da(t,[{x:a.left+a.width/2,y:a.top+a.height},{x:a.left+a.width/2,y:a.top+a.height+ha.nodeSpacing/2},{x:o.left+o.width/2,y:c.y-ha.nodeSpacing/2},c],i)}else da(t,[{x:a.left+a.width/2,y:a.top+a.height},{x:a.left+a.width/2,y:a.top+ha.nodeSpacing/2},{x:o.left+o.width/2,y:o.top-ha.nodeSpacing/2},{x:o.left+o.width/2,y:o.top}],i)}}function ya(t,e){return t.select(e).node().cloneNode(!0)}function va(t,e,n,r){var i,a=Object.keys(la).length;if("string"==typeof e)do{if(i=la[e],f.debug("in renderCommitHistory",i.id,i.seq),t.select("#node-"+e).size()>0)return;t.append((function(){return ya(t,"#def-commit")})).attr("class","commit").attr("id",(function(){return"node-"+i.id})).attr("transform",(function(){switch(r){case"LR":return"translate("+(i.seq*ha.nodeSpacing+ha.leftMargin)+", "+aa*ha.branchOffset+")";case"BT":return"translate("+(aa*ha.branchOffset+ha.leftMargin)+", "+(a-i.seq)*ha.nodeSpacing+")"}})).attr("fill",ha.nodeFillColor).attr("stroke",ha.nodeStrokeColor).attr("stroke-width",ha.nodeStrokeWidth);var o=void 0;for(var s in n)if(n[s].commit===i){o=n[s];break}o&&(f.debug("found branch ",o.name),t.select("#node-"+i.id+" p").append("xhtml:span").attr("class","branch-label").text(o.name+", ")),t.select("#node-"+i.id+" p").append("xhtml:span").attr("class","commit-id").text(i.id),""!==i.message&&"BT"===r&&t.select("#node-"+i.id+" p").append("xhtml:span").attr("class","commit-msg").text(", "+i.message),e=i.parent}while(e&&la[e]);Array.isArray(e)&&(f.debug("found merge commmit",e),va(t,e[0],n,r),aa++,va(t,e[1],n,r),aa--)}function ma(t,e,n,r){for(r=r||0;e.seq>0&&!e.lineDrawn;)"string"==typeof e.parent?(ga(t,e.id,e.parent,n,r),e.lineDrawn=!0,e=la[e.parent]):Array.isArray(e.parent)&&(ga(t,e.id,e.parent[0],n,r),ga(t,e.id,e.parent[1],n,r+1),ma(t,la[e.parent[1]],n,r+1),e.lineDrawn=!0,e=la[e.parent[0]])}var ba,xa=function(t){fa=t},_a=function(t,e,n){try{var r=ua.a.parser;r.yy=sa,r.yy.clear(),f.debug("in gitgraph renderer",t+"\n","id:",e,n),r.parse(t+"\n"),ha=Object.assign(ha,fa,sa.getOptions()),f.debug("effective options",ha);var i=sa.getDirection();la=sa.getCommits();var a=sa.getBranchesAsObjArray();"BT"===i&&(ha.nodeLabel.x=a.length*ha.branchOffset,ha.nodeLabel.width="100%",ha.nodeLabel.y=-2*ha.nodeRadius);var o=Object(s.select)('[id="'.concat(e,'"]'));for(var c in function(t){t.append("defs").append("g").attr("id","def-commit").append("circle").attr("r",ha.nodeRadius).attr("cx",0).attr("cy",0),t.select("#def-commit").append("foreignObject").attr("width",ha.nodeLabel.width).attr("height",ha.nodeLabel.height).attr("x",ha.nodeLabel.x).attr("y",ha.nodeLabel.y).attr("class","node-label").attr("requiredFeatures","http://www.w3.org/TR/SVG11/feature#Extensibility").append("p").html("")}(o),aa=1,a){var u=a[c];va(o,u.commit.id,a,i),ma(o,u.commit,i),aa++}o.attr("height",(function(){return"BT"===i?Object.keys(la).length*ha.nodeSpacing:(a.length+1)*ha.branchOffset}))}catch(t){f.error("Error while rendering gitgraph"),f.error(t.message)}},ka="",wa=!1,Ea={setMessage:function(t){f.debug("Setting message to: "+t),ka=t},getMessage:function(){return ka},setInfo:function(t){wa=t},getInfo:function(){return wa}},Ta=n(72),Ca=n.n(Ta),Sa={},Aa=function(t){Object.keys(t).forEach((function(e){Sa[e]=t[e]}))},Ma=function(t,e,n){try{var r=Ca.a.parser;r.yy=Ea,f.debug("Renering info diagram\n"+t),r.parse(t),f.debug("Parsed info diagram");var i=Object(s.select)("#"+e);i.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size","32px").style("text-anchor","middle").text("v "+n),i.attr("height",100),i.attr("width",400)}catch(t){f.error("Error while rendering info diagram"),f.error(t.message)}},Oa={},Da=function(t){Object.keys(t).forEach((function(e){Oa[e]=t[e]}))},Na=function(t,e){try{f.debug("Renering svg for syntax error\n");var n=Object(s.select)("#"+t),r=n.append("g");r.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),r.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),r.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),r.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),r.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),r.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),r.append("text").attr("class","error-text").attr("x",1240).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in graph"),r.append("text").attr("class","error-text").attr("x",1050).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text("mermaid version "+e),n.attr("height",100),n.attr("width",400),n.attr("viewBox","768 0 512 512")}catch(t){f.error("Error while rendering info diagram"),f.error(t.message)}},Ba={},La="",Fa={parseDirective:function(t,e,n){$o.parseDirective(this,t,e,n)},getConfig:function(){return xt().pie},addSection:function(t,e){void 0===Ba[t]&&(Ba[t]=e,f.debug("Added new section :",t))},getSections:function(){return Ba},cleanupValue:function(t){return":"===t.substring(0,1)?(t=t.substring(1).trim(),Number(t.trim())):Number(t.trim())},clear:function(){Ba={},La=""},setTitle:function(t){La=t},getTitle:function(){return La}},Pa=n(73),Ia=n.n(Pa),ja={},Ra=function(t){Object.keys(t).forEach((function(e){ja[e]=t[e]}))},Ya=function(t,e){try{var n=Ia.a.parser;n.yy=Fa,f.debug("Rendering info diagram\n"+t),n.yy.clear(),n.parse(t),f.debug("Parsed info diagram");var r=document.getElementById(e);void 0===(ba=r.parentElement.offsetWidth)&&(ba=1200),void 0!==ja.useWidth&&(ba=ja.useWidth);var i=Object(s.select)("#"+e);$(i,450,ba,ja.useMaxWidth),r.setAttribute("viewBox","0 0 "+ba+" 450");var a=Math.min(ba,450)/2-40,o=i.append("g").attr("transform","translate("+ba/2+",225)"),c=Fa.getSections(),u=0;Object.keys(c).forEach((function(t){u+=c[t]}));var l=Object(s.scaleOrdinal)().domain(c).range(s.schemeSet2),h=Object(s.pie)().value((function(t){return t.value}))(Object(s.entries)(c)),d=Object(s.arc)().innerRadius(0).outerRadius(a);o.selectAll("mySlices").data(h).enter().append("path").attr("d",d).attr("fill",(function(t){return l(t.data.key)})).attr("stroke","black").style("stroke-width","2px").style("opacity",.7),o.selectAll("mySlices").data(h).enter().append("text").text((function(t){return(t.data.value/u*100).toFixed(0)+"%"})).attr("transform",(function(t){return"translate("+d.centroid(t)+")"})).style("text-anchor","middle").attr("class","slice").style("font-size",17),o.append("text").text(n.yy.getTitle()).attr("x",0).attr("y",-200).attr("class","pieTitleText");var p=o.selectAll(".legend").data(l.domain()).enter().append("g").attr("class","legend").attr("transform",(function(t,e){return"translate(216,"+(22*e-22*l.domain().length/2)+")"}));p.append("rect").attr("width",18).attr("height",18).style("fill",l).style("stroke",l),p.append("text").attr("x",22).attr("y",14).text((function(t){return t}))}catch(t){f.error("Error while rendering info diagram"),f.error(t)}},za={},Ua=[],$a="",Wa={Cardinality:{ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE"},Identification:{NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"},parseDirective:function(t,e,n){$o.parseDirective(this,t,e,n)},getConfig:function(){return xt().er},addEntity:function(t){void 0===za[t]&&(za[t]=t,f.debug("Added new entity :",t))},getEntities:function(){return za},addRelationship:function(t,e,n,r){var i={entityA:t,roleA:e,entityB:n,relSpec:r};Ua.push(i),f.debug("Added new relationship :",i)},getRelationships:function(){return Ua},clear:function(){za={},Ua=[],$a=""},setTitle:function(t){$a=t},getTitle:function(){return $a}},Va=n(74),Ha=n.n(Va),Ga={ONLY_ONE_START:"ONLY_ONE_START",ONLY_ONE_END:"ONLY_ONE_END",ZERO_OR_ONE_START:"ZERO_OR_ONE_START",ZERO_OR_ONE_END:"ZERO_OR_ONE_END",ONE_OR_MORE_START:"ONE_OR_MORE_START",ONE_OR_MORE_END:"ONE_OR_MORE_END",ZERO_OR_MORE_START:"ZERO_OR_MORE_START",ZERO_OR_MORE_END:"ZERO_OR_MORE_END"},qa=Ga,Xa=function(t,e){var n;t.append("defs").append("marker").attr("id",Ga.ONLY_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",Ga.ONLY_ONE_END).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,0 L3,18 M9,0 L9,18"),(n=t.append("defs").append("marker").attr("id",Ga.ZERO_OR_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto")).append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),n.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18"),(n=t.append("defs").append("marker").attr("id",Ga.ZERO_OR_ONE_END).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto")).append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),n.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,0 L21,18"),t.append("defs").append("marker").attr("id",Ga.ONE_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",Ga.ONE_OR_MORE_END).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"),(n=t.append("defs").append("marker").attr("id",Ga.ZERO_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto")).append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),n.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18"),(n=t.append("defs").append("marker").attr("id",Ga.ZERO_OR_MORE_END).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto")).append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),n.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")},Za={},Ja=function(t){return(t.entityA+t.roleA+t.entityB).replace(/\s/g,"")},Qa=0,Ka=function(t){for(var e=Object.keys(t),n=0;n/gi," "),r=t.append("text");r.attr("x",e.x),r.attr("y",e.y),r.attr("class","legend"),r.style("text-anchor",e.anchor),void 0!==e.class&&r.attr("class",e.class);var i=r.append("tspan");return i.attr("x",e.x+2*e.textMargin),i.text(n),r},go=-1,yo=function(){return{x:0,y:0,width:100,anchor:"start",height:100,rx:0,ry:0}},vo=function(){function t(t,e,n,i,a,o,s,c){r(e.append("text").attr("x",n+a/2).attr("y",i+o/2+5).style("font-color",c).style("text-anchor","middle").text(t),s)}function e(t,e,n,i,a,o,s,c,u){for(var l=c.taskFontSize,h=c.taskFontFamily,f=t.split(//gi),d=0;d3?function(t){var e=Object(s.arc)().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(15/2.2);t.append("path").attr("class","mouth").attr("d",e).attr("transform","translate("+o.cx+","+(o.cy+2)+")")}(c):o.score<3?function(t){var e=Object(s.arc)().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(15/2.2);t.append("path").attr("class","mouth").attr("d",e).attr("transform","translate("+o.cx+","+(o.cy+7)+")")}(c):function(t){t.append("line").attr("class","mouth").attr("stroke",2).attr("x1",o.cx-5).attr("y1",o.cy+7).attr("x2",o.cx+5).attr("y2",o.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}(c);var u=yo();u.x=e.x,u.y=e.y,u.fill=e.fill,u.width=n.width,u.height=n.height,u.class="task task-type-"+e.num,u.rx=3,u.ry=3,ho(i,u);var l=e.x+14;e.people.forEach((function(t){var n=e.actors[t],r={cx:l,cy:e.y,r:7,fill:n,stroke:"#000",title:t};fo(i,r),l+=10})),vo(n)(e.task,i,u.x,u.y,u.width,u.height,{class:"task"},n,e.colour)},ko=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")};eo.parser.yy=lo;var wo={leftMargin:150,diagramMarginX:50,diagramMarginY:20,taskMargin:50,width:150,height:50,taskFontSize:14,taskFontFamily:'"Open-Sans", "sans-serif"',boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"]},Eo={};var To=wo.leftMargin,Co={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},updateVal:function(t,e,n,r){void 0===t[e]?t[e]=n:t[e]=r(n,t[e])},updateBounds:function(t,e,n,r){var i,a=this,o=0;this.sequenceItems.forEach((function(s){o++;var c=a.sequenceItems.length-o+1;a.updateVal(s,"starty",e-c*wo.boxMargin,Math.min),a.updateVal(s,"stopy",r+c*wo.boxMargin,Math.max),a.updateVal(Co.data,"startx",t-c*wo.boxMargin,Math.min),a.updateVal(Co.data,"stopx",n+c*wo.boxMargin,Math.max),"activation"!==i&&(a.updateVal(s,"startx",t-c*wo.boxMargin,Math.min),a.updateVal(s,"stopx",n+c*wo.boxMargin,Math.max),a.updateVal(Co.data,"starty",e-c*wo.boxMargin,Math.min),a.updateVal(Co.data,"stopy",r+c*wo.boxMargin,Math.max))}))},insert:function(t,e,n,r){var i=Math.min(t,n),a=Math.max(t,n),o=Math.min(e,r),s=Math.max(e,r);this.updateVal(Co.data,"startx",i,Math.min),this.updateVal(Co.data,"starty",o,Math.min),this.updateVal(Co.data,"stopx",a,Math.max),this.updateVal(Co.data,"stopy",s,Math.max),this.updateBounds(i,o,a,s)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return this.data}},So=wo.sectionFills,Ao=wo.sectionColours,Mo=function(t,e,n){for(var r="",i=n+(2*wo.height+wo.diagramMarginY),a=0,o="#CCC",s="black",c=0,u=0;u tspan {\n fill: ").concat(t.actorTextColor,";\n stroke: none;\n }\n\n .actor-line {\n stroke: ").concat(t.actorLineColor,";\n }\n\n .messageLine0 {\n stroke-width: 1.5;\n stroke-dasharray: none;\n stroke: ").concat(t.signalColor,";\n }\n\n .messageLine1 {\n stroke-width: 1.5;\n stroke-dasharray: 2, 2;\n stroke: ").concat(t.signalColor,";\n }\n\n #arrowhead path {\n fill: ").concat(t.signalColor,";\n stroke: ").concat(t.signalColor,";\n }\n\n .sequenceNumber {\n fill: ").concat(t.sequenceNumberColor,";\n }\n\n #sequencenumber {\n fill: ").concat(t.signalColor,";\n }\n\n #crosshead path {\n fill: ").concat(t.signalColor,";\n stroke: ").concat(t.signalColor,";\n }\n\n .messageText {\n fill: ").concat(t.signalTextColor,";\n stroke: ").concat(t.signalTextColor,";\n }\n\n .labelBox {\n stroke: ").concat(t.labelBoxBorderColor,";\n fill: ").concat(t.labelBoxBkgColor,";\n }\n\n .labelText, .labelText > tspan {\n fill: ").concat(t.labelTextColor,";\n stroke: none;\n }\n\n .loopText, .loopText > tspan {\n fill: ").concat(t.loopTextColor,";\n stroke: none;\n }\n\n .loopLine {\n stroke-width: 2px;\n stroke-dasharray: 2, 2;\n stroke: ").concat(t.labelBoxBorderColor,";\n fill: ").concat(t.labelBoxBorderColor,";\n }\n\n .note {\n //stroke: #decc93;\n stroke: ").concat(t.noteBorderColor,";\n fill: ").concat(t.noteBkgColor,";\n }\n\n .noteText, .noteText > tspan {\n fill: ").concat(t.noteTextColor,";\n stroke: none;\n }\n\n .activation0 {\n fill: ").concat(t.activationBkgColor,";\n stroke: ").concat(t.activationBorderColor,";\n }\n\n .activation1 {\n fill: ").concat(t.activationBkgColor,";\n stroke: ").concat(t.activationBorderColor,";\n }\n\n .activation2 {\n fill: ").concat(t.activationBkgColor,";\n stroke: ").concat(t.activationBorderColor,";\n }\n")},gantt:function(t){return'\n .mermaid-main-font {\n font-family: "trebuchet ms", verdana, arial;\n font-family: var(--mermaid-font-family);\n }\n\n .section {\n stroke: none;\n opacity: 0.2;\n }\n\n .section0 {\n fill: '.concat(t.sectionBkgColor,";\n }\n\n .section2 {\n fill: ").concat(t.sectionBkgColor2,";\n }\n\n .section1,\n .section3 {\n fill: ").concat(t.altSectionBkgColor,";\n opacity: 0.2;\n }\n\n .sectionTitle0 {\n fill: ").concat(t.titleColor,";\n }\n\n .sectionTitle1 {\n fill: ").concat(t.titleColor,";\n }\n\n .sectionTitle2 {\n fill: ").concat(t.titleColor,";\n }\n\n .sectionTitle3 {\n fill: ").concat(t.titleColor,";\n }\n\n .sectionTitle {\n text-anchor: start;\n font-size: 11px;\n text-height: 14px;\n font-family: 'trebuchet ms', verdana, arial;\n font-family: var(--mermaid-font-family);\n\n }\n\n\n /* Grid and axis */\n\n .grid .tick {\n stroke: ").concat(t.gridColor,";\n opacity: 0.8;\n shape-rendering: crispEdges;\n text {\n font-family: ").concat(t.fontFamily,";\n fill: ").concat(t.textColor,";\n }\n }\n\n .grid path {\n stroke-width: 0;\n }\n\n\n /* Today line */\n\n .today {\n fill: none;\n stroke: ").concat(t.todayLineColor,";\n stroke-width: 2px;\n }\n\n\n /* Task styling */\n\n /* Default task */\n\n .task {\n stroke-width: 2;\n }\n\n .taskText {\n text-anchor: middle;\n font-family: 'trebuchet ms', verdana, arial;\n font-family: var(--mermaid-font-family);\n }\n\n .taskText:not([font-size]) {\n font-size: 11px;\n }\n\n .taskTextOutsideRight {\n fill: ").concat(t.taskTextDarkColor,";\n text-anchor: start;\n font-size: 11px;\n font-family: 'trebuchet ms', verdana, arial;\n font-family: var(--mermaid-font-family);\n\n }\n\n .taskTextOutsideLeft {\n fill: ").concat(t.taskTextDarkColor,";\n text-anchor: end;\n font-size: 11px;\n }\n\n /* Special case clickable */\n .task.clickable {\n cursor: pointer;\n }\n .taskText.clickable {\n cursor: pointer;\n fill: ").concat(t.taskTextClickableColor," !important;\n font-weight: bold;\n }\n\n .taskTextOutsideLeft.clickable {\n cursor: pointer;\n fill: ").concat(t.taskTextClickableColor," !important;\n font-weight: bold;\n }\n\n .taskTextOutsideRight.clickable {\n cursor: pointer;\n fill: ").concat(t.taskTextClickableColor," !important;\n font-weight: bold;\n }\n\n /* Specific task settings for the sections*/\n\n .taskText0,\n .taskText1,\n .taskText2,\n .taskText3 {\n fill: ").concat(t.taskTextColor,";\n }\n\n .task0,\n .task1,\n .task2,\n .task3 {\n fill: ").concat(t.taskBkgColor,";\n stroke: ").concat(t.taskBorderColor,";\n }\n\n .taskTextOutside0,\n .taskTextOutside2\n {\n fill: ").concat(t.taskTextOutsideColor,";\n }\n\n .taskTextOutside1,\n .taskTextOutside3 {\n fill: ").concat(t.taskTextOutsideColor,";\n }\n\n\n /* Active task */\n\n .active0,\n .active1,\n .active2,\n .active3 {\n fill: ").concat(t.activeTaskBkgColor,";\n stroke: ").concat(t.activeTaskBorderColor,";\n }\n\n .activeText0,\n .activeText1,\n .activeText2,\n .activeText3 {\n fill: ").concat(t.taskTextDarkColor," !important;\n }\n\n\n /* Completed task */\n\n .done0,\n .done1,\n .done2,\n .done3 {\n stroke: ").concat(t.doneTaskBorderColor,";\n fill: ").concat(t.doneTaskBkgColor,";\n stroke-width: 2;\n }\n\n .doneText0,\n .doneText1,\n .doneText2,\n .doneText3 {\n fill: ").concat(t.taskTextDarkColor," !important;\n }\n\n\n /* Tasks on the critical line */\n\n .crit0,\n .crit1,\n .crit2,\n .crit3 {\n stroke: ").concat(t.critBorderColor,";\n fill: ").concat(t.critBkgColor,";\n stroke-width: 2;\n }\n\n .activeCrit0,\n .activeCrit1,\n .activeCrit2,\n .activeCrit3 {\n stroke: ").concat(t.critBorderColor,";\n fill: ").concat(t.activeTaskBkgColor,";\n stroke-width: 2;\n }\n\n .doneCrit0,\n .doneCrit1,\n .doneCrit2,\n .doneCrit3 {\n stroke: ").concat(t.critBorderColor,";\n fill: ").concat(t.doneTaskBkgColor,";\n stroke-width: 2;\n cursor: pointer;\n shape-rendering: crispEdges;\n }\n\n .milestone {\n transform: rotate(45deg) scale(0.8,0.8);\n }\n\n .milestoneText {\n font-style: italic;\n }\n .doneCritText0,\n .doneCritText1,\n .doneCritText2,\n .doneCritText3 {\n fill: ").concat(t.taskTextDarkColor," !important;\n }\n\n .activeCritText0,\n .activeCritText1,\n .activeCritText2,\n .activeCritText3 {\n fill: ").concat(t.taskTextDarkColor," !important;\n }\n\n .titleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ").concat(t.textColor," ;\n font-family: 'trebuchet ms', verdana, arial;\n font-family: var(--mermaid-font-family);\n }\n")},classDiagram:No,"classDiagram-v2":No,class:No,stateDiagram:Lo,state:Lo,git:function(){return"\n .commit-id,\n .commit-msg,\n .branch-label {\n fill: lightgrey;\n color: lightgrey;\n font-family: 'trebuchet ms', verdana, arial;\n font-family: var(--mermaid-font-family);\n }\n"},info:function(){return""},pie:function(t){return".pieTitleText {\n text-anchor: middle;\n font-size: 25px;\n fill: ".concat(t.taskTextDarkColor,";\n font-family: ").concat(t.fontFamily,";\n }\n .slice {\n font-family: ").concat(t.fontFamily,";\n fill: ").concat(t.textColor,";\n // fill: white;\n }\n .legend text {\n fill: ").concat(t.taskTextDarkColor,";\n font-family: ").concat(t.fontFamily,";\n font-size: 17px;\n }\n")},er:function(t){return"\n .entityBox {\n fill: ".concat(t.mainBkg,";\n stroke: ").concat(t.nodeBorder,";\n }\n\n .relationshipLabelBox {\n fill: ").concat(t.tertiaryColor,";\n opacity: 0.7;\n background-color: ").concat(t.tertiaryColor,";\n rect {\n opacity: 0.5;\n }\n }\n\n .relationshipLine {\n stroke: ").concat(t.lineColor,";\n }\n")},journey:function(t){return".label {\n font-family: 'trebuchet ms', verdana, arial;\n font-family: var(--mermaid-font-family);\n color: ".concat(t.textColor,";\n }\n .mouth {\n stroke: #666;\n }\n\n line {\n stroke: ").concat(t.textColor,"\n }\n\n .legend {\n fill: ").concat(t.textColor,";\n }\n\n .label text {\n fill: #333;\n }\n .label {\n color: ").concat(t.textColor,"\n }\n\n .face {\n fill: #FFF8DC;\n stroke: #999;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ").concat(t.mainBkg,";\n stroke: ").concat(t.nodeBorder,";\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ").concat(t.arrowheadColor,";\n }\n\n .edgePath .path {\n stroke: ").concat(t.lineColor,";\n stroke-width: 1.5px;\n }\n\n .flowchart-link {\n stroke: ").concat(t.lineColor,";\n fill: none;\n }\n\n .edgeLabel {\n background-color: ").concat(t.edgeLabelBackground,";\n rect {\n opacity: 0.5;\n }\n text-align: center;\n }\n\n .cluster rect {\n }\n\n .cluster text {\n fill: ").concat(t.titleColor,";\n }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: 'trebuchet ms', verdana, arial;\n font-family: var(--mermaid-font-family);\n font-size: 12px;\n background: ").concat(t.tertiaryColor,";\n border: 1px solid ").concat(t.border2,";\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .task-type-0, .section-type-0 {\n ").concat(t.fillType0?"fill: ".concat(t.fillType0):"",";\n }\n .task-type-1, .section-type-1 {\n ").concat(t.fillType0?"fill: ".concat(t.fillType1):"",";\n }\n .task-type-2, .section-type-2 {\n ").concat(t.fillType0?"fill: ".concat(t.fillType2):"",";\n }\n .task-type-3, .section-type-3 {\n ").concat(t.fillType0?"fill: ".concat(t.fillType3):"",";\n }\n .task-type-4, .section-type-4 {\n ").concat(t.fillType0?"fill: ".concat(t.fillType4):"",";\n }\n .task-type-5, .section-type-5 {\n ").concat(t.fillType0?"fill: ".concat(t.fillType5):"",";\n }\n .task-type-6, .section-type-6 {\n ").concat(t.fillType0?"fill: ".concat(t.fillType6):"",";\n }\n .task-type-7, .section-type-7 {\n ").concat(t.fillType0?"fill: ".concat(t.fillType7):"",";\n }\n")}},Po=function(t,e,n){return" {\n font-family: ".concat(n.fontFamily,";\n font-size: ").concat(n.fontSize,";\n fill: ").concat(n.textColor,"\n }\n\n /* Classes common for multiple diagrams */\n\n .error-icon {\n fill: ").concat(n.errorBkgColor,";\n }\n .error-text {\n fill: ").concat(n.errorTextColor,";\n stroke: ").concat(n.errorTextColor,";\n }\n\n .edge-thickness-normal {\n stroke-width: 2px;\n }\n .edge-thickness-thick {\n stroke-width: 3.5px\n }\n .edge-pattern-solid {\n stroke-dasharray: 0;\n }\n\n .edge-pattern-dashed{\n stroke-dasharray: 3;\n }\n .edge-pattern-dotted {\n stroke-dasharray: 2;\n }\n\n .marker {\n fill: ").concat(n.lineColor,";\n }\n .marker.cross {\n stroke: ").concat(n.lineColor,";\n }\n\n svg {\n font-family: ").concat(n.fontFamily,";\n font-size: ").concat(n.fontSize,";\n }\n\n ").concat(Fo[t](n),"\n\n ").concat(e,"\n\n ").concat(t," { fill: apa;}\n")};function Io(t){return(Io="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var jo={},Ro=function(t,e,n){switch(f.debug("Directive type=".concat(e.type," with args:"),e.args),e.type){case"init":case"initialize":["config"].forEach((function(t){void 0!==e.args[t]&&("flowchart-v2"===n&&(n="flowchart"),e.args[n]=e.args[t],delete e.args[t])})),e.args,kt(e.args);break;case"wrap":case"nowrap":t&&t.setWrap&&t.setWrap("wrap"===e.type);break;default:f.warn("Unhandled directive: source: '%%{".concat(e.type,": ").concat(JSON.stringify(e.args?e.args:{}),"}%%"),e)}};function Yo(t){xa(t.git),ve(t.flowchart),Nn(t.flowchart),void 0!==t.sequenceDiagram&&br.setConf(P(t.sequence,t.sequenceDiagram)),br.setConf(t.sequence),ei(t.gantt),ci(t.class),Ri(t.state),Hi(t.state),Aa(t.class),Ra(t.class),Ka(t.er),Oo(t.journey),Da(t.class)}function zo(){}var Uo=Object.freeze({render:function(t,e,n,r){wt();var i=e,a=W.detectInit(i);a&&kt(a);var u=xt();if(e.length>u.maxTextSize&&(i="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa"),void 0!==r)r.innerHTML="",Object(s.select)(r).append("div").attr("id","d"+t).attr("style","font-family: "+u.fontFamily).append("svg").attr("id",t).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg").append("g");else{var l=document.getElementById(t);l&&l.remove();var h=document.querySelector("#d"+t);h&&h.remove(),Object(s.select)("body").append("div").attr("id","d"+t).append("svg").attr("id",t).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg").append("g")}window.txt=i,i=function(t){var e=t;return e=(e=(e=e.replace(/style.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)}))).replace(/classDef.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)}))).replace(/#\w+;/g,(function(t){var e=t.substring(1,t.length-1);return/^\+?\d+$/.test(e)?"fl°°"+e+"¶ß":"fl°"+e+"¶ß"}))}(i);var d=Object(s.select)("#d"+t).node(),p=W.detectType(i),g=d.firstChild,y=g.firstChild,v="";if(void 0!==u.themeCSS&&(v+="\n".concat(u.themeCSS)),void 0!==u.fontFamily&&(v+="\n:root { --mermaid-font-family: ".concat(u.fontFamily,"}")),void 0!==u.altFontFamily&&(v+="\n:root { --mermaid-alt-font-family: ".concat(u.altFontFamily,"}")),"flowchart"===p||"flowchart-v2"===p||"graph"===p){var m=me(i);for(var b in m)v+="\n.".concat(b," > * { ").concat(m[b].styles.join(" !important; ")," !important; }"),m[b].textStyles&&(v+="\n.".concat(b," tspan { ").concat(m[b].textStyles.join(" !important; ")," !important; }"))}var x=(new o.a)("#".concat(t),Po(p,v,u.themeVariables)),_=document.createElement("style");_.innerHTML=x,g.insertBefore(_,y);try{switch(p){case"git":u.flowchart.arrowMarkerAbsolute=u.arrowMarkerAbsolute,xa(u.git),_a(i,t,!1);break;case"flowchart":u.flowchart.arrowMarkerAbsolute=u.arrowMarkerAbsolute,ve(u.flowchart),be(i,t,!1);break;case"flowchart-v2":u.flowchart.arrowMarkerAbsolute=u.arrowMarkerAbsolute,Nn(u.flowchart),Bn(i,t,!1);break;case"sequence":u.sequence.arrowMarkerAbsolute=u.arrowMarkerAbsolute,u.sequenceDiagram?(br.setConf(Object.assign(u.sequence,u.sequenceDiagram)),console.error("`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.")):br.setConf(u.sequence),br.draw(i,t);break;case"gantt":u.gantt.arrowMarkerAbsolute=u.arrowMarkerAbsolute,ei(u.gantt),ni(i,t);break;case"class":u.class.arrowMarkerAbsolute=u.arrowMarkerAbsolute,ci(u.class),ui(i,t);break;case"classDiagram":u.class.arrowMarkerAbsolute=u.arrowMarkerAbsolute,hi(u.class),fi(i,t);break;case"state":u.class.arrowMarkerAbsolute=u.arrowMarkerAbsolute,Ri(u.state),Yi(i,t);break;case"stateDiagram":u.class.arrowMarkerAbsolute=u.arrowMarkerAbsolute,Hi(u.state),Gi(i,t);break;case"info":u.class.arrowMarkerAbsolute=u.arrowMarkerAbsolute,Aa(u.class),Ma(i,t,c.version);break;case"pie":u.class.arrowMarkerAbsolute=u.arrowMarkerAbsolute,Ra(u.pie),Ya(i,t,c.version);break;case"er":Ka(u.er),to(i,t,c.version);break;case"journey":Oo(u.journey),Do(i,t,c.version)}}catch(e){throw Na(t,c.version),e}Object(s.select)('[id="'.concat(t,'"]')).selectAll("foreignobject > *").attr("xmlns","http://www.w3.org/1999/xhtml");var k=Object(s.select)("#d"+t).node().innerHTML;if(f.debug("cnf.arrowMarkerAbsolute",u.arrowMarkerAbsolute),u.arrowMarkerAbsolute&&"false"!==u.arrowMarkerAbsolute||(k=k.replace(/marker-end="url\(.*?#/g,'marker-end="url(#',"g")),k=function(t){var e=t;return e=(e=(e=e.replace(/fl°°/g,(function(){return"&#"}))).replace(/fl°/g,(function(){return"&"}))).replace(/¶ß/g,(function(){return";"}))}(k),void 0!==n)switch(p){case"flowchart":case"flowchart-v2":n(k,qt.bindFunctions);break;case"gantt":n(k,Jr.bindFunctions);break;case"class":case"classDiagram":n(k,on.bindFunctions);break;default:n(k)}else f.debug("CB = undefined!");var w=Object(s.select)("#d"+t).node();return null!==w&&"function"==typeof w.remove&&Object(s.select)("#d"+t).node().remove(),k},parse:function(t){var e=W.detectInit(t);e&&f.debug("reinit ",e);var n,r=W.detectType(t);switch(f.debug("Type "+r),r){case"git":(n=ua.a).parser.yy=sa;break;case"flowchart":case"flowchart-v2":qt.clear(),(n=Zt.a).parser.yy=qt;break;case"sequence":(n=$n.a).parser.yy=ar;break;case"gantt":(n=_r.a).parser.yy=Jr;break;case"class":case"classDiagram":(n=ii.a).parser.yy=on;break;case"state":case"stateDiagram":(n=Mi.a).parser.yy=Si;break;case"info":f.debug("info info info"),(n=Ca.a).parser.yy=Ea;break;case"pie":f.debug("pie"),(n=Ia.a).parser.yy=Fa;break;case"er":f.debug("er"),(n=Ha.a).parser.yy=Wa;break;case"journey":f.debug("Journey"),(n=no.a).parser.yy=lo}return n.parser.yy.graphType=r,n.parser.yy.parseError=function(t,e){throw{str:t,hash:e}},n.parse(t),n},parseDirective:function(t,e,n,r){try{if(void 0!==e)switch(e=e.trim(),n){case"open_directive":jo={};break;case"type_directive":jo.type=e.toLowerCase();break;case"arg_directive":jo.args=JSON.parse(e);break;case"close_directive":Ro(t,jo,r),jo=null}}catch(t){f.error("Error while rendering sequenceDiagram directive: ".concat(e," jison context: ").concat(n)),f.error(t.message)}},initialize:function(t){t&&t.fontFamily&&(t.themeVariables&&t.themeVariables.fontFamily||(t.themeVariables={fontFamily:t.fontFamily})),ft=P({},t),t&&t.theme&<[t.theme]?t.themeVariables=lt[t.theme].getThemeVariables(t.themeVariables):t&&(t.themeVariables=lt.default.getThemeVariables(t.themeVariables));var e="object"===Io(t)?function(t){return gt=P({},pt),gt=P(gt,t),t.theme&&(gt.themeVariables=lt[t.theme].getThemeVariables(t.themeVariables)),vt=mt(gt,yt),gt}(t):bt();Yo(e),d(e.logLevel)},reinitialize:zo,getConfig:xt,setConfig:function(t){return P(vt,t),xt()},getSiteConfig:bt,updateSiteConfig:function(t){return gt=P(gt,t),mt(gt,yt),gt},reset:function(){wt()},globalReset:function(){wt(),Yo(xt())},defaultConfig:pt});d(xt().logLevel),wt(xt());var $o=Uo,Wo=function(){Vo.startOnLoad?$o.getConfig().startOnLoad&&Vo.init():void 0===Vo.startOnLoad&&(f.debug("In start, no config"),$o.getConfig().startOnLoad&&Vo.init())};"undefined"!=typeof document&& +/*! + * Wait for document loaded before starting the execution + */ +window.addEventListener("load",(function(){Wo()}),!1);var Vo={startOnLoad:!0,htmlLabels:!0,mermaidAPI:$o,parse:$o.parse,render:$o.render,init:function(){var t,e,n,r=this,a=$o.getConfig();arguments.length>=2?( +/*! sequence config was passed as #1 */ +void 0!==arguments[0]&&(Vo.sequenceConfig=arguments[0]),t=arguments[1]):t=arguments[0],"function"==typeof arguments[arguments.length-1]?(e=arguments[arguments.length-1],f.debug("Callback function found")):void 0!==a.mermaid&&("function"==typeof a.mermaid.callback?(e=a.mermaid.callback,f.debug("Callback function found")):f.debug("No Callback function found")),t=void 0===t?document.querySelectorAll(".mermaid"):"string"==typeof t?document.querySelectorAll(t):t instanceof window.Node?[t]:t,f.debug("Start On Load before: "+Vo.startOnLoad),void 0!==Vo.startOnLoad&&(f.debug("Start On Load inner: "+Vo.startOnLoad),$o.updateSiteConfig({startOnLoad:Vo.startOnLoad})),void 0!==Vo.ganttConfig&&$o.updateSiteConfig({gantt:Vo.ganttConfig});for(var o=function(a){var o=t[a]; +/*! Check if previously processed */if(o.getAttribute("data-processed"))return"continue";o.setAttribute("data-processed",!0);var s="mermaid-".concat(Date.now());n=i(n=o.innerHTML).trim().replace(//gi,"
");var c=W.detectInit(n);c&&f.debug("Detected early reinit: ",c);try{$o.render(s,n,(function(t,n){o.innerHTML=t,void 0!==e&&e(s),n&&n(o)}),o)}catch(t){f.warn("Syntax Error rendering"),f.warn(t),r.parseError&&r.parseError(t)}},s=0;s b3 + b4 -> b3 + b3 -> b1 + b2 -> genesis + b1 -> genesis +} +``` + +A blockchain network is comprised of nodes. These nodes each have a view of many different forks of a blockchain and must decide which forks to follow and what actions to take based on the forks of the chain that they are aware of. + +So in specifying an architecture to carry out the functionality of a Parachain Host, we have to answer two categories of questions: + +1. What is the state-transition function of the blockchain? What is necessary for a transition to be considered valid, and what information is carried within the implicit state of a block? +1. Being aware of various forks of the blockchain as well as global private state such as a view of the current time, what behaviors should a node undertake? What information should a node extract from the state of which forks, and how should that information be used? + +The first category of questions will be addressed by the Runtime, which defines the state-transition logic of the chain. Runtime logic only has to focus on the perspective of one chain, as each state has only a single parent state. + +The second category of questions addressed by Node-side behavior. Node-side behavior defines all activities that a node undertakes, given its view of the blockchain/block-DAG. Node-side behavior can take into account all or many of the forks of the blockchain, and only conditionally undertake certain activities based on which forks it is aware of, as well as the state of the head of those forks. + +```dot process +digraph G { + Runtime [shape=box] + "Node" [shape=box margin=0.5] + Transport [shape=rectangle width=5] + + Runtime -> "Node" [dir=both label="Runtime API"] + + "Node" -> Transport [penwidth=1] +} + +``` + +It is also helpful to divide Node-side behavior into two further categories: Networking and Core. Networking behaviors relate to how information is distributed between nodes. Core behaviors relate to internal work that a specific node does. These two categories of behavior often interact, but can be heavily abstracted from each other. Core behaviors care that information is distributed and received, but not the internal details of how distribution and receipt function. Networking behaviors act on requests for distribution or fetching of information, but are not concerned with how the information is used afterwards. This allows us to create clean boundaries between Core and Networking activities, improving the modularity of the code. + +```text + ___________________ ____________________ + / Core \ / Networking \ + | | Send "Hello" | | + | |- to "foo" --->| | + | | | | + | | | | + | | | | + | | Got "World" | | + | |<-- from "bar" --| | + | | | | + \___________________/ \____________________/ + ______| |______ + ___Transport___ + +``` + +Node-side behavior is split up into various subsystems. Subsystems are long-lived workers that perform a particular category of work. Subsystems can communicate with each other, and do so via an [Overseer](node/overseer.md) that prevents race conditions. + +Runtime logic is divided up into Modules and APIs. Modules encapsulate particular behavior of the system. Modules consist of storage, routines, and entry-points. Routines are invoked by entry points, by other modules, upon block initialization or closing. Routines can read and alter the storage of the module. Entry-points are the means by which new information is introduced to a module and can limit the origins (user, root, parachain) that they accept being called by. Each block in the blockchain contains a set of Extrinsics. Each extrinsic targets a a specific entry point to trigger and which data should be passed to it. Runtime APIs provide a means for Node-side behavior to extract meaningful information from the state of a single fork. + +These two aspects of the implementation are heavily dependent on each other. The Runtime depends on Node-side behavior to author blocks, and to include Extrinsics which trigger the correct entry points. The Node-side behavior relies on Runtime APIs to extract information necessary to determine which actions to take. diff --git a/polkadot/roadmap/implementers-guide/src/disputes-flow.md b/polkadot/roadmap/implementers-guide/src/disputes-flow.md new file mode 100644 index 0000000000000000000000000000000000000000..a325b2ce727276fbb8b91e0a11760365bd56cdc1 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/disputes-flow.md @@ -0,0 +1,124 @@ +# Disputes Flows + +A component-free description in what-if form with addition state graphs of the dispute. + +```mermaid +stateDiagram-v2 + [*] --> WaitForBackingVote: negative Vote received + [*] --> WaitForDisputeVote: backing Vote received + WaitForBackingVote --> Open: negative Vote received + WaitForDisputeVote --> Open: backing Vote received + Open --> Concluded: Incoming Vote via Gossip + Open --> Open: No ⅔ supermajority + Open --> [*] + Concluded --> [*] +``` + +--- + +```mermaid +stateDiagram-v2 + [*] --> Open: First Vote(s) received + Open --> HasPoV : Fetch Availability Store for PoV + + HasPoV --> HasCode : Fetch historical Code + HasCode --> VerifyWithRuntime: All Data locally avail + + Open --> DisputeAvailabilityDataReceived + DisputeAvailabilityDataReceived --> VerifyWithRuntime: Received Gossip + + HasPoV --> RequestDisputeAvailabilityData: nope + HasCode --> RequestDisputeAvailabilityData: nope + RequestDisputeAvailabilityData --> VerifyWithRuntime: Received + RequestDisputeAvailabilityData --> RequestDisputeAvailabilityData: Timed out - pick another peer + + VerifyWithRuntime --> CastVoteValid: Block Valid + VerifyWithRuntime --> CastVoteInvalid: Block Invalid + CastVoteInvalid --> GossipVote + CastVoteValid --> GossipVote + GossipVote --> [*] + +``` + +--- + +Dispute Availability Data + +```mermaid +stateDiagram-v2 + [*] --> Open: First Vote(s) received + Open --> DisputeDataAvail: somehow the data became available + Open --> RespondUnavailable: Data not available + IncomingRequestDisputeAvailabilityData --> RespondUnavailable + IncomingRequestDisputeAvailabilityData --> DisputeDataAvail + DisputeDataAvail --> RespondWithDisputeAvailabilityData: Send + VoteGossipReceived --> Track: implies source peer has
dispute availablity data +``` + +--- + +Peer handling + +```mermaid +stateDiagram-v2 + [*] --> Open: First Vote(s) received + Open --> GossipVotes: for all current peers + Open --> PeerConnected: another + PeerConnected --> GossipVotes: Peer connects + GossipVotes --> [*] +``` + +## Conditional formulation + +The set of validators eligible to vote consists of +the validators that had duty at the time of backing, plus backing votes by the backing validators. + +If a validator receives an initial dispute message (a set of votes where there are at least two opposing votes contained), and the PoV or Code are hence not reconstructable from local storage, that validator must request the required data from its peers. + +The dispute availability message must contain code, persisted validation data, and the proof of validity. + +Only peers that already voted shall be queried for the dispute availability data. + +The peer to be queried for disputes data, must be picked at random. + +A validator must retain code, persisted validation data and PoV until a block, that contains the dispute resolution, is finalized - plus an additional 24 hours. + +Dispute availability gossip must continue beyond the dispute resolution, until the post resolution timeout expired (equiv to the timeout until which additional late votes are accepted). + +Remote disputes are disputes that are in relation to a chain that is not part of the local validators active heads. + +All incoming votes must be persisted. + +Persisted votes stay persisted for `N` sessions, and are cleaned up on a per session basis. + +Votes must be queryable by a particular validator, identified by its signing key. + +Votes must be queryable by a particular validator, identified by a session index and the validator index valid in that session. + +If there exists a negative and a positive vote for a particular block, a dispute is detected. + +If a dispute is detected, all currently available votes for that block must be gossiped. + +If an incoming dispute vote is detected, a validator must cast their own vote. The vote is determined by validating the PoV with the Code at the time of backing the block in question. + +If the validator was also a backer of the block, validation and casting an additional vote should be skipped. + +If the count of votes pro or cons regarding the disputed block, reaches the required ⅔ supermajority (including the backing votes), the conclusion must be recorded on chain and the voters on the loosing and no-shows being slashed appropriately. + +If a block is found invalid by a dispute resolution, it must be blacklisted to avoid resync or further build on that chain if other chains are available (to be detailed in the grandpa fork choice rule). + +A dispute accepts Votes after the dispute is resolved, for 1 day. + +If a vote is received, after the dispute is resolved, the vote shall still be recorded in the state root, albeit yielding less reward. + +Recording in the state root might happen batched, at timeout expiry. + +If a new active head/chain appears, and the dispute resolution was not recorded on that chain yet, the dispute resolution or open dispute must be recorded / transplanted to that chain as well, since the disputes must be present on all chains to make sure the offender is punished. + +If a validator votes in two opposing ways, this composes of a double vote like in other cases (backing, approval voting). + +If a dispute is not resolved within due time, all validators are to be slashed for a small amount. + +If a dispute is not resolved within due time, governance mode shall be entered for manual resolution. + +If a validator unexpectedly restarts, the dispute shall be continued with the state based on votes being cast and being present in persistent storage. diff --git a/polkadot/roadmap/implementers-guide/src/further-reading.md b/polkadot/roadmap/implementers-guide/src/further-reading.md new file mode 100644 index 0000000000000000000000000000000000000000..535a2204d9485187b273f61d9f701ec3359d7d51 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/further-reading.md @@ -0,0 +1,4 @@ +# Further Reading + +- Polkadot Wiki on Consensus: +- Polkadot Spec: diff --git a/polkadot/roadmap/implementers-guide/src/glossary.md b/polkadot/roadmap/implementers-guide/src/glossary.md new file mode 100644 index 0000000000000000000000000000000000000000..a036ccdd668c54ff89933189238757d9b65632b1 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/glossary.md @@ -0,0 +1,50 @@ +# Glossary + +Here you can find definitions of a bunch of jargon, usually specific to the Polkadot project. + +- **Approval Checker:** A validator who randomly self-selects so to perform validity checks on a parablock which is pending approval. +- **BABE:** (Blind Assignment for Blockchain Extension). The algorithm validators use to safely extend the Relay Chain. See [the Polkadot wiki][0] for more information. +- **Backable Candidate:** A Parachain Candidate which is backed by a majority of validators assigned to a given parachain. +- **Backed Candidate:** A Backable Candidate noted in a relay-chain block +- **Backing:** A set of statements proving that a Parachain Candidate is backable. +- **Collator:** A node who generates Proofs-of-Validity (PoV) for blocks of a specific parachain. +- **DMP:** (Downward Message Passing). Message passing from the relay-chain to a parachain. Also there is a runtime parachains module with the same name. +- **DMQ:** (Downward Message Queue). A message queue for messages from the relay-chain down to a parachain. A parachain has +exactly one downward message queue. +- **Extrinsic:** An element of a relay-chain block which triggers a specific entry-point of a runtime module with given arguments. +- **GRANDPA:** (Ghost-based Recursive ANcestor Deriving Prefix Agreement). The algorithm validators use to guarantee finality of the Relay Chain. +- **HRMP:** (Horizontally Relay-routed Message Passing). A mechanism for message passing between parachains (hence horizontal) that leverages the relay-chain storage. Predates XCMP. Also there is a runtime parachains module with the same name. +- **Inclusion Pipeline:** The set of steps taken to carry a Parachain Candidate from authoring, to backing, to availability and full inclusion in an active fork of its parachain. +- **Module:** A component of the Runtime logic, encapsulating storage, routines, and entry-points. +- **Module Entry Point:** A recipient of new information presented to the Runtime. This may trigger routines. +- **Module Routine:** A piece of code executed within a module by block initialization, closing, or upon an entry point being triggered. This may execute computation, and read or write storage. +- **MQC:** (Message Queue Chain). A cryptographic data structure that resembles an append-only linked list which doesn't store original values but only their hashes. The whole structure is described by a single hash, referred as a "head". When a value is appended, it's contents hashed with the previous head creating a hash that becomes a new head. +- **Node:** A participant in the Polkadot network, who follows the protocols of communication and connection to other nodes. Nodes form a peer-to-peer network topology without a central authority. +- **Parachain Candidate, or Candidate:** A proposed block for inclusion into a parachain. +- **Parablock:** A block in a parachain. +- **Parachain:** A constituent chain secured by the Relay Chain's validators. +- **Parachain Validators:** A subset of validators assigned during a period of time to back candidates for a specific parachain +- **On-demand parachain:** A parachain which is scheduled on a pay-as-you-go basis. +- **Lease holding parachain:** A parachain possessing an active slot lease. The lease holder is assigned a single availability core for the duration of the lease, granting consistent blockspace scheduling at the rate 1 parablock per relay block. +- **PDK (Parachain Development Kit):** A toolset that allows one to develop a parachain. Cumulus is a PDK. +- **Preimage:** In our context, if `H(X) = Y` where `H` is a hash function and `Y` is the hash, then `X` is the hash preimage. +- **Proof-of-Validity (PoV):** A stateless-client proof that a parachain candidate is valid, with respect to some validation function. +- **PVF:** Parachain Validation Function. The validation code that is run by validators on parachains. +- **PVF Prechecking:** This is the process of initially checking the PVF when it is first added. We attempt preparation of the PVF and make sure it succeeds within a given timeout, plus some additional checks. +- **PVF Preparation:** This is the process of preparing the WASM blob and includes both prevalidation and compilation. As there is no prevalidation right now, preparation just consists of compilation. +- **Relay Parent:** A block in the relay chain, referred to in a context where work is being done in the context of the state at this block. +- **Runtime:** The relay-chain state machine. +- **Runtime Module:** See Module. +- **Runtime API:** A means for the node-side behavior to access structured information based on the state of a fork of the blockchain. +- **Subsystem:** A long-running task which is responsible for carrying out a particular category of work. +- **UMP:** (Upward Message Passing) A vertical message passing mechanism from a parachain to the relay chain. +- **Validator:** Specially-selected node in the network who is responsible for validating parachain blocks and issuing attestations about their validity. +- **Validation Function:** A piece of Wasm code that describes the state-transition function of a parachain. +- **VMP:** (Vertical Message Passing) A family of mechanisms that are responsible for message exchange between the relay chain and parachains. +- **XCMP:** (Cross-Chain Message Passing) A type of horizontal message passing (i.e. between parachains) that allows secure message passing directly between parachains and has minimal resource requirements from the relay chain, thus highly scalable. + +## See Also + +Also of use is the [Substrate Glossary](https://substrate.dev/docs/en/knowledgebase/getting-started/glossary). + +[0]: https://wiki.polkadot.network/docs/learn-consensus diff --git a/polkadot/roadmap/implementers-guide/src/messaging.md b/polkadot/roadmap/implementers-guide/src/messaging.md new file mode 100644 index 0000000000000000000000000000000000000000..edc810e034154278e53e78b1e563dcbf299b1613 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/messaging.md @@ -0,0 +1,105 @@ +# Messaging Overview + +The Polkadot Host has a few mechanisms that are responsible for message passing. They can be generally divided +on two categories: Horizontal and Vertical. Horizontal Message Passing (HMP) refers to mechanisms +that are responsible for exchanging messages between parachains. Vertical Message Passing (VMP) is +used for communication between the relay chain and parachains. + +## Vertical Message Passing + +```dot process +digraph { + rc [shape=Mdiamond label="Relay Chain"]; + p1 [shape=box label = "Parachain"]; + + rc -> p1 [label="DMP"]; + p1 -> rc [label="UMP"]; +} +``` + +Downward Message Passing (DMP) is a mechanism for delivering messages to parachains from the relay chain. + +Each parachain has its own queue that stores all pending inbound downward messages. A parachain +doesn't have to process all messages at once, however, there are rules as to how the downward message queue +should be processed. Currently, at least one message must be consumed per candidate if the queue is not empty. +The downward message queue doesn't have a cap on its size and it is up to the relay-chain to put mechanisms +that prevent spamming in place. + +Upward Message Passing (UMP) is a mechanism responsible for delivering messages in the opposite direction: +from a parachain up to the relay chain. Upward messages are essentially byte blobs. However, they are interpreted +by the relay-chain according to the XCM standard. + +The XCM standard is a common vocabulary of messages. The XCM standard doesn't require a particular interpretation of +a message. However, the parachains host (e.g. Polkadot) guarantees certain semantics for those. + +Moreover, while most XCM messages are handled by the on-chain XCM interpreter, some of the messages are special +cased. Specifically, those messages can be checked during the acceptance criteria and thus invalid +messages would lead to rejecting the candidate itself. + +One kind of such a message is `Xcm::Transact`. This upward message can be seen as a way for a parachain +to execute arbitrary entrypoints on the relay-chain. `Xcm::Transact` messages resemble regular extrinsics with the exception that they +originate from a parachain. + +The payload of `Xcm::Transact` messages is referred as to `Dispatchable`. When a candidate with such a message is enacted +the dispatchables are put into a queue corresponding to the parachain. There can be only so many dispatchables in that queue at once. +The weight that processing of the dispatchables can consume is limited by a preconfigured value. Therefore, it is possible +that some dispatchables will be left for later blocks. To make the dispatching more fair, the queues are processed turn-by-turn +in a round robin fashion. + +The second category of special cased XCM messages are for horizontal messaging channel management, +namely messages meant to request opening and closing HRMP channels (HRMP will be described below). + +## Horizontal Message Passing + +```dot process +digraph { + rc [shape=Mdiamond color="gray" fontcolor="gray" label="Relay Chain"]; + + subgraph { + rank = "same" + p1 [shape=box label = "Parachain 1"]; + p2 [shape=box label = "Parachain 2"]; + } + + rc -> p1 [label="DMP" color="gray" fontcolor="gray"]; + p1 -> rc [label="UMP" color="gray" fontcolor="gray"]; + + rc -> p2 [label="DMP" color="gray" fontcolor="gray"]; + p2 -> rc [label="UMP" color="gray" fontcolor="gray"]; + + p2 -> p1 [dir=both label="XCMP"]; +} +``` + +### Cross-Chain Message Passing + +The most important member of this family is XCMP. + +> ℹ️ XCMP is currently under construction and details are subject for change. + +XCMP is a message passing mechanism between parachains that require minimal involvement of the relay chain. +The relay chain provides means for sending parachains to authenticate messages sent to recipient parachains. + +Semantically communication occurs through so called channels. A channel is unidirectional and it has +two endpoints, for sender and for recipient. A channel can be opened only if the both parties agree +and closed unilaterally. + +Only the channel metadata is stored on the relay-chain in a very compact form: all messages and their +contents sent by the sender parachain are encoded using only one root hash. This root is referred as +MQC head. + +The authenticity of the messages must be proven using that root hash to the receiving party at the +candidate authoring time. The proof stems from the relay parent storage that contains the root hash of the channel. +Since not all messages are required to be processed by the receiver's candidate, only the processed +messages are supplied (i.e. preimages), rest are provided as hashes. + +Further details can be found at the official repository for the +[Cross-Consensus Message Format (XCM)](https://github.com/paritytech/xcm-format/blob/master/README.md), as well as +at the [W3F research website](https://research.web3.foundation/en/latest/polkadot/XCMP.html) and +[this blogpost](https://medium.com/web3foundation/polkadots-messaging-scheme-b1ec560908b7). + +HRMP (Horizontally Relay-routed Message Passing) is a stop gap that predates XCMP. Semantically, it mimics XCMP's interface. +The crucial difference from XCMP though is that all the messages are stored in the relay-chain storage. That makes +things simple but at the same time that makes HRMP more demanding in terms of resources thus making it more expensive. + +Once XCMP is available we expect to retire HRMP. diff --git a/polkadot/roadmap/implementers-guide/src/node/README.md b/polkadot/roadmap/implementers-guide/src/node/README.md new file mode 100644 index 0000000000000000000000000000000000000000..edd72d2335b5941971bfc8b9534a4f70b94762d8 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/README.md @@ -0,0 +1,31 @@ +# Node Architecture + +## Design Goals + +* Modularity: Components of the system should be as self-contained as possible. Communication boundaries between components should be well-defined and mockable. This is key to creating testable, easily reviewable code. +* Minimizing side effects: Components of the system should aim to minimize side effects and to communicate with other components via message-passing. +* Operational Safety: The software will be managing signing keys where conflicting messages can lead to large amounts of value to be slashed. Care should be taken to ensure that no messages are signed incorrectly or in conflict with each other. + +The architecture of the node-side behavior aims to embody the Rust principles of ownership and message-passing to create clean, isolatable code. Each resource should have a single owner, with minimal sharing where unavoidable. + +Many operations that need to be carried out involve the network, which is asynchronous. This asynchrony affects all core subsystems that rely on the network as well. The approach of hierarchical state machines is well-suited to this kind of environment. + +We introduce + +## Components + +The node architecture consists of the following components: + * The Overseer (and subsystems): A hierarchy of state machines where an overseer supervises subsystems. Subsystems can contain their own internal hierarchy of jobs. This is elaborated on in the next section on Subsystems. + * A block proposer: Logic triggered by the consensus algorithm of the chain when the node should author a block. + * A GRANDPA voting rule: A strategy for selecting chains to vote on in the GRANDPA algorithm to ensure that only valid parachain candidates appear in finalized relay-chain blocks. + +## Assumptions + +The Node-side code comes with a set of assumptions that we build upon. These assumptions encompass most of the fundamental blockchain functionality. + +We assume the following constraints regarding provided basic functionality: + * The underlying **consensus** algorithm, whether it is BABE or SASSAFRAS is implemented. + * There is a **chain synchronization** protocol which will search for and download the longest available chains at all times. + * The **state** of all blocks at the head of the chain is available. There may be **state pruning** such that state of the last `k` blocks behind the last finalized block are available, as well as the state of all their descendants. This assumption implies that the state of all active leaves and their last `k` ancestors are all available. The underlying implementation is expected to support `k` of a few hundred blocks, but we reduce this to a very conservative `k=5` for our purposes. + * There is an underlying **networking** framework which provides **peer discovery** services which will provide us with peers and will not create "loopback" connections to our own node. The number of peers we will have is assumed to be bounded at 1000. + * There is a **transaction pool** and a **transaction propagation** mechanism which maintains a set of current transactions and distributes to connected peers. Current transactions are those which are not outdated relative to some "best" fork of the chain, which is part of the active heads, and have not been included in the best fork. diff --git a/polkadot/roadmap/implementers-guide/src/node/approval/README.md b/polkadot/roadmap/implementers-guide/src/node/approval/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1f65173e16bb0c3ffd47d72ccf674820dc252148 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/approval/README.md @@ -0,0 +1,7 @@ +# Approval Subsystems + +The approval subsystems implement the node-side of the [Approval Protocol](../../protocol-approval.md). + +We make a divide between the [assignment/voting logic](approval-voting.md) and the [distribution logic](approval-distribution.md) that distributes assignment certifications and approval votes. The logic in the assignment and voting also informs the GRANDPA voting rule on how to vote. + +These subsystems are intended to flag issues and begin participating in live disputes. Dispute subsystems also track all observed votes (backing, approval, and dispute-specific) by all validators on all candidates. diff --git a/polkadot/roadmap/implementers-guide/src/node/approval/approval-distribution.md b/polkadot/roadmap/implementers-guide/src/node/approval/approval-distribution.md new file mode 100644 index 0000000000000000000000000000000000000000..81c98afa16bf25439a59ae42ae1d3ace96a5558c --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/approval/approval-distribution.md @@ -0,0 +1,262 @@ +# Approval Distribution + +A subsystem for the distribution of assignments and approvals for approval checks on candidates over the network. + +The [Approval Voting](approval-voting.md) subsystem is responsible for active participation in a protocol designed to select a sufficient number of validators to check each and every candidate which appears in the relay chain. Statements of participation in this checking process are divided into two kinds: + - **Assignments** indicate that validators have been selected to do checking + - **Approvals** indicate that validators have checked and found the candidate satisfactory. + +The [Approval Voting](approval-voting.md) subsystem handles all the issuing and tallying of this protocol, but this subsystem is responsible for the disbursal of statements among the validator-set. + +The inclusion pipeline of candidates concludes after availability, and only after inclusion do candidates actually get pushed into the approval checking pipeline. As such, this protocol deals with the candidates _made available by_ particular blocks, as opposed to the candidates which actually appear within those blocks, which are the candidates _backed by_ those blocks. Unless stated otherwise, whenever we reference a candidate partially by block hash, we are referring to the set of candidates _made available by_ those blocks. + +We implement this protocol as a gossip protocol, and like other parachain-related gossip protocols our primary concerns are about ensuring fast message propagation while maintaining an upper bound on the number of messages any given node must store at any time. + +Approval messages should always follow assignments, so we need to be able to discern two pieces of information based on our [View](../../types/network.md#universal-types): + 1. Is a particular assignment relevant under a given `View`? + 2. Is a particular approval relevant to any assignment in a set? + +For our own local view, these two queries must not yield false negatives. When applied to our peers' views, it is acceptable for them to yield false negatives. The reason for that is that our peers' views may be beyond ours, and we are not capable of fully evaluating them. Once we have caught up, we can check again for false negatives to continue distributing. + +For assignments, what we need to be checking is whether we are aware of the (block, candidate) pair that the assignment references. For approvals, we need to be aware of an assignment by the same validator which references the candidate being approved. + +However, awareness on its own of a (block, candidate) pair would imply that even ancient candidates all the way back to the genesis are relevant. We are actually not interested in anything before finality. + +We gossip assignments along a grid topology produced by the [Gossip Support Subsystem](../utility/gossip-support.md) and also to a few random peers. The first time we accept an assignment or approval, regardless of the source, which originates from a validator peer in a shared dimension of the grid, we propagate the message to validator peers in the unshared dimension as well as a few random peers. + +But, in case these mechanisms don't work on their own, we need to trade bandwidth for protocol liveness by introducing aggression. + +Aggression has 3 levels: + Aggression Level 0: The basic behaviors described above. + Aggression Level 1: The originator of a message sends to all peers. Other peers follow the rules above. + Aggression Level 2: All peers send all messages to all their row and column neighbors. This means that each validator will, on average, receive each message approximately 2*sqrt(n) times. + +These aggression levels are chosen based on how long a block has taken to finalize: assignments and approvals related to the unfinalized block will be propagated with more aggression. In particular, it's only the earliest unfinalized blocks that aggression should be applied to, because descendants may be unfinalized only by virtue of being descendants. + +## Protocol + +Input: + - `ApprovalDistributionMessage::NewBlocks` + - `ApprovalDistributionMessage::DistributeAssignment` + - `ApprovalDistributionMessage::DistributeApproval` + - `ApprovalDistributionMessage::NetworkBridgeUpdate` + - `OverseerSignal::BlockFinalized` + +Output: + - `ApprovalVotingMessage::CheckAndImportAssignment` + - `ApprovalVotingMessage::CheckAndImportApproval` + - `NetworkBridgeMessage::SendValidationMessage::ApprovalDistribution` + +## Functionality + +```rust +type BlockScopedCandidate = (Hash, CandidateHash); + +enum PendingMessage { + Assignment(IndirectAssignmentCert, CoreIndex), + Approval(IndirectSignedApprovalVote), +} + +/// The `State` struct is responsible for tracking the overall state of the subsystem. +/// +/// It tracks metadata about our view of the unfinalized chain, which assignments and approvals we have seen, and our peers' views. +struct State { + // These two fields are used in conjunction to construct a view over the unfinalized chain. + blocks_by_number: BTreeMap>, + blocks: HashMap, + + /// Our view updates to our peers can race with `NewBlocks` updates. We store messages received + /// against the directly mentioned blocks in our view in this map until `NewBlocks` is received. + /// + /// As long as the parent is already in the `blocks` map and `NewBlocks` messages aren't delayed + /// by more than a block length, this strategy will work well for mitigating the race. This is + /// also a race that occurs typically on local networks. + pending_known: HashMap)>>, + + // Peer view data is partially stored here, and partially inline within the `BlockEntry`s + peer_views: HashMap, +} + +enum MessageFingerprint { + Assigment(Hash, u32, ValidatorIndex), + Approval(Hash, u32, ValidatorIndex), +} + +struct Knowledge { + known_messages: HashSet, +} + +struct PeerKnowledge { + /// The knowledge we've sent to the peer. + sent: Knowledge, + /// The knowledge we've received from the peer. + received: Knowledge, +} + +/// Information about blocks in our current view as well as whether peers know of them. +struct BlockEntry { + // Peers who we know are aware of this block and thus, the candidates within it. This maps to their knowledge of messages. + known_by: HashMap, + // The number of the block. + number: BlockNumber, + // The parent hash of the block. + parent_hash: Hash, + // Our knowledge of messages. + knowledge: Knowledge, + // A votes entry for each candidate. + candidates: IndexMap, +} + +enum ApprovalState { + Assigned(AssignmentCert), + Approved(AssignmentCert, ApprovalSignature), +} + +/// Information about candidates in the context of a particular block they are included in. In other words, +/// multiple `CandidateEntry`s may exist for the same candidate, if it is included by multiple blocks - this is likely the case +/// when there are forks. +struct CandidateEntry { + approvals: HashMap, +} +``` + +### Network updates + +#### `NetworkBridgeEvent::PeerConnected` + +Add a blank view to the `peer_views` state. + +#### `NetworkBridgeEvent::PeerDisconnected` + +Remove the view under the associated `PeerId` from `State::peer_views`. + +Iterate over every `BlockEntry` and remove `PeerId` from it. + +#### `NetworkBridgeEvent::OurViewChange` + +Remove entries in `pending_known` for all hashes not present in the view. +Ensure a vector is present in `pending_known` for each hash in the view that does not have an entry in `blocks`. + +#### `NetworkBridgeEvent::PeerViewChange` + +Invoke `unify_with_peer(peer, view)` to catch them up to messages we have. + +We also need to use the `view.finalized_number` to remove the `PeerId` from any blocks that it won't be wanting information about anymore. Note that we have to be on guard for peers doing crazy stuff like jumping their `finalized_number` forward 10 trillion blocks to try and get us stuck in a loop for ages. + +One of the safeguards we can implement is to reject view updates from peers where the new `finalized_number` is less than the previous. + +We augment that by defining `constrain(x)` to output the x bounded by the first and last numbers in `state.blocks_by_number`. + +From there, we can loop backwards from `constrain(view.finalized_number)` until `constrain(last_view.finalized_number)` is reached, removing the `PeerId` from all `BlockEntry`s referenced at that height. We can break the loop early if we ever exit the bound supplied by the first block in `state.blocks_by_number`. + +#### `NetworkBridgeEvent::PeerMessage` + +If the block hash referenced by the message exists in `pending_known`, add it to the vector of pending messages and return. + +If the message is of type `ApprovalDistributionV1Message::Assignment(assignment_cert, claimed_index)`, then call `import_and_circulate_assignment(MessageSource::Peer(sender), assignment_cert, claimed_index)` + +If the message is of type `ApprovalDistributionV1Message::Approval(approval_vote)`, then call `import_and_circulate_approval(MessageSource::Peer(sender), approval_vote)` + +### Subsystem Updates + +#### `ApprovalDistributionMessage::NewBlocks` + +Create `BlockEntry` and `CandidateEntries` for all blocks. + +For all entries in `pending_known`: + * If there is now an entry under `blocks` for the block hash, drain all messages and import with `import_and_circulate_assignment` and `import_and_circulate_approval`. + +For all peers: + * Compute `view_intersection` as the intersection of the peer's view blocks with the hashes of the new blocks. + * Invoke `unify_with_peer(peer, view_intersection)`. + +#### `ApprovalDistributionMessage::DistributeAsignment` + +Call `import_and_circulate_assignment` with `MessageSource::Local`. + +#### `ApprovalDistributionMessage::DistributeApproval` + +Call `import_and_circulate_approval` with `MessageSource::Local`. + +#### `OverseerSignal::BlockFinalized` + +Prune all lists from `blocks_by_number` with number less than or equal to `finalized_number`. Prune all the `BlockEntry`s referenced by those lists. + + +### Utility + +```rust +enum MessageSource { + Peer(PeerId), + Local, +} +``` + +#### `import_and_circulate_assignment(source: MessageSource, assignment: IndirectAssignmentCert, claimed_candidate_index: CandidateIndex)` + +Imports an assignment cert referenced by block hash and candidate index. As a postcondition, if the cert is valid, it will have distributed the cert to all peers who have the block in their view, with the exclusion of the peer referenced by the `MessageSource`. + +We maintain a few invariants: + * we only send an assignment to a peer after we add its fingerprint to our knowledge + * we add a fingerprint of an assignment to our knowledge only if it's valid and hasn't been added before + +The algorithm is the following: + + * Load the `BlockEntry` using `assignment.block_hash`. If it does not exist, report the source if it is `MessageSource::Peer` and return. + * Compute a fingerprint for the `assignment` using `claimed_candidate_index`. + * If the source is `MessageSource::Peer(sender)`: + * check if `peer` appears under `known_by` and whether the fingerprint is in the knowledge of the peer. If the peer does not know the block, report for providing data out-of-view and proceed. If the peer does know the block and the `sent` knowledge contains the fingerprint, report for providing replicate data and return, otherwise, insert into the `received` knowledge and return. + * If the message fingerprint appears under the `BlockEntry`'s `Knowledge`, give the peer a small positive reputation boost, + add the fingerprint to the peer's knowledge only if it knows about the block and return. + Note that we must do this after checking for out-of-view and if the peers knows about the block to avoid being spammed. + If we did this check earlier, a peer could provide data out-of-view repeatedly and be rewarded for it. + * Dispatch `ApprovalVotingMessage::CheckAndImportAssignment(assignment)` and wait for the response. + * If the result is `AssignmentCheckResult::Accepted` + * If the vote was accepted but not duplicate, give the peer a positive reputation boost + * add the fingerprint to both our and the peer's knowledge in the `BlockEntry`. Note that we only doing this after making sure we have the right fingerprint. + * If the result is `AssignmentCheckResult::AcceptedDuplicate`, add the fingerprint to the peer's knowledge if it knows about the block and return. + * If the result is `AssignmentCheckResult::TooFarInFuture`, mildly punish the peer and return. + * If the result is `AssignmentCheckResult::Bad`, punish the peer and return. + * If the source is `MessageSource::Local(CandidateIndex)` + * check if the fingerprint appears under the `BlockEntry's` knowledge. If not, add it. + * Load the candidate entry for the given candidate index. It should exist unless there is a logic error in the approval voting subsystem. + * Set the approval state for the validator index to `ApprovalState::Assigned` unless the approval state is set already. This should not happen as long as the approval voting subsystem instructs us to ignore duplicate assignments. + * Dispatch a `ApprovalDistributionV1Message::Assignment(assignment, candidate_index)` to all peers in the `BlockEntry`'s `known_by` set, excluding the peer in the `source`, if `source` has kind `MessageSource::Peer`. Add the fingerprint of the assignment to the knowledge of each peer. + + +#### `import_and_circulate_approval(source: MessageSource, approval: IndirectSignedApprovalVote)` + +Imports an approval signature referenced by block hash and candidate index: + + * Load the `BlockEntry` using `approval.block_hash` and the candidate entry using `approval.candidate_entry`. If either does not exist, report the source if it is `MessageSource::Peer` and return. + * Compute a fingerprint for the approval. + * Compute a fingerprint for the corresponding assignment. If the `BlockEntry`'s knowledge does not contain that fingerprint, then report the source if it is `MessageSource::Peer` and return. All references to a fingerprint after this refer to the approval's, not the assignment's. + * If the source is `MessageSource::Peer(sender)`: + * check if `peer` appears under `known_by` and whether the fingerprint is in the knowledge of the peer. If the peer does not know the block, report for providing data out-of-view and proceed. If the peer does know the block and the `sent` knowledge contains the fingerprint, report for providing replicate data and return, otherwise, insert into the `received` knowledge and return. + * If the message fingerprint appears under the `BlockEntry`'s `Knowledge`, give the peer a small positive reputation boost, + add the fingerprint to the peer's knowledge only if it knows about the block and return. + Note that we must do this after checking for out-of-view to avoid being spammed. If we did this check earlier, a peer could provide data out-of-view repeatedly and be rewarded for it. + * Dispatch `ApprovalVotingMessage::CheckAndImportApproval(approval)` and wait for the response. + * If the result is `VoteCheckResult::Accepted(())`: + * Give the peer a positive reputation boost and add the fingerprint to both our and the peer's knowledge. + * If the result is `VoteCheckResult::Bad`: + * Report the peer and return. + * Load the candidate entry for the given candidate index. It should exist unless there is a logic error in the approval voting subsystem. + * Set the approval state for the validator index to `ApprovalState::Approved`. It should already be in the `Assigned` state as our `BlockEntry` knowledge contains a fingerprint for the assignment. + * Dispatch a `ApprovalDistributionV1Message::Approval(approval)` to all peers in the `BlockEntry`'s `known_by` set, excluding the peer in the `source`, if `source` has kind `MessageSource::Peer`. Add the fingerprint of the assignment to the knowledge of each peer. Note that this obeys the politeness conditions: + * We guarantee elsewhere that all peers within `known_by` are aware of all assignments relative to the block. + * We've checked that this specific approval has a corresponding assignment within the `BlockEntry`. + * Thus, all peers are aware of the assignment or have a message to them in-flight which will make them so. + + +#### `unify_with_peer(peer: PeerId, view)`: + +1. Initialize a set `missing_knowledge = {}` + +For each block in the view: + 2. Load the `BlockEntry` for the block. If the block is unknown, or the number is less than or equal to the view's finalized number go to step 6. + 3. Inspect the `known_by` set of the `BlockEntry`. If the peer already knows all assignments/approvals, go to step 6. + 4. Add the peer to `known_by` and add the hash and missing knowledge of the block to `missing_knowledge`. + 5. Return to step 2 with the ancestor of the block. + +6. For each block in `missing_knowledge`, send all assignments and approvals for all candidates in those blocks to the peer. diff --git a/polkadot/roadmap/implementers-guide/src/node/approval/approval-voting.md b/polkadot/roadmap/implementers-guide/src/node/approval/approval-voting.md new file mode 100644 index 0000000000000000000000000000000000000000..88744e50cf7956b6629a1f8b97895eae13287012 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/approval/approval-voting.md @@ -0,0 +1,385 @@ +# Approval Voting + +Reading the [section on the approval protocol](../../protocol-approval.md) will likely be necessary to understand the aims of this subsystem. + +Approval votes are split into two parts: Assignments and Approvals. Validators first broadcast their assignment to indicate intent to check a candidate. Upon successfully checking, they broadcast an approval vote. If a validator doesn't broadcast their approval vote shortly after issuing an assignment, this is an indication that they are being prevented from recovering or validating the block data and that more validators should self-select to check the candidate. This is known as a "no-show". + +The core of this subsystem is a Tick-based timer loop, where Ticks are 500ms. We also reason about time in terms of `DelayTranche`s, which measure the number of ticks elapsed since a block was produced. We track metadata for all un-finalized but included candidates. We compute our local assignments to check each candidate, as well as which `DelayTranche` those assignments may be minimally triggered at. As the same candidate may appear in more than one block, we must produce our potential assignments for each (Block, Candidate) pair. The timing loop is based on waiting for assignments to become no-shows or waiting to broadcast and begin our own assignment to check. + +Another main component of this subsystem is the logic for determining when a (Block, Candidate) pair has been approved and when to broadcast and trigger our own assignment. Once a (Block, Candidate) pair has been approved, we mark a corresponding bit in the `BlockEntry` that indicates the candidate has been approved under the block. When we trigger our own assignment, we broadcast it via Approval Distribution, begin fetching the data from Availability Recovery, and then pass it through to the Candidate Validation. Once these steps are successful, we issue our approval vote. If any of these steps fail, we don't issue any vote and will "no-show" from the perspective of other validators in addition a dispute is raised via the dispute-coordinator, by sending `IssueLocalStatement`. + +Where this all fits into Polkadot is via block finality. Our goal is to not finalize any block containing a candidate that is not approved. We provide a hook for a custom GRANDPA voting rule - GRANDPA makes requests of the form (target, minimum) consisting of a target block (i.e. longest chain) that it would like to finalize, and a minimum block which, due to the rules of GRANDPA, must be voted on. The minimum is typically the last finalized block, but may be beyond it, in the case of having a last-round-estimate beyond the last finalized. Thus, our goal is to inform GRANDPA of some block between target and minimum which we believe can be finalized safely. We do this by iterating backwards from the target to the minimum and finding the longest continuous chain from minimum where all candidates included by those blocks have been approved. + +## Protocol + +Input: + - `ApprovalVotingMessage::CheckAndImportAssignment` + - `ApprovalVotingMessage::CheckAndImportApproval` + - `ApprovalVotingMessage::ApprovedAncestor` + +Output: + - `ApprovalDistributionMessage::DistributeAssignment` + - `ApprovalDistributionMessage::DistributeApproval` + - `RuntimeApiMessage::Request` + - `ChainApiMessage` + - `AvailabilityRecoveryMessage::Recover` + - `CandidateExecutionMessage::ValidateFromExhaustive` + +## Functionality + +The approval voting subsystem is responsible for casting votes and determining approval of candidates and as a result, blocks. + +This subsystem wraps a database which is used to store metadata about unfinalized blocks and the candidates within them. Candidates may appear in multiple blocks, and assignment criteria are chosen differently based on the hash of the block they appear in. + +## Database Schema + +The database schema is designed with the following goals in mind: + 1. To provide an easy index from unfinalized blocks to candidates + 1. To provide a lookup from candidate hash to approval status + 1. To be easy to clear on start-up. What has happened while we were offline is unimportant. + 1. To be fast to clear entries outdated by finality + +Structs: + +```rust +struct TrancheEntry { + tranche: DelayTranche, + // assigned validators who have not yet approved, and the instant we received + // their assignment. + assignments: Vec<(ValidatorIndex, Tick)>, +} + +struct OurAssignment { + cert: AssignmentCert, + tranche: DelayTranche, + validator_index: ValidatorIndex, + triggered: bool, +} + +struct ApprovalEntry { + tranches: Vec, // sorted ascending by tranche number. + backing_group: GroupIndex, + our_assignment: Option, + our_approval_sig: Option, + assignments: Bitfield, // n_validators bits + approved: bool, +} + +struct CandidateEntry { + candidate: CandidateReceipt, + session: SessionIndex, + // Assignments are based on blocks, so we need to track assignments separately + // based on the block we are looking at. + block_assignments: HashMap, + approvals: Bitfield, // n_validators bits +} + +struct BlockEntry { + block_hash: Hash, + session: SessionIndex, + slot: Slot, + // random bytes derived from the VRF submitted within the block by the block + // author as a credential and used as input to approval assignment criteria. + relay_vrf_story: [u8; 32], + // The candidates included as-of this block and the index of the core they are + // leaving. Sorted ascending by core index. + candidates: Vec<(CoreIndex, Hash)>, + // A bitfield where the i'th bit corresponds to the i'th candidate in `candidates`. + // The i'th bit is `true` iff the candidate has been approved in the context of + // this block. The block can be considered approved has all bits set to 1 + approved_bitfield: Bitfield, + children: Vec, +} + +// slot_duration * 2 + DelayTranche gives the number of delay tranches since the +// unix epoch. +type Tick = u64; + +struct StoredBlockRange(BlockNumber, BlockNumber); +``` + +In the schema, we map + +``` +"StoredBlocks" => StoredBlockRange +BlockNumber => Vec +BlockHash => BlockEntry +CandidateHash => CandidateEntry +``` + +## Logic + +```rust +const APPROVAL_SESSIONS: SessionIndex = 6; + +// The minimum amount of ticks that an assignment must have been known for. +const APPROVAL_DELAY: Tick = 2; +``` + +In-memory state: + +```rust +struct ApprovalVoteRequest { + validator_index: ValidatorIndex, + block_hash: Hash, + candidate_index: CandidateIndex, +} + +// Requests that background work (approval voting tasks) may need to make of the main subsystem +// task. +enum BackgroundRequest { + ApprovalVote(ApprovalVoteRequest), + // .. others, unspecified as per implementation. +} + +// This is the general state of the subsystem. The actual implementation may split this +// into further pieces. +struct State { + earliest_session: SessionIndex, + session_info: Vec, + babe_epoch: Option, // information about a cached BABE epoch. + keystore: Keystore, + + // A scheduler which keeps at most one wakeup per hash, candidate hash pair and + // maps such pairs to `Tick`s. + wakeups: Wakeups, + + // These are connected to each other. + background_tx: mpsc::Sender, + background_rx: mpsc::Receiver, +} +``` + +This guide section makes no explicit references to writes to or reads from disk. Instead, it handles them implicitly, with the understanding that updates to block, candidate, and approval entries are persisted to disk. + +[`SessionInfo`](../../runtime/session_info.md) + +On start-up, we clear everything currently stored by the database. This is done by loading the `StoredBlockRange`, iterating through each block number, iterating through each block hash, and iterating through each candidate referenced by each block. Although this is `O(o*n*p)`, we don't expect to have more than a few unfinalized blocks at any time and in extreme cases, a few thousand. The clearing operation should be relatively fast as a result. + +Main loop: + * Each iteration, select over all of + * The next `Tick` in `wakeups`: trigger `wakeup_process` for each `(Hash, Hash)` pair scheduled under the `Tick` and then remove all entries under the `Tick`. + * The next message from the overseer: handle the message as described in the [Incoming Messages section](#incoming-messages) + * The next approval vote request from `background_rx` + * If this is an `ApprovalVoteRequest`, [Issue an approval vote](#issue-approval-vote). + +### Incoming Messages + +#### `OverseerSignal::BlockFinalized` + +On receiving an `OverseerSignal::BlockFinalized(h)`, we fetch the block number `b` of that block from the `ChainApi` subsystem. We update our `StoredBlockRange` to begin at `b+1`. Additionally, we remove all block entries and candidates referenced by them up to and including `b`. Lastly, we prune out all descendants of `h` transitively: when we remove a `BlockEntry` with number `b` that is not equal to `h`, we recursively delete all the `BlockEntry`s referenced as children. We remove the `block_assignments` entry for the block hash and if `block_assignments` is now empty, remove the `CandidateEntry`. We also update each of the `BlockNumber -> Vec` keys in the database to reflect the blocks at that height, clearing if empty. + + +#### `OverseerSignal::ActiveLeavesUpdate` + +On receiving an `OverseerSignal::ActiveLeavesUpdate(update)`: + * We determine the set of new blocks that were not in our previous view. This is done by querying the ancestry of all new items in the view and contrasting against the stored `BlockNumber`s. Typically, there will be only one new block. We fetch the headers and information on these blocks from the `ChainApi` subsystem. Stale leaves in the update can be ignored. + * We update the `StoredBlockRange` and the `BlockNumber` maps. + * We use the `RuntimeApiSubsystem` to determine information about these blocks. It is generally safe to assume that runtime state is available for recent, unfinalized blocks. In the case that it isn't, it means that we are catching up to the head of the chain and needn't worry about assignments to those blocks anyway, as the security assumption of the protocol tolerates nodes being temporarily offline or out-of-date. + * We fetch the set of candidates included by each block by dispatching a `RuntimeApiRequest::CandidateEvents` and checking the `CandidateIncluded` events. + * We fetch the session of the block by dispatching a `session_index_for_child` request with the parent-hash of the block. + * If the `session index - APPROVAL_SESSIONS > state.earliest_session`, then bump `state.earliest_sessions` to that amount and prune earlier sessions. + * If the session isn't in our `state.session_info`, load the session info for it and for all sessions since the earliest-session, including the earliest-session, if that is missing. And it can be, just after pruning, if we've done a big jump forward, as is the case when we've just finished chain synchronization. + * If any of the runtime API calls fail, we just warn and skip the block. + * We use the `RuntimeApiSubsystem` to determine the set of candidates included in these blocks and use BABE logic to determine the slot number and VRF of the blocks. + * We also note how late we appear to have received the block. We create a `BlockEntry` for each block and a `CandidateEntry` for each candidate obtained from `CandidateIncluded` events after making a `RuntimeApiRequest::CandidateEvents` request. + * For each candidate, if the amount of needed approvals is more than the validators remaining after the backing group of the candidate is subtracted, then the candidate is insta-approved as approval would be impossible otherwise. If all candidates in the block are insta-approved, or there are no candidates in the block, then the block is insta-approved. If the block is insta-approved, a [`ChainSelectionMessage::Approved`][CSM] should be sent for the block. + * Ensure that the `CandidateEntry` contains a `block_assignments` entry for the block, with the correct backing group set. + * If a validator in this session, compute and assign `our_assignment` for the `block_assignments` + * Only if not a member of the backing group. + * Run `RelayVRFModulo` and `RelayVRFDelay` according to the [the approvals protocol section](../../protocol-approval.md#assignment-criteria). Ensure that the assigned core derived from the output is covered by the auxiliary signature aggregated in the `VRFPRoof`. + * [Handle Wakeup](#handle-wakeup) for each new candidate in each new block - this will automatically broadcast a 0-tranche assignment, kick off approval work, and schedule the next delay. + * Dispatch an `ApprovalDistributionMessage::NewBlocks` with the meta information filled out for each new block. + +#### `ApprovalVotingMessage::CheckAndImportAssignment` + +On receiving a `ApprovalVotingMessage::CheckAndImportAssignment` message, we check the assignment cert against the block entry. The cert itself contains information necessary to determine the candidate that is being assigned-to. In detail: + * Load the `BlockEntry` for the relay-parent referenced by the message. If there is none, return `AssignmentCheckResult::Bad`. + * Fetch the `SessionInfo` for the session of the block + * Determine the assignment key of the validator based on that. + * Determine the claimed core index by looking up the candidate with given index in `block_entry.candidates`. Return `AssignmentCheckResult::Bad` if missing. + * Check the assignment cert + * If the cert kind is `RelayVRFModulo`, then the certificate is valid as long as `sample < session_info.relay_vrf_samples` and the VRF is valid for the validator's key with the input `block_entry.relay_vrf_story ++ sample.encode()` as described with [the approvals protocol section](../../protocol-approval.md#assignment-criteria). We set `core_index = vrf.make_bytes().to_u32() % session_info.n_cores`. If the `BlockEntry` causes inclusion of a candidate at `core_index`, then this is a valid assignment for the candidate at `core_index` and has delay tranche 0. Otherwise, it can be ignored. + * If the cert kind is `RelayVRFDelay`, then we check if the VRF is valid for the validator's key with the input `block_entry.relay_vrf_story ++ cert.core_index.encode()` as described in [the approvals protocol section](../../protocol-approval.md#assignment-criteria). The cert can be ignored if the block did not cause inclusion of a candidate on that core index. Otherwise, this is a valid assignment for the included candidate. The delay tranche for the assignment is determined by reducing `(vrf.make_bytes().to_u64() % (session_info.n_delay_tranches + session_info.zeroth_delay_tranche_width)).saturating_sub(session_info.zeroth_delay_tranche_width)`. + * We also check that the core index derived by the output is covered by the `VRFProof` by means of an auxiliary signature. + * If the delay tranche is too far in the future, return `AssignmentCheckResult::TooFarInFuture`. + * Import the assignment. + * Load the candidate in question and access the `approval_entry` for the block hash the cert references. + * Ignore if we already observe the validator as having been assigned. + * Ensure the validator index is not part of the backing group for the candidate. + * Ensure the validator index is not present in the approval entry already. + * Create a tranche entry for the delay tranche in the approval entry and note the assignment within it. + * Note the candidate index within the approval entry. + * [Schedule a wakeup](#schedule-wakeup) for this block, candidate pair. + * return the appropriate `AssignmentCheckResult` on the response channel. + +#### `ApprovalVotingMessage::CheckAndImportApproval` + +On receiving a `CheckAndImportApproval(indirect_approval_vote, response_channel)` message: + * Fetch the `BlockEntry` from the indirect approval vote's `block_hash`. If none, return `ApprovalCheckResult::Bad`. + * Fetch the `CandidateEntry` from the indirect approval vote's `candidate_index`. If the block did not trigger inclusion of enough candidates, return `ApprovalCheckResult::Bad`. + * Construct a `SignedApprovalVote` using the candidate hash and check against the validator's approval key, based on the session info of the block. If invalid or no such validator, return `ApprovalCheckResult::Bad`. + * Send `ApprovalCheckResult::Accepted` + * [Import the checked approval vote](#import-checked-approval) + +#### `ApprovalVotingMessage::ApprovedAncestor` + +On receiving an `ApprovedAncestor(Hash, BlockNumber, response_channel)`: + * Iterate over the ancestry of the hash all the way back to block number given, starting from the provided block hash. Load the `CandidateHash`es from each block entry. + * Keep track of an `all_approved_max: Option<(Hash, BlockNumber, Vec<(Hash, Vec))>`. + * For each block hash encountered, load the `BlockEntry` associated. If any are not found, return `None` on the response channel and conclude. + * If the block entry's `approval_bitfield` has all bits set to 1 and `all_approved_max == None`, set `all_approved_max = Some((current_hash, current_number))`. + * If the block entry's `approval_bitfield` has any 0 bits, set `all_approved_max = None`. + * If `all_approved_max` is `Some`, push the current block hash and candidate hashes onto the list of blocks and candidates `all_approved_max`. + * After iterating all ancestry, return `all_approved_max`. + +### Updates and Auxiliary Logic + +#### Import Checked Approval + * Import an approval vote which we can assume to have passed signature checks and correspond to an imported assignment. + * Requires `(BlockEntry, CandidateEntry, ValidatorIndex)` + * Set the corresponding bit of the `approvals` bitfield in the `CandidateEntry` to `1`. If already `1`, return. + * Checks the approval state of a candidate under a specific block, and updates the block and candidate entries accordingly. + * Checks the `ApprovalEntry` for the block. + * [determine the tranches to inspect](#determine-required-tranches) of the candidate, + * [the candidate is approved under the block](#check-approval), set the corresponding bit in the `block_entry.approved_bitfield`. + * If the block is now fully approved and was not before, send a [`ChainSelectionMessage::Approved`][CSM]. + * Otherwise, [schedule a wakeup of the candidate](#schedule-wakeup) + * If the approval vote originates locally, set the `our_approval_sig` in the candidate entry. + +#### Handling Wakeup + * Handle a previously-scheduled wakeup of a candidate under a specific block. + * Requires `(relay_block, candidate_hash)` + * Load the `BlockEntry` and `CandidateEntry` from disk. If either is not present, this may have lost a race with finality and can be ignored. Also load the `ApprovalEntry` for the block and candidate. + * [determine the `RequiredTranches` of the candidate](#determine-required-tranches). + * Determine if we should trigger our assignment. + * If we've already triggered or `OurAssignment` is `None`, we do not trigger. + * If we have `RequiredTranches::All`, then we trigger if the candidate is [not approved](#check-approval). We have no next wakeup as we assume that other validators are doing the same and we will be implicitly woken up by handling new votes. + * If we have `RequiredTranches::Pending { considered, next_no_show, uncovered, maximum_broadcast, clock_drift }`, then we trigger if our assignment's tranche is less than or equal to `maximum_broadcast` and the current tick, with `clock_drift` applied, is at least the tick of our tranche. + * If we have `RequiredTranches::Exact { .. }` then we do not trigger, because this value indicates that no new assignments are needed at the moment. + * If we should trigger our assignment + * Import the assignment to the `ApprovalEntry` + * Broadcast on network with an `ApprovalDistributionMessage::DistributeAssignment`. + * [Launch approval work](#launch-approval-work) for the candidate. + * [Schedule a new wakeup](#schedule-wakeup) of the candidate. + +#### Schedule Wakeup + + * Requires `(approval_entry, candidate_entry)` which effectively denotes a `(Block Hash, Candidate Hash)` pair - the candidate, along with the block it appears in. + * Also requires `RequiredTranches` + * If the `approval_entry` is approved, this doesn't need to be woken up again. + * If `RequiredTranches::All` - no wakeup. We assume other incoming votes will trigger wakeup and potentially re-schedule. + * If `RequiredTranches::Pending { considered, next_no_show, uncovered, maximum_broadcast, clock_drift }` - schedule at the lesser of the next no-show tick, or the tick, offset positively by `clock_drift` of the next non-empty tranche we are aware of after `considered`, including any tranche containing our own unbroadcast assignment. This can lead to no wakeup in the case that we have already broadcast our assignment and there are no pending no-shows; that is, we have approval votes for every assignment we've received that is not already a no-show. In this case, we will be re-triggered by other validators broadcasting their assignments. + * If `RequiredTranches::Exact { next_no_show, latest_assignment_tick, .. }` - set a wakeup for the earlier of the next no-show tick or the latest assignment tick + `APPROVAL_DELAY`. + +#### Launch Approval Work + +* Requires `(SessionIndex, SessionInfo, CandidateReceipt, ValidatorIndex, backing_group, block_hash, candidate_index)` +* Extract the public key of the `ValidatorIndex` from the `SessionInfo` for the session. +* Issue an `AvailabilityRecoveryMessage::RecoverAvailableData(candidate, session_index, Some(backing_group), response_sender)` +* Load the historical validation code of the parachain by dispatching a `RuntimeApiRequest::ValidationCodeByHash(descriptor.validation_code_hash)` against the state of `block_hash`. +* Spawn a background task with a clone of `background_tx` + * Wait for the available data + * Issue a `CandidateValidationMessage::ValidateFromExhaustive` message with `APPROVAL_EXECUTION_TIMEOUT` as the timeout parameter. + * Wait for the result of validation + * Check that the result of validation, if valid, matches the commitments in the receipt. + * If valid, issue a message on `background_tx` detailing the request. + * If any of the data, the candidate, or the commitments are invalid, issue on `background_tx` a [`DisputeCoordinatorMessage::IssueLocalStatement`](../../types/overseer-protocol.md#dispute-coordinator-message) with `valid = false` to initiate a dispute. + +#### Issue Approval Vote + * Fetch the block entry and candidate entry. Ignore if `None` - we've probably just lost a race with finality. + * Construct a `SignedApprovalVote` with the validator index for the session. + * [Import the checked approval vote](#import-checked-approval). It is "checked" as we've just issued the signature. + * Construct a `IndirectSignedApprovalVote` using the information about the vote. + * Dispatch `ApprovalDistributionMessage::DistributeApproval`. + +### Determining Approval of Candidate + +#### Determine Required Tranches + +This logic is for inspecting an approval entry that tracks the assignments received, along with information on which assignments have corresponding approval votes. Inspection also involves the current time and expected requirements and is used to help the higher-level code determine the following: + * Whether to broadcast the local assignment + * Whether to check that the candidate entry has been completely approved. + * If the candidate is waiting on approval, when to schedule the next wakeup of the `(candidate, block)` pair at a point where the state machine could be advanced. + +These routines are pure functions which only depend on the environmental state. The expectation is that this determination is re-run every time we attempt to update an approval entry: either when we trigger a wakeup to advance the state machine based on a no-show or our own broadcast, or when we receive further assignments or approvals from the network. + +Thus it may be that at some point in time, we consider that tranches 0..X is required to be considered, but as we receive more information, we might require fewer tranches. Or votes that we perceived to be missing and require replacement are filled in and change our view. + +Requires `(approval_entry, approvals_received, tranche_now, block_tick, no_show_duration, needed_approvals)` + +```rust +enum RequiredTranches { + // All validators appear to be required, based on tranches already taken and remaining no-shows. + All, + // More tranches required - We're awaiting more assignments. + Pending { + /// The highest considered delay tranche when counting assignments. + considered: DelayTranche, + /// The tick at which the next no-show, of the assignments counted, would occur. + next_no_show: Option, + /// The highest tranche to consider when looking to broadcast own assignment. + /// This should be considered along with the clock drift to avoid broadcasting + /// assignments that are before the local time. + maximum_broadcast: DelayTranche, + /// The clock drift, in ticks, to apply to the local clock when determining whether + /// to broadcast an assignment or when to schedule a wakeup. The local clock should be treated + /// as though it is `clock_drift` ticks earlier. + clock_drift: Tick, + }, + // An exact number of required tranches and a number of no-shows. This indicates that the amount of `needed_approvals` are assigned and additionally all no-shows are covered. + Exact { + /// The tranche to inspect up to. + needed: DelayTranche, + /// The amount of missing votes that should be tolerated. + tolerated_missing: usize, + /// When the next no-show would be, if any. This is used to schedule the next wakeup in the + /// event that there are some assignments that don't have corresponding approval votes. If this + /// is `None`, all assignments have approvals. + next_no_show: Option, + /// The last tick at which a needed assignment was received. + last_assignment_tick: Option, + } +} +``` + +**Clock-drift and Tranche-taking** + +Our vote-counting procedure depends heavily on how we interpret time based on the presence of no-shows - assignments which have no corresponding approval after some time. + +We have this is because of how we handle no-shows: we keep track of the depth of no-shows we are covering. + +As an example: there may be initial no-shows in tranche 0. It'll take `no_show_duration` ticks before those are considered no-shows. Then, we don't want to immediately take `no_show_duration` more tranches. Instead, we want to take one tranche for each uncovered no-show. However, as we take those tranches, there may be further no-shows. Since these depth-1 no-shows should have only been triggered after the depth-0 no-shows were already known to be no-shows, we need to discount the local clock by `no_show_duration` to see whether these should be considered no-shows or not. There may be malicious parties who broadcast their assignment earlier than they were meant to, who shouldn't be counted as instant no-shows. We continue onwards to cover all depth-1 no-shows which may lead to depth-2 no-shows and so on. + +Likewise, when considering how many tranches to take, the no-show depth should be used to apply a depth-discount or clock drift to the `tranche_now`. + +**Procedure** + + * Start with `depth = 0`. + * Set a clock drift of `depth * no_show_duration` + * Take tranches up to `tranche_now - clock_drift` until all needed assignments are met. + * Keep track of the `next_no_show` according to the clock drift, as we go. + * Keep track of the `last_assignment_tick` as we go. + * If running out of tranches before then, return `Pending { considered, next_no_show, maximum_broadcast, clock_drift }` + * If there are no no-shows, return `Exact { needed, tolerated_missing, next_no_show, last_assignment_tick }` + * `maximum_broadcast` is either `DelayTranche::max_value()` at tranche 0 or otherwise by the last considered tranche + the number of uncovered no-shows at this point. + * If there are no-shows, return to the beginning, incrementing `depth` and attempting to cover the number of no-shows. Each no-show must be covered by a non-empty tranche, which are tranches that have at least one assignment. Each non-empty tranche covers exactly one no-show. + * If at any point, it seems that all validators are required, do an early return with `RequiredTranches::All` which indicates that everyone should broadcast. + +#### Check Approval + * Check whether a candidate is approved under a particular block. + * Requires `(block_entry, candidate_entry, approval_entry, n_tranches)` + * If we have `3 * n_approvals > n_validators`, return true. This is because any set with f+1 validators must have at least one honest validator, who has approved the candidate. + * If `n_tranches` is `RequiredTranches::Pending`, return false + * If `n_tranches` is `RequiredTranches::All`, return false. + * If `n_tranches` is `RequiredTranches::Exact { tranche, tolerated_missing, latest_assignment_tick, .. }`, then we return whether all assigned validators up to `tranche` less `tolerated_missing` have approved and `latest_assignment_tick + APPROVAL_DELAY >= tick_now`. + * e.g. if we had 5 tranches and 1 tolerated missing, we would accept only if all but 1 of assigned validators in tranches 0..=5 have approved. In that example, we also accept all validators in tranches 0..=5 having approved, but that would indicate that the `RequiredTranches` value was incorrectly constructed, so it is not realistic. `tolerated_missing` actually represents covered no-shows. If there are more missing approvals than there are tolerated missing, that indicates that there are some assignments which are not yet no-shows, but may become no-shows, and we should wait for the validators to either approve or become no-shows. + * e.g. If the above passes and the `latest_assignment_tick` was 5 and the current tick was 6, then we'd return false. + +### Time + +#### Current Tranche + * Given the slot number of a block, and the current time, this informs about the current tranche. + * Convert `time.saturating_sub(slot_number.to_time())` to a delay tranches value + +[CSM]: ../../types/overseer-protocol.md#chainselectionmessage diff --git a/polkadot/roadmap/implementers-guide/src/node/availability/README.md b/polkadot/roadmap/implementers-guide/src/node/availability/README.md new file mode 100644 index 0000000000000000000000000000000000000000..76bd6467e178917b396173be1d59aca32e5b3930 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/availability/README.md @@ -0,0 +1,3 @@ +# Availability Subsystems + +The availability subsystems are responsible for ensuring that Proofs of Validity of backed candidates are widely available within the validator set, without requiring every node to retain a full copy. They accomplish this by broadly distributing erasure-coded chunks of the PoV, keeping track of which validator has which chunk by means of signed bitfields. They are also responsible for reassembling a complete PoV when required, e.g. when an approval checker needs to validate a parachain block. diff --git a/polkadot/roadmap/implementers-guide/src/node/availability/availability-distribution.md b/polkadot/roadmap/implementers-guide/src/node/availability/availability-distribution.md new file mode 100644 index 0000000000000000000000000000000000000000..1760a2ee7df4ef44d33ce514f02c34a1620083f2 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/availability/availability-distribution.md @@ -0,0 +1,98 @@ +# Availability Distribution + +This subsystem is responsible for distribution availability data to peers. +Availability data are chunks, `PoV`s and `AvailableData` (which is `PoV` + +`PersistedValidationData`). It does so via request response protocols. + +In particular this subsystem is responsible for: + +- Respond to network requests requesting availability data by querying the + [Availability Store](../utility/availability-store.md). +- Request chunks from backing validators to put them in the local `Availability + Store` whenever we find an occupied core on any fresh leaf, + this is to ensure availability by at least 2/3+ of all validators, this + happens after a candidate is backed. +- Fetch `PoV` from validators, when requested via `FetchPoV` message from + backing (`pov_requester` module). + +The backing subsystem is responsible of making available data available in the +local `Availability Store` upon validation. This subsystem will serve any +network requests by querying that store. + +## Protocol + +This subsystem does not handle any peer set messages, but the `pov_requester` +does connect to validators of the same backing group on the validation peer +set, to ensure fast propagation of statements between those validators and for +ensuring already established connections for requesting `PoV`s. Other than that +this subsystem drives request/response protocols. + +Input: + +- `OverseerSignal::ActiveLeaves(ActiveLeavesUpdate)` +- `AvailabilityDistributionMessage{msg: ChunkFetchingRequest}` +- `AvailabilityDistributionMessage{msg: PoVFetchingRequest}` +- `AvailabilityDistributionMessage{msg: FetchPoV}` + +Output: + +- `NetworkBridgeMessage::SendRequests(Requests, IfDisconnected::TryConnect)` +- `AvailabilityStore::QueryChunk(candidate_hash, index, response_channel)` +- `AvailabilityStore::StoreChunk(candidate_hash, chunk)` +- `AvailabilityStore::QueryAvailableData(candidate_hash, response_channel)` +- `RuntimeApiRequest::SessionIndexForChild` +- `RuntimeApiRequest::SessionInfo` +- `RuntimeApiRequest::AvailabilityCores` + +## Functionality + +### PoV Requester + +The PoV requester in the `pov_requester` module takes care of staying connected +to validators of the current backing group of this very validator on the `Validation` +peer set and it will handle `FetchPoV` requests by issuing network requests to +those validators. It will check the hash of the received `PoV`, but will not do any +further validation. That needs to be done by the original `FetchPoV` sender +(backing subsystem). + +### Chunk Requester + +After a candidate is backed, the availability of the PoV block must be confirmed +by 2/3+ of all validators. The chunk requester is responsible of making that +availability a reality. + +It does that by querying checking occupied cores for all active leaves. For each +occupied core it will spawn a task fetching the erasure chunk which has the +`ValidatorIndex` of the node. For this an `ChunkFetchingRequest` is issued, via +substrate's generic request/response protocol. + +The spawned task will start trying to fetch the chunk from validators in +responsible group of the occupied core, in a random order. For ensuring that we +use already open TCP connections wherever possible, the requester maintains a +cache and preserves that random order for the entire session. + +Note however that, because not all validators in a group have to be actual +backers, not all of them are required to have the needed chunk. This in turn +could lead to low throughput, as we have to wait for fetches to fail, +before reaching a validator finally having our chunk. We do rank back validators +not delivering our chunk, but as backers could vary from block to block on a +perfectly legitimate basis, this is still not ideal. See issues [2509](https://github.com/paritytech/polkadot/issues/2509) and [2512](https://github.com/paritytech/polkadot/issues/2512) +for more information. + +The current implementation also only fetches chunks for occupied cores in blocks +in active leaves. This means though, if active leaves skips a block or we are +particularly slow in fetching our chunk, we might not fetch our chunk if +availability reached 2/3 fast enough (slot becomes free). This is not desirable +as we would like as many validators as possible to have their chunk. See this +[issue](https://github.com/paritytech/polkadot/issues/2513) for more details. + + +### Serving + +On the other side the subsystem will listen for incoming `ChunkFetchingRequest`s +and `PoVFetchingRequest`s from the network bridge and will respond to queries, +by looking the requested chunks and `PoV`s up in the availability store, this +happens in the `responder` module. + +We rely on the backing subsystem to make available data available locally in the +`Availability Store` after it has validated it. diff --git a/polkadot/roadmap/implementers-guide/src/node/availability/availability-recovery.md b/polkadot/roadmap/implementers-guide/src/node/availability/availability-recovery.md new file mode 100644 index 0000000000000000000000000000000000000000..48fb0fb1ca19da77a04fdec4dd8993bacceafef2 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/availability/availability-recovery.md @@ -0,0 +1,139 @@ +# Availability Recovery + +This subsystem is the inverse of the [Availability Distribution](availability-distribution.md) subsystem: validators will serve the availability chunks kept in the availability store to nodes who connect to them. And the subsystem will also implement the other side: the logic for nodes to connect to validators, request availability pieces, and reconstruct the `AvailableData`. + +This version of the availability recovery subsystem is based off of direct connections to validators. In order to recover any given `AvailableData`, we must recover at least `f + 1` pieces from validators of the session. Thus, we will connect to and query randomly chosen validators until we have received `f + 1` pieces. + +## Protocol + +`PeerSet`: `Validation` + +Input: + +- `NetworkBridgeUpdate(update)` +- `AvailabilityRecoveryMessage::RecoverAvailableData(candidate, session, backing_group, response)` + +Output: + +- `NetworkBridge::SendValidationMessage` +- `NetworkBridge::ReportPeer` +- `AvailabilityStore::QueryChunk` + +## Functionality + +We hold a state which tracks the currently ongoing recovery tasks, as well as which request IDs correspond to which task. A recovery task is a structure encapsulating all recovery tasks with the network necessary to recover the available data in respect to one candidate. + +```rust +struct State { + /// Each recovery is implemented as an independent async task, and the handles only supply information about the result. + ongoing_recoveries: FuturesUnordered, + /// A recent block hash for which state should be available. + live_block_hash: Hash, + // An LRU cache of recently recovered data. + availability_lru: LruCache>, +} + +/// This is a future, which concludes either when a response is received from the recovery tasks, +/// or all the `awaiting` channels have closed. +struct RecoveryHandle { + candidate_hash: CandidateHash, + interaction_response: RemoteHandle, + awaiting: Vec>>, +} + +struct Unavailable; +struct Concluded(CandidateHash, Result); + +struct RecoveryTaskParams { + validator_authority_keys: Vec, + validators: Vec, + // The number of pieces needed. + threshold: usize, + candidate_hash: Hash, + erasure_root: Hash, +} + +enum RecoveryTask { + RequestFromBackers { + // a random shuffling of the validators from the backing group which indicates the order + // in which we connect to them and request the chunk. + shuffled_backers: Vec, + } + RequestChunksFromValidators { + // a random shuffling of the validators which indicates the order in which we connect to the validators and + // request the chunk from them. + shuffling: Vec, + received_chunks: Map, + requesting_chunks: FuturesUnordered>, + } +} + +struct RecoveryTask { + to_subsystems: SubsystemSender, + params: RecoveryTaskParams, + source: Source, +} +``` + +### Signal Handling + +On `ActiveLeavesUpdate`, if `activated` is non-empty, set `state.live_block_hash` to the first block in `Activated`. + +Ignore `BlockFinalized` signals. + +On `Conclude`, shut down the subsystem. + +#### `AvailabilityRecoveryMessage::RecoverAvailableData(receipt, session, Option, response)` + +1. Check the `availability_lru` for the candidate and return the data if so. +1. Check if there is already an recovery handle for the request. If so, add the response handle to it. +1. Otherwise, load the session info for the given session under the state of `live_block_hash`, and initiate a recovery task with *`launch_recovery_task`*. Add a recovery handle to the state and add the response channel to it. +1. If the session info is not available, return `RecoveryError::Unavailable` on the response channel. + +### Recovery logic + +#### `launch_recovery_task(session_index, session_info, candidate_receipt, candidate_hash, Option)` + +1. Compute the threshold from the session info. It should be `f + 1`, where `n = 3f + k`, where `k in {1, 2, 3}`, and `n` is the number of validators. +1. Set the various fields of `RecoveryParams` based on the validator lists in `session_info` and information about the candidate. +1. If the `backing_group_index` is `Some`, start in the `RequestFromBackers` phase with a shuffling of the backing group validator indices and a `None` requesting value. +1. Otherwise, start in the `RequestChunksFromValidators` source with `received_chunks`,`requesting_chunks`, and `next_shuffling` all empty. +1. Set the `to_subsystems` sender to be equal to a clone of the `SubsystemContext`'s sender. +1. Initialize `received_chunks` to an empty set, as well as `requesting_chunks`. + +Launch the source as a background task running `run(recovery_task)`. + +#### `run(recovery_task) -> Result` + +```rust +// How many parallel requests to have going at once. +const N_PARALLEL: usize = 50; +``` + +* Request `AvailabilityStoreMessage::QueryAvailableData`. If it exists, return that. +* If the task contains `RequestFromBackers` + * Loop: + * If the `requesting_pov` is `Some`, poll for updates on it. If it concludes, set `requesting_pov` to `None`. + * If the `requesting_pov` is `None`, take the next backer off the `shuffled_backers`. + * If the backer is `Some`, issue a `NetworkBridgeMessage::Requests` with a network request for the `AvailableData` and wait for the response. + * If it concludes with a `None` result, return to beginning. + * If it concludes with available data, attempt a re-encoding. + * If it has the correct erasure-root, break and issue a `Ok(available_data)`. + * If it has an incorrect erasure-root, return to beginning. + * Send the result to each member of `awaiting`. + * If the backer is `None`, set the source to `RequestChunksFromValidators` with a random shuffling of validators and empty `received_chunks`, and `requesting_chunks` and break the loop. + +* If the task contains `RequestChunksFromValidators`: + * Request `AvailabilityStoreMessage::QueryAllChunks`. For each chunk that exists, add it to `received_chunks` and remote the validator from `shuffling`. + * Loop: + * If `received_chunks + requesting_chunks + shuffling` lengths are less than the threshold, break and return `Err(Unavailable)`. + * Poll for new updates from `requesting_chunks`. Check merkle proofs of any received chunks. If the request simply fails due to network issues, insert into the front of `shuffling` to be retried. + * If `received_chunks` has more than `threshold` entries, attempt to recover the data. + * If that fails, return `Err(RecoveryError::Invalid)` + * If correct: + * If re-encoding produces an incorrect erasure-root, break and issue a `Err(RecoveryError::Invalid)`. + * break and issue `Ok(available_data)` + * Send the result to each member of `awaiting`. + * While there are fewer than `N_PARALLEL` entries in `requesting_chunks`, + * Pop the next item from `shuffling`. If it's empty and `requesting_chunks` is empty, return `Err(RecoveryError::Unavailable)`. + * Issue a `NetworkBridgeMessage::Requests` and wait for the response in `requesting_chunks`. diff --git a/polkadot/roadmap/implementers-guide/src/node/availability/bitfield-distribution.md b/polkadot/roadmap/implementers-guide/src/node/availability/bitfield-distribution.md new file mode 100644 index 0000000000000000000000000000000000000000..53bd8a1bced61f5783bfeee937786c9b4741d80e --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/availability/bitfield-distribution.md @@ -0,0 +1,34 @@ +# Bitfield Distribution + +Validators vote on the availability of a backed candidate by issuing signed bitfields, where each bit corresponds to a single candidate. These bitfields can be used to compactly determine which backed candidates are available or not based on a 2/3+ quorum. + +## Protocol + +`PeerSet`: `Validation` + +Input: +[`BitfieldDistributionMessage`](../../types/overseer-protocol.md#bitfield-distribution-message) which are gossiped to all peers, no matter if validator or not. + +Output: + +- `NetworkBridge::SendValidationMessage([PeerId], message)` gossip a verified incoming bitfield on to interested subsystems within this validator node. +- `NetworkBridge::ReportPeer(PeerId, cost_or_benefit)` improve or penalize the reputation of peers based on the messages that are received relative to the current view. +- `ProvisionerMessage::ProvisionableData(ProvisionableData::Bitfield(relay_parent, SignedAvailabilityBitfield))` pass + on the bitfield to the other submodules via the overseer. + +## Functionality + +This is implemented as a gossip system. + +It is necessary to track peer connection, view change, and disconnection events, in order to maintain an index of which peers are interested in which relay parent bitfields. + + +Before gossiping incoming bitfields, they must be checked to be signed by one of the validators +of the validator set relevant to the current relay parent. +Only accept bitfields relevant to our current view and only distribute bitfields to other peers when relevant to their most recent view. +Accept and distribute only one bitfield per validator. + + +When receiving a bitfield either from the network or from a `DistributeBitfield` message, forward it along to the block authorship (provisioning) subsystem for potential inclusion in a block. + +Peers connecting after a set of valid bitfield gossip messages was received, those messages must be cached and sent upon connection of new peers or re-connecting peers. diff --git a/polkadot/roadmap/implementers-guide/src/node/availability/bitfield-signing.md b/polkadot/roadmap/implementers-guide/src/node/availability/bitfield-signing.md new file mode 100644 index 0000000000000000000000000000000000000000..08cbe528473ea4fd7099cedf15b58a6995a07226 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/availability/bitfield-signing.md @@ -0,0 +1,29 @@ +# Bitfield Signing + +Validators vote on the availability of a backed candidate by issuing signed bitfields, where each bit corresponds to a single candidate. These bitfields can be used to compactly determine which backed candidates are available or not based on a 2/3+ quorum. + +## Protocol + +Input: + +There is no dedicated input mechanism for bitfield signing. Instead, Bitfield Signing produces a bitfield representing the current state of availability on `StartWork`. + +Output: + +- `BitfieldDistribution::DistributeBitfield`: distribute a locally signed bitfield +- `AvailabilityStore::QueryChunk(CandidateHash, validator_index, response_channel)` + +## Functionality + +Upon receipt of an `ActiveLeavesUpdate`, launch bitfield signing job for each `activated` head referring to a fresh leaf. Stop the job for each `deactivated` head. + +## Bitfield Signing Job + +Localized to a specific relay-parent `r` +If not running as a validator, do nothing. + +- For each fresh leaf, begin by waiting a fixed period of time so availability distribution has the chance to make candidates available. +- Determine our validator index `i`, the set of backed candidates pending availability in `r`, and which bit of the bitfield each corresponds to. +- Start with an empty bitfield. For each bit in the bitfield, if there is a candidate pending availability, query the [Availability Store](../utility/availability-store.md) for whether we have the availability chunk for our validator index. The `OccupiedCore` struct contains the candidate hash so the full candidate does not need to be fetched from runtime. +- For all chunks we have, set the corresponding bit in the bitfield. +- Sign the bitfield and dispatch a `BitfieldDistribution::DistributeBitfield` message. diff --git a/polkadot/roadmap/implementers-guide/src/node/backing/README.md b/polkadot/roadmap/implementers-guide/src/node/backing/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ac47abefb0d043e3daaf6d2c3ba9a7e19c3b9413 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/backing/README.md @@ -0,0 +1,10 @@ +# Backing Subsystems + +The backing subsystems, when conceived as a black box, receive an arbitrary quantity of parablock candidates and associated proofs of validity from arbitrary untrusted collators. From these, they produce a bounded quantity of backable candidates which relay chain block authors may choose to include in a subsequent block. + +In broad strokes, the flow operates like this: + +- **Candidate Selection** winnows the field of parablock candidates, selecting up to one of them to second. +- **Candidate Backing** ensures that a seconding candidate is valid, then generates the appropriate `Statement`. It also keeps track of which candidates have received the backing of a quorum of other validators. +- **Statement Distribution** is the networking component which ensures that all validators receive each others' statements. +- **PoV Distribution** is the networking component which ensures that validators considering a candidate can get the appropriate PoV. diff --git a/polkadot/roadmap/implementers-guide/src/node/backing/candidate-backing.md b/polkadot/roadmap/implementers-guide/src/node/backing/candidate-backing.md new file mode 100644 index 0000000000000000000000000000000000000000..0eee0cc532ef17c922e03e0b2fb299313702ffb3 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/backing/candidate-backing.md @@ -0,0 +1,151 @@ +# Candidate Backing + +The Candidate Backing subsystem ensures every parablock considered for relay block inclusion has been seconded by at least one validator, and approved by a quorum. Parablocks for which not enough validators will assert correctness are discarded. If the block later proves invalid, the initial backers are slashable; this gives polkadot a rational threat model during subsequent stages. + +Its role is to produce backable candidates for inclusion in new relay-chain blocks. It does so by issuing signed [`Statement`s][Statement] and tracking received statements signed by other validators. Once enough statements are received, they can be combined into backing for specific candidates. + +Note that though the candidate backing subsystem attempts to produce as many backable candidates as possible, it does _not_ attempt to choose a single authoritative one. The choice of which actually gets included is ultimately up to the block author, by whatever metrics it may use; those are opaque to this subsystem. + +Once a sufficient quorum has agreed that a candidate is valid, this subsystem notifies the [Provisioner][PV], which in turn engages block production mechanisms to include the parablock. + +## Protocol + +Input: [`CandidateBackingMessage`][CBM] + +Output: + +- [`CandidateValidationMessage`][CVM] +- [`RuntimeApiMessage`][RAM] +- [`CollatorProtocolMessage`][CPM] +- [`ProvisionerMessage`][PM] +- [`AvailabilityDistributionMessage`][ADM] +- [`StatementDistributionMessage`][SDM] + +## Functionality + +The [Collator Protocol][CP] subsystem is the primary source of non-overseer messages into this subsystem. That subsystem generates appropriate [`CandidateBackingMessage`s][CBM] and passes them to this subsystem. + +This subsystem requests validation from the [Candidate Validation][CV] and generates an appropriate [`Statement`][Statement]. All `Statement`s are then passed on to the [Statement Distribution][SD] subsystem to be gossiped to peers. When [Candidate Validation][CV] decides that a candidate is invalid, and it was recommended to us to second by our own [Collator Protocol][CP] subsystem, a message is sent to the [Collator Protocol][CP] subsystem with the candidate's hash so that the collator which recommended it can be penalized. + +The subsystem should maintain a set of handles to Candidate Backing Jobs that are currently live, as well as the relay-parent to which they correspond. + +### On Overseer Signal + +* If the signal is an [`OverseerSignal`][OverseerSignal]`::ActiveLeavesUpdate`: + * spawn a Candidate Backing Job for each `activated` head referring to a fresh leaf, storing a bidirectional channel with the Candidate Backing Job in the set of handles. + * cease the Candidate Backing Job for each `deactivated` head, if any. +* If the signal is an [`OverseerSignal`][OverseerSignal]`::Conclude`: Forward conclude messages to all jobs, wait a small amount of time for them to join, and then exit. + +### On Receiving `CandidateBackingMessage` + +* If the message is a [`CandidateBackingMessage`][CBM]`::GetBackedCandidates`, get all backable candidates from the statement table and send them back. +* If the message is a [`CandidateBackingMessage`][CBM]`::Second`, sign and dispatch a `Seconded` statement only if we have not seconded any other candidate and have not signed a `Valid` statement for the requested candidate. Signing both a `Seconded` and `Valid` message is a double-voting misbehavior with a heavy penalty, and this could occur if another validator has seconded the same candidate and we've received their message before the internal seconding request. +* If the message is a [`CandidateBackingMessage`][CBM]`::Statement`, count the statement to the quorum. If the statement in the message is `Seconded` and it contains a candidate that belongs to our assignment, request the corresponding `PoV` from the backing node via `AvailabilityDistribution` and launch validation. Issue our own `Valid` or `Invalid` statement as a result. + +If the seconding node did not provide us with the `PoV` we will retry fetching from other backing validators. + + +> big TODO: "contextual execution" +> +> * At the moment we only allow inclusion of _new_ parachain candidates validated by _current_ validators. +> * Allow inclusion of _old_ parachain candidates validated by _current_ validators. +> * Allow inclusion of _old_ parachain candidates validated by _old_ validators. +> +> This will probably blur the lines between jobs, will probably require inter-job communication and a short-term memory of recently backable, but not backed candidates. + +## Candidate Backing Job + +The Candidate Backing Job represents the work a node does for backing candidates with respect to a particular relay-parent. + +The goal of a Candidate Backing Job is to produce as many backable candidates as possible. This is done via signed [`Statement`s][STMT] by validators. If a candidate receives a majority of supporting Statements from the Parachain Validators currently assigned, then that candidate is considered backable. + +### On Startup + +* Fetch current validator set, validator -> parachain assignments from [`Runtime API`][RA] subsystem using [`RuntimeApiRequest::Validators`][RAM] and [`RuntimeApiRequest::ValidatorGroups`][RAM] +* Determine if the node controls a key in the current validator set. Call this the local key if so. +* If the local key exists, extract the parachain head and validation function from the [`Runtime API`][RA] for the parachain the local key is assigned to by issuing a [`RuntimeApiRequest::Validators`][RAM] +* Issue a [`RuntimeApiRequest::SigningContext`][RAM] message to get a context that will later be used upon signing. + +### On Receiving New Candidate Backing Message + +```rust +match msg { + GetBackedCandidates(hashes, tx) => { + // Send back a set of backable candidates. + } + CandidateBackingMessage::Second(hash, candidate) => { + if candidate is unknown and in local assignment { + if spawn_validation_work(candidate, parachain head, validation function).await == Valid { + send(DistributePoV(pov)) + } + } + } + CandidateBackingMessage::Statement(hash, statement) => { + // count to the votes on this candidate + if let Statement::Seconded(candidate) = statement { + if candidate.parachain_id == our_assignment { + spawn_validation_work(candidate, parachain head, validation function) + } + } + } +} +``` + +Add `Seconded` statements and `Valid` statements to a quorum. If the quorum reaches a pre-defined threshold, send a [`ProvisionerMessage`][PM]`::ProvisionableData(ProvisionableData::BackedCandidate(CandidateReceipt))` message. +`Invalid` statements that conflict with already witnessed `Seconded` and `Valid` statements for the given candidate, statements that are double-votes, self-contradictions and so on, should result in issuing a [`ProvisionerMessage`][PM]`::MisbehaviorReport` message for each newly detected case of this kind. + +Backing does not need to concern itself with providing statements to the dispute +coordinator as the dispute coordinator scrapes them from chain. This way the +import is batched and contains only statements that actually made it on some +chain. + +### Validating Candidates. + +```rust +fn spawn_validation_work(candidate, parachain head, validation function) { + asynchronously { + let pov = (fetch pov block).await + + let valid = (validate pov block).await; + if valid { + // make PoV available for later distribution. Send data to the availability store to keep. + // sign and dispatch `valid` statement to network if we have not seconded the given candidate. + } else { + // sign and dispatch `invalid` statement to network. + } + } +} +``` + +### Fetch PoV Block + +Create a `(sender, receiver)` pair. +Dispatch a [`AvailabilityDistributionMessage`][ADM]`::FetchPoV{ validator_index, pov_hash, candidate_hash, tx, } and listen on the passed receiver for a response. Availability distribution will send the request to the validator specified by `validator_index`, which might not be serving it for whatever reasons, therefore we need to retry with other backing validators in that case. + + +### Validate PoV Block + +Create a `(sender, receiver)` pair. +Dispatch a `CandidateValidationMessage::Validate(validation function, candidate, pov, BACKING_EXECUTION_TIMEOUT, sender)` and listen on the receiver for a response. + +### Distribute Signed Statement + +Dispatch a [`StatementDistributionMessage`][SDM]`::Share(relay_parent, SignedFullStatementWithPVD)`. + +[OverseerSignal]: ../../types/overseer-protocol.md#overseer-signal +[Statement]: ../../types/backing.md#statement-type +[STMT]: ../../types/backing.md#statement-type +[CPM]: ../../types/overseer-protocol.md#collator-protocol-message +[RAM]: ../../types/overseer-protocol.md#runtime-api-message +[CVM]: ../../types/overseer-protocol.md#validation-request-type +[PM]: ../../types/overseer-protocol.md#provisioner-message +[CBM]: ../../types/overseer-protocol.md#candidate-backing-message +[ADM]: ../../types/overseer-protocol.md#availability-distribution-message +[SDM]: ../../types/overseer-protocol.md#statement-distribution-message +[DCM]: ../../types/overseer-protocol.md#dispute-coordinator-message + +[CP]: ../collators/collator-protocol.md +[CV]: ../utility/candidate-validation.md +[SD]: statement-distribution.md +[RA]: ../utility/runtime-api.md +[PV]: ../utility/provisioner.md diff --git a/polkadot/roadmap/implementers-guide/src/node/backing/pov-distribution.md b/polkadot/roadmap/implementers-guide/src/node/backing/pov-distribution.md new file mode 100644 index 0000000000000000000000000000000000000000..f2dffa8d0cc01756c9a7016b62b505a1bbf86b2a --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/backing/pov-distribution.md @@ -0,0 +1 @@ +# PoV Distribution diff --git a/polkadot/roadmap/implementers-guide/src/node/backing/prospective-parachains.md b/polkadot/roadmap/implementers-guide/src/node/backing/prospective-parachains.md new file mode 100644 index 0000000000000000000000000000000000000000..a48444a46e402b6c30e2280f3923db50943ef2ce --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/backing/prospective-parachains.md @@ -0,0 +1,158 @@ +# Prospective Parachains + +## Overview + +**Purpose:** Tracks and handles prospective parachain fragments and informs +other backing-stage subsystems of work to be done. + +"prospective": +- [*prə'spɛktɪv*] adj. +- future, likely, potential + +Asynchronous backing changes the runtime to accept parachain candidates from a +certain allowed range of historic relay-parents. This means we can now build +*prospective parachains* – that is, trees of potential (but likely) future +parachain blocks. This is the subsystem responsible for doing so. + +Other subsystems such as Backing rely on Prospective Parachains, e.g. for +determining if a candidate can be seconded. This subsystem is the main +coordinator of work within the node for the collation and backing phases of +parachain consensus. + +Prospective Parachains is primarily an implementation of fragment trees. It also +handles concerns such as: + +- the relay-chain being forkful +- session changes + +See the following sections for more details. + +### Fragment Trees + +This subsystem builds up fragment trees, which are trees of prospective para +candidates. Each path through the tree represents a possible state transition +path for the para. Each potential candidate is a fragment, or a node, in the +tree. Candidates are validated against constraints as they are added. + +This subsystem builds up trees for each relay-chain block in the view, for each +para. These fragment trees are used for: + +- providing backable candidates to other subsystems +- sanity-checking that candidates can be seconded +- getting seconded candidates under active leaves +- etc. + +For example, here is a tree with several possible paths: + +``` +Para Head registered by the relay chain: included_head + ↲ ↳ +depth 0: head_0_a head_0_b + ↲ ↳ +depth 1: head_1_a head_1_b + ↲ | ↳ +depth 2: head_2_a1 head_2_a2 head_2_a3 +``` + +### The Relay-Chain Being Forkful + +We account for the same candidate possibly appearing in different forks. While +we still build fragment trees for each head in each fork, we are efficient with +how we reference candidates to save space. + +### Session Changes + +Allowed ancestry doesn't cross session boundary. That is, you can only build on +top of the freshest relay parent when the session starts. This is a current +limitation that may be lifted in the future. + +Also, runtime configuration values needed for constraints (such as +`max_pov_size`) are constant within a session. This is important when building +prospective validation data. This is unlikely to change. + +## Messages + +### Incoming + +- `ActiveLeaves` + - Notification of a change in the set of active leaves. + - Constructs fragment trees for each para for each new leaf. +- `ProspectiveParachainsMessage::IntroduceCandidate` + - Informs the subsystem of a new candidate. + - Sent by the Backing Subsystem when it is importing a statement for a + new candidate. +- `ProspectiveParachainsMessage::CandidateSeconded` + - Informs the subsystem that a previously introduced candidate has + been seconded. + - Sent by the Backing Subsystem when it is importing a statement for a + new candidate after it sends `IntroduceCandidate`, if that wasn't + rejected by Prospective Parachains. +- `ProspectiveParachainsMessage::CandidateBacked` + - Informs the subsystem that a previously introduced candidate has + been backed. + - Sent by the Backing Subsystem after it successfully imports a + statement giving a candidate the necessary quorum of backing votes. +- `ProspectiveParachainsMessage::GetBackableCandidate` + - Get a backable candidate hash along with its relay parent for a given parachain, + under a given relay-parent (leaf) hash, which is a descendant of given candidate hashes. + - Sent by the Provisioner when requesting backable candidates, when + selecting candidates for a given relay-parent. +- `ProspectiveParachainsMessage::GetHypotheticalFrontier` + - Gets the hypothetical frontier membership of candidates with the + given properties under the specified active leaves' fragment trees. + - Sent by the Backing Subsystem when sanity-checking whether a candidate can + be seconded based on its hypothetical frontiers. +- `ProspectiveParachainsMessage::GetTreeMembership` + - Gets the membership of the candidate in all fragment trees. + - Sent by the Backing Subsystem when it needs to update the candidates + seconded at various depths under new active leaves. +- `ProspectiveParachainsMessage::GetMinimumRelayParents` + - Gets the minimum accepted relay-parent number for each para in the + fragment tree for the given relay-chain block hash. + - That is, this returns the minimum relay-parent block number in the + same branch of the relay-chain which is accepted in the fragment + tree for each para-id. + - Sent by the Backing, Statement Distribution, and Collator Protocol + subsystems when activating leaves in the implicit view. +- `ProspectiveParachainsMessage::GetProspectiveValidationData` + - Gets the validation data of some prospective candidate. The + candidate doesn't need to be part of any fragment tree. + - Sent by the Collator Protocol subsystem (validator side) when + handling a fetched collation result. + +### Outgoing + +- `RuntimeApiRequest::StagingParaBackingState` + - Gets the backing state of the given para (the constraints of the para and + candidates pending availability). +- `RuntimeApiRequest::AvailabilityCores` + - Gets information on all availability cores. +- `ChainApiMessage::Ancestors` + - Requests the `k` ancestor block hashes of a block with the given + hash. +- `ChainApiMessage::BlockHeader` + - Requests the block header by hash. + +## Glossary + +- **Candidate storage:** Stores candidates and information about them + such as their relay-parents and their backing states. Is indexed in + various ways. +- **Constraints:** + - Constraints on the actions that can be taken by a new parachain + block. + - Exhaustively define the set of valid inputs and outputs to parachain + execution. +- **Fragment:** A prospective para block (that is, a block not yet referenced by + the relay-chain). Fragments are anchored to the relay-chain at a particular + relay-parent. +- **Fragment tree:** + - A tree of fragments. Together, these fragments define one or more + prospective paths a parachain's state may transition through. + - See the "Fragment Tree" section. +- **Inclusion emulation:** Emulation of the logic that the runtime uses + for checking parachain blocks. +- **Relay-parent:** A particular relay-chain block that a fragment is + anchored to. +- **Scope:** The scope of a fragment tree, defining limits on nodes + within the tree. diff --git a/polkadot/roadmap/implementers-guide/src/node/backing/statement-distribution-legacy.md b/polkadot/roadmap/implementers-guide/src/node/backing/statement-distribution-legacy.md new file mode 100644 index 0000000000000000000000000000000000000000..5cbc875d8a733ebd224056b1658570c345b9b7b7 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/backing/statement-distribution-legacy.md @@ -0,0 +1,119 @@ +# Statement Distribution (Legacy) + +This describes the legacy, backwards-compatible version of the Statement +Distribution subsystem. + +**Note:** All the V1 (legacy) code was extracted out to a `legacy_v1` module of +the `statement-distribution` crate, which doesn't alter any logic. V2 (new +protocol) peers also run `legacy_v1` and communicate with V1 peers using V1 +messages and with V2 peers using V2 messages. Once the runtime upgrade goes +through on all networks, this `legacy_v1` code will no longer be triggered and +will be vestigial and can be removed. + +## Overview + +The Statement Distribution Subsystem is responsible for distributing statements about seconded candidates between validators. + +## Protocol + +`PeerSet`: `Validation` + +Input: + +- `NetworkBridgeUpdate(update)` +- `StatementDistributionMessage` + +Output: + +- `NetworkBridge::SendMessage(PeerId, message)` +- `NetworkBridge::SendRequests(StatementFetchingV1)` +- `NetworkBridge::ReportPeer(PeerId, cost_or_benefit)` + +## Functionality + +Implemented as a gossip protocol. Handles updates to our view and peers' views. Neighbor packets are used to inform peers which chain heads we are interested in data for. + +The Statement Distribution Subsystem is responsible for distributing signed statements that we have generated and for forwarding statements generated by other validators. It also detects a variety of Validator misbehaviors for reporting to the [Provisioner Subsystem](../utility/provisioner.md). During the Backing stage of the inclusion pipeline, Statement Distribution is the main point of contact with peer nodes. On receiving a signed statement from a peer in the same backing group, assuming the peer receipt state machine is in an appropriate state, it sends the Candidate Receipt to the [Candidate Backing subsystem](candidate-backing.md) to handle the validator's statement. On receiving `StatementDistributionMessage::Share` we make sure to send messages to our backing group in addition to random other peers, to ensure a fast backing process and getting all statements quickly for distribution. + +This subsystem tracks equivocating validators and stops accepting information from them. It establishes a data-dependency order: + +- In order to receive a `Seconded` message we have the corresponding chain head in our view +- In order to receive a `Valid` message we must have received the corresponding `Seconded` message. + +And respect this data-dependency order from our peers by respecting their views. This subsystem is responsible for checking message signatures. + +The Statement Distribution subsystem sends statements to peer nodes. + +## Peer Receipt State Machine + +There is a very simple state machine which governs which messages we are willing to receive from peers. Not depicted in the state machine: on initial receipt of any [`SignedFullStatement`](../../types/backing.md#signed-statement-type), validate that the provided signature does in fact sign the included data. Note that each individual parablock candidate gets its own instance of this state machine; it is perfectly legal to receive a `Valid(X)` before a `Seconded(Y)`, as long as a `Seconded(X)` has been received. + +A: Initial State. Receive `SignedFullStatement(Statement::Second)`: extract `Statement`, forward to Candidate Backing, proceed to B. Receive any other `SignedFullStatement` variant: drop it. + +B: Receive any `SignedFullStatement`: check signature and determine whether the statement is new to us. if new, forward to Candidate Backing and circulate to other peers. Receive `OverseerMessage::StopWork`: proceed to C. + +C: Receive any message for this block: drop it. + +For large statements (see below), we also keep track of the total received large +statements per peer and have a hard limit on that number for flood protection. +This is necessary as in the current code we only forward statements once we have +all the data, therefore flood protection for large statement is a bit more +subtle. This will become an obsolete problem once [off chain code +upgrades](https://github.com/paritytech/polkadot/issues/2979) are implemented. + +## Peer Knowledge Tracking + +The peer receipt state machine implies that for parsimony of network resources, we should model the knowledge of our peers, and help them out. For example, let's consider a case with peers A, B, and C, validators X and Y, and candidate M. A sends us a `Statement::Second(M)` signed by X. We've double-checked it, and it's valid. While we're checking it, we receive a copy of X's `Statement::Second(M)` from `B`, along with a `Statement::Valid(M)` signed by Y. + +Our response to A is just the `Statement::Valid(M)` signed by Y. However, we haven't heard anything about this from C. Therefore, we send it everything we have: first a copy of X's `Statement::Second`, then Y's `Statement::Valid`. + +This system implies a certain level of duplication of messages--we received X's `Statement::Second` from both our peers, and C may experience the same--but it minimizes the degree to which messages are simply dropped. + +And respect this data-dependency order from our peers. This subsystem is responsible for checking message signatures. + +No jobs. We follow view changes from the [`NetworkBridge`](../utility/network-bridge.md), which in turn is updated by the overseer. + +## Equivocations and Flood Protection + +An equivocation is a double-vote by a validator. The [Candidate Backing](candidate-backing.md) Subsystem is better-suited than this one to detect equivocations as it adds votes to quorum trackers. + +At this level, we are primarily concerned about flood-protection, and to some extent, detecting equivocations is a part of that. In particular, we are interested in detecting equivocations of `Seconded` statements. Since every other statement is dependent on `Seconded` statements, ensuring that we only ever hold a bounded number of `Seconded` statements is sufficient for flood-protection. + +The simple approach is to say that we only receive up to two `Seconded` statements per validator per chain head. However, the marginal cost of equivocation, conditional on having already equivocated, is close to 0, since a single double-vote offence is counted as all double-vote offences for a particular chain-head. Even if it were not, there is some amount of equivocations that can be done such that the marginal cost of issuing further equivocations is close to 0, as there would be an amount of equivocations necessary to be completely and totally obliterated by the slashing algorithm. We fear the validator with nothing left to lose. + +With that in mind, this simple approach has a caveat worth digging deeper into. + +First: We may be aware of two equivocated `Seconded` statements issued by a validator. A totally honest peer of ours can also be aware of one or two different `Seconded` statements issued by the same validator. And yet another peer may be aware of one or two _more_ `Seconded` statements. And so on. This interacts badly with pre-emptive sending logic. Upon sending a `Seconded` statement to a peer, we will want to pre-emptively follow up with all statements relative to that candidate. Waiting for acknowledgment introduces latency at every hop, so that is best avoided. What can happen is that upon receipt of the `Seconded` statement, the peer will discard it as it falls beyond the bound of 2 that it is allowed to store. It cannot store anything in memory about discarded candidates as that would introduce a DoS vector. Then, the peer would receive from us all of the statements pertaining to that candidate, which, from its perspective, would be undesired - they are data-dependent on the `Seconded` statement we sent them, but they have erased all record of that from their memory. Upon receiving a potential flood of undesired statements, this 100% honest peer may choose to disconnect from us. In this way, an adversary may be able to partition the network with careful distribution of equivocated `Seconded` statements. + +The fix is to track, per-peer, the hashes of up to 4 candidates per validator (per relay-parent) that the peer is aware of. It is 4 because we may send them 2 and they may send us 2 different ones. We track the data that they are aware of as the union of things we have sent them and things they have sent us. If we receive a 1st or 2nd `Seconded` statement from a peer, we note it in the peer's known candidates even if we do disregard the data locally. And then, upon receipt of any data dependent on that statement, we do not reduce that peer's standing in our eyes, as the data was not undesired. + +There is another caveat to the fix: we don't want to allow the peer to flood us because it has set things up in a way that it knows we will drop all of its traffic. +We also track how many statements we have received per peer, per candidate, and per chain-head. This is any statement concerning a particular candidate: `Seconded`, `Valid`, or `Invalid`. If we ever receive a statement from a peer which would push any of these counters beyond twice the amount of validators at the chain-head, we begin to lower the peer's standing and eventually disconnect. This bound is a massive overestimate and could be reduced to twice the number of validators in the corresponding validator group. It is worth noting that the goal at the time of writing is to ensure any finite bound on the amount of stored data, as any equivocation results in a large slash. + +## Large statements + +Seconded statements can become quite large on parachain runtime upgrades for +example. For this reason, there exists a `LargeStatement` constructor for the +`StatementDistributionMessage` wire message, which only contains light metadata +of a statement. The actual candidate data is not included. This message type is +used whenever a message is deemed large. The receiver of such a message needs to +request the actual payload via request/response by means of a +`StatementFetchingV1` request. + +This is necessary as distribution of a large payload (mega bytes) via gossip +would make the network collapse and timely distribution of statements would no +longer be possible. By using request/response it is ensured that each peer only +transferes large data once. We only take good care to detect an overloaded +peer early and immediately move on to a different peer for fetching the data. +This mechanism should result in a good load distribution and therefore a rather +optimal distribution path. + +With these optimizations, distribution of payloads in the size of up to 3 to 4 +MB should work with Kusama validator specifications. For scaling up even more, +runtime upgrades and message passing should be done off chain at some point. + +Flood protection considerations: For making DoS attacks slightly harder on this +subsystem, nodes will only respond to large statement requests, when they +previously notified that peer via gossip about that statement. So, it is not +possible to DoS nodes at scale, by requesting candidate data over and over +again. diff --git a/polkadot/roadmap/implementers-guide/src/node/backing/statement-distribution.md b/polkadot/roadmap/implementers-guide/src/node/backing/statement-distribution.md new file mode 100644 index 0000000000000000000000000000000000000000..2e014284821063075f08d2b624a387a9a4879a12 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/backing/statement-distribution.md @@ -0,0 +1,479 @@ +# Statement Distribution + +This subsystem is responsible for distributing signed statements that we have generated and forwarding statements generated by our peers. Received candidate receipts and statements are passed to the [Candidate Backing subsystem](candidate-backing.md) to handle producing local statements. On receiving `StatementDistributionMessage::Share`, this subsystem distributes the message across the network with redundency to ensure a fast backing process. + +## Overview + +**Goal:** every well-connected node is aware of every next potential parachain +block. + +Validators can either: + +- receive parachain block from collator, check block, and gossip statement. +- receive statements from other validators, check the parachain block if it + originated within their own group, gossip forward statement if valid. + +Validators must have statements, candidates, and persisted validation from all +other validators. This is because we need to store statements from validators +who've checked the candidate on the relay chain, so we know who to hold +accountable in case of disputes. Any validator can be selected as the next +relay-chain block author, and this is not revealed in advance for security +reasons. As a result, all validators must have a up to date view of all possible +parachain candidates + backing statements that could be placed on-chain in the +next block. + +[This blog post](https://polkadot.network/blog/polkadot-v1-0-sharding-and-economic-security) +puts it another way: "Validators who aren't assigned to the parachain still +listen for the attestations [statements] because whichever validator ends up +being the author of the relay-chain block needs to bundle up attested parachain +blocks for several parachains and place them into the relay-chain block." + +Backing-group quorum (that is, enough backing group votes) must be reached +before the block author will consider the candidate. Therefore, validators need +to consider _all_ seconded candidates within their own group, because that's +what they're assigned to work on. Validators only need to consider _backable_ +candidates from other groups. This informs the design of the statement +distribution protocol to have separate phases for in-group and out-group +distribution, respectively called "cluster" and "grid" mode (see below). + +### With Async Backing + +Asynchronous backing changes the runtime to accept parachain candidates from a +certain allowed range of historic relay-parents. These candidates must be backed +by the group assigned to the parachain as-of their corresponding relay parents. + +## Protocol + +To address the concern of dealing with large numbers of spam candidates or +statements, the overall design approach is to combine a focused "clustering" +protocol for legitimate fresh candidates with a broad-distribution "grid" +protocol to quickly get backed candidates into the hands of many validators. +Validators do not eagerly send each other heavy `CommittedCandidateReceipt`, +but instead request these lazily through request/response protocols. + +A high-level description of the protocol follows: + +### Messages + +Nodes can send each other a few kinds of messages: `Statement`, +`BackedCandidateManifest`, `BackedCandidateAcknowledgement`. + +- `Statement` messages contain only a signed compact statement, without full + candidate info. +- `BackedCandidateManifest` messages advertise a description of a backed + candidate and stored statements. +- `BackedCandidateAcknowledgement` messages acknowledge that a backed candidate + is fully known. + +### Request/response protocol + +Nodes can request the full `CommittedCandidateReceipt` and +`PersistedValidationData`, along with statements, over a request/response +protocol. This is the `AttestedCandidateRequest`; the response is +`AttestedCandidateResponse`. + +### Importability and the Hypothetical Frontier + +The **prospective parachains** subsystem maintains prospective "fragment trees" +which can be used to determine whether a particular parachain candidate could +possibly be included in the future. Candidates which either are within a +fragment tree or _would be_ part of a fragment tree if accepted are said to be +in the "hypothetical frontier". + +The **statement-distribution** subsystem keeps track of all candidates, and +updates its knowledge of the hypothetical frontier based on events such as new +relay parents, new confirmed candidates, and newly backed candidates. + +We only consider statements as "importable" when the corresponding candidate is +part of the hypothetical frontier, and only send "importable" statements to the +backing subsystem itself. + +### Cluster Mode + +- Validator nodes are partitioned into groups (with some exceptions), and + validators within a group at a relay-parent can send each other `Statement` + messages for any candidates within that group and based on that relay-parent. +- This is referred to as the "cluster" mode. + - Right now these are the same as backing groups, though "cluster" + specifically refers to the set of nodes communicating with each other in the + first phase of distribution. +- `Seconded` statements must be sent before `Valid` statements. +- `Seconded` statements may only be sent to other members of the group when the + candidate is fully known by the local validator. + - "Fully known" means the validator has the full `CommittedCandidateReceipt` + and `PersistedValidationData`, which it receives on request from other + validators or from a collator. + - The reason for this is that sending a statement (which is always a + `CompactStatement` carrying nothing but a hash and signature) to the + cluster, is also a signal that the sending node is available to request the + candidate from. + - This makes the protocol easier to reason about, while also reducing network + messages about candidates that don't really exist. +- Validators in a cluster receiving messages about unknown candidates request + the candidate (and statements) from other cluster members which have it. +- Spam considerations + - The maximum depth of candidates allowed in asynchronous backing determines + the maximum amount of `Seconded` statements originating from a validator V + which each validator in a cluster may send to others. This bounds the number + of candidates. + - There is a small number of validators in each group, which further limits + the amount of candidates. +- We accept candidates which don't fit in the fragment trees of any relay + parents. + - "Accept" means "attempt to request and store in memory until useful or + expired". + - We listen to prospective parachains subsystem to learn of new additions to + the fragment trees. + - Use this to attempt to import the candidate later. + +### Grid Mode + +- Every consensus session provides randomness and a fixed validator set, which + is used to build a redundant grid topology. + - It's redundant in the sense that there are 2 paths from every node to every + other node. See "Grid Topology" section for more details. +- This grid topology is used to create a sending path from each validator group + to every validator. +- When a node observes a candidate as backed, it sends a + `BackedCandidateManifest` to their "receiving" nodes. +- If receiving nodes don't yet know the candidate, they request it. +- Once they know the candidate, they respond with a + `BackedCandidateAcknowledgement`. +- Once two nodes perform a manifest/acknowledgement exchange, they can send + `Statement` messages directly to each other for any new statements they might + need. + - This limits the amount of statements we'd have to deal with w.r.t. + candidates that don't really exist. See "Manifest Exchange" section. +- There are limitations on the number of candidates that can be advertised by + each peer, similar to those in the cluster. Validators do not request + candidates which exceed these limitations. +- Validators request candidates as soon as they are advertised, but do not + import the statements until the candidate is part of the hypothetical + frontier, and do not re-advertise or acknowledge until the candidate is + considered both backable and part of the hypothetical frontier. +- Note that requesting is not an implicit acknowledgement, and an explicit + acknowledgement must be sent upon receipt. + +## Messages + +### Incoming + +- `ActiveLeaves` + - Notification of a change in the set of active leaves. +- `StatementDistributionMessage::Share` + - Notification of a locally-originating statement. That is, this statement + comes from our node and should be distributed to other nodes. + - Sent by the Backing Subsystem after it successfully imports a + locally-originating statement. +- `StatementDistributionMessage::Backed` + - Notification of a candidate being backed (received enough validity votes + from the backing group). + - Sent by the Backing Subsystem after it successfully imports a statement for + the first time and after sending ~Share~. +- `StatementDistributionMessage::NetworkBridgeUpdate` + - See next section. + +#### Network bridge events + +- v1 compatibility + - Messages for the v1 protocol are routed to the legacy statement + distribution. +- `Statement` + - Notification of a signed statement. + - Sent by a peer's Statement Distribution subsystem when circulating + statements. +- `BackedCandidateManifest` + - Notification of a backed candidate being known by the sending node. + - For the candidate being requested by the receiving node if needed. + - Announcement. + - Sent by a peer's Statement Distribution subsystem. +- `BackedCandidateKnown` + - Notification of a backed candidate being known by the sending node. + - For informing a receiving node which already has the candidate. + - Acknowledgement. + - Sent by a peer's Statement Distribution subsystem. + +### Outgoing + +- `NetworkBridgeTxMessage::SendValidationMessages` + - Sends a peer all pending messages / acknowledgements / statements for a + relay parent, either through the cluster or the grid. +- `NetworkBridgeTxMessage::SendValidationMessage` + - Circulates a compact statement to all peers who need it, either through the + cluster or the grid. +- `NetworkBridgeTxMessage::ReportPeer` + - Reports a peer (either good or bad). +- `CandidateBackingMessage::Statement` + - Note a validator's statement about a particular candidate. +- `ProspectiveParachainsMessage::GetHypotheticalFrontier` + - Gets the hypothetical frontier membership of candidates under active leaves' + fragment trees. +- `NetworkBridgeTxMessage::SendRequests` + - Sends requests, initiating the request/response protocol. + +## Request/Response + +We also have a request/response protocol because validators do not eagerly send +each other heavy `CommittedCandidateReceipt`, but instead need to request these +lazily. + +### Protocol + +1. Requesting Validator + + - Requests are queued up with `RequestManager::get_or_insert`. + - Done as needed, when handling incoming manifests/statements. + - `RequestManager::dispatch_requests` sends any queued-up requests. + - Calls `RequestManager::next_request` to completion. + - Creates the `OutgoingRequest`, saves the receiver in + `RequestManager::pending_responses`. + - Does nothing if we have more responses pending than the limit of parallel + requests. + +2. Peer + + - Requests come in on a peer on the `IncomingRequestReceiver`. + - Runs in a background responder task which feeds requests to `answer_request` + through `MuxedMessage`. + - This responder task has a limit on the number of parallel requests. + - `answer_request` on the peer takes the request and sends a response. + - Does this using the response sender on the request. + +3. Requesting Validator + + - `receive_response` on the original validator yields a response. + - Response was sent on the request's response sender. + - Uses `RequestManager::await_incoming` to await on pending responses in an + unordered fashion. + - Runs on the `MuxedMessage` receiver. + - `handle_response` handles the response. + +### API + +- `dispatch_requests` + - Dispatches pending requests for candidate data & statements. +- `answer_request` + - Answers an incoming request for a candidate. + - Takes an incoming `AttestedCandidateRequest`. +- `receive_response` + - Wait on the next incoming response. + - If there are no requests pending, this future never resolves. + - Returns `UnhandledResponse` +- `handle_response` + - Handles an incoming response. + - Takes `UnhandledResponse` + +## Manifests + +A manifest is a message about a known backed candidate, along with a description +of the statements backing it. It can be one of two kinds: + +- `Full`: Contains information about the candidate and should be sent to peers + who may not have the candidate yet. This is also called an `Announcement`. +- `Acknowledgement`: Omits information implicit in the candidate, and should be + sent to peers which are guaranteed to have the candidate already. + +### Manifest Exchange + +Manifest exchange is when a receiving node received a `Full` manifest and +replied with an `Acknowledgement`. It indicates that both nodes know the +candidate as valid and backed. This allows the nodes to send `Statement` +messages directly to each other for any new statements. + +Why? This limits the amount of statements we'd have to deal with w.r.t. +candidates that don't really exist. Limiting out-of-group statement distribution +between peers to only candidates that both peers agree are backed and exist +ensures we only have to store statements about real candidates. + +In practice, manifest exchange means that one of three things have happened: + +- They announced, we acknowledged. +- We announced, they acknowledged. +- We announced, they announced. + +Concerning the last case, note that it is possible for two nodes to have each +other in their sending set. Consider: + +``` +1 2 +3 4 +``` + +If validators 2 and 4 are in group B, then there is a path `2->1->3` and +`4->3->1`. Therefore, 1 and 3 might send each other manifests for the same +candidate at the same time, without having seen the other's yet. This also +counts as a manifest exchange, but is only allowed to occur in this way. + +After the exchange is complete, we update pending statements. Pending statements +are those we know locally that the remote node does not. + +#### Alternative Paths Through The Topology + +Nodes should send a `BackedCandidateAcknowledgement(CandidateHash, +StatementFilter)` notification to any peer which has sent a manifest, and the +candidate has been acquired by other means. This keeps alternative paths through +the topology open, which allows nodes to receive additional statements that come +later, but not after the candidate has been posted on-chain. + +This is mostly about the limitation that the runtime has no way for block +authors to post statements that come after the parablock is posted on-chain and +ensure those validators still get rewarded. Technically, we only need enough +statements to back the candidate and the manifest + request will provide that. +But more statements might come shortly afterwards, and we want those to end up +on-chain as well to ensure all validators in the group are rewarded. + +For clarity, here is the full timeline: + +1. candidate seconded +1. backable in cluster +1. distributed along grid +1. latecomers issue statements +1. candidate posted on chain +1. really latecomers issue statements + +## Cluster Module + +The cluster module provides direct distribution of unbacked candidates within a +group. By utilizing this initial phase of propagating only within +clusters/groups, we bound the number of `Seconded` messages per validator per +relay-parent, helping us prevent spam. Validators can try to circumvent this, +but they would only consume a few KB of memory and it is trivially slashable on +chain. + +The cluster module determines whether to accept/reject messages from other +validators in the same group. It keeps track of what we have sent to other +validators in the group, and pending statements. For the full protocol, see +"Protocol". + +## Grid Module + +The grid module provides distribution of backed candidates and late statements +outside the backing group. For the full protocol, see the "Protocol" section. + +### Grid Topology + +For distributing outside our cluster (aka backing group) we use a 2D grid +topology. This limits the amount of peers we send messages to, and handles +view updates. + +The basic operation of the grid topology is that: + +- A validator producing a message sends it to its row-neighbors and its + column-neighbors. +- A validator receiving a message originating from one of its row-neighbors + sends it to its column-neighbors. +- A validator receiving a message originating from one of its column-neighbors + sends it to its row-neighbors. + +This grid approach defines 2 unique paths for every validator to reach every +other validator in at most 2 hops, providing redundancy. + +Propagation follows these rules: + +- Each node has a receiving set and a sending set. These are different for each + group. That is, if a node receives a candidate from group A, it checks if it + is allowed to receive from that node for candidates from group A. +- For groups that we are in, receive from nobody and send to our X/Y peers. +- For groups that we are not part of: + - We receive from any validator in the group we share a slice with and send to + the corresponding X/Y slice in the other dimension. + - For any validators we don't share a slice with, we receive from the nodes + which share a slice with them. + +### Example + +For size 11, the matrix would be: + +``` +0 1 2 +3 4 5 +6 7 8 +9 10 +``` + +e.g. for index 10, the neighbors would be 1, 4, 7, 9 -- these are the nodes we +could directly communicate with (e.g. either send to or receive from). + +Now, which of these neighbors can 10 receive from? Recall that the +sending/receiving sets for 10 would be different for different groups. Here are +some hypothetical scenarios: + +- **Scenario 1:** 9 belongs to group A but not 10. Here, 10 can directly receive + candidates from group A from 9. 10 would propagate them to the nodes in {1, 4, + 7} that are not in A. +- **Scenario 2:** 6 is in group A instead of 9, and 7 is not in group A. 10 can + receive group A messages from 7 or 9. 10 will try to relay these messages, but + 7 and 9 together should have already propagated the message to all x/y + peers of 10. If so, then 10 will just receive acknowledgements in reply rather + than requests. +- **Scenario 3:** 10 itself is in group A. 10 would not receive candidates from + this group from any other nodes through the grid. It would itself send such + candidates to all its neighbors that are not in A. + +### Seconding Limit + +The seconding limit is a per-validator limit. Before asynchronous backing, we +had a rule that every validator was only allowed to second one candidate per +relay parent. With asynchronous backing, we have a 'maximum depth' which makes +it possible to second multiple candidates per relay parent. The seconding limit +is set to `max depth + 1` to set an upper bound on candidates entering the +system. + +## Candidates Module + +The candidates module provides a tracker for all known candidates in the view, +whether they are confirmed or not, and how peers have advertised the candidates. +What is a confirmed candidate? It is a candidate for which we have the full +receipt and the persisted validation data. This module gets confirmed candidates +from two sources: + +- It can be that a validator fetched a collation directly from the collator and + validated it. +- The first time a validator gets an announcement for an unknown candidate, it + will send a request for the candidate. Upon receiving a response and + validating it (see `UnhandledResponse::validate_response`), it will mark the + candidate as confirmed. + +## Requests Module + +The requests module provides a manager for pending requests for candidate data, +as well as pending responses. See "Request/Response Protocol" for a high-level +description of the flow. See module-docs for full details. + +## Glossary + +- **Acknowledgement:** A partial manifest sent to a validator that already has the + candidate to inform them that the sending node also knows the candidate. + Concludes a manifest exchange. +- **Announcement:** A full manifest indicating that a backed candidate is known by + the sending node. Initiates a manifest exchange. +- **Attestation:** See "Statement". +- **Backable vs. Backed:** + - Note that we sometimes use "backed" to refer to candidates that are + "backable", but not yet backed on chain. + - **Backed** should technically mean that the parablock candidate and its + backing statements have been added to a relay chain block. + - **Backable** is when the necessary backing statements have been acquired but + those statements and the parablock candidate haven't been backed in a relay + chain block yet. +- **Fragment tree:** A parachain fragment not referenced by the relay-chain. + It is a tree of prospective parachain blocks. +- **Manifest:** A message about a known backed candidate, along with a + description of the statements backing it. There are two kinds of manifest, + `Acknowledgement` and `Announcement`. See "Manifests" section. +- **Peer:** Another validator that a validator is connected to. +- **Request/response:** A protocol used to lazily request and receive heavy + candidate data when needed. +- **Reputation:** Tracks reputation of peers. Applies annoyance cost and good + behavior benefits. +- **Statement:** Signed statements that can be made about parachain candidates. + - **Seconded:** Proposal of a parachain candidate. Implicit validity vote. + - **Valid:** States that a parachain candidate is valid. +- **Target:** Target validator to send a statement to. +- **View:** Current knowledge of the chain state. + - **Explicit view** / **immediate view** + - The view a peer has of the relay chain heads and highest finalized block. + - **Implicit view** + - Derived from the immediate view. Composed of active leaves and minimum + relay-parents allowed for candidates of various parachains at those + leaves. diff --git a/polkadot/roadmap/implementers-guide/src/node/collators/README.md b/polkadot/roadmap/implementers-guide/src/node/collators/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3642e415efaba54621eccf98f781e17567f2502d --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/collators/README.md @@ -0,0 +1,6 @@ +# Collators + +Collators are special nodes which bridge a parachain to the relay chain. They are simultaneously full nodes of the parachain, and at least light clients of the relay chain. Their overall contribution to the system is the generation of Proofs of Validity for parachain candidates. + +The **Collation Generation** subsystem triggers collators to produce collations +and then forwards them to **Collator Protocol** to circulate to validators. diff --git a/polkadot/roadmap/implementers-guide/src/node/collators/collation-generation.md b/polkadot/roadmap/implementers-guide/src/node/collators/collation-generation.md new file mode 100644 index 0000000000000000000000000000000000000000..9053ea40f89e8f2407f98d8e2a5b0826135c13f1 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/collators/collation-generation.md @@ -0,0 +1,146 @@ +# Collation Generation + +The collation generation subsystem is executed on collator nodes and produces candidates to be distributed to validators. If configured to produce collations for a para, it produces collations and then feeds them to the [Collator Protocol][CP] subsystem, which handles the networking. + +## Protocol + +Collation generation for Parachains currently works in the following way: + +1. A new relay chain block is imported. +2. The collation generation subsystem checks if the core associated to + the parachain is free and if yes, continues. +3. Collation generation calls our collator callback, if present, to generate a PoV. If none exists, do nothing. +4. Authoring logic determines if the current node should build a PoV. +5. Build new PoV and give it back to collation generation. + +## Messages + +### Incoming + +- `ActiveLeaves` + - Notification of a change in the set of active leaves. + - Triggers collation generation procedure outlined in "Protocol" section. +- `CollationGenerationMessage::Initialize` + - Initializes the subsystem. Carries a config. + - No more than one initialization message should ever be sent to the collation + generation subsystem. + - Sent by a collator to initialize this subsystem. +- `CollationGenerationMessage::SubmitCollation` + - If the subsystem isn't initialized or the relay-parent is too old to be relevant, ignore the message. + - Otherwise, use the provided parameters to generate a [`CommittedCandidateReceipt`] + - Submit the collation to the collator-protocol with `CollatorProtocolMessage::DistributeCollation`. + +### Outgoing + +- `CollatorProtocolMessage::DistributeCollation` + - Provides a generated collation to distribute to validators. + +## Functionality + +The process of generating a collation for a parachain is very parachain-specific. As such, the details of how to do so are left beyond the scope of this description. The subsystem should be implemented as an abstract wrapper, which is aware of this configuration: + +```rust +/// The output of a collator. +/// +/// This differs from `CandidateCommitments` in two ways: +/// +/// - does not contain the erasure root; that's computed at the Polkadot level, not at Cumulus +/// - contains a proof of validity. +pub struct Collation { + /// Messages destined to be interpreted by the Relay chain itself. + pub upward_messages: Vec, + /// The horizontal messages sent by the parachain. + pub horizontal_messages: Vec>, + /// New validation code. + pub new_validation_code: Option, + /// The head-data produced as a result of execution. + pub head_data: HeadData, + /// Proof to verify the state transition of the parachain. + pub proof_of_validity: PoV, + /// The number of messages processed from the DMQ. + pub processed_downward_messages: u32, + /// The mark which specifies the block number up to which all inbound HRMP messages are processed. + pub hrmp_watermark: BlockNumber, +} + +/// Result of the [`CollatorFn`] invocation. +pub struct CollationResult { + /// The collation that was build. + pub collation: Collation, + /// An optional result sender that should be informed about a successfully seconded collation. + /// + /// There is no guarantee that this sender is informed ever about any result, it is completely okay to just drop it. + /// However, if it is called, it should be called with the signed statement of a parachain validator seconding the + /// collation. + pub result_sender: Option>, +} + +/// Signal that is being returned when a collation was seconded by a validator. +pub struct CollationSecondedSignal { + /// The hash of the relay chain block that was used as context to sign [`Self::statement`]. + pub relay_parent: Hash, + /// The statement about seconding the collation. + /// + /// Anything else than `Statement::Seconded` is forbidden here. + pub statement: SignedFullStatement, +} + +/// Collation function. +/// +/// Will be called with the hash of the relay chain block the parachain block should be build on and the +/// [`ValidationData`] that provides information about the state of the parachain on the relay chain. +/// +/// Returns an optional [`CollationResult`]. +pub type CollatorFn = Box< + dyn Fn( + Hash, + &PersistedValidationData, + ) -> Pin> + Send>> + + Send + + Sync, +>; + +/// Configuration for the collation generator +pub struct CollationGenerationConfig { + /// Collator's authentication key, so it can sign things. + pub key: CollatorPair, + /// Collation function. See [`CollatorFn`] for more details. + pub collator: Option, + /// The parachain that this collator collates for + pub para_id: ParaId, +} +``` + +The configuration should be optional, to allow for the case where the node is not run with the capability to collate. + +### Summary in plain English + +- **Collation (output of a collator)** + + - Contains the PoV (proof to verify the state transition of the + parachain) and other data. + +- **Collation result** + + - Contains the collation, and an optional result sender for a + collation-seconded signal. + +- **Collation seconded signal** + + - The signal that is returned when a collation was seconded by a + validator. + +- **Collation function** + + - Called with the relay chain block the parablock will be built on top + of. + - Called with the validation data. + - Provides information about the state of the parachain on the relay + chain. + +- **Collation generation config** + + - Contains collator's authentication key, optional collator function, and + parachain ID. + +[CP]: collator-protocol.md diff --git a/polkadot/roadmap/implementers-guide/src/node/collators/collator-protocol.md b/polkadot/roadmap/implementers-guide/src/node/collators/collator-protocol.md new file mode 100644 index 0000000000000000000000000000000000000000..09265a5348475b9f277a0ae5379ce9af3e15da55 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/collators/collator-protocol.md @@ -0,0 +1,138 @@ +# Collator Protocol + +The Collator Protocol implements the network protocol by which collators and validators communicate. It is used by collators to distribute collations to validators and used by validators to accept collations by collators. + +Collator-to-Validator networking is more difficult than Validator-to-Validator networking because the set of possible collators for any given para is unbounded, unlike the validator set. Validator-to-Validator networking protocols can easily be implemented as gossip because the data can be bounded, and validators can authenticate each other by their `PeerId`s for the purposes of instantiating and accepting connections. + +Since, at least at the level of the para abstraction, the collator-set for any given para is unbounded, validators need to make sure that they are receiving connections from capable and honest collators and that their bandwidth and time are not being wasted by attackers. Communicating across this trust-boundary is the most difficult part of this subsystem. + +Validation of candidates is a heavy task, and furthermore, the [`PoV`][PoV] itself is a large piece of data. Empirically, `PoV`s are on the order of 10MB. + +> TODO: note the incremental validation function Ximin proposes at https://github.com/paritytech/polkadot/issues/1348 + +As this network protocol serves as a bridge between collators and validators, it communicates primarily with one subsystem on behalf of each. As a collator, this will receive messages from the [`CollationGeneration`][CG] subsystem. As a validator, this will communicate only with the [`CandidateBacking`][CB]. + +## Protocol + +Input: [`CollatorProtocolMessage`][CPM] + +Output: + +- [`RuntimeApiMessage`][RAM] +- [`NetworkBridgeMessage`][NBM] +- [`CandidateBackingMessage`][CBM] + +## Functionality + +This network protocol uses the `Collation` peer-set of the [`NetworkBridge`][NB]. + +It uses the [`CollatorProtocolV1Message`](../../types/network.md#collator-protocol) as its `WireMessage` + +Since this protocol functions both for validators and collators, it is easiest to go through the protocol actions for each of them separately. + +Validators and collators. +```dot process +digraph { + c1 [shape=MSquare, label="Collator 1"]; + c2 [shape=MSquare, label="Collator 2"]; + + v1 [shape=MSquare, label="Validator 1"]; + v2 [shape=MSquare, label="Validator 2"]; + + c1 -> v1; + c1 -> v2; + c2 -> v2; +} +``` + +### Collators + +It is assumed that collators are only collating on a single parachain. Collations are generated by the [Collation Generation][CG] subsystem. We will keep up to one local collation per relay-parent, based on `DistributeCollation` messages. If the para is not scheduled on any core, at the relay-parent, or the relay-parent isn't in the active-leaves set, we ignore the message as it must be invalid in that case - although this indicates a logic error elsewhere in the node. + +We keep track of the Para ID we are collating on as a collator. This starts as `None`, and is updated with each `CollateOn` message received. If the `ParaId` of a collation requested to be distributed does not match the one we expect, we ignore the message. + +As with most other subsystems, we track the active leaves set by following `ActiveLeavesUpdate` signals. + +For the purposes of actually distributing a collation, we need to be connected to the validators who are interested in collations on that `ParaId` at this point in time. We assume that there is a discovery API for connecting to a set of validators. + +As seen in the [Scheduler Module][SCH] of the runtime, validator groups are fixed for an entire session and their rotations across cores are predictable. Collators will want to do these things when attempting to distribute collations at a given relay-parent: + * Determine which core the para collated-on is assigned to. + * Determine the group on that core. + * Issue a discovery request for the validators of the current group with[`NetworkBridgeMessage`][NBM]`::ConnectToValidators`. + +Once connected to the relevant peers for the current group assigned to the core (transitively, the para), advertise the collation to any of them which advertise the relay-parent in their view (as provided by the [Network Bridge][NB]). If any respond with a request for the full collation, provide it. However, we only send one collation at a time per relay parent, other requests need to wait. This is done to reduce the bandwidth requirements of a collator and also increases the chance to fully send the collation to at least one validator. From the point where one validator has received the collation and seconded it, it will also start to share this collation with other validators in its backing group. Upon receiving a view update from any of these peers which includes a relay-parent for which we have a collation that they will find relevant, advertise the collation to them if we haven't already. + +### Validators + +On the validator side of the protocol, validators need to accept incoming connections from collators. They should keep some peer slots open for accepting new speculative connections from collators and should disconnect from collators who are not relevant. + +```dot process +digraph G { + label = "Declaring, advertising, and providing collations"; + labelloc = "t"; + rankdir = LR; + + subgraph cluster_collator { + rank = min; + label = "Collator"; + graph[style = border, rank = min]; + + c1, c2 [label = ""]; + } + + subgraph cluster_validator { + rank = same; + label = "Validator"; + graph[style = border]; + + v1, v2 [label = ""]; + } + + c1 -> v1 [label = "Declare and advertise"]; + + v1 -> c2 [label = "Request"]; + + c2 -> v2 [label = "Provide"]; + + v2 -> v2 [label = "Note Good/Bad"]; +} +``` + +When peers connect to us, they can `Declare` that they represent a collator with given public key and intend to collate on a specific para ID. Once they've declared that, and we checked their signature, they can begin to send advertisements of collations. The peers should not send us any advertisements for collations that are on a relay-parent outside of our view or for a para outside of the one they've declared. + +The protocol tracks advertisements received and the source of the advertisement. The advertisement source is the `PeerId` of the peer who sent the message. We accept one advertisement per collator per source per relay-parent. + +As a validator, we will handle requests from other subsystems to fetch a collation on a specific `ParaId` and relay-parent. These requests are made with the request response protocol `CollationFetchingRequest` request. To do so, we need to first check if we have already gathered a collation on that `ParaId` and relay-parent. If not, we need to select one of the advertisements and issue a request for it. If we've already issued a request, we shouldn't issue another one until the first has returned. + +When acting on an advertisement, we issue a `Requests::CollationFetchingV1`. However, we only request one collation at a time per relay parent. This reduces the bandwidth requirements and as we can second only one candidate per relay parent, the others are probably not required anyway. If the request times out, we need to note the collator as being unreliable and reduce its priority relative to other collators. + +As a validator, once the collation has been fetched some other subsystem will inspect and do deeper validation of the collation. The subsystem will report to this subsystem with a [`CollatorProtocolMessage`][CPM]`::ReportCollator`. In that case, if we are connected directly to the collator, we apply a cost to the `PeerId` associated with the collator and potentially disconnect or blacklist it. If the collation is seconded, we notify the collator and apply a benefit to the `PeerId` associated with the collator. + +### Interaction with [Candidate Backing][CB] + +As collators advertise the availability, a validator will simply second the first valid parablock candidate per relay head by sending a [`CandidateBackingMessage`][CBM]`::Second`. Note that this message contains the relay parent of the advertised collation, the candidate receipt and the [PoV][PoV]. + +Subsequently, once a valid parablock candidate has been seconded, the [`CandidateBacking`][CB] subsystem will send a [`CollatorProtocolMessage`][CPM]`::Seconded`, which will trigger this subsystem to notify the collator at the `PeerId` that first advertised the parablock on the seconded relay head of their successful seconding. + + +## Future Work + +Several approaches have been discussed, but all have some issues: + +- The current approach is very straightforward. However, that protocol is vulnerable to a single collator which, as an attack or simply through chance, gets its block candidate to the node more often than its fair share of the time. +- If collators produce blocks via Aura, BABE or in future Sassafras, it may be possible to choose an "Official" collator for the round, but it may be tricky to ensure that the PVF logic is enforced at collator leader election. +- We could use relay-chain BABE randomness to generate some delay `D` on the order of 1 second, +- 1 second. The collator would then second the first valid parablock which arrives after `D`, or in case none has arrived by `2*D`, the last valid parablock which has arrived. This makes it very hard for a collator to game the system to always get its block nominated, but it reduces the maximum throughput of the system by introducing delay into an already tight schedule. +- A variation of that scheme would be to have a fixed acceptance window `D` for parablock candidates and keep track of count `C`: the number of parablock candidates received. At the end of the period `D`, we choose a random number I in the range `[0, C)` and second the block at Index I. Its drawback is the same: it must wait the full `D` period before seconding any of its received candidates, reducing throughput. +- In order to protect against DoS attacks, it may be prudent to run throw out collations from collators that have behaved poorly (whether recently or historically) and subsequently only verify the PoV for the most suitable of collations. + +[CB]: ../backing/candidate-backing.md +[CBM]: ../../types/overseer-protocol.md#candidate-backing-mesage +[CG]: collation-generation.md +[CPM]: ../../types/overseer-protocol.md#collator-protocol-message +[CS]: ../backing/candidate-selection.md +[CSM]: ../../types/overseer-protocol.md#candidate-selection-message +[NB]: ../utility/network-bridge.md +[NBM]: ../../types/overseer-protocol.md#network-bridge-message +[PoV]: ../../types/availability.md#proofofvalidity +[RAM]: ../../types/overseer-protocol.md#runtime-api-message +[SCH]: ../../runtime/scheduler.md diff --git a/polkadot/roadmap/implementers-guide/src/node/disputes/README.md b/polkadot/roadmap/implementers-guide/src/node/disputes/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a6e126b1534b8548f2f971dbaee095908f6db3c9 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/disputes/README.md @@ -0,0 +1,18 @@ +# Disputes Subsystems + +If approval voting finds an invalid candidate, a dispute is raised. The disputes +subsystems are concerned with the following: + +1. Disputes can be raised +2. Disputes (votes) get propagated to all other validators +3. Votes get recorded as necessary +3. Nodes will participate in disputes in a sensible fashion +4. Finality is stopped while a candidate is being disputed on chain +5. Chains can be reverted in case a dispute concludes invalid +6. Votes are provided to the provisioner for importing on chain, in order for + slashing to work. + +The dispute-coordinator subsystem interfaces with the provisioner and chain +selection to make the bulk of this possible. `dispute-distribution` is concerned +with getting votes out to other validators and receiving them in a spam +resilient way. diff --git a/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-coordinator.md b/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-coordinator.md new file mode 100644 index 0000000000000000000000000000000000000000..7692491fde1f7fbe47bf7ae9fa96a159d15587dd --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-coordinator.md @@ -0,0 +1,789 @@ +# Dispute Coordinator + +The coordinator is the central subsystem of the node-side components which +participate in disputes. It wraps a database, which is used to track statements +observed by _all_ validators over some window of sessions. Votes older than this +session window are pruned. + +In particular the dispute-coordinator is responsible for: + +- Ensuring that the node is able to raise a dispute in case an invalid candidate + is found during approval checking. +- Ensuring that backing and approval votes will be recorded on chain. With these + votes on chain we can be certain that appropriate targets for slashing will be + available for concluded disputes. Also, scraping these votes during a dispute + is necessary for critical spam prevention measures. +- Ensuring backing votes will never get overridden by explicit votes. +- Coordinating actual participation in a dispute, ensuring that the node + participates in any justified dispute in a way that ensures resolution of + disputes on the network even in the case of many disputes raised (flood/DoS + scenario). +- Ensuring disputes resolve, even for candidates on abandoned forks as much as + reasonably possible, to rule out "free tries" and thus guarantee our gambler's + ruin property. +- Providing an API for chain selection, so we can prevent finalization of any + chain which has included candidates for which a dispute is either ongoing or + concluded invalid and avoid building on chains with an included invalid + candidate. +- Providing an API for retrieving (resolved) disputes, including all votes, both + implicit (approval, backing) and explicit dispute votes. So validators can get + rewarded/slashed accordingly. + +## Ensuring That Disputes Can Be Raised + +If a candidate turns out invalid in approval checking, the `approval-voting` +subsystem will try to issue a dispute. For this, it will send a message +`DisputeCoordinatorMessage::IssueLocalStatement` to the dispute coordinator, +indicating to cast an explicit invalid vote. It is the responsibility of the +dispute coordinator on reception of such a message to create and sign that +explicit invalid vote and trigger a dispute if none for that candidate is +already ongoing. + +In order to raise a dispute, a node has to be able to provide two opposing votes. +Given that the reason of the backing phase is to have validators with skin in +the game, the opposing valid vote will very likely be a backing vote. It could +also be some already cast approval vote, but the significant point here is: As +long as we have backing votes available, any node will be able to raise a +dispute. + +Therefore a vital responsibility of the dispute coordinator is to make sure +backing votes are available for all candidates that might still get disputed. To +accomplish this task in an efficient way the dispute-coordinator relies on chain +scraping. Whenever a candidate gets backed on chain, we record in chain storage +the backing votes imported in that block. This way, given the chain state for a +given relay chain block, we can retrieve via a provided runtime API the backing +votes imported by that block. The dispute coordinator makes sure to query those +votes for any non finalized blocks: In case of missed blocks, it will do chain +traversal as necessary. + +Relying on chain scraping is very efficient for two reasons: + +1. Votes are already batched. We import all available backing votes for a + candidate all at once. If instead we imported votes from candidate-backing as + they came along, we would import each vote individually which is + inefficient in the current dispute coordinator implementation (quadratic + complexity). +2. We also import less votes in total, as we avoid importing statements for + candidates that never got successfully backed on any chain. + +It also is secure, because disputes are only ever raised in the approval voting +phase. A node only starts the approval process after it has seen a candidate +included on some chain, for that to happen it must have been backed previously. +Therefore backing votes are available at that point in time. Signals are +processed first, so even if a block is skipped and we only start importing +backing votes on the including block, we will have seen the backing votes by the +time we process messages from approval voting. + +In summary, for making it possible for a dispute to be raised, recording of +backing votes from chain is sufficient and efficient. In particular there is no +need to preemptively import approval votes, which has shown to be a very +inefficient process. (Quadratic complexity adds up, with 35 votes in total per candidate) + +Approval votes are very relevant nonetheless as we are going to see in the next +section. + +## Ensuring approval votes will be recorded + +### Ensuring Recording + +Only votes recorded by the dispute coordinator will be considered for slashing. + +While there is no need to record approval votes in the dispute coordinator +preemptively, we make some effort to have any in approval-voting received +approval votes recorded when a dispute actually happens: + +This is not required for concluding the dispute, as nodes send their own vote +anyway (either explicit valid or their existing approval-vote). What nodes can +do though, is participating in approval-voting, casting a vote, but later when a +dispute is raised reconsider their vote and send an explicit invalid vote. If +they managed to only have that one recorded, then they could avoid a slash. + +This is not a problem for our basic security assumptions: The backers are the +ones to be supposed to have skin in the game, so we are not too woried about +colluding approval voters getting away slash free as the gambler's ruin property +is maintained anyway. There is however a separate problem, from colluding +approval-voters, that is "lazy" approval voters. If it were easy and reliable +for approval-voters to reconsider their vote, in case of an actual dispute, then +they don't have a direct incentive (apart from playing a part in securing the +network) to properly run the validation function at all - they could just always +vote "valid" totally risk free. (While they would alwasy risk a slash by voting +invalid.) + + +So we do want to fetch approval votes from approval-voting. Importing votes is +most efficient when batched. At the same time approval voting and disputes are +running concurrently so approval votes are expected to trickle in still, when a +dispute is already ongoing. + +Hence, we have the following requirements for importing approval votes: + +1. Only import them when there is a dispute, because otherwise we are + wasting lots of resources _always_ for the exceptional case of a dispute. +2. Import votes batched when possible, to avoid quadratic import complexity. +3. Take into account that approval voting is still ongoing, while a dispute is + already running. + +With a design where approval voting sends votes to the dispute-coordinator by +itself, we would need to make approval voting aware of ongoing disputes and once +it is aware it could start sending all already existing votes batched and +trickling in votes as they come. The problem with this is, that it adds some +unnecessary complexity to approval-voting and also we might still import most of +the votes unbatched one-by-one, depending on what point in time the dispute was +raised. + +Instead of the dispute coordinator informing approval-voting of an ongoing +dispute for it to begin forwarding votes to the dispute coordinator, it makes +more sense for the dispute-coordinator to just ask approval-voting for votes of +candidates in dispute. This way, the dispute coordinator can also pick the best +time for maximizing the number of votes in the batch. + +Now the question remains, when should the dispute coordinator ask +approval-voting for votes? + +In fact for slashing it is only relevant to have them once the dispute +concluded, so we can query approval voting the moment the dispute concludes! +Two concerns that come to mind, are easily addressed: + +1. Timing: We would like to rely as little as possible on implementation details + of approval voting. In particular, if the dispute is ongoing for a long time, + do we have any guarantees that approval votes are kept around long enough by + approval voting? Will approval votes still be present by the time the + dispute concludes in all cases? The answer is nuanced, but in general we + cannot rely on it. The problem is first, that finalization and + approval-voting is an off-chain process so there is no global consensus: As + soon as at least f+1 honest (f=n/3, where n is the number of + validators/nodes) nodes have seen the dispute conclude, finalization will + take place and approval votes will be cleared. This would still be fine, if + we had some guarantees that those honest nodes will be able to include those + votes in a block. This guarantee does not exist unfortunately, we will + discuss the problem and solutions in more detail [below][#Ensuring Chain Import]. + + The second problem is that approval-voting will abandon votes as soon as a + chain can no longer be finalized (some other/better fork already has been). + This second problem can somehow be mitigated by also importing votes as soon + as a dispute is detected, but not fully resolved. It is still inherently + racy. The good thing is, this should be good enough: We are worried about + lazy approval checkers, the system does not need to be perfect. It should be + enough if there is some risk of getting caught. +2. We are not worried about the dispute not concluding, as nodes will always + send their own vote, regardless of it being an explict or an already existing + approval-vote. + +Conclusion: As long as we make sure, if our own approval vote gets imported +(which would prevent dispute participation) to also distribute it via +dispute-distribution, disputes can conclude. To mitigate raciness with +approval-voting deleting votes we will import approval votes twice during a +dispute: Once when it is raised, to make as sure as possible to see approval +votes also for abandoned forks and second when the dispute concludes, to +maximize the amount of potentially malicious approval votes to be recorded. The +raciness obviously is not fully resolved by this, but this is fine as argued +above. + +Ensuring vote import on chain is covered in the next section. + +What we don't care about is that honest approval-voters will likely validate +twice, once in approval voting and once via dispute-participation. Avoiding that +does not really seem worthwhile though, as disputes are for one exceptional, so +a little wasted effort won't affect everyday performance - second, even with +eager importing of approval votes, those doubled work is still present as +disputes and approvals are racing. Every time participation is faster than +approval, a node would do double work. + +### Ensuring Chain Import + +While in the previous section we discussed means for nodes to ensure relevant +votes are recorded so lazy approval checkers get slashed properly, it is crucial +to also discuss the actual chain import. Only if we guarantee that recorded votes +will get imported on chain (on all potential chains really) we will succeed +in executing slashes. Particularly we need to make sure backing votes end up on +chain consistently. + +Dispute distribution will make sure all explicit dispute votes get distributed +among nodes which includes current block producers (current authority set) which +is an important property: If the dispute carries on across an era change, we +need to ensure that the new validator set will learn about any disputes and +their votes, so they can put that information on chain. Dispute-distribution +luckily has this property and always sends votes to the current authority set. +The issue is, for dispute-distribution, nodes send only their own explicit (or +in some cases their approval vote) in addition to some opposing vote. This +guarantees that at least some backing or approval vote will be present at the +block producer, but we don't have a 100% guarantee to have votes for all +backers, even less for approval checkers. + +Reason for backing votes: While backing votes will be present on at least some +chain, that does not mean that any such chain is still considered for block +production in the current set - they might only exist on an already abandoned +fork. This means a block producer that just joined the set, might not have seen +any of them. + +For approvals it is even more tricky and less necessary: Approval voting together +with finalization is a completely off-chain process therefore those protocols +don't care about block production at all. Approval votes only have a guarantee of +being propagated between the nodes that are responsible for finalizing the +concerned blocks. This implies that on an era change the current authority set, +will not necessarily get informed about any approval votes for the previous era. +Hence even if all validators of the previous era successfully recorded all approval +votes in the dispute coordinator, they won't get a chance to put them on chain, +hence they won't be considered for slashing. + +It is important to note, that the essential properties of the system still hold: +Dispute-distribution will distribute at _least one_ "valid" vote to the current +authority set, hence at least one node will get slashed in case of outcome +"invalid". Also in reality the validator set is rarely exchanged 100%, therefore +in practice some validators in the current authority set will overlap with the +ones in the previous set and will be able to record votes on chain. + +Still, for maximum accountability we need to make sure a previous authority set +can communicate votes to the next one, regardless of any chain: This is yet to +be implemented see section "Resiliency" in dispute-distribution and +[this](https://github.com/paritytech/polkadot/issues/3398) ticket. + +## Coordinating Actual Dispute Participation + +Once the dispute coordinator learns about a dispute, it is its responsibility to +make sure the local node participates in that dispute. + +The dispute coordinator learns about a dispute by importing votes from either +chain scraping or from dispute-distribution. If it finds opposing votes (always +the case when coming from dispute-distribution), it records the presence of a +dispute. Then, in case it does not find any local vote for that dispute already, +it needs to trigger participation in the dispute (see previous section for +considerations when the found local vote is an approval vote). + +Participation means, recovering availability and re-evaluating the POV. The +result of that validation (either valid or invalid) will be the node's vote on +that dispute: Either explicit "invalid" or "valid". The dispute coordinator will +inform `dispute-distribution` about our vote and `dispute-distribution` will make +sure that our vote gets distributed to all other validators. + +Nothing ever is that easy though. We can not blindly import anything that comes +along and trigger participation no matter what. + +### Spam Considerations + +In Polkadot's security model, it is important that attempts to attack the system +result in a slash of the offenders. Therefore we need to make sure that this +slash is actually happening. Attackers could try to prevent the slashing from +taking place, by overwhelming validators with disputes in such a way that no +single dispute ever concludes, because nodes are busy processing newly incoming +ones. Other attacks are imaginable as well, like raising disputes for candidates +that don't exist, just filling up everyone's disk slowly or worse making nodes +try to participate, which will result in lots of network requests for recovering +availability. + +The last point brings up a significant consideration in general: Disputes are +about escalation: Every node will suddenly want to check, instead of only a few. +A single message will trigger the whole network to start significant amount of +work and will cause lots of network traffic and messages. Hence the +dispute system is very susceptible to being a brutal amplifier for DoS attacks, +resulting in DoS attacks to become very easy and cheap, if we are not careful. + +One counter measure we are taking is making raising of disputes a costly thing: +If you raise a dispute, because you claim a candidate is invalid, although it is +in fact valid - you will get slashed, hence you pay for consuming those +resources. The issue is: This only works if the dispute concerns a candidate +that actually exists! + +If a node raises a dispute for a candidate that never got included (became +available) on any chain, then the dispute can never conclude, hence nobody gets +slashed. It makes sense to point out that this is less bad than it might sound +at first, as trying to participate in a dispute for a non existing candidate is +"relatively" cheap. Each node will send out a few hundred tiny request messages +for availability chunks, which all will end up in a tiny response "NoSuchChunk" +and then no participation will actually happen as there is nothing to +participate. Malicious nodes could provide chunks, which would make things more +costly, but at the full expense of the attackers bandwidth - no amplification +here. I am bringing that up for completeness only: Triggering a thousand nodes +to send out a thousand tiny network messages by just sending out a single +garbage message, is still a significant amplification and is nothing to ignore - +this could absolutely be used to cause harm! + +### Participation + +As explained, just blindly participating in any "dispute" that comes along is +not a good idea. First we would like to make sure the dispute is actually +genuine, to prevent cheap DoS attacks. Secondly, in case of genuine disputes, we +would like to conclude one after the other, in contrast to +processing all at the same time, slowing down progress on all of them, bringing +individual processing to a complete halt in the worst case (nodes get overwhelmed +at some stage in the pipeline). + +To ensure to only spend significant work on genuine disputes, we only trigger +participation at all on any _vote import_ if any of the following holds true: + +- We saw the disputed candidate included in some not yet finalized block on at + least one fork of the chain. +- We have seen the disputed candidate backed in some not yet finalized block on + at least one fork of the chain. This ensures the candidate is at least not + completely made up and there has been some effort already flown into that + candidate. Generally speaking a dispute shouldn't be raised for a candidate + which is backed but is not yet included. Disputes are raised during approval + checking. We participate on such disputes as a precaution - maybe we haven't + seen the `CandidateIncluded` event yet? +- The dispute is already confirmed: Meaning that 1/3+1 nodes already + participated, as this suggests in our threat model that there was at least one + honest node that already voted, so the dispute must be genuine. + +Note: A node might be out of sync with the chain and we might only learn about a +block, including a candidate, after we learned about the dispute. This means, we +have to re-evaluate participation decisions on block import! + +With this, nodes won't waste significant resources on completely made up +candidates. The next step is to process dispute participation in a (globally) +ordered fashion. Meaning a majority of validators should arrive at at least +roughly at the same ordering of participation, for disputes to get resolved one +after another. This order is only relevant if there are lots of disputes, so we +obviously only need to worry about order if participations start queuing up. + +We treat participation for candidates that we have seen included with priority +and put them on a priority queue which sorts participation based on the block +number of the relay parent of the candidate and for candidates with the same +relay parent height further by the `CandidateHash`. This ordering is globally +unique and also prioritizes older candidates. + +The latter property makes sense, because if an older candidate turns out invalid, +we can roll back the full chain at once. If we resolved earlier disputes first +and they turned out invalid as well, we might need to roll back a couple of +times instead of just once to the oldest offender. This is obviously a good +idea, in particular it makes it impossible for an attacker to prevent rolling +back a very old candidate, by keeping raising disputes for newer candidates. + +For candidates we have not seen included, but we know are backed (thanks to +chain scraping) or we have seen a dispute with 1/3+1 participation (confirmed +dispute) on them - we put participation on a best-effort queue. It has got the +same ordering as the priority one - by block heights of the relay parent, older +blocks are with priority. There is a possibility not to be able to obtain the +block number of the parent when we are inserting the dispute in the queue. To +account for races, we will promote any existing participation request to the +priority queue once we learn about an including block. NOTE: this is still work +in progress and is tracked by [this +issue](https://github.com/paritytech/polkadot/issues/5875). + +### Abandoned Forks + +Finalization: As mentioned we care about included and backed candidates on any +non-finalized chain, given that any disputed chain will not get finalized, we +don't need to care about finalized blocks, but what about forks that fall behind +the finalized chain in terms of block number? For those we would still like to +be able to participate in any raised disputes, otherwise attackers might be able +to avoid a slash if they manage to create a better fork after they learned about +the approval checkers. Therefore we do care about those forks even after they +have fallen behind the finalized chain. + +For simplicity we also care about the actual finalized chain (not just forks) up +to a certain depth. We do have to limit the depth, because otherwise we open a +DoS vector again. The depth (into the finalized chain) should be oriented on the +approval-voting execution timeout, in particular it should be significantly +larger. Otherwise by the time the execution is allowed to finish, we already +dropped information about those candidates and the dispute could not conclude. + +## Import + +### Spam Considerations + +In the last section we looked at how to treat queuing participations to +handle heavy dispute load well. This already ensures, that honest nodes won't +amplify cheap DoS attacks. There is one minor issue remaining: Even if we delay +participation until we have some confirmation of the authenticity of the +dispute, we should also not blindly import all votes arriving into the database +as this might be used to just slowly fill up disk space, until the node is no +longer functional. This leads to our last protection mechanism at the dispute +coordinator level (dispute-distribution also has its own), which is spam slots. +For each import containing an invalid vote, where we don't know whether it might +be spam or not we increment a counter for each signing participant of explicit +`invalid` votes. + +What votes do we treat as a potential spam? A vote will increase a spam slot if +and only if all of the following conditions are satisfied: + +* the candidate under dispute was not seen included nor backed on any chain +* the dispute is not confirmed +* we haven't cast a vote for the dispute + +Whenever any vote on a dispute is imported these conditions are checked. If the +dispute is found not to be potential spam, then spam slots for the disputed candidate hash are cleared. This decrements the spam count for every validator +which had voted invalid. + +To keep spam slots from filling up unnecessarily we want to clear spam slots +whenever a candidate is seen to be backed or included. Fortunately this behavior +is acheived by clearing slots on vote import as described above. Because on chain +backing votes are processed when a block backing the disputed candidate is discovered, spam slots are cleared for every backed candidate. Included +candidates have also been seen as backed on the same fork, so decrementing spam +slots is handled in that case as well. + +The reason this works is because we only need to worry about actual dispute +votes. Import of backing votes are already rate limited and concern only real +candidates. For approval votes a similar argument holds (if they come from +approval-voting), but we also don't import them until a dispute already +concluded. For actual dispute votes we need two opposing votes, so there must be +an explicit `invalid` vote in the import. Only a third of the validators can be +malicious, so spam disk usage is limited to `2*vote_size*n/3*NUM_SPAM_SLOTS`, with +`n` being the number of validators. + +### Backing Votes + +Backing votes are in some way special. For starters they are the only valid +votes that are guaranteed to exist for any valid dispute to be raised. Second +they are the only votes that commit to a shorter execution timeout +`BACKING_EXECUTION_TIMEOUT`, compared to a more lenient timeout used in approval +voting. To account properly for execution time variance across machines, +slashing might treat backing votes differently (more aggressively) than other +voting `valid` votes. Hence in import we shall never override a backing vote +with another valid vote. They can not be assumed to be interchangeable. + +## Attacks & Considerations + +The following attacks on the priority queue and best-effort queues are +considered in above design. + +### Priority Queue + +On the priority queue, we will only queue participations for candidates we have +seen included on any chain. Any attack attempt would start with a candidate +included on some chain, but an attacker could try to only reveal the including +relay chain blocks to just some honest validators and stop as soon as it learns +that some honest validator would have a relevant approval assignment. + +Without revealing the including block to any honest validator, we don't really +have an attack yet. Once the block is revealed though, the above is actually +very hard. Each honest validator will re-distribute the block it just learned +about. This means an attacker would need to pull of a targeted DoS attack, which +allows the validator to send its assignment, but prevents it from forwarding and +sharing the relay chain block. + +This sounds already hard enough, provided that we also start participation if +we learned about an including block after the dispute has been raised already +(we need to update participation queues on new leaves), but to be even safer +we choose to have an additional best-effort queue. + +### Best-Effort Queue + +While attacking the priority queue is already pretty hard, attacking the +best-effort queue is even harder. For a candidate to be a threat, it has to be +included on some chain. For it to be included, it has to have been backed before +and at least n/3 honest nodes must have seen that block, so availability +(inclusion) can be reached. Making a full third of the nodes not further +propagate a block, while at the same time allowing them to fetch chunks, sign +and distribute bitfields seems almost infeasible and even if accomplished, those +nodes would be enough to confirm a dispute and we have not even touched the +above fact that in addition, for an attack, the following including block must +be shared with honest validators as well. + +It is worth mentioning that a successful attack on the priority queue as +outlined above is already outside of our threat model, as it assumes n/3 +malicious nodes + additionally malfunctioning/DoSed nodes. Even more so for +attacks on the best-effort queue, as our threat model only allows for n/3 +malicious _or_ malfunctioning nodes in total. It would therefore be a valid +decision to ditch the best-effort queue, if it proves to become a burden or +creates other issues. + +One issue we should not be worried about though is spam. For abusing best-effort +for spam, the following scenario would be necessary: + +An attacker controls a backing group: The attacker can then have candidates +backed and choose to not provide chunks. This should come at a cost to miss out +on rewards for backing, so is not free. At the same time it is rate limited, as +a backing group can only back so many candidates legitimately. (~ 1 per slot): + +1. They have to wait until a malicious actor becomes block producer (for causing + additional forks via equivocation for example). +2. Forks are possible, but if caused by equivocation also not free. +3. For each fork the attacker has to wait until the candidate times out, for + backing another one. + +Assuming there can only be a handful of forks, 2) together with 3) the candidate +timeout restriction, frequency should indeed be in the ballpark of once per +slot. Scaling linearly in the number of controlled backing groups, so two groups +would mean 2 backings per slot, ... + +So by this reasoning an attacker could only do very limited harm and at the same +time will have to pay some price for it (it will miss out on rewards). Overall +the work done by the network might even be in the same ballpark as if actors +just behaved honestly: + +1. Validators would have fetched chunks +2. Approval checkers would have done approval checks + +While because of the attack (backing, not providing chunks and afterwards +disputing the candidate), the work for 1000 validators would be: + +All validators sending out ~ 1000 tiny requests over already established +connections, with also tiny (byte) responses. + +This means around a million requests, while in the honest case it would be ~ +10000 (30 approval checkers x330) - where each request triggers a response in +the range of kilobytes. Hence network load alone will likely be higher in the +honest case than in the DoS attempt case, which would mean the DoS attempt +actually reduces load, while also costing rewards. + +In the worst case this can happen multiple times, as we would retry that on +every vote import. The effect would still be in the same ballpark as honest +behavior though and can also be mitigated by chilling repeated availability +recovery requests for example. + +## Out of Scope + +### No Disputes for Non Included Candidates + +We only ever care about disputes for candidates that have been included on at +least some chain (became available). This is because the availability system was +designed for precisely that: Only with inclusion (availability) we have +guarantees about the candidate to actually be available. Because only then we +have guarantees that malicious backers can be reliably checked and slashed. Also, by design non included candidates do not pose any threat to the system. + +One could think of an (additional) dispute system to make it possible to dispute +any candidate that has been proposed by a validator, no matter whether it got +successfully included or even backed. Unfortunately, it would be very brittle +(no availability) and also spam protection would be way harder than for the +disputes handled by the dispute-coordinator. In fact, all the spam handling +strategies described above would simply be unavailable. + +It is worth thinking about who could actually raise such disputes anyway: +Approval checkers certainly not, as they will only ever check once availability +succeeded. The only other nodes that meaningfully could/would are honest backing +nodes or collators. For collators spam considerations would be even worse as +there can be an unlimited number of them and we can not charge them for spam, so +trying to handle disputes raised by collators would be even more complex. For +honest backers: It actually makes more sense for them to wait until availability +is reached as well, as only then they have guarantees that other nodes will be +able to check. If they disputed before, all nodes would need to recover the data +from them, so they would be an easy DoS target. + +In summary: The availability system was designed for raising disputes in a +meaningful and secure way after availability was reached. Trying to raise +disputes before does not meaningfully contribute to the systems security/might +even weaken it as attackers are warned before availability is reached, while at +the same time adding signficant amount of complexity. We therefore punt on such +disputes and concentrate on disputes the system was designed to handle. + +### No Disputes for Already Finalized Blocks + +Note that by above rules in the `Participation` section, we will not participate +in disputes concerning a candidate in an already finalized block. This is +because, disputing an already finalized block is simply too late and therefore +of little value. Once finalized, bridges have already processed the block for +example, so we have to assume the damage is already done. Governance has to step +in and fix what can be fixed. + +Making disputes for already finalized blocks possible would only provide two +features: + +1. We can at least still slash attackers. +2. We can freeze the chain to some governance only mode, in an attempt to + minimize potential harm done. + +Both seem kind of worthwhile, although as argued above, it is likely that there +is not too much that can be done in 2 and we would likely only ending up DoSing +the whole system without much we can do. 1 can also be achieved via governance +mechanisms. + +In any case, our focus should be making as sure as reasonably possible that any +potentially invalid block does not get finalized in the first place. Not +allowing disputing already finalized blocks actually helps a great deal with +this goal as it massively reduces the amount of candidates that can be disputed. + +This makes attempts to overwhelm the system with disputes significantly harder +and counter measures way easier. We can limit inclusion for example (as +suggested [here](https://github.com/paritytech/polkadot/issues/5898) in case of +high dispute load. Another measure we have at our disposal is that on finality +lag block production will slow down, implicitly reducing the rate of new +candidates that can be disputed. Hence, the cutting-off of the unlimited +candidate supply of already finalized blocks, guarantees the necessary DoS +protection and ensures we can have measures in place to keep up with processing +of disputes. + +If we allowed participation for disputes for already finalized candidates, the +above spam protection mechanisms would be insufficient/relying 100% on full and +quick disabling of spamming validators. + +## Database Schema + +We use an underlying Key-Value database where we assume we have the following operations available: + * `write(key, value)` + * `read(key) -> Option` + * `iter_with_prefix(prefix) -> Iterator<(key, value)>` - gives all keys and values in + lexicographical order where the key starts with `prefix`. + +We use this database to encode the following schema: + +```rust +("candidate-votes", SessionIndex, CandidateHash) -> Option +"recent-disputes" -> RecentDisputes +"earliest-session" -> Option +``` + +The meta information that we track per-candidate is defined as the `CandidateVotes` struct. +This draws on the [dispute statement types][DisputeTypes] + +```rust +/// Tracked votes on candidates, for the purposes of dispute resolution. +pub struct CandidateVotes { + /// The receipt of the candidate itself. + pub candidate_receipt: CandidateReceipt, + /// Votes of validity, sorted by validator index. + pub valid: Vec<(ValidDisputeStatementKind, ValidatorIndex, ValidatorSignature)>, + /// Votes of invalidity, sorted by validator index. + pub invalid: Vec<(InvalidDisputeStatementKind, ValidatorIndex, ValidatorSignature)>, +} + +/// The mapping for recent disputes; any which have not yet been pruned for being ancient. +pub type RecentDisputes = std::collections::BTreeMap<(SessionIndex, CandidateHash), DisputeStatus>; + +/// The status of dispute. This is a state machine which can be altered by the +/// helper methods. +pub enum DisputeStatus { + /// The dispute is active and unconcluded. + Active, + /// The dispute has been concluded in favor of the candidate + /// since the given timestamp. + ConcludedFor(Timestamp), + /// The dispute has been concluded against the candidate + /// since the given timestamp. + /// + /// This takes precedence over `ConcludedFor` in the case that + /// both are true, which is impossible unless a large amount of + /// validators are participating on both sides. + ConcludedAgainst(Timestamp), + /// Dispute has been confirmed (more than `byzantine_threshold` have already participated/ or + /// we have seen the candidate included already/participated successfully ourselves). + Confirmed, +} +``` + +## Protocol + +Input: [`DisputeCoordinatorMessage`][DisputeCoordinatorMessage] + +Output: + - [`RuntimeApiMessage`][RuntimeApiMessage] + +## Functionality + +This assumes a constant `DISPUTE_WINDOW: SessionWindowSize`. This should correspond to at least 1 +day. + +Ephemeral in-memory state: + +```rust +struct State { + keystore: Arc, + rolling_session_window: RollingSessionWindow, + highest_session: SessionIndex, + spam_slots: SpamSlots, + participation: Participation, + ordering_provider: OrderingProvider, + participation_receiver: WorkerMessageReceiver, + metrics: Metrics, + // This tracks only rolling session window failures. + // It can be a `Vec` if the need to track more arises. + error: Option, + /// Latest relay blocks that have been successfully scraped. + last_scraped_blocks: LruCache, +} +``` + +### On startup + +When the subsystem is initialised it waits for a new leaf (message +`OverseerSignal::ActiveLeaves`). The leaf is used to initialise a +`RollingSessionWindow` instance (contains leaf hash and `DISPUTE_WINDOW` which +is a constant). + +Next the active disputes are loaded from the DB and initialize spam slots +accordingly, then for each loaded dispute, we either send a +`DisputeDistribution::SendDispute` if there is a local vote from us available or +if there is none and participation is in order, we push the dispute to +participation. + +### The main loop + +Just after the subsystem initialisation the main loop (`fn run_until_error()`) runs until +`OverseerSignal::Conclude` signal is received. Before executing the actual main loop the leaf and +the participations, obtained during startup are enqueued for processing. If there is capacity (the +number of running participations is less than `MAX_PARALLEL_PARTICIPATIONS`) participation jobs are +started (`func participate`). Finally the component waits for messages from Overseer. The behaviour +on each message is described in the following subsections. + +### On `OverseerSignal::ActiveLeaves` + +Initiates processing via the `Participation` module and updates the internal state of the subsystem. +More concretely: + +* Passes the `ActiveLeavesUpdate` message to the ordering provider. +* Updates the session info cache. +* Updates `self.highest_session`. +* Prunes old spam slots in case the session window has advanced. +* Scrapes on chain votes. + +### On `MuxedMessage::Participation` + +This message is sent from `Participatuion` module and indicates a processed dispute participation. +It's the result of the processing job initiated with `OverseerSignal::ActiveLeaves`. The subsystem +issues a `DisputeMessage` with the result. + +### On `OverseerSignal::Conclude` + +Exit gracefully. + +### On `OverseerSignal::BlockFinalized` + +Performs cleanup of the finalized candidate. + +### On `DisputeCoordinatorMessage::ImportStatements` + +Import statements by validators are processed in `fn handle_import_statements()`. The function has +got three main responsibilities: +* Initiate participation in disputes and sending out of any existing own + approval vote in case of a raised dispute. +* Persist all fresh votes in the database. Fresh votes in this context means votes that are not + already processed by the node. +* Spam protection on all invalid (`DisputeStatement::Invalid`) votes. Please check the SpamSlots + section for details on how spam protection works. + +### On `DisputeCoordinatorMessage::RecentDisputes` + +Returns all recent disputes saved in the DB. + +### On `DisputeCoordinatorMessage::ActiveDisputes` + +Returns all recent disputes concluded within the last `ACTIVE_DURATION_SECS` . + +### On `DisputeCoordinatorMessage::QueryCandidateVotes` + +Loads `candidate-votes` for every `(SessionIndex, CandidateHash)` in the input query and returns +data within each `CandidateVote`. If a particular `candidate-vote` is missing, that particular +request is omitted from the response. + +### On `DisputeCoordinatorMessage::IssueLocalStatement` + +Executes `fn issue_local_statement()` which performs the following operations: + +* Deconstruct into parts `{ session_index, candidate_hash, candidate_receipt, is_valid }`. +* Construct a [`DisputeStatement`][DisputeStatement] based on `Valid` or `Invalid`, depending on the + parameterization of this routine. +* Sign the statement with each key in the `SessionInfo`'s list of parachain validation keys which is + present in the keystore, except those whose indices appear in `voted_indices`. This will typically + just be one key, but this does provide some future-proofing for situations where the same node may + run on behalf multiple validators. At the time of writing, this is not a use-case we support as + other subsystems do not invariably provide this guarantee. +* Write statement to DB. +* Send a `DisputeDistributionMessage::SendDispute` message to get the vote distributed to other + validators. + +### On `DisputeCoordinatorMessage::DetermineUndisputedChain` + +Executes `fn determine_undisputed_chain()` which performs the following: + +* Load `"recent-disputes"`. +* Deconstruct into parts `{ base_number, block_descriptions, rx }` +* Starting from the beginning of `block_descriptions`: + 1. Check the `RecentDisputes` for a dispute of each candidate in the block description. + 1. If there is a dispute which is active or concluded negative, exit the loop. +* For the highest index `i` reached in the `block_descriptions`, send `(base_number + i + 1, + block_hash)` on the channel, unless `i` is 0, in which case `None` should be sent. The + `block_hash` is determined by inspecting `block_descriptions[i]`. + +[DisputeTypes]: ../../types/disputes.md +[DisputeStatement]: ../../types/disputes.md#disputestatement +[DisputeCoordinatorMessage]: ../../types/overseer-protocol.md#dispute-coordinator-message +[RuntimeApiMessage]: ../../types/overseer-protocol.md#runtime-api-message diff --git a/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-distribution.md b/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-distribution.md new file mode 100644 index 0000000000000000000000000000000000000000..3a45f53c45d7905a5c0b9ff3fe1a8ae299b211f9 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-distribution.md @@ -0,0 +1,429 @@ +# Dispute Distribution + +Dispute distribution is responsible for ensuring all concerned validators will +be aware of a dispute and have the relevant votes. + +## Design Goals + +This design should result in a protocol that is: + +- resilient to nodes being temporarily unavailable +- make sure nodes are aware of a dispute quickly +- relatively efficient, should not cause too much stress on the network +- be resilient when it comes to spam +- be simple and boring: We want disputes to work when they happen + +## Protocol + +Distributing disputes needs to be a reliable protocol. We would like to make as +sure as possible that our vote got properly delivered to all concerned +validators. For this to work, this subsystem won't be gossip based, but instead +will use a request/response protocol for application level confirmations. The +request will be the payload (the actual votes/statements), the response will +be the confirmation. See [below][#wire-format]. + +### Input + +[`DisputeDistributionMessage`][DisputeDistributionMessage] + +### Output + +- [`DisputeCoordinatorMessage::ActiveDisputes`][DisputeCoordinatorMessage] +- [`DisputeCoordinatorMessage::ImportStatements`][DisputeCoordinatorMessage] +- [`DisputeCoordinatorMessage::QueryCandidateVotes`][DisputeCoordinatorMessage] +- [`RuntimeApiMessage`][RuntimeApiMessage] + +### Wire format + +#### Disputes + +Protocol: `"///send_dispute/1"` + +Request: + +```rust +struct DisputeRequest { + /// The candidate being disputed. + pub candidate_receipt: CandidateReceipt, + + /// The session the candidate appears in. + pub session_index: SessionIndex, + + /// The invalid vote data that makes up this dispute. + pub invalid_vote: InvalidDisputeVote, + + /// The valid vote that makes this dispute request valid. + pub valid_vote: ValidDisputeVote, +} + +/// Any invalid vote (currently only explicit). +pub struct InvalidDisputeVote { + /// The voting validator index. + pub validator_index: ValidatorIndex, + + /// The validator signature, that can be verified when constructing a + /// `SignedDisputeStatement`. + pub signature: ValidatorSignature, + + /// Kind of dispute statement. + pub kind: InvalidDisputeStatementKind, +} + +/// Any valid vote (backing, approval, explicit). +pub struct ValidDisputeVote { + /// The voting validator index. + pub validator_index: ValidatorIndex, + + /// The validator signature, that can be verified when constructing a + /// `SignedDisputeStatement`. + pub signature: ValidatorSignature, + + /// Kind of dispute statement. + pub kind: ValidDisputeStatementKind, +} +``` + +Response: + +```rust +enum DisputeResponse { + Confirmed +} +``` + +#### Vote Recovery + +Protocol: `"///req_votes/1"` + +```rust +struct IHaveVotesRequest { + candidate_hash: CandidateHash, + session: SessionIndex, + valid_votes: Bitfield, + invalid_votes: Bitfield, +} + +``` + +Response: + +```rust +struct VotesResponse { + /// All votes we have, but the requester was missing. + missing: Vec<(DisputeStatement, ValidatorIndex, ValidatorSignature)>, +} +``` + +## Starting a Dispute + +A dispute is initiated once a node sends the first `DisputeRequest` wire message, +which must contain an "invalid" vote and a "valid" vote. + +The dispute distribution subsystem can get instructed to send that message out to +all concerned validators by means of a `DisputeDistributionMessage::SendDispute` +message. That message must contain an invalid vote from the local node and some +valid one, e.g. a backing statement. + +We include a valid vote as well, so any node regardless of whether it is synced +with the chain or not or has seen backing/approval vote can see that there are +conflicting votes available, hence we have a valid dispute. Nodes will still +need to check whether the disputing votes are somewhat current and not some +stale ones. + +## Participating in a Dispute + +Upon receiving a `DisputeRequest` message, a dispute distribution will trigger the +import of the received votes via the dispute coordinator +(`DisputeCoordinatorMessage::ImportStatements`). The dispute coordinator will +take care of participating in that dispute if necessary. Once it is done, the +coordinator will send a `DisputeDistributionMessage::SendDispute` message to dispute +distribution. From here, everything is the same as for starting a dispute, +except that if the local node deemed the candidate valid, the `SendDispute` +message will contain a valid vote signed by our node and will contain the +initially received `Invalid` vote. + +Note, that we rely on `dispute-coordinator` to check validity of a dispute for spam +protection (see below). + +## Sending of messages + +Starting and participating in a dispute are pretty similar from the perspective +of dispute distribution. Once we receive a `SendDispute` message, we try to make +sure to get the data out. We keep track of all the parachain validators that +should see the message, which are all the parachain validators of the session +where the dispute happened as they will want to participate in the dispute. In +addition we also need to get the votes out to all authorities of the current +session (which might be the same or not and may change during the dispute). +Those authorities will not participate in the dispute, but need to see the +statements so they can include them in blocks. + +### Reliability + +We only consider a message transmitted, once we received a confirmation message. +If not, we will keep retrying getting that message out as long as the dispute is +deemed alive. To determine whether a dispute is still alive we will ask the +`dispute-coordinator` for a list of all still active disputes via a +`DisputeCoordinatorMessage::ActiveDisputes` message before each retry run. Once +a dispute is no longer live, we will clean up the state accordingly. + +### Order + +We assume `SendDispute` messages are coming in an order of importance, hence +`dispute-distribution` will make sure to send out network messages in the same +order, even on retry. + +### Rate Limit + +For spam protection (see below), we employ an artificial rate limiting on sending +out messages in order to not hit the rate limit at the receiving side, which +would result in our messages getting dropped and our reputation getting reduced. + +## Reception + +As we shall see the receiving side is mostly about handling spam and ensuring +the dispute-coordinator learns about disputes as fast as possible. + +Goals for the receiving side: + +1. Get new disputes to the dispute-coordinator as fast as possible, so + prioritization can happen properly. +2. Batch votes per disputes as much as possible for good import performance. +3. Prevent malicious nodes exhausting node resources by sending lots of messages. +4. Prevent malicious nodes from sending so many messages/(fake) disputes, + preventing us from concluding good ones. +5. Limit ability of malicious nodes of delaying the vote import due to batching + logic. + +Goal 1 and 2 seem to be conflicting, but an easy compromise is possible: When +learning about a new dispute, we will import the vote immediately, making the +dispute coordinator aware and also getting immediate feedback on the validity. +Then if valid we can batch further incoming votes, with less time constraints as +the dispute-coordinator already knows about the dispute. + +Goal 3 and 4 are obviously very related and both can easily be solved via rate +limiting as we shall see below. Rate limits should already be implemented at the +substrate level, but [are not](https://github.com/paritytech/substrate/issues/7750) +at the time of writing. But even if they were, the enforced substrate limits would +likely not be configurable and thus would still be to high for our needs as we can +rely on the following observations: + +1. Each honest validator will only send one message (apart from duplicates on + timeout) per candidate/dispute. +2. An honest validator needs to fully recover availability and validate the + candidate for casting a vote. + +With these two observations, we can conclude that honest validators will usually +not send messages at a high rate. We can therefore enforce conservative rate +limits and thus minimize harm spamming malicious nodes can have. + +Before we dive into how rate limiting solves all spam issues elegantly, let's +discuss that honest behaviour further: + +What about session changes? Here we might have to inform a new validator set of +lots of already existing disputes at once. + +With observation 1) and a rate limit that is per peer, we are still good: + +Let's assume a rate limit of one message per 200ms per sender. This means 5 +messages from each validator per second. 5 messages means 5 disputes! +Conclusively, we will be able to conclude 5 disputes per second - no matter what +malicious actors are doing. This is assuming dispute messages are sent ordered, +but even if not perfectly ordered: On average it will be 5 disputes per second. + +This is good enough! All those disputes are valid ones and will result in +slashing and disabling of validators. Let's assume all of them conclude `valid`, +and we disable validators only after 100 raised concluding valid disputes, we +would still start disabling misbehaving validators in only 20 seconds. + +One could also think that in addition participation is expected to take longer, +which means on average we can import/conclude disputes faster than they are +generated - regardless of dispute spam. Unfortunately this is not necessarily +true: There might be parachains with very light load where recovery and +validation can be accomplished very quickly - maybe faster than we can import +those disputes. + +This is probably an argument for not imposing a too low rate limit, although the +issue is more general: Even without any rate limit, if an attacker generates +disputes at a very high rate, nodes will be having trouble keeping participation +up, hence the problem should be mitigated at a [more fundamental +layer](https://github.com/paritytech/polkadot/issues/5898). + +For nodes that have been offline for a while, the same argument as for session +changes holds, but matters even less: We assume 2/3 of nodes to be online, so +even if the worst case 1/3 offline happens and they could not import votes fast +enough (as argued above, they in fact can) it would not matter for consensus. + +### Rate Limiting + +As suggested previously, rate limiting allows to mitigate all threats that come +from malicious actors trying to overwhelm the system in order to get away without +a slash, when it comes to dispute-distribution. In this section we will explain +how in greater detail. + +The idea is to open a queue with limited size for each peer. We will process +incoming messages as fast as we can by doing the following: + +1. Check that the sending peer is actually a valid authority - otherwise drop + message and decrease reputation/disconnect. +2. Put message on the peer's queue, if queue is full - drop it. + +Every `RATE_LIMIT` seconds (or rather milliseconds), we pause processing +incoming requests to go a full circle and process one message from each queue. +Processing means `Batching` as explained in the next section. + +### Batching + +To achieve goal 2 we will batch incoming votes/messages together before passing +them on as a single batch to the `dispute-coordinator`. To adhere to goal 1 as +well, we will do the following: + +1. For an incoming message, we check whether we have an existing batch for that + candidate, if not we import directly to the dispute-coordinator, as we have + to assume this is concerning a new dispute. +2. We open a batch and start collecting incoming messages for that candidate, + instead of immediately forwarding. +4. We keep collecting votes in the batch until we receive less than + `MIN_KEEP_BATCH_ALIVE_VOTES` unique votes in the last `BATCH_COLLECTING_INTERVAL`. This is + important to accommodate for goal 5 and also 3. +5. We send the whole batch to the dispute-coordinator. + +This together with rate limiting explained above ensures we will be able to +process valid disputes: We can limit the number of simultaneous existing batches +to some high value, but can be rather certain that this limit will never be +reached - hence we won't drop valid disputes: + +Let's assume `MIN_KEEP_BATCH_ALIVE_VOTES` is 10, `BATCH_COLLECTING_INTERVAL` +is `500ms` and above `RATE_LIMIT` is `100ms`. 1/3 of validators are malicious, +so for 1000 this means around 330 malicious actors worst case. + +All those actors can send a message every `100ms`, that is 10 per second. This +means at the begining of an attack they can open up around 3300 batches. Each +containing two votes. So memory usage is still negligible. In reality it is even +less, as we also demand 10 new votes to trickle in per batch in order to keep it +alive, every `500ms`. Hence for the first second, each batch requires 20 votes +each. Each message is 2 votes, so this means 10 messages per batch. Hence to +keep those batches alive 10 attackers are needed for each batch. This reduces +the number of opened batches by a factor of 10: So we only have 330 batches in 1 +second - each containing 20 votes. + +The next second: In order to further grow memory usage, attackers have to +maintain 10 messages per batch and second. Number of batches equals the number +of attackers, each has 10 messages per second, all are needed to maintain the +batches in memory. Therefore we have a hard cap of around 330 (number of +malicious nodes) open batches. Each can be filled with number of malicious +actor's votes. So 330 batches with each 330 votes: Let's assume approximately 100 +bytes per signature/vote. This results in a worst case memory usage of 330 * 330 +* 100 ~= 10 MiB. + +For 10_000 validators, we are already in the Gigabyte range, which means that +with a validator set that large we might want to be more strict with the rate limit or +require a larger rate of incoming votes per batch to keep them alive. + +For a thousand validators a limit on batches of around 1000 should never be +reached in practice. Hence due to rate limiting we have a very good chance to +not ever having to drop a potential valid dispute due to some resource limit. + +Further safe guards are possible: The dispute-coordinator actually +confirms/denies imports. So once we receive a denial by the dispute-coordinator +for the initial imported votes, we can opt into flushing the batch immediately +and importing the votes. This swaps memory usage for more CPU usage, but if that +import is deemed invalid again we can immediately decrease the reputation of the +sending peers, so this should be a net win. For the time being we punt on this +for simplicity. + +Instead of filling batches to maximize memory usage, attackers could also try to +overwhelm the dispute coordinator by only sending votes for new candidates all +the time. This attack vector is mitigated also by above rate limit and +decreasing the peer's reputation on denial of the invalid imports by the +coordinator. + +### Node Startup + +Nothing special happens on node startup. We expect the `dispute-coordinator` to +inform us about any ongoing disputes via `SendDispute` messages. + +## Backing and Approval Votes + +Backing and approval votes get imported when they arrive/are created via the +dispute coordinator by corresponding subsystems. + +We assume that under normal operation each node will be aware of backing and +approval votes and optimize for that case. Nevertheless we want disputes to +conclude fast and reliable, therefore if a node is not aware of backing/approval +votes it can request the missing votes from the node that informed it about the +dispute (see [Resiliency](#Resiliency]) + +## Resiliency + +The above protocol should be sufficient for most cases, but there are certain +cases we also want to have covered: + +- Non validator nodes might be interested in ongoing voting, even before it is + recorded on chain. +- Nodes might have missed votes, especially backing or approval votes. + Recovering them from chain is difficult and expensive, due to runtime upgrades + and untyped extrinsics. +- More importantly, on era changes the new authority set, from the perspective + of approval-voting have no need to see "old" approval votes, hence they might + not see them, can therefore not import them into the dispute coordinator and + therefore no authority will put them on chain. + +To cover those cases, we introduce a second request/response protocol, which can +be handled on a lower priority basis as the one above. It consists of the +request/response messages as described in the [protocol +section][#vote-recovery]. + +Nodes may send those requests to validators, if they feel they are missing +votes. E.g. after some timeout, if no majority was reached yet in their point of +view or if they are not aware of any backing/approval votes for a received +disputed candidate. + +The receiver of a `IHaveVotesRequest` message will do the following: + +1. See if the sender is missing votes we are aware of - if so, respond with + those votes. +2. Check whether the sender knows about any votes, we don't know about and if so + send a `IHaveVotesRequest` request back, with our knowledge. +3. Record the peer's knowledge. + +When to send `IHaveVotesRequest` messages: + +1. Whenever we are asked to do so via + `DisputeDistributionMessage::FetchMissingVotes`. +2. Approximately once per block to some random validator as long as the dispute + is active. + +Spam considerations: Nodes want to accept those messages once per validator and +per slot. They are free to drop more frequent requests or requests for stale +data. Requests coming from non validator nodes, can be handled on a best effort +basis. + +## Considerations + +Dispute distribution is critical. We should keep track of available validator +connections and issue warnings if we are not connected to a majority of +validators. We should also keep track of failed sending attempts and log +warnings accordingly. As disputes are rare and TCP is a reliable protocol, +probably each failed attempt should trigger a warning in logs and also logged +into some Prometheus metric. + +## Disputes for non available candidates + +If deemed necessary we can later on also support disputes for non available +candidates, but disputes for those cases have totally different requirements. + +First of all such disputes are not time critical. We just want to have +some offender slashed at some point, but we have no risk of finalizing any bad +data. + +Second, as we won't have availability for such data, the node that initiated the +dispute will be responsible for providing the disputed data initially. Then +nodes which did the check already are also providers of the data, hence +distributing load and making prevention of the dispute from concluding harder +and harder over time. Assuming an attacker can not DoS a node forever, the +dispute will succeed eventually, which is all that matters. And again, even if +an attacker managed to prevent such a dispute from happening somehow, there is +no real harm done: There was no serious attack to begin with. + +[DisputeDistributionMessage]: ../../types/overseer-protocol.md#dispute-distribution-message +[RuntimeApiMessage]: ../../types/overseer-protocol.md#runtime-api-message diff --git a/polkadot/roadmap/implementers-guide/src/node/grandpa-voting-rule.md b/polkadot/roadmap/implementers-guide/src/node/grandpa-voting-rule.md new file mode 100644 index 0000000000000000000000000000000000000000..5e608ccfd62e7d37a9a1c7cdc45130b5a535e9c3 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/grandpa-voting-rule.md @@ -0,0 +1,10 @@ +# GRANDPA Voting Rule + +Specifics on the motivation and types of constraints we apply to the GRANDPA voting logic as well as the definitions of **viable** and **finalizable** blocks can be found in the [Chain Selection Protocol](../protocol-chain-selection.md) section. +The subsystem which provides us with viable leaves is the [Chain Selection Subsystem](utility/chain-selection.md). + +GRANDPA's regular voting rule is for each validator to select the longest chain they are aware of. GRANDPA proceeds in rounds, collecting information from all online validators and determines the blocks that a supermajority of validators all have in common with each other. + +The low-level GRANDPA logic will provide us with a **required block**. We can find the best leaf containing that block in its chain with the [`ChainSelectionMessage::BestLeafContaining`](../types/overseer-protocol.md#chain-selection-message). If the result is `None`, then we will simply cast a vote on the required block. + +The **viable** leaves provided from the chain selection subsystem are not necessarily **finalizable**, so we need to perform further work to discover the finalizable ancestor of the block. The first constraint is to avoid voting on any unapproved block. The highest approved ancestor of a given block can be determined by querying the Approval Voting subsystem via the [`ApprovalVotingMessage::ApprovedAncestor`](../types/overseer-protocol.md#approval-voting) message. If the response is `Some`, we continue and apply the second constraint. The second constraint is to avoid voting on any block containing a candidate undergoing an active dispute. The list of block hashes and candidates returned from `ApprovedAncestor` should be reversed, and passed to the [`DisputeCoordinatorMessage::DetermineUndisputedChain`](../types/overseer-protocol.md#dispute-coordinator-message) to determine the **finalizable** block which will be our eventual vote. diff --git a/polkadot/roadmap/implementers-guide/src/node/overseer.md b/polkadot/roadmap/implementers-guide/src/node/overseer.md new file mode 100644 index 0000000000000000000000000000000000000000..21300d9098a2949b21b5ac8f9efd54cd5dd37472 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/overseer.md @@ -0,0 +1,98 @@ +# Overseer + +The overseer is responsible for these tasks: + +1. Setting up, monitoring, and handing failure for overseen subsystems. +1. Providing a "heartbeat" of which relay-parents subsystems should be working on. +1. Acting as a message bus between subsystems. + +The hierarchy of subsystems: + +```text ++--------------+ +------------------+ +--------------------+ +| | | |----> Subsystem A | +| Block Import | | | +--------------------+ +| Events |------> | +--------------------+ ++--------------+ | |----> Subsystem B | + | Overseer | +--------------------+ ++--------------+ | | +--------------------+ +| | | |----> Subsystem C | +| Finalization |------> | +--------------------+ +| Events | | | +--------------------+ +| | | |----> Subsystem D | ++--------------+ +------------------+ +--------------------+ + +``` + +The overseer determines work to do based on block import events and block finalization events. It does this by keeping track of the set of relay-parents for which work is currently being done. This is known as the "active leaves" set. It determines an initial set of active leaves on startup based on the data on-disk, and uses events about blockchain import to update the active leaves. Updates lead to [`OverseerSignal`](../types/overseer-protocol.md#overseer-signal)`::ActiveLeavesUpdate` being sent according to new relay-parents, as well as relay-parents to stop considering. Block import events inform the overseer of leaves that no longer need to be built on, now that they have children, and inform us to begin building on those children. Block finalization events inform us when we can stop focusing on blocks that appear to have been orphaned. + +The overseer is also responsible for tracking the freshness of active leaves. Leaves are fresh when they're encountered for the first time, and stale when they're encountered for subsequent times. This can occur after chain reversions or when the fork-choice rule abandons some chain. This distinction is used to manage **Reversion Safety**. Consensus messages are often localized to a specific relay-parent, and it is often a misbehavior to equivocate or sign two conflicting messages. When reverting the chain, we may begin work on a leaf that subsystems have already signed messages for. Subsystems which need to account for reversion safety should avoid performing work on stale leaves. + +The overseer's logic can be described with these functions: + +## On Startup + +* Start all subsystems +* Determine all blocks of the blockchain that should be built on. This should typically be the head of the best fork of the chain we are aware of. Sometimes add recent forks as well. +* Send an `OverseerSignal::ActiveLeavesUpdate` to all subsystems with `activated` containing each of these blocks. +* Begin listening for block import and finality events + +## On Block Import Event + +* Apply the block import event to the active leaves. A new block should lead to its addition to the active leaves set and its parent being deactivated. +* Mark any stale leaves as stale. The overseer should track all leaves it activates to determine whether leaves are fresh or stale. +* Send an `OverseerSignal::ActiveLeavesUpdate` message to all subsystems containing all activated and deactivated leaves. +* Ensure all `ActiveLeavesUpdate` messages are flushed before resuming activity as a message router. + +> TODO: in the future, we may want to avoid building on too many sibling blocks at once. the notion of a "preferred head" among many competing sibling blocks would imply changes in our "active leaves" update rules here + +## On Finalization Event + +* Note the height `h` of the newly finalized block `B`. +* Prune all leaves from the active leaves which have height `<= h` and are not `B`. +* Issue `OverseerSignal::ActiveLeavesUpdate` containing all deactivated leaves. + +## On Subsystem Failure + +Subsystems are essential tasks meant to run as long as the node does. Subsystems can spawn ephemeral work in the form of jobs, but the subsystems themselves should not go down. If a subsystem goes down, it will be because of a critical error that should take the entire node down as well. + +## Communication Between Subsystems + +When a subsystem wants to communicate with another subsystem, or, more typically, a job within a subsystem wants to communicate with its counterpart under another subsystem, that communication must happen via the overseer. Consider this example where a job on subsystem A wants to send a message to its counterpart under subsystem B. This is a realistic scenario, where you can imagine that both jobs correspond to work under the same relay-parent. + +```text + +--------+ +--------+ + | | | | + |Job A-1 | (sends message) (receives message) |Job B-1 | + | | | | + +----|---+ +----^---+ + | +------------------------------+ ^ + v | | | ++---------v---------+ | | +---------|---------+ +| | | | | | +| Subsystem A | | Overseer / Message | | Subsystem B | +| -------->> Bus -------->> | +| | | | | | ++-------------------+ | | +-------------------+ + | | + +------------------------------+ +``` + +First, the subsystem that spawned a job is responsible for handling the first step of the communication. The overseer is not aware of the hierarchy of tasks within any given subsystem and is only responsible for subsystem-to-subsystem communication. So the sending subsystem must pass on the message via the overseer to the receiving subsystem, in such a way that the receiving subsystem can further address the communication to one of its internal tasks, if necessary. + +This communication prevents a certain class of race conditions. When the Overseer determines that it is time for subsystems to begin working on top of a particular relay-parent, it will dispatch a `ActiveLeavesUpdate` message to all subsystems to do so, and those messages will be handled asynchronously by those subsystems. Some subsystems will receive those messsages before others, and it is important that a message sent by subsystem A after receiving `ActiveLeavesUpdate` message will arrive at subsystem B after its `ActiveLeavesUpdate` message. If subsystem A maintained an independent channel with subsystem B to communicate, it would be possible for subsystem B to handle the side message before the `ActiveLeavesUpdate` message, but it wouldn't have any logical course of action to take with the side message - leading to it being discarded or improperly handled. Well-architectured state machines should have a single source of inputs, so that is what we do here. + +One exception is reasonable to make for responses to requests. A request should be made via the overseer in order to ensure that it arrives after any relevant `ActiveLeavesUpdate` message. A subsystem issuing a request as a result of a `ActiveLeavesUpdate` message can safely receive the response via a side-channel for two reasons: + +1. It's impossible for a request to be answered before it arrives, it is provable that any response to a request obeys the same ordering constraint. +1. The request was sent as a result of handling a `ActiveLeavesUpdate` message. Then there is no possible future in which the `ActiveLeavesUpdate` message has not been handled upon the receipt of the response. + +So as a single exception to the rule that all communication must happen via the overseer we allow the receipt of responses to requests via a side-channel, which may be established for that purpose. This simplifies any cases where the outside world desires to make a request to a subsystem, as the outside world can then establish a side-channel to receive the response on. + +It's important to note that the overseer is not aware of the internals of subsystems, and this extends to the jobs that they spawn. The overseer isn't aware of the existence or definition of those jobs, and is only aware of the outer subsystems with which it interacts. This gives subsystem implementations leeway to define internal jobs as they see fit, and to wrap a more complex hierarchy of state machines than having a single layer of jobs for relay-parent-based work. Likewise, subsystems aren't required to spawn jobs. Certain types of subsystems, such as those for shared storage or networking resources, won't perform block-based work but would still benefit from being on the Overseer's message bus. These subsystems can just ignore the overseer's signals for block-based work. + +Furthermore, the protocols by which subsystems communicate with each other should be well-defined irrespective of the implementation of the subsystem. In other words, their interface should be distinct from their implementation. This will prevent subsystems from accessing aspects of each other that are beyond the scope of the communication boundary. + +## On shutdown + +Send an `OverseerSignal::Conclude` message to each subsystem and wait some time for them to conclude before hard-exiting. diff --git a/polkadot/roadmap/implementers-guide/src/node/subsystems-and-jobs.md b/polkadot/roadmap/implementers-guide/src/node/subsystems-and-jobs.md new file mode 100644 index 0000000000000000000000000000000000000000..6e3b4cd2d166b820a1084fe1e423886d7d6dea38 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/subsystems-and-jobs.md @@ -0,0 +1,418 @@ +# Subsystems and Jobs + +In this section we define the notions of Subsystems and Jobs. These are guidelines for how we will employ an architecture of hierarchical state machines. We'll have a top-level state machine which oversees the next level of state machines which oversee another layer of state machines and so on. The next sections will lay out these guidelines for what we've called subsystems and jobs, since this model applies to many of the tasks that the Node-side behavior needs to encompass, but these are only guidelines and some Subsystems may have deeper hierarchies internally. + +Subsystems are long-lived worker tasks that are in charge of performing some particular kind of work. All subsystems can communicate with each other via a well-defined protocol. Subsystems can't generally communicate directly, but must coordinate communication through an [Overseer](overseer.md), which is responsible for relaying messages, handling subsystem failures, and dispatching work signals. + +Most work that happens on the Node-side is related to building on top of a specific relay-chain block, which is contextually known as the "relay parent". We call it the relay parent to explicitly denote that it is a block in the relay chain and not on a parachain. We refer to the parent because when we are in the process of building a new block, we don't know what that new block is going to be. The parent block is our only stable point of reference, even though it is usually only useful when it is not yet a parent but in fact a leaf of the block-DAG expected to soon become a parent (because validators are authoring on top of it). Furthermore, we are assuming a forkful blockchain-extension protocol, which means that there may be multiple possible children of the relay-parent. Even if the relay parent has multiple children blocks, the parent of those children is the same, and the context in which those children is authored should be the same. The parent block is the best and most stable reference to use for defining the scope of work items and messages, and is typically referred to by its cryptographic hash. + +Since this goal of determining when to start and conclude work relative to a specific relay-parent is common to most, if not all subsystems, it is logically the job of the Overseer to distribute those signals as opposed to each subsystem duplicating that effort, potentially being out of synchronization with each other. Subsystem A should be able to expect that subsystem B is working on the same relay-parents as it is. One of the Overseer's tasks is to provide this heartbeat, or synchronized rhythm, to the system. + +The work that subsystems spawn to be done on a specific relay-parent is known as a job. Subsystems should set up and tear down jobs according to the signals received from the overseer. Subsystems may share or cache state between jobs. + +Subsystems must be robust to spurious exits. The outputs of the set of subsystems as a whole comprises of signed messages and data committed to disk. Care must be taken to avoid issuing messages that are not substantiated. Since subsystems need to be safe under spurious exits, it is the expected behavior that an `OverseerSignal::Conclude` can just lead to breaking the loop and exiting directly as opposed to waiting for everything to shut down gracefully. + +## Subsystem Message Traffic + +Which subsystems send messages to which other subsystems. + +**Note**: This diagram omits the overseer for simplicity. In fact, all messages are relayed via the overseer. + +**Note**: Messages with a filled diamond arrowhead ("♦") include a `oneshot::Sender` which communicates a response from the recipient. +Messages with an open triangle arrowhead ("Δ") do not include a return sender. + +```dot process +digraph { + rankdir=LR; + node [shape = oval]; + concentrate = true; + + av_store [label = "Availability Store"] + avail_dist [label = "Availability Distribution"] + avail_rcov [label = "Availability Recovery"] + bitf_dist [label = "Bitfield Distribution"] + bitf_sign [label = "Bitfield Signing"] + cand_back [label = "Candidate Backing"] + cand_sel [label = "Candidate Selection"] + cand_val [label = "Candidate Validation"] + chn_api [label = "Chain API"] + coll_gen [label = "Collation Generation"] + coll_prot [label = "Collator Protocol"] + net_brdg [label = "Network Bridge"] + pov_dist [label = "PoV Distribution"] + provisioner [label = "Provisioner"] + runt_api [label = "Runtime API"] + stmt_dist [label = "Statement Distribution"] + + av_store -> runt_api [arrowhead = "diamond", label = "Request::CandidateEvents"] + av_store -> chn_api [arrowhead = "diamond", label = "BlockNumber"] + av_store -> chn_api [arrowhead = "diamond", label = "BlockHeader"] + av_store -> runt_api [arrowhead = "diamond", label = "Request::Validators"] + av_store -> chn_api [arrowhead = "diamond", label = "FinalizedBlockHash"] + + avail_dist -> net_brdg [arrowhead = "onormal", label = "Request::SendValidationMessages"] + avail_dist -> runt_api [arrowhead = "diamond", label = "Request::AvailabilityCores"] + avail_dist -> net_brdg [arrowhead = "onormal", label = "ReportPeer"] + avail_dist -> av_store [arrowhead = "diamond", label = "QueryDataAvailability"] + avail_dist -> av_store [arrowhead = "diamond", label = "QueryChunk"] + avail_dist -> av_store [arrowhead = "diamond", label = "StoreChunk"] + avail_dist -> runt_api [arrowhead = "diamond", label = "Request::Validators"] + avail_dist -> chn_api [arrowhead = "diamond", label = "Ancestors"] + avail_dist -> runt_api [arrowhead = "diamond", label = "Request::SessionIndexForChild"] + + avail_rcov -> net_brdg [arrowhead = "onormal", label = "ReportPeer"] + avail_rcov -> av_store [arrowhead = "diamond", label = "QueryChunk"] + avail_rcov -> net_brdg [arrowhead = "diamond", label = "ConnectToValidators"] + avail_rcov -> net_brdg [arrowhead = "onormal", label = "SendValidationMessage::Chunk"] + avail_rcov -> net_brdg [arrowhead = "onormal", label = "SendValidationMessage::RequestChunk"] + + bitf_dist -> net_brdg [arrowhead = "onormal", label = "ReportPeer"] + bitf_dist -> provisioner [arrowhead = "onormal", label = "ProvisionableData::Bitfield"] + bitf_dist -> net_brdg [arrowhead = "onormal", label = "SendValidationMessage"] + bitf_dist -> net_brdg [arrowhead = "onormal", label = "SendValidationMessage"] + bitf_dist -> runt_api [arrowhead = "diamond", label = "Request::Validatiors"] + bitf_dist -> runt_api [arrowhead = "diamond", label = "Request::SessionIndexForChild"] + + bitf_sign -> av_store [arrowhead = "diamond", label = "QueryChunkAvailability"] + bitf_sign -> runt_api [arrowhead = "diamond", label = "Request::AvailabilityCores"] + bitf_sign -> bitf_dist [arrowhead = "onormal", label = "DistributeBitfield"] + + cand_back -> av_store [arrowhead = "diamond", label = "StoreAvailableData"] + cand_back -> pov_dist [arrowhead = "diamond", label = "FetchPoV"] + cand_back -> cand_val [arrowhead = "diamond", label = "ValidateFromChainState"] + cand_back -> cand_sel [arrowhead = "onormal", label = "Invalid"] + cand_back -> provisioner [arrowhead = "onormal", label = "ProvisionableData::MisbehaviorReport"] + cand_back -> provisioner [arrowhead = "onormal", label = "ProvisionableData::BackedCandidate"] + cand_back -> pov_dist [arrowhead = "onormal", label = "DistributePoV"] + cand_back -> stmt_dist [arrowhead = "onormal", label = "Share"] + + cand_sel -> coll_prot [arrowhead = "diamond", label = "FetchCollation"] + cand_sel -> cand_back [arrowhead = "onormal", label = "Second"] + cand_sel -> coll_prot [arrowhead = "onormal", label = "ReportCollator"] + + cand_val -> runt_api [arrowhead = "diamond", label = "Request::PersistedValidationData"] + cand_val -> runt_api [arrowhead = "diamond", label = "Request::ValidationCode"] + cand_val -> runt_api [arrowhead = "diamond", label = "Request::CheckValidationOutputs"] + + coll_gen -> coll_prot [arrowhead = "onormal", label = "DistributeCollation"] + + coll_prot -> net_brdg [arrowhead = "onormal", label = "ReportPeer"] + coll_prot -> net_brdg [arrowhead = "onormal", label = "Declare"] + coll_prot -> net_brdg [arrowhead = "onormal", label = "AdvertiseCollation"] + coll_prot -> net_brdg [arrowhead = "onormal", label = "Collation"] + coll_prot -> net_brdg [arrowhead = "onormal", label = "RequestCollation"] + coll_prot -> cand_sel [arrowhead = "onormal", label = "Collation"] + + net_brdg -> avail_dist [arrowhead = "onormal", label = "NetworkBridgeUpdate"] + net_brdg -> bitf_dist [arrowhead = "onormal", label = "NetworkBridgeUpdate"] + net_brdg -> pov_dist [arrowhead = "onormal", label = "NetworkBridgeUpdate"] + net_brdg -> stmt_dist [arrowhead = "onormal", label = "NetworkBridgeUpdate"] + net_brdg -> coll_prot [arrowhead = "onormal", label = "NetworkBridgeUpdate"] + + pov_dist -> net_brdg [arrowhead = "onormal", label = "SendValidationMessage"] + pov_dist -> net_brdg [arrowhead = "onormal", label = "ReportPeer"] + + provisioner -> cand_back [arrowhead = "diamond", label = "GetBackedCandidates"] + provisioner -> chn_api [arrowhead = "diamond", label = "BlockNumber"] + + stmt_dist -> net_brdg [arrowhead = "onormal", label = "SendValidationMessage"] + stmt_dist -> net_brdg [arrowhead = "onormal", label = "ReportPeer"] + stmt_dist -> cand_back [arrowhead = "onormal", label = "Statement"] + stmt_dist -> runt_api [arrowhead = "onormal", label = "Request::Validators"] + stmt_dist -> runt_api [arrowhead = "onormal", label = "Request::SessionIndexForChild"] +} +``` + +## The Path to Inclusion (Node Side) + +Let's contextualize that diagram a bit by following a parachain block from its creation through finalization. +Parachains can use completely arbitrary processes to generate blocks. The relay chain doesn't know or care about +the details; each parachain just needs to provide a [collator](collators/collation-generation.md). + +**Note**: Inter-subsystem communications are relayed via the overseer, but that step is omitted here for brevity. + +**Note**: Dashed lines indicate a request/response cycle, where the response is communicated asynchronously via +a oneshot channel. Adjacent dashed lines may be processed in parallel. + +```mermaid +sequenceDiagram + participant Overseer + participant CollationGeneration + participant RuntimeApi + participant CollatorProtocol + + Overseer ->> CollationGeneration: ActiveLeavesUpdate + loop for each activated head + CollationGeneration -->> RuntimeApi: Request availability cores + CollationGeneration -->> RuntimeApi: Request validators + + Note over CollationGeneration: Determine an appropriate ScheduledCore
and OccupiedCoreAssumption + + CollationGeneration -->> RuntimeApi: Request full validation data + + Note over CollationGeneration: Build the collation + + CollationGeneration ->> CollatorProtocol: DistributeCollation + end +``` + +The `DistributeCollation` messages that `CollationGeneration` sends to the `CollatorProtocol` contains +two items: a `CandidateReceipt` and `PoV`. The `CollatorProtocol` is then responsible for distributing +that collation to interested validators. However, not all potential collations are of interest. The +`CandidateSelection` subsystem is responsible for determining which collations are interesting, before +`CollatorProtocol` actually fetches the collation. + +```mermaid +sequenceDiagram + participant CollationGeneration + participant CS as CollatorProtocol::CollatorSide + participant NB as NetworkBridge + participant VS as CollatorProtocol::ValidatorSide + participant CandidateSelection + + CollationGeneration ->> CS: DistributeCollation + CS -->> NB: ConnectToValidators + + Note over CS,NB: This connects to multiple validators. + + CS ->> NB: Declare + NB ->> VS: Declare + + Note over CS: Ensure that the connected validator is among
the para's validator set. Otherwise, skip it. + + CS ->> NB: AdvertiseCollation + NB ->> VS: AdvertiseCollation + + VS ->> CandidateSelection: Collation + + Note over CandidateSelection: Lots of other machinery in play here,
but there are only three outcomes from the
perspective of the `CollatorProtocol`: + + alt happy path + CandidateSelection -->> VS: FetchCollation + Activate VS + VS ->> NB: RequestCollation + NB ->> CS: RequestCollation + CS ->> NB: Collation + NB ->> VS: Collation + Deactivate VS + + else collation invalid or unexpected + CandidateSelection ->> VS: ReportCollator + VS ->> NB: ReportPeer + + else CandidateSelection already selected a different candidate + Note over CandidateSelection: silently drop + end +``` + +Assuming we hit the happy path, flow continues with `CandidateSelection` receiving a `(candidate_receipt, pov)` as +the return value from its +`FetchCollation` request. The only time `CandidateSelection` actively requests a collation is when +it hasn't yet seconded one for some `relay_parent`, and is ready to second. + +```mermaid +sequenceDiagram + participant CS as CandidateSelection + participant CB as CandidateBacking + participant CV as CandidateValidation + participant PV as Provisioner + participant SD as StatementDistribution + participant PD as PoVDistribution + + CS ->> CB: Second + % fn validate_and_make_available + CB -->> CV: ValidateFromChainState + + Note over CB,CV: There's some complication in the source, as
candidates are actually validated in a separate task. + + alt valid + Note over CB: This is where we transform the CandidateReceipt into a CommittedCandidateReceipt + % CandidateBackingJob::sign_import_and_distribute_statement + % CandidateBackingJob::import_statement + CB ->> PV: ProvisionableData::BackedCandidate + % CandidateBackingJob::issue_new_misbehaviors + opt if there is misbehavior to report + CB ->> PV: ProvisionableData::MisbehaviorReport + end + % CandidateBackingJob::distribute_signed_statement + CB ->> SD: Share + % CandidateBackingJob::distribute_pov + CB ->> PD: DistributePoV + else invalid + CB ->> CS: Invalid + end +``` + +At this point, you'll see that control flows in two directions: to `StatementDistribution` to distribute +the `SignedStatement`, and to `PoVDistribution` to distribute the `PoV`. However, that's largely a mirage: +while the initial implementation distributes `PoV`s by gossip, that's inefficient, and will be replaced +with a system which fetches `PoV`s only when actually necessary. + +> TODO: figure out more precisely the current status and plans; write them up + +Therefore, we'll follow the `SignedStatement`. The `StatementDistribution` subsystem is largely concerned +with implementing a gossip protocol: + +```mermaid +sequenceDiagram + participant SD as StatementDistribution + participant NB as NetworkBridge + + alt On receipt of a
SignedStatement from CandidateBacking + % fn circulate_statement_and_dependents + SD ->> NB: SendValidationMessage + + Note right of NB: Bridge sends validation message to all appropriate peers + else On receipt of peer validation message + NB ->> SD: NetworkBridgeUpdate + + % fn handle_incoming_message + alt if we aren't already aware of the relay parent for this statement + SD ->> NB: ReportPeer + end + + % fn circulate_statement + opt if we know of peers who haven't seen this message, gossip it + SD ->> NB: SendValidationMessage + end + end +``` + +But who are these `Listener`s who've asked to be notified about incoming `SignedStatement`s? +Nobody, as yet. + +Let's pick back up with the PoV Distribution subsystem. + +```mermaid +sequenceDiagram + participant CB as CandidateBacking + participant PD as PoVDistribution + participant Listener + participant NB as NetworkBridge + + CB ->> PD: DistributePoV + + Note over PD,Listener: Various subsystems can register listeners for when PoVs arrive + + loop for each Listener + PD ->> Listener: Arc + end + + Note over PD: Gossip to connected peers + + PD ->> NB: SendPoV + + Note over PD,NB: On receipt of a network PoV, PovDistribution forwards it to each Listener.
It also penalizes bad gossipers. +``` + +Unlike in the case of `StatementDistribution`, there is another subsystem which in various circumstances +already registers a listener to be notified when a new `PoV` arrives: `CandidateBacking`. Note that this +is the second time that `CandidateBacking` has gotten involved. The first instance was from the perspective +of the validator choosing to second a candidate via its `CandidateSelection` subsystem. This time, it's +from the perspective of some other validator, being informed that this foreign `PoV` has been received. + +```mermaid +sequenceDiagram + participant SD as StatementDistribution + participant CB as CandidateBacking + participant PD as PoVDistribution + participant AS as AvailabilityStore + + SD ->> CB: Statement + % CB::maybe_validate_and_import => CB::kick_off_validation_work + CB -->> PD: FetchPoV + Note over CB,PD: This call creates the Listener from the previous diagram + + CB ->> AS: StoreAvailableData +``` + +At this point, things have gone a bit nonlinear. Let's pick up the thread again with `BitfieldSigning`. As +the `Overseer` activates each relay parent, it starts a `BitfieldSigningJob` which operates on an extremely +simple metric: after creation, it immediately goes to sleep for 1.5 seconds. On waking, it records the state +of the world pertaining to availability at that moment. + +```mermaid +sequenceDiagram + participant OS as Overseer + participant BS as BitfieldSigning + participant RA as RuntimeApi + participant AS as AvailabilityStore + participant BD as BitfieldDistribution + + OS ->> BS: ActiveLeavesUpdate + loop for each activated relay parent + Note over BS: Wait 1.5 seconds + BS -->> RA: Request::AvailabilityCores + loop for each availability core + BS -->> AS: QueryChunkAvailability + end + BS ->> BD: DistributeBitfield + end +``` + +`BitfieldDistribution` is, like the other `*Distribution` subsystems, primarily interested in implementing +a peer-to-peer gossip network propagating its particular messages. However, it also serves as an essential +relay passing the message along. + +```mermaid +sequenceDiagram + participant BS as BitfieldSigning + participant BD as BitfieldDistribution + participant NB as NetworkBridge + participant PV as Provisioner + + BS ->> BD: DistributeBitfield + BD ->> PV: ProvisionableData::Bitfield + BD ->> NB: SendValidationMessage::BitfieldDistribution::Bitfield +``` + +We've now seen the message flow to the `Provisioner`: both `CandidateBacking` and `BitfieldDistribution` +contribute provisionable data. Now, let's look at that subsystem. + +Much like the `BitfieldSigning` subsystem, the `Provisioner` creates a new job for each newly-activated +leaf, and starts a timer. Unlike `BitfieldSigning`, we won't depict that part of the process, because +the `Provisioner` also has other things going on. + +```mermaid +sequenceDiagram + participant A as Arbitrary + participant PV as Provisioner + participant CB as CandidateBacking + participant BD as BitfieldDistribution + participant RA as RuntimeApi + participant PI as ParachainsInherentDataProvider + + alt receive provisionable data + alt + CB ->> PV: ProvisionableData + else + BD ->> PV: ProvisionableData + end + + loop over stored Senders + PV ->> A: ProvisionableData + end + + Note over PV: store bitfields and backed candidates + else receive request for inherent data + PI ->> PV: RequestInherentData + alt we have already constructed the inherent data + PV ->> PI: send the inherent data + else we have not yet constructed the inherent data + Note over PV,PI: Store the return sender without sending immediately + end + else timer times out + note over PV: Waited 2 seconds + PV -->> RA: RuntimeApiRequest::AvailabilityCores + Note over PV: construct and store the inherent data + loop over stored inherent data requests + PV ->> PI: (SignedAvailabilityBitfields, BackedCandidates) + end + end +``` + +In principle, any arbitrary subsystem could send a `RequestInherentData` to the `Provisioner`. In practice, +only the `ParachainsInherentDataProvider` does so. + +The tuple `(SignedAvailabilityBitfields, BackedCandidates, ParentHeader)` is injected by the `ParachainsInherentDataProvider` +into the inherent data. From that point on, control passes from the node to the runtime. diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/README.md b/polkadot/roadmap/implementers-guide/src/node/utility/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4b79f057a525ddb2ac78e6eacf187c07651c0721 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/README.md @@ -0,0 +1,3 @@ +# Utility Subsystems + +The utility subsystems are an assortment which don't have a natural home in another subsystem collection. diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/availability-store.md b/polkadot/roadmap/implementers-guide/src/node/utility/availability-store.md new file mode 100644 index 0000000000000000000000000000000000000000..bd61455934e43080502382c54b2c3c6b5afb85ce --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/availability-store.md @@ -0,0 +1,212 @@ +# Availability Store + +This is a utility subsystem responsible for keeping available certain data and pruning that data. + +The two data types: + +- Full PoV blocks of candidates we have validated +- Availability chunks of candidates that were backed and noted available on-chain. + +For each of these data we have pruning rules that determine how long we need to keep that data available. + +PoV hypothetically only need to be kept around until the block where the data was made fully available is finalized. However, disputes can revert finality, so we need to be a bit more conservative and we add a delay. We should keep the PoV until a block that finalized availability of it has been finalized for 1 day + 1 hour. + +Availability chunks need to be kept available until the dispute period for the corresponding candidate has ended. We can accomplish this by using the same criterion as the above. This gives us a pruning condition of the block finalizing availability of the chunk being final for 1 day + 1 hour. + +There is also the case where a validator commits to make a PoV available, but the corresponding candidate is never backed. In this case, we keep the PoV available for 1 hour. + +There may be multiple competing blocks all ending the availability phase for a particular candidate. Until finality, it will be unclear which of those is actually the canonical chain, so the pruning records for PoVs and Availability chunks should keep track of all such blocks. + +## Lifetime of the block data and chunks in storage + +```dot process +digraph { + label = "Block data FSM\n\n\n"; + labelloc = "t"; + rankdir="LR"; + + st [label = "Stored"; shape = circle] + inc [label = "Included"; shape = circle] + fin [label = "Finalized"; shape = circle] + prn [label = "Pruned"; shape = circle] + + st -> inc [label = "Block\nincluded"] + st -> prn [label = "Stored block\ntimed out"] + inc -> fin [label = "Block\nfinalized"] + inc -> st [label = "Competing blocks\nfinalized"] + fin -> prn [label = "Block keep time\n(1 day + 1 hour) elapsed"] +} +``` + +## Database Schema + +We use an underlying Key-Value database where we assume we have the following operations available: + +- `write(key, value)` +- `read(key) -> Option` +- `iter_with_prefix(prefix) -> Iterator<(key, value)>` - gives all keys and values in lexicographical order where the key starts with `prefix`. + +We use this database to encode the following schema: + +```rust +("available", CandidateHash) -> Option +("chunk", CandidateHash, u32) -> Option +("meta", CandidateHash) -> Option + +("unfinalized", BlockNumber, BlockHash, CandidateHash) -> Option<()> +("prune_by_time", Timestamp, CandidateHash) -> Option<()> +``` + +Timestamps are the wall-clock seconds since Unix epoch. Timestamps and block numbers are both encoded as big-endian so lexicographic order is ascending. + +The meta information that we track per-candidate is defined as the `CandidateMeta` struct + +```rust +struct CandidateMeta { + state: State, + data_available: bool, + chunks_stored: Bitfield, +} + +enum State { + /// Candidate data was first observed at the given time but is not available in any block. + Unavailable(Timestamp), + /// The candidate was first observed at the given time and was included in the given list of unfinalized blocks, which may be + /// empty. The timestamp here is not used for pruning. Either one of these blocks will be finalized or the state will regress to + /// `State::Unavailable`, in which case the same timestamp will be reused. + Unfinalized(Timestamp, Vec<(BlockNumber, BlockHash)>), + /// Candidate data has appeared in a finalized block and did so at the given time. + Finalized(Timestamp) +} +``` + +We maintain the invariant that if a candidate has a meta entry, its available data exists on disk if `data_available` is true. All chunks mentioned in the meta entry are available. + +Additionally, there is exactly one `prune_by_time` entry which holds the candidate hash unless the state is `Unfinalized`. There may be zero, one, or many "unfinalized" keys with the given candidate, and this will correspond to the `state` of the meta entry. + +## Protocol + +Input: [`AvailabilityStoreMessage`][ASM] + +Output: + +- [`RuntimeApiMessage`][RAM] + +## Functionality + +For each head in the `activated` list: + +- Load all ancestors of the head back to the finalized block so we don't miss anything if import notifications are missed. If a `StoreChunk` message is received for a candidate which has no entry, then we will prematurely lose the data. +- Note any new candidates backed in the head. Update the `CandidateMeta` for each. If the `CandidateMeta` does not exist, create it as `Unavailable` with the current timestamp. Register a `"prune_by_time"` entry based on the current timestamp + 1 hour. +- Note any new candidate included in the head. Update the `CandidateMeta` for each, performing a transition from `Unavailable` to `Unfinalized` if necessary. That includes removing the `"prune_by_time"` entry. Add the head hash and number to the state, if unfinalized. Add an `"unfinalized"` entry for the block and candidate. +- The `CandidateEvent` runtime API can be used for this purpose. + +On `OverseerSignal::BlockFinalized(finalized)` events: + +- for each key in `iter_with_prefix("unfinalized")` + - Stop if the key is beyond `("unfinalized, finalized)` + - For each block number f that we encounter, load the finalized hash for that block. + - The state of each `CandidateMeta` we encounter here must be `Unfinalized`, since we loaded the candidate from an `"unfinalized"` key. + - For each candidate that we encounter under `f` and the finalized block hash, + - Update the `CandidateMeta` to have `State::Finalized`. Remove all `"unfinalized"` entries from the old `Unfinalized` state. + - Register a `"prune_by_time"` entry for the candidate based on the current time + 1 day + 1 hour. + - For each candidate that we encounter under `f` which is not under the finalized block hash, + - Remove all entries under `f` in the `Unfinalized` state. + - If the `CandidateMeta` has state `Unfinalized` with an empty list of blocks, downgrade to `Unavailable` and re-schedule pruning under the timestamp + 1 hour. We do not prune here as the candidate still may be included in a descendant of the finalized chain. + - Remove all `"unfinalized"` keys under `f`. +- Update `last_finalized` = finalized. + + This is roughly `O(n * m)` where n is the number of blocks finalized since the last update, and `m` is the number of parachains. + +On `QueryAvailableData` message: + +- Query `("available", candidate_hash)` + + This is `O(n)` in the size of the data, which may be large. + +On `QueryDataAvailability` message: + +- Query whether `("meta", candidate_hash)` exists and `data_available == true`. + + This is `O(n)` in the size of the metadata which is small. + +On `QueryChunk` message: + +- Query `("chunk", candidate_hash, index)` + + This is `O(n)` in the size of the data, which may be large. + +On `QueryAllChunks` message: + +- Query `("meta", candidate_hash)`. If `None`, send an empty response and return. +- For all `1` bits in the `chunks_stored`, query `("chunk", candidate_hash, index)`. Ignore but warn on errors, and return a vector of all loaded chunks. + +On `QueryChunkAvailability` message: + +- Query whether `("meta", candidate_hash)` exists and the bit at `index` is set. + + This is `O(n)` in the size of the metadata which is small. + +On `StoreChunk` message: + +- If there is a `CandidateMeta` under the candidate hash, set the bit of the erasure-chunk in the `chunks_stored` bitfield to `1`. If it was not `1` already, write the chunk under `("chunk", candidate_hash, chunk_index)`. + + This is `O(n)` in the size of the chunk. + +On `StoreAvailableData` message: + +- Compute the erasure root of the available data and compare it with `expected_erasure_root`. Return `StoreAvailableDataError::InvalidErasureRoot` on mismatch. +- If there is no `CandidateMeta` under the candidate hash, create it with `State::Unavailable(now)`. Load the `CandidateMeta` otherwise. +- Store `data` under `("available", candidate_hash)` and set `data_available` to true. +- Store each chunk under `("chunk", candidate_hash, index)` and set every bit in `chunks_stored` to `1`. + + This is `O(n)` in the size of the data as the aggregate size of the chunks is proportional to the data. + +Every 5 minutes, run a pruning routine: + +- for each key in `iter_with_prefix("prune_by_time")`: + - If the key is beyond `("prune_by_time", now)`, return. + - Remove the key. + - Extract `candidate_hash` from the key. + - Load and remove the `("meta", candidate_hash)` + - For each erasure chunk bit set, remove `("chunk", candidate_hash, bit_index)`. + - If `data_available`, remove `("available", candidate_hash)` + + This is O(n * m) in the amount of candidates and average size of the data stored. This is probably the most expensive operation but does not need + to be run very often. + +## Basic scenarios to test + +Basically we need to test the correctness of data flow through state FSMs described earlier. These tests obviously assume that some mocking of time is happening. + +- Stored data that is never included pruned in necessary timeout + - A block (and/or a chunk) is added to the store. + - We never note that the respective candidate is included. + - Until a defined timeout the data in question is available. + - After this timeout the data is no longer available. + +- Stored data is kept until we are certain it is finalized. + - A block (and/or a chunk) is added to the store. + - It is available. + - Before the inclusion timeout expires notify storage that the candidate was included. + - The data is still available. + - Wait for an absurd amount of time (longer than 1 day). + - Check that the data is still available. + - Send finality notification about the block in question. + - Wait for some time below finalized data timeout. + - The data is still available. + - Wait until the data should have been pruned. + - The data is no longer available. + +- Fork-awareness of the relay chain is taken into account + - Block `B1` is added to the store. + - Block `B2` is added to the store. + - Notify the subsystem that both `B1` and `B2` were included in different leafs of relay chain. + - Notify the subsystem that the leaf with `B1` was finalized. + - Leaf with `B2` is never finalized. + - Leaf with `B2` is pruned and its data is no longer available. + - Wait until the finalized data of `B1` should have been pruned. + - `B1` is no longer available. + +[RAM]: ../../types/overseer-protocol.md#runtime-api-message +[ASM]: ../../types/overseer-protocol.md#availability-store-message diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/candidate-validation.md b/polkadot/roadmap/implementers-guide/src/node/utility/candidate-validation.md new file mode 100644 index 0000000000000000000000000000000000000000..4a1d02be556091b2e223996493bffadb7fd43476 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/candidate-validation.md @@ -0,0 +1,53 @@ +# Candidate Validation + +This subsystem is responsible for handling candidate validation requests. It is a simple request/response server. + +A variety of subsystems want to know if a parachain block candidate is valid. None of them care about the detailed mechanics of how a candidate gets validated, just the results. This subsystem handles those details. + +## Protocol + +Input: [`CandidateValidationMessage`](../../types/overseer-protocol.md#validation-request-type) + +Output: Validation result via the provided response side-channel. + +## Functionality + +This subsystem groups the requests it handles in two categories: *candidate validation* and *PVF pre-checking*. + +The first category can be further subdivided in two request types: one which draws out validation data from the state, and another which accepts all validation data exhaustively. Validation returns three possible outcomes on the response channel: the candidate is valid, the candidate is invalid, or an internal error occurred. + +Parachain candidates are validated against their validation function: A piece of Wasm code that describes the state-transition of the parachain. Validation function execution is not metered. This means that an execution which is an infinite loop or simply takes too long must be forcibly exited by some other means. For this reason, we recommend dispatching candidate validation to be done on subprocesses which can be killed if they time-out. + +Upon receiving a validation request, the first thing the candidate validation subsystem should do is make sure it has all the necessary parameters to the validation function. These are: + * The Validation Function itself. + * The [`CandidateDescriptor`](../../types/candidate.md#candidatedescriptor). + * The [`ValidationData`](../../types/candidate.md#validationdata). + * The [`PoV`](../../types/availability.md#proofofvalidity). + +The second category is for PVF pre-checking. This is primarly used by the [PVF pre-checker](pvf-prechecker.md) subsystem. + +### Determining Parameters + +For a [`CandidateValidationMessage`][CVM]`::ValidateFromExhaustive`, these parameters are exhaustively provided. + +For a [`CandidateValidationMessage`][CVM]`::ValidateFromChainState`, some more work needs to be done. Due to the uncertainty of Availability Cores (implemented in the [`Scheduler`](../../runtime/scheduler.md) module of the runtime), a candidate at a particular relay-parent and for a particular para may have two different valid validation-data to be executed under depending on what is assumed to happen if the para is occupying a core at the onset of the new block. This is encoded as an `OccupiedCoreAssumption` in the runtime API. + +The way that we can determine which assumption the candidate is meant to be executed under is simply to do an exhaustive check of both possibilities based on the state of the relay-parent. First we fetch the validation data under the assumption that the block occupying becomes available. If the `validation_data_hash` of the `CandidateDescriptor` matches this validation data, we use that. Otherwise, if the `validation_data_hash` matches the validation data fetched under the `TimedOut` assumption, we use that. Otherwise, we return a `ValidationResult::Invalid` response and conclude. + +Then, we can fetch the validation code from the runtime based on which type of candidate this is. This gives us all the parameters. The descriptor and PoV come from the request itself, and the other parameters have been derived from the state. + +> TODO: This would be a great place for caching to avoid making lots of runtime requests. That would need a job, though. + +### Execution of the Parachain Wasm + +Once we have all parameters, we can spin up a background task to perform the validation in a way that doesn't hold up the entire event loop. Before invoking the validation function itself, this should first do some basic checks: + * The collator signature is valid + * The PoV provided matches the `pov_hash` field of the descriptor + +For more details please see [PVF Host and Workers](pvf-host-and-workers.md). + +### Checking Validation Outputs + +If we can assume the presence of the relay-chain state (that is, during processing [`CandidateValidationMessage`][CVM]`::ValidateFromChainState`) we can run all the checks that the relay-chain would run at the inclusion time thus confirming that the candidate will be accepted. + +[CVM]: ../../types/overseer-protocol.md#validationrequesttype diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/chain-api.md b/polkadot/roadmap/implementers-guide/src/node/utility/chain-api.md new file mode 100644 index 0000000000000000000000000000000000000000..e9ef9b5695bc386ca9f0bc493b151fd6f0dff892 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/chain-api.md @@ -0,0 +1,21 @@ +# Chain API + +The Chain API subsystem is responsible for providing a single point of access to chain state data via a set of pre-determined queries. + +## Protocol + +Input: [`ChainApiMessage`](../../types/overseer-protocol.md#chain-api-message) + +Output: None + +## Functionality + +On receipt of `ChainApiMessage`, answer the request and provide the response to the side-channel embedded within the request. + +Currently, the following requests are supported: +* Block hash to number +* Block hash to header +* Block weight +* Finalized block number to hash +* Last finalized block number +* Ancestors diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/chain-selection.md b/polkadot/roadmap/implementers-guide/src/node/utility/chain-selection.md new file mode 100644 index 0000000000000000000000000000000000000000..640691e559615b3f703535aa82658a3c6c9693d9 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/chain-selection.md @@ -0,0 +1,42 @@ +# Chain Selection Subsystem + +This subsystem implements the necessary metadata for the implementation of the [chain selection](../../protocol-chain-selection.md) portion of the protocol. + +The subsystem wraps a database component which maintains a view of the unfinalized chain and records the properties of each block: whether the block is **viable**, whether it is **stagnant**, and whether it is **reverted**. It should also maintain an updated set of active leaves in accordance with this view, which should be cheap to query. Leaves are ordered descending first by weight and then by block number. + +This subsystem needs to update its information on the unfinalized chain: + * On every leaf-activated signal + * On every block-finalized signal + * On every `ChainSelectionMessage::Approve` + * On every `ChainSelectionMessage::RevertBlocks` + * Periodically, to detect stagnation. + +Simple implementations of these updates do `O(n_unfinalized_blocks)` disk operations. If the amount of unfinalized blocks is relatively small, the updates should not take very much time. However, in cases where there are hundreds or thousands of unfinalized blocks the naive implementations of these update algorithms would have to be replaced with more sophisticated versions. + +### `OverseerSignal::ActiveLeavesUpdate` + +Determine all new blocks implicitly referenced by any new active leaves and add them to the view. Update the set of viable leaves accordingly. The weights of imported blocks can be determined by the [`ChainApiMessage::BlockWeight`](../../types/overseer-protocol.md#chain-api-message). + +### `OverseerSignal::BlockFinalized` + +Delete data for all orphaned chains and update all metadata descending from the new finalized block accordingly, along with the set of viable leaves. Note that finalizing a **reverted** or **stagnant** block means that the descendants of those blocks may lose that status because the definitions of those properties don't include the finalized chain. Update the set of viable leaves accordingly. + +### `ChainSelectionMessage::Approved` + +Update the approval status of the referenced block. If the block was stagnant and thus non-viable and is now viable, then the metadata of all of its descendants needs to be updated as well, as they may no longer be stagnant either. Update the set of viable leaves accordingly. + +### `ChainSelectionMessage::Leaves` + +Gets all leaves of the chain, i.e. block hashes that are suitable to build upon and have no suitable children. Supplies the leaves in descending order by score. + +### `ChainSelectionMessage::BestLeafContaining` + +If the required block is unknown or not viable, then return `None`. Iterate over all leaves in order of descending weight, returning the first leaf containing the required block in its chain, and `None` otherwise. + +### `ChainSelectionMessage::RevertBlocks` +This message indicates that a dispute has concluded against a parachain block candidate. The message passes along a vector containing the block number and block hash of each block where the disputed candidate was included. The passed blocks will be marked as reverted, and their descendants will be marked as non-viable. + + +### Periodically + +Detect stagnant blocks and apply the stagnant definition to all descendants. Update the set of viable leaves accordingly. diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/gossip-support.md b/polkadot/roadmap/implementers-guide/src/node/utility/gossip-support.md new file mode 100644 index 0000000000000000000000000000000000000000..6f47346d0be9f122c5f7f10613c1ba02705aca5a --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/gossip-support.md @@ -0,0 +1,19 @@ +# Gossip Support + +The Gossip Support Subsystem is responsible for keeping track of session changes +and issuing a connection request to all validators in the next, current and +a few past sessions if we are a validator in these sessions. +The request will add all validators to a reserved PeerSet, meaning we will not +reject a connection request from any validator in that set. + +In addition to that, it creates a gossip overlay topology per session which +limits the amount of messages sent and received to be an order of sqrt of the +validators. Our neighbors in this graph will be forwarded to the network bridge +with the `NetworkBridgeMessage::NewGossipTopology` message. + +See https://github.com/paritytech/polkadot/issues/3239 for more details. + +The gossip topology is used by parachain distribution subsystems, +such as Bitfield Distribution, (small) Statement Distribution and +Approval Distribution to limit the amount of peers we send messages to +and handle view updates. diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/network-bridge.md b/polkadot/roadmap/implementers-guide/src/node/utility/network-bridge.md new file mode 100644 index 0000000000000000000000000000000000000000..3245772d9d8d180fef6f7e8b7374ea03c34b72c3 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/network-bridge.md @@ -0,0 +1,135 @@ +# Network Bridge + +One of the main features of the overseer/subsystem duality is to avoid shared ownership of resources and to communicate via message-passing. However, implementing each networking subsystem as its own network protocol brings a fair share of challenges. + +The most notable challenge is coordinating and eliminating race conditions of peer connection and disconnection events. If we have many network protocols that peers are supposed to be connected on, it is difficult to enforce that a peer is indeed connected on all of them or the order in which those protocols receive notifications that peers have connected. This becomes especially difficult when attempting to share peer state across protocols. All of the Parachain-Host's gossip protocols eliminate DoS with a data-dependency on current chain heads. However, it is inefficient and confusing to implement the logic for tracking our current chain heads as well as our peers' on each of those subsystems. Having one subsystem for tracking this shared state and distributing it to the others is an improvement in architecture and efficiency. + +One other piece of shared state to track is peer reputation. When peers are found to have provided value or cost, we adjust their reputation accordingly. + +So in short, this Subsystem acts as a bridge between an actual network component and a subsystem's protocol. The implementation of the underlying network component is beyond the scope of this module. We make certain assumptions about the network component: + * The network allows registering of protocols and multiple versions of each protocol. + * The network handles version negotiation of protocols with peers and only connects the peer on the highest version of the protocol. + * Each protocol has its own peer-set, although there may be some overlap. + * The network provides peer-set management utilities for discovering the peer-IDs of validators and a means of dialing peers with given IDs. + + +The network bridge makes use of the peer-set feature, but is not generic over peer-set. Instead, it exposes two peer-sets that event producers can attach to: `Validation` and `Collation`. More information can be found on the documentation of the [`NetworkBridgeMessage`][NBM]. + +## Protocol + +Input: [`NetworkBridgeMessage`][NBM] + + +Output: + - [`ApprovalDistributionMessage`][AppD]`::NetworkBridgeUpdate` + - [`BitfieldDistributionMessage`][BitD]`::NetworkBridgeUpdate` + - [`CollatorProtocolMessage`][CollP]`::NetworkBridgeUpdate` + - [`StatementDistributionMessage`][StmtD]`::NetworkBridgeUpdate` + +## Functionality + +This network bridge sends messages of these types over the network. + +```rust +enum WireMessage { + ProtocolMessage(M), + ViewUpdate(View), +} +``` + +and instantiates this type twice, once using the [`ValidationProtocolV1`][VP1] message type, and once with the [`CollationProtocolV1`][CP1] message type. + +```rust +type ValidationV1Message = WireMessage; +type CollationV1Message = WireMessage; +``` + +### Startup + +On startup, we register two protocols with the underlying network utility. One for validation and one for collation. We register only version 1 of each of these protocols. + +### Main Loop + +The bulk of the work done by this subsystem is in responding to network events, signals from the overseer, and messages from other subsystems. + +Each network event is associated with a particular peer-set. + +### Overseer Signal: `ActiveLeavesUpdate` + +The `activated` and `deactivated` lists determine the evolution of our local view over time. A `ProtocolMessage::ViewUpdate` is issued to each connected peer on each peer-set, and a `NetworkBridgeEvent::OurViewChange` is issued to each event handler for each protocol. + +We only send view updates if the node has indicated that it has finished major blockchain synchronization. + +If we are connected to the same peer on both peer-sets, we will send the peer two view updates as a result. + +### Overseer Signal: `BlockFinalized` + +We update our view's `finalized_number` to the provided one and delay `ProtocolMessage::ViewUpdate` and `NetworkBridgeEvent::OurViewChange` till the next `ActiveLeavesUpdate`. + +### Network Event: `PeerConnected` + +Issue a `NetworkBridgeEvent::PeerConnected` for each [Event Handler](#event-handlers) of the peer-set and negotiated protocol version of the peer. Also issue a `NetworkBridgeEvent::PeerViewChange` and send the peer our current view, but only if the node has indicated that it has finished major blockchain synchronization. Otherwise, we only send the peer an empty view. + +### Network Event: `PeerDisconnected` + +Issue a `NetworkBridgeEvent::PeerDisconnected` for each [Event Handler](#event-handlers) of the peer-set and negotiated protocol version of the peer. + +### Network Event: `ProtocolMessage` + +Map the message onto the corresponding [Event Handler](#event-handlers) based on the peer-set this message was received on and dispatch via overseer. + +### Network Event: `ViewUpdate` + +- Check that the new view is valid and note it as the most recent view update of the peer on this peer-set. +- Map a `NetworkBridgeEvent::PeerViewChange` onto the corresponding [Event Handler](#event-handlers) based on the peer-set this message was received on and dispatch via overseer. + +### `ReportPeer` + +- Adjust peer reputation according to cost or benefit provided + +### `DisconnectPeer` + +- Disconnect the peer from the peer-set requested, if connected. + +### `SendValidationMessage` / `SendValidationMessages` + +- Issue a corresponding `ProtocolMessage` to each listed peer on the validation peer-set. + +### `SendCollationMessage` / `SendCollationMessages` + +- Issue a corresponding `ProtocolMessage` to each listed peer on the collation peer-set. + +### `ConnectToValidators` + +- Determine the DHT keys to use for each validator based on the relay-chain state and Runtime API. +- Recover the Peer IDs of the validators from the DHT. There may be more than one peer ID per validator. +- Send all `(ValidatorId, PeerId)` pairs on the response channel. +- Feed all Peer IDs to peer set manager the underlying network provides. + +### `NewGossipTopology` + +- Map all `AuthorityDiscoveryId`s to `PeerId`s and issue a corresponding `NetworkBridgeUpdate` + to all validation subsystems. + +## Event Handlers + +Network bridge event handlers are the intended recipients of particular network protocol messages. These are each a variant of a message to be sent via the overseer. + +### Validation V1 + +* `ApprovalDistributionV1Message -> ApprovalDistributionMessage::NetworkBridgeUpdate` +* `BitfieldDistributionV1Message -> BitfieldDistributionMessage::NetworkBridgeUpdate` +* `StatementDistributionV1Message -> StatementDistributionMessage::NetworkBridgeUpdate` + +### Collation V1 + +* `CollatorProtocolV1Message -> CollatorProtocolMessage::NetworkBridgeUpdate` + +[NBM]: ../../types/overseer-protocol.md#network-bridge-message +[AppD]: ../../types/overseer-protocol.md#approval-distribution-message +[BitD]: ../../types/overseer-protocol.md#bitfield-distribution-message +[StmtD]: ../../types/overseer-protocol.md#statement-distribution-message +[CollP]: ../../types/overseer-protocol.md#collator-protocol-message + +[VP1]: ../../types/network.md#validation-v1 +[CP1]: ../../types/network.md#collation-v1 diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/peer-set-manager.md b/polkadot/roadmap/implementers-guide/src/node/utility/peer-set-manager.md new file mode 100644 index 0000000000000000000000000000000000000000..bf2d461536700aa37ec0fef062ca47fe1747decc --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/peer-set-manager.md @@ -0,0 +1,9 @@ +# Peer Set Manager + +> TODO + +## Protocol + +## Functionality + +## Jobs, if any diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/provisioner.md b/polkadot/roadmap/implementers-guide/src/node/utility/provisioner.md new file mode 100644 index 0000000000000000000000000000000000000000..a3998cabba6ce67f7eb43ff12591f6213530fa2a --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/provisioner.md @@ -0,0 +1,186 @@ +# Provisioner + +Relay chain block authorship authority is governed by BABE and is beyond the scope of the Overseer and the rest of the subsystems. That said, ultimately the block author needs to select a set of backable parachain candidates and other consensus data, and assemble a block from them. This subsystem is responsible for providing the necessary data to all potential block authors. + +## Provisionable Data + +There are several distinct types of provisionable data, but they share this property in common: all should eventually be included in a relay chain block. + +### Backed Candidates + +The block author can choose 0 or 1 backed parachain candidates per parachain; the only constraint is that each backable candidate has the appropriate relay parent. However, the choice of a backed candidate must be the block author's. The provisioner subsystem is how those block authors make this choice in practice. + +### Signed Bitfields + +[Signed bitfields](../../types/availability.md#signed-availability-bitfield) are attestations from a particular validator about which candidates it believes are available. Those will only be provided on fresh leaves. + +### Misbehavior Reports + +Misbehavior reports are self-contained proofs of misbehavior by a validator or group of validators. For example, it is very easy to verify a double-voting misbehavior report: the report contains two votes signed by the same key, advocating different outcomes. Concretely, misbehavior reports become inherents which cause dots to be slashed. + +Note that there is no mechanism in place which forces a block author to include a misbehavior report which it doesn't like, for example if it would be slashed by such a report. The chain's defense against this is to have a relatively long slash period, such that it's likely to encounter an honest author before the slash period expires. + +### Dispute Inherent + +The dispute inherent is similar to a misbehavior report in that it is an attestation of misbehavior on the part of a validator or group of validators. Unlike a misbehavior report, it is not self-contained: resolution requires coordinated action by several validators. The canonical example of a dispute inherent involves an approval checker discovering that a set of validators has improperly approved an invalid parachain block: resolving this requires the entire validator set to re-validate the block, so that the minority can be slashed. + +Dispute resolution is complex and is explained in substantially more detail [here](../../runtime/disputes.md). + +## Protocol + +The subsystem should maintain a set of handles to Block Authorship Provisioning iterations that are currently live. + +### On Overseer Signal + +- `ActiveLeavesUpdate`: + - For each `activated` head: + - spawn a Block Authorship Provisioning iteration with the given relay parent, storing a bidirectional channel with that iteration. + - For each `deactivated` head: + - terminate the Block Authorship Provisioning iteration for the given relay parent, if any. +- `Conclude`: Forward `Conclude` to all iterations, waiting a small amount of time for them to join, and then hard-exiting. + +### On `ProvisionerMessage` + +Forward the message to the appropriate Block Authorship Provisioning iteration, or discard if no appropriate iteration is currently active. + +### Per Provisioning Iteration + +Input: [`ProvisionerMessage`](../../types/overseer-protocol.md#provisioner-message). Backed candidates come from the [Candidate Backing subsystem](../backing/candidate-backing.md), signed bitfields come from the [Bitfield Distribution subsystem](../availability/bitfield-distribution.md), and disputes come from the [Disputes Subsystem](../disputes/dispute-coordinator.md). Misbehavior reports are currently sent from the [Candidate Backing subsystem](../backing/candidate-backing.md) and contain the following misbehaviors: + +1. `Misbehavior::ValidityDoubleVote` +2. `Misbehavior::MultipleCandidates` +3. `Misbehavior::UnauthorizedStatement` +4. `Misbehavior::DoubleSign` + +But we choose not to punish these forms of misbehavior for the time being. Risks from misbehavior are sufficiently mitigated at the protocol level via reputation changes. Punitive actions here may become desirable enough to dedicate time to in the future. + +At initialization, this subsystem has no outputs. + +Block authors request the inherent data they should use for constructing the inherent in the block which contains parachain execution information. + +## Block Production + +When a validator is selected by BABE to author a block, it becomes a block producer. The provisioner is the subsystem best suited to choosing which specific backed candidates and availability bitfields should be assembled into the block. To engage this functionality, a `ProvisionerMessage::RequestInherentData` is sent; the response is a [`ParaInherentData`](../../types/runtime.md#parainherentdata). Each relay chain block backs at most one backable parachain block candidate per parachain. Additionally no further block candidate can be backed until the previous one either gets declared available or expired. If bitfields indicate that candidate A, predecessor of B, should be declared available, then B can be backed in the same relay block. Appropriate bitfields, as outlined in the section on [bitfield selection](#bitfield-selection), and any dispute statements should be attached as well. + +### Bitfield Selection + +Our goal with respect to bitfields is simple: maximize availability. However, it's not quite as simple as always including all bitfields; there are constraints which still need to be met: + +- not more than one bitfield per validator +- each 1 bit must correspond to an occupied core + +Beyond that, a semi-arbitrary selection policy is fine. In order to meet the goal of maximizing availability, a heuristic of picking the bitfield with the greatest number of 1 bits set in the event of conflict is useful. + +### Dispute Statement Selection + +This is the point at which the block author provides further votes to active disputes or initiates new disputes in the runtime state. + +The block-authoring logic of the runtime has an extra step between handling the inherent-data and producing the actual inherent call, which we assume performs the work of filtering out disputes which are not relevant to the on-chain state. Backing votes are always kept in the dispute statement set. This ensures we punish the maximum number of misbehaving backers. + +To select disputes: + +- Issue a `DisputeCoordinatorMessage::RecentDisputes` message and wait for the response. This is a set of all disputes in recent sessions which we are aware of. + +### Determining Bitfield Availability + +An occupied core has a `CoreAvailability` bitfield. We also have a list of `SignedAvailabilityBitfield`s. We need to determine from these whether or not a core at a particular index has become available. + +The key insight required is that `CoreAvailability` is transverse to the `SignedAvailabilityBitfield`s: if we conceptualize the list of bitfields as many rows, each bit of which is its own column, then `CoreAvailability` for a given core index is the vertical slice of bits in the set at that index. + +To compute bitfield availability, then: + +- Start with a copy of `OccupiedCore.availability` +- For each bitfield in the list of `SignedAvailabilityBitfield`s: + - Get the bitfield's `validator_index` + - Update the availability. Conceptually, assuming bit vectors: `availability[validator_index] |= bitfield[core_idx]` +- Availability has a 2/3 threshold. Therefore: `3 * availability.count_ones() >= 2 * availability.len()` + +### Candidate Selection: Prospective Parachains Mode + +The state of the provisioner `PerRelayParent` tracks an important setting, `ProspectiveParachainsMode`. This setting determines which backable candidate selection method the provisioner uses. + +`ProspectiveParachainsMode::Disabled` - The provisioner uses its own internal legacy candidate selection. +`ProspectiveParachainsMode::Enabled` - The provisioner requests that [prospective parachains](../backing/prospective-parachains.md) provide selected candidates. + +Candidates selected with `ProspectiveParachainsMode::Enabled` are able to benefit from the increased block production time asynchronous backing allows. For this reason all Polkadot protocol networks will eventually use prospective parachains candidate selection. Then legacy candidate selection will be removed as obsolete. + +### Prospective Parachains Candidate Selection + +The goal of candidate selection is to determine which cores are free, and then to the degree possible, pick a candidate appropriate to each free core. In prospective parachains candidate selection the provisioner handles the former process while [prospective parachains](../backing/prospective-parachains.md) handles the latter. + +To select backable candidates: + +- Get the list of core states from the runtime API +- For each core state: + - On `CoreState::Free` + - The core is unscheduled and doesn’t need to be provisioned with a candidate + - On `CoreState::Scheduled` + - The core is unoccupied and scheduled to accept a backed block for a particular `para_id`. + - The provisioner requests a backable candidate from [prospective parachains](../backing/prospective-parachains.md) with the desired relay parent, the core’s scheduled `para_id`, and an empty required path. + - On `CoreState::Occupied` + - The availability core is occupied by a parachain block candidate pending availability. A further candidate need not be provided by the provisioner unless the core will be vacated this block. This is the case when either bitfields indicate the current core occupant has been made available or a timeout is reached. + - If `bitfields_indicate_availability` + - If `Some(scheduled_core) = occupied_core.next_up_on_available`, the core will be vacated and in need of a provisioned candidate. The provisioner requests a backable candidate from [prospective parachains](../backing/prospective-parachains.md) with the core’s scheduled `para_id` and a required path with one entry. This entry corresponds to the parablock candidate previously occupying this core, which was made available and can be built upon even though it hasn’t been seen as included in a relay chain block yet. See the Required Path section below for more detail. + - If `occupied_core.next_up_on_available` is `None`, then the core being vacated is unscheduled and doesn’t need to be provisioned with a candidate. + - Else-if `occupied_core.time_out_at == block_number` + - If `Some(scheduled_core) = occupied_core.next_up_on_timeout`, the core will be vacated and in need of a provisioned candidate. A candidate is requested in exactly the same way as with `CoreState::Scheduled`. + - Else the core being vacated is unscheduled and doesn’t need to be provisioned with a candidate +The end result of this process is a vector of `CandidateHash`s, sorted in order of their core index. + +#### Required Path + +Required path is a parameter for `ProspectiveParachainsMessage::GetBackableCandidate`, which the provisioner sends in candidate selection. + +An empty required path indicates that the requested candidate should be a direct child of the most recently included parablock for the given `para_id` as of the given relay parent. + +In contrast, a required path with one or more entries prompts [prospective parachains](../backing/prospective-parachains.md) to step forward through its fragment tree for the given `para_id` and relay parent until the desired parablock is reached. We then select a direct child of that parablock to pass to the provisioner. + +The parablocks making up a required path do not need to have been previously seen as included in relay chain blocks. Thus the ability to provision backable candidates based on a required path effectively decouples backing from inclusion. + +### Legacy Candidate Selection + +Legacy candidate selection takes place in the provisioner. Thus the provisioner needs to keep an up to date record of all [backed_candidates](../../types/backing.md#backed-candidate) `PerRelayParent` to pick from. + +The goal of candidate selection is to determine which cores are free, and then to the degree possible, pick a candidate appropriate to each free core. + +To determine availability: + +- Get the list of core states from the runtime API +- For each core state: + - On `CoreState::Scheduled`, then we can make an `OccupiedCoreAssumption::Free`. + - On `CoreState::Occupied`, then we may be able to make an assumption: + - If the bitfields indicate availability and there is a scheduled `next_up_on_available`, then we can make an `OccupiedCoreAssumption::Included`. + - If the bitfields do not indicate availability, and there is a scheduled `next_up_on_time_out`, and `occupied_core.time_out_at == block_number_under_production`, then we can make an `OccupiedCoreAssumption::TimedOut`. + - If we did not make an `OccupiedCoreAssumption`, then continue on to the next core. + - Now compute the core's `validation_data_hash`: get the `PersistedValidationData` from the runtime, given the known `ParaId` and `OccupiedCoreAssumption`; + - Find an appropriate candidate for the core. + - There are two constraints: `backed_candidate.candidate.descriptor.para_id == scheduled_core.para_id && candidate.candidate.descriptor.validation_data_hash == computed_validation_data_hash`. + - In the event that more than one candidate meets the constraints, selection between the candidates is arbitrary. However, not more than one candidate can be selected per core. + +The end result of this process is a vector of `CandidateHash`s, sorted in order of their core index. + +### Retrieving Full `BackedCandidate`s for Selected Hashes + +Legacy candidate selection and prospective parachains candidate selection both leave us with a vector of `CandidateHash`s. These are passed to the backing subsystem with `CandidateBackingMessage::GetBackedCandidates`. + +The response is a vector of `BackedCandidate`s, sorted in order of their core index and ready to be provisioned to block authoring. The candidate selection and retrieval process should select at maximum one candidate which upgrades the runtime validation code. + +## Glossary + +- **Relay-parent:** + - A particular relay-chain block which serves as an anchor and reference point for processes and data which depend on relay-chain state. +- **Active Leaf:** + - A relay chain block which is the head of an active fork of the relay chain. + - Block authorship provisioning jobs are spawned per active leaf and concluded for any leaves which become inactive. +- **Candidate Selection:** + - The process by which the provisioner selects backable parachain block candidates to pass to block authoring. + - Two versions, prospective parachains candidate selection and legacy candidate selection. See their respective protocol sections for details. +- **Availability Core:** + - Often referred to simply as "cores", availability cores are an abstraction used for resource management. For the provisioner, availability cores are most relevant in that core states determine which `para_id`s to provision backable candidates for. + - For more on availability cores see [Scheduler Module: Availability Cores](../../runtime/scheduler.md#availability-cores) +- **Availability Bitfield:** + - Often referred to simply as a "bitfield", an availability bitfield represents the view of parablock candidate availability from a particular validator's perspective. Each bit in the bitfield corresponds to a single [availability core](../../runtime-api/availability-cores.md). + - For more on availability bitfields see [availability](../../types/availability.md) +- **Backable vs. Backed:** + - Note that we sometimes use "backed" to refer to candidates that are "backable", but not yet backed on chain. + - Backable means that a quorum of the candidate's assigned backing group have provided signed affirming statements. \ No newline at end of file diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/pvf-host-and-workers.md b/polkadot/roadmap/implementers-guide/src/node/utility/pvf-host-and-workers.md new file mode 100644 index 0000000000000000000000000000000000000000..bcf01b61f2173f024dc50cccacc877534f22aaf2 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/pvf-host-and-workers.md @@ -0,0 +1,134 @@ +# PVF Host and Workers + +The PVF host is responsible for handling requests to prepare and execute PVF +code blobs, which it sends to PVF workers running in their own child processes. + +This system has two high-levels goals that we will touch on here: *determinism* +and *security*. + +## Determinism + +One high-level goal is to make PVF operations as deterministic as possible, to +reduce the rate of disputes. Disputes can happen due to e.g. a job timing out on +one machine, but not another. While we do not have full determinism, there are +some dispute reduction mechanisms in place right now. + +### Retrying execution requests + +If the execution request fails during **preparation**, we will retry if it is +possible that the preparation error was transient (e.g. if the error was a panic +or time out). We will only retry preparation if another request comes in after +15 minutes, to ensure any potential transient conditions had time to be +resolved. We will retry up to 5 times. + +If the actual **execution** of the artifact fails, we will retry once if it was +a possibly transient error, to allow the conditions that led to the error to +hopefully resolve. We use a more brief delay here (1 second as opposed to 15 +minutes for preparation (see above)), because a successful execution must happen +in a short amount of time. + +We currently know of the following specific cases that will lead to a retried +execution request: + +1. **OOM:** The host might have been temporarily low on memory due to other + processes running on the same machine. **NOTE:** This case will lead to + voting against the candidate (and possibly a dispute) if the retry is still + not successful. +2. **Artifact missing:** The prepared artifact might have been deleted due to + operator error or some bug in the system. +3. **Panic:** The worker thread panicked for some indeterminate reason, which + may or may not be independent of the candidate or PVF. + +### Preparation timeouts + +We use timeouts for both preparation and execution jobs to limit the amount of +time they can take. As the time for a job can vary depending on the machine and +load on the machine, this can potentially lead to disputes where some validators +successfuly execute a PVF and others don't. + +One dispute mitigation we have in place is a more lenient timeout for +preparation during execution than during pre-checking. The rationale is that the +PVF has already passed pre-checking, so we know it should be valid, and we allow +it to take longer than expected, as this is likely due to an issue with the +machine and not the PVF. + +### CPU clock timeouts + +Another timeout-related mitigation we employ is to measure the time taken by +jobs using CPU time, rather than wall clock time. This is because the CPU time +of a process is less variable under different system conditions. When the +overall system is under heavy load, the wall clock time of a job is affected +more than the CPU time. + +### Internal errors + +In general, for errors not raising a dispute we have to be very careful. This is +only sound, if we either: + +1. Ruled out that error in pre-checking. If something is not checked in + pre-checking, even if independent of the candidate and PVF, we must raise a + dispute. +2. We are 100% confident that it is a hardware/local issue: Like corrupted file, + etc. + +Reasoning: Otherwise it would be possible to register a PVF where candidates can +not be checked, but we don't get a dispute - so nobody gets punished. Second, we +end up with a finality stall that is not going to resolve! + +There are some error conditions where we can't be sure whether the candidate is +really invalid or some internal glitch occurred, e.g. panics. Whenever we are +unsure, we can never treat an error as internal as we would abstain from voting. +So we will first retry the candidate, and if the issue persists we are forced to +vote invalid. + +## Security + +With [on-demand parachains](https://github.com/orgs/paritytech/projects/67), it +is much easier to submit PVFs to the chain for preparation and execution. This +makes it easier for erroneous disputes and slashing to occur, whether +intentional (as a result of a malicious attacker) or not (a bug or operator +error occurred). + +Therefore, another goal of ours is to harden our security around PVFs, in order +to protect the economic interests of validators and increase overall confidence +in the system. + +### Possible attacks / threat model + +Webassembly is already sandboxed, but there have already been reported multiple +CVEs enabling remote code execution. See e.g. these two advisories from +[Mar 2023](https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-ff4p-7xrq-q5r8) +and [Jul 2022](https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-7f6x-jwh5-m9r4). + +So what are we actually worried about? Things that come to mind: + +1. **Consensus faults** - If an attacker can get some source of randomness they + could vote against with 50% chance and cause unresolvable disputes. +2. **Targeted slashes** - An attacker can target certain validators (e.g. some + validators running on vulnerable hardware) and make them vote invalid and get + them slashed. +3. **Mass slashes** - With some source of randomness they can do an untargeted + attack. I.e. a baddie can do significant economic damage by voting against + with 1/3 chance, without even stealing keys or completely replacing the + binary. +4. **Stealing keys** - That would be pretty bad. Should not be possible with + sandboxing. We should at least not allow filesystem-access or network access. +5. **Taking control over the validator.** E.g. replacing the `polkadot` binary + with a `polkadot-evil` binary. Should again not be possible with the above + sandboxing in place. +6. **Intercepting and manipulating packages** - Effect very similar to the + above, hard to do without also being able to do 4 or 5. + +### Restricting file-system access + +A basic security mechanism is to make sure that any thread directly interfacing +with untrusted code does not have access to the file-system. This provides some +protection against attackers accessing sensitive data or modifying data on the +host machine. + +### Clearing env vars + +We clear environment variables before handling untrusted code, because why give +attackers potentially sensitive data unnecessarily? And even if everything else +is locked down, env vars can potentially provide a source of randomness (see +point 1, "Consensus faults" above). diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/pvf-prechecker.md b/polkadot/roadmap/implementers-guide/src/node/utility/pvf-prechecker.md new file mode 100644 index 0000000000000000000000000000000000000000..3cae12e65f33e7fff728124ffc1b75d1f785b7ef --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/pvf-prechecker.md @@ -0,0 +1,48 @@ +# PVF Pre-checker + +The PVF pre-checker is a subsystem that is responsible for watching the relay chain for new PVFs that require pre-checking. Head over to [overview] for the PVF pre-checking process overview. + +## Protocol + +There is no dedicated input mechanism for PVF pre-checker. Instead, PVF pre-checker looks on the `ActiveLeavesUpdate` event stream for work. + +This subsytem does not produce any output messages either. The subsystem will, however, send messages to the [Runtime API] subsystem to query for the pending PVFs and to submit votes. In addition to that, it will also communicate with [Candidate Validation] Subsystem to request PVF pre-check. + +## Functionality + +If the node is running in a collator mode, this subsystem will be disabled. The PVF pre-checker subsystem keeps track of the PVFs that are relevant for the subsystem. + +To be relevant for the subsystem, a PVF must be returned by the [`pvfs_require_precheck` runtime API][PVF pre-checking runtime API] in any of the active leaves. If the PVF is not present in any of the active leaves, it ceases to be relevant. + +When a PVF just becomes relevant, the subsystem will send a message to the [Candidate Validation] subsystem asking for the pre-check. + +Upon receving a message from the candidate-validation subsystem, the pre-checker will note down that the PVF has its judgement and will also sign and submit a [`PvfCheckStatement`][PvfCheckStatement] via the [`submit_pvf_check_statement` runtime API][PVF pre-checking runtime API]. In case, a judgement was received for a PVF that is no longer in view it is ignored. + +Since a vote only is valid during [one session][overview], the subsystem will have to resign and submit the statements for the new session. The new session is assumed to be started if at least one of the leaves has a greater session index that was previously observed in any of the leaves. + +The subsystem tracks all the statements that it submitted within a session. If for some reason a PVF became irrelevant and then becomes relevant again, the subsystem will not submit a new statement for that PVF within the same session. + +If the node is not in the active validator set, it will still perform all the checks. However, it will only submit the check statements when the node is in the active validator set. + +### Rejecting failed PVFs + +It is possible that the candidate validation was not able to check the PVF, e.g. if it timed out. In that case, the PVF pre-checker will vote against it. This is considered safe, as there is no slashing for being on the wrong side of a pre-check vote. + +Rejecting instead of abstaining is better in several ways: + +1. Conclusion is reached faster - we have actual votes, instead of relying on a timeout. +1. Being strict in pre-checking makes it safer to be more lenient in preparation errors afterwards. Hence we have more leeway in avoiding raising dubious disputes, without making things less secure. + +Also, if we only abstain, an attacker can specially craft a PVF wasm blob so that it will fail on e.g. 50% of the validators. In that case a supermajority will never be reached and the vote will repeat multiple times, most likely with the same result (since all votes are cleared on a session change). This is avoided by rejecting failed PVFs, and by only requiring 1/3 of validators to reject a PVF to reach a decision. + +### Note on Disputes + +Having a pre-checking phase allows us to make certain assumptions later when preparing the PVF for execution. If a runtime passed pre-checking, then we know that the runtime should be valid, and therefore any issue during preparation for execution can be assumed to be a local problem on the current node. + +For this reason, even deterministic preparation errors should not trigger disputes. And since we do not dispute as a result of the pre-checking phase, as stated above, it should be impossible for preparation in general to result in disputes. + +[overview]: ../../pvf-prechecking.md +[Runtime API]: runtime-api.md +[PVF pre-checking runtime API]: ../../runtime-api/pvf-prechecking.md +[Candidate Validation]: candidate-validation.md +[PvfCheckStatement]: ../../types/pvf-prechecking.md#pvfcheckstatement diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/runtime-api.md b/polkadot/roadmap/implementers-guide/src/node/utility/runtime-api.md new file mode 100644 index 0000000000000000000000000000000000000000..6271429c2666fff7c3728fb6997042ac1fd5bacb --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/node/utility/runtime-api.md @@ -0,0 +1,17 @@ +# Runtime API + +The Runtime API subsystem is responsible for providing a single point of access to runtime state data via a set of pre-determined queries. This prevents shared ownership of a blockchain client resource by providing + +## Protocol + +Input: [`RuntimeApiMessage`](../../types/overseer-protocol.md#runtime-api-message) + +Output: None + +## Functionality + +On receipt of `RuntimeApiMessage::Request(relay_parent, request)`, answer the request using the post-state of the `relay_parent` provided and provide the response to the side-channel embedded within the request. + +## Jobs + +> TODO Don't limit requests based on parent hash, but limit caching. No caching should be done for any requests on `relay_parent`s that are not active based on `ActiveLeavesUpdate` messages. Maybe with some leeway for things that have just been stopped. diff --git a/polkadot/roadmap/implementers-guide/src/protocol-approval.md b/polkadot/roadmap/implementers-guide/src/protocol-approval.md new file mode 100644 index 0000000000000000000000000000000000000000..693822ce07973a2016e6ac2bed61a7670e559875 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/protocol-approval.md @@ -0,0 +1,202 @@ +# Approval Process + +The Approval Process is the mechanism by which the relay-chain ensures that only valid parablocks are finalized and that backing validators are held accountable for managing to get bad blocks included into the relay chain. + +Having a parachain include a bad block into a fork of the relay-chain is not catastrophic as long as the block isn't finalized by the relay-chain's finality gadget, GRANDPA. If the block isn't finalized, that means that the fork of the relay-chain can be reverted in favor of another by means of a dynamic fork-choice rule which leads honest validators to ignore any forks containing that parablock. + +Dealing with a bad parablock proceeds in these stages: +1. Detection +2. Escalation +3. Consequences + +First, the bad block must be detected by an honest party. Second, the honest party must escalate the bad block to be checked by all validators. And last, the correct consequences of a bad block must occur. The first consequence, as mentioned above, is to revert the chain so what full nodes perceive to be best no longer contains the bad parablock. The second consequence is to slash all malicious validators. Note that, if the chain containing the bad block is reverted, that the result of the dispute needs to be transplanted or at least transplantable to all other forks of the chain so that malicious validators are slashed in all possible histories. Phrased alternatively, there needs to be no possible relay-chain in which malicious validators get away cost-free. + +Accepting a parablock is the end result of having passed through the detection stage without dispute, or having passed through the escalation/dispute stage with a positive outcome. For this to work, we need the detection procedure to have the properties that enough honest validators are always selected to check the parablock and that they cannot be interfered with by an adversary. This needs to be balanced with the scaling concern of parachains in general: the easiest way to get the first property is to have everyone check everything, but that is clearly too heavy. So we also have a desired constraint on the other property that we have as few validators as possible check any particular parablock. Our assignment function is the method by which we select validators to do approval checks on parablocks. + +It often makes more sense to think of relay-chain blocks as having been approved or not as opposed to thinking about whether parablocks have been approved. A relay-chain block containing a single bad parablock needs to be reverted, and a relay-chain block that contains only approved parablocks can be called approved, as long as its parent relay-chain block is also approved. It is important that the validity of any particular relay-chain block depend on the validity of its ancestry, so we do not finalize a block which has a bad block in its ancestry. + +```dot process Approval Process +digraph { + Included -> Assignments -> Approval -> Finality + Assignments -> Escalation -> Consequences +} +``` + +Approval has roughly two parts: + +- **Assignments** determines which validators performs approval checks on which candidates. It ensures that each candidate receives enough random checkers, while reducing adversaries' odds for obtaining enough checkers, and limiting adversaries' foreknowledge. It tracks approval votes to identify when "no show" approval check takes suspiciously long, perhaps indicating the node being under attack, and assigns more checks in this case. It tracks relay chain equivocations to determine when adversaries possibly gained foreknowledge about assignments, and adds additional checks in this case. + +- **Approval checks** listens to the assignments subsystem for outgoing assignment notices that we shall check specific candidates. It then performs these checks by first invoking the reconstruction subsystem to obtain the candidate, second invoking the candidate validity utility subsystem upon the candidate, and finally sending out an approval vote, or perhaps initiating a dispute. + +These both run first as off-chain consensus protocols using messages gossiped among all validators, and second as an on-chain record of this off-chain protocols' progress after the fact. We need the on-chain protocol to provide rewards for the off-chain protocol. + +Approval requires two gossiped message types, assignment notices created by its assignments subsystem, and approval votes sent by our approval checks subsystem when authorized by the candidate validity utility subsystem. + +### Approval keys + +We need two separate keys for the approval subsystem: + +- **Approval assignment keys** are sr25519/schnorrkel keys used only for the assignment criteria VRFs. We implicitly sign assignment notices with approval assignment keys by including their relay chain context and additional data in the VRF's extra message, but exclude these from its VRF input. + +- **Approval vote keys** would only sign off on candidate parablock validity and has no natural key type restrictions. There's no need for this to actually embody a new session key type. We just want to make a distinction between assignments and approvals, although distant future node configurations might favor separate roles. We re-use the same keys as are used for parachain backing in practice. + +Approval vote keys could relatively easily be handled by some hardened signer tooling, perhaps even HSMs assuming we select ed25519 for approval vote keys. Approval assignment keys might or might not support hardened signer tooling, but doing so sounds far more complex. In fact, assignment keys determine only VRF outputs that determine approval checker assignments, for which they can only act or not act, so they cannot equivocate, lie, etc. and represent little if any slashing risk for validator operators. + +In future, we shall determine which among the several hardening techniques best benefits the network as a whole. We could provide a multi-process multi-machine architecture for validators, perhaps even reminiscent of GNUNet, or perhaps more resembling smart HSM tooling. We might instead design a system that more resembled full systems, like like Cosmos' sentry nodes. In either case, approval assignments might be handled by a slightly hardened machine, but not necessarily nearly as hardened as approval votes, but approval votes machines must similarly run foreign WASM code, which increases their risk, so assignments being separate sounds helpful. + +## Assignments + +Approval assignment determines on which candidate parachain blocks each validator performs approval checks. An approval session considers only one relay chain block and assigns only those candidates that relay chain block declares available. + +Assignment balances several concerns: + +- limits adversaries' foreknowledge about assignments, +- ensures enough checkers, and +- distributes assignments relatively equitably. + +Assignees determine their own assignments to check specific candidates using two or three assignment criteria. Assignees never reveal their assignments until relevant, and gossip delays assignments sent early, which limits others' foreknowledge. Assignees learn their assignment only with the relay chain block. + +All criteria require the validator evaluate a verifiable random function (VRF) using their VRF secret key. All criteria input specific data called "stories" about the session's relay chain block, and output candidates to check and a precedence called a `DelayTranche`. + +We liberate availability cores when their candidate becomes available of course, but one approval assignment criteria continues associating each candidate with the core number it occupied when it became available. + +Assignment operates in loosely timed rounds determined by this `DelayTranche`s, which proceed roughly 12 times faster than six second block production assuming half second gossip times. If a candidate `C` needs more approval checkers by the time we reach round `t` then any validators with an assignment to `C` in delay tranche `t` gossip their send assignment notice for `C`. We continue until all candidates have enough approval checkers assigned. We take entire tranches together if we do not yet have enough, so we expect strictly more than enough checkers. We also take later tranches if some checkers return their approval votes too slow (see no shows below). + +Assignment ensures validators check those relay chain blocks for which they have delay tranche zero aka the highest precedence, so that adversaries always face honest checkers equal to the expected number of assignments with delay tranche zero. + +Among these criteria, the BABE VRF output provides the story for two, which reduces how frequently adversaries could position their own checkers. We have one criterion whose story consists of the candidate's block hash plus external knowledge that a relay chain equivocation exists with a conflicting candidate. It provides unforeseeable assignments when adversaries gain foreknowledge about the other two by committing an equivocation in relay chain block production. + +## Announcements / Notices + +We gossip assignment notices among nodes so that all validators know which validators should check each candidate, and if any candidate requires more checkers. + +Assignment notices consist of a relay chain context given by a block hash, an assignment criteria, consisting of the criteria identifier and optionally a criteria specific field, an assignee identifier, and a VRF signature by the assignee, which itself consists of a VRF pre-output and a DLEQ proof. Its VRF input consists of the criteria, usually including a criteria specific field, and a "story" about its relay chain context block. + +We never include stories inside the gossip messages containing assignment notices, but require each validator reconstruct them. We never care about assignments in the disputes process, so this does not complicate remote disputes. + +In a Schnorr VRF, there is an extra signed message distinct from this input, which we set to the relay chain block hash. As a result, assignment notices are self signing and can be "politely" gossiped without additional signatures, meaning between nodes who can compute the story from the relay chain context. In other words, if we cannot compute the story required by an assignment notice's VRF part then our self signing property fails and we cannot verify its origin. We could fix this with either another signature layer (64 bytes) or by including the VRF input point computed from the story (32 bytes), but doing so appears unhelpful. + +Any validator could send their assignment notices and/or approval votes too early. We gossip the approval votes early because they represent a major commitment by the validator. We delay gossiping the assignment notices until they agree with our local clock however. We also impose a politeness condition that the recipient knows the relay chain context used by the assignment notice. + +## Stories + +We based assignment criteria upon two possible "stories" about the relay chain block `R` that included the candidate aka declared the candidate available. All stories have an output that attempts to minimize adversarial influence, which then acts as the VRF input for an assignment criteria. + +We first have a `RelayVRFStory` that outputs the randomness from another VRF output produced by the relay chain block producer when creating `R`. Among honest nodes, only this one relay chain block producer who creates `R` knew the story in advance, and even they knew nothing two epochs previously. + +In BABE, we create this value calling `schnorrkel::vrf::VRFInOut::make_bytes` with a context "A&V RC-VRF", with the `VRFInOut` coming from either the VRF that authorized block production for primary blocks, or else from the secondary block VRF for the secondary block type. + +In Sassafras, we shall always use the non-anonymized recycling VRF output, never the anonymized ring VRF that authorizes block production. We do not currently know if Sassafras shall have a separate schnorrkel key, but if it reuses its ring VRF key there is an equivalent `ring_vrf::VRFInOut::make_bytes`. + +We like that `RelayVRFStory` admits relatively few choices, but an adversary who equivocates in relay chain block production could learn assignments that depend upon the `RelayVRFStory` too early because the same relay chain VRF appears in multiple blocks. + +We therefore provide a secondary `RelayEquivocationStory` that outputs the candidate's block hash, but only for candidate equivocations. We say a candidate `C` in `R` is an equivocation when there exists another relay chain block `R1` that equivocates for `R` in the sense that `R` and `R1` have the same `RelayVRFStory`, but `R` contains `C` and `R1` does not contain `C`. + +We want checkers for candidate equivocations that lie outside our preferred relay chain as well, which represents a slightly different usage for the assignments module, and might require more information in the gossip messages. + +## Assignment criteria + +Assignment criteria compute actual assignments using stories and the validators' secret approval assignment key. Assignment criteria output a `Position` consisting of both a `ParaId` to be checked, as well as a precedence `DelayTranche` for when the assignment becomes valid. + +Assignment criteria come in three flavors, `RelayVRFModulo`, `RelayVRFDelay` and `RelayEquivocation`. Among these, both `RelayVRFModulo` and `RelayVRFDelay` run a VRF whose input is the output of a `RelayVRFStory`, while `RelayEquivocation` runs a VRF whose input is the output of a `RelayEquivocationStory`. + +Among these, we have two distinct VRF output computations: + +`RelayVRFModulo` runs several distinct samples whose VRF input is the `RelayVRFStory` and the sample number. It computes the VRF output with `schnorrkel::vrf::VRFInOut::make_bytes` using the context "A&V Core", reduces this number modulo the number of availability cores, and outputs the candidate just declared available by, and included by aka leaving, that availability core. We drop any samples that return no candidate because no candidate was leaving the sampled availability core in this relay chain block. We choose three samples initially, but we could make polkadot more secure and efficient by increasing this to four or five, and reducing the backing checks accordingly. All successful `RelayVRFModulo` samples are assigned delay tranche zero. + +There is no sampling process for `RelayVRFDelay` and `RelayEquivocation`. We instead run them on specific candidates and they compute a delay from their VRF output. `RelayVRFDelay` runs for all candidates included under, aka declared available by, a relay chain block, and inputs the associated VRF output via `RelayVRFStory`. `RelayEquivocation` runs only on candidate block equivocations, and inputs their block hashes via the `RelayEquivocation` story. + +`RelayVRFDelay` and `RelayEquivocation` both compute their output with `schnorrkel::vrf::VRFInOut::make_bytes` using the context "A&V Tranche" and reduce the result modulo `num_delay_tranches + zeroth_delay_tranche_width`, and consolidate results 0 through `zeroth_delay_tranche_width` to be 0. In this way, they ensure the zeroth delay tranche has `zeroth_delay_tranche_width+1` times as many assignments as any other tranche. + +As future work (or TODO?), we should merge assignment notices with the same delay and story using `vrf_merge`. We cannot merge those with the same delay and different stories because `RelayEquivocationStory`s could change but `RelayVRFStory` never changes. + +## Announcer and Watcher/Tracker + +We track all validators' announced approval assignments for each candidate associated to each relay chain block, which tells us which validators were assigned to which candidates. + +We permit at most one assignment per candidate per story per validator, so one validator could be assigned under both the `RelayVRFDelay` and `RelayEquivocation` criteria, but not under both `RelayVRFModulo` and `RelayVRFDelay` criteria, since those both use the same story. We permit only one approval vote per candidate per validator, which counts for any applicable criteria. + +We announce, and start checking for, our own assignments when the delay of their tranche is reached, but only if the tracker says the assignee candidate requires more approval checkers. We never announce an assignment we believe unnecessary because early announcements gives an adversary information. All delay tranche zero assignments always get announced, which includes all `RelayVRFModulo` assignments. + +In other words, if some candidate `C` needs more approval checkers by the time we reach round `t` then any validators with an assignment to `C` in delay tranche `t` gossip their send assignment notice for `C`, and begin reconstruction and validation for 'C. If however `C` reached enough assignments, then validators with later assignments skip announcing their assignments. + +We continue until all candidates have enough approval checkers assigned. We never prioritize assignments within tranches and count all or no assignments for a given tranche together, so we often overshoot the target number of assigned approval checkers. + +### No shows + +We have a "no show" timeout longer than one relay chain slot, so at least 6 seconds, during which we expect approval checks should succeed in reconstructing the candidate block, in redoing its erasure coding to check the candidate receipt, and finally in rechecking the candidate block itself. + +We consider a validator a "no show" if they do not approve or dispute within this "no show" timeout from our receiving their assignment notice. We time this from our receipt of their assignment notice instead of our imagined real time for their tranche because otherwise receiving late assignment notices creates immediate "no shows" and unnecessary work. + +We worry "no shows" represent a validator under denial of service attack, presumably to prevent it from reconstructing the candidate, but perhaps delaying it form gossiping a dispute too. We therefore always replace "no shows" by adding one entire extra delay tranche worth of validators, so such attacks always result in additional checkers. + +As an example, imagine we need 20 checkers, but tranche zero produces only 14, and tranche one only 4, then we take all 5 from tranche two, and thus require 23 checkers for that candidate. If one checker Charlie from tranche one or two does not respond within say 8 seconds, then we add all 7 checkers from tranche three. If again one checker Cindy from tranche three does not respond within 8 seconds then we take all 3 checkers from tranche four. We now have 33 checkers working on the candidate, so this escalated quickly. + +We escalated so quickly because we worried that Charlie and Cindy might be the only honest checkers assigned to that candidate. If therefore either Charlie or Cindy finally return an approval, then we can conclude approval, and abandon the checkers from tranche four. + +We therefore require the "no show" timeout to be longer than a relay chain slot so that we can witness "no shows" on-chain. We discuss below how this helps reward validators who replace "no shows". + +We avoid slashing for "no shows" by itself, although being "no show" could enter into some computation that punishes repeated poor performance, presumably replaces `ImOnline`, and we could reduce their rewards and further rewards those who filled in. + +As future work, we foresee expanding the "no show" scheme to anonymize the additional checkers, like by using assignment noticed with a new criteria that employs a ring VRF and then all validators providing cover by requesting a couple erasure coded pieces, but such anonymity scheme sound extremely complex and lie far beyond our initial functionality. + +## Assignment postponement + +We expect validators could occasionally overloaded when they randomly acquire too many assignments. All these fluctuations amortize over multiple blocks fairly well, but this slows down finality. + +We therefore permit validators to delay sending their assignment noticed intentionally. If nobody knows about their assignment then they avoid creating "no shows" and the workload progresses normally. + +We strongly prefer if postponements come from tranches higher aka less important than zero because tranche zero checks provide somewhat more security. + +TODO: When? Is this optimal for the network? etc. + +## On-chain verification + +We should verify approval on-chain to reward approval checkers. We therefore require the "no show" timeout to be longer than a relay chain slot so that we can witness "no shows" on-chain, which helps with this goal. The major challenge with an on-chain record of the off-chain process is adversarial block producers who may either censor votes or publish votes to the chain which cause other votes to be ignored and unrewarded (reward stealing). + +In principle, all validators have some "tranche" at which they're assigned to the parachain candidate, which ensures we reach enough validators eventually. As noted above, we often retract "no shows" when the slow validator eventually shows up, so witnessing their initially being a "no show" helps manage rewards. + +We expect on-chain verification should work in two phases: We first record assignments notices and approval votes on-chain in relay chain block, doing the VRF or regular signature verification again in block verification, and inserting chain authenticated unsigned notes into the relay chain state that contain the checker, tranche, paraid, and relay block height for each assignment notice. We then later have another relay chain block that runs some "approved" intrinsic, which extract all these notes from the state and feeds them into our approval code. + +We now encounter one niche concern in the interaction between postponement and on-chain verification: Any validator with a tranche zero (or other low) assignment could delay sending an assignment notice, like because they postponed their assigned tranche (which is allowed). If they later send this assignment notices right around finality time, then they race with this approved. intrinsic: If their announcement gets on-chain (also allowed), then yes it delays finality. If it does not get on-chain, then yes we've one announcement that the off-chain consensus system says is valid, but the chain ignores for being too slow. + +We need the chain to win in this case, but doing this requires imposing an annoyingly long overarching delay upon finality. We might explore limits on postponement too, but this sounds much harder. + +## Parameters + +We prefer doing approval checkers assignments under `RelayVRFModulo` as opposed to `RelayVRFDelay` because `RelayVRFModulo` avoids giving individual checkers too many assignments and tranche zero assignments benefit security the most. We suggest assigning at least 16 checkers under `RelayVRFModulo` although assignment levels have never been properly analyzed. + +Our delay criteria `RelayVRFDelay` and `RelayEquivocation` both have two primary paramaters, expected checkers per tranche and the zeroth delay tranche width. + +We require expected checkers per tranche to be less than three because otherwise an adversary with 1/3 stake could force all nodes into checking all blocks. We strongly recommend expected checkers per tranche to be less than two, which helps avoid both accidental and intentional explosions. We also suggest expected checkers per tranche be larger than one, which helps prevent adversaries from predicting than advancing one tranche adds only their own validators. + +We improve security more with tranche zero assignments, so `RelayEquivocation` should consolidates its first several tranches into tranche zero. We describe this as the zeroth delay tranche width, which initially we set to 12 for `RelayEquivocation` and `1` for `RelayVRFDelay`. + +## Why VRFs? + +We do assignments with VRFs to give "enough" checkers some meaning beyond merely "expected" checkers: + +We could specify a protocol that used only system randomness, which works because our strongest defense is the expected number of honest checkers who assign themselves. In this, adversaries could trivially flood their own blocks with their own checkers, so this strong defense becomes our only defense, and delay tranches become useless, so some blocks actually have zero approval checkers and possibly only one checker overall. + +VRFs though require adversaries wait far longer between such attacks, which also helps against adversaries with little at stake because they compromised validators. VRFs raise user confidence that no such "drive by" attacks occurred because the delay tranche system ensure at least some minimum number of approval checkers. In this vein, VRFs permit reducing backing checks and increasing approval checks, which makes polkadot more efficient. + +## Gossip + +Any validator could send their assignment notices and/or approval votes too early. We gossip the approval votes because they represent a major commitment by the validator. We retain but delay gossiping the assignment notices until they agree with our local clock. + +Assignment notices being gossiped too early might create a denial of service vector. If so, we might exploit the relative time scheme that synchronizes our clocks, which conceivably permits just dropping excessively early assignments. + +## Finality GRANDPA Voting Rule + +The relay-chain requires validators to participate in GRANDPA. In GRANDPA, validators submit off-chain votes on what they believe to be the best block of the chain, and GRANDPA determines the common block contained by a supermajority of sub-chains. There are also additional constraints on what can be submitted based on results of previous rounds of voting. + +In order to avoid finalizing anything which has not received enough approval votes or is disputed, we will pair the approval protocol with an alteration to the GRANDPA voting strategy for honest nodes which causes them to vote only on chains where every parachain candidate within has been approved. Furthermore, the voting rule prevents voting for chains where there is any live dispute or any dispute has resolved to a candidate being invalid. + +Thus, the finalized relay-chain should contain only relay-chain blocks where a majority believe that every block within has been sufficiently approved. + +### Future work + +We could consider additional gossip messages with which nodes claims "slow availability" and/or "slow candidate" to fine tune the assignments "no show" system, but long enough "no show" delays suffice probably. + +We shall develop more practical experience with UDP once the availability system works using direct UDP connections. In this, we should discover if reconstruction performs adequately with a complete graphs or +benefits from topology restrictions. At this point, an assignment notices could implicitly request pieces from a random 1/3rd, perhaps topology restricted, which saves one gossip round. If this preliminary fast reconstruction fails, then nodes' request alternative pieces directly. There is an interesting design space in how this overlaps with "slow availability" claims. diff --git a/polkadot/roadmap/implementers-guide/src/protocol-chain-selection.md b/polkadot/roadmap/implementers-guide/src/protocol-chain-selection.md new file mode 100644 index 0000000000000000000000000000000000000000..dd066df43cdde8e0f9c0e4ecd9364e2b7fb68fbd --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/protocol-chain-selection.md @@ -0,0 +1,48 @@ +# Chain Selection + +Chain selection processes in blockchains are used for the purpose of selecting blocks to build on and finalize. It is important for these processes to be consistent among nodes and resilient to a maximum proportion of malicious nodes which do not obey the chain selection process. + +The parachain host uses both a block authoring system and a finality gadget. The chain selection strategy of the parachain host involves two key components: a _leaf-selection_ rule and a set of _finality constraints_. When it's a validator's turn to author on a block, they are expected to select the best block via the leaf-selection rule to build on top of. When a validator is participating in finality, there is a minimum block which can be voted on, which is usually the finalized block. The validator should select the best chain according to the leaf-selection rule and subsequently apply the finality constraints to arrive at the actual vote cast by that validator. + +Before diving into the particularities of the leaf-selection rule and the finality constraints, it's important to discuss the goals that these components are meant to achieve. For this it is useful to create the definitions of _viable_ and _finalizable_ blocks. + +### Property Definitions + +A block is considered **viable** when all of the following hold: + 1. It is or descends from the finalized block + 2. It is not **stagnant** + 3. It is not **reverted**. + +A block is considered a **viable leaf** when all of the following hold: + 1. It is **viable** + 2. It has no **viable** descendant. + +A block is considered **stagnant** when either: + 1. It is unfinalized, is not approved, and has not been approved within 2 minutes + 2. Its parent is **stagnant**. + +A block is considered **reverted** when either: + 1. It is unfinalized and includes a candidate which has lost a dispute + 2. Its parent is **reverted** + +A block is considered **finalizable** when all of the following hold: + 1. It is **viable** + 2. Its parent, if unfinalized, is **finalizable**. + 3. It is either finalized or approved. + 4. It is either finalized or includes no candidates which have unresolved disputes or have lost a dispute. + + +### The leaf-selection rule + +We assume that every block has an implicit weight or score which can be used to compare blocks. In BABE, this is determined by the number of primary slots included in the chain. In PoW, this is the chain with either the most work or GHOST weight. + +The leaf-selection rule based on our definitions above is simple: we take the maximum-scoring viable leaf we are aware of. In the case of a tie we select the one with a lower lexicographical block hash. + +### The best-chain-containing rule + +Finality gadgets, as mentioned above, will often impose an additional requirement to vote on a chain containing a specific block, known as the **required** block. Although this is typically the most recently finalized block, it is possible that it may be a block that is unfinalized. When receiving such a request: +1. If the required block is the best finalized block, then select the best viable leaf. +2. If the required block is unfinalized and non-viable, then select the required block and go no further. This is likely an indication that something bad will be finalized in the network, which will never happen when approvals & disputes are functioning correctly. Nevertheless we account for the case here. +3. If the required block is unfinalized and viable, then iterate over the viable leaves in descending order by score and select the first one which contains the required block in its chain. Backwards iteration is a simple way to check this, but if unfinalized chains grow long then Merkle Mountain-Ranges will most likely be more efficient. + +Once selecting a leaf, the chain should be constrained to the maximum of the required block or the highest **finalizable** ancestor. diff --git a/polkadot/roadmap/implementers-guide/src/protocol-disputes.md b/polkadot/roadmap/implementers-guide/src/protocol-disputes.md new file mode 100644 index 0000000000000000000000000000000000000000..ebbc534f199237d5fd56348b4f6b0f180d16866f --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/protocol-disputes.md @@ -0,0 +1,67 @@ +# Disputes + +Fast forward to [more detailed disputes requirements](./disputes-flow.md). + +## Motivation and Background + +All parachain blocks that end up in the finalized relay chain should be valid. This does not apply to blocks that are only backed, but not included. + +We have two primary components for ensuring that nothing invalid ends up in the finalized relay chain: + * Approval Checking, as described [here](./protocol-approval.md) and implemented according to the [Approval Voting](node/approval/approval-voting.md) subsystem. This protocol can be shown to prevent invalid parachain blocks from making their way into the finalized relay chain as long as the amount of attempts are limited. + * Disputes, this protocol, which ensures that each attempt to include something bad is caught, and the offending validators are punished. +Disputes differ from backing and approval process (and can not be part of those) in that a dispute is independent of a particular fork, while both backing and approval operate on particular forks. This distinction is important! Approval voting stops, if an alternative fork which might not contain the currently approved candidate gets finalized. This is totally fine from the perspective of approval voting as its sole purpose is to make sure invalid blocks won't get finalized. For disputes on the other hand we have different requirements: Even though the "danger" is past and the adversaries were not able to get their invalid block approved, we still want them to get slashed for the attempt. Otherwise they just have been able to get a free try, but this is something we need to avoid in our security model, as it is based on the assumption that the probability of getting an invalid block finalized is very low and an attacker would get bankrupt before it could have tried often enough. + +Every dispute stems from a disagreement among two or more validators. If a bad actor creates a bad block, but the bad actor never distributes it to honest validators, then nobody will dispute it. Of course, such a situation is not even an attack on the network, so we don't need to worry about defending against it. + +We are interested in identifying and deterring the following attack scenario: + * A parablock included on a branch of the relay chain is bad + +We are also interested in identifying these additional scenarios: + * A parablock backed on a branch of the relay chain is bad + * A parablock seconded, but not backed on any branch of the relay chain, is bad. + +Punishing misbehavior in the latter two scenarios doesn't effect our security guarantees and introduces substantial technical challenges as described in the `No Disputes for Non Included Candidates` section of [Dispute Coordinator](./node/disputes/dispute-coordinator.md). We therefore choose to punt on disputes in these cases, instead favoring the protocol simplicity resulting from only punishing in the first scenario. + +As covered in the [protocol overview](./protocol-overview.md), checking a parachain block requires 3 pieces of data: the parachain validation code, the [`AvailableData`](types/availability.md), and the [`CandidateReceipt`](types/candidate.md). The validation code is available on-chain, and published ahead of time, so that no two branches of the relay chain have diverging views of the validation code for a given parachain. Note that only for the first scenario, where the parablock has been included on a branch of the relay chain, is the data necessarily available. Thus, dispute processes should begin with an availability process to ensure availability of the `AvailableData`. This availability process will conclude quickly if the data is already available. If the data is not already available, then the initiator of the dispute must make it available. + +Disputes have both an on-chain and an off-chain component. Slashing and punishment is handled on-chain, so votes by validators on either side of the dispute must be placed on-chain. Furthermore, a dispute on one branch of the relay chain should be transposed to all other active branches of the relay chain. The fact that slashing occurs _in all histories_ is crucial for deterring attempts to attack the network. The attacker should not be able to escape with their funds because the network has moved on to another branch of the relay chain where no attack was attempted. + +In fact, this is why we introduce a distinction between _local_ and _remote_ disputes. We categorize disputes as either local or remote relative to any particular branch of the relay chain. Local disputes are about dealing with our first scenario, where a parablock has been included on the specific branch we are looking at. In these cases, the chain is corrupted all the way back to the point where the parablock was backed and must be discarded. However, as mentioned before, the dispute must propagate to all other branches of the relay chain. All other disputes are considered _remote_. For the on-chain component, when handling a dispute for a block which was not included in the current fork of the relay chain, it is impossible to discern between our attack scenarios. It is possible that the parablock was included somewhere, or backed somewhere, or wasn't backed anywhere. The on-chain component for handling these cases will be the same. + +## Initiation + +Disputes are initiated by any validator who finds their opinion on the validity of a parablock in opposition to another issued statement. As all statements currently gathered by the relay chain imply validity, disputes will be initiated only by nodes which perceive that the parablock is bad. + +The initiation of a dispute begins off-chain. A validator signs a message indicating that it disputes the validity of the parablock and notifies all other validators, off-chain, of all of the statements it is aware of for the disputed parablock. These may be backing statements or approval-checking statements. It is worth noting that there is no special message type for initiating a dispute. It is the same message as is used to participate in a dispute and vote negatively. As such, there is no consensus required on who initiated a dispute, only on the fact that there is a dispute in-progress. + +In practice, the initiator of a dispute will be either one of the backers or one of the approval checkers for the parablock. If the result of execution is found to be invalid, the validator will initiate the dispute as described above. Furthermore, if the dispute occurs during the backing phase, the initiator must make the data available to other validators. If the dispute occurs during approval checking, the data is already available. + +Lastly, it is possible that for backing disputes, i.e. where the data is not already available among all validators, that an adversary may DoS the few parties who are checking the block to prevent them from distributing the data to other validators participating in the dispute process. Note that this can only occur pre-inclusion for any given parablock, so the downside of this attack is small and it is not security-critical to address these cases. However, we assume that the adversary can only prevent the validator from issuing messages for a limited amount of time. We also assume that there is a side-channel where the relay chain's governance mechanisms can trigger disputes by providing the full PoV and candidate receipt on-chain manually. + +## Dispute Participation + +Once becoming aware of a dispute, it is the responsibility of all validators to participate in the dispute. Concretely, this means: + * Circulate all statements about the candidate that we are aware of - backing statements, approval checking statements, and dispute statements. + * If we have already issued any type of statement about the candidate, go no further. + * Download the [`AvailableData`](types/availability.md). If possible, this should first be attempted from other dispute participants or backing validators, and then [(via erasure-coding)](node/availability/availability-recovery.md) from all validators. + * Extract the Validation Code from any recent relay chain block. Code is guaranteed to be kept available on-chain, so we don't need to download any particular fork of the chain. + * Execute the block under the validation code, using the `AvailableData`, and check that all outputs are correct, including the `erasure-root` of the [`CandidateReceipt`](types/candidate.md). + * Issue a dispute participation statement to the effect of the validity of the candidate block. + +Disputes _conclude_ after ⅔ supermajority is reached in either direction. + +The on-chain component of disputes can be initiated by providing any two conflicting votes and it also waits for a ⅔ supermajority on either side. The on-chain component also tracks which parablocks have already been disputed so the same parablock may only be disputed once on any particular branch of the relay chain. Lastly, it also tracks which blocks have been included on the current branch of the relay chain. When a dispute is initiated for a para, inclusion is halted for the para until the dispute concludes. + +The author of a relay chain block should initiate the on-chain component of disputes for all disputes which the chain is not aware of, and provide all statements to the on-chain component as well. This should all be done via _inherents_. + +Validators can learn about dispute statements in two ways: + * Receiving them from other validators over gossip + * Scraping them from imported blocks of the relay chain. This is also used for validators to track other types of statements, such as backing statements. + +Validators are rewarded for providing statements to the chain as well as for participating in the dispute, on either side. However, the losing side of the dispute is slashed. + +## Dispute Conclusion + +Disputes, roughly, are over when one side reaches a ⅔ supermajority. They may also never conclude without either side witnessing supermajority, which will only happen if the majority of validators are unable to vote for some reason. Furthermore, disputes on-chain will stay open for some fixed amount of time even after concluding, to accept new votes. + +Late votes, after the dispute already reached a ⅔ supermajority, must be rewarded (albeit a smaller amount) as well. diff --git a/polkadot/roadmap/implementers-guide/src/protocol-overview.md b/polkadot/roadmap/implementers-guide/src/protocol-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..fa5a866e6121b4e1607332f7c9bb5ffb795ed658 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/protocol-overview.md @@ -0,0 +1,219 @@ +# Protocol Overview + +This section aims to describe, at a high level, the actors and protocols involved in running parachains in Polkadot. Specifically, we describe how different actors communicate with each other, what data structures they keep both individually and collectively, and the high-level purpose on why they do these things. + +Our top-level goal is to carry a parachain block from authoring to secure inclusion, and define a process which can be carried out repeatedly and in parallel for many different parachains to extend them over time. Understanding of the high-level approach taken here is important to provide context for the proposed architecture further on. The key parts of Polkadot relevant to this are the main Polkadot blockchain, known as the relay-chain, and the actors which provide security and inputs to this blockchain. + +First, it's important to go over the main actors we have involved in this protocol. + +1. Validators. These nodes are responsible for validating proposed parachain blocks. They do so by checking a Proof-of-Validity (PoV) of the block and ensuring that the PoV remains available. They put financial capital down as "skin in the game" which can be slashed (destroyed) if they are proven to have misvalidated. +1. Collators. These nodes are responsible for creating the Proofs-of-Validity that validators know how to check. Creating a PoV typically requires familiarity with the transaction format and block authoring rules of the parachain, as well as having access to the full state of the parachain. + +This implies a simple pipeline where collators send validators parachain blocks and their requisite PoV to check. Then, validators validate the block using the PoV, signing statements which describe either the positive or negative outcome, and with enough positive statements, the block can be noted on the relay-chain. Negative statements are not a veto but will lead to a dispute, with those on the wrong side being slashed. If another validator later detects that a validator or group of validators incorrectly signed a statement claiming a block was valid, then those validators will be _slashed_, with the checker receiving a bounty. + +However, there is a problem with this formulation. In order for another validator to check the previous group of validators' work after the fact, the PoV must remain _available_ so the other validator can fetch it in order to check the work. The PoVs are expected to be too large to include in the blockchain directly, so we require an alternate _data availability_ scheme which requires validators to prove that the inputs to their work will remain available, and so their work can be checked. Empirical tests tell us that many PoVs may be between 1 and 10MB during periods of heavy load. + +Here is a description of the Inclusion Pipeline: the path a parachain block (or parablock, for short) takes from creation to inclusion: + +1. Validators are selected and assigned to parachains by the Validator Assignment routine. +1. A collator produces the parachain block, which is known as a parachain candidate or candidate, along with a PoV for the candidate. +1. The collator forwards the candidate and PoV to validators assigned to the same parachain via the [Collator Protocol](node/collators/collator-protocol.md). +1. The validators assigned to a parachain at a given point in time participate in the [Candidate Backing subsystem](node/backing/candidate-backing.md) to validate candidates that were put forward for validation. Candidates which gather enough signed validity statements from validators are considered "backable". Their backing is the set of signed validity statements. +1. A relay-chain block author, selected by BABE, can note up to one (1) backable candidate for each parachain to include in the relay-chain block alongside its backing. A backable candidate once included in the relay-chain is considered backed in that fork of the relay-chain. +1. Once backed in the relay-chain, the parachain candidate is considered to be "pending availability". It is not considered to be included as part of the parachain until it is proven available. +1. In the following relay-chain blocks, validators will participate in the [Availability Distribution subsystem](node/availability/availability-distribution.md) to ensure availability of the candidate. Information regarding the availability of the candidate will be noted in the subsequent relay-chain blocks. +1. Once the relay-chain state machine has enough information to consider the candidate's PoV as being available, the candidate is considered to be part of the parachain and is graduated to being a full parachain block, or parablock for short. + +Note that the candidate can fail to be included in any of the following ways: + +- The collator is not able to propagate the candidate to any validators assigned to the parachain. +- The candidate is not backed by validators participating in the Candidate Backing Subsystem. +- The candidate is not selected by a relay-chain block author to be included in the relay chain +- The candidate's PoV is not considered as available within a timeout and is discarded from the relay chain. + +This process can be divided further down. Steps 2 & 3 relate to the work of the collator in collating and distributing the candidate to validators via the Collation Distribution Subsystem. Steps 3 & 4 relate to the work of the validators in the Candidate Backing Subsystem and the block author (itself a validator) to include the block into the relay chain. Steps 6, 7, and 8 correspond to the logic of the relay-chain state-machine (otherwise known as the Runtime) used to fully incorporate the block into the chain. Step 7 requires further work on the validators' parts to participate in the Availability Distribution Subsystem and include that information into the relay chain for step 8 to be fully realized. + +This brings us to the second part of the process. Once a parablock is considered available and part of the parachain, it is still "pending approval". At this stage in the pipeline, the parablock has been backed by a majority of validators in the group assigned to that parachain, and its data has been guaranteed available by the set of validators as a whole. Once it's considered available, the host will even begin to accept children of that block. At this point, we can consider the parablock as having been tentatively included in the parachain, although more confirmations are desired. However, the validators in the parachain-group (known as the "Parachain Validators" for that parachain) are sampled from a validator set which contains some proportion of byzantine, or arbitrarily malicious members. This implies that the Parachain Validators for some parachain may be majority-dishonest, which means that (secondary) approval checks must be done on the block before it can be considered approved. This is necessary only because the Parachain Validators for a given parachain are sampled from an overall validator set which is assumed to be up to <1/3 dishonest - meaning that there is a chance to randomly sample Parachain Validators for a parachain that are majority or fully dishonest and can back a candidate wrongly. The Approval Process allows us to detect such misbehavior after-the-fact without allocating more Parachain Validators and reducing the throughput of the system. A parablock's failure to pass the approval process will invalidate the block as well as all of its descendants. However, only the validators who backed the block in question will be slashed, not the validators who backed the descendants. + +The Approval Process, at a glance, looks like this: + +1. Parablocks that have been included by the Inclusion Pipeline are pending approval for a time-window known as the secondary checking window. +1. During the secondary-checking window, validators randomly self-select to perform secondary checks on the parablock. +1. These validators, known in this context as secondary checkers, acquire the parablock and its PoV, and re-run the validation function. +1. The secondary checkers gossip the result of their checks. Contradictory results lead to escalation, where all validators are required to check the block. The validators on the losing side of the dispute are slashed. +1. At the end of the Approval Process, the parablock is either Approved or it is rejected. More on the rejection process later. + +More information on the Approval Process can be found in the dedicated section on [Approval](protocol-approval.md). More information on Disputes can be found in the dedicated section on [Disputes](protocol-disputes.md). + +These two pipelines sum up the sequence of events necessary to extend and acquire full security on a Parablock. Note that the Inclusion Pipeline must conclude for a specific parachain before a new block can be accepted on that parachain. After inclusion, the Approval Process kicks off, and can be running for many parachain blocks at once. + +Reiterating the lifecycle of a candidate: + +1. Candidate: put forward by a collator to a validator. +1. Seconded: put forward by a validator to other validators +1. Backable: validity attested to by a majority of assigned validators +1. Backed: Backable & noted in a fork of the relay-chain. +1. Pending availability: Backed but not yet considered available. +1. Included: Backed and considered available. +1. Accepted: Backed, available, and undisputed + +```dot process Inclusion Pipeline +digraph { + subgraph cluster_vg { + label=< + Parachain Validators +
+ (subset of all) + > + labeljust=l + style=filled + color=lightgrey + node [style=filled color=white] + + v1 [label="Validator 1"] + v2 [label="Validator 2"] + v3 [label="Validator 3"] + + b [label="(3) Backable", shape=box] + + v1 -> v2 [label="(2) Seconded"] + v1 -> v3 [label="(2) Seconded"] + + v2 -> b [style=dashed arrowhead=none] + v3 -> b [style=dashed arrowhead=none] + v1 -> b [style=dashed arrowhead=none] + } + + v4 [label=< + Validator 4 (relay chain) +
+ + (selected by BABE) + + >] + + col [label="Collator"] + pa [label="(5) Relay Block (Pending Availability)", shape=box] + pb [label="Parablock", shape=box] + rc [label="Relay Chain Validators"] + + subgraph cluster_approval { + label=< + Secondary Checkers +
+ (subset of all) + > + labeljust=l + style=filled + color=lightgrey + node [style=filled color=white] + + a5 [label="Validator 5"] + a6 [label="Validator 6"] + a7 [label="Validator 7"] + } + + b -> v4 [label="(4) Backed"] + col -> v1 [label="(1) Candidate"] + v4 -> pa + pa -> pb [label="(6) a few blocks later..." arrowhead=none] + pb -> a5 + pb -> a6 + pb -> a7 + + a5 -> rc [label="(7) Approved"] + a6 -> rc [label="(7) Approved"] + a7 -> rc [label="(7) Approved"] +} +``` + +The diagram above shows the happy path of a block from (1) Candidate to the (7) Approved state. + +It is also important to take note of the fact that the relay-chain is extended by BABE, which is a forkful algorithm. That means that different block authors can be chosen at the same time, and may not be building on the same block parent. Furthermore, the set of validators is not fixed, nor is the set of parachains. And even with the same set of validators and parachains, the validators' assignments to parachains is flexible. This means that the architecture proposed in the next chapters must deal with the variability and multiplicity of the network state. + + +```dot process +digraph { + rca [label="Relay Block A" shape=box] + rcb [label="Relay Block B" shape=box] + rcc [label="Relay Block C" shape=box] + + vg1 [label=< + Validator Group 1 +
+
+ + (Validator 4) +
+ (Validator 1) (Validator 2) +
+ (Validator 5) +
+ >] + vg2 [label=< + Validator Group 2 +
+
+ + (Validator 7) +
+ (Validator 3) (Validator 6) +
+ >] + + rcb -> rca + rcc -> rcb + + vg1 -> rcc [label="Building on C" style=dashed arrowhead=none] + vg2 -> rcb [label="Building on B" style=dashed arrowhead=none] +} +``` + +In this example, group 1 has received block C while the others have not due to network asynchrony. Now, a validator from group 2 may be able to build another block on top of B, called `C'`. Assume that afterwards, some validators become aware of both C and `C'`, while others remain only aware of one. + +```dot process +digraph { + rca [label="Relay Block A" shape=box] + rcb [label="Relay Block B" shape=box] + rcc [label="Relay Block C" shape=box] + rcc_prime [label="Relay Block C'" shape=box] + + vg1 [label=< + Validator Group 1 +
+
+ + (Validator 4) (Validator 1) + + >] + vg2 [label=< + Validator Group 2 +
+
+ + (Validator 7) (Validator 6) + + >] + vg3 [label=< + Validator Group 3 +
+
+ + (Validator 2) (Validator 3) +
+ (Validator 5) +
+ >] + + rcb -> rca + rcc -> rcb + rcc_prime -> rcb + + vg1 -> rcc [style=dashed arrowhead=none] + vg2 -> rcc_prime [style=dashed arrowhead=none] + vg3 -> rcc_prime [style=dashed arrowhead=none] + vg3 -> rcc [style=dashed arrowhead=none] +} +``` + +Those validators that are aware of many competing heads must be aware of the work happening on each one. They may contribute to some or a full extent on both. It is possible that due to network asynchrony two forks may grow in parallel for some time, although in the absence of an adversarial network this is unlikely in the case where there are validators who are aware of both chain heads. diff --git a/polkadot/roadmap/implementers-guide/src/pvf-prechecking.md b/polkadot/roadmap/implementers-guide/src/pvf-prechecking.md new file mode 100644 index 0000000000000000000000000000000000000000..91cc8f9b6a20d72912704fe943420037b22144cf --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/pvf-prechecking.md @@ -0,0 +1,73 @@ +# PVF Pre-checking Overview + +## Motivation + +Parachains' validation function is described by a wasm module that we refer to as a PVF. Since a PVF is a wasm module the typical way of executing it is to compile it to machine code. + +Typically an optimizing compiler consists of algorithms that are able to optimize the resulting machine code heavily. However, while those algorithms perform quite well for a typical wasm code produced by standard toolchains (e.g. rustc/LLVM), those algorithms can be abused to consume a lot of resources. Moreover, since those algorithms are rather complex there is a lot of room for a bug that can crash the compiler. + +If compilation of a Parachain Validation Function (PVF) takes too long or uses too much memory, this can leave a node in limbo as to whether a candidate of that parachain is valid or not. + +The amount of time that a PVF takes to compile is a subjective resource limit and as such PVFs may be maliciously crafted so that there is e.g. a 50/50 split of validators which can and cannot compile and execute the PVF. + +This has the following implications: +- In backing, inclusion may be slow due to backing groups being unable to execute the block +- In approval checking, there may be many no-shows, leading to slow finality +- In disputes, neither side may reach supermajority. Nobody will get slashed and the chain will not be reverted or finalized. + +As a result of this issue we need a fairly hard guarantee that the PVFs of registered parachains/threads can be compiled within a reasonable amount of time. + +## Solution + +The problem is solved by having a pre-checking process. + +### Pre-checking + +Pre-checking mostly consists of attempting to prepare (compile) the PVF WASM blob. We use more strict limits (e.g. timeouts) here compared to regular preparation for execution. This way errors during preparation later are likely unrelated to the PVF itself, as it already passed pre-checking. We can treat such errors as local node issues. + +We also have an additional step where we attempt to instantiate the WASM runtime without running it. This is unrelated to preparation so we don't time it, but it does help us catch more issues. + +### Protocol + +Pre-checking is run when a new validation code is included in the chain. A new PVF can be added in two cases: + +- A new parachain is registered. +- An existing parachain signalled an upgrade of its validation code. + +Before any of those operations finish, the PVF pre-checking vote is initiated. The PVF pre-checking vote is identified by the PVF code hash that is being voted on. If there is already PVF pre-checking process running, then no +new PVF pre-checking vote will be started. Instead, the operation just subscribes to the existing vote. + +The pre-checking vote can be concluded either by obtaining a threshold of votes for a decision, or if it expires. The threshold to accept is a supermajority of 2/3 of validators. We reject once a supermajority is no longer possible. + +Each validator checks the list of PVFs available for voting. The vote is binary, i.e. accept or reject a given PVF. As soon as the threshold of votes are collected for one of the sides of the vote, the voting is concluded in that direction and the effects of the voting are enacted. + +Only validators from the active set can participate in the vote. The set of active validators can change each session. That's why we reset the votes each session. A voting that observed a certain number of sessions will be rejected. + +The effects of the PVF accepting depend on the operations requested it: + +1. All onboardings subscribed to the approved PVF pre-checking process will get scheduled and after passing 2 session boundaries they will be onboarded. +1. All upgrades subscribed to the approved PVF pre-checking process will get scheduled very similarly to the existing process. Upgrades with pre-checking are really the same process that is just delayed by the time required for pre-checking voting. In case of instant approval the mechanism is exactly the same. + +In case PVF pre-checking process was concluded with rejection, then all the operations that are subscribed to the rejected PVF pre-checking process will be processed as follows. That is, onboarding or upgrading will be cancelled. + +The logic described above is implemented by the [paras] module. + +### Subsystem + +On the node-side, there is a PVF pre-checking [subsystem][pvf-prechecker-subsystem] that scans the chain for new PVFs via using [runtime APIs][pvf-runtime-api]. Upon finding a new PVF, the subsystem will initiate a PVF pre-checking request and wait for the result. Whenever the result is obtained, the subsystem will use the [runtime API][pvf-runtime-api] to submit a vote for the PVF. The vote is an unsigned transaction. The vote will be distributed via the gossip similarly to a normal transaction. Eventually a block producer will include the vote into the block where it will be handled by the [runtime][paras]. + +## Summary + +Parachains' validation function is described by a wasm module that we refer to as a PVF. + +In order to make the PVF usable for candidate validation it has to be registered on-chain. + +As part of the registration process, it has to go through pre-checking. Pre-checking is a game of attempting preparation and additional checks, and reporting the results back on-chain. + +We define preparation as a process that: validates the consistency of the wasm binary (aka prevalidation) and the compilation of the wasm module into machine code (referred to as an artifact). + +Besides pre-checking, preparation can also be triggered by execution, since a compiled artifact is needed for the execution. If an artifact already exists, execution will skip preparation. If it does do preparation, execution uses a more lenient timeout than preparation, to avoid the situation where honest validators fail on valid, pre-checked PVFs. + +[paras]: runtime/paras.md +[pvf-runtime-api]: runtime-api/pvf-prechecking.md +[pvf-prechecker-subsystem]: node/utility/pvf-prechecker.md diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/README.md b/polkadot/roadmap/implementers-guide/src/runtime-api/README.md new file mode 100644 index 0000000000000000000000000000000000000000..740ffd38ccee831a58e7fda2e7d1d64171b46856 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/README.md @@ -0,0 +1,55 @@ +# Runtime APIs + +Runtime APIs are the means by which the node-side code extracts information from the state of the runtime. + +Every block in the relay-chain contains a *state root* which is the root hash of a state trie encapsulating all storage of runtime modules after execution of the block. This is a cryptographic commitment to a unique state. We use the terminology of accessing the *state at* a block to refer accessing the state referred to by the state root of that block. + +Although Runtime APIs are often used for simple storage access, they are actually empowered to do arbitrary computation. The implementation of the Runtime APIs lives within the Runtime as Wasm code and exposes `extern` functions that can be invoked with arguments and have a return value. Runtime APIs have access to a variety of host functions, which are contextual functions provided by the Wasm execution context, that allow it to carry out many different types of behaviors. + +Abilities provided by host functions includes: + +* State Access +* Offchain-DB Access +* Submitting transactions to the transaction queue +* Optimized versions of cryptographic functions +* More + +So it is clear that Runtime APIs are a versatile and powerful tool to leverage the state of the chain. In general, we will use Runtime APIs for these purposes: + +* Access of a storage item +* Access of a bundle of related storage items +* Deriving a value from storage based on arguments +* Submitting misbehavior reports + +More broadly, we have the goal of using Runtime APIs to write Node-side code that fulfills the requirements set by the Runtime. In particular, the constraints set forth by the [Scheduler](../runtime/scheduler.md) and [Inclusion](../runtime/inclusion.md) modules. These modules are responsible for advancing paras with a two-phase protocol where validators are first chosen to validate and back a candidate and then required to ensure availability of referenced data. In the second phase, validators are meant to attest to those para-candidates that they have their availability chunk for. As the Node-side code needs to generate the inputs into these two phases, the runtime API needs to transmit information from the runtime that is aware of the Availability Cores model instantiated by the Scheduler and Inclusion modules. + +Node-side code is also responsible for detecting and reporting misbehavior performed by other validators, and the set of Runtime APIs needs to provide methods for observing live disputes and submitting reports as transactions. + +The next sections will contain information on specific runtime APIs. The format is this: + +```rust +/// Fetch the value of the runtime API at the block. +/// +/// Definitionally, the `at` parameter cannot be any block that is not in the chain. +/// Thus the return value is unconditional. However, for in-practice implementations +/// it may be possible to provide an `at` parameter as a hash, which may not refer to a +/// valid block or one which implements the runtime API. In those cases it would be +/// best for the implementation to return an error indicating the failure mode. +fn some_runtime_api(at: Block, arg1: Type1, arg2: Type2, ...) -> ReturnValue; +``` + +Certain runtime APIs concerning the state of a para require the caller to provide an `OccupiedCoreAssumption`. This indicates how the result of the runtime API should be computed if there is a candidate from the para occupying an availability core in the [Inclusion Module](../runtime/inclusion.md). + +The choices of assumption are whether the candidate occupying that core should be assumed to have been made available and included or timed out and discarded, along with a third option to assert that the core was not occupied. This choice affects everything from the parent head-data, the validation code, and the state of message-queues. Typically, users will take the assumption that either the core was free or that the occupying candidate was included, as timeouts are expected only in adversarial circumstances and even so, only in a small minority of blocks directly following validator set rotations. + +```rust +/// An assumption being made about the state of an occupied core. +enum OccupiedCoreAssumption { + /// The candidate occupying the core was made available and included to free the core. + Included, + /// The candidate occupying the core timed out and freed the core without advancing the para. + TimedOut, + /// The core was not occupied to begin with. + Free, +} +``` \ No newline at end of file diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/availability-cores.md b/polkadot/roadmap/implementers-guide/src/runtime-api/availability-cores.md new file mode 100644 index 0000000000000000000000000000000000000000..9402924f0013a67e2623fdc48710f7ef60bf8b76 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/availability-cores.md @@ -0,0 +1,59 @@ +# Availability Cores + +Yields information on all availability cores. Cores are either free or occupied. Free cores can have paras assigned to them. Occupied cores don't, but they can become available part-way through a block due to bitfields and then have something scheduled on them. To allow optimistic validation of candidates, the occupied cores are accompanied by information on what is upcoming. This information can be leveraged when validators perceive that there is a high likelihood of a core becoming available based on bitfields seen, and then optimistically validate something that would become scheduled based on that, although there is no guarantee on what the block producer will actually include in the block. + +See also the [Scheduler Module](../runtime/scheduler.md) for a high-level description of what an availability core is and why it exists. + +```rust +fn availability_cores(at: Block) -> Vec; +``` + +This is all the information that a validator needs about scheduling for the current block. It includes all information on [Scheduler](../runtime/scheduler.md) core-assignments and [Inclusion](../runtime/inclusion.md) state of blocks occupying availability cores. It includes data necessary to determine not only which paras are assigned now, but which cores are likely to become freed after processing bitfields, and exactly which bitfields would be necessary to make them so. The implementation of this runtime API should invoke `Scheduler::clear` and `Scheduler::schedule(Vec::new(), current_block_number + 1)` to ensure that scheduling is accurate. + +```rust +struct OccupiedCore { + // NOTE: this has no ParaId as it can be deduced from the candidate descriptor. + /// If this core is freed by availability, this is the assignment that is next up on this + /// core, if any. None if there is nothing queued for this core. + next_up_on_available: Option, + /// The relay-chain block number this began occupying the core at. + occupied_since: BlockNumber, + /// The relay-chain block this will time-out at, if any. + time_out_at: BlockNumber, + /// If this core is freed by being timed-out, this is the assignment that is next up on this + /// core. None if there is nothing queued for this core or there is no possibility of timing + /// out. + next_up_on_time_out: Option, + /// A bitfield with 1 bit for each validator in the set. `1` bits mean that the corresponding + /// validators has attested to availability on-chain. A 2/3+ majority of `1` bits means that + /// this will be available. + availability: Bitfield, + /// The group assigned to distribute availability pieces of this candidate. + group_responsible: GroupIndex, + /// The hash of the candidate occupying the core. + candidate_hash: CandidateHash, + /// The descriptor of the candidate occupying the core. + candidate_descriptor: CandidateDescriptor, +} + +struct ScheduledCore { + /// The ID of a para scheduled. + para_id: ParaId, + /// The collator required to author the block, if any. + collator: Option, +} + +enum CoreState { + /// The core is currently occupied. + Occupied(OccupiedCore), + /// The core is currently free, with a para scheduled and given the opportunity + /// to occupy. + /// + /// If a particular Collator is required to author this block, that is also present in this + /// variant. + Scheduled(ScheduledCore), + /// The core is currently free and there is nothing scheduled. This can be the case for on-demand + /// cores when there are no on-demand parachain blocks queued. Leased cores will never be left idle. + Free, +} +``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/candidate-events.md b/polkadot/roadmap/implementers-guide/src/runtime-api/candidate-events.md new file mode 100644 index 0000000000000000000000000000000000000000..1bea22745a05a2baac343ff34905b97fb8b3636e --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/candidate-events.md @@ -0,0 +1,16 @@ +# Candidate Events + +Yields a vector of events concerning candidates that occurred within the given block. + +```rust +enum CandidateEvent { + /// This candidate receipt was backed in the most recent block. + CandidateBacked(CandidateReceipt, HeadData, CoreIndex, GroupIndex), + /// This candidate receipt was included and became a parablock at the most recent block. + CandidateIncluded(CandidateReceipt, HeadData, CoreIndex, GroupIndex), + /// This candidate receipt was not made available in time and timed out. + CandidateTimedOut(CandidateReceipt, HeadData, CoreIndex), +} + +fn candidate_events(at: Block) -> Vec; +``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/candidate-pending-availability.md b/polkadot/roadmap/implementers-guide/src/runtime-api/candidate-pending-availability.md new file mode 100644 index 0000000000000000000000000000000000000000..9c8969f6a958b2cce360ad83c1dc1e57d91e207e --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/candidate-pending-availability.md @@ -0,0 +1,7 @@ +# Candidate Pending Availability + +Get the receipt of a candidate pending availability. This returns `Some` for any paras assigned to occupied cores in `availability_cores` and `None` otherwise. + +```rust +fn candidate_pending_availability(at: Block, ParaId) -> Option; +``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/candidates-included.md b/polkadot/roadmap/implementers-guide/src/runtime-api/candidates-included.md new file mode 100644 index 0000000000000000000000000000000000000000..7692c422833d49f477584b5fe127d422138932da --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/candidates-included.md @@ -0,0 +1,8 @@ +# Candidates Included + +This runtime API is for checking which candidates have been included within the chain, locally. + +```rust +/// Input and output have the same length. +fn candidates_included(Vec<(SessionIndex, CandidateHash)>) -> Vec; +``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/disputes-info.md b/polkadot/roadmap/implementers-guide/src/runtime-api/disputes-info.md new file mode 100644 index 0000000000000000000000000000000000000000..3548d5fb5793a2e664f4ec3d681ec5e609471919 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/disputes-info.md @@ -0,0 +1,24 @@ +# Disputes Info + +Get information about all disputes known by the chain as well as information about which validators the disputes subsystem will accept disputes from. These disputes may be either live or concluded. The [`DisputeState`](../types/disputes.md#disputestate) can be used to determine whether the dispute still accepts votes, as well as which validators' votes may be included. + +```rust +struct Dispute { + session: SessionIndex, + candidate: CandidateHash, + dispute_state: DisputeState, + local: bool, +} + +struct SpamSlotsInfo { + max_spam_slots: u32, + session_spam_slots: Vec<(SessionIndex, Vec)>, +} + +struct DisputesInfo { + disputes: Vec, + spam_slots: SpamSlotsInfo, +} + +fn disputes_info() -> DisputesInfo; +``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/persisted-validation-data.md b/polkadot/roadmap/implementers-guide/src/runtime-api/persisted-validation-data.md new file mode 100644 index 0000000000000000000000000000000000000000..2fd3e55c8712c5c85193ee60b9e6c736dc0ec2b7 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/persisted-validation-data.md @@ -0,0 +1,11 @@ +# Persisted Validation Data + +Yields the [`PersistedValidationData`](../types/candidate.md#persistedvalidationdata) for the given [`ParaId`](../types/candidate.md#paraid) along with an assumption that should be used if the para currently occupies a core: + +```rust +/// Returns the persisted validation data for the given para and occupied core assumption. +/// +/// Returns `None` if either the para is not registered or the assumption is `Freed` +/// and the para already occupies a core. +fn persisted_validation_data(at: Block, ParaId, OccupiedCoreAssumption) -> Option; +``` \ No newline at end of file diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/pvf-prechecking.md b/polkadot/roadmap/implementers-guide/src/runtime-api/pvf-prechecking.md new file mode 100644 index 0000000000000000000000000000000000000000..c74232367bff5de1084f1fe41312c6f5767b3cfa --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/pvf-prechecking.md @@ -0,0 +1,22 @@ +# PVF Pre-checking + +> ⚠️ This runtime API was added in v2. + +There are two main runtime APIs to work with PVF pre-checking. + +The first runtime API is designed to fetch all PVFs that require pre-checking voting. The PVFs are +identified by their code hashes. As soon as the PVF gains required support, the runtime API will +not return the PVF anymore. + +```rust +fn pvfs_require_precheck() -> Vec; +``` + +The second runtime API is needed to submit the judgement for a PVF, whether it is approved or not. +The voting process uses unsigned transactions. The [`PvfCheckStatement`](../types/pvf-prechecking.md) is circulated through the network via gossip similar to a normal transaction. At some point the validator +will include the statement in the block, where it will be processed by the runtime. If that was the +last vote before gaining the super-majority, this PVF will not be returned by `pvfs_require_precheck` anymore. + +```rust +fn submit_pvf_check_statement(stmt: PvfCheckStatement, signature: ValidatorSignature); +``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/session-index.md b/polkadot/roadmap/implementers-guide/src/runtime-api/session-index.md new file mode 100644 index 0000000000000000000000000000000000000000..1baf6a167dbb2543a1b6080dbe22dac266827fd5 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/session-index.md @@ -0,0 +1,12 @@ +# Session Index + +Get the session index that is expected at the child of a block. + +In the [`Initializer`](../runtime/initializer.md) module, session changes are buffered by one block. The session index of the child of any relay block is always predictable by that block's state. + +This session index can be used to derive a [`SigningContext`](../types/candidate.md#signing-context). + +```rust +/// Returns the session index expected at a child of the block. +fn session_index_for_child(at: Block) -> SessionIndex; +``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/validation-code.md b/polkadot/roadmap/implementers-guide/src/runtime-api/validation-code.md new file mode 100644 index 0000000000000000000000000000000000000000..84c4e37a73769afef9c0ec83485917f3439825d6 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/validation-code.md @@ -0,0 +1,21 @@ +# Validation Code + +Fetch the validation code used by a para, making the given `OccupiedCoreAssumption`. + +```rust +fn validation_code(at: Block, ParaId, OccupiedCoreAssumption) -> Option; +``` + +Fetch the validation code (past, present or future) by its hash. + +```rust +fn validation_code_by_hash(at: Block, ValidationCodeHash) -> Option; +``` + +Fetch the validation code hash used by a para, making the given `OccupiedCoreAssumption`. + +> ⚠️ This API was introduced in `ParachainHost` v2. + +```rust +fn validation_code_hash(at: Block, ParaId, OccupiedCoreAssumption) -> Option; +``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/validator-groups.md b/polkadot/roadmap/implementers-guide/src/runtime-api/validator-groups.md new file mode 100644 index 0000000000000000000000000000000000000000..8815a0217411773789f5d844991976ab84e70b67 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/validator-groups.md @@ -0,0 +1,31 @@ +# Validator Groups + +Yields the validator groups used during the current session. The validators in the groups are referred to by their index into the validator-set and this is assumed to be as-of the child of the block whose state is being queried. + +```rust +/// A helper data-type for tracking validator-group rotations. +struct GroupRotationInfo { + session_start_block: BlockNumber, + group_rotation_frequency: BlockNumber, + now: BlockNumber, // The successor of the block in whose state this runtime API is queried. +} + +impl GroupRotationInfo { + /// Returns the index of the group needed to validate the core at the given index, + /// assuming the given amount of cores/groups. + fn group_for_core(&self, core_index, cores) -> GroupIndex; + + /// Returns the block number of the next rotation after the current block. If the current block + /// is 10 and the rotation frequency is 5, this should return 15. + fn next_rotation_at(&self) -> BlockNumber; + + /// Returns the block number of the last rotation before or including the current block. If the + /// current block is 10 and the rotation frequency is 5, this should return 10. + fn last_rotation_at(&self) -> BlockNumber; +} + +/// Returns the validator groups and rotation info localized based on the block whose state +/// this is invoked on. Note that `now` in the `GroupRotationInfo` should be the successor of +/// the number of the block. +fn validator_groups(at: Block) -> (Vec>, GroupRotationInfo); +``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/validators.md b/polkadot/roadmap/implementers-guide/src/runtime-api/validators.md new file mode 100644 index 0000000000000000000000000000000000000000..b7f1d964754755c2224dc89a3503835398a581a2 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/validators.md @@ -0,0 +1,7 @@ +# Validators + +Yields the validator-set at the state of a given block. This validator set is always the one responsible for backing parachains in the child of the provided block. + +```rust +fn validators(at: Block) -> Vec; +``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime/README.md b/polkadot/roadmap/implementers-guide/src/runtime/README.md new file mode 100644 index 0000000000000000000000000000000000000000..995b684b1f06d07bb56b4b51bad6861f0082bd68 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/README.md @@ -0,0 +1,58 @@ +# Runtime Architecture + +It's clear that we want to separate different aspects of the runtime logic into different modules. Modules define their own storage, routines, and entry-points. They also define initialization and finalization logic. + +Due to the (lack of) guarantees provided by a particular blockchain-runtime framework, there is no defined or dependable order in which modules' initialization or finalization logic will run. Supporting this blockchain-runtime framework is important enough to include that same uncertainty in our model of runtime modules in this guide. Furthermore, initialization logic of modules can trigger the entry-points or routines of other modules. This is one architectural pressure against dividing the runtime logic into multiple modules. However, in this case the benefits of splitting things up outweigh the costs, provided that we take certain precautions against initialization and entry-point races. + +We also expect, although it's beyond the scope of this guide, that these runtime modules will exist alongside various other modules. This has two facets to consider. First, even if the modules that we describe here don't invoke each others' entry points or routines during initialization, we still have to protect against those other modules doing that. Second, some of those modules are expected to provide governance capabilities for the chain. Configuration exposed by parachain-host modules is mostly for the benefit of these governance modules, to allow the operators or community of the chain to tweak parameters. + +The runtime's primary role is to manage scheduling and updating of parachains, as well as handling misbehavior reports and slashing. This guide doesn't focus on how parachains are registered, only that they are. Also, this runtime description assumes that validator sets are selected somehow, but doesn't assume any other details than a periodic _session change_ event. Session changes give information about the incoming validator set and the validator set of the following session. + +The runtime also serves another role, which is to make data available to the Node-side logic via Runtime APIs. These Runtime APIs should be sufficient for the Node-side code to author blocks correctly. + +There is some functionality of the relay chain relating to parachains that we also consider beyond the scope of this document. In particular, all modules related to how parachains are registered aren't part of this guide, although we do provide routines that should be called by the registration process. + +We will split the logic of the runtime up into these modules: + +* Initializer: manages initialization order of the other modules. +* Shared: manages shared storage and configurations for other modules. +* Configuration: manages configuration and configuration updates in a non-racy manner. +* Paras: manages chain-head and validation code for parachains. +* Scheduler: manages parachain scheduling as well as validator assignments. +* Inclusion: handles the inclusion and availability of scheduled parachains. +* SessionInfo: manages various session keys of validators and other params stored per session. +* Disputes: handles dispute resolution for included, available parablocks. +* Slashing: handles slashing logic for concluded disputes. +* HRMP: handles horizontal messages between paras. +* UMP: handles upward messages from a para to the relay chain. +* DMP: handles downward messages from the relay chain to the para. + +The [Initializer module](initializer.md) is special - it's responsible for handling the initialization logic of the other modules to ensure that the correct initialization order and related invariants are maintained. The other modules won't specify a on-initialize logic, but will instead expose a special semi-private routine that the initialization module will call. The other modules are relatively straightforward and perform the roles described above. + +The Parachain Host operates under a changing set of validators. Time is split up into periodic sessions, where each session brings a potentially new set of validators. Sessions are buffered by one, meaning that the validators of the upcoming session `n+1` are determined at the end of session `n-1`, right before session `n` starts. Parachain Host runtime modules need to react to changes in the validator set, as it will affect the runtime logic for processing candidate backing, availability bitfields, and misbehavior reports. The Parachain Host modules can't determine ahead-of-time exactly when session change notifications are going to happen within the block (note: this depends on module initialization order again - better to put session before parachains modules). + +The relay chain is intended to use BABE or SASSAFRAS, which both have the property that a session changing at a block is determined not by the number of the block but instead by the time the block is authored. In some sense, sessions change in-between blocks, not at blocks. This has the side effect that the session of a child block cannot be determined solely by the parent block's identifier. Being able to unilaterally determine the validator-set at a specific block based on its parent hash would make a lot of Node-side logic much simpler. + +In order to regain the property that the validator set of a block is predictable by its parent block, we delay session changes' application to Parachains by 1 block. This means that if there is a session change at block X, that session change will be stored and applied during initialization of direct descendants of X. This principal side effect of this change is that the Parachains runtime can disagree with session or consensus modules about which session it currently is. Misbehavior reporting routines in particular will be affected by this, although not severely. The parachains runtime might believe it is the last block of the session while the system is really in the first block of the next session. In such cases, a historical validator-set membership proof will need to accompany any misbehavior report, although they typically do not need to during current-session misbehavior reports. + +So the other role of the initializer module is to forward session change notifications to modules in the initialization order. Session change is also the point at which the [Configuration Module](configuration.md) updates the configuration. Most of the other modules will handle changes in the configuration during their session change operation, so the initializer should provide both the old and new configuration to all the other +modules alongside the session change notification. This means that a session change notification should consist of the following data: + +```rust +struct SessionChangeNotification { + // The new validators in the session. + validators: Vec, + // The validators for the next session. + queued: Vec, + // The configuration before handling the session change. + prev_config: HostConfiguration, + // The configuration after handling the session change. + new_config: HostConfiguration, + // A secure randomn seed for the session, gathered from BABE. + random_seed: [u8; 32], + // The session index of the beginning session. + session_index: SessionIndex, +} +``` + +> TODO Diagram: order of runtime operations (initialization, session change) diff --git a/polkadot/roadmap/implementers-guide/src/runtime/configuration.md b/polkadot/roadmap/implementers-guide/src/runtime/configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..be62ab2d4d5e0eda4b14358673a152328afe98b1 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/configuration.md @@ -0,0 +1,64 @@ +# Configuration Pallet + +This module is responsible for managing all configuration of the parachain host in-flight. It provides a central point for configuration updates to prevent races between configuration changes and parachain-processing logic. Configuration can only change during the session change routine, and as this module handles the session change notification first it provides an invariant that the configuration does not change throughout the entire session. Both the [scheduler](scheduler.md) and [inclusion](inclusion.md) modules rely on this invariant to ensure proper behavior of the scheduler. + +The configuration that we will be tracking is the [`HostConfiguration`](../types/runtime.md#host-configuration) struct. + +## Storage + +The configuration module is responsible for two main pieces of storage. + +```rust +/// The current configuration to be used. +Configuration: HostConfiguration; +/// A pending configuration to be applied on session change. +PendingConfigs: Vec<(SessionIndex, HostConfiguration)>; +/// A flag that says if the consistency checks should be omitted. +BypassConsistencyCheck: bool; +``` + +## Session change + +The session change routine works as follows: + +- If there is no pending configurations, then return early. +- Take all pending configurations that are less than or equal to the current session index. + - Get the pending configuration with the highest session index and apply it to the current configuration. Discard the earlier ones if any. + +## Routines + +```rust +enum InconsistentError { + // ... +} + +impl HostConfiguration { + fn check_consistency(&self) -> Result<(), InconsistentError> { /* ... */ } +} + +/// Get the host configuration. +pub fn configuration() -> HostConfiguration { + Configuration::get() +} + +/// Schedules updating the host configuration. The update is given by the `updater` closure. The +/// closure takes the current version of the configuration and returns the new version. +/// Returns an `Err` if the closure returns a broken configuration. However, there are a couple of +/// exceptions: +/// +/// - if the configuration that was passed in the closure is already broken, then it will pass the +/// update: you cannot break something that is already broken. +/// - If the `BypassConsistencyCheck` flag is set, then the checks will be skipped. +/// +/// The changes made by this function will always be scheduled at session X, where X is the current session index + 2. +/// If there is already a pending update for X, then the closure will receive the already pending configuration for +/// session X. +/// +/// If there is already a pending update for the current session index + 1, then it won't be touched. Otherwise, +/// that would violate the promise of this function that changes will be applied on the second session change (cur + 2). +fn schedule_config_update(updater: impl FnOnce(&mut HostConfiguration>)) -> DispatchResult +``` + +## Entry-points + +The Configuration module exposes an entry point for each configuration member. These entry-points accept calls only from governance origins. These entry-points will use the `update_configuration` routine to update the specific configuration field. diff --git a/polkadot/roadmap/implementers-guide/src/runtime/disputes.md b/polkadot/roadmap/implementers-guide/src/runtime/disputes.md new file mode 100644 index 0000000000000000000000000000000000000000..a2558b74f56279e713ab0f40735df68527c91584 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/disputes.md @@ -0,0 +1,141 @@ +# Disputes Pallet + +After a backed candidate is made available, it is included and proceeds into an acceptance period during which validators are randomly selected to do (secondary) approval checks of the parablock. Any reports disputing the validity of the candidate will cause escalation, where even more validators are requested to check the block, and so on, until either the parablock is determined to be invalid or valid. Those on the wrong side of the dispute are slashed and, if the parablock is deemed invalid, the relay chain is rolled back to a point before that block was included. + +However, this isn't the end of the story. We are working in a forkful blockchain environment, which carries three important considerations: + +1. For security, validators that misbehave shouldn't only be slashed on one fork, but on all possible forks. Validators that misbehave shouldn't be able to create a new fork of the chain when caught and get away with their misbehavior. +1. It is possible (and likely) that the parablock being contested has not appeared on all forks. +1. If a block author believes that there is a disputed parablock on a specific fork that will resolve to a reversion of the fork, that block author has more incentive to build on a different fork which does not include that parablock. + +This means that in all likelihood, there is the possibility of disputes that are started on one fork of the relay chain, and as soon as the dispute resolution process starts to indicate that the parablock is indeed invalid, that fork of the relay chain will be abandoned and the dispute will never be fully resolved on that chain. + +Even if this doesn't happen, there is the possibility that there are two disputes underway, and one resolves leading to a reversion of the chain before the other has concluded. In this case we want to both transplant the concluded dispute onto other forks of the chain as well as the unconcluded dispute. + +We account for these requirements by having the disputes module handle two kinds of disputes. + +1. Local disputes: those contesting the validity of the current fork by disputing a parablock included within it. +1. Remote disputes: a dispute that has partially or fully resolved on another fork which is transplanted to the local fork for completion and eventual slashing. + +When a local dispute concludes negatively, the chain needs to be abandoned and reverted back to a block where the state does not contain the bad parablock. We expect that due to the [Approval Checking Protocol](../protocol-approval.md), the current executing block should not be finalized. So we do two things when a local dispute concludes negatively: +1. Freeze the state of parachains so nothing further is backed or included. +1. Issue a digest in the header of the block that signals to nodes that this branch of the chain is to be abandoned. + +If, as is expected, the chain is unfinalized, the freeze will have no effect as no honest validator will attempt to build on the frozen chain. However, if the approval checking protocol has failed and the bad parablock is finalized, the freeze serves to put the chain into a governance-only mode. + +The storage of this module is designed around tracking [`DisputeState`s](../types/disputes.md#disputestate), updating them with votes, and tracking blocks included by this branch of the relay chain. It also contains a `Frozen` parameter designed to freeze the state of all parachains. + +## Storage + +Storage Layout: + +```rust +LastPrunedSession: Option, + +// All ongoing or concluded disputes for the last several sessions. +Disputes: double_map (SessionIndex, CandidateHash) -> Option, +// All included blocks on the chain, as well as the block number in this chain that +// should be reverted back to if the candidate is disputed and determined to be invalid. +Included: double_map (SessionIndex, CandidateHash) -> Option, +// Whether the chain is frozen or not. Starts as `None`. When this is `Some`, +// the chain will not accept any new parachain blocks for backing or inclusion, +// and its value indicates the last valid block number in the chain. +// It can only be set back to `None` by governance intervention. +Frozen: Option, +``` + +> `byzantine_threshold` refers to the maximum number `f` of validators which may be byzantine. The total number of validators is `n = 3f + e` where `e in { 1, 2, 3 }`. + +## Session Change + +1. If the current session is not greater than `config.dispute_period + 1`, nothing to do here. +1. Set `pruning_target = current_session - config.dispute_period - 1`. We add the extra `1` because we want to keep things for `config.dispute_period` _full_ sessions. + The stuff at the end of the most recent session has been around for a little over 0 sessions, not a little over 1. +1. If `LastPrunedSession` is `None`, then set `LastPrunedSession` to `Some(pruning_target)` and return. +2. Otherwise, clear out all disputes and included candidates entries in the range `last_pruned..=pruning_target` and set `LastPrunedSession` to `Some(pruning_target)`. + +## Block Initialization + +This is currently a `no op`. + +## Routines + +* `filter_multi_dispute_data(MultiDisputeStatementSet) -> MultiDisputeStatementSet`: + 1. Takes a `MultiDisputeStatementSet` and filters it down to a `MultiDisputeStatementSet` + that satisfies all the criteria of `provide_multi_dispute_data`. That is, eliminating + ancient votes, duplicates and unconfirmed disputes. + This can be used by block authors to create the final submission in a block which is + guaranteed to pass the `provide_multi_dispute_data` checks. + +* `provide_multi_dispute_data(MultiDisputeStatementSet) -> Vec<(SessionIndex, Hash)>`: + 1. Pass on each dispute statement set to `provide_dispute_data`, propagating failure. + 2. Return a list of all candidates who just had disputes initiated. + +* `provide_dispute_data(DisputeStatementSet) -> bool`: Provide data to an ongoing dispute or initiate a dispute. + 1. All statements must be issued under the correct session for the correct candidate. + 1. `SessionInfo` is used to check statement signatures and this function should fail if any signatures are invalid. + 1. If there is no dispute under `Disputes`, create a new `DisputeState` with blank bitfields. + 1. If `concluded_at` is `Some`, and is `concluded_at + config.post_conclusion_acceptance_period < now`, return false. + 2. Import all statements into the dispute. This should fail if any statements are duplicate or if the corresponding bit for the corresponding validator is set in the dispute already. + 3. If `concluded_at` is `None`, reward all statements. + 4. If `concluded_at` is `Some`, reward all statements slightly less. + 5. If either side now has supermajority and did not previously, slash the other side. This may be both sides, and we support this possibility in code, but note that this requires validators to participate on both sides which has negative expected value. Set `concluded_at` to `Some(now)` if it was `None`. + 6. If just concluded against the candidate and the `Included` map contains `(session, candidate)`: invoke `revert_and_freeze` with the stored block number. + 7. Return true if just initiated, false otherwise. + +* `disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState)>`: Get a list of all disputes and info about dispute state. + 1. Iterate over all disputes in `Disputes` and collect into a vector. + +* `note_included(SessionIndex, CandidateHash, included_in: BlockNumber)`: + 1. Add `(SessionIndex, CandidateHash)` to the `Included` map with `included_in - 1` as the value. + 1. If there is a dispute under `(SessionIndex, CandidateHash)` that has concluded against the candidate, invoke `revert_and_freeze` with the stored block number. + +* `concluded_invalid(SessionIndex, CandidateHash) -> bool`: Returns whether a candidate has already concluded a dispute in the negative. + +* `is_frozen()`: Load the value of `Frozen` from storage. Return true if `Some` and false if `None`. + +* `last_valid_block()`: Load the value of `Frozen` from storage and return. None indicates that all blocks in the chain are potentially valid. + +* `revert_and_freeze(BlockNumber)`: + 1. If `is_frozen()` return. + 1. Set `Frozen` to `Some(BlockNumber)` to indicate a rollback to the block number. + 1. Issue a `Revert(BlockNumber + 1)` log to indicate a rollback of the block's child in the header chain, which is the same as a rollback to the block number. + +# Disputes filtering + +All disputes delivered to the runtime by the client are filtered before the actual import. In this context actual import +means persisted in the runtime storage. The filtering has got two purposes: +- Limit the amount of data saved onchain. +- Prevent persisting malicious dispute data onchain. + +*Implementation note*: Filtering is performed in function `filter_dispute_data` from `Disputes` pallet. + +The filtering is performed on the whole statement set which is about to be imported onchain. The following filters are +applied: +1. Remove ancient disputes - if a dispute is concluded before the block number indicated in `OLDEST_ACCEPTED` parameter + it is removed from the set. `OLDEST_ACCEPTED` is a runtime configuration option. + *Implementation note*: `dispute_post_conclusion_acceptance_period` from + `HostConfiguration` is used in the current Polkadot/Kusama implementation. +2. Remove votes from unknown validators. If there is a vote from a validator which wasn't an authority in the session + where the dispute was raised - they are removed. Please note that this step removes only single votes instead of + removing the whole dispute. +3. Remove one sided disputes - if a dispute doesn't contain two opposing votes it is not imported onchain. This serves + as a measure not to import one sided disputes. A dispute is raised only if there are two opposing votes so if the + client is not sending them the dispute is a potential spam. +4. Remove unconfirmed disputes - if a dispute contains less votes than the byzantine threshold it is removed. This is + also a spam precaution. A legitimate client will send only confirmed disputes to the runtime. + +# Rewards and slashing + +After the disputes are filtered the validators participating in the disputes are rewarded and more importantly the +offenders are slashed. Generally there can be two types of punishments: +* "against valid" - the offender claimed that a valid candidate is invalid. +* "for invalid" - the offender claimed that an invalid candidate is valid. + +A dispute might be inconclusive. This means that it has timed out without being confirmed. A confirmed dispute is one +containing votes more than the byzantine threshold (1/3 of the active validators). Validators participating in +inconclusive disputes are not slashed. Thanks to the applied filtering (described in the previous section) one can be +confident that there are no spam disputes in the runtime. So if a validator is not voting it is due to another reason +(e.g. being under DoS attack). There is no reason to punish such validators with a slash. + +*Implementation note*: Slashing is performed in `process_checked_dispute_data` from `Disputes` pallet. \ No newline at end of file diff --git a/polkadot/roadmap/implementers-guide/src/runtime/dmp.md b/polkadot/roadmap/implementers-guide/src/runtime/dmp.md new file mode 100644 index 0000000000000000000000000000000000000000..f56df31934efefd9d5025835cd103ced22913669 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/dmp.md @@ -0,0 +1,51 @@ +# DMP Pallet + +A module responsible for Downward Message Processing (DMP). See [Messaging Overview](../messaging.md) for more details. + +## Storage + +Storage layout required for implementation of DMP. + +```rust +/// The downward messages addressed for a certain para. +DownwardMessageQueues: map ParaId => Vec; +/// A mapping that stores the downward message queue MQC head for each para. +/// +/// Each link in this chain has a form: +/// `(prev_head, B, H(M))`, where +/// - `prev_head`: is the previous head hash or zero if none. +/// - `B`: is the relay-chain block number in which a message was appended. +/// - `H(M)`: is the hash of the message being appended. +DownwardMessageQueueHeads: map ParaId => Hash; +``` + +## Initialization + +No initialization routine runs for this module. + +## Routines + +Candidate Acceptance Function: + +* `check_processed_downward_messages(P: ParaId, relay_parent_number: BlockNumber, processed_downward_messages: u32)`: + 1. Checks that `processed_downward_messages` is at least 1 if `DownwardMessageQueues` for `P` is not empty at the given `relay_parent_number`. + 1. Checks that `DownwardMessageQueues` for `P` is at least `processed_downward_messages` long. + +Candidate Enactment: + +* `prune_dmq(P: ParaId, processed_downward_messages: u32)`: + 1. Remove the first `processed_downward_messages` from the `DownwardMessageQueues` of `P`. + +Utility routines. + +`queue_downward_message(P: ParaId, M: DownwardMessage)`: + 1. Check if the size of `M` exceeds the `config.max_downward_message_size`. If so, return an error. + 1. Wrap `M` into `InboundDownwardMessage` using the current block number for `sent_at`. + 1. Obtain a new MQC link for the resulting `InboundDownwardMessage` and replace `DownwardMessageQueueHeads` for `P` with the resulting hash. + 1. Add the resulting `InboundDownwardMessage` into `DownwardMessageQueues` for `P`. + +## Session Change + +1. For each `P` in `outgoing_paras` (generated by `Paras::on_new_session`): + 1. Remove all `DownwardMessageQueues` of `P`. + 1. Remove `DownwardMessageQueueHeads` for `P`. diff --git a/polkadot/roadmap/implementers-guide/src/runtime/hrmp.md b/polkadot/roadmap/implementers-guide/src/runtime/hrmp.md new file mode 100644 index 0000000000000000000000000000000000000000..927c14cd596968bc7d2e82030140a02263093e20 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/hrmp.md @@ -0,0 +1,269 @@ +# HRMP Pallet + +A module responsible for Horizontally Relay-routed Message Passing (HRMP). See [Messaging Overview](../messaging.md) for more details. + +## Storage + +HRMP related structs: + +```rust +/// A description of a request to open an HRMP channel. +struct HrmpOpenChannelRequest { + /// Indicates if this request was confirmed by the recipient. + confirmed: bool, + /// The amount that the sender supplied at the time of creation of this request. + sender_deposit: Balance, + /// The maximum message size that could be put into the channel. + max_message_size: u32, + /// The maximum number of messages that can be pending in the channel at once. + max_capacity: u32, + /// The maximum total size of the messages that can be pending in the channel at once. + max_total_size: u32, +} + +/// A metadata of an HRMP channel. +struct HrmpChannel { + /// The amount that the sender supplied as a deposit when opening this channel. + sender_deposit: Balance, + /// The amount that the recipient supplied as a deposit when accepting opening this channel. + recipient_deposit: Balance, + /// The maximum number of messages that can be pending in the channel at once. + max_capacity: u32, + /// The maximum total size of the messages that can be pending in the channel at once. + max_total_size: u32, + /// The maximum message size that could be put into the channel. + max_message_size: u32, + /// The current number of messages pending in the channel. + /// Invariant: should be less or equal to `max_capacity`. + msg_count: u32, + /// The total size in bytes of all message payloads in the channel. + /// Invariant: should be less or equal to `max_total_size`. + total_size: u32, + /// A head of the Message Queue Chain for this channel. Each link in this chain has a form: + /// `(prev_head, B, H(M))`, where + /// - `prev_head`: is the previous value of `mqc_head` or zero if none. + /// - `B`: is the [relay-chain] block number in which a message was appended + /// - `H(M)`: is the hash of the message being appended. + /// This value is initialized to a special value that consists of all zeroes which indicates + /// that no messages were previously added. + mqc_head: Option, +} +``` +HRMP related storage layout + +```rust +/// The set of pending HRMP open channel requests. +/// +/// The set is accompanied by a list for iteration. +/// +/// Invariant: +/// - There are no channels that exists in list but not in the set and vice versa. +HrmpOpenChannelRequests: map HrmpChannelId => Option; +HrmpOpenChannelRequestsList: Vec; + +/// This mapping tracks how many open channel requests are inititated by a given sender para. +/// Invariant: `HrmpOpenChannelRequests` should contain the same number of items that has `(X, _)` +/// as the number of `HrmpOpenChannelRequestCount` for `X`. +HrmpOpenChannelRequestCount: map ParaId => u32; +/// This mapping tracks how many open channel requests were accepted by a given recipient para. +/// Invariant: `HrmpOpenChannelRequests` should contain the same number of items `(_, X)` with +/// `confirmed` set to true, as the number of `HrmpAcceptedChannelRequestCount` for `X`. +HrmpAcceptedChannelRequestCount: map ParaId => u32; + +/// A set of pending HRMP close channel requests that are going to be closed during the session change. +/// Used for checking if a given channel is registered for closure. +/// +/// The set is accompanied by a list for iteration. +/// +/// Invariant: +/// - There are no channels that exists in list but not in the set and vice versa. +HrmpCloseChannelRequests: map HrmpChannelId => Option<()>; +HrmpCloseChannelRequestsList: Vec; + +/// The HRMP watermark associated with each para. +/// Invariant: +/// - each para `P` used here as a key should satisfy `Paras::is_valid_para(P)` within a session. +HrmpWatermarks: map ParaId => Option; +/// HRMP channel data associated with each para. +/// Invariant: +/// - each participant in the channel should satisfy `Paras::is_valid_para(P)` within a session. +HrmpChannels: map HrmpChannelId => Option; +/// Ingress/egress indexes allow to find all the senders and receivers given the opposite +/// side. I.e. +/// +/// (a) ingress index allows to find all the senders for a given recipient. +/// (b) egress index allows to find all the recipients for a given sender. +/// +/// Invariants: +/// - for each ingress index entry for `P` each item `I` in the index should present in `HrmpChannels` +/// as `(I, P)`. +/// - for each egress index entry for `P` each item `E` in the index should present in `HrmpChannels` +/// as `(P, E)`. +/// - there should be no other dangling channels in `HrmpChannels`. +/// - the vectors are sorted. +HrmpIngressChannelsIndex: map ParaId => Vec; +HrmpEgressChannelsIndex: map ParaId => Vec; +/// Storage for the messages for each channel. +/// Invariant: cannot be non-empty if the corresponding channel in `HrmpChannels` is `None`. +HrmpChannelContents: map HrmpChannelId => Vec; +/// Maintains a mapping that can be used to answer the question: +/// What paras sent a message at the given block number for a given reciever. +/// Invariants: +/// - The inner `Vec` is never empty. +/// - The inner `Vec` cannot store two same `ParaId`. +/// - The outer vector is sorted ascending by block number and cannot store two items with the same +/// block number. +HrmpChannelDigests: map ParaId => Vec<(BlockNumber, Vec)>; +``` + +## Initialization + +No initialization routine runs for this module. + +## Routines + +Candidate Acceptance Function: + +* `check_hrmp_watermark(P: ParaId, new_hrmp_watermark)`: + 1. `new_hrmp_watermark` should be strictly greater than the value of `HrmpWatermarks` for `P` (if any). + 1. `new_hrmp_watermark` must not be greater than the context's block number. + 1. `new_hrmp_watermark` should be either + 1. equal to the context's block number + 1. or in `HrmpChannelDigests` for `P` an entry with the block number should exist +* `check_outbound_hrmp(sender: ParaId, Vec)`: + 1. Checks that there are at most `config.hrmp_max_message_num_per_candidate` messages. + 1. Checks that horizontal messages are sorted by ascending recipient ParaId and there is no two horizontal messages have the same recipient. + 1. For each horizontal message `M` with the channel `C` identified by `(sender, M.recipient)` check: + 1. exists + 1. `M`'s payload size doesn't exceed a preconfigured limit `C.max_message_size` + 1. `M`'s payload size summed with the `C.total_size` doesn't exceed a preconfigured limit `C.max_total_size`. + 1. `C.msg_count + 1` doesn't exceed a preconfigured limit `C.max_capacity`. + +Candidate Enactment: + +* `queue_outbound_hrmp(sender: ParaId, Vec)`: + 1. For each horizontal message `HM` with the channel `C` identified by `(sender, HM.recipient)`: + 1. Append `HM` into `HrmpChannelContents` that corresponds to `C` with `sent_at` equals to the current block number. + 1. Locate or create an entry in `HrmpChannelDigests` for `HM.recipient` and append `sender` into the entry's list. + 1. Increment `C.msg_count` + 1. Increment `C.total_size` by `HM`'s payload size + 1. Append a new link to the MQC and save the new head in `C.mqc_head`. Note that the current block number as of enactment is used for the link. +* `prune_hrmp(recipient, new_hrmp_watermark)`: + 1. From `HrmpChannelDigests` for `recipient` remove all entries up to an entry with block number equal to `new_hrmp_watermark`. + 1. From the removed digests construct a set of paras that sent new messages within the interval between the old and new watermarks. + 1. For each channel `C` identified by `(sender, recipient)` for each `sender` coming from the set, prune messages up to the `new_hrmp_watermark`. + 1. For each pruned message `M` from channel `C`: + 1. Decrement `C.msg_count` + 1. Decrement `C.total_size` by `M`'s payload size. + 1. Set `HrmpWatermarks` for `P` to be equal to `new_hrmp_watermark` + > NOTE: That collecting digests can be inefficient and the time it takes grows very fast. Thanks to the aggressive + > parameterization this shouldn't be a big of a deal. + > If that becomes a problem consider introducing an extra dictionary which says at what block the given sender + > sent a message to the recipient. + +## Entry-points + +The following entry-points are meant to be used for HRMP channel management. + +Those entry-points are meant to be called from a parachain. `origin` is defined as the `ParaId` of +the parachain executed the message. + +* `hrmp_init_open_channel(recipient, proposed_max_capacity, proposed_max_message_size)`: + 1. Check that the `origin` is not `recipient`. + 1. Check that `proposed_max_capacity` is less or equal to `config.hrmp_channel_max_capacity` and greater than zero. + 1. Check that `proposed_max_message_size` is less or equal to `config.hrmp_channel_max_message_size` and greater than zero. + 1. Check that `recipient` is a valid para. + 1. Check that there is no existing channel for `(origin, recipient)` in `HrmpChannels`. + 1. Check that there is no existing open channel request (`origin`, `recipient`) in `HrmpOpenChannelRequests`. + 1. Check that the sum of the number of already opened HRMP channels by the `origin` (the size + of the set found `HrmpEgressChannelsIndex` for `origin`) and the number of open requests by the + `origin` (the value from `HrmpOpenChannelRequestCount` for `origin`) doesn't exceed the limit of + channels (`config.hrmp_max_parachain_outbound_channels` or `config.hrmp_max_parathread_outbound_channels`) minus 1. + 1. Check that `origin`'s balance is more or equal to `config.hrmp_sender_deposit` + 1. Reserve the deposit for the `origin` according to `config.hrmp_sender_deposit` + 1. Increase `HrmpOpenChannelRequestCount` by 1 for `origin`. + 1. Append `(origin, recipient)` to `HrmpOpenChannelRequestsList`. + 1. Add a new entry to `HrmpOpenChannelRequests` for `(origin, recipient)` + 1. Set `sender_deposit` to `config.hrmp_sender_deposit` + 1. Set `max_capacity` to `proposed_max_capacity` + 1. Set `max_message_size` to `proposed_max_message_size` + 1. Set `max_total_size` to `config.hrmp_channel_max_total_size` + 1. Send a downward message to `recipient` notifying about an inbound HRMP channel request. + - The DM is sent using `queue_downward_message`. + - The DM is represented by the `HrmpNewChannelOpenRequest` XCM message. + - `sender` is set to `origin`, + - `max_message_size` is set to `proposed_max_message_size`, + - `max_capacity` is set to `proposed_max_capacity`. +* `hrmp_accept_open_channel(sender)`: + 1. Check that there is an existing request between (`sender`, `origin`) in `HrmpOpenChannelRequests` + 1. Check that it is not confirmed. + 1. Check that the sum of the number of inbound HRMP channels opened to `origin` (the size of the set + found in `HrmpIngressChannelsIndex` for `origin`) and the number of accepted open requests by the `origin` + (the value from `HrmpAcceptedChannelRequestCount` for `origin`) doesn't exceed the limit of channels + (`config.hrmp_max_parachain_inbound_channels` or `config.hrmp_max_parathread_inbound_channels`) + minus 1. + 1. Check that `origin`'s balance is more or equal to `config.hrmp_recipient_deposit`. + 1. Reserve the deposit for the `origin` according to `config.hrmp_recipient_deposit` + 1. For the request in `HrmpOpenChannelRequests` identified by `(sender, P)`, set `confirmed` flag to `true`. + 1. Increase `HrmpAcceptedChannelRequestCount` by 1 for `origin`. + 1. Send a downward message to `sender` notifying that the channel request was accepted. + - The DM is sent using `queue_downward_message`. + - The DM is represented by the `HrmpChannelAccepted` XCM message. + - `recipient` is set to `origin`. +* `hrmp_cancel_open_request(ch)`: + 1. Check that `origin` is either `ch.sender` or `ch.recipient` + 1. Check that the open channel request `ch` exists. + 1. Check that the open channel request for `ch` is not confirmed. + 1. Remove `ch` from `HrmpOpenChannelRequests` and `HrmpOpenChannelRequestsList` + 1. Decrement `HrmpAcceptedChannelRequestCount` for `ch.recipient` by 1. + 1. Unreserve the deposit of `ch.sender`. +* `hrmp_close_channel(ch)`: + 1. Check that `origin` is either `ch.sender` or `ch.recipient` + 1. Check that `HrmpChannels` for `ch` exists. + 1. Check that `ch` is not in the `HrmpCloseChannelRequests` set. + 1. If not already there, insert a new entry `Some(())` to `HrmpCloseChannelRequests` for `ch` + and append `ch` to `HrmpCloseChannelRequestsList`. + 1. Send a downward message to the opposite party notifying about the channel closing. + - The DM is sent using `queue_downward_message`. + - The DM is represented by the `HrmpChannelClosing` XCM message with: + - `initator` is set to `origin`, + - `sender` is set to `ch.sender`, + - `recipient` is set to `ch.recipient`. + - The opposite party is `ch.sender` if `origin` is `ch.recipient` and `ch.recipient` if `origin` is `ch.sender`. + +## Session Change + +1. For each `P` in `outgoing_paras` (generated by `Paras::on_new_session`): + 1. Remove all inbound channels of `P`, i.e. `(_, P)`, + 1. Remove all outbound channels of `P`, i.e. `(P, _)`, + 1. Remove `HrmpOpenChannelRequestCount` for `P` + 1. Remove `HrmpAcceptedChannelRequestCount` for `P`. + 1. Remove `HrmpOpenChannelRequests` and `HrmpOpenChannelRequestsList` for `(P, _)` and `(_, P)`. + 1. For each removed channel request `C`: + 1. Unreserve the sender's deposit if the sender is not present in `outgoing_paras` + 1. Unreserve the recipient's deposit if `C` is confirmed and the recipient is not present in `outgoing_paras` +1. For each channel designator `D` in `HrmpOpenChannelRequestsList` we query the request `R` from `HrmpOpenChannelRequests`: + 1. if `R.confirmed = true`, + 1. if both `D.sender` and `D.recipient` are not offboarded. + 1. create a new channel `C` between `(D.sender, D.recipient)`. + 1. Initialize the `C.sender_deposit` with `R.sender_deposit` and `C.recipient_deposit` + with the value found in the configuration `config.hrmp_recipient_deposit`. + 1. Insert `sender` into the set `HrmpIngressChannelsIndex` for the `recipient`. + 1. Insert `recipient` into the set `HrmpEgressChannelsIndex` for the `sender`. + 1. decrement `HrmpOpenChannelRequestCount` for `D.sender` by 1. + 1. decrement `HrmpAcceptedChannelRequestCount` for `D.recipient` by 1. + 1. remove `R` + 1. remove `D` +1. For each HRMP channel designator `D` in `HrmpCloseChannelRequestsList` + 1. remove the channel identified by `D`, if exists. + 1. remove `D` from `HrmpCloseChannelRequests`. + 1. remove `D` from `HrmpCloseChannelRequestsList` + +To remove a HRMP channel `C` identified with a tuple `(sender, recipient)`: + +1. Return `C.sender_deposit` to the `sender`. +1. Return `C.recipient_deposit` to the `recipient`. +1. Remove `C` from `HrmpChannels`. +1. Remove `C` from `HrmpChannelContents`. +1. Remove `recipient` from the set `HrmpEgressChannelsIndex` for `sender`. +1. Remove `sender` from the set `HrmpIngressChannelsIndex` for `recipient`. diff --git a/polkadot/roadmap/implementers-guide/src/runtime/inclusion.md b/polkadot/roadmap/implementers-guide/src/runtime/inclusion.md new file mode 100644 index 0000000000000000000000000000000000000000..3fe7711ae2d0ee8a1ae5dc7a0d6bb0a1cf27789d --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/inclusion.md @@ -0,0 +1,153 @@ +# Inclusion Pallet + +The inclusion module is responsible for inclusion and availability of scheduled parachains. It also manages the UMP dispatch queue of each parachain. + +## Storage + +Helper structs: + +```rust +struct AvailabilityBitfield { + bitfield: BitVec, // one bit per core. + submitted_at: BlockNumber, // for accounting, as meaning of bits may change over time. +} + +struct CandidatePendingAvailability { + core: CoreIndex, // availability core + hash: CandidateHash, + descriptor: CandidateDescriptor, + availability_votes: Bitfield, // one bit per validator. + relay_parent_number: BlockNumber, // number of the relay-parent. + backers: Bitfield, // one bit per validator, set for those who backed the candidate. + backed_in_number: BlockNumber, + backing_group: GroupIndex, +} +``` + +Storage Layout: + +```rust +/// The latest bitfield for each validator, referred to by index. +bitfields: map ValidatorIndex => AvailabilityBitfield; +/// Candidates pending availability. +PendingAvailability: map ParaId => CandidatePendingAvailability; +/// The commitments of candidates pending availability, by ParaId. +PendingAvailabilityCommitments: map ParaId => CandidateCommitments; +``` + +## Config Dependencies + +* `MessageQueue`: + The message queue provides general queueing and processing functionality. Currently it + replaces the old `UMP` dispatch queue. Other use-cases can be implemented as well by + adding new variants to `AggregateMessageOrigin`. Normally it should be set to an instance + of the `MessageQueue` pallet. + +## Session Change + +1. Clear out all candidates pending availability. +1. Clear out all validator bitfields. + +Optional: +1. The UMP queue of all outgoing paras can be "swept". This would prevent the dispatch queue from automatically being serviced. It is a consideration for the chain and specific behaviour is not defined. + +## Initialization + +No initialization routine runs for this module. However, the initialization of the `MessageQueue` pallet will attempt to process any pending UMP messages. + + +## Routines + +All failed checks should lead to an unrecoverable error making the block invalid. + +* `process_bitfields(expected_bits, Bitfields, core_lookup: Fn(CoreIndex) -> Option)`: + 1. Call `sanitize_bitfields` and use the sanitized `signed_bitfields` from now on. + 1. Call `sanitize_backed_candidates` and use the sanitized `backed_candidates` from now on. + 1. Apply each bit of bitfield to the corresponding pending candidate, looking up on-demand parachain cores using the `core_lookup`. Disregard bitfields that have a `1` bit for any free cores. + 1. For each applied bit of each availability-bitfield, set the bit for the validator in the `CandidatePendingAvailability`'s `availability_votes` bitfield. Track all candidates that now have >2/3 of bits set in their `availability_votes`. These candidates are now available and can be enacted. + 1. For all now-available candidates, invoke the `enact_candidate` routine with the candidate and relay-parent number. + 1. Return a list of `(CoreIndex, CandidateHash)` from freed cores consisting of the cores where candidates have become available. +* `sanitize_bitfields( + unchecked_bitfields: UncheckedSignedAvailabilityBitfields, + disputed_bitfield: DisputedBitfield, + expected_bits: usize, + parent_hash: T::Hash, + session_index: SessionIndex, + validators: &[ValidatorId], + full_check: FullCheck, + )`: + 1. check that `disputed_bitfield` has the same number of bits as the `expected_bits`, iff not return early with an empty vec. + 1. each of the below checks is for each bitfield. If a check does not pass the bitfield will be skipped. + 1. check that there are no bits set that reference a disputed candidate. + 1. check that the number of bits is equal to `expected_bits`. + 1. check that the validator index is strictly increasing (and thus also unique). + 1. check that the validator bit index is not out of bounds. + 1. check the validators signature, iff `full_check=FullCheck::Yes`. + +* `sanitize_backed_candidates) -> bool>( + mut backed_candidates: Vec>, + candidate_has_concluded_invalid_dispute: F, + scheduled: &[CoreAssignment], + ) ` + 1. filter out any backed candidates that have concluded invalid. + 1. filters backed candidates whom's paraid was scheduled by means of the provided `scheduled` parameter. + 1. sorts remaining candidates with respect to the core index assigned to them. + +* `process_candidates(allowed_relay_parents, BackedCandidates, scheduled: Vec, group_validators: Fn(GroupIndex) -> Option>)`: + > For details on `AllowedRelayParentsTracker` see documentation for [Shared](./shared.md) module. + 1. check that each candidate corresponds to a scheduled core and that they are ordered in the same order the cores appear in assignments in `scheduled`. + 1. check that `scheduled` is sorted ascending by `CoreIndex`, without duplicates. + 1. check that the relay-parent from each candidate receipt is one of the allowed relay-parents. + 1. check that there is no candidate pending availability for any scheduled `ParaId`. + 1. check that each candidate's `validation_data_hash` corresponds to a `PersistedValidationData` computed from the state of the context block. + 1. If the core assignment includes a specific collator, ensure the backed candidate is issued by that collator. + 1. Ensure that any code upgrade scheduled by the candidate does not happen within `config.validation_upgrade_cooldown` of `Paras::last_code_upgrade(para_id, true)`, if any, comparing against the value of `Paras::FutureCodeUpgrades` for the given para ID. + 1. Check the collator's signature on the candidate data. + 1. check the backing of the candidate using the signatures and the bitfields, comparing against the validators assigned to the groups, fetched with the `group_validators` lookup, while group indices are computed by `Scheduler` according to group rotation info. + 1. call `check_upward_messages(config, para, commitments.upward_messages)` to check that the upward messages are valid. + 1. call `Dmp::check_processed_downward_messages(para, commitments.processed_downward_messages)` to check that the DMQ is properly drained. + 1. call `Hrmp::check_hrmp_watermark(para, commitments.hrmp_watermark)` for each candidate to check rules of processing the HRMP watermark. + 1. using `Hrmp::check_outbound_hrmp(sender, commitments.horizontal_messages)` ensure that the each candidate sent a valid set of horizontal messages + 1. create an entry in the `PendingAvailability` map for each backed candidate with a blank `availability_votes` bitfield. + 1. create a corresponding entry in the `PendingAvailabilityCommitments` with the commitments. + 1. Return a `Vec` of all scheduled cores of the list of passed assignments that a candidate was successfully backed for, sorted ascending by CoreIndex. +* `enact_candidate(relay_parent_number: BlockNumber, CommittedCandidateReceipt)`: + 1. If the receipt contains a code upgrade, Call `Paras::schedule_code_upgrade(para_id, code, relay_parent_number, config)`. + > TODO: Note that this is safe as long as we never enact candidates where the relay parent is across a session boundary. In that case, which we should be careful to avoid with contextual execution, the configuration might have changed and the para may de-sync from the host's understanding of it. + 1. Reward all backing validators of each candidate, contained within the `backers` field. + 1. call `receive_upward_messages` for each backed candidate, using the [`UpwardMessage`s](../types/messages.md#upward-message) from the [`CandidateCommitments`](../types/candidate.md#candidate-commitments). + 1. call `Dmp::prune_dmq` with the para id of the candidate and the candidate's `processed_downward_messages`. + 1. call `Hrmp::prune_hrmp` with the para id of the candiate and the candidate's `hrmp_watermark`. + 1. call `Hrmp::queue_outbound_hrmp` with the para id of the candidate and the list of horizontal messages taken from the commitment, + 1. Call `Paras::note_new_head` using the `HeadData` from the receipt and `relay_parent_number`. + +* `collect_pending`: + + ```rust + fn collect_pending(f: impl Fn(CoreIndex, BlockNumber) -> bool) -> Vec { + // sweep through all paras pending availability. if the predicate returns true, when given the core index and + // the block number the candidate has been pending availability since, then clean up the corresponding storage for that candidate and the commitments. + // return a vector of cleaned-up core IDs. + } + ``` +* `force_enact(ParaId)`: Forcibly enact the candidate with the given ID as though it had been deemed available by bitfields. Is a no-op if there is no candidate pending availability for this para-id. This should generally not be used but it is useful during execution of Runtime APIs, where the changes to the state are expected to be discarded directly after. +* `candidate_pending_availability(ParaId) -> Option`: returns the `CommittedCandidateReceipt` pending availability for the para provided, if any. +* `pending_availability(ParaId) -> Option`: returns the metadata around the candidate pending availability for the para, if any. +* `collect_disputed(disputed: Vec) -> Vec`: Sweeps through all paras pending availability. If the candidate hash is one of the disputed candidates, then clean up the corresponding storage for that candidate and the commitments. Return a vector of cleaned-up core IDs. + +These functions were formerly part of the UMP pallet: + +* `check_upward_messages(P: ParaId, Vec)`: + 1. Checks that the parachain is not currently offboarding and error otherwise. + 1. Checks that there are at most `config.max_upward_message_num_per_candidate` messages to be enqueued. + 1. Checks that no message exceeds `config.max_upward_message_size`. + 1. Checks that the total resulting queue size would not exceed `co`. + 1. Verify that queuing up the messages could not result in exceeding the queue's footprint + according to the config items `config.max_upward_queue_count` and `config.max_upward_queue_size`. The queue's current footprint is provided in `well_known_keys` + in order to facilitate oraclisation on to the para. + +Candidate Enactment: + +* `receive_upward_messages(P: ParaId, Vec)`: + 1. Process each upward message `M` in order: + 1. Place in the dispatch queue according to its para ID (or handle it immediately). diff --git a/polkadot/roadmap/implementers-guide/src/runtime/initializer.md b/polkadot/roadmap/implementers-guide/src/runtime/initializer.md new file mode 100644 index 0000000000000000000000000000000000000000..19dfcbde50a9266305c3cb952655cb8870bfc5e2 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/initializer.md @@ -0,0 +1,45 @@ +# Initializer Pallet + +This module is responsible for initializing the other modules in a deterministic order. It also has one other purpose as described in the overview of the runtime: accepting and forwarding session change notifications. + +## Storage + +```rust +HasInitialized: bool; +// buffered session changes along with the block number at which they should be applied. +// +// typically this will be empty or one element long. ordered ascending by BlockNumber and insertion +// order. +BufferedSessionChanges: Vec<(BlockNumber, ValidatorSet, ValidatorSet)>; +``` + +## Initialization + +Before initializing modules, remove all changes from the `BufferedSessionChanges` with number less than or equal to the current block number, and apply the last one. The session change is applied to all modules in the same order as initialization. + +The other parachains modules are initialized in this order: + +1. Configuration +1. Shared +1. Paras +1. Scheduler +1. Inclusion +1. SessionInfo +1. Disputes +1. DMP +1. UMP +1. HRMP + +The [Configuration Module](configuration.md) is first, since all other modules need to operate under the same configuration as each other. Then the [Shared](shared.md) module is invoked, which determines the set of active validators. It would lead to inconsistency if, for example, the scheduler ran first and then the configuration was updated before the Inclusion module. + +Set `HasInitialized` to true. + +## Session Change + +Store the session change information in `BufferedSessionChange` along with the block number at which it was submitted, plus one. Although the expected operational parameters of the block authorship system should prevent more than one change from being buffered at any time, it may occur. Regardless, we always need to track the block number at which the session change can be applied so as to remain flexible over session change notifications being issued before or after initialization of the current block. + +## Finalization + +Finalization order is less important in this case than initialization order, so we finalize the modules in the reverse order from initialization. + +Set `HasInitialized` to false. diff --git a/polkadot/roadmap/implementers-guide/src/runtime/parainherent.md b/polkadot/roadmap/implementers-guide/src/runtime/parainherent.md new file mode 100644 index 0000000000000000000000000000000000000000..405468c609a701b1e12147ba1a22442562a0b921 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/parainherent.md @@ -0,0 +1,57 @@ +# `ParaInherent` + +This module is responsible for providing all data given to the runtime by the block author to the various parachains modules. The entry-point is mandatory, in that it must be invoked exactly once within every block, and it is also "inherent", in that it is provided with no origin by the block author. The data within it carries its own authentication; i.e. the data takes the form of signed statements by validators. Invalid data will be filtered and not applied. + +This module does not have the same initialization/finalization concerns as the others, as it only requires that entry points be triggered after all modules have initialized and that finalization happens after entry points are triggered. Both of these are assumptions we have already made about the runtime's order of operations, so this module doesn't need to be initialized or finalized by the `Initializer`. + +There are a couple of important notes to the operations in this inherent as they relate to disputes. + +1. We don't accept bitfields or backed candidates if in "governance-only" mode from having a local dispute conclude on this fork. +1. When disputes are initiated, we remove the block from pending availability. This allows us to roll back chains to the block before blocks are included as opposed to backing. It's important to do this before processing bitfields. +1. `Inclusion::collect_disputed` is kind of expensive so it's important to gate this on whether there are actually any new disputes. Which should be never. +1. And we don't accept parablocks that have open disputes or disputes that have concluded against the candidate. It's important to import dispute statements before backing, but this is already the case as disputes are imported before processing bitfields. + +## Storage + +```rust +/// Whether the para inherent was included or not. +Included: Option<()>, +``` + +```rust +/// Scraped on chain votes to be used in disputes off-chain. +OnChainVotes: Option, +``` + +## Finalization + +1. Take (get and clear) the value of `Included`. If it is not `Some`, throw an unrecoverable error. + +## Entry Points + +* `enter`: This entry-point accepts one parameter: [`ParaInherentData`](../types/runtime.md#ParaInherentData). +* `create_inherent`: This entry-point accepts one parameter: `InherentData`. + +Both entry points share mostly the same code. `create_inherent` will +meaningfully limit inherent data to adhere to the weight limit, in addition to +sanitizing any inputs and filtering out invalid data. Conceptually it is part of +the block production. The `enter` call on the other hand is part of block import +and consumes/imports the data previously produced by `create_inherent`. + +In practice both calls process inherent data and apply it to the state. Block +production and block import should arrive at the same new state. Hence we re-use +the same logic to ensure this is the case. + +The only real difference between the two is, that on `create_inherent` we +actually need the processed and filtered inherent data to build the block, while +on `enter` the processed data should for one be identical to the incoming +inherent data (assuming honest block producers) and second it is irrelevant, as +we are not building a block but just processing it, so the processed inherent +data is simply dropped. + +This also means that the `enter` function keeps data around for no good reason. +This seems acceptable though as the size of a block is rather limited. +Nevertheless if we ever wanted to optimize this we can easily implement an +inherent collector that has two implementations, where one clones and stores the +data and the other just passes it on. + diff --git a/polkadot/roadmap/implementers-guide/src/runtime/paras.md b/polkadot/roadmap/implementers-guide/src/runtime/paras.md new file mode 100644 index 0000000000000000000000000000000000000000..b3015bd5729052db4b99e6285465f46efc07cb03 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/paras.md @@ -0,0 +1,278 @@ +# Paras Pallet + +The Paras module is responsible for storing information on parachains. Registered +parachains cannot change except at session boundaries and after at least a full +session has passed. This is primarily to ensure that the number and meaning of bits required for the +availability bitfields does not change except at session boundaries. + +It's also responsible for: + +- managing parachain validation code upgrades as well as maintaining availability of old parachain +code and its pruning. +- vetting PVFs by means of the PVF pre-checking mechanism. + +## Storage + +### Utility Structs + +```rust +// the two key times necessary to track for every code replacement. +pub struct ReplacementTimes { + /// The relay-chain block number that the code upgrade was expected to be activated. + /// This is when the code change occurs from the para's perspective - after the + /// first parablock included with a relay-parent with number >= this value. + expected_at: BlockNumber, + /// The relay-chain block number at which the parablock activating the code upgrade was + /// actually included. This means considered included and available, so this is the time at which + /// that parablock enters the acceptance period in this fork of the relay-chain. + activated_at: BlockNumber, +} + +/// Metadata used to track previous parachain validation code that we keep in +/// the state. +pub struct ParaPastCodeMeta { + // Block numbers where the code was expected to be replaced and where the code + // was actually replaced, respectively. The first is used to do accurate lookups + // of historic code in historic contexts, whereas the second is used to do + // pruning on an accurate timeframe. These can be used as indices + // into the `PastCode` map along with the `ParaId` to fetch the code itself. + upgrade_times: Vec, + // This tracks the highest pruned code-replacement, if any. + last_pruned: Option, +} + +struct ParaGenesisArgs { + /// The initial head-data to use. + genesis_head: HeadData, + /// The validation code to start with. + validation_code: ValidationCode, + /// True if parachain, false if parathread. + parachain: bool, +} + +/// The possible states of a para, to take into account delayed lifecycle changes. +pub enum ParaLifecycle { + /// A Para is new and is onboarding. + Onboarding, + /// Para is a Parathread (on-demand parachain). + Parathread, + /// Para is a lease holding Parachain. + Parachain, + /// Para is a Parathread (on-demand Parachain) which is upgrading to a lease holding Parachain. + UpgradingParathread, + /// Para is a lease holding Parachain which is downgrading to an on-demand parachain. + DowngradingParachain, + /// Parathread (on-demand parachain) is being offboarded. + OutgoingParathread, + /// Parachain is being offboarded. + OutgoingParachain, +} + +enum PvfCheckCause { + /// PVF vote was initiated by the initial onboarding process of the given para. + Onboarding(ParaId), + /// PVF vote was initiated by signalling of an upgrade by the given para. + Upgrade { + /// The ID of the parachain that initiated or is waiting for the conclusion of pre-checking. + id: ParaId, + /// The relay-chain block number that was used as the relay-parent for the parablock that + /// initiated the upgrade. + relay_parent_number: BlockNumber, + }, +} + +struct PvfCheckActiveVoteState { + // The two following vectors have their length equal to the number of validators in the active + // set. They start with all zeroes. A 1 is set at an index when the validator at the that index + // makes a vote. Once a 1 is set for either of the vectors, that validator cannot vote anymore. + // Since the active validator set changes each session, the bit vectors are reinitialized as + // well: zeroed and resized so that each validator gets its own bit. + votes_accept: BitVec, + votes_reject: BitVec, + + /// The number of session changes this PVF vote has observed. Therefore, this number is + /// increased at each session boundary. When created, it is initialized with 0. + age: SessionIndex, + /// The block number at which this PVF vote was created. + created_at: BlockNumber, + /// A list of causes for this PVF pre-checking. Has at least one. + causes: Vec, +} +``` + +#### Para Lifecycle + +Because the state changes of parachains are delayed, we track the specific state of +the para using the `ParaLifecycle` enum. + +``` +None Parathread (on-demand parachain) Parachain + + + + + | | | + | (≈2 Session Delay) | | + | | | + +----------------------->+ | + | Onboarding | | + | | | + +-------------------------------------------------->+ + | Onboarding | | + | | | + | +------------------------->+ + | | UpgradingParathread | + | | | + | +<-------------------------+ + | | DowngradingParachain | + | | | + |<-----------------------+ | + | OutgoingParathread | | + | | | + +<--------------------------------------------------+ + | | OutgoingParachain | + | | | + + + + +``` + +Note that if PVF pre-checking is enabled, onboarding of a para may potentially be delayed. This can +happen due to PVF pre-checking voting concluding late. + +During the transition period, the para object is still considered in its existing state. + +### Storage Layout + +```rust +use frame_system::pallet_prelude::BlockNumberFor; +/// All currently active PVF pre-checking votes. +/// +/// Invariant: +/// - There are no PVF pre-checking votes that exists in list but not in the set and vice versa. +PvfActiveVoteMap: map ValidationCodeHash => PvfCheckActiveVoteState; +/// The list of all currently active PVF votes. Auxiliary to `PvfActiveVoteMap`. +PvfActiveVoteList: Vec; +/// All parachains. Ordered ascending by ParaId. On-demand parachains are not included. +Parachains: Vec, +/// The current lifecycle state of all known Para Ids. +ParaLifecycle: map ParaId => Option, +/// The head-data of every registered para. +Heads: map ParaId => Option; +/// The context (relay-chain block number) of the most recent parachain head. +MostRecentContext: map ParaId => BlockNumber; +/// The validation code hash of every live para. +CurrentCodeHash: map ParaId => Option; +/// Actual past code hash, indicated by the para id as well as the block number at which it became outdated. +PastCodeHash: map (ParaId, BlockNumber) => Option; +/// Past code of parachains. The parachains themselves may not be registered anymore, +/// but we also keep their code on-chain for the same amount of time as outdated code +/// to keep it available for secondary checkers. +PastCodeMeta: map ParaId => ParaPastCodeMeta; +/// Which paras have past code that needs pruning and the relay-chain block at which the code was replaced. +/// Note that this is the actual height of the included block, not the expected height at which the +/// code upgrade would be applied, although they may be equal. +/// This is to ensure the entire acceptance period is covered, not an offset acceptance period starting +/// from the time at which the parachain perceives a code upgrade as having occurred. +/// Multiple entries for a single para are permitted. Ordered ascending by block number. +PastCodePruning: Vec<(ParaId, BlockNumber)>; +/// The block number at which the planned code change is expected for a para. +/// The change will be applied after the first parablock for this ID included which executes +/// in the context of a relay chain block with a number >= `expected_at`. +FutureCodeUpgrades: map ParaId => Option; +/// Hash of the actual future code of a para. +FutureCodeHash: map ParaId => Option; +/// This is used by the relay-chain to communicate to a parachain a go-ahead with in the upgrade procedure. +/// +/// This value is absent when there are no upgrades scheduled or during the time the relay chain +/// performs the checks. It is set at the first relay-chain block when the corresponding parachain +/// can switch its upgrade function. As soon as the parachain's block is included, the value +/// gets reset to `None`. +/// +/// NOTE that this field is used by parachains via merkle storage proofs, therefore changing +/// the format will require migration of parachains. +UpgradeGoAheadSignal: map hasher(twox_64_concat) ParaId => Option; +/// This is used by the relay-chain to communicate that there are restrictions for performing +/// an upgrade for this parachain. +/// +/// This may be a because the parachain waits for the upgrade cooldown to expire. Another +/// potential use case is when we want to perform some maintanance (such as storage migration) +/// we could restrict upgrades to make the process simpler. +/// +/// NOTE that this field is used by parachains via merkle storage proofs, therefore changing +/// the format will require migration of parachains. +UpgradeRestrictionSignal: map hasher(twox_64_concat) ParaId => Option; +/// The list of parachains that are awaiting for their upgrade restriction to cooldown. +/// +/// Ordered ascending by block number. +UpgradeCooldowns: Vec<(ParaId, BlockNumberFor)>; +/// The list of upcoming code upgrades. Each item is a pair of which para performs a code +/// upgrade and at which relay-chain block it is expected at. +/// +/// Ordered ascending by block number. +UpcomingUpgrades: Vec<(ParaId, BlockNumberFor)>; +/// The actions to perform during the start of a specific session index. +ActionsQueue: map SessionIndex => Vec; +/// Upcoming paras instantiation arguments. +/// +/// NOTE that after PVF pre-checking is enabled the para genesis arg will have it's code set +/// to empty. Instead, the code will be saved into the storage right away via `CodeByHash`. +UpcomingParasGenesis: map ParaId => Option; +/// The number of references on the validation code in `CodeByHash` storage. +CodeByHashRefs: map ValidationCodeHash => u32; +/// Validation code stored by its hash. +CodeByHash: map ValidationCodeHash => Option +``` + +## Session Change + +1. Execute all queued actions for paralifecycle changes: + 1. Clean up outgoing paras. + 1. This means removing the entries under `Heads`, `CurrentCode`, `FutureCodeUpgrades`, + `FutureCode` and `MostRecentContext`. An according entry should be added to `PastCode`, `PastCodeMeta`, and `PastCodePruning` using the outgoing `ParaId` and removed `CurrentCode` value. This is because any outdated validation code must remain available on-chain for a determined amount + of blocks, and validation code outdated by de-registering the para is still subject to that + invariant. + 1. Apply all incoming paras by initializing the `Heads` and `CurrentCode` using the genesis + parameters as well as `MostRecentContext` to `0`. + 1. Amend the `Parachains` list and `ParaLifecycle` to reflect changes in registered parachains. + 1. Amend the `ParaLifecycle` set to reflect changes in registered on-demand parachains. + 1. Upgrade all on-demand parachains that should become lease holding parachains, updating the `Parachains` list and + `ParaLifecycle`. + 1. Downgrade all lease holding parachains that should become on-demand parachains, updating the `Parachains` list and + `ParaLifecycle`. + 1. (Deferred) Return list of outgoing paras to the initializer for use by other modules. +1. Go over all active PVF pre-checking votes: + 1. Increment `age` of the vote. + 1. If `age` reached `cfg.pvf_voting_ttl`, then enact PVF rejection and remove the vote from the active list. + 1. Otherwise, reinitialize the ballots. + 1. Resize the `votes_accept`/`votes_reject` to have the same length as the incoming validator set. + 1. Zero all the votes. +## Initialization + +1. Do pruning based on all entries in `PastCodePruning` with `BlockNumber <= now`. Update the + corresponding `PastCodeMeta` and `PastCode` accordingly. +1. Toggle the upgrade related signals + 1. Collect all `(para_id, expected_at)` from `UpcomingUpgrades` where `expected_at <= now` and prune them. For each para pruned set `UpgradeGoAheadSignal` to `GoAhead`. Reserve weight for the state modification to upgrade each para pruned. + 1. Collect all `(para_id, next_possible_upgrade_at)` from `UpgradeCooldowns` where `next_possible_upgrade_at <= now`. For each para obtained this way reserve weight to remove its `UpgradeRestrictionSignal` on finalization. + +## Routines + +* `schedule_para_initialize(ParaId, ParaGenesisArgs)`: Schedule a para to be initialized at the next + session. Noop if para is already registered in the system with some `ParaLifecycle`. +* `schedule_para_cleanup(ParaId)`: Schedule a para to be cleaned up after the next full session. +* `schedule_parathread_upgrade(ParaId)`: Schedule a parathread (on-demand parachain) to be upgraded to a parachain. +* `schedule_parachain_downgrade(ParaId)`: Schedule a parachain to be downgraded from lease holding to on-demand. +* `schedule_code_upgrade(ParaId, new_code, relay_parent: BlockNumber, HostConfiguration)`: Schedule a future code + upgrade of the given parachain. In case the PVF pre-checking is disabled, or the new code is already present in the storage, the upgrade will be applied after inclusion of a block of the same parachain + executed in the context of a relay-chain block with number >= `relay_parent + config.validation_upgrade_delay`. If the upgrade is scheduled `UpgradeRestrictionSignal` is set and it will remain set until `relay_parent + config.validation_upgrade_cooldown`. +In case the PVF pre-checking is enabled, or the new code is not already present in the storage, then the PVF pre-checking run will be scheduled for that validation code. If the pre-checking concludes with rejection, then the upgrade is canceled. Otherwise, after pre-checking is concluded the upgrade will be scheduled and be enacted as described above. +* `note_new_head(ParaId, HeadData, BlockNumber)`: note that a para has progressed to a new head, + where the new head was executed in the context of a relay-chain block with given number, the latter value is inserted into the `MostRecentContext` mapping. This will apply pending code upgrades based on the block number provided. If an upgrade took place it will clear the `UpgradeGoAheadSignal`. +* `lifecycle(ParaId) -> Option`: Return the `ParaLifecycle` of a para. +* `is_parachain(ParaId) -> bool`: Returns true if the para ID references any live lease holding parachain, + including those which may be transitioning to an on-demand parachain in the future. +* `is_parathread(ParaId) -> bool`: Returns true if the para ID references any live parathread (on-demand parachain), + including those which may be transitioning to a lease holding parachain in the future. +* `is_valid_para(ParaId) -> bool`: Returns true if the para ID references either a live on-demand parachain + or live lease holding parachain. +* `can_upgrade_validation_code(ParaId) -> bool`: Returns true if the given para can signal code upgrade right now. +* `pvfs_require_prechecking() -> Vec`: Returns the list of PVF validation code hashes that require PVF pre-checking votes. + +## Finalization + +Collect all `(para_id, next_possible_upgrade_at)` from `UpgradeCooldowns` where `next_possible_upgrade_at <= now` and prune them. For each para pruned remove its `UpgradeRestrictionSignal`. diff --git a/polkadot/roadmap/implementers-guide/src/runtime/scheduler.md b/polkadot/roadmap/implementers-guide/src/runtime/scheduler.md new file mode 100644 index 0000000000000000000000000000000000000000..312ecedcb50f7c0108248f4dc9803465be2a0839 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/scheduler.md @@ -0,0 +1,235 @@ +# Scheduler Pallet + +> TODO: this section is still heavily under construction. key questions about availability cores and validator assignment are still open and the flow of the the section may be contradictory or inconsistent + +The Scheduler module is responsible for two main tasks: + +- Partitioning validators into groups and assigning groups to parachains. +- Scheduling parachains for each block + +It aims to achieve these tasks with these goals in mind: + +- It should be possible to know at least a block ahead-of-time, ideally more, which validators are going to be assigned to which parachains. +- Parachains that have a candidate pending availability in this fork of the chain should not be assigned. +- Validator assignments should not be gameable. Malicious cartels should not be able to manipulate the scheduler to assign themselves as desired. +- High or close to optimal throughput of parachains. Work among validator groups should be balanced. + +## Availability Cores + +The Scheduler manages resource allocation using the concept of "Availability Cores". There will be one availability core for each lease holding parachain, and a fixed number of cores used for multiplexing on-demand parachains. Validators will be partitioned into groups, with the same number of groups as availability cores. Validator groups will be assigned to different availability cores over time. + +An availability core can exist in either one of two states at the beginning or end of a block: free or occupied. A free availability core can have a lease holding or on-demand parachain assigned to it for the potential to have a backed candidate included. After backing, the core enters the occupied state as the backed candidate is pending availability. There is an important distinction: a core is not considered occupied until it is in charge of a block pending availability, although the implementation may treat scheduled cores the same as occupied ones for brevity. A core exits the occupied state when the candidate is no longer pending availability - either on timeout or on availability. A core starting in the occupied state can move to the free state and back to occupied all within a single block, as availability bitfields are processed before backed candidates. At the end of the block, there is a possible timeout on availability which can move the core back to the free state if occupied. + +Cores are treated as an ordered list and are typically referred to by their index in that list. + +```dot process +digraph { + label = "Availability Core State Machine\n\n\n"; + labelloc = "t"; + + { rank=same vg1 vg2 } + + vg1 [label = "Free" shape=rectangle] + vg2 [label = "Occupied" shape=rectangle] + + vg1 -> vg2 [label = "Assignment & Backing" ] + vg2 -> vg1 [label = "Availability or Timeout" ] +} +``` + +```dot process +digraph { + label = "Availability Core Transitions within Block\n\n\n"; + labelloc = "t"; + splines="line"; + + subgraph cluster_left { + label = ""; + labelloc = "t"; + + fr1 [label = "Free" shape=rectangle] + fr2 [label = "Free" shape=rectangle] + occ [label = "Occupied" shape=rectangle] + + fr1 -> fr2 [label = "No Backing"] + fr1 -> occ [label = "Backing"] + + { rank=same fr2 occ } + } + + subgraph cluster_right { + label = ""; + labelloc = "t"; + + occ2 [label = "Occupied" shape=rectangle] + fr3 [label = "Free" shape=rectangle] + fr4 [label = "Free" shape=rectangle] + occ3 [label = "Occupied" shape=rectangle] + occ4 [label = "Occupied" shape=rectangle] + + occ2 -> fr3 [label = "Availability"] + occ2 -> occ3 [label = "No availability"] + fr3 -> fr4 [label = "No backing"] + fr3 -> occ4 [label = "Backing"] + occ3 -> occ4 [label = "(no change)"] + occ3 -> fr3 [label = "Availability Timeout"] + + { rank=same; fr3[group=g1]; occ3[group=g2] } + { rank=same; fr4[group=g1]; occ4[group=g2] } + } +} +``` + +## Validator Groups + +Validator group assignments do not need to change very quickly. The security benefits of fast rotation are redundant with the challenge mechanism in the [Approval process](../protocol-approval.md). Because of this, we only divide validators into groups at the beginning of the session and do not shuffle membership during the session. However, we do take steps to ensure that no particular validator group has dominance over a single lease holding parachain or on-demand parachain-multiplexer for an entire session to provide better guarantees of live-ness. + +Validator groups rotate across availability cores in a round-robin fashion, with rotation occurring at fixed intervals. The i'th group will be assigned to the `(i+k)%n`'th core at any point in time, where `k` is the number of rotations that have occurred in the session, and `n` is the number of cores. This makes upcoming rotations within the same session predictable. + +When a rotation occurs, validator groups are still responsible for distributing availability chunks for any previous cores that are still occupied and pending availability. In practice, rotation and availability-timeout frequencies should be set so this will only be the core they have just been rotated from. It is possible that a validator group is rotated onto a core which is currently occupied. In this case, the validator group will have nothing to do until the previously-assigned group finishes their availability work and frees the core or the availability process times out. Depending on if the core is for a lease holding parachain or on-demand parachain, a different timeout `t` from the [`HostConfiguration`](../types/runtime.md#host-configuration) will apply. Availability timeouts should only be triggered in the first `t-1` blocks after the beginning of a rotation. + +## Claims + +On-demand parachains operate on a system of claims. Collators purchase claims on authoring the next block of an on-demand parachain, although the purchase mechanism is beyond the scope of the scheduler. The scheduler guarantees that they'll be given at least a certain number of attempts to author a candidate that is backed. Attempts that fail during the availability phase are not counted, since ensuring availability at that stage is the responsibility of the backing validators, not of the collator. When a claim is accepted, it is placed into a queue of claims, and each claim is assigned to a particular on-demand parachain-multiplexing core in advance. Given that the current assignments of validator groups to cores are known, and the upcoming assignments are predictable, it is possible for on-demand parachain collators to know who they should be talking to now and how they should begin establishing connections with as a fallback. + +With this information, the Node-side can be aware of which on-demand parachains have a good chance of being includable within the relay-chain block and can focus any additional resources on backing candidates from those on-demand parachains. Furthermore, Node-side code is aware of which validator group will be responsible for that thread. If the necessary conditions are reached for core reassignment, those candidates can be backed within the same block as the core being freed. + +On-demand claims, when scheduled onto a free core, may not result in a block pending availability. This may be due to collator error, networking timeout, or censorship by the validator group. In this case, the claims should be retried a certain number of times to give the collator a fair shot. + +## Storage + +Utility structs: + +```rust +// A claim on authoring the next block for a given parathread (on-demand parachain). +struct ParathreadClaim(ParaId, CollatorId); + +// An entry tracking a parathread (on-demand parachain) claim to ensure it does not +// pass the maximum number of retries. +struct ParathreadEntry { + claim: ParathreadClaim, + retries: u32, +} + +// A queued parathread (on-demand parachain) entry, pre-assigned to a core. +struct QueuedParathread { + claim: ParathreadEntry, + /// offset within the set of parathreads (on-demand parachains) ranged `0..config.parathread_cores`. + core_offset: u32, +} + +struct ParathreadQueue { + queue: Vec, + /// offset within the set of parathreads (on-demand parachains) ranged `0..config.parathread_cores`. + next_core_offset: u32, +} + +enum CoreOccupied { + // On-demand parachain + Parathread(ParathreadEntry), // claim & retries + Parachain, +} + +enum AssignmentKind { + Parachain, + // On-demand parachain + Parathread(CollatorId, u32), +} + +struct CoreAssignment { + core: CoreIndex, + para_id: ParaId, + kind: AssignmentKind, +} +// reasons a core might be freed. +enum FreedReason { + Concluded, + TimedOut, +} +``` + +Storage layout: + +```rust +/// All the validator groups. One for each core. Indices are into the `ActiveValidators` storage. +ValidatorGroups: Vec>; +/// A queue of upcoming parathread (on-demand parachain) claims and which core they should be mapped onto. +ParathreadQueue: ParathreadQueue; +/// One entry for each availability core. Entries are `None` if the core is not currently occupied. +/// The i'th parachain lease belongs to the i'th core, with the remaining cores all being +/// on-demand parachain-multiplexers. +AvailabilityCores: Vec>; +/// An index used to ensure that only one claim on a parathread (on-demand parachain) exists in the queue or is +/// currently being handled by an occupied core. +ParathreadClaimIndex: Vec; +/// The block number where the session start occurred. Used to track how many group rotations have occurred. +SessionStartBlock: BlockNumber; +/// Currently scheduled cores - free but up to be occupied. +/// The value contained here will not be valid after the end of a block. +/// Runtime APIs should be used to determine scheduled cores +/// for the upcoming block. +Scheduled: Vec, // sorted ascending by CoreIndex. +``` + +## Session Change + +Session changes are the only time that configuration can change, and the [Configuration module](configuration.md)'s session-change logic is handled before this module's. We also lean on the behavior of the [Inclusion module](inclusion.md) which clears all its occupied cores on session change. Thus we don't have to worry about cores being occupied across session boundaries and it is safe to re-size the `AvailabilityCores` bitfield. + +Actions: + +1. Set `SessionStartBlock` to current block number + 1, as session changes are applied at the end of the block. +1. Clear all `Some` members of `AvailabilityCores`. Return all parathread claims to queue with retries un-incremented. +1. Set `configuration = Configuration::configuration()` (see [`HostConfiguration`](../types/runtime.md#host-configuration)) +1. Fetch `Shared::ActiveValidators` as AV. +1. Determine the number of cores & validator groups as `n_cores`. This is the maximum of + 1. `Paras::parachains().len() + configuration.parathread_cores` + 1. `n_validators / max_validators_per_core` if `configuration.max_validators_per_core` is `Some` and non-zero. +1. Resize `AvailabilityCores` to have length `n_cores` with all `None` entries. +1. Compute new validator groups by shuffling using a secure randomness beacon + - Note that the total number of validators `V` in AV may not be evenly divided by `n_cores`. + - The groups are selected by partitioning AV. The first `V % N` groups will have `(V / n_cores) + 1` members, while the remaining groups will have `(V / N)` members each. + - Instead of using the indices within AV, which point to the broader set, indices _into_ AV should be used. This implies that groups should have simply ascending validator indices. +1. Prune the parathread (on-demand parachain) queue to remove all retries beyond `configuration.parathread_retries`. + - Also prune all on-demand claims corresponding to de-registered parachains. + - all pruned claims should have their entry removed from the parathread (on-demand parachain) index. + - assign all non-pruned claims to new cores if the number of on-demand parachain cores has changed between the `new_config` and `old_config` of the `SessionChangeNotification`. + - Assign claims in equal balance across all cores if rebalancing, and set the `next_core` of the `ParathreadQueue` (on-demand queue) by incrementing the relative index of the last assigned core and taking it modulo the number of on-demand cores. + +## Initialization + +No initialization routine runs for this module. + +## Finalization + +No finalization routine runs for this module. + +## Routines + +- `add_parathread_claim(ParathreadClaim)`: Add a parathread (on-demand parachain) claim to the queue. + - Fails if any on-demand claim on the same parachain is currently indexed. + - Fails if the queue length is >= `config.scheduling_lookahead * config.parathread_cores`. + - The core used for the on-demand claim is the `next_core` field of the `ParathreadQueue` (on-demand queue) and adding `Paras::parachains().len()` to it. + - `next_core` is then updated by adding 1 and taking it modulo `config.parathread_cores`. + - The claim is then added to the claim index. +- `free_cores(Vec<(CoreIndex, FreedReason)>)`: indicate previosuly-occupied cores which are to be considered returned and why they are being returned. + - All freed lease holding parachain cores should be assigned to their respective parachain + - All freed on-demand parachain cores whose reason for freeing was `FreedReason::Concluded` should have the claim removed from the claim index. + - All freed on-demand cores whose reason for freeing was `FreedReason::TimedOut` should have the claim added to the parathread queue (on-demand queue) again without retries incremented + - All freed on-demand cores should take the next on-demand parachain entry from the queue. +- `schedule(Vec<(CoreIndex, FreedReason)>, now: BlockNumber)`: schedule new core assignments, with a parameter indicating previously-occupied cores which are to be considered returned and why they are being returned. + - Invoke `free_cores(freed_cores)` + - The i'th validator group will be assigned to the `(i+k)%n`'th core at any point in time, where `k` is the number of rotations that have occurred in the session, and `n` is the total number of cores. This makes upcoming rotations within the same session predictable. Rotations are based off of `now`. +- `scheduled() -> Vec`: Get currently scheduled core assignments. +- `occupied(Vec)`. Note that the given cores have become occupied. + - Behavior undefined if any given cores were not scheduled. + - Behavior undefined if the given cores are not sorted ascending by core index + - This clears them from `Scheduled` and marks each corresponding `core` in the `AvailabilityCores` as occupied. + - Since both the availability cores and the newly-occupied cores lists are sorted ascending, this method can be implemented efficiently. +- `core_para(CoreIndex) -> ParaId`: return the currently-scheduled or occupied ParaId for the given core. +- `group_validators(GroupIndex) -> Option>`: return all validators in a given group, if the group index is valid for this session. +- `availability_timeout_predicate() -> Option bool>`: returns an optional predicate that should be used for timing out occupied cores. if `None`, no timing-out should be done. The predicate accepts the index of the core, and the block number since which it has been occupied. The predicate should be implemented based on the time since the last validator group rotation, and the respective parachain timeouts, i.e. only within `max(config.chain_availability_period, config.thread_availability_period)` of the last rotation would this return `Some`. +- `group_rotation_info(now: BlockNumber) -> GroupRotationInfo`: Returns a helper for determining group rotation. +- `next_up_on_available(CoreIndex) -> Option`: Return the next thing that will be scheduled on this core assuming it is currently occupied and the candidate occupying it became available. Returns in `ScheduledCore` format (todo: link to Runtime APIs page; linkcheck doesn't allow this right now). For lease holding parachains, this is always the ID of the parachain and no specified collator. For on-demand parachains, this is based on the next item in the `ParathreadQueue` (on-demand queue) assigned to that core, and is `None` if there isn't one. +- `next_up_on_time_out(CoreIndex) -> Option`: Return the next thing that will be scheduled on this core assuming it is currently occupied and the candidate occupying it timed out. Returns in `ScheduledCore` format (todo: link to Runtime APIs page; linkcheck doesn't allow this right now). For parachains, this is always the ID of the parachain and no specified collator. For on-demand parachains, this is based on the next item in the `ParathreadQueue` (on-demand queue) assigned to that core, or if there isn't one, the claim that is currently occupying the core. Otherwise `None`. +- `clear()`: + - Free all scheduled cores and return on-demand claims to queue, with retries incremented. Skip on-demand parachains which no longer exist under paras. diff --git a/polkadot/roadmap/implementers-guide/src/runtime/session_info.md b/polkadot/roadmap/implementers-guide/src/runtime/session_info.md new file mode 100644 index 0000000000000000000000000000000000000000..5ee63ab5a903072935b75abc909d164af5ae5d6b --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/session_info.md @@ -0,0 +1,75 @@ +# Session Info + +For disputes and approvals, we need access to information about validator sets from prior sessions. We also often want easy access to the same information about the current session's validator set. This module aggregates and stores this information in a rolling window while providing easy APIs for access. + +## Storage + +Helper structs: + +```rust +struct SessionInfo { + /// Validators in canonical ordering. + /// + /// NOTE: There might be more authorities in the current session, than `validators` participating + /// in parachain consensus. See + /// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148). + /// + /// `SessionInfo::validators` will be limited to to `max_validators` when set. + validators: Vec, + /// Validators' authority discovery keys for the session in canonical ordering. + /// + /// NOTE: The first `validators.len()` entries will match the corresponding validators in + /// `validators`, afterwards any remaining authorities can be found. This is any authorities not + /// participating in parachain consensus - see + /// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148) + #[cfg_attr(feature = "std", ignore_malloc_size_of = "outside type")] + discovery_keys: Vec, + /// The assignment keys for validators. + /// + /// NOTE: There might be more authorities in the current session, than validators participating + /// in parachain consensus. See + /// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148). + /// + /// Therefore: + /// ```ignore + /// assignment_keys.len() == validators.len() && validators.len() <= discovery_keys.len() + /// ``` + assignment_keys: Vec, + /// Validators in shuffled ordering - these are the validator groups as produced + /// by the `Scheduler` module for the session and are typically referred to by + /// `GroupIndex`. + validator_groups: Vec>, + /// The number of availability cores used by the protocol during this session. + n_cores: u32, + /// The zeroth delay tranche width. + zeroth_delay_tranche_width: u32, + /// The number of samples we do of `relay_vrf_modulo`. + relay_vrf_modulo_samples: u32, + /// The number of delay tranches in total. + n_delay_tranches: u32, + /// How many slots (BABE / SASSAFRAS) must pass before an assignment is considered a + /// no-show. + no_show_slots: u32, + /// The number of validators needed to approve a block. + needed_approvals: u32, +} +``` + +Storage Layout: + +```rust +/// The earliest session for which previous session info is stored. +EarliestStoredSession: SessionIndex, +/// Session information. Should have an entry from `EarliestStoredSession..=CurrentSessionIndex` +Sessions: map SessionIndex => Option, +``` + +## Session Change + +1. Update `EarliestStoredSession` based on `config.dispute_period` and remove all entries from `Sessions` from the previous value up to the new value. +1. Create a new entry in `Sessions` with information about the current session. Use `shared::ActiveValidators` to determine the indices into the broader validator sets (validation, assignment, discovery) which are actually used for parachain validation. Only these validators should appear in the `SessionInfo`. + +## Routines + +* `earliest_stored_session() -> SessionIndex`: Yields the earliest session for which we have information stored. +* `session_info(session: SessionIndex) -> Option`: Yields the session info for the given session, if stored. diff --git a/polkadot/roadmap/implementers-guide/src/runtime/shared.md b/polkadot/roadmap/implementers-guide/src/runtime/shared.md new file mode 100644 index 0000000000000000000000000000000000000000..0f173134e2a2c8b205f6429ff3267d3706842f6f --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/runtime/shared.md @@ -0,0 +1,87 @@ +# Shared Pallet + +This module is responsible for managing shared storage and configuration for other modules. + +It is important that other pallets are able to use the Shared Module, so it should not have a +dependency on any other modules in the Parachains Runtime. + +For the moment, it is used exclusively to track the current session index across the Parachains +Runtime system, and when it should be allowed to schedule future changes to Paras or Configurations. + +## Constants + +```rust +// `SESSION_DELAY` is used to delay any changes to Paras registration or configurations. +// Wait until the session index is 2 larger then the current index to apply any changes, +// which guarantees that at least one full session has passed before any changes are applied. +pub(crate) const SESSION_DELAY: SessionIndex = 2; +``` + +## Storage + +Helper structs: + +```rust +struct AllowedRelayParentsTracker { + // The past relay parents, paired with state roots, that are viable to build upon. + // + // They are in ascending chronologic order, so the newest relay parents are at + // the back of the deque. + // + // (relay_parent, state_root) + // + // NOTE: the size limit of look-back is currently defined as a constant in Runtime. + buffer: VecDeque<(Hash, Hash)>, + + // The number of the most recent relay-parent, if any. + latest_number: BlockNumber, +} +``` + +Storage Layout: + +```rust +/// The current session index within the Parachains Runtime system. +CurrentSessionIndex: SessionIndex; +/// All the validators actively participating in parachain consensus. +/// Indices are into the broader validator set. +ActiveValidatorIndices: Vec, +/// The parachain attestation keys of the validators actively participating in parachain consensus. +/// This should be the same length as `ActiveValidatorIndices`. +ActiveValidatorKeys: Vec +/// Relay-parents allowed to build candidates upon. +AllowedRelayParents: AllowedRelayParentsTracker, +``` + +## Initialization + +The Shared Module currently has no initialization routines. + +The Shared Module is initialized directly after the Configuration module, but before all other +modules. It is important to update the Shared Module before any other module since its state may be +used within the logic of other modules, and it is important that the state is consistent across +them. + +## Session Change + +During a session change, the Shared Module receives and stores the current Session Index directly from the initializer module, along with the broader validator set, and it returns the new list of validators. + +The list of validators should be first shuffled according to the chain's random seed and then truncated. The indices of these validators should be set to `ActiveValidatorIndices` and then returned back to the initializer. `ActiveValidatorKeys` should be set accordingly. + +This information is used in the: + +* Configuration Module: For delaying updates to configurations until at lease one full session has + passed. +* Paras Module: For delaying updates to paras until at least one full session has passed. + +Allowed relay parents buffer, which is maintained by [ParaInherent](./parainherent.md) module, is cleared on every session change. + +## Finalization + +The Shared Module currently has no finalization routines. + +## Functions + +* `scheduled_sessions() -> SessionIndex`: Return the next session index where updates to the + Parachains Runtime system would be safe to apply. +* `set_session_index(SessionIndex)`: For tests. Set the current session index in the Shared Module. diff --git a/polkadot/roadmap/implementers-guide/src/types/README.md b/polkadot/roadmap/implementers-guide/src/types/README.md new file mode 100644 index 0000000000000000000000000000000000000000..807130a5e66b25c441f4945fc2dfb3b63de4f354 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/types/README.md @@ -0,0 +1,432 @@ +# Type Definitions + +This section of the guide provides type definitions of various categories. + +## V1 Overview + +Diagrams are rendered in high resolution; open them in a separate tab to see full scale. + +These data types are defined in `polkadot/primitives/src/v1.rs`: + +```dot process +digraph { + rankdir = LR; + node [shape = plain] + + CandidateDescriptor [label = < + + + + + + + + + +
CandidateDescriptor<H = Hash>
para_idId
relay_parentH
collatorCollatorId
persisted_validation_data_hashHash
pov_hashHash
erasure_rootHash
signatureCollatorSignature
+ >] + + CandidateDescriptor:para_id -> Id:w + CandidateDescriptor:pov_hash -> PoVHash + CandidateDescriptor:collator -> CollatorId:w + CandidateDescriptor:persisted_validation_data_hash -> PersistedValidationDataHash + + Id [label="polkadot_parachain::primitives::Id"] + CollatorId [label="polkadot_primitives::v2::CollatorId"] + + PoVHash [label = "Hash", shape="doublecircle", fill="gray90"] + + PoVHash -> PoV:name + + CandidateReceipt [label = < + + + + +
CandidateReceipt<H = Hash>
descriptorCandidateDescriptor<H>
commitments_hashHash
+ >] + + CandidateReceipt:descriptor -> CandidateDescriptor:name + CandidateReceipt:commitments_hash -> CandidateCommitmentsHash + + CandidateHash [label = "Hash", shape="doublecircle", fill="gray90"] + CandidateHash -> CandidateReceipt:name + + CandidateCommitmentsHash [label = "Hash", shape="doublecircle", fill="gray90"] + CandidateCommitmentsHash -> CandidateCommitments:name + + FullCandidateReceipt [label = < + + + + +
FullCandidateReceipt<H = Hash, N = BlockNumber>
innerCandidateReceipt<H>
validation_dataValidationData<N>
+ >] + + FullCandidateReceipt:inner -> CandidateReceipt:name + FullCandidateReceipt:validation_data -> ValidationData:name + + CommittedCandidateReceipt [label = < + + + + +
CommittedCandidateReceipt<H = Hash>
descriptorCandidateDescriptor<H>
commitmentsCandidateCommitments
+ >] + + CommittedCandidateReceipt:descriptor -> CandidateDescriptor:name + CommittedCandidateReceipt:commitments -> CandidateCommitments:name + + ValidationData [label = < + + + + +
ValidationData<N = BlockNumber>
persistedPersistedValidationData<N>
transientTransientValidationData<N>
+ >] + + ValidationData:persisted -> PersistedValidationData:name + ValidationData:transient -> TransientValidationData:name + + PersistedValidationData [label = < + + + + + + +
PersistedValidationData<N = BlockNumber>
parent_headHeadData
block_numberN
relay_parent_storage_rootHash
max_pov_sizeu32
+ >] + + PersistedValidationData:parent_head -> HeadData:w + + PersistedValidationDataHash [label = "Hash", shape="doublecircle", fill="gray90"] + PersistedValidationDataHash -> PersistedValidationData:name + + TransientValidationData [label = < + + + + + + + +
TransientValidationData<N = BlockNumber>
max_code_sizeu32
max_head_data_sizeu32
balanceBalance
code_upgrade_allowedOption<N>
dmq_lengthu32
+ >] + + TransientValidationData:balance -> "polkadot_core_primitives::v2::Balance":w + + CandidateCommitments [label = < + + + + + + + + +
CandidateCommitments<N = BlockNumber>
upward_messagesVec<UpwardMessage>
horizontal_messagesVec<OutboundHrmpMessage<Id>>
new_validation_codeOption<ValidationCode>
head_dataHeadData
processed_downward_messagesu32
hrmp_watermarkN
+ >] + + CandidateCommitments:upward_messages -> "polkadot_parachain::primitives::UpwardMessage":w + CandidateCommitments:horizontal_messages -> "polkadot_core_primitives::v2::OutboundHrmpMessage":w + CandidateCommitments:head_data -> HeadData:w + CandidateCommitments:horizontal_messages -> "polkadot_parachain::primitives::Id":w + CandidateCommitments:new_validation_code -> "polkadot_parachain::primitives::ValidationCode":w + + PoV [label = < + + + +
PoV
block_dataBlockData
+ >] + + PoV:block_data -> "polkadot_parachain::primitives::BlockData":w + + BackedCandidate [label = < + + + + + +
BackedCandidate<H = Hash>
candidateCommittedCandidateReceipt<H>
validity_votesVec<ValidityAttestation>
validator_indicesBitVec
+ >] + + BackedCandidate:candidate -> CommittedCandidateReceipt:name + BackedCandidate:validity_votes -> "polkadot_primitives:v0:ValidityAttestation":w + + HeadData [label = "polkadot_parachain::primitives::HeadData"] + + CoreIndex [label = < + + + +
CoreIndex
0u32
+ >] + + GroupIndex [label = < + + + +
GroupIndex
0u32
+ >] + + ParathreadClaim [label = < + + + + +
ParathreadClaim
0Id
1CollatorId
+ >] + + ParathreadClaim:0 -> Id:w + ParathreadClaim:1 -> CollatorId:w + + MessageQueueChainLink [label = "(prev_head, B, H(M))\nSee doc of AbridgedHrmpChannel::mqc_head"] + MQCHash [label = "Hash", shape="doublecircle", fill="gray90"] + + MQCHash -> MessageQueueChainLink + + ParathreadEntry [label = < + + + + +
ParathreadEntry
claimParathreadClaim
retriesu32
+ >] + + ParathreadEntry:claim -> ParathreadClaim:name + + CoreOccupied [label = < + + + + +
enum CoreOccupied
Parathread(ParathreadEntry)
Parachain
+ >] + + CoreOccupied:parathread -> ParathreadEntry:name + + AvailableData [label = < + + + + +
AvailableData
povArc<PoV>
validation_dataPersistedValidationData
+ >] + + AvailableData:pov -> PoV:name + AvailableData:validation_data -> PersistedValidationData:name + + GroupRotationInfo [label = < + + + + + +
GroupRotationInfo<N = BlockNumber>
session_start_blockN
group_rotation_frequencyN
nowN
+ >] + + OccupiedCore [label = < + + + + + + + + + + +
OccupiedCore<H = Hash, N = BlockNumber>
next_up_on_availableOption<ScheduledCore>
occupied_sinceN
time_out_atN
next_up_on_time_outOption<ScheduledCore>
availabilityBitVec
group_responsibleGroupIndex
candidate_hashCandidateHash
candidate_descriptorCandidateDescriptor
+ >] + + OccupiedCore:next_up_on_available -> ScheduledCore:name + OccupiedCore:next_up_on_time_out -> ScheduledCore:name + OccupiedCore:group_responsible -> GroupIndex + OccupiedCore:candidate_hash -> CandidateHash + OccupiedCore:candidate_descriptor -> CandidateDescriptor:name + + ScheduledCore [label = < + + + + +
ScheduledCore
para_idId
collatorOption<CollatorId>
+ >] + + ScheduledCore:para_id -> Id:w + ScheduledCore:collator -> CollatorId:w + + CoreState [label = < + + + + + +
enum CoreState<H = Hash, N = BlockNumber>
Occupied(OccupiedCore<H, N>)
Scheduled(ScheduledCore)
Free
+ >] + + CoreState:occupied -> OccupiedCore:name + CoreState:scheduled -> ScheduledCore:name + + CandidateEvent [label = < + + + + + +
enum CandidateEvent<H = Hash>
CandidateBacked(CandidateReceipt<H>, HeadData)
CandidateIncluded(CandidateReceipt<H>, HeadData)
CandidateTimedOut(CandidateReceipt<H>, HeadData)
+ >] + + CandidateEvent:e -> CandidateReceipt:name + CandidateEvent:e -> HeadData:w + + SessionInfo [label = < + + + + + + + + + + + + +
SessionInfo
validatorsVec<ValidatorId>
discovery_keysVec<AuthorityDiscoveryId>
assignment_keysVec<AssignmentId>
validator_groupsVec<Vec<ValidatorIndex>>
n_coresu32
zeroth_delay_tranche_widthu32
relay_vrf_modulo_samplesu32
n_delay_tranchesu32
no_show_slotsu32
needed_approvalsu32
+ >] + + SessionInfo:validators -> ValidatorId:w + SessionInfo:discovery_keys -> AuthorityDiscoveryId:w + SessionInfo:validator_groups -> ValidatorIndex:w + + ValidatorId [label = "polkadot_primitives::v2::ValidatorId"] + AuthorityDiscoveryId [label = "sp_authority_discovery::AuthorityId"] + ValidatorIndex [label = "polkadot_primitives::v2::ValidatorIndex"] + + AbridgedHostConfiguration [label = < + + + + + + + + + + + +
AbridgedHostConfiguration
max_code_sizeu32
max_head_data_sizeu32
max_upward_queue_countu32
max_upward_queue_sizeu32
max_upward_message_sizeu32
max_upward_messages_num_per_candidateu32
hrmp_max_message_num_per_candidateu32
validation_upgrade_cooldownBlockNumber
validation_upgrade_delayBlockNumber
+ >] + + AbridgedHrmpChannel [label = < + + + + + + + + +
AbridgedHrmpChannel
max_capacityu32
max_total_sizeu32
max_message_sizeu32
msg_countu32
total_sizeu32
mqc_headOption<Hash>
+ >] + + AbridgedHrmpChannel:mqc_head -> MQCHash +} +``` + +These data types are defined in `polkadot/parachain/src/primitives.rs`: + +```dot process +digraph { + rankdir = LR; + node [shape = plain] + + HeadData [label = < + + + +
HeadData
0Vec<u8>
+ >] + + ValidationCode [label = < + + + +
ValidationCode
0Vec<u8>
+ >] + + BlockData [label = < + + + +
BlockData
0Vec<u8>
+ >] + + Id [label = < + + + +
Id
0u32
+ >] + + Sibling [label = < + + + +
Sibling
0Id
+ >] + + Sibling:0 -> Id:name + + HrmpChannelId [label = < + + + + +
HrmpChannelId
senderId
recipientId
+ >] + + HrmpChannelId:e -> Id:name + + ValidationParams [label = < + + + + + + +
ValidationParams
parent_headHeadData
block_dataBlockData
relay_parent_numberRelayChainBlockNumber
relay_parent_storage_rootHash
+ >] + + ValidationParams:parent_head -> HeadData:name + ValidationParams:block_data -> BlockData:name + ValidationParams:relay_parent_number -> RelayChainBlockNumber:w + + RelayChainBlockNumber [label = "polkadot_core_primitives::BlockNumber"] + + ValidationResult [label = < + + + + + + + + +
ValidationResult
head_dataHeadData
new_validation_codeOption<ValidationCode>
upward_messagesVec<UpwardMessage>
horizontal_messagesVec<OutboundHrmpMessage<Id>>
processed_downward_messagesu32
hrmp_watermarkRelayChainBlockNumber
+ >] + + ValidationResult:head_data -> HeadData:name + ValidationResult:new_validation_code -> ValidationCode:name + ValidationResult:upward_messages -> UpwardMessage:w + ValidationResult:horizontal_messages -> OutboundHrmpMessage:w + ValidationResult:horizontal_messages -> Id:name + ValidationResult:hrmp_watermark -> RelayChainBlockNumber:w + + UpwardMessage [label = "Vec"] + OutboundHrmpMessage [label = "polkadot_core_primitives::OutboundHrmpMessage"] +} +``` diff --git a/polkadot/roadmap/implementers-guide/src/types/approval.md b/polkadot/roadmap/implementers-guide/src/types/approval.md new file mode 100644 index 0000000000000000000000000000000000000000..b58e0a8187e1d3af2eae4a7a0ec8d1ee64368b56 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/types/approval.md @@ -0,0 +1,101 @@ +# Approval Types + +## `AssignmentId` + +The public key of a keypair used by a validator for determining assignments to approve included parachain candidates. + +## `AssignmentCert` + +An `AssignmentCert`, short for Assignment Certificate, is a piece of data provided by a validator to prove that they have been selected to perform approval checks on an included candidate. + +These certificates can be checked in the context of a specific block, candidate, and validator assignment VRF key. The block state will also provide further context about the availability core states at that block. + +```rust +enum AssignmentCertKind { + RelayVRFModulo { + sample: u32, + }, + RelayVRFDelay { + core_index: CoreIndex, + } +} + +struct AssignmentCert { + // The criterion which is claimed to be met by this cert. + kind: AssignmentCertKind, + // The VRF showing the criterion is met. + vrf: (VRFPreOut, VRFProof), +} +``` + +> TODO: `RelayEquivocation` cert. Probably can only be broadcast to chains that have handled an equivocation report. + +## `IndirectAssignmentCert` + +An assignment cert which refers to the candidate under which the assignment is relevant by block hash. + +```rust +struct IndirectAssignmentCert { + // A block hash where the candidate appears. + block_hash: Hash, + validator: ValidatorIndex, + cert: AssignmentCert, +} +``` + +## `ApprovalVote` + +A vote of approval on a candidate. + +```rust +struct ApprovalVote(Hash); +``` + +## `SignedApprovalVote` + +An approval vote signed with a validator's key. This should be verifiable under the `ValidatorId` corresponding to the `ValidatorIndex` of the session, which should be implicit from context. + +```rust +struct SignedApprovalVote { + vote: ApprovalVote, + validator: ValidatorIndex, + signature: ValidatorSignature, +} +``` + +## `IndirectSignedApprovalVote` + +A signed approval vote which references the candidate indirectly via the block. If there exists a look-up to the candidate hash from the block hash and candidate index, then this can be transformed into a `SignedApprovalVote`. + +Although this vote references the candidate by a specific block hash and candidate index, the signature is computed on the actual `SignedApprovalVote` payload. + +```rust +struct IndirectSignedApprovalVote { + // A block hash where the candidate appears. + block_hash: Hash, + // The index of the candidate in the list of candidates fully included as-of the block. + candidate_index: CandidateIndex, + validator: ValidatorIndex, + signature: ValidatorSignature, +} +``` + +## `CheckedAssignmentCert` + +An assignment cert which has checked both the VRF and the validity of the implied assignment according to the selection criteria rules of the protocol. This type should be declared in such a way as to be instantiatable only when the checks have actually been done. Fields should be accessible via getters, not direct struct access. + +```rust +struct CheckedAssignmentCert { + cert: AssignmentCert, + validator: ValidatorIndex, + relay_block: Hash, + candidate_hash: Hash, + delay_tranche: DelayTranche, +} +``` + +## `DelayTranche` + +```rust +type DelayTranche = u32; +``` diff --git a/polkadot/roadmap/implementers-guide/src/types/availability.md b/polkadot/roadmap/implementers-guide/src/types/availability.md new file mode 100644 index 0000000000000000000000000000000000000000..e2b90e86f43fe6ce4d8e679866d7f6e7ce002865 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/types/availability.md @@ -0,0 +1,65 @@ +# Availability + +One of the key roles of validators is to ensure availability of all data necessary to validate +candidates for the duration of a challenge period. This is done via an erasure-coding of the data to keep available. + +## Signed Availability Bitfield + +A bitfield [signed](backing.md#signed-wrapper) by a particular validator about the availability of pending candidates. + + +```rust +type SignedAvailabilityBitfield = Signed; + +struct Bitfields(Vec<(SignedAvailabilityBitfield)>), // bitfields sorted by validator index, ascending +``` + +### Semantics + +A `SignedAvailabilityBitfield` represents the view from a particular validator's perspective. Each bit in the bitfield corresponds to a single [availability core](../runtime-api/availability-cores.md). A `1` bit indicates that the validator believes the following statements to be true for a core: + +- the availability core is occupied +- there exists a [`CommittedCandidateReceipt`](candidate.html#committed-candidate-receipt) corresponding to that core. In other words, that para has a block in progress. +- the validator's [Availability Store](../node/utility/availability-store.md) contains a chunk of that parablock's PoV. + +In other words, it is the transpose of [`OccupiedCore::availability`](../runtime-api/availability-cores.md). + +## Proof-of-Validity + +Often referred to as PoV, this is a type-safe wrapper around bytes (`Vec`) when referring to data that acts as a stateless-client proof of validity of a candidate, when used as input to the validation function of the para. + +```rust +struct PoV(Vec); +``` + + +## Available Data + +This is the data we want to keep available for each [candidate](candidate.md) included in the relay chain. This is the PoV of the block, as well as the [`PersistedValidationData`](candidate.md#persistedvalidationdata) + +```rust +struct AvailableData { + /// The Proof-of-Validation of the candidate. + pov: Arc, + /// The persisted validation data used to check the candidate. + validation_data: PersistedValidationData, +} +``` + +> TODO: With XCMP, we also need to keep available the outgoing messages as a result of para-validation. + +## Erasure Chunk + +The [`AvailableData`](#availabledata) is split up into an erasure-coding as part of the availability process. Each validator gets a chunk. This describes one of those chunks, along with its proof against a merkle root hash, which should be apparent from context, and is the `erasure_root` field of a [`CandidateDescriptor`](candidate.md#candidatedescriptor). + + +```rust +struct ErasureChunk { + /// The erasure-encoded chunk of data belonging to the candidate block. + chunk: Vec, + /// The index of this erasure-encoded chunk of data. + index: u32, + /// Proof for this chunk's branch in the Merkle tree. + proof: Vec>, +} +``` diff --git a/polkadot/roadmap/implementers-guide/src/types/backing.md b/polkadot/roadmap/implementers-guide/src/types/backing.md new file mode 100644 index 0000000000000000000000000000000000000000..5fcb3ae161b621b9fd1cc7e91bcc89561980618d --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/types/backing.md @@ -0,0 +1,116 @@ +# Backing Types + +[Candidates](candidate.md) go through many phases before being considered included in a fork of the relay chain and eventually accepted. + +These types describe the data used in the backing phase. Some are sent over the wire within subsystems, and some are simply included in the relay-chain block. + +## Validity Attestation + +An attestation of validity for a candidate, used as part of a backing. Both the `Seconded` and `Valid` statements are considered attestations of validity. This structure is only useful where the candidate referenced is apparent. + +```rust +enum ValidityAttestation { + /// Implicit validity attestation by issuing. + /// This corresponds to issuance of a `Seconded` statement. + Implicit(ValidatorSignature), + /// An explicit attestation. This corresponds to issuance of a + /// `Valid` statement. + Explicit(ValidatorSignature), +} +``` + +## Signed Wrapper + +There are a few distinct types which we desire to sign, and validate the signatures of. Instead of duplicating this work, we extract a signed wrapper. + +```rust,ignore +/// A signed type which encapsulates the common desire to sign some data and validate a signature. +/// +/// Note that the internal fields are not public; they are all accessable by immutable getters. +/// This reduces the chance that they are accidentally mutated, invalidating the signature. +struct Signed { + /// The payload is part of the signed data. The rest is the signing context, + /// which is known both at signing and at validation. + payload: Payload, + /// The index of the validator signing this statement. + validator_index: ValidatorIndex, + /// The signature by the validator of the signed payload. + signature: ValidatorSignature, +} + +impl, RealPayload: Encode> Signed { + fn sign(payload: Payload, context: SigningContext, index: ValidatorIndex, key: ValidatorPair) -> Signed { ... } + fn validate(&self, context: SigningContext, key: ValidatorId) -> bool { ... } +} +``` + +Note the presence of the [`SigningContext`](../types/candidate.md#signing-context) in the signatures of the `sign` and `validate` methods. To ensure cryptographic security, the actual signed payload is always the SCALE encoding of `(payload.into(), signing_context)`. Including the signing context prevents replay attacks. + +`EncodeAs` is a helper trait with a blanket impl which ensures that any `T` can `EncodeAs`. Therefore, for the generic case where `RealPayload = Payload`, it changes nothing. However, we `impl EncodeAs for Statement`, which helps efficiency. + +## Statement Type + +The [Candidate Backing subsystem](../node/backing/candidate-backing.md) issues and signs these after candidate validation. + +```rust +/// A statement about the validity of a parachain candidate. +enum Statement { + /// A statement about a new candidate being seconded by a validator. This is an implicit validity vote. + /// + /// The main semantic difference between `Seconded` and `Valid` comes from the fact that every validator may + /// second only 1 candidate; this places an upper bound on the total number of candidates whose validity + /// needs to be checked. A validator who seconds more than 1 parachain candidate per relay head is subject + /// to slashing. + Seconded(CommittedCandidateReceipt), + /// A statement about the validity of a candidate, based on candidate's hash. + Valid(Hash), +} + +/// A statement about the validity of a parachain candidate. +/// +/// This variant should only be used in the production of `SignedStatement`s. The only difference between +/// this enum and `Statement` is that the `Seconded` variant contains a `Hash` instead of a `CandidateReceipt`. +/// The rationale behind the difference is that the signature should always be on the hash instead of the +/// full data, as this lowers the requirement for checking while retaining necessary cryptographic properties +enum CompactStatement { + /// A statement about a new candidate being seconded by a validator. This is an implicit validity vote. + Seconded(Hash), + /// A statement about the validity of a candidate, based on candidate's hash. + Valid(Hash), +} +``` + +`CompactStatement` exists because a `CandidateReceipt` includes `HeadData`, which does not have a bounded size. + +## Signed Statement Type + +A statement which has been [cryptographically signed](#signed-wrapper) by a validator. + +```rust +/// A signed statement, containing the committed candidate receipt in the `Seconded` variant. +pub type SignedFullStatement = Signed; + +/// A signed statement, containing only the hash. +pub type SignedStatement = Signed; +``` + +Munging the signed `Statement` into a `CompactStatement` before signing allows the candidate receipt itself to be omitted when checking a signature on a `Seconded` statement. + +## Backed Candidate + +An [`CommittedCandidateReceipt`](candidate.md#committed-candidate-receipt) along with all data necessary to prove its backing. This is submitted to the relay-chain to process and move along the candidate to the pending-availability stage. + +```rust +struct BackedCandidate { + candidate: CommittedCandidateReceipt, + validity_votes: Vec, + // the indices of validators who signed the candidate within the group. There is no need to include + // bit for any validators who are not in the group, so this is more compact. + // The number of bits is the number of validators in the group. + // + // the group should be apparent from context. + validator_indices: BitVec, +} + +struct BackedCandidates(Vec); // sorted by para-id. +``` diff --git a/polkadot/roadmap/implementers-guide/src/types/candidate.md b/polkadot/roadmap/implementers-guide/src/types/candidate.md new file mode 100644 index 0000000000000000000000000000000000000000..a37f98054c5e5a8430c5d2f3509b2efa3eb5988e --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/types/candidate.md @@ -0,0 +1,186 @@ +# Candidate Types + +Para candidates are some of the most common types, both within the runtime and on the Node-side. +Candidates are the fundamental datatype for advancing parachains, encapsulating the collator's signature, the context of the parablock, the commitments to the output, and a commitment to the data which proves it valid. + +In a way, this entire guide is about these candidates: how they are scheduled, constructed, backed, included, and challenged. + +This section will describe the base candidate type, its components, and variants that contain extra data. + +## Para Id + +A unique 32-bit identifier referring to a specific para (chain or thread). The relay-chain runtime guarantees that `ParaId`s are unique for the duration of any session, but recycling and reuse over a longer period of time is permitted. + +```rust +struct ParaId(u32); +``` + +## Candidate Receipt + +Much info in a [`FullCandidateReceipt`](#full-candidate-receipt) is duplicated from the relay-chain state. When the corresponding relay-chain state is considered widely available, the Candidate Receipt should be favored over the `FullCandidateReceipt`. + +Examples of situations where the state is readily available includes within the scope of work done by subsystems working on a given relay-parent, or within the logic of the runtime importing a backed candidate. + +```rust +/// A candidate-receipt. +struct CandidateReceipt { + /// The descriptor of the candidate. + descriptor: CandidateDescriptor, + /// The hash of the encoded commitments made as a result of candidate execution. + commitments_hash: Hash, +} +``` + +## Full Candidate Receipt + +This is the full receipt type. The `PersistedValidationData` are technically redundant with the `inner.relay_parent`, which uniquely describes the block in the blockchain from whose state these values are derived. The [`CandidateReceipt`](#candidate-receipt) variant is often used instead for this reason. + +However, the Full Candidate Receipt type is useful as a means of avoiding the implicit dependency on availability of old blockchain state. In situations such as availability and approval, having the full description of the candidate within a self-contained struct is convenient. + +```rust +/// All data pertaining to the execution of a para candidate. +struct FullCandidateReceipt { + inner: CandidateReceipt, + validation_data: PeristedValidationData, +} +``` + +## Committed Candidate Receipt + +This is a variant of the candidate receipt which includes the commitments of the candidate receipt alongside the descriptor. This should be favored over the [`Candidate Receipt`](#candidate-receipt) in situations where the candidate is not going to be executed but the actual data committed to is important. This is often the case in the backing phase. + +The hash of the committed candidate receipt will be the same as the corresponding [`Candidate Receipt`](#candidate-receipt), because it is computed by first hashing the encoding of the commitments to form a plain [`Candidate Receipt`](#candidate-receipt). + +```rust +/// A candidate-receipt with commitments directly included. +struct CommittedCandidateReceipt { + /// The descriptor of the candidate. + descriptor: CandidateDescriptor, + /// The commitments of the candidate receipt. + commitments: CandidateCommitments, +} +``` + +## Candidate Descriptor + +This struct is pure description of the candidate, in a lightweight format. + +```rust +/// A unique descriptor of the candidate receipt. +struct CandidateDescriptor { + /// The ID of the para this is a candidate for. + para_id: ParaId, + /// The hash of the relay-chain block this is executed in the context of. + relay_parent: Hash, + /// The collator's sr25519 public key. + collator: CollatorId, + /// The blake2-256 hash of the persisted validation data. These are extra parameters + /// derived from relay-chain state that influence the validity of the block which + /// must also be kept available for approval checkers. + persisted_validation_data_hash: Hash, + /// The blake2-256 hash of the `pov-block`. + pov_hash: Hash, + /// The root of a block's erasure encoding Merkle tree. + erasure_root: Hash, + /// Signature on blake2-256 of components of this receipt: + /// The parachain index, the relay parent, the validation data hash, and the `pov_hash`. + signature: CollatorSignature, + /// Hash of the para header that is being generated by this candidate. + para_head: Hash, + /// The blake2-256 hash of the validation code bytes. + validation_code_hash: ValidationCodeHash, +} +``` + +## `ValidationParams` + +```rust +/// Validation parameters for evaluating the parachain validity function. +pub struct ValidationParams { + /// Previous head-data. + pub parent_head: HeadData, + /// The collation body. + pub block_data: BlockData, + /// The current relay-chain block number. + pub relay_parent_number: RelayChainBlockNumber, + /// The relay-chain block's storage root. + pub relay_parent_storage_root: Hash, +} +``` + +## `PersistedValidationData` + +The validation data provides information about how to create the inputs for validation of a candidate. This information is derived from the chain state and will vary from para to para, although some of the fields may be the same for every para. + +Since this data is used to form inputs to the validation function, it needs to be persisted by the availability system to avoid dependence on availability of the relay-chain state. + +Furthermore, the validation data acts as a way to authorize the additional data the collator needs to pass to the validation function. For example, the validation function can check whether the incoming messages (e.g. downward messages) were actually sent by using the data provided in the validation data using so called MQC heads. + +Since the commitments of the validation function are checked by the relay-chain, approval checkers can rely on the invariant that the relay-chain only includes para-blocks for which these checks have already been done. As such, there is no need for the validation data used to inform validators and collators about the checks the relay-chain will perform to be persisted by the availability system. + +The `PersistedValidationData` should be relatively lightweight primarily because it is constructed during inclusion for each candidate and therefore lies on the critical path of inclusion. + +```rust +struct PersistedValidationData { + /// The parent head-data. + parent_head: HeadData, + /// The relay-chain block number this is in the context of. This informs the collator. + relay_parent_number: BlockNumber, + /// The relay-chain block storage root this is in the context of. + relay_parent_storage_root: Hash, + /// The list of MQC heads for the inbound channels paired with the sender para ids. This + /// vector is sorted ascending by the para id and doesn't contain multiple entries with the same + /// sender. + /// + /// The HRMP MQC heads will be used by the validation function to authorize the input messages passed + /// by the collator. + hrmp_mqc_heads: Vec<(ParaId, Hash)>, + /// The maximum legal size of a POV block, in bytes. + pub max_pov_size: u32, +} +``` + +## `HeadData` + +Head data is a type-safe abstraction around bytes (`Vec`) for the purposes of representing heads of parachains. + +```rust +struct HeadData(Vec); +``` + +## Candidate Commitments + +The execution and validation of parachain candidates produces a number of values which either must be committed to blocks on the relay chain or committed to the state of the relay chain. + +```rust +/// Commitments made in a `CandidateReceipt`. Many of these are outputs of validation. +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Default))] +struct CandidateCommitments { + /// Messages directed to other paras routed via the relay chain. + horizontal_messages: Vec, + /// Messages destined to be interpreted by the Relay chain itself. + upward_messages: Vec, + /// New validation code. + new_validation_code: Option, + /// The head-data produced as a result of execution. + head_data: HeadData, + /// The number of messages processed from the DMQ. + processed_downward_messages: u32, + /// The mark which specifies the block number up to which all inbound HRMP messages are processed. + hrmp_watermark: BlockNumber, +} +``` + +## Signing Context + +This struct provides context to signatures by combining with various payloads to localize the signature to a particular session index and relay-chain hash. Having these fields included in the signature makes misbehavior attribution much simpler. + +```rust +struct SigningContext { + /// The relay-chain block hash this signature is in the context of. + parent_hash: Hash, + /// The session index this signature is in the context of. + session_index: SessionIndex, +} +``` diff --git a/polkadot/roadmap/implementers-guide/src/types/disputes.md b/polkadot/roadmap/implementers-guide/src/types/disputes.md new file mode 100644 index 0000000000000000000000000000000000000000..24f152b1308f7a1613958cb210aeeef12901fefe --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/types/disputes.md @@ -0,0 +1,90 @@ +# Disputes + +## `DisputeStatementSet` + +```rust +/// A set of statements about a specific candidate. +struct DisputeStatementSet { + candidate_hash: CandidateHash, + session: SessionIndex, + statements: Vec<(DisputeStatement, ValidatorIndex, ValidatorSignature)>, +} +``` + +## `DisputeStatement` + +```rust +/// A statement about a candidate, to be used within some dispute resolution process. +/// +/// Statements are either in favor of the candidate's validity or against it. +enum DisputeStatement { + /// A valid statement, of the given kind + Valid(ValidDisputeStatementKind), + /// An invalid statement, of the given kind. + Invalid(InvalidDisputeStatementKind), +} + +``` + +## Dispute Statement Kinds + +Kinds of dispute statements. Each of these can be combined with a candidate hash, session index, validator public key, and validator signature to reproduce and check the original statement. + +```rust +enum ValidDisputeStatementKind { + Explicit, + BackingSeconded(Hash), + BackingValid(Hash), + ApprovalChecking, +} + +enum InvalidDisputeStatementKind { + Explicit, +} +``` + +## `ExplicitDisputeStatement` + +```rust +struct ExplicitDisputeStatement { + valid: bool, + candidate_hash: CandidateHash, + session: SessionIndex, +} +``` + +## `MultiDisputeStatementSet` + +Sets of statements for many (zero or more) disputes. + +```rust +type MultiDisputeStatementSet = Vec; +``` + +## `DisputeState` + +```rust +struct DisputeState { + validators_for: Bitfield, // one bit per validator. + validators_against: Bitfield, // one bit per validator. + start: BlockNumber, + concluded_at: Option, +} +``` + +## `ScrapedOnChainVotes` + +```rust +/// Type for transcending recorded on-chain +/// dispute relevant votes and conclusions to +/// the off-chain `DisputesCoordinator`. +struct ScrapedOnChainVotes { + /// The session index at which the block was included. + session: SessionIndex, + /// The backing and seconding validity attestations for all candidates, provigind the full candidate receipt. + backing_validators_per_candidate: Vec<(CandidateReceipt, Vec<(ValidatorIndex, ValidityAttestation)>)> + /// Set of concluded disputes that were recorded + /// on chain within the inherent. + disputes: MultiDisputeStatementSet, +} +``` diff --git a/polkadot/roadmap/implementers-guide/src/types/messages.md b/polkadot/roadmap/implementers-guide/src/types/messages.md new file mode 100644 index 0000000000000000000000000000000000000000..8ea58d14e85d796a2adef08f20b570c95e0b9d85 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/types/messages.md @@ -0,0 +1,74 @@ +# Message types + +Types of messages that are passed between parachains and the relay chain: UMP, DMP, XCMP. + +There is also HRMP (Horizontally Relay-routed Message Passing) which provides the same functionality +although with smaller scalability potential. + +## Vertical Message Passing + +Types required for message passing between the relay-chain and a parachain. + +Actual contents of the messages is specified by the XCM standard. + +```rust,ignore +/// A message sent from a parachain to the relay-chain. +type UpwardMessage = Vec; + +/// A message sent from the relay-chain down to a parachain. +/// +/// The size of the message is limited by the `config.max_downward_message_size` +/// parameter. +type DownwardMessage = Vec; + +/// This struct extends `DownwardMessage` by adding the relay-chain block number when the message was +/// enqueued in the downward message queue. +struct InboundDownwardMessage { + /// The block number at which this messages was put into the downward message queue. + pub sent_at: BlockNumber, + /// The actual downward message to processes. + pub msg: DownwardMessage, +} +``` + +## Horizontal Message Passing + +## HrmpChannelId + +A type that uniquely identifies an HRMP channel. An HRMP channel is established between two paras. +In text, we use the notation `(A, B)` to specify a channel between A and B. The channels are +unidirectional, meaning that `(A, B)` and `(B, A)` refer to different channels. The convention is +that we use the first item tuple for the sender and the second for the recipient. Only one channel +is allowed between two participants in one direction, i.e. there cannot be 2 different channels +identified by `(A, B)`. + +```rust,ignore +struct HrmpChannelId { + sender: ParaId, + recipient: ParaId, +} +``` + +## Horizontal Message + +This is a message sent from a parachain to another parachain that travels through the relay chain. +This message ends up in the recipient's mailbox. A size of a horizontal message is defined by its +`data` payload. + +```rust,ignore +struct OutboundHrmpMessage { + /// The para that will get this message in its downward message queue. + pub recipient: ParaId, + /// The message payload. + pub data: Vec, +} + +struct InboundHrmpMessage { + /// The block number at which this message was sent. + /// Specifically, it is the block number at which the candidate that sends this message was + /// enacted. + pub sent_at: BlockNumber, + /// The message payload. + pub data: Vec, +} +``` diff --git a/polkadot/roadmap/implementers-guide/src/types/network.md b/polkadot/roadmap/implementers-guide/src/types/network.md new file mode 100644 index 0000000000000000000000000000000000000000..b698ca2075bfe6e40a2098b2beaaa8c29dd60d27 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/types/network.md @@ -0,0 +1,194 @@ +# Network Types + +These types are those that are actually sent over the network to subsystems. + +## Universal Types + +```rust +type RequestId = u64; +type ProtocolVersion = u32; +struct PeerId(...); // opaque, unique identifier of a peer. +struct View { + // Up to `N` (5?) chain heads. + heads: Vec, + // The number of the finalized block. + finalized_number: BlockNumber, +} + +enum ObservedRole { + Full, + Light, +} +``` + +## V1 Network Subsystem Message Types + +### Approval Distribution V1 + +```rust +enum ApprovalDistributionV1Message { + /// Assignments for candidates in recent, unfinalized blocks. + /// + /// The u32 is the claimed index of the candidate this assignment corresponds to. Actually checking the assignment + /// may yield a different result. + Assignments(Vec<(IndirectAssignmentCert, u32)>), + /// Approvals for candidates in some recent, unfinalized block. + Approvals(Vec), +} +``` + +### Availability Distribution V1 + +```rust +enum AvailabilityDistributionV1Message { + /// An erasure chunk for a given candidate hash. + Chunk(CandidateHash, ErasureChunk), +} +``` + +### Availability Recovery V1 + +```rust +enum AvailabilityRecoveryV1Message { + /// Request a chunk for a given candidate hash and validator index. + RequestChunk(RequestId, CandidateHash, ValidatorIndex), + /// Respond with chunk for a given candidate hash and validator index. + /// The response may be `None` if the requestee does not have the chunk. + Chunk(RequestId, Option), + /// Request the full data for a given candidate hash. + RequestFullData(RequestId, CandidateHash), + /// Respond with data for a given candidate hash and validator index. + /// The response may be `None` if the requestee does not have the data. + FullData(RequestId, Option), + +} +``` + +### Bitfield Distribution V1 + +```rust +enum BitfieldDistributionV1Message { + /// A signed availability bitfield for a given relay-parent hash. + Bitfield(Hash, SignedAvailabilityBitfield), +} +``` + +### PoV Distribution V1 + +```rust +enum PoVDistributionV1Message { + /// Notification that we are awaiting the given PoVs (by hash) against a + /// specific relay-parent hash. + Awaiting(Hash, Vec), + /// Notification of an awaited PoV, in a given relay-parent context. + /// (`relay_parent`, `pov_hash`, `pov`) + SendPoV(Hash, Hash, PoV), +} +``` + +### Statement Distribution V1 + +```rust +enum StatementDistributionV1Message { + /// A signed full statement under a given relay-parent. + Statement(Hash, SignedFullStatement) +} +``` + +### Collator Protocol V1 + +```rust +enum CollatorProtocolV1Message { + /// Declare the intent to advertise collations under a collator ID and `Para`, attaching a + /// signature of the `PeerId` of the node using the given collator ID key. + Declare(CollatorId, ParaId, CollatorSignature), + /// Advertise a collation to a validator. Can only be sent once the peer has + /// declared that they are a collator with given ID. + AdvertiseCollation(Hash), + /// A collation sent to a validator was seconded. + CollationSeconded(SignedFullStatement), +} +``` + +## V1 Wire Protocols + +### Validation V1 + +These are the messages for the protocol on the validation peer-set. + +```rust +enum ValidationProtocolV1 { + ApprovalDistribution(ApprovalDistributionV1Message), + AvailabilityDistribution(AvailabilityDistributionV1Message), + AvailabilityRecovery(AvailabilityRecoveryV1Message), + BitfieldDistribution(BitfieldDistributionV1Message), + PoVDistribution(PoVDistributionV1Message), + StatementDistribution(StatementDistributionV1Message), +} +``` + +### Collation V1 + +These are the messages for the protocol on the collation peer-set + +```rust +enum CollationProtocolV1 { + CollatorProtocol(CollatorProtocolV1Message), +} +``` + +## Network Bridge Event + +These updates are posted from the [Network Bridge Subsystem](../node/utility/network-bridge.md) to other subsystems based on registered listeners. + +```rust +struct NewGossipTopology { + /// The session index this topology corresponds to. + session: SessionIndex, + /// The topology itself. + topology: SessionGridTopology, + /// The local validator index, if any. + local_index: Option, +} + +struct SessionGridTopology { + /// An array mapping validator indices to their indices in the + /// shuffling itself. This has the same size as the number of validators + /// in the session. + shuffled_indices: Vec, + /// The canonical shuffling of validators for the session. + canonical_shuffling: Vec, +} + +struct TopologyPeerInfo { + /// The validator's known peer IDs. + peer_ids: Vec, + /// The index of the validator in the discovery keys of the corresponding + /// `SessionInfo`. This can extend _beyond_ the set of active parachain validators. + validator_index: ValidatorIndex, + /// The authority discovery public key of the validator in the corresponding + /// `SessionInfo`. + discovery_id: AuthorityDiscoveryId, +} + +enum NetworkBridgeEvent { + /// A peer with given ID is now connected. + PeerConnected(PeerId, ObservedRole, ProtocolVersion, Option>), + /// A peer with given ID is now disconnected. + PeerDisconnected(PeerId), + /// Our neighbors in the new gossip topology. + /// We're not necessarily connected to all of them. + /// + /// This message is issued only on the validation peer set. + /// + /// Note, that the distribution subsystems need to handle the last + /// view update of the newly added gossip peers manually. + NewGossipTopology(NewGossipTopology), + /// We received a message from the given peer. + PeerMessage(PeerId, M), + /// The given peer has updated its description of its view. + PeerViewChange(PeerId, View), // guaranteed to come after peer connected event. + /// We have posted the given view update to all connected peers. + OurViewChange(View), +} +``` diff --git a/polkadot/roadmap/implementers-guide/src/types/overseer-protocol.md b/polkadot/roadmap/implementers-guide/src/types/overseer-protocol.md new file mode 100644 index 0000000000000000000000000000000000000000..3d9037699da6127de0af46a3e67d8b8e531f1f43 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/types/overseer-protocol.md @@ -0,0 +1,963 @@ +# Overseer Protocol + +This chapter contains message types sent to and from the overseer, and the underlying subsystem message types that are transmitted using these. + +## Overseer Signal + +Signals from the overseer to a subsystem to request change in execution that has to be obeyed by the subsystem. + +```rust +enum OverseerSignal { + /// Signal about a change in active leaves. + ActiveLeavesUpdate(ActiveLeavesUpdate), + /// Signal about a new best finalized block. + BlockFinalized(Hash), + /// Conclude all operation. + Conclude, +} +``` + +All subsystems have their own message types; all of them need to be able to listen for overseer signals as well. There are currently two proposals for how to handle that with unified communication channels: + +1. Retaining the `OverseerSignal` definition above, add `enum FromOrchestra {Signal(OverseerSignal), Message(T)}`. +1. Add a generic varint to `OverseerSignal`: `Message(T)`. + +Either way, there will be some top-level type encapsulating messages from the overseer to each subsystem. + +## Active Leaves Update + +Indicates a change in active leaves. Activated leaves should have jobs, whereas deactivated leaves should lead to winding-down of work based on those leaves. + +```rust +enum LeafStatus { + // A leaf is fresh when it's the first time the leaf has been encountered. + // Most leaves should be fresh. + Fresh, + // A leaf is stale when it's encountered for a subsequent time. This will + // happen when the chain is reverted or the fork-choice rule abandons some + // chain. + Stale, +} + +struct ActiveLeavesUpdate { + activated: [(Hash, Number, LeafStatus)], // in practice, these should probably be a SmallVec + deactivated: [Hash], +} +``` + +## All Messages + +A message type tying together all message types that are used across Subsystems. + +```rust +enum AllMessages { + CandidateValidation(CandidateValidationMessage), + CandidateBacking(CandidateBackingMessage), + ChainApi(ChainApiMessage), + CollatorProtocol(CollatorProtocolMessage), + StatementDistribution(StatementDistributionMessage), + AvailabilityDistribution(AvailabilityDistributionMessage), + AvailabilityRecovery(AvailabilityRecoveryMessage), + BitfieldDistribution(BitfieldDistributionMessage), + BitfieldSigning(BitfieldSigningMessage), + Provisioner(ProvisionerMessage), + RuntimeApi(RuntimeApiMessage), + AvailabilityStore(AvailabilityStoreMessage), + NetworkBridge(NetworkBridgeMessage), + CollationGeneration(CollationGenerationMessage), + ApprovalVoting(ApprovalVotingMessage), + ApprovalDistribution(ApprovalDistributionMessage), + GossipSupport(GossipSupportMessage), + DisputeCoordinator(DisputeCoordinatorMessage), + ChainSelection(ChainSelectionMessage), + PvfChecker(PvfCheckerMessage), +} +``` + +## Approval Voting Message + +Messages received by the approval voting subsystem. + +```rust +enum AssignmentCheckResult { + // The vote was accepted and should be propagated onwards. + Accepted, + // The vote was valid but duplicate and should not be propagated onwards. + AcceptedDuplicate, + // The vote was valid but too far in the future to accept right now. + TooFarInFuture, + // The vote was bad and should be ignored, reporting the peer who propagated it. + Bad(AssignmentCheckError), +} + +pub enum AssignmentCheckError { + UnknownBlock(Hash), + UnknownSessionIndex(SessionIndex), + InvalidCandidateIndex(CandidateIndex), + InvalidCandidate(CandidateIndex, CandidateHash), + InvalidCert(ValidatorIndex), + Internal(Hash, CandidateHash), +} + +enum ApprovalCheckResult { + // The vote was accepted and should be propagated onwards. + Accepted, + // The vote was bad and should be ignored, reporting the peer who propagated it. + Bad(ApprovalCheckError), +} + +pub enum ApprovalCheckError { + UnknownBlock(Hash), + UnknownSessionIndex(SessionIndex), + InvalidCandidateIndex(CandidateIndex), + InvalidValidatorIndex(ValidatorIndex), + InvalidCandidate(CandidateIndex, CandidateHash), + InvalidSignature(ValidatorIndex), + NoAssignment(ValidatorIndex), + Internal(Hash, CandidateHash), +} + +enum ApprovalVotingMessage { + /// Check if the assignment is valid and can be accepted by our view of the protocol. + /// Should not be sent unless the block hash is known. + CheckAndImportAssignment( + IndirectAssignmentCert, + CandidateIndex, // The index of the candidate included in the block. + ResponseChannel, + ), + /// Check if the approval vote is valid and can be accepted by our view of the + /// protocol. + /// + /// Should not be sent unless the block hash within the indirect vote is known. + CheckAndImportApproval( + IndirectSignedApprovalVote, + ResponseChannel, + ), + /// Returns the highest possible ancestor hash of the provided block hash which is + /// acceptable to vote on finality for. Along with that, return the lists of candidate hashes + /// which appear in every block from the (non-inclusive) base number up to (inclusive) the specified + /// approved ancestor. + /// This list starts from the highest block (the approved ancestor itself) and moves backwards + /// towards the base number. + /// + /// The base number is typically the number of the last finalized block, but in GRANDPA it is + /// possible for the base to be slightly higher than the last finalized block. + /// + /// The `BlockNumber` provided is the number of the block's ancestor which is the + /// earliest possible vote. + /// + /// It can also return the same block hash, if that is acceptable to vote upon. + /// Return `None` if the input hash is unrecognized. + ApprovedAncestor { + target_hash: Hash, + base_number: BlockNumber, + rx: ResponseChannel)>)>> + }, +} +``` + +## Approval Distribution Message + +Messages received by the approval distribution subsystem. + +```rust +/// Metadata about a block which is now live in the approval protocol. +struct BlockApprovalMeta { + /// The hash of the block. + hash: Hash, + /// The number of the block. + number: BlockNumber, + /// The candidates included by the block. Note that these are not the same as the candidates that appear within the + /// block body. + parent_hash: Hash, + /// The candidates included by the block. Note that these are not the same as the candidates that appear within the + /// block body. + candidates: Vec, + /// The consensus slot of the block. + slot: Slot, + /// The session of the block. + session: SessionIndex, +} + +enum ApprovalDistributionMessage { + /// Notify the `ApprovalDistribution` subsystem about new blocks and the candidates contained within + /// them. + NewBlocks(Vec), + /// Distribute an assignment cert from the local validator. The cert is assumed + /// to be valid, relevant, and for the given relay-parent and validator index. + /// + /// The `u32` param is the candidate index in the fully-included list. + DistributeAssignment(IndirectAssignmentCert, u32), + /// Distribute an approval vote for the local validator. The approval vote is assumed to be + /// valid, relevant, and the corresponding approval already issued. If not, the subsystem is free to drop + /// the message. + DistributeApproval(IndirectSignedApprovalVote), + /// An update from the network bridge. + NetworkBridgeUpdate(NetworkBridgeEvent), +} +``` + +## Availability Distribution Message + +Messages received by the availability distribution subsystem. + +This is a network protocol that receives messages of type [`AvailabilityDistributionV1Message`][AvailabilityDistributionV1NetworkMessage]. + +```rust +enum AvailabilityDistributionMessage { + /// Incoming network request for an availability chunk. + ChunkFetchingRequest(IncomingRequest), + /// Incoming network request for a seconded PoV. + PoVFetchingRequest(IncomingRequest), + /// Instruct availability distribution to fetch a remote PoV. + /// + /// NOTE: The result of this fetch is not yet locally validated and could be bogus. + FetchPoV { + /// The relay parent giving the necessary context. + relay_parent: Hash, + /// Validator to fetch the PoV from. + from_validator: ValidatorIndex, + /// Candidate hash to fetch the PoV for. + candidate_hash: CandidateHash, + /// Expected hash of the PoV, a PoV not matching this hash will be rejected. + pov_hash: Hash, + /// Sender for getting back the result of this fetch. + /// + /// The sender will be canceled if the fetching failed for some reason. + tx: oneshot::Sender, + }, +} +``` + +## Availability Recovery Message + +Messages received by the availability recovery subsystem. + +```rust +enum RecoveryError { + Invalid, + Unavailable, +} +enum AvailabilityRecoveryMessage { + /// Recover available data from validators on the network. + RecoverAvailableData( + CandidateReceipt, + SessionIndex, + Option, // Backing validator group to request the data directly from. + ResponseChannel>, + ), +} +``` + +## Availability Store Message + +Messages to and from the availability store. + +```rust +pub enum AvailabilityStoreMessage { + /// Query a `AvailableData` from the AV store. + QueryAvailableData(CandidateHash, oneshot::Sender>), + + /// Query whether a `AvailableData` exists within the AV Store. + /// + /// This is useful in cases when existence + /// matters, but we don't want to necessarily pass around multiple + /// megabytes of data to get a single bit of information. + QueryDataAvailability(CandidateHash, oneshot::Sender), + + /// Query an `ErasureChunk` from the AV store by the candidate hash and validator index. + QueryChunk(CandidateHash, ValidatorIndex, oneshot::Sender>), + + /// Get the size of an `ErasureChunk` from the AV store by the candidate hash. + QueryChunkSize(CandidateHash, oneshot::Sender>), + + /// Query all chunks that we have for the given candidate hash. + QueryAllChunks(CandidateHash, oneshot::Sender>), + + /// Query whether an `ErasureChunk` exists within the AV Store. + /// + /// This is useful in cases like bitfield signing, when existence + /// matters, but we don't want to necessarily pass around large + /// quantities of data to get a single bit of information. + QueryChunkAvailability(CandidateHash, ValidatorIndex, oneshot::Sender), + + /// Store an `ErasureChunk` in the AV store. + /// + /// Return `Ok(())` if the store operation succeeded, `Err(())` if it failed. + StoreChunk { + /// A hash of the candidate this chunk belongs to. + candidate_hash: CandidateHash, + /// The chunk itself. + chunk: ErasureChunk, + /// Sending side of the channel to send result to. + tx: oneshot::Sender>, + }, + + /// Computes and checks the erasure root of `AvailableData` before storing all of its chunks in + /// the AV store. + /// + /// Return `Ok(())` if the store operation succeeded, `Err(StoreAvailableData)` if it failed. + StoreAvailableData { + /// A hash of the candidate this `available_data` belongs to. + candidate_hash: CandidateHash, + /// The number of validators in the session. + n_validators: u32, + /// The `AvailableData` itself. + available_data: AvailableData, + /// Erasure root we expect to get after chunking. + expected_erasure_root: Hash, + /// Sending side of the channel to send result to. + tx: oneshot::Sender>, + }, +} + +/// The error result type of a [`AvailabilityStoreMessage::StoreAvailableData`] request. +pub enum StoreAvailableDataError { + InvalidErasureRoot, +} +``` + +## Bitfield Distribution Message + +Messages received by the bitfield distribution subsystem. +This is a network protocol that receives messages of type [`BitfieldDistributionV1Message`][BitfieldDistributionV1NetworkMessage]. + +```rust +enum BitfieldDistributionMessage { + /// Distribute a bitfield signed by a validator to other validators. + /// The bitfield distribution subsystem will assume this is indeed correctly signed. + DistributeBitfield(relay_parent, SignedAvailabilityBitfield), + /// Receive a network bridge update. + NetworkBridgeUpdate(NetworkBridgeEvent), +} +``` + +## Bitfield Signing Message + +Currently, the bitfield signing subsystem receives no specific messages. + +```rust +/// Non-instantiable message type +enum BitfieldSigningMessage { } +``` + +## Candidate Backing Message + +```rust +enum CandidateBackingMessage { + /// Requests a set of backable candidates attested by the subsystem. + /// + /// Each pair is (candidate_hash, candidate_relay_parent). + GetBackedCandidates(Vec<(CandidateHash, Hash)>, oneshot::Sender>), + /// Note that the Candidate Backing subsystem should second the given candidate in the context of the + /// given relay-parent (ref. by hash). This candidate must be validated using the provided PoV. + /// The PoV is expected to match the `pov_hash` in the descriptor. + Second(Hash, CandidateReceipt, PoV), + /// Note a peer validator's statement about a particular candidate. Disagreements about validity must be escalated + /// to a broader check by the Disputes Subsystem, though that escalation is deferred until the approval voting + /// stage to guarantee availability. Agreements are simply tallied until a quorum is reached. + Statement(Statement), +} +``` + +## Chain API Message + +The Chain API subsystem is responsible for providing an interface to chain data. + +```rust +enum ChainApiMessage { + /// Get the block number by hash. + /// Returns `None` if a block with the given hash is not present in the db. + BlockNumber(Hash, ResponseChannel, Error>>), + /// Request the block header by hash. + /// Returns `None` if a block with the given hash is not present in the db. + BlockHeader(Hash, ResponseChannel, Error>>), + /// Get the cumulative weight of the given block, by hash. + /// If the block or weight is unknown, this returns `None`. + /// + /// Weight is used for comparing blocks in a fork-choice rule. + BlockWeight(Hash, ResponseChannel, Error>>), + /// Get the finalized block hash by number. + /// Returns `None` if a block with the given number is not present in the db. + /// Note: the caller must ensure the block is finalized. + FinalizedBlockHash(BlockNumber, ResponseChannel, Error>>), + /// Get the last finalized block number. + /// This request always succeeds. + FinalizedBlockNumber(ResponseChannel>), + /// Request the `k` ancestors block hashes of a block with the given hash. + /// The response channel may return a `Vec` of size up to `k` + /// filled with ancestors hashes with the following order: + /// `parent`, `grandparent`, ... + Ancestors { + /// The hash of the block in question. + hash: Hash, + /// The number of ancestors to request. + k: usize, + /// The response channel. + response_channel: ResponseChannel, Error>>, + } +} +``` + +## Chain Selection Message + +Messages received by the [Chain Selection subsystem](../node/utility/chain-selection.md) + +```rust +enum ChainSelectionMessage { + /// Signal to the chain selection subsystem that a specific block has been approved. + Approved(Hash), + /// Request the leaves in descending order by score. + Leaves(ResponseChannel>), + /// Request the best leaf containing the given block in its ancestry. Return `None` if + /// there is no such leaf. + BestLeafContaining(Hash, ResponseChannel>), + +} +``` + +## Collator Protocol Message + +Messages received by the [Collator Protocol subsystem](../node/collators/collator-protocol.md) + +This is a network protocol that receives messages of type [`CollatorProtocolV1Message`][CollatorProtocolV1NetworkMessage]. + +```rust +enum CollatorProtocolMessage { + /// Signal to the collator protocol that it should connect to validators with the expectation + /// of collating on the given para. This is only expected to be called once, early on, if at all, + /// and only by the Collation Generation subsystem. As such, it will overwrite the value of + /// the previous signal. + /// + /// This should be sent before any `DistributeCollation` message. + CollateOn(ParaId), + /// Provide a collation to distribute to validators with an optional result sender. + /// + /// The result sender should be informed when at least one parachain validator seconded the collation. It is also + /// completely okay to just drop the sender. + DistributeCollation(CandidateReceipt, PoV, Option>), + /// Fetch a collation under the given relay-parent for the given ParaId. + FetchCollation(Hash, ParaId, ResponseChannel<(CandidateReceipt, PoV)>), + /// Report a collator as having provided an invalid collation. This should lead to disconnect + /// and blacklist of the collator. + ReportCollator(CollatorId), + /// Note a collator as having provided a good collation. + NoteGoodCollation(CollatorId, SignedFullStatement), + /// Notify a collator that its collation was seconded. + NotifyCollationSeconded(CollatorId, Hash, SignedFullStatement), +} +``` + +## Collation Generation Message + +Messages received by the [Collation Generation subsystem](../node/collators/collation-generation.md) + +This is the core interface by which collators built on top of a Polkadot node submit collations to validators. As such, these messages are not sent by any subsystem but are instead sent from outside of the overseer. + +```rust +/// A function provided to the subsystem which it uses to pull new collations. +/// +/// This mode of querying collations is obsoleted by `CollationGenerationMessages::SubmitCollation` +/// +/// The response channel, if present, is meant to receive a `Seconded` statement as a +/// form of authentication, for collation mechanisms which rely on this for anti-spam. +type CollatorFn = Fn(Hash, PersistedValidationData) -> Future>)>; + +/// Configuration for the collation generator +struct CollationGenerationConfig { + /// Collator's authentication key, so it can sign things. + key: CollatorPair, + /// Collation function. See [`CollatorFn`] for more details. + collator: CollatorFn, + /// The parachain that this collator collates for + para_id: ParaId, +} + +/// Parameters for submitting a collation +struct SubmitCollationParams { + /// The relay-parent the collation is built against. + relay_parent: Hash, + /// The collation itself (PoV and commitments) + collation: Collation, + /// The parent block's head-data. + parent_head: HeadData, + /// The hash of the validation code the collation was created against. + validation_code_hash: ValidationCodeHash, + /// A response channel for receiving a `Seconded` message about the candidate + /// once produced by a validator. This is not guaranteed to provide anything. + result_sender: Option>, +} + +enum CollationGenerationMessage { + /// Initialize the collation generation subsystem + Initialize(CollationGenerationConfig), + /// Submit a collation to the subsystem. This will package it into a signed + /// [`CommittedCandidateReceipt`] and distribute along the network to validators. + /// + /// If sent before `Initialize`, this will be ignored. + SubmitCollation(SubmitCollationParams), +} +``` + +## Dispute Coordinator Message + +Messages received by the [Dispute Coordinator subsystem](../node/disputes/dispute-coordinator.md) + +This subsystem coordinates participation in disputes, tracks live disputes, and observed statements of validators from subsystems. + +```rust +enum DisputeCoordinatorMessage { + /// Import a statement by a validator about a candidate. + /// + /// The subsystem will silently discard ancient statements or sets of only dispute-specific statements for + /// candidates that are previously unknown to the subsystem. The former is simply because ancient + /// data is not relevant and the latter is as a DoS prevention mechanism. Both backing and approval + /// statements already undergo anti-DoS procedures in their respective subsystems, but statements + /// cast specifically for disputes are not necessarily relevant to any candidate the system is + /// already aware of and thus present a DoS vector. Our expectation is that nodes will notify each + /// other of disputes over the network by providing (at least) 2 conflicting statements, of which one is either + /// a backing or validation statement. + /// + /// This does not do any checking of the message signature. + ImportStatements { + /// The hash of the candidate. + candidate_hash: CandidateHash, + /// The candidate receipt itself. + candidate_receipt: CandidateReceipt, + /// The session the candidate appears in. + session: SessionIndex, + /// Triples containing the following: + /// - A statement, either indicating validity or invalidity of the candidate. + /// - The validator index (within the session of the candidate) of the validator casting the vote. + /// - The signature of the validator casting the vote. + statements: Vec<(DisputeStatement, ValidatorIndex, ValidatorSignature)>, + + /// Inform the requester once we finished importing. + /// + /// This is, we either discarded the votes, just record them because we + /// casted our vote already or recovered availability for the candidate + /// successfully. + pending_confirmation: oneshot::Sender + }, + /// Fetch a list of all recent disputes that the co-ordinator is aware of. + /// These are disputes which have occurred any time in recent sessions, which may have already concluded. + RecentDisputes(ResponseChannel>), + /// Fetch a list of all active disputes that the co-ordinator is aware of. + /// These disputes are either unconcluded or recently concluded. + ActiveDisputes(ResponseChannel>), + /// Get candidate votes for a candidate. + QueryCandidateVotes(SessionIndex, CandidateHash, ResponseChannel>), + /// Sign and issue local dispute votes. A value of `true` indicates validity, and `false` invalidity. + IssueLocalStatement(SessionIndex, CandidateHash, CandidateReceipt, bool), + /// Determine the highest undisputed block within the given chain, based on where candidates + /// were included. If even the base block should not be finalized due to a dispute, + /// then `None` should be returned on the channel. + /// + /// The block descriptions begin counting upwards from the block after the given `base_number`. The `base_number` + /// is typically the number of the last finalized block but may be slightly higher. This block + /// is inevitably going to be finalized so it is not accounted for by this function. + DetermineUndisputedChain { + base_number: BlockNumber, + block_descriptions: Vec<(BlockHash, SessionIndex, Vec)>, + rx: ResponseSender>, + } +} + +/// Result of `ImportStatements`. +pub enum ImportStatementsResult { + /// Import was invalid (candidate was not available) and the sending peer should get banned. + InvalidImport, + /// Import was valid and can be confirmed to peer. + ValidImport +} +``` + + +## Dispute Distribution Message + +Messages received by the [Dispute Distribution +subsystem](../node/disputes/dispute-distribution.md). This subsystem is +responsible of distributing explicit dispute statements. + +```rust +enum DisputeDistributionMessage { + + /// Tell dispute distribution to distribute an explicit dispute statement to + /// validators. + SendDispute((ValidVote, InvalidVote)), + + /// Ask DisputeDistribution to get votes we don't know about. + /// Fetched votes will be reported via `DisputeCoordinatorMessage::ImportStatements` + FetchMissingVotes { + candidate_hash: CandidateHash, + session: SessionIndex, + known_valid_votes: Bitfield, + known_invalid_votes: Bitfield, + /// Optional validator to query from. `ValidatorIndex` as in the above + /// referenced session. + from_validator: Option, + } +} +``` + +## Network Bridge Message + +Messages received by the network bridge. This subsystem is invoked by others to manipulate access +to the low-level networking code. + +```rust +/// Peer-sets handled by the network bridge. +enum PeerSet { + /// The collation peer-set is used to distribute collations from collators to validators. + Collation, + /// The validation peer-set is used to distribute information relevant to parachain + /// validation among validators. This may include nodes which are not validators, + /// as some protocols on this peer-set are expected to be gossip. + Validation, +} + +enum NetworkBridgeMessage { + /// Report a cost or benefit of a peer. Negative values are costs, positive are benefits. + ReportPeer(PeerId, cost_benefit: i32), + /// Disconnect a peer from the given peer-set without affecting their reputation. + DisconnectPeer(PeerId, PeerSet), + /// Send a message to one or more peers on the validation peerset. + SendValidationMessage([PeerId], ValidationProtocolV1), + /// Send a message to one or more peers on the collation peerset. + SendCollationMessage([PeerId], ValidationProtocolV1), + /// Send multiple validation messages. + SendValidationMessages([([PeerId, ValidationProtocolV1])]), + /// Send multiple collation messages. + SendCollationMessages([([PeerId, ValidationProtocolV1])]), + /// Connect to peers who represent the given `validator_ids`. + /// + /// Also ask the network to stay connected to these peers at least + /// until a new request is issued. + /// + /// Because it overrides the previous request, it must be ensured + /// that `validator_ids` include all peers the subsystems + /// are interested in (per `PeerSet`). + /// + /// A caller can learn about validator connections by listening to the + /// `PeerConnected` events from the network bridge. + ConnectToValidators { + /// Ids of the validators to connect to. + validator_ids: HashSet, + /// The underlying protocol to use for this request. + peer_set: PeerSet, + /// Sends back the number of `AuthorityDiscoveryId`s which + /// authority discovery has failed to resolve. + failed: oneshot::Sender, + }, + /// Inform the distribution subsystems about the new + /// gossip network topology formed. + NewGossipTopology { + /// The session info this gossip topology is concerned with. + session: SessionIndex, + /// Our validator index in the session, if any. + local_index: Option, + /// The canonical shuffling of validators for the session. + canonical_shuffling: Vec<(AuthorityDiscoveryId, ValidatorIndex)>, + /// The reverse mapping of `canonical_shuffling`: from validator index + /// to the index in `canonical_shuffling` + shuffled_indices: Vec, + } +} +``` + +## Misbehavior Report + +```rust +pub type Misbehavior = generic::Misbehavior< + CommittedCandidateReceipt, + CandidateHash, + ValidatorIndex, + ValidatorSignature, +>; + +mod generic { + /// Misbehavior: voting more than one way on candidate validity. + /// + /// Since there are three possible ways to vote, a double vote is possible in + /// three possible combinations (unordered) + pub enum ValidityDoubleVote { + /// Implicit vote by issuing and explicitly voting validity. + IssuedAndValidity((Candidate, Signature), (Digest, Signature)), + /// Implicit vote by issuing and explicitly voting invalidity + IssuedAndInvalidity((Candidate, Signature), (Digest, Signature)), + /// Direct votes for validity and invalidity + ValidityAndInvalidity(Candidate, Signature, Signature), + } + + /// Misbehavior: multiple signatures on same statement. + pub enum DoubleSign { + /// On candidate. + Candidate(Candidate, Signature, Signature), + /// On validity. + Validity(Digest, Signature, Signature), + /// On invalidity. + Invalidity(Digest, Signature, Signature), + } + + /// Misbehavior: declaring multiple candidates. + pub struct MultipleCandidates { + /// The first candidate seen. + pub first: (Candidate, Signature), + /// The second candidate seen. + pub second: (Candidate, Signature), + } + + /// Misbehavior: submitted statement for wrong group. + pub struct UnauthorizedStatement { + /// A signed statement which was submitted without proper authority. + pub statement: SignedStatement, + } + + pub enum Misbehavior { + /// Voted invalid and valid on validity. + ValidityDoubleVote(ValidityDoubleVote), + /// Submitted multiple candidates. + MultipleCandidates(MultipleCandidates), + /// Submitted a message that was unauthorized. + UnauthorizedStatement(UnauthorizedStatement), + /// Submitted two valid signatures for the same message. + DoubleSign(DoubleSign), + } +} +``` + +## PoV Distribution Message + +This is a network protocol that receives messages of type [`PoVDistributionV1Message`][PoVDistributionV1NetworkMessage]. + +```rust +enum PoVDistributionMessage { + /// Fetch a PoV from the network. + /// + /// This `CandidateDescriptor` should correspond to a candidate seconded under the provided + /// relay-parent hash. + FetchPoV(Hash, CandidateDescriptor, ResponseChannel), + /// Distribute a PoV for the given relay-parent and CandidateDescriptor. + /// The PoV should correctly hash to the PoV hash mentioned in the CandidateDescriptor + DistributePoV(Hash, CandidateDescriptor, PoV), + /// An update from the network bridge. + NetworkBridgeUpdate(NetworkBridgeEvent), +} +``` + +## Provisioner Message + +```rust +/// This data becomes intrinsics or extrinsics which should be included in a future relay chain block. +enum ProvisionableData { + /// This bitfield indicates the availability of various candidate blocks. + Bitfield(Hash, SignedAvailabilityBitfield), + /// The Candidate Backing subsystem believes that this candidate is valid, pending availability. + BackedCandidate(CandidateReceipt), + /// Misbehavior reports are self-contained proofs of validator misbehavior. + MisbehaviorReport(Hash, MisbehaviorReport), + /// Disputes trigger a broad dispute resolution process. + Dispute(Hash, Signature), +} + +/// Message to the Provisioner. +/// +/// In all cases, the Hash is that of the relay parent. +enum ProvisionerMessage { + /// This message allows external subsystems to request current inherent data that could be used for + /// advancing the state of parachain consensus in a block building upon the given hash. + /// + /// If called at different points in time, this may give different results. + RequestInherentData(Hash, oneshot::Sender), + /// This data should become part of a relay chain block + ProvisionableData(ProvisionableData), +} +``` + +## Runtime API Message + +The Runtime API subsystem is responsible for providing an interface to the state of the chain's runtime. + +This is fueled by an auxiliary type encapsulating all request types defined in the [Runtime API section](../runtime-api) of the guide. + +```rust +enum RuntimeApiRequest { + /// Get the version of the runtime API at the given parent hash, if any. + Version(ResponseChannel), + /// Get the current validator set. + Validators(ResponseChannel>), + /// Get the validator groups and rotation info. + ValidatorGroups(ResponseChannel<(Vec>, GroupRotationInfo)>), + /// Get information about all availability cores. + AvailabilityCores(ResponseChannel>), + /// with the given occupied core assumption. + PersistedValidationData( + ParaId, + OccupiedCoreAssumption, + ResponseChannel>, + ), + /// Sends back `true` if the commitments pass all acceptance criteria checks. + CheckValidationOutputs( + ParaId, + CandidateCommitments, + RuntimeApiSender, + ), + /// Get the session index for children of the block. This can be used to construct a signing + /// context. + SessionIndexForChild(ResponseChannel), + /// Get the validation code for a specific para, using the given occupied core assumption. + ValidationCode(ParaId, OccupiedCoreAssumption, ResponseChannel>), + /// Get validation code by its hash, either past, current or future code can be returned, + /// as long as state is still available. + ValidationCodeByHash(ValidationCodeHash, RuntimeApiSender>), + /// Get a committed candidate receipt for all candidates pending availability. + CandidatePendingAvailability(ParaId, ResponseChannel>), + /// Get all events concerning candidates in the last block. + CandidateEvents(ResponseChannel>), + /// Get the session info for the given session, if stored. + SessionInfo(SessionIndex, ResponseChannel>), + /// Get all the pending inbound messages in the downward message queue for a para. + DmqContents(ParaId, ResponseChannel>>), + /// Get the contents of all channels addressed to the given recipient. Channels that have no + /// messages in them are also included. + InboundHrmpChannelsContents(ParaId, ResponseChannel>>>), + /// Get information about the BABE epoch this block was produced in. + BabeEpoch(ResponseChannel), +} + +enum RuntimeApiMessage { + /// Make a request of the runtime API against the post-state of the given relay-parent. + Request(Hash, RuntimeApiRequest), + /// Get the version of the runtime API at the given parent hash, if any. + Version(Hash, ResponseChannel>) +} +``` + +## Statement Distribution Message + +The Statement Distribution subsystem distributes signed statements and candidates from validators to other validators. It does this by distributing full statements, which embed the candidate receipt, as opposed to compact statements which don't. +It receives updates from the network bridge and signed statements to share with other validators. + +This is a network protocol that receives messages of type [`StatementDistributionV1Message`][StatementDistributionV1NetworkMessage]. + +```rust +enum StatementDistributionMessage { + /// An update from the network bridge. + NetworkBridgeUpdate(NetworkBridgeEvent), + /// We have validated a candidate and want to share our judgment with our peers. + /// The hash is the relay parent. + /// + /// The statement distribution subsystem assumes that the statement should be correctly + /// signed. + Share(Hash, SignedFullStatementWithPVD), +} +``` + +## Validation Request Type + +Various modules request that the [Candidate Validation subsystem](../node/utility/candidate-validation.md) validate a block with this message. It returns [`ValidationOutputs`](candidate.md#validationoutputs) for successful validation. + +```rust + +/// The outcome of the candidate-validation's PVF pre-check request. +pub enum PreCheckOutcome { + /// The PVF has been compiled successfully within the given constraints. + Valid, + /// The PVF could not be compiled. This variant is used when the candidate-validation subsystem + /// can be sure that the PVF is invalid. To give a couple of examples: a PVF that cannot be + /// decompressed or that does not represent a structurally valid WebAssembly file. + Invalid, + /// This variant is used when the PVF cannot be compiled but for other reasons that are not + /// included into [`PreCheckOutcome::Invalid`]. This variant can indicate that the PVF in + /// question is invalid, however it is not necessary that PVF that received this judgement + /// is invalid. + /// + /// For example, if during compilation the preparation worker was killed we cannot be sure why + /// it happened: because the PVF was malicious made the worker to use too much memory or its + /// because the host machine is under severe memory pressure and it decided to kill the worker. + Failed, +} + +/// Result of the validation of the candidate. +enum ValidationResult { + /// Candidate is valid, and here are the outputs and the validation data used to form inputs. + /// In practice, this should be a shared type so that validation caching can be done. + Valid(CandidateCommitments, PersistedValidationData), + /// Candidate is invalid. + Invalid, +} + +const BACKING_EXECUTION_TIMEOUT: Duration = 2 seconds; +const APPROVAL_EXECUTION_TIMEOUT: Duration = 6 seconds; + +/// Messages received by the Validation subsystem. +/// +/// ## Validation Requests +/// +/// Validation requests made to the subsystem should return an error only on internal error. +/// Otherwise, they should return either `Ok(ValidationResult::Valid(_))` +/// or `Ok(ValidationResult::Invalid)`. +#[derive(Debug)] +pub enum CandidateValidationMessage { + /// Validate a candidate with provided parameters using relay-chain state. + /// + /// This will implicitly attempt to gather the `PersistedValidationData` and `ValidationCode` + /// from the runtime API of the chain, based on the `relay_parent` + /// of the `CandidateDescriptor`. + /// + /// This will also perform checking of validation outputs against the acceptance criteria. + /// + /// If there is no state available which can provide this data or the core for + /// the para is not free at the relay-parent, an error is returned. + ValidateFromChainState( + CandidateDescriptor, + Arc, + Duration, // Execution timeout. + oneshot::Sender>, + ), + /// Validate a candidate with provided, exhaustive parameters for validation. + /// + /// Explicitly provide the `PersistedValidationData` and `ValidationCode` so this can do full + /// validation without needing to access the state of the relay-chain. + /// + /// This request doesn't involve acceptance criteria checking, therefore only useful for the + /// cases where the validity of the candidate is established. This is the case for the typical + /// use-case: approval checkers would use this request relying on the full prior checks + /// performed by the relay-chain. + ValidateFromExhaustive( + PersistedValidationData, + ValidationCode, + CandidateDescriptor, + Arc, + Duration, // Execution timeout. + oneshot::Sender>, + ), + /// Try to compile the given validation code and send back + /// the outcome. + /// + /// The validation code is specified by the hash and will be queried from the runtime API at the + /// given relay-parent. + PreCheck( + // Relay-parent + Hash, + ValidationCodeHash, + oneshot::Sender, + ), +} +``` + +## PVF Pre-checker Message + +Currently, the PVF pre-checker subsystem receives no specific messages. + +```rust +/// Non-instantiable message type +pub enum PvfCheckerMessage { } +``` + +[NBE]: ../network.md#network-bridge-event +[AvailabilityDistributionV1NetworkMessage]: network.md#availability-distribution-v1 +[BitfieldDistributionV1NetworkMessage]: network.md#bitfield-distribution-v1 +[PoVDistributionV1NetworkMessage]: network.md#pov-distribution-v1 +[StatementDistributionV1NetworkMessage]: network.md#statement-distribution-v1 +[CollatorProtocolV1NetworkMessage]: network.md#collator-protocol-v1 diff --git a/polkadot/roadmap/implementers-guide/src/types/pvf-prechecking.md b/polkadot/roadmap/implementers-guide/src/types/pvf-prechecking.md new file mode 100644 index 0000000000000000000000000000000000000000..f68f1e60feee6c2e23eca0bee4488a51ba0ae2ec --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/types/pvf-prechecking.md @@ -0,0 +1,24 @@ +# PVF Pre-checking types + +## `PvfCheckStatement` + +> ⚠️ This type was added in v2. + +One of the main units of information on which PVF pre-checking voting is build is the `PvfCheckStatement`. + +This is a statement by the validator who ran the pre-checking process for a PVF. A PVF is identified by the `ValidationCodeHash`. + +The statement is valid only during a single session, specified in the `session_index`. + +```rust +struct PvfCheckStatement { + /// `true` if the subject passed pre-checking and `false` otherwise. + pub accept: bool, + /// The validation code hash that was checked. + pub subject: ValidationCodeHash, + /// The index of a session during which this statement is considered valid. + pub session_index: SessionIndex, + /// The index of the validator from which this statement originates. + pub validator_index: ValidatorIndex, +} +``` diff --git a/polkadot/roadmap/implementers-guide/src/types/runtime.md b/polkadot/roadmap/implementers-guide/src/types/runtime.md new file mode 100644 index 0000000000000000000000000000000000000000..79da899bd35eae6afff6dd8e6fb53bf670f2c4a2 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/types/runtime.md @@ -0,0 +1,125 @@ +# Runtime + +Types used within the runtime exclusively and pervasively. + +## Host Configuration + +The internal-to-runtime configuration of the parachain host. This is expected to be altered only by governance procedures. + +```rust +struct HostConfiguration { + /// The minimum period, in blocks, between which parachains can update their validation code. + pub validation_upgrade_cooldown: BlockNumber, + /// The delay, in blocks, before a validation upgrade is applied. + pub validation_upgrade_delay: BlockNumber, + /// How long to keep code on-chain, in blocks. This should be sufficiently long that disputes + /// have concluded. + pub code_retention_period: BlockNumber, + /// The maximum validation code size, in bytes. + pub max_code_size: u32, + /// The maximum head-data size, in bytes. + pub max_head_data_size: u32, + /// The amount of availability cores to dedicate to parathreads (on-demand parachains). + pub parathread_cores: u32, + /// The number of retries that a parathread (on-demand parachain) author has to submit their block. + pub parathread_retries: u32, + /// How often parachain groups should be rotated across parachains. + pub group_rotation_frequency: BlockNumber, + /// The availability period, in blocks, for parachains. This is the amount of blocks + /// after inclusion that validators have to make the block available and signal its availability to + /// the chain. Must be at least 1. + pub chain_availability_period: BlockNumber, + /// The availability period, in blocks, for parathreads (on-demand parachains). Same as the `chain_availability_period`, + /// but a differing timeout due to differing requirements. Must be at least 1. + pub thread_availability_period: BlockNumber, + /// The amount of blocks ahead to schedule on-demand parachains. + pub scheduling_lookahead: u32, + /// The maximum number of validators to have per core. `None` means no maximum. + pub max_validators_per_core: Option, + /// The maximum number of validators to use for parachains, in total. `None` means no maximum. + pub max_validators: Option, + /// The amount of sessions to keep for disputes. + pub dispute_period: SessionIndex, + /// How long after dispute conclusion to accept statements. + pub dispute_post_conclusion_acceptance_period: BlockNumber, + /// The maximum number of dispute spam slots + pub dispute_max_spam_slots: u32, + /// The amount of consensus slots that must pass between submitting an assignment and + /// submitting an approval vote before a validator is considered a no-show. + /// Must be at least 1. + pub no_show_slots: u32, + /// The number of delay tranches in total. + pub n_delay_tranches: u32, + /// The width of the zeroth delay tranche for approval assignments. This many delay tranches + /// beyond 0 are all consolidated to form a wide 0 tranche. + pub zeroth_delay_tranche_width: u32, + /// The number of validators needed to approve a block. + pub needed_approvals: u32, + /// The number of samples to do of the RelayVRFModulo approval assignment criterion. + pub relay_vrf_modulo_samples: u32, + /// Total number of individual messages allowed in the parachain -> relay-chain message queue. + pub max_upward_queue_count: u32, + /// Total size of messages allowed in the parachain -> relay-chain message queue before which + /// no further messages may be added to it. If it exceeds this then the queue may contain only + /// a single message. + pub max_upward_queue_size: u32, + /// The maximum size of an upward message that can be sent by a candidate. + /// + /// This parameter affects the upper bound of size of `CandidateCommitments`. + pub max_upward_message_size: u32, + /// The maximum number of messages that a candidate can contain. + /// + /// This parameter affects the upper bound of size of `CandidateCommitments`. + pub max_upward_message_num_per_candidate: u32, + /// The maximum size of a message that can be put in a downward message queue. + /// + /// Since we require receiving at least one DMP message the obvious upper bound of the size is + /// the PoV size. Of course, there is a lot of other different things that a parachain may + /// decide to do with its PoV so this value in practice will be picked as a fraction of the PoV + /// size. + pub max_downward_message_size: u32, + /// The deposit that the sender should provide for opening an HRMP channel. + pub hrmp_sender_deposit: u32, + /// The deposit that the recipient should provide for accepting opening an HRMP channel. + pub hrmp_recipient_deposit: u32, + /// The maximum number of messages allowed in an HRMP channel at once. + pub hrmp_channel_max_capacity: u32, + /// The maximum total size of messages in bytes allowed in an HRMP channel at once. + pub hrmp_channel_max_total_size: u32, + /// The maximum number of inbound HRMP channels a parachain is allowed to accept. + pub hrmp_max_parachain_inbound_channels: u32, + /// The maximum number of inbound HRMP channels a parathread (on-demand parachain) is allowed to accept. + pub hrmp_max_parathread_inbound_channels: u32, + /// The maximum size of a message that could ever be put into an HRMP channel. + /// + /// This parameter affects the upper bound of size of `CandidateCommitments`. + pub hrmp_channel_max_message_size: u32, + /// The maximum number of outbound HRMP channels a parachain is allowed to open. + pub hrmp_max_parachain_outbound_channels: u32, + /// The maximum number of outbound HRMP channels a parathread (on-demand parachain) is allowed to open. + pub hrmp_max_parathread_outbound_channels: u32, + /// The maximum number of outbound HRMP messages can be sent by a candidate. + /// + /// This parameter affects the upper bound of size of `CandidateCommitments`. + pub hrmp_max_message_num_per_candidate: u32, +} +``` + +## ParaInherentData + +Inherent data passed to a runtime entry-point for the advancement of parachain consensus. + +This contains 4 pieces of data: +1. [`Bitfields`](availability.md#signed-availability-bitfield) +2. [`BackedCandidates`](backing.md#backed-candidate) +3. [`MultiDisputeStatementSet`](disputes.md#multidisputestatementset) +4. `Header` + +```rust +struct ParaInherentData { + bitfields: Bitfields, + backed_candidates: BackedCandidates, + dispute_statements: MultiDisputeStatementSet, + parent_header: Header +} +``` diff --git a/polkadot/roadmap/implementers-guide/src/whence-parachains.md b/polkadot/roadmap/implementers-guide/src/whence-parachains.md new file mode 100644 index 0000000000000000000000000000000000000000..41842e93943b41699a6ddb06ee5589a9c1e713c5 --- /dev/null +++ b/polkadot/roadmap/implementers-guide/src/whence-parachains.md @@ -0,0 +1,29 @@ +# Whence Parachains + +Parachains are the solution to a problem. As with any solution, it cannot be understood without first understanding the problem. So let's start by going over the issues faced by blockchain technology that led to us beginning to explore the design space for something like parachains. + +## Issue 1: Scalability + +It became clear a few years ago that the transaction throughput of simple Proof-of-Work (PoW) blockchains such as Bitcoin, Ethereum, and myriad others was simply too low. + +> TODO: what if there were more blockchains, etc. + +Proof-of-Stake (PoS) systems can accomplish higher throughput than PoW blockchains. PoS systems are secured by bonded capital as opposed to spent effort - liquidity opportunity cost vs. burning electricity. The way they work is by selecting a set of validators with known economic identity who lock up tokens in exchange for earning the right to "validate" or participate in the consensus process. If they are found to carry out that process wrongly, they will be slashed, meaning some or all of the locked tokens will be burned. This provides a strong disincentive in the direction of misbehavior. + +Since the consensus protocol doesn't revolve around wasting effort, block times and agreement can occur much faster. Solutions to PoW challenges don't have to be found before a block can be authored, so the overhead of authoring a block is reduced to only the costs of creating and distributing the block. + +However, consensus on a PoS chain requires full agreement of 2/3+ of the validator set for everything that occurs at Layer 1: all logic which is carried out as part of the blockchain's state machine. This means that everybody still needs to check everything. Furthermore, validators may have different views of the system based on the information that they receive over an asynchronous network, making agreement on the latest state more difficult. + +Parachains are an example of a **sharded** protocol. Sharding is a concept borrowed from traditional database architecture. Rather than requiring every participant to check every transaction, we require each participant to check some subset of transactions, with enough redundancy baked in that byzantine (arbitrarily malicious) participants can't sneak in invalid transactions - at least not without being detected and getting slashed, with those transactions reverted. + +Sharding and Proof-of-Stake in coordination with each other allow a parachain host to provide full security on many parachains, even without all participants checking all state transitions. + +> TODO: note about network effects & bridging + +## Issue 2: Flexibility / Specialization + +"dumb" VMs don't give you the flexibility. Any engineer knows that being able to specialize on a problem gives them and their users more _leverage_. + +> TODO: expand on leverage + +Having recognized these issues, we set out to find a solution to these problems, which could allow developers to create and deploy purpose-built blockchains unified under a common source of security, with the capability of message-passing between them; a _heterogeneous sharding solution_, which we have come to know as **Parachains**. diff --git a/polkadot/roadmap/parachains.md b/polkadot/roadmap/parachains.md new file mode 100644 index 0000000000000000000000000000000000000000..9d6c014a1c7c48e88c274998f1e7fae0aff904d3 --- /dev/null +++ b/polkadot/roadmap/parachains.md @@ -0,0 +1,233 @@ +# Parachains Roadmap +This is a roadmap for the core technology underlying Parachains - what protocols, APIs, and code paths need to be in place to fully instantiate a self-sufficient and secure parachain. We don't attempt to cover anything on what APIs a parachain toolkit might expose in order to make use of parachain features - only how those features are implemented and the low-level APIs that they expose to the validation function, if any. + +## Categories +We will use these categories to delineate features: + +*Runtime*: Runtime code for the Relay chain specifying consensus-critical state and updates that all full nodes must maintain or perform. + +*Networking*: Protocols for nodes to speak to each other and transmit information across the network. + +*Node*: State or updates that must be maintained or performed by some or all nodes off-chain. Often interfaces with networking components, and references runtime state. + +--- +## Sub-projects and features: +This section contains various sub-projects and the features that make them up. + +### Infrastructure/API + +#### *Peer Set Management* + +Category: Networking + +Validators assigned to a parachain need a way to discover and connect to collators in order to get fresh parachain blocks to validate. + +Collators need to discover and connect to validators in order to submit parachain blocks. + +Fishermen need to talk to validators and collators to fetch available data and circulate reports. + +Some connections are long-lived, some are just for a single request. + +#### Custom libp2p sub-protocols + +Polkadot parachains involve many distinct networking protocols. Ideally, we'd be able to spawn each of these as a separate futures task which communicates via channel with other protocols or node code as necessary. This requires changes in Substrate and libp2p. + +--- +### Assignment + +#### *Auctions* + +Category: Runtime + +Auctioning and registration of parachains. This is already implemented and follows the [Parachain Allocation — Research at W3F](https://research.web3.foundation/en/latest/polkadot/Parachain-Allocation.html) document. + +#### *On-demand Blockspace Purchase* + +Category: Runtime + +The blockspace purchasing system for on-demand parachains consists of an on-chain mechanism for resolving block space purchases by collators and ensuring that they author a block. + +The node-side portion of on-demand parachains is for collators to actually purchase blockspace and to configure the conditions in which purchases are made. + +#### *Validator Assignment* + +Category: Runtime + +Assignment of validators to parachains. Validators are only assigned to parachains for a short period of time. Tweakable parameters include length of time assigned to each parachain and length of time in advance that the network is aware of validators' assignments. + +--- +### Agreement + +#### *Attestation Circulation* + +Category: Networking + +A black-box networking component for circulating attestation messages (`Candidate`, `Valid`, `Invalid`) between validators of any given parachain to create a quorum on which blocks can be included. + +#### *Availability Erasure-coding* + +Category: Node, Networking + +For each potential, considered parachain block, perform an erasure-coding of the PoV and outgoing messages of the block. Call the number of validators on the relay chain for the Relay-chain block this parachain block is being considered for inclusion in `n`. Erasure-code into `n` pieces, where any `f + 1` can recover (`f` being the maximum number of tolerated faulty nodes = ~ `n / 3`). The `i'th` validator stores the `i'th` piece of the coding and provides it to any who ask. + +#### *PoV block fetching* + +Category: Networking + +A black-box networking component for validators or fishermen on a parachain to obtain the PoV block referenced by hash in an attestation, for the purpose of validating. When fetching "current" PoV blocks (close to the head of the chain, or relating to the block currently being built), this should be fast. When fetching "old" PoV blocks, it should be possible and fall back on recovering from the availability erasure-coding. + +#### *On-demand Blockspace Purchase* + +Category: Node, Networking + +How and when collators are configured to purchase on-demand blockspace. + +#### *Collation Loop* + +Category: Node, Networking + +The main event loop of a collator node: + 1. new relay chain block B + 2. sync new parachain head P w.r.t. B + 3. build new child of P + 4. submit to validators + +--- +### Cross-chain Messaging + +https://hackmd.io/ILoQltEISP697oMYe4HbrA?view +https://github.com/paritytech/polkadot/issues/597 + +The biggest sub-project of the parachains roadmap - how messages are sent between parachains. This involves the state-machine ordering of incoming messages, protocols for fetching those messages, and node logic for persisting the messages. + +This is designed around a concept of unidirectional _channels_ between paras, which consist of a sender and receiver. At each relay chain block, each para has an opportunity to send a message on each channel for which it controls the sending half. It will also attempt to process messages on each receiving half of the channel which it controls _in order_: messages sent at block height `b` must be processed before those sent at block height `b+1`. For messages on different channels sent at the same block height, there will be some well-defined order in which they should be processed. + +This means that a receiving para will have a maximum height differential of `1` in terms of the most recently processed message's send-height across all of the channels it is receiving on. The minimum processed send-height of a receiving para is known as its _watermark_. All messages on all channels sending to this para before or at the watermark have been processed. + +#### *Finalize CandidateReceipt format* + +Category: Runtime / Node + +The `CandidateReceipt` is the wrapper around a parablock header which is submitted to the runtime. It contains cryptographic commitments to data which is important for validation or interpretation of the parablock, including the hash of the witness data and outgoing message data. + +The `CandidateReceipt` format should be finalized in accordance to the XCMP writeups linked above - most importantly, to be altered to hold `bitfield` and `message_root` fields which cryptographically commit to the state of each open channel. + +#### *Finalize PovBlock format* + +Category: Runtime / Node + +The `PovBlock` or `Proof-of-Validity` block contains all the data you need to validate a parablock. It will need to contain incoming message queues and potentially outgoing ones as well. + +#### *CST Update Procedure* + +Category: Runtime + +Storage definitions and update logic of the Channel State Table (CST) based on the supplied `CandidateReceipt`s in a relay chain block. + +#### *CST Entry Proof Generation and Checking* + +Category: Node + +Means for full nodes of the relay chain to generate proofs of items in the CST and for light clients or pruned nodes to check those proofs. + +#### *MQC Storage and Distribution Protocol* + +Category: Node + +Every channel's state is described by a Message Queue Chain (MQC) which is a hash-chain, where the links are defined by `(M, b, H)`: the message most recently sent, the block height at which the prior message was sent, and the hash of the prior link. + +It is the responsibility of the full nodes of the _sending_ para to maintain all links of the MQC up to and including the link where `b` is less than the watermark of the _receiving_ para. + +Full nodes of the para will be aware of the head of all MQCs for its channels because they are produced by execution of the block. This will take collaboration with the Cumulus team (https://github.com/paritytech/cumulus) on APIs. + +We will need a network where collators of paras can discover and fetch the relevant portion of the MQC incoming from all channels. + +#### *Channel Registrar and Economics* + +Category: Runtime + +Runtime logic for paras to open and close channels by putting down a deposit. The amount of channels an on-demand parachain can open will be limited. Channels that are pending close should remain open until the watermark of the recipient has reached the block height of the close request. + +--- +### Fishing/Slashing + +#### *Validity/Availability Report Handler* + +Category: Runtime + +In Polkadot, a bad parachain group can force inclusion of an invalid or unavailable parachain block. It is the job of fishermen to detect those blocks and report them to the runtime. This item is about the report handler + +The W3F-research writeup on availability/validity provides a high-level view of the dispute resolution process: [Availability and Validity — Research at W3F](https://research.web3.foundation/en/latest/polkadot/Availability_and_Validity.html) + +One of the main behaviors that is unimplemented and needs to be is the _rollback_ that occurs when the dispute resolution process concludes that an error has been made. When we mark a parachain block as having been invalid or unavailable, we need to roll back all parachains to a point from just before this state. We would also need to roll back relay chain state, because there may have been messages from a parachain to a relay chain that now need to be rolled back. The easiest thing to do would be to side-step that by putting a delay on upwards messages, but this would impact the UX of parachain participation in slot auctions, council votes, etc. considerably. Assuming we can't side-step this, we will have to find a way to roll back selected state of the relay chain. + +#### *Double-vote Slash Handler* + +Category: Runtime + +In the attestation process, validators may submit only one `Candidate` message for a given relay chain block. If issuing a `Candidate` message on a parachain block, neither a `Valid` or `Invalid` vote cannot be issued on that parachain block, as the `Candidate` message is an implicit validity vote. Otherwise, it is illegal to cast both a `Valid` and `Invalid` vote on a given parachain block. + +Runtime handlers that take two conflicting votes as arguments and slash the offender are needed. + +#### *Validity/Availability Fishing* + +Category: Node + +This code-path is also taken by validators who self-select based on VRF [Availability and Validity — Research at W3F](https://research.web3.foundation/en/latest/polkadot/Availability_and_Validity.html). Validators and fishermen will select parachain blocks to re-validate. In these steps: +* Attempt to recover the PoV block, falling back on the erasure-coding. If not available, issue report. +* Attempt to validate the PoV block. If invalid, issue report. + +#### *Double-vote Fishing* + +Category: Node + +Nodes that observe a double-vote in the attestation process should submit a report to the chain to trigger slashing. + +--- + +# Phases +This roadmap is divided up into phases, where each represents another set of deliverables or iteration on a black-box component with respect to the prior phase. + +## Phase 0: MVP +The very first phase - this is parachains without slashing (full security) or cross-chain messaging. It is primarily a PoC that registration and validation are working correctly. + +### Infrastructure/API: + - Custom libp2p sub-protocols + - Peer Set Management + +### Assignment: + - Auctions + - On-demand Blockspace purchase + - Validator Assignment + +### Agreement: + - Attestation Circulation (black box: gossip) + - Availability Erasure-coding (black box: gossip) + - PoV block fetching (black box: gossip) + - Collation Loop + +### Cross-chain Messaging: + - Finalize `CandidateReceipt` format + +## Phase 1: Fishing and Slashing + +This phase marks advancement in the security of parachains. Once completed, parachains are a full-fledged cryptoeconomically secure rollup primitive. This phase also includes implementation work on XCMP, but does not enable it fully. + +### Agreement + - Availability Erasure-coding (black box: targeted distribution) + - PoV block fetching (black box: targeted distribution and fetching) + +### Fishing/Slashing + - Validity/Availability Report Handler + - Double-vote Slash Handler + - Validity/Availability Fishing + - Double-vote Fishing + +### Cross-chain Messaging: + - Finalize `PoVBlock` format. + +## Phase 2: Messaging + +This phase marks delivery of cross-chain messaging. + +Pretty much everything left from the XCMP section. diff --git a/polkadot/roadmap/phase-1.png b/polkadot/roadmap/phase-1.png new file mode 100644 index 0000000000000000000000000000000000000000..d6d272aefb09c1b78c8cd413bda31b0691498a5c Binary files /dev/null and b/polkadot/roadmap/phase-1.png differ diff --git a/polkadot/roadmap/phase-1.toml b/polkadot/roadmap/phase-1.toml new file mode 100644 index 0000000000000000000000000000000000000000..50ef1f741fe9d448a29e9a4018746305b3fb2586 --- /dev/null +++ b/polkadot/roadmap/phase-1.toml @@ -0,0 +1,64 @@ +# Phase 0 + +[[group]] +name = "phase-0" +label = "Phase 0: MVP" +items = [] + +# Phase 1 + +[[group]] +name = "two-phase-inclusion" +label = "Two-phase inclusion of parachain candidates" +requires = ["phase-0"] +items = [ + { label = "Buffer submitted parachain candidate until considered available." }, + { label = "Validators submit signed bitfields re: availability of parachains" }, + { label = "relay chain fully includes candidate once considered available" } +] + +[[group]] +name = "secondary-checking" +label = "Secondary checks and self-selection by validators" +requires = ["two-phase-inclusion"] +items = [ + { label = "Extract #VCheck for all checkable candidates" }, + { label = "Maintain a frontier of candidates that are likely to be checked soon" }, + { label = "Listen for new reports on candidates and new checks to update frontier" }, +] + +[[group]] +name = "runtime-availability-validity-slashing" +label = "Availability and Validity slashing in the runtime" +requires = ["two-phase-inclusion"] +items = [ + { label = "Track all candidates within the slash period as well as their session" }, + { label = "Submit secondary checks to runtime", port = "submitsecondary", requires = ["secondary-checking"]}, + { label = "Track reports and attestatations for candidates" }, +] + +[[group]] +name = "non-direct-ancestor" +label = "Allow candidates with non-direct ancestor" +items = [ + { label = "Extend GlobalValidationData with random seed and session index"}, + { label = "Block author can provide minimally-attested candidate with older relay parent" }, + { label = "Runtime can accept and process candidates with older relay-parent" }, + { label = "Revise availability-store pruning to ensure only needed data is kept" }, +] + +[[group]] +name = "grandpa-voting-rule" +label = "GRANDPA voting rule to follow valid/available chains" +requires = ["runtime-availability-validity-slashing"] +items = [ + { label = "Add a utility to flag a block and all of its ancestors as abandoned" }, + { label = "Accept new blocks on abandoned but mark them abandoned as well." }, + { label = "Do not vote or build on abandoned chains" }, +] + +[[group]] +name = "phase-1" +label = "Phase 1: Availability and Validity" +requires = ["non-direct-ancestor", "grandpa-voting-rule", "runtime-availability-validity-slashing"] +items = [] diff --git a/polkadot/roadmap/render.sh b/polkadot/roadmap/render.sh new file mode 100644 index 0000000000000000000000000000000000000000..a54384bac459a47187a14fc5fe31e03d336ab3c8 --- /dev/null +++ b/polkadot/roadmap/render.sh @@ -0,0 +1,11 @@ +# requires skill-tree: github.com/nikomatsakis/skill-tree + +render () { + echo "Rendering $1" + skill-tree $1.toml output + python3 -c "from graphviz import render; render('dot', 'png', 'output/skill-tree.dot')" + mv output/skill-tree.dot.png "$1.png" + rm -rf output +} + +render phase-1 diff --git a/polkadot/rpc/Cargo.toml b/polkadot/rpc/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..18913718676c822bc795527dc90a455bc7267923 --- /dev/null +++ b/polkadot/rpc/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "polkadot-rpc" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +jsonrpsee = { version = "0.16.2", features = ["server"] } +polkadot-primitives = { path = "../primitives" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus-babe-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus-beefy = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus-beefy-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus-epochs = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus-grandpa-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-sync-state-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +txpool-api = { package = "sc-transaction-pool-api", git = "https://github.com/paritytech/substrate", branch = "master" } +frame-rpc-system = { package = "substrate-frame-rpc-system", git = "https://github.com/paritytech/substrate", branch = "master" } +mmr-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-state-trie-migration-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/polkadot/rpc/src/lib.rs b/polkadot/rpc/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..bf9daddba505e9f9bd61bdf74429ef8654101d8d --- /dev/null +++ b/polkadot/rpc/src/lib.rs @@ -0,0 +1,177 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot-specific RPCs implementation. + +#![warn(missing_docs)] + +use std::sync::Arc; + +use jsonrpsee::RpcModule; +use polkadot_primitives::{AccountId, Balance, Block, BlockNumber, Hash, Nonce}; +use sc_client_api::AuxStore; +use sc_consensus_beefy::communication::notification::{ + BeefyBestBlockStream, BeefyVersionedFinalityProofStream, +}; +use sc_consensus_grandpa::FinalityProofProvider; +pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor}; +use sp_api::ProvideRuntimeApi; +use sp_block_builder::BlockBuilder; +use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; +use sp_consensus::SelectChain; +use sp_consensus_babe::BabeApi; +use sp_keystore::KeystorePtr; +use txpool_api::TransactionPool; + +/// A type representing all RPC extensions. +pub type RpcExtension = RpcModule<()>; + +/// Extra dependencies for BABE. +pub struct BabeDeps { + /// A handle to the BABE worker for issuing requests. + pub babe_worker_handle: sc_consensus_babe::BabeWorkerHandle, + /// The keystore that manages the keys of the node. + pub keystore: KeystorePtr, +} + +/// Dependencies for GRANDPA +pub struct GrandpaDeps { + /// Voting round info. + pub shared_voter_state: sc_consensus_grandpa::SharedVoterState, + /// Authority set info. + pub shared_authority_set: sc_consensus_grandpa::SharedAuthoritySet, + /// Receives notifications about justification events from Grandpa. + pub justification_stream: sc_consensus_grandpa::GrandpaJustificationStream, + /// Executor to drive the subscription manager in the Grandpa RPC handler. + pub subscription_executor: sc_rpc::SubscriptionTaskExecutor, + /// Finality proof provider. + pub finality_provider: Arc>, +} + +/// Dependencies for BEEFY +pub struct BeefyDeps { + /// Receives notifications about finality proof events from BEEFY. + pub beefy_finality_proof_stream: BeefyVersionedFinalityProofStream, + /// Receives notifications about best block events from BEEFY. + pub beefy_best_block_stream: BeefyBestBlockStream, + /// Executor to drive the subscription manager in the BEEFY RPC handler. + pub subscription_executor: sc_rpc::SubscriptionTaskExecutor, +} + +/// Full client dependencies +pub struct FullDeps { + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, + /// The [`SelectChain`] Strategy + pub select_chain: SC, + /// A copy of the chain spec. + pub chain_spec: Box, + /// Whether to deny unsafe calls + pub deny_unsafe: DenyUnsafe, + /// BABE specific dependencies. + pub babe: BabeDeps, + /// GRANDPA specific dependencies. + pub grandpa: GrandpaDeps, + /// BEEFY specific dependencies. + pub beefy: BeefyDeps, + /// Backend used by the node. + pub backend: Arc, +} + +/// Instantiate all RPC extensions. +pub fn create_full( + FullDeps { client, pool, select_chain, chain_spec, deny_unsafe, babe, grandpa, beefy, backend } : FullDeps, +) -> Result> +where + C: ProvideRuntimeApi + + HeaderBackend + + AuxStore + + HeaderMetadata + + Send + + Sync + + 'static, + C::Api: frame_rpc_system::AccountNonceApi, + C::Api: mmr_rpc::MmrRuntimeApi::Hash, BlockNumber>, + C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, + C::Api: BabeApi, + C::Api: BlockBuilder, + P: TransactionPool + Sync + Send + 'static, + SC: SelectChain + 'static, + B: sc_client_api::Backend + Send + Sync + 'static, + B::State: sc_client_api::StateBackend>, +{ + use frame_rpc_system::{System, SystemApiServer}; + use mmr_rpc::{Mmr, MmrApiServer}; + use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; + use sc_consensus_babe_rpc::{Babe, BabeApiServer}; + use sc_consensus_beefy_rpc::{Beefy, BeefyApiServer}; + use sc_consensus_grandpa_rpc::{Grandpa, GrandpaApiServer}; + use sc_sync_state_rpc::{SyncState, SyncStateApiServer}; + use substrate_state_trie_migration_rpc::{StateMigration, StateMigrationApiServer}; + + let mut io = RpcModule::new(()); + let BabeDeps { babe_worker_handle, keystore } = babe; + let GrandpaDeps { + shared_voter_state, + shared_authority_set, + justification_stream, + subscription_executor, + finality_provider, + } = grandpa; + + io.merge(StateMigration::new(client.clone(), backend.clone(), deny_unsafe).into_rpc())?; + io.merge(System::new(client.clone(), pool.clone(), deny_unsafe).into_rpc())?; + io.merge(TransactionPayment::new(client.clone()).into_rpc())?; + io.merge( + Mmr::new( + client.clone(), + backend + .offchain_storage() + .ok_or("Backend doesn't provide the required offchain storage")?, + ) + .into_rpc(), + )?; + io.merge( + Babe::new(client.clone(), babe_worker_handle.clone(), keystore, select_chain, deny_unsafe) + .into_rpc(), + )?; + io.merge( + Grandpa::new( + subscription_executor, + shared_authority_set.clone(), + shared_voter_state, + justification_stream, + finality_provider, + ) + .into_rpc(), + )?; + io.merge( + SyncState::new(chain_spec, client, shared_authority_set, babe_worker_handle)?.into_rpc(), + )?; + + io.merge( + Beefy::::new( + beefy.beefy_finality_proof_stream, + beefy.beefy_best_block_stream, + beefy.subscription_executor, + )? + .into_rpc(), + )?; + + Ok(io) +} diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..dda7c2e9236880762584d7fec69b181a9a763344 --- /dev/null +++ b/polkadot/runtime/common/Cargo.toml @@ -0,0 +1,127 @@ +[package] +name = "polkadot-runtime-common" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +impl-trait-for-tuples = "0.2.2" +bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +log = { version = "0.4.17", default-features = false } +rustc-hex = { version = "2.1.0", default-features = false } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.163", default-features = false, features = ["alloc"] } +serde_derive = { version = "1.0.117" } +static_assertions = "1.1.0" + +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false , features=["serde"]} +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features=["serde"] } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false , features=["serde"]} +sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features=["serde"] } + +pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-fast-unstake = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking-reward-fn = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } + +primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } +libsecp256k1 = { version = "0.7.0", default-features = false } +runtime-parachains = { package = "polkadot-runtime-parachains", path = "../parachains", default-features = false } + +slot-range-helper = { path = "slot_range_helper", default-features = false } +xcm = { path = "../../xcm", default-features = false } + +[dev-dependencies] +hex-literal = "0.4.1" +frame-support-test = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +serde_json = "1.0.96" +libsecp256k1 = "0.7.0" +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../primitives/test-helpers" } + +[features] +default = ["std"] +experimental = [ + "frame-support/experimental" +] +no_std = [] +std = [ + "bitvec/std", + "parity-scale-codec/std", + "scale-info/std", + "log/std", + "rustc-hex/std", + "serde/std", + "primitives/std", + "inherents/std", + "sp-core/std", + "sp-api/std", + "sp-std/std", + "sp-io/std", + "frame-support/std", + "pallet-authorship/std", + "pallet-balances/std", + "pallet-session/std", + "pallet-fast-unstake/std", + "pallet-staking/std", + "pallet-staking-reward-fn/std", + "pallet-timestamp/std", + "pallet-vesting/std", + "pallet-transaction-payment/std", + "pallet-treasury/std", + "pallet-election-provider-multi-phase/std", + "slot-range-helper/std", + "sp-runtime/std", + "sp-session/std", + "sp-staking/std", + "frame-system/std", + "libsecp256k1/std", + "runtime-parachains/std", + "xcm/std", + "sp-npos-elections/std", +] +runtime-benchmarks = [ + "libsecp256k1/hmac", + "libsecp256k1/static-context", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "runtime-parachains/runtime-benchmarks", + "pallet-babe/runtime-benchmarks", + "pallet-fast-unstake/runtime-benchmarks" +] +try-runtime = [ + "runtime-parachains/try-runtime", + "pallet-authorship/try-runtime", + "pallet-balances/try-runtime", + "pallet-session/try-runtime", + "pallet-staking/try-runtime", + "pallet-timestamp/try-runtime", + "pallet-vesting/try-runtime", + "pallet-transaction-payment/try-runtime", + "pallet-treasury/try-runtime", + "pallet-fast-unstake/try-runtime", +] diff --git a/polkadot/runtime/common/slot_range_helper/Cargo.toml b/polkadot/runtime/common/slot_range_helper/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..3d48b1c03c5380f6408b3164020d01de499629e1 --- /dev/null +++ b/polkadot/runtime/common/slot_range_helper/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "slot-range-helper" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +paste = "1.0" +enumn = "0.1.8" +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +[features] +default = ["std"] +std = [ + "sp-std/std", + "parity-scale-codec/std", + "sp-runtime/std", +] diff --git a/polkadot/runtime/common/slot_range_helper/src/lib.rs b/polkadot/runtime/common/slot_range_helper/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..bbe5b61ae1f3af6fd4a316ed4202942ba52e3264 --- /dev/null +++ b/polkadot/runtime/common/slot_range_helper/src/lib.rs @@ -0,0 +1,290 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A helper macro for generating `SlotRange` enum. + +#![cfg_attr(not(feature = "std"), no_std)] + +pub use enumn::N; +pub use parity_scale_codec::{Decode, Encode}; +pub use paste; +pub use sp_runtime::traits::CheckedSub; +pub use sp_std::{ops::Add, result}; + +/// This macro generates a `SlotRange` enum of arbitrary length for use in the Slot Auction +/// mechanism on Polkadot. +/// +/// Usage: +/// ``` +/// slot_range_helper::generate_slot_range!(Zero(0), One(1), Two(2), Three(3)); +/// ``` +/// +/// To extend the usage, continue to add `Identifier(value)` items to the macro. +/// +/// This will generate an enum `SlotRange` with the following properties: +/// +/// * Enum variants will range from all consecutive combinations of inputs, i.e. `ZeroZero`, +/// `ZeroOne`, `ZeroTwo`, `ZeroThree`, `OneOne`, `OneTwo`, `OneThree`... +/// * A constant `LEASE_PERIODS_PER_SLOT` will count the number of lease periods. +/// * A constant `SLOT_RANGE_COUNT` will count the total number of enum variants. +/// * A function `as_pair` will return a tuple representation of the `SlotRange`. +/// * A function `intersects` will tell you if two slot ranges intersect with one another. +/// * A function `len` will tell you the length of occupying a `SlotRange`. +/// * A function `new_bounded` will generate a `SlotRange` from an input of the current lease +/// period, the starting lease period, and the final lease period. +#[macro_export] +macro_rules! generate_slot_range{ + // Entry point + ($( $x:ident ( $e:expr ) ),*) => { + $crate::generate_lease_period_per_slot!( $( $x )* ); + $crate::generate_slot_range!(@inner + { } + $( $x ( $e ) )* + ); + }; + // Does the magic... + (@inner + { $( $parsed:ident ( $t1:expr, $t2:expr ) )* } + $current:ident ( $ce:expr ) + $( $remaining:ident ( $re:expr ) )* + ) => { + $crate::paste::paste! { + $crate::generate_slot_range!(@inner + { + $( $parsed ( $t1, $t2 ) )* + [< $current $current >] ( $ce, $ce ) + $( [< $current $remaining >] ($ce, $re) )* + } + $( $remaining ( $re ) )* + ); + } + }; + (@inner + { $( $parsed:ident ( $t1:expr, $t2:expr ) )* } + ) => { + $crate::generate_slot_range_enum!(@inner $( $parsed )* ); + + $crate::generate_slot_range_count!( $( $parsed )* ); + + #[cfg(feature = "std")] + impl std::fmt::Debug for SlotRange { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + let p = self.as_pair(); + write!(fmt, "[{}..{}]", p.0, p.1) + } + } + + impl SlotRange { + pub const LEASE_PERIODS_PER_SLOT: usize = LEASE_PERIODS_PER_SLOT; + pub const SLOT_RANGE_COUNT: usize = SLOT_RANGE_COUNT; + + $crate::generate_slot_range_as_pair!(@inner $( $parsed ( $t1, $t2 ) )* ); + + $crate::generate_slot_range_len!(@inner $( $parsed ( $t1, $t2 ) )* ); + + $crate::generate_slot_range_new_bounded!(@inner $( $parsed ( $t1, $t2 ) )* ); + } + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! generate_slot_range_enum { + (@inner + $( $parsed:ident )* + ) => { + /// A compactly represented sub-range from the series. + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, $crate::Encode, $crate::Decode, $crate::N)] + #[repr(u8)] + pub enum SlotRange { $( $parsed ),* } + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! generate_slot_range_as_pair { + (@inner + $( $parsed:ident ( $t1:expr, $t2:expr ) )* + ) => { + /// Return true if two `SlotRange` intersect in their lease periods. + pub fn intersects(&self, other: SlotRange) -> bool { + let a = self.as_pair(); + let b = other.as_pair(); + b.0 <= a.1 && a.0 <= b.1 + // == !(b.0 > a.1 || a.0 > b.1) + } + + /// Return a tuple representation of the `SlotRange`. + /// + /// Example:`SlotRange::OneTwo.as_pair() == (1, 2)` + pub fn as_pair(&self) -> (u8, u8) { + match self { + $( SlotRange::$parsed => { ($t1, $t2) } )* + } + } + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! generate_slot_range_len { + // Use evaluated length in function. + (@inner + $( $parsed:ident ( $t1:expr, $t2:expr ) )* + ) => { + /// Return the length of occupying a `SlotRange`. + /// + /// Example:`SlotRange::OneTwo.len() == 2` + pub fn len(&self) -> usize { + match self { + // len (0, 2) = 2 - 0 + 1 = 3 + $( SlotRange::$parsed => { ( $t2 - $t1 + 1) } )* + } + } + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! generate_slot_range_new_bounded { + (@inner + $( $parsed:ident ( $t1:expr, $t2:expr ) )* + ) => { + /// Construct a `SlotRange` from the current lease period, the first lease period of the range, + /// and the last lease period of the range. + /// + /// For example: `SlotRange::new_bounded(1, 2, 3) == SlotRange::OneTwo`. + pub fn new_bounded< + Index: $crate::Add + $crate::CheckedSub + Copy + Ord + From + TryInto + >( + current: Index, + first: Index, + last: Index + ) -> $crate::result::Result { + if first > last || first < current || last >= current + (LEASE_PERIODS_PER_SLOT as u32).into() { + return Err("Invalid range for this auction") + } + let count: u32 = last.checked_sub(&first) + .ok_or("range ends before it begins")? + .try_into() + .map_err(|_| "range too big")?; + let first: u32 = first.checked_sub(¤t) + .ok_or("range begins too early")? + .try_into() + .map_err(|_| "start too far")?; + match (first, first + count) { + $( ($t1, $t2) => { Ok(SlotRange::$parsed) })* + _ => Err("bad range"), + } + } + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! generate_slot_range_count { + ( + $start:ident $( $rest:ident )* + ) => { + $crate::generate_slot_range_count!(@inner 1; $( $rest )*); + }; + (@inner + $count:expr; + $start:ident $( $rest:ident )* + ) => { + $crate::generate_slot_range_count!(@inner $count + 1; $( $rest )*); + }; + (@inner + $count:expr; + ) => { + const SLOT_RANGE_COUNT: usize = $count; + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! generate_lease_period_per_slot { + ( + $start:ident $( $rest:ident )* + ) => { + $crate::generate_lease_period_per_slot!(@inner 1; $( $rest )*); + }; + (@inner + $count:expr; + $start:ident $( $rest:ident )* + ) => { + $crate::generate_lease_period_per_slot!(@inner $count + 1; $( $rest )*); + }; + (@inner + $count:expr; + ) => { + const LEASE_PERIODS_PER_SLOT: usize = $count; + }; +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn slot_range_4_works() { + generate_slot_range!(Zero(0), One(1), Two(2), Three(3)); + + assert_eq!(SlotRange::LEASE_PERIODS_PER_SLOT, 4); + // Sum over n from 0 - 4 + assert_eq!(SlotRange::SLOT_RANGE_COUNT, 10); + assert_eq!(SlotRange::new_bounded(0u32, 1u32, 2u32).unwrap(), SlotRange::OneTwo); + assert_eq!(SlotRange::new_bounded(5u32, 6u32, 7u32).unwrap(), SlotRange::OneTwo); + assert!(SlotRange::new_bounded(10u32, 6u32, 7u32).is_err()); + assert!(SlotRange::new_bounded(10u32, 16u32, 17u32).is_err()); + assert!(SlotRange::new_bounded(10u32, 11u32, 10u32).is_err()); + assert_eq!(SlotRange::TwoTwo.len(), 1); + assert_eq!(SlotRange::OneTwo.len(), 2); + assert_eq!(SlotRange::ZeroThree.len(), 4); + assert!(SlotRange::ZeroOne.intersects(SlotRange::OneThree)); + assert!(!SlotRange::ZeroOne.intersects(SlotRange::TwoThree)); + assert_eq!(SlotRange::ZeroZero.as_pair(), (0, 0)); + assert_eq!(SlotRange::OneThree.as_pair(), (1, 3)); + } + + #[test] + fn slot_range_8_works() { + generate_slot_range!(Zero(0), One(1), Two(2), Three(3), Four(4), Five(5), Six(6), Seven(7)); + + assert_eq!(SlotRange::LEASE_PERIODS_PER_SLOT, 8); + // Sum over n from 0 to 8 + assert_eq!(SlotRange::SLOT_RANGE_COUNT, 36); + assert_eq!(SlotRange::new_bounded(0u32, 1u32, 2u32).unwrap(), SlotRange::OneTwo); + assert_eq!(SlotRange::new_bounded(5u32, 6u32, 7u32).unwrap(), SlotRange::OneTwo); + assert!(SlotRange::new_bounded(10u32, 6u32, 7u32).is_err()); + // This one passes with slot range 8 + assert_eq!(SlotRange::new_bounded(10u32, 16u32, 17u32).unwrap(), SlotRange::SixSeven); + assert!(SlotRange::new_bounded(10u32, 17u32, 18u32).is_err()); + assert!(SlotRange::new_bounded(10u32, 20u32, 21u32).is_err()); + assert!(SlotRange::new_bounded(10u32, 11u32, 10u32).is_err()); + assert_eq!(SlotRange::TwoTwo.len(), 1); + assert_eq!(SlotRange::OneTwo.len(), 2); + assert_eq!(SlotRange::ZeroThree.len(), 4); + assert_eq!(SlotRange::ZeroSeven.len(), 8); + assert!(SlotRange::ZeroOne.intersects(SlotRange::OneThree)); + assert!(!SlotRange::ZeroOne.intersects(SlotRange::TwoThree)); + assert!(SlotRange::FiveSix.intersects(SlotRange::SixSeven)); + assert!(!SlotRange::ThreeFive.intersects(SlotRange::SixSeven)); + assert_eq!(SlotRange::ZeroZero.as_pair(), (0, 0)); + assert_eq!(SlotRange::OneThree.as_pair(), (1, 3)); + assert_eq!(SlotRange::SixSeven.as_pair(), (6, 7)); + } +} diff --git a/polkadot/runtime/common/src/assigned_slots/benchmarking.rs b/polkadot/runtime/common/src/assigned_slots/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..61638fe6cabfce76d4323e65a1983e18fae22ffc --- /dev/null +++ b/polkadot/runtime/common/src/assigned_slots/benchmarking.rs @@ -0,0 +1,160 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Benchmarking for assigned_slots pallet + +#![cfg(feature = "runtime-benchmarks")] +use super::*; + +use frame_benchmarking::v2::*; +use frame_support::assert_ok; +use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin}; +use primitives::Id as ParaId; +use sp_runtime::traits::Bounded; + +type CurrencyOf = <::Leaser as Leaser>>::Currency; +type BalanceOf = <<::Leaser as Leaser>>::Currency as Currency< + ::AccountId, +>>::Balance; +#[benchmarks(where T: Config)] +mod benchmarks { + use super::*; + + use crate::assigned_slots::Pallet as AssignedSlots; + + fn register_parachain(para_id: ParaId) { + let who: T::AccountId = whitelisted_caller(); + let worst_validation_code = T::Registrar::worst_validation_code(); + let worst_head_data = T::Registrar::worst_head_data(); + + CurrencyOf::::make_free_balance_be(&who, BalanceOf::::max_value()); + + assert_ok!(T::Registrar::register( + who, + para_id, + worst_head_data, + worst_validation_code.clone() + )); + assert_ok!(paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + worst_validation_code, + )); + T::Registrar::execute_pending_transitions(); + } + + #[benchmark] + fn assign_perm_parachain_slot() { + let para_id = ParaId::from(1_u32); + let caller = RawOrigin::Root; + + let _ = + AssignedSlots::::set_max_permanent_slots(frame_system::Origin::::Root.into(), 10); + register_parachain::(para_id); + + let counter = PermanentSlotCount::::get(); + let current_lease_period: BlockNumberFor = + T::Leaser::lease_period_index(frame_system::Pallet::::block_number()) + .and_then(|x| Some(x.0)) + .unwrap(); + #[extrinsic_call] + assign_perm_parachain_slot(caller, para_id); + + assert_eq!( + PermanentSlots::::get(para_id), + Some(( + current_lease_period, + LeasePeriodOf::::from(T::PermanentSlotLeasePeriodLength::get()), + )) + ); + assert_eq!(PermanentSlotCount::::get(), counter + 1); + } + + #[benchmark] + fn assign_temp_parachain_slot() { + let para_id = ParaId::from(2_u32); + let caller = RawOrigin::Root; + + let _ = + AssignedSlots::::set_max_temporary_slots(frame_system::Origin::::Root.into(), 10); + register_parachain::(para_id); + + let current_lease_period: BlockNumberFor = + T::Leaser::lease_period_index(frame_system::Pallet::::block_number()) + .and_then(|x| Some(x.0)) + .unwrap(); + + let counter = TemporarySlotCount::::get(); + #[extrinsic_call] + assign_temp_parachain_slot(caller, para_id, SlotLeasePeriodStart::Current); + + let tmp = ParachainTemporarySlot { + manager: whitelisted_caller(), + period_begin: current_lease_period, + period_count: LeasePeriodOf::::from(T::TemporarySlotLeasePeriodLength::get()), + last_lease: Some(BlockNumberFor::::zero()), + lease_count: 1, + }; + assert_eq!(TemporarySlots::::get(para_id), Some(tmp)); + assert_eq!(TemporarySlotCount::::get(), counter + 1); + } + + #[benchmark] + fn unassign_parachain_slot() { + let para_id = ParaId::from(3_u32); + let caller = RawOrigin::Root; + + let _ = + AssignedSlots::::set_max_temporary_slots(frame_system::Origin::::Root.into(), 10); + register_parachain::(para_id); + + let _ = AssignedSlots::::assign_temp_parachain_slot( + caller.clone().into(), + para_id, + SlotLeasePeriodStart::Current, + ); + + let counter = TemporarySlotCount::::get(); + #[extrinsic_call] + unassign_parachain_slot(caller, para_id); + + assert_eq!(TemporarySlots::::get(para_id), None); + assert_eq!(TemporarySlotCount::::get(), counter - 1); + } + + #[benchmark] + fn set_max_permanent_slots() { + let caller = RawOrigin::Root; + #[extrinsic_call] + set_max_permanent_slots(caller, u32::MAX); + + assert_eq!(MaxPermanentSlots::::get(), u32::MAX); + } + + #[benchmark] + fn set_max_temporary_slots() { + let caller = RawOrigin::Root; + #[extrinsic_call] + set_max_temporary_slots(caller, u32::MAX); + + assert_eq!(MaxTemporarySlots::::get(), u32::MAX); + } + + impl_benchmark_test_suite!( + AssignedSlots, + crate::assigned_slots::tests::new_test_ext(), + crate::assigned_slots::tests::Test, + ); +} diff --git a/polkadot/runtime/common/src/assigned_slots/migration.rs b/polkadot/runtime/common/src/assigned_slots/migration.rs new file mode 100644 index 0000000000000000000000000000000000000000..884d67222d281afb1c8c5b302dc6d466af141c8f --- /dev/null +++ b/polkadot/runtime/common/src/assigned_slots/migration.rs @@ -0,0 +1,77 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::{Config, MaxPermanentSlots, MaxTemporarySlots, Pallet, LOG_TARGET}; +use frame_support::{ + dispatch::GetStorageVersion, + traits::{Get, OnRuntimeUpgrade}, +}; + +#[cfg(feature = "try-runtime")] +use frame_support::ensure; +#[cfg(feature = "try-runtime")] +use sp_std::vec::Vec; + +pub mod v1 { + + use super::*; + pub struct MigrateToV1(sp_std::marker::PhantomData); + impl OnRuntimeUpgrade for MigrateToV1 { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + let onchain_version = Pallet::::on_chain_storage_version(); + ensure!(onchain_version < 1, "assigned_slots::MigrateToV1 migration can be deleted"); + Ok(Default::default()) + } + + fn on_runtime_upgrade() -> frame_support::weights::Weight { + let onchain_version = Pallet::::on_chain_storage_version(); + if onchain_version < 1 { + const MAX_PERMANENT_SLOTS: u32 = 100; + const MAX_TEMPORARY_SLOTS: u32 = 100; + + >::put(MAX_PERMANENT_SLOTS); + >::put(MAX_TEMPORARY_SLOTS); + // Return the weight consumed by the migration. + T::DbWeight::get().reads_writes(1, 3) + } else { + log::info!(target: LOG_TARGET, "MigrateToV1 should be removed"); + T::DbWeight::get().reads(1) + } + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + let onchain_version = Pallet::::on_chain_storage_version(); + ensure!(onchain_version == 1, "assigned_slots::MigrateToV1 needs to be run"); + assert_eq!(>::get(), 100); + assert_eq!(>::get(), 100); + Ok(()) + } + } + + /// [`VersionUncheckedMigrateToV1`] wrapped in a + /// [`frame_support::migrations::VersionedRuntimeUpgrade`], ensuring the migration is only + /// performed when on-chain version is 0. + #[cfg(feature = "experimental")] + pub type VersionCheckedMigrateToV1 = frame_support::migrations::VersionedRuntimeUpgrade< + 0, + 1, + MigrateToV1, + Pallet, + ::DbWeight, + >; +} diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..3683cfc210fa0dcfc3d7995753639879bf3386f8 --- /dev/null +++ b/polkadot/runtime/common/src/assigned_slots/mod.rs @@ -0,0 +1,1467 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This pallet allows to assign permanent (long-lived) or temporary +//! (short-lived) parachain slots to paras, leveraging the existing +//! parachain slot lease mechanism. Temporary slots are given turns +//! in a fair (though best-effort) manner. +//! The dispatchables must be called from the configured origin +//! (typically `Sudo` or a governance origin). +//! This pallet should not be used on a production relay chain, +//! only on a test relay chain (e.g. Rococo). + +pub mod benchmarking; +pub mod migration; + +use crate::{ + slots::{self, Pallet as Slots, WeightInfo as SlotsWeightInfo}, + traits::{LeaseError, Leaser, Registrar}, +}; +use frame_support::{pallet_prelude::*, traits::Currency}; +use frame_system::pallet_prelude::*; +pub use pallet::*; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use primitives::Id as ParaId; +use runtime_parachains::{ + configuration, + paras::{self}, +}; +use scale_info::TypeInfo; +use sp_runtime::traits::{One, Saturating, Zero}; +use sp_std::prelude::*; + +const LOG_TARGET: &str = "runtime::assigned_slots"; + +/// Lease period an assigned slot should start from (current, or next one). +#[derive(Encode, Decode, Clone, Copy, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub enum SlotLeasePeriodStart { + Current, + Next, +} + +/// Information about a temporary parachain slot. +#[derive(Encode, Decode, Clone, PartialEq, Eq, Default, MaxEncodedLen, RuntimeDebug, TypeInfo)] +pub struct ParachainTemporarySlot { + /// Manager account of the para. + pub manager: AccountId, + /// Lease period the parachain slot should ideally start from, + /// As slot are allocated in a best-effort manner, this could be later, + /// but not earlier than the specified period. + pub period_begin: LeasePeriod, + /// Number of lease period the slot lease will last. + /// This is set to the value configured in `TemporarySlotLeasePeriodLength`. + pub period_count: LeasePeriod, + /// Last lease period this slot had a turn in (incl. current). + /// This is set to the beginning period of a slot. + pub last_lease: Option, + /// Number of leases this temporary slot had (incl. current). + pub lease_count: u32, +} + +pub trait WeightInfo { + fn assign_perm_parachain_slot() -> Weight; + fn assign_temp_parachain_slot() -> Weight; + fn unassign_parachain_slot() -> Weight; + fn set_max_permanent_slots() -> Weight; + fn set_max_temporary_slots() -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn assign_perm_parachain_slot() -> Weight { + Weight::zero() + } + fn assign_temp_parachain_slot() -> Weight { + Weight::zero() + } + fn unassign_parachain_slot() -> Weight { + Weight::zero() + } + fn set_max_permanent_slots() -> Weight { + Weight::zero() + } + fn set_max_temporary_slots() -> Weight { + Weight::zero() + } +} + +type BalanceOf = <<::Leaser as Leaser>>::Currency as Currency< + ::AccountId, +>>::Balance; +type LeasePeriodOf = <::Leaser as Leaser>>::LeasePeriod; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + /// The current storage version. + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + #[pallet::config] + #[pallet::disable_frame_system_supertrait_check] + pub trait Config: configuration::Config + paras::Config + slots::Config { + /// The overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// Origin for assigning slots. + type AssignSlotOrigin: EnsureOrigin<::RuntimeOrigin>; + + /// The type representing the leasing system. + type Leaser: Leaser< + BlockNumberFor, + AccountId = Self::AccountId, + LeasePeriod = BlockNumberFor, + >; + + /// The number of lease periods a permanent parachain slot lasts. + #[pallet::constant] + type PermanentSlotLeasePeriodLength: Get; + + /// The number of lease periods a temporary parachain slot lasts. + #[pallet::constant] + type TemporarySlotLeasePeriodLength: Get; + + /// The max number of temporary slots to be scheduled per lease periods. + #[pallet::constant] + type MaxTemporarySlotPerLeasePeriod: Get; + + /// Weight Information for the Extrinsics in the Pallet + type WeightInfo: WeightInfo; + } + + /// Assigned permanent slots, with their start lease period, and duration. + #[pallet::storage] + #[pallet::getter(fn permanent_slots)] + pub type PermanentSlots = + StorageMap<_, Twox64Concat, ParaId, (LeasePeriodOf, LeasePeriodOf), OptionQuery>; + + /// Number of assigned (and active) permanent slots. + #[pallet::storage] + #[pallet::getter(fn permanent_slot_count)] + pub type PermanentSlotCount = StorageValue<_, u32, ValueQuery>; + + /// Assigned temporary slots. + #[pallet::storage] + #[pallet::getter(fn temporary_slots)] + pub type TemporarySlots = StorageMap< + _, + Twox64Concat, + ParaId, + ParachainTemporarySlot>, + OptionQuery, + >; + + /// Number of assigned temporary slots. + #[pallet::storage] + #[pallet::getter(fn temporary_slot_count)] + pub type TemporarySlotCount = StorageValue<_, u32, ValueQuery>; + + /// Number of active temporary slots in current slot lease period. + #[pallet::storage] + #[pallet::getter(fn active_temporary_slot_count)] + pub type ActiveTemporarySlotCount = StorageValue<_, u32, ValueQuery>; + + /// The max number of temporary slots that can be assigned. + #[pallet::storage] + pub type MaxTemporarySlots = StorageValue<_, u32, ValueQuery>; + + /// The max number of permanent slots that can be assigned. + #[pallet::storage] + pub type MaxPermanentSlots = StorageValue<_, u32, ValueQuery>; + + #[pallet::genesis_config] + #[derive(frame_support::DefaultNoBound)] + pub struct GenesisConfig { + pub max_temporary_slots: u32, + pub max_permanent_slots: u32, + pub _config: PhantomData, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + >::put(&self.max_permanent_slots); + >::put(&self.max_temporary_slots); + } + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// A parachain was assigned a permanent parachain slot + PermanentSlotAssigned(ParaId), + /// A parachain was assigned a temporary parachain slot + TemporarySlotAssigned(ParaId), + /// The maximum number of permanent slots has been changed + MaxPermanentSlotsChanged { slots: u32 }, + /// The maximum number of temporary slots has been changed + MaxTemporarySlotsChanged { slots: u32 }, + } + + #[pallet::error] + pub enum Error { + /// The specified parachain is not registered. + ParaDoesntExist, + /// Not a parathread (on-demand parachain). + NotParathread, + /// Cannot upgrade on-demand parachain to lease holding + /// parachain. + CannotUpgrade, + /// Cannot downgrade lease holding parachain to + /// on-demand. + CannotDowngrade, + /// Permanent or Temporary slot already assigned. + SlotAlreadyAssigned, + /// Permanent or Temporary slot has not been assigned. + SlotNotAssigned, + /// An ongoing lease already exists. + OngoingLeaseExists, + // The maximum number of permanent slots exceeded + MaxPermanentSlotsExceeded, + // The maximum number of temporary slots exceeded + MaxTemporarySlotsExceeded, + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(n: BlockNumberFor) -> Weight { + if let Some((lease_period, first_block)) = Self::lease_period_index(n) { + // If we're beginning a new lease period then handle that. + if first_block { + return Self::manage_lease_period_start(lease_period) + } + } + + // We didn't return early above, so we didn't do anything. + Weight::zero() + } + } + + #[pallet::call] + impl Pallet { + /// Assign a permanent parachain slot and immediately create a lease for it. + #[pallet::call_index(0)] + #[pallet::weight((::WeightInfo::assign_perm_parachain_slot(), DispatchClass::Operational))] + pub fn assign_perm_parachain_slot(origin: OriginFor, id: ParaId) -> DispatchResult { + T::AssignSlotOrigin::ensure_origin(origin)?; + + let manager = T::Registrar::manager_of(id).ok_or(Error::::ParaDoesntExist)?; + + ensure!(T::Registrar::is_parathread(id), Error::::NotParathread); + + ensure!( + !Self::has_permanent_slot(id) && !Self::has_temporary_slot(id), + Error::::SlotAlreadyAssigned + ); + + let current_lease_period: BlockNumberFor = Self::current_lease_period_index(); + ensure!( + !T::Leaser::already_leased( + id, + current_lease_period, + // Check current lease & next one + current_lease_period.saturating_add( + BlockNumberFor::::from(2u32) + .saturating_mul(T::PermanentSlotLeasePeriodLength::get().into()) + ) + ), + Error::::OngoingLeaseExists + ); + + ensure!( + PermanentSlotCount::::get() < MaxPermanentSlots::::get(), + Error::::MaxPermanentSlotsExceeded + ); + + // Permanent slot assignment fails if a lease cannot be created + Self::configure_slot_lease( + id, + manager, + current_lease_period, + T::PermanentSlotLeasePeriodLength::get().into(), + ) + .map_err(|_| Error::::CannotUpgrade)?; + + PermanentSlots::::insert( + id, + ( + current_lease_period, + LeasePeriodOf::::from(T::PermanentSlotLeasePeriodLength::get()), + ), + ); + >::mutate(|count| count.saturating_inc()); + + Self::deposit_event(Event::::PermanentSlotAssigned(id)); + Ok(()) + } + + /// Assign a temporary parachain slot. The function tries to create a lease for it + /// immediately if `SlotLeasePeriodStart::Current` is specified, and if the number + /// of currently active temporary slots is below `MaxTemporarySlotPerLeasePeriod`. + #[pallet::call_index(1)] + #[pallet::weight((::WeightInfo::assign_temp_parachain_slot(), DispatchClass::Operational))] + pub fn assign_temp_parachain_slot( + origin: OriginFor, + id: ParaId, + lease_period_start: SlotLeasePeriodStart, + ) -> DispatchResult { + T::AssignSlotOrigin::ensure_origin(origin)?; + + let manager = T::Registrar::manager_of(id).ok_or(Error::::ParaDoesntExist)?; + + ensure!(T::Registrar::is_parathread(id), Error::::NotParathread); + + ensure!( + !Self::has_permanent_slot(id) && !Self::has_temporary_slot(id), + Error::::SlotAlreadyAssigned + ); + + let current_lease_period: BlockNumberFor = Self::current_lease_period_index(); + ensure!( + !T::Leaser::already_leased( + id, + current_lease_period, + // Check current lease & next one + current_lease_period.saturating_add( + BlockNumberFor::::from(2u32) + .saturating_mul(T::TemporarySlotLeasePeriodLength::get().into()) + ) + ), + Error::::OngoingLeaseExists + ); + + ensure!( + TemporarySlotCount::::get() < MaxTemporarySlots::::get(), + Error::::MaxTemporarySlotsExceeded + ); + + let mut temp_slot = ParachainTemporarySlot { + manager: manager.clone(), + period_begin: match lease_period_start { + SlotLeasePeriodStart::Current => current_lease_period, + SlotLeasePeriodStart::Next => current_lease_period + One::one(), + }, + period_count: T::TemporarySlotLeasePeriodLength::get().into(), + last_lease: None, + lease_count: 0, + }; + + if lease_period_start == SlotLeasePeriodStart::Current && + Self::active_temporary_slot_count() < T::MaxTemporarySlotPerLeasePeriod::get() + { + // Try to allocate slot directly + match Self::configure_slot_lease( + id, + manager, + temp_slot.period_begin, + temp_slot.period_count, + ) { + Ok(_) => { + ActiveTemporarySlotCount::::mutate(|count| count.saturating_inc()); + temp_slot.last_lease = Some(temp_slot.period_begin); + temp_slot.lease_count += 1; + }, + Err(err) => { + // Treat failed lease creation as warning .. slot will be allocated a lease + // in a subsequent lease period by the `allocate_temporary_slot_leases` + // function. + log::warn!( + target: LOG_TARGET, + "Failed to allocate a temp slot for para {:?} at period {:?}: {:?}", + id, + current_lease_period, + err + ); + }, + } + } + + TemporarySlots::::insert(id, temp_slot); + >::mutate(|count| count.saturating_inc()); + + Self::deposit_event(Event::::TemporarySlotAssigned(id)); + + Ok(()) + } + + /// Unassign a permanent or temporary parachain slot + #[pallet::call_index(2)] + #[pallet::weight((::WeightInfo::unassign_parachain_slot(), DispatchClass::Operational))] + pub fn unassign_parachain_slot(origin: OriginFor, id: ParaId) -> DispatchResult { + T::AssignSlotOrigin::ensure_origin(origin.clone())?; + + ensure!( + Self::has_permanent_slot(id) || Self::has_temporary_slot(id), + Error::::SlotNotAssigned + ); + + // Check & cache para status before we clear the lease + let is_parachain = Self::is_parachain(id); + + // Remove perm or temp slot + Self::clear_slot_leases(origin.clone(), id)?; + + if PermanentSlots::::contains_key(id) { + PermanentSlots::::remove(id); + >::mutate(|count| *count = count.saturating_sub(One::one())); + } else if TemporarySlots::::contains_key(id) { + TemporarySlots::::remove(id); + >::mutate(|count| *count = count.saturating_sub(One::one())); + if is_parachain { + >::mutate(|active_count| { + *active_count = active_count.saturating_sub(One::one()) + }); + } + } + + // Force downgrade to on-demand parachain (if needed) before end of lease period + if is_parachain { + if let Err(err) = runtime_parachains::schedule_parachain_downgrade::(id) { + // Treat failed downgrade as warning .. slot lease has been cleared, + // so the parachain will be downgraded anyway by the slots pallet + // at the end of the lease period . + log::warn!( + target: LOG_TARGET, + "Failed to downgrade parachain {:?} at period {:?}: {:?}", + id, + Self::current_lease_period_index(), + err + ); + } + } + + Ok(()) + } + + /// Sets the storage value [`MaxPermanentSlots`]. + #[pallet::call_index(3)] + #[pallet::weight((::WeightInfo::set_max_permanent_slots(), DispatchClass::Operational))] + pub fn set_max_permanent_slots(origin: OriginFor, slots: u32) -> DispatchResult { + ensure_root(origin)?; + + >::put(slots); + + Self::deposit_event(Event::::MaxPermanentSlotsChanged { slots }); + Ok(()) + } + + /// Sets the storage value [`MaxTemporarySlots`]. + #[pallet::call_index(4)] + #[pallet::weight((::WeightInfo::set_max_temporary_slots(), DispatchClass::Operational))] + pub fn set_max_temporary_slots(origin: OriginFor, slots: u32) -> DispatchResult { + ensure_root(origin)?; + + >::put(slots); + + Self::deposit_event(Event::::MaxTemporarySlotsChanged { slots }); + Ok(()) + } + } +} + +impl Pallet { + /// Allocate temporary slot leases up to `MaxTemporarySlotPerLeasePeriod` per lease period. + /// Beyond the already active temporary slot leases, this function will activate more leases + /// in the following order of preference: + /// - Assigned slots that didn't have a turn yet, though their `period_begin` has passed. + /// - Assigned slots that already had one (or more) turn(s): they will be considered for the + /// current slot lease if they weren't active in the preceding one, and will be ranked by + /// total number of lease (lower first), and then when they last a turn (older ones first). + /// If any remaining ex-aequo, we just take the para ID in ascending order as discriminator. + /// + /// Assigned slots with a `period_begin` bigger than current lease period are not considered + /// (yet). + /// + /// The function will call out to `Leaser::lease_out` to create the appropriate slot leases. + fn allocate_temporary_slot_leases(lease_period_index: LeasePeriodOf) -> DispatchResult { + let mut active_temp_slots = 0u32; + let mut pending_temp_slots = Vec::new(); + TemporarySlots::::iter().for_each(|(para, slot)| { + match slot.last_lease { + Some(last_lease) + if last_lease <= lease_period_index && + lease_period_index < + (last_lease.saturating_add(slot.period_count)) => + { + // Active slot lease + active_temp_slots += 1; + } + Some(last_lease) + // Slot w/ past lease, only consider it every other slot lease period (times period_count) + if last_lease.saturating_add(slot.period_count.saturating_mul(2u32.into())) <= lease_period_index => { + pending_temp_slots.push((para, slot)); + }, + None if slot.period_begin <= lease_period_index => { + // Slot hasn't had a lease yet + pending_temp_slots.insert(0, (para, slot)); + }, + _ => { + // Slot not being considered for this lease period (will be for a subsequent one) + }, + } + }); + + let mut newly_created_lease = 0u32; + if active_temp_slots < T::MaxTemporarySlotPerLeasePeriod::get() && + !pending_temp_slots.is_empty() + { + // Sort by lease_count, favoring slots that had no or less turns first + // (then by last_lease index, and then Para ID) + pending_temp_slots.sort_by(|a, b| { + a.1.lease_count + .cmp(&b.1.lease_count) + .then_with(|| a.1.last_lease.cmp(&b.1.last_lease)) + .then_with(|| a.0.cmp(&b.0)) + }); + + let slots_to_be_upgraded = pending_temp_slots.iter().take( + (T::MaxTemporarySlotPerLeasePeriod::get().saturating_sub(active_temp_slots)) + as usize, + ); + + for (id, temp_slot) in slots_to_be_upgraded { + TemporarySlots::::try_mutate::<_, _, Error, _>(id, |s| { + // Configure temp slot lease + Self::configure_slot_lease( + *id, + temp_slot.manager.clone(), + lease_period_index, + temp_slot.period_count, + ) + .map_err(|_| Error::::CannotUpgrade)?; + + // Update temp slot lease info in storage + *s = Some(ParachainTemporarySlot { + manager: temp_slot.manager.clone(), + period_begin: temp_slot.period_begin, + period_count: temp_slot.period_count, + last_lease: Some(lease_period_index), + lease_count: temp_slot.lease_count + 1, + }); + + newly_created_lease += 1; + + Ok(()) + })?; + } + } + + ActiveTemporarySlotCount::::set(active_temp_slots + newly_created_lease); + + Ok(()) + } + + /// Clear out all slot leases for both permanent & temporary slots. + /// The function merely calls out to `Slots::clear_all_leases`. + fn clear_slot_leases(origin: OriginFor, id: ParaId) -> DispatchResult { + Slots::::clear_all_leases(origin, id) + } + + /// Create a parachain slot lease based on given params. + /// The function merely calls out to `Leaser::lease_out`. + fn configure_slot_lease( + para: ParaId, + manager: T::AccountId, + lease_period: LeasePeriodOf, + lease_duration: LeasePeriodOf, + ) -> Result<(), LeaseError> { + T::Leaser::lease_out(para, &manager, BalanceOf::::zero(), lease_period, lease_duration) + } + + /// Returns whether a para has been assigned a permanent slot. + fn has_permanent_slot(id: ParaId) -> bool { + PermanentSlots::::contains_key(id) + } + + /// Returns whether a para has been assigned temporary slot. + fn has_temporary_slot(id: ParaId) -> bool { + TemporarySlots::::contains_key(id) + } + + /// Returns whether a para is currently a lease holding parachain. + fn is_parachain(id: ParaId) -> bool { + T::Registrar::is_parachain(id) + } + + /// Returns current lease period index. + fn current_lease_period_index() -> LeasePeriodOf { + T::Leaser::lease_period_index(frame_system::Pallet::::block_number()) + .and_then(|x| Some(x.0)) + .unwrap() + } + + /// Returns lease period index for block + fn lease_period_index(block: BlockNumberFor) -> Option<(LeasePeriodOf, bool)> { + T::Leaser::lease_period_index(block) + } + + /// Handles start of a lease period. + fn manage_lease_period_start(lease_period_index: LeasePeriodOf) -> Weight { + // Note: leases that have ended in previous lease period, should have been cleaned in slots + // pallet. + if let Err(err) = Self::allocate_temporary_slot_leases(lease_period_index) { + log::error!( + target: LOG_TARGET, + "Allocating slots failed for lease period {:?}, with: {:?}", + lease_period_index, + err + ); + } + ::WeightInfo::force_lease() * + (T::MaxTemporarySlotPerLeasePeriod::get() as u64) + } +} + +/// tests for this pallet +#[cfg(test)] +mod tests { + use super::*; + + use crate::{assigned_slots, mock::TestRegistrar, slots}; + use ::test_helpers::{dummy_head_data, dummy_validation_code}; + use frame_support::{assert_noop, assert_ok, parameter_types}; + use frame_system::EnsureRoot; + use pallet_balances; + use primitives::BlockNumber; + use runtime_parachains::{ + configuration as parachains_configuration, paras as parachains_paras, + shared as parachains_shared, + }; + use sp_core::H256; + use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + transaction_validity::TransactionPriority, + BuildStorage, + DispatchError::BadOrigin, + }; + + type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; + type Block = frame_system::mocking::MockBlockU32; + + frame_support::construct_runtime!( + pub enum Test + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Configuration: parachains_configuration::{Pallet, Call, Storage, Config}, + ParasShared: parachains_shared::{Pallet, Call, Storage}, + Parachains: parachains_paras::{Pallet, Call, Storage, Config, Event}, + Slots: slots::{Pallet, Call, Storage, Event}, + AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event}, + } + ); + + impl frame_system::offchain::SendTransactionTypes for Test + where + RuntimeCall: From, + { + type Extrinsic = UncheckedExtrinsic; + type OverarchingCall = RuntimeCall; + } + + parameter_types! { + pub const BlockHashCount: u32 = 250; + } + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + } + + parameter_types! { + pub const ExistentialDeposit: u64 = 1; + } + + impl pallet_balances::Config for Test { + type Balance = u64; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<1>; + type MaxFreezes = ConstU32<1>; + } + + impl parachains_configuration::Config for Test { + type WeightInfo = parachains_configuration::TestWeightInfo; + } + + parameter_types! { + pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); + } + + impl parachains_paras::Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = parachains_paras::TestWeightInfo; + type UnsignedPriority = ParasUnsignedPriority; + type QueueFootprinter = (); + type NextSessionRotation = crate::mock::TestNextSessionRotation; + } + + impl parachains_shared::Config for Test {} + + parameter_types! { + pub const LeasePeriod: BlockNumber = 3; + pub static LeaseOffset: BlockNumber = 0; + pub const ParaDeposit: u64 = 1; + } + + impl slots::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Registrar = TestRegistrar; + type LeasePeriod = LeasePeriod; + type LeaseOffset = LeaseOffset; + type ForceOrigin = EnsureRoot; + type WeightInfo = crate::slots::TestWeightInfo; + } + + parameter_types! { + pub const PermanentSlotLeasePeriodLength: u32 = 3; + pub const TemporarySlotLeasePeriodLength: u32 = 2; + pub const MaxTemporarySlotPerLeasePeriod: u32 = 2; + } + + impl assigned_slots::Config for Test { + type RuntimeEvent = RuntimeEvent; + type AssignSlotOrigin = EnsureRoot; + type Leaser = Slots; + type PermanentSlotLeasePeriodLength = PermanentSlotLeasePeriodLength; + type TemporarySlotLeasePeriodLength = TemporarySlotLeasePeriodLength; + type MaxTemporarySlotPerLeasePeriod = MaxTemporarySlotPerLeasePeriod; + type WeightInfo = crate::assigned_slots::TestWeightInfo; + } + + // This function basically just builds a genesis storage key/value store according to + // our desired mock up. + pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + } + .assimilate_storage(&mut t) + .unwrap(); + + crate::assigned_slots::GenesisConfig:: { + max_temporary_slots: 6, + max_permanent_slots: 2, + _config: Default::default(), + } + .assimilate_storage(&mut t) + .unwrap(); + + t.into() + } + + fn run_to_block(n: BlockNumber) { + while System::block_number() < n { + let mut block = System::block_number(); + // on_finalize hooks + AssignedSlots::on_finalize(block); + Slots::on_finalize(block); + Parachains::on_finalize(block); + ParasShared::on_finalize(block); + Configuration::on_finalize(block); + Balances::on_finalize(block); + System::on_finalize(block); + // Set next block + System::set_block_number(block + 1); + block = System::block_number(); + // on_initialize hooks + System::on_initialize(block); + Balances::on_initialize(block); + Configuration::on_initialize(block); + ParasShared::on_initialize(block); + Parachains::on_initialize(block); + Slots::on_initialize(block); + AssignedSlots::on_initialize(block); + } + } + + #[test] + fn basic_setup_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_eq!(AssignedSlots::current_lease_period_index(), 0); + assert_eq!(Slots::deposit_held(1.into(), &1), 0); + + run_to_block(3); + assert_eq!(AssignedSlots::current_lease_period_index(), 1); + }); + } + + #[test] + fn assign_perm_slot_fails_for_unknown_para() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_noop!( + AssignedSlots::assign_perm_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + ), + Error::::ParaDoesntExist + ); + }); + } + + #[test] + fn assign_perm_slot_fails_for_invalid_origin() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_noop!( + AssignedSlots::assign_perm_parachain_slot( + RuntimeOrigin::signed(1), + ParaId::from(1_u32), + ), + BadOrigin + ); + }); + } + + #[test] + fn assign_perm_slot_fails_when_not_parathread() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code(), + )); + assert_ok!(TestRegistrar::::make_parachain(ParaId::from(1_u32))); + + assert_noop!( + AssignedSlots::assign_perm_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + ), + Error::::NotParathread + ); + }); + } + + #[test] + fn assign_perm_slot_fails_when_existing_lease() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code(), + )); + + // Register lease in current lease period + assert_ok!(Slots::lease_out(ParaId::from(1_u32), &1, 1, 1, 1)); + // Try to assign a perm slot in current period fails + assert_noop!( + AssignedSlots::assign_perm_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + ), + Error::::OngoingLeaseExists + ); + + // Cleanup + assert_ok!(Slots::clear_all_leases(RuntimeOrigin::root(), 1.into())); + + // Register lease for next lease period + assert_ok!(Slots::lease_out(ParaId::from(1_u32), &1, 1, 2, 1)); + // Should be detected and also fail + assert_noop!( + AssignedSlots::assign_perm_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + ), + Error::::OngoingLeaseExists + ); + }); + } + + #[test] + fn assign_perm_slot_fails_when_max_perm_slots_exceeded() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code(), + )); + + assert_ok!(TestRegistrar::::register( + 2, + ParaId::from(2_u32), + dummy_head_data(), + dummy_validation_code(), + )); + + assert_ok!(TestRegistrar::::register( + 3, + ParaId::from(3_u32), + dummy_head_data(), + dummy_validation_code(), + )); + + assert_ok!(AssignedSlots::assign_perm_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + )); + assert_ok!(AssignedSlots::assign_perm_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(2_u32), + )); + assert_eq!(AssignedSlots::permanent_slot_count(), 2); + + assert_noop!( + AssignedSlots::assign_perm_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(3_u32), + ), + Error::::MaxPermanentSlotsExceeded + ); + }); + } + + #[test] + fn assign_perm_slot_succeeds_for_parathread() { + new_test_ext().execute_with(|| { + let mut block = 1; + run_to_block(block); + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code(), + )); + + assert_eq!(AssignedSlots::permanent_slot_count(), 0); + assert_eq!(AssignedSlots::permanent_slots(ParaId::from(1_u32)), None); + + assert_ok!(AssignedSlots::assign_perm_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + )); + + // Para is a lease holding parachain for PermanentSlotLeasePeriodLength * LeasePeriod + // blocks + while block < 9 { + println!("block #{}", block); + + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(1_u32)), true); + + assert_eq!(AssignedSlots::permanent_slot_count(), 1); + assert_eq!(AssignedSlots::has_permanent_slot(ParaId::from(1_u32)), true); + assert_eq!(AssignedSlots::permanent_slots(ParaId::from(1_u32)), Some((0, 3))); + + assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 2), true); + + block += 1; + run_to_block(block); + } + + // Para lease ended, downgraded back to parathread (on-demand parachain) + assert_eq!(TestRegistrar::::is_parathread(ParaId::from(1_u32)), true); + assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 5), false); + }); + } + + #[test] + fn assign_temp_slot_fails_for_unknown_para() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_noop!( + AssignedSlots::assign_temp_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + SlotLeasePeriodStart::Current + ), + Error::::ParaDoesntExist + ); + }); + } + + #[test] + fn assign_temp_slot_fails_for_invalid_origin() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_noop!( + AssignedSlots::assign_temp_parachain_slot( + RuntimeOrigin::signed(1), + ParaId::from(1_u32), + SlotLeasePeriodStart::Current + ), + BadOrigin + ); + }); + } + + #[test] + fn assign_temp_slot_fails_when_not_parathread() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code(), + )); + assert_ok!(TestRegistrar::::make_parachain(ParaId::from(1_u32))); + + assert_noop!( + AssignedSlots::assign_temp_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + SlotLeasePeriodStart::Current + ), + Error::::NotParathread + ); + }); + } + + #[test] + fn assign_temp_slot_fails_when_existing_lease() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code(), + )); + + // Register lease in current lease period + assert_ok!(Slots::lease_out(ParaId::from(1_u32), &1, 1, 1, 1)); + // Try to assign a perm slot in current period fails + assert_noop!( + AssignedSlots::assign_temp_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + SlotLeasePeriodStart::Current + ), + Error::::OngoingLeaseExists + ); + + // Cleanup + assert_ok!(Slots::clear_all_leases(RuntimeOrigin::root(), 1.into())); + + // Register lease for next lease period + assert_ok!(Slots::lease_out(ParaId::from(1_u32), &1, 1, 2, 1)); + // Should be detected and also fail + assert_noop!( + AssignedSlots::assign_temp_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + SlotLeasePeriodStart::Current + ), + Error::::OngoingLeaseExists + ); + }); + } + + #[test] + fn assign_temp_slot_fails_when_max_temp_slots_exceeded() { + new_test_ext().execute_with(|| { + run_to_block(1); + + // Register 6 paras & a temp slot for each + for n in 0..=5 { + assert_ok!(TestRegistrar::::register( + n, + ParaId::from(n as u32), + dummy_head_data(), + dummy_validation_code() + )); + + assert_ok!(AssignedSlots::assign_temp_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(n as u32), + SlotLeasePeriodStart::Current + )); + } + + assert_eq!(AssignedSlots::temporary_slot_count(), 6); + + // Attempt to assign one more temp slot + assert_ok!(TestRegistrar::::register( + 7, + ParaId::from(7_u32), + dummy_head_data(), + dummy_validation_code(), + )); + assert_noop!( + AssignedSlots::assign_temp_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(7_u32), + SlotLeasePeriodStart::Current + ), + Error::::MaxTemporarySlotsExceeded + ); + }); + } + + #[test] + fn assign_temp_slot_succeeds_for_single_parathread() { + new_test_ext().execute_with(|| { + let mut block = 1; + run_to_block(block); + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code(), + )); + + assert_eq!(AssignedSlots::temporary_slots(ParaId::from(1_u32)), None); + + assert_ok!(AssignedSlots::assign_temp_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + SlotLeasePeriodStart::Current + )); + assert_eq!(AssignedSlots::temporary_slot_count(), 1); + assert_eq!(AssignedSlots::active_temporary_slot_count(), 1); + + // Block 1-5 + // Para is a lease holding parachain for TemporarySlotLeasePeriodLength * LeasePeriod + // blocks + while block < 6 { + println!("block #{}", block); + println!("lease period #{}", AssignedSlots::current_lease_period_index()); + println!("lease {:?}", Slots::lease(ParaId::from(1_u32))); + + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(1_u32)), true); + + assert_eq!(AssignedSlots::has_temporary_slot(ParaId::from(1_u32)), true); + assert_eq!(AssignedSlots::active_temporary_slot_count(), 1); + assert_eq!( + AssignedSlots::temporary_slots(ParaId::from(1_u32)), + Some(ParachainTemporarySlot { + manager: 1, + period_begin: 0, + period_count: 2, // TemporarySlotLeasePeriodLength + last_lease: Some(0), + lease_count: 1 + }) + ); + + assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 1), true); + + block += 1; + run_to_block(block); + } + + // Block 6 + println!("block #{}", block); + println!("lease period #{}", AssignedSlots::current_lease_period_index()); + println!("lease {:?}", Slots::lease(ParaId::from(1_u32))); + + // Para lease ended, downgraded back to on-demand parachain + assert_eq!(TestRegistrar::::is_parathread(ParaId::from(1_u32)), true); + assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 3), false); + assert_eq!(AssignedSlots::active_temporary_slot_count(), 0); + + // Block 12 + // Para should get a turn after TemporarySlotLeasePeriodLength * LeasePeriod blocks + run_to_block(12); + println!("block #{}", block); + println!("lease period #{}", AssignedSlots::current_lease_period_index()); + println!("lease {:?}", Slots::lease(ParaId::from(1_u32))); + + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(1_u32)), true); + assert_eq!(Slots::already_leased(ParaId::from(1_u32), 4, 5), true); + assert_eq!(AssignedSlots::active_temporary_slot_count(), 1); + }); + } + + #[test] + fn assign_temp_slot_succeeds_for_multiple_parathreads() { + new_test_ext().execute_with(|| { + // Block 1, Period 0 + run_to_block(1); + + // Register 6 paras & a temp slot for each + // (3 slots in current lease period, 3 in the next one) + for n in 0..=5 { + assert_ok!(TestRegistrar::::register( + n, + ParaId::from(n as u32), + dummy_head_data(), + dummy_validation_code() + )); + + assert_ok!(AssignedSlots::assign_temp_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(n as u32), + if (n % 2).is_zero() { + SlotLeasePeriodStart::Current + } else { + SlotLeasePeriodStart::Next + } + )); + } + + // Block 1-5, Period 0-1 + for n in 1..=5 { + if n > 1 { + run_to_block(n); + } + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(0)), true); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(1_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(2_u32)), true); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(3_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(4_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(5_u32)), false); + assert_eq!(AssignedSlots::active_temporary_slot_count(), 2); + } + + // Block 6-11, Period 2-3 + for n in 6..=11 { + run_to_block(n); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(0)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(1_u32)), true); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(2_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(3_u32)), true); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(4_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(5_u32)), false); + assert_eq!(AssignedSlots::active_temporary_slot_count(), 2); + } + + // Block 12-17, Period 4-5 + for n in 12..=17 { + run_to_block(n); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(0)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(1_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(2_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(3_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(4_u32)), true); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(5_u32)), true); + assert_eq!(AssignedSlots::active_temporary_slot_count(), 2); + } + + // Block 18-23, Period 6-7 + for n in 18..=23 { + run_to_block(n); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(0)), true); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(1_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(2_u32)), true); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(3_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(4_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(5_u32)), false); + assert_eq!(AssignedSlots::active_temporary_slot_count(), 2); + } + + // Block 24-29, Period 8-9 + for n in 24..=29 { + run_to_block(n); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(0)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(1_u32)), true); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(2_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(3_u32)), true); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(4_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(5_u32)), false); + assert_eq!(AssignedSlots::active_temporary_slot_count(), 2); + } + + // Block 30-35, Period 10-11 + for n in 30..=35 { + run_to_block(n); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(0)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(1_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(2_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(3_u32)), false); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(4_u32)), true); + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(5_u32)), true); + assert_eq!(AssignedSlots::active_temporary_slot_count(), 2); + } + }); + } + + #[test] + fn unassign_slot_fails_for_unknown_para() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_noop!( + AssignedSlots::unassign_parachain_slot(RuntimeOrigin::root(), ParaId::from(1_u32),), + Error::::SlotNotAssigned + ); + }); + } + + #[test] + fn unassign_slot_fails_for_invalid_origin() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_noop!( + AssignedSlots::assign_perm_parachain_slot( + RuntimeOrigin::signed(1), + ParaId::from(1_u32), + ), + BadOrigin + ); + }); + } + + #[test] + fn unassign_perm_slot_succeeds() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code(), + )); + + assert_ok!(AssignedSlots::assign_perm_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + )); + + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(1_u32)), true); + + assert_ok!(AssignedSlots::unassign_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + )); + + assert_eq!(AssignedSlots::permanent_slot_count(), 0); + assert_eq!(AssignedSlots::has_permanent_slot(ParaId::from(1_u32)), false); + assert_eq!(AssignedSlots::permanent_slots(ParaId::from(1_u32)), None); + + assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 2), false); + }); + } + + #[test] + fn unassign_temp_slot_succeeds() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code(), + )); + + assert_ok!(AssignedSlots::assign_temp_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + SlotLeasePeriodStart::Current + )); + + assert_eq!(TestRegistrar::::is_parachain(ParaId::from(1_u32)), true); + + assert_ok!(AssignedSlots::unassign_parachain_slot( + RuntimeOrigin::root(), + ParaId::from(1_u32), + )); + + assert_eq!(AssignedSlots::temporary_slot_count(), 0); + assert_eq!(AssignedSlots::active_temporary_slot_count(), 0); + assert_eq!(AssignedSlots::has_temporary_slot(ParaId::from(1_u32)), false); + assert_eq!(AssignedSlots::temporary_slots(ParaId::from(1_u32)), None); + + assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 1), false); + }); + } + #[test] + fn set_max_permanent_slots_fails_for_no_root_origin() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_noop!( + AssignedSlots::set_max_permanent_slots(RuntimeOrigin::signed(1), 5), + BadOrigin + ); + }); + } + #[test] + fn set_max_permanent_slots_succeeds() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_eq!(MaxPermanentSlots::::get(), 2); + assert_ok!(AssignedSlots::set_max_permanent_slots(RuntimeOrigin::root(), 10),); + assert_eq!(MaxPermanentSlots::::get(), 10); + }); + } + + #[test] + fn set_max_temporary_slots_fails_for_no_root_origin() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_noop!( + AssignedSlots::set_max_temporary_slots(RuntimeOrigin::signed(1), 5), + BadOrigin + ); + }); + } + #[test] + fn set_max_temporary_slots_succeeds() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_eq!(MaxTemporarySlots::::get(), 6); + assert_ok!(AssignedSlots::set_max_temporary_slots(RuntimeOrigin::root(), 12),); + assert_eq!(MaxTemporarySlots::::get(), 12); + }); + } +} diff --git a/polkadot/runtime/common/src/auctions.rs b/polkadot/runtime/common/src/auctions.rs new file mode 100644 index 0000000000000000000000000000000000000000..9c2bb04b9c8ea6f5917738583887b108e0847de5 --- /dev/null +++ b/polkadot/runtime/common/src/auctions.rs @@ -0,0 +1,1951 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Auctioning system to determine the set of Parachains in operation. This includes logic for the +//! auctioning mechanism and for reserving balance as part of the "payment". Unreserving the balance +//! happens elsewhere. + +use crate::{ + slot_range::SlotRange, + traits::{AuctionStatus, Auctioneer, LeaseError, Leaser, Registrar}, +}; +use frame_support::{ + dispatch::DispatchResult, + ensure, + traits::{Currency, Get, Randomness, ReservableCurrency}, + weights::Weight, +}; +use frame_system::pallet_prelude::BlockNumberFor; +pub use pallet::*; +use parity_scale_codec::Decode; +use primitives::Id as ParaId; +use sp_runtime::traits::{CheckedSub, One, Saturating, Zero}; +use sp_std::{mem::swap, prelude::*}; + +type CurrencyOf = <::Leaser as Leaser>>::Currency; +type BalanceOf = <<::Leaser as Leaser>>::Currency as Currency< + ::AccountId, +>>::Balance; + +pub trait WeightInfo { + fn new_auction() -> Weight; + fn bid() -> Weight; + fn cancel_auction() -> Weight; + fn on_initialize() -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn new_auction() -> Weight { + Weight::zero() + } + fn bid() -> Weight { + Weight::zero() + } + fn cancel_auction() -> Weight { + Weight::zero() + } + fn on_initialize() -> Weight { + Weight::zero() + } +} + +/// An auction index. We count auctions in this type. +pub type AuctionIndex = u32; + +type LeasePeriodOf = <::Leaser as Leaser>>::LeasePeriod; + +// Winning data type. This encodes the top bidders of each range together with their bid. +type WinningData = [Option<(::AccountId, ParaId, BalanceOf)>; + SlotRange::SLOT_RANGE_COUNT]; +// Winners data type. This encodes each of the final winners of a parachain auction, the parachain +// index assigned to them, their winning bid and the range that they won. +type WinnersData = + Vec<(::AccountId, ParaId, BalanceOf, SlotRange)>; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::{dispatch::DispatchClass, pallet_prelude::*, traits::EnsureOrigin}; + use frame_system::{ensure_root, ensure_signed, pallet_prelude::*}; + + #[pallet::pallet] + pub struct Pallet(_); + + /// The module's configuration trait. + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// The type representing the leasing system. + type Leaser: Leaser< + BlockNumberFor, + AccountId = Self::AccountId, + LeasePeriod = BlockNumberFor, + >; + + /// The parachain registrar type. + type Registrar: Registrar; + + /// The number of blocks over which an auction may be retroactively ended. + #[pallet::constant] + type EndingPeriod: Get>; + + /// The length of each sample to take during the ending period. + /// + /// `EndingPeriod` / `SampleLength` = Total # of Samples + #[pallet::constant] + type SampleLength: Get>; + + /// Something that provides randomness in the runtime. + type Randomness: Randomness>; + + /// The origin which may initiate auctions. + type InitiateOrigin: EnsureOrigin; + + /// Weight Information for the Extrinsics in the Pallet + type WeightInfo: WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// An auction started. Provides its index and the block number where it will begin to + /// close and the first lease period of the quadruplet that is auctioned. + AuctionStarted { + auction_index: AuctionIndex, + lease_period: LeasePeriodOf, + ending: BlockNumberFor, + }, + /// An auction ended. All funds become unreserved. + AuctionClosed { auction_index: AuctionIndex }, + /// Funds were reserved for a winning bid. First balance is the extra amount reserved. + /// Second is the total. + Reserved { bidder: T::AccountId, extra_reserved: BalanceOf, total_amount: BalanceOf }, + /// Funds were unreserved since bidder is no longer active. `[bidder, amount]` + Unreserved { bidder: T::AccountId, amount: BalanceOf }, + /// Someone attempted to lease the same slot twice for a parachain. The amount is held in + /// reserve but no parachain slot has been leased. + ReserveConfiscated { para_id: ParaId, leaser: T::AccountId, amount: BalanceOf }, + /// A new bid has been accepted as the current winner. + BidAccepted { + bidder: T::AccountId, + para_id: ParaId, + amount: BalanceOf, + first_slot: LeasePeriodOf, + last_slot: LeasePeriodOf, + }, + /// The winning offset was chosen for an auction. This will map into the `Winning` storage + /// map. + WinningOffset { auction_index: AuctionIndex, block_number: BlockNumberFor }, + } + + #[pallet::error] + pub enum Error { + /// This auction is already in progress. + AuctionInProgress, + /// The lease period is in the past. + LeasePeriodInPast, + /// Para is not registered + ParaNotRegistered, + /// Not a current auction. + NotCurrentAuction, + /// Not an auction. + NotAuction, + /// Auction has already ended. + AuctionEnded, + /// The para is already leased out for part of this range. + AlreadyLeasedOut, + } + + /// Number of auctions started so far. + #[pallet::storage] + #[pallet::getter(fn auction_counter)] + pub type AuctionCounter = StorageValue<_, AuctionIndex, ValueQuery>; + + /// Information relating to the current auction, if there is one. + /// + /// The first item in the tuple is the lease period index that the first of the four + /// contiguous lease periods on auction is for. The second is the block number when the + /// auction will "begin to end", i.e. the first block of the Ending Period of the auction. + #[pallet::storage] + #[pallet::getter(fn auction_info)] + pub type AuctionInfo = StorageValue<_, (LeasePeriodOf, BlockNumberFor)>; + + /// Amounts currently reserved in the accounts of the bidders currently winning + /// (sub-)ranges. + #[pallet::storage] + #[pallet::getter(fn reserved_amounts)] + pub type ReservedAmounts = + StorageMap<_, Twox64Concat, (T::AccountId, ParaId), BalanceOf>; + + /// The winning bids for each of the 10 ranges at each sample in the final Ending Period of + /// the current auction. The map's key is the 0-based index into the Sample Size. The + /// first sample of the ending period is 0; the last is `Sample Size - 1`. + #[pallet::storage] + #[pallet::getter(fn winning)] + pub type Winning = StorageMap<_, Twox64Concat, BlockNumberFor, WinningData>; + + #[pallet::extra_constants] + impl Pallet { + #[pallet::constant_name(SlotRangeCount)] + fn slot_range_count() -> u32 { + SlotRange::SLOT_RANGE_COUNT as u32 + } + + #[pallet::constant_name(LeasePeriodsPerSlot)] + fn lease_periods_per_slot() -> u32 { + SlotRange::LEASE_PERIODS_PER_SLOT as u32 + } + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(n: BlockNumberFor) -> Weight { + let mut weight = T::DbWeight::get().reads(1); + + // If the current auction was in its ending period last block, then ensure that the + // (sub-)range winner information is duplicated from the previous block in case no bids + // happened in the last block. + if let AuctionStatus::EndingPeriod(offset, _sub_sample) = Self::auction_status(n) { + weight = weight.saturating_add(T::DbWeight::get().reads(1)); + if !Winning::::contains_key(&offset) { + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + let winning_data = offset + .checked_sub(&One::one()) + .and_then(Winning::::get) + .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); + Winning::::insert(offset, winning_data); + } + } + + // Check to see if an auction just ended. + if let Some((winning_ranges, auction_lease_period_index)) = Self::check_auction_end(n) { + // Auction is ended now. We have the winning ranges and the lease period index which + // acts as the offset. Handle it. + Self::manage_auction_end(auction_lease_period_index, winning_ranges); + weight = weight.saturating_add(T::WeightInfo::on_initialize()); + } + + weight + } + } + + #[pallet::call] + impl Pallet { + /// Create a new auction. + /// + /// This can only happen when there isn't already an auction in progress and may only be + /// called by the root origin. Accepts the `duration` of this auction and the + /// `lease_period_index` of the initial lease period of the four that are to be auctioned. + #[pallet::call_index(0)] + #[pallet::weight((T::WeightInfo::new_auction(), DispatchClass::Operational))] + pub fn new_auction( + origin: OriginFor, + #[pallet::compact] duration: BlockNumberFor, + #[pallet::compact] lease_period_index: LeasePeriodOf, + ) -> DispatchResult { + T::InitiateOrigin::ensure_origin(origin)?; + Self::do_new_auction(duration, lease_period_index) + } + + /// Make a new bid from an account (including a parachain account) for deploying a new + /// parachain. + /// + /// Multiple simultaneous bids from the same bidder are allowed only as long as all active + /// bids overlap each other (i.e. are mutually exclusive). Bids cannot be redacted. + /// + /// - `sub` is the sub-bidder ID, allowing for multiple competing bids to be made by (and + /// funded by) the same account. + /// - `auction_index` is the index of the auction to bid on. Should just be the present + /// value of `AuctionCounter`. + /// - `first_slot` is the first lease period index of the range to bid on. This is the + /// absolute lease period index value, not an auction-specific offset. + /// - `last_slot` is the last lease period index of the range to bid on. This is the + /// absolute lease period index value, not an auction-specific offset. + /// - `amount` is the amount to bid to be held as deposit for the parachain should the + /// bid win. This amount is held throughout the range. + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::bid())] + pub fn bid( + origin: OriginFor, + #[pallet::compact] para: ParaId, + #[pallet::compact] auction_index: AuctionIndex, + #[pallet::compact] first_slot: LeasePeriodOf, + #[pallet::compact] last_slot: LeasePeriodOf, + #[pallet::compact] amount: BalanceOf, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::handle_bid(who, para, auction_index, first_slot, last_slot, amount)?; + Ok(()) + } + + /// Cancel an in-progress auction. + /// + /// Can only be called by Root origin. + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::cancel_auction())] + pub fn cancel_auction(origin: OriginFor) -> DispatchResult { + ensure_root(origin)?; + // Unreserve all bids. + for ((bidder, _), amount) in ReservedAmounts::::drain() { + CurrencyOf::::unreserve(&bidder, amount); + } + #[allow(deprecated)] + Winning::::remove_all(None); + AuctionInfo::::kill(); + Ok(()) + } + } +} + +impl Auctioneer> for Pallet { + type AccountId = T::AccountId; + type LeasePeriod = BlockNumberFor; + type Currency = CurrencyOf; + + fn new_auction( + duration: BlockNumberFor, + lease_period_index: LeasePeriodOf, + ) -> DispatchResult { + Self::do_new_auction(duration, lease_period_index) + } + + // Returns the status of the auction given the current block number. + fn auction_status(now: BlockNumberFor) -> AuctionStatus> { + let early_end = match AuctionInfo::::get() { + Some((_, early_end)) => early_end, + None => return AuctionStatus::NotStarted, + }; + + let after_early_end = match now.checked_sub(&early_end) { + Some(after_early_end) => after_early_end, + None => return AuctionStatus::StartingPeriod, + }; + + let ending_period = T::EndingPeriod::get(); + if after_early_end < ending_period { + let sample_length = T::SampleLength::get().max(One::one()); + let sample = after_early_end / sample_length; + let sub_sample = after_early_end % sample_length; + return AuctionStatus::EndingPeriod(sample, sub_sample) + } else { + // This is safe because of the comparison operator above + return AuctionStatus::VrfDelay(after_early_end - ending_period) + } + } + + fn place_bid( + bidder: T::AccountId, + para: ParaId, + first_slot: LeasePeriodOf, + last_slot: LeasePeriodOf, + amount: BalanceOf, + ) -> DispatchResult { + Self::handle_bid(bidder, para, AuctionCounter::::get(), first_slot, last_slot, amount) + } + + fn lease_period_index(b: BlockNumberFor) -> Option<(Self::LeasePeriod, bool)> { + T::Leaser::lease_period_index(b) + } + + #[cfg(any(feature = "runtime-benchmarks", test))] + fn lease_period_length() -> (BlockNumberFor, BlockNumberFor) { + T::Leaser::lease_period_length() + } + + fn has_won_an_auction(para: ParaId, bidder: &T::AccountId) -> bool { + !T::Leaser::deposit_held(para, bidder).is_zero() + } +} + +impl Pallet { + // A trick to allow me to initialize large arrays with nothing in them. + const EMPTY: Option<(::AccountId, ParaId, BalanceOf)> = None; + + /// Create a new auction. + /// + /// This can only happen when there isn't already an auction in progress. Accepts the `duration` + /// of this auction and the `lease_period_index` of the initial lease period of the four that + /// are to be auctioned. + fn do_new_auction( + duration: BlockNumberFor, + lease_period_index: LeasePeriodOf, + ) -> DispatchResult { + let maybe_auction = AuctionInfo::::get(); + ensure!(maybe_auction.is_none(), Error::::AuctionInProgress); + let now = frame_system::Pallet::::block_number(); + if let Some((current_lease_period, _)) = T::Leaser::lease_period_index(now) { + // If there is no active lease period, then we don't need to make this check. + ensure!(lease_period_index >= current_lease_period, Error::::LeasePeriodInPast); + } + + // Bump the counter. + let n = AuctionCounter::::mutate(|n| { + *n += 1; + *n + }); + + // Set the information. + let ending = frame_system::Pallet::::block_number().saturating_add(duration); + AuctionInfo::::put((lease_period_index, ending)); + + Self::deposit_event(Event::::AuctionStarted { + auction_index: n, + lease_period: lease_period_index, + ending, + }); + Ok(()) + } + + /// Actually place a bid in the current auction. + /// + /// - `bidder`: The account that will be funding this bid. + /// - `auction_index`: The auction index of the bid. For this to succeed, must equal + /// the current value of `AuctionCounter`. + /// - `first_slot`: The first lease period index of the range to be bid on. + /// - `last_slot`: The last lease period index of the range to be bid on (inclusive). + /// - `amount`: The total amount to be the bid for deposit over the range. + pub fn handle_bid( + bidder: T::AccountId, + para: ParaId, + auction_index: u32, + first_slot: LeasePeriodOf, + last_slot: LeasePeriodOf, + amount: BalanceOf, + ) -> DispatchResult { + // Ensure para is registered before placing a bid on it. + ensure!(T::Registrar::is_registered(para), Error::::ParaNotRegistered); + // Bidding on latest auction. + ensure!(auction_index == AuctionCounter::::get(), Error::::NotCurrentAuction); + // Assume it's actually an auction (this should never fail because of above). + let (first_lease_period, _) = AuctionInfo::::get().ok_or(Error::::NotAuction)?; + + // Get the auction status and the current sample block. For the starting period, the sample + // block is zero. + let auction_status = Self::auction_status(frame_system::Pallet::::block_number()); + // The offset into the ending samples of the auction. + let offset = match auction_status { + AuctionStatus::NotStarted => return Err(Error::::AuctionEnded.into()), + AuctionStatus::StartingPeriod => Zero::zero(), + AuctionStatus::EndingPeriod(o, _) => o, + AuctionStatus::VrfDelay(_) => return Err(Error::::AuctionEnded.into()), + }; + + // We also make sure that the bid is not for any existing leases the para already has. + ensure!( + !T::Leaser::already_leased(para, first_slot, last_slot), + Error::::AlreadyLeasedOut + ); + + // Our range. + let range = SlotRange::new_bounded(first_lease_period, first_slot, last_slot)?; + // Range as an array index. + let range_index = range as u8 as usize; + + // The current winning ranges. + let mut current_winning = Winning::::get(offset) + .or_else(|| offset.checked_sub(&One::one()).and_then(Winning::::get)) + .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); + + // If this bid beat the previous winner of our range. + if current_winning[range_index].as_ref().map_or(true, |last| amount > last.2) { + // Ok; we are the new winner of this range - reserve the additional amount and record. + + // Get the amount already held on deposit if this is a renewal bid (i.e. there's + // an existing lease on the same para by the same leaser). + let existing_lease_deposit = T::Leaser::deposit_held(para, &bidder); + let reserve_required = amount.saturating_sub(existing_lease_deposit); + + // Get the amount already reserved in any prior and still active bids by us. + let bidder_para = (bidder.clone(), para); + let already_reserved = ReservedAmounts::::get(&bidder_para).unwrap_or_default(); + + // If these don't already cover the bid... + if let Some(additional) = reserve_required.checked_sub(&already_reserved) { + // ...then reserve some more funds from their account, failing if there's not + // enough funds. + CurrencyOf::::reserve(&bidder, additional)?; + // ...and record the amount reserved. + ReservedAmounts::::insert(&bidder_para, reserve_required); + + Self::deposit_event(Event::::Reserved { + bidder: bidder.clone(), + extra_reserved: additional, + total_amount: reserve_required, + }); + } + + // Return any funds reserved for the previous winner if we are not in the ending period + // and they no longer have any active bids. + let mut outgoing_winner = Some((bidder.clone(), para, amount)); + swap(&mut current_winning[range_index], &mut outgoing_winner); + if let Some((who, para, _amount)) = outgoing_winner { + if auction_status.is_starting() && + current_winning + .iter() + .filter_map(Option::as_ref) + .all(|&(ref other, other_para, _)| other != &who || other_para != para) + { + // Previous bidder is no longer winning any ranges: unreserve their funds. + if let Some(amount) = ReservedAmounts::::take(&(who.clone(), para)) { + // It really should be reserved; there's not much we can do here on fail. + let err_amt = CurrencyOf::::unreserve(&who, amount); + debug_assert!(err_amt.is_zero()); + Self::deposit_event(Event::::Unreserved { bidder: who, amount }); + } + } + } + + // Update the range winner. + Winning::::insert(offset, ¤t_winning); + Self::deposit_event(Event::::BidAccepted { + bidder, + para_id: para, + amount, + first_slot, + last_slot, + }); + } + Ok(()) + } + + /// Some when the auction's end is known (with the end block number). None if it is unknown. + /// If `Some` then the block number must be at most the previous block and at least the + /// previous block minus `T::EndingPeriod::get()`. + /// + /// This mutates the state, cleaning up `AuctionInfo` and `Winning` in the case of an auction + /// ending. An immediately subsequent call with the same argument will always return `None`. + fn check_auction_end(now: BlockNumberFor) -> Option<(WinningData, LeasePeriodOf)> { + if let Some((lease_period_index, early_end)) = AuctionInfo::::get() { + let ending_period = T::EndingPeriod::get(); + let late_end = early_end.saturating_add(ending_period); + let is_ended = now >= late_end; + if is_ended { + // auction definitely ended. + // check to see if we can determine the actual ending point. + let (raw_offset, known_since) = T::Randomness::random(&b"para_auction"[..]); + + if late_end <= known_since { + // Our random seed was known only after the auction ended. Good to use. + let raw_offset_block_number = >::decode( + &mut raw_offset.as_ref(), + ) + .expect("secure hashes should always be bigger than the block number; qed"); + let offset = (raw_offset_block_number % ending_period) / + T::SampleLength::get().max(One::one()); + + let auction_counter = AuctionCounter::::get(); + Self::deposit_event(Event::::WinningOffset { + auction_index: auction_counter, + block_number: offset, + }); + let res = Winning::::get(offset) + .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); + // This `remove_all` statement should remove at most `EndingPeriod` / + // `SampleLength` items, which should be bounded and sensibly configured in the + // runtime. + #[allow(deprecated)] + Winning::::remove_all(None); + AuctionInfo::::kill(); + return Some((res, lease_period_index)) + } + } + } + None + } + + /// Auction just ended. We have the current lease period, the auction's lease period (which + /// is guaranteed to be at least the current period) and the bidders that were winning each + /// range at the time of the auction's close. + fn manage_auction_end( + auction_lease_period_index: LeasePeriodOf, + winning_ranges: WinningData, + ) { + // First, unreserve all amounts that were reserved for the bids. We will later re-reserve + // the amounts from the bidders that ended up being assigned the slot so there's no need to + // special-case them here. + for ((bidder, _), amount) in ReservedAmounts::::drain() { + CurrencyOf::::unreserve(&bidder, amount); + } + + // Next, calculate the winning combination of slots and thus the final winners of the + // auction. + let winners = Self::calculate_winners(winning_ranges); + + // Go through those winners and re-reserve their bid, updating our table of deposits + // accordingly. + for (leaser, para, amount, range) in winners.into_iter() { + let begin_offset = LeasePeriodOf::::from(range.as_pair().0 as u32); + let period_begin = auction_lease_period_index + begin_offset; + let period_count = LeasePeriodOf::::from(range.len() as u32); + + match T::Leaser::lease_out(para, &leaser, amount, period_begin, period_count) { + Err(LeaseError::ReserveFailed) | + Err(LeaseError::AlreadyEnded) | + Err(LeaseError::NoLeasePeriod) => { + // Should never happen since we just unreserved this amount (and our offset is + // from the present period). But if it does, there's not much we can do. + }, + Err(LeaseError::AlreadyLeased) => { + // The leaser attempted to get a second lease on the same para ID, possibly + // griefing us. Let's keep the amount reserved and let governance sort it out. + if CurrencyOf::::reserve(&leaser, amount).is_ok() { + Self::deposit_event(Event::::ReserveConfiscated { + para_id: para, + leaser, + amount, + }); + } + }, + Ok(()) => {}, // Nothing to report. + } + } + + Self::deposit_event(Event::::AuctionClosed { + auction_index: AuctionCounter::::get(), + }); + } + + /// Calculate the final winners from the winning slots. + /// + /// This is a simple dynamic programming algorithm designed by Al, the original code is at: + /// `https://github.com/w3f/consensus/blob/master/NPoS/auctiondynamicthing.py` + fn calculate_winners(mut winning: WinningData) -> WinnersData { + let winning_ranges = { + let mut best_winners_ending_at: [(Vec, BalanceOf); + SlotRange::LEASE_PERIODS_PER_SLOT] = Default::default(); + let best_bid = |range: SlotRange| { + winning[range as u8 as usize] + .as_ref() + .map(|(_, _, amount)| *amount * (range.len() as u32).into()) + }; + for i in 0..SlotRange::LEASE_PERIODS_PER_SLOT { + let r = SlotRange::new_bounded(0, 0, i as u32).expect("`i < LPPS`; qed"); + if let Some(bid) = best_bid(r) { + best_winners_ending_at[i] = (vec![r], bid); + } + for j in 0..i { + let r = SlotRange::new_bounded(0, j as u32 + 1, i as u32) + .expect("`i < LPPS`; `j < i`; `j + 1 < LPPS`; qed"); + if let Some(mut bid) = best_bid(r) { + bid += best_winners_ending_at[j].1; + if bid > best_winners_ending_at[i].1 { + let mut new_winners = best_winners_ending_at[j].0.clone(); + new_winners.push(r); + best_winners_ending_at[i] = (new_winners, bid); + } + } else { + if best_winners_ending_at[j].1 > best_winners_ending_at[i].1 { + best_winners_ending_at[i] = best_winners_ending_at[j].clone(); + } + } + } + } + best_winners_ending_at[SlotRange::LEASE_PERIODS_PER_SLOT - 1].0.clone() + }; + + winning_ranges + .into_iter() + .filter_map(|range| { + winning[range as u8 as usize] + .take() + .map(|(bidder, para, amount)| (bidder, para, amount, range)) + }) + .collect::>() + } +} + +/// tests for this module +#[cfg(test)] +mod tests { + use super::*; + use crate::{auctions, mock::TestRegistrar}; + use ::test_helpers::{dummy_hash, dummy_head_data, dummy_validation_code}; + use frame_support::{ + assert_noop, assert_ok, assert_storage_noop, + dispatch::DispatchError::BadOrigin, + ord_parameter_types, parameter_types, + traits::{ConstU32, EitherOfDiverse, OnFinalize, OnInitialize}, + }; + use frame_system::{EnsureRoot, EnsureSignedBy}; + use pallet_balances; + use primitives::{BlockNumber, Id as ParaId}; + use sp_core::H256; + use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + BuildStorage, + }; + use std::{cell::RefCell, collections::BTreeMap}; + + type Block = frame_system::mocking::MockBlockU32; + + frame_support::construct_runtime!( + pub enum Test + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Auctions: auctions::{Pallet, Call, Storage, Event}, + } + ); + + parameter_types! { + pub const BlockHashCount: u32 = 250; + } + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + } + + parameter_types! { + pub const ExistentialDeposit: u64 = 1; + pub const MaxReserves: u32 = 50; + } + + impl pallet_balances::Config for Test { + type Balance = u64; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxLocks = (); + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<1>; + type MaxFreezes = ConstU32<1>; + } + + #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug)] + pub struct LeaseData { + leaser: u64, + amount: u64, + } + + thread_local! { + pub static LEASES: + RefCell> = RefCell::new(BTreeMap::new()); + } + + fn leases() -> Vec<((ParaId, BlockNumber), LeaseData)> { + LEASES.with(|p| (&*p.borrow()).clone().into_iter().collect::>()) + } + + pub struct TestLeaser; + impl Leaser for TestLeaser { + type AccountId = u64; + type LeasePeriod = BlockNumber; + type Currency = Balances; + + fn lease_out( + para: ParaId, + leaser: &Self::AccountId, + amount: >::Balance, + period_begin: Self::LeasePeriod, + period_count: Self::LeasePeriod, + ) -> Result<(), LeaseError> { + LEASES.with(|l| { + let mut leases = l.borrow_mut(); + let now = System::block_number(); + let (current_lease_period, _) = + Self::lease_period_index(now).ok_or(LeaseError::NoLeasePeriod)?; + if period_begin < current_lease_period { + return Err(LeaseError::AlreadyEnded) + } + for period in period_begin..(period_begin + period_count) { + if leases.contains_key(&(para, period)) { + return Err(LeaseError::AlreadyLeased) + } + leases.insert((para, period), LeaseData { leaser: *leaser, amount }); + } + Ok(()) + }) + } + + fn deposit_held( + para: ParaId, + leaser: &Self::AccountId, + ) -> >::Balance { + leases() + .iter() + .filter_map(|((id, _period), data)| { + if id == ¶ && &data.leaser == leaser { + Some(data.amount) + } else { + None + } + }) + .max() + .unwrap_or_default() + } + + fn lease_period_length() -> (BlockNumber, BlockNumber) { + (10, 0) + } + + fn lease_period_index(b: BlockNumber) -> Option<(Self::LeasePeriod, bool)> { + let (lease_period_length, offset) = Self::lease_period_length(); + let b = b.checked_sub(offset)?; + + let lease_period = b / lease_period_length; + let first_block = (b % lease_period_length).is_zero(); + + Some((lease_period, first_block)) + } + + fn already_leased( + para_id: ParaId, + first_period: Self::LeasePeriod, + last_period: Self::LeasePeriod, + ) -> bool { + leases().into_iter().any(|((para, period), _data)| { + para == para_id && first_period <= period && period <= last_period + }) + } + } + + ord_parameter_types! { + pub const Six: u64 = 6; + } + + type RootOrSix = EitherOfDiverse, EnsureSignedBy>; + + thread_local! { + pub static LAST_RANDOM: RefCell> = RefCell::new(None); + } + fn set_last_random(output: H256, known_since: u32) { + LAST_RANDOM.with(|p| *p.borrow_mut() = Some((output, known_since))) + } + pub struct TestPastRandomness; + impl Randomness for TestPastRandomness { + fn random(_subject: &[u8]) -> (H256, u32) { + LAST_RANDOM.with(|p| { + if let Some((output, known_since)) = &*p.borrow() { + (*output, *known_since) + } else { + (H256::zero(), frame_system::Pallet::::block_number()) + } + }) + } + } + + parameter_types! { + pub static EndingPeriod: BlockNumber = 3; + pub static SampleLength: BlockNumber = 1; + } + + impl Config for Test { + type RuntimeEvent = RuntimeEvent; + type Leaser = TestLeaser; + type Registrar = TestRegistrar; + type EndingPeriod = EndingPeriod; + type SampleLength = SampleLength; + type Randomness = TestPastRandomness; + type InitiateOrigin = RootOrSix; + type WeightInfo = crate::auctions::TestWeightInfo; + } + + // This function basically just builds a genesis storage key/value store according to + // our desired mock up. + pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + } + .assimilate_storage(&mut t) + .unwrap(); + let mut ext: sp_io::TestExternalities = t.into(); + ext.execute_with(|| { + // Register para 0, 1, 2, and 3 for tests + assert_ok!(TestRegistrar::::register( + 1, + 0.into(), + dummy_head_data(), + dummy_validation_code() + )); + assert_ok!(TestRegistrar::::register( + 1, + 1.into(), + dummy_head_data(), + dummy_validation_code() + )); + assert_ok!(TestRegistrar::::register( + 1, + 2.into(), + dummy_head_data(), + dummy_validation_code() + )); + assert_ok!(TestRegistrar::::register( + 1, + 3.into(), + dummy_head_data(), + dummy_validation_code() + )); + }); + ext + } + + fn run_to_block(n: BlockNumber) { + while System::block_number() < n { + Auctions::on_finalize(System::block_number()); + Balances::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + System::set_block_number(System::block_number() + 1); + System::on_initialize(System::block_number()); + Balances::on_initialize(System::block_number()); + Auctions::on_initialize(System::block_number()); + } + } + + #[test] + fn basic_setup_works() { + new_test_ext().execute_with(|| { + assert_eq!(AuctionCounter::::get(), 0); + assert_eq!(TestLeaser::deposit_held(0u32.into(), &1), 0); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + + run_to_block(10); + + assert_eq!(AuctionCounter::::get(), 0); + assert_eq!(TestLeaser::deposit_held(0u32.into(), &1), 0); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + }); + } + + #[test] + fn can_start_auction() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_noop!(Auctions::new_auction(RuntimeOrigin::signed(1), 5, 1), BadOrigin); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + + assert_eq!(AuctionCounter::::get(), 1); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + }); + } + + #[test] + fn bidding_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5)); + + assert_eq!(Balances::reserved_balance(1), 5); + assert_eq!(Balances::free_balance(1), 5); + assert_eq!( + Auctions::winning(0).unwrap()[SlotRange::ZeroThree as u8 as usize], + Some((1, 0.into(), 5)) + ); + }); + } + + #[test] + fn under_bidding_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5)); + + assert_storage_noop!({ + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 0.into(), 1, 1, 4, 1)); + }); + }); + } + + #[test] + fn over_bidding_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 0.into(), 1, 1, 4, 6)); + + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::reserved_balance(2), 6); + assert_eq!(Balances::free_balance(2), 14); + assert_eq!( + Auctions::winning(0).unwrap()[SlotRange::ZeroThree as u8 as usize], + Some((2, 0.into(), 6)) + ); + }); + } + + #[test] + fn auction_proceeds_correctly() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + + assert_eq!(AuctionCounter::::get(), 1); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(2); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(3); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(4); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(5); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(6); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); + + run_to_block(7); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); + + run_to_block(8); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); + + run_to_block(9); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + }); + } + + #[test] + fn can_win_auction() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1)); + assert_eq!(Balances::reserved_balance(1), 1); + assert_eq!(Balances::free_balance(1), 9); + run_to_block(9); + + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 4), LeaseData { leaser: 1, amount: 1 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); + }); + } + + #[test] + fn can_win_auction_with_late_randomness() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1)); + assert_eq!(Balances::reserved_balance(1), 1); + assert_eq!(Balances::free_balance(1), 9); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + run_to_block(8); + // Auction has not yet ended. + assert_eq!(leases(), vec![]); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); + // This will prevent the auction's winner from being decided in the next block, since + // the random seed was known before the final bids were made. + set_last_random(H256::zero(), 8); + // Auction definitely ended now, but we don't know exactly when in the last 3 blocks yet + // since no randomness available yet. + run_to_block(9); + // Auction has now ended... But auction winner still not yet decided, so no leases yet. + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::VrfDelay(0) + ); + assert_eq!(leases(), vec![]); + + // Random seed now updated to a value known at block 9, when the auction ended. This + // means that the winner can now be chosen. + set_last_random(H256::zero(), 9); + run_to_block(10); + // Auction ended and winner selected + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 4), LeaseData { leaser: 1, amount: 1 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); + }); + } + + #[test] + fn can_win_incomplete_auction() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 4, 4, 5)); + run_to_block(9); + + assert_eq!(leases(), vec![((0.into(), 4), LeaseData { leaser: 1, amount: 5 }),]); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); + }); + } + + #[test] + fn should_choose_best_combination() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 0.into(), 1, 2, 3, 4)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), 0.into(), 1, 4, 4, 2)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 1.into(), 1, 1, 4, 2)); + run_to_block(9); + + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 2), LeaseData { leaser: 2, amount: 4 }), + ((0.into(), 3), LeaseData { leaser: 2, amount: 4 }), + ((0.into(), 4), LeaseData { leaser: 3, amount: 2 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); + assert_eq!(TestLeaser::deposit_held(1.into(), &1), 0); + assert_eq!(TestLeaser::deposit_held(0.into(), &2), 4); + assert_eq!(TestLeaser::deposit_held(0.into(), &3), 2); + }); + } + + #[test] + fn gap_bid_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + + // User 1 will make a bid for period 1 and 4 for the same Para 0 + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 4, 4, 4)); + + // User 2 and 3 will make a bid for para 1 on period 2 and 3 respectively + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 1.into(), 1, 2, 2, 2)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), 1.into(), 1, 3, 3, 3)); + + // Total reserved should be the max of the two + assert_eq!(Balances::reserved_balance(1), 4); + + // Other people are reserved correctly too + assert_eq!(Balances::reserved_balance(2), 2); + assert_eq!(Balances::reserved_balance(3), 3); + + // End the auction. + run_to_block(9); + + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 4), LeaseData { leaser: 1, amount: 4 }), + ((1.into(), 2), LeaseData { leaser: 2, amount: 2 }), + ((1.into(), 3), LeaseData { leaser: 3, amount: 3 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 4); + assert_eq!(TestLeaser::deposit_held(1.into(), &2), 2); + assert_eq!(TestLeaser::deposit_held(1.into(), &3), 3); + }); + } + + #[test] + fn deposit_credit_should_work() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 5)); + assert_eq!(Balances::reserved_balance(1), 5); + run_to_block(10); + + assert_eq!(leases(), vec![((0.into(), 1), LeaseData { leaser: 1, amount: 5 }),]); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); + + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 2)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 2, 2, 6)); + // Only 1 reserved since we have a deposit credit of 5. + assert_eq!(Balances::reserved_balance(1), 1); + run_to_block(20); + + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), + ((0.into(), 2), LeaseData { leaser: 1, amount: 6 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 6); + }); + } + + #[test] + fn deposit_credit_on_alt_para_should_not_count() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 5)); + assert_eq!(Balances::reserved_balance(1), 5); + run_to_block(10); + + assert_eq!(leases(), vec![((0.into(), 1), LeaseData { leaser: 1, amount: 5 }),]); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); + + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 2)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 1.into(), 2, 2, 2, 6)); + // 6 reserved since we are bidding on a new para; only works because we don't + assert_eq!(Balances::reserved_balance(1), 6); + run_to_block(20); + + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), + ((1.into(), 2), LeaseData { leaser: 1, amount: 6 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); + assert_eq!(TestLeaser::deposit_held(1.into(), &1), 6); + }); + } + + #[test] + fn multiple_bids_work_pre_ending() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + + for i in 1..6u64 { + run_to_block(i as _); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(i), 0.into(), 1, 1, 4, i)); + for j in 1..6 { + assert_eq!(Balances::reserved_balance(j), if j == i { j } else { 0 }); + assert_eq!(Balances::free_balance(j), if j == i { j * 9 } else { j * 10 }); + } + } + + run_to_block(9); + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 5, amount: 5 }), + ((0.into(), 2), LeaseData { leaser: 5, amount: 5 }), + ((0.into(), 3), LeaseData { leaser: 5, amount: 5 }), + ((0.into(), 4), LeaseData { leaser: 5, amount: 5 }), + ] + ); + }); + } + + #[test] + fn multiple_bids_work_post_ending() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 0, 1)); + + for i in 1..6u64 { + run_to_block(((i - 1) / 2 + 1) as _); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(i), 0.into(), 1, 1, 4, i)); + for j in 1..6 { + assert_eq!(Balances::reserved_balance(j), if j <= i { j } else { 0 }); + assert_eq!(Balances::free_balance(j), if j <= i { j * 9 } else { j * 10 }); + } + } + for i in 1..6u64 { + assert_eq!(ReservedAmounts::::get((i, ParaId::from(0))).unwrap(), i); + } + + run_to_block(5); + assert_eq!( + leases(), + (1..=4) + .map(|i| ((0.into(), i), LeaseData { leaser: 2, amount: 2 })) + .collect::>() + ); + }); + } + + #[test] + fn incomplete_calculate_winners_works() { + let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; + winning[SlotRange::ThreeThree as u8 as usize] = Some((1, 0.into(), 1)); + + let winners = vec![(1, 0.into(), 1, SlotRange::ThreeThree)]; + + assert_eq!(Auctions::calculate_winners(winning), winners); + } + + #[test] + fn first_incomplete_calculate_winners_works() { + let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; + winning[0] = Some((1, 0.into(), 1)); + + let winners = vec![(1, 0.into(), 1, SlotRange::ZeroZero)]; + + assert_eq!(Auctions::calculate_winners(winning), winners); + } + + #[test] + fn calculate_winners_works() { + let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; + winning[SlotRange::ZeroZero as u8 as usize] = Some((2, 0.into(), 2)); + winning[SlotRange::ZeroThree as u8 as usize] = Some((1, 100.into(), 1)); + winning[SlotRange::OneOne as u8 as usize] = Some((3, 1.into(), 1)); + winning[SlotRange::TwoTwo as u8 as usize] = Some((1, 2.into(), 53)); + winning[SlotRange::ThreeThree as u8 as usize] = Some((5, 3.into(), 1)); + + let winners = vec![ + (2, 0.into(), 2, SlotRange::ZeroZero), + (3, 1.into(), 1, SlotRange::OneOne), + (1, 2.into(), 53, SlotRange::TwoTwo), + (5, 3.into(), 1, SlotRange::ThreeThree), + ]; + assert_eq!(Auctions::calculate_winners(winning), winners); + + winning[SlotRange::ZeroOne as u8 as usize] = Some((4, 10.into(), 3)); + let winners = vec![ + (4, 10.into(), 3, SlotRange::ZeroOne), + (1, 2.into(), 53, SlotRange::TwoTwo), + (5, 3.into(), 1, SlotRange::ThreeThree), + ]; + assert_eq!(Auctions::calculate_winners(winning), winners); + + winning[SlotRange::ZeroThree as u8 as usize] = Some((1, 100.into(), 100)); + let winners = vec![(1, 100.into(), 100, SlotRange::ZeroThree)]; + assert_eq!(Auctions::calculate_winners(winning), winners); + } + + #[test] + fn lower_bids_are_correctly_refunded() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 1, 1)); + let para_1 = ParaId::from(1_u32); + let para_2 = ParaId::from(2_u32); + + // Make a bid and reserve a balance + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), para_1, 1, 1, 4, 9)); + assert_eq!(Balances::reserved_balance(1), 9); + assert_eq!(ReservedAmounts::::get((1, para_1)), Some(9)); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(ReservedAmounts::::get((2, para_2)), None); + + // Bigger bid, reserves new balance and returns funds + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), para_2, 1, 1, 4, 19)); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(ReservedAmounts::::get((1, para_1)), None); + assert_eq!(Balances::reserved_balance(2), 19); + assert_eq!(ReservedAmounts::::get((2, para_2)), Some(19)); + }); + } + + #[test] + fn initialize_winners_in_ending_period_works() { + new_test_ext().execute_with(|| { + assert_eq!(::ExistentialDeposit::get(), 1); + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 1)); + let para_1 = ParaId::from(1_u32); + let para_2 = ParaId::from(2_u32); + let para_3 = ParaId::from(3_u32); + + // Make bids + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), para_1, 1, 1, 4, 9)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), para_2, 1, 3, 4, 19)); + + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; + winning[SlotRange::ZeroThree as u8 as usize] = Some((1, para_1, 9)); + winning[SlotRange::TwoThree as u8 as usize] = Some((2, para_2, 19)); + assert_eq!(Auctions::winning(0), Some(winning)); + + run_to_block(9); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(10); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); + assert_eq!(Auctions::winning(0), Some(winning)); + + run_to_block(11); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); + assert_eq!(Auctions::winning(1), Some(winning)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), para_3, 1, 3, 4, 29)); + + run_to_block(12); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); + winning[SlotRange::TwoThree as u8 as usize] = Some((3, para_3, 29)); + assert_eq!(Auctions::winning(2), Some(winning)); + }); + } + + #[test] + fn handle_bid_requires_registered_para() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_noop!( + Auctions::bid(RuntimeOrigin::signed(1), 1337.into(), 1, 1, 4, 1), + Error::::ParaNotRegistered + ); + assert_ok!(TestRegistrar::::register( + 1, + 1337.into(), + dummy_head_data(), + dummy_validation_code() + )); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 1337.into(), 1, 1, 4, 1)); + }); + } + + #[test] + fn handle_bid_checks_existing_lease_periods() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 2, 3, 1)); + assert_eq!(Balances::reserved_balance(1), 1); + assert_eq!(Balances::free_balance(1), 9); + run_to_block(9); + + assert_eq!( + leases(), + vec![ + ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); + + // Para 1 just won an auction above and won some lease periods. + // No bids can work which overlap these periods. + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_noop!( + Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 1, 4, 1), + Error::::AlreadyLeasedOut, + ); + assert_noop!( + Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 1, 2, 1), + Error::::AlreadyLeasedOut, + ); + assert_noop!( + Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 3, 4, 1), + Error::::AlreadyLeasedOut, + ); + // This is okay, not an overlapping bid. + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 1, 1, 1)); + }); + } + + // Here we will test that taking only 10 samples during the ending period works as expected. + #[test] + fn less_winning_samples_work() { + new_test_ext().execute_with(|| { + assert_eq!(::ExistentialDeposit::get(), 1); + EndingPeriod::set(30); + SampleLength::set(10); + + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 11)); + let para_1 = ParaId::from(1_u32); + let para_2 = ParaId::from(2_u32); + let para_3 = ParaId::from(3_u32); + + // Make bids + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), para_1, 1, 11, 14, 9)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), para_2, 1, 13, 14, 19)); + + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; + winning[SlotRange::ZeroThree as u8 as usize] = Some((1, para_1, 9)); + winning[SlotRange::TwoThree as u8 as usize] = Some((2, para_2, 19)); + assert_eq!(Auctions::winning(0), Some(winning)); + + run_to_block(9); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(10); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); + assert_eq!(Auctions::winning(0), Some(winning)); + + // New bids update the current winning + assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), para_3, 1, 14, 14, 29)); + winning[SlotRange::ThreeThree as u8 as usize] = Some((3, para_3, 29)); + assert_eq!(Auctions::winning(0), Some(winning)); + + run_to_block(20); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); + assert_eq!(Auctions::winning(1), Some(winning)); + run_to_block(25); + // Overbid mid sample + assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), para_3, 1, 13, 14, 29)); + winning[SlotRange::TwoThree as u8 as usize] = Some((3, para_3, 29)); + assert_eq!(Auctions::winning(1), Some(winning)); + + run_to_block(30); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); + assert_eq!(Auctions::winning(2), Some(winning)); + + set_last_random(H256::from([254; 32]), 40); + run_to_block(40); + // Auction ended and winner selected + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + assert_eq!( + leases(), + vec![ + ((3.into(), 13), LeaseData { leaser: 3, amount: 29 }), + ((3.into(), 14), LeaseData { leaser: 3, amount: 29 }), + ] + ); + }); + } + + #[test] + fn auction_status_works() { + new_test_ext().execute_with(|| { + EndingPeriod::set(30); + SampleLength::set(10); + set_last_random(dummy_hash(), 0); + + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 11)); + + run_to_block(9); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(10); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); + + run_to_block(11); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 1) + ); + + run_to_block(19); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 9) + ); + + run_to_block(20); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); + + run_to_block(25); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 5) + ); + + run_to_block(30); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); + + run_to_block(39); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 9) + ); + + run_to_block(40); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::VrfDelay(0) + ); + + run_to_block(44); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::VrfDelay(4) + ); + + set_last_random(dummy_hash(), 45); + run_to_block(45); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + }); + } + + #[test] + fn can_cancel_auction() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1)); + assert_eq!(Balances::reserved_balance(1), 1); + assert_eq!(Balances::free_balance(1), 9); + + assert_noop!(Auctions::cancel_auction(RuntimeOrigin::signed(6)), BadOrigin); + assert_ok!(Auctions::cancel_auction(RuntimeOrigin::root())); + + assert!(AuctionInfo::::get().is_none()); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(ReservedAmounts::::iter().count(), 0); + assert_eq!(Winning::::iter().count(), 0); + }); + } +} + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking { + use super::{Pallet as Auctions, *}; + use frame_support::{ + assert_ok, + traits::{EnsureOrigin, OnInitialize}, + }; + use frame_system::RawOrigin; + use runtime_parachains::paras; + use sp_runtime::{traits::Bounded, SaturatedConversion}; + + use frame_benchmarking::{account, benchmarks, whitelisted_caller, BenchmarkError}; + + fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); + } + + fn fill_winners(lease_period_index: LeasePeriodOf) { + let auction_index = AuctionCounter::::get(); + let minimum_balance = CurrencyOf::::minimum_balance(); + + for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 { + let owner = account("owner", n, 0); + let worst_validation_code = T::Registrar::worst_validation_code(); + let worst_head_data = T::Registrar::worst_head_data(); + CurrencyOf::::make_free_balance_be(&owner, BalanceOf::::max_value()); + + assert!(T::Registrar::register( + owner, + ParaId::from(n), + worst_head_data, + worst_validation_code + ) + .is_ok()); + } + assert_ok!(paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + T::Registrar::worst_validation_code(), + )); + + T::Registrar::execute_pending_transitions(); + + for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 { + let bidder = account("bidder", n, 0); + CurrencyOf::::make_free_balance_be(&bidder, BalanceOf::::max_value()); + + let slot_range = SlotRange::n((n - 1) as u8).unwrap(); + let (start, end) = slot_range.as_pair(); + + assert!(Auctions::::bid( + RawOrigin::Signed(bidder).into(), + ParaId::from(n), + auction_index, + lease_period_index + start.into(), // First Slot + lease_period_index + end.into(), // Last slot + minimum_balance.saturating_mul(n.into()), // Amount + ) + .is_ok()); + } + } + + benchmarks! { + where_clause { where T: pallet_babe::Config + paras::Config } + + new_auction { + let duration = BlockNumberFor::::max_value(); + let lease_period_index = LeasePeriodOf::::max_value(); + let origin = + T::InitiateOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + }: _(origin, duration, lease_period_index) + verify { + assert_last_event::(Event::::AuctionStarted { + auction_index: AuctionCounter::::get(), + lease_period: LeasePeriodOf::::max_value(), + ending: BlockNumberFor::::max_value(), + }.into()); + } + + // Worst case scenario a new bid comes in which kicks out an existing bid for the same slot. + bid { + // If there is an offset, we need to be on that block to be able to do lease things. + let (_, offset) = T::Leaser::lease_period_length(); + frame_system::Pallet::::set_block_number(offset + One::one()); + + // Create a new auction + let duration = BlockNumberFor::::max_value(); + let lease_period_index = LeasePeriodOf::::zero(); + let origin = T::InitiateOrigin::try_successful_origin() + .expect("InitiateOrigin has no successful origin required for the benchmark"); + Auctions::::new_auction(origin, duration, lease_period_index)?; + + let para = ParaId::from(0); + let new_para = ParaId::from(1_u32); + + // Register the paras + let owner = account("owner", 0, 0); + CurrencyOf::::make_free_balance_be(&owner, BalanceOf::::max_value()); + let worst_head_data = T::Registrar::worst_head_data(); + let worst_validation_code = T::Registrar::worst_validation_code(); + T::Registrar::register(owner.clone(), para, worst_head_data.clone(), worst_validation_code.clone())?; + T::Registrar::register(owner, new_para, worst_head_data, worst_validation_code.clone())?; + assert_ok!(paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + worst_validation_code, + )); + + T::Registrar::execute_pending_transitions(); + + // Make an existing bid + let auction_index = AuctionCounter::::get(); + let first_slot = AuctionInfo::::get().unwrap().0; + let last_slot = first_slot + 3u32.into(); + let first_amount = CurrencyOf::::minimum_balance(); + let first_bidder: T::AccountId = account("first_bidder", 0, 0); + CurrencyOf::::make_free_balance_be(&first_bidder, BalanceOf::::max_value()); + Auctions::::bid( + RawOrigin::Signed(first_bidder.clone()).into(), + para, + auction_index, + first_slot, + last_slot, + first_amount, + )?; + + let caller: T::AccountId = whitelisted_caller(); + CurrencyOf::::make_free_balance_be(&caller, BalanceOf::::max_value()); + let bigger_amount = CurrencyOf::::minimum_balance().saturating_mul(10u32.into()); + assert_eq!(CurrencyOf::::reserved_balance(&first_bidder), first_amount); + }: _(RawOrigin::Signed(caller.clone()), new_para, auction_index, first_slot, last_slot, bigger_amount) + verify { + // Confirms that we unreserved funds from a previous bidder, which is worst case scenario. + assert_eq!(CurrencyOf::::reserved_balance(&caller), bigger_amount); + } + + // Worst case: 10 bidders taking all wining spots, and we need to calculate the winner for auction end. + // Entire winner map should be full and removed at the end of the benchmark. + on_initialize { + // If there is an offset, we need to be on that block to be able to do lease things. + let (lease_length, offset) = T::Leaser::lease_period_length(); + frame_system::Pallet::::set_block_number(offset + One::one()); + + // Create a new auction + let duration: BlockNumberFor = lease_length / 2u32.into(); + let lease_period_index = LeasePeriodOf::::zero(); + let now = frame_system::Pallet::::block_number(); + let origin = T::InitiateOrigin::try_successful_origin() + .expect("InitiateOrigin has no successful origin required for the benchmark"); + Auctions::::new_auction(origin, duration, lease_period_index)?; + + fill_winners::(lease_period_index); + + for winner in Winning::::get(BlockNumberFor::::from(0u32)).unwrap().iter() { + assert!(winner.is_some()); + } + + let winning_data = Winning::::get(BlockNumberFor::::from(0u32)).unwrap(); + // Make winning map full + for i in 0u32 .. (T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { + Winning::::insert(BlockNumberFor::::from(i), winning_data.clone()); + } + + // Move ahead to the block we want to initialize + frame_system::Pallet::::set_block_number(duration + now + T::EndingPeriod::get()); + + // Trigger epoch change for new random number value: + { + pallet_babe::Pallet::::on_initialize(duration + now + T::EndingPeriod::get()); + let authorities = pallet_babe::Pallet::::authorities(); + let next_authorities = authorities.clone(); + pallet_babe::Pallet::::enact_epoch_change(authorities, next_authorities, None); + } + + }: { + Auctions::::on_initialize(duration + now + T::EndingPeriod::get()); + } verify { + let auction_index = AuctionCounter::::get(); + assert_last_event::(Event::::AuctionClosed { auction_index }.into()); + assert!(Winning::::iter().count().is_zero()); + } + + // Worst case: 10 bidders taking all wining spots, and winning data is full. + cancel_auction { + // If there is an offset, we need to be on that block to be able to do lease things. + let (lease_length, offset) = T::Leaser::lease_period_length(); + frame_system::Pallet::::set_block_number(offset + One::one()); + + // Create a new auction + let duration: BlockNumberFor = lease_length / 2u32.into(); + let lease_period_index = LeasePeriodOf::::zero(); + let now = frame_system::Pallet::::block_number(); + let origin = T::InitiateOrigin::try_successful_origin() + .expect("InitiateOrigin has no successful origin required for the benchmark"); + Auctions::::new_auction(origin, duration, lease_period_index)?; + + fill_winners::(lease_period_index); + + let winning_data = Winning::::get(BlockNumberFor::::from(0u32)).unwrap(); + for winner in winning_data.iter() { + assert!(winner.is_some()); + } + + // Make winning map full + for i in 0u32 .. (T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { + Winning::::insert(BlockNumberFor::::from(i), winning_data.clone()); + } + assert!(AuctionInfo::::get().is_some()); + }: _(RawOrigin::Root) + verify { + assert!(AuctionInfo::::get().is_none()); + } + + impl_benchmark_test_suite!( + Auctions, + crate::integration_tests::new_test_ext(), + crate::integration_tests::Test, + ); + } +} diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs new file mode 100644 index 0000000000000000000000000000000000000000..9cc06b2bede29808e984230d4c2355073eacaebb --- /dev/null +++ b/polkadot/runtime/common/src/claims.rs @@ -0,0 +1,1696 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// 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 . + +//! Pallet to process claims from Ethereum addresses. + +use frame_support::{ + ensure, + traits::{Currency, Get, IsSubType, VestingSchedule}, + weights::Weight, + DefaultNoBound, +}; +pub use pallet::*; +use parity_scale_codec::{Decode, Encode}; +use primitives::ValidityError; +use scale_info::TypeInfo; +use serde::{self, Deserialize, Deserializer, Serialize, Serializer}; +use sp_io::{crypto::secp256k1_ecdsa_recover, hashing::keccak_256}; +use sp_runtime::{ + traits::{CheckedSub, DispatchInfoOf, SignedExtension, Zero}, + transaction_validity::{ + InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, + }, + RuntimeDebug, +}; +#[cfg(not(feature = "std"))] +use sp_std::alloc::{format, string::String}; +use sp_std::{fmt::Debug, prelude::*}; + +type CurrencyOf = <::VestingSchedule as VestingSchedule< + ::AccountId, +>>::Currency; +type BalanceOf = as Currency<::AccountId>>::Balance; + +pub trait WeightInfo { + fn claim() -> Weight; + fn mint_claim() -> Weight; + fn claim_attest() -> Weight; + fn attest() -> Weight; + fn move_claim() -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn claim() -> Weight { + Weight::zero() + } + fn mint_claim() -> Weight { + Weight::zero() + } + fn claim_attest() -> Weight { + Weight::zero() + } + fn attest() -> Weight { + Weight::zero() + } + fn move_claim() -> Weight { + Weight::zero() + } +} + +/// The kind of statement an account needs to make for a claim to be valid. +#[derive( + Encode, Decode, Clone, Copy, Eq, PartialEq, RuntimeDebug, TypeInfo, Serialize, Deserialize, +)] +pub enum StatementKind { + /// Statement required to be made by non-SAFT holders. + Regular, + /// Statement required to be made by SAFT holders. + Saft, +} + +impl StatementKind { + /// Convert this to the (English) statement it represents. + fn to_text(self) -> &'static [u8] { + match self { + StatementKind::Regular => + &b"I hereby agree to the terms of the statement whose SHA-256 multihash is \ + Qmc1XYqT6S39WNp2UeiRUrZichUWUPpGEThDE6dAb3f6Ny. (This may be found at the URL: \ + https://statement.polkadot.network/regular.html)"[..], + StatementKind::Saft => + &b"I hereby agree to the terms of the statement whose SHA-256 multihash is \ + QmXEkMahfhHJPzT3RjkXiZVFi77ZeVeuxtAjhojGRNYckz. (This may be found at the URL: \ + https://statement.polkadot.network/saft.html)"[..], + } + } +} + +impl Default for StatementKind { + fn default() -> Self { + StatementKind::Regular + } +} + +/// An Ethereum address (i.e. 20 bytes, used to represent an Ethereum account). +/// +/// This gets serialized to the 0x-prefixed hex representation. +#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, Default, RuntimeDebug, TypeInfo)] +pub struct EthereumAddress([u8; 20]); + +impl Serialize for EthereumAddress { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let hex: String = rustc_hex::ToHex::to_hex(&self.0[..]); + serializer.serialize_str(&format!("0x{}", hex)) + } +} + +impl<'de> Deserialize<'de> for EthereumAddress { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let base_string = String::deserialize(deserializer)?; + let offset = if base_string.starts_with("0x") { 2 } else { 0 }; + let s = &base_string[offset..]; + if s.len() != 40 { + Err(serde::de::Error::custom( + "Bad length of Ethereum address (should be 42 including '0x')", + ))?; + } + let raw: Vec = rustc_hex::FromHex::from_hex(s) + .map_err(|e| serde::de::Error::custom(format!("{:?}", e)))?; + let mut r = Self::default(); + r.0.copy_from_slice(&raw); + Ok(r) + } +} + +#[derive(Encode, Decode, Clone, TypeInfo)] +pub struct EcdsaSignature(pub [u8; 65]); + +impl PartialEq for EcdsaSignature { + fn eq(&self, other: &Self) -> bool { + &self.0[..] == &other.0[..] + } +} + +impl sp_std::fmt::Debug for EcdsaSignature { + fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { + write!(f, "EcdsaSignature({:?})", &self.0[..]) + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + /// Configuration trait. + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type VestingSchedule: VestingSchedule>; + #[pallet::constant] + type Prefix: Get<&'static [u8]>; + type MoveClaimOrigin: EnsureOrigin; + type WeightInfo: WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// Someone claimed some DOTs. + Claimed { who: T::AccountId, ethereum_address: EthereumAddress, amount: BalanceOf }, + } + + #[pallet::error] + pub enum Error { + /// Invalid Ethereum signature. + InvalidEthereumSignature, + /// Ethereum address has no claim. + SignerHasNoClaim, + /// Account ID sending transaction has no claim. + SenderHasNoClaim, + /// There's not enough in the pot to pay out some unvested amount. Generally implies a + /// logic error. + PotUnderflow, + /// A needed statement was not included. + InvalidStatement, + /// The account already has a vested balance. + VestedBalanceExists, + } + + #[pallet::storage] + #[pallet::getter(fn claims)] + pub(super) type Claims = StorageMap<_, Identity, EthereumAddress, BalanceOf>; + + #[pallet::storage] + #[pallet::getter(fn total)] + pub(super) type Total = StorageValue<_, BalanceOf, ValueQuery>; + + /// Vesting schedule for a claim. + /// First balance is the total amount that should be held for vesting. + /// Second balance is how much should be unlocked per block. + /// The block number is when the vesting should start. + #[pallet::storage] + #[pallet::getter(fn vesting)] + pub(super) type Vesting = + StorageMap<_, Identity, EthereumAddress, (BalanceOf, BalanceOf, BlockNumberFor)>; + + /// The statement kind that must be signed, if any. + #[pallet::storage] + pub(super) type Signing = StorageMap<_, Identity, EthereumAddress, StatementKind>; + + /// Pre-claimed Ethereum accounts, by the Account ID that they are claimed to. + #[pallet::storage] + pub(super) type Preclaims = StorageMap<_, Identity, T::AccountId, EthereumAddress>; + + #[pallet::genesis_config] + #[derive(DefaultNoBound)] + pub struct GenesisConfig { + pub claims: + Vec<(EthereumAddress, BalanceOf, Option, Option)>, + pub vesting: Vec<(EthereumAddress, (BalanceOf, BalanceOf, BlockNumberFor))>, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + // build `Claims` + self.claims.iter().map(|(a, b, _, _)| (*a, *b)).for_each(|(a, b)| { + Claims::::insert(a, b); + }); + // build `Total` + Total::::put( + self.claims + .iter() + .fold(Zero::zero(), |acc: BalanceOf, &(_, b, _, _)| acc + b), + ); + // build `Vesting` + self.vesting.iter().for_each(|(k, v)| { + Vesting::::insert(k, v); + }); + // build `Signing` + self.claims + .iter() + .filter_map(|(a, _, _, s)| Some((*a, (*s)?))) + .for_each(|(a, s)| { + Signing::::insert(a, s); + }); + // build `Preclaims` + self.claims.iter().filter_map(|(a, _, i, _)| Some((i.clone()?, *a))).for_each( + |(i, a)| { + Preclaims::::insert(i, a); + }, + ); + } + } + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + /// Make a claim to collect your DOTs. + /// + /// The dispatch origin for this call must be _None_. + /// + /// Unsigned Validation: + /// A call to claim is deemed valid if the signature provided matches + /// the expected signed message of: + /// + /// > Ethereum Signed Message: + /// > (configured prefix string)(address) + /// + /// and `address` matches the `dest` account. + /// + /// Parameters: + /// - `dest`: The destination account to payout the claim. + /// - `ethereum_signature`: The signature of an ethereum signed message matching the format + /// described above. + /// + /// + /// The weight of this call is invariant over the input parameters. + /// Weight includes logic to validate unsigned `claim` call. + /// + /// Total Complexity: O(1) + /// + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::claim())] + pub fn claim( + origin: OriginFor, + dest: T::AccountId, + ethereum_signature: EcdsaSignature, + ) -> DispatchResult { + ensure_none(origin)?; + + let data = dest.using_encoded(to_ascii_hex); + let signer = Self::eth_recover(ðereum_signature, &data, &[][..]) + .ok_or(Error::::InvalidEthereumSignature)?; + ensure!(Signing::::get(&signer).is_none(), Error::::InvalidStatement); + + Self::process_claim(signer, dest)?; + Ok(()) + } + + /// Mint a new claim to collect DOTs. + /// + /// The dispatch origin for this call must be _Root_. + /// + /// Parameters: + /// - `who`: The Ethereum address allowed to collect this claim. + /// - `value`: The number of DOTs that will be claimed. + /// - `vesting_schedule`: An optional vesting schedule for these DOTs. + /// + /// + /// The weight of this call is invariant over the input parameters. + /// We assume worst case that both vesting and statement is being inserted. + /// + /// Total Complexity: O(1) + /// + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::mint_claim())] + pub fn mint_claim( + origin: OriginFor, + who: EthereumAddress, + value: BalanceOf, + vesting_schedule: Option<(BalanceOf, BalanceOf, BlockNumberFor)>, + statement: Option, + ) -> DispatchResult { + ensure_root(origin)?; + + >::mutate(|t| *t += value); + >::insert(who, value); + if let Some(vs) = vesting_schedule { + >::insert(who, vs); + } + if let Some(s) = statement { + Signing::::insert(who, s); + } + Ok(()) + } + + /// Make a claim to collect your DOTs by signing a statement. + /// + /// The dispatch origin for this call must be _None_. + /// + /// Unsigned Validation: + /// A call to `claim_attest` is deemed valid if the signature provided matches + /// the expected signed message of: + /// + /// > Ethereum Signed Message: + /// > (configured prefix string)(address)(statement) + /// + /// and `address` matches the `dest` account; the `statement` must match that which is + /// expected according to your purchase arrangement. + /// + /// Parameters: + /// - `dest`: The destination account to payout the claim. + /// - `ethereum_signature`: The signature of an ethereum signed message matching the format + /// described above. + /// - `statement`: The identity of the statement which is being attested to in the + /// signature. + /// + /// + /// The weight of this call is invariant over the input parameters. + /// Weight includes logic to validate unsigned `claim_attest` call. + /// + /// Total Complexity: O(1) + /// + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::claim_attest())] + pub fn claim_attest( + origin: OriginFor, + dest: T::AccountId, + ethereum_signature: EcdsaSignature, + statement: Vec, + ) -> DispatchResult { + ensure_none(origin)?; + + let data = dest.using_encoded(to_ascii_hex); + let signer = Self::eth_recover(ðereum_signature, &data, &statement) + .ok_or(Error::::InvalidEthereumSignature)?; + if let Some(s) = Signing::::get(signer) { + ensure!(s.to_text() == &statement[..], Error::::InvalidStatement); + } + Self::process_claim(signer, dest)?; + Ok(()) + } + + /// Attest to a statement, needed to finalize the claims process. + /// + /// WARNING: Insecure unless your chain includes `PrevalidateAttests` as a + /// `SignedExtension`. + /// + /// Unsigned Validation: + /// A call to attest is deemed valid if the sender has a `Preclaim` registered + /// and provides a `statement` which is expected for the account. + /// + /// Parameters: + /// - `statement`: The identity of the statement which is being attested to in the + /// signature. + /// + /// + /// The weight of this call is invariant over the input parameters. + /// Weight includes logic to do pre-validation on `attest` call. + /// + /// Total Complexity: O(1) + /// + #[pallet::call_index(3)] + #[pallet::weight(( + T::WeightInfo::attest(), + DispatchClass::Normal, + Pays::No + ))] + pub fn attest(origin: OriginFor, statement: Vec) -> DispatchResult { + let who = ensure_signed(origin)?; + let signer = Preclaims::::get(&who).ok_or(Error::::SenderHasNoClaim)?; + if let Some(s) = Signing::::get(signer) { + ensure!(s.to_text() == &statement[..], Error::::InvalidStatement); + } + Self::process_claim(signer, who.clone())?; + Preclaims::::remove(&who); + Ok(()) + } + + #[pallet::call_index(4)] + #[pallet::weight(T::WeightInfo::move_claim())] + pub fn move_claim( + origin: OriginFor, + old: EthereumAddress, + new: EthereumAddress, + maybe_preclaim: Option, + ) -> DispatchResultWithPostInfo { + T::MoveClaimOrigin::try_origin(origin).map(|_| ()).or_else(ensure_root)?; + + Claims::::take(&old).map(|c| Claims::::insert(&new, c)); + Vesting::::take(&old).map(|c| Vesting::::insert(&new, c)); + Signing::::take(&old).map(|c| Signing::::insert(&new, c)); + maybe_preclaim.map(|preclaim| { + Preclaims::::mutate(&preclaim, |maybe_o| { + if maybe_o.as_ref().map_or(false, |o| o == &old) { + *maybe_o = Some(new) + } + }) + }); + Ok(Pays::No.into()) + } + } + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + + fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { + const PRIORITY: u64 = 100; + + let (maybe_signer, maybe_statement) = match call { + // + // The weight of this logic is included in the `claim` dispatchable. + // + Call::claim { dest: account, ethereum_signature } => { + let data = account.using_encoded(to_ascii_hex); + (Self::eth_recover(ðereum_signature, &data, &[][..]), None) + }, + // + // The weight of this logic is included in the `claim_attest` dispatchable. + // + Call::claim_attest { dest: account, ethereum_signature, statement } => { + let data = account.using_encoded(to_ascii_hex); + ( + Self::eth_recover(ðereum_signature, &data, &statement), + Some(statement.as_slice()), + ) + }, + _ => return Err(InvalidTransaction::Call.into()), + }; + + let signer = maybe_signer.ok_or(InvalidTransaction::Custom( + ValidityError::InvalidEthereumSignature.into(), + ))?; + + let e = InvalidTransaction::Custom(ValidityError::SignerHasNoClaim.into()); + ensure!(>::contains_key(&signer), e); + + let e = InvalidTransaction::Custom(ValidityError::InvalidStatement.into()); + match Signing::::get(signer) { + None => ensure!(maybe_statement.is_none(), e), + Some(s) => ensure!(Some(s.to_text()) == maybe_statement, e), + } + + Ok(ValidTransaction { + priority: PRIORITY, + requires: vec![], + provides: vec![("claims", signer).encode()], + longevity: TransactionLongevity::max_value(), + propagate: true, + }) + } + } +} + +/// Converts the given binary data into ASCII-encoded hex. It will be twice the length. +fn to_ascii_hex(data: &[u8]) -> Vec { + let mut r = Vec::with_capacity(data.len() * 2); + let mut push_nibble = |n| r.push(if n < 10 { b'0' + n } else { b'a' - 10 + n }); + for &b in data.iter() { + push_nibble(b / 16); + push_nibble(b % 16); + } + r +} + +impl Pallet { + // Constructs the message that Ethereum RPC's `personal_sign` and `eth_sign` would sign. + fn ethereum_signable_message(what: &[u8], extra: &[u8]) -> Vec { + let prefix = T::Prefix::get(); + let mut l = prefix.len() + what.len() + extra.len(); + let mut rev = Vec::new(); + while l > 0 { + rev.push(b'0' + (l % 10) as u8); + l /= 10; + } + let mut v = b"\x19Ethereum Signed Message:\n".to_vec(); + v.extend(rev.into_iter().rev()); + v.extend_from_slice(prefix); + v.extend_from_slice(what); + v.extend_from_slice(extra); + v + } + + // Attempts to recover the Ethereum address from a message signature signed by using + // the Ethereum RPC's `personal_sign` and `eth_sign`. + fn eth_recover(s: &EcdsaSignature, what: &[u8], extra: &[u8]) -> Option { + let msg = keccak_256(&Self::ethereum_signable_message(what, extra)); + let mut res = EthereumAddress::default(); + res.0 + .copy_from_slice(&keccak_256(&secp256k1_ecdsa_recover(&s.0, &msg).ok()?[..])[12..]); + Some(res) + } + + fn process_claim(signer: EthereumAddress, dest: T::AccountId) -> sp_runtime::DispatchResult { + let balance_due = >::get(&signer).ok_or(Error::::SignerHasNoClaim)?; + + let new_total = Self::total().checked_sub(&balance_due).ok_or(Error::::PotUnderflow)?; + + let vesting = Vesting::::get(&signer); + if vesting.is_some() && T::VestingSchedule::vesting_balance(&dest).is_some() { + return Err(Error::::VestedBalanceExists.into()) + } + + // We first need to deposit the balance to ensure that the account exists. + CurrencyOf::::deposit_creating(&dest, balance_due); + + // Check if this claim should have a vesting schedule. + if let Some(vs) = vesting { + // This can only fail if the account already has a vesting schedule, + // but this is checked above. + T::VestingSchedule::add_vesting_schedule(&dest, vs.0, vs.1, vs.2) + .expect("No other vesting schedule exists, as checked above; qed"); + } + + >::put(new_total); + >::remove(&signer); + >::remove(&signer); + Signing::::remove(&signer); + + // Let's deposit an event to let the outside world know this happened. + Self::deposit_event(Event::::Claimed { + who: dest, + ethereum_address: signer, + amount: balance_due, + }); + + Ok(()) + } +} + +/// Validate `attest` calls prior to execution. Needed to avoid a DoS attack since they are +/// otherwise free to place on chain. +#[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] +#[scale_info(skip_type_params(T))] +pub struct PrevalidateAttests(sp_std::marker::PhantomData) +where + ::RuntimeCall: IsSubType>; + +impl Debug for PrevalidateAttests +where + ::RuntimeCall: IsSubType>, +{ + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "PrevalidateAttests") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +impl PrevalidateAttests +where + ::RuntimeCall: IsSubType>, +{ + /// Create new `SignedExtension` to check runtime version. + pub fn new() -> Self { + Self(sp_std::marker::PhantomData) + } +} + +impl SignedExtension for PrevalidateAttests +where + ::RuntimeCall: IsSubType>, +{ + type AccountId = T::AccountId; + type Call = ::RuntimeCall; + type AdditionalSigned = (); + type Pre = (); + const IDENTIFIER: &'static str = "PrevalidateAttests"; + + fn additional_signed(&self) -> Result { + Ok(()) + } + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) + } + + // + // The weight of this logic is included in the `attest` dispatchable. + // + fn validate( + &self, + who: &Self::AccountId, + call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> TransactionValidity { + if let Some(local_call) = call.is_sub_type() { + if let Call::attest { statement: attested_statement } = local_call { + let signer = Preclaims::::get(who) + .ok_or(InvalidTransaction::Custom(ValidityError::SignerHasNoClaim.into()))?; + if let Some(s) = Signing::::get(signer) { + let e = InvalidTransaction::Custom(ValidityError::InvalidStatement.into()); + ensure!(&attested_statement[..] == s.to_text(), e); + } + } + } + Ok(ValidTransaction::default()) + } +} + +#[cfg(any(test, feature = "runtime-benchmarks"))] +mod secp_utils { + use super::*; + + pub fn public(secret: &libsecp256k1::SecretKey) -> libsecp256k1::PublicKey { + libsecp256k1::PublicKey::from_secret_key(secret) + } + pub fn eth(secret: &libsecp256k1::SecretKey) -> EthereumAddress { + let mut res = EthereumAddress::default(); + res.0.copy_from_slice(&keccak_256(&public(secret).serialize()[1..65])[12..]); + res + } + pub fn sig( + secret: &libsecp256k1::SecretKey, + what: &[u8], + extra: &[u8], + ) -> EcdsaSignature { + let msg = keccak_256(&>::ethereum_signable_message( + &to_ascii_hex(what)[..], + extra, + )); + let (sig, recovery_id) = libsecp256k1::sign(&libsecp256k1::Message::parse(&msg), secret); + let mut r = [0u8; 65]; + r[0..64].copy_from_slice(&sig.serialize()[..]); + r[64] = recovery_id.serialize(); + EcdsaSignature(r) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use hex_literal::hex; + use secp_utils::*; + + use parity_scale_codec::Encode; + use sp_core::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 crate::claims; + use claims::Call as ClaimsCall; + use frame_support::{ + assert_err, assert_noop, assert_ok, + dispatch::{DispatchError::BadOrigin, GetDispatchInfo, Pays}, + ord_parameter_types, parameter_types, + traits::{ConstU32, ExistenceRequirement, WithdrawReasons}, + }; + use pallet_balances; + use sp_runtime::{ + traits::{BlakeTwo256, Identity, IdentityLookup}, + transaction_validity::TransactionLongevity, + BuildStorage, TokenError, + }; + + type Block = frame_system::mocking::MockBlock; + + frame_support::construct_runtime!( + pub enum Test + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Vesting: pallet_vesting::{Pallet, Call, Storage, Config, Event}, + Claims: claims::{Pallet, Call, Storage, Config, Event, ValidateUnsigned}, + } + ); + + parameter_types! { + pub const BlockHashCount: u32 = 250; + } + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + } + + parameter_types! { + pub const ExistentialDeposit: u64 = 1; + } + + impl pallet_balances::Config for Test { + type Balance = u64; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<1>; + type MaxFreezes = ConstU32<1>; + } + + parameter_types! { + pub const MinVestedTransfer: u64 = 1; + pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = + WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); + } + + impl pallet_vesting::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BlockNumberToBalance = Identity; + type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = (); + type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; + const MAX_VESTING_SCHEDULES: u32 = 28; + } + + parameter_types! { + pub Prefix: &'static [u8] = b"Pay RUSTs to the TEST account:"; + } + ord_parameter_types! { + pub const Six: u64 = 6; + } + + impl Config for Test { + type RuntimeEvent = RuntimeEvent; + type VestingSchedule = Vesting; + type Prefix = Prefix; + type MoveClaimOrigin = frame_system::EnsureSignedBy; + type WeightInfo = TestWeightInfo; + } + + fn alice() -> libsecp256k1::SecretKey { + libsecp256k1::SecretKey::parse(&keccak_256(b"Alice")).unwrap() + } + fn bob() -> libsecp256k1::SecretKey { + libsecp256k1::SecretKey::parse(&keccak_256(b"Bob")).unwrap() + } + fn dave() -> libsecp256k1::SecretKey { + libsecp256k1::SecretKey::parse(&keccak_256(b"Dave")).unwrap() + } + fn eve() -> libsecp256k1::SecretKey { + libsecp256k1::SecretKey::parse(&keccak_256(b"Eve")).unwrap() + } + fn frank() -> libsecp256k1::SecretKey { + libsecp256k1::SecretKey::parse(&keccak_256(b"Frank")).unwrap() + } + + // This function basically just builds a genesis storage key/value store according to + // our desired mockup. + pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + // We use default for brevity, but you can configure as desired if needed. + pallet_balances::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); + claims::GenesisConfig:: { + claims: vec![ + (eth(&alice()), 100, None, None), + (eth(&dave()), 200, None, Some(StatementKind::Regular)), + (eth(&eve()), 300, Some(42), Some(StatementKind::Saft)), + (eth(&frank()), 400, Some(43), None), + ], + vesting: vec![(eth(&alice()), (50, 10, 1))], + } + .assimilate_storage(&mut t) + .unwrap(); + t.into() + } + + fn total_claims() -> u64 { + 100 + 200 + 300 + 400 + } + + #[test] + fn basic_setup_works() { + new_test_ext().execute_with(|| { + assert_eq!(Claims::total(), total_claims()); + assert_eq!(Claims::claims(ð(&alice())), Some(100)); + assert_eq!(Claims::claims(ð(&dave())), Some(200)); + assert_eq!(Claims::claims(ð(&eve())), Some(300)); + assert_eq!(Claims::claims(ð(&frank())), Some(400)); + assert_eq!(Claims::claims(&EthereumAddress::default()), None); + assert_eq!(Claims::vesting(ð(&alice())), Some((50, 10, 1))); + }); + } + + #[test] + fn serde_works() { + let x = EthereumAddress(hex!["0123456789abcdef0123456789abcdef01234567"]); + let y = serde_json::to_string(&x).unwrap(); + assert_eq!(y, "\"0x0123456789abcdef0123456789abcdef01234567\""); + let z: EthereumAddress = serde_json::from_str(&y).unwrap(); + assert_eq!(x, z); + } + + #[test] + fn claiming_works() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(42), 0); + assert_ok!(Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + )); + assert_eq!(Balances::free_balance(&42), 100); + assert_eq!(Vesting::vesting_balance(&42), Some(50)); + assert_eq!(Claims::total(), total_claims() - 100); + }); + } + + #[test] + fn basic_claim_moving_works() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(42), 0); + assert_noop!( + Claims::move_claim(RuntimeOrigin::signed(1), eth(&alice()), eth(&bob()), None), + BadOrigin + ); + assert_ok!(Claims::move_claim( + RuntimeOrigin::signed(6), + eth(&alice()), + eth(&bob()), + None + )); + assert_noop!( + Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + ), + Error::::SignerHasNoClaim + ); + assert_ok!(Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&bob(), &42u64.encode(), &[][..]) + )); + assert_eq!(Balances::free_balance(&42), 100); + assert_eq!(Vesting::vesting_balance(&42), Some(50)); + assert_eq!(Claims::total(), total_claims() - 100); + }); + } + + #[test] + fn claim_attest_moving_works() { + new_test_ext().execute_with(|| { + assert_ok!(Claims::move_claim( + RuntimeOrigin::signed(6), + eth(&dave()), + eth(&bob()), + None + )); + let s = sig::(&bob(), &42u64.encode(), StatementKind::Regular.to_text()); + assert_ok!(Claims::claim_attest( + RuntimeOrigin::none(), + 42, + s, + StatementKind::Regular.to_text().to_vec() + )); + assert_eq!(Balances::free_balance(&42), 200); + }); + } + + #[test] + fn attest_moving_works() { + new_test_ext().execute_with(|| { + assert_ok!(Claims::move_claim( + RuntimeOrigin::signed(6), + eth(&eve()), + eth(&bob()), + Some(42) + )); + assert_ok!(Claims::attest( + RuntimeOrigin::signed(42), + StatementKind::Saft.to_text().to_vec() + )); + assert_eq!(Balances::free_balance(&42), 300); + }); + } + + #[test] + fn claiming_does_not_bypass_signing() { + new_test_ext().execute_with(|| { + assert_ok!(Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + )); + assert_noop!( + Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&dave(), &42u64.encode(), &[][..]) + ), + Error::::InvalidStatement, + ); + assert_noop!( + Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&eve(), &42u64.encode(), &[][..]) + ), + Error::::InvalidStatement, + ); + assert_ok!(Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&frank(), &42u64.encode(), &[][..]) + )); + }); + } + + #[test] + fn attest_claiming_works() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(42), 0); + let s = sig::(&dave(), &42u64.encode(), StatementKind::Saft.to_text()); + let r = Claims::claim_attest( + RuntimeOrigin::none(), + 42, + s.clone(), + StatementKind::Saft.to_text().to_vec(), + ); + assert_noop!(r, Error::::InvalidStatement); + + let r = Claims::claim_attest( + RuntimeOrigin::none(), + 42, + s, + StatementKind::Regular.to_text().to_vec(), + ); + assert_noop!(r, Error::::SignerHasNoClaim); + // ^^^ we use ecdsa_recover, so an invalid signature just results in a random signer id + // being recovered, which realistically will never have a claim. + + let s = sig::(&dave(), &42u64.encode(), StatementKind::Regular.to_text()); + assert_ok!(Claims::claim_attest( + RuntimeOrigin::none(), + 42, + s, + StatementKind::Regular.to_text().to_vec() + )); + assert_eq!(Balances::free_balance(&42), 200); + assert_eq!(Claims::total(), total_claims() - 200); + + let s = sig::(&dave(), &42u64.encode(), StatementKind::Regular.to_text()); + let r = Claims::claim_attest( + RuntimeOrigin::none(), + 42, + s, + StatementKind::Regular.to_text().to_vec(), + ); + assert_noop!(r, Error::::SignerHasNoClaim); + }); + } + + #[test] + fn attesting_works() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(42), 0); + assert_noop!( + Claims::attest(RuntimeOrigin::signed(69), StatementKind::Saft.to_text().to_vec()), + Error::::SenderHasNoClaim + ); + assert_noop!( + Claims::attest( + RuntimeOrigin::signed(42), + StatementKind::Regular.to_text().to_vec() + ), + Error::::InvalidStatement + ); + assert_ok!(Claims::attest( + RuntimeOrigin::signed(42), + StatementKind::Saft.to_text().to_vec() + )); + assert_eq!(Balances::free_balance(&42), 300); + assert_eq!(Claims::total(), total_claims() - 300); + }); + } + + #[test] + fn claim_cannot_clobber_preclaim() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(42), 0); + // Alice's claim is 100 + assert_ok!(Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + )); + assert_eq!(Balances::free_balance(&42), 100); + // Eve's claim is 300 through Account 42 + assert_ok!(Claims::attest( + RuntimeOrigin::signed(42), + StatementKind::Saft.to_text().to_vec() + )); + assert_eq!(Balances::free_balance(&42), 100 + 300); + assert_eq!(Claims::total(), total_claims() - 400); + }); + } + + #[test] + fn valid_attest_transactions_are_free() { + new_test_ext().execute_with(|| { + let p = PrevalidateAttests::::new(); + let c = RuntimeCall::Claims(ClaimsCall::attest { + statement: StatementKind::Saft.to_text().to_vec(), + }); + let di = c.get_dispatch_info(); + assert_eq!(di.pays_fee, Pays::No); + let r = p.validate(&42, &c, &di, 20); + assert_eq!(r, TransactionValidity::Ok(ValidTransaction::default())); + }); + } + + #[test] + fn invalid_attest_transactions_are_recognized() { + new_test_ext().execute_with(|| { + let p = PrevalidateAttests::::new(); + let c = RuntimeCall::Claims(ClaimsCall::attest { + statement: StatementKind::Regular.to_text().to_vec(), + }); + let di = c.get_dispatch_info(); + let r = p.validate(&42, &c, &di, 20); + assert!(r.is_err()); + let c = RuntimeCall::Claims(ClaimsCall::attest { + statement: StatementKind::Saft.to_text().to_vec(), + }); + let di = c.get_dispatch_info(); + let r = p.validate(&69, &c, &di, 20); + assert!(r.is_err()); + }); + } + + #[test] + fn cannot_bypass_attest_claiming() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(42), 0); + let s = sig::(&dave(), &42u64.encode(), &[]); + let r = Claims::claim(RuntimeOrigin::none(), 42, s.clone()); + assert_noop!(r, Error::::InvalidStatement); + }); + } + + #[test] + fn add_claim_works() { + new_test_ext().execute_with(|| { + assert_noop!( + Claims::mint_claim(RuntimeOrigin::signed(42), eth(&bob()), 200, None, None), + sp_runtime::traits::BadOrigin, + ); + assert_eq!(Balances::free_balance(42), 0); + assert_noop!( + Claims::claim( + RuntimeOrigin::none(), + 69, + sig::(&bob(), &69u64.encode(), &[][..]) + ), + Error::::SignerHasNoClaim, + ); + assert_ok!(Claims::mint_claim(RuntimeOrigin::root(), eth(&bob()), 200, None, None)); + assert_eq!(Claims::total(), total_claims() + 200); + assert_ok!(Claims::claim( + RuntimeOrigin::none(), + 69, + sig::(&bob(), &69u64.encode(), &[][..]) + )); + assert_eq!(Balances::free_balance(&69), 200); + assert_eq!(Vesting::vesting_balance(&69), None); + assert_eq!(Claims::total(), total_claims()); + }); + } + + #[test] + fn add_claim_with_vesting_works() { + new_test_ext().execute_with(|| { + assert_noop!( + Claims::mint_claim( + RuntimeOrigin::signed(42), + eth(&bob()), + 200, + Some((50, 10, 1)), + None + ), + sp_runtime::traits::BadOrigin, + ); + assert_eq!(Balances::free_balance(42), 0); + assert_noop!( + Claims::claim( + RuntimeOrigin::none(), + 69, + sig::(&bob(), &69u64.encode(), &[][..]) + ), + Error::::SignerHasNoClaim, + ); + assert_ok!(Claims::mint_claim( + RuntimeOrigin::root(), + eth(&bob()), + 200, + Some((50, 10, 1)), + None + )); + assert_ok!(Claims::claim( + RuntimeOrigin::none(), + 69, + sig::(&bob(), &69u64.encode(), &[][..]) + )); + assert_eq!(Balances::free_balance(&69), 200); + assert_eq!(Vesting::vesting_balance(&69), Some(50)); + + // Make sure we can not transfer the vested balance. + assert_err!( + >::transfer( + &69, + &80, + 180, + ExistenceRequirement::AllowDeath + ), + TokenError::Frozen, + ); + }); + } + + #[test] + fn add_claim_with_statement_works() { + new_test_ext().execute_with(|| { + assert_noop!( + Claims::mint_claim( + RuntimeOrigin::signed(42), + eth(&bob()), + 200, + None, + Some(StatementKind::Regular) + ), + sp_runtime::traits::BadOrigin, + ); + assert_eq!(Balances::free_balance(42), 0); + let signature = sig::(&bob(), &69u64.encode(), StatementKind::Regular.to_text()); + assert_noop!( + Claims::claim_attest( + RuntimeOrigin::none(), + 69, + signature.clone(), + StatementKind::Regular.to_text().to_vec() + ), + Error::::SignerHasNoClaim + ); + assert_ok!(Claims::mint_claim( + RuntimeOrigin::root(), + eth(&bob()), + 200, + None, + Some(StatementKind::Regular) + )); + assert_noop!( + Claims::claim_attest(RuntimeOrigin::none(), 69, signature.clone(), vec![],), + Error::::SignerHasNoClaim + ); + assert_ok!(Claims::claim_attest( + RuntimeOrigin::none(), + 69, + signature.clone(), + StatementKind::Regular.to_text().to_vec() + )); + assert_eq!(Balances::free_balance(&69), 200); + }); + } + + #[test] + fn origin_signed_claiming_fail() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(42), 0); + assert_err!( + Claims::claim( + RuntimeOrigin::signed(42), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + ), + sp_runtime::traits::BadOrigin, + ); + }); + } + + #[test] + fn double_claiming_doesnt_work() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(42), 0); + assert_ok!(Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + )); + assert_noop!( + Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + ), + Error::::SignerHasNoClaim + ); + }); + } + + #[test] + fn claiming_while_vested_doesnt_work() { + new_test_ext().execute_with(|| { + CurrencyOf::::make_free_balance_be(&69, total_claims()); + assert_eq!(Balances::free_balance(69), total_claims()); + // A user is already vested + assert_ok!(::VestingSchedule::add_vesting_schedule( + &69, + total_claims(), + 100, + 10 + )); + assert_ok!(Claims::mint_claim( + RuntimeOrigin::root(), + eth(&bob()), + 200, + Some((50, 10, 1)), + None + )); + // New total + assert_eq!(Claims::total(), total_claims() + 200); + + // They should not be able to claim + assert_noop!( + Claims::claim( + RuntimeOrigin::none(), + 69, + sig::(&bob(), &69u64.encode(), &[][..]) + ), + Error::::VestedBalanceExists, + ); + }); + } + + #[test] + fn non_sender_sig_doesnt_work() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(42), 0); + assert_noop!( + Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&alice(), &69u64.encode(), &[][..]) + ), + Error::::SignerHasNoClaim + ); + }); + } + + #[test] + fn non_claimant_doesnt_work() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::free_balance(42), 0); + assert_noop!( + Claims::claim( + RuntimeOrigin::none(), + 42, + sig::(&bob(), &69u64.encode(), &[][..]) + ), + Error::::SignerHasNoClaim + ); + }); + } + + #[test] + fn real_eth_sig_works() { + new_test_ext().execute_with(|| { + // "Pay RUSTs to the TEST account:2a00000000000000" + let sig = hex!["444023e89b67e67c0562ed0305d252a5dd12b2af5ac51d6d3cb69a0b486bc4b3191401802dc29d26d586221f7256cd3329fe82174bdf659baea149a40e1c495d1c"]; + let sig = EcdsaSignature(sig); + let who = 42u64.using_encoded(to_ascii_hex); + let signer = Claims::eth_recover(&sig, &who, &[][..]).unwrap(); + assert_eq!(signer.0, hex!["6d31165d5d932d571f3b44695653b46dcc327e84"]); + }); + } + + #[test] + fn validate_unsigned_works() { + use sp_runtime::traits::ValidateUnsigned; + let source = sp_runtime::transaction_validity::TransactionSource::External; + + new_test_ext().execute_with(|| { + assert_eq!( + >::validate_unsigned( + source, + &ClaimsCall::claim { + dest: 1, + ethereum_signature: sig::(&alice(), &1u64.encode(), &[][..]) + } + ), + Ok(ValidTransaction { + priority: 100, + requires: vec![], + provides: vec![("claims", eth(&alice())).encode()], + longevity: TransactionLongevity::max_value(), + propagate: true, + }) + ); + assert_eq!( + >::validate_unsigned( + source, + &ClaimsCall::claim { dest: 0, ethereum_signature: EcdsaSignature([0; 65]) } + ), + InvalidTransaction::Custom(ValidityError::InvalidEthereumSignature.into()).into(), + ); + assert_eq!( + >::validate_unsigned( + source, + &ClaimsCall::claim { + dest: 1, + ethereum_signature: sig::(&bob(), &1u64.encode(), &[][..]) + } + ), + InvalidTransaction::Custom(ValidityError::SignerHasNoClaim.into()).into(), + ); + let s = sig::(&dave(), &1u64.encode(), StatementKind::Regular.to_text()); + let call = ClaimsCall::claim_attest { + dest: 1, + ethereum_signature: s, + statement: StatementKind::Regular.to_text().to_vec(), + }; + assert_eq!( + >::validate_unsigned(source, &call), + Ok(ValidTransaction { + priority: 100, + requires: vec![], + provides: vec![("claims", eth(&dave())).encode()], + longevity: TransactionLongevity::max_value(), + propagate: true, + }) + ); + assert_eq!( + >::validate_unsigned( + source, + &ClaimsCall::claim_attest { + dest: 1, + ethereum_signature: EcdsaSignature([0; 65]), + statement: StatementKind::Regular.to_text().to_vec() + } + ), + InvalidTransaction::Custom(ValidityError::InvalidEthereumSignature.into()).into(), + ); + + let s = sig::(&bob(), &1u64.encode(), StatementKind::Regular.to_text()); + let call = ClaimsCall::claim_attest { + dest: 1, + ethereum_signature: s, + statement: StatementKind::Regular.to_text().to_vec(), + }; + assert_eq!( + >::validate_unsigned(source, &call), + InvalidTransaction::Custom(ValidityError::SignerHasNoClaim.into()).into(), + ); + + let s = sig::(&dave(), &1u64.encode(), StatementKind::Saft.to_text()); + let call = ClaimsCall::claim_attest { + dest: 1, + ethereum_signature: s, + statement: StatementKind::Regular.to_text().to_vec(), + }; + assert_eq!( + >::validate_unsigned(source, &call), + InvalidTransaction::Custom(ValidityError::SignerHasNoClaim.into()).into(), + ); + + let s = sig::(&dave(), &1u64.encode(), StatementKind::Saft.to_text()); + let call = ClaimsCall::claim_attest { + dest: 1, + ethereum_signature: s, + statement: StatementKind::Saft.to_text().to_vec(), + }; + assert_eq!( + >::validate_unsigned(source, &call), + InvalidTransaction::Custom(ValidityError::InvalidStatement.into()).into(), + ); + }); + } +} + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking { + use super::*; + use crate::claims::Call; + use frame_benchmarking::{account, benchmarks}; + use frame_support::dispatch::UnfilteredDispatchable; + use frame_system::RawOrigin; + use secp_utils::*; + use sp_runtime::{traits::ValidateUnsigned, DispatchResult}; + + const SEED: u32 = 0; + + const MAX_CLAIMS: u32 = 10_000; + const VALUE: u32 = 1_000_000; + + fn create_claim(input: u32) -> DispatchResult { + let secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&input.encode())).unwrap(); + let eth_address = eth(&secret_key); + let vesting = Some((100_000u32.into(), 1_000u32.into(), 100u32.into())); + super::Pallet::::mint_claim( + RawOrigin::Root.into(), + eth_address, + VALUE.into(), + vesting, + None, + )?; + Ok(()) + } + + fn create_claim_attest(input: u32) -> DispatchResult { + let secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&input.encode())).unwrap(); + let eth_address = eth(&secret_key); + let vesting = Some((100_000u32.into(), 1_000u32.into(), 100u32.into())); + super::Pallet::::mint_claim( + RawOrigin::Root.into(), + eth_address, + VALUE.into(), + vesting, + Some(Default::default()), + )?; + Ok(()) + } + + benchmarks! { + // Benchmark `claim` including `validate_unsigned` logic. + claim { + let c = MAX_CLAIMS; + + for i in 0 .. c / 2 { + create_claim::(c)?; + create_claim_attest::(u32::MAX - c)?; + } + + let secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&c.encode())).unwrap(); + let eth_address = eth(&secret_key); + let account: T::AccountId = account("user", c, SEED); + let vesting = Some((100_000u32.into(), 1_000u32.into(), 100u32.into())); + let signature = sig::(&secret_key, &account.encode(), &[][..]); + super::Pallet::::mint_claim(RawOrigin::Root.into(), eth_address, VALUE.into(), vesting, None)?; + assert_eq!(Claims::::get(eth_address), Some(VALUE.into())); + let source = sp_runtime::transaction_validity::TransactionSource::External; + let call_enc = Call::::claim { + dest: account.clone(), + ethereum_signature: signature.clone() + }.encode(); + }: { + let call = as Decode>::decode(&mut &*call_enc) + .expect("call is encoded above, encoding must be correct"); + super::Pallet::::validate_unsigned(source, &call).map_err(|e| -> &'static str { e.into() })?; + call.dispatch_bypass_filter(RawOrigin::None.into())?; + } + verify { + assert_eq!(Claims::::get(eth_address), None); + } + + // Benchmark `mint_claim` when there already exists `c` claims in storage. + mint_claim { + let c = MAX_CLAIMS; + + for i in 0 .. c / 2 { + create_claim::(c)?; + create_claim_attest::(u32::MAX - c)?; + } + + let eth_address = account("eth_address", 0, SEED); + let vesting = Some((100_000u32.into(), 1_000u32.into(), 100u32.into())); + let statement = StatementKind::Regular; + }: _(RawOrigin::Root, eth_address, VALUE.into(), vesting, Some(statement)) + verify { + assert_eq!(Claims::::get(eth_address), Some(VALUE.into())); + } + + // Benchmark `claim_attest` including `validate_unsigned` logic. + claim_attest { + let c = MAX_CLAIMS; + + for i in 0 .. c / 2 { + create_claim::(c)?; + create_claim_attest::(u32::MAX - c)?; + } + + // Crate signature + let attest_c = u32::MAX - c; + let secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&attest_c.encode())).unwrap(); + let eth_address = eth(&secret_key); + let account: T::AccountId = account("user", c, SEED); + let vesting = Some((100_000u32.into(), 1_000u32.into(), 100u32.into())); + let statement = StatementKind::Regular; + let signature = sig::(&secret_key, &account.encode(), statement.to_text()); + super::Pallet::::mint_claim(RawOrigin::Root.into(), eth_address, VALUE.into(), vesting, Some(statement))?; + assert_eq!(Claims::::get(eth_address), Some(VALUE.into())); + let call_enc = Call::::claim_attest { + dest: account.clone(), + ethereum_signature: signature.clone(), + statement: StatementKind::Regular.to_text().to_vec() + }.encode(); + let source = sp_runtime::transaction_validity::TransactionSource::External; + }: { + let call = as Decode>::decode(&mut &*call_enc) + .expect("call is encoded above, encoding must be correct"); + super::Pallet::::validate_unsigned(source, &call).map_err(|e| -> &'static str { e.into() })?; + call.dispatch_bypass_filter(RawOrigin::None.into())?; + } + verify { + assert_eq!(Claims::::get(eth_address), None); + } + + // Benchmark `attest` including prevalidate logic. + attest { + let c = MAX_CLAIMS; + + for i in 0 .. c / 2 { + create_claim::(c)?; + create_claim_attest::(u32::MAX - c)?; + } + + let attest_c = u32::MAX - c; + let secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&attest_c.encode())).unwrap(); + let eth_address = eth(&secret_key); + let account: T::AccountId = account("user", c, SEED); + let vesting = Some((100_000u32.into(), 1_000u32.into(), 100u32.into())); + let statement = StatementKind::Regular; + let signature = sig::(&secret_key, &account.encode(), statement.to_text()); + super::Pallet::::mint_claim(RawOrigin::Root.into(), eth_address, VALUE.into(), vesting, Some(statement))?; + Preclaims::::insert(&account, eth_address); + assert_eq!(Claims::::get(eth_address), Some(VALUE.into())); + + let call = super::Call::::attest { statement: StatementKind::Regular.to_text().to_vec() }; + // We have to copy the validate statement here because of trait issues... :( + let validate = |who: &T::AccountId, call: &super::Call| -> DispatchResult { + if let Call::attest{ statement: attested_statement } = call { + let signer = Preclaims::::get(who).ok_or("signer has no claim")?; + if let Some(s) = Signing::::get(signer) { + ensure!(&attested_statement[..] == s.to_text(), "invalid statement"); + } + } + Ok(()) + }; + let call_enc = call.encode(); + }: { + let call = as Decode>::decode(&mut &*call_enc) + .expect("call is encoded above, encoding must be correct"); + validate(&account, &call)?; + call.dispatch_bypass_filter(RawOrigin::Signed(account).into())?; + } + verify { + assert_eq!(Claims::::get(eth_address), None); + } + + move_claim { + let c = MAX_CLAIMS; + + for i in 0 .. c / 2 { + create_claim::(c)?; + create_claim_attest::(u32::MAX - c)?; + } + + let attest_c = u32::MAX - c; + let secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&attest_c.encode())).unwrap(); + let eth_address = eth(&secret_key); + + let new_secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&(u32::MAX/2).encode())).unwrap(); + let new_eth_address = eth(&new_secret_key); + + let account: T::AccountId = account("user", c, SEED); + Preclaims::::insert(&account, eth_address); + + assert!(Claims::::contains_key(eth_address)); + assert!(!Claims::::contains_key(new_eth_address)); + }: _(RawOrigin::Root, eth_address, new_eth_address, Some(account)) + verify { + assert!(!Claims::::contains_key(eth_address)); + assert!(Claims::::contains_key(new_eth_address)); + } + + // Benchmark the time it takes to do `repeat` number of keccak256 hashes + #[extra] + keccak256 { + let i in 0 .. 10_000; + let bytes = (i).encode(); + }: { + for index in 0 .. i { + let _hash = keccak_256(&bytes); + } + } + + // Benchmark the time it takes to do `repeat` number of `eth_recover` + #[extra] + eth_recover { + let i in 0 .. 1_000; + // Crate signature + let secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&i.encode())).unwrap(); + let account: T::AccountId = account("user", i, SEED); + let signature = sig::(&secret_key, &account.encode(), &[][..]); + let data = account.using_encoded(to_ascii_hex); + let extra = StatementKind::default().to_text(); + }: { + for _ in 0 .. i { + assert!(super::Pallet::::eth_recover(&signature, &data, extra).is_some()); + } + } + + impl_benchmark_test_suite!( + Pallet, + crate::claims::tests::new_test_ext(), + crate::claims::tests::Test, + ); + } +} diff --git a/polkadot/runtime/common/src/crowdloan/migration.rs b/polkadot/runtime/common/src/crowdloan/migration.rs new file mode 100644 index 0000000000000000000000000000000000000000..03c4ab6c31193478b5c0cc9cb45b9f3437d8254c --- /dev/null +++ b/polkadot/runtime/common/src/crowdloan/migration.rs @@ -0,0 +1,228 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use frame_support::{ + dispatch::GetStorageVersion, + storage_alias, + traits::{OnRuntimeUpgrade, StorageVersion}, + Twox64Concat, +}; + +pub struct MigrateToTrackInactiveV2(sp_std::marker::PhantomData); +impl OnRuntimeUpgrade for MigrateToTrackInactiveV2 { + fn on_runtime_upgrade() -> Weight { + let onchain_version = Pallet::::on_chain_storage_version(); + + if onchain_version == 1 { + let mut translated = 0u64; + for item in Funds::::iter_values() { + let b = + CurrencyOf::::total_balance(&Pallet::::fund_account_id(item.fund_index)); + CurrencyOf::::deactivate(b); + translated.saturating_inc(); + } + + StorageVersion::new(2).put::>(); + log::info!(target: "runtime::crowdloan", "Summed {} funds, storage to version 1", translated); + T::DbWeight::get().reads_writes(translated * 2 + 1, translated * 2 + 1) + } else { + log::info!(target: "runtime::crowdloan", "Migration did not execute. This probably should be removed"); + T::DbWeight::get().reads(1) + } + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + let total = Funds::::iter_values() + .map(|item| { + CurrencyOf::::total_balance(&Pallet::::fund_account_id(item.fund_index)) + }) + .fold(BalanceOf::::zero(), |a, i| a.saturating_add(i)); + Ok((total, CurrencyOf::::active_issuance()).encode()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(total: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + if let Ok((total, active)) = <(BalanceOf, BalanceOf)>::decode(&mut total.as_slice()) { + ensure!(active - total == CurrencyOf::::active_issuance(), "the total be correct"); + Ok(()) + } else { + Err("the state parameter should be something that was generated by pre_upgrade".into()) + } + } +} + +/// Migrations for using fund index to create fund accounts instead of para ID. +pub mod crowdloan_index_migration { + use super::*; + + #[storage_alias] + type NextTrieIndex = StorageValue, FundIndex>; + + #[storage_alias] + type Leases = StorageMap< + Slots, + Twox64Concat, + ParaId, + Vec::AccountId, BalanceOf)>>, + >; + + // The old way we generated fund accounts. + fn old_fund_account_id(index: ParaId) -> T::AccountId { + T::PalletId::get().into_sub_account_truncating(index) + } + + pub fn pre_migrate() -> Result<(), &'static str> { + // `NextTrieIndex` should have a value. + + let next_index = NextTrieIndex::::get().unwrap_or_default(); + ensure!(next_index > 0, "Next index is zero, which implies no migration is needed."); + + log::info!( + target: "runtime", + "next trie index: {:?}", + next_index, + ); + + for (para_id, fund) in Funds::::iter() { + let old_fund_account = old_fund_account_id::(para_id); + let total_balance = CurrencyOf::::total_balance(&old_fund_account); + + log::info!( + target: "runtime", + "para_id={:?}, old_fund_account={:?}, total_balance={:?}, fund.raised={:?}", + para_id, old_fund_account, total_balance, fund.raised + ); + + // Each fund should have some non-zero balance. + ensure!( + total_balance >= fund.raised, + "Total balance is not equal to the funds raised." + ); + + let leases = Leases::::get(para_id).unwrap_or_default(); + let mut found_lease_deposit = false; + for (who, _amount) in leases.iter().flatten() { + if *who == old_fund_account { + found_lease_deposit = true; + break + } + } + if found_lease_deposit { + log::info!( + target: "runtime", + "para_id={:?}, old_fund_account={:?}, leases={:?}", + para_id, old_fund_account, leases, + ); + } + } + + Ok(()) + } + + /// This migration converts crowdloans to use a crowdloan index rather than the parachain id as + /// a unique identifier. This makes it easier to swap two crowdloans between parachains. + pub fn migrate() -> frame_support::weights::Weight { + let mut weight = Weight::zero(); + + // First migrate `NextTrieIndex` counter to `NextFundIndex`. + + let next_index = NextTrieIndex::::take().unwrap_or_default(); + NextFundIndex::::set(next_index); + + weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 2)); + + // Migrate all accounts from `old_fund_account` to `fund_account` using `fund_index`. + for (para_id, fund) in Funds::::iter() { + let old_fund_account = old_fund_account_id::(para_id); + let new_fund_account = Pallet::::fund_account_id(fund.fund_index); + + // Funds should only have a free balance and a reserve balance. Both of these are in the + // `Account` storage item, so we just swap them. + let account_info = frame_system::Account::::take(&old_fund_account); + frame_system::Account::::insert(&new_fund_account, account_info); + + weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 2)); + + let mut leases = Leases::::get(para_id).unwrap_or_default(); + for (who, _amount) in leases.iter_mut().flatten() { + if *who == old_fund_account { + *who = new_fund_account.clone(); + } + } + + Leases::::insert(para_id, leases); + } + + weight + } + + pub fn post_migrate() -> Result<(), &'static str> { + // `NextTrieIndex` should not have a value, and `NextFundIndex` should. + ensure!(NextTrieIndex::::get().is_none(), "NextTrieIndex still has a value."); + + let next_index = NextFundIndex::::get(); + log::info!( + target: "runtime", + "next fund index: {:?}", + next_index, + ); + + ensure!( + next_index > 0, + "NextFundIndex was not migrated or is zero. We assume it cannot be zero else no migration is needed." + ); + + // Each fund should have balance migrated correctly. + for (para_id, fund) in Funds::::iter() { + // Old fund account is deleted. + let old_fund_account = old_fund_account_id::(para_id); + ensure!( + frame_system::Account::::get(&old_fund_account) == Default::default(), + "Old account wasn't reset to default value." + ); + + // New fund account has the correct balance. + let new_fund_account = Pallet::::fund_account_id(fund.fund_index); + let total_balance = CurrencyOf::::total_balance(&new_fund_account); + + ensure!( + total_balance >= fund.raised, + "Total balance in new account is different than the funds raised." + ); + + let leases = Leases::::get(para_id).unwrap_or_default(); + let mut new_account_found = false; + for (who, _amount) in leases.iter().flatten() { + if *who == old_fund_account { + panic!("Old fund account found after migration!"); + } else if *who == new_fund_account { + new_account_found = true; + } + } + if new_account_found { + log::info!( + target: "runtime::crowdloan", + "para_id={:?}, new_fund_account={:?}, leases={:?}", + para_id, new_fund_account, leases, + ); + } + } + + Ok(()) + } +} diff --git a/polkadot/runtime/common/src/crowdloan/mod.rs b/polkadot/runtime/common/src/crowdloan/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..0303808e074775a5dd9309291d129d526bcb2f58 --- /dev/null +++ b/polkadot/runtime/common/src/crowdloan/mod.rs @@ -0,0 +1,2236 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! # Parachain `Crowdloaning` pallet +//! +//! The point of this pallet is to allow parachain projects to offer the ability to help fund a +//! deposit for the parachain. When the crowdloan has ended, the funds are returned. +//! +//! Each fund has a child-trie which stores all contributors account IDs together with the amount +//! they contributed; the root of this can then be used by the parachain to allow contributors to +//! prove that they made some particular contribution to the project (e.g. to be rewarded through +//! some token or badge). The trie is retained for later (efficient) redistribution back to the +//! contributors. +//! +//! Contributions must be of at least `MinContribution` (to account for the resources taken in +//! tracking contributions), and may never tally greater than the fund's `cap`, set and fixed at the +//! time of creation. The `create` call may be used to create a new fund. In order to do this, then +//! a deposit must be paid of the amount `SubmissionDeposit`. Substantial resources are taken on +//! the main trie in tracking a fund and this accounts for that. +//! +//! Funds may be set up during an auction period; their closing time is fixed at creation (as a +//! block number) and if the fund is not successful by the closing time, then it can be dissolved. +//! Funds may span multiple auctions, and even auctions that sell differing periods. However, for a +//! fund to be active in bidding for an auction, it *must* have had *at least one bid* since the end +//! of the last auction. Until a fund takes a further bid following the end of an auction, then it +//! will be inactive. +//! +//! Contributors will get a refund of their contributions from completed funds before the crowdloan +//! can be dissolved. +//! +//! Funds may accept contributions at any point before their success or end. When a parachain +//! slot auction enters its ending period, then parachains will each place a bid; the bid will be +//! raised once per block if the parachain had additional funds contributed since the last bid. +//! +//! Successful funds remain tracked (in the `Funds` storage item and the associated child trie) as +//! long as the parachain remains active. Users can withdraw their funds once the slot is completed +//! and funds are returned to the crowdloan account. + +pub mod migration; + +use crate::{ + slot_range::SlotRange, + traits::{Auctioneer, Registrar}, +}; +use frame_support::{ + ensure, + pallet_prelude::{DispatchResult, Weight}, + storage::{child, ChildTriePrefixIterator}, + traits::{ + Currency, + ExistenceRequirement::{self, AllowDeath, KeepAlive}, + Get, ReservableCurrency, + }, + Identity, PalletId, +}; +use frame_system::pallet_prelude::BlockNumberFor; +pub use pallet::*; +use parity_scale_codec::{Decode, Encode}; +use primitives::Id as ParaId; +use scale_info::TypeInfo; +use sp_runtime::{ + traits::{ + AccountIdConversion, CheckedAdd, Hash, IdentifyAccount, One, Saturating, Verify, Zero, + }, + MultiSignature, MultiSigner, RuntimeDebug, +}; +use sp_std::vec::Vec; + +type CurrencyOf = <::Auctioneer as Auctioneer>>::Currency; +type LeasePeriodOf = <::Auctioneer as Auctioneer>>::LeasePeriod; +type BalanceOf = as Currency<::AccountId>>::Balance; + +#[allow(dead_code)] +type NegativeImbalanceOf = + as Currency<::AccountId>>::NegativeImbalance; + +type FundIndex = u32; + +pub trait WeightInfo { + fn create() -> Weight; + fn contribute() -> Weight; + fn withdraw() -> Weight; + fn refund(k: u32) -> Weight; + fn dissolve() -> Weight; + fn edit() -> Weight; + fn add_memo() -> Weight; + fn on_initialize(n: u32) -> Weight; + fn poke() -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn create() -> Weight { + Weight::zero() + } + fn contribute() -> Weight { + Weight::zero() + } + fn withdraw() -> Weight { + Weight::zero() + } + fn refund(_k: u32) -> Weight { + Weight::zero() + } + fn dissolve() -> Weight { + Weight::zero() + } + fn edit() -> Weight { + Weight::zero() + } + fn add_memo() -> Weight { + Weight::zero() + } + fn on_initialize(_n: u32) -> Weight { + Weight::zero() + } + fn poke() -> Weight { + Weight::zero() + } +} + +#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub enum LastContribution { + Never, + PreEnding(u32), + Ending(BlockNumber), +} + +/// Information on a funding effort for a pre-existing parachain. We assume that the parachain ID +/// is known as it's used for the key of the storage item for which this is the value (`Funds`). +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +#[codec(dumb_trait_bound)] +pub struct FundInfo { + /// The owning account who placed the deposit. + pub depositor: AccountId, + /// An optional verifier. If exists, contributions must be signed by verifier. + pub verifier: Option, + /// The amount of deposit placed. + pub deposit: Balance, + /// The total amount raised. + pub raised: Balance, + /// Block number after which the funding must have succeeded. If not successful at this number + /// then everyone may withdraw their funds. + pub end: BlockNumber, + /// A hard-cap on the amount that may be contributed. + pub cap: Balance, + /// The most recent block that this had a contribution. Determines if we make a bid or not. + /// If this is `Never`, this fund has never received a contribution. + /// If this is `PreEnding(n)`, this fund received a contribution sometime in auction + /// number `n` before the ending period. + /// If this is `Ending(n)`, this fund received a contribution during the current ending period, + /// where `n` is how far into the ending period the contribution was made. + pub last_contribution: LastContribution, + /// First lease period in range to bid on; it's actually a `LeasePeriod`, but that's the same + /// type as `BlockNumber`. + pub first_period: LeasePeriod, + /// Last lease period in range to bid on; it's actually a `LeasePeriod`, but that's the same + /// type as `BlockNumber`. + pub last_period: LeasePeriod, + /// Unique index used to represent this fund. + pub fund_index: FundIndex, +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::{ensure_root, ensure_signed, pallet_prelude::*}; + + /// The current storage version. + const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); + + #[pallet::pallet] + #[pallet::without_storage_info] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// `PalletId` for the crowdloan pallet. An appropriate value could be + /// `PalletId(*b"py/cfund")` + #[pallet::constant] + type PalletId: Get; + + /// The amount to be held on deposit by the depositor of a crowdloan. + type SubmissionDeposit: Get>; + + /// The minimum amount that may be contributed into a crowdloan. Should almost certainly be + /// at least `ExistentialDeposit`. + #[pallet::constant] + type MinContribution: Get>; + + /// Max number of storage keys to remove per extrinsic call. + #[pallet::constant] + type RemoveKeysLimit: Get; + + /// The parachain registrar type. We just use this to ensure that only the manager of a para + /// is able to start a crowdloan for its slot. + type Registrar: Registrar; + + /// The type representing the auctioning system. + type Auctioneer: Auctioneer< + BlockNumberFor, + AccountId = Self::AccountId, + LeasePeriod = BlockNumberFor, + >; + + /// The maximum length for the memo attached to a crowdloan contribution. + type MaxMemoLength: Get; + + /// Weight Information for the Extrinsics in the Pallet + type WeightInfo: WeightInfo; + } + + /// Info on all of the funds. + #[pallet::storage] + #[pallet::getter(fn funds)] + pub(crate) type Funds = StorageMap< + _, + Twox64Concat, + ParaId, + FundInfo, BlockNumberFor, LeasePeriodOf>, + >; + + /// The funds that have had additional contributions during the last block. This is used + /// in order to determine which funds should submit new or updated bids. + #[pallet::storage] + #[pallet::getter(fn new_raise)] + pub(super) type NewRaise = StorageValue<_, Vec, ValueQuery>; + + /// The number of auctions that have entered into their ending period so far. + #[pallet::storage] + #[pallet::getter(fn endings_count)] + pub(super) type EndingsCount = StorageValue<_, u32, ValueQuery>; + + /// Tracker for the next available fund index + #[pallet::storage] + #[pallet::getter(fn next_fund_index)] + pub(super) type NextFundIndex = StorageValue<_, u32, ValueQuery>; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// Create a new crowdloaning campaign. + Created { para_id: ParaId }, + /// Contributed to a crowd sale. + Contributed { who: T::AccountId, fund_index: ParaId, amount: BalanceOf }, + /// Withdrew full balance of a contributor. + Withdrew { who: T::AccountId, fund_index: ParaId, amount: BalanceOf }, + /// The loans in a fund have been partially dissolved, i.e. there are some left + /// over child keys that still need to be killed. + PartiallyRefunded { para_id: ParaId }, + /// All loans in a fund have been refunded. + AllRefunded { para_id: ParaId }, + /// Fund is dissolved. + Dissolved { para_id: ParaId }, + /// The result of trying to submit a new bid to the Slots pallet. + HandleBidResult { para_id: ParaId, result: DispatchResult }, + /// The configuration to a crowdloan has been edited. + Edited { para_id: ParaId }, + /// A memo has been updated. + MemoUpdated { who: T::AccountId, para_id: ParaId, memo: Vec }, + /// A parachain has been moved to `NewRaise` + AddedToNewRaise { para_id: ParaId }, + } + + #[pallet::error] + pub enum Error { + /// The current lease period is more than the first lease period. + FirstPeriodInPast, + /// The first lease period needs to at least be less than 3 `max_value`. + FirstPeriodTooFarInFuture, + /// Last lease period must be greater than first lease period. + LastPeriodBeforeFirstPeriod, + /// The last lease period cannot be more than 3 periods after the first period. + LastPeriodTooFarInFuture, + /// The campaign ends before the current block number. The end must be in the future. + CannotEndInPast, + /// The end date for this crowdloan is not sensible. + EndTooFarInFuture, + /// There was an overflow. + Overflow, + /// The contribution was below the minimum, `MinContribution`. + ContributionTooSmall, + /// Invalid fund index. + InvalidParaId, + /// Contributions exceed maximum amount. + CapExceeded, + /// The contribution period has already ended. + ContributionPeriodOver, + /// The origin of this call is invalid. + InvalidOrigin, + /// This crowdloan does not correspond to a parachain. + NotParachain, + /// This parachain lease is still active and retirement cannot yet begin. + LeaseActive, + /// This parachain's bid or lease is still active and withdraw cannot yet begin. + BidOrLeaseActive, + /// The crowdloan has not yet ended. + FundNotEnded, + /// There are no contributions stored in this crowdloan. + NoContributions, + /// The crowdloan is not ready to dissolve. Potentially still has a slot or in retirement + /// period. + NotReadyToDissolve, + /// Invalid signature. + InvalidSignature, + /// The provided memo is too large. + MemoTooLarge, + /// The fund is already in `NewRaise` + AlreadyInNewRaise, + /// No contributions allowed during the VRF delay + VrfDelayInProgress, + /// A lease period has not started yet, due to an offset in the starting block. + NoLeasePeriod, + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(num: BlockNumberFor) -> frame_support::weights::Weight { + if let Some((sample, sub_sample)) = T::Auctioneer::auction_status(num).is_ending() { + // This is the very first block in the ending period + if sample.is_zero() && sub_sample.is_zero() { + // first block of ending period. + EndingsCount::::mutate(|c| *c += 1); + } + let new_raise = NewRaise::::take(); + let new_raise_len = new_raise.len() as u32; + for (fund, para_id) in + new_raise.into_iter().filter_map(|i| Self::funds(i).map(|f| (f, i))) + { + // Care needs to be taken by the crowdloan creator that this function will + // succeed given the crowdloaning configuration. We do some checks ahead of time + // in crowdloan `create`. + let result = T::Auctioneer::place_bid( + Self::fund_account_id(fund.fund_index), + para_id, + fund.first_period, + fund.last_period, + fund.raised, + ); + + Self::deposit_event(Event::::HandleBidResult { para_id, result }); + } + T::WeightInfo::on_initialize(new_raise_len) + } else { + T::DbWeight::get().reads(1) + } + } + } + + #[pallet::call] + impl Pallet { + /// Create a new crowdloaning campaign for a parachain slot with the given lease period + /// range. + /// + /// This applies a lock to your parachain configuration, ensuring that it cannot be changed + /// by the parachain manager. + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::create())] + pub fn create( + origin: OriginFor, + #[pallet::compact] index: ParaId, + #[pallet::compact] cap: BalanceOf, + #[pallet::compact] first_period: LeasePeriodOf, + #[pallet::compact] last_period: LeasePeriodOf, + #[pallet::compact] end: BlockNumberFor, + verifier: Option, + ) -> DispatchResult { + let depositor = ensure_signed(origin)?; + let now = frame_system::Pallet::::block_number(); + + ensure!(first_period <= last_period, Error::::LastPeriodBeforeFirstPeriod); + let last_period_limit = first_period + .checked_add(&((SlotRange::LEASE_PERIODS_PER_SLOT as u32) - 1).into()) + .ok_or(Error::::FirstPeriodTooFarInFuture)?; + ensure!(last_period <= last_period_limit, Error::::LastPeriodTooFarInFuture); + ensure!(end > now, Error::::CannotEndInPast); + + // Here we check the lease period on the ending block is at most the first block of the + // period after `first_period`. If it would be larger, there is no way we could win an + // active auction, thus it would make no sense to have a crowdloan this long. + let (lease_period_at_end, is_first_block) = + T::Auctioneer::lease_period_index(end).ok_or(Error::::NoLeasePeriod)?; + let adjusted_lease_period_at_end = if is_first_block { + lease_period_at_end.saturating_sub(One::one()) + } else { + lease_period_at_end + }; + ensure!(adjusted_lease_period_at_end <= first_period, Error::::EndTooFarInFuture); + + // Can't start a crowdloan for a lease period that already passed. + if let Some((current_lease_period, _)) = T::Auctioneer::lease_period_index(now) { + ensure!(first_period >= current_lease_period, Error::::FirstPeriodInPast); + } + + // There should not be an existing fund. + ensure!(!Funds::::contains_key(index), Error::::FundNotEnded); + + let manager = T::Registrar::manager_of(index).ok_or(Error::::InvalidParaId)?; + ensure!(depositor == manager, Error::::InvalidOrigin); + ensure!(T::Registrar::is_registered(index), Error::::InvalidParaId); + + let fund_index = Self::next_fund_index(); + let new_fund_index = fund_index.checked_add(1).ok_or(Error::::Overflow)?; + + let deposit = T::SubmissionDeposit::get(); + + frame_system::Pallet::::inc_providers(&Self::fund_account_id(fund_index)); + CurrencyOf::::reserve(&depositor, deposit)?; + + Funds::::insert( + index, + FundInfo { + depositor, + verifier, + deposit, + raised: Zero::zero(), + end, + cap, + last_contribution: LastContribution::Never, + first_period, + last_period, + fund_index, + }, + ); + + NextFundIndex::::put(new_fund_index); + // Add a lock to the para so that the configuration cannot be changed. + T::Registrar::apply_lock(index); + + Self::deposit_event(Event::::Created { para_id: index }); + Ok(()) + } + + /// Contribute to a crowd sale. This will transfer some balance over to fund a parachain + /// slot. It will be withdrawable when the crowdloan has ended and the funds are unused. + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::contribute())] + pub fn contribute( + origin: OriginFor, + #[pallet::compact] index: ParaId, + #[pallet::compact] value: BalanceOf, + signature: Option, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::do_contribute(who, index, value, signature, KeepAlive) + } + + /// Withdraw full balance of a specific contributor. + /// + /// Origin must be signed, but can come from anyone. + /// + /// The fund must be either in, or ready for, retirement. For a fund to be *in* retirement, + /// then the retirement flag must be set. For a fund to be ready for retirement, then: + /// - it must not already be in retirement; + /// - the amount of raised funds must be bigger than the _free_ balance of the account; + /// - and either: + /// - the block number must be at least `end`; or + /// - the current lease period must be greater than the fund's `last_period`. + /// + /// In this case, the fund's retirement flag is set and its `end` is reset to the current + /// block number. + /// + /// - `who`: The account whose contribution should be withdrawn. + /// - `index`: The parachain to whose crowdloan the contribution was made. + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::withdraw())] + pub fn withdraw( + origin: OriginFor, + who: T::AccountId, + #[pallet::compact] index: ParaId, + ) -> DispatchResult { + ensure_signed(origin)?; + + let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let now = frame_system::Pallet::::block_number(); + let fund_account = Self::fund_account_id(fund.fund_index); + Self::ensure_crowdloan_ended(now, &fund_account, &fund)?; + + let (balance, _) = Self::contribution_get(fund.fund_index, &who); + ensure!(balance > Zero::zero(), Error::::NoContributions); + + CurrencyOf::::transfer(&fund_account, &who, balance, AllowDeath)?; + CurrencyOf::::reactivate(balance); + + Self::contribution_kill(fund.fund_index, &who); + fund.raised = fund.raised.saturating_sub(balance); + + Funds::::insert(index, &fund); + + Self::deposit_event(Event::::Withdrew { who, fund_index: index, amount: balance }); + Ok(()) + } + + /// Automatically refund contributors of an ended crowdloan. + /// Due to weight restrictions, this function may need to be called multiple + /// times to fully refund all users. We will refund `RemoveKeysLimit` users at a time. + /// + /// Origin must be signed, but can come from anyone. + #[pallet::call_index(3)] + #[pallet::weight(T::WeightInfo::refund(T::RemoveKeysLimit::get()))] + pub fn refund( + origin: OriginFor, + #[pallet::compact] index: ParaId, + ) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; + + let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let now = frame_system::Pallet::::block_number(); + let fund_account = Self::fund_account_id(fund.fund_index); + Self::ensure_crowdloan_ended(now, &fund_account, &fund)?; + + let mut refund_count = 0u32; + // Try killing the crowdloan child trie + let contributions = Self::contribution_iterator(fund.fund_index); + // Assume everyone will be refunded. + let mut all_refunded = true; + for (who, (balance, _)) in contributions { + if refund_count >= T::RemoveKeysLimit::get() { + // Not everyone was able to be refunded this time around. + all_refunded = false; + break + } + CurrencyOf::::transfer(&fund_account, &who, balance, AllowDeath)?; + CurrencyOf::::reactivate(balance); + Self::contribution_kill(fund.fund_index, &who); + fund.raised = fund.raised.saturating_sub(balance); + refund_count += 1; + } + + // Save the changes. + Funds::::insert(index, &fund); + + if all_refunded { + Self::deposit_event(Event::::AllRefunded { para_id: index }); + // Refund for unused refund count. + Ok(Some(T::WeightInfo::refund(refund_count)).into()) + } else { + Self::deposit_event(Event::::PartiallyRefunded { para_id: index }); + // No weight to refund since we did not finish the loop. + Ok(().into()) + } + } + + /// Remove a fund after the retirement period has ended and all funds have been returned. + #[pallet::call_index(4)] + #[pallet::weight(T::WeightInfo::dissolve())] + pub fn dissolve(origin: OriginFor, #[pallet::compact] index: ParaId) -> DispatchResult { + let who = ensure_signed(origin)?; + + let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let now = frame_system::Pallet::::block_number(); + + // Only allow dissolution when the raised funds goes to zero, + // and the caller is the fund creator or we are past the end date. + let permitted = who == fund.depositor || now >= fund.end; + let can_dissolve = permitted && fund.raised.is_zero(); + ensure!(can_dissolve, Error::::NotReadyToDissolve); + + // Assuming state is not corrupted, the child trie should already be cleaned up + // and all funds in the crowdloan account have been returned. If not, governance + // can take care of that. + debug_assert!(Self::contribution_iterator(fund.fund_index).count().is_zero()); + + frame_system::Pallet::::dec_providers(&Self::fund_account_id(fund.fund_index))?; + CurrencyOf::::unreserve(&fund.depositor, fund.deposit); + Funds::::remove(index); + Self::deposit_event(Event::::Dissolved { para_id: index }); + Ok(()) + } + + /// Edit the configuration for an in-progress crowdloan. + /// + /// Can only be called by Root origin. + #[pallet::call_index(5)] + #[pallet::weight(T::WeightInfo::edit())] + pub fn edit( + origin: OriginFor, + #[pallet::compact] index: ParaId, + #[pallet::compact] cap: BalanceOf, + #[pallet::compact] first_period: LeasePeriodOf, + #[pallet::compact] last_period: LeasePeriodOf, + #[pallet::compact] end: BlockNumberFor, + verifier: Option, + ) -> DispatchResult { + ensure_root(origin)?; + + let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + + Funds::::insert( + index, + FundInfo { + depositor: fund.depositor, + verifier, + deposit: fund.deposit, + raised: fund.raised, + end, + cap, + last_contribution: fund.last_contribution, + first_period, + last_period, + fund_index: fund.fund_index, + }, + ); + + Self::deposit_event(Event::::Edited { para_id: index }); + Ok(()) + } + + /// Add an optional memo to an existing crowdloan contribution. + /// + /// Origin must be Signed, and the user must have contributed to the crowdloan. + #[pallet::call_index(6)] + #[pallet::weight(T::WeightInfo::add_memo())] + pub fn add_memo(origin: OriginFor, index: ParaId, memo: Vec) -> DispatchResult { + let who = ensure_signed(origin)?; + + ensure!(memo.len() <= T::MaxMemoLength::get().into(), Error::::MemoTooLarge); + let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + + let (balance, _) = Self::contribution_get(fund.fund_index, &who); + ensure!(balance > Zero::zero(), Error::::NoContributions); + + Self::contribution_put(fund.fund_index, &who, &balance, &memo); + Self::deposit_event(Event::::MemoUpdated { who, para_id: index, memo }); + Ok(()) + } + + /// Poke the fund into `NewRaise` + /// + /// Origin must be Signed, and the fund has non-zero raise. + #[pallet::call_index(7)] + #[pallet::weight(T::WeightInfo::poke())] + pub fn poke(origin: OriginFor, index: ParaId) -> DispatchResult { + ensure_signed(origin)?; + let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + ensure!(!fund.raised.is_zero(), Error::::NoContributions); + ensure!(!NewRaise::::get().contains(&index), Error::::AlreadyInNewRaise); + NewRaise::::append(index); + Self::deposit_event(Event::::AddedToNewRaise { para_id: index }); + Ok(()) + } + + /// Contribute your entire balance to a crowd sale. This will transfer the entire balance of + /// a user over to fund a parachain slot. It will be withdrawable when the crowdloan has + /// ended and the funds are unused. + #[pallet::call_index(8)] + #[pallet::weight(T::WeightInfo::contribute())] + pub fn contribute_all( + origin: OriginFor, + #[pallet::compact] index: ParaId, + signature: Option, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + let value = CurrencyOf::::free_balance(&who); + Self::do_contribute(who, index, value, signature, AllowDeath) + } + } +} + +impl Pallet { + /// The account ID of the fund pot. + /// + /// This actually does computation. If you need to keep using it, then make sure you cache the + /// value and only call this once. + pub fn fund_account_id(index: FundIndex) -> T::AccountId { + T::PalletId::get().into_sub_account_truncating(index) + } + + pub fn id_from_index(index: FundIndex) -> child::ChildInfo { + let mut buf = Vec::new(); + buf.extend_from_slice(b"crowdloan"); + buf.extend_from_slice(&index.encode()[..]); + child::ChildInfo::new_default(T::Hashing::hash(&buf[..]).as_ref()) + } + + pub fn contribution_put( + index: FundIndex, + who: &T::AccountId, + balance: &BalanceOf, + memo: &[u8], + ) { + who.using_encoded(|b| child::put(&Self::id_from_index(index), b, &(balance, memo))); + } + + pub fn contribution_get(index: FundIndex, who: &T::AccountId) -> (BalanceOf, Vec) { + who.using_encoded(|b| { + child::get_or_default::<(BalanceOf, Vec)>(&Self::id_from_index(index), b) + }) + } + + pub fn contribution_kill(index: FundIndex, who: &T::AccountId) { + who.using_encoded(|b| child::kill(&Self::id_from_index(index), b)); + } + + pub fn crowdloan_kill(index: FundIndex) -> child::KillStorageResult { + #[allow(deprecated)] + child::kill_storage(&Self::id_from_index(index), Some(T::RemoveKeysLimit::get())) + } + + pub fn contribution_iterator( + index: FundIndex, + ) -> ChildTriePrefixIterator<(T::AccountId, (BalanceOf, Vec))> { + ChildTriePrefixIterator::<_>::with_prefix_over_key::( + &Self::id_from_index(index), + &[], + ) + } + + /// This function checks all conditions which would qualify a crowdloan has ended. + /// * If we have reached the `fund.end` block OR the first lease period the fund is trying to + /// bid for has started already. + /// * And, if the fund has enough free funds to refund full raised amount. + fn ensure_crowdloan_ended( + now: BlockNumberFor, + fund_account: &T::AccountId, + fund: &FundInfo, BlockNumberFor, LeasePeriodOf>, + ) -> sp_runtime::DispatchResult { + // `fund.end` can represent the end of a failed crowdloan or the beginning of retirement + // If the current lease period is past the first period they are trying to bid for, then + // it is already too late to win the bid. + let (current_lease_period, _) = + T::Auctioneer::lease_period_index(now).ok_or(Error::::NoLeasePeriod)?; + ensure!( + now >= fund.end || current_lease_period > fund.first_period, + Error::::FundNotEnded + ); + // free balance must greater than or equal amount raised, otherwise funds are being used + // and a bid or lease must be active. + ensure!( + CurrencyOf::::free_balance(&fund_account) >= fund.raised, + Error::::BidOrLeaseActive + ); + + Ok(()) + } + + fn do_contribute( + who: T::AccountId, + index: ParaId, + value: BalanceOf, + signature: Option, + existence: ExistenceRequirement, + ) -> DispatchResult { + ensure!(value >= T::MinContribution::get(), Error::::ContributionTooSmall); + let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + fund.raised = fund.raised.checked_add(&value).ok_or(Error::::Overflow)?; + ensure!(fund.raised <= fund.cap, Error::::CapExceeded); + + // Make sure crowdloan has not ended + let now = >::block_number(); + ensure!(now < fund.end, Error::::ContributionPeriodOver); + + // Make sure crowdloan is in a valid lease period + let now = frame_system::Pallet::::block_number(); + let (current_lease_period, _) = + T::Auctioneer::lease_period_index(now).ok_or(Error::::NoLeasePeriod)?; + ensure!(current_lease_period <= fund.first_period, Error::::ContributionPeriodOver); + + // Make sure crowdloan has not already won. + let fund_account = Self::fund_account_id(fund.fund_index); + ensure!( + !T::Auctioneer::has_won_an_auction(index, &fund_account), + Error::::BidOrLeaseActive + ); + + // We disallow any crowdloan contributions during the VRF Period, so that people do not + // sneak their contributions into the auction when it would not impact the outcome. + ensure!(!T::Auctioneer::auction_status(now).is_vrf(), Error::::VrfDelayInProgress); + + let (old_balance, memo) = Self::contribution_get(fund.fund_index, &who); + + if let Some(ref verifier) = fund.verifier { + let signature = signature.ok_or(Error::::InvalidSignature)?; + let payload = (index, &who, old_balance, value); + let valid = payload.using_encoded(|encoded| { + signature.verify(encoded, &verifier.clone().into_account()) + }); + ensure!(valid, Error::::InvalidSignature); + } + + CurrencyOf::::transfer(&who, &fund_account, value, existence)?; + CurrencyOf::::deactivate(value); + + let balance = old_balance.saturating_add(value); + Self::contribution_put(fund.fund_index, &who, &balance, &memo); + + if T::Auctioneer::auction_status(now).is_ending().is_some() { + match fund.last_contribution { + // In ending period; must ensure that we are in NewRaise. + LastContribution::Ending(n) if n == now => { + // do nothing - already in NewRaise + }, + _ => { + NewRaise::::append(index); + fund.last_contribution = LastContribution::Ending(now); + }, + } + } else { + let endings_count = Self::endings_count(); + match fund.last_contribution { + LastContribution::PreEnding(a) if a == endings_count => { + // Not in ending period and no auctions have ended ending since our + // previous bid which was also not in an ending period. + // `NewRaise` will contain our ID still: Do nothing. + }, + _ => { + // Not in ending period; but an auction has been ending since our previous + // bid, or we never had one to begin with. Add bid. + NewRaise::::append(index); + fund.last_contribution = LastContribution::PreEnding(endings_count); + }, + } + } + + Funds::::insert(index, &fund); + + Self::deposit_event(Event::::Contributed { who, fund_index: index, amount: value }); + Ok(()) + } +} + +impl crate::traits::OnSwap for Pallet { + fn on_swap(one: ParaId, other: ParaId) { + Funds::::mutate(one, |x| Funds::::mutate(other, |y| sp_std::mem::swap(x, y))) + } +} + +#[cfg(any(feature = "runtime-benchmarks", test))] +mod crypto { + use sp_core::ed25519; + use sp_io::crypto::{ed25519_generate, ed25519_sign}; + use sp_runtime::{MultiSignature, MultiSigner}; + use sp_std::vec::Vec; + + pub fn create_ed25519_pubkey(seed: Vec) -> MultiSigner { + ed25519_generate(0.into(), Some(seed)).into() + } + + pub fn create_ed25519_signature(payload: &[u8], pubkey: MultiSigner) -> MultiSignature { + let edpubkey = ed25519::Public::try_from(pubkey).unwrap(); + let edsig = ed25519_sign(0.into(), &edpubkey, payload).unwrap(); + edsig.into() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use frame_support::{ + assert_noop, assert_ok, parameter_types, + traits::{ConstU32, OnFinalize, OnInitialize}, + }; + use primitives::Id as ParaId; + use sp_core::H256; + use std::{cell::RefCell, collections::BTreeMap, sync::Arc}; + // 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 crate::{ + crowdloan, + mock::TestRegistrar, + traits::{AuctionStatus, OnSwap}, + }; + use ::test_helpers::{dummy_head_data, dummy_validation_code}; + use sp_keystore::{testing::MemoryKeystore, KeystoreExt}; + use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup, TrailingZeroInput}, + BuildStorage, DispatchResult, + }; + + type Block = frame_system::mocking::MockBlock; + + frame_support::construct_runtime!( + pub enum Test + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Crowdloan: crowdloan::{Pallet, Call, Storage, Event}, + } + ); + + parameter_types! { + pub const BlockHashCount: u32 = 250; + } + + type BlockNumber = u64; + + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + } + + parameter_types! { + pub const ExistentialDeposit: u64 = 1; + } + + impl pallet_balances::Config for Test { + type Balance = u64; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<1>; + type MaxFreezes = ConstU32<1>; + } + + #[derive(Copy, Clone, Eq, PartialEq, Debug)] + struct BidPlaced { + height: u64, + bidder: u64, + para: ParaId, + first_period: u64, + last_period: u64, + amount: u64, + } + thread_local! { + static AUCTION: RefCell> = RefCell::new(None); + static VRF_DELAY: RefCell = RefCell::new(0); + static ENDING_PERIOD: RefCell = RefCell::new(5); + static BIDS_PLACED: RefCell> = RefCell::new(Vec::new()); + static HAS_WON: RefCell> = RefCell::new(BTreeMap::new()); + } + + #[allow(unused)] + fn set_ending_period(ending_period: u64) { + ENDING_PERIOD.with(|p| *p.borrow_mut() = ending_period); + } + fn auction() -> Option<(u64, u64)> { + AUCTION.with(|p| *p.borrow()) + } + fn ending_period() -> u64 { + ENDING_PERIOD.with(|p| *p.borrow()) + } + fn bids() -> Vec { + BIDS_PLACED.with(|p| p.borrow().clone()) + } + fn vrf_delay() -> u64 { + VRF_DELAY.with(|p| *p.borrow()) + } + fn set_vrf_delay(delay: u64) { + VRF_DELAY.with(|p| *p.borrow_mut() = delay); + } + // Emulate what would happen if we won an auction: + // balance is reserved and a deposit_held is recorded + fn set_winner(para: ParaId, who: u64, winner: bool) { + let fund = Funds::::get(para).unwrap(); + let account_id = Crowdloan::fund_account_id(fund.fund_index); + if winner { + let ed = ::ExistentialDeposit::get(); + let free_balance = Balances::free_balance(&account_id); + Balances::reserve(&account_id, free_balance - ed) + .expect("should be able to reserve free balance minus ED"); + } else { + let reserved_balance = Balances::reserved_balance(&account_id); + Balances::unreserve(&account_id, reserved_balance); + } + HAS_WON.with(|p| p.borrow_mut().insert((para, who), winner)); + } + + pub struct TestAuctioneer; + impl Auctioneer for TestAuctioneer { + type AccountId = u64; + type LeasePeriod = u64; + type Currency = Balances; + + fn new_auction(duration: u64, lease_period_index: u64) -> DispatchResult { + let now = System::block_number(); + let (current_lease_period, _) = + Self::lease_period_index(now).ok_or("no lease period yet")?; + assert!(lease_period_index >= current_lease_period); + + let ending = System::block_number().saturating_add(duration); + AUCTION.with(|p| *p.borrow_mut() = Some((lease_period_index, ending))); + Ok(()) + } + + fn auction_status(now: u64) -> AuctionStatus { + let early_end = match auction() { + Some((_, early_end)) => early_end, + None => return AuctionStatus::NotStarted, + }; + let after_early_end = match now.checked_sub(early_end) { + Some(after_early_end) => after_early_end, + None => return AuctionStatus::StartingPeriod, + }; + + let ending_period = ending_period(); + if after_early_end < ending_period { + return AuctionStatus::EndingPeriod(after_early_end, 0) + } else { + let after_end = after_early_end - ending_period; + // Optional VRF delay + if after_end < vrf_delay() { + return AuctionStatus::VrfDelay(after_end) + } else { + // VRF delay is done, so we just end the auction + return AuctionStatus::NotStarted + } + } + } + + fn place_bid( + bidder: u64, + para: ParaId, + first_period: u64, + last_period: u64, + amount: u64, + ) -> DispatchResult { + let height = System::block_number(); + BIDS_PLACED.with(|p| { + p.borrow_mut().push(BidPlaced { + height, + bidder, + para, + first_period, + last_period, + amount, + }) + }); + Ok(()) + } + + fn lease_period_index(b: BlockNumber) -> Option<(u64, bool)> { + let (lease_period_length, offset) = Self::lease_period_length(); + let b = b.checked_sub(offset)?; + + let lease_period = b / lease_period_length; + let first_block = (b % lease_period_length).is_zero(); + Some((lease_period, first_block)) + } + + fn lease_period_length() -> (u64, u64) { + (20, 0) + } + + fn has_won_an_auction(para: ParaId, bidder: &u64) -> bool { + HAS_WON.with(|p| *p.borrow().get(&(para, *bidder)).unwrap_or(&false)) + } + } + + parameter_types! { + pub const SubmissionDeposit: u64 = 1; + pub const MinContribution: u64 = 10; + pub const CrowdloanPalletId: PalletId = PalletId(*b"py/cfund"); + pub const RemoveKeysLimit: u32 = 10; + pub const MaxMemoLength: u8 = 32; + } + + impl Config for Test { + type RuntimeEvent = RuntimeEvent; + type SubmissionDeposit = SubmissionDeposit; + type MinContribution = MinContribution; + type PalletId = CrowdloanPalletId; + type RemoveKeysLimit = RemoveKeysLimit; + type Registrar = TestRegistrar; + type Auctioneer = TestAuctioneer; + type MaxMemoLength = MaxMemoLength; + type WeightInfo = crate::crowdloan::TestWeightInfo; + } + + use pallet_balances::Error as BalancesError; + + // This function basically just builds a genesis storage key/value store according to + // our desired mockup. + pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 1000), (2, 2000), (3, 3000), (4, 4000)], + } + .assimilate_storage(&mut t) + .unwrap(); + let keystore = MemoryKeystore::new(); + let mut t: sp_io::TestExternalities = t.into(); + t.register_extension(KeystoreExt(Arc::new(keystore))); + t + } + + fn new_para() -> ParaId { + for i in 0.. { + let para: ParaId = i.into(); + if TestRegistrar::::is_registered(para) { + continue + } + assert_ok!(TestRegistrar::::register( + 1, + para, + dummy_head_data(), + dummy_validation_code() + )); + return para + } + unreachable!() + } + + fn run_to_block(n: u64) { + while System::block_number() < n { + Crowdloan::on_finalize(System::block_number()); + Balances::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + System::set_block_number(System::block_number() + 1); + System::on_initialize(System::block_number()); + Balances::on_initialize(System::block_number()); + Crowdloan::on_initialize(System::block_number()); + } + } + + fn last_event() -> RuntimeEvent { + System::events().pop().expect("RuntimeEvent expected").event + } + + #[test] + fn basic_setup_works() { + new_test_ext().execute_with(|| { + assert_eq!(System::block_number(), 0); + assert_eq!(Crowdloan::funds(ParaId::from(0)), None); + let empty: Vec = Vec::new(); + assert_eq!(Crowdloan::new_raise(), empty); + assert_eq!(Crowdloan::contribution_get(0u32, &1).0, 0); + assert_eq!(Crowdloan::endings_count(), 0); + + assert_ok!(TestAuctioneer::new_auction(5, 0)); + + assert_eq!(bids(), vec![]); + assert_ok!(TestAuctioneer::place_bid(1, 2.into(), 0, 3, 6)); + let b = BidPlaced { + height: 0, + bidder: 1, + para: 2.into(), + first_period: 0, + last_period: 3, + amount: 6, + }; + assert_eq!(bids(), vec![b]); + assert_eq!(TestAuctioneer::auction_status(4), AuctionStatus::::StartingPeriod); + assert_eq!(TestAuctioneer::auction_status(5), AuctionStatus::::EndingPeriod(0, 0)); + assert_eq!(TestAuctioneer::auction_status(9), AuctionStatus::::EndingPeriod(4, 0)); + assert_eq!(TestAuctioneer::auction_status(11), AuctionStatus::::NotStarted); + }); + } + + #[test] + fn create_works() { + new_test_ext().execute_with(|| { + let para = new_para(); + // Now try to create a crowdloan campaign + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 4, 9, None)); + // This is what the initial `fund_info` should look like + let fund_info = FundInfo { + depositor: 1, + verifier: None, + deposit: 1, + raised: 0, + // 5 blocks length + 3 block ending period + 1 starting block + end: 9, + cap: 1000, + last_contribution: LastContribution::Never, + first_period: 1, + last_period: 4, + fund_index: 0, + }; + assert_eq!(Crowdloan::funds(para), Some(fund_info)); + // User has deposit removed from their free balance + assert_eq!(Balances::free_balance(1), 999); + // Deposit is placed in reserved + assert_eq!(Balances::reserved_balance(1), 1); + // No new raise until first contribution + let empty: Vec = Vec::new(); + assert_eq!(Crowdloan::new_raise(), empty); + }); + } + + #[test] + fn create_with_verifier_works() { + new_test_ext().execute_with(|| { + let pubkey = crypto::create_ed25519_pubkey(b"//verifier".to_vec()); + let para = new_para(); + // Now try to create a crowdloan campaign + assert_ok!(Crowdloan::create( + RuntimeOrigin::signed(1), + para, + 1000, + 1, + 4, + 9, + Some(pubkey.clone()) + )); + // This is what the initial `fund_info` should look like + let fund_info = FundInfo { + depositor: 1, + verifier: Some(pubkey), + deposit: 1, + raised: 0, + // 5 blocks length + 3 block ending period + 1 starting block + end: 9, + cap: 1000, + last_contribution: LastContribution::Never, + first_period: 1, + last_period: 4, + fund_index: 0, + }; + assert_eq!(Crowdloan::funds(ParaId::from(0)), Some(fund_info)); + // User has deposit removed from their free balance + assert_eq!(Balances::free_balance(1), 999); + // Deposit is placed in reserved + assert_eq!(Balances::reserved_balance(1), 1); + // No new raise until first contribution + let empty: Vec = Vec::new(); + assert_eq!(Crowdloan::new_raise(), empty); + }); + } + + #[test] + fn create_handles_basic_errors() { + new_test_ext().execute_with(|| { + // Now try to create a crowdloan campaign + let para = new_para(); + + let e = Error::::InvalidParaId; + assert_noop!( + Crowdloan::create(RuntimeOrigin::signed(1), 1.into(), 1000, 1, 4, 9, None), + e + ); + // Cannot create a crowdloan with bad lease periods + let e = Error::::LastPeriodBeforeFirstPeriod; + assert_noop!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 4, 1, 9, None), e); + let e = Error::::LastPeriodTooFarInFuture; + assert_noop!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 9, 9, None), e); + + // Cannot create a crowdloan without some deposit funds + assert_ok!(TestRegistrar::::register( + 1337, + ParaId::from(1234), + dummy_head_data(), + dummy_validation_code() + )); + let e = BalancesError::::InsufficientBalance; + assert_noop!( + Crowdloan::create( + RuntimeOrigin::signed(1337), + ParaId::from(1234), + 1000, + 1, + 3, + 9, + None + ), + e + ); + + // Cannot create a crowdloan with nonsense end date + // This crowdloan would end in lease period 2, but is bidding for some slot that starts + // in lease period 1. + assert_noop!( + Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 4, 41, None), + Error::::EndTooFarInFuture + ); + }); + } + + #[test] + fn contribute_works() { + new_test_ext().execute_with(|| { + let para = new_para(); + let index = NextFundIndex::::get(); + + // Set up a crowdloan + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 4, 9, None)); + + // No contributions yet + assert_eq!(Crowdloan::contribution_get(u32::from(para), &1).0, 0); + + // User 1 contributes to their own crowdloan + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(1), para, 49, None)); + // User 1 has spent some funds to do this, transfer fees **are** taken + assert_eq!(Balances::free_balance(1), 950); + // Contributions are stored in the trie + assert_eq!(Crowdloan::contribution_get(u32::from(para), &1).0, 49); + // Contributions appear in free balance of crowdloan + assert_eq!(Balances::free_balance(Crowdloan::fund_account_id(index)), 49); + // Crowdloan is added to NewRaise + assert_eq!(Crowdloan::new_raise(), vec![para]); + + let fund = Crowdloan::funds(para).unwrap(); + + // Last contribution time recorded + assert_eq!(fund.last_contribution, LastContribution::PreEnding(0)); + assert_eq!(fund.raised, 49); + }); + } + + #[test] + fn contribute_with_verifier_works() { + new_test_ext().execute_with(|| { + let para = new_para(); + let index = NextFundIndex::::get(); + let pubkey = crypto::create_ed25519_pubkey(b"//verifier".to_vec()); + // Set up a crowdloan + assert_ok!(Crowdloan::create( + RuntimeOrigin::signed(1), + para, + 1000, + 1, + 4, + 9, + Some(pubkey.clone()) + )); + + // No contributions yet + assert_eq!(Crowdloan::contribution_get(u32::from(para), &1).0, 0); + + // Missing signature + assert_noop!( + Crowdloan::contribute(RuntimeOrigin::signed(1), para, 49, None), + Error::::InvalidSignature + ); + + let payload = (0u32, 1u64, 0u64, 49u64); + let valid_signature = + crypto::create_ed25519_signature(&payload.encode(), pubkey.clone()); + let invalid_signature = + MultiSignature::decode(&mut TrailingZeroInput::zeroes()).unwrap(); + + // Invalid signature + assert_noop!( + Crowdloan::contribute(RuntimeOrigin::signed(1), para, 49, Some(invalid_signature)), + Error::::InvalidSignature + ); + + // Valid signature wrong parameter + assert_noop!( + Crowdloan::contribute( + RuntimeOrigin::signed(1), + para, + 50, + Some(valid_signature.clone()) + ), + Error::::InvalidSignature + ); + assert_noop!( + Crowdloan::contribute( + RuntimeOrigin::signed(2), + para, + 49, + Some(valid_signature.clone()) + ), + Error::::InvalidSignature + ); + + // Valid signature + assert_ok!(Crowdloan::contribute( + RuntimeOrigin::signed(1), + para, + 49, + Some(valid_signature.clone()) + )); + + // Reuse valid signature + assert_noop!( + Crowdloan::contribute(RuntimeOrigin::signed(1), para, 49, Some(valid_signature)), + Error::::InvalidSignature + ); + + let payload_2 = (0u32, 1u64, 49u64, 10u64); + let valid_signature_2 = crypto::create_ed25519_signature(&payload_2.encode(), pubkey); + + // New valid signature + assert_ok!(Crowdloan::contribute( + RuntimeOrigin::signed(1), + para, + 10, + Some(valid_signature_2) + )); + + // Contributions appear in free balance of crowdloan + assert_eq!(Balances::free_balance(Crowdloan::fund_account_id(index)), 59); + + // Contribution amount is correct + let fund = Crowdloan::funds(para).unwrap(); + assert_eq!(fund.raised, 59); + }); + } + + #[test] + fn contribute_handles_basic_errors() { + new_test_ext().execute_with(|| { + let para = new_para(); + + // Cannot contribute to non-existing fund + assert_noop!( + Crowdloan::contribute(RuntimeOrigin::signed(1), para, 49, None), + Error::::InvalidParaId + ); + // Cannot contribute below minimum contribution + assert_noop!( + Crowdloan::contribute(RuntimeOrigin::signed(1), para, 9, None), + Error::::ContributionTooSmall + ); + + // Set up a crowdloan + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 4, 9, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(1), para, 101, None)); + + // Cannot contribute past the limit + assert_noop!( + Crowdloan::contribute(RuntimeOrigin::signed(2), para, 900, None), + Error::::CapExceeded + ); + + // Move past end date + run_to_block(10); + + // Cannot contribute to ended fund + assert_noop!( + Crowdloan::contribute(RuntimeOrigin::signed(1), para, 49, None), + Error::::ContributionPeriodOver + ); + + // If a crowdloan has already won, it should not allow contributions. + let para_2 = new_para(); + let index = NextFundIndex::::get(); + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para_2, 1000, 1, 4, 40, None)); + // Emulate a win by leasing out and putting a deposit. Slots pallet would normally do + // this. + let crowdloan_account = Crowdloan::fund_account_id(index); + set_winner(para_2, crowdloan_account, true); + assert_noop!( + Crowdloan::contribute(RuntimeOrigin::signed(1), para_2, 49, None), + Error::::BidOrLeaseActive + ); + + // Move past lease period 1, should not be allowed to have further contributions with a + // crowdloan that has starting period 1. + let para_3 = new_para(); + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para_3, 1000, 1, 4, 40, None)); + run_to_block(40); + let now = System::block_number(); + assert_eq!(TestAuctioneer::lease_period_index(now).unwrap().0, 2); + assert_noop!( + Crowdloan::contribute(RuntimeOrigin::signed(1), para_3, 49, None), + Error::::ContributionPeriodOver + ); + }); + } + + #[test] + fn cannot_contribute_during_vrf() { + new_test_ext().execute_with(|| { + set_vrf_delay(5); + + let para = new_para(); + let first_period = 1; + let last_period = 4; + + assert_ok!(TestAuctioneer::new_auction(5, 0)); + + // Set up a crowdloan + assert_ok!(Crowdloan::create( + RuntimeOrigin::signed(1), + para, + 1000, + first_period, + last_period, + 20, + None + )); + + run_to_block(8); + // Can def contribute when auction is running. + assert!(TestAuctioneer::auction_status(System::block_number()).is_ending().is_some()); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 250, None)); + + run_to_block(10); + // Can't contribute when auction is in the VRF delay period. + assert!(TestAuctioneer::auction_status(System::block_number()).is_vrf()); + assert_noop!( + Crowdloan::contribute(RuntimeOrigin::signed(2), para, 250, None), + Error::::VrfDelayInProgress + ); + + run_to_block(15); + // Its fine to contribute when no auction is running. + assert!(!TestAuctioneer::auction_status(System::block_number()).is_in_progress()); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 250, None)); + }) + } + + #[test] + fn bidding_works() { + new_test_ext().execute_with(|| { + let para = new_para(); + let index = NextFundIndex::::get(); + let first_period = 1; + let last_period = 4; + + assert_ok!(TestAuctioneer::new_auction(5, 0)); + + // Set up a crowdloan + assert_ok!(Crowdloan::create( + RuntimeOrigin::signed(1), + para, + 1000, + first_period, + last_period, + 9, + None + )); + let bidder = Crowdloan::fund_account_id(index); + + // Fund crowdloan + run_to_block(1); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 100, None)); + run_to_block(3); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(3), para, 150, None)); + run_to_block(5); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(4), para, 200, None)); + run_to_block(8); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 250, None)); + run_to_block(10); + + assert_eq!( + bids(), + vec![ + BidPlaced { height: 5, amount: 250, bidder, para, first_period, last_period }, + BidPlaced { height: 6, amount: 450, bidder, para, first_period, last_period }, + BidPlaced { height: 9, amount: 700, bidder, para, first_period, last_period }, + ] + ); + + // Endings count incremented + assert_eq!(Crowdloan::endings_count(), 1); + }); + } + + #[test] + fn withdraw_from_failed_works() { + new_test_ext().execute_with(|| { + let para = new_para(); + let index = NextFundIndex::::get(); + + // Set up a crowdloan + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 1, 9, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 100, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(3), para, 50, None)); + + run_to_block(10); + let account_id = Crowdloan::fund_account_id(index); + // para has no reserved funds, indicating it did not win the auction. + assert_eq!(Balances::reserved_balance(&account_id), 0); + // but there's still the funds in its balance. + assert_eq!(Balances::free_balance(&account_id), 150); + assert_eq!(Balances::free_balance(2), 1900); + assert_eq!(Balances::free_balance(3), 2950); + + assert_ok!(Crowdloan::withdraw(RuntimeOrigin::signed(2), 2, para)); + assert_eq!(Balances::free_balance(&account_id), 50); + assert_eq!(Balances::free_balance(2), 2000); + + assert_ok!(Crowdloan::withdraw(RuntimeOrigin::signed(2), 3, para)); + assert_eq!(Balances::free_balance(&account_id), 0); + assert_eq!(Balances::free_balance(3), 3000); + }); + } + + #[test] + fn withdraw_cannot_be_griefed() { + new_test_ext().execute_with(|| { + let para = new_para(); + let index = NextFundIndex::::get(); + + // Set up a crowdloan + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 1, 9, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 100, None)); + + run_to_block(10); + let account_id = Crowdloan::fund_account_id(index); + + // user sends the crowdloan funds trying to make an accounting error + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), account_id, 10)); + + // overfunded now + assert_eq!(Balances::free_balance(&account_id), 110); + assert_eq!(Balances::free_balance(2), 1900); + + assert_ok!(Crowdloan::withdraw(RuntimeOrigin::signed(2), 2, para)); + assert_eq!(Balances::free_balance(2), 2000); + + // Some funds are left over + assert_eq!(Balances::free_balance(&account_id), 10); + // They wil be left in the account at the end + assert_ok!(Crowdloan::dissolve(RuntimeOrigin::signed(1), para)); + assert_eq!(Balances::free_balance(&account_id), 10); + }); + } + + #[test] + fn refund_works() { + new_test_ext().execute_with(|| { + let para = new_para(); + let index = NextFundIndex::::get(); + let account_id = Crowdloan::fund_account_id(index); + + // Set up a crowdloan ending on 9 + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 1, 9, None)); + // Make some contributions + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(1), para, 100, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 200, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(3), para, 300, None)); + + assert_eq!(Balances::free_balance(account_id), 600); + + // Can't refund before the crowdloan it has ended + assert_noop!( + Crowdloan::refund(RuntimeOrigin::signed(1337), para), + Error::::FundNotEnded, + ); + + // Move to the end of the crowdloan + run_to_block(10); + assert_ok!(Crowdloan::refund(RuntimeOrigin::signed(1337), para)); + + // Funds are returned + assert_eq!(Balances::free_balance(account_id), 0); + // 1 deposit for the crowdloan which hasn't dissolved yet. + assert_eq!(Balances::free_balance(1), 1000 - 1); + assert_eq!(Balances::free_balance(2), 2000); + assert_eq!(Balances::free_balance(3), 3000); + }); + } + + #[test] + fn multiple_refund_works() { + new_test_ext().execute_with(|| { + let para = new_para(); + let index = NextFundIndex::::get(); + let account_id = Crowdloan::fund_account_id(index); + + // Set up a crowdloan ending on 9 + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para, 100000, 1, 1, 9, None)); + // Make more contributions than our limit + for i in 1..=RemoveKeysLimit::get() * 2 { + Balances::make_free_balance_be(&i.into(), (1000 * i).into()); + assert_ok!(Crowdloan::contribute( + RuntimeOrigin::signed(i.into()), + para, + (i * 100).into(), + None + )); + } + + assert_eq!(Balances::free_balance(account_id), 21000); + + // Move to the end of the crowdloan + run_to_block(10); + assert_ok!(Crowdloan::refund(RuntimeOrigin::signed(1337), para)); + assert_eq!( + last_event(), + super::Event::::PartiallyRefunded { para_id: para }.into() + ); + + // Funds still left over + assert!(!Balances::free_balance(account_id).is_zero()); + + // Call again + assert_ok!(Crowdloan::refund(RuntimeOrigin::signed(1337), para)); + assert_eq!(last_event(), super::Event::::AllRefunded { para_id: para }.into()); + + // Funds are returned + assert_eq!(Balances::free_balance(account_id), 0); + // 1 deposit for the crowdloan which hasn't dissolved yet. + for i in 1..=RemoveKeysLimit::get() * 2 { + assert_eq!(Balances::free_balance(&i.into()), i as u64 * 1000); + } + }); + } + + #[test] + fn refund_and_dissolve_works() { + new_test_ext().execute_with(|| { + let para = new_para(); + let issuance = Balances::total_issuance(); + + // Set up a crowdloan + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 1, 9, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 100, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(3), para, 50, None)); + + run_to_block(10); + // All funds are refunded + assert_ok!(Crowdloan::refund(RuntimeOrigin::signed(2), para)); + + // Now that `fund.raised` is zero, it can be dissolved. + assert_ok!(Crowdloan::dissolve(RuntimeOrigin::signed(1), para)); + assert_eq!(Balances::free_balance(1), 1000); + assert_eq!(Balances::free_balance(2), 2000); + assert_eq!(Balances::free_balance(3), 3000); + assert_eq!(Balances::total_issuance(), issuance); + }); + } + + #[test] + fn dissolve_works() { + new_test_ext().execute_with(|| { + let para = new_para(); + let issuance = Balances::total_issuance(); + + // Set up a crowdloan + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 1, 9, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 100, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(3), para, 50, None)); + + // Can't dissolve before it ends + assert_noop!( + Crowdloan::dissolve(RuntimeOrigin::signed(1), para), + Error::::NotReadyToDissolve + ); + + run_to_block(10); + set_winner(para, 1, true); + // Can't dissolve when it won. + assert_noop!( + Crowdloan::dissolve(RuntimeOrigin::signed(1), para), + Error::::NotReadyToDissolve + ); + set_winner(para, 1, false); + + // Can't dissolve while it still has user funds + assert_noop!( + Crowdloan::dissolve(RuntimeOrigin::signed(1), para), + Error::::NotReadyToDissolve + ); + + // All funds are refunded + assert_ok!(Crowdloan::refund(RuntimeOrigin::signed(2), para)); + + // Now that `fund.raised` is zero, it can be dissolved. + assert_ok!(Crowdloan::dissolve(RuntimeOrigin::signed(1), para)); + assert_eq!(Balances::free_balance(1), 1000); + assert_eq!(Balances::free_balance(2), 2000); + assert_eq!(Balances::free_balance(3), 3000); + assert_eq!(Balances::total_issuance(), issuance); + }); + } + + #[test] + fn withdraw_from_finished_works() { + new_test_ext().execute_with(|| { + assert_eq!(::ExistentialDeposit::get(), 1); + let para = new_para(); + let index = NextFundIndex::::get(); + let account_id = Crowdloan::fund_account_id(index); + + // Set up a crowdloan + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 1, 9, None)); + + // Fund crowdloans. + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 100, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(3), para, 50, None)); + // simulate the reserving of para's funds. this actually happens in the Slots pallet. + assert_ok!(Balances::reserve(&account_id, 149)); + + run_to_block(19); + assert_noop!( + Crowdloan::withdraw(RuntimeOrigin::signed(2), 2, para), + Error::::BidOrLeaseActive + ); + + run_to_block(20); + // simulate the unreserving of para's funds, now that the lease expired. this actually + // happens in the Slots pallet. + Balances::unreserve(&account_id, 150); + + // para has no reserved funds, indicating it did ot win the auction. + assert_eq!(Balances::reserved_balance(&account_id), 0); + // but there's still the funds in its balance. + assert_eq!(Balances::free_balance(&account_id), 150); + assert_eq!(Balances::free_balance(2), 1900); + assert_eq!(Balances::free_balance(3), 2950); + + assert_ok!(Crowdloan::withdraw(RuntimeOrigin::signed(2), 2, para)); + assert_eq!(Balances::free_balance(&account_id), 50); + assert_eq!(Balances::free_balance(2), 2000); + + assert_ok!(Crowdloan::withdraw(RuntimeOrigin::signed(2), 3, para)); + assert_eq!(Balances::free_balance(&account_id), 0); + assert_eq!(Balances::free_balance(3), 3000); + }); + } + + #[test] + fn on_swap_works() { + new_test_ext().execute_with(|| { + let para_1 = new_para(); + let para_2 = new_para(); + + // Set up crowdloans + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para_1, 1000, 1, 1, 9, None)); + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para_2, 1000, 1, 1, 9, None)); + // Different contributions + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para_1, 100, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(3), para_2, 50, None)); + // Original state + assert_eq!(Funds::::get(para_1).unwrap().raised, 100); + assert_eq!(Funds::::get(para_2).unwrap().raised, 50); + // Swap + Crowdloan::on_swap(para_1, para_2); + // Final state + assert_eq!(Funds::::get(para_2).unwrap().raised, 100); + assert_eq!(Funds::::get(para_1).unwrap().raised, 50); + }); + } + + #[test] + fn cannot_create_fund_when_already_active() { + new_test_ext().execute_with(|| { + let para_1 = new_para(); + + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para_1, 1000, 1, 1, 9, None)); + // Cannot create a fund again + assert_noop!( + Crowdloan::create(RuntimeOrigin::signed(1), para_1, 1000, 1, 1, 9, None), + Error::::FundNotEnded, + ); + }); + } + + #[test] + fn edit_works() { + new_test_ext().execute_with(|| { + let para_1 = new_para(); + + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para_1, 1000, 1, 1, 9, None)); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para_1, 100, None)); + let old_crowdloan = Crowdloan::funds(para_1).unwrap(); + + assert_ok!(Crowdloan::edit(RuntimeOrigin::root(), para_1, 1234, 2, 3, 4, None)); + let new_crowdloan = Crowdloan::funds(para_1).unwrap(); + + // Some things stay the same + assert_eq!(old_crowdloan.depositor, new_crowdloan.depositor); + assert_eq!(old_crowdloan.deposit, new_crowdloan.deposit); + assert_eq!(old_crowdloan.raised, new_crowdloan.raised); + + // Some things change + assert!(old_crowdloan.cap != new_crowdloan.cap); + assert!(old_crowdloan.first_period != new_crowdloan.first_period); + assert!(old_crowdloan.last_period != new_crowdloan.last_period); + }); + } + + #[test] + fn add_memo_works() { + new_test_ext().execute_with(|| { + let para_1 = new_para(); + + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para_1, 1000, 1, 1, 9, None)); + // Cant add a memo before you have contributed. + assert_noop!( + Crowdloan::add_memo(RuntimeOrigin::signed(1), para_1, b"hello, world".to_vec()), + Error::::NoContributions, + ); + // Make a contribution. Initially no memo. + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(1), para_1, 100, None)); + assert_eq!(Crowdloan::contribution_get(0u32, &1), (100, vec![])); + // Can't place a memo that is too large. + assert_noop!( + Crowdloan::add_memo(RuntimeOrigin::signed(1), para_1, vec![123; 123]), + Error::::MemoTooLarge, + ); + // Adding a memo to an existing contribution works + assert_ok!(Crowdloan::add_memo( + RuntimeOrigin::signed(1), + para_1, + b"hello, world".to_vec() + )); + assert_eq!(Crowdloan::contribution_get(0u32, &1), (100, b"hello, world".to_vec())); + // Can contribute again and data persists + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(1), para_1, 100, None)); + assert_eq!(Crowdloan::contribution_get(0u32, &1), (200, b"hello, world".to_vec())); + }); + } + + #[test] + fn poke_works() { + new_test_ext().execute_with(|| { + let para_1 = new_para(); + + assert_ok!(TestAuctioneer::new_auction(5, 0)); + assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para_1, 1000, 1, 1, 9, None)); + // Should fail when no contributions. + assert_noop!( + Crowdloan::poke(RuntimeOrigin::signed(1), para_1), + Error::::NoContributions + ); + assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para_1, 100, None)); + run_to_block(6); + assert_ok!(Crowdloan::poke(RuntimeOrigin::signed(1), para_1)); + assert_eq!(Crowdloan::new_raise(), vec![para_1]); + assert_noop!( + Crowdloan::poke(RuntimeOrigin::signed(1), para_1), + Error::::AlreadyInNewRaise + ); + }); + } +} + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking { + use super::{Pallet as Crowdloan, *}; + use frame_support::{assert_ok, traits::OnInitialize}; + use frame_system::RawOrigin; + use runtime_parachains::paras; + use sp_core::crypto::UncheckedFrom; + use sp_runtime::traits::{Bounded, CheckedSub}; + use sp_std::prelude::*; + + use frame_benchmarking::{account, benchmarks, whitelisted_caller}; + + fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); + } + + fn create_fund(id: u32, end: BlockNumberFor) -> ParaId { + let cap = BalanceOf::::max_value(); + let (_, offset) = T::Auctioneer::lease_period_length(); + // Set to the very beginning of lease period index 0. + frame_system::Pallet::::set_block_number(offset); + let now = frame_system::Pallet::::block_number(); + let (lease_period_index, _) = T::Auctioneer::lease_period_index(now).unwrap_or_default(); + let first_period = lease_period_index; + let last_period = + lease_period_index + ((SlotRange::LEASE_PERIODS_PER_SLOT as u32) - 1).into(); + let para_id = id.into(); + + let caller = account("fund_creator", id, 0); + CurrencyOf::::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Assume ed25519 is most complex signature format + let pubkey = crypto::create_ed25519_pubkey(b"//verifier".to_vec()); + + let head_data = T::Registrar::worst_head_data(); + let validation_code = T::Registrar::worst_validation_code(); + assert_ok!(T::Registrar::register( + caller.clone(), + para_id, + head_data, + validation_code.clone() + )); + assert_ok!(paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + validation_code, + )); + T::Registrar::execute_pending_transitions(); + + assert_ok!(Crowdloan::::create( + RawOrigin::Signed(caller).into(), + para_id, + cap, + first_period, + last_period, + end, + Some(pubkey) + )); + + para_id + } + + fn contribute_fund(who: &T::AccountId, index: ParaId) { + CurrencyOf::::make_free_balance_be(&who, BalanceOf::::max_value()); + let value = T::MinContribution::get(); + + let pubkey = crypto::create_ed25519_pubkey(b"//verifier".to_vec()); + let payload = (index, &who, BalanceOf::::default(), value); + let sig = crypto::create_ed25519_signature(&payload.encode(), pubkey); + + assert_ok!(Crowdloan::::contribute( + RawOrigin::Signed(who.clone()).into(), + index, + value, + Some(sig) + )); + } + + benchmarks! { + where_clause { where T: paras::Config } + + create { + let para_id = ParaId::from(1_u32); + let cap = BalanceOf::::max_value(); + let first_period = 0u32.into(); + let last_period = 3u32.into(); + let (lpl, offset) = T::Auctioneer::lease_period_length(); + let end = lpl + offset; + + let caller: T::AccountId = whitelisted_caller(); + let head_data = T::Registrar::worst_head_data(); + let validation_code = T::Registrar::worst_validation_code(); + + let verifier = MultiSigner::unchecked_from(account::<[u8; 32]>("verifier", 0, 0)); + + CurrencyOf::::make_free_balance_be(&caller, BalanceOf::::max_value()); + T::Registrar::register(caller.clone(), para_id, head_data, validation_code.clone())?; + assert_ok!(paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + validation_code, + )); + + T::Registrar::execute_pending_transitions(); + + }: _(RawOrigin::Signed(caller), para_id, cap, first_period, last_period, end, Some(verifier)) + verify { + assert_last_event::(Event::::Created { para_id }.into()) + } + + // Contribute has two arms: PreEnding and Ending, but both are equal complexity. + contribute { + let (lpl, offset) = T::Auctioneer::lease_period_length(); + let end = lpl + offset; + let fund_index = create_fund::(1, end); + let caller: T::AccountId = whitelisted_caller(); + let contribution = T::MinContribution::get(); + CurrencyOf::::make_free_balance_be(&caller, BalanceOf::::max_value()); + assert!(NewRaise::::get().is_empty()); + + let pubkey = crypto::create_ed25519_pubkey(b"//verifier".to_vec()); + let payload = (fund_index, &caller, BalanceOf::::default(), contribution); + let sig = crypto::create_ed25519_signature(&payload.encode(), pubkey); + + }: _(RawOrigin::Signed(caller.clone()), fund_index, contribution, Some(sig)) + verify { + // NewRaise is appended to, so we don't need to fill it up for worst case scenario. + assert!(!NewRaise::::get().is_empty()); + assert_last_event::(Event::::Contributed { who: caller, fund_index, amount: contribution }.into()); + } + + withdraw { + let (lpl, offset) = T::Auctioneer::lease_period_length(); + let end = lpl + offset; + let fund_index = create_fund::(1337, end); + let caller: T::AccountId = whitelisted_caller(); + let contributor = account("contributor", 0, 0); + contribute_fund::(&contributor, fund_index); + frame_system::Pallet::::set_block_number(BlockNumberFor::::max_value()); + }: _(RawOrigin::Signed(caller), contributor.clone(), fund_index) + verify { + assert_last_event::(Event::::Withdrew { who: contributor, fund_index, amount: T::MinContribution::get() }.into()); + } + + // Worst case: Refund removes `RemoveKeysLimit` keys, and is fully refunded. + #[skip_meta] + refund { + let k in 0 .. T::RemoveKeysLimit::get(); + let (lpl, offset) = T::Auctioneer::lease_period_length(); + let end = lpl + offset; + let fund_index = create_fund::(1337, end); + + // Dissolve will remove at most `RemoveKeysLimit` at once. + for i in 0 .. k { + contribute_fund::(&account("contributor", i, 0), fund_index); + } + + let caller: T::AccountId = whitelisted_caller(); + frame_system::Pallet::::set_block_number(BlockNumberFor::::max_value()); + }: _(RawOrigin::Signed(caller), fund_index) + verify { + assert_last_event::(Event::::AllRefunded { para_id: fund_index }.into()); + } + + dissolve { + let (lpl, offset) = T::Auctioneer::lease_period_length(); + let end = lpl + offset; + let fund_index = create_fund::(1337, end); + let caller: T::AccountId = whitelisted_caller(); + frame_system::Pallet::::set_block_number(BlockNumberFor::::max_value()); + }: _(RawOrigin::Signed(caller.clone()), fund_index) + verify { + assert_last_event::(Event::::Dissolved { para_id: fund_index }.into()); + } + + edit { + let para_id = ParaId::from(1_u32); + let cap = BalanceOf::::max_value(); + let first_period = 0u32.into(); + let last_period = 3u32.into(); + let (lpl, offset) = T::Auctioneer::lease_period_length(); + let end = lpl + offset; + + let caller: T::AccountId = whitelisted_caller(); + let head_data = T::Registrar::worst_head_data(); + let validation_code = T::Registrar::worst_validation_code(); + + let verifier = MultiSigner::unchecked_from(account::<[u8; 32]>("verifier", 0, 0)); + + CurrencyOf::::make_free_balance_be(&caller, BalanceOf::::max_value()); + T::Registrar::register(caller.clone(), para_id, head_data, validation_code.clone())?; + assert_ok!(paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + validation_code, + )); + + T::Registrar::execute_pending_transitions(); + + Crowdloan::::create( + RawOrigin::Signed(caller).into(), + para_id, cap, first_period, last_period, end, Some(verifier.clone()), + )?; + + // Doesn't matter what we edit to, so use the same values. + }: _(RawOrigin::Root, para_id, cap, first_period, last_period, end, Some(verifier)) + verify { + assert_last_event::(Event::::Edited { para_id }.into()) + } + + add_memo { + let (lpl, offset) = T::Auctioneer::lease_period_length(); + let end = lpl + offset; + let fund_index = create_fund::(1, end); + let caller: T::AccountId = whitelisted_caller(); + contribute_fund::(&caller, fund_index); + let worst_memo = vec![42; T::MaxMemoLength::get().into()]; + }: _(RawOrigin::Signed(caller.clone()), fund_index, worst_memo.clone()) + verify { + let fund = Funds::::get(fund_index).expect("fund was created..."); + assert_eq!( + Crowdloan::::contribution_get(fund.fund_index, &caller), + (T::MinContribution::get(), worst_memo), + ); + } + + poke { + let (lpl, offset) = T::Auctioneer::lease_period_length(); + let end = lpl + offset; + let fund_index = create_fund::(1, end); + let caller: T::AccountId = whitelisted_caller(); + contribute_fund::(&caller, fund_index); + NewRaise::::kill(); + assert!(NewRaise::::get().is_empty()); + }: _(RawOrigin::Signed(caller), fund_index) + verify { + assert!(!NewRaise::::get().is_empty()); + assert_last_event::(Event::::AddedToNewRaise { para_id: fund_index }.into()) + } + + // Worst case scenario: N funds are all in the `NewRaise` list, we are + // in the beginning of the ending period, and each fund outbids the next + // over the same periods. + on_initialize { + // We test the complexity over different number of new raise + let n in 2 .. 100; + let (lpl, offset) = T::Auctioneer::lease_period_length(); + let end_block = lpl + offset - 1u32.into(); + + let pubkey = crypto::create_ed25519_pubkey(b"//verifier".to_vec()); + + for i in 0 .. n { + let fund_index = create_fund::(i, end_block); + let contributor: T::AccountId = account("contributor", i, 0); + let contribution = T::MinContribution::get() * (i + 1).into(); + let payload = (fund_index, &contributor, BalanceOf::::default(), contribution); + let sig = crypto::create_ed25519_signature(&payload.encode(), pubkey.clone()); + + CurrencyOf::::make_free_balance_be(&contributor, BalanceOf::::max_value()); + Crowdloan::::contribute(RawOrigin::Signed(contributor).into(), fund_index, contribution, Some(sig))?; + } + + let now = frame_system::Pallet::::block_number(); + let (lease_period_index, _) = T::Auctioneer::lease_period_index(now).unwrap_or_default(); + let duration = end_block + .checked_sub(&frame_system::Pallet::::block_number()) + .ok_or("duration of auction less than zero")?; + T::Auctioneer::new_auction(duration, lease_period_index)?; + + assert_eq!(T::Auctioneer::auction_status(end_block).is_ending(), Some((0u32.into(), 0u32.into()))); + assert_eq!(NewRaise::::get().len(), n as usize); + let old_endings_count = EndingsCount::::get(); + }: { + Crowdloan::::on_initialize(end_block); + } verify { + assert_eq!(EndingsCount::::get(), old_endings_count + 1); + assert_last_event::(Event::::HandleBidResult { para_id: (n - 1).into(), result: Ok(()) }.into()); + } + + impl_benchmark_test_suite!( + Crowdloan, + crate::integration_tests::new_test_ext_with_offset(10), + crate::integration_tests::Test, + ); + } +} diff --git a/polkadot/runtime/common/src/elections.rs b/polkadot/runtime/common/src/elections.rs new file mode 100644 index 0000000000000000000000000000000000000000..5fd3971180f6a82c50ba2b9797a4fcf1334e2b7f --- /dev/null +++ b/polkadot/runtime/common/src/elections.rs @@ -0,0 +1,62 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Code for elections. + +/// Implements the weight types for the elections module and a specific +/// runtime. +/// This macro should not be called directly; use [`impl_runtime_weights`] instead. +#[macro_export] +macro_rules! impl_elections_weights { + ($runtime:ident) => { + parameter_types! { + /// A limit for off-chain phragmen unsigned solution submission. + /// + /// We want to keep it as high as possible, but can't risk having it reject, + /// so we always subtract the base block execution weight. + pub OffchainSolutionWeightLimit: Weight = BlockWeights::get() + .get(DispatchClass::Normal) + .max_extrinsic + .expect("Normal extrinsics have weight limit configured by default; qed") + .saturating_sub($runtime::weights::BlockExecutionWeight::get()); + + /// A limit for off-chain phragmen unsigned solution length. + /// + /// We allow up to 90% of the block's size to be consumed by the solution. + pub OffchainSolutionLengthLimit: u32 = Perbill::from_rational(90_u32, 100) * + *BlockLength::get() + .max + .get(DispatchClass::Normal); + } + }; +} + +/// The numbers configured here could always be more than the the maximum limits of staking pallet +/// to ensure election snapshot will not run out of memory. For now, we set them to smaller values +/// since the staking is bounded and the weight pipeline takes hours for this single pallet. +pub struct BenchmarkConfig; +impl pallet_election_provider_multi_phase::BenchmarkingConfig for BenchmarkConfig { + const VOTERS: [u32; 2] = [1000, 2000]; + const TARGETS: [u32; 2] = [500, 1000]; + const ACTIVE_VOTERS: [u32; 2] = [500, 800]; + const DESIRED_TARGETS: [u32; 2] = [200, 400]; + const SNAPSHOT_MAXIMUM_VOTERS: u32 = 1000; + const MINER_MAXIMUM_VOTERS: u32 = 1000; + const MAXIMUM_TARGETS: u32 = 300; +} + +/// The accuracy type used for genesis election provider; +pub type OnChainAccuracy = sp_runtime::Perbill; diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs new file mode 100644 index 0000000000000000000000000000000000000000..0d0dee2e9ad9187123d3828c71c7f5d208880f7d --- /dev/null +++ b/polkadot/runtime/common/src/impls.rs @@ -0,0 +1,293 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Auxiliary `struct`/`enum`s for polkadot runtime. + +use crate::NegativeImbalance; +use frame_support::traits::{Currency, Imbalance, OnUnbalanced}; +use primitives::Balance; +use sp_runtime::Perquintill; + +/// Logic for the author to get a portion of fees. +pub struct ToAuthor(sp_std::marker::PhantomData); +impl OnUnbalanced> for ToAuthor +where + R: pallet_balances::Config + pallet_authorship::Config, + ::AccountId: From, + ::AccountId: Into, +{ + fn on_nonzero_unbalanced(amount: NegativeImbalance) { + if let Some(author) = >::author() { + >::resolve_creating(&author, amount); + } + } +} + +pub struct DealWithFees(sp_std::marker::PhantomData); +impl OnUnbalanced> for DealWithFees +where + R: pallet_balances::Config + pallet_treasury::Config + pallet_authorship::Config, + pallet_treasury::Pallet: OnUnbalanced>, + ::AccountId: From, + ::AccountId: Into, +{ + fn on_unbalanceds(mut fees_then_tips: impl Iterator>) { + if let Some(fees) = fees_then_tips.next() { + // for fees, 80% to treasury, 20% to author + let mut split = fees.ration(80, 20); + if let Some(tips) = fees_then_tips.next() { + // for tips, if any, 100% to author + tips.merge_into(&mut split.1); + } + use pallet_treasury::Pallet as Treasury; + as OnUnbalanced<_>>::on_unbalanced(split.0); + as OnUnbalanced<_>>::on_unbalanced(split.1); + } + } +} + +pub fn era_payout( + total_staked: Balance, + total_stakable: Balance, + max_annual_inflation: Perquintill, + period_fraction: Perquintill, + auctioned_slots: u64, +) -> (Balance, Balance) { + use pallet_staking_reward_fn::compute_inflation; + use sp_runtime::traits::Saturating; + + let min_annual_inflation = Perquintill::from_rational(25u64, 1000u64); + let delta_annual_inflation = max_annual_inflation.saturating_sub(min_annual_inflation); + + // 30% reserved for up to 60 slots. + let auction_proportion = Perquintill::from_rational(auctioned_slots.min(60), 200u64); + + // Therefore the ideal amount at stake (as a percentage of total issuance) is 75% less the + // amount that we expect to be taken up with auctions. + let ideal_stake = Perquintill::from_percent(75).saturating_sub(auction_proportion); + + let stake = Perquintill::from_rational(total_staked, total_stakable); + let falloff = Perquintill::from_percent(5); + let adjustment = compute_inflation(stake, ideal_stake, falloff); + let staking_inflation = + min_annual_inflation.saturating_add(delta_annual_inflation * adjustment); + + let max_payout = period_fraction * max_annual_inflation * total_stakable; + let staking_payout = (period_fraction * staking_inflation) * total_stakable; + let rest = max_payout.saturating_sub(staking_payout); + + let other_issuance = total_stakable.saturating_sub(total_staked); + if total_staked > other_issuance { + let _cap_rest = Perquintill::from_rational(other_issuance, total_staked) * staking_payout; + // We don't do anything with this, but if we wanted to, we could introduce a cap on the + // treasury amount with: `rest = rest.min(cap_rest);` + } + (staking_payout, rest) +} + +#[cfg(test)] +mod tests { + use super::*; + use frame_support::{ + dispatch::DispatchClass, + parameter_types, + traits::{ConstU32, FindAuthor}, + weights::Weight, + PalletId, + }; + use frame_system::limits; + use primitives::AccountId; + use sp_core::{ConstU64, H256}; + use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + BuildStorage, Perbill, + }; + + type Block = frame_system::mocking::MockBlock; + const TEST_ACCOUNT: AccountId = AccountId::new([1; 32]); + + frame_support::construct_runtime!( + pub enum Test + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Authorship: pallet_authorship::{Pallet, Storage}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, + } + ); + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder() + .base_block(Weight::from_parts(10, 0)) + .for_class(DispatchClass::all(), |weight| { + weight.base_extrinsic = Weight::from_parts(100, 0); + }) + .for_class(DispatchClass::non_mandatory(), |weight| { + weight.max_total = Some(Weight::from_parts(1024, u64::MAX)); + }) + .build_or_panic(); + pub BlockLength: limits::BlockLength = limits::BlockLength::max(2 * 1024); + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type Nonce = u64; + type RuntimeCall = RuntimeCall; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type BlockLength = BlockLength; + type BlockWeights = BlockWeights; + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + } + + impl pallet_balances::Config for Test { + type Balance = u64; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ConstU64<1>; + type AccountStore = System; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<1>; + type MaxFreezes = ConstU32<1>; + } + + parameter_types! { + pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); + pub const MaxApprovals: u32 = 100; + } + + impl pallet_treasury::Config for Test { + type Currency = pallet_balances::Pallet; + type ApproveOrigin = frame_system::EnsureRoot; + type RejectOrigin = frame_system::EnsureRoot; + type RuntimeEvent = RuntimeEvent; + type OnSlash = (); + type ProposalBond = (); + type ProposalBondMinimum = (); + type ProposalBondMaximum = (); + type SpendPeriod = (); + type Burn = (); + type BurnDestination = (); + type PalletId = TreasuryPalletId; + type SpendFunds = (); + type MaxApprovals = MaxApprovals; + type WeightInfo = (); + type SpendOrigin = frame_support::traits::NeverEnsureOrigin; + } + + pub struct OneAuthor; + impl FindAuthor for OneAuthor { + fn find_author<'a, I>(_: I) -> Option + where + I: 'a, + { + Some(TEST_ACCOUNT) + } + } + impl pallet_authorship::Config for Test { + type FindAuthor = OneAuthor; + type EventHandler = (); + } + + pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + // We use default for brevity, but you can configure as desired if needed. + pallet_balances::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); + t.into() + } + + #[test] + fn test_fees_and_tip_split() { + new_test_ext().execute_with(|| { + let fee = Balances::issue(10); + let tip = Balances::issue(20); + + assert_eq!(Balances::free_balance(Treasury::account_id()), 0); + assert_eq!(Balances::free_balance(TEST_ACCOUNT), 0); + + DealWithFees::on_unbalanceds(vec![fee, tip].into_iter()); + + // Author gets 100% of tip and 20% of fee = 22 + assert_eq!(Balances::free_balance(TEST_ACCOUNT), 22); + // Treasury gets 80% of fee + assert_eq!(Balances::free_balance(Treasury::account_id()), 8); + }); + } + + #[test] + fn compute_inflation_should_give_sensible_results() { + assert_eq!( + pallet_staking_reward_fn::compute_inflation( + Perquintill::from_percent(75), + Perquintill::from_percent(75), + Perquintill::from_percent(5), + ), + Perquintill::one() + ); + assert_eq!( + pallet_staking_reward_fn::compute_inflation( + Perquintill::from_percent(50), + Perquintill::from_percent(75), + Perquintill::from_percent(5), + ), + Perquintill::from_rational(2u64, 3u64) + ); + assert_eq!( + pallet_staking_reward_fn::compute_inflation( + Perquintill::from_percent(80), + Perquintill::from_percent(75), + Perquintill::from_percent(5), + ), + Perquintill::from_rational(1u64, 2u64) + ); + } + + #[test] + fn era_payout_should_give_sensible_results() { + assert_eq!( + era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0,), + (10, 0) + ); + assert_eq!( + era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0,), + (6, 4) + ); + } +} diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..f78347dedd8caadc209001bfa8894d8fa2f900f6 --- /dev/null +++ b/polkadot/runtime/common/src/integration_tests.rs @@ -0,0 +1,1698 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Mocking utilities for testing with real pallets. + +use crate::{ + auctions, crowdloan, + mock::{conclude_pvf_checking, validators_public_keys}, + paras_registrar, + slot_range::SlotRange, + slots, + traits::{AuctionStatus, Auctioneer, Leaser, Registrar as RegistrarT}, +}; +use frame_support::{ + assert_noop, assert_ok, parameter_types, + traits::{ConstU32, Currency, OnFinalize, OnInitialize}, + weights::Weight, + PalletId, +}; +use frame_support_test::TestRandomness; +use frame_system::EnsureRoot; +use parity_scale_codec::Encode; +use primitives::{ + BlockNumber, HeadData, Id as ParaId, SessionIndex, ValidationCode, LOWEST_PUBLIC_ID, +}; +use runtime_parachains::{ + configuration, origin, paras, shared, Origin as ParaOrigin, ParaLifecycle, +}; +use sp_core::H256; +use sp_io::TestExternalities; +use sp_keyring::Sr25519Keyring; +use sp_keystore::{testing::MemoryKeystore, KeystoreExt}; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup, One}, + transaction_validity::TransactionPriority, + AccountId32, BuildStorage, +}; +use sp_std::sync::Arc; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlockU32; + +type AccountId = AccountId32; +type Balance = u32; +type Moment = u32; + +fn account_id(i: u32) -> AccountId32 { + let b4 = i.encode(); + let b32 = [&b4[..], &b4[..], &b4[..], &b4[..], &b4[..], &b4[..], &b4[..], &b4[..]].concat(); + let array: [u8; 32] = b32.try_into().unwrap(); + array.into() +} + +fn signed(i: u32) -> RuntimeOrigin { + let account_id = account_id(i); + RuntimeOrigin::signed(account_id) +} + +frame_support::construct_runtime!( + pub enum Test + { + // System Stuff + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned}, + + // Parachains Runtime + Configuration: configuration::{Pallet, Call, Storage, Config}, + Paras: paras::{Pallet, Call, Storage, Event, Config}, + ParasShared: shared::{Pallet, Call, Storage}, + ParachainsOrigin: origin::{Pallet, Origin}, + + // Para Onboarding Pallets + Registrar: paras_registrar::{Pallet, Call, Storage, Event}, + Auctions: auctions::{Pallet, Call, Storage, Event}, + Crowdloan: crowdloan::{Pallet, Call, Storage, Event}, + Slots: slots::{Pallet, Call, Storage, Event}, + } +); + +impl frame_system::offchain::SendTransactionTypes for Test +where + RuntimeCall: From, +{ + type Extrinsic = UncheckedExtrinsic; + type OverarchingCall = RuntimeCall; +} + +use crate::{auctions::Error as AuctionsError, crowdloan::Error as CrowdloanError}; + +parameter_types! { + pub const BlockHashCount: u32 = 250; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max( + Weight::from_parts(4 * 1024 * 1024, u64::MAX), + ); +} + +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = BlockWeights; + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub const EpochDuration: u64 = 10; + pub const ExpectedBlockTime: Moment = 6_000; + pub const ReportLongevity: u64 = 10; + pub const MaxAuthorities: u32 = 100_000; +} + +impl pallet_babe::Config for Test { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; + type EpochChangeTrigger = pallet_babe::ExternalTrigger; + type DisabledValidators = (); + type WeightInfo = (); + type MaxAuthorities = MaxAuthorities; + type MaxNominators = ConstU32<0>; + type KeyOwnerProof = sp_core::Void; + type EquivocationReportSystem = (); +} + +parameter_types! { + pub const MinimumPeriod: Moment = 6_000 / 2; +} + +impl pallet_timestamp::Config for Test { + type Moment = Moment; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +parameter_types! { + pub static ExistentialDeposit: Balance = 1; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Test { + type MaxLocks = (); + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +impl configuration::Config for Test { + type WeightInfo = configuration::TestWeightInfo; +} + +impl shared::Config for Test {} + +impl origin::Config for Test {} + +parameter_types! { + pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +impl paras::Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = paras::TestWeightInfo; + type UnsignedPriority = ParasUnsignedPriority; + type QueueFootprinter = (); + type NextSessionRotation = crate::mock::TestNextSessionRotation; +} + +parameter_types! { + pub const ParaDeposit: Balance = 500; + pub const DataDepositPerByte: Balance = 1; +} + +impl paras_registrar::Config for Test { + type RuntimeEvent = RuntimeEvent; + type OnSwap = (Crowdloan, Slots); + type ParaDeposit = ParaDeposit; + type DataDepositPerByte = DataDepositPerByte; + type Currency = Balances; + type RuntimeOrigin = RuntimeOrigin; + type WeightInfo = crate::paras_registrar::TestWeightInfo; +} + +parameter_types! { + pub const EndingPeriod: BlockNumber = 10; + pub const SampleLength: BlockNumber = 1; +} + +impl auctions::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Leaser = Slots; + type Registrar = Registrar; + type EndingPeriod = EndingPeriod; + type SampleLength = SampleLength; + type Randomness = TestRandomness; + type InitiateOrigin = EnsureRoot; + type WeightInfo = crate::auctions::TestWeightInfo; +} + +parameter_types! { + pub const LeasePeriod: BlockNumber = 100; + pub static LeaseOffset: BlockNumber = 5; +} + +impl slots::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Registrar = Registrar; + type LeasePeriod = LeasePeriod; + type LeaseOffset = LeaseOffset; + type ForceOrigin = EnsureRoot; + type WeightInfo = crate::slots::TestWeightInfo; +} + +parameter_types! { + pub const CrowdloanId: PalletId = PalletId(*b"py/cfund"); + pub const SubmissionDeposit: Balance = 100; + pub const MinContribution: Balance = 1; + pub const RemoveKeysLimit: u32 = 100; + pub const MaxMemoLength: u8 = 32; +} + +impl crowdloan::Config for Test { + type RuntimeEvent = RuntimeEvent; + type PalletId = CrowdloanId; + type SubmissionDeposit = SubmissionDeposit; + type MinContribution = MinContribution; + type RemoveKeysLimit = RemoveKeysLimit; + type Registrar = Registrar; + type Auctioneer = Auctions; + type MaxMemoLength = MaxMemoLength; + type WeightInfo = crate::crowdloan::TestWeightInfo; +} + +/// Create a new set of test externalities. +pub fn new_test_ext() -> TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + configuration::GenesisConfig:: { + config: configuration::HostConfiguration { + max_code_size: 2 * 1024 * 1024, // 2 MB + max_head_data_size: 1 * 1024 * 1024, // 1 MB + ..Default::default() + }, + } + .assimilate_storage(&mut t) + .unwrap(); + let keystore = MemoryKeystore::new(); + let mut ext: sp_io::TestExternalities = t.into(); + ext.register_extension(KeystoreExt(Arc::new(keystore))); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +#[cfg(feature = "runtime-benchmarks")] +pub fn new_test_ext_with_offset(n: BlockNumber) -> TestExternalities { + LeaseOffset::set(n); + new_test_ext() +} + +const BLOCKS_PER_SESSION: u32 = 10; + +const VALIDATORS: &[Sr25519Keyring] = &[ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, +]; + +fn maybe_new_session(n: u32) { + if n % BLOCKS_PER_SESSION == 0 { + let session_index = shared::Pallet::::session_index() + 1; + let validators_pub_keys = validators_public_keys(VALIDATORS); + + shared::Pallet::::set_session_index(session_index); + shared::Pallet::::set_active_validators_ascending(validators_pub_keys); + Paras::test_on_new_session(); + } +} + +fn test_genesis_head(size: usize) -> HeadData { + HeadData(vec![0u8; size]) +} + +fn test_validation_code(size: usize) -> ValidationCode { + let validation_code = vec![0u8; size as usize]; + ValidationCode(validation_code) +} + +fn para_origin(id: u32) -> ParaOrigin { + ParaOrigin::Parachain(id.into()) +} + +fn add_blocks(n: u32) { + let block_number = System::block_number(); + run_to_block(block_number + n); +} + +fn run_to_block(n: u32) { + assert!(System::block_number() < n); + while System::block_number() < n { + let block_number = System::block_number(); + AllPalletsWithSystem::on_finalize(block_number); + System::set_block_number(block_number + 1); + maybe_new_session(block_number + 1); + AllPalletsWithSystem::on_initialize(block_number + 1); + } +} + +fn run_to_session(n: u32) { + let block_number = BLOCKS_PER_SESSION * n; + run_to_block(block_number); +} + +fn last_event() -> RuntimeEvent { + System::events().pop().expect("RuntimeEvent expected").event +} + +fn contains_event(event: RuntimeEvent) -> bool { + System::events().iter().any(|x| x.event == event) +} + +// Runs an end to end test of the auction, crowdloan, slots, and onboarding process over varying +// lease period offsets. +#[test] +fn basic_end_to_end_works() { + for offset in [0u32, 50, 100, 200].iter() { + LeaseOffset::set(*offset); + new_test_ext().execute_with(|| { + let para_1 = LOWEST_PUBLIC_ID; + let para_2 = LOWEST_PUBLIC_ID + 1; + assert!(System::block_number().is_one()); + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + let start_block = System::block_number(); + + // User 1 and 2 will own parachains + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); + // First register 2 on-demand parachains + let genesis_head = Registrar::worst_head_data(); + let validation_code = Registrar::worst_validation_code(); + assert_ok!(Registrar::reserve(signed(1))); + assert_ok!(Registrar::register( + signed(1), + ParaId::from(para_1), + genesis_head.clone(), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + assert_ok!(Registrar::reserve(signed(2))); + assert_ok!(Registrar::register( + signed(2), + ParaId::from(2001), + genesis_head, + validation_code, + )); + + // Paras should be onboarding + assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Onboarding)); + assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Onboarding)); + + // Start a new auction in the future + let duration = 99u32 + offset; + let lease_period_index_start = 4u32; + assert_ok!(Auctions::new_auction( + RuntimeOrigin::root(), + duration, + lease_period_index_start + )); + + // 2 sessions later they are parathreads (on-demand parachains) + run_to_session(START_SESSION_INDEX + 2); + assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parathread)); + assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parathread)); + + // Para 1 will bid directly for slot 1, 2 + // Open a crowdloan for Para 2 for slot 3, 4 + assert_ok!(Crowdloan::create( + signed(2), + ParaId::from(para_2), + 1_000, // Cap + lease_period_index_start + 2, // First Slot + lease_period_index_start + 3, // Last Slot + 200 + offset, // Block End + None, + )); + let fund_2 = Crowdloan::funds(ParaId::from(para_2)).unwrap(); + let crowdloan_account = Crowdloan::fund_account_id(fund_2.fund_index); + + // Auction ending begins on block 100 + offset, so we make a bid before then. + run_to_block(start_block + 90 + offset); + + Balances::make_free_balance_be(&account_id(10), 1_000_000_000); + Balances::make_free_balance_be(&account_id(20), 1_000_000_000); + + // User 10 will bid directly for parachain 1 + assert_ok!(Auctions::bid( + signed(10), + ParaId::from(para_1), + 1, // Auction Index + lease_period_index_start + 0, // First Slot + lease_period_index_start + 1, // Last slot + 910, // Amount + )); + + // User 2 will be a contribute to crowdloan for parachain 2 + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(2), ParaId::from(para_2), 920, None)); + + // Auction ends at block 110 + offset + run_to_block(start_block + 109 + offset); + assert!(contains_event( + crowdloan::Event::::HandleBidResult { + para_id: ParaId::from(para_2), + result: Ok(()) + } + .into() + )); + run_to_block(start_block + 110 + offset); + assert_eq!( + last_event(), + auctions::Event::::AuctionClosed { auction_index: 1 }.into() + ); + + // Paras should have won slots + assert_eq!( + slots::Leases::::get(ParaId::from(para_1)), + // -- 1 --- 2 --- 3 --------- 4 ------------ 5 -------- + vec![None, None, None, Some((account_id(10), 910)), Some((account_id(10), 910))], + ); + assert_eq!( + slots::Leases::::get(ParaId::from(para_2)), + // -- 1 --- 2 --- 3 --- 4 --- 5 ---------------- 6 --------------------------- 7 + // ---------------- + vec![ + None, + None, + None, + None, + None, + Some((crowdloan_account.clone(), 920)), + Some((crowdloan_account.clone(), 920)) + ], + ); + + // Should not be able to contribute to a winning crowdloan + Balances::make_free_balance_be(&account_id(3), 1_000_000_000); + assert_noop!( + Crowdloan::contribute(signed(3), ParaId::from(2001), 10, None), + CrowdloanError::::BidOrLeaseActive + ); + + // New leases will start on block 400 + let lease_start_block = start_block + 400 + offset; + run_to_block(lease_start_block); + + // First slot, Para 1 should be transitioning to lease holding Parachain + assert_eq!( + Paras::lifecycle(ParaId::from(para_1)), + Some(ParaLifecycle::UpgradingParathread) + ); + assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parathread)); + + // Two sessions later, it has upgraded + run_to_block(lease_start_block + 20); + assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parachain)); + assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parathread)); + + // Second slot nothing happens :) + run_to_block(lease_start_block + 100); + assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parachain)); + assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parathread)); + + // Third slot, Para 2 should be upgrading, and Para 1 is downgrading + run_to_block(lease_start_block + 200); + assert_eq!( + Paras::lifecycle(ParaId::from(para_1)), + Some(ParaLifecycle::DowngradingParachain) + ); + assert_eq!( + Paras::lifecycle(ParaId::from(para_2)), + Some(ParaLifecycle::UpgradingParathread) + ); + + // Two sessions later, they have transitioned + run_to_block(lease_start_block + 220); + assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parathread)); + assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parachain)); + + // Fourth slot nothing happens :) + run_to_block(lease_start_block + 300); + assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parathread)); + assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parachain)); + + // Fifth slot, Para 2 is downgrading + run_to_block(lease_start_block + 400); + assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parathread)); + assert_eq!( + Paras::lifecycle(ParaId::from(para_2)), + Some(ParaLifecycle::DowngradingParachain) + ); + + // Two sessions later, Para 2 is downgraded + run_to_block(lease_start_block + 420); + assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parathread)); + assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parathread)); + }); + } +} + +#[test] +fn basic_errors_fail() { + new_test_ext().execute_with(|| { + assert!(System::block_number().is_one()); + let para_id = LOWEST_PUBLIC_ID; + // Can't double register + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); + + let genesis_head = Registrar::worst_head_data(); + let validation_code = Registrar::worst_validation_code(); + assert_ok!(Registrar::reserve(signed(1))); + assert_ok!(Registrar::register( + signed(1), + para_id, + genesis_head.clone(), + validation_code.clone(), + )); + assert_ok!(Registrar::reserve(signed(2))); + assert_noop!( + Registrar::register(signed(2), para_id, genesis_head, validation_code,), + paras_registrar::Error::::NotOwner + ); + + // Start an auction + let duration = 99u32; + let lease_period_index_start = 4u32; + assert_ok!(Auctions::new_auction( + RuntimeOrigin::root(), + duration, + lease_period_index_start + )); + + // Cannot create a crowdloan if you do not own the para + assert_noop!( + Crowdloan::create( + signed(2), + para_id, + 1_000, // Cap + lease_period_index_start + 2, // First Slot + lease_period_index_start + 3, // Last Slot + 200, // Block End + None, + ), + crowdloan::Error::::InvalidOrigin + ); + }); +} + +#[test] +fn competing_slots() { + // This test will verify that competing slots, from different sources will resolve + // appropriately. + new_test_ext().execute_with(|| { + assert!(System::block_number().is_one()); + let max_bids = 10u32; + let para_id = LOWEST_PUBLIC_ID; + + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + // Create n paras and owners + let validation_code = Registrar::worst_validation_code(); + for n in 1..=max_bids { + Balances::make_free_balance_be(&account_id(n), 1_000_000_000); + let genesis_head = Registrar::worst_head_data(); + assert_ok!(Registrar::reserve(signed(n))); + assert_ok!(Registrar::register( + signed(n), + para_id + n - 1, + genesis_head, + validation_code.clone(), + )); + } + // The code undergoing the prechecking is the same for all paras. + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + // Start a new auction in the future + let duration = 149u32; + let lease_period_index_start = 4u32; + assert_ok!(Auctions::new_auction( + RuntimeOrigin::root(), + duration, + lease_period_index_start + )); + + // Paras should be onboarded + run_to_session(START_SESSION_INDEX + 2); + + for n in 1..=max_bids { + // Increment block number + run_to_block(System::block_number() + 10); + + Balances::make_free_balance_be(&account_id(n * 10), n * 1_000); + + let (start, end) = match n { + 1 => (0, 0), + 2 => (0, 1), + 3 => (0, 2), + 4 => (0, 3), + 5 => (1, 1), + 6 => (1, 2), + 7 => (1, 3), + 8 => (2, 2), + 9 => (2, 3), + 10 => (3, 3), + _ => panic!("test not meant for this"), + }; + + // Users will bid directly for parachain + assert_ok!(Auctions::bid( + signed(n * 10), + para_id + n - 1, + 1, // Auction Index + lease_period_index_start + start, // First Slot + lease_period_index_start + end, // Last slot + n * 900, // Amount + )); + } + + // Auction should be done after ending period + run_to_block(180); + + // Appropriate Paras should have won slots + // 900 + 4500 + 2x 8100 = 21,600 + // 900 + 4500 + 7200 + 9000 = 21,600 + assert_eq!( + slots::Leases::::get(para_id), + // -- 1 --- 2 --- 3 ---------- 4 ------ + vec![None, None, None, Some((account_id(10), 900))], + ); + assert_eq!( + slots::Leases::::get(para_id + 4), + // -- 1 --- 2 --- 3 --- 4 ---------- 5 ------- + vec![None, None, None, None, Some((account_id(50), 4500))], + ); + // TODO: Is this right? + assert_eq!( + slots::Leases::::get(para_id + 8), + // -- 1 --- 2 --- 3 --- 4 --- 5 ---------- 6 --------------- 7 ------- + vec![ + None, + None, + None, + None, + None, + Some((account_id(90), 8100)), + Some((account_id(90), 8100)) + ], + ); + }); +} + +#[test] +fn competing_bids() { + // This test will verify that competing bids, from different sources will resolve appropriately. + new_test_ext().execute_with(|| { + assert!(System::block_number().is_one()); + + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + let start_para = LOWEST_PUBLIC_ID - 1; + // Create 3 paras and owners + let validation_code = Registrar::worst_validation_code(); + for n in 1..=3 { + Balances::make_free_balance_be(&account_id(n), 1_000_000_000); + let genesis_head = Registrar::worst_head_data(); + assert_ok!(Registrar::reserve(signed(n))); + assert_ok!(Registrar::register( + signed(n), + ParaId::from(start_para + n), + genesis_head, + validation_code.clone(), + )); + } + // The code undergoing the prechecking is the same for all paras. + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + // Finish registration of paras. + run_to_session(START_SESSION_INDEX + 2); + + // Start a new auction in the future + let starting_block = System::block_number(); + let duration = 99u32; + let lease_period_index_start = 4u32; + assert_ok!(Auctions::new_auction( + RuntimeOrigin::root(), + duration, + lease_period_index_start + )); + + for n in 1..=3 { + // Create a crowdloan for each para + assert_ok!(Crowdloan::create( + signed(n), + ParaId::from(start_para + n), + 100_000, // Cap + lease_period_index_start + 2, // First Slot + lease_period_index_start + 3, // Last Slot + 200, // Block End, + None, + )); + } + + for n in 1..=9 { + // Increment block number + run_to_block(starting_block + n * 10); + + Balances::make_free_balance_be(&account_id(n * 10), n * 1_000); + + let para = start_para + n % 3 + 1; + + if n % 2 == 0 { + // User 10 will bid directly for parachain 1 + assert_ok!(Auctions::bid( + signed(n * 10), + ParaId::from(para), + 1, // Auction Index + lease_period_index_start + 0, // First Slot + lease_period_index_start + 1, // Last slot + n * 900, // Amount + )); + } else { + // User 20 will be a contribute to crowdloan for parachain 2 + assert_ok!(Crowdloan::contribute( + signed(n * 10), + ParaId::from(para), + n + 900, + None, + )); + } + } + + // Auction should be done + run_to_block(starting_block + 110); + + // Appropriate Paras should have won slots + let fund_1 = Crowdloan::funds(ParaId::from(2000)).unwrap(); + let crowdloan_1 = Crowdloan::fund_account_id(fund_1.fund_index); + assert_eq!( + slots::Leases::::get(ParaId::from(2000)), + // -- 1 --- 2 --- 3 --- 4 --- 5 ------------- 6 ------------------------ 7 + // ------------- + vec![ + None, + None, + None, + None, + None, + Some((crowdloan_1.clone(), 1812)), + Some((crowdloan_1.clone(), 1812)) + ], + ); + assert_eq!( + slots::Leases::::get(ParaId::from(2002)), + // -- 1 --- 2 --- 3 ---------- 4 --------------- 5 ------- + vec![None, None, None, Some((account_id(80), 7200)), Some((account_id(80), 7200))], + ); + }); +} + +#[test] +fn basic_swap_works() { + // This test will test a swap between a lease holding parachain and on-demand parachain works + // successfully. + new_test_ext().execute_with(|| { + assert!(System::block_number().is_one()); /* So events are emitted */ + + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + // User 1 and 2 will own paras + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); + // First register 2 on-demand parachains with different data + let validation_code = test_validation_code(10); + assert_ok!(Registrar::reserve(signed(1))); + assert_ok!(Registrar::register( + signed(1), + ParaId::from(2000), + test_genesis_head(10), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + let validation_code = test_validation_code(20); + assert_ok!(Registrar::reserve(signed(2))); + assert_ok!(Registrar::register( + signed(2), + ParaId::from(2001), + test_genesis_head(20), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + // Paras should be onboarding + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Onboarding)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Onboarding)); + + // Start a new auction in the future + let duration = 99u32; + let lease_period_index_start = 4u32; + assert_ok!(Auctions::new_auction( + RuntimeOrigin::root(), + duration, + lease_period_index_start + )); + + // 2 sessions later they are on-demand parachains + run_to_session(START_SESSION_INDEX + 2); + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parathread)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parathread)); + + // Open a crowdloan for Para 1 for slots 0-3 + assert_ok!(Crowdloan::create( + signed(1), + ParaId::from(2000), + 1_000_000, // Cap + lease_period_index_start + 0, // First Slot + lease_period_index_start + 3, // Last Slot + 200, // Block End + None, + )); + let fund = Crowdloan::funds(ParaId::from(2000)).unwrap(); + let crowdloan_account = Crowdloan::fund_account_id(fund.fund_index); + + // Bunch of contributions + let mut total = 0; + for i in 10..20 { + Balances::make_free_balance_be(&account_id(i), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(i), ParaId::from(2000), 900 - i, None)); + total += 900 - i; + } + assert!(total > 0); + assert_eq!(Balances::free_balance(&crowdloan_account), total); + + // Go to end of auction where everyone won their slots + run_to_block(200); + + // Deposit is appropriately taken + // ----------------------------------------- para deposit --- crowdloan + assert_eq!(Balances::reserved_balance(&account_id(1)), (500 + 10 * 2 * 1) + 100); + assert_eq!(Balances::reserved_balance(&account_id(2)), 500 + 20 * 2 * 1); + assert_eq!(Balances::reserved_balance(&crowdloan_account), total); + // Crowdloan is appropriately set + assert!(Crowdloan::funds(ParaId::from(2000)).is_some()); + assert!(Crowdloan::funds(ParaId::from(2001)).is_none()); + + // New leases will start on block 400 + let lease_start_block = 400; + run_to_block(lease_start_block); + + // Slots are won by Para 1 + assert!(!Slots::lease(ParaId::from(2000)).is_empty()); + assert!(Slots::lease(ParaId::from(2001)).is_empty()); + + // 2 sessions later it is a parachain + run_to_block(lease_start_block + 20); + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parachain)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parathread)); + + // Initiate a swap + assert_ok!(Registrar::swap( + para_origin(2000).into(), + ParaId::from(2000), + ParaId::from(2001) + )); + assert_ok!(Registrar::swap( + para_origin(2001).into(), + ParaId::from(2001), + ParaId::from(2000) + )); + + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::DowngradingParachain)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::UpgradingParathread)); + + // 2 session later they have swapped + run_to_block(lease_start_block + 40); + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parathread)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parachain)); + + // Deregister on-demand parachain + assert_ok!(Registrar::deregister(para_origin(2000).into(), ParaId::from(2000))); + // Correct deposit is unreserved + assert_eq!(Balances::reserved_balance(&account_id(1)), 100); // crowdloan deposit left over + assert_eq!(Balances::reserved_balance(&account_id(2)), 500 + 20 * 2 * 1); + // Crowdloan ownership is swapped + assert!(Crowdloan::funds(ParaId::from(2000)).is_none()); + assert!(Crowdloan::funds(ParaId::from(2001)).is_some()); + // Slot is swapped + assert!(Slots::lease(ParaId::from(2000)).is_empty()); + assert!(!Slots::lease(ParaId::from(2001)).is_empty()); + + // Cant dissolve + assert_noop!( + Crowdloan::dissolve(signed(1), ParaId::from(2000)), + CrowdloanError::::InvalidParaId + ); + assert_noop!( + Crowdloan::dissolve(signed(2), ParaId::from(2001)), + CrowdloanError::::NotReadyToDissolve + ); + + // Go way in the future when the para is offboarded + run_to_block(lease_start_block + 1000); + + // Withdraw of contributions works + assert_eq!(Balances::free_balance(&crowdloan_account), total); + for i in 10..20 { + assert_ok!(Crowdloan::withdraw(signed(i), account_id(i), ParaId::from(2001))); + } + assert_eq!(Balances::free_balance(&crowdloan_account), 0); + + // Dissolve returns the balance of the person who put a deposit for crowdloan + assert_ok!(Crowdloan::dissolve(signed(1), ParaId::from(2001))); + assert_eq!(Balances::reserved_balance(&account_id(1)), 0); + assert_eq!(Balances::reserved_balance(&account_id(2)), 500 + 20 * 2 * 1); + + // Final deregister sets everything back to the start + assert_ok!(Registrar::deregister(para_origin(2001).into(), ParaId::from(2001))); + assert_eq!(Balances::reserved_balance(&account_id(2)), 0); + }) +} + +#[test] +fn parachain_swap_works() { + // This test will test a swap between two parachains works successfully. + new_test_ext().execute_with(|| { + assert!(System::block_number().is_one()); /* So events are emitted */ + + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + // User 1 and 2 will own paras + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); + // First register 2 on-demand parachains with different data + let validation_code = test_validation_code(10); + assert_ok!(Registrar::reserve(signed(1))); + assert_ok!(Registrar::register( + signed(1), + ParaId::from(2000), + test_genesis_head(10), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + let validation_code = test_validation_code(20); + assert_ok!(Registrar::reserve(signed(2))); + assert_ok!(Registrar::register( + signed(2), + ParaId::from(2001), + test_genesis_head(20), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + // Paras should be onboarding + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Onboarding)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Onboarding)); + + assert_eq!( + Balances::total_balance(&Crowdloan::fund_account_id(Crowdloan::next_fund_index())), + 0 + ); + + // Start a new auction in the future + let start_auction = |lease_period_index_start, winner, end| { + let unique_id = winner - 1999u32; + let starting_block = System::block_number(); + let duration = 99u32; + assert_ok!(Auctions::new_auction( + RuntimeOrigin::root(), + duration, + lease_period_index_start + )); + + // 2 sessions later they are on-demand parachains + run_to_block(starting_block + 20); + assert_eq!(Paras::lifecycle(ParaId::from(winner)), Some(ParaLifecycle::Parathread)); + + // Open a crowdloan for Para 1 for slots 0-3 + assert_ok!(Crowdloan::create( + signed(unique_id), + ParaId::from(winner), + 1_000_000, // Cap + lease_period_index_start + 0, // First Slot + lease_period_index_start + 7, // Last Slot + end, // Block End + None, + )); + let winner_fund = Crowdloan::funds(ParaId::from(winner)).unwrap(); + let crowdloan_account = Crowdloan::fund_account_id(winner_fund.fund_index); + + // Bunch of contributions + let mut total = 0; + for i in (unique_id * 10)..(unique_id + 1) * 10 { + Balances::make_free_balance_be(&account_id(i), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(i), ParaId::from(winner), 900 - i, None)); + total += 900 - i; + } + assert!(total > 0); + assert_eq!(Balances::free_balance(&crowdloan_account), total); + + // Go to end of auction where everyone won their slots + run_to_block(end); + + // Crowdloan is appropriately set + assert!(Crowdloan::funds(ParaId::from(winner)).is_some()); + + // New leases will start on block lease period index * 100 + let lease_start_block = lease_period_index_start * 100; + run_to_block(lease_start_block); + }; + + start_auction(4u32, 2000, 200); + // Slots are won by Para 1 + assert!(!Slots::lease(ParaId::from(2000)).is_empty()); + assert!(Slots::lease(ParaId::from(2001)).is_empty()); + + // 2 sessions later it is a parachain + run_to_block(4 * 100 + 20); + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parachain)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parathread)); + + // Let's repeat the process now for another parachain. + start_auction(6u32, 2001, 500); + // Slots are won by Para 1 + assert!(!Slots::lease(ParaId::from(2000)).is_empty()); + assert!(!Slots::lease(ParaId::from(2001)).is_empty()); + + // 2 sessions later it is a parachain + run_to_block(6 * 100 + 20); + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parachain)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parachain)); + + // Currently we are on lease 6 + assert_eq!( + >::lease_period_index(System::block_number()), + Some((6u32, false)) + ); + + // This means that parachain 1 should only have 6 slots left, and parachain 2 has all 8. + assert_eq!(slots::Leases::::get(ParaId::from(2000)).len(), 6); + assert_eq!(slots::Leases::::get(ParaId::from(2001)).len(), 8); + + let fund_2000 = Crowdloan::funds(ParaId::from(2000)).unwrap(); + assert_eq!(fund_2000.fund_index, 0); + assert_eq!( + Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2000.fund_index)), + fund_2000.raised + ); + + let fund_2001 = Crowdloan::funds(ParaId::from(2001)).unwrap(); + assert_eq!(fund_2001.fund_index, 1); + assert_eq!( + Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2001.fund_index)), + fund_2001.raised + ); + + assert_eq!(Slots::lease(ParaId::from(2000)).len(), 6); + assert_eq!(Slots::lease(ParaId::from(2001)).len(), 8); + + // Now we swap them. + assert_ok!(Registrar::swap( + para_origin(2000).into(), + ParaId::from(2000), + ParaId::from(2001) + )); + assert_ok!(Registrar::swap( + para_origin(2001).into(), + ParaId::from(2001), + ParaId::from(2000) + )); + assert!(contains_event( + paras_registrar::Event::::Swapped { + para_id: ParaId::from(2001), + other_id: ParaId::from(2000) + } + .into() + )); + + // Crowdloan Swapped + let fund_2000 = Crowdloan::funds(ParaId::from(2000)).unwrap(); + assert_eq!(fund_2000.fund_index, 1); + assert_eq!( + Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2000.fund_index)), + fund_2000.raised + ); + + let fund_2001 = Crowdloan::funds(ParaId::from(2001)).unwrap(); + assert_eq!(fund_2001.fund_index, 0); + assert_eq!( + Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2001.fund_index)), + fund_2001.raised + ); + + // Slots Swapped + assert_eq!(Slots::lease(ParaId::from(2000)).len(), 8); + assert_eq!(Slots::lease(ParaId::from(2001)).len(), 6); + }) +} + +#[test] +fn crowdloan_ending_period_bid() { + new_test_ext().execute_with(|| { + assert!(System::block_number().is_one()); /* So events are emitted */ + + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + // User 1 and 2 will own paras + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); + // First register 2 on-demand parachains + let validation_code = test_validation_code(10); + assert_ok!(Registrar::reserve(signed(1))); + assert_ok!(Registrar::register( + signed(1), + ParaId::from(2000), + test_genesis_head(10), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + let validation_code = test_validation_code(20); + assert_ok!(Registrar::reserve(signed(2))); + assert_ok!(Registrar::register( + signed(2), + ParaId::from(2001), + test_genesis_head(20), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + // Paras should be onboarding + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Onboarding)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Onboarding)); + + // Start a new auction in the future + let duration = 99u32; + let ends_at = System::block_number() + duration; + let lease_period_index_start = 4u32; + assert_ok!(Auctions::new_auction( + RuntimeOrigin::root(), + duration, + lease_period_index_start + )); + + // 2 sessions later they are on-demand parachains + run_to_session(START_SESSION_INDEX + 2); + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parathread)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parathread)); + + // Open a crowdloan for Para 1 for slots 0-3 + assert_ok!(Crowdloan::create( + signed(1), + ParaId::from(2000), + 1_000_000, // Cap + lease_period_index_start + 0, // First Slot + lease_period_index_start + 3, // Last Slot + 200, // Block End + None, + )); + let fund = Crowdloan::funds(ParaId::from(2000)).unwrap(); + let crowdloan_account = Crowdloan::fund_account_id(fund.fund_index); + + // Bunch of contributions + let mut total = 0; + for i in 10..20 { + Balances::make_free_balance_be(&account_id(i), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(i), ParaId::from(2000), 900 - i, None)); + total += 900 - i; + } + assert!(total > 0); + assert_eq!(Balances::free_balance(&crowdloan_account), total); + + // Bid for para 2 directly + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); + assert_ok!(Auctions::bid( + signed(2), + ParaId::from(2001), + 1, // Auction Index + lease_period_index_start + 0, // First Slot + lease_period_index_start + 1, // Last slot + 900, // Amount + )); + + // Go to beginning of ending period + run_to_block(ends_at); + + assert_eq!(Auctions::auction_status(ends_at), AuctionStatus::::EndingPeriod(0, 0)); + let mut winning = [(); SlotRange::SLOT_RANGE_COUNT].map(|_| None); + + winning[SlotRange::ZeroOne as u8 as usize] = Some((account_id(2), ParaId::from(2001), 900)); + winning[SlotRange::ZeroThree as u8 as usize] = + Some((crowdloan_account.clone(), ParaId::from(2000), total)); + + assert_eq!(Auctions::winning(0), Some(winning)); + + run_to_block(ends_at + 1); + + Balances::make_free_balance_be(&account_id(1234), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(1234), ParaId::from(2000), 900, None)); + + // Data propagates correctly + run_to_block(ends_at + 2); + let mut winning = [(); SlotRange::SLOT_RANGE_COUNT].map(|_| None); + winning[SlotRange::ZeroOne as u8 as usize] = Some((account_id(2), ParaId::from(2001), 900)); + winning[SlotRange::ZeroThree as u8 as usize] = + Some((crowdloan_account.clone(), ParaId::from(2000), total + 900)); + assert_eq!(Auctions::winning(2), Some(winning)); + }) +} + +#[test] +fn auction_bid_requires_registered_para() { + new_test_ext().execute_with(|| { + assert!(System::block_number().is_one()); /* So events are emitted */ + + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + // Start a new auction in the future + let duration = 99u32; + let lease_period_index_start = 4u32; + assert_ok!(Auctions::new_auction( + RuntimeOrigin::root(), + duration, + lease_period_index_start + )); + + // Can't bid with non-registered paras + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + assert_noop!( + Auctions::bid( + signed(1), + ParaId::from(2000), + 1, // Auction Index + lease_period_index_start + 0, // First Slot + lease_period_index_start + 1, // Last slot + 900, // Amount + ), + AuctionsError::::ParaNotRegistered + ); + + // Now we register the para + let validation_code = test_validation_code(10); + assert_ok!(Registrar::reserve(signed(1))); + assert_ok!(Registrar::register( + signed(1), + ParaId::from(2000), + test_genesis_head(10), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + // Still can't bid until it is fully onboarded + assert_noop!( + Auctions::bid( + signed(1), + ParaId::from(2000), + 1, // Auction Index + lease_period_index_start + 0, // First Slot + lease_period_index_start + 1, // Last slot + 900, // Amount + ), + AuctionsError::::ParaNotRegistered + ); + + // Onboarded on Session 2 + run_to_session(START_SESSION_INDEX + 2); + + // Success + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + assert_ok!(Auctions::bid( + signed(1), + ParaId::from(2000), + 1, // Auction Index + lease_period_index_start + 0, // First Slot + lease_period_index_start + 1, // Last slot + 900, // Amount + )); + }); +} + +#[test] +fn gap_bids_work() { + new_test_ext().execute_with(|| { + assert!(System::block_number().is_one()); /* So events are emitted */ + + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + // Start a new auction in the future + let duration = 99u32; + let lease_period_index_start = 4u32; + assert_ok!(Auctions::new_auction( + RuntimeOrigin::root(), + duration, + lease_period_index_start + )); + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); + + // Now register 2 paras + let validation_code = test_validation_code(10); + assert_ok!(Registrar::reserve(signed(1))); + assert_ok!(Registrar::register( + signed(1), + ParaId::from(2000), + test_genesis_head(10), + validation_code.clone(), + )); + assert_ok!(Registrar::reserve(signed(2))); + assert_ok!(Registrar::register( + signed(2), + ParaId::from(2001), + test_genesis_head(10), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + // Onboarded on Session 2 + run_to_session(START_SESSION_INDEX + 2); + + // Make bids + Balances::make_free_balance_be(&account_id(10), 1_000_000_000); + Balances::make_free_balance_be(&account_id(20), 1_000_000_000); + // Slot 1 for 100 from 10 + assert_ok!(Auctions::bid( + signed(10), + ParaId::from(2000), + 1, // Auction Index + lease_period_index_start + 0, // First Slot + lease_period_index_start + 0, // Last slot + 100, // Amount + )); + // Slot 4 for 400 from 10 + assert_ok!(Auctions::bid( + signed(10), + ParaId::from(2000), + 1, // Auction Index + lease_period_index_start + 3, // First Slot + lease_period_index_start + 3, // Last slot + 400, // Amount + )); + + // A bid for another para is counted separately. + assert_ok!(Auctions::bid( + signed(10), + ParaId::from(2001), + 1, // Auction Index + lease_period_index_start + 1, // First Slot + lease_period_index_start + 1, // Last slot + 555, // Amount + )); + assert_eq!(Balances::reserved_balance(&account_id(10)), 400 + 555); + + // Slot 2 for 800 from 20, overtaking 10's bid + assert_ok!(Auctions::bid( + signed(20), + ParaId::from(2000), + 1, // Auction Index + lease_period_index_start + 1, // First Slot + lease_period_index_start + 1, // Last slot + 800, // Amount + )); + // Slot 3 for 200 from 20 + assert_ok!(Auctions::bid( + signed(20), + ParaId::from(2000), + 1, // Auction Index + lease_period_index_start + 2, // First Slot + lease_period_index_start + 2, // Last slot + 200, // Amount + )); + + // Finish the auction + run_to_block(130 + LeaseOffset::get()); + + // Should have won the lease periods + assert_eq!( + slots::Leases::::get(ParaId::from(2000)), + vec![ + // LP 1 + None, + // LP 2 + None, + // LP 3 + None, + // LP 4 + Some((account_id(10), 100)), + // LP 5 + Some((account_id(20), 800)), + // LP 6 + Some((account_id(20), 200)), + // LP 7 + Some((account_id(10), 400)) + ], + ); + // Appropriate amount is reserved (largest of the values) + assert_eq!(Balances::reserved_balance(&account_id(10)), 400); + // Appropriate amount is reserved (largest of the values) + assert_eq!(Balances::reserved_balance(&account_id(20)), 800); + + // Progress through the leases and note the correct amount of balance is reserved. + + add_blocks(300 + LeaseOffset::get()); + assert_eq!( + slots::Leases::::get(ParaId::from(2000)), + vec![ + // LP 4 + Some((account_id(10), 100)), + // LP 5 + Some((account_id(20), 800)), + // LP 6 + Some((account_id(20), 200)), + // LP 7 + Some((account_id(10), 400)) + ], + ); + // Nothing changed. + assert_eq!(Balances::reserved_balance(&account_id(10)), 400); + assert_eq!(Balances::reserved_balance(&account_id(20)), 800); + + // Lease period 4 is done, but nothing is unreserved since user 1 has a debt on lease 7 + add_blocks(100); + assert_eq!( + slots::Leases::::get(ParaId::from(2000)), + vec![ + // LP 5 + Some((account_id(20), 800)), + // LP 6 + Some((account_id(20), 200)), + // LP 7 + Some((account_id(10), 400)) + ], + ); + // Nothing changed. + assert_eq!(Balances::reserved_balance(&account_id(10)), 400); + assert_eq!(Balances::reserved_balance(&account_id(20)), 800); + + // Lease period 5 is done, and 20 will unreserve down to 200. + add_blocks(100); + assert_eq!( + slots::Leases::::get(ParaId::from(2000)), + // --------- 6 -------------- 7 ------- + vec![Some((account_id(20), 200)), Some((account_id(10), 400))], + ); + assert_eq!(Balances::reserved_balance(&account_id(10)), 400); + assert_eq!(Balances::reserved_balance(&account_id(20)), 200); + + // Lease period 6 is done, and 20 will unreserve everything. + add_blocks(100); + assert_eq!( + slots::Leases::::get(ParaId::from(2000)), + // --------- 7 ------- + vec![Some((account_id(10), 400))], + ); + assert_eq!(Balances::reserved_balance(&account_id(10)), 400); + assert_eq!(Balances::reserved_balance(&account_id(20)), 0); + + // All leases are done. Everything is unreserved. + add_blocks(100); + assert_eq!(slots::Leases::::get(ParaId::from(2000)), vec![]); + assert_eq!(Balances::reserved_balance(&account_id(10)), 0); + assert_eq!(Balances::reserved_balance(&account_id(20)), 0); + }); +} + +// This test verifies that if a parachain already has won some lease periods, that it cannot bid for +// any of those same lease periods again. +#[test] +fn cant_bid_on_existing_lease_periods() { + new_test_ext().execute_with(|| { + assert!(System::block_number().is_one()); /* So events are emitted */ + + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + // First register an on-demand parachain + let validation_code = test_validation_code(10); + assert_ok!(Registrar::reserve(signed(1))); + assert_ok!(Registrar::register( + signed(1), + ParaId::from(2000), + test_genesis_head(10), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + // Start a new auction in the future + let starting_block = System::block_number(); + let duration = 99u32; + let lease_period_index_start = 4u32; + assert_ok!(Auctions::new_auction( + RuntimeOrigin::root(), + duration, + lease_period_index_start + )); + + // 2 sessions later they are on-demand parachains + run_to_session(START_SESSION_INDEX + 2); + + // Open a crowdloan for Para 1 for slots 0-3 + assert_ok!(Crowdloan::create( + signed(1), + ParaId::from(2000), + 1_000_000, // Cap + lease_period_index_start + 0, // First Slot + lease_period_index_start + 1, // Last Slot + 400, // Long block end + None, + )); + let fund = Crowdloan::funds(ParaId::from(2000)).unwrap(); + let crowdloan_account = Crowdloan::fund_account_id(fund.fund_index); + + // Bunch of contributions + let mut total = 0; + for i in 10..20 { + Balances::make_free_balance_be(&account_id(i), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(i), ParaId::from(2000), 900 - i, None)); + total += 900 - i; + } + assert!(total > 0); + assert_eq!(Balances::free_balance(&crowdloan_account), total); + + // Finish the auction. + run_to_block(starting_block + 110); + + // Appropriate Paras should have won slots + assert_eq!( + slots::Leases::::get(ParaId::from(2000)), + // -- 1 --- 2 --- 3 ------------- 4 ------------------------ 5 ------------- + vec![ + None, + None, + None, + Some((crowdloan_account.clone(), 8855)), + Some((crowdloan_account.clone(), 8855)) + ], + ); + + // Let's start another auction for the same range + let starting_block = System::block_number(); + let duration = 99u32; + let lease_period_index_start = 4u32; + assert_ok!(Auctions::new_auction( + RuntimeOrigin::root(), + duration, + lease_period_index_start + )); + + // Poke the crowdloan into `NewRaise` + assert_ok!(Crowdloan::poke(signed(1), ParaId::from(2000))); + assert_eq!(Crowdloan::new_raise(), vec![ParaId::from(2000)]); + + // Beginning of ending block. + run_to_block(starting_block + 100); + + // Bids cannot be made which intersect + assert_noop!( + Auctions::bid( + RuntimeOrigin::signed(crowdloan_account.clone()), + ParaId::from(2000), + 2, + lease_period_index_start + 0, + lease_period_index_start + 1, + 100, + ), + AuctionsError::::AlreadyLeasedOut, + ); + + assert_noop!( + Auctions::bid( + RuntimeOrigin::signed(crowdloan_account.clone()), + ParaId::from(2000), + 2, + lease_period_index_start + 1, + lease_period_index_start + 2, + 100, + ), + AuctionsError::::AlreadyLeasedOut, + ); + + assert_noop!( + Auctions::bid( + RuntimeOrigin::signed(crowdloan_account.clone()), + ParaId::from(2000), + 2, + lease_period_index_start - 1, + lease_period_index_start + 0, + 100, + ), + AuctionsError::::AlreadyLeasedOut, + ); + + assert_noop!( + Auctions::bid( + RuntimeOrigin::signed(crowdloan_account.clone()), + ParaId::from(2000), + 2, + lease_period_index_start + 0, + lease_period_index_start + 0, + 100, + ), + AuctionsError::::AlreadyLeasedOut, + ); + + assert_noop!( + Auctions::bid( + RuntimeOrigin::signed(crowdloan_account.clone()), + ParaId::from(2000), + 2, + lease_period_index_start + 1, + lease_period_index_start + 1, + 100, + ), + AuctionsError::::AlreadyLeasedOut, + ); + + assert_noop!( + Auctions::bid( + RuntimeOrigin::signed(crowdloan_account.clone()), + ParaId::from(2000), + 2, + lease_period_index_start - 1, + lease_period_index_start + 5, + 100, + ), + AuctionsError::::AlreadyLeasedOut, + ); + + // Will work when not overlapping + assert_ok!(Auctions::bid( + RuntimeOrigin::signed(crowdloan_account.clone()), + ParaId::from(2000), + 2, + lease_period_index_start + 2, + lease_period_index_start + 3, + 100, + )); + }); +} diff --git a/polkadot/runtime/common/src/lib.rs b/polkadot/runtime/common/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..61968e48832c24edde0fb96ee02fc6044400cae5 --- /dev/null +++ b/polkadot/runtime/common/src/lib.rs @@ -0,0 +1,276 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Common runtime code for Polkadot and Kusama. + +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod assigned_slots; +pub mod auctions; +pub mod claims; +pub mod crowdloan; +pub mod elections; +pub mod impls; +pub mod paras_registrar; +pub mod paras_sudo_wrapper; +pub mod purchase; +pub mod slot_range; +pub mod slots; +pub mod traits; + +#[cfg(feature = "try-runtime")] +pub mod try_runtime; +pub mod xcm_sender; + +#[cfg(test)] +mod integration_tests; +#[cfg(test)] +mod mock; + +use frame_support::{ + parameter_types, + traits::{ConstU32, Currency, OneSessionHandler}, + weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, +}; +use frame_system::limits; +use primitives::{AssignmentId, Balance, BlockNumber, ValidatorId}; +use sp_runtime::{FixedPointNumber, Perbill, Perquintill}; +use static_assertions::const_assert; + +pub use pallet_balances::Call as BalancesCall; +#[cfg(feature = "std")] +pub use pallet_staking::StakerStatus; +pub use pallet_timestamp::Call as TimestampCall; +use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; +pub use sp_runtime::traits::Bounded; +#[cfg(any(feature = "std", test))] +pub use sp_runtime::BuildStorage; + +/// Implementations of some helper traits passed into runtime modules as associated types. +pub use impls::ToAuthor; + +pub type NegativeImbalance = as Currency< + ::AccountId, +>>::NegativeImbalance; + +/// We assume that an on-initialize consumes 1% of the weight on average, hence a single extrinsic +/// will not be allowed to consume more than `AvailableBlockRatio - 1%`. +pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(1); +/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used +/// by Operational extrinsics. +pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); +/// We allow for 2 seconds of compute with a 6 second average block time. +/// The storage proof size is not limited so far. +pub const MAXIMUM_BLOCK_WEIGHT: Weight = + Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX); + +const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct()); + +// Common constants used in all runtimes. +parameter_types! { + pub const BlockHashCount: BlockNumber = 4096; + /// The portion of the `NORMAL_DISPATCH_RATIO` that we adjust the fees with. Blocks filled less + /// than this will decrease the weight and more will increase. + pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); + /// The adjustment variable of the runtime. Higher values will cause `TargetBlockFullness` to + /// change the fees more rapidly. + pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(75, 1000_000); + /// Minimum amount of the multiplier. This value cannot be too low. A test case should ensure + /// that combined with `AdjustmentVariable`, we can recover from the minimum. + /// See `multiplier_can_grow_from_zero`. + pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10u128); + /// The maximum amount of the multiplier. + pub MaximumMultiplier: Multiplier = Bounded::max_value(); + /// Maximum length of block. Up to 5MB. + pub BlockLength: limits::BlockLength = + limits::BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); +} + +/// Parameterized slow adjusting fee updated based on +/// https://research.web3.foundation/Polkadot/overview/token-economics#2-slow-adjusting-mechanism +pub type SlowAdjustingFeeUpdate = TargetedFeeAdjustment< + R, + TargetBlockFullness, + AdjustmentVariable, + MinimumMultiplier, + MaximumMultiplier, +>; + +/// Implements the weight types for a runtime. +/// It expects the passed runtime constants to contain a `weights` module. +/// The generated weight types were formerly part of the common +/// runtime but are now runtime dependant. +#[macro_export] +macro_rules! impl_runtime_weights { + ($runtime:ident) => { + use frame_support::{dispatch::DispatchClass, weights::Weight}; + use frame_system::limits; + use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; + pub use runtime_common::{ + impl_elections_weights, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT, + NORMAL_DISPATCH_RATIO, + }; + use sp_runtime::{FixedPointNumber, Perquintill}; + + // Implement the weight types of the elections module. + impl_elections_weights!($runtime); + + // Expose the weight from the runtime constants module. + pub use $runtime::weights::{ + BlockExecutionWeight, ExtrinsicBaseWeight, ParityDbWeight, RocksDbWeight, + }; + + parameter_types! { + /// Block weights base values and limits. + pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder() + .base_block($runtime::weights::BlockExecutionWeight::get()) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = $runtime::weights::ExtrinsicBaseWeight::get(); + }) + .for_class(DispatchClass::Normal, |weights| { + weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); + }) + .for_class(DispatchClass::Operational, |weights| { + weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); + // Operational transactions have an extra reserved space, so that they + // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. + weights.reserved = Some( + MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT, + ); + }) + .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) + .build_or_panic(); + } + }; +} + +/// The type used for currency conversion. +/// +/// This must only be used as long as the balance type is `u128`. +pub type CurrencyToVote = sp_staking::currency_to_vote::U128CurrencyToVote; +static_assertions::assert_eq_size!(primitives::Balance, u128); + +/// A placeholder since there is currently no provided session key handler for parachain validator +/// keys. +pub struct ParachainSessionKeyPlaceholder(sp_std::marker::PhantomData); +impl sp_runtime::BoundToRuntimeAppPublic for ParachainSessionKeyPlaceholder { + type Public = ValidatorId; +} + +impl OneSessionHandler + for ParachainSessionKeyPlaceholder +{ + type Key = ValidatorId; + + fn on_genesis_session<'a, I: 'a>(_validators: I) + where + I: Iterator, + T::AccountId: 'a, + { + } + + fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I) + where + I: Iterator, + T::AccountId: 'a, + { + } + + fn on_disabled(_: u32) {} +} + +/// A placeholder since there is currently no provided session key handler for parachain validator +/// keys. +pub struct AssignmentSessionKeyPlaceholder(sp_std::marker::PhantomData); +impl sp_runtime::BoundToRuntimeAppPublic for AssignmentSessionKeyPlaceholder { + type Public = AssignmentId; +} + +impl OneSessionHandler + for AssignmentSessionKeyPlaceholder +{ + type Key = AssignmentId; + + fn on_genesis_session<'a, I: 'a>(_validators: I) + where + I: Iterator, + T::AccountId: 'a, + { + } + + fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I) + where + I: Iterator, + T::AccountId: 'a, + { + } + + fn on_disabled(_: u32) {} +} + +/// A reasonable benchmarking config for staking pallet. +pub struct StakingBenchmarkingConfig; +impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig { + type MaxValidators = ConstU32<1000>; + type MaxNominators = ConstU32<1000>; +} + +/// Convert a balance to an unsigned 256-bit number, use in nomination pools. +pub struct BalanceToU256; +impl sp_runtime::traits::Convert for BalanceToU256 { + fn convert(n: Balance) -> sp_core::U256 { + n.into() + } +} + +/// Convert an unsigned 256-bit number to balance, use in nomination pools. +pub struct U256ToBalance; +impl sp_runtime::traits::Convert for U256ToBalance { + fn convert(n: sp_core::U256) -> Balance { + use frame_support::traits::Defensive; + n.try_into().defensive_unwrap_or(Balance::MAX) + } +} + +/// Macro to set a value (e.g. when using the `parameter_types` macro) to either a production value +/// or to an environment variable or testing value (in case the `fast-runtime` feature is selected). +/// Note that the environment variable is evaluated _at compile time_. +/// +/// Usage: +/// ```Rust +/// parameter_types! { +/// // Note that the env variable version parameter cannot be const. +/// pub LaunchPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1, "KSM_LAUNCH_PERIOD"); +/// pub const VotingPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1 * MINUTES); +/// } +/// ``` +#[macro_export] +macro_rules! prod_or_fast { + ($prod:expr, $test:expr) => { + if cfg!(feature = "fast-runtime") { + $test + } else { + $prod + } + }; + ($prod:expr, $test:expr, $env:expr) => { + if cfg!(feature = "fast-runtime") { + core::option_env!($env).map(|s| s.parse().ok()).flatten().unwrap_or($test) + } else { + $prod + } + }; +} diff --git a/polkadot/runtime/common/src/mock.rs b/polkadot/runtime/common/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..ed25072e246e0c1acc8ae71335b7409e34e6edb3 --- /dev/null +++ b/polkadot/runtime/common/src/mock.rs @@ -0,0 +1,270 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Mocking utilities for testing. + +use crate::traits::Registrar; +use frame_support::{ + dispatch::{DispatchError, DispatchResult}, + weights::Weight, +}; +use frame_system::pallet_prelude::BlockNumberFor; +use parity_scale_codec::{Decode, Encode}; +use primitives::{HeadData, Id as ParaId, PvfCheckStatement, SessionIndex, ValidationCode}; +use runtime_parachains::paras; +use sp_keyring::Sr25519Keyring; +use sp_runtime::{traits::SaturatedConversion, Permill}; +use std::{cell::RefCell, collections::HashMap}; + +thread_local! { + static OPERATIONS: RefCell> = RefCell::new(Vec::new()); + static PARACHAINS: RefCell> = RefCell::new(Vec::new()); + // On-demand parachains + static PARATHREADS: RefCell> = RefCell::new(Vec::new()); + static LOCKS: RefCell> = RefCell::new(HashMap::new()); + static MANAGERS: RefCell>> = RefCell::new(HashMap::new()); +} + +pub struct TestRegistrar(sp_std::marker::PhantomData); + +impl Registrar for TestRegistrar { + type AccountId = T::AccountId; + + fn manager_of(id: ParaId) -> Option { + MANAGERS.with(|x| x.borrow().get(&id).and_then(|v| T::AccountId::decode(&mut &v[..]).ok())) + } + + fn parachains() -> Vec { + PARACHAINS.with(|x| x.borrow().clone()) + } + + // Is on-demand parachain + fn is_parathread(id: ParaId) -> bool { + PARATHREADS.with(|x| x.borrow().binary_search(&id).is_ok()) + } + + fn apply_lock(id: ParaId) { + LOCKS.with(|x| x.borrow_mut().insert(id, true)); + } + + fn remove_lock(id: ParaId) { + LOCKS.with(|x| x.borrow_mut().insert(id, false)); + } + + fn register( + manager: Self::AccountId, + id: ParaId, + _genesis_head: HeadData, + _validation_code: ValidationCode, + ) -> DispatchResult { + // Should not be parachain. + PARACHAINS.with(|x| { + let parachains = x.borrow_mut(); + match parachains.binary_search(&id) { + Ok(_) => Err(DispatchError::Other("Already Parachain")), + Err(_) => Ok(()), + } + })?; + // Should not be parathread (on-demand parachain), then make it. + PARATHREADS.with(|x| { + let mut parathreads = x.borrow_mut(); + match parathreads.binary_search(&id) { + Ok(_) => Err(DispatchError::Other("Already Parathread")), + Err(i) => { + parathreads.insert(i, id); + Ok(()) + }, + } + })?; + MANAGERS.with(|x| x.borrow_mut().insert(id, manager.encode())); + Ok(()) + } + + fn deregister(id: ParaId) -> DispatchResult { + // Should not be parachain. + PARACHAINS.with(|x| { + let parachains = x.borrow_mut(); + match parachains.binary_search(&id) { + Ok(_) => Err(DispatchError::Other("cannot deregister parachain")), + Err(_) => Ok(()), + } + })?; + // Remove from parathreads (on-demand parachains). + PARATHREADS.with(|x| { + let mut parathreads = x.borrow_mut(); + match parathreads.binary_search(&id) { + Ok(i) => { + parathreads.remove(i); + Ok(()) + }, + Err(_) => Err(DispatchError::Other("not parathread, so cannot `deregister`")), + } + })?; + MANAGERS.with(|x| x.borrow_mut().remove(&id)); + Ok(()) + } + + /// If the ParaId corresponds to a parathread (on-demand parachain), + /// then upgrade it to a lease holding parachain + fn make_parachain(id: ParaId) -> DispatchResult { + PARATHREADS.with(|x| { + let mut parathreads = x.borrow_mut(); + match parathreads.binary_search(&id) { + Ok(i) => { + parathreads.remove(i); + Ok(()) + }, + Err(_) => Err(DispatchError::Other("not parathread, so cannot `make_parachain`")), + } + })?; + PARACHAINS.with(|x| { + let mut parachains = x.borrow_mut(); + match parachains.binary_search(&id) { + Ok(_) => Err(DispatchError::Other("already parachain, so cannot `make_parachain`")), + Err(i) => { + parachains.insert(i, id); + Ok(()) + }, + } + })?; + OPERATIONS.with(|x| { + x.borrow_mut().push(( + id, + frame_system::Pallet::::block_number().saturated_into(), + true, + )) + }); + Ok(()) + } + + /// If the ParaId corresponds to a lease holding parachain, then downgrade it to a + /// parathread (on-demand parachain) + fn make_parathread(id: ParaId) -> DispatchResult { + PARACHAINS.with(|x| { + let mut parachains = x.borrow_mut(); + match parachains.binary_search(&id) { + Ok(i) => { + parachains.remove(i); + Ok(()) + }, + Err(_) => Err(DispatchError::Other("not parachain, so cannot `make_parathread`")), + } + })?; + PARATHREADS.with(|x| { + let mut parathreads = x.borrow_mut(); + match parathreads.binary_search(&id) { + Ok(_) => + Err(DispatchError::Other("already parathread, so cannot `make_parathread`")), + Err(i) => { + parathreads.insert(i, id); + Ok(()) + }, + } + })?; + OPERATIONS.with(|x| { + x.borrow_mut().push(( + id, + frame_system::Pallet::::block_number().saturated_into(), + false, + )) + }); + Ok(()) + } + + #[cfg(test)] + fn worst_head_data() -> HeadData { + vec![0u8; 1000].into() + } + + #[cfg(test)] + fn worst_validation_code() -> ValidationCode { + let validation_code = vec![0u8; 1000]; + validation_code.into() + } + + #[cfg(test)] + fn execute_pending_transitions() {} +} + +impl TestRegistrar { + pub fn operations() -> Vec<(ParaId, BlockNumberFor, bool)> { + OPERATIONS + .with(|x| x.borrow().iter().map(|(p, b, c)| (*p, (*b).into(), *c)).collect::>()) + } + + #[allow(dead_code)] + pub fn parachains() -> Vec { + PARACHAINS.with(|x| x.borrow().clone()) + } + + #[allow(dead_code)] + pub fn parathreads() -> Vec { + PARATHREADS.with(|x| x.borrow().clone()) + } + + #[allow(dead_code)] + pub fn clear_storage() { + OPERATIONS.with(|x| x.borrow_mut().clear()); + PARACHAINS.with(|x| x.borrow_mut().clear()); + PARATHREADS.with(|x| x.borrow_mut().clear()); + MANAGERS.with(|x| x.borrow_mut().clear()); + } +} + +/// A very dumb implementation of `EstimateNextSessionRotation`. At the moment of writing, this +/// is more to satisfy type requirements rather than to test anything. +pub struct TestNextSessionRotation; + +impl frame_support::traits::EstimateNextSessionRotation for TestNextSessionRotation { + fn average_session_length() -> u32 { + 10 + } + + fn estimate_current_session_progress(_now: u32) -> (Option, Weight) { + (None, Weight::zero()) + } + + fn estimate_next_session_rotation(_now: u32) -> (Option, Weight) { + (None, Weight::zero()) + } +} + +pub fn validators_public_keys(validators: &[Sr25519Keyring]) -> Vec { + validators.iter().map(|v| v.public().into()).collect() +} + +pub fn conclude_pvf_checking( + validation_code: &ValidationCode, + validators: &[Sr25519Keyring], + session_index: SessionIndex, +) { + let num_required = primitives::supermajority_threshold(validators.len()); + validators.iter().enumerate().take(num_required).for_each(|(idx, key)| { + let validator_index = idx as u32; + let statement = PvfCheckStatement { + accept: true, + subject: validation_code.hash(), + session_index, + validator_index: validator_index.into(), + }; + let signature = key.sign(&statement.signing_payload()); + let _ = paras::Pallet::::include_pvf_check_statement( + frame_system::Origin::::None.into(), + statement, + signature.into(), + ); + }); +} diff --git a/polkadot/runtime/common/src/paras_registrar.rs b/polkadot/runtime/common/src/paras_registrar.rs new file mode 100644 index 0000000000000000000000000000000000000000..3f5a8e1a5f93caca0fe5c243107825eeab068ca2 --- /dev/null +++ b/polkadot/runtime/common/src/paras_registrar.rs @@ -0,0 +1,1573 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Pallet to handle parachain registration and related fund management. +//! In essence this is a simple wrapper around `paras`. + +use frame_support::{ + dispatch::DispatchResult, + ensure, + pallet_prelude::Weight, + traits::{Currency, Get, ReservableCurrency}, +}; +use frame_system::{self, ensure_root, ensure_signed}; +use primitives::{HeadData, Id as ParaId, ValidationCode, LOWEST_PUBLIC_ID}; +use runtime_parachains::{ + configuration, ensure_parachain, + paras::{self, ParaGenesisArgs}, + Origin, ParaLifecycle, +}; +use sp_std::{prelude::*, result}; + +use crate::traits::{OnSwap, Registrar}; +pub use pallet::*; +use parity_scale_codec::{Decode, Encode}; +use runtime_parachains::paras::ParaKind; +use scale_info::TypeInfo; +use sp_runtime::{ + traits::{CheckedSub, Saturating}, + RuntimeDebug, +}; + +#[derive(Encode, Decode, Clone, PartialEq, Eq, Default, RuntimeDebug, TypeInfo)] +pub struct ParaInfo { + /// The account that has placed a deposit for registering this para. + pub(crate) manager: Account, + /// The amount reserved by the `manager` account for the registration. + deposit: Balance, + /// Whether the para registration should be locked from being controlled by the manager. + locked: bool, +} + +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + +pub trait WeightInfo { + fn reserve() -> Weight; + fn register() -> Weight; + fn force_register() -> Weight; + fn deregister() -> Weight; + fn swap() -> Weight; + fn schedule_code_upgrade(b: u32) -> Weight; + fn set_current_head(b: u32) -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn reserve() -> Weight { + Weight::zero() + } + fn register() -> Weight { + Weight::zero() + } + fn force_register() -> Weight { + Weight::zero() + } + fn deregister() -> Weight { + Weight::zero() + } + fn swap() -> Weight { + Weight::zero() + } + fn schedule_code_upgrade(_b: u32) -> Weight { + Weight::zero() + } + fn set_current_head(_b: u32) -> Weight { + Weight::zero() + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + #[pallet::disable_frame_system_supertrait_check] + pub trait Config: configuration::Config + paras::Config { + /// The overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// The aggregated origin type must support the `parachains` origin. We require that we can + /// infallibly convert between this origin and the system origin, but in reality, they're + /// the same type, we just can't express that to the Rust type system without writing a + /// `where` clause everywhere. + type RuntimeOrigin: From<::RuntimeOrigin> + + Into::RuntimeOrigin>>; + + /// The system's currency for on-demand parachain payment. + type Currency: ReservableCurrency; + + /// Runtime hook for when a lease holding parachain and on-demand parachain swap. + type OnSwap: crate::traits::OnSwap; + + /// The deposit to be paid to run a on-demand parachain. + /// This should include the cost for storing the genesis head and validation code. + #[pallet::constant] + type ParaDeposit: Get>; + + /// The deposit to be paid per byte stored on chain. + #[pallet::constant] + type DataDepositPerByte: Get>; + + /// Weight Information for the Extrinsics in the Pallet + type WeightInfo: WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + Registered { para_id: ParaId, manager: T::AccountId }, + Deregistered { para_id: ParaId }, + Reserved { para_id: ParaId, who: T::AccountId }, + Swapped { para_id: ParaId, other_id: ParaId }, + } + + #[pallet::error] + pub enum Error { + /// The ID is not registered. + NotRegistered, + /// The ID is already registered. + AlreadyRegistered, + /// The caller is not the owner of this Id. + NotOwner, + /// Invalid para code size. + CodeTooLarge, + /// Invalid para head data size. + HeadDataTooLarge, + /// Para is not a Parachain. + NotParachain, + /// Para is not a Parathread (on-demand parachain). + NotParathread, + /// Cannot deregister para + CannotDeregister, + /// Cannot schedule downgrade of lease holding parachain to on-demand parachain + CannotDowngrade, + /// Cannot schedule upgrade of on-demand parachain to lease holding parachain + CannotUpgrade, + /// Para is locked from manipulation by the manager. Must use parachain or relay chain + /// governance. + ParaLocked, + /// The ID given for registration has not been reserved. + NotReserved, + /// Registering parachain with empty code is not allowed. + EmptyCode, + /// Cannot perform a parachain slot / lifecycle swap. Check that the state of both paras + /// are correct for the swap to work. + CannotSwap, + } + + /// Pending swap operations. + #[pallet::storage] + pub(super) type PendingSwap = StorageMap<_, Twox64Concat, ParaId, ParaId>; + + /// Amount held on deposit for each para and the original depositor. + /// + /// The given account ID is responsible for registering the code and initial head data, but may + /// only do so if it isn't yet registered. (After that, it's up to governance to do so.) + #[pallet::storage] + pub type Paras = + StorageMap<_, Twox64Concat, ParaId, ParaInfo>>; + + /// The next free `ParaId`. + #[pallet::storage] + pub type NextFreeParaId = StorageValue<_, ParaId, ValueQuery>; + + #[pallet::genesis_config] + pub struct GenesisConfig { + #[serde(skip)] + pub _config: sp_std::marker::PhantomData, + pub next_free_para_id: ParaId, + } + + impl Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { next_free_para_id: LOWEST_PUBLIC_ID, _config: Default::default() } + } + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + NextFreeParaId::::put(self.next_free_para_id); + } + } + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + /// Register head data and validation code for a reserved Para Id. + /// + /// ## Arguments + /// - `origin`: Must be called by a `Signed` origin. + /// - `id`: The para ID. Must be owned/managed by the `origin` signing account. + /// - `genesis_head`: The genesis head data of the parachain/thread. + /// - `validation_code`: The initial validation code of the parachain/thread. + /// + /// ## Deposits/Fees + /// The origin signed account must reserve a corresponding deposit for the registration. + /// Anything already reserved previously for this para ID is accounted for. + /// + /// ## Events + /// The `Registered` event is emitted in case of success. + #[pallet::call_index(0)] + #[pallet::weight(::WeightInfo::register())] + pub fn register( + origin: OriginFor, + id: ParaId, + genesis_head: HeadData, + validation_code: ValidationCode, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::do_register(who, None, id, genesis_head, validation_code, true)?; + Ok(()) + } + + /// Force the registration of a Para Id on the relay chain. + /// + /// This function must be called by a Root origin. + /// + /// The deposit taken can be specified for this registration. Any `ParaId` + /// can be registered, including sub-1000 IDs which are System Parachains. + #[pallet::call_index(1)] + #[pallet::weight(::WeightInfo::force_register())] + pub fn force_register( + origin: OriginFor, + who: T::AccountId, + deposit: BalanceOf, + id: ParaId, + genesis_head: HeadData, + validation_code: ValidationCode, + ) -> DispatchResult { + ensure_root(origin)?; + Self::do_register(who, Some(deposit), id, genesis_head, validation_code, false) + } + + /// Deregister a Para Id, freeing all data and returning any deposit. + /// + /// The caller must be Root, the `para` owner, or the `para` itself. The para must be an + /// on-demand parachain. + #[pallet::call_index(2)] + #[pallet::weight(::WeightInfo::deregister())] + pub fn deregister(origin: OriginFor, id: ParaId) -> DispatchResult { + Self::ensure_root_para_or_owner(origin, id)?; + Self::do_deregister(id) + } + + /// Swap a lease holding parachain with another parachain, either on-demand or lease + /// holding. + /// + /// The origin must be Root, the `para` owner, or the `para` itself. + /// + /// The swap will happen only if there is already an opposite swap pending. If there is not, + /// the swap will be stored in the pending swaps map, ready for a later confirmatory swap. + /// + /// The `ParaId`s remain mapped to the same head data and code so external code can rely on + /// `ParaId` to be a long-term identifier of a notional "parachain". However, their + /// scheduling info (i.e. whether they're an on-demand parachain or lease holding + /// parachain), auction information and the auction deposit are switched. + #[pallet::call_index(3)] + #[pallet::weight(::WeightInfo::swap())] + pub fn swap(origin: OriginFor, id: ParaId, other: ParaId) -> DispatchResult { + Self::ensure_root_para_or_owner(origin, id)?; + + // If `id` and `other` is the same id, we treat this as a "clear" function, and exit + // early, since swapping the same id would otherwise be a noop. + if id == other { + PendingSwap::::remove(id); + return Ok(()) + } + + // Sanity check that `id` is even a para. + let id_lifecycle = + paras::Pallet::::lifecycle(id).ok_or(Error::::NotRegistered)?; + + if PendingSwap::::get(other) == Some(id) { + let other_lifecycle = + paras::Pallet::::lifecycle(other).ok_or(Error::::NotRegistered)?; + // identify which is a lease holding parachain and which is a parathread (on-demand + // parachain) + if id_lifecycle == ParaLifecycle::Parachain && + other_lifecycle == ParaLifecycle::Parathread + { + Self::do_thread_and_chain_swap(id, other); + } else if id_lifecycle == ParaLifecycle::Parathread && + other_lifecycle == ParaLifecycle::Parachain + { + Self::do_thread_and_chain_swap(other, id); + } else if id_lifecycle == ParaLifecycle::Parachain && + other_lifecycle == ParaLifecycle::Parachain + { + // If both chains are currently parachains, there is nothing funny we + // need to do for their lifecycle management, just swap the underlying + // data. + T::OnSwap::on_swap(id, other); + } else { + return Err(Error::::CannotSwap.into()) + } + Self::deposit_event(Event::::Swapped { para_id: id, other_id: other }); + PendingSwap::::remove(other); + } else { + PendingSwap::::insert(id, other); + } + + Ok(()) + } + + /// Remove a manager lock from a para. This will allow the manager of a + /// previously locked para to deregister or swap a para without using governance. + /// + /// Can only be called by the Root origin or the parachain. + #[pallet::call_index(4)] + #[pallet::weight(T::DbWeight::get().reads_writes(1, 1))] + pub fn remove_lock(origin: OriginFor, para: ParaId) -> DispatchResult { + Self::ensure_root_or_para(origin, para)?; + ::remove_lock(para); + Ok(()) + } + + /// Reserve a Para Id on the relay chain. + /// + /// This function will reserve a new Para Id to be owned/managed by the origin account. + /// The origin account is able to register head data and validation code using `register` to + /// create an on-demand parachain. Using the Slots pallet, an on-demand parachain can then + /// be upgraded to a lease holding parachain. + /// + /// ## Arguments + /// - `origin`: Must be called by a `Signed` origin. Becomes the manager/owner of the new + /// para ID. + /// + /// ## Deposits/Fees + /// The origin must reserve a deposit of `ParaDeposit` for the registration. + /// + /// ## Events + /// The `Reserved` event is emitted in case of success, which provides the ID reserved for + /// use. + #[pallet::call_index(5)] + #[pallet::weight(::WeightInfo::reserve())] + pub fn reserve(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + let id = NextFreeParaId::::get().max(LOWEST_PUBLIC_ID); + Self::do_reserve(who, None, id)?; + NextFreeParaId::::set(id + 1); + Ok(()) + } + + /// Add a manager lock from a para. This will prevent the manager of a + /// para to deregister or swap a para. + /// + /// Can be called by Root, the parachain, or the parachain manager if the parachain is + /// unlocked. + #[pallet::call_index(6)] + #[pallet::weight(T::DbWeight::get().reads_writes(1, 1))] + pub fn add_lock(origin: OriginFor, para: ParaId) -> DispatchResult { + Self::ensure_root_para_or_owner(origin, para)?; + ::apply_lock(para); + Ok(()) + } + + /// Schedule a parachain upgrade. + /// + /// Can be called by Root, the parachain, or the parachain manager if the parachain is + /// unlocked. + #[pallet::call_index(7)] + #[pallet::weight(::WeightInfo::schedule_code_upgrade(new_code.0.len() as u32))] + pub fn schedule_code_upgrade( + origin: OriginFor, + para: ParaId, + new_code: ValidationCode, + ) -> DispatchResult { + Self::ensure_root_para_or_owner(origin, para)?; + runtime_parachains::schedule_code_upgrade::(para, new_code)?; + Ok(()) + } + + /// Set the parachain's current head. + /// + /// Can be called by Root, the parachain, or the parachain manager if the parachain is + /// unlocked. + #[pallet::call_index(8)] + #[pallet::weight(::WeightInfo::set_current_head(new_head.0.len() as u32))] + pub fn set_current_head( + origin: OriginFor, + para: ParaId, + new_head: HeadData, + ) -> DispatchResult { + Self::ensure_root_para_or_owner(origin, para)?; + runtime_parachains::set_current_head::(para, new_head); + Ok(()) + } + } +} + +impl Registrar for Pallet { + type AccountId = T::AccountId; + + /// Return the manager `AccountId` of a para if one exists. + fn manager_of(id: ParaId) -> Option { + Some(Paras::::get(id)?.manager) + } + + // All lease holding parachains. Ordered ascending by ParaId. On-demand parachains are not + // included. + fn parachains() -> Vec { + paras::Pallet::::parachains() + } + + // Return if a para is a parathread (on-demand parachain) + fn is_parathread(id: ParaId) -> bool { + paras::Pallet::::is_parathread(id) + } + + // Return if a para is a lease holding parachain + fn is_parachain(id: ParaId) -> bool { + paras::Pallet::::is_parachain(id) + } + + // Apply a lock to the parachain. + fn apply_lock(id: ParaId) { + Paras::::mutate(id, |x| x.as_mut().map(|info| info.locked = true)); + } + + // Remove a lock from the parachain. + fn remove_lock(id: ParaId) { + Paras::::mutate(id, |x| x.as_mut().map(|info| info.locked = false)); + } + + // Register a Para ID under control of `manager`. + // + // Note this is a backend registration API, so verification of ParaId + // is not done here to prevent. + fn register( + manager: T::AccountId, + id: ParaId, + genesis_head: HeadData, + validation_code: ValidationCode, + ) -> DispatchResult { + Self::do_register(manager, None, id, genesis_head, validation_code, false) + } + + // Deregister a Para ID, free any data, and return any deposits. + fn deregister(id: ParaId) -> DispatchResult { + Self::do_deregister(id) + } + + // Upgrade a registered on-demand parachain into a lease holding parachain. + fn make_parachain(id: ParaId) -> DispatchResult { + // Para backend should think this is an on-demand parachain... + ensure!( + paras::Pallet::::lifecycle(id) == Some(ParaLifecycle::Parathread), + Error::::NotParathread + ); + runtime_parachains::schedule_parathread_upgrade::(id) + .map_err(|_| Error::::CannotUpgrade)?; + // Once a para has upgraded to a parachain, it can no longer be managed by the owner. + // Intentionally, the flag stays with the para even after downgrade. + Self::apply_lock(id); + Ok(()) + } + + // Downgrade a registered para into a parathread (on-demand parachain). + fn make_parathread(id: ParaId) -> DispatchResult { + // Para backend should think this is a parachain... + ensure!( + paras::Pallet::::lifecycle(id) == Some(ParaLifecycle::Parachain), + Error::::NotParachain + ); + runtime_parachains::schedule_parachain_downgrade::(id) + .map_err(|_| Error::::CannotDowngrade)?; + Ok(()) + } + + #[cfg(any(feature = "runtime-benchmarks", test))] + fn worst_head_data() -> HeadData { + let max_head_size = configuration::Pallet::::config().max_head_data_size; + assert!(max_head_size > 0, "max_head_data can't be zero for generating worst head data."); + vec![0u8; max_head_size as usize].into() + } + + #[cfg(any(feature = "runtime-benchmarks", test))] + fn worst_validation_code() -> ValidationCode { + let max_code_size = configuration::Pallet::::config().max_code_size; + assert!(max_code_size > 0, "max_code_size can't be zero for generating worst code data."); + let validation_code = vec![0u8; max_code_size as usize]; + validation_code.into() + } + + #[cfg(any(feature = "runtime-benchmarks", test))] + fn execute_pending_transitions() { + use runtime_parachains::shared; + shared::Pallet::::set_session_index(shared::Pallet::::scheduled_session()); + paras::Pallet::::test_on_new_session(); + } +} + +impl Pallet { + /// Ensure the origin is one of Root, the `para` owner, or the `para` itself. + /// If the origin is the `para` owner, the `para` must be unlocked. + fn ensure_root_para_or_owner( + origin: ::RuntimeOrigin, + id: ParaId, + ) -> DispatchResult { + ensure_signed(origin.clone()) + .map_err(|e| e.into()) + .and_then(|who| -> DispatchResult { + let para_info = Paras::::get(id).ok_or(Error::::NotRegistered)?; + ensure!(!para_info.locked, Error::::ParaLocked); + ensure!(para_info.manager == who, Error::::NotOwner); + Ok(()) + }) + .or_else(|_| -> DispatchResult { Self::ensure_root_or_para(origin, id) }) + } + + /// Ensure the origin is one of Root or the `para` itself. + fn ensure_root_or_para( + origin: ::RuntimeOrigin, + id: ParaId, + ) -> DispatchResult { + if let Ok(caller_id) = ensure_parachain(::RuntimeOrigin::from(origin.clone())) + { + // Check if matching para id... + ensure!(caller_id == id, Error::::NotOwner); + } else { + // Check if root... + ensure_root(origin.clone())?; + } + Ok(()) + } + + fn do_reserve( + who: T::AccountId, + deposit_override: Option>, + id: ParaId, + ) -> DispatchResult { + ensure!(!Paras::::contains_key(id), Error::::AlreadyRegistered); + ensure!(paras::Pallet::::lifecycle(id).is_none(), Error::::AlreadyRegistered); + + let deposit = deposit_override.unwrap_or_else(T::ParaDeposit::get); + ::Currency::reserve(&who, deposit)?; + let info = ParaInfo { manager: who.clone(), deposit, locked: false }; + + Paras::::insert(id, info); + Self::deposit_event(Event::::Reserved { para_id: id, who }); + Ok(()) + } + + /// Attempt to register a new Para Id under management of `who` in the + /// system with the given information. + fn do_register( + who: T::AccountId, + deposit_override: Option>, + id: ParaId, + genesis_head: HeadData, + validation_code: ValidationCode, + ensure_reserved: bool, + ) -> DispatchResult { + let deposited = if let Some(para_data) = Paras::::get(id) { + ensure!(para_data.manager == who, Error::::NotOwner); + ensure!(!para_data.locked, Error::::ParaLocked); + para_data.deposit + } else { + ensure!(!ensure_reserved, Error::::NotReserved); + Default::default() + }; + ensure!(paras::Pallet::::lifecycle(id).is_none(), Error::::AlreadyRegistered); + let (genesis, deposit) = + Self::validate_onboarding_data(genesis_head, validation_code, ParaKind::Parathread)?; + let deposit = deposit_override.unwrap_or(deposit); + + if let Some(additional) = deposit.checked_sub(&deposited) { + ::Currency::reserve(&who, additional)?; + } else if let Some(rebate) = deposited.checked_sub(&deposit) { + ::Currency::unreserve(&who, rebate); + }; + let info = ParaInfo { manager: who.clone(), deposit, locked: false }; + + Paras::::insert(id, info); + // We check above that para has no lifecycle, so this should not fail. + let res = runtime_parachains::schedule_para_initialize::(id, genesis); + debug_assert!(res.is_ok()); + Self::deposit_event(Event::::Registered { para_id: id, manager: who }); + Ok(()) + } + + /// Deregister a Para Id, freeing all data returning any deposit. + fn do_deregister(id: ParaId) -> DispatchResult { + match paras::Pallet::::lifecycle(id) { + // Para must be a parathread (on-demand parachain), or not exist at all. + Some(ParaLifecycle::Parathread) | None => {}, + _ => return Err(Error::::NotParathread.into()), + } + runtime_parachains::schedule_para_cleanup::(id) + .map_err(|_| Error::::CannotDeregister)?; + + if let Some(info) = Paras::::take(&id) { + ::Currency::unreserve(&info.manager, info.deposit); + } + + PendingSwap::::remove(id); + Self::deposit_event(Event::::Deregistered { para_id: id }); + Ok(()) + } + + /// Verifies the onboarding data is valid for a para. + /// + /// Returns `ParaGenesisArgs` and the deposit needed for the data. + fn validate_onboarding_data( + genesis_head: HeadData, + validation_code: ValidationCode, + para_kind: ParaKind, + ) -> Result<(ParaGenesisArgs, BalanceOf), sp_runtime::DispatchError> { + let config = configuration::Pallet::::config(); + ensure!(validation_code.0.len() > 0, Error::::EmptyCode); + ensure!(validation_code.0.len() <= config.max_code_size as usize, Error::::CodeTooLarge); + ensure!( + genesis_head.0.len() <= config.max_head_data_size as usize, + Error::::HeadDataTooLarge + ); + + let per_byte_fee = T::DataDepositPerByte::get(); + let deposit = T::ParaDeposit::get() + .saturating_add(per_byte_fee.saturating_mul((genesis_head.0.len() as u32).into())) + .saturating_add(per_byte_fee.saturating_mul((validation_code.0.len() as u32).into())); + + Ok((ParaGenesisArgs { genesis_head, validation_code, para_kind }, deposit)) + } + + /// Swap a lease holding parachain and parathread (on-demand parachain), which involves + /// scheduling an appropriate lifecycle update. + fn do_thread_and_chain_swap(to_downgrade: ParaId, to_upgrade: ParaId) { + let res1 = runtime_parachains::schedule_parachain_downgrade::(to_downgrade); + debug_assert!(res1.is_ok()); + let res2 = runtime_parachains::schedule_parathread_upgrade::(to_upgrade); + debug_assert!(res2.is_ok()); + T::OnSwap::on_swap(to_upgrade, to_downgrade); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + mock::conclude_pvf_checking, paras_registrar, traits::Registrar as RegistrarTrait, + }; + use frame_support::{ + assert_noop, assert_ok, + error::BadOrigin, + parameter_types, + traits::{ConstU32, OnFinalize, OnInitialize}, + }; + use frame_system::limits; + use pallet_balances::Error as BalancesError; + use primitives::{Balance, BlockNumber, SessionIndex}; + use runtime_parachains::{configuration, origin, shared}; + use sp_core::H256; + use sp_io::TestExternalities; + use sp_keyring::Sr25519Keyring; + use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + transaction_validity::TransactionPriority, + BuildStorage, Perbill, + }; + use sp_std::collections::btree_map::BTreeMap; + + type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; + type Block = frame_system::mocking::MockBlockU32; + + frame_support::construct_runtime!( + pub enum Test + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Configuration: configuration::{Pallet, Call, Storage, Config}, + Parachains: paras::{Pallet, Call, Storage, Config, Event}, + ParasShared: shared::{Pallet, Call, Storage}, + Registrar: paras_registrar::{Pallet, Call, Storage, Event}, + ParachainsOrigin: origin::{Pallet, Origin}, + } + ); + + impl frame_system::offchain::SendTransactionTypes for Test + where + RuntimeCall: From, + { + type Extrinsic = UncheckedExtrinsic; + type OverarchingCall = RuntimeCall; + } + + const NORMAL_RATIO: Perbill = Perbill::from_percent(75); + parameter_types! { + pub const BlockHashCount: u32 = 250; + pub BlockWeights: limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, u64::MAX)); + pub BlockLength: limits::BlockLength = + limits::BlockLength::max_with_normal_ratio(4 * 1024 * 1024, NORMAL_RATIO); + } + + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type DbWeight = (); + type BlockWeights = BlockWeights; + type BlockLength = BlockLength; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + } + + parameter_types! { + pub const ExistentialDeposit: Balance = 1; + } + + impl pallet_balances::Config for Test { + type Balance = u128; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<1>; + type MaxFreezes = ConstU32<1>; + } + + impl shared::Config for Test {} + + impl origin::Config for Test {} + + parameter_types! { + pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); + } + + impl paras::Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = paras::TestWeightInfo; + type UnsignedPriority = ParasUnsignedPriority; + type QueueFootprinter = (); + type NextSessionRotation = crate::mock::TestNextSessionRotation; + } + + impl configuration::Config for Test { + type WeightInfo = configuration::TestWeightInfo; + } + + parameter_types! { + pub const ParaDeposit: Balance = 10; + pub const DataDepositPerByte: Balance = 1; + pub const MaxRetries: u32 = 3; + } + + impl Config for Test { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type OnSwap = MockSwap; + type ParaDeposit = ParaDeposit; + type DataDepositPerByte = DataDepositPerByte; + type WeightInfo = TestWeightInfo; + } + + pub fn new_test_ext() -> TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + configuration::GenesisConfig:: { + config: configuration::HostConfiguration { + max_code_size: 2 * 1024 * 1024, // 2 MB + max_head_data_size: 1 * 1024 * 1024, // 1 MB + ..Default::default() + }, + } + .assimilate_storage(&mut t) + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(1, 10_000_000), (2, 10_000_000), (3, 10_000_000)], + } + .assimilate_storage(&mut t) + .unwrap(); + + t.into() + } + + parameter_types! { + pub static SwapData: BTreeMap = BTreeMap::new(); + } + + pub struct MockSwap; + impl OnSwap for MockSwap { + fn on_swap(one: ParaId, other: ParaId) { + let mut swap_data = SwapData::get(); + let one_data = swap_data.remove(&one).unwrap_or_default(); + let other_data = swap_data.remove(&other).unwrap_or_default(); + swap_data.insert(one, other_data); + swap_data.insert(other, one_data); + SwapData::set(swap_data); + } + } + + const BLOCKS_PER_SESSION: u32 = 3; + + const VALIDATORS: &[Sr25519Keyring] = &[ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + + fn run_to_block(n: BlockNumber) { + // NOTE that this function only simulates modules of interest. Depending on new pallet may + // require adding it here. + assert!(System::block_number() < n); + while System::block_number() < n { + let b = System::block_number(); + + if System::block_number() > 1 { + System::on_finalize(System::block_number()); + } + // Session change every 3 blocks. + if (b + 1) % BLOCKS_PER_SESSION == 0 { + let session_index = shared::Pallet::::session_index() + 1; + let validators_pub_keys = VALIDATORS.iter().map(|v| v.public().into()).collect(); + + shared::Pallet::::set_session_index(session_index); + shared::Pallet::::set_active_validators_ascending(validators_pub_keys); + + Parachains::test_on_new_session(); + } + System::set_block_number(b + 1); + System::on_initialize(System::block_number()); + } + } + + fn run_to_session(n: BlockNumber) { + let block_number = n * BLOCKS_PER_SESSION; + run_to_block(block_number); + } + + fn test_genesis_head(size: usize) -> HeadData { + HeadData(vec![0u8; size]) + } + + fn test_validation_code(size: usize) -> ValidationCode { + let validation_code = vec![0u8; size as usize]; + ValidationCode(validation_code) + } + + fn para_origin(id: ParaId) -> RuntimeOrigin { + runtime_parachains::Origin::Parachain(id).into() + } + + fn max_code_size() -> u32 { + Configuration::config().max_code_size + } + + fn max_head_size() -> u32 { + Configuration::config().max_head_data_size + } + + #[test] + fn basic_setup_works() { + new_test_ext().execute_with(|| { + assert_eq!(PendingSwap::::get(&ParaId::from(0u32)), None); + assert_eq!(Paras::::get(&ParaId::from(0u32)), None); + }); + } + + #[test] + fn end_to_end_scenario_works() { + new_test_ext().execute_with(|| { + let para_id = LOWEST_PUBLIC_ID; + + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + // first para is not yet registered + assert!(!Parachains::is_parathread(para_id)); + // We register the Para ID + let validation_code = test_validation_code(32); + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); + assert_ok!(Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(32), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + run_to_session(START_SESSION_INDEX + 2); + // It is now a parathread (on-demand parachain). + assert!(Parachains::is_parathread(para_id)); + assert!(!Parachains::is_parachain(para_id)); + // Some other external process will elevate on-demand to lease holding parachain + assert_ok!(Registrar::make_parachain(para_id)); + run_to_session(START_SESSION_INDEX + 4); + // It is now a lease holding parachain. + assert!(!Parachains::is_parathread(para_id)); + assert!(Parachains::is_parachain(para_id)); + // Turn it back into a parathread (on-demand parachain) + assert_ok!(Registrar::make_parathread(para_id)); + run_to_session(START_SESSION_INDEX + 6); + assert!(Parachains::is_parathread(para_id)); + assert!(!Parachains::is_parachain(para_id)); + // Deregister it + assert_ok!(Registrar::deregister(RuntimeOrigin::root(), para_id,)); + run_to_session(START_SESSION_INDEX + 8); + // It is nothing + assert!(!Parachains::is_parathread(para_id)); + assert!(!Parachains::is_parachain(para_id)); + }); + } + + #[test] + fn register_works() { + new_test_ext().execute_with(|| { + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + let para_id = LOWEST_PUBLIC_ID; + assert!(!Parachains::is_parathread(para_id)); + + let validation_code = test_validation_code(32); + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); + assert_eq!(Balances::reserved_balance(&1), ::ParaDeposit::get()); + assert_ok!(Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(32), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + run_to_session(START_SESSION_INDEX + 2); + assert!(Parachains::is_parathread(para_id)); + assert_eq!( + Balances::reserved_balance(&1), + ::ParaDeposit::get() + + 64 * ::DataDepositPerByte::get() + ); + }); + } + + #[test] + fn register_handles_basic_errors() { + new_test_ext().execute_with(|| { + let para_id = LOWEST_PUBLIC_ID; + + assert_noop!( + Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(max_head_size() as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::NotReserved + ); + + // Successfully register para + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); + + assert_noop!( + Registrar::register( + RuntimeOrigin::signed(2), + para_id, + test_genesis_head(max_head_size() as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::NotOwner + ); + + assert_ok!(Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(max_head_size() as usize), + test_validation_code(max_code_size() as usize), + )); + // Can skip pre-check and deregister para which's still onboarding. + run_to_session(2); + + assert_ok!(Registrar::deregister(RuntimeOrigin::root(), para_id)); + + // Can't do it again + assert_noop!( + Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(max_head_size() as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::NotReserved + ); + + // Head Size Check + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(2))); + assert_noop!( + Registrar::register( + RuntimeOrigin::signed(2), + para_id + 1, + test_genesis_head((max_head_size() + 1) as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::HeadDataTooLarge + ); + + // Code Size Check + assert_noop!( + Registrar::register( + RuntimeOrigin::signed(2), + para_id + 1, + test_genesis_head(max_head_size() as usize), + test_validation_code((max_code_size() + 1) as usize), + ), + Error::::CodeTooLarge + ); + + // Needs enough funds for deposit + assert_noop!( + Registrar::reserve(RuntimeOrigin::signed(1337)), + BalancesError::::InsufficientBalance + ); + }); + } + + #[test] + fn deregister_works() { + new_test_ext().execute_with(|| { + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + let para_id = LOWEST_PUBLIC_ID; + assert!(!Parachains::is_parathread(para_id)); + + let validation_code = test_validation_code(32); + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); + assert_ok!(Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(32), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + run_to_session(START_SESSION_INDEX + 2); + assert!(Parachains::is_parathread(para_id)); + assert_ok!(Registrar::deregister(RuntimeOrigin::root(), para_id,)); + run_to_session(START_SESSION_INDEX + 4); + assert!(paras::Pallet::::lifecycle(para_id).is_none()); + assert_eq!(Balances::reserved_balance(&1), 0); + }); + } + + #[test] + fn deregister_handles_basic_errors() { + new_test_ext().execute_with(|| { + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + let para_id = LOWEST_PUBLIC_ID; + assert!(!Parachains::is_parathread(para_id)); + + let validation_code = test_validation_code(32); + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); + assert_ok!(Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(32), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + run_to_session(START_SESSION_INDEX + 2); + assert!(Parachains::is_parathread(para_id)); + // Owner check + assert_noop!(Registrar::deregister(RuntimeOrigin::signed(2), para_id,), BadOrigin); + assert_ok!(Registrar::make_parachain(para_id)); + run_to_session(START_SESSION_INDEX + 4); + // Cant directly deregister parachain + assert_noop!( + Registrar::deregister(RuntimeOrigin::root(), para_id,), + Error::::NotParathread + ); + }); + } + + #[test] + fn swap_works() { + new_test_ext().execute_with(|| { + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + // Successfully register first two parachains + let para_1 = LOWEST_PUBLIC_ID; + let para_2 = LOWEST_PUBLIC_ID + 1; + + let validation_code = test_validation_code(max_code_size() as usize); + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); + assert_ok!(Registrar::register( + RuntimeOrigin::signed(1), + para_1, + test_genesis_head(max_head_size() as usize), + validation_code.clone(), + )); + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(2))); + assert_ok!(Registrar::register( + RuntimeOrigin::signed(2), + para_2, + test_genesis_head(max_head_size() as usize), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + run_to_session(START_SESSION_INDEX + 2); + + // Upgrade para 1 into a parachain + assert_ok!(Registrar::make_parachain(para_1)); + + // Set some mock swap data. + let mut swap_data = SwapData::get(); + swap_data.insert(para_1, 69); + swap_data.insert(para_2, 1337); + SwapData::set(swap_data); + + run_to_session(START_SESSION_INDEX + 4); + + // Roles are as we expect + assert!(Parachains::is_parachain(para_1)); + assert!(!Parachains::is_parathread(para_1)); + assert!(!Parachains::is_parachain(para_2)); + assert!(Parachains::is_parathread(para_2)); + + // Both paras initiate a swap + // Swap between parachain and parathread + assert_ok!(Registrar::swap(para_origin(para_1), para_1, para_2,)); + assert_ok!(Registrar::swap(para_origin(para_2), para_2, para_1,)); + System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped { + para_id: para_2, + other_id: para_1, + })); + + run_to_session(START_SESSION_INDEX + 6); + + // Roles are swapped + assert!(!Parachains::is_parachain(para_1)); + assert!(Parachains::is_parathread(para_1)); + assert!(Parachains::is_parachain(para_2)); + assert!(!Parachains::is_parathread(para_2)); + + // Data is swapped + assert_eq!(SwapData::get().get(¶_1).unwrap(), &1337); + assert_eq!(SwapData::get().get(¶_2).unwrap(), &69); + + // Both paras initiate a swap + // Swap between parathread and parachain + assert_ok!(Registrar::swap(para_origin(para_1), para_1, para_2,)); + assert_ok!(Registrar::swap(para_origin(para_2), para_2, para_1,)); + System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped { + para_id: para_2, + other_id: para_1, + })); + + // Data is swapped + assert_eq!(SwapData::get().get(¶_1).unwrap(), &69); + assert_eq!(SwapData::get().get(¶_2).unwrap(), &1337); + + // Parachain to parachain swap + let para_3 = LOWEST_PUBLIC_ID + 2; + let validation_code = test_validation_code(max_code_size() as usize); + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(3))); + assert_ok!(Registrar::register( + RuntimeOrigin::signed(3), + para_3, + test_genesis_head(max_head_size() as usize), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX + 6); + + run_to_session(START_SESSION_INDEX + 8); + + // Upgrade para 3 into a parachain + assert_ok!(Registrar::make_parachain(para_3)); + + // Set some mock swap data. + let mut swap_data = SwapData::get(); + swap_data.insert(para_3, 777); + SwapData::set(swap_data); + + run_to_session(START_SESSION_INDEX + 10); + + // Both are parachains + assert!(Parachains::is_parachain(para_3)); + assert!(!Parachains::is_parathread(para_3)); + assert!(Parachains::is_parachain(para_1)); + assert!(!Parachains::is_parathread(para_1)); + + // Both paras initiate a swap + // Swap between parachain and parachain + assert_ok!(Registrar::swap(para_origin(para_1), para_1, para_3,)); + assert_ok!(Registrar::swap(para_origin(para_3), para_3, para_1,)); + System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped { + para_id: para_3, + other_id: para_1, + })); + + // Data is swapped + assert_eq!(SwapData::get().get(¶_3).unwrap(), &69); + assert_eq!(SwapData::get().get(¶_1).unwrap(), &777); + }); + } + + #[test] + fn para_lock_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); + let para_id = LOWEST_PUBLIC_ID; + assert_ok!(Registrar::register( + RuntimeOrigin::signed(1), + para_id, + vec![1; 3].into(), + vec![1, 2, 3].into(), + )); + + assert_noop!(Registrar::add_lock(RuntimeOrigin::signed(2), para_id), BadOrigin); + // Once they begin onboarding, we lock them in. + assert_ok!(Registrar::add_lock(RuntimeOrigin::signed(1), para_id)); + // Owner cannot pass origin check when checking lock + assert_noop!( + Registrar::ensure_root_para_or_owner(RuntimeOrigin::signed(1), para_id), + BadOrigin + ); + // Owner cannot remove lock. + assert_noop!(Registrar::remove_lock(RuntimeOrigin::signed(1), para_id), BadOrigin); + // Para can. + assert_ok!(Registrar::remove_lock(para_origin(para_id), para_id)); + // Owner can pass origin check again + assert_ok!(Registrar::ensure_root_para_or_owner(RuntimeOrigin::signed(1), para_id)); + }); + } + + #[test] + fn swap_handles_bad_states() { + new_test_ext().execute_with(|| { + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + let para_1 = LOWEST_PUBLIC_ID; + let para_2 = LOWEST_PUBLIC_ID + 1; + + // paras are not yet registered + assert!(!Parachains::is_parathread(para_1)); + assert!(!Parachains::is_parathread(para_2)); + + // Cannot even start a swap + assert_noop!( + Registrar::swap(RuntimeOrigin::root(), para_1, para_2), + Error::::NotRegistered + ); + + // We register Paras 1 and 2 + let validation_code = test_validation_code(32); + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); + assert_ok!(Registrar::reserve(RuntimeOrigin::signed(2))); + assert_ok!(Registrar::register( + RuntimeOrigin::signed(1), + para_1, + test_genesis_head(32), + validation_code.clone(), + )); + assert_ok!(Registrar::register( + RuntimeOrigin::signed(2), + para_2, + test_genesis_head(32), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + // Cannot swap + assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + run_to_session(START_SESSION_INDEX + 2); + + // They are now parathreads (on-demand parachains). + assert!(Parachains::is_parathread(para_1)); + assert!(Parachains::is_parathread(para_2)); + + // Cannot swap + assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + // Some other external process will elevate one on-demand + // parachain to a lease holding parachain + assert_ok!(Registrar::make_parachain(para_1)); + + // Cannot swap + assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + run_to_session(START_SESSION_INDEX + 3); + + // Cannot swap + assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + run_to_session(START_SESSION_INDEX + 4); + + // It is now a lease holding parachain. + assert!(Parachains::is_parachain(para_1)); + assert!(Parachains::is_parathread(para_2)); + + // Swap works here. + assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_2, para_1)); + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::Registrar(paras_registrar::Event::Swapped { .. }) + ))); + + run_to_session(START_SESSION_INDEX + 5); + + // Cannot swap + assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + run_to_session(START_SESSION_INDEX + 6); + + // Swap worked! + assert!(Parachains::is_parachain(para_2)); + assert!(Parachains::is_parathread(para_1)); + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::Registrar(paras_registrar::Event::Swapped { .. }) + ))); + + // Something starts to downgrade a para + assert_ok!(Registrar::make_parathread(para_2)); + + run_to_session(START_SESSION_INDEX + 7); + + // Cannot swap + assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + run_to_session(START_SESSION_INDEX + 8); + + assert!(Parachains::is_parathread(para_1)); + assert!(Parachains::is_parathread(para_2)); + }); + } +} + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking { + use super::{Pallet as Registrar, *}; + use crate::traits::Registrar as RegistrarT; + use frame_support::assert_ok; + use frame_system::RawOrigin; + use primitives::{MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE}; + use runtime_parachains::{paras, shared, Origin as ParaOrigin}; + use sp_runtime::traits::Bounded; + + use frame_benchmarking::{account, benchmarks, whitelisted_caller}; + + fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); + } + + fn register_para(id: u32) -> ParaId { + let para = ParaId::from(id); + let genesis_head = Registrar::::worst_head_data(); + let validation_code = Registrar::::worst_validation_code(); + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + assert_ok!(Registrar::::reserve(RawOrigin::Signed(caller.clone()).into())); + assert_ok!(Registrar::::register( + RawOrigin::Signed(caller).into(), + para, + genesis_head, + validation_code.clone() + )); + assert_ok!(runtime_parachains::paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + validation_code, + )); + return para + } + + fn para_origin(id: u32) -> ParaOrigin { + ParaOrigin::Parachain(id.into()) + } + + // This function moves forward to the next scheduled session for parachain lifecycle upgrades. + fn next_scheduled_session() { + shared::Pallet::::set_session_index(shared::Pallet::::scheduled_session()); + paras::Pallet::::test_on_new_session(); + } + + benchmarks! { + where_clause { where ParaOrigin: Into<::RuntimeOrigin> } + + reserve { + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + }: _(RawOrigin::Signed(caller.clone())) + verify { + assert_last_event::(Event::::Reserved { para_id: LOWEST_PUBLIC_ID, who: caller }.into()); + assert!(Paras::::get(LOWEST_PUBLIC_ID).is_some()); + assert_eq!(paras::Pallet::::lifecycle(LOWEST_PUBLIC_ID), None); + } + + register { + let para = LOWEST_PUBLIC_ID; + let genesis_head = Registrar::::worst_head_data(); + let validation_code = Registrar::::worst_validation_code(); + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + assert_ok!(Registrar::::reserve(RawOrigin::Signed(caller.clone()).into())); + }: _(RawOrigin::Signed(caller.clone()), para, genesis_head, validation_code.clone()) + verify { + assert_last_event::(Event::::Registered{ para_id: para, manager: caller }.into()); + assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Onboarding)); + assert_ok!(runtime_parachains::paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + validation_code, + )); + next_scheduled_session::(); + assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Parathread)); + } + + force_register { + let manager: T::AccountId = account("manager", 0, 0); + let deposit = 0u32.into(); + let para = ParaId::from(69); + let genesis_head = Registrar::::worst_head_data(); + let validation_code = Registrar::::worst_validation_code(); + }: _(RawOrigin::Root, manager.clone(), deposit, para, genesis_head, validation_code.clone()) + verify { + assert_last_event::(Event::::Registered { para_id: para, manager }.into()); + assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Onboarding)); + assert_ok!(runtime_parachains::paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + validation_code, + )); + next_scheduled_session::(); + assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Parathread)); + } + + deregister { + let para = register_para::(LOWEST_PUBLIC_ID.into()); + next_scheduled_session::(); + let caller: T::AccountId = whitelisted_caller(); + }: _(RawOrigin::Signed(caller), para) + verify { + assert_last_event::(Event::::Deregistered { para_id: para }.into()); + } + + swap { + // On demand parachain + let parathread = register_para::(LOWEST_PUBLIC_ID.into()); + let parachain = register_para::((LOWEST_PUBLIC_ID + 1).into()); + + let parachain_origin = para_origin(parachain.into()); + + // Actually finish registration process + next_scheduled_session::(); + + // Upgrade the parachain + Registrar::::make_parachain(parachain)?; + next_scheduled_session::(); + + assert_eq!(paras::Pallet::::lifecycle(parachain), Some(ParaLifecycle::Parachain)); + assert_eq!(paras::Pallet::::lifecycle(parathread), Some(ParaLifecycle::Parathread)); + + let caller: T::AccountId = whitelisted_caller(); + Registrar::::swap(parachain_origin.into(), parachain, parathread)?; + }: _(RawOrigin::Signed(caller.clone()), parathread, parachain) + verify { + next_scheduled_session::(); + // Swapped! + assert_eq!(paras::Pallet::::lifecycle(parachain), Some(ParaLifecycle::Parathread)); + assert_eq!(paras::Pallet::::lifecycle(parathread), Some(ParaLifecycle::Parachain)); + } + + schedule_code_upgrade { + let b in 1 .. MAX_CODE_SIZE; + let new_code = ValidationCode(vec![0; b as usize]); + let para_id = ParaId::from(1000); + }: _(RawOrigin::Root, para_id, new_code) + + set_current_head { + let b in 1 .. MAX_HEAD_DATA_SIZE; + let new_head = HeadData(vec![0; b as usize]); + let para_id = ParaId::from(1000); + }: _(RawOrigin::Root, para_id, new_head) + + impl_benchmark_test_suite!( + Registrar, + crate::integration_tests::new_test_ext(), + crate::integration_tests::Test, + ); + } +} diff --git a/polkadot/runtime/common/src/paras_sudo_wrapper.rs b/polkadot/runtime/common/src/paras_sudo_wrapper.rs new file mode 100644 index 0000000000000000000000000000000000000000..0fc2644b2a0b0e21b07e8dca719e7c702c9f40a4 --- /dev/null +++ b/polkadot/runtime/common/src/paras_sudo_wrapper.rs @@ -0,0 +1,174 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A simple wrapper allowing `Sudo` to call into `paras` routines. + +use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::*; +pub use pallet::*; +use parity_scale_codec::Encode; +use primitives::Id as ParaId; +use runtime_parachains::{ + configuration, dmp, hrmp, + paras::{self, ParaGenesisArgs}, + ParaLifecycle, +}; +use sp_std::boxed::Box; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + #[pallet::disable_frame_system_supertrait_check] + pub trait Config: configuration::Config + paras::Config + dmp::Config + hrmp::Config {} + + #[pallet::error] + pub enum Error { + /// The specified parachain is not registered. + ParaDoesntExist, + /// The specified parachain is already registered. + ParaAlreadyExists, + /// A DMP message couldn't be sent because it exceeds the maximum size allowed for a + /// downward message. + ExceedsMaxMessageSize, + /// Could not schedule para cleanup. + CouldntCleanup, + /// Not a parathread (on-demand parachain). + NotParathread, + /// Not a lease holding parachain. + NotParachain, + /// Cannot upgrade on-demand parachain to lease holding parachain. + CannotUpgrade, + /// Cannot downgrade lease holding parachain to on-demand. + CannotDowngrade, + } + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + /// Schedule a para to be initialized at the start of the next session. + #[pallet::call_index(0)] + #[pallet::weight((1_000, DispatchClass::Operational))] + pub fn sudo_schedule_para_initialize( + origin: OriginFor, + id: ParaId, + genesis: ParaGenesisArgs, + ) -> DispatchResult { + ensure_root(origin)?; + runtime_parachains::schedule_para_initialize::(id, genesis) + .map_err(|_| Error::::ParaAlreadyExists)?; + Ok(()) + } + + /// Schedule a para to be cleaned up at the start of the next session. + #[pallet::call_index(1)] + #[pallet::weight((1_000, DispatchClass::Operational))] + pub fn sudo_schedule_para_cleanup(origin: OriginFor, id: ParaId) -> DispatchResult { + ensure_root(origin)?; + runtime_parachains::schedule_para_cleanup::(id) + .map_err(|_| Error::::CouldntCleanup)?; + Ok(()) + } + + /// Upgrade a parathread (on-demand parachain) to a lease holding parachain + #[pallet::call_index(2)] + #[pallet::weight((1_000, DispatchClass::Operational))] + pub fn sudo_schedule_parathread_upgrade( + origin: OriginFor, + id: ParaId, + ) -> DispatchResult { + ensure_root(origin)?; + // Para backend should think this is a parathread (on-demand parachain)... + ensure!( + paras::Pallet::::lifecycle(id) == Some(ParaLifecycle::Parathread), + Error::::NotParathread, + ); + runtime_parachains::schedule_parathread_upgrade::(id) + .map_err(|_| Error::::CannotUpgrade)?; + Ok(()) + } + + /// Downgrade a lease holding parachain to an on-demand parachain + #[pallet::call_index(3)] + #[pallet::weight((1_000, DispatchClass::Operational))] + pub fn sudo_schedule_parachain_downgrade( + origin: OriginFor, + id: ParaId, + ) -> DispatchResult { + ensure_root(origin)?; + // Para backend should think this is a parachain... + ensure!( + paras::Pallet::::lifecycle(id) == Some(ParaLifecycle::Parachain), + Error::::NotParachain, + ); + runtime_parachains::schedule_parachain_downgrade::(id) + .map_err(|_| Error::::CannotDowngrade)?; + Ok(()) + } + + /// Send a downward XCM to the given para. + /// + /// The given parachain should exist and the payload should not exceed the preconfigured + /// size `config.max_downward_message_size`. + #[pallet::call_index(4)] + #[pallet::weight((1_000, DispatchClass::Operational))] + pub fn sudo_queue_downward_xcm( + origin: OriginFor, + id: ParaId, + xcm: Box, + ) -> DispatchResult { + ensure_root(origin)?; + ensure!(>::is_valid_para(id), Error::::ParaDoesntExist); + let config = >::config(); + >::queue_downward_message(&config, id, xcm.encode()).map_err(|e| match e + { + dmp::QueueDownwardMessageError::ExceedsMaxMessageSize => + Error::::ExceedsMaxMessageSize.into(), + }) + } + + /// Forcefully establish a channel from the sender to the recipient. + /// + /// This is equivalent to sending an `Hrmp::hrmp_init_open_channel` extrinsic followed by + /// `Hrmp::hrmp_accept_open_channel`. + #[pallet::call_index(5)] + #[pallet::weight((1_000, DispatchClass::Operational))] + pub fn sudo_establish_hrmp_channel( + origin: OriginFor, + sender: ParaId, + recipient: ParaId, + max_capacity: u32, + max_message_size: u32, + ) -> DispatchResult { + ensure_root(origin)?; + + >::init_open_channel( + sender, + recipient, + max_capacity, + max_message_size, + )?; + >::accept_open_channel(recipient, sender)?; + Ok(()) + } + } +} diff --git a/polkadot/runtime/common/src/purchase.rs b/polkadot/runtime/common/src/purchase.rs new file mode 100644 index 0000000000000000000000000000000000000000..72795a733ea9e5dc98d76baa1e2d1f69c1bf7580 --- /dev/null +++ b/polkadot/runtime/common/src/purchase.rs @@ -0,0 +1,1212 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// 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 . + +//! Pallet to process purchase of DOTs. + +use frame_support::{ + pallet_prelude::*, + traits::{Currency, EnsureOrigin, ExistenceRequirement, Get, VestingSchedule}, +}; +use frame_system::pallet_prelude::*; +pub use pallet::*; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_core::sr25519; +use sp_runtime::{ + traits::{CheckedAdd, Saturating, Verify, Zero}, + AnySignature, DispatchError, DispatchResult, Permill, RuntimeDebug, +}; +use sp_std::prelude::*; + +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + +/// The kind of statement an account needs to make for a claim to be valid. +#[derive(Encode, Decode, Clone, Copy, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub enum AccountValidity { + /// Account is not valid. + Invalid, + /// Account has initiated the account creation process. + Initiated, + /// Account is pending validation. + Pending, + /// Account is valid with a low contribution amount. + ValidLow, + /// Account is valid with a high contribution amount. + ValidHigh, + /// Account has completed the purchase process. + Completed, +} + +impl Default for AccountValidity { + fn default() -> Self { + AccountValidity::Invalid + } +} + +impl AccountValidity { + fn is_valid(&self) -> bool { + match self { + Self::Invalid => false, + Self::Initiated => false, + Self::Pending => false, + Self::ValidLow => true, + Self::ValidHigh => true, + Self::Completed => false, + } + } +} + +/// All information about an account regarding the purchase of DOTs. +#[derive(Encode, Decode, Default, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub struct AccountStatus { + /// The current validity status of the user. Will denote if the user has passed KYC, + /// how much they are able to purchase, and when their purchase process has completed. + validity: AccountValidity, + /// The amount of free DOTs they have purchased. + free_balance: Balance, + /// The amount of locked DOTs they have purchased. + locked_balance: Balance, + /// Their sr25519/ed25519 signature verifying they have signed our required statement. + signature: Vec, + /// The percentage of VAT the purchaser is responsible for. This is already factored into + /// account balance. + vat: Permill, +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// Balances Pallet + type Currency: Currency; + + /// Vesting Pallet + type VestingSchedule: VestingSchedule< + Self::AccountId, + Moment = BlockNumberFor, + Currency = Self::Currency, + >; + + /// The origin allowed to set account status. + type ValidityOrigin: EnsureOrigin; + + /// The origin allowed to make configurations to the pallet. + type ConfigurationOrigin: EnsureOrigin; + + /// The maximum statement length for the statement users to sign when creating an account. + #[pallet::constant] + type MaxStatementLength: Get; + + /// The amount of purchased locked DOTs that we will unlock for basic actions on the chain. + #[pallet::constant] + type UnlockedProportion: Get; + + /// The maximum amount of locked DOTs that we will unlock. + #[pallet::constant] + type MaxUnlocked: Get>; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// A [new] account was created. + AccountCreated { who: T::AccountId }, + /// Someone's account validity was updated. + ValidityUpdated { who: T::AccountId, validity: AccountValidity }, + /// Someone's purchase balance was updated. + BalanceUpdated { who: T::AccountId, free: BalanceOf, locked: BalanceOf }, + /// A payout was made to a purchaser. + PaymentComplete { who: T::AccountId, free: BalanceOf, locked: BalanceOf }, + /// A new payment account was set. + PaymentAccountSet { who: T::AccountId }, + /// A new statement was set. + StatementUpdated, + /// A new statement was set. `[block_number]` + UnlockBlockUpdated { block_number: BlockNumberFor }, + } + + #[pallet::error] + pub enum Error { + /// Account is not currently valid to use. + InvalidAccount, + /// Account used in the purchase already exists. + ExistingAccount, + /// Provided signature is invalid + InvalidSignature, + /// Account has already completed the purchase process. + AlreadyCompleted, + /// An overflow occurred when doing calculations. + Overflow, + /// The statement is too long to be stored on chain. + InvalidStatement, + /// The unlock block is in the past! + InvalidUnlockBlock, + /// Vesting schedule already exists for this account. + VestingScheduleExists, + } + + // A map of all participants in the DOT purchase process. + #[pallet::storage] + pub(super) type Accounts = + StorageMap<_, Blake2_128Concat, T::AccountId, AccountStatus>, ValueQuery>; + + // The account that will be used to payout participants of the DOT purchase process. + #[pallet::storage] + pub(super) type PaymentAccount = StorageValue<_, T::AccountId, OptionQuery>; + + // The statement purchasers will need to sign to participate. + #[pallet::storage] + pub(super) type Statement = StorageValue<_, Vec, ValueQuery>; + + // The block where all locked dots will unlock. + #[pallet::storage] + pub(super) type UnlockBlock = StorageValue<_, BlockNumberFor, ValueQuery>; + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + /// Create a new account. Proof of existence through a valid signed message. + /// + /// We check that the account does not exist at this stage. + /// + /// Origin must match the `ValidityOrigin`. + #[pallet::call_index(0)] + #[pallet::weight(Weight::from_parts(200_000_000, 0) + T::DbWeight::get().reads_writes(4, 1))] + pub fn create_account( + origin: OriginFor, + who: T::AccountId, + signature: Vec, + ) -> DispatchResult { + T::ValidityOrigin::ensure_origin(origin)?; + // Account is already being tracked by the pallet. + ensure!(!Accounts::::contains_key(&who), Error::::ExistingAccount); + // Account should not have a vesting schedule. + ensure!( + T::VestingSchedule::vesting_balance(&who).is_none(), + Error::::VestingScheduleExists + ); + + // Verify the signature provided is valid for the statement. + Self::verify_signature(&who, &signature)?; + + // Create a new pending account. + let status = AccountStatus { + validity: AccountValidity::Initiated, + signature, + free_balance: Zero::zero(), + locked_balance: Zero::zero(), + vat: Permill::zero(), + }; + Accounts::::insert(&who, status); + Self::deposit_event(Event::::AccountCreated { who }); + Ok(()) + } + + /// Update the validity status of an existing account. If set to completed, the account + /// will no longer be able to continue through the crowdfund process. + /// + /// We check that the account exists at this stage, but has not completed the process. + /// + /// Origin must match the `ValidityOrigin`. + #[pallet::call_index(1)] + #[pallet::weight(T::DbWeight::get().reads_writes(1, 1))] + pub fn update_validity_status( + origin: OriginFor, + who: T::AccountId, + validity: AccountValidity, + ) -> DispatchResult { + T::ValidityOrigin::ensure_origin(origin)?; + ensure!(Accounts::::contains_key(&who), Error::::InvalidAccount); + Accounts::::try_mutate( + &who, + |status: &mut AccountStatus>| -> DispatchResult { + ensure!( + status.validity != AccountValidity::Completed, + Error::::AlreadyCompleted + ); + status.validity = validity; + Ok(()) + }, + )?; + Self::deposit_event(Event::::ValidityUpdated { who, validity }); + Ok(()) + } + + /// Update the balance of a valid account. + /// + /// We check that the account is valid for a balance transfer at this point. + /// + /// Origin must match the `ValidityOrigin`. + #[pallet::call_index(2)] + #[pallet::weight(T::DbWeight::get().reads_writes(2, 1))] + pub fn update_balance( + origin: OriginFor, + who: T::AccountId, + free_balance: BalanceOf, + locked_balance: BalanceOf, + vat: Permill, + ) -> DispatchResult { + T::ValidityOrigin::ensure_origin(origin)?; + + Accounts::::try_mutate( + &who, + |status: &mut AccountStatus>| -> DispatchResult { + // Account has a valid status (not Invalid, Pending, or Completed)... + ensure!(status.validity.is_valid(), Error::::InvalidAccount); + + free_balance.checked_add(&locked_balance).ok_or(Error::::Overflow)?; + status.free_balance = free_balance; + status.locked_balance = locked_balance; + status.vat = vat; + Ok(()) + }, + )?; + Self::deposit_event(Event::::BalanceUpdated { + who, + free: free_balance, + locked: locked_balance, + }); + Ok(()) + } + + /// Pay the user and complete the purchase process. + /// + /// We reverify all assumptions about the state of an account, and complete the process. + /// + /// Origin must match the configured `PaymentAccount` (if it is not configured then this + /// will always fail with `BadOrigin`). + #[pallet::call_index(3)] + #[pallet::weight(T::DbWeight::get().reads_writes(4, 2))] + pub fn payout(origin: OriginFor, who: T::AccountId) -> DispatchResult { + // Payments must be made directly by the `PaymentAccount`. + let payment_account = ensure_signed(origin)?; + let test_against = PaymentAccount::::get().ok_or(DispatchError::BadOrigin)?; + ensure!(payment_account == test_against, DispatchError::BadOrigin); + + // Account should not have a vesting schedule. + ensure!( + T::VestingSchedule::vesting_balance(&who).is_none(), + Error::::VestingScheduleExists + ); + + Accounts::::try_mutate( + &who, + |status: &mut AccountStatus>| -> DispatchResult { + // Account has a valid status (not Invalid, Pending, or Completed)... + ensure!(status.validity.is_valid(), Error::::InvalidAccount); + + // Transfer funds from the payment account into the purchasing user. + let total_balance = status + .free_balance + .checked_add(&status.locked_balance) + .ok_or(Error::::Overflow)?; + T::Currency::transfer( + &payment_account, + &who, + total_balance, + ExistenceRequirement::AllowDeath, + )?; + + if !status.locked_balance.is_zero() { + let unlock_block = UnlockBlock::::get(); + // We allow some configurable portion of the purchased locked DOTs to be + // unlocked for basic usage. + let unlocked = (T::UnlockedProportion::get() * status.locked_balance) + .min(T::MaxUnlocked::get()); + let locked = status.locked_balance.saturating_sub(unlocked); + // We checked that this account has no existing vesting schedule. So this + // function should never fail, however if it does, not much we can do about + // it at this point. + let _ = T::VestingSchedule::add_vesting_schedule( + // Apply vesting schedule to this user + &who, + // For this much amount + locked, + // Unlocking the full amount after one block + locked, + // When everything unlocks + unlock_block, + ); + } + + // Setting the user account to `Completed` ends the purchase process for this + // user. + status.validity = AccountValidity::Completed; + Self::deposit_event(Event::::PaymentComplete { + who: who.clone(), + free: status.free_balance, + locked: status.locked_balance, + }); + Ok(()) + }, + )?; + Ok(()) + } + + /* Configuration Operations */ + + /// Set the account that will be used to payout users in the DOT purchase process. + /// + /// Origin must match the `ConfigurationOrigin` + #[pallet::call_index(4)] + #[pallet::weight(T::DbWeight::get().writes(1))] + pub fn set_payment_account(origin: OriginFor, who: T::AccountId) -> DispatchResult { + T::ConfigurationOrigin::ensure_origin(origin)?; + // Possibly this is worse than having the caller account be the payment account? + PaymentAccount::::put(who.clone()); + Self::deposit_event(Event::::PaymentAccountSet { who }); + Ok(()) + } + + /// Set the statement that must be signed for a user to participate on the DOT sale. + /// + /// Origin must match the `ConfigurationOrigin` + #[pallet::call_index(5)] + #[pallet::weight(T::DbWeight::get().writes(1))] + pub fn set_statement(origin: OriginFor, statement: Vec) -> DispatchResult { + T::ConfigurationOrigin::ensure_origin(origin)?; + ensure!( + (statement.len() as u32) < T::MaxStatementLength::get(), + Error::::InvalidStatement + ); + // Possibly this is worse than having the caller account be the payment account? + Statement::::set(statement); + Self::deposit_event(Event::::StatementUpdated); + Ok(()) + } + + /// Set the block where locked DOTs will become unlocked. + /// + /// Origin must match the `ConfigurationOrigin` + #[pallet::call_index(6)] + #[pallet::weight(T::DbWeight::get().writes(1))] + pub fn set_unlock_block( + origin: OriginFor, + unlock_block: BlockNumberFor, + ) -> DispatchResult { + T::ConfigurationOrigin::ensure_origin(origin)?; + ensure!( + unlock_block > frame_system::Pallet::::block_number(), + Error::::InvalidUnlockBlock + ); + // Possibly this is worse than having the caller account be the payment account? + UnlockBlock::::set(unlock_block); + Self::deposit_event(Event::::UnlockBlockUpdated { block_number: unlock_block }); + Ok(()) + } + } +} + +impl Pallet { + fn verify_signature(who: &T::AccountId, signature: &[u8]) -> Result<(), DispatchError> { + // sr25519 always expects a 64 byte signature. + let signature: AnySignature = sr25519::Signature::from_slice(signature) + .ok_or(Error::::InvalidSignature)? + .into(); + + // In Polkadot, the AccountId is always the same as the 32 byte public key. + let account_bytes: [u8; 32] = account_to_bytes(who)?; + let public_key = sr25519::Public::from_raw(account_bytes); + + let message = Statement::::get(); + + // Check if everything is good or not. + match signature.verify(message.as_slice(), &public_key) { + true => Ok(()), + false => Err(Error::::InvalidSignature)?, + } + } +} + +// This function converts a 32 byte AccountId to its byte-array equivalent form. +fn account_to_bytes(account: &AccountId) -> Result<[u8; 32], DispatchError> +where + AccountId: Encode, +{ + let account_vec = account.encode(); + ensure!(account_vec.len() == 32, "AccountId must be 32 bytes."); + let mut bytes = [0u8; 32]; + bytes.copy_from_slice(&account_vec); + Ok(bytes) +} + +/// WARNING: Executing this function will clear all storage used by this pallet. +/// Be sure this is what you want... +pub fn remove_pallet() -> frame_support::weights::Weight +where + T: frame_system::Config, +{ + #[allow(deprecated)] + use frame_support::migration::remove_storage_prefix; + #[allow(deprecated)] + remove_storage_prefix(b"Purchase", b"Accounts", b""); + #[allow(deprecated)] + remove_storage_prefix(b"Purchase", b"PaymentAccount", b""); + #[allow(deprecated)] + remove_storage_prefix(b"Purchase", b"Statement", b""); + #[allow(deprecated)] + remove_storage_prefix(b"Purchase", b"UnlockBlock", b""); + + ::BlockWeights::get().max_block +} + +#[cfg(test)] +mod tests { + use super::*; + + use sp_core::{crypto::AccountId32, ed25519, Pair, Public, 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 crate::purchase; + use frame_support::{ + assert_noop, assert_ok, + dispatch::DispatchError::BadOrigin, + ord_parameter_types, parameter_types, + traits::{Currency, WithdrawReasons}, + }; + use sp_runtime::{ + traits::{BlakeTwo256, Dispatchable, IdentifyAccount, Identity, IdentityLookup, Verify}, + ArithmeticError, BuildStorage, MultiSignature, + }; + + type Block = frame_system::mocking::MockBlock; + + frame_support::construct_runtime!( + pub enum Test + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Vesting: pallet_vesting::{Pallet, Call, Storage, Config, Event}, + Purchase: purchase::{Pallet, Call, Storage, Event}, + } + ); + + type AccountId = AccountId32; + + parameter_types! { + pub const BlockHashCount: u32 = 250; + } + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + } + + parameter_types! { + pub const ExistentialDeposit: u64 = 1; + } + + impl pallet_balances::Config for Test { + type Balance = u64; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<1>; + type MaxFreezes = ConstU32<1>; + } + + parameter_types! { + pub const MinVestedTransfer: u64 = 1; + pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = + WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); + } + + impl pallet_vesting::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BlockNumberToBalance = Identity; + type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = (); + type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; + const MAX_VESTING_SCHEDULES: u32 = 28; + } + + parameter_types! { + pub const MaxStatementLength: u32 = 1_000; + pub const UnlockedProportion: Permill = Permill::from_percent(10); + pub const MaxUnlocked: u64 = 10; + } + + ord_parameter_types! { + pub const ValidityOrigin: AccountId = AccountId32::from([0u8; 32]); + pub const PaymentOrigin: AccountId = AccountId32::from([1u8; 32]); + pub const ConfigurationOrigin: AccountId = AccountId32::from([2u8; 32]); + } + + impl Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type VestingSchedule = Vesting; + type ValidityOrigin = frame_system::EnsureSignedBy; + type ConfigurationOrigin = frame_system::EnsureSignedBy; + type MaxStatementLength = MaxStatementLength; + type UnlockedProportion = UnlockedProportion; + type MaxUnlocked = MaxUnlocked; + } + + // This function basically just builds a genesis storage key/value store according to + // our desired mockup. It also executes our `setup` function which sets up this pallet for use. + pub fn new_test_ext() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| setup()); + ext + } + + fn setup() { + let statement = b"Hello, World".to_vec(); + let unlock_block = 100; + Purchase::set_statement(RuntimeOrigin::signed(configuration_origin()), statement).unwrap(); + Purchase::set_unlock_block(RuntimeOrigin::signed(configuration_origin()), unlock_block) + .unwrap(); + Purchase::set_payment_account( + RuntimeOrigin::signed(configuration_origin()), + payment_account(), + ) + .unwrap(); + Balances::make_free_balance_be(&payment_account(), 100_000); + } + + type AccountPublic = ::Signer; + + /// Helper function to generate a crypto pair from seed + fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() + } + + /// Helper function to generate an account ID from seed + fn get_account_id_from_seed(seed: &str) -> AccountId + where + AccountPublic: From<::Public>, + { + AccountPublic::from(get_from_seed::(seed)).into_account() + } + + fn alice() -> AccountId { + get_account_id_from_seed::("Alice") + } + + fn alice_ed25519() -> AccountId { + get_account_id_from_seed::("Alice") + } + + fn bob() -> AccountId { + get_account_id_from_seed::("Bob") + } + + fn alice_signature() -> [u8; 64] { + // echo -n "Hello, World" | subkey -s sign "bottom drive obey lake curtain smoke basket hold + // race lonely fit walk//Alice" + hex_literal::hex!("20e0faffdf4dfe939f2faa560f73b1d01cde8472e2b690b7b40606a374244c3a2e9eb9c8107c10b605138374003af8819bd4387d7c24a66ee9253c2e688ab881") + } + + fn bob_signature() -> [u8; 64] { + // echo -n "Hello, World" | subkey -s sign "bottom drive obey lake curtain smoke basket hold + // race lonely fit walk//Bob" + hex_literal::hex!("d6d460187ecf530f3ec2d6e3ac91b9d083c8fbd8f1112d92a82e4d84df552d18d338e6da8944eba6e84afaacf8a9850f54e7b53a84530d649be2e0119c7ce889") + } + + fn alice_signature_ed25519() -> [u8; 64] { + // echo -n "Hello, World" | subkey -e sign "bottom drive obey lake curtain smoke basket hold + // race lonely fit walk//Alice" + hex_literal::hex!("ee3f5a6cbfc12a8f00c18b811dc921b550ddf272354cda4b9a57b1d06213fcd8509f5af18425d39a279d13622f14806c3e978e2163981f2ec1c06e9628460b0e") + } + + fn validity_origin() -> AccountId { + ValidityOrigin::get() + } + + fn configuration_origin() -> AccountId { + ConfigurationOrigin::get() + } + + fn payment_account() -> AccountId { + [42u8; 32].into() + } + + #[test] + fn set_statement_works_and_handles_basic_errors() { + new_test_ext().execute_with(|| { + let statement = b"Test Set Statement".to_vec(); + // Invalid origin + assert_noop!( + Purchase::set_statement(RuntimeOrigin::signed(alice()), statement.clone()), + BadOrigin, + ); + // Too Long + let long_statement = [0u8; 10_000].to_vec(); + assert_noop!( + Purchase::set_statement( + RuntimeOrigin::signed(configuration_origin()), + long_statement + ), + Error::::InvalidStatement, + ); + // Just right... + assert_ok!(Purchase::set_statement( + RuntimeOrigin::signed(configuration_origin()), + statement.clone() + )); + assert_eq!(Statement::::get(), statement); + }); + } + + #[test] + fn set_unlock_block_works_and_handles_basic_errors() { + new_test_ext().execute_with(|| { + let unlock_block = 69; + // Invalid origin + assert_noop!( + Purchase::set_unlock_block(RuntimeOrigin::signed(alice()), unlock_block), + BadOrigin, + ); + // Block Number in Past + let bad_unlock_block = 50; + System::set_block_number(bad_unlock_block); + assert_noop!( + Purchase::set_unlock_block( + RuntimeOrigin::signed(configuration_origin()), + bad_unlock_block + ), + Error::::InvalidUnlockBlock, + ); + // Just right... + assert_ok!(Purchase::set_unlock_block( + RuntimeOrigin::signed(configuration_origin()), + unlock_block + )); + assert_eq!(UnlockBlock::::get(), unlock_block); + }); + } + + #[test] + fn set_payment_account_works_and_handles_basic_errors() { + new_test_ext().execute_with(|| { + let payment_account: AccountId = [69u8; 32].into(); + // Invalid Origin + assert_noop!( + Purchase::set_payment_account( + RuntimeOrigin::signed(alice()), + payment_account.clone() + ), + BadOrigin, + ); + // Just right... + assert_ok!(Purchase::set_payment_account( + RuntimeOrigin::signed(configuration_origin()), + payment_account.clone() + )); + assert_eq!(PaymentAccount::::get(), Some(payment_account)); + }); + } + + #[test] + fn signature_verification_works() { + new_test_ext().execute_with(|| { + assert_ok!(Purchase::verify_signature(&alice(), &alice_signature())); + assert_ok!(Purchase::verify_signature(&alice_ed25519(), &alice_signature_ed25519())); + assert_ok!(Purchase::verify_signature(&bob(), &bob_signature())); + + // Mixing and matching fails + assert_noop!( + Purchase::verify_signature(&alice(), &bob_signature()), + Error::::InvalidSignature + ); + assert_noop!( + Purchase::verify_signature(&bob(), &alice_signature()), + Error::::InvalidSignature + ); + }); + } + + #[test] + fn account_creation_works() { + new_test_ext().execute_with(|| { + assert!(!Accounts::::contains_key(alice())); + assert_ok!(Purchase::create_account( + RuntimeOrigin::signed(validity_origin()), + alice(), + alice_signature().to_vec(), + )); + assert_eq!( + Accounts::::get(alice()), + AccountStatus { + validity: AccountValidity::Initiated, + free_balance: Zero::zero(), + locked_balance: Zero::zero(), + signature: alice_signature().to_vec(), + vat: Permill::zero(), + } + ); + }); + } + + #[test] + fn account_creation_handles_basic_errors() { + new_test_ext().execute_with(|| { + // Wrong Origin + assert_noop!( + Purchase::create_account( + RuntimeOrigin::signed(alice()), + alice(), + alice_signature().to_vec() + ), + BadOrigin, + ); + + // Wrong Account/Signature + assert_noop!( + Purchase::create_account( + RuntimeOrigin::signed(validity_origin()), + alice(), + bob_signature().to_vec() + ), + Error::::InvalidSignature, + ); + + // Account with vesting + Balances::make_free_balance_be(&alice(), 100); + assert_ok!(::VestingSchedule::add_vesting_schedule( + &alice(), + 100, + 1, + 50 + )); + assert_noop!( + Purchase::create_account( + RuntimeOrigin::signed(validity_origin()), + alice(), + alice_signature().to_vec() + ), + Error::::VestingScheduleExists, + ); + + // Duplicate Purchasing Account + assert_ok!(Purchase::create_account( + RuntimeOrigin::signed(validity_origin()), + bob(), + bob_signature().to_vec() + )); + assert_noop!( + Purchase::create_account( + RuntimeOrigin::signed(validity_origin()), + bob(), + bob_signature().to_vec() + ), + Error::::ExistingAccount, + ); + }); + } + + #[test] + fn update_validity_status_works() { + new_test_ext().execute_with(|| { + // Alice account is created. + assert_ok!(Purchase::create_account( + RuntimeOrigin::signed(validity_origin()), + alice(), + alice_signature().to_vec(), + )); + // She submits KYC, and we update the status to `Pending`. + assert_ok!(Purchase::update_validity_status( + RuntimeOrigin::signed(validity_origin()), + alice(), + AccountValidity::Pending, + )); + // KYC comes back negative, so we mark the account invalid. + assert_ok!(Purchase::update_validity_status( + RuntimeOrigin::signed(validity_origin()), + alice(), + AccountValidity::Invalid, + )); + assert_eq!( + Accounts::::get(alice()), + AccountStatus { + validity: AccountValidity::Invalid, + free_balance: Zero::zero(), + locked_balance: Zero::zero(), + signature: alice_signature().to_vec(), + vat: Permill::zero(), + } + ); + // She fixes it, we mark her account valid. + assert_ok!(Purchase::update_validity_status( + RuntimeOrigin::signed(validity_origin()), + alice(), + AccountValidity::ValidLow, + )); + assert_eq!( + Accounts::::get(alice()), + AccountStatus { + validity: AccountValidity::ValidLow, + free_balance: Zero::zero(), + locked_balance: Zero::zero(), + signature: alice_signature().to_vec(), + vat: Permill::zero(), + } + ); + }); + } + + #[test] + fn update_validity_status_handles_basic_errors() { + new_test_ext().execute_with(|| { + // Wrong Origin + assert_noop!( + Purchase::update_validity_status( + RuntimeOrigin::signed(alice()), + alice(), + AccountValidity::Pending, + ), + BadOrigin + ); + // Inactive Account + assert_noop!( + Purchase::update_validity_status( + RuntimeOrigin::signed(validity_origin()), + alice(), + AccountValidity::Pending, + ), + Error::::InvalidAccount + ); + // Already Completed + assert_ok!(Purchase::create_account( + RuntimeOrigin::signed(validity_origin()), + alice(), + alice_signature().to_vec(), + )); + assert_ok!(Purchase::update_validity_status( + RuntimeOrigin::signed(validity_origin()), + alice(), + AccountValidity::Completed, + )); + assert_noop!( + Purchase::update_validity_status( + RuntimeOrigin::signed(validity_origin()), + alice(), + AccountValidity::Pending, + ), + Error::::AlreadyCompleted + ); + }); + } + + #[test] + fn update_balance_works() { + new_test_ext().execute_with(|| { + // Alice account is created + assert_ok!(Purchase::create_account( + RuntimeOrigin::signed(validity_origin()), + alice(), + alice_signature().to_vec() + )); + // And approved for basic contribution + assert_ok!(Purchase::update_validity_status( + RuntimeOrigin::signed(validity_origin()), + alice(), + AccountValidity::ValidLow, + )); + // We set a balance on the user based on the payment they made. 50 locked, 50 free. + assert_ok!(Purchase::update_balance( + RuntimeOrigin::signed(validity_origin()), + alice(), + 50, + 50, + Permill::from_rational(77u32, 1000u32), + )); + assert_eq!( + Accounts::::get(alice()), + AccountStatus { + validity: AccountValidity::ValidLow, + free_balance: 50, + locked_balance: 50, + signature: alice_signature().to_vec(), + vat: Permill::from_parts(77000), + } + ); + // We can update the balance based on new information. + assert_ok!(Purchase::update_balance( + RuntimeOrigin::signed(validity_origin()), + alice(), + 25, + 50, + Permill::zero(), + )); + assert_eq!( + Accounts::::get(alice()), + AccountStatus { + validity: AccountValidity::ValidLow, + free_balance: 25, + locked_balance: 50, + signature: alice_signature().to_vec(), + vat: Permill::zero(), + } + ); + }); + } + + #[test] + fn update_balance_handles_basic_errors() { + new_test_ext().execute_with(|| { + // Wrong Origin + assert_noop!( + Purchase::update_balance( + RuntimeOrigin::signed(alice()), + alice(), + 50, + 50, + Permill::zero(), + ), + BadOrigin + ); + // Inactive Account + assert_noop!( + Purchase::update_balance( + RuntimeOrigin::signed(validity_origin()), + alice(), + 50, + 50, + Permill::zero(), + ), + Error::::InvalidAccount + ); + // Overflow + assert_noop!( + Purchase::update_balance( + RuntimeOrigin::signed(validity_origin()), + alice(), + u64::MAX, + u64::MAX, + Permill::zero(), + ), + Error::::InvalidAccount + ); + }); + } + + #[test] + fn payout_works() { + new_test_ext().execute_with(|| { + // Alice and Bob accounts are created + assert_ok!(Purchase::create_account( + RuntimeOrigin::signed(validity_origin()), + alice(), + alice_signature().to_vec() + )); + assert_ok!(Purchase::create_account( + RuntimeOrigin::signed(validity_origin()), + bob(), + bob_signature().to_vec() + )); + // Alice is approved for basic contribution + assert_ok!(Purchase::update_validity_status( + RuntimeOrigin::signed(validity_origin()), + alice(), + AccountValidity::ValidLow, + )); + // Bob is approved for high contribution + assert_ok!(Purchase::update_validity_status( + RuntimeOrigin::signed(validity_origin()), + bob(), + AccountValidity::ValidHigh, + )); + // We set a balance on the users based on the payment they made. 50 locked, 50 free. + assert_ok!(Purchase::update_balance( + RuntimeOrigin::signed(validity_origin()), + alice(), + 50, + 50, + Permill::zero(), + )); + assert_ok!(Purchase::update_balance( + RuntimeOrigin::signed(validity_origin()), + bob(), + 100, + 150, + Permill::zero(), + )); + // Now we call payout for Alice and Bob. + assert_ok!(Purchase::payout(RuntimeOrigin::signed(payment_account()), alice(),)); + assert_ok!(Purchase::payout(RuntimeOrigin::signed(payment_account()), bob(),)); + // Payment is made. + assert_eq!(::Currency::free_balance(&payment_account()), 99_650); + assert_eq!(::Currency::free_balance(&alice()), 100); + // 10% of the 50 units is unlocked automatically for Alice + assert_eq!(::VestingSchedule::vesting_balance(&alice()), Some(45)); + assert_eq!(::Currency::free_balance(&bob()), 250); + // A max of 10 units is unlocked automatically for Bob + assert_eq!(::VestingSchedule::vesting_balance(&bob()), Some(140)); + // Status is completed. + assert_eq!( + Accounts::::get(alice()), + AccountStatus { + validity: AccountValidity::Completed, + free_balance: 50, + locked_balance: 50, + signature: alice_signature().to_vec(), + vat: Permill::zero(), + } + ); + assert_eq!( + Accounts::::get(bob()), + AccountStatus { + validity: AccountValidity::Completed, + free_balance: 100, + locked_balance: 150, + signature: bob_signature().to_vec(), + vat: Permill::zero(), + } + ); + // Vesting lock is removed in whole on block 101 (100 blocks after block 1) + System::set_block_number(100); + let vest_call = RuntimeCall::Vesting(pallet_vesting::Call::::vest {}); + assert_ok!(vest_call.clone().dispatch(RuntimeOrigin::signed(alice()))); + assert_ok!(vest_call.clone().dispatch(RuntimeOrigin::signed(bob()))); + assert_eq!(::VestingSchedule::vesting_balance(&alice()), Some(45)); + assert_eq!(::VestingSchedule::vesting_balance(&bob()), Some(140)); + System::set_block_number(101); + assert_ok!(vest_call.clone().dispatch(RuntimeOrigin::signed(alice()))); + assert_ok!(vest_call.clone().dispatch(RuntimeOrigin::signed(bob()))); + assert_eq!(::VestingSchedule::vesting_balance(&alice()), None); + assert_eq!(::VestingSchedule::vesting_balance(&bob()), None); + }); + } + + #[test] + fn payout_handles_basic_errors() { + new_test_ext().execute_with(|| { + // Wrong Origin + assert_noop!(Purchase::payout(RuntimeOrigin::signed(alice()), alice(),), BadOrigin); + // Account with Existing Vesting Schedule + Balances::make_free_balance_be(&bob(), 100); + assert_ok!( + ::VestingSchedule::add_vesting_schedule(&bob(), 100, 1, 50,) + ); + assert_noop!( + Purchase::payout(RuntimeOrigin::signed(payment_account()), bob(),), + Error::::VestingScheduleExists + ); + // Invalid Account (never created) + assert_noop!( + Purchase::payout(RuntimeOrigin::signed(payment_account()), alice(),), + Error::::InvalidAccount + ); + // Invalid Account (created, but not valid) + assert_ok!(Purchase::create_account( + RuntimeOrigin::signed(validity_origin()), + alice(), + alice_signature().to_vec() + )); + assert_noop!( + Purchase::payout(RuntimeOrigin::signed(payment_account()), alice(),), + Error::::InvalidAccount + ); + // Not enough funds in payment account + assert_ok!(Purchase::update_validity_status( + RuntimeOrigin::signed(validity_origin()), + alice(), + AccountValidity::ValidHigh, + )); + assert_ok!(Purchase::update_balance( + RuntimeOrigin::signed(validity_origin()), + alice(), + 100_000, + 100_000, + Permill::zero(), + )); + assert_noop!( + Purchase::payout(RuntimeOrigin::signed(payment_account()), alice()), + ArithmeticError::Underflow + ); + }); + } + + #[test] + fn remove_pallet_works() { + new_test_ext().execute_with(|| { + let account_status = AccountStatus { + validity: AccountValidity::Completed, + free_balance: 1234, + locked_balance: 4321, + signature: b"my signature".to_vec(), + vat: Permill::from_percent(50), + }; + + // Add some storage. + Accounts::::insert(alice(), account_status.clone()); + Accounts::::insert(bob(), account_status); + PaymentAccount::::put(alice()); + Statement::::put(b"hello, world!".to_vec()); + UnlockBlock::::put(4); + + // Verify storage exists. + assert_eq!(Accounts::::iter().count(), 2); + assert!(PaymentAccount::::exists()); + assert!(Statement::::exists()); + assert!(UnlockBlock::::exists()); + + // Remove storage. + remove_pallet::(); + + // Verify storage is gone. + assert_eq!(Accounts::::iter().count(), 0); + assert!(!PaymentAccount::::exists()); + assert!(!Statement::::exists()); + assert!(!UnlockBlock::::exists()); + }); + } +} diff --git a/polkadot/runtime/common/src/slot_range.rs b/polkadot/runtime/common/src/slot_range.rs new file mode 100644 index 0000000000000000000000000000000000000000..1116acaa4d5c2d10541de816e92e8b12afc43ec9 --- /dev/null +++ b/polkadot/runtime/common/src/slot_range.rs @@ -0,0 +1,69 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The `SlotRange` struct which succinctly handles the 36 values that +//! represent all sub ranges between 0 and 7 inclusive. + +slot_range_helper::generate_slot_range!( + Zero(0), + One(1), + Two(2), + Three(3), + Four(4), + Five(5), + Six(6), + Seven(7) +); + +// Will generate: +// pub enum SlotRange { +// ZeroZero, 0 +// ZeroOne, 1 +// ZeroTwo, 2 +// ZeroThree, 3 +// ZeroFour, 4 +// ZeroFive, 5 +// ZeroSix, 6 +// ZeroSeven, 7 +// OneOne, 8 +// OneTwo, 9 +// OneThree, 10 +// OneFour, 11 +// OneFive, 12 +// OneSix, 13 +// OneSeven, 14 +// TwoTwo, 15 +// TwoThree, 16 +// TwoFour, 17 +// TwoFive, 18 +// TwoSix, 19 +// TwoSeven, 20 +// ThreeThree, 21 +// ThreeFour, 22 +// ThreeFive, 23 +// ThreeSix, 24 +// ThreeSeven, 25 +// FourFour, 26 +// FourFive, 27 +// FourSix, 28 +// FourSeven, 29 +// FiveFive, 30 +// FiveSix, 31 +// FiveSeven, 32 +// SixSix, 33 +// SixSeven, 34 +// SevenSeven, 35 +// } diff --git a/polkadot/runtime/common/src/slots/migration.rs b/polkadot/runtime/common/src/slots/migration.rs new file mode 100644 index 0000000000000000000000000000000000000000..4b499ca7c7bd8c5b1a386e658e7e38100f7f652a --- /dev/null +++ b/polkadot/runtime/common/src/slots/migration.rs @@ -0,0 +1,90 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::crowdloan; +use sp_runtime::traits::AccountIdConversion; + +/// Migrations for using fund index to create fund accounts instead of para ID. +pub mod slots_crowdloan_index_migration { + use super::*; + + // The old way we generated fund accounts. + fn old_fund_account_id(index: ParaId) -> T::AccountId { + ::PalletId::get().into_sub_account_truncating(index) + } + + pub fn pre_migrate() -> Result<(), &'static str> { + for (para_id, leases) in Leases::::iter() { + let old_fund_account = old_fund_account_id::(para_id); + + for (who, _amount) in leases.iter().flatten() { + if *who == old_fund_account { + let crowdloan = + crowdloan::Funds::::get(para_id).ok_or("no crowdloan found")?; + log::info!( + target: "runtime", + "para_id={:?}, old_fund_account={:?}, fund_id={:?}, leases={:?}", + para_id, old_fund_account, crowdloan.fund_index, leases, + ); + break + } + } + } + + Ok(()) + } + + pub fn migrate() -> frame_support::weights::Weight { + let mut weight = Weight::zero(); + + for (para_id, mut leases) in Leases::::iter() { + weight = weight.saturating_add(T::DbWeight::get().reads(2)); + // the para id must have a crowdloan + if let Some(fund) = crowdloan::Funds::::get(para_id) { + let old_fund_account = old_fund_account_id::(para_id); + let new_fund_account = crowdloan::Pallet::::fund_account_id(fund.fund_index); + + // look for places the old account is used, and replace with the new account. + for (who, _amount) in leases.iter_mut().flatten() { + if *who == old_fund_account { + *who = new_fund_account.clone(); + } + } + + // insert the changes. + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + Leases::::insert(para_id, leases); + } + } + + weight + } + + pub fn post_migrate() -> Result<(), &'static str> { + for (para_id, leases) in Leases::::iter() { + let old_fund_account = old_fund_account_id::(para_id); + log::info!(target: "runtime", "checking para_id: {:?}", para_id); + // check the old fund account doesn't exist anywhere. + for (who, _amount) in leases.iter().flatten() { + if *who == old_fund_account { + panic!("old fund account found after migration!"); + } + } + } + Ok(()) + } +} diff --git a/polkadot/runtime/common/src/slots/mod.rs b/polkadot/runtime/common/src/slots/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..a3efd5bfa30a6c4bd8455834534514712f6458ae --- /dev/null +++ b/polkadot/runtime/common/src/slots/mod.rs @@ -0,0 +1,1168 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Parathread and parachains leasing system. Allows para IDs to be claimed, the code and data to be +//! initialized and parachain slots (i.e. continuous scheduling) to be leased. Also allows for +//! parachains and parathreads to be swapped. +//! +//! This doesn't handle the mechanics of determining which para ID actually ends up with a parachain +//! lease. This must handled by a separately, through the trait interface that this pallet provides +//! or the root dispatchables. + +pub mod migration; + +use crate::traits::{LeaseError, Leaser, Registrar}; +use frame_support::{ + pallet_prelude::*, + traits::{Currency, ReservableCurrency}, + weights::Weight, +}; +use frame_system::pallet_prelude::*; +pub use pallet::*; +use primitives::Id as ParaId; +use sp_runtime::traits::{CheckedConversion, CheckedSub, Saturating, Zero}; +use sp_std::prelude::*; + +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; +type LeasePeriodOf = BlockNumberFor; + +pub trait WeightInfo { + fn force_lease() -> Weight; + fn manage_lease_period_start(c: u32, t: u32) -> Weight; + fn clear_all_leases() -> Weight; + fn trigger_onboard() -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn force_lease() -> Weight { + Weight::zero() + } + fn manage_lease_period_start(_c: u32, _t: u32) -> Weight { + Weight::zero() + } + fn clear_all_leases() -> Weight { + Weight::zero() + } + fn trigger_onboard() -> Weight { + Weight::zero() + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// The currency type used for bidding. + type Currency: ReservableCurrency; + + /// The parachain registrar type. + type Registrar: Registrar; + + /// The number of blocks over which a single period lasts. + #[pallet::constant] + type LeasePeriod: Get>; + + /// The number of blocks to offset each lease period by. + #[pallet::constant] + type LeaseOffset: Get>; + + /// The origin which may forcibly create or clear leases. Root can always do this. + type ForceOrigin: EnsureOrigin<::RuntimeOrigin>; + + /// Weight Information for the Extrinsics in the Pallet + type WeightInfo: WeightInfo; + } + + /// Amounts held on deposit for each (possibly future) leased parachain. + /// + /// The actual amount locked on its behalf by any account at any time is the maximum of the + /// second values of the items in this list whose first value is the account. + /// + /// The first item in the list is the amount locked for the current Lease Period. Following + /// items are for the subsequent lease periods. + /// + /// The default value (an empty list) implies that the parachain no longer exists (or never + /// existed) as far as this pallet is concerned. + /// + /// If a parachain doesn't exist *yet* but is scheduled to exist in the future, then it + /// will be left-padded with one or more `None`s to denote the fact that nothing is held on + /// deposit for the non-existent chain currently, but is held at some point in the future. + /// + /// It is illegal for a `None` value to trail in the list. + #[pallet::storage] + #[pallet::getter(fn lease)] + pub type Leases = + StorageMap<_, Twox64Concat, ParaId, Vec)>>, ValueQuery>; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// A new `[lease_period]` is beginning. + NewLeasePeriod { lease_period: LeasePeriodOf }, + /// A para has won the right to a continuous set of lease periods as a parachain. + /// First balance is any extra amount reserved on top of the para's existing deposit. + /// Second balance is the total amount reserved. + Leased { + para_id: ParaId, + leaser: T::AccountId, + period_begin: LeasePeriodOf, + period_count: LeasePeriodOf, + extra_reserved: BalanceOf, + total_amount: BalanceOf, + }, + } + + #[pallet::error] + pub enum Error { + /// The parachain ID is not onboarding. + ParaNotOnboarding, + /// There was an error with the lease. + LeaseError, + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(n: BlockNumberFor) -> Weight { + if let Some((lease_period, first_block)) = Self::lease_period_index(n) { + // If we're beginning a new lease period then handle that. + if first_block { + return Self::manage_lease_period_start(lease_period) + } + } + + // We didn't return early above, so we didn't do anything. + Weight::zero() + } + } + + #[pallet::call] + impl Pallet { + /// Just a connect into the `lease_out` call, in case Root wants to force some lease to + /// happen independently of any other on-chain mechanism to use it. + /// + /// The dispatch origin for this call must match `T::ForceOrigin`. + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::force_lease())] + pub fn force_lease( + origin: OriginFor, + para: ParaId, + leaser: T::AccountId, + amount: BalanceOf, + period_begin: LeasePeriodOf, + period_count: LeasePeriodOf, + ) -> DispatchResult { + T::ForceOrigin::ensure_origin(origin)?; + Self::lease_out(para, &leaser, amount, period_begin, period_count) + .map_err(|_| Error::::LeaseError)?; + Ok(()) + } + + /// Clear all leases for a Para Id, refunding any deposits back to the original owners. + /// + /// The dispatch origin for this call must match `T::ForceOrigin`. + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::clear_all_leases())] + pub fn clear_all_leases(origin: OriginFor, para: ParaId) -> DispatchResult { + T::ForceOrigin::ensure_origin(origin)?; + let deposits = Self::all_deposits_held(para); + + // Refund any deposits for these leases + for (who, deposit) in deposits { + let err_amount = T::Currency::unreserve(&who, deposit); + debug_assert!(err_amount.is_zero()); + } + + Leases::::remove(para); + Ok(()) + } + + /// Try to onboard a parachain that has a lease for the current lease period. + /// + /// This function can be useful if there was some state issue with a para that should + /// have onboarded, but was unable to. As long as they have a lease period, we can + /// let them onboard from here. + /// + /// Origin must be signed, but can be called by anyone. + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::trigger_onboard())] + pub fn trigger_onboard(origin: OriginFor, para: ParaId) -> DispatchResult { + let _ = ensure_signed(origin)?; + let leases = Leases::::get(para); + match leases.first() { + // If the first element in leases is present, then it has a lease! + // We can try to onboard it. + Some(Some(_lease_info)) => T::Registrar::make_parachain(para)?, + // Otherwise, it does not have a lease. + Some(None) | None => return Err(Error::::ParaNotOnboarding.into()), + }; + Ok(()) + } + } +} + +impl Pallet { + /// A new lease period is beginning. We're at the start of the first block of it. + /// + /// We need to on-board and off-board parachains as needed. We should also handle reducing/ + /// returning deposits. + fn manage_lease_period_start(lease_period_index: LeasePeriodOf) -> Weight { + Self::deposit_event(Event::::NewLeasePeriod { lease_period: lease_period_index }); + + let old_parachains = T::Registrar::parachains(); + + // Figure out what chains need bringing on. + let mut parachains = Vec::new(); + for (para, mut lease_periods) in Leases::::iter() { + if lease_periods.is_empty() { + continue + } + // ^^ should never be empty since we would have deleted the entry otherwise. + + if lease_periods.len() == 1 { + // Just one entry, which corresponds to the now-ended lease period. + // + // `para` is now just an on-demand parachain. + // + // Unreserve whatever is left. + if let Some((who, value)) = &lease_periods[0] { + T::Currency::unreserve(&who, *value); + } + + // Remove the now-empty lease list. + Leases::::remove(para); + } else { + // The parachain entry has leased future periods. + + // We need to pop the first deposit entry, which corresponds to the now- + // ended lease period. + let maybe_ended_lease = lease_periods.remove(0); + + Leases::::insert(para, &lease_periods); + + // If we *were* active in the last period and so have ended a lease... + if let Some(ended_lease) = maybe_ended_lease { + // Then we need to get the new amount that should continue to be held on + // deposit for the parachain. + let now_held = Self::deposit_held(para, &ended_lease.0); + + // If this is less than what we were holding for this leaser's now-ended lease, + // then unreserve it. + if let Some(rebate) = ended_lease.1.checked_sub(&now_held) { + T::Currency::unreserve(&ended_lease.0, rebate); + } + } + + // If we have an active lease in the new period, then add to the current parachains + if lease_periods[0].is_some() { + parachains.push(para); + } + } + } + parachains.sort(); + + for para in parachains.iter() { + if old_parachains.binary_search(para).is_err() { + // incoming. + let res = T::Registrar::make_parachain(*para); + debug_assert!(res.is_ok()); + } + } + + for para in old_parachains.iter() { + if parachains.binary_search(para).is_err() { + // outgoing. + let res = T::Registrar::make_parathread(*para); + debug_assert!(res.is_ok()); + } + } + + T::WeightInfo::manage_lease_period_start( + old_parachains.len() as u32, + parachains.len() as u32, + ) + } + + // Return a vector of (user, balance) for all deposits for a parachain. + // Useful when trying to clean up a parachain leases, as this would tell + // you all the balances you need to unreserve. + fn all_deposits_held(para: ParaId) -> Vec<(T::AccountId, BalanceOf)> { + let mut tracker = sp_std::collections::btree_map::BTreeMap::new(); + Leases::::get(para).into_iter().for_each(|lease| match lease { + Some((who, amount)) => match tracker.get(&who) { + Some(prev_amount) => + if amount > *prev_amount { + tracker.insert(who, amount); + }, + None => { + tracker.insert(who, amount); + }, + }, + None => {}, + }); + + tracker.into_iter().collect() + } +} + +impl crate::traits::OnSwap for Pallet { + fn on_swap(one: ParaId, other: ParaId) { + Leases::::mutate(one, |x| Leases::::mutate(other, |y| sp_std::mem::swap(x, y))) + } +} + +impl Leaser> for Pallet { + type AccountId = T::AccountId; + type LeasePeriod = BlockNumberFor; + type Currency = T::Currency; + + fn lease_out( + para: ParaId, + leaser: &Self::AccountId, + amount: >::Balance, + period_begin: Self::LeasePeriod, + period_count: Self::LeasePeriod, + ) -> Result<(), LeaseError> { + let now = frame_system::Pallet::::block_number(); + let (current_lease_period, _) = + Self::lease_period_index(now).ok_or(LeaseError::NoLeasePeriod)?; + // Finally, we update the deposit held so it is `amount` for the new lease period + // indices that were won in the auction. + let offset = period_begin + .checked_sub(¤t_lease_period) + .and_then(|x| x.checked_into::()) + .ok_or(LeaseError::AlreadyEnded)?; + + // offset is the amount into the `Deposits` items list that our lease begins. `period_count` + // is the number of items that it lasts for. + + // The lease period index range (begin, end) that newly belongs to this parachain + // ID. We need to ensure that it features in `Deposits` to prevent it from being + // reaped too early (any managed parachain whose `Deposits` set runs low will be + // removed). + Leases::::try_mutate(para, |d| { + // Left-pad with `None`s as necessary. + if d.len() < offset { + d.resize_with(offset, || None); + } + let period_count_usize = + period_count.checked_into::().ok_or(LeaseError::AlreadyEnded)?; + // Then place the deposit values for as long as the chain should exist. + for i in offset..(offset + period_count_usize) { + if d.len() > i { + // Already exists but it's `None`. That means a later slot was already leased. + // No problem. + if d[i] == None { + d[i] = Some((leaser.clone(), amount)); + } else { + // The chain tried to lease the same period twice. This might be a griefing + // attempt. + // + // We bail, not giving any lease and leave it for governance to sort out. + return Err(LeaseError::AlreadyLeased) + } + } else if d.len() == i { + // Doesn't exist. This is usual. + d.push(Some((leaser.clone(), amount))); + } else { + // earlier resize means it must be >= i; qed + // defensive code though since we really don't want to panic here. + } + } + + // Figure out whether we already have some funds of `leaser` held in reserve for + // `para_id`. If so, then we can deduct those from the amount that we need to reserve. + let maybe_additional = amount.checked_sub(&Self::deposit_held(para, &leaser)); + if let Some(ref additional) = maybe_additional { + T::Currency::reserve(&leaser, *additional) + .map_err(|_| LeaseError::ReserveFailed)?; + } + + let reserved = maybe_additional.unwrap_or_default(); + + // Check if current lease period is same as period begin, and onboard them directly. + // This will allow us to support onboarding new parachains in the middle of a lease + // period. + if current_lease_period == period_begin { + // Best effort. Not much we can do if this fails. + let _ = T::Registrar::make_parachain(para); + } + + Self::deposit_event(Event::::Leased { + para_id: para, + leaser: leaser.clone(), + period_begin, + period_count, + extra_reserved: reserved, + total_amount: amount, + }); + + Ok(()) + }) + } + + fn deposit_held( + para: ParaId, + leaser: &Self::AccountId, + ) -> >::Balance { + Leases::::get(para) + .into_iter() + .map(|lease| match lease { + Some((who, amount)) => + if &who == leaser { + amount + } else { + Zero::zero() + }, + None => Zero::zero(), + }) + .max() + .unwrap_or_else(Zero::zero) + } + + #[cfg(any(feature = "runtime-benchmarks", test))] + fn lease_period_length() -> (BlockNumberFor, BlockNumberFor) { + (T::LeasePeriod::get(), T::LeaseOffset::get()) + } + + fn lease_period_index(b: BlockNumberFor) -> Option<(Self::LeasePeriod, bool)> { + // Note that blocks before `LeaseOffset` do not count as any lease period. + let offset_block_now = b.checked_sub(&T::LeaseOffset::get())?; + let lease_period = offset_block_now / T::LeasePeriod::get(); + let first_block = (offset_block_now % T::LeasePeriod::get()).is_zero(); + + Some((lease_period, first_block)) + } + + fn already_leased( + para_id: ParaId, + first_period: Self::LeasePeriod, + last_period: Self::LeasePeriod, + ) -> bool { + let now = frame_system::Pallet::::block_number(); + let (current_lease_period, _) = match Self::lease_period_index(now) { + Some(clp) => clp, + None => return true, + }; + + // Can't look in the past, so we pick whichever is the biggest. + let start_period = first_period.max(current_lease_period); + // Find the offset to look into the lease period list. + // Subtraction is safe because of max above. + let offset = match (start_period - current_lease_period).checked_into::() { + Some(offset) => offset, + None => return true, + }; + + // This calculates how deep we should look in the vec for a potential lease. + let period_count = match last_period.saturating_sub(start_period).checked_into::() { + Some(period_count) => period_count, + None => return true, + }; + + // Get the leases, and check each item in the vec which is part of the range we are + // checking. + let leases = Leases::::get(para_id); + for slot in offset..=offset + period_count { + if let Some(Some(_)) = leases.get(slot) { + // If there exists any lease period, we exit early and return true. + return true + } + } + + // If we got here, then we did not find any overlapping leases. + false + } +} + +/// tests for this pallet +#[cfg(test)] +mod tests { + use super::*; + + use crate::{mock::TestRegistrar, slots}; + use ::test_helpers::{dummy_head_data, dummy_validation_code}; + use frame_support::{assert_noop, assert_ok, parameter_types}; + use frame_system::EnsureRoot; + use pallet_balances; + use primitives::BlockNumber; + use sp_core::H256; + use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + BuildStorage, + }; + + type Block = frame_system::mocking::MockBlockU32; + + frame_support::construct_runtime!( + pub enum Test + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Slots: slots::{Pallet, Call, Storage, Event}, + } + ); + + parameter_types! { + pub const BlockHashCount: u32 = 250; + } + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + } + + parameter_types! { + pub const ExistentialDeposit: u64 = 1; + } + + impl pallet_balances::Config for Test { + type Balance = u64; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<1>; + type MaxFreezes = ConstU32<1>; + } + + parameter_types! { + pub const LeasePeriod: BlockNumber = 10; + pub static LeaseOffset: BlockNumber = 0; + pub const ParaDeposit: u64 = 1; + } + + impl Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Registrar = TestRegistrar; + type LeasePeriod = LeasePeriod; + type LeaseOffset = LeaseOffset; + type ForceOrigin = EnsureRoot; + type WeightInfo = crate::slots::TestWeightInfo; + } + + // This function basically just builds a genesis storage key/value store according to + // our desired mock up. + pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + } + .assimilate_storage(&mut t) + .unwrap(); + t.into() + } + + fn run_to_block(n: BlockNumber) { + while System::block_number() < n { + Slots::on_finalize(System::block_number()); + Balances::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + System::set_block_number(System::block_number() + 1); + System::on_initialize(System::block_number()); + Balances::on_initialize(System::block_number()); + Slots::on_initialize(System::block_number()); + } + } + + #[test] + fn basic_setup_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_eq!(Slots::lease_period_length(), (10, 0)); + let now = System::block_number(); + assert_eq!(Slots::lease_period_index(now).unwrap().0, 0); + assert_eq!(Slots::deposit_held(1.into(), &1), 0); + + run_to_block(10); + let now = System::block_number(); + assert_eq!(Slots::lease_period_index(now).unwrap().0, 1); + }); + } + + #[test] + fn lease_lifecycle_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code() + )); + + assert_ok!(Slots::lease_out(1.into(), &1, 1, 1, 1)); + assert_eq!(Slots::deposit_held(1.into(), &1), 1); + assert_eq!(Balances::reserved_balance(1), 1); + + run_to_block(19); + assert_eq!(Slots::deposit_held(1.into(), &1), 1); + assert_eq!(Balances::reserved_balance(1), 1); + + run_to_block(20); + assert_eq!(Slots::deposit_held(1.into(), &1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + + assert_eq!( + TestRegistrar::::operations(), + vec![(1.into(), 10, true), (1.into(), 20, false),] + ); + }); + } + + #[test] + fn lease_interrupted_lifecycle_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code() + )); + + assert_ok!(Slots::lease_out(1.into(), &1, 6, 1, 1)); + assert_ok!(Slots::lease_out(1.into(), &1, 4, 3, 1)); + + run_to_block(19); + assert_eq!(Slots::deposit_held(1.into(), &1), 6); + assert_eq!(Balances::reserved_balance(1), 6); + + run_to_block(20); + assert_eq!(Slots::deposit_held(1.into(), &1), 4); + assert_eq!(Balances::reserved_balance(1), 4); + + run_to_block(39); + assert_eq!(Slots::deposit_held(1.into(), &1), 4); + assert_eq!(Balances::reserved_balance(1), 4); + + run_to_block(40); + assert_eq!(Slots::deposit_held(1.into(), &1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + + assert_eq!( + TestRegistrar::::operations(), + vec![ + (1.into(), 10, true), + (1.into(), 20, false), + (1.into(), 30, true), + (1.into(), 40, false), + ] + ); + }); + } + + #[test] + fn lease_relayed_lifecycle_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code() + )); + + assert!(Slots::lease_out(1.into(), &1, 6, 1, 1).is_ok()); + assert!(Slots::lease_out(1.into(), &2, 4, 2, 1).is_ok()); + assert_eq!(Slots::deposit_held(1.into(), &1), 6); + assert_eq!(Balances::reserved_balance(1), 6); + assert_eq!(Slots::deposit_held(1.into(), &2), 4); + assert_eq!(Balances::reserved_balance(2), 4); + + run_to_block(19); + assert_eq!(Slots::deposit_held(1.into(), &1), 6); + assert_eq!(Balances::reserved_balance(1), 6); + assert_eq!(Slots::deposit_held(1.into(), &2), 4); + assert_eq!(Balances::reserved_balance(2), 4); + + run_to_block(20); + assert_eq!(Slots::deposit_held(1.into(), &1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Slots::deposit_held(1.into(), &2), 4); + assert_eq!(Balances::reserved_balance(2), 4); + + run_to_block(29); + assert_eq!(Slots::deposit_held(1.into(), &1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Slots::deposit_held(1.into(), &2), 4); + assert_eq!(Balances::reserved_balance(2), 4); + + run_to_block(30); + assert_eq!(Slots::deposit_held(1.into(), &1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Slots::deposit_held(1.into(), &2), 0); + assert_eq!(Balances::reserved_balance(2), 0); + + assert_eq!( + TestRegistrar::::operations(), + vec![(1.into(), 10, true), (1.into(), 30, false),] + ); + }); + } + + #[test] + fn lease_deposit_increase_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code() + )); + + assert!(Slots::lease_out(1.into(), &1, 4, 1, 1).is_ok()); + assert_eq!(Slots::deposit_held(1.into(), &1), 4); + assert_eq!(Balances::reserved_balance(1), 4); + + assert!(Slots::lease_out(1.into(), &1, 6, 2, 1).is_ok()); + assert_eq!(Slots::deposit_held(1.into(), &1), 6); + assert_eq!(Balances::reserved_balance(1), 6); + + run_to_block(29); + assert_eq!(Slots::deposit_held(1.into(), &1), 6); + assert_eq!(Balances::reserved_balance(1), 6); + + run_to_block(30); + assert_eq!(Slots::deposit_held(1.into(), &1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + + assert_eq!( + TestRegistrar::::operations(), + vec![(1.into(), 10, true), (1.into(), 30, false),] + ); + }); + } + + #[test] + fn lease_deposit_decrease_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code() + )); + + assert!(Slots::lease_out(1.into(), &1, 6, 1, 1).is_ok()); + assert_eq!(Slots::deposit_held(1.into(), &1), 6); + assert_eq!(Balances::reserved_balance(1), 6); + + assert!(Slots::lease_out(1.into(), &1, 4, 2, 1).is_ok()); + assert_eq!(Slots::deposit_held(1.into(), &1), 6); + assert_eq!(Balances::reserved_balance(1), 6); + + run_to_block(19); + assert_eq!(Slots::deposit_held(1.into(), &1), 6); + assert_eq!(Balances::reserved_balance(1), 6); + + run_to_block(20); + assert_eq!(Slots::deposit_held(1.into(), &1), 4); + assert_eq!(Balances::reserved_balance(1), 4); + + run_to_block(29); + assert_eq!(Slots::deposit_held(1.into(), &1), 4); + assert_eq!(Balances::reserved_balance(1), 4); + + run_to_block(30); + assert_eq!(Slots::deposit_held(1.into(), &1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + + assert_eq!( + TestRegistrar::::operations(), + vec![(1.into(), 10, true), (1.into(), 30, false),] + ); + }); + } + + #[test] + fn clear_all_leases_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code() + )); + + let max_num = 5u32; + + // max_num different people are reserved for leases to Para ID 1 + for i in 1u32..=max_num { + let j: u64 = i.into(); + assert_ok!(Slots::lease_out(1.into(), &j, j * 10 - 1, i * i, i)); + assert_eq!(Slots::deposit_held(1.into(), &j), j * 10 - 1); + assert_eq!(Balances::reserved_balance(j), j * 10 - 1); + } + + assert_ok!(Slots::clear_all_leases(RuntimeOrigin::root(), 1.into())); + + // Balances cleaned up correctly + for i in 1u32..=max_num { + let j: u64 = i.into(); + assert_eq!(Slots::deposit_held(1.into(), &j), 0); + assert_eq!(Balances::reserved_balance(j), 0); + } + + // Leases is empty. + assert!(Leases::::get(ParaId::from(1_u32)).is_empty()); + }); + } + + #[test] + fn lease_out_current_lease_period() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code() + )); + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(2_u32), + dummy_head_data(), + dummy_validation_code() + )); + + run_to_block(20); + let now = System::block_number(); + assert_eq!(Slots::lease_period_index(now).unwrap().0, 2); + // Can't lease from the past + assert!(Slots::lease_out(1.into(), &1, 1, 1, 1).is_err()); + // Lease in the current period triggers onboarding + assert_ok!(Slots::lease_out(1.into(), &1, 1, 2, 1)); + // Lease in the future doesn't + assert_ok!(Slots::lease_out(2.into(), &1, 1, 3, 1)); + + assert_eq!(TestRegistrar::::operations(), vec![(1.into(), 20, true),]); + }); + } + + #[test] + fn trigger_onboard_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(1_u32), + dummy_head_data(), + dummy_validation_code() + )); + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(2_u32), + dummy_head_data(), + dummy_validation_code() + )); + assert_ok!(TestRegistrar::::register( + 1, + ParaId::from(3_u32), + dummy_head_data(), + dummy_validation_code() + )); + + // We will directly manipulate leases to emulate some kind of failure in the system. + // Para 1 will have no leases + // Para 2 will have a lease period in the current index + Leases::::insert(ParaId::from(2_u32), vec![Some((0, 0))]); + // Para 3 will have a lease period in a future index + Leases::::insert(ParaId::from(3_u32), vec![None, None, Some((0, 0))]); + + // Para 1 should fail cause they don't have any leases + assert_noop!( + Slots::trigger_onboard(RuntimeOrigin::signed(1), 1.into()), + Error::::ParaNotOnboarding + ); + + // Para 2 should succeed + assert_ok!(Slots::trigger_onboard(RuntimeOrigin::signed(1), 2.into())); + + // Para 3 should fail cause their lease is in the future + assert_noop!( + Slots::trigger_onboard(RuntimeOrigin::signed(1), 3.into()), + Error::::ParaNotOnboarding + ); + + // Trying Para 2 again should fail cause they are not currently an on-demand parachain + assert!(Slots::trigger_onboard(RuntimeOrigin::signed(1), 2.into()).is_err()); + + assert_eq!(TestRegistrar::::operations(), vec![(2.into(), 1, true),]); + }); + } + + #[test] + fn lease_period_offset_works() { + new_test_ext().execute_with(|| { + let (lpl, offset) = Slots::lease_period_length(); + assert_eq!(offset, 0); + assert_eq!(Slots::lease_period_index(0), Some((0, true))); + assert_eq!(Slots::lease_period_index(1), Some((0, false))); + assert_eq!(Slots::lease_period_index(lpl - 1), Some((0, false))); + assert_eq!(Slots::lease_period_index(lpl), Some((1, true))); + assert_eq!(Slots::lease_period_index(lpl + 1), Some((1, false))); + assert_eq!(Slots::lease_period_index(2 * lpl - 1), Some((1, false))); + assert_eq!(Slots::lease_period_index(2 * lpl), Some((2, true))); + assert_eq!(Slots::lease_period_index(2 * lpl + 1), Some((2, false))); + + // Lease period is 10, and we add an offset of 5. + LeaseOffset::set(5); + let (lpl, offset) = Slots::lease_period_length(); + assert_eq!(offset, 5); + assert_eq!(Slots::lease_period_index(0), None); + assert_eq!(Slots::lease_period_index(1), None); + assert_eq!(Slots::lease_period_index(offset), Some((0, true))); + assert_eq!(Slots::lease_period_index(lpl), Some((0, false))); + assert_eq!(Slots::lease_period_index(lpl - 1 + offset), Some((0, false))); + assert_eq!(Slots::lease_period_index(lpl + offset), Some((1, true))); + assert_eq!(Slots::lease_period_index(lpl + offset + 1), Some((1, false))); + assert_eq!(Slots::lease_period_index(2 * lpl - 1 + offset), Some((1, false))); + assert_eq!(Slots::lease_period_index(2 * lpl + offset), Some((2, true))); + assert_eq!(Slots::lease_period_index(2 * lpl + offset + 1), Some((2, false))); + }); + } +} + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking { + use super::*; + use frame_support::assert_ok; + use frame_system::RawOrigin; + use runtime_parachains::paras; + use sp_runtime::traits::{Bounded, One}; + + use frame_benchmarking::{account, benchmarks, whitelisted_caller, BenchmarkError}; + + use crate::slots::Pallet as Slots; + + fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); + } + + // Registers a parathread (on-demand parachain) + fn register_a_parathread(i: u32) -> (ParaId, T::AccountId) { + let para = ParaId::from(i); + let leaser: T::AccountId = account("leaser", i, 0); + T::Currency::make_free_balance_be(&leaser, BalanceOf::::max_value()); + let worst_head_data = T::Registrar::worst_head_data(); + let worst_validation_code = T::Registrar::worst_validation_code(); + + assert_ok!(T::Registrar::register( + leaser.clone(), + para, + worst_head_data, + worst_validation_code.clone(), + )); + assert_ok!(paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + worst_validation_code, + )); + + T::Registrar::execute_pending_transitions(); + + (para, leaser) + } + + benchmarks! { + where_clause { where T: paras::Config } + + force_lease { + // If there is an offset, we need to be on that block to be able to do lease things. + frame_system::Pallet::::set_block_number(T::LeaseOffset::get() + One::one()); + let para = ParaId::from(1337); + let leaser: T::AccountId = account("leaser", 0, 0); + T::Currency::make_free_balance_be(&leaser, BalanceOf::::max_value()); + let amount = T::Currency::minimum_balance(); + let period_begin = 69u32.into(); + let period_count = 3u32.into(); + let origin = + T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + }: _(origin, para, leaser.clone(), amount, period_begin, period_count) + verify { + assert_last_event::(Event::::Leased { + para_id: para, + leaser, period_begin, + period_count, + extra_reserved: amount, + total_amount: amount, + }.into()); + } + + // Worst case scenario, T on-demand parachains onboard, and C lease holding parachains offboard. + manage_lease_period_start { + // Assume reasonable maximum of 100 paras at any time + let c in 0 .. 100; + let t in 0 .. 100; + + let period_begin = 1u32.into(); + let period_count = 4u32.into(); + + // If there is an offset, we need to be on that block to be able to do lease things. + frame_system::Pallet::::set_block_number(T::LeaseOffset::get() + One::one()); + + // Make T parathreads (on-demand parachains) + let paras_info = (0..t).map(|i| { + register_a_parathread::(i) + }).collect::>(); + + T::Registrar::execute_pending_transitions(); + + // T on-demand parachains are upgrading to lease holding parachains + for (para, leaser) in paras_info { + let amount = T::Currency::minimum_balance(); + let origin = T::ForceOrigin::try_successful_origin() + .expect("ForceOrigin has no successful origin required for the benchmark"); + Slots::::force_lease(origin, para, leaser, amount, period_begin, period_count)?; + } + + T::Registrar::execute_pending_transitions(); + + // C lease holding parachains are downgrading to on-demand parachains + for i in 200 .. 200 + c { + let (para, leaser) = register_a_parathread::(i); + T::Registrar::make_parachain(para)?; + } + + T::Registrar::execute_pending_transitions(); + + for i in 0 .. t { + assert!(T::Registrar::is_parathread(ParaId::from(i))); + } + + for i in 200 .. 200 + c { + assert!(T::Registrar::is_parachain(ParaId::from(i))); + } + }: { + Slots::::manage_lease_period_start(period_begin); + } verify { + // All paras should have switched. + T::Registrar::execute_pending_transitions(); + for i in 0 .. t { + assert!(T::Registrar::is_parachain(ParaId::from(i))); + } + for i in 200 .. 200 + c { + assert!(T::Registrar::is_parathread(ParaId::from(i))); + } + } + + // Assume that at most 8 people have deposits for leases on a parachain. + // This would cover at least 4 years of leases in the worst case scenario. + clear_all_leases { + let max_people = 8; + let (para, _) = register_a_parathread::(1); + + // If there is an offset, we need to be on that block to be able to do lease things. + frame_system::Pallet::::set_block_number(T::LeaseOffset::get() + One::one()); + + for i in 0 .. max_people { + let leaser = account("lease_deposit", i, 0); + let amount = T::Currency::minimum_balance(); + T::Currency::make_free_balance_be(&leaser, BalanceOf::::max_value()); + + // Average slot has 4 lease periods. + let period_count: LeasePeriodOf = 4u32.into(); + let period_begin = period_count * i.into(); + let origin = T::ForceOrigin::try_successful_origin() + .expect("ForceOrigin has no successful origin required for the benchmark"); + Slots::::force_lease(origin, para, leaser, amount, period_begin, period_count)?; + } + + for i in 0 .. max_people { + let leaser = account("lease_deposit", i, 0); + assert_eq!(T::Currency::reserved_balance(&leaser), T::Currency::minimum_balance()); + } + + let origin = + T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + }: _(origin, para) + verify { + for i in 0 .. max_people { + let leaser = account("lease_deposit", i, 0); + assert_eq!(T::Currency::reserved_balance(&leaser), 0u32.into()); + } + } + + trigger_onboard { + // get a parachain into a bad state where they did not onboard + let (para, _) = register_a_parathread::(1); + Leases::::insert(para, vec![Some((account::("lease_insert", 0, 0), BalanceOf::::default()))]); + assert!(T::Registrar::is_parathread(para)); + let caller = whitelisted_caller(); + }: _(RawOrigin::Signed(caller), para) + verify { + T::Registrar::execute_pending_transitions(); + assert!(T::Registrar::is_parachain(para)); + } + + impl_benchmark_test_suite!( + Slots, + crate::integration_tests::new_test_ext(), + crate::integration_tests::Test, + ); + } +} diff --git a/polkadot/runtime/common/src/traits.rs b/polkadot/runtime/common/src/traits.rs new file mode 100644 index 0000000000000000000000000000000000000000..8f75bf5c2fd8362e324f2bb42f28f462375921c1 --- /dev/null +++ b/polkadot/runtime/common/src/traits.rs @@ -0,0 +1,265 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Traits used across pallets for Polkadot. + +use frame_support::{ + dispatch::DispatchResult, + traits::{Currency, ReservableCurrency}, +}; +use primitives::{HeadData, Id as ParaId, ValidationCode}; +use sp_std::vec::*; + +/// Parachain registration API. +pub trait Registrar { + /// The account ID type that encodes a parachain manager ID. + type AccountId; + + /// Report the manager (permissioned owner) of a parachain, if there is one. + fn manager_of(id: ParaId) -> Option; + + /// All lease holding parachains. Ordered ascending by `ParaId`. On-demand + /// parachains are not included. + fn parachains() -> Vec; + + /// Return if a `ParaId` is a lease holding Parachain. + fn is_parachain(id: ParaId) -> bool { + Self::parachains().binary_search(&id).is_ok() + } + + /// Return if a `ParaId` is a Parathread (on-demand parachain). + fn is_parathread(id: ParaId) -> bool; + + /// Return if a `ParaId` is registered in the system. + fn is_registered(id: ParaId) -> bool { + Self::is_parathread(id) || Self::is_parachain(id) + } + + /// Apply a lock to the para registration so that it cannot be modified by + /// the manager directly. Instead the para must use its sovereign governance + /// or the governance of the relay chain. + fn apply_lock(id: ParaId); + + /// Remove any lock on the para registration. + fn remove_lock(id: ParaId); + + /// Register a Para ID under control of `who`. Registration may be be + /// delayed by session rotation. + fn register( + who: Self::AccountId, + id: ParaId, + genesis_head: HeadData, + validation_code: ValidationCode, + ) -> DispatchResult; + + /// Deregister a Para ID, free any data, and return any deposits. + fn deregister(id: ParaId) -> DispatchResult; + + /// Elevate a para to parachain status. + fn make_parachain(id: ParaId) -> DispatchResult; + + /// Downgrade lease holding parachain into parathread (on-demand parachain) + fn make_parathread(id: ParaId) -> DispatchResult; + + #[cfg(any(feature = "runtime-benchmarks", test))] + fn worst_head_data() -> HeadData; + + #[cfg(any(feature = "runtime-benchmarks", test))] + fn worst_validation_code() -> ValidationCode; + + /// Execute any pending state transitions for paras. + /// For example onboarding to on-demand parachain, or upgrading on-demand to + /// lease holding parachain. + #[cfg(any(feature = "runtime-benchmarks", test))] + fn execute_pending_transitions(); +} + +/// Error type for something that went wrong with leasing. +#[derive(Debug)] +pub enum LeaseError { + /// Unable to reserve the funds in the leaser's account. + ReserveFailed, + /// There is already a lease on at least one period for the given para. + AlreadyLeased, + /// The period to be leased has already ended. + AlreadyEnded, + /// A lease period has not started yet, due to an offset in the starting block. + NoLeasePeriod, +} + +/// Lease manager. Used by the auction module to handle parachain slot leases. +pub trait Leaser { + /// An account identifier for a leaser. + type AccountId; + + /// The measurement type for counting lease periods (generally just a `BlockNumber`). + type LeasePeriod; + + /// The currency type in which the lease is taken. + type Currency: ReservableCurrency; + + /// Lease a new parachain slot for `para`. + /// + /// `leaser` shall have a total of `amount` balance reserved by the implementer of this trait. + /// + /// Note: The implementer of the trait (the leasing system) is expected to do all + /// reserve/unreserve calls. The caller of this trait *SHOULD NOT* pre-reserve the deposit + /// (though should ensure that it is reservable). + /// + /// The lease will last from `period_begin` for `period_count` lease periods. It is undefined if + /// the `para` already has a slot leased during those periods. + /// + /// Returns `Err` in the case of an error, and in which case nothing is changed. + fn lease_out( + para: ParaId, + leaser: &Self::AccountId, + amount: >::Balance, + period_begin: Self::LeasePeriod, + period_count: Self::LeasePeriod, + ) -> Result<(), LeaseError>; + + /// Return the amount of balance currently held in reserve on `leaser`'s account for leasing + /// `para`. This won't go down outside a lease period. + fn deposit_held( + para: ParaId, + leaser: &Self::AccountId, + ) -> >::Balance; + + /// The length of a lease period, and any offset which may be introduced. + /// This is only used in benchmarking to automate certain calls. + #[cfg(any(feature = "runtime-benchmarks", test))] + fn lease_period_length() -> (BlockNumber, BlockNumber); + + /// Returns the lease period at `block`, and if this is the first block of a new lease period. + /// + /// Will return `None` if the first lease period has not started yet, for example when an offset + /// is placed. + fn lease_period_index(block: BlockNumber) -> Option<(Self::LeasePeriod, bool)>; + + /// Returns true if the parachain already has a lease in any of lease periods in the inclusive + /// range `[first_period, last_period]`, intersected with the unbounded range + /// [`current_lease_period`..] . + fn already_leased( + para_id: ParaId, + first_period: Self::LeasePeriod, + last_period: Self::LeasePeriod, + ) -> bool; +} + +/// An enum which tracks the status of the auction system, and which phase it is in. +#[derive(PartialEq, Debug)] +pub enum AuctionStatus { + /// An auction has not started yet. + NotStarted, + /// We are in the starting period of the auction, collecting initial bids. + StartingPeriod, + /// We are in the ending period of the auction, where we are taking snapshots of the winning + /// bids. This state supports "sampling", where we may only take a snapshot every N blocks. + /// In this case, the first number is the current sample number, and the second number + /// is the sub-sample. i.e. for sampling every 20 blocks, the 25th block in the ending period + /// will be `EndingPeriod(1, 5)`. + EndingPeriod(BlockNumber, BlockNumber), + /// We have completed the bidding process and are waiting for the VRF to return some acceptable + /// randomness to select the winner. The number represents how many blocks we have been + /// waiting. + VrfDelay(BlockNumber), +} + +impl AuctionStatus { + /// Returns true if the auction is in any state other than `NotStarted`. + pub fn is_in_progress(&self) -> bool { + !matches!(self, Self::NotStarted) + } + /// Return true if the auction is in the starting period. + pub fn is_starting(&self) -> bool { + matches!(self, Self::StartingPeriod) + } + /// Returns `Some(sample, sub_sample)` if the auction is in the `EndingPeriod`, + /// otherwise returns `None`. + pub fn is_ending(self) -> Option<(BlockNumber, BlockNumber)> { + match self { + Self::EndingPeriod(sample, sub_sample) => Some((sample, sub_sample)), + _ => None, + } + } + /// Returns true if the auction is in the `VrfDelay` period. + pub fn is_vrf(&self) -> bool { + matches!(self, Self::VrfDelay(_)) + } +} + +pub trait Auctioneer { + /// An account identifier for a leaser. + type AccountId; + + /// The measurement type for counting lease periods (generally the same as `BlockNumber`). + type LeasePeriod; + + /// The currency type in which the lease is taken. + type Currency: ReservableCurrency; + + /// Create a new auction. + /// + /// This can only happen when there isn't already an auction in progress. Accepts the `duration` + /// of this auction and the `lease_period_index` of the initial lease period of the four that + /// are to be auctioned. + fn new_auction(duration: BlockNumber, lease_period_index: Self::LeasePeriod) -> DispatchResult; + + /// Given the current block number, return the current auction status. + fn auction_status(now: BlockNumber) -> AuctionStatus; + + /// Place a bid in the current auction. + /// + /// - `bidder`: The account that will be funding this bid. + /// - `para`: The para to bid for. + /// - `first_slot`: The first lease period index of the range to be bid on. + /// - `last_slot`: The last lease period index of the range to be bid on (inclusive). + /// - `amount`: The total amount to be the bid for deposit over the range. + /// + /// The account `Bidder` must have at least `amount` available as a free balance in `Currency`. + /// The implementation *MUST* remove or reserve `amount` funds from `bidder` and those funds + /// should be returned or freed once the bid is rejected or lease has ended. + fn place_bid( + bidder: Self::AccountId, + para: ParaId, + first_slot: Self::LeasePeriod, + last_slot: Self::LeasePeriod, + amount: >::Balance, + ) -> DispatchResult; + + /// The length of a lease period, and any offset which may be introduced. + /// This is only used in benchmarking to automate certain calls. + #[cfg(any(feature = "runtime-benchmarks", test))] + fn lease_period_length() -> (BlockNumber, BlockNumber); + + /// Returns the lease period at `block`, and if this is the first block of a new lease period. + /// + /// Will return `None` if the first lease period has not started yet, for example when an offset + /// is placed. + fn lease_period_index(block: BlockNumber) -> Option<(Self::LeasePeriod, bool)>; + + /// Check if the para and user combination has won an auction in the past. + fn has_won_an_auction(para: ParaId, bidder: &Self::AccountId) -> bool; +} + +/// Runtime hook for when we swap a lease holding parachain and an on-demand parachain. +#[impl_trait_for_tuples::impl_for_tuples(30)] +pub trait OnSwap { + /// Updates any needed state/references to enact a logical swap of two parachains. Identity, + /// code and `head_data` remain equivalent for all parachains/threads, however other properties + /// such as leases, deposits held and thread/chain nature are swapped. + fn on_swap(one: ParaId, other: ParaId); +} diff --git a/polkadot/runtime/common/src/try_runtime.rs b/polkadot/runtime/common/src/try_runtime.rs new file mode 100644 index 0000000000000000000000000000000000000000..81aa34317bfd7a7f82340bc4a8c10760049fd690 --- /dev/null +++ b/polkadot/runtime/common/src/try_runtime.rs @@ -0,0 +1,107 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Common try-runtime only tests for runtimes. + +use frame_support::{ + dispatch::RawOrigin, + traits::{Get, Hooks}, +}; +use pallet_fast_unstake::{Pallet as FastUnstake, *}; +use pallet_staking::*; +use sp_std::{collections::btree_set::BTreeSet, prelude::*}; + +/// register all inactive nominators for fast-unstake, and progress until they have all been +/// processed. +pub fn migrate_all_inactive_nominators() +where + ::RuntimeEvent: TryInto>, +{ + let mut unstaked_ok = 0; + let mut unstaked_err = 0; + let mut unstaked_slashed = 0; + + let all_stakers = Ledger::::iter().map(|(ctrl, l)| (ctrl, l.stash)).collect::>(); + let mut all_exposed = BTreeSet::new(); + ErasStakers::::iter().for_each(|(_, val, expo)| { + all_exposed.insert(val); + all_exposed.extend(expo.others.iter().map(|ie| ie.who.clone())) + }); + + let eligible = all_stakers + .iter() + .filter_map(|(ctrl, stash)| all_exposed.contains(stash).then_some(ctrl)) + .collect::>(); + + log::info!( + target: "runtime::test", + "registering {} out of {} stakers for fast-unstake", + eligible.len(), + all_stakers.len() + ); + for ctrl in eligible { + if let Err(why) = + FastUnstake::::register_fast_unstake(RawOrigin::Signed(ctrl.clone()).into()) + { + log::warn!(target: "runtime::test", "failed to register {:?} due to {:?}", ctrl, why); + } + } + + log::info!( + target: "runtime::test", + "registered {} successfully, starting at {:?}.", + Queue::::count(), + frame_system::Pallet::::block_number(), + ); + while Queue::::count() != 0 || Head::::get().is_some() { + let now = frame_system::Pallet::::block_number(); + let weight = ::BlockWeights::get().max_block; + let consumed = FastUnstake::::on_idle(now, weight); + log::debug!(target: "runtime::test", "consumed {:?} ({})", consumed, consumed.ref_time() as f32 / weight.ref_time() as f32); + + frame_system::Pallet::::read_events_no_consensus() + .into_iter() + .map(|r| r.event) + .filter_map(|e| { + let maybe_fast_unstake_event: Option> = + e.try_into().ok(); + maybe_fast_unstake_event + }) + .for_each(|e: pallet_fast_unstake::Event| match e { + pallet_fast_unstake::Event::::Unstaked { result, .. } => + if result.is_ok() { + unstaked_ok += 1; + } else { + unstaked_err += 1 + }, + pallet_fast_unstake::Event::::Slashed { .. } => unstaked_slashed += 1, + pallet_fast_unstake::Event::::InternalError => unreachable!(), + _ => {}, + }); + + if now % 100u32.into() == sp_runtime::traits::Zero::zero() { + log::info!( + target: "runtime::test", + "status: ok {}, err {}, slash {}", + unstaked_ok, + unstaked_err, + unstaked_slashed, + ); + } + + frame_system::Pallet::::reset_events(); + } +} diff --git a/polkadot/runtime/common/src/xcm_sender.rs b/polkadot/runtime/common/src/xcm_sender.rs new file mode 100644 index 0000000000000000000000000000000000000000..ff529143c5094dff797c420a5040b4f62639701e --- /dev/null +++ b/polkadot/runtime/common/src/xcm_sender.rs @@ -0,0 +1,166 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! XCM sender for relay chain. + +use frame_support::traits::Get; +use frame_system::pallet_prelude::BlockNumberFor; +use parity_scale_codec::Encode; +use primitives::Id as ParaId; +use runtime_parachains::{ + configuration::{self, HostConfiguration}, + dmp, FeeTracker, +}; +use sp_runtime::FixedPointNumber; +use sp_std::{marker::PhantomData, prelude::*}; +use xcm::prelude::*; +use SendError::*; + +/// Simple value-bearing trait for determining/expressing the assets required to be paid for a +/// messages to be delivered to a parachain. +pub trait PriceForParachainDelivery { + /// Return the assets required to deliver `message` to the given `para` destination. + fn price_for_parachain_delivery(para: ParaId, message: &Xcm<()>) -> MultiAssets; +} +impl PriceForParachainDelivery for () { + fn price_for_parachain_delivery(_: ParaId, _: &Xcm<()>) -> MultiAssets { + MultiAssets::new() + } +} + +/// Implementation of `PriceForParachainDelivery` which returns a fixed price. +pub struct ConstantPrice(sp_std::marker::PhantomData); +impl> PriceForParachainDelivery for ConstantPrice { + fn price_for_parachain_delivery(_: ParaId, _: &Xcm<()>) -> MultiAssets { + T::get() + } +} + +/// Implementation of `PriceForParachainDelivery` which returns an exponentially increasing price. +/// The `A` type parameter is used to denote the asset ID that will be used for paying the delivery +/// fee. +/// +/// The formula for the fee is based on the sum of a base fee plus a message length fee, multiplied +/// by a specified factor. In mathematical form, it is `F * (B + encoded_msg_len * M)`. +pub struct ExponentialPrice(sp_std::marker::PhantomData<(A, B, M, F)>); +impl, B: Get, M: Get, F: FeeTracker> PriceForParachainDelivery + for ExponentialPrice +{ + fn price_for_parachain_delivery(para: ParaId, msg: &Xcm<()>) -> MultiAssets { + let msg_fee = (msg.encoded_size() as u128).saturating_mul(M::get()); + let fee_sum = B::get().saturating_add(msg_fee); + let amount = F::get_fee_factor(para).saturating_mul_int(fee_sum); + (A::get(), amount).into() + } +} + +/// XCM sender for relay chain. It only sends downward message. +pub struct ChildParachainRouter(PhantomData<(T, W, P)>); + +impl + SendXcm for ChildParachainRouter +{ + type Ticket = (HostConfiguration>, ParaId, Vec); + + fn validate( + dest: &mut Option, + msg: &mut Option>, + ) -> SendResult<(HostConfiguration>, ParaId, Vec)> { + let d = dest.take().ok_or(MissingArgument)?; + let id = if let MultiLocation { parents: 0, interior: X1(Parachain(id)) } = &d { + *id + } else { + *dest = Some(d); + return Err(NotApplicable) + }; + + // Downward message passing. + let xcm = msg.take().ok_or(MissingArgument)?; + let config = >::config(); + let para = id.into(); + let price = P::price_for_parachain_delivery(para, &xcm); + let blob = W::wrap_version(&d, xcm).map_err(|()| DestinationUnsupported)?.encode(); + >::can_queue_downward_message(&config, ¶, &blob) + .map_err(Into::::into)?; + + Ok(((config, para, blob), price)) + } + + fn deliver( + (config, para, blob): (HostConfiguration>, ParaId, Vec), + ) -> Result { + let hash = sp_io::hashing::blake2_256(&blob[..]); + >::queue_downward_message(&config, para, blob) + .map(|()| hash) + .map_err(|_| SendError::Transport(&"Error placing into DMP queue")) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use frame_support::parameter_types; + use runtime_parachains::FeeTracker; + use sp_runtime::FixedU128; + + parameter_types! { + pub const BaseDeliveryFee: u128 = 300_000_000; + pub const TransactionByteFee: u128 = 1_000_000; + pub FeeAssetId: AssetId = Concrete(Here.into()); + } + + struct TestFeeTracker; + impl FeeTracker for TestFeeTracker { + fn get_fee_factor(_: ParaId) -> FixedU128 { + FixedU128::from_rational(101, 100) + } + } + + type TestExponentialPrice = + ExponentialPrice; + + #[test] + fn exponential_price_correct_price_calculation() { + let id: ParaId = 123.into(); + let b: u128 = BaseDeliveryFee::get(); + let m: u128 = TransactionByteFee::get(); + + // F * (B + msg_length * M) + // message_length = 1 + let result: u128 = TestFeeTracker::get_fee_factor(id).saturating_mul_int(b + m); + assert_eq!( + TestExponentialPrice::price_for_parachain_delivery(id, &Xcm(vec![])), + (FeeAssetId::get(), result).into() + ); + + // message size = 2 + let result: u128 = TestFeeTracker::get_fee_factor(id).saturating_mul_int(b + (2 * m)); + assert_eq!( + TestExponentialPrice::price_for_parachain_delivery(id, &Xcm(vec![ClearOrigin])), + (FeeAssetId::get(), result).into() + ); + + // message size = 4 + let result: u128 = TestFeeTracker::get_fee_factor(id).saturating_mul_int(b + (4 * m)); + assert_eq!( + TestExponentialPrice::price_for_parachain_delivery( + id, + &Xcm(vec![SetAppendix(Xcm(vec![ClearOrigin]))]) + ), + (FeeAssetId::get(), result).into() + ); + } +} diff --git a/polkadot/runtime/kusama/Cargo.toml b/polkadot/runtime/kusama/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..3a253f47dde6cdb041547175b8d6c2ab8a77c318 --- /dev/null +++ b/polkadot/runtime/kusama/Cargo.toml @@ -0,0 +1,337 @@ +[package] +name = "kusama-runtime" +build = "build.rs" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +log = { version = "0.4.17", default-features = false } +rustc-hex = { version = "2.1.0", default-features = false } +serde = { version = "1.0.163", default-features = false } +serde_derive = { version = "1.0.117", optional = true } +static_assertions = "1.1.0" +smallvec = "1.8.0" + +authority-discovery-primitives = { package = "sp-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +beefy-primitives = { package = "sp-consensus-beefy", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +binary-merkle-tree = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +kusama-runtime-constants = { package = "kusama-runtime-constants", path = "./constants", default-features = false } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +offchain-primitives = { package = "sp-offchain", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +tx-pool-api = { package = "sp-transaction-pool", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +block-builder-api = { package = "sp-block-builder", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +pallet-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-bags-list = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-beefy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-beefy-mmr = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-bounties = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-child-bounties = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-nomination-pools-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-conviction-voting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-democracy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-elections-phragmen = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-fast-unstake = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-executive = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-nis = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-identity = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-im-online = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-indices = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-message-queue = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-mmr = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-multisig = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-nomination-pools = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-offences = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-preimage = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-proxy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-ranked-collective = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-recovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-referenda = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-scheduler = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-society = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = ["experimental"] } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-state-trie-migration = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system = {git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-tips = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-whitelist = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-xcm = { path = "../../xcm/pallet-xcm", default-features = false } +pallet-xcm-benchmarks = { path = "../../xcm/pallet-xcm-benchmarks", default-features = false, optional = true } +frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-offences-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-session-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-nomination-pools-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-election-provider-support-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +hex-literal = "0.4.1" + +runtime-common = { package = "polkadot-runtime-common", path = "../common", default-features = false } +runtime-parachains = { package = "polkadot-runtime-parachains", path = "../parachains", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } + +xcm = { package = "xcm", path = "../../xcm", default-features = false } +xcm-executor = { package = "xcm-executor", path = "../../xcm/xcm-executor", default-features = false } +xcm-builder = { package = "xcm-builder", path = "../../xcm/xcm-builder", default-features = false } + +[dev-dependencies] +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "master" } +sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } +separator = "0.4.1" +serde_json = "1.0.96" +remote-externalities = { git = "https://github.com/paritytech/substrate", branch = "master", package = "frame-remote-externalities" } +tokio = { version = "1.24.2", features = ["macros"] } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +[build-dependencies] +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = ["std"] +no_std = [] +only-staking = [] +std = [ + "authority-discovery-primitives/std", + "bitvec/std", + "primitives/std", + "rustc-hex/std", + "parity-scale-codec/std", + "scale-info/std", + "inherents/std", + "sp-arithmetic/std", + "sp-core/std", + "sp-api/std", + "tx-pool-api/std", + "block-builder-api/std", + "offchain-primitives/std", + "sp-std/std", + "sp-io/std", + "frame-support/std", + "frame-executive/std", + "pallet-authority-discovery/std", + "pallet-authorship/std", + "pallet-bags-list/std", + "pallet-balances/std", + "pallet-beefy/std", + "pallet-beefy-mmr/std", + "pallet-bounties/std", + "pallet-child-bounties/std", + "pallet-transaction-payment/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-collective/std", + "pallet-conviction-voting/std", + "pallet-elections-phragmen/std", + "pallet-election-provider-multi-phase/std", + "pallet-fast-unstake/std", + "pallet-democracy/std", + "pallet-nis/std", + "pallet-grandpa/std", + "pallet-identity/std", + "pallet-im-online/std", + "pallet-indices/std", + "pallet-membership/std", + "pallet-message-queue/std", + "pallet-mmr/std", + "pallet-multisig/std", + "pallet-nomination-pools/std", + "pallet-nomination-pools-runtime-api/std", + "pallet-offences/std", + "pallet-preimage/std", + "pallet-proxy/std", + "pallet-ranked-collective/std", + "pallet-recovery/std", + "pallet-referenda/std", + "pallet-scheduler/std", + "pallet-session/std", + "pallet-society/std", + "pallet-staking/std", + "pallet-staking-runtime-api/std", + "pallet-state-trie-migration/std", + "pallet-timestamp/std", + "pallet-tips/std", + "pallet-treasury/std", + "pallet-utility/std", + "pallet-vesting/std", + "pallet-whitelist/std", + "pallet-babe/std", + "pallet-xcm/std", + "sp-application-crypto/std", + "sp-mmr-primitives/std", + "sp-runtime/std", + "sp-staking/std", + "frame-system/std", + "frame-system-rpc-runtime-api/std", + "sp-version/std", + "serde_derive", + "serde/std", + "log/std", + "babe-primitives/std", + "sp-session/std", + "runtime-common/std", + "runtime-parachains/std", + "frame-try-runtime/std", + "sp-npos-elections/std", + "beefy-primitives/std", + "kusama-runtime-constants/std", + "xcm/std", + "xcm-executor/std", + "xcm-builder/std", + "frame-election-provider-support/std", +] +runtime-benchmarks = [ + "runtime-common/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "pallet-babe/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-bounties/runtime-benchmarks", + "pallet-child-bounties/runtime-benchmarks", + "pallet-collective/runtime-benchmarks", + "pallet-conviction-voting/runtime-benchmarks", + "pallet-democracy/runtime-benchmarks", + "pallet-elections-phragmen/runtime-benchmarks", + "pallet-election-provider-multi-phase/runtime-benchmarks", + "pallet-election-provider-support-benchmarking/runtime-benchmarks", + "pallet-fast-unstake/runtime-benchmarks", + "pallet-nis/runtime-benchmarks", + "pallet-grandpa/runtime-benchmarks", + "pallet-identity/runtime-benchmarks", + "pallet-im-online/runtime-benchmarks", + "pallet-indices/runtime-benchmarks", + "pallet-membership/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "pallet-multisig/runtime-benchmarks", + "pallet-nomination-pools/runtime-benchmarks", + "pallet-nomination-pools-benchmarking/runtime-benchmarks", + "pallet-preimage/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", + "pallet-ranked-collective/runtime-benchmarks", + "pallet-referenda/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", + "pallet-society/runtime-benchmarks", + "pallet-recovery/runtime-benchmarks", + "pallet-staking/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-tips/runtime-benchmarks", + "pallet-treasury/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", + "pallet-vesting/runtime-benchmarks", + "pallet-offences-benchmarking/runtime-benchmarks", + "pallet-session-benchmarking/runtime-benchmarks", + "pallet-whitelist/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "frame-system-benchmarking/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + "frame-election-provider-support/runtime-benchmarks", + "pallet-bags-list/runtime-benchmarks", + "runtime-parachains/runtime-benchmarks", + "pallet-xcm-benchmarks/runtime-benchmarks", +] +try-runtime = [ + "frame-executive/try-runtime", + "frame-try-runtime", + "frame-system/try-runtime", + "pallet-authority-discovery/try-runtime", + "pallet-authorship/try-runtime", + "pallet-bags-list/try-runtime", + "pallet-balances/try-runtime", + "pallet-beefy/try-runtime", + "pallet-beefy-mmr/try-runtime", + "pallet-bounties/try-runtime", + "pallet-child-bounties/try-runtime", + "pallet-transaction-payment/try-runtime", + "pallet-collective/try-runtime", + "pallet-conviction-voting/try-runtime", + "pallet-elections-phragmen/try-runtime", + "pallet-election-provider-multi-phase/try-runtime", + "pallet-fast-unstake/try-runtime", + "pallet-democracy/try-runtime", + "pallet-nis/try-runtime", + "pallet-grandpa/try-runtime", + "pallet-identity/try-runtime", + "pallet-im-online/try-runtime", + "pallet-indices/try-runtime", + "pallet-membership/try-runtime", + "pallet-message-queue/try-runtime", + "pallet-mmr/try-runtime", + "pallet-multisig/try-runtime", + "pallet-nomination-pools/try-runtime", + "pallet-offences/try-runtime", + "pallet-preimage/try-runtime", + "pallet-proxy/try-runtime", + "pallet-ranked-collective/try-runtime", + "pallet-recovery/try-runtime", + "pallet-referenda/try-runtime", + "pallet-scheduler/try-runtime", + "pallet-session/try-runtime", + "pallet-society/try-runtime", + "pallet-staking/try-runtime", + "pallet-state-trie-migration/try-runtime", + "pallet-timestamp/try-runtime", + "pallet-tips/try-runtime", + "pallet-treasury/try-runtime", + "pallet-utility/try-runtime", + "pallet-vesting/try-runtime", + "pallet-whitelist/try-runtime", + "pallet-babe/try-runtime", + "pallet-xcm/try-runtime", + "runtime-common/try-runtime", +] +# When enabled, the runtime API will not be build. +# +# This is required by Cumulus to access certain types of the +# runtime without clashing with the runtime API exported functions +# in WASM. +disable-runtime-api = [] + +# A feature that should be enabled when the runtime should be build for on-chain +# deployment. This will disable stuff that shouldn't be part of the on-chain wasm +# to make it smaller like logging for example. +on-chain-release-build = [ + "sp-api/disable-logging", +] + +# Set timing constants (e.g. session period) to faster versions to speed up testing. +fast-runtime = [] + +runtime-metrics = ["runtime-parachains/runtime-metrics", "sp-io/with-tracing"] diff --git a/polkadot/runtime/kusama/build.rs b/polkadot/runtime/kusama/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..404ba3f2fdbdfdc68d35d0dd08958448f30d90c6 --- /dev/null +++ b/polkadot/runtime/kusama/build.rs @@ -0,0 +1,25 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .import_memory() + .export_heap_base() + .build() +} diff --git a/polkadot/runtime/kusama/constants/Cargo.toml b/polkadot/runtime/kusama/constants/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..293c91bbd5434ae3e8bd8dcd83cf6b066450f9d1 --- /dev/null +++ b/polkadot/runtime/kusama/constants/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "kusama-runtime-constants" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +smallvec = "1.8.0" + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../../primitives", default-features = false } +runtime-common = { package = "polkadot-runtime-common", path = "../../common", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-weights = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } + +[features] +default = ["std"] +std = [ + "frame-support/std", + "primitives/std", + "runtime-common/std", + "sp-core/std", + "sp-runtime/std", + "sp-weights/std" +] diff --git a/polkadot/runtime/kusama/constants/src/lib.rs b/polkadot/runtime/kusama/constants/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..78f96b35106503f8b2596e773e3af70e6ff4795e --- /dev/null +++ b/polkadot/runtime/kusama/constants/src/lib.rs @@ -0,0 +1,128 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod weights; + +/// Money matters. +pub mod currency { + use primitives::Balance; + + /// The existential deposit. + pub const EXISTENTIAL_DEPOSIT: Balance = 1 * CENTS; + + pub const UNITS: Balance = 1_000_000_000_000; + pub const QUID: Balance = UNITS / 30; + pub const CENTS: Balance = QUID / 100; + pub const GRAND: Balance = QUID * 1_000; + pub const MILLICENTS: Balance = CENTS / 1_000; + + pub const fn deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 2_000 * CENTS + (bytes as Balance) * 100 * MILLICENTS + } +} + +/// Time and blocks. +pub mod time { + use primitives::{BlockNumber, Moment}; + use runtime_common::prod_or_fast; + pub const MILLISECS_PER_BLOCK: Moment = 6000; + pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; + pub const EPOCH_DURATION_IN_SLOTS: BlockNumber = prod_or_fast!(1 * HOURS, 1 * MINUTES); + + // These time units are defined in number of blocks. + pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); + pub const HOURS: BlockNumber = MINUTES * 60; + pub const DAYS: BlockNumber = HOURS * 24; + pub const WEEKS: BlockNumber = DAYS * 7; + + // 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. + // The choice of is done in accordance to the slot duration and expected target + // block time, for safely resisting network delays of maximum two seconds. + // + pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); +} + +/// Fee-related. +pub mod fee { + use crate::weights::ExtrinsicBaseWeight; + use frame_support::weights::{ + WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, + }; + use primitives::Balance; + use smallvec::smallvec; + pub use sp_runtime::Perbill; + + /// The block saturation level. Fees will be updates based on this value. + pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); + + /// 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, `MAXIMUM_BLOCK_WEIGHT`] + /// - [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. + pub struct WeightToFee; + impl WeightToFeePolynomial for WeightToFee { + type Balance = Balance; + fn polynomial() -> WeightToFeeCoefficients { + // in Kusama, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: + let p = super::currency::CENTS; + let q = 10 * Balance::from(ExtrinsicBaseWeight::get().ref_time()); + smallvec![WeightToFeeCoefficient { + degree: 1, + negative: false, + coeff_frac: Perbill::from_rational(p % q, q), + coeff_integer: p / q, + }] + } + } +} + +#[cfg(test)] +mod tests { + use super::{ + currency::{CENTS, MILLICENTS}, + fee::WeightToFee, + }; + use crate::weights::ExtrinsicBaseWeight; + use frame_support::weights::WeightToFee as WeightToFeeT; + use runtime_common::MAXIMUM_BLOCK_WEIGHT; + + #[test] + // Test that the fee for `MAXIMUM_BLOCK_WEIGHT` of weight has sane bounds. + fn full_block_fee_is_correct() { + // A full block should cost between 1,000 and 10,000 CENTS. + let full_block = WeightToFee::weight_to_fee(&MAXIMUM_BLOCK_WEIGHT); + assert!(full_block >= 1_000 * CENTS); + assert!(full_block <= 10_000 * CENTS); + } + + #[test] + // This function tests that the fee for `ExtrinsicBaseWeight` of weight is correct + fn extrinsic_base_fee_is_correct() { + // `ExtrinsicBaseWeight` should cost 1/10 of a CENT + println!("Base: {}", ExtrinsicBaseWeight::get()); + let x = WeightToFee::weight_to_fee(&ExtrinsicBaseWeight::get()); + let y = CENTS / 10; + assert!(x.max(y) - x.min(y) < MILLICENTS); + } +} diff --git a/polkadot/runtime/kusama/constants/src/weights/block_weights.rs b/polkadot/runtime/kusama/constants/src/weights/block_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..8423e1f810c551166572a4d86b1c3bea3ba5af2b --- /dev/null +++ b/polkadot/runtime/kusama/constants/src/weights/block_weights.rs @@ -0,0 +1,81 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19 (Y/M/D) +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! +//! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Development` +//! WARMUPS: `10`, REPEAT: `100` +//! WEIGHT-PATH: `runtime/kusama/constants/src/weights/` +//! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` + +// Executed Command: +// ./target/production/polkadot +// benchmark +// overhead +// --chain=kusama-dev +// --execution=wasm +// --wasm-execution=compiled +// --weight-path=runtime/kusama/constants/src/weights/ +// --warmup=10 +// --repeat=100 +// --header=./file_header.txt + +use sp_core::parameter_types; +use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; + +parameter_types! { + /// Time to execute an empty block. + /// Calculated by multiplying the *Average* with `1.0` and adding `0`. + /// + /// Stats nanoseconds: + /// Min, Max: 14_012_555, 15_267_251 + /// Average: 14_278_073 + /// Median: 14_244_231 + /// Std-Dev: 180701.37 + /// + /// Percentiles nanoseconds: + /// 99th: 14_916_615 + /// 95th: 14_622_262 + /// 75th: 14_317_299 + pub const BlockExecutionWeight: Weight = + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(14_278_073), 0); +} + +#[cfg(test)] +mod test_weights { + use sp_weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::BlockExecutionWeight::get(); + + // At least 100 µs. + assert!( + w.ref_time() >= 100u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 100 µs." + ); + // At most 50 ms. + assert!( + w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 50 ms." + ); + } +} diff --git a/polkadot/runtime/kusama/constants/src/weights/extrinsic_weights.rs b/polkadot/runtime/kusama/constants/src/weights/extrinsic_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..6a2fb7dd206e11de7c79cb7905c2e9a459cabf13 --- /dev/null +++ b/polkadot/runtime/kusama/constants/src/weights/extrinsic_weights.rs @@ -0,0 +1,81 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19 (Y/M/D) +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! +//! SHORT-NAME: `extrinsic`, LONG-NAME: `ExtrinsicBase`, RUNTIME: `Development` +//! WARMUPS: `10`, REPEAT: `100` +//! WEIGHT-PATH: `runtime/kusama/constants/src/weights/` +//! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` + +// Executed Command: +// ./target/production/polkadot +// benchmark +// overhead +// --chain=kusama-dev +// --execution=wasm +// --wasm-execution=compiled +// --weight-path=runtime/kusama/constants/src/weights/ +// --warmup=10 +// --repeat=100 +// --header=./file_header.txt + +use sp_core::parameter_types; +use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; + +parameter_types! { + /// Time to execute a NO-OP extrinsic, for example `System::remark`. + /// Calculated by multiplying the *Average* with `1.0` and adding `0`. + /// + /// Stats nanoseconds: + /// Min, Max: 123_598, 126_451 + /// Average: 124_706 + /// Median: 124_675 + /// Std-Dev: 548.81 + /// + /// Percentiles nanoseconds: + /// 99th: 126_070 + /// 95th: 125_605 + /// 75th: 125_041 + pub const ExtrinsicBaseWeight: Weight = + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(124_706), 0); +} + +#[cfg(test)] +mod test_weights { + use sp_weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::ExtrinsicBaseWeight::get(); + + // At least 10 µs. + assert!( + w.ref_time() >= 10u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 10 µs." + ); + // At most 1 ms. + assert!( + w.ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 1 ms." + ); + } +} diff --git a/polkadot/runtime/kusama/constants/src/weights/mod.rs b/polkadot/runtime/kusama/constants/src/weights/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..23812ce7ed0528c394f84042fb9842eb617a834b --- /dev/null +++ b/polkadot/runtime/kusama/constants/src/weights/mod.rs @@ -0,0 +1,28 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Expose the auto generated weight files. + +pub mod block_weights; +pub mod extrinsic_weights; +pub mod paritydb_weights; +pub mod rocksdb_weights; + +pub use block_weights::BlockExecutionWeight; +pub use extrinsic_weights::ExtrinsicBaseWeight; +pub use paritydb_weights::constants::ParityDbWeight; +pub use rocksdb_weights::constants::RocksDbWeight; diff --git a/polkadot/runtime/kusama/constants/src/weights/paritydb_weights.rs b/polkadot/runtime/kusama/constants/src/weights/paritydb_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..25679703831a13b8d1bb7fb7dd4d92fa84b1f255 --- /dev/null +++ b/polkadot/runtime/kusama/constants/src/weights/paritydb_weights.rs @@ -0,0 +1,63 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// `ParityDB` can be enabled with a feature flag, but is still experimental. These weights + /// are available for brave runtime engineers who may want to try this out as default. + pub const ParityDbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 8_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + write: 50_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use super::constants::ParityDbWeight as W; + use frame_support::weights::constants; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/polkadot/runtime/kusama/constants/src/weights/rocksdb_weights.rs b/polkadot/runtime/kusama/constants/src/weights/rocksdb_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..3dd817aa6f137085b0e5fdf2b11b7f50e5c8b002 --- /dev/null +++ b/polkadot/runtime/kusama/constants/src/weights/rocksdb_weights.rs @@ -0,0 +1,63 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// By default, Substrate uses `RocksDB`, so this will be the weight used throughout + /// the runtime. + pub const RocksDbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 25_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + write: 100_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use super::constants::RocksDbWeight as W; + use frame_support::weights::constants; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/polkadot/runtime/kusama/src/bag_thresholds.rs b/polkadot/runtime/kusama/src/bag_thresholds.rs new file mode 100644 index 0000000000000000000000000000000000000000..82dc4c3a8119e8e38bdacd767d26f8dd5c4d0a7c --- /dev/null +++ b/polkadot/runtime/kusama/src/bag_thresholds.rs @@ -0,0 +1,234 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated voter bag thresholds. +//! +//! Generated on 2021-07-05T14:34:44.453491278+00:00 +//! for the kusama runtime. + +/// Existential weight for this runtime. +#[cfg(any(test, feature = "std"))] +#[allow(unused)] +pub const EXISTENTIAL_WEIGHT: u64 = 33_333_333; + +/// Constant ratio between bags for this runtime. +#[cfg(any(test, feature = "std"))] +#[allow(unused)] +pub const CONSTANT_RATIO: f64 = 1.1455399939091000; + +/// Upper thresholds delimiting the bag list. +pub const THRESHOLDS: [u64; 200] = [ + 33_333_333, + 38_184_666, + 43_742_062, + 50_108_281, + 57_401_040, + 65_755_187, + 75_325_197, + 86_288_026, + 98_846_385, + 113_232_487, + 129_712_342, + 148_590_675, + 170_216_561, + 194_989_878, + 223_368_704, + 255_877_784, + 293_118_235, + 335_778_661, + 384_647_885, + 440_629_536, + 504_758_756, + 578_221_342, + 662_375_673, + 758_777_824, + 869_210_344, + 995_715_212, + 1_140_631_598, + 1_306_639_114, + 1_496_807_363, + 1_714_652_697, + 1_964_203_240, + 2_250_073_368, + 2_577_549_032, + 2_952_685_502, + 3_382_419_332, + 3_874_696_621, + 4_438_619_944, + 5_084_616_664, + 5_824_631_742, + 6_672_348_610, + 7_643_442_186, + 8_755_868_715, + 10_030_197_794, + 11_489_992_720, + 13_162_246_190, + 15_077_879_420, + 17_272_313_899, + 19_786_126_359, + 22_665_799_069, + 25_964_579_327, + 29_743_464_044, + 34_072_327_620, + 39_031_213_974, + 44_711_816_618, + 51_219_174_136, + 58_673_612_428, + 67_212_969_623, + 76_995_144_813, + 88_201_017_720, + 101_037_793_302, + 115_742_833_124, + 132_588_044_352, + 151_884_907_519, + 173_990_236_034, + 199_312_773_927, + 228_320_753_830, + 261_550_554_952, + 299_616_621_127, + 343_222_822_341, + 393_175_469_814, + 450_398_225_296, + 515_949_180_262, + 591_040_420_815, + 677_060_440_060, + 775_599_812_382, + 888_480_604_352, + 1_017_790_066_098, + 1_165_919_226_119, + 1_335_607_103_187, + 1_529_991_352_850, + 1_752_666_285_025, + 2_007_749_325_472, + 2_299_957_150_072, + 2_634_692_899_685, + 3_018_146_088_258, + 3_457_407_051_560, + 3_960_598_052_785, + 4_537_023_469_264, + 5_197_341_837_346, + 5_953_762_936_697, + 6_820_273_558_240, + 7_812_896_130_365, + 8_949_984_985_591, + 10_252_565_745_880, + 11_744_724_102_088, + 13_454_051_176_370, + 15_412_153_702_632, + 17_655_238_458_639, + 20_224_781_756_373, + 23_168_296_370_008, + 26_540_210_082_583, + 30_402_872_096_348, + 34_827_705_916_070, + 39_896_530_022_963, + 45_703_070_759_499, + 52_354_695_399_464, + 59_974_397_449_015, + 68_703_070_888_447, + 78_702_115_407_088, + 90_156_420_804_069, + 103_277_785_738_759, + 118_308_834_046_123, + 135_527_501_032_588, + 155_252_172_707_386, + 177_847_572_977_594, + 203_731_507_665_501, + 233_382_590_050_230, + 267_349_090_784_630, + 306_259_075_829_029, + 350_832_019_859_793, + 401_892_109_893_305, + 460_383_485_119_292, + 527_387_694_739_404, + 604_143_696_619_511, + 692_070_766_545_736, + 792_794_741_693_469, + 908_178_083_570_703, + 1_040_354_316_321_961, + 1_191_767_477_182_765, + 1_365_217_308_553_008, + 1_563_911_027_324_411, + 1_791_522_628_715_580, + 2_052_260_821_186_860, + 2_350_946_848_602_280, + 2_693_103_638_628_474, + 3_085_057_925_791_037, + 3_534_057_237_519_885, + 4_048_403_906_342_940, + 4_637_608_586_213_668, + 5_312_566_111_603_995, + 6_085_756_951_128_531, + 6_971_477_980_728_040, + 7_986_106_843_580_624, + 9_148_404_784_952_770, + 10_479_863_561_632_778, + 12_005_102_840_561_012, + 13_752_325_434_854_380, + 15_753_838_794_879_048, + 18_046_652_397_130_688, + 20_673_162_077_088_732, + 23_681_933_959_870_064, + 27_128_602_484_145_260, + 31_076_899_124_450_156, + 35_599_830_833_736_348, + 40_781_029_996_443_328, + 46_716_300_853_732_512, + 53_515_390_995_440_424, + 61_304_020_674_959_928, + 70_226_207_470_596_936, + 80_446_929_278_126_800, + 92_155_174_875_271_168, + 105_567_438_465_310_176, + 120_931_722_816_550_704, + 138_532_125_018_688_464, + 158_694_089_650_123_072, + 181_790_426_491_212_160, + 208_248_204_055_475_872, + 238_556_646_405_290_848, + 273_276_179_270_092_192, + 313_048_792_736_563_520, + 358_609_912_124_694_080, + 410_801_996_551_064_960, + 470_590_116_626_953_088, + 539_079_799_334_522_496, + 617_537_470_046_187_776, + 707_413_869_675_350_912, + 810_370_879_959_114_368, + 928_312_252_892_475_904, + 1_063_418_812_524_189_696, + 1_218_188_780_021_782_528, + 1_395_483_967_646_286_592, + 1_598_582_695_797_773_824, + 1_831_240_411_607_374_592, + 2_097_759_129_958_809_600, + 2_403_066_980_955_773_440, + 2_752_809_334_727_236_096, + 3_153_453_188_536_351_744, + 3_612_406_746_388_564_480, + 4_138_156_402_255_148_032, + 4_740_423_659_834_265_600, + 5_430_344_890_413_097_984, + 6_220_677_252_688_132_096, + 7_126_034_582_154_840_064, + 8_163_157_611_837_691_904, + 9_351_223_520_943_572_992, + 10_712_200_535_224_332_288, + 12_271_254_135_873_939_456, + 14_057_212_388_066_050_048, + 16_103_098_993_404_108_800, + 18_446_744_073_709_551_615, +]; diff --git a/polkadot/runtime/kusama/src/governance/fellowship.rs b/polkadot/runtime/kusama/src/governance/fellowship.rs new file mode 100644 index 0000000000000000000000000000000000000000..8837c19e0eb1461b3c287037ef69e776d46ac832 --- /dev/null +++ b/polkadot/runtime/kusama/src/governance/fellowship.rs @@ -0,0 +1,358 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Elements of governance concerning the Polkadot Fellowship. This is only a temporary arrangement +//! since the Polkadot Fellowship belongs under the Polkadot Relay. However, that is not yet in +//! place, so until then it will need to live here. Once it is in place and there exists a bridge +//! between Polkadot/Kusama then this code can be removed. + +use frame_support::traits::{MapSuccess, TryMapSuccess}; +use sp_arithmetic::traits::CheckedSub; +use sp_runtime::{ + morph_types, + traits::{ConstU16, Replace, TypedGet}, +}; + +use super::*; +use crate::{DAYS, QUID}; + +parameter_types! { + pub const AlarmInterval: BlockNumber = 1; + pub const SubmissionDeposit: Balance = 0; + pub const UndecidingTimeout: BlockNumber = 7 * DAYS; +} + +pub struct TracksInfo; +impl pallet_referenda::TracksInfo for TracksInfo { + type Id = u16; + type RuntimeOrigin = ::PalletsOrigin; + fn tracks() -> &'static [(Self::Id, pallet_referenda::TrackInfo)] { + static DATA: [(u16, pallet_referenda::TrackInfo); 10] = [ + ( + 0u16, + pallet_referenda::TrackInfo { + name: "candidates", + max_deciding: 10, + decision_deposit: 100 * QUID, + prepare_period: 30 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 30 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + }, + ), + ( + 1u16, + pallet_referenda::TrackInfo { + name: "members", + max_deciding: 10, + decision_deposit: 10 * QUID, + prepare_period: 30 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 30 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + }, + ), + ( + 2u16, + pallet_referenda::TrackInfo { + name: "proficients", + max_deciding: 10, + decision_deposit: 10 * QUID, + prepare_period: 30 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 30 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + }, + ), + ( + 3u16, + pallet_referenda::TrackInfo { + name: "fellows", + max_deciding: 10, + decision_deposit: 10 * QUID, + prepare_period: 30 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 30 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + }, + ), + ( + 4u16, + pallet_referenda::TrackInfo { + name: "senior fellows", + max_deciding: 10, + decision_deposit: 10 * QUID, + prepare_period: 30 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 30 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + }, + ), + ( + 5u16, + pallet_referenda::TrackInfo { + name: "experts", + max_deciding: 10, + decision_deposit: 1 * QUID, + prepare_period: 30 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 30 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + }, + ), + ( + 6u16, + pallet_referenda::TrackInfo { + name: "senior experts", + max_deciding: 10, + decision_deposit: 1 * QUID, + prepare_period: 30 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 30 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + }, + ), + ( + 7u16, + pallet_referenda::TrackInfo { + name: "masters", + max_deciding: 10, + decision_deposit: 1 * QUID, + prepare_period: 30 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 30 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + }, + ), + ( + 8u16, + pallet_referenda::TrackInfo { + name: "senior masters", + max_deciding: 10, + decision_deposit: 1 * QUID, + prepare_period: 30 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 30 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + }, + ), + ( + 9u16, + pallet_referenda::TrackInfo { + name: "grand masters", + max_deciding: 10, + decision_deposit: 1 * QUID, + prepare_period: 30 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 30 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + }, + ), + ]; + &DATA[..] + } + fn track_for(id: &Self::RuntimeOrigin) -> Result { + use super::origins::Origin; + + #[cfg(feature = "runtime-benchmarks")] + { + // For benchmarks, we enable a root origin. + // It is important that this is not available in production! + let root: Self::RuntimeOrigin = frame_system::RawOrigin::Root.into(); + if &root == id { + return Ok(9) + } + } + + match Origin::try_from(id.clone()) { + Ok(Origin::FellowshipInitiates) => Ok(0), + Ok(Origin::Fellowship1Dan) => Ok(1), + Ok(Origin::Fellowship2Dan) => Ok(2), + Ok(Origin::Fellowship3Dan) | Ok(Origin::Fellows) => Ok(3), + Ok(Origin::Fellowship4Dan) => Ok(4), + Ok(Origin::Fellowship5Dan) | Ok(Origin::FellowshipExperts) => Ok(5), + Ok(Origin::Fellowship6Dan) => Ok(6), + Ok(Origin::Fellowship7Dan | Origin::FellowshipMasters) => Ok(7), + Ok(Origin::Fellowship8Dan) => Ok(8), + Ok(Origin::Fellowship9Dan) => Ok(9), + _ => Err(()), + } + } +} +pallet_referenda::impl_tracksinfo_get!(TracksInfo, Balance, BlockNumber); + +pub type FellowshipReferendaInstance = pallet_referenda::Instance2; + +impl pallet_referenda::Config for Runtime { + type WeightInfo = weights::pallet_referenda_fellowship_referenda::WeightInfo; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type Scheduler = Scheduler; + type Currency = Balances; + type SubmitOrigin = + pallet_ranked_collective::EnsureMember; + type CancelOrigin = FellowshipExperts; + type KillOrigin = FellowshipMasters; + type Slash = Treasury; + type Votes = pallet_ranked_collective::Votes; + type Tally = pallet_ranked_collective::TallyOf; + type SubmissionDeposit = SubmissionDeposit; + type MaxQueued = ConstU32<100>; + type UndecidingTimeout = UndecidingTimeout; + type AlarmInterval = AlarmInterval; + type Tracks = TracksInfo; + type Preimages = Preimage; +} + +pub type FellowshipCollectiveInstance = pallet_ranked_collective::Instance1; + +morph_types! { + /// A `TryMorph` implementation to reduce a scalar by a particular amount, checking for + /// underflow. + pub type CheckedReduceBy: TryMorph = |r: N::Type| -> Result { + r.checked_sub(&N::get()).ok_or(()) + } where N::Type: CheckedSub; +} + +impl pallet_ranked_collective::Config for Runtime { + type WeightInfo = weights::pallet_ranked_collective::WeightInfo; + type RuntimeEvent = RuntimeEvent; + // Promotion is by any of: + // - Root can demote arbitrarily. + // - the FellowshipAdmin origin (i.e. token holder referendum); + // - a vote by the rank *above* the new rank. + type PromoteOrigin = EitherOf< + frame_system::EnsureRootWithSuccess>, + EitherOf< + MapSuccess>>, + TryMapSuccess>>, + >, + >; + // Demotion is by any of: + // - Root can demote arbitrarily. + // - the FellowshipAdmin origin (i.e. token holder referendum); + // - a vote by the rank two above the current rank. + type DemoteOrigin = EitherOf< + frame_system::EnsureRootWithSuccess>, + EitherOf< + MapSuccess>>, + TryMapSuccess>>, + >, + >; + type Polls = FellowshipReferenda; + type MinRankOfClass = sp_runtime::traits::Identity; + type VoteWeight = pallet_ranked_collective::Geometric; +} diff --git a/polkadot/runtime/kusama/src/governance/mod.rs b/polkadot/runtime/kusama/src/governance/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..c8a7b360ed4e9685e838864f739d32bb54938cb0 --- /dev/null +++ b/polkadot/runtime/kusama/src/governance/mod.rs @@ -0,0 +1,93 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! New governance configurations for the Kusama runtime. + +use super::*; +use frame_support::{ + parameter_types, + traits::{ConstU16, EitherOf}, +}; +use frame_system::EnsureRootWithSuccess; + +mod origins; +pub use origins::{ + pallet_custom_origins, AuctionAdmin, Fellows, FellowshipAdmin, FellowshipExperts, + FellowshipInitiates, FellowshipMasters, GeneralAdmin, LeaseAdmin, ReferendumCanceller, + ReferendumKiller, Spender, StakingAdmin, Treasurer, WhitelistedCaller, +}; +mod tracks; +pub use tracks::TracksInfo; +mod fellowship; +pub use fellowship::{FellowshipCollectiveInstance, FellowshipReferendaInstance}; + +parameter_types! { + pub const VoteLockingPeriod: BlockNumber = 7 * DAYS; +} + +impl pallet_conviction_voting::Config for Runtime { + type WeightInfo = weights::pallet_conviction_voting::WeightInfo; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type VoteLockingPeriod = VoteLockingPeriod; + type MaxVotes = ConstU32<512>; + type MaxTurnout = + frame_support::traits::tokens::currency::ActiveIssuanceOf; + type Polls = Referenda; +} + +parameter_types! { + pub const AlarmInterval: BlockNumber = 1; + pub const SubmissionDeposit: Balance = 1 * QUID; + pub const UndecidingTimeout: BlockNumber = 14 * DAYS; +} + +parameter_types! { + pub const MaxBalance: Balance = Balance::max_value(); +} +pub type TreasurySpender = EitherOf, Spender>; + +impl origins::pallet_custom_origins::Config for Runtime {} + +impl pallet_whitelist::Config for Runtime { + type WeightInfo = weights::pallet_whitelist::WeightInfo; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WhitelistOrigin = + EitherOf>, Fellows>; + type DispatchWhitelistedOrigin = EitherOf, WhitelistedCaller>; + type Preimages = Preimage; +} + +impl pallet_referenda::Config for Runtime { + type WeightInfo = weights::pallet_referenda_referenda::WeightInfo; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type Scheduler = Scheduler; + type Currency = Balances; + type SubmitOrigin = frame_system::EnsureSigned; + type CancelOrigin = EitherOf, ReferendumCanceller>; + type KillOrigin = EitherOf, ReferendumKiller>; + type Slash = Treasury; + type Votes = pallet_conviction_voting::VotesOf; + type Tally = pallet_conviction_voting::TallyOf; + type SubmissionDeposit = SubmissionDeposit; + type MaxQueued = ConstU32<100>; + type UndecidingTimeout = UndecidingTimeout; + type AlarmInterval = AlarmInterval; + type Tracks = TracksInfo; + type Preimages = Preimage; +} diff --git a/polkadot/runtime/kusama/src/governance/origins.rs b/polkadot/runtime/kusama/src/governance/origins.rs new file mode 100644 index 0000000000000000000000000000000000000000..c5cb035a526947a973eabd8b4bca32c6b280b10d --- /dev/null +++ b/polkadot/runtime/kusama/src/governance/origins.rs @@ -0,0 +1,194 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Custom origins for governance interventions. + +pub use pallet_custom_origins::*; + +#[frame_support::pallet] +pub mod pallet_custom_origins { + use crate::{Balance, GRAND, QUID}; + use frame_support::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + #[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)] + #[pallet::origin] + pub enum Origin { + /// Origin for cancelling slashes. + StakingAdmin, + /// Origin for spending (any amount of) funds. + Treasurer, + /// Origin for managing the composition of the fellowship. + FellowshipAdmin, + /// Origin for managing the registrar and permissioned HRMP channel operations. + GeneralAdmin, + /// Origin for starting auctions. + AuctionAdmin, + /// Origin able to force slot leases. + LeaseAdmin, + /// Origin able to cancel referenda. + ReferendumCanceller, + /// Origin able to kill referenda. + ReferendumKiller, + /// Origin able to spend up to 1 KSM from the treasury at once. + SmallTipper, + /// Origin able to spend up to 5 KSM from the treasury at once. + BigTipper, + /// Origin able to spend up to 50 KSM from the treasury at once. + SmallSpender, + /// Origin able to spend up to 500 KSM from the treasury at once. + MediumSpender, + /// Origin able to spend up to 5,000 KSM from the treasury at once. + BigSpender, + /// Origin able to dispatch a whitelisted call. + WhitelistedCaller, + /// Origin commanded by any members of the Polkadot Fellowship (no Dan grade needed). + FellowshipInitiates, + /// Origin commanded by Polkadot Fellows (3rd Dan fellows or greater). + Fellows, + /// Origin commanded by Polkadot Experts (5th Dan fellows or greater). + FellowshipExperts, + /// Origin commanded by Polkadot Masters (7th Dan fellows of greater). + FellowshipMasters, + /// Origin commanded by rank 1 of the Polkadot Fellowship and with a success of 1. + Fellowship1Dan, + /// Origin commanded by rank 2 of the Polkadot Fellowship and with a success of 2. + Fellowship2Dan, + /// Origin commanded by rank 3 of the Polkadot Fellowship and with a success of 3. + Fellowship3Dan, + /// Origin commanded by rank 4 of the Polkadot Fellowship and with a success of 4. + Fellowship4Dan, + /// Origin commanded by rank 5 of the Polkadot Fellowship and with a success of 5. + Fellowship5Dan, + /// Origin commanded by rank 6 of the Polkadot Fellowship and with a success of 6. + Fellowship6Dan, + /// Origin commanded by rank 7 of the Polkadot Fellowship and with a success of 7. + Fellowship7Dan, + /// Origin commanded by rank 8 of the Polkadot Fellowship and with a success of 8. + Fellowship8Dan, + /// Origin commanded by rank 9 of the Polkadot Fellowship and with a success of 9. + Fellowship9Dan, + } + + macro_rules! decl_unit_ensures { + ( $name:ident: $success_type:ty = $success:expr ) => { + pub struct $name; + impl> + From> + EnsureOrigin for $name + { + type Success = $success_type; + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + Origin::$name => Ok($success), + r => Err(O::from(r)), + }) + } + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + Ok(O::from(Origin::$name)) + } + } + }; + ( $name:ident ) => { decl_unit_ensures! { $name : () = () } }; + ( $name:ident: $success_type:ty = $success:expr, $( $rest:tt )* ) => { + decl_unit_ensures! { $name: $success_type = $success } + decl_unit_ensures! { $( $rest )* } + }; + ( $name:ident, $( $rest:tt )* ) => { + decl_unit_ensures! { $name } + decl_unit_ensures! { $( $rest )* } + }; + () => {} + } + decl_unit_ensures!( + StakingAdmin, + Treasurer, + FellowshipAdmin, + GeneralAdmin, + AuctionAdmin, + LeaseAdmin, + ReferendumCanceller, + ReferendumKiller, + WhitelistedCaller, + FellowshipInitiates: u16 = 0, + Fellows: u16 = 3, + FellowshipExperts: u16 = 5, + FellowshipMasters: u16 = 7, + ); + + macro_rules! decl_ensure { + ( + $vis:vis type $name:ident: EnsureOrigin { + $( $item:ident = $success:expr, )* + } + ) => { + $vis struct $name; + impl> + From> + EnsureOrigin for $name + { + type Success = $success_type; + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + $( + Origin::$item => Ok($success), + )* + r => Err(O::from(r)), + }) + } + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + // By convention the more privileged origins go later, so for greatest chance + // of success, we want the last one. + let _result: Result = Err(()); + $( + let _result: Result = Ok(O::from(Origin::$item)); + )* + _result + } + } + } + } + + decl_ensure! { + pub type Spender: EnsureOrigin { + SmallTipper = 250 * QUID, + BigTipper = 1 * GRAND, + SmallSpender = 10 * GRAND, + MediumSpender = 100 * GRAND, + BigSpender = 1_000 * GRAND, + Treasurer = 10_000 * GRAND, + } + } + + decl_ensure! { + pub type EnsureFellowship: EnsureOrigin { + Fellowship1Dan = 1, + Fellowship2Dan = 2, + Fellowship3Dan = 3, + Fellowship4Dan = 4, + Fellowship5Dan = 5, + Fellowship6Dan = 6, + Fellowship7Dan = 7, + Fellowship8Dan = 8, + Fellowship9Dan = 9, + } + } +} diff --git a/polkadot/runtime/kusama/src/governance/tracks.rs b/polkadot/runtime/kusama/src/governance/tracks.rs new file mode 100644 index 0000000000000000000000000000000000000000..08a87a677c353694f68df0ff96b9e6ba111ee058 --- /dev/null +++ b/polkadot/runtime/kusama/src/governance/tracks.rs @@ -0,0 +1,320 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Track configurations for governance. + +use super::*; + +const fn percent(x: i32) -> sp_arithmetic::FixedI64 { + sp_arithmetic::FixedI64::from_rational(x as u128, 100) +} +use pallet_referenda::Curve; +const APP_ROOT: Curve = Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_ROOT: Curve = Curve::make_linear(28, 28, percent(0), percent(50)); +const APP_STAKING_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_STAKING_ADMIN: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_TREASURER: Curve = Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_TREASURER: Curve = Curve::make_linear(28, 28, percent(0), percent(50)); +const APP_FELLOWSHIP_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_FELLOWSHIP_ADMIN: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_GENERAL_ADMIN: Curve = + Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_GENERAL_ADMIN: Curve = + Curve::make_reciprocal(7, 28, percent(10), percent(0), percent(50)); +const APP_AUCTION_ADMIN: Curve = + Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_AUCTION_ADMIN: Curve = + Curve::make_reciprocal(7, 28, percent(10), percent(0), percent(50)); +const APP_LEASE_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_LEASE_ADMIN: Curve = Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_REFERENDUM_CANCELLER: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_REFERENDUM_CANCELLER: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_REFERENDUM_KILLER: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_REFERENDUM_KILLER: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_SMALL_TIPPER: Curve = Curve::make_linear(10, 28, percent(50), percent(100)); +const SUP_SMALL_TIPPER: Curve = Curve::make_reciprocal(1, 28, percent(4), percent(0), percent(50)); +const APP_BIG_TIPPER: Curve = Curve::make_linear(10, 28, percent(50), percent(100)); +const SUP_BIG_TIPPER: Curve = Curve::make_reciprocal(8, 28, percent(1), percent(0), percent(50)); +const APP_SMALL_SPENDER: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_SMALL_SPENDER: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_MEDIUM_SPENDER: Curve = Curve::make_linear(23, 28, percent(50), percent(100)); +const SUP_MEDIUM_SPENDER: Curve = + Curve::make_reciprocal(16, 28, percent(1), percent(0), percent(50)); +const APP_BIG_SPENDER: Curve = Curve::make_linear(28, 28, percent(50), percent(100)); +const SUP_BIG_SPENDER: Curve = Curve::make_reciprocal(20, 28, percent(1), percent(0), percent(50)); +const APP_WHITELISTED_CALLER: Curve = + Curve::make_reciprocal(16, 28 * 24, percent(96), percent(50), percent(100)); +const SUP_WHITELISTED_CALLER: Curve = + Curve::make_reciprocal(1, 28, percent(20), percent(5), percent(50)); + +const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 15] = [ + ( + 0, + pallet_referenda::TrackInfo { + name: "root", + max_deciding: 1, + decision_deposit: 100 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 24 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_ROOT, + min_support: SUP_ROOT, + }, + ), + ( + 1, + pallet_referenda::TrackInfo { + name: "whitelisted_caller", + max_deciding: 100, + decision_deposit: 10 * GRAND, + prepare_period: 30 * MINUTES, + decision_period: 14 * DAYS, + confirm_period: 10 * MINUTES, + min_enactment_period: 10 * MINUTES, + min_approval: APP_WHITELISTED_CALLER, + min_support: SUP_WHITELISTED_CALLER, + }, + ), + ( + 10, + pallet_referenda::TrackInfo { + name: "staking_admin", + max_deciding: 10, + decision_deposit: 5 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_STAKING_ADMIN, + min_support: SUP_STAKING_ADMIN, + }, + ), + ( + 11, + pallet_referenda::TrackInfo { + name: "treasurer", + max_deciding: 10, + decision_deposit: 1 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_TREASURER, + min_support: SUP_TREASURER, + }, + ), + ( + 12, + pallet_referenda::TrackInfo { + name: "lease_admin", + max_deciding: 10, + decision_deposit: 5 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_LEASE_ADMIN, + min_support: SUP_LEASE_ADMIN, + }, + ), + ( + 13, + pallet_referenda::TrackInfo { + name: "fellowship_admin", + max_deciding: 10, + decision_deposit: 5 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_FELLOWSHIP_ADMIN, + min_support: SUP_FELLOWSHIP_ADMIN, + }, + ), + ( + 14, + pallet_referenda::TrackInfo { + name: "general_admin", + max_deciding: 10, + decision_deposit: 5 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_GENERAL_ADMIN, + min_support: SUP_GENERAL_ADMIN, + }, + ), + ( + 15, + pallet_referenda::TrackInfo { + name: "auction_admin", + max_deciding: 10, + decision_deposit: 5 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_AUCTION_ADMIN, + min_support: SUP_AUCTION_ADMIN, + }, + ), + ( + 20, + pallet_referenda::TrackInfo { + name: "referendum_canceller", + max_deciding: 1_000, + decision_deposit: 10 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 7 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_REFERENDUM_CANCELLER, + min_support: SUP_REFERENDUM_CANCELLER, + }, + ), + ( + 21, + pallet_referenda::TrackInfo { + name: "referendum_killer", + max_deciding: 1_000, + decision_deposit: 50 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_REFERENDUM_KILLER, + min_support: SUP_REFERENDUM_KILLER, + }, + ), + ( + 30, + pallet_referenda::TrackInfo { + name: "small_tipper", + max_deciding: 200, + decision_deposit: 1 * QUID, + prepare_period: 1 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 10 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: APP_SMALL_TIPPER, + min_support: SUP_SMALL_TIPPER, + }, + ), + ( + 31, + pallet_referenda::TrackInfo { + name: "big_tipper", + max_deciding: 100, + decision_deposit: 10 * QUID, + prepare_period: 10 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 1 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_BIG_TIPPER, + min_support: SUP_BIG_TIPPER, + }, + ), + ( + 32, + pallet_referenda::TrackInfo { + name: "small_spender", + max_deciding: 50, + decision_deposit: 100 * QUID, + prepare_period: 4 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 12 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_SMALL_SPENDER, + min_support: SUP_SMALL_SPENDER, + }, + ), + ( + 33, + pallet_referenda::TrackInfo { + name: "medium_spender", + max_deciding: 50, + decision_deposit: 200 * QUID, + prepare_period: 4 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 24 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_MEDIUM_SPENDER, + min_support: SUP_MEDIUM_SPENDER, + }, + ), + ( + 34, + pallet_referenda::TrackInfo { + name: "big_spender", + max_deciding: 50, + decision_deposit: 400 * QUID, + prepare_period: 4 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 48 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_BIG_SPENDER, + min_support: SUP_BIG_SPENDER, + }, + ), +]; + +pub struct TracksInfo; +impl pallet_referenda::TracksInfo for TracksInfo { + type Id = u16; + type RuntimeOrigin = ::PalletsOrigin; + fn tracks() -> &'static [(Self::Id, pallet_referenda::TrackInfo)] { + &TRACKS_DATA[..] + } + fn track_for(id: &Self::RuntimeOrigin) -> Result { + if let Ok(system_origin) = frame_system::RawOrigin::try_from(id.clone()) { + match system_origin { + frame_system::RawOrigin::Root => Ok(0), + _ => Err(()), + } + } else if let Ok(custom_origin) = origins::Origin::try_from(id.clone()) { + match custom_origin { + origins::Origin::WhitelistedCaller => Ok(1), + // General admin + origins::Origin::StakingAdmin => Ok(10), + origins::Origin::Treasurer => Ok(11), + origins::Origin::LeaseAdmin => Ok(12), + origins::Origin::FellowshipAdmin => Ok(13), + origins::Origin::GeneralAdmin => Ok(14), + origins::Origin::AuctionAdmin => Ok(15), + // Referendum admins + origins::Origin::ReferendumCanceller => Ok(20), + origins::Origin::ReferendumKiller => Ok(21), + // Limited treasury spenders + origins::Origin::SmallTipper => Ok(30), + origins::Origin::BigTipper => Ok(31), + origins::Origin::SmallSpender => Ok(32), + origins::Origin::MediumSpender => Ok(33), + origins::Origin::BigSpender => Ok(34), + _ => Err(()), + } + } else { + Err(()) + } + } +} +pallet_referenda::impl_tracksinfo_get!(TracksInfo, Balance, BlockNumber); diff --git a/polkadot/runtime/kusama/src/lib.rs b/polkadot/runtime/kusama/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..e9e3fb2d2026f194ac00da9692ad2b6a9bece2d4 --- /dev/null +++ b/polkadot/runtime/kusama/src/lib.rs @@ -0,0 +1,2715 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Kusama runtime. This can be compiled with `#[no_std]`, ready for Wasm. + +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit. +#![recursion_limit = "512"] + +use pallet_nis::WithMaximumOf; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use primitives::{ + slashing, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, + CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash, + Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce, + OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, SessionInfo, Signature, + ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, LOWEST_PUBLIC_ID, + PARACHAIN_KEY_TYPE_ID, +}; +use runtime_common::{ + auctions, claims, crowdloan, impl_runtime_weights, impls::DealWithFees, paras_registrar, + prod_or_fast, slots, BalanceToU256, BlockHashCount, BlockLength, CurrencyToVote, + SlowAdjustingFeeUpdate, U256ToBalance, +}; +use scale_info::TypeInfo; +use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*}; + +use runtime_parachains::{ + assigner_parachains as parachains_assigner_parachains, + configuration as parachains_configuration, disputes as parachains_disputes, + disputes::slashing as parachains_slashing, + dmp as parachains_dmp, hrmp as parachains_hrmp, inclusion as parachains_inclusion, + inclusion::{AggregateMessageOrigin, UmpQueueId}, + initializer as parachains_initializer, origin as parachains_origin, paras as parachains_paras, + paras_inherent as parachains_paras_inherent, reward_points as parachains_reward_points, + runtime_api_impl::v5 as parachains_runtime_api_impl, + scheduler as parachains_scheduler, session_info as parachains_session_info, + shared as parachains_shared, +}; + +use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; +use beefy_primitives::{ + ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}, + mmr::{BeefyDataProvider, MmrLeafVersion}, +}; +use frame_election_provider_support::{ + bounds::ElectionBoundsBuilder, generate_solution_type, onchain, NposSolution, + SequentialPhragmen, +}; +use frame_support::{ + construct_runtime, parameter_types, + traits::{ + ConstU32, Contains, EitherOf, EitherOfDiverse, InstanceFilter, KeyOwnerProofSystem, + PrivilegeCmp, ProcessMessage, ProcessMessageError, StorageMapShim, WithdrawReasons, + }, + weights::{ConstantMultiplier, WeightMeter}, + PalletId, +}; +use frame_system::EnsureRoot; +use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +use pallet_session::historical as session_historical; +use pallet_transaction_payment::{CurrencyAdapter, FeeDetails, RuntimeDispatchInfo}; +use sp_core::{ConstU128, OpaqueMetadata, H256}; +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, + traits::{ + AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT, + Keccak256, OpaqueKeys, SaturatedConversion, Verify, + }, + transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, FixedU128, KeyTypeId, Perbill, Percent, Permill, RuntimeDebug, +}; +use sp_staking::SessionIndex; +#[cfg(any(feature = "std", test))] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; +use xcm::latest::Junction; + +pub use frame_system::Call as SystemCall; +pub use pallet_balances::Call as BalancesCall; +pub use pallet_election_provider_multi_phase::Call as EPMCall; +#[cfg(feature = "std")] +pub use pallet_staking::StakerStatus; +use pallet_staking::UseValidatorsMap; +use sp_runtime::traits::Get; +#[cfg(any(feature = "std", test))] +pub use sp_runtime::BuildStorage; + +/// Constant values used within the runtime. +use kusama_runtime_constants::{currency::*, fee::*, time::*}; + +// Weights used in the runtime. +mod weights; + +// Voter bag threshold definitions. +mod bag_thresholds; + +// Historical information of society finances. +mod past_payouts; + +// XCM configurations. +pub mod xcm_config; + +// Governance configurations. +pub mod governance; +use governance::{ + pallet_custom_origins, AuctionAdmin, Fellows, GeneralAdmin, LeaseAdmin, StakingAdmin, + Treasurer, TreasurySpender, +}; + +#[cfg(test)] +mod tests; + +impl_runtime_weights!(kusama_runtime_constants); + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +/// Runtime version (Kusama). +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("kusama"), + impl_name: create_runtime_str!("parity-kusama"), + authoring_version: 2, + spec_version: 9430, + impl_version: 0, + #[cfg(not(feature = "disable-runtime-api"))] + apis: RUNTIME_API_VERSIONS, + #[cfg(feature = "disable-runtime-api")] + apis: sp_version::create_apis_vec![[]], + transaction_version: 23, + state_version: 1, +}; + +/// The BABE epoch configuration at genesis. +pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration = + babe_primitives::BabeEpochConfiguration { + c: PRIMARY_PROBABILITY, + allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots, + }; + +/// Native version. +#[cfg(any(feature = "std", test))] +pub fn native_version() -> NativeVersion { + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } +} + +/// We currently allow all calls. +pub struct BaseFilter; +impl Contains for BaseFilter { + fn contains(_c: &RuntimeCall) -> bool { + true + } +} + +parameter_types! { + pub const Version: RuntimeVersion = VERSION; + pub const SS58Prefix: u8 = 2; +} + +impl frame_system::Config for Runtime { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = BlockWeights; + type BlockLength = BlockLength; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = Nonce; + type Hash = Hash; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = AccountIdLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type DbWeight = RocksDbWeight; + type Version = Version; + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = weights::frame_system::WeightInfo; + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; + pub const NoPreimagePostponement: Option = Some(10); +} + +/// Used the compare the privilege of an origin inside the scheduler. +pub struct OriginPrivilegeCmp; + +impl PrivilegeCmp for OriginPrivilegeCmp { + fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option { + if left == right { + return Some(Ordering::Equal) + } + + match (left, right) { + // Root is greater than anything. + (OriginCaller::system(frame_system::RawOrigin::Root), _) => Some(Ordering::Greater), + // For every other origin we don't care, as they are not used for `ScheduleOrigin`. + _ => None, + } + } +} + +impl pallet_scheduler::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaximumSchedulerWeight; + // The goal of having ScheduleOrigin include AuctionAdmin is to allow the auctions track of + // OpenGov to schedule periodic auctions. + type ScheduleOrigin = EitherOf, AuctionAdmin>; + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type WeightInfo = weights::pallet_scheduler::WeightInfo; + type OriginPrivilegeCmp = OriginPrivilegeCmp; + type Preimages = Preimage; +} + +parameter_types! { + pub const PreimageBaseDeposit: Balance = deposit(2, 64); + pub const PreimageByteDeposit: Balance = deposit(0, 1); +} + +impl pallet_preimage::Config for Runtime { + type WeightInfo = weights::pallet_preimage::WeightInfo; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type BaseDeposit = PreimageBaseDeposit; + type ByteDeposit = PreimageByteDeposit; +} + +parameter_types! { + pub EpochDuration: u64 = prod_or_fast!( + EPOCH_DURATION_IN_SLOTS as u64, + 2 * MINUTES as u64, + "KSM_EPOCH_DURATION" + ); + pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; + pub ReportLongevity: u64 = + BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get(); +} + +impl pallet_babe::Config for Runtime { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; + + // session module is the trigger + type EpochChangeTrigger = pallet_babe::ExternalTrigger; + + type DisabledValidators = Session; + + type KeyOwnerProof = + >::Proof; + + type EquivocationReportSystem = + pallet_babe::EquivocationReportSystem; + + type WeightInfo = (); + + type MaxAuthorities = MaxAuthorities; + type MaxNominators = MaxNominatorRewardedPerValidator; +} + +parameter_types! { + pub const IndexDeposit: Balance = 100 * CENTS; +} + +impl pallet_indices::Config for Runtime { + type AccountIndex = AccountIndex; + type Currency = Balances; + type Deposit = IndexDeposit; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_indices::WeightInfo; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = weights::pallet_balances::WeightInfo; + type FreezeIdentifier = (); + type MaxFreezes = (); + type RuntimeHoldReason = RuntimeHoldReason; + type MaxHolds = ConstU32<1>; +} + +parameter_types! { + pub BeefySetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); +} + +impl pallet_beefy::Config for Runtime { + type BeefyId = BeefyId; + type MaxAuthorities = MaxAuthorities; + type MaxNominators = MaxNominatorRewardedPerValidator; + type MaxSetIdSessionEntries = BeefySetIdSessionEntries; + type OnNewValidatorSet = BeefyMmrLeaf; + type WeightInfo = (); + type KeyOwnerProof = >::Proof; + type EquivocationReportSystem = + pallet_beefy::EquivocationReportSystem; +} + +impl pallet_mmr::Config for Runtime { + const INDEXING_PREFIX: &'static [u8] = mmr::INDEXING_PREFIX; + type Hashing = Keccak256; + type OnNewRoot = pallet_beefy_mmr::DepositBeefyDigest; + type WeightInfo = (); + type LeafData = pallet_beefy_mmr::Pallet; +} + +/// MMR helper types. +mod mmr { + use super::Runtime; + pub use pallet_mmr::primitives::*; + + pub type Leaf = <::LeafData as LeafDataProvider>::LeafData; + pub type Hashing = ::Hashing; + pub type Hash = ::Output; +} + +parameter_types! { + /// Version of the produced MMR leaf. + /// + /// The version consists of two parts; + /// - `major` (3 bits) + /// - `minor` (5 bits) + /// + /// `major` should be updated only if decoding the previous MMR Leaf format from the payload + /// is not possible (i.e. backward incompatible change). + /// `minor` should be updated if fields are added to the previous MMR Leaf, which given SCALE + /// encoding does not prevent old leafs from being decoded. + /// + /// Hence we expect `major` to be changed really rarely (think never). + /// See [`MmrLeafVersion`] type documentation for more details. + pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0); +} + +/// A BEEFY data provider that merkelizes all the parachain heads at the current block +/// (sorted by their parachain id). +pub struct ParaHeadsRootProvider; +impl BeefyDataProvider for ParaHeadsRootProvider { + fn extra_data() -> H256 { + let mut para_heads: Vec<(u32, Vec)> = Paras::parachains() + .into_iter() + .filter_map(|id| Paras::para_head(&id).map(|head| (id.into(), head.0))) + .collect(); + para_heads.sort_by_key(|k| k.0); + binary_merkle_tree::merkle_root::( + para_heads.into_iter().map(|pair| pair.encode()), + ) + .into() + } +} + +impl pallet_beefy_mmr::Config for Runtime { + type LeafVersion = LeafVersion; + type BeefyAuthorityToMerkleLeaf = pallet_beefy_mmr::BeefyEcdsaToEthereum; + type LeafExtra = H256; + type BeefyDataProvider = ParaHeadsRootProvider; +} + +parameter_types! { + pub const TransactionByteFee: Balance = 10 * MILLICENTS; + /// This value increases the priority of `Operational` transactions by adding + /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`. + pub const OperationalFeeMultiplier: u8 = 5; +} + +impl pallet_transaction_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter>; + type OperationalFeeMultiplier = OperationalFeeMultiplier; + type WeightToFee = WeightToFee; + type LengthToFee = ConstantMultiplier; + type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; +} + +parameter_types! { + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; +} +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = Babe; + type MinimumPeriod = MinimumPeriod; + type WeightInfo = weights::pallet_timestamp::WeightInfo; +} + +impl pallet_authorship::Config for Runtime { + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; + type EventHandler = (Staking, ImOnline); +} + +impl_opaque_keys! { + pub struct OldSessionKeys { + pub grandpa: Grandpa, + pub babe: Babe, + pub im_online: ImOnline, + pub para_validator: Initializer, + pub para_assignment: ParaSessionInfo, + pub authority_discovery: AuthorityDiscovery, + } +} + +impl_opaque_keys! { + pub struct SessionKeys { + pub grandpa: Grandpa, + pub babe: Babe, + pub im_online: ImOnline, + pub para_validator: Initializer, + pub para_assignment: ParaSessionInfo, + pub authority_discovery: AuthorityDiscovery, + pub beefy: Beefy, + } +} + +// remove this when removing `OldSessionKeys` +fn transform_session_keys(v: AccountId, old: OldSessionKeys) -> SessionKeys { + SessionKeys { + grandpa: old.grandpa, + babe: old.babe, + im_online: old.im_online, + para_validator: old.para_validator, + para_assignment: old.para_assignment, + authority_discovery: old.authority_discovery, + beefy: { + // From Session::upgrade_keys(): + // + // Care should be taken that the raw versions of the + // added keys are unique for every `ValidatorId, KeyTypeId` combination. + // This is an invariant that the session pallet typically maintains internally. + // + // So, produce a dummy value that's unique for the `ValidatorId, KeyTypeId` combination. + let mut id: BeefyId = sp_application_crypto::ecdsa::Public::from_raw([0u8; 33]).into(); + let id_raw: &mut [u8] = id.as_mut(); + id_raw[1..33].copy_from_slice(v.as_ref()); + id_raw[0..4].copy_from_slice(b"beef"); + id + }, + } +} + +impl pallet_session::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = AccountId; + type ValidatorIdOf = pallet_staking::StashOf; + type ShouldEndSession = Babe; + type NextSessionRotation = Babe; + type SessionManager = pallet_session::historical::NoteHistoricalRoot; + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; + type WeightInfo = weights::pallet_session::WeightInfo; +} + +impl pallet_session::historical::Config for Runtime { + type FullIdentification = pallet_staking::Exposure; + type FullIdentificationOf = pallet_staking::ExposureOf; +} + +parameter_types! { + // phase durations. 1/4 of the last session for each. + // in testing: 1min or half of the session for each + pub SignedPhase: u32 = prod_or_fast!( + EPOCH_DURATION_IN_SLOTS / 4, + (1 * MINUTES).min(EpochDuration::get().saturated_into::() / 2), + "KSM_SIGNED_PHASE" + ); + pub UnsignedPhase: u32 = prod_or_fast!( + EPOCH_DURATION_IN_SLOTS / 4, + (1 * MINUTES).min(EpochDuration::get().saturated_into::() / 2), + "KSM_UNSIGNED_PHASE" + ); + + // signed config + pub const SignedMaxSubmissions: u32 = 16; + pub const SignedMaxRefunds: u32 = 16 / 4; + pub const SignedDepositBase: Balance = deposit(2, 0); + pub const SignedDepositByte: Balance = deposit(0, 10) / 1024; + // Each good submission will get 1/10 KSM as reward + pub SignedRewardBase: Balance = UNITS / 10; + pub BetterUnsignedThreshold: Perbill = Perbill::from_rational(5u32, 10_000); + + // 1 hour session, 15 minutes unsigned phase, 8 offchain executions. + pub OffchainRepeat: BlockNumber = UnsignedPhase::get() / 8; + + pub const MaxElectingVoters: u32 = 12_500; + /// We take the top 12500 nominators as electing voters and all of the validators as electable + /// targets. Whilst this is the case, we cannot and shall not increase the size of the + /// validator intentions. + pub ElectionBounds: frame_election_provider_support::bounds::ElectionBounds = + ElectionBoundsBuilder::default().voters_count(MaxElectingVoters::get().into()).build(); + pub NposSolutionPriority: TransactionPriority = + Perbill::from_percent(90) * TransactionPriority::max_value(); + /// Setup election pallet to support maximum winners upto 2000. This will mean Staking Pallet + /// cannot have active validators higher than this count. + pub const MaxActiveValidators: u32 = 2000; +} + +generate_solution_type!( + #[compact] + pub struct NposCompactSolution24::< + VoterIndex = u32, + TargetIndex = u16, + Accuracy = sp_runtime::PerU16, + MaxVoters = MaxElectingVoters, + >(24) +); + +pub struct OnChainSeqPhragmen; +impl onchain::Config for OnChainSeqPhragmen { + type System = Runtime; + type Solver = SequentialPhragmen; + type DataProvider = Staking; + type WeightInfo = weights::frame_election_provider_support::WeightInfo; + type MaxWinners = MaxActiveValidators; + type Bounds = ElectionBounds; +} + +impl pallet_election_provider_multi_phase::MinerConfig for Runtime { + type AccountId = AccountId; + type MaxLength = OffchainSolutionLengthLimit; + type MaxWeight = OffchainSolutionWeightLimit; + type Solution = NposCompactSolution24; + type MaxVotesPerVoter = < + ::DataProvider + as + frame_election_provider_support::ElectionDataProvider + >::MaxVotesPerVoter; + type MaxWinners = MaxActiveValidators; + + // The unsigned submissions have to respect the weight of the submit_unsigned call, thus their + // weight estimate function is wired to this call's weight. + fn solution_weight(v: u32, t: u32, a: u32, d: u32) -> Weight { + < + ::WeightInfo + as + pallet_election_provider_multi_phase::WeightInfo + >::submit_unsigned(v, t, a, d) + } +} + +impl pallet_election_provider_multi_phase::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type EstimateCallFee = TransactionPayment; + type UnsignedPhase = UnsignedPhase; + type SignedMaxSubmissions = SignedMaxSubmissions; + type SignedMaxRefunds = SignedMaxRefunds; + type SignedRewardBase = SignedRewardBase; + type SignedDepositBase = SignedDepositBase; + type SignedDepositByte = SignedDepositByte; + type SignedDepositWeight = (); + type SignedMaxWeight = + ::MaxWeight; + type MinerConfig = Self; + type SlashHandler = (); // burn slashes + type RewardHandler = (); // nothing to do upon rewards + type SignedPhase = SignedPhase; + type BetterUnsignedThreshold = BetterUnsignedThreshold; + type BetterSignedThreshold = (); + type OffchainRepeat = OffchainRepeat; + type MinerTxPriority = NposSolutionPriority; + type DataProvider = Staking; + #[cfg(any(feature = "fast-runtime", feature = "runtime-benchmarks"))] + type Fallback = onchain::OnChainExecution; + #[cfg(not(any(feature = "fast-runtime", feature = "runtime-benchmarks")))] + type Fallback = frame_election_provider_support::NoElection<( + AccountId, + BlockNumber, + Staking, + MaxActiveValidators, + )>; + type GovernanceFallback = onchain::OnChainExecution; + type Solver = SequentialPhragmen< + AccountId, + pallet_election_provider_multi_phase::SolutionAccuracyOf, + (), + >; + type BenchmarkingConfig = runtime_common::elections::BenchmarkConfig; + type ForceOrigin = EitherOf, StakingAdmin>; + type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo; + type MaxWinners = MaxActiveValidators; + type ElectionBounds = ElectionBounds; +} + +parameter_types! { + pub const BagThresholds: &'static [u64] = &bag_thresholds::THRESHOLDS; +} + +type VoterBagsListInstance = pallet_bags_list::Instance1; +impl pallet_bags_list::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ScoreProvider = Staking; + type WeightInfo = weights::pallet_bags_list::WeightInfo; + type BagThresholds = BagThresholds; + type Score = sp_npos_elections::VoteWeight; +} + +pub struct EraPayout; +impl pallet_staking::EraPayout for EraPayout { + fn era_payout( + total_staked: Balance, + _total_issuance: Balance, + era_duration_millis: u64, + ) -> (Balance, Balance) { + // all para-ids that are currently active. + let auctioned_slots = Paras::parachains() + .into_iter() + // all active para-ids that do not belong to a system or common good chain is the number + // of parachains that we should take into account for inflation. + .filter(|i| *i >= LOWEST_PUBLIC_ID) + .count() as u64; + + const MAX_ANNUAL_INFLATION: Perquintill = Perquintill::from_percent(10); + const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; + + runtime_common::impls::era_payout( + total_staked, + Nis::issuance().other, + MAX_ANNUAL_INFLATION, + Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR), + auctioned_slots, + ) + } +} + +parameter_types! { + // Six sessions in an era (6 hours). + pub const SessionsPerEra: SessionIndex = prod_or_fast!(6, 1); + + // 28 eras for unbonding (7 days). + pub BondingDuration: sp_staking::EraIndex = prod_or_fast!( + 28, + 28, + "DOT_BONDING_DURATION" + ); + // 27 eras in which slashes can be cancelled (slightly less than 7 days). + pub SlashDeferDuration: sp_staking::EraIndex = prod_or_fast!( + 27, + 27, + "DOT_SLASH_DEFER_DURATION" + ); + pub const MaxNominatorRewardedPerValidator: u32 = 512; + pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17); + // 24 + pub const MaxNominations: u32 = ::LIMIT as u32; +} + +impl pallet_staking::Config for Runtime { + type Currency = Balances; + type CurrencyBalance = Balance; + type UnixTime = Timestamp; + type CurrencyToVote = CurrencyToVote; + type ElectionProvider = ElectionProviderMultiPhase; + type GenesisElectionProvider = onchain::OnChainExecution; + type RewardRemainder = Treasury; + type RuntimeEvent = RuntimeEvent; + type Slash = Treasury; + type Reward = (); + type SessionsPerEra = SessionsPerEra; + type BondingDuration = BondingDuration; + type SlashDeferDuration = SlashDeferDuration; + type AdminOrigin = EitherOf, StakingAdmin>; + type SessionInterface = Self; + type EraPayout = EraPayout; + type NextNewSession = Session; + type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; + type OffendingValidatorsThreshold = OffendingValidatorsThreshold; + type VoterList = VoterList; + type TargetList = UseValidatorsMap; + type NominationsQuota = pallet_staking::FixedNominationsQuota<{ MaxNominations::get() }>; + type MaxUnlockingChunks = frame_support::traits::ConstU32<32>; + type HistoryDepth = frame_support::traits::ConstU32<84>; + type BenchmarkingConfig = runtime_common::StakingBenchmarkingConfig; + type EventListeners = NominationPools; + type WeightInfo = weights::pallet_staking::WeightInfo; +} + +impl pallet_fast_unstake::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BatchSize = frame_support::traits::ConstU32<64>; + type Deposit = frame_support::traits::ConstU128<{ CENTS * 100 }>; + type ControlOrigin = EnsureRoot; + type Staking = Staking; + type MaxErasToCheckPerBlock = ConstU32<1>; + #[cfg(feature = "runtime-benchmarks")] + type MaxBackersPerValidator = MaxNominatorRewardedPerValidator; + type WeightInfo = weights::pallet_fast_unstake::WeightInfo; +} + +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: Balance = 2000 * CENTS; + pub const ProposalBondMaximum: Balance = 1 * GRAND; + pub const SpendPeriod: BlockNumber = 6 * DAYS; + pub const Burn: Permill = Permill::from_perthousand(2); + pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); + + pub const TipCountdown: BlockNumber = 1 * DAYS; + pub const TipFindersFee: Percent = Percent::from_percent(20); + pub const TipReportDepositBase: Balance = 100 * CENTS; + pub const DataDepositPerByte: Balance = 1 * CENTS; + pub const MaxApprovals: u32 = 100; + pub const MaxAuthorities: u32 = 100_000; + pub const MaxKeys: u32 = 10_000; + pub const MaxPeerInHeartbeats: u32 = 10_000; +} + +impl pallet_treasury::Config for Runtime { + type PalletId = TreasuryPalletId; + type Currency = Balances; + type ApproveOrigin = EitherOfDiverse, Treasurer>; + type RejectOrigin = EitherOfDiverse, Treasurer>; + type RuntimeEvent = RuntimeEvent; + type OnSlash = Treasury; + type ProposalBond = ProposalBond; + type ProposalBondMinimum = ProposalBondMinimum; + type ProposalBondMaximum = ProposalBondMaximum; + type SpendPeriod = SpendPeriod; + type Burn = Burn; + type BurnDestination = Society; + type MaxApprovals = MaxApprovals; + type WeightInfo = weights::pallet_treasury::WeightInfo; + type SpendFunds = Bounties; + type SpendOrigin = TreasurySpender; +} + +parameter_types! { + pub const BountyDepositBase: Balance = 100 * CENTS; + pub const BountyDepositPayoutDelay: BlockNumber = 4 * DAYS; + pub const BountyUpdatePeriod: BlockNumber = 90 * DAYS; + pub const MaximumReasonLength: u32 = 16384; + pub const CuratorDepositMultiplier: Permill = Permill::from_percent(50); + pub const CuratorDepositMin: Balance = 10 * CENTS; + pub const CuratorDepositMax: Balance = 500 * CENTS; + pub const BountyValueMinimum: Balance = 200 * CENTS; +} + +impl pallet_bounties::Config for Runtime { + type BountyDepositBase = BountyDepositBase; + type BountyDepositPayoutDelay = BountyDepositPayoutDelay; + type BountyUpdatePeriod = BountyUpdatePeriod; + type CuratorDepositMultiplier = CuratorDepositMultiplier; + type CuratorDepositMin = CuratorDepositMin; + type CuratorDepositMax = CuratorDepositMax; + type BountyValueMinimum = BountyValueMinimum; + type ChildBountyManager = ChildBounties; + type DataDepositPerByte = DataDepositPerByte; + type RuntimeEvent = RuntimeEvent; + type MaximumReasonLength = MaximumReasonLength; + type WeightInfo = weights::pallet_bounties::WeightInfo; +} + +parameter_types! { + pub const MaxActiveChildBountyCount: u32 = 100; + pub const ChildBountyValueMinimum: Balance = BountyValueMinimum::get() / 10; +} + +impl pallet_child_bounties::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type MaxActiveChildBountyCount = MaxActiveChildBountyCount; + type ChildBountyValueMinimum = ChildBountyValueMinimum; + type WeightInfo = weights::pallet_child_bounties::WeightInfo; +} + +impl pallet_offences::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type IdentificationTuple = pallet_session::historical::IdentificationTuple; + type OnOffenceHandler = Staking; +} + +impl pallet_authority_discovery::Config for Runtime { + type MaxAuthorities = MaxAuthorities; +} + +parameter_types! { + pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +impl pallet_im_online::Config for Runtime { + type AuthorityId = ImOnlineId; + type RuntimeEvent = RuntimeEvent; + type ValidatorSet = Historical; + type NextSessionRotation = Babe; + type ReportUnresponsiveness = Offences; + type UnsignedPriority = ImOnlineUnsignedPriority; + type WeightInfo = weights::pallet_im_online::WeightInfo; + type MaxKeys = MaxKeys; + type MaxPeerInHeartbeats = MaxPeerInHeartbeats; +} + +parameter_types! { + pub MaxSetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); +} + +impl pallet_grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + + type WeightInfo = (); + type MaxAuthorities = MaxAuthorities; + type MaxNominators = MaxNominatorRewardedPerValidator; + type MaxSetIdSessionEntries = MaxSetIdSessionEntries; + + type KeyOwnerProof = >::Proof; + + type EquivocationReportSystem = + pallet_grandpa::EquivocationReportSystem; +} + +/// Submits transaction with the node's public and signature type. Adheres to the signed extension +/// format of the chain. +impl frame_system::offchain::CreateSignedTransaction for Runtime +where + RuntimeCall: From, +{ + fn create_transaction>( + call: RuntimeCall, + public: ::Signer, + account: AccountId, + nonce: ::Nonce, + ) -> Option<(RuntimeCall, ::SignaturePayload)> { + use sp_runtime::traits::StaticLookup; + // take the biggest period possible. + let period = + BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; + + let current_block = System::block_number() + .saturated_into::() + // The `System::block_number` is initialized with `n+1`, + // so the actual block number is `n`. + .saturating_sub(1); + let tip = 0; + let extra: SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(generic::Era::mortal( + period, + current_block, + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + ); + let raw_payload = SignedPayload::new(call, extra) + .map_err(|e| { + log::warn!("Unable to create signed payload: {:?}", e); + }) + .ok()?; + let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; + let (call, extra, _) = raw_payload.deconstruct(); + let address = ::Lookup::unlookup(account); + Some((call, (address, signature, extra))) + } +} + +impl frame_system::offchain::SigningTypes for Runtime { + type Public = ::Signer; + type Signature = Signature; +} + +impl frame_system::offchain::SendTransactionTypes for Runtime +where + RuntimeCall: From, +{ + type Extrinsic = UncheckedExtrinsic; + type OverarchingCall = RuntimeCall; +} + +parameter_types! { + pub Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:"; +} + +impl claims::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type VestingSchedule = Vesting; + type Prefix = Prefix; + type MoveClaimOrigin = EnsureRoot; + type WeightInfo = weights::runtime_common_claims::WeightInfo; +} + +parameter_types! { + // Minimum 100 bytes/KSM deposited (1 CENT/byte) + pub const BasicDeposit: Balance = 1000 * CENTS; // 258 bytes on-chain + pub const FieldDeposit: Balance = 250 * CENTS; // 66 bytes on-chain + pub const SubAccountDeposit: Balance = 200 * CENTS; // 53 bytes on-chain + pub const MaxSubAccounts: u32 = 100; + pub const MaxAdditionalFields: u32 = 100; + pub const MaxRegistrars: u32 = 20; +} + +impl pallet_identity::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BasicDeposit = BasicDeposit; + type FieldDeposit = FieldDeposit; + type SubAccountDeposit = SubAccountDeposit; + type MaxSubAccounts = MaxSubAccounts; + type MaxAdditionalFields = MaxAdditionalFields; + type MaxRegistrars = MaxRegistrars; + type Slashed = Treasury; + type ForceOrigin = EitherOf, GeneralAdmin>; + type RegistrarOrigin = EitherOf, GeneralAdmin>; + type WeightInfo = weights::pallet_identity::WeightInfo; +} + +impl pallet_utility::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type PalletsOrigin = OriginCaller; + type WeightInfo = weights::pallet_utility::WeightInfo; +} + +parameter_types! { + // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. + pub const DepositBase: Balance = deposit(1, 88); + // Additional storage item size of 32 bytes. + pub const DepositFactor: Balance = deposit(0, 32); + pub const MaxSignatories: u32 = 100; +} + +impl pallet_multisig::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type DepositBase = DepositBase; + type DepositFactor = DepositFactor; + type MaxSignatories = MaxSignatories; + type WeightInfo = weights::pallet_multisig::WeightInfo; +} + +parameter_types! { + pub const ConfigDepositBase: Balance = 500 * CENTS; + pub const FriendDepositFactor: Balance = 50 * CENTS; + pub const MaxFriends: u16 = 9; + pub const RecoveryDeposit: Balance = 500 * CENTS; +} + +impl pallet_recovery::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type ConfigDepositBase = ConfigDepositBase; + type FriendDepositFactor = FriendDepositFactor; + type MaxFriends = MaxFriends; + type RecoveryDeposit = RecoveryDeposit; +} + +parameter_types! { + pub const SocietyPalletId: PalletId = PalletId(*b"py/socie"); +} + +impl pallet_society::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type GraceStrikes = ConstU32<10>; + type PeriodSpend = ConstU128<{ 500 * QUID }>; + type VotingPeriod = ConstU32<{ 5 * DAYS }>; + type ClaimPeriod = ConstU32<{ 2 * DAYS }>; + type MaxLockDuration = ConstU32<{ 36 * 30 * DAYS }>; + type FounderSetOrigin = EnsureRoot; + type ChallengePeriod = ConstU32<{ 7 * DAYS }>; + type MaxPayouts = ConstU32<8>; + type MaxBids = ConstU32<512>; + type PalletId = SocietyPalletId; + type WeightInfo = weights::pallet_society::WeightInfo; +} + +parameter_types! { + pub const MinVestedTransfer: Balance = 100 * CENTS; + pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = + WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); +} + +impl pallet_vesting::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BlockNumberToBalance = ConvertInto; + type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = weights::pallet_vesting::WeightInfo; + type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; + const MAX_VESTING_SCHEDULES: u32 = 28; +} + +parameter_types! { + // One storage item; key size 32, value size 8; . + pub const ProxyDepositBase: Balance = deposit(1, 8); + // Additional storage item size of 33 bytes. + pub const ProxyDepositFactor: Balance = deposit(0, 33); + pub const MaxProxies: u16 = 32; + pub const AnnouncementDepositBase: Balance = deposit(1, 8); + pub const AnnouncementDepositFactor: Balance = deposit(0, 66); + pub const MaxPending: u16 = 32; +} + +/// The type used to represent the kinds of proxying allowed. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + RuntimeDebug, + MaxEncodedLen, + TypeInfo, +)] +pub enum ProxyType { + Any, + NonTransfer, + Governance, + Staking, + IdentityJudgement, + CancelProxy, + Auction, + Society, + NominationPools, +} + +impl Default for ProxyType { + fn default() -> Self { + Self::Any + } +} + +impl InstanceFilter for ProxyType { + fn filter(&self, c: &RuntimeCall) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => matches!( + c, + RuntimeCall::System(..) | + RuntimeCall::Babe(..) | + RuntimeCall::Timestamp(..) | + RuntimeCall::Indices(pallet_indices::Call::claim {..}) | + RuntimeCall::Indices(pallet_indices::Call::free {..}) | + RuntimeCall::Indices(pallet_indices::Call::freeze {..}) | + // Specifically omitting Indices `transfer`, `force_transfer` + // Specifically omitting the entire Balances pallet + RuntimeCall::Staking(..) | + RuntimeCall::Session(..) | + RuntimeCall::Grandpa(..) | + RuntimeCall::ImOnline(..) | + RuntimeCall::Treasury(..) | + RuntimeCall::Bounties(..) | + RuntimeCall::ChildBounties(..) | + RuntimeCall::ConvictionVoting(..) | + RuntimeCall::Referenda(..) | + RuntimeCall::FellowshipCollective(..) | + RuntimeCall::FellowshipReferenda(..) | + RuntimeCall::Whitelist(..) | + RuntimeCall::Claims(..) | + RuntimeCall::Utility(..) | + RuntimeCall::Identity(..) | + RuntimeCall::Society(..) | + RuntimeCall::Recovery(pallet_recovery::Call::as_recovered {..}) | + RuntimeCall::Recovery(pallet_recovery::Call::vouch_recovery {..}) | + RuntimeCall::Recovery(pallet_recovery::Call::claim_recovery {..}) | + RuntimeCall::Recovery(pallet_recovery::Call::close_recovery {..}) | + RuntimeCall::Recovery(pallet_recovery::Call::remove_recovery {..}) | + RuntimeCall::Recovery(pallet_recovery::Call::cancel_recovered {..}) | + // Specifically omitting Recovery `create_recovery`, `initiate_recovery` + RuntimeCall::Vesting(pallet_vesting::Call::vest {..}) | + RuntimeCall::Vesting(pallet_vesting::Call::vest_other {..}) | + // Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer` + RuntimeCall::Scheduler(..) | + RuntimeCall::Proxy(..) | + RuntimeCall::Multisig(..) | + RuntimeCall::Nis(..) | + RuntimeCall::Registrar(paras_registrar::Call::register {..}) | + RuntimeCall::Registrar(paras_registrar::Call::deregister {..}) | + // Specifically omitting Registrar `swap` + RuntimeCall::Registrar(paras_registrar::Call::reserve {..}) | + RuntimeCall::Crowdloan(..) | + RuntimeCall::Slots(..) | + RuntimeCall::Auctions(..) | // Specifically omitting the entire XCM Pallet + RuntimeCall::VoterList(..) | + RuntimeCall::NominationPools(..) | + RuntimeCall::FastUnstake(..) + ), + ProxyType::Governance => matches!( + c, + RuntimeCall::Treasury(..) | + RuntimeCall::Bounties(..) | + RuntimeCall::Utility(..) | + RuntimeCall::ChildBounties(..) | + // OpenGov calls + RuntimeCall::ConvictionVoting(..) | + RuntimeCall::Referenda(..) | + RuntimeCall::FellowshipCollective(..) | + RuntimeCall::FellowshipReferenda(..) | + RuntimeCall::Whitelist(..) + ), + ProxyType::Staking => { + matches!( + c, + RuntimeCall::Staking(..) | + RuntimeCall::Session(..) | RuntimeCall::Utility(..) | + RuntimeCall::FastUnstake(..) | + RuntimeCall::VoterList(..) | + RuntimeCall::NominationPools(..) + ) + }, + ProxyType::NominationPools => { + matches!(c, RuntimeCall::NominationPools(..) | RuntimeCall::Utility(..)) + }, + ProxyType::IdentityJudgement => matches!( + c, + RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. }) | + RuntimeCall::Utility(..) + ), + ProxyType::CancelProxy => { + matches!(c, RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })) + }, + ProxyType::Auction => matches!( + c, + RuntimeCall::Auctions(..) | + RuntimeCall::Crowdloan(..) | + RuntimeCall::Registrar(..) | + RuntimeCall::Slots(..) + ), + ProxyType::Society => matches!(c, RuntimeCall::Society(..)), + } + } + fn is_superset(&self, o: &Self) -> bool { + match (self, o) { + (x, y) if x == y => true, + (ProxyType::Any, _) => true, + (_, ProxyType::Any) => false, + (ProxyType::NonTransfer, _) => true, + _ => false, + } + } +} + +impl pallet_proxy::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type ProxyType = ProxyType; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type MaxProxies = MaxProxies; + type WeightInfo = weights::pallet_proxy::WeightInfo; + type MaxPending = MaxPending; + type CallHasher = BlakeTwo256; + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; +} + +impl parachains_origin::Config for Runtime {} + +impl parachains_configuration::Config for Runtime { + type WeightInfo = weights::runtime_parachains_configuration::WeightInfo; +} + +impl parachains_shared::Config for Runtime {} + +impl parachains_session_info::Config for Runtime { + type ValidatorSet = Historical; +} + +impl parachains_inclusion::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type DisputesHandler = ParasDisputes; + type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints; + type MessageQueue = MessageQueue; + type WeightInfo = weights::runtime_parachains_inclusion::WeightInfo; +} + +parameter_types! { + pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +impl parachains_paras::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::runtime_parachains_paras::WeightInfo; + type UnsignedPriority = ParasUnsignedPriority; + type QueueFootprinter = ParaInclusion; + type NextSessionRotation = Babe; +} + +parameter_types! { + /// Amount of weight that can be spent per block to service messages. + /// + /// # WARNING + /// + /// This is not a good value for para-chains since the `Scheduler` already uses up to 80% block weight. + pub MessageQueueServiceWeight: Weight = Perbill::from_percent(20) * BlockWeights::get().max_block; + pub const MessageQueueHeapSize: u32 = 65_536; + pub const MessageQueueMaxStale: u32 = 16; +} + +/// Message processor to handle any messages that were enqueued into the `MessageQueue` pallet. +pub struct MessageProcessor; +impl ProcessMessage for MessageProcessor { + type Origin = AggregateMessageOrigin; + + fn process_message( + message: &[u8], + origin: Self::Origin, + meter: &mut WeightMeter, + id: &mut [u8; 32], + ) -> Result { + let para = match origin { + AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para, + }; + xcm_builder::ProcessXcmMessage::< + Junction, + xcm_executor::XcmExecutor, + RuntimeCall, + >::process_message(message, Junction::Parachain(para.into()), meter, id) + } +} + +impl pallet_message_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Size = u32; + type HeapSize = MessageQueueHeapSize; + type MaxStale = MessageQueueMaxStale; + type ServiceWeight = MessageQueueServiceWeight; + #[cfg(not(feature = "runtime-benchmarks"))] + type MessageProcessor = MessageProcessor; + #[cfg(feature = "runtime-benchmarks")] + type MessageProcessor = + pallet_message_queue::mock_helpers::NoopMessageProcessor; + type QueueChangeHandler = ParaInclusion; + type QueuePausedQuery = (); + type WeightInfo = weights::pallet_message_queue::WeightInfo; +} + +impl parachains_dmp::Config for Runtime {} + +impl parachains_hrmp::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type ChannelManager = EitherOf, GeneralAdmin>; + type Currency = Balances; + type WeightInfo = weights::runtime_parachains_hrmp::WeightInfo; +} + +impl parachains_paras_inherent::Config for Runtime { + type WeightInfo = weights::runtime_parachains_paras_inherent::WeightInfo; +} + +impl parachains_scheduler::Config for Runtime { + type AssignmentProvider = ParaAssignmentProvider; +} + +impl parachains_assigner_parachains::Config for Runtime {} + +impl parachains_initializer::Config for Runtime { + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type ForceOrigin = EnsureRoot; + type WeightInfo = weights::runtime_parachains_initializer::WeightInfo; +} + +impl parachains_disputes::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints; + type SlashingHandler = parachains_slashing::SlashValidatorsForDisputes; + type WeightInfo = weights::runtime_parachains_disputes::WeightInfo; +} + +impl parachains_slashing::Config for Runtime { + type KeyOwnerProofSystem = Historical; + type KeyOwnerProof = + >::Proof; + type KeyOwnerIdentification = >::IdentificationTuple; + type HandleReports = parachains_slashing::SlashingReportHandler< + Self::KeyOwnerIdentification, + Offences, + ReportLongevity, + >; + type WeightInfo = weights::runtime_parachains_disputes_slashing::WeightInfo; + type BenchmarkingConfig = parachains_slashing::BenchConfig<1000>; +} + +parameter_types! { + pub const ParaDeposit: Balance = 40 * UNITS; +} + +impl paras_registrar::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type OnSwap = (Crowdloan, Slots); + type ParaDeposit = ParaDeposit; + type DataDepositPerByte = DataDepositPerByte; + type WeightInfo = weights::runtime_common_paras_registrar::WeightInfo; +} + +parameter_types! { + // 6 weeks + pub LeasePeriod: BlockNumber = prod_or_fast!(6 * WEEKS, 6 * WEEKS, "KSM_LEASE_PERIOD"); +} + +impl slots::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Registrar = Registrar; + type LeasePeriod = LeasePeriod; + type LeaseOffset = (); + type ForceOrigin = EitherOf, LeaseAdmin>; + type WeightInfo = weights::runtime_common_slots::WeightInfo; +} + +parameter_types! { + pub const CrowdloanId: PalletId = PalletId(*b"py/cfund"); + pub const OldSubmissionDeposit: Balance = 3 * GRAND; // ~ 10 KSM + pub const MinContribution: Balance = 3_000 * CENTS; // ~ .1 KSM + pub const RemoveKeysLimit: u32 = 1000; + // Allow 32 bytes for an additional memo to a crowdloan. + pub const MaxMemoLength: u8 = 32; +} + +impl crowdloan::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type PalletId = CrowdloanId; + type SubmissionDeposit = OldSubmissionDeposit; + type MinContribution = MinContribution; + type RemoveKeysLimit = RemoveKeysLimit; + type Registrar = Registrar; + type Auctioneer = Auctions; + type MaxMemoLength = MaxMemoLength; + type WeightInfo = weights::runtime_common_crowdloan::WeightInfo; +} + +parameter_types! { + // The average auction is 7 days long, so this will be 70% for ending period. + // 5 Days = 72000 Blocks @ 6 sec per block + pub const EndingPeriod: BlockNumber = 5 * DAYS; + // ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples + pub const SampleLength: BlockNumber = 2 * MINUTES; +} + +impl auctions::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Leaser = Slots; + type Registrar = Registrar; + type EndingPeriod = EndingPeriod; + type SampleLength = SampleLength; + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type InitiateOrigin = EitherOf, AuctionAdmin>; + type WeightInfo = weights::runtime_common_auctions::WeightInfo; +} + +type NisCounterpartInstance = pallet_balances::Instance2; +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ConstU128<10_000_000_000>; // One KTC cent + type AccountStore = StorageMapShim< + pallet_balances::Account, + AccountId, + pallet_balances::AccountData, + >; + type MaxLocks = ConstU32<4>; + type MaxReserves = ConstU32<4>; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = weights::pallet_balances_nis_counterpart_balances::WeightInfo; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +parameter_types! { + pub const NisBasePeriod: BlockNumber = 7 * DAYS; + pub const MinBid: Balance = 100 * QUID; + pub MinReceipt: Perquintill = Perquintill::from_rational(1u64, 10_000_000u64); + pub const IntakePeriod: BlockNumber = 5 * MINUTES; + pub MaxIntakeWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10; + pub const ThawThrottle: (Perquintill, BlockNumber) = (Perquintill::from_percent(25), 5); + pub storage NisTarget: Perquintill = Perquintill::zero(); + pub const NisPalletId: PalletId = PalletId(*b"py/nis "); +} + +impl pallet_nis::Config for Runtime { + type WeightInfo = weights::pallet_nis::WeightInfo; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type CurrencyBalance = Balance; + type FundOrigin = frame_system::EnsureSigned; + type Counterpart = NisCounterpartBalances; + type CounterpartAmount = WithMaximumOf>; + type Deficit = (); // Mint + type IgnoredIssuance = (); + type Target = NisTarget; + type PalletId = NisPalletId; + type QueueCount = ConstU32<500>; + type MaxQueueLen = ConstU32<1000>; + type FifoQueueLen = ConstU32<250>; + type BasePeriod = NisBasePeriod; + type MinBid = MinBid; + type MinReceipt = MinReceipt; + type IntakePeriod = IntakePeriod; + type MaxIntakeWeight = MaxIntakeWeight; + type ThawThrottle = ThawThrottle; + type RuntimeHoldReason = RuntimeHoldReason; +} + +parameter_types! { + pub const PoolsPalletId: PalletId = PalletId(*b"py/nopls"); + pub const MaxPointsToBalance: u8 = 10; +} + +impl pallet_nomination_pools::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_nomination_pools::WeightInfo; + type Currency = Balances; + type RewardCounter = FixedU128; + type BalanceToU256 = BalanceToU256; + type U256ToBalance = U256ToBalance; + type Staking = Staking; + type PostUnbondingPoolsWindow = ConstU32<4>; + type MaxMetadataLen = ConstU32<256>; + // we use the same number of allowed unlocking chunks as with staking. + type MaxUnbonding = ::MaxUnlockingChunks; + type PalletId = PoolsPalletId; + type MaxPointsToBalance = MaxPointsToBalance; +} + +parameter_types! { + // The deposit configuration for the singed migration. Specially if you want to allow any signed account to do the migration (see `SignedFilter`, these deposits should be high) + pub const MigrationSignedDepositPerItem: Balance = 1 * CENTS; + pub const MigrationSignedDepositBase: Balance = 20 * CENTS * 100; + pub const MigrationMaxKeyLen: u32 = 512; +} + +impl pallet_state_trie_migration::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type SignedDepositPerItem = MigrationSignedDepositPerItem; + type SignedDepositBase = MigrationSignedDepositBase; + type ControlOrigin = EnsureRoot; + type SignedFilter = frame_support::traits::NeverEnsureOrigin; + + // Use same weights as substrate ones. + type WeightInfo = pallet_state_trie_migration::weights::SubstrateWeight; + type MaxKeyLen = MigrationMaxKeyLen; +} + +construct_runtime! { + pub enum Runtime + { + // Basic stuff; balances is uncallable initially. + System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, + + // Babe must be before session. + Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned} = 1, + + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, + Indices: pallet_indices::{Pallet, Call, Storage, Config, Event} = 3, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 4, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 33, + + // Consensus support. + // Authorship must be before session in order to note author in the correct session and era + // for im-online and staking. + Authorship: pallet_authorship::{Pallet, Storage} = 5, + Staking: pallet_staking::{Pallet, Call, Storage, Config, Event} = 6, + Offences: pallet_offences::{Pallet, Storage, Event} = 7, + Historical: session_historical::{Pallet} = 34, + + // BEEFY Bridges support. + Beefy: pallet_beefy::{Pallet, Call, Storage, Config, ValidateUnsigned} = 200, + // MMR leaf construction must be before session in order to have leaf contents + // refer to block consistently. see substrate issue #11797 for details. + Mmr: pallet_mmr::{Pallet, Storage} = 201, + BeefyMmrLeaf: pallet_beefy_mmr::{Pallet, Storage} = 202, + + Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 8, + Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned} = 10, + ImOnline: pallet_im_online::{Pallet, Call, Storage, Event, ValidateUnsigned, Config} = 11, + AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config} = 12, + + // Governance stuff. + Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 18, + ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event} = 20, + Referenda: pallet_referenda::{Pallet, Call, Storage, Event} = 21, +// pub type FellowshipCollectiveInstance = pallet_ranked_collective::Instance1; + FellowshipCollective: pallet_ranked_collective::::{ + Pallet, Call, Storage, Event + } = 22, +// pub type FellowshipReferendaInstance = pallet_referenda::Instance2; + FellowshipReferenda: pallet_referenda::::{ + Pallet, Call, Storage, Event + } = 23, + Origins: pallet_custom_origins::{Origin} = 43, + Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event} = 44, + + // Claims. Usable initially. + Claims: claims::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 19, + + // Utility module. + Utility: pallet_utility::{Pallet, Call, Event} = 24, + + // Less simple identity module. + Identity: pallet_identity::{Pallet, Call, Storage, Event} = 25, + + // Society module. + Society: pallet_society::{Pallet, Call, Storage, Event} = 26, + + // Social recovery module. + Recovery: pallet_recovery::{Pallet, Call, Storage, Event} = 27, + + // Vesting. Usable initially, but removed once all vesting is finished. + Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config} = 28, + + // System scheduler. + Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 29, + + // Proxy module. Late addition. + Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 30, + + // Multisig module. Late addition. + Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 31, + + // Preimage registrar. + Preimage: pallet_preimage::{Pallet, Call, Storage, Event} = 32, + + // Bounties modules. + Bounties: pallet_bounties::{Pallet, Call, Storage, Event} = 35, + ChildBounties: pallet_child_bounties = 40, + + // Election pallet. Only works with staking, but placed here to maintain indices. + ElectionProviderMultiPhase: pallet_election_provider_multi_phase::{Pallet, Call, Storage, Event, ValidateUnsigned} = 37, + + // NIS pallet. + Nis: pallet_nis::{Pallet, Call, Storage, Event, HoldReason} = 38, +// pub type NisCounterpartInstance = pallet_balances::Instance2; + NisCounterpartBalances: pallet_balances:: = 45, + + // Provides a semi-sorted list of nominators for staking. + VoterList: pallet_bags_list::::{Pallet, Call, Storage, Event} = 39, + + // nomination pools: extension to staking. + NominationPools: pallet_nomination_pools::{Pallet, Call, Storage, Event, Config} = 41, + + // Fast unstake pallet: extension to staking. + FastUnstake: pallet_fast_unstake = 42, + + // Parachains pallets. Start indices at 50 to leave room. + ParachainsOrigin: parachains_origin::{Pallet, Origin} = 50, + Configuration: parachains_configuration::{Pallet, Call, Storage, Config} = 51, + ParasShared: parachains_shared::{Pallet, Call, Storage} = 52, + ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event} = 53, + ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent} = 54, + ParaScheduler: parachains_scheduler::{Pallet, Storage} = 55, + Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 56, + Initializer: parachains_initializer::{Pallet, Call, Storage} = 57, + Dmp: parachains_dmp::{Pallet, Storage} = 58, + Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 60, + ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 61, + ParasDisputes: parachains_disputes::{Pallet, Call, Storage, Event} = 62, + ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned} = 63, + ParaAssignmentProvider: parachains_assigner_parachains::{Pallet, Storage} = 64, + + // Parachain Onboarding Pallets. Start indices at 70 to leave room. + Registrar: paras_registrar::{Pallet, Call, Storage, Event} = 70, + Slots: slots::{Pallet, Call, Storage, Event} = 71, + Auctions: auctions::{Pallet, Call, Storage, Event} = 72, + Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 73, + + // State trie migration pallet, only temporary. + StateTrieMigration: pallet_state_trie_migration = 98, + + // Pallet for sending XCM. + XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 99, + + // Generalized message queue + MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 100, + } +} + +/// The address format for describing accounts. +pub type Address = sp_runtime::MultiAddress; +/// Block header type as expected by this runtime. +pub type Header = generic::Header; +/// Block type as expected by this runtime. +pub type Block = generic::Block; +/// A Block signed with a Justification +pub type SignedBlock = generic::SignedBlock; +/// `BlockId` type as expected by this runtime. +pub type BlockId = generic::BlockId; +/// The `SignedExtension` to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckMortality, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); + +pub struct NominationPoolsMigrationV4OldPallet; +impl Get for NominationPoolsMigrationV4OldPallet { + fn get() -> Perbill { + Perbill::from_percent(10) + } +} + +/// All migrations that will run on the next runtime upgrade. +/// +/// This contains the combined migrations of the last 10 releases. It allows to skip runtime +/// upgrades in case governance decides to do so. THE ORDER IS IMPORTANT. +pub type Migrations = migrations::Unreleased; + +/// The runtime migrations per release. +#[allow(deprecated, missing_docs)] +pub mod migrations { + use super::*; + use frame_support::traits::LockIdentifier; + use frame_system::pallet_prelude::BlockNumberFor; + + parameter_types! { + pub const DemocracyPalletName: &'static str = "Democracy"; + pub const CouncilPalletName: &'static str = "Council"; + pub const TechnicalCommitteePalletName: &'static str = "TechnicalCommittee"; + pub const PhragmenElectionPalletName: &'static str = "PhragmenElection"; + pub const TechnicalMembershipPalletName: &'static str = "TechnicalMembership"; + pub const TipsPalletName: &'static str = "Tips"; + pub const PhragmenElectionPalletId: LockIdentifier = *b"phrelect"; + } + + // Special Config for Gov V1 pallets, allowing us to run migrations for them without + // implementing their configs on [`Runtime`]. + pub struct UnlockConfig; + impl pallet_democracy::migrations::unlock_and_unreserve_all_funds::UnlockConfig for UnlockConfig { + type Currency = Balances; + type MaxVotes = ConstU32<100>; + type MaxDeposits = ConstU32<100>; + type AccountId = AccountId; + type BlockNumber = BlockNumberFor; + type DbWeight = ::DbWeight; + type PalletName = DemocracyPalletName; + } + impl pallet_elections_phragmen::migrations::unlock_and_unreserve_all_funds::UnlockConfig + for UnlockConfig + { + type Currency = Balances; + type MaxVotesPerVoter = ConstU32<16>; + type PalletId = PhragmenElectionPalletId; + type AccountId = AccountId; + type DbWeight = ::DbWeight; + type PalletName = PhragmenElectionPalletName; + } + impl pallet_tips::migrations::unreserve_deposits::UnlockConfig<()> for UnlockConfig { + type Currency = Balances; + type Hash = Hash; + type DataDepositPerByte = DataDepositPerByte; + type TipReportDepositBase = TipReportDepositBase; + type AccountId = AccountId; + type BlockNumber = BlockNumberFor; + type DbWeight = ::DbWeight; + type PalletName = TipsPalletName; + } + + /// Upgrade Session keys to include BEEFY key. + /// When this is removed, should also remove `OldSessionKeys`. + pub struct UpgradeSessionKeys; + impl frame_support::traits::OnRuntimeUpgrade for UpgradeSessionKeys { + fn on_runtime_upgrade() -> Weight { + Session::upgrade_keys::(transform_session_keys); + Perbill::from_percent(50) * BlockWeights::get().max_block + } + } + + /// Unreleased migrations. Add new ones here: + pub type Unreleased = ( + init_state_migration::InitMigrate, + pallet_society::migrations::VersionCheckedMigrateToV2< + Runtime, + (), + past_payouts::PastPayouts, + >, + pallet_im_online::migration::v1::Migration, + parachains_configuration::migration::v7::MigrateToV7, + parachains_scheduler::migration::v1::MigrateToV1, + parachains_configuration::migration::v8::MigrateToV8, + + // Unlock/unreserve balances from Gov v1 pallets that hold them + // https://github.com/paritytech/polkadot/issues/6749 + pallet_elections_phragmen::migrations::unlock_and_unreserve_all_funds::UnlockAndUnreserveAllFunds, + pallet_democracy::migrations::unlock_and_unreserve_all_funds::UnlockAndUnreserveAllFunds, + pallet_tips::migrations::unreserve_deposits::UnreserveDeposits, + + // Delete storage key/values from all Gov v1 pallets + frame_support::migrations::RemovePallet::DbWeight>, + frame_support::migrations::RemovePallet::DbWeight>, + frame_support::migrations::RemovePallet::DbWeight>, + frame_support::migrations::RemovePallet::DbWeight>, + frame_support::migrations::RemovePallet::DbWeight>, + frame_support::migrations::RemovePallet::DbWeight>, + + // Upgrade SessionKeys to include BEEFY key + UpgradeSessionKeys, + ); +} + +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + generic::UncheckedExtrinsic; +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, + Migrations, +>; +/// The payload being signed in the transactions. +pub type SignedPayload = generic::SignedPayload; + +#[cfg(feature = "runtime-benchmarks")] +mod benches { + frame_benchmarking::define_benchmarks!( + // Polkadot + // NOTE: Make sure to prefix these with `runtime_common::` so + // that the path resolves correctly in the generated file. + [runtime_common::auctions, Auctions] + [runtime_common::crowdloan, Crowdloan] + [runtime_common::claims, Claims] + [runtime_common::slots, Slots] + [runtime_common::paras_registrar, Registrar] + [runtime_parachains::configuration, Configuration] + [runtime_parachains::hrmp, Hrmp] + [runtime_parachains::disputes, ParasDisputes] + [runtime_parachains::disputes::slashing, ParasSlashing] + [runtime_parachains::inclusion, ParaInclusion] + [runtime_parachains::initializer, Initializer] + [runtime_parachains::paras_inherent, ParaInherent] + [runtime_parachains::paras, Paras] + // Substrate + [pallet_balances, Balances] + [pallet_balances, NisCounterpartBalances] + [pallet_bags_list, VoterList] + [frame_benchmarking::baseline, Baseline::] + [pallet_bounties, Bounties] + [pallet_child_bounties, ChildBounties] + [pallet_conviction_voting, ConvictionVoting] + [pallet_election_provider_multi_phase, ElectionProviderMultiPhase] + [frame_election_provider_support, ElectionProviderBench::] + [pallet_fast_unstake, FastUnstake] + [pallet_nis, Nis] + [pallet_identity, Identity] + [pallet_im_online, ImOnline] + [pallet_indices, Indices] + [pallet_message_queue, MessageQueue] + [pallet_multisig, Multisig] + [pallet_nomination_pools, NominationPoolsBench::] + [pallet_offences, OffencesBench::] + [pallet_preimage, Preimage] + [pallet_proxy, Proxy] + [pallet_ranked_collective, FellowshipCollective] + [pallet_recovery, Recovery] + [pallet_referenda, Referenda] + [pallet_referenda, FellowshipReferenda] + [pallet_scheduler, Scheduler] + [pallet_session, SessionBench::] + [pallet_society, Society] + [pallet_staking, Staking] + [frame_system, SystemBench::] + [pallet_timestamp, Timestamp] + [pallet_treasury, Treasury] + [pallet_utility, Utility] + [pallet_vesting, Vesting] + [pallet_whitelist, Whitelist] + // XCM + [pallet_xcm, XcmPallet] + [pallet_xcm_benchmarks::fungible, pallet_xcm_benchmarks::fungible::Pallet::] + [pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::] + ); +} + +#[cfg(not(feature = "disable-runtime-api"))] +sp_api::impl_runtime_apis! { + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block); + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } + } + + impl block_builder_api::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: inherents::InherentData, + ) -> inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl tx_pool_api::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl offchain_primitives::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl primitives::runtime_api::ParachainHost for Runtime { + fn validators() -> Vec { + parachains_runtime_api_impl::validators::() + } + + fn validator_groups() -> (Vec>, GroupRotationInfo) { + parachains_runtime_api_impl::validator_groups::() + } + + fn availability_cores() -> Vec> { + parachains_runtime_api_impl::availability_cores::() + } + + fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option> { + parachains_runtime_api_impl::persisted_validation_data::(para_id, assumption) + } + + fn assumed_validation_data( + para_id: ParaId, + expected_persisted_validation_data_hash: Hash, + ) -> Option<(PersistedValidationData, ValidationCodeHash)> { + parachains_runtime_api_impl::assumed_validation_data::( + para_id, + expected_persisted_validation_data_hash, + ) + } + + fn check_validation_outputs( + para_id: ParaId, + outputs: primitives::CandidateCommitments, + ) -> bool { + parachains_runtime_api_impl::check_validation_outputs::(para_id, outputs) + } + + fn session_index_for_child() -> SessionIndex { + parachains_runtime_api_impl::session_index_for_child::() + } + + fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option { + parachains_runtime_api_impl::validation_code::(para_id, assumption) + } + + fn candidate_pending_availability(para_id: ParaId) -> Option> { + parachains_runtime_api_impl::candidate_pending_availability::(para_id) + } + + fn candidate_events() -> Vec> { + parachains_runtime_api_impl::candidate_events::(|ev| { + match ev { + RuntimeEvent::ParaInclusion(ev) => { + Some(ev) + } + _ => None, + } + }) + } + + fn session_info(index: SessionIndex) -> Option { + parachains_runtime_api_impl::session_info::(index) + } + + fn session_executor_params(session_index: SessionIndex) -> Option { + parachains_runtime_api_impl::session_executor_params::(session_index) + } + + fn dmq_contents(recipient: ParaId) -> Vec> { + parachains_runtime_api_impl::dmq_contents::(recipient) + } + + fn inbound_hrmp_channels_contents( + recipient: ParaId + ) -> BTreeMap>> { + parachains_runtime_api_impl::inbound_hrmp_channels_contents::(recipient) + } + + fn validation_code_by_hash(hash: ValidationCodeHash) -> Option { + parachains_runtime_api_impl::validation_code_by_hash::(hash) + } + + fn on_chain_votes() -> Option> { + parachains_runtime_api_impl::on_chain_votes::() + } + + fn submit_pvf_check_statement( + stmt: primitives::PvfCheckStatement, + signature: primitives::ValidatorSignature, + ) { + parachains_runtime_api_impl::submit_pvf_check_statement::(stmt, signature) + } + + fn pvfs_require_precheck() -> Vec { + parachains_runtime_api_impl::pvfs_require_precheck::() + } + + fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option + { + parachains_runtime_api_impl::validation_code_hash::(para_id, assumption) + } + + fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState)> { + parachains_runtime_api_impl::get_session_disputes::() + } + + fn unapplied_slashes( + ) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> { + parachains_runtime_api_impl::unapplied_slashes::() + } + + fn key_ownership_proof( + validator_id: ValidatorId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((PARACHAIN_KEY_TYPE_ID, validator_id)) + .map(|p| p.encode()) + .map(slashing::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_dispute_lost( + dispute_proof: slashing::DisputeProof, + key_ownership_proof: slashing::OpaqueKeyOwnershipProof, + ) -> Option<()> { + parachains_runtime_api_impl::submit_unsigned_slashing_report::( + dispute_proof, + key_ownership_proof, + ) + } + } + + impl beefy_primitives::BeefyApi for Runtime { + fn beefy_genesis() -> Option { + Beefy::genesis_block() + } + + fn validator_set() -> Option> { + Beefy::validator_set() + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: beefy_primitives::EquivocationProof< + BlockNumber, + BeefyId, + BeefySignature, + >, + key_owner_proof: beefy_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Beefy::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + + fn generate_key_ownership_proof( + _set_id: beefy_primitives::ValidatorSetId, + authority_id: BeefyId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((beefy_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(beefy_primitives::OpaqueKeyOwnershipProof::new) + } + } + + impl mmr::MmrApi for Runtime { + fn mmr_root() -> Result { + Ok(Mmr::mmr_root()) + } + + fn mmr_leaf_count() -> Result { + Ok(Mmr::mmr_leaves()) + } + + fn generate_proof( + block_numbers: Vec, + best_known_block_number: Option, + ) -> Result<(Vec, mmr::Proof), mmr::Error> { + Mmr::generate_proof(block_numbers, best_known_block_number).map( + |(leaves, proof)| { + ( + leaves + .into_iter() + .map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf)) + .collect(), + proof, + ) + }, + ) + } + + fn verify_proof(leaves: Vec, proof: mmr::Proof) + -> Result<(), mmr::Error> + { + let leaves = leaves.into_iter().map(|leaf| + leaf.into_opaque_leaf() + .try_decode() + .ok_or(mmr::Error::Verify)).collect::, mmr::Error>>()?; + Mmr::verify_leaves(leaves, proof) + } + + fn verify_proof_stateless( + root: mmr::Hash, + leaves: Vec, + proof: mmr::Proof + ) -> Result<(), mmr::Error> { + let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect(); + pallet_mmr::verify_leaves_proof::(root, nodes, proof) + } + } + + impl pallet_beefy_mmr::BeefyMmrApi for RuntimeApi { + fn authority_set_proof() -> beefy_primitives::mmr::BeefyAuthoritySet { + BeefyMmrLeaf::authority_set_proof() + } + + fn next_authority_set_proof() -> beefy_primitives::mmr::BeefyNextAuthoritySet { + BeefyMmrLeaf::next_authority_set_proof() + } + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> Vec<(GrandpaId, u64)> { + Grandpa::grandpa_authorities() + } + + fn current_set_id() -> fg_primitives::SetId { + Grandpa::current_set_id() + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: fg_primitives::EquivocationProof< + ::Hash, + sp_runtime::traits::NumberFor, + >, + key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Grandpa::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + + fn generate_key_ownership_proof( + _set_id: fg_primitives::SetId, + authority_id: fg_primitives::AuthorityId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((fg_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(fg_primitives::OpaqueKeyOwnershipProof::new) + } + } + + impl babe_primitives::BabeApi for Runtime { + fn configuration() -> babe_primitives::BabeConfiguration { + let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG); + babe_primitives::BabeConfiguration { + slot_duration: Babe::slot_duration(), + epoch_length: EpochDuration::get(), + c: epoch_config.c, + authorities: Babe::authorities().to_vec(), + randomness: Babe::randomness(), + allowed_slots: epoch_config.allowed_slots, + } + } + + fn current_epoch_start() -> babe_primitives::Slot { + Babe::current_epoch_start() + } + + fn current_epoch() -> babe_primitives::Epoch { + Babe::current_epoch() + } + + fn next_epoch() -> babe_primitives::Epoch { + Babe::next_epoch() + } + + fn generate_key_ownership_proof( + _slot: babe_primitives::Slot, + authority_id: babe_primitives::AuthorityId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((babe_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(babe_primitives::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: babe_primitives::EquivocationProof<::Header>, + key_owner_proof: babe_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Babe::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + } + + impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + parachains_runtime_api_impl::relevant_authority_ids::() + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Nonce { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< + Block, + Balance, + > for Runtime { + fn query_info(uxt: ::Extrinsic, len: u32) -> RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details(uxt: ::Extrinsic, len: u32) -> FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi + for Runtime + { + fn query_call_info(call: RuntimeCall, len: u32) -> RuntimeDispatchInfo { + TransactionPayment::query_call_info(call, len) + } + fn query_call_fee_details(call: RuntimeCall, len: u32) -> FeeDetails { + TransactionPayment::query_call_fee_details(call, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl pallet_nomination_pools_runtime_api::NominationPoolsApi< + Block, + AccountId, + Balance, + > for Runtime { + fn pending_rewards(member: AccountId) -> Balance { + NominationPools::api_pending_rewards(member).unwrap_or_default() + } + + fn points_to_balance(pool_id: pallet_nomination_pools::PoolId, points: Balance) -> Balance { + NominationPools::api_points_to_balance(pool_id, points) + } + + fn balance_to_points(pool_id: pallet_nomination_pools::PoolId, new_funds: Balance) -> Balance { + NominationPools::api_balance_to_points(pool_id, new_funds) + } + } + + impl pallet_staking_runtime_api::StakingApi for Runtime { + fn nominations_quota(balance: Balance) -> u32 { + Staking::api_nominations_quota(balance) + } + } + + #[cfg(feature = "try-runtime")] + impl frame_try_runtime::TryRuntime for Runtime { + fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { + log::info!("try-runtime::on_runtime_upgrade kusama."); + let weight = Executive::try_runtime_upgrade(checks).unwrap(); + (weight, BlockWeights::get().max_block) + } + + fn execute_block( + block: Block, + state_root_check: bool, + signature_check: bool, + select: frame_try_runtime::TryStateSelect, + ) -> Weight { + // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to + // have a backtrace here. + Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap() + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + + use pallet_session_benchmarking::Pallet as SessionBench; + use pallet_offences_benchmarking::Pallet as OffencesBench; + use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench; + use frame_system_benchmarking::Pallet as SystemBench; + use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; + use frame_benchmarking::baseline::Pallet as Baseline; + + let mut list = Vec::::new(); + list_benchmarks!(list, extra); + + let storage_info = AllPalletsWithSystem::storage_info(); + return (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result< + Vec, + sp_runtime::RuntimeString, + > { + use frame_support::traits::WhitelistedStorageKeys; + use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError}; + use sp_storage::TrackedStorageKey; + // Trying to add benchmarks directly to some pallets caused cyclic dependency issues. + // To get around that, we separated the benchmarks into its own crate. + use pallet_session_benchmarking::Pallet as SessionBench; + use pallet_offences_benchmarking::Pallet as OffencesBench; + use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench; + use frame_system_benchmarking::Pallet as SystemBench; + use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; + use frame_benchmarking::baseline::Pallet as Baseline; + use xcm::latest::prelude::*; + use xcm_config::{ + LocalCheckAccount, SovereignAccountOf, Statemine, TokenLocation, XcmConfig, + }; + + impl pallet_session_benchmarking::Config for Runtime {} + impl pallet_offences_benchmarking::Config for Runtime {} + impl pallet_election_provider_support_benchmarking::Config for Runtime {} + impl frame_system_benchmarking::Config for Runtime {} + impl frame_benchmarking::baseline::Config for Runtime {} + impl pallet_nomination_pools_benchmarking::Config for Runtime {} + impl runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {} + + impl pallet_xcm_benchmarks::Config for Runtime { + type XcmConfig = XcmConfig; + type AccountIdConverter = SovereignAccountOf; + fn valid_destination() -> Result { + Ok(Statemine::get()) + } + fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + // Kusama only knows about KSM. + vec![MultiAsset{ + id: Concrete(TokenLocation::get()), + fun: Fungible(1_000_000 * UNITS), + }].into() + } + } + + parameter_types! { + pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + Statemine::get(), + MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, + )); + pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + } + + impl pallet_xcm_benchmarks::fungible::Config for Runtime { + type TransactAsset = Balances; + + type CheckedAccount = LocalCheckAccount; + type TrustedTeleporter = TrustedTeleporter; + type TrustedReserve = TrustedReserve; + + fn get_multi_asset() -> MultiAsset { + MultiAsset { + id: Concrete(TokenLocation::get()), + fun: Fungible(1 * UNITS), + } + } + } + + impl pallet_xcm_benchmarks::generic::Config for Runtime { + type RuntimeCall = RuntimeCall; + + fn worst_case_response() -> (u64, Response) { + (0u64, Response::Version(Default::default())) + } + + fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + // Kusama doesn't support asset exchanges + Err(BenchmarkError::Skip) + } + + fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + // The XCM executor of Kusama doesn't have a configured `UniversalAliases` + Err(BenchmarkError::Skip) + } + + fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + Ok((Statemine::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) + } + + fn subscribe_origin() -> Result { + Ok(Statemine::get()) + } + + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + let origin = Statemine::get(); + let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = MultiLocation { parents: 0, interior: Here }; + Ok((origin, ticket, assets)) + } + + fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + // Kusama doesn't support asset locking + Err(BenchmarkError::Skip) + } + + fn export_message_origin_and_destination( + ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + // Kusama doesn't support exporting messages + Err(BenchmarkError::Skip) + } + + fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + // The XCM executor of Kusama doesn't have a configured `Aliasers` + Err(BenchmarkError::Skip) + } + } + + let mut whitelist: Vec = AllPalletsWithSystem::whitelisted_storage_keys(); + let treasury_key = frame_system::Account::::hashed_key_for(Treasury::account_id()); + whitelist.push(treasury_key.to_vec().into()); + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + + add_benchmarks!(params, batches); + + Ok(batches) + } + } +} + +#[cfg(test)] +mod fees_tests { + use super::*; + use sp_runtime::assert_eq_error_rate; + + #[test] + fn signed_deposit_is_sensible() { + // ensure this number does not change, or that it is checked after each change. + // a 1 MB solution should need around 0.16 KSM deposit + let deposit = SignedDepositBase::get() + (SignedDepositByte::get() * 1024 * 1024); + assert_eq_error_rate!(deposit, UNITS * 167 / 100, UNITS / 100); + } +} + +#[cfg(test)] +mod multiplier_tests { + use super::*; + use frame_support::{dispatch::DispatchInfo, traits::OnFinalize}; + use runtime_common::{MinimumMultiplier, TargetBlockFullness}; + use separator::Separatable; + use sp_runtime::traits::Convert; + + fn run_with_system_weight(w: Weight, mut assertions: F) + where + F: FnMut() -> (), + { + let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap() + .into(); + t.execute_with(|| { + System::set_block_consumed_resources(w, 0); + assertions() + }); + } + + #[test] + fn multiplier_can_grow_from_zero() { + let minimum_multiplier = MinimumMultiplier::get(); + let target = TargetBlockFullness::get() * + BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap(); + // if the min is too small, then this will not change, and we are doomed forever. + // the weight is 1/100th bigger than target. + run_with_system_weight(target.saturating_mul(101) / 100, || { + let next = SlowAdjustingFeeUpdate::::convert(minimum_multiplier); + assert!(next > minimum_multiplier, "{:?} !>= {:?}", next, minimum_multiplier); + }) + } + + #[test] + fn fast_unstake_estimate() { + use pallet_fast_unstake::WeightInfo; + let block_time = BlockWeights::get().max_block.ref_time() as f32; + let on_idle = weights::pallet_fast_unstake::WeightInfo::::on_idle_check( + 1000, + ::BatchSize::get(), + ) + .ref_time() as f32; + println!("ratio of block weight for full batch fast-unstake {}", on_idle / block_time); + assert!(on_idle / block_time <= 0.5f32) + } + + #[test] + #[ignore] + fn multiplier_growth_simulator() { + // assume the multiplier is initially set to its minimum. We update it with values twice the + //target (target is 25%, thus 50%) and we see at which point it reaches 1. + let mut multiplier = MinimumMultiplier::get(); + let block_weight = BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap(); + let mut blocks = 0; + let mut fees_paid = 0; + + frame_system::Pallet::::set_block_consumed_resources(Weight::MAX, 0); + let info = DispatchInfo { weight: Weight::MAX, ..Default::default() }; + + let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap() + .into(); + // set the minimum + t.execute_with(|| { + pallet_transaction_payment::NextFeeMultiplier::::set(MinimumMultiplier::get()); + }); + + while multiplier <= Multiplier::from_u32(1) { + t.execute_with(|| { + // imagine this tx was called. + let fee = TransactionPayment::compute_fee(0, &info, 0); + fees_paid += fee; + + // this will update the multiplier. + System::set_block_consumed_resources(block_weight, 0); + TransactionPayment::on_finalize(1); + let next = TransactionPayment::next_fee_multiplier(); + + assert!(next > multiplier, "{:?} !>= {:?}", next, multiplier); + multiplier = next; + + println!( + "block = {} / multiplier {:?} / fee = {:?} / fess so far {:?}", + blocks, + multiplier, + fee.separated_string(), + fees_paid.separated_string() + ); + }); + blocks += 1; + } + } + + #[test] + #[ignore] + fn multiplier_cool_down_simulator() { + // assume the multiplier is initially set to its minimum. We update it with values twice the + //target (target is 25%, thus 50%) and we see at which point it reaches 1. + let mut multiplier = Multiplier::from_u32(2); + let mut blocks = 0; + + let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap() + .into(); + // set the minimum + t.execute_with(|| { + pallet_transaction_payment::NextFeeMultiplier::::set(multiplier); + }); + + while multiplier > Multiplier::from_u32(0) { + t.execute_with(|| { + // this will update the multiplier. + TransactionPayment::on_finalize(1); + let next = TransactionPayment::next_fee_multiplier(); + + assert!(next < multiplier, "{:?} !>= {:?}", next, multiplier); + multiplier = next; + + println!("block = {} / multiplier {:?}", blocks, multiplier); + }); + blocks += 1; + } + } +} + +#[cfg(all(test, feature = "try-runtime"))] +mod remote_tests { + use super::*; + use frame_try_runtime::{runtime_decl_for_try_runtime::TryRuntime, UpgradeCheckSelect}; + use remote_externalities::{ + Builder, Mode, OfflineConfig, OnlineConfig, SnapshotConfig, Transport, + }; + use std::env::var; + + #[tokio::test] + async fn run_migrations() { + if var("RUN_MIGRATION_TESTS").is_err() { + return + } + + sp_tracing::try_init_simple(); + let transport: Transport = + var("WS").unwrap_or("wss://kusama-rpc.polkadot.io:443".to_string()).into(); + let maybe_state_snapshot: Option = var("SNAP").map(|s| s.into()).ok(); + let mut ext = Builder::::default() + .mode(if let Some(state_snapshot) = maybe_state_snapshot { + Mode::OfflineOrElseOnline( + OfflineConfig { state_snapshot: state_snapshot.clone() }, + OnlineConfig { + transport, + state_snapshot: Some(state_snapshot), + ..Default::default() + }, + ) + } else { + Mode::Online(OnlineConfig { transport, ..Default::default() }) + }) + .build() + .await + .unwrap(); + ext.execute_with(|| Runtime::on_runtime_upgrade(UpgradeCheckSelect::PreAndPost)); + } + + #[tokio::test] + #[ignore = "this test is meant to be executed manually"] + async fn try_fast_unstake_all() { + sp_tracing::try_init_simple(); + let transport: Transport = + var("WS").unwrap_or("wss://kusama-rpc.polkadot.io:443".to_string()).into(); + let maybe_state_snapshot: Option = var("SNAP").map(|s| s.into()).ok(); + let mut ext = Builder::::default() + .mode(if let Some(state_snapshot) = maybe_state_snapshot { + Mode::OfflineOrElseOnline( + OfflineConfig { state_snapshot: state_snapshot.clone() }, + OnlineConfig { + transport, + state_snapshot: Some(state_snapshot), + ..Default::default() + }, + ) + } else { + Mode::Online(OnlineConfig { transport, ..Default::default() }) + }) + .build() + .await + .unwrap(); + ext.execute_with(|| { + pallet_fast_unstake::ErasToCheckPerBlock::::put(1); + runtime_common::try_runtime::migrate_all_inactive_nominators::() + }); + } +} + +mod init_state_migration { + use super::Runtime; + use frame_support::traits::OnRuntimeUpgrade; + use pallet_state_trie_migration::{AutoLimits, MigrationLimits, MigrationProcess}; + #[cfg(feature = "try-runtime")] + use sp_runtime::DispatchError; + #[cfg(not(feature = "std"))] + use sp_std::prelude::*; + + /// Initialize an automatic migration process. + pub struct InitMigrate; + impl OnRuntimeUpgrade for InitMigrate { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, DispatchError> { + frame_support::ensure!( + AutoLimits::::get().is_none(), + DispatchError::Other("Automigration already started.") + ); + Ok(Default::default()) + } + + fn on_runtime_upgrade() -> frame_support::weights::Weight { + if MigrationProcess::::get() == Default::default() && + AutoLimits::::get().is_none() + { + // We use limits to target 600ko proofs per block and + // avg 800_000_000_000 of weight per block. + // See spreadsheet 4800_400 in + // https://raw.githubusercontent.com/cheme/substrate/try-runtime-mig/ksm.ods + AutoLimits::::put(Some(MigrationLimits { item: 4_800, size: 204800 * 2 })); + log::info!("Automatic trie migration started."); + ::DbWeight::get().reads_writes(2, 1) + } else { + log::info!("Automatic trie migration not started."); + ::DbWeight::get().reads(2) + } + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), DispatchError> { + frame_support::ensure!( + AutoLimits::::get().is_some(), + DispatchError::Other("Automigration started.") + ); + Ok(()) + } + } +} diff --git a/polkadot/runtime/kusama/src/past_payouts.rs b/polkadot/runtime/kusama/src/past_payouts.rs new file mode 100644 index 0000000000000000000000000000000000000000..2d8b67902b89184867a3f35b651ca8e37425204d --- /dev/null +++ b/polkadot/runtime/kusama/src/past_payouts.rs @@ -0,0 +1,312 @@ +// This file is part of Polkadot. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::*; +use hex_literal::hex; +use pallet_society::migrations::from_raw_past_payouts; + +parameter_types! { + pub PastPayouts: Vec<(AccountId, Balance)> = from_raw_past_payouts::(vec![ + (hex!["04152389a92e4356ed03ed30625afba062b9c4496116cba888e89f347834a31e"], 89000000000000u128), + (hex!["0483de2b96cd3756f05301eb1bca875166ae5be67a81f86a1dad152bccad6909"], 54666600000000u128), + (hex!["048a62b89589f7573c5f80584de850b9c8bcd4cb7a8766948d3db713d8a57204"], 83000000000000u128), + (hex!["060e1eacd9f4460ae43b28d39e472078784482139e483307436344019a48f26e"], 15513300000000u128), + (hex!["0ab0b61984dfcfe2fcb82147f0a2f00f992fa8a6b5ee81490387f8210a1ab678"], 6766666600u128), + (hex!["0c6e31c65ee1e82129879a145eb0c0d4de45e60c3dcab1d2219628cd70673a6b"], 69000000000000u128), + (hex!["10e9e630de91310a60b0bc7a4a2303a60b703afde9239750921514deb2655a0d"], 54333200000000u128), + (hex!["162eb21266fef25e25eb8286994264450b8c80ccf2911967cc42ee4cc55c2061"], 14223300000000u128), + (hex!["183f8c4d5084d96816ae7d82d44373b99bb134a16845d1589df4467671e3b56a"], 23333300000000u128), + (hex!["18b2624ddf0eca6c9698496801dcda614580367a4d54833fe75bbf54a9a09966"], 52999900000000u128), + (hex!["18b44d4c64c3aa3fb20d88b016a412d8f27000912fa7b350ed270ac8f55b3a27"], 5135000000000u128), + (hex!["1aa23df47ab442adc15f6c923cfd0f6c4255b2cacc19538028685e37410a691f"], 54000000000000u128), + (hex!["1ce0527c225ce227c1cceed0317eae0817bd600be3aa87489a704678c95a5451"], 41166600000000u128), + (hex!["1e20318bd5c0bc44576955b7205354b8ed9c8e4a783ba9da70d5cee0e11b4740"], 11000000000000u128), + (hex!["1e6fa8ff46b01fe3b8c52ea50a5ab61313ffac31393a28f621625840a6b3776d"], 11556600000000u128), + (hex!["20243c6b74a5f83b89ec202a337bd06ebc985fe7b1557184bfd012dc9bc97873"], 13000000000000u128), + (hex!["22cabf36e0954f0c013af666e27e46cb9a41f7a0db46ccec245f43b5ba438452"], 31000000000000u128), + (hex!["24172a563943291c97d252def71e17abf467a1626bca358728a90a82b3de3118"], 200000000000000u128), + (hex!["247f22a3073d04a85ab417505bb7667a5941ed74cfa596dfc7402813198a0560"], 68999000000000u128), + (hex!["28250c422851313e923c89cc0a41fec2af80cc124290343ae250f77ff60d767d"], 6993300000000u128), + (hex!["2c709012f807af8fc3f0d2abb0c51ca9a88d4ef24d1a092bf89dacf5ce63ea1d"], 333333333332u128), + (hex!["305b27652a4dc8038c587df4cf1d7758b413fe18a97b3a3a5c7d609f50092e11"], 39000000000000u128), + (hex!["3063796fb70f0bcde597bb7ed4d50f6ec7755686c894c7dbaa1ea2e33103876e"], 11650000000000u128), + (hex!["325c848b9000d5430844bd5486d34d844acd89e11964ed1b535bf45557e1c87f"], 10666600000000u128), + (hex!["3a632ab63a0ec92f1b67af756a49c8849f5722a345e54ef51cb294bef569070b"], 14993300000000u128), + (hex!["3c97e1879015dfb64a367e0f0eb32f16968fb6be6a48da7de7776bc8953c854d"], 18149900000000u128), + (hex!["3e8eb90cd422b7d72f166f135ed3db2137d0d9216e14cfdbd0ca75d2a18e2235"], 83000000000000u128), + (hex!["3ea89a71ac11ea023bf42d9d6215a9d8c775e626a2ee38d574b297f42c58a622"], 15056500000000u128), + (hex!["402d95c5f6d37ab03ecbec4628d290b2cc7571ff790ee5757b21bbcba4108924"], 12666600000000u128), + (hex!["40300fe00bcfb90f3ded42dc082b775dd9a8a8ea491261a262a78155a069a268"], 112000000000000u128), + (hex!["406855a4bb07710384d3876cf37cacbd66f2f1dab2346ebea130b00f63d0d317"], 83500000000000u128), + (hex!["40c6e021d4d80b9b38d850b1c5334ea88b2bcc148d07e83f5be1b45b8ceb3740"], 9893300000000u128), + (hex!["40f8a816b07bd23e166d2e479cfd5a3e5118f3937230ca5088eff9e33c84b552"], 12790000000000u128), + (hex!["422286e0da2fb826f04e46d2f6ef1319a43412261d0f8d91274a81eee21af24e"], 69000000000000u128), + (hex!["484a648ebe737d7dbee39d8e169d5ded94d29f70100e4d3ee87162c4a8bbdf73"], 2483300000000u128), + (hex!["4c4a2f66cd9f5000968f0913f01ac1181ccd2db137d6af152252ee3de689450b"], 2000000000000u128), + (hex!["505eb7820f60d0949697617b2f3366bd616d8c7e96724aa681e0113f6bf45c46"], 898900000000u128), + (hex!["569f5ab70b93bb40ecb5a8888bbbc781c785ac3709863e9866422f0fd62f2477"], 8000000000000u128), + (hex!["5c1be3d517926a6c194d42131d996140f3e8d7398764423cab176341b882ee7b"], 8490000000000u128), + (hex!["5c32313c22eebc15ecf28ebb75ed8e264d53e50429a5ce09ed3a86e72732c56d"], 5000000000000u128), + (hex!["5c436629095023be4d2ed2120002497bc18295fb485a11e83e529e617412626f"], 6999900000000u128), + (hex!["5c81f3afd924f4cdd7c151d539c7abc3cd3de33eebd59403b81b568b8efa2d3b"], 15000000000000u128), + (hex!["602d798e4d6f076cb28719b4bc757645ff0894a591173bd923bc8cb631fdeb0c"], 201660000000000u128), + (hex!["621014fccda62dbd21d32b3628691f68cecafa887a62d641ba8876e3e7e4c068"], 8000000000000u128), + (hex!["6613962cf897114a56ba84bbad47f52c46dc56960aae8ccfc71805cfc3fced19"], 32666600000000u128), + (hex!["662ef2fa0d3a90f1f9691d05daee187d35fb17482cc72b3e03922358d0bdcc6f"], 10000000000000u128), + (hex!["687b7e0289f5d116a2b68cf9d0496f62de37e579ea777ce39d81471c09ec142b"], 275000000000000u128), + (hex!["688de40f61eb6ecc19b4c3702267c0bbf052ed9ee843ff6d346d765f89ed6067"], 7000000000000u128), + (hex!["68fae6be10c90d572388d42129e074005005baf68d116a993073c5648ec78865"], 6356600000000u128), + (hex!["6a8cafed3a670189545d5b242aec4d52bb4fe90f5af2f5984d8a14eb44713a70"], 12780000000000u128), + (hex!["6c64f0ac3b73174aa0b0cd935b5576611e405c8485ef13a0be8bf2ea3a48da6f"], 8000000000000u128), + (hex!["6eb31a06ff9d943b174f683f8327e3b4847a02e197e951f01ac7759b4c102f10"], 52333300000000u128), + (hex!["6ed537e76f1ef68764d7544cd7a8be19cbaba2ef8af181090d281d80105fd963"], 175000000000000u128), + (hex!["7241b3a590243df346a79a2d0ebf79dc990f07c1c499145d0424f3769ca4c826"], 81000000000000u128), + (hex!["728ea7cd638962b92ec6405e7b5572b67cfbc96c7c2fc7becf4cddb22b50b02c"], 11890000000000u128), + (hex!["7a91a646fd4d7592aabed6ad7f3c1d9f12371f200ae3d644454c80272b8e8c14"], 44000000000000u128), + (hex!["7c9ae158bf660dbd429592d055efe4897fad8a07c4ed61accd1861380c5c3843"], 24666600000000u128), + (hex!["7cb95b196a81bb0b7952e94ff0624b9b1429e81bee0f03c8bf2f3cea5213c611"], 5805000000000u128), + (hex!["7ec0c61a682519e78e65026c51ceea52273870636814605a33518f02ad543317"], 6969600000000u128), + (hex!["802c32932fca84ba9c80d57e4b0ebccc8404ee75a346ae0b50a17666bb38c01c"], 4986600000000u128), + (hex!["806369b4f04792b7bd1a0d8586b7aa528591ba732362e3fb3d52d7b01e741b18"], 8660866667000u128), + (hex!["80a551df4b4b67586a512356fc0e513d641e39f62172d185465dfee61e67143a"], 15160000000000u128), + (hex!["821e24cd21f1da627bea7b7077d591b9c8a48f93dd87eb7f3f1ac4ec512f7b5f"], 7500000000000u128), + (hex!["84c62d27805ac9c7a62086e31dfae23703ac9dfb37fbd31bec95aa611c5d2c33"], 999666600000000u128), + (hex!["865facd74193d96f1b35a702efe05116e7be752d77f46c7fe4720905728ccb36"], 6993300000000u128), + (hex!["88077737732044369dc52dd7f7bf400cfb493a219f013fbfdd46f7cd52673d6f"], 67666600000000u128), + (hex!["8865278958eaaba42406d1ae16545267c944113c216fffc386edb4d6a8cffd36"], 5000000000000u128), + (hex!["8ad06fa44a5669702a29b394424560714a1af90ad9efb57f3864b93b1ff7961c"], 100000000000u128), + (hex!["8e7215d5218f170d0865fcbe16b2ceb752db7e7bfce3f3d487ecb60e776a2c36"], 39333200000000u128), + (hex!["8ef7167c4d50be846c6a03591e13005fa68ef858d87321bb79428b121e105a11"], 9166600000000u128), + (hex!["90bc6fc1133c3df447222e89b5ceaa028b69348ee381385239377b31df275248"], 15000000000000u128), + (hex!["90da58a51d922ae69f27d8020d52e2fc71a5e5af1b63571bae81ddb87f8ff424"], 6696900000000u128), + (hex!["92af8236baeef25f6e85ed30d85b758f5604c5c4c4c3637657fea1946a3da61b"], 13000000000000u128), + (hex!["969fe4cba88544e8d3d71f31790cc1d377cf85a89e1b3d03e7a8b932aed1d312"], 84000000000000u128), + (hex!["96be4635aeb775be58f3c0843bd8bc1832d257e56905525dcb3d38126d8f855e"], 12166600000000u128), + (hex!["9822df7da6d3c119f5118587b29eaa30aaf00839e2a03161c2df4222a0d8744e"], 8999900000000u128), + (hex!["9cb774a6051717a844657f0c037a93173f70afc000babd2f7f0be7d1e8475436"], 9000000000000u128), + (hex!["9eb27cde65b09610cbe8a3d3b82c6730f5a5dd51aeb082fdd74236c4765a040a"], 8890000000000u128), + (hex!["a0c6e8d74992d1ea3e43081624b2cddbd98b50d7a75998662ce6adbb2290aa64"], 175000000000000u128), + (hex!["a2b8bfb3c0c1f04346134e7b27cb5b63de8a7af0d57c502d09c05ba7b3dd1e28"], 9326600000000u128), + (hex!["a415a980463876c54b503c358613b5c02d8ac9781c13378797c54ab37fc07c05"], 8666600000000u128), + (hex!["a48539457aa2e54048493ccaf980be18253d8cabd6eecd295e6b62e6a357352f"], 8879900000000u128), + (hex!["a60b82ce304c28aad744e2a95924b3e1e560803a75e5a39fc91300556e9a9538"], 83499000000000u128), + (hex!["a673009c77c4734fbc09f3bf505e3414282f714e89688ca3fa9292921cb7e51d"], 93000000000000u128), + (hex!["a69f19b16dfdfb01b1d480c59512b0d589e600538cd9102de9619ef419211f1b"], 11993300000000u128), + (hex!["aa17e09d3e9685a53d52d5123cc7f4f6f9fc7f3ab34f268a6f8860de68f2b612"], 15000000000000u128), + (hex!["aa893ab408a0c0b8bb175ed7fa2b042e0fd30915e6ab8f66a9ac524e552d167f"], 11480000000000u128), + (hex!["accd5106f4794d9052617617a993556b15c6e62859282bad7edb24592d728a69"], 94999000000000u128), + (hex!["ae4bada5af908d3bddd0cb7e250d38da99cf9d6508a6b1118a89dc59fb372a4a"], 17000000000000u128), + (hex!["b2012e8078883fdd9693d75c90bb669834f7b2c302def049e6eb486e56dc7365"], 13500000000000u128), + (hex!["b2fa9763f56890cabe29a1ea971851a3234aecd03584c44f822e036fbd9c5156"], 8554600000000u128), + (hex!["b8a750597d770430e4f9771829cf964825ea6750a6229deb06dc515371c7033f"], 96600000000u128), + (hex!["ba8a15ff06ff808a77b93ad335884ac66e3744a5cea908f8b8a865d98a934541"], 21333300000000u128), + (hex!["baf98d06056833e2e887c85c938aeb1c31dff74a91d35d9863327abc8ec93f4a"], 7500000000000u128), + (hex!["c2487c00d0e309fdb96d1e0ed7bb2da173d777b3ae26b25c1369992add25972d"], 21000000000000u128), + (hex!["c2fc6a3cc910e05c508c8b252f32c6df760858d12c6a636b256135e966edcf7e"], 9715500000000u128), + (hex!["c443922426297f4ded0e635f0a92b8e31823b2e6893398b1e8351c34a728fe34"], 6493300000000u128), + (hex!["c4f4760edf86fffa05380f31bf047c72837cccfc684d9dd9b1d7fa4e3503ce51"], 14500000000000u128), + (hex!["c676a26c89e3be0451afa1126516b8f88b3da99511aba215ec99707ac5f08e3c"], 14833300000000u128), + (hex!["d25af2fedd4eb672f218932fde44f97f10c1d7788efd0079957ffad4f186ae78"], 100000000000000u128), + (hex!["d4610b986b4e4cb505ce0003142df98f803b7c3413acc9f7805992dc2a00483c"], 110000000000000u128), + (hex!["d80cb19a68fb4ae325cd0209e8563cf3d5ff0368e2ede5530940f29371a02a25"], 19000000000000u128), + (hex!["dc8f45881886ba4d2e2409ea49661b14a29a72e64d7a59d98465a9cee8084107"], 34666600000000u128), + (hex!["de3898d3824e41435b6519f2095d25af51954af6be4a946d5d2df46df3ea264f"], 110000000000000u128), + (hex!["e2094a5bcc479f2e6c83bfdbc88fe3658b817522ba1fb240f804b131ffa81600"], 41000000000000u128), + (hex!["e27bc8259449251380d0b6c848cd607b12a09b0fa8fd8875ae3f6eea70c3fd69"], 1993300000000u128), + (hex!["e45c09f0387a72f3a1eeb9e1a8f23feb738bc48d56d99ab88c8a910807c48a0c"], 18646600000000u128), + (hex!["e62321ed84ec54791122f2ec72e9e36d3cb336ed358d6848a65b8410b405650a"], 9216100000000u128), + (hex!["e80d8a511c20f08d8abbd69f1258fa27c28181ffa8fbee0989f706e7b6c48b21"], 9000000000000u128), + (hex!["ea53405eb9054ddf0b6b82de940a4646c70cb815ba4c4616394fe0488030bb32"], 72333300000000u128), + (hex!["eedfb6337bed7b15d7a0338820e8a4981d96fe7284e444885c7f478fe649012f"], 14566600000000u128), + (hex!["f20f603b0314b04a4c3b295cbfc7b53c11370cc0349ddb3cd32c91c5b416fc51"], 7493300000000u128), + (hex!["f4fa6e013f0a33b809b8c1dc8d73c1461407a474106f5def66c109a3d7c4f556"], 56666600000000u128), + (hex!["faaede0e8cfb95d55e325e29a4737decb4a20960a525384003248c5610405b7d"], 1893300000000u128), + (hex!["fae2f8b2e08e32c333e0332b4254119241c2f15421846b76b693eba714b3e571"], 20333300000000u128), + (hex!["44152e29de73d969a8d5bc6d0b3497f31ee7e7f6e01722a5a91fccadd6bcce76"], 14900000000000u128), + (hex!["4adb5df8ae7001c508d3e630deda167bce1760aa0e7c8544a1e3b70358ac3b45"], 15900000000000u128), + (hex!["f04581f47bc54daf59437fe8a8e7e76ab3f034d8b30f3629652a6a013f7e0b38"], 13986600000000u128), + (hex!["9c107fbcac10f60dc1910e27210283c39f8d5951816f8d7c8f5f96d0c71dbb29"], 26666666400u128), + ].into_iter()); +} + +#[test] +fn check_addresses() { + use sp_core::{ + crypto::{AccountId32, Ss58Codec}, + hexdisplay::HexDisplay, + }; + + let payouts: Vec<(&'static str, f64)> = vec![ + ("CffzJo8UPWwvwPF73VcbEv4jSG4ckvGwNePL9V52hYh743X", 89f64), + ("CgEt8AwW9SThQXpLBAZy3MpKgNG7ZHaEDGeV5MLqHVPVoJg", 54.6666f64), + ("CgGpRVgE8WXd2hjc3GBVxGpnG9KpjkvEGNkM6AAaCBmhQY9", 83f64), + ("CiFzvmP1wyXB8nUHh6rA1j7tFQFBx2akg57TwdTGjRAXicm", 15.5133f64), + ("CpLVRWcUd7PxDPSmtXwQC3628dwEYiMd3GbqZTnqvphMN3B", 0.0067666666f64), + ("CrcpvEZP2Z82iYFUPConih1t46VFwttrX7Tv19NW6hoCzKG", 69f64), + ("CxVmQoEyZKimVp3eMgtNHSwiFrEU3gwF1NGNPBo2gUNSr1g", 54.3332f64), + ("D5QSdd589pFWeJm9bz1j3RTyy14ejKpnUKyEa4GBW9kYkVC", 14.2233f64), + ("D87YYjk4agajQXHr1VyiW1qpzfm5QV4L8bk7XduhimVVS7H", 23.3333f64), + ("D8hf8DjZ2eb8X6cyNAYx14fRa7hVUqB52ejx5YNc2ed81gC", 52.9999f64), + ("D8iEArcApNbkH9BxEvc2AfLLWMD1sWS9F2XdRXyY9J6QDpi", 5.135f64), + ("DBExZRq4qoK8xiZaHTR7iP9tWmQ8FL9JSQG8DLyLL8yV2J8", 54f64), + ("DEBVjNhPic2eVBw2y42xJpTJfCSvDXXA6ibs7MzpXp2s2hj", 41.1666f64), + ("DFpWz9jGga5ZKcRghQGchhMhSHURUcUc2TaT7dMB4pQhkeB", 11f64), + ("DGE8ATd2NaitqX4jdvZNXFNMmY9Qui6swnfoheCiz7efWGG", 11.5566f64), + ("DJTpC2pbDJeoJ2CTHSQBurbkbd9ZgkD2WYNDtCmJhem3swh", 13f64), + ("DMwNfM1mwrraAoSG3LSnZcwGzuUcKipqYmRsFeCuvTvrdgL", 31f64), + ("DPe86fQfixDTfejAiEJbRt2mvbtcGkWdGXsyCFDu37iKYVu", 200f64), + ("DQB1TYcr7dw4UsHaNbNhM2jtyYaoQQrBoWS7jLb95D39XGb", 68.999f64), + ("DUxSQ29BxeZWDXin4jZN7ogArgxJDohyeuKsqY83WqPhT4h", 6.9933f64), + ("DaViizibrmJZwyUchRMRebv5YMXadS4PbYBLuZhbfMTtxPm", 0f64), + ("Dab4bfYTZRUDMWjYAUQuFbDreQ9mt7nULWu3Dw7jodbzVe9", 0.333333333332f64), + ("DfitqjAjNxJykJYaigWQmSRw7T847hfytxwVRuAwscdtYUh", 39f64), + ("DfmNCWtsVSG9D8KWazZ84VdkSVgxot6989W1qL7bHEAP7SF", 11.65f64), + ("DiMPtqB6HeYpYkjJJKNR6btJjmUNeG8yyhSg1N8UL3st5Um", 10.6666f64), + ("Dikw9VJqJ4fJFcXuKaSqu3eSwBQM6zC8ja9rdAP3RbfeK1Y", 0f64), + ("Dtskg3rQsxSpxxBG4pJYjTujm9fo48Q7qnEYtBfJ6UDqtSS", 14.9933f64), + ("DwmWULE1g84ZMYyM4du8SmcQCkuz7VL7C6GmaWKoRXSG6vJ", 18.1499f64), + ("DzLtEdo7ScPi1o3izPETynSm9kdXJF8H1Y68b3eFbsQUgm6", 83f64), + ("DzUa9PynyTKBEJ9Yjk27o44aav9XaJG8p57YHKVNaorxbZu", 15.0565f64), + ("E2U89NfSnVCmY3hBQHEdJ9KV6shd6B8h4EWkNLcSJCPRAk8", 12.6666f64), + ("E2UrpeDCGs2mb9SZLzAk8E89yWaZncAvjFD5VnbYbDp44Xo", 112f64), + ("E2maNj3d7YZZhpeUwCGGeThD7JX2zk1W8AUQ1Rqb2K9oDBR", 83.5f64), + ("E3FfH6nbxCwQ9bg3oHAmBFpS3qEtWLbQ4QV8XUqn6qQaaab", 9.8933f64), + ("E3WSzAdgZtu3o8NjTJdwweJjpmSGwcf42pZAFDR7CsNTrrr", 12.79f64), + ("E52wAv1fTdLGUNR4CNSbeCmj1yNUeSFnj1CPKbRzTubt3YU", 69f64), + ("ED74i7eA79DtKFu5WXbcLXLWT2E1XSDEdJSAEkU3ePN7LE4", 2.4833f64), + ("EDQWMYr6a9aLjTbsMtKFAcoUsVA6qvm66RJsyJsNgbpxCFx", 0f64), + ("EJ4FuvmVpU7Ri2GRMtQVhhfHsHzGLYngbKJzJ58RkmRrzJm", 0f64), + ("EJMCExEPNyuq6EofbvwD2ErZKwuZCJVTFhiDcDwuW12c187", 2f64), + ("EPhV6vifCet2sJPPCNGnUZdRhsQpfcsbxRvDkjsMPPCCvwR", 0.8989f64), + ("EQ12pCgs4H3XHgDTc5n44xfXo6WNNkAg33b4aDFv3eUSgZd", 0f64), + ("EXtySo37DkJUdQb5425KGzUCG8ecYL4nVkcNB5XZpDQPH73", 8f64), + ("Ef6D2jpq92FoX8wSKihodFCg8juMjFu9CBnMwwBQDbYi4XU", 8.49f64), + ("EfCqHrWEwRnRq2ekmTmWvKzYwKtcgD4uaJAm3T92wx3ekUx", 5f64), + ("EfHwkqXCDup8Hi7DVWsPTDQoGiaW55HXgbQV3XzVSCEu1ii", 6.9999f64), + ("EfcXWwDMt9UoYhj6KRfEA4NLccsZK2eQ2AFpGw4EGatNwcj", 15f64), + ("EkRd7vCKiDZi6BM6tHKs5YAeGmE3MmQgChrrbtkRkf6SBwW", 201.66f64), + ("EntzFKky1rX9oYWzEiv4K4D997XGtCH9BHCmairrXhrW2gb", 8f64), + ("EtADjuauj4ETanscktz4jpejZdkCMVPnRxKos6AwgpzLdHM", 32.6666f64), + ("EtJMBiUVsHm3bwfMhWksQ14mv1P69BHjp7ELYDWdqXynR6K", 10f64), + ("EwKBYgaaELEEB5Vm9QAgArinAtps3dRUmb9bwBVTg5HqvxJ", 275f64), + ("EwQeYkCGQtBHMgKvNZ7NZ9Dy9tqKJDqN3DknJm5XF8czbYB", 7f64), + ("Ewy2kju7jdqBFbp95Nw1go31KyiMHS9rRVaevGkM62F1btd", 6.3566f64), + ("Ez2PN6BKn31byeQTrTBqP6MAv4WF7eKF3J8UXXxaaAd1Kuv", 12.78f64), + ("F2Sg6L8dTASXBz4rn9Rv4xsfaCKPn21pDzAX9HSAR8krMzR", 8f64), + ("F5TzLdntQpfz5RXcqCqJM4NKrjS7jVnAcNRKhu5FpLLWm2i", 52.3333f64), + ("F5e8A2i3XZvA5jZTYmwcUiHzVsoTAhJDgMxZEnsFe8dq2VA", 175f64), + ("FA8VcXg8Yzg9RvVrTdhcKk5JLSH1hcwrS9fr7pjFraCRWcm", 81f64), + ("FAXMVgYUWh6s2SFaX9h33mrjXXeq8HTcNwFHEy9D1eimrLK", 11.89f64), + ("FM2dJMRnBkbJDbdtqhRpLfgRbwJBkiw6iKT8u6UJ7pojypt", 44f64), + ("FPhTtxHSTKZM4fTndfgBSSXyTpdMkpEnqojAvGTS1c8hv9S", 24.6666f64), + ("FPrWyj8aDy3dofjmXZE5mx4o6Kf82MnEGGpjVEHjH7khReo", 5.805f64), + ("FSWpLozBJnXdVhE8t7LXYEpBybwse3S795WYFKiobhZWKVE", 6.9696f64), + ("FUNmzDNdzWtXK51EZmwbDJXQALhcYGCQUeo8E4rtcx9QBX7", 4.9866f64), + ("FUfBKr2pDxKrxmExGp4hjU6St4BDgffzKcyAqv6pruGnez1", 8.660866667f64), + ("FUzksiAhxzSvvPqiYvUEwK32rFf6Fmyug9GZEdbMaoLmwh5", 15.16f64), + ("FWvhQBV91wrvaqWiqDZfq4QPYYPFS28UV8zNgeJYyUexxXm", 7.5f64), + ("FaQi6AhM49SdjBd7oZJftAPE6tt9mrH8AdySztpYUU1B6Vq", 999.6666f64), + ("FcWMb9VtQutzQ5hxguyQrWKtN28zaXKuXLbL3D9oX6AJbiC", 6.9933f64), + ("FcxNWVy5RESDsErjwyZmPCW6Z8Y3fbfLzmou34YZTrbcraL", 0f64), + ("FegFL7hjGtjwRWvDMabMuPFGTzToioEWu4BLxjRxYPfvCpn", 67.6666f64), + ("FfA5YrMeaPzBYB4rE4JBuauXua6BEAQoJPTd8dRCLCdRdhM", 5f64), + ("FiL3XNxVpx5Cgnh4WPpPWms5Ed9tGqA44YEtHVDyPacHVGt", 0.1f64), + ("Fo6D1N9EjneyZYYPGxiW1WNKsj1S9Gx1nxcrMCkKGQ1bwDM", 39.3332f64), + ("Fomib3HNL24Cv6CbLJUf59yDF5shGFyDg8Wx7eGtmDdwrRF", 9.1666f64), + ("Fr6PbzHWKrTvmFJmiYy7MD1iaUpTKHN91VS5iQZZgo7BWCw", 15f64), + ("FrFGwHJKqLTyGDwqWfLgGYFDkjP12yAATQuh4oNpZMhpFzM", 6.6969f64), + ("Ft2cSCw4V47d2S7V9nN2S6V5ByGmAnkfbkFbWUVuHVuaMvW", 0f64), + ("FtG8FbxJXfDj6fcGp3eTL9tKJzkfqT9k8PREKXDgKmbnSDR", 0f64), + ("FteeR6d11cvmoRUmvoBeYYHNpMd5onPnpGy5PUcR6Vo7dJX", 13f64), + ("FypCVBt2MU61ZVL3N6mePXaUXrFX9nvGK6h5yqR89jc6JeW", 84f64), + ("FyyDvxKBmKr81HwQWtbugiFRiu2P1JpSqBDid56AfFevuTV", 12.1666f64), + ("G1o9z4HVf2pW7bbyKKNRP9MnmGEN4n7Ada3yJRpNzaiPoKd", 8.9999f64), + ("G7oV7X7FzJJ2g8TetMvAaC4GvM1ZCzPCnfSk5KcnVy2PJEF", 9f64), + ("GAQ75C8zHzVjWJLDH5PqFbLxfyck89wLJkhCzMZTXBFV5L7", 8.89f64), + ("GD8GVB4Ai4uCSzMCiX6C4vuY4DVkBctQRT6QMqD6y5mJfr9", 175f64), + ("GFgA4KV6Mm2TsHwEYtXfXZCf6QzebuN7c69UJGcRF2vCDTD", 9.3266f64), + ("GHTohCLUcLyB8w4xMr4TyDkvUzDnim6fadWfJ7edPke971d", 8.6666f64), + ("GJ2wraBjTtXH3m2TUxsVEc1bQdiuo6yiZUfczsws19uioX9", 8.8799f64), + ("GL2tM9Q6KL6XxMEWBg5jdjLezP4EzYsh3bqR1pjTmwDY1Mf", 83.499f64), + ("GLZdTryDdiHe3gVwFdncm2a6pKN6EiMxTGJQFHq5RxcNJZt", 93f64), + ("GLnjFi1U2jk6hDs7HCL1Y8XHsVLPHd2UAQh3AqRgpcUAUcn", 11.9933f64), + ("GRLkXUQUNqQMxKnNH1cM5TvWmu2H3yxGx9ohvJXSxRHUyJq", 15f64), + ("GRvRXw8jB2H9EGojmmjM4vZCeofuu91W2Zpbtr2QC5f7iLb", 11.48f64), + ("GUtkCnQKsVXzjqJvSZkiHtvdwZoEyukZrDE1iLTyV8F7tH6", 94.999f64), + ("GWrL9KsayVkniG2GmkYoTRDaFHhpTTSf6fL25e623bHVkRt", 17f64), + ("GbiPhuH4m4BCYiiLpqo2S2TyFxvgpfdSKWMdp9ZrbKdtXeM", 13.5f64), + ("GczUwD9zRdzJnTCr9kyREURmVeYpZAg1wNWrZMjqqimHcds", 8.5546f64), + ("GkS2m7UK6RSUkFiCHYPRtp8GCKdPtrBwP1wj7448gWoiut8", 0.0966f64), + ("Gnh63rW5fy3FAbnZQPkajyrQXxQGkg56Waoe2Ede1RjRjrJ", 0f64), + ("GnkMTVovNUith3JMaN5yvpuuwPzVeFbjM15wzg6LrAQSN6P", 0f64), + ("GnuSjJqE7VWMUGYsEEqsMioXwzNXfhu7FPMvdfKCiVazJwD", 21.3333f64), + ("GoUZE6g169BskxYVFV6prDUN4siKxa6Mr8VZD8B6TU9MEtX", 7.5f64), + ("Gy4LfGahVbR4eM8Sj2aCC4hHFk4fbUWGZCWQV5pjSGwJRZb", 21f64), + ("GyynnvzZzcJt24FQ6DNNg77Mgbfe8ddLdUiQG6nssoBVpmE", 9.7155f64), + ("H1eyZGi1DKxTGdtM8UQRA1RGEe6kGhvKC4onRpy97qKqiPE", 6.4933f64), + ("H2ZXJi5QAVB29d48oWgM1oBAmg2ngiofft4yEeyq58pViwt", 14.5f64), + ("H4YEv9v4DzU6WJsF2pxSHGcVxZEZDS761XWYsnRKX7P3aMQ", 14.8333f64), + ("H9eSvWe34vQDJAWckeTHWSqSChRat8bgKHG39GC1fjvEm7y", 0f64), + ("HJHs8fpzT916HTQgdGf6s69qp5zwNmZpTTnGXmm6qNqaQyW", 0f64), + ("HL8bEp8YicBdrUmJocCAWVLKUaR2dd1y6jnD934pbre3un1", 100f64), + ("HNnVpuhqgXRRDL8h4H39EgvvXtVYEtFSPi1XBWHcEW4cEYc", 110f64), + ("HTbdbMAMsFkUVeoMQ6pbH341DgQ1a4MpdCcaBu5N6uShJBq", 19f64), + ("HZWcWK1Px51bWgu1BD5d9M6A1djczFsdRWVwhVpRrU6VUJH", 34.6666f64), + ("Hbgxh54N33ApEZrpnYGhhvPJNYWD5LNprZodPVnSHq7QDDh", 110f64), + ("Hgh6jDVF9SXHs5pw6TfAXMWj4qHXpU6Q4dXh7h8zpx26cdw", 41f64), + ("HhH7NMA7FEkj327ZktSzkthknuQU591tLr1vX8zuc4E4JkB", 1.9933f64), + ("Hjjn1CmyGWKCswCmVZJFTFMJkruTtgeycEmvR4rWJYU7izQ", 18.6466f64), + ("HkRdC1w5XDvQQadAS2nL58mPRBCLyUCZAAiaV7DUWJgj7P8", 0f64), + ("Hn4y5xom4rBD49e2eMTpsEbqAJgE7uSR62VGLVv78ZqCuxT", 9.2161f64), + ("Hpaecetm5cBAJYDVqN9VeFUgVNQh3AAJAqUKAFW8PZGRst6", 9f64), + ("HsZTGLU5foma6bWoC7BGAs51aRu9TNc2RKRQBcfaHhJES1z", 72.3333f64), + ("HyXNSykBLZFMK8eAdys5L97ncetUhnStnLKMpuSp7kM9bCU", 14.5666f64), + ("J3hg1qmm6VeU6WWcxGQnKaMnD8wYAxnFQwaysE7RhVXbNvs", 7.4933f64), + ("J7XbTDFU4SRUaW6t6mYiK4tzDXtguhwa5ZK13EVCE5F2qak", 56.6666f64), + ("J9c2fcmRhhNaJAxA8yLMkxap7PEWuYc1UaaTqxunfKscjG3", 0f64), + ("JBfNxpntp7DaRM7pzg4XEm9TYX3gCaAVZvwgZW25ZzwXjy2", 0f64), + ("JEzQAbxmotcDNAXFFgcDcjgEF9gbuxaxer4bhGdKEfQqyRw", 0f64), + ("JF1SD3o1qZFdLBWmKTRHcHgBsXZRGGJhkwLeStYNoHs7ep1", 1.8933f64), + ("JFGuwWzqiyJZ3MPM8NRy7kK75MdxwSkh7GNZcsVd6BpZq2h", 20.3333f64), + ("D5WYdgC7f4W6jGCkQaQ3Lfe5P5F7JvfhYBAX9G6CBToMYe4", 0f64), + ("EJgdRddcYSd6XWnwr8oZkkzxJJX8SLwig38d5yxZSRgJGQZ", 0f64), + ("FXRK8xzufVJ45bCXuCCRr6FuS1dCfx9VjiuwqZDSqzEWgLm", 0f64), + ("Gt8ferkwFEX9jLbxpuhLYqKdNzP9KtjZcGYVN2mMbuCwhAP", 0f64), + ("HHCd33jjDBJJDZic7rbQZMuMaoe5ddYaRkaLf7tDURHpE56", 0f64), + ("E7b4mfFEhpnbw7iKdhvnBw7fXoQ1QFQE4TtTRhseWMU1H2E", 14.9000f64), + ("EGUE7VyrVLVSoaG43XVrEf3eKcgzJC8p3mFRtPUTMNLhdYs", 15.9000f64), + ("EtommijqrHDFWFvBxP515oUbkXx9vK2qohzrmwpCXbU7Yx2", 0f64), + ("GxzBsXcxZXXaKcLXj4CWGDdoCaXRVmcRkyiUAHFc1AfTMEV", 0f64), + ("H1heyw8DdkexFHAJ85GhuJr5om72Kx2DdK6sHsmb2f9ebUJ", 0f64), + ("J1Mf8RWcRWpuCRBAQVq6yRgb9exuHdKJdfV2NymtbXdkTF4", 13.9866f64), + ("FX6PCBQr4gtejvdR5dCdstrxmS3oFrzjZHtAKXSBumEse96", 0f64), + ("EdE26hU1nVmmVoteHWGKX8BuayykEg84iz7x3MCmzfocn2u", 0f64), + ("DzN3bMAAKKam6DBr9co4r1TBSj5X6Looh3JvNmfegiVrUgy", 0f64), + ("Dx2p54FSAxrqvFVN4ptvjV9LoUHkKQirM8SbLjD9PVnAonv", 0f64), + ("G6wtWujSHgT24UxXhDHVaVbnY5fBkUJLsjykyWBvtNs2aGQ", 0.0266666664f64), + ("DMrWWv31QiiDDESjGjyVcGhoCYMkPvrSTHHUDK5mR1riV2A", 0f64), + ("EkahQVDKRCe97ZT9TgS1YyfTzLgPah5PHa8NsfGFLsPKpjo", 0f64), + ("GhQ3gB8oaLZfjSd6gyeYZgymnJ2LEmvaUrSELBbva9342Y6", 0f64), + ]; + for (who, amount) in payouts.into_iter().filter(|&(_, amount)| amount > 0f64) { + println!( + "(hex![\"{}\"], {}u128),", + HexDisplay::from(AsRef::<[u8; 32]>::as_ref(&AccountId32::from_string(who).unwrap())), + (amount * 1_000_000_000_000f64).round() as u128, + ) + } +} diff --git a/polkadot/runtime/kusama/src/tests.rs b/polkadot/runtime/kusama/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..053c3054ab463fa8c99fc4c430dc6b4bfc726efa --- /dev/null +++ b/polkadot/runtime/kusama/src/tests.rs @@ -0,0 +1,177 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests for the Kusama Runtime Configuration + +use crate::*; +use frame_support::{ + dispatch::GetDispatchInfo, traits::WhitelistedStorageKeys, weights::WeightToFee as WeightToFeeT, +}; +use keyring::Sr25519Keyring::Charlie; +use pallet_transaction_payment::Multiplier; +use parity_scale_codec::Encode; +use runtime_common::MinimumMultiplier; +use separator::Separatable; +use sp_core::hexdisplay::HexDisplay; +use sp_runtime::FixedPointNumber; +use std::collections::HashSet; + +#[test] +fn nis_hold_reason_encoding_is_correct() { + assert_eq!(RuntimeHoldReason::Nis(pallet_nis::HoldReason::NftReceipt).encode(), [38, 0]); +} + +#[test] +fn remove_keys_weight_is_sensible() { + use runtime_common::crowdloan::WeightInfo; + let max_weight = ::WeightInfo::refund(RemoveKeysLimit::get()); + // Max remove keys limit should be no more than half the total block weight. + assert!((max_weight * 2).all_lt(BlockWeights::get().max_block)); +} + +#[test] +fn sample_size_is_sensible() { + use runtime_common::auctions::WeightInfo; + // Need to clean up all samples at the end of an auction. + let samples: BlockNumber = EndingPeriod::get() / SampleLength::get(); + let max_weight: Weight = RocksDbWeight::get().reads_writes(samples.into(), samples.into()); + // Max sample cleanup should be no more than half the total block weight. + assert!((max_weight * 2).all_lt(BlockWeights::get().max_block)); + assert!((::WeightInfo::on_initialize() * 2) + .all_lt(BlockWeights::get().max_block)); +} + +#[test] +fn payout_weight_portion() { + use pallet_staking::WeightInfo; + let payout_weight = + ::WeightInfo::payout_stakers_alive_staked( + MaxNominatorRewardedPerValidator::get(), + ) + .ref_time() as f64; + let block_weight = BlockWeights::get().max_block.ref_time() as f64; + + println!( + "a full payout takes {:.2} of the block weight [{} / {}]", + payout_weight / block_weight, + payout_weight, + block_weight + ); + assert!(payout_weight * 2f64 < block_weight); +} + +#[test] +#[ignore] +fn block_cost() { + let max_block_weight = BlockWeights::get().max_block; + let raw_fee = WeightToFee::weight_to_fee(&max_block_weight); + + println!( + "Full Block weight == {} // WeightToFee(full_block) == {} plank", + max_block_weight, + raw_fee.separated_string(), + ); +} + +#[test] +#[ignore] +fn transfer_cost_min_multiplier() { + let min_multiplier = MinimumMultiplier::get(); + let call = pallet_balances::Call::::transfer_keep_alive { + dest: Charlie.to_account_id().into(), + value: Default::default(), + }; + let info = call.get_dispatch_info(); + // convert to outer call. + let call = RuntimeCall::Balances(call); + let len = call.using_encoded(|e| e.len()) as u32; + + let mut ext = sp_io::TestExternalities::new_empty(); + let mut test_with_multiplier = |m| { + ext.execute_with(|| { + pallet_transaction_payment::NextFeeMultiplier::::put(m); + let fee = TransactionPayment::compute_fee(len, &info, 0); + println!( + "weight = {:?} // multiplier = {:?} // full transfer fee = {:?}", + info.weight.ref_time().separated_string(), + pallet_transaction_payment::NextFeeMultiplier::::get(), + fee.separated_string(), + ); + }); + }; + + test_with_multiplier(min_multiplier); + test_with_multiplier(Multiplier::saturating_from_rational(1, 1u128)); + test_with_multiplier(Multiplier::saturating_from_rational(1, 1_000u128)); + test_with_multiplier(Multiplier::saturating_from_rational(1, 1_000_000u128)); + test_with_multiplier(Multiplier::saturating_from_rational(1, 1_000_000_000u128)); +} + +#[test] +fn nominator_limit() { + use pallet_election_provider_multi_phase::WeightInfo; + // starting point of the nominators. + let all_voters: u32 = 10_000; + + // assuming we want around 5k candidates and 1k active validators. + let all_targets: u32 = 5_000; + let desired: u32 = 1_000; + let weight_with = |active| { + ::WeightInfo::submit_unsigned( + all_voters.max(active), + all_targets, + active, + desired, + ) + }; + + let mut active = 1; + while weight_with(active).all_lte(OffchainSolutionWeightLimit::get()) || active == all_voters { + active += 1; + } + + println!("can support {} nominators to yield a weight of {}", active, weight_with(active)); +} + +#[test] +fn call_size() { + RuntimeCall::assert_size_under(256); +} + +#[test] +fn check_whitelist() { + let whitelist: HashSet = AllPalletsWithSystem::whitelisted_storage_keys() + .iter() + .map(|e| HexDisplay::from(&e.key).to_string()) + .collect(); + + // Block number + assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac")); + // Total issuance + assert!(whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80")); + // Execution phase + assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a")); + // Event count + assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850")); + // System events + assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7")); + // Configuration ActiveConfig + assert!(whitelist.contains("06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385")); + // XcmPallet VersionDiscoveryQueue + assert!(whitelist.contains("1405f2411d0af5a7ff397e7c9dc68d194a222ba0333561192e474c59ed8e30e1")); + // XcmPallet SafeXcmVersion + assert!(whitelist.contains("1405f2411d0af5a7ff397e7c9dc68d196323ae84c43568be0d1394d5d0d522c4")); +} diff --git a/polkadot/runtime/kusama/src/weights/frame_benchmarking_baseline.rs b/polkadot/runtime/kusama/src/weights/frame_benchmarking_baseline.rs new file mode 100644 index 0000000000000000000000000000000000000000..e9f934f56564e5093d2567b535a0218b5707860e --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/frame_benchmarking_baseline.rs @@ -0,0 +1,108 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `frame_benchmarking::baseline` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=frame_benchmarking::baseline +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/frame_benchmarking_baseline.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_benchmarking::baseline`. +pub struct WeightInfo(PhantomData); +impl frame_benchmarking::baseline::WeightInfo for WeightInfo { + /// The range of component `i` is `[0, 1000000]`. + fn addition(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 173_000 picoseconds. + Weight::from_parts(235_396, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 1000000]`. + fn subtraction(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 177_000 picoseconds. + Weight::from_parts(228_745, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 1000000]`. + fn multiplication(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 178_000 picoseconds. + Weight::from_parts(233_063, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 1000000]`. + fn division(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 167_000 picoseconds. + Weight::from_parts(224_853, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn hashing() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 23_298_471_000 picoseconds. + Weight::from_parts(23_321_832_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 100]`. + fn sr25519_verification(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 228_000 picoseconds. + Weight::from_parts(8_448_493, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 18_878 + .saturating_add(Weight::from_parts(55_611_437, 0).saturating_mul(i.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/frame_election_provider_support.rs b/polkadot/runtime/kusama/src/weights/frame_election_provider_support.rs new file mode 100644 index 0000000000000000000000000000000000000000..9cdbd67d5e1db379958c12516e5e2f999379ef9b --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/frame_election_provider_support.rs @@ -0,0 +1,83 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `frame_election_provider_support` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=frame_election_provider_support +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_election_provider_support`. +pub struct WeightInfo(PhantomData); +impl frame_election_provider_support::WeightInfo for WeightInfo { + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `d` is `[5, 16]`. + fn phragmen(v: u32, _t: u32, d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_647_123_000 picoseconds. + Weight::from_parts(6_809_648_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 139_689 + .saturating_add(Weight::from_parts(6_171_199, 0).saturating_mul(v.into())) + // Standard Error: 14_281_333 + .saturating_add(Weight::from_parts(1_423_059_328, 0).saturating_mul(d.into())) + } + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `d` is `[5, 16]`. + fn phragmms(v: u32, _t: u32, d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_616_850_000 picoseconds. + Weight::from_parts(4_769_028_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 123_691 + .saturating_add(Weight::from_parts(4_925_892, 0).saturating_mul(v.into())) + // Standard Error: 12_645_798 + .saturating_add(Weight::from_parts(1_357_902_261, 0).saturating_mul(d.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/frame_system.rs b/polkadot/runtime/kusama/src/weights/frame_system.rs new file mode 100644 index 0000000000000000000000000000000000000000..927977e9be0119a70de110f3c566608bbbbd6845 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/frame_system.rs @@ -0,0 +1,147 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `frame_system` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=frame_system +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system`. +pub struct WeightInfo(PhantomData); +impl frame_system::WeightInfo for WeightInfo { + /// The range of component `b` is `[0, 3932160]`. + fn remark(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_951_000 picoseconds. + Weight::from_parts(2_015_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(431, 0).saturating_mul(b.into())) + } + /// The range of component `b` is `[0, 3932160]`. + fn remark_with_event(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_410_000 picoseconds. + Weight::from_parts(7_603_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_793, 0).saturating_mul(b.into())) + } + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a686561707061676573` (r:0 w:1) + /// Proof Skipped: unknown `0x3a686561707061676573` (r:0 w:1) + fn set_heap_pages() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1485` + // Minimum execution time: 3_736_000 picoseconds. + Weight::from_parts(3_922_000, 0) + .saturating_add(Weight::from_parts(0, 1485)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a636f6465` (r:0 w:1) + /// Proof Skipped: unknown `0x3a636f6465` (r:0 w:1) + fn set_code() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1485` + // Minimum execution time: 93_052_017_000 picoseconds. + Weight::from_parts(98_271_042_000, 0) + .saturating_add(Weight::from_parts(0, 1485)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 1000]`. + fn set_storage(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_100_000 picoseconds. + Weight::from_parts(2_131_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1_975 + .saturating_add(Weight::from_parts(744_852, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 1000]`. + fn kill_storage(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_089_000 picoseconds. + Weight::from_parts(2_129_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1_093 + .saturating_add(Weight::from_parts(568_923, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `p` is `[0, 1000]`. + fn kill_prefix(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `105 + p * (69 ±0)` + // Estimated: `118 + p * (70 ±0)` + // Minimum execution time: 3_913_000 picoseconds. + Weight::from_parts(4_056_000, 0) + .saturating_add(Weight::from_parts(0, 118)) + // Standard Error: 2_452 + .saturating_add(Weight::from_parts(1_281_244, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/mod.rs b/polkadot/runtime/kusama/src/weights/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..b3642d49d46390d2551b5f5420ef1b5626f40678 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/mod.rs @@ -0,0 +1,69 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! A list of the different weight modules for our runtime. + +pub mod frame_election_provider_support; +pub mod frame_system; +pub mod pallet_bags_list; +pub mod pallet_balances; +pub mod pallet_balances_nis_counterpart_balances; +pub mod pallet_bounties; +pub mod pallet_child_bounties; +pub mod pallet_collective_council; +pub mod pallet_collective_technical_committee; +pub mod pallet_conviction_voting; +pub mod pallet_democracy; +pub mod pallet_election_provider_multi_phase; +pub mod pallet_elections_phragmen; +pub mod pallet_fast_unstake; +pub mod pallet_identity; +pub mod pallet_im_online; +pub mod pallet_indices; +pub mod pallet_membership; +pub mod pallet_message_queue; +pub mod pallet_multisig; +pub mod pallet_nis; +pub mod pallet_nomination_pools; +pub mod pallet_preimage; +pub mod pallet_proxy; +pub mod pallet_ranked_collective; +pub mod pallet_referenda_fellowship_referenda; +pub mod pallet_referenda_referenda; +pub mod pallet_scheduler; +pub mod pallet_session; +pub mod pallet_society; +pub mod pallet_staking; +pub mod pallet_timestamp; +pub mod pallet_tips; +pub mod pallet_treasury; +pub mod pallet_utility; +pub mod pallet_vesting; +pub mod pallet_whitelist; +pub mod pallet_xcm; +pub mod runtime_common_auctions; +pub mod runtime_common_claims; +pub mod runtime_common_crowdloan; +pub mod runtime_common_paras_registrar; +pub mod runtime_common_slots; +pub mod runtime_parachains_configuration; +pub mod runtime_parachains_disputes; +pub mod runtime_parachains_disputes_slashing; +pub mod runtime_parachains_hrmp; +pub mod runtime_parachains_inclusion; +pub mod runtime_parachains_initializer; +pub mod runtime_parachains_paras; +pub mod runtime_parachains_paras_inherent; +pub mod xcm; diff --git a/polkadot/runtime/kusama/src/weights/pallet_bags_list.rs b/polkadot/runtime/kusama/src/weights/pallet_bags_list.rs new file mode 100644 index 0000000000000000000000000000000000000000..b138ae3003b7e40360a6bb9b3b9ddd17957738a2 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_bags_list.rs @@ -0,0 +1,109 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_bags_list` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_bags_list +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bags_list`. +pub struct WeightInfo(PhantomData); +impl pallet_bags_list::WeightInfo for WeightInfo { + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:4 w:4) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn rebag_non_terminal() -> Weight { + // Proof Size summary in bytes: + // Measured: `1654` + // Estimated: `11506` + // Minimum execution time: 60_661_000 picoseconds. + Weight::from_parts(62_784_000, 0) + .saturating_add(Weight::from_parts(0, 11506)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn rebag_terminal() -> Weight { + // Proof Size summary in bytes: + // Measured: `1548` + // Estimated: `8877` + // Minimum execution time: 58_537_000 picoseconds. + Weight::from_parts(60_665_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: VoterList ListNodes (r:4 w:4) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:2 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:2 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn put_in_front_of() -> Weight { + // Proof Size summary in bytes: + // Measured: `1857` + // Estimated: `11506` + // Minimum execution time: 66_168_000 picoseconds. + Weight::from_parts(67_855_000, 0) + .saturating_add(Weight::from_parts(0, 11506)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(6)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_balances.rs b/polkadot/runtime/kusama/src/weights/pallet_balances.rs new file mode 100644 index 0000000000000000000000000000000000000000..a8498f52f8bc4ef05669a8f59de55747f7bc6f1b --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_balances.rs @@ -0,0 +1,99 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +//! Autogenerated weights for `pallet_balances` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-11-15, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_balances +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `pallet_balances`. +pub struct WeightInfo(PhantomData); +impl pallet_balances::WeightInfo for WeightInfo { + // Storage: System Account (r:1 w:1) + fn transfer_allow_death() -> Weight { + // Minimum execution time: 40_902 nanoseconds. + Weight::from_parts(41_638_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_keep_alive() -> Weight { + // Minimum execution time: 30_093 nanoseconds. + Weight::from_parts(30_732_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn force_set_balance_creating() -> Weight { + // Minimum execution time: 23_901 nanoseconds. + Weight::from_parts(24_238_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn force_set_balance_killing() -> Weight { + // Minimum execution time: 26_402 nanoseconds. + Weight::from_parts(27_026_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:2 w:2) + fn force_transfer() -> Weight { + // Minimum execution time: 40_328 nanoseconds. + Weight::from_parts(41_242_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(2 as u64)) + .saturating_add(T::DbWeight::get().writes(2 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_all() -> Weight { + // Minimum execution time: 35_401 nanoseconds. + Weight::from_parts(36_122_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn force_unreserve() -> Weight { + // Minimum execution time: 20_178 nanoseconds. + Weight::from_parts(20_435_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + fn upgrade_accounts(_: u32) -> Weight { + Weight::from_parts(0, 0) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_balances_balances.rs b/polkadot/runtime/kusama/src/weights/pallet_balances_balances.rs new file mode 100644 index 0000000000000000000000000000000000000000..f65c5722d8be347e086d4833e87591475a2ea385 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_balances_balances.rs @@ -0,0 +1,154 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_balances` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_balances +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_balances`. +pub struct WeightInfo(PhantomData); +impl pallet_balances::WeightInfo for WeightInfo { + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_allow_death() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 55_712_000 picoseconds. + Weight::from_parts(56_594_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_keep_alive() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 42_461_000 picoseconds. + Weight::from_parts(43_407_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_set_balance_creating() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 15_909_000 picoseconds. + Weight::from_parts(16_376_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_set_balance_killing() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 23_026_000 picoseconds. + Weight::from_parts(23_599_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `6196` + // Minimum execution time: 57_520_000 picoseconds. + Weight::from_parts(58_933_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_all() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 51_663_000 picoseconds. + Weight::from_parts(52_494_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_unreserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 18_726_000 picoseconds. + Weight::from_parts(19_172_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:999 w:999) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `u` is `[1, 1000]`. + /// The range of component `u` is `[1, 1000]`. + fn upgrade_accounts(u: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + u * (135 ±0)` + // Estimated: `990 + u * (2603 ±0)` + // Minimum execution time: 18_041_000 picoseconds. + Weight::from_parts(18_377_000, 0) + .saturating_add(Weight::from_parts(0, 990)) + // Standard Error: 12_295 + .saturating_add(Weight::from_parts(16_146_961, 0).saturating_mul(u.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_balances_nis_counterpart_balances.rs b/polkadot/runtime/kusama/src/weights/pallet_balances_nis_counterpart_balances.rs new file mode 100644 index 0000000000000000000000000000000000000000..730d622e9abce38a90d69d3b1a1fa3baf85708b5 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_balances_nis_counterpart_balances.rs @@ -0,0 +1,178 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_balances` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_balances +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_balances`. +pub struct WeightInfo(PhantomData); +impl pallet_balances::WeightInfo for WeightInfo { + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:2 w:2) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_allow_death() -> Weight { + // Proof Size summary in bytes: + // Measured: `219` + // Estimated: `6164` + // Minimum execution time: 56_458_000 picoseconds. + Weight::from_parts(57_881_000, 0) + .saturating_add(Weight::from_parts(0, 6164)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:0) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:2 w:2) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_keep_alive() -> Weight { + // Proof Size summary in bytes: + // Measured: `219` + // Estimated: `6164` + // Minimum execution time: 43_014_000 picoseconds. + Weight::from_parts(44_098_000, 0) + .saturating_add(Weight::from_parts(0, 6164)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + fn force_set_balance_creating() -> Weight { + // Proof Size summary in bytes: + // Measured: `217` + // Estimated: `3577` + // Minimum execution time: 14_712_000 picoseconds. + Weight::from_parts(15_189_000, 0) + .saturating_add(Weight::from_parts(0, 3577)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + fn force_set_balance_killing() -> Weight { + // Proof Size summary in bytes: + // Measured: `393` + // Estimated: `3593` + // Minimum execution time: 25_131_000 picoseconds. + Weight::from_parts(25_796_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:2 w:2) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `322` + // Estimated: `6196` + // Minimum execution time: 58_350_000 picoseconds. + Weight::from_parts(59_738_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: NisCounterpartBalances Account (r:2 w:2) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:0) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_all() -> Weight { + // Proof Size summary in bytes: + // Measured: `219` + // Estimated: `6164` + // Minimum execution time: 52_544_000 picoseconds. + Weight::from_parts(53_454_000, 0) + .saturating_add(Weight::from_parts(0, 6164)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_unreserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `391` + // Estimated: `3593` + // Minimum execution time: 20_615_000 picoseconds. + Weight::from_parts(21_215_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: NisCounterpartBalances Account (r:999 w:999) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:999 w:999) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `u` is `[1, 1000]`. + /// The range of component `u` is `[1, 1000]`. + fn upgrade_accounts(u: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + u * (256 ±0)` + // Estimated: `990 + u * (2603 ±0)` + // Minimum execution time: 20_150_000 picoseconds. + Weight::from_parts(20_438_000, 0) + .saturating_add(Weight::from_parts(0, 990)) + // Standard Error: 26_020 + .saturating_add(Weight::from_parts(18_369_413, 0).saturating_mul(u.into())) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(u.into()))) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(u.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_bounties.rs b/polkadot/runtime/kusama/src/weights/pallet_bounties.rs new file mode 100644 index 0000000000000000000000000000000000000000..07ddb5240e6a1d43340f5b87f589d3f003600b64 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_bounties.rs @@ -0,0 +1,230 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_bounties` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_bounties +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bounties`. +pub struct WeightInfo(PhantomData); +impl pallet_bounties::WeightInfo for WeightInfo { + /// Storage: Bounties BountyCount (r:1 w:1) + /// Proof: Bounties BountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:0 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// The range of component `d` is `[0, 16384]`. + fn propose_bounty(d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `177` + // Estimated: `3593` + // Minimum execution time: 28_620_000 picoseconds. + Weight::from_parts(30_319_265, 0) + .saturating_add(Weight::from_parts(0, 3593)) + // Standard Error: 7 + .saturating_add(Weight::from_parts(715, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + fn approve_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `269` + // Estimated: `3642` + // Minimum execution time: 10_397_000 picoseconds. + Weight::from_parts(10_777_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + fn propose_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `289` + // Estimated: `3642` + // Minimum execution time: 9_065_000 picoseconds. + Weight::from_parts(9_477_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn unassign_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `465` + // Estimated: `3642` + // Minimum execution time: 42_565_000 picoseconds. + Weight::from_parts(43_956_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn accept_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `461` + // Estimated: `3642` + // Minimum execution time: 27_461_000 picoseconds. + Weight::from_parts(28_307_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + fn award_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `405` + // Estimated: `3642` + // Minimum execution time: 19_269_000 picoseconds. + Weight::from_parts(19_884_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn claim_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `769` + // Estimated: `8799` + // Minimum execution time: 120_844_000 picoseconds. + Weight::from_parts(125_606_000, 0) + .saturating_add(Weight::from_parts(0, 8799)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn close_bounty_proposed() -> Weight { + // Proof Size summary in bytes: + // Measured: `449` + // Estimated: `3642` + // Minimum execution time: 47_439_000 picoseconds. + Weight::from_parts(48_838_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn close_bounty_active() -> Weight { + // Proof Size summary in bytes: + // Measured: `685` + // Estimated: `6196` + // Minimum execution time: 81_354_000 picoseconds. + Weight::from_parts(83_515_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + fn extend_bounty_expiry() -> Weight { + // Proof Size summary in bytes: + // Measured: `325` + // Estimated: `3642` + // Minimum execution time: 14_850_000 picoseconds. + Weight::from_parts(15_365_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:100 w:100) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:200 w:200) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `b` is `[0, 100]`. + fn spend_funds(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + b * (297 ±0)` + // Estimated: `1887 + b * (5206 ±0)` + // Minimum execution time: 4_606_000 picoseconds. + Weight::from_parts(4_691_000, 0) + .saturating_add(Weight::from_parts(0, 1887)) + // Standard Error: 15_735 + .saturating_add(Weight::from_parts(44_695_416, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(b.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(b.into()))) + .saturating_add(Weight::from_parts(0, 5206).saturating_mul(b.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_child_bounties.rs b/polkadot/runtime/kusama/src/weights/pallet_child_bounties.rs new file mode 100644 index 0000000000000000000000000000000000000000..252060ba37b3b187841e080db84a4bcdd1398c76 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_child_bounties.rs @@ -0,0 +1,202 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_child_bounties` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_child_bounties +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_child_bounties`. +pub struct WeightInfo(PhantomData); +impl pallet_child_bounties::WeightInfo for WeightInfo { + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyCount (r:1 w:1) + /// Proof: ChildBounties ChildBountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:0 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// The range of component `d` is `[0, 16384]`. + fn add_child_bounty(d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `545` + // Estimated: `6196` + // Minimum execution time: 69_355_000 picoseconds. + Weight::from_parts(72_208_416, 0) + .saturating_add(Weight::from_parts(0, 6196)) + // Standard Error: 10 + .saturating_add(Weight::from_parts(705, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + fn propose_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `599` + // Estimated: `3642` + // Minimum execution time: 17_313_000 picoseconds. + Weight::from_parts(18_161_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn accept_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `745` + // Estimated: `3642` + // Minimum execution time: 32_629_000 picoseconds. + Weight::from_parts(33_843_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn unassign_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `745` + // Estimated: `3642` + // Minimum execution time: 47_994_000 picoseconds. + Weight::from_parts(49_346_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + fn award_child_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `642` + // Estimated: `3642` + // Minimum execution time: 21_866_000 picoseconds. + Weight::from_parts(22_532_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn claim_child_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `614` + // Estimated: `8799` + // Minimum execution time: 116_595_000 picoseconds. + Weight::from_parts(118_921_000, 0) + .saturating_add(Weight::from_parts(0, 8799)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn close_child_bounty_added() -> Weight { + // Proof Size summary in bytes: + // Measured: `845` + // Estimated: `6196` + // Minimum execution time: 76_806_000 picoseconds. + Weight::from_parts(79_568_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn close_child_bounty_active() -> Weight { + // Proof Size summary in bytes: + // Measured: `1032` + // Estimated: `8799` + // Minimum execution time: 93_885_000 picoseconds. + Weight::from_parts(96_680_000, 0) + .saturating_add(Weight::from_parts(0, 8799)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(7)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_collective_council.rs b/polkadot/runtime/kusama/src/weights/pallet_collective_council.rs new file mode 100644 index 0000000000000000000000000000000000000000..84157595f7cb04f636965d998493c18cb16de550 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_collective_council.rs @@ -0,0 +1,322 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +//! Autogenerated weights for `pallet_collective` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-03-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_collective +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `pallet_collective`. +pub struct WeightInfo(PhantomData); +impl pallet_collective::WeightInfo for WeightInfo { + /// Storage: Council Members (r:1 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:100 w:100) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Prime (r:0 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + fn set_members(m: u32, _n: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + m * (3232 ±0) + p * (3190 ±0)` + // Estimated: `19164 + m * (7799 ±17) + p * (10110 ±17)` + // Minimum execution time: 17_032_000 picoseconds. + Weight::from_parts(17_263_000, 0) + .saturating_add(Weight::from_parts(0, 19164)) + // Standard Error: 51_363 + .saturating_add(Weight::from_parts(5_779_193, 0).saturating_mul(m.into())) + // Standard Error: 51_363 + .saturating_add(Weight::from_parts(8_434_866, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 7799).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 10110).saturating_mul(p.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `136 + m * (32 ±0)` + // Estimated: `1622 + m * (32 ±0)` + // Minimum execution time: 15_686_000 picoseconds. + Weight::from_parts(15_185_500, 0) + .saturating_add(Weight::from_parts(0, 1622)) + // Standard Error: 26 + .saturating_add(Weight::from_parts(1_363, 0).saturating_mul(b.into())) + // Standard Error: 277 + .saturating_add(Weight::from_parts(15_720, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:0) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn propose_execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `136 + m * (32 ±0)` + // Estimated: `5224 + m * (64 ±0)` + // Minimum execution time: 18_314_000 picoseconds. + Weight::from_parts(17_659_522, 0) + .saturating_add(Weight::from_parts(0, 5224)) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_153, 0).saturating_mul(b.into())) + // Standard Error: 237 + .saturating_add(Weight::from_parts(25_439, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalCount (r:1 w:1) + /// Proof Skipped: Council ProposalCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:0 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `426 + m * (32 ±0) + p * (36 ±0)` + // Estimated: `9685 + m * (165 ±0) + p * (180 ±0)` + // Minimum execution time: 23_916_000 picoseconds. + Weight::from_parts(25_192_989, 0) + .saturating_add(Weight::from_parts(0, 9685)) + // Standard Error: 50 + .saturating_add(Weight::from_parts(2_327, 0).saturating_mul(b.into())) + // Standard Error: 528 + .saturating_add(Weight::from_parts(17_763, 0).saturating_mul(m.into())) + // Standard Error: 522 + .saturating_add(Weight::from_parts(116_903, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 165).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 180).saturating_mul(p.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[5, 100]`. + /// The range of component `m` is `[5, 100]`. + fn vote(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `875 + m * (64 ±0)` + // Estimated: `6698 + m * (128 ±0)` + // Minimum execution time: 21_641_000 picoseconds. + Weight::from_parts(22_373_888, 0) + .saturating_add(Weight::from_parts(0, 6698)) + // Standard Error: 299 + .saturating_add(Weight::from_parts(41_168, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 128).saturating_mul(m.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `464 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `8211 + m * (260 ±0) + p * (144 ±0)` + // Minimum execution time: 26_158_000 picoseconds. + Weight::from_parts(27_675_242, 0) + .saturating_add(Weight::from_parts(0, 8211)) + // Standard Error: 845 + .saturating_add(Weight::from_parts(10_799, 0).saturating_mul(m.into())) + // Standard Error: 824 + .saturating_add(Weight::from_parts(141_199, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 260).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 144).saturating_mul(p.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `766 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `12372 + b * (4 ±0) + m * (264 ±0) + p * (160 ±0)` + // Minimum execution time: 37_601_000 picoseconds. + Weight::from_parts(41_302_278, 0) + .saturating_add(Weight::from_parts(0, 12372)) + // Standard Error: 67 + .saturating_add(Weight::from_parts(1_608, 0).saturating_mul(b.into())) + // Standard Error: 716 + .saturating_add(Weight::from_parts(14_628, 0).saturating_mul(m.into())) + // Standard Error: 698 + .saturating_add(Weight::from_parts(129_997, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 264).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 160).saturating_mul(p.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:0) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `484 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `10240 + m * (325 ±0) + p * (180 ±0)` + // Minimum execution time: 29_185_000 picoseconds. + Weight::from_parts(30_594_183, 0) + .saturating_add(Weight::from_parts(0, 10240)) + // Standard Error: 865 + .saturating_add(Weight::from_parts(30_165, 0).saturating_mul(m.into())) + // Standard Error: 844 + .saturating_add(Weight::from_parts(131_623, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 325).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 180).saturating_mul(p.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:0) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `786 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `14575 + b * (5 ±0) + m * (330 ±0) + p * (200 ±0)` + // Minimum execution time: 43_157_000 picoseconds. + Weight::from_parts(43_691_874, 0) + .saturating_add(Weight::from_parts(0, 14575)) + // Standard Error: 61 + .saturating_add(Weight::from_parts(1_862, 0).saturating_mul(b.into())) + // Standard Error: 654 + .saturating_add(Weight::from_parts(17_183, 0).saturating_mul(m.into())) + // Standard Error: 638 + .saturating_add(Weight::from_parts(133_193, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 5).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 330).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 200).saturating_mul(p.into())) + } + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:0 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `p` is `[1, 100]`. + /// The range of component `p` is `[1, 100]`. + fn disapprove_proposal(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `293 + p * (32 ±0)` + // Estimated: `2364 + p * (96 ±0)` + // Minimum execution time: 14_666_000 picoseconds. + Weight::from_parts(16_623_386, 0) + .saturating_add(Weight::from_parts(0, 2364)) + // Standard Error: 430 + .saturating_add(Weight::from_parts(111_461, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 96).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_collective_technical_committee.rs b/polkadot/runtime/kusama/src/weights/pallet_collective_technical_committee.rs new file mode 100644 index 0000000000000000000000000000000000000000..0bf5d2839b0a2c40e9894460202419c13ca21ed8 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_collective_technical_committee.rs @@ -0,0 +1,322 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +//! Autogenerated weights for `pallet_collective` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-03-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_collective +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `pallet_collective`. +pub struct WeightInfo(PhantomData); +impl pallet_collective::WeightInfo for WeightInfo { + /// Storage: TechnicalCommittee Members (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:100 w:100) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + fn set_members(m: u32, _n: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + m * (3232 ±0) + p * (3190 ±0)` + // Estimated: `19320 + m * (7799 ±16) + p * (10110 ±16)` + // Minimum execution time: 17_755_000 picoseconds. + Weight::from_parts(18_022_000, 0) + .saturating_add(Weight::from_parts(0, 19320)) + // Standard Error: 48_475 + .saturating_add(Weight::from_parts(5_505_299, 0).saturating_mul(m.into())) + // Standard Error: 48_475 + .saturating_add(Weight::from_parts(8_260_850, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 7799).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 10110).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `175 + m * (32 ±0)` + // Estimated: `1661 + m * (32 ±0)` + // Minimum execution time: 16_765_000 picoseconds. + Weight::from_parts(15_653_912, 0) + .saturating_add(Weight::from_parts(0, 1661)) + // Standard Error: 25 + .saturating_add(Weight::from_parts(1_539, 0).saturating_mul(b.into())) + // Standard Error: 261 + .saturating_add(Weight::from_parts(17_896, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:0) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn propose_execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `175 + m * (32 ±0)` + // Estimated: `5302 + m * (64 ±0)` + // Minimum execution time: 19_194_000 picoseconds. + Weight::from_parts(18_366_867, 0) + .saturating_add(Weight::from_parts(0, 5302)) + // Standard Error: 19 + .saturating_add(Weight::from_parts(1_342, 0).saturating_mul(b.into())) + // Standard Error: 200 + .saturating_add(Weight::from_parts(22_738, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalCount (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `465 + m * (32 ±0) + p * (36 ±0)` + // Estimated: `9880 + m * (165 ±0) + p * (180 ±0)` + // Minimum execution time: 24_958_000 picoseconds. + Weight::from_parts(25_925_520, 0) + .saturating_add(Weight::from_parts(0, 9880)) + // Standard Error: 54 + .saturating_add(Weight::from_parts(2_430, 0).saturating_mul(b.into())) + // Standard Error: 570 + .saturating_add(Weight::from_parts(17_303, 0).saturating_mul(m.into())) + // Standard Error: 563 + .saturating_add(Weight::from_parts(119_736, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 165).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 180).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[5, 100]`. + /// The range of component `m` is `[5, 100]`. + fn vote(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `914 + m * (64 ±0)` + // Estimated: `6776 + m * (128 ±0)` + // Minimum execution time: 22_620_000 picoseconds. + Weight::from_parts(23_356_968, 0) + .saturating_add(Weight::from_parts(0, 6776)) + // Standard Error: 273 + .saturating_add(Weight::from_parts(40_919, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 128).saturating_mul(m.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:0 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `503 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `8367 + m * (260 ±0) + p * (144 ±0)` + // Minimum execution time: 27_667_000 picoseconds. + Weight::from_parts(29_094_490, 0) + .saturating_add(Weight::from_parts(0, 8367)) + // Standard Error: 842 + .saturating_add(Weight::from_parts(25_691, 0).saturating_mul(m.into())) + // Standard Error: 821 + .saturating_add(Weight::from_parts(133_244, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 260).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 144).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `805 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `12528 + b * (4 ±0) + m * (264 ±0) + p * (160 ±0)` + // Minimum execution time: 41_678_000 picoseconds. + Weight::from_parts(42_218_269, 0) + .saturating_add(Weight::from_parts(0, 12528)) + // Standard Error: 59 + .saturating_add(Weight::from_parts(1_661, 0).saturating_mul(b.into())) + // Standard Error: 624 + .saturating_add(Weight::from_parts(16_946, 0).saturating_mul(m.into())) + // Standard Error: 608 + .saturating_add(Weight::from_parts(129_170, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 264).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 160).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:0 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `523 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `10435 + m * (325 ±0) + p * (180 ±0)` + // Minimum execution time: 30_447_000 picoseconds. + Weight::from_parts(32_661_910, 0) + .saturating_add(Weight::from_parts(0, 10435)) + // Standard Error: 531 + .saturating_add(Weight::from_parts(29_960, 0).saturating_mul(m.into())) + // Standard Error: 517 + .saturating_add(Weight::from_parts(120_475, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 325).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 180).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `825 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `14770 + b * (5 ±0) + m * (330 ±0) + p * (200 ±0)` + // Minimum execution time: 44_068_000 picoseconds. + Weight::from_parts(44_673_420, 0) + .saturating_add(Weight::from_parts(0, 14770)) + // Standard Error: 59 + .saturating_add(Weight::from_parts(1_779, 0).saturating_mul(b.into())) + // Standard Error: 625 + .saturating_add(Weight::from_parts(17_794, 0).saturating_mul(m.into())) + // Standard Error: 609 + .saturating_add(Weight::from_parts(134_062, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 5).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 330).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 200).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:0 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `p` is `[1, 100]`. + /// The range of component `p` is `[1, 100]`. + fn disapprove_proposal(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `332 + p * (32 ±0)` + // Estimated: `2481 + p * (96 ±0)` + // Minimum execution time: 15_528_000 picoseconds. + Weight::from_parts(17_434_864, 0) + .saturating_add(Weight::from_parts(0, 2481)) + // Standard Error: 405 + .saturating_add(Weight::from_parts(111_909, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 96).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_conviction_voting.rs b/polkadot/runtime/kusama/src/weights/pallet_conviction_voting.rs new file mode 100644 index 0000000000000000000000000000000000000000..ba505737f1b070d21931c7e467b4853de1f119d2 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_conviction_voting.rs @@ -0,0 +1,195 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_conviction_voting` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_conviction_voting +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_conviction_voting`. +pub struct WeightInfo(PhantomData); +impl pallet_conviction_voting::WeightInfo for WeightInfo { + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn vote_new() -> Weight { + // Proof Size summary in bytes: + // Measured: `13445` + // Estimated: `42428` + // Minimum execution time: 151_077_000 picoseconds. + Weight::from_parts(165_283_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn vote_existing() -> Weight { + // Proof Size summary in bytes: + // Measured: `14166` + // Estimated: `83866` + // Minimum execution time: 232_420_000 picoseconds. + Weight::from_parts(244_439_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn remove_vote() -> Weight { + // Proof Size summary in bytes: + // Measured: `13918` + // Estimated: `83866` + // Minimum execution time: 205_017_000 picoseconds. + Weight::from_parts(216_594_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + fn remove_other_vote() -> Weight { + // Proof Size summary in bytes: + // Measured: `13004` + // Estimated: `30706` + // Minimum execution time: 84_226_000 picoseconds. + Weight::from_parts(91_255_000, 0) + .saturating_add(Weight::from_parts(0, 30706)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ConvictionVoting VotingFor (r:2 w:2) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:512 w:512) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 512]`. + fn delegate(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `29640 + r * (365 ±0)` + // Estimated: `83866 + r * (3411 ±0)` + // Minimum execution time: 78_708_000 picoseconds. + Weight::from_parts(2_053_488_615, 0) + .saturating_add(Weight::from_parts(0, 83866)) + // Standard Error: 179_271 + .saturating_add(Weight::from_parts(47_806_482, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 3411).saturating_mul(r.into())) + } + /// Storage: ConvictionVoting VotingFor (r:2 w:2) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:512 w:512) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 512]`. + fn undelegate(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `29555 + r * (365 ±0)` + // Estimated: `83866 + r * (3411 ±0)` + // Minimum execution time: 45_232_000 picoseconds. + Weight::from_parts(2_045_021_014, 0) + .saturating_add(Weight::from_parts(0, 83866)) + // Standard Error: 185_130 + .saturating_add(Weight::from_parts(47_896_011, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 3411).saturating_mul(r.into())) + } + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + fn unlock() -> Weight { + // Proof Size summary in bytes: + // Measured: `12218` + // Estimated: `30706` + // Minimum execution time: 116_446_000 picoseconds. + Weight::from_parts(124_043_000, 0) + .saturating_add(Weight::from_parts(0, 30706)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_democracy.rs b/polkadot/runtime/kusama/src/weights/pallet_democracy.rs new file mode 100644 index 0000000000000000000000000000000000000000..794c8c8159660e8fe7f1eb27f3b1b3905d5dc5df --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_democracy.rs @@ -0,0 +1,513 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +//! Autogenerated weights for `pallet_democracy` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-03-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_democracy +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `pallet_democracy`. +pub struct WeightInfo(PhantomData); +impl pallet_democracy::WeightInfo for WeightInfo { + /// Storage: Democracy PublicPropCount (r:1 w:1) + /// Proof: Democracy PublicPropCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:0) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:0 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + fn propose() -> Weight { + // Proof Size summary in bytes: + // Measured: `4768` + // Estimated: `26379` + // Minimum execution time: 35_098_000 picoseconds. + Weight::from_parts(35_696_000, 0) + .saturating_add(Weight::from_parts(0, 26379)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + fn second() -> Weight { + // Proof Size summary in bytes: + // Measured: `3523` + // Estimated: `6695` + // Minimum execution time: 32_218_000 picoseconds. + Weight::from_parts(32_458_000, 0) + .saturating_add(Weight::from_parts(0, 6695)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + fn vote_new() -> Weight { + // Proof Size summary in bytes: + // Measured: `3437` + // Estimated: `15690` + // Minimum execution time: 46_641_000 picoseconds. + Weight::from_parts(47_324_000, 0) + .saturating_add(Weight::from_parts(0, 15690)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + fn vote_existing() -> Weight { + // Proof Size summary in bytes: + // Measured: `3459` + // Estimated: `15690` + // Minimum execution time: 47_172_000 picoseconds. + Weight::from_parts(47_732_000, 0) + .saturating_add(Weight::from_parts(0, 15690)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy Cancellations (r:1 w:1) + /// Proof: Democracy Cancellations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn emergency_cancel() -> Weight { + // Proof Size summary in bytes: + // Measured: `333` + // Estimated: `10682` + // Minimum execution time: 25_744_000 picoseconds. + Weight::from_parts(26_226_000, 0) + .saturating_add(Weight::from_parts(0, 10682)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:3 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:0 w:1) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + fn blacklist() -> Weight { + // Proof Size summary in bytes: + // Measured: `5877` + // Estimated: `42332` + // Minimum execution time: 88_365_000 picoseconds. + Weight::from_parts(90_080_000, 0) + .saturating_add(Weight::from_parts(0, 42332)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:0) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + fn external_propose() -> Weight { + // Proof Size summary in bytes: + // Measured: `3383` + // Estimated: `8320` + // Minimum execution time: 12_868_000 picoseconds. + Weight::from_parts(13_178_000, 0) + .saturating_add(Weight::from_parts(0, 8320)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:0 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + fn external_propose_majority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_714_000 picoseconds. + Weight::from_parts(3_895_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:0 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + fn external_propose_default() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_565_000 picoseconds. + Weight::from_parts(3_831_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:1) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:2) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:0 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + fn fast_track() -> Weight { + // Proof Size summary in bytes: + // Measured: `253` + // Estimated: `6624` + // Minimum execution time: 26_453_000 picoseconds. + Weight::from_parts(26_938_000, 0) + .saturating_add(Weight::from_parts(0, 6624)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:1) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn veto_external() -> Weight { + // Proof Size summary in bytes: + // Measured: `3486` + // Estimated: `11838` + // Minimum execution time: 30_869_000 picoseconds. + Weight::from_parts(31_397_000, 0) + .saturating_add(Weight::from_parts(0, 11838)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn cancel_proposal() -> Weight { + // Proof Size summary in bytes: + // Measured: `5788` + // Estimated: `31993` + // Minimum execution time: 72_692_000 picoseconds. + Weight::from_parts(73_692_000, 0) + .saturating_add(Weight::from_parts(0, 31993)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:0 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + fn cancel_referendum() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3518` + // Minimum execution time: 19_506_000 picoseconds. + Weight::from_parts(19_823_000, 0) + .saturating_add(Weight::from_parts(0, 3518)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Democracy LowestUnbaked (r:1 w:1) + /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:0) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn on_initialize_base(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `211 + r * (86 ±0)` + // Estimated: `3968 + r * (2676 ±0)` + // Minimum execution time: 6_019_000 picoseconds. + Weight::from_parts(9_632_674, 0) + .saturating_add(Weight::from_parts(0, 3968)) + // Standard Error: 6_651 + .saturating_add(Weight::from_parts(2_769_264, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy LowestUnbaked (r:1 w:1) + /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:0) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy LastTabledWasExternal (r:1 w:0) + /// Proof: Democracy LastTabledWasExternal (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn on_initialize_base_with_launch_period(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `211 + r * (86 ±0)` + // Estimated: `25258 + r * (2676 ±0)` + // Minimum execution time: 9_143_000 picoseconds. + Weight::from_parts(12_247_629, 0) + .saturating_add(Weight::from_parts(0, 25258)) + // Standard Error: 6_077 + .saturating_add(Weight::from_parts(2_764_547, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy VotingOf (r:3 w:3) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:99) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn delegate(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `797 + r * (108 ±0)` + // Estimated: `25554 + r * (2676 ±0)` + // Minimum execution time: 41_153_000 picoseconds. + Weight::from_parts(42_787_487, 0) + .saturating_add(Weight::from_parts(0, 25554)) + // Standard Error: 7_883 + .saturating_add(Weight::from_parts(3_862_521, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy VotingOf (r:2 w:2) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:99) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn undelegate(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `460 + r * (108 ±0)` + // Estimated: `14520 + r * (2676 ±0)` + // Minimum execution time: 20_767_000 picoseconds. + Weight::from_parts(21_768_239, 0) + .saturating_add(Weight::from_parts(0, 14520)) + // Standard Error: 9_791 + .saturating_add(Weight::from_parts(3_862_103, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy PublicProps (r:0 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + fn clear_public_proposals() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_663_000 picoseconds. + Weight::from_parts(3_798_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn unlock_remove(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `530` + // Estimated: `15617` + // Minimum execution time: 19_923_000 picoseconds. + Weight::from_parts(25_945_279, 0) + .saturating_add(Weight::from_parts(0, 15617)) + // Standard Error: 1_366 + .saturating_add(Weight::from_parts(22_003, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn unlock_set(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `531 + r * (22 ±0)` + // Estimated: `15617` + // Minimum execution time: 24_393_000 picoseconds. + Weight::from_parts(25_690_593, 0) + .saturating_add(Weight::from_parts(0, 15617)) + // Standard Error: 553 + .saturating_add(Weight::from_parts(59_042, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 100]`. + fn remove_vote(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `695 + r * (26 ±0)` + // Estimated: `10926` + // Minimum execution time: 15_551_000 picoseconds. + Weight::from_parts(17_809_948, 0) + .saturating_add(Weight::from_parts(0, 10926)) + // Standard Error: 1_907 + .saturating_add(Weight::from_parts(86_496, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 100]`. + fn remove_other_vote(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `695 + r * (26 ±0)` + // Estimated: `10926` + // Minimum execution time: 16_027_000 picoseconds. + Weight::from_parts(17_860_077, 0) + .saturating_add(Weight::from_parts(0, 10926)) + // Standard Error: 1_950 + .saturating_add(Weight::from_parts(87_722, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn set_external_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `323` + // Estimated: `5173` + // Minimum execution time: 17_551_000 picoseconds. + Weight::from_parts(17_776_000, 0) + .saturating_add(Weight::from_parts(0, 5173)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn clear_external_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `253` + // Estimated: `5135` + // Minimum execution time: 16_020_000 picoseconds. + Weight::from_parts(16_477_000, 0) + .saturating_add(Weight::from_parts(0, 5135)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn set_proposal_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `4855` + // Estimated: `21743` + // Minimum execution time: 33_144_000 picoseconds. + Weight::from_parts(33_457_000, 0) + .saturating_add(Weight::from_parts(0, 21743)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn clear_proposal_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `4789` + // Estimated: `21705` + // Minimum execution time: 31_022_000 picoseconds. + Weight::from_parts(31_534_000, 0) + .saturating_add(Weight::from_parts(0, 21705)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn set_referendum_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 14_512_000 picoseconds. + Weight::from_parts(14_769_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn clear_referendum_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `269` + // Estimated: `7184` + // Minimum execution time: 17_966_000 picoseconds. + Weight::from_parts(18_270_000, 0) + .saturating_add(Weight::from_parts(0, 7184)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_election_provider_multi_phase.rs b/polkadot/runtime/kusama/src/weights/pallet_election_provider_multi_phase.rs new file mode 100644 index 0000000000000000000000000000000000000000..d670d324aba04543a2fe98b654ae341f55009c38 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_election_provider_multi_phase.rs @@ -0,0 +1,272 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_election_provider_multi_phase` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_election_provider_multi_phase +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_election_provider_multi_phase`. +pub struct WeightInfo(PhantomData); +impl pallet_election_provider_multi_phase::WeightInfo for WeightInfo { + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentPlannedSession (r:1 w:0) + /// Proof: Staking CurrentPlannedSession (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Babe EpochIndex (r:1 w:0) + /// Proof: Babe EpochIndex (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe GenesisSlot (r:1 w:0) + /// Proof: Babe GenesisSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Staking ForceEra (r:1 w:0) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + fn on_initialize_nothing() -> Weight { + // Proof Size summary in bytes: + // Measured: `959` + // Estimated: `3481` + // Minimum execution time: 21_207_000 picoseconds. + Weight::from_parts(22_059_000, 0) + .saturating_add(Weight::from_parts(0, 3481)) + .saturating_add(T::DbWeight::get().reads(8)) + } + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + fn on_initialize_open_signed() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `1565` + // Minimum execution time: 11_472_000 picoseconds. + Weight::from_parts(11_772_000, 0) + .saturating_add(Weight::from_parts(0, 1565)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + fn on_initialize_open_unsigned() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `1565` + // Minimum execution time: 12_466_000 picoseconds. + Weight::from_parts(12_954_000, 0) + .saturating_add(Weight::from_parts(0, 1565)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + fn finalize_signed_phase_accept_solution() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 31_347_000 picoseconds. + Weight::from_parts(32_088_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn finalize_signed_phase_reject_solution() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 21_061_000 picoseconds. + Weight::from_parts(21_819_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + fn create_snapshot_internal(v: u32, _t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 796_200_000 picoseconds. + Weight::from_parts(848_268_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 6_942 + .saturating_add(Weight::from_parts(625_196, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `a` is `[500, 800]`. + /// The range of component `d` is `[200, 400]`. + fn elect_queued(a: u32, d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `832 + a * (1152 ±0) + d * (47 ±0)` + // Estimated: `4282 + a * (1152 ±0) + d * (48 ±0)` + // Minimum execution time: 598_364_000 picoseconds. + Weight::from_parts(3_028_177, 0) + .saturating_add(Weight::from_parts(0, 4282)) + // Standard Error: 29_462 + .saturating_add(Weight::from_parts(1_292_240, 0).saturating_mul(a.into())) + // Standard Error: 44_163 + .saturating_add(Weight::from_parts(113_479, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(9)) + .saturating_add(Weight::from_parts(0, 1152).saturating_mul(a.into())) + .saturating_add(Weight::from_parts(0, 48).saturating_mul(d.into())) + } + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TransactionPayment NextFeeMultiplier (r:1 w:0) + /// Proof: TransactionPayment NextFeeMultiplier (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) + fn submit() -> Weight { + // Proof Size summary in bytes: + // Measured: `1170` + // Estimated: `2655` + // Minimum execution time: 50_887_000 picoseconds. + Weight::from_parts(53_335_000, 0) + .saturating_add(Weight::from_parts(0, 2655)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `a` is `[500, 800]`. + /// The range of component `d` is `[200, 400]`. + fn submit_unsigned(v: u32, t: u32, a: u32, _d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `185 + t * (32 ±0) + v * (809 ±0)` + // Estimated: `1670 + t * (32 ±0) + v * (809 ±0)` + // Minimum execution time: 9_246_269_000 picoseconds. + Weight::from_parts(9_558_256_000, 0) + .saturating_add(Weight::from_parts(0, 1670)) + // Standard Error: 40_767 + .saturating_add(Weight::from_parts(476_361, 0).saturating_mul(v.into())) + // Standard Error: 120_810 + .saturating_add(Weight::from_parts(7_762_441, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) + .saturating_add(Weight::from_parts(0, 809).saturating_mul(v.into())) + } + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `a` is `[500, 800]`. + /// The range of component `d` is `[200, 400]`. + fn feasibility_check(v: u32, t: u32, a: u32, _d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `160 + t * (32 ±0) + v * (809 ±0)` + // Estimated: `1645 + t * (32 ±0) + v * (809 ±0)` + // Minimum execution time: 7_414_707_000 picoseconds. + Weight::from_parts(7_699_413_000, 0) + .saturating_add(Weight::from_parts(0, 1645)) + // Standard Error: 29_542 + .saturating_add(Weight::from_parts(312_856, 0).saturating_mul(v.into())) + // Standard Error: 87_545 + .saturating_add(Weight::from_parts(5_993_730, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) + .saturating_add(Weight::from_parts(0, 809).saturating_mul(v.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_elections_phragmen.rs b/polkadot/runtime/kusama/src/weights/pallet_elections_phragmen.rs new file mode 100644 index 0000000000000000000000000000000000000000..a5c1c4dfd3d0ee5b34d98c935c6d3c10a46aa429 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_elections_phragmen.rs @@ -0,0 +1,303 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +//! Autogenerated weights for `pallet_elections_phragmen` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-03-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_elections_phragmen +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `pallet_elections_phragmen`. +pub struct WeightInfo(PhantomData); +impl pallet_elections_phragmen::WeightInfo for WeightInfo { + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// The range of component `v` is `[1, 16]`. + fn vote_equal(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `403 + v * (80 ±0)` + // Estimated: `14292 + v * (320 ±0)` + // Minimum execution time: 27_353_000 picoseconds. + Weight::from_parts(28_103_445, 0) + .saturating_add(Weight::from_parts(0, 14292)) + // Standard Error: 4_556 + .saturating_add(Weight::from_parts(117_766, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 320).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// The range of component `v` is `[2, 16]`. + fn vote_more(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `371 + v * (80 ±0)` + // Estimated: `14164 + v * (320 ±0)` + // Minimum execution time: 36_885_000 picoseconds. + Weight::from_parts(37_769_975, 0) + .saturating_add(Weight::from_parts(0, 14164)) + // Standard Error: 6_586 + .saturating_add(Weight::from_parts(123_567, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 320).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// The range of component `v` is `[2, 16]`. + fn vote_less(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `403 + v * (80 ±0)` + // Estimated: `14292 + v * (320 ±0)` + // Minimum execution time: 36_610_000 picoseconds. + Weight::from_parts(37_524_808, 0) + .saturating_add(Weight::from_parts(0, 14292)) + // Standard Error: 6_164 + .saturating_add(Weight::from_parts(147_944, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 320).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + fn remove_voter() -> Weight { + // Proof Size summary in bytes: + // Measured: `925` + // Estimated: `9154` + // Minimum execution time: 33_052_000 picoseconds. + Weight::from_parts(33_677_000, 0) + .saturating_add(Weight::from_parts(0, 9154)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: PhragmenElection Candidates (r:1 w:1) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `c` is `[1, 1000]`. + fn submit_candidacy(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2712 + c * (48 ±0)` + // Estimated: `12585 + c * (144 ±0)` + // Minimum execution time: 32_163_000 picoseconds. + Weight::from_parts(24_757_419, 0) + .saturating_add(Weight::from_parts(0, 12585)) + // Standard Error: 902 + .saturating_add(Weight::from_parts(79_765, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 144).saturating_mul(c.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:1) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `c` is `[1, 1000]`. + fn renounce_candidacy_candidate(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `284 + c * (48 ±0)` + // Estimated: `1756 + c * (48 ±0)` + // Minimum execution time: 24_805_000 picoseconds. + Weight::from_parts(17_940_635, 0) + .saturating_add(Weight::from_parts(0, 1756)) + // Standard Error: 888 + .saturating_add(Weight::from_parts(59_369, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) + } + /// Storage: PhragmenElection Members (r:1 w:1) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + fn renounce_candidacy_members() -> Weight { + // Proof Size summary in bytes: + // Measured: `2986` + // Estimated: `20870` + // Minimum execution time: 42_908_000 picoseconds. + Weight::from_parts(43_409_000, 0) + .saturating_add(Weight::from_parts(0, 20870)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + fn renounce_candidacy_runners_up() -> Weight { + // Proof Size summary in bytes: + // Measured: `1681` + // Estimated: `3166` + // Minimum execution time: 27_419_000 picoseconds. + Weight::from_parts(27_912_000, 0) + .saturating_add(Weight::from_parts(0, 3166)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + fn remove_member_without_replacement() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_000_000_000_000 picoseconds. + Weight::from_parts(2_000_000_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: PhragmenElection Members (r:1 w:1) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + fn remove_member_with_replacement() -> Weight { + // Proof Size summary in bytes: + // Measured: `2986` + // Estimated: `24463` + // Minimum execution time: 57_465_000 picoseconds. + Weight::from_parts(58_107_000, 0) + .saturating_add(Weight::from_parts(0, 24463)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: PhragmenElection Voting (r:10001 w:10000) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Balances Locks (r:10000 w:10000) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: System Account (r:10000 w:10000) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `v` is `[5000, 10000]`. + /// The range of component `d` is `[0, 5000]`. + fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `35989 + v * (808 ±0)` + // Estimated: `154956 + v * (12084 ±0)` + // Minimum execution time: 319_677_473_000 picoseconds. + Weight::from_parts(320_382_361_000, 0) + .saturating_add(Weight::from_parts(0, 154956)) + // Standard Error: 270_292 + .saturating_add(Weight::from_parts(38_671_603, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 12084).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:1) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:1) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:10001 w:0) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:962 w:962) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: PhragmenElection ElectionRounds (r:1 w:1) + /// Proof Skipped: PhragmenElection ElectionRounds (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:0 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `c` is `[1, 1000]`. + /// The range of component `v` is `[1, 10000]`. + /// The range of component `e` is `[10000, 160000]`. + fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + v * (607 ±0) + e * (28 ±0)` + // Estimated: `4839313 + v * (5481 ±4) + e * (123 ±0) + c * (2560 ±0)` + // Minimum execution time: 30_795_431_000 picoseconds. + Weight::from_parts(30_861_700_000, 0) + .saturating_add(Weight::from_parts(0, 4839313)) + // Standard Error: 482_348 + .saturating_add(Weight::from_parts(37_626_560, 0).saturating_mul(v.into())) + // Standard Error: 30_954 + .saturating_add(Weight::from_parts(2_016_889, 0).saturating_mul(e.into())) + .saturating_add(T::DbWeight::get().reads(265)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 5481).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(0, 123).saturating_mul(e.into())) + .saturating_add(Weight::from_parts(0, 2560).saturating_mul(c.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_fast_unstake.rs b/polkadot/runtime/kusama/src/weights/pallet_fast_unstake.rs new file mode 100644 index 0000000000000000000000000000000000000000..34fec8e784f73538d5d9cddbc948e989c70b5455 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_fast_unstake.rs @@ -0,0 +1,203 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_fast_unstake` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_fast_unstake +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_fast_unstake`. +pub struct WeightInfo(PhantomData); +impl pallet_fast_unstake::WeightInfo for WeightInfo { + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:1) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(3191), added: 3686, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:0) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:64 w:0) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Bonded (r:64 w:64) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:64 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:64 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: System Account (r:64 w:64) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:64 w:64) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:64 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:0 w:64) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:64) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 64]`. + fn on_idle_unstake(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1176 + b * (343 ±0)` + // Estimated: `4676 + b * (3774 ±0)` + // Minimum execution time: 90_522_000 picoseconds. + Weight::from_parts(30_621_885, 0) + .saturating_add(Weight::from_parts(0, 4676)) + // Standard Error: 35_474 + .saturating_add(Weight::from_parts(58_149_619, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(b.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(b.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(b.into())) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:1) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(3191), added: 3686, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:0) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStakers (r:257 w:0) + /// Proof Skipped: Staking ErasStakers (max_values: None, max_size: None, mode: Measured) + /// The range of component `v` is `[1, 256]`. + /// The range of component `b` is `[1, 64]`. + fn on_idle_check(v: u32, b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1344 + b * (48 ±0) + v * (18487 ±0)` + // Estimated: `4676 + b * (49 ±0) + v * (20963 ±0)` + // Minimum execution time: 1_633_429_000 picoseconds. + Weight::from_parts(1_647_031_000, 0) + .saturating_add(Weight::from_parts(0, 4676)) + // Standard Error: 14_231_088 + .saturating_add(Weight::from_parts(454_485_752, 0).saturating_mul(v.into())) + // Standard Error: 56_940_204 + .saturating_add(Weight::from_parts(1_784_096_716, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 49).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 20963).saturating_mul(v.into())) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: FastUnstake Queue (r:1 w:1) + /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:0) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(3191), added: 3686, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:1) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn register_fast_unstake() -> Weight { + // Proof Size summary in bytes: + // Measured: `1826` + // Estimated: `4764` + // Minimum execution time: 120_577_000 picoseconds. + Weight::from_parts(123_610_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(15)) + .saturating_add(T::DbWeight::get().writes(9)) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: FastUnstake Queue (r:1 w:1) + /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:0) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(3191), added: 3686, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:1) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn deregister() -> Weight { + // Proof Size summary in bytes: + // Measured: `1084` + // Estimated: `4676` + // Minimum execution time: 42_258_000 picoseconds. + Weight::from_parts(43_647_000, 0) + .saturating_add(Weight::from_parts(0, 4676)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:0 w:1) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn control() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_524_000 picoseconds. + Weight::from_parts(2_654_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_identity.rs b/polkadot/runtime/kusama/src/weights/pallet_identity.rs new file mode 100644 index 0000000000000000000000000000000000000000..f4952db592b421cd67fd61b802c1ddc7a431780f --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_identity.rs @@ -0,0 +1,359 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_identity` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_identity +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_identity`. +pub struct WeightInfo(PhantomData); +impl pallet_identity::WeightInfo for WeightInfo { + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn add_registrar(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `32 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 11_854_000 picoseconds. + Weight::from_parts(12_968_221, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 5_813 + .saturating_add(Weight::from_parts(102_873, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn set_identity(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `442 + r * (5 ±0)` + // Estimated: `11003` + // Minimum execution time: 32_800_000 picoseconds. + Weight::from_parts(28_706_621, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 12_190 + .saturating_add(Weight::from_parts(261_969, 0).saturating_mul(r.into())) + // Standard Error: 2_378 + .saturating_add(Weight::from_parts(500_617, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:100 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn set_subs_new(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `11003 + s * (2589 ±0)` + // Minimum execution time: 8_815_000 picoseconds. + Weight::from_parts(21_946_444, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 5_757 + .saturating_add(Weight::from_parts(3_241_262, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(s.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 2589).saturating_mul(s.into())) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 100]`. + fn set_subs_old(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `194 + p * (32 ±0)` + // Estimated: `11003` + // Minimum execution time: 8_892_000 picoseconds. + Weight::from_parts(21_343_974, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 5_109 + .saturating_add(Weight::from_parts(1_410_415, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + } + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `s` is `[0, 100]`. + /// The range of component `x` is `[0, 100]`. + fn clear_identity(r: u32, s: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 60_331_000 picoseconds. + Weight::from_parts(29_115_598, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 21_877 + .saturating_add(Weight::from_parts(216_644, 0).saturating_mul(r.into())) + // Standard Error: 4_272 + .saturating_add(Weight::from_parts(1_420_433, 0).saturating_mul(s.into())) + // Standard Error: 4_272 + .saturating_add(Weight::from_parts(311_436, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn request_judgement(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `367 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 33_470_000 picoseconds. + Weight::from_parts(32_277_730, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 4_577 + .saturating_add(Weight::from_parts(121_062, 0).saturating_mul(r.into())) + // Standard Error: 893 + .saturating_add(Weight::from_parts(496_715, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn cancel_request(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `398 + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 29_626_000 picoseconds. + Weight::from_parts(28_419_375, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 5_566 + .saturating_add(Weight::from_parts(143_337, 0).saturating_mul(r.into())) + // Standard Error: 1_086 + .saturating_add(Weight::from_parts(487_332, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_fee(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_221_000 picoseconds. + Weight::from_parts(7_708_979, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_516 + .saturating_add(Weight::from_parts(101_163, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_account_id(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_288_000 picoseconds. + Weight::from_parts(7_757_754, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_365 + .saturating_add(Weight::from_parts(95_345, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_fields(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_204_000 picoseconds. + Weight::from_parts(7_679_617, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_358 + .saturating_add(Weight::from_parts(100_186, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + /// The range of component `x` is `[0, 100]`. + fn provide_judgement(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `445 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 23_125_000 picoseconds. + Weight::from_parts(22_392_893, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 5_154 + .saturating_add(Weight::from_parts(121_813, 0).saturating_mul(r.into())) + // Standard Error: 953 + .saturating_add(Weight::from_parts(806_355, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `s` is `[0, 100]`. + /// The range of component `x` is `[0, 100]`. + fn kill_identity(r: u32, s: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `676 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 76_226_000 picoseconds. + Weight::from_parts(35_456_327, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 18_829 + .saturating_add(Weight::from_parts(615_512, 0).saturating_mul(r.into())) + // Standard Error: 3_677 + .saturating_add(Weight::from_parts(1_462_016, 0).saturating_mul(s.into())) + // Standard Error: 3_677 + .saturating_add(Weight::from_parts(328_050, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 99]`. + fn add_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `475 + s * (36 ±0)` + // Estimated: `11003` + // Minimum execution time: 29_381_000 picoseconds. + Weight::from_parts(33_288_068, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_624 + .saturating_add(Weight::from_parts(120_173, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 100]`. + fn rename_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `591 + s * (3 ±0)` + // Estimated: `11003` + // Minimum execution time: 12_418_000 picoseconds. + Weight::from_parts(13_798_930, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 856 + .saturating_add(Weight::from_parts(43_306, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 100]`. + fn remove_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `638 + s * (35 ±0)` + // Estimated: `11003` + // Minimum execution time: 33_242_000 picoseconds. + Weight::from_parts(36_552_253, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 2_385 + .saturating_add(Weight::from_parts(98_359, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 99]`. + fn quit_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `704 + s * (37 ±0)` + // Estimated: `6723` + // Minimum execution time: 24_017_000 picoseconds. + Weight::from_parts(27_149_414, 0) + .saturating_add(Weight::from_parts(0, 6723)) + // Standard Error: 1_769 + .saturating_add(Weight::from_parts(79_539, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_im_online.rs b/polkadot/runtime/kusama/src/weights/pallet_im_online.rs new file mode 100644 index 0000000000000000000000000000000000000000..3bb3d65c4a6b0e462aab3e179c77203a121b5a14 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_im_online.rs @@ -0,0 +1,77 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_im_online` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_im_online +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_im_online`. +pub struct WeightInfo(PhantomData); +impl pallet_im_online::WeightInfo for WeightInfo { + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session CurrentIndex (r:1 w:0) + /// Proof Skipped: Session CurrentIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ImOnline Keys (r:1 w:0) + /// Proof: ImOnline Keys (max_values: Some(1), max_size: Some(320002), added: 320497, mode: MaxEncodedLen) + /// Storage: ImOnline ReceivedHeartbeats (r:1 w:1) + /// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(25), added: 2500, mode: MaxEncodedLen) + /// Storage: ImOnline AuthoredBlocks (r:1 w:0) + /// Proof: ImOnline AuthoredBlocks (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// The range of component `k` is `[1, 1000]`. + fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `361 + k * (32 ±0)` + // Estimated: `321487 + k * (1761 ±0)` + // Minimum execution time: 82_038_000 picoseconds. + Weight::from_parts(100_726_620, 0) + .saturating_add(Weight::from_parts(0, 321487)) + // Standard Error: 600 + .saturating_add(Weight::from_parts(30_346, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 1761).saturating_mul(k.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_indices.rs b/polkadot/runtime/kusama/src/weights/pallet_indices.rs new file mode 100644 index 0000000000000000000000000000000000000000..b26562975cf80b4bd095956ad5be0a804bceed9c --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_indices.rs @@ -0,0 +1,117 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_indices` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_indices +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_indices`. +pub struct WeightInfo(PhantomData); +impl pallet_indices::WeightInfo for WeightInfo { + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `142` + // Estimated: `3534` + // Minimum execution time: 25_322_000 picoseconds. + Weight::from_parts(26_124_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `341` + // Estimated: `3593` + // Minimum execution time: 36_790_000 picoseconds. + Weight::from_parts(37_218_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn free() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3534` + // Minimum execution time: 25_968_000 picoseconds. + Weight::from_parts(26_450_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `341` + // Estimated: `3593` + // Minimum execution time: 27_734_000 picoseconds. + Weight::from_parts(28_523_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn freeze() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3534` + // Minimum execution time: 27_980_000 picoseconds. + Weight::from_parts(28_448_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_membership.rs b/polkadot/runtime/kusama/src/weights/pallet_membership.rs new file mode 100644 index 0000000000000000000000000000000000000000..6b144bc879494612c89052ed84bf5d221075aa60 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_membership.rs @@ -0,0 +1,202 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +//! Autogenerated weights for `pallet_membership` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-03-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_membership +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `pallet_membership`. +pub struct WeightInfo(PhantomData); +impl pallet_membership::WeightInfo for WeightInfo { + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 99]`. + fn add_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `208 + m * (64 ±0)` + // Estimated: `6793 + m * (192 ±0)` + // Minimum execution time: 15_847_000 picoseconds. + Weight::from_parts(16_597_325, 0) + .saturating_add(Weight::from_parts(0, 6793)) + // Standard Error: 411 + .saturating_add(Weight::from_parts(35_801, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 192).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[2, 100]`. + fn remove_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `312 + m * (64 ±0)` + // Estimated: `8622 + m * (192 ±0)` + // Minimum execution time: 18_412_000 picoseconds. + Weight::from_parts(19_251_698, 0) + .saturating_add(Weight::from_parts(0, 8622)) + // Standard Error: 474 + .saturating_add(Weight::from_parts(32_206, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 192).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[2, 100]`. + fn swap_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `312 + m * (64 ±0)` + // Estimated: `8622 + m * (192 ±0)` + // Minimum execution time: 18_502_000 picoseconds. + Weight::from_parts(19_583_888, 0) + .saturating_add(Weight::from_parts(0, 8622)) + // Standard Error: 619 + .saturating_add(Weight::from_parts(44_408, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 192).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn reset_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `312 + m * (64 ±0)` + // Estimated: `8622 + m * (192 ±0)` + // Minimum execution time: 18_088_000 picoseconds. + Weight::from_parts(19_292_324, 0) + .saturating_add(Weight::from_parts(0, 8622)) + // Standard Error: 759 + .saturating_add(Weight::from_parts(162_348, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 192).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn change_key(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `312 + m * (64 ±0)` + // Estimated: `8622 + m * (192 ±0)` + // Minimum execution time: 19_134_000 picoseconds. + Weight::from_parts(20_242_466, 0) + .saturating_add(Weight::from_parts(0, 8622)) + // Standard Error: 962 + .saturating_add(Weight::from_parts(47_779, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 192).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:0) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalMembership Prime (r:0 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn set_prime(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `32 + m * (32 ±0)` + // Estimated: `4719 + m * (32 ±0)` + // Minimum execution time: 6_726_000 picoseconds. + Weight::from_parts(6_966_055, 0) + .saturating_add(Weight::from_parts(0, 4719)) + // Standard Error: 255 + .saturating_add(Weight::from_parts(13_950, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Prime (r:0 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn clear_prime(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_010_000 picoseconds. + Weight::from_parts(3_196_429, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 78 + .saturating_add(Weight::from_parts(471, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_message_queue.rs b/polkadot/runtime/kusama/src/weights/pallet_message_queue.rs new file mode 100644 index 0000000000000000000000000000000000000000..f149eef194fb5895665cd853cd7fa2ffd58600df --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_message_queue.rs @@ -0,0 +1,193 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_message_queue` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_message_queue +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_message_queue`. +pub struct WeightInfo(PhantomData); +impl pallet_message_queue::WeightInfo for WeightInfo { + /// Storage: MessageQueue ServiceHead (r:1 w:0) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn ready_ring_knit() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `6050` + // Minimum execution time: 11_603_000 picoseconds. + Weight::from_parts(11_953_000, 0) + .saturating_add(Weight::from_parts(0, 6050)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + fn ready_ring_unknit() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `6050` + // Minimum execution time: 10_668_000 picoseconds. + Weight::from_parts(11_105_000, 0) + .saturating_add(Weight::from_parts(0, 6050)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn service_queue_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `42` + // Estimated: `3520` + // Minimum execution time: 4_158_000 picoseconds. + Weight::from_parts(4_379_000, 0) + .saturating_add(Weight::from_parts(0, 3520)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + fn service_page_base_completion() -> Weight { + // Proof Size summary in bytes: + // Measured: `115` + // Estimated: `69051` + // Minimum execution time: 5_873_000 picoseconds. + Weight::from_parts(6_002_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + fn service_page_base_no_completion() -> Weight { + // Proof Size summary in bytes: + // Measured: `115` + // Estimated: `69051` + // Minimum execution time: 6_110_000 picoseconds. + Weight::from_parts(6_385_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_page_item() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 92_242_000 picoseconds. + Weight::from_parts(92_796_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn bump_service_head() -> Weight { + // Proof Size summary in bytes: + // Measured: `149` + // Estimated: `3520` + // Minimum execution time: 6_386_000 picoseconds. + Weight::from_parts(6_629_000, 0) + .saturating_add(Weight::from_parts(0, 3520)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn reap_page() -> Weight { + // Proof Size summary in bytes: + // Measured: `65714` + // Estimated: `69051` + // Minimum execution time: 59_294_000 picoseconds. + Weight::from_parts(60_608_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn execute_overweight_page_removed() -> Weight { + // Proof Size summary in bytes: + // Measured: `65714` + // Estimated: `69051` + // Minimum execution time: 75_134_000 picoseconds. + Weight::from_parts(76_729_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn execute_overweight_page_updated() -> Weight { + // Proof Size summary in bytes: + // Measured: `65714` + // Estimated: `69051` + // Minimum execution time: 117_320_000 picoseconds. + Weight::from_parts(119_640_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_multisig.rs b/polkadot/runtime/kusama/src/weights/pallet_multisig.rs new file mode 100644 index 0000000000000000000000000000000000000000..108189c6ca1db47df39a19983dfbc79079470315 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_multisig.rs @@ -0,0 +1,165 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_multisig` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_multisig +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_multisig`. +pub struct WeightInfo(PhantomData); +impl pallet_multisig::WeightInfo for WeightInfo { + /// The range of component `z` is `[0, 10000]`. + fn as_multi_threshold_1(z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_299_000 picoseconds. + Weight::from_parts(14_368_762, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 5 + .saturating_add(Weight::from_parts(557, 0).saturating_mul(z.into())) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_create(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `301 + s * (2 ±0)` + // Estimated: `6811` + // Minimum execution time: 45_147_000 picoseconds. + Weight::from_parts(34_161_081, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 1_022 + .saturating_add(Weight::from_parts(127_000, 0).saturating_mul(s.into())) + // Standard Error: 10 + .saturating_add(Weight::from_parts(1_553, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[3, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_approve(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `320` + // Estimated: `6811` + // Minimum execution time: 29_650_000 picoseconds. + Weight::from_parts(20_868_716, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 1_323 + .saturating_add(Weight::from_parts(112_380, 0).saturating_mul(s.into())) + // Standard Error: 12 + .saturating_add(Weight::from_parts(1_440, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_complete(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `426 + s * (33 ±0)` + // Estimated: `6811` + // Minimum execution time: 50_649_000 picoseconds. + Weight::from_parts(34_736_758, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 1_738 + .saturating_add(Weight::from_parts(182_282, 0).saturating_mul(s.into())) + // Standard Error: 17 + .saturating_add(Weight::from_parts(1_824, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn approve_as_multi_create(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `301 + s * (2 ±0)` + // Estimated: `6811` + // Minimum execution time: 32_162_000 picoseconds. + Weight::from_parts(33_215_652, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 1_093 + .saturating_add(Weight::from_parts(133_715, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn approve_as_multi_approve(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `320` + // Estimated: `6811` + // Minimum execution time: 18_073_000 picoseconds. + Weight::from_parts(19_038_713, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 681 + .saturating_add(Weight::from_parts(111_279, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn cancel_as_multi(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `492 + s * (1 ±0)` + // Estimated: `6811` + // Minimum execution time: 33_867_000 picoseconds. + Weight::from_parts(34_896_470, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 1_002 + .saturating_add(Weight::from_parts(116_935, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_nis.rs b/polkadot/runtime/kusama/src/weights/pallet_nis.rs new file mode 100644 index 0000000000000000000000000000000000000000..2dc8b261eb57ac2fb6b73a34f6a11480fc66e718 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_nis.rs @@ -0,0 +1,252 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_nis` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_nis +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_nis`. +pub struct WeightInfo(PhantomData); +impl pallet_nis::WeightInfo for WeightInfo { + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(10002), added: 10497, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 999]`. + fn place_bid(l: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `10210 + l * (48 ±0)` + // Estimated: `51487` + // Minimum execution time: 49_318_000 picoseconds. + Weight::from_parts(47_894_330, 0) + .saturating_add(Weight::from_parts(0, 51487)) + // Standard Error: 1_184 + .saturating_add(Weight::from_parts(110_633, 0).saturating_mul(l.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(10002), added: 10497, mode: MaxEncodedLen) + fn place_bid_max() -> Weight { + // Proof Size summary in bytes: + // Measured: `58212` + // Estimated: `51487` + // Minimum execution time: 162_699_000 picoseconds. + Weight::from_parts(171_243_000, 0) + .saturating_add(Weight::from_parts(0, 51487)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(10002), added: 10497, mode: MaxEncodedLen) + /// The range of component `l` is `[1, 1000]`. + fn retract_bid(l: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `10210 + l * (48 ±0)` + // Estimated: `51487` + // Minimum execution time: 51_827_000 picoseconds. + Weight::from_parts(44_282_033, 0) + .saturating_add(Weight::from_parts(0, 51487)) + // Standard Error: 1_145 + .saturating_add(Weight::from_parts(121_058, 0).saturating_mul(l.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Nis Summary (r:1 w:0) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn fund_deficit() -> Weight { + // Proof Size summary in bytes: + // Measured: `225` + // Estimated: `3593` + // Minimum execution time: 39_765_000 picoseconds. + Weight::from_parts(40_525_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + fn communify() -> Weight { + // Proof Size summary in bytes: + // Measured: `470` + // Estimated: `3593` + // Minimum execution time: 75_890_000 picoseconds. + Weight::from_parts(77_519_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + fn privatize() -> Weight { + // Proof Size summary in bytes: + // Measured: `660` + // Estimated: `3593` + // Minimum execution time: 92_622_000 picoseconds. + Weight::from_parts(94_127_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + fn thaw_private() -> Weight { + // Proof Size summary in bytes: + // Measured: `388` + // Estimated: `3593` + // Minimum execution time: 49_336_000 picoseconds. + Weight::from_parts(50_333_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn thaw_communal() -> Weight { + // Proof Size summary in bytes: + // Measured: `604` + // Estimated: `3593` + // Minimum execution time: 98_220_000 picoseconds. + Weight::from_parts(100_348_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(10002), added: 10497, mode: MaxEncodedLen) + fn process_queues() -> Weight { + // Proof Size summary in bytes: + // Measured: `10658` + // Estimated: `11487` + // Minimum execution time: 33_893_000 picoseconds. + Weight::from_parts(37_495_000, 0) + .saturating_add(Weight::from_parts(0, 11487)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + fn process_queue() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `51487` + // Minimum execution time: 4_173_000 picoseconds. + Weight::from_parts(4_322_000, 0) + .saturating_add(Weight::from_parts(0, 51487)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Nis Receipts (r:0 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + fn process_bid() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_747_000 picoseconds. + Weight::from_parts(6_952_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_nomination_pools.rs b/polkadot/runtime/kusama/src/weights/pallet_nomination_pools.rs new file mode 100644 index 0000000000000000000000000000000000000000..65bb76860b3055aa5d27b3363d4629be4b9ec6e1 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_nomination_pools.rs @@ -0,0 +1,603 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_nomination_pools` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_nomination_pools +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_nomination_pools`. +pub struct WeightInfo(PhantomData); +impl pallet_nomination_pools::WeightInfo for WeightInfo { + /// Storage: NominationPools MinJoinBond (r:1 w:0) + /// Proof: NominationPools MinJoinBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembersPerPool (r:1 w:0) + /// Proof: NominationPools MaxPoolMembersPerPool (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembers (r:1 w:0) + /// Proof: NominationPools MaxPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn join() -> Weight { + // Proof Size summary in bytes: + // Measured: `3229` + // Estimated: `8877` + // Minimum execution time: 198_640_000 picoseconds. + Weight::from_parts(205_158_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(19)) + .saturating_add(T::DbWeight::get().writes(12)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn bond_extra_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `3239` + // Estimated: `8877` + // Minimum execution time: 191_638_000 picoseconds. + Weight::from_parts(200_580_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(12)) + } + /// Storage: NominationPools ClaimPermissions (r:1 w:0) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn bond_extra_other() -> Weight { + // Proof Size summary in bytes: + // Measured: `3304` + // Estimated: `8877` + // Minimum execution time: 232_697_000 picoseconds. + Weight::from_parts(238_503_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(17)) + .saturating_add(T::DbWeight::get().writes(13)) + } + /// Storage: NominationPools ClaimPermissions (r:1 w:0) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn claim_payout() -> Weight { + // Proof Size summary in bytes: + // Measured: `1171` + // Estimated: `4182` + // Minimum execution time: 79_834_000 picoseconds. + Weight::from_parts(81_793_000, 0) + .saturating_add(Weight::from_parts(0, 4182)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: NominationPools SubPoolsStorage (r:1 w:1) + /// Proof: NominationPools SubPoolsStorage (max_values: None, max_size: Some(1197), added: 3672, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForSubPoolsStorage (r:1 w:1) + /// Proof: NominationPools CounterForSubPoolsStorage (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn unbond() -> Weight { + // Proof Size summary in bytes: + // Measured: `3506` + // Estimated: `8877` + // Minimum execution time: 175_155_000 picoseconds. + Weight::from_parts(179_781_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(20)) + .saturating_add(T::DbWeight::get().writes(13)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn pool_withdraw_unbonded(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1608` + // Estimated: `4764` + // Minimum execution time: 63_367_000 picoseconds. + Weight::from_parts(65_562_125, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_722 + .saturating_add(Weight::from_parts(47_690, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools SubPoolsStorage (r:1 w:1) + /// Proof: NominationPools SubPoolsStorage (max_values: None, max_size: Some(1197), added: 3672, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools ClaimPermissions (r:0 w:1) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_update(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2036` + // Estimated: `4764` + // Minimum execution time: 132_738_000 picoseconds. + Weight::from_parts(136_968_458, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_891 + .saturating_add(Weight::from_parts(75_317, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools SubPoolsStorage (r:1 w:1) + /// Proof: NominationPools SubPoolsStorage (max_values: None, max_size: Some(1197), added: 3672, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:0) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools ReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools ReversePoolIdLookup (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools CounterForReversePoolIdLookup (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForRewardPools (r:1 w:1) + /// Proof: NominationPools CounterForRewardPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForSubPoolsStorage (r:1 w:1) + /// Proof: NominationPools CounterForSubPoolsStorage (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools Metadata (r:1 w:1) + /// Proof: NominationPools Metadata (max_values: None, max_size: Some(270), added: 2745, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForBondedPools (r:1 w:1) + /// Proof: NominationPools CounterForBondedPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: NominationPools ClaimPermissions (r:0 w:1) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_kill(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2394` + // Estimated: `6196` + // Minimum execution time: 223_915_000 picoseconds. + Weight::from_parts(229_729_576, 0) + .saturating_add(Weight::from_parts(0, 6196)) + // Standard Error: 5_670 + .saturating_add(Weight::from_parts(38_117, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(21)) + .saturating_add(T::DbWeight::get().writes(18)) + } + /// Storage: NominationPools LastPoolId (r:1 w:1) + /// Proof: NominationPools LastPoolId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MinCreateBond (r:1 w:0) + /// Proof: NominationPools MinCreateBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MinJoinBond (r:1 w:0) + /// Proof: NominationPools MinJoinBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPools (r:1 w:0) + /// Proof: NominationPools MaxPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForBondedPools (r:1 w:1) + /// Proof: NominationPools CounterForBondedPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembersPerPool (r:1 w:0) + /// Proof: NominationPools MaxPoolMembersPerPool (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembers (r:1 w:0) + /// Proof: NominationPools MaxPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForRewardPools (r:1 w:1) + /// Proof: NominationPools CounterForRewardPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools ReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools ReversePoolIdLookup (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools CounterForReversePoolIdLookup (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + fn create() -> Weight { + // Proof Size summary in bytes: + // Measured: `1222` + // Estimated: `6196` + // Minimum execution time: 193_054_000 picoseconds. + Weight::from_parts(200_888_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(22)) + .saturating_add(T::DbWeight::get().writes(15)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:1 w:0) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:25 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 24]`. + fn nominate(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1774` + // Estimated: `4556 + n * (2520 ±0)` + // Minimum execution time: 67_269_000 picoseconds. + Weight::from_parts(68_792_502, 0) + .saturating_add(Weight::from_parts(0, 4556)) + // Standard Error: 6_020 + .saturating_add(Weight::from_parts(1_407_587, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(Weight::from_parts(0, 2520).saturating_mul(n.into())) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + fn set_state() -> Weight { + // Proof Size summary in bytes: + // Measured: `1363` + // Estimated: `4556` + // Minimum execution time: 35_349_000 picoseconds. + Weight::from_parts(36_869_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools Metadata (r:1 w:1) + /// Proof: NominationPools Metadata (max_values: None, max_size: Some(270), added: 2745, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForMetadata (r:1 w:1) + /// Proof: NominationPools CounterForMetadata (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 256]`. + fn set_metadata(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `531` + // Estimated: `3735` + // Minimum execution time: 13_767_000 picoseconds. + Weight::from_parts(14_685_113, 0) + .saturating_add(Weight::from_parts(0, 3735)) + // Standard Error: 303 + .saturating_add(Weight::from_parts(1_304, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: NominationPools MinJoinBond (r:0 w:1) + /// Proof: NominationPools MinJoinBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembers (r:0 w:1) + /// Proof: NominationPools MaxPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembersPerPool (r:0 w:1) + /// Proof: NominationPools MaxPoolMembersPerPool (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MinCreateBond (r:0 w:1) + /// Proof: NominationPools MinCreateBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:0 w:1) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPools (r:0 w:1) + /// Proof: NominationPools MaxPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn set_configs() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_044_000 picoseconds. + Weight::from_parts(6_296_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + fn update_roles() -> Weight { + // Proof Size summary in bytes: + // Measured: `531` + // Estimated: `3685` + // Minimum execution time: 19_642_000 picoseconds. + Weight::from_parts(20_205_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn chill() -> Weight { + // Proof Size summary in bytes: + // Measured: `1937` + // Estimated: `4556` + // Minimum execution time: 65_923_000 picoseconds. + Weight::from_parts(68_711_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn set_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `770` + // Estimated: `3685` + // Minimum execution time: 32_824_000 picoseconds. + Weight::from_parts(33_654_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + fn set_commission_max() -> Weight { + // Proof Size summary in bytes: + // Measured: `571` + // Estimated: `3685` + // Minimum execution time: 18_577_000 picoseconds. + Weight::from_parts(19_317_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + fn set_commission_change_rate() -> Weight { + // Proof Size summary in bytes: + // Measured: `531` + // Estimated: `3685` + // Minimum execution time: 19_228_000 picoseconds. + Weight::from_parts(20_070_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools PoolMembers (r:1 w:0) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools ClaimPermissions (r:1 w:1) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + fn set_claim_permission() -> Weight { + // Proof Size summary in bytes: + // Measured: `542` + // Estimated: `4182` + // Minimum execution time: 14_300_000 picoseconds. + Weight::from_parts(14_678_000, 0) + .saturating_add(Weight::from_parts(0, 4182)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn claim_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `968` + // Estimated: `3685` + // Minimum execution time: 65_367_000 picoseconds. + Weight::from_parts(67_417_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_offences.rs b/polkadot/runtime/kusama/src/weights/pallet_offences.rs new file mode 100644 index 0000000000000000000000000000000000000000..12a045d66761c2214abfe782a1b52efd5fa6421c --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_offences.rs @@ -0,0 +1,222 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_offences` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_offences +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_offences`. +pub struct WeightInfo(PhantomData); +impl pallet_offences::WeightInfo for WeightInfo { + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:100 w:100) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:100 w:100) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:2500 w:2500) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:2500 w:2500) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:100 w:100) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:299 w:299) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:100 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking NominatorSlashInEra (r:2400 w:2400) + /// Proof: Staking NominatorSlashInEra (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[1, 100]`. + /// The range of component `o` is `[2, 100]`. + /// The range of component `n` is `[0, 24]`. + fn report_offence_im_online(_r: u32, o: u32, n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + n * (2863 ±0) + o * (1226 ±0)` + // Estimated: `128540 + n * (156186 ±29) + o * (38402 ±7)` + // Minimum execution time: 695_466_000 picoseconds. + Weight::from_parts(705_203_000, 0) + .saturating_add(Weight::from_parts(0, 128540)) + // Standard Error: 4_753_384 + .saturating_add(Weight::from_parts(476_947_930, 0).saturating_mul(o.into())) + // Standard Error: 19_364_925 + .saturating_add(Weight::from_parts(573_438_006, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(172)) + .saturating_add(T::DbWeight::get().reads((51_u64).saturating_mul(o.into()))) + .saturating_add(T::DbWeight::get().reads((185_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(165)) + .saturating_add(T::DbWeight::get().writes((50_u64).saturating_mul(o.into()))) + .saturating_add(T::DbWeight::get().writes((185_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 156186).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 38402).saturating_mul(o.into())) + } + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:1 w:1) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:1 w:1) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:25 w:25) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:25 w:25) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking NominatorSlashInEra (r:24 w:24) + /// Proof: Staking NominatorSlashInEra (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[0, 24]`. + fn report_offence_grandpa(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1831 + n * (48 ±0)` + // Estimated: `5686 + n * (2551 ±0)` + // Minimum execution time: 92_093_000 picoseconds. + Weight::from_parts(104_573_662, 0) + .saturating_add(Weight::from_parts(0, 5686)) + // Standard Error: 22_045 + .saturating_add(Weight::from_parts(10_859_187, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(19)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(13)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2551).saturating_mul(n.into())) + } + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:1 w:1) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:1 w:1) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:25 w:25) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:25 w:25) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking NominatorSlashInEra (r:24 w:24) + /// Proof: Staking NominatorSlashInEra (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[0, 24]`. + fn report_offence_babe(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1831 + n * (48 ±0)` + // Estimated: `5686 + n * (2551 ±0)` + // Minimum execution time: 92_097_000 picoseconds. + Weight::from_parts(104_496_920, 0) + .saturating_add(Weight::from_parts(0, 5686)) + // Standard Error: 25_384 + .saturating_add(Weight::from_parts(10_982_115, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(19)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(13)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2551).saturating_mul(n.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_preimage.rs b/polkadot/runtime/kusama/src/weights/pallet_preimage.rs new file mode 100644 index 0000000000000000000000000000000000000000..8c04eb2cd4ea424cc77dcdf6e882eff987408096 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_preimage.rs @@ -0,0 +1,218 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_preimage` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_preimage +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_preimage`. +pub struct WeightInfo(PhantomData); +impl pallet_preimage::WeightInfo for WeightInfo { + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `143` + // Estimated: `3556` + // Minimum execution time: 29_231_000 picoseconds. + Weight::from_parts(29_712_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 5 + .saturating_add(Weight::from_parts(2_593, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_requested_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3556` + // Minimum execution time: 15_753_000 picoseconds. + Weight::from_parts(15_927_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 5 + .saturating_add(Weight::from_parts(2_585, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_no_deposit_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3556` + // Minimum execution time: 15_147_000 picoseconds. + Weight::from_parts(15_364_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 4 + .saturating_add(Weight::from_parts(2_553, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unnote_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `289` + // Estimated: `3556` + // Minimum execution time: 52_018_000 picoseconds. + Weight::from_parts(57_037_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unnote_no_deposit_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 32_110_000 picoseconds. + Weight::from_parts(35_435_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `188` + // Estimated: `3556` + // Minimum execution time: 28_380_000 picoseconds. + Weight::from_parts(31_692_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_no_deposit_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 18_218_000 picoseconds. + Weight::from_parts(20_005_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_unnoted_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `42` + // Estimated: `3556` + // Minimum execution time: 24_225_000 picoseconds. + Weight::from_parts(27_623_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_requested_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3556` + // Minimum execution time: 11_614_000 picoseconds. + Weight::from_parts(12_372_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unrequest_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 30_214_000 picoseconds. + Weight::from_parts(32_682_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn unrequest_unnoted_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3556` + // Minimum execution time: 10_659_000 picoseconds. + Weight::from_parts(12_066_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn unrequest_multi_referenced_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3556` + // Minimum execution time: 10_770_000 picoseconds. + Weight::from_parts(11_745_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_proxy.rs b/polkadot/runtime/kusama/src/weights/pallet_proxy.rs new file mode 100644 index 0000000000000000000000000000000000000000..d30547d7d01cd95a766a13ff9a26a73418b059b5 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_proxy.rs @@ -0,0 +1,224 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_proxy` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_proxy +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_proxy`. +pub struct WeightInfo(PhantomData); +impl pallet_proxy::WeightInfo for WeightInfo { + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 15_098_000 picoseconds. + Weight::from_parts(15_489_847, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 2_263 + .saturating_add(Weight::from_parts(63_093, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn proxy_announced(a: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `554 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `5698` + // Minimum execution time: 39_651_000 picoseconds. + Weight::from_parts(40_543_916, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 4_675 + .saturating_add(Weight::from_parts(155_883, 0).saturating_mul(a.into())) + // Standard Error: 4_830 + .saturating_add(Weight::from_parts(30_475, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn remove_announcement(a: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + a * (68 ±0)` + // Estimated: `5698` + // Minimum execution time: 24_096_000 picoseconds. + Weight::from_parts(25_043_982, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 2_018 + .saturating_add(Weight::from_parts(161_362, 0).saturating_mul(a.into())) + // Standard Error: 2_085 + .saturating_add(Weight::from_parts(5_869, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn reject_announcement(a: u32, _p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + a * (68 ±0)` + // Estimated: `5698` + // Minimum execution time: 24_544_000 picoseconds. + Weight::from_parts(25_464_879, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 1_840 + .saturating_add(Weight::from_parts(157_224, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn announce(a: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `486 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `5698` + // Minimum execution time: 33_869_000 picoseconds. + Weight::from_parts(36_671_590, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 4_508 + .saturating_add(Weight::from_parts(170_494, 0).saturating_mul(a.into())) + // Standard Error: 4_657 + .saturating_add(Weight::from_parts(29_881, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn add_proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 25_378_000 picoseconds. + Weight::from_parts(26_232_312, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 1_337 + .saturating_add(Weight::from_parts(62_294, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn remove_proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 25_306_000 picoseconds. + Weight::from_parts(26_702_472, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 1_760 + .saturating_add(Weight::from_parts(52_636, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn remove_proxies(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 22_177_000 picoseconds. + Weight::from_parts(22_859_150, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 2_374 + .saturating_add(Weight::from_parts(51_085, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn create_pure(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `239` + // Estimated: `4706` + // Minimum execution time: 27_010_000 picoseconds. + Weight::from_parts(27_910_735, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 1_618 + .saturating_add(Weight::from_parts(10_864, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 30]`. + fn kill_pure(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `264 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 23_039_000 picoseconds. + Weight::from_parts(23_903_487, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 2_434 + .saturating_add(Weight::from_parts(45_603, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_ranked_collective.rs b/polkadot/runtime/kusama/src/weights/pallet_ranked_collective.rs new file mode 100644 index 0000000000000000000000000000000000000000..21f3f651f2e3b2baf5015f7090b09880dc13b87a --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_ranked_collective.rs @@ -0,0 +1,176 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_ranked_collective` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_ranked_collective +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_ranked_collective`. +pub struct WeightInfo(PhantomData); +impl pallet_ranked_collective::WeightInfo for WeightInfo { + /// Storage: FellowshipCollective Members (r:1 w:1) + /// Proof: FellowshipCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:1) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipCollective IndexToId (r:0 w:1) + /// Proof: FellowshipCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: FellowshipCollective IdToIndex (r:0 w:1) + /// Proof: FellowshipCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + fn add_member() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3507` + // Minimum execution time: 16_103_000 picoseconds. + Weight::from_parts(16_743_000, 0) + .saturating_add(Weight::from_parts(0, 3507)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: FellowshipCollective Members (r:1 w:1) + /// Proof: FellowshipCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:11 w:11) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipCollective IdToIndex (r:11 w:11) + /// Proof: FellowshipCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: FellowshipCollective IndexToId (r:11 w:11) + /// Proof: FellowshipCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 10]`. + fn remove_member(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `550 + r * (281 ±0)` + // Estimated: `3519 + r * (2529 ±0)` + // Minimum execution time: 27_225_000 picoseconds. + Weight::from_parts(31_460_102, 0) + .saturating_add(Weight::from_parts(0, 3519)) + // Standard Error: 23_877 + .saturating_add(Weight::from_parts(12_798_296, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 2529).saturating_mul(r.into())) + } + /// Storage: FellowshipCollective Members (r:1 w:1) + /// Proof: FellowshipCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:1) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipCollective IndexToId (r:0 w:1) + /// Proof: FellowshipCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: FellowshipCollective IdToIndex (r:0 w:1) + /// Proof: FellowshipCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 10]`. + fn promote_member(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `248 + r * (17 ±0)` + // Estimated: `3507` + // Minimum execution time: 18_964_000 picoseconds. + Weight::from_parts(19_901_082, 0) + .saturating_add(Weight::from_parts(0, 3507)) + // Standard Error: 4_560 + .saturating_add(Weight::from_parts(326_770, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: FellowshipCollective Members (r:1 w:1) + /// Proof: FellowshipCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:1) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipCollective IdToIndex (r:1 w:1) + /// Proof: FellowshipCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: FellowshipCollective IndexToId (r:1 w:1) + /// Proof: FellowshipCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 10]`. + fn demote_member(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `566 + r * (72 ±0)` + // Estimated: `3519` + // Minimum execution time: 27_310_000 picoseconds. + Weight::from_parts(30_386_652, 0) + .saturating_add(Weight::from_parts(0, 3519)) + // Standard Error: 33_721 + .saturating_add(Weight::from_parts(667_118, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: FellowshipCollective Members (r:1 w:0) + /// Proof: FellowshipCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipCollective Voting (r:1 w:1) + /// Proof: FellowshipCollective Voting (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn vote() -> Weight { + // Proof Size summary in bytes: + // Measured: `638` + // Estimated: `83866` + // Minimum execution time: 50_373_000 picoseconds. + Weight::from_parts(51_359_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:0) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipCollective VotingCleanup (r:1 w:0) + /// Proof: FellowshipCollective VotingCleanup (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: FellowshipCollective Voting (r:100 w:100) + /// Proof: FellowshipCollective Voting (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// The range of component `n` is `[0, 100]`. + fn cleanup_poll(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `434 + n * (50 ±0)` + // Estimated: `4365 + n * (2540 ±0)` + // Minimum execution time: 14_237_000 picoseconds. + Weight::from_parts(16_304_970, 0) + .saturating_add(Weight::from_parts(0, 4365)) + // Standard Error: 2_460 + .saturating_add(Weight::from_parts(1_185_342, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2540).saturating_mul(n.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_recovery.rs b/polkadot/runtime/kusama/src/weights/pallet_recovery.rs new file mode 100644 index 0000000000000000000000000000000000000000..6f2fdfa334f6eadb351a91174316741f79ac5c7a --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_recovery.rs @@ -0,0 +1,186 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_recovery` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_recovery +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_recovery`. +pub struct WeightInfo(PhantomData); +impl pallet_recovery::WeightInfo for WeightInfo { + /// Storage: Recovery Proxy (r:1 w:0) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + fn as_recovered() -> Weight { + // Proof Size summary in bytes: + // Measured: `182` + // Estimated: `3545` + // Minimum execution time: 9_088_000 picoseconds. + Weight::from_parts(9_345_000, 0) + .saturating_add(Weight::from_parts(0, 3545)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: Recovery Proxy (r:0 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + fn set_recovered() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_810_000 picoseconds. + Weight::from_parts(9_033_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery Recoverable (r:1 w:1) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 9]`. + fn create_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3816` + // Minimum execution time: 25_748_000 picoseconds. + Weight::from_parts(26_517_291, 0) + .saturating_add(Weight::from_parts(0, 3816)) + // Standard Error: 4_572 + .saturating_add(Weight::from_parts(103_064, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + fn initiate_recovery() -> Weight { + // Proof Size summary in bytes: + // Measured: `173` + // Estimated: `3854` + // Minimum execution time: 28_593_000 picoseconds. + Weight::from_parts(29_386_000, 0) + .saturating_add(Weight::from_parts(0, 3854)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 9]`. + fn vouch_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `261 + n * (64 ±0)` + // Estimated: `3854` + // Minimum execution time: 18_621_000 picoseconds. + Weight::from_parts(19_241_387, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 5_538 + .saturating_add(Weight::from_parts(263_385, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:0) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: Recovery Proxy (r:1 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 9]`. + fn claim_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `293 + n * (64 ±0)` + // Estimated: `3854` + // Minimum execution time: 22_870_000 picoseconds. + Weight::from_parts(23_779_105, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 4_668 + .saturating_add(Weight::from_parts(149_312, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 9]`. + fn close_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `414 + n * (32 ±0)` + // Estimated: `3854` + // Minimum execution time: 34_111_000 picoseconds. + Weight::from_parts(35_420_404, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 5_909 + .saturating_add(Weight::from_parts(46_955, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Recovery ActiveRecoveries (r:1 w:0) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: Recovery Recoverable (r:1 w:1) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 9]`. + fn remove_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `170 + n * (32 ±0)` + // Estimated: `3854` + // Minimum execution time: 30_441_000 picoseconds. + Weight::from_parts(31_553_945, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 7_463 + .saturating_add(Weight::from_parts(119_815, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery Proxy (r:1 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + fn cancel_recovered() -> Weight { + // Proof Size summary in bytes: + // Measured: `182` + // Estimated: `3545` + // Minimum execution time: 10_937_000 picoseconds. + Weight::from_parts(11_333_000, 0) + .saturating_add(Weight::from_parts(0, 3545)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_referenda_fellowship_referenda.rs b/polkadot/runtime/kusama/src/weights/pallet_referenda_fellowship_referenda.rs new file mode 100644 index 0000000000000000000000000000000000000000..a4ac066791168a67b17289a1c87b1ede681f92ad --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_referenda_fellowship_referenda.rs @@ -0,0 +1,525 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_referenda` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_referenda +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_referenda`. +pub struct WeightInfo(PhantomData); +impl pallet_referenda::WeightInfo for WeightInfo { + /// Storage: FellowshipCollective Members (r:1 w:0) + /// Proof: FellowshipCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda ReferendumCount (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda ReferendumInfoFor (r:0 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + fn submit() -> Weight { + // Proof Size summary in bytes: + // Measured: `327` + // Estimated: `42428` + // Minimum execution time: 28_969_000 picoseconds. + Weight::from_parts(30_902_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_preparing() -> Weight { + // Proof Size summary in bytes: + // Measured: `404` + // Estimated: `83866` + // Minimum execution time: 53_500_000 picoseconds. + Weight::from_parts(54_447_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda DecidingCount (r:1 w:0) + /// Proof: FellowshipReferenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda TrackQueue (r:1 w:1) + /// Proof: FellowshipReferenda TrackQueue (max_values: None, max_size: Some(812), added: 3287, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `2042` + // Estimated: `42428` + // Minimum execution time: 114_321_000 picoseconds. + Weight::from_parts(122_607_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda DecidingCount (r:1 w:0) + /// Proof: FellowshipReferenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda TrackQueue (r:1 w:1) + /// Proof: FellowshipReferenda TrackQueue (max_values: None, max_size: Some(812), added: 3287, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_not_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `2083` + // Estimated: `42428` + // Minimum execution time: 113_476_000 picoseconds. + Weight::from_parts(120_078_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda DecidingCount (r:1 w:1) + /// Proof: FellowshipReferenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_passing() -> Weight { + // Proof Size summary in bytes: + // Measured: `774` + // Estimated: `83866` + // Minimum execution time: 194_798_000 picoseconds. + Weight::from_parts(208_378_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda DecidingCount (r:1 w:1) + /// Proof: FellowshipReferenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_failing() -> Weight { + // Proof Size summary in bytes: + // Measured: `639` + // Estimated: `83866` + // Minimum execution time: 69_502_000 picoseconds. + Weight::from_parts(71_500_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + fn refund_decision_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `317` + // Estimated: `4365` + // Minimum execution time: 30_561_000 picoseconds. + Weight::from_parts(31_427_000, 0) + .saturating_add(Weight::from_parts(0, 4365)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + fn refund_submission_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `167` + // Estimated: `4365` + // Minimum execution time: 14_535_000 picoseconds. + Weight::from_parts(14_999_000, 0) + .saturating_add(Weight::from_parts(0, 4365)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn cancel() -> Weight { + // Proof Size summary in bytes: + // Measured: `349` + // Estimated: `83866` + // Minimum execution time: 38_532_000 picoseconds. + Weight::from_parts(39_361_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda MetadataOf (r:1 w:0) + /// Proof: FellowshipReferenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + fn kill() -> Weight { + // Proof Size summary in bytes: + // Measured: `450` + // Estimated: `83866` + // Minimum execution time: 78_956_000 picoseconds. + Weight::from_parts(80_594_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: FellowshipReferenda TrackQueue (r:1 w:0) + /// Proof: FellowshipReferenda TrackQueue (max_values: None, max_size: Some(812), added: 3287, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda DecidingCount (r:1 w:1) + /// Proof: FellowshipReferenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + fn one_fewer_deciding_queue_empty() -> Weight { + // Proof Size summary in bytes: + // Measured: `140` + // Estimated: `4277` + // Minimum execution time: 9_450_000 picoseconds. + Weight::from_parts(9_881_000, 0) + .saturating_add(Weight::from_parts(0, 4277)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: FellowshipReferenda TrackQueue (r:1 w:1) + /// Proof: FellowshipReferenda TrackQueue (max_values: None, max_size: Some(812), added: 3287, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn one_fewer_deciding_failing() -> Weight { + // Proof Size summary in bytes: + // Measured: `2376` + // Estimated: `42428` + // Minimum execution time: 98_126_000 picoseconds. + Weight::from_parts(102_511_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: FellowshipReferenda TrackQueue (r:1 w:1) + /// Proof: FellowshipReferenda TrackQueue (max_values: None, max_size: Some(812), added: 3287, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn one_fewer_deciding_passing() -> Weight { + // Proof Size summary in bytes: + // Measured: `2362` + // Estimated: `42428` + // Minimum execution time: 99_398_000 picoseconds. + Weight::from_parts(104_045_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:0) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda TrackQueue (r:1 w:1) + /// Proof: FellowshipReferenda TrackQueue (max_values: None, max_size: Some(812), added: 3287, mode: MaxEncodedLen) + fn nudge_referendum_requeued_insertion() -> Weight { + // Proof Size summary in bytes: + // Measured: `1807` + // Estimated: `4365` + // Minimum execution time: 43_734_000 picoseconds. + Weight::from_parts(46_962_000, 0) + .saturating_add(Weight::from_parts(0, 4365)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:0) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda TrackQueue (r:1 w:1) + /// Proof: FellowshipReferenda TrackQueue (max_values: None, max_size: Some(812), added: 3287, mode: MaxEncodedLen) + fn nudge_referendum_requeued_slide() -> Weight { + // Proof Size summary in bytes: + // Measured: `1774` + // Estimated: `4365` + // Minimum execution time: 42_863_000 picoseconds. + Weight::from_parts(46_241_000, 0) + .saturating_add(Weight::from_parts(0, 4365)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda DecidingCount (r:1 w:0) + /// Proof: FellowshipReferenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda TrackQueue (r:1 w:1) + /// Proof: FellowshipReferenda TrackQueue (max_values: None, max_size: Some(812), added: 3287, mode: MaxEncodedLen) + fn nudge_referendum_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `1790` + // Estimated: `4365` + // Minimum execution time: 57_511_000 picoseconds. + Weight::from_parts(64_027_000, 0) + .saturating_add(Weight::from_parts(0, 4365)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda DecidingCount (r:1 w:0) + /// Proof: FellowshipReferenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda TrackQueue (r:1 w:1) + /// Proof: FellowshipReferenda TrackQueue (max_values: None, max_size: Some(812), added: 3287, mode: MaxEncodedLen) + fn nudge_referendum_not_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `1831` + // Estimated: `4365` + // Minimum execution time: 56_726_000 picoseconds. + Weight::from_parts(61_962_000, 0) + .saturating_add(Weight::from_parts(0, 4365)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_no_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `301` + // Estimated: `42428` + // Minimum execution time: 24_870_000 picoseconds. + Weight::from_parts(25_837_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_preparing() -> Weight { + // Proof Size summary in bytes: + // Measured: `349` + // Estimated: `42428` + // Minimum execution time: 25_297_000 picoseconds. + Weight::from_parts(26_086_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + fn nudge_referendum_timed_out() -> Weight { + // Proof Size summary in bytes: + // Measured: `208` + // Estimated: `4365` + // Minimum execution time: 16_776_000 picoseconds. + Weight::from_parts(17_396_000, 0) + .saturating_add(Weight::from_parts(0, 4365)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda DecidingCount (r:1 w:1) + /// Proof: FellowshipReferenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_begin_deciding_failing() -> Weight { + // Proof Size summary in bytes: + // Measured: `584` + // Estimated: `42428` + // Minimum execution time: 37_780_000 picoseconds. + Weight::from_parts(38_626_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda DecidingCount (r:1 w:1) + /// Proof: FellowshipReferenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_begin_deciding_passing() -> Weight { + // Proof Size summary in bytes: + // Measured: `719` + // Estimated: `42428` + // Minimum execution time: 85_265_000 picoseconds. + Weight::from_parts(89_986_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_begin_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `770` + // Estimated: `42428` + // Minimum execution time: 143_283_000 picoseconds. + Weight::from_parts(158_540_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_end_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `755` + // Estimated: `42428` + // Minimum execution time: 143_736_000 picoseconds. + Weight::from_parts(162_755_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_continue_not_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `770` + // Estimated: `42428` + // Minimum execution time: 139_021_000 picoseconds. + Weight::from_parts(157_398_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_continue_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `776` + // Estimated: `42428` + // Minimum execution time: 78_530_000 picoseconds. + Weight::from_parts(83_556_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + fn nudge_referendum_approved() -> Weight { + // Proof Size summary in bytes: + // Measured: `776` + // Estimated: `83866` + // Minimum execution time: 174_165_000 picoseconds. + Weight::from_parts(188_496_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:1) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipCollective MemberCount (r:1 w:0) + /// Proof: FellowshipCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_rejected() -> Weight { + // Proof Size summary in bytes: + // Measured: `772` + // Estimated: `42428` + // Minimum execution time: 142_964_000 picoseconds. + Weight::from_parts(157_257_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:0) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda MetadataOf (r:0 w:1) + /// Proof: FellowshipReferenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + fn set_some_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `352` + // Estimated: `4365` + // Minimum execution time: 20_126_000 picoseconds. + Weight::from_parts(20_635_000, 0) + .saturating_add(Weight::from_parts(0, 4365)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: FellowshipReferenda ReferendumInfoFor (r:1 w:0) + /// Proof: FellowshipReferenda ReferendumInfoFor (max_values: None, max_size: Some(900), added: 3375, mode: MaxEncodedLen) + /// Storage: FellowshipReferenda MetadataOf (r:1 w:1) + /// Proof: FellowshipReferenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + fn clear_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `285` + // Estimated: `4365` + // Minimum execution time: 17_716_000 picoseconds. + Weight::from_parts(18_324_000, 0) + .saturating_add(Weight::from_parts(0, 4365)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_referenda_referenda.rs b/polkadot/runtime/kusama/src/weights/pallet_referenda_referenda.rs new file mode 100644 index 0000000000000000000000000000000000000000..accaa0ef10d970839ff1d2470154f8952ad70ce9 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_referenda_referenda.rs @@ -0,0 +1,523 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_referenda` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_referenda +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_referenda`. +pub struct WeightInfo(PhantomData); +impl pallet_referenda::WeightInfo for WeightInfo { + /// Storage: Referenda ReferendumCount (r:1 w:1) + /// Proof: Referenda ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:0 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + fn submit() -> Weight { + // Proof Size summary in bytes: + // Measured: `186` + // Estimated: `42428` + // Minimum execution time: 39_146_000 picoseconds. + Weight::from_parts(40_383_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_preparing() -> Weight { + // Proof Size summary in bytes: + // Measured: `439` + // Estimated: `83866` + // Minimum execution time: 51_385_000 picoseconds. + Weight::from_parts(52_701_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `3196` + // Estimated: `42428` + // Minimum execution time: 70_018_000 picoseconds. + Weight::from_parts(75_868_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_not_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `3216` + // Estimated: `42428` + // Minimum execution time: 69_311_000 picoseconds. + Weight::from_parts(72_425_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_passing() -> Weight { + // Proof Size summary in bytes: + // Measured: `439` + // Estimated: `83866` + // Minimum execution time: 64_385_000 picoseconds. + Weight::from_parts(66_178_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_failing() -> Weight { + // Proof Size summary in bytes: + // Measured: `439` + // Estimated: `83866` + // Minimum execution time: 62_200_000 picoseconds. + Weight::from_parts(63_782_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + fn refund_decision_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `279` + // Estimated: `4401` + // Minimum execution time: 29_677_000 picoseconds. + Weight::from_parts(30_603_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + fn refund_submission_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `269` + // Estimated: `4401` + // Minimum execution time: 29_897_000 picoseconds. + Weight::from_parts(30_618_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn cancel() -> Weight { + // Proof Size summary in bytes: + // Measured: `347` + // Estimated: `83866` + // Minimum execution time: 37_697_000 picoseconds. + Weight::from_parts(38_953_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:1 w:0) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + fn kill() -> Weight { + // Proof Size summary in bytes: + // Measured: `588` + // Estimated: `83866` + // Minimum execution time: 106_001_000 picoseconds. + Weight::from_parts(107_102_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda TrackQueue (r:1 w:0) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + fn one_fewer_deciding_queue_empty() -> Weight { + // Proof Size summary in bytes: + // Measured: `102` + // Estimated: `5477` + // Minimum execution time: 8_987_000 picoseconds. + Weight::from_parts(9_431_000, 0) + .saturating_add(Weight::from_parts(0, 5477)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn one_fewer_deciding_failing() -> Weight { + // Proof Size summary in bytes: + // Measured: `3116` + // Estimated: `42428` + // Minimum execution time: 55_344_000 picoseconds. + Weight::from_parts(58_026_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn one_fewer_deciding_passing() -> Weight { + // Proof Size summary in bytes: + // Measured: `3116` + // Estimated: `42428` + // Minimum execution time: 57_003_000 picoseconds. + Weight::from_parts(60_347_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + fn nudge_referendum_requeued_insertion() -> Weight { + // Proof Size summary in bytes: + // Measured: `2939` + // Estimated: `5477` + // Minimum execution time: 23_001_000 picoseconds. + Weight::from_parts(24_812_000, 0) + .saturating_add(Weight::from_parts(0, 5477)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + fn nudge_referendum_requeued_slide() -> Weight { + // Proof Size summary in bytes: + // Measured: `2939` + // Estimated: `5477` + // Minimum execution time: 23_299_000 picoseconds. + Weight::from_parts(24_465_000, 0) + .saturating_add(Weight::from_parts(0, 5477)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + fn nudge_referendum_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `2943` + // Estimated: `5477` + // Minimum execution time: 28_223_000 picoseconds. + Weight::from_parts(29_664_000, 0) + .saturating_add(Weight::from_parts(0, 5477)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + fn nudge_referendum_not_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `2963` + // Estimated: `5477` + // Minimum execution time: 27_474_000 picoseconds. + Weight::from_parts(29_072_000, 0) + .saturating_add(Weight::from_parts(0, 5477)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_no_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `299` + // Estimated: `42428` + // Minimum execution time: 24_405_000 picoseconds. + Weight::from_parts(25_184_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_preparing() -> Weight { + // Proof Size summary in bytes: + // Measured: `347` + // Estimated: `42428` + // Minimum execution time: 24_572_000 picoseconds. + Weight::from_parts(25_287_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + fn nudge_referendum_timed_out() -> Weight { + // Proof Size summary in bytes: + // Measured: `206` + // Estimated: `4401` + // Minimum execution time: 16_042_000 picoseconds. + Weight::from_parts(16_610_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_begin_deciding_failing() -> Weight { + // Proof Size summary in bytes: + // Measured: `347` + // Estimated: `42428` + // Minimum execution time: 33_639_000 picoseconds. + Weight::from_parts(34_749_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_begin_deciding_passing() -> Weight { + // Proof Size summary in bytes: + // Measured: `347` + // Estimated: `42428` + // Minimum execution time: 36_467_000 picoseconds. + Weight::from_parts(37_693_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_begin_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `400` + // Estimated: `42428` + // Minimum execution time: 29_857_000 picoseconds. + Weight::from_parts(30_840_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_end_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `383` + // Estimated: `42428` + // Minimum execution time: 31_028_000 picoseconds. + Weight::from_parts(32_154_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_continue_not_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `400` + // Estimated: `42428` + // Minimum execution time: 28_594_000 picoseconds. + Weight::from_parts(29_092_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_continue_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `404` + // Estimated: `42428` + // Minimum execution time: 27_246_000 picoseconds. + Weight::from_parts(28_003_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + fn nudge_referendum_approved() -> Weight { + // Proof Size summary in bytes: + // Measured: `404` + // Estimated: `83866` + // Minimum execution time: 43_426_000 picoseconds. + Weight::from_parts(44_917_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_rejected() -> Weight { + // Proof Size summary in bytes: + // Measured: `400` + // Estimated: `42428` + // Minimum execution time: 30_285_000 picoseconds. + Weight::from_parts(31_575_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:0 w:1) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + fn set_some_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `350` + // Estimated: `4401` + // Minimum execution time: 19_254_000 picoseconds. + Weight::from_parts(19_855_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:1 w:1) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + fn clear_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `283` + // Estimated: `4401` + // Minimum execution time: 16_957_000 picoseconds. + Weight::from_parts(17_556_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_scheduler.rs b/polkadot/runtime/kusama/src/weights/pallet_scheduler.rs new file mode 100644 index 0000000000000000000000000000000000000000..3e8e8810b2e5fae3c1bae957a37d27502cf60080 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_scheduler.rs @@ -0,0 +1,207 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_scheduler` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_scheduler +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_scheduler`. +pub struct WeightInfo(PhantomData); +impl pallet_scheduler::WeightInfo for WeightInfo { + /// Storage: Scheduler IncompleteSince (r:1 w:1) + /// Proof: Scheduler IncompleteSince (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn service_agendas_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `69` + // Estimated: `1489` + // Minimum execution time: 4_091_000 picoseconds. + Weight::from_parts(4_209_000, 0) + .saturating_add(Weight::from_parts(0, 1489)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 50]`. + fn service_agenda_base(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 3_545_000 picoseconds. + Weight::from_parts(6_437_280, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 1_955 + .saturating_add(Weight::from_parts(892_412, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_task_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_679_000 picoseconds. + Weight::from_parts(5_799_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Preimage PreimageFor (r:1 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: Measured) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// The range of component `s` is `[128, 4194304]`. + fn service_task_fetched(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `179 + s * (1 ±0)` + // Estimated: `3644 + s * (1 ±0)` + // Minimum execution time: 19_438_000 picoseconds. + Weight::from_parts(19_663_000, 0) + .saturating_add(Weight::from_parts(0, 3644)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_513, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(s.into())) + } + /// Storage: Scheduler Lookup (r:0 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + fn service_task_named() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_131_000 picoseconds. + Weight::from_parts(7_388_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_task_periodic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_761_000 picoseconds. + Weight::from_parts(5_896_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn execute_dispatch_signed() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_530_000 picoseconds. + Weight::from_parts(2_632_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn execute_dispatch_unsigned() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_548_000 picoseconds. + Weight::from_parts(2_632_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 49]`. + fn schedule(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 12_757_000 picoseconds. + Weight::from_parts(15_453_687, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 2_121 + .saturating_add(Weight::from_parts(920_922, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: Scheduler Lookup (r:0 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 50]`. + fn cancel(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 17_412_000 picoseconds. + Weight::from_parts(16_293_532, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 2_448 + .saturating_add(Weight::from_parts(1_635_003, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 49]`. + fn schedule_named(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `293 + s * (185 ±0)` + // Estimated: `42428` + // Minimum execution time: 16_149_000 picoseconds. + Weight::from_parts(19_661_866, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 2_641 + .saturating_add(Weight::from_parts(952_864, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 50]`. + fn cancel_named(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `319 + s * (185 ±0)` + // Estimated: `42428` + // Minimum execution time: 18_858_000 picoseconds. + Weight::from_parts(18_380_802, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 3_271 + .saturating_add(Weight::from_parts(1_687_802, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_session.rs b/polkadot/runtime/kusama/src/weights/pallet_session.rs new file mode 100644 index 0000000000000000000000000000000000000000..3f5469477e5816412a52de10066500df50448fbe --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_session.rs @@ -0,0 +1,85 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_session` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_session +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_session`. +pub struct WeightInfo(PhantomData); +impl pallet_session::WeightInfo for WeightInfo { + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Session NextKeys (r:1 w:1) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session KeyOwner (r:6 w:6) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) + fn set_keys() -> Weight { + // Proof Size summary in bytes: + // Measured: `2050` + // Estimated: `17890` + // Minimum execution time: 60_102_000 picoseconds. + Weight::from_parts(63_699_000, 0) + .saturating_add(Weight::from_parts(0, 17890)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Session NextKeys (r:1 w:1) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session KeyOwner (r:0 w:6) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) + fn purge_keys() -> Weight { + // Proof Size summary in bytes: + // Measured: `1914` + // Estimated: `5379` + // Minimum execution time: 42_242_000 picoseconds. + Weight::from_parts(43_575_000, 0) + .saturating_add(Weight::from_parts(0, 5379)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(7)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_society.rs b/polkadot/runtime/kusama/src/weights/pallet_society.rs new file mode 100644 index 0000000000000000000000000000000000000000..2b564349b413cc4499f98e819ff6133e2bf39934 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_society.rs @@ -0,0 +1,437 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_society` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_society +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_society`. +pub struct WeightInfo(PhantomData); +impl pallet_society::WeightInfo for WeightInfo { + /// Storage: Society Bids (r:1 w:1) + /// Proof Skipped: Society Bids (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Candidates (r:1 w:0) + /// Proof Skipped: Society Candidates (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Members (r:1 w:0) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + /// Storage: Society SuspendedMembers (r:1 w:0) + /// Proof Skipped: Society SuspendedMembers (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Parameters (r:1 w:0) + /// Proof Skipped: Society Parameters (max_values: Some(1), max_size: None, mode: Measured) + fn bid() -> Weight { + // Proof Size summary in bytes: + // Measured: `416` + // Estimated: `3881` + // Minimum execution time: 35_388_000 picoseconds. + Weight::from_parts(36_165_000, 0) + .saturating_add(Weight::from_parts(0, 3881)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Society Bids (r:1 w:1) + /// Proof Skipped: Society Bids (max_values: Some(1), max_size: None, mode: Measured) + fn unbid() -> Weight { + // Proof Size summary in bytes: + // Measured: `433` + // Estimated: `1918` + // Minimum execution time: 28_387_000 picoseconds. + Weight::from_parts(29_224_000, 0) + .saturating_add(Weight::from_parts(0, 1918)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Society Bids (r:1 w:1) + /// Proof Skipped: Society Bids (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Candidates (r:1 w:0) + /// Proof Skipped: Society Candidates (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Members (r:2 w:1) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + /// Storage: Society SuspendedMembers (r:1 w:0) + /// Proof Skipped: Society SuspendedMembers (max_values: None, max_size: None, mode: Measured) + fn vouch() -> Weight { + // Proof Size summary in bytes: + // Measured: `453` + // Estimated: `6393` + // Minimum execution time: 25_337_000 picoseconds. + Weight::from_parts(26_143_000, 0) + .saturating_add(Weight::from_parts(0, 6393)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Society Bids (r:1 w:1) + /// Proof Skipped: Society Bids (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Members (r:1 w:1) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + fn unvouch() -> Weight { + // Proof Size summary in bytes: + // Measured: `507` + // Estimated: `3972` + // Minimum execution time: 17_975_000 picoseconds. + Weight::from_parts(18_695_000, 0) + .saturating_add(Weight::from_parts(0, 3972)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Society Candidates (r:1 w:1) + /// Proof Skipped: Society Candidates (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Members (r:1 w:0) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Votes (r:1 w:1) + /// Proof Skipped: Society Votes (max_values: None, max_size: None, mode: Measured) + fn vote() -> Weight { + // Proof Size summary in bytes: + // Measured: `541` + // Estimated: `4006` + // Minimum execution time: 23_173_000 picoseconds. + Weight::from_parts(23_764_000, 0) + .saturating_add(Weight::from_parts(0, 4006)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Society Defending (r:1 w:1) + /// Proof Skipped: Society Defending (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Members (r:1 w:0) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + /// Storage: Society ChallengeRoundCount (r:1 w:0) + /// Proof Skipped: Society ChallengeRoundCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society DefenderVotes (r:1 w:1) + /// Proof Skipped: Society DefenderVotes (max_values: None, max_size: None, mode: Measured) + fn defender_vote() -> Weight { + // Proof Size summary in bytes: + // Measured: `533` + // Estimated: `3998` + // Minimum execution time: 21_744_000 picoseconds. + Weight::from_parts(22_406_000, 0) + .saturating_add(Weight::from_parts(0, 3998)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Society Members (r:1 w:0) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Payouts (r:1 w:1) + /// Proof Skipped: Society Payouts (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn payout() -> Weight { + // Proof Size summary in bytes: + // Measured: `622` + // Estimated: `4087` + // Minimum execution time: 50_058_000 picoseconds. + Weight::from_parts(51_077_000, 0) + .saturating_add(Weight::from_parts(0, 4087)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Society Members (r:1 w:1) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Payouts (r:1 w:1) + /// Proof Skipped: Society Payouts (max_values: None, max_size: None, mode: Measured) + fn waive_repay() -> Weight { + // Proof Size summary in bytes: + // Measured: `519` + // Estimated: `3984` + // Minimum execution time: 21_305_000 picoseconds. + Weight::from_parts(22_020_000, 0) + .saturating_add(Weight::from_parts(0, 3984)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Society Head (r:1 w:1) + /// Proof Skipped: Society Head (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society MemberCount (r:1 w:1) + /// Proof Skipped: Society MemberCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society MemberByIndex (r:0 w:1) + /// Proof Skipped: Society MemberByIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Founder (r:0 w:1) + /// Proof Skipped: Society Founder (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Rules (r:0 w:1) + /// Proof Skipped: Society Rules (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Members (r:0 w:1) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Parameters (r:0 w:1) + /// Proof Skipped: Society Parameters (max_values: Some(1), max_size: None, mode: Measured) + fn found_society() -> Weight { + // Proof Size summary in bytes: + // Measured: `114` + // Estimated: `1599` + // Minimum execution time: 19_952_000 picoseconds. + Weight::from_parts(20_365_000, 0) + .saturating_add(Weight::from_parts(0, 1599)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Society Founder (r:1 w:1) + /// Proof Skipped: Society Founder (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society MemberCount (r:1 w:1) + /// Proof Skipped: Society MemberCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Members (r:5 w:5) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + /// Storage: Society MemberByIndex (r:5 w:5) + /// Proof Skipped: Society MemberByIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Votes (r:4 w:4) + /// Proof Skipped: Society Votes (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Candidates (r:4 w:4) + /// Proof Skipped: Society Candidates (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Head (r:0 w:1) + /// Proof Skipped: Society Head (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Defending (r:0 w:1) + /// Proof Skipped: Society Defending (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society ChallengeRoundCount (r:0 w:1) + /// Proof Skipped: Society ChallengeRoundCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Skeptic (r:0 w:1) + /// Proof Skipped: Society Skeptic (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Pot (r:0 w:1) + /// Proof Skipped: Society Pot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Rules (r:0 w:1) + /// Proof Skipped: Society Rules (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society RoundCount (r:0 w:1) + /// Proof Skipped: Society RoundCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Bids (r:0 w:1) + /// Proof Skipped: Society Bids (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Parameters (r:0 w:1) + /// Proof Skipped: Society Parameters (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society NextHead (r:0 w:1) + /// Proof Skipped: Society NextHead (max_values: Some(1), max_size: None, mode: Measured) + fn dissolve() -> Weight { + // Proof Size summary in bytes: + // Measured: `1626` + // Estimated: `14991` + // Minimum execution time: 64_547_000 picoseconds. + Weight::from_parts(66_190_000, 0) + .saturating_add(Weight::from_parts(0, 14991)) + .saturating_add(T::DbWeight::get().reads(20)) + .saturating_add(T::DbWeight::get().writes(30)) + } + /// Storage: Society Founder (r:1 w:0) + /// Proof Skipped: Society Founder (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society SuspendedMembers (r:1 w:1) + /// Proof Skipped: Society SuspendedMembers (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Payouts (r:1 w:0) + /// Proof Skipped: Society Payouts (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Pot (r:1 w:1) + /// Proof Skipped: Society Pot (max_values: Some(1), max_size: None, mode: Measured) + fn judge_suspended_member() -> Weight { + // Proof Size summary in bytes: + // Measured: `456` + // Estimated: `3921` + // Minimum execution time: 22_276_000 picoseconds. + Weight::from_parts(22_817_000, 0) + .saturating_add(Weight::from_parts(0, 3921)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Society Founder (r:1 w:0) + /// Proof Skipped: Society Founder (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society MemberCount (r:1 w:0) + /// Proof Skipped: Society MemberCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Parameters (r:0 w:1) + /// Proof Skipped: Society Parameters (max_values: Some(1), max_size: None, mode: Measured) + fn set_parameters() -> Weight { + // Proof Size summary in bytes: + // Measured: `359` + // Estimated: `1844` + // Minimum execution time: 14_857_000 picoseconds. + Weight::from_parts(15_268_000, 0) + .saturating_add(Weight::from_parts(0, 1844)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Society Candidates (r:1 w:1) + /// Proof Skipped: Society Candidates (max_values: None, max_size: None, mode: Measured) + /// Storage: Society RoundCount (r:1 w:0) + /// Proof Skipped: Society RoundCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Skeptic (r:1 w:0) + /// Proof Skipped: Society Skeptic (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Votes (r:1 w:0) + /// Proof Skipped: Society Votes (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Members (r:1 w:1) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Parameters (r:1 w:0) + /// Proof Skipped: Society Parameters (max_values: Some(1), max_size: None, mode: Measured) + fn punish_skeptic() -> Weight { + // Proof Size summary in bytes: + // Measured: `608` + // Estimated: `4073` + // Minimum execution time: 24_995_000 picoseconds. + Weight::from_parts(25_968_000, 0) + .saturating_add(Weight::from_parts(0, 4073)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Society Candidates (r:1 w:1) + /// Proof Skipped: Society Candidates (max_values: None, max_size: None, mode: Measured) + /// Storage: Society RoundCount (r:1 w:0) + /// Proof Skipped: Society RoundCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Parameters (r:1 w:0) + /// Proof Skipped: Society Parameters (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society MemberCount (r:1 w:1) + /// Proof Skipped: Society MemberCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society NextHead (r:1 w:1) + /// Proof Skipped: Society NextHead (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Society MemberByIndex (r:0 w:1) + /// Proof Skipped: Society MemberByIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Members (r:0 w:1) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + fn claim_membership() -> Weight { + // Proof Size summary in bytes: + // Measured: `604` + // Estimated: `4069` + // Minimum execution time: 41_570_000 picoseconds. + Weight::from_parts(42_576_000, 0) + .saturating_add(Weight::from_parts(0, 4069)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Society Founder (r:1 w:0) + /// Proof Skipped: Society Founder (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Candidates (r:1 w:1) + /// Proof Skipped: Society Candidates (max_values: None, max_size: None, mode: Measured) + /// Storage: Society RoundCount (r:1 w:0) + /// Proof Skipped: Society RoundCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Parameters (r:1 w:0) + /// Proof Skipped: Society Parameters (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society MemberCount (r:1 w:1) + /// Proof Skipped: Society MemberCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society NextHead (r:1 w:1) + /// Proof Skipped: Society NextHead (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Society MemberByIndex (r:0 w:1) + /// Proof Skipped: Society MemberByIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Members (r:0 w:1) + /// Proof Skipped: Society Members (max_values: None, max_size: None, mode: Measured) + fn bestow_membership() -> Weight { + // Proof Size summary in bytes: + // Measured: `622` + // Estimated: `4087` + // Minimum execution time: 43_450_000 picoseconds. + Weight::from_parts(44_330_000, 0) + .saturating_add(Weight::from_parts(0, 4087)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Society Founder (r:1 w:0) + /// Proof Skipped: Society Founder (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society Candidates (r:1 w:1) + /// Proof Skipped: Society Candidates (max_values: None, max_size: None, mode: Measured) + /// Storage: Society RoundCount (r:1 w:0) + /// Proof Skipped: Society RoundCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn kick_candidate() -> Weight { + // Proof Size summary in bytes: + // Measured: `748` + // Estimated: `6196` + // Minimum execution time: 43_754_000 picoseconds. + Weight::from_parts(44_431_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Society Candidates (r:1 w:1) + /// Proof Skipped: Society Candidates (max_values: None, max_size: None, mode: Measured) + /// Storage: Society RoundCount (r:1 w:0) + /// Proof Skipped: Society RoundCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn resign_candidacy() -> Weight { + // Proof Size summary in bytes: + // Measured: `718` + // Estimated: `6196` + // Minimum execution time: 38_184_000 picoseconds. + Weight::from_parts(38_748_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Society Candidates (r:1 w:1) + /// Proof Skipped: Society Candidates (max_values: None, max_size: None, mode: Measured) + /// Storage: Society RoundCount (r:1 w:0) + /// Proof Skipped: Society RoundCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn drop_candidate() -> Weight { + // Proof Size summary in bytes: + // Measured: `730` + // Estimated: `6196` + // Minimum execution time: 38_442_000 picoseconds. + Weight::from_parts(39_150_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Society Candidates (r:1 w:0) + /// Proof Skipped: Society Candidates (max_values: None, max_size: None, mode: Measured) + /// Storage: Society VoteClearCursor (r:1 w:0) + /// Proof Skipped: Society VoteClearCursor (max_values: None, max_size: None, mode: Measured) + /// Storage: Society Votes (r:2 w:2) + /// Proof Skipped: Society Votes (max_values: None, max_size: None, mode: Measured) + fn cleanup_candidacy() -> Weight { + // Proof Size summary in bytes: + // Measured: `524` + // Estimated: `6464` + // Minimum execution time: 17_373_000 picoseconds. + Weight::from_parts(18_288_000, 0) + .saturating_add(Weight::from_parts(0, 6464)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Society ChallengeRoundCount (r:1 w:0) + /// Proof Skipped: Society ChallengeRoundCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Society DefenderVotes (r:1 w:1) + /// Proof Skipped: Society DefenderVotes (max_values: None, max_size: None, mode: Measured) + fn cleanup_challenge() -> Weight { + // Proof Size summary in bytes: + // Measured: `482` + // Estimated: `3947` + // Minimum execution time: 12_642_000 picoseconds. + Weight::from_parts(13_281_000, 0) + .saturating_add(Weight::from_parts(0, 3947)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_staking.rs b/polkadot/runtime/kusama/src/weights/pallet_staking.rs new file mode 100644 index 0000000000000000000000000000000000000000..a7268a21bb99622be7c89b28e43f0c8d363b6e26 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_staking.rs @@ -0,0 +1,796 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_staking` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_staking +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_staking`. +pub struct WeightInfo(PhantomData); +impl pallet_staking::WeightInfo for WeightInfo { + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + fn bond() -> Weight { + // Proof Size summary in bytes: + // Measured: `980` + // Estimated: `4764` + // Minimum execution time: 51_609_000 picoseconds. + Weight::from_parts(52_360_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn bond_extra() -> Weight { + // Proof Size summary in bytes: + // Measured: `1955` + // Estimated: `8877` + // Minimum execution time: 94_514_000 picoseconds. + Weight::from_parts(96_430_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn unbond() -> Weight { + // Proof Size summary in bytes: + // Measured: `2166` + // Estimated: `8877` + // Minimum execution time: 97_981_000 picoseconds. + Weight::from_parts(102_906_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_update(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `944` + // Estimated: `4764` + // Minimum execution time: 44_962_000 picoseconds. + Weight::from_parts(46_452_900, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_541 + .saturating_add(Weight::from_parts(40_855, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Staking SpanSlash (r:0 w:100) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_kill(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2217 + s * (4 ±0)` + // Estimated: `6248 + s * (4 ±0)` + // Minimum execution time: 94_257_000 picoseconds. + Weight::from_parts(102_162_641, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 4_137 + .saturating_add(Weight::from_parts(1_401_944, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(13)) + .saturating_add(T::DbWeight::get().writes(11)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking MinValidatorBond (r:1 w:0) + /// Proof: Staking MinValidatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking MinCommission (r:1 w:0) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking MaxValidatorsCount (r:1 w:0) + /// Proof: Staking MaxValidatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn validate() -> Weight { + // Proof Size summary in bytes: + // Measured: `1341` + // Estimated: `4556` + // Minimum execution time: 57_139_000 picoseconds. + Weight::from_parts(58_021_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:128 w:128) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// The range of component `k` is `[1, 128]`. + fn kick(k: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1326 + k * (823 ±0)` + // Estimated: `4556 + k * (3289 ±0)` + // Minimum execution time: 36_112_000 picoseconds. + Weight::from_parts(31_474_845, 0) + .saturating_add(Weight::from_parts(0, 4556)) + // Standard Error: 13_249 + .saturating_add(Weight::from_parts(9_813_360, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) + .saturating_add(Weight::from_parts(0, 3289).saturating_mul(k.into())) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:1 w:0) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:25 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 24]`. + fn nominate(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1921 + n * (88 ±0)` + // Estimated: `6248 + n * (2520 ±0)` + // Minimum execution time: 66_845_000 picoseconds. + Weight::from_parts(67_790_022, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 18_238 + .saturating_add(Weight::from_parts(3_739_950, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(Weight::from_parts(0, 2520).saturating_mul(n.into())) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn chill() -> Weight { + // Proof Size summary in bytes: + // Measured: `1671` + // Estimated: `6248` + // Minimum execution time: 59_727_000 picoseconds. + Weight::from_parts(61_591_000, 0) + .saturating_add(Weight::from_parts(0, 6248)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + fn set_payee() -> Weight { + // Proof Size summary in bytes: + // Measured: `735` + // Estimated: `4556` + // Minimum execution time: 13_578_000 picoseconds. + Weight::from_parts(14_266_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:2 w:2) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + fn set_controller() -> Weight { + // Proof Size summary in bytes: + // Measured: `834` + // Estimated: `8122` + // Minimum execution time: 21_128_000 picoseconds. + Weight::from_parts(21_739_000, 0) + .saturating_add(Weight::from_parts(0, 8122)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Staking ValidatorCount (r:0 w:1) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn set_validator_count() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_016_000 picoseconds. + Weight::from_parts(3_195_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking ForceEra (r:0 w:1) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + fn force_no_eras() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_431_000 picoseconds. + Weight::from_parts(9_624_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking ForceEra (r:0 w:1) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + fn force_new_era() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_322_000 picoseconds. + Weight::from_parts(9_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking ForceEra (r:0 w:1) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + fn force_new_era_always() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_209_000 picoseconds. + Weight::from_parts(9_772_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking Invulnerables (r:0 w:1) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[0, 1000]`. + fn set_invulnerables(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_228_000 picoseconds. + Weight::from_parts(3_437_995, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 50 + .saturating_add(Weight::from_parts(12_179, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:0 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Staking SpanSlash (r:0 w:100) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn force_unstake(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1947 + s * (4 ±0)` + // Estimated: `6248 + s * (4 ±0)` + // Minimum execution time: 86_567_000 picoseconds. + Weight::from_parts(93_537_408, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 3_840 + .saturating_add(Weight::from_parts(1_371_525, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(12)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) + } + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `s` is `[1, 1000]`. + fn cancel_deferred_slash(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `66572` + // Estimated: `70037` + // Minimum execution time: 129_433_000 picoseconds. + Weight::from_parts(939_746_867, 0) + .saturating_add(Weight::from_parts(0, 70037)) + // Standard Error: 58_234 + .saturating_add(Weight::from_parts(4_851_875, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasValidatorReward (r:1 w:0) + /// Proof: Staking ErasValidatorReward (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:513 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking ErasStakersClipped (r:1 w:0) + /// Proof Skipped: Staking ErasStakersClipped (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasRewardPoints (r:1 w:0) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasValidatorPrefs (r:1 w:0) + /// Proof: Staking ErasValidatorPrefs (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:513 w:0) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: System Account (r:513 w:513) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `n` is `[0, 512]`. + fn payout_stakers_dead_controller(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `34175 + n * (149 ±0)` + // Estimated: `32387 + n * (2603 ±1)` + // Minimum execution time: 121_648_000 picoseconds. + Weight::from_parts(145_330_037, 0) + .saturating_add(Weight::from_parts(0, 32387)) + // Standard Error: 30_044 + .saturating_add(Weight::from_parts(35_396_961, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(n.into())) + } + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasValidatorReward (r:1 w:0) + /// Proof: Staking ErasValidatorReward (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:513 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:513 w:513) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking ErasStakersClipped (r:1 w:0) + /// Proof Skipped: Staking ErasStakersClipped (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasRewardPoints (r:1 w:0) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasValidatorPrefs (r:1 w:0) + /// Proof: Staking ErasValidatorPrefs (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:513 w:0) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: System Account (r:513 w:513) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:513 w:513) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:513 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `n` is `[0, 512]`. + fn payout_stakers_alive_staked(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `58149 + n * (385 ±0)` + // Estimated: `53036 + n * (3774 ±2)` + // Minimum execution time: 159_726_000 picoseconds. + Weight::from_parts(163_012_000, 0) + .saturating_add(Weight::from_parts(0, 53036)) + // Standard Error: 96_376 + .saturating_add(Weight::from_parts(59_227_426, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(n.into())) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// The range of component `l` is `[1, 32]`. + fn rebond(l: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1956 + l * (5 ±0)` + // Estimated: `8877` + // Minimum execution time: 88_119_000 picoseconds. + Weight::from_parts(91_343_026, 0) + .saturating_add(Weight::from_parts(0, 8877)) + // Standard Error: 5_157 + .saturating_add(Weight::from_parts(38_885, 0).saturating_mul(l.into())) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Staking SpanSlash (r:0 w:100) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 100]`. + fn reap_stash(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2217 + s * (4 ±0)` + // Estimated: `6248 + s * (4 ±0)` + // Minimum execution time: 100_347_000 picoseconds. + Weight::from_parts(103_081_218, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 3_957 + .saturating_add(Weight::from_parts(1_403_417, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(11)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) + } + /// Storage: VoterList CounterForListNodes (r:1 w:0) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:166 w:0) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:110 w:0) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:110 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:11 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:110 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:110 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:0) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinimumValidatorCount (r:1 w:0) + /// Proof: Staking MinimumValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:1) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStakersClipped (r:0 w:10) + /// Proof Skipped: Staking ErasStakersClipped (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasValidatorPrefs (r:0 w:10) + /// Proof: Staking ErasValidatorPrefs (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + /// Storage: Staking ErasStakers (r:0 w:10) + /// Proof Skipped: Staking ErasStakers (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasTotalStake (r:0 w:1) + /// Proof: Staking ErasTotalStake (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:0 w:1) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking MinimumActiveStake (r:0 w:1) + /// Proof: Staking MinimumActiveStake (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// The range of component `v` is `[1, 10]`. + /// The range of component `n` is `[0, 100]`. + fn new_era(v: u32, n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + n * (714 ±0) + v * (3592 ±0)` + // Estimated: `425452 + n * (3566 ±0) + v * (3566 ±0)` + // Minimum execution time: 543_737_000 picoseconds. + Weight::from_parts(547_799_000, 0) + .saturating_add(Weight::from_parts(0, 425452)) + // Standard Error: 2_046_982 + .saturating_add(Weight::from_parts(66_708_000, 0).saturating_mul(v.into())) + // Standard Error: 203_970 + .saturating_add(Weight::from_parts(20_246_221, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(173)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(v.into())) + } + /// Storage: VoterList CounterForListNodes (r:1 w:0) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:166 w:0) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2000 w:0) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:2000 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1000 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:2000 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:2000 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// Storage: Staking MinimumActiveStake (r:0 w:1) + /// Proof: Staking MinimumActiveStake (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// The range of component `v` is `[500, 1000]`. + /// The range of component `n` is `[500, 1000]`. + fn get_npos_voters(v: u32, n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `3151 + n * (1161 ±0) + v * (389 ±0)` + // Estimated: `425452 + n * (3566 ±0) + v * (3566 ±0)` + // Minimum execution time: 38_906_963_000 picoseconds. + Weight::from_parts(39_744_147_000, 0) + .saturating_add(Weight::from_parts(0, 425452)) + // Standard Error: 411_378 + .saturating_add(Weight::from_parts(3_691_522, 0).saturating_mul(v.into())) + // Standard Error: 411_378 + .saturating_add(Weight::from_parts(5_732_105, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(168)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(v.into())) + } + /// Storage: Staking CounterForValidators (r:1 w:0) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1001 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// The range of component `v` is `[500, 1000]`. + fn get_npos_targets(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `917 + v * (50 ±0)` + // Estimated: `3510 + v * (2520 ±0)` + // Minimum execution time: 2_614_613_000 picoseconds. + Weight::from_parts(127_976_836, 0) + .saturating_add(Weight::from_parts(0, 3510)) + // Standard Error: 10_285 + .saturating_add(Weight::from_parts(5_101_327, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) + } + /// Storage: Staking MinCommission (r:0 w:1) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinValidatorBond (r:0 w:1) + /// Proof: Staking MinValidatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking MaxValidatorsCount (r:0 w:1) + /// Proof: Staking MaxValidatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ChillThreshold (r:0 w:1) + /// Proof: Staking ChillThreshold (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:0 w:1) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:0 w:1) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + fn set_staking_configs_all_set() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_533_000 picoseconds. + Weight::from_parts(6_797_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking MinCommission (r:0 w:1) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinValidatorBond (r:0 w:1) + /// Proof: Staking MinValidatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking MaxValidatorsCount (r:0 w:1) + /// Proof: Staking MaxValidatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ChillThreshold (r:0 w:1) + /// Proof: Staking ChillThreshold (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:0 w:1) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:0 w:1) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + fn set_staking_configs_all_remove() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_056_000 picoseconds. + Weight::from_parts(6_255_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(814), added: 3289, mode: MaxEncodedLen) + /// Storage: Staking ChillThreshold (r:1 w:0) + /// Proof: Staking ChillThreshold (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:1 w:0) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn chill_other() -> Weight { + // Proof Size summary in bytes: + // Measured: `1794` + // Estimated: `6248` + // Minimum execution time: 71_915_000 picoseconds. + Weight::from_parts(73_500_000, 0) + .saturating_add(Weight::from_parts(0, 6248)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking MinCommission (r:1 w:0) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + fn force_apply_min_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `627` + // Estimated: `3510` + // Minimum execution time: 12_994_000 picoseconds. + Weight::from_parts(13_452_000, 0) + .saturating_add(Weight::from_parts(0, 3510)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking MinCommission (r:0 w:1) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn set_min_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_191_000 picoseconds. + Weight::from_parts(3_315_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_timestamp.rs b/polkadot/runtime/kusama/src/weights/pallet_timestamp.rs new file mode 100644 index 0000000000000000000000000000000000000000..ab127fd9606466fc5a1ec0a8c6b5435c17115d26 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_timestamp.rs @@ -0,0 +1,75 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_timestamp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_timestamp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_timestamp`. +pub struct WeightInfo(PhantomData); +impl pallet_timestamp::WeightInfo for WeightInfo { + /// Storage: Timestamp Now (r:1 w:1) + /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + fn set() -> Weight { + // Proof Size summary in bytes: + // Measured: `311` + // Estimated: `1493` + // Minimum execution time: 9_183_000 picoseconds. + Weight::from_parts(9_579_000, 0) + .saturating_add(Weight::from_parts(0, 1493)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn on_finalize() -> Weight { + // Proof Size summary in bytes: + // Measured: `94` + // Estimated: `0` + // Minimum execution time: 3_897_000 picoseconds. + Weight::from_parts(4_053_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_tips.rs b/polkadot/runtime/kusama/src/weights/pallet_tips.rs new file mode 100644 index 0000000000000000000000000000000000000000..64729ed63039f53c5c3ae9a3317e4f976c29645b --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_tips.rs @@ -0,0 +1,159 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +//! Autogenerated weights for `pallet_tips` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-03-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_tips +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `pallet_tips`. +pub struct WeightInfo(PhantomData); +impl pallet_tips::WeightInfo for WeightInfo { + /// Storage: Tips Reasons (r:1 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[0, 16384]`. + fn report_awesome(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `6938` + // Minimum execution time: 23_689_000 picoseconds. + Weight::from_parts(24_837_709, 0) + .saturating_add(Weight::from_parts(0, 6938)) + // Standard Error: 6 + .saturating_add(Weight::from_parts(1_449, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + fn retract_tip() -> Weight { + // Proof Size summary in bytes: + // Measured: `221` + // Estimated: `3907` + // Minimum execution time: 23_163_000 picoseconds. + Weight::from_parts(23_386_000, 0) + .saturating_add(Weight::from_parts(0, 3907)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:1 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Tips (r:0 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[0, 16384]`. + /// The range of component `t` is `[1, 19]`. + fn tip_new(r: u32, t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `108 + t * (64 ±0)` + // Estimated: `5274 + t * (192 ±0)` + // Minimum execution time: 18_945_000 picoseconds. + Weight::from_parts(17_578_665, 0) + .saturating_add(Weight::from_parts(0, 5274)) + // Standard Error: 6 + .saturating_add(Weight::from_parts(1_320, 0).saturating_mul(r.into())) + // Standard Error: 5_480 + .saturating_add(Weight::from_parts(154_765, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 192).saturating_mul(t.into())) + } + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// The range of component `t` is `[1, 19]`. + fn tip(t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `329 + t * (112 ±0)` + // Estimated: `5608 + t * (224 ±0)` + // Minimum execution time: 14_212_000 picoseconds. + Weight::from_parts(14_717_871, 0) + .saturating_add(Weight::from_parts(0, 5608)) + // Standard Error: 1_305 + .saturating_add(Weight::from_parts(135_786, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 224).saturating_mul(t.into())) + } + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// The range of component `t` is `[1, 19]`. + fn close_tip(t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `368 + t * (112 ±0)` + // Estimated: `9620 + t * (336 ±0)` + // Minimum execution time: 41_550_000 picoseconds. + Weight::from_parts(43_011_989, 0) + .saturating_add(Weight::from_parts(0, 9620)) + // Standard Error: 5_482 + .saturating_add(Weight::from_parts(120_085, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 336).saturating_mul(t.into())) + } + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// The range of component `t` is `[1, 19]`. + fn slash_tip(t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `269` + // Estimated: `4003` + // Minimum execution time: 13_897_000 picoseconds. + Weight::from_parts(14_435_129, 0) + .saturating_add(Weight::from_parts(0, 4003)) + // Standard Error: 1_409 + .saturating_add(Weight::from_parts(9_959, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_treasury.rs b/polkadot/runtime/kusama/src/weights/pallet_treasury.rs new file mode 100644 index 0000000000000000000000000000000000000000..fe2e4f9cee8f8edd52ddb76f30410edabb8c1bf4 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_treasury.rs @@ -0,0 +1,154 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_treasury` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_treasury +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_treasury`. +pub struct WeightInfo(PhantomData); +impl pallet_treasury::WeightInfo for WeightInfo { + /// Storage: Treasury ProposalCount (r:1 w:1) + /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:0 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + fn spend() -> Weight { + // Proof Size summary in bytes: + // Measured: `6` + // Estimated: `1887` + // Minimum execution time: 14_076_000 picoseconds. + Weight::from_parts(14_546_000, 0) + .saturating_add(Weight::from_parts(0, 1887)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Treasury ProposalCount (r:1 w:1) + /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:0 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + fn propose_spend() -> Weight { + // Proof Size summary in bytes: + // Measured: `107` + // Estimated: `1489` + // Minimum execution time: 27_324_000 picoseconds. + Weight::from_parts(27_723_000, 0) + .saturating_add(Weight::from_parts(0, 1489)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Treasury Proposals (r:1 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn reject_proposal() -> Weight { + // Proof Size summary in bytes: + // Measured: `265` + // Estimated: `3593` + // Minimum execution time: 41_722_000 picoseconds. + Weight::from_parts(42_638_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Treasury Proposals (r:1 w:0) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 99]`. + fn approve_proposal(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `433 + p * (8 ±0)` + // Estimated: `3573` + // Minimum execution time: 8_332_000 picoseconds. + Weight::from_parts(10_971_007, 0) + .saturating_add(Weight::from_parts(0, 3573)) + // Standard Error: 1_480 + .saturating_add(Weight::from_parts(78_440, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + fn remove_approval() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `1887` + // Minimum execution time: 6_465_000 picoseconds. + Weight::from_parts(6_632_000, 0) + .saturating_add(Weight::from_parts(0, 1887)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Treasury Deactivated (r:1 w:1) + /// Proof: Treasury Deactivated (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:100 w:100) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:201 w:201) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 100]`. + fn on_initialize_proposals(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `264 + p * (251 ±0)` + // Estimated: `3593 + p * (5206 ±0)` + // Minimum execution time: 67_339_000 picoseconds. + Weight::from_parts(61_523_213, 0) + .saturating_add(Weight::from_parts(0, 3593)) + // Standard Error: 28_817 + .saturating_add(Weight::from_parts(44_009_562, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 5206).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_utility.rs b/polkadot/runtime/kusama/src/weights/pallet_utility.rs new file mode 100644 index 0000000000000000000000000000000000000000..d6843617fe32d7749f89307c023212696dc55dd5 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_utility.rs @@ -0,0 +1,102 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_utility` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_utility +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_utility`. +pub struct WeightInfo(PhantomData); +impl pallet_utility::WeightInfo for WeightInfo { + /// The range of component `c` is `[0, 1000]`. + fn batch(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_750_000 picoseconds. + Weight::from_parts(7_924_668, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1_937 + .saturating_add(Weight::from_parts(5_116_413, 0).saturating_mul(c.into())) + } + fn as_derivative() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_928_000 picoseconds. + Weight::from_parts(5_208_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `c` is `[0, 1000]`. + fn batch_all(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_747_000 picoseconds. + Weight::from_parts(12_311_060, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 4_311 + .saturating_add(Weight::from_parts(5_344_485, 0).saturating_mul(c.into())) + } + fn dispatch_as() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_012_000 picoseconds. + Weight::from_parts(9_239_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `c` is `[0, 1000]`. + fn force_batch(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_708_000 picoseconds. + Weight::from_parts(10_795_859, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2_055 + .saturating_add(Weight::from_parts(5_143_833, 0).saturating_mul(c.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_vesting.rs b/polkadot/runtime/kusama/src/weights/pallet_vesting.rs new file mode 100644 index 0000000000000000000000000000000000000000..b33a9174bce1163ac5a990bd0502433cbd28f0ed --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_vesting.rs @@ -0,0 +1,241 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_vesting` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_vesting +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_vesting`. +pub struct WeightInfo(PhantomData); +impl pallet_vesting::WeightInfo for WeightInfo { + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `314 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 34_784_000 picoseconds. + Weight::from_parts(33_272_889, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_885 + .saturating_add(Weight::from_parts(59_791, 0).saturating_mul(l.into())) + // Standard Error: 3_354 + .saturating_add(Weight::from_parts(107_412, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `314 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 38_597_000 picoseconds. + Weight::from_parts(38_328_545, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_835 + .saturating_add(Weight::from_parts(30_108, 0).saturating_mul(l.into())) + // Standard Error: 3_265 + .saturating_add(Weight::from_parts(67_840, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `417 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 36_505_000 picoseconds. + Weight::from_parts(35_149_105, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_328 + .saturating_add(Weight::from_parts(59_063, 0).saturating_mul(l.into())) + // Standard Error: 2_363 + .saturating_add(Weight::from_parts(102_227, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `417 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 39_946_000 picoseconds. + Weight::from_parts(40_375_572, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_657 + .saturating_add(Weight::from_parts(36_203, 0).saturating_mul(l.into())) + // Standard Error: 2_948 + .saturating_add(Weight::from_parts(54_092, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `488 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 73_800_000 picoseconds. + Weight::from_parts(76_190_149, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 3_306 + .saturating_add(Weight::from_parts(62_177, 0).saturating_mul(l.into())) + // Standard Error: 5_882 + .saturating_add(Weight::from_parts(142_130, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn force_vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `591 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `6196` + // Minimum execution time: 74_744_000 picoseconds. + Weight::from_parts(77_992_773, 0) + .saturating_add(Weight::from_parts(0, 6196)) + // Standard Error: 3_321 + .saturating_add(Weight::from_parts(66_392, 0).saturating_mul(l.into())) + // Standard Error: 5_910 + .saturating_add(Weight::from_parts(142_911, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn not_unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `415 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 37_626_000 picoseconds. + Weight::from_parts(36_213_370, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_056 + .saturating_add(Weight::from_parts(56_586, 0).saturating_mul(l.into())) + // Standard Error: 3_798 + .saturating_add(Weight::from_parts(111_413, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `415 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 41_647_000 picoseconds. + Weight::from_parts(40_350_649, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_906 + .saturating_add(Weight::from_parts(59_779, 0).saturating_mul(l.into())) + // Standard Error: 3_521 + .saturating_add(Weight::from_parts(111_787, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_whitelist.rs b/polkadot/runtime/kusama/src/weights/pallet_whitelist.rs new file mode 100644 index 0000000000000000000000000000000000000000..fe2d317651a028294d4d70d94b97896d1bcb5edb --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_whitelist.rs @@ -0,0 +1,118 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_whitelist` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_whitelist +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_whitelist`. +pub struct WeightInfo(PhantomData); +impl pallet_whitelist::WeightInfo for WeightInfo { + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn whitelist_call() -> Weight { + // Proof Size summary in bytes: + // Measured: `118` + // Estimated: `3556` + // Minimum execution time: 19_893_000 picoseconds. + Weight::from_parts(20_176_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn remove_whitelisted_call() -> Weight { + // Proof Size summary in bytes: + // Measured: `247` + // Estimated: `3556` + // Minimum execution time: 17_393_000 picoseconds. + Weight::from_parts(18_076_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:1 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: Measured) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 4194294]`. + fn dispatch_whitelisted_call(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `323 + n * (1 ±0)` + // Estimated: `3787 + n * (1 ±0)` + // Minimum execution time: 29_485_000 picoseconds. + Weight::from_parts(29_730_000, 0) + .saturating_add(Weight::from_parts(0, 3787)) + // Standard Error: 8 + .saturating_add(Weight::from_parts(1_530, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) + } + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 10000]`. + fn dispatch_whitelisted_call_with_preimage(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `247` + // Estimated: `3556` + // Minimum execution time: 21_190_000 picoseconds. + Weight::from_parts(21_802_426, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(1_465, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/pallet_xcm.rs b/polkadot/runtime/kusama/src/weights/pallet_xcm.rs new file mode 100644 index 0000000000000000000000000000000000000000..4b1a790a57a146641fd172b71d5248de500e108a --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/pallet_xcm.rs @@ -0,0 +1,282 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_xcm +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/var/lib/gitlab-runner/builds/zyw4fam_/0/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=kusama-dev +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm`. +pub struct WeightInfo(PhantomData); +impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn send() -> Weight { + // Proof Size summary in bytes: + // Measured: `211` + // Estimated: `3676` + // Minimum execution time: 36_359_000 picoseconds. + Weight::from_parts(37_262_000, 0) + .saturating_add(Weight::from_parts(0, 3676)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + fn teleport_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 22_115_000 picoseconds. + Weight::from_parts(22_381_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn reserve_transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 21_978_000 picoseconds. + Weight::from_parts(22_407_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn execute() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_620_000 picoseconds. + Weight::from_parts(10_061_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: XcmPallet SupportedVersion (r:0 w:1) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + fn force_xcm_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_884_000 picoseconds. + Weight::from_parts(10_207_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn force_default_xcm_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_939_000 picoseconds. + Weight::from_parts(3_022_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: XcmPallet VersionNotifiers (r:1 w:1) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet QueryCounter (r:1 w:1) + /// Proof Skipped: XcmPallet QueryCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet Queries (r:0 w:1) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + fn force_subscribe_version_notify() -> Weight { + // Proof Size summary in bytes: + // Measured: `211` + // Estimated: `3676` + // Minimum execution time: 40_948_000 picoseconds. + Weight::from_parts(41_577_000, 0) + .saturating_add(Weight::from_parts(0, 3676)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: XcmPallet VersionNotifiers (r:1 w:1) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet Queries (r:0 w:1) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + fn force_unsubscribe_version_notify() -> Weight { + // Proof Size summary in bytes: + // Measured: `538` + // Estimated: `4003` + // Minimum execution time: 45_857_000 picoseconds. + Weight::from_parts(47_289_000, 0) + .saturating_add(Weight::from_parts(0, 4003)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: XcmPallet XcmExecutionSuspended (r:0 w:1) + /// Proof Skipped: XcmPallet XcmExecutionSuspended (max_values: Some(1), max_size: None, mode: Measured) + fn force_suspension() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_837_000 picoseconds. + Weight::from_parts(3_065_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: XcmPallet SupportedVersion (r:4 w:2) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + fn migrate_supported_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `229` + // Estimated: `11119` + // Minimum execution time: 17_125_000 picoseconds. + Weight::from_parts(17_582_000, 0) + .saturating_add(Weight::from_parts(0, 11119)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifiers (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + fn migrate_version_notifiers() -> Weight { + // Proof Size summary in bytes: + // Measured: `233` + // Estimated: `11123` + // Minimum execution time: 16_834_000 picoseconds. + Weight::from_parts(17_412_000, 0) + .saturating_add(Weight::from_parts(0, 11123)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:5 w:0) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn already_notified_target() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `13608` + // Minimum execution time: 18_784_000 picoseconds. + Weight::from_parts(19_184_000, 0) + .saturating_add(Weight::from_parts(0, 13608)) + .saturating_add(T::DbWeight::get().reads(5)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:2 w:1) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn notify_current_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `281` + // Estimated: `6221` + // Minimum execution time: 38_232_000 picoseconds. + Weight::from_parts(39_125_000, 0) + .saturating_add(Weight::from_parts(0, 6221)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:3 w:0) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn notify_target_migration_fail() -> Weight { + // Proof Size summary in bytes: + // Measured: `272` + // Estimated: `8687` + // Minimum execution time: 9_661_000 picoseconds. + Weight::from_parts(10_094_000, 0) + .saturating_add(Weight::from_parts(0, 8687)) + .saturating_add(T::DbWeight::get().reads(3)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn migrate_version_notify_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `240` + // Estimated: `11130` + // Minimum execution time: 17_593_000 picoseconds. + Weight::from_parts(18_158_000, 0) + .saturating_add(Weight::from_parts(0, 11130)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn migrate_and_notify_old_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `285` + // Estimated: `11175` + // Minimum execution time: 45_525_000 picoseconds. + Weight::from_parts(46_583_000, 0) + .saturating_add(Weight::from_parts(0, 11175)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(6)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_auctions.rs b/polkadot/runtime/kusama/src/weights/runtime_common_auctions.rs new file mode 100644 index 0000000000000000000000000000000000000000..2370f98f07037c03634ae549b5120ba64a50c8f7 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_common_auctions.rs @@ -0,0 +1,143 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::auctions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::auctions +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_common_auctions.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::auctions`. +pub struct WeightInfo(PhantomData); +impl runtime_common::auctions::WeightInfo for WeightInfo { + /// Storage: Auctions AuctionInfo (r:1 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Auctions AuctionCounter (r:1 w:1) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn new_auction() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `1493` + // Minimum execution time: 12_713_000 picoseconds. + Weight::from_parts(13_211_000, 0) + .saturating_add(Weight::from_parts(0, 1493)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions Winning (r:1 w:1) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:2 w:2) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn bid() -> Weight { + // Proof Size summary in bytes: + // Measured: `661` + // Estimated: `6060` + // Minimum execution time: 98_648_000 picoseconds. + Weight::from_parts(106_823_000, 0) + .saturating_add(Weight::from_parts(0, 6060)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Auctions AuctionInfo (r:1 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe NextRandomness (r:1 w:0) + /// Proof: Babe NextRandomness (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: Babe EpochStart (r:1 w:0) + /// Proof: Babe EpochStart (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Auctions Winning (r:3600 w:3600) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:37 w:36) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:36 w:36) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Slots Leases (r:7 w:7) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + fn on_initialize() -> Weight { + // Proof Size summary in bytes: + // Measured: `6947699` + // Estimated: `15822990` + // Minimum execution time: 7_936_854_000 picoseconds. + Weight::from_parts(8_091_086_000, 0) + .saturating_add(Weight::from_parts(0, 15822990)) + .saturating_add(T::DbWeight::get().reads(3688)) + .saturating_add(T::DbWeight::get().writes(3683)) + } + /// Storage: Auctions ReservedAmounts (r:37 w:36) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:36 w:36) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Auctions Winning (r:3600 w:3600) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions AuctionInfo (r:0 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + fn cancel_auction() -> Weight { + // Proof Size summary in bytes: + // Measured: `177732` + // Estimated: `15822990` + // Minimum execution time: 6_127_393_000 picoseconds. + Weight::from_parts(6_302_044_000, 0) + .saturating_add(Weight::from_parts(0, 15822990)) + .saturating_add(T::DbWeight::get().reads(3673)) + .saturating_add(T::DbWeight::get().writes(3673)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_claims.rs b/polkadot/runtime/kusama/src/weights/runtime_common_claims.rs new file mode 100644 index 0000000000000000000000000000000000000000..ecf29f0cdc1858fe21ed07c28cc1f81d607cf039 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_common_claims.rs @@ -0,0 +1,169 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::claims` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::claims +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_common_claims.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::claims`. +pub struct WeightInfo(PhantomData); +impl runtime_common::claims::WeightInfo for WeightInfo { + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + fn claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `620` + // Estimated: `4764` + // Minimum execution time: 213_980_000 picoseconds. + Weight::from_parts(229_096_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:0 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Claims (r:0 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:0 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + fn mint_claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `216` + // Estimated: `1701` + // Minimum execution time: 13_378_000 picoseconds. + Weight::from_parts(15_841_000, 0) + .saturating_add(Weight::from_parts(0, 1701)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + fn claim_attest() -> Weight { + // Proof Size summary in bytes: + // Measured: `620` + // Estimated: `4764` + // Minimum execution time: 213_747_000 picoseconds. + Weight::from_parts(236_937_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Claims Preclaims (r:1 w:1) + /// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + fn attest() -> Weight { + // Proof Size summary in bytes: + // Measured: `694` + // Estimated: `4764` + // Minimum execution time: 103_706_000 picoseconds. + Weight::from_parts(108_213_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Claims Claims (r:1 w:2) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:2) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:2) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Preclaims (r:1 w:1) + /// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured) + fn move_claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `440` + // Estimated: `3905` + // Minimum execution time: 27_331_000 picoseconds. + Weight::from_parts(29_408_000, 0) + .saturating_add(Weight::from_parts(0, 3905)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(7)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_crowdloan.rs b/polkadot/runtime/kusama/src/weights/runtime_common_crowdloan.rs new file mode 100644 index 0000000000000000000000000000000000000000..1785e0e5d38ba3748068fa9c083c7c5e318fb19e --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_common_crowdloan.rs @@ -0,0 +1,225 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::crowdloan` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::crowdloan +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_common_crowdloan.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::crowdloan`. +pub struct WeightInfo(PhantomData); +impl runtime_common::crowdloan::WeightInfo for WeightInfo { + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan NextFundIndex (r:1 w:1) + /// Proof Skipped: Crowdloan NextFundIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn create() -> Weight { + // Proof Size summary in bytes: + // Measured: `415` + // Estimated: `3880` + // Minimum execution time: 67_350_000 picoseconds. + Weight::from_parts(70_662_000, 0) + .saturating_add(Weight::from_parts(0, 3880)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Crowdloan EndingsCount (r:1 w:0) + /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + fn contribute() -> Weight { + // Proof Size summary in bytes: + // Measured: `463` + // Estimated: `3928` + // Minimum execution time: 172_864_000 picoseconds. + Weight::from_parts(181_577_000, 0) + .saturating_add(Weight::from_parts(0, 3928)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + /// Proof Skipped: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + fn withdraw() -> Weight { + // Proof Size summary in bytes: + // Measured: `690` + // Estimated: `6196` + // Minimum execution time: 92_816_000 picoseconds. + Weight::from_parts(102_956_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `k` is `[0, 1000]`. + fn refund(k: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `128 + k * (189 ±0)` + // Estimated: `141 + k * (189 ±0)` + // Minimum execution time: 67_361_000 picoseconds. + Weight::from_parts(73_320_000, 0) + .saturating_add(Weight::from_parts(0, 141)) + // Standard Error: 30_080 + .saturating_add(Weight::from_parts(43_879_049, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(k.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(k.into()))) + .saturating_add(Weight::from_parts(0, 189).saturating_mul(k.into())) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn dissolve() -> Weight { + // Proof Size summary in bytes: + // Measured: `515` + // Estimated: `6196` + // Minimum execution time: 56_194_000 picoseconds. + Weight::from_parts(63_604_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + fn edit() -> Weight { + // Proof Size summary in bytes: + // Measured: `235` + // Estimated: `3700` + // Minimum execution time: 27_093_000 picoseconds. + Weight::from_parts(32_181_000, 0) + .saturating_add(Weight::from_parts(0, 3700)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Crowdloan Funds (r:1 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + fn add_memo() -> Weight { + // Proof Size summary in bytes: + // Measured: `412` + // Estimated: `3877` + // Minimum execution time: 39_489_000 picoseconds. + Weight::from_parts(44_798_000, 0) + .saturating_add(Weight::from_parts(0, 3877)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Crowdloan Funds (r:1 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + fn poke() -> Weight { + // Proof Size summary in bytes: + // Measured: `239` + // Estimated: `3704` + // Minimum execution time: 26_147_000 picoseconds. + Weight::from_parts(30_760_000, 0) + .saturating_add(Weight::from_parts(0, 3704)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Crowdloan EndingsCount (r:1 w:1) + /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan Funds (r:100 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Paras ParaLifecycles (r:100 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:100 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions Winning (r:1 w:1) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:100 w:100) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:100 w:100) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `n` is `[2, 100]`. + fn on_initialize(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `130 + n * (356 ±0)` + // Estimated: `5385 + n * (2832 ±0)` + // Minimum execution time: 163_693_000 picoseconds. + Weight::from_parts(22_145_813, 0) + .saturating_add(Weight::from_parts(0, 5385)) + // Standard Error: 47_670 + .saturating_add(Weight::from_parts(72_049_146, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2832).saturating_mul(n.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_paras_registrar.rs b/polkadot/runtime/kusama/src/weights/runtime_common_paras_registrar.rs new file mode 100644 index 0000000000000000000000000000000000000000..9426d667346b1b4f72e3776d3a2d766182553fab --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_common_paras_registrar.rs @@ -0,0 +1,218 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::paras_registrar` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::paras_registrar +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_common_paras_registrar.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::paras_registrar`. +pub struct WeightInfo(PhantomData); +impl runtime_common::paras_registrar::WeightInfo for WeightInfo { + /// Storage: Registrar NextFreeParaId (r:1 w:1) + /// Proof Skipped: Registrar NextFreeParaId (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + fn reserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `70` + // Estimated: `3535` + // Minimum execution time: 30_262_000 picoseconds. + Weight::from_parts(30_881_000, 0) + .saturating_add(Weight::from_parts(0, 3535)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:0 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpcomingParasGenesis (r:0 w:1) + /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) + fn register() -> Weight { + // Proof Size summary in bytes: + // Measured: `329` + // Estimated: `3794` + // Minimum execution time: 6_443_064_000 picoseconds. + Weight::from_parts(7_074_736_000, 0) + .saturating_add(Weight::from_parts(0, 3794)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:0 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpcomingParasGenesis (r:0 w:1) + /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) + fn force_register() -> Weight { + // Proof Size summary in bytes: + // Measured: `219` + // Estimated: `3684` + // Minimum execution time: 6_298_725_000 picoseconds. + Weight::from_parts(7_130_498_000, 0) + .saturating_add(Weight::from_parts(0, 3684)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeHash (r:1 w:0) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: Registrar PendingSwap (r:0 w:1) + /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) + fn deregister() -> Weight { + // Proof Size summary in bytes: + // Measured: `476` + // Estimated: `3941` + // Minimum execution time: 60_696_000 picoseconds. + Weight::from_parts(65_976_000, 0) + .saturating_add(Weight::from_parts(0, 3941)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Registrar Paras (r:1 w:0) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:2 w:2) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar PendingSwap (r:1 w:1) + /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan Funds (r:2 w:2) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:2 w:2) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + fn swap() -> Weight { + // Proof Size summary in bytes: + // Measured: `713` + // Estimated: `6653` + // Minimum execution time: 72_165_000 picoseconds. + Weight::from_parts(80_369_000, 0) + .saturating_add(Weight::from_parts(0, 6653)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Paras FutureCodeHash (r:1 w:1) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:1 w:1) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeCooldowns (r:1 w:1) + /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[1, 3145728]`. + fn schedule_code_upgrade(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `177` + // Estimated: `3642` + // Minimum execution time: 40_883_000 picoseconds. + Weight::from_parts(41_276_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + // Standard Error: 5 + .saturating_add(Weight::from_parts(2_552, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[1, 1048576]`. + fn set_current_head(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_864_000 picoseconds. + Weight::from_parts(9_023_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(983, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_slots.rs b/polkadot/runtime/kusama/src/weights/runtime_common_slots.rs new file mode 100644 index 0000000000000000000000000000000000000000..8c76ff2c693ae5b78b1d05ce5070e669e07c545c --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_common_slots.rs @@ -0,0 +1,135 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::slots` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::slots +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_common_slots.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::slots`. +pub struct WeightInfo(PhantomData); +impl runtime_common::slots::WeightInfo for WeightInfo { + /// Storage: Slots Leases (r:1 w:1) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_lease() -> Weight { + // Proof Size summary in bytes: + // Measured: `220` + // Estimated: `3685` + // Minimum execution time: 30_513_000 picoseconds. + Weight::from_parts(31_238_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Slots Leases (r:101 w:100) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:200 w:200) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:100 w:100) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 100]`. + /// The range of component `t` is `[0, 100]`. + fn manage_lease_period_start(c: u32, t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `46 + c * (47 ±0) + t * (308 ±0)` + // Estimated: `2823 + c * (2526 ±0) + t * (2789 ±0)` + // Minimum execution time: 758_558_000 picoseconds. + Weight::from_parts(769_052_000, 0) + .saturating_add(Weight::from_parts(0, 2823)) + // Standard Error: 93_260 + .saturating_add(Weight::from_parts(3_338_461, 0).saturating_mul(c.into())) + // Standard Error: 93_260 + .saturating_add(Weight::from_parts(13_755_524, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(t.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(t.into()))) + .saturating_add(Weight::from_parts(0, 2526).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 2789).saturating_mul(t.into())) + } + /// Storage: Slots Leases (r:1 w:1) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:8 w:8) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn clear_all_leases() -> Weight { + // Proof Size summary in bytes: + // Measured: `2692` + // Estimated: `21814` + // Minimum execution time: 155_205_000 picoseconds. + Weight::from_parts(162_036_000, 0) + .saturating_add(Weight::from_parts(0, 21814)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(9)) + } + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + fn trigger_onboard() -> Weight { + // Proof Size summary in bytes: + // Measured: `617` + // Estimated: `4082` + // Minimum execution time: 38_799_000 picoseconds. + Weight::from_parts(42_044_000, 0) + .saturating_add(Weight::from_parts(0, 4082)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_parachains_configuration.rs b/polkadot/runtime/kusama/src/weights/runtime_parachains_configuration.rs new file mode 100644 index 0000000000000000000000000000000000000000..22609209c7333386874d23172b91e3ada94b8fab --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_parachains_configuration.rs @@ -0,0 +1,157 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::configuration` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-fljshgub-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("kusama-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_parachains::configuration +// --chain=kusama-dev +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::configuration`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::configuration::WeightInfo for WeightInfo { + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_block_number() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_186_000 picoseconds. + Weight::from_parts(9_567_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_u32() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_388_000 picoseconds. + Weight::from_parts(9_723_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_option_u32() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_264_000 picoseconds. + Weight::from_parts(9_477_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn set_hrmp_open_request_ttl() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_000_000_000_000 picoseconds. + Weight::from_parts(2_000_000_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_balance() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_282_000 picoseconds. + Weight::from_parts(9_641_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_executor_params() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_937_000 picoseconds. + Weight::from_parts(10_445_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_perbill() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_106_000 picoseconds. + Weight::from_parts(9_645_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_parachains_disputes.rs b/polkadot/runtime/kusama/src/weights/runtime_parachains_disputes.rs new file mode 100644 index 0000000000000000000000000000000000000000..be78e3ac86b6ac2475df11c85d5afba9e5df396b --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_parachains_disputes.rs @@ -0,0 +1,64 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::disputes` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::disputes +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_parachains_disputes.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::disputes`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::disputes::WeightInfo for WeightInfo { + /// Storage: ParasDisputes Frozen (r:0 w:1) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + fn force_unfreeze() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_684_000 picoseconds. + Weight::from_parts(2_943_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_parachains_disputes_slashing.rs b/polkadot/runtime/kusama/src/weights/runtime_parachains_disputes_slashing.rs new file mode 100644 index 0000000000000000000000000000000000000000..bcde1ef418d8934df5855ab5331b631e040dda6a --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_parachains_disputes_slashing.rs @@ -0,0 +1,101 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::disputes::slashing` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::disputes::slashing +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_parachains_disputes_slashing.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::disputes::slashing`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::disputes::slashing::WeightInfo for WeightInfo { + /// Storage: Session CurrentIndex (r:1 w:0) + /// Proof Skipped: Session CurrentIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Historical HistoricalSessions (r:1 w:0) + /// Proof: Historical HistoricalSessions (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: ParasSlashing UnappliedSlashes (r:1 w:1) + /// Proof Skipped: ParasSlashing UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:1 w:1) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:1 w:1) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:1 w:1) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session DisabledValidators (r:1 w:1) + /// Proof Skipped: Session DisabledValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[4, 1000]`. + fn report_dispute_lost(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `5325 + n * (184 ±0)` + // Estimated: `8537 + n * (188 ±0)` + // Minimum execution time: 117_607_000 picoseconds. + Weight::from_parts(165_902_178, 0) + .saturating_add(Weight::from_parts(0, 8537)) + // Standard Error: 3_310 + .saturating_add(Weight::from_parts(358_233, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(17)) + .saturating_add(T::DbWeight::get().writes(10)) + .saturating_add(Weight::from_parts(0, 188).saturating_mul(n.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_parachains_hrmp.rs b/polkadot/runtime/kusama/src/weights/runtime_parachains_hrmp.rs new file mode 100644 index 0000000000000000000000000000000000000000..c13a8413e4102ac4fbedb64fab0c92fcb6dcf247 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_parachains_hrmp.rs @@ -0,0 +1,285 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::hrmp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::hrmp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_parachains_hrmp.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::hrmp`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::hrmp::WeightInfo for WeightInfo { + /// Storage: Paras ParaLifecycles (r:2 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_init_open_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `350` + // Estimated: `6290` + // Minimum execution time: 37_901_000 picoseconds. + Weight::from_parts(38_728_000, 0) + .saturating_add(Weight::from_parts(0, 6290)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_accept_open_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `582` + // Estimated: `4047` + // Minimum execution time: 37_634_000 picoseconds. + Weight::from_parts(38_332_000, 0) + .saturating_add(Weight::from_parts(0, 4047)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_close_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `453` + // Estimated: `3918` + // Minimum execution time: 33_719_000 picoseconds. + Weight::from_parts(34_342_000, 0) + .saturating_add(Weight::from_parts(0, 3918)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:254 w:254) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:0 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelContents (r:0 w:254) + /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:0 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 127]`. + /// The range of component `e` is `[0, 127]`. + fn force_clean_hrmp(i: u32, e: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `197 + e * (100 ±0) + i * (100 ±0)` + // Estimated: `3659 + e * (2575 ±0) + i * (2575 ±0)` + // Minimum execution time: 1_267_013_000 picoseconds. + Weight::from_parts(1_283_708_000, 0) + .saturating_add(Weight::from_parts(0, 3659)) + // Standard Error: 118_117 + .saturating_add(Weight::from_parts(3_722_255, 0).saturating_mul(i.into())) + // Standard Error: 118_117 + .saturating_add(Weight::from_parts(3_701_842, 0).saturating_mul(e.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into()))) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(e.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(i.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(e.into()))) + .saturating_add(Weight::from_parts(0, 2575).saturating_mul(e.into())) + .saturating_add(Weight::from_parts(0, 2575).saturating_mul(i.into())) + } + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:256 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:128 w:128) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:0 w:128) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn force_process_hrmp_open(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `425 + c * (136 ±0)` + // Estimated: `1880 + c * (5086 ±0)` + // Minimum execution time: 6_798_000 picoseconds. + Weight::from_parts(6_921_000, 0) + .saturating_add(Weight::from_parts(0, 1880)) + // Standard Error: 12_517 + .saturating_add(Weight::from_parts(21_683_294, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((6_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 5086).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:128 w:128) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequests (r:0 w:128) + /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelContents (r:0 w:128) + /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn force_process_hrmp_close(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `268 + c * (124 ±0)` + // Estimated: `1728 + c * (2600 ±0)` + // Minimum execution time: 5_695_000 picoseconds. + Weight::from_parts(5_776_000, 0) + .saturating_add(Weight::from_parts(0, 1728)) + // Standard Error: 11_189 + .saturating_add(Weight::from_parts(13_477_149, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 2600).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn hrmp_cancel_open_request(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `959 + c * (13 ±0)` + // Estimated: `4228 + c * (15 ±0)` + // Minimum execution time: 21_141_000 picoseconds. + Weight::from_parts(29_731_969, 0) + .saturating_add(Weight::from_parts(0, 4228)) + // Standard Error: 3_263 + .saturating_add(Weight::from_parts(198_283, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 15).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn clean_open_channel_requests(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `176 + c * (63 ±0)` + // Estimated: `1655 + c * (2538 ±0)` + // Minimum execution time: 4_573_000 picoseconds. + Weight::from_parts(5_593_572, 0) + .saturating_add(Weight::from_parts(0, 1655)) + // Standard Error: 4_134 + .saturating_add(Weight::from_parts(3_565_821, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 2538).saturating_mul(c.into())) + } + /// Storage: Paras ParaLifecycles (r:2 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:2 w:2) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:2 w:2) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + fn force_open_hrmp_channel(_c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `350` + // Estimated: `6290` + // Minimum execution time: 53_253_000 picoseconds. + Weight::from_parts(55_141_000, 0) + .saturating_add(Weight::from_parts(0, 6290)) + .saturating_add(T::DbWeight::get().reads(13)) + .saturating_add(T::DbWeight::get().writes(8)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_parachains_inclusion.rs b/polkadot/runtime/kusama/src/weights/runtime_parachains_inclusion.rs new file mode 100644 index 0000000000000000000000000000000000000000..9ca4b2fe2a7e7353dc09bc9b7415c57f2b7807e8 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_parachains_inclusion.rs @@ -0,0 +1,75 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::inclusion` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::inclusion +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_parachains_inclusion.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::inclusion`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::inclusion::WeightInfo for WeightInfo { + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:999) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// The range of component `i` is `[1, 1000]`. + fn receive_upward_messages(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `65761` + // Estimated: `69051` + // Minimum execution time: 119_471_000 picoseconds. + Weight::from_parts(120_105_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + // Standard Error: 42_037 + .saturating_add(Weight::from_parts(103_436_040, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_parachains_initializer.rs b/polkadot/runtime/kusama/src/weights/runtime_parachains_initializer.rs new file mode 100644 index 0000000000000000000000000000000000000000..31878846d328126ac41cb71969c8d14a9108d9f4 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_parachains_initializer.rs @@ -0,0 +1,69 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::initializer` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::initializer +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_parachains_initializer.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::initializer`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::initializer::WeightInfo for WeightInfo { + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `d` is `[0, 65536]`. + fn force_approve(d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + d * (11 ±0)` + // Estimated: `1480 + d * (11 ±0)` + // Minimum execution time: 3_509_000 picoseconds. + Weight::from_parts(3_655_000, 0) + .saturating_add(Weight::from_parts(0, 1480)) + // Standard Error: 15 + .saturating_add(Weight::from_parts(2_861, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 11).saturating_mul(d.into())) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_parachains_paras.rs b/polkadot/runtime/kusama/src/weights/runtime_parachains_paras.rs new file mode 100644 index 0000000000000000000000000000000000000000..9e66592fbdfab1520b0267f4fbbeb6bde5809d22 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_parachains_paras.rs @@ -0,0 +1,289 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::paras` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::paras +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_parachains_paras.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::paras`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::paras::WeightInfo for WeightInfo { + /// Storage: Paras CurrentCodeHash (r:1 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PastCodeMeta (r:1 w:1) + /// Proof Skipped: Paras PastCodeMeta (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PastCodePruning (r:1 w:1) + /// Proof Skipped: Paras PastCodePruning (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PastCodeHash (r:0 w:1) + /// Proof Skipped: Paras PastCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:0 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn force_set_current_code(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `8309` + // Estimated: `11774` + // Minimum execution time: 33_015_000 picoseconds. + Weight::from_parts(33_678_000, 0) + .saturating_add(Weight::from_parts(0, 11774)) + // Standard Error: 5 + .saturating_add(Weight::from_parts(2_417, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// The range of component `s` is `[1, 1048576]`. + fn force_set_current_head(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_308_000 picoseconds. + Weight::from_parts(8_473_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(992, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: Paras Heads (r:0 w:1) + fn force_set_most_recent_context() -> Weight { + Weight::from_parts(10_155_000, 0) + // Standard Error: 0 + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + /// Storage: Paras FutureCodeHash (r:1 w:1) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeCooldowns (r:1 w:1) + /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn force_schedule_code_upgrade(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `8428` + // Estimated: `11893` + // Minimum execution time: 49_058_000 picoseconds. + Weight::from_parts(49_768_000, 0) + .saturating_add(Weight::from_parts(0, 11893)) + // Standard Error: 7 + .saturating_add(Weight::from_parts(2_541, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `s` is `[1, 1048576]`. + fn force_note_new_head(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `95` + // Estimated: `3560` + // Minimum execution time: 13_559_000 picoseconds. + Weight::from_parts(13_774_000, 0) + .saturating_add(Weight::from_parts(0, 3560)) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_082, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + fn force_queue_action() -> Weight { + // Proof Size summary in bytes: + // Measured: `4288` + // Estimated: `7753` + // Minimum execution time: 20_213_000 picoseconds. + Weight::from_parts(20_576_000, 0) + .saturating_add(Weight::from_parts(0, 7753)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn add_trusted_validation_code(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `659` + // Estimated: `4124` + // Minimum execution time: 99_127_000 picoseconds. + Weight::from_parts(82_909_137, 0) + .saturating_add(Weight::from_parts(0, 4124)) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_848, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Paras CodeByHashRefs (r:1 w:0) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:0 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + fn poke_unused_validation_code() -> Weight { + // Proof Size summary in bytes: + // Measured: `28` + // Estimated: `3493` + // Minimum execution time: 5_816_000 picoseconds. + Weight::from_parts(6_139_000, 0) + .saturating_add(Weight::from_parts(0, 3493)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement() -> Weight { + // Proof Size summary in bytes: + // Measured: `26682` + // Estimated: `30147` + // Minimum execution time: 116_078_000 picoseconds. + Weight::from_parts(119_110_000, 0) + .saturating_add(Weight::from_parts(0, 30147)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras UpcomingUpgrades (r:1 w:1) + /// Proof Skipped: Paras UpcomingUpgrades (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:0 w:100) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_upgrade_accept() -> Weight { + // Proof Size summary in bytes: + // Measured: `27236` + // Estimated: `30701` + // Minimum execution time: 934_879_000 picoseconds. + Weight::from_parts(946_892_000, 0) + .saturating_add(Weight::from_parts(0, 30701)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(104)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_upgrade_reject() -> Weight { + // Proof Size summary in bytes: + // Measured: `27214` + // Estimated: `30679` + // Minimum execution time: 112_297_000 picoseconds. + Weight::from_parts(118_546_000, 0) + .saturating_add(Weight::from_parts(0, 30679)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_onboarding_accept() -> Weight { + // Proof Size summary in bytes: + // Measured: `26704` + // Estimated: `30169` + // Minimum execution time: 723_534_000 picoseconds. + Weight::from_parts(746_144_000, 0) + .saturating_add(Weight::from_parts(0, 30169)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_onboarding_reject() -> Weight { + // Proof Size summary in bytes: + // Measured: `26682` + // Estimated: `30147` + // Minimum execution time: 110_352_000 picoseconds. + Weight::from_parts(115_568_000, 0) + .saturating_add(Weight::from_parts(0, 30147)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/runtime_parachains_paras_inherent.rs b/polkadot/runtime/kusama/src/weights/runtime_parachains_paras_inherent.rs new file mode 100644 index 0000000000000000000000000000000000000000..9a9a3a3dffb5a1a1f364610cbb2dd8267adf8a97 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_parachains_paras_inherent.rs @@ -0,0 +1,345 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::paras_inherent` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-xerhrdyb-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_parachains::paras_inherent +// --chain=kusama-dev +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::paras_inherent`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::paras_inherent::WeightInfo for WeightInfo { + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: ParaSessionInfo Sessions (r:1 w:0) + /// Proof Skipped: ParaSessionInfo Sessions (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:1) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes BackersOnDisputes (r:1 w:1) + /// Proof Skipped: ParasDisputes BackersOnDisputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Included (r:1 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `v` is `[10, 200]`. + fn enter_variable_disputes(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `50671` + // Estimated: `56611 + v * (23 ±0)` + // Minimum execution time: 1_008_586_000 picoseconds. + Weight::from_parts(471_892_709, 0) + .saturating_add(Weight::from_parts(0, 56611)) + // Standard Error: 15_634 + .saturating_add(Weight::from_parts(56_433_120, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(27)) + .saturating_add(T::DbWeight::get().writes(15)) + .saturating_add(Weight::from_parts(0, 23).saturating_mul(v.into())) + } + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:0) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion AvailabilityBitfields (r:0 w:1) + /// Proof Skipped: ParaInclusion AvailabilityBitfields (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Included (r:0 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + fn enter_bitfields() -> Weight { + // Proof Size summary in bytes: + // Measured: `42504` + // Estimated: `48444` + // Minimum execution time: 469_409_000 picoseconds. + Weight::from_parts(487_865_000, 0) + .saturating_add(Weight::from_parts(0, 48444)) + .saturating_add(T::DbWeight::get().reads(25)) + .saturating_add(T::DbWeight::get().writes(16)) + } + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:0) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: ParasDisputes Included (r:0 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `v` is `[101, 200]`. + fn enter_backed_candidates_variable(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `42540` + // Estimated: `48480` + // Minimum execution time: 6_874_816_000 picoseconds. + Weight::from_parts(1_229_912_739, 0) + .saturating_add(Weight::from_parts(0, 48480)) + // Standard Error: 27_352 + .saturating_add(Weight::from_parts(56_137_302, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(28)) + .saturating_add(T::DbWeight::get().writes(15)) + } + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:0) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeHash (r:1 w:0) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:1 w:0) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: ParasDisputes Included (r:0 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + fn enter_backed_candidate_code_upgrade() -> Weight { + // Proof Size summary in bytes: + // Measured: `42567` + // Estimated: `48507` + // Minimum execution time: 41_075_073_000 picoseconds. + Weight::from_parts(43_753_587_000, 0) + .saturating_add(Weight::from_parts(0, 48507)) + .saturating_add(T::DbWeight::get().reads(30)) + .saturating_add(T::DbWeight::get().writes(15)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/xcm/mod.rs b/polkadot/runtime/kusama/src/weights/xcm/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..5958abe40df94109fb3c4ee09b70a47edccda9da --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/xcm/mod.rs @@ -0,0 +1,290 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +mod pallet_xcm_benchmarks_fungible; +mod pallet_xcm_benchmarks_generic; + +use crate::Runtime; +use frame_support::weights::Weight; +use sp_std::prelude::*; +use xcm::{latest::prelude::*, DoubleEncoded}; + +use pallet_xcm_benchmarks_fungible::WeightInfo as XcmBalancesWeight; +use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; + +/// Types of asset supported by the Kusama runtime. +pub enum AssetTypes { + /// An asset backed by `pallet-balances`. + Balances, + /// Unknown asset. + Unknown, +} + +impl From<&MultiAsset> for AssetTypes { + fn from(asset: &MultiAsset) -> Self { + match asset { + MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), .. } => + AssetTypes::Balances, + _ => AssetTypes::Unknown, + } + } +} + +trait WeighMultiAssets { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight; +} + +// Kusama only knows about one asset, the balances pallet. +const MAX_ASSETS: u64 = 1; + +impl WeighMultiAssets for MultiAssetFilter { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { + match self { + Self::Definite(assets) => assets + .inner() + .into_iter() + .map(From::from) + .map(|t| match t { + AssetTypes::Balances => balances_weight, + AssetTypes::Unknown => Weight::MAX, + }) + .fold(Weight::zero(), |acc, x| acc.saturating_add(x)), + // We don't support any NFTs on Kusama, so these two variants will always match + // only 1 kind of fungible asset. + Self::Wild(AllOf { .. } | AllOfCounted { .. }) => balances_weight, + Self::Wild(AllCounted(count)) => + balances_weight.saturating_mul(MAX_ASSETS.min(*count as u64)), + Self::Wild(All) => balances_weight.saturating_mul(MAX_ASSETS), + } + } +} + +impl WeighMultiAssets for MultiAssets { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { + self.inner() + .into_iter() + .map(|m| >::from(m)) + .map(|t| match t { + AssetTypes::Balances => balances_weight, + AssetTypes::Unknown => Weight::MAX, + }) + .fold(Weight::zero(), |acc, x| acc.saturating_add(x)) + } +} + +pub struct KusamaXcmWeight(core::marker::PhantomData); +impl XcmWeightInfo for KusamaXcmWeight { + fn withdraw_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) + } + fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { + // Kusama doesn't support ReserveAssetDeposited, so this benchmark has a default weight + assets.weigh_multi_assets(XcmBalancesWeight::::reserve_asset_deposited()) + } + fn receive_teleported_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) + } + fn query_response( + _query_id: &u64, + _response: &Response, + _max_weight: &Weight, + _querier: &Option, + ) -> Weight { + XcmGeneric::::query_response() + } + fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) + } + fn transfer_reserve_asset( + assets: &MultiAssets, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::transfer_reserve_asset()) + } + fn transact( + _origin_kind: &OriginKind, + _require_weight_at_most: &Weight, + _call: &DoubleEncoded, + ) -> Weight { + XcmGeneric::::transact() + } + fn hrmp_new_channel_open_request( + _sender: &u32, + _max_message_size: &u32, + _max_capacity: &u32, + ) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn hrmp_channel_accepted(_recipient: &u32) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn hrmp_channel_closing(_initiator: &u32, _sender: &u32, _recipient: &u32) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn clear_origin() -> Weight { + XcmGeneric::::clear_origin() + } + fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + XcmGeneric::::descend_origin() + } + fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::report_error() + } + + fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::deposit_asset()) + } + fn deposit_reserve_asset( + assets: &MultiAssetFilter, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::deposit_reserve_asset()) + } + fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + // Kusama does not currently support exchange asset operations + Weight::MAX + } + fn initiate_reserve_withdraw( + assets: &MultiAssetFilter, + _reserve: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) + } + fn initiate_teleport( + assets: &MultiAssetFilter, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::initiate_teleport()) + } + fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + XcmGeneric::::report_holding() + } + fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + XcmGeneric::::buy_execution() + } + fn refund_surplus() -> Weight { + XcmGeneric::::refund_surplus() + } + fn set_error_handler(_xcm: &Xcm) -> Weight { + XcmGeneric::::set_error_handler() + } + fn set_appendix(_xcm: &Xcm) -> Weight { + XcmGeneric::::set_appendix() + } + fn clear_error() -> Weight { + XcmGeneric::::clear_error() + } + fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + XcmGeneric::::claim_asset() + } + fn trap(_code: &u64) -> Weight { + XcmGeneric::::trap() + } + fn subscribe_version(_query_id: &QueryId, _max_response_weight: &Weight) -> Weight { + XcmGeneric::::subscribe_version() + } + fn unsubscribe_version() -> Weight { + XcmGeneric::::unsubscribe_version() + } + fn burn_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + } + fn expect_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + } + fn expect_origin(_origin: &Option) -> Weight { + XcmGeneric::::expect_origin() + } + fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { + XcmGeneric::::expect_error() + } + fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight { + XcmGeneric::::expect_transact_status() + } + fn query_pallet(_module_name: &Vec, _response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::query_pallet() + } + fn expect_pallet( + _index: &u32, + _name: &Vec, + _module_name: &Vec, + _crate_major: &u32, + _min_crate_minor: &u32, + ) -> Weight { + XcmGeneric::::expect_pallet() + } + fn report_transact_status(_response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::report_transact_status() + } + fn clear_transact_status() -> Weight { + XcmGeneric::::clear_transact_status() + } + fn universal_origin(_: &Junction) -> Weight { + // Kusama does not currently support universal origin operations + Weight::MAX + } + fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { + // Kusama relay should not support export message operations + Weight::MAX + } + fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Kusama does not currently support asset locking operations + Weight::MAX + } + fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Kusama does not currently support asset locking operations + Weight::MAX + } + fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Kusama does not currently support asset locking operations + Weight::MAX + } + fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Kusama does not currently support asset locking operations + Weight::MAX + } + fn set_fees_mode(_: &bool) -> Weight { + XcmGeneric::::set_fees_mode() + } + fn set_topic(_topic: &[u8; 32]) -> Weight { + XcmGeneric::::set_topic() + } + fn clear_topic() -> Weight { + XcmGeneric::::clear_topic() + } + fn alias_origin(_: &MultiLocation) -> Weight { + // XCM Executor does not currently support alias origin operations + Weight::MAX + } + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + XcmGeneric::::unpaid_execution() + } +} + +#[test] +fn all_counted_has_a_sane_weight_upper_limit() { + let assets = MultiAssetFilter::Wild(AllCounted(4294967295)); + let weight = Weight::from_parts(1000, 1000); + + assert_eq!(assets.weigh_multi_assets(weight), weight * MAX_ASSETS); +} diff --git a/polkadot/runtime/kusama/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs b/polkadot/runtime/kusama/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs new file mode 100644 index 0000000000000000000000000000000000000000..07f3ccb48d9268275ef8d56d7240bddead0e9896 --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs @@ -0,0 +1,179 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm_benchmarks::fungible` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-gghbxkbs-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_xcm_benchmarks::fungible +// --chain=kusama-dev +// --header=./file_header.txt +// --template=./xcm/pallet-xcm-benchmarks/template.hbs +// --output=./runtime/kusama/src/weights/xcm/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm_benchmarks::fungible`. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn withdraw_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `3593` + // Minimum execution time: 23_950_000 picoseconds. + Weight::from_parts(24_720_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn transfer_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `6196` + // Minimum execution time: 51_687_000 picoseconds. + Weight::from_parts(52_490_000, 6196) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn transfer_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `177` + // Estimated: `6196` + // Minimum execution time: 75_438_000 picoseconds. + Weight::from_parts(77_495_000, 6196) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn reserve_asset_deposited() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_000_000_000_000 picoseconds. + Weight::from_parts(2_000_000_000_000, 0) + } + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn initiate_reserve_withdraw() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3541` + // Minimum execution time: 28_370_000 picoseconds. + Weight::from_parts(29_100_000, 3541) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn receive_teleported_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `3593` + // Minimum execution time: 23_041_000 picoseconds. + Weight::from_parts(23_433_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn deposit_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 25_386_000 picoseconds. + Weight::from_parts(25_904_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn deposit_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3593` + // Minimum execution time: 50_645_000 picoseconds. + Weight::from_parts(51_719_000, 3593) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn initiate_teleport() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3593` + // Minimum execution time: 53_055_000 picoseconds. + Weight::from_parts(54_214_000, 3593) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs new file mode 100644 index 0000000000000000000000000000000000000000..fb0ca3c19f425643f2532a0f5241688c6d84a69b --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -0,0 +1,341 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm_benchmarks::generic` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-02, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm3`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/var/lib/gitlab-runner/builds/zyw4fam_/0/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_xcm_benchmarks::generic +// --chain=kusama-dev +// --header=./file_header.txt +// --template=./xcm/pallet-xcm-benchmarks/template.hbs +// --output=./runtime/kusama/src/weights/xcm/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm_benchmarks::generic`. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn report_holding() -> Weight { + // Proof Size summary in bytes: + // Measured: `211` + // Estimated: `3676` + // Minimum execution time: 32_102_000 picoseconds. + Weight::from_parts(33_749_000, 3676) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + pub(crate) fn buy_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_624_000 picoseconds. + Weight::from_parts(2_714_000, 0) + } + /// Storage: XcmPallet Queries (r:1 w:0) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + pub(crate) fn query_response() -> Weight { + // Proof Size summary in bytes: + // Measured: `169` + // Estimated: `3634` + // Minimum execution time: 10_599_000 picoseconds. + Weight::from_parts(10_882_000, 3634) + .saturating_add(T::DbWeight::get().reads(1)) + } + pub(crate) fn transact() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 11_985_000 picoseconds. + Weight::from_parts(12_274_000, 0) + } + pub(crate) fn refund_surplus() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_739_000 picoseconds. + Weight::from_parts(2_862_000, 0) + } + pub(crate) fn set_error_handler() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_533_000 picoseconds. + Weight::from_parts(2_646_000, 0) + } + pub(crate) fn set_appendix() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_563_000 picoseconds. + Weight::from_parts(2_647_000, 0) + } + pub(crate) fn clear_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_512_000 picoseconds. + Weight::from_parts(2_574_000, 0) + } + pub(crate) fn descend_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_307_000 picoseconds. + Weight::from_parts(3_448_000, 0) + } + pub(crate) fn clear_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_524_000 picoseconds. + Weight::from_parts(2_614_000, 0) + } + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn report_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `211` + // Estimated: `3676` + // Minimum execution time: 27_275_000 picoseconds. + Weight::from_parts(27_861_000, 3676) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: XcmPallet AssetTraps (r:1 w:1) + /// Proof Skipped: XcmPallet AssetTraps (max_values: None, max_size: None, mode: Measured) + pub(crate) fn claim_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `226` + // Estimated: `3691` + // Minimum execution time: 14_731_000 picoseconds. + Weight::from_parts(15_006_000, 3691) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub(crate) fn trap() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_446_000 picoseconds. + Weight::from_parts(2_581_000, 0) + } + /// Storage: XcmPallet VersionNotifyTargets (r:1 w:1) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn subscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `211` + // Estimated: `3676` + // Minimum execution time: 34_319_000 picoseconds. + Weight::from_parts(34_708_000, 3676) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:0 w:1) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + pub(crate) fn unsubscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_974_000 picoseconds. + Weight::from_parts(5_155_000, 0) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub(crate) fn burn_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_059_000 picoseconds. + Weight::from_parts(4_125_000, 0) + } + pub(crate) fn expect_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_657_000 picoseconds. + Weight::from_parts(2_741_000, 0) + } + pub(crate) fn expect_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_585_000 picoseconds. + Weight::from_parts(2_653_000, 0) + } + pub(crate) fn expect_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_552_000 picoseconds. + Weight::from_parts(2_632_000, 0) + } + pub(crate) fn expect_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_682_000 picoseconds. + Weight::from_parts(2_763_000, 0) + } + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn query_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `211` + // Estimated: `3676` + // Minimum execution time: 34_316_000 picoseconds. + Weight::from_parts(34_682_000, 3676) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + pub(crate) fn expect_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_938_000 picoseconds. + Weight::from_parts(8_071_000, 0) + } + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn report_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `211` + // Estimated: `3676` + // Minimum execution time: 28_002_000 picoseconds. + Weight::from_parts(28_184_000, 3676) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + pub(crate) fn clear_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_520_000 picoseconds. + Weight::from_parts(2_617_000, 0) + } + pub(crate) fn set_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_506_000 picoseconds. + Weight::from_parts(2_560_000, 0) + } + pub(crate) fn clear_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_503_000 picoseconds. + Weight::from_parts(2_605_000, 0) + } + pub(crate) fn set_fees_mode() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_511_000 picoseconds. + Weight::from_parts(2_597_000, 0) + } + pub(crate) fn unpaid_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_617_000 picoseconds. + Weight::from_parts(2_715_000, 0) + } +} diff --git a/polkadot/runtime/kusama/src/xcm_config.rs b/polkadot/runtime/kusama/src/xcm_config.rs new file mode 100644 index 0000000000000000000000000000000000000000..c90e6c55a94b42d9e3c1273dbfbc8a7ae105bb89 --- /dev/null +++ b/polkadot/runtime/kusama/src/xcm_config.rs @@ -0,0 +1,465 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! XCM configurations for the Kusama runtime. + +use super::{ + parachains_origin, AccountId, AllPalletsWithSystem, Balances, Dmp, Fellows, ParaId, Runtime, + RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, TransactionByteFee, WeightToFee, + XcmPallet, +}; +use frame_support::{ + match_types, parameter_types, + traits::{Contains, Everything, Nothing}, + weights::Weight, +}; +use frame_system::EnsureRoot; +use kusama_runtime_constants::currency::CENTS; +use runtime_common::{ + crowdloan, paras_registrar, + xcm_sender::{ChildParachainRouter, ExponentialPrice}, + ToAuthor, +}; +use sp_core::ConstU32; +use xcm::latest::prelude::*; +use xcm_builder::{ + AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, + AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative, + ChildParachainConvertsVia, ChildSystemParachainAsSuperuser, + CurrencyAdapter as XcmCurrencyAdapter, IsChildSystemParachain, IsConcrete, MintLocation, + OriginToPluralityVoice, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, + WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, +}; +use xcm_executor::traits::WithOriginFilter; + +parameter_types! { + /// The location of the KSM token, from the context of this chain. Since this token is native to this + /// chain, we make it synonymous with it and thus it is the `Here` location, which means "equivalent to + /// the context". + pub const TokenLocation: MultiLocation = Here.into_location(); + /// The Kusama network ID. This is named. + pub const ThisNetwork: NetworkId = Kusama; + /// Our XCM location ancestry - i.e. our location within the Consensus Universe. + /// + /// Since Kusama is a top-level relay-chain with its own consensus, it's just our network ID. + pub UniversalLocation: InteriorMultiLocation = ThisNetwork::get().into(); + /// The check account, which holds any native assets that have been teleported out and not back in (yet). + pub CheckAccount: AccountId = XcmPallet::check_account(); + /// The check account that is allowed to mint assets locally. + pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); +} + +/// The canonical means of converting a `MultiLocation` into an `AccountId`, used when we want to +/// determine the sovereign account controlled by a location. +pub type SovereignAccountOf = ( + // We can convert a child parachain using the standard `AccountId` conversion. + ChildParachainConvertsVia, + // We can directly alias an `AccountId32` into a local account. + AccountId32Aliases, +); + +/// Our asset transactor. This is what allows us to interest with the runtime facilities from the +/// point of view of XCM-only concepts like `MultiLocation` and `MultiAsset`. +/// +/// Ours is only aware of the Balances pallet, which is mapped to `TokenLocation`. +pub type LocalAssetTransactor = XcmCurrencyAdapter< + // Use this currency: + Balances, + // Use this currency when it is a fungible asset matching the given location or name: + IsConcrete, + // We can convert the MultiLocations with our converter above: + SovereignAccountOf, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We track our teleports in/out to keep total issuance correct. + LocalCheckAccount, +>; + +/// The means that we convert the XCM message origin location into a local dispatch origin. +type LocalOriginConverter = ( + // A `Signed` origin of the sovereign account that the original location controls. + SovereignSignedViaLocation, + // A child parachain, natively expressed, has the `Parachain` origin. + ChildParachainAsNative, + // The AccountId32 location type can be expressed natively as a `Signed` origin. + SignedAccountId32AsNative, + // A system child parachain, expressed as a Superuser, converts to the `Root` origin. + ChildSystemParachainAsSuperuser, +); + +parameter_types! { + /// The amount of weight an XCM operation takes. This is a safe overestimate. + pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); + /// Maximum number of instructions in a single XCM fragment. A sanity check against weight + /// calculations getting too crazy. + pub const MaxInstructions: u32 = 100; + /// The asset ID for the asset that we use to pay for message delivery fees. + pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); + /// The base fee for the message delivery fees. + pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); +} + +/// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our +/// individual routers. +pub type XcmRouter = WithUniqueTopic<( + // Only one router so far - use DMP to communicate with child parachains. + ChildParachainRouter< + Runtime, + XcmPallet, + ExponentialPrice, + >, +)>; + +parameter_types! { + pub const Ksm: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); + pub const Statemine: MultiLocation = Parachain(1000).into_location(); + pub const Encointer: MultiLocation = Parachain(1001).into_location(); + pub const KsmForStatemine: (MultiAssetFilter, MultiLocation) = (Ksm::get(), Statemine::get()); + pub const KsmForEncointer: (MultiAssetFilter, MultiLocation) = (Ksm::get(), Encointer::get()); + pub const MaxAssetsIntoHolding: u32 = 64; +} +pub type TrustedTeleporters = + (xcm_builder::Case, xcm_builder::Case); + +match_types! { + pub type OnlyParachains: impl Contains = { + MultiLocation { parents: 0, interior: X1(Parachain(_)) } + }; +} + +/// The barriers one of which must be passed for an XCM message to be executed. +pub type Barrier = TrailingSetTopicAsId<( + // Weight that is paid for may be consumed. + TakeWeightCredit, + // Expected responses are OK. + AllowKnownQueryResponses, + WithComputedOrigin< + ( + // If the message is one that immediately attempts to pay for execution, then allow it. + AllowTopLevelPaidExecutionFrom, + // Messages coming from system parachains need not pay for execution. + AllowExplicitUnpaidExecutionFrom>, + // Subscriptions for version tracking are OK. + AllowSubscriptionsFrom, + ), + UniversalLocation, + ConstU32<8>, + >, +)>; + +/// A call filter for the XCM Transact instruction. This is a temporary measure until we properly +/// account for proof size weights. +/// +/// Calls that are allowed through this filter must: +/// 1. Have a fixed weight; +/// 2. Cannot lead to another call being made; +/// 3. Have a defined proof size weight, e.g. no unbounded vecs in call parameters. +pub struct SafeCallFilter; +impl Contains for SafeCallFilter { + fn contains(call: &RuntimeCall) -> bool { + #[cfg(feature = "runtime-benchmarks")] + { + if matches!(call, RuntimeCall::System(frame_system::Call::remark_with_event { .. })) { + return true + } + } + + match call { + RuntimeCall::System( + frame_system::Call::kill_prefix { .. } | frame_system::Call::set_heap_pages { .. }, + ) | + RuntimeCall::Babe(..) | + RuntimeCall::Timestamp(..) | + RuntimeCall::Indices(..) | + RuntimeCall::Balances(..) | + RuntimeCall::Crowdloan( + crowdloan::Call::create { .. } | + crowdloan::Call::contribute { .. } | + crowdloan::Call::withdraw { .. } | + crowdloan::Call::refund { .. } | + crowdloan::Call::dissolve { .. } | + crowdloan::Call::edit { .. } | + crowdloan::Call::poke { .. } | + crowdloan::Call::contribute_all { .. }, + ) | + RuntimeCall::Staking( + pallet_staking::Call::bond { .. } | + pallet_staking::Call::bond_extra { .. } | + pallet_staking::Call::unbond { .. } | + pallet_staking::Call::withdraw_unbonded { .. } | + pallet_staking::Call::validate { .. } | + pallet_staking::Call::nominate { .. } | + pallet_staking::Call::chill { .. } | + pallet_staking::Call::set_payee { .. } | + pallet_staking::Call::set_controller { .. } | + pallet_staking::Call::set_validator_count { .. } | + pallet_staking::Call::increase_validator_count { .. } | + pallet_staking::Call::scale_validator_count { .. } | + pallet_staking::Call::force_no_eras { .. } | + pallet_staking::Call::force_new_era { .. } | + pallet_staking::Call::set_invulnerables { .. } | + pallet_staking::Call::force_unstake { .. } | + pallet_staking::Call::force_new_era_always { .. } | + pallet_staking::Call::payout_stakers { .. } | + pallet_staking::Call::rebond { .. } | + pallet_staking::Call::reap_stash { .. } | + pallet_staking::Call::set_staking_configs { .. } | + pallet_staking::Call::chill_other { .. } | + pallet_staking::Call::force_apply_min_commission { .. }, + ) | + RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) | + RuntimeCall::Grandpa(..) | + RuntimeCall::ImOnline(..) | + RuntimeCall::Treasury(..) | + RuntimeCall::ConvictionVoting(..) | + RuntimeCall::Referenda( + pallet_referenda::Call::place_decision_deposit { .. } | + pallet_referenda::Call::refund_decision_deposit { .. } | + pallet_referenda::Call::cancel { .. } | + pallet_referenda::Call::kill { .. } | + pallet_referenda::Call::nudge_referendum { .. } | + pallet_referenda::Call::one_fewer_deciding { .. }, + ) | + RuntimeCall::FellowshipCollective(..) | + RuntimeCall::FellowshipReferenda( + pallet_referenda::Call::place_decision_deposit { .. } | + pallet_referenda::Call::refund_decision_deposit { .. } | + pallet_referenda::Call::cancel { .. } | + pallet_referenda::Call::kill { .. } | + pallet_referenda::Call::nudge_referendum { .. } | + pallet_referenda::Call::one_fewer_deciding { .. }, + ) | + RuntimeCall::Claims( + super::claims::Call::claim { .. } | + super::claims::Call::mint_claim { .. } | + super::claims::Call::move_claim { .. }, + ) | + RuntimeCall::Utility(pallet_utility::Call::as_derivative { .. }) | + RuntimeCall::Identity( + pallet_identity::Call::add_registrar { .. } | + pallet_identity::Call::set_identity { .. } | + pallet_identity::Call::clear_identity { .. } | + pallet_identity::Call::request_judgement { .. } | + pallet_identity::Call::cancel_request { .. } | + pallet_identity::Call::set_fee { .. } | + pallet_identity::Call::set_account_id { .. } | + pallet_identity::Call::set_fields { .. } | + pallet_identity::Call::provide_judgement { .. } | + pallet_identity::Call::kill_identity { .. } | + pallet_identity::Call::add_sub { .. } | + pallet_identity::Call::rename_sub { .. } | + pallet_identity::Call::remove_sub { .. } | + pallet_identity::Call::quit_sub { .. }, + ) | + RuntimeCall::Society(..) | + RuntimeCall::Recovery(..) | + RuntimeCall::Vesting(..) | + RuntimeCall::Bounties( + pallet_bounties::Call::propose_bounty { .. } | + pallet_bounties::Call::approve_bounty { .. } | + pallet_bounties::Call::propose_curator { .. } | + pallet_bounties::Call::unassign_curator { .. } | + pallet_bounties::Call::accept_curator { .. } | + pallet_bounties::Call::award_bounty { .. } | + pallet_bounties::Call::claim_bounty { .. } | + pallet_bounties::Call::close_bounty { .. }, + ) | + RuntimeCall::ChildBounties(..) | + RuntimeCall::ElectionProviderMultiPhase(..) | + RuntimeCall::VoterList(..) | + RuntimeCall::NominationPools( + pallet_nomination_pools::Call::join { .. } | + pallet_nomination_pools::Call::bond_extra { .. } | + pallet_nomination_pools::Call::claim_payout { .. } | + pallet_nomination_pools::Call::unbond { .. } | + pallet_nomination_pools::Call::pool_withdraw_unbonded { .. } | + pallet_nomination_pools::Call::withdraw_unbonded { .. } | + pallet_nomination_pools::Call::create { .. } | + pallet_nomination_pools::Call::create_with_pool_id { .. } | + pallet_nomination_pools::Call::set_state { .. } | + pallet_nomination_pools::Call::set_configs { .. } | + pallet_nomination_pools::Call::update_roles { .. } | + pallet_nomination_pools::Call::chill { .. }, + ) | + RuntimeCall::Hrmp(..) | + RuntimeCall::Registrar( + paras_registrar::Call::deregister { .. } | + paras_registrar::Call::swap { .. } | + paras_registrar::Call::remove_lock { .. } | + paras_registrar::Call::reserve { .. } | + paras_registrar::Call::add_lock { .. }, + ) | + RuntimeCall::XcmPallet(pallet_xcm::Call::limited_reserve_transfer_assets { + .. + }) | + RuntimeCall::Whitelist(pallet_whitelist::Call::whitelist_call { .. }) | + RuntimeCall::Proxy(..) => true, + _ => false, + } + } +} + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = LocalOriginConverter; + type IsReserve = (); + type IsTeleporter = TrustedTeleporters; + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = WeightInfoBounds< + crate::weights::xcm::KusamaXcmWeight, + RuntimeCall, + MaxInstructions, + >; + // The weight trader piggybacks on the existing transaction-fee conversion logic. + type Trader = + UsingComponents>; + type ResponseHandler = XcmPallet; + type AssetTrap = XcmPallet; + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = XcmPallet; + type SubscriptionService = XcmPallet; + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + // No bridges yet... + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = WithOriginFilter; + type SafeCallFilter = SafeCallFilter; + type Aliasers = Nothing; +} + +parameter_types! { + // StakingAdmin pluralistic body. + pub const StakingAdminBodyId: BodyId = BodyId::Defense; + // Fellows pluralistic body. + pub const FellowsBodyId: BodyId = BodyId::Technical; +} + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parachain(1000).into()); +} + +/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior +/// location of this chain. +pub type LocalOriginToLocation = ( + // And a usual Signed origin to be used in XCM as a corresponding AccountId32 + SignedToAccountId32, +); + +/// Type to convert the `StakingAdmin` origin to a Plurality `MultiLocation` value. +pub type StakingAdminToPlurality = + OriginToPluralityVoice; + +/// Type to convert the Fellows origin to a Plurality `MultiLocation` value. +pub type FellowsToPlurality = OriginToPluralityVoice; + +/// Type to convert a pallet `Origin` type value into a `MultiLocation` value which represents an +/// interior location of this chain for a destination chain. +pub type LocalPalletOriginToLocation = ( + // StakingAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + StakingAdminToPlurality, + // Fellows origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + FellowsToPlurality, +); + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + // We only allow the root, fellows and the staking admin to send messages. + // This is basically safe to enable for everyone (safe the possibility of someone spamming the + // parachain if they're willing to pay the KSM to send from the Relay-chain), but it's useless + // until we bring in XCM v3 which will make `DescendOrigin` a bit more useful. + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = XcmRouter; + // Anyone can execute XCM messages locally. + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = xcm_executor::XcmExecutor; + // Anyone is able to use teleportation regardless of who they are and what they want to + // teleport. + type XcmTeleportFilter = Everything; + // Anyone is able to use reserve transfers regardless of who they are and what they want to + // transfer. + type XcmReserveTransferFilter = Everything; + type Weigher = WeightInfoBounds< + crate::weights::xcm::KusamaXcmWeight, + RuntimeCall, + MaxInstructions, + >; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = (); + type TrustedLockers = (); + type SovereignAccountOf = SovereignAccountOf; + type MaxLockers = ConstU32<8>; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = crate::weights::pallet_xcm::WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} + +#[test] +fn karura_liquid_staking_xcm_has_sane_weight_upper_limt() { + use frame_support::dispatch::GetDispatchInfo; + use parity_scale_codec::Decode; + use xcm::VersionedXcm; + use xcm_executor::traits::WeightBounds; + + // should be [WithdrawAsset, BuyExecution, Transact, RefundSurplus, DepositAsset] + let blob = hex_literal::hex!("02140004000000000700e40b540213000000000700e40b54020006010700c817a804341801000006010b00c490bf4302140d010003ffffffff000100411f"); + let Ok(VersionedXcm::V2(old_xcm)) = VersionedXcm::::decode(&mut &blob[..]) + else { + panic!("can't decode XCM blob") + }; + let mut xcm: Xcm = + old_xcm.try_into().expect("conversion from v2 to v3 failed"); + let weight = ::Weigher::weight(&mut xcm) + .expect("weighing XCM failed"); + + // Test that the weigher gives us a sensible weight but don't exactly hard-code it, otherwise it + // will be out of date after each re-run. + assert!(weight.all_lte(Weight::from_parts(30_313_281_000, 72_722))); + + let Some(Transact { require_weight_at_most, call, .. }) = + xcm.inner_mut().into_iter().find(|inst| matches!(inst, Transact { .. })) + else { + panic!("no Transact instruction found") + }; + // should be pallet_utility.as_derivative { index: 0, call: pallet_staking::bond_extra { + // max_additional: 2490000000000 } } + let message_call = call.take_decoded().expect("can't decode Transact call"); + let call_weight = message_call.get_dispatch_info().weight; + // Ensure that the Transact instruction is giving a sensible `require_weight_at_most` value + assert!( + call_weight.all_lte(*require_weight_at_most), + "call weight ({:?}) was not less than or equal to require_weight_at_most ({:?})", + call_weight, + require_weight_at_most + ); +} diff --git a/polkadot/runtime/metrics/Cargo.toml b/polkadot/runtime/metrics/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7bbf8d066f05c4a050afc0965d106f50edf62870 --- /dev/null +++ b/polkadot/runtime/metrics/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "polkadot-runtime-metrics" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false} +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +parity-scale-codec = { version = "3.6.1", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } + +bs58 = { version = "0.4.0", default-features = false, features = ["alloc"] } + +[features] +default = ["std"] +std = [ + "sp-std/std", + "sp-tracing/std", + "parity-scale-codec/std", + "primitives/std", + "bs58/std" +] +runtime-metrics = ["sp-tracing/with-tracing", "frame-benchmarking"] diff --git a/polkadot/runtime/metrics/src/lib.rs b/polkadot/runtime/metrics/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..6164d71f112a47bce0a91da044aa8d9166c8a8b7 --- /dev/null +++ b/polkadot/runtime/metrics/src/lib.rs @@ -0,0 +1,33 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Runtime metric interface similar to native Prometheus metrics. +//! +//! This is intended to be used only for testing and debugging and **must never +//! be used in production**. It requires the Substrate wasm tracing support +//! and command line configuration: `--tracing-targets wasm_tracing=trace`. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "runtime-metrics")] +mod with_runtime_metrics; +#[cfg(feature = "runtime-metrics")] +pub use crate::with_runtime_metrics::*; + +#[cfg(not(feature = "runtime-metrics"))] +mod without_runtime_metrics; +#[cfg(not(feature = "runtime-metrics"))] +pub use crate::without_runtime_metrics::*; diff --git a/polkadot/runtime/metrics/src/with_runtime_metrics.rs b/polkadot/runtime/metrics/src/with_runtime_metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..562aa9ca162b55da49e7f384aa5470906fe8a7da --- /dev/null +++ b/polkadot/runtime/metrics/src/with_runtime_metrics.rs @@ -0,0 +1,147 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This module provides an implementation for the runtime metrics types: `Counter`, +//! `CounterVec` and `Histogram`. These types expose a Prometheus like interface and +//! same functionality. Each instance of a runtime metric is mapped to a Prometheus +//! metric on the client side. The runtime metrics must be registered with the registry +//! in the client, otherwise they will not be published. + +const TRACING_TARGET: &'static str = "metrics"; + +use parity_scale_codec::Encode; +use primitives::{ + metric_definitions::{CounterDefinition, CounterVecDefinition, HistogramDefinition}, + RuntimeMetricLabelValues, RuntimeMetricOp, RuntimeMetricUpdate, +}; + +use sp_std::prelude::*; + +/// Holds a set of counters that have different values for their labels, +/// like Prometheus `CounterVec`. +pub struct CounterVec { + name: &'static str, +} + +/// A counter metric. +pub struct Counter { + name: &'static str, +} + +pub struct Histogram { + name: &'static str, +} + +/// Convenience trait implemented for all metric types. +trait MetricEmitter { + fn emit(metric_op: &RuntimeMetricUpdate) { + sp_tracing::event!( + target: TRACING_TARGET, + sp_tracing::Level::TRACE, + update_op = bs58::encode(&metric_op.encode()).into_string().as_str() + ); + } +} + +/// +pub struct LabeledMetric { + name: &'static str, + label_values: RuntimeMetricLabelValues, +} + +impl LabeledMetric { + /// Increment the counter by `value`. + pub fn inc_by(&self, value: u64) { + let metric_update = RuntimeMetricUpdate { + metric_name: Vec::from(self.name), + op: RuntimeMetricOp::IncrementCounterVec(value, self.label_values.clone()), + }; + + Self::emit(&metric_update); + } + + /// Increment the counter value. + pub fn inc(&self) { + self.inc_by(1); + } +} + +impl MetricEmitter for LabeledMetric {} +impl MetricEmitter for Counter {} +impl MetricEmitter for Histogram {} + +impl CounterVec { + /// Create a new counter as specified by `definition`. This metric needs to be registered + /// in the client before it can be used. + pub const fn new(definition: CounterVecDefinition) -> Self { + // No register op is emitted since the metric is supposed to be registered + // on the client by the time `inc()` is called. + CounterVec { name: definition.name } + } + + /// Returns a `LabeledMetric` instance that provides an interface for incrementing + /// the metric. + pub fn with_label_values(&self, label_values: &[&'static str]) -> LabeledMetric { + LabeledMetric { name: self.name, label_values: label_values.into() } + } +} + +impl Counter { + /// Create a new counter as specified by `definition`. This metric needs to be registered + /// in the client before it can be used. + pub const fn new(definition: CounterDefinition) -> Self { + Counter { name: definition.name } + } + + /// Increment counter by `value`. + pub fn inc_by(&self, value: u64) { + let metric_update = RuntimeMetricUpdate { + metric_name: Vec::from(self.name), + op: RuntimeMetricOp::IncrementCounter(value), + }; + + Self::emit(&metric_update); + } + + /// Increment counter. + pub fn inc(&self) { + self.inc_by(1); + } +} + +impl Histogram { + /// Create a new histogram as specified by `definition`. This metric needs to be registered + /// in the client before it can be used. + pub const fn new(definition: HistogramDefinition) -> Self { + // No register op is emitted since the metric is supposed to be registered + // on the client by the time `inc()` is called. + Histogram { name: definition.name } + } + + // Observe a value in the histogram + pub fn observe(&self, value: u128) { + let metric_update = RuntimeMetricUpdate { + metric_name: Vec::from(self.name), + op: RuntimeMetricOp::ObserveHistogram(value), + }; + Self::emit(&metric_update); + } +} + +/// Returns current time in ns +pub fn get_current_time() -> u128 { + frame_benchmarking::benchmarking::current_time() +} diff --git a/polkadot/runtime/metrics/src/without_runtime_metrics.rs b/polkadot/runtime/metrics/src/without_runtime_metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..41d9c24635ae49e544f5fe1eaf18bc740d8a30c9 --- /dev/null +++ b/polkadot/runtime/metrics/src/without_runtime_metrics.rs @@ -0,0 +1,76 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Runtime metrics are usable from the wasm runtime only. The purpose of this module is to +//! provide a dummy implementation for the native runtime to avoid cluttering the runtime code +//! with `#[cfg(feature = "runtime-metrics")]`. + +use primitives::metric_definitions::{ + CounterDefinition, CounterVecDefinition, HistogramDefinition, +}; + +/// A dummy `Counter`. +pub struct Counter; +/// A dummy `CounterVec`. +pub struct CounterVec; + +/// A dummy `Histogram` +pub struct Histogram; + +/// Dummy implementation. +impl CounterVec { + /// Constructor. + pub const fn new(_definition: CounterVecDefinition) -> Self { + CounterVec + } + /// Sets label values, implementation is a `no op`. + pub fn with_label_values(&self, _label_values: &[&'static str]) -> &Self { + self + } + /// Increment counter by value, implementation is a `no op`. + pub fn inc_by(&self, _: u64) {} + /// Increment counter, implementation is a `no op`. + pub fn inc(&self) {} +} + +/// Dummy implementation. +impl Counter { + /// Constructor. + pub const fn new(_definition: CounterDefinition) -> Self { + Counter + } + /// Increment counter by value, implementation is a `no op`. + pub fn inc_by(&self, _: u64) {} + /// Increment counter, implementation is a `no op`. + pub fn inc(&self) {} +} + +/// Dummy implementation +impl Histogram { + /// Create a new histogram as specified by `definition`. This metric needs to be registered + /// in the client before it can be used. + pub const fn new(_definition: HistogramDefinition) -> Self { + Histogram + } + + // Observe a value in the histogram + pub fn observe(&self, _value: u128) {} +} + +/// Dummy implementation - always 0 +pub fn get_current_time() -> u128 { + 0 +} diff --git a/polkadot/runtime/parachains/Cargo.toml b/polkadot/runtime/parachains/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..c3acdd781ea290784d13fc828285a7e2d7deca8e --- /dev/null +++ b/polkadot/runtime/parachains/Cargo.toml @@ -0,0 +1,126 @@ +[package] +name = "polkadot-runtime-parachains" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } +log = { version = "0.4.17", default-features = false } +rustc-hex = { version = "2.1.0", default-features = false } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.163", default-features = false, features = ["derive", "alloc"] } +derive_more = "0.99.17" +bitflags = "1.3.2" + +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features=["serde"] } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features=["serde"] } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features=["serde"] } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } + +pallet-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-message-queue = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +xcm = { package = "xcm", path = "../../xcm", default-features = false } +xcm-executor = { package = "xcm-executor", path = "../../xcm/xcm-executor", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } + +rand = { version = "0.8.5", default-features = false } +rand_chacha = { version = "0.3.1", default-features = false } +static_assertions = { version = "1.1.0", optional = true } +polkadot-parachain = { path = "../../parachain", default-features = false } +polkadot-runtime-metrics = { path = "../metrics", default-features = false} + +[dev-dependencies] +futures = "0.3.21" +hex-literal = "0.4.1" +keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "master" } +frame-support-test = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../primitives/test-helpers"} +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +thousands = "0.2.0" +assert_matches = "1" +serde_json = "1.0.96" + +[features] +default = ["std"] +no_std = [] +std = [ + "bitvec/std", + "parity-scale-codec/std", + "rustc-hex/std", + "scale-info/std", + "serde/std", + "primitives/std", + "inherents/std", + "sp-core/std", + "sp-api/std", + "sp-keystore", + "sp-std/std", + "sp-io/std", + "frame-support/std", + "sp-runtime/std", + "sp-session/std", + "sp-staking/std", + "pallet-authority-discovery/std", + "pallet-authorship/std", + "pallet-babe/std", + "pallet-balances/std", + "pallet-message-queue/std", + "pallet-session/std", + "pallet-staking/std", + "pallet-timestamp/std", + "pallet-vesting/std", + "frame-system/std", + "xcm/std", + "xcm-executor/std", + "log/std", + "polkadot-runtime-metrics/std", +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-babe/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "pallet-staking/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-vesting/runtime-benchmarks", + "primitives/runtime-benchmarks", + "static_assertions", + "sp-application-crypto", +] +try-runtime = [ + "frame-support/try-runtime", + "pallet-authority-discovery/try-runtime", + "pallet-authorship/try-runtime", + "pallet-babe/try-runtime", + "pallet-balances/try-runtime", + "pallet-message-queue/try-runtime", + "pallet-session/try-runtime", + "pallet-staking/try-runtime", + "pallet-timestamp/try-runtime", + "pallet-vesting/try-runtime", +] +runtime-metrics = ["sp-tracing/with-tracing", "polkadot-runtime-metrics/runtime-metrics"] diff --git a/polkadot/runtime/parachains/src/assigner.rs b/polkadot/runtime/parachains/src/assigner.rs new file mode 100644 index 0000000000000000000000000000000000000000..55434da11f307cd2a7af86f6d81d29460df6678f --- /dev/null +++ b/polkadot/runtime/parachains/src/assigner.rs @@ -0,0 +1,111 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Polkadot multiplexing assignment provider. +//! Provides blockspace assignments for both bulk and on demand parachains. +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::{v5::Assignment, CoreIndex, Id as ParaId}; + +use crate::{ + configuration, paras, + scheduler::common::{AssignmentProvider, AssignmentProviderConfig}, +}; + +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + configuration::Config + paras::Config { + type ParachainsAssignmentProvider: AssignmentProvider>; + type OnDemandAssignmentProvider: AssignmentProvider>; + } +} + +// Aliases to make the impl more readable. +type ParachainAssigner = ::ParachainsAssignmentProvider; +type OnDemandAssigner = ::OnDemandAssignmentProvider; + +impl Pallet { + // Helper fn for the AssignmentProvider implementation. + // Assumes that the first allocation of cores is to bulk parachains. + // This function will return false if there are no cores assigned to the bulk parachain + // assigner. + fn is_bulk_core(core_idx: &CoreIndex) -> bool { + let parachain_cores = + as AssignmentProvider>>::session_core_count(); + (0..parachain_cores).contains(&core_idx.0) + } +} + +impl AssignmentProvider> for Pallet { + fn session_core_count() -> u32 { + let parachain_cores = + as AssignmentProvider>>::session_core_count(); + let on_demand_cores = + as AssignmentProvider>>::session_core_count(); + + parachain_cores.saturating_add(on_demand_cores) + } + + /// Pops an `Assignment` from a specified `CoreIndex` + fn pop_assignment_for_core( + core_idx: CoreIndex, + concluded_para: Option, + ) -> Option { + if Pallet::::is_bulk_core(&core_idx) { + as AssignmentProvider>>::pop_assignment_for_core( + core_idx, + concluded_para, + ) + } else { + as AssignmentProvider>>::pop_assignment_for_core( + core_idx, + concluded_para, + ) + } + } + + fn push_assignment_for_core(core_idx: CoreIndex, assignment: Assignment) { + if Pallet::::is_bulk_core(&core_idx) { + as AssignmentProvider>>::push_assignment_for_core( + core_idx, assignment, + ) + } else { + as AssignmentProvider>>::push_assignment_for_core( + core_idx, assignment, + ) + } + } + + fn get_provider_config(core_idx: CoreIndex) -> AssignmentProviderConfig> { + if Pallet::::is_bulk_core(&core_idx) { + as AssignmentProvider>>::get_provider_config( + core_idx, + ) + } else { + as AssignmentProvider>>::get_provider_config( + core_idx, + ) + } + } +} diff --git a/polkadot/runtime/parachains/src/assigner_on_demand/benchmarking.rs b/polkadot/runtime/parachains/src/assigner_on_demand/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..42ca94d5185fc99c10930d9a242f53dfe25a4cdb --- /dev/null +++ b/polkadot/runtime/parachains/src/assigner_on_demand/benchmarking.rs @@ -0,0 +1,109 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! On demand assigner pallet benchmarking. + +#![cfg(feature = "runtime-benchmarks")] + +use super::{Pallet, *}; +use crate::{ + configuration::{HostConfiguration, Pallet as ConfigurationPallet}, + paras::{Pallet as ParasPallet, ParaGenesisArgs, ParaKind, ParachainsCache}, + shared::Pallet as ParasShared, +}; + +use frame_benchmarking::v2::*; +use frame_system::RawOrigin; +use sp_runtime::traits::Bounded; + +use primitives::{ + HeadData, Id as ParaId, SessionIndex, ValidationCode, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, +}; + +// Constants for the benchmarking +const SESSION_INDEX: SessionIndex = 1; + +// Initialize a parathread for benchmarking. +pub fn init_parathread(para_id: ParaId) +where + T: Config + crate::paras::Config + crate::shared::Config, +{ + ParasShared::::set_session_index(SESSION_INDEX); + let mut config = HostConfiguration::default(); + config.on_demand_cores = 1; + ConfigurationPallet::::force_set_active_config(config); + let mut parachains = ParachainsCache::new(); + ParasPallet::::initialize_para_now( + &mut parachains, + para_id, + &ParaGenesisArgs { + para_kind: ParaKind::Parathread, + genesis_head: HeadData(vec![1, 2, 3, 4]), + validation_code: ValidationCode(vec![1, 2, 3, 4]), + }, + ); +} + +#[benchmarks] +mod benchmarks { + /// We want to fill the queue to the maximum, so exactly one more item fits. + const MAX_FILL_BENCH: u32 = ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE.saturating_sub(1); + + use super::*; + #[benchmark] + fn place_order_keep_alive(s: Linear<1, MAX_FILL_BENCH>) { + // Setup + let caller = whitelisted_caller(); + let para_id = ParaId::from(111u32); + init_parathread::(para_id); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + let assignment = Assignment::new(para_id); + + for _ in 0..s { + Pallet::::add_on_demand_assignment(assignment.clone(), QueuePushDirection::Back) + .unwrap(); + } + + #[extrinsic_call] + _(RawOrigin::Signed(caller.into()), BalanceOf::::max_value(), para_id) + } + + #[benchmark] + fn place_order_allow_death(s: Linear<1, MAX_FILL_BENCH>) { + // Setup + let caller = whitelisted_caller(); + let para_id = ParaId::from(111u32); + init_parathread::(para_id); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + let assignment = Assignment::new(para_id); + + for _ in 0..s { + Pallet::::add_on_demand_assignment(assignment.clone(), QueuePushDirection::Back) + .unwrap(); + } + + #[extrinsic_call] + _(RawOrigin::Signed(caller.into()), BalanceOf::::max_value(), para_id) + } + + impl_benchmark_test_suite!( + Pallet, + crate::mock::new_test_ext( + crate::assigner_on_demand::mock_helpers::GenesisConfigBuilder::default().build() + ), + crate::mock::Test + ); +} diff --git a/polkadot/runtime/parachains/src/assigner_on_demand/mock_helpers.rs b/polkadot/runtime/parachains/src/assigner_on_demand/mock_helpers.rs new file mode 100644 index 0000000000000000000000000000000000000000..acfb24cbf1943e9cc40e67338b448814c3ab7adf --- /dev/null +++ b/polkadot/runtime/parachains/src/assigner_on_demand/mock_helpers.rs @@ -0,0 +1,86 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Helper functions for tests, also used in runtime-benchmarks. + +#![cfg(test)] + +use super::*; + +use crate::{ + mock::MockGenesisConfig, + paras::{ParaGenesisArgs, ParaKind}, +}; + +use primitives::{Balance, HeadData, ValidationCode}; + +pub fn default_genesis_config() -> MockGenesisConfig { + MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: crate::configuration::HostConfiguration { ..Default::default() }, + }, + ..Default::default() + } +} + +#[derive(Debug)] +pub struct GenesisConfigBuilder { + pub on_demand_cores: u32, + pub on_demand_base_fee: Balance, + pub on_demand_fee_variability: Perbill, + pub on_demand_max_queue_size: u32, + pub on_demand_target_queue_utilization: Perbill, + pub onboarded_on_demand_chains: Vec, +} + +impl Default for GenesisConfigBuilder { + fn default() -> Self { + Self { + on_demand_cores: 10, + on_demand_base_fee: 10_000, + on_demand_fee_variability: Perbill::from_percent(1), + on_demand_max_queue_size: 100, + on_demand_target_queue_utilization: Perbill::from_percent(25), + onboarded_on_demand_chains: vec![], + } + } +} + +impl GenesisConfigBuilder { + pub(super) fn build(self) -> MockGenesisConfig { + let mut genesis = default_genesis_config(); + let config = &mut genesis.configuration.config; + config.on_demand_cores = self.on_demand_cores; + config.on_demand_base_fee = self.on_demand_base_fee; + config.on_demand_fee_variability = self.on_demand_fee_variability; + config.on_demand_queue_max_size = self.on_demand_max_queue_size; + config.on_demand_target_queue_utilization = self.on_demand_target_queue_utilization; + + let paras = &mut genesis.paras.paras; + for para_id in self.onboarded_on_demand_chains { + paras.push(( + para_id, + ParaGenesisArgs { + genesis_head: HeadData::from(vec![0u8]), + validation_code: ValidationCode::from(vec![0u8]), + para_kind: ParaKind::Parathread, + }, + )) + } + + genesis + } +} diff --git a/polkadot/runtime/parachains/src/assigner_on_demand/mod.rs b/polkadot/runtime/parachains/src/assigner_on_demand/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..5a60201e4fa8a4501c185324e8e72099c505bbc3 --- /dev/null +++ b/polkadot/runtime/parachains/src/assigner_on_demand/mod.rs @@ -0,0 +1,614 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The parachain on demand assignment module. +//! +//! Implements a mechanism for taking in orders for pay as you go (PAYG) or on demand +//! parachain (previously parathreads) assignments. This module is not handled by the +//! initializer but is instead instantiated in the `construct_runtime` macro. +//! +//! The module currently limits parallel execution of blocks from the same `ParaId` via +//! a core affinity mechanism. As long as there exists an affinity for a `CoreIndex` for +//! a specific `ParaId`, orders for blockspace for that `ParaId` will only be assigned to +//! that `CoreIndex`. This affinity mechanism can be removed if it can be shown that parallel +//! execution is valid. + +mod benchmarking; +mod mock_helpers; + +#[cfg(test)] +mod tests; + +use crate::{ + configuration, paras, + scheduler::common::{AssignmentProvider, AssignmentProviderConfig}, +}; + +use frame_support::{ + pallet_prelude::*, + traits::{ + Currency, + ExistenceRequirement::{self, AllowDeath, KeepAlive}, + WithdrawReasons, + }, +}; +use frame_system::pallet_prelude::*; +use primitives::{v5::Assignment, CoreIndex, Id as ParaId}; +use sp_runtime::{ + traits::{One, SaturatedConversion}, + FixedPointNumber, FixedPointOperand, FixedU128, Perbill, Saturating, +}; + +use sp_std::{collections::vec_deque::VecDeque, prelude::*}; + +const LOG_TARGET: &str = "runtime::parachains::assigner-on-demand"; + +pub use pallet::*; + +pub trait WeightInfo { + fn place_order_allow_death(s: u32) -> Weight; + fn place_order_keep_alive(s: u32) -> Weight; +} + +/// A weight info that is only suitable for testing. +pub struct TestWeightInfo; + +impl WeightInfo for TestWeightInfo { + fn place_order_allow_death(_: u32) -> Weight { + Weight::MAX + } + + fn place_order_keep_alive(_: u32) -> Weight { + Weight::MAX + } +} + +/// Keeps track of how many assignments a scheduler currently has at a specific `CoreIndex` for a +/// specific `ParaId`. +#[derive(Encode, Decode, Default, Clone, Copy, TypeInfo)] +#[cfg_attr(test, derive(PartialEq, Debug))] +pub struct CoreAffinityCount { + core_idx: CoreIndex, + count: u32, +} + +/// An indicator as to which end of the `OnDemandQueue` an assignment will be placed. +pub enum QueuePushDirection { + Back, + Front, +} + +/// Shorthand for the Balance type the runtime is using. +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + +/// Errors that can happen during spot traffic calculation. +#[derive(PartialEq)] +#[cfg_attr(feature = "std", derive(Debug))] +pub enum SpotTrafficCalculationErr { + /// The order queue capacity is at 0. + QueueCapacityIsZero, + /// The queue size is larger than the queue capacity. + QueueSizeLargerThanCapacity, + /// Arithmetic error during division, either division by 0 or over/underflow. + Division, +} + +#[frame_support::pallet] +pub mod pallet { + + use super::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + configuration::Config + paras::Config { + /// The runtime's definition of an event. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// The runtime's definition of a Currency. + type Currency: Currency; + + /// Something that provides the weight of this pallet. + type WeightInfo: WeightInfo; + + /// The default value for the spot traffic multiplier. + #[pallet::constant] + type TrafficDefaultValue: Get; + } + + /// Creates an empty spot traffic value if one isn't present in storage already. + #[pallet::type_value] + pub fn SpotTrafficOnEmpty() -> FixedU128 { + T::TrafficDefaultValue::get() + } + + /// Creates an empty on demand queue if one isn't present in storage already. + #[pallet::type_value] + pub fn OnDemandQueueOnEmpty() -> VecDeque { + VecDeque::new() + } + + /// Keeps track of the multiplier used to calculate the current spot price for the on demand + /// assigner. + #[pallet::storage] + pub(super) type SpotTraffic = + StorageValue<_, FixedU128, ValueQuery, SpotTrafficOnEmpty>; + + /// The order storage entry. Uses a VecDeque to be able to push to the front of the + /// queue from the scheduler on session boundaries. + #[pallet::storage] + pub type OnDemandQueue = + StorageValue<_, VecDeque, ValueQuery, OnDemandQueueOnEmpty>; + + /// Maps a `ParaId` to `CoreIndex` and keeps track of how many assignments the scheduler has in + /// it's lookahead. Keeping track of this affinity prevents parallel execution of the same + /// `ParaId` on two or more `CoreIndex`es. + #[pallet::storage] + pub(super) type ParaIdAffinity = + StorageMap<_, Twox256, ParaId, CoreAffinityCount, OptionQuery>; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// An order was placed at some spot price amount. + OnDemandOrderPlaced { para_id: ParaId, spot_price: BalanceOf }, + /// The value of the spot traffic multiplier changed. + SpotTrafficSet { traffic: FixedU128 }, + } + + #[pallet::error] + pub enum Error { + /// The `ParaId` supplied to the `place_order` call is not a valid `ParaThread`, making the + /// call is invalid. + InvalidParaId, + /// The order queue is full, `place_order` will not continue. + QueueFull, + /// The current spot price is higher than the max amount specified in the `place_order` + /// call, making it invalid. + SpotPriceHigherThanMaxAmount, + /// There are no on demand cores available. `place_order` will not add anything to the + /// queue. + NoOnDemandCores, + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(_now: BlockNumberFor) -> Weight { + let config = >::config(); + // Calculate spot price multiplier and store it. + let old_traffic = SpotTraffic::::get(); + match Self::calculate_spot_traffic( + old_traffic, + config.on_demand_queue_max_size, + Self::queue_size(), + config.on_demand_target_queue_utilization, + config.on_demand_fee_variability, + ) { + Ok(new_traffic) => { + // Only update storage on change + if new_traffic != old_traffic { + SpotTraffic::::set(new_traffic); + Pallet::::deposit_event(Event::::SpotTrafficSet { + traffic: new_traffic, + }); + return T::DbWeight::get().reads_writes(2, 1) + } + }, + Err(SpotTrafficCalculationErr::QueueCapacityIsZero) => { + log::debug!( + target: LOG_TARGET, + "Error calculating spot traffic: The order queue capacity is at 0." + ); + }, + Err(SpotTrafficCalculationErr::QueueSizeLargerThanCapacity) => { + log::debug!( + target: LOG_TARGET, + "Error calculating spot traffic: The queue size is larger than the queue capacity." + ); + }, + Err(SpotTrafficCalculationErr::Division) => { + log::debug!( + target: LOG_TARGET, + "Error calculating spot traffic: Arithmetic error during division, either division by 0 or over/underflow." + ); + }, + }; + T::DbWeight::get().reads_writes(2, 0) + } + } + + #[pallet::call] + impl Pallet { + /// Create a single on demand core order. + /// Will use the spot price for the current block and will reap the account if needed. + /// + /// Parameters: + /// - `origin`: The sender of the call, funds will be withdrawn from this account. + /// - `max_amount`: The maximum balance to withdraw from the origin to place an order. + /// - `para_id`: A `ParaId` the origin wants to provide blockspace for. + /// + /// Errors: + /// - `InsufficientBalance`: from the Currency implementation + /// - `InvalidParaId` + /// - `QueueFull` + /// - `SpotPriceHigherThanMaxAmount` + /// - `NoOnDemandCores` + /// + /// Events: + /// - `SpotOrderPlaced` + #[pallet::call_index(0)] + #[pallet::weight(::WeightInfo::place_order_allow_death(OnDemandQueue::::get().len() as u32))] + pub fn place_order_allow_death( + origin: OriginFor, + max_amount: BalanceOf, + para_id: ParaId, + ) -> DispatchResult { + let sender = ensure_signed(origin)?; + Pallet::::do_place_order(sender, max_amount, para_id, AllowDeath) + } + + /// Same as the [`place_order_allow_death`] call , but with a check that placing the order + /// will not reap the account. + /// + /// Parameters: + /// - `origin`: The sender of the call, funds will be withdrawn from this account. + /// - `max_amount`: The maximum balance to withdraw from the origin to place an order. + /// - `para_id`: A `ParaId` the origin wants to provide blockspace for. + /// + /// Errors: + /// - `InsufficientBalance`: from the Currency implementation + /// - `InvalidParaId` + /// - `QueueFull` + /// - `SpotPriceHigherThanMaxAmount` + /// - `NoOnDemandCores` + /// + /// Events: + /// - `SpotOrderPlaced` + #[pallet::call_index(1)] + #[pallet::weight(::WeightInfo::place_order_keep_alive(OnDemandQueue::::get().len() as u32))] + pub fn place_order_keep_alive( + origin: OriginFor, + max_amount: BalanceOf, + para_id: ParaId, + ) -> DispatchResult { + let sender = ensure_signed(origin)?; + Pallet::::do_place_order(sender, max_amount, para_id, KeepAlive) + } + } +} + +impl Pallet +where + BalanceOf: FixedPointOperand, +{ + /// Helper function for `place_order_*` calls. Used to differentiate between placing orders + /// with a keep alive check or to allow the account to be reaped. + /// + /// Parameters: + /// - `sender`: The sender of the call, funds will be withdrawn from this account. + /// - `max_amount`: The maximum balance to withdraw from the origin to place an order. + /// - `para_id`: A `ParaId` the origin wants to provide blockspace for. + /// - `existence_requirement`: Whether or not to ensure that the account will not be reaped. + /// + /// Errors: + /// - `InsufficientBalance`: from the Currency implementation + /// - `InvalidParaId` + /// - `QueueFull` + /// - `SpotPriceHigherThanMaxAmount` + /// - `NoOnDemandCores` + /// + /// Events: + /// - `SpotOrderPlaced` + fn do_place_order( + sender: ::AccountId, + max_amount: BalanceOf, + para_id: ParaId, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { + let config = >::config(); + + // Are there any schedulable cores in this session + ensure!(config.on_demand_cores > 0, Error::::NoOnDemandCores); + + // Traffic always falls back to 1.0 + let traffic = SpotTraffic::::get(); + + // Calculate spot price + let spot_price: BalanceOf = + traffic.saturating_mul_int(config.on_demand_base_fee.saturated_into::>()); + + // Is the current price higher than `max_amount` + ensure!(spot_price.le(&max_amount), Error::::SpotPriceHigherThanMaxAmount); + + // Charge the sending account the spot price + T::Currency::withdraw(&sender, spot_price, WithdrawReasons::FEE, existence_requirement)?; + + let assignment = Assignment::new(para_id); + + let res = Pallet::::add_on_demand_assignment(assignment, QueuePushDirection::Back); + + match res { + Ok(_) => { + Pallet::::deposit_event(Event::::OnDemandOrderPlaced { para_id, spot_price }); + return Ok(()) + }, + Err(err) => return Err(err), + } + } + + /// The spot price multiplier. This is based on the transaction fee calculations defined in: + /// https://research.web3.foundation/Polkadot/overview/token-economics#setting-transaction-fees + /// + /// Parameters: + /// - `traffic`: The previously calculated multiplier, can never go below 1.0. + /// - `queue_capacity`: The max size of the order book. + /// - `queue_size`: How many orders are currently in the order book. + /// - `target_queue_utilisation`: How much of the queue_capacity should be ideally occupied, + /// expressed in percentages(perbill). + /// - `variability`: A variability factor, i.e. how quickly the spot price adjusts. This number + /// can be chosen by p/(k*(1-s)) where p is the desired ratio increase in spot price over k + /// number of blocks. s is the target_queue_utilisation. A concrete example: v = + /// 0.05/(20*(1-0.25)) = 0.0033. + /// + /// Returns: + /// - A `FixedU128` in the range of `Config::TrafficDefaultValue` - `FixedU128::MAX` on + /// success. + /// + /// Errors: + /// - `SpotTrafficCalculationErr::QueueCapacityIsZero` + /// - `SpotTrafficCalculationErr::QueueSizeLargerThanCapacity` + /// - `SpotTrafficCalculationErr::Division` + pub(crate) fn calculate_spot_traffic( + traffic: FixedU128, + queue_capacity: u32, + queue_size: u32, + target_queue_utilisation: Perbill, + variability: Perbill, + ) -> Result { + // Return early if queue has no capacity. + if queue_capacity == 0 { + return Err(SpotTrafficCalculationErr::QueueCapacityIsZero) + } + + // Return early if queue size is greater than capacity. + if queue_size > queue_capacity { + return Err(SpotTrafficCalculationErr::QueueSizeLargerThanCapacity) + } + + // (queue_size / queue_capacity) - target_queue_utilisation + let queue_util_ratio = FixedU128::from_rational(queue_size.into(), queue_capacity.into()); + let positive = queue_util_ratio >= target_queue_utilisation.into(); + let queue_util_diff = queue_util_ratio.max(target_queue_utilisation.into()) - + queue_util_ratio.min(target_queue_utilisation.into()); + + // variability * queue_util_diff + let var_times_qud = queue_util_diff.saturating_mul(variability.into()); + + // variability^2 * queue_util_diff^2 + let var_times_qud_pow = var_times_qud.saturating_mul(var_times_qud); + + // (variability^2 * queue_util_diff^2)/2 + let div_by_two: FixedU128; + match var_times_qud_pow.const_checked_div(2.into()) { + Some(dbt) => div_by_two = dbt, + None => return Err(SpotTrafficCalculationErr::Division), + } + + // traffic * (1 + queue_util_diff) + div_by_two + if positive { + let new_traffic = queue_util_diff + .saturating_add(div_by_two) + .saturating_add(One::one()) + .saturating_mul(traffic); + Ok(new_traffic.max(::TrafficDefaultValue::get())) + } else { + let new_traffic = queue_util_diff.saturating_sub(div_by_two).saturating_mul(traffic); + Ok(new_traffic.max(::TrafficDefaultValue::get())) + } + } + + /// Adds an assignment to the on demand queue. + /// + /// Paramenters: + /// - `assignment`: The on demand assignment to add to the queue. + /// - `location`: Whether to push this entry to the back or the front of the queue. Pushing an + /// entry to the front of the queue is only used when the scheduler wants to push back an + /// entry it has already popped. + /// Returns: + /// - The unit type on success. + /// + /// Errors: + /// - `InvalidParaId` + /// - `QueueFull` + pub fn add_on_demand_assignment( + assignment: Assignment, + location: QueuePushDirection, + ) -> Result<(), DispatchError> { + // Only parathreads are valid paraids for on the go parachains. + ensure!(>::is_parathread(assignment.para_id), Error::::InvalidParaId); + + let config = >::config(); + + OnDemandQueue::::try_mutate(|queue| { + // Abort transaction if queue is too large + ensure!(Self::queue_size() < config.on_demand_queue_max_size, Error::::QueueFull); + match location { + QueuePushDirection::Back => queue.push_back(assignment), + QueuePushDirection::Front => queue.push_front(assignment), + }; + Ok(()) + }) + } + + /// Get the size of the on demand queue. + /// + /// Returns: + /// - The size of the on demand queue. + fn queue_size() -> u32 { + let config = >::config(); + match OnDemandQueue::::get().len().try_into() { + Ok(size) => return size, + Err(_) => { + log::debug!( + target: LOG_TARGET, + "Failed to fetch the on demand queue size, returning the max size." + ); + return config.on_demand_queue_max_size + }, + } + } + + /// Getter for the order queue. + pub fn get_queue() -> VecDeque { + OnDemandQueue::::get() + } + + /// Getter for the affinity tracker. + pub fn get_affinity_map(para_id: ParaId) -> Option { + ParaIdAffinity::::get(para_id) + } + + /// Decreases the affinity of a `ParaId` to a specified `CoreIndex`. + /// Subtracts from the count of the `CoreAffinityCount` if an entry is found and the core_idx + /// matches. When the count reaches 0, the entry is removed. + /// A non-existant entry is a no-op. + fn decrease_affinity(para_id: ParaId, core_idx: CoreIndex) { + ParaIdAffinity::::mutate(para_id, |maybe_affinity| { + if let Some(affinity) = maybe_affinity { + if affinity.core_idx == core_idx { + let new_count = affinity.count.saturating_sub(1); + if new_count > 0 { + *maybe_affinity = Some(CoreAffinityCount { core_idx, count: new_count }); + } else { + *maybe_affinity = None; + } + } + } + }); + } + + /// Increases the affinity of a `ParaId` to a specified `CoreIndex`. + /// Adds to the count of the `CoreAffinityCount` if an entry is found and the core_idx matches. + /// A non-existant entry will be initialized with a count of 1 and uses the supplied + /// `CoreIndex`. + fn increase_affinity(para_id: ParaId, core_idx: CoreIndex) { + ParaIdAffinity::::mutate(para_id, |maybe_affinity| match maybe_affinity { + Some(affinity) => + if affinity.core_idx == core_idx { + *maybe_affinity = Some(CoreAffinityCount { + core_idx, + count: affinity.count.saturating_add(1), + }); + }, + None => { + *maybe_affinity = Some(CoreAffinityCount { core_idx, count: 1 }); + }, + }) + } +} + +impl AssignmentProvider> for Pallet { + fn session_core_count() -> u32 { + let config = >::config(); + config.on_demand_cores + } + + /// Take the next queued entry that is available for a given core index. + /// Invalidates and removes orders with a `para_id` that is not `ParaLifecycle::Parathread` + /// but only in [0..P] range slice of the order queue, where P is the element that is + /// removed from the order queue. + /// + /// Parameters: + /// - `core_idx`: The core index + /// - `previous_paraid`: Which paraid was previously processed on the requested core. Is None if + /// nothing was processed on the core. + fn pop_assignment_for_core( + core_idx: CoreIndex, + previous_para: Option, + ) -> Option { + // Only decrease the affinity of the previous para if it exists. + // A nonexistant `ParaId` indicates that the scheduler has not processed any + // `ParaId` this session. + if let Some(previous_para_id) = previous_para { + Pallet::::decrease_affinity(previous_para_id, core_idx) + } + + let mut queue: VecDeque = OnDemandQueue::::get(); + + let mut invalidated_para_id_indexes: Vec = vec![]; + + // Get the position of the next `ParaId`. Select either a valid `ParaId` that has an + // affinity to the same `CoreIndex` as the scheduler asks for or a valid `ParaId` with no + // affinity at all. + let pos = queue.iter().enumerate().position(|(index, assignment)| { + if >::is_parathread(assignment.para_id) { + match ParaIdAffinity::::get(&assignment.para_id) { + Some(affinity) => return affinity.core_idx == core_idx, + None => return true, + } + } + // Record no longer valid para_ids. + invalidated_para_id_indexes.push(index); + return false + }); + + // Collect the popped value. + let popped = pos.and_then(|p: usize| { + if let Some(assignment) = queue.remove(p) { + Pallet::::increase_affinity(assignment.para_id, core_idx); + return Some(assignment) + }; + None + }); + + // Only remove the invalid indexes *after* using the index. + // Removed in reverse order so that the indexes don't shift. + invalidated_para_id_indexes.iter().rev().for_each(|idx| { + queue.remove(*idx); + }); + + // Write changes to storage. + OnDemandQueue::::set(queue); + + popped + } + + /// Push an assignment back to the queue. + /// Typically used on session boundaries. + /// Parameters: + /// - `core_idx`: The core index + /// - `assignment`: The on demand assignment. + fn push_assignment_for_core(core_idx: CoreIndex, assignment: Assignment) { + Pallet::::decrease_affinity(assignment.para_id, core_idx); + // Skip the queue on push backs from scheduler + match Pallet::::add_on_demand_assignment(assignment, QueuePushDirection::Front) { + Ok(_) => {}, + Err(_) => {}, + } + } + + fn get_provider_config(_core_idx: CoreIndex) -> AssignmentProviderConfig> { + let config = >::config(); + AssignmentProviderConfig { + availability_period: config.paras_availability_period, + max_availability_timeouts: config.on_demand_retries, + ttl: config.on_demand_ttl, + } + } +} diff --git a/polkadot/runtime/parachains/src/assigner_on_demand/tests.rs b/polkadot/runtime/parachains/src/assigner_on_demand/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..8041179cd90c51c6a1d6bb820ba0572539f1e271 --- /dev/null +++ b/polkadot/runtime/parachains/src/assigner_on_demand/tests.rs @@ -0,0 +1,558 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use crate::{ + assigner_on_demand::{mock_helpers::GenesisConfigBuilder, Error}, + initializer::SessionChangeNotification, + mock::{ + new_test_ext, Balances, OnDemandAssigner, Paras, ParasShared, RuntimeOrigin, Scheduler, + System, Test, + }, + paras::{ParaGenesisArgs, ParaKind}, +}; +use frame_support::{assert_noop, assert_ok, error::BadOrigin}; +use pallet_balances::Error as BalancesError; +use primitives::{ + v5::{Assignment, ValidationCode}, + BlockNumber, SessionIndex, +}; +use sp_std::collections::btree_map::BTreeMap; + +fn schedule_blank_para(id: ParaId, parakind: ParaKind) { + let validation_code: ValidationCode = vec![1, 2, 3].into(); + assert_ok!(Paras::schedule_para_initialize( + id, + ParaGenesisArgs { + genesis_head: Vec::new().into(), + validation_code: validation_code.clone(), + para_kind: parakind, + } + )); + + assert_ok!(Paras::add_trusted_validation_code(RuntimeOrigin::root(), validation_code)); +} + +fn run_to_block( + to: BlockNumber, + new_session: impl Fn(BlockNumber) -> Option>, +) { + while System::block_number() < to { + let b = System::block_number(); + + Scheduler::initializer_finalize(); + Paras::initializer_finalize(b); + + if let Some(notification) = new_session(b + 1) { + let mut notification_with_session_index = notification; + // We will make every session change trigger an action queue. Normally this may require + // 2 or more session changes. + if notification_with_session_index.session_index == SessionIndex::default() { + notification_with_session_index.session_index = ParasShared::scheduled_session(); + } + Paras::initializer_on_new_session(¬ification_with_session_index); + Scheduler::initializer_on_new_session(¬ification_with_session_index); + } + + System::on_finalize(b); + + System::on_initialize(b + 1); + System::set_block_number(b + 1); + + Paras::initializer_initialize(b + 1); + Scheduler::initializer_initialize(b + 1); + + // In the real runtime this is expected to be called by the `InclusionInherent` pallet. + Scheduler::update_claimqueue(BTreeMap::new(), b + 1); + } +} + +#[test] +fn spot_traffic_capacity_zero_returns_none() { + match OnDemandAssigner::calculate_spot_traffic( + FixedU128::from(u128::MAX), + 0u32, + u32::MAX, + Perbill::from_percent(100), + Perbill::from_percent(1), + ) { + Ok(_) => panic!("Error"), + Err(e) => assert_eq!(e, SpotTrafficCalculationErr::QueueCapacityIsZero), + }; +} + +#[test] +fn spot_traffic_queue_size_larger_than_capacity_returns_none() { + match OnDemandAssigner::calculate_spot_traffic( + FixedU128::from(u128::MAX), + 1u32, + 2u32, + Perbill::from_percent(100), + Perbill::from_percent(1), + ) { + Ok(_) => panic!("Error"), + Err(e) => assert_eq!(e, SpotTrafficCalculationErr::QueueSizeLargerThanCapacity), + } +} + +#[test] +fn spot_traffic_calculation_identity() { + match OnDemandAssigner::calculate_spot_traffic( + FixedU128::from_u32(1), + 1000, + 100, + Perbill::from_percent(10), + Perbill::from_percent(3), + ) { + Ok(res) => { + assert_eq!(res, FixedU128::from_u32(1)) + }, + _ => (), + } +} + +#[test] +fn spot_traffic_calculation_u32_max() { + match OnDemandAssigner::calculate_spot_traffic( + FixedU128::from_u32(1), + u32::MAX, + u32::MAX, + Perbill::from_percent(100), + Perbill::from_percent(3), + ) { + Ok(res) => { + assert_eq!(res, FixedU128::from_u32(1)) + }, + _ => panic!("Error"), + }; +} + +#[test] +fn spot_traffic_calculation_u32_traffic_max() { + match OnDemandAssigner::calculate_spot_traffic( + FixedU128::from(u128::MAX), + u32::MAX, + u32::MAX, + Perbill::from_percent(1), + Perbill::from_percent(1), + ) { + Ok(res) => assert_eq!(res, FixedU128::from(u128::MAX)), + _ => panic!("Error"), + }; +} + +#[test] +fn sustained_target_increases_spot_traffic() { + let mut traffic = FixedU128::from_u32(1u32); + for _ in 0..50 { + traffic = OnDemandAssigner::calculate_spot_traffic( + traffic, + 100, + 12, + Perbill::from_percent(10), + Perbill::from_percent(100), + ) + .unwrap() + } + assert_eq!(traffic, FixedU128::from_inner(2_718_103_312_071_174_015u128)) +} + +#[test] +fn spot_traffic_can_decrease() { + let traffic = FixedU128::from_u32(100u32); + match OnDemandAssigner::calculate_spot_traffic( + traffic, + 100u32, + 0u32, + Perbill::from_percent(100), + Perbill::from_percent(100), + ) { + Ok(new_traffic) => + assert_eq!(new_traffic, FixedU128::from_inner(50_000_000_000_000_000_000u128)), + _ => panic!("Error"), + } +} + +#[test] +fn spot_traffic_decreases_over_time() { + let mut traffic = FixedU128::from_u32(100u32); + for _ in 0..5 { + traffic = OnDemandAssigner::calculate_spot_traffic( + traffic, + 100u32, + 0u32, + Perbill::from_percent(100), + Perbill::from_percent(100), + ) + .unwrap(); + println!("{traffic}"); + } + assert_eq!(traffic, FixedU128::from_inner(3_125_000_000_000_000_000u128)) +} + +#[test] +fn place_order_works() { + let alice = 1u64; + let amt = 10_000_000u128; + let para_id = ParaId::from(111); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + // Initialize the parathread and wait for it to be ready. + schedule_blank_para(para_id, ParaKind::Parathread); + + assert!(!Paras::is_parathread(para_id)); + + run_to_block(100, |n| if n == 100 { Some(Default::default()) } else { None }); + + assert!(Paras::is_parathread(para_id)); + + // Does not work unsigned + assert_noop!( + OnDemandAssigner::place_order_allow_death(RuntimeOrigin::none(), amt, para_id), + BadOrigin + ); + + // Does not work with max_amount lower than fee + let low_max_amt = 1u128; + assert_noop!( + OnDemandAssigner::place_order_allow_death( + RuntimeOrigin::signed(alice), + low_max_amt, + para_id, + ), + Error::::SpotPriceHigherThanMaxAmount, + ); + + // Does not work with insufficient balance + assert_noop!( + OnDemandAssigner::place_order_allow_death(RuntimeOrigin::signed(alice), amt, para_id), + BalancesError::::InsufficientBalance + ); + + // Works + Balances::make_free_balance_be(&alice, amt); + run_to_block(101, |n| if n == 101 { Some(Default::default()) } else { None }); + assert_ok!(OnDemandAssigner::place_order_allow_death( + RuntimeOrigin::signed(alice), + amt, + para_id + )); + }); +} + +#[test] +fn place_order_keep_alive_keeps_alive() { + let alice = 1u64; + let amt = 1u128; // The same as crate::mock's EXISTENTIAL_DEPOSIT + let max_amt = 10_000_000u128; + let para_id = ParaId::from(111); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + // Initialize the parathread and wait for it to be ready. + schedule_blank_para(para_id, ParaKind::Parathread); + Balances::make_free_balance_be(&alice, amt); + + assert!(!Paras::is_parathread(para_id)); + run_to_block(100, |n| if n == 100 { Some(Default::default()) } else { None }); + assert!(Paras::is_parathread(para_id)); + + assert_noop!( + OnDemandAssigner::place_order_keep_alive( + RuntimeOrigin::signed(alice), + max_amt, + para_id + ), + BalancesError::::InsufficientBalance + ); + }); +} + +#[test] +fn add_on_demand_assignment_works() { + let para_a = ParaId::from(111); + let assignment = Assignment::new(para_a); + + let mut genesis = GenesisConfigBuilder::default(); + genesis.on_demand_max_queue_size = 1; + new_test_ext(genesis.build()).execute_with(|| { + // Initialize the parathread and wait for it to be ready. + schedule_blank_para(para_a, ParaKind::Parathread); + + // `para_a` is not onboarded as a parathread yet. + assert_noop!( + OnDemandAssigner::add_on_demand_assignment( + assignment.clone(), + QueuePushDirection::Back + ), + Error::::InvalidParaId + ); + + assert!(!Paras::is_parathread(para_a)); + run_to_block(100, |n| if n == 100 { Some(Default::default()) } else { None }); + assert!(Paras::is_parathread(para_a)); + + // `para_a` is now onboarded as a valid parathread. + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment.clone(), + QueuePushDirection::Back + )); + + // Max queue size is 1, queue should be full. + assert_noop!( + OnDemandAssigner::add_on_demand_assignment(assignment, QueuePushDirection::Back), + Error::::QueueFull + ); + }); +} + +#[test] +fn spotqueue_push_directions() { + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + let para_a = ParaId::from(111); + let para_b = ParaId::from(222); + let para_c = ParaId::from(333); + + schedule_blank_para(para_a, ParaKind::Parathread); + schedule_blank_para(para_b, ParaKind::Parathread); + schedule_blank_para(para_c, ParaKind::Parathread); + + run_to_block(11, |n| if n == 11 { Some(Default::default()) } else { None }); + + let assignment_a = Assignment { para_id: para_a }; + let assignment_b = Assignment { para_id: para_b }; + let assignment_c = Assignment { para_id: para_c }; + + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_a.clone(), + QueuePushDirection::Front + )); + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_b.clone(), + QueuePushDirection::Front + )); + + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_c.clone(), + QueuePushDirection::Back + )); + + assert_eq!(OnDemandAssigner::queue_size(), 3); + assert_eq!( + OnDemandAssigner::get_queue(), + VecDeque::from(vec![assignment_b, assignment_a, assignment_c]) + ) + }); +} + +#[test] +fn affinity_changes_work() { + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + let para_a = ParaId::from(111); + schedule_blank_para(para_a, ParaKind::Parathread); + + run_to_block(11, |n| if n == 11 { Some(Default::default()) } else { None }); + + let assignment_a = Assignment { para_id: para_a }; + // There should be no affinity before starting. + assert!(OnDemandAssigner::get_affinity_map(para_a).is_none()); + + // Add enough assignments to the order queue. + for _ in 0..10 { + OnDemandAssigner::add_on_demand_assignment( + assignment_a.clone(), + QueuePushDirection::Front, + ) + .expect("Invalid paraid or queue full"); + } + + // There should be no affinity before the scheduler pops. + assert!(OnDemandAssigner::get_affinity_map(para_a).is_none()); + + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), None); + + // Affinity count is 1 after popping. + assert_eq!(OnDemandAssigner::get_affinity_map(para_a).unwrap().count, 1); + + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), Some(para_a)); + + // Affinity count is 1 after popping with a previous para. + assert_eq!(OnDemandAssigner::get_affinity_map(para_a).unwrap().count, 1); + assert_eq!(OnDemandAssigner::queue_size(), 8); + + for _ in 0..3 { + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), None); + } + + // Affinity count is 4 after popping 3 times without a previous para. + assert_eq!(OnDemandAssigner::get_affinity_map(para_a).unwrap().count, 4); + assert_eq!(OnDemandAssigner::queue_size(), 5); + + for _ in 0..5 { + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), Some(para_a)); + } + + // Affinity count should still be 4 but queue should be empty. + assert_eq!(OnDemandAssigner::get_affinity_map(para_a).unwrap().count, 4); + assert_eq!(OnDemandAssigner::queue_size(), 0); + + // Pop 4 times and get to exactly 0 (None) affinity. + for _ in 0..4 { + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), Some(para_a)); + } + assert!(OnDemandAssigner::get_affinity_map(para_a).is_none()); + + // Decreasing affinity beyond 0 should still be None. + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), Some(para_a)); + assert!(OnDemandAssigner::get_affinity_map(para_a).is_none()); + }); +} + +#[test] +fn affinity_prohibits_parallel_scheduling() { + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + let para_a = ParaId::from(111); + let para_b = ParaId::from(222); + + schedule_blank_para(para_a, ParaKind::Parathread); + schedule_blank_para(para_b, ParaKind::Parathread); + + run_to_block(11, |n| if n == 11 { Some(Default::default()) } else { None }); + + let assignment_a = Assignment { para_id: para_a }; + let assignment_b = Assignment { para_id: para_b }; + + // There should be no affinity before starting. + assert!(OnDemandAssigner::get_affinity_map(para_a).is_none()); + assert!(OnDemandAssigner::get_affinity_map(para_b).is_none()); + + // Add 2 assignments for para_a for every para_b. + OnDemandAssigner::add_on_demand_assignment(assignment_a.clone(), QueuePushDirection::Back) + .expect("Invalid paraid or queue full"); + + OnDemandAssigner::add_on_demand_assignment(assignment_a.clone(), QueuePushDirection::Back) + .expect("Invalid paraid or queue full"); + + OnDemandAssigner::add_on_demand_assignment(assignment_b.clone(), QueuePushDirection::Back) + .expect("Invalid paraid or queue full"); + + assert_eq!(OnDemandAssigner::queue_size(), 3); + + // Approximate having 1 core. + for _ in 0..3 { + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), None); + } + + // Affinity on one core is meaningless. + assert_eq!(OnDemandAssigner::get_affinity_map(para_a).unwrap().count, 2); + assert_eq!(OnDemandAssigner::get_affinity_map(para_b).unwrap().count, 1); + assert_eq!( + OnDemandAssigner::get_affinity_map(para_a).unwrap().core_idx, + OnDemandAssigner::get_affinity_map(para_b).unwrap().core_idx + ); + + // Clear affinity + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), Some(para_a)); + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), Some(para_a)); + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), Some(para_b)); + + // Add 2 assignments for para_a for every para_b. + OnDemandAssigner::add_on_demand_assignment(assignment_a.clone(), QueuePushDirection::Back) + .expect("Invalid paraid or queue full"); + + OnDemandAssigner::add_on_demand_assignment(assignment_a.clone(), QueuePushDirection::Back) + .expect("Invalid paraid or queue full"); + + OnDemandAssigner::add_on_demand_assignment(assignment_b.clone(), QueuePushDirection::Back) + .expect("Invalid paraid or queue full"); + + // Approximate having 2 cores. + for _ in 0..3 { + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), None); + OnDemandAssigner::pop_assignment_for_core(CoreIndex(1), None); + } + + // Affinity should be the same as before, but on different cores. + assert_eq!(OnDemandAssigner::get_affinity_map(para_a).unwrap().count, 2); + assert_eq!(OnDemandAssigner::get_affinity_map(para_b).unwrap().count, 1); + assert_eq!(OnDemandAssigner::get_affinity_map(para_a).unwrap().core_idx, CoreIndex(0)); + assert_eq!(OnDemandAssigner::get_affinity_map(para_b).unwrap().core_idx, CoreIndex(1)); + }); +} + +#[test] +fn cannot_place_order_when_no_on_demand_cores() { + let mut genesis = GenesisConfigBuilder::default(); + genesis.on_demand_cores = 0; + let para_id = ParaId::from(10); + let alice = 1u64; + let amt = 10_000_000u128; + + new_test_ext(genesis.build()).execute_with(|| { + schedule_blank_para(para_id, ParaKind::Parathread); + Balances::make_free_balance_be(&alice, amt); + + assert!(!Paras::is_parathread(para_id)); + + run_to_block(10, |n| if n == 10 { Some(Default::default()) } else { None }); + + assert!(Paras::is_parathread(para_id)); + + assert_noop!( + OnDemandAssigner::place_order_allow_death(RuntimeOrigin::signed(alice), amt, para_id), + Error::::NoOnDemandCores + ); + }); +} + +#[test] +fn on_demand_orders_cannot_be_popped_if_lifecycle_changes() { + let para_id = ParaId::from(10); + let assignment = Assignment { para_id }; + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + // Register the para_id as a parathread + schedule_blank_para(para_id, ParaKind::Parathread); + + assert!(!Paras::is_parathread(para_id)); + run_to_block(10, |n| if n == 10 { Some(Default::default()) } else { None }); + assert!(Paras::is_parathread(para_id)); + + // Add two assignments for a para_id with a valid lifecycle. + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment.clone(), + QueuePushDirection::Back + )); + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment.clone(), + QueuePushDirection::Back + )); + + // First pop is fine + assert!(OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), None) == Some(assignment)); + + // Deregister para + assert_ok!(Paras::schedule_para_cleanup(para_id)); + + // Run to new session and verify that para_id is no longer a valid parathread. + assert!(Paras::is_parathread(para_id)); + run_to_block(20, |n| if n == 20 { Some(Default::default()) } else { None }); + assert!(!Paras::is_parathread(para_id)); + + // Second pop should be None. + assert!(OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), Some(para_id)) == None); + }); +} diff --git a/polkadot/runtime/parachains/src/assigner_parachains.rs b/polkadot/runtime/parachains/src/assigner_parachains.rs new file mode 100644 index 0000000000000000000000000000000000000000..9a6b970597d52e58d595afad642ffdde7681e857 --- /dev/null +++ b/polkadot/runtime/parachains/src/assigner_parachains.rs @@ -0,0 +1,70 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The bulk (parachain slot auction) blockspace assignment provider. +//! This provider is tightly coupled with the configuration and paras modules. + +use crate::{ + configuration, paras, + scheduler::common::{AssignmentProvider, AssignmentProviderConfig}, +}; +use frame_system::pallet_prelude::BlockNumberFor; +pub use pallet::*; +use primitives::{v5::Assignment, CoreIndex, Id as ParaId}; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + configuration::Config + paras::Config {} +} + +impl AssignmentProvider> for Pallet { + fn session_core_count() -> u32 { + >::parachains().len() as u32 + } + + fn pop_assignment_for_core( + core_idx: CoreIndex, + _concluded_para: Option, + ) -> Option { + >::parachains() + .get(core_idx.0 as usize) + .copied() + .map(|para_id| Assignment::new(para_id)) + } + + /// Bulk assignment has no need to push the assignment back on a session change, + /// this is a no-op in the case of a bulk assignment slot. + fn push_assignment_for_core(_: CoreIndex, _: Assignment) {} + + fn get_provider_config(_core_idx: CoreIndex) -> AssignmentProviderConfig> { + let config = >::config(); + AssignmentProviderConfig { + availability_period: config.paras_availability_period, + // The next assignment already goes to the same [`ParaId`], no timeout tracking needed. + max_availability_timeouts: 0, + // The next assignment already goes to the same [`ParaId`], this can be any number + // that's high enough to clear the time it takes to clear backing/availability. + ttl: BlockNumberFor::::from(10u32), + } + } +} diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs new file mode 100644 index 0000000000000000000000000000000000000000..4921af5bedda7c0354c30eeef85a153556eb7fee --- /dev/null +++ b/polkadot/runtime/parachains/src/builder.rs @@ -0,0 +1,722 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::{ + configuration, inclusion, initializer, paras, + paras::ParaKind, + paras_inherent, + scheduler::{self, common::AssignmentProviderConfig}, + session_info, shared, +}; +use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; +use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::*; +use primitives::{ + collator_signature_payload, + v5::{Assignment, ParasEntry}, + AvailabilityBitfield, BackedCandidate, CandidateCommitments, CandidateDescriptor, + CandidateHash, CollatorId, CollatorSignature, CommittedCandidateReceipt, CompactStatement, + CoreIndex, CoreOccupied, DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, + Id as ParaId, IndexedVec, InherentData as ParachainsInherentData, InvalidDisputeStatementKind, + PersistedValidationData, SessionIndex, SigningContext, UncheckedSigned, + ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, ValidityAttestation, +}; +use sp_core::{sr25519, H256}; +use sp_runtime::{ + generic::Digest, + traits::{Header as HeaderT, One, TrailingZeroInput, Zero}, + RuntimeAppPublic, +}; +use sp_std::{collections::btree_map::BTreeMap, prelude::Vec, vec}; + +fn mock_validation_code() -> ValidationCode { + ValidationCode(vec![1, 2, 3]) +} + +/// Grab an account, seeded by a name and index. +/// +/// This is directly from frame-benchmarking. Copy/pasted so we can use it when not compiling with +/// "features = runtime-benchmarks". +fn account(name: &'static str, index: u32, seed: u32) -> AccountId { + let entropy = (name, index, seed).using_encoded(sp_io::hashing::blake2_256); + AccountId::decode(&mut TrailingZeroInput::new(&entropy[..])) + .expect("infinite input; no invalid input; qed") +} + +/// Create a 32 byte slice based on the given number. +fn byte32_slice_from(n: u32) -> [u8; 32] { + let mut slice = [0u8; 32]; + slice[31] = (n % (1 << 8)) as u8; + slice[30] = ((n >> 8) % (1 << 8)) as u8; + slice[29] = ((n >> 16) % (1 << 8)) as u8; + slice[28] = ((n >> 24) % (1 << 8)) as u8; + + slice +} + +/// Paras inherent `enter` benchmark scenario builder. +pub(crate) struct BenchBuilder { + /// Active validators. Validators should be declared prior to all other setup. + validators: Option>, + /// Starting block number; we expect it to get incremented on session setup. + block_number: BlockNumberFor, + /// Starting session; we expect it to get incremented on session setup. + session: SessionIndex, + /// Session we want the scenario to take place in. We will roll to this session. + target_session: u32, + /// Optionally set the max validators per core; otherwise uses the configuration value. + max_validators_per_core: Option, + /// Optionally set the max validators; otherwise uses the configuration value. + max_validators: Option, + /// Optionally set the number of dispute statements for each candidate. + dispute_statements: BTreeMap, + /// Session index of for each dispute. Index of slice corresponds to a core, + /// which is offset by the number of entries for `backed_and_concluding_cores`. I.E. if + /// `backed_and_concluding_cores` has 3 entries, the first index of `dispute_sessions` + /// will correspond to core index 3. There must be one entry for each core with a dispute + /// statement set. + dispute_sessions: Vec, + /// Map from core seed to number of validity votes. + backed_and_concluding_cores: BTreeMap, + /// Make every candidate include a code upgrade by setting this to `Some` where the interior + /// value is the byte length of the new code. + code_upgrade: Option, + _phantom: sp_std::marker::PhantomData, +} + +/// Paras inherent `enter` benchmark scenario. +#[cfg(any(feature = "runtime-benchmarks", test))] +pub(crate) struct Bench { + pub(crate) data: ParachainsInherentData>, + pub(crate) _session: u32, + pub(crate) _block_number: BlockNumberFor, +} + +impl BenchBuilder { + /// Create a new `BenchBuilder` with some opinionated values that should work with the rest + /// of the functions in this implementation. + pub(crate) fn new() -> Self { + BenchBuilder { + validators: None, + block_number: Zero::zero(), + session: SessionIndex::from(0u32), + target_session: 2u32, + max_validators_per_core: None, + max_validators: None, + dispute_statements: BTreeMap::new(), + dispute_sessions: Default::default(), + backed_and_concluding_cores: Default::default(), + code_upgrade: None, + _phantom: sp_std::marker::PhantomData::, + } + } + + /// Set the session index for each dispute statement set (in other words, set the session the + /// the dispute statement set's relay chain block is from). Indexes of `dispute_sessions` + /// correspond to a core, which is offset by the number of entries for + /// `backed_and_concluding_cores`. I.E. if `backed_and_concluding_cores` cores has 3 entries, + /// the first index of `dispute_sessions` will correspond to core index 3. + /// + /// Note that there must be an entry for each core with a dispute statement set. + pub(crate) fn set_dispute_sessions(mut self, dispute_sessions: impl AsRef<[u32]>) -> Self { + self.dispute_sessions = dispute_sessions.as_ref().to_vec(); + self + } + + /// Set a map from core/para id seed to number of validity votes. + pub(crate) fn set_backed_and_concluding_cores( + mut self, + backed_and_concluding_cores: BTreeMap, + ) -> Self { + self.backed_and_concluding_cores = backed_and_concluding_cores; + self + } + + /// Set to include a code upgrade for all backed candidates. The value will be the byte length + /// of the code. + pub(crate) fn set_code_upgrade(mut self, code_upgrade: impl Into>) -> Self { + self.code_upgrade = code_upgrade.into(); + self + } + + /// Mock header. + pub(crate) fn header(block_number: BlockNumberFor) -> HeaderFor { + HeaderFor::::new( + block_number, // `block_number`, + Default::default(), // `extrinsics_root`, + Default::default(), // `storage_root`, + Default::default(), // `parent_hash`, + Default::default(), // digest, + ) + } + + /// Number of the relay parent block. + fn relay_parent_number(&self) -> u32 { + (self.block_number - One::one()) + .try_into() + .map_err(|_| ()) + .expect("self.block_number is u32") + } + + /// Maximum number of validators that may be part of a validator group. + pub(crate) fn fallback_max_validators() -> u32 { + configuration::Pallet::::config().max_validators.unwrap_or(200) + } + + /// Maximum number of validators participating in parachains consensus (a.k.a. active + /// validators). + fn max_validators(&self) -> u32 { + self.max_validators.unwrap_or(Self::fallback_max_validators()) + } + + /// Set the maximum number of active validators. + #[cfg(not(feature = "runtime-benchmarks"))] + pub(crate) fn set_max_validators(mut self, n: u32) -> Self { + self.max_validators = Some(n); + self + } + + /// Maximum number of validators per core (a.k.a. max validators per group). This value is used + /// if none is explicitly set on the builder. + pub(crate) fn fallback_max_validators_per_core() -> u32 { + configuration::Pallet::::config().max_validators_per_core.unwrap_or(5) + } + + /// Specify a mapping of core index/ para id to the number of dispute statements for the + /// corresponding dispute statement set. Note that if the number of disputes is not specified + /// it fallbacks to having a dispute per every validator. Additionally, an entry is not + /// guaranteed to have a dispute - it must line up with the cores marked as disputed as defined + /// in `Self::Build`. + #[cfg(not(feature = "runtime-benchmarks"))] + pub(crate) fn set_dispute_statements(mut self, m: BTreeMap) -> Self { + self.dispute_statements = m; + self + } + + /// Get the maximum number of validators per core. + fn max_validators_per_core(&self) -> u32 { + self.max_validators_per_core.unwrap_or(Self::fallback_max_validators_per_core()) + } + + /// Set maximum number of validators per core. + #[cfg(not(feature = "runtime-benchmarks"))] + pub(crate) fn set_max_validators_per_core(mut self, n: u32) -> Self { + self.max_validators_per_core = Some(n); + self + } + + /// Get the maximum number of cores we expect from this configuration. + pub(crate) fn max_cores(&self) -> u32 { + self.max_validators() / self.max_validators_per_core() + } + + /// Get the minimum number of validity votes in order for a backed candidate to be included. + #[cfg(feature = "runtime-benchmarks")] + pub(crate) fn fallback_min_validity_votes() -> u32 { + (Self::fallback_max_validators() / 2) + 1 + } + + /// Create para id, core index, and grab the associated group index from the scheduler pallet. + fn create_indexes(&self, seed: u32) -> (ParaId, CoreIndex, GroupIndex) { + let para_id = ParaId::from(seed); + let core_idx = CoreIndex(seed); + let group_idx = + scheduler::Pallet::::group_assigned_to_core(core_idx, self.block_number).unwrap(); + + (para_id, core_idx, group_idx) + } + + fn mock_head_data() -> HeadData { + let max_head_size = configuration::Pallet::::config().max_head_data_size; + HeadData(vec![0xFF; max_head_size as usize]) + } + + fn candidate_descriptor_mock() -> CandidateDescriptor { + CandidateDescriptor:: { + para_id: 0.into(), + relay_parent: Default::default(), + collator: CollatorId::from(sr25519::Public::from_raw([42u8; 32])), + persisted_validation_data_hash: Default::default(), + pov_hash: Default::default(), + erasure_root: Default::default(), + signature: CollatorSignature::from(sr25519::Signature([42u8; 64])), + para_head: Default::default(), + validation_code_hash: mock_validation_code().hash(), + } + } + + /// Create a mock of `CandidatePendingAvailability`. + fn candidate_availability_mock( + group_idx: GroupIndex, + core_idx: CoreIndex, + candidate_hash: CandidateHash, + availability_votes: BitVec, + ) -> inclusion::CandidatePendingAvailability> { + inclusion::CandidatePendingAvailability::>::new( + core_idx, // core + candidate_hash, // hash + Self::candidate_descriptor_mock(), // candidate descriptor + availability_votes, // availability votes + Default::default(), // backers + Zero::zero(), // relay parent + One::one(), // relay chain block this was backed in + group_idx, // backing group + ) + } + + /// Add `CandidatePendingAvailability` and `CandidateCommitments` to the relevant storage items. + /// + /// NOTE: the default `CandidateCommitments` used does not include any data that would lead to + /// heavy code paths in `enact_candidate`. But enact_candidates does return a weight which will + /// get taken into account. + fn add_availability( + para_id: ParaId, + core_idx: CoreIndex, + group_idx: GroupIndex, + availability_votes: BitVec, + candidate_hash: CandidateHash, + ) { + let candidate_availability = Self::candidate_availability_mock( + group_idx, + core_idx, + candidate_hash, + availability_votes, + ); + let commitments = CandidateCommitments:: { + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + head_data: Self::mock_head_data(), + processed_downward_messages: 0, + hrmp_watermark: 0u32.into(), + }; + inclusion::PendingAvailability::::insert(para_id, candidate_availability); + inclusion::PendingAvailabilityCommitments::::insert(¶_id, commitments); + } + + /// Create an `AvailabilityBitfield` where `concluding` is a map where each key is a core index + /// that is concluding and `cores` is the total number of cores in the system. + fn availability_bitvec(concluding: &BTreeMap, cores: u32) -> AvailabilityBitfield { + let mut bitfields = bitvec::bitvec![u8, bitvec::order::Lsb0; 0; 0]; + for i in 0..cores { + if concluding.get(&(i as u32)).is_some() { + bitfields.push(true); + } else { + bitfields.push(false) + } + } + + bitfields.into() + } + + /// Run to block number `to`, calling `initializer` `on_initialize` and `on_finalize` along the + /// way. + fn run_to_block(to: u32) { + let to = to.into(); + while frame_system::Pallet::::block_number() < to { + let b = frame_system::Pallet::::block_number(); + initializer::Pallet::::on_finalize(b); + + let b = b + One::one(); + frame_system::Pallet::::set_block_number(b); + initializer::Pallet::::on_initialize(b); + } + } + + /// Register `cores` count of parachains. + /// + /// Note that this must be called at least 2 sessions before the target session as there is a + /// n+2 session delay for the scheduled actions to take effect. + fn setup_para_ids(cores: u32) { + // make sure parachains exist prior to session change. + for i in 0..cores { + let para_id = ParaId::from(i as u32); + let validation_code = mock_validation_code(); + + paras::Pallet::::schedule_para_initialize( + para_id, + paras::ParaGenesisArgs { + genesis_head: Self::mock_head_data(), + validation_code: validation_code.clone(), + para_kind: ParaKind::Parachain, + }, + ) + .unwrap(); + paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + validation_code, + ) + .unwrap(); + } + } + + /// Generate validator key pairs and account ids. + fn generate_validator_pairs(validator_count: u32) -> Vec<(T::AccountId, ValidatorId)> { + (0..validator_count) + .map(|i| { + let public = ValidatorId::generate_pair(None); + + // The account Id is not actually used anywhere, just necessary to fulfill the + // expected type of the `validators` param of `test_trigger_on_new_session`. + let account: T::AccountId = account("validator", i, i); + (account, public) + }) + .collect() + } + + fn signing_context(&self) -> SigningContext { + SigningContext { + parent_hash: Self::header(self.block_number).hash(), + session_index: self.session, + } + } + + /// Create a bitvec of `validators` length with all yes votes. + fn validator_availability_votes_yes(validators: usize) -> BitVec { + // every validator confirms availability. + bitvec::bitvec![u8, bitvec::order::Lsb0; 1; validators as usize] + } + + /// Setup session 1 and create `self.validators_map` and `self.validators`. + fn setup_session( + mut self, + target_session: SessionIndex, + validators: Vec<(T::AccountId, ValidatorId)>, + total_cores: u32, + ) -> Self { + let mut block = 1; + for session in 0..=target_session { + initializer::Pallet::::test_trigger_on_new_session( + false, + session, + validators.iter().map(|(a, v)| (a, v.clone())), + None, + ); + block += 1; + Self::run_to_block(block); + } + + let block_number = BlockNumberFor::::from(block); + let header = Self::header(block_number); + + frame_system::Pallet::::reset_events(); + frame_system::Pallet::::initialize( + &header.number(), + &header.hash(), + &Digest { logs: Vec::new() }, + ); + + assert_eq!(>::session_index(), target_session); + + // We need to refetch validators since they have been shuffled. + let validators_shuffled = session_info::Pallet::::session_info(target_session) + .unwrap() + .validators + .clone(); + + self.validators = Some(validators_shuffled); + self.block_number = block_number; + self.session = target_session; + assert_eq!(paras::Pallet::::parachains().len(), total_cores as usize); + + self + } + + /// Create a `UncheckedSigned for each validator where each core in + /// `concluding_cores` is fully available. Additionally set up storage such that each + /// `concluding_cores`is pending becoming fully available so the generated bitfields will be + /// to the cores successfully being freed from the candidates being marked as available. + fn create_availability_bitfields( + &self, + concluding_cores: &BTreeMap, + total_cores: u32, + ) -> Vec> { + let validators = + self.validators.as_ref().expect("must have some validators prior to calling"); + + let availability_bitvec = Self::availability_bitvec(concluding_cores, total_cores); + + let bitfields: Vec> = validators + .iter() + .enumerate() + .map(|(i, public)| { + let unchecked_signed = UncheckedSigned::::benchmark_sign( + public, + availability_bitvec.clone(), + &self.signing_context(), + ValidatorIndex(i as u32), + ); + + unchecked_signed + }) + .collect(); + + for (seed, _) in concluding_cores.iter() { + // make sure the candidates that will be concluding are marked as pending availability. + let (para_id, core_idx, group_idx) = self.create_indexes(*seed); + Self::add_availability( + para_id, + core_idx, + group_idx, + Self::validator_availability_votes_yes(validators.len()), + CandidateHash(H256::from(byte32_slice_from(*seed))), + ); + } + + bitfields + } + + /// Create backed candidates for `cores_with_backed_candidates`. You need these cores to be + /// scheduled _within_ paras inherent, which requires marking the available bitfields as fully + /// available. + /// - `cores_with_backed_candidates` Mapping of `para_id`/`core_idx`/`group_idx` seed to number + /// of + /// validity votes. + fn create_backed_candidates( + &self, + cores_with_backed_candidates: &BTreeMap, + includes_code_upgrade: Option, + ) -> Vec> { + let validators = + self.validators.as_ref().expect("must have some validators prior to calling"); + let config = configuration::Pallet::::config(); + + cores_with_backed_candidates + .iter() + .map(|(seed, num_votes)| { + assert!(*num_votes <= validators.len() as u32); + let (para_id, _core_idx, group_idx) = self.create_indexes(*seed); + + // This generates a pair and adds it to the keystore, returning just the public. + let collator_public = CollatorId::generate_pair(None); + let header = Self::header(self.block_number); + let relay_parent = header.hash(); + let head_data = Self::mock_head_data(); + let persisted_validation_data_hash = PersistedValidationData:: { + parent_head: head_data.clone(), + relay_parent_number: self.relay_parent_number(), + relay_parent_storage_root: Default::default(), + max_pov_size: config.max_pov_size, + } + .hash(); + + let pov_hash = Default::default(); + let validation_code_hash = mock_validation_code().hash(); + let payload = collator_signature_payload( + &relay_parent, + ¶_id, + &persisted_validation_data_hash, + &pov_hash, + &validation_code_hash, + ); + let signature = collator_public.sign(&payload).unwrap(); + + // Set the head data so it can be used while validating the signatures on the + // candidate receipt. + paras::Pallet::::heads_insert(¶_id, head_data.clone()); + + let mut past_code_meta = paras::ParaPastCodeMeta::>::default(); + past_code_meta.note_replacement(0u32.into(), 0u32.into()); + + let group_validators = scheduler::Pallet::::group_validators(group_idx).unwrap(); + + let candidate = CommittedCandidateReceipt:: { + descriptor: CandidateDescriptor:: { + para_id, + relay_parent, + collator: collator_public, + persisted_validation_data_hash, + pov_hash, + erasure_root: Default::default(), + signature, + para_head: head_data.hash(), + validation_code_hash, + }, + commitments: CandidateCommitments:: { + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: includes_code_upgrade + .map(|v| ValidationCode(vec![42u8; v as usize])), + head_data, + processed_downward_messages: 0, + hrmp_watermark: self.relay_parent_number(), + }, + }; + + let candidate_hash = candidate.hash(); + + let validity_votes: Vec<_> = group_validators + .iter() + .take(*num_votes as usize) + .map(|val_idx| { + let public = validators.get(*val_idx).unwrap(); + let sig = UncheckedSigned::::benchmark_sign( + public, + CompactStatement::Valid(candidate_hash), + &self.signing_context(), + *val_idx, + ) + .benchmark_signature(); + + ValidityAttestation::Explicit(sig.clone()) + }) + .collect(); + + BackedCandidate:: { + candidate, + validity_votes, + validator_indices: bitvec::bitvec![u8, bitvec::order::Lsb0; 1; group_validators.len()], + } + }) + .collect() + } + + /// Fill cores `start..last` with dispute statement sets. The statement sets will have 3/4th of + /// votes be valid, and 1/4th of votes be invalid. + fn create_disputes( + &self, + start: u32, + last: u32, + dispute_sessions: impl AsRef<[u32]>, + ) -> Vec { + let validators = + self.validators.as_ref().expect("must have some validators prior to calling"); + + let dispute_sessions = dispute_sessions.as_ref(); + (start..last) + .map(|seed| { + let dispute_session_idx = (seed - start) as usize; + let session = dispute_sessions + .get(dispute_session_idx) + .cloned() + .unwrap_or(self.target_session); + + let (para_id, core_idx, group_idx) = self.create_indexes(seed); + let candidate_hash = CandidateHash(H256::from(byte32_slice_from(seed))); + let relay_parent = H256::from(byte32_slice_from(seed)); + + Self::add_availability( + para_id, + core_idx, + group_idx, + Self::validator_availability_votes_yes(validators.len()), + candidate_hash, + ); + + let statements_len = + self.dispute_statements.get(&seed).cloned().unwrap_or(validators.len() as u32); + let statements = (0..statements_len) + .map(|validator_index| { + let validator_public = &validators.get(ValidatorIndex::from(validator_index)).expect("Test case is not borked. `ValidatorIndex` out of bounds of `ValidatorId`s."); + + // We need dispute statements on each side. And we don't want a revert log + // so we make sure that we have a super majority with valid statements. + let dispute_statement = if validator_index % 4 == 0 { + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit) + } else if validator_index < 3 { + // Set two votes as backing for the dispute set to be accepted + DisputeStatement::Valid( + ValidDisputeStatementKind::BackingValid(relay_parent) + ) + } else { + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit) + }; + let data = dispute_statement.payload_data(candidate_hash, session); + let statement_sig = validator_public.sign(&data).unwrap(); + + (dispute_statement, ValidatorIndex(validator_index), statement_sig) + }) + .collect(); + + DisputeStatementSet { candidate_hash: candidate_hash, session, statements } + }) + .collect() + } + + /// Build a scenario for testing or benchmarks. + /// + /// Note that this API only allows building scenarios where the `backed_and_concluding_cores` + /// are mutually exclusive with the cores for disputes. So + /// `backed_and_concluding_cores.len() + dispute_sessions.len()` must be less than the max + /// number of cores. + pub(crate) fn build(self) -> Bench { + // Make sure relevant storage is cleared. This is just to get the asserts to work when + // running tests because it seems the storage is not cleared in between. + #[allow(deprecated)] + inclusion::PendingAvailabilityCommitments::::remove_all(None); + #[allow(deprecated)] + inclusion::PendingAvailability::::remove_all(None); + + // We don't allow a core to have both disputes and be marked fully available at this block. + let cores = self.max_cores(); + let used_cores = + (self.dispute_sessions.len() + self.backed_and_concluding_cores.len()) as u32; + assert!(used_cores <= cores); + + // NOTE: there is an n+2 session delay for these actions to take effect. + // We are currently in Session 0, so these changes will take effect in Session 2. + Self::setup_para_ids(used_cores); + + let validator_ids = Self::generate_validator_pairs(self.max_validators()); + let target_session = SessionIndex::from(self.target_session); + let builder = self.setup_session(target_session, validator_ids, used_cores); + + let bitfields = + builder.create_availability_bitfields(&builder.backed_and_concluding_cores, used_cores); + let backed_candidates = builder + .create_backed_candidates(&builder.backed_and_concluding_cores, builder.code_upgrade); + + let disputes = builder.create_disputes( + builder.backed_and_concluding_cores.len() as u32, + used_cores, + builder.dispute_sessions.as_slice(), + ); + + assert_eq!( + inclusion::PendingAvailabilityCommitments::::iter().count(), + used_cores as usize, + ); + assert_eq!(inclusion::PendingAvailability::::iter().count(), used_cores as usize,); + + // Mark all the used cores as occupied. We expect that there are + // `backed_and_concluding_cores` that are pending availability and that there are + // `used_cores - backed_and_concluding_cores ` which are about to be disputed. + let now = >::block_number() + One::one(); + let cores = (0..used_cores) + .into_iter() + .map(|i| { + let AssignmentProviderConfig { ttl, .. } = + scheduler::Pallet::::assignment_provider_config(CoreIndex(i)); + CoreOccupied::Paras(ParasEntry::new( + Assignment::new(ParaId::from(i as u32)), + now + ttl, + )) + }) + .collect(); + scheduler::AvailabilityCores::::set(cores); + + Bench:: { + data: ParachainsInherentData { + bitfields, + backed_candidates, + disputes, + parent_header: Self::header(builder.block_number), + }, + _session: target_session, + _block_number: builder.block_number, + } + } +} diff --git a/polkadot/runtime/parachains/src/configuration.rs b/polkadot/runtime/parachains/src/configuration.rs new file mode 100644 index 0000000000000000000000000000000000000000..accc01a2b18015856a67860fb32c299953aafd21 --- /dev/null +++ b/polkadot/runtime/parachains/src/configuration.rs @@ -0,0 +1,1343 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Configuration manager for the Polkadot runtime parachains logic. +//! +//! Configuration can change only at session boundaries and is buffered until then. + +use crate::{inclusion::MAX_UPWARD_MESSAGE_SIZE_BOUND, shared}; +use frame_support::{pallet_prelude::*, DefaultNoBound}; +use frame_system::pallet_prelude::*; +use parity_scale_codec::{Decode, Encode}; +use polkadot_parachain::primitives::{MAX_HORIZONTAL_MESSAGE_NUM, MAX_UPWARD_MESSAGE_NUM}; +use primitives::{ + vstaging::AsyncBackingParams, Balance, ExecutorParams, SessionIndex, MAX_CODE_SIZE, + MAX_HEAD_DATA_SIZE, MAX_POV_SIZE, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, +}; +use sp_runtime::{traits::Zero, Perbill}; +use sp_std::prelude::*; + +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +pub mod migration; + +pub use pallet::*; + +const LOG_TARGET: &str = "runtime::configuration"; + +/// All configuration of the runtime with respect to paras. +#[derive( + Clone, + Encode, + Decode, + PartialEq, + sp_core::RuntimeDebug, + scale_info::TypeInfo, + serde::Serialize, + serde::Deserialize, +)] +pub struct HostConfiguration { + // NOTE: This structure is used by parachains via merkle proofs. Therefore, this struct + // requires special treatment. + // + // A parachain requested this struct can only depend on the subset of this struct. + // Specifically, only a first few fields can be depended upon. These fields cannot be changed + // without corresponding migration of the parachains. + /** + * The parameters that are required for the parachains. + */ + + /// The maximum validation code size, in bytes. + pub max_code_size: u32, + /// The maximum head-data size, in bytes. + pub max_head_data_size: u32, + /// Total number of individual messages allowed in the parachain -> relay-chain message queue. + pub max_upward_queue_count: u32, + /// Total size of messages allowed in the parachain -> relay-chain message queue before which + /// no further messages may be added to it. If it exceeds this then the queue may contain only + /// a single message. + pub max_upward_queue_size: u32, + /// The maximum size of an upward message that can be sent by a candidate. + /// + /// This parameter affects the size upper bound of the `CandidateCommitments`. + pub max_upward_message_size: u32, + /// The maximum number of messages that a candidate can contain. + /// + /// This parameter affects the size upper bound of the `CandidateCommitments`. + pub max_upward_message_num_per_candidate: u32, + /// The maximum number of outbound HRMP messages can be sent by a candidate. + /// + /// This parameter affects the upper bound of size of `CandidateCommitments`. + pub hrmp_max_message_num_per_candidate: u32, + /// The minimum period, in blocks, between which parachains can update their validation code. + /// + /// This number is used to prevent parachains from spamming the relay chain with validation + /// code upgrades. The only thing it controls is the number of blocks the + /// `UpgradeRestrictionSignal` is set for the parachain in question. + /// + /// If PVF pre-checking is enabled this should be greater than the maximum number of blocks + /// PVF pre-checking can take. Intuitively, this number should be greater than the duration + /// specified by [`pvf_voting_ttl`]. Unlike, [`pvf_voting_ttl`], this parameter uses blocks + /// as a unit. + #[cfg_attr(feature = "std", serde(alias = "validation_upgrade_frequency"))] + pub validation_upgrade_cooldown: BlockNumber, + /// The delay, in blocks, after which an upgrade of the validation code is applied. + /// + /// The upgrade for a parachain takes place when the first candidate which has relay-parent >= + /// the relay-chain block where the upgrade is scheduled. This block is referred as to + /// `expected_at`. + /// + /// `expected_at` is determined when the upgrade is scheduled. This happens when the candidate + /// that signals the upgrade is enacted. Right now, the relay-parent block number of the + /// candidate scheduling the upgrade is used to determine the `expected_at`. This may change in + /// the future with [#4601]. + /// + /// When PVF pre-checking is enabled, the upgrade is scheduled only after the PVF pre-check has + /// been completed. + /// + /// Note, there are situations in which `expected_at` in the past. For example, if + /// [`paras_availability_period`] is less than the delay set by + /// this field or if PVF pre-check took more time than the delay. In such cases, the upgrade is + /// further at the earliest possible time determined by [`minimum_validation_upgrade_delay`]. + /// + /// The rationale for this delay has to do with relay-chain reversions. In case there is an + /// invalid candidate produced with the new version of the code, then the relay-chain can + /// revert [`validation_upgrade_delay`] many blocks back and still find the new code in the + /// storage by hash. + /// + /// [#4601]: https://github.com/paritytech/polkadot/issues/4601 + pub validation_upgrade_delay: BlockNumber, + /// Asynchronous backing parameters. + pub async_backing_params: AsyncBackingParams, + + /** + * The parameters that are not essential, but still may be of interest for parachains. + */ + + /// The maximum POV block size, in bytes. + pub max_pov_size: u32, + /// The maximum size of a message that can be put in a downward message queue. + /// + /// Since we require receiving at least one DMP message the obvious upper bound of the size is + /// the PoV size. Of course, there is a lot of other different things that a parachain may + /// decide to do with its PoV so this value in practice will be picked as a fraction of the PoV + /// size. + pub max_downward_message_size: u32, + /// The maximum number of outbound HRMP channels a parachain is allowed to open. + pub hrmp_max_parachain_outbound_channels: u32, + /// The deposit that the sender should provide for opening an HRMP channel. + pub hrmp_sender_deposit: Balance, + /// The deposit that the recipient should provide for accepting opening an HRMP channel. + pub hrmp_recipient_deposit: Balance, + /// The maximum number of messages allowed in an HRMP channel at once. + pub hrmp_channel_max_capacity: u32, + /// The maximum total size of messages in bytes allowed in an HRMP channel at once. + pub hrmp_channel_max_total_size: u32, + /// The maximum number of inbound HRMP channels a parachain is allowed to accept. + pub hrmp_max_parachain_inbound_channels: u32, + /// The maximum size of a message that could ever be put into an HRMP channel. + /// + /// This parameter affects the upper bound of size of `CandidateCommitments`. + pub hrmp_channel_max_message_size: u32, + /// The executor environment parameters + pub executor_params: ExecutorParams, + + /** + * Parameters that will unlikely be needed by parachains. + */ + + /// How long to keep code on-chain, in blocks. This should be sufficiently long that disputes + /// have concluded. + pub code_retention_period: BlockNumber, + /// The amount of execution cores to dedicate to on demand execution. + pub on_demand_cores: u32, + /// The number of retries that a on demand author has to submit their block. + pub on_demand_retries: u32, + /// The maximum queue size of the pay as you go module. + pub on_demand_queue_max_size: u32, + /// The target utilization of the spot price queue in percentages. + pub on_demand_target_queue_utilization: Perbill, + /// How quickly the fee rises in reaction to increased utilization. + /// The lower the number the slower the increase. + pub on_demand_fee_variability: Perbill, + /// The minimum amount needed to claim a slot in the spot pricing queue. + pub on_demand_base_fee: Balance, + /// The number of blocks an on demand claim stays in the scheduler's claimqueue before getting + /// cleared. This number should go reasonably higher than the number of blocks in the async + /// backing lookahead. + pub on_demand_ttl: BlockNumber, + /// How often parachain groups should be rotated across parachains. + /// + /// Must be non-zero. + pub group_rotation_frequency: BlockNumber, + /// The availability period, in blocks. This is the amount of blocks + /// after inclusion that validators have to make the block available and signal its + /// availability to the chain. + /// + /// Must be at least 1. + pub paras_availability_period: BlockNumber, + /// The amount of blocks ahead to schedule paras. + pub scheduling_lookahead: u32, + /// The maximum number of validators to have per core. + /// + /// `None` means no maximum. + pub max_validators_per_core: Option, + /// The maximum number of validators to use for parachain consensus, period. + /// + /// `None` means no maximum. + pub max_validators: Option, + /// The amount of sessions to keep for disputes. + pub dispute_period: SessionIndex, + /// How long after dispute conclusion to accept statements. + pub dispute_post_conclusion_acceptance_period: BlockNumber, + /// The amount of consensus slots that must pass between submitting an assignment and + /// submitting an approval vote before a validator is considered a no-show. + /// + /// Must be at least 1. + pub no_show_slots: u32, + /// The number of delay tranches in total. + pub n_delay_tranches: u32, + /// The width of the zeroth delay tranche for approval assignments. This many delay tranches + /// beyond 0 are all consolidated to form a wide 0 tranche. + pub zeroth_delay_tranche_width: u32, + /// The number of validators needed to approve a block. + pub needed_approvals: u32, + /// The number of samples to do of the `RelayVRFModulo` approval assignment criterion. + pub relay_vrf_modulo_samples: u32, + /// If an active PVF pre-checking vote observes this many number of sessions it gets + /// automatically rejected. + /// + /// 0 means PVF pre-checking will be rejected on the first observed session unless the voting + /// gained supermajority before that the session change. + pub pvf_voting_ttl: SessionIndex, + /// The lower bound number of blocks an upgrade can be scheduled. + /// + /// Typically, upgrade gets scheduled [`validation_upgrade_delay`] relay-chain blocks after + /// the relay-parent of the parablock that signalled the validation code upgrade. However, + /// in the case a pre-checking voting was concluded in a longer duration the upgrade will be + /// scheduled to the next block. + /// + /// That can disrupt parachain inclusion. Specifically, it will make the blocks that were + /// already backed invalid. + /// + /// To prevent that, we introduce the minimum number of blocks after which the upgrade can be + /// scheduled. This number is controlled by this field. + /// + /// This value should be greater than [`paras_availability_period`]. + pub minimum_validation_upgrade_delay: BlockNumber, +} + +impl> Default for HostConfiguration { + fn default() -> Self { + Self { + async_backing_params: AsyncBackingParams { + max_candidate_depth: 0, + allowed_ancestry_len: 0, + }, + group_rotation_frequency: 1u32.into(), + paras_availability_period: 1u32.into(), + no_show_slots: 1u32.into(), + validation_upgrade_cooldown: Default::default(), + validation_upgrade_delay: 2u32.into(), + code_retention_period: Default::default(), + max_code_size: Default::default(), + max_pov_size: Default::default(), + max_head_data_size: Default::default(), + on_demand_cores: Default::default(), + on_demand_retries: Default::default(), + scheduling_lookahead: 1, + max_validators_per_core: Default::default(), + max_validators: None, + dispute_period: 6, + dispute_post_conclusion_acceptance_period: 100.into(), + n_delay_tranches: Default::default(), + zeroth_delay_tranche_width: Default::default(), + needed_approvals: Default::default(), + relay_vrf_modulo_samples: Default::default(), + max_upward_queue_count: Default::default(), + max_upward_queue_size: Default::default(), + max_downward_message_size: Default::default(), + max_upward_message_size: Default::default(), + max_upward_message_num_per_candidate: Default::default(), + hrmp_sender_deposit: Default::default(), + hrmp_recipient_deposit: Default::default(), + hrmp_channel_max_capacity: Default::default(), + hrmp_channel_max_total_size: Default::default(), + hrmp_max_parachain_inbound_channels: Default::default(), + hrmp_channel_max_message_size: Default::default(), + hrmp_max_parachain_outbound_channels: Default::default(), + hrmp_max_message_num_per_candidate: Default::default(), + pvf_voting_ttl: 2u32.into(), + minimum_validation_upgrade_delay: 2.into(), + executor_params: Default::default(), + on_demand_queue_max_size: ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, + on_demand_base_fee: 10_000_000u128, + on_demand_fee_variability: Perbill::from_percent(3), + on_demand_target_queue_utilization: Perbill::from_percent(25), + on_demand_ttl: 5u32.into(), + } + } +} + +/// Enumerates the possible inconsistencies of `HostConfiguration`. +#[derive(Debug)] +pub enum InconsistentError { + /// `group_rotation_frequency` is set to zero. + ZeroGroupRotationFrequency, + /// `paras_availability_period` is set to zero. + ZeroParasAvailabilityPeriod, + /// `no_show_slots` is set to zero. + ZeroNoShowSlots, + /// `max_code_size` exceeds the hard limit of `MAX_CODE_SIZE`. + MaxCodeSizeExceedHardLimit { max_code_size: u32 }, + /// `max_head_data_size` exceeds the hard limit of `MAX_HEAD_DATA_SIZE`. + MaxHeadDataSizeExceedHardLimit { max_head_data_size: u32 }, + /// `max_pov_size` exceeds the hard limit of `MAX_POV_SIZE`. + MaxPovSizeExceedHardLimit { max_pov_size: u32 }, + /// `minimum_validation_upgrade_delay` is less than `paras_availability_period`. + MinimumValidationUpgradeDelayLessThanChainAvailabilityPeriod { + minimum_validation_upgrade_delay: BlockNumber, + paras_availability_period: BlockNumber, + }, + /// `validation_upgrade_delay` is less than or equal 1. + ValidationUpgradeDelayIsTooLow { validation_upgrade_delay: BlockNumber }, + /// Maximum UMP message size ([`MAX_UPWARD_MESSAGE_SIZE_BOUND`]) exceeded. + MaxUpwardMessageSizeExceeded { max_message_size: u32 }, + /// Maximum HRMP message num ([`MAX_HORIZONTAL_MESSAGE_NUM`]) exceeded. + MaxHorizontalMessageNumExceeded { max_message_num: u32 }, + /// Maximum UMP message num ([`MAX_UPWARD_MESSAGE_NUM`]) exceeded. + MaxUpwardMessageNumExceeded { max_message_num: u32 }, + /// Maximum number of HRMP outbound channels exceeded. + MaxHrmpOutboundChannelsExceeded, + /// Maximum number of HRMP inbound channels exceeded. + MaxHrmpInboundChannelsExceeded, +} + +impl HostConfiguration +where + BlockNumber: Zero + PartialOrd + sp_std::fmt::Debug + Clone + From, +{ + /// Checks that this instance is consistent with the requirements on each individual member. + /// + /// # Errors + /// + /// This function returns an error if the configuration is inconsistent. + pub fn check_consistency(&self) -> Result<(), InconsistentError> { + use InconsistentError::*; + + if self.group_rotation_frequency.is_zero() { + return Err(ZeroGroupRotationFrequency) + } + + if self.paras_availability_period.is_zero() { + return Err(ZeroParasAvailabilityPeriod) + } + + if self.no_show_slots.is_zero() { + return Err(ZeroNoShowSlots) + } + + if self.max_code_size > MAX_CODE_SIZE { + return Err(MaxCodeSizeExceedHardLimit { max_code_size: self.max_code_size }) + } + + if self.max_head_data_size > MAX_HEAD_DATA_SIZE { + return Err(MaxHeadDataSizeExceedHardLimit { + max_head_data_size: self.max_head_data_size, + }) + } + + if self.max_pov_size > MAX_POV_SIZE { + return Err(MaxPovSizeExceedHardLimit { max_pov_size: self.max_pov_size }) + } + + if self.minimum_validation_upgrade_delay <= self.paras_availability_period { + return Err(MinimumValidationUpgradeDelayLessThanChainAvailabilityPeriod { + minimum_validation_upgrade_delay: self.minimum_validation_upgrade_delay.clone(), + paras_availability_period: self.paras_availability_period.clone(), + }) + } + + if self.validation_upgrade_delay <= 1.into() { + return Err(ValidationUpgradeDelayIsTooLow { + validation_upgrade_delay: self.validation_upgrade_delay.clone(), + }) + } + + if self.max_upward_message_size > crate::inclusion::MAX_UPWARD_MESSAGE_SIZE_BOUND { + return Err(MaxUpwardMessageSizeExceeded { + max_message_size: self.max_upward_message_size, + }) + } + + if self.hrmp_max_message_num_per_candidate > MAX_HORIZONTAL_MESSAGE_NUM { + return Err(MaxHorizontalMessageNumExceeded { + max_message_num: self.hrmp_max_message_num_per_candidate, + }) + } + + if self.max_upward_message_num_per_candidate > MAX_UPWARD_MESSAGE_NUM { + return Err(MaxUpwardMessageNumExceeded { + max_message_num: self.max_upward_message_num_per_candidate, + }) + } + + if self.hrmp_max_parachain_outbound_channels > crate::hrmp::HRMP_MAX_OUTBOUND_CHANNELS_BOUND + { + return Err(MaxHrmpOutboundChannelsExceeded) + } + + if self.hrmp_max_parachain_inbound_channels > crate::hrmp::HRMP_MAX_INBOUND_CHANNELS_BOUND { + return Err(MaxHrmpInboundChannelsExceeded) + } + + Ok(()) + } + + /// Checks that this instance is consistent with the requirements on each individual member. + /// + /// # Panics + /// + /// This function panics if the configuration is inconsistent. + pub fn panic_if_not_consistent(&self) { + if let Err(err) = self.check_consistency() { + panic!("Host configuration is inconsistent: {:?}\nCfg:\n{:#?}", err, self); + } + } +} + +pub trait WeightInfo { + fn set_config_with_block_number() -> Weight; + fn set_config_with_u32() -> Weight; + fn set_config_with_option_u32() -> Weight; + fn set_config_with_balance() -> Weight; + fn set_hrmp_open_request_ttl() -> Weight; + fn set_config_with_executor_params() -> Weight; + fn set_config_with_perbill() -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn set_config_with_block_number() -> Weight { + Weight::MAX + } + fn set_config_with_u32() -> Weight { + Weight::MAX + } + fn set_config_with_option_u32() -> Weight { + Weight::MAX + } + fn set_config_with_balance() -> Weight { + Weight::MAX + } + fn set_hrmp_open_request_ttl() -> Weight { + Weight::MAX + } + fn set_config_with_executor_params() -> Weight { + Weight::MAX + } + fn set_config_with_perbill() -> Weight { + Weight::MAX + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + /// The current storage version. + /// + /// v0-v1: + /// v1-v2: + /// v2-v3: + /// v3-v4: + /// v4-v5: + /// + + /// + + /// v5-v6: (remove UMP dispatch queue) + /// v6-v7: + /// v7-v8: + const STORAGE_VERSION: StorageVersion = StorageVersion::new(8); + + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + shared::Config { + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::error] + pub enum Error { + /// The new value for a configuration parameter is invalid. + InvalidNewValue, + } + + /// The active configuration for the current session. + #[pallet::storage] + #[pallet::whitelist_storage] + #[pallet::getter(fn config)] + pub(crate) type ActiveConfig = + StorageValue<_, HostConfiguration>, ValueQuery>; + + /// Pending configuration changes. + /// + /// This is a list of configuration changes, each with a session index at which it should + /// be applied. + /// + /// The list is sorted ascending by session index. Also, this list can only contain at most + /// 2 items: for the next session and for the `scheduled_session`. + #[pallet::storage] + pub(crate) type PendingConfigs = + StorageValue<_, Vec<(SessionIndex, HostConfiguration>)>, ValueQuery>; + + /// If this is set, then the configuration setters will bypass the consistency checks. This + /// is meant to be used only as the last resort. + #[pallet::storage] + pub(crate) type BypassConsistencyCheck = StorageValue<_, bool, ValueQuery>; + + #[pallet::genesis_config] + #[derive(DefaultNoBound)] + pub struct GenesisConfig { + pub config: HostConfiguration>, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + self.config.panic_if_not_consistent(); + ActiveConfig::::put(&self.config); + } + } + + #[pallet::call] + impl Pallet { + /// Set the validation upgrade cooldown. + #[pallet::call_index(0)] + #[pallet::weight(( + T::WeightInfo::set_config_with_block_number(), + DispatchClass::Operational, + ))] + pub fn set_validation_upgrade_cooldown( + origin: OriginFor, + new: BlockNumberFor, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.validation_upgrade_cooldown = new; + }) + } + + /// Set the validation upgrade delay. + #[pallet::call_index(1)] + #[pallet::weight(( + T::WeightInfo::set_config_with_block_number(), + DispatchClass::Operational, + ))] + pub fn set_validation_upgrade_delay( + origin: OriginFor, + new: BlockNumberFor, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.validation_upgrade_delay = new; + }) + } + + /// Set the acceptance period for an included candidate. + #[pallet::call_index(2)] + #[pallet::weight(( + T::WeightInfo::set_config_with_block_number(), + DispatchClass::Operational, + ))] + pub fn set_code_retention_period( + origin: OriginFor, + new: BlockNumberFor, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.code_retention_period = new; + }) + } + + /// Set the max validation code size for incoming upgrades. + #[pallet::call_index(3)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_max_code_size(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.max_code_size = new; + }) + } + + /// Set the max POV block size for incoming upgrades. + #[pallet::call_index(4)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_max_pov_size(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.max_pov_size = new; + }) + } + + /// Set the max head data size for paras. + #[pallet::call_index(5)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_max_head_data_size(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.max_head_data_size = new; + }) + } + + /// Set the number of on demand execution cores. + #[pallet::call_index(6)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_on_demand_cores(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.on_demand_cores = new; + }) + } + + /// Set the number of retries for a particular on demand. + #[pallet::call_index(7)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_on_demand_retries(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.on_demand_retries = new; + }) + } + + /// Set the parachain validator-group rotation frequency + #[pallet::call_index(8)] + #[pallet::weight(( + T::WeightInfo::set_config_with_block_number(), + DispatchClass::Operational, + ))] + pub fn set_group_rotation_frequency( + origin: OriginFor, + new: BlockNumberFor, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.group_rotation_frequency = new; + }) + } + + /// Set the availability period for paras. + #[pallet::call_index(9)] + #[pallet::weight(( + T::WeightInfo::set_config_with_block_number(), + DispatchClass::Operational, + ))] + pub fn set_paras_availability_period( + origin: OriginFor, + new: BlockNumberFor, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.paras_availability_period = new; + }) + } + + /// Set the scheduling lookahead, in expected number of blocks at peak throughput. + #[pallet::call_index(11)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_scheduling_lookahead(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.scheduling_lookahead = new; + }) + } + + /// Set the maximum number of validators to assign to any core. + #[pallet::call_index(12)] + #[pallet::weight(( + T::WeightInfo::set_config_with_option_u32(), + DispatchClass::Operational, + ))] + pub fn set_max_validators_per_core( + origin: OriginFor, + new: Option, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.max_validators_per_core = new; + }) + } + + /// Set the maximum number of validators to use in parachain consensus. + #[pallet::call_index(13)] + #[pallet::weight(( + T::WeightInfo::set_config_with_option_u32(), + DispatchClass::Operational, + ))] + pub fn set_max_validators(origin: OriginFor, new: Option) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.max_validators = new; + }) + } + + /// Set the dispute period, in number of sessions to keep for disputes. + #[pallet::call_index(14)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_dispute_period(origin: OriginFor, new: SessionIndex) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.dispute_period = new; + }) + } + + /// Set the dispute post conclusion acceptance period. + #[pallet::call_index(15)] + #[pallet::weight(( + T::WeightInfo::set_config_with_block_number(), + DispatchClass::Operational, + ))] + pub fn set_dispute_post_conclusion_acceptance_period( + origin: OriginFor, + new: BlockNumberFor, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.dispute_post_conclusion_acceptance_period = new; + }) + } + + /// Set the no show slots, in number of number of consensus slots. + /// Must be at least 1. + #[pallet::call_index(18)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_no_show_slots(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.no_show_slots = new; + }) + } + + /// Set the total number of delay tranches. + #[pallet::call_index(19)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_n_delay_tranches(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.n_delay_tranches = new; + }) + } + + /// Set the zeroth delay tranche width. + #[pallet::call_index(20)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_zeroth_delay_tranche_width(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.zeroth_delay_tranche_width = new; + }) + } + + /// Set the number of validators needed to approve a block. + #[pallet::call_index(21)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_needed_approvals(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.needed_approvals = new; + }) + } + + /// Set the number of samples to do of the `RelayVRFModulo` approval assignment criterion. + #[pallet::call_index(22)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_relay_vrf_modulo_samples(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.relay_vrf_modulo_samples = new; + }) + } + + /// Sets the maximum items that can present in a upward dispatch queue at once. + #[pallet::call_index(23)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_max_upward_queue_count(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.max_upward_queue_count = new; + }) + } + + /// Sets the maximum total size of items that can present in a upward dispatch queue at + /// once. + #[pallet::call_index(24)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_max_upward_queue_size(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + ensure!(new <= MAX_UPWARD_MESSAGE_SIZE_BOUND, Error::::InvalidNewValue); + + Self::schedule_config_update(|config| { + config.max_upward_queue_size = new; + }) + } + + /// Set the critical downward message size. + #[pallet::call_index(25)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_max_downward_message_size(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.max_downward_message_size = new; + }) + } + + /// Sets the maximum size of an upward message that can be sent by a candidate. + #[pallet::call_index(27)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_max_upward_message_size(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.max_upward_message_size = new; + }) + } + + /// Sets the maximum number of messages that a candidate can contain. + #[pallet::call_index(28)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_max_upward_message_num_per_candidate( + origin: OriginFor, + new: u32, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.max_upward_message_num_per_candidate = new; + }) + } + + /// Sets the number of sessions after which an HRMP open channel request expires. + #[pallet::call_index(29)] + #[pallet::weight(( + T::WeightInfo::set_hrmp_open_request_ttl(), + DispatchClass::Operational, + ))] + // Deprecated, but is not marked as such, because that would trigger warnings coming from + // the macro. + pub fn set_hrmp_open_request_ttl(_origin: OriginFor, _new: u32) -> DispatchResult { + Err("this doesn't have any effect".into()) + } + + /// Sets the amount of funds that the sender should provide for opening an HRMP channel. + #[pallet::call_index(30)] + #[pallet::weight(( + T::WeightInfo::set_config_with_balance(), + DispatchClass::Operational, + ))] + pub fn set_hrmp_sender_deposit(origin: OriginFor, new: Balance) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.hrmp_sender_deposit = new; + }) + } + + /// Sets the amount of funds that the recipient should provide for accepting opening an HRMP + /// channel. + #[pallet::call_index(31)] + #[pallet::weight(( + T::WeightInfo::set_config_with_balance(), + DispatchClass::Operational, + ))] + pub fn set_hrmp_recipient_deposit(origin: OriginFor, new: Balance) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.hrmp_recipient_deposit = new; + }) + } + + /// Sets the maximum number of messages allowed in an HRMP channel at once. + #[pallet::call_index(32)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_hrmp_channel_max_capacity(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.hrmp_channel_max_capacity = new; + }) + } + + /// Sets the maximum total size of messages in bytes allowed in an HRMP channel at once. + #[pallet::call_index(33)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_hrmp_channel_max_total_size(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.hrmp_channel_max_total_size = new; + }) + } + + /// Sets the maximum number of inbound HRMP channels a parachain is allowed to accept. + #[pallet::call_index(34)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_hrmp_max_parachain_inbound_channels( + origin: OriginFor, + new: u32, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.hrmp_max_parachain_inbound_channels = new; + }) + } + + /// Sets the maximum size of a message that could ever be put into an HRMP channel. + #[pallet::call_index(36)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_hrmp_channel_max_message_size(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.hrmp_channel_max_message_size = new; + }) + } + + /// Sets the maximum number of outbound HRMP channels a parachain is allowed to open. + #[pallet::call_index(37)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_hrmp_max_parachain_outbound_channels( + origin: OriginFor, + new: u32, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.hrmp_max_parachain_outbound_channels = new; + }) + } + + /// Sets the maximum number of outbound HRMP messages can be sent by a candidate. + #[pallet::call_index(39)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_hrmp_max_message_num_per_candidate( + origin: OriginFor, + new: u32, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.hrmp_max_message_num_per_candidate = new; + }) + } + + /// Set the number of session changes after which a PVF pre-checking voting is rejected. + #[pallet::call_index(42)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_pvf_voting_ttl(origin: OriginFor, new: SessionIndex) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.pvf_voting_ttl = new; + }) + } + + /// Sets the minimum delay between announcing the upgrade block for a parachain until the + /// upgrade taking place. + /// + /// See the field documentation for information and constraints for the new value. + #[pallet::call_index(43)] + #[pallet::weight(( + T::WeightInfo::set_config_with_block_number(), + DispatchClass::Operational, + ))] + pub fn set_minimum_validation_upgrade_delay( + origin: OriginFor, + new: BlockNumberFor, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.minimum_validation_upgrade_delay = new; + }) + } + + /// Setting this to true will disable consistency checks for the configuration setters. + /// Use with caution. + #[pallet::call_index(44)] + #[pallet::weight(( + T::DbWeight::get().writes(1), + DispatchClass::Operational, + ))] + pub fn set_bypass_consistency_check(origin: OriginFor, new: bool) -> DispatchResult { + ensure_root(origin)?; + BypassConsistencyCheck::::put(new); + Ok(()) + } + + /// Set the asynchronous backing parameters. + #[pallet::call_index(45)] + #[pallet::weight(( + T::WeightInfo::set_config_with_option_u32(), // The same size in bytes. + DispatchClass::Operational, + ))] + pub fn set_async_backing_params( + origin: OriginFor, + new: AsyncBackingParams, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.async_backing_params = new; + }) + } + + /// Set PVF executor parameters. + #[pallet::call_index(46)] + #[pallet::weight(( + T::WeightInfo::set_config_with_executor_params(), + DispatchClass::Operational, + ))] + pub fn set_executor_params(origin: OriginFor, new: ExecutorParams) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.executor_params = new; + }) + } + + /// Set the on demand (parathreads) base fee. + #[pallet::call_index(47)] + #[pallet::weight(( + T::WeightInfo::set_config_with_balance(), + DispatchClass::Operational, + ))] + pub fn set_on_demand_base_fee(origin: OriginFor, new: Balance) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.on_demand_base_fee = new; + }) + } + + /// Set the on demand (parathreads) fee variability. + #[pallet::call_index(48)] + #[pallet::weight(( + T::WeightInfo::set_config_with_perbill(), + DispatchClass::Operational, + ))] + pub fn set_on_demand_fee_variability(origin: OriginFor, new: Perbill) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.on_demand_fee_variability = new; + }) + } + + /// Set the on demand (parathreads) queue max size. + #[pallet::call_index(49)] + #[pallet::weight(( + T::WeightInfo::set_config_with_option_u32(), + DispatchClass::Operational, + ))] + pub fn set_on_demand_queue_max_size(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.on_demand_queue_max_size = new; + }) + } + /// Set the on demand (parathreads) fee variability. + #[pallet::call_index(50)] + #[pallet::weight(( + T::WeightInfo::set_config_with_perbill(), + DispatchClass::Operational, + ))] + pub fn set_on_demand_target_queue_utilization( + origin: OriginFor, + new: Perbill, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.on_demand_target_queue_utilization = new; + }) + } + /// Set the on demand (parathreads) ttl in the claimqueue. + #[pallet::call_index(51)] + #[pallet::weight(( + T::WeightInfo::set_config_with_block_number(), + DispatchClass::Operational + ))] + pub fn set_on_demand_ttl(origin: OriginFor, new: BlockNumberFor) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.on_demand_ttl = new; + }) + } + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn integrity_test() { + assert_eq!( + &ActiveConfig::::hashed_key(), + primitives::well_known_keys::ACTIVE_CONFIG, + "`well_known_keys::ACTIVE_CONFIG` doesn't match key of `ActiveConfig`! Make sure that the name of the\ + configuration pallet is `Configuration` in the runtime!", + ); + } + } +} + +/// A struct that holds the configuration that was active before the session change and optionally +/// a configuration that became active after the session change. +pub struct SessionChangeOutcome { + /// Previously active configuration. + pub prev_config: HostConfiguration, + /// If new configuration was applied during the session change, this is the new configuration. + pub new_config: Option>, +} + +impl Pallet { + /// Called by the initializer to initialize the configuration pallet. + pub(crate) fn initializer_initialize(_now: BlockNumberFor) -> Weight { + Weight::zero() + } + + /// Called by the initializer to finalize the configuration pallet. + pub(crate) fn initializer_finalize() {} + + /// Called by the initializer to note that a new session has started. + /// + /// Returns the configuration that was actual before the session change and the configuration + /// that became active after the session change. If there were no scheduled changes, both will + /// be the same. + pub(crate) fn initializer_on_new_session( + session_index: &SessionIndex, + ) -> SessionChangeOutcome> { + let pending_configs = >::get(); + let prev_config = ActiveConfig::::get(); + + // No pending configuration changes, so we're done. + if pending_configs.is_empty() { + return SessionChangeOutcome { prev_config, new_config: None } + } + + let (mut past_and_present, future) = pending_configs + .into_iter() + .partition::, _>(|&(apply_at_session, _)| apply_at_session <= *session_index); + + if past_and_present.len() > 1 { + // This should never happen since we schedule configuration changes only into the future + // sessions and this handler called for each session change. + log::error!( + target: LOG_TARGET, + "Skipping applying configuration changes scheduled sessions in the past", + ); + } + + let new_config = past_and_present.pop().map(|(_, config)| config); + if let Some(ref new_config) = new_config { + // Apply the new configuration. + ActiveConfig::::put(new_config); + } + + >::put(future); + + SessionChangeOutcome { prev_config, new_config } + } + + /// Return the session index that should be used for any future scheduled changes. + fn scheduled_session() -> SessionIndex { + shared::Pallet::::scheduled_session() + } + + /// Forcibly set the active config. This should be used with extreme care, and typically + /// only when enabling parachains runtime pallets for the first time on a chain which has + /// been running without them. + pub fn force_set_active_config(config: HostConfiguration>) { + ActiveConfig::::set(config); + } + + /// This function should be used to update members of the configuration. + /// + /// This function is used to update the configuration in a way that is safe. It will check the + /// resulting configuration and ensure that the update is valid. If the update is invalid, it + /// will check if the previous configuration was valid. If it was invalid, we proceed with + /// updating the configuration, giving a chance to recover from such a condition. + /// + /// The actual configuration change take place after a couple of sessions have passed. In case + /// this function is called more than once in a session, then the pending configuration change + /// will be updated and the changes will be applied at once. + // NOTE: Explicitly tell rustc not to inline this because otherwise heuristics note the incoming + // closure making it's attractive to inline. However, in this case, we will end up with lots of + // duplicated code (making this function to show up in the top of heaviest functions) only for + // the sake of essentially avoiding an indirect call. Doesn't worth it. + #[inline(never)] + pub(crate) fn schedule_config_update( + updater: impl FnOnce(&mut HostConfiguration>), + ) -> DispatchResult { + let mut pending_configs = >::get(); + + // 1. pending_configs = [] No pending configuration changes. + // + // That means we should use the active config as the base configuration. We will insert + // the new pending configuration as (cur+2, new_config) into the list. + // + // 2. pending_configs = [(cur+2, X)] There is a configuration that is pending for the + // scheduled session. + // + // We will use X as the base configuration. We can update the pending configuration X + // directly. + // + // 3. pending_configs = [(cur+1, X)] There is a pending configuration scheduled and it will + // be applied in the next session. + // + // We will use X as the base configuration. We need to schedule a new configuration + // change for the `scheduled_session` and use X as the base for the new configuration. + // + // 4. pending_configs = [(cur+1, X), (cur+2, Y)] There is a pending configuration change in + // the next session and for the scheduled session. Due to case №3, we can be sure that Y + // is based on top of X. This means we can use Y as the base configuration and update Y + // directly. + // + // There cannot be (cur, X) because those are applied in the session change handler for the + // current session. + + // First, we need to decide what we should use as the base configuration. + let mut base_config = pending_configs + .last() + .map(|(_, config)| config.clone()) + .unwrap_or_else(Self::config); + let base_config_consistent = base_config.check_consistency().is_ok(); + + // Now, we need to decide what the new configuration should be. + // We also move the `base_config` to `new_config` to empahsize that the base config was + // destroyed by the `updater`. + updater(&mut base_config); + let new_config = base_config; + + if BypassConsistencyCheck::::get() { + // This will emit a warning each configuration update if the consistency check is + // bypassed. This is an attempt to make sure the bypass is not accidentally left on. + log::warn!( + target: LOG_TARGET, + "Bypassing the consistency check for the configuration change!", + ); + } else if let Err(e) = new_config.check_consistency() { + if base_config_consistent { + // Base configuration is consistent and the new configuration is inconsistent. + // This means that the value set by the `updater` is invalid and we can return + // it as an error. + log::warn!( + target: LOG_TARGET, + "Configuration change rejected due to invalid configuration: {:?}", + e, + ); + return Err(Error::::InvalidNewValue.into()) + } else { + // The configuration was already broken, so we can as well proceed with the update. + // You cannot break something that is already broken. + // + // That will allow to call several functions and ultimately return the configuration + // into consistent state. + log::warn!( + target: LOG_TARGET, + "The new configuration is broken but the old is broken as well. Proceeding", + ); + } + } + + let scheduled_session = Self::scheduled_session(); + + if let Some(&mut (_, ref mut config)) = pending_configs + .iter_mut() + .find(|&&mut (apply_at_session, _)| apply_at_session >= scheduled_session) + { + *config = new_config; + } else { + // We are scheduling a new configuration change for the scheduled session. + pending_configs.push((scheduled_session, new_config)); + } + + >::put(pending_configs); + + Ok(()) + } +} diff --git a/polkadot/runtime/parachains/src/configuration/benchmarking.rs b/polkadot/runtime/parachains/src/configuration/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..d9d11ab56e496980e8090a99ed88452a351e970e --- /dev/null +++ b/polkadot/runtime/parachains/src/configuration/benchmarking.rs @@ -0,0 +1,57 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::configuration::*; +use frame_benchmarking::{benchmarks, BenchmarkError, BenchmarkResult}; +use frame_system::RawOrigin; +use primitives::{ExecutorParam, ExecutorParams, PvfExecTimeoutKind, PvfPrepTimeoutKind}; +use sp_runtime::traits::One; + +benchmarks! { + set_config_with_block_number {}: set_code_retention_period(RawOrigin::Root, One::one()) + + set_config_with_u32 {}: set_max_code_size(RawOrigin::Root, 100) + + set_config_with_option_u32 {}: set_max_validators(RawOrigin::Root, Some(10)) + + set_hrmp_open_request_ttl {}: { + Err(BenchmarkError::Override( + BenchmarkResult::from_weight(T::BlockWeights::get().max_block) + ))?; + } + + set_config_with_balance {}: set_hrmp_sender_deposit(RawOrigin::Root, 100_000_000_000) + + set_config_with_executor_params {}: set_executor_params(RawOrigin::Root, ExecutorParams::from(&[ + ExecutorParam::MaxMemoryPages(2080), + ExecutorParam::StackLogicalMax(65536), + ExecutorParam::StackNativeMax(256 * 1024 * 1024), + ExecutorParam::WasmExtBulkMemory, + ExecutorParam::PrecheckingMaxMemory(2 * 1024 * 1024 * 1024), + ExecutorParam::PvfPrepTimeout(PvfPrepTimeoutKind::Precheck, 60_000), + ExecutorParam::PvfPrepTimeout(PvfPrepTimeoutKind::Lenient, 360_000), + ExecutorParam::PvfExecTimeout(PvfExecTimeoutKind::Backing, 2_000), + ExecutorParam::PvfExecTimeout(PvfExecTimeoutKind::Approval, 12_000), + ][..])) + + set_config_with_perbill {}: set_on_demand_fee_variability(RawOrigin::Root, Perbill::from_percent(100)) + + impl_benchmark_test_suite!( + Pallet, + crate::mock::new_test_ext(Default::default()), + crate::mock::Test + ); +} diff --git a/polkadot/runtime/parachains/src/configuration/migration.rs b/polkadot/runtime/parachains/src/configuration/migration.rs new file mode 100644 index 0000000000000000000000000000000000000000..4499b116462b8af97c53275a4e0eea3ce0c902a6 --- /dev/null +++ b/polkadot/runtime/parachains/src/configuration/migration.rs @@ -0,0 +1,21 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A module that is responsible for migration of storage. + +pub mod v6; +pub mod v7; +pub mod v8; diff --git a/polkadot/runtime/parachains/src/configuration/migration/v6.rs b/polkadot/runtime/parachains/src/configuration/migration/v6.rs new file mode 100644 index 0000000000000000000000000000000000000000..beed54deaffa8ea6c9331948027ecf57766ce67d --- /dev/null +++ b/polkadot/runtime/parachains/src/configuration/migration/v6.rs @@ -0,0 +1,137 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Contains the V6 storage definition of the host configuration. + +use crate::configuration::{Config, Pallet}; +use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::BlockNumberFor; +use sp_std::vec::Vec; + +use primitives::{vstaging::AsyncBackingParams, Balance, ExecutorParams, SessionIndex}; +#[cfg(feature = "try-runtime")] +use sp_std::prelude::*; + +#[derive(parity_scale_codec::Encode, parity_scale_codec::Decode, Debug, Clone)] +pub struct V6HostConfiguration { + pub max_code_size: u32, + pub max_head_data_size: u32, + pub max_upward_queue_count: u32, + pub max_upward_queue_size: u32, + pub max_upward_message_size: u32, + pub max_upward_message_num_per_candidate: u32, + pub hrmp_max_message_num_per_candidate: u32, + pub validation_upgrade_cooldown: BlockNumber, + pub validation_upgrade_delay: BlockNumber, + pub async_backing_params: AsyncBackingParams, + pub max_pov_size: u32, + pub max_downward_message_size: u32, + pub hrmp_max_parachain_outbound_channels: u32, + pub hrmp_max_parathread_outbound_channels: u32, + pub hrmp_sender_deposit: Balance, + pub hrmp_recipient_deposit: Balance, + pub hrmp_channel_max_capacity: u32, + pub hrmp_channel_max_total_size: u32, + pub hrmp_max_parachain_inbound_channels: u32, + pub hrmp_max_parathread_inbound_channels: u32, + pub hrmp_channel_max_message_size: u32, + pub executor_params: ExecutorParams, + pub code_retention_period: BlockNumber, + pub parathread_cores: u32, + pub parathread_retries: u32, + pub group_rotation_frequency: BlockNumber, + pub chain_availability_period: BlockNumber, + pub thread_availability_period: BlockNumber, + pub scheduling_lookahead: u32, + pub max_validators_per_core: Option, + pub max_validators: Option, + pub dispute_period: SessionIndex, + pub dispute_post_conclusion_acceptance_period: BlockNumber, + pub no_show_slots: u32, + pub n_delay_tranches: u32, + pub zeroth_delay_tranche_width: u32, + pub needed_approvals: u32, + pub relay_vrf_modulo_samples: u32, + pub pvf_checking_enabled: bool, + pub pvf_voting_ttl: SessionIndex, + pub minimum_validation_upgrade_delay: BlockNumber, +} + +impl> Default for V6HostConfiguration { + fn default() -> Self { + Self { + async_backing_params: AsyncBackingParams { + max_candidate_depth: 0, + allowed_ancestry_len: 0, + }, + group_rotation_frequency: 1u32.into(), + chain_availability_period: 1u32.into(), + thread_availability_period: 1u32.into(), + no_show_slots: 1u32.into(), + validation_upgrade_cooldown: Default::default(), + validation_upgrade_delay: 2u32.into(), + code_retention_period: Default::default(), + max_code_size: Default::default(), + max_pov_size: Default::default(), + max_head_data_size: Default::default(), + parathread_cores: Default::default(), + parathread_retries: Default::default(), + scheduling_lookahead: Default::default(), + max_validators_per_core: Default::default(), + max_validators: None, + dispute_period: 6, + dispute_post_conclusion_acceptance_period: 100.into(), + n_delay_tranches: Default::default(), + zeroth_delay_tranche_width: Default::default(), + needed_approvals: Default::default(), + relay_vrf_modulo_samples: Default::default(), + max_upward_queue_count: Default::default(), + max_upward_queue_size: Default::default(), + max_downward_message_size: Default::default(), + max_upward_message_size: Default::default(), + max_upward_message_num_per_candidate: Default::default(), + hrmp_sender_deposit: Default::default(), + hrmp_recipient_deposit: Default::default(), + hrmp_channel_max_capacity: Default::default(), + hrmp_channel_max_total_size: Default::default(), + hrmp_max_parachain_inbound_channels: Default::default(), + hrmp_max_parathread_inbound_channels: Default::default(), + hrmp_channel_max_message_size: Default::default(), + hrmp_max_parachain_outbound_channels: Default::default(), + hrmp_max_parathread_outbound_channels: Default::default(), + hrmp_max_message_num_per_candidate: Default::default(), + pvf_checking_enabled: false, + pvf_voting_ttl: 2u32.into(), + minimum_validation_upgrade_delay: 2.into(), + executor_params: Default::default(), + } + } +} + +mod v6 { + use super::*; + + #[frame_support::storage_alias] + pub(crate) type ActiveConfig = + StorageValue, V6HostConfiguration>, OptionQuery>; + + #[frame_support::storage_alias] + pub(crate) type PendingConfigs = StorageValue< + Pallet, + Vec<(SessionIndex, V6HostConfiguration>)>, + OptionQuery, + >; +} diff --git a/polkadot/runtime/parachains/src/configuration/migration/v7.rs b/polkadot/runtime/parachains/src/configuration/migration/v7.rs new file mode 100644 index 0000000000000000000000000000000000000000..11365138120782c7b5909d320f2778401f0e2916 --- /dev/null +++ b/polkadot/runtime/parachains/src/configuration/migration/v7.rs @@ -0,0 +1,405 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A module that is responsible for migration of storage. + +use crate::configuration::{self, Config, Pallet}; +use frame_support::{ + pallet_prelude::*, + traits::{Defensive, StorageVersion}, + weights::Weight, +}; +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::{vstaging::AsyncBackingParams, Balance, ExecutorParams, SessionIndex}; +use sp_std::vec::Vec; + +use frame_support::traits::OnRuntimeUpgrade; + +use super::v6::V6HostConfiguration; + +#[derive(parity_scale_codec::Encode, parity_scale_codec::Decode, Debug, Clone)] +pub struct V7HostConfiguration { + pub max_code_size: u32, + pub max_head_data_size: u32, + pub max_upward_queue_count: u32, + pub max_upward_queue_size: u32, + pub max_upward_message_size: u32, + pub max_upward_message_num_per_candidate: u32, + pub hrmp_max_message_num_per_candidate: u32, + pub validation_upgrade_cooldown: BlockNumber, + pub validation_upgrade_delay: BlockNumber, + pub async_backing_params: AsyncBackingParams, + pub max_pov_size: u32, + pub max_downward_message_size: u32, + pub hrmp_max_parachain_outbound_channels: u32, + pub hrmp_max_parathread_outbound_channels: u32, + pub hrmp_sender_deposit: Balance, + pub hrmp_recipient_deposit: Balance, + pub hrmp_channel_max_capacity: u32, + pub hrmp_channel_max_total_size: u32, + pub hrmp_max_parachain_inbound_channels: u32, + pub hrmp_max_parathread_inbound_channels: u32, + pub hrmp_channel_max_message_size: u32, + pub executor_params: ExecutorParams, + pub code_retention_period: BlockNumber, + pub parathread_cores: u32, + pub parathread_retries: u32, + pub group_rotation_frequency: BlockNumber, + pub chain_availability_period: BlockNumber, + pub thread_availability_period: BlockNumber, + pub scheduling_lookahead: u32, + pub max_validators_per_core: Option, + pub max_validators: Option, + pub dispute_period: SessionIndex, + pub dispute_post_conclusion_acceptance_period: BlockNumber, + pub no_show_slots: u32, + pub n_delay_tranches: u32, + pub zeroth_delay_tranche_width: u32, + pub needed_approvals: u32, + pub relay_vrf_modulo_samples: u32, + pub pvf_voting_ttl: SessionIndex, + pub minimum_validation_upgrade_delay: BlockNumber, +} + +impl> Default for V7HostConfiguration { + fn default() -> Self { + Self { + async_backing_params: AsyncBackingParams { + max_candidate_depth: 0, + allowed_ancestry_len: 0, + }, + group_rotation_frequency: 1u32.into(), + chain_availability_period: 1u32.into(), + thread_availability_period: 1u32.into(), + no_show_slots: 1u32.into(), + validation_upgrade_cooldown: Default::default(), + validation_upgrade_delay: 2u32.into(), + code_retention_period: Default::default(), + max_code_size: Default::default(), + max_pov_size: Default::default(), + max_head_data_size: Default::default(), + parathread_cores: Default::default(), + parathread_retries: Default::default(), + scheduling_lookahead: Default::default(), + max_validators_per_core: Default::default(), + max_validators: None, + dispute_period: 6, + dispute_post_conclusion_acceptance_period: 100.into(), + n_delay_tranches: Default::default(), + zeroth_delay_tranche_width: Default::default(), + needed_approvals: Default::default(), + relay_vrf_modulo_samples: Default::default(), + max_upward_queue_count: Default::default(), + max_upward_queue_size: Default::default(), + max_downward_message_size: Default::default(), + max_upward_message_size: Default::default(), + max_upward_message_num_per_candidate: Default::default(), + hrmp_sender_deposit: Default::default(), + hrmp_recipient_deposit: Default::default(), + hrmp_channel_max_capacity: Default::default(), + hrmp_channel_max_total_size: Default::default(), + hrmp_max_parachain_inbound_channels: Default::default(), + hrmp_max_parathread_inbound_channels: Default::default(), + hrmp_channel_max_message_size: Default::default(), + hrmp_max_parachain_outbound_channels: Default::default(), + hrmp_max_parathread_outbound_channels: Default::default(), + hrmp_max_message_num_per_candidate: Default::default(), + pvf_voting_ttl: 2u32.into(), + minimum_validation_upgrade_delay: 2.into(), + executor_params: Default::default(), + } + } +} + +mod v6 { + use super::*; + + #[frame_support::storage_alias] + pub(crate) type ActiveConfig = + StorageValue, V6HostConfiguration>, OptionQuery>; + + #[frame_support::storage_alias] + pub(crate) type PendingConfigs = StorageValue< + Pallet, + Vec<(SessionIndex, V6HostConfiguration>)>, + OptionQuery, + >; +} + +mod v7 { + use super::*; + + #[frame_support::storage_alias] + pub(crate) type ActiveConfig = + StorageValue, V7HostConfiguration>, OptionQuery>; + + #[frame_support::storage_alias] + pub(crate) type PendingConfigs = StorageValue< + Pallet, + Vec<(SessionIndex, V7HostConfiguration>)>, + OptionQuery, + >; +} + +pub struct MigrateToV7(sp_std::marker::PhantomData); +impl OnRuntimeUpgrade for MigrateToV7 { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + log::trace!(target: crate::configuration::LOG_TARGET, "Running pre_upgrade()"); + Ok(Vec::new()) + } + + fn on_runtime_upgrade() -> Weight { + log::info!(target: configuration::LOG_TARGET, "MigrateToV7 started"); + if StorageVersion::get::>() == 6 { + let weight_consumed = migrate_to_v7::(); + + log::info!(target: configuration::LOG_TARGET, "MigrateToV7 executed successfully"); + StorageVersion::new(7).put::>(); + + weight_consumed + } else { + log::warn!(target: configuration::LOG_TARGET, "MigrateToV7 should be removed."); + T::DbWeight::get().reads(1) + } + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + log::trace!(target: crate::configuration::LOG_TARGET, "Running post_upgrade()"); + ensure!( + StorageVersion::get::>() >= 7, + "Storage version should be >= 7 after the migration" + ); + + Ok(()) + } +} + +fn migrate_to_v7() -> Weight { + // Unusual formatting is justified: + // - make it easier to verify that fields assign what they supposed to assign. + // - this code is transient and will be removed after all migrations are done. + // - this code is important enough to optimize for legibility sacrificing consistency. + #[rustfmt::skip] + let translate = + |pre: V6HostConfiguration>| -> + V7HostConfiguration> + { + V7HostConfiguration { +max_code_size : pre.max_code_size, +max_head_data_size : pre.max_head_data_size, +max_upward_queue_count : pre.max_upward_queue_count, +max_upward_queue_size : pre.max_upward_queue_size, +max_upward_message_size : pre.max_upward_message_size, +max_upward_message_num_per_candidate : pre.max_upward_message_num_per_candidate, +hrmp_max_message_num_per_candidate : pre.hrmp_max_message_num_per_candidate, +validation_upgrade_cooldown : pre.validation_upgrade_cooldown, +validation_upgrade_delay : pre.validation_upgrade_delay, +max_pov_size : pre.max_pov_size, +max_downward_message_size : pre.max_downward_message_size, +hrmp_max_parachain_outbound_channels : pre.hrmp_max_parachain_outbound_channels, +hrmp_max_parathread_outbound_channels : pre.hrmp_max_parathread_outbound_channels, +hrmp_sender_deposit : pre.hrmp_sender_deposit, +hrmp_recipient_deposit : pre.hrmp_recipient_deposit, +hrmp_channel_max_capacity : pre.hrmp_channel_max_capacity, +hrmp_channel_max_total_size : pre.hrmp_channel_max_total_size, +hrmp_max_parachain_inbound_channels : pre.hrmp_max_parachain_inbound_channels, +hrmp_max_parathread_inbound_channels : pre.hrmp_max_parathread_inbound_channels, +hrmp_channel_max_message_size : pre.hrmp_channel_max_message_size, +code_retention_period : pre.code_retention_period, +parathread_cores : pre.parathread_cores, +parathread_retries : pre.parathread_retries, +group_rotation_frequency : pre.group_rotation_frequency, +chain_availability_period : pre.chain_availability_period, +thread_availability_period : pre.thread_availability_period, +scheduling_lookahead : pre.scheduling_lookahead, +max_validators_per_core : pre.max_validators_per_core, +max_validators : pre.max_validators, +dispute_period : pre.dispute_period, +dispute_post_conclusion_acceptance_period: pre.dispute_post_conclusion_acceptance_period, +no_show_slots : pre.no_show_slots, +n_delay_tranches : pre.n_delay_tranches, +zeroth_delay_tranche_width : pre.zeroth_delay_tranche_width, +needed_approvals : pre.needed_approvals, +relay_vrf_modulo_samples : pre.relay_vrf_modulo_samples, +pvf_voting_ttl : pre.pvf_voting_ttl, +minimum_validation_upgrade_delay : pre.minimum_validation_upgrade_delay, +async_backing_params : pre.async_backing_params, +executor_params : pre.executor_params, + } + }; + + let v6 = v6::ActiveConfig::::get() + .defensive_proof("Could not decode old config") + .unwrap_or_default(); + let v7 = translate(v6); + v7::ActiveConfig::::set(Some(v7)); + + // Allowed to be empty. + let pending_v6 = v6::PendingConfigs::::get().unwrap_or_default(); + let mut pending_v7 = Vec::new(); + + for (session, v6) in pending_v6.into_iter() { + let v7 = translate(v6); + pending_v7.push((session, v7)); + } + v7::PendingConfigs::::set(Some(pending_v7.clone())); + + let num_configs = (pending_v7.len() + 1) as u64; + T::DbWeight::get().reads_writes(num_configs, num_configs) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::{new_test_ext, Test}; + + #[test] + fn v6_deserialized_from_actual_data() { + // Example how to get new `raw_config`: + // We'll obtain the raw_config at a specified a block + // Steps: + // 1. Go to Polkadot.js -> Developer -> Chain state -> Storage: https://polkadot.js.org/apps/#/chainstate + // 2. Set these parameters: + // 2.1. selected state query: configuration; activeConfig(): + // PolkadotRuntimeParachainsConfigurationHostConfiguration 2.2. blockhash to query at: + // 0xf89d3ab5312c5f70d396dc59612f0aa65806c798346f9db4b35278baed2e0e53 (the hash of the + // block) 2.3. Note the value of encoded storage key -> + // 0x06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385 for the referenced + // block. 2.4. You'll also need the decoded values to update the test. + // 3. Go to Polkadot.js -> Developer -> Chain state -> Raw storage + // 3.1 Enter the encoded storage key and you get the raw config. + + // This exceeds the maximal line width length, but that's fine, since this is not code and + // doesn't need to be read and also leaving it as one line allows to easily copy it. + let raw_config = hex_literal::hex!["00003000005000005555150000008000fbff0100000200000a000000c80000006400000000000000000000000000500000c800000a0000000000000000c0220fca950300000000000000000000c0220fca9503000000000000000000e8030000009001000a0000000000000000900100008070000000000000000000000a000000050000000500000001000000010500000001c80000000600000058020000020000002800000000000000020000000100000001020000000f000000"]; + + let v6 = + V6HostConfiguration::::decode(&mut &raw_config[..]).unwrap(); + + // We check only a sample of the values here. If we missed any fields or messed up data + // types that would skew all the fields coming after. + assert_eq!(v6.max_code_size, 3_145_728); + assert_eq!(v6.validation_upgrade_cooldown, 200); + assert_eq!(v6.max_pov_size, 5_242_880); + assert_eq!(v6.hrmp_channel_max_message_size, 102_400); + assert_eq!(v6.n_delay_tranches, 40); + assert_eq!(v6.minimum_validation_upgrade_delay, 15); + assert_eq!(v6.group_rotation_frequency, 10); + } + + #[test] + fn test_migrate_to_v7() { + // Host configuration has lots of fields. However, in this migration we only remove one + // field. The most important part to check are a couple of the last fields. We also pick + // extra fields to check arbitrarily, e.g. depending on their position (i.e. the middle) and + // also their type. + // + // We specify only the picked fields and the rest should be provided by the `Default` + // implementation. That implementation is copied over between the two types and should work + // fine. + let v6 = V6HostConfiguration:: { + needed_approvals: 69, + thread_availability_period: 55, + hrmp_recipient_deposit: 1337, + max_pov_size: 1111, + chain_availability_period: 33, + minimum_validation_upgrade_delay: 20, + pvf_checking_enabled: true, + ..Default::default() + }; + + let mut pending_configs = Vec::new(); + pending_configs.push((100, v6.clone())); + pending_configs.push((300, v6.clone())); + + new_test_ext(Default::default()).execute_with(|| { + // Implant the v6 version in the state. + v6::ActiveConfig::::set(Some(v6)); + v6::PendingConfigs::::set(Some(pending_configs)); + + migrate_to_v7::(); + + let v7 = v7::ActiveConfig::::get().unwrap(); + let mut configs_to_check = v7::PendingConfigs::::get().unwrap(); + configs_to_check.push((0, v7.clone())); + + for (_, v6) in configs_to_check { + #[rustfmt::skip] + { + assert_eq!(v6.max_code_size , v7.max_code_size); + assert_eq!(v6.max_head_data_size , v7.max_head_data_size); + assert_eq!(v6.max_upward_queue_count , v7.max_upward_queue_count); + assert_eq!(v6.max_upward_queue_size , v7.max_upward_queue_size); + assert_eq!(v6.max_upward_message_size , v7.max_upward_message_size); + assert_eq!(v6.max_upward_message_num_per_candidate , v7.max_upward_message_num_per_candidate); + assert_eq!(v6.hrmp_max_message_num_per_candidate , v7.hrmp_max_message_num_per_candidate); + assert_eq!(v6.validation_upgrade_cooldown , v7.validation_upgrade_cooldown); + assert_eq!(v6.validation_upgrade_delay , v7.validation_upgrade_delay); + assert_eq!(v6.max_pov_size , v7.max_pov_size); + assert_eq!(v6.max_downward_message_size , v7.max_downward_message_size); + assert_eq!(v6.hrmp_max_parachain_outbound_channels , v7.hrmp_max_parachain_outbound_channels); + assert_eq!(v6.hrmp_max_parathread_outbound_channels , v7.hrmp_max_parathread_outbound_channels); + assert_eq!(v6.hrmp_sender_deposit , v7.hrmp_sender_deposit); + assert_eq!(v6.hrmp_recipient_deposit , v7.hrmp_recipient_deposit); + assert_eq!(v6.hrmp_channel_max_capacity , v7.hrmp_channel_max_capacity); + assert_eq!(v6.hrmp_channel_max_total_size , v7.hrmp_channel_max_total_size); + assert_eq!(v6.hrmp_max_parachain_inbound_channels , v7.hrmp_max_parachain_inbound_channels); + assert_eq!(v6.hrmp_max_parathread_inbound_channels , v7.hrmp_max_parathread_inbound_channels); + assert_eq!(v6.hrmp_channel_max_message_size , v7.hrmp_channel_max_message_size); + assert_eq!(v6.code_retention_period , v7.code_retention_period); + assert_eq!(v6.parathread_cores , v7.parathread_cores); + assert_eq!(v6.parathread_retries , v7.parathread_retries); + assert_eq!(v6.group_rotation_frequency , v7.group_rotation_frequency); + assert_eq!(v6.chain_availability_period , v7.chain_availability_period); + assert_eq!(v6.thread_availability_period , v7.thread_availability_period); + assert_eq!(v6.scheduling_lookahead , v7.scheduling_lookahead); + assert_eq!(v6.max_validators_per_core , v7.max_validators_per_core); + assert_eq!(v6.max_validators , v7.max_validators); + assert_eq!(v6.dispute_period , v7.dispute_period); + assert_eq!(v6.no_show_slots , v7.no_show_slots); + assert_eq!(v6.n_delay_tranches , v7.n_delay_tranches); + assert_eq!(v6.zeroth_delay_tranche_width , v7.zeroth_delay_tranche_width); + assert_eq!(v6.needed_approvals , v7.needed_approvals); + assert_eq!(v6.relay_vrf_modulo_samples , v7.relay_vrf_modulo_samples); + assert_eq!(v6.pvf_voting_ttl , v7.pvf_voting_ttl); + assert_eq!(v6.minimum_validation_upgrade_delay , v7.minimum_validation_upgrade_delay); + assert_eq!(v6.async_backing_params.allowed_ancestry_len, v7.async_backing_params.allowed_ancestry_len); + assert_eq!(v6.async_backing_params.max_candidate_depth , v7.async_backing_params.max_candidate_depth); + assert_eq!(v6.executor_params , v7.executor_params); + }; // ; makes this a statement. `rustfmt::skip` cannot be put on an expression. + } + }); + } + + // Test that migration doesn't panic in case there're no pending configurations upgrades in + // pallet's storage. + #[test] + fn test_migrate_to_v7_no_pending() { + let v6 = V6HostConfiguration::::default(); + + new_test_ext(Default::default()).execute_with(|| { + // Implant the v6 version in the state. + v6::ActiveConfig::::set(Some(v6)); + // Ensure there're no pending configs. + v6::PendingConfigs::::set(None); + + // Shouldn't fail. + migrate_to_v7::(); + }); + } +} diff --git a/polkadot/runtime/parachains/src/configuration/migration/v8.rs b/polkadot/runtime/parachains/src/configuration/migration/v8.rs new file mode 100644 index 0000000000000000000000000000000000000000..7f7cc1cdefcd974cbb6923ed1ed9de2fac56983d --- /dev/null +++ b/polkadot/runtime/parachains/src/configuration/migration/v8.rs @@ -0,0 +1,319 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A module that is responsible for migration of storage. + +use crate::configuration::{self, Config, Pallet}; +use frame_support::{ + pallet_prelude::*, + traits::{Defensive, StorageVersion}, + weights::Weight, +}; +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::SessionIndex; +use sp_runtime::Perbill; +use sp_std::vec::Vec; + +use frame_support::traits::OnRuntimeUpgrade; + +use super::v7::V7HostConfiguration; +type V8HostConfiguration = configuration::HostConfiguration; + +mod v7 { + use super::*; + + #[frame_support::storage_alias] + pub(crate) type ActiveConfig = + StorageValue, V7HostConfiguration>, OptionQuery>; + + #[frame_support::storage_alias] + pub(crate) type PendingConfigs = StorageValue< + Pallet, + Vec<(SessionIndex, V7HostConfiguration>)>, + OptionQuery, + >; +} + +mod v8 { + use super::*; + + #[frame_support::storage_alias] + pub(crate) type ActiveConfig = + StorageValue, V8HostConfiguration>, OptionQuery>; + + #[frame_support::storage_alias] + pub(crate) type PendingConfigs = StorageValue< + Pallet, + Vec<(SessionIndex, V8HostConfiguration>)>, + OptionQuery, + >; +} + +pub struct MigrateToV8(sp_std::marker::PhantomData); +impl OnRuntimeUpgrade for MigrateToV8 { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + log::trace!(target: crate::configuration::LOG_TARGET, "Running pre_upgrade() for HostConfiguration MigrateToV8"); + Ok(Vec::new()) + } + + fn on_runtime_upgrade() -> Weight { + log::info!(target: configuration::LOG_TARGET, "HostConfiguration MigrateToV8 started"); + if StorageVersion::get::>() == 7 { + let weight_consumed = migrate_to_v8::(); + + log::info!(target: configuration::LOG_TARGET, "HostConfiguration MigrateToV8 executed successfully"); + StorageVersion::new(8).put::>(); + + weight_consumed + } else { + log::warn!(target: configuration::LOG_TARGET, "HostConfiguration MigrateToV8 should be removed."); + T::DbWeight::get().reads(1) + } + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + log::trace!(target: crate::configuration::LOG_TARGET, "Running post_upgrade() for HostConfiguration MigrateToV8"); + ensure!( + StorageVersion::get::>() >= 8, + "Storage version should be >= 8 after the migration" + ); + + Ok(()) + } +} + +fn migrate_to_v8() -> Weight { + // Unusual formatting is justified: + // - make it easier to verify that fields assign what they supposed to assign. + // - this code is transient and will be removed after all migrations are done. + // - this code is important enough to optimize for legibility sacrificing consistency. + #[rustfmt::skip] + let translate = + |pre: V7HostConfiguration>| -> + V8HostConfiguration> + { + V8HostConfiguration { +max_code_size : pre.max_code_size, +max_head_data_size : pre.max_head_data_size, +max_upward_queue_count : pre.max_upward_queue_count, +max_upward_queue_size : pre.max_upward_queue_size, +max_upward_message_size : pre.max_upward_message_size, +max_upward_message_num_per_candidate : pre.max_upward_message_num_per_candidate, +hrmp_max_message_num_per_candidate : pre.hrmp_max_message_num_per_candidate, +validation_upgrade_cooldown : pre.validation_upgrade_cooldown, +validation_upgrade_delay : pre.validation_upgrade_delay, +max_pov_size : pre.max_pov_size, +max_downward_message_size : pre.max_downward_message_size, +hrmp_sender_deposit : pre.hrmp_sender_deposit, +hrmp_recipient_deposit : pre.hrmp_recipient_deposit, +hrmp_channel_max_capacity : pre.hrmp_channel_max_capacity, +hrmp_channel_max_total_size : pre.hrmp_channel_max_total_size, +hrmp_max_parachain_inbound_channels : pre.hrmp_max_parachain_inbound_channels, +hrmp_max_parachain_outbound_channels : pre.hrmp_max_parachain_outbound_channels, +hrmp_channel_max_message_size : pre.hrmp_channel_max_message_size, +code_retention_period : pre.code_retention_period, +on_demand_cores : pre.parathread_cores, +on_demand_retries : pre.parathread_retries, +group_rotation_frequency : pre.group_rotation_frequency, +paras_availability_period : pre.chain_availability_period, +scheduling_lookahead : pre.scheduling_lookahead, +max_validators_per_core : pre.max_validators_per_core, +max_validators : pre.max_validators, +dispute_period : pre.dispute_period, +dispute_post_conclusion_acceptance_period: pre.dispute_post_conclusion_acceptance_period, +no_show_slots : pre.no_show_slots, +n_delay_tranches : pre.n_delay_tranches, +zeroth_delay_tranche_width : pre.zeroth_delay_tranche_width, +needed_approvals : pre.needed_approvals, +relay_vrf_modulo_samples : pre.relay_vrf_modulo_samples, +pvf_voting_ttl : pre.pvf_voting_ttl, +minimum_validation_upgrade_delay : pre.minimum_validation_upgrade_delay, +async_backing_params : pre.async_backing_params, +executor_params : pre.executor_params, +on_demand_queue_max_size : 10_000u32, +on_demand_base_fee : 10_000_000u128, +on_demand_fee_variability : Perbill::from_percent(3), +on_demand_target_queue_utilization : Perbill::from_percent(25), +on_demand_ttl : 5u32.into(), + } + }; + + let v7 = v7::ActiveConfig::::get() + .defensive_proof("Could not decode old config") + .unwrap_or_default(); + let v8 = translate(v7); + v8::ActiveConfig::::set(Some(v8)); + + // Allowed to be empty. + let pending_v7 = v7::PendingConfigs::::get().unwrap_or_default(); + let mut pending_v8 = Vec::new(); + + for (session, v7) in pending_v7.into_iter() { + let v8 = translate(v7); + pending_v8.push((session, v8)); + } + v8::PendingConfigs::::set(Some(pending_v8.clone())); + + let num_configs = (pending_v8.len() + 1) as u64; + T::DbWeight::get().reads_writes(num_configs, num_configs) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::{new_test_ext, Test}; + + #[test] + fn v8_deserialized_from_actual_data() { + // Example how to get new `raw_config`: + // We'll obtain the raw_config at a specified a block + // Steps: + // 1. Go to Polkadot.js -> Developer -> Chain state -> Storage: https://polkadot.js.org/apps/#/chainstate + // 2. Set these parameters: + // 2.1. selected state query: configuration; activeConfig(): + // PolkadotRuntimeParachainsConfigurationHostConfiguration + // 2.2. blockhash to query at: + // 0xf89d3ab5312c5f70d396dc59612f0aa65806c798346f9db4b35278baed2e0e53 (the hash of + // the block) + // 2.3. Note the value of encoded storage key -> + // 0x06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385 for the + // referenced block. + // 2.4. You'll also need the decoded values to update the test. + // 3. Go to Polkadot.js -> Developer -> Chain state -> Raw storage + // 3.1 Enter the encoded storage key and you get the raw config. + + // This exceeds the maximal line width length, but that's fine, since this is not code and + // doesn't need to be read and also leaving it as one line allows to easily copy it. + let raw_config = + hex_literal::hex![" + 0000300000800000080000000000100000c8000005000000050000000200000002000000000000000000000000005000000010000400000000000000000000000000000000000000000000000000000000000000000000000800000000200000040000000000100000b004000000000000000000001027000080b2e60e80c3c9018096980000000000000000000000000005000000140000000400000001000000010100000000060000006400000002000000190000000000000002000000020000000200000005000000" + ]; + + let v8 = + V8HostConfiguration::::decode(&mut &raw_config[..]).unwrap(); + + // We check only a sample of the values here. If we missed any fields or messed up data + // types that would skew all the fields coming after. + assert_eq!(v8.max_code_size, 3_145_728); + assert_eq!(v8.validation_upgrade_cooldown, 2); + assert_eq!(v8.max_pov_size, 5_242_880); + assert_eq!(v8.hrmp_channel_max_message_size, 1_048_576); + assert_eq!(v8.n_delay_tranches, 25); + assert_eq!(v8.minimum_validation_upgrade_delay, 5); + assert_eq!(v8.group_rotation_frequency, 20); + assert_eq!(v8.on_demand_cores, 0); + assert_eq!(v8.on_demand_base_fee, 10_000_000); + } + + #[test] + fn test_migrate_to_v8() { + // Host configuration has lots of fields. However, in this migration we only remove one + // field. The most important part to check are a couple of the last fields. We also pick + // extra fields to check arbitrarily, e.g. depending on their position (i.e. the middle) and + // also their type. + // + // We specify only the picked fields and the rest should be provided by the `Default` + // implementation. That implementation is copied over between the two types and should work + // fine. + let v7 = V7HostConfiguration:: { + needed_approvals: 69, + thread_availability_period: 55, + hrmp_recipient_deposit: 1337, + max_pov_size: 1111, + chain_availability_period: 33, + minimum_validation_upgrade_delay: 20, + ..Default::default() + }; + + let mut pending_configs = Vec::new(); + pending_configs.push((100, v7.clone())); + pending_configs.push((300, v7.clone())); + + new_test_ext(Default::default()).execute_with(|| { + // Implant the v6 version in the state. + v7::ActiveConfig::::set(Some(v7)); + v7::PendingConfigs::::set(Some(pending_configs)); + + migrate_to_v8::(); + + let v8 = v8::ActiveConfig::::get().unwrap(); + let mut configs_to_check = v8::PendingConfigs::::get().unwrap(); + configs_to_check.push((0, v8.clone())); + + for (_, v7) in configs_to_check { + #[rustfmt::skip] + { + assert_eq!(v7.max_code_size , v8.max_code_size); + assert_eq!(v7.max_head_data_size , v8.max_head_data_size); + assert_eq!(v7.max_upward_queue_count , v8.max_upward_queue_count); + assert_eq!(v7.max_upward_queue_size , v8.max_upward_queue_size); + assert_eq!(v7.max_upward_message_size , v8.max_upward_message_size); + assert_eq!(v7.max_upward_message_num_per_candidate , v8.max_upward_message_num_per_candidate); + assert_eq!(v7.hrmp_max_message_num_per_candidate , v8.hrmp_max_message_num_per_candidate); + assert_eq!(v7.validation_upgrade_cooldown , v8.validation_upgrade_cooldown); + assert_eq!(v7.validation_upgrade_delay , v8.validation_upgrade_delay); + assert_eq!(v7.max_pov_size , v8.max_pov_size); + assert_eq!(v7.max_downward_message_size , v8.max_downward_message_size); + assert_eq!(v7.hrmp_max_parachain_outbound_channels , v8.hrmp_max_parachain_outbound_channels); + assert_eq!(v7.hrmp_sender_deposit , v8.hrmp_sender_deposit); + assert_eq!(v7.hrmp_recipient_deposit , v8.hrmp_recipient_deposit); + assert_eq!(v7.hrmp_channel_max_capacity , v8.hrmp_channel_max_capacity); + assert_eq!(v7.hrmp_channel_max_total_size , v8.hrmp_channel_max_total_size); + assert_eq!(v7.hrmp_max_parachain_inbound_channels , v8.hrmp_max_parachain_inbound_channels); + assert_eq!(v7.hrmp_channel_max_message_size , v8.hrmp_channel_max_message_size); + assert_eq!(v7.code_retention_period , v8.code_retention_period); + assert_eq!(v7.on_demand_cores , v8.on_demand_cores); + assert_eq!(v7.on_demand_retries , v8.on_demand_retries); + assert_eq!(v7.group_rotation_frequency , v8.group_rotation_frequency); + assert_eq!(v7.paras_availability_period , v8.paras_availability_period); + assert_eq!(v7.scheduling_lookahead , v8.scheduling_lookahead); + assert_eq!(v7.max_validators_per_core , v8.max_validators_per_core); + assert_eq!(v7.max_validators , v8.max_validators); + assert_eq!(v7.dispute_period , v8.dispute_period); + assert_eq!(v7.no_show_slots , v8.no_show_slots); + assert_eq!(v7.n_delay_tranches , v8.n_delay_tranches); + assert_eq!(v7.zeroth_delay_tranche_width , v8.zeroth_delay_tranche_width); + assert_eq!(v7.needed_approvals , v8.needed_approvals); + assert_eq!(v7.relay_vrf_modulo_samples , v8.relay_vrf_modulo_samples); + assert_eq!(v7.pvf_voting_ttl , v8.pvf_voting_ttl); + assert_eq!(v7.minimum_validation_upgrade_delay , v8.minimum_validation_upgrade_delay); + assert_eq!(v7.async_backing_params.allowed_ancestry_len, v8.async_backing_params.allowed_ancestry_len); + assert_eq!(v7.async_backing_params.max_candidate_depth , v8.async_backing_params.max_candidate_depth); + assert_eq!(v7.executor_params , v8.executor_params); + }; // ; makes this a statement. `rustfmt::skip` cannot be put on an expression. + } + }); + } + + // Test that migration doesn't panic in case there're no pending configurations upgrades in + // pallet's storage. + #[test] + fn test_migrate_to_v8_no_pending() { + let v7 = V7HostConfiguration::::default(); + + new_test_ext(Default::default()).execute_with(|| { + // Implant the v6 version in the state. + v7::ActiveConfig::::set(Some(v7)); + // Ensure there're no pending configs. + v7::PendingConfigs::::set(None); + + // Shouldn't fail. + migrate_to_v8::(); + }); + } +} diff --git a/polkadot/runtime/parachains/src/configuration/tests.rs b/polkadot/runtime/parachains/src/configuration/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..43c03067a9a745e92f7f645c8d49f193fc7cfebe --- /dev/null +++ b/polkadot/runtime/parachains/src/configuration/tests.rs @@ -0,0 +1,520 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::mock::{new_test_ext, Configuration, ParasShared, RuntimeOrigin, Test}; +use frame_support::{assert_err, assert_noop, assert_ok}; + +fn on_new_session(session_index: SessionIndex) -> (HostConfiguration, HostConfiguration) { + ParasShared::set_session_index(session_index); + let SessionChangeOutcome { prev_config, new_config } = + Configuration::initializer_on_new_session(&session_index); + let new_config = new_config.unwrap_or_else(|| prev_config.clone()); + (prev_config, new_config) +} + +#[test] +fn default_is_consistent() { + new_test_ext(Default::default()).execute_with(|| { + Configuration::config().panic_if_not_consistent(); + }); +} + +#[test] +fn scheduled_session_is_two_sessions_from_now() { + new_test_ext(Default::default()).execute_with(|| { + // The logic here is really tested only with scheduled_session = 2. It should work + // with other values, but that should receive a more rigorious testing. + on_new_session(1); + assert_eq!(Configuration::scheduled_session(), 3); + }); +} + +#[test] +fn initializer_on_new_session() { + new_test_ext(Default::default()).execute_with(|| { + let (prev_config, new_config) = on_new_session(1); + assert_eq!(prev_config, new_config); + assert_ok!(Configuration::set_validation_upgrade_delay(RuntimeOrigin::root(), 100)); + + let (prev_config, new_config) = on_new_session(2); + assert_eq!(prev_config, new_config); + + let (prev_config, new_config) = on_new_session(3); + assert_eq!(prev_config, HostConfiguration::default()); + assert_eq!(new_config, HostConfiguration { validation_upgrade_delay: 100, ..prev_config }); + }); +} + +#[test] +fn config_changes_after_2_session_boundary() { + new_test_ext(Default::default()).execute_with(|| { + let old_config = Configuration::config(); + let mut config = old_config.clone(); + config.validation_upgrade_delay = 100; + assert!(old_config != config); + + assert_ok!(Configuration::set_validation_upgrade_delay(RuntimeOrigin::root(), 100)); + + // Verify that the current configuration has not changed and that there is a scheduled + // change for the SESSION_DELAY sessions in advance. + assert_eq!(Configuration::config(), old_config); + assert_eq!(PendingConfigs::::get(), vec![(2, config.clone())]); + + on_new_session(1); + + // One session has passed, we should be still waiting for the pending configuration. + assert_eq!(Configuration::config(), old_config); + assert_eq!(PendingConfigs::::get(), vec![(2, config.clone())]); + + on_new_session(2); + + assert_eq!(Configuration::config(), config); + assert_eq!(PendingConfigs::::get(), vec![]); + }) +} + +#[test] +fn consecutive_changes_within_one_session() { + new_test_ext(Default::default()).execute_with(|| { + let old_config = Configuration::config(); + let mut config = old_config.clone(); + config.validation_upgrade_delay = 100; + config.validation_upgrade_cooldown = 100; + assert!(old_config != config); + + assert_ok!(Configuration::set_validation_upgrade_delay(RuntimeOrigin::root(), 100)); + assert_ok!(Configuration::set_validation_upgrade_cooldown(RuntimeOrigin::root(), 100)); + assert_eq!(Configuration::config(), old_config); + assert_eq!(PendingConfigs::::get(), vec![(2, config.clone())]); + + on_new_session(1); + + assert_eq!(Configuration::config(), old_config); + assert_eq!(PendingConfigs::::get(), vec![(2, config.clone())]); + + on_new_session(2); + + assert_eq!(Configuration::config(), config); + assert_eq!(PendingConfigs::::get(), vec![]); + }); +} + +#[test] +fn pending_next_session_but_we_upgrade_once_more() { + new_test_ext(Default::default()).execute_with(|| { + let initial_config = Configuration::config(); + let intermediate_config = + HostConfiguration { validation_upgrade_delay: 100, ..initial_config.clone() }; + let final_config = HostConfiguration { + validation_upgrade_delay: 100, + validation_upgrade_cooldown: 99, + ..initial_config.clone() + }; + + assert_ok!(Configuration::set_validation_upgrade_delay(RuntimeOrigin::root(), 100)); + assert_eq!(Configuration::config(), initial_config); + assert_eq!(PendingConfigs::::get(), vec![(2, intermediate_config.clone())]); + + on_new_session(1); + + // We are still waiting until the pending configuration is applied and we add another + // update. + assert_ok!(Configuration::set_validation_upgrade_cooldown(RuntimeOrigin::root(), 99)); + + // This should result in yet another configiguration change scheduled. + assert_eq!(Configuration::config(), initial_config); + assert_eq!( + PendingConfigs::::get(), + vec![(2, intermediate_config.clone()), (3, final_config.clone())] + ); + + on_new_session(2); + + assert_eq!(Configuration::config(), intermediate_config); + assert_eq!(PendingConfigs::::get(), vec![(3, final_config.clone())]); + + on_new_session(3); + + assert_eq!(Configuration::config(), final_config); + assert_eq!(PendingConfigs::::get(), vec![]); + }); +} + +#[test] +fn scheduled_session_config_update_while_next_session_pending() { + new_test_ext(Default::default()).execute_with(|| { + let initial_config = Configuration::config(); + let intermediate_config = + HostConfiguration { validation_upgrade_delay: 100, ..initial_config.clone() }; + let final_config = HostConfiguration { + validation_upgrade_delay: 100, + validation_upgrade_cooldown: 99, + code_retention_period: 98, + ..initial_config.clone() + }; + + assert_ok!(Configuration::set_validation_upgrade_delay(RuntimeOrigin::root(), 100)); + assert_eq!(Configuration::config(), initial_config); + assert_eq!(PendingConfigs::::get(), vec![(2, intermediate_config.clone())]); + + on_new_session(1); + + // The second call should fall into the case where we already have a pending config + // update for the scheduled_session, but we want to update it once more. + assert_ok!(Configuration::set_validation_upgrade_cooldown(RuntimeOrigin::root(), 99)); + assert_ok!(Configuration::set_code_retention_period(RuntimeOrigin::root(), 98)); + + // This should result in yet another configiguration change scheduled. + assert_eq!(Configuration::config(), initial_config); + assert_eq!( + PendingConfigs::::get(), + vec![(2, intermediate_config.clone()), (3, final_config.clone())] + ); + + on_new_session(2); + + assert_eq!(Configuration::config(), intermediate_config); + assert_eq!(PendingConfigs::::get(), vec![(3, final_config.clone())]); + + on_new_session(3); + + assert_eq!(Configuration::config(), final_config); + assert_eq!(PendingConfigs::::get(), vec![]); + }); +} + +#[test] +fn invariants() { + new_test_ext(Default::default()).execute_with(|| { + assert_err!( + Configuration::set_max_code_size(RuntimeOrigin::root(), MAX_CODE_SIZE + 1), + Error::::InvalidNewValue + ); + + assert_err!( + Configuration::set_max_pov_size(RuntimeOrigin::root(), MAX_POV_SIZE + 1), + Error::::InvalidNewValue + ); + + assert_err!( + Configuration::set_max_head_data_size(RuntimeOrigin::root(), MAX_HEAD_DATA_SIZE + 1), + Error::::InvalidNewValue + ); + + assert_err!( + Configuration::set_paras_availability_period(RuntimeOrigin::root(), 0), + Error::::InvalidNewValue + ); + assert_err!( + Configuration::set_no_show_slots(RuntimeOrigin::root(), 0), + Error::::InvalidNewValue + ); + + ActiveConfig::::put(HostConfiguration { + paras_availability_period: 10, + minimum_validation_upgrade_delay: 11, + ..Default::default() + }); + assert_err!( + Configuration::set_paras_availability_period(RuntimeOrigin::root(), 12), + Error::::InvalidNewValue + ); + assert_err!( + Configuration::set_minimum_validation_upgrade_delay(RuntimeOrigin::root(), 9), + Error::::InvalidNewValue + ); + + assert_err!( + Configuration::set_validation_upgrade_delay(RuntimeOrigin::root(), 0), + Error::::InvalidNewValue + ); + }); +} + +#[test] +fn consistency_bypass_works() { + new_test_ext(Default::default()).execute_with(|| { + assert_err!( + Configuration::set_max_code_size(RuntimeOrigin::root(), MAX_CODE_SIZE + 1), + Error::::InvalidNewValue + ); + + assert_ok!(Configuration::set_bypass_consistency_check(RuntimeOrigin::root(), true)); + assert_ok!(Configuration::set_max_code_size(RuntimeOrigin::root(), MAX_CODE_SIZE + 1)); + + assert_eq!( + Configuration::config().max_code_size, + HostConfiguration::::default().max_code_size + ); + + on_new_session(1); + on_new_session(2); + + assert_eq!(Configuration::config().max_code_size, MAX_CODE_SIZE + 1); + }); +} + +#[test] +fn setting_pending_config_members() { + new_test_ext(Default::default()).execute_with(|| { + let new_config = HostConfiguration { + async_backing_params: AsyncBackingParams { + allowed_ancestry_len: 0, + max_candidate_depth: 0, + }, + validation_upgrade_cooldown: 100, + validation_upgrade_delay: 10, + code_retention_period: 5, + max_code_size: 100_000, + max_pov_size: 1024, + max_head_data_size: 1_000, + on_demand_cores: 2, + on_demand_retries: 5, + group_rotation_frequency: 20, + paras_availability_period: 10, + scheduling_lookahead: 3, + max_validators_per_core: None, + max_validators: None, + dispute_period: 239, + dispute_post_conclusion_acceptance_period: 10, + no_show_slots: 240, + n_delay_tranches: 241, + zeroth_delay_tranche_width: 242, + needed_approvals: 242, + relay_vrf_modulo_samples: 243, + max_upward_queue_count: 1337, + max_upward_queue_size: 228, + max_downward_message_size: 2048, + max_upward_message_size: 448, + max_upward_message_num_per_candidate: 5, + hrmp_sender_deposit: 22, + hrmp_recipient_deposit: 4905, + hrmp_channel_max_capacity: 3921, + hrmp_channel_max_total_size: 7687, + hrmp_max_parachain_inbound_channels: 37, + hrmp_channel_max_message_size: 8192, + hrmp_max_parachain_outbound_channels: 10, + hrmp_max_message_num_per_candidate: 20, + pvf_voting_ttl: 3, + minimum_validation_upgrade_delay: 20, + executor_params: Default::default(), + on_demand_queue_max_size: 10_000u32, + on_demand_base_fee: 10_000_000u128, + on_demand_fee_variability: Perbill::from_percent(3), + on_demand_target_queue_utilization: Perbill::from_percent(25), + on_demand_ttl: 5u32, + }; + + Configuration::set_validation_upgrade_cooldown( + RuntimeOrigin::root(), + new_config.validation_upgrade_cooldown, + ) + .unwrap(); + Configuration::set_validation_upgrade_delay( + RuntimeOrigin::root(), + new_config.validation_upgrade_delay, + ) + .unwrap(); + Configuration::set_code_retention_period( + RuntimeOrigin::root(), + new_config.code_retention_period, + ) + .unwrap(); + Configuration::set_max_code_size(RuntimeOrigin::root(), new_config.max_code_size).unwrap(); + Configuration::set_max_pov_size(RuntimeOrigin::root(), new_config.max_pov_size).unwrap(); + Configuration::set_max_head_data_size(RuntimeOrigin::root(), new_config.max_head_data_size) + .unwrap(); + Configuration::set_on_demand_cores(RuntimeOrigin::root(), new_config.on_demand_cores) + .unwrap(); + Configuration::set_on_demand_retries(RuntimeOrigin::root(), new_config.on_demand_retries) + .unwrap(); + Configuration::set_group_rotation_frequency( + RuntimeOrigin::root(), + new_config.group_rotation_frequency, + ) + .unwrap(); + // This comes out of order to satisfy the validity criteria for the chain and thread + // availability periods. + Configuration::set_minimum_validation_upgrade_delay( + RuntimeOrigin::root(), + new_config.minimum_validation_upgrade_delay, + ) + .unwrap(); + Configuration::set_paras_availability_period( + RuntimeOrigin::root(), + new_config.paras_availability_period, + ) + .unwrap(); + Configuration::set_scheduling_lookahead( + RuntimeOrigin::root(), + new_config.scheduling_lookahead, + ) + .unwrap(); + Configuration::set_max_validators_per_core( + RuntimeOrigin::root(), + new_config.max_validators_per_core, + ) + .unwrap(); + Configuration::set_max_validators(RuntimeOrigin::root(), new_config.max_validators) + .unwrap(); + Configuration::set_dispute_period(RuntimeOrigin::root(), new_config.dispute_period) + .unwrap(); + Configuration::set_dispute_post_conclusion_acceptance_period( + RuntimeOrigin::root(), + new_config.dispute_post_conclusion_acceptance_period, + ) + .unwrap(); + Configuration::set_no_show_slots(RuntimeOrigin::root(), new_config.no_show_slots).unwrap(); + Configuration::set_n_delay_tranches(RuntimeOrigin::root(), new_config.n_delay_tranches) + .unwrap(); + Configuration::set_zeroth_delay_tranche_width( + RuntimeOrigin::root(), + new_config.zeroth_delay_tranche_width, + ) + .unwrap(); + Configuration::set_needed_approvals(RuntimeOrigin::root(), new_config.needed_approvals) + .unwrap(); + Configuration::set_relay_vrf_modulo_samples( + RuntimeOrigin::root(), + new_config.relay_vrf_modulo_samples, + ) + .unwrap(); + Configuration::set_max_upward_queue_count( + RuntimeOrigin::root(), + new_config.max_upward_queue_count, + ) + .unwrap(); + Configuration::set_max_upward_queue_size( + RuntimeOrigin::root(), + new_config.max_upward_queue_size, + ) + .unwrap(); + assert_noop!( + Configuration::set_max_upward_queue_size( + RuntimeOrigin::root(), + MAX_UPWARD_MESSAGE_SIZE_BOUND + 1, + ), + Error::::InvalidNewValue + ); + Configuration::set_max_downward_message_size( + RuntimeOrigin::root(), + new_config.max_downward_message_size, + ) + .unwrap(); + Configuration::set_max_upward_message_size( + RuntimeOrigin::root(), + new_config.max_upward_message_size, + ) + .unwrap(); + Configuration::set_max_upward_message_num_per_candidate( + RuntimeOrigin::root(), + new_config.max_upward_message_num_per_candidate, + ) + .unwrap(); + Configuration::set_hrmp_sender_deposit( + RuntimeOrigin::root(), + new_config.hrmp_sender_deposit, + ) + .unwrap(); + Configuration::set_hrmp_recipient_deposit( + RuntimeOrigin::root(), + new_config.hrmp_recipient_deposit, + ) + .unwrap(); + Configuration::set_hrmp_channel_max_capacity( + RuntimeOrigin::root(), + new_config.hrmp_channel_max_capacity, + ) + .unwrap(); + Configuration::set_hrmp_channel_max_total_size( + RuntimeOrigin::root(), + new_config.hrmp_channel_max_total_size, + ) + .unwrap(); + Configuration::set_hrmp_max_parachain_inbound_channels( + RuntimeOrigin::root(), + new_config.hrmp_max_parachain_inbound_channels, + ) + .unwrap(); + Configuration::set_hrmp_channel_max_message_size( + RuntimeOrigin::root(), + new_config.hrmp_channel_max_message_size, + ) + .unwrap(); + Configuration::set_hrmp_max_parachain_outbound_channels( + RuntimeOrigin::root(), + new_config.hrmp_max_parachain_outbound_channels, + ) + .unwrap(); + Configuration::set_hrmp_max_message_num_per_candidate( + RuntimeOrigin::root(), + new_config.hrmp_max_message_num_per_candidate, + ) + .unwrap(); + Configuration::set_pvf_voting_ttl(RuntimeOrigin::root(), new_config.pvf_voting_ttl) + .unwrap(); + + assert_eq!(PendingConfigs::::get(), vec![(shared::SESSION_DELAY, new_config)],); + }) +} + +#[test] +fn non_root_cannot_set_config() { + new_test_ext(Default::default()).execute_with(|| { + assert!(Configuration::set_validation_upgrade_delay(RuntimeOrigin::signed(1), 100).is_err()); + }); +} + +#[test] +fn verify_externally_accessible() { + // This test verifies that the value can be accessed through the well known keys and the + // host configuration decodes into the abridged version. + + use primitives::{well_known_keys, AbridgedHostConfiguration}; + + new_test_ext(Default::default()).execute_with(|| { + let mut ground_truth = HostConfiguration::default(); + ground_truth.async_backing_params = + AsyncBackingParams { allowed_ancestry_len: 111, max_candidate_depth: 222 }; + + // Make sure that the configuration is stored in the storage. + ActiveConfig::::put(ground_truth.clone()); + + // Extract the active config via the well known key. + let raw_active_config = sp_io::storage::get(well_known_keys::ACTIVE_CONFIG) + .expect("config must be present in storage under ACTIVE_CONFIG"); + let abridged_config = AbridgedHostConfiguration::decode(&mut &raw_active_config[..]) + .expect("HostConfiguration must be decodable into AbridgedHostConfiguration"); + + assert_eq!( + abridged_config, + AbridgedHostConfiguration { + max_code_size: ground_truth.max_code_size, + max_head_data_size: ground_truth.max_head_data_size, + max_upward_queue_count: ground_truth.max_upward_queue_count, + max_upward_queue_size: ground_truth.max_upward_queue_size, + max_upward_message_size: ground_truth.max_upward_message_size, + max_upward_message_num_per_candidate: ground_truth + .max_upward_message_num_per_candidate, + hrmp_max_message_num_per_candidate: ground_truth.hrmp_max_message_num_per_candidate, + validation_upgrade_cooldown: ground_truth.validation_upgrade_cooldown, + validation_upgrade_delay: ground_truth.validation_upgrade_delay, + async_backing_params: ground_truth.async_backing_params, + }, + ); + }); +} diff --git a/polkadot/runtime/parachains/src/disputes.rs b/polkadot/runtime/parachains/src/disputes.rs new file mode 100644 index 0000000000000000000000000000000000000000..cf2e99e7359abf59d47d3d0c03667a860ab57559 --- /dev/null +++ b/polkadot/runtime/parachains/src/disputes.rs @@ -0,0 +1,1293 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Runtime component for handling disputes of parachain candidates. + +use crate::{ + configuration, initializer::SessionChangeNotification, metrics::METRICS, session_info, +}; +use bitvec::{bitvec, order::Lsb0 as BitOrderLsb0}; +use frame_support::{ensure, weights::Weight}; +use frame_system::pallet_prelude::*; +use parity_scale_codec::{Decode, Encode}; +use polkadot_runtime_metrics::get_current_time; +use primitives::{ + byzantine_threshold, supermajority_threshold, ApprovalVote, CandidateHash, + CheckedDisputeStatementSet, CheckedMultiDisputeStatementSet, CompactStatement, ConsensusLog, + DisputeState, DisputeStatement, DisputeStatementSet, ExplicitDisputeStatement, + InvalidDisputeStatementKind, MultiDisputeStatementSet, SessionIndex, SigningContext, + ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorSignature, +}; +use scale_info::TypeInfo; +use sp_runtime::{ + traits::{AppVerify, One, Saturating, Zero}, + DispatchError, RuntimeDebug, SaturatedConversion, +}; +use sp_std::{cmp::Ordering, collections::btree_set::BTreeSet, prelude::*}; + +#[cfg(test)] +#[allow(unused_imports)] +pub(crate) use self::tests::run_to_block; + +pub mod slashing; +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +pub mod migration; + +const LOG_TARGET: &str = "runtime::disputes"; + +/// Whether the dispute is local or remote. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub enum DisputeLocation { + Local, + Remote, +} + +/// The result of a dispute, whether the candidate is deemed valid (for) or invalid (against). +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub enum DisputeResult { + Valid, + Invalid, +} + +/// Reward hooks for disputes. +pub trait RewardValidators { + // Give each validator a reward, likely small, for participating in the dispute. + fn reward_dispute_statement( + session: SessionIndex, + validators: impl IntoIterator, + ); +} + +impl RewardValidators for () { + fn reward_dispute_statement(_: SessionIndex, _: impl IntoIterator) {} +} + +/// Punishment hooks for disputes. +pub trait SlashingHandler { + /// Punish a series of validators who were for an invalid parablock. This is + /// expected to be a major punishment. + fn punish_for_invalid( + session: SessionIndex, + candidate_hash: CandidateHash, + losers: impl IntoIterator, + backers: impl IntoIterator, + ); + + /// Punish a series of validators who were against a valid parablock. This + /// is expected to be a minor punishment. + fn punish_against_valid( + session: SessionIndex, + candidate_hash: CandidateHash, + losers: impl IntoIterator, + backers: impl IntoIterator, + ); + + /// Called by the initializer to initialize the slashing pallet. + fn initializer_initialize(now: BlockNumber) -> Weight; + + /// Called by the initializer to finalize the slashing pallet. + fn initializer_finalize(); + + /// Called by the initializer to note that a new session has started. + fn initializer_on_new_session(session_index: SessionIndex); +} + +impl SlashingHandler for () { + fn punish_for_invalid( + _: SessionIndex, + _: CandidateHash, + _: impl IntoIterator, + _: impl IntoIterator, + ) { + } + + fn punish_against_valid( + _: SessionIndex, + _: CandidateHash, + _: impl IntoIterator, + _: impl IntoIterator, + ) { + } + + fn initializer_initialize(_now: BlockNumber) -> Weight { + Weight::zero() + } + + fn initializer_finalize() {} + + fn initializer_on_new_session(_: SessionIndex) {} +} + +/// Provide a `Ordering` for the two provided dispute statement sets according to the +/// following prioritization: +/// 1. Prioritize local disputes over remote disputes +/// 2. Prioritize older disputes over newer disputes +fn dispute_ordering_compare, BlockNumber: Ord>( + a: &DisputeStatementSet, + b: &DisputeStatementSet, +) -> Ordering +where + T: ?Sized, +{ + let a_local_block = + >::included_state(a.session, a.candidate_hash); + let b_local_block = + >::included_state(b.session, b.candidate_hash); + match (a_local_block, b_local_block) { + // Prioritize local disputes over remote disputes. + (None, Some(_)) => Ordering::Greater, + (Some(_), None) => Ordering::Less, + // For local disputes, prioritize those that occur at an earlier height. + (Some(a_height), Some(b_height)) => + a_height.cmp(&b_height).then_with(|| a.candidate_hash.cmp(&b.candidate_hash)), + // Prioritize earlier remote disputes using session as rough proxy. + (None, None) => { + let session_ord = a.session.cmp(&b.session); + if session_ord == Ordering::Equal { + // sort by hash as last resort, to make below dedup work consistently + a.candidate_hash.cmp(&b.candidate_hash) + } else { + session_ord + } + }, + } +} + +/// Hook into disputes handling. +/// +/// Allows decoupling parachains handling from disputes so that it can +/// potentially be disabled when instantiating a specific runtime. +pub trait DisputesHandler { + /// Whether the chain is frozen, if the chain is frozen it will not accept + /// any new parachain blocks for backing or inclusion. + fn is_frozen() -> bool; + + /// Remove dispute statement duplicates and sort the non-duplicates based on + /// local (lower indicies) vs remotes (higher indices) and age (older with lower indices). + /// + /// Returns `Ok(())` if no duplicates were present, `Err(())` otherwise. + /// + /// Unsorted data does not change the return value, while the node side + /// is generally expected to pass them in sorted. + fn deduplicate_and_sort_dispute_data( + statement_sets: &mut MultiDisputeStatementSet, + ) -> Result<(), ()> { + // TODO: Consider trade-of to avoid `O(n * log(n))` average lookups of `included_state` + // TODO: instead make a single pass and store the values lazily. + // TODO: https://github.com/paritytech/polkadot/issues/4527 + let n = statement_sets.len(); + + statement_sets.sort_by(dispute_ordering_compare::); + statement_sets + .dedup_by(|a, b| a.session == b.session && a.candidate_hash == b.candidate_hash); + + // if there were any duplicates, indicate that to the caller. + if n == statement_sets.len() { + Ok(()) + } else { + Err(()) + } + } + + /// Filter a single dispute statement set. + /// + /// Used in cases where more granular control is required, i.e. when + /// accounting for maximum block weight. + fn filter_dispute_data( + statement_set: DisputeStatementSet, + post_conclusion_acceptance_period: BlockNumber, + ) -> Option; + + /// Handle sets of dispute statements corresponding to 0 or more candidates. + /// Returns a vector of freshly created disputes. + fn process_checked_multi_dispute_data( + statement_sets: &CheckedMultiDisputeStatementSet, + ) -> Result, DispatchError>; + + /// Note that the given candidate has been included. + fn note_included( + session: SessionIndex, + candidate_hash: CandidateHash, + included_in: BlockNumber, + ); + + /// Retrieve the included state of a given candidate in a particular session. If it + /// returns `Some`, then we have a local dispute for the given `candidate_hash`. + fn included_state(session: SessionIndex, candidate_hash: CandidateHash) -> Option; + + /// Whether the given candidate concluded invalid in a dispute with supermajority. + fn concluded_invalid(session: SessionIndex, candidate_hash: CandidateHash) -> bool; + + /// Called by the initializer to initialize the disputes pallet. + fn initializer_initialize(now: BlockNumber) -> Weight; + + /// Called by the initializer to finalize the disputes pallet. + fn initializer_finalize(); + + /// Called by the initializer to note that a new session has started. + fn initializer_on_new_session(notification: &SessionChangeNotification); +} + +impl DisputesHandler for () { + fn is_frozen() -> bool { + false + } + + fn deduplicate_and_sort_dispute_data( + statement_sets: &mut MultiDisputeStatementSet, + ) -> Result<(), ()> { + statement_sets.clear(); + Ok(()) + } + + fn filter_dispute_data( + _set: DisputeStatementSet, + _post_conclusion_acceptance_period: BlockNumber, + ) -> Option { + None + } + + fn process_checked_multi_dispute_data( + _statement_sets: &CheckedMultiDisputeStatementSet, + ) -> Result, DispatchError> { + Ok(Vec::new()) + } + + fn note_included( + _session: SessionIndex, + _candidate_hash: CandidateHash, + _included_in: BlockNumber, + ) { + } + + fn included_state( + _session: SessionIndex, + _candidate_hash: CandidateHash, + ) -> Option { + None + } + + fn concluded_invalid(_session: SessionIndex, _candidate_hash: CandidateHash) -> bool { + false + } + + fn initializer_initialize(_now: BlockNumber) -> Weight { + Weight::zero() + } + + fn initializer_finalize() {} + + fn initializer_on_new_session(_notification: &SessionChangeNotification) {} +} + +impl DisputesHandler> for pallet::Pallet +where + BlockNumberFor: Ord, +{ + fn is_frozen() -> bool { + pallet::Pallet::::is_frozen() + } + + fn filter_dispute_data( + set: DisputeStatementSet, + post_conclusion_acceptance_period: BlockNumberFor, + ) -> Option { + pallet::Pallet::::filter_dispute_data(&set, post_conclusion_acceptance_period) + .filter_statement_set(set) + } + + fn process_checked_multi_dispute_data( + statement_sets: &CheckedMultiDisputeStatementSet, + ) -> Result, DispatchError> { + pallet::Pallet::::process_checked_multi_dispute_data(statement_sets) + } + + fn note_included( + session: SessionIndex, + candidate_hash: CandidateHash, + included_in: BlockNumberFor, + ) { + pallet::Pallet::::note_included(session, candidate_hash, included_in) + } + + fn included_state( + session: SessionIndex, + candidate_hash: CandidateHash, + ) -> Option> { + pallet::Pallet::::included_state(session, candidate_hash) + } + + fn concluded_invalid(session: SessionIndex, candidate_hash: CandidateHash) -> bool { + pallet::Pallet::::concluded_invalid(session, candidate_hash) + } + + fn initializer_initialize(now: BlockNumberFor) -> Weight { + pallet::Pallet::::initializer_initialize(now) + } + + fn initializer_finalize() { + pallet::Pallet::::initializer_finalize() + } + + fn initializer_on_new_session(notification: &SessionChangeNotification>) { + pallet::Pallet::::initializer_on_new_session(notification) + } +} + +pub trait WeightInfo { + fn force_unfreeze() -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn force_unfreeze() -> Weight { + Weight::zero() + } +} + +pub use pallet::*; +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config + configuration::Config + session_info::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type RewardValidators: RewardValidators; + type SlashingHandler: SlashingHandler>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + /// The current storage version. + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::without_storage_info] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + /// The last pruned session, if any. All data stored by this module + /// references sessions. + #[pallet::storage] + pub(super) type LastPrunedSession = StorageValue<_, SessionIndex>; + + /// All ongoing or concluded disputes for the last several sessions. + #[pallet::storage] + pub(super) type Disputes = StorageDoubleMap< + _, + Twox64Concat, + SessionIndex, + Blake2_128Concat, + CandidateHash, + DisputeState>, + >; + + /// Backing votes stored for each dispute. + /// This storage is used for slashing. + #[pallet::storage] + pub(super) type BackersOnDisputes = StorageDoubleMap< + _, + Twox64Concat, + SessionIndex, + Blake2_128Concat, + CandidateHash, + BTreeSet, + >; + + /// All included blocks on the chain, as well as the block number in this chain that + /// should be reverted back to if the candidate is disputed and determined to be invalid. + #[pallet::storage] + pub(super) type Included = StorageDoubleMap< + _, + Twox64Concat, + SessionIndex, + Blake2_128Concat, + CandidateHash, + BlockNumberFor, + >; + + /// Whether the chain is frozen. Starts as `None`. When this is `Some`, + /// the chain will not accept any new parachain blocks for backing or inclusion, + /// and its value indicates the last valid block number in the chain. + /// It can only be set back to `None` by governance intervention. + #[pallet::storage] + #[pallet::getter(fn last_valid_block)] + pub(super) type Frozen = StorageValue<_, Option>, ValueQuery>; + + #[pallet::event] + #[pallet::generate_deposit(pub fn deposit_event)] + pub enum Event { + /// A dispute has been initiated. \[candidate hash, dispute location\] + DisputeInitiated(CandidateHash, DisputeLocation), + /// A dispute has concluded for or against a candidate. + /// `\[para id, candidate hash, dispute result\]` + DisputeConcluded(CandidateHash, DisputeResult), + /// A dispute has concluded with supermajority against a candidate. + /// Block authors should no longer build on top of this head and should + /// instead revert the block at the given height. This should be the + /// number of the child of the last known valid block in the chain. + Revert(BlockNumberFor), + } + + #[pallet::error] + pub enum Error { + /// Duplicate dispute statement sets provided. + DuplicateDisputeStatementSets, + /// Ancient dispute statement provided. + AncientDisputeStatement, + /// Validator index on statement is out of bounds for session. + ValidatorIndexOutOfBounds, + /// Invalid signature on statement. + InvalidSignature, + /// Validator vote submitted more than once to dispute. + DuplicateStatement, + /// A dispute where there are only votes on one side. + SingleSidedDispute, + /// A dispute vote from a malicious backer. + MaliciousBacker, + /// No backing votes were provides along dispute statements. + MissingBackingVotes, + /// Unconfirmed dispute statement sets provided. + UnconfirmedDispute, + } + + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight(::WeightInfo::force_unfreeze())] + pub fn force_unfreeze(origin: OriginFor) -> DispatchResult { + ensure_root(origin)?; + Frozen::::set(None); + Ok(()) + } + } +} + +bitflags::bitflags! { + #[derive(Default)] + struct DisputeStateFlags: u8 { + /// The byzantine threshold of `f + 1` votes (and hence participating validators) was reached. + const CONFIRMED = 0b0001; + /// Is the supermajority for validity of the dispute reached. + const FOR_SUPERMAJORITY = 0b0010; + /// Is the supermajority against the validity of the block reached. + const AGAINST_SUPERMAJORITY = 0b0100; + /// Is there f+1 against the validity of the block reached + const AGAINST_BYZANTINE = 0b1000; + } +} + +impl DisputeStateFlags { + fn from_state(state: &DisputeState) -> Self { + // Only correct since `DisputeState` is _always_ initialized + // with the validator set based on the session. + let n = state.validators_for.len(); + + let byzantine_threshold = byzantine_threshold(n); + let supermajority_threshold = supermajority_threshold(n); + + let mut flags = DisputeStateFlags::default(); + let all_participants = state.validators_for.clone() | state.validators_against.clone(); + if all_participants.count_ones() > byzantine_threshold { + flags |= DisputeStateFlags::CONFIRMED; + } + + if state.validators_for.count_ones() >= supermajority_threshold { + flags |= DisputeStateFlags::FOR_SUPERMAJORITY; + } + + if state.validators_against.count_ones() > byzantine_threshold { + flags |= DisputeStateFlags::AGAINST_BYZANTINE; + } + + if state.validators_against.count_ones() >= supermajority_threshold { + flags |= DisputeStateFlags::AGAINST_SUPERMAJORITY; + } + + flags + } +} + +struct ImportSummary { + /// The new state, with all votes imported. + state: DisputeState, + /// List of validators who backed the candidate being disputed. + backers: BTreeSet, + /// Validators to slash for being (wrongly) on the AGAINST side. + slash_against: Vec, + /// Validators to slash for being (wrongly) on the FOR side. + slash_for: Vec, + // New participants in the dispute. + new_participants: bitvec::vec::BitVec, + // Difference in state flags from previous. + new_flags: DisputeStateFlags, +} + +#[derive(RuntimeDebug, PartialEq, Eq)] +enum VoteImportError { + /// Validator index was outside the range of valid validator indices in the given session. + ValidatorIndexOutOfBounds, + /// Found a duplicate statement in the dispute statement set. + DuplicateStatement, + /// Found an explicit valid statement after backing statement. + /// Backers should not participate in explicit voting so this is + /// only possible on malicious backers. + MaliciousBacker, +} + +#[derive(RuntimeDebug, Copy, Clone, PartialEq, Eq)] +enum VoteKind { + /// A backing vote that is counted as "for" vote in dispute resolution. + Backing, + /// Either an approval vote or and explicit dispute "for" vote. + ExplicitValid, + /// An explicit dispute "against" vote. + Invalid, +} + +impl From<&DisputeStatement> for VoteKind { + fn from(statement: &DisputeStatement) -> Self { + if statement.is_backing() { + Self::Backing + } else if statement.indicates_validity() { + Self::ExplicitValid + } else { + Self::Invalid + } + } +} + +impl VoteKind { + fn is_valid(&self) -> bool { + match self { + Self::Backing | Self::ExplicitValid => true, + Self::Invalid => false, + } + } + + fn is_backing(&self) -> bool { + match self { + Self::Backing => true, + Self::Invalid | Self::ExplicitValid => false, + } + } +} + +impl From for Error { + fn from(e: VoteImportError) -> Self { + match e { + VoteImportError::ValidatorIndexOutOfBounds => Error::::ValidatorIndexOutOfBounds, + VoteImportError::DuplicateStatement => Error::::DuplicateStatement, + VoteImportError::MaliciousBacker => Error::::MaliciousBacker, + } + } +} + +/// A transport statement bit change for a single validator. +#[derive(RuntimeDebug, PartialEq, Eq)] +struct ImportUndo { + /// The validator index to which to associate the statement import. + validator_index: ValidatorIndex, + /// The kind and direction of the vote. + vote_kind: VoteKind, + /// Has the validator participated before, i.e. in backing or + /// with an opposing vote. + new_participant: bool, +} + +struct DisputeStateImporter { + state: DisputeState, + backers: BTreeSet, + now: BlockNumber, + new_participants: bitvec::vec::BitVec, + pre_flags: DisputeStateFlags, + pre_state: DisputeState, + // The list of backing votes before importing the batch of votes. This field should be + // initialized as empty on the first import of the dispute votes and should remain non-empty + // afterwards. + // + // If a dispute has concluded and the candidate was found invalid, we may want to slash as many + // backers as possible. This list allows us to slash these backers once their votes have been + // imported post dispute conclusion. + pre_backers: BTreeSet, +} + +impl DisputeStateImporter { + fn new( + state: DisputeState, + backers: BTreeSet, + now: BlockNumber, + ) -> Self { + let pre_flags = DisputeStateFlags::from_state(&state); + let new_participants = bitvec::bitvec![u8, BitOrderLsb0; 0; state.validators_for.len()]; + // consistency checks + for i in backers.iter() { + debug_assert_eq!(state.validators_for.get(i.0 as usize).map(|b| *b), Some(true)); + } + let pre_state = state.clone(); + let pre_backers = backers.clone(); + + DisputeStateImporter { + state, + backers, + now, + new_participants, + pre_flags, + pre_state, + pre_backers, + } + } + + fn import( + &mut self, + validator: ValidatorIndex, + kind: VoteKind, + ) -> Result { + let (bits, other_bits) = if kind.is_valid() { + (&mut self.state.validators_for, &mut self.state.validators_against) + } else { + (&mut self.state.validators_against, &mut self.state.validators_for) + }; + + // out of bounds or already participated + match bits.get(validator.0 as usize).map(|b| *b) { + None => return Err(VoteImportError::ValidatorIndexOutOfBounds), + Some(true) => { + // We allow backing statements to be imported after an + // explicit "for" vote, but not the other way around. + match (kind.is_backing(), self.backers.contains(&validator)) { + (true, true) | (false, false) => + return Err(VoteImportError::DuplicateStatement), + (false, true) => return Err(VoteImportError::MaliciousBacker), + (true, false) => {}, + } + }, + Some(false) => {}, + } + + // consistency check + debug_assert!((validator.0 as usize) < self.new_participants.len()); + + let mut undo = + ImportUndo { validator_index: validator, vote_kind: kind, new_participant: false }; + + bits.set(validator.0 as usize, true); + if kind.is_backing() { + let is_new = self.backers.insert(validator); + // invariant check + debug_assert!(is_new); + } + + // New participants tracks those validators by index, which didn't appear on either + // side of the dispute until now (so they make a first appearance). + // To verify this we need to assure they also were not part of the opposing side before. + if other_bits.get(validator.0 as usize).map_or(false, |b| !*b) { + undo.new_participant = true; + self.new_participants.set(validator.0 as usize, true); + } + + Ok(undo) + } + + /// Revert a done transaction. + fn undo(&mut self, undo: ImportUndo) { + if undo.vote_kind.is_valid() { + self.state.validators_for.set(undo.validator_index.0 as usize, false); + } else { + self.state.validators_against.set(undo.validator_index.0 as usize, false); + } + + if undo.vote_kind.is_backing() { + self.backers.remove(&undo.validator_index); + } + + if undo.new_participant { + self.new_participants.set(undo.validator_index.0 as usize, false); + } + } + + /// Collect all dispute votes. + fn finish(mut self) -> ImportSummary { + let pre_flags = self.pre_flags; + let post_flags = DisputeStateFlags::from_state(&self.state); + + let pre_post_contains = |flags| (pre_flags.contains(flags), post_flags.contains(flags)); + + // 1. Check for FOR supermajority. + let slash_against = match pre_post_contains(DisputeStateFlags::FOR_SUPERMAJORITY) { + (false, true) => { + if self.state.concluded_at.is_none() { + self.state.concluded_at = Some(self.now.clone()); + } + + // provide AGAINST voters to slash. + self.state + .validators_against + .iter_ones() + .map(|i| ValidatorIndex(i as _)) + .collect() + }, + (true, true) => { + // provide new AGAINST voters to slash. + self.state + .validators_against + .iter_ones() + .filter(|i| self.pre_state.validators_against.get(*i).map_or(false, |b| !*b)) + .map(|i| ValidatorIndex(i as _)) + .collect() + }, + (true, false) => { + log::error!("Dispute statements are never removed. This is a bug"); + Vec::new() + }, + (false, false) => Vec::new(), + }; + + // 2. Check for AGAINST supermajority. + let slash_for = match pre_post_contains(DisputeStateFlags::AGAINST_SUPERMAJORITY) { + (false, true) => { + if self.state.concluded_at.is_none() { + self.state.concluded_at = Some(self.now.clone()); + } + + // provide FOR voters to slash. + self.state.validators_for.iter_ones().map(|i| ValidatorIndex(i as _)).collect() + }, + (true, true) => { + // provide new FOR voters to slash including new backers + // who might have voted FOR before + let new_backing_vote = |i: &ValidatorIndex| -> bool { + !self.pre_backers.contains(i) && self.backers.contains(i) + }; + self.state + .validators_for + .iter_ones() + .filter(|i| { + self.pre_state.validators_for.get(*i).map_or(false, |b| !*b) || + new_backing_vote(&ValidatorIndex(*i as _)) + }) + .map(|i| ValidatorIndex(i as _)) + .collect() + }, + (true, false) => { + log::error!("Dispute statements are never removed. This is a bug"); + Vec::new() + }, + (false, false) => Vec::new(), + }; + + ImportSummary { + state: self.state, + backers: self.backers, + slash_against, + slash_for, + new_participants: self.new_participants, + new_flags: post_flags - pre_flags, + } + } +} + +// A filter on a dispute statement set. +#[derive(PartialEq)] +#[cfg_attr(test, derive(Debug))] +enum StatementSetFilter { + // Remove the entire dispute statement set. + RemoveAll, + // Remove the votes with given index from the statement set. + RemoveIndices(Vec), +} + +impl StatementSetFilter { + fn filter_statement_set( + self, + mut statement_set: DisputeStatementSet, + ) -> Option { + match self { + StatementSetFilter::RemoveAll => None, + StatementSetFilter::RemoveIndices(mut indices) => { + indices.sort(); + indices.dedup(); + + // reverse order ensures correctness + for index in indices.into_iter().rev() { + // `swap_remove` guarantees linear complexity. + statement_set.statements.swap_remove(index); + } + + if statement_set.statements.is_empty() { + None + } else { + // we just checked correctness when filtering. + Some(CheckedDisputeStatementSet::unchecked_from_unchecked(statement_set)) + } + }, + } + } + + fn remove_index(&mut self, i: usize) { + if let StatementSetFilter::RemoveIndices(ref mut indices) = *self { + indices.push(i) + } + } +} + +impl Pallet { + /// Called by the initializer to initialize the disputes module. + pub(crate) fn initializer_initialize(_now: BlockNumberFor) -> Weight { + Weight::zero() + } + + /// Called by the initializer to finalize the disputes pallet. + pub(crate) fn initializer_finalize() {} + + /// Called by the initializer to note a new session in the disputes pallet. + pub(crate) fn initializer_on_new_session( + notification: &SessionChangeNotification>, + ) { + let config = >::config(); + + if notification.session_index <= config.dispute_period + 1 { + return + } + + let pruning_target = notification.session_index - config.dispute_period - 1; + + LastPrunedSession::::mutate(|last_pruned| { + let to_prune = if let Some(last_pruned) = last_pruned { + *last_pruned + 1..=pruning_target + } else { + pruning_target..=pruning_target + }; + + for to_prune in to_prune { + // This should be small, as disputes are rare, so `None` is fine. + #[allow(deprecated)] + >::remove_prefix(to_prune, None); + #[allow(deprecated)] + >::remove_prefix(to_prune, None); + + // This is larger, and will be extracted to the `shared` pallet for more proper + // pruning. TODO: https://github.com/paritytech/polkadot/issues/3469 + #[allow(deprecated)] + >::remove_prefix(to_prune, None); + } + + *last_pruned = Some(pruning_target); + }); + } + + /// Handle sets of dispute statements corresponding to 0 or more candidates. + /// Returns a vector of freshly created disputes. + /// + /// Assumes `statement_sets` were already de-duplicated. + /// + /// # Warning + /// + /// This functions modifies the state when failing. It is expected to be called in inherent, + /// and to fail the extrinsic on error. As invalid inherents are not allowed, the dirty state + /// is not committed. + pub(crate) fn process_checked_multi_dispute_data( + statement_sets: &CheckedMultiDisputeStatementSet, + ) -> Result, DispatchError> { + let config = >::config(); + + let mut fresh = Vec::with_capacity(statement_sets.len()); + for statement_set in statement_sets { + let dispute_target = { + let statement_set = statement_set.as_ref(); + (statement_set.session, statement_set.candidate_hash) + }; + if Self::process_checked_dispute_data( + statement_set, + config.dispute_post_conclusion_acceptance_period, + )? { + fresh.push(dispute_target); + } + } + + Ok(fresh) + } + + // Given a statement set, this produces a filter to be applied to the statement set. + // It either removes the entire dispute statement set or some specific votes from it. + // + // Votes which are duplicate or already known by the chain are filtered out. + // The entire set is removed if the dispute is both, ancient and concluded. + // Disputes without enough votes to get confirmed are also filtered out. + fn filter_dispute_data( + set: &DisputeStatementSet, + post_conclusion_acceptance_period: BlockNumberFor, + ) -> StatementSetFilter { + let mut filter = StatementSetFilter::RemoveIndices(Vec::new()); + + // Dispute statement sets on any dispute which concluded + // before this point are to be rejected. + let now = >::block_number(); + let oldest_accepted = now.saturating_sub(post_conclusion_acceptance_period); + + // Load session info to access validators + let session_info = match >::session_info(set.session) { + Some(s) => s, + None => return StatementSetFilter::RemoveAll, + }; + + let n_validators = session_info.validators.len(); + + // Check for ancient. + let dispute_state = { + if let Some(dispute_state) = >::get(&set.session, &set.candidate_hash) { + if dispute_state.concluded_at.as_ref().map_or(false, |c| c < &oldest_accepted) { + return StatementSetFilter::RemoveAll + } + + dispute_state + } else { + // No state in storage, this indicates it's the first dispute statement set as well. + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 0; n_validators], + validators_against: bitvec![u8, BitOrderLsb0; 0; n_validators], + start: now, + concluded_at: None, + } + } + }; + + let backers = + >::get(&set.session, &set.candidate_hash).unwrap_or_default(); + + // Check and import all votes. + let summary = { + let mut importer = DisputeStateImporter::new(dispute_state, backers, now); + for (i, (statement, validator_index, signature)) in set.statements.iter().enumerate() { + // ensure the validator index is present in the session info + // and the signature is valid + let validator_public = match session_info.validators.get(*validator_index) { + None => { + filter.remove_index(i); + continue + }, + Some(v) => v, + }; + + let kind = VoteKind::from(statement); + + let undo = match importer.import(*validator_index, kind) { + Ok(u) => u, + Err(_) => { + filter.remove_index(i); + continue + }, + }; + + // Check signature after attempting import. + // + // Since we expect that this filter will be applied to + // disputes long after they're concluded, 99% of the time, + // the duplicate filter above will catch them before needing + // to do a heavy signature check. + // + // This is only really important until the post-conclusion acceptance threshold + // is reached, and then no part of this loop will be hit. + if let Err(()) = check_signature( + &validator_public, + set.candidate_hash, + set.session, + statement, + signature, + ) { + importer.undo(undo); + filter.remove_index(i); + continue + }; + } + + importer.finish() + }; + + // Reject disputes which don't have at least one vote on each side. + if summary.state.validators_for.count_ones() == 0 || + summary.state.validators_against.count_ones() == 0 + { + return StatementSetFilter::RemoveAll + } + + // Reject disputes containing less votes than needed for confirmation. + if (summary.state.validators_for.clone() | &summary.state.validators_against).count_ones() <= + byzantine_threshold(summary.state.validators_for.len()) + { + return StatementSetFilter::RemoveAll + } + + filter + } + + /// Handle a set of dispute statements corresponding to a single candidate. + /// + /// Fails if the dispute data is invalid. Returns a Boolean indicating whether the + /// dispute is fresh. + fn process_checked_dispute_data( + set: &CheckedDisputeStatementSet, + dispute_post_conclusion_acceptance_period: BlockNumberFor, + ) -> Result { + // Dispute statement sets on any dispute which concluded + // before this point are to be rejected. + let now = >::block_number(); + let oldest_accepted = now.saturating_sub(dispute_post_conclusion_acceptance_period); + + let set = set.as_ref(); + + // Load session info to access validators + let session_info = match >::session_info(set.session) { + Some(s) => s, + None => return Err(Error::::AncientDisputeStatement.into()), + }; + + let n_validators = session_info.validators.len(); + + // Check for ancient. + let (fresh, dispute_state) = { + if let Some(dispute_state) = >::get(&set.session, &set.candidate_hash) { + ensure!( + dispute_state.concluded_at.as_ref().map_or(true, |c| c >= &oldest_accepted), + Error::::AncientDisputeStatement, + ); + + (false, dispute_state) + } else { + ( + true, + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 0; n_validators], + validators_against: bitvec![u8, BitOrderLsb0; 0; n_validators], + start: now, + concluded_at: None, + }, + ) + } + }; + + let backers = + >::get(&set.session, &set.candidate_hash).unwrap_or_default(); + + // Import all votes. They were pre-checked. + let summary = { + let mut importer = DisputeStateImporter::new(dispute_state, backers, now); + for (statement, validator_index, _signature) in &set.statements { + let kind = VoteKind::from(statement); + + importer.import(*validator_index, kind).map_err(Error::::from)?; + } + + importer.finish() + }; + + // Reject disputes which don't have at least one vote on each side. + ensure!( + summary.state.validators_for.count_ones() > 0 && + summary.state.validators_against.count_ones() > 0, + Error::::SingleSidedDispute, + ); + + // Reject disputes containing less votes than needed for confirmation. + ensure!( + (summary.state.validators_for.clone() | &summary.state.validators_against).count_ones() > + byzantine_threshold(summary.state.validators_for.len()), + Error::::UnconfirmedDispute, + ); + let backers = summary.backers; + // Reject statements with no accompanying backing votes. + ensure!(!backers.is_empty(), Error::::MissingBackingVotes); + >::insert(&set.session, &set.candidate_hash, backers.clone()); + // AUDIT: from now on, no error should be returned. + + let DisputeStatementSet { ref session, ref candidate_hash, .. } = set; + let session = *session; + let candidate_hash = *candidate_hash; + + if fresh { + let is_local = >::contains_key(&session, &candidate_hash); + + Self::deposit_event(Event::DisputeInitiated( + candidate_hash, + if is_local { DisputeLocation::Local } else { DisputeLocation::Remote }, + )); + } + + { + if summary.new_flags.contains(DisputeStateFlags::FOR_SUPERMAJORITY) { + Self::deposit_event(Event::DisputeConcluded(candidate_hash, DisputeResult::Valid)); + } + + // It is possible, although unexpected, for a dispute to conclude twice. + // This would require f+1 validators to vote in both directions. + // A dispute cannot conclude more than once in each direction. + + if summary.new_flags.contains(DisputeStateFlags::AGAINST_SUPERMAJORITY) { + Self::deposit_event(Event::DisputeConcluded( + candidate_hash, + DisputeResult::Invalid, + )); + } + } + + // Reward statements. + T::RewardValidators::reward_dispute_statement( + session, + summary.new_participants.iter_ones().map(|i| ValidatorIndex(i as _)), + ); + + // Slash participants on a losing side. + { + // a valid candidate, according to 2/3. Punish those on the 'against' side. + T::SlashingHandler::punish_against_valid( + session, + candidate_hash, + summary.slash_against, + backers.clone(), + ); + + // an invalid candidate, according to 2/3. Punish those on the 'for' side. + T::SlashingHandler::punish_for_invalid( + session, + candidate_hash, + summary.slash_for, + backers, + ); + } + + >::insert(&session, &candidate_hash, &summary.state); + + // Freeze if the INVALID votes against some local candidate are above the byzantine + // threshold + if summary.new_flags.contains(DisputeStateFlags::AGAINST_BYZANTINE) { + if let Some(revert_to) = >::get(&session, &candidate_hash) { + Self::revert_and_freeze(revert_to); + } + } + + Ok(fresh) + } + + #[allow(unused)] + pub(crate) fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState>)> + { + >::iter().collect() + } + + pub(crate) fn note_included( + session: SessionIndex, + candidate_hash: CandidateHash, + included_in: BlockNumberFor, + ) { + if included_in.is_zero() { + return + } + + let revert_to = included_in - One::one(); + + >::insert(&session, &candidate_hash, revert_to); + + if let Some(state) = >::get(&session, candidate_hash) { + if has_supermajority_against(&state) { + Self::revert_and_freeze(revert_to); + } + } + } + + pub(crate) fn included_state( + session: SessionIndex, + candidate_hash: CandidateHash, + ) -> Option> { + >::get(session, candidate_hash) + } + + pub(crate) fn concluded_invalid(session: SessionIndex, candidate_hash: CandidateHash) -> bool { + >::get(&session, &candidate_hash).map_or(false, |dispute| { + // A dispute that has concluded with supermajority-against. + has_supermajority_against(&dispute) + }) + } + + pub(crate) fn is_frozen() -> bool { + Self::last_valid_block().is_some() + } + + pub(crate) fn revert_and_freeze(revert_to: BlockNumberFor) { + if Self::last_valid_block().map_or(true, |last| last > revert_to) { + Frozen::::set(Some(revert_to)); + + // The `Revert` log is about reverting a block, not reverting to a block. + // If we want to revert to block X in the current chain, we need to revert + // block X+1. + let revert = revert_to + One::one(); + Self::deposit_event(Event::Revert(revert)); + frame_system::Pallet::::deposit_log( + ConsensusLog::Revert(revert.saturated_into()).into(), + ); + } + } +} + +fn has_supermajority_against(dispute: &DisputeState) -> bool { + let supermajority_threshold = supermajority_threshold(dispute.validators_against.len()); + dispute.validators_against.count_ones() >= supermajority_threshold +} + +fn check_signature( + validator_public: &ValidatorId, + candidate_hash: CandidateHash, + session: SessionIndex, + statement: &DisputeStatement, + validator_signature: &ValidatorSignature, +) -> Result<(), ()> { + let payload = match *statement { + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit) => + ExplicitDisputeStatement { valid: true, candidate_hash, session }.signing_payload(), + DisputeStatement::Valid(ValidDisputeStatementKind::BackingSeconded(inclusion_parent)) => + CompactStatement::Seconded(candidate_hash).signing_payload(&SigningContext { + session_index: session, + parent_hash: inclusion_parent, + }), + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid(inclusion_parent)) => + CompactStatement::Valid(candidate_hash).signing_payload(&SigningContext { + session_index: session, + parent_hash: inclusion_parent, + }), + DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking) => + ApprovalVote(candidate_hash).signing_payload(session), + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit) => + ExplicitDisputeStatement { valid: false, candidate_hash, session }.signing_payload(), + }; + + let start = get_current_time(); + + let res = + if validator_signature.verify(&payload[..], &validator_public) { Ok(()) } else { Err(()) }; + + let end = get_current_time(); + + METRICS.on_signature_check_complete(end.saturating_sub(start)); // ns + + res +} diff --git a/polkadot/runtime/parachains/src/disputes/benchmarking.rs b/polkadot/runtime/parachains/src/disputes/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..05f4b3f1ac8198ebdb7cf161f5e95bd9f7152fc9 --- /dev/null +++ b/polkadot/runtime/parachains/src/disputes/benchmarking.rs @@ -0,0 +1,36 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use frame_benchmarking::benchmarks; +use frame_system::RawOrigin; +use sp_runtime::traits::One; + +benchmarks! { + force_unfreeze { + Frozen::::set(Some(One::one())); + }: _(RawOrigin::Root) + verify { + assert!(Frozen::::get().is_none()) + } + + impl_benchmark_test_suite!( + Pallet, + crate::mock::new_test_ext(Default::default()), + crate::mock::Test + ); +} diff --git a/polkadot/runtime/parachains/src/disputes/migration.rs b/polkadot/runtime/parachains/src/disputes/migration.rs new file mode 100644 index 0000000000000000000000000000000000000000..ccd367e41b36e619d246bcd2785ae771aeafdec3 --- /dev/null +++ b/polkadot/runtime/parachains/src/disputes/migration.rs @@ -0,0 +1,97 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Storage migration(s) related to disputes pallet + +use frame_support::traits::StorageVersion; + +pub mod v1 { + use super::*; + use crate::disputes::{Config, Pallet}; + use frame_support::{ + pallet_prelude::*, storage_alias, traits::OnRuntimeUpgrade, weights::Weight, + }; + use primitives::SessionIndex; + use sp_std::prelude::*; + + #[storage_alias] + type SpamSlots = StorageMap, Twox64Concat, SessionIndex, Vec>; + + pub struct MigrateToV1(sp_std::marker::PhantomData); + impl OnRuntimeUpgrade for MigrateToV1 { + fn on_runtime_upgrade() -> Weight { + let mut weight: Weight = Weight::zero(); + + if StorageVersion::get::>() < 1 { + log::info!(target: crate::disputes::LOG_TARGET, "Migrating disputes storage to v1"); + weight += migrate_to_v1::(); + StorageVersion::new(1).put::>(); + weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + } else { + log::info!( + target: crate::disputes::LOG_TARGET, + "Disputes storage up to date - no need for migration" + ); + } + + weight + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + log::trace!( + target: crate::disputes::LOG_TARGET, + "SpamSlots before migration: {}", + SpamSlots::::iter().count() + ); + ensure!( + StorageVersion::get::>() == 0, + "Storage version should be less than `1` before the migration", + ); + Ok(Vec::new()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + log::trace!(target: crate::disputes::LOG_TARGET, "Running post_upgrade()"); + ensure!( + StorageVersion::get::>() >= 1, + "Storage version should be `1` after the migration" + ); + ensure!( + SpamSlots::::iter().count() == 0, + "SpamSlots should be empty after the migration" + ); + Ok(()) + } + } + + /// Migrates the pallet storage to the most recent version, checking and setting the + /// `StorageVersion`. + pub fn migrate_to_v1() -> Weight { + let mut weight: Weight = Weight::zero(); + + // SpamSlots should not contain too many keys so removing everything at once should be safe + let res = SpamSlots::::clear(u32::MAX, None); + // `loops` is the number of iterations => used to calculate read weights + // `backend` is the number of keys removed from the backend => used to calculate write + // weights + weight = weight + .saturating_add(T::DbWeight::get().reads_writes(res.loops as u64, res.backend as u64)); + + weight + } +} diff --git a/polkadot/runtime/parachains/src/disputes/slashing.rs b/polkadot/runtime/parachains/src/disputes/slashing.rs new file mode 100644 index 0000000000000000000000000000000000000000..b27a7ab1ad734162e11f808825db46e59979b23b --- /dev/null +++ b/polkadot/runtime/parachains/src/disputes/slashing.rs @@ -0,0 +1,728 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Dispute slashing pallet. +//! +//! Once a dispute is concluded, we want to slash validators who were on the +//! wrong side of the dispute. The slashing amount depends on whether the +//! candidate was valid (none at the moment) or invalid (big). In addition to +//! that, we might want to kick out the validators from the active set. +//! Currently, we limit slashing to the backing group for invalid disputes. +//! +//! The `offences` pallet from Substrate provides us with a way to do both. +//! Currently, the interface expects us to provide staking information including +//! nominator exposure in order to submit an offence. +//! +//! Normally, we'd able to fetch this information from the runtime as soon as +//! the dispute is concluded. This is also what `im-online` pallet does. +//! However, since a dispute can conclude several sessions after the candidate +//! was backed (see `dispute_period` in `HostConfiguration`), we can't rely on +//! this information being available in the context of the current block. The +//! `babe` and `grandpa` equivocation handlers also have to deal with this +//! problem. +//! +//! Our implementation looks like a hybrid of `im-online` and `grandpa` +//! equivocation handlers. Meaning, we submit an `offence` for the concluded +//! disputes about the current session candidate directly from the runtime. If, +//! however, the dispute is about a past session, we record unapplied slashes on +//! chain, without `FullIdentification` of the offenders. Later on, a block +//! producer can submit an unsigned transaction with `KeyOwnershipProof` of an +//! offender and submit it to the runtime to produce an offence. + +use crate::{disputes, initializer::ValidatorSetCount, session_info::IdentificationTuple}; +use frame_support::{ + dispatch::Pays, + traits::{Defensive, Get, KeyOwnerProofSystem, ValidatorSet, ValidatorSetWithIdentification}, + weights::Weight, +}; +use frame_system::pallet_prelude::BlockNumberFor; + +use primitives::{ + vstaging::slashing::{DisputeProof, DisputesTimeSlot, PendingSlashes, SlashingOffenceKind}, + CandidateHash, SessionIndex, ValidatorId, ValidatorIndex, +}; +use scale_info::TypeInfo; +use sp_runtime::{ + traits::Convert, + transaction_validity::{ + InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity, + TransactionValidityError, ValidTransaction, + }, + KeyTypeId, Perbill, +}; +use sp_session::{GetSessionNumber, GetValidatorCount}; +use sp_staking::offence::{DisableStrategy, Kind, Offence, OffenceError, ReportOffence}; +use sp_std::{ + collections::{btree_map::Entry, btree_set::BTreeSet}, + prelude::*, +}; + +const LOG_TARGET: &str = "runtime::parachains::slashing"; + +// These are constants, but we want to make them configurable +// via `HostConfiguration` in the future. +const SLASH_FOR_INVALID: Perbill = Perbill::from_percent(100); +const SLASH_AGAINST_VALID: Perbill = Perbill::zero(); +const DEFENSIVE_PROOF: &'static str = "disputes module should bail on old session"; + +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; + +/// The benchmarking configuration. +pub trait BenchmarkingConfiguration { + const MAX_VALIDATORS: u32; +} + +pub struct BenchConfig; + +impl BenchmarkingConfiguration for BenchConfig { + const MAX_VALIDATORS: u32 = M; +} + +/// An offence that is filed when a series of validators lost a dispute. +#[derive(TypeInfo)] +#[cfg_attr(feature = "std", derive(Clone, PartialEq, Eq))] +pub struct SlashingOffence { + /// The size of the validator set in that session. + pub validator_set_count: ValidatorSetCount, + /// Should be unique per dispute. + pub time_slot: DisputesTimeSlot, + /// Staking information about the validators that lost the dispute + /// needed for slashing. + pub offenders: Vec, + /// What fraction of the total exposure that should be slashed for + /// this offence. + pub slash_fraction: Perbill, + /// Whether the candidate was valid or invalid. + pub kind: SlashingOffenceKind, +} + +impl Offence for SlashingOffence +where + Offender: Clone, +{ + const ID: Kind = *b"disputes:slashin"; + + type TimeSlot = DisputesTimeSlot; + + fn offenders(&self) -> Vec { + self.offenders.clone() + } + + fn session_index(&self) -> SessionIndex { + self.time_slot.session_index + } + + fn validator_set_count(&self) -> ValidatorSetCount { + self.validator_set_count + } + + fn time_slot(&self) -> Self::TimeSlot { + self.time_slot.clone() + } + + fn disable_strategy(&self) -> DisableStrategy { + match self.kind { + SlashingOffenceKind::ForInvalid => DisableStrategy::Always, + // in the future we might change it based on number of disputes initiated: + // + SlashingOffenceKind::AgainstValid => DisableStrategy::Never, + } + } + + fn slash_fraction(&self, _offenders: u32) -> Perbill { + self.slash_fraction + } +} + +impl SlashingOffence { + fn new( + session_index: SessionIndex, + candidate_hash: CandidateHash, + validator_set_count: ValidatorSetCount, + offenders: Vec, + kind: SlashingOffenceKind, + ) -> Self { + let time_slot = DisputesTimeSlot::new(session_index, candidate_hash); + let slash_fraction = match kind { + SlashingOffenceKind::ForInvalid => SLASH_FOR_INVALID, + SlashingOffenceKind::AgainstValid => SLASH_AGAINST_VALID, + }; + Self { time_slot, validator_set_count, offenders, slash_fraction, kind } + } +} + +/// This type implements `SlashingHandler`. +pub struct SlashValidatorsForDisputes { + _phantom: sp_std::marker::PhantomData, +} + +impl Default for SlashValidatorsForDisputes { + fn default() -> Self { + Self { _phantom: Default::default() } + } +} + +impl SlashValidatorsForDisputes> +where + T: Config>, +{ + /// If in the current session, returns the identified validators. `None` + /// otherwise. + fn maybe_identify_validators( + session_index: SessionIndex, + validators: impl IntoIterator, + ) -> Option>> { + // We use `ValidatorSet::session_index` and not + // `shared::Pallet::session_index()` because at the first block of a new era, + // the `IdentificationOf` of a validator in the previous session might be + // missing, while `shared` pallet would return the same session index as being + // updated at the end of the block. + let current_session = T::ValidatorSet::session_index(); + if session_index == current_session { + let account_keys = crate::session_info::Pallet::::account_keys(session_index); + let account_ids = account_keys.defensive_unwrap_or_default(); + + let fully_identified = validators + .into_iter() + .flat_map(|i| account_ids.get(i.0 as usize).cloned()) + .filter_map(|id| { + >::IdentificationOf::convert( + id.clone() + ).map(|full_id| (id, full_id)) + }) + .collect::>>(); + return Some(fully_identified) + } + None + } + + fn do_punish( + session_index: SessionIndex, + candidate_hash: CandidateHash, + kind: SlashingOffenceKind, + losers: impl IntoIterator, + backers: impl IntoIterator, + ) { + // sanity check for the current implementation + if kind == SlashingOffenceKind::AgainstValid { + debug_assert!(false, "should only slash ForInvalid disputes"); + return + } + let losers: BTreeSet<_> = losers.into_iter().collect(); + if losers.is_empty() { + return + } + let backers: BTreeSet<_> = backers.into_iter().collect(); + let to_punish: Vec = losers.intersection(&backers).cloned().collect(); + if to_punish.is_empty() { + return + } + + let session_info = crate::session_info::Pallet::::session_info(session_index); + let session_info = match session_info.defensive_proof(DEFENSIVE_PROOF) { + Some(info) => info, + None => return, + }; + + let maybe = Self::maybe_identify_validators(session_index, to_punish.iter().cloned()); + if let Some(offenders) = maybe { + let validator_set_count = session_info.discovery_keys.len() as ValidatorSetCount; + let offence = SlashingOffence::new( + session_index, + candidate_hash, + validator_set_count, + offenders, + kind, + ); + // This is the first time we report an offence for this dispute, + // so it is not a duplicate. + let _ = T::HandleReports::report_offence(offence); + return + } + + let keys = to_punish + .into_iter() + .filter_map(|i| session_info.validators.get(i).cloned().map(|id| (i, id))) + .collect(); + let unapplied = PendingSlashes { keys, kind }; + + let append = |old: &mut Option| { + let old = old + .get_or_insert(PendingSlashes { keys: Default::default(), kind: unapplied.kind }); + debug_assert_eq!(old.kind, unapplied.kind); + + old.keys.extend(unapplied.keys) + }; + >::mutate(session_index, candidate_hash, append); + } +} + +impl disputes::SlashingHandler> for SlashValidatorsForDisputes> +where + T: Config>, +{ + fn punish_for_invalid( + session_index: SessionIndex, + candidate_hash: CandidateHash, + losers: impl IntoIterator, + backers: impl IntoIterator, + ) { + let kind = SlashingOffenceKind::ForInvalid; + Self::do_punish(session_index, candidate_hash, kind, losers, backers); + } + + fn punish_against_valid( + _session_index: SessionIndex, + _candidate_hash: CandidateHash, + _losers: impl IntoIterator, + _backers: impl IntoIterator, + ) { + // do nothing for now + // NOTE: changing that requires modifying `do_punish` implementation + } + + fn initializer_initialize(now: BlockNumberFor) -> Weight { + Pallet::::initializer_initialize(now) + } + + fn initializer_finalize() { + Pallet::::initializer_finalize() + } + + fn initializer_on_new_session(session_index: SessionIndex) { + Pallet::::initializer_on_new_session(session_index) + } +} + +/// A trait that defines methods to report an offence (after the slashing report +/// has been validated) and for submitting a transaction to report a slash (from +/// an offchain context). +pub trait HandleReports { + /// The longevity, in blocks, that the offence report is valid for. When + /// using the staking pallet this should be equal to the bonding duration + /// (in blocks, not eras). + type ReportLongevity: Get; + + /// Report an offence. + fn report_offence( + offence: SlashingOffence, + ) -> Result<(), OffenceError>; + + /// Returns true if the offenders at the given time slot has already been + /// reported. + fn is_known_offence( + offenders: &[T::KeyOwnerIdentification], + time_slot: &DisputesTimeSlot, + ) -> bool; + + /// Create and dispatch a slashing report extrinsic. + /// This should be called offchain. + fn submit_unsigned_slashing_report( + dispute_proof: DisputeProof, + key_owner_proof: T::KeyOwnerProof, + ) -> Result<(), sp_runtime::TryRuntimeError>; +} + +impl HandleReports for () { + type ReportLongevity = (); + + fn report_offence( + _offence: SlashingOffence, + ) -> Result<(), OffenceError> { + Ok(()) + } + + fn is_known_offence( + _offenders: &[T::KeyOwnerIdentification], + _time_slot: &DisputesTimeSlot, + ) -> bool { + true + } + + fn submit_unsigned_slashing_report( + _dispute_proof: DisputeProof, + _key_owner_proof: T::KeyOwnerProof, + ) -> Result<(), sp_runtime::TryRuntimeError> { + Ok(()) + } +} + +pub trait WeightInfo { + fn report_dispute_lost(validator_count: ValidatorSetCount) -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn report_dispute_lost(_validator_count: ValidatorSetCount) -> Weight { + Weight::zero() + } +} + +pub use pallet::*; +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config + crate::disputes::Config { + /// The proof of key ownership, used for validating slashing reports. + /// The proof must include the session index and validator count of the + /// session at which the offence occurred. + type KeyOwnerProof: Parameter + GetSessionNumber + GetValidatorCount; + + /// The identification of a key owner, used when reporting slashes. + type KeyOwnerIdentification: Parameter; + + /// A system for proving ownership of keys, i.e. that a given key was + /// part of a validator set, needed for validating slashing reports. + type KeyOwnerProofSystem: KeyOwnerProofSystem< + (KeyTypeId, ValidatorId), + Proof = Self::KeyOwnerProof, + IdentificationTuple = Self::KeyOwnerIdentification, + >; + + /// The slashing report handling subsystem, defines methods to report an + /// offence (after the slashing report has been validated) and for + /// submitting a transaction to report a slash (from an offchain + /// context). NOTE: when enabling slashing report handling (i.e. this + /// type isn't set to `()`) you must use this pallet's + /// `ValidateUnsigned` in the runtime definition. + type HandleReports: HandleReports; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + + /// Benchmarking configuration. + type BenchmarkingConfig: BenchmarkingConfiguration; + } + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + /// Validators pending dispute slashes. + #[pallet::storage] + pub(super) type UnappliedSlashes = StorageDoubleMap< + _, + Twox64Concat, + SessionIndex, + Blake2_128Concat, + CandidateHash, + PendingSlashes, + >; + + /// `ValidatorSetCount` per session. + #[pallet::storage] + pub(super) type ValidatorSetCounts = + StorageMap<_, Twox64Concat, SessionIndex, ValidatorSetCount>; + + #[pallet::error] + pub enum Error { + /// The key ownership proof is invalid. + InvalidKeyOwnershipProof, + /// The session index is too old or invalid. + InvalidSessionIndex, + /// The candidate hash is invalid. + InvalidCandidateHash, + /// There is no pending slash for the given validator index and time + /// slot. + InvalidValidatorIndex, + /// The validator index does not match the validator id. + ValidatorIndexIdMismatch, + /// The given slashing report is valid but already previously reported. + DuplicateSlashingReport, + } + + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight(::WeightInfo::report_dispute_lost( + key_owner_proof.validator_count() + ))] + pub fn report_dispute_lost_unsigned( + origin: OriginFor, + // box to decrease the size of the call + dispute_proof: Box, + key_owner_proof: T::KeyOwnerProof, + ) -> DispatchResultWithPostInfo { + ensure_none(origin)?; + + let validator_set_count = key_owner_proof.validator_count() as ValidatorSetCount; + // check the membership proof to extract the offender's id + let key = (primitives::PARACHAIN_KEY_TYPE_ID, dispute_proof.validator_id.clone()); + let offender = T::KeyOwnerProofSystem::check_proof(key, key_owner_proof) + .ok_or(Error::::InvalidKeyOwnershipProof)?; + + let session_index = dispute_proof.time_slot.session_index; + + // check that there is a pending slash for the given + // validator index and candidate hash + let candidate_hash = dispute_proof.time_slot.candidate_hash; + let try_remove = |v: &mut Option| -> Result<(), DispatchError> { + let pending = v.as_mut().ok_or(Error::::InvalidCandidateHash)?; + if pending.kind != dispute_proof.kind { + return Err(Error::::InvalidCandidateHash.into()) + } + + match pending.keys.entry(dispute_proof.validator_index) { + Entry::Vacant(_) => return Err(Error::::InvalidValidatorIndex.into()), + // check that `validator_index` matches `validator_id` + Entry::Occupied(e) if e.get() != &dispute_proof.validator_id => + return Err(Error::::ValidatorIndexIdMismatch.into()), + Entry::Occupied(e) => { + e.remove(); // the report is correct + }, + } + + // if the last validator is slashed for this dispute, clean up the storage + if pending.keys.is_empty() { + *v = None; + } + + Ok(()) + }; + + >::try_mutate_exists(&session_index, &candidate_hash, try_remove)?; + + let offence = SlashingOffence::new( + session_index, + candidate_hash, + validator_set_count, + vec![offender], + dispute_proof.kind, + ); + + >::report_offence(offence) + .map_err(|_| Error::::DuplicateSlashingReport)?; + + Ok(Pays::No.into()) + } + } + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity { + Self::validate_unsigned(source, call) + } + + fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { + Self::pre_dispatch(call) + } + } +} + +impl Pallet { + /// Called by the initializer to initialize the disputes slashing module. + fn initializer_initialize(_now: BlockNumberFor) -> Weight { + Weight::zero() + } + + /// Called by the initializer to finalize the disputes slashing pallet. + fn initializer_finalize() {} + + /// Called by the initializer to note a new session in the disputes slashing + /// pallet. + fn initializer_on_new_session(session_index: SessionIndex) { + // This should be small, as disputes are limited by spam slots, so no limit is + // fine. + const REMOVE_LIMIT: u32 = u32::MAX; + + let config = >::config(); + if session_index <= config.dispute_period + 1 { + return + } + + let old_session = session_index - config.dispute_period - 1; + let _ = >::clear_prefix(old_session, REMOVE_LIMIT, None); + } + + pub(crate) fn unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, PendingSlashes)> { + >::iter().collect() + } + + pub(crate) fn submit_unsigned_slashing_report( + dispute_proof: DisputeProof, + key_ownership_proof: ::KeyOwnerProof, + ) -> Option<()> { + T::HandleReports::submit_unsigned_slashing_report(dispute_proof, key_ownership_proof).ok() + } +} + +/// Methods for the `ValidateUnsigned` implementation: +/// +/// It restricts calls to `report_dispute_lost_unsigned` to local calls (i.e. +/// extrinsics generated on this node) or that already in a block. This +/// guarantees that only block authors can include unsigned slashing reports. +impl Pallet { + pub fn validate_unsigned(source: TransactionSource, call: &Call) -> TransactionValidity { + if let Call::report_dispute_lost_unsigned { dispute_proof, key_owner_proof } = call { + // discard slashing report not coming from the local node + match source { + TransactionSource::Local | TransactionSource::InBlock => { /* allowed */ }, + _ => { + log::warn!( + target: LOG_TARGET, + "rejecting unsigned transaction because it is not local/in-block." + ); + + return InvalidTransaction::Call.into() + }, + } + + // check report staleness + is_known_offence::(dispute_proof, key_owner_proof)?; + + let longevity = >::ReportLongevity::get(); + + let tag_prefix = match dispute_proof.kind { + SlashingOffenceKind::ForInvalid => "DisputeForInvalid", + SlashingOffenceKind::AgainstValid => "DisputeAgainstValid", + }; + + ValidTransaction::with_tag_prefix(tag_prefix) + // We assign the maximum priority for any report. + .priority(TransactionPriority::max_value()) + // Only one report for the same offender at the same slot. + .and_provides((dispute_proof.time_slot.clone(), dispute_proof.validator_id.clone())) + .longevity(longevity) + // We don't propagate this. This can never be included on a remote node. + .propagate(false) + .build() + } else { + InvalidTransaction::Call.into() + } + } + + pub fn pre_dispatch(call: &Call) -> Result<(), TransactionValidityError> { + if let Call::report_dispute_lost_unsigned { dispute_proof, key_owner_proof } = call { + is_known_offence::(dispute_proof, key_owner_proof) + } else { + Err(InvalidTransaction::Call.into()) + } + } +} + +fn is_known_offence( + dispute_proof: &DisputeProof, + key_owner_proof: &T::KeyOwnerProof, +) -> Result<(), TransactionValidityError> { + // check the membership proof to extract the offender's id + let key = (primitives::PARACHAIN_KEY_TYPE_ID, dispute_proof.validator_id.clone()); + + let offender = T::KeyOwnerProofSystem::check_proof(key, key_owner_proof.clone()) + .ok_or(InvalidTransaction::BadProof)?; + + // check if the offence has already been reported, + // and if so then we can discard the report. + let is_known_offence = >::is_known_offence( + &[offender], + &dispute_proof.time_slot, + ); + + if is_known_offence { + Err(InvalidTransaction::Stale.into()) + } else { + Ok(()) + } +} + +/// Actual `HandleReports` implemention. +/// +/// When configured properly, should be instantiated with +/// `T::KeyOwnerIdentification, Offences, ReportLongevity` parameters. +pub struct SlashingReportHandler { + _phantom: sp_std::marker::PhantomData<(I, R, L)>, +} + +impl Default for SlashingReportHandler { + fn default() -> Self { + Self { _phantom: Default::default() } + } +} + +impl HandleReports for SlashingReportHandler +where + T: Config + frame_system::offchain::SendTransactionTypes>, + R: ReportOffence< + T::AccountId, + T::KeyOwnerIdentification, + SlashingOffence, + >, + L: Get, +{ + type ReportLongevity = L; + + fn report_offence( + offence: SlashingOffence, + ) -> Result<(), OffenceError> { + let reporters = Vec::new(); + R::report_offence(reporters, offence) + } + + fn is_known_offence( + offenders: &[T::KeyOwnerIdentification], + time_slot: &DisputesTimeSlot, + ) -> bool { + , + >>::is_known_offence(offenders, time_slot) + } + + fn submit_unsigned_slashing_report( + dispute_proof: DisputeProof, + key_owner_proof: ::KeyOwnerProof, + ) -> Result<(), sp_runtime::TryRuntimeError> { + use frame_system::offchain::SubmitTransaction; + + let session_index = dispute_proof.time_slot.session_index; + let validator_index = dispute_proof.validator_index.0; + let kind = dispute_proof.kind; + + let call = Call::report_dispute_lost_unsigned { + dispute_proof: Box::new(dispute_proof), + key_owner_proof, + }; + + match SubmitTransaction::>::submit_unsigned_transaction(call.into()) { + Ok(()) => { + log::info!( + target: LOG_TARGET, + "Submitted dispute slashing report, session({}), index({}), kind({:?})", + session_index, + validator_index, + kind, + ); + Ok(()) + }, + Err(()) => { + log::error!( + target: LOG_TARGET, + "Error submitting dispute slashing report, session({}), index({}), kind({:?})", + session_index, + validator_index, + kind, + ); + Err(sp_runtime::DispatchError::Other("")) + }, + } + } +} diff --git a/polkadot/runtime/parachains/src/disputes/slashing/benchmarking.rs b/polkadot/runtime/parachains/src/disputes/slashing/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..3ede1c908802558da7af09a7201d4e18a82f4dbc --- /dev/null +++ b/polkadot/runtime/parachains/src/disputes/slashing/benchmarking.rs @@ -0,0 +1,163 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use crate::{disputes::SlashingHandler, initializer, shared}; +use frame_benchmarking::{benchmarks, whitelist_account}; +use frame_support::traits::{OnFinalize, OnInitialize}; +use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin}; +use pallet_staking::testing_utils::create_validators; +use parity_scale_codec::Decode; +use primitives::{Hash, PARACHAIN_KEY_TYPE_ID}; +use sp_runtime::traits::{One, OpaqueKeys, StaticLookup}; +use sp_session::MembershipProof; + +// Candidate hash of the disputed candidate. +const CANDIDATE_HASH: CandidateHash = CandidateHash(Hash::zero()); + +pub trait Config: + pallet_session::Config + + pallet_session::historical::Config + + pallet_staking::Config + + super::Config + + shared::Config + + initializer::Config +{ +} + +fn setup_validator_set(n: u32) -> (SessionIndex, MembershipProof, ValidatorId) +where + T: Config, +{ + pallet_staking::ValidatorCount::::put(n); + + let balance_factor = 1000; + // create validators and set random session keys + for (n, who) in create_validators::(n, balance_factor).unwrap().into_iter().enumerate() { + use rand::{RngCore, SeedableRng}; + + let validator = T::Lookup::lookup(who).unwrap(); + let controller = pallet_staking::Pallet::::bonded(validator).unwrap(); + + let keys = { + const SESSION_KEY_LEN: usize = 32; + let key_ids = T::Keys::key_ids(); + let mut keys_len = key_ids.len() * SESSION_KEY_LEN; + if key_ids.contains(&sp_core::crypto::key_types::BEEFY) { + // BEEFY key is 33 bytes long, not 32. + keys_len += 1; + } + let mut keys = vec![0u8; keys_len]; + let mut rng = rand_chacha::ChaCha12Rng::seed_from_u64(n as u64); + rng.fill_bytes(&mut keys); + keys + }; + + let keys: T::Keys = Decode::decode(&mut &keys[..]).expect("wrong number of session keys?"); + let proof: Vec = vec![]; + + whitelist_account!(controller); + pallet_session::Pallet::::set_keys(RawOrigin::Signed(controller).into(), keys, proof) + .expect("session::set_keys should work"); + } + + pallet_session::Pallet::::on_initialize(BlockNumberFor::::one()); + initializer::Pallet::::on_initialize(BlockNumberFor::::one()); + // skip sessions until the new validator set is enacted + while pallet_session::Pallet::::validators().len() < n as usize { + pallet_session::Pallet::::rotate_session(); + } + initializer::Pallet::::on_finalize(BlockNumberFor::::one()); + + let session_index = crate::shared::Pallet::::session_index(); + let session_info = crate::session_info::Pallet::::session_info(session_index); + let session_info = session_info.unwrap(); + let validator_id = session_info.validators.get(ValidatorIndex::from(0)).unwrap().clone(); + let key = (PARACHAIN_KEY_TYPE_ID, validator_id.clone()); + let key_owner_proof = pallet_session::historical::Pallet::::prove(key).unwrap(); + + // rotate a session to make sure `key_owner_proof` is historical + initializer::Pallet::::on_initialize(BlockNumberFor::::one()); + pallet_session::Pallet::::rotate_session(); + initializer::Pallet::::on_finalize(BlockNumberFor::::one()); + + let idx = crate::shared::Pallet::::session_index(); + assert!( + idx > session_index, + "session rotation should work for parachain pallets: {} <= {}", + idx, + session_index, + ); + + (session_index, key_owner_proof, validator_id) +} + +fn setup_dispute(session_index: SessionIndex, validator_id: ValidatorId) -> DisputeProof +where + T: Config, +{ + let current_session = T::ValidatorSet::session_index(); + assert_ne!(session_index, current_session); + + let validator_index = ValidatorIndex(0); + let losers = [validator_index].into_iter(); + let backers = losers.clone(); + + T::SlashingHandler::punish_for_invalid(session_index, CANDIDATE_HASH, losers, backers); + + let unapplied = >::get(session_index, CANDIDATE_HASH); + assert_eq!(unapplied.unwrap().keys.len(), 1); + + dispute_proof(session_index, validator_id, validator_index) +} + +fn dispute_proof( + session_index: SessionIndex, + validator_id: ValidatorId, + validator_index: ValidatorIndex, +) -> DisputeProof { + let kind = SlashingOffenceKind::ForInvalid; + let time_slot = DisputesTimeSlot::new(session_index, CANDIDATE_HASH); + + DisputeProof { time_slot, kind, validator_index, validator_id } +} + +benchmarks! { + where_clause { + where T: Config, + } + + // in this setup we have a single `ForInvalid` dispute + // submitted for a past session + report_dispute_lost { + let n in 4..<::BenchmarkingConfig as BenchmarkingConfiguration>::MAX_VALIDATORS; + + let origin = RawOrigin::None.into(); + let (session_index, key_owner_proof, validator_id) = setup_validator_set::(n); + let dispute_proof = setup_dispute::(session_index, validator_id); + }: { + let result = Pallet::::report_dispute_lost_unsigned( + origin, + Box::new(dispute_proof), + key_owner_proof, + ); + assert!(result.is_ok()); + } verify { + let unapplied = >::get(session_index, CANDIDATE_HASH); + assert!(unapplied.is_none()); + } +} diff --git a/polkadot/runtime/parachains/src/disputes/tests.rs b/polkadot/runtime/parachains/src/disputes/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..0757084084f64349e14e9f9df192fb3a479db7db --- /dev/null +++ b/polkadot/runtime/parachains/src/disputes/tests.rs @@ -0,0 +1,2368 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::{ + configuration::HostConfiguration, + disputes::DisputesHandler, + mock::{ + new_test_ext, AccountId, AllPalletsWithSystem, Initializer, MockGenesisConfig, System, + Test, PUNISH_BACKERS_FOR, PUNISH_VALIDATORS_AGAINST, PUNISH_VALIDATORS_FOR, + REWARD_VALIDATORS, + }, +}; +use frame_support::{ + assert_err, assert_noop, assert_ok, + traits::{OnFinalize, OnInitialize}, +}; +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::BlockNumber; +use sp_core::{crypto::CryptoType, Pair}; + +const VOTE_FOR: VoteKind = VoteKind::ExplicitValid; +const VOTE_AGAINST: VoteKind = VoteKind::Invalid; +const VOTE_BACKING: VoteKind = VoteKind::Backing; + +fn filter_dispute_set(stmts: MultiDisputeStatementSet) -> CheckedMultiDisputeStatementSet { + let config = >::config(); + let post_conclusion_acceptance_period = config.dispute_post_conclusion_acceptance_period; + + stmts + .into_iter() + .filter_map(|set| { + let filter = + Pallet::::filter_dispute_data(&set, post_conclusion_acceptance_period); + filter.filter_statement_set(set) + }) + .collect::>() +} + +/// Returns `true` if duplicate items were found, otherwise `false`. +/// +/// `check_equal(a: &T, b: &T)` _must_ return `true`, iff `a` and `b` are equal, otherwise `false. +/// The definition of _equal_ is to be defined by the user. +/// +/// Attention: Requires the input `iter` to be sorted, such that _equals_ +/// would be adjacent in respect whatever `check_equal` defines as equality! +fn contains_duplicates_in_sorted_iter< + 'a, + T: 'a, + I: 'a + IntoIterator, + C: 'static + FnMut(&T, &T) -> bool, +>( + iter: I, + mut check_equal: C, +) -> bool { + let mut iter = iter.into_iter(); + if let Some(mut previous) = iter.next() { + while let Some(current) = iter.next() { + if check_equal(previous, current) { + return true + } + previous = current; + } + } + return false +} + +// All arguments for `initializer::on_new_session` +type NewSession<'a> = ( + bool, + SessionIndex, + Vec<(&'a AccountId, ValidatorId)>, + Option>, +); + +// Run to specific block, while calling disputes pallet hooks manually, because disputes is not +// integrated in initializer yet. +pub(crate) fn run_to_block<'a>( + to: BlockNumber, + new_session: impl Fn(BlockNumber) -> Option>, +) { + while System::block_number() < to { + let b = System::block_number(); + if b != 0 { + // circumvent requirement to have bitfields and headers in block for testing purposes + crate::paras_inherent::Included::::set(Some(())); + + AllPalletsWithSystem::on_finalize(b); + System::finalize(); + } + + System::reset_events(); + System::initialize(&(b + 1), &Default::default(), &Default::default()); + AllPalletsWithSystem::on_initialize(b + 1); + + if let Some(new_session) = new_session(b + 1) { + Initializer::test_trigger_on_new_session( + new_session.0, + new_session.1, + new_session.2.into_iter(), + new_session.3.map(|q| q.into_iter()), + ); + } + } +} + +#[test] +fn test_contains_duplicates_in_sorted_iter() { + // We here use the implicit ascending sorting and builtin equality of integers + let v = vec![1, 2, 3, 5, 5, 8]; + assert_eq!(true, contains_duplicates_in_sorted_iter(&v, |a, b| a == b)); + + let v = vec![1, 2, 3, 4]; + assert_eq!(false, contains_duplicates_in_sorted_iter(&v, |a, b| a == b)); +} + +#[test] +fn test_dispute_state_flag_from_state() { + assert_eq!( + DisputeStateFlags::from_state(&DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 0, 0, 0, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 0, 0, 0, 0, 0, 0, 0, 0], + start: 0, + concluded_at: None, + }), + DisputeStateFlags::default(), + ); + + assert_eq!( + DisputeStateFlags::from_state(&DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 1, 1, 1, 1, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 0, 0, 0, 0, 0, 0, 0], + start: 0, + concluded_at: None, + }), + DisputeStateFlags::FOR_SUPERMAJORITY | DisputeStateFlags::CONFIRMED, + ); + + assert_eq!( + DisputeStateFlags::from_state(&DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 0, 0, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 1, 1, 1, 0, 0, 0, 0], + start: 0, + concluded_at: None, + }), + DisputeStateFlags::CONFIRMED | DisputeStateFlags::AGAINST_BYZANTINE, + ); + + assert_eq!( + DisputeStateFlags::from_state(&DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 0, 0, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 1, 1, 1, 1, 1, 0, 0], + start: 0, + concluded_at: None, + }), + DisputeStateFlags::AGAINST_SUPERMAJORITY | + DisputeStateFlags::CONFIRMED | + DisputeStateFlags::AGAINST_BYZANTINE, + ); +} + +#[test] +fn test_import_new_participant() { + let mut importer = DisputeStateImporter::new( + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 0, 0, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 0, 0, 0, 0, 0, 0, 0, 0], + start: 0, + concluded_at: None, + }, + BTreeSet::new(), + 0, + ); + + assert_err!( + importer.import(ValidatorIndex(9), VOTE_FOR), + VoteImportError::ValidatorIndexOutOfBounds, + ); + + assert_err!(importer.import(ValidatorIndex(0), VOTE_FOR), VoteImportError::DuplicateStatement); + assert_ok!(importer.import(ValidatorIndex(0), VOTE_AGAINST)); + + assert_ok!(importer.import(ValidatorIndex(2), VOTE_FOR)); + assert_err!(importer.import(ValidatorIndex(2), VOTE_FOR), VoteImportError::DuplicateStatement); + + assert_ok!(importer.import(ValidatorIndex(2), VOTE_AGAINST)); + assert_err!( + importer.import(ValidatorIndex(2), VOTE_AGAINST), + VoteImportError::DuplicateStatement + ); + + let summary = importer.finish(); + assert_eq!(summary.new_flags, DisputeStateFlags::default()); + assert_eq!( + summary.state, + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 0, 1, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 1, 0, 1, 0, 0, 0, 0, 0], + start: 0, + concluded_at: None, + }, + ); + assert!(summary.slash_for.is_empty()); + assert!(summary.slash_against.is_empty()); + assert_eq!(summary.new_participants, bitvec![u8, BitOrderLsb0; 0, 0, 1, 0, 0, 0, 0, 0]); +} + +#[test] +fn test_import_prev_participant_confirmed() { + let mut importer = DisputeStateImporter::new( + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 0, 0, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 0, 1, 0, 0, 0, 0, 0, 0], + start: 0, + concluded_at: None, + }, + BTreeSet::new(), + 0, + ); + + assert_ok!(importer.import(ValidatorIndex(2), VOTE_FOR)); + + let summary = importer.finish(); + assert_eq!( + summary.state, + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 0, 1, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 0, 1, 0, 0, 0, 0, 0, 0], + start: 0, + concluded_at: None, + }, + ); + + assert!(summary.slash_for.is_empty()); + assert!(summary.slash_against.is_empty()); + assert_eq!(summary.new_participants, bitvec![u8, BitOrderLsb0; 0, 0, 1, 0, 0, 0, 0, 0]); + assert_eq!(summary.new_flags, DisputeStateFlags::CONFIRMED); +} + +#[test] +fn test_import_prev_participant_confirmed_slash_for() { + let mut importer = DisputeStateImporter::new( + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 0, 0, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 0, 1, 0, 0, 0, 0, 0, 0], + start: 0, + concluded_at: None, + }, + BTreeSet::new(), + 0, + ); + + assert_ok!(importer.import(ValidatorIndex(2), VOTE_FOR)); + assert_ok!(importer.import(ValidatorIndex(2), VOTE_AGAINST)); + assert_ok!(importer.import(ValidatorIndex(3), VOTE_AGAINST)); + assert_ok!(importer.import(ValidatorIndex(4), VOTE_AGAINST)); + assert_ok!(importer.import(ValidatorIndex(5), VOTE_AGAINST)); + assert_ok!(importer.import(ValidatorIndex(6), VOTE_AGAINST)); + + let summary = importer.finish(); + assert_eq!( + summary.state, + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 0, 1, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 0, 1, 1, 1, 1, 1, 1, 0], + start: 0, + concluded_at: Some(0), + }, + ); + + assert_eq!(summary.slash_for, vec![ValidatorIndex(0), ValidatorIndex(2)]); + assert!(summary.slash_against.is_empty()); + assert_eq!(summary.new_participants, bitvec![u8, BitOrderLsb0; 0, 0, 1, 1, 1, 1, 1, 0]); + assert_eq!( + summary.new_flags, + DisputeStateFlags::CONFIRMED | + DisputeStateFlags::AGAINST_SUPERMAJORITY | + DisputeStateFlags::AGAINST_BYZANTINE, + ); +} + +#[test] +fn test_import_slash_against() { + let mut importer = DisputeStateImporter::new( + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 0, 1, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 0, 1, 0, 0, 0, 0, 0, 0], + start: 0, + concluded_at: None, + }, + BTreeSet::new(), + 0, + ); + + assert_ok!(importer.import(ValidatorIndex(3), VOTE_FOR)); + assert_ok!(importer.import(ValidatorIndex(4), VOTE_FOR)); + assert_ok!(importer.import(ValidatorIndex(5), VOTE_AGAINST)); + assert_ok!(importer.import(ValidatorIndex(6), VOTE_FOR)); + assert_ok!(importer.import(ValidatorIndex(7), VOTE_FOR)); + + let summary = importer.finish(); + assert_eq!( + summary.state, + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 0, 1, 1, 1, 0, 1, 1], + validators_against: bitvec![u8, BitOrderLsb0; 0, 1, 0, 0, 0, 1, 0, 0], + start: 0, + concluded_at: Some(0), + }, + ); + assert!(summary.slash_for.is_empty()); + assert_eq!(summary.slash_against, vec![ValidatorIndex(1), ValidatorIndex(5)]); + assert_eq!(summary.new_participants, bitvec![u8, BitOrderLsb0; 0, 0, 0, 1, 1, 1, 1, 1]); + assert_eq!(summary.new_flags, DisputeStateFlags::FOR_SUPERMAJORITY); +} + +#[test] +fn test_import_backing_votes() { + let mut importer = DisputeStateImporter::new( + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 0, 1, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 0, 1, 0, 0, 0, 0, 0, 0], + start: 0, + concluded_at: None, + }, + BTreeSet::from_iter([ValidatorIndex(0)]), + 0, + ); + + assert_ok!(importer.import(ValidatorIndex(3), VOTE_FOR)); + assert_ok!(importer.import(ValidatorIndex(3), VOTE_BACKING)); + assert_ok!(importer.import(ValidatorIndex(3), VOTE_AGAINST)); + assert_ok!(importer.import(ValidatorIndex(6), VOTE_FOR)); + assert_ok!(importer.import(ValidatorIndex(7), VOTE_BACKING)); + // Don't import backing vote twice + assert_err!( + importer.import(ValidatorIndex(0), VOTE_BACKING), + VoteImportError::DuplicateStatement, + ); + // Don't import explicit votes after backing + assert_err!(importer.import(ValidatorIndex(7), VOTE_FOR), VoteImportError::MaliciousBacker,); + + let summary = importer.finish(); + assert_eq!( + summary.state, + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 0, 1, 1, 0, 0, 1, 1], + validators_against: bitvec![u8, BitOrderLsb0; 0, 1, 0, 1, 0, 0, 0, 0], + start: 0, + concluded_at: None, + }, + ); + assert_eq!( + summary.backers, + BTreeSet::from_iter([ValidatorIndex(0), ValidatorIndex(3), ValidatorIndex(7),]), + ); +} + +// Test pruning works +#[test] +fn test_initializer_on_new_session() { + let dispute_period = 3; + + let mock_genesis_config = MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { dispute_period, ..Default::default() }, + }, + ..Default::default() + }; + + new_test_ext(mock_genesis_config).execute_with(|| { + let v0 = ::Pair::generate().0; + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + Pallet::::note_included(0, candidate_hash, 0); + Pallet::::note_included(1, candidate_hash, 1); + Pallet::::note_included(2, candidate_hash, 2); + Pallet::::note_included(3, candidate_hash, 3); + Pallet::::note_included(4, candidate_hash, 4); + Pallet::::note_included(5, candidate_hash, 5); + Pallet::::note_included(6, candidate_hash, 5); + + run_to_block(7, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); + + // current session is 7, + // we keep for dispute_period + 1 session and we remove in on_finalize + // thus we keep info for session 3, 4, 5, 6, 7. + assert_eq!(Included::::iter_prefix(0).count(), 0); + assert_eq!(Included::::iter_prefix(1).count(), 0); + assert_eq!(Included::::iter_prefix(2).count(), 0); + assert_eq!(Included::::iter_prefix(3).count(), 1); + assert_eq!(Included::::iter_prefix(4).count(), 1); + assert_eq!(Included::::iter_prefix(5).count(), 1); + assert_eq!(Included::::iter_prefix(6).count(), 1); + }); +} + +#[test] +fn test_provide_data_duplicate_error() { + new_test_ext(Default::default()).execute_with(|| { + let candidate_hash_1 = CandidateHash(sp_core::H256::repeat_byte(1)); + let candidate_hash_2 = CandidateHash(sp_core::H256::repeat_byte(2)); + + let mut stmts = vec![ + DisputeStatementSet { + candidate_hash: candidate_hash_2, + session: 2, + statements: vec![], + }, + DisputeStatementSet { + candidate_hash: candidate_hash_1, + session: 1, + statements: vec![], + }, + DisputeStatementSet { + candidate_hash: candidate_hash_2, + session: 2, + statements: vec![], + }, + ]; + + assert!(Pallet::::deduplicate_and_sort_dispute_data(&mut stmts).is_err()); + assert_eq!(stmts.len(), 2); + }) +} + +#[test] +fn test_provide_multi_dispute_is_providing() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + + run_to_block(3, |b| { + // a new session at each block + if b == 1 { + Some(( + true, + b, + vec![(&0, v0.public()), (&1, v1.public())], + Some(vec![(&0, v0.public()), (&1, v1.public())]), + )) + } else { + Some((true, b, vec![(&1, v1.public())], Some(vec![(&1, v1.public())]))) + } + }); + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + let inclusion_parent = sp_core::H256::repeat_byte(0xff); + let session = 1; + let stmts = vec![DisputeStatementSet { + candidate_hash, + session, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid( + inclusion_parent, + )), + ValidatorIndex(0), + v0.sign(&CompactStatement::Valid(candidate_hash).signing_payload( + &SigningContext { session_index: session, parent_hash: inclusion_parent }, + )), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v1.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ], + }]; + + assert_ok!( + Pallet::::process_checked_multi_dispute_data( + &stmts + .into_iter() + .map(CheckedDisputeStatementSet::unchecked_from_unchecked) + .collect() + ), + vec![(1, candidate_hash)], + ); + }) +} + +#[test] +fn test_disputes_with_missing_backing_votes_are_rejected() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + + run_to_block(3, |b| { + // a new session at each block + if b == 1 { + Some(( + true, + b, + vec![(&0, v0.public()), (&1, v1.public())], + Some(vec![(&0, v0.public()), (&1, v1.public())]), + )) + } else { + Some((true, b, vec![(&1, v1.public())], Some(vec![(&1, v1.public())]))) + } + }); + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + let session = 1; + + let stmts = vec![DisputeStatementSet { + candidate_hash, + session, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { valid: true, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v1.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ], + }]; + + assert!(Pallet::::process_checked_multi_dispute_data( + &stmts + .into_iter() + .map(CheckedDisputeStatementSet::unchecked_from_unchecked) + .collect() + ) + .is_err(),); + }) +} + +#[test] +fn test_freeze_on_note_included() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + + run_to_block(6, |b| { + // a new session at each block + Some(( + true, + b, + vec![(&0, v0.public()), (&1, v1.public())], + Some(vec![(&0, v0.public()), (&1, v1.public())]), + )) + }); + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + let inclusion_parent = sp_core::H256::repeat_byte(0xff); + let session = 3; + + // v0 votes for 3 + let stmts = vec![DisputeStatementSet { + candidate_hash, + session: 3, + statements: vec![ + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session: 3 } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v1.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session: 3 } + .signing_payload(), + ), + ), + ( + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid( + inclusion_parent, + )), + ValidatorIndex(1), + v0.sign(&CompactStatement::Valid(candidate_hash).signing_payload( + &SigningContext { session_index: session, parent_hash: inclusion_parent }, + )), + ), + ], + }]; + assert!(Pallet::::process_checked_multi_dispute_data( + &stmts + .into_iter() + .map(CheckedDisputeStatementSet::unchecked_from_unchecked) + .collect() + ) + .is_ok()); + + Pallet::::note_included(3, candidate_hash, 3); + assert_eq!(Frozen::::get(), Some(2)); + }); +} + +#[test] +fn test_freeze_provided_against_supermajority_for_included() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + + run_to_block(6, |b| { + // a new session at each block + Some(( + true, + b, + vec![(&0, v0.public()), (&1, v1.public())], + Some(vec![(&0, v0.public()), (&1, v1.public())]), + )) + }); + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + let inclusion_parent = sp_core::H256::repeat_byte(0xff); + let session = 3; + + // v0 votes for 3 + let stmts = vec![DisputeStatementSet { + candidate_hash, + session, + statements: vec![ + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v1.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid( + inclusion_parent, + )), + ValidatorIndex(1), + v0.sign(&CompactStatement::Valid(candidate_hash).signing_payload( + &SigningContext { session_index: session, parent_hash: inclusion_parent }, + )), + ), + ], + }]; + + Pallet::::note_included(3, candidate_hash, 3); + assert!(Pallet::::process_checked_multi_dispute_data( + &stmts + .into_iter() + .map(CheckedDisputeStatementSet::unchecked_from_unchecked) + .collect() + ) + .is_ok()); + assert_eq!(Frozen::::get(), Some(2)); + }); +} + +#[test] +fn test_freeze_provided_against_byzantine_threshold_for_included() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + let v2 = ::Pair::generate().0; + let v3 = ::Pair::generate().0; + let v4 = ::Pair::generate().0; + let v5 = ::Pair::generate().0; + let v6 = ::Pair::generate().0; + + let active_set = vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + (&4, v4.public()), + (&5, v5.public()), + (&6, v6.public()), + ]; + + run_to_block(6, |b| Some((true, b, active_set.clone(), Some(active_set.clone())))); + + // A candidate which will be disputed + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + let inclusion_parent = sp_core::H256::repeat_byte(0xff); + let session = 3; + + // A byzantine threshold of INVALID + let stmts = vec![DisputeStatementSet { + candidate_hash, + session, + statements: vec![ + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v1.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(2), + v2.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid( + inclusion_parent, + )), + ValidatorIndex(1), + v0.sign(&CompactStatement::Valid(candidate_hash).signing_payload( + &SigningContext { session_index: session, parent_hash: inclusion_parent }, + )), + ), + ], + }]; + + // Include the candidate and import the votes + Pallet::::note_included(3, candidate_hash, 3); + assert!(Pallet::::process_checked_multi_dispute_data( + &stmts + .into_iter() + .map(CheckedDisputeStatementSet::unchecked_from_unchecked) + .collect() + ) + .is_ok()); + // Successful import should freeze the chain + assert_eq!(Frozen::::get(), Some(2)); + + // Now include one more block + run_to_block(7, |b| Some((true, b, active_set.clone(), Some(active_set.clone())))); + Pallet::::note_included(3, CandidateHash(sp_core::H256::repeat_byte(2)), 3); + + // And generate enough votes to reach supermajority of invalid votes + let stmts = vec![DisputeStatementSet { + candidate_hash, + session, + statements: vec![ + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(3), + v3.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(4), + v4.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(5), + v5.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ], + }]; + assert!(Pallet::::process_checked_multi_dispute_data( + &stmts + .into_iter() + .map(CheckedDisputeStatementSet::unchecked_from_unchecked) + .collect() + ) + .is_ok()); + // Chain should still be frozen + assert_eq!(Frozen::::get(), Some(2)); + }); +} + +mod unconfirmed_disputes { + use super::*; + use assert_matches::assert_matches; + use sp_runtime::ModuleError; + + // Shared initialization code between `test_unconfirmed_are_ignored` and + // `test_unconfirmed_disputes_cause_block_import_error` + fn generate_dispute_statement_set_and_run_to_block() -> DisputeStatementSet { + // 7 validators needed for byzantine threshold of 2. + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + let v2 = ::Pair::generate().0; + let v3 = ::Pair::generate().0; + let v4 = ::Pair::generate().0; + let v5 = ::Pair::generate().0; + let v6 = ::Pair::generate().0; + + // Mapping between key pair and `ValidatorIndex` + // v0 -> 0 + // v1 -> 3 + // v2 -> 6 + // v3 -> 5 + // v4 -> 1 + // v5 -> 4 + // v6 -> 2 + + run_to_block(6, |b| { + // a new session at each block + Some(( + true, + b, + vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + (&4, v4.public()), + (&5, v5.public()), + (&6, v6.public()), + ], + Some(vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + (&4, v4.public()), + (&5, v5.public()), + (&6, v6.public()), + ]), + )) + }); + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + + // v0 votes for 4, v1 votes against 4. + DisputeStatementSet { + candidate_hash, + session: 4, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { valid: true, candidate_hash, session: 4 } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(3), + v1.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session: 4 } + .signing_payload(), + ), + ), + ], + } + } + #[test] + fn test_unconfirmed_are_ignored() { + new_test_ext(Default::default()).execute_with(|| { + let stmts = vec![generate_dispute_statement_set_and_run_to_block()]; + let stmts = filter_dispute_set(stmts); + + // Not confirmed => should be filtered out + assert_ok!(Pallet::::process_checked_multi_dispute_data(&stmts), vec![],); + }); + } + + #[test] + fn test_unconfirmed_disputes_cause_block_import_error() { + new_test_ext(Default::default()).execute_with(|| { + + let stmts = generate_dispute_statement_set_and_run_to_block(); + let stmts = vec![CheckedDisputeStatementSet::unchecked_from_unchecked(stmts)]; + + assert_matches!( + Pallet::::process_checked_multi_dispute_data(&stmts), + Err(DispatchError::Module(ModuleError{index: _, error: _, message})) => assert_eq!(message, Some("UnconfirmedDispute")) + ); + + }); + } +} + +// tests for: +// * provide_multi_dispute: with success scenario +// * disputes: correctness of datas +// * could_be_invalid: correctness of datas +// * ensure rewards and punishment are correctly called. +#[test] +fn test_provide_multi_dispute_success_and_other() { + new_test_ext(Default::default()).execute_with(|| { + // 7 validators needed for byzantine threshold of 2. + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + let v2 = ::Pair::generate().0; + let v3 = ::Pair::generate().0; + let v4 = ::Pair::generate().0; + let v5 = ::Pair::generate().0; + let v6 = ::Pair::generate().0; + + // Mapping between key pair and `ValidatorIndex` + // v0 -> 0 + // v1 -> 3 + // v2 -> 6 + // v3 -> 5 + // v4 -> 1 + // v5 -> 4 + // v6 -> 2 + + run_to_block(6, |b| { + // a new session at each block + Some(( + true, + b, + vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + (&4, v4.public()), + (&5, v5.public()), + (&6, v6.public()), + ], + Some(vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + (&4, v4.public()), + (&5, v5.public()), + (&6, v6.public()), + ]), + )) + }); + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + let inclusion_parent = sp_core::H256::repeat_byte(0xff); + let session = 3; + + // v0 and v1 vote for 3, v6 votes against + let stmts = vec![DisputeStatementSet { + candidate_hash, + session, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid( + inclusion_parent, + )), + ValidatorIndex(0), + v0.sign(&CompactStatement::Valid(candidate_hash).signing_payload( + &SigningContext { session_index: session, parent_hash: inclusion_parent }, + )), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(2), + v6.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(3), + v1.sign( + &ExplicitDisputeStatement { valid: true, candidate_hash, session: 3 } + .signing_payload(), + ), + ), + ], + }]; + + let stmts = filter_dispute_set(stmts); + + assert_ok!( + Pallet::::process_checked_multi_dispute_data(&stmts), + vec![(3, candidate_hash)], + ); + + // v3 votes against 3 and for 5, v2 and v6 vote against 5. + let stmts = vec![ + DisputeStatementSet { + candidate_hash, + session: 3, + statements: vec![( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(5), + v3.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session: 3 } + .signing_payload(), + ), + )], + }, + DisputeStatementSet { + candidate_hash, + session: 5, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid( + inclusion_parent, + )), + ValidatorIndex(5), + v3.sign(&CompactStatement::Valid(candidate_hash).signing_payload( + &SigningContext { session_index: 5, parent_hash: inclusion_parent }, + )), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(6), + v2.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session: 5 } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(2), + v6.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session: 5 } + .signing_payload(), + ), + ), + ], + }, + ]; + + let stmts = filter_dispute_set(stmts); + assert_ok!( + Pallet::::process_checked_multi_dispute_data(&stmts), + vec![(5, candidate_hash)], + ); + + // v2 votes for 3 + let stmts = vec![DisputeStatementSet { + candidate_hash, + session: 3, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(6), + v2.sign( + &ExplicitDisputeStatement { valid: true, candidate_hash, session: 3 } + .signing_payload(), + ), + )], + }]; + let stmts = filter_dispute_set(stmts); + assert_ok!(Pallet::::process_checked_multi_dispute_data(&stmts), vec![]); + + let stmts = vec![ + // 0, 4, and 5 vote against 5 + DisputeStatementSet { + candidate_hash, + session: 5, + statements: vec![ + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session: 5 } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v4.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session: 5 } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(4), + v5.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session: 5 } + .signing_payload(), + ), + ), + ], + }, + // 4 and 5 vote for 3 + DisputeStatementSet { + candidate_hash, + session: 3, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v4.sign( + &ExplicitDisputeStatement { valid: true, candidate_hash, session: 3 } + .signing_payload(), + ), + ), + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(4), + v5.sign( + &ExplicitDisputeStatement { valid: true, candidate_hash, session: 3 } + .signing_payload(), + ), + ), + ], + }, + ]; + let stmts = filter_dispute_set(stmts); + assert_ok!(Pallet::::process_checked_multi_dispute_data(&stmts), vec![]); + + assert_eq!( + Pallet::::disputes(), + vec![ + ( + 5, + candidate_hash, + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 0, 0, 0, 0, 0, 1, 0], + validators_against: bitvec![u8, BitOrderLsb0; 1, 1, 1, 0, 1, 0, 1], + start: 6, + concluded_at: Some(6), // 5 vote against + } + ), + ( + 3, + candidate_hash, + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 1, 0, 1, 1, 0, 1], + validators_against: bitvec![u8, BitOrderLsb0; 0, 0, 1, 0, 0, 1, 0], + start: 6, + concluded_at: Some(6), // 5 vote for + } + ), + ] + ); + + assert!(!Pallet::::concluded_invalid(3, candidate_hash)); + assert!(!Pallet::::concluded_invalid(4, candidate_hash)); + assert!(Pallet::::concluded_invalid(5, candidate_hash)); + + // Ensure the `reward_validator` function was correctly called + assert_eq!( + REWARD_VALIDATORS.with(|r| r.borrow().clone()), + vec![ + (3, vec![ValidatorIndex(0), ValidatorIndex(2), ValidatorIndex(3)]), + (3, vec![ValidatorIndex(5)]), + (5, vec![ValidatorIndex(2), ValidatorIndex(5), ValidatorIndex(6)]), + (3, vec![ValidatorIndex(6)]), + (5, vec![ValidatorIndex(0), ValidatorIndex(1), ValidatorIndex(4)]), + (3, vec![ValidatorIndex(1), ValidatorIndex(4)]), + ], + ); + + // Ensure punishment against is called + assert_eq!( + PUNISH_VALIDATORS_AGAINST.with(|r| r.borrow().clone()), + vec![ + (3, vec![]), + (3, vec![]), + (5, vec![]), + (3, vec![]), + (5, vec![]), + (3, vec![ValidatorIndex(2), ValidatorIndex(5)]), + ], + ); + + // Ensure punishment for is called + assert_eq!( + PUNISH_VALIDATORS_FOR.with(|r| r.borrow().clone()), + vec![ + (3, vec![]), + (3, vec![]), + (5, vec![]), + (3, vec![]), + (5, vec![ValidatorIndex(5)]), + (3, vec![]), + ], + ); + }) +} + +/// In this setup we have only one dispute concluding AGAINST. +/// There are some votes imported post dispute conclusion. +/// We make sure these votes are accounted for in punishment. +#[test] +fn test_punish_post_conclusion() { + new_test_ext(Default::default()).execute_with(|| { + // supermajority threshold is 5 + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + let v2 = ::Pair::generate().0; + let v3 = ::Pair::generate().0; + let v4 = ::Pair::generate().0; + let v5 = ::Pair::generate().0; + let v6 = ::Pair::generate().0; + // Mapping between key pair and `ValidatorIndex` + // v0 -> 0 + // v1 -> 3 + // v2 -> 6 + // v3 -> 5 + // v4 -> 1 + // v5 -> 4 + // v6 -> 2 + + run_to_block(6, |b| { + // a new session at each block + Some(( + true, + b, + vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + (&4, v4.public()), + (&5, v5.public()), + (&6, v6.public()), + ], + Some(vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + (&4, v4.public()), + (&5, v5.public()), + (&6, v6.public()), + ]), + )) + }); + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + let inclusion_parent = sp_core::H256::repeat_byte(0xff); + let session = 3; + + let stmts = vec![DisputeStatementSet { + candidate_hash, + session, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid( + inclusion_parent, + )), + ValidatorIndex(0), + v0.sign(&CompactStatement::Valid(candidate_hash).signing_payload( + &SigningContext { session_index: session, parent_hash: inclusion_parent }, + )), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v4.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(2), + v6.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(6), + v2.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(4), + v5.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(5), + v3.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking), + ValidatorIndex(3), + v1.sign(&ApprovalVote(candidate_hash).signing_payload(session)), + ), + ], + }]; + + let stmts = filter_dispute_set(stmts); + assert_ok!( + Pallet::::process_checked_multi_dispute_data(&stmts), + vec![(session, candidate_hash)], + ); + + assert_eq!( + PUNISH_VALIDATORS_FOR.with(|r| r.borrow().clone()), + vec![(session, vec![ValidatorIndex(0), ValidatorIndex(3)]),], + ); + assert_eq!( + PUNISH_BACKERS_FOR.with(|r| r.borrow().clone()), + vec![(session, vec![ValidatorIndex(0)]),], + ); + + // someone reveals 3 backing vote, 6 votes against + let stmts = vec![DisputeStatementSet { + candidate_hash, + session, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid( + inclusion_parent, + )), + ValidatorIndex(3), + v1.sign(&CompactStatement::Valid(candidate_hash).signing_payload( + &SigningContext { session_index: session, parent_hash: inclusion_parent }, + )), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(6), + v2.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ], + }]; + + let stmts = filter_dispute_set(stmts); + assert_ok!(Pallet::::process_checked_multi_dispute_data(&stmts), vec![],); + + // Ensure punishment for is called + assert_eq!( + PUNISH_VALIDATORS_FOR.with(|r| r.borrow().clone()), + vec![ + (session, vec![ValidatorIndex(0), ValidatorIndex(3)]), + (session, vec![ValidatorIndex(3)]), + ], + ); + + assert_eq!( + PUNISH_BACKERS_FOR.with(|r| r.borrow().clone()), + vec![ + (session, vec![ValidatorIndex(0)]), + (session, vec![ValidatorIndex(0), ValidatorIndex(3)]) + ], + ); + + assert_eq!( + PUNISH_VALIDATORS_AGAINST.with(|r| r.borrow().clone()), + vec![(session, vec![]), (session, vec![]),], + ); + }) +} + +#[test] +fn test_revert_and_freeze() { + new_test_ext(Default::default()).execute_with(|| { + // events are ignored for genesis block + System::set_block_number(1); + + Frozen::::put(Some(0)); + assert_noop!( + { + Pallet::::revert_and_freeze(0); + Result::<(), ()>::Err(()) // Just a small trick in order to use `assert_noop`. + }, + (), + ); + + Frozen::::kill(); + Pallet::::revert_and_freeze(0); + + assert_eq!(Frozen::::get(), Some(0)); + assert_eq!(System::digest().logs[0], ConsensusLog::Revert(1).into()); + System::assert_has_event(Event::Revert(1).into()); + }) +} + +#[test] +fn test_revert_and_freeze_merges() { + new_test_ext(Default::default()).execute_with(|| { + Frozen::::put(Some(10)); + assert_noop!( + { + Pallet::::revert_and_freeze(10); + Result::<(), ()>::Err(()) // Just a small trick in order to use `assert_noop`. + }, + (), + ); + + Pallet::::revert_and_freeze(8); + assert_eq!(Frozen::::get(), Some(8)); + }) +} + +#[test] +fn test_has_supermajority_against() { + assert_eq!( + has_supermajority_against(&DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 1, 0, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 1, 1, 1, 1, 1, 0, 0, 0], + start: 0, + concluded_at: None, + }), + false, + ); + + assert_eq!( + has_supermajority_against(&DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 1, 1, 0, 0, 0, 0, 0, 0], + validators_against: bitvec![u8, BitOrderLsb0; 1, 1, 1, 1, 1, 1, 0, 0], + start: 0, + concluded_at: None, + }), + true, + ); +} + +#[test] +fn test_check_signature() { + let validator_id = ::Pair::generate().0; + let wrong_validator_id = ::Pair::generate().0; + + let session = 0; + let wrong_session = 1; + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + let wrong_candidate_hash = CandidateHash(sp_core::H256::repeat_byte(2)); + let inclusion_parent = sp_core::H256::repeat_byte(3); + let wrong_inclusion_parent = sp_core::H256::repeat_byte(4); + + let statement_1 = DisputeStatement::Valid(ValidDisputeStatementKind::Explicit); + let statement_2 = + DisputeStatement::Valid(ValidDisputeStatementKind::BackingSeconded(inclusion_parent)); + let wrong_statement_2 = + DisputeStatement::Valid(ValidDisputeStatementKind::BackingSeconded(wrong_inclusion_parent)); + let statement_3 = + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid(inclusion_parent)); + let wrong_statement_3 = + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid(wrong_inclusion_parent)); + let statement_4 = DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking); + let statement_5 = DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit); + + let signed_1 = validator_id + .sign(&ExplicitDisputeStatement { valid: true, candidate_hash, session }.signing_payload()); + let signed_2 = validator_id.sign(&CompactStatement::Seconded(candidate_hash).signing_payload( + &SigningContext { session_index: session, parent_hash: inclusion_parent }, + )); + let signed_3 = validator_id.sign(&CompactStatement::Valid(candidate_hash).signing_payload( + &SigningContext { session_index: session, parent_hash: inclusion_parent }, + )); + let signed_4 = validator_id.sign(&ApprovalVote(candidate_hash).signing_payload(session)); + let signed_5 = validator_id.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session }.signing_payload(), + ); + + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_1 + ) + .is_ok()); + assert!(check_signature( + &wrong_validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + wrong_candidate_hash, + session, + &statement_1, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + wrong_session, + &statement_1, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_1 + ) + .is_err()); + + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_2 + ) + .is_ok()); + assert!(check_signature( + &wrong_validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + wrong_candidate_hash, + session, + &statement_2, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + wrong_session, + &statement_2, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &wrong_statement_2, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_2 + ) + .is_err()); + + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_3 + ) + .is_ok()); + assert!(check_signature( + &wrong_validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + wrong_candidate_hash, + session, + &statement_3, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + wrong_session, + &statement_3, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &wrong_statement_3, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_3 + ) + .is_err()); + + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_4 + ) + .is_ok()); + assert!(check_signature( + &wrong_validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + wrong_candidate_hash, + session, + &statement_4, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + wrong_session, + &statement_4, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_4 + ) + .is_err()); + + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_5 + ) + .is_ok()); + assert!(check_signature( + &wrong_validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + wrong_candidate_hash, + session, + &statement_5, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + wrong_session, + &statement_5, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_5 + ) + .is_err()); +} + +#[test] +fn deduplication_and_sorting_works() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + let v2 = ::Pair::generate().0; + let v3 = ::Pair::generate().0; + + run_to_block(3, |b| { + // a new session at each block + Some(( + true, + b, + vec![(&0, v0.public()), (&1, v1.public()), (&2, v2.public()), (&3, v3.public())], + Some(vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + ]), + )) + }); + + let candidate_hash_a = CandidateHash(sp_core::H256::repeat_byte(1)); + let candidate_hash_b = CandidateHash(sp_core::H256::repeat_byte(2)); + let candidate_hash_c = CandidateHash(sp_core::H256::repeat_byte(3)); + + let create_explicit_statement = |vidx: ValidatorIndex, + validator: &::Pair, + c_hash: &CandidateHash, + valid, + session| { + let payload = ExplicitDisputeStatement { valid, candidate_hash: *c_hash, session } + .signing_payload(); + let sig = validator.sign(&payload); + (DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), vidx, sig.clone()) + }; + + let explicit_triple_a = + create_explicit_statement(ValidatorIndex(0), &v0, &candidate_hash_a, true, 1); + let explicit_triple_a_bad = + create_explicit_statement(ValidatorIndex(1), &v1, &candidate_hash_a, false, 1); + + let explicit_triple_b = + create_explicit_statement(ValidatorIndex(0), &v0, &candidate_hash_b, true, 2); + let explicit_triple_b_bad = + create_explicit_statement(ValidatorIndex(1), &v1, &candidate_hash_b, false, 2); + + let explicit_triple_c = + create_explicit_statement(ValidatorIndex(0), &v0, &candidate_hash_c, true, 2); + let explicit_triple_c_bad = + create_explicit_statement(ValidatorIndex(1), &v1, &candidate_hash_c, false, 2); + + let mut disputes = vec![ + DisputeStatementSet { + candidate_hash: candidate_hash_b, + session: 2, + statements: vec![explicit_triple_b.clone(), explicit_triple_b_bad.clone()], + }, + // same session as above + DisputeStatementSet { + candidate_hash: candidate_hash_c, + session: 2, + statements: vec![explicit_triple_c, explicit_triple_c_bad], + }, + // the duplicate set + DisputeStatementSet { + candidate_hash: candidate_hash_b, + session: 2, + statements: vec![explicit_triple_b.clone(), explicit_triple_b_bad.clone()], + }, + DisputeStatementSet { + candidate_hash: candidate_hash_a, + session: 1, + statements: vec![explicit_triple_a, explicit_triple_a_bad], + }, + ]; + + let disputes_orig = disputes.clone(); + + as DisputesHandler>>::deduplicate_and_sort_dispute_data( + &mut disputes, + ) + .unwrap_err(); + + // assert ordering of local only disputes, and at the same time, and being free of + // duplicates + assert_eq!(disputes_orig.len(), disputes.len() + 1); + + let are_these_equal = |a: &DisputeStatementSet, b: &DisputeStatementSet| { + use core::cmp::Ordering; + // we only have local disputes here, so sorting of those adheres to the + // simplified sorting logic + let cmp = + a.session.cmp(&b.session).then_with(|| a.candidate_hash.cmp(&b.candidate_hash)); + assert_ne!(cmp, Ordering::Greater); + cmp == Ordering::Equal + }; + + assert_eq!(false, contains_duplicates_in_sorted_iter(&disputes, are_these_equal)); + }) +} + +fn apply_filter_all>( + sets: I, +) -> Vec { + let config = >::config(); + let post_conclusion_acceptance_period = config.dispute_post_conclusion_acceptance_period; + + let mut acc = Vec::::new(); + for dispute_statement in sets { + if let Some(checked) = + as DisputesHandler>>::filter_dispute_data( + dispute_statement, + post_conclusion_acceptance_period, + ) { + acc.push(checked); + } + } + acc +} + +#[test] +fn filter_removes_duplicates_within_set() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + + run_to_block(3, |b| { + // a new session at each block + Some(( + true, + b, + vec![(&0, v0.public()), (&1, v1.public())], + Some(vec![(&0, v0.public()), (&1, v1.public())]), + )) + }); + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + + let payload = + ExplicitDisputeStatement { valid: true, candidate_hash, session: 1 }.signing_payload(); + + let payload_against = + ExplicitDisputeStatement { valid: false, candidate_hash, session: 1 }.signing_payload(); + + let sig_a = v0.sign(&payload); + let sig_b = v0.sign(&payload); + let sig_c = v0.sign(&payload); + let sig_d = v1.sign(&payload_against); + + let statements = DisputeStatementSet { + candidate_hash, + session: 1, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a.clone(), + ), + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_b, + ), + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_c, + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + sig_d.clone(), + ), + ], + }; + + let post_conclusion_acceptance_period = 10; + let statements = + as DisputesHandler>>::filter_dispute_data( + statements, + post_conclusion_acceptance_period, + ); + + assert_eq!( + statements, + Some(CheckedDisputeStatementSet::unchecked_from_unchecked(DisputeStatementSet { + candidate_hash, + session: 1, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a, + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + sig_d, + ), + ] + })) + ); + }) +} + +#[test] +fn filter_bad_signatures_correctly_detects_single_sided() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + let v2 = ::Pair::generate().0; + let v3 = ::Pair::generate().0; + + run_to_block(3, |b| { + // a new session at each block + Some(( + true, + b, + vec![(&0, v0.public()), (&1, v1.public()), (&2, v2.public()), (&3, v3.public())], + Some(vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + ]), + )) + }); + + let candidate_hash_a = CandidateHash(sp_core::H256::repeat_byte(1)); + + let payload = |c_hash: &CandidateHash, valid| { + ExplicitDisputeStatement { valid, candidate_hash: *c_hash, session: 1 } + .signing_payload() + }; + + let payload_a = payload(&candidate_hash_a, true); + let payload_a_bad = payload(&candidate_hash_a, false); + + let sig_0 = v0.sign(&payload_a); + let sig_1 = v1.sign(&payload_a_bad); + + let statements = vec![DisputeStatementSet { + candidate_hash: candidate_hash_a, + session: 1, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_0.clone(), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(2), + sig_1.clone(), + ), + ], + }]; + + let statements = apply_filter_all::(statements); + + assert!(statements.is_empty()); + }) +} + +#[test] +fn filter_removes_session_out_of_bounds() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + + run_to_block(3, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + + let payload = + ExplicitDisputeStatement { valid: true, candidate_hash, session: 1 }.signing_payload(); + + let sig_a = v0.sign(&payload); + + let statements = vec![DisputeStatementSet { + candidate_hash, + session: 100, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a, + )], + }]; + + let statements = apply_filter_all::(statements); + + assert!(statements.is_empty()); + }) +} + +#[test] +fn filter_removes_concluded_ancient() { + let dispute_post_conclusion_acceptance_period = 2; + + let mock_genesis_config = MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { + dispute_post_conclusion_acceptance_period, + ..Default::default() + }, + }, + ..Default::default() + }; + + new_test_ext(mock_genesis_config).execute_with(|| { + let v0 = ::Pair::generate().0; + + run_to_block(3, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); + + let candidate_hash_a = CandidateHash(sp_core::H256::repeat_byte(1)); + let candidate_hash_b = CandidateHash(sp_core::H256::repeat_byte(2)); + + >::insert( + &1, + &candidate_hash_a, + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 0; 4], + validators_against: bitvec![u8, BitOrderLsb0; 1; 4], + start: 0, + concluded_at: Some(0), + }, + ); + + >::insert( + &1, + &candidate_hash_b, + DisputeState { + validators_for: bitvec![u8, BitOrderLsb0; 0; 4], + validators_against: bitvec![u8, BitOrderLsb0; 1; 4], + start: 0, + concluded_at: Some(1), + }, + ); + + let payload_a = + ExplicitDisputeStatement { valid: true, candidate_hash: candidate_hash_a, session: 1 } + .signing_payload(); + + let payload_b = + ExplicitDisputeStatement { valid: true, candidate_hash: candidate_hash_b, session: 1 } + .signing_payload(); + + let sig_a = v0.sign(&payload_a); + let sig_b = v0.sign(&payload_b); + + let statements = vec![ + DisputeStatementSet { + candidate_hash: candidate_hash_a, + session: 1, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a, + )], + }, + DisputeStatementSet { + candidate_hash: candidate_hash_b, + session: 1, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_b.clone(), + )], + }, + ]; + + let statements = apply_filter_all::(statements); + + assert_eq!( + statements, + vec![CheckedDisputeStatementSet::unchecked_from_unchecked(DisputeStatementSet { + candidate_hash: candidate_hash_b, + session: 1, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_b, + ),] + })] + ); + }) +} + +#[test] +fn filter_removes_duplicate_statements_sets() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + + run_to_block(3, |b| { + // a new session at each block + Some(( + true, + b, + vec![(&0, v0.public()), (&1, v1.public())], + Some(vec![(&0, v0.public()), (&1, v1.public())]), + )) + }); + + let candidate_hash_a = CandidateHash(sp_core::H256::repeat_byte(1)); + + let payload = + ExplicitDisputeStatement { valid: true, candidate_hash: candidate_hash_a, session: 1 } + .signing_payload(); + + let payload_against = + ExplicitDisputeStatement { valid: false, candidate_hash: candidate_hash_a, session: 1 } + .signing_payload(); + + let sig_a = v0.sign(&payload); + let sig_a_against = v1.sign(&payload_against); + + let statements = vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a.clone(), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + sig_a_against.clone(), + ), + ]; + + let mut sets = vec![ + DisputeStatementSet { + candidate_hash: candidate_hash_a, + session: 1, + statements: statements.clone(), + }, + DisputeStatementSet { + candidate_hash: candidate_hash_a, + session: 1, + statements: statements.clone(), + }, + ]; + + // `Err(())` indicates presence of duplicates + assert!( as DisputesHandler< + BlockNumberFor, + >>::deduplicate_and_sort_dispute_data(&mut sets) + .is_err()); + + assert_eq!( + sets, + vec![DisputeStatementSet { candidate_hash: candidate_hash_a, session: 1, statements }] + ); + }) +} + +#[test] +fn filter_ignores_single_sided() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + + run_to_block(3, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); + + let candidate_hash_a = CandidateHash(sp_core::H256::repeat_byte(1)); + + let payload = + ExplicitDisputeStatement { valid: true, candidate_hash: candidate_hash_a, session: 1 } + .signing_payload(); + + let sig_a = v0.sign(&payload); + + let statements = vec![DisputeStatementSet { + candidate_hash: candidate_hash_a, + session: 1, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a.clone(), + )], + }]; + + let statements = apply_filter_all::(statements); + + assert!(statements.is_empty()); + }) +} + +#[test] +fn import_ignores_single_sided() { + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + + run_to_block(3, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); + + let candidate_hash_a = CandidateHash(sp_core::H256::repeat_byte(1)); + + let payload = + ExplicitDisputeStatement { valid: true, candidate_hash: candidate_hash_a, session: 1 } + .signing_payload(); + + let sig_a = v0.sign(&payload); + + let statements = vec![DisputeStatementSet { + candidate_hash: candidate_hash_a, + session: 1, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a.clone(), + )], + }]; + + let statements = apply_filter_all::(statements); + assert!(statements.is_empty()); + }) +} diff --git a/polkadot/runtime/parachains/src/dmp.rs b/polkadot/runtime/parachains/src/dmp.rs new file mode 100644 index 0000000000000000000000000000000000000000..490c2fa1cd09c607022663d49f1705bb45a0d0df --- /dev/null +++ b/polkadot/runtime/parachains/src/dmp.rs @@ -0,0 +1,368 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! To prevent Out of Memory errors on the `DownwardMessageQueue`, an +//! exponential fee factor (`DeliveryFeeFactor`) is set. The fee factor +//! increments exponentially after the number of messages in the +//! `DownwardMessageQueue` pass a threshold. This threshold is set as: +//! +//! ```ignore +//! // Maximum max sized messages that can be send to +//! // the DownwardMessageQueue before it runs out of memory +//! max_messsages = MAX_POSSIBLE_ALLOCATION / max_downward_message_size +//! threshold = max_messages / THRESHOLD_FACTOR +//! ``` +//! Based on the THRESHOLD_FACTOR, the threshold is set as a fraction of the +//! total messages. The `DeliveryFeeFactor` increases for a message over the +//! threshold by: +//! +//! `DeliveryFeeFactor = DeliveryFeeFactor * +//! (EXPONENTIAL_FEE_BASE + MESSAGE_SIZE_FEE_BASE * encoded_message_size_in_KB)` +//! +//! And decreases when the number of messages in the `DownwardMessageQueue` fall +//! below the threshold by: +//! +//! `DeliveryFeeFactor = DeliveryFeeFactor / EXPONENTIAL_FEE_BASE` +//! +//! As an extra defensive measure, a `max_messages` hard +//! limit is set to the number of messages in the DownwardMessageQueue. Messages +//! that would increase the number of messages in the queue above this hard +//! limit are dropped. + +use crate::{ + configuration::{self, HostConfiguration}, + initializer, FeeTracker, +}; +use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::{DownwardMessage, Hash, Id as ParaId, InboundDownwardMessage}; +use sp_core::MAX_POSSIBLE_ALLOCATION; +use sp_runtime::{ + traits::{BlakeTwo256, Hash as HashT, SaturatedConversion}, + FixedU128, Saturating, +}; +use sp_std::{fmt, prelude::*}; +use xcm::latest::SendError; + +pub use pallet::*; + +#[cfg(test)] +mod tests; + +const THRESHOLD_FACTOR: u32 = 2; +const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(105, 100); // 1.05 +const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); // 0.001 + +/// An error sending a downward message. +#[cfg_attr(test, derive(Debug))] +pub enum QueueDownwardMessageError { + /// The message being sent exceeds the configured max message size. + ExceedsMaxMessageSize, +} + +impl From for SendError { + fn from(err: QueueDownwardMessageError) -> Self { + match err { + QueueDownwardMessageError::ExceedsMaxMessageSize => SendError::ExceedsMaxMessageSize, + } + } +} + +/// An error returned by [`check_processed_downward_messages`] that indicates an acceptance check +/// didn't pass. +pub enum ProcessedDownwardMessagesAcceptanceErr { + /// If there are pending messages then `processed_downward_messages` should be at least 1, + AdvancementRule, + /// `processed_downward_messages` should not be greater than the number of pending messages. + Underflow { processed_downward_messages: u32, dmq_length: u32 }, +} + +impl fmt::Debug for ProcessedDownwardMessagesAcceptanceErr { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + use ProcessedDownwardMessagesAcceptanceErr::*; + match *self { + AdvancementRule => { + write!(fmt, "DMQ is not empty, but processed_downward_messages is 0",) + }, + Underflow { processed_downward_messages, dmq_length } => write!( + fmt, + "processed_downward_messages = {}, but dmq_length is only {}", + processed_downward_messages, dmq_length, + ), + } + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + configuration::Config {} + + /// The downward messages addressed for a certain para. + #[pallet::storage] + pub(crate) type DownwardMessageQueues = StorageMap< + _, + Twox64Concat, + ParaId, + Vec>>, + ValueQuery, + >; + + /// A mapping that stores the downward message queue MQC head for each para. + /// + /// Each link in this chain has a form: + /// `(prev_head, B, H(M))`, where + /// - `prev_head`: is the previous head hash or zero if none. + /// - `B`: is the relay-chain block number in which a message was appended. + /// - `H(M)`: is the hash of the message being appended. + #[pallet::storage] + pub(crate) type DownwardMessageQueueHeads = + StorageMap<_, Twox64Concat, ParaId, Hash, ValueQuery>; + + /// Initialization value for the DeliveryFee factor. + #[pallet::type_value] + pub fn InitialFactor() -> FixedU128 { + FixedU128::from_u32(1) + } + + /// The number to multiply the base delivery fee by. + #[pallet::storage] + pub(crate) type DeliveryFeeFactor = + StorageMap<_, Twox64Concat, ParaId, FixedU128, ValueQuery, InitialFactor>; +} +/// Routines and getters related to downward message passing. +impl Pallet { + /// Block initialization logic, called by initializer. + pub(crate) fn initializer_initialize(_now: BlockNumberFor) -> Weight { + Weight::zero() + } + + /// Block finalization logic, called by initializer. + pub(crate) fn initializer_finalize() {} + + /// Called by the initializer to note that a new session has started. + pub(crate) fn initializer_on_new_session( + _notification: &initializer::SessionChangeNotification>, + outgoing_paras: &[ParaId], + ) { + Self::perform_outgoing_para_cleanup(outgoing_paras); + } + + /// Iterate over all paras that were noted for offboarding and remove all the data + /// associated with them. + fn perform_outgoing_para_cleanup(outgoing: &[ParaId]) { + for outgoing_para in outgoing { + Self::clean_dmp_after_outgoing(outgoing_para); + } + } + + /// Remove all relevant storage items for an outgoing parachain. + fn clean_dmp_after_outgoing(outgoing_para: &ParaId) { + DownwardMessageQueues::::remove(outgoing_para); + DownwardMessageQueueHeads::::remove(outgoing_para); + } + + /// Determine whether enqueuing a downward message to a specific recipient para would result + /// in an error. If this returns `Ok(())` the caller can be certain that a call to + /// `queue_downward_message` with the same parameters will be successful. + pub fn can_queue_downward_message( + config: &HostConfiguration>, + para: &ParaId, + msg: &DownwardMessage, + ) -> Result<(), QueueDownwardMessageError> { + let serialized_len = msg.len() as u32; + if serialized_len > config.max_downward_message_size { + return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) + } + + // Hard limit on Queue size + if Self::dmq_length(*para) > Self::dmq_max_length(config.max_downward_message_size) { + return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) + } + + Ok(()) + } + + /// Enqueue a downward message to a specific recipient para. + /// + /// When encoded, the message should not exceed the `config.max_downward_message_size`. + /// Otherwise, the message won't be sent and `Err` will be returned. + /// + /// It is possible to send a downward message to a non-existent para. That, however, would lead + /// to a dangling storage. If the caller cannot statically prove that the recipient exists + /// then the caller should perform a runtime check. + pub fn queue_downward_message( + config: &HostConfiguration>, + para: ParaId, + msg: DownwardMessage, + ) -> Result<(), QueueDownwardMessageError> { + let serialized_len = msg.len() as u32; + if serialized_len > config.max_downward_message_size { + return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) + } + + // Hard limit on Queue size + if Self::dmq_length(para) > Self::dmq_max_length(config.max_downward_message_size) { + return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) + } + + let inbound = + InboundDownwardMessage { msg, sent_at: >::block_number() }; + + // obtain the new link in the MQC and update the head. + DownwardMessageQueueHeads::::mutate(para, |head| { + let new_head = + BlakeTwo256::hash_of(&(*head, inbound.sent_at, T::Hashing::hash_of(&inbound.msg))); + *head = new_head; + }); + + let q_len = DownwardMessageQueues::::mutate(para, |v| { + v.push(inbound); + v.len() + }); + + let threshold = + Self::dmq_max_length(config.max_downward_message_size).saturating_div(THRESHOLD_FACTOR); + if q_len > (threshold as usize) { + let message_size_factor = + FixedU128::from_u32(serialized_len.saturating_div(1024) as u32) + .saturating_mul(MESSAGE_SIZE_FEE_BASE); + Self::increment_fee_factor(para, message_size_factor); + } + + Ok(()) + } + + /// Checks if the number of processed downward messages is valid. + pub(crate) fn check_processed_downward_messages( + para: ParaId, + relay_parent_number: BlockNumberFor, + processed_downward_messages: u32, + ) -> Result<(), ProcessedDownwardMessagesAcceptanceErr> { + let dmq_length = Self::dmq_length(para); + + if dmq_length > 0 && processed_downward_messages == 0 { + // The advancement rule is for at least one downwards message to be processed + // if the queue is non-empty at the relay-parent. Downwards messages are annotated + // with the block number, so we compare the earliest (first) against the relay parent. + let contents = Self::dmq_contents(para); + + // sanity: if dmq_length is >0 this should always be 'Some'. + if contents.get(0).map_or(false, |msg| msg.sent_at <= relay_parent_number) { + return Err(ProcessedDownwardMessagesAcceptanceErr::AdvancementRule) + } + } + + // Note that we might be allowing a parachain to signal that it's processed + // messages that hadn't been placed in the queue at the relay_parent. + // only 'stupid' parachains would do it and we don't (and can't) force anyone + // to act on messages, so the lenient approach is fine here. + if dmq_length < processed_downward_messages { + return Err(ProcessedDownwardMessagesAcceptanceErr::Underflow { + processed_downward_messages, + dmq_length, + }) + } + + Ok(()) + } + + /// Prunes the specified number of messages from the downward message queue of the given para. + pub(crate) fn prune_dmq(para: ParaId, processed_downward_messages: u32) -> Weight { + let q_len = DownwardMessageQueues::::mutate(para, |q| { + let processed_downward_messages = processed_downward_messages as usize; + if processed_downward_messages > q.len() { + // reaching this branch is unexpected due to the constraint established by + // `check_processed_downward_messages`. But better be safe than sorry. + q.clear(); + } else { + *q = q.split_off(processed_downward_messages); + } + q.len() + }); + + let config = configuration::ActiveConfig::::get(); + let threshold = + Self::dmq_max_length(config.max_downward_message_size).saturating_div(THRESHOLD_FACTOR); + if q_len <= (threshold as usize) { + Self::decrement_fee_factor(para); + } + T::DbWeight::get().reads_writes(1, 1) + } + + /// Returns the Head of Message Queue Chain for the given para or `None` if there is none + /// associated with it. + #[cfg(test)] + fn dmq_mqc_head(para: ParaId) -> Hash { + DownwardMessageQueueHeads::::get(¶) + } + + /// Returns the number of pending downward messages addressed to the given para. + /// + /// Returns 0 if the para doesn't have an associated downward message queue. + pub(crate) fn dmq_length(para: ParaId) -> u32 { + DownwardMessageQueues::::decode_len(¶) + .unwrap_or(0) + .saturated_into::() + } + + fn dmq_max_length(max_downward_message_size: u32) -> u32 { + MAX_POSSIBLE_ALLOCATION.checked_div(max_downward_message_size).unwrap_or(0) + } + + /// Returns the downward message queue contents for the given para. + /// + /// The most recent messages are the latest in the vector. + pub(crate) fn dmq_contents( + recipient: ParaId, + ) -> Vec>> { + DownwardMessageQueues::::get(&recipient) + } + + /// Raise the delivery fee factor by a multiplicative factor and stores the resulting value. + /// + /// Returns the new delivery fee factor after the increment. + pub(crate) fn increment_fee_factor(para: ParaId, message_size_factor: FixedU128) -> FixedU128 { + >::mutate(para, |f| { + *f = f.saturating_mul(EXPONENTIAL_FEE_BASE + message_size_factor); + *f + }) + } + + /// Reduce the delivery fee factor by a multiplicative factor and stores the resulting value. + /// + /// Does not reduce the fee factor below the initial value, which is currently set as 1. + /// + /// Returns the new delivery fee factor after the decrement. + pub(crate) fn decrement_fee_factor(para: ParaId) -> FixedU128 { + >::mutate(para, |f| { + *f = InitialFactor::get().max(*f / EXPONENTIAL_FEE_BASE); + *f + }) + } +} + +impl FeeTracker for Pallet { + fn get_fee_factor(para: ParaId) -> FixedU128 { + DeliveryFeeFactor::::get(para) + } +} diff --git a/polkadot/runtime/parachains/src/dmp/tests.rs b/polkadot/runtime/parachains/src/dmp/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..a65984840da585ec524120fb4fb95111734e4eff --- /dev/null +++ b/polkadot/runtime/parachains/src/dmp/tests.rs @@ -0,0 +1,299 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::{ + configuration::ActiveConfig, + mock::{new_test_ext, Configuration, Dmp, MockGenesisConfig, Paras, System, Test}, +}; +use frame_support::assert_ok; +use hex_literal::hex; +use parity_scale_codec::Encode; +use primitives::BlockNumber; + +pub(crate) fn run_to_block(to: BlockNumber, new_session: Option>) { + while System::block_number() < to { + let b = System::block_number(); + Paras::initializer_finalize(b); + Dmp::initializer_finalize(); + if new_session.as_ref().map_or(false, |v| v.contains(&(b + 1))) { + Dmp::initializer_on_new_session(&Default::default(), &Vec::new()); + } + System::on_finalize(b); + + System::on_initialize(b + 1); + System::set_block_number(b + 1); + + Paras::initializer_finalize(b + 1); + Dmp::initializer_initialize(b + 1); + } +} + +fn default_genesis_config() -> MockGenesisConfig { + MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: crate::configuration::HostConfiguration { + max_downward_message_size: 1024, + ..Default::default() + }, + }, + ..Default::default() + } +} + +fn queue_downward_message( + para_id: ParaId, + msg: DownwardMessage, +) -> Result<(), QueueDownwardMessageError> { + Dmp::queue_downward_message(&Configuration::config(), para_id, msg) +} + +#[test] +fn clean_dmp_works() { + let a = ParaId::from(1312); + let b = ParaId::from(228); + let c = ParaId::from(123); + + new_test_ext(default_genesis_config()).execute_with(|| { + // enqueue downward messages to A, B and C. + queue_downward_message(a, vec![1, 2, 3]).unwrap(); + queue_downward_message(b, vec![4, 5, 6]).unwrap(); + queue_downward_message(c, vec![7, 8, 9]).unwrap(); + + let notification = crate::initializer::SessionChangeNotification::default(); + let outgoing_paras = vec![a, b]; + Dmp::initializer_on_new_session(¬ification, &outgoing_paras); + + assert!(DownwardMessageQueues::::get(&a).is_empty()); + assert!(DownwardMessageQueues::::get(&b).is_empty()); + assert!(!DownwardMessageQueues::::get(&c).is_empty()); + }); +} + +#[test] +fn dmq_length_and_head_updated_properly() { + let a = ParaId::from(1312); + let b = ParaId::from(228); + + new_test_ext(default_genesis_config()).execute_with(|| { + assert_eq!(Dmp::dmq_length(a), 0); + assert_eq!(Dmp::dmq_length(b), 0); + + queue_downward_message(a, vec![1, 2, 3]).unwrap(); + + assert_eq!(Dmp::dmq_length(a), 1); + assert_eq!(Dmp::dmq_length(b), 0); + assert!(!Dmp::dmq_mqc_head(a).is_zero()); + assert!(Dmp::dmq_mqc_head(b).is_zero()); + }); +} + +#[test] +fn dmp_mqc_head_fixture() { + let a = ParaId::from(2000); + + new_test_ext(default_genesis_config()).execute_with(|| { + run_to_block(2, None); + assert!(Dmp::dmq_mqc_head(a).is_zero()); + queue_downward_message(a, vec![1, 2, 3]).unwrap(); + + run_to_block(3, None); + queue_downward_message(a, vec![4, 5, 6]).unwrap(); + + assert_eq!( + Dmp::dmq_mqc_head(a), + hex!["88dc00db8cc9d22aa62b87807705831f164387dfa49f80a8600ed1cbe1704b6b"].into(), + ); + }); +} + +#[test] +fn check_processed_downward_messages() { + let a = ParaId::from(1312); + + new_test_ext(default_genesis_config()).execute_with(|| { + let block_number = System::block_number(); + + // processed_downward_messages=0 is allowed when the DMQ is empty. + assert!(Dmp::check_processed_downward_messages(a, block_number, 0).is_ok()); + + queue_downward_message(a, vec![1, 2, 3]).unwrap(); + queue_downward_message(a, vec![4, 5, 6]).unwrap(); + queue_downward_message(a, vec![7, 8, 9]).unwrap(); + + // 0 doesn't pass if the DMQ has msgs. + assert!(Dmp::check_processed_downward_messages(a, block_number, 0).is_err()); + // a candidate can consume up to 3 messages + assert!(Dmp::check_processed_downward_messages(a, block_number, 1).is_ok()); + assert!(Dmp::check_processed_downward_messages(a, block_number, 2).is_ok()); + assert!(Dmp::check_processed_downward_messages(a, block_number, 3).is_ok()); + // there is no 4 messages in the queue + assert!(Dmp::check_processed_downward_messages(a, block_number, 4).is_err()); + }); +} + +#[test] +fn check_processed_downward_messages_advancement_rule() { + let a = ParaId::from(1312); + + new_test_ext(default_genesis_config()).execute_with(|| { + let block_number = System::block_number(); + + run_to_block(block_number + 1, None); + let advanced_block_number = System::block_number(); + + queue_downward_message(a, vec![1, 2, 3]).unwrap(); + queue_downward_message(a, vec![4, 5, 6]).unwrap(); + + // The queue was empty at genesis, 0 is OK despite it being non-empty in the further block. + assert!(Dmp::check_processed_downward_messages(a, block_number, 0).is_ok()); + // For the advanced block number, however, the rule is broken in case of 0. + assert!(Dmp::check_processed_downward_messages(a, advanced_block_number, 0).is_err()); + }); +} + +#[test] +fn dmq_pruning() { + let a = ParaId::from(1312); + + new_test_ext(default_genesis_config()).execute_with(|| { + assert_eq!(Dmp::dmq_length(a), 0); + + queue_downward_message(a, vec![1, 2, 3]).unwrap(); + queue_downward_message(a, vec![4, 5, 6]).unwrap(); + queue_downward_message(a, vec![7, 8, 9]).unwrap(); + assert_eq!(Dmp::dmq_length(a), 3); + + // pruning 0 elements shouldn't change anything. + Dmp::prune_dmq(a, 0); + assert_eq!(Dmp::dmq_length(a), 3); + + Dmp::prune_dmq(a, 2); + assert_eq!(Dmp::dmq_length(a), 1); + }); +} + +#[test] +fn queue_downward_message_critical() { + let a = ParaId::from(1312); + + let mut genesis = default_genesis_config(); + genesis.configuration.config.max_downward_message_size = 7; + + new_test_ext(genesis).execute_with(|| { + let smol = [0; 3].to_vec(); + let big = [0; 8].to_vec(); + + // still within limits + assert_eq!(smol.encode().len(), 4); + assert!(queue_downward_message(a, smol).is_ok()); + + // that's too big + assert_eq!(big.encode().len(), 9); + assert!(queue_downward_message(a, big).is_err()); + }); +} + +#[test] +fn verify_dmq_mqc_head_is_externally_accessible() { + use hex_literal::hex; + use primitives::well_known_keys; + + let a = ParaId::from(2020); + + new_test_ext(default_genesis_config()).execute_with(|| { + let head = sp_io::storage::get(&well_known_keys::dmq_mqc_head(a)); + assert_eq!(head, None); + + queue_downward_message(a, vec![1, 2, 3]).unwrap(); + + let head = sp_io::storage::get(&well_known_keys::dmq_mqc_head(a)); + assert_eq!( + head, + Some( + hex!["434f8579a2297dfea851bf6be33093c83a78b655a53ae141a7894494c0010589"] + .to_vec() + .into() + ) + ); + }); +} + +#[test] +fn verify_fee_increment_and_decrement() { + let a = ParaId::from(123); + let mut genesis = default_genesis_config(); + genesis.configuration.config.max_downward_message_size = 16777216; + new_test_ext(genesis).execute_with(|| { + let initial = InitialFactor::get(); + assert_eq!(DeliveryFeeFactor::::get(a), initial); + + // Under fee limit + queue_downward_message(a, vec![1]).unwrap(); + assert_eq!(DeliveryFeeFactor::::get(a), initial); + + // Limit reached so fee is increased + queue_downward_message(a, vec![1]).unwrap(); + let result = InitialFactor::get().saturating_mul(EXPONENTIAL_FEE_BASE); + assert_eq!(DeliveryFeeFactor::::get(a), result); + + Dmp::prune_dmq(a, 1); + assert_eq!(DeliveryFeeFactor::::get(a), initial); + + // 10 Kb message adds additional 0.001 per KB fee factor + let big_message = [0; 10240].to_vec(); + let msg_len_in_kb = big_message.len().saturating_div(1024) as u32; + let result = initial.saturating_mul( + EXPONENTIAL_FEE_BASE + + MESSAGE_SIZE_FEE_BASE.saturating_mul(FixedU128::from_u32(msg_len_in_kb)), + ); + queue_downward_message(a, big_message).unwrap(); + assert_eq!(DeliveryFeeFactor::::get(a), result); + + queue_downward_message(a, vec![1]).unwrap(); + let result = result.saturating_mul(EXPONENTIAL_FEE_BASE); + assert_eq!(DeliveryFeeFactor::::get(a), result); + + Dmp::prune_dmq(a, 3); + let result = result / EXPONENTIAL_FEE_BASE; + assert_eq!(DeliveryFeeFactor::::get(a), result); + assert_eq!(Dmp::dmq_length(a), 0); + + // Messages under limit will keep decreasing fee factor until base fee factor is reached + queue_downward_message(a, vec![1]).unwrap(); + Dmp::prune_dmq(a, 1); + queue_downward_message(a, vec![1]).unwrap(); + Dmp::prune_dmq(a, 1); + assert_eq!(DeliveryFeeFactor::::get(a), initial); + }); +} + +#[test] +fn verify_fee_factor_reaches_high_value() { + let a = ParaId::from(123); + let mut genesis = default_genesis_config(); + genesis.configuration.config.max_downward_message_size = 51200; + new_test_ext(genesis).execute_with(|| { + let max_messages = + Dmp::dmq_max_length(ActiveConfig::::get().max_downward_message_size); + let mut total_fee_factor = FixedU128::from_float(1.0); + for _ in 1..max_messages { + assert_ok!(queue_downward_message(a, vec![])); + total_fee_factor = total_fee_factor + (DeliveryFeeFactor::::get(a)); + } + assert!(total_fee_factor > FixedU128::from_u32(100_000_000)); + }); +} diff --git a/polkadot/runtime/parachains/src/hrmp.rs b/polkadot/runtime/parachains/src/hrmp.rs new file mode 100644 index 0000000000000000000000000000000000000000..a3ce6e2d8a3503d73a9a4453378ce67c24597c08 --- /dev/null +++ b/polkadot/runtime/parachains/src/hrmp.rs @@ -0,0 +1,1613 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::{ + configuration::{self, HostConfiguration}, + dmp, ensure_parachain, initializer, paras, +}; +use frame_support::{pallet_prelude::*, traits::ReservableCurrency, DefaultNoBound}; +use frame_system::pallet_prelude::*; +use parity_scale_codec::{Decode, Encode}; +use polkadot_parachain::primitives::HorizontalMessages; +use primitives::{ + Balance, Hash, HrmpChannelId, Id as ParaId, InboundHrmpMessage, OutboundHrmpMessage, + SessionIndex, +}; +use scale_info::TypeInfo; +use sp_runtime::traits::{AccountIdConversion, BlakeTwo256, Hash as HashT, UniqueSaturatedInto}; +use sp_std::{ + collections::{btree_map::BTreeMap, btree_set::BTreeSet}, + fmt, mem, + prelude::*, +}; + +pub use pallet::*; + +/// Maximum bound that can be set for inbound channels. +/// +/// If inaccurate, the weighing of this pallet might become inaccurate. It is expected form the +/// `configurations` pallet to check these values before setting +pub const HRMP_MAX_INBOUND_CHANNELS_BOUND: u32 = 128; +/// Same as [`HRMP_MAX_INBOUND_CHANNELS_BOUND`], but for outbound channels. +pub const HRMP_MAX_OUTBOUND_CHANNELS_BOUND: u32 = 128; + +#[cfg(test)] +pub(crate) mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +pub trait WeightInfo { + fn hrmp_init_open_channel() -> Weight; + fn hrmp_accept_open_channel() -> Weight; + fn hrmp_close_channel() -> Weight; + fn force_clean_hrmp(i: u32, e: u32) -> Weight; + fn force_process_hrmp_open(c: u32) -> Weight; + fn force_process_hrmp_close(c: u32) -> Weight; + fn hrmp_cancel_open_request(c: u32) -> Weight; + fn clean_open_channel_requests(c: u32) -> Weight; + fn force_open_hrmp_channel(c: u32) -> Weight; +} + +/// A weight info that is only suitable for testing. +pub struct TestWeightInfo; + +impl WeightInfo for TestWeightInfo { + fn hrmp_accept_open_channel() -> Weight { + Weight::MAX + } + fn force_clean_hrmp(_: u32, _: u32) -> Weight { + Weight::MAX + } + fn force_process_hrmp_close(_: u32) -> Weight { + Weight::MAX + } + fn force_process_hrmp_open(_: u32) -> Weight { + Weight::MAX + } + fn hrmp_cancel_open_request(_: u32) -> Weight { + Weight::MAX + } + fn hrmp_close_channel() -> Weight { + Weight::MAX + } + fn hrmp_init_open_channel() -> Weight { + Weight::MAX + } + fn clean_open_channel_requests(_: u32) -> Weight { + Weight::MAX + } + fn force_open_hrmp_channel(_: u32) -> Weight { + Weight::MAX + } +} + +/// A description of a request to open an HRMP channel. +#[derive(Encode, Decode, TypeInfo)] +pub struct HrmpOpenChannelRequest { + /// Indicates if this request was confirmed by the recipient. + pub confirmed: bool, + /// NOTE: this field is deprecated. Channel open requests became non-expiring and this value + /// became unused. + pub _age: SessionIndex, + /// The amount that the sender supplied at the time of creation of this request. + pub sender_deposit: Balance, + /// The maximum message size that could be put into the channel. + pub max_message_size: u32, + /// The maximum number of messages that can be pending in the channel at once. + pub max_capacity: u32, + /// The maximum total size of the messages that can be pending in the channel at once. + pub max_total_size: u32, +} + +/// A metadata of an HRMP channel. +#[derive(Encode, Decode, TypeInfo)] +#[cfg_attr(test, derive(Debug))] +pub struct HrmpChannel { + // NOTE: This structure is used by parachains via merkle proofs. Therefore, this struct + // requires special treatment. + // + // A parachain requested this struct can only depend on the subset of this struct. + // Specifically, only a first few fields can be depended upon (See `AbridgedHrmpChannel`). + // These fields cannot be changed without corresponding migration of parachains. + /// The maximum number of messages that can be pending in the channel at once. + pub max_capacity: u32, + /// The maximum total size of the messages that can be pending in the channel at once. + pub max_total_size: u32, + /// The maximum message size that could be put into the channel. + pub max_message_size: u32, + /// The current number of messages pending in the channel. + /// Invariant: should be less or equal to `max_capacity`.s`. + pub msg_count: u32, + /// The total size in bytes of all message payloads in the channel. + /// Invariant: should be less or equal to `max_total_size`. + pub total_size: u32, + /// A head of the Message Queue Chain for this channel. Each link in this chain has a form: + /// `(prev_head, B, H(M))`, where + /// - `prev_head`: is the previous value of `mqc_head` or zero if none. + /// - `B`: is the [relay-chain] block number in which a message was appended + /// - `H(M)`: is the hash of the message being appended. + /// This value is initialized to a special value that consists of all zeroes which indicates + /// that no messages were previously added. + pub mqc_head: Option, + /// The amount that the sender supplied as a deposit when opening this channel. + pub sender_deposit: Balance, + /// The amount that the recipient supplied as a deposit when accepting opening this channel. + pub recipient_deposit: Balance, +} + +/// An error returned by [`check_hrmp_watermark`] that indicates an acceptance criteria check +/// didn't pass. +pub enum HrmpWatermarkAcceptanceErr { + AdvancementRule { new_watermark: BlockNumber, last_watermark: BlockNumber }, + AheadRelayParent { new_watermark: BlockNumber, relay_chain_parent_number: BlockNumber }, + LandsOnBlockWithNoMessages { new_watermark: BlockNumber }, +} + +/// An error returned by [`check_outbound_hrmp`] that indicates an acceptance criteria check +/// didn't pass. +pub enum OutboundHrmpAcceptanceErr { + MoreMessagesThanPermitted { sent: u32, permitted: u32 }, + NotSorted { idx: u32 }, + NoSuchChannel { idx: u32, channel_id: HrmpChannelId }, + MaxMessageSizeExceeded { idx: u32, msg_size: u32, max_size: u32 }, + TotalSizeExceeded { idx: u32, total_size: u32, limit: u32 }, + CapacityExceeded { idx: u32, count: u32, limit: u32 }, +} + +impl fmt::Debug for HrmpWatermarkAcceptanceErr +where + BlockNumber: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + use HrmpWatermarkAcceptanceErr::*; + match self { + AdvancementRule { new_watermark, last_watermark } => write!( + fmt, + "the HRMP watermark is not advanced relative to the last watermark ({:?} > {:?})", + new_watermark, last_watermark, + ), + AheadRelayParent { new_watermark, relay_chain_parent_number } => write!( + fmt, + "the HRMP watermark is ahead the relay-parent ({:?} > {:?})", + new_watermark, relay_chain_parent_number + ), + LandsOnBlockWithNoMessages { new_watermark } => write!( + fmt, + "the HRMP watermark ({:?}) doesn't land on a block with messages received", + new_watermark + ), + } + } +} + +impl fmt::Debug for OutboundHrmpAcceptanceErr { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + use OutboundHrmpAcceptanceErr::*; + match self { + MoreMessagesThanPermitted { sent, permitted } => write!( + fmt, + "more HRMP messages than permitted by config ({} > {})", + sent, permitted, + ), + NotSorted { idx } => { + write!(fmt, "the HRMP messages are not sorted (first unsorted is at index {})", idx,) + }, + NoSuchChannel { idx, channel_id } => write!( + fmt, + "the HRMP message at index {} is sent to a non existent channel {:?}->{:?}", + idx, channel_id.sender, channel_id.recipient, + ), + MaxMessageSizeExceeded { idx, msg_size, max_size } => write!( + fmt, + "the HRMP message at index {} exceeds the negotiated channel maximum message size ({} > {})", + idx, msg_size, max_size, + ), + TotalSizeExceeded { idx, total_size, limit } => write!( + fmt, + "sending the HRMP message at index {} would exceed the neogitiated channel total size ({} > {})", + idx, total_size, limit, + ), + CapacityExceeded { idx, count, limit } => write!( + fmt, + "sending the HRMP message at index {} would exceed the neogitiated channel capacity ({} > {})", + idx, count, limit, + ), + } + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: + frame_system::Config + configuration::Config + paras::Config + dmp::Config + { + /// The outer event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + type RuntimeOrigin: From + + From<::RuntimeOrigin> + + Into::RuntimeOrigin>>; + + /// The origin that can perform "force" actions on channels. + type ChannelManager: EnsureOrigin<::RuntimeOrigin>; + + /// An interface for reserving deposits for opening channels. + /// + /// NOTE that this Currency instance will be charged with the amounts defined in the + /// `Configuration` pallet. Specifically, that means that the `Balance` of the `Currency` + /// implementation should be the same as `Balance` as used in the `Configuration`. + type Currency: ReservableCurrency; + + /// Something that provides the weight of this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// Open HRMP channel requested. + /// `[sender, recipient, proposed_max_capacity, proposed_max_message_size]` + OpenChannelRequested(ParaId, ParaId, u32, u32), + /// An HRMP channel request sent by the receiver was canceled by either party. + /// `[by_parachain, channel_id]` + OpenChannelCanceled(ParaId, HrmpChannelId), + /// Open HRMP channel accepted. `[sender, recipient]` + OpenChannelAccepted(ParaId, ParaId), + /// HRMP channel closed. `[by_parachain, channel_id]` + ChannelClosed(ParaId, HrmpChannelId), + /// An HRMP channel was opened via Root origin. + /// `[sender, recipient, proposed_max_capacity, proposed_max_message_size]` + HrmpChannelForceOpened(ParaId, ParaId, u32, u32), + } + + #[pallet::error] + pub enum Error { + /// The sender tried to open a channel to themselves. + OpenHrmpChannelToSelf, + /// The recipient is not a valid para. + OpenHrmpChannelInvalidRecipient, + /// The requested capacity is zero. + OpenHrmpChannelZeroCapacity, + /// The requested capacity exceeds the global limit. + OpenHrmpChannelCapacityExceedsLimit, + /// The requested maximum message size is 0. + OpenHrmpChannelZeroMessageSize, + /// The open request requested the message size that exceeds the global limit. + OpenHrmpChannelMessageSizeExceedsLimit, + /// The channel already exists + OpenHrmpChannelAlreadyExists, + /// There is already a request to open the same channel. + OpenHrmpChannelAlreadyRequested, + /// The sender already has the maximum number of allowed outbound channels. + OpenHrmpChannelLimitExceeded, + /// The channel from the sender to the origin doesn't exist. + AcceptHrmpChannelDoesntExist, + /// The channel is already confirmed. + AcceptHrmpChannelAlreadyConfirmed, + /// The recipient already has the maximum number of allowed inbound channels. + AcceptHrmpChannelLimitExceeded, + /// The origin tries to close a channel where it is neither the sender nor the recipient. + CloseHrmpChannelUnauthorized, + /// The channel to be closed doesn't exist. + CloseHrmpChannelDoesntExist, + /// The channel close request is already requested. + CloseHrmpChannelAlreadyUnderway, + /// Canceling is requested by neither the sender nor recipient of the open channel request. + CancelHrmpOpenChannelUnauthorized, + /// The open request doesn't exist. + OpenHrmpChannelDoesntExist, + /// Cannot cancel an HRMP open channel request because it is already confirmed. + OpenHrmpChannelAlreadyConfirmed, + /// The provided witness data is wrong. + WrongWitness, + } + + /// The set of pending HRMP open channel requests. + /// + /// The set is accompanied by a list for iteration. + /// + /// Invariant: + /// - There are no channels that exists in list but not in the set and vice versa. + #[pallet::storage] + pub type HrmpOpenChannelRequests = + StorageMap<_, Twox64Concat, HrmpChannelId, HrmpOpenChannelRequest>; + + // NOTE: could become bounded, but we don't have a global maximum for this. + // `HRMP_MAX_INBOUND_CHANNELS_BOUND` are per parachain, while this storage tracks the + // global state. + #[pallet::storage] + pub type HrmpOpenChannelRequestsList = + StorageValue<_, Vec, ValueQuery>; + + /// This mapping tracks how many open channel requests are initiated by a given sender para. + /// Invariant: `HrmpOpenChannelRequests` should contain the same number of items that has + /// `(X, _)` as the number of `HrmpOpenChannelRequestCount` for `X`. + #[pallet::storage] + pub type HrmpOpenChannelRequestCount = + StorageMap<_, Twox64Concat, ParaId, u32, ValueQuery>; + + /// This mapping tracks how many open channel requests were accepted by a given recipient para. + /// Invariant: `HrmpOpenChannelRequests` should contain the same number of items `(_, X)` with + /// `confirmed` set to true, as the number of `HrmpAcceptedChannelRequestCount` for `X`. + #[pallet::storage] + pub type HrmpAcceptedChannelRequestCount = + StorageMap<_, Twox64Concat, ParaId, u32, ValueQuery>; + + /// A set of pending HRMP close channel requests that are going to be closed during the session + /// change. Used for checking if a given channel is registered for closure. + /// + /// The set is accompanied by a list for iteration. + /// + /// Invariant: + /// - There are no channels that exists in list but not in the set and vice versa. + #[pallet::storage] + pub type HrmpCloseChannelRequests = StorageMap<_, Twox64Concat, HrmpChannelId, ()>; + + #[pallet::storage] + pub type HrmpCloseChannelRequestsList = + StorageValue<_, Vec, ValueQuery>; + + /// The HRMP watermark associated with each para. + /// Invariant: + /// - each para `P` used here as a key should satisfy `Paras::is_valid_para(P)` within a + /// session. + #[pallet::storage] + pub type HrmpWatermarks = StorageMap<_, Twox64Concat, ParaId, BlockNumberFor>; + + /// HRMP channel data associated with each para. + /// Invariant: + /// - each participant in the channel should satisfy `Paras::is_valid_para(P)` within a session. + #[pallet::storage] + pub type HrmpChannels = StorageMap<_, Twox64Concat, HrmpChannelId, HrmpChannel>; + + /// Ingress/egress indexes allow to find all the senders and receivers given the opposite side. + /// I.e. + /// + /// (a) ingress index allows to find all the senders for a given recipient. + /// (b) egress index allows to find all the recipients for a given sender. + /// + /// Invariants: + /// - for each ingress index entry for `P` each item `I` in the index should present in + /// `HrmpChannels` as `(I, P)`. + /// - for each egress index entry for `P` each item `E` in the index should present in + /// `HrmpChannels` as `(P, E)`. + /// - there should be no other dangling channels in `HrmpChannels`. + /// - the vectors are sorted. + #[pallet::storage] + pub type HrmpIngressChannelsIndex = + StorageMap<_, Twox64Concat, ParaId, Vec, ValueQuery>; + + // NOTE that this field is used by parachains via merkle storage proofs, therefore changing + // the format will require migration of parachains. + #[pallet::storage] + pub type HrmpEgressChannelsIndex = + StorageMap<_, Twox64Concat, ParaId, Vec, ValueQuery>; + + /// Storage for the messages for each channel. + /// Invariant: cannot be non-empty if the corresponding channel in `HrmpChannels` is `None`. + #[pallet::storage] + pub type HrmpChannelContents = StorageMap< + _, + Twox64Concat, + HrmpChannelId, + Vec>>, + ValueQuery, + >; + + /// Maintains a mapping that can be used to answer the question: What paras sent a message at + /// the given block number for a given receiver. Invariants: + /// - The inner `Vec` is never empty. + /// - The inner `Vec` cannot store two same `ParaId`. + /// - The outer vector is sorted ascending by block number and cannot store two items with the + /// same block number. + #[pallet::storage] + pub type HrmpChannelDigests = + StorageMap<_, Twox64Concat, ParaId, Vec<(BlockNumberFor, Vec)>, ValueQuery>; + + /// Preopen the given HRMP channels. + /// + /// The values in the tuple corresponds to + /// `(sender, recipient, max_capacity, max_message_size)`, i.e. similar to `init_open_channel`. + /// In fact, the initialization is performed as if the `init_open_channel` and + /// `accept_open_channel` were called with the respective parameters and the session change take + /// place. + /// + /// As such, each channel initializer should satisfy the same constraints, namely: + /// + /// 1. `max_capacity` and `max_message_size` should be within the limits set by the + /// configuration pallet. + /// 2. `sender` and `recipient` must be valid paras. + #[pallet::genesis_config] + #[derive(DefaultNoBound)] + pub struct GenesisConfig { + #[serde(skip)] + _config: sp_std::marker::PhantomData, + preopen_hrmp_channels: Vec<(ParaId, ParaId, u32, u32)>, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + initialize_storage::(&self.preopen_hrmp_channels); + } + } + + #[pallet::call] + impl Pallet { + /// Initiate opening a channel from a parachain to a given recipient with given channel + /// parameters. + /// + /// - `proposed_max_capacity` - specifies how many messages can be in the channel at once. + /// - `proposed_max_message_size` - specifies the maximum size of the messages. + /// + /// These numbers are a subject to the relay-chain configuration limits. + /// + /// The channel can be opened only after the recipient confirms it and only on a session + /// change. + #[pallet::call_index(0)] + #[pallet::weight(::WeightInfo::hrmp_init_open_channel())] + pub fn hrmp_init_open_channel( + origin: OriginFor, + recipient: ParaId, + proposed_max_capacity: u32, + proposed_max_message_size: u32, + ) -> DispatchResult { + let origin = ensure_parachain(::RuntimeOrigin::from(origin))?; + Self::init_open_channel( + origin, + recipient, + proposed_max_capacity, + proposed_max_message_size, + )?; + Self::deposit_event(Event::OpenChannelRequested( + origin, + recipient, + proposed_max_capacity, + proposed_max_message_size, + )); + Ok(()) + } + + /// Accept a pending open channel request from the given sender. + /// + /// The channel will be opened only on the next session boundary. + #[pallet::call_index(1)] + #[pallet::weight(::WeightInfo::hrmp_accept_open_channel())] + pub fn hrmp_accept_open_channel(origin: OriginFor, sender: ParaId) -> DispatchResult { + let origin = ensure_parachain(::RuntimeOrigin::from(origin))?; + Self::accept_open_channel(origin, sender)?; + Self::deposit_event(Event::OpenChannelAccepted(sender, origin)); + Ok(()) + } + + /// Initiate unilateral closing of a channel. The origin must be either the sender or the + /// recipient in the channel being closed. + /// + /// The closure can only happen on a session change. + #[pallet::call_index(2)] + #[pallet::weight(::WeightInfo::hrmp_close_channel())] + pub fn hrmp_close_channel( + origin: OriginFor, + channel_id: HrmpChannelId, + ) -> DispatchResult { + let origin = ensure_parachain(::RuntimeOrigin::from(origin))?; + Self::close_channel(origin, channel_id.clone())?; + Self::deposit_event(Event::ChannelClosed(origin, channel_id)); + Ok(()) + } + + /// This extrinsic triggers the cleanup of all the HRMP storage items that a para may have. + /// Normally this happens once per session, but this allows you to trigger the cleanup + /// immediately for a specific parachain. + /// + /// Number of inbound and outbound channels for `para` must be provided as witness data. + /// + /// Origin must be the `ChannelManager`. + #[pallet::call_index(3)] + #[pallet::weight(::WeightInfo::force_clean_hrmp(*_inbound, *_outbound))] + pub fn force_clean_hrmp( + origin: OriginFor, + para: ParaId, + _inbound: u32, + _outbound: u32, + ) -> DispatchResult { + T::ChannelManager::ensure_origin(origin)?; + Self::clean_hrmp_after_outgoing(¶); + Ok(()) + } + + /// Force process HRMP open channel requests. + /// + /// If there are pending HRMP open channel requests, you can use this function to process + /// all of those requests immediately. + /// + /// Total number of opening channels must be provided as witness data. + /// + /// Origin must be the `ChannelManager`. + #[pallet::call_index(4)] + #[pallet::weight(::WeightInfo::force_process_hrmp_open(*_channels))] + pub fn force_process_hrmp_open(origin: OriginFor, _channels: u32) -> DispatchResult { + T::ChannelManager::ensure_origin(origin)?; + let host_config = configuration::Pallet::::config(); + Self::process_hrmp_open_channel_requests(&host_config); + Ok(()) + } + + /// Force process HRMP close channel requests. + /// + /// If there are pending HRMP close channel requests, you can use this function to process + /// all of those requests immediately. + /// + /// Total number of closing channels must be provided as witness data. + /// + /// Origin must be the `ChannelManager`. + #[pallet::call_index(5)] + #[pallet::weight(::WeightInfo::force_process_hrmp_close(*_channels))] + pub fn force_process_hrmp_close(origin: OriginFor, _channels: u32) -> DispatchResult { + T::ChannelManager::ensure_origin(origin)?; + Self::process_hrmp_close_channel_requests(); + Ok(()) + } + + /// This cancels a pending open channel request. It can be canceled by either of the sender + /// or the recipient for that request. The origin must be either of those. + /// + /// The cancellation happens immediately. It is not possible to cancel the request if it is + /// already accepted. + /// + /// Total number of open requests (i.e. `HrmpOpenChannelRequestsList`) must be provided as + /// witness data. + #[pallet::call_index(6)] + #[pallet::weight(::WeightInfo::hrmp_cancel_open_request(*open_requests))] + pub fn hrmp_cancel_open_request( + origin: OriginFor, + channel_id: HrmpChannelId, + open_requests: u32, + ) -> DispatchResult { + let origin = ensure_parachain(::RuntimeOrigin::from(origin))?; + ensure!( + HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32 <= + open_requests, + Error::::WrongWitness + ); + Self::cancel_open_request(origin, channel_id.clone())?; + Self::deposit_event(Event::OpenChannelCanceled(origin, channel_id)); + Ok(()) + } + + /// Open a channel from a `sender` to a `recipient` `ParaId`. Although opened by governance, + /// the `max_capacity` and `max_message_size` are still subject to the Relay Chain's + /// configured limits. + /// + /// Expected use is when one of the `ParaId`s involved in the channel is governed by the + /// Relay Chain, e.g. a system parachain. + /// + /// Origin must be the `ChannelManager`. + #[pallet::call_index(7)] + #[pallet::weight(::WeightInfo::force_open_hrmp_channel(1))] + pub fn force_open_hrmp_channel( + origin: OriginFor, + sender: ParaId, + recipient: ParaId, + max_capacity: u32, + max_message_size: u32, + ) -> DispatchResultWithPostInfo { + T::ChannelManager::ensure_origin(origin)?; + + // Guard against a common footgun where someone makes a channel request to a system + // parachain and then makes a proposal to open the channel via governance, which fails + // because `init_open_channel` fails if there is an existing request. This check will + // clear an existing request such that `init_open_channel` should otherwise succeed. + let channel_id = HrmpChannelId { sender, recipient }; + let cancel_request: u32 = + if let Some(_open_channel) = HrmpOpenChannelRequests::::get(&channel_id) { + Self::cancel_open_request(sender, channel_id)?; + 1 + } else { + 0 + }; + + // Now we proceed with normal init/accept. + Self::init_open_channel(sender, recipient, max_capacity, max_message_size)?; + Self::accept_open_channel(recipient, sender)?; + Self::deposit_event(Event::HrmpChannelForceOpened( + sender, + recipient, + max_capacity, + max_message_size, + )); + + Ok(Some(::WeightInfo::force_open_hrmp_channel(cancel_request)).into()) + } + } +} + +fn initialize_storage(preopen_hrmp_channels: &[(ParaId, ParaId, u32, u32)]) { + let host_config = configuration::Pallet::::config(); + for &(sender, recipient, max_capacity, max_message_size) in preopen_hrmp_channels { + if let Err(err) = + preopen_hrmp_channel::(sender, recipient, max_capacity, max_message_size) + { + panic!("failed to initialize the genesis storage: {:?}", err); + } + } + >::process_hrmp_open_channel_requests(&host_config); +} + +fn preopen_hrmp_channel( + sender: ParaId, + recipient: ParaId, + max_capacity: u32, + max_message_size: u32, +) -> DispatchResult { + >::init_open_channel(sender, recipient, max_capacity, max_message_size)?; + >::accept_open_channel(recipient, sender)?; + Ok(()) +} + +/// Routines and getters related to HRMP. +impl Pallet { + /// Block initialization logic, called by initializer. + pub(crate) fn initializer_initialize(_now: BlockNumberFor) -> Weight { + Weight::zero() + } + + /// Block finalization logic, called by initializer. + pub(crate) fn initializer_finalize() {} + + /// Called by the initializer to note that a new session has started. + pub(crate) fn initializer_on_new_session( + notification: &initializer::SessionChangeNotification>, + outgoing_paras: &[ParaId], + ) -> Weight { + let w1 = Self::perform_outgoing_para_cleanup(¬ification.prev_config, outgoing_paras); + Self::process_hrmp_open_channel_requests(¬ification.prev_config); + Self::process_hrmp_close_channel_requests(); + w1.saturating_add(::WeightInfo::force_process_hrmp_open( + outgoing_paras.len() as u32 + )) + .saturating_add(::WeightInfo::force_process_hrmp_close( + outgoing_paras.len() as u32 + )) + } + + /// Iterate over all paras that were noted for offboarding and remove all the data + /// associated with them. + fn perform_outgoing_para_cleanup( + config: &HostConfiguration>, + outgoing: &[ParaId], + ) -> Weight { + let mut w = Self::clean_open_channel_requests(config, outgoing); + for outgoing_para in outgoing { + Self::clean_hrmp_after_outgoing(outgoing_para); + + // we need a few extra bits of data to weigh this -- all of this is read internally + // anyways, so no overhead. + let ingress_count = + HrmpIngressChannelsIndex::::decode_len(outgoing_para).unwrap_or_default() as u32; + let egress_count = + HrmpEgressChannelsIndex::::decode_len(outgoing_para).unwrap_or_default() as u32; + w = w.saturating_add(::WeightInfo::force_clean_hrmp( + ingress_count, + egress_count, + )); + } + w + } + + // Go over the HRMP open channel requests and remove all in which offboarding paras participate. + // + // This will also perform the refunds for the counterparty if it doesn't offboard. + pub(crate) fn clean_open_channel_requests( + config: &HostConfiguration>, + outgoing: &[ParaId], + ) -> Weight { + // First collect all the channel ids of the open requests in which there is at least one + // party presents in the outgoing list. + // + // Both the open channel request list and outgoing list are expected to be small enough. + // In the most common case there will be only single outgoing para. + let open_channel_reqs = HrmpOpenChannelRequestsList::::get(); + let (go, stay): (Vec, Vec) = open_channel_reqs + .into_iter() + .partition(|req_id| outgoing.iter().any(|id| req_id.is_participant(*id))); + HrmpOpenChannelRequestsList::::put(stay); + + // Then iterate over all open requests to be removed, pull them out of the set and perform + // the refunds if applicable. + for req_id in go { + let req_data = match HrmpOpenChannelRequests::::take(&req_id) { + Some(req_data) => req_data, + None => { + // Can't normally happen but no need to panic. + continue + }, + }; + + // Return the deposit of the sender, but only if it is not the para being offboarded. + if !outgoing.contains(&req_id.sender) { + T::Currency::unreserve( + &req_id.sender.into_account_truncating(), + req_data.sender_deposit.unique_saturated_into(), + ); + } + + // If the request was confirmed, then it means it was confirmed in the finished session. + // Therefore, the config's hrmp_recipient_deposit represents the actual value of the + // deposit. + // + // We still want to refund the deposit only if the para is not being offboarded. + if req_data.confirmed { + if !outgoing.contains(&req_id.recipient) { + T::Currency::unreserve( + &req_id.recipient.into_account_truncating(), + config.hrmp_recipient_deposit.unique_saturated_into(), + ); + } + Self::decrease_accepted_channel_request_count(req_id.recipient); + } + } + + ::WeightInfo::clean_open_channel_requests(outgoing.len() as u32) + } + + /// Remove all storage entries associated with the given para. + fn clean_hrmp_after_outgoing(outgoing_para: &ParaId) { + HrmpOpenChannelRequestCount::::remove(outgoing_para); + HrmpAcceptedChannelRequestCount::::remove(outgoing_para); + + let ingress = HrmpIngressChannelsIndex::::take(outgoing_para) + .into_iter() + .map(|sender| HrmpChannelId { sender, recipient: *outgoing_para }); + let egress = HrmpEgressChannelsIndex::::take(outgoing_para) + .into_iter() + .map(|recipient| HrmpChannelId { sender: *outgoing_para, recipient }); + let mut to_close = ingress.chain(egress).collect::>(); + to_close.sort(); + to_close.dedup(); + + for channel in to_close { + Self::close_hrmp_channel(&channel); + } + } + + /// Iterate over all open channel requests and: + /// + /// - prune the stale requests + /// - enact the confirmed requests + fn process_hrmp_open_channel_requests(config: &HostConfiguration>) { + let mut open_req_channels = HrmpOpenChannelRequestsList::::get(); + if open_req_channels.is_empty() { + return + } + + // iterate the vector starting from the end making our way to the beginning. This way we + // can leverage `swap_remove` to efficiently remove an item during iteration. + let mut idx = open_req_channels.len(); + loop { + // bail if we've iterated over all items. + if idx == 0 { + break + } + + idx -= 1; + let channel_id = open_req_channels[idx].clone(); + let request = HrmpOpenChannelRequests::::get(&channel_id).expect( + "can't be `None` due to the invariant that the list contains the same items as the set; qed", + ); + + if request.confirmed { + if >::is_valid_para(channel_id.sender) && + >::is_valid_para(channel_id.recipient) + { + HrmpChannels::::insert( + &channel_id, + HrmpChannel { + sender_deposit: request.sender_deposit, + recipient_deposit: config.hrmp_recipient_deposit, + max_capacity: request.max_capacity, + max_total_size: request.max_total_size, + max_message_size: request.max_message_size, + msg_count: 0, + total_size: 0, + mqc_head: None, + }, + ); + + HrmpIngressChannelsIndex::::mutate(&channel_id.recipient, |v| { + if let Err(i) = v.binary_search(&channel_id.sender) { + v.insert(i, channel_id.sender); + } + }); + HrmpEgressChannelsIndex::::mutate(&channel_id.sender, |v| { + if let Err(i) = v.binary_search(&channel_id.recipient) { + v.insert(i, channel_id.recipient); + } + }); + } + + Self::decrease_open_channel_request_count(channel_id.sender); + Self::decrease_accepted_channel_request_count(channel_id.recipient); + + let _ = open_req_channels.swap_remove(idx); + HrmpOpenChannelRequests::::remove(&channel_id); + } + } + + HrmpOpenChannelRequestsList::::put(open_req_channels); + } + + /// Iterate over all close channel requests unconditionally closing the channels. + fn process_hrmp_close_channel_requests() { + let close_reqs = HrmpCloseChannelRequestsList::::take(); + for condemned_ch_id in close_reqs { + HrmpCloseChannelRequests::::remove(&condemned_ch_id); + Self::close_hrmp_channel(&condemned_ch_id); + } + } + + /// Close and remove the designated HRMP channel. + /// + /// This includes returning the deposits. + /// + /// This function is idempotent, meaning that after the first application it should have no + /// effect (i.e. it won't return the deposits twice). + fn close_hrmp_channel(channel_id: &HrmpChannelId) { + if let Some(HrmpChannel { sender_deposit, recipient_deposit, .. }) = + HrmpChannels::::take(channel_id) + { + T::Currency::unreserve( + &channel_id.sender.into_account_truncating(), + sender_deposit.unique_saturated_into(), + ); + T::Currency::unreserve( + &channel_id.recipient.into_account_truncating(), + recipient_deposit.unique_saturated_into(), + ); + } + + HrmpChannelContents::::remove(channel_id); + + HrmpEgressChannelsIndex::::mutate(&channel_id.sender, |v| { + if let Ok(i) = v.binary_search(&channel_id.recipient) { + v.remove(i); + } + }); + HrmpIngressChannelsIndex::::mutate(&channel_id.recipient, |v| { + if let Ok(i) = v.binary_search(&channel_id.sender) { + v.remove(i); + } + }); + } + + /// Check that the candidate of the given recipient controls the HRMP watermark properly. + pub(crate) fn check_hrmp_watermark( + recipient: ParaId, + relay_chain_parent_number: BlockNumberFor, + new_hrmp_watermark: BlockNumberFor, + ) -> Result<(), HrmpWatermarkAcceptanceErr>> { + // First, check where the watermark CANNOT legally land. + // + // (a) For ensuring that messages are eventually processed, we require each parablock's + // watermark to be greater than the last one. The exception to this is if the previous + // watermark was already equal to the current relay-parent number. + // + // (b) However, a parachain cannot read into "the future", therefore the watermark should + // not be greater than the relay-chain context block which the parablock refers to. + if new_hrmp_watermark == relay_chain_parent_number { + return Ok(()) + } + + if new_hrmp_watermark > relay_chain_parent_number { + return Err(HrmpWatermarkAcceptanceErr::AheadRelayParent { + new_watermark: new_hrmp_watermark, + relay_chain_parent_number, + }) + } + + if let Some(last_watermark) = HrmpWatermarks::::get(&recipient) { + if new_hrmp_watermark <= last_watermark { + return Err(HrmpWatermarkAcceptanceErr::AdvancementRule { + new_watermark: new_hrmp_watermark, + last_watermark, + }) + } + } + + // Second, check where the watermark CAN land. It's one of the following: + // + // (a) The relay parent block number (checked above). + // (b) A relay-chain block in which this para received at least one message (checked here) + let digest = HrmpChannelDigests::::get(&recipient); + if !digest + .binary_search_by_key(&new_hrmp_watermark, |(block_no, _)| *block_no) + .is_ok() + { + return Err(HrmpWatermarkAcceptanceErr::LandsOnBlockWithNoMessages { + new_watermark: new_hrmp_watermark, + }) + } + Ok(()) + } + + /// Returns HRMP watermarks of previously sent messages to a given para. + pub(crate) fn valid_watermarks(recipient: ParaId) -> Vec> { + HrmpChannelDigests::::get(&recipient) + .into_iter() + .map(|(block_no, _)| block_no) + .collect() + } + + pub(crate) fn check_outbound_hrmp( + config: &HostConfiguration>, + sender: ParaId, + out_hrmp_msgs: &[OutboundHrmpMessage], + ) -> Result<(), OutboundHrmpAcceptanceErr> { + if out_hrmp_msgs.len() as u32 > config.hrmp_max_message_num_per_candidate { + return Err(OutboundHrmpAcceptanceErr::MoreMessagesThanPermitted { + sent: out_hrmp_msgs.len() as u32, + permitted: config.hrmp_max_message_num_per_candidate, + }) + } + + let mut last_recipient = None::; + + for (idx, out_msg) in + out_hrmp_msgs.iter().enumerate().map(|(idx, out_msg)| (idx as u32, out_msg)) + { + match last_recipient { + // the messages must be sorted in ascending order and there must be no two messages + // sent to the same recipient. Thus we can check that every recipient is strictly + // greater than the previous one. + Some(last_recipient) if out_msg.recipient <= last_recipient => + return Err(OutboundHrmpAcceptanceErr::NotSorted { idx }), + _ => last_recipient = Some(out_msg.recipient), + } + + let channel_id = HrmpChannelId { sender, recipient: out_msg.recipient }; + + let channel = match HrmpChannels::::get(&channel_id) { + Some(channel) => channel, + None => return Err(OutboundHrmpAcceptanceErr::NoSuchChannel { channel_id, idx }), + }; + + let msg_size = out_msg.data.len() as u32; + if msg_size > channel.max_message_size { + return Err(OutboundHrmpAcceptanceErr::MaxMessageSizeExceeded { + idx, + msg_size, + max_size: channel.max_message_size, + }) + } + + let new_total_size = channel.total_size + out_msg.data.len() as u32; + if new_total_size > channel.max_total_size { + return Err(OutboundHrmpAcceptanceErr::TotalSizeExceeded { + idx, + total_size: new_total_size, + limit: channel.max_total_size, + }) + } + + let new_msg_count = channel.msg_count + 1; + if new_msg_count > channel.max_capacity { + return Err(OutboundHrmpAcceptanceErr::CapacityExceeded { + idx, + count: new_msg_count, + limit: channel.max_capacity, + }) + } + } + + Ok(()) + } + + /// Returns remaining outbound channels capacity in messages and in bytes per recipient para. + pub(crate) fn outbound_remaining_capacity(sender: ParaId) -> Vec<(ParaId, (u32, u32))> { + let recipients = HrmpEgressChannelsIndex::::get(&sender); + let mut remaining = Vec::with_capacity(recipients.len()); + + for recipient in recipients { + let Some(channel) = HrmpChannels::::get(&HrmpChannelId { sender, recipient }) else { + continue + }; + remaining.push(( + recipient, + ( + channel.max_capacity - channel.msg_count, + channel.max_total_size - channel.total_size, + ), + )); + } + + remaining + } + + pub(crate) fn prune_hrmp(recipient: ParaId, new_hrmp_watermark: BlockNumberFor) -> Weight { + let mut weight = Weight::zero(); + + // sift through the incoming messages digest to collect the paras that sent at least one + // message to this parachain between the old and new watermarks. + let senders = HrmpChannelDigests::::mutate(&recipient, |digest| { + let mut senders = BTreeSet::new(); + let mut leftover = Vec::with_capacity(digest.len()); + for (block_no, paras_sent_msg) in mem::replace(digest, Vec::new()) { + if block_no <= new_hrmp_watermark { + senders.extend(paras_sent_msg); + } else { + leftover.push((block_no, paras_sent_msg)); + } + } + *digest = leftover; + senders + }); + weight += T::DbWeight::get().reads_writes(1, 1); + + // having all senders we can trivially find out the channels which we need to prune. + let channels_to_prune = + senders.into_iter().map(|sender| HrmpChannelId { sender, recipient }); + for channel_id in channels_to_prune { + // prune each channel up to the new watermark keeping track how many messages we removed + // and what is the total byte size of them. + let (mut pruned_cnt, mut pruned_size) = (0, 0); + + let contents = HrmpChannelContents::::get(&channel_id); + let mut leftover = Vec::with_capacity(contents.len()); + for msg in contents { + if msg.sent_at <= new_hrmp_watermark { + pruned_cnt += 1; + pruned_size += msg.data.len(); + } else { + leftover.push(msg); + } + } + if !leftover.is_empty() { + HrmpChannelContents::::insert(&channel_id, leftover); + } else { + HrmpChannelContents::::remove(&channel_id); + } + + // update the channel metadata. + HrmpChannels::::mutate(&channel_id, |channel| { + if let Some(ref mut channel) = channel { + channel.msg_count -= pruned_cnt as u32; + channel.total_size -= pruned_size as u32; + } + }); + + weight += T::DbWeight::get().reads_writes(2, 2); + } + + HrmpWatermarks::::insert(&recipient, new_hrmp_watermark); + weight += T::DbWeight::get().reads_writes(0, 1); + + weight + } + + /// Process the outbound HRMP messages by putting them into the appropriate recipient queues. + /// + /// Returns the amount of weight consumed. + pub(crate) fn queue_outbound_hrmp(sender: ParaId, out_hrmp_msgs: HorizontalMessages) -> Weight { + let mut weight = Weight::zero(); + let now = >::block_number(); + + for out_msg in out_hrmp_msgs { + let channel_id = HrmpChannelId { sender, recipient: out_msg.recipient }; + + let mut channel = match HrmpChannels::::get(&channel_id) { + Some(channel) => channel, + None => { + // apparently, that since acceptance of this candidate the recipient was + // offboarded and the channel no longer exists. + continue + }, + }; + + let inbound = InboundHrmpMessage { sent_at: now, data: out_msg.data }; + + // book keeping + channel.msg_count += 1; + channel.total_size += inbound.data.len() as u32; + + // compute the new MQC head of the channel + let prev_head = channel.mqc_head.unwrap_or(Default::default()); + let new_head = BlakeTwo256::hash_of(&( + prev_head, + inbound.sent_at, + T::Hashing::hash_of(&inbound.data), + )); + channel.mqc_head = Some(new_head); + + HrmpChannels::::insert(&channel_id, channel); + HrmpChannelContents::::append(&channel_id, inbound); + + // The digests are sorted in ascending by block number order. There are only two + // possible scenarios here ("the current" is the block of candidate's inclusion): + // + // (a) It's the first time anybody sends a message to this recipient within this block. + // In this case, the digest vector would be empty or the block number of the latest + // entry is smaller than the current. + // + // (b) Somebody has already sent a message within the current block. That means that + // the block number of the latest entry is equal to the current. + // + // Note that having the latest entry greater than the current block number is a logical + // error. + let mut recipient_digest = HrmpChannelDigests::::get(&channel_id.recipient); + if let Some(cur_block_digest) = recipient_digest + .last_mut() + .filter(|(block_no, _)| *block_no == now) + .map(|(_, ref mut d)| d) + { + cur_block_digest.push(sender); + } else { + recipient_digest.push((now, vec![sender])); + } + HrmpChannelDigests::::insert(&channel_id.recipient, recipient_digest); + + weight += T::DbWeight::get().reads_writes(2, 2); + } + + weight + } + + /// Initiate opening a channel from a parachain to a given recipient with given channel + /// parameters. + /// + /// Basically the same as [`hrmp_init_open_channel`](Pallet::hrmp_init_open_channel) but + /// intended for calling directly from other pallets rather than dispatched. + pub fn init_open_channel( + origin: ParaId, + recipient: ParaId, + proposed_max_capacity: u32, + proposed_max_message_size: u32, + ) -> DispatchResult { + ensure!(origin != recipient, Error::::OpenHrmpChannelToSelf); + ensure!( + >::is_valid_para(recipient), + Error::::OpenHrmpChannelInvalidRecipient, + ); + + let config = >::config(); + ensure!(proposed_max_capacity > 0, Error::::OpenHrmpChannelZeroCapacity); + ensure!( + proposed_max_capacity <= config.hrmp_channel_max_capacity, + Error::::OpenHrmpChannelCapacityExceedsLimit, + ); + ensure!(proposed_max_message_size > 0, Error::::OpenHrmpChannelZeroMessageSize); + ensure!( + proposed_max_message_size <= config.hrmp_channel_max_message_size, + Error::::OpenHrmpChannelMessageSizeExceedsLimit, + ); + + let channel_id = HrmpChannelId { sender: origin, recipient }; + ensure!( + HrmpOpenChannelRequests::::get(&channel_id).is_none(), + Error::::OpenHrmpChannelAlreadyRequested, + ); + ensure!( + HrmpChannels::::get(&channel_id).is_none(), + Error::::OpenHrmpChannelAlreadyExists, + ); + + let egress_cnt = HrmpEgressChannelsIndex::::decode_len(&origin).unwrap_or(0) as u32; + let open_req_cnt = HrmpOpenChannelRequestCount::::get(&origin); + let channel_num_limit = config.hrmp_max_parachain_outbound_channels; + ensure!( + egress_cnt + open_req_cnt < channel_num_limit, + Error::::OpenHrmpChannelLimitExceeded, + ); + + T::Currency::reserve( + &origin.into_account_truncating(), + config.hrmp_sender_deposit.unique_saturated_into(), + )?; + + // mutating storage directly now -- shall not bail henceforth. + + HrmpOpenChannelRequestCount::::insert(&origin, open_req_cnt + 1); + HrmpOpenChannelRequests::::insert( + &channel_id, + HrmpOpenChannelRequest { + confirmed: false, + _age: 0, + sender_deposit: config.hrmp_sender_deposit, + max_capacity: proposed_max_capacity, + max_message_size: proposed_max_message_size, + max_total_size: config.hrmp_channel_max_total_size, + }, + ); + HrmpOpenChannelRequestsList::::append(channel_id); + + let notification_bytes = { + use parity_scale_codec::Encode as _; + use xcm::opaque::{latest::prelude::*, VersionedXcm}; + + VersionedXcm::from(Xcm(vec![HrmpNewChannelOpenRequest { + sender: u32::from(origin), + max_capacity: proposed_max_capacity, + max_message_size: proposed_max_message_size, + }])) + .encode() + }; + if let Err(dmp::QueueDownwardMessageError::ExceedsMaxMessageSize) = + >::queue_downward_message(&config, recipient, notification_bytes) + { + // this should never happen unless the max downward message size is configured to an + // jokingly small number. + log::error!( + target: "runtime::hrmp", + "sending 'init_open_channel::notification_bytes' failed." + ); + debug_assert!(false); + } + + Ok(()) + } + + /// Accept a pending open channel request from the given sender. + /// + /// Basically the same as [`hrmp_accept_open_channel`](Pallet::hrmp_accept_open_channel) but + /// intended for calling directly from other pallets rather than dispatched. + pub fn accept_open_channel(origin: ParaId, sender: ParaId) -> DispatchResult { + let channel_id = HrmpChannelId { sender, recipient: origin }; + let mut channel_req = HrmpOpenChannelRequests::::get(&channel_id) + .ok_or(Error::::AcceptHrmpChannelDoesntExist)?; + ensure!(!channel_req.confirmed, Error::::AcceptHrmpChannelAlreadyConfirmed); + + // check if by accepting this open channel request, this parachain would exceed the + // number of inbound channels. + let config = >::config(); + let channel_num_limit = config.hrmp_max_parachain_inbound_channels; + let ingress_cnt = HrmpIngressChannelsIndex::::decode_len(&origin).unwrap_or(0) as u32; + let accepted_cnt = HrmpAcceptedChannelRequestCount::::get(&origin); + ensure!( + ingress_cnt + accepted_cnt < channel_num_limit, + Error::::AcceptHrmpChannelLimitExceeded, + ); + + T::Currency::reserve( + &origin.into_account_truncating(), + config.hrmp_recipient_deposit.unique_saturated_into(), + )?; + + // persist the updated open channel request and then increment the number of accepted + // channels. + channel_req.confirmed = true; + HrmpOpenChannelRequests::::insert(&channel_id, channel_req); + HrmpAcceptedChannelRequestCount::::insert(&origin, accepted_cnt + 1); + + let notification_bytes = { + use parity_scale_codec::Encode as _; + use xcm::opaque::{latest::prelude::*, VersionedXcm}; + let xcm = Xcm(vec![HrmpChannelAccepted { recipient: u32::from(origin) }]); + VersionedXcm::from(xcm).encode() + }; + if let Err(dmp::QueueDownwardMessageError::ExceedsMaxMessageSize) = + >::queue_downward_message(&config, sender, notification_bytes) + { + // this should never happen unless the max downward message size is configured to an + // jokingly small number. + log::error!( + target: "runtime::hrmp", + "sending 'accept_open_channel::notification_bytes' failed." + ); + debug_assert!(false); + } + + Ok(()) + } + + fn cancel_open_request(origin: ParaId, channel_id: HrmpChannelId) -> DispatchResult { + // check if the origin is allowed to close the channel. + ensure!(channel_id.is_participant(origin), Error::::CancelHrmpOpenChannelUnauthorized); + + let open_channel_req = HrmpOpenChannelRequests::::get(&channel_id) + .ok_or(Error::::OpenHrmpChannelDoesntExist)?; + ensure!(!open_channel_req.confirmed, Error::::OpenHrmpChannelAlreadyConfirmed); + + // Remove the request by the channel id and sync the accompanying list with the set. + HrmpOpenChannelRequests::::remove(&channel_id); + HrmpOpenChannelRequestsList::::mutate(|open_req_channels| { + if let Some(pos) = open_req_channels.iter().position(|x| x == &channel_id) { + open_req_channels.swap_remove(pos); + } + }); + + Self::decrease_open_channel_request_count(channel_id.sender); + // Don't decrease `HrmpAcceptedChannelRequestCount` because we don't consider confirmed + // requests here. + + // Unreserve the sender's deposit. The recipient could not have left their deposit because + // we ensured that the request is not confirmed. + T::Currency::unreserve( + &channel_id.sender.into_account_truncating(), + open_channel_req.sender_deposit.unique_saturated_into(), + ); + + Ok(()) + } + + fn close_channel(origin: ParaId, channel_id: HrmpChannelId) -> Result<(), Error> { + // check if the origin is allowed to close the channel. + ensure!(channel_id.is_participant(origin), Error::::CloseHrmpChannelUnauthorized); + + // check if the channel requested to close does exist. + ensure!( + HrmpChannels::::get(&channel_id).is_some(), + Error::::CloseHrmpChannelDoesntExist, + ); + + // check that there is no outstanding close request for this channel + ensure!( + HrmpCloseChannelRequests::::get(&channel_id).is_none(), + Error::::CloseHrmpChannelAlreadyUnderway, + ); + + HrmpCloseChannelRequests::::insert(&channel_id, ()); + HrmpCloseChannelRequestsList::::append(channel_id.clone()); + + let config = >::config(); + let notification_bytes = { + use parity_scale_codec::Encode as _; + use xcm::opaque::{latest::prelude::*, VersionedXcm}; + + VersionedXcm::from(Xcm(vec![HrmpChannelClosing { + initiator: u32::from(origin), + sender: u32::from(channel_id.sender), + recipient: u32::from(channel_id.recipient), + }])) + .encode() + }; + let opposite_party = + if origin == channel_id.sender { channel_id.recipient } else { channel_id.sender }; + if let Err(dmp::QueueDownwardMessageError::ExceedsMaxMessageSize) = + >::queue_downward_message(&config, opposite_party, notification_bytes) + { + // this should never happen unless the max downward message size is configured to an + // jokingly small number. + log::error!( + target: "runtime::hrmp", + "sending 'close_channel::notification_bytes' failed." + ); + debug_assert!(false); + } + + Ok(()) + } + + /// Returns the list of MQC heads for the inbound channels of the given recipient para paired + /// with the sender para ids. This vector is sorted ascending by the para id and doesn't contain + /// multiple entries with the same sender. + #[cfg(test)] + fn hrmp_mqc_heads(recipient: ParaId) -> Vec<(ParaId, Hash)> { + let sender_set = HrmpIngressChannelsIndex::::get(&recipient); + + // The ingress channels vector is sorted, thus `mqc_heads` is sorted as well. + let mut mqc_heads = Vec::with_capacity(sender_set.len()); + for sender in sender_set { + let channel_metadata = HrmpChannels::::get(&HrmpChannelId { sender, recipient }); + let mqc_head = channel_metadata + .and_then(|metadata| metadata.mqc_head) + .unwrap_or(Hash::default()); + mqc_heads.push((sender, mqc_head)); + } + + mqc_heads + } + + /// Returns contents of all channels addressed to the given recipient. Channels that have no + /// messages in them are also included. + pub(crate) fn inbound_hrmp_channels_contents( + recipient: ParaId, + ) -> BTreeMap>>> { + let sender_set = HrmpIngressChannelsIndex::::get(&recipient); + + let mut inbound_hrmp_channels_contents = BTreeMap::new(); + for sender in sender_set { + let channel_contents = + HrmpChannelContents::::get(&HrmpChannelId { sender, recipient }); + inbound_hrmp_channels_contents.insert(sender, channel_contents); + } + + inbound_hrmp_channels_contents + } +} + +impl Pallet { + /// Decreases the open channel request count for the given sender. If the value reaches zero + /// it is removed completely. + fn decrease_open_channel_request_count(sender: ParaId) { + HrmpOpenChannelRequestCount::::mutate_exists(&sender, |opt_rc| { + *opt_rc = opt_rc.and_then(|rc| match rc.saturating_sub(1) { + 0 => None, + n => Some(n), + }); + }); + } + + /// Decreases the accepted channel request count for the given sender. If the value reaches + /// zero it is removed completely. + fn decrease_accepted_channel_request_count(recipient: ParaId) { + HrmpAcceptedChannelRequestCount::::mutate_exists(&recipient, |opt_rc| { + *opt_rc = opt_rc.and_then(|rc| match rc.saturating_sub(1) { + 0 => None, + n => Some(n), + }); + }); + } + + #[cfg(any(feature = "runtime-benchmarks", test))] + fn assert_storage_consistency_exhaustive() { + fn assert_is_sorted(slice: &[T], id: &str) { + assert!(slice.windows(2).all(|xs| xs[0] <= xs[1]), "{} supposed to be sorted", id); + } + + let assert_contains_only_onboarded = |paras: Vec, cause: &str| { + for para in paras { + assert!( + crate::paras::Pallet::::is_valid_para(para), + "{}: {:?} para is offboarded", + cause, + para + ); + } + }; + + assert_eq!( + HrmpOpenChannelRequests::::iter().map(|(k, _)| k).collect::>(), + HrmpOpenChannelRequestsList::::get().into_iter().collect::>(), + ); + + // verify that the set of keys in `HrmpOpenChannelRequestCount` corresponds to the set + // of _senders_ in `HrmpOpenChannelRequests`. + // + // having ensured that, we can go ahead and go over all counts and verify that they match. + assert_eq!( + HrmpOpenChannelRequestCount::::iter() + .map(|(k, _)| k) + .collect::>(), + HrmpOpenChannelRequests::::iter() + .map(|(k, _)| k.sender) + .collect::>(), + ); + for (open_channel_initiator, expected_num) in HrmpOpenChannelRequestCount::::iter() { + let actual_num = HrmpOpenChannelRequests::::iter() + .filter(|(ch, _)| ch.sender == open_channel_initiator) + .count() as u32; + assert_eq!(expected_num, actual_num); + } + + // The same as above, but for accepted channel request count. Note that we are interested + // only in confirmed open requests. + assert_eq!( + HrmpAcceptedChannelRequestCount::::iter() + .map(|(k, _)| k) + .collect::>(), + HrmpOpenChannelRequests::::iter() + .filter(|(_, v)| v.confirmed) + .map(|(k, _)| k.recipient) + .collect::>(), + ); + for (channel_recipient, expected_num) in HrmpAcceptedChannelRequestCount::::iter() { + let actual_num = HrmpOpenChannelRequests::::iter() + .filter(|(ch, v)| ch.recipient == channel_recipient && v.confirmed) + .count() as u32; + assert_eq!(expected_num, actual_num); + } + + assert_eq!( + HrmpCloseChannelRequests::::iter().map(|(k, _)| k).collect::>(), + HrmpCloseChannelRequestsList::::get().into_iter().collect::>(), + ); + + // A HRMP watermark can be None for an onboarded parachain. However, an offboarded parachain + // cannot have an HRMP watermark: it should've been cleanup. + assert_contains_only_onboarded( + HrmpWatermarks::::iter().map(|(k, _)| k).collect::>(), + "HRMP watermarks should contain only onboarded paras", + ); + + // An entry in `HrmpChannels` indicates that the channel is open. Only open channels can + // have contents. + for (non_empty_channel, contents) in HrmpChannelContents::::iter() { + assert!(HrmpChannels::::contains_key(&non_empty_channel)); + + // pedantic check: there should be no empty vectors in storage, those should be modeled + // by a removed kv pair. + assert!(!contents.is_empty()); + } + + // Senders and recipients must be onboarded. Otherwise, all channels associated with them + // are removed. + assert_contains_only_onboarded( + HrmpChannels::::iter() + .flat_map(|(k, _)| vec![k.sender, k.recipient]) + .collect::>(), + "senders and recipients in all channels should be onboarded", + ); + + // Check the docs for `HrmpIngressChannelsIndex` and `HrmpEgressChannelsIndex` in decl + // storage to get an index what are the channel mappings indexes. + // + // Here, from indexes. + // + // ingress egress + // + // a -> [x, y] x -> [a, b] + // b -> [x, z] y -> [a] + // z -> [b] + // + // we derive a list of channels they represent. + // + // (a, x) (a, x) + // (a, y) (a, y) + // (b, x) (b, x) + // (b, z) (b, z) + // + // and then that we compare that to the channel list in the `HrmpChannels`. + let channel_set_derived_from_ingress = HrmpIngressChannelsIndex::::iter() + .flat_map(|(p, v)| v.into_iter().map(|i| (i, p)).collect::>()) + .collect::>(); + let channel_set_derived_from_egress = HrmpEgressChannelsIndex::::iter() + .flat_map(|(p, v)| v.into_iter().map(|e| (p, e)).collect::>()) + .collect::>(); + let channel_set_ground_truth = HrmpChannels::::iter() + .map(|(k, _)| (k.sender, k.recipient)) + .collect::>(); + assert_eq!(channel_set_derived_from_ingress, channel_set_derived_from_egress); + assert_eq!(channel_set_derived_from_egress, channel_set_ground_truth); + + HrmpIngressChannelsIndex::::iter() + .map(|(_, v)| v) + .for_each(|v| assert_is_sorted(&v, "HrmpIngressChannelsIndex")); + HrmpEgressChannelsIndex::::iter() + .map(|(_, v)| v) + .for_each(|v| assert_is_sorted(&v, "HrmpIngressChannelsIndex")); + + assert_contains_only_onboarded( + HrmpChannelDigests::::iter().map(|(k, _)| k).collect::>(), + "HRMP channel digests should contain only onboarded paras", + ); + for (_digest_for_para, digest) in HrmpChannelDigests::::iter() { + // Assert that items are in **strictly** ascending order. The strictness also implies + // there are no duplicates. + assert!(digest.windows(2).all(|xs| xs[0].0 < xs[1].0)); + + for (_, mut senders) in digest { + assert!(!senders.is_empty()); + + // check for duplicates. For that we sort the vector, then perform deduplication. + // if the vector stayed the same, there are no duplicates. + senders.sort(); + let orig_senders = senders.clone(); + senders.dedup(); + assert_eq!( + orig_senders, senders, + "duplicates removed implies existence of duplicates" + ); + } + } + } +} diff --git a/polkadot/runtime/parachains/src/hrmp/benchmarking.rs b/polkadot/runtime/parachains/src/hrmp/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..3fe347a7bcbaf054b23afa67ecaa7bb20d9100b0 --- /dev/null +++ b/polkadot/runtime/parachains/src/hrmp/benchmarking.rs @@ -0,0 +1,360 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::{ + configuration::Pallet as Configuration, + hrmp::{Pallet as Hrmp, *}, + paras::{Pallet as Paras, ParaKind, ParachainsCache}, + shared::Pallet as Shared, +}; +use frame_support::{assert_ok, traits::Currency}; + +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + +fn register_parachain_with_balance(id: ParaId, balance: BalanceOf) { + let mut parachains = ParachainsCache::new(); + Paras::::initialize_para_now( + &mut parachains, + id, + &crate::paras::ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: vec![1].into(), + validation_code: vec![1].into(), + }, + ); + T::Currency::make_free_balance_be(&id.into_account_truncating(), balance); +} + +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +/// Enumerates the phase in the setup process of a channel between two parachains. +enum ParachainSetupStep { + /// A channel open has been requested + Requested, + /// A channel open has been requested and accepted. + Accepted, + /// A channel open has been requested and accepted, and a session has passed and is now open. + Established, + /// A channel open has been requested and accepted, and a session has passed and is now + /// open, and now it has been requested to close down. + CloseRequested, +} + +fn establish_para_connection( + from: u32, + to: u32, + until: ParachainSetupStep, +) -> [(ParaId, crate::Origin); 2] +where + ::RuntimeOrigin: From, +{ + let config = Configuration::::config(); + let ed = T::Currency::minimum_balance(); + let deposit: BalanceOf = config.hrmp_sender_deposit.unique_saturated_into(); + let capacity = config.hrmp_channel_max_capacity; + let message_size = config.hrmp_channel_max_message_size; + + let sender: ParaId = from.into(); + let sender_origin: crate::Origin = from.into(); + + let recipient: ParaId = to.into(); + let recipient_origin: crate::Origin = to.into(); + + let output = [(sender, sender_origin.clone()), (recipient, recipient_origin.clone())]; + + // Make both a parachain if they are already not. + if !Paras::::is_parachain(sender) { + register_parachain_with_balance::(sender, deposit + ed); + } + if !Paras::::is_parachain(recipient) { + register_parachain_with_balance::(recipient, deposit + ed); + } + + assert_ok!(Hrmp::::hrmp_init_open_channel( + sender_origin.clone().into(), + recipient, + capacity, + message_size + )); + + if matches!(until, ParachainSetupStep::Requested) { + return output + } + + assert_ok!(Hrmp::::hrmp_accept_open_channel(recipient_origin.into(), sender)); + if matches!(until, ParachainSetupStep::Accepted) { + return output + } + + Hrmp::::process_hrmp_open_channel_requests(&Configuration::::config()); + if matches!(until, ParachainSetupStep::Established) { + return output + } + + let channel_id = HrmpChannelId { sender, recipient }; + assert_ok!(Hrmp::::hrmp_close_channel(sender_origin.clone().into(), channel_id)); + if matches!(until, ParachainSetupStep::CloseRequested) { + // NOTE: this is just for expressiveness, otherwise the if-statement is 100% useless. + return output + } + + output +} + +/// Prefix value for account generation. These numbers are used as seeds to create distinct (para) +/// accounts. +/// +/// To maintain sensibility created accounts should always be unique and never overlap. For example, +/// if for some benchmarking component `c`, accounts are being created `for s in 0..c` with seed +/// `PREFIX_0 + s`, then we must assert that `c <= PREFIX_1`, meaning that it won't overlap with +/// `PREFIX_2`. +/// +/// These values are chosen large enough so that the likelihood of any clash is already very low. +const PREFIX_0: u32 = 10_000; +const PREFIX_1: u32 = PREFIX_0 * 2; +const MAX_UNIQUE_CHANNELS: u32 = 128; + +static_assertions::const_assert!(MAX_UNIQUE_CHANNELS < PREFIX_0); +static_assertions::const_assert!(HRMP_MAX_INBOUND_CHANNELS_BOUND < PREFIX_0); +static_assertions::const_assert!(HRMP_MAX_OUTBOUND_CHANNELS_BOUND < PREFIX_0); + +frame_benchmarking::benchmarks! { + where_clause { where ::RuntimeOrigin: From } + + hrmp_init_open_channel { + let sender_id: ParaId = 1u32.into(); + let sender_origin: crate::Origin = 1u32.into(); + + let recipient_id: ParaId = 2u32.into(); + + // make sure para is registered, and has enough balance. + let ed = T::Currency::minimum_balance(); + let deposit: BalanceOf = Configuration::::config().hrmp_sender_deposit.unique_saturated_into(); + register_parachain_with_balance::(sender_id, deposit + ed); + register_parachain_with_balance::(recipient_id, deposit + ed); + + let capacity = Configuration::::config().hrmp_channel_max_capacity; + let message_size = Configuration::::config().hrmp_channel_max_message_size; + }: _(sender_origin, recipient_id, capacity, message_size) + verify { + assert_last_event::( + Event::::OpenChannelRequested(sender_id, recipient_id, capacity, message_size).into() + ); + } + + hrmp_accept_open_channel { + let [(sender, _), (recipient, recipient_origin)] = + establish_para_connection::(1, 2, ParachainSetupStep::Requested); + }: _(recipient_origin, sender) + verify { + assert_last_event::(Event::::OpenChannelAccepted(sender, recipient).into()); + } + + hrmp_close_channel { + let [(sender, sender_origin), (recipient, _)] = + establish_para_connection::(1, 2, ParachainSetupStep::Established); + let channel_id = HrmpChannelId { sender, recipient }; + }: _(sender_origin, channel_id.clone()) + verify { + assert_last_event::(Event::::ChannelClosed(sender, channel_id).into()); + } + + // NOTE: a single parachain should have the maximum number of allowed ingress and egress + // channels. + force_clean_hrmp { + // ingress channels to a single leaving parachain that need to be closed. + let i in 0 .. (HRMP_MAX_INBOUND_CHANNELS_BOUND - 1); + // egress channels to a single leaving parachain that need to be closed. + let e in 0 .. (HRMP_MAX_OUTBOUND_CHANNELS_BOUND - 1); + + // first, update the configs to support this many open channels... + assert_ok!( + Configuration::::set_hrmp_max_parachain_outbound_channels(frame_system::RawOrigin::Root.into(), e + 1) + ); + assert_ok!( + Configuration::::set_hrmp_max_parachain_inbound_channels(frame_system::RawOrigin::Root.into(), i + 1) + ); + // .. and enact it. + Configuration::::initializer_on_new_session(&Shared::::scheduled_session()); + + let config = Configuration::::config(); + let deposit: BalanceOf = config.hrmp_sender_deposit.unique_saturated_into(); + + let para: ParaId = 1u32.into(); + let para_origin: crate::Origin = 1u32.into(); + register_parachain_with_balance::(para, deposit); + T::Currency::make_free_balance_be(¶.into_account_truncating(), deposit * 256u32.into()); + + for ingress_para_id in 0..i { + // establish ingress channels to `para`. + let ingress_para_id = ingress_para_id + PREFIX_0; + let _ = establish_para_connection::(ingress_para_id, para.into(), ParachainSetupStep::Established); + } + + // nothing should be left unprocessed. + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default(), 0); + + for egress_para_id in 0..e { + // establish egress channels to `para`. + let egress_para_id = egress_para_id + PREFIX_1; + let _ = establish_para_connection::(para.into(), egress_para_id, ParachainSetupStep::Established); + } + + // nothing should be left unprocessed. + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default(), 0); + + // all in all, we have created this many channels. + assert_eq!(HrmpChannels::::iter().count() as u32, i + e); + }: _(frame_system::Origin::::Root, para, i, e) verify { + // all in all, all of them must be gone by now. + assert_eq!(HrmpChannels::::iter().count() as u32, 0); + // borrow this function from the tests to make sure state is clear, given that we do a lot + // of out-of-ordinary ops here. + Hrmp::::assert_storage_consistency_exhaustive(); + } + + force_process_hrmp_open { + // number of channels that need to be processed. Worse case is an N-M relation: unique + // sender and recipients for all channels. + let c in 0 .. MAX_UNIQUE_CHANNELS; + + for id in 0 .. c { + let _ = establish_para_connection::(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Accepted); + } + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, c); + }: _(frame_system::Origin::::Root, c) + verify { + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, 0); + } + + force_process_hrmp_close { + // number of channels that need to be processed. Worse case is an N-M relation: unique + // sender and recipients for all channels. + let c in 0 .. MAX_UNIQUE_CHANNELS; + + for id in 0 .. c { + let _ = establish_para_connection::(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::CloseRequested); + } + + assert_eq!(HrmpCloseChannelRequestsList::::decode_len().unwrap_or_default() as u32, c); + }: _(frame_system::Origin::::Root, c) + verify { + assert_eq!(HrmpCloseChannelRequestsList::::decode_len().unwrap_or_default() as u32, 0); + } + + hrmp_cancel_open_request { + // number of items already existing in the `HrmpOpenChannelRequestsList`, other than the + // one that we remove. + let c in 0 .. MAX_UNIQUE_CHANNELS; + + for id in 0 .. c { + let _ = establish_para_connection::(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Requested); + } + + let [(sender, sender_origin), (recipient, _)] = + establish_para_connection::(1, 2, ParachainSetupStep::Requested); + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, c + 1); + let channel_id = HrmpChannelId { sender, recipient }; + }: _(sender_origin, channel_id, c + 1) + verify { + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, c); + } + + // worse case will be `n` parachain channel requests, where in all of them either the sender or + // the recipient need to be cleaned. This enforces the deposit of at least one to be processed. + // No code path for triggering two deposit process exists. + clean_open_channel_requests { + let c in 0 .. MAX_UNIQUE_CHANNELS; + + for id in 0 .. c { + let _ = establish_para_connection::(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Requested); + } + + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, c); + let outgoing = (0..c).map(|id| (id + PREFIX_1).into()).collect::>(); + let config = Configuration::::config(); + }: { + Hrmp::::clean_open_channel_requests(&config, &outgoing); + } verify { + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, 0); + } + + force_open_hrmp_channel { + let sender_id: ParaId = 1u32.into(); + let sender_origin: crate::Origin = 1u32.into(); + let recipient_id: ParaId = 2u32.into(); + + // make sure para is registered, and has enough balance. + let ed = T::Currency::minimum_balance(); + let sender_deposit: BalanceOf = + Configuration::::config().hrmp_sender_deposit.unique_saturated_into(); + let recipient_deposit: BalanceOf = + Configuration::::config().hrmp_recipient_deposit.unique_saturated_into(); + register_parachain_with_balance::(sender_id, sender_deposit + ed); + register_parachain_with_balance::(recipient_id, recipient_deposit + ed); + + let capacity = Configuration::::config().hrmp_channel_max_capacity; + let message_size = Configuration::::config().hrmp_channel_max_message_size; + + // Weight parameter only accepts `u32`, `0` and `1` used to represent `false` and `true`, + // respectively. + let c = [0, 1]; + let channel_id = HrmpChannelId { sender: sender_id, recipient: recipient_id }; + for channels_to_close in c { + if channels_to_close == 1 { + // this will consume more weight if a channel _request_ already exists, because it + // will need to clear the request. + assert_ok!(Hrmp::::hrmp_init_open_channel( + sender_origin.clone().into(), + recipient_id, + capacity, + message_size + )); + assert!(HrmpOpenChannelRequests::::get(&channel_id).is_some()); + } else { + if HrmpOpenChannelRequests::::get(&channel_id).is_some() { + assert_ok!(Hrmp::::hrmp_cancel_open_request( + sender_origin.clone().into(), + channel_id.clone(), + MAX_UNIQUE_CHANNELS, + )); + } + assert!(HrmpOpenChannelRequests::::get(&channel_id).is_none()); + } + } + + // but the _channel_ should not exist + assert!(HrmpChannels::::get(&channel_id).is_none()); + }: _(frame_system::Origin::::Root, sender_id, recipient_id, capacity, message_size) + verify { + assert_last_event::( + Event::::HrmpChannelForceOpened(sender_id, recipient_id, capacity, message_size).into() + ); + } +} + +frame_benchmarking::impl_benchmark_test_suite!( + Hrmp, + crate::mock::new_test_ext(crate::hrmp::tests::GenesisConfigBuilder::default().build()), + crate::mock::Test +); diff --git a/polkadot/runtime/parachains/src/hrmp/tests.rs b/polkadot/runtime/parachains/src/hrmp/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..8cfaf48d10ef7f688ef37a4fb3a12182a7e06c13 --- /dev/null +++ b/polkadot/runtime/parachains/src/hrmp/tests.rs @@ -0,0 +1,719 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::mock::{ + deregister_parachain, new_test_ext, register_parachain, register_parachain_with_balance, + Configuration, Hrmp, MockGenesisConfig, Paras, ParasShared, RuntimeEvent as MockEvent, + RuntimeOrigin, System, Test, +}; +use frame_support::assert_noop; +use primitives::BlockNumber; +use std::collections::BTreeMap; + +pub(crate) fn run_to_block(to: BlockNumber, new_session: Option>) { + let config = Configuration::config(); + while System::block_number() < to { + let b = System::block_number(); + + // NOTE: this is in reverse initialization order. + Hrmp::initializer_finalize(); + Paras::initializer_finalize(b); + ParasShared::initializer_finalize(); + + if new_session.as_ref().map_or(false, |v| v.contains(&(b + 1))) { + let notification = crate::initializer::SessionChangeNotification { + prev_config: config.clone(), + new_config: config.clone(), + session_index: ParasShared::session_index() + 1, + ..Default::default() + }; + + // NOTE: this is in initialization order. + ParasShared::initializer_on_new_session( + notification.session_index, + notification.random_seed, + ¬ification.new_config, + notification.validators.clone(), + ); + let outgoing_paras = Paras::initializer_on_new_session(¬ification); + Hrmp::initializer_on_new_session(¬ification, &outgoing_paras); + } + + System::on_finalize(b); + + System::on_initialize(b + 1); + System::set_block_number(b + 1); + + // NOTE: this is in initialization order. + ParasShared::initializer_initialize(b + 1); + Paras::initializer_initialize(b + 1); + Hrmp::initializer_initialize(b + 1); + } +} + +#[derive(Debug)] +pub(super) struct GenesisConfigBuilder { + hrmp_channel_max_capacity: u32, + hrmp_channel_max_message_size: u32, + hrmp_max_paras_outbound_channels: u32, + hrmp_max_paras_inbound_channels: u32, + hrmp_max_message_num_per_candidate: u32, + hrmp_channel_max_total_size: u32, + hrmp_sender_deposit: Balance, + hrmp_recipient_deposit: Balance, +} + +impl Default for GenesisConfigBuilder { + fn default() -> Self { + Self { + hrmp_channel_max_capacity: 2, + hrmp_channel_max_message_size: 8, + hrmp_max_paras_outbound_channels: 2, + hrmp_max_paras_inbound_channels: 2, + hrmp_max_message_num_per_candidate: 2, + hrmp_channel_max_total_size: 16, + hrmp_sender_deposit: 100, + hrmp_recipient_deposit: 100, + } + } +} + +impl GenesisConfigBuilder { + pub(super) fn build(self) -> crate::mock::MockGenesisConfig { + let mut genesis = default_genesis_config(); + let config = &mut genesis.configuration.config; + config.hrmp_channel_max_capacity = self.hrmp_channel_max_capacity; + config.hrmp_channel_max_message_size = self.hrmp_channel_max_message_size; + config.hrmp_max_parachain_outbound_channels = self.hrmp_max_paras_outbound_channels; + config.hrmp_max_parachain_inbound_channels = self.hrmp_max_paras_inbound_channels; + config.hrmp_max_message_num_per_candidate = self.hrmp_max_message_num_per_candidate; + config.hrmp_channel_max_total_size = self.hrmp_channel_max_total_size; + config.hrmp_sender_deposit = self.hrmp_sender_deposit; + config.hrmp_recipient_deposit = self.hrmp_recipient_deposit; + genesis + } +} + +fn default_genesis_config() -> MockGenesisConfig { + MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: crate::configuration::HostConfiguration { + max_downward_message_size: 1024, + ..Default::default() + }, + }, + ..Default::default() + } +} + +fn channel_exists(sender: ParaId, recipient: ParaId) -> bool { + HrmpChannels::::get(&HrmpChannelId { sender, recipient }).is_some() +} + +#[test] +fn empty_state_consistent_state() { + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + Hrmp::assert_storage_consistency_exhaustive(); + }); +} + +#[test] +fn open_channel_works() { + let para_a = 1.into(); + let para_a_origin: crate::Origin = 1.into(); + let para_b = 3.into(); + let para_b_origin: crate::Origin = 3.into(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + // We need both A & B to be registered and alive parachains. + register_parachain(para_a); + register_parachain(para_b); + + run_to_block(5, Some(vec![4, 5])); + Hrmp::hrmp_init_open_channel(para_a_origin.into(), para_b, 2, 8).unwrap(); + Hrmp::assert_storage_consistency_exhaustive(); + assert!(System::events().iter().any(|record| record.event == + MockEvent::Hrmp(Event::OpenChannelRequested(para_a, para_b, 2, 8)))); + + Hrmp::hrmp_accept_open_channel(para_b_origin.into(), para_a).unwrap(); + Hrmp::assert_storage_consistency_exhaustive(); + assert!(System::events() + .iter() + .any(|record| record.event == + MockEvent::Hrmp(Event::OpenChannelAccepted(para_a, para_b)))); + + // Advance to a block 6, but without session change. That means that the channel has + // not been created yet. + run_to_block(6, None); + assert!(!channel_exists(para_a, para_b)); + Hrmp::assert_storage_consistency_exhaustive(); + + // Now let the session change happen and thus open the channel. + run_to_block(8, Some(vec![8])); + assert!(channel_exists(para_a, para_b)); + }); +} + +#[test] +fn force_open_channel_works() { + let para_a = 1.into(); + let para_b = 3.into(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + // We need both A & B to be registered and live parachains. + register_parachain(para_a); + register_parachain(para_b); + + run_to_block(5, Some(vec![4, 5])); + Hrmp::force_open_hrmp_channel(RuntimeOrigin::root(), para_a, para_b, 2, 8).unwrap(); + Hrmp::assert_storage_consistency_exhaustive(); + assert!(System::events().iter().any(|record| record.event == + MockEvent::Hrmp(Event::HrmpChannelForceOpened(para_a, para_b, 2, 8)))); + + // Advance to a block 6, but without session change. That means that the channel has + // not been created yet. + run_to_block(6, None); + assert!(!channel_exists(para_a, para_b)); + Hrmp::assert_storage_consistency_exhaustive(); + + // Now let the session change happen and thus open the channel. + run_to_block(8, Some(vec![8])); + assert!(channel_exists(para_a, para_b)); + }); +} + +#[test] +fn force_open_channel_works_with_existing_request() { + let para_a = 1.into(); + let para_a_origin: crate::Origin = 1.into(); + let para_b = 3.into(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + // We need both A & B to be registered and live parachains. + register_parachain(para_a); + register_parachain(para_b); + + // Request a channel from `a` to `b`. + run_to_block(3, Some(vec![2, 3])); + Hrmp::hrmp_init_open_channel(para_a_origin.into(), para_b, 2, 8).unwrap(); + Hrmp::assert_storage_consistency_exhaustive(); + assert!(System::events().iter().any(|record| record.event == + MockEvent::Hrmp(Event::OpenChannelRequested(para_a, para_b, 2, 8)))); + + run_to_block(5, Some(vec![4, 5])); + // the request exists, but no channel. + assert!(HrmpOpenChannelRequests::::get(&HrmpChannelId { + sender: para_a, + recipient: para_b + }) + .is_some()); + assert!(!channel_exists(para_a, para_b)); + // now force open it. + Hrmp::force_open_hrmp_channel(RuntimeOrigin::root(), para_a, para_b, 2, 8).unwrap(); + Hrmp::assert_storage_consistency_exhaustive(); + assert!(System::events().iter().any(|record| record.event == + MockEvent::Hrmp(Event::HrmpChannelForceOpened(para_a, para_b, 2, 8)))); + + // Advance to a block 6, but without session change. That means that the channel has + // not been created yet. + run_to_block(6, None); + assert!(!channel_exists(para_a, para_b)); + Hrmp::assert_storage_consistency_exhaustive(); + + // Now let the session change happen and thus open the channel. + run_to_block(8, Some(vec![8])); + assert!(channel_exists(para_a, para_b)); + }); +} + +#[test] +fn close_channel_works() { + let para_a = 5.into(); + let para_b = 2.into(); + let para_b_origin: crate::Origin = 2.into(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + register_parachain(para_a); + register_parachain(para_b); + + run_to_block(5, Some(vec![4, 5])); + Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); + Hrmp::accept_open_channel(para_b, para_a).unwrap(); + + run_to_block(6, Some(vec![6])); + assert!(channel_exists(para_a, para_b)); + + // Close the channel. The effect is not immediate, but rather deferred to the next + // session change. + let channel_id = HrmpChannelId { sender: para_a, recipient: para_b }; + Hrmp::hrmp_close_channel(para_b_origin.into(), channel_id.clone()).unwrap(); + assert!(channel_exists(para_a, para_b)); + Hrmp::assert_storage_consistency_exhaustive(); + + // After the session change the channel should be closed. + run_to_block(8, Some(vec![8])); + assert!(!channel_exists(para_a, para_b)); + Hrmp::assert_storage_consistency_exhaustive(); + assert!(System::events().iter().any(|record| record.event == + MockEvent::Hrmp(Event::ChannelClosed(para_b, channel_id.clone())))); + }); +} + +#[test] +fn send_recv_messages() { + let para_a = 32.into(); + let para_b = 64.into(); + + let mut genesis = GenesisConfigBuilder::default(); + genesis.hrmp_channel_max_message_size = 20; + genesis.hrmp_channel_max_total_size = 20; + new_test_ext(genesis.build()).execute_with(|| { + register_parachain(para_a); + register_parachain(para_b); + + run_to_block(5, Some(vec![4, 5])); + Hrmp::init_open_channel(para_a, para_b, 2, 20).unwrap(); + Hrmp::accept_open_channel(para_b, para_a).unwrap(); + + // On Block 6: + // A sends a message to B + run_to_block(6, Some(vec![6])); + assert!(channel_exists(para_a, para_b)); + let msgs: HorizontalMessages = + vec![OutboundHrmpMessage { recipient: para_b, data: b"this is an emergency".to_vec() }] + .try_into() + .unwrap(); + let config = Configuration::config(); + assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok()); + let _ = Hrmp::queue_outbound_hrmp(para_a, msgs); + Hrmp::assert_storage_consistency_exhaustive(); + + // On Block 7: + // B receives the message sent by A. B sets the watermark to 6. + run_to_block(7, None); + assert!(Hrmp::check_hrmp_watermark(para_b, 7, 6).is_ok()); + let _ = Hrmp::prune_hrmp(para_b, 6); + Hrmp::assert_storage_consistency_exhaustive(); + }); +} + +#[test] +fn hrmp_mqc_head_fixture() { + let para_a = 2000.into(); + let para_b = 2024.into(); + + let mut genesis = GenesisConfigBuilder::default(); + genesis.hrmp_channel_max_message_size = 20; + genesis.hrmp_channel_max_total_size = 20; + new_test_ext(genesis.build()).execute_with(|| { + register_parachain(para_a); + register_parachain(para_b); + + run_to_block(2, Some(vec![1, 2])); + Hrmp::init_open_channel(para_a, para_b, 2, 20).unwrap(); + Hrmp::accept_open_channel(para_b, para_a).unwrap(); + + run_to_block(3, Some(vec![3])); + let _ = Hrmp::queue_outbound_hrmp( + para_a, + vec![OutboundHrmpMessage { recipient: para_b, data: vec![1, 2, 3] }] + .try_into() + .unwrap(), + ); + + run_to_block(4, None); + let _ = Hrmp::queue_outbound_hrmp( + para_a, + vec![OutboundHrmpMessage { recipient: para_b, data: vec![4, 5, 6] }] + .try_into() + .unwrap(), + ); + + assert_eq!( + Hrmp::hrmp_mqc_heads(para_b), + vec![( + para_a, + hex_literal::hex![ + "a964fd3b4f3d3ce92a0e25e576b87590d92bb5cb7031909c7f29050e1f04a375" + ] + .into() + ),], + ); + }); +} + +#[test] +fn accept_incoming_request_and_offboard() { + let para_a = 32.into(); + let para_b = 64.into(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + register_parachain(para_a); + register_parachain(para_b); + + run_to_block(5, Some(vec![4, 5])); + Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); + Hrmp::accept_open_channel(para_b, para_a).unwrap(); + deregister_parachain(para_a); + + // On Block 7: 2x session change. The channel should not be created. + run_to_block(7, Some(vec![6, 7])); + assert!(!Paras::is_valid_para(para_a)); + assert!(!channel_exists(para_a, para_b)); + Hrmp::assert_storage_consistency_exhaustive(); + }); +} + +#[test] +fn check_sent_messages() { + let para_a = 32.into(); + let para_b = 64.into(); + let para_c = 97.into(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + register_parachain(para_a); + register_parachain(para_b); + register_parachain(para_c); + + run_to_block(5, Some(vec![4, 5])); + + // Open two channels to the same receiver, b: + // a -> b, c -> b + Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); + Hrmp::accept_open_channel(para_b, para_a).unwrap(); + Hrmp::init_open_channel(para_c, para_b, 2, 8).unwrap(); + Hrmp::accept_open_channel(para_b, para_c).unwrap(); + + // On Block 6: session change. + run_to_block(6, Some(vec![6])); + assert!(Paras::is_valid_para(para_a)); + + let msgs: HorizontalMessages = + vec![OutboundHrmpMessage { recipient: para_b, data: b"knock".to_vec() }] + .try_into() + .unwrap(); + let config = Configuration::config(); + assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok()); + let _ = Hrmp::queue_outbound_hrmp(para_a, msgs.clone()); + + // Verify that the sent messages are there and that also the empty channels are present. + let mqc_heads = Hrmp::hrmp_mqc_heads(para_b); + let contents = Hrmp::inbound_hrmp_channels_contents(para_b); + assert_eq!( + contents, + vec![ + (para_a, vec![InboundHrmpMessage { sent_at: 6, data: b"knock".to_vec() }]), + (para_c, vec![]) + ] + .into_iter() + .collect::>(), + ); + assert_eq!( + mqc_heads, + vec![ + ( + para_a, + hex_literal::hex!( + "3bba6404e59c91f51deb2ae78f1273ebe75896850713e13f8c0eba4b0996c483" + ) + .into() + ), + (para_c, Default::default()) + ], + ); + + Hrmp::assert_storage_consistency_exhaustive(); + }); +} + +#[test] +fn verify_externally_accessible() { + use primitives::{well_known_keys, AbridgedHrmpChannel}; + + let para_a = 20.into(); + let para_b = 21.into(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + // Register two parachains, wait until a session change, then initiate channel open + // request and accept that, and finally wait until the next session. + register_parachain(para_a); + register_parachain(para_b); + run_to_block(5, Some(vec![4, 5])); + Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); + Hrmp::accept_open_channel(para_b, para_a).unwrap(); + run_to_block(8, Some(vec![8])); + + // Here we have a channel a->b opened. + // + // Try to obtain this channel from the storage and + // decode it into the abridged version. + assert!(channel_exists(para_a, para_b)); + let raw_hrmp_channel = + sp_io::storage::get(&well_known_keys::hrmp_channels(HrmpChannelId { + sender: para_a, + recipient: para_b, + })) + .expect("the channel exists and we must be able to get it through well known keys"); + let abridged_hrmp_channel = AbridgedHrmpChannel::decode(&mut &raw_hrmp_channel[..]) + .expect("HrmpChannel should be decodable as AbridgedHrmpChannel"); + + assert_eq!( + abridged_hrmp_channel, + AbridgedHrmpChannel { + max_capacity: 2, + max_total_size: 16, + max_message_size: 8, + msg_count: 0, + total_size: 0, + mqc_head: None, + }, + ); + + let raw_ingress_index = + sp_io::storage::get(&well_known_keys::hrmp_ingress_channel_index(para_b)) + .expect("the ingress index must be present for para_b"); + let ingress_index = >::decode(&mut &raw_ingress_index[..]) + .expect("ingress indexx should be decodable as a list of para ids"); + assert_eq!(ingress_index, vec![para_a]); + + // Now, verify that we can access and decode the egress index. + let raw_egress_index = + sp_io::storage::get(&well_known_keys::hrmp_egress_channel_index(para_a)) + .expect("the egress index must be present for para_a"); + let egress_index = >::decode(&mut &raw_egress_index[..]) + .expect("egress index should be decodable as a list of para ids"); + assert_eq!(egress_index, vec![para_b]); + }); +} + +#[test] +fn charging_deposits() { + let para_a = 32.into(); + let para_b = 64.into(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + register_parachain_with_balance(para_a, 0); + register_parachain(para_b); + run_to_block(5, Some(vec![4, 5])); + + assert_noop!( + Hrmp::init_open_channel(para_a, para_b, 2, 8), + pallet_balances::Error::::InsufficientBalance + ); + }); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + register_parachain(para_a); + register_parachain_with_balance(para_b, 0); + run_to_block(5, Some(vec![4, 5])); + + Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); + + assert_noop!( + Hrmp::accept_open_channel(para_b, para_a), + pallet_balances::Error::::InsufficientBalance + ); + }); +} + +#[test] +fn refund_deposit_on_normal_closure() { + let para_a = 32.into(); + let para_b = 64.into(); + + let mut genesis = GenesisConfigBuilder::default(); + genesis.hrmp_sender_deposit = 20; + genesis.hrmp_recipient_deposit = 15; + new_test_ext(genesis.build()).execute_with(|| { + // Register two parachains funded with different amounts of funds and arrange a channel. + register_parachain_with_balance(para_a, 100); + register_parachain_with_balance(para_b, 110); + run_to_block(5, Some(vec![4, 5])); + Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); + Hrmp::accept_open_channel(para_b, para_a).unwrap(); + assert_eq!(::Currency::free_balance(¶_a.into_account_truncating()), 80); + assert_eq!(::Currency::free_balance(¶_b.into_account_truncating()), 95); + run_to_block(8, Some(vec![8])); + + // Now, we close the channel and wait until the next session. + Hrmp::close_channel(para_b, HrmpChannelId { sender: para_a, recipient: para_b }).unwrap(); + run_to_block(10, Some(vec![10])); + assert_eq!( + ::Currency::free_balance(¶_a.into_account_truncating()), + 100 + ); + assert_eq!( + ::Currency::free_balance(¶_b.into_account_truncating()), + 110 + ); + }); +} + +#[test] +fn refund_deposit_on_offboarding() { + let para_a = 32.into(); + let para_b = 64.into(); + + let mut genesis = GenesisConfigBuilder::default(); + genesis.hrmp_sender_deposit = 20; + genesis.hrmp_recipient_deposit = 15; + new_test_ext(genesis.build()).execute_with(|| { + // Register two parachains and open a channel between them. + register_parachain_with_balance(para_a, 100); + register_parachain_with_balance(para_b, 110); + run_to_block(5, Some(vec![4, 5])); + Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); + Hrmp::accept_open_channel(para_b, para_a).unwrap(); + assert_eq!(::Currency::free_balance(¶_a.into_account_truncating()), 80); + assert_eq!(::Currency::free_balance(¶_b.into_account_truncating()), 95); + run_to_block(8, Some(vec![8])); + assert!(channel_exists(para_a, para_b)); + + // Then deregister one parachain. + deregister_parachain(para_a); + run_to_block(10, Some(vec![9, 10])); + + // The channel should be removed. + assert!(!Paras::is_valid_para(para_a)); + assert!(!channel_exists(para_a, para_b)); + Hrmp::assert_storage_consistency_exhaustive(); + + assert_eq!( + ::Currency::free_balance(¶_a.into_account_truncating()), + 100 + ); + assert_eq!( + ::Currency::free_balance(¶_b.into_account_truncating()), + 110 + ); + }); +} + +#[test] +fn no_dangling_open_requests() { + let para_a = 32.into(); + let para_b = 64.into(); + + let mut genesis = GenesisConfigBuilder::default(); + genesis.hrmp_sender_deposit = 20; + genesis.hrmp_recipient_deposit = 15; + new_test_ext(genesis.build()).execute_with(|| { + // Register two parachains and open a channel between them. + register_parachain_with_balance(para_a, 100); + register_parachain_with_balance(para_b, 110); + run_to_block(5, Some(vec![4, 5])); + + // Start opening a channel a->b + Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); + assert_eq!(::Currency::free_balance(¶_a.into_account_truncating()), 80); + + // Then deregister one parachain, but don't wait two sessions until it takes effect. + // Instead, `para_b` will confirm the request, which will take place the same time + // the offboarding should happen. + deregister_parachain(para_a); + run_to_block(9, Some(vec![9])); + Hrmp::accept_open_channel(para_b, para_a).unwrap(); + assert_eq!(::Currency::free_balance(¶_b.into_account_truncating()), 95); + assert!(!channel_exists(para_a, para_b)); + run_to_block(10, Some(vec![10])); + + // The outcome we expect is `para_b` should receive the refund. + assert_eq!( + ::Currency::free_balance(¶_b.into_account_truncating()), + 110 + ); + assert!(!channel_exists(para_a, para_b)); + Hrmp::assert_storage_consistency_exhaustive(); + }); +} + +#[test] +fn cancel_pending_open_channel_request() { + let para_a = 32.into(); + let para_b = 64.into(); + + let mut genesis = GenesisConfigBuilder::default(); + genesis.hrmp_sender_deposit = 20; + genesis.hrmp_recipient_deposit = 15; + new_test_ext(genesis.build()).execute_with(|| { + // Register two parachains and open a channel between them. + register_parachain_with_balance(para_a, 100); + register_parachain_with_balance(para_b, 110); + run_to_block(5, Some(vec![4, 5])); + + // Start opening a channel a->b + Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); + assert_eq!(::Currency::free_balance(¶_a.into_account_truncating()), 80); + + // Cancel opening the channel + Hrmp::cancel_open_request(para_a, HrmpChannelId { sender: para_a, recipient: para_b }) + .unwrap(); + assert_eq!( + ::Currency::free_balance(¶_a.into_account_truncating()), + 100 + ); + + run_to_block(10, Some(vec![10])); + assert!(!channel_exists(para_a, para_b)); + Hrmp::assert_storage_consistency_exhaustive(); + }); +} + +#[test] +fn watermark_maxed_out_at_relay_parent() { + let para_a = 32.into(); + let para_b = 64.into(); + + let mut genesis = GenesisConfigBuilder::default(); + genesis.hrmp_channel_max_message_size = 20; + genesis.hrmp_channel_max_total_size = 20; + new_test_ext(genesis.build()).execute_with(|| { + register_parachain(para_a); + register_parachain(para_b); + + run_to_block(5, Some(vec![4, 5])); + Hrmp::init_open_channel(para_a, para_b, 2, 20).unwrap(); + Hrmp::accept_open_channel(para_b, para_a).unwrap(); + + // On Block 6: + // A sends a message to B + run_to_block(6, Some(vec![6])); + assert!(channel_exists(para_a, para_b)); + let msgs: HorizontalMessages = + vec![OutboundHrmpMessage { recipient: para_b, data: b"this is an emergency".to_vec() }] + .try_into() + .unwrap(); + let config = Configuration::config(); + assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok()); + let _ = Hrmp::queue_outbound_hrmp(para_a, msgs); + Hrmp::assert_storage_consistency_exhaustive(); + + // On block 8: + // B receives the message sent by A. B sets the watermark to 7. + run_to_block(8, None); + assert!(Hrmp::check_hrmp_watermark(para_b, 7, 7).is_ok()); + let _ = Hrmp::prune_hrmp(para_b, 7); + Hrmp::assert_storage_consistency_exhaustive(); + + // On block 9: + // B includes a candidate with the same relay parent as before. + run_to_block(9, None); + assert!(Hrmp::check_hrmp_watermark(para_b, 7, 7).is_ok()); + let _ = Hrmp::prune_hrmp(para_b, 7); + Hrmp::assert_storage_consistency_exhaustive(); + }); +} diff --git a/polkadot/runtime/parachains/src/inclusion/benchmarking.rs b/polkadot/runtime/parachains/src/inclusion/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..0471c0c3b2bf8795e19ce5c522a961361f4d38b8 --- /dev/null +++ b/polkadot/runtime/parachains/src/inclusion/benchmarking.rs @@ -0,0 +1,41 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use frame_benchmarking::benchmarks; +use pallet_message_queue as mq; + +benchmarks! { + where_clause { + where + T: mq::Config, + } + + receive_upward_messages { + let i in 1 .. 1000; + + let max_len = mq::MaxMessageLenOf::::get() as usize; + let para = 42u32.into(); // not especially important. + let upward_messages = vec![vec![0; max_len]; i as usize]; + Pallet::::receive_upward_messages(para, vec![vec![0; max_len]; 1].as_slice()); + }: { Pallet::::receive_upward_messages(para, upward_messages.as_slice()) } + + impl_benchmark_test_suite!( + Pallet, + crate::mock::new_test_ext(Default::default()), + crate::mock::Test + ); +} diff --git a/polkadot/runtime/parachains/src/inclusion/mod.rs b/polkadot/runtime/parachains/src/inclusion/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e60aac0080cfca6d53000441958d1f15bada1265 --- /dev/null +++ b/polkadot/runtime/parachains/src/inclusion/mod.rs @@ -0,0 +1,1357 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The inclusion pallet is responsible for inclusion and availability of scheduled parachains. +//! +//! It is responsible for carrying candidates from being backable to being backed, and then from +//! backed to included. + +use crate::{ + configuration::{self, HostConfiguration}, + disputes, dmp, hrmp, paras, + scheduler::{self, common::CoreAssignment}, + shared::{self, AllowedRelayParentsTracker}, +}; +use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; +use frame_support::{ + defensive, + pallet_prelude::*, + traits::{Defensive, EnqueueMessage}, + BoundedSlice, +}; +use frame_system::pallet_prelude::*; +use pallet_message_queue::OnQueueChanged; +use parity_scale_codec::{Decode, Encode}; +use primitives::{ + supermajority_threshold, well_known_keys, AvailabilityBitfield, BackedCandidate, + CandidateCommitments, CandidateDescriptor, CandidateHash, CandidateReceipt, + CommittedCandidateReceipt, CoreIndex, GroupIndex, Hash, HeadData, Id as ParaId, + SignedAvailabilityBitfields, SigningContext, UpwardMessage, ValidatorId, ValidatorIndex, + ValidityAttestation, +}; +use scale_info::TypeInfo; +use sp_runtime::{traits::One, DispatchError, SaturatedConversion, Saturating}; +#[cfg(feature = "std")] +use sp_std::fmt; +use sp_std::{collections::btree_set::BTreeSet, prelude::*}; + +pub use pallet::*; + +#[cfg(test)] +pub(crate) mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +pub trait WeightInfo { + fn receive_upward_messages(i: u32) -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn receive_upward_messages(_: u32) -> Weight { + Weight::MAX + } +} + +impl WeightInfo for () { + fn receive_upward_messages(_: u32) -> Weight { + Weight::zero() + } +} + +/// Maximum value that `config.max_upward_message_size` can be set to. +/// +/// This is used for benchmarking sanely bounding relevant storage items. It is expected from the +/// `configuration` pallet to check these values before setting. +pub const MAX_UPWARD_MESSAGE_SIZE_BOUND: u32 = 128 * 1024; + +/// A bitfield signed by a validator indicating that it is keeping its piece of the erasure-coding +/// for any backed candidates referred to by a `1` bit available. +/// +/// The bitfield's signature should be checked at the point of submission. Afterwards it can be +/// dropped. +#[derive(Encode, Decode, TypeInfo)] +#[cfg_attr(test, derive(Debug))] +pub struct AvailabilityBitfieldRecord { + bitfield: AvailabilityBitfield, // one bit per core. + submitted_at: N, // for accounting, as meaning of bits may change over time. +} + +/// A backed candidate pending availability. +#[derive(Encode, Decode, PartialEq, TypeInfo)] +#[cfg_attr(test, derive(Debug))] +pub struct CandidatePendingAvailability { + /// The availability core this is assigned to. + core: CoreIndex, + /// The candidate hash. + hash: CandidateHash, + /// The candidate descriptor. + descriptor: CandidateDescriptor, + /// The received availability votes. One bit per validator. + availability_votes: BitVec, + /// The backers of the candidate pending availability. + backers: BitVec, + /// The block number of the relay-parent of the receipt. + relay_parent_number: N, + /// The block number of the relay-chain block this was backed in. + backed_in_number: N, + /// The group index backing this block. + backing_group: GroupIndex, +} + +impl CandidatePendingAvailability { + /// Get the availability votes on the candidate. + pub(crate) fn availability_votes(&self) -> &BitVec { + &self.availability_votes + } + + /// Get the relay-chain block number this was backed in. + pub(crate) fn backed_in_number(&self) -> &N { + &self.backed_in_number + } + + /// Get the core index. + pub(crate) fn core_occupied(&self) -> CoreIndex { + self.core + } + + /// Get the candidate hash. + pub(crate) fn candidate_hash(&self) -> CandidateHash { + self.hash + } + + /// Get the candidate descriptor. + pub(crate) fn candidate_descriptor(&self) -> &CandidateDescriptor { + &self.descriptor + } + + /// Get the candidate's relay parent's number. + pub(crate) fn relay_parent_number(&self) -> N + where + N: Clone, + { + self.relay_parent_number.clone() + } + + #[cfg(any(feature = "runtime-benchmarks", test))] + pub(crate) fn new( + core: CoreIndex, + hash: CandidateHash, + descriptor: CandidateDescriptor, + availability_votes: BitVec, + backers: BitVec, + relay_parent_number: N, + backed_in_number: N, + backing_group: GroupIndex, + ) -> Self { + Self { + core, + hash, + descriptor, + availability_votes, + backers, + relay_parent_number, + backed_in_number, + backing_group, + } + } +} + +/// A hook for applying validator rewards +pub trait RewardValidators { + // Reward the validators with the given indices for issuing backing statements. + fn reward_backing(validators: impl IntoIterator); + // Reward the validators with the given indices for issuing availability bitfields. + // Validators are sent to this hook when they have contributed to the availability + // of a candidate by setting a bit in their bitfield. + fn reward_bitfields(validators: impl IntoIterator); +} + +/// Helper return type for `process_candidates`. +#[derive(Encode, Decode, PartialEq, TypeInfo)] +#[cfg_attr(test, derive(Debug))] +pub(crate) struct ProcessedCandidates { + pub(crate) core_indices: Vec<(CoreIndex, ParaId)>, + pub(crate) candidate_receipt_with_backing_validator_indices: + Vec<(CandidateReceipt, Vec<(ValidatorIndex, ValidityAttestation)>)>, +} + +impl Default for ProcessedCandidates { + fn default() -> Self { + Self { + core_indices: Vec::new(), + candidate_receipt_with_backing_validator_indices: Vec::new(), + } + } +} + +/// Number of backing votes we need for a valid backing. +/// +/// WARNING: This check has to be kept in sync with the node side checks. +pub fn minimum_backing_votes(n_validators: usize) -> usize { + // For considerations on this value see: + // https://github.com/paritytech/polkadot/pull/1656#issuecomment-999734650 + // and + // https://github.com/paritytech/polkadot/issues/4386 + sp_std::cmp::min(n_validators, 2) +} + +/// Reads the footprint of queues for a specific origin type. +pub trait QueueFootprinter { + type Origin; + + fn message_count(origin: Self::Origin) -> u64; +} + +impl QueueFootprinter for () { + type Origin = UmpQueueId; + + fn message_count(_: Self::Origin) -> u64 { + 0 + } +} + +/// Aggregate message origin for the `MessageQueue` pallet. +/// +/// Can be extended to serve further use-cases besides just UMP. Is stored in storage, so any change +/// to existing values will require a migration. +#[derive(Encode, Decode, Clone, MaxEncodedLen, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub enum AggregateMessageOrigin { + /// Inbound upward message. + #[codec(index = 0)] + Ump(UmpQueueId), +} + +/// Identifies a UMP queue inside the `MessageQueue` pallet. +/// +/// It is written in verbose form since future variants like `Loopback` and `Bridged` are already +/// forseeable. +#[derive(Encode, Decode, Clone, MaxEncodedLen, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub enum UmpQueueId { + /// The message originated from this parachain. + #[codec(index = 0)] + Para(ParaId), +} + +#[cfg(feature = "runtime-benchmarks")] +impl From for AggregateMessageOrigin { + fn from(n: u32) -> Self { + // Some dummy for the benchmarks. + Self::Ump(UmpQueueId::Para(n.into())) + } +} + +/// The maximal length of a UMP message. +pub type MaxUmpMessageLenOf = + <::MessageQueue as EnqueueMessage>::MaxMessageLen; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: + frame_system::Config + + shared::Config + + paras::Config + + dmp::Config + + hrmp::Config + + configuration::Config + + scheduler::Config + { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type DisputesHandler: disputes::DisputesHandler>; + type RewardValidators: RewardValidators; + + /// The system message queue. + /// + /// The message queue provides general queueing and processing functionality. Currently it + /// replaces the old `UMP` dispatch queue. Other use-cases can be implemented as well by + /// adding new variants to `AggregateMessageOrigin`. + type MessageQueue: EnqueueMessage; + + /// Weight info for the calls of this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// A candidate was backed. `[candidate, head_data]` + CandidateBacked(CandidateReceipt, HeadData, CoreIndex, GroupIndex), + /// A candidate was included. `[candidate, head_data]` + CandidateIncluded(CandidateReceipt, HeadData, CoreIndex, GroupIndex), + /// A candidate timed out. `[candidate, head_data]` + CandidateTimedOut(CandidateReceipt, HeadData, CoreIndex), + /// Some upward messages have been received and will be processed. + UpwardMessagesReceived { from: ParaId, count: u32 }, + } + + #[pallet::error] + pub enum Error { + /// Validator indices are out of order or contains duplicates. + UnsortedOrDuplicateValidatorIndices, + /// Dispute statement sets are out of order or contain duplicates. + UnsortedOrDuplicateDisputeStatementSet, + /// Backed candidates are out of order (core index) or contain duplicates. + UnsortedOrDuplicateBackedCandidates, + /// A different relay parent was provided compared to the on-chain stored one. + UnexpectedRelayParent, + /// Availability bitfield has unexpected size. + WrongBitfieldSize, + /// Bitfield consists of zeros only. + BitfieldAllZeros, + /// Multiple bitfields submitted by same validator or validators out of order by index. + BitfieldDuplicateOrUnordered, + /// Validator index out of bounds. + ValidatorIndexOutOfBounds, + /// Invalid signature + InvalidBitfieldSignature, + /// Candidate submitted but para not scheduled. + UnscheduledCandidate, + /// Candidate scheduled despite pending candidate already existing for the para. + CandidateScheduledBeforeParaFree, + /// Scheduled cores out of order. + ScheduledOutOfOrder, + /// Head data exceeds the configured maximum. + HeadDataTooLarge, + /// Code upgrade prematurely. + PrematureCodeUpgrade, + /// Output code is too large + NewCodeTooLarge, + /// The candidate's relay-parent was not allowed. Either it was + /// not recent enough or it didn't advance based on the last parachain block. + DisallowedRelayParent, + /// Failed to compute group index for the core: either it's out of bounds + /// or the relay parent doesn't belong to the current session. + InvalidAssignment, + /// Invalid group index in core assignment. + InvalidGroupIndex, + /// Insufficient (non-majority) backing. + InsufficientBacking, + /// Invalid (bad signature, unknown validator, etc.) backing. + InvalidBacking, + /// Collator did not sign PoV. + NotCollatorSigned, + /// The validation data hash does not match expected. + ValidationDataHashMismatch, + /// The downward message queue is not processed correctly. + IncorrectDownwardMessageHandling, + /// At least one upward message sent does not pass the acceptance criteria. + InvalidUpwardMessages, + /// The candidate didn't follow the rules of HRMP watermark advancement. + HrmpWatermarkMishandling, + /// The HRMP messages sent by the candidate is not valid. + InvalidOutboundHrmp, + /// The validation code hash of the candidate is not valid. + InvalidValidationCodeHash, + /// The `para_head` hash in the candidate descriptor doesn't match the hash of the actual + /// para head in the commitments. + ParaHeadMismatch, + /// A bitfield that references a freed core, + /// either intentionally or as part of a concluded + /// invalid dispute. + BitfieldReferencesFreedCore, + } + + /// The latest bitfield for each validator, referred to by their index in the validator set. + #[pallet::storage] + pub(crate) type AvailabilityBitfields = + StorageMap<_, Twox64Concat, ValidatorIndex, AvailabilityBitfieldRecord>>; + + /// Candidates pending availability by `ParaId`. + #[pallet::storage] + pub(crate) type PendingAvailability = StorageMap< + _, + Twox64Concat, + ParaId, + CandidatePendingAvailability>, + >; + + /// The commitments of candidates pending availability, by `ParaId`. + #[pallet::storage] + pub(crate) type PendingAvailabilityCommitments = + StorageMap<_, Twox64Concat, ParaId, CandidateCommitments>; + + #[pallet::call] + impl Pallet {} +} + +const LOG_TARGET: &str = "runtime::inclusion"; + +/// The reason that a candidate's outputs were rejected for. +#[derive(derive_more::From)] +#[cfg_attr(feature = "std", derive(Debug))] +enum AcceptanceCheckErr { + HeadDataTooLarge, + /// Code upgrades are not permitted at the current time. + PrematureCodeUpgrade, + /// The new runtime blob is too large. + NewCodeTooLarge, + /// The candidate violated this DMP acceptance criteria. + ProcessedDownwardMessages(dmp::ProcessedDownwardMessagesAcceptanceErr), + /// The candidate violated this UMP acceptance criteria. + UpwardMessages(UmpAcceptanceCheckErr), + /// The candidate violated this HRMP watermark acceptance criteria. + HrmpWatermark(hrmp::HrmpWatermarkAcceptanceErr), + /// The candidate violated this outbound HRMP acceptance criteria. + OutboundHrmp(hrmp::OutboundHrmpAcceptanceErr), +} + +/// An error returned by [`check_upward_messages`] that indicates a violation of one of acceptance +/// criteria rules. +#[cfg_attr(test, derive(PartialEq))] +pub enum UmpAcceptanceCheckErr { + /// The maximal number of messages that can be submitted in one batch was exceeded. + MoreMessagesThanPermitted { sent: u32, permitted: u32 }, + /// The maximal size of a single message was exceeded. + MessageSize { idx: u32, msg_size: u32, max_size: u32 }, + /// The allowed number of messages in the queue was exceeded. + CapacityExceeded { count: u64, limit: u64 }, + /// The allowed combined message size in the queue was exceeded. + TotalSizeExceeded { total_size: u64, limit: u64 }, + /// A para-chain cannot send UMP messages while it is offboarding. + IsOffboarding, +} + +#[cfg(feature = "std")] +impl fmt::Debug for UmpAcceptanceCheckErr { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match *self { + UmpAcceptanceCheckErr::MoreMessagesThanPermitted { sent, permitted } => write!( + fmt, + "more upward messages than permitted by config ({} > {})", + sent, permitted, + ), + UmpAcceptanceCheckErr::MessageSize { idx, msg_size, max_size } => write!( + fmt, + "upward message idx {} larger than permitted by config ({} > {})", + idx, msg_size, max_size, + ), + UmpAcceptanceCheckErr::CapacityExceeded { count, limit } => write!( + fmt, + "the ump queue would have more items than permitted by config ({} > {})", + count, limit, + ), + UmpAcceptanceCheckErr::TotalSizeExceeded { total_size, limit } => write!( + fmt, + "the ump queue would have grown past the max size permitted by config ({} > {})", + total_size, limit, + ), + UmpAcceptanceCheckErr::IsOffboarding => + write!(fmt, "upward message rejected because the para is off-boarding",), + } + } +} + +impl Pallet { + /// Block initialization logic, called by initializer. + pub(crate) fn initializer_initialize(_now: BlockNumberFor) -> Weight { + Weight::zero() + } + + /// Block finalization logic, called by initializer. + pub(crate) fn initializer_finalize() {} + + /// Handle an incoming session change. + pub(crate) fn initializer_on_new_session( + _notification: &crate::initializer::SessionChangeNotification>, + outgoing_paras: &[ParaId], + ) { + // unlike most drain methods, drained elements are not cleared on `Drop` of the iterator + // and require consumption. + for _ in >::drain() {} + for _ in >::drain() {} + for _ in >::drain() {} + + Self::cleanup_outgoing_ump_dispatch_queues(outgoing_paras); + } + + pub(crate) fn cleanup_outgoing_ump_dispatch_queues(outgoing: &[ParaId]) { + for outgoing_para in outgoing { + Self::cleanup_outgoing_ump_dispatch_queue(*outgoing_para); + } + } + + pub(crate) fn cleanup_outgoing_ump_dispatch_queue(para: ParaId) { + T::MessageQueue::sweep_queue(AggregateMessageOrigin::Ump(UmpQueueId::Para(para))); + } + + /// Extract the freed cores based on cores that became available. + /// + /// Bitfields are expected to have been sanitized already. E.g. via `sanitize_bitfields`! + /// + /// Updates storage items `PendingAvailability` and `AvailabilityBitfields`. + /// + /// Returns a `Vec` of `CandidateHash`es and their respective `AvailabilityCore`s that became + /// available, and cores free. + pub(crate) fn update_pending_availability_and_get_freed_cores( + expected_bits: usize, + validators: &[ValidatorId], + signed_bitfields: SignedAvailabilityBitfields, + core_lookup: F, + ) -> Vec<(CoreIndex, CandidateHash)> + where + F: Fn(CoreIndex) -> Option, + { + let mut assigned_paras_record = (0..expected_bits) + .map(|bit_index| core_lookup(CoreIndex::from(bit_index as u32))) + .map(|opt_para_id| { + opt_para_id.map(|para_id| (para_id, PendingAvailability::::get(¶_id))) + }) + .collect::>(); + + let now = >::block_number(); + for (checked_bitfield, validator_index) in + signed_bitfields.into_iter().map(|signed_bitfield| { + let validator_idx = signed_bitfield.validator_index(); + let checked_bitfield = signed_bitfield.into_payload(); + (checked_bitfield, validator_idx) + }) { + for (bit_idx, _) in checked_bitfield.0.iter().enumerate().filter(|(_, is_av)| **is_av) { + let pending_availability = if let Some((_, pending_availability)) = + assigned_paras_record[bit_idx].as_mut() + { + pending_availability + } else { + // For honest validators, this happens in case of unoccupied cores, + // which in turn happens in case of a disputed candidate. + // A malicious one might include arbitrary indices, but they are represented + // by `None` values and will be sorted out in the next if case. + continue + }; + + // defensive check - this is constructed by loading the availability bitfield + // record, which is always `Some` if the core is occupied - that's why we're here. + let validator_index = validator_index.0 as usize; + if let Some(mut bit) = + pending_availability.as_mut().and_then(|candidate_pending_availability| { + candidate_pending_availability.availability_votes.get_mut(validator_index) + }) { + *bit = true; + } + } + + let record = + AvailabilityBitfieldRecord { bitfield: checked_bitfield, submitted_at: now }; + + >::insert(&validator_index, record); + } + + let threshold = availability_threshold(validators.len()); + + let mut freed_cores = Vec::with_capacity(expected_bits); + for (para_id, pending_availability) in assigned_paras_record + .into_iter() + .flatten() + .filter_map(|(id, p)| p.map(|p| (id, p))) + { + if pending_availability.availability_votes.count_ones() >= threshold { + >::remove(¶_id); + let commitments = match PendingAvailabilityCommitments::::take(¶_id) { + Some(commitments) => commitments, + None => { + log::warn!( + target: LOG_TARGET, + "Inclusion::process_bitfields: PendingAvailability and PendingAvailabilityCommitments + are out of sync, did someone mess with the storage?", + ); + continue + }, + }; + + let receipt = CommittedCandidateReceipt { + descriptor: pending_availability.descriptor, + commitments, + }; + let _weight = Self::enact_candidate( + pending_availability.relay_parent_number, + receipt, + pending_availability.backers, + pending_availability.availability_votes, + pending_availability.core, + pending_availability.backing_group, + ); + + freed_cores.push((pending_availability.core, pending_availability.hash)); + } else { + >::insert(¶_id, &pending_availability); + } + } + + freed_cores + } + + /// Process candidates that have been backed. Provide the relay storage root, a set of + /// candidates and scheduled cores. + /// + /// Both should be sorted ascending by core index, and the candidates should be a subset of + /// scheduled cores. If these conditions are not met, the execution of the function fails. + pub(crate) fn process_candidates( + allowed_relay_parents: &AllowedRelayParentsTracker>, + candidates: Vec>, + scheduled: Vec>>, + group_validators: GV, + ) -> Result, DispatchError> + where + GV: Fn(GroupIndex) -> Option>, + { + let now = >::block_number(); + + ensure!(candidates.len() <= scheduled.len(), Error::::UnscheduledCandidate); + + if scheduled.is_empty() { + return Ok(ProcessedCandidates::default()) + } + + let validators = shared::Pallet::::active_validator_keys(); + + // Collect candidate receipts with backers. + let mut candidate_receipt_with_backing_validator_indices = + Vec::with_capacity(candidates.len()); + + // Do all checks before writing storage. + let core_indices_and_backers = { + let mut skip = 0; + let mut core_indices_and_backers = Vec::with_capacity(candidates.len()); + let mut last_core = None; + + let mut check_assignment_in_order = + |assignment: &CoreAssignment>| -> DispatchResult { + ensure!( + last_core.map_or(true, |core| assignment.core > core), + Error::::ScheduledOutOfOrder, + ); + + last_core = Some(assignment.core); + Ok(()) + }; + + // We combine an outer loop over candidates with an inner loop over the scheduled, + // where each iteration of the outer loop picks up at the position + // in scheduled just after the past iteration left off. + // + // If the candidates appear in the same order as they appear in `scheduled`, + // then they should always be found. If the end of `scheduled` is reached, + // then the candidate was either not scheduled or out-of-order. + // + // In the meantime, we do certain sanity checks on the candidates and on the scheduled + // list. + 'next_backed_candidate: for (candidate_idx, backed_candidate) in + candidates.iter().enumerate() + { + let relay_parent_hash = backed_candidate.descriptor().relay_parent; + let para_id = backed_candidate.descriptor().para_id; + + let prev_context = >::para_most_recent_context(para_id); + + let check_ctx = CandidateCheckContext::::new(prev_context); + let signing_context = SigningContext { + parent_hash: relay_parent_hash, + session_index: shared::Pallet::::session_index(), + }; + + let relay_parent_number = match check_ctx.verify_backed_candidate( + &allowed_relay_parents, + candidate_idx, + backed_candidate, + )? { + Err(FailedToCreatePVD) => { + log::debug!( + target: LOG_TARGET, + "Failed to create PVD for candidate {}", + candidate_idx, + ); + // We don't want to error out here because it will + // brick the relay-chain. So we return early without + // doing anything. + return Ok(ProcessedCandidates::default()) + }, + Ok(rpn) => rpn, + }; + + let para_id = backed_candidate.descriptor().para_id; + let mut backers = bitvec::bitvec![u8, BitOrderLsb0; 0; validators.len()]; + + for (i, core_assignment) in scheduled[skip..].iter().enumerate() { + check_assignment_in_order(core_assignment)?; + + if para_id == core_assignment.paras_entry.para_id() { + ensure!( + >::get(¶_id).is_none() && + >::get(¶_id).is_none(), + Error::::CandidateScheduledBeforeParaFree, + ); + + // account for already skipped, and then skip this one. + skip = i + skip + 1; + + // The candidate based upon relay parent `N` should be backed by a group + // assigned to core at block `N + 1`. Thus, `relay_parent_number + 1` + // will always land in the current session. + let group_idx = >::group_assigned_to_core( + core_assignment.core, + relay_parent_number + One::one(), + ) + .ok_or_else(|| { + log::warn!( + target: LOG_TARGET, + "Failed to compute group index for candidate {}", + candidate_idx + ); + Error::::InvalidAssignment + })?; + let group_vals = group_validators(group_idx) + .ok_or_else(|| Error::::InvalidGroupIndex)?; + + // check the signatures in the backing and that it is a majority. + { + let maybe_amount_validated = primitives::check_candidate_backing( + &backed_candidate, + &signing_context, + group_vals.len(), + |intra_group_vi| { + group_vals + .get(intra_group_vi) + .and_then(|vi| validators.get(vi.0 as usize)) + .map(|v| v.clone()) + }, + ); + + match maybe_amount_validated { + Ok(amount_validated) => ensure!( + amount_validated >= minimum_backing_votes(group_vals.len()), + Error::::InsufficientBacking, + ), + Err(()) => { + Err(Error::::InvalidBacking)?; + }, + } + + let mut backer_idx_and_attestation = + Vec::<(ValidatorIndex, ValidityAttestation)>::with_capacity( + backed_candidate.validator_indices.count_ones(), + ); + let candidate_receipt = backed_candidate.receipt(); + + for ((bit_idx, _), attestation) in backed_candidate + .validator_indices + .iter() + .enumerate() + .filter(|(_, signed)| **signed) + .zip(backed_candidate.validity_votes.iter().cloned()) + { + let val_idx = group_vals + .get(bit_idx) + .expect("this query succeeded above; qed"); + backer_idx_and_attestation.push((*val_idx, attestation)); + + backers.set(val_idx.0 as _, true); + } + candidate_receipt_with_backing_validator_indices + .push((candidate_receipt, backer_idx_and_attestation)); + } + + core_indices_and_backers.push(( + (core_assignment.core, core_assignment.paras_entry.para_id()), + backers, + group_idx, + relay_parent_number, + )); + continue 'next_backed_candidate + } + } + + // end of loop reached means that the candidate didn't appear in the non-traversed + // section of the `scheduled` slice. either it was not scheduled or didn't appear in + // `candidates` in the correct order. + ensure!(false, Error::::UnscheduledCandidate); + } + + // check remainder of scheduled cores, if any. + for assignment in scheduled[skip..].iter() { + check_assignment_in_order(assignment)?; + } + + core_indices_and_backers + }; + + // one more sweep for actually writing to storage. + let core_indices = core_indices_and_backers.iter().map(|(c, ..)| *c).collect(); + for (candidate, (core, backers, group, relay_parent_number)) in + candidates.into_iter().zip(core_indices_and_backers) + { + let para_id = candidate.descriptor().para_id; + + // initialize all availability votes to 0. + let availability_votes: BitVec = + bitvec::bitvec![u8, BitOrderLsb0; 0; validators.len()]; + + Self::deposit_event(Event::::CandidateBacked( + candidate.candidate.to_plain(), + candidate.candidate.commitments.head_data.clone(), + core.0, + group, + )); + + let candidate_hash = candidate.candidate.hash(); + + let (descriptor, commitments) = + (candidate.candidate.descriptor, candidate.candidate.commitments); + + >::insert( + ¶_id, + CandidatePendingAvailability { + core: core.0, + hash: candidate_hash, + descriptor, + availability_votes, + relay_parent_number, + backers: backers.to_bitvec(), + backed_in_number: now, + backing_group: group, + }, + ); + >::insert(¶_id, commitments); + } + + Ok(ProcessedCandidates:: { + core_indices, + candidate_receipt_with_backing_validator_indices, + }) + } + + /// Run the acceptance criteria checks on the given candidate commitments. + pub(crate) fn check_validation_outputs_for_runtime_api( + para_id: ParaId, + relay_parent_number: BlockNumberFor, + validation_outputs: primitives::CandidateCommitments, + ) -> bool { + let prev_context = >::para_most_recent_context(para_id); + let check_ctx = CandidateCheckContext::::new(prev_context); + + if check_ctx + .check_validation_outputs( + para_id, + relay_parent_number, + &validation_outputs.head_data, + &validation_outputs.new_validation_code, + validation_outputs.processed_downward_messages, + &validation_outputs.upward_messages, + BlockNumberFor::::from(validation_outputs.hrmp_watermark), + &validation_outputs.horizontal_messages, + ) + .is_err() + { + log::debug!( + target: LOG_TARGET, + "Validation outputs checking for parachain `{}` failed", + u32::from(para_id), + ); + false + } else { + true + } + } + + fn enact_candidate( + relay_parent_number: BlockNumberFor, + receipt: CommittedCandidateReceipt, + backers: BitVec, + availability_votes: BitVec, + core_index: CoreIndex, + backing_group: GroupIndex, + ) -> Weight { + let plain = receipt.to_plain(); + let commitments = receipt.commitments; + let config = >::config(); + + T::RewardValidators::reward_backing( + backers + .iter() + .enumerate() + .filter(|(_, backed)| **backed) + .map(|(i, _)| ValidatorIndex(i as _)), + ); + + T::RewardValidators::reward_bitfields( + availability_votes + .iter() + .enumerate() + .filter(|(_, voted)| **voted) + .map(|(i, _)| ValidatorIndex(i as _)), + ); + + // initial weight is config read. + let mut weight = T::DbWeight::get().reads_writes(1, 0); + if let Some(new_code) = commitments.new_validation_code { + // Block number of candidate's inclusion. + let now = >::block_number(); + + weight.saturating_add(>::schedule_code_upgrade( + receipt.descriptor.para_id, + new_code, + now, + &config, + )); + } + + // enact the messaging facet of the candidate. + weight.saturating_accrue(>::prune_dmq( + receipt.descriptor.para_id, + commitments.processed_downward_messages, + )); + weight.saturating_accrue(Self::receive_upward_messages( + receipt.descriptor.para_id, + commitments.upward_messages.as_slice(), + )); + weight.saturating_accrue(>::prune_hrmp( + receipt.descriptor.para_id, + BlockNumberFor::::from(commitments.hrmp_watermark), + )); + weight.saturating_accrue(>::queue_outbound_hrmp( + receipt.descriptor.para_id, + commitments.horizontal_messages, + )); + + Self::deposit_event(Event::::CandidateIncluded( + plain, + commitments.head_data.clone(), + core_index, + backing_group, + )); + + weight.saturating_add(>::note_new_head( + receipt.descriptor.para_id, + commitments.head_data, + relay_parent_number, + )) + } + + pub(crate) fn relay_dispatch_queue_size(para_id: ParaId) -> (u32, u32) { + let fp = T::MessageQueue::footprint(AggregateMessageOrigin::Ump(UmpQueueId::Para(para_id))); + (fp.count as u32, fp.size as u32) + } + + /// Check that all the upward messages sent by a candidate pass the acceptance criteria. + pub(crate) fn check_upward_messages( + config: &HostConfiguration>, + para: ParaId, + upward_messages: &[UpwardMessage], + ) -> Result<(), UmpAcceptanceCheckErr> { + // Cannot send UMP messages while off-boarding. + if >::is_offboarding(para) { + ensure!(upward_messages.is_empty(), UmpAcceptanceCheckErr::IsOffboarding); + } + + let additional_msgs = upward_messages.len() as u32; + if additional_msgs > config.max_upward_message_num_per_candidate { + return Err(UmpAcceptanceCheckErr::MoreMessagesThanPermitted { + sent: additional_msgs, + permitted: config.max_upward_message_num_per_candidate, + }) + } + + let (para_queue_count, mut para_queue_size) = Self::relay_dispatch_queue_size(para); + + if para_queue_count.saturating_add(additional_msgs) > config.max_upward_queue_count { + return Err(UmpAcceptanceCheckErr::CapacityExceeded { + count: para_queue_count.saturating_add(additional_msgs).into(), + limit: config.max_upward_queue_count.into(), + }) + } + + for (idx, msg) in upward_messages.into_iter().enumerate() { + let msg_size = msg.len() as u32; + if msg_size > config.max_upward_message_size { + return Err(UmpAcceptanceCheckErr::MessageSize { + idx: idx as u32, + msg_size, + max_size: config.max_upward_message_size, + }) + } + // make sure that the queue is not overfilled. + // we do it here only once since returning false invalidates the whole relay-chain + // block. + if para_queue_size.saturating_add(msg_size) > config.max_upward_queue_size { + return Err(UmpAcceptanceCheckErr::TotalSizeExceeded { + total_size: para_queue_size.saturating_add(msg_size).into(), + limit: config.max_upward_queue_size.into(), + }) + } + para_queue_size.saturating_accrue(msg_size); + } + + Ok(()) + } + + /// Enqueues `upward_messages` from a `para`'s accepted candidate block. + /// + /// This function is infallible since the candidate was already accepted and we therefore need + /// to deal with the messages as given. Messages that are too long will be ignored since such + /// candidates should have already been rejected in [`Self::check_upward_messages`]. + pub(crate) fn receive_upward_messages(para: ParaId, upward_messages: &[Vec]) -> Weight { + let bounded = upward_messages + .iter() + .filter_map(|d| { + BoundedSlice::try_from(&d[..]) + .map_err(|e| { + defensive!("Accepted candidate contains too long msg, len=", d.len()); + e + }) + .ok() + }) + .collect(); + Self::receive_bounded_upward_messages(para, bounded) + } + + /// Enqueues storage-bounded `upward_messages` from a `para`'s accepted candidate block. + pub(crate) fn receive_bounded_upward_messages( + para: ParaId, + messages: Vec>>, + ) -> Weight { + let count = messages.len() as u32; + if count == 0 { + return Weight::zero() + } + + T::MessageQueue::enqueue_messages( + messages.into_iter(), + AggregateMessageOrigin::Ump(UmpQueueId::Para(para)), + ); + let weight = ::WeightInfo::receive_upward_messages(count); + Self::deposit_event(Event::UpwardMessagesReceived { from: para, count }); + weight + } + + /// Cleans up all paras pending availability that the predicate returns true for. + /// + /// The predicate accepts the index of the core and the block number the core has been occupied + /// since (i.e. the block number the candidate was backed at in this fork of the relay chain). + /// + /// Returns a vector of cleaned-up core IDs. + pub(crate) fn collect_pending( + pred: impl Fn(CoreIndex, BlockNumberFor) -> bool, + ) -> Vec { + let mut cleaned_up_ids = Vec::new(); + let mut cleaned_up_cores = Vec::new(); + + for (para_id, pending_record) in >::iter() { + if pred(pending_record.core, pending_record.backed_in_number) { + cleaned_up_ids.push(para_id); + cleaned_up_cores.push(pending_record.core); + } + } + + for para_id in cleaned_up_ids { + let pending = >::take(¶_id); + let commitments = >::take(¶_id); + + if let (Some(pending), Some(commitments)) = (pending, commitments) { + // defensive: this should always be true. + let candidate = CandidateReceipt { + descriptor: pending.descriptor, + commitments_hash: commitments.hash(), + }; + + Self::deposit_event(Event::::CandidateTimedOut( + candidate, + commitments.head_data, + pending.core, + )); + } + } + + cleaned_up_cores + } + + /// Cleans up all paras pending availability that are in the given list of disputed candidates. + /// + /// Returns a vector of cleaned-up core IDs. + pub(crate) fn collect_disputed(disputed: &BTreeSet) -> Vec { + let mut cleaned_up_ids = Vec::new(); + let mut cleaned_up_cores = Vec::new(); + + for (para_id, pending_record) in >::iter() { + if disputed.contains(&pending_record.hash) { + cleaned_up_ids.push(para_id); + cleaned_up_cores.push(pending_record.core); + } + } + + for para_id in cleaned_up_ids { + let _ = >::take(¶_id); + let _ = >::take(¶_id); + } + + cleaned_up_cores + } + + /// Forcibly enact the candidate with the given ID as though it had been deemed available + /// by bitfields. + /// + /// Is a no-op if there is no candidate pending availability for this para-id. + /// This should generally not be used but it is useful during execution of Runtime APIs, + /// where the changes to the state are expected to be discarded directly after. + pub(crate) fn force_enact(para: ParaId) { + let pending = >::take(¶); + let commitments = >::take(¶); + + if let (Some(pending), Some(commitments)) = (pending, commitments) { + let candidate = + CommittedCandidateReceipt { descriptor: pending.descriptor, commitments }; + + Self::enact_candidate( + pending.relay_parent_number, + candidate, + pending.backers, + pending.availability_votes, + pending.core, + pending.backing_group, + ); + } + } + + /// Returns the `CommittedCandidateReceipt` pending availability for the para provided, if any. + pub(crate) fn candidate_pending_availability( + para: ParaId, + ) -> Option> { + >::get(¶) + .map(|p| p.descriptor) + .and_then(|d| >::get(¶).map(move |c| (d, c))) + .map(|(d, c)| CommittedCandidateReceipt { descriptor: d, commitments: c }) + } + + /// Returns the metadata around the candidate pending availability for the + /// para provided, if any. + pub(crate) fn pending_availability( + para: ParaId, + ) -> Option>> { + >::get(¶) + } +} + +const fn availability_threshold(n_validators: usize) -> usize { + supermajority_threshold(n_validators) +} + +impl AcceptanceCheckErr { + /// Returns the same error so that it can be threaded through a needle of `DispatchError` and + /// ultimately returned from a `Dispatchable`. + fn strip_into_dispatch_err(self) -> Error { + use AcceptanceCheckErr::*; + match self { + HeadDataTooLarge => Error::::HeadDataTooLarge, + PrematureCodeUpgrade => Error::::PrematureCodeUpgrade, + NewCodeTooLarge => Error::::NewCodeTooLarge, + ProcessedDownwardMessages(_) => Error::::IncorrectDownwardMessageHandling, + UpwardMessages(_) => Error::::InvalidUpwardMessages, + HrmpWatermark(_) => Error::::HrmpWatermarkMishandling, + OutboundHrmp(_) => Error::::InvalidOutboundHrmp, + } + } +} + +impl OnQueueChanged for Pallet { + // Write back the remaining queue capacity into `relay_dispatch_queue_remaining_capacity`. + fn on_queue_changed(origin: AggregateMessageOrigin, count: u64, size: u64) { + let para = match origin { + AggregateMessageOrigin::Ump(UmpQueueId::Para(p)) => p, + }; + let (count, size) = (count.saturated_into(), size.saturated_into()); + // TODO paritytech/polkadot#6283: Remove all usages of `relay_dispatch_queue_size` + #[allow(deprecated)] + well_known_keys::relay_dispatch_queue_size_typed(para).set((count, size)); + + let config = >::config(); + let remaining_count = config.max_upward_queue_count.saturating_sub(count); + let remaining_size = config.max_upward_queue_size.saturating_sub(size); + well_known_keys::relay_dispatch_queue_remaining_capacity(para) + .set((remaining_count, remaining_size)); + } +} + +/// A collection of data required for checking a candidate. +pub(crate) struct CandidateCheckContext { + config: configuration::HostConfiguration>, + prev_context: Option>, +} + +/// An error indicating that creating Persisted Validation Data failed +/// while checking a candidate's validity. +pub(crate) struct FailedToCreatePVD; + +impl CandidateCheckContext { + pub(crate) fn new(prev_context: Option>) -> Self { + Self { config: >::config(), prev_context } + } + + /// Execute verification of the candidate. + /// + /// Assures: + /// * relay-parent in-bounds + /// * collator signature check passes + /// * code hash of commitments matches current code hash + /// * para head in the descriptor and commitments match + /// + /// Returns the relay-parent block number. + pub(crate) fn verify_backed_candidate( + &self, + allowed_relay_parents: &AllowedRelayParentsTracker>, + candidate_idx: usize, + backed_candidate: &BackedCandidate<::Hash>, + ) -> Result, FailedToCreatePVD>, Error> { + let para_id = backed_candidate.descriptor().para_id; + let relay_parent = backed_candidate.descriptor().relay_parent; + + // Check that the relay-parent is one of the allowed relay-parents. + let (relay_parent_storage_root, relay_parent_number) = { + match allowed_relay_parents.acquire_info(relay_parent, self.prev_context) { + None => return Err(Error::::DisallowedRelayParent), + Some(info) => info, + } + }; + + { + let persisted_validation_data = match crate::util::make_persisted_validation_data::( + para_id, + relay_parent_number, + relay_parent_storage_root, + ) + .defensive_proof("the para is registered") + { + Some(l) => l, + None => return Ok(Err(FailedToCreatePVD)), + }; + + let expected = persisted_validation_data.hash(); + + ensure!( + expected == backed_candidate.descriptor().persisted_validation_data_hash, + Error::::ValidationDataHashMismatch, + ); + } + + ensure!( + backed_candidate.descriptor().check_collator_signature().is_ok(), + Error::::NotCollatorSigned, + ); + + let validation_code_hash = >::current_code_hash(para_id) + // A candidate for a parachain without current validation code is not scheduled. + .ok_or_else(|| Error::::UnscheduledCandidate)?; + ensure!( + backed_candidate.descriptor().validation_code_hash == validation_code_hash, + Error::::InvalidValidationCodeHash, + ); + + ensure!( + backed_candidate.descriptor().para_head == + backed_candidate.candidate.commitments.head_data.hash(), + Error::::ParaHeadMismatch, + ); + + if let Err(err) = self.check_validation_outputs( + para_id, + relay_parent_number, + &backed_candidate.candidate.commitments.head_data, + &backed_candidate.candidate.commitments.new_validation_code, + backed_candidate.candidate.commitments.processed_downward_messages, + &backed_candidate.candidate.commitments.upward_messages, + BlockNumberFor::::from(backed_candidate.candidate.commitments.hrmp_watermark), + &backed_candidate.candidate.commitments.horizontal_messages, + ) { + log::debug!( + target: LOG_TARGET, + "Validation outputs checking during inclusion of a candidate {} for parachain `{}` failed", + candidate_idx, + u32::from(para_id), + ); + Err(err.strip_into_dispatch_err::())?; + }; + Ok(Ok(relay_parent_number)) + } + + /// Check the given outputs after candidate validation on whether it passes the acceptance + /// criteria. + /// + /// The things that are checked can be roughly divided into limits and minimums. + /// + /// Limits are things like max message queue sizes and max head data size. + /// + /// Minimums are things like the minimum amount of messages that must be processed + /// by the parachain block. + /// + /// Limits are checked against the current state. The parachain block must be acceptable + /// by the current relay-chain state regardless of whether it was acceptable at some relay-chain + /// state in the past. + /// + /// Minimums are checked against the current state but modulated by + /// considering the information available at the relay-parent of the parachain block. + fn check_validation_outputs( + &self, + para_id: ParaId, + relay_parent_number: BlockNumberFor, + head_data: &HeadData, + new_validation_code: &Option, + processed_downward_messages: u32, + upward_messages: &[primitives::UpwardMessage], + hrmp_watermark: BlockNumberFor, + horizontal_messages: &[primitives::OutboundHrmpMessage], + ) -> Result<(), AcceptanceCheckErr>> { + ensure!( + head_data.0.len() <= self.config.max_head_data_size as _, + AcceptanceCheckErr::HeadDataTooLarge, + ); + + // if any, the code upgrade attempt is allowed. + if let Some(new_validation_code) = new_validation_code { + ensure!( + >::can_upgrade_validation_code(para_id), + AcceptanceCheckErr::PrematureCodeUpgrade, + ); + ensure!( + new_validation_code.0.len() <= self.config.max_code_size as _, + AcceptanceCheckErr::NewCodeTooLarge, + ); + } + + // check if the candidate passes the messaging acceptance criteria + >::check_processed_downward_messages( + para_id, + relay_parent_number, + processed_downward_messages, + )?; + Pallet::::check_upward_messages(&self.config, para_id, upward_messages)?; + >::check_hrmp_watermark(para_id, relay_parent_number, hrmp_watermark)?; + >::check_outbound_hrmp(&self.config, para_id, horizontal_messages)?; + + Ok(()) + } +} + +impl QueueFootprinter for Pallet { + type Origin = UmpQueueId; + + fn message_count(origin: Self::Origin) -> u64 { + T::MessageQueue::footprint(AggregateMessageOrigin::Ump(origin)).count + } +} diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..7c22ac36a802fac04041fc5f97811e100dd4f81a --- /dev/null +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -0,0 +1,2284 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::{ + configuration::HostConfiguration, + initializer::SessionChangeNotification, + mock::{ + new_test_ext, Configuration, MockGenesisConfig, ParaInclusion, Paras, ParasShared, + Scheduler, System, Test, + }, + paras::{ParaGenesisArgs, ParaKind}, + paras_inherent::DisputedBitfield, + shared::AllowedRelayParentsTracker, +}; +use primitives::{SignedAvailabilityBitfields, UncheckedSignedAvailabilityBitfields}; + +use assert_matches::assert_matches; +use frame_support::assert_noop; +use keyring::Sr25519Keyring; +use parity_scale_codec::DecodeAll; +use primitives::{ + v5::{Assignment, ParasEntry}, + BlockNumber, CandidateCommitments, CandidateDescriptor, CollatorId, + CompactStatement as Statement, Hash, SignedAvailabilityBitfield, SignedStatement, + ValidationCode, ValidatorId, ValidityAttestation, PARACHAIN_KEY_TYPE_ID, +}; +use sc_keystore::LocalKeystore; +use sp_keystore::{Keystore, KeystorePtr}; +use std::sync::Arc; +use test_helpers::{dummy_collator, dummy_collator_signature, dummy_validation_code}; + +fn default_config() -> HostConfiguration { + let mut config = HostConfiguration::default(); + config.on_demand_cores = 1; + config.max_code_size = 0b100000; + config.max_head_data_size = 0b100000; + config.group_rotation_frequency = u32::MAX; + config +} + +pub(crate) fn genesis_config(paras: Vec<(ParaId, ParaKind)>) -> MockGenesisConfig { + MockGenesisConfig { + paras: paras::GenesisConfig { + paras: paras + .into_iter() + .map(|(id, para_kind)| { + ( + id, + ParaGenesisArgs { + genesis_head: Vec::new().into(), + validation_code: dummy_validation_code(), + para_kind, + }, + ) + }) + .collect(), + ..Default::default() + }, + configuration: configuration::GenesisConfig { config: default_config() }, + ..Default::default() + } +} + +fn default_allowed_relay_parent_tracker() -> AllowedRelayParentsTracker { + let mut allowed = AllowedRelayParentsTracker::default(); + + let relay_parent = System::parent_hash(); + let parent_number = System::block_number().saturating_sub(1); + + allowed.update(relay_parent, Hash::zero(), parent_number, 1); + allowed +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub(crate) enum BackingKind { + #[allow(unused)] + Unanimous, + Threshold, + Lacking, +} + +pub(crate) fn collator_sign_candidate( + collator: Sr25519Keyring, + candidate: &mut CommittedCandidateReceipt, +) { + candidate.descriptor.collator = collator.public().into(); + + let payload = primitives::collator_signature_payload( + &candidate.descriptor.relay_parent, + &candidate.descriptor.para_id, + &candidate.descriptor.persisted_validation_data_hash, + &candidate.descriptor.pov_hash, + &candidate.descriptor.validation_code_hash, + ); + + candidate.descriptor.signature = collator.sign(&payload[..]).into(); + assert!(candidate.descriptor().check_collator_signature().is_ok()); +} + +pub(crate) fn back_candidate( + candidate: CommittedCandidateReceipt, + validators: &[Sr25519Keyring], + group: &[ValidatorIndex], + keystore: &KeystorePtr, + signing_context: &SigningContext, + kind: BackingKind, +) -> BackedCandidate { + let mut validator_indices = bitvec::bitvec![u8, BitOrderLsb0; 0; group.len()]; + let threshold = minimum_backing_votes(group.len()); + + let signing = match kind { + BackingKind::Unanimous => group.len(), + BackingKind::Threshold => threshold, + BackingKind::Lacking => threshold.saturating_sub(1), + }; + + let mut validity_votes = Vec::with_capacity(signing); + let candidate_hash = candidate.hash(); + + for (idx_in_group, val_idx) in group.iter().enumerate().take(signing) { + let key: Sr25519Keyring = validators[val_idx.0 as usize]; + *validator_indices.get_mut(idx_in_group).unwrap() = true; + + let signature = SignedStatement::sign( + &keystore, + Statement::Valid(candidate_hash), + signing_context, + *val_idx, + &key.public().into(), + ) + .unwrap() + .unwrap() + .signature() + .clone(); + + validity_votes.push(ValidityAttestation::Explicit(signature).into()); + } + + let backed = BackedCandidate { candidate, validity_votes, validator_indices }; + + let successfully_backed = + primitives::check_candidate_backing(&backed, signing_context, group.len(), |i| { + Some(validators[group[i].0 as usize].public().into()) + }) + .ok() + .unwrap_or(0) >= + threshold; + + match kind { + BackingKind::Unanimous | BackingKind::Threshold => assert!(successfully_backed), + BackingKind::Lacking => assert!(!successfully_backed), + }; + + backed +} + +pub(crate) fn run_to_block_default_notifications(to: BlockNumber, new_session: Vec) { + run_to_block(to, |b| { + new_session.contains(&b).then_some(SessionChangeNotification { + prev_config: Configuration::config(), + new_config: Configuration::config(), + session_index: ParasShared::session_index() + 1, + ..Default::default() + }) + }); +} + +pub(crate) fn run_to_block( + to: BlockNumber, + new_session: impl Fn(BlockNumber) -> Option>, +) { + while System::block_number() < to { + let b = System::block_number(); + + ParaInclusion::initializer_finalize(); + Paras::initializer_finalize(b); + ParasShared::initializer_finalize(); + + if let Some(notification) = new_session(b + 1) { + ParasShared::initializer_on_new_session( + notification.session_index, + notification.random_seed, + ¬ification.new_config, + notification.validators.clone(), + ); + let outgoing = Paras::initializer_on_new_session(¬ification); + ParaInclusion::initializer_on_new_session(¬ification, &outgoing); + } + + System::on_finalize(b); + + System::on_initialize(b + 1); + System::set_block_number(b + 1); + + ParasShared::initializer_initialize(b + 1); + Paras::initializer_initialize(b + 1); + ParaInclusion::initializer_initialize(b + 1); + } +} + +pub(crate) fn expected_bits() -> usize { + Paras::parachains().len() + Configuration::config().on_demand_cores as usize +} + +fn default_bitfield() -> AvailabilityBitfield { + AvailabilityBitfield(bitvec::bitvec![u8, BitOrderLsb0; 0; expected_bits()]) +} + +fn default_availability_votes() -> BitVec { + bitvec::bitvec![u8, BitOrderLsb0; 0; ParasShared::active_validator_keys().len()] +} + +fn default_backing_bitfield() -> BitVec { + bitvec::bitvec![u8, BitOrderLsb0; 0; ParasShared::active_validator_keys().len()] +} + +fn backing_bitfield(v: &[usize]) -> BitVec { + let mut b = default_backing_bitfield(); + for i in v { + b.set(*i, true); + } + b +} + +pub(crate) fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec { + val_ids.iter().map(|v| v.public().into()).collect() +} + +pub(crate) fn sign_bitfield( + keystore: &KeystorePtr, + key: &Sr25519Keyring, + validator_index: ValidatorIndex, + bitfield: AvailabilityBitfield, + signing_context: &SigningContext, +) -> SignedAvailabilityBitfield { + SignedAvailabilityBitfield::sign( + &keystore, + bitfield, + &signing_context, + validator_index, + &key.public().into(), + ) + .unwrap() + .unwrap() +} + +pub(crate) struct TestCandidateBuilder { + pub(crate) para_id: ParaId, + pub(crate) head_data: HeadData, + pub(crate) para_head_hash: Option, + pub(crate) pov_hash: Hash, + pub(crate) relay_parent: Hash, + pub(crate) persisted_validation_data_hash: Hash, + pub(crate) new_validation_code: Option, + pub(crate) validation_code: ValidationCode, + pub(crate) hrmp_watermark: BlockNumber, +} + +impl std::default::Default for TestCandidateBuilder { + fn default() -> Self { + let zeros = Hash::zero(); + Self { + para_id: 0.into(), + head_data: Default::default(), + para_head_hash: None, + pov_hash: zeros, + relay_parent: zeros, + persisted_validation_data_hash: zeros, + new_validation_code: None, + validation_code: dummy_validation_code(), + hrmp_watermark: 0u32.into(), + } + } +} + +impl TestCandidateBuilder { + pub(crate) fn build(self) -> CommittedCandidateReceipt { + CommittedCandidateReceipt { + descriptor: CandidateDescriptor { + para_id: self.para_id, + pov_hash: self.pov_hash, + relay_parent: self.relay_parent, + persisted_validation_data_hash: self.persisted_validation_data_hash, + validation_code_hash: self.validation_code.hash(), + para_head: self.para_head_hash.unwrap_or_else(|| self.head_data.hash()), + erasure_root: Default::default(), + signature: dummy_collator_signature(), + collator: dummy_collator(), + }, + commitments: CandidateCommitments { + head_data: self.head_data, + new_validation_code: self.new_validation_code, + hrmp_watermark: self.hrmp_watermark, + ..Default::default() + }, + } + } +} + +pub(crate) fn make_vdata_hash(para_id: ParaId) -> Option { + let relay_parent_number = >::block_number() - 1; + make_vdata_hash_with_block_number(para_id, relay_parent_number) +} + +fn make_vdata_hash_with_block_number( + para_id: ParaId, + relay_parent_number: BlockNumber, +) -> Option { + let persisted_validation_data = crate::util::make_persisted_validation_data::( + para_id, + relay_parent_number, + Default::default(), + )?; + Some(persisted_validation_data.hash()) +} + +/// Wrapper around `sanitize_bitfields` with less parameters. +fn simple_sanitize_bitfields( + unchecked_bitfields: UncheckedSignedAvailabilityBitfields, + disputed_bitfield: DisputedBitfield, + expected_bits: usize, +) -> SignedAvailabilityBitfields { + let parent_hash = frame_system::Pallet::::parent_hash(); + let session_index = shared::Pallet::::session_index(); + let validators = shared::Pallet::::active_validator_keys(); + + crate::paras_inherent::sanitize_bitfields::( + unchecked_bitfields, + disputed_bitfield, + expected_bits, + parent_hash, + session_index, + &validators, + ) +} +/// Process a set of already sanitized bitfields. +pub(crate) fn process_bitfields( + expected_bits: usize, + signed_bitfields: SignedAvailabilityBitfields, + core_lookup: impl Fn(CoreIndex) -> Option, +) -> Vec<(CoreIndex, CandidateHash)> { + let validators = shared::Pallet::::active_validator_keys(); + + ParaInclusion::update_pending_availability_and_get_freed_cores::<_>( + expected_bits, + &validators[..], + signed_bitfields, + core_lookup, + ) +} + +#[test] +fn collect_pending_cleans_up_pending() { + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + let thread_a = ParaId::from(3_u32); + + let paras = vec![ + (chain_a, ParaKind::Parachain), + (chain_b, ParaKind::Parachain), + (thread_a, ParaKind::Parathread), + ]; + new_test_ext(genesis_config(paras)).execute_with(|| { + let default_candidate = TestCandidateBuilder::default().build(); + >::insert( + chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: default_candidate.hash(), + descriptor: default_candidate.descriptor.clone(), + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(0), + }, + ); + PendingAvailabilityCommitments::::insert( + chain_a, + default_candidate.commitments.clone(), + ); + + >::insert( + &chain_b, + CandidatePendingAvailability { + core: CoreIndex::from(1), + hash: default_candidate.hash(), + descriptor: default_candidate.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(1), + }, + ); + PendingAvailabilityCommitments::::insert(chain_b, default_candidate.commitments); + + run_to_block(5, |_| None); + + assert!(>::get(&chain_a).is_some()); + assert!(>::get(&chain_b).is_some()); + assert!(>::get(&chain_a).is_some()); + assert!(>::get(&chain_b).is_some()); + + ParaInclusion::collect_pending(|core, _since| core == CoreIndex::from(0)); + + assert!(>::get(&chain_a).is_none()); + assert!(>::get(&chain_b).is_some()); + assert!(>::get(&chain_a).is_none()); + assert!(>::get(&chain_b).is_some()); + }); +} + +#[test] +fn bitfield_checks() { + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + let thread_a = ParaId::from(3_u32); + + let paras = vec![ + (chain_a, ParaKind::Parachain), + (chain_b, ParaKind::Parachain), + (thread_a, ParaKind::Parathread), + ]; + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + for validator in validators.iter() { + Keystore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); + } + let validator_public = validator_pubkeys(&validators); + + new_test_ext(genesis_config(paras.clone())).execute_with(|| { + shared::Pallet::::set_active_validators_ascending(validator_public.clone()); + shared::Pallet::::set_session_index(5); + + let signing_context = + SigningContext { parent_hash: System::parent_hash(), session_index: 5 }; + + let core_lookup = |core| match core { + core if core == CoreIndex::from(0) => Some(chain_a), + core if core == CoreIndex::from(1) => Some(chain_b), + core if core == CoreIndex::from(2) => Some(thread_a), + core if core == CoreIndex::from(3) => None, // for the expected_cores() + 1 test below. + _ => panic!("out of bounds for testing"), + }; + + // too many bits in bitfield + { + let mut bare_bitfield = default_bitfield(); + bare_bitfield.0.push(false); + let signed = sign_bitfield( + &keystore, + &validators[0], + ValidatorIndex(0), + bare_bitfield, + &signing_context, + ); + + let checked_bitfields = simple_sanitize_bitfields( + vec![signed.into()], + DisputedBitfield::zeros(expected_bits()), + expected_bits(), + ); + assert_eq!( + checked_bitfields.len(), + 0, + "Bitfield has wrong size, it should have been filtered." + ); + } + + // not enough bits + { + let bare_bitfield = default_bitfield(); + let signed = sign_bitfield( + &keystore, + &validators[0], + ValidatorIndex(0), + bare_bitfield, + &signing_context, + ); + + let checked_bitfields = simple_sanitize_bitfields( + vec![signed.into()], + DisputedBitfield::zeros(expected_bits()), + expected_bits() + 1, + ); + assert_eq!( + checked_bitfields.len(), + 0, + "Bitfield has wrong size, it should have been filtered." + ); + } + + // non-pending bit set. + { + let mut bare_bitfield = default_bitfield(); + *bare_bitfield.0.get_mut(0).unwrap() = true; + let signed = sign_bitfield( + &keystore, + &validators[0], + ValidatorIndex(0), + bare_bitfield, + &signing_context, + ); + + // the threshold to free a core is 4 availability votes, but we only expect 1 valid + // valid bitfield because `signed_0` will get skipped for being out of order. + let checked_bitfields = simple_sanitize_bitfields( + vec![signed.into()], + DisputedBitfield::zeros(expected_bits()), + expected_bits(), + ); + assert_eq!(checked_bitfields.len(), 1, "No bitfields should have been filtered!"); + + let x = process_bitfields(expected_bits(), checked_bitfields, core_lookup); + assert!(x.is_empty(), "No core should be freed."); + } + + // empty bitfield signed: always ok, but kind of useless. + { + let bare_bitfield = default_bitfield(); + let signed = sign_bitfield( + &keystore, + &validators[0], + ValidatorIndex(0), + bare_bitfield, + &signing_context, + ); + let checked_bitfields = simple_sanitize_bitfields( + vec![signed.into()], + DisputedBitfield::zeros(expected_bits()), + expected_bits(), + ); + assert_eq!(checked_bitfields.len(), 1, "No bitfields should have been filtered!"); + + let x = process_bitfields(expected_bits(), checked_bitfields, core_lookup); + assert!(x.is_empty(), "No core should be freed."); + } + + // bitfield signed with pending bit signed. + { + let mut bare_bitfield = default_bitfield(); + + assert_eq!(core_lookup(CoreIndex::from(0)), Some(chain_a)); + + let default_candidate = TestCandidateBuilder::default().build(); + >::insert( + chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: default_candidate.hash(), + descriptor: default_candidate.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(0), + }, + ); + PendingAvailabilityCommitments::::insert(chain_a, default_candidate.commitments); + + *bare_bitfield.0.get_mut(0).unwrap() = true; + let signed = sign_bitfield( + &keystore, + &validators[0], + ValidatorIndex(0), + bare_bitfield, + &signing_context, + ); + + let checked_bitfields = simple_sanitize_bitfields( + vec![signed.into()], + DisputedBitfield::zeros(expected_bits()), + expected_bits(), + ); + assert_eq!(checked_bitfields.len(), 1, "No bitfields should have been filtered!"); + + let x = process_bitfields(expected_bits(), checked_bitfields, core_lookup); + assert!(x.is_empty(), "No core should be freed."); + + >::remove(chain_a); + PendingAvailabilityCommitments::::remove(chain_a); + } + + // bitfield signed with pending bit signed, but no commitments. + { + let mut bare_bitfield = default_bitfield(); + + assert_eq!(core_lookup(CoreIndex::from(0)), Some(chain_a)); + + let default_candidate = TestCandidateBuilder::default().build(); + >::insert( + chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: default_candidate.hash(), + descriptor: default_candidate.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(0), + }, + ); + + *bare_bitfield.0.get_mut(0).unwrap() = true; + let signed = sign_bitfield( + &keystore, + &validators[0], + ValidatorIndex(0), + bare_bitfield, + &signing_context, + ); + + let checked_bitfields = simple_sanitize_bitfields( + vec![signed.into()], + DisputedBitfield::zeros(expected_bits()), + expected_bits(), + ); + assert_eq!(checked_bitfields.len(), 1, "No bitfields should have been filtered!"); + + let x = process_bitfields(expected_bits(), checked_bitfields, core_lookup); + // no core is freed + assert!(x.is_empty(), "No core should be freed."); + } + }); +} + +#[test] +fn availability_threshold_is_supermajority() { + assert_eq!(3, availability_threshold(4)); + assert_eq!(5, availability_threshold(6)); + assert_eq!(7, availability_threshold(9)); +} + +#[test] +fn supermajority_bitfields_trigger_availability() { + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + let thread_a = ParaId::from(3_u32); + + let paras = vec![ + (chain_a, ParaKind::Parachain), + (chain_b, ParaKind::Parachain), + (thread_a, ParaKind::Parathread), + ]; + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + for validator in validators.iter() { + Keystore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); + } + let validator_public = validator_pubkeys(&validators); + + new_test_ext(genesis_config(paras)).execute_with(|| { + shared::Pallet::::set_active_validators_ascending(validator_public.clone()); + shared::Pallet::::set_session_index(5); + + let signing_context = + SigningContext { parent_hash: System::parent_hash(), session_index: 5 }; + + let core_lookup = |core| match core { + core if core == CoreIndex::from(0) => Some(chain_a), + core if core == CoreIndex::from(1) => Some(chain_b), + core if core == CoreIndex::from(2) => Some(thread_a), + _ => panic!("Core out of bounds for 2 parachains and 1 parathread core."), + }; + + let candidate_a = TestCandidateBuilder { + para_id: chain_a, + head_data: vec![1, 2, 3, 4].into(), + ..Default::default() + } + .build(); + + >::insert( + chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: candidate_a.hash(), + descriptor: candidate_a.clone().descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: backing_bitfield(&[3, 4]), + backing_group: GroupIndex::from(0), + }, + ); + PendingAvailabilityCommitments::::insert(chain_a, candidate_a.clone().commitments); + + let candidate_b = TestCandidateBuilder { + para_id: chain_b, + head_data: vec![5, 6, 7, 8].into(), + ..Default::default() + } + .build(); + + >::insert( + chain_b, + CandidatePendingAvailability { + core: CoreIndex::from(1), + hash: candidate_b.hash(), + descriptor: candidate_b.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: backing_bitfield(&[0, 2]), + backing_group: GroupIndex::from(1), + }, + ); + PendingAvailabilityCommitments::::insert(chain_b, candidate_b.commitments); + + // this bitfield signals that a and b are available. + let a_and_b_available = { + let mut bare_bitfield = default_bitfield(); + *bare_bitfield.0.get_mut(0).unwrap() = true; + *bare_bitfield.0.get_mut(1).unwrap() = true; + + bare_bitfield + }; + + // this bitfield signals that only a is available. + let a_available = { + let mut bare_bitfield = default_bitfield(); + *bare_bitfield.0.get_mut(0).unwrap() = true; + + bare_bitfield + }; + + let threshold = availability_threshold(validators.len()); + + // 4 of 5 first value >= 2/3 + assert_eq!(threshold, 4); + + let signed_bitfields = validators + .iter() + .enumerate() + .filter_map(|(i, key)| { + let to_sign = if i < 3 { + a_and_b_available.clone() + } else if i < 4 { + a_available.clone() + } else { + // sign nothing. + return None + }; + + Some( + sign_bitfield( + &keystore, + key, + ValidatorIndex(i as _), + to_sign, + &signing_context, + ) + .into(), + ) + }) + .collect::>(); + + let old_len = signed_bitfields.len(); + let checked_bitfields = simple_sanitize_bitfields( + signed_bitfields, + DisputedBitfield::zeros(expected_bits()), + expected_bits(), + ); + assert_eq!(checked_bitfields.len(), old_len, "No bitfields should have been filtered!"); + + // only chain A's core is freed. + let v = process_bitfields(expected_bits(), checked_bitfields, core_lookup); + assert_eq!(vec![(CoreIndex(0), candidate_a.hash())], v); + + // chain A had 4 signing off, which is >= threshold. + // chain B has 3 signing off, which is < threshold. + assert!(>::get(&chain_a).is_none()); + assert!(>::get(&chain_a).is_none()); + assert!(>::get(&chain_b).is_some()); + assert_eq!(>::get(&chain_b).unwrap().availability_votes, { + // check that votes from first 3 were tracked. + + let mut votes = default_availability_votes(); + *votes.get_mut(0).unwrap() = true; + *votes.get_mut(1).unwrap() = true; + *votes.get_mut(2).unwrap() = true; + + votes + }); + + // and check that chain head was enacted. + assert_eq!(Paras::para_head(&chain_a), Some(vec![1, 2, 3, 4].into())); + + // Check that rewards are applied. + { + let rewards = crate::mock::availability_rewards(); + + assert_eq!(rewards.len(), 4); + assert_eq!(rewards.get(&ValidatorIndex(0)).unwrap(), &1); + assert_eq!(rewards.get(&ValidatorIndex(1)).unwrap(), &1); + assert_eq!(rewards.get(&ValidatorIndex(2)).unwrap(), &1); + assert_eq!(rewards.get(&ValidatorIndex(3)).unwrap(), &1); + } + + { + let rewards = crate::mock::backing_rewards(); + + assert_eq!(rewards.len(), 2); + assert_eq!(rewards.get(&ValidatorIndex(3)).unwrap(), &1); + assert_eq!(rewards.get(&ValidatorIndex(4)).unwrap(), &1); + } + }); +} + +#[test] +fn candidate_checks() { + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + let thread_a = ParaId::from(3_u32); + + // The block number of the relay-parent for testing. + const RELAY_PARENT_NUM: BlockNumber = 4; + + let paras = vec![ + (chain_a, ParaKind::Parachain), + (chain_b, ParaKind::Parachain), + (thread_a, ParaKind::Parathread), + ]; + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + for validator in validators.iter() { + Keystore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); + } + let validator_public = validator_pubkeys(&validators); + + new_test_ext(genesis_config(paras)).execute_with(|| { + shared::Pallet::::set_active_validators_ascending(validator_public.clone()); + shared::Pallet::::set_session_index(5); + + run_to_block(5, |_| None); + + let signing_context = + SigningContext { parent_hash: System::parent_hash(), session_index: 5 }; + + let group_validators = |group_index: GroupIndex| { + match group_index { + group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]), + group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]), + group_index if group_index == GroupIndex::from(2) => Some(vec![4]), + _ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"), + } + .map(|m| m.into_iter().map(ValidatorIndex).collect::>()) + }; + + // When processing candidates, we compute the group index from scheduler. + let validator_groups = vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2), ValidatorIndex(3)], + vec![ValidatorIndex(4)], + ]; + Scheduler::set_validator_groups(validator_groups); + + let entry_ttl = 10_000; + let thread_collator: CollatorId = Sr25519Keyring::Two.public().into(); + let chain_a_assignment = CoreAssignment { + core: CoreIndex::from(0), + paras_entry: ParasEntry::new(Assignment::new(chain_a), entry_ttl), + }; + + let chain_b_assignment = CoreAssignment { + core: CoreIndex::from(1), + paras_entry: ParasEntry::new(Assignment::new(chain_b), entry_ttl), + }; + + let thread_a_assignment = CoreAssignment { + core: CoreIndex::from(2), + paras_entry: ParasEntry::new(Assignment::new(thread_a), entry_ttl), + }; + + let allowed_relay_parents = default_allowed_relay_parent_tracker(); + + // unscheduled candidate. + { + let mut candidate = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); + + let backed = back_candidate( + candidate, + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + assert_noop!( + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed], + vec![chain_b_assignment.clone()], + &group_validators, + ), + Error::::UnscheduledCandidate + ); + } + + // candidates out of order. + { + let mut candidate_a = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + let mut candidate_b = TestCandidateBuilder { + para_id: chain_b, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(2), + persisted_validation_data_hash: make_vdata_hash(chain_b).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); + + collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_b); + + let backed_a = back_candidate( + candidate_a, + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + let backed_b = back_candidate( + candidate_b, + &validators, + group_validators(GroupIndex::from(1)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + // out-of-order manifests as unscheduled. + assert_noop!( + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed_b, backed_a], + vec![chain_a_assignment.clone(), chain_b_assignment.clone()], + &group_validators, + ), + Error::::UnscheduledCandidate + ); + } + + // candidate not backed. + { + let mut candidate = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); + + let backed = back_candidate( + candidate, + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Lacking, + ); + + assert_noop!( + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed], + vec![chain_a_assignment.clone()], + &group_validators, + ), + Error::::InsufficientBacking + ); + } + + // one of candidates is not based on allowed relay parent. + { + let wrong_parent_hash = Hash::repeat_byte(222); + assert!(System::parent_hash() != wrong_parent_hash); + + let mut candidate_a = TestCandidateBuilder { + para_id: chain_a, + relay_parent: wrong_parent_hash, + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + ..Default::default() + } + .build(); + + let mut candidate_b = TestCandidateBuilder { + para_id: chain_b, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(2), + persisted_validation_data_hash: make_vdata_hash(chain_b).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); + + collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_b); + + let backed_a = back_candidate( + candidate_a, + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + let backed_b = back_candidate( + candidate_b, + &validators, + group_validators(GroupIndex::from(1)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + assert_noop!( + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed_b, backed_a], + vec![chain_a_assignment.clone(), chain_b_assignment.clone()], + &group_validators, + ), + Error::::DisallowedRelayParent + ); + } + + // candidate not well-signed by collator. + { + let mut candidate = TestCandidateBuilder { + para_id: thread_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(thread_a).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + + assert_eq!(CollatorId::from(Sr25519Keyring::Two.public()), thread_collator); + collator_sign_candidate(Sr25519Keyring::Two, &mut candidate); + + // change the candidate after signing. + candidate.descriptor.pov_hash = Hash::repeat_byte(2); + + let backed = back_candidate( + candidate, + &validators, + group_validators(GroupIndex::from(2)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + assert_noop!( + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed], + vec![thread_a_assignment.clone()], + &group_validators, + ), + Error::::NotCollatorSigned + ); + } + + // para occupied - reject. + { + let mut candidate = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); + + let backed = back_candidate( + candidate, + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + let candidate = TestCandidateBuilder::default().build(); + >::insert( + &chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: candidate.hash(), + descriptor: candidate.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 3, + backed_in_number: 4, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(0), + }, + ); + >::insert(&chain_a, candidate.commitments); + + assert_noop!( + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed], + vec![chain_a_assignment.clone()], + &group_validators, + ), + Error::::CandidateScheduledBeforeParaFree + ); + + >::remove(&chain_a); + >::remove(&chain_a); + } + + // messed up commitments storage - do not panic - reject. + { + let mut candidate = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); + + // this is not supposed to happen + >::insert(&chain_a, candidate.commitments.clone()); + + let backed = back_candidate( + candidate, + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + assert_noop!( + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed], + vec![chain_a_assignment.clone()], + &group_validators, + ), + Error::::CandidateScheduledBeforeParaFree + ); + + >::remove(&chain_a); + } + + // interfering code upgrade - reject + { + let mut candidate = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + new_validation_code: Some(vec![5, 6, 7, 8].into()), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); + + let backed = back_candidate( + candidate, + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + { + let cfg = Configuration::config(); + let expected_at = 10 + cfg.validation_upgrade_delay; + assert_eq!(expected_at, 12); + Paras::schedule_code_upgrade(chain_a, vec![1, 2, 3, 4].into(), expected_at, &cfg); + } + + assert_noop!( + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed], + vec![chain_a_assignment.clone()], + &group_validators, + ), + Error::::PrematureCodeUpgrade + ); + } + + // Bad validation data hash - reject + { + let mut candidate = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: [42u8; 32].into(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); + + let backed = back_candidate( + candidate, + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + assert_eq!( + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed], + vec![chain_a_assignment.clone()], + &group_validators, + ), + Err(Error::::ValidationDataHashMismatch.into()), + ); + } + + // bad validation code hash + { + let mut candidate = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + validation_code: ValidationCode(vec![1]), + ..Default::default() + } + .build(); + + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); + + let backed = back_candidate( + candidate, + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + assert_noop!( + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed], + vec![chain_a_assignment.clone()], + &group_validators, + ), + Error::::InvalidValidationCodeHash + ); + } + + // Para head hash in descriptor doesn't match head data + { + let mut candidate = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + para_head_hash: Some(Hash::random()), + ..Default::default() + } + .build(); + + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); + + let backed = back_candidate( + candidate, + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + assert_noop!( + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed], + vec![chain_a_assignment.clone()], + &group_validators, + ), + Error::::ParaHeadMismatch + ); + } + }); +} + +#[test] +fn backing_works() { + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + let thread_a = ParaId::from(3_u32); + + // The block number of the relay-parent for testing. + const RELAY_PARENT_NUM: BlockNumber = 4; + + let paras = vec![ + (chain_a, ParaKind::Parachain), + (chain_b, ParaKind::Parachain), + (thread_a, ParaKind::Parathread), + ]; + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + for validator in validators.iter() { + Keystore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); + } + let validator_public = validator_pubkeys(&validators); + + new_test_ext(genesis_config(paras)).execute_with(|| { + shared::Pallet::::set_active_validators_ascending(validator_public.clone()); + shared::Pallet::::set_session_index(5); + + run_to_block(5, |_| None); + + let signing_context = + SigningContext { parent_hash: System::parent_hash(), session_index: 5 }; + + let group_validators = |group_index: GroupIndex| { + match group_index { + group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]), + group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]), + group_index if group_index == GroupIndex::from(2) => Some(vec![4]), + _ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"), + } + .map(|vs| vs.into_iter().map(ValidatorIndex).collect::>()) + }; + + // When processing candidates, we compute the group index from scheduler. + let validator_groups = vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2), ValidatorIndex(3)], + vec![ValidatorIndex(4)], + ]; + Scheduler::set_validator_groups(validator_groups); + + let allowed_relay_parents = default_allowed_relay_parent_tracker(); + + let entry_ttl = 10_000; + let chain_a_assignment = CoreAssignment { + core: CoreIndex::from(0), + paras_entry: ParasEntry::new(Assignment::new(chain_a), entry_ttl), + }; + + let chain_b_assignment = CoreAssignment { + core: CoreIndex::from(1), + paras_entry: ParasEntry::new(Assignment::new(chain_b), entry_ttl), + }; + + let thread_a_assignment = CoreAssignment { + core: CoreIndex::from(2), + paras_entry: ParasEntry::new(Assignment::new(thread_a), entry_ttl), + }; + + let mut candidate_a = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); + + let mut candidate_b = TestCandidateBuilder { + para_id: chain_b, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(2), + persisted_validation_data_hash: make_vdata_hash(chain_b).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_b); + + let mut candidate_c = TestCandidateBuilder { + para_id: thread_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(3), + persisted_validation_data_hash: make_vdata_hash(thread_a).unwrap(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_c); + + let backed_a = back_candidate( + candidate_a.clone(), + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + let backed_b = back_candidate( + candidate_b.clone(), + &validators, + group_validators(GroupIndex::from(1)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + let backed_c = back_candidate( + candidate_c.clone(), + &validators, + group_validators(GroupIndex::from(2)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + let backed_candidates = vec![backed_a.clone(), backed_b.clone(), backed_c]; + let get_backing_group_idx = { + // the order defines the group implicitly for this test case + let backed_candidates_with_groups = backed_candidates + .iter() + .enumerate() + .map(|(idx, backed_candidate)| (backed_candidate.hash(), GroupIndex(idx as _))) + .collect::>(); + + move |candidate_hash_x: CandidateHash| -> Option { + backed_candidates_with_groups.iter().find_map(|(candidate_hash, grp)| { + if *candidate_hash == candidate_hash_x { + Some(*grp) + } else { + None + } + }) + } + }; + + let ProcessedCandidates { + core_indices: occupied_cores, + candidate_receipt_with_backing_validator_indices, + } = ParaInclusion::process_candidates( + &allowed_relay_parents, + backed_candidates.clone(), + vec![ + chain_a_assignment.clone(), + chain_b_assignment.clone(), + thread_a_assignment.clone(), + ], + &group_validators, + ) + .expect("candidates scheduled, in order, and backed"); + + assert_eq!( + occupied_cores, + vec![ + (CoreIndex::from(0), chain_a), + (CoreIndex::from(1), chain_b), + (CoreIndex::from(2), thread_a) + ] + ); + + // Transform the votes into the setup we expect + let expected = { + let mut intermediate = std::collections::HashMap::< + CandidateHash, + (CandidateReceipt, Vec<(ValidatorIndex, ValidityAttestation)>), + >::new(); + backed_candidates.into_iter().for_each(|backed_candidate| { + let candidate_receipt_with_backers = intermediate + .entry(backed_candidate.hash()) + .or_insert_with(|| (backed_candidate.receipt(), Vec::new())); + + assert_eq!( + backed_candidate.validity_votes.len(), + backed_candidate.validator_indices.count_ones() + ); + candidate_receipt_with_backers.1.extend( + backed_candidate + .validator_indices + .iter() + .enumerate() + .filter(|(_, signed)| **signed) + .zip(backed_candidate.validity_votes.iter().cloned()) + .filter_map(|((validator_index_within_group, _), attestation)| { + let grp_idx = get_backing_group_idx(backed_candidate.hash()).unwrap(); + group_validators(grp_idx).map(|validator_indices| { + (validator_indices[validator_index_within_group], attestation) + }) + }), + ); + }); + intermediate.into_values().collect::>() + }; + + // sort, since we use a hashmap above + let assure_candidate_sorting = |mut candidate_receipts_with_backers: Vec<( + CandidateReceipt, + Vec<(ValidatorIndex, ValidityAttestation)>, + )>| { + candidate_receipts_with_backers.sort_by(|(cr1, _), (cr2, _)| { + cr1.descriptor().para_id.cmp(&cr2.descriptor().para_id) + }); + candidate_receipts_with_backers + }; + assert_eq!( + assure_candidate_sorting(expected), + assure_candidate_sorting(candidate_receipt_with_backing_validator_indices) + ); + + let backers = { + let num_backers = minimum_backing_votes(group_validators(GroupIndex(0)).unwrap().len()); + backing_bitfield(&(0..num_backers).collect::>()) + }; + assert_eq!( + >::get(&chain_a), + Some(CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: candidate_a.hash(), + descriptor: candidate_a.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: System::block_number() - 1, + backed_in_number: System::block_number(), + backers, + backing_group: GroupIndex::from(0), + }) + ); + assert_eq!( + >::get(&chain_a), + Some(candidate_a.commitments), + ); + + let backers = { + let num_backers = minimum_backing_votes(group_validators(GroupIndex(0)).unwrap().len()); + backing_bitfield(&(0..num_backers).map(|v| v + 2).collect::>()) + }; + assert_eq!( + >::get(&chain_b), + Some(CandidatePendingAvailability { + core: CoreIndex::from(1), + hash: candidate_b.hash(), + descriptor: candidate_b.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: System::block_number() - 1, + backed_in_number: System::block_number(), + backers, + backing_group: GroupIndex::from(1), + }) + ); + assert_eq!( + >::get(&chain_b), + Some(candidate_b.commitments), + ); + + assert_eq!( + >::get(&thread_a), + Some(CandidatePendingAvailability { + core: CoreIndex::from(2), + hash: candidate_c.hash(), + descriptor: candidate_c.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: System::block_number() - 1, + backed_in_number: System::block_number(), + backers: backing_bitfield(&[4]), + backing_group: GroupIndex::from(2), + }) + ); + assert_eq!( + >::get(&thread_a), + Some(candidate_c.commitments), + ); + }); +} + +#[test] +fn can_include_candidate_with_ok_code_upgrade() { + let chain_a = ParaId::from(1_u32); + + // The block number of the relay-parent for testing. + const RELAY_PARENT_NUM: BlockNumber = 4; + + let paras = vec![(chain_a, ParaKind::Parachain)]; + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + for validator in validators.iter() { + Keystore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); + } + let validator_public = validator_pubkeys(&validators); + + new_test_ext(genesis_config(paras)).execute_with(|| { + shared::Pallet::::set_active_validators_ascending(validator_public.clone()); + shared::Pallet::::set_session_index(5); + + run_to_block(5, |_| None); + + let signing_context = + SigningContext { parent_hash: System::parent_hash(), session_index: 5 }; + + let group_validators = |group_index: GroupIndex| { + match group_index { + group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1, 2, 3, 4]), + _ => panic!("Group index out of bounds for 1 parachain"), + } + .map(|vs| vs.into_iter().map(ValidatorIndex).collect::>()) + }; + + // When processing candidates, we compute the group index from scheduler. + let validator_groups = vec![vec![ + ValidatorIndex(0), + ValidatorIndex(1), + ValidatorIndex(2), + ValidatorIndex(3), + ValidatorIndex(4), + ]]; + Scheduler::set_validator_groups(validator_groups); + + let allowed_relay_parents = default_allowed_relay_parent_tracker(); + let entry_ttl = 10_000; + let chain_a_assignment = CoreAssignment { + core: CoreIndex::from(0), + paras_entry: ParasEntry::new(Assignment::new(chain_a), entry_ttl), + }; + + let mut candidate_a = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + new_validation_code: Some(vec![1, 2, 3].into()), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); + + let backed_a = back_candidate( + candidate_a.clone(), + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + let ProcessedCandidates { core_indices: occupied_cores, .. } = + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed_a], + vec![chain_a_assignment.clone()], + &group_validators, + ) + .expect("candidates scheduled, in order, and backed"); + + assert_eq!(occupied_cores, vec![(CoreIndex::from(0), chain_a)]); + + let backers = { + let num_backers = minimum_backing_votes(group_validators(GroupIndex(0)).unwrap().len()); + backing_bitfield(&(0..num_backers).collect::>()) + }; + assert_eq!( + >::get(&chain_a), + Some(CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: candidate_a.hash(), + descriptor: candidate_a.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: System::block_number() - 1, + backed_in_number: System::block_number(), + backers, + backing_group: GroupIndex::from(0), + }) + ); + assert_eq!( + >::get(&chain_a), + Some(candidate_a.commitments), + ); + }); +} + +#[test] +fn check_allowed_relay_parents() { + let chain_a = ParaId::from(1); + let chain_b = ParaId::from(2); + let thread_a = ParaId::from(3); + + let paras = vec![ + (chain_a, ParaKind::Parachain), + (chain_b, ParaKind::Parachain), + (thread_a, ParaKind::Parathread), + ]; + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + for validator in validators.iter() { + Keystore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); + } + let validator_public = validator_pubkeys(&validators); + let mut config = genesis_config(paras); + config.configuration.config.group_rotation_frequency = 1; + + new_test_ext(config).execute_with(|| { + shared::Pallet::::set_active_validators_ascending(validator_public.clone()); + shared::Pallet::::set_session_index(5); + + run_to_block(5, |_| None); + + let group_validators = |group_index: GroupIndex| { + match group_index { + group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]), + group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]), + group_index if group_index == GroupIndex::from(2) => Some(vec![4]), + _ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"), + } + .map(|vs| vs.into_iter().map(ValidatorIndex).collect::>()) + }; + + // When processing candidates, we compute the group index from scheduler. + let validator_groups = vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2), ValidatorIndex(3)], + vec![ValidatorIndex(4)], + ]; + Scheduler::set_validator_groups(validator_groups); + + // Base each candidate on one of allowed relay parents. + // + // Note that the group rotation frequency is set to 1 above, + // which means groups shift at each relay parent. + // + // For example, candidate `a` is based on block 1, + // thus it will be included in block 2, its group index is + // core = 0 shifted 2 times: one for group rotation and one for + // fetching the group assigned to the next block. + // + // Candidates `b` and `c` are constructed accordingly. + + let relay_parent_a = (1, Hash::repeat_byte(0x1)); + let relay_parent_b = (2, Hash::repeat_byte(0x2)); + let relay_parent_c = (3, Hash::repeat_byte(0x3)); + + let mut allowed_relay_parents = AllowedRelayParentsTracker::default(); + let max_ancestry_len = 3; + allowed_relay_parents.update( + relay_parent_a.1, + Hash::zero(), + relay_parent_a.0, + max_ancestry_len, + ); + allowed_relay_parents.update( + relay_parent_b.1, + Hash::zero(), + relay_parent_b.0, + max_ancestry_len, + ); + allowed_relay_parents.update( + relay_parent_c.1, + Hash::zero(), + relay_parent_c.0, + max_ancestry_len, + ); + + let chain_a_assignment = CoreAssignment { + core: CoreIndex::from(0), + paras_entry: ParasEntry { + assignment: Assignment { para_id: chain_a }, + availability_timeouts: 0, + ttl: 5, + }, + }; + + let chain_b_assignment = CoreAssignment { + core: CoreIndex::from(1), + paras_entry: ParasEntry { + assignment: Assignment { para_id: chain_b }, + availability_timeouts: 0, + ttl: 5, + }, + }; + + let thread_a_assignment = CoreAssignment { + core: CoreIndex::from(2), + paras_entry: ParasEntry::new(Assignment::new(thread_a), 5), + }; + + let mut candidate_a = TestCandidateBuilder { + para_id: chain_a, + relay_parent: relay_parent_a.1, + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash_with_block_number( + chain_a, + relay_parent_a.0, + ) + .unwrap(), + hrmp_watermark: relay_parent_a.0, + ..Default::default() + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); + let signing_context_a = SigningContext { parent_hash: relay_parent_a.1, session_index: 5 }; + + let mut candidate_b = TestCandidateBuilder { + para_id: chain_b, + relay_parent: relay_parent_b.1, + pov_hash: Hash::repeat_byte(2), + persisted_validation_data_hash: make_vdata_hash_with_block_number( + chain_b, + relay_parent_b.0, + ) + .unwrap(), + hrmp_watermark: relay_parent_b.0, + ..Default::default() + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_b); + let signing_context_b = SigningContext { parent_hash: relay_parent_b.1, session_index: 5 }; + + let mut candidate_c = TestCandidateBuilder { + para_id: thread_a, + relay_parent: relay_parent_c.1, + pov_hash: Hash::repeat_byte(3), + persisted_validation_data_hash: make_vdata_hash_with_block_number( + thread_a, + relay_parent_c.0, + ) + .unwrap(), + hrmp_watermark: relay_parent_c.0, + ..Default::default() + } + .build(); + collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_c); + let signing_context_c = SigningContext { parent_hash: relay_parent_c.1, session_index: 5 }; + + let backed_a = back_candidate( + candidate_a.clone(), + &validators, + group_validators(GroupIndex::from(2)).unwrap().as_ref(), + &keystore, + &signing_context_a, + BackingKind::Threshold, + ); + + let backed_b = back_candidate( + candidate_b.clone(), + &validators, + group_validators(GroupIndex::from(1)).unwrap().as_ref(), + &keystore, + &signing_context_b, + BackingKind::Threshold, + ); + + let backed_c = back_candidate( + candidate_c.clone(), + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context_c, + BackingKind::Threshold, + ); + + let backed_candidates = vec![backed_a, backed_b, backed_c]; + + ParaInclusion::process_candidates( + &allowed_relay_parents, + backed_candidates.clone(), + vec![ + chain_a_assignment.clone(), + chain_b_assignment.clone(), + thread_a_assignment.clone(), + ], + &group_validators, + ) + .expect("candidates scheduled, in order, and backed"); + }); +} + +#[test] +fn session_change_wipes() { + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + let thread_a = ParaId::from(3_u32); + + let paras = vec![ + (chain_a, ParaKind::Parachain), + (chain_b, ParaKind::Parachain), + (thread_a, ParaKind::Parathread), + ]; + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + for validator in validators.iter() { + Keystore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); + } + let validator_public = validator_pubkeys(&validators); + + new_test_ext(genesis_config(paras)).execute_with(|| { + shared::Pallet::::set_active_validators_ascending(validator_public.clone()); + shared::Pallet::::set_session_index(5); + + let validators_new = + vec![Sr25519Keyring::Alice, Sr25519Keyring::Bob, Sr25519Keyring::Charlie]; + + let validator_public_new = validator_pubkeys(&validators_new); + + run_to_block(10, |_| None); + + >::insert( + &ValidatorIndex(0), + AvailabilityBitfieldRecord { bitfield: default_bitfield(), submitted_at: 9 }, + ); + + >::insert( + &ValidatorIndex(1), + AvailabilityBitfieldRecord { bitfield: default_bitfield(), submitted_at: 9 }, + ); + + >::insert( + &ValidatorIndex(4), + AvailabilityBitfieldRecord { bitfield: default_bitfield(), submitted_at: 9 }, + ); + + let candidate = TestCandidateBuilder::default().build(); + >::insert( + &chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: candidate.hash(), + descriptor: candidate.descriptor.clone(), + availability_votes: default_availability_votes(), + relay_parent_number: 5, + backed_in_number: 6, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(0), + }, + ); + >::insert(&chain_a, candidate.commitments.clone()); + + >::insert( + &chain_b, + CandidatePendingAvailability { + core: CoreIndex::from(1), + hash: candidate.hash(), + descriptor: candidate.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 6, + backed_in_number: 7, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(1), + }, + ); + >::insert(&chain_b, candidate.commitments); + + run_to_block(11, |_| None); + + assert_eq!(shared::Pallet::::session_index(), 5); + + assert!(>::get(&ValidatorIndex(0)).is_some()); + assert!(>::get(&ValidatorIndex(1)).is_some()); + assert!(>::get(&ValidatorIndex(4)).is_some()); + + assert!(>::get(&chain_a).is_some()); + assert!(>::get(&chain_b).is_some()); + assert!(>::get(&chain_a).is_some()); + assert!(>::get(&chain_b).is_some()); + + run_to_block(12, |n| match n { + 12 => Some(SessionChangeNotification { + validators: validator_public_new.clone(), + queued: Vec::new(), + prev_config: default_config(), + new_config: default_config(), + random_seed: Default::default(), + session_index: 6, + }), + _ => None, + }); + + assert_eq!(shared::Pallet::::session_index(), 6); + + assert!(>::get(&ValidatorIndex(0)).is_none()); + assert!(>::get(&ValidatorIndex(1)).is_none()); + assert!(>::get(&ValidatorIndex(4)).is_none()); + + assert!(>::get(&chain_a).is_none()); + assert!(>::get(&chain_b).is_none()); + assert!(>::get(&chain_a).is_none()); + assert!(>::get(&chain_b).is_none()); + + assert!(>::iter().collect::>().is_empty()); + assert!(>::iter().collect::>().is_empty()); + assert!(>::iter().collect::>().is_empty()); + }); +} + +/// Assert that the encoding of a known `AggregateMessageOrigin` did not change. +#[test] +fn aggregate_origin_decode_regression_check() { + let ump = AggregateMessageOrigin::Ump(UmpQueueId::Para(u32::MAX.into())); + let raw = (0u8, 0u8, u32::MAX).encode(); + let decoded = AggregateMessageOrigin::decode_all(&mut &raw[..]); + assert_eq!(decoded, Ok(ump), "Migration needed for AggregateMessageOrigin"); +} + +#[test] +fn para_upgrade_delay_scheduled_from_inclusion() { + let chain_a = ParaId::from(1_u32); + + // The block number of the relay-parent for testing. + const RELAY_PARENT_NUM: BlockNumber = 4; + + let paras = vec![(chain_a, ParaKind::Parachain)]; + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + for validator in validators.iter() { + Keystore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); + } + let validator_public = validator_pubkeys(&validators); + + new_test_ext(genesis_config(paras)).execute_with(|| { + shared::Pallet::::set_active_validators_ascending(validator_public.clone()); + shared::Pallet::::set_session_index(5); + + let new_validation_code: ValidationCode = vec![1, 2, 3, 4, 5].into(); + let new_validation_code_hash = new_validation_code.hash(); + + // Otherwise upgrade is no-op. + assert_ne!(new_validation_code, dummy_validation_code()); + + run_to_block(5, |_| None); + + let signing_context = + SigningContext { parent_hash: System::parent_hash(), session_index: 5 }; + + let group_validators = |group_index: GroupIndex| { + match group_index { + group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1, 2, 3, 4]), + _ => panic!("Group index out of bounds for 1 parachain"), + } + .map(|vs| vs.into_iter().map(ValidatorIndex).collect::>()) + }; + + // When processing candidates, we compute the group index from scheduler. + let validator_groups = vec![vec![ + ValidatorIndex(0), + ValidatorIndex(1), + ValidatorIndex(2), + ValidatorIndex(3), + ValidatorIndex(4), + ]]; + Scheduler::set_validator_groups(validator_groups); + + let core_lookup = |core| match core { + core if core == CoreIndex::from(0) => Some(chain_a), + _ => None, + }; + + let allowed_relay_parents = default_allowed_relay_parent_tracker(); + + let chain_a_assignment = CoreAssignment { + core: CoreIndex::from(0), + paras_entry: ParasEntry { + assignment: Assignment { para_id: chain_a }, + availability_timeouts: 0, + ttl: 5, + }, + }; + + let mut candidate_a = TestCandidateBuilder { + para_id: chain_a, + relay_parent: System::parent_hash(), + pov_hash: Hash::repeat_byte(1), + persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), + new_validation_code: Some(new_validation_code.clone()), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); + + let backed_a = back_candidate( + candidate_a.clone(), + &validators, + group_validators(GroupIndex::from(0)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + + let ProcessedCandidates { core_indices: occupied_cores, .. } = + ParaInclusion::process_candidates( + &allowed_relay_parents, + vec![backed_a], + vec![chain_a_assignment.clone()], + &group_validators, + ) + .expect("candidates scheduled, in order, and backed"); + + assert_eq!(occupied_cores, vec![(CoreIndex::from(0), chain_a)]); + + // Run a couple of blocks before the inclusion. + run_to_block(7, |_| None); + + let mut bare_bitfield = default_bitfield(); + *bare_bitfield.0.get_mut(0).unwrap() = true; + + let signed_bitfields = validators + .iter() + .enumerate() + .map(|(i, key)| { + sign_bitfield( + &keystore, + key, + ValidatorIndex(i as _), + bare_bitfield.clone(), + &signing_context, + ) + .into() + }) + .collect::>(); + + let checked_bitfields = simple_sanitize_bitfields( + signed_bitfields, + DisputedBitfield::zeros(expected_bits()), + expected_bits(), + ); + + let v = process_bitfields(expected_bits(), checked_bitfields, core_lookup); + assert_eq!(vec![(CoreIndex(0), candidate_a.hash())], v); + + assert!(>::get(&chain_a).is_none()); + assert!(>::get(&chain_a).is_none()); + + let active_vote_state = paras::Pallet::::active_vote_state(&new_validation_code_hash) + .expect("prechecking must be initiated"); + + let cause = &active_vote_state.causes()[0]; + // Upgrade block is the block of inclusion, not candidate's parent. + assert_matches!(cause, + paras::PvfCheckCause::Upgrade { id, included_at } + if id == &chain_a && included_at == &7 + ); + }); +} diff --git a/polkadot/runtime/parachains/src/initializer.rs b/polkadot/runtime/parachains/src/initializer.rs new file mode 100644 index 0000000000000000000000000000000000000000..b4f8721be5188e6fd8840e18accdfcaababdf61a --- /dev/null +++ b/polkadot/runtime/parachains/src/initializer.rs @@ -0,0 +1,341 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This module is responsible for maintaining a consistent initialization order for all other +//! parachains modules. It's also responsible for finalization and session change notifications. +//! +//! This module can throw fatal errors if session-change notifications are received after +//! initialization. + +use crate::{ + configuration::{self, HostConfiguration}, + disputes::{self, DisputesHandler as _, SlashingHandler as _}, + dmp, hrmp, inclusion, paras, scheduler, session_info, shared, +}; +use frame_support::{ + traits::{OneSessionHandler, Randomness}, + weights::Weight, +}; +use frame_system::limits::BlockWeights; +use parity_scale_codec::{Decode, Encode}; +use primitives::{BlockNumber, ConsensusLog, SessionIndex, ValidatorId}; +use scale_info::TypeInfo; +use sp_std::prelude::*; + +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +pub use pallet::*; + +/// Information about a session change that has just occurred. +#[derive(Clone)] +pub struct SessionChangeNotification { + /// The new validators in the session. + pub validators: Vec, + /// The queued validators for the following session. + pub queued: Vec, + /// The configuration before handling the session change + pub prev_config: HostConfiguration, + /// The configuration after handling the session change. + pub new_config: HostConfiguration, + /// A secure random seed for the session, gathered from BABE. + pub random_seed: [u8; 32], + /// New session index. + pub session_index: SessionIndex, +} + +/// Number of validators (not only parachain) in a session. +pub type ValidatorSetCount = u32; + +impl> Default for SessionChangeNotification { + fn default() -> Self { + Self { + validators: Vec::new(), + queued: Vec::new(), + prev_config: HostConfiguration::default(), + new_config: HostConfiguration::default(), + random_seed: Default::default(), + session_index: Default::default(), + } + } +} + +#[derive(Encode, Decode, TypeInfo)] +struct BufferedSessionChange { + validators: Vec, + queued: Vec, + session_index: SessionIndex, +} + +pub trait WeightInfo { + fn force_approve(d: u32) -> Weight; +} + +impl WeightInfo for () { + fn force_approve(_: u32) -> Weight { + BlockWeights::default().max_block + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: + frame_system::Config + + configuration::Config + + shared::Config + + paras::Config + + scheduler::Config + + inclusion::Config + + session_info::Config + + disputes::Config + + dmp::Config + + hrmp::Config + { + /// A randomness beacon. + type Randomness: Randomness>; + /// An origin which is allowed to force updates to parachains. + type ForceOrigin: EnsureOrigin<::RuntimeOrigin>; + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + /// Whether the parachains modules have been initialized within this block. + /// + /// Semantically a `bool`, but this guarantees it should never hit the trie, + /// as this is cleared in `on_finalize` and Frame optimizes `None` values to be empty values. + /// + /// As a `bool`, `set(false)` and `remove()` both lead to the next `get()` being false, but one + /// of them writes to the trie and one does not. This confusion makes `Option<()>` more suitable + /// for the semantics of this variable. + #[pallet::storage] + pub(super) type HasInitialized = StorageValue<_, ()>; + + /// Buffered session changes along with the block number at which they should be applied. + /// + /// Typically this will be empty or one element long. Apart from that this item never hits + /// the storage. + /// + /// However this is a `Vec` regardless to handle various edge cases that may occur at runtime + /// upgrade boundaries or if governance intervenes. + #[pallet::storage] + pub(super) type BufferedSessionChanges = + StorageValue<_, Vec, ValueQuery>; + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(now: BlockNumberFor) -> Weight { + // The other modules are initialized in this order: + // - Configuration + // - Paras + // - Scheduler + // - Inclusion + // - `SessionInfo` + // - Disputes + // - DMP + // - UMP + // - HRMP + let total_weight = configuration::Pallet::::initializer_initialize(now) + + shared::Pallet::::initializer_initialize(now) + + paras::Pallet::::initializer_initialize(now) + + scheduler::Pallet::::initializer_initialize(now) + + inclusion::Pallet::::initializer_initialize(now) + + session_info::Pallet::::initializer_initialize(now) + + T::DisputesHandler::initializer_initialize(now) + + T::SlashingHandler::initializer_initialize(now) + + dmp::Pallet::::initializer_initialize(now) + + hrmp::Pallet::::initializer_initialize(now); + + HasInitialized::::set(Some(())); + + total_weight + } + + fn on_finalize(now: BlockNumberFor) { + // reverse initialization order. + hrmp::Pallet::::initializer_finalize(); + dmp::Pallet::::initializer_finalize(); + T::SlashingHandler::initializer_finalize(); + T::DisputesHandler::initializer_finalize(); + session_info::Pallet::::initializer_finalize(); + inclusion::Pallet::::initializer_finalize(); + scheduler::Pallet::::initializer_finalize(); + paras::Pallet::::initializer_finalize(now); + shared::Pallet::::initializer_finalize(); + configuration::Pallet::::initializer_finalize(); + + // Apply buffered session changes as the last thing. This way the runtime APIs and the + // next block will observe the next session. + // + // Note that we only apply the last session as all others lasted less than a block + // (weirdly). + if let Some(BufferedSessionChange { session_index, validators, queued }) = + BufferedSessionChanges::::take().pop() + { + Self::apply_new_session(session_index, validators, queued); + } + + HasInitialized::::take(); + } + } + + #[pallet::call] + impl Pallet { + /// Issue a signal to the consensus engine to forcibly act as though all parachain + /// blocks in all relay chain blocks up to and including the given number in the current + /// chain are valid and should be finalized. + #[pallet::call_index(0)] + #[pallet::weight(( + ::WeightInfo::force_approve( + frame_system::Pallet::::digest().logs.len() as u32, + ), + DispatchClass::Operational, + ))] + pub fn force_approve(origin: OriginFor, up_to: BlockNumber) -> DispatchResult { + T::ForceOrigin::ensure_origin(origin)?; + + frame_system::Pallet::::deposit_log(ConsensusLog::ForceApprove(up_to).into()); + Ok(()) + } + } +} + +impl Pallet { + fn apply_new_session( + session_index: SessionIndex, + all_validators: Vec, + queued: Vec, + ) { + let random_seed = { + let mut buf = [0u8; 32]; + // TODO: audit usage of randomness API + // https://github.com/paritytech/polkadot/issues/2601 + let (random_hash, _) = T::Randomness::random(&b"paras"[..]); + let len = sp_std::cmp::min(32, random_hash.as_ref().len()); + buf[..len].copy_from_slice(&random_hash.as_ref()[..len]); + buf + }; + + // inform about upcoming new session + scheduler::Pallet::::pre_new_session(); + + let configuration::SessionChangeOutcome { prev_config, new_config } = + configuration::Pallet::::initializer_on_new_session(&session_index); + let new_config = new_config.unwrap_or_else(|| prev_config.clone()); + + let validators = shared::Pallet::::initializer_on_new_session( + session_index, + random_seed, + &new_config, + all_validators, + ); + + let notification = SessionChangeNotification { + validators, + queued, + prev_config, + new_config, + random_seed, + session_index, + }; + + let outgoing_paras = paras::Pallet::::initializer_on_new_session(¬ification); + scheduler::Pallet::::initializer_on_new_session(¬ification); + inclusion::Pallet::::initializer_on_new_session(¬ification, &outgoing_paras); + session_info::Pallet::::initializer_on_new_session(¬ification); + T::DisputesHandler::initializer_on_new_session(¬ification); + T::SlashingHandler::initializer_on_new_session(session_index); + dmp::Pallet::::initializer_on_new_session(¬ification, &outgoing_paras); + hrmp::Pallet::::initializer_on_new_session(¬ification, &outgoing_paras); + } + + /// Should be called when a new session occurs. Buffers the session notification to be applied + /// at the end of the block. If `queued` is `None`, the `validators` are considered queued. + fn on_new_session<'a, I: 'a>( + _changed: bool, + session_index: SessionIndex, + validators: I, + queued: Option, + ) where + I: Iterator, + { + let validators: Vec<_> = validators.map(|(_, v)| v).collect(); + let queued: Vec<_> = if let Some(queued) = queued { + queued.map(|(_, v)| v).collect() + } else { + validators.clone() + }; + + if session_index == 0 { + // Genesis session should be immediately enacted. + Self::apply_new_session(0, validators, queued); + } else { + BufferedSessionChanges::::mutate(|v| { + v.push(BufferedSessionChange { validators, queued, session_index }) + }); + } + } + + // Allow to trigger `on_new_session` in tests, this is needed as long as `pallet_session` is not + // implemented in mock. + #[cfg(any(test, feature = "runtime-benchmarks"))] + pub(crate) fn test_trigger_on_new_session<'a, I: 'a>( + changed: bool, + session_index: SessionIndex, + validators: I, + queued: Option, + ) where + I: Iterator, + { + Self::on_new_session(changed, session_index, validators, queued) + } +} + +impl sp_runtime::BoundToRuntimeAppPublic for Pallet { + type Public = ValidatorId; +} + +impl OneSessionHandler for Pallet { + type Key = ValidatorId; + + fn on_genesis_session<'a, I: 'a>(validators: I) + where + I: Iterator, + { + >::on_new_session(false, 0, validators, None); + } + + fn on_new_session<'a, I: 'a>(changed: bool, validators: I, queued: I) + where + I: Iterator, + { + let session_index = >::current_index(); + >::on_new_session(changed, session_index, validators, Some(queued)); + } + + fn on_disabled(_i: u32) {} +} diff --git a/polkadot/runtime/parachains/src/initializer/benchmarking.rs b/polkadot/runtime/parachains/src/initializer/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..dd87ce9c9d974332bf7213ff3311fdb38adfbca9 --- /dev/null +++ b/polkadot/runtime/parachains/src/initializer/benchmarking.rs @@ -0,0 +1,45 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use frame_benchmarking::benchmarks; +use frame_system::RawOrigin; +use primitives::ConsensusLog; +use sp_runtime::DigestItem; + +// Random large number for the digest +const DIGEST_MAX_LEN: u32 = 65536; + +benchmarks! { + force_approve { + let d in 0 .. DIGEST_MAX_LEN; + for _ in 0 .. d { + >::deposit_log(ConsensusLog::ForceApprove(d).into()); + } + }: _(RawOrigin::Root, d + 1) + verify { + assert_eq!( + >::digest().logs.last().unwrap(), + &DigestItem::from(ConsensusLog::ForceApprove(d + 1)), + ); + } + + impl_benchmark_test_suite!( + Pallet, + crate::mock::new_test_ext(Default::default()), + crate::mock::Test + ); +} diff --git a/polkadot/runtime/parachains/src/initializer/tests.rs b/polkadot/runtime/parachains/src/initializer/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..b0993d739fa9a9dbb22d25ee62861f37ce1152e2 --- /dev/null +++ b/polkadot/runtime/parachains/src/initializer/tests.rs @@ -0,0 +1,133 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::mock::{ + new_test_ext, Configuration, Dmp, Initializer, MockGenesisConfig, Paras, SessionInfo, System, + Test, +}; +use primitives::{HeadData, Id as ParaId}; +use test_helpers::dummy_validation_code; + +use crate::paras::ParaKind; +use frame_support::{ + assert_ok, + traits::{OnFinalize, OnInitialize}, +}; + +#[test] +fn session_0_is_instantly_applied() { + new_test_ext(Default::default()).execute_with(|| { + Initializer::on_new_session(false, 0, Vec::new().into_iter(), Some(Vec::new().into_iter())); + + let v = BufferedSessionChanges::::get(); + assert!(v.is_empty()); + + assert_eq!(SessionInfo::earliest_stored_session(), 0); + assert!(SessionInfo::session_info(0).is_some()); + }); +} + +#[test] +fn session_change_before_initialize_is_still_buffered_after() { + new_test_ext(Default::default()).execute_with(|| { + Initializer::on_new_session(false, 1, Vec::new().into_iter(), Some(Vec::new().into_iter())); + + let now = System::block_number(); + Initializer::on_initialize(now); + + let v = BufferedSessionChanges::::get(); + assert_eq!(v.len(), 1); + }); +} + +#[test] +fn session_change_applied_on_finalize() { + new_test_ext(Default::default()).execute_with(|| { + Initializer::on_initialize(1); + Initializer::on_new_session(false, 1, Vec::new().into_iter(), Some(Vec::new().into_iter())); + + Initializer::on_finalize(1); + + assert!(BufferedSessionChanges::::get().is_empty()); + }); +} + +#[test] +fn sets_flag_on_initialize() { + new_test_ext(Default::default()).execute_with(|| { + Initializer::on_initialize(1); + + assert!(HasInitialized::::get().is_some()); + }) +} + +#[test] +fn clears_flag_on_finalize() { + new_test_ext(Default::default()).execute_with(|| { + Initializer::on_initialize(1); + Initializer::on_finalize(1); + + assert!(HasInitialized::::get().is_none()); + }) +} + +#[test] +fn scheduled_cleanup_performed() { + let a = ParaId::from(1312); + let b = ParaId::from(228); + let c = ParaId::from(123); + + let mock_genesis = crate::paras::ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: HeadData(vec![4, 5, 6]), + validation_code: dummy_validation_code(), + }; + + new_test_ext(MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: crate::configuration::HostConfiguration { + max_downward_message_size: 1024, + ..Default::default() + }, + }, + paras: crate::paras::GenesisConfig { + paras: vec![ + (a, mock_genesis.clone()), + (b, mock_genesis.clone()), + (c, mock_genesis.clone()), + ], + ..Default::default() + }, + ..Default::default() + }) + .execute_with(|| { + // enqueue downward messages to A, B and C. + assert_ok!(Dmp::queue_downward_message(&Configuration::config(), a, vec![1, 2, 3])); + assert_ok!(Dmp::queue_downward_message(&Configuration::config(), b, vec![4, 5, 6])); + assert_ok!(Dmp::queue_downward_message(&Configuration::config(), c, vec![7, 8, 9])); + + assert_ok!(Paras::schedule_para_cleanup(a)); + assert_ok!(Paras::schedule_para_cleanup(b)); + + // Apply session 2 in the future + Initializer::apply_new_session(2, vec![], vec![]); + + assert!(Dmp::dmq_contents(a).is_empty()); + assert!(Dmp::dmq_contents(b).is_empty()); + assert!(!Dmp::dmq_contents(c).is_empty()); + }); +} diff --git a/polkadot/runtime/parachains/src/lib.rs b/polkadot/runtime/parachains/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..056eef35426098532663ee0f3e727fac3a3e5d16 --- /dev/null +++ b/polkadot/runtime/parachains/src/lib.rs @@ -0,0 +1,107 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Runtime modules for parachains code. +//! +//! It is crucial to include all the modules from this crate in the runtime, in +//! particular the `Initializer` module, as it is responsible for initializing the state +//! of the other modules. + +#![cfg_attr(feature = "runtime-benchmarks", recursion_limit = "256")] +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod assigner; +pub mod assigner_on_demand; +pub mod assigner_parachains; +pub mod configuration; +pub mod disputes; +pub mod dmp; +pub mod hrmp; +pub mod inclusion; +pub mod initializer; +pub mod metrics; +pub mod origin; +pub mod paras; +pub mod paras_inherent; +pub mod reward_points; +pub mod scheduler; +pub mod session_info; +pub mod shared; + +pub mod runtime_api_impl; + +mod util; + +#[cfg(any(feature = "runtime-benchmarks", test))] +mod builder; +#[cfg(test)] +mod mock; +#[cfg(test)] +mod ump_tests; + +pub use origin::{ensure_parachain, Origin}; +pub use paras::ParaLifecycle; +use primitives::{HeadData, Id as ParaId, ValidationCode}; +use sp_runtime::{DispatchResult, FixedU128}; + +/// Trait for tracking message delivery fees on a transport protocol. +pub trait FeeTracker { + fn get_fee_factor(para: ParaId) -> FixedU128; +} + +/// Schedule a para to be initialized at the start of the next session with the given genesis data. +/// +/// See [`paras::Pallet::schedule_para_initialize`] for more details. +pub fn schedule_para_initialize( + id: ParaId, + genesis: paras::ParaGenesisArgs, +) -> Result<(), ()> { + >::schedule_para_initialize(id, genesis).map_err(|_| ()) +} + +/// Schedule a para to be cleaned up at the start of the next session. +/// +/// See [`paras::Pallet::schedule_para_cleanup`] for more details. +pub fn schedule_para_cleanup(id: primitives::Id) -> Result<(), ()> { + >::schedule_para_cleanup(id).map_err(|_| ()) +} + +/// Schedule a parathread (on-demand parachain) to be upgraded to a lease holding parachain. +pub fn schedule_parathread_upgrade(id: ParaId) -> Result<(), ()> { + paras::Pallet::::schedule_parathread_upgrade(id).map_err(|_| ()) +} + +/// Schedule a lease holding parachain to be downgraded to an on-demand parachain. +pub fn schedule_parachain_downgrade(id: ParaId) -> Result<(), ()> { + paras::Pallet::::schedule_parachain_downgrade(id).map_err(|_| ()) +} + +/// Schedules a validation code upgrade to a parachain with the given id. +/// +/// This simply calls [`crate::paras::Pallet::schedule_code_upgrade_external`]. +pub fn schedule_code_upgrade( + id: ParaId, + new_code: ValidationCode, +) -> DispatchResult { + paras::Pallet::::schedule_code_upgrade_external(id, new_code) +} + +/// Sets the current parachain head with the given id. +/// +/// This simply calls [`crate::paras::Pallet::set_current_head`]. +pub fn set_current_head(id: ParaId, new_head: HeadData) { + paras::Pallet::::set_current_head(id, new_head) +} diff --git a/polkadot/runtime/parachains/src/metrics.rs b/polkadot/runtime/parachains/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..023bd09f83a82577662eff7c2d95b82b39411dd3 --- /dev/null +++ b/polkadot/runtime/parachains/src/metrics.rs @@ -0,0 +1,114 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Runtime declaration of the parachain metrics. + +use polkadot_runtime_metrics::{Counter, CounterVec, Histogram}; +use primitives::metric_definitions::{ + PARACHAIN_CREATE_INHERENT_BITFIELDS_SIGNATURE_CHECKS, + PARACHAIN_INHERENT_DATA_BITFIELDS_PROCESSED, PARACHAIN_INHERENT_DATA_CANDIDATES_PROCESSED, + PARACHAIN_INHERENT_DATA_DISPUTE_SETS_PROCESSED, PARACHAIN_INHERENT_DATA_WEIGHT, + PARACHAIN_VERIFY_DISPUTE_SIGNATURE, +}; + +pub struct Metrics { + /// Samples inherent data weight. + inherent_data_weight: CounterVec, + /// Counts how many inherent bitfields processed in `process_inherent_data`. + bitfields_processed: Counter, + /// Counts how many parachain candidates processed in `process_inherent_data`. + candidates_processed: CounterVec, + /// Counts dispute statements sets processed in `process_inherent_data`. + dispute_sets_processed: CounterVec, + /// Counts bitfield signature checks in `process_inherent_data`. + bitfields_signature_checks: CounterVec, + + /// Histogram with the time spent checking a validator signature of a dispute statement + signature_timings: Histogram, +} + +impl Metrics { + /// Sample the inherent data weight metric before filtering. + pub fn on_before_filter(&self, value: u64) { + self.inherent_data_weight.with_label_values(&["before-filter"]).inc_by(value); + } + + /// Sample the inherent data weight metric after filtering. + pub fn on_after_filter(&self, value: u64) { + self.inherent_data_weight.with_label_values(&["after-filter"]).inc_by(value); + } + + /// Increment the number of bitfields processed. + pub fn on_bitfields_processed(&self, value: u64) { + self.bitfields_processed.inc_by(value); + } + + /// Increment the number of parachain candidates included. + pub fn on_candidates_included(&self, value: u64) { + self.candidates_processed.with_label_values(&["included"]).inc_by(value); + } + + /// Increment the number of parachain candidates sanitized. + pub fn on_candidates_sanitized(&self, value: u64) { + self.candidates_processed.with_label_values(&["sanitized"]).inc_by(value); + } + + /// Increment the total number of parachain candidates received in `process_inherent_data`. + pub fn on_candidates_processed_total(&self, value: u64) { + self.candidates_processed.with_label_values(&["total"]).inc_by(value); + } + + /// Sample the relay chain freeze events causing runtime to not process candidates in + /// `process_inherent_data`. + pub fn on_relay_chain_freeze(&self) { + self.dispute_sets_processed.with_label_values(&["frozen"]).inc(); + } + + /// Increment the number of disputes that have concluded as invalid. + pub fn on_disputes_concluded_invalid(&self, value: u64) { + self.dispute_sets_processed + .with_label_values(&["concluded_invalid"]) + .inc_by(value); + } + + /// Increment the number of disputes imported. + pub fn on_disputes_imported(&self, value: u64) { + self.dispute_sets_processed.with_label_values(&["imported"]).inc_by(value); + } + + pub fn on_valid_bitfield_signature(&self) { + self.bitfields_signature_checks.with_label_values(&["valid"]).inc_by(1); + } + + pub fn on_invalid_bitfield_signature(&self) { + self.bitfields_signature_checks.with_label_values(&["invalid"]).inc_by(1); + } + + pub fn on_signature_check_complete(&self, val: u128) { + self.signature_timings.observe(val); + } +} + +pub const METRICS: Metrics = Metrics { + inherent_data_weight: CounterVec::new(PARACHAIN_INHERENT_DATA_WEIGHT), + bitfields_processed: Counter::new(PARACHAIN_INHERENT_DATA_BITFIELDS_PROCESSED), + candidates_processed: CounterVec::new(PARACHAIN_INHERENT_DATA_CANDIDATES_PROCESSED), + dispute_sets_processed: CounterVec::new(PARACHAIN_INHERENT_DATA_DISPUTE_SETS_PROCESSED), + bitfields_signature_checks: CounterVec::new( + PARACHAIN_CREATE_INHERENT_BITFIELDS_SIGNATURE_CHECKS, + ), + signature_timings: Histogram::new(PARACHAIN_VERIFY_DISPUTE_SIGNATURE), +}; diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..f978b6c3360e49d9755267b56e34328102326caf --- /dev/null +++ b/polkadot/runtime/parachains/src/mock.rs @@ -0,0 +1,580 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Mocks for all the traits. + +use crate::{ + assigner, assigner_on_demand, assigner_parachains, configuration, disputes, dmp, hrmp, + inclusion::{self, AggregateMessageOrigin, UmpQueueId}, + initializer, origin, paras, + paras::ParaKind, + paras_inherent, scheduler, session_info, shared, ParaId, +}; + +use frame_support::{ + assert_ok, parameter_types, + traits::{ + Currency, ProcessMessage, ProcessMessageError, ValidatorSet, ValidatorSetWithIdentification, + }, + weights::{Weight, WeightMeter}, +}; +use frame_support_test::TestRandomness; +use frame_system::limits; +use parity_scale_codec::Decode; +use primitives::{ + AuthorityDiscoveryId, Balance, BlockNumber, CandidateHash, Moment, SessionIndex, UpwardMessage, + ValidationCode, ValidatorIndex, +}; +use sp_core::{ConstU32, H256}; +use sp_io::TestExternalities; +use sp_runtime::{ + traits::{AccountIdConversion, BlakeTwo256, IdentityLookup}, + transaction_validity::TransactionPriority, + BuildStorage, FixedU128, Perbill, Permill, +}; +use std::{cell::RefCell, collections::HashMap}; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlockU32; + +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + Balances: pallet_balances, + MessageQueue: pallet_message_queue, + Paras: paras, + Configuration: configuration, + ParasShared: shared, + ParaInclusion: inclusion, + ParaInherent: paras_inherent, + Scheduler: scheduler, + Assigner: assigner, + OnDemandAssigner: assigner_on_demand, + ParachainsAssigner: assigner_parachains, + Initializer: initializer, + Dmp: dmp, + Hrmp: hrmp, + ParachainsOrigin: origin, + SessionInfo: session_info, + Disputes: disputes, + Babe: pallet_babe, + } +); + +impl frame_system::offchain::SendTransactionTypes for Test +where + RuntimeCall: From, +{ + type Extrinsic = UncheckedExtrinsic; + type OverarchingCall = RuntimeCall; +} + +parameter_types! { + pub const BlockHashCount: u32 = 250; + pub static BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max( + Weight::from_parts(4 * 1024 * 1024, u64::MAX), + ); + pub static BlockLength: limits::BlockLength = limits::BlockLength::max_with_normal_ratio(u32::MAX, Perbill::from_percent(75)); +} + +pub type AccountId = u64; + +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = BlockWeights; + type BlockLength = BlockLength; + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub static ExistentialDeposit: u64 = 1; +} + +impl pallet_balances::Config for Test { + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +parameter_types! { + pub const EpochDuration: u64 = 10; + pub const ExpectedBlockTime: Moment = 6_000; + pub const ReportLongevity: u64 = 10; + pub const MaxAuthorities: u32 = 100_000; +} + +impl pallet_babe::Config for Test { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; + + // session module is the trigger + type EpochChangeTrigger = pallet_babe::ExternalTrigger; + type DisabledValidators = (); + type WeightInfo = (); + type MaxAuthorities = MaxAuthorities; + type MaxNominators = ConstU32<0>; + type KeyOwnerProof = sp_core::Void; + type EquivocationReportSystem = (); +} + +parameter_types! { + pub const MinimumPeriod: Moment = 6_000 / 2; +} + +impl pallet_timestamp::Config for Test { + type Moment = Moment; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +impl crate::initializer::Config for Test { + type Randomness = TestRandomness; + type ForceOrigin = frame_system::EnsureRoot; + type WeightInfo = (); +} + +impl crate::configuration::Config for Test { + type WeightInfo = crate::configuration::TestWeightInfo; +} + +impl crate::shared::Config for Test {} + +impl origin::Config for Test {} + +parameter_types! { + pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +/// A very dumb implementation of `EstimateNextSessionRotation`. At the moment of writing, this +/// is more to satisfy type requirements rather than to test anything. +pub struct TestNextSessionRotation; + +impl frame_support::traits::EstimateNextSessionRotation for TestNextSessionRotation { + fn average_session_length() -> u32 { + 10 + } + + fn estimate_current_session_progress(_now: u32) -> (Option, Weight) { + (None, Weight::zero()) + } + + fn estimate_next_session_rotation(_now: u32) -> (Option, Weight) { + (None, Weight::zero()) + } +} + +impl crate::paras::Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = crate::paras::TestWeightInfo; + type UnsignedPriority = ParasUnsignedPriority; + type QueueFootprinter = ParaInclusion; + type NextSessionRotation = TestNextSessionRotation; +} + +impl crate::dmp::Config for Test {} + +parameter_types! { + pub const FirstMessageFactorPercent: u64 = 100; +} + +impl crate::hrmp::Config for Test { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type ChannelManager = frame_system::EnsureRoot; + type Currency = pallet_balances::Pallet; + type WeightInfo = crate::hrmp::TestWeightInfo; +} + +impl crate::disputes::Config for Test { + type RuntimeEvent = RuntimeEvent; + type RewardValidators = Self; + type SlashingHandler = Self; + type WeightInfo = crate::disputes::TestWeightInfo; +} + +thread_local! { + pub static REWARD_VALIDATORS: RefCell)>> = RefCell::new(Vec::new()); + pub static PUNISH_VALIDATORS_FOR: RefCell)>> = RefCell::new(Vec::new()); + pub static PUNISH_VALIDATORS_AGAINST: RefCell)>> = RefCell::new(Vec::new()); + pub static PUNISH_BACKERS_FOR: RefCell)>> = RefCell::new(Vec::new()); +} + +impl crate::disputes::RewardValidators for Test { + fn reward_dispute_statement( + session: SessionIndex, + validators: impl IntoIterator, + ) { + REWARD_VALIDATORS.with(|r| r.borrow_mut().push((session, validators.into_iter().collect()))) + } +} + +impl crate::disputes::SlashingHandler for Test { + fn punish_for_invalid( + session: SessionIndex, + _: CandidateHash, + losers: impl IntoIterator, + backers: impl IntoIterator, + ) { + PUNISH_VALIDATORS_FOR + .with(|r| r.borrow_mut().push((session, losers.into_iter().collect()))); + PUNISH_BACKERS_FOR.with(|r| r.borrow_mut().push((session, backers.into_iter().collect()))); + } + + fn punish_against_valid( + session: SessionIndex, + _: CandidateHash, + losers: impl IntoIterator, + _backers: impl IntoIterator, + ) { + PUNISH_VALIDATORS_AGAINST + .with(|r| r.borrow_mut().push((session, losers.into_iter().collect()))) + } + + fn initializer_initialize(_now: BlockNumber) -> Weight { + Weight::zero() + } + + fn initializer_finalize() {} + + fn initializer_on_new_session(_: SessionIndex) {} +} + +impl crate::scheduler::Config for Test { + type AssignmentProvider = Assigner; +} + +pub struct TestMessageQueueWeight; +impl pallet_message_queue::WeightInfo for TestMessageQueueWeight { + fn ready_ring_knit() -> Weight { + Weight::zero() + } + fn ready_ring_unknit() -> Weight { + Weight::zero() + } + fn service_queue_base() -> Weight { + Weight::zero() + } + fn service_page_base_completion() -> Weight { + Weight::zero() + } + fn service_page_base_no_completion() -> Weight { + Weight::zero() + } + fn service_page_item() -> Weight { + Weight::zero() + } + fn bump_service_head() -> Weight { + Weight::zero() + } + fn reap_page() -> Weight { + Weight::zero() + } + fn execute_overweight_page_removed() -> Weight { + Weight::zero() + } + fn execute_overweight_page_updated() -> Weight { + Weight::zero() + } +} +parameter_types! { + pub const MessageQueueServiceWeight: Weight = Weight::from_all(500); +} + +pub type MessageQueueSize = u32; + +impl pallet_message_queue::Config for Test { + type Size = MessageQueueSize; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = TestMessageQueueWeight; + type MessageProcessor = TestProcessMessage; + type QueueChangeHandler = ParaInclusion; + type QueuePausedQuery = (); + type HeapSize = ConstU32<65536>; + type MaxStale = ConstU32<8>; + type ServiceWeight = MessageQueueServiceWeight; +} + +impl assigner::Config for Test { + type ParachainsAssignmentProvider = ParachainsAssigner; + type OnDemandAssignmentProvider = OnDemandAssigner; +} + +impl assigner_parachains::Config for Test {} + +parameter_types! { + pub const OnDemandTrafficDefaultValue: FixedU128 = FixedU128::from_u32(1); +} + +impl assigner_on_demand::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type TrafficDefaultValue = OnDemandTrafficDefaultValue; + type WeightInfo = crate::assigner_on_demand::TestWeightInfo; +} + +impl crate::inclusion::Config for Test { + type WeightInfo = (); + type RuntimeEvent = RuntimeEvent; + type DisputesHandler = Disputes; + type RewardValidators = TestRewardValidators; + type MessageQueue = MessageQueue; +} + +impl crate::paras_inherent::Config for Test { + type WeightInfo = crate::paras_inherent::TestWeightInfo; +} + +pub struct MockValidatorSet; + +impl ValidatorSet for MockValidatorSet { + type ValidatorId = AccountId; + type ValidatorIdOf = ValidatorIdOf; + fn session_index() -> SessionIndex { + 0 + } + fn validators() -> Vec { + Vec::new() + } +} + +impl ValidatorSetWithIdentification for MockValidatorSet { + type Identification = (); + type IdentificationOf = FoolIdentificationOf; +} + +pub struct FoolIdentificationOf; +impl sp_runtime::traits::Convert> for FoolIdentificationOf { + fn convert(_: AccountId) -> Option<()> { + Some(()) + } +} + +pub struct ValidatorIdOf; +impl sp_runtime::traits::Convert> for ValidatorIdOf { + fn convert(a: AccountId) -> Option { + Some(a) + } +} + +impl crate::session_info::Config for Test { + type ValidatorSet = MockValidatorSet; +} + +thread_local! { + pub static DISCOVERY_AUTHORITIES: RefCell> = RefCell::new(Vec::new()); +} + +pub fn discovery_authorities() -> Vec { + DISCOVERY_AUTHORITIES.with(|r| r.borrow().clone()) +} + +pub fn set_discovery_authorities(new: Vec) { + DISCOVERY_AUTHORITIES.with(|r| *r.borrow_mut() = new); +} + +impl crate::session_info::AuthorityDiscoveryConfig for Test { + fn authorities() -> Vec { + discovery_authorities() + } +} + +thread_local! { + pub static BACKING_REWARDS: RefCell> + = RefCell::new(HashMap::new()); + + pub static AVAILABILITY_REWARDS: RefCell> + = RefCell::new(HashMap::new()); +} + +pub fn backing_rewards() -> HashMap { + BACKING_REWARDS.with(|r| r.borrow().clone()) +} + +pub fn availability_rewards() -> HashMap { + AVAILABILITY_REWARDS.with(|r| r.borrow().clone()) +} + +parameter_types! { + pub static Processed: Vec<(ParaId, UpwardMessage)> = vec![]; +} + +/// An implementation of a UMP sink that just records which messages were processed. +/// +/// A message's weight is defined by the first 4 bytes of its data, which we decode into a +/// `u32`. +pub struct TestProcessMessage; +impl ProcessMessage for TestProcessMessage { + type Origin = AggregateMessageOrigin; + + fn process_message( + message: &[u8], + origin: AggregateMessageOrigin, + meter: &mut WeightMeter, + _id: &mut [u8; 32], + ) -> Result { + let para = match origin { + AggregateMessageOrigin::Ump(UmpQueueId::Para(p)) => p, + }; + + let required = match u32::decode(&mut &message[..]) { + Ok(w) => Weight::from_parts(w as u64, w as u64), + Err(_) => return Err(ProcessMessageError::Corrupt), // same as the real `ProcessMessage` + }; + if meter.try_consume(required).is_err() { + return Err(ProcessMessageError::Overweight(required)) + } + + let mut processed = Processed::get(); + processed.push((para, message.to_vec())); + Processed::set(processed); + Ok(true) + } +} + +pub struct TestRewardValidators; + +impl inclusion::RewardValidators for TestRewardValidators { + fn reward_backing(v: impl IntoIterator) { + BACKING_REWARDS.with(|r| { + let mut r = r.borrow_mut(); + for i in v { + *r.entry(i).or_insert(0) += 1; + } + }) + } + fn reward_bitfields(v: impl IntoIterator) { + AVAILABILITY_REWARDS.with(|r| { + let mut r = r.borrow_mut(); + for i in v { + *r.entry(i).or_insert(0) += 1; + } + }) + } +} + +/// Create a new set of test externalities. +pub fn new_test_ext(state: MockGenesisConfig) -> TestExternalities { + use sp_keystore::{testing::MemoryKeystore, KeystoreExt, KeystorePtr}; + use sp_std::sync::Arc; + + sp_tracing::try_init_simple(); + + BACKING_REWARDS.with(|r| r.borrow_mut().clear()); + AVAILABILITY_REWARDS.with(|r| r.borrow_mut().clear()); + + let mut t = state.system.build_storage().unwrap(); + state.configuration.assimilate_storage(&mut t).unwrap(); + state.paras.assimilate_storage(&mut t).unwrap(); + + let mut ext: TestExternalities = t.into(); + ext.register_extension(KeystoreExt(Arc::new(MemoryKeystore::new()) as KeystorePtr)); + + ext +} + +#[derive(Default)] +pub struct MockGenesisConfig { + pub system: frame_system::GenesisConfig, + pub configuration: crate::configuration::GenesisConfig, + pub paras: crate::paras::GenesisConfig, +} + +pub fn assert_last_event(generic_event: RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +pub fn assert_last_events(generic_events: E) +where + E: DoubleEndedIterator + ExactSizeIterator, +{ + for (i, (got, want)) in frame_system::Pallet::::events() + .into_iter() + .rev() + .map(|e| e.event) + .zip(generic_events.rev().map(::RuntimeEvent::from)) + .rev() + .enumerate() + { + assert_eq!((i, got), (i, want)); + } +} + +pub(crate) fn register_parachain_with_balance(id: ParaId, balance: Balance) { + let validation_code: ValidationCode = vec![1].into(); + assert_ok!(Paras::schedule_para_initialize( + id, + crate::paras::ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: vec![1].into(), + validation_code: validation_code.clone(), + }, + )); + + assert_ok!(Paras::add_trusted_validation_code(RuntimeOrigin::root(), validation_code)); + ::Currency::make_free_balance_be( + &id.into_account_truncating(), + balance, + ); +} + +pub(crate) fn register_parachain(id: ParaId) { + register_parachain_with_balance(id, 1000); +} + +pub(crate) fn deregister_parachain(id: ParaId) { + assert_ok!(Paras::schedule_para_cleanup(id)); +} + +/// Calls `schedule_para_cleanup` in a new storage transactions, since it assumes rollback on error. +pub(crate) fn try_deregister_parachain(id: ParaId) -> crate::DispatchResult { + frame_support::storage::transactional::with_storage_layer(|| Paras::schedule_para_cleanup(id)) +} diff --git a/polkadot/runtime/parachains/src/origin.rs b/polkadot/runtime/parachains/src/origin.rs new file mode 100644 index 0000000000000000000000000000000000000000..c83fec1b8923ad9048d1425e4de570c17fce5742 --- /dev/null +++ b/polkadot/runtime/parachains/src/origin.rs @@ -0,0 +1,75 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Declaration of the parachain specific origin and a pallet that hosts it. + +use primitives::Id as ParaId; +use sp_runtime::traits::BadOrigin; +use sp_std::result; + +pub use pallet::*; + +/// Ensure that the origin `o` represents a parachain. +/// Returns `Ok` with the parachain ID that effected the extrinsic or an `Err` otherwise. +pub fn ensure_parachain(o: OuterOrigin) -> result::Result +where + OuterOrigin: Into>, +{ + match o.into() { + Ok(Origin::Parachain(id)) => Ok(id), + _ => Err(BadOrigin), + } +} + +/// There is no way to register an origin type in `construct_runtime` without a pallet the origin +/// belongs to. +/// +/// This module fulfills only the single purpose of housing the `Origin` in `construct_runtime`. +// ideally, though, the `construct_runtime` should support a free-standing origin. +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config {} + + /// Origin for the parachains. + #[pallet::origin] + #[derive( + PartialEq, + Eq, + Clone, + Encode, + Decode, + sp_core::RuntimeDebug, + scale_info::TypeInfo, + MaxEncodedLen, + )] + pub enum Origin { + /// It comes from a parachain. + Parachain(ParaId), + } +} + +impl From for Origin { + fn from(id: u32) -> Origin { + Origin::Parachain(id.into()) + } +} diff --git a/polkadot/runtime/parachains/src/paras/benchmarking.rs b/polkadot/runtime/parachains/src/paras/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..5c060547601f5869a671856b3bf3ceebf49ee812 --- /dev/null +++ b/polkadot/runtime/parachains/src/paras/benchmarking.rs @@ -0,0 +1,199 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::configuration::HostConfiguration; +use frame_benchmarking::benchmarks; +use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin}; +use primitives::{HeadData, Id as ParaId, ValidationCode, MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE}; +use sp_runtime::traits::{One, Saturating}; + +mod pvf_check; + +use self::pvf_check::{VoteCause, VoteOutcome}; + +// 2 ^ 10, because binary search time complexity is O(log(2, n)) and n = 1024 gives us a big and +// round number. +// Due to the limited number of parachains, the number of pruning, upcoming upgrades and cooldowns +// shouldn't exceed this number. +const SAMPLE_SIZE: u32 = 1024; + +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +fn generate_disordered_pruning() { + let mut needs_pruning = Vec::new(); + + for i in 0..SAMPLE_SIZE { + let id = ParaId::from(i); + let block_number = BlockNumberFor::::from(1000u32); + needs_pruning.push((id, block_number)); + } + + PastCodePruning::::put(needs_pruning); +} + +pub(crate) fn generate_disordered_upgrades() { + let mut upgrades = Vec::new(); + let mut cooldowns = Vec::new(); + + for i in 0..SAMPLE_SIZE { + let id = ParaId::from(i); + let block_number = BlockNumberFor::::from(1000u32); + upgrades.push((id, block_number)); + cooldowns.push((id, block_number)); + } + + UpcomingUpgrades::::put(upgrades); + UpgradeCooldowns::::put(cooldowns); +} + +fn generate_disordered_actions_queue() { + let mut queue = Vec::new(); + let next_session = shared::Pallet::::session_index().saturating_add(One::one()); + + for _ in 0..SAMPLE_SIZE { + let id = ParaId::from(1000); + queue.push(id); + } + + ActionsQueue::::mutate(next_session, |v| { + *v = queue; + }); +} + +benchmarks! { + force_set_current_code { + let c in 1 .. MAX_CODE_SIZE; + let new_code = ValidationCode(vec![0; c as usize]); + let para_id = ParaId::from(c as u32); + CurrentCodeHash::::insert(¶_id, new_code.hash()); + generate_disordered_pruning::(); + }: _(RawOrigin::Root, para_id, new_code) + verify { + assert_last_event::(Event::CurrentCodeUpdated(para_id).into()); + } + force_set_current_head { + let s in 1 .. MAX_HEAD_DATA_SIZE; + let new_head = HeadData(vec![0; s as usize]); + let para_id = ParaId::from(1000); + }: _(RawOrigin::Root, para_id, new_head) + verify { + assert_last_event::(Event::CurrentHeadUpdated(para_id).into()); + } + force_set_most_recent_context { + let para_id = ParaId::from(1000); + let context = BlockNumberFor::::from(1000u32); + }: _(RawOrigin::Root, para_id, context) + force_schedule_code_upgrade { + let c in 1 .. MAX_CODE_SIZE; + let new_code = ValidationCode(vec![0; c as usize]); + let para_id = ParaId::from(c as u32); + let block = BlockNumberFor::::from(c); + generate_disordered_upgrades::(); + }: _(RawOrigin::Root, para_id, new_code, block) + verify { + assert_last_event::(Event::CodeUpgradeScheduled(para_id).into()); + } + force_note_new_head { + let s in 1 .. MAX_HEAD_DATA_SIZE; + let para_id = ParaId::from(1000); + let new_head = HeadData(vec![0; s as usize]); + let old_code_hash = ValidationCode(vec![0]).hash(); + CurrentCodeHash::::insert(¶_id, old_code_hash); + // schedule an expired code upgrade for this `para_id` so that force_note_new_head would use + // the worst possible code path + let expired = frame_system::Pallet::::block_number().saturating_sub(One::one()); + let config = HostConfiguration::>::default(); + generate_disordered_pruning::(); + Pallet::::schedule_code_upgrade(para_id, ValidationCode(vec![0]), expired, &config); + }: _(RawOrigin::Root, para_id, new_head) + verify { + assert_last_event::(Event::NewHeadNoted(para_id).into()); + } + force_queue_action { + let para_id = ParaId::from(1000); + generate_disordered_actions_queue::(); + }: _(RawOrigin::Root, para_id) + verify { + let next_session = crate::shared::Pallet::::session_index().saturating_add(One::one()); + assert_last_event::(Event::ActionQueued(para_id, next_session).into()); + } + + add_trusted_validation_code { + let c in 1 .. MAX_CODE_SIZE; + let new_code = ValidationCode(vec![0; c as usize]); + + pvf_check::prepare_bypassing_bench::(new_code.clone()); + }: _(RawOrigin::Root, new_code) + + poke_unused_validation_code { + let code_hash = [0; 32].into(); + }: _(RawOrigin::Root, code_hash) + + include_pvf_check_statement { + let (stmt, signature) = pvf_check::prepare_inclusion_bench::(); + }: { + let _ = Pallet::::include_pvf_check_statement(RawOrigin::None.into(), stmt, signature); + } + + include_pvf_check_statement_finalize_upgrade_accept { + let (stmt, signature) = pvf_check::prepare_finalization_bench::( + VoteCause::Upgrade, + VoteOutcome::Accept, + ); + }: { + let _ = Pallet::::include_pvf_check_statement(RawOrigin::None.into(), stmt, signature); + } + + include_pvf_check_statement_finalize_upgrade_reject { + let (stmt, signature) = pvf_check::prepare_finalization_bench::( + VoteCause::Upgrade, + VoteOutcome::Reject, + ); + }: { + let _ = Pallet::::include_pvf_check_statement(RawOrigin::None.into(), stmt, signature); + } + + include_pvf_check_statement_finalize_onboarding_accept { + let (stmt, signature) = pvf_check::prepare_finalization_bench::( + VoteCause::Onboarding, + VoteOutcome::Accept, + ); + }: { + let _ = Pallet::::include_pvf_check_statement(RawOrigin::None.into(), stmt, signature); + } + + include_pvf_check_statement_finalize_onboarding_reject { + let (stmt, signature) = pvf_check::prepare_finalization_bench::( + VoteCause::Onboarding, + VoteOutcome::Reject, + ); + }: { + let _ = Pallet::::include_pvf_check_statement(RawOrigin::None.into(), stmt, signature); + } + + impl_benchmark_test_suite!( + Pallet, + crate::mock::new_test_ext(Default::default()), + crate::mock::Test + ); +} diff --git a/polkadot/runtime/parachains/src/paras/benchmarking/pvf_check.rs b/polkadot/runtime/parachains/src/paras/benchmarking/pvf_check.rs new file mode 100644 index 0000000000000000000000000000000000000000..ab5e13124436d076018b6e30dc2cc8a13162d5a1 --- /dev/null +++ b/polkadot/runtime/parachains/src/paras/benchmarking/pvf_check.rs @@ -0,0 +1,223 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This module focuses on the benchmarking of the `include_pvf_check_statement` dispatchable. + +use crate::{configuration, paras::*, shared::Pallet as ParasShared}; +use frame_support::assert_ok; +use frame_system::RawOrigin; +use primitives::{HeadData, Id as ParaId, ValidationCode, ValidatorId, ValidatorIndex}; +use sp_application_crypto::RuntimeAppPublic; + +// Constants for the benchmarking +const SESSION_INDEX: SessionIndex = 1; +const VALIDATOR_NUM: usize = 800; +const CAUSES_NUM: usize = 100; +fn validation_code() -> ValidationCode { + ValidationCode(vec![0]) +} +fn old_validation_code() -> ValidationCode { + ValidationCode(vec![1]) +} + +/// Prepares the PVF check statement and the validator signature to pass into +/// `include_pvf_check_statement` during benchmarking phase. +/// +/// It won't trigger finalization, so we expect the benchmarking will only measure the performance +/// of only vote accounting. +pub fn prepare_inclusion_bench() -> (PvfCheckStatement, ValidatorSignature) +where + T: Config + shared::Config, +{ + initialize::(); + // we do not plan to trigger finalization, thus the cause is inconsequential. + initialize_pvf_active_vote::(VoteCause::Onboarding, CAUSES_NUM); + + // `unwrap` cannot panic here since the `initialize` function should initialize validators count + // to be more than 0. + // + // VoteDirection doesn't matter here as well. + let stmt_n_sig = generate_statements::(VoteOutcome::Accept).next().unwrap(); + + stmt_n_sig +} + +/// Prepares conditions for benchmarking of the finalization part of `include_pvf_check_statement`. +/// +/// This function will initialize a PVF pre-check vote, then submit a number of PVF pre-checking +/// statements so that to achieve the quorum only one statement is left. This statement is returned +/// from this function and is expected to be passed into `include_pvf_check_statement` during the +/// benchmarking phase. +pub fn prepare_finalization_bench( + cause: VoteCause, + outcome: VoteOutcome, +) -> (PvfCheckStatement, ValidatorSignature) +where + T: Config + shared::Config, +{ + initialize::(); + initialize_pvf_active_vote::(cause, CAUSES_NUM); + + let mut stmts = generate_statements::(outcome).collect::>(); + // this should be ensured by the `initialize` function. + assert!(stmts.len() > 2); + + // stash the last statement to be used in the benchmarking phase. + let stmt_n_sig = stmts.pop().unwrap(); + + for (stmt, sig) in stmts { + let r = Pallet::::include_pvf_check_statement(RawOrigin::None.into(), stmt, sig); + assert!(r.is_ok()); + } + + stmt_n_sig +} + +/// Prepares storage for invoking `add_trusted_validation_code` with several paras initializing to +/// the same code. +pub fn prepare_bypassing_bench(validation_code: ValidationCode) +where + T: Config + shared::Config, +{ + // Suppose a sensible number of paras initialize to the same code. + const PARAS_NUM: usize = 10; + + initialize::(); + for i in 0..PARAS_NUM { + let id = ParaId::from(i as u32); + assert_ok!(Pallet::::schedule_para_initialize( + id, + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: HeadData(vec![1, 2, 3, 4]), + validation_code: validation_code.clone(), + }, + )); + } +} + +/// What caused the PVF pre-checking vote? +#[derive(PartialEq, Eq, Copy, Clone, Debug)] +pub enum VoteCause { + Onboarding, + Upgrade, +} + +/// The outcome of the PVF pre-checking vote. +#[derive(PartialEq, Eq, Copy, Clone, Debug)] +pub enum VoteOutcome { + Accept, + Reject, +} + +fn initialize() +where + T: Config + shared::Config, +{ + // 0. generate a list of validators + let validators = (0..VALIDATOR_NUM) + .map(|_| ::generate_pair(None)) + .collect::>(); + + // 1. Make sure PVF pre-checking is enabled in the config. + let config = configuration::Pallet::::config(); + configuration::Pallet::::force_set_active_config(config.clone()); + + // 2. initialize a new session with deterministic validator set. + ParasShared::::set_active_validators_ascending(validators.clone()); + ParasShared::::set_session_index(SESSION_INDEX); +} + +/// Creates a new PVF pre-checking active vote. +/// +/// The subject of the vote (i.e. validation code) and the cause (upgrade/onboarding) is specified +/// by the test setup. +fn initialize_pvf_active_vote(vote_cause: VoteCause, causes_num: usize) +where + T: Config + shared::Config, +{ + for i in 0..causes_num { + let id = ParaId::from(i as u32); + + if vote_cause == VoteCause::Upgrade { + // we do care about validation code being actually different, since there is a check + // that prevents upgrading to the same code. + let old_validation_code = old_validation_code(); + let validation_code = validation_code(); + + let mut parachains = ParachainsCache::new(); + Pallet::::initialize_para_now( + &mut parachains, + id, + &ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: HeadData(vec![1, 2, 3, 4]), + validation_code: old_validation_code, + }, + ); + // don't care about performance here, but we do care about robustness. So dump the cache + // asap. + drop(parachains); + + Pallet::::schedule_code_upgrade( + id, + validation_code, + /* relay_parent_number */ 1u32.into(), + &configuration::Pallet::::config(), + ); + } else { + let r = Pallet::::schedule_para_initialize( + id, + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: HeadData(vec![1, 2, 3, 4]), + validation_code: validation_code(), + }, + ); + assert!(r.is_ok()); + } + } +} + +/// Generates a list of votes combined with signatures for the active validator set. The number of +/// votes is equal to the minimum number of votes required to reach the threshold for either accept +/// or reject. +fn generate_statements( + vote_outcome: VoteOutcome, +) -> impl Iterator +where + T: Config + shared::Config, +{ + let validators = ParasShared::::active_validator_keys(); + + let accept_threshold = primitives::supermajority_threshold(validators.len()); + let required_votes = match vote_outcome { + VoteOutcome::Accept => accept_threshold, + VoteOutcome::Reject => validators.len() - accept_threshold, + }; + (0..required_votes).map(move |validator_index| { + let stmt = PvfCheckStatement { + accept: vote_outcome == VoteOutcome::Accept, + subject: validation_code().hash(), + session_index: SESSION_INDEX, + + validator_index: ValidatorIndex(validator_index as u32), + }; + let signature = validators[validator_index].sign(&stmt.signing_payload()).unwrap(); + + (stmt, signature) + }) +} diff --git a/polkadot/runtime/parachains/src/paras/mod.rs b/polkadot/runtime/parachains/src/paras/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..95b89a1ca2c3a91ccde730b1254d213e6157a6b6 --- /dev/null +++ b/polkadot/runtime/parachains/src/paras/mod.rs @@ -0,0 +1,2219 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The paras pallet acts as the main registry of paras. +//! +//! # Tracking State of Paras +//! +//! The most important responsibility of this module is to track which parachains +//! are active and what their current state is. The current state of a para consists of the current +//! head data and the current validation code (AKA Parachain Validation Function (PVF)). +//! +//! A para is not considered live until it is registered and activated in this pallet. +//! +//! The set of parachains cannot change except at session boundaries. This is primarily to ensure +//! that the number and meaning of bits required for the availability bitfields does not change +//! except at session boundaries. +//! +//! # Validation Code Upgrades +//! +//! When a para signals the validation code upgrade it will be processed by this module. This can +//! be in turn split into more fine grained items: +//! +//! - Part of the acceptance criteria checks if the para can indeed signal an upgrade, +//! +//! - When the candidate is enacted, this module schedules code upgrade, storing the prospective +//! validation code. +//! +//! - Actually assign the prospective validation code to be the current one after all conditions are +//! fulfilled. +//! +//! The conditions that must be met before the para can use the new validation code are: +//! +//! 1. The validation code should have been "soaked" in the storage for a given number of blocks. +//! That is, the validation code should have been stored in on-chain storage for some time, so +//! that in case of a revert with a non-extreme height difference, that validation code can still +//! be found on-chain. +//! +//! 2. The validation code was vetted by the validators and declared as non-malicious in a processes +//! known as PVF pre-checking. +//! +//! # Validation Code Management +//! +//! Potentially, one validation code can be used by several different paras. For example, during +//! initial stages of deployment several paras can use the same "shell" validation code, or +//! there can be shards of the same para that use the same validation code. +//! +//! In case a validation code ceases to have any users it must be pruned from the on-chain storage. +//! +//! # Para Lifecycle Management +//! +//! A para can be in one of the two stable states: it is either a lease holding parachain or an +//! on-demand parachain. +//! +//! However, in order to get into one of those two states, it must first be onboarded. Onboarding +//! can be only enacted at session boundaries. Onboarding must take at least one full session. +//! Moreover, a brand new validation code should go through the PVF pre-checking process. +//! +//! Once the para is in one of the two stable states, it can switch to the other stable state or to +//! initiate offboarding process. The result of offboarding is removal of all data related to that +//! para. +//! +//! # PVF Pre-checking +//! +//! As was mentioned above, a brand new validation code should go through a process of approval. As +//! part of this process, validators from the active set will take the validation code and check if +//! it is malicious. Once they did that and have their judgement, either accept or reject, they +//! issue a statement in a form of an unsigned extrinsic. This extrinsic is processed by this +//! pallet. Once supermajority is gained for accept, then the process that initiated the check is +//! resumed (as mentioned before this can be either upgrading of validation code or onboarding). If +//! getting a supermajority becomes impossible (>1/3 of validators have already voted against), then +//! we reject. +//! +//! Below is a state diagram that depicts states of a single PVF pre-checking vote. +//! +//! ```text +//! ┌──────────┐ +//! supermajority │ │ +//! ┌────────for───────────▶│ accepted │ +//! vote────┐ │ │ │ +//! │ │ │ └──────────┘ +//! │ │ │ +//! │ ┌───────┐ +//! │ │ │ +//! └─▶│ init │──── >1/3 against ┌──────────┐ +//! │ │ │ │ │ +//! └───────┘ └──────────▶│ rejected │ +//! ▲ │ │ │ +//! │ │ session └──────────┘ +//! │ └──change +//! │ │ +//! │ ▼ +//! ┌─────┐ +//! start──────▶│reset│ +//! └─────┘ +//! ``` + +use crate::{ + configuration, + inclusion::{QueueFootprinter, UmpQueueId}, + initializer::SessionChangeNotification, + shared, +}; +use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; +use frame_support::{pallet_prelude::*, traits::EstimateNextSessionRotation, DefaultNoBound}; +use frame_system::pallet_prelude::*; +use parity_scale_codec::{Decode, Encode}; +use primitives::{ + ConsensusLog, HeadData, Id as ParaId, PvfCheckStatement, SessionIndex, UpgradeGoAhead, + UpgradeRestriction, ValidationCode, ValidationCodeHash, ValidatorSignature, +}; +use scale_info::{Type, TypeInfo}; +use sp_core::RuntimeDebug; +use sp_runtime::{ + traits::{AppVerify, One, Saturating}, + DispatchResult, SaturatedConversion, +}; +use sp_std::{cmp, collections::btree_set::BTreeSet, mem, prelude::*}; + +use serde::{Deserialize, Serialize}; + +pub use crate::Origin as ParachainOrigin; + +#[cfg(feature = "runtime-benchmarks")] +pub(crate) mod benchmarking; + +#[cfg(test)] +pub(crate) mod tests; + +pub use pallet::*; + +const LOG_TARGET: &str = "runtime::paras"; + +// the two key times necessary to track for every code replacement. +#[derive(Default, Encode, Decode, TypeInfo)] +#[cfg_attr(test, derive(Debug, Clone, PartialEq))] +pub struct ReplacementTimes { + /// The relay-chain block number that the code upgrade was expected to be activated. + /// This is when the code change occurs from the para's perspective - after the + /// first parablock included with a relay-parent with number >= this value. + expected_at: N, + /// The relay-chain block number at which the parablock activating the code upgrade was + /// actually included. This means considered included and available, so this is the time at + /// which that parablock enters the acceptance period in this fork of the relay-chain. + activated_at: N, +} + +/// Metadata used to track previous parachain validation code that we keep in +/// the state. +#[derive(Default, Encode, Decode, TypeInfo)] +#[cfg_attr(test, derive(Debug, Clone, PartialEq))] +pub struct ParaPastCodeMeta { + /// Block numbers where the code was expected to be replaced and where the code + /// was actually replaced, respectively. The first is used to do accurate look-ups + /// of historic code in historic contexts, whereas the second is used to do + /// pruning on an accurate timeframe. These can be used as indices + /// into the `PastCodeHash` map along with the `ParaId` to fetch the code itself. + upgrade_times: Vec>, + /// Tracks the highest pruned code-replacement, if any. This is the `activated_at` value, + /// not the `expected_at` value. + last_pruned: Option, +} + +/// The possible states of a para, to take into account delayed lifecycle changes. +/// +/// If the para is in a "transition state", it is expected that the parachain is +/// queued in the `ActionsQueue` to transition it into a stable state. Its lifecycle +/// state will be used to determine the state transition to apply to the para. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +pub enum ParaLifecycle { + /// Para is new and is onboarding as an on-demand or lease holding Parachain. + Onboarding, + /// Para is a Parathread (on-demand parachain). + Parathread, + /// Para is a lease holding Parachain. + Parachain, + /// Para is a Parathread (on-demand parachain) which is upgrading to a lease holding Parachain. + UpgradingParathread, + /// Para is a lease holding Parachain which is downgrading to an on-demand parachain. + DowngradingParachain, + /// Parathread (on-demand parachain) is queued to be offboarded. + OffboardingParathread, + /// Parachain is queued to be offboarded. + OffboardingParachain, +} + +impl ParaLifecycle { + /// Returns true if parachain is currently onboarding. To learn if the + /// parachain is onboarding as a lease holding or on-demand parachain, look at the + /// `UpcomingGenesis` storage item. + pub fn is_onboarding(&self) -> bool { + matches!(self, ParaLifecycle::Onboarding) + } + + /// Returns true if para is in a stable state, i.e. it is currently + /// a lease holding or on-demand parachain, and not in any transition state. + pub fn is_stable(&self) -> bool { + matches!(self, ParaLifecycle::Parathread | ParaLifecycle::Parachain) + } + + /// Returns true if para is currently treated as a parachain. + /// This also includes transitioning states, so you may want to combine + /// this check with `is_stable` if you specifically want `Paralifecycle::Parachain`. + pub fn is_parachain(&self) -> bool { + matches!( + self, + ParaLifecycle::Parachain | + ParaLifecycle::DowngradingParachain | + ParaLifecycle::OffboardingParachain + ) + } + + /// Returns true if para is currently treated as a parathread (on-demand parachain). + /// This also includes transitioning states, so you may want to combine + /// this check with `is_stable` if you specifically want `Paralifecycle::Parathread`. + pub fn is_parathread(&self) -> bool { + matches!( + self, + ParaLifecycle::Parathread | + ParaLifecycle::UpgradingParathread | + ParaLifecycle::OffboardingParathread + ) + } + + /// Returns true if para is currently offboarding. + pub fn is_offboarding(&self) -> bool { + matches!(self, ParaLifecycle::OffboardingParathread | ParaLifecycle::OffboardingParachain) + } + + /// Returns true if para is in any transitionary state. + pub fn is_transitioning(&self) -> bool { + !Self::is_stable(self) + } +} + +impl ParaPastCodeMeta { + // note a replacement has occurred at a given block number. + pub(crate) fn note_replacement(&mut self, expected_at: N, activated_at: N) { + self.upgrade_times.push(ReplacementTimes { expected_at, activated_at }) + } + + /// Returns `true` if the upgrade logs list is empty. + fn is_empty(&self) -> bool { + self.upgrade_times.is_empty() + } + + // The block at which the most recently tracked code change occurred, from the perspective + // of the para. + #[cfg(test)] + fn most_recent_change(&self) -> Option { + self.upgrade_times.last().map(|x| x.expected_at) + } + + // prunes all code upgrade logs occurring at or before `max`. + // note that code replaced at `x` is the code used to validate all blocks before + // `x`. Thus, `max` should be outside of the slashing window when this is invoked. + // + // Since we don't want to prune anything inside the acceptance period, and the parablock only + // enters the acceptance period after being included, we prune based on the activation height of + // the code change, not the expected height of the code change. + // + // returns an iterator of block numbers at which code was replaced, where the replaced + // code should be now pruned, in ascending order. + fn prune_up_to(&'_ mut self, max: N) -> impl Iterator + '_ { + let to_prune = self.upgrade_times.iter().take_while(|t| t.activated_at <= max).count(); + let drained = if to_prune == 0 { + // no-op prune. + self.upgrade_times.drain(self.upgrade_times.len()..) + } else { + // if we are actually pruning something, update the `last_pruned` member. + self.last_pruned = Some(self.upgrade_times[to_prune - 1].activated_at); + self.upgrade_times.drain(..to_prune) + }; + + drained.map(|times| times.expected_at) + } +} + +/// Arguments for initializing a para. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, Serialize, Deserialize)] +pub struct ParaGenesisArgs { + /// The initial head data to use. + pub genesis_head: HeadData, + /// The initial validation code to use. + pub validation_code: ValidationCode, + /// Lease holding or on-demand parachain. + #[serde(rename = "parachain")] + pub para_kind: ParaKind, +} + +/// Distinguishes between lease holding Parachain and Parathread (on-demand parachain) +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] +pub enum ParaKind { + Parathread, + Parachain, +} + +impl Serialize for ParaKind { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + match self { + ParaKind::Parachain => serializer.serialize_bool(true), + ParaKind::Parathread => serializer.serialize_bool(false), + } + } +} + +impl<'de> Deserialize<'de> for ParaKind { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + match serde::de::Deserialize::deserialize(deserializer) { + Ok(true) => Ok(ParaKind::Parachain), + Ok(false) => Ok(ParaKind::Parathread), + _ => Err(serde::de::Error::custom("invalid ParaKind serde representation")), + } + } +} + +// Manual encoding, decoding, and TypeInfo as the parakind field in ParaGenesisArgs used to be a +// bool +impl Encode for ParaKind { + fn size_hint(&self) -> usize { + true.size_hint() + } + + fn using_encoded R>(&self, f: F) -> R { + match self { + ParaKind::Parachain => true.using_encoded(f), + ParaKind::Parathread => false.using_encoded(f), + } + } +} + +impl Decode for ParaKind { + fn decode( + input: &mut I, + ) -> Result { + match bool::decode(input) { + Ok(true) => Ok(ParaKind::Parachain), + Ok(false) => Ok(ParaKind::Parathread), + _ => Err("Invalid ParaKind representation".into()), + } + } +} + +impl TypeInfo for ParaKind { + type Identity = bool; + fn type_info() -> Type { + bool::type_info() + } +} + +/// This enum describes a reason why a particular PVF pre-checking vote was initiated. When the +/// PVF vote in question is concluded, this enum indicates what changes should be performed. +#[derive(Debug, Encode, Decode, TypeInfo)] +pub(crate) enum PvfCheckCause { + /// PVF vote was initiated by the initial onboarding process of the given para. + Onboarding(ParaId), + /// PVF vote was initiated by signalling of an upgrade by the given para. + Upgrade { + /// The ID of the parachain that initiated or is waiting for the conclusion of + /// pre-checking. + id: ParaId, + /// The relay-chain block number of **inclusion** of candidate that that initiated the + /// upgrade. + /// + /// It's important to count upgrade enactment delay from the inclusion of this candidate + /// instead of its relay parent -- in order to keep PVF available in case of chain + /// reversions. + /// + /// See https://github.com/paritytech/polkadot/issues/4601 for detailed explanation. + included_at: BlockNumber, + }, +} + +impl PvfCheckCause { + /// Returns the ID of the para that initiated or subscribed to the pre-checking vote. + fn para_id(&self) -> ParaId { + match *self { + PvfCheckCause::Onboarding(id) => id, + PvfCheckCause::Upgrade { id, .. } => id, + } + } +} + +/// Specifies what was the outcome of a PVF pre-checking vote. +#[derive(Copy, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +enum PvfCheckOutcome { + Accepted, + Rejected, +} + +/// This struct describes the current state of an in-progress PVF pre-checking vote. +#[derive(Encode, Decode, TypeInfo)] +pub(crate) struct PvfCheckActiveVoteState { + // The two following vectors have their length equal to the number of validators in the active + // set. They start with all zeroes. A 1 is set at an index when the validator at the that index + // makes a vote. Once a 1 is set for either of the vectors, that validator cannot vote anymore. + // Since the active validator set changes each session, the bit vectors are reinitialized as + // well: zeroed and resized so that each validator gets its own bit. + votes_accept: BitVec, + votes_reject: BitVec, + + /// The number of session changes this PVF vote has observed. Therefore, this number is + /// increased at each session boundary. When created, it is initialized with 0. + age: SessionIndex, + /// The block number at which this PVF vote was created. + created_at: BlockNumber, + /// A list of causes for this PVF pre-checking. Has at least one. + causes: Vec>, +} + +impl PvfCheckActiveVoteState { + /// Returns a new instance of vote state, started at the specified block `now`, with the + /// number of validators in the current session `n_validators` and the originating `cause`. + fn new(now: BlockNumber, n_validators: usize, cause: PvfCheckCause) -> Self { + let mut causes = Vec::with_capacity(1); + causes.push(cause); + Self { + created_at: now, + votes_accept: bitvec::bitvec![u8, BitOrderLsb0; 0; n_validators], + votes_reject: bitvec::bitvec![u8, BitOrderLsb0; 0; n_validators], + age: 0, + causes, + } + } + + /// Resets all votes and resizes the votes vectors corresponding to the number of validators + /// in the new session. + fn reinitialize_ballots(&mut self, n_validators: usize) { + let clear_and_resize = |v: &mut BitVec<_, _>| { + v.clear(); + v.resize(n_validators, false); + }; + clear_and_resize(&mut self.votes_accept); + clear_and_resize(&mut self.votes_reject); + } + + /// Returns `Some(true)` if the validator at the given index has already cast their vote within + /// the ongoing session. Returns `None` in case the index is out of bounds. + fn has_vote(&self, validator_index: usize) -> Option { + let accept_vote = self.votes_accept.get(validator_index)?; + let reject_vote = self.votes_reject.get(validator_index)?; + Some(*accept_vote || *reject_vote) + } + + /// Returns `None` if the quorum is not reached, or the direction of the decision. + fn quorum(&self, n_validators: usize) -> Option { + let accept_threshold = primitives::supermajority_threshold(n_validators); + // At this threshold, a supermajority is no longer possible, so we reject. + let reject_threshold = n_validators - accept_threshold; + + if self.votes_accept.count_ones() >= accept_threshold { + Some(PvfCheckOutcome::Accepted) + } else if self.votes_reject.count_ones() > reject_threshold { + Some(PvfCheckOutcome::Rejected) + } else { + None + } + } + + #[cfg(test)] + pub(crate) fn causes(&self) -> &[PvfCheckCause] { + self.causes.as_slice() + } +} + +pub trait WeightInfo { + fn force_set_current_code(c: u32) -> Weight; + fn force_set_current_head(s: u32) -> Weight; + fn force_set_most_recent_context() -> Weight; + fn force_schedule_code_upgrade(c: u32) -> Weight; + fn force_note_new_head(s: u32) -> Weight; + fn force_queue_action() -> Weight; + fn add_trusted_validation_code(c: u32) -> Weight; + fn poke_unused_validation_code() -> Weight; + + fn include_pvf_check_statement_finalize_upgrade_accept() -> Weight; + fn include_pvf_check_statement_finalize_upgrade_reject() -> Weight; + fn include_pvf_check_statement_finalize_onboarding_accept() -> Weight; + fn include_pvf_check_statement_finalize_onboarding_reject() -> Weight; + fn include_pvf_check_statement() -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn force_set_current_code(_c: u32) -> Weight { + Weight::MAX + } + fn force_set_current_head(_s: u32) -> Weight { + Weight::MAX + } + fn force_set_most_recent_context() -> Weight { + Weight::MAX + } + fn force_schedule_code_upgrade(_c: u32) -> Weight { + Weight::MAX + } + fn force_note_new_head(_s: u32) -> Weight { + Weight::MAX + } + fn force_queue_action() -> Weight { + Weight::MAX + } + fn add_trusted_validation_code(_c: u32) -> Weight { + // Called during integration tests for para initialization. + Weight::zero() + } + fn poke_unused_validation_code() -> Weight { + Weight::MAX + } + fn include_pvf_check_statement_finalize_upgrade_accept() -> Weight { + Weight::MAX + } + fn include_pvf_check_statement_finalize_upgrade_reject() -> Weight { + Weight::MAX + } + fn include_pvf_check_statement_finalize_onboarding_accept() -> Weight { + Weight::MAX + } + fn include_pvf_check_statement_finalize_onboarding_reject() -> Weight { + Weight::MAX + } + fn include_pvf_check_statement() -> Weight { + // This special value is to distinguish from the finalizing variants above in tests. + Weight::MAX - Weight::from_parts(1, 1) + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use sp_runtime::transaction_validity::{ + InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity, + ValidTransaction, + }; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: + frame_system::Config + + configuration::Config + + shared::Config + + frame_system::offchain::SendTransactionTypes> + { + type RuntimeEvent: From + IsType<::RuntimeEvent>; + + #[pallet::constant] + type UnsignedPriority: Get; + + type NextSessionRotation: EstimateNextSessionRotation>; + + /// Retrieve how many UMP messages are enqueued for this para-chain. + /// + /// This is used to judge whether or not a para-chain can offboard. Per default this should + /// be set to the `ParaInclusion` pallet. + type QueueFootprinter: QueueFootprinter; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// Current code has been updated for a Para. `para_id` + CurrentCodeUpdated(ParaId), + /// Current head has been updated for a Para. `para_id` + CurrentHeadUpdated(ParaId), + /// A code upgrade has been scheduled for a Para. `para_id` + CodeUpgradeScheduled(ParaId), + /// A new head has been noted for a Para. `para_id` + NewHeadNoted(ParaId), + /// A para has been queued to execute pending actions. `para_id` + ActionQueued(ParaId, SessionIndex), + /// The given para either initiated or subscribed to a PVF check for the given validation + /// code. `code_hash` `para_id` + PvfCheckStarted(ValidationCodeHash, ParaId), + /// The given validation code was accepted by the PVF pre-checking vote. + /// `code_hash` `para_id` + PvfCheckAccepted(ValidationCodeHash, ParaId), + /// The given validation code was rejected by the PVF pre-checking vote. + /// `code_hash` `para_id` + PvfCheckRejected(ValidationCodeHash, ParaId), + } + + #[pallet::error] + pub enum Error { + /// Para is not registered in our system. + NotRegistered, + /// Para cannot be onboarded because it is already tracked by our system. + CannotOnboard, + /// Para cannot be offboarded at this time. + CannotOffboard, + /// Para cannot be upgraded to a lease holding parachain. + CannotUpgrade, + /// Para cannot be downgraded to an on-demand parachain. + CannotDowngrade, + /// The statement for PVF pre-checking is stale. + PvfCheckStatementStale, + /// The statement for PVF pre-checking is for a future session. + PvfCheckStatementFuture, + /// Claimed validator index is out of bounds. + PvfCheckValidatorIndexOutOfBounds, + /// The signature for the PVF pre-checking is invalid. + PvfCheckInvalidSignature, + /// The given validator already has cast a vote. + PvfCheckDoubleVote, + /// The given PVF does not exist at the moment of process a vote. + PvfCheckSubjectInvalid, + /// Parachain cannot currently schedule a code upgrade. + CannotUpgradeCode, + } + + /// All currently active PVF pre-checking votes. + /// + /// Invariant: + /// - There are no PVF pre-checking votes that exists in list but not in the set and vice versa. + #[pallet::storage] + pub(super) type PvfActiveVoteMap = StorageMap< + _, + Twox64Concat, + ValidationCodeHash, + PvfCheckActiveVoteState>, + OptionQuery, + >; + + /// The list of all currently active PVF votes. Auxiliary to `PvfActiveVoteMap`. + #[pallet::storage] + pub(super) type PvfActiveVoteList = + StorageValue<_, Vec, ValueQuery>; + + /// All lease holding parachains. Ordered ascending by `ParaId`. On demand parachains are not + /// included. + /// + /// Consider using the [`ParachainsCache`] type of modifying. + #[pallet::storage] + #[pallet::getter(fn parachains)] + pub(crate) type Parachains = StorageValue<_, Vec, ValueQuery>; + + /// The current lifecycle of a all known Para IDs. + #[pallet::storage] + pub(super) type ParaLifecycles = StorageMap<_, Twox64Concat, ParaId, ParaLifecycle>; + + /// The head-data of every registered para. + #[pallet::storage] + #[pallet::getter(fn para_head)] + pub(super) type Heads = StorageMap<_, Twox64Concat, ParaId, HeadData>; + + /// The context (relay-chain block number) of the most recent parachain head. + #[pallet::storage] + #[pallet::getter(fn para_most_recent_context)] + pub(super) type MostRecentContext = + StorageMap<_, Twox64Concat, ParaId, BlockNumberFor>; + + /// The validation code hash of every live para. + /// + /// Corresponding code can be retrieved with [`CodeByHash`]. + #[pallet::storage] + #[pallet::getter(fn current_code_hash)] + pub(super) type CurrentCodeHash = + StorageMap<_, Twox64Concat, ParaId, ValidationCodeHash>; + + /// Actual past code hash, indicated by the para id as well as the block number at which it + /// became outdated. + /// + /// Corresponding code can be retrieved with [`CodeByHash`]. + #[pallet::storage] + pub(super) type PastCodeHash = + StorageMap<_, Twox64Concat, (ParaId, BlockNumberFor), ValidationCodeHash>; + + /// Past code of parachains. The parachains themselves may not be registered anymore, + /// but we also keep their code on-chain for the same amount of time as outdated code + /// to keep it available for approval checkers. + #[pallet::storage] + #[pallet::getter(fn past_code_meta)] + pub(super) type PastCodeMeta = + StorageMap<_, Twox64Concat, ParaId, ParaPastCodeMeta>, ValueQuery>; + + /// Which paras have past code that needs pruning and the relay-chain block at which the code + /// was replaced. Note that this is the actual height of the included block, not the expected + /// height at which the code upgrade would be applied, although they may be equal. + /// This is to ensure the entire acceptance period is covered, not an offset acceptance period + /// starting from the time at which the parachain perceives a code upgrade as having occurred. + /// Multiple entries for a single para are permitted. Ordered ascending by block number. + #[pallet::storage] + pub(super) type PastCodePruning = + StorageValue<_, Vec<(ParaId, BlockNumberFor)>, ValueQuery>; + + /// The block number at which the planned code change is expected for a para. + /// The change will be applied after the first parablock for this ID included which executes + /// in the context of a relay chain block with a number >= `expected_at`. + #[pallet::storage] + #[pallet::getter(fn future_code_upgrade_at)] + pub(super) type FutureCodeUpgrades = + StorageMap<_, Twox64Concat, ParaId, BlockNumberFor>; + + /// The actual future code hash of a para. + /// + /// Corresponding code can be retrieved with [`CodeByHash`]. + #[pallet::storage] + #[pallet::getter(fn future_code_hash)] + pub(super) type FutureCodeHash = + StorageMap<_, Twox64Concat, ParaId, ValidationCodeHash>; + + /// This is used by the relay-chain to communicate to a parachain a go-ahead with in the upgrade + /// procedure. + /// + /// This value is absent when there are no upgrades scheduled or during the time the relay chain + /// performs the checks. It is set at the first relay-chain block when the corresponding + /// parachain can switch its upgrade function. As soon as the parachain's block is included, the + /// value gets reset to `None`. + /// + /// NOTE that this field is used by parachains via merkle storage proofs, therefore changing + /// the format will require migration of parachains. + #[pallet::storage] + pub(super) type UpgradeGoAheadSignal = + StorageMap<_, Twox64Concat, ParaId, UpgradeGoAhead>; + + /// This is used by the relay-chain to communicate that there are restrictions for performing + /// an upgrade for this parachain. + /// + /// This may be a because the parachain waits for the upgrade cooldown to expire. Another + /// potential use case is when we want to perform some maintenance (such as storage migration) + /// we could restrict upgrades to make the process simpler. + /// + /// NOTE that this field is used by parachains via merkle storage proofs, therefore changing + /// the format will require migration of parachains. + #[pallet::storage] + #[pallet::getter(fn upgrade_restriction_signal)] + pub(super) type UpgradeRestrictionSignal = + StorageMap<_, Twox64Concat, ParaId, UpgradeRestriction>; + + /// The list of parachains that are awaiting for their upgrade restriction to cooldown. + /// + /// Ordered ascending by block number. + #[pallet::storage] + pub(super) type UpgradeCooldowns = + StorageValue<_, Vec<(ParaId, BlockNumberFor)>, ValueQuery>; + + /// The list of upcoming code upgrades. Each item is a pair of which para performs a code + /// upgrade and at which relay-chain block it is expected at. + /// + /// Ordered ascending by block number. + #[pallet::storage] + pub(super) type UpcomingUpgrades = + StorageValue<_, Vec<(ParaId, BlockNumberFor)>, ValueQuery>; + + /// The actions to perform during the start of a specific session index. + #[pallet::storage] + #[pallet::getter(fn actions_queue)] + pub(super) type ActionsQueue = + StorageMap<_, Twox64Concat, SessionIndex, Vec, ValueQuery>; + + /// Upcoming paras instantiation arguments. + /// + /// NOTE that after PVF pre-checking is enabled the para genesis arg will have it's code set + /// to empty. Instead, the code will be saved into the storage right away via `CodeByHash`. + #[pallet::storage] + pub(super) type UpcomingParasGenesis = + StorageMap<_, Twox64Concat, ParaId, ParaGenesisArgs>; + + /// The number of reference on the validation code in [`CodeByHash`] storage. + #[pallet::storage] + pub(super) type CodeByHashRefs = + StorageMap<_, Identity, ValidationCodeHash, u32, ValueQuery>; + + /// Validation code stored by its hash. + /// + /// This storage is consistent with [`FutureCodeHash`], [`CurrentCodeHash`] and + /// [`PastCodeHash`]. + #[pallet::storage] + #[pallet::getter(fn code_by_hash)] + pub(super) type CodeByHash = + StorageMap<_, Identity, ValidationCodeHash, ValidationCode>; + + #[pallet::genesis_config] + #[derive(DefaultNoBound)] + pub struct GenesisConfig { + #[serde(skip)] + pub _config: sp_std::marker::PhantomData, + pub paras: Vec<(ParaId, ParaGenesisArgs)>, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + let mut parachains = ParachainsCache::new(); + for (id, genesis_args) in &self.paras { + if genesis_args.validation_code.0.is_empty() { + panic!("empty validation code is not allowed in genesis"); + } + Pallet::::initialize_para_now(&mut parachains, *id, genesis_args); + } + // parachains are flushed on drop + } + } + + #[pallet::call] + impl Pallet { + /// Set the storage for the parachain validation code immediately. + #[pallet::call_index(0)] + #[pallet::weight(::WeightInfo::force_set_current_code(new_code.0.len() as u32))] + pub fn force_set_current_code( + origin: OriginFor, + para: ParaId, + new_code: ValidationCode, + ) -> DispatchResult { + ensure_root(origin)?; + let maybe_prior_code_hash = CurrentCodeHash::::get(¶); + let new_code_hash = new_code.hash(); + Self::increase_code_ref(&new_code_hash, &new_code); + CurrentCodeHash::::insert(¶, new_code_hash); + + let now = frame_system::Pallet::::block_number(); + if let Some(prior_code_hash) = maybe_prior_code_hash { + Self::note_past_code(para, now, now, prior_code_hash); + } else { + log::error!( + target: LOG_TARGET, + "Pallet paras storage is inconsistent, prior code not found {:?}", + ¶ + ); + } + Self::deposit_event(Event::CurrentCodeUpdated(para)); + Ok(()) + } + + /// Set the storage for the current parachain head data immediately. + #[pallet::call_index(1)] + #[pallet::weight(::WeightInfo::force_set_current_head(new_head.0.len() as u32))] + pub fn force_set_current_head( + origin: OriginFor, + para: ParaId, + new_head: HeadData, + ) -> DispatchResult { + ensure_root(origin)?; + Self::set_current_head(para, new_head); + Ok(()) + } + + /// Schedule an upgrade as if it was scheduled in the given relay parent block. + #[pallet::call_index(2)] + #[pallet::weight(::WeightInfo::force_schedule_code_upgrade(new_code.0.len() as u32))] + pub fn force_schedule_code_upgrade( + origin: OriginFor, + para: ParaId, + new_code: ValidationCode, + relay_parent_number: BlockNumberFor, + ) -> DispatchResult { + ensure_root(origin)?; + let config = configuration::Pallet::::config(); + Self::schedule_code_upgrade(para, new_code, relay_parent_number, &config); + Self::deposit_event(Event::CodeUpgradeScheduled(para)); + Ok(()) + } + + /// Note a new block head for para within the context of the current block. + #[pallet::call_index(3)] + #[pallet::weight(::WeightInfo::force_note_new_head(new_head.0.len() as u32))] + pub fn force_note_new_head( + origin: OriginFor, + para: ParaId, + new_head: HeadData, + ) -> DispatchResult { + ensure_root(origin)?; + let now = frame_system::Pallet::::block_number(); + Self::note_new_head(para, new_head, now); + Self::deposit_event(Event::NewHeadNoted(para)); + Ok(()) + } + + /// Put a parachain directly into the next session's action queue. + /// We can't queue it any sooner than this without going into the + /// initializer... + #[pallet::call_index(4)] + #[pallet::weight(::WeightInfo::force_queue_action())] + pub fn force_queue_action(origin: OriginFor, para: ParaId) -> DispatchResult { + ensure_root(origin)?; + let next_session = shared::Pallet::::session_index().saturating_add(One::one()); + ActionsQueue::::mutate(next_session, |v| { + if let Err(i) = v.binary_search(¶) { + v.insert(i, para); + } + }); + Self::deposit_event(Event::ActionQueued(para, next_session)); + Ok(()) + } + + /// Adds the validation code to the storage. + /// + /// The code will not be added if it is already present. Additionally, if PVF pre-checking + /// is running for that code, it will be instantly accepted. + /// + /// Otherwise, the code will be added into the storage. Note that the code will be added + /// into storage with reference count 0. This is to account the fact that there are no users + /// for this code yet. The caller will have to make sure that this code eventually gets + /// used by some parachain or removed from the storage to avoid storage leaks. For the + /// latter prefer to use the `poke_unused_validation_code` dispatchable to raw storage + /// manipulation. + /// + /// This function is mainly meant to be used for upgrading parachains that do not follow + /// the go-ahead signal while the PVF pre-checking feature is enabled. + #[pallet::call_index(5)] + #[pallet::weight(::WeightInfo::add_trusted_validation_code(validation_code.0.len() as u32))] + pub fn add_trusted_validation_code( + origin: OriginFor, + validation_code: ValidationCode, + ) -> DispatchResult { + ensure_root(origin)?; + let code_hash = validation_code.hash(); + + if let Some(vote) = PvfActiveVoteMap::::get(&code_hash) { + // Remove the existing vote. + PvfActiveVoteMap::::remove(&code_hash); + PvfActiveVoteList::::mutate(|l| { + if let Ok(i) = l.binary_search(&code_hash) { + l.remove(i); + } + }); + + let cfg = configuration::Pallet::::config(); + Self::enact_pvf_accepted( + >::block_number(), + &code_hash, + &vote.causes, + vote.age, + &cfg, + ); + return Ok(()) + } + + if CodeByHash::::contains_key(&code_hash) { + // There is no vote, but the code exists. Nothing to do here. + return Ok(()) + } + + // At this point the code is unknown and there is no PVF pre-checking vote for it, so we + // can just add the code into the storage. + // + // NOTE That we do not use `increase_code_ref` here, because the code is not yet used + // by any parachain. + CodeByHash::::insert(code_hash, &validation_code); + + Ok(()) + } + + /// Remove the validation code from the storage iff the reference count is 0. + /// + /// This is better than removing the storage directly, because it will not remove the code + /// that was suddenly got used by some parachain while this dispatchable was pending + /// dispatching. + #[pallet::call_index(6)] + #[pallet::weight(::WeightInfo::poke_unused_validation_code())] + pub fn poke_unused_validation_code( + origin: OriginFor, + validation_code_hash: ValidationCodeHash, + ) -> DispatchResult { + ensure_root(origin)?; + if CodeByHashRefs::::get(&validation_code_hash) == 0 { + CodeByHash::::remove(&validation_code_hash); + } + Ok(()) + } + + /// Includes a statement for a PVF pre-checking vote. Potentially, finalizes the vote and + /// enacts the results if that was the last vote before achieving the supermajority. + #[pallet::call_index(7)] + #[pallet::weight( + ::WeightInfo::include_pvf_check_statement_finalize_upgrade_accept() + .max(::WeightInfo::include_pvf_check_statement_finalize_upgrade_reject()) + .max(::WeightInfo::include_pvf_check_statement_finalize_onboarding_accept() + .max(::WeightInfo::include_pvf_check_statement_finalize_onboarding_reject()) + ) + )] + pub fn include_pvf_check_statement( + origin: OriginFor, + stmt: PvfCheckStatement, + signature: ValidatorSignature, + ) -> DispatchResultWithPostInfo { + ensure_none(origin)?; + + let validators = shared::Pallet::::active_validator_keys(); + let current_session = shared::Pallet::::session_index(); + if stmt.session_index < current_session { + return Err(Error::::PvfCheckStatementStale.into()) + } else if stmt.session_index > current_session { + return Err(Error::::PvfCheckStatementFuture.into()) + } + let validator_index = stmt.validator_index.0 as usize; + let validator_public = validators + .get(validator_index) + .ok_or(Error::::PvfCheckValidatorIndexOutOfBounds)?; + + let signing_payload = stmt.signing_payload(); + ensure!( + signature.verify(&signing_payload[..], &validator_public), + Error::::PvfCheckInvalidSignature, + ); + + let mut active_vote = PvfActiveVoteMap::::get(&stmt.subject) + .ok_or(Error::::PvfCheckSubjectInvalid)?; + + // Ensure that the validator submitting this statement hasn't voted already. + ensure!( + !active_vote + .has_vote(validator_index) + .ok_or(Error::::PvfCheckValidatorIndexOutOfBounds)?, + Error::::PvfCheckDoubleVote, + ); + + // Finally, cast the vote and persist. + if stmt.accept { + active_vote.votes_accept.set(validator_index, true); + } else { + active_vote.votes_reject.set(validator_index, true); + } + + if let Some(outcome) = active_vote.quorum(validators.len()) { + // The quorum has been achieved. + // + // Remove the PVF vote from the active map and finalize the PVF checking according + // to the outcome. + PvfActiveVoteMap::::remove(&stmt.subject); + PvfActiveVoteList::::mutate(|l| { + if let Ok(i) = l.binary_search(&stmt.subject) { + l.remove(i); + } + }); + match outcome { + PvfCheckOutcome::Accepted => { + let cfg = configuration::Pallet::::config(); + Self::enact_pvf_accepted( + >::block_number(), + &stmt.subject, + &active_vote.causes, + active_vote.age, + &cfg, + ); + }, + PvfCheckOutcome::Rejected => { + Self::enact_pvf_rejected(&stmt.subject, active_vote.causes); + }, + } + + // No weight refund since this statement was the last one and lead to finalization. + Ok(().into()) + } else { + // No quorum has been achieved. + // + // - So just store the updated state back into the storage. + // - Only charge weight for simple vote inclusion. + PvfActiveVoteMap::::insert(&stmt.subject, active_vote); + Ok(Some(::WeightInfo::include_pvf_check_statement()).into()) + } + } + + /// Set the storage for the current parachain head data immediately. + #[pallet::call_index(8)] + #[pallet::weight(::WeightInfo::force_set_most_recent_context())] + pub fn force_set_most_recent_context( + origin: OriginFor, + para: ParaId, + context: BlockNumberFor, + ) -> DispatchResult { + ensure_root(origin)?; + MostRecentContext::::insert(¶, context); + Ok(()) + } + } + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + + fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { + let (stmt, signature) = match call { + Call::include_pvf_check_statement { stmt, signature } => (stmt, signature), + _ => return InvalidTransaction::Call.into(), + }; + + let current_session = shared::Pallet::::session_index(); + if stmt.session_index < current_session { + return InvalidTransaction::Stale.into() + } else if stmt.session_index > current_session { + return InvalidTransaction::Future.into() + } + + let validator_index = stmt.validator_index.0 as usize; + let validators = shared::Pallet::::active_validator_keys(); + let validator_public = match validators.get(validator_index) { + Some(pk) => pk, + None => return InvalidTransaction::Custom(INVALID_TX_BAD_VALIDATOR_IDX).into(), + }; + + let signing_payload = stmt.signing_payload(); + if !signature.verify(&signing_payload[..], &validator_public) { + return InvalidTransaction::BadProof.into() + } + + let active_vote = match PvfActiveVoteMap::::get(&stmt.subject) { + Some(v) => v, + None => return InvalidTransaction::Custom(INVALID_TX_BAD_SUBJECT).into(), + }; + + match active_vote.has_vote(validator_index) { + Some(false) => (), + Some(true) => return InvalidTransaction::Custom(INVALID_TX_DOUBLE_VOTE).into(), + None => return InvalidTransaction::Custom(INVALID_TX_BAD_VALIDATOR_IDX).into(), + } + + ValidTransaction::with_tag_prefix("PvfPreCheckingVote") + .priority(T::UnsignedPriority::get()) + .longevity( + TryInto::::try_into( + T::NextSessionRotation::average_session_length() / 2u32.into(), + ) + .unwrap_or(64_u64), + ) + .and_provides((stmt.session_index, stmt.validator_index, stmt.subject)) + .propagate(true) + .build() + } + + fn pre_dispatch(_call: &Self::Call) -> Result<(), TransactionValidityError> { + // Return `Ok` here meaning that as soon as the transaction got into the block, it will + // always dispatched. This is OK, since the `include_pvf_check_statement` dispatchable + // will perform the same checks anyway, so there is no point doing it here. + // + // On the other hand, if we did not provide the implementation, then the default + // implementation would be used. The default implementation just delegates the + // pre-dispatch validation to `validate_unsigned`. + Ok(()) + } + } +} + +// custom transaction error codes +const INVALID_TX_BAD_VALIDATOR_IDX: u8 = 1; +const INVALID_TX_BAD_SUBJECT: u8 = 2; +const INVALID_TX_DOUBLE_VOTE: u8 = 3; + +impl Pallet { + /// This is a call to schedule code upgrades for parachains which is safe to be called + /// outside of this module. That means this function does all checks necessary to ensure + /// that some external code is allowed to trigger a code upgrade. We do not do auth checks, + /// that should be handled by whomever calls this function. + pub(crate) fn schedule_code_upgrade_external( + id: ParaId, + new_code: ValidationCode, + ) -> DispatchResult { + // Check that we can schedule an upgrade at all. + ensure!(Self::can_upgrade_validation_code(id), Error::::CannotUpgradeCode); + let config = configuration::Pallet::::config(); + let current_block = frame_system::Pallet::::block_number(); + // Schedule the upgrade with a delay just like if a parachain triggered the upgrade. + let upgrade_block = current_block.saturating_add(config.validation_upgrade_delay); + Self::schedule_code_upgrade(id, new_code, upgrade_block, &config); + Self::deposit_event(Event::CodeUpgradeScheduled(id)); + Ok(()) + } + + /// Set the current head of a parachain. + pub(crate) fn set_current_head(para: ParaId, new_head: HeadData) { + Heads::::insert(¶, new_head); + Self::deposit_event(Event::CurrentHeadUpdated(para)); + } + + /// Called by the initializer to initialize the paras pallet. + pub(crate) fn initializer_initialize(now: BlockNumberFor) -> Weight { + let weight = Self::prune_old_code(now); + weight + Self::process_scheduled_upgrade_changes(now) + } + + /// Called by the initializer to finalize the paras pallet. + pub(crate) fn initializer_finalize(now: BlockNumberFor) { + Self::process_scheduled_upgrade_cooldowns(now); + } + + /// Called by the initializer to note that a new session has started. + /// + /// Returns the list of outgoing paras from the actions queue. + pub(crate) fn initializer_on_new_session( + notification: &SessionChangeNotification>, + ) -> Vec { + let outgoing_paras = Self::apply_actions_queue(notification.session_index); + Self::groom_ongoing_pvf_votes(¬ification.new_config, notification.validators.len()); + outgoing_paras + } + + /// The validation code of live para. + pub(crate) fn current_code(para_id: &ParaId) -> Option { + Self::current_code_hash(para_id).and_then(|code_hash| { + let code = CodeByHash::::get(&code_hash); + if code.is_none() { + log::error!( + "Pallet paras storage is inconsistent, code not found for hash {}", + code_hash, + ); + debug_assert!(false, "inconsistent paras storages"); + } + code + }) + } + + // Apply all para actions queued for the given session index. + // + // The actions to take are based on the lifecycle of of the paras. + // + // The final state of any para after the actions queue should be as a + // lease holding parachain, on-demand parachain, or not registered. (stable states) + // + // Returns the list of outgoing paras from the actions queue. + fn apply_actions_queue(session: SessionIndex) -> Vec { + let actions = ActionsQueue::::take(session); + let mut parachains = ParachainsCache::new(); + let now = >::block_number(); + let mut outgoing = Vec::new(); + + for para in actions { + let lifecycle = ParaLifecycles::::get(¶); + match lifecycle { + None | Some(ParaLifecycle::Parathread) | Some(ParaLifecycle::Parachain) => { /* Nothing to do... */ + }, + Some(ParaLifecycle::Onboarding) => { + if let Some(genesis_data) = UpcomingParasGenesis::::take(¶) { + Self::initialize_para_now(&mut parachains, para, &genesis_data); + } + }, + // Upgrade an on-demand parachain to a lease holding parachain + Some(ParaLifecycle::UpgradingParathread) => { + parachains.add(para); + ParaLifecycles::::insert(¶, ParaLifecycle::Parachain); + }, + // Downgrade a lease holding parachain to an on-demand parachain + Some(ParaLifecycle::DowngradingParachain) => { + parachains.remove(para); + ParaLifecycles::::insert(¶, ParaLifecycle::Parathread); + }, + // Offboard a lease holding or on-demand parachain from the system + Some(ParaLifecycle::OffboardingParachain) | + Some(ParaLifecycle::OffboardingParathread) => { + parachains.remove(para); + + Heads::::remove(¶); + MostRecentContext::::remove(¶); + FutureCodeUpgrades::::remove(¶); + UpgradeGoAheadSignal::::remove(¶); + UpgradeRestrictionSignal::::remove(¶); + ParaLifecycles::::remove(¶); + let removed_future_code_hash = FutureCodeHash::::take(¶); + if let Some(removed_future_code_hash) = removed_future_code_hash { + Self::decrease_code_ref(&removed_future_code_hash); + } + + let removed_code_hash = CurrentCodeHash::::take(¶); + if let Some(removed_code_hash) = removed_code_hash { + Self::note_past_code(para, now, now, removed_code_hash); + } + + outgoing.push(para); + }, + } + } + + if !outgoing.is_empty() { + // Filter offboarded parachains from the upcoming upgrades and upgrade cooldowns list. + // + // We do it after the offboarding to get away with only a single read/write per list. + // + // NOTE both of those iterates over the list and the outgoing. We do not expect either + // of these to be large. Thus should be fine. + UpcomingUpgrades::::mutate(|upcoming_upgrades| { + *upcoming_upgrades = mem::take(upcoming_upgrades) + .into_iter() + .filter(|(para, _)| !outgoing.contains(para)) + .collect(); + }); + UpgradeCooldowns::::mutate(|upgrade_cooldowns| { + *upgrade_cooldowns = mem::take(upgrade_cooldowns) + .into_iter() + .filter(|(para, _)| !outgoing.contains(para)) + .collect(); + }); + } + + // Persist parachains into the storage explicitly. + drop(parachains); + + outgoing + } + + // note replacement of the code of para with given `id`, which occured in the + // context of the given relay-chain block number. provide the replaced code. + // + // `at` for para-triggered replacement is the block number of the relay-chain + // block in whose context the parablock was executed + // (i.e. number of `relay_parent` in the receipt) + fn note_past_code( + id: ParaId, + at: BlockNumberFor, + now: BlockNumberFor, + old_code_hash: ValidationCodeHash, + ) -> Weight { + PastCodeMeta::::mutate(&id, |past_meta| { + past_meta.note_replacement(at, now); + }); + + PastCodeHash::::insert(&(id, at), old_code_hash); + + // Schedule pruning for this past-code to be removed as soon as it + // exits the slashing window. + PastCodePruning::::mutate(|pruning| { + let insert_idx = + pruning.binary_search_by_key(&now, |&(_, b)| b).unwrap_or_else(|idx| idx); + pruning.insert(insert_idx, (id, now)); + }); + + T::DbWeight::get().reads_writes(2, 3) + } + + // looks at old code metadata, compares them to the current acceptance window, and prunes those + // that are too old. + fn prune_old_code(now: BlockNumberFor) -> Weight { + let config = configuration::Pallet::::config(); + let code_retention_period = config.code_retention_period; + if now <= code_retention_period { + let weight = T::DbWeight::get().reads_writes(1, 0); + return weight + } + + // The height of any changes we no longer should keep around. + let pruning_height = now - (code_retention_period + One::one()); + + let pruning_tasks_done = + PastCodePruning::::mutate(|pruning_tasks: &mut Vec<(_, BlockNumberFor)>| { + let (pruning_tasks_done, pruning_tasks_to_do) = { + // find all past code that has just exited the pruning window. + let up_to_idx = + pruning_tasks.iter().take_while(|&(_, at)| at <= &pruning_height).count(); + (up_to_idx, pruning_tasks.drain(..up_to_idx)) + }; + + for (para_id, _) in pruning_tasks_to_do { + let full_deactivate = PastCodeMeta::::mutate(¶_id, |meta| { + for pruned_repl_at in meta.prune_up_to(pruning_height) { + let removed_code_hash = + PastCodeHash::::take(&(para_id, pruned_repl_at)); + + if let Some(removed_code_hash) = removed_code_hash { + Self::decrease_code_ref(&removed_code_hash); + } else { + log::warn!( + target: LOG_TARGET, + "Missing code for removed hash {:?}", + removed_code_hash, + ); + } + } + + meta.is_empty() && Self::para_head(¶_id).is_none() + }); + + // This parachain has been removed and now the vestigial code + // has been removed from the state. clean up meta as well. + if full_deactivate { + PastCodeMeta::::remove(¶_id); + } + } + + pruning_tasks_done as u64 + }); + + // 1 read for the meta for each pruning task, 1 read for the config + // 2 writes: updating the meta and pruning the code + T::DbWeight::get().reads_writes(1 + pruning_tasks_done, 2 * pruning_tasks_done) + } + + /// Process the timers related to upgrades. Specifically, the upgrade go ahead signals toggle + /// and the upgrade cooldown restrictions. However, this function does not actually unset + /// the upgrade restriction, that will happen in the `initializer_finalize` function. However, + /// this function does count the number of cooldown timers expired so that we can reserve weight + /// for the `initializer_finalize` function. + fn process_scheduled_upgrade_changes(now: BlockNumberFor) -> Weight { + // account weight for `UpcomingUpgrades::mutate`. + let mut weight = T::DbWeight::get().reads_writes(1, 1); + let upgrades_signaled = UpcomingUpgrades::::mutate( + |upcoming_upgrades: &mut Vec<(ParaId, BlockNumberFor)>| { + let num = upcoming_upgrades.iter().take_while(|&(_, at)| at <= &now).count(); + for (para, _) in upcoming_upgrades.drain(..num) { + UpgradeGoAheadSignal::::insert(¶, UpgradeGoAhead::GoAhead); + } + num + }, + ); + weight += T::DbWeight::get().writes(upgrades_signaled as u64); + + // account weight for `UpgradeCooldowns::get`. + weight += T::DbWeight::get().reads(1); + let cooldowns_expired = + UpgradeCooldowns::::get().iter().take_while(|&(_, at)| at <= &now).count(); + + // reserve weight for `initializer_finalize`: + // - 1 read and 1 write for `UpgradeCooldowns::mutate`. + // - 1 write per expired cooldown. + weight += T::DbWeight::get().reads_writes(1, 1); + weight += T::DbWeight::get().reads(cooldowns_expired as u64); + + weight + } + + /// Actually perform unsetting the expired upgrade restrictions. + /// + /// See `process_scheduled_upgrade_changes` for more details. + fn process_scheduled_upgrade_cooldowns(now: BlockNumberFor) { + UpgradeCooldowns::::mutate( + |upgrade_cooldowns: &mut Vec<(ParaId, BlockNumberFor)>| { + // Remove all expired signals and also prune the cooldowns. + upgrade_cooldowns.retain(|(para, at)| { + if at <= &now { + UpgradeRestrictionSignal::::remove(¶); + false + } else { + true + } + }); + }, + ); + } + + /// Goes over all PVF votes in progress, reinitializes ballots, increments ages and prunes the + /// active votes that reached their time-to-live. + fn groom_ongoing_pvf_votes( + cfg: &configuration::HostConfiguration>, + new_n_validators: usize, + ) -> Weight { + let mut weight = T::DbWeight::get().reads(1); + + let potentially_active_votes = PvfActiveVoteList::::get(); + + // Initially empty list which contains all the PVF active votes that made it through this + // session change. + // + // **Ordered** as well as `PvfActiveVoteList`. + let mut actually_active_votes = Vec::with_capacity(potentially_active_votes.len()); + + for vote_subject in potentially_active_votes { + let mut vote_state = match PvfActiveVoteMap::::take(&vote_subject) { + Some(v) => v, + None => { + // This branch should never be reached. This is due to the fact that the set of + // `PvfActiveVoteMap`'s keys is always equal to the set of items found in + // `PvfActiveVoteList`. + log::warn!( + target: LOG_TARGET, + "The PvfActiveVoteMap is out of sync with PvfActiveVoteList!", + ); + debug_assert!(false); + continue + }, + }; + + vote_state.age += 1; + if vote_state.age < cfg.pvf_voting_ttl { + weight += T::DbWeight::get().writes(1); + vote_state.reinitialize_ballots(new_n_validators); + PvfActiveVoteMap::::insert(&vote_subject, vote_state); + + // push maintaining the original order. + actually_active_votes.push(vote_subject); + } else { + // TTL is reached. Reject. + weight += Self::enact_pvf_rejected(&vote_subject, vote_state.causes); + } + } + + weight += T::DbWeight::get().writes(1); + PvfActiveVoteList::::put(actually_active_votes); + + weight + } + + fn enact_pvf_accepted( + now: BlockNumberFor, + code_hash: &ValidationCodeHash, + causes: &[PvfCheckCause>], + sessions_observed: SessionIndex, + cfg: &configuration::HostConfiguration>, + ) -> Weight { + let mut weight = Weight::zero(); + for cause in causes { + weight += T::DbWeight::get().reads_writes(3, 2); + Self::deposit_event(Event::PvfCheckAccepted(*code_hash, cause.para_id())); + + match cause { + PvfCheckCause::Onboarding(id) => { + weight += Self::proceed_with_onboarding(*id, sessions_observed); + }, + PvfCheckCause::Upgrade { id, included_at } => { + weight += Self::proceed_with_upgrade(*id, code_hash, now, *included_at, cfg); + }, + } + } + weight + } + + fn proceed_with_onboarding(id: ParaId, sessions_observed: SessionIndex) -> Weight { + let weight = T::DbWeight::get().reads_writes(2, 1); + + // we should onboard only after `SESSION_DELAY` sessions but we should take + // into account the number of sessions the PVF pre-checking occupied. + // + // we cannot onboard at the current session, so it must be at least one + // session ahead. + let onboard_at: SessionIndex = shared::Pallet::::session_index() + + cmp::max(shared::SESSION_DELAY.saturating_sub(sessions_observed), 1); + + ActionsQueue::::mutate(onboard_at, |v| { + if let Err(i) = v.binary_search(&id) { + v.insert(i, id); + } + }); + + weight + } + + fn proceed_with_upgrade( + id: ParaId, + code_hash: &ValidationCodeHash, + now: BlockNumberFor, + relay_parent_number: BlockNumberFor, + cfg: &configuration::HostConfiguration>, + ) -> Weight { + let mut weight = Weight::zero(); + + // Compute the relay-chain block number starting at which the code upgrade is ready to be + // applied. + // + // The first parablock that has a relay-parent higher or at the same height of `expected_at` + // will trigger the code upgrade. The parablock that comes after that will be validated + // against the new validation code. + // + // Here we are trying to choose the block number that will have `validation_upgrade_delay` + // blocks from the relay-parent of inclusion of the the block that scheduled code upgrade + // but no less than `minimum_validation_upgrade_delay`. We want this delay out of caution + // so that when the last vote for pre-checking comes the parachain will have some time until + // the upgrade finally takes place. + let expected_at = cmp::max( + relay_parent_number + cfg.validation_upgrade_delay, + now + cfg.minimum_validation_upgrade_delay, + ); + + weight += T::DbWeight::get().reads_writes(1, 4); + FutureCodeUpgrades::::insert(&id, expected_at); + + UpcomingUpgrades::::mutate(|upcoming_upgrades| { + let insert_idx = upcoming_upgrades + .binary_search_by_key(&expected_at, |&(_, b)| b) + .unwrap_or_else(|idx| idx); + upcoming_upgrades.insert(insert_idx, (id, expected_at)); + }); + + let expected_at = expected_at.saturated_into(); + let log = ConsensusLog::ParaScheduleUpgradeCode(id, *code_hash, expected_at); + >::deposit_log(log.into()); + + weight + } + + fn enact_pvf_rejected( + code_hash: &ValidationCodeHash, + causes: Vec>>, + ) -> Weight { + let mut weight = Weight::zero(); + + for cause in causes { + // Whenever PVF pre-checking is started or a new cause is added to it, the RC is bumped. + // Now we need to unbump it. + weight += Self::decrease_code_ref(code_hash); + + weight += T::DbWeight::get().reads_writes(3, 2); + Self::deposit_event(Event::PvfCheckRejected(*code_hash, cause.para_id())); + + match cause { + PvfCheckCause::Onboarding(id) => { + // Here we need to undo everything that was done during + // `schedule_para_initialize`. Essentially, the logic is similar to offboarding, + // with exception that before actual onboarding the parachain did not have a + // chance to reach to upgrades. Therefore we can skip all the upgrade related + // storage items here. + weight += T::DbWeight::get().writes(3); + UpcomingParasGenesis::::remove(&id); + CurrentCodeHash::::remove(&id); + ParaLifecycles::::remove(&id); + }, + PvfCheckCause::Upgrade { id, .. } => { + weight += T::DbWeight::get().writes(2); + UpgradeGoAheadSignal::::insert(&id, UpgradeGoAhead::Abort); + FutureCodeHash::::remove(&id); + }, + } + } + + weight + } + + /// Verify that `schedule_para_initialize` can be called successfully. + /// + /// Returns false if para is already registered in the system. + pub fn can_schedule_para_initialize(id: &ParaId) -> bool { + ParaLifecycles::::get(id).is_none() + } + + /// Schedule a para to be initialized. If the validation code is not already stored in the + /// code storage, then a PVF pre-checking process will be initiated. + /// + /// Only after the PVF pre-checking succeeds can the para be onboarded. Note, that calling this + /// does not guarantee that the parachain will eventually be onboarded. This can happen in case + /// the PVF does not pass PVF pre-checking. + /// + /// The Para ID should be not activated in this pallet. The validation code supplied in + /// `genesis_data` should not be empty. If those conditions are not met, then the para cannot + /// be onboarded. + pub(crate) fn schedule_para_initialize( + id: ParaId, + mut genesis_data: ParaGenesisArgs, + ) -> DispatchResult { + // Make sure parachain isn't already in our system and that the onboarding parameters are + // valid. + ensure!(Self::can_schedule_para_initialize(&id), Error::::CannotOnboard); + ensure!(!genesis_data.validation_code.0.is_empty(), Error::::CannotOnboard); + ParaLifecycles::::insert(&id, ParaLifecycle::Onboarding); + + // HACK: here we are doing something nasty. + // + // In order to fix the [soaking issue] we insert the code eagerly here. When the onboarding + // is finally enacted, we do not need to insert the code anymore. Therefore, there is no + // reason for the validation code to be copied into the `ParaGenesisArgs`. We also do not + // want to risk it by copying the validation code needlessly to not risk adding more + // memory pressure. + // + // That said, we also want to preserve `ParaGenesisArgs` as it is, for now. There are two + // reasons: + // + // - Doing it within the context of the PR that introduces this change is undesirable, since + // it is already a big change, and that change would require a migration. Moreover, if we + // run the new version of the runtime, there will be less things to worry about during the + // eventual proper migration. + // + // - This data type already is used for generating genesis, and changing it will probably + // introduce some unnecessary burden. + // + // So instead of going through it right now, we will do something sneaky. Specifically: + // + // - Insert the `CurrentCodeHash` now, instead during the onboarding. That would allow to + // get rid of hashing of the validation code when onboarding. + // + // - Replace `validation_code` with a sentinel value: an empty vector. This should be fine + // as long we do not allow registering parachains with empty code. At the moment of + // writing this should already be the case. + // + // - Empty value is treated as the current code is already inserted during the onboarding. + // + // This is only an intermediate solution and should be fixed in foreseable future. + // + // [soaking issue]: https://github.com/paritytech/polkadot/issues/3918 + let validation_code = + mem::replace(&mut genesis_data.validation_code, ValidationCode(Vec::new())); + UpcomingParasGenesis::::insert(&id, genesis_data); + let validation_code_hash = validation_code.hash(); + CurrentCodeHash::::insert(&id, validation_code_hash); + + let cfg = configuration::Pallet::::config(); + Self::kick_off_pvf_check( + PvfCheckCause::Onboarding(id), + validation_code_hash, + validation_code, + &cfg, + ); + + Ok(()) + } + + /// Schedule a para to be cleaned up at the start of the next session. + /// + /// Will return error if either is true: + /// + /// - para is not a stable parachain (i.e. [`ParaLifecycle::is_stable`] is `false`) + /// - para has a pending upgrade. + /// - para has unprocessed messages in its UMP queue. + /// + /// No-op if para is not registered at all. + pub(crate) fn schedule_para_cleanup(id: ParaId) -> DispatchResult { + // Disallow offboarding in case there is a PVF pre-checking in progress. + // + // This is not a fundamental limitation but rather simplification: it allows us to get + // away without introducing additional logic for pruning and, more importantly, enacting + // ongoing PVF pre-checking votes. It also removes some nasty edge cases. + // + // However, an upcoming upgrade on its own imposes no restrictions. An upgrade is enacted + // with a new para head, so if a para never progresses we still should be able to offboard + // it. + // + // This implicitly assumes that the given para exists, i.e. it's lifecycle != None. + if let Some(future_code_hash) = FutureCodeHash::::get(&id) { + let active_prechecking = PvfActiveVoteList::::get(); + if active_prechecking.contains(&future_code_hash) { + return Err(Error::::CannotOffboard.into()) + } + } + + let lifecycle = ParaLifecycles::::get(&id); + match lifecycle { + // If para is not registered, nothing to do! + None => return Ok(()), + Some(ParaLifecycle::Parathread) => { + ParaLifecycles::::insert(&id, ParaLifecycle::OffboardingParathread); + }, + Some(ParaLifecycle::Parachain) => { + ParaLifecycles::::insert(&id, ParaLifecycle::OffboardingParachain); + }, + _ => return Err(Error::::CannotOffboard.into()), + } + + let scheduled_session = Self::scheduled_session(); + ActionsQueue::::mutate(scheduled_session, |v| { + if let Err(i) = v.binary_search(&id) { + v.insert(i, id); + } + }); + + if ::QueueFootprinter::message_count(UmpQueueId::Para(id)) != 0 { + return Err(Error::::CannotOffboard.into()) + } + + Ok(()) + } + + /// Schedule a parathread (on-demand parachain) to be upgraded to a lease holding parachain. + /// + /// Will return error if `ParaLifecycle` is not `Parathread`. + pub(crate) fn schedule_parathread_upgrade(id: ParaId) -> DispatchResult { + let scheduled_session = Self::scheduled_session(); + let lifecycle = ParaLifecycles::::get(&id).ok_or(Error::::NotRegistered)?; + + ensure!(lifecycle == ParaLifecycle::Parathread, Error::::CannotUpgrade); + + ParaLifecycles::::insert(&id, ParaLifecycle::UpgradingParathread); + ActionsQueue::::mutate(scheduled_session, |v| { + if let Err(i) = v.binary_search(&id) { + v.insert(i, id); + } + }); + + Ok(()) + } + + /// Schedule a lease holding parachain to be downgraded to an on-demand parachain. + /// + /// Noop if `ParaLifecycle` is not `Parachain`. + pub(crate) fn schedule_parachain_downgrade(id: ParaId) -> DispatchResult { + let scheduled_session = Self::scheduled_session(); + let lifecycle = ParaLifecycles::::get(&id).ok_or(Error::::NotRegistered)?; + + ensure!(lifecycle == ParaLifecycle::Parachain, Error::::CannotDowngrade); + + ParaLifecycles::::insert(&id, ParaLifecycle::DowngradingParachain); + ActionsQueue::::mutate(scheduled_session, |v| { + if let Err(i) = v.binary_search(&id) { + v.insert(i, id); + } + }); + + Ok(()) + } + + /// Schedule a future code upgrade of the given parachain. + /// + /// If the new code is not known, then the PVF pre-checking will be started for that validation + /// code. In case the validation code does not pass the PVF pre-checking process, the + /// upgrade will be aborted. + /// + /// Only after the code is approved by the process, the upgrade can be scheduled. Specifically, + /// the relay-chain block number will be determined at which the upgrade will take place. We + /// call that block `expected_at`. + /// + /// Once the candidate with the relay-parent >= `expected_at` is enacted, the new validation + /// code will be applied. Therefore, the new code will be used to validate the next candidate. + /// + /// The new code should not be equal to the current one, otherwise the upgrade will be aborted. + /// If there is already a scheduled code upgrade for the para, this is a no-op. + /// + /// Inclusion block number specifies relay parent which enacted candidate initiating the + /// upgrade. + pub(crate) fn schedule_code_upgrade( + id: ParaId, + new_code: ValidationCode, + inclusion_block_number: BlockNumberFor, + cfg: &configuration::HostConfiguration>, + ) -> Weight { + let mut weight = T::DbWeight::get().reads(1); + + // Enacting this should be prevented by the `can_schedule_upgrade` + if FutureCodeHash::::contains_key(&id) { + // This branch should never be reached. Signalling an upgrade is disallowed for a para + // that already has one upgrade scheduled. + // + // Any candidate that attempts to do that should be rejected by + // `can_upgrade_validation_code`. + // + // NOTE: we cannot set `UpgradeGoAheadSignal` signal here since this will be reset by + // the following call `note_new_head` + log::warn!(target: LOG_TARGET, "ended up scheduling an upgrade while one is pending",); + return weight + } + + let code_hash = new_code.hash(); + + // para signals an update to the same code? This does not make a lot of sense, so abort the + // process right away. + // + // We do not want to allow this since it will mess with the code reference counting. + weight += T::DbWeight::get().reads(1); + if CurrentCodeHash::::get(&id) == Some(code_hash) { + // NOTE: we cannot set `UpgradeGoAheadSignal` signal here since this will be reset by + // the following call `note_new_head` + log::warn!( + target: LOG_TARGET, + "para tried to upgrade to the same code. Abort the upgrade", + ); + return weight + } + + // This is the start of the upgrade process. Prevent any further attempts at upgrading. + weight += T::DbWeight::get().writes(2); + FutureCodeHash::::insert(&id, &code_hash); + UpgradeRestrictionSignal::::insert(&id, UpgradeRestriction::Present); + + weight += T::DbWeight::get().reads_writes(1, 1); + let next_possible_upgrade_at = inclusion_block_number + cfg.validation_upgrade_cooldown; + UpgradeCooldowns::::mutate(|upgrade_cooldowns| { + let insert_idx = upgrade_cooldowns + .binary_search_by_key(&next_possible_upgrade_at, |&(_, b)| b) + .unwrap_or_else(|idx| idx); + upgrade_cooldowns.insert(insert_idx, (id, next_possible_upgrade_at)); + }); + + weight += Self::kick_off_pvf_check( + PvfCheckCause::Upgrade { id, included_at: inclusion_block_number }, + code_hash, + new_code, + cfg, + ); + + weight + } + + /// Makes sure that the given code hash has passed pre-checking. + /// + /// If the given code hash has already passed pre-checking, then the approval happens + /// immediately. + /// + /// If the code is unknown, but the pre-checking for that PVF is already running then we perform + /// "coalescing". We save the cause for this PVF pre-check request and just add it to the + /// existing active PVF vote. + /// + /// And finally, if the code is unknown and pre-checking is not running, we start the + /// pre-checking process anew. + /// + /// Unconditionally increases the reference count for the passed `code`. + fn kick_off_pvf_check( + cause: PvfCheckCause>, + code_hash: ValidationCodeHash, + code: ValidationCode, + cfg: &configuration::HostConfiguration>, + ) -> Weight { + let mut weight = Weight::zero(); + + weight += T::DbWeight::get().reads_writes(3, 2); + Self::deposit_event(Event::PvfCheckStarted(code_hash, cause.para_id())); + + weight += T::DbWeight::get().reads(1); + match PvfActiveVoteMap::::get(&code_hash) { + None => { + // We deliberately are using `CodeByHash` here instead of the `CodeByHashRefs`. This + // is because the code may have been added by `add_trusted_validation_code`. + let known_code = CodeByHash::::contains_key(&code_hash); + weight += T::DbWeight::get().reads(1); + + if known_code { + // The code is known and there is no active PVF vote for it meaning it is + // already checked -- fast track the PVF checking into the accepted state. + weight += T::DbWeight::get().reads(1); + let now = >::block_number(); + weight += Self::enact_pvf_accepted(now, &code_hash, &[cause], 0, cfg); + } else { + // PVF is not being pre-checked and it is not known. Start a new pre-checking + // process. + weight += T::DbWeight::get().reads_writes(3, 2); + let now = >::block_number(); + let n_validators = shared::Pallet::::active_validator_keys().len(); + PvfActiveVoteMap::::insert( + &code_hash, + PvfCheckActiveVoteState::new(now, n_validators, cause), + ); + PvfActiveVoteList::::mutate(|l| { + if let Err(idx) = l.binary_search(&code_hash) { + l.insert(idx, code_hash); + } + }); + } + }, + Some(mut vote_state) => { + // Coalescing: the PVF is already being pre-checked so we just need to piggy back + // on it. + weight += T::DbWeight::get().writes(1); + vote_state.causes.push(cause); + PvfActiveVoteMap::::insert(&code_hash, vote_state); + }, + } + + // We increase the code RC here in any case. Intuitively the parachain that requested this + // action is now a user of that PVF. + // + // If the result of the pre-checking is reject, then we would decrease the RC for each + // cause, including the current. + // + // If the result of the pre-checking is accept, then we do nothing to the RC because the PVF + // will continue be used by the same users. + // + // If the PVF was fast-tracked (i.e. there is already non zero RC) and there is no + // pre-checking, we also do not change the RC then. + weight += Self::increase_code_ref(&code_hash, &code); + + weight + } + + /// Note that a para has progressed to a new head, where the new head was executed in the + /// context of a relay-chain block with given number. This will apply pending code upgrades + /// based on the relay-parent block number provided. + pub(crate) fn note_new_head( + id: ParaId, + new_head: HeadData, + execution_context: BlockNumberFor, + ) -> Weight { + Heads::::insert(&id, new_head); + MostRecentContext::::insert(&id, execution_context); + + if let Some(expected_at) = FutureCodeUpgrades::::get(&id) { + if expected_at <= execution_context { + FutureCodeUpgrades::::remove(&id); + UpgradeGoAheadSignal::::remove(&id); + + // Both should always be `Some` in this case, since a code upgrade is scheduled. + let new_code_hash = if let Some(new_code_hash) = FutureCodeHash::::take(&id) { + new_code_hash + } else { + log::error!(target: LOG_TARGET, "Missing future code hash for {:?}", &id); + return T::DbWeight::get().reads_writes(3, 1 + 3) + }; + let maybe_prior_code_hash = CurrentCodeHash::::get(&id); + CurrentCodeHash::::insert(&id, &new_code_hash); + + let log = ConsensusLog::ParaUpgradeCode(id, new_code_hash); + >::deposit_log(log.into()); + + // `now` is only used for registering pruning as part of `fn note_past_code` + let now = >::block_number(); + + let weight = if let Some(prior_code_hash) = maybe_prior_code_hash { + Self::note_past_code(id, expected_at, now, prior_code_hash) + } else { + log::error!(target: LOG_TARGET, "Missing prior code hash for para {:?}", &id); + Weight::zero() + }; + + // add 1 to writes due to heads update. + weight + T::DbWeight::get().reads_writes(3, 1 + 3) + } else { + T::DbWeight::get().reads_writes(1, 1 + 0) + } + } else { + // This means there is no upgrade scheduled. + // + // In case the upgrade was aborted by the relay-chain we should reset + // the `Abort` signal. + UpgradeGoAheadSignal::::remove(&id); + T::DbWeight::get().reads_writes(1, 2) + } + } + + /// Returns the list of PVFs (aka validation code) that require casting a vote by a validator in + /// the active validator set. + pub(crate) fn pvfs_require_precheck() -> Vec { + PvfActiveVoteList::::get() + } + + /// Submits a given PVF check statement with corresponding signature as an unsigned transaction + /// into the memory pool. Ultimately, that disseminates the transaction accross the network. + /// + /// This function expects an offchain context and cannot be callable from the on-chain logic. + /// + /// The signature assumed to pertain to `stmt`. + pub(crate) fn submit_pvf_check_statement( + stmt: PvfCheckStatement, + signature: ValidatorSignature, + ) { + use frame_system::offchain::SubmitTransaction; + + if let Err(e) = SubmitTransaction::>::submit_unsigned_transaction( + Call::include_pvf_check_statement { stmt, signature }.into(), + ) { + log::error!(target: LOG_TARGET, "Error submitting pvf check statement: {:?}", e,); + } + } + + /// Returns the current lifecycle state of the para. + pub fn lifecycle(id: ParaId) -> Option { + ParaLifecycles::::get(&id) + } + + /// Returns whether the given ID refers to a valid para. + /// + /// Paras that are onboarding or offboarding are not included. + pub fn is_valid_para(id: ParaId) -> bool { + if let Some(state) = ParaLifecycles::::get(&id) { + !state.is_onboarding() && !state.is_offboarding() + } else { + false + } + } + + /// Returns whether the given ID refers to a para that is offboarding. + /// + /// An invalid or non-offboarding para ID will return `false`. + pub fn is_offboarding(id: ParaId) -> bool { + ParaLifecycles::::get(&id).map_or(false, |state| state.is_offboarding()) + } + + /// Whether a para ID corresponds to any live lease holding parachain. + /// + /// Includes lease holding parachains which will downgrade to a on-demand parachains in the + /// future. + pub fn is_parachain(id: ParaId) -> bool { + if let Some(state) = ParaLifecycles::::get(&id) { + state.is_parachain() + } else { + false + } + } + + /// Whether a para ID corresponds to any live parathread (on-demand parachain). + /// + /// Includes on-demand parachains which will upgrade to lease holding parachains in the future. + pub fn is_parathread(id: ParaId) -> bool { + if let Some(state) = ParaLifecycles::::get(&id) { + state.is_parathread() + } else { + false + } + } + + /// If a candidate from the specified parachain were submitted at the current block, this + /// function returns if that candidate passes the acceptance criteria. + pub(crate) fn can_upgrade_validation_code(id: ParaId) -> bool { + FutureCodeHash::::get(&id).is_none() && UpgradeRestrictionSignal::::get(&id).is_none() + } + + /// Return the session index that should be used for any future scheduled changes. + fn scheduled_session() -> SessionIndex { + shared::Pallet::::scheduled_session() + } + + /// Store the validation code if not already stored, and increase the number of reference. + /// + /// Returns the weight consumed. + fn increase_code_ref(code_hash: &ValidationCodeHash, code: &ValidationCode) -> Weight { + let mut weight = T::DbWeight::get().reads_writes(1, 1); + CodeByHashRefs::::mutate(code_hash, |refs| { + if *refs == 0 { + weight += T::DbWeight::get().writes(1); + CodeByHash::::insert(code_hash, code); + } + *refs += 1; + }); + weight + } + + /// Decrease the number of reference of the validation code and remove it from storage if zero + /// is reached. + /// + /// Returns the weight consumed. + fn decrease_code_ref(code_hash: &ValidationCodeHash) -> Weight { + let mut weight = T::DbWeight::get().reads(1); + let refs = CodeByHashRefs::::get(code_hash); + if refs == 0 { + log::error!(target: LOG_TARGET, "Code refs is already zero for {:?}", code_hash); + return weight + } + if refs <= 1 { + weight += T::DbWeight::get().writes(2); + CodeByHash::::remove(code_hash); + CodeByHashRefs::::remove(code_hash); + } else { + weight += T::DbWeight::get().writes(1); + CodeByHashRefs::::insert(code_hash, refs - 1); + } + weight + } + + /// Test function for triggering a new session in this pallet. + #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] + pub fn test_on_new_session() { + Self::initializer_on_new_session(&SessionChangeNotification { + session_index: shared::Pallet::::session_index(), + ..Default::default() + }); + } + + #[cfg(any(feature = "runtime-benchmarks", test))] + pub fn heads_insert(para_id: &ParaId, head_data: HeadData) { + Heads::::insert(para_id, head_data); + } + + /// A low-level function to eagerly initialize a given para. + pub(crate) fn initialize_para_now( + parachains: &mut ParachainsCache, + id: ParaId, + genesis_data: &ParaGenesisArgs, + ) { + match genesis_data.para_kind { + ParaKind::Parachain => { + parachains.add(id); + ParaLifecycles::::insert(&id, ParaLifecycle::Parachain); + }, + ParaKind::Parathread => ParaLifecycles::::insert(&id, ParaLifecycle::Parathread), + } + + // HACK: see the notice in `schedule_para_initialize`. + // + // Apparently, this is left over from a prior version of the runtime. + // To handle this we just insert the code and link the current code hash + // to it. + if !genesis_data.validation_code.0.is_empty() { + let code_hash = genesis_data.validation_code.hash(); + Self::increase_code_ref(&code_hash, &genesis_data.validation_code); + CurrentCodeHash::::insert(&id, code_hash); + } + + Heads::::insert(&id, &genesis_data.genesis_head); + MostRecentContext::::insert(&id, BlockNumberFor::::from(0u32)); + } + + #[cfg(test)] + pub(crate) fn active_vote_state( + code_hash: &ValidationCodeHash, + ) -> Option>> { + PvfActiveVoteMap::::get(code_hash) + } +} + +/// An overlay over the `Parachains` storage entry that provides a convenient interface for adding +/// or removing parachains in bulk. +pub(crate) struct ParachainsCache { + // `None` here means the parachains list has not been accessed yet, nevermind modified. + parachains: Option>, + _config: PhantomData, +} + +impl ParachainsCache { + pub fn new() -> Self { + Self { parachains: None, _config: PhantomData } + } + + fn ensure_initialized(&mut self) -> &mut BTreeSet { + self.parachains + .get_or_insert_with(|| Parachains::::get().into_iter().collect()) + } + + /// Adds the given para id to the list. + pub fn add(&mut self, id: ParaId) { + let parachains = self.ensure_initialized(); + parachains.insert(id); + } + + /// Removes the given para id from the list of parachains. Does nothing if the id is not in the + /// list. + pub fn remove(&mut self, id: ParaId) { + let parachains = self.ensure_initialized(); + parachains.remove(&id); + } +} + +impl Drop for ParachainsCache { + fn drop(&mut self) { + if let Some(parachains) = self.parachains.take() { + Parachains::::put(parachains.into_iter().collect::>()); + } + } +} diff --git a/polkadot/runtime/parachains/src/paras/tests.rs b/polkadot/runtime/parachains/src/paras/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..a024525c817a81b176d160240ec4854b67990e37 --- /dev/null +++ b/polkadot/runtime/parachains/src/paras/tests.rs @@ -0,0 +1,1826 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use frame_support::{assert_err, assert_ok, assert_storage_noop}; +use keyring::Sr25519Keyring; +use primitives::{BlockNumber, ValidatorId, PARACHAIN_KEY_TYPE_ID}; +use sc_keystore::LocalKeystore; +use sp_keystore::{Keystore, KeystorePtr}; +use std::sync::Arc; +use test_helpers::{dummy_head_data, dummy_validation_code}; + +use crate::{ + configuration::HostConfiguration, + mock::{ + new_test_ext, Configuration, MockGenesisConfig, Paras, ParasShared, RuntimeOrigin, System, + Test, + }, +}; + +static VALIDATORS: &[Sr25519Keyring] = &[ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, +]; + +fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec { + val_ids.iter().map(|v| v.public().into()).collect() +} + +fn sign_and_include_pvf_check_statement(stmt: PvfCheckStatement) { + let validators = &[ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + let signature = validators[stmt.validator_index.0 as usize].sign(&stmt.signing_payload()); + Paras::include_pvf_check_statement(None.into(), stmt, signature.into()).unwrap(); +} + +fn submit_super_majority_pvf_votes( + validation_code: &ValidationCode, + session_index: SessionIndex, + accept: bool, +) { + [0, 1, 2, 3] + .into_iter() + .map(|i| PvfCheckStatement { + accept, + subject: validation_code.hash(), + session_index, + validator_index: i.into(), + }) + .for_each(sign_and_include_pvf_check_statement); +} + +fn run_to_block(to: BlockNumber, new_session: Option>) { + let keystore: KeystorePtr = Arc::new(LocalKeystore::in_memory()); + for validator in VALIDATORS.iter() { + Keystore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); + } + let validator_pubkeys = validator_pubkeys(VALIDATORS); + + while System::block_number() < to { + let b = System::block_number(); + Paras::initializer_finalize(b); + ParasShared::initializer_finalize(); + if new_session.as_ref().map_or(false, |v| v.contains(&(b + 1))) { + let mut session_change_notification = SessionChangeNotification::default(); + session_change_notification.session_index = ParasShared::session_index() + 1; + session_change_notification.validators = validator_pubkeys.clone(); + ParasShared::initializer_on_new_session( + session_change_notification.session_index, + session_change_notification.random_seed, + &session_change_notification.new_config, + session_change_notification.validators.clone(), + ); + ParasShared::set_active_validators_ascending(validator_pubkeys.clone()); + Paras::initializer_on_new_session(&session_change_notification); + } + System::on_finalize(b); + + System::on_initialize(b + 1); + System::set_block_number(b + 1); + + ParasShared::initializer_initialize(b + 1); + Paras::initializer_initialize(b + 1); + } +} + +fn upgrade_at( + expected_at: BlockNumber, + activated_at: BlockNumber, +) -> ReplacementTimes { + ReplacementTimes { expected_at, activated_at } +} + +fn check_code_is_stored(validation_code: &ValidationCode) { + assert!(CodeByHashRefs::::get(validation_code.hash()) != 0); + assert!(CodeByHash::::contains_key(validation_code.hash())); +} + +fn check_code_is_not_stored(validation_code: &ValidationCode) { + assert!(!CodeByHashRefs::::contains_key(validation_code.hash())); + assert!(!CodeByHash::::contains_key(validation_code.hash())); +} + +/// An utility for checking that certain events were deposited. +struct EventValidator { + events: Vec< + frame_system::EventRecord<::RuntimeEvent, primitives::Hash>, + >, +} + +impl EventValidator { + fn new() -> Self { + Self { events: Vec::new() } + } + + fn started(&mut self, code: &ValidationCode, id: ParaId) -> &mut Self { + self.events.push(frame_system::EventRecord { + phase: frame_system::Phase::Initialization, + event: Event::PvfCheckStarted(code.hash(), id).into(), + topics: vec![], + }); + self + } + + fn rejected(&mut self, code: &ValidationCode, id: ParaId) -> &mut Self { + self.events.push(frame_system::EventRecord { + phase: frame_system::Phase::Initialization, + event: Event::PvfCheckRejected(code.hash(), id).into(), + topics: vec![], + }); + self + } + + fn accepted(&mut self, code: &ValidationCode, id: ParaId) -> &mut Self { + self.events.push(frame_system::EventRecord { + phase: frame_system::Phase::Initialization, + event: Event::PvfCheckAccepted(code.hash(), id).into(), + topics: vec![], + }); + self + } + + fn check(&self) { + assert_eq!(&frame_system::Pallet::::events(), &self.events); + } +} + +#[test] +fn para_past_code_pruning_works_correctly() { + let mut past_code = ParaPastCodeMeta::default(); + past_code.note_replacement(10u32, 10); + past_code.note_replacement(20, 25); + past_code.note_replacement(30, 35); + + let old = past_code.clone(); + assert!(past_code.prune_up_to(9).collect::>().is_empty()); + assert_eq!(old, past_code); + + assert_eq!(past_code.prune_up_to(10).collect::>(), vec![10]); + assert_eq!( + past_code, + ParaPastCodeMeta { + upgrade_times: vec![upgrade_at(20, 25), upgrade_at(30, 35)], + last_pruned: Some(10), + } + ); + + assert!(past_code.prune_up_to(21).collect::>().is_empty()); + + assert_eq!(past_code.prune_up_to(26).collect::>(), vec![20]); + assert_eq!( + past_code, + ParaPastCodeMeta { upgrade_times: vec![upgrade_at(30, 35)], last_pruned: Some(25) } + ); + + past_code.note_replacement(40, 42); + past_code.note_replacement(50, 53); + past_code.note_replacement(60, 66); + + assert_eq!( + past_code, + ParaPastCodeMeta { + upgrade_times: vec![ + upgrade_at(30, 35), + upgrade_at(40, 42), + upgrade_at(50, 53), + upgrade_at(60, 66) + ], + last_pruned: Some(25), + } + ); + + assert_eq!(past_code.prune_up_to(60).collect::>(), vec![30, 40, 50]); + assert_eq!( + past_code, + ParaPastCodeMeta { upgrade_times: vec![upgrade_at(60, 66)], last_pruned: Some(53) } + ); + + assert_eq!(past_code.most_recent_change(), Some(60)); + assert_eq!(past_code.prune_up_to(66).collect::>(), vec![60]); + + assert_eq!(past_code, ParaPastCodeMeta { upgrade_times: Vec::new(), last_pruned: Some(66) }); +} + +#[test] +fn schedule_para_init_rejects_empty_code() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + assert_err!( + Paras::schedule_para_initialize( + 1000.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parathread, + genesis_head: dummy_head_data(), + validation_code: ValidationCode(vec![]), + } + ), + Error::::CannotOnboard, + ); + + assert_ok!(Paras::schedule_para_initialize( + 1000.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parathread, + genesis_head: dummy_head_data(), + validation_code: ValidationCode(vec![1]), + } + )); + }); +} + +#[test] +fn para_past_code_pruning_in_initialize() { + let code_retention_period = 10; + let paras = vec![ + ( + 0u32.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: dummy_head_data(), + validation_code: dummy_validation_code(), + }, + ), + ( + 1u32.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parathread, + genesis_head: dummy_head_data(), + validation_code: dummy_validation_code(), + }, + ), + ]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { code_retention_period, ..Default::default() }, + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + let id = ParaId::from(0u32); + let at_block: BlockNumber = 10; + let included_block: BlockNumber = 12; + let validation_code = ValidationCode(vec![4, 5, 6]); + + Paras::increase_code_ref(&validation_code.hash(), &validation_code); + PastCodeHash::::insert(&(id, at_block), &validation_code.hash()); + PastCodePruning::::put(&vec![(id, included_block)]); + + { + let mut code_meta = Paras::past_code_meta(&id); + code_meta.note_replacement(at_block, included_block); + PastCodeMeta::::insert(&id, &code_meta); + } + + let pruned_at: BlockNumber = included_block + code_retention_period + 1; + assert_eq!(PastCodeHash::::get(&(id, at_block)), Some(validation_code.hash())); + check_code_is_stored(&validation_code); + + run_to_block(pruned_at - 1, None); + assert_eq!(PastCodeHash::::get(&(id, at_block)), Some(validation_code.hash())); + assert_eq!(Paras::past_code_meta(&id).most_recent_change(), Some(at_block)); + check_code_is_stored(&validation_code); + + run_to_block(pruned_at, None); + assert!(PastCodeHash::::get(&(id, at_block)).is_none()); + assert!(Paras::past_code_meta(&id).most_recent_change().is_none()); + check_code_is_not_stored(&validation_code); + }); +} + +#[test] +fn note_new_head_sets_head() { + let code_retention_period = 10; + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: dummy_head_data(), + validation_code: dummy_validation_code(), + }, + )]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { code_retention_period, ..Default::default() }, + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + let id_a = ParaId::from(0u32); + + assert_eq!(Paras::para_head(&id_a), Some(dummy_head_data())); + + Paras::note_new_head(id_a, vec![1, 2, 3].into(), 0); + + assert_eq!(Paras::para_head(&id_a), Some(vec![1, 2, 3].into())); + }); +} + +#[test] +fn note_past_code_sets_up_pruning_correctly() { + let code_retention_period = 10; + let paras = vec![ + ( + 0u32.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: dummy_head_data(), + validation_code: dummy_validation_code(), + }, + ), + ( + 1u32.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parathread, + genesis_head: dummy_head_data(), + validation_code: dummy_validation_code(), + }, + ), + ]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { code_retention_period, ..Default::default() }, + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + let id_a = ParaId::from(0u32); + let id_b = ParaId::from(1u32); + + Paras::note_past_code(id_a, 10, 12, ValidationCode(vec![1, 2, 3]).hash()); + Paras::note_past_code(id_b, 20, 23, ValidationCode(vec![4, 5, 6]).hash()); + + assert_eq!(PastCodePruning::::get(), vec![(id_a, 12), (id_b, 23)]); + assert_eq!( + Paras::past_code_meta(&id_a), + ParaPastCodeMeta { upgrade_times: vec![upgrade_at(10, 12)], last_pruned: None } + ); + assert_eq!( + Paras::past_code_meta(&id_b), + ParaPastCodeMeta { upgrade_times: vec![upgrade_at(20, 23)], last_pruned: None } + ); + }); +} + +#[test] +fn code_upgrade_applied_after_delay() { + let code_retention_period = 10; + let validation_upgrade_delay = 5; + let validation_upgrade_cooldown = 10; + + let original_code = ValidationCode(vec![1, 2, 3]); + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: dummy_head_data(), + validation_code: original_code.clone(), + }, + )]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { + code_retention_period, + validation_upgrade_delay, + validation_upgrade_cooldown, + ..Default::default() + }, + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + check_code_is_stored(&original_code); + + let para_id = ParaId::from(0); + let new_code = ValidationCode(vec![4, 5, 6]); + + // Wait for at least one session change to set active validators. + const EXPECTED_SESSION: SessionIndex = 1; + run_to_block(2, Some(vec![1])); + assert_eq!(Paras::current_code(¶_id), Some(original_code.clone())); + + let (expected_at, next_possible_upgrade_at) = { + // this parablock is in the context of block 1. + let expected_at = 1 + validation_upgrade_delay; + let next_possible_upgrade_at = 1 + validation_upgrade_cooldown; + Paras::schedule_code_upgrade(para_id, new_code.clone(), 1, &Configuration::config()); + // Include votes for super-majority. + submit_super_majority_pvf_votes(&new_code, EXPECTED_SESSION, true); + + Paras::note_new_head(para_id, Default::default(), 1); + + assert!(Paras::past_code_meta(¶_id).most_recent_change().is_none()); + assert_eq!(FutureCodeUpgrades::::get(¶_id), Some(expected_at)); + assert_eq!(FutureCodeHash::::get(¶_id), Some(new_code.hash())); + assert_eq!(UpcomingUpgrades::::get(), vec![(para_id, expected_at)]); + assert_eq!(UpgradeCooldowns::::get(), vec![(para_id, next_possible_upgrade_at)]); + assert_eq!(Paras::current_code(¶_id), Some(original_code.clone())); + check_code_is_stored(&original_code); + check_code_is_stored(&new_code); + + (expected_at, next_possible_upgrade_at) + }; + + run_to_block(expected_at, None); + + // the candidate is in the context of the parent of `expected_at`, + // thus does not trigger the code upgrade. + { + Paras::note_new_head(para_id, Default::default(), expected_at - 1); + + assert!(Paras::past_code_meta(¶_id).most_recent_change().is_none()); + assert_eq!(FutureCodeUpgrades::::get(¶_id), Some(expected_at)); + assert_eq!(FutureCodeHash::::get(¶_id), Some(new_code.hash())); + assert_eq!(UpgradeGoAheadSignal::::get(¶_id), Some(UpgradeGoAhead::GoAhead)); + assert_eq!(Paras::current_code(¶_id), Some(original_code.clone())); + check_code_is_stored(&original_code); + check_code_is_stored(&new_code); + } + + run_to_block(expected_at + 1, None); + + // the candidate is in the context of `expected_at`, and triggers + // the upgrade. + { + Paras::note_new_head(para_id, Default::default(), expected_at); + + assert_eq!(Paras::past_code_meta(¶_id).most_recent_change(), Some(expected_at)); + assert_eq!( + PastCodeHash::::get(&(para_id, expected_at)), + Some(original_code.hash()), + ); + assert!(FutureCodeUpgrades::::get(¶_id).is_none()); + assert!(FutureCodeHash::::get(¶_id).is_none()); + assert!(UpgradeGoAheadSignal::::get(¶_id).is_none()); + assert_eq!(Paras::current_code(¶_id), Some(new_code.clone())); + assert_eq!( + UpgradeRestrictionSignal::::get(¶_id), + Some(UpgradeRestriction::Present), + ); + assert_eq!(UpgradeCooldowns::::get(), vec![(para_id, next_possible_upgrade_at)]); + check_code_is_stored(&original_code); + check_code_is_stored(&new_code); + } + + run_to_block(next_possible_upgrade_at + 1, None); + + { + assert!(UpgradeRestrictionSignal::::get(¶_id).is_none()); + assert!(UpgradeCooldowns::::get().is_empty()); + } + }); +} + +#[test] +fn code_upgrade_applied_after_delay_even_when_late() { + let code_retention_period = 10; + let validation_upgrade_delay = 5; + let validation_upgrade_cooldown = 10; + + let original_code = ValidationCode(vec![1, 2, 3]); + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: dummy_head_data(), + validation_code: original_code.clone(), + }, + )]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { + code_retention_period, + validation_upgrade_delay, + validation_upgrade_cooldown, + ..Default::default() + }, + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + let para_id = ParaId::from(0); + let new_code = ValidationCode(vec![4, 5, 6]); + + // Wait for at least one session change to set active validators. + const EXPECTED_SESSION: SessionIndex = 1; + run_to_block(2, Some(vec![1])); + assert_eq!(Paras::current_code(¶_id), Some(original_code.clone())); + + let expected_at = { + // this parablock is in the context of block 1. + let expected_at = 1 + validation_upgrade_delay; + let next_possible_upgrade_at = 1 + validation_upgrade_cooldown; + Paras::schedule_code_upgrade(para_id, new_code.clone(), 1, &Configuration::config()); + // Include votes for super-majority. + submit_super_majority_pvf_votes(&new_code, EXPECTED_SESSION, true); + + Paras::note_new_head(para_id, Default::default(), 1); + + assert!(Paras::past_code_meta(¶_id).most_recent_change().is_none()); + assert_eq!(FutureCodeUpgrades::::get(¶_id), Some(expected_at)); + assert_eq!(FutureCodeHash::::get(¶_id), Some(new_code.hash())); + assert_eq!(UpcomingUpgrades::::get(), vec![(para_id, expected_at)]); + assert_eq!(UpgradeCooldowns::::get(), vec![(para_id, next_possible_upgrade_at)]); + assert!(UpgradeGoAheadSignal::::get(¶_id).is_none()); + assert_eq!(Paras::current_code(¶_id), Some(original_code.clone())); + + expected_at + }; + + run_to_block(expected_at + 1 + 4, None); + + // the candidate is in the context of the first descendant of `expected_at`, and triggers + // the upgrade. + { + // The signal should be set to go-ahead until the new head is actually processed. + assert_eq!(UpgradeGoAheadSignal::::get(¶_id), Some(UpgradeGoAhead::GoAhead)); + + Paras::note_new_head(para_id, Default::default(), expected_at + 4); + + assert_eq!(Paras::past_code_meta(¶_id).most_recent_change(), Some(expected_at)); + + assert_eq!( + PastCodeHash::::get(&(para_id, expected_at)), + Some(original_code.hash()), + ); + assert!(FutureCodeUpgrades::::get(¶_id).is_none()); + assert!(FutureCodeHash::::get(¶_id).is_none()); + assert!(UpgradeGoAheadSignal::::get(¶_id).is_none()); + assert_eq!(Paras::current_code(¶_id), Some(new_code.clone())); + } + }); +} + +#[test] +fn submit_code_change_when_not_allowed_is_err() { + let code_retention_period = 10; + let validation_upgrade_delay = 7; + let validation_upgrade_cooldown = 100; + + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: dummy_head_data(), + validation_code: vec![1, 2, 3].into(), + }, + )]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { + code_retention_period, + validation_upgrade_delay, + validation_upgrade_cooldown, + ..Default::default() + }, + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + let para_id = ParaId::from(0); + let new_code = ValidationCode(vec![4, 5, 6]); + let newer_code = ValidationCode(vec![4, 5, 6, 7]); + + // Wait for at least one session change to set active validators. + const EXPECTED_SESSION: SessionIndex = 1; + run_to_block(1, Some(vec![1])); + + Paras::schedule_code_upgrade(para_id, new_code.clone(), 1, &Configuration::config()); + // Include votes for super-majority. + submit_super_majority_pvf_votes(&new_code, EXPECTED_SESSION, true); + + assert_eq!(FutureCodeUpgrades::::get(¶_id), Some(1 + validation_upgrade_delay)); + assert_eq!(FutureCodeHash::::get(¶_id), Some(new_code.hash())); + check_code_is_stored(&new_code); + + // We expect that if an upgrade is signalled while there is already one pending we just + // ignore it. Note that this is only true from perspective of this module. + run_to_block(2, None); + assert!(!Paras::can_upgrade_validation_code(para_id)); + Paras::schedule_code_upgrade(para_id, newer_code.clone(), 2, &Configuration::config()); + assert_eq!( + FutureCodeUpgrades::::get(¶_id), + Some(1 + validation_upgrade_delay), /* did not change since the same assertion from + * the last time. */ + ); + assert_eq!(FutureCodeHash::::get(¶_id), Some(new_code.hash())); + check_code_is_not_stored(&newer_code); + }); +} + +#[test] +fn upgrade_restriction_elapsed_doesnt_mean_can_upgrade() { + // Situation: parachain scheduled upgrade but it doesn't produce any candidate after + // `expected_at`. When `validation_upgrade_cooldown` elapsed the parachain produces a + // candidate that tries to upgrade the code. + // + // In the current code this is not allowed: the upgrade should be consumed first. This is + // rather an artifact of the current implementation and not necessarily something we want + // to keep in the future. + // + // This test exists that this is not accidentally changed. + + let code_retention_period = 10; + let validation_upgrade_delay = 7; + let validation_upgrade_cooldown = 30; + + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: dummy_head_data(), + validation_code: vec![1, 2, 3].into(), + }, + )]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { + code_retention_period, + validation_upgrade_delay, + validation_upgrade_cooldown, + ..Default::default() + }, + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + let para_id = 0u32.into(); + let new_code = ValidationCode(vec![4, 5, 6]); + let newer_code = ValidationCode(vec![4, 5, 6, 7]); + + // Wait for at least one session change to set active validators. + const EXPECTED_SESSION: SessionIndex = 1; + run_to_block(1, Some(vec![1])); + + Paras::schedule_code_upgrade(para_id, new_code.clone(), 0, &Configuration::config()); + // Include votes for super-majority. + submit_super_majority_pvf_votes(&new_code, EXPECTED_SESSION, true); + + Paras::note_new_head(para_id, dummy_head_data(), 0); + assert_eq!( + UpgradeRestrictionSignal::::get(¶_id), + Some(UpgradeRestriction::Present), + ); + assert_eq!(FutureCodeUpgrades::::get(¶_id), Some(0 + validation_upgrade_delay)); + assert!(!Paras::can_upgrade_validation_code(para_id)); + + run_to_block(31, None); + assert!(UpgradeRestrictionSignal::::get(¶_id).is_none()); + + // Note the para still cannot upgrade the validation code. + assert!(!Paras::can_upgrade_validation_code(para_id)); + + // And scheduling another upgrade does not do anything. `expected_at` is still the same. + Paras::schedule_code_upgrade(para_id, newer_code.clone(), 30, &Configuration::config()); + assert_eq!(FutureCodeUpgrades::::get(¶_id), Some(0 + validation_upgrade_delay)); + }); +} + +#[test] +fn full_parachain_cleanup_storage() { + let code_retention_period = 20; + let validation_upgrade_delay = 1 + 5; + + let original_code = ValidationCode(vec![1, 2, 3]); + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: dummy_head_data(), + validation_code: original_code.clone(), + }, + )]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { + code_retention_period, + validation_upgrade_delay, + minimum_validation_upgrade_delay: 2, + // Those are not relevant to this test. However, HostConfiguration is still a + // subject for the consistency check. + paras_availability_period: 1, + ..Default::default() + }, + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + check_code_is_stored(&original_code); + + let para_id = ParaId::from(0); + let new_code = ValidationCode(vec![4, 5, 6]); + + // Wait for at least one session change to set active validators. + const EXPECTED_SESSION: SessionIndex = 1; + run_to_block(2, Some(vec![1])); + + assert_eq!(Paras::current_code(¶_id), Some(original_code.clone())); + check_code_is_stored(&original_code); + + let expected_at = { + // this parablock is in the context of block 1. + let expected_at = 1 + validation_upgrade_delay; + Paras::schedule_code_upgrade(para_id, new_code.clone(), 1, &Configuration::config()); + // Include votes for super-majority. + submit_super_majority_pvf_votes(&new_code, EXPECTED_SESSION, true); + + Paras::note_new_head(para_id, Default::default(), 1); + + assert!(Paras::past_code_meta(¶_id).most_recent_change().is_none()); + assert_eq!(FutureCodeUpgrades::::get(¶_id), Some(expected_at)); + assert_eq!(FutureCodeHash::::get(¶_id), Some(new_code.hash())); + assert_eq!(Paras::current_code(¶_id), Some(original_code.clone())); + check_code_is_stored(&original_code); + check_code_is_stored(&new_code); + + expected_at + }; + + // Enact the upgrade. + // + // For that run to block #7 and submit a new head. + assert_eq!(expected_at, 7); + run_to_block(7, None); + assert_eq!(>::block_number(), 7); + Paras::note_new_head(para_id, Default::default(), expected_at); + + assert_ok!(Paras::schedule_para_cleanup(para_id)); + + // run to block #10, with a 2 session changes at the end of the block 7 & 8 (so 8 and 9 + // observe the new sessions). + run_to_block(10, Some(vec![8, 9])); + + // cleaning up the parachain should place the current parachain code + // into the past code buffer & schedule cleanup. + // + // Why 7 and 8? See above, the clean up scheduled above was processed at the block 8. + // The initial upgrade was enacted at the block 7. + assert_eq!(Paras::past_code_meta(¶_id).most_recent_change(), Some(8)); + assert_eq!(PastCodeHash::::get(&(para_id, 8)), Some(new_code.hash())); + assert_eq!(PastCodePruning::::get(), vec![(para_id, 7), (para_id, 8)]); + check_code_is_stored(&original_code); + check_code_is_stored(&new_code); + + // any future upgrades haven't been used to validate yet, so those + // are cleaned up immediately. + assert!(FutureCodeUpgrades::::get(¶_id).is_none()); + assert!(FutureCodeHash::::get(¶_id).is_none()); + assert!(Paras::current_code(¶_id).is_none()); + + // run to do the final cleanup + let cleaned_up_at = 8 + code_retention_period + 1; + run_to_block(cleaned_up_at, None); + + // now the final cleanup: last past code cleaned up, and this triggers meta cleanup. + assert_eq!(Paras::past_code_meta(¶_id), Default::default()); + assert!(PastCodeHash::::get(&(para_id, 7)).is_none()); + assert!(PastCodeHash::::get(&(para_id, 8)).is_none()); + assert!(PastCodePruning::::get().is_empty()); + check_code_is_not_stored(&original_code); + check_code_is_not_stored(&new_code); + }); +} + +#[test] +fn cannot_offboard_ongoing_pvf_check() { + let para_id = ParaId::from(0); + + let existing_code: ValidationCode = vec![1, 2, 3].into(); + let new_code: ValidationCode = vec![3, 2, 1].into(); + + let paras = vec![( + para_id, + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: Default::default(), + validation_code: existing_code, + }, + )]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + run_to_block(2, Some(vec![1])); + + // Relay parent of the block that schedules the upgrade. + const RELAY_PARENT: BlockNumber = 1; + // Expected current session index. + const EXPECTED_SESSION: SessionIndex = 1; + + Paras::schedule_code_upgrade( + para_id, + new_code.clone(), + RELAY_PARENT, + &Configuration::config(), + ); + assert!(!Paras::pvfs_require_precheck().is_empty()); + + // Cannot offboard when there's an ongoing pvf-check voting. + assert_err!(Paras::schedule_para_cleanup(para_id), Error::::CannotOffboard); + + // Include votes for super-majority. + submit_super_majority_pvf_votes(&new_code, EXPECTED_SESSION, true); + + // Voting concluded, can offboard even though an upgrade is in progress. + assert_ok!(Paras::schedule_para_cleanup(para_id)); + }); +} + +#[test] +fn para_incoming_at_session() { + let code_a = ValidationCode(vec![2]); + let code_b = ValidationCode(vec![1]); + let code_c = ValidationCode(vec![3]); + + let genesis_config = MockGenesisConfig::default(); + + new_test_ext(genesis_config).execute_with(|| { + run_to_block(1, Some(vec![1])); + + let b = ParaId::from(525); + let a = ParaId::from(999); + let c = ParaId::from(333); + + assert_ok!(Paras::schedule_para_initialize( + b, + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: vec![1].into(), + validation_code: code_b.clone(), + }, + )); + + assert_ok!(Paras::schedule_para_initialize( + a, + ParaGenesisArgs { + para_kind: ParaKind::Parathread, + genesis_head: vec![2].into(), + validation_code: code_a.clone(), + }, + )); + + assert_ok!(Paras::schedule_para_initialize( + c, + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: vec![3].into(), + validation_code: code_c.clone(), + }, + )); + + IntoIterator::into_iter([0, 1, 2, 3]) + .map(|i| PvfCheckStatement { + accept: true, + subject: code_a.hash(), + session_index: 1, + validator_index: i.into(), + }) + .for_each(sign_and_include_pvf_check_statement); + + IntoIterator::into_iter([1, 2, 3, 4]) + .map(|i| PvfCheckStatement { + accept: true, + subject: code_b.hash(), + session_index: 1, + validator_index: i.into(), + }) + .for_each(sign_and_include_pvf_check_statement); + + IntoIterator::into_iter([0, 2, 3, 4]) + .map(|i| PvfCheckStatement { + accept: true, + subject: code_c.hash(), + session_index: 1, + validator_index: i.into(), + }) + .for_each(sign_and_include_pvf_check_statement); + + assert_eq!(ActionsQueue::::get(Paras::scheduled_session()), vec![c, b, a],); + + // Lifecycle is tracked correctly + assert_eq!(ParaLifecycles::::get(&a), Some(ParaLifecycle::Onboarding)); + assert_eq!(ParaLifecycles::::get(&b), Some(ParaLifecycle::Onboarding)); + assert_eq!(ParaLifecycles::::get(&c), Some(ParaLifecycle::Onboarding)); + + // run to block without session change. + run_to_block(2, None); + + assert_eq!(Paras::parachains(), Vec::new()); + assert_eq!(ActionsQueue::::get(Paras::scheduled_session()), vec![c, b, a],); + + // Lifecycle is tracked correctly + assert_eq!(ParaLifecycles::::get(&a), Some(ParaLifecycle::Onboarding)); + assert_eq!(ParaLifecycles::::get(&b), Some(ParaLifecycle::Onboarding)); + assert_eq!(ParaLifecycles::::get(&c), Some(ParaLifecycle::Onboarding)); + + // Two sessions pass, so action queue is triggered + run_to_block(4, Some(vec![3, 4])); + + assert_eq!(Paras::parachains(), vec![c, b]); + assert_eq!(ActionsQueue::::get(Paras::scheduled_session()), Vec::new()); + + // Lifecycle is tracked correctly + assert_eq!(ParaLifecycles::::get(&a), Some(ParaLifecycle::Parathread)); + assert_eq!(ParaLifecycles::::get(&b), Some(ParaLifecycle::Parachain)); + assert_eq!(ParaLifecycles::::get(&c), Some(ParaLifecycle::Parachain)); + + assert_eq!(Paras::current_code(&a), Some(vec![2].into())); + assert_eq!(Paras::current_code(&b), Some(vec![1].into())); + assert_eq!(Paras::current_code(&c), Some(vec![3].into())); + }) +} + +#[test] +fn code_hash_at_returns_up_to_end_of_code_retention_period() { + let code_retention_period = 10; + let validation_upgrade_delay = 2; + + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: dummy_head_data(), + validation_code: vec![1, 2, 3].into(), + }, + )]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { + code_retention_period, + validation_upgrade_delay, + ..Default::default() + }, + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + // Wait for at least one session change to set active validators. + run_to_block(2, Some(vec![1])); + const EXPECTED_SESSION: SessionIndex = 1; + + let para_id = ParaId::from(0); + let old_code: ValidationCode = vec![1, 2, 3].into(); + let new_code: ValidationCode = vec![4, 5, 6].into(); + Paras::schedule_code_upgrade(para_id, new_code.clone(), 0, &Configuration::config()); + // Include votes for super-majority. + submit_super_majority_pvf_votes(&new_code, EXPECTED_SESSION, true); + + // The new validation code can be applied but a new parablock hasn't gotten in yet, + // so the old code should still be current. + run_to_block(3, None); + assert_eq!(Paras::current_code(¶_id), Some(old_code.clone())); + + run_to_block(10, None); + Paras::note_new_head(para_id, Default::default(), 7); + + assert_eq!(Paras::past_code_meta(¶_id).upgrade_times, vec![upgrade_at(4, 10)]); + assert_eq!(Paras::current_code(¶_id), Some(new_code.clone())); + + // Make sure that the old code is available **before** the code retion period passes. + run_to_block(10 + code_retention_period, None); + assert_eq!(Paras::code_by_hash(&old_code.hash()), Some(old_code.clone())); + assert_eq!(Paras::code_by_hash(&new_code.hash()), Some(new_code.clone())); + + run_to_block(10 + code_retention_period + 1, None); + + // code entry should be pruned now. + + assert_eq!( + Paras::past_code_meta(¶_id), + ParaPastCodeMeta { upgrade_times: Vec::new(), last_pruned: Some(10) }, + ); + + assert_eq!(Paras::code_by_hash(&old_code.hash()), None); // pruned :( + assert_eq!(Paras::code_by_hash(&new_code.hash()), Some(new_code.clone())); + }); +} + +#[test] +fn code_ref_is_cleaned_correctly() { + new_test_ext(Default::default()).execute_with(|| { + let code: ValidationCode = vec![1, 2, 3].into(); + Paras::increase_code_ref(&code.hash(), &code); + Paras::increase_code_ref(&code.hash(), &code); + + assert!(CodeByHash::::contains_key(code.hash())); + assert_eq!(CodeByHashRefs::::get(code.hash()), 2); + + Paras::decrease_code_ref(&code.hash()); + + assert!(CodeByHash::::contains_key(code.hash())); + assert_eq!(CodeByHashRefs::::get(code.hash()), 1); + + Paras::decrease_code_ref(&code.hash()); + + assert!(!CodeByHash::::contains_key(code.hash())); + assert!(!CodeByHashRefs::::contains_key(code.hash())); + }); +} + +#[test] +fn pvf_check_coalescing_onboarding_and_upgrade() { + let validation_upgrade_delay = 5; + + let a = ParaId::from(111); + let b = ParaId::from(222); + let existing_code: ValidationCode = vec![1, 2, 3].into(); + let validation_code: ValidationCode = vec![3, 2, 1].into(); + + let paras = vec![( + a, + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: Default::default(), + validation_code: existing_code, + }, + )]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { validation_upgrade_delay, ..Default::default() }, + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + // At this point `a` is already onboarded. Run to block 1 performing session change at + // the end of block #0. + run_to_block(2, Some(vec![1])); + + // Expected current session index. + const EXPECTED_SESSION: SessionIndex = 1; + // Relay parent of the parablock that schedules the upgrade. + const RELAY_PARENT: BlockNumber = 1; + + // Now we register `b` with `validation_code` + assert_ok!(Paras::schedule_para_initialize( + b, + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: vec![2].into(), + validation_code: validation_code.clone(), + }, + )); + + // And now at the same time upgrade `a` to `validation_code` + Paras::schedule_code_upgrade( + a, + validation_code.clone(), + RELAY_PARENT, + &Configuration::config(), + ); + assert!(!Paras::pvfs_require_precheck().is_empty()); + + // Supermajority of validators vote for `validation_code`. It should be approved. + submit_super_majority_pvf_votes(&validation_code, EXPECTED_SESSION, true); + + // Check that `b` actually onboards. + assert_eq!(ActionsQueue::::get(EXPECTED_SESSION + 2), vec![b]); + + // Check that the upgrade got scheduled. + assert_eq!( + FutureCodeUpgrades::::get(&a), + Some(RELAY_PARENT + validation_upgrade_delay), + ); + + // Verify that the required events were emitted. + EventValidator::new() + .started(&validation_code, b) + .started(&validation_code, a) + .accepted(&validation_code, b) + .accepted(&validation_code, a) + .check(); + }); +} + +#[test] +fn pvf_check_onboarding_reject_on_expiry() { + let pvf_voting_ttl = 2; + let a = ParaId::from(111); + let validation_code: ValidationCode = vec![3, 2, 1].into(); + + let genesis_config = MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { pvf_voting_ttl, ..Default::default() }, + }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + run_to_block(1, Some(vec![1])); + + assert_ok!(Paras::schedule_para_initialize( + a, + ParaGenesisArgs { + para_kind: ParaKind::Parathread, + genesis_head: vec![2].into(), + validation_code: validation_code.clone(), + }, + )); + + // Make sure that we kicked off the PVF vote for this validation code and that the + // validation code is stored. + assert!(PvfActiveVoteMap::::get(&validation_code.hash()).is_some()); + check_code_is_stored(&validation_code); + + // Skip 2 sessions (i.e. `pvf_voting_ttl`) verifying that the code is still stored in + // the intermediate session. + assert_eq!(pvf_voting_ttl, 2); + run_to_block(2, Some(vec![2])); + check_code_is_stored(&validation_code); + run_to_block(3, Some(vec![3])); + + // --- At this point the PVF vote for onboarding should be rejected. + + // Verify that the PVF is no longer stored and there is no active PVF vote. + check_code_is_not_stored(&validation_code); + assert!(PvfActiveVoteMap::::get(&validation_code.hash()).is_none()); + assert!(Paras::pvfs_require_precheck().is_empty()); + + // Verify that at this point we can again try to initialize the same para. + assert!(Paras::can_schedule_para_initialize(&a)); + }); +} + +#[test] +fn pvf_check_upgrade_reject() { + let a = ParaId::from(111); + let old_code: ValidationCode = vec![1, 2, 3].into(); + let new_code: ValidationCode = vec![3, 2, 1].into(); + + let paras = vec![( + a, + ParaGenesisArgs { + para_kind: ParaKind::Parathread, + genesis_head: Default::default(), + validation_code: old_code, + }, + )]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + // At this point `a` is already onboarded. Run to block 1 performing session change at + // the end of block #0. + run_to_block(2, Some(vec![1])); + + // Relay parent of the block that schedules the upgrade. + const RELAY_PARENT: BlockNumber = 1; + // Expected current session index. + const EXPECTED_SESSION: SessionIndex = 1; + + Paras::schedule_code_upgrade(a, new_code.clone(), RELAY_PARENT, &Configuration::config()); + check_code_is_stored(&new_code); + + // 1/3 of validators vote against `new_code`. PVF should not be rejected yet. + sign_and_include_pvf_check_statement(PvfCheckStatement { + accept: false, + subject: new_code.hash(), + session_index: EXPECTED_SESSION, + validator_index: 0.into(), + }); + + // Verify that the new code is not yet discarded. + check_code_is_stored(&new_code); + + // >1/3 of validators vote against `new_code`. PVF should be rejected. + sign_and_include_pvf_check_statement(PvfCheckStatement { + accept: false, + subject: new_code.hash(), + session_index: EXPECTED_SESSION, + validator_index: 1.into(), + }); + + // Verify that the new code is discarded. + check_code_is_not_stored(&new_code); + + assert!(PvfActiveVoteMap::::get(&new_code.hash()).is_none()); + assert!(Paras::pvfs_require_precheck().is_empty()); + assert!(FutureCodeHash::::get(&a).is_none()); + + // Verify that the required events were emitted. + EventValidator::new().started(&new_code, a).rejected(&new_code, a).check(); + }); +} + +#[test] +fn pvf_check_submit_vote() { + let code_a: ValidationCode = vec![3, 2, 1].into(); + let code_b: ValidationCode = vec![1, 2, 3].into(); + + let check = |stmt: PvfCheckStatement| -> (Result<_, _>, Result<_, _>) { + let validators = &[ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + Sr25519Keyring::Eve, // <- this validator is not in the set + ]; + let signature: ValidatorSignature = + validators[stmt.validator_index.0 as usize].sign(&stmt.signing_payload()).into(); + + let call = + Call::include_pvf_check_statement { stmt: stmt.clone(), signature: signature.clone() }; + let validate_unsigned = + ::validate_unsigned(TransactionSource::InBlock, &call) + .map(|_| ()); + let dispatch_result = + Paras::include_pvf_check_statement(None.into(), stmt.clone(), signature.clone()) + .map(|_| ()); + + (validate_unsigned, dispatch_result) + }; + + let genesis_config = MockGenesisConfig::default(); + + new_test_ext(genesis_config).execute_with(|| { + // Important to run this to seed the validators. + run_to_block(1, Some(vec![1])); + + assert_ok!(Paras::schedule_para_initialize( + 1000.into(), + ParaGenesisArgs { + para_kind: ParaKind::Parathread, + genesis_head: vec![2].into(), + validation_code: code_a.clone(), + }, + )); + + assert_eq!( + check(PvfCheckStatement { + accept: false, + subject: code_a.hash(), + session_index: 1, + validator_index: 1.into(), + }), + (Ok(()), Ok(())), + ); + + // A vote in the same direction. + let (unsigned, dispatch) = check(PvfCheckStatement { + accept: false, + subject: code_a.hash(), + session_index: 1, + validator_index: 1.into(), + }); + assert_eq!(unsigned, Err(InvalidTransaction::Custom(INVALID_TX_DOUBLE_VOTE).into())); + assert_err!(dispatch, Error::::PvfCheckDoubleVote); + + // Equivocation + let (unsigned, dispatch) = check(PvfCheckStatement { + accept: true, + subject: code_a.hash(), + session_index: 1, + validator_index: 1.into(), + }); + assert_eq!(unsigned, Err(InvalidTransaction::Custom(INVALID_TX_DOUBLE_VOTE).into())); + assert_err!(dispatch, Error::::PvfCheckDoubleVote); + + // Vote for an earlier session. + let (unsigned, dispatch) = check(PvfCheckStatement { + accept: false, + subject: code_a.hash(), + session_index: 0, + validator_index: 1.into(), + }); + assert_eq!(unsigned, Err(InvalidTransaction::Stale.into())); + assert_err!(dispatch, Error::::PvfCheckStatementStale); + + // Vote for an later session. + let (unsigned, dispatch) = check(PvfCheckStatement { + accept: false, + subject: code_a.hash(), + session_index: 2, + validator_index: 1.into(), + }); + assert_eq!(unsigned, Err(InvalidTransaction::Future.into())); + assert_err!(dispatch, Error::::PvfCheckStatementFuture); + + // Validator not in the set. + let (unsigned, dispatch) = check(PvfCheckStatement { + accept: false, + subject: code_a.hash(), + session_index: 1, + validator_index: 5.into(), + }); + assert_eq!(unsigned, Err(InvalidTransaction::Custom(INVALID_TX_BAD_VALIDATOR_IDX).into())); + assert_err!(dispatch, Error::::PvfCheckValidatorIndexOutOfBounds); + + // Bad subject (code_b) + let (unsigned, dispatch) = check(PvfCheckStatement { + accept: false, + subject: code_b.hash(), + session_index: 1, + validator_index: 1.into(), + }); + assert_eq!(unsigned, Err(InvalidTransaction::Custom(INVALID_TX_BAD_SUBJECT).into())); + assert_err!(dispatch, Error::::PvfCheckSubjectInvalid); + }); +} + +#[test] +fn include_pvf_check_statement_refunds_weight() { + let a = ParaId::from(111); + let old_code: ValidationCode = vec![1, 2, 3].into(); + let new_code: ValidationCode = vec![3, 2, 1].into(); + + let paras = vec![( + a, + ParaGenesisArgs { + para_kind: ParaKind::Parathread, + genesis_head: Default::default(), + validation_code: old_code, + }, + )]; + + let genesis_config = MockGenesisConfig { + paras: GenesisConfig { paras, ..Default::default() }, + ..Default::default() + }; + + new_test_ext(genesis_config).execute_with(|| { + // At this point `a` is already onboarded. Run to block 1 performing session change at + // the end of block #0. + run_to_block(2, Some(vec![1])); + + // Relay parent of the block that schedules the upgrade. + const RELAY_PARENT: BlockNumber = 1; + // Expected current session index. + const EXPECTED_SESSION: SessionIndex = 1; + + Paras::schedule_code_upgrade(a, new_code.clone(), RELAY_PARENT, &Configuration::config()); + + let mut stmts = IntoIterator::into_iter([0, 1, 2, 3]) + .map(|i| { + let stmt = PvfCheckStatement { + accept: true, + subject: new_code.hash(), + session_index: EXPECTED_SESSION, + validator_index: (i as u32).into(), + }; + let sig = VALIDATORS[i].sign(&stmt.signing_payload()); + (stmt, sig) + }) + .collect::>(); + let last_one = stmts.pop().unwrap(); + + // Verify that just vote submission is priced accordingly. + for (stmt, sig) in stmts { + let r = Paras::include_pvf_check_statement(None.into(), stmt, sig.into()).unwrap(); + assert_eq!(r.actual_weight, Some(TestWeightInfo::include_pvf_check_statement())); + } + + // Verify that the last statement is priced maximally. + let (stmt, sig) = last_one; + let r = Paras::include_pvf_check_statement(None.into(), stmt, sig.into()).unwrap(); + assert_eq!(r.actual_weight, None); + }); +} + +#[test] +fn add_trusted_validation_code_inserts_with_no_users() { + // This test is to ensure that trusted validation code is inserted into the storage + // with the reference count equal to 0. + let validation_code = ValidationCode(vec![1, 2, 3]); + new_test_ext(Default::default()).execute_with(|| { + assert_ok!(Paras::add_trusted_validation_code( + RuntimeOrigin::root(), + validation_code.clone() + )); + assert_eq!(CodeByHashRefs::::get(&validation_code.hash()), 0,); + }); +} + +#[test] +fn add_trusted_validation_code_idempotent() { + // This test makes sure that calling add_trusted_validation_code twice with the same + // parameters is a no-op. + let validation_code = ValidationCode(vec![1, 2, 3]); + new_test_ext(Default::default()).execute_with(|| { + assert_ok!(Paras::add_trusted_validation_code( + RuntimeOrigin::root(), + validation_code.clone() + )); + assert_storage_noop!({ + assert_ok!(Paras::add_trusted_validation_code( + RuntimeOrigin::root(), + validation_code.clone() + )); + }); + }); +} + +#[test] +fn poke_unused_validation_code_removes_code_cleanly() { + // This test makes sure that calling poke_unused_validation_code with a code that is currently + // in the storage but has no users will remove it cleanly from the storage. + let validation_code = ValidationCode(vec![1, 2, 3]); + new_test_ext(Default::default()).execute_with(|| { + assert_ok!(Paras::add_trusted_validation_code( + RuntimeOrigin::root(), + validation_code.clone() + )); + assert_ok!(Paras::poke_unused_validation_code( + RuntimeOrigin::root(), + validation_code.hash() + )); + + assert_eq!(CodeByHashRefs::::get(&validation_code.hash()), 0); + assert!(!CodeByHash::::contains_key(&validation_code.hash())); + }); +} + +#[test] +fn poke_unused_validation_code_doesnt_remove_code_with_users() { + let para_id = 100.into(); + let validation_code = ValidationCode(vec![1, 2, 3]); + new_test_ext(Default::default()).execute_with(|| { + // First we add the code to the storage. + assert_ok!(Paras::add_trusted_validation_code( + RuntimeOrigin::root(), + validation_code.clone() + )); + + // Then we add a user to the code, say by upgrading. + run_to_block(2, None); + Paras::schedule_code_upgrade(para_id, validation_code.clone(), 1, &Configuration::config()); + Paras::note_new_head(para_id, HeadData::default(), 1); + + // Finally we poke the code, which should not remove it from the storage. + assert_storage_noop!({ + assert_ok!(Paras::poke_unused_validation_code( + RuntimeOrigin::root(), + validation_code.hash() + )); + }); + check_code_is_stored(&validation_code); + }); +} + +#[test] +fn increase_code_ref_doesnt_have_allergy_on_add_trusted_validation_code() { + // Verify that accidential calling of increase_code_ref or decrease_code_ref does not lead + // to a disaster. + // NOTE that this test is extra paranoid, as it is not really possible to hit + // `decrease_code_ref` without calling `increase_code_ref` first. + let code = ValidationCode(vec![1, 2, 3]); + + new_test_ext(Default::default()).execute_with(|| { + assert_ok!(Paras::add_trusted_validation_code(RuntimeOrigin::root(), code.clone())); + Paras::increase_code_ref(&code.hash(), &code); + Paras::increase_code_ref(&code.hash(), &code); + assert!(CodeByHash::::contains_key(code.hash())); + assert_eq!(CodeByHashRefs::::get(code.hash()), 2); + }); + + new_test_ext(Default::default()).execute_with(|| { + assert_ok!(Paras::add_trusted_validation_code(RuntimeOrigin::root(), code.clone())); + Paras::decrease_code_ref(&code.hash()); + assert!(CodeByHash::::contains_key(code.hash())); + assert_eq!(CodeByHashRefs::::get(code.hash()), 0); + }); +} + +#[test] +fn add_trusted_validation_code_insta_approval() { + // In particular, this tests that `kick_off_pvf_check` reacts to the + // `add_trusted_validation_code` and uses the `CodeByHash::contains_key` which is what + // `add_trusted_validation_code` uses. + let para_id = 100.into(); + let validation_code = ValidationCode(vec![1, 2, 3]); + let validation_upgrade_delay = 25; + let minimum_validation_upgrade_delay = 2; + let genesis_config = MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { + validation_upgrade_delay, + minimum_validation_upgrade_delay, + ..Default::default() + }, + }, + ..Default::default() + }; + new_test_ext(genesis_config).execute_with(|| { + assert_ok!(Paras::add_trusted_validation_code( + RuntimeOrigin::root(), + validation_code.clone() + )); + + // Then some parachain upgrades it's code with the relay-parent 1. + run_to_block(2, None); + Paras::schedule_code_upgrade(para_id, validation_code.clone(), 1, &Configuration::config()); + Paras::note_new_head(para_id, HeadData::default(), 1); + + // Verify that the code upgrade has `expected_at` set to `26`. + assert_eq!(FutureCodeUpgrades::::get(¶_id), Some(1 + validation_upgrade_delay)); + + // Verify that the required events were emitted. + EventValidator::new() + .started(&validation_code, para_id) + .accepted(&validation_code, para_id) + .check(); + }); +} + +#[test] +fn add_trusted_validation_code_enacts_existing_pvf_vote() { + // This test makes sure that calling `add_trusted_validation_code` with a code that is + // already going through PVF pre-checking voting will conclude the voting and enact the + // code upgrade. + let para_id = 100.into(); + let validation_code = ValidationCode(vec![1, 2, 3]); + let validation_upgrade_delay = 25; + let minimum_validation_upgrade_delay = 2; + let genesis_config = MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: HostConfiguration { + validation_upgrade_delay, + minimum_validation_upgrade_delay, + ..Default::default() + }, + }, + ..Default::default() + }; + new_test_ext(genesis_config).execute_with(|| { + // First, some parachain upgrades it's code with the relay-parent 1. + run_to_block(2, None); + Paras::schedule_code_upgrade(para_id, validation_code.clone(), 1, &Configuration::config()); + Paras::note_new_head(para_id, HeadData::default(), 1); + + // No upgrade should be scheduled at this point. PVF pre-checking vote should run for + // that PVF. + assert!(FutureCodeUpgrades::::get(¶_id).is_none()); + assert!(PvfActiveVoteMap::::contains_key(&validation_code.hash())); + + // Then we add a trusted validation code. That should conclude the vote. + assert_ok!(Paras::add_trusted_validation_code( + RuntimeOrigin::root(), + validation_code.clone() + )); + assert!(FutureCodeUpgrades::::get(¶_id).is_some()); + assert!(!PvfActiveVoteMap::::contains_key(&validation_code.hash())); + }); +} + +#[test] +fn verify_upgrade_go_ahead_signal_is_externally_accessible() { + use primitives::well_known_keys; + + let a = ParaId::from(2020); + + new_test_ext(Default::default()).execute_with(|| { + assert!(sp_io::storage::get(&well_known_keys::upgrade_go_ahead_signal(a)).is_none()); + UpgradeGoAheadSignal::::insert(&a, UpgradeGoAhead::GoAhead); + assert_eq!( + sp_io::storage::get(&well_known_keys::upgrade_go_ahead_signal(a)).unwrap(), + vec![1u8], + ); + }); +} + +#[test] +fn verify_upgrade_restriction_signal_is_externally_accessible() { + use primitives::well_known_keys; + + let a = ParaId::from(2020); + + new_test_ext(Default::default()).execute_with(|| { + assert!(sp_io::storage::get(&well_known_keys::upgrade_restriction_signal(a)).is_none()); + UpgradeRestrictionSignal::::insert(&a, UpgradeRestriction::Present); + assert_eq!( + sp_io::storage::get(&well_known_keys::upgrade_restriction_signal(a)).unwrap(), + vec![0], + ); + }); +} + +#[test] +fn verify_para_head_is_externally_accessible() { + use primitives::well_known_keys; + + let a = ParaId::from(2020); + let expected_head_data = HeadData(vec![0, 1, 2, 3]); + + new_test_ext(Default::default()).execute_with(|| { + Heads::::insert(&a, expected_head_data.clone()); + let encoded = sp_io::storage::get(&well_known_keys::para_head(a)).unwrap(); + let head_data = HeadData::decode(&mut encoded.as_ref()); + assert_eq!(head_data, Ok(expected_head_data)); + }); +} + +#[test] +fn most_recent_context() { + let validation_code: ValidationCode = vec![1, 2, 3].into(); + + let genesis_config = MockGenesisConfig::default(); + + new_test_ext(genesis_config).execute_with(|| { + const EXPECTED_SESSION: SessionIndex = 1; + run_to_block(1, Some(vec![1])); + + let para_id = ParaId::from(111); + + assert_eq!(Paras::para_most_recent_context(para_id), None); + + assert_ok!(Paras::schedule_para_initialize( + para_id, + ParaGenesisArgs { + para_kind: ParaKind::Parachain, + genesis_head: vec![1].into(), + validation_code: validation_code.clone(), + }, + )); + submit_super_majority_pvf_votes(&validation_code, EXPECTED_SESSION, true); + + assert_eq!(ParaLifecycles::::get(¶_id), Some(ParaLifecycle::Onboarding)); + + // Two sessions pass, so action queue is triggered. + run_to_block(4, Some(vec![3, 4])); + + // Double-check the para is onboarded, the context is set to the recent block. + assert_eq!(ParaLifecycles::::get(¶_id), Some(ParaLifecycle::Parachain)); + assert_eq!(Paras::para_most_recent_context(para_id), Some(0)); + + // Progress para to the new head and check that the recent context is updated. + Paras::note_new_head(para_id, vec![4, 5, 6].into(), 3); + assert_eq!(Paras::para_most_recent_context(para_id), Some(3)); + + // Finally, offboard the para and expect the context to be cleared. + assert_ok!(Paras::schedule_para_cleanup(para_id)); + run_to_block(6, Some(vec![5, 6])); + assert_eq!(Paras::para_most_recent_context(para_id), None); + }) +} + +#[test] +fn parakind_encodes_decodes_to_bool_scale() { + let chain_kind = ParaKind::Parachain.encode(); + let chain_bool = true.encode(); + assert_eq!(chain_kind, chain_bool); + + let chain_dec = ParaKind::decode(&mut chain_kind.as_slice()); + assert_eq!(chain_dec, Ok(ParaKind::Parachain)); + + let thread_kind = ParaKind::Parathread.encode(); + let thread_bool = false.encode(); + assert_eq!(thread_kind, thread_bool); + + let thread_dec = ParaKind::decode(&mut thread_kind.as_slice()); + assert_eq!(thread_dec, Ok(ParaKind::Parathread)); + + assert_eq!(bool::type_info(), ParaKind::type_info()); +} + +#[test] +fn parakind_encodes_decodes_to_bool_serde() { + let chain = ParaKind::Parachain; + let ser_chain = serde_json::to_string(&ParaKind::Parachain).unwrap(); + let de_chain: ParaKind = serde_json::from_str(&ser_chain).unwrap(); + assert_eq!(chain, de_chain); + + let ser_true = serde_json::to_string(&true).unwrap(); + assert_eq!(ser_true, ser_chain); + + let thread = ParaKind::Parathread; + let ser_thread = serde_json::to_string(&thread).unwrap(); + let de_thread: ParaKind = serde_json::from_str(&ser_thread).unwrap(); + assert_eq!(thread, de_thread); + + let ser_false = serde_json::to_string(&false).unwrap(); + assert_eq!(ser_false, ser_thread); +} + +#[test] +fn parachains_cache_is_set() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let a = ParaId::from(111); + + let mut parachains_cache: ParachainsCache = ParachainsCache::new(); + + // Add element twice + parachains_cache.add(a); + parachains_cache.add(a); + + // Flush cache to storage + drop(parachains_cache); + + // In order after addition + assert_eq!(Parachains::::get(), vec![a]); + + let mut parachains_cache: ParachainsCache = ParachainsCache::new(); + + // Remove element twice + parachains_cache.remove(a); + parachains_cache.remove(a); + + // Flush cache to storage + drop(parachains_cache); + + // In order after removal + assert_eq!(Parachains::::get(), vec![]); + + let mut parachains_cache: ParachainsCache = ParachainsCache::new(); + + // Remove nonexisting element + parachains_cache.remove(a); + assert_storage_noop!(drop(parachains_cache)); + assert_eq!(Parachains::::get(), vec![]); + }); +} + +#[test] +fn parachains_cache_preserves_order() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let a = ParaId::from(111); + let b = ParaId::from(222); + let c = ParaId::from(333); + let d = ParaId::from(444); + + let mut parachains_cache: ParachainsCache = ParachainsCache::new(); + + // Add in mixed order + parachains_cache.add(b); + parachains_cache.add(c); + parachains_cache.add(a); + parachains_cache.add(d); + + // Flush cache to storage + drop(parachains_cache); + + // In order after addition + assert_eq!(Parachains::::get(), vec![a, b, c, d]); + + let mut parachains_cache: ParachainsCache = ParachainsCache::new(); + + // Remove 2 elements + parachains_cache.remove(b); + parachains_cache.remove(d); + + // Flush cache to storage + drop(parachains_cache); + + // In order after removal + assert_eq!(Parachains::::get(), vec![a, c]); + }); +} diff --git a/polkadot/runtime/parachains/src/paras_inherent/benchmarking.rs b/polkadot/runtime/parachains/src/paras_inherent/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..3043127c3174660b72a55ce850bb9d05c2330ad2 --- /dev/null +++ b/polkadot/runtime/parachains/src/paras_inherent/benchmarking.rs @@ -0,0 +1,220 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::{inclusion, ParaId}; +use frame_benchmarking::{benchmarks, impl_benchmark_test_suite}; +use frame_system::RawOrigin; +use sp_std::collections::btree_map::BTreeMap; + +use crate::builder::BenchBuilder; + +benchmarks! { + // Variant over `v`, the number of dispute statements in a dispute statement set. This gives the + // weight of a single dispute statement set. + enter_variable_disputes { + let v in 10..BenchBuilder::::fallback_max_validators(); + + let scenario = BenchBuilder::::new() + .set_dispute_sessions(&[2]) + .build(); + + let mut benchmark = scenario.data.clone(); + let dispute = benchmark.disputes.pop().unwrap(); + + benchmark.bitfields.clear(); + benchmark.backed_candidates.clear(); + benchmark.disputes.clear(); + + benchmark.disputes.push(dispute); + benchmark.disputes.get_mut(0).unwrap().statements.drain(v as usize..); + }: enter(RawOrigin::None, benchmark) + verify { + // Assert that the block was not discarded + assert!(Included::::get().is_some()); + + // Assert that there are on-chain votes that got scraped + let onchain_votes = OnChainVotes::::get(); + assert!(onchain_votes.is_some()); + let vote = onchain_votes.unwrap(); + + // Ensure that the votes are for the correct session + assert_eq!(vote.session, scenario._session); + } + + // The weight of one bitfield. + enter_bitfields { + let cores_with_backed: BTreeMap<_, _> + = vec![(0, BenchBuilder::::fallback_max_validators())] + .into_iter() + .collect(); + + let scenario = BenchBuilder::::new() + .set_backed_and_concluding_cores(cores_with_backed) + .build(); + + let mut benchmark = scenario.data.clone(); + let bitfield = benchmark.bitfields.pop().unwrap(); + + benchmark.bitfields.clear(); + benchmark.backed_candidates.clear(); + benchmark.disputes.clear(); + + benchmark.bitfields.push(bitfield); + }: enter(RawOrigin::None, benchmark) + verify { + // Assert that the block was not discarded + assert!(Included::::get().is_some()); + // Assert that there are on-chain votes that got scraped + let onchain_votes = OnChainVotes::::get(); + assert!(onchain_votes.is_some()); + let vote = onchain_votes.unwrap(); + // Ensure that the votes are for the correct session + assert_eq!(vote.session, scenario._session); + } + + // Variant over `v`, the amount of validity votes for a backed candidate. This gives the weight + // of a single backed candidate. + enter_backed_candidates_variable { + // NOTE: the starting value must be over half of the max validators per group so the backed + // candidate is not rejected. Also, we cannot have more validity votes than validators in + // the group. + + // Do not use this range for Rococo because it only has 1 validator per backing group, + // which causes issues when trying to create slopes with the benchmarking analysis. Instead + // use v = 1 for running Rococo benchmarks + let v in (BenchBuilder::::fallback_min_validity_votes()) + ..(BenchBuilder::::fallback_max_validators()); + + // Comment in for running rococo benchmarks + // let v = 1; + + let cores_with_backed: BTreeMap<_, _> + = vec![(0, v)] // The backed candidate will have `v` validity votes. + .into_iter() + .collect(); + + let scenario = BenchBuilder::::new() + .set_backed_and_concluding_cores(cores_with_backed.clone()) + .build(); + + let mut benchmark = scenario.data.clone(); + + // There is 1 backed, + assert_eq!(benchmark.backed_candidates.len(), 1); + // with `v` validity votes. + assert_eq!(benchmark.backed_candidates.get(0).unwrap().validity_votes.len(), v as usize); + + benchmark.bitfields.clear(); + benchmark.disputes.clear(); + }: enter(RawOrigin::None, benchmark) + verify { + let max_validators_per_core = BenchBuilder::::fallback_max_validators_per_core(); + // Assert that the block was not discarded + assert!(Included::::get().is_some()); + // Assert that there are on-chain votes that got scraped + let onchain_votes = OnChainVotes::::get(); + assert!(onchain_votes.is_some()); + let vote = onchain_votes.unwrap(); + // Ensure that the votes are for the correct session + assert_eq!(vote.session, scenario._session); + // Ensure that there are an expected number of candidates + let header = BenchBuilder::::header(scenario._block_number.clone()); + // Traverse candidates and assert descriptors are as expected + for (para_id, backing_validators) in vote.backing_validators_per_candidate.iter().enumerate() { + let descriptor = backing_validators.0.descriptor(); + assert_eq!(ParaId::from(para_id), descriptor.para_id); + assert_eq!(header.hash(), descriptor.relay_parent); + assert_eq!(backing_validators.1.len(), v as usize); + } + + assert_eq!( + inclusion::PendingAvailabilityCommitments::::iter().count(), + cores_with_backed.len() + ); + assert_eq!( + inclusion::PendingAvailability::::iter().count(), + cores_with_backed.len() + ); + } + + enter_backed_candidate_code_upgrade { + // For now we always assume worst case code size. In the future we could vary over this. + let v = crate::configuration::Pallet::::config().max_code_size; + + let cores_with_backed: BTreeMap<_, _> + = vec![(0, BenchBuilder::::fallback_min_validity_votes())] + .into_iter() + .collect(); + + let scenario = BenchBuilder::::new() + .set_backed_and_concluding_cores(cores_with_backed.clone()) + .set_code_upgrade(v) + .build(); + + let mut benchmark = scenario.data.clone(); + + // There is 1 backed + assert_eq!(benchmark.backed_candidates.len(), 1); + assert_eq!( + benchmark.backed_candidates.get(0).unwrap().validity_votes.len() as u32, + BenchBuilder::::fallback_min_validity_votes() + ); + + benchmark.bitfields.clear(); + benchmark.disputes.clear(); + crate::paras::benchmarking::generate_disordered_upgrades::(); + }: enter(RawOrigin::None, benchmark) + verify { + let max_validators_per_core = BenchBuilder::::fallback_max_validators_per_core(); + // Assert that the block was not discarded + assert!(Included::::get().is_some()); + // Assert that there are on-chain votes that got scraped + let onchain_votes = OnChainVotes::::get(); + assert!(onchain_votes.is_some()); + let vote = onchain_votes.unwrap(); + // Ensure that the votes are for the correct session + assert_eq!(vote.session, scenario._session); + // Ensure that there are an expected number of candidates + let header = BenchBuilder::::header(scenario._block_number.clone()); + // Traverse candidates and assert descriptors are as expected + for (para_id, backing_validators) + in vote.backing_validators_per_candidate.iter().enumerate() { + let descriptor = backing_validators.0.descriptor(); + assert_eq!(ParaId::from(para_id), descriptor.para_id); + assert_eq!(header.hash(), descriptor.relay_parent); + assert_eq!( + backing_validators.1.len() as u32, + BenchBuilder::::fallback_min_validity_votes() + ); + } + + assert_eq!( + inclusion::PendingAvailabilityCommitments::::iter().count(), + cores_with_backed.len() + ); + assert_eq!( + inclusion::PendingAvailability::::iter().count(), + cores_with_backed.len() + ); + } +} + +impl_benchmark_test_suite!( + Pallet, + crate::mock::new_test_ext(Default::default()), + crate::mock::Test +); diff --git a/polkadot/runtime/parachains/src/paras_inherent/misc.rs b/polkadot/runtime/parachains/src/paras_inherent/misc.rs new file mode 100644 index 0000000000000000000000000000000000000000..e77b26b9e12f5fa34ab80967496f50ab07b3d6bf --- /dev/null +++ b/polkadot/runtime/parachains/src/paras_inherent/misc.rs @@ -0,0 +1,112 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use sp_std::{cmp::Ordering, vec::Vec}; + +/// A helper trait to allow calling retain while getting access +/// to the index of the item in the `vec`. +pub trait IndexedRetain { + /// Retains only the elements specified by the predicate. + /// + /// In other words, remove all elements `e` residing at + /// index `i` such that `f(i, &e)` returns `false`. This method + /// operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. + fn indexed_retain(&mut self, f: impl FnMut(usize, &T) -> bool); +} + +impl IndexedRetain for Vec { + fn indexed_retain(&mut self, mut f: impl FnMut(usize, &T) -> bool) { + let mut idx = 0_usize; + self.retain(move |item| { + let ret = f(idx, item); + idx += 1_usize; + ret + }) + } +} + +/// Helper trait until `is_sorted_by` is stabilized. +/// TODO: https://github.com/rust-lang/rust/issues/53485 +pub trait IsSortedBy { + fn is_sorted_by(self, cmp: F) -> bool + where + F: FnMut(&T, &T) -> Ordering; +} + +impl<'x, T, X> IsSortedBy for X +where + X: 'x + IntoIterator, + T: 'x, +{ + fn is_sorted_by(self, mut cmp: F) -> bool + where + F: FnMut(&T, &T) -> Ordering, + { + let mut iter = self.into_iter(); + let mut previous: &T = if let Some(previous) = iter.next() { + previous + } else { + // empty is always sorted + return true + }; + while let Some(cursor) = iter.next() { + match cmp(&previous, &cursor) { + Ordering::Greater => return false, + _ => { + // ordering is ok + }, + } + previous = cursor; + } + true + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn is_sorted_simple() { + let v = vec![1_i32, 2, 3, 1000]; + assert!(IsSortedBy::::is_sorted_by(v.as_slice(), |a: &i32, b: &i32| { a.cmp(b) })); + assert!(!IsSortedBy::::is_sorted_by(&v, |a, b| { b.cmp(a) })); + + let v = vec![8_i32, 8, 8, 8]; + assert!(IsSortedBy::::is_sorted_by(v.as_slice(), |a: &i32, b: &i32| { a.cmp(b) })); + assert!(IsSortedBy::::is_sorted_by(v.as_slice(), |a: &i32, b: &i32| { b.cmp(a) })); + } + + #[test] + fn is_not_sorted() { + let v = vec![7, 1, 3]; + assert!(!IsSortedBy::is_sorted_by(&v, |a, b| { a.cmp(b) })); + assert!(!IsSortedBy::is_sorted_by(&v, |a, b| { b.cmp(a) })); + } + + #[test] + fn empty_is_sorted() { + let v = Vec::::new(); + assert!(IsSortedBy::is_sorted_by(&v, |_a, _b| { unreachable!() })); + } + + #[test] + fn single_items_is_sorted() { + let v = vec![7_u8]; + assert!(IsSortedBy::is_sorted_by(&v, |_a, _b| { unreachable!() })); + } +} diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..6244f44e434b03106393879b815fcbfb0a3a5e0d --- /dev/null +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -0,0 +1,1037 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Provides glue code over the scheduler and inclusion modules, and accepting +//! one inherent per block that can include new para candidates and bitfields. +//! +//! Unlike other modules in this crate, it does not need to be initialized by the initializer, +//! as it has no initialization logic and its finalization logic depends only on the details of +//! this module. + +use crate::{ + configuration, + disputes::DisputesHandler, + inclusion, + inclusion::CandidateCheckContext, + initializer, + metrics::METRICS, + paras, + scheduler::{ + self, + common::{CoreAssignment, FreedReason}, + }, + shared, ParaId, +}; +use bitvec::prelude::BitVec; +use frame_support::{ + dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}, + inherent::{InherentData, InherentIdentifier, MakeFatalError, ProvideInherent}, + pallet_prelude::*, + traits::Randomness, +}; +use frame_system::pallet_prelude::*; +use pallet_babe::{self, ParentBlockRandomness}; +use primitives::{ + BackedCandidate, CandidateHash, CandidateReceipt, CheckedDisputeStatementSet, + CheckedMultiDisputeStatementSet, CoreIndex, DisputeStatementSet, + InherentData as ParachainsInherentData, MultiDisputeStatementSet, ScrapedOnChainVotes, + SessionIndex, SignedAvailabilityBitfields, SigningContext, UncheckedSignedAvailabilityBitfield, + UncheckedSignedAvailabilityBitfields, ValidatorId, ValidatorIndex, ValidityAttestation, + PARACHAINS_INHERENT_IDENTIFIER, +}; +use rand::{seq::SliceRandom, SeedableRng}; + +use scale_info::TypeInfo; +use sp_runtime::traits::{Header as HeaderT, One}; +use sp_std::{ + collections::{btree_map::BTreeMap, btree_set::BTreeSet}, + prelude::*, + vec::Vec, +}; + +mod misc; +mod weights; + +use self::weights::checked_multi_dispute_statement_sets_weight; +pub use self::{ + misc::{IndexedRetain, IsSortedBy}, + weights::{ + backed_candidate_weight, backed_candidates_weight, dispute_statement_set_weight, + multi_dispute_statement_sets_weight, paras_inherent_total_weight, signed_bitfield_weight, + signed_bitfields_weight, TestWeightInfo, WeightInfo, + }, +}; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &str = "runtime::inclusion-inherent"; + +/// A bitfield concerning concluded disputes for candidates +/// associated to the core index equivalent to the bit position. +#[derive(Default, PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +pub(crate) struct DisputedBitfield(pub(crate) BitVec); + +impl From> for DisputedBitfield { + fn from(inner: BitVec) -> Self { + Self(inner) + } +} + +#[cfg(test)] +impl DisputedBitfield { + /// Create a new bitfield, where each bit is set to `false`. + pub fn zeros(n: usize) -> Self { + Self::from(BitVec::::repeat(false, n)) + } +} + +/// The context in which the inherent data is checked or processed. +#[derive(PartialEq)] +pub enum ProcessInherentDataContext { + /// Enables filtering/limits weight of inherent up to maximum block weight. + /// Invariant: InherentWeight <= BlockWeight. + ProvideInherent, + /// Checks the InherentWeight invariant. + Enter, +} +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + #[pallet::disable_frame_system_supertrait_check] + pub trait Config: + inclusion::Config + scheduler::Config + initializer::Config + pallet_babe::Config + { + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::error] + pub enum Error { + /// Inclusion inherent called more than once per block. + TooManyInclusionInherents, + /// The hash of the submitted parent header doesn't correspond to the saved block hash of + /// the parent. + InvalidParentHeader, + /// Disputed candidate that was concluded invalid. + CandidateConcludedInvalid, + /// The data given to the inherent will result in an overweight block. + InherentOverweight, + /// The ordering of dispute statements was invalid. + DisputeStatementsUnsortedOrDuplicates, + /// A dispute statement was invalid. + DisputeInvalid, + } + + /// Whether the paras inherent was included within this block. + /// + /// The `Option<()>` is effectively a `bool`, but it never hits storage in the `None` variant + /// due to the guarantees of FRAME's storage APIs. + /// + /// If this is `None` at the end of the block, we panic and render the block invalid. + #[pallet::storage] + pub(crate) type Included = StorageValue<_, ()>; + + /// Scraped on chain data for extracting resolved disputes as well as backing votes. + #[pallet::storage] + #[pallet::getter(fn on_chain_votes)] + pub(crate) type OnChainVotes = StorageValue<_, ScrapedOnChainVotes>; + + /// Update the disputes statements set part of the on-chain votes. + pub(crate) fn set_scrapable_on_chain_disputes( + session: SessionIndex, + checked_disputes: CheckedMultiDisputeStatementSet, + ) { + crate::paras_inherent::OnChainVotes::::mutate(move |value| { + let disputes = + checked_disputes.into_iter().map(DisputeStatementSet::from).collect::>(); + let backing_validators_per_candidate = match value.take() { + Some(v) => v.backing_validators_per_candidate, + None => Vec::new(), + }; + *value = Some(ScrapedOnChainVotes:: { + backing_validators_per_candidate, + disputes, + session, + }); + }) + } + + /// Update the backing votes including part of the on-chain votes. + pub(crate) fn set_scrapable_on_chain_backings( + session: SessionIndex, + backing_validators_per_candidate: Vec<( + CandidateReceipt, + Vec<(ValidatorIndex, ValidityAttestation)>, + )>, + ) { + crate::paras_inherent::OnChainVotes::::mutate(move |value| { + let disputes = match value.take() { + Some(v) => v.disputes, + None => MultiDisputeStatementSet::default(), + }; + *value = Some(ScrapedOnChainVotes:: { + backing_validators_per_candidate, + disputes, + session, + }); + }) + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(_: BlockNumberFor) -> Weight { + T::DbWeight::get().reads_writes(1, 1) // in `on_finalize`. + } + + fn on_finalize(_: BlockNumberFor) { + if Included::::take().is_none() { + panic!("Bitfields and heads must be included every block"); + } + } + } + + #[pallet::inherent] + impl ProvideInherent for Pallet { + type Call = Call; + type Error = MakeFatalError<()>; + const INHERENT_IDENTIFIER: InherentIdentifier = PARACHAINS_INHERENT_IDENTIFIER; + + fn create_inherent(data: &InherentData) -> Option { + let inherent_data = Self::create_inherent_inner(data)?; + + Some(Call::enter { data: inherent_data }) + } + + fn is_inherent(call: &Self::Call) -> bool { + matches!(call, Call::enter { .. }) + } + } + + /// Collect all freed cores based on storage data. (i.e. append cores freed from timeouts to + /// the given `freed_concluded`). + /// + /// The parameter `freed_concluded` contains all core indicies that became + /// free due to candidate that became available. + pub(crate) fn collect_all_freed_cores( + freed_concluded: I, + ) -> BTreeMap + where + I: core::iter::IntoIterator, + T: Config, + { + // Handle timeouts for any availability core work. + let availability_pred = >::availability_timeout_predicate(); + let freed_timeout = if let Some(pred) = availability_pred { + >::collect_pending(pred) + } else { + Vec::new() + }; + + // Schedule paras again, given freed cores, and reasons for freeing. + let freed = freed_concluded + .into_iter() + .map(|(c, _hash)| (c, FreedReason::Concluded)) + .chain(freed_timeout.into_iter().map(|c| (c, FreedReason::TimedOut))) + .collect::>(); + freed + } + + #[pallet::call] + impl Pallet { + /// Enter the paras inherent. This will process bitfields and backed candidates. + #[pallet::call_index(0)] + #[pallet::weight(( + paras_inherent_total_weight::( + data.backed_candidates.as_slice(), + &data.bitfields, + &data.disputes, + ), + DispatchClass::Mandatory, + ))] + pub fn enter( + origin: OriginFor, + data: ParachainsInherentData>, + ) -> DispatchResultWithPostInfo { + ensure_none(origin)?; + + ensure!(!Included::::exists(), Error::::TooManyInclusionInherents); + Included::::set(Some(())); + + Self::process_inherent_data(data, ProcessInherentDataContext::Enter) + .map(|(_processed, post_info)| post_info) + } + } +} + +impl Pallet { + /// Create the `ParachainsInherentData` that gets passed to [`Self::enter`] in + /// [`Self::create_inherent`]. This code is pulled out of [`Self::create_inherent`] so it can be + /// unit tested. + fn create_inherent_inner(data: &InherentData) -> Option>> { + let parachains_inherent_data = match data.get_data(&Self::INHERENT_IDENTIFIER) { + Ok(Some(d)) => d, + Ok(None) => return None, + Err(_) => { + log::warn!(target: LOG_TARGET, "ParachainsInherentData failed to decode"); + return None + }, + }; + match Self::process_inherent_data( + parachains_inherent_data, + ProcessInherentDataContext::ProvideInherent, + ) { + Ok((processed, _)) => Some(processed), + Err(err) => { + log::warn!(target: LOG_TARGET, "Processing inherent data failed: {:?}", err); + None + }, + } + } + + /// Process inherent data. + /// + /// The given inherent data is processed and state is altered accordingly. If any data could + /// not be applied (inconsitencies, weight limit, ...) it is removed. + /// + /// When called from `create_inherent` the `context` must be set to + /// `ProcessInherentDataContext::ProvideInherent` so it guarantees the invariant that inherent + /// is not overweight. + /// It is **mandatory** that calls from `enter` set `context` to + /// `ProcessInherentDataContext::Enter` to ensure the weight invariant is checked. + /// + /// Returns: Result containing processed inherent data and weight, the processed inherent would + /// consume. + fn process_inherent_data( + data: ParachainsInherentData>, + context: ProcessInherentDataContext, + ) -> sp_std::result::Result< + (ParachainsInherentData>, PostDispatchInfo), + DispatchErrorWithPostInfo, + > { + #[cfg(feature = "runtime-metrics")] + sp_io::init_tracing(); + + let ParachainsInherentData { + mut bitfields, + mut backed_candidates, + parent_header, + mut disputes, + } = data; + + log::debug!( + target: LOG_TARGET, + "[process_inherent_data] bitfields.len(): {}, backed_candidates.len(): {}, disputes.len() {}", + bitfields.len(), + backed_candidates.len(), + disputes.len() + ); + + let parent_hash = >::parent_hash(); + + ensure!( + parent_header.hash().as_ref() == parent_hash.as_ref(), + Error::::InvalidParentHeader, + ); + + let now = >::block_number(); + let config = >::config(); + + // Before anything else, update the allowed relay-parents. + { + let parent_number = now - One::one(); + let parent_storage_root = *parent_header.state_root(); + + shared::AllowedRelayParents::::mutate(|tracker| { + tracker.update( + parent_hash, + parent_storage_root, + parent_number, + config.async_backing_params.allowed_ancestry_len, + ); + }); + } + let allowed_relay_parents = >::allowed_relay_parents(); + + let candidates_weight = backed_candidates_weight::(&backed_candidates); + let bitfields_weight = signed_bitfields_weight::(&bitfields); + let disputes_weight = multi_dispute_statement_sets_weight::(&disputes); + + let all_weight_before = candidates_weight + bitfields_weight + disputes_weight; + + METRICS.on_before_filter(all_weight_before.ref_time()); + log::debug!(target: LOG_TARGET, "Size before filter: {}, candidates + bitfields: {}, disputes: {}", all_weight_before.proof_size(), candidates_weight.proof_size() + bitfields_weight.proof_size(), disputes_weight.proof_size()); + log::debug!(target: LOG_TARGET, "Time weight before filter: {}, candidates + bitfields: {}, disputes: {}", all_weight_before.ref_time(), candidates_weight.ref_time() + bitfields_weight.ref_time(), disputes_weight.ref_time()); + + let current_session = >::session_index(); + let expected_bits = >::availability_cores().len(); + let validator_public = shared::Pallet::::active_validator_keys(); + + // We are assuming (incorrectly) to have all the weight (for the mandatory class or even + // full block) available to us. This can lead to slightly overweight blocks, which still + // works as the dispatch class for `enter` is `Mandatory`. By using the `Mandatory` + // dispatch class, the upper layers impose no limit on the weight of this inherent, instead + // we limit ourselves and make sure to stay within reasonable bounds. It might make sense + // to subtract BlockWeights::base_block to reduce chances of becoming overweight. + let max_block_weight = { + let dispatch_class = DispatchClass::Mandatory; + let max_block_weight_full = ::BlockWeights::get(); + log::debug!(target: LOG_TARGET, "Max block weight: {}", max_block_weight_full.max_block); + // Get max block weight for the mandatory class if defined, otherwise total max weight + // of the block. + let max_weight = max_block_weight_full + .per_class + .get(dispatch_class) + .max_total + .unwrap_or(max_block_weight_full.max_block); + log::debug!(target: LOG_TARGET, "Used max block time weight: {}", max_weight); + + let max_block_size_full = ::BlockLength::get(); + let max_block_size = max_block_size_full.max.get(dispatch_class); + log::debug!(target: LOG_TARGET, "Used max block size: {}", max_block_size); + + // Adjust proof size to max block size as we are tracking tx size. + max_weight.set_proof_size(*max_block_size as u64) + }; + log::debug!(target: LOG_TARGET, "Used max block weight: {}", max_block_weight); + + let entropy = compute_entropy::(parent_hash); + let mut rng = rand_chacha::ChaChaRng::from_seed(entropy.into()); + + // Filter out duplicates and continue. + if let Err(()) = T::DisputesHandler::deduplicate_and_sort_dispute_data(&mut disputes) { + log::debug!(target: LOG_TARGET, "Found duplicate statement sets, retaining the first"); + } + + let post_conclusion_acceptance_period = config.dispute_post_conclusion_acceptance_period; + + let dispute_statement_set_valid = move |set: DisputeStatementSet| { + T::DisputesHandler::filter_dispute_data(set, post_conclusion_acceptance_period) + }; + + // Limit the disputes first, since the following statements depend on the votes include + // here. + let (checked_disputes_sets, checked_disputes_sets_consumed_weight) = + limit_and_sanitize_disputes::( + disputes, + dispute_statement_set_valid, + max_block_weight, + ); + + let all_weight_after = if context == ProcessInherentDataContext::ProvideInherent { + // Assure the maximum block weight is adhered, by limiting bitfields and backed + // candidates. Dispute statement sets were already limited before. + let non_disputes_weight = apply_weight_limit::( + &mut backed_candidates, + &mut bitfields, + max_block_weight.saturating_sub(checked_disputes_sets_consumed_weight), + &mut rng, + ); + + let all_weight_after = + non_disputes_weight.saturating_add(checked_disputes_sets_consumed_weight); + + METRICS.on_after_filter(all_weight_after.ref_time()); + log::debug!( + target: LOG_TARGET, + "[process_inherent_data] after filter: bitfields.len(): {}, backed_candidates.len(): {}, checked_disputes_sets.len() {}", + bitfields.len(), + backed_candidates.len(), + checked_disputes_sets.len() + ); + log::debug!(target: LOG_TARGET, "Size after filter: {}, candidates + bitfields: {}, disputes: {}", all_weight_after.proof_size(), non_disputes_weight.proof_size(), checked_disputes_sets_consumed_weight.proof_size()); + log::debug!(target: LOG_TARGET, "Time weight after filter: {}, candidates + bitfields: {}, disputes: {}", all_weight_after.ref_time(), non_disputes_weight.ref_time(), checked_disputes_sets_consumed_weight.ref_time()); + + if all_weight_after.any_gt(max_block_weight) { + log::warn!(target: LOG_TARGET, "Post weight limiting weight is still too large, time: {}, size: {}", all_weight_after.ref_time(), all_weight_after.proof_size()); + } + all_weight_after + } else { + // This check is performed in the context of block execution. Ensures inherent weight + // invariants guaranteed by `create_inherent_data` for block authorship. + if all_weight_before.any_gt(max_block_weight) { + log::error!( + "Overweight para inherent data reached the runtime {:?}: {} > {}", + parent_hash, + all_weight_before, + max_block_weight + ); + } + + ensure!(all_weight_before.all_lte(max_block_weight), Error::::InherentOverweight); + all_weight_before + }; + + // Note that `process_checked_multi_dispute_data` will iterate and import each + // dispute; so the input here must be reasonably bounded, + // which is guaranteed by the checks and weight limitation above. + // We don't care about fresh or not disputes + // this writes them to storage, so let's query it via those means + // if this fails for whatever reason, that's ok. + if let Err(e) = + T::DisputesHandler::process_checked_multi_dispute_data(&checked_disputes_sets) + { + log::warn!(target: LOG_TARGET, "MultiDisputesData failed to update: {:?}", e); + }; + METRICS.on_disputes_imported(checked_disputes_sets.len() as u64); + + set_scrapable_on_chain_disputes::(current_session, checked_disputes_sets.clone()); + + if T::DisputesHandler::is_frozen() { + // Relay chain freeze, at this point we will not include any parachain blocks. + METRICS.on_relay_chain_freeze(); + + let disputes = checked_disputes_sets + .into_iter() + .map(|checked| checked.into()) + .collect::>(); + let processed = ParachainsInherentData { + bitfields: Vec::new(), + backed_candidates: Vec::new(), + disputes, + parent_header, + }; + + // The relay chain we are currently on is invalid. Proceed no further on parachains. + return Ok((processed, Some(checked_disputes_sets_consumed_weight).into())) + } + + // Contains the disputes that are concluded in the current session only, + // since these are the only ones that are relevant for the occupied cores + // and lightens the load on `collect_disputed` significantly. + // Cores can't be occupied with candidates of the previous sessions, and only + // things with new votes can have just concluded. We only need to collect + // cores with disputes that conclude just now, because disputes that + // concluded longer ago have already had any corresponding cores cleaned up. + let current_concluded_invalid_disputes = checked_disputes_sets + .iter() + .map(AsRef::as_ref) + .filter(|dss| dss.session == current_session) + .map(|dss| (dss.session, dss.candidate_hash)) + .filter(|(session, candidate)| { + ::DisputesHandler::concluded_invalid(*session, *candidate) + }) + .map(|(_session, candidate)| candidate) + .collect::>(); + + let freed_disputed: BTreeMap = + >::collect_disputed(¤t_concluded_invalid_disputes) + .into_iter() + .map(|core| (core, FreedReason::Concluded)) + .collect(); + + // Create a bit index from the set of core indices where each index corresponds to + // a core index that was freed due to a dispute. + // + // I.e. 010100 would indicate, the candidates on Core 1 and 3 would be disputed. + let disputed_bitfield = create_disputed_bitfield(expected_bits, freed_disputed.keys()); + + if !freed_disputed.is_empty() { + >::update_claimqueue(freed_disputed.clone(), now); + } + + let bitfields = sanitize_bitfields::( + bitfields, + disputed_bitfield, + expected_bits, + parent_hash, + current_session, + &validator_public[..], + ); + METRICS.on_bitfields_processed(bitfields.len() as u64); + + // Process new availability bitfields, yielding any availability cores whose + // work has now concluded. + let freed_concluded = + >::update_pending_availability_and_get_freed_cores::<_>( + expected_bits, + &validator_public[..], + bitfields.clone(), + >::core_para, + ); + + // Inform the disputes module of all included candidates. + for (_, candidate_hash) in &freed_concluded { + T::DisputesHandler::note_included(current_session, *candidate_hash, now); + } + + METRICS.on_candidates_included(freed_concluded.len() as u64); + + let freed = collect_all_freed_cores::(freed_concluded.iter().cloned()); + + let scheduled = >::update_claimqueue(freed, now); + + METRICS.on_candidates_processed_total(backed_candidates.len() as u64); + + let backed_candidates = sanitize_backed_candidates::( + backed_candidates, + |candidate_idx: usize, + backed_candidate: &BackedCandidate<::Hash>| + -> bool { + let para_id = backed_candidate.descriptor().para_id; + let prev_context = >::para_most_recent_context(para_id); + let check_ctx = CandidateCheckContext::::new(prev_context); + + // never include a concluded-invalid candidate + current_concluded_invalid_disputes.contains(&backed_candidate.hash()) || + // Instead of checking the candidates with code upgrades twice + // move the checking up here and skip it in the training wheels fallback. + // That way we avoid possible duplicate checks while assuring all + // backed candidates fine to pass on. + // + // NOTE: this is the only place where we check the relay-parent. + check_ctx + .verify_backed_candidate(&allowed_relay_parents, candidate_idx, backed_candidate) + .is_err() + }, + &scheduled[..], + ); + + METRICS.on_candidates_sanitized(backed_candidates.len() as u64); + + // Process backed candidates according to scheduled cores. + let inclusion::ProcessedCandidates::< as HeaderT>::Hash> { + core_indices: occupied, + candidate_receipt_with_backing_validator_indices, + } = >::process_candidates( + &allowed_relay_parents, + backed_candidates.clone(), + scheduled, + >::group_validators, + )?; + // Note which of the scheduled cores were actually occupied by a backed candidate. + >::occupied(occupied.into_iter().map(|e| (e.0, e.1)).collect()); + + set_scrapable_on_chain_backings::( + current_session, + candidate_receipt_with_backing_validator_indices, + ); + + let disputes = checked_disputes_sets + .into_iter() + .map(|checked| checked.into()) + .collect::>(); + + let bitfields = bitfields.into_iter().map(|v| v.into_unchecked()).collect(); + + let processed = + ParachainsInherentData { bitfields, backed_candidates, disputes, parent_header }; + Ok((processed, Some(all_weight_after).into())) + } +} + +/// Derive a bitfield from dispute +pub(super) fn create_disputed_bitfield<'a, I>( + expected_bits: usize, + freed_cores: I, +) -> DisputedBitfield +where + I: 'a + IntoIterator, +{ + let mut bitvec = BitVec::repeat(false, expected_bits); + for core_idx in freed_cores { + let core_idx = core_idx.0 as usize; + if core_idx < expected_bits { + bitvec.set(core_idx, true); + } + } + DisputedBitfield::from(bitvec) +} + +/// Select a random subset, with preference for certain indices. +/// +/// Adds random items to the set until all candidates +/// are tried or the remaining weight is depleted. +/// +/// Returns the weight of all selected items from `selectables` +/// as well as their indices in ascending order. +fn random_sel Weight>( + rng: &mut rand_chacha::ChaChaRng, + selectables: &[X], + mut preferred_indices: Vec, + weight_fn: F, + weight_limit: Weight, +) -> (Weight, Vec) { + if selectables.is_empty() { + return (Weight::zero(), Vec::new()) + } + // all indices that are not part of the preferred set + let mut indices = (0..selectables.len()) + .into_iter() + .filter(|idx| !preferred_indices.contains(idx)) + .collect::>(); + let mut picked_indices = Vec::with_capacity(selectables.len().saturating_sub(1)); + + let mut weight_acc = Weight::zero(); + + preferred_indices.shuffle(rng); + for preferred_idx in preferred_indices { + // preferred indices originate from outside + if let Some(item) = selectables.get(preferred_idx) { + let updated = weight_acc.saturating_add(weight_fn(item)); + if updated.any_gt(weight_limit) { + continue + } + weight_acc = updated; + picked_indices.push(preferred_idx); + } + } + + indices.shuffle(rng); + for idx in indices { + let item = &selectables[idx]; + let updated = weight_acc.saturating_add(weight_fn(item)); + + if updated.any_gt(weight_limit) { + continue + } + weight_acc = updated; + + picked_indices.push(idx); + } + + // sorting indices, so the ordering is retained + // unstable sorting is fine, since there are no duplicates in indices + // and even if there were, they don't have an identity + picked_indices.sort_unstable(); + (weight_acc, picked_indices) +} + +/// Considers an upper threshold that the inherent data must not exceed. +/// +/// If there is sufficient space, all bitfields and all candidates +/// will be included. +/// +/// Otherwise tries to include all disputes, and then tries to fill the remaining space with +/// bitfields and then candidates. +/// +/// The selection process is random. For candidates, there is an exception for code upgrades as they +/// are preferred. And for disputes, local and older disputes are preferred (see +/// `limit_and_sanitize_disputes`). for backed candidates, since with a increasing number of +/// parachains their chances of inclusion become slim. All backed candidates are checked +/// beforehands in `fn create_inherent_inner` which guarantees sanity. +/// +/// Assumes disputes are already filtered by the time this is called. +/// +/// Returns the total weight consumed by `bitfields` and `candidates`. +fn apply_weight_limit( + candidates: &mut Vec::Hash>>, + bitfields: &mut UncheckedSignedAvailabilityBitfields, + max_consumable_weight: Weight, + rng: &mut rand_chacha::ChaChaRng, +) -> Weight { + let total_candidates_weight = backed_candidates_weight::(candidates.as_slice()); + + let total_bitfields_weight = signed_bitfields_weight::(&bitfields); + + let total = total_bitfields_weight.saturating_add(total_candidates_weight); + + // candidates + bitfields fit into the block + if max_consumable_weight.all_gte(total) { + return total + } + + // Prefer code upgrades, they tend to be large and hence stand no chance to be picked + // late while maintaining the weight bounds. + let preferred_indices = candidates + .iter() + .enumerate() + .filter_map(|(idx, candidate)| { + candidate.candidate.commitments.new_validation_code.as_ref().map(|_code| idx) + }) + .collect::>(); + + // There is weight remaining to be consumed by a subset of candidates + // which are going to be picked now. + if let Some(max_consumable_by_candidates) = + max_consumable_weight.checked_sub(&total_bitfields_weight) + { + let (acc_candidate_weight, indices) = + random_sel::::Hash>, _>( + rng, + &candidates, + preferred_indices, + |c| backed_candidate_weight::(c), + max_consumable_by_candidates, + ); + log::debug!(target: LOG_TARGET, "Indices Candidates: {:?}, size: {}", indices, candidates.len()); + candidates.indexed_retain(|idx, _backed_candidate| indices.binary_search(&idx).is_ok()); + // pick all bitfields, and + // fill the remaining space with candidates + let total_consumed = acc_candidate_weight.saturating_add(total_bitfields_weight); + + return total_consumed + } + + candidates.clear(); + + // insufficient space for even the bitfields alone, so only try to fit as many of those + // into the block and skip the candidates entirely + let (total_consumed, indices) = random_sel::( + rng, + &bitfields, + vec![], + |bitfield| signed_bitfield_weight::(&bitfield), + max_consumable_weight, + ); + log::debug!(target: LOG_TARGET, "Indices Bitfields: {:?}, size: {}", indices, bitfields.len()); + + bitfields.indexed_retain(|idx, _bitfield| indices.binary_search(&idx).is_ok()); + + total_consumed +} + +/// Filter bitfields based on freed core indices, validity, and other sanity checks. +/// +/// Do sanity checks on the bitfields: +/// +/// 1. no more than one bitfield per validator +/// 2. bitfields are ascending by validator index. +/// 3. each bitfield has exactly `expected_bits` +/// 4. signature is valid +/// 5. remove any disputed core indices +/// +/// If any of those is not passed, the bitfield is dropped. +pub(crate) fn sanitize_bitfields( + unchecked_bitfields: UncheckedSignedAvailabilityBitfields, + disputed_bitfield: DisputedBitfield, + expected_bits: usize, + parent_hash: T::Hash, + session_index: SessionIndex, + validators: &[ValidatorId], +) -> SignedAvailabilityBitfields { + let mut bitfields = Vec::with_capacity(unchecked_bitfields.len()); + + let mut last_index: Option = None; + + if disputed_bitfield.0.len() != expected_bits { + // This is a system logic error that should never occur, but we want to handle it gracefully + // so we just drop all bitfields + log::error!(target: LOG_TARGET, "BUG: disputed_bitfield != expected_bits"); + return vec![] + } + + let all_zeros = BitVec::::repeat(false, expected_bits); + let signing_context = SigningContext { parent_hash, session_index }; + for unchecked_bitfield in unchecked_bitfields { + // Find and skip invalid bitfields. + if unchecked_bitfield.unchecked_payload().0.len() != expected_bits { + log::trace!( + target: LOG_TARGET, + "bad bitfield length: {} != {:?}", + unchecked_bitfield.unchecked_payload().0.len(), + expected_bits, + ); + continue + } + + if unchecked_bitfield.unchecked_payload().0.clone() & disputed_bitfield.0.clone() != + all_zeros + { + log::trace!( + target: LOG_TARGET, + "bitfield contains disputed cores: {:?}", + unchecked_bitfield.unchecked_payload().0.clone() & disputed_bitfield.0.clone() + ); + continue + } + + let validator_index = unchecked_bitfield.unchecked_validator_index(); + + if !last_index.map_or(true, |last_index: ValidatorIndex| last_index < validator_index) { + log::trace!( + target: LOG_TARGET, + "bitfield validator index is not greater than last: !({:?} < {})", + last_index.as_ref().map(|x| x.0), + validator_index.0 + ); + continue + } + + if unchecked_bitfield.unchecked_validator_index().0 as usize >= validators.len() { + log::trace!( + target: LOG_TARGET, + "bitfield validator index is out of bounds: {} >= {}", + validator_index.0, + validators.len(), + ); + continue + } + + let validator_public = &validators[validator_index.0 as usize]; + + // Validate bitfield signature. + if let Ok(signed_bitfield) = + unchecked_bitfield.try_into_checked(&signing_context, validator_public) + { + bitfields.push(signed_bitfield); + METRICS.on_valid_bitfield_signature(); + } else { + log::warn!(target: LOG_TARGET, "Invalid bitfield signature"); + METRICS.on_invalid_bitfield_signature(); + }; + + last_index = Some(validator_index); + } + bitfields +} + +/// Filter out any candidates that have a concluded invalid dispute. +/// +/// `scheduled` follows the same naming scheme as provided in the +/// guide: Currently `free` but might become `occupied`. +/// For the filtering here the relevant part is only the current `free` +/// state. +/// +/// `candidate_has_concluded_invalid_dispute` must return `true` if the candidate +/// is disputed, false otherwise. The passed `usize` is the candidate index. +/// +/// The returned `Vec` is sorted according to the occupied core index. +fn sanitize_backed_candidates< + T: crate::inclusion::Config, + F: FnMut(usize, &BackedCandidate) -> bool, +>( + mut backed_candidates: Vec>, + mut candidate_has_concluded_invalid_dispute_or_is_invalid: F, + scheduled: &[CoreAssignment>], +) -> Vec> { + // Remove any candidates that were concluded invalid. + // This does not assume sorting. + backed_candidates.indexed_retain(move |candidate_idx, backed_candidate| { + !candidate_has_concluded_invalid_dispute_or_is_invalid(candidate_idx, backed_candidate) + }); + + let scheduled_paras_to_core_idx = scheduled + .into_iter() + .map(|core_assignment| (core_assignment.paras_entry.para_id(), core_assignment.core)) + .collect::>(); + + // Assure the backed candidate's `ParaId`'s core is free. + // This holds under the assumption that `Scheduler::schedule` is called _before_. + // We don't check the relay-parent because this is done in the closure when + // constructing the inherent and during actual processing otherwise. + + backed_candidates.retain(|backed_candidate| { + let desc = backed_candidate.descriptor(); + + scheduled_paras_to_core_idx.get(&desc.para_id).is_some() + }); + + // Sort the `Vec` last, once there is a guarantee that these + // `BackedCandidates` references the expected relay chain parent, + // but more importantly are scheduled for a free core. + // This both avoids extra work for obviously invalid candidates, + // but also allows this to be done in place. + backed_candidates.sort_by(|x, y| { + // Never panics, since we filtered all panic arguments out in the previous `fn retain`. + scheduled_paras_to_core_idx[&x.descriptor().para_id] + .cmp(&scheduled_paras_to_core_idx[&y.descriptor().para_id]) + }); + + backed_candidates +} + +/// Derive entropy from babe provided per block randomness. +/// +/// In the odd case none is available, uses the `parent_hash` and +/// a const value, while emitting a warning. +fn compute_entropy(parent_hash: T::Hash) -> [u8; 32] { + const CANDIDATE_SEED_SUBJECT: [u8; 32] = *b"candidate-seed-selection-subject"; + // NOTE: this is slightly gameable since this randomness was already public + // by the previous block, while for the block author this randomness was + // known 2 epochs ago. it is marginally better than using the parent block + // hash since it's harder to influence the VRF output than the block hash. + let vrf_random = ParentBlockRandomness::::random(&CANDIDATE_SEED_SUBJECT[..]).0; + let mut entropy: [u8; 32] = CANDIDATE_SEED_SUBJECT; + if let Some(vrf_random) = vrf_random { + entropy.as_mut().copy_from_slice(vrf_random.as_ref()); + } else { + // in case there is no VRF randomness present, we utilize the relay parent + // as seed, it's better than a static value. + log::warn!(target: LOG_TARGET, "ParentBlockRandomness did not provide entropy"); + entropy.as_mut().copy_from_slice(parent_hash.as_ref()); + } + entropy +} + +/// Limit disputes in place. +/// +/// Assumes ordering of disputes, retains sorting of the statement. +/// +/// Prime source of overload safety for dispute votes: +/// 1. Check accumulated weight does not exceed the maximum block weight. +/// 2. If exceeded: +/// 1. Check validity of all dispute statements sequentially +/// 2. If not exceeded: +/// 1. If weight is exceeded by locals, pick the older ones (lower indices) until the weight limit +/// is reached. +/// +/// Returns the consumed weight amount, that is guaranteed to be less than the provided +/// `max_consumable_weight`. +fn limit_and_sanitize_disputes< + T: Config, + CheckValidityFn: FnMut(DisputeStatementSet) -> Option, +>( + disputes: MultiDisputeStatementSet, + mut dispute_statement_set_valid: CheckValidityFn, + max_consumable_weight: Weight, +) -> (Vec, Weight) { + // The total weight if all disputes would be included + let disputes_weight = multi_dispute_statement_sets_weight::(&disputes); + + if disputes_weight.any_gt(max_consumable_weight) { + log::debug!(target: LOG_TARGET, "Above max consumable weight: {}/{}", disputes_weight, max_consumable_weight); + let mut checked_acc = Vec::::with_capacity(disputes.len()); + + // Accumualated weight of all disputes picked, that passed the checks. + let mut weight_acc = Weight::zero(); + + // Select disputes in-order until the remaining weight is attained + disputes.into_iter().for_each(|dss| { + let dispute_weight = dispute_statement_set_weight::(&dss); + let updated = weight_acc.saturating_add(dispute_weight); + if max_consumable_weight.all_gte(updated) { + // Always apply the weight. Invalid data cost processing time too: + weight_acc = updated; + if let Some(checked) = dispute_statement_set_valid(dss) { + checked_acc.push(checked); + } + } + }); + + (checked_acc, weight_acc) + } else { + // Go through all of them, and just apply the filter, they would all fit + let checked = disputes + .into_iter() + .filter_map(|dss| dispute_statement_set_valid(dss)) + .collect::>(); + // some might have been filtered out, so re-calc the weight + let checked_disputes_weight = checked_multi_dispute_statement_sets_weight::(&checked); + (checked, checked_disputes_weight) + } +} diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..1e5271909664d2bb98752b102cfef57532444bce --- /dev/null +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -0,0 +1,1337 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +// In order to facilitate benchmarks as tests we have a benchmark feature gated `WeightInfo` impl +// that uses 0 for all the weights. Because all the weights are 0, the tests that rely on +// weights for limiting data will fail, so we don't run them when using the benchmark feature. +#[cfg(not(feature = "runtime-benchmarks"))] +mod enter { + + use super::*; + use crate::{ + builder::{Bench, BenchBuilder}, + mock::{new_test_ext, BlockLength, BlockWeights, MockGenesisConfig, Test}, + }; + use assert_matches::assert_matches; + use frame_support::assert_ok; + use frame_system::limits; + use sp_runtime::Perbill; + use sp_std::collections::btree_map::BTreeMap; + + struct TestConfig { + dispute_statements: BTreeMap, + dispute_sessions: Vec, + backed_and_concluding: BTreeMap, + num_validators_per_core: u32, + code_upgrade: Option, + } + + fn make_inherent_data( + TestConfig { + dispute_statements, + dispute_sessions, + backed_and_concluding, + num_validators_per_core, + code_upgrade, + }: TestConfig, + ) -> Bench { + let builder = BenchBuilder::::new() + .set_max_validators( + (dispute_sessions.len() + backed_and_concluding.len()) as u32 * + num_validators_per_core, + ) + .set_max_validators_per_core(num_validators_per_core) + .set_dispute_statements(dispute_statements) + .set_backed_and_concluding_cores(backed_and_concluding) + .set_dispute_sessions(&dispute_sessions[..]); + + if let Some(code_size) = code_upgrade { + builder.set_code_upgrade(code_size).build() + } else { + builder.build() + } + } + + #[test] + // Validate that if we create 2 backed candidates which are assigned to 2 cores that will be + // freed via becoming fully available, the backed candidates will not be filtered out in + // `create_inherent` and will not cause `enter` to early. + fn include_backed_candidates() { + let config = MockGenesisConfig::default(); + assert!(config.configuration.config.scheduling_lookahead > 0); + + new_test_ext(config).execute_with(|| { + let dispute_statements = BTreeMap::new(); + + let mut backed_and_concluding = BTreeMap::new(); + backed_and_concluding.insert(0, 1); + backed_and_concluding.insert(1, 1); + + let scenario = make_inherent_data(TestConfig { + dispute_statements, + dispute_sessions: vec![], // No disputes + backed_and_concluding, + num_validators_per_core: 1, + code_upgrade: None, + }); + + // We expect the scenario to have cores 0 & 1 with pending availability. The backed + // candidates are also created for cores 0 & 1, so once the pending available + // become fully available those cores are marked as free and scheduled for the backed + // candidates. + let expected_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (2 validators) + assert_eq!(expected_para_inherent_data.bitfields.len(), 2); + // * 1 backed candidate per core (2 cores) + assert_eq!(expected_para_inherent_data.backed_candidates.len(), 2); + // * 0 disputes. + assert_eq!(expected_para_inherent_data.disputes.len(), 0); + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + + // The current schedule is empty prior to calling `create_inherent_enter`. + assert!(>::claimqueue_is_empty()); + + // Nothing is filtered out (including the backed candidates.) + assert_eq!( + Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(), + expected_para_inherent_data + ); + + assert_eq!( + // The length of this vec is equal to the number of candidates, so we know our 2 + // backed candidates did not get filtered out + Pallet::::on_chain_votes().unwrap().backing_validators_per_candidate.len(), + 2 + ); + + assert_eq!( + // The session of the on chain votes should equal the current session, which is 2 + Pallet::::on_chain_votes().unwrap().session, + 2 + ); + }); + } + + #[test] + fn test_session_is_tracked_in_on_chain_scraping() { + use crate::disputes::run_to_block; + use primitives::{ + DisputeStatement, DisputeStatementSet, ExplicitDisputeStatement, + InvalidDisputeStatementKind, ValidDisputeStatementKind, + }; + use sp_core::{crypto::CryptoType, Pair}; + + new_test_ext(Default::default()).execute_with(|| { + let v0 = ::Pair::generate().0; + let v1 = ::Pair::generate().0; + + run_to_block(6, |b| { + // a new session at each block + Some(( + true, + b, + vec![(&0, v0.public()), (&1, v1.public())], + Some(vec![(&0, v0.public()), (&1, v1.public())]), + )) + }); + + let generate_votes = |session: u32, candidate_hash: CandidateHash| { + // v0 votes for 3 + vec![DisputeStatementSet { + candidate_hash, + session, + statements: vec![ + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v1.sign( + &ExplicitDisputeStatement { valid: false, candidate_hash, session } + .signing_payload(), + ), + ), + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v1.sign( + &ExplicitDisputeStatement { valid: true, candidate_hash, session } + .signing_payload(), + ), + ), + ], + }] + .into_iter() + .map(CheckedDisputeStatementSet::unchecked_from_unchecked) + .collect::>() + }; + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); + let statements = generate_votes(3, candidate_hash); + set_scrapable_on_chain_disputes::(3, statements); + assert_matches!(pallet::Pallet::::on_chain_votes(), Some(ScrapedOnChainVotes { + session, + .. + } ) => { + assert_eq!(session, 3); + }); + run_to_block(7, |b| { + // a new session at each block + Some(( + true, + b, + vec![(&0, v0.public()), (&1, v1.public())], + Some(vec![(&0, v0.public()), (&1, v1.public())]), + )) + }); + + let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(2)); + let statements = generate_votes(7, candidate_hash); + set_scrapable_on_chain_disputes::(7, statements); + assert_matches!(pallet::Pallet::::on_chain_votes(), Some(ScrapedOnChainVotes { + session, + .. + } ) => { + assert_eq!(session, 7); + }); + }); + } + + #[test] + // Ensure that disputes are filtered out if the session is in the future. + fn filter_multi_dispute_data() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + // Create the inherent data for this block + let dispute_statements = BTreeMap::new(); + + let backed_and_concluding = BTreeMap::new(); + + let scenario = make_inherent_data(TestConfig { + dispute_statements, + dispute_sessions: vec![1, 2, 3 /* Session 3 too new, will get filtered out */], + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + }); + + let expected_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 3 disputes => 3 cores, 15 + // validators) + assert_eq!(expected_para_inherent_data.bitfields.len(), 15); + // * 0 backed candidate per core + assert_eq!(expected_para_inherent_data.backed_candidates.len(), 0); + // * 3 disputes. + assert_eq!(expected_para_inherent_data.disputes.len(), 3); + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + + // The current schedule is empty prior to calling `create_inherent_enter`. + assert!(>::claimqueue_is_empty()); + + let multi_dispute_inherent_data = + Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(); + // Dispute for session that lies too far in the future should be filtered out + assert!(multi_dispute_inherent_data != expected_para_inherent_data); + + assert_eq!(multi_dispute_inherent_data.disputes.len(), 2); + + // Assert that the first 2 disputes are included + assert_eq!( + &multi_dispute_inherent_data.disputes[..2], + &expected_para_inherent_data.disputes[..2], + ); + + assert_ok!(Pallet::::enter( + frame_system::RawOrigin::None.into(), + multi_dispute_inherent_data, + )); + + assert_eq!( + // The length of this vec is equal to the number of candidates, so we know there + // where no backed candidates included + Pallet::::on_chain_votes().unwrap().backing_validators_per_candidate.len(), + 0 + ); + + assert_eq!( + // The session of the on chain votes should equal the current session, which is 2 + Pallet::::on_chain_votes().unwrap().session, + 2 + ); + }); + } + + #[test] + // Ensure that when dispute data establishes an over weight block that we adequately + // filter out disputes according to our prioritization rule + fn limit_dispute_data() { + sp_tracing::try_init_simple(); + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + // Create the inherent data for this block + let dispute_statements = BTreeMap::new(); + // No backed and concluding cores, so all cores will be filled with disputes. + let backed_and_concluding = BTreeMap::new(); + + let scenario = make_inherent_data(TestConfig { + dispute_statements, + dispute_sessions: vec![2, 2, 1], // 3 cores with disputes + backed_and_concluding, + num_validators_per_core: 6, + code_upgrade: None, + }); + + let expected_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (6 validators per core, 3 disputes => 18 validators) + assert_eq!(expected_para_inherent_data.bitfields.len(), 18); + // * 0 backed candidate per core + assert_eq!(expected_para_inherent_data.backed_candidates.len(), 0); + // * 3 disputes. + assert_eq!(expected_para_inherent_data.disputes.len(), 3); + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + + // The current schedule is empty prior to calling `create_inherent_enter`. + assert!(>::claimqueue_is_empty()); + + let limit_inherent_data = + Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(); + // Expect that inherent data is filtered to include only 2 disputes + assert!(limit_inherent_data != expected_para_inherent_data); + + // Ensure that the included disputes are sorted by session + assert_eq!(limit_inherent_data.disputes.len(), 2); + assert_eq!(limit_inherent_data.disputes[0].session, 1); + assert_eq!(limit_inherent_data.disputes[1].session, 2); + + assert_ok!(Pallet::::enter( + frame_system::RawOrigin::None.into(), + limit_inherent_data, + )); + + assert_eq!( + // Ensure that our inherent data did not included backed candidates as expected + Pallet::::on_chain_votes().unwrap().backing_validators_per_candidate.len(), + 0 + ); + + assert_eq!( + // The session of the on chain votes should equal the current session, which is 2 + Pallet::::on_chain_votes().unwrap().session, + 2 + ); + }); + } + + #[test] + // Ensure that when a block is over weight due to disputes, but there is still sufficient + // block weight to include a number of signed bitfields, the inherent data is filtered + // as expected + fn limit_dispute_data_ignore_backed_candidates() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + // Create the inherent data for this block + let dispute_statements = BTreeMap::new(); + + let mut backed_and_concluding = BTreeMap::new(); + // 2 backed candidates shall be scheduled + backed_and_concluding.insert(0, 2); + backed_and_concluding.insert(1, 2); + + let scenario = make_inherent_data(TestConfig { + dispute_statements, + dispute_sessions: vec![2, 2, 1], // 3 cores with disputes + backed_and_concluding, + num_validators_per_core: 4, + code_upgrade: None, + }); + + let expected_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (4 validators per core, 2 backed candidates, 3 disputes => + // 4*5 = 20) + assert_eq!(expected_para_inherent_data.bitfields.len(), 20); + // * 2 backed candidates + assert_eq!(expected_para_inherent_data.backed_candidates.len(), 2); + // * 3 disputes. + assert_eq!(expected_para_inherent_data.disputes.len(), 3); + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + + // The current schedule is empty prior to calling `create_inherent_enter`. + assert!(>::claimqueue_is_empty()); + + // Nothing is filtered out (including the backed candidates.) + let limit_inherent_data = + Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(); + assert!(limit_inherent_data != expected_para_inherent_data); + + // Three disputes is over weight (see previous test), so we expect to only see 2 + // disputes + assert_eq!(limit_inherent_data.disputes.len(), 2); + // Ensure disputes are filtered as expected + assert_eq!(limit_inherent_data.disputes[0].session, 1); + assert_eq!(limit_inherent_data.disputes[1].session, 2); + // Ensure all bitfields are included as these are still not over weight + assert_eq!( + limit_inherent_data.bitfields.len(), + expected_para_inherent_data.bitfields.len() + ); + // Ensure that all backed candidates are filtered out as either would make the block + // over weight + assert_eq!(limit_inherent_data.backed_candidates.len(), 0); + + assert_ok!(Pallet::::enter( + frame_system::RawOrigin::None.into(), + limit_inherent_data, + )); + + assert_eq!( + // The length of this vec is equal to the number of candidates, so we know + // all of our candidates got filtered out + Pallet::::on_chain_votes().unwrap().backing_validators_per_candidate.len(), + 0, + ); + + assert_eq!( + // The session of the on chain votes should equal the current session, which is 2 + Pallet::::on_chain_votes().unwrap().session, + 2 + ); + }); + } + + #[test] + // Ensure an overweight block with an excess amount of disputes and bitfields, the bitfields are + // filtered to accommodate the block size and no backed candidates are included. + fn limit_bitfields_some() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + // Create the inherent data for this block + let mut dispute_statements = BTreeMap::new(); + // Cap the number of statements per dispute to 20 in order to ensure we have enough + // space in the block for some (but not all) bitfields + dispute_statements.insert(2, 20); + dispute_statements.insert(3, 20); + dispute_statements.insert(4, 20); + + let mut backed_and_concluding = BTreeMap::new(); + // Schedule 2 backed candidates + backed_and_concluding.insert(0, 2); + backed_and_concluding.insert(1, 2); + + let scenario = make_inherent_data(TestConfig { + dispute_statements, + dispute_sessions: vec![2, 2, 1], // 3 cores with disputes + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + }); + + let expected_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 2 backed candidates, 3 disputes => + // 4*5 = 20), + assert_eq!(expected_para_inherent_data.bitfields.len(), 25); + // * 2 backed candidates, + assert_eq!(expected_para_inherent_data.backed_candidates.len(), 2); + // * 3 disputes. + assert_eq!(expected_para_inherent_data.disputes.len(), 3); + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + + // The current schedule is empty prior to calling `create_inherent_enter`. + assert!(>::claimqueue_is_empty()); + + // Nothing is filtered out (including the backed candidates.) + let limit_inherent_data = + Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(); + assert_ne!(limit_inherent_data, expected_para_inherent_data); + assert!(inherent_data_weight(&limit_inherent_data) + .all_lte(inherent_data_weight(&expected_para_inherent_data))); + assert!(inherent_data_weight(&limit_inherent_data) + .all_lte(max_block_weight_proof_size_adjusted())); + + // Three disputes is over weight (see previous test), so we expect to only see 2 + // disputes + assert_eq!(limit_inherent_data.disputes.len(), 2); + // Ensure disputes are filtered as expected + assert_eq!(limit_inherent_data.disputes[0].session, 1); + assert_eq!(limit_inherent_data.disputes[1].session, 2); + // Ensure all bitfields are included as these are still not over weight + assert_eq!(limit_inherent_data.bitfields.len(), 20,); + // Ensure that all backed candidates are filtered out as either would make the block + // over weight + assert_eq!(limit_inherent_data.backed_candidates.len(), 0); + + assert_ok!(Pallet::::enter( + frame_system::RawOrigin::None.into(), + limit_inherent_data, + )); + + assert_eq!( + // The length of this vec is equal to the number of candidates, so we know + // all of our candidates got filtered out + Pallet::::on_chain_votes().unwrap().backing_validators_per_candidate.len(), + 0, + ); + + assert_eq!( + // The session of the on chain votes should equal the current session, which is 2 + Pallet::::on_chain_votes().unwrap().session, + 2 + ); + }); + } + + #[test] + // Ensure that when a block is over weight due to disputes and bitfields, we filter. + fn limit_bitfields_overweight() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + // Create the inherent data for this block + let mut dispute_statements = BTreeMap::new(); + // Control the number of statements per dispute to ensure we have enough space + // in the block for some (but not all) bitfields + dispute_statements.insert(2, 20); + dispute_statements.insert(3, 20); + dispute_statements.insert(4, 20); + + let mut backed_and_concluding = BTreeMap::new(); + // 2 backed candidates shall be scheduled + backed_and_concluding.insert(0, 2); + backed_and_concluding.insert(1, 2); + + let scenario = make_inherent_data(TestConfig { + dispute_statements, + dispute_sessions: vec![2, 2, 1], // 3 cores with disputes + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + }); + + let expected_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 2 backed candidates, 3 disputes => + // 5*5 = 25) + assert_eq!(expected_para_inherent_data.bitfields.len(), 25); + // * 2 backed candidates + assert_eq!(expected_para_inherent_data.backed_candidates.len(), 2); + // * 3 disputes. + assert_eq!(expected_para_inherent_data.disputes.len(), 3); + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + + let limit_inherent_data = + Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(); + assert_eq!(limit_inherent_data.bitfields.len(), 20); + assert_eq!(limit_inherent_data.disputes.len(), 2); + assert_eq!(limit_inherent_data.backed_candidates.len(), 0); + }); + } + + fn max_block_weight_proof_size_adjusted() -> Weight { + let raw_weight = ::BlockWeights::get().max_block; + let block_length = ::BlockLength::get(); + raw_weight.set_proof_size(*block_length.max.get(DispatchClass::Mandatory) as u64) + } + + fn inherent_data_weight(inherent_data: &ParachainsInherentData) -> Weight { + use thousands::Separable; + + let multi_dispute_statement_sets_weight = + multi_dispute_statement_sets_weight::(&inherent_data.disputes); + let signed_bitfields_weight = signed_bitfields_weight::(&inherent_data.bitfields); + let backed_candidates_weight = + backed_candidates_weight::(&inherent_data.backed_candidates); + + let sum = multi_dispute_statement_sets_weight + + signed_bitfields_weight + + backed_candidates_weight; + + println!( + "disputes({})={} + bitfields({})={} + candidates({})={} -> {}", + inherent_data.disputes.len(), + multi_dispute_statement_sets_weight.separate_with_underscores(), + inherent_data.bitfields.len(), + signed_bitfields_weight.separate_with_underscores(), + inherent_data.backed_candidates.len(), + backed_candidates_weight.separate_with_underscores(), + sum.separate_with_underscores() + ); + sum + } + + // Ensure that when a block is over weight due to disputes and bitfields, we filter. + #[test] + fn limit_candidates_over_weight_1() { + let config = MockGenesisConfig::default(); + assert!(config.configuration.config.scheduling_lookahead > 0); + + new_test_ext(config).execute_with(|| { + // Create the inherent data for this block + let mut dispute_statements = BTreeMap::new(); + // Control the number of statements per dispute to ensure we have enough space + // in the block for some (but not all) bitfields + dispute_statements.insert(2, 17); + dispute_statements.insert(3, 17); + dispute_statements.insert(4, 17); + + let mut backed_and_concluding = BTreeMap::new(); + // 2 backed candidates shall be scheduled + backed_and_concluding.insert(0, 16); + backed_and_concluding.insert(1, 25); + + let scenario = make_inherent_data(TestConfig { + dispute_statements, + dispute_sessions: vec![2, 2, 1], // 3 cores with disputes + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + }); + + let expected_para_inherent_data = scenario.data.clone(); + assert!(max_block_weight_proof_size_adjusted() + .any_lt(inherent_data_weight(&expected_para_inherent_data))); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 2 backed candidates, 3 disputes => + // 5*5 = 25) + assert_eq!(expected_para_inherent_data.bitfields.len(), 25); + // * 2 backed candidates + assert_eq!(expected_para_inherent_data.backed_candidates.len(), 2); + // * 3 disputes. + assert_eq!(expected_para_inherent_data.disputes.len(), 3); + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + + let limit_inherent_data = + Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(); + // Expect that inherent data is filtered to include only 1 backed candidate and 2 + // disputes + assert!(limit_inherent_data != expected_para_inherent_data); + assert!( + max_block_weight_proof_size_adjusted() + .all_gte(inherent_data_weight(&limit_inherent_data)), + "Post limiting exceeded block weight: max={} vs. inherent={}", + max_block_weight_proof_size_adjusted(), + inherent_data_weight(&limit_inherent_data) + ); + + // * 1 bitfields + assert_eq!(limit_inherent_data.bitfields.len(), 25); + // * 2 backed candidates + assert_eq!(limit_inherent_data.backed_candidates.len(), 1); + // * 3 disputes. + assert_eq!(limit_inherent_data.disputes.len(), 2); + + assert_ok!(Pallet::::enter( + frame_system::RawOrigin::None.into(), + limit_inherent_data, + )); + + // TODO [now]: this assertion fails with async backing runtime. + assert_eq!( + // The length of this vec is equal to the number of candidates, so we know our 2 + // backed candidates did not get filtered out + Pallet::::on_chain_votes().unwrap().backing_validators_per_candidate.len(), + 1 + ); + + assert_eq!( + // The session of the on chain votes should equal the current session, which is 2 + Pallet::::on_chain_votes().unwrap().session, + 2 + ); + }); + } + + #[test] + fn disputes_are_size_limited() { + BlockLength::set(limits::BlockLength::max_with_normal_ratio( + 600, + Perbill::from_percent(75), + )); + // Virtually no time based limit: + BlockWeights::set(frame_system::limits::BlockWeights::simple_max(Weight::from_parts( + u64::MAX, + u64::MAX, + ))); + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + // Create the inherent data for this block + let mut dispute_statements = BTreeMap::new(); + dispute_statements.insert(2, 7); + dispute_statements.insert(3, 7); + dispute_statements.insert(4, 7); + + let backed_and_concluding = BTreeMap::new(); + + let scenario = make_inherent_data(TestConfig { + dispute_statements, + dispute_sessions: vec![2, 2, 1], // 3 cores with disputes + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + }); + + let expected_para_inherent_data = scenario.data.clone(); + assert!(max_block_weight_proof_size_adjusted() + .any_lt(inherent_data_weight(&expected_para_inherent_data))); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 3 disputes => 3*5 = 15) + assert_eq!(expected_para_inherent_data.bitfields.len(), 15); + // * 2 backed candidates + assert_eq!(expected_para_inherent_data.backed_candidates.len(), 0); + // * 3 disputes. + assert_eq!(expected_para_inherent_data.disputes.len(), 3); + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + let limit_inherent_data = + Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(); + // Expect that inherent data is filtered to include only 1 backed candidate and 2 + // disputes + assert!(limit_inherent_data != expected_para_inherent_data); + assert!( + max_block_weight_proof_size_adjusted() + .all_gte(inherent_data_weight(&limit_inherent_data)), + "Post limiting exceeded block weight: max={} vs. inherent={}", + max_block_weight_proof_size_adjusted(), + inherent_data_weight(&limit_inherent_data) + ); + + // * 1 bitfields - gone + assert_eq!(limit_inherent_data.bitfields.len(), 0); + // * 2 backed candidates - still none. + assert_eq!(limit_inherent_data.backed_candidates.len(), 0); + // * 3 disputes - filtered. + assert_eq!(limit_inherent_data.disputes.len(), 1); + }); + } + + #[test] + fn bitfields_are_size_limited() { + BlockLength::set(limits::BlockLength::max_with_normal_ratio( + 600, + Perbill::from_percent(75), + )); + // Virtually no time based limit: + BlockWeights::set(frame_system::limits::BlockWeights::simple_max(Weight::from_parts( + u64::MAX, + u64::MAX, + ))); + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + // Create the inherent data for this block + let dispute_statements = BTreeMap::new(); + + let mut backed_and_concluding = BTreeMap::new(); + // 2 backed candidates shall be scheduled + backed_and_concluding.insert(0, 2); + backed_and_concluding.insert(1, 2); + + let scenario = make_inherent_data(TestConfig { + dispute_statements, + dispute_sessions: Vec::new(), + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + }); + + let expected_para_inherent_data = scenario.data.clone(); + assert!(max_block_weight_proof_size_adjusted() + .any_lt(inherent_data_weight(&expected_para_inherent_data))); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 2 backed candidates => 2*5 = 10) + assert_eq!(expected_para_inherent_data.bitfields.len(), 10); + // * 2 backed candidates + assert_eq!(expected_para_inherent_data.backed_candidates.len(), 2); + // * 3 disputes. + assert_eq!(expected_para_inherent_data.disputes.len(), 0); + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + + let limit_inherent_data = + Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(); + // Expect that inherent data is filtered to include only 1 backed candidate and 2 + // disputes + assert!(limit_inherent_data != expected_para_inherent_data); + assert!( + max_block_weight_proof_size_adjusted() + .all_gte(inherent_data_weight(&limit_inherent_data)), + "Post limiting exceeded block weight: max={} vs. inherent={}", + max_block_weight_proof_size_adjusted(), + inherent_data_weight(&limit_inherent_data) + ); + + // * 1 bitfields have been filtered + assert_eq!(limit_inherent_data.bitfields.len(), 8); + // * 2 backed candidates have been filtered as well (not even space for bitfields) + assert_eq!(limit_inherent_data.backed_candidates.len(), 0); + // * 3 disputes. Still none. + assert_eq!(limit_inherent_data.disputes.len(), 0); + }); + } + + #[test] + fn candidates_are_size_limited() { + BlockLength::set(limits::BlockLength::max_with_normal_ratio( + 1_300, + Perbill::from_percent(75), + )); + // Virtually no time based limit: + BlockWeights::set(frame_system::limits::BlockWeights::simple_max(Weight::from_parts( + u64::MAX, + u64::MAX, + ))); + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let mut backed_and_concluding = BTreeMap::new(); + // 2 backed candidates shall be scheduled + backed_and_concluding.insert(0, 2); + backed_and_concluding.insert(1, 2); + + let scenario = make_inherent_data(TestConfig { + dispute_statements: BTreeMap::new(), + dispute_sessions: Vec::new(), + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + }); + + let expected_para_inherent_data = scenario.data.clone(); + assert!(max_block_weight_proof_size_adjusted() + .any_lt(inherent_data_weight(&expected_para_inherent_data))); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 2 backed candidates, 0 disputes => + // 2*5 = 10) + assert_eq!(expected_para_inherent_data.bitfields.len(), 10); + // * 2 backed candidates + assert_eq!(expected_para_inherent_data.backed_candidates.len(), 2); + // * 0 disputes. + assert_eq!(expected_para_inherent_data.disputes.len(), 0); + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + + let limit_inherent_data = + Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(); + // Expect that inherent data is filtered to include only 1 backed candidate and 2 + // disputes + assert!(limit_inherent_data != expected_para_inherent_data); + assert!( + max_block_weight_proof_size_adjusted() + .all_gte(inherent_data_weight(&limit_inherent_data)), + "Post limiting exceeded block weight: max={} vs. inherent={}", + max_block_weight_proof_size_adjusted(), + inherent_data_weight(&limit_inherent_data) + ); + + // * 1 bitfields - no filtering here + assert_eq!(limit_inherent_data.bitfields.len(), 10); + // * 2 backed candidates + assert_eq!(limit_inherent_data.backed_candidates.len(), 1); + // * 0 disputes. + assert_eq!(limit_inherent_data.disputes.len(), 0); + }); + } + + // Ensure that overweight parachain inherents are always rejected by the runtime. + // Runtime should panic and return `InherentOverweight` error. + #[test] + fn inherent_create_weight_invariant() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + // Create an overweight inherent and oversized block + let mut dispute_statements = BTreeMap::new(); + dispute_statements.insert(2, 100); + dispute_statements.insert(3, 200); + dispute_statements.insert(4, 300); + + let mut backed_and_concluding = BTreeMap::new(); + + for i in 0..30 { + backed_and_concluding.insert(i, i); + } + + let scenario = make_inherent_data(TestConfig { + dispute_statements, + dispute_sessions: vec![2, 2, 1], // 3 cores with disputes + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + }); + + let expected_para_inherent_data = scenario.data.clone(); + assert!(max_block_weight_proof_size_adjusted() + .any_lt(inherent_data_weight(&expected_para_inherent_data))); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 30 backed candidates, 3 disputes + // => 5*33 = 165) + assert_eq!(expected_para_inherent_data.bitfields.len(), 165); + // * 30 backed candidates + assert_eq!(expected_para_inherent_data.backed_candidates.len(), 30); + // * 3 disputes. + assert_eq!(expected_para_inherent_data.disputes.len(), 3); + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) + .unwrap(); + let dispatch_error = Pallet::::enter( + frame_system::RawOrigin::None.into(), + expected_para_inherent_data, + ) + .unwrap_err() + .error; + + assert_eq!(dispatch_error, Error::::InherentOverweight.into()); + }); + } +} + +fn default_header() -> primitives::Header { + primitives::Header { + parent_hash: Default::default(), + number: 0, + state_root: Default::default(), + extrinsics_root: Default::default(), + digest: Default::default(), + } +} + +mod sanitizers { + use super::*; + + use crate::inclusion::tests::{ + back_candidate, collator_sign_candidate, BackingKind, TestCandidateBuilder, + }; + use bitvec::order::Lsb0; + use primitives::{ + AvailabilityBitfield, GroupIndex, Hash, Id as ParaId, SignedAvailabilityBitfield, + ValidatorIndex, + }; + use sp_core::crypto::UncheckedFrom; + + use crate::mock::Test; + use keyring::Sr25519Keyring; + use primitives::{ + v5::{Assignment, ParasEntry}, + PARACHAIN_KEY_TYPE_ID, + }; + use sc_keystore::LocalKeystore; + use sp_keystore::{Keystore, KeystorePtr}; + use std::sync::Arc; + + fn validator_pubkeys(val_ids: &[keyring::Sr25519Keyring]) -> Vec { + val_ids.iter().map(|v| v.public().into()).collect() + } + + #[test] + fn bitfields() { + let header = default_header(); + let parent_hash = header.hash(); + // 2 cores means two bits + let expected_bits = 2; + let session_index = SessionIndex::from(0_u32); + + let crypto_store = LocalKeystore::in_memory(); + let crypto_store = Arc::new(crypto_store) as KeystorePtr; + let signing_context = SigningContext { parent_hash, session_index }; + + let validators = vec![ + keyring::Sr25519Keyring::Alice, + keyring::Sr25519Keyring::Bob, + keyring::Sr25519Keyring::Charlie, + keyring::Sr25519Keyring::Dave, + ]; + for validator in validators.iter() { + Keystore::sr25519_generate_new( + &*crypto_store, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); + } + let validator_public = validator_pubkeys(&validators); + + let checked_bitfields = [ + BitVec::::repeat(true, expected_bits), + BitVec::::repeat(true, expected_bits), + { + let mut bv = BitVec::::repeat(false, expected_bits); + bv.set(expected_bits - 1, true); + bv + }, + ] + .iter() + .enumerate() + .map(|(vi, ab)| { + let validator_index = ValidatorIndex::from(vi as u32); + SignedAvailabilityBitfield::sign( + &crypto_store, + AvailabilityBitfield::from(ab.clone()), + &signing_context, + validator_index, + &validator_public[vi], + ) + .unwrap() + .unwrap() + }) + .collect::>(); + + let unchecked_bitfields = checked_bitfields + .iter() + .cloned() + .map(|v| v.into_unchecked()) + .collect::>(); + + let disputed_bitfield = DisputedBitfield::zeros(expected_bits); + + { + assert_eq!( + sanitize_bitfields::( + unchecked_bitfields.clone(), + disputed_bitfield.clone(), + expected_bits, + parent_hash, + session_index, + &validator_public[..], + ), + checked_bitfields.clone() + ); + assert_eq!( + sanitize_bitfields::( + unchecked_bitfields.clone(), + disputed_bitfield.clone(), + expected_bits, + parent_hash, + session_index, + &validator_public[..], + ), + checked_bitfields.clone() + ); + } + + // disputed bitfield is non-zero + { + let mut disputed_bitfield = DisputedBitfield::zeros(expected_bits); + // pretend the first core was freed by either a malicious validator + // or by resolved dispute + disputed_bitfield.0.set(0, true); + + assert_eq!( + sanitize_bitfields::( + unchecked_bitfields.clone(), + disputed_bitfield.clone(), + expected_bits, + parent_hash, + session_index, + &validator_public[..], + ) + .len(), + 1 + ); + assert_eq!( + sanitize_bitfields::( + unchecked_bitfields.clone(), + disputed_bitfield.clone(), + expected_bits, + parent_hash, + session_index, + &validator_public[..], + ) + .len(), + 1 + ); + } + + // bitfield size mismatch + { + assert!(sanitize_bitfields::( + unchecked_bitfields.clone(), + disputed_bitfield.clone(), + expected_bits + 1, + parent_hash, + session_index, + &validator_public[..], + ) + .is_empty()); + assert!(sanitize_bitfields::( + unchecked_bitfields.clone(), + disputed_bitfield.clone(), + expected_bits + 1, + parent_hash, + session_index, + &validator_public[..], + ) + .is_empty()); + } + + // remove the last validator + { + let shortened = validator_public.len() - 2; + assert_eq!( + &sanitize_bitfields::( + unchecked_bitfields.clone(), + disputed_bitfield.clone(), + expected_bits, + parent_hash, + session_index, + &validator_public[..shortened], + )[..], + &checked_bitfields[..shortened] + ); + assert_eq!( + &sanitize_bitfields::( + unchecked_bitfields.clone(), + disputed_bitfield.clone(), + expected_bits, + parent_hash, + session_index, + &validator_public[..shortened], + )[..], + &checked_bitfields[..shortened] + ); + } + + // switch ordering of bitfields + { + let mut unchecked_bitfields = unchecked_bitfields.clone(); + let x = unchecked_bitfields.swap_remove(0); + unchecked_bitfields.push(x); + let result: UncheckedSignedAvailabilityBitfields = sanitize_bitfields::( + unchecked_bitfields.clone(), + disputed_bitfield.clone(), + expected_bits, + parent_hash, + session_index, + &validator_public[..], + ) + .into_iter() + .map(|v| v.into_unchecked()) + .collect(); + assert_eq!(&result, &unchecked_bitfields[..(unchecked_bitfields.len() - 2)]); + } + + // check the validators signature + { + let mut unchecked_bitfields = unchecked_bitfields.clone(); + + // insert a bad signature for the last bitfield + let last_bit_idx = unchecked_bitfields.len() - 1; + unchecked_bitfields + .get_mut(last_bit_idx) + .and_then(|u| Some(u.set_signature(UncheckedFrom::unchecked_from([1u8; 64])))) + .expect("we are accessing a valid index"); + assert_eq!( + &sanitize_bitfields::( + unchecked_bitfields.clone(), + disputed_bitfield.clone(), + expected_bits, + parent_hash, + session_index, + &validator_public[..], + )[..], + &checked_bitfields[..last_bit_idx] + ); + } + // duplicate bitfields + { + let mut unchecked_bitfields = unchecked_bitfields.clone(); + + // insert a bad signature for the last bitfield + let last_bit_idx = unchecked_bitfields.len() - 1; + unchecked_bitfields + .get_mut(last_bit_idx) + .and_then(|u| Some(u.set_signature(UncheckedFrom::unchecked_from([1u8; 64])))) + .expect("we are accessing a valid index"); + assert_eq!( + &sanitize_bitfields::( + unchecked_bitfields.clone().into_iter().chain(unchecked_bitfields).collect(), + disputed_bitfield.clone(), + expected_bits, + parent_hash, + session_index, + &validator_public[..], + )[..], + &checked_bitfields[..last_bit_idx] + ); + } + } + + #[test] + fn candidates() { + const RELAY_PARENT_NUM: u32 = 3; + + let header = default_header(); + let relay_parent = header.hash(); + let session_index = SessionIndex::from(0_u32); + + let keystore = LocalKeystore::in_memory(); + let keystore = Arc::new(keystore) as KeystorePtr; + let signing_context = SigningContext { parent_hash: relay_parent, session_index }; + + let validators = vec![ + keyring::Sr25519Keyring::Alice, + keyring::Sr25519Keyring::Bob, + keyring::Sr25519Keyring::Charlie, + keyring::Sr25519Keyring::Dave, + ]; + for validator in validators.iter() { + Keystore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); + } + + let has_concluded_invalid = + |_idx: usize, _backed_candidate: &BackedCandidate| -> bool { false }; + + let entry_ttl = 10_000; + let scheduled = (0_usize..2) + .into_iter() + .map(|idx| { + let core_idx = CoreIndex::from(idx as u32); + let ca = CoreAssignment { + paras_entry: ParasEntry::new( + Assignment::new(ParaId::from(1_u32 + idx as u32)), + entry_ttl, + ), + core: core_idx, + }; + ca + }) + .collect::>(); + + let group_validators = |group_index: GroupIndex| { + match group_index { + group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]), + group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]), + _ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"), + } + .map(|m| m.into_iter().map(ValidatorIndex).collect::>()) + }; + + let backed_candidates = (0_usize..2) + .into_iter() + .map(|idx0| { + let idx1 = idx0 + 1; + let mut candidate = TestCandidateBuilder { + para_id: ParaId::from(idx1), + relay_parent, + pov_hash: Hash::repeat_byte(idx1 as u8), + persisted_validation_data_hash: [42u8; 32].into(), + hrmp_watermark: RELAY_PARENT_NUM, + ..Default::default() + } + .build(); + + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); + + let backed = back_candidate( + candidate, + &validators, + group_validators(GroupIndex::from(idx0 as u32)).unwrap().as_ref(), + &keystore, + &signing_context, + BackingKind::Threshold, + ); + backed + }) + .collect::>(); + + // happy path + assert_eq!( + sanitize_backed_candidates::( + backed_candidates.clone(), + has_concluded_invalid, + &scheduled + ), + backed_candidates + ); + + // nothing is scheduled, so no paraids match, thus all backed candidates are skipped + { + let scheduled = &Vec::new(); + assert!(sanitize_backed_candidates::( + backed_candidates.clone(), + has_concluded_invalid, + &scheduled + ) + .is_empty()); + } + + // candidates that have concluded as invalid are filtered out + { + // mark every second one as concluded invalid + let set = { + let mut set = std::collections::HashSet::new(); + for (idx, backed_candidate) in backed_candidates.iter().enumerate() { + if idx & 0x01 == 0 { + set.insert(backed_candidate.hash()); + } + } + set + }; + let has_concluded_invalid = + |_idx: usize, candidate: &BackedCandidate| set.contains(&candidate.hash()); + assert_eq!( + sanitize_backed_candidates::( + backed_candidates.clone(), + has_concluded_invalid, + &scheduled + ) + .len(), + backed_candidates.len() / 2 + ); + } + } +} diff --git a/polkadot/runtime/parachains/src/paras_inherent/weights.rs b/polkadot/runtime/parachains/src/paras_inherent/weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..05cc53fae04652c188d62b57fa5281aa6bb88e22 --- /dev/null +++ b/polkadot/runtime/parachains/src/paras_inherent/weights.rs @@ -0,0 +1,175 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! We use benchmarks to get time weights, for proof_size we manually use the size of the input +//! data, which will be part of the block. This is because we don't care about the storage proof on +//! the relay chain, but we do care about the size of the block, by putting the tx in the +//! proof_size we can use the already existing weight limiting code to limit the used size as well. + +use parity_scale_codec::{Encode, WrapperTypeEncode}; +use primitives::{ + CheckedMultiDisputeStatementSet, MultiDisputeStatementSet, UncheckedSignedAvailabilityBitfield, + UncheckedSignedAvailabilityBitfields, +}; + +use super::{BackedCandidate, Config, DisputeStatementSet, Weight}; + +pub trait WeightInfo { + /// Variant over `v`, the count of dispute statements in a dispute statement set. This gives the + /// weight of a single dispute statement set. + fn enter_variable_disputes(v: u32) -> Weight; + /// The weight of one bitfield. + fn enter_bitfields() -> Weight; + /// Variant over `v`, the count of validity votes for a backed candidate. This gives the weight + /// of a single backed candidate. + fn enter_backed_candidates_variable(v: u32) -> Weight; + /// The weight of a single backed candidate with a code upgrade. + fn enter_backed_candidate_code_upgrade() -> Weight; +} + +pub struct TestWeightInfo; +// `WeightInfo` impl for unit and integration tests. Based off of the `max_block` weight for the +// mock. +#[cfg(not(feature = "runtime-benchmarks"))] +impl WeightInfo for TestWeightInfo { + fn enter_variable_disputes(v: u32) -> Weight { + // MAX Block Weight should fit 4 disputes + Weight::from_parts(80_000 * v as u64 + 80_000, 0) + } + fn enter_bitfields() -> Weight { + // MAX Block Weight should fit 4 backed candidates + Weight::from_parts(40_000u64, 0) + } + fn enter_backed_candidates_variable(v: u32) -> Weight { + // MAX Block Weight should fit 4 backed candidates + Weight::from_parts(40_000 * v as u64 + 40_000, 0) + } + fn enter_backed_candidate_code_upgrade() -> Weight { + Weight::zero() + } +} +// To simplify benchmarks running as tests, we set all the weights to 0. `enter` will exit early +// when if the data causes it to be over weight, but we don't want that to block a benchmark from +// running as a test. +#[cfg(feature = "runtime-benchmarks")] +impl WeightInfo for TestWeightInfo { + fn enter_variable_disputes(_v: u32) -> Weight { + Weight::zero() + } + fn enter_bitfields() -> Weight { + Weight::zero() + } + fn enter_backed_candidates_variable(_v: u32) -> Weight { + Weight::zero() + } + fn enter_backed_candidate_code_upgrade() -> Weight { + Weight::zero() + } +} + +pub fn paras_inherent_total_weight( + backed_candidates: &[BackedCandidate<::Hash>], + bitfields: &UncheckedSignedAvailabilityBitfields, + disputes: &MultiDisputeStatementSet, +) -> Weight { + backed_candidates_weight::(backed_candidates) + .saturating_add(signed_bitfields_weight::(bitfields)) + .saturating_add(multi_dispute_statement_sets_weight::(disputes)) +} + +pub fn multi_dispute_statement_sets_weight( + disputes: &MultiDisputeStatementSet, +) -> Weight { + set_proof_size_to_tx_size( + disputes + .iter() + .map(|d| dispute_statement_set_weight::(d)) + .fold(Weight::zero(), |acc_weight, weight| acc_weight.saturating_add(weight)), + disputes, + ) +} + +pub fn checked_multi_dispute_statement_sets_weight( + disputes: &CheckedMultiDisputeStatementSet, +) -> Weight { + set_proof_size_to_tx_size( + disputes + .iter() + .map(|d| dispute_statement_set_weight::(d)) + .fold(Weight::zero(), |acc_weight, weight| acc_weight.saturating_add(weight)), + disputes, + ) +} + +/// Get time weights from benchmarks and set proof size to tx size. +pub fn dispute_statement_set_weight(statement_set: D) -> Weight +where + T: Config, + D: AsRef + WrapperTypeEncode + Sized + Encode, +{ + set_proof_size_to_tx_size( + <::WeightInfo as WeightInfo>::enter_variable_disputes( + statement_set.as_ref().statements.len() as u32, + ), + statement_set, + ) +} + +pub fn signed_bitfields_weight( + bitfields: &UncheckedSignedAvailabilityBitfields, +) -> Weight { + set_proof_size_to_tx_size( + <::WeightInfo as WeightInfo>::enter_bitfields() + .saturating_mul(bitfields.len() as u64), + bitfields, + ) +} + +pub fn signed_bitfield_weight(bitfield: &UncheckedSignedAvailabilityBitfield) -> Weight { + set_proof_size_to_tx_size( + <::WeightInfo as WeightInfo>::enter_bitfields(), + bitfield, + ) +} + +pub fn backed_candidate_weight( + candidate: &BackedCandidate, +) -> Weight { + set_proof_size_to_tx_size( + if candidate.candidate.commitments.new_validation_code.is_some() { + <::WeightInfo as WeightInfo>::enter_backed_candidate_code_upgrade() + } else { + <::WeightInfo as WeightInfo>::enter_backed_candidates_variable( + candidate.validity_votes.len() as u32, + ) + }, + candidate, + ) +} + +pub fn backed_candidates_weight( + candidates: &[BackedCandidate], +) -> Weight { + candidates + .iter() + .map(|c| backed_candidate_weight::(c)) + .fold(Weight::zero(), |acc, x| acc.saturating_add(x)) +} + +/// Set proof_size component of `Weight` to tx size. +fn set_proof_size_to_tx_size(weight: Weight, arg: Arg) -> Weight { + weight.set_proof_size(arg.encoded_size() as u64) +} diff --git a/polkadot/runtime/parachains/src/reward_points.rs b/polkadot/runtime/parachains/src/reward_points.rs new file mode 100644 index 0000000000000000000000000000000000000000..e9a9c5547a7ad8f35b61008c49f0002126a5b276 --- /dev/null +++ b/polkadot/runtime/parachains/src/reward_points.rs @@ -0,0 +1,92 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! An implementation of the `RewardValidators` trait used by `inclusion` that employs +//! `pallet-staking` to compute the rewards. +//! +//! Based on +//! which doesn't currently mention availability bitfields. As such, we don't reward them +//! for the time being, although we will build schemes to do so in the future. + +use crate::{session_info, shared}; +use frame_support::traits::{Defensive, ValidatorSet}; +use primitives::{SessionIndex, ValidatorIndex}; +use sp_std::collections::btree_set::BTreeSet; + +/// The amount of era points given by backing a candidate that is included. +pub const BACKING_POINTS: u32 = 20; +/// The amount of era points given by dispute voting on a candidate. +pub const DISPUTE_STATEMENT_POINTS: u32 = 20; + +/// Rewards validators for participating in parachains with era points in pallet-staking. +pub struct RewardValidatorsWithEraPoints(sp_std::marker::PhantomData); + +impl RewardValidatorsWithEraPoints +where + C: pallet_staking::Config + session_info::Config, + C::ValidatorSet: ValidatorSet, +{ + /// Reward validators in session with points, but only if they are in the active set. + fn reward_only_active( + session_index: SessionIndex, + indices: impl IntoIterator, + points: u32, + ) { + let validators = session_info::Pallet::::account_keys(&session_index); + let validators = match validators + .defensive_proof("account_keys are present for dispute_period sessions") + { + Some(validators) => validators, + None => return, + }; + // limit rewards to the active validator set + let active_set: BTreeSet<_> = C::ValidatorSet::validators().into_iter().collect(); + + let rewards = indices + .into_iter() + .filter_map(|i| validators.get(i.0 as usize).cloned()) + .filter(|v| active_set.contains(v)) + .map(|v| (v, points)); + + >::reward_by_ids(rewards); + } +} + +impl crate::inclusion::RewardValidators for RewardValidatorsWithEraPoints +where + C: pallet_staking::Config + shared::Config + session_info::Config, + C::ValidatorSet: ValidatorSet, +{ + fn reward_backing(indices: impl IntoIterator) { + let session_index = shared::Pallet::::session_index(); + Self::reward_only_active(session_index, indices, BACKING_POINTS); + } + + fn reward_bitfields(_validators: impl IntoIterator) {} +} + +impl crate::disputes::RewardValidators for RewardValidatorsWithEraPoints +where + C: pallet_staking::Config + session_info::Config, + C::ValidatorSet: ValidatorSet, +{ + fn reward_dispute_statement( + session: SessionIndex, + validators: impl IntoIterator, + ) { + Self::reward_only_active(session, validators, DISPUTE_STATEMENT_POINTS); + } +} diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/mod.rs b/polkadot/runtime/parachains/src/runtime_api_impl/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e066ad825a3300545a4ecf7840084ecbfc838223 --- /dev/null +++ b/polkadot/runtime/parachains/src/runtime_api_impl/mod.rs @@ -0,0 +1,29 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Runtime API implementations for Parachains. +//! +//! These are exposed as different modules using different sets of primitives. +//! At the moment there is a `v2` module for the current stable API and +//! `vstaging` module for all staging methods. +//! When new version of the stable API is released it will be based on `v2` and +//! will contain methods from `vstaging`. +//! The promotion consists of the following steps: +//! 1. Bump the version of the stable module (e.g. `v2` becomes `v3`) +//! 2. Move methods from `vstaging` to `v3`. The new stable version should include all methods from +//! `vstaging` tagged with the new version number (e.g. all `v3` methods). +pub mod v5; +pub mod vstaging; diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/v5.rs b/polkadot/runtime/parachains/src/runtime_api_impl/v5.rs new file mode 100644 index 0000000000000000000000000000000000000000..cd15796897334a477ee19e33aa9cc4a92c68605e --- /dev/null +++ b/polkadot/runtime/parachains/src/runtime_api_impl/v5.rs @@ -0,0 +1,414 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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. + +//! A module exporting runtime API implementation functions for all runtime APIs using `v5` +//! primitives. +//! +//! Runtimes implementing the v2 runtime API are recommended to forward directly to these +//! functions. + +use crate::{ + configuration, disputes, dmp, hrmp, inclusion, initializer, paras, paras_inherent, scheduler, + session_info, shared, +}; +use frame_system::pallet_prelude::*; +use primitives::{ + slashing, AuthorityDiscoveryId, CandidateEvent, CandidateHash, CommittedCandidateReceipt, + CoreIndex, CoreOccupied, CoreState, DisputeState, ExecutorParams, GroupIndex, + GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, + OccupiedCore, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, + ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, + ValidatorId, ValidatorIndex, ValidatorSignature, +}; +use sp_runtime::traits::One; +use sp_std::{collections::btree_map::BTreeMap, prelude::*}; + +/// Implementation for the `validators` function of the runtime API. +pub fn validators() -> Vec { + >::active_validator_keys() +} + +/// Implementation for the `validator_groups` function of the runtime API. +pub fn validator_groups( +) -> (Vec>, GroupRotationInfo>) { + let now = >::block_number() + One::one(); + + let groups = >::validator_groups(); + let rotation_info = >::group_rotation_info(now); + + (groups, rotation_info) +} + +/// Implementation for the `availability_cores` function of the runtime API. +pub fn availability_cores() -> Vec>> { + let cores = >::availability_cores(); + let config = >::config(); + let now = >::block_number() + One::one(); + let rotation_info = >::group_rotation_info(now); + + let time_out_at = |backed_in_number, availability_period| { + let time_out_at = backed_in_number + availability_period; + + let current_window = rotation_info.last_rotation_at() + availability_period; + let next_rotation = rotation_info.next_rotation_at(); + + // If we are within `period` blocks of rotation, timeouts are being checked + // actively. We could even time out this block. + if time_out_at < current_window { + time_out_at + } else if time_out_at <= next_rotation { + // Otherwise, it will time out at the sooner of the next rotation + next_rotation + } else { + // or the scheduled time-out. This is by definition within `period` blocks + // of `next_rotation` and is thus a valid timeout block. + time_out_at + } + }; + + let group_responsible_for = + |backed_in_number, core_index| match >::group_assigned_to_core( + core_index, + backed_in_number, + ) { + Some(g) => g, + None => { + log::warn!( + target: "runtime::polkadot-api::v2", + "Could not determine the group responsible for core extracted \ + from list of cores for some prior block in same session", + ); + + GroupIndex(0) + }, + }; + + let mut core_states: Vec<_> = cores + .into_iter() + .enumerate() + .map(|(i, core)| match core { + CoreOccupied::Paras(entry) => { + let pending_availability = + >::pending_availability(entry.para_id()) + .expect("Occupied core always has pending availability; qed"); + + let backed_in_number = *pending_availability.backed_in_number(); + CoreState::Occupied(OccupiedCore { + next_up_on_available: >::next_up_on_available(CoreIndex( + i as u32, + )), + occupied_since: backed_in_number, + time_out_at: time_out_at(backed_in_number, config.paras_availability_period), + next_up_on_time_out: >::next_up_on_time_out(CoreIndex( + i as u32, + )), + availability: pending_availability.availability_votes().clone(), + group_responsible: group_responsible_for( + backed_in_number, + pending_availability.core_occupied(), + ), + candidate_hash: pending_availability.candidate_hash(), + candidate_descriptor: pending_availability.candidate_descriptor().clone(), + }) + }, + CoreOccupied::Free => CoreState::Free, + }) + .collect(); + + // This will overwrite only `Free` cores if the scheduler module is working as intended. + for scheduled in >::scheduled_claimqueue() { + core_states[scheduled.core.0 as usize] = CoreState::Scheduled(primitives::ScheduledCore { + para_id: scheduled.paras_entry.para_id(), + collator: None, + }); + } + + core_states +} + +/// Returns current block number being processed and the corresponding root hash. +fn current_relay_parent( +) -> (BlockNumberFor, ::Hash) { + use parity_scale_codec::Decode as _; + let state_version = >::runtime_version().state_version(); + let relay_parent_number = >::block_number(); + let relay_parent_storage_root = T::Hash::decode(&mut &sp_io::storage::root(state_version)[..]) + .expect("storage root must decode to the Hash type; qed"); + (relay_parent_number, relay_parent_storage_root) +} + +fn with_assumption( + para_id: ParaId, + assumption: OccupiedCoreAssumption, + build: F, +) -> Option +where + Config: inclusion::Config, + F: FnOnce() -> Option, +{ + match assumption { + OccupiedCoreAssumption::Included => { + >::force_enact(para_id); + build() + }, + OccupiedCoreAssumption::TimedOut => build(), + OccupiedCoreAssumption::Free => { + if >::pending_availability(para_id).is_some() { + None + } else { + build() + } + }, + } +} + +/// Implementation for the `persisted_validation_data` function of the runtime API. +pub fn persisted_validation_data( + para_id: ParaId, + assumption: OccupiedCoreAssumption, +) -> Option>> { + let (relay_parent_number, relay_parent_storage_root) = current_relay_parent::(); + with_assumption::(para_id, assumption, || { + crate::util::make_persisted_validation_data::( + para_id, + relay_parent_number, + relay_parent_storage_root, + ) + }) +} + +/// Implementation for the `assumed_validation_data` function of the runtime API. +pub fn assumed_validation_data( + para_id: ParaId, + expected_persisted_validation_data_hash: Hash, +) -> Option<(PersistedValidationData>, ValidationCodeHash)> { + let (relay_parent_number, relay_parent_storage_root) = current_relay_parent::(); + // This closure obtains the `persisted_validation_data` for the given `para_id` and matches + // its hash against an expected one. + let make_validation_data = || { + crate::util::make_persisted_validation_data::( + para_id, + relay_parent_number, + relay_parent_storage_root, + ) + .filter(|validation_data| validation_data.hash() == expected_persisted_validation_data_hash) + }; + + let persisted_validation_data = make_validation_data().or_else(|| { + // Try again with force enacting the core. This check only makes sense if + // the core is occupied. + >::pending_availability(para_id).and_then(|_| { + >::force_enact(para_id); + make_validation_data() + }) + }); + // If we were successful, also query current validation code hash. + persisted_validation_data.zip(>::current_code_hash(¶_id)) +} + +/// Implementation for the `check_validation_outputs` function of the runtime API. +pub fn check_validation_outputs( + para_id: ParaId, + outputs: primitives::CandidateCommitments, +) -> bool { + let relay_parent_number = >::block_number(); + >::check_validation_outputs_for_runtime_api( + para_id, + relay_parent_number, + outputs, + ) +} + +/// Implementation for the `session_index_for_child` function of the runtime API. +pub fn session_index_for_child() -> SessionIndex { + // Just returns the session index from `inclusion`. Runtime APIs follow + // initialization so the initializer will have applied any pending session change + // which is expected at the child of the block whose context the runtime API was invoked + // in. + // + // Incidentally, this is also the rationale for why it is OK to query validators or + // occupied cores or etc. and expect the correct response "for child". + >::session_index() +} + +/// Implementation for the `AuthorityDiscoveryApi::authorities()` function of the runtime API. +/// It is a heavy call, but currently only used for authority discovery, so it is fine. +/// Gets next, current and some historical authority ids using `session_info` module. +pub fn relevant_authority_ids( +) -> Vec { + let current_session_index = session_index_for_child::(); + let earliest_stored_session = >::earliest_stored_session(); + + // Due to `max_validators`, the `SessionInfo` stores only the validators who are actively + // selected to participate in parachain consensus. We'd like all authorities for the current + // and next sessions to be used in authority-discovery. The two sets likely have large overlap. + let mut authority_ids = >::current_authorities().to_vec(); + authority_ids.extend(>::next_authorities().to_vec()); + + // Due to disputes, we'd like to remain connected to authorities of the previous few sessions. + // For this, we don't need anyone other than the validators actively participating in consensus. + for session_index in earliest_stored_session..current_session_index { + let info = >::session_info(session_index); + if let Some(mut info) = info { + authority_ids.append(&mut info.discovery_keys); + } + } + + authority_ids.sort(); + authority_ids.dedup(); + + authority_ids +} + +/// Implementation for the `validation_code` function of the runtime API. +pub fn validation_code( + para_id: ParaId, + assumption: OccupiedCoreAssumption, +) -> Option { + with_assumption::(para_id, assumption, || >::current_code(¶_id)) +} + +/// Implementation for the `candidate_pending_availability` function of the runtime API. +pub fn candidate_pending_availability( + para_id: ParaId, +) -> Option> { + >::candidate_pending_availability(para_id) +} + +/// Implementation for the `candidate_events` function of the runtime API. +// NOTE: this runs without block initialization, as it accesses events. +// this means it can run in a different session than other runtime APIs at the same block. +pub fn candidate_events(extract_event: F) -> Vec> +where + T: initializer::Config, + F: Fn(::RuntimeEvent) -> Option>, +{ + use inclusion::Event as RawEvent; + + >::read_events_no_consensus() + .into_iter() + .filter_map(|record| extract_event(record.event)) + .filter_map(|event| { + Some(match event { + RawEvent::::CandidateBacked(c, h, core, group) => + CandidateEvent::CandidateBacked(c, h, core, group), + RawEvent::::CandidateIncluded(c, h, core, group) => + CandidateEvent::CandidateIncluded(c, h, core, group), + RawEvent::::CandidateTimedOut(c, h, core) => + CandidateEvent::CandidateTimedOut(c, h, core), + // Not needed for candidate events. + RawEvent::::UpwardMessagesReceived { .. } => return None, + RawEvent::::__Ignore(_, _) => unreachable!("__Ignore cannot be used"), + }) + }) + .collect() +} + +/// Get the session info for the given session, if stored. +pub fn session_info(index: SessionIndex) -> Option { + >::session_info(index) +} + +/// Implementation for the `dmq_contents` function of the runtime API. +pub fn dmq_contents( + recipient: ParaId, +) -> Vec>> { + >::dmq_contents(recipient) +} + +/// Implementation for the `inbound_hrmp_channels_contents` function of the runtime API. +pub fn inbound_hrmp_channels_contents( + recipient: ParaId, +) -> BTreeMap>>> { + >::inbound_hrmp_channels_contents(recipient) +} + +/// Implementation for the `validation_code_by_hash` function of the runtime API. +pub fn validation_code_by_hash( + hash: ValidationCodeHash, +) -> Option { + >::code_by_hash(hash) +} + +/// Disputes imported via means of on-chain imports. +pub fn on_chain_votes() -> Option> { + >::on_chain_votes() +} + +/// Submits an PVF pre-checking vote. See [`paras::Pallet::submit_pvf_check_statement`]. +pub fn submit_pvf_check_statement( + stmt: PvfCheckStatement, + signature: ValidatorSignature, +) { + >::submit_pvf_check_statement(stmt, signature) +} + +/// Returns the list of all PVF code hashes that require pre-checking. See +/// [`paras::Pallet::pvfs_require_precheck`]. +pub fn pvfs_require_precheck() -> Vec { + >::pvfs_require_precheck() +} + +/// Returns the validation code hash for the given parachain making the given +/// `OccupiedCoreAssumption`. +pub fn validation_code_hash( + para_id: ParaId, + assumption: OccupiedCoreAssumption, +) -> Option +where + T: inclusion::Config, +{ + with_assumption::(para_id, assumption, || { + >::current_code_hash(¶_id) + }) +} + +/// Implementation for `get_session_disputes` function from the runtime API +pub fn get_session_disputes( +) -> Vec<(SessionIndex, CandidateHash, DisputeState>)> { + >::disputes() +} + +/// Get session executor parameter set +pub fn session_executor_params( + session_index: SessionIndex, +) -> Option { + // This is to bootstrap the storage working around the runtime migration issue: + // https://github.com/paritytech/substrate/issues/9997 + // After the bootstrap is complete (no less than 7 session passed with the runtime) + // this code should be replaced with a pure + // >::session_executor_params(session_index) call. + match >::session_executor_params(session_index) { + Some(ep) => Some(ep), + None => Some(ExecutorParams::default()), + } +} + +/// Implementation of `unapplied_slashes` runtime API +pub fn unapplied_slashes( +) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> { + >::unapplied_slashes() +} + +/// Implementation of `submit_report_dispute_lost` runtime API +pub fn submit_unsigned_slashing_report( + dispute_proof: slashing::DisputeProof, + key_ownership_proof: slashing::OpaqueKeyOwnershipProof, +) -> Option<()> { + let key_ownership_proof = key_ownership_proof.decode()?; + + >::submit_unsigned_slashing_report( + dispute_proof, + key_ownership_proof, + ) +} diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs new file mode 100644 index 0000000000000000000000000000000000000000..5406428377d0dd0a0991f3f6edab35ada25bda13 --- /dev/null +++ b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -0,0 +1,120 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Put implementations of functions from staging APIs here. + +use crate::{configuration, dmp, hrmp, inclusion, initializer, paras, shared}; +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::{ + vstaging::{ + AsyncBackingParams, BackingState, CandidatePendingAvailability, Constraints, + InboundHrmpLimitations, OutboundHrmpChannelLimitations, + }, + Id as ParaId, +}; +use sp_std::prelude::*; + +/// Implementation for `StagingParaBackingState` function from the runtime API +pub fn backing_state( + para_id: ParaId, +) -> Option>> { + let config = >::config(); + // Async backing is only expected to be enabled with a tracker capacity of 1. + // Subsequent configuration update gets applied on new session, which always + // clears the buffer. + // + // Thus, minimum relay parent is ensured to have asynchronous backing enabled. + let now = >::block_number(); + let min_relay_parent_number = >::allowed_relay_parents() + .hypothetical_earliest_block_number(now, config.async_backing_params.allowed_ancestry_len); + + let required_parent = >::para_head(para_id)?; + let validation_code_hash = >::current_code_hash(para_id)?; + + let upgrade_restriction = >::upgrade_restriction_signal(para_id); + let future_validation_code = + >::future_code_upgrade_at(para_id).and_then(|block_num| { + // Only read the storage if there's a pending upgrade. + Some(block_num).zip(>::future_code_hash(para_id)) + }); + + let (ump_msg_count, ump_total_bytes) = + >::relay_dispatch_queue_size(para_id); + let ump_remaining = config.max_upward_queue_count - ump_msg_count; + let ump_remaining_bytes = config.max_upward_queue_size - ump_total_bytes; + + let dmp_remaining_messages = >::dmq_contents(para_id) + .into_iter() + .map(|msg| msg.sent_at) + .collect(); + + let valid_watermarks = >::valid_watermarks(para_id); + let hrmp_inbound = InboundHrmpLimitations { valid_watermarks }; + let hrmp_channels_out = >::outbound_remaining_capacity(para_id) + .into_iter() + .map(|(para, (messages_remaining, bytes_remaining))| { + (para, OutboundHrmpChannelLimitations { messages_remaining, bytes_remaining }) + }) + .collect(); + + let constraints = Constraints { + min_relay_parent_number, + max_pov_size: config.max_pov_size, + max_code_size: config.max_code_size, + ump_remaining, + ump_remaining_bytes, + max_ump_num_per_candidate: config.max_upward_message_num_per_candidate, + dmp_remaining_messages, + hrmp_inbound, + hrmp_channels_out, + max_hrmp_num_per_candidate: config.hrmp_max_message_num_per_candidate, + required_parent, + validation_code_hash, + upgrade_restriction, + future_validation_code, + }; + + let pending_availability = { + // Note: the API deals with a `Vec` as it is future-proof for cases + // where there may be multiple candidates pending availability at a time. + // But at the moment only one candidate can be pending availability per + // parachain. + crate::inclusion::PendingAvailability::::get(¶_id) + .and_then(|pending| { + let commitments = + crate::inclusion::PendingAvailabilityCommitments::::get(¶_id); + commitments.map(move |c| (pending, c)) + }) + .map(|(pending, commitments)| { + CandidatePendingAvailability { + candidate_hash: pending.candidate_hash(), + descriptor: pending.candidate_descriptor().clone(), + commitments, + relay_parent_number: pending.relay_parent_number(), + max_pov_size: constraints.max_pov_size, // assume always same in session. + } + }) + .into_iter() + .collect() + }; + + Some(BackingState { constraints, pending_availability }) +} + +/// Implementation for `StagingAsyncBackingParams` function from the runtime API +pub fn async_backing_params() -> AsyncBackingParams { + >::config().async_backing_params +} diff --git a/polkadot/runtime/parachains/src/scheduler.rs b/polkadot/runtime/parachains/src/scheduler.rs new file mode 100644 index 0000000000000000000000000000000000000000..577bcd153b5b032fbc447de74c93c0f4f1b156d3 --- /dev/null +++ b/polkadot/runtime/parachains/src/scheduler.rs @@ -0,0 +1,672 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The scheduler module for parachains and parathreads. +//! +//! This module is responsible for two main tasks: +//! - Partitioning validators into groups and assigning groups to parachains and parathreads +//! - Scheduling parachains and parathreads +//! +//! It aims to achieve these tasks with these goals in mind: +//! - It should be possible to know at least a block ahead-of-time, ideally more, which validators +//! are going to be assigned to which parachains. +//! - Parachains that have a candidate pending availability in this fork of the chain should not be +//! assigned. +//! - Validator assignments should not be gameable. Malicious cartels should not be able to +//! manipulate the scheduler to assign themselves as desired. +//! - High or close to optimal throughput of parachains and parathreads. Work among validator groups +//! should be balanced. +//! +//! The Scheduler manages resource allocation using the concept of "Availability Cores". +//! There will be one availability core for each parachain, and a fixed number of cores +//! used for multiplexing parathreads. Validators will be partitioned into groups, with the same +//! number of groups as availability cores. Validator groups will be assigned to different +//! availability cores over time. + +use crate::{configuration, initializer::SessionChangeNotification, paras}; +use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::{ + v5::ParasEntry, CoreIndex, CoreOccupied, GroupIndex, GroupRotationInfo, Id as ParaId, + ScheduledCore, ValidatorIndex, +}; +use sp_runtime::traits::{One, Saturating}; +use sp_std::{ + collections::{btree_map::BTreeMap, vec_deque::VecDeque}, + prelude::*, +}; + +pub mod common; + +use common::{AssignmentProvider, AssignmentProviderConfig, CoreAssignment, FreedReason}; + +pub use pallet::*; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &str = "runtime::parachains::scheduler"; +pub mod migration; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::without_storage_info] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + configuration::Config + paras::Config { + type AssignmentProvider: AssignmentProvider>; + } + + /// All the validator groups. One for each core. Indices are into `ActiveValidators` - not the + /// broader set of Polkadot validators, but instead just the subset used for parachains during + /// this session. + /// + /// Bound: The number of cores is the sum of the numbers of parachains and parathread + /// multiplexers. Reasonably, 100-1000. The dominant factor is the number of validators: safe + /// upper bound at 10k. + #[pallet::storage] + #[pallet::getter(fn validator_groups)] + pub(crate) type ValidatorGroups = StorageValue<_, Vec>, ValueQuery>; + + /// One entry for each availability core. Entries are `None` if the core is not currently + /// occupied. Can be temporarily `Some` if scheduled but not occupied. + /// The i'th parachain belongs to the i'th core, with the remaining cores all being + /// parathread-multiplexers. + /// + /// Bounded by the maximum of either of these two values: + /// * The number of parachains and parathread multiplexers + /// * The number of validators divided by `configuration.max_validators_per_core`. + #[pallet::storage] + #[pallet::getter(fn availability_cores)] + pub(crate) type AvailabilityCores = + StorageValue<_, Vec>>, ValueQuery>; + + /// The block number where the session start occurred. Used to track how many group rotations + /// have occurred. + /// + /// Note that in the context of parachains modules the session change is signaled during + /// the block and enacted at the end of the block (at the finalization stage, to be exact). + /// Thus for all intents and purposes the effect of the session change is observed at the + /// block following the session change, block number of which we save in this storage value. + #[pallet::storage] + #[pallet::getter(fn session_start_block)] + pub(crate) type SessionStartBlock = StorageValue<_, BlockNumberFor, ValueQuery>; + + /// One entry for each availability core. The `VecDeque` represents the assignments to be + /// scheduled on that core. `None` is used to signal to not schedule the next para of the core + /// as there is one currently being scheduled. Not using `None` here would overwrite the + /// `CoreState` in the runtime API. The value contained here will not be valid after the end of + /// a block. Runtime APIs should be used to determine scheduled cores/ for the upcoming block. + #[pallet::storage] + #[pallet::getter(fn claimqueue)] + pub(crate) type ClaimQueue = StorageValue< + _, + BTreeMap>>>>, + ValueQuery, + >; +} + +type PositionInClaimqueue = u32; +type TimedoutParas = BTreeMap>>; +type ConcludedParas = BTreeMap; + +impl Pallet { + /// Called by the initializer to initialize the scheduler pallet. + pub(crate) fn initializer_initialize(_now: BlockNumberFor) -> Weight { + Weight::zero() + } + + /// Called by the initializer to finalize the scheduler pallet. + pub(crate) fn initializer_finalize() {} + + /// Called before the initializer notifies of a new session. + pub(crate) fn pre_new_session() { + Self::push_claimqueue_items_to_assignment_provider(); + Self::push_occupied_cores_to_assignment_provider(); + } + + /// Called by the initializer to note that a new session has started. + pub(crate) fn initializer_on_new_session( + notification: &SessionChangeNotification>, + ) { + let SessionChangeNotification { validators, new_config, .. } = notification; + let config = new_config; + + let n_cores = core::cmp::max( + T::AssignmentProvider::session_core_count(), + match config.max_validators_per_core { + Some(x) if x != 0 => validators.len() as u32 / x, + _ => 0, + }, + ); + + AvailabilityCores::::mutate(|cores| { + cores.resize(n_cores as _, CoreOccupied::Free); + }); + + // shuffle validators into groups. + if n_cores == 0 || validators.is_empty() { + ValidatorGroups::::set(Vec::new()); + } else { + let group_base_size = validators.len() / n_cores as usize; + let n_larger_groups = validators.len() % n_cores as usize; + + // Groups contain indices into the validators from the session change notification, + // which are already shuffled. + + let mut groups: Vec> = Vec::new(); + for i in 0..n_larger_groups { + let offset = (group_base_size + 1) * i; + groups.push( + (0..group_base_size + 1) + .map(|j| offset + j) + .map(|j| ValidatorIndex(j as _)) + .collect(), + ); + } + + for i in 0..(n_cores as usize - n_larger_groups) { + let offset = (n_larger_groups * (group_base_size + 1)) + (i * group_base_size); + groups.push( + (0..group_base_size) + .map(|j| offset + j) + .map(|j| ValidatorIndex(j as _)) + .collect(), + ); + } + + ValidatorGroups::::set(groups); + } + + let now = >::block_number() + One::one(); + >::set(now); + } + + /// Free unassigned cores. Provide a list of cores that should be considered newly-freed along + /// with the reason for them being freed. Returns a tuple of concluded and timedout paras. + fn free_cores( + just_freed_cores: impl IntoIterator, + ) -> (ConcludedParas, TimedoutParas) { + let mut timedout_paras: BTreeMap>> = + BTreeMap::new(); + let mut concluded_paras = BTreeMap::new(); + + AvailabilityCores::::mutate(|cores| { + let c_len = cores.len(); + + just_freed_cores + .into_iter() + .filter(|(freed_index, _)| (freed_index.0 as usize) < c_len) + .for_each(|(freed_index, freed_reason)| { + match &cores[freed_index.0 as usize] { + CoreOccupied::Free => {}, + CoreOccupied::Paras(entry) => { + match freed_reason { + FreedReason::Concluded => { + concluded_paras.insert(freed_index, entry.para_id()); + }, + FreedReason::TimedOut => { + timedout_paras.insert(freed_index, entry.clone()); + }, + }; + }, + }; + + cores[freed_index.0 as usize] = CoreOccupied::Free; + }) + }); + + (concluded_paras, timedout_paras) + } + + /// Note that the given cores have become occupied. Update the claimqueue accordingly. + pub(crate) fn occupied( + now_occupied: BTreeMap, + ) -> BTreeMap { + let mut availability_cores = AvailabilityCores::::get(); + + log::debug!(target: LOG_TARGET, "[occupied] now_occupied {:?}", now_occupied); + + let pos_mapping: BTreeMap = now_occupied + .iter() + .flat_map(|(core_idx, para_id)| { + match Self::remove_from_claimqueue(*core_idx, *para_id) { + Err(e) => { + log::debug!( + target: LOG_TARGET, + "[occupied] error on remove_from_claimqueue {}", + e + ); + None + }, + Ok((pos_in_claimqueue, pe)) => { + // is this correct? + availability_cores[core_idx.0 as usize] = CoreOccupied::Paras(pe); + + Some((*core_idx, pos_in_claimqueue)) + }, + } + }) + .collect(); + + // Drop expired claims after processing now_occupied. + Self::drop_expired_claims_from_claimqueue(); + + AvailabilityCores::::set(availability_cores); + + pos_mapping + } + + /// Iterates through every element in all claim queues and tries to add new assignments from the + /// `AssignmentProvider`. A claim is considered expired if it's `ttl` field is lower than the + /// current block height. + fn drop_expired_claims_from_claimqueue() { + let now = >::block_number(); + let availability_cores = AvailabilityCores::::get(); + + ClaimQueue::::mutate(|cq| { + for (idx, _) in (0u32..).zip(availability_cores) { + let core_idx = CoreIndex(idx); + if let Some(core_claimqueue) = cq.get_mut(&core_idx) { + let mut dropped_claims: Vec> = vec![]; + core_claimqueue.retain(|maybe_entry| { + if let Some(entry) = maybe_entry { + if entry.ttl < now { + dropped_claims.push(Some(entry.para_id())); + return false + } + } + true + }); + + // For all claims dropped due to TTL, attempt to pop a new entry to + // the back of the claimqueue. + for drop in dropped_claims { + match T::AssignmentProvider::pop_assignment_for_core(core_idx, drop) { + Some(assignment) => { + let AssignmentProviderConfig { ttl, .. } = + T::AssignmentProvider::get_provider_config(core_idx); + core_claimqueue.push_back(Some(ParasEntry::new( + assignment.clone(), + now + ttl, + ))); + }, + None => (), + } + } + } + } + }); + } + + /// Get the para (chain or thread) ID assigned to a particular core or index, if any. Core + /// indices out of bounds will return `None`, as will indices of unassigned cores. + pub(crate) fn core_para(core_index: CoreIndex) -> Option { + let cores = AvailabilityCores::::get(); + match cores.get(core_index.0 as usize) { + None | Some(CoreOccupied::Free) => None, + Some(CoreOccupied::Paras(entry)) => Some(entry.para_id()), + } + } + + /// Get the validators in the given group, if the group index is valid for this session. + pub(crate) fn group_validators(group_index: GroupIndex) -> Option> { + ValidatorGroups::::get().get(group_index.0 as usize).map(|g| g.clone()) + } + + /// Get the group assigned to a specific core by index at the current block number. Result + /// undefined if the core index is unknown or the block number is less than the session start + /// index. + pub(crate) fn group_assigned_to_core( + core: CoreIndex, + at: BlockNumberFor, + ) -> Option { + let config = >::config(); + let session_start_block = >::get(); + + if at < session_start_block { + return None + } + + let validator_groups = ValidatorGroups::::get(); + + if core.0 as usize >= validator_groups.len() { + return None + } + + let rotations_since_session_start: BlockNumberFor = + (at - session_start_block) / config.group_rotation_frequency.into(); + + let rotations_since_session_start = + as TryInto>::try_into(rotations_since_session_start) + .unwrap_or(0); + // Error case can only happen if rotations occur only once every u32::max(), + // so functionally no difference in behavior. + + let group_idx = + (core.0 as usize + rotations_since_session_start as usize) % validator_groups.len(); + Some(GroupIndex(group_idx as u32)) + } + + /// Returns an optional predicate that should be used for timing out occupied cores. + /// + /// If `None`, no timing-out should be done. The predicate accepts the index of the core, and + /// the block number since which it has been occupied, and the respective parachain timeouts, + /// i.e. only within `config.paras_availability_period` of the last rotation would this return + /// `Some`, unless there are no rotations. + /// + /// The timeout used to depend, but does not depend any more on group rotations. First of all + /// it only matters if a para got another chance (a retry). If there is a retry and it happens + /// still within the same group rotation a censoring backing group would need to censor again + /// and lose out again on backing rewards. This is bad for the censoring backing group, it does + /// not matter for the parachain as long as it is retried often enough (so it eventually gets a + /// try on another backing group) - the effect is similar to having a prolonged timeout. It + /// should also be noted that for both malicious and offline backing groups it is actually more + /// realistic that the candidate will not be backed to begin with, instead of getting backed + /// and then not made available. + pub(crate) fn availability_timeout_predicate( + ) -> Option) -> bool> { + let now = >::block_number(); + let config = >::config(); + let session_start = >::get(); + + let blocks_since_session_start = now.saturating_sub(session_start); + let blocks_since_last_rotation = + blocks_since_session_start % config.group_rotation_frequency.max(1u8.into()); + + if blocks_since_last_rotation >= config.paras_availability_period { + None + } else { + Some(|core_index: CoreIndex, pending_since| { + let availability_cores = AvailabilityCores::::get(); + let AssignmentProviderConfig { availability_period, .. } = + T::AssignmentProvider::get_provider_config(core_index); + let now = >::block_number(); + match availability_cores.get(core_index.0 as usize) { + None => true, // out-of-bounds, doesn't really matter what is returned. + Some(CoreOccupied::Free) => true, // core free, still doesn't matter. + Some(CoreOccupied::Paras(_)) => + now.saturating_sub(pending_since) >= availability_period, + } + }) + } + } + + /// Returns a helper for determining group rotation. + pub(crate) fn group_rotation_info( + now: BlockNumberFor, + ) -> GroupRotationInfo> { + let session_start_block = Self::session_start_block(); + let group_rotation_frequency = + >::config().group_rotation_frequency; + + GroupRotationInfo { session_start_block, now, group_rotation_frequency } + } + + /// Return the next thing that will be scheduled on this core assuming it is currently + /// occupied and the candidate occupying it became available. + pub(crate) fn next_up_on_available(core: CoreIndex) -> Option { + ClaimQueue::::get().get(&core).and_then(|a| { + a.iter() + .find_map(|e| e.as_ref()) + .map(|pe| Self::paras_entry_to_scheduled_core(pe)) + }) + } + + fn paras_entry_to_scheduled_core(pe: &ParasEntry>) -> ScheduledCore { + ScheduledCore { para_id: pe.para_id(), collator: None } + } + + /// Return the next thing that will be scheduled on this core assuming it is currently + /// occupied and the candidate occupying it times out. + pub(crate) fn next_up_on_time_out(core: CoreIndex) -> Option { + Self::next_up_on_available(core).or_else(|| { + // Or, if none, the claim currently occupying the core, + // as it would be put back on the queue after timing out if number of retries is not at + // the maximum. + let cores = AvailabilityCores::::get(); + cores.get(core.0 as usize).and_then(|c| match c { + CoreOccupied::Free => None, + CoreOccupied::Paras(pe) => { + let AssignmentProviderConfig { max_availability_timeouts, .. } = + T::AssignmentProvider::get_provider_config(core); + + if pe.availability_timeouts < max_availability_timeouts { + Some(Self::paras_entry_to_scheduled_core(pe)) + } else { + None + } + }, + }) + }) + } + + /// Pushes occupied cores to the assignment provider. + fn push_occupied_cores_to_assignment_provider() { + AvailabilityCores::::mutate(|cores| { + for (core_idx, core) in cores.iter_mut().enumerate() { + match core { + CoreOccupied::Free => continue, + CoreOccupied::Paras(entry) => { + let core_idx = CoreIndex::from(core_idx as u32); + Self::maybe_push_assignment(core_idx, entry.clone()); + }, + } + *core = CoreOccupied::Free; + } + }); + } + + // on new session + fn push_claimqueue_items_to_assignment_provider() { + for (core_idx, core_claimqueue) in ClaimQueue::::take() { + // Push back in reverse order so that when we pop from the provider again, + // the entries in the claimqueue are in the same order as they are right now. + for para_entry in core_claimqueue.into_iter().flatten().rev() { + Self::maybe_push_assignment(core_idx, para_entry); + } + } + } + + /// Push assignments back to the provider on session change unless the paras + /// timed out on availability before. + fn maybe_push_assignment(core_idx: CoreIndex, pe: ParasEntry>) { + if pe.availability_timeouts == 0 { + T::AssignmentProvider::push_assignment_for_core(core_idx, pe.assignment); + } + } + + // + // ClaimQueue related functions + // + fn claimqueue_lookahead() -> u32 { + >::config().scheduling_lookahead + } + + /// Updates the claimqueue by moving it to the next paras and filling empty spots with new + /// paras. + pub(crate) fn update_claimqueue( + just_freed_cores: impl IntoIterator, + now: BlockNumberFor, + ) -> Vec>> { + Self::move_claimqueue_forward(); + Self::free_cores_and_fill_claimqueue(just_freed_cores, now) + } + + /// Moves all elements in the claimqueue forward. + fn move_claimqueue_forward() { + let mut cq = ClaimQueue::::get(); + for (_, core_queue) in cq.iter_mut() { + // First pop the finished claims from the front. + match core_queue.front() { + None => {}, + Some(None) => { + core_queue.pop_front(); + }, + Some(_) => {}, + } + } + + ClaimQueue::::set(cq); + } + + /// Frees cores and fills the free claimqueue spots by popping from the `AssignmentProvider`. + fn free_cores_and_fill_claimqueue( + just_freed_cores: impl IntoIterator, + now: BlockNumberFor, + ) -> Vec>> { + let (mut concluded_paras, mut timedout_paras) = Self::free_cores(just_freed_cores); + + // This can only happen on new sessions at which we move all assignments back to the + // provider. Hence, there's nothing we need to do here. + if ValidatorGroups::::get().is_empty() { + vec![] + } else { + let n_lookahead = Self::claimqueue_lookahead(); + let n_session_cores = T::AssignmentProvider::session_core_count(); + let cq = ClaimQueue::::get(); + let ttl = >::config().on_demand_ttl; + + for core_idx in 0..n_session_cores { + let core_idx = CoreIndex::from(core_idx); + + // add previously timedout paras back into the queue + if let Some(mut entry) = timedout_paras.remove(&core_idx) { + let AssignmentProviderConfig { max_availability_timeouts, .. } = + T::AssignmentProvider::get_provider_config(core_idx); + if entry.availability_timeouts < max_availability_timeouts { + // Increment the timeout counter. + entry.availability_timeouts += 1; + // Reset the ttl so that a timed out assignment. + entry.ttl = now + ttl; + Self::add_to_claimqueue(core_idx, entry); + // The claim has been added back into the claimqueue. + // Do not pop another assignment for the core. + continue + } else { + // Consider timed out assignments for on demand parachains as concluded for + // the assignment provider + let ret = concluded_paras.insert(core_idx, entry.para_id()); + debug_assert!(ret.is_none()); + } + } + + // We consider occupied cores to be part of the claimqueue + let n_lookahead_used = cq.get(&core_idx).map_or(0, |v| v.len() as u32) + + if Self::is_core_occupied(core_idx) { 1 } else { 0 }; + for _ in n_lookahead_used..n_lookahead { + let concluded_para = concluded_paras.remove(&core_idx); + if let Some(assignment) = + T::AssignmentProvider::pop_assignment_for_core(core_idx, concluded_para) + { + Self::add_to_claimqueue(core_idx, ParasEntry::new(assignment, now + ttl)); + } + } + } + + debug_assert!(timedout_paras.is_empty()); + debug_assert!(concluded_paras.is_empty()); + + Self::scheduled_claimqueue() + } + } + + fn is_core_occupied(core_idx: CoreIndex) -> bool { + match AvailabilityCores::::get().get(core_idx.0 as usize) { + None | Some(CoreOccupied::Free) => false, + Some(CoreOccupied::Paras(_)) => true, + } + } + + fn add_to_claimqueue(core_idx: CoreIndex, pe: ParasEntry>) { + ClaimQueue::::mutate(|la| { + let la_deque = la.entry(core_idx).or_insert_with(|| VecDeque::new()); + la_deque.push_back(Some(pe)); + }); + } + + /// Returns `ParasEntry` with `para_id` at `core_idx` if found. + fn remove_from_claimqueue( + core_idx: CoreIndex, + para_id: ParaId, + ) -> Result<(PositionInClaimqueue, ParasEntry>), &'static str> { + ClaimQueue::::mutate(|cq| { + let core_claims = cq.get_mut(&core_idx).ok_or("core_idx not found in lookahead")?; + + let pos = core_claims + .iter() + .position(|a| a.as_ref().map_or(false, |pe| pe.para_id() == para_id)) + .ok_or("para id not found at core_idx lookahead")?; + + let pe = core_claims + .remove(pos) + .ok_or("remove returned None")? + .ok_or("Element in Claimqueue was None.")?; + + // Since the core is now occupied, the next entry in the claimqueue in order to achieve + // 12 second block times needs to be None + if core_claims.front() != Some(&None) { + core_claims.push_front(None); + } + Ok((pos as u32, pe)) + }) + } + + // TODO: Temporary to imitate the old schedule() call. Will be adjusted when we make the + // scheduler AB ready + pub(crate) fn scheduled_claimqueue() -> Vec>> { + let claimqueue = ClaimQueue::::get(); + + claimqueue + .into_iter() + .flat_map(|(core_idx, v)| { + v.front() + .cloned() + .flatten() + .map(|pe| CoreAssignment { core: core_idx, paras_entry: pe }) + }) + .collect() + } + + #[cfg(any(feature = "runtime-benchmarks", test))] + pub(crate) fn assignment_provider_config( + core_idx: CoreIndex, + ) -> AssignmentProviderConfig> { + T::AssignmentProvider::get_provider_config(core_idx) + } + + #[cfg(any(feature = "try-runtime", test))] + fn claimqueue_len() -> usize { + ClaimQueue::::get().iter().map(|la_vec| la_vec.1.len()).sum() + } + + #[cfg(all(not(feature = "runtime-benchmarks"), test))] + pub(crate) fn claimqueue_is_empty() -> bool { + Self::claimqueue_len() == 0 + } + + #[cfg(test)] + pub(crate) fn set_validator_groups(validator_groups: Vec>) { + ValidatorGroups::::set(validator_groups); + } +} diff --git a/polkadot/runtime/parachains/src/scheduler/common.rs b/polkadot/runtime/parachains/src/scheduler/common.rs new file mode 100644 index 0000000000000000000000000000000000000000..0e8e8338b17b71c01e3c131e9ea5a7483f666571 --- /dev/null +++ b/polkadot/runtime/parachains/src/scheduler/common.rs @@ -0,0 +1,96 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Common traits and types used by the scheduler and assignment providers. + +use frame_support::pallet_prelude::*; +use primitives::{ + v5::{Assignment, ParasEntry}, + CoreIndex, Id as ParaId, +}; +use scale_info::TypeInfo; +use sp_std::prelude::*; + +// Only used to link to configuration documentation. +#[allow(unused)] +use crate::configuration::HostConfiguration; + +/// Reasons a core might be freed +#[derive(Clone, Copy)] +pub enum FreedReason { + /// The core's work concluded and the parablock assigned to it is considered available. + Concluded, + /// The core's work timed out. + TimedOut, +} + +/// A set of variables required by the scheduler in order to operate. +pub struct AssignmentProviderConfig { + /// The availability period specified by the implementation. + /// See [`HostConfiguration::paras_availability_period`] for more information. + pub availability_period: BlockNumber, + + /// How many times a collation can time out on availability. + /// Zero timeouts still means that a collation can be provided as per the slot auction + /// assignment provider. + pub max_availability_timeouts: u32, + + /// How long the collator has to provide a collation to the backing group before being dropped. + pub ttl: BlockNumber, +} + +pub trait AssignmentProvider { + /// How many cores are allocated to this provider. + fn session_core_count() -> u32; + + /// Pops an [`Assignment`] from the provider for a specified [`CoreIndex`]. + /// The `concluded_para` field makes the caller report back to the provider + /// which [`ParaId`] it processed last on the supplied [`CoreIndex`]. + fn pop_assignment_for_core( + core_idx: CoreIndex, + concluded_para: Option, + ) -> Option; + + /// Push back an already popped assignment. Intended for provider implementations + /// that need to be able to keep track of assignments over session boundaries, + /// such as the on demand assignment provider. + fn push_assignment_for_core(core_idx: CoreIndex, assignment: Assignment); + + /// Returns a set of variables needed by the scheduler + fn get_provider_config(core_idx: CoreIndex) -> AssignmentProviderConfig; +} + +/// How a core is mapped to a backing group and a `ParaId` +#[derive(Clone, Encode, Decode, PartialEq, TypeInfo)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct CoreAssignment { + /// The core that is assigned. + pub core: CoreIndex, + /// The para id and accompanying information needed to collate and back a parablock. + pub paras_entry: ParasEntry, +} + +impl CoreAssignment { + /// Returns the [`ParaId`] of the assignment. + pub fn para_id(&self) -> ParaId { + self.paras_entry.para_id() + } + + /// Returns the inner [`ParasEntry`] of the assignment. + pub fn to_paras_entry(self) -> ParasEntry { + self.paras_entry + } +} diff --git a/polkadot/runtime/parachains/src/scheduler/migration.rs b/polkadot/runtime/parachains/src/scheduler/migration.rs new file mode 100644 index 0000000000000000000000000000000000000000..32ac9deaf68f24149382bb9acaadc0368687d36b --- /dev/null +++ b/polkadot/runtime/parachains/src/scheduler/migration.rs @@ -0,0 +1,166 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A module that is responsible for migration of storage. + +use super::*; +use frame_support::{ + pallet_prelude::ValueQuery, storage_alias, traits::OnRuntimeUpgrade, weights::Weight, +}; +use primitives::vstaging::Assignment; + +mod v0 { + use super::*; + + use primitives::CollatorId; + #[storage_alias] + pub(super) type Scheduled = StorageValue, Vec, ValueQuery>; + + #[derive(Encode, Decode)] + pub struct QueuedParathread { + claim: primitives::ParathreadEntry, + core_offset: u32, + } + + #[derive(Encode, Decode, Default)] + pub struct ParathreadClaimQueue { + queue: Vec, + next_core_offset: u32, + } + + // Only here to facilitate the migration. + impl ParathreadClaimQueue { + pub fn len(self) -> usize { + self.queue.len() + } + } + + #[storage_alias] + pub(super) type ParathreadQueue = + StorageValue, ParathreadClaimQueue, ValueQuery>; + + #[storage_alias] + pub(super) type ParathreadClaimIndex = + StorageValue, Vec, ValueQuery>; + + /// The assignment type. + #[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] + #[cfg_attr(feature = "std", derive(PartialEq))] + pub enum AssignmentKind { + /// A parachain. + Parachain, + /// A parathread. + Parathread(CollatorId, u32), + } + + /// How a free core is scheduled to be assigned. + #[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] + #[cfg_attr(feature = "std", derive(PartialEq))] + pub struct CoreAssignment { + /// The core that is assigned. + pub core: CoreIndex, + /// The unique ID of the para that is assigned to the core. + pub para_id: ParaId, + /// The kind of the assignment. + pub kind: AssignmentKind, + /// The index of the validator group assigned to the core. + pub group_idx: GroupIndex, + } +} + +pub mod v1 { + use super::*; + use crate::scheduler; + use frame_support::traits::StorageVersion; + + pub struct MigrateToV1(sp_std::marker::PhantomData); + impl OnRuntimeUpgrade for MigrateToV1 { + fn on_runtime_upgrade() -> Weight { + if StorageVersion::get::>() == 0 { + let weight_consumed = migrate_to_v1::(); + + log::info!(target: scheduler::LOG_TARGET, "Migrating para scheduler storage to v1"); + StorageVersion::new(1).put::>(); + + weight_consumed + } else { + log::warn!(target: scheduler::LOG_TARGET, "Para scheduler v1 migration should be removed."); + T::DbWeight::get().reads(1) + } + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::DispatchError> { + log::trace!( + target: crate::scheduler::LOG_TARGET, + "Scheduled before migration: {}", + v0::Scheduled::::get().len() + ); + + let bytes = u32::to_be_bytes(v0::Scheduled::::get().len() as u32); + + Ok(bytes.to_vec()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(state: Vec) -> Result<(), sp_runtime::DispatchError> { + log::trace!(target: crate::scheduler::LOG_TARGET, "Running post_upgrade()"); + ensure!( + StorageVersion::get::>() >= 1, + "Storage version should be at least `1` after the migration" + ); + ensure!( + v0::Scheduled::::get().len() == 0, + "Scheduled should be empty after the migration" + ); + + let sched_len = u32::from_be_bytes(state.try_into().unwrap()); + ensure!( + Pallet::::claimqueue_len() as u32 == sched_len, + "Scheduled completely moved to ClaimQueue after migration" + ); + + Ok(()) + } + } +} + +pub fn migrate_to_v1() -> Weight { + let mut weight: Weight = Weight::zero(); + + let pq = v0::ParathreadQueue::::take(); + let pq_len = pq.len() as u64; + + let pci = v0::ParathreadClaimIndex::::take(); + let pci_len = pci.len() as u64; + + let now = >::block_number(); + let scheduled = v0::Scheduled::::take(); + let sched_len = scheduled.len() as u64; + for core_assignment in scheduled { + let core_idx = core_assignment.core; + let assignment = Assignment::new(core_assignment.para_id); + let pe = ParasEntry::new(assignment, now); + Pallet::::add_to_claimqueue(core_idx, pe); + } + + // 2x as once for Scheduled and once for Claimqueue + weight = weight.saturating_add(T::DbWeight::get().reads_writes(2 * sched_len, 2 * sched_len)); + weight = weight.saturating_add(T::DbWeight::get().reads_writes(pq_len, pq_len)); + weight = weight.saturating_add(T::DbWeight::get().reads_writes(pci_len, pci_len)); + + weight +} diff --git a/polkadot/runtime/parachains/src/scheduler/tests.rs b/polkadot/runtime/parachains/src/scheduler/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..e203531ca49d2f985a32f32421db2ac49e2ac1cf --- /dev/null +++ b/polkadot/runtime/parachains/src/scheduler/tests.rs @@ -0,0 +1,1531 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use frame_support::assert_ok; +use keyring::Sr25519Keyring; +use primitives::{v5::Assignment, BlockNumber, SessionIndex, ValidationCode, ValidatorId}; +use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet}; + +use crate::{ + assigner_on_demand::QueuePushDirection, + configuration::HostConfiguration, + initializer::SessionChangeNotification, + mock::{ + new_test_ext, MockGenesisConfig, OnDemandAssigner, Paras, ParasShared, RuntimeOrigin, + Scheduler, System, Test, + }, + paras::{ParaGenesisArgs, ParaKind}, +}; + +fn schedule_blank_para(id: ParaId, parakind: ParaKind) { + let validation_code: ValidationCode = vec![1, 2, 3].into(); + assert_ok!(Paras::schedule_para_initialize( + id, + ParaGenesisArgs { + genesis_head: Vec::new().into(), + validation_code: validation_code.clone(), + para_kind: parakind, + } + )); + + assert_ok!(Paras::add_trusted_validation_code(RuntimeOrigin::root(), validation_code)); +} + +fn run_to_block( + to: BlockNumber, + new_session: impl Fn(BlockNumber) -> Option>, +) { + while System::block_number() < to { + let b = System::block_number(); + + Scheduler::initializer_finalize(); + Paras::initializer_finalize(b); + + if let Some(notification) = new_session(b + 1) { + let mut notification_with_session_index = notification; + // We will make every session change trigger an action queue. Normally this may require + // 2 or more session changes. + if notification_with_session_index.session_index == SessionIndex::default() { + notification_with_session_index.session_index = ParasShared::scheduled_session(); + } + Scheduler::pre_new_session(); + + Paras::initializer_on_new_session(¬ification_with_session_index); + Scheduler::initializer_on_new_session(¬ification_with_session_index); + } + + System::on_finalize(b); + + System::on_initialize(b + 1); + System::set_block_number(b + 1); + + Paras::initializer_initialize(b + 1); + Scheduler::initializer_initialize(b + 1); + + // In the real runtime this is expected to be called by the `InclusionInherent` pallet. + Scheduler::update_claimqueue(BTreeMap::new(), b + 1); + } +} + +fn run_to_end_of_block( + to: BlockNumber, + new_session: impl Fn(BlockNumber) -> Option>, +) { + run_to_block(to, &new_session); + + Scheduler::initializer_finalize(); + Paras::initializer_finalize(to); + + if let Some(notification) = new_session(to + 1) { + Scheduler::pre_new_session(); + + Paras::initializer_on_new_session(¬ification); + Scheduler::initializer_on_new_session(¬ification); + } + + System::on_finalize(to); +} + +fn default_config() -> HostConfiguration { + HostConfiguration { + on_demand_cores: 3, + group_rotation_frequency: 10, + paras_availability_period: 3, + scheduling_lookahead: 2, + on_demand_retries: 1, + // This field does not affect anything that scheduler does. However, `HostConfiguration` + // is still a subject to consistency test. It requires that + // `minimum_validation_upgrade_delay` is greater than `chain_availability_period` and + // `thread_availability_period`. + minimum_validation_upgrade_delay: 6, + ..Default::default() + } +} + +fn genesis_config(config: &HostConfiguration) -> MockGenesisConfig { + MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { config: config.clone() }, + ..Default::default() + } +} + +pub(crate) fn claimqueue_contains_only_none() -> bool { + let mut cq = Scheduler::claimqueue(); + for (_, v) in cq.iter_mut() { + v.retain(|e| e.is_some()); + } + + cq.values().map(|v| v.len()).sum::() == 0 +} + +pub(crate) fn claimqueue_contains_para_ids(pids: Vec) -> bool { + let set: BTreeSet = ClaimQueue::::get() + .into_iter() + .flat_map(|(_, assignments)| { + assignments + .into_iter() + .filter_map(|assignment| assignment.and_then(|pe| Some(pe.para_id()))) + }) + .collect(); + + pids.into_iter().all(|pid| set.contains(&pid)) +} + +pub(crate) fn availability_cores_contains_para_ids(pids: Vec) -> bool { + let set: BTreeSet = AvailabilityCores::::get() + .into_iter() + .filter_map(|core| match core { + CoreOccupied::Free => None, + CoreOccupied::Paras(entry) => Some(entry.para_id()), + }) + .collect(); + + pids.into_iter().all(|pid| set.contains(&pid)) +} + +#[test] +fn claimqueue_ttl_drop_fn_works() { + let mut config = default_config(); + config.scheduling_lookahead = 3; + let genesis_config = genesis_config(&config); + + let para_id = ParaId::from(100); + let core_idx = CoreIndex::from(0); + let mut now = 10; + + new_test_ext(genesis_config).execute_with(|| { + assert!(default_config().on_demand_ttl == 5); + // Register and run to a blockheight where the para is in a valid state. + schedule_blank_para(para_id, ParaKind::Parathread); + run_to_block(10, |n| if n == 10 { Some(Default::default()) } else { None }); + + // Add a claim on core 0 with a ttl in the past. + let paras_entry = ParasEntry::new(Assignment::new(para_id), now - 5); + Scheduler::add_to_claimqueue(core_idx, paras_entry.clone()); + + // Claim is in queue prior to call. + assert!(claimqueue_contains_para_ids::(vec![para_id])); + + // Claim is dropped post call. + Scheduler::drop_expired_claims_from_claimqueue(); + assert!(!claimqueue_contains_para_ids::(vec![para_id])); + + // Add a claim on core 0 with a ttl in the future (15). + let paras_entry = ParasEntry::new(Assignment::new(para_id), now + 5); + Scheduler::add_to_claimqueue(core_idx, paras_entry.clone()); + + // Claim is in queue post call. + Scheduler::drop_expired_claims_from_claimqueue(); + assert!(claimqueue_contains_para_ids::(vec![para_id])); + + now = now + 6; + run_to_block(now, |_| None); + + // Claim is dropped + Scheduler::drop_expired_claims_from_claimqueue(); + assert!(!claimqueue_contains_para_ids::(vec![para_id])); + + // Add a claim on core 0 with a ttl == now (16) + let paras_entry = ParasEntry::new(Assignment::new(para_id), now); + Scheduler::add_to_claimqueue(core_idx, paras_entry.clone()); + + // Claim is in queue post call. + Scheduler::drop_expired_claims_from_claimqueue(); + assert!(claimqueue_contains_para_ids::(vec![para_id])); + + now = now + 1; + run_to_block(now, |_| None); + + // Drop expired claim. + Scheduler::drop_expired_claims_from_claimqueue(); + + // Add a claim on core 0 with a ttl == now (17) + let paras_entry_non_expired = ParasEntry::new(Assignment::new(para_id), now); + let paras_entry_expired = ParasEntry::new(Assignment::new(para_id), now - 2); + // ttls = [17, 15, 17] + Scheduler::add_to_claimqueue(core_idx, paras_entry_non_expired.clone()); + Scheduler::add_to_claimqueue(core_idx, paras_entry_expired.clone()); + Scheduler::add_to_claimqueue(core_idx, paras_entry_non_expired.clone()); + let cq = Scheduler::claimqueue(); + assert!(cq.get(&core_idx).unwrap().len() == 3); + + // Add claims to on demand assignment provider. + let assignment = Assignment::new(para_id); + + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment.clone(), + QueuePushDirection::Back + )); + + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment, + QueuePushDirection::Back + )); + + // Drop expired claim. + Scheduler::drop_expired_claims_from_claimqueue(); + + let cq = Scheduler::claimqueue(); + let cqc = cq.get(&core_idx).unwrap(); + // Same number of claims + assert!(cqc.len() == 3); + + // The first 2 claims in the queue should have a ttl of 17, + // being the ones set up prior in this test as claims 1 and 3. + // The third claim is popped from the assignment provider and + // has a new ttl set by the scheduler of now + config.on_demand_ttl. + // ttls = [17, 17, 22] + assert!(cqc.iter().enumerate().all(|(index, entry)| { + match index { + 0 | 1 => return entry.clone().unwrap().ttl == 17, + 2 => return entry.clone().unwrap().ttl == 22, + _ => return false, + } + })) + }); +} + +// Pretty useless here. Should be on parathread assigner... if at all +#[test] +fn add_parathread_claim_works() { + let genesis_config = genesis_config(&default_config()); + + let thread_id = ParaId::from(10); + let core_index = CoreIndex::from(0); + let entry_ttl = 10_000; + + new_test_ext(genesis_config).execute_with(|| { + schedule_blank_para(thread_id, ParaKind::Parathread); + + assert!(!Paras::is_parathread(thread_id)); + + run_to_block(10, |n| if n == 10 { Some(Default::default()) } else { None }); + + assert!(Paras::is_parathread(thread_id)); + + let pe = ParasEntry::new(Assignment::new(thread_id), entry_ttl); + Scheduler::add_to_claimqueue(core_index, pe.clone()); + + let cq = Scheduler::claimqueue(); + assert_eq!(Scheduler::claimqueue_len(), 1); + assert_eq!(*(cq.get(&core_index).unwrap().front().unwrap()), Some(pe)); + }) +} + +#[test] +fn session_change_shuffles_validators() { + let genesis_config = genesis_config(&default_config()); + + assert_eq!(default_config().on_demand_cores, 3); + new_test_ext(genesis_config).execute_with(|| { + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + + // ensure that we have 5 groups by registering 2 parachains. + schedule_blank_para(chain_a, ParaKind::Parachain); + schedule_blank_para(chain_b, ParaKind::Parachain); + + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: default_config(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Bob.public()), + ValidatorId::from(Sr25519Keyring::Charlie.public()), + ValidatorId::from(Sr25519Keyring::Dave.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ValidatorId::from(Sr25519Keyring::Ferdie.public()), + ValidatorId::from(Sr25519Keyring::One.public()), + ], + random_seed: [99; 32], + ..Default::default() + }), + _ => None, + }); + + let groups = ValidatorGroups::::get(); + assert_eq!(groups.len(), 5); + + // first two groups have the overflow. + for i in 0..2 { + assert_eq!(groups[i].len(), 2); + } + + for i in 2..5 { + assert_eq!(groups[i].len(), 1); + } + }); +} + +#[test] +fn session_change_takes_only_max_per_core() { + let config = { + let mut config = default_config(); + config.on_demand_cores = 0; + config.max_validators_per_core = Some(1); + config + }; + + let genesis_config = genesis_config(&config); + + new_test_ext(genesis_config).execute_with(|| { + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + let chain_c = ParaId::from(3_u32); + + // ensure that we have 5 groups by registering 2 parachains. + schedule_blank_para(chain_a, ParaKind::Parachain); + schedule_blank_para(chain_b, ParaKind::Parachain); + schedule_blank_para(chain_c, ParaKind::Parathread); + + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: config.clone(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Bob.public()), + ValidatorId::from(Sr25519Keyring::Charlie.public()), + ValidatorId::from(Sr25519Keyring::Dave.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ValidatorId::from(Sr25519Keyring::Ferdie.public()), + ValidatorId::from(Sr25519Keyring::One.public()), + ], + random_seed: [99; 32], + ..Default::default() + }), + _ => None, + }); + + let groups = ValidatorGroups::::get(); + assert_eq!(groups.len(), 7); + + // Every validator gets its own group, even though there are 2 paras. + for i in 0..7 { + assert_eq!(groups[i].len(), 1); + } + }); +} + +#[test] +fn fill_claimqueue_fills() { + let genesis_config = genesis_config(&default_config()); + + let lookahead = genesis_config.configuration.config.scheduling_lookahead as usize; + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + + let thread_a = ParaId::from(3_u32); + let thread_b = ParaId::from(4_u32); + let thread_c = ParaId::from(5_u32); + + let assignment_a = Assignment { para_id: thread_a }; + let assignment_b = Assignment { para_id: thread_b }; + let assignment_c = Assignment { para_id: thread_c }; + + new_test_ext(genesis_config).execute_with(|| { + assert_eq!(default_config().on_demand_cores, 3); + + // register 2 lease holding parachains + schedule_blank_para(chain_a, ParaKind::Parachain); + schedule_blank_para(chain_b, ParaKind::Parachain); + + // and 3 parathreads (on-demand parachains) + schedule_blank_para(thread_a, ParaKind::Parathread); + schedule_blank_para(thread_b, ParaKind::Parathread); + schedule_blank_para(thread_c, ParaKind::Parathread); + + // start a new session to activate, 5 validators for 5 cores. + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: default_config(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Bob.public()), + ValidatorId::from(Sr25519Keyring::Charlie.public()), + ValidatorId::from(Sr25519Keyring::Dave.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ], + ..Default::default() + }), + _ => None, + }); + + { + assert_eq!(Scheduler::claimqueue_len(), 2 * lookahead); + let scheduled = Scheduler::scheduled_claimqueue(); + + // Cannot assert on indices anymore as they depend on the assignment providers + assert!(claimqueue_contains_para_ids::(vec![chain_a, chain_b])); + + assert_eq!( + scheduled[0], + CoreAssignment { + core: CoreIndex(0), + paras_entry: ParasEntry { + assignment: Assignment { para_id: chain_a }, + availability_timeouts: 0, + ttl: 6 + }, + } + ); + + assert_eq!( + scheduled[1], + CoreAssignment { + core: CoreIndex(1), + paras_entry: ParasEntry { + assignment: Assignment { para_id: chain_b }, + availability_timeouts: 0, + ttl: 6 + }, + } + ); + } + + // add a couple of parathread assignments. + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_a, + QueuePushDirection::Back + )); + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_b, + QueuePushDirection::Back + )); + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_c, + QueuePushDirection::Back + )); + + run_to_block(2, |_| None); + // cores 0 and 1 should be occupied. mark them as such. + Scheduler::occupied( + vec![(CoreIndex(0), chain_a), (CoreIndex(1), chain_b)].into_iter().collect(), + ); + + run_to_block(3, |_| None); + + { + assert_eq!(Scheduler::claimqueue_len(), 5); + let scheduled = Scheduler::scheduled_claimqueue(); + + assert_eq!( + scheduled[0], + CoreAssignment { + core: CoreIndex(0), + paras_entry: ParasEntry { + assignment: Assignment { para_id: chain_a }, + availability_timeouts: 0, + ttl: 6 + }, + } + ); + assert_eq!( + scheduled[1], + CoreAssignment { + core: CoreIndex(1), + paras_entry: ParasEntry { + assignment: Assignment { para_id: chain_b }, + availability_timeouts: 0, + ttl: 6 + }, + } + ); + + // Was added a block later, note the TTL. + assert_eq!( + scheduled[2], + CoreAssignment { + core: CoreIndex(2), + paras_entry: ParasEntry { + assignment: Assignment { para_id: thread_a }, + availability_timeouts: 0, + ttl: 7 + }, + } + ); + // Sits on the same core as `thread_a` + assert_eq!( + Scheduler::claimqueue().get(&CoreIndex(2)).unwrap()[1], + Some(ParasEntry { + assignment: Assignment { para_id: thread_b }, + availability_timeouts: 0, + ttl: 7 + }) + ); + assert_eq!( + scheduled[3], + CoreAssignment { + core: CoreIndex(3), + paras_entry: ParasEntry { + assignment: Assignment { para_id: thread_c }, + availability_timeouts: 0, + ttl: 7 + }, + } + ); + } + }); +} + +#[test] +fn schedule_schedules_including_just_freed() { + let mut config = default_config(); + // NOTE: This test expects on demand cores to each get slotted on to a different core + // and not fill up the claimqueue of each core first. + config.scheduling_lookahead = 1; + let genesis_config = genesis_config(&config); + + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + + let thread_a = ParaId::from(3_u32); + let thread_b = ParaId::from(4_u32); + let thread_c = ParaId::from(5_u32); + let thread_d = ParaId::from(6_u32); + let thread_e = ParaId::from(7_u32); + + let assignment_a = Assignment { para_id: thread_a }; + let assignment_b = Assignment { para_id: thread_b }; + let assignment_c = Assignment { para_id: thread_c }; + let assignment_d = Assignment { para_id: thread_d }; + let assignment_e = Assignment { para_id: thread_e }; + + new_test_ext(genesis_config).execute_with(|| { + assert_eq!(default_config().on_demand_cores, 3); + + // register 2 lease holding parachains + schedule_blank_para(chain_a, ParaKind::Parachain); + schedule_blank_para(chain_b, ParaKind::Parachain); + + // and 5 parathreads (on-demand parachains) + schedule_blank_para(thread_a, ParaKind::Parathread); + schedule_blank_para(thread_b, ParaKind::Parathread); + schedule_blank_para(thread_c, ParaKind::Parathread); + schedule_blank_para(thread_d, ParaKind::Parathread); + schedule_blank_para(thread_e, ParaKind::Parathread); + + // start a new session to activate, 5 validators for 5 cores. + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: default_config(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Bob.public()), + ValidatorId::from(Sr25519Keyring::Charlie.public()), + ValidatorId::from(Sr25519Keyring::Dave.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ], + ..Default::default() + }), + _ => None, + }); + + // add a couple of parathread claims now that the parathreads are live. + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_a, + QueuePushDirection::Back + )); + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_c, + QueuePushDirection::Back + )); + + let mut now = 2; + run_to_block(now, |_| None); + + assert_eq!(Scheduler::scheduled_claimqueue().len(), 4); + + // cores 0, 1, 2, and 3 should be occupied. mark them as such. + let mut occupied_map: BTreeMap = BTreeMap::new(); + occupied_map.insert(CoreIndex(0), chain_a); + occupied_map.insert(CoreIndex(1), chain_b); + occupied_map.insert(CoreIndex(2), thread_a); + occupied_map.insert(CoreIndex(3), thread_c); + Scheduler::occupied(occupied_map); + + { + let cores = AvailabilityCores::::get(); + + // cores 0, 1, 2, and 3 are all `CoreOccupied::Paras(ParasEntry...)` + assert!(cores[0] != CoreOccupied::Free); + assert!(cores[1] != CoreOccupied::Free); + assert!(cores[2] != CoreOccupied::Free); + assert!(cores[3] != CoreOccupied::Free); + + // core 4 is free + assert!(cores[4] == CoreOccupied::Free); + + assert!(Scheduler::scheduled_claimqueue().is_empty()); + + // All core index entries in the claimqueue should have `None` in them. + Scheduler::claimqueue().iter().for_each(|(_core_idx, core_queue)| { + assert!(core_queue.iter().all(|claim| claim.is_none())) + }) + } + + // add a couple more parathread claims - the claim on `b` will go to the 3rd parathread core + // (4) and the claim on `d` will go back to the 1st parathread core (2). The claim on `e` + // then will go for core `3`. + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_b, + QueuePushDirection::Back + )); + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_d, + QueuePushDirection::Back + )); + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_e.clone(), + QueuePushDirection::Back + )); + now = 3; + run_to_block(now, |_| None); + + { + let scheduled = Scheduler::scheduled_claimqueue(); + + // cores 0 and 1 are occupied by lease holding parachains. cores 2 and 3 are occupied by + // on-demand parachain claims. core 4 was free. + assert_eq!(scheduled.len(), 1); + assert_eq!( + scheduled[0], + CoreAssignment { + core: CoreIndex(4), + paras_entry: ParasEntry { + assignment: Assignment { para_id: thread_b }, + availability_timeouts: 0, + ttl: 8 + }, + } + ); + } + + // now note that cores 0, 2, and 3 were freed. + let just_updated: BTreeMap = vec![ + (CoreIndex(0), FreedReason::Concluded), + (CoreIndex(2), FreedReason::Concluded), + (CoreIndex(3), FreedReason::TimedOut), // should go back on queue. + ] + .into_iter() + .collect(); + Scheduler::update_claimqueue(just_updated, now); + + { + let scheduled = Scheduler::scheduled_claimqueue(); + + // 1 thing scheduled before, + 3 cores freed. + assert_eq!(scheduled.len(), 4); + assert_eq!( + scheduled[0], + CoreAssignment { + core: CoreIndex(0), + paras_entry: ParasEntry { + assignment: Assignment { para_id: chain_a }, + availability_timeouts: 0, + ttl: 8 + }, + } + ); + assert_eq!( + scheduled[1], + CoreAssignment { + core: CoreIndex(2), + paras_entry: ParasEntry { + assignment: Assignment { para_id: thread_d }, + availability_timeouts: 0, + ttl: 8 + }, + } + ); + // Although C was descheduled, the core `4` was occupied so C goes back to the queue. + assert_eq!( + scheduled[2], + CoreAssignment { + core: CoreIndex(3), + paras_entry: ParasEntry { + assignment: Assignment { para_id: thread_c }, + availability_timeouts: 1, + ttl: 8 + }, + } + ); + assert_eq!( + scheduled[3], + CoreAssignment { + core: CoreIndex(4), + paras_entry: ParasEntry { + assignment: Assignment { para_id: thread_b }, + availability_timeouts: 0, + ttl: 8 + }, + } + ); + + // The only assignment yet to be popped on to the claim queue is `thread_e`. + // This is due to `thread_c` timing out. + let order_queue = OnDemandAssigner::get_queue(); + assert!(order_queue.len() == 1); + assert!(order_queue[0] == assignment_e); + + // Chain B's core was not marked concluded or timed out, it should be on an + // availability core + assert!(availability_cores_contains_para_ids::(vec![chain_b])); + // Thread A claim should have been wiped, but thread C claim should remain. + assert!(!claimqueue_contains_para_ids::(vec![thread_a])); + assert!(claimqueue_contains_para_ids::(vec![thread_c])); + assert!(!availability_cores_contains_para_ids::(vec![thread_a, thread_c])); + } + }); +} + +#[test] +fn schedule_clears_availability_cores() { + let mut config = default_config(); + config.scheduling_lookahead = 1; + let genesis_config = genesis_config(&config); + + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + let chain_c = ParaId::from(3_u32); + + new_test_ext(genesis_config).execute_with(|| { + assert_eq!(default_config().on_demand_cores, 3); + + // register 3 parachains + schedule_blank_para(chain_a, ParaKind::Parachain); + schedule_blank_para(chain_b, ParaKind::Parachain); + schedule_blank_para(chain_c, ParaKind::Parachain); + + // start a new session to activate, 5 validators for 5 cores. + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: default_config(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Bob.public()), + ValidatorId::from(Sr25519Keyring::Charlie.public()), + ValidatorId::from(Sr25519Keyring::Dave.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ], + ..Default::default() + }), + _ => None, + }); + + run_to_block(2, |_| None); + + assert_eq!(Scheduler::claimqueue().len(), 3); + + // cores 0, 1, and 2 should be occupied. mark them as such. + Scheduler::occupied( + vec![(CoreIndex(0), chain_a), (CoreIndex(1), chain_b), (CoreIndex(2), chain_c)] + .into_iter() + .collect(), + ); + + { + let cores = AvailabilityCores::::get(); + + assert_eq!(cores[0].is_free(), false); + assert_eq!(cores[1].is_free(), false); + assert_eq!(cores[2].is_free(), false); + + assert!(claimqueue_contains_only_none()); + } + + run_to_block(3, |_| None); + + // now note that cores 0 and 2 were freed. + Scheduler::free_cores_and_fill_claimqueue( + vec![(CoreIndex(0), FreedReason::Concluded), (CoreIndex(2), FreedReason::Concluded)] + .into_iter() + .collect::>(), + 3, + ); + + { + let claimqueue = Scheduler::claimqueue(); + let claimqueue_0 = claimqueue.get(&CoreIndex(0)).unwrap().clone(); + let claimqueue_2 = claimqueue.get(&CoreIndex(2)).unwrap().clone(); + let entry_ttl = 8; + assert_eq!(claimqueue_0.len(), 1); + assert_eq!(claimqueue_2.len(), 1); + assert_eq!( + claimqueue_0, + vec![Some(ParasEntry::new(Assignment::new(chain_a), entry_ttl))], + ); + assert_eq!( + claimqueue_2, + vec![Some(ParasEntry::new(Assignment::new(chain_c), entry_ttl))], + ); + + // The freed cores should be `Free` in `AvailabilityCores`. + let cores = AvailabilityCores::::get(); + assert!(cores[0].is_free()); + assert!(cores[2].is_free()); + } + }); +} + +#[test] +fn schedule_rotates_groups() { + let config = { + let mut config = default_config(); + + // make sure on demand requests don't retry-out + config.on_demand_retries = config.group_rotation_frequency * 3; + config.on_demand_cores = 2; + config.scheduling_lookahead = 1; + config + }; + + let rotation_frequency = config.group_rotation_frequency; + let on_demand_cores = config.on_demand_cores; + + let genesis_config = genesis_config(&config); + + let thread_a = ParaId::from(1_u32); + let thread_b = ParaId::from(2_u32); + + let assignment_a = Assignment { para_id: thread_a }; + let assignment_b = Assignment { para_id: thread_b }; + + new_test_ext(genesis_config).execute_with(|| { + assert_eq!(default_config().on_demand_cores, 3); + + schedule_blank_para(thread_a, ParaKind::Parathread); + schedule_blank_para(thread_b, ParaKind::Parathread); + + // start a new session to activate, 5 validators for 5 cores. + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: config.clone(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ], + ..Default::default() + }), + _ => None, + }); + + let session_start_block = Scheduler::session_start_block(); + assert_eq!(session_start_block, 1); + + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_a, + QueuePushDirection::Back + )); + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_b, + QueuePushDirection::Back + )); + + let mut now = 2; + run_to_block(now, |_| None); + + let assert_groups_rotated = |rotations: u32, now: &BlockNumberFor| { + let scheduled = Scheduler::scheduled_claimqueue(); + assert_eq!(scheduled.len(), 2); + assert_eq!( + Scheduler::group_assigned_to_core(scheduled[0].core, *now).unwrap(), + GroupIndex((0u32 + rotations) % on_demand_cores) + ); + assert_eq!( + Scheduler::group_assigned_to_core(scheduled[1].core, *now).unwrap(), + GroupIndex((1u32 + rotations) % on_demand_cores) + ); + }; + + assert_groups_rotated(0, &now); + + // one block before first rotation. + now = rotation_frequency; + run_to_block(rotation_frequency, |_| None); + + assert_groups_rotated(0, &now); + + // first rotation. + now = now + 1; + run_to_block(now, |_| None); + assert_groups_rotated(1, &now); + + // one block before second rotation. + now = rotation_frequency * 2; + run_to_block(now, |_| None); + assert_groups_rotated(1, &now); + + // second rotation. + now = now + 1; + run_to_block(now, |_| None); + assert_groups_rotated(2, &now); + }); +} + +#[test] +fn on_demand_claims_are_pruned_after_timing_out() { + let max_retries = 20; + let mut config = default_config(); + config.scheduling_lookahead = 1; + config.on_demand_cores = 2; + config.on_demand_retries = max_retries; + let genesis_config = genesis_config(&config); + + let thread_a = ParaId::from(1_u32); + + let assignment_a = Assignment { para_id: thread_a }; + + new_test_ext(genesis_config).execute_with(|| { + schedule_blank_para(thread_a, ParaKind::Parathread); + + // #1 + let mut now = 1; + run_to_block(now, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: default_config(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ], + ..Default::default() + }), + _ => None, + }); + + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_a.clone(), + QueuePushDirection::Back + )); + + // #2 + now += 1; + run_to_block(now, |_| None); + assert_eq!(Scheduler::claimqueue().len(), 1); + // ParaId a is in the claimqueue. + assert!(claimqueue_contains_para_ids::(vec![thread_a])); + + Scheduler::occupied(vec![(CoreIndex(0), thread_a)].into_iter().collect()); + // ParaId a is no longer in the claimqueue. + assert!(!claimqueue_contains_para_ids::(vec![thread_a])); + // It is in availability cores. + assert!(availability_cores_contains_para_ids::(vec![thread_a])); + + // #3 + now += 1; + // Run to block #n over the max_retries value. + // In this case, both validator groups with time out on availability and + // the assignment will be dropped. + for n in now..=(now + max_retries + 1) { + // #n + run_to_block(n, |_| None); + // Time out on core 0. + let just_updated: BTreeMap = vec![ + (CoreIndex(0), FreedReason::TimedOut), // should go back on queue. + ] + .into_iter() + .collect(); + let core_assignments = Scheduler::update_claimqueue(just_updated, now); + + // ParaId a exists in the claim queue until max_retries is reached. + if n < max_retries + now { + assert!(claimqueue_contains_para_ids::(vec![thread_a])); + } else { + assert!(!claimqueue_contains_para_ids::(vec![thread_a])); + } + + // Occupy the cores based on the output of update_claimqueue. + Scheduler::occupied( + core_assignments + .iter() + .map(|core_assignment| (core_assignment.core, core_assignment.para_id())) + .collect(), + ); + } + + // ParaId a does not exist in the claimqueue/availability_cores after + // threshold has been reached. + assert!(!claimqueue_contains_para_ids::(vec![thread_a])); + assert!(!availability_cores_contains_para_ids::(vec![thread_a])); + + // #25 + now += max_retries + 2; + + // Add assignment back to the mix. + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_a.clone(), + QueuePushDirection::Back + )); + run_to_block(now, |_| None); + + assert!(claimqueue_contains_para_ids::(vec![thread_a])); + + // #26 + now += 1; + // Run to block #n but this time have group 1 conclude the availabilty. + for n in now..=(now + max_retries + 1) { + // #n + run_to_block(n, |_| None); + // Time out core 0 if group 0 is assigned to it, if group 1 is assigned, conclude. + let mut just_updated: BTreeMap = BTreeMap::new(); + if let Some(group) = Scheduler::group_assigned_to_core(CoreIndex(0), n) { + match group { + GroupIndex(0) => { + just_updated.insert(CoreIndex(0), FreedReason::TimedOut); // should go back on queue. + }, + GroupIndex(1) => { + just_updated.insert(CoreIndex(0), FreedReason::Concluded); + }, + _ => panic!("Should only have 2 groups here"), + } + } + + let core_assignments = Scheduler::update_claimqueue(just_updated, now); + + // ParaId a exists in the claim queue until groups are rotated. + if n < 31 { + assert!(claimqueue_contains_para_ids::(vec![thread_a])); + } else { + assert!(!claimqueue_contains_para_ids::(vec![thread_a])); + } + + // Occupy the cores based on the output of update_claimqueue. + Scheduler::occupied( + core_assignments + .iter() + .map(|core_assignment| (core_assignment.core, core_assignment.para_id())) + .collect(), + ); + } + + // ParaId a does not exist in the claimqueue/availability_cores after + // being concluded + assert!(!claimqueue_contains_para_ids::(vec![thread_a])); + assert!(!availability_cores_contains_para_ids::(vec![thread_a])); + }); +} + +#[test] +fn availability_predicate_works() { + let genesis_config = genesis_config(&default_config()); + + let HostConfiguration { group_rotation_frequency, paras_availability_period, .. } = + default_config(); + + assert!(paras_availability_period < group_rotation_frequency); + + let chain_a = ParaId::from(1_u32); + let thread_a = ParaId::from(2_u32); + + new_test_ext(genesis_config).execute_with(|| { + schedule_blank_para(chain_a, ParaKind::Parachain); + schedule_blank_para(thread_a, ParaKind::Parathread); + + // start a new session with our chain registered. + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: default_config(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Bob.public()), + ValidatorId::from(Sr25519Keyring::Charlie.public()), + ValidatorId::from(Sr25519Keyring::Dave.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ], + ..Default::default() + }), + _ => None, + }); + + // assign some availability cores. + { + let entry_ttl = 10_000; + AvailabilityCores::::mutate(|cores| { + cores[0] = + CoreOccupied::Paras(ParasEntry::new(Assignment::new(chain_a), entry_ttl)); + cores[1] = + CoreOccupied::Paras(ParasEntry::new(Assignment::new(thread_a), entry_ttl)); + }); + } + + run_to_block(1 + paras_availability_period, |_| None); + + assert!(Scheduler::availability_timeout_predicate().is_none()); + + run_to_block(1 + group_rotation_frequency, |_| None); + + { + let pred = Scheduler::availability_timeout_predicate() + .expect("predicate exists recently after rotation"); + + let now = System::block_number(); + let would_be_timed_out = now - paras_availability_period; + for i in 0..AvailabilityCores::::get().len() { + // returns true for unoccupied cores. + // And can time out paras at this stage. + assert!(pred(CoreIndex(i as u32), would_be_timed_out)); + } + + assert!(!pred(CoreIndex(0), now)); + assert!(!pred(CoreIndex(1), now)); + assert!(pred(CoreIndex(2), now)); + + // check the tight bound. + assert!(pred(CoreIndex(0), now - paras_availability_period)); + assert!(pred(CoreIndex(1), now - paras_availability_period)); + + // check the threshold is exact. + assert!(!pred(CoreIndex(0), now - paras_availability_period + 1)); + assert!(!pred(CoreIndex(1), now - paras_availability_period + 1)); + } + + run_to_block(1 + group_rotation_frequency + paras_availability_period, |_| None); + }); +} + +#[test] +fn next_up_on_available_uses_next_scheduled_or_none_for_thread() { + let mut config = default_config(); + config.on_demand_cores = 1; + + let genesis_config = genesis_config(&config); + + let thread_a = ParaId::from(1_u32); + let thread_b = ParaId::from(2_u32); + + new_test_ext(genesis_config).execute_with(|| { + schedule_blank_para(thread_a, ParaKind::Parathread); + schedule_blank_para(thread_b, ParaKind::Parathread); + + // start a new session to activate, 5 validators for 5 cores. + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: config.clone(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ], + ..Default::default() + }), + _ => None, + }); + + let thread_entry_a = ParasEntry { + assignment: Assignment { para_id: thread_a }, + availability_timeouts: 0, + ttl: 5, + }; + let thread_entry_b = ParasEntry { + assignment: Assignment { para_id: thread_b }, + availability_timeouts: 0, + ttl: 5, + }; + + Scheduler::add_to_claimqueue(CoreIndex(0), thread_entry_a.clone()); + + run_to_block(2, |_| None); + + { + assert_eq!(Scheduler::claimqueue_len(), 1); + assert_eq!(Scheduler::availability_cores().len(), 1); + + let mut map = BTreeMap::new(); + map.insert(CoreIndex(0), thread_a); + Scheduler::occupied(map); + + let cores = Scheduler::availability_cores(); + match &cores[0] { + CoreOccupied::Paras(entry) => assert_eq!(entry, &thread_entry_a), + _ => panic!("with no chains, only core should be a thread core"), + } + + assert!(Scheduler::next_up_on_available(CoreIndex(0)).is_none()); + + Scheduler::add_to_claimqueue(CoreIndex(0), thread_entry_b); + + assert_eq!( + Scheduler::next_up_on_available(CoreIndex(0)).unwrap(), + ScheduledCore { para_id: thread_b, collator: None } + ); + } + }); +} + +#[test] +fn next_up_on_time_out_reuses_claim_if_nothing_queued() { + let mut config = default_config(); + config.on_demand_cores = 1; + + let genesis_config = genesis_config(&config); + + let thread_a = ParaId::from(1_u32); + let thread_b = ParaId::from(2_u32); + + let assignment_a = Assignment { para_id: thread_a }; + let assignment_b = Assignment { para_id: thread_b }; + + new_test_ext(genesis_config).execute_with(|| { + schedule_blank_para(thread_a, ParaKind::Parathread); + schedule_blank_para(thread_b, ParaKind::Parathread); + + // start a new session to activate, 5 validators for 5 cores. + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: config.clone(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ], + ..Default::default() + }), + _ => None, + }); + + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_a.clone(), + QueuePushDirection::Back + )); + + run_to_block(2, |_| None); + + { + assert_eq!(Scheduler::claimqueue().len(), 1); + assert_eq!(Scheduler::availability_cores().len(), 1); + + let mut map = BTreeMap::new(); + map.insert(CoreIndex(0), thread_a); + Scheduler::occupied(map); + + let cores = Scheduler::availability_cores(); + match cores.get(0).unwrap() { + CoreOccupied::Paras(entry) => assert_eq!(entry.assignment, assignment_a.clone()), + _ => panic!("with no chains, only core should be a thread core"), + } + + // There's nothing more to pop for core 0 from the assignment provider. + assert!( + OnDemandAssigner::pop_assignment_for_core(CoreIndex(0), Some(thread_a)).is_none() + ); + + assert_eq!( + Scheduler::next_up_on_time_out(CoreIndex(0)).unwrap(), + ScheduledCore { para_id: thread_a, collator: None } + ); + + assert_ok!(OnDemandAssigner::add_on_demand_assignment( + assignment_b.clone(), + QueuePushDirection::Back + )); + + // Pop assignment_b into the claimqueue + Scheduler::update_claimqueue(BTreeMap::new(), 2); + + //// Now that there is an earlier next-up, we use that. + assert_eq!( + Scheduler::next_up_on_available(CoreIndex(0)).unwrap(), + ScheduledCore { para_id: thread_b, collator: None } + ); + } + }); +} + +#[test] +fn next_up_on_available_is_parachain_always() { + let mut config = default_config(); + config.on_demand_cores = 0; + let genesis_config = genesis_config(&config); + let chain_a = ParaId::from(1_u32); + + new_test_ext(genesis_config).execute_with(|| { + schedule_blank_para(chain_a, ParaKind::Parachain); + + // start a new session to activate, 5 validators for 5 cores. + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: config.clone(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ], + ..Default::default() + }), + _ => None, + }); + + run_to_block(2, |_| None); + + { + assert_eq!(Scheduler::claimqueue().len(), 1); + assert_eq!(Scheduler::availability_cores().len(), 1); + + Scheduler::occupied(vec![(CoreIndex(0), chain_a)].into_iter().collect()); + + let cores = Scheduler::availability_cores(); + match &cores[0] { + CoreOccupied::Paras(pe) if pe.para_id() == chain_a => {}, + _ => panic!("with no threads, only core should be a chain core"), + } + + // Now that there is an earlier next-up, we use that. + assert_eq!( + Scheduler::next_up_on_available(CoreIndex(0)).unwrap(), + ScheduledCore { para_id: chain_a, collator: None } + ); + } + }); +} + +#[test] +fn next_up_on_time_out_is_parachain_always() { + let mut config = default_config(); + config.on_demand_cores = 0; + + let genesis_config = genesis_config(&config); + + let chain_a = ParaId::from(1_u32); + + new_test_ext(genesis_config).execute_with(|| { + schedule_blank_para(chain_a, ParaKind::Parachain); + + // start a new session to activate, 5 validators for 5 cores. + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: config.clone(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ], + ..Default::default() + }), + _ => None, + }); + + run_to_block(2, |_| None); + + { + assert_eq!(Scheduler::claimqueue().len(), 1); + assert_eq!(Scheduler::availability_cores().len(), 1); + + Scheduler::occupied(vec![(CoreIndex(0), chain_a)].into_iter().collect()); + + let cores = Scheduler::availability_cores(); + match &cores[0] { + CoreOccupied::Paras(pe) if pe.para_id() == chain_a => {}, + _ => panic!("Core should be occupied by chain_a ParaId"), + } + + // Now that there is an earlier next-up, we use that. + assert_eq!( + Scheduler::next_up_on_available(CoreIndex(0)).unwrap(), + ScheduledCore { para_id: chain_a, collator: None } + ); + } + }); +} + +#[test] +fn session_change_requires_reschedule_dropping_removed_paras() { + let mut config = default_config(); + config.scheduling_lookahead = 1; + let genesis_config = genesis_config(&config); + + assert_eq!(default_config().on_demand_cores, 3); + new_test_ext(genesis_config).execute_with(|| { + let chain_a = ParaId::from(1_u32); + let chain_b = ParaId::from(2_u32); + + // ensure that we have 5 groups by registering 2 parachains. + schedule_blank_para(chain_a, ParaKind::Parachain); + schedule_blank_para(chain_b, ParaKind::Parachain); + + run_to_block(1, |number| match number { + 1 => Some(SessionChangeNotification { + new_config: default_config(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Bob.public()), + ValidatorId::from(Sr25519Keyring::Charlie.public()), + ValidatorId::from(Sr25519Keyring::Dave.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ValidatorId::from(Sr25519Keyring::Ferdie.public()), + ValidatorId::from(Sr25519Keyring::One.public()), + ], + random_seed: [99; 32], + ..Default::default() + }), + _ => None, + }); + + assert_eq!(Scheduler::claimqueue().len(), 2); + + let groups = ValidatorGroups::::get(); + assert_eq!(groups.len(), 5); + + assert_ok!(Paras::schedule_para_cleanup(chain_b)); + run_to_end_of_block(2, |number| match number { + 2 => Some(SessionChangeNotification { + new_config: default_config(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Bob.public()), + ValidatorId::from(Sr25519Keyring::Charlie.public()), + ValidatorId::from(Sr25519Keyring::Dave.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ValidatorId::from(Sr25519Keyring::Ferdie.public()), + ValidatorId::from(Sr25519Keyring::One.public()), + ], + random_seed: [99; 32], + ..Default::default() + }), + _ => None, + }); + + Scheduler::update_claimqueue(BTreeMap::new(), 3); + + assert_eq!( + Scheduler::claimqueue(), + vec![( + CoreIndex(0), + vec![Some(ParasEntry::new( + Assignment::new(chain_a), + // At end of block 2 + config.on_demand_ttl + 2 + ))] + .into_iter() + .collect() + )] + .into_iter() + .collect() + ); + + // Add parachain back + schedule_blank_para(chain_b, ParaKind::Parachain); + + run_to_block(3, |number| match number { + 3 => Some(SessionChangeNotification { + new_config: default_config(), + validators: vec![ + ValidatorId::from(Sr25519Keyring::Alice.public()), + ValidatorId::from(Sr25519Keyring::Bob.public()), + ValidatorId::from(Sr25519Keyring::Charlie.public()), + ValidatorId::from(Sr25519Keyring::Dave.public()), + ValidatorId::from(Sr25519Keyring::Eve.public()), + ValidatorId::from(Sr25519Keyring::Ferdie.public()), + ValidatorId::from(Sr25519Keyring::One.public()), + ], + random_seed: [99; 32], + ..Default::default() + }), + _ => None, + }); + + assert_eq!(Scheduler::claimqueue().len(), 2); + + let groups = ValidatorGroups::::get(); + assert_eq!(groups.len(), 5); + + Scheduler::update_claimqueue(BTreeMap::new(), 4); + + assert_eq!( + Scheduler::claimqueue(), + vec![ + ( + CoreIndex(0), + vec![Some(ParasEntry::new( + Assignment::new(chain_a), + // At block 3 + config.on_demand_ttl + 3 + ))] + .into_iter() + .collect() + ), + ( + CoreIndex(1), + vec![Some(ParasEntry::new( + Assignment::new(chain_b), + // At block 3 + config.on_demand_ttl + 3 + ))] + .into_iter() + .collect() + ), + ] + .into_iter() + .collect() + ); + }); +} diff --git a/polkadot/runtime/parachains/src/session_info.rs b/polkadot/runtime/parachains/src/session_info.rs new file mode 100644 index 0000000000000000000000000000000000000000..0043851be0f22ef50cabb1b5f9f9fd51e9b5e188 --- /dev/null +++ b/polkadot/runtime/parachains/src/session_info.rs @@ -0,0 +1,229 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The session info pallet provides information about validator sets +//! from prior sessions needed for approvals and disputes. +//! +//! See . + +use crate::{ + configuration, paras, scheduler, shared, + util::{take_active_subset, take_active_subset_and_inactive}, +}; +use frame_support::{ + pallet_prelude::*, + traits::{OneSessionHandler, ValidatorSet, ValidatorSetWithIdentification}, +}; +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::{AssignmentId, AuthorityDiscoveryId, ExecutorParams, SessionIndex, SessionInfo}; +use sp_std::vec::Vec; + +pub use pallet::*; + +pub mod migration; + +#[cfg(test)] +mod tests; + +/// A type for representing the validator account id in a session. +pub type AccountId = <::ValidatorSet as ValidatorSet< + ::AccountId, +>>::ValidatorId; + +/// A tuple of `(AccountId, Identification)` where `Identification` +/// is the full identification of `AccountId`. +pub type IdentificationTuple = ( + AccountId, + <::ValidatorSet as ValidatorSetWithIdentification< + ::AccountId, + >>::Identification, +); + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::storage_version(migration::STORAGE_VERSION)] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: + frame_system::Config + + configuration::Config + + shared::Config + + paras::Config + + scheduler::Config + + AuthorityDiscoveryConfig + { + /// A type for retrieving `AccountId`s of the validators in the current session. + /// These are stash keys of the validators. + /// It's used for rewards and slashing. `Identification` is only needed for slashing. + type ValidatorSet: ValidatorSetWithIdentification; + } + + /// Assignment keys for the current session. + /// Note that this API is private due to it being prone to 'off-by-one' at session boundaries. + /// When in doubt, use `Sessions` API instead. + #[pallet::storage] + pub(super) type AssignmentKeysUnsafe = + StorageValue<_, Vec, ValueQuery>; + + /// The earliest session for which previous session info is stored. + #[pallet::storage] + #[pallet::getter(fn earliest_stored_session)] + pub(crate) type EarliestStoredSession = StorageValue<_, SessionIndex, ValueQuery>; + + /// Session information in a rolling window. + /// Should have an entry in range `EarliestStoredSession..=CurrentSessionIndex`. + /// Does not have any entries before the session index in the first session change notification. + #[pallet::storage] + #[pallet::getter(fn session_info)] + pub(crate) type Sessions = StorageMap<_, Identity, SessionIndex, SessionInfo>; + + /// The validator account keys of the validators actively participating in parachain consensus. + // We do not store this in `SessionInfo` to avoid leaking the `AccountId` type to the client, + // which would complicate the migration process if we are to change it in the future. + #[pallet::storage] + #[pallet::getter(fn account_keys)] + pub(crate) type AccountKeys = + StorageMap<_, Identity, SessionIndex, Vec>>; + + /// Executor parameter set for a given session index + #[pallet::storage] + #[pallet::getter(fn session_executor_params)] + pub(crate) type SessionExecutorParams = + StorageMap<_, Identity, SessionIndex, ExecutorParams>; +} + +/// An abstraction for the authority discovery pallet +/// to help with mock testing. +pub trait AuthorityDiscoveryConfig { + /// Retrieve authority identifiers of the current authority set in canonical ordering. + fn authorities() -> Vec; +} + +impl AuthorityDiscoveryConfig for T { + fn authorities() -> Vec { + >::current_authorities().to_vec() + } +} + +impl Pallet { + /// Handle an incoming session change. + pub(crate) fn initializer_on_new_session( + notification: &crate::initializer::SessionChangeNotification>, + ) { + let config = >::config(); + + let dispute_period = config.dispute_period; + + let validators = notification.validators.clone().into(); + let discovery_keys = ::authorities(); + let assignment_keys = AssignmentKeysUnsafe::::get(); + let active_set = >::active_validator_indices(); + + let validator_groups = >::validator_groups().into(); + let n_cores = >::availability_cores().len() as u32; + let zeroth_delay_tranche_width = config.zeroth_delay_tranche_width; + let relay_vrf_modulo_samples = config.relay_vrf_modulo_samples; + let n_delay_tranches = config.n_delay_tranches; + let no_show_slots = config.no_show_slots; + let needed_approvals = config.needed_approvals; + + let new_session_index = notification.session_index; + let random_seed = notification.random_seed; + let old_earliest_stored_session = EarliestStoredSession::::get(); + let new_earliest_stored_session = new_session_index.saturating_sub(dispute_period); + let new_earliest_stored_session = + core::cmp::max(new_earliest_stored_session, old_earliest_stored_session); + // remove all entries from `Sessions` from the previous value up to the new value + // avoid a potentially heavy loop when introduced on a live chain + if old_earliest_stored_session != 0 || Sessions::::get(0).is_some() { + for idx in old_earliest_stored_session..new_earliest_stored_session { + Sessions::::remove(&idx); + // Idx will be missing for a few sessions after the runtime upgrade. + // But it shouldn'be be a problem. + AccountKeys::::remove(&idx); + SessionExecutorParams::::remove(&idx); + } + // update `EarliestStoredSession` based on `config.dispute_period` + EarliestStoredSession::::set(new_earliest_stored_session); + } else { + // just introduced on a live chain + EarliestStoredSession::::set(new_session_index); + } + + // The validator set is guaranteed to be of the current session + // because we delay `on_new_session` till the end of the block. + let account_ids = T::ValidatorSet::validators(); + let active_account_ids = take_active_subset(&active_set, &account_ids); + AccountKeys::::insert(&new_session_index, &active_account_ids); + + // create a new entry in `Sessions` with information about the current session + let new_session_info = SessionInfo { + validators, // these are from the notification and are thus already correct. + discovery_keys: take_active_subset_and_inactive(&active_set, &discovery_keys), + assignment_keys: take_active_subset(&active_set, &assignment_keys), + validator_groups, + n_cores, + zeroth_delay_tranche_width, + relay_vrf_modulo_samples, + n_delay_tranches, + no_show_slots, + needed_approvals, + active_validator_indices: active_set, + random_seed, + dispute_period, + }; + Sessions::::insert(&new_session_index, &new_session_info); + + SessionExecutorParams::::insert(&new_session_index, config.executor_params); + } + + /// Called by the initializer to initialize the session info pallet. + pub(crate) fn initializer_initialize(_now: BlockNumberFor) -> Weight { + Weight::zero() + } + + /// Called by the initializer to finalize the session info pallet. + pub(crate) fn initializer_finalize() {} +} + +impl sp_runtime::BoundToRuntimeAppPublic for Pallet { + type Public = AssignmentId; +} + +impl OneSessionHandler for Pallet { + type Key = AssignmentId; + + fn on_genesis_session<'a, I: 'a>(_validators: I) + where + I: Iterator, + { + } + + fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, _queued: I) + where + I: Iterator, + { + let assignment_keys: Vec<_> = validators.map(|(_, v)| v).collect(); + AssignmentKeysUnsafe::::set(assignment_keys); + } + + fn on_disabled(_i: u32) {} +} diff --git a/polkadot/runtime/parachains/src/session_info/migration.rs b/polkadot/runtime/parachains/src/session_info/migration.rs new file mode 100644 index 0000000000000000000000000000000000000000..228c1e3bb2515b14f5fe59a89578b03be065955d --- /dev/null +++ b/polkadot/runtime/parachains/src/session_info/migration.rs @@ -0,0 +1,22 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A module that is responsible for migration of storage. + +use frame_support::traits::StorageVersion; + +/// The current storage version. +pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); diff --git a/polkadot/runtime/parachains/src/session_info/tests.rs b/polkadot/runtime/parachains/src/session_info/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..727b7c79fbaeae18be2c2a40f4f38f562d1481dd --- /dev/null +++ b/polkadot/runtime/parachains/src/session_info/tests.rs @@ -0,0 +1,211 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::{ + configuration::HostConfiguration, + initializer::SessionChangeNotification, + mock::{ + new_test_ext, Configuration, MockGenesisConfig, ParasShared, RuntimeOrigin, SessionInfo, + System, Test, + }, + util::take_active_subset, +}; +use keyring::Sr25519Keyring; +use primitives::{BlockNumber, ValidatorId, ValidatorIndex}; + +fn run_to_block( + to: BlockNumber, + new_session: impl Fn(BlockNumber) -> Option>, +) { + while System::block_number() < to { + let b = System::block_number(); + + SessionInfo::initializer_finalize(); + ParasShared::initializer_finalize(); + Configuration::initializer_finalize(); + + if let Some(notification) = new_session(b + 1) { + Configuration::initializer_on_new_session(¬ification.session_index); + ParasShared::initializer_on_new_session( + notification.session_index, + notification.random_seed, + ¬ification.new_config, + notification.validators.clone(), + ); + SessionInfo::initializer_on_new_session(¬ification); + } + + System::on_finalize(b); + + System::on_initialize(b + 1); + System::set_block_number(b + 1); + + Configuration::initializer_initialize(b + 1); + ParasShared::initializer_initialize(b + 1); + SessionInfo::initializer_initialize(b + 1); + } +} + +fn default_config() -> HostConfiguration { + HostConfiguration { + on_demand_cores: 1, + dispute_period: 2, + needed_approvals: 3, + ..Default::default() + } +} + +fn genesis_config() -> MockGenesisConfig { + MockGenesisConfig { + configuration: configuration::GenesisConfig { config: default_config() }, + ..Default::default() + } +} + +fn session_changes(n: BlockNumber) -> Option> { + if n % 10 == 0 { + Some(SessionChangeNotification { session_index: n / 10, ..Default::default() }) + } else { + None + } +} + +fn new_session_every_block(n: BlockNumber) -> Option> { + Some(SessionChangeNotification { session_index: n, ..Default::default() }) +} + +#[test] +fn session_pruning_is_based_on_dispute_period() { + new_test_ext(genesis_config()).execute_with(|| { + // Dispute period starts at 2 + let config = Configuration::config(); + assert_eq!(config.dispute_period, 2); + + // Move to session 10 + run_to_block(100, session_changes); + // Earliest stored session is 10 - 2 = 8 + assert_eq!(EarliestStoredSession::::get(), 8); + // Pruning works as expected + assert!(Sessions::::get(7).is_none()); + assert!(Sessions::::get(8).is_some()); + assert!(Sessions::::get(9).is_some()); + + // changing `dispute_period` works + let dispute_period = 5; + Configuration::set_dispute_period(RuntimeOrigin::root(), dispute_period).unwrap(); + + // Dispute period does not automatically change + let config = Configuration::config(); + assert_eq!(config.dispute_period, 2); + // Two sessions later it will though + run_to_block(120, session_changes); + let config = Configuration::config(); + assert_eq!(config.dispute_period, 5); + + run_to_block(200, session_changes); + assert_eq!(EarliestStoredSession::::get(), 20 - dispute_period); + + // Increase dispute period even more + let new_dispute_period = 16; + Configuration::set_dispute_period(RuntimeOrigin::root(), new_dispute_period).unwrap(); + + run_to_block(210, session_changes); + assert_eq!(EarliestStoredSession::::get(), 21 - dispute_period); + + // Two sessions later it kicks in + run_to_block(220, session_changes); + let config = Configuration::config(); + assert_eq!(config.dispute_period, 16); + // Earliest session stays the same + assert_eq!(EarliestStoredSession::::get(), 21 - dispute_period); + + // We still don't have enough stored sessions to start pruning + run_to_block(300, session_changes); + assert_eq!(EarliestStoredSession::::get(), 21 - dispute_period); + + // now we do + run_to_block(420, session_changes); + assert_eq!(EarliestStoredSession::::get(), 42 - new_dispute_period); + }) +} + +#[test] +fn session_info_is_based_on_config() { + new_test_ext(genesis_config()).execute_with(|| { + run_to_block(1, new_session_every_block); + let session = Sessions::::get(&1).unwrap(); + assert_eq!(session.needed_approvals, 3); + + // change some param + Configuration::set_needed_approvals(RuntimeOrigin::root(), 42).unwrap(); + // 2 sessions later + run_to_block(3, new_session_every_block); + let session = Sessions::::get(&3).unwrap(); + assert_eq!(session.needed_approvals, 42); + }) +} + +#[test] +fn session_info_active_subsets() { + let unscrambled = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + ]; + + let active_set = vec![ValidatorIndex(4), ValidatorIndex(0), ValidatorIndex(2)]; + + let unscrambled_validators: Vec = + unscrambled.iter().map(|v| v.public().into()).collect(); + let unscrambled_discovery: Vec = + unscrambled.iter().map(|v| v.public().into()).collect(); + let unscrambled_assignment: Vec = + unscrambled.iter().map(|v| v.public().into()).collect(); + + let validators = take_active_subset(&active_set, &unscrambled_validators); + + new_test_ext(genesis_config()).execute_with(|| { + ParasShared::set_active_validators_with_indices(active_set.clone(), validators.clone()); + + assert_eq!(ParasShared::active_validator_indices(), active_set); + + AssignmentKeysUnsafe::::set(unscrambled_assignment.clone()); + crate::mock::set_discovery_authorities(unscrambled_discovery.clone()); + assert_eq!(::authorities(), unscrambled_discovery); + + // invoke directly, because `run_to_block` will invoke `Shared` and clobber our + // values. + SessionInfo::initializer_on_new_session(&SessionChangeNotification { + session_index: 1, + validators: validators.clone(), + ..Default::default() + }); + let session = Sessions::::get(&1).unwrap(); + + assert_eq!(session.validators.to_vec(), validators); + assert_eq!( + session.discovery_keys, + take_active_subset_and_inactive(&active_set, &unscrambled_discovery), + ); + assert_eq!( + session.assignment_keys, + take_active_subset(&active_set, &unscrambled_assignment), + ); + }) +} diff --git a/polkadot/runtime/parachains/src/shared.rs b/polkadot/runtime/parachains/src/shared.rs new file mode 100644 index 0000000000000000000000000000000000000000..ad13c9e48448fa888573b9361d1aa59debbf781e --- /dev/null +++ b/polkadot/runtime/parachains/src/shared.rs @@ -0,0 +1,242 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A pallet for any shared state that other pallets may want access to. +//! +//! To avoid cyclic dependencies, it is important that this pallet is not +//! dependent on any of the other pallets. + +use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::{SessionIndex, ValidatorId, ValidatorIndex}; +use sp_runtime::traits::AtLeast32BitUnsigned; +use sp_std::{collections::vec_deque::VecDeque, vec::Vec}; + +use rand::{seq::SliceRandom, SeedableRng}; +use rand_chacha::ChaCha20Rng; + +use crate::configuration::HostConfiguration; + +pub use pallet::*; + +// `SESSION_DELAY` is used to delay any changes to Paras registration or configurations. +// Wait until the session index is 2 larger then the current index to apply any changes, +// which guarantees that at least one full session has passed before any changes are applied. +pub(crate) const SESSION_DELAY: SessionIndex = 2; + +#[cfg(test)] +mod tests; + +/// Information about past relay-parents. +#[derive(Encode, Decode, Default, TypeInfo)] +pub struct AllowedRelayParentsTracker { + // The past relay parents, paired with state roots, that are viable to build upon. + // + // They are in ascending chronologic order, so the newest relay parents are at + // the back of the deque. + // + // (relay_parent, state_root) + buffer: VecDeque<(Hash, Hash)>, + + // The number of the most recent relay-parent, if any. + // If the buffer is empty, this value has no meaning and may + // be nonsensical. + latest_number: BlockNumber, +} + +impl + AllowedRelayParentsTracker +{ + /// Add a new relay-parent to the allowed relay parents, along with info about the header. + /// Provide a maximum ancestry length for the buffer, which will cause old relay-parents to be + /// pruned. + pub(crate) fn update( + &mut self, + relay_parent: Hash, + state_root: Hash, + number: BlockNumber, + max_ancestry_len: u32, + ) { + // + 1 for the most recent block, which is always allowed. + let buffer_size_limit = max_ancestry_len as usize + 1; + + self.buffer.push_back((relay_parent, state_root)); + self.latest_number = number; + while self.buffer.len() > buffer_size_limit { + let _ = self.buffer.pop_front(); + } + + // We only allow relay parents within the same sessions, the buffer + // gets cleared on session changes. + } + + /// Attempt to acquire the state root and block number to be used when building + /// upon the given relay-parent. + /// + /// This only succeeds if the relay-parent is one of the allowed relay-parents. + /// If a previous relay-parent number is passed, then this only passes if the new relay-parent + /// is more recent than the previous. + pub(crate) fn acquire_info( + &self, + relay_parent: Hash, + prev: Option, + ) -> Option<(Hash, BlockNumber)> { + let pos = self.buffer.iter().position(|(rp, _)| rp == &relay_parent)?; + let age = (self.buffer.len() - 1) - pos; + let number = self.latest_number - BlockNumber::from(age as u32); + + if let Some(prev) = prev { + if prev > number { + return None + } + } + + Some((self.buffer[pos].1, number)) + } + + /// Returns block number of the earliest block the buffer would contain if + /// `now` is pushed into it. + pub(crate) fn hypothetical_earliest_block_number( + &self, + now: BlockNumber, + max_ancestry_len: u32, + ) -> BlockNumber { + let allowed_ancestry_len = max_ancestry_len.min(self.buffer.len() as u32); + + now - allowed_ancestry_len.into() + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config {} + + /// The current session index. + #[pallet::storage] + #[pallet::getter(fn session_index)] + pub(super) type CurrentSessionIndex = StorageValue<_, SessionIndex, ValueQuery>; + + /// All the validators actively participating in parachain consensus. + /// Indices are into the broader validator set. + #[pallet::storage] + #[pallet::getter(fn active_validator_indices)] + pub(super) type ActiveValidatorIndices = + StorageValue<_, Vec, ValueQuery>; + + /// The parachain attestation keys of the validators actively participating in parachain + /// consensus. This should be the same length as `ActiveValidatorIndices`. + #[pallet::storage] + #[pallet::getter(fn active_validator_keys)] + pub(super) type ActiveValidatorKeys = StorageValue<_, Vec, ValueQuery>; + + /// All allowed relay-parents. + #[pallet::storage] + #[pallet::getter(fn allowed_relay_parents)] + pub(crate) type AllowedRelayParents = + StorageValue<_, AllowedRelayParentsTracker>, ValueQuery>; + + #[pallet::call] + impl Pallet {} +} + +impl Pallet { + /// Called by the initializer to initialize the configuration pallet. + pub(crate) fn initializer_initialize(_now: BlockNumberFor) -> Weight { + Weight::zero() + } + + /// Called by the initializer to finalize the configuration pallet. + pub(crate) fn initializer_finalize() {} + + /// Called by the initializer to note that a new session has started. + /// + /// Returns the list of outgoing paras from the actions queue. + pub(crate) fn initializer_on_new_session( + session_index: SessionIndex, + random_seed: [u8; 32], + new_config: &HostConfiguration>, + all_validators: Vec, + ) -> Vec { + // Drop allowed relay parents buffer on a session change. + // + // During the initialization of the next block we always add its parent + // to the tracker. + // + // With asynchronous backing candidates built on top of relay + // parent `R` are still restricted by the runtime to be backed + // by the group assigned at `number(R) + 1`, which is guaranteed + // to be in the current session. + AllowedRelayParents::::mutate(|tracker| tracker.buffer.clear()); + + CurrentSessionIndex::::set(session_index); + let mut rng: ChaCha20Rng = SeedableRng::from_seed(random_seed); + + let mut shuffled_indices: Vec<_> = (0..all_validators.len()) + .enumerate() + .map(|(i, _)| ValidatorIndex(i as _)) + .collect(); + + shuffled_indices.shuffle(&mut rng); + + if let Some(max) = new_config.max_validators { + shuffled_indices.truncate(max as usize); + } + + let active_validator_keys = + crate::util::take_active_subset(&shuffled_indices, &all_validators); + + ActiveValidatorIndices::::set(shuffled_indices); + ActiveValidatorKeys::::set(active_validator_keys.clone()); + + active_validator_keys + } + + /// Return the session index that should be used for any future scheduled changes. + pub fn scheduled_session() -> SessionIndex { + Self::session_index().saturating_add(SESSION_DELAY) + } + + /// Test function for setting the current session index. + #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] + pub fn set_session_index(index: SessionIndex) { + CurrentSessionIndex::::set(index); + } + + #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] + pub fn set_active_validators_ascending(active: Vec) { + ActiveValidatorIndices::::set( + (0..active.len()).map(|i| ValidatorIndex(i as _)).collect(), + ); + ActiveValidatorKeys::::set(active); + } + + #[cfg(test)] + pub(crate) fn set_active_validators_with_indices( + indices: Vec, + keys: Vec, + ) { + assert_eq!(indices.len(), keys.len()); + ActiveValidatorIndices::::set(indices); + ActiveValidatorKeys::::set(keys); + } +} diff --git a/polkadot/runtime/parachains/src/shared/tests.rs b/polkadot/runtime/parachains/src/shared/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..91891ba8d75bb993474e06aafcc4b452a62b0fe7 --- /dev/null +++ b/polkadot/runtime/parachains/src/shared/tests.rs @@ -0,0 +1,168 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::{ + configuration::HostConfiguration, + mock::{new_test_ext, MockGenesisConfig, ParasShared}, +}; +use assert_matches::assert_matches; +use keyring::Sr25519Keyring; +use primitives::Hash; + +fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec { + val_ids.iter().map(|v| v.public().into()).collect() +} + +#[test] +fn tracker_earliest_block_number() { + let mut tracker = AllowedRelayParentsTracker::default(); + + // Test it on an empty tracker. + let now: u32 = 1; + let max_ancestry_len = 5; + assert_eq!(tracker.hypothetical_earliest_block_number(now, max_ancestry_len), now); + + // Push a single block into the tracker, suppose max capacity is 1. + let max_ancestry_len = 0; + tracker.update(Hash::zero(), Hash::zero(), 0, max_ancestry_len); + assert_eq!(tracker.hypothetical_earliest_block_number(now, max_ancestry_len), now); + + // Test a greater capacity. + let max_ancestry_len = 4; + let now = 4; + for i in 1..now { + tracker.update(Hash::zero(), Hash::zero(), i, max_ancestry_len); + assert_eq!(tracker.hypothetical_earliest_block_number(i + 1, max_ancestry_len), 0); + } + + // Capacity exceeded. + tracker.update(Hash::zero(), Hash::zero(), now, max_ancestry_len); + assert_eq!(tracker.hypothetical_earliest_block_number(now + 1, max_ancestry_len), 1); +} + +#[test] +fn tracker_acquire_info() { + let mut tracker = AllowedRelayParentsTracker::::default(); + let max_ancestry_len = 2; + + // (relay_parent, state_root) pairs. + let blocks = &[ + (Hash::repeat_byte(0), Hash::repeat_byte(10)), + (Hash::repeat_byte(1), Hash::repeat_byte(11)), + (Hash::repeat_byte(2), Hash::repeat_byte(12)), + ]; + + let (relay_parent, state_root) = blocks[0]; + tracker.update(relay_parent, state_root, 0, max_ancestry_len); + assert_matches!( + tracker.acquire_info(relay_parent, None), + Some((s, b)) if s == state_root && b == 0 + ); + + let (relay_parent, state_root) = blocks[1]; + tracker.update(relay_parent, state_root, 1u32, max_ancestry_len); + let (relay_parent, state_root) = blocks[2]; + tracker.update(relay_parent, state_root, 2u32, max_ancestry_len); + for (block_num, (rp, state_root)) in blocks.iter().enumerate().take(2) { + assert_matches!( + tracker.acquire_info(*rp, None), + Some((s, b)) if &s == state_root && b == block_num as u32 + ); + + assert!(tracker.acquire_info(*rp, Some(2)).is_none()); + } + + for (block_num, (rp, state_root)) in blocks.iter().enumerate().skip(1) { + assert_matches!( + tracker.acquire_info(*rp, Some(block_num as u32 - 1)), + Some((s, b)) if &s == state_root && b == block_num as u32 + ); + } +} + +#[test] +fn sets_and_shuffles_validators() { + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + + let mut config = HostConfiguration::default(); + config.max_validators = None; + + let pubkeys = validator_pubkeys(&validators); + + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let validators = ParasShared::initializer_on_new_session(1, [1; 32], &config, pubkeys); + + assert_eq!( + validators, + validator_pubkeys(&[ + Sr25519Keyring::Ferdie, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Alice, + ]) + ); + + assert_eq!(ParasShared::active_validator_keys(), validators); + + assert_eq!( + ParasShared::active_validator_indices(), + vec![ + ValidatorIndex(4), + ValidatorIndex(1), + ValidatorIndex(2), + ValidatorIndex(3), + ValidatorIndex(0), + ] + ); + }); +} + +#[test] +fn sets_truncates_and_shuffles_validators() { + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, + ]; + + let mut config = HostConfiguration::default(); + config.max_validators = Some(2); + + let pubkeys = validator_pubkeys(&validators); + + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let validators = ParasShared::initializer_on_new_session(1, [1; 32], &config, pubkeys); + + assert_eq!(validators, validator_pubkeys(&[Sr25519Keyring::Ferdie, Sr25519Keyring::Bob,])); + + assert_eq!(ParasShared::active_validator_keys(), validators); + + assert_eq!( + ParasShared::active_validator_indices(), + vec![ValidatorIndex(4), ValidatorIndex(1),] + ); + }); +} diff --git a/polkadot/runtime/parachains/src/ump_tests.rs b/polkadot/runtime/parachains/src/ump_tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..22aee31043a28714051a8b76a7d077120982951f --- /dev/null +++ b/polkadot/runtime/parachains/src/ump_tests.rs @@ -0,0 +1,661 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::{ + inclusion::{ + tests::run_to_block_default_notifications as run_to_block, AggregateMessageOrigin, + AggregateMessageOrigin::Ump, UmpAcceptanceCheckErr, UmpQueueId, + }, + mock::{ + assert_last_event, assert_last_events, new_test_ext, Configuration, MessageQueue, + MessageQueueSize, MockGenesisConfig, ParaInclusion, Processed, System, Test, *, + }, +}; +use frame_support::{ + assert_noop, assert_ok, + pallet_prelude::*, + traits::{EnqueueMessage, ExecuteOverweightError, ServiceQueues}, + weights::Weight, +}; +use primitives::{well_known_keys, Id as ParaId, UpwardMessage}; +use sp_core::twox_64; +use sp_io::hashing::blake2_256; +use sp_runtime::traits::Bounded; +use sp_std::prelude::*; + +pub(super) struct GenesisConfigBuilder { + max_upward_message_size: u32, + max_upward_message_num_per_candidate: u32, + max_upward_queue_count: u32, + max_upward_queue_size: u32, +} + +impl Default for GenesisConfigBuilder { + fn default() -> Self { + Self { + max_upward_message_size: 16, + max_upward_message_num_per_candidate: 2, + max_upward_queue_count: 4, + max_upward_queue_size: 64, + } + } +} + +impl GenesisConfigBuilder { + pub(super) fn large_queue_count() -> Self { + Self { max_upward_queue_count: 128, ..Default::default() } + } + + pub(super) fn build(self) -> crate::mock::MockGenesisConfig { + let mut genesis = default_genesis_config(); + let config = &mut genesis.configuration.config; + + config.max_upward_message_size = self.max_upward_message_size; + config.max_upward_message_num_per_candidate = self.max_upward_message_num_per_candidate; + config.max_upward_queue_count = self.max_upward_queue_count; + config.max_upward_queue_size = self.max_upward_queue_size; + genesis + } +} + +fn default_genesis_config() -> MockGenesisConfig { + MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: crate::configuration::HostConfiguration { + max_downward_message_size: 1024, + ..Default::default() + }, + }, + ..Default::default() + } +} + +fn queue_upward_msg(para: ParaId, msg: UpwardMessage) { + try_queue_upward_msg(para, msg).unwrap(); +} + +fn try_queue_upward_msg(para: ParaId, msg: UpwardMessage) -> Result<(), UmpAcceptanceCheckErr> { + let msgs = vec![msg]; + ParaInclusion::check_upward_messages(&Configuration::config(), para, &msgs)?; + ParaInclusion::receive_upward_messages(para, msgs.as_slice()); + Ok(()) +} + +mod check_upward_messages { + use super::*; + + const P_0: ParaId = ParaId::new(0u32); + const P_1: ParaId = ParaId::new(1u32); + + // Currently its trivial since unbounded, but this function will be handy when we bound it. + fn msg(data: &str) -> UpwardMessage { + data.as_bytes().to_vec() + } + + /// Check that these messages *could* be queued. + fn check(para: ParaId, msgs: Vec, err: Option) { + assert_eq!( + ParaInclusion::check_upward_messages(&Configuration::config(), para, &msgs[..]).err(), + err + ); + } + + /// Enqueue these upward messages. + fn queue(para: ParaId, msgs: Vec) { + msgs.into_iter().for_each(|msg| super::queue_upward_msg(para, msg)); + } + + #[test] + fn basic_works() { + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + let _g = frame_support::StorageNoopGuard::default(); + check(P_0, vec![msg("p0m0")], None); + check(P_1, vec![msg("p1m0")], None); + check(P_0, vec![msg("p0m1")], None); + check(P_1, vec![msg("p1m1")], None); + }); + } + + #[test] + fn num_per_candidate_exceeded_error() { + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + let _g = frame_support::StorageNoopGuard::default(); + let permitted = Configuration::config().max_upward_message_num_per_candidate; + + for sent in 0..permitted + 1 { + check(P_0, vec![msg(""); sent as usize], None); + } + for sent in permitted + 1..permitted + 10 { + check( + P_0, + vec![msg(""); sent as usize], + Some(UmpAcceptanceCheckErr::MoreMessagesThanPermitted { sent, permitted }), + ); + } + }); + } + + #[test] + fn size_per_message_exceeded_error() { + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + let _g = frame_support::StorageNoopGuard::default(); + let max_size = Configuration::config().max_upward_message_size; + let max_per_candidate = Configuration::config().max_upward_message_num_per_candidate; + + for msg_size in 0..=max_size { + check(P_0, vec![vec![0; msg_size as usize]], None); + } + for msg_size in max_size + 1..max_size + 10 { + for goods in 0..max_per_candidate { + let mut msgs = vec![vec![0; max_size as usize]; goods as usize]; + msgs.push(vec![0; msg_size as usize]); + + check( + P_0, + msgs, + Some(UmpAcceptanceCheckErr::MessageSize { idx: goods, msg_size, max_size }), + ); + } + } + }); + } + + #[test] + fn queue_count_exceeded_error() { + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + let limit = Configuration::config().max_upward_queue_count as u64; + + for _ in 0..limit { + check(P_0, vec![msg("")], None); + queue(P_0, vec![msg("")]); + } + + check( + P_0, + vec![msg("")], + Some(UmpAcceptanceCheckErr::CapacityExceeded { count: limit + 1, limit }), + ); + check( + P_0, + vec![msg(""); 2], + Some(UmpAcceptanceCheckErr::CapacityExceeded { count: limit + 2, limit }), + ); + }); + } + + #[test] + fn queue_size_exceeded_error() { + new_test_ext(GenesisConfigBuilder::large_queue_count().build()).execute_with(|| { + let limit = Configuration::config().max_upward_queue_size as u64; + assert_eq!(pallet_message_queue::ItemHeader::::max_encoded_len(), 5); + assert!( + Configuration::config().max_upward_queue_size < + crate::inclusion::MaxUmpMessageLenOf::::get(), + "Test will not work" + ); + + for _ in 0..limit { + check(P_0, vec![msg("1")], None); + queue(P_0, vec![msg("1")]); + } + + check( + P_0, + vec![msg("1")], + Some(UmpAcceptanceCheckErr::TotalSizeExceeded { total_size: limit + 1, limit }), + ); + check( + P_0, + vec![msg("123456")], + Some(UmpAcceptanceCheckErr::TotalSizeExceeded { total_size: limit + 6, limit }), + ); + }); + } +} + +#[test] +fn dispatch_empty() { + new_test_ext(default_genesis_config()).execute_with(|| { + // make sure that the case with empty queues is handled properly + MessageQueue::service_queues(Weight::max_value()); + }); +} + +#[test] +fn dispatch_single_message() { + let a = ParaId::from(228); + let msg = 1000u32.encode(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + queue_upward_msg(a, msg.clone()); + MessageQueue::service_queues(Weight::max_value()); + assert_eq!(Processed::take(), vec![(a, msg)]); + }); +} + +#[test] +fn dispatch_resume_after_exceeding_dispatch_stage_weight() { + let a = ParaId::from(128); + let c = ParaId::from(228); + let q = ParaId::from(911); + + let a_msg_1 = (200u32, "a_msg_1").encode(); + let a_msg_2 = (100u32, "a_msg_2").encode(); + let c_msg_1 = (300u32, "c_msg_1").encode(); + let c_msg_2 = (100u32, "c_msg_2").encode(); + let q_msg = (500u32, "q_msg").encode(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + queue_upward_msg(q, q_msg.clone()); + queue_upward_msg(c, c_msg_1.clone()); + queue_upward_msg(a, a_msg_1.clone()); + queue_upward_msg(a, a_msg_2.clone()); + + // we expect only two first messages to fit in the first iteration. + MessageQueue::service_queues(Weight::from_parts(500, 500)); + assert_eq!(Processed::take(), vec![(q, q_msg)]); + queue_upward_msg(c, c_msg_2.clone()); + // second iteration should process the second message. + MessageQueue::service_queues(Weight::from_parts(500, 500)); + assert_eq!(Processed::take(), vec![(c, c_msg_1), (c, c_msg_2)]); + // 3rd iteration. + MessageQueue::service_queues(Weight::from_parts(500, 500)); + assert_eq!(Processed::take(), vec![(a, a_msg_1), (a, a_msg_2)]); + // finally, make sure that the queue is empty. + MessageQueue::service_queues(Weight::from_parts(500, 500)); + assert_eq!(Processed::take(), vec![]); + }); +} + +#[test] +fn dispatch_keeps_message_after_weight_exhausted() { + let a = ParaId::from(128); + + let a_msg_1 = (300u32, "a_msg_1").encode(); + let a_msg_2 = (300u32, "a_msg_2").encode(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + queue_upward_msg(a, a_msg_1.clone()); + queue_upward_msg(a, a_msg_2.clone()); + + // we expect only one message to fit in the first iteration. + MessageQueue::service_queues(Weight::from_parts(500, 500)); + assert_eq!(Processed::take(), vec![(a, a_msg_1)]); + // second iteration should process the remaining message. + MessageQueue::service_queues(Weight::from_parts(500, 500)); + assert_eq!(Processed::take(), vec![(a, a_msg_2)]); + // finally, make sure that the queue is empty. + MessageQueue::service_queues(Weight::from_parts(500, 500)); + assert_eq!(Processed::take(), vec![]); + }); +} + +#[test] +fn dispatch_correctly_handle_remove_of_latest() { + let a = ParaId::from(1991); + let b = ParaId::from(1999); + + let a_msg_1 = (300u32, "a_msg_1").encode(); + let a_msg_2 = (300u32, "a_msg_2").encode(); + let b_msg_1 = (300u32, "b_msg_1").encode(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + // We want to test here an edge case, where we remove the queue with the highest + // para id (i.e. last in the `needs_dispatch` order). + // + // If the last entry was removed we should proceed execution, assuming we still have + // weight available. + + queue_upward_msg(a, a_msg_1.clone()); + queue_upward_msg(a, a_msg_2.clone()); + queue_upward_msg(b, b_msg_1.clone()); + MessageQueue::service_queues(Weight::from_parts(900, 900)); + assert_eq!(Processed::take(), vec![(a, a_msg_1), (a, a_msg_2), (b, b_msg_1)]); + }); +} + +#[test] +#[cfg_attr(debug_assertions, should_panic = "Defensive failure has been triggered")] +fn queue_enact_too_long_ignored() { + const P_0: ParaId = ParaId::new(0u32); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + let max_enact = crate::inclusion::MaxUmpMessageLenOf::::get() as usize; + let m1 = (300u32, "a_msg_1").encode(); + let m2 = vec![0u8; max_enact + 1]; + let m3 = (300u32, "a_msg_3").encode(); + + // .. but the enact defensively ignores. + ParaInclusion::receive_upward_messages(P_0, &[m1.clone(), m2.clone(), m3.clone()]); + // There is one message in the queue now: + MessageQueue::service_queues(Weight::from_parts(900, 900)); + assert_eq!(Processed::take(), vec![(P_0, m1), (P_0, m3)]); + }); +} + +/// Check that the Inclusion pallet correctly updates the well known keys in the MQ handler. +/// +/// Also checks that it works in the presence of overweight messages. +#[test] +fn relay_dispatch_queue_size_is_updated() { + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + let cfg = Configuration::config(); + + for p in 0..100 { + let para = p.into(); + // Do some tricks with the weight such that the MQ pallet will process in order: + // Q0:0, Q1:0 … Q0:1, Q1:1 … + let m1 = (300u32 * (100 - p), "m1").encode(); + let m2 = (300u32 * (100 - p), "m11").encode(); + + queue_upward_msg(para, m1); + queue_upward_msg(para, m2); + + assert_queue_size(para, 2, 15); + assert_queue_remaining( + para, + cfg.max_upward_queue_count - 2, + cfg.max_upward_queue_size - 15, + ); + + // Now processing one message should also update the queue size. + MessageQueue::service_queues(Weight::from_all(300u64 * (100 - p) as u64)); + assert_queue_remaining( + para, + cfg.max_upward_queue_count - 1, + cfg.max_upward_queue_size - 8, + ); + } + + // The messages of Q0…Q98 are overweight, so `service_queues` wont help. + for p in 0..98 { + let para = UmpQueueId::Para(p.into()); + MessageQueue::service_queues(Weight::from_all(u64::MAX)); + + let fp = MessageQueue::footprint(AggregateMessageOrigin::Ump(para)); + let (para_queue_count, para_queue_size) = (fp.count, fp.size); + assert_eq!(para_queue_count, 1, "count wrong for para: {}", p); + assert_eq!(para_queue_size, 8, "size wrong for para: {}", p); + } + // All queues are empty after processing overweight messages. + for p in 0..100 { + let para = UmpQueueId::Para(p.into()); + let _ = ::execute_overweight( + Weight::from_all(u64::MAX), + (AggregateMessageOrigin::Ump(para.clone()), 0, 1), + ); + + assert_queue_remaining(p.into(), cfg.max_upward_queue_count, cfg.max_upward_queue_size); + let fp = MessageQueue::footprint(AggregateMessageOrigin::Ump(para)); + let (para_queue_count, para_queue_size) = (fp.count, fp.size); + assert_eq!(para_queue_count, 0, "count wrong for para: {}", p); + assert_eq!(para_queue_size, 0, "size wrong for para: {}", p); + } + }); +} + +/// Assert that the old and the new way of accessing `relay_dispatch_queue_size` is the same. +#[test] +fn relay_dispatch_queue_size_key_is_correct() { + #![allow(deprecated)] + // Storage alias to the old way of accessing the queue size. + #[frame_support::storage_alias] + type RelayDispatchQueueSize = StorageMap; + + for i in 0..1024 { + // A "random" para id. + let para: ParaId = u32::from_ne_bytes(twox_64(&i.encode())[..4].try_into().unwrap()).into(); + + let well_known = primitives::well_known_keys::relay_dispatch_queue_size(para); + let aliased = RelayDispatchQueueSize::hashed_key_for(para); + + assert_eq!(well_known, aliased, "Old and new key must match"); + } +} + +#[test] +fn verify_relay_dispatch_queue_size_is_externally_accessible() { + // Make sure that the relay dispatch queue size storage entry is accessible via well known + // keys and is decodable into a (u32, u32). + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + let cfg = Configuration::config(); + + for para in 0..10 { + let para = para.into(); + queue_upward_msg(para, vec![0u8; 3]); + assert_queue_size(para, 1, 3); + assert_queue_remaining( + para, + cfg.max_upward_queue_count - 1, + cfg.max_upward_queue_size - 3, + ); + + queue_upward_msg(para, vec![0u8; 3]); + assert_queue_size(para, 2, 6); + assert_queue_remaining( + para, + cfg.max_upward_queue_count - 2, + cfg.max_upward_queue_size - 6, + ); + } + }); +} + +fn assert_queue_size(para: ParaId, count: u32, size: u32) { + #[allow(deprecated)] + let raw_queue_size = sp_io::storage::get(&well_known_keys::relay_dispatch_queue_size(para)).expect( + "enqueing a message should create the dispatch queue\ + and it should be accessible via the well known keys", + ); + let (c, s) = <(u32, u32)>::decode(&mut &raw_queue_size[..]) + .expect("the dispatch queue size should be decodable into (u32, u32)"); + assert_eq!((c, s), (count, size)); + + // Test the deprecated but at least type-safe `relay_dispatch_queue_size_typed`: + #[allow(deprecated)] + let (c, s) = well_known_keys::relay_dispatch_queue_size_typed(para).get().expect( + "enqueing a message should create the dispatch queue\ + and it should be accessible via the well known keys", + ); + assert_eq!((c, s), (count, size)); +} + +fn assert_queue_remaining(para: ParaId, count: u32, size: u32) { + let (remaining_cnt, remaining_size) = + well_known_keys::relay_dispatch_queue_remaining_capacity(para) + .get() + .expect("No storage value"); + assert_eq!(remaining_cnt, count, "Wrong number of remaining messages in Q{}", para); + assert_eq!(remaining_size, size, "Wrong remaining size in Q{}", para); +} + +#[test] +fn service_overweight_unknown() { + // This test just makes sure that 0 is not a valid index and we can use it not worrying in + // the next test. + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + assert_noop!( + ::execute_overweight( + Weight::MAX, + (Ump(UmpQueueId::Para(0u32.into())), 0, 0) + ), + ExecuteOverweightError::NotFound, + ); + }); +} + +#[test] +fn overweight_queue_works() { + let para_a = ParaId::from(2021); + + let a_msg_1 = (301u32, "a_msg_1").encode(); + let a_msg_2 = (501u32, "a_msg_2").encode(); + let a_msg_3 = (501u32, "a_msg_3").encode(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + // HACK: Start with the block number 1. This is needed because should an event be + // emitted during the genesis block they will be implicitly wiped. + System::set_block_number(1); + + // This one is overweight. However, the weight is plenty and we can afford to execute + // this message, thus expect it. + queue_upward_msg(para_a, a_msg_1.clone()); + queue_upward_msg(para_a, a_msg_2.clone()); + queue_upward_msg(para_a, a_msg_3.clone()); + + MessageQueue::service_queues(Weight::from_parts(500, 500)); + let hash_1 = blake2_256(&a_msg_1[..]); + let hash_2 = blake2_256(&a_msg_2[..]); + let hash_3 = blake2_256(&a_msg_3[..]); + assert_last_events( + [ + pallet_message_queue::Event::::Processed { + id: hash_1, + origin: Ump(UmpQueueId::Para(para_a)), + weight_used: Weight::from_parts(301, 301), + success: true, + } + .into(), + pallet_message_queue::Event::::OverweightEnqueued { + id: hash_2, + origin: Ump(UmpQueueId::Para(para_a)), + page_index: 0, + message_index: 1, + } + .into(), + pallet_message_queue::Event::::OverweightEnqueued { + id: hash_3, + origin: Ump(UmpQueueId::Para(para_a)), + page_index: 0, + message_index: 2, + } + .into(), + ] + .into_iter(), + ); + assert_eq!(Processed::take(), vec![(para_a, a_msg_1)]); + + // Now verify that if we wanted to service this overweight message with less than enough + // weight it will fail. + assert_noop!( + ::execute_overweight( + Weight::from_parts(500, 500), + (Ump(UmpQueueId::Para(para_a)), 0, 2) + ), + ExecuteOverweightError::InsufficientWeight, + ); + + // ... and if we try to service it with just enough weight it will succeed as well. + assert_ok!(::execute_overweight( + Weight::from_parts(501, 501), + (Ump(UmpQueueId::Para(para_a)), 0, 2) + )); + assert_last_event( + pallet_message_queue::Event::::Processed { + id: hash_3, + origin: Ump(UmpQueueId::Para(para_a)), + weight_used: Weight::from_parts(501, 501), + success: true, + } + .into(), + ); + + // But servicing again will not work. + assert_noop!( + ::execute_overweight( + Weight::from_parts(501, 501), + (Ump(UmpQueueId::Para(para_a)), 0, 2) + ), + ExecuteOverweightError::AlreadyProcessed, + ); + + // Using an invalid index does not work. + assert_noop!( + ::execute_overweight( + Weight::from_parts(501, 501), + (Ump(UmpQueueId::Para(para_a)), 0, 3) + ), + ExecuteOverweightError::NotFound, + ); + }); +} + +/// Tests that UMP messages in the dispatch queue of the relay prevents the parachain from being +/// scheduled for offboarding. +#[test] +fn cannot_offboard_while_ump_dispatch_queued() { + let para = 32.into(); + let msg = (300u32, "something").encode(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + register_parachain(para); + run_to_block(5, vec![4, 5]); + + queue_upward_msg(para, msg.clone()); + queue_upward_msg(para, msg.clone()); + // Cannot offboard since there are two UMP messages in the queue. + for i in 6..10 { + assert!(try_deregister_parachain(para).is_err()); + run_to_block(i, vec![i]); + assert!(Paras::is_valid_para(para)); + } + + // Now let's process the first message. + MessageQueue::on_initialize(System::block_number()); + assert_eq!(Processed::take().len(), 1); + // Cannot offboard since there is another one in the queue. + assert!(try_deregister_parachain(para).is_err()); + // Now also process the second message ... + MessageQueue::on_initialize(System::block_number()); + assert_eq!(Processed::take().len(), 1); + + // ... and offboard. + run_to_block(10, vec![10]); + assert!(Paras::is_valid_para(para)); + assert_ok!(try_deregister_parachain(para)); + assert!(Paras::is_offboarding(para)); + + // Offboarding completed. + run_to_block(11, vec![11]); + assert!(!Paras::is_valid_para(para)); + }); +} + +/// A para-chain cannot send an UMP to the relay chain while it is offboarding. +#[test] +fn cannot_enqueue_ump_while_offboarding() { + let para = 32.into(); + let msg = (300u32, "something").encode(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + register_parachain(para); + run_to_block(5, vec![4, 5]); + + // Start with an offboarding para. + assert_ok!(try_deregister_parachain(para)); + assert!(Paras::is_offboarding(para)); + + // Cannot enqueue a message. + assert!(try_queue_upward_msg(para, msg.clone()).is_err()); + run_to_block(6, vec![6]); + // Para is still there and still cannot enqueue a message. + assert!(Paras::is_offboarding(para)); + assert!(try_queue_upward_msg(para, msg.clone()).is_err()); + // Now offboarding is completed. + run_to_block(7, vec![7]); + assert!(!Paras::is_valid_para(para)); + }); +} diff --git a/polkadot/runtime/parachains/src/util.rs b/polkadot/runtime/parachains/src/util.rs new file mode 100644 index 0000000000000000000000000000000000000000..aa07ef0800554e9676ff67df8efb91f6643f502b --- /dev/null +++ b/polkadot/runtime/parachains/src/util.rs @@ -0,0 +1,119 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Utilities that don't belong to any particular module but may draw +//! on all modules. + +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::{Id as ParaId, PersistedValidationData, ValidatorIndex}; +use sp_std::{collections::btree_set::BTreeSet, vec::Vec}; + +use crate::{configuration, hrmp, paras}; + +/// Make the persisted validation data for a particular parachain, a specified relay-parent and it's +/// storage root. +/// +/// This ties together the storage of several modules. +pub fn make_persisted_validation_data( + para_id: ParaId, + relay_parent_number: BlockNumberFor, + relay_parent_storage_root: T::Hash, +) -> Option>> { + let config = >::config(); + + Some(PersistedValidationData { + parent_head: >::para_head(¶_id)?, + relay_parent_number, + relay_parent_storage_root, + max_pov_size: config.max_pov_size, + }) +} + +/// Take an active subset of a set containing all validators. +/// +/// First item in pair will be all items in set have indices found in the `active` indices set (in +/// the order of the `active` vec, the second item will contain the rest, in the original order. +/// +/// ```ignore +/// split_active_subset(active, all).0 == take_active_subset(active, all) +/// ``` +pub fn split_active_subset(active: &[ValidatorIndex], all: &[T]) -> (Vec, Vec) { + let active_set: BTreeSet<_> = active.iter().cloned().collect(); + // active result has ordering of active set. + let active_result = take_active_subset(active, all); + // inactive result preserves original ordering of `all`. + let inactive_result = all + .iter() + .enumerate() + .filter(|(i, _)| !active_set.contains(&ValidatorIndex(*i as _))) + .map(|(_, v)| v) + .cloned() + .collect(); + + if active_result.len() != active.len() { + log::warn!( + target: "runtime::parachains", + "Took active validators from set with wrong size.", + ); + } + + (active_result, inactive_result) +} + +/// Uses `split_active_subset` and concatenates the inactive to the active vec. +/// +/// ```ignore +/// split_active_subset(active, all)[0..active.len()]) == take_active_subset(active, all) +/// ``` +pub fn take_active_subset_and_inactive(active: &[ValidatorIndex], all: &[T]) -> Vec { + let (mut a, mut i) = split_active_subset(active, all); + a.append(&mut i); + a +} + +/// Take the active subset of a set containing all validators. +pub fn take_active_subset(active: &[ValidatorIndex], set: &[T]) -> Vec { + let subset: Vec<_> = active.iter().filter_map(|i| set.get(i.0 as usize)).cloned().collect(); + + if subset.len() != active.len() { + log::warn!( + target: "runtime::parachains", + "Took active validators from set with wrong size", + ); + } + + subset +} + +#[cfg(test)] +mod tests { + + use sp_std::vec::Vec; + + use crate::util::{split_active_subset, take_active_subset}; + use primitives::ValidatorIndex; + + #[test] + fn take_active_subset_is_compatible_with_split_active_subset() { + let active: Vec<_> = vec![ValidatorIndex(1), ValidatorIndex(7), ValidatorIndex(3)]; + let validators = vec![9, 1, 6, 7, 4, 5, 2, 3, 0, 8]; + let (selected, unselected) = split_active_subset(&active, &validators); + let selected2 = take_active_subset(&active, &validators); + assert_eq!(selected, selected2); + assert_eq!(unselected, vec![9, 6, 4, 5, 2, 0, 8]); + assert_eq!(selected, vec![1, 3, 7]); + } +} diff --git a/polkadot/runtime/polkadot/Cargo.toml b/polkadot/runtime/polkadot/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..76a01051a1224f37db2def28cead145dc8f0d879 --- /dev/null +++ b/polkadot/runtime/polkadot/Cargo.toml @@ -0,0 +1,308 @@ +[package] +name = "polkadot-runtime" +build = "build.rs" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +log = { version = "0.4.17", default-features = false } +rustc-hex = { version = "2.1.0", default-features = false } +serde = { version = "1.0.163", default-features = false } +serde_derive = { version = "1.0.117", optional = true } +static_assertions = "1.1.0" +smallvec = "1.8.0" + +authority-discovery-primitives = { package = "sp-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +beefy-primitives = { package = "sp-consensus-beefy", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +block-builder-api = { package = "sp-block-builder", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +offchain-primitives = { package = "sp-offchain", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +tx-pool-api = { package = "sp-transaction-pool", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +pallet-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-bags-list = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-bounties = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-child-bounties = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-conviction-voting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-democracy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-elections-phragmen = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-fast-unstake = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-executive = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-identity = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-im-online = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-indices = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-message-queue = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-multisig = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-nomination-pools = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-nomination-pools-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-offences = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-preimage = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-proxy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-referenda = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-scheduler = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking-reward-curve = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-staking-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system = {git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +polkadot-runtime-constants = { package = "polkadot-runtime-constants", path = "./constants", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-tips = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-whitelist = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-xcm = { path = "../../xcm/pallet-xcm", default-features = false, features=["experimental"] } +pallet-xcm-benchmarks = { path = "../../xcm/pallet-xcm-benchmarks", default-features = false, optional = true } + +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-election-provider-support-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-offences-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-session-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-nomination-pools-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +hex-literal = { version = "0.4.1", optional = true } + +runtime-common = { package = "polkadot-runtime-common", path = "../common", default-features = false } +runtime-parachains = { package = "polkadot-runtime-parachains", path = "../parachains", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } + +xcm = { package = "xcm", path = "../../xcm", default-features = false } +xcm-executor = { package = "xcm-executor", path = "../../xcm/xcm-executor", default-features = false } +xcm-builder = { package = "xcm-builder", path = "../../xcm/xcm-builder", default-features = false } + +[dev-dependencies] +hex-literal = "0.4.1" +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "master" } +sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } +serde_json = "1.0.96" +separator = "0.4.1" +remote-externalities = { git = "https://github.com/paritytech/substrate", branch = "master", package = "frame-remote-externalities" } +tokio = { version = "1.24.2", features = ["macros"] } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +[build-dependencies] +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = ["std"] +no_std = [] +only-staking = [] +std = [ + "authority-discovery-primitives/std", + "bitvec/std", + "primitives/std", + "rustc-hex/std", + "parity-scale-codec/std", + "scale-info/std", + "inherents/std", + "sp-arithmetic/std", + "sp-core/std", + "sp-api/std", + "tx-pool-api/std", + "block-builder-api/std", + "offchain-primitives/std", + "sp-arithmetic/std", + "sp-std/std", + "sp-mmr-primitives/std", + "frame-support/std", + "frame-executive/std", + "pallet-authority-discovery/std", + "pallet-authorship/std", + "pallet-bags-list/std", + "pallet-balances/std", + "pallet-bounties/std", + "pallet-child-bounties/std", + "pallet-conviction-voting/std", + "pallet-transaction-payment/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-collective/std", + "pallet-elections-phragmen/std", + "pallet-election-provider-multi-phase/std", + "pallet-democracy/std", + "pallet-fast-unstake/std", + "pallet-grandpa/std", + "pallet-identity/std", + "pallet-im-online/std", + "pallet-indices/std", + "pallet-membership/std", + "pallet-message-queue/std", + "pallet-multisig/std", + "pallet-nomination-pools/std", + "pallet-nomination-pools-runtime-api/std", + "pallet-offences/std", + "pallet-preimage/std", + "pallet-proxy/std", + "pallet-referenda/std", + "pallet-scheduler/std", + "pallet-session/std", + "pallet-staking/std", + "pallet-staking-runtime-api/std", + "pallet-timestamp/std", + "pallet-treasury/std", + "pallet-tips/std", + "pallet-babe/std", + "pallet-vesting/std", + "pallet-whitelist/std", + "pallet-utility/std", + "sp-runtime/std", + "sp-staking/std", + "frame-system/std", + "frame-system-rpc-runtime-api/std", + "polkadot-runtime-constants/std", + "sp-version/std", + "serde_derive", + "serde/std", + "log/std", + "babe-primitives/std", + "sp-session/std", + "runtime-common/std", + "frame-try-runtime/std", + "sp-npos-elections/std", + "beefy-primitives/std", + "frame-election-provider-support/std", + "pallet-xcm/std", + "xcm/std", + "xcm-executor/std", + "xcm-builder/std", +] +runtime-benchmarks = [ + "runtime-common/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "pallet-babe/runtime-benchmarks", + "pallet-bags-list/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-collective/runtime-benchmarks", + "pallet-conviction-voting/runtime-benchmarks", + "pallet-democracy/runtime-benchmarks", + "pallet-elections-phragmen/runtime-benchmarks", + "pallet-election-provider-multi-phase/runtime-benchmarks", + "pallet-election-provider-support-benchmarking/runtime-benchmarks", + "pallet-fast-unstake/runtime-benchmarks", + "pallet-grandpa/runtime-benchmarks", + "pallet-identity/runtime-benchmarks", + "pallet-im-online/runtime-benchmarks", + "pallet-indices/runtime-benchmarks", + "pallet-membership/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "pallet-multisig/runtime-benchmarks", + "pallet-nomination-pools/runtime-benchmarks", + "pallet-nomination-pools-benchmarking/runtime-benchmarks", + "pallet-preimage/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", + "pallet-referenda/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", + "pallet-staking/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-treasury/runtime-benchmarks", + "pallet-bounties/runtime-benchmarks", + "pallet-child-bounties/runtime-benchmarks", + "pallet-tips/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", + "pallet-vesting/runtime-benchmarks", + "pallet-whitelist/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "pallet-offences-benchmarking/runtime-benchmarks", + "pallet-session-benchmarking/runtime-benchmarks", + "frame-system-benchmarking/runtime-benchmarks", + "hex-literal", + "xcm-builder/runtime-benchmarks", + "frame-election-provider-support/runtime-benchmarks", + "runtime-parachains/runtime-benchmarks", + "pallet-xcm-benchmarks/runtime-benchmarks", +] +try-runtime = [ + "frame-executive/try-runtime", + "frame-try-runtime", + "frame-system/try-runtime", + "runtime-common/try-runtime", + "pallet-authority-discovery/try-runtime", + "pallet-authorship/try-runtime", + "pallet-balances/try-runtime", + "pallet-bags-list/try-runtime", + "pallet-bounties/try-runtime", + "pallet-child-bounties/try-runtime", + "pallet-conviction-voting/try-runtime", + "pallet-transaction-payment/try-runtime", + "pallet-collective/try-runtime", + "pallet-elections-phragmen/try-runtime", + "pallet-election-provider-multi-phase/try-runtime", + "pallet-fast-unstake/try-runtime", + "pallet-democracy/try-runtime", + "pallet-grandpa/try-runtime", + "pallet-identity/try-runtime", + "pallet-im-online/try-runtime", + "pallet-indices/try-runtime", + "pallet-membership/try-runtime", + "pallet-message-queue/try-runtime", + "pallet-multisig/try-runtime", + "pallet-nomination-pools/try-runtime", + "pallet-offences/try-runtime", + "pallet-preimage/try-runtime", + "pallet-proxy/try-runtime", + "pallet-referenda/try-runtime", + "pallet-scheduler/try-runtime", + "pallet-session/try-runtime", + "pallet-staking/try-runtime", + "pallet-timestamp/try-runtime", + "pallet-treasury/try-runtime", + "pallet-tips/try-runtime", + "pallet-babe/try-runtime", + "pallet-vesting/try-runtime", + "pallet-whitelist/try-runtime", + "pallet-utility/try-runtime", + "pallet-xcm/try-runtime", +] +# When enabled, the runtime API will not be build. +# +# This is required by Cumulus to access certain types of the +# runtime without clashing with the runtime API exported functions +# in WASM. +disable-runtime-api = [] + +# A feature that should be enabled when the runtime should be build for on-chain +# deployment. This will disable stuff that shouldn't be part of the on-chain wasm +# to make it smaller like logging for example. +on-chain-release-build = [ + "sp-api/disable-logging", +] + +# Set timing constants (e.g. session period) to faster versions to speed up testing. +fast-runtime = [] + +runtime-metrics = ["runtime-parachains/runtime-metrics", "sp-io/with-tracing"] diff --git a/polkadot/runtime/polkadot/README.adoc b/polkadot/runtime/polkadot/README.adoc new file mode 100644 index 0000000000000000000000000000000000000000..33373310819f975270260a27e94907dcca9498bb --- /dev/null +++ b/polkadot/runtime/polkadot/README.adoc @@ -0,0 +1,5 @@ + += Polkadot Runtime + +placeholder +//TODO Write content :) (https://github.com/paritytech/polkadot/issues/159) diff --git a/polkadot/runtime/polkadot/build.rs b/polkadot/runtime/polkadot/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..428c971bc132a5c7e856e6485246c4fd2ff57822 --- /dev/null +++ b/polkadot/runtime/polkadot/build.rs @@ -0,0 +1,25 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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 Polkadot. If not, see . + +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .import_memory() + .export_heap_base() + .build() +} diff --git a/polkadot/runtime/polkadot/constants/Cargo.toml b/polkadot/runtime/polkadot/constants/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..42a9c685ea826dd989b4052eb2dd99b90949c89e --- /dev/null +++ b/polkadot/runtime/polkadot/constants/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "polkadot-runtime-constants" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +smallvec = "1.8.0" + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../../primitives", default-features = false } +runtime-common = { package = "polkadot-runtime-common", path = "../../common", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-weights = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } + +[features] +default = ["std"] +std = [ + "frame-support/std", + "primitives/std", + "runtime-common/std", + "sp-core/std", + "sp-runtime/std", + "sp-weights/std" +] diff --git a/polkadot/runtime/polkadot/constants/src/lib.rs b/polkadot/runtime/polkadot/constants/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..304d86d1dd7c572531006d76c9aab844daa19a62 --- /dev/null +++ b/polkadot/runtime/polkadot/constants/src/lib.rs @@ -0,0 +1,150 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod weights; + +pub use self::currency::DOLLARS; + +/// Money matters. +pub mod currency { + use primitives::Balance; + + /// The existential deposit. + pub const EXISTENTIAL_DEPOSIT: Balance = 100 * CENTS; + + pub const UNITS: Balance = 10_000_000_000; + pub const DOLLARS: Balance = UNITS; // 10_000_000_000 + pub const GRAND: Balance = DOLLARS * 1_000; // 10_000_000_000_000 + pub const CENTS: Balance = DOLLARS / 100; // 100_000_000 + pub const MILLICENTS: Balance = CENTS / 1_000; // 100_000 + + pub const fn deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 20 * DOLLARS + (bytes as Balance) * 100 * MILLICENTS + } +} + +/// Time and blocks. +pub mod time { + use primitives::{BlockNumber, Moment}; + use runtime_common::prod_or_fast; + pub const MILLISECS_PER_BLOCK: Moment = 6000; + pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; + pub const EPOCH_DURATION_IN_SLOTS: BlockNumber = prod_or_fast!(4 * HOURS, 1 * MINUTES); + + // These time units are defined in number of blocks. + pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); + pub const HOURS: BlockNumber = MINUTES * 60; + pub const DAYS: BlockNumber = HOURS * 24; + pub const WEEKS: BlockNumber = DAYS * 7; + + // 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. + // The choice of is done in accordance to the slot duration and expected target + // block time, for safely resisting network delays of maximum two seconds. + // + pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); +} + +/// Fee-related. +pub mod fee { + use crate::weights::ExtrinsicBaseWeight; + use frame_support::weights::{ + WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, + }; + use primitives::Balance; + use smallvec::smallvec; + pub use sp_runtime::Perbill; + + /// The block saturation level. Fees will be updates based on this value. + pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); + + /// 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, `MAXIMUM_BLOCK_WEIGHT`] + /// - [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. + pub struct WeightToFee; + impl WeightToFeePolynomial for WeightToFee { + type Balance = Balance; + fn polynomial() -> WeightToFeeCoefficients { + // in Polkadot, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: + let p = super::currency::CENTS; + let q = 10 * Balance::from(ExtrinsicBaseWeight::get().ref_time()); + smallvec![WeightToFeeCoefficient { + degree: 1, + negative: false, + coeff_frac: Perbill::from_rational(p % q, q), + coeff_integer: p / q, + }] + } + } +} + +/// XCM protocol related constants. +pub mod xcm { + /// Pluralistic bodies existing within the consensus. + pub mod body { + // Preallocated for the Root body. + #[allow(dead_code)] + const ROOT_INDEX: u32 = 0; + // The bodies corresponding to the Polkadot OpenGov Origins. + pub const FELLOWSHIP_ADMIN_INDEX: u32 = 1; + } +} + +/// System Parachains. +pub mod system_parachain { + /// Statemint parachain ID. + pub const STATEMINT_ID: u32 = 1000; + /// Collectives parachain ID. + pub const COLLECTIVES_ID: u32 = 1001; +} + +#[cfg(test)] +mod tests { + use super::{ + currency::{CENTS, DOLLARS, MILLICENTS}, + fee::WeightToFee, + }; + use crate::weights::ExtrinsicBaseWeight; + use frame_support::weights::WeightToFee as WeightToFeeT; + use runtime_common::MAXIMUM_BLOCK_WEIGHT; + + #[test] + // Test that the fee for `MAXIMUM_BLOCK_WEIGHT` of weight has sane bounds. + fn full_block_fee_is_correct() { + // A full block should cost between 10 and 100 DOLLARS. + let full_block = WeightToFee::weight_to_fee(&MAXIMUM_BLOCK_WEIGHT); + assert!(full_block >= 10 * DOLLARS); + assert!(full_block <= 100 * DOLLARS); + } + + #[test] + // This function tests that the fee for `ExtrinsicBaseWeight` of weight is correct + fn extrinsic_base_fee_is_correct() { + // `ExtrinsicBaseWeight` should cost 1/10 of a CENT + println!("Base: {}", ExtrinsicBaseWeight::get()); + let x = WeightToFee::weight_to_fee(&ExtrinsicBaseWeight::get()); + let y = CENTS / 10; + assert!(x.max(y) - x.min(y) < MILLICENTS); + } +} diff --git a/polkadot/runtime/polkadot/constants/src/weights/block_weights.rs b/polkadot/runtime/polkadot/constants/src/weights/block_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..9608fd534069de346bf98e95b46e6f1c5170d025 --- /dev/null +++ b/polkadot/runtime/polkadot/constants/src/weights/block_weights.rs @@ -0,0 +1,81 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18 (Y/M/D) +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! +//! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Development` +//! WARMUPS: `10`, REPEAT: `100` +//! WEIGHT-PATH: `runtime/polkadot/constants/src/weights/` +//! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` + +// Executed Command: +// ./target/production/polkadot +// benchmark +// overhead +// --chain=polkadot-dev +// --execution=wasm +// --wasm-execution=compiled +// --weight-path=runtime/polkadot/constants/src/weights/ +// --warmup=10 +// --repeat=100 +// --header=./file_header.txt + +use sp_core::parameter_types; +use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; + +parameter_types! { + /// Time to execute an empty block. + /// Calculated by multiplying the *Average* with `1.0` and adding `0`. + /// + /// Stats nanoseconds: + /// Min, Max: 13_546_462, 14_258_156 + /// Average: 13_806_190 + /// Median: 13_798_575 + /// Std-Dev: 141568.11 + /// + /// Percentiles nanoseconds: + /// 99th: 14_144_016 + /// 95th: 14_039_432 + /// 75th: 13_904_965 + pub const BlockExecutionWeight: Weight = + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(13_806_190), 0); +} + +#[cfg(test)] +mod test_weights { + use sp_weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::BlockExecutionWeight::get(); + + // At least 100 µs. + assert!( + w.ref_time() >= 100u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 100 µs." + ); + // At most 50 ms. + assert!( + w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 50 ms." + ); + } +} diff --git a/polkadot/runtime/polkadot/constants/src/weights/extrinsic_weights.rs b/polkadot/runtime/polkadot/constants/src/weights/extrinsic_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..fac87924821f5d98b9c552f016935b45617adfb8 --- /dev/null +++ b/polkadot/runtime/polkadot/constants/src/weights/extrinsic_weights.rs @@ -0,0 +1,81 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18 (Y/M/D) +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! +//! SHORT-NAME: `extrinsic`, LONG-NAME: `ExtrinsicBase`, RUNTIME: `Development` +//! WARMUPS: `10`, REPEAT: `100` +//! WEIGHT-PATH: `runtime/polkadot/constants/src/weights/` +//! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` + +// Executed Command: +// ./target/production/polkadot +// benchmark +// overhead +// --chain=polkadot-dev +// --execution=wasm +// --wasm-execution=compiled +// --weight-path=runtime/polkadot/constants/src/weights/ +// --warmup=10 +// --repeat=100 +// --header=./file_header.txt + +use sp_core::parameter_types; +use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; + +parameter_types! { + /// Time to execute a NO-OP extrinsic, for example `System::remark`. + /// Calculated by multiplying the *Average* with `1.0` and adding `0`. + /// + /// Stats nanoseconds: + /// Min, Max: 125_467, 127_402 + /// Average: 126_045 + /// Median: 126_039 + /// Std-Dev: 310.96 + /// + /// Percentiles nanoseconds: + /// 99th: 126_699 + /// 95th: 126_620 + /// 75th: 126_207 + pub const ExtrinsicBaseWeight: Weight = + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(126_045), 0); +} + +#[cfg(test)] +mod test_weights { + use sp_weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::ExtrinsicBaseWeight::get(); + + // At least 10 µs. + assert!( + w.ref_time() >= 10u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 10 µs." + ); + // At most 1 ms. + assert!( + w.ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 1 ms." + ); + } +} diff --git a/polkadot/runtime/polkadot/constants/src/weights/mod.rs b/polkadot/runtime/polkadot/constants/src/weights/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..23812ce7ed0528c394f84042fb9842eb617a834b --- /dev/null +++ b/polkadot/runtime/polkadot/constants/src/weights/mod.rs @@ -0,0 +1,28 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Expose the auto generated weight files. + +pub mod block_weights; +pub mod extrinsic_weights; +pub mod paritydb_weights; +pub mod rocksdb_weights; + +pub use block_weights::BlockExecutionWeight; +pub use extrinsic_weights::ExtrinsicBaseWeight; +pub use paritydb_weights::constants::ParityDbWeight; +pub use rocksdb_weights::constants::RocksDbWeight; diff --git a/polkadot/runtime/polkadot/constants/src/weights/paritydb_weights.rs b/polkadot/runtime/polkadot/constants/src/weights/paritydb_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..ae7bedc394f8cd485de9ee72064f351d787450e3 --- /dev/null +++ b/polkadot/runtime/polkadot/constants/src/weights/paritydb_weights.rs @@ -0,0 +1,109 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-03-30 (Y/M/D) +//! +//! DATABASE: `ParityDb`, RUNTIME: `Polkadot` +//! BLOCK-NUM: `BlockId::Number(9653477)` +//! SKIP-WRITE: `false`, SKIP-READ: `false`, WARMUPS: `1` +//! STATE-VERSION: `V0`, STATE-CACHE-SIZE: `0` +//! WEIGHT-PATH: `runtime/polkadot/constants/src/weights/` +//! METRIC: `Average`, WEIGHT-MUL: `1.1`, WEIGHT-ADD: `0` + +// Executed Command: +// ./target/production/polkadot +// benchmark-storage +// --db=paritydb +// --state-version=0 +// --mul=1.1 +// --weight-path=runtime/polkadot/constants/src/weights/ + +/// Storage DB weights for the `Polkadot` runtime and `ParityDb`. +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// `ParityDB` can be enabled with a feature flag, but is still experimental. These weights + /// are available for brave runtime engineers who may want to try this out as default. + pub const ParityDbWeight: RuntimeDbWeight = RuntimeDbWeight { + /// Time to read one storage item. + /// Calculated by multiplying the *Average* of all values with `1.1` and adding `0`. + /// + /// Stats [NS]: + /// Min, Max: 4_611, 13_478_005 + /// Average: 10_750 + /// Median: 10_655 + /// Std-Dev: 12214.49 + /// + /// Percentiles [NS]: + /// 99th: 14_451 + /// 95th: 12_588 + /// 75th: 11_200 + read: 11_826 * constants::WEIGHT_REF_TIME_PER_NANOS, + + /// Time to write one storage item. + /// Calculated by multiplying the *Average* of all values with `1.1` and adding `0`. + /// + /// Stats [NS]: + /// Min, Max: 8_023, 47_367_740 + /// Average: 34_592 + /// Median: 32_703 + /// Std-Dev: 49417.24 + /// + /// Percentiles [NS]: + /// 99th: 69_379 + /// 95th: 47_168 + /// 75th: 35_252 + write: 38_052 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use super::constants::ParityDbWeight as W; + use frame_support::weights::constants; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn bound() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/polkadot/runtime/polkadot/constants/src/weights/rocksdb_weights.rs b/polkadot/runtime/polkadot/constants/src/weights/rocksdb_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..029f892b01dc247c7906f90441b63e6da5903297 --- /dev/null +++ b/polkadot/runtime/polkadot/constants/src/weights/rocksdb_weights.rs @@ -0,0 +1,108 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-03-29 (Y/M/D) +//! +//! DATABASE: `RocksDb`, RUNTIME: `Polkadot` +//! BLOCK-NUM: `BlockId::Number(9643856)` +//! SKIP-WRITE: `false`, SKIP-READ: `false`, WARMUPS: `1` +//! STATE-VERSION: `V0`, STATE-CACHE-SIZE: `0` +//! WEIGHT-PATH: `runtime/polkadot/constants/src/weights/` +//! METRIC: `Average`, WEIGHT-MUL: `1.1`, WEIGHT-ADD: `0` + +// Executed Command: +// ./target/production/polkadot +// benchmark-storage +// --state-version=0 +// --mul=1.1 +// --weight-path=runtime/polkadot/constants/src/weights/ + +/// Storage DB weights for the `Polkadot` runtime and `RocksDb`. +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// By default, Substrate uses `RocksDB`, so this will be the weight used throughout + /// the runtime. + pub const RocksDbWeight: RuntimeDbWeight = RuntimeDbWeight { + /// Time to read one storage item. + /// Calculated by multiplying the *Average* of all values with `1.1` and adding `0`. + /// + /// Stats [NS]: + /// Min, Max: 5_015, 1_441_022 + /// Average: 18_635 + /// Median: 17_795 + /// Std-Dev: 4829.75 + /// + /// Percentiles [NS]: + /// 99th: 32_074 + /// 95th: 26_658 + /// 75th: 19_363 + read: 20_499 * constants::WEIGHT_REF_TIME_PER_NANOS, + + /// Time to write one storage item. + /// Calculated by multiplying the *Average* of all values with `1.1` and adding `0`. + /// + /// Stats [NS]: + /// Min, Max: 16_368, 34_500_937 + /// Average: 75_882 + /// Median: 74_236 + /// Std-Dev: 64706.41 + /// + /// Percentiles [NS]: + /// 99th: 111_151 + /// 95th: 92_666 + /// 75th: 80_297 + write: 83_471 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use super::constants::RocksDbWeight as W; + use frame_support::weights::constants; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn bound() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/polkadot/runtime/polkadot/src/bag_thresholds.rs b/polkadot/runtime/polkadot/src/bag_thresholds.rs new file mode 100644 index 0000000000000000000000000000000000000000..56c764f7a6985424f06e9bc289126b2b68be3aa2 --- /dev/null +++ b/polkadot/runtime/polkadot/src/bag_thresholds.rs @@ -0,0 +1,234 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated bag thresholds. +//! +//! Generated on 2021-10-14T08:36:33.156699497+00:00 +//! for the polkadot runtime. + +/// Existential weight for this runtime. +#[cfg(any(test, feature = "std"))] +#[allow(unused)] +pub const EXISTENTIAL_WEIGHT: u64 = 10_000_000_000; + +/// Constant ratio between bags for this runtime. +#[cfg(any(test, feature = "std"))] +#[allow(unused)] +pub const CONSTANT_RATIO: f64 = 1.1131723507077667; + +/// Upper thresholds delimiting the bag list. +pub const THRESHOLDS: [u64; 200] = [ + 10_000_000_000, + 11_131_723_507, + 12_391_526_824, + 13_793_905_044, + 15_354_993_703, + 17_092_754_435, + 19_027_181_634, + 21_180_532_507, + 23_577_583_160, + 26_245_913_670, + 29_216_225_417, + 32_522_694_326, + 36_203_364_094, + 40_300_583_912, + 44_861_495_728, + 49_938_576_656, + 55_590_242_767, + 61_881_521_217, + 68_884_798_439, + 76_680_653_006, + 85_358_782_760, + 95_019_036_859, + 105_772_564_622, + 117_743_094_401, + 131_068_357_174, + 145_901_671_259, + 162_413_706_368, + 180_794_447_305, + 201_255_379_901, + 224_031_924_337, + 249_386_143_848, + 277_609_759_981, + 309_027_509_097, + 344_000_878_735, + 382_932_266_827, + 426_269_611_626, + 474_511_545_609, + 528_213_132_664, + 587_992_254_562, + 654_536_720_209, + 728_612_179_460, + 811_070_932_564, + 902_861_736_593, + 1_005_040_721_687, + 1_118_783_542_717, + 1_245_398_906_179, + 1_386_343_627_960, + 1_543_239_395_225, + 1_717_891_425_287, + 1_912_309_236_147, + 2_128_729_767_682, + 2_369_643_119_512, + 2_637_821_201_686, + 2_936_349_627_828, + 3_268_663_217_709, + 3_638_585_517_729, + 4_050_372_794_022, + 4_508_763_004_364, + 5_019_030_312_352, + 5_587_045_771_074, + 6_219_344_874_498, + 6_923_202_753_807, + 7_706_717_883_882, + 8_578_905_263_043, + 9_549_800_138_161, + 10_630_573_468_586, + 11_833_660_457_397, + 13_172_903_628_838, + 14_663_712_098_160, + 16_323_238_866_411, + 18_170_578_180_087, + 20_226_985_226_447, + 22_516_120_692_255, + 25_064_322_999_817, + 27_900_911_352_605, + 31_058_523_077_268, + 34_573_489_143_434, + 38_486_252_181_966, + 42_841_831_811_331, + 47_690_342_626_046, + 53_087_570_807_094, + 59_095_615_988_698, + 65_783_605_766_662, + 73_228_491_069_308, + 81_515_931_542_404, + 90_741_281_135_191, + 101_010_685_227_495, + 112_442_301_921_293, + 125_167_661_548_718, + 139_333_180_038_781, + 155_101_843_555_358, + 172_655_083_789_626, + 192_194_865_483_744, + 213_946_010_204_502, + 238_158_783_103_893, + 265_111_772_429_462, + 295_115_094_915_607, + 328_513_963_936_552, + 365_692_661_475_578, + 407_078_959_611_349, + 453_149_042_394_237, + 504_432_984_742_966, + 561_520_851_400_862, + 625_069_486_125_324, + 695_810_069_225_823, + 774_556_530_406_243, + 862_214_913_708_369, + 959_793_802_308_039, + 1_068_415_923_109_985, + 1_189_331_064_661_951, + 1_323_930_457_019_515, + 1_473_762_779_014_021, + 1_640_551_977_100_649, + 1_826_217_100_807_404, + 2_032_894_383_008_501, + 2_262_961_819_074_188, + 2_519_066_527_700_738, + 2_804_155_208_229_882, + 3_121_508_044_894_685, + 3_474_776_448_088_622, + 3_868_025_066_902_796, + 4_305_778_556_320_752, + 4_793_073_637_166_665, + 5_335_517_047_800_242, + 5_939_350_054_341_159, + 6_611_520_261_667_250, + 7_359_761_551_432_161, + 8_192_683_066_856_378, + 9_119_868_268_136_230, + 10_151_985_198_186_376, + 11_300_909_227_415_580, + 12_579_859_689_817_292, + 14_003_551_982_487_792, + 15_588_366_878_604_342, + 17_352_539_001_951_086, + 19_316_366_631_550_092, + 21_502_445_250_375_680, + 23_935_927_525_325_748, + 26_644_812_709_737_600, + 29_660_268_798_266_784, + 33_016_991_140_790_860, + 36_753_601_641_491_664, + 40_913_093_136_236_104, + 45_543_324_061_189_736, + 50_697_569_104_240_168, + 56_435_132_174_936_472, + 62_822_028_745_677_552, + 69_931_745_415_056_768, + 77_846_085_432_775_824, + 86_656_109_914_600_688, + 96_463_185_576_826_656, + 107_380_151_045_315_664, + 119_532_615_158_469_088, + 133_060_402_202_199_856, + 148_119_160_705_543_712, + 164_882_154_307_451_552, + 183_542_255_300_186_560, + 204_314_163_786_713_728, + 227_436_877_985_347_776, + 253_176_444_104_585_088, + 281_829_017_427_734_464, + 313_724_269_827_691_328, + 349_229_182_918_168_832, + 388_752_270_484_770_624, + 432_748_278_778_513_664, + 481_723_418_752_617_984, + 536_241_190_443_833_600, + 596_928_866_512_693_376, + 664_484_709_541_257_600, + 739_686_006_129_409_280, + 823_398_010_228_713_984, + 916_583_898_614_395_264, + 1_020_315_853_041_475_584, + 1_135_787_396_594_579_584, + 1_264_327_126_171_442_688, + 1_407_413_999_103_859_968, + 1_566_694_349_801_462_272, + 1_744_000_832_209_069_824, + 1_941_373_506_026_471_680, + 2_161_083_309_305_266_176, + 2_405_658_187_494_662_656, + 2_677_912_179_572_818_944, + 2_980_977_795_924_034_048, + 3_318_342_060_496_414_208, + 3_693_886_631_935_247_360, + 4_111_932_465_319_354_368, + 4_577_289_528_371_127_808, + 5_095_312_144_166_932_480, + 5_671_960_597_112_134_656, + 6_313_869_711_009_142_784, + 7_028_425_188_266_614_784, + 7_823_848_588_596_424_704, + 8_709_291_924_949_524_480, + 9_694_942_965_096_232_960, + 10_792_142_450_433_898_496, + 12_013_514_580_722_579_456, + 13_373_112_266_084_982_784, + 14_886_578_817_516_689_408, + 16_571_327_936_291_497_984, + 18_446_744_073_709_551_615, +]; diff --git a/polkadot/runtime/polkadot/src/governance/mod.rs b/polkadot/runtime/polkadot/src/governance/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..79c904622dddea96112c29f4e58bdf92f53de3b8 --- /dev/null +++ b/polkadot/runtime/polkadot/src/governance/mod.rs @@ -0,0 +1,97 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! New governance configurations for the Polkadot runtime. + +use super::*; +use crate::xcm_config::CollectivesLocation; +use frame_support::{parameter_types, traits::EitherOf}; +use frame_system::EnsureRootWithSuccess; +use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; +use xcm::latest::BodyId; + +mod origins; +pub use origins::{ + pallet_custom_origins, AuctionAdmin, FellowshipAdmin, GeneralAdmin, LeaseAdmin, + ReferendumCanceller, ReferendumKiller, Spender, StakingAdmin, Treasurer, WhitelistedCaller, +}; +mod tracks; +pub use tracks::TracksInfo; + +parameter_types! { + pub const VoteLockingPeriod: BlockNumber = prod_or_fast!(28 * DAYS, 1); +} + +impl pallet_conviction_voting::Config for Runtime { + type WeightInfo = weights::pallet_conviction_voting::WeightInfo; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type VoteLockingPeriod = VoteLockingPeriod; + type MaxVotes = ConstU32<512>; + type MaxTurnout = + frame_support::traits::tokens::currency::ActiveIssuanceOf; + type Polls = Referenda; +} + +parameter_types! { + pub const AlarmInterval: BlockNumber = 1; + pub const SubmissionDeposit: Balance = 1 * DOLLARS; + pub const UndecidingTimeout: BlockNumber = 14 * DAYS; +} + +parameter_types! { + pub const MaxBalance: Balance = Balance::max_value(); +} +pub type TreasurySpender = EitherOf, Spender>; + +impl origins::pallet_custom_origins::Config for Runtime {} + +parameter_types! { + // Fellows pluralistic body. + pub const FellowsBodyId: BodyId = BodyId::Technical; +} + +impl pallet_whitelist::Config for Runtime { + type WeightInfo = weights::pallet_whitelist::WeightInfo; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WhitelistOrigin = EitherOfDiverse< + EnsureRoot, + EnsureXcm>, + >; + type DispatchWhitelistedOrigin = EitherOf, WhitelistedCaller>; + type Preimages = Preimage; +} + +impl pallet_referenda::Config for Runtime { + type WeightInfo = weights::pallet_referenda::WeightInfo; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type Scheduler = Scheduler; + type Currency = Balances; + type SubmitOrigin = frame_system::EnsureSigned; + type CancelOrigin = EitherOf, ReferendumCanceller>; + type KillOrigin = EitherOf, ReferendumKiller>; + type Slash = Treasury; + type Votes = pallet_conviction_voting::VotesOf; + type Tally = pallet_conviction_voting::TallyOf; + type SubmissionDeposit = SubmissionDeposit; + type MaxQueued = ConstU32<100>; + type UndecidingTimeout = UndecidingTimeout; + type AlarmInterval = AlarmInterval; + type Tracks = TracksInfo; + type Preimages = Preimage; +} diff --git a/polkadot/runtime/polkadot/src/governance/origins.rs b/polkadot/runtime/polkadot/src/governance/origins.rs new file mode 100644 index 0000000000000000000000000000000000000000..551e05e556db414731efe5a003709509544cb63a --- /dev/null +++ b/polkadot/runtime/polkadot/src/governance/origins.rs @@ -0,0 +1,151 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Custom origins for governance interventions. + +pub use pallet_custom_origins::*; + +#[frame_support::pallet] +pub mod pallet_custom_origins { + use crate::{Balance, DOLLARS, GRAND}; + use frame_support::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + #[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)] + #[pallet::origin] + pub enum Origin { + /// Origin able to cancel slashes and manage minimum commission. + StakingAdmin, + /// Origin for spending up to $10,000,000 DOT from the treasury as well as generally + /// administering it. + Treasurer, + /// Origin for managing the composition of the fellowship. + FellowshipAdmin, + /// Origin for managing the registrar and permissioned HRMP channel operations. + GeneralAdmin, + /// Origin for starting auctions. + AuctionAdmin, + /// Origin able to force slot leases. + LeaseAdmin, + /// Origin able to cancel referenda. + ReferendumCanceller, + /// Origin able to kill referenda. + ReferendumKiller, + /// Origin able to spend around $250 from the treasury at once. + SmallTipper, + /// Origin able to spend around $1,000 from the treasury at once. + BigTipper, + /// Origin able to spend around $10,000 from the treasury at once. + SmallSpender, + /// Origin able to spend around $100,000 from the treasury at once. + MediumSpender, + /// Origin able to spend up to $1,000,000 DOT from the treasury at once. + BigSpender, + /// Origin able to dispatch a whitelisted call. + WhitelistedCaller, + } + + macro_rules! decl_unit_ensures { + ( $name:ident: $success_type:ty = $success:expr ) => { + pub struct $name; + impl> + From> + EnsureOrigin for $name + { + type Success = $success_type; + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + Origin::$name => Ok($success), + r => Err(O::from(r)), + }) + } + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + Ok(O::from(Origin::$name)) + } + } + }; + ( $name:ident ) => { decl_unit_ensures! { $name : () = () } }; + ( $name:ident: $success_type:ty = $success:expr, $( $rest:tt )* ) => { + decl_unit_ensures! { $name: $success_type = $success } + decl_unit_ensures! { $( $rest )* } + }; + ( $name:ident, $( $rest:tt )* ) => { + decl_unit_ensures! { $name } + decl_unit_ensures! { $( $rest )* } + }; + () => {} + } + decl_unit_ensures!( + StakingAdmin, + Treasurer, + FellowshipAdmin, + GeneralAdmin, + AuctionAdmin, + LeaseAdmin, + ReferendumCanceller, + ReferendumKiller, + WhitelistedCaller, + ); + + macro_rules! decl_ensure { + ( + $vis:vis type $name:ident: EnsureOrigin { + $( $item:ident = $success:expr, )* + } + ) => { + $vis struct $name; + impl> + From> + EnsureOrigin for $name + { + type Success = $success_type; + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + $( + Origin::$item => Ok($success), + )* + r => Err(O::from(r)), + }) + } + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + // By convention the more privileged origins go later, so for greatest chance + // of success, we want the last one. + let _result: Result = Err(()); + $( + let _result: Result = Ok(O::from(Origin::$item)); + )* + _result + } + } + } + } + + decl_ensure! { + pub type Spender: EnsureOrigin { + SmallTipper = 250 * DOLLARS, + BigTipper = 1 * GRAND, + SmallSpender = 10 * GRAND, + MediumSpender = 100 * GRAND, + BigSpender = 1_000 * GRAND, + Treasurer = 10_000 * GRAND, + } + } +} diff --git a/polkadot/runtime/polkadot/src/governance/tracks.rs b/polkadot/runtime/polkadot/src/governance/tracks.rs new file mode 100644 index 0000000000000000000000000000000000000000..2b6d470e516e64cd31b791c724670f5bbf8c556c --- /dev/null +++ b/polkadot/runtime/polkadot/src/governance/tracks.rs @@ -0,0 +1,319 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Track configurations for governance. + +use super::*; + +const fn percent(x: i32) -> sp_arithmetic::FixedI64 { + sp_arithmetic::FixedI64::from_rational(x as u128, 100) +} +use pallet_referenda::Curve; +const APP_ROOT: Curve = Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_ROOT: Curve = Curve::make_linear(28, 28, percent(0), percent(50)); +const APP_STAKING_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_STAKING_ADMIN: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_TREASURER: Curve = Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_TREASURER: Curve = Curve::make_linear(28, 28, percent(0), percent(50)); +const APP_FELLOWSHIP_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_FELLOWSHIP_ADMIN: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_GENERAL_ADMIN: Curve = + Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_GENERAL_ADMIN: Curve = + Curve::make_reciprocal(7, 28, percent(10), percent(0), percent(50)); +const APP_AUCTION_ADMIN: Curve = + Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_AUCTION_ADMIN: Curve = + Curve::make_reciprocal(7, 28, percent(10), percent(0), percent(50)); +const APP_LEASE_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_LEASE_ADMIN: Curve = Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_REFERENDUM_CANCELLER: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_REFERENDUM_CANCELLER: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_REFERENDUM_KILLER: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_REFERENDUM_KILLER: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_SMALL_TIPPER: Curve = Curve::make_linear(10, 28, percent(50), percent(100)); +const SUP_SMALL_TIPPER: Curve = Curve::make_reciprocal(1, 28, percent(4), percent(0), percent(50)); +const APP_BIG_TIPPER: Curve = Curve::make_linear(10, 28, percent(50), percent(100)); +const SUP_BIG_TIPPER: Curve = Curve::make_reciprocal(8, 28, percent(1), percent(0), percent(50)); +const APP_SMALL_SPENDER: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_SMALL_SPENDER: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_MEDIUM_SPENDER: Curve = Curve::make_linear(23, 28, percent(50), percent(100)); +const SUP_MEDIUM_SPENDER: Curve = + Curve::make_reciprocal(16, 28, percent(1), percent(0), percent(50)); +const APP_BIG_SPENDER: Curve = Curve::make_linear(28, 28, percent(50), percent(100)); +const SUP_BIG_SPENDER: Curve = Curve::make_reciprocal(20, 28, percent(1), percent(0), percent(50)); +const APP_WHITELISTED_CALLER: Curve = + Curve::make_reciprocal(16, 28 * 24, percent(96), percent(50), percent(100)); +const SUP_WHITELISTED_CALLER: Curve = + Curve::make_reciprocal(1, 28, percent(20), percent(5), percent(50)); + +const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 15] = [ + ( + 0, + pallet_referenda::TrackInfo { + name: "root", + max_deciding: 1, + decision_deposit: 100 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 24 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_ROOT, + min_support: SUP_ROOT, + }, + ), + ( + 1, + pallet_referenda::TrackInfo { + name: "whitelisted_caller", + max_deciding: 100, + decision_deposit: 10 * GRAND, + prepare_period: 30 * MINUTES, + decision_period: 28 * DAYS, + confirm_period: 10 * MINUTES, + min_enactment_period: 10 * MINUTES, + min_approval: APP_WHITELISTED_CALLER, + min_support: SUP_WHITELISTED_CALLER, + }, + ), + ( + 10, + pallet_referenda::TrackInfo { + name: "staking_admin", + max_deciding: 10, + decision_deposit: 5 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_STAKING_ADMIN, + min_support: SUP_STAKING_ADMIN, + }, + ), + ( + 11, + pallet_referenda::TrackInfo { + name: "treasurer", + max_deciding: 10, + decision_deposit: 1 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_TREASURER, + min_support: SUP_TREASURER, + }, + ), + ( + 12, + pallet_referenda::TrackInfo { + name: "lease_admin", + max_deciding: 10, + decision_deposit: 5 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_LEASE_ADMIN, + min_support: SUP_LEASE_ADMIN, + }, + ), + ( + 13, + pallet_referenda::TrackInfo { + name: "fellowship_admin", + max_deciding: 10, + decision_deposit: 5 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_FELLOWSHIP_ADMIN, + min_support: SUP_FELLOWSHIP_ADMIN, + }, + ), + ( + 14, + pallet_referenda::TrackInfo { + name: "general_admin", + max_deciding: 10, + decision_deposit: 5 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_GENERAL_ADMIN, + min_support: SUP_GENERAL_ADMIN, + }, + ), + ( + 15, + pallet_referenda::TrackInfo { + name: "auction_admin", + max_deciding: 10, + decision_deposit: 5 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_AUCTION_ADMIN, + min_support: SUP_AUCTION_ADMIN, + }, + ), + ( + 20, + pallet_referenda::TrackInfo { + name: "referendum_canceller", + max_deciding: 1_000, + decision_deposit: 10 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 7 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_REFERENDUM_CANCELLER, + min_support: SUP_REFERENDUM_CANCELLER, + }, + ), + ( + 21, + pallet_referenda::TrackInfo { + name: "referendum_killer", + max_deciding: 1_000, + decision_deposit: 50 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_REFERENDUM_KILLER, + min_support: SUP_REFERENDUM_KILLER, + }, + ), + ( + 30, + pallet_referenda::TrackInfo { + name: "small_tipper", + max_deciding: 200, + decision_deposit: 1 * DOLLARS, + prepare_period: 1 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 10 * MINUTES, + min_enactment_period: 1 * MINUTES, + min_approval: APP_SMALL_TIPPER, + min_support: SUP_SMALL_TIPPER, + }, + ), + ( + 31, + pallet_referenda::TrackInfo { + name: "big_tipper", + max_deciding: 100, + decision_deposit: 10 * DOLLARS, + prepare_period: 10 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 1 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_BIG_TIPPER, + min_support: SUP_BIG_TIPPER, + }, + ), + ( + 32, + pallet_referenda::TrackInfo { + name: "small_spender", + max_deciding: 50, + decision_deposit: 100 * DOLLARS, + prepare_period: 4 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 12 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_SMALL_SPENDER, + min_support: SUP_SMALL_SPENDER, + }, + ), + ( + 33, + pallet_referenda::TrackInfo { + name: "medium_spender", + max_deciding: 50, + decision_deposit: 200 * DOLLARS, + prepare_period: 4 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 24 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_MEDIUM_SPENDER, + min_support: SUP_MEDIUM_SPENDER, + }, + ), + ( + 34, + pallet_referenda::TrackInfo { + name: "big_spender", + max_deciding: 50, + decision_deposit: 400 * DOLLARS, + prepare_period: 4 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 48 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_BIG_SPENDER, + min_support: SUP_BIG_SPENDER, + }, + ), +]; + +pub struct TracksInfo; +impl pallet_referenda::TracksInfo for TracksInfo { + type Id = u16; + type RuntimeOrigin = ::PalletsOrigin; + fn tracks() -> &'static [(Self::Id, pallet_referenda::TrackInfo)] { + &TRACKS_DATA[..] + } + fn track_for(id: &Self::RuntimeOrigin) -> Result { + if let Ok(system_origin) = frame_system::RawOrigin::try_from(id.clone()) { + match system_origin { + frame_system::RawOrigin::Root => Ok(0), + _ => Err(()), + } + } else if let Ok(custom_origin) = origins::Origin::try_from(id.clone()) { + match custom_origin { + origins::Origin::WhitelistedCaller => Ok(1), + // General admin + origins::Origin::StakingAdmin => Ok(10), + origins::Origin::Treasurer => Ok(11), + origins::Origin::LeaseAdmin => Ok(12), + origins::Origin::FellowshipAdmin => Ok(13), + origins::Origin::GeneralAdmin => Ok(14), + origins::Origin::AuctionAdmin => Ok(15), + // Referendum admins + origins::Origin::ReferendumCanceller => Ok(20), + origins::Origin::ReferendumKiller => Ok(21), + // Limited treasury spenders + origins::Origin::SmallTipper => Ok(30), + origins::Origin::BigTipper => Ok(31), + origins::Origin::SmallSpender => Ok(32), + origins::Origin::MediumSpender => Ok(33), + origins::Origin::BigSpender => Ok(34), + } + } else { + Err(()) + } + } +} +pallet_referenda::impl_tracksinfo_get!(TracksInfo, Balance, BlockNumber); diff --git a/polkadot/runtime/polkadot/src/lib.rs b/polkadot/runtime/polkadot/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..c4458076cb3d9e6516d53fd61b7da08dcf9b1bcc --- /dev/null +++ b/polkadot/runtime/polkadot/src/lib.rs @@ -0,0 +1,2586 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Polkadot runtime. This can be compiled with `#[no_std]`, ready for Wasm. + +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. +#![recursion_limit = "512"] + +use pallet_transaction_payment::CurrencyAdapter; +use runtime_common::{ + auctions, claims, crowdloan, impl_runtime_weights, impls::DealWithFees, paras_registrar, + prod_or_fast, slots, BlockHashCount, BlockLength, CurrencyToVote, SlowAdjustingFeeUpdate, +}; + +use runtime_parachains::{ + assigner_parachains as parachains_assigner_parachains, + configuration as parachains_configuration, disputes as parachains_disputes, + disputes::slashing as parachains_slashing, + dmp as parachains_dmp, hrmp as parachains_hrmp, inclusion as parachains_inclusion, + inclusion::{AggregateMessageOrigin, UmpQueueId}, + initializer as parachains_initializer, origin as parachains_origin, paras as parachains_paras, + paras_inherent as parachains_paras_inherent, reward_points as parachains_reward_points, + runtime_api_impl::v5 as parachains_runtime_api_impl, + scheduler as parachains_scheduler, session_info as parachains_session_info, + shared as parachains_shared, +}; + +use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; +use beefy_primitives::ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}; +use frame_election_provider_support::{ + bounds::ElectionBoundsBuilder, generate_solution_type, onchain, SequentialPhragmen, +}; +use frame_support::{ + construct_runtime, parameter_types, + traits::{ + ConstU32, EitherOf, EitherOfDiverse, InstanceFilter, KeyOwnerProofSystem, PrivilegeCmp, + ProcessMessage, ProcessMessageError, WithdrawReasons, + }, + weights::{ConstantMultiplier, WeightMeter}, + PalletId, +}; +use frame_system::EnsureRoot; +use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +use pallet_session::historical as session_historical; +use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use primitives::{ + slashing, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, + CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash, + Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce, + OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, SessionInfo, Signature, + ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, LOWEST_PUBLIC_ID, + PARACHAIN_KEY_TYPE_ID, +}; +use sp_core::OpaqueMetadata; +use sp_mmr_primitives as mmr; +use sp_runtime::{ + create_runtime_str, + curve::PiecewiseLinear, + generic, impl_opaque_keys, + traits::{ + AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT, + OpaqueKeys, SaturatedConversion, Verify, + }, + transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, FixedU128, KeyTypeId, Perbill, Percent, Permill, RuntimeDebug, +}; +use sp_staking::SessionIndex; +use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*}; +#[cfg(any(feature = "std", test))] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; +use xcm::latest::Junction; + +pub use frame_system::Call as SystemCall; +pub use pallet_balances::Call as BalancesCall; +pub use pallet_election_provider_multi_phase::Call as EPMCall; +#[cfg(feature = "std")] +pub use pallet_staking::StakerStatus; +use pallet_staking::UseValidatorsMap; +pub use pallet_timestamp::Call as TimestampCall; +use sp_runtime::traits::Get; +#[cfg(any(feature = "std", test))] +pub use sp_runtime::BuildStorage; + +/// Constant values used within the runtime. +use polkadot_runtime_constants::{currency::*, fee::*, time::*}; + +// Weights used in the runtime. +mod weights; + +mod bag_thresholds; + +// Governance configurations. +pub mod governance; +use governance::{ + pallet_custom_origins, AuctionAdmin, FellowshipAdmin, GeneralAdmin, LeaseAdmin, StakingAdmin, + Treasurer, TreasurySpender, +}; + +pub mod xcm_config; + +impl_runtime_weights!(polkadot_runtime_constants); + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +// Polkadot version identifier; +/// Runtime version (Polkadot). +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("polkadot"), + impl_name: create_runtime_str!("parity-polkadot"), + authoring_version: 0, + spec_version: 9430, + impl_version: 0, + #[cfg(not(feature = "disable-runtime-api"))] + apis: RUNTIME_API_VERSIONS, + #[cfg(feature = "disable-runtime-api")] + apis: sp_version::create_apis_vec![[]], + transaction_version: 24, + state_version: 0, +}; + +/// The BABE epoch configuration at genesis. +pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration = + babe_primitives::BabeEpochConfiguration { + c: PRIMARY_PROBABILITY, + allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots, + }; + +/// Native version. +#[cfg(any(feature = "std", test))] +pub fn native_version() -> NativeVersion { + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } +} + +parameter_types! { + pub const Version: RuntimeVersion = VERSION; + pub const SS58Prefix: u8 = 0; +} + +impl frame_system::Config for Runtime { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = BlockWeights; + type BlockLength = BlockLength; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = Nonce; + type Hash = Hash; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = AccountIdLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type DbWeight = RocksDbWeight; + type Version = Version; + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = weights::frame_system::WeightInfo; + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * + BlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; + pub const NoPreimagePostponement: Option = Some(10); +} + +/// Used the compare the privilege of an origin inside the scheduler. +pub struct OriginPrivilegeCmp; + +impl PrivilegeCmp for OriginPrivilegeCmp { + fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option { + if left == right { + return Some(Ordering::Equal) + } + + match (left, right) { + // Root is greater than anything. + (OriginCaller::system(frame_system::RawOrigin::Root), _) => Some(Ordering::Greater), + // For every other origin we don't care, as they are not used for `ScheduleOrigin`. + _ => None, + } + } +} + +impl pallet_scheduler::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaximumSchedulerWeight; + // The goal of having ScheduleOrigin include AuctionAdmin is to allow the auctions track of + // OpenGov to schedule periodic auctions. + type ScheduleOrigin = EitherOf, AuctionAdmin>; + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type WeightInfo = weights::pallet_scheduler::WeightInfo; + type OriginPrivilegeCmp = OriginPrivilegeCmp; + type Preimages = Preimage; +} + +parameter_types! { + pub const PreimageMaxSize: u32 = 4096 * 1024; + pub const PreimageBaseDeposit: Balance = deposit(2, 64); + pub const PreimageByteDeposit: Balance = deposit(0, 1); +} + +impl pallet_preimage::Config for Runtime { + type WeightInfo = weights::pallet_preimage::WeightInfo; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type BaseDeposit = PreimageBaseDeposit; + type ByteDeposit = PreimageByteDeposit; +} + +parameter_types! { + pub EpochDuration: u64 = prod_or_fast!( + EPOCH_DURATION_IN_SLOTS as u64, + 2 * MINUTES as u64, + "DOT_EPOCH_DURATION" + ); + pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; + pub ReportLongevity: u64 = + BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get(); +} + +impl pallet_babe::Config for Runtime { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; + + // session module is the trigger + type EpochChangeTrigger = pallet_babe::ExternalTrigger; + + type DisabledValidators = Session; + + type WeightInfo = (); + + type MaxAuthorities = MaxAuthorities; + type MaxNominators = MaxNominatorRewardedPerValidator; + + type KeyOwnerProof = + >::Proof; + + type EquivocationReportSystem = + pallet_babe::EquivocationReportSystem; +} + +parameter_types! { + pub const IndexDeposit: Balance = 10 * DOLLARS; +} + +impl pallet_indices::Config for Runtime { + type AccountIndex = AccountIndex; + type Currency = Balances; + type Deposit = IndexDeposit; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_indices::WeightInfo; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = weights::pallet_balances::WeightInfo; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +parameter_types! { + pub const TransactionByteFee: Balance = 10 * MILLICENTS; + /// This value increases the priority of `Operational` transactions by adding + /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`. + pub const OperationalFeeMultiplier: u8 = 5; +} + +impl pallet_transaction_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter>; + type OperationalFeeMultiplier = OperationalFeeMultiplier; + type WeightToFee = WeightToFee; + type LengthToFee = ConstantMultiplier; + type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; +} + +parameter_types! { + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; +} +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = Babe; + type MinimumPeriod = MinimumPeriod; + type WeightInfo = weights::pallet_timestamp::WeightInfo; +} + +impl pallet_authorship::Config for Runtime { + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; + type EventHandler = (Staking, ImOnline); +} + +impl_opaque_keys! { + pub struct SessionKeys { + pub grandpa: Grandpa, + pub babe: Babe, + pub im_online: ImOnline, + pub para_validator: Initializer, + pub para_assignment: ParaSessionInfo, + pub authority_discovery: AuthorityDiscovery, + } +} + +impl pallet_session::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = AccountId; + type ValidatorIdOf = pallet_staking::StashOf; + type ShouldEndSession = Babe; + type NextSessionRotation = Babe; + type SessionManager = pallet_session::historical::NoteHistoricalRoot; + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; + type WeightInfo = weights::pallet_session::WeightInfo; +} + +impl pallet_session::historical::Config for Runtime { + type FullIdentification = pallet_staking::Exposure; + type FullIdentificationOf = pallet_staking::ExposureOf; +} + +parameter_types! { + // phase durations. 1/4 of the last session for each. + // in testing: 1min or half of the session for each + pub SignedPhase: u32 = prod_or_fast!( + EPOCH_DURATION_IN_SLOTS / 4, + (1 * MINUTES).min(EpochDuration::get().saturated_into::() / 2), + "DOT_SIGNED_PHASE" + ); + pub UnsignedPhase: u32 = prod_or_fast!( + EPOCH_DURATION_IN_SLOTS / 4, + (1 * MINUTES).min(EpochDuration::get().saturated_into::() / 2), + "DOT_UNSIGNED_PHASE" + ); + + // signed config + pub const SignedMaxSubmissions: u32 = 16; + pub const SignedMaxRefunds: u32 = 16 / 4; + // 40 DOTs fixed deposit.. + pub const SignedDepositBase: Balance = deposit(2, 0); + // 0.01 DOT per KB of solution data. + pub const SignedDepositByte: Balance = deposit(0, 10) / 1024; + // Each good submission will get 1 DOT as reward + pub SignedRewardBase: Balance = 1 * UNITS; + pub BetterUnsignedThreshold: Perbill = Perbill::from_rational(5u32, 10_000); + + // 4 hour session, 1 hour unsigned phase, 32 offchain executions. + pub OffchainRepeat: BlockNumber = UnsignedPhase::get() / 32; + + pub const MaxElectingVoters: u32 = 22_500; + /// We take the top 22500 nominators as electing voters and all of the validators as electable + /// targets. Whilst this is the case, we cannot and shall not increase the size of the + /// validator intentions. + pub ElectionBounds: frame_election_provider_support::bounds::ElectionBounds = + ElectionBoundsBuilder::default().voters_count(MaxElectingVoters::get().into()).build(); + /// Setup election pallet to support maximum winners upto 1200. This will mean Staking Pallet + /// cannot have active validators higher than this count. + pub const MaxActiveValidators: u32 = 1200; +} + +generate_solution_type!( + #[compact] + pub struct NposCompactSolution16::< + VoterIndex = u32, + TargetIndex = u16, + Accuracy = sp_runtime::PerU16, + MaxVoters = MaxElectingVoters, + >(16) +); + +pub struct OnChainSeqPhragmen; +impl onchain::Config for OnChainSeqPhragmen { + type System = Runtime; + type Solver = SequentialPhragmen; + type DataProvider = Staking; + type WeightInfo = weights::frame_election_provider_support::WeightInfo; + type MaxWinners = MaxActiveValidators; + type Bounds = ElectionBounds; +} + +impl pallet_election_provider_multi_phase::MinerConfig for Runtime { + type AccountId = AccountId; + type MaxLength = OffchainSolutionLengthLimit; + type MaxWeight = OffchainSolutionWeightLimit; + type Solution = NposCompactSolution16; + type MaxVotesPerVoter = < + ::DataProvider + as + frame_election_provider_support::ElectionDataProvider + >::MaxVotesPerVoter; + type MaxWinners = MaxActiveValidators; + + // The unsigned submissions have to respect the weight of the submit_unsigned call, thus their + // weight estimate function is wired to this call's weight. + fn solution_weight(v: u32, t: u32, a: u32, d: u32) -> Weight { + < + ::WeightInfo + as + pallet_election_provider_multi_phase::WeightInfo + >::submit_unsigned(v, t, a, d) + } +} + +impl pallet_election_provider_multi_phase::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type EstimateCallFee = TransactionPayment; + type SignedPhase = SignedPhase; + type UnsignedPhase = UnsignedPhase; + type SignedMaxSubmissions = SignedMaxSubmissions; + type SignedMaxRefunds = SignedMaxRefunds; + type SignedRewardBase = SignedRewardBase; + type SignedDepositBase = SignedDepositBase; + type SignedDepositByte = SignedDepositByte; + type SignedDepositWeight = (); + type SignedMaxWeight = + ::MaxWeight; + type MinerConfig = Self; + type SlashHandler = (); // burn slashes + type RewardHandler = (); // nothing to do upon rewards + type BetterUnsignedThreshold = BetterUnsignedThreshold; + type BetterSignedThreshold = (); + type OffchainRepeat = OffchainRepeat; + type MinerTxPriority = NposSolutionPriority; + type DataProvider = Staking; + #[cfg(any(feature = "fast-runtime", feature = "runtime-benchmarks"))] + type Fallback = onchain::OnChainExecution; + #[cfg(not(any(feature = "fast-runtime", feature = "runtime-benchmarks")))] + type Fallback = frame_election_provider_support::NoElection<( + AccountId, + BlockNumber, + Staking, + MaxActiveValidators, + )>; + type GovernanceFallback = onchain::OnChainExecution; + type Solver = SequentialPhragmen< + AccountId, + pallet_election_provider_multi_phase::SolutionAccuracyOf, + (), + >; + type BenchmarkingConfig = runtime_common::elections::BenchmarkConfig; + type ForceOrigin = EitherOf, StakingAdmin>; + type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo; + type MaxWinners = MaxActiveValidators; + type ElectionBounds = ElectionBounds; +} + +parameter_types! { + pub const BagThresholds: &'static [u64] = &bag_thresholds::THRESHOLDS; +} + +type VoterBagsListInstance = pallet_bags_list::Instance1; +impl pallet_bags_list::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ScoreProvider = Staking; + type WeightInfo = weights::pallet_bags_list::WeightInfo; + type BagThresholds = BagThresholds; + type Score = sp_npos_elections::VoteWeight; +} + +// TODO #6469: This shouldn't be static, but a lazily cached value, not built unless needed, and +// re-built in case input parameters have changed. The `ideal_stake` should be determined by the +// amount of parachain slots being bid on: this should be around `(75 - 25.min(slots / 4))%`. +pallet_staking_reward_curve::build! { + const REWARD_CURVE: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + // 3:2:1 staked : parachains : float. + // while there's no parachains, then this is 75% staked : 25% float. + ideal_stake: 0_750_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); +} + +parameter_types! { + // Six sessions in an era (24 hours). + pub const SessionsPerEra: SessionIndex = prod_or_fast!(6, 1); + + // 28 eras for unbonding (28 days). + pub BondingDuration: sp_staking::EraIndex = prod_or_fast!( + 28, + 28, + "DOT_BONDING_DURATION" + ); + pub SlashDeferDuration: sp_staking::EraIndex = prod_or_fast!( + 27, + 27, + "DOT_SLASH_DEFER_DURATION" + ); + pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; + pub const MaxNominatorRewardedPerValidator: u32 = 512; + pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17); + // 16 + pub const MaxNominations: u32 = ::LIMIT as u32; +} + +pub struct EraPayout; +impl pallet_staking::EraPayout for EraPayout { + fn era_payout( + total_staked: Balance, + total_issuance: Balance, + era_duration_millis: u64, + ) -> (Balance, Balance) { + // all para-ids that are not active. + let auctioned_slots = Paras::parachains() + .into_iter() + // all active para-ids that do not belong to a system or common good chain is the number + // of parachains that we should take into account for inflation. + .filter(|i| *i >= LOWEST_PUBLIC_ID) + .count() as u64; + + const MAX_ANNUAL_INFLATION: Perquintill = Perquintill::from_percent(10); + const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; + + runtime_common::impls::era_payout( + total_staked, + total_issuance, + MAX_ANNUAL_INFLATION, + Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR), + auctioned_slots, + ) + } +} + +impl pallet_staking::Config for Runtime { + type Currency = Balances; + type CurrencyBalance = Balance; + type UnixTime = Timestamp; + type CurrencyToVote = CurrencyToVote; + type RewardRemainder = Treasury; + type RuntimeEvent = RuntimeEvent; + type Slash = Treasury; + type Reward = (); + type SessionsPerEra = SessionsPerEra; + type BondingDuration = BondingDuration; + type SlashDeferDuration = SlashDeferDuration; + type AdminOrigin = EitherOf, StakingAdmin>; + type SessionInterface = Self; + type EraPayout = EraPayout; + type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; + type OffendingValidatorsThreshold = OffendingValidatorsThreshold; + type NextNewSession = Session; + type ElectionProvider = ElectionProviderMultiPhase; + type GenesisElectionProvider = onchain::OnChainExecution; + type VoterList = VoterList; + type TargetList = UseValidatorsMap; + type NominationsQuota = pallet_staking::FixedNominationsQuota<{ MaxNominations::get() }>; + type MaxUnlockingChunks = frame_support::traits::ConstU32<32>; + type HistoryDepth = frame_support::traits::ConstU32<84>; + type BenchmarkingConfig = runtime_common::StakingBenchmarkingConfig; + type EventListeners = NominationPools; + type WeightInfo = weights::pallet_staking::WeightInfo; +} + +impl pallet_fast_unstake::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BatchSize = frame_support::traits::ConstU32<16>; + type Deposit = frame_support::traits::ConstU128<{ UNITS }>; + type ControlOrigin = EnsureRoot; + type Staking = Staking; + type MaxErasToCheckPerBlock = ConstU32<1>; + #[cfg(feature = "runtime-benchmarks")] + type MaxBackersPerValidator = MaxNominatorRewardedPerValidator; + type WeightInfo = weights::pallet_fast_unstake::WeightInfo; +} + +parameter_types! { + // Minimum 4 CENTS/byte + pub const BasicDeposit: Balance = deposit(1, 258); + pub const FieldDeposit: Balance = deposit(0, 66); + pub const SubAccountDeposit: Balance = deposit(1, 53); + pub const MaxSubAccounts: u32 = 100; + pub const MaxAdditionalFields: u32 = 100; + pub const MaxRegistrars: u32 = 20; +} + +impl pallet_identity::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BasicDeposit = BasicDeposit; + type FieldDeposit = FieldDeposit; + type SubAccountDeposit = SubAccountDeposit; + type MaxSubAccounts = MaxSubAccounts; + type MaxAdditionalFields = MaxAdditionalFields; + type MaxRegistrars = MaxRegistrars; + type Slashed = Treasury; + type ForceOrigin = EitherOf, GeneralAdmin>; + type RegistrarOrigin = EitherOf, GeneralAdmin>; + type WeightInfo = weights::pallet_identity::WeightInfo; +} + +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: Balance = 100 * DOLLARS; + pub const ProposalBondMaximum: Balance = 500 * DOLLARS; + pub const SpendPeriod: BlockNumber = 24 * DAYS; + pub const Burn: Permill = Permill::from_percent(1); + pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); + + pub const TipCountdown: BlockNumber = 1 * DAYS; + pub const TipFindersFee: Percent = Percent::from_percent(20); + pub const TipReportDepositBase: Balance = 1 * DOLLARS; + pub const DataDepositPerByte: Balance = 1 * CENTS; + pub const MaxApprovals: u32 = 100; + pub const MaxAuthorities: u32 = 100_000; + pub const MaxKeys: u32 = 10_000; + pub const MaxPeerInHeartbeats: u32 = 10_000; + pub const RootSpendOriginMaxAmount: Balance = Balance::MAX; + pub const CouncilSpendOriginMaxAmount: Balance = Balance::MAX; +} + +impl pallet_treasury::Config for Runtime { + type PalletId = TreasuryPalletId; + type Currency = Balances; + type ApproveOrigin = EitherOfDiverse, Treasurer>; + type RejectOrigin = EitherOfDiverse, Treasurer>; + type RuntimeEvent = RuntimeEvent; + type OnSlash = Treasury; + type ProposalBond = ProposalBond; + type ProposalBondMinimum = ProposalBondMinimum; + type ProposalBondMaximum = ProposalBondMaximum; + type SpendPeriod = SpendPeriod; + type Burn = Burn; + type BurnDestination = (); + type SpendFunds = Bounties; + type MaxApprovals = MaxApprovals; + type WeightInfo = weights::pallet_treasury::WeightInfo; + type SpendOrigin = TreasurySpender; +} + +parameter_types! { + pub const BountyDepositBase: Balance = 1 * DOLLARS; + pub const BountyDepositPayoutDelay: BlockNumber = 8 * DAYS; + pub const BountyUpdatePeriod: BlockNumber = 90 * DAYS; + pub const MaximumReasonLength: u32 = 16384; + pub const CuratorDepositMultiplier: Permill = Permill::from_percent(50); + pub const CuratorDepositMin: Balance = 10 * DOLLARS; + pub const CuratorDepositMax: Balance = 200 * DOLLARS; + pub const BountyValueMinimum: Balance = 10 * DOLLARS; +} + +impl pallet_bounties::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type BountyDepositBase = BountyDepositBase; + type BountyDepositPayoutDelay = BountyDepositPayoutDelay; + type BountyUpdatePeriod = BountyUpdatePeriod; + type CuratorDepositMultiplier = CuratorDepositMultiplier; + type CuratorDepositMin = CuratorDepositMin; + type CuratorDepositMax = CuratorDepositMax; + type BountyValueMinimum = BountyValueMinimum; + type ChildBountyManager = ChildBounties; + type DataDepositPerByte = DataDepositPerByte; + type MaximumReasonLength = MaximumReasonLength; + type WeightInfo = weights::pallet_bounties::WeightInfo; +} + +parameter_types! { + pub const MaxActiveChildBountyCount: u32 = 100; + pub const ChildBountyValueMinimum: Balance = BountyValueMinimum::get() / 10; +} + +impl pallet_child_bounties::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type MaxActiveChildBountyCount = MaxActiveChildBountyCount; + type ChildBountyValueMinimum = ChildBountyValueMinimum; + type WeightInfo = weights::pallet_child_bounties::WeightInfo; +} + +impl pallet_offences::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type IdentificationTuple = pallet_session::historical::IdentificationTuple; + type OnOffenceHandler = Staking; +} + +impl pallet_authority_discovery::Config for Runtime { + type MaxAuthorities = MaxAuthorities; +} + +parameter_types! { + pub NposSolutionPriority: TransactionPriority = + Perbill::from_percent(90) * TransactionPriority::max_value(); + pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +impl pallet_im_online::Config for Runtime { + type AuthorityId = ImOnlineId; + type RuntimeEvent = RuntimeEvent; + type ValidatorSet = Historical; + type NextSessionRotation = Babe; + type ReportUnresponsiveness = Offences; + type UnsignedPriority = ImOnlineUnsignedPriority; + type WeightInfo = weights::pallet_im_online::WeightInfo; + type MaxKeys = MaxKeys; + type MaxPeerInHeartbeats = MaxPeerInHeartbeats; +} + +parameter_types! { + pub MaxSetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); +} + +impl pallet_grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + + type WeightInfo = (); + type MaxAuthorities = MaxAuthorities; + type MaxNominators = MaxNominatorRewardedPerValidator; + type MaxSetIdSessionEntries = MaxSetIdSessionEntries; + + type KeyOwnerProof = >::Proof; + + type EquivocationReportSystem = + pallet_grandpa::EquivocationReportSystem; +} + +/// Submits a transaction with the node's public and signature type. Adheres to the signed extension +/// format of the chain. +impl frame_system::offchain::CreateSignedTransaction for Runtime +where + RuntimeCall: From, +{ + fn create_transaction>( + call: RuntimeCall, + public: ::Signer, + account: AccountId, + nonce: ::Nonce, + ) -> Option<(RuntimeCall, ::SignaturePayload)> { + use sp_runtime::traits::StaticLookup; + // take the biggest period possible. + let period = + BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; + + let current_block = System::block_number() + .saturated_into::() + // The `System::block_number` is initialized with `n+1`, + // so the actual block number is `n`. + .saturating_sub(1); + let tip = 0; + let extra: SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(generic::Era::mortal( + period, + current_block, + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + claims::PrevalidateAttests::::new(), + ); + let raw_payload = SignedPayload::new(call, extra) + .map_err(|e| { + log::warn!("Unable to create signed payload: {:?}", e); + }) + .ok()?; + let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; + let (call, extra, _) = raw_payload.deconstruct(); + let address = ::Lookup::unlookup(account); + Some((call, (address, signature, extra))) + } +} + +impl frame_system::offchain::SigningTypes for Runtime { + type Public = ::Signer; + type Signature = Signature; +} + +impl frame_system::offchain::SendTransactionTypes for Runtime +where + RuntimeCall: From, +{ + type Extrinsic = UncheckedExtrinsic; + type OverarchingCall = RuntimeCall; +} + +parameter_types! { + // Deposit for a parathread (on-demand parachain) + pub const ParathreadDeposit: Balance = 500 * DOLLARS; + pub const MaxRetries: u32 = 3; +} + +parameter_types! { + pub Prefix: &'static [u8] = b"Pay DOTs to the Polkadot account:"; +} + +impl claims::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type VestingSchedule = Vesting; + type Prefix = Prefix; + /// Only Root can move a claim. + type MoveClaimOrigin = EnsureRoot; + type WeightInfo = weights::runtime_common_claims::WeightInfo; +} + +parameter_types! { + pub const MinVestedTransfer: Balance = 1 * DOLLARS; + pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = + WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); +} + +impl pallet_vesting::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BlockNumberToBalance = ConvertInto; + type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = weights::pallet_vesting::WeightInfo; + type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; + const MAX_VESTING_SCHEDULES: u32 = 28; +} + +impl pallet_utility::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type PalletsOrigin = OriginCaller; + type WeightInfo = weights::pallet_utility::WeightInfo; +} + +parameter_types! { + // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. + pub const DepositBase: Balance = deposit(1, 88); + // Additional storage item size of 32 bytes. + pub const DepositFactor: Balance = deposit(0, 32); + pub const MaxSignatories: u32 = 100; +} + +impl pallet_multisig::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type DepositBase = DepositBase; + type DepositFactor = DepositFactor; + type MaxSignatories = MaxSignatories; + type WeightInfo = weights::pallet_multisig::WeightInfo; +} + +parameter_types! { + // One storage item; key size 32, value size 8; . + pub const ProxyDepositBase: Balance = deposit(1, 8); + // Additional storage item size of 33 bytes. + pub const ProxyDepositFactor: Balance = deposit(0, 33); + pub const MaxProxies: u16 = 32; + pub const AnnouncementDepositBase: Balance = deposit(1, 8); + pub const AnnouncementDepositFactor: Balance = deposit(0, 66); + pub const MaxPending: u16 = 32; +} + +/// The type used to represent the kinds of proxying allowed. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + RuntimeDebug, + MaxEncodedLen, + scale_info::TypeInfo, +)] +pub enum ProxyType { + Any = 0, + NonTransfer = 1, + Governance = 2, + Staking = 3, + // Skip 4 as it is now removed (was SudoBalances) + IdentityJudgement = 5, + CancelProxy = 6, + Auction = 7, + NominationPools = 8, +} + +#[cfg(test)] +mod proxy_type_tests { + use super::*; + + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug)] + pub enum OldProxyType { + Any, + NonTransfer, + Governance, + Staking, + SudoBalances, + IdentityJudgement, + } + + #[test] + fn proxy_type_decodes_correctly() { + for (i, j) in vec![ + (OldProxyType::Any, ProxyType::Any), + (OldProxyType::NonTransfer, ProxyType::NonTransfer), + (OldProxyType::Governance, ProxyType::Governance), + (OldProxyType::Staking, ProxyType::Staking), + (OldProxyType::IdentityJudgement, ProxyType::IdentityJudgement), + ] + .into_iter() + { + assert_eq!(i.encode(), j.encode()); + } + assert!(ProxyType::decode(&mut &OldProxyType::SudoBalances.encode()[..]).is_err()); + } +} + +impl Default for ProxyType { + fn default() -> Self { + Self::Any + } +} +impl InstanceFilter for ProxyType { + fn filter(&self, c: &RuntimeCall) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => matches!( + c, + RuntimeCall::System(..) | + RuntimeCall::Scheduler(..) | + RuntimeCall::Babe(..) | + RuntimeCall::Timestamp(..) | + RuntimeCall::Indices(pallet_indices::Call::claim{..}) | + RuntimeCall::Indices(pallet_indices::Call::free{..}) | + RuntimeCall::Indices(pallet_indices::Call::freeze{..}) | + // Specifically omitting Indices `transfer`, `force_transfer` + // Specifically omitting the entire Balances pallet + RuntimeCall::Staking(..) | + RuntimeCall::Session(..) | + RuntimeCall::Grandpa(..) | + RuntimeCall::ImOnline(..) | + RuntimeCall::Treasury(..) | + RuntimeCall::Bounties(..) | + RuntimeCall::ChildBounties(..) | + RuntimeCall::ConvictionVoting(..) | + RuntimeCall::Referenda(..) | + RuntimeCall::Whitelist(..) | + RuntimeCall::Claims(..) | + RuntimeCall::Vesting(pallet_vesting::Call::vest{..}) | + RuntimeCall::Vesting(pallet_vesting::Call::vest_other{..}) | + // Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer` + RuntimeCall::Utility(..) | + RuntimeCall::Identity(..) | + RuntimeCall::Proxy(..) | + RuntimeCall::Multisig(..) | + RuntimeCall::Registrar(paras_registrar::Call::register {..}) | + RuntimeCall::Registrar(paras_registrar::Call::deregister {..}) | + // Specifically omitting Registrar `swap` + RuntimeCall::Registrar(paras_registrar::Call::reserve {..}) | + RuntimeCall::Crowdloan(..) | + RuntimeCall::Slots(..) | + RuntimeCall::Auctions(..) | // Specifically omitting the entire XCM Pallet + RuntimeCall::VoterList(..) | + RuntimeCall::NominationPools(..) | + RuntimeCall::FastUnstake(..) + ), + ProxyType::Governance => matches!( + c, + RuntimeCall::Treasury(..) | + RuntimeCall::Bounties(..) | + RuntimeCall::Utility(..) | + RuntimeCall::ChildBounties(..) | + RuntimeCall::ConvictionVoting(..) | + RuntimeCall::Referenda(..) | + RuntimeCall::Whitelist(..) + ), + ProxyType::Staking => { + matches!( + c, + RuntimeCall::Staking(..) | + RuntimeCall::Session(..) | RuntimeCall::Utility(..) | + RuntimeCall::FastUnstake(..) | + RuntimeCall::VoterList(..) | + RuntimeCall::NominationPools(..) + ) + }, + ProxyType::NominationPools => { + matches!(c, RuntimeCall::NominationPools(..) | RuntimeCall::Utility(..)) + }, + ProxyType::IdentityJudgement => matches!( + c, + RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. }) | + RuntimeCall::Utility(..) + ), + ProxyType::CancelProxy => { + matches!(c, RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })) + }, + ProxyType::Auction => matches!( + c, + RuntimeCall::Auctions(..) | + RuntimeCall::Crowdloan(..) | + RuntimeCall::Registrar(..) | + RuntimeCall::Slots(..) + ), + } + } + fn is_superset(&self, o: &Self) -> bool { + match (self, o) { + (x, y) if x == y => true, + (ProxyType::Any, _) => true, + (_, ProxyType::Any) => false, + (ProxyType::NonTransfer, _) => true, + _ => false, + } + } +} + +impl pallet_proxy::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type ProxyType = ProxyType; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type MaxProxies = MaxProxies; + type WeightInfo = weights::pallet_proxy::WeightInfo; + type MaxPending = MaxPending; + type CallHasher = BlakeTwo256; + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; +} + +impl parachains_origin::Config for Runtime {} + +impl parachains_configuration::Config for Runtime { + type WeightInfo = weights::runtime_parachains_configuration::WeightInfo; +} + +impl parachains_shared::Config for Runtime {} + +impl parachains_session_info::Config for Runtime { + type ValidatorSet = Historical; +} + +impl parachains_inclusion::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type DisputesHandler = ParasDisputes; + type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints; + type MessageQueue = MessageQueue; + type WeightInfo = weights::runtime_parachains_inclusion::WeightInfo; +} + +parameter_types! { + pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +impl parachains_paras::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::runtime_parachains_paras::WeightInfo; + type UnsignedPriority = ParasUnsignedPriority; + type QueueFootprinter = ParaInclusion; + type NextSessionRotation = Babe; +} + +parameter_types! { + /// Amount of weight that can be spent per block to service messages. + /// + /// # WARNING + /// + /// This is not a good value for para-chains since the `Scheduler` already uses up to 80% block weight. + pub MessageQueueServiceWeight: Weight = Perbill::from_percent(20) * BlockWeights::get().max_block; + pub const MessageQueueHeapSize: u32 = 65_536; + pub const MessageQueueMaxStale: u32 = 8; +} + +/// Message processor to handle any messages that were enqueued into the `MessageQueue` pallet. +pub struct MessageProcessor; +impl ProcessMessage for MessageProcessor { + type Origin = AggregateMessageOrigin; + + fn process_message( + message: &[u8], + origin: Self::Origin, + meter: &mut WeightMeter, + id: &mut [u8; 32], + ) -> Result { + let para = match origin { + AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para, + }; + xcm_builder::ProcessXcmMessage::< + Junction, + xcm_executor::XcmExecutor, + RuntimeCall, + >::process_message(message, Junction::Parachain(para.into()), meter, id) + } +} + +impl pallet_message_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Size = u32; + type HeapSize = MessageQueueHeapSize; + type MaxStale = MessageQueueMaxStale; + type ServiceWeight = MessageQueueServiceWeight; + #[cfg(not(feature = "runtime-benchmarks"))] + type MessageProcessor = MessageProcessor; + #[cfg(feature = "runtime-benchmarks")] + type MessageProcessor = + pallet_message_queue::mock_helpers::NoopMessageProcessor; + type QueueChangeHandler = ParaInclusion; + type QueuePausedQuery = (); + type WeightInfo = weights::pallet_message_queue::WeightInfo; +} + +impl parachains_dmp::Config for Runtime {} + +impl parachains_hrmp::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type ChannelManager = EitherOf, GeneralAdmin>; + type Currency = Balances; + type WeightInfo = weights::runtime_parachains_hrmp::WeightInfo; +} + +impl parachains_paras_inherent::Config for Runtime { + type WeightInfo = weights::runtime_parachains_paras_inherent::WeightInfo; +} + +impl parachains_scheduler::Config for Runtime { + type AssignmentProvider = ParaAssignmentProvider; +} + +impl parachains_assigner_parachains::Config for Runtime {} + +impl parachains_initializer::Config for Runtime { + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type ForceOrigin = EnsureRoot; + type WeightInfo = weights::runtime_parachains_initializer::WeightInfo; +} + +impl parachains_disputes::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints; + type SlashingHandler = parachains_slashing::SlashValidatorsForDisputes; + type WeightInfo = weights::runtime_parachains_disputes::WeightInfo; +} + +impl parachains_slashing::Config for Runtime { + type KeyOwnerProofSystem = Historical; + type KeyOwnerProof = + >::Proof; + type KeyOwnerIdentification = >::IdentificationTuple; + type HandleReports = parachains_slashing::SlashingReportHandler< + Self::KeyOwnerIdentification, + Offences, + ReportLongevity, + >; + type WeightInfo = weights::runtime_parachains_disputes_slashing::WeightInfo; + type BenchmarkingConfig = parachains_slashing::BenchConfig<1000>; +} + +parameter_types! { + // Mostly arbitrary deposit price, but should provide an adequate incentive not to spam reserve + // `ParaId`s. + pub const ParaDeposit: Balance = 100 * DOLLARS; + pub const ParaDataByteDeposit: Balance = deposit(0, 1); +} + +impl paras_registrar::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type OnSwap = (Crowdloan, Slots); + type ParaDeposit = ParaDeposit; + type DataDepositPerByte = ParaDataByteDeposit; + type WeightInfo = weights::runtime_common_paras_registrar::WeightInfo; +} + +parameter_types! { + // 12 weeks = 3 months per lease period -> 8 lease periods ~ 2 years + pub LeasePeriod: BlockNumber = prod_or_fast!(12 * WEEKS, 12 * WEEKS, "DOT_LEASE_PERIOD"); + // Polkadot Genesis was on May 26, 2020. + // Target Parachain Onboarding Date: Dec 15, 2021. + // Difference is 568 days. + // We want a lease period to start on the target onboarding date. + // 568 % (12 * 7) = 64 day offset + pub LeaseOffset: BlockNumber = prod_or_fast!(64 * DAYS, 0, "DOT_LEASE_OFFSET"); +} + +impl slots::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Registrar = Registrar; + type LeasePeriod = LeasePeriod; + type LeaseOffset = LeaseOffset; + type ForceOrigin = EitherOf, LeaseAdmin>; + type WeightInfo = weights::runtime_common_slots::WeightInfo; +} + +parameter_types! { + pub const CrowdloanId: PalletId = PalletId(*b"py/cfund"); + // Accounts for 10_000 contributions, each using 48 bytes (16 bytes for balance, and 32 bytes + // for a memo). + pub const SubmissionDeposit: Balance = deposit(1, 480_000); + // The minimum crowdloan contribution. + pub const MinContribution: Balance = 5 * DOLLARS; + pub const RemoveKeysLimit: u32 = 1000; + // Allow 32 bytes for an additional memo to a crowdloan. + pub const MaxMemoLength: u8 = 32; +} + +impl crowdloan::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type PalletId = CrowdloanId; + type SubmissionDeposit = SubmissionDeposit; + type MinContribution = MinContribution; + type RemoveKeysLimit = RemoveKeysLimit; + type Registrar = Registrar; + type Auctioneer = Auctions; + type MaxMemoLength = MaxMemoLength; + type WeightInfo = weights::runtime_common_crowdloan::WeightInfo; +} + +parameter_types! { + // The average auction is 7 days long, so this will be 70% for ending period. + // 5 Days = 72000 Blocks @ 6 sec per block + pub const EndingPeriod: BlockNumber = 5 * DAYS; + // ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples + pub const SampleLength: BlockNumber = 2 * MINUTES; +} + +impl auctions::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Leaser = Slots; + type Registrar = Registrar; + type EndingPeriod = EndingPeriod; + type SampleLength = SampleLength; + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type InitiateOrigin = EitherOf, AuctionAdmin>; + type WeightInfo = weights::runtime_common_auctions::WeightInfo; +} + +parameter_types! { + pub const PoolsPalletId: PalletId = PalletId(*b"py/nopls"); + // Allow pools that got slashed up to 90% to remain operational. + pub const MaxPointsToBalance: u8 = 10; +} + +impl pallet_nomination_pools::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type RewardCounter = FixedU128; + type BalanceToU256 = runtime_common::BalanceToU256; + type U256ToBalance = runtime_common::U256ToBalance; + type Staking = Staking; + type PostUnbondingPoolsWindow = frame_support::traits::ConstU32<4>; + type MaxMetadataLen = frame_support::traits::ConstU32<256>; + // we use the same number of allowed unlocking chunks as with staking. + type MaxUnbonding = ::MaxUnlockingChunks; + type PalletId = PoolsPalletId; + type MaxPointsToBalance = MaxPointsToBalance; + type WeightInfo = weights::pallet_nomination_pools::WeightInfo; +} + +pub struct InitiateNominationPools; +impl frame_support::traits::OnRuntimeUpgrade for InitiateNominationPools { + fn on_runtime_upgrade() -> frame_support::weights::Weight { + // we use one as an indicator if this has already been set. + if pallet_nomination_pools::MaxPools::::get().is_none() { + // 5 DOT to join a pool. + pallet_nomination_pools::MinJoinBond::::put(5 * UNITS); + // 100 DOT to create a pool. + pallet_nomination_pools::MinCreateBond::::put(100 * UNITS); + + // Initialize with limits for now. + pallet_nomination_pools::MaxPools::::put(0); + pallet_nomination_pools::MaxPoolMembersPerPool::::put(0); + pallet_nomination_pools::MaxPoolMembers::::put(0); + + log::info!(target: "runtime::polkadot", "pools config initiated 🎉"); + ::DbWeight::get().reads_writes(1, 5) + } else { + log::info!(target: "runtime::polkadot", "pools config already initiated 😏"); + ::DbWeight::get().reads(1) + } + } +} + +construct_runtime! { + pub enum Runtime + { + // Basic stuff; balances is uncallable initially. + System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, + Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 1, + Preimage: pallet_preimage::{Pallet, Call, Storage, Event} = 10, + + // Babe must be before session. + Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned} = 2, + + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3, + Indices: pallet_indices::{Pallet, Call, Storage, Config, Event} = 4, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 5, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 32, + + // Consensus support. + // Authorship must be before session in order to note author in the correct session and era + // for im-online and staking. + Authorship: pallet_authorship::{Pallet, Storage} = 6, + Staking: pallet_staking::{Pallet, Call, Storage, Config, Event} = 7, + Offences: pallet_offences::{Pallet, Storage, Event} = 8, + Historical: session_historical::{Pallet} = 33, + Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 9, + Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned} = 11, + ImOnline: pallet_im_online::{Pallet, Call, Storage, Event, ValidateUnsigned, Config} = 12, + AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config} = 13, + + // OpenGov stuff. + Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 19, + ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event} = 20, + Referenda: pallet_referenda::{Pallet, Call, Storage, Event} = 21, + Origins: pallet_custom_origins::{Origin} = 22, + Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event} = 23, + + // Claims. Usable initially. + Claims: claims::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 24, + // Vesting. Usable initially, but removed once all vesting is finished. + Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config} = 25, + // Cunning utilities. Usable initially. + Utility: pallet_utility::{Pallet, Call, Event} = 26, + + // Identity. Late addition. + Identity: pallet_identity::{Pallet, Call, Storage, Event} = 28, + + // Proxy module. Late addition. + Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 29, + + // Multisig dispatch. Late addition. + Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 30, + + // Bounties modules. + Bounties: pallet_bounties::{Pallet, Call, Storage, Event} = 34, + ChildBounties: pallet_child_bounties = 38, + + // Election pallet. Only works with staking, but placed here to maintain indices. + ElectionProviderMultiPhase: pallet_election_provider_multi_phase::{Pallet, Call, Storage, Event, ValidateUnsigned} = 36, + + // Provides a semi-sorted list of nominators for staking. + VoterList: pallet_bags_list::::{Pallet, Call, Storage, Event} = 37, + + // Nomination pools: extension to staking. + NominationPools: pallet_nomination_pools::{Pallet, Call, Storage, Event, Config} = 39, + + // Fast unstake pallet: extension to staking. + FastUnstake: pallet_fast_unstake = 40, + + // Parachains pallets. Start indices at 50 to leave room. + ParachainsOrigin: parachains_origin::{Pallet, Origin} = 50, + Configuration: parachains_configuration::{Pallet, Call, Storage, Config} = 51, + ParasShared: parachains_shared::{Pallet, Call, Storage} = 52, + ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event} = 53, + ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent} = 54, + ParaScheduler: parachains_scheduler::{Pallet, Storage} = 55, + Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 56, + Initializer: parachains_initializer::{Pallet, Call, Storage} = 57, + Dmp: parachains_dmp::{Pallet, Storage} = 58, + // Ump 59 + Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 60, + ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 61, + ParasDisputes: parachains_disputes::{Pallet, Call, Storage, Event} = 62, + ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned} = 63, + ParaAssignmentProvider: parachains_assigner_parachains::{Pallet} = 64, + + // Parachain Onboarding Pallets. Start indices at 70 to leave room. + Registrar: paras_registrar::{Pallet, Call, Storage, Event} = 70, + Slots: slots::{Pallet, Call, Storage, Event} = 71, + Auctions: auctions::{Pallet, Call, Storage, Event} = 72, + Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 73, + + // Pallet for sending XCM. + XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 99, + + // Generalized message queue + MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 100, + } +} + +/// The address format for describing accounts. +pub type Address = sp_runtime::MultiAddress; +/// Block header type as expected by this runtime. +pub type Header = generic::Header; +/// Block type as expected by this runtime. +pub type Block = generic::Block; +/// A Block signed with a Justification +pub type SignedBlock = generic::SignedBlock; +/// `BlockId` type as expected by this runtime. +pub type BlockId = generic::BlockId; +/// The `SignedExtension` to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckMortality, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, + claims::PrevalidateAttests, +); + +pub struct NominationPoolsMigrationV4OldPallet; +impl Get for NominationPoolsMigrationV4OldPallet { + fn get() -> Perbill { + Perbill::zero() + } +} + +/// All migrations that will run on the next runtime upgrade. +/// +/// This contains the combined migrations of the last 10 releases. It allows to skip runtime +/// upgrades in case governance decides to do so. THE ORDER IS IMPORTANT. +pub type Migrations = migrations::Unreleased; + +/// The runtime migrations per release. +#[allow(deprecated, missing_docs)] +pub mod migrations { + use super::*; + use frame_support::traits::LockIdentifier; + use frame_system::pallet_prelude::BlockNumberFor; + + parameter_types! { + pub const DemocracyPalletName: &'static str = "Democracy"; + pub const CouncilPalletName: &'static str = "Council"; + pub const TechnicalCommitteePalletName: &'static str = "TechnicalCommittee"; + pub const PhragmenElectionPalletName: &'static str = "PhragmenElection"; + pub const TechnicalMembershipPalletName: &'static str = "TechnicalMembership"; + pub const TipsPalletName: &'static str = "Tips"; + pub const PhragmenElectionPalletId: LockIdentifier = *b"phrelect"; + } + + // Special Config for Gov V1 pallets, allowing us to run migrations for them without + // implementing their configs on [`Runtime`]. + pub struct UnlockConfig; + impl pallet_democracy::migrations::unlock_and_unreserve_all_funds::UnlockConfig for UnlockConfig { + type Currency = Balances; + type MaxVotes = ConstU32<100>; + type MaxDeposits = ConstU32<100>; + type AccountId = AccountId; + type BlockNumber = BlockNumberFor; + type DbWeight = ::DbWeight; + type PalletName = DemocracyPalletName; + } + impl pallet_elections_phragmen::migrations::unlock_and_unreserve_all_funds::UnlockConfig + for UnlockConfig + { + type Currency = Balances; + type MaxVotesPerVoter = ConstU32<16>; + type PalletId = PhragmenElectionPalletId; + type AccountId = AccountId; + type DbWeight = ::DbWeight; + type PalletName = PhragmenElectionPalletName; + } + impl pallet_tips::migrations::unreserve_deposits::UnlockConfig<()> for UnlockConfig { + type Currency = Balances; + type Hash = Hash; + type DataDepositPerByte = DataDepositPerByte; + type TipReportDepositBase = TipReportDepositBase; + type AccountId = AccountId; + type BlockNumber = BlockNumberFor; + type DbWeight = ::DbWeight; + type PalletName = TipsPalletName; + } + + /// Unreleased migrations. Add new ones here: + pub type Unreleased = ( + pallet_im_online::migration::v1::Migration, + parachains_configuration::migration::v7::MigrateToV7, + parachains_scheduler::migration::v1::MigrateToV1, + parachains_configuration::migration::v8::MigrateToV8, + + // Gov v1 storage migrations + // https://github.com/paritytech/polkadot/issues/6749 + pallet_elections_phragmen::migrations::unlock_and_unreserve_all_funds::UnlockAndUnreserveAllFunds, + pallet_democracy::migrations::unlock_and_unreserve_all_funds::UnlockAndUnreserveAllFunds, + pallet_tips::migrations::unreserve_deposits::UnreserveDeposits, + + // Delete all Gov v1 pallet storage key/values. + frame_support::migrations::RemovePallet::DbWeight>, + frame_support::migrations::RemovePallet::DbWeight>, + frame_support::migrations::RemovePallet::DbWeight>, + frame_support::migrations::RemovePallet::DbWeight>, + frame_support::migrations::RemovePallet::DbWeight>, + frame_support::migrations::RemovePallet::DbWeight>, + ); +} + +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + generic::UncheckedExtrinsic; +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, + Migrations, +>; + +/// The payload being signed in transactions. +pub type SignedPayload = generic::SignedPayload; + +#[cfg(feature = "runtime-benchmarks")] +mod benches { + frame_benchmarking::define_benchmarks!( + // Polkadot + // NOTE: Make sure to prefix these with `runtime_common::` so + // the that path resolves correctly in the generated file. + [runtime_common::auctions, Auctions] + [runtime_common::claims, Claims] + [runtime_common::crowdloan, Crowdloan] + [runtime_common::slots, Slots] + [runtime_common::paras_registrar, Registrar] + [runtime_parachains::configuration, Configuration] + [runtime_parachains::disputes, ParasDisputes] + [runtime_parachains::disputes::slashing, ParasSlashing] + [runtime_parachains::hrmp, Hrmp] + [runtime_parachains::inclusion, ParaInclusion] + [runtime_parachains::initializer, Initializer] + [runtime_parachains::paras, Paras] + [runtime_parachains::paras_inherent, ParaInherent] + // Substrate + [pallet_bags_list, VoterList] + [pallet_balances, Balances] + [frame_benchmarking::baseline, Baseline::] + [pallet_bounties, Bounties] + [pallet_child_bounties, ChildBounties] + [pallet_election_provider_multi_phase, ElectionProviderMultiPhase] + [frame_election_provider_support, ElectionProviderBench::] + [pallet_fast_unstake, FastUnstake] + [pallet_identity, Identity] + [pallet_im_online, ImOnline] + [pallet_indices, Indices] + [pallet_message_queue, MessageQueue] + [pallet_multisig, Multisig] + [pallet_nomination_pools, NominationPoolsBench::] + [pallet_offences, OffencesBench::] + [pallet_preimage, Preimage] + [pallet_proxy, Proxy] + [pallet_scheduler, Scheduler] + [pallet_session, SessionBench::] + [pallet_staking, Staking] + [frame_system, SystemBench::] + [pallet_timestamp, Timestamp] + [pallet_treasury, Treasury] + [pallet_utility, Utility] + [pallet_vesting, Vesting] + [pallet_conviction_voting, ConvictionVoting] + [pallet_referenda, Referenda] + [pallet_whitelist, Whitelist] + // XCM + [pallet_xcm, XcmPallet] + [pallet_xcm_benchmarks::fungible, pallet_xcm_benchmarks::fungible::Pallet::] + [pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::] + ); +} + +#[cfg(not(feature = "disable-runtime-api"))] +sp_api::impl_runtime_apis! { + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block); + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } + } + + impl block_builder_api::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: inherents::InherentData, + ) -> inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl pallet_nomination_pools_runtime_api::NominationPoolsApi< + Block, + AccountId, + Balance, + > for Runtime { + fn pending_rewards(member: AccountId) -> Balance { + NominationPools::api_pending_rewards(member).unwrap_or_default() + } + + fn points_to_balance(pool_id: pallet_nomination_pools::PoolId, points: Balance) -> Balance { + NominationPools::api_points_to_balance(pool_id, points) + } + + fn balance_to_points(pool_id: pallet_nomination_pools::PoolId, new_funds: Balance) -> Balance { + NominationPools::api_balance_to_points(pool_id, new_funds) + } + } + + impl pallet_staking_runtime_api::StakingApi for Runtime { + fn nominations_quota(balance: Balance) -> u32 { + Staking::api_nominations_quota(balance) + } + } + + impl tx_pool_api::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl offchain_primitives::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl primitives::runtime_api::ParachainHost for Runtime { + fn validators() -> Vec { + parachains_runtime_api_impl::validators::() + } + + fn validator_groups() -> (Vec>, GroupRotationInfo) { + parachains_runtime_api_impl::validator_groups::() + } + + fn availability_cores() -> Vec> { + parachains_runtime_api_impl::availability_cores::() + } + + fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option> { + parachains_runtime_api_impl::persisted_validation_data::(para_id, assumption) + } + + fn assumed_validation_data( + para_id: ParaId, + expected_persisted_validation_data_hash: Hash, + ) -> Option<(PersistedValidationData, ValidationCodeHash)> { + parachains_runtime_api_impl::assumed_validation_data::( + para_id, + expected_persisted_validation_data_hash, + ) + } + + fn check_validation_outputs( + para_id: ParaId, + outputs: primitives::CandidateCommitments, + ) -> bool { + parachains_runtime_api_impl::check_validation_outputs::(para_id, outputs) + } + + fn session_index_for_child() -> SessionIndex { + parachains_runtime_api_impl::session_index_for_child::() + } + + fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option { + parachains_runtime_api_impl::validation_code::(para_id, assumption) + } + + fn candidate_pending_availability(para_id: ParaId) -> Option> { + parachains_runtime_api_impl::candidate_pending_availability::(para_id) + } + + fn candidate_events() -> Vec> { + parachains_runtime_api_impl::candidate_events::(|ev| { + match ev { + RuntimeEvent::ParaInclusion(ev) => { + Some(ev) + } + _ => None, + } + }) + } + + fn session_info(index: SessionIndex) -> Option { + parachains_runtime_api_impl::session_info::(index) + } + + fn session_executor_params(session_index: SessionIndex) -> Option { + parachains_runtime_api_impl::session_executor_params::(session_index) + } + + fn dmq_contents(recipient: ParaId) -> Vec> { + parachains_runtime_api_impl::dmq_contents::(recipient) + } + + fn inbound_hrmp_channels_contents( + recipient: ParaId + ) -> BTreeMap>> { + parachains_runtime_api_impl::inbound_hrmp_channels_contents::(recipient) + } + + fn validation_code_by_hash(hash: ValidationCodeHash) -> Option { + parachains_runtime_api_impl::validation_code_by_hash::(hash) + } + + fn on_chain_votes() -> Option> { + parachains_runtime_api_impl::on_chain_votes::() + } + + fn submit_pvf_check_statement( + stmt: primitives::PvfCheckStatement, + signature: primitives::ValidatorSignature, + ) { + parachains_runtime_api_impl::submit_pvf_check_statement::(stmt, signature) + } + + fn pvfs_require_precheck() -> Vec { + parachains_runtime_api_impl::pvfs_require_precheck::() + } + + fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option + { + parachains_runtime_api_impl::validation_code_hash::(para_id, assumption) + } + + fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState)> { + parachains_runtime_api_impl::get_session_disputes::() + } + + fn unapplied_slashes( + ) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> { + parachains_runtime_api_impl::unapplied_slashes::() + } + + fn key_ownership_proof( + validator_id: ValidatorId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((PARACHAIN_KEY_TYPE_ID, validator_id)) + .map(|p| p.encode()) + .map(slashing::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_dispute_lost( + dispute_proof: slashing::DisputeProof, + key_ownership_proof: slashing::OpaqueKeyOwnershipProof, + ) -> Option<()> { + parachains_runtime_api_impl::submit_unsigned_slashing_report::( + dispute_proof, + key_ownership_proof, + ) + } + } + + impl beefy_primitives::BeefyApi for Runtime { + fn beefy_genesis() -> Option { + // dummy implementation due to lack of BEEFY pallet. + None + } + + fn validator_set() -> Option> { + // dummy implementation due to lack of BEEFY pallet. + None + } + + fn submit_report_equivocation_unsigned_extrinsic( + _equivocation_proof: beefy_primitives::EquivocationProof< + BlockNumber, + BeefyId, + BeefySignature, + >, + _key_owner_proof: beefy_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + + fn generate_key_ownership_proof( + _set_id: beefy_primitives::ValidatorSetId, + _authority_id: BeefyId, + ) -> Option { + None + } + } + + impl mmr::MmrApi for Runtime { + fn mmr_root() -> Result { + Err(mmr::Error::PalletNotIncluded) + } + + fn mmr_leaf_count() -> Result { + Err(mmr::Error::PalletNotIncluded) + } + + fn generate_proof( + _block_numbers: Vec, + _best_known_block_number: Option, + ) -> Result<(Vec, mmr::Proof), mmr::Error> { + Err(mmr::Error::PalletNotIncluded) + } + + fn verify_proof(_leaves: Vec, _proof: mmr::Proof) + -> Result<(), mmr::Error> + { + Err(mmr::Error::PalletNotIncluded) + } + + fn verify_proof_stateless( + _root: Hash, + _leaves: Vec, + _proof: mmr::Proof + ) -> Result<(), mmr::Error> { + Err(mmr::Error::PalletNotIncluded) + } + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> Vec<(GrandpaId, u64)> { + Grandpa::grandpa_authorities() + } + + fn current_set_id() -> fg_primitives::SetId { + Grandpa::current_set_id() + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: fg_primitives::EquivocationProof< + ::Hash, + sp_runtime::traits::NumberFor, + >, + key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Grandpa::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + + fn generate_key_ownership_proof( + _set_id: fg_primitives::SetId, + authority_id: fg_primitives::AuthorityId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((fg_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(fg_primitives::OpaqueKeyOwnershipProof::new) + } + } + + impl babe_primitives::BabeApi for Runtime { + fn configuration() -> babe_primitives::BabeConfiguration { + let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG); + babe_primitives::BabeConfiguration { + slot_duration: Babe::slot_duration(), + epoch_length: EpochDuration::get(), + c: epoch_config.c, + authorities: Babe::authorities().to_vec(), + randomness: Babe::randomness(), + allowed_slots: epoch_config.allowed_slots, + } + } + + fn current_epoch_start() -> babe_primitives::Slot { + Babe::current_epoch_start() + } + + fn current_epoch() -> babe_primitives::Epoch { + Babe::current_epoch() + } + + fn next_epoch() -> babe_primitives::Epoch { + Babe::next_epoch() + } + + fn generate_key_ownership_proof( + _slot: babe_primitives::Slot, + authority_id: babe_primitives::AuthorityId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((babe_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(babe_primitives::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: babe_primitives::EquivocationProof<::Header>, + key_owner_proof: babe_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Babe::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + } + + impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + parachains_runtime_api_impl::relevant_authority_ids::() + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Nonce { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< + Block, + Balance, + > for Runtime { + fn query_info(uxt: ::Extrinsic, len: u32) -> RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details(uxt: ::Extrinsic, len: u32) -> FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi + for Runtime + { + fn query_call_info(call: RuntimeCall, len: u32) -> RuntimeDispatchInfo { + TransactionPayment::query_call_info(call, len) + } + fn query_call_fee_details(call: RuntimeCall, len: u32) -> FeeDetails { + TransactionPayment::query_call_fee_details(call, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + #[cfg(feature = "try-runtime")] + impl frame_try_runtime::TryRuntime for Runtime { + fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { + log::info!("try-runtime::on_runtime_upgrade polkadot."); + let weight = Executive::try_runtime_upgrade(checks).unwrap(); + (weight, BlockWeights::get().max_block) + } + + fn execute_block( + block: Block, + state_root_check: bool, + signature_check: bool, + select: frame_try_runtime::TryStateSelect, + ) -> Weight { + // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to + // have a backtrace here. + Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap() + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + + use pallet_session_benchmarking::Pallet as SessionBench; + use pallet_offences_benchmarking::Pallet as OffencesBench; + use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench; + use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; + use frame_system_benchmarking::Pallet as SystemBench; + use frame_benchmarking::baseline::Pallet as Baseline; + + let mut list = Vec::::new(); + list_benchmarks!(list, extra); + + let storage_info = AllPalletsWithSystem::storage_info(); + return (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result< + Vec, + sp_runtime::RuntimeString, + > { + use frame_support::traits::WhitelistedStorageKeys; + use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError}; + use sp_storage::TrackedStorageKey; + // Trying to add benchmarks directly to some pallets caused cyclic dependency issues. + // To get around that, we separated the benchmarks into its own crate. + use pallet_session_benchmarking::Pallet as SessionBench; + use pallet_offences_benchmarking::Pallet as OffencesBench; + use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench; + use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; + use frame_system_benchmarking::Pallet as SystemBench; + use frame_benchmarking::baseline::Pallet as Baseline; + use xcm::latest::prelude::*; + use xcm_config::{XcmConfig, StatemintLocation, TokenLocation, LocalCheckAccount, SovereignAccountOf}; + + impl pallet_session_benchmarking::Config for Runtime {} + impl pallet_offences_benchmarking::Config for Runtime {} + impl pallet_election_provider_support_benchmarking::Config for Runtime {} + impl frame_system_benchmarking::Config for Runtime {} + impl frame_benchmarking::baseline::Config for Runtime {} + impl pallet_nomination_pools_benchmarking::Config for Runtime {} + impl runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {} + + let mut whitelist: Vec = AllPalletsWithSystem::whitelisted_storage_keys(); + let treasury_key = frame_system::Account::::hashed_key_for(Treasury::account_id()); + whitelist.push(treasury_key.to_vec().into()); + + impl pallet_xcm_benchmarks::Config for Runtime { + type XcmConfig = XcmConfig; + type AccountIdConverter = SovereignAccountOf; + fn valid_destination() -> Result { + Ok(StatemintLocation::get()) + } + fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + // Polkadot only knows about DOT + vec![MultiAsset { id: Concrete(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS) }].into() + } + } + + parameter_types! { + pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + StatemintLocation::get(), + MultiAsset { id: Concrete(TokenLocation::get()), fun: Fungible(1 * UNITS) } + )); + pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + } + + impl pallet_xcm_benchmarks::fungible::Config for Runtime { + type TransactAsset = Balances; + + type CheckedAccount = LocalCheckAccount; + type TrustedTeleporter = TrustedTeleporter; + type TrustedReserve = TrustedReserve; + + fn get_multi_asset() -> MultiAsset { + MultiAsset { + id: Concrete(TokenLocation::get()), + fun: Fungible(1 * UNITS) + } + } + } + + impl pallet_xcm_benchmarks::generic::Config for Runtime { + type RuntimeCall = RuntimeCall; + + fn worst_case_response() -> (u64, Response) { + (0u64, Response::Version(Default::default())) + } + + fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + // Polkadot doesn't support asset exchanges + Err(BenchmarkError::Skip) + } + + fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + // The XCM executor of Polkadot doesn't have a configured `UniversalAliases` + Err(BenchmarkError::Skip) + } + + fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + Ok((StatemintLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) + } + + fn subscribe_origin() -> Result { + Ok(StatemintLocation::get()) + } + + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + let origin = StatemintLocation::get(); + let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = MultiLocation { parents: 0, interior: Here }; + Ok((origin, ticket, assets)) + } + + fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + // Polkadot doesn't support asset locking + Err(BenchmarkError::Skip) + } + + fn export_message_origin_and_destination( + ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + // Polkadot doesn't support exporting messages + Err(BenchmarkError::Skip) + } + + fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + // The XCM executor of Polkadot doesn't have a configured `Aliasers` + Err(BenchmarkError::Skip) + } + } + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + + add_benchmarks!(params, batches); + + Ok(batches) + } + } +} + +#[cfg(test)] +mod test_fees { + use super::*; + use frame_support::{dispatch::GetDispatchInfo, weights::WeightToFee as WeightToFeeT}; + use keyring::Sr25519Keyring::{Alice, Charlie}; + use pallet_transaction_payment::Multiplier; + use runtime_common::MinimumMultiplier; + use separator::Separatable; + use sp_runtime::{assert_eq_error_rate, FixedPointNumber, MultiAddress, MultiSignature}; + + #[test] + fn payout_weight_portion() { + use pallet_staking::WeightInfo; + let payout_weight = + ::WeightInfo::payout_stakers_alive_staked( + MaxNominatorRewardedPerValidator::get(), + ) + .ref_time() as f64; + let block_weight = BlockWeights::get().max_block.ref_time() as f64; + + println!( + "a full payout takes {:.2} of the block weight [{} / {}]", + payout_weight / block_weight, + payout_weight, + block_weight + ); + assert!(payout_weight * 2f64 < block_weight); + } + + #[test] + fn block_cost() { + let max_block_weight = BlockWeights::get().max_block; + let raw_fee = WeightToFee::weight_to_fee(&max_block_weight); + + let fee_with_multiplier = |m: Multiplier| { + println!( + "Full Block weight == {} // multiplier: {:?} // WeightToFee(full_block) == {} plank", + max_block_weight, + m, + m.saturating_mul_int(raw_fee).separated_string(), + ); + }; + fee_with_multiplier(MinimumMultiplier::get()); + fee_with_multiplier(Multiplier::from_rational(1, 2)); + fee_with_multiplier(Multiplier::from_u32(1)); + fee_with_multiplier(Multiplier::from_u32(2)); + } + + #[test] + fn transfer_cost_min_multiplier() { + let min_multiplier = MinimumMultiplier::get(); + let call = pallet_balances::Call::::transfer_keep_alive { + dest: Charlie.to_account_id().into(), + value: Default::default(), + }; + let info = call.get_dispatch_info(); + println!("call = {:?} / info = {:?}", call, info); + // convert to runtime call. + let call = RuntimeCall::Balances(call); + let extra: SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(generic::Era::immortal()), + frame_system::CheckNonce::::from(1), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + claims::PrevalidateAttests::::new(), + ); + let uxt = UncheckedExtrinsic { + function: call, + signature: Some(( + MultiAddress::Id(Alice.to_account_id()), + MultiSignature::Sr25519(Alice.sign(b"foo")), + extra, + )), + }; + let len = uxt.encoded_size(); + + let mut ext = sp_io::TestExternalities::new_empty(); + let mut test_with_multiplier = |m: Multiplier| { + ext.execute_with(|| { + pallet_transaction_payment::NextFeeMultiplier::::put(m); + let fee = TransactionPayment::query_fee_details(uxt.clone(), len as u32); + println!( + "multiplier = {:?} // fee details = {:?} // final fee = {:?}", + pallet_transaction_payment::NextFeeMultiplier::::get(), + fee, + fee.final_fee().separated_string(), + ); + }); + }; + + test_with_multiplier(min_multiplier); + test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1u128)); + test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_0u128)); + test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_00u128)); + test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_000u128)); + test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_000_000u128)); + test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_000_000_000u128)); + } + + #[test] + fn nominator_limit() { + use pallet_election_provider_multi_phase::WeightInfo; + // starting point of the nominators. + let target_voters: u32 = 50_000; + + // assuming we want around 5k candidates and 1k active validators. (March 31, 2021) + let all_targets: u32 = 5_000; + let desired: u32 = 1_000; + let weight_with = |active| { + ::WeightInfo::submit_unsigned( + active, + all_targets, + active, + desired, + ) + }; + + let mut active = target_voters; + while weight_with(active).all_lte(OffchainSolutionWeightLimit::get()) || + active == target_voters + { + active += 1; + } + + println!("can support {} nominators to yield a weight of {}", active, weight_with(active)); + assert!(active > target_voters, "we need to reevaluate the weight of the election system"); + } + + #[test] + fn signed_deposit_is_sensible() { + // ensure this number does not change, or that it is checked after each change. + // a 1 MB solution should take (40 + 10) DOTs of deposit. + let deposit = SignedDepositBase::get() + (SignedDepositByte::get() * 1024 * 1024); + assert_eq_error_rate!(deposit, 50 * DOLLARS, DOLLARS); + } +} + +#[cfg(test)] +mod test { + use std::collections::HashSet; + + use super::*; + use frame_support::traits::WhitelistedStorageKeys; + use sp_core::hexdisplay::HexDisplay; + + #[test] + fn call_size() { + RuntimeCall::assert_size_under(230); + } + + #[test] + fn check_whitelist() { + let whitelist: HashSet = AllPalletsWithSystem::whitelisted_storage_keys() + .iter() + .map(|e| HexDisplay::from(&e.key).to_string()) + .collect(); + + // Block number + assert!( + whitelist.contains("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac") + ); + // Total issuance + assert!( + whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80") + ); + // Execution phase + assert!( + whitelist.contains("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a") + ); + // Event count + assert!( + whitelist.contains("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850") + ); + // System events + assert!( + whitelist.contains("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7") + ); + // XcmPallet VersionDiscoveryQueue + assert!( + whitelist.contains("1405f2411d0af5a7ff397e7c9dc68d194a222ba0333561192e474c59ed8e30e1") + ); + // XcmPallet SafeXcmVersion + assert!( + whitelist.contains("1405f2411d0af5a7ff397e7c9dc68d196323ae84c43568be0d1394d5d0d522c4") + ); + } +} + +#[cfg(test)] +mod multiplier_tests { + use super::*; + use frame_support::{dispatch::DispatchInfo, traits::OnFinalize}; + use runtime_common::{MinimumMultiplier, TargetBlockFullness}; + use separator::Separatable; + use sp_runtime::traits::Convert; + + fn run_with_system_weight(w: Weight, mut assertions: F) + where + F: FnMut() -> (), + { + let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap() + .into(); + t.execute_with(|| { + System::set_block_consumed_resources(w, 0); + assertions() + }); + } + + #[test] + fn multiplier_can_grow_from_zero() { + let minimum_multiplier = MinimumMultiplier::get(); + let target = TargetBlockFullness::get() * + BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap(); + // if the min is too small, then this will not change, and we are doomed forever. + // the weight is 1/100th bigger than target. + run_with_system_weight(target.saturating_mul(101) / 100, || { + let next = SlowAdjustingFeeUpdate::::convert(minimum_multiplier); + assert!(next > minimum_multiplier, "{:?} !>= {:?}", next, minimum_multiplier); + }) + } + + #[test] + fn fast_unstake_estimate() { + use pallet_fast_unstake::WeightInfo; + let block_time = BlockWeights::get().max_block.ref_time() as f32; + let on_idle = weights::pallet_fast_unstake::WeightInfo::::on_idle_check( + 300, + ::BatchSize::get(), + ) + .ref_time() as f32; + println!("ratio of block weight for full batch fast-unstake {}", on_idle / block_time); + assert!(on_idle / block_time <= 0.5f32) + } + + #[test] + #[ignore] + fn multiplier_growth_simulator() { + // assume the multiplier is initially set to its minimum. We update it with values twice the + //target (target is 25%, thus 50%) and we see at which point it reaches 1. + let mut multiplier = MinimumMultiplier::get(); + let block_weight = BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap(); + let mut blocks = 0; + let mut fees_paid = 0; + + frame_system::Pallet::::set_block_consumed_resources(Weight::MAX, 0); + let info = DispatchInfo { weight: Weight::MAX, ..Default::default() }; + + let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap() + .into(); + // set the minimum + t.execute_with(|| { + pallet_transaction_payment::NextFeeMultiplier::::set(MinimumMultiplier::get()); + }); + + while multiplier <= Multiplier::from_u32(1) { + t.execute_with(|| { + // imagine this tx was called. + let fee = TransactionPayment::compute_fee(0, &info, 0); + fees_paid += fee; + + // this will update the multiplier. + System::set_block_consumed_resources(block_weight, 0); + TransactionPayment::on_finalize(1); + let next = TransactionPayment::next_fee_multiplier(); + + assert!(next > multiplier, "{:?} !>= {:?}", next, multiplier); + multiplier = next; + + println!( + "block = {} / multiplier {:?} / fee = {:?} / fess so far {:?}", + blocks, + multiplier, + fee.separated_string(), + fees_paid.separated_string() + ); + }); + blocks += 1; + } + } + + #[test] + #[ignore] + fn multiplier_cool_down_simulator() { + // assume the multiplier is initially set to its minimum. We update it with values twice the + //target (target is 25%, thus 50%) and we see at which point it reaches 1. + let mut multiplier = Multiplier::from_u32(2); + let mut blocks = 0; + + let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap() + .into(); + // set the minimum + t.execute_with(|| { + pallet_transaction_payment::NextFeeMultiplier::::set(multiplier); + }); + + while multiplier > Multiplier::from_u32(0) { + t.execute_with(|| { + // this will update the multiplier. + TransactionPayment::on_finalize(1); + let next = TransactionPayment::next_fee_multiplier(); + + assert!(next < multiplier, "{:?} !>= {:?}", next, multiplier); + multiplier = next; + + println!("block = {} / multiplier {:?}", blocks, multiplier); + }); + blocks += 1; + } + } +} + +#[cfg(all(test, feature = "try-runtime"))] +mod remote_tests { + use super::*; + use frame_try_runtime::{runtime_decl_for_try_runtime::TryRuntime, UpgradeCheckSelect}; + use remote_externalities::{ + Builder, Mode, OfflineConfig, OnlineConfig, SnapshotConfig, Transport, + }; + use std::env::var; + + #[tokio::test] + async fn run_migrations() { + if var("RUN_MIGRATION_TESTS").is_err() { + return + } + + sp_tracing::try_init_simple(); + let transport: Transport = + var("WS").unwrap_or("wss://rpc.polkadot.io:443".to_string()).into(); + let maybe_state_snapshot: Option = var("SNAP").map(|s| s.into()).ok(); + let mut ext = Builder::::default() + .mode(if let Some(state_snapshot) = maybe_state_snapshot { + Mode::OfflineOrElseOnline( + OfflineConfig { state_snapshot: state_snapshot.clone() }, + OnlineConfig { + transport, + state_snapshot: Some(state_snapshot), + ..Default::default() + }, + ) + } else { + Mode::Online(OnlineConfig { transport, ..Default::default() }) + }) + .build() + .await + .unwrap(); + ext.execute_with(|| Runtime::on_runtime_upgrade(UpgradeCheckSelect::PreAndPost)); + } + + #[tokio::test] + #[ignore = "this test is meant to be executed manually"] + async fn try_fast_unstake_all() { + sp_tracing::try_init_simple(); + let transport: Transport = + var("WS").unwrap_or("wss://rpc.polkadot.io:443".to_string()).into(); + let maybe_state_snapshot: Option = var("SNAP").map(|s| s.into()).ok(); + let mut ext = Builder::::default() + .mode(if let Some(state_snapshot) = maybe_state_snapshot { + Mode::OfflineOrElseOnline( + OfflineConfig { state_snapshot: state_snapshot.clone() }, + OnlineConfig { + transport, + state_snapshot: Some(state_snapshot), + ..Default::default() + }, + ) + } else { + Mode::Online(OnlineConfig { transport, ..Default::default() }) + }) + .build() + .await + .unwrap(); + ext.execute_with(|| { + pallet_fast_unstake::ErasToCheckPerBlock::::put(1); + runtime_common::try_runtime::migrate_all_inactive_nominators::() + }); + } +} diff --git a/polkadot/runtime/polkadot/src/weights/frame_benchmarking_baseline.rs b/polkadot/runtime/polkadot/src/weights/frame_benchmarking_baseline.rs new file mode 100644 index 0000000000000000000000000000000000000000..bb27fdc880ca46c2f05e368a51b7da77e23b7a10 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/frame_benchmarking_baseline.rs @@ -0,0 +1,108 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `frame_benchmarking::baseline` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=frame_benchmarking::baseline +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/frame_benchmarking_baseline.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_benchmarking::baseline`. +pub struct WeightInfo(PhantomData); +impl frame_benchmarking::baseline::WeightInfo for WeightInfo { + /// The range of component `i` is `[0, 1000000]`. + fn addition(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 163_000 picoseconds. + Weight::from_parts(209_370, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 1000000]`. + fn subtraction(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 159_000 picoseconds. + Weight::from_parts(203_916, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 1000000]`. + fn multiplication(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 163_000 picoseconds. + Weight::from_parts(211_152, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 1000000]`. + fn division(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 165_000 picoseconds. + Weight::from_parts(205_618, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn hashing() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 22_794_873_000 picoseconds. + Weight::from_parts(22_858_244_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 100]`. + fn sr25519_verification(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 218_000 picoseconds. + Weight::from_parts(2_663_311, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 6_556 + .saturating_add(Weight::from_parts(55_473_775, 0).saturating_mul(i.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/frame_election_provider_support.rs b/polkadot/runtime/polkadot/src/weights/frame_election_provider_support.rs new file mode 100644 index 0000000000000000000000000000000000000000..109c82884214d9a5012ad9ed05367c45f8913c79 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/frame_election_provider_support.rs @@ -0,0 +1,83 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `frame_election_provider_support` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=frame_election_provider_support +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_election_provider_support`. +pub struct WeightInfo(PhantomData); +impl frame_election_provider_support::WeightInfo for WeightInfo { + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `d` is `[5, 16]`. + fn phragmen(v: u32, _t: u32, d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_659_138_000 picoseconds. + Weight::from_parts(6_742_669_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 134_896 + .saturating_add(Weight::from_parts(5_872_242, 0).saturating_mul(v.into())) + // Standard Error: 13_791_372 + .saturating_add(Weight::from_parts(1_417_540_796, 0).saturating_mul(d.into())) + } + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `d` is `[5, 16]`. + fn phragmms(v: u32, _t: u32, d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_614_958_000 picoseconds. + Weight::from_parts(4_655_159_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 121_610 + .saturating_add(Weight::from_parts(4_875_919, 0).saturating_mul(v.into())) + // Standard Error: 12_432_980 + .saturating_add(Weight::from_parts(1_332_850_451, 0).saturating_mul(d.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/frame_system.rs b/polkadot/runtime/polkadot/src/weights/frame_system.rs new file mode 100644 index 0000000000000000000000000000000000000000..e6ece50fc8e0f1244b4286ee644ef12a9ca9ad48 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/frame_system.rs @@ -0,0 +1,147 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `frame_system` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=frame_system +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system`. +pub struct WeightInfo(PhantomData); +impl frame_system::WeightInfo for WeightInfo { + /// The range of component `b` is `[0, 3932160]`. + fn remark(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_933_000 picoseconds. + Weight::from_parts(2_016_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(469, 0).saturating_mul(b.into())) + } + /// The range of component `b` is `[0, 3932160]`. + fn remark_with_event(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_415_000 picoseconds. + Weight::from_parts(7_513_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_834, 0).saturating_mul(b.into())) + } + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a686561707061676573` (r:0 w:1) + /// Proof Skipped: unknown `0x3a686561707061676573` (r:0 w:1) + fn set_heap_pages() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1485` + // Minimum execution time: 3_680_000 picoseconds. + Weight::from_parts(3_889_000, 0) + .saturating_add(Weight::from_parts(0, 1485)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a636f6465` (r:0 w:1) + /// Proof Skipped: unknown `0x3a636f6465` (r:0 w:1) + fn set_code() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1485` + // Minimum execution time: 92_505_621_000 picoseconds. + Weight::from_parts(96_677_957_000, 0) + .saturating_add(Weight::from_parts(0, 1485)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 1000]`. + fn set_storage(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_080_000 picoseconds. + Weight::from_parts(2_160_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1_639 + .saturating_add(Weight::from_parts(731_622, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 1000]`. + fn kill_storage(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_135_000 picoseconds. + Weight::from_parts(2_184_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 976 + .saturating_add(Weight::from_parts(554_293, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `p` is `[0, 1000]`. + fn kill_prefix(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `132 + p * (69 ±0)` + // Estimated: `128 + p * (70 ±0)` + // Minimum execution time: 3_851_000 picoseconds. + Weight::from_parts(4_039_000, 0) + .saturating_add(Weight::from_parts(0, 128)) + // Standard Error: 1_612 + .saturating_add(Weight::from_parts(1_220_557, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/mod.rs b/polkadot/runtime/polkadot/src/weights/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..596b594c93707388d8c2a36bd2531a616dffd3b3 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/mod.rs @@ -0,0 +1,64 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! A list of the different weight modules for our runtime. + +pub mod frame_election_provider_support; +pub mod frame_system; +pub mod pallet_bags_list; +pub mod pallet_balances; +pub mod pallet_bounties; +pub mod pallet_child_bounties; +pub mod pallet_collective_council; +pub mod pallet_collective_technical_committee; +pub mod pallet_conviction_voting; +pub mod pallet_democracy; +pub mod pallet_election_provider_multi_phase; +pub mod pallet_elections_phragmen; +pub mod pallet_fast_unstake; +pub mod pallet_identity; +pub mod pallet_im_online; +pub mod pallet_indices; +pub mod pallet_membership; +pub mod pallet_message_queue; +pub mod pallet_multisig; +pub mod pallet_nomination_pools; +pub mod pallet_preimage; +pub mod pallet_proxy; +pub mod pallet_referenda; +pub mod pallet_scheduler; +pub mod pallet_session; +pub mod pallet_staking; +pub mod pallet_timestamp; +pub mod pallet_tips; +pub mod pallet_treasury; +pub mod pallet_utility; +pub mod pallet_vesting; +pub mod pallet_whitelist; +pub mod pallet_xcm; +pub mod runtime_common_auctions; +pub mod runtime_common_claims; +pub mod runtime_common_crowdloan; +pub mod runtime_common_paras_registrar; +pub mod runtime_common_slots; +pub mod runtime_parachains_configuration; +pub mod runtime_parachains_disputes; +pub mod runtime_parachains_disputes_slashing; +pub mod runtime_parachains_hrmp; +pub mod runtime_parachains_inclusion; +pub mod runtime_parachains_initializer; +pub mod runtime_parachains_paras; +pub mod runtime_parachains_paras_inherent; +pub mod xcm; diff --git a/polkadot/runtime/polkadot/src/weights/pallet_bags_list.rs b/polkadot/runtime/polkadot/src/weights/pallet_bags_list.rs new file mode 100644 index 0000000000000000000000000000000000000000..47decc88d73e0a80db09b776fd4c0b0a8eed2a22 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_bags_list.rs @@ -0,0 +1,109 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_bags_list` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_bags_list +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bags_list`. +pub struct WeightInfo(PhantomData); +impl pallet_bags_list::WeightInfo for WeightInfo { + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:4 w:4) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn rebag_non_terminal() -> Weight { + // Proof Size summary in bytes: + // Measured: `1622` + // Estimated: `11506` + // Minimum execution time: 61_742_000 picoseconds. + Weight::from_parts(63_696_000, 0) + .saturating_add(Weight::from_parts(0, 11506)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn rebag_terminal() -> Weight { + // Proof Size summary in bytes: + // Measured: `1516` + // Estimated: `8877` + // Minimum execution time: 60_247_000 picoseconds. + Weight::from_parts(62_096_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: VoterList ListNodes (r:4 w:4) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:2 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:2 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn put_in_front_of() -> Weight { + // Proof Size summary in bytes: + // Measured: `1827` + // Estimated: `11506` + // Minimum execution time: 67_049_000 picoseconds. + Weight::from_parts(68_704_000, 0) + .saturating_add(Weight::from_parts(0, 11506)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(6)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_balances.rs b/polkadot/runtime/polkadot/src/weights/pallet_balances.rs new file mode 100644 index 0000000000000000000000000000000000000000..374718082615204d49f4e06c51a7579e64326d22 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_balances.rs @@ -0,0 +1,153 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_balances` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_balances +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_balances`. +pub struct WeightInfo(PhantomData); +impl pallet_balances::WeightInfo for WeightInfo { + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_allow_death() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 56_740_000 picoseconds. + Weight::from_parts(57_361_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_keep_alive() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 42_767_000 picoseconds. + Weight::from_parts(43_195_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_set_balance_creating() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 17_405_000 picoseconds. + Weight::from_parts(17_754_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_set_balance_killing() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 24_580_000 picoseconds. + Weight::from_parts(25_063_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `6196` + // Minimum execution time: 59_923_000 picoseconds. + Weight::from_parts(60_797_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_all() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 52_587_000 picoseconds. + Weight::from_parts(53_496_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_unreserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 20_257_000 picoseconds. + Weight::from_parts(20_977_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:999 w:999) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `u` is `[1, 1000]`. + fn upgrade_accounts(u: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + u * (135 ±0)` + // Estimated: `990 + u * (2603 ±0)` + // Minimum execution time: 19_254_000 picoseconds. + Weight::from_parts(19_508_000, 0) + .saturating_add(Weight::from_parts(0, 990)) + // Standard Error: 12_504 + .saturating_add(Weight::from_parts(16_053_923, 0).saturating_mul(u.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_bounties.rs b/polkadot/runtime/polkadot/src/weights/pallet_bounties.rs new file mode 100644 index 0000000000000000000000000000000000000000..62a417832901954a01306579dba58bd5b7019c62 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_bounties.rs @@ -0,0 +1,230 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_bounties` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_bounties +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bounties`. +pub struct WeightInfo(PhantomData); +impl pallet_bounties::WeightInfo for WeightInfo { + /// Storage: Bounties BountyCount (r:1 w:1) + /// Proof: Bounties BountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:0 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// The range of component `d` is `[0, 16384]`. + fn propose_bounty(d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `177` + // Estimated: `3593` + // Minimum execution time: 30_000_000 picoseconds. + Weight::from_parts(31_021_890, 0) + .saturating_add(Weight::from_parts(0, 3593)) + // Standard Error: 6 + .saturating_add(Weight::from_parts(757, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + fn approve_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `269` + // Estimated: `3642` + // Minimum execution time: 11_055_000 picoseconds. + Weight::from_parts(11_875_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + fn propose_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `289` + // Estimated: `3642` + // Minimum execution time: 10_266_000 picoseconds. + Weight::from_parts(10_581_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn unassign_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `465` + // Estimated: `3642` + // Minimum execution time: 43_566_000 picoseconds. + Weight::from_parts(44_671_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn accept_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `461` + // Estimated: `3642` + // Minimum execution time: 28_400_000 picoseconds. + Weight::from_parts(29_259_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + fn award_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `439` + // Estimated: `3642` + // Minimum execution time: 20_071_000 picoseconds. + Weight::from_parts(20_662_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn claim_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `803` + // Estimated: `8799` + // Minimum execution time: 119_806_000 picoseconds. + Weight::from_parts(122_217_000, 0) + .saturating_add(Weight::from_parts(0, 8799)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn close_bounty_proposed() -> Weight { + // Proof Size summary in bytes: + // Measured: `483` + // Estimated: `3642` + // Minimum execution time: 48_528_000 picoseconds. + Weight::from_parts(49_592_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn close_bounty_active() -> Weight { + // Proof Size summary in bytes: + // Measured: `719` + // Estimated: `6196` + // Minimum execution time: 79_963_000 picoseconds. + Weight::from_parts(81_894_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + fn extend_bounty_expiry() -> Weight { + // Proof Size summary in bytes: + // Measured: `325` + // Estimated: `3642` + // Minimum execution time: 15_794_000 picoseconds. + Weight::from_parts(16_237_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:100 w:100) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:200 w:200) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `b` is `[0, 100]`. + fn spend_funds(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + b * (297 ±0)` + // Estimated: `1887 + b * (5206 ±0)` + // Minimum execution time: 5_312_000 picoseconds. + Weight::from_parts(5_480_000, 0) + .saturating_add(Weight::from_parts(0, 1887)) + // Standard Error: 12_652 + .saturating_add(Weight::from_parts(45_246_882, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(b.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(b.into()))) + .saturating_add(Weight::from_parts(0, 5206).saturating_mul(b.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_child_bounties.rs b/polkadot/runtime/polkadot/src/weights/pallet_child_bounties.rs new file mode 100644 index 0000000000000000000000000000000000000000..0e885883f093c739892944729ba8b1a1ec545ca5 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_child_bounties.rs @@ -0,0 +1,202 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_child_bounties` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_child_bounties +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_child_bounties`. +pub struct WeightInfo(PhantomData); +impl pallet_child_bounties::WeightInfo for WeightInfo { + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyCount (r:1 w:1) + /// Proof: ChildBounties ChildBountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:0 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// The range of component `d` is `[0, 16384]`. + fn add_child_bounty(d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `579` + // Estimated: `6196` + // Minimum execution time: 71_357_000 picoseconds. + Weight::from_parts(73_240_027, 0) + .saturating_add(Weight::from_parts(0, 6196)) + // Standard Error: 12 + .saturating_add(Weight::from_parts(830, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + fn propose_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `633` + // Estimated: `3642` + // Minimum execution time: 18_405_000 picoseconds. + Weight::from_parts(19_111_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn accept_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `779` + // Estimated: `3642` + // Minimum execution time: 33_467_000 picoseconds. + Weight::from_parts(34_246_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn unassign_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `779` + // Estimated: `3642` + // Minimum execution time: 49_658_000 picoseconds. + Weight::from_parts(50_457_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + fn award_child_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `676` + // Estimated: `3642` + // Minimum execution time: 22_723_000 picoseconds. + Weight::from_parts(23_232_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn claim_child_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `648` + // Estimated: `8799` + // Minimum execution time: 119_809_000 picoseconds. + Weight::from_parts(120_890_000, 0) + .saturating_add(Weight::from_parts(0, 8799)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn close_child_bounty_added() -> Weight { + // Proof Size summary in bytes: + // Measured: `879` + // Estimated: `6196` + // Minimum execution time: 77_381_000 picoseconds. + Weight::from_parts(78_284_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn close_child_bounty_active() -> Weight { + // Proof Size summary in bytes: + // Measured: `1066` + // Estimated: `8799` + // Minimum execution time: 95_032_000 picoseconds. + Weight::from_parts(96_932_000, 0) + .saturating_add(Weight::from_parts(0, 8799)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(7)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_collective_council.rs b/polkadot/runtime/polkadot/src/weights/pallet_collective_council.rs new file mode 100644 index 0000000000000000000000000000000000000000..0d75865bf2e9e519516f473ae172598db8b4bbfe --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_collective_council.rs @@ -0,0 +1,327 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_collective` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_collective +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_collective`. +pub struct WeightInfo(PhantomData); +impl pallet_collective::WeightInfo for WeightInfo { + /// Storage: Council Members (r:1 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:100 w:100) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Prime (r:0 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + fn set_members(m: u32, _n: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + m * (3232 ±0) + p * (3190 ±0)` + // Estimated: `15762 + m * (1967 ±16) + p * (4332 ±16)` + // Minimum execution time: 17_563_000 picoseconds. + Weight::from_parts(17_790_000, 0) + .saturating_add(Weight::from_parts(0, 15762)) + // Standard Error: 43_106 + .saturating_add(Weight::from_parts(4_715_053, 0).saturating_mul(m.into())) + // Standard Error: 43_106 + .saturating_add(Weight::from_parts(8_200_250, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 1967).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 4332).saturating_mul(p.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `103 + m * (32 ±0)` + // Estimated: `1589 + m * (32 ±0)` + // Minimum execution time: 16_175_000 picoseconds. + Weight::from_parts(15_361_457, 0) + .saturating_add(Weight::from_parts(0, 1589)) + // Standard Error: 17 + .saturating_add(Weight::from_parts(1_795, 0).saturating_mul(b.into())) + // Standard Error: 184 + .saturating_add(Weight::from_parts(14_177, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:0) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn propose_execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `103 + m * (32 ±0)` + // Estimated: `3569 + m * (32 ±0)` + // Minimum execution time: 18_948_000 picoseconds. + Weight::from_parts(18_240_525, 0) + .saturating_add(Weight::from_parts(0, 3569)) + // Standard Error: 21 + .saturating_add(Weight::from_parts(1_603, 0).saturating_mul(b.into())) + // Standard Error: 224 + .saturating_add(Weight::from_parts(22_805, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalCount (r:1 w:1) + /// Proof Skipped: Council ProposalCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:0 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `393 + m * (32 ±0) + p * (36 ±0)` + // Estimated: `3785 + m * (33 ±0) + p * (36 ±0)` + // Minimum execution time: 25_762_000 picoseconds. + Weight::from_parts(24_727_354, 0) + .saturating_add(Weight::from_parts(0, 3785)) + // Standard Error: 87 + .saturating_add(Weight::from_parts(3_653, 0).saturating_mul(b.into())) + // Standard Error: 908 + .saturating_add(Weight::from_parts(28_147, 0).saturating_mul(m.into())) + // Standard Error: 897 + .saturating_add(Weight::from_parts(198_752, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 33).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[5, 100]`. + /// The range of component `m` is `[5, 100]`. + fn vote(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `842 + m * (64 ±0)` + // Estimated: `4306 + m * (64 ±0)` + // Minimum execution time: 26_644_000 picoseconds. + Weight::from_parts(27_694_655, 0) + .saturating_add(Weight::from_parts(0, 4306)) + // Standard Error: 624 + .saturating_add(Weight::from_parts(54_184, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `431 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3876 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 27_742_000 picoseconds. + Weight::from_parts(27_892_765, 0) + .saturating_add(Weight::from_parts(0, 3876)) + // Standard Error: 666 + .saturating_add(Weight::from_parts(35_102, 0).saturating_mul(m.into())) + // Standard Error: 649 + .saturating_add(Weight::from_parts(190_180, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `733 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4050 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 39_283_000 picoseconds. + Weight::from_parts(40_633_810, 0) + .saturating_add(Weight::from_parts(0, 4050)) + // Standard Error: 144 + .saturating_add(Weight::from_parts(3_292, 0).saturating_mul(b.into())) + // Standard Error: 1_524 + .saturating_add(Weight::from_parts(9_562, 0).saturating_mul(m.into())) + // Standard Error: 1_485 + .saturating_add(Weight::from_parts(237_159, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:0) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `451 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3896 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 30_417_000 picoseconds. + Weight::from_parts(30_840_007, 0) + .saturating_add(Weight::from_parts(0, 3896)) + // Standard Error: 662 + .saturating_add(Weight::from_parts(37_877, 0).saturating_mul(m.into())) + // Standard Error: 645 + .saturating_add(Weight::from_parts(189_312, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:0) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `753 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4070 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 41_630_000 picoseconds. + Weight::from_parts(42_847_316, 0) + .saturating_add(Weight::from_parts(0, 4070)) + // Standard Error: 134 + .saturating_add(Weight::from_parts(3_962, 0).saturating_mul(b.into())) + // Standard Error: 1_423 + .saturating_add(Weight::from_parts(22_489, 0).saturating_mul(m.into())) + // Standard Error: 1_387 + .saturating_add(Weight::from_parts(244_543, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) + } + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:0 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `p` is `[1, 100]`. + /// The range of component `p` is `[1, 100]`. + fn disapprove_proposal(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `260 + p * (32 ±0)` + // Estimated: `1745 + p * (32 ±0)` + // Minimum execution time: 15_754_000 picoseconds. + Weight::from_parts(17_477_133, 0) + .saturating_add(Weight::from_parts(0, 1745)) + // Standard Error: 608 + .saturating_add(Weight::from_parts(178_320, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_collective_technical_committee.rs b/polkadot/runtime/polkadot/src/weights/pallet_collective_technical_committee.rs new file mode 100644 index 0000000000000000000000000000000000000000..07fb1209b0a17b1a8990a0f71f81804d2d13314b --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_collective_technical_committee.rs @@ -0,0 +1,327 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_collective` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_collective +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_collective`. +pub struct WeightInfo(PhantomData); +impl pallet_collective::WeightInfo for WeightInfo { + /// Storage: TechnicalCommittee Members (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:100 w:100) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + fn set_members(m: u32, _n: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + m * (3232 ±0) + p * (3190 ±0)` + // Estimated: `15800 + m * (1967 ±16) + p * (4332 ±16)` + // Minimum execution time: 18_203_000 picoseconds. + Weight::from_parts(18_473_000, 0) + .saturating_add(Weight::from_parts(0, 15800)) + // Standard Error: 43_603 + .saturating_add(Weight::from_parts(4_734_955, 0).saturating_mul(m.into())) + // Standard Error: 43_603 + .saturating_add(Weight::from_parts(8_291_611, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 1967).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 4332).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `141 + m * (32 ±0)` + // Estimated: `1627 + m * (32 ±0)` + // Minimum execution time: 17_071_000 picoseconds. + Weight::from_parts(16_315_595, 0) + .saturating_add(Weight::from_parts(0, 1627)) + // Standard Error: 14 + .saturating_add(Weight::from_parts(1_706, 0).saturating_mul(b.into())) + // Standard Error: 146 + .saturating_add(Weight::from_parts(13_626, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:0) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn propose_execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `141 + m * (32 ±0)` + // Estimated: `3607 + m * (32 ±0)` + // Minimum execution time: 19_983_000 picoseconds. + Weight::from_parts(18_925_239, 0) + .saturating_add(Weight::from_parts(0, 3607)) + // Standard Error: 17 + .saturating_add(Weight::from_parts(1_664, 0).saturating_mul(b.into())) + // Standard Error: 176 + .saturating_add(Weight::from_parts(23_169, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalCount (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `431 + m * (32 ±0) + p * (36 ±0)` + // Estimated: `3823 + m * (33 ±0) + p * (36 ±0)` + // Minimum execution time: 26_490_000 picoseconds. + Weight::from_parts(25_739_853, 0) + .saturating_add(Weight::from_parts(0, 3823)) + // Standard Error: 77 + .saturating_add(Weight::from_parts(3_479, 0).saturating_mul(b.into())) + // Standard Error: 807 + .saturating_add(Weight::from_parts(28_438, 0).saturating_mul(m.into())) + // Standard Error: 796 + .saturating_add(Weight::from_parts(199_864, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 33).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[5, 100]`. + /// The range of component `m` is `[5, 100]`. + fn vote(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `880 + m * (64 ±0)` + // Estimated: `4344 + m * (64 ±0)` + // Minimum execution time: 27_693_000 picoseconds. + Weight::from_parts(28_461_881, 0) + .saturating_add(Weight::from_parts(0, 4344)) + // Standard Error: 592 + .saturating_add(Weight::from_parts(55_442, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:0 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3914 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 28_958_000 picoseconds. + Weight::from_parts(28_772_598, 0) + .saturating_add(Weight::from_parts(0, 3914)) + // Standard Error: 673 + .saturating_add(Weight::from_parts(36_736, 0).saturating_mul(m.into())) + // Standard Error: 657 + .saturating_add(Weight::from_parts(191_282, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `771 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4088 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 40_599_000 picoseconds. + Weight::from_parts(40_617_733, 0) + .saturating_add(Weight::from_parts(0, 4088)) + // Standard Error: 122 + .saturating_add(Weight::from_parts(3_479, 0).saturating_mul(b.into())) + // Standard Error: 1_296 + .saturating_add(Weight::from_parts(34_407, 0).saturating_mul(m.into())) + // Standard Error: 1_263 + .saturating_add(Weight::from_parts(236_766, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:0 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `489 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3934 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 32_265_000 picoseconds. + Weight::from_parts(31_660_039, 0) + .saturating_add(Weight::from_parts(0, 3934)) + // Standard Error: 689 + .saturating_add(Weight::from_parts(39_118, 0).saturating_mul(m.into())) + // Standard Error: 672 + .saturating_add(Weight::from_parts(192_797, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `791 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4108 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 42_456_000 picoseconds. + Weight::from_parts(43_760_828, 0) + .saturating_add(Weight::from_parts(0, 4108)) + // Standard Error: 132 + .saturating_add(Weight::from_parts(3_531, 0).saturating_mul(b.into())) + // Standard Error: 1_397 + .saturating_add(Weight::from_parts(28_101, 0).saturating_mul(m.into())) + // Standard Error: 1_362 + .saturating_add(Weight::from_parts(248_244, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:0 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `p` is `[1, 100]`. + /// The range of component `p` is `[1, 100]`. + fn disapprove_proposal(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `298 + p * (32 ±0)` + // Estimated: `1783 + p * (32 ±0)` + // Minimum execution time: 16_506_000 picoseconds. + Weight::from_parts(18_127_000, 0) + .saturating_add(Weight::from_parts(0, 1783)) + // Standard Error: 616 + .saturating_add(Weight::from_parts(175_889, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_conviction_voting.rs b/polkadot/runtime/polkadot/src/weights/pallet_conviction_voting.rs new file mode 100644 index 0000000000000000000000000000000000000000..ce42464c292f742e6fcbcfb23f661961fc90fe19 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_conviction_voting.rs @@ -0,0 +1,195 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_conviction_voting` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_conviction_voting +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_conviction_voting`. +pub struct WeightInfo(PhantomData); +impl pallet_conviction_voting::WeightInfo for WeightInfo { + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn vote_new() -> Weight { + // Proof Size summary in bytes: + // Measured: `13551` + // Estimated: `42428` + // Minimum execution time: 154_104_000 picoseconds. + Weight::from_parts(162_701_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn vote_existing() -> Weight { + // Proof Size summary in bytes: + // Measured: `14272` + // Estimated: `83866` + // Minimum execution time: 241_839_000 picoseconds. + Weight::from_parts(251_787_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn remove_vote() -> Weight { + // Proof Size summary in bytes: + // Measured: `14024` + // Estimated: `83866` + // Minimum execution time: 198_871_000 picoseconds. + Weight::from_parts(208_410_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + fn remove_other_vote() -> Weight { + // Proof Size summary in bytes: + // Measured: `13110` + // Estimated: `30706` + // Minimum execution time: 86_480_000 picoseconds. + Weight::from_parts(90_343_000, 0) + .saturating_add(Weight::from_parts(0, 30706)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ConvictionVoting VotingFor (r:2 w:2) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:512 w:512) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 512]`. + fn delegate(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `29746 + r * (365 ±0)` + // Estimated: `83866 + r * (3411 ±0)` + // Minimum execution time: 82_384_000 picoseconds. + Weight::from_parts(1_967_705_239, 0) + .saturating_add(Weight::from_parts(0, 83866)) + // Standard Error: 169_648 + .saturating_add(Weight::from_parts(46_550_419, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 3411).saturating_mul(r.into())) + } + /// Storage: ConvictionVoting VotingFor (r:2 w:2) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:512 w:512) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 512]`. + fn undelegate(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `29661 + r * (365 ±0)` + // Estimated: `83866 + r * (3411 ±0)` + // Minimum execution time: 50_266_000 picoseconds. + Weight::from_parts(1_956_854_151, 0) + .saturating_add(Weight::from_parts(0, 83866)) + // Standard Error: 172_335 + .saturating_add(Weight::from_parts(46_688_704, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 3411).saturating_mul(r.into())) + } + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + fn unlock() -> Weight { + // Proof Size summary in bytes: + // Measured: `12323` + // Estimated: `30706` + // Minimum execution time: 114_930_000 picoseconds. + Weight::from_parts(122_209_000, 0) + .saturating_add(Weight::from_parts(0, 30706)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_democracy.rs b/polkadot/runtime/polkadot/src/weights/pallet_democracy.rs new file mode 100644 index 0000000000000000000000000000000000000000..069b10a2bcc5ad1949cb26120766334e8ed4a729 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_democracy.rs @@ -0,0 +1,528 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_democracy` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_democracy +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_democracy`. +pub struct WeightInfo(PhantomData); +impl pallet_democracy::WeightInfo for WeightInfo { + /// Storage: Democracy PublicPropCount (r:1 w:1) + /// Proof: Democracy PublicPropCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:0) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:0 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + fn propose() -> Weight { + // Proof Size summary in bytes: + // Measured: `4768` + // Estimated: `18187` + // Minimum execution time: 47_165_000 picoseconds. + Weight::from_parts(48_488_000, 0) + .saturating_add(Weight::from_parts(0, 18187)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + fn second() -> Weight { + // Proof Size summary in bytes: + // Measured: `3523` + // Estimated: `6695` + // Minimum execution time: 41_328_000 picoseconds. + Weight::from_parts(42_526_000, 0) + .saturating_add(Weight::from_parts(0, 6695)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + fn vote_new() -> Weight { + // Proof Size summary in bytes: + // Measured: `3437` + // Estimated: `7260` + // Minimum execution time: 57_941_000 picoseconds. + Weight::from_parts(59_547_000, 0) + .saturating_add(Weight::from_parts(0, 7260)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + fn vote_existing() -> Weight { + // Proof Size summary in bytes: + // Measured: `3459` + // Estimated: `7260` + // Minimum execution time: 63_933_000 picoseconds. + Weight::from_parts(65_560_000, 0) + .saturating_add(Weight::from_parts(0, 7260)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy Cancellations (r:1 w:1) + /// Proof: Democracy Cancellations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn emergency_cancel() -> Weight { + // Proof Size summary in bytes: + // Measured: `333` + // Estimated: `3666` + // Minimum execution time: 26_501_000 picoseconds. + Weight::from_parts(26_882_000, 0) + .saturating_add(Weight::from_parts(0, 3666)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:3 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:0 w:1) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + fn blacklist() -> Weight { + // Proof Size summary in bytes: + // Measured: `5877` + // Estimated: `18187` + // Minimum execution time: 111_868_000 picoseconds. + Weight::from_parts(116_733_000, 0) + .saturating_add(Weight::from_parts(0, 18187)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:0) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + fn external_propose() -> Weight { + // Proof Size summary in bytes: + // Measured: `3383` + // Estimated: `6703` + // Minimum execution time: 13_786_000 picoseconds. + Weight::from_parts(14_280_000, 0) + .saturating_add(Weight::from_parts(0, 6703)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:0 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + fn external_propose_majority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_320_000 picoseconds. + Weight::from_parts(3_467_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:0 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + fn external_propose_default() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_540_000 picoseconds. + Weight::from_parts(3_681_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:1) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:2) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:0 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + fn fast_track() -> Weight { + // Proof Size summary in bytes: + // Measured: `253` + // Estimated: `3518` + // Minimum execution time: 28_074_000 picoseconds. + Weight::from_parts(28_980_000, 0) + .saturating_add(Weight::from_parts(0, 3518)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:1) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn veto_external() -> Weight { + // Proof Size summary in bytes: + // Measured: `3486` + // Estimated: `6703` + // Minimum execution time: 32_243_000 picoseconds. + Weight::from_parts(32_604_000, 0) + .saturating_add(Weight::from_parts(0, 6703)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn cancel_proposal() -> Weight { + // Proof Size summary in bytes: + // Measured: `5788` + // Estimated: `18187` + // Minimum execution time: 93_410_000 picoseconds. + Weight::from_parts(95_323_000, 0) + .saturating_add(Weight::from_parts(0, 18187)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:0 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + fn cancel_referendum() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3518` + // Minimum execution time: 20_185_000 picoseconds. + Weight::from_parts(20_661_000, 0) + .saturating_add(Weight::from_parts(0, 3518)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Democracy LowestUnbaked (r:1 w:1) + /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:0) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn on_initialize_base(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `211 + r * (86 ±0)` + // Estimated: `1489 + r * (2676 ±0)` + // Minimum execution time: 7_484_000 picoseconds. + Weight::from_parts(8_532_503, 0) + .saturating_add(Weight::from_parts(0, 1489)) + // Standard Error: 6_320 + .saturating_add(Weight::from_parts(3_176_208, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy LowestUnbaked (r:1 w:1) + /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:0) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy LastTabledWasExternal (r:1 w:0) + /// Proof: Democracy LastTabledWasExternal (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn on_initialize_base_with_launch_period(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `211 + r * (86 ±0)` + // Estimated: `18187 + r * (2676 ±0)` + // Minimum execution time: 10_406_000 picoseconds. + Weight::from_parts(11_689_093, 0) + .saturating_add(Weight::from_parts(0, 18187)) + // Standard Error: 7_450 + .saturating_add(Weight::from_parts(3_172_162, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy VotingOf (r:3 w:3) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:99) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn delegate(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `797 + r * (108 ±0)` + // Estimated: `19800 + r * (2676 ±0)` + // Minimum execution time: 42_210_000 picoseconds. + Weight::from_parts(47_151_756, 0) + .saturating_add(Weight::from_parts(0, 19800)) + // Standard Error: 9_095 + .saturating_add(Weight::from_parts(4_553_285, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy VotingOf (r:2 w:2) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:99) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn undelegate(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `460 + r * (108 ±0)` + // Estimated: `13530 + r * (2676 ±0)` + // Minimum execution time: 21_815_000 picoseconds. + Weight::from_parts(21_914_769, 0) + .saturating_add(Weight::from_parts(0, 13530)) + // Standard Error: 7_866 + .saturating_add(Weight::from_parts(4_497_036, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy PublicProps (r:0 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + fn clear_public_proposals() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_315_000 picoseconds. + Weight::from_parts(3_525_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn unlock_remove(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `530` + // Estimated: `7260` + // Minimum execution time: 25_326_000 picoseconds. + Weight::from_parts(40_406_995, 0) + .saturating_add(Weight::from_parts(0, 7260)) + // Standard Error: 3_775 + .saturating_add(Weight::from_parts(111_536, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn unlock_set(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `531 + r * (22 ±0)` + // Estimated: `7260` + // Minimum execution time: 35_263_000 picoseconds. + Weight::from_parts(39_034_189, 0) + .saturating_add(Weight::from_parts(0, 7260)) + // Standard Error: 2_263 + .saturating_add(Weight::from_parts(143_605, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 100]`. + fn remove_vote(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `695 + r * (26 ±0)` + // Estimated: `7260` + // Minimum execution time: 15_880_000 picoseconds. + Weight::from_parts(19_395_916, 0) + .saturating_add(Weight::from_parts(0, 7260)) + // Standard Error: 1_616 + .saturating_add(Weight::from_parts(144_889, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 100]`. + fn remove_other_vote(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `695 + r * (26 ±0)` + // Estimated: `7260` + // Minimum execution time: 16_157_000 picoseconds. + Weight::from_parts(19_671_561, 0) + .saturating_add(Weight::from_parts(0, 7260)) + // Standard Error: 1_803 + .saturating_add(Weight::from_parts(143_214, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn set_external_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `323` + // Estimated: `3556` + // Minimum execution time: 18_768_000 picoseconds. + Weight::from_parts(19_420_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn clear_external_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `253` + // Estimated: `3518` + // Minimum execution time: 17_184_000 picoseconds. + Weight::from_parts(17_768_000, 0) + .saturating_add(Weight::from_parts(0, 3518)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn set_proposal_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `4855` + // Estimated: `18187` + // Minimum execution time: 40_295_000 picoseconds. + Weight::from_parts(41_356_000, 0) + .saturating_add(Weight::from_parts(0, 18187)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn clear_proposal_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `4789` + // Estimated: `18187` + // Minimum execution time: 37_215_000 picoseconds. + Weight::from_parts(38_297_000, 0) + .saturating_add(Weight::from_parts(0, 18187)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn set_referendum_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 14_960_000 picoseconds. + Weight::from_parts(15_339_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn clear_referendum_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `269` + // Estimated: `3666` + // Minimum execution time: 19_182_000 picoseconds. + Weight::from_parts(19_788_000, 0) + .saturating_add(Weight::from_parts(0, 3666)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_election_provider_multi_phase.rs b/polkadot/runtime/polkadot/src/weights/pallet_election_provider_multi_phase.rs new file mode 100644 index 0000000000000000000000000000000000000000..f16da40e8eceb02293ac6d6149c6bc1bba2ecaab --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_election_provider_multi_phase.rs @@ -0,0 +1,272 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_election_provider_multi_phase` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_election_provider_multi_phase +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_election_provider_multi_phase`. +pub struct WeightInfo(PhantomData); +impl pallet_election_provider_multi_phase::WeightInfo for WeightInfo { + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentPlannedSession (r:1 w:0) + /// Proof: Staking CurrentPlannedSession (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Babe EpochIndex (r:1 w:0) + /// Proof: Babe EpochIndex (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe GenesisSlot (r:1 w:0) + /// Proof: Babe GenesisSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Staking ForceEra (r:1 w:0) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + fn on_initialize_nothing() -> Weight { + // Proof Size summary in bytes: + // Measured: `993` + // Estimated: `3481` + // Minimum execution time: 19_675_000 picoseconds. + Weight::from_parts(20_310_000, 0) + .saturating_add(Weight::from_parts(0, 3481)) + .saturating_add(T::DbWeight::get().reads(8)) + } + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + fn on_initialize_open_signed() -> Weight { + // Proof Size summary in bytes: + // Measured: `114` + // Estimated: `1599` + // Minimum execution time: 12_119_000 picoseconds. + Weight::from_parts(12_730_000, 0) + .saturating_add(Weight::from_parts(0, 1599)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + fn on_initialize_open_unsigned() -> Weight { + // Proof Size summary in bytes: + // Measured: `114` + // Estimated: `1599` + // Minimum execution time: 13_456_000 picoseconds. + Weight::from_parts(13_787_000, 0) + .saturating_add(Weight::from_parts(0, 1599)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + fn finalize_signed_phase_accept_solution() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 33_871_000 picoseconds. + Weight::from_parts(34_289_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn finalize_signed_phase_reject_solution() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 22_897_000 picoseconds. + Weight::from_parts(23_307_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + fn create_snapshot_internal(v: u32, _t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 556_279_000 picoseconds. + Weight::from_parts(581_580_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3_088 + .saturating_add(Weight::from_parts(312_241, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `a` is `[500, 800]`. + /// The range of component `d` is `[200, 400]`. + fn elect_queued(a: u32, d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `338 + a * (768 ±0) + d * (48 ±0)` + // Estimated: `3890 + a * (768 ±0) + d * (49 ±0)` + // Minimum execution time: 420_334_000 picoseconds. + Weight::from_parts(18_023_312, 0) + .saturating_add(Weight::from_parts(0, 3890)) + // Standard Error: 7_565 + .saturating_add(Weight::from_parts(659_974, 0).saturating_mul(a.into())) + // Standard Error: 11_339 + .saturating_add(Weight::from_parts(287_336, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(9)) + .saturating_add(Weight::from_parts(0, 768).saturating_mul(a.into())) + .saturating_add(Weight::from_parts(0, 49).saturating_mul(d.into())) + } + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TransactionPayment NextFeeMultiplier (r:1 w:0) + /// Proof: TransactionPayment NextFeeMultiplier (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) + fn submit() -> Weight { + // Proof Size summary in bytes: + // Measured: `1204` + // Estimated: `2689` + // Minimum execution time: 49_669_000 picoseconds. + Weight::from_parts(52_076_000, 0) + .saturating_add(Weight::from_parts(0, 2689)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `a` is `[500, 800]`. + /// The range of component `d` is `[200, 400]`. + fn submit_unsigned(v: u32, t: u32, a: u32, _d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `219 + t * (32 ±0) + v * (553 ±0)` + // Estimated: `1704 + t * (32 ±0) + v * (553 ±0)` + // Minimum execution time: 5_966_688_000 picoseconds. + Weight::from_parts(6_129_265_000, 0) + .saturating_add(Weight::from_parts(0, 1704)) + // Standard Error: 20_174 + .saturating_add(Weight::from_parts(154_243, 0).saturating_mul(v.into())) + // Standard Error: 59_786 + .saturating_add(Weight::from_parts(5_709_666, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) + .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) + } + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `a` is `[500, 800]`. + /// The range of component `d` is `[200, 400]`. + fn feasibility_check(v: u32, t: u32, a: u32, _d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `194 + t * (32 ±0) + v * (553 ±0)` + // Estimated: `1679 + t * (32 ±0) + v * (553 ±0)` + // Minimum execution time: 5_058_457_000 picoseconds. + Weight::from_parts(5_216_393_000, 0) + .saturating_add(Weight::from_parts(0, 1679)) + // Standard Error: 15_829 + .saturating_add(Weight::from_parts(278_945, 0).saturating_mul(v.into())) + // Standard Error: 46_908 + .saturating_add(Weight::from_parts(3_239_889, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) + .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_elections_phragmen.rs b/polkadot/runtime/polkadot/src/weights/pallet_elections_phragmen.rs new file mode 100644 index 0000000000000000000000000000000000000000..e93de0c14c1c2190bfba6cdce9b1f9680ffb5ba4 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_elections_phragmen.rs @@ -0,0 +1,318 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_elections_phragmen` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_elections_phragmen +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_elections_phragmen`. +pub struct WeightInfo(PhantomData); +impl pallet_elections_phragmen::WeightInfo for WeightInfo { + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `v` is `[1, 16]`. + fn vote_equal(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `369 + v * (80 ±0)` + // Estimated: `4764 + v * (80 ±0)` + // Minimum execution time: 32_711_000 picoseconds. + Weight::from_parts(33_843_954, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 3_332 + .saturating_add(Weight::from_parts(148_060, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `v` is `[2, 16]`. + fn vote_more(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `337 + v * (80 ±0)` + // Estimated: `4764 + v * (80 ±0)` + // Minimum execution time: 46_078_000 picoseconds. + Weight::from_parts(46_574_818, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 3_834 + .saturating_add(Weight::from_parts(182_895, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `v` is `[2, 16]`. + fn vote_less(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `369 + v * (80 ±0)` + // Estimated: `4764 + v * (80 ±0)` + // Minimum execution time: 45_677_000 picoseconds. + Weight::from_parts(46_613_391, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 4_271 + .saturating_add(Weight::from_parts(180_095, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + fn remove_voter() -> Weight { + // Proof Size summary in bytes: + // Measured: `891` + // Estimated: `4764` + // Minimum execution time: 47_963_000 picoseconds. + Weight::from_parts(48_833_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: PhragmenElection Candidates (r:1 w:1) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `c` is `[1, 1000]`. + fn submit_candidacy(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2358 + c * (48 ±0)` + // Estimated: `3841 + c * (48 ±0)` + // Minimum execution time: 39_368_000 picoseconds. + Weight::from_parts(28_568_416, 0) + .saturating_add(Weight::from_parts(0, 3841)) + // Standard Error: 1_416 + .saturating_add(Weight::from_parts(131_107, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:1) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `c` is `[1, 1000]`. + fn renounce_candidacy_candidate(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `250 + c * (48 ±0)` + // Estimated: `1722 + c * (48 ±0)` + // Minimum execution time: 34_977_000 picoseconds. + Weight::from_parts(24_677_388, 0) + .saturating_add(Weight::from_parts(0, 1722)) + // Standard Error: 1_498 + .saturating_add(Weight::from_parts(100_855, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) + } + /// Storage: PhragmenElection Members (r:1 w:1) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + fn renounce_candidacy_members() -> Weight { + // Proof Size summary in bytes: + // Measured: `2599` + // Estimated: `4084` + // Minimum execution time: 52_891_000 picoseconds. + Weight::from_parts(53_852_000, 0) + .saturating_add(Weight::from_parts(0, 4084)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + fn renounce_candidacy_runners_up() -> Weight { + // Proof Size summary in bytes: + // Measured: `1711` + // Estimated: `3196` + // Minimum execution time: 36_514_000 picoseconds. + Weight::from_parts(37_441_000, 0) + .saturating_add(Weight::from_parts(0, 3196)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + fn remove_member_without_replacement() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_000_000_000_000 picoseconds. + Weight::from_parts(2_000_000_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: PhragmenElection Members (r:1 w:1) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + fn remove_member_with_replacement() -> Weight { + // Proof Size summary in bytes: + // Measured: `2599` + // Estimated: `4084` + // Minimum execution time: 73_160_000 picoseconds. + Weight::from_parts(74_548_000, 0) + .saturating_add(Weight::from_parts(0, 4084)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: PhragmenElection Voting (r:10001 w:10000) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Balances Locks (r:10000 w:10000) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:10000 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:10000 w:10000) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `v` is `[5000, 10000]`. + /// The range of component `d` is `[0, 5000]`. + fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `36028 + v * (808 ±0)` + // Estimated: `39768 + v * (3774 ±0)` + // Minimum execution time: 434_369_619_000 picoseconds. + Weight::from_parts(436_606_328_000, 0) + .saturating_add(Weight::from_parts(0, 39768)) + // Standard Error: 365_744 + .saturating_add(Weight::from_parts(53_633_149, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:1) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:1) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:10001 w:0) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:967 w:967) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: PhragmenElection ElectionRounds (r:1 w:1) + /// Proof Skipped: PhragmenElection ElectionRounds (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:0 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `c` is `[1, 1000]`. + /// The range of component `v` is `[1, 10000]`. + /// The range of component `e` is `[10000, 160000]`. + fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + e * (28 ±0) + v * (607 ±0)` + // Estimated: `2771984 + c * (2560 ±0) + e * (16 ±0) + v * (2744 ±4)` + // Minimum execution time: 39_817_678_000 picoseconds. + Weight::from_parts(40_023_537_000, 0) + .saturating_add(Weight::from_parts(0, 2771984)) + // Standard Error: 411_583 + .saturating_add(Weight::from_parts(34_005_169, 0).saturating_mul(v.into())) + // Standard Error: 26_412 + .saturating_add(Weight::from_parts(1_743_887, 0).saturating_mul(e.into())) + .saturating_add(T::DbWeight::get().reads(269)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 2560).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 16).saturating_mul(e.into())) + .saturating_add(Weight::from_parts(0, 2744).saturating_mul(v.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_fast_unstake.rs b/polkadot/runtime/polkadot/src/weights/pallet_fast_unstake.rs new file mode 100644 index 0000000000000000000000000000000000000000..38771e04cb5738a51f77d9565fa5bbf3fdef7fb6 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_fast_unstake.rs @@ -0,0 +1,203 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_fast_unstake` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_fast_unstake +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_fast_unstake`. +pub struct WeightInfo(PhantomData); +impl pallet_fast_unstake::WeightInfo for WeightInfo { + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:1) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(886), added: 1381, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:0) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:16 w:0) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Bonded (r:16 w:16) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:16 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:16 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: System Account (r:16 w:16) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:16 w:16) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:16 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:0 w:16) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:16) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 16]`. + fn on_idle_unstake(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1057 + b * (359 ±0)` + // Estimated: `2542 + b * (3774 ±0)` + // Minimum execution time: 89_149_000 picoseconds. + Weight::from_parts(41_025_862, 0) + .saturating_add(Weight::from_parts(0, 2542)) + // Standard Error: 41_892 + .saturating_add(Weight::from_parts(56_756_404, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(b.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(b.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(b.into())) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:1) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(886), added: 1381, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:0) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStakers (r:257 w:0) + /// Proof Skipped: Staking ErasStakers (max_values: None, max_size: None, mode: Measured) + /// The range of component `v` is `[1, 256]`. + /// The range of component `b` is `[1, 16]`. + fn on_idle_check(v: u32, b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1411 + b * (48 ±0) + v * (19511 ±0)` + // Estimated: `4726 + b * (52 ±0) + v * (21987 ±0)` + // Minimum execution time: 645_357_000 picoseconds. + Weight::from_parts(650_793_000, 0) + .saturating_add(Weight::from_parts(0, 4726)) + // Standard Error: 5_811_859 + .saturating_add(Weight::from_parts(194_264_130, 0).saturating_mul(v.into())) + // Standard Error: 93_262_882 + .saturating_add(Weight::from_parts(2_905_419_408, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 52).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 21987).saturating_mul(v.into())) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: FastUnstake Queue (r:1 w:1) + /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:0) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(886), added: 1381, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:1) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn register_fast_unstake() -> Weight { + // Proof Size summary in bytes: + // Measured: `1919` + // Estimated: `6248` + // Minimum execution time: 128_072_000 picoseconds. + Weight::from_parts(133_183_000, 0) + .saturating_add(Weight::from_parts(0, 6248)) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(10)) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: FastUnstake Queue (r:1 w:1) + /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:0) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(886), added: 1381, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:1) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn deregister() -> Weight { + // Proof Size summary in bytes: + // Measured: `1118` + // Estimated: `4556` + // Minimum execution time: 40_801_000 picoseconds. + Weight::from_parts(42_396_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:0 w:1) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn control() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_531_000 picoseconds. + Weight::from_parts(2_706_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_identity.rs b/polkadot/runtime/polkadot/src/weights/pallet_identity.rs new file mode 100644 index 0000000000000000000000000000000000000000..8ec244ea127c10baafd7d2646b66dea919a83833 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_identity.rs @@ -0,0 +1,359 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_identity` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_identity +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_identity`. +pub struct WeightInfo(PhantomData); +impl pallet_identity::WeightInfo for WeightInfo { + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn add_registrar(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `32 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 12_135_000 picoseconds. + Weight::from_parts(12_609_967, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 2_052 + .saturating_add(Weight::from_parts(100_719, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn set_identity(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `442 + r * (5 ±0)` + // Estimated: `11003` + // Minimum execution time: 32_888_000 picoseconds. + Weight::from_parts(30_128_985, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 5_003 + .saturating_add(Weight::from_parts(185_434, 0).saturating_mul(r.into())) + // Standard Error: 976 + .saturating_add(Weight::from_parts(470_886, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:100 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn set_subs_new(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `11003 + s * (2589 ±0)` + // Minimum execution time: 8_780_000 picoseconds. + Weight::from_parts(21_992_489, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 3_846 + .saturating_add(Weight::from_parts(3_111_150, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(s.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 2589).saturating_mul(s.into())) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 100]`. + fn set_subs_old(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `194 + p * (32 ±0)` + // Estimated: `11003` + // Minimum execution time: 8_828_000 picoseconds. + Weight::from_parts(22_708_063, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 3_578 + .saturating_add(Weight::from_parts(1_303_160, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + } + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `s` is `[0, 100]`. + /// The range of component `x` is `[0, 100]`. + fn clear_identity(r: u32, s: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 56_805_000 picoseconds. + Weight::from_parts(32_595_150, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 9_806 + .saturating_add(Weight::from_parts(148_154, 0).saturating_mul(r.into())) + // Standard Error: 1_915 + .saturating_add(Weight::from_parts(1_305_241, 0).saturating_mul(s.into())) + // Standard Error: 1_915 + .saturating_add(Weight::from_parts(253_271, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn request_judgement(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `367 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 32_747_000 picoseconds. + Weight::from_parts(30_894_600, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 3_575 + .saturating_add(Weight::from_parts(173_522, 0).saturating_mul(r.into())) + // Standard Error: 697 + .saturating_add(Weight::from_parts(484_893, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn cancel_request(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `398 + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 29_601_000 picoseconds. + Weight::from_parts(28_786_367, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 4_460 + .saturating_add(Weight::from_parts(120_240, 0).saturating_mul(r.into())) + // Standard Error: 870 + .saturating_add(Weight::from_parts(484_414, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_fee(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_562_000 picoseconds. + Weight::from_parts(8_106_958, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_945 + .saturating_add(Weight::from_parts(75_862, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_account_id(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_437_000 picoseconds. + Weight::from_parts(7_970_108, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_497 + .saturating_add(Weight::from_parts(93_785, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_fields(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_337_000 picoseconds. + Weight::from_parts(7_782_268, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_272 + .saturating_add(Weight::from_parts(97_602, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + /// The range of component `x` is `[0, 100]`. + fn provide_judgement(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `445 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 22_825_000 picoseconds. + Weight::from_parts(21_046_708, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 5_012 + .saturating_add(Weight::from_parts(180_118, 0).saturating_mul(r.into())) + // Standard Error: 927 + .saturating_add(Weight::from_parts(788_617, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `s` is `[0, 100]`. + /// The range of component `x` is `[0, 100]`. + fn kill_identity(r: u32, s: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `676 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 75_635_000 picoseconds. + Weight::from_parts(47_274_783, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 11_632 + .saturating_add(Weight::from_parts(230_554, 0).saturating_mul(r.into())) + // Standard Error: 2_271 + .saturating_add(Weight::from_parts(1_333_461, 0).saturating_mul(s.into())) + // Standard Error: 2_271 + .saturating_add(Weight::from_parts(276_612, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 99]`. + fn add_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `475 + s * (36 ±0)` + // Estimated: `11003` + // Minimum execution time: 29_374_000 picoseconds. + Weight::from_parts(33_426_262, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_171 + .saturating_add(Weight::from_parts(101_531, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 100]`. + fn rename_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `591 + s * (3 ±0)` + // Estimated: `11003` + // Minimum execution time: 12_449_000 picoseconds. + Weight::from_parts(13_803_167, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 492 + .saturating_add(Weight::from_parts(39_985, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 100]`. + fn remove_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `638 + s * (35 ±0)` + // Estimated: `11003` + // Minimum execution time: 32_962_000 picoseconds. + Weight::from_parts(35_538_881, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_052 + .saturating_add(Weight::from_parts(96_317, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 99]`. + fn quit_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `704 + s * (37 ±0)` + // Estimated: `6723` + // Minimum execution time: 25_233_000 picoseconds. + Weight::from_parts(27_271_178, 0) + .saturating_add(Weight::from_parts(0, 6723)) + // Standard Error: 897 + .saturating_add(Weight::from_parts(92_723, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_im_online.rs b/polkadot/runtime/polkadot/src/weights/pallet_im_online.rs new file mode 100644 index 0000000000000000000000000000000000000000..93264c0c6991ec04e723ae3da29eebd5130e7117 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_im_online.rs @@ -0,0 +1,77 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_im_online` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_im_online +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_im_online`. +pub struct WeightInfo(PhantomData); +impl pallet_im_online::WeightInfo for WeightInfo { + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session CurrentIndex (r:1 w:0) + /// Proof Skipped: Session CurrentIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ImOnline Keys (r:1 w:0) + /// Proof: ImOnline Keys (max_values: Some(1), max_size: Some(320002), added: 320497, mode: MaxEncodedLen) + /// Storage: ImOnline ReceivedHeartbeats (r:1 w:1) + /// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(25), added: 2500, mode: MaxEncodedLen) + /// Storage: ImOnline AuthoredBlocks (r:1 w:0) + /// Proof: ImOnline AuthoredBlocks (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// The range of component `k` is `[1, 1000]`. + fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `361 + k * (32 ±0)` + // Estimated: `321487 + k * (1761 ±0)` + // Minimum execution time: 83_488_000 picoseconds. + Weight::from_parts(99_862_268, 0) + .saturating_add(Weight::from_parts(0, 321487)) + // Standard Error: 567 + .saturating_add(Weight::from_parts(35_207, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 1761).saturating_mul(k.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_indices.rs b/polkadot/runtime/polkadot/src/weights/pallet_indices.rs new file mode 100644 index 0000000000000000000000000000000000000000..94f2285efc25e0d345b823277432f4235a7668cf --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_indices.rs @@ -0,0 +1,117 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_indices` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_indices +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_indices`. +pub struct WeightInfo(PhantomData); +impl pallet_indices::WeightInfo for WeightInfo { + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `142` + // Estimated: `3534` + // Minimum execution time: 24_795_000 picoseconds. + Weight::from_parts(25_532_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `341` + // Estimated: `3593` + // Minimum execution time: 35_879_000 picoseconds. + Weight::from_parts(36_559_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn free() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3534` + // Minimum execution time: 25_628_000 picoseconds. + Weight::from_parts(26_584_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `341` + // Estimated: `3593` + // Minimum execution time: 28_963_000 picoseconds. + Weight::from_parts(29_722_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn freeze() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3534` + // Minimum execution time: 27_596_000 picoseconds. + Weight::from_parts(28_182_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_membership.rs b/polkadot/runtime/polkadot/src/weights/pallet_membership.rs new file mode 100644 index 0000000000000000000000000000000000000000..a4e5ce4a7bbb8f6b05f2c3934820f1628174984b --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_membership.rs @@ -0,0 +1,207 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_membership` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_membership +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_membership`. +pub struct WeightInfo(PhantomData); +impl pallet_membership::WeightInfo for WeightInfo { + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 99]`. + fn add_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `174 + m * (64 ±0)` + // Estimated: `4687 + m * (64 ±0)` + // Minimum execution time: 17_443_000 picoseconds. + Weight::from_parts(18_272_399, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 376 + .saturating_add(Weight::from_parts(33_633, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[2, 100]`. + fn remove_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `278 + m * (64 ±0)` + // Estimated: `4687 + m * (64 ±0)` + // Minimum execution time: 19_826_000 picoseconds. + Weight::from_parts(20_859_732, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 667 + .saturating_add(Weight::from_parts(33_155, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[2, 100]`. + fn swap_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `278 + m * (64 ±0)` + // Estimated: `4687 + m * (64 ±0)` + // Minimum execution time: 20_151_000 picoseconds. + Weight::from_parts(20_774_114, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 447 + .saturating_add(Weight::from_parts(44_052, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn reset_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `278 + m * (64 ±0)` + // Estimated: `4687 + m * (64 ±0)` + // Minimum execution time: 19_846_000 picoseconds. + Weight::from_parts(20_903_563, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 865 + .saturating_add(Weight::from_parts(149_306, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn change_key(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `278 + m * (64 ±0)` + // Estimated: `4687 + m * (64 ±0)` + // Minimum execution time: 20_523_000 picoseconds. + Weight::from_parts(21_705_085, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 948 + .saturating_add(Weight::from_parts(44_568, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:0) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalMembership Prime (r:0 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn set_prime(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `32 + m * (32 ±0)` + // Estimated: `4687 + m * (32 ±0)` + // Minimum execution time: 8_032_000 picoseconds. + Weight::from_parts(8_386_682, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 190 + .saturating_add(Weight::from_parts(9_724, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Prime (r:0 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn clear_prime(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_061_000 picoseconds. + Weight::from_parts(3_304_217, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 80 + .saturating_add(Weight::from_parts(273, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_message_queue.rs b/polkadot/runtime/polkadot/src/weights/pallet_message_queue.rs new file mode 100644 index 0000000000000000000000000000000000000000..b0b9776b0114d95fc5cca0634c4ff7eaaa0ff1e6 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_message_queue.rs @@ -0,0 +1,199 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_message_queue` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_message_queue +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_message_queue`. +pub struct WeightInfo(PhantomData); +impl pallet_message_queue::WeightInfo for WeightInfo { + /// Storage: MessageQueue ServiceHead (r:1 w:0) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn ready_ring_knit() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `6050` + // Minimum execution time: 12_778_000 picoseconds. + Weight::from_parts(13_167_000, 0) + .saturating_add(Weight::from_parts(0, 6050)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + fn ready_ring_unknit() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `6050` + // Minimum execution time: 11_910_000 picoseconds. + Weight::from_parts(12_318_000, 0) + .saturating_add(Weight::from_parts(0, 6050)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn service_queue_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `42` + // Estimated: `3520` + // Minimum execution time: 5_070_000 picoseconds. + Weight::from_parts(5_266_000, 0) + .saturating_add(Weight::from_parts(0, 3520)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + fn service_page_base_completion() -> Weight { + // Proof Size summary in bytes: + // Measured: `115` + // Estimated: `69051` + // Minimum execution time: 6_812_000 picoseconds. + Weight::from_parts(7_085_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + fn service_page_base_no_completion() -> Weight { + // Proof Size summary in bytes: + // Measured: `115` + // Estimated: `69051` + // Minimum execution time: 7_136_000 picoseconds. + Weight::from_parts(7_392_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_page_item() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 92_069_000 picoseconds. + Weight::from_parts(92_769_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn bump_service_head() -> Weight { + // Proof Size summary in bytes: + // Measured: `149` + // Estimated: `3520` + // Minimum execution time: 7_443_000 picoseconds. + Weight::from_parts(7_670_000, 0) + .saturating_add(Weight::from_parts(0, 3520)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn reap_page() -> Weight { + // Proof Size summary in bytes: + // Measured: `66030` + // Estimated: `69051` + // Minimum execution time: 67_176_000 picoseconds. + Weight::from_parts(68_406_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn execute_overweight_page_removed() -> Weight { + // Proof Size summary in bytes: + // Measured: `66030` + // Estimated: `69051` + // Minimum execution time: 83_156_000 picoseconds. + Weight::from_parts(85_134_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn execute_overweight_page_updated() -> Weight { + // Proof Size summary in bytes: + // Measured: `66030` + // Estimated: `69051` + // Minimum execution time: 125_205_000 picoseconds. + Weight::from_parts(127_325_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_multisig.rs b/polkadot/runtime/polkadot/src/weights/pallet_multisig.rs new file mode 100644 index 0000000000000000000000000000000000000000..70df8a78d4f11b6605994a095daaeb842f89d304 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_multisig.rs @@ -0,0 +1,165 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_multisig` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_multisig +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_multisig`. +pub struct WeightInfo(PhantomData); +impl pallet_multisig::WeightInfo for WeightInfo { + /// The range of component `z` is `[0, 10000]`. + fn as_multi_threshold_1(z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_729_000 picoseconds. + Weight::from_parts(14_236_505, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(610, 0).saturating_mul(z.into())) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_create(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `267 + s * (2 ±0)` + // Estimated: `6811` + // Minimum execution time: 45_550_000 picoseconds. + Weight::from_parts(34_831_496, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 772 + .saturating_add(Weight::from_parts(120_012, 0).saturating_mul(s.into())) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_567, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[3, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_approve(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `286` + // Estimated: `6811` + // Minimum execution time: 29_794_000 picoseconds. + Weight::from_parts(20_091_975, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 775 + .saturating_add(Weight::from_parts(111_349, 0).saturating_mul(s.into())) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_553, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_complete(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `392 + s * (33 ±0)` + // Estimated: `6811` + // Minimum execution time: 51_181_000 picoseconds. + Weight::from_parts(38_235_268, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 973 + .saturating_add(Weight::from_parts(145_449, 0).saturating_mul(s.into())) + // Standard Error: 9 + .saturating_add(Weight::from_parts(1_618, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn approve_as_multi_create(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `267 + s * (2 ±0)` + // Estimated: `6811` + // Minimum execution time: 33_278_000 picoseconds. + Weight::from_parts(33_697_154, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 863 + .saturating_add(Weight::from_parts(122_174, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn approve_as_multi_approve(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `286` + // Estimated: `6811` + // Minimum execution time: 18_541_000 picoseconds. + Weight::from_parts(19_007_991, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 847 + .saturating_add(Weight::from_parts(106_382, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn cancel_as_multi(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `458 + s * (1 ±0)` + // Estimated: `6811` + // Minimum execution time: 34_373_000 picoseconds. + Weight::from_parts(35_062_021, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 770 + .saturating_add(Weight::from_parts(113_576, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_nomination_pools.rs b/polkadot/runtime/polkadot/src/weights/pallet_nomination_pools.rs new file mode 100644 index 0000000000000000000000000000000000000000..7273389a08055be1d61a617b9e19b1d19f34a11d --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_nomination_pools.rs @@ -0,0 +1,601 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_nomination_pools` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_nomination_pools +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_nomination_pools`. +pub struct WeightInfo(PhantomData); +impl pallet_nomination_pools::WeightInfo for WeightInfo { + /// Storage: NominationPools MinJoinBond (r:1 w:0) + /// Proof: NominationPools MinJoinBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembersPerPool (r:1 w:0) + /// Proof: NominationPools MaxPoolMembersPerPool (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembers (r:1 w:0) + /// Proof: NominationPools MaxPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn join() -> Weight { + // Proof Size summary in bytes: + // Measured: `3195` + // Estimated: `8877` + // Minimum execution time: 191_933_000 picoseconds. + Weight::from_parts(199_790_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(19)) + .saturating_add(T::DbWeight::get().writes(12)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn bond_extra_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `3205` + // Estimated: `8877` + // Minimum execution time: 189_630_000 picoseconds. + Weight::from_parts(195_241_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(12)) + } + /// Storage: NominationPools ClaimPermissions (r:1 w:0) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn bond_extra_other() -> Weight { + // Proof Size summary in bytes: + // Measured: `3152` + // Estimated: `8799` + // Minimum execution time: 220_371_000 picoseconds. + Weight::from_parts(224_963_000, 0) + .saturating_add(Weight::from_parts(0, 8799)) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(12)) + } + /// Storage: NominationPools ClaimPermissions (r:1 w:0) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn claim_payout() -> Weight { + // Proof Size summary in bytes: + // Measured: `1137` + // Estimated: `4182` + // Minimum execution time: 81_050_000 picoseconds. + Weight::from_parts(82_523_000, 0) + .saturating_add(Weight::from_parts(0, 4182)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: NominationPools SubPoolsStorage (r:1 w:1) + /// Proof: NominationPools SubPoolsStorage (max_values: None, max_size: Some(1197), added: 3672, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForSubPoolsStorage (r:1 w:1) + /// Proof: NominationPools CounterForSubPoolsStorage (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn unbond() -> Weight { + // Proof Size summary in bytes: + // Measured: `3475` + // Estimated: `8877` + // Minimum execution time: 174_402_000 picoseconds. + Weight::from_parts(180_701_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(20)) + .saturating_add(T::DbWeight::get().writes(13)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn pool_withdraw_unbonded(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1580` + // Estimated: `4764` + // Minimum execution time: 63_246_000 picoseconds. + Weight::from_parts(65_760_934, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_105 + .saturating_add(Weight::from_parts(61_621, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools SubPoolsStorage (r:1 w:1) + /// Proof: NominationPools SubPoolsStorage (max_values: None, max_size: Some(1197), added: 3672, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools ClaimPermissions (r:0 w:1) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_update(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2008` + // Estimated: `4764` + // Minimum execution time: 133_264_000 picoseconds. + Weight::from_parts(137_557_538, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_409 + .saturating_add(Weight::from_parts(71_667, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools SubPoolsStorage (r:1 w:1) + /// Proof: NominationPools SubPoolsStorage (max_values: None, max_size: Some(1197), added: 3672, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:0) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools ReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools ReversePoolIdLookup (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools CounterForReversePoolIdLookup (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForRewardPools (r:1 w:1) + /// Proof: NominationPools CounterForRewardPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForSubPoolsStorage (r:1 w:1) + /// Proof: NominationPools CounterForSubPoolsStorage (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools Metadata (r:1 w:1) + /// Proof: NominationPools Metadata (max_values: None, max_size: Some(270), added: 2745, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForBondedPools (r:1 w:1) + /// Proof: NominationPools CounterForBondedPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: NominationPools ClaimPermissions (r:0 w:1) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_kill(_s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2364` + // Estimated: `6196` + // Minimum execution time: 223_680_000 picoseconds. + Weight::from_parts(232_248_103, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(21)) + .saturating_add(T::DbWeight::get().writes(18)) + } + /// Storage: NominationPools LastPoolId (r:1 w:1) + /// Proof: NominationPools LastPoolId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MinCreateBond (r:1 w:0) + /// Proof: NominationPools MinCreateBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MinJoinBond (r:1 w:0) + /// Proof: NominationPools MinJoinBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPools (r:1 w:0) + /// Proof: NominationPools MaxPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForBondedPools (r:1 w:1) + /// Proof: NominationPools CounterForBondedPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembersPerPool (r:1 w:0) + /// Proof: NominationPools MaxPoolMembersPerPool (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembers (r:1 w:0) + /// Proof: NominationPools MaxPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForRewardPools (r:1 w:1) + /// Proof: NominationPools CounterForRewardPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools ReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools ReversePoolIdLookup (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools CounterForReversePoolIdLookup (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + fn create() -> Weight { + // Proof Size summary in bytes: + // Measured: `1188` + // Estimated: `6196` + // Minimum execution time: 195_007_000 picoseconds. + Weight::from_parts(199_781_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(22)) + .saturating_add(T::DbWeight::get().writes(15)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:1 w:0) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:17 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 16]`. + fn nominate(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1745` + // Estimated: `4556 + n * (2520 ±0)` + // Minimum execution time: 68_155_000 picoseconds. + Weight::from_parts(68_982_265, 0) + .saturating_add(Weight::from_parts(0, 4556)) + // Standard Error: 9_798 + .saturating_add(Weight::from_parts(1_483_835, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(Weight::from_parts(0, 2520).saturating_mul(n.into())) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + fn set_state() -> Weight { + // Proof Size summary in bytes: + // Measured: `1333` + // Estimated: `4556` + // Minimum execution time: 34_246_000 picoseconds. + Weight::from_parts(35_523_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools Metadata (r:1 w:1) + /// Proof: NominationPools Metadata (max_values: None, max_size: Some(270), added: 2745, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForMetadata (r:1 w:1) + /// Proof: NominationPools CounterForMetadata (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 256]`. + fn set_metadata(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `497` + // Estimated: `3735` + // Minimum execution time: 14_742_000 picoseconds. + Weight::from_parts(15_414_886, 0) + .saturating_add(Weight::from_parts(0, 3735)) + // Standard Error: 140 + .saturating_add(Weight::from_parts(1_641, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: NominationPools MinJoinBond (r:0 w:1) + /// Proof: NominationPools MinJoinBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembers (r:0 w:1) + /// Proof: NominationPools MaxPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembersPerPool (r:0 w:1) + /// Proof: NominationPools MaxPoolMembersPerPool (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MinCreateBond (r:0 w:1) + /// Proof: NominationPools MinCreateBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:0 w:1) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPools (r:0 w:1) + /// Proof: NominationPools MaxPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn set_configs() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_186_000 picoseconds. + Weight::from_parts(6_325_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + fn update_roles() -> Weight { + // Proof Size summary in bytes: + // Measured: `497` + // Estimated: `3685` + // Minimum execution time: 20_194_000 picoseconds. + Weight::from_parts(21_006_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn chill() -> Weight { + // Proof Size summary in bytes: + // Measured: `1908` + // Estimated: `4556` + // Minimum execution time: 66_180_000 picoseconds. + Weight::from_parts(68_446_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn set_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `736` + // Estimated: `3685` + // Minimum execution time: 32_843_000 picoseconds. + Weight::from_parts(33_862_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + fn set_commission_max() -> Weight { + // Proof Size summary in bytes: + // Measured: `537` + // Estimated: `3685` + // Minimum execution time: 19_565_000 picoseconds. + Weight::from_parts(20_103_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + fn set_commission_change_rate() -> Weight { + // Proof Size summary in bytes: + // Measured: `497` + // Estimated: `3685` + // Minimum execution time: 19_957_000 picoseconds. + Weight::from_parts(20_927_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools PoolMembers (r:1 w:0) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools ClaimPermissions (r:1 w:1) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + fn set_claim_permission() -> Weight { + // Proof Size summary in bytes: + // Measured: `508` + // Estimated: `4182` + // Minimum execution time: 15_092_000 picoseconds. + Weight::from_parts(15_507_000, 0) + .saturating_add(Weight::from_parts(0, 4182)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn claim_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `934` + // Estimated: `3685` + // Minimum execution time: 63_775_000 picoseconds. + Weight::from_parts(65_498_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_offences.rs b/polkadot/runtime/polkadot/src/weights/pallet_offences.rs new file mode 100644 index 0000000000000000000000000000000000000000..1233133dfa3916465ecc2e087558745ecd13910c --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_offences.rs @@ -0,0 +1,222 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_offences` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_offences +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_offences`. +pub struct WeightInfo(PhantomData); +impl pallet_offences::WeightInfo for WeightInfo { + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:100 w:100) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:100 w:100) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1700 w:1700) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:1700 w:1700) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:100 w:100) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:299 w:299) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:100 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking NominatorSlashInEra (r:1600 w:1600) + /// Proof: Staking NominatorSlashInEra (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[1, 100]`. + /// The range of component `o` is `[2, 100]`. + /// The range of component `n` is `[0, 16]`. + fn report_offence_im_online(_r: u32, o: u32, n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + n * (3454 ±0) + o * (1042 ±0)` + // Estimated: `88614 + n * (157019 ±1_888) + o * (26384 ±310)` + // Minimum execution time: 528_759_000 picoseconds. + Weight::from_parts(538_714_000, 0) + .saturating_add(Weight::from_parts(0, 88614)) + // Standard Error: 3_704_868 + .saturating_add(Weight::from_parts(378_188_057, 0).saturating_mul(o.into())) + // Standard Error: 22_512_446 + .saturating_add(Weight::from_parts(389_244_693, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(124)) + .saturating_add(T::DbWeight::get().reads((37_u64).saturating_mul(o.into()))) + .saturating_add(T::DbWeight::get().reads((187_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(117)) + .saturating_add(T::DbWeight::get().writes((36_u64).saturating_mul(o.into()))) + .saturating_add(T::DbWeight::get().writes((187_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 157019).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 26384).saturating_mul(o.into())) + } + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:1 w:1) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:1 w:1) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:17 w:17) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:17 w:17) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking NominatorSlashInEra (r:16 w:16) + /// Proof: Staking NominatorSlashInEra (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[0, 16]`. + fn report_offence_grandpa(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1709 + n * (66 ±0)` + // Estimated: `5520 + n * (2551 ±0)` + // Minimum execution time: 92_527_000 picoseconds. + Weight::from_parts(104_194_764, 0) + .saturating_add(Weight::from_parts(0, 5520)) + // Standard Error: 32_501 + .saturating_add(Weight::from_parts(11_219_757, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(19)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(13)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2551).saturating_mul(n.into())) + } + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:1 w:1) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:1 w:1) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:17 w:17) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:17 w:17) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking NominatorSlashInEra (r:16 w:16) + /// Proof: Staking NominatorSlashInEra (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[0, 16]`. + fn report_offence_babe(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1709 + n * (66 ±0)` + // Estimated: `5520 + n * (2551 ±0)` + // Minimum execution time: 93_431_000 picoseconds. + Weight::from_parts(104_636_499, 0) + .saturating_add(Weight::from_parts(0, 5520)) + // Standard Error: 31_475 + .saturating_add(Weight::from_parts(11_183_248, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(19)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(13)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2551).saturating_mul(n.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_preimage.rs b/polkadot/runtime/polkadot/src/weights/pallet_preimage.rs new file mode 100644 index 0000000000000000000000000000000000000000..91605e072f0930a9fc47acd0af3856b2128459fb --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_preimage.rs @@ -0,0 +1,218 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_preimage` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_preimage +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_preimage`. +pub struct WeightInfo(PhantomData); +impl pallet_preimage::WeightInfo for WeightInfo { + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `143` + // Estimated: `3556` + // Minimum execution time: 31_712_000 picoseconds. + Weight::from_parts(32_014_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 5 + .saturating_add(Weight::from_parts(2_433, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_requested_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3556` + // Minimum execution time: 16_935_000 picoseconds. + Weight::from_parts(17_306_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(2_448, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_no_deposit_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3556` + // Minimum execution time: 16_600_000 picoseconds. + Weight::from_parts(16_837_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(2_424, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unnote_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `289` + // Estimated: `3556` + // Minimum execution time: 50_349_000 picoseconds. + Weight::from_parts(55_322_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unnote_no_deposit_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 32_867_000 picoseconds. + Weight::from_parts(36_581_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `188` + // Estimated: `3556` + // Minimum execution time: 27_810_000 picoseconds. + Weight::from_parts(30_821_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_no_deposit_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 17_455_000 picoseconds. + Weight::from_parts(19_842_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_unnoted_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `42` + // Estimated: `3556` + // Minimum execution time: 19_593_000 picoseconds. + Weight::from_parts(22_947_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_requested_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3556` + // Minimum execution time: 11_066_000 picoseconds. + Weight::from_parts(12_720_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unrequest_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 28_739_000 picoseconds. + Weight::from_parts(31_484_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn unrequest_unnoted_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3556` + // Minimum execution time: 10_424_000 picoseconds. + Weight::from_parts(11_233_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn unrequest_multi_referenced_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3556` + // Minimum execution time: 11_087_000 picoseconds. + Weight::from_parts(12_055_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_proxy.rs b/polkadot/runtime/polkadot/src/weights/pallet_proxy.rs new file mode 100644 index 0000000000000000000000000000000000000000..662b610f86ba845a8df8b336d5258b6cf448c403 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_proxy.rs @@ -0,0 +1,222 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_proxy` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_proxy +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_proxy`. +pub struct WeightInfo(PhantomData); +impl pallet_proxy::WeightInfo for WeightInfo { + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 15_142_000 picoseconds. + Weight::from_parts(15_809_707, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 889 + .saturating_add(Weight::from_parts(29_639, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn proxy_announced(a: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `554 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `5698` + // Minimum execution time: 38_116_000 picoseconds. + Weight::from_parts(38_591_703, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 2_336 + .saturating_add(Weight::from_parts(169_558, 0).saturating_mul(a.into())) + // Standard Error: 2_414 + .saturating_add(Weight::from_parts(25_502, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn remove_announcement(a: u32, _p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + a * (68 ±0)` + // Estimated: `5698` + // Minimum execution time: 24_792_000 picoseconds. + Weight::from_parts(26_160_353, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 1_738 + .saturating_add(Weight::from_parts(157_640, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn reject_announcement(a: u32, _p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + a * (68 ±0)` + // Estimated: `5698` + // Minimum execution time: 24_905_000 picoseconds. + Weight::from_parts(26_368_411, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 1_895 + .saturating_add(Weight::from_parts(155_491, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn announce(a: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `486 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `5698` + // Minimum execution time: 34_820_000 picoseconds. + Weight::from_parts(35_236_824, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 1_574 + .saturating_add(Weight::from_parts(166_722, 0).saturating_mul(a.into())) + // Standard Error: 1_626 + .saturating_add(Weight::from_parts(25_405, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn add_proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 25_820_000 picoseconds. + Weight::from_parts(27_003_669, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 1_555 + .saturating_add(Weight::from_parts(65_038, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn remove_proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 26_328_000 picoseconds. + Weight::from_parts(27_336_521, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 1_703 + .saturating_add(Weight::from_parts(57_107, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn remove_proxies(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 23_016_000 picoseconds. + Weight::from_parts(23_867_116, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 1_227 + .saturating_add(Weight::from_parts(38_349, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn create_pure(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `239` + // Estimated: `4706` + // Minimum execution time: 27_525_000 picoseconds. + Weight::from_parts(28_670_720, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 1_869 + .saturating_add(Weight::from_parts(16_659, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 30]`. + fn kill_pure(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `264 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 23_877_000 picoseconds. + Weight::from_parts(24_530_683, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 1_569 + .saturating_add(Weight::from_parts(49_912, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_referenda.rs b/polkadot/runtime/polkadot/src/weights/pallet_referenda.rs new file mode 100644 index 0000000000000000000000000000000000000000..7f6fb0419c76b54ca933dea5baf457266eeaae41 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_referenda.rs @@ -0,0 +1,523 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_referenda` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_referenda +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_referenda`. +pub struct WeightInfo(PhantomData); +impl pallet_referenda::WeightInfo for WeightInfo { + /// Storage: Referenda ReferendumCount (r:1 w:1) + /// Proof: Referenda ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:0 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + fn submit() -> Weight { + // Proof Size summary in bytes: + // Measured: `291` + // Estimated: `42428` + // Minimum execution time: 40_432_000 picoseconds. + Weight::from_parts(41_423_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_preparing() -> Weight { + // Proof Size summary in bytes: + // Measured: `544` + // Estimated: `83866` + // Minimum execution time: 52_009_000 picoseconds. + Weight::from_parts(54_126_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `3331` + // Estimated: `42428` + // Minimum execution time: 69_077_000 picoseconds. + Weight::from_parts(71_533_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_not_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `3351` + // Estimated: `42428` + // Minimum execution time: 68_115_000 picoseconds. + Weight::from_parts(70_485_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_passing() -> Weight { + // Proof Size summary in bytes: + // Measured: `544` + // Estimated: `83866` + // Minimum execution time: 64_860_000 picoseconds. + Weight::from_parts(66_772_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn place_decision_deposit_failing() -> Weight { + // Proof Size summary in bytes: + // Measured: `544` + // Estimated: `83866` + // Minimum execution time: 63_403_000 picoseconds. + Weight::from_parts(64_420_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + fn refund_decision_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `384` + // Estimated: `4401` + // Minimum execution time: 31_560_000 picoseconds. + Weight::from_parts(32_111_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + fn refund_submission_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `374` + // Estimated: `4401` + // Minimum execution time: 31_536_000 picoseconds. + Weight::from_parts(32_118_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn cancel() -> Weight { + // Proof Size summary in bytes: + // Measured: `452` + // Estimated: `83866` + // Minimum execution time: 39_132_000 picoseconds. + Weight::from_parts(39_878_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:1 w:0) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + fn kill() -> Weight { + // Proof Size summary in bytes: + // Measured: `693` + // Estimated: `83866` + // Minimum execution time: 105_261_000 picoseconds. + Weight::from_parts(106_923_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda TrackQueue (r:1 w:0) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + fn one_fewer_deciding_queue_empty() -> Weight { + // Proof Size summary in bytes: + // Measured: `207` + // Estimated: `5477` + // Minimum execution time: 9_171_000 picoseconds. + Weight::from_parts(9_585_000, 0) + .saturating_add(Weight::from_parts(0, 5477)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn one_fewer_deciding_failing() -> Weight { + // Proof Size summary in bytes: + // Measured: `3221` + // Estimated: `42428` + // Minimum execution time: 49_135_000 picoseconds. + Weight::from_parts(50_860_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn one_fewer_deciding_passing() -> Weight { + // Proof Size summary in bytes: + // Measured: `3221` + // Estimated: `42428` + // Minimum execution time: 53_279_000 picoseconds. + Weight::from_parts(54_069_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + fn nudge_referendum_requeued_insertion() -> Weight { + // Proof Size summary in bytes: + // Measured: `3044` + // Estimated: `5477` + // Minimum execution time: 22_537_000 picoseconds. + Weight::from_parts(23_853_000, 0) + .saturating_add(Weight::from_parts(0, 5477)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + fn nudge_referendum_requeued_slide() -> Weight { + // Proof Size summary in bytes: + // Measured: `3044` + // Estimated: `5477` + // Minimum execution time: 22_686_000 picoseconds. + Weight::from_parts(23_947_000, 0) + .saturating_add(Weight::from_parts(0, 5477)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + fn nudge_referendum_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `3048` + // Estimated: `5477` + // Minimum execution time: 28_373_000 picoseconds. + Weight::from_parts(29_033_000, 0) + .saturating_add(Weight::from_parts(0, 5477)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + fn nudge_referendum_not_queued() -> Weight { + // Proof Size summary in bytes: + // Measured: `3068` + // Estimated: `5477` + // Minimum execution time: 28_137_000 picoseconds. + Weight::from_parts(28_716_000, 0) + .saturating_add(Weight::from_parts(0, 5477)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_no_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `404` + // Estimated: `42428` + // Minimum execution time: 25_880_000 picoseconds. + Weight::from_parts(26_405_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_preparing() -> Weight { + // Proof Size summary in bytes: + // Measured: `452` + // Estimated: `42428` + // Minimum execution time: 26_349_000 picoseconds. + Weight::from_parts(27_181_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + fn nudge_referendum_timed_out() -> Weight { + // Proof Size summary in bytes: + // Measured: `311` + // Estimated: `4401` + // Minimum execution time: 17_735_000 picoseconds. + Weight::from_parts(18_130_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_begin_deciding_failing() -> Weight { + // Proof Size summary in bytes: + // Measured: `452` + // Estimated: `42428` + // Minimum execution time: 36_244_000 picoseconds. + Weight::from_parts(37_174_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_begin_deciding_passing() -> Weight { + // Proof Size summary in bytes: + // Measured: `452` + // Estimated: `42428` + // Minimum execution time: 38_250_000 picoseconds. + Weight::from_parts(38_771_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_begin_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `505` + // Estimated: `42428` + // Minimum execution time: 31_177_000 picoseconds. + Weight::from_parts(31_886_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_end_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `488` + // Estimated: `42428` + // Minimum execution time: 31_826_000 picoseconds. + Weight::from_parts(32_664_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_continue_not_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `505` + // Estimated: `42428` + // Minimum execution time: 28_957_000 picoseconds. + Weight::from_parts(29_810_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_continue_confirming() -> Weight { + // Proof Size summary in bytes: + // Measured: `509` + // Estimated: `42428` + // Minimum execution time: 28_002_000 picoseconds. + Weight::from_parts(28_440_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + fn nudge_referendum_approved() -> Weight { + // Proof Size summary in bytes: + // Measured: `509` + // Estimated: `83866` + // Minimum execution time: 43_527_000 picoseconds. + Weight::from_parts(44_536_000, 0) + .saturating_add(Weight::from_parts(0, 83866)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + fn nudge_referendum_rejected() -> Weight { + // Proof Size summary in bytes: + // Measured: `505` + // Estimated: `42428` + // Minimum execution time: 31_767_000 picoseconds. + Weight::from_parts(32_407_000, 0) + .saturating_add(Weight::from_parts(0, 42428)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:0 w:1) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + fn set_some_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `455` + // Estimated: `4401` + // Minimum execution time: 21_013_000 picoseconds. + Weight::from_parts(21_503_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:1 w:1) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + fn clear_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `388` + // Estimated: `4401` + // Minimum execution time: 18_535_000 picoseconds. + Weight::from_parts(19_056_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_scheduler.rs b/polkadot/runtime/polkadot/src/weights/pallet_scheduler.rs new file mode 100644 index 0000000000000000000000000000000000000000..79ad62954ec66bea85994112976fa9966d991f7e --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_scheduler.rs @@ -0,0 +1,207 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_scheduler` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_scheduler +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_scheduler`. +pub struct WeightInfo(PhantomData); +impl pallet_scheduler::WeightInfo for WeightInfo { + /// Storage: Scheduler IncompleteSince (r:1 w:1) + /// Proof: Scheduler IncompleteSince (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn service_agendas_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `69` + // Estimated: `1489` + // Minimum execution time: 5_003_000 picoseconds. + Weight::from_parts(5_239_000, 0) + .saturating_add(Weight::from_parts(0, 1489)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 50]`. + fn service_agenda_base(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 4_577_000 picoseconds. + Weight::from_parts(7_388_958, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 1_944 + .saturating_add(Weight::from_parts(898_872, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_task_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_430_000 picoseconds. + Weight::from_parts(5_696_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Preimage PreimageFor (r:1 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: Measured) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// The range of component `s` is `[128, 4194304]`. + fn service_task_fetched(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `179 + s * (1 ±0)` + // Estimated: `3644 + s * (1 ±0)` + // Minimum execution time: 20_567_000 picoseconds. + Weight::from_parts(20_856_000, 0) + .saturating_add(Weight::from_parts(0, 3644)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_523, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(s.into())) + } + /// Storage: Scheduler Lookup (r:0 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + fn service_task_named() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_013_000 picoseconds. + Weight::from_parts(7_231_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_task_periodic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_486_000 picoseconds. + Weight::from_parts(5_656_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn execute_dispatch_signed() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_532_000 picoseconds. + Weight::from_parts(2_635_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn execute_dispatch_unsigned() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_502_000 picoseconds. + Weight::from_parts(2_615_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 49]`. + fn schedule(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 14_011_000 picoseconds. + Weight::from_parts(16_753_097, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 1_751 + .saturating_add(Weight::from_parts(908_905, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: Scheduler Lookup (r:0 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 50]`. + fn cancel(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 18_326_000 picoseconds. + Weight::from_parts(17_114_477, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 2_468 + .saturating_add(Weight::from_parts(1_642_647, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 49]`. + fn schedule_named(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `293 + s * (185 ±0)` + // Estimated: `42428` + // Minimum execution time: 16_885_000 picoseconds. + Weight::from_parts(20_432_099, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 2_865 + .saturating_add(Weight::from_parts(954_709, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 50]`. + fn cancel_named(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `319 + s * (185 ±0)` + // Estimated: `42428` + // Minimum execution time: 19_988_000 picoseconds. + Weight::from_parts(19_533_754, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 3_226 + .saturating_add(Weight::from_parts(1_671_811, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_session.rs b/polkadot/runtime/polkadot/src/weights/pallet_session.rs new file mode 100644 index 0000000000000000000000000000000000000000..53f470ef5340b10b9ef51dd3ed4696780112c86e --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_session.rs @@ -0,0 +1,85 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_session` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_session +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_session`. +pub struct WeightInfo(PhantomData); +impl pallet_session::WeightInfo for WeightInfo { + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Session NextKeys (r:1 w:1) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session KeyOwner (r:6 w:6) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) + fn set_keys() -> Weight { + // Proof Size summary in bytes: + // Measured: `1920` + // Estimated: `17760` + // Minimum execution time: 59_408_000 picoseconds. + Weight::from_parts(60_600_000, 0) + .saturating_add(Weight::from_parts(0, 17760)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Session NextKeys (r:1 w:1) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session KeyOwner (r:0 w:6) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) + fn purge_keys() -> Weight { + // Proof Size summary in bytes: + // Measured: `1784` + // Estimated: `5249` + // Minimum execution time: 42_078_000 picoseconds. + Weight::from_parts(43_200_000, 0) + .saturating_add(Weight::from_parts(0, 5249)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(7)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_staking.rs b/polkadot/runtime/polkadot/src/weights/pallet_staking.rs new file mode 100644 index 0000000000000000000000000000000000000000..80a60467eda137aeda6ee08460537679af4b40f9 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_staking.rs @@ -0,0 +1,796 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_staking` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_staking +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_staking`. +pub struct WeightInfo(PhantomData); +impl pallet_staking::WeightInfo for WeightInfo { + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + fn bond() -> Weight { + // Proof Size summary in bytes: + // Measured: `980` + // Estimated: `4764` + // Minimum execution time: 52_344_000 picoseconds. + Weight::from_parts(53_469_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn bond_extra() -> Weight { + // Proof Size summary in bytes: + // Measured: `1925` + // Estimated: `8877` + // Minimum execution time: 96_497_000 picoseconds. + Weight::from_parts(98_479_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn unbond() -> Weight { + // Proof Size summary in bytes: + // Measured: `2132` + // Estimated: `8877` + // Minimum execution time: 98_872_000 picoseconds. + Weight::from_parts(101_630_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_update(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `947` + // Estimated: `4764` + // Minimum execution time: 42_427_000 picoseconds. + Weight::from_parts(44_370_898, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_286 + .saturating_add(Weight::from_parts(49_383, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Staking SpanSlash (r:0 w:100) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_kill(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2185 + s * (4 ±0)` + // Estimated: `6248 + s * (4 ±0)` + // Minimum execution time: 95_067_000 picoseconds. + Weight::from_parts(101_507_625, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 3_419 + .saturating_add(Weight::from_parts(1_387_390, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(13)) + .saturating_add(T::DbWeight::get().writes(11)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking MinValidatorBond (r:1 w:0) + /// Proof: Staking MinValidatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking MinCommission (r:1 w:0) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking MaxValidatorsCount (r:1 w:0) + /// Proof: Staking MaxValidatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn validate() -> Weight { + // Proof Size summary in bytes: + // Measured: `1309` + // Estimated: `4556` + // Minimum execution time: 58_106_000 picoseconds. + Weight::from_parts(59_755_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:128 w:128) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// The range of component `k` is `[1, 128]`. + fn kick(k: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1214 + k * (569 ±0)` + // Estimated: `4556 + k * (3033 ±0)` + // Minimum execution time: 30_053_000 picoseconds. + Weight::from_parts(30_456_129, 0) + .saturating_add(Weight::from_parts(0, 4556)) + // Standard Error: 8_026 + .saturating_add(Weight::from_parts(9_197_360, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) + .saturating_add(Weight::from_parts(0, 3033).saturating_mul(k.into())) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:1 w:0) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:17 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 16]`. + fn nominate(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1805 + n * (102 ±0)` + // Estimated: `6248 + n * (2520 ±0)` + // Minimum execution time: 68_438_000 picoseconds. + Weight::from_parts(65_922_031, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 13_125 + .saturating_add(Weight::from_parts(4_057_833, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(Weight::from_parts(0, 2520).saturating_mul(n.into())) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn chill() -> Weight { + // Proof Size summary in bytes: + // Measured: `1639` + // Estimated: `6248` + // Minimum execution time: 61_082_000 picoseconds. + Weight::from_parts(62_694_000, 0) + .saturating_add(Weight::from_parts(0, 6248)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + fn set_payee() -> Weight { + // Proof Size summary in bytes: + // Measured: `737` + // Estimated: `4556` + // Minimum execution time: 14_638_000 picoseconds. + Weight::from_parts(15_251_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:2 w:2) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + fn set_controller() -> Weight { + // Proof Size summary in bytes: + // Measured: `836` + // Estimated: `8122` + // Minimum execution time: 21_077_000 picoseconds. + Weight::from_parts(21_635_000, 0) + .saturating_add(Weight::from_parts(0, 8122)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Staking ValidatorCount (r:0 w:1) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn set_validator_count() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_006_000 picoseconds. + Weight::from_parts(3_176_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking ForceEra (r:0 w:1) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + fn force_no_eras() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_462_000 picoseconds. + Weight::from_parts(9_740_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking ForceEra (r:0 w:1) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + fn force_new_era() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_279_000 picoseconds. + Weight::from_parts(9_662_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking ForceEra (r:0 w:1) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + fn force_new_era_always() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_346_000 picoseconds. + Weight::from_parts(9_708_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking Invulnerables (r:0 w:1) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[0, 1000]`. + fn set_invulnerables(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_120_000 picoseconds. + Weight::from_parts(3_442_453, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 40 + .saturating_add(Weight::from_parts(12_464, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:0 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Staking SpanSlash (r:0 w:100) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn force_unstake(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1911 + s * (4 ±0)` + // Estimated: `6248 + s * (4 ±0)` + // Minimum execution time: 86_885_000 picoseconds. + Weight::from_parts(92_726_876, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 2_614 + .saturating_add(Weight::from_parts(1_393_582, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(12)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) + } + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `s` is `[1, 1000]`. + fn cancel_deferred_slash(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `66572` + // Estimated: `70037` + // Minimum execution time: 131_927_000 picoseconds. + Weight::from_parts(933_717_768, 0) + .saturating_add(Weight::from_parts(0, 70037)) + // Standard Error: 57_864 + .saturating_add(Weight::from_parts(4_834_464, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasValidatorReward (r:1 w:0) + /// Proof: Staking ErasValidatorReward (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:513 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking ErasStakersClipped (r:1 w:0) + /// Proof Skipped: Staking ErasStakersClipped (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasRewardPoints (r:1 w:0) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasValidatorPrefs (r:1 w:0) + /// Proof: Staking ErasValidatorPrefs (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:513 w:0) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: System Account (r:513 w:513) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `n` is `[0, 512]`. + fn payout_stakers_dead_controller(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `34179 + n * (150 ±0)` + // Estimated: `32391 + n * (2603 ±0)` + // Minimum execution time: 118_319_000 picoseconds. + Weight::from_parts(150_596_293, 0) + .saturating_add(Weight::from_parts(0, 32391)) + // Standard Error: 18_978 + .saturating_add(Weight::from_parts(34_357_240, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(n.into())) + } + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasValidatorReward (r:1 w:0) + /// Proof: Staking ErasValidatorReward (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:513 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:513 w:513) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking ErasStakersClipped (r:1 w:0) + /// Proof Skipped: Staking ErasStakersClipped (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasRewardPoints (r:1 w:0) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasValidatorPrefs (r:1 w:0) + /// Proof: Staking ErasValidatorPrefs (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:513 w:0) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: System Account (r:513 w:513) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:513 w:513) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:513 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `n` is `[0, 512]`. + fn payout_stakers_alive_staked(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `58153 + n * (388 ±0)` + // Estimated: `53040 + n * (3774 ±0)` + // Minimum execution time: 140_238_000 picoseconds. + Weight::from_parts(80_637_879, 0) + .saturating_add(Weight::from_parts(0, 53040)) + // Standard Error: 53_109 + .saturating_add(Weight::from_parts(55_488_791, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(n.into())) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// The range of component `l` is `[1, 32]`. + fn rebond(l: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1926 + l * (5 ±0)` + // Estimated: `8877` + // Minimum execution time: 89_764_000 picoseconds. + Weight::from_parts(92_966_007, 0) + .saturating_add(Weight::from_parts(0, 8877)) + // Standard Error: 4_077 + .saturating_add(Weight::from_parts(44_963, 0).saturating_mul(l.into())) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Staking SpanSlash (r:0 w:100) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 100]`. + fn reap_stash(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2185 + s * (4 ±0)` + // Estimated: `6248 + s * (4 ±0)` + // Minimum execution time: 102_828_000 picoseconds. + Weight::from_parts(104_295_311, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 3_221 + .saturating_add(Weight::from_parts(1_380_506, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(11)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) + } + /// Storage: VoterList CounterForListNodes (r:1 w:0) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:178 w:0) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:110 w:0) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:110 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:11 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:110 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:110 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:0) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinimumValidatorCount (r:1 w:0) + /// Proof: Staking MinimumValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:1) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStakersClipped (r:0 w:10) + /// Proof Skipped: Staking ErasStakersClipped (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasValidatorPrefs (r:0 w:10) + /// Proof: Staking ErasValidatorPrefs (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + /// Storage: Staking ErasStakers (r:0 w:10) + /// Proof Skipped: Staking ErasStakers (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasTotalStake (r:0 w:1) + /// Proof: Staking ErasTotalStake (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:0 w:1) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking MinimumActiveStake (r:0 w:1) + /// Proof: Staking MinimumActiveStake (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// The range of component `v` is `[1, 10]`. + /// The range of component `n` is `[0, 100]`. + fn new_era(v: u32, n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + n * (716 ±0) + v * (3594 ±0)` + // Estimated: `456136 + n * (3566 ±3) + v * (3566 ±38)` + // Minimum execution time: 543_692_000 picoseconds. + Weight::from_parts(548_108_000, 0) + .saturating_add(Weight::from_parts(0, 456136)) + // Standard Error: 2_062_056 + .saturating_add(Weight::from_parts(64_901_773, 0).saturating_mul(v.into())) + // Standard Error: 205_472 + .saturating_add(Weight::from_parts(18_855_795, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(185)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(v.into())) + } + /// Storage: VoterList CounterForListNodes (r:1 w:0) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:178 w:0) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2000 w:0) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:2000 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1000 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:2000 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:2000 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// Storage: Staking MinimumActiveStake (r:0 w:1) + /// Proof: Staking MinimumActiveStake (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// The range of component `v` is `[500, 1000]`. + /// The range of component `n` is `[500, 1000]`. + fn get_npos_voters(v: u32, n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `3117 + n * (907 ±0) + v * (391 ±0)` + // Estimated: `456136 + n * (3566 ±0) + v * (3566 ±0)` + // Minimum execution time: 36_757_500_000 picoseconds. + Weight::from_parts(37_291_052_000, 0) + .saturating_add(Weight::from_parts(0, 456136)) + // Standard Error: 408_866 + .saturating_add(Weight::from_parts(5_324_689, 0).saturating_mul(v.into())) + // Standard Error: 408_866 + .saturating_add(Weight::from_parts(4_075_058, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(180)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(v.into())) + } + /// Storage: Staking CounterForValidators (r:1 w:0) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1001 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// The range of component `v` is `[500, 1000]`. + fn get_npos_targets(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `917 + v * (50 ±0)` + // Estimated: `3510 + v * (2520 ±0)` + // Minimum execution time: 2_558_883_000 picoseconds. + Weight::from_parts(85_901_228, 0) + .saturating_add(Weight::from_parts(0, 3510)) + // Standard Error: 7_392 + .saturating_add(Weight::from_parts(5_071_697, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) + } + /// Storage: Staking MinCommission (r:0 w:1) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinValidatorBond (r:0 w:1) + /// Proof: Staking MinValidatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking MaxValidatorsCount (r:0 w:1) + /// Proof: Staking MaxValidatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ChillThreshold (r:0 w:1) + /// Proof: Staking ChillThreshold (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:0 w:1) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:0 w:1) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + fn set_staking_configs_all_set() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_298_000 picoseconds. + Weight::from_parts(6_596_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking MinCommission (r:0 w:1) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinValidatorBond (r:0 w:1) + /// Proof: Staking MinValidatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking MaxValidatorsCount (r:0 w:1) + /// Proof: Staking MaxValidatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ChillThreshold (r:0 w:1) + /// Proof: Staking ChillThreshold (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:0 w:1) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:0 w:1) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + fn set_staking_configs_all_remove() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_901_000 picoseconds. + Weight::from_parts(6_092_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking ChillThreshold (r:1 w:0) + /// Proof: Staking ChillThreshold (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:1 w:0) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn chill_other() -> Weight { + // Proof Size summary in bytes: + // Measured: `1762` + // Estimated: `6248` + // Minimum execution time: 72_549_000 picoseconds. + Weight::from_parts(74_685_000, 0) + .saturating_add(Weight::from_parts(0, 6248)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking MinCommission (r:1 w:0) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + fn force_apply_min_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `627` + // Estimated: `3510` + // Minimum execution time: 13_882_000 picoseconds. + Weight::from_parts(14_453_000, 0) + .saturating_add(Weight::from_parts(0, 3510)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking MinCommission (r:0 w:1) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn set_min_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_998_000 picoseconds. + Weight::from_parts(3_175_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_timestamp.rs b/polkadot/runtime/polkadot/src/weights/pallet_timestamp.rs new file mode 100644 index 0000000000000000000000000000000000000000..27d92d609fd46687d269a0cf2660120b722252b7 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_timestamp.rs @@ -0,0 +1,75 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_timestamp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_timestamp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_timestamp`. +pub struct WeightInfo(PhantomData); +impl pallet_timestamp::WeightInfo for WeightInfo { + /// Storage: Timestamp Now (r:1 w:1) + /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + fn set() -> Weight { + // Proof Size summary in bytes: + // Measured: `345` + // Estimated: `1493` + // Minimum execution time: 10_314_000 picoseconds. + Weight::from_parts(10_644_000, 0) + .saturating_add(Weight::from_parts(0, 1493)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn on_finalize() -> Weight { + // Proof Size summary in bytes: + // Measured: `128` + // Estimated: `0` + // Minimum execution time: 4_852_000 picoseconds. + Weight::from_parts(5_026_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_tips.rs b/polkadot/runtime/polkadot/src/weights/pallet_tips.rs new file mode 100644 index 0000000000000000000000000000000000000000..62e08e017a877e7e9026590839c4e06981b20883 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_tips.rs @@ -0,0 +1,164 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_tips` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_tips +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_tips`. +pub struct WeightInfo(PhantomData); +impl pallet_tips::WeightInfo for WeightInfo { + /// Storage: Tips Reasons (r:1 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[0, 16384]`. + fn report_awesome(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3469` + // Minimum execution time: 28_332_000 picoseconds. + Weight::from_parts(29_229_064, 0) + .saturating_add(Weight::from_parts(0, 3469)) + // Standard Error: 20 + .saturating_add(Weight::from_parts(1_717, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + fn retract_tip() -> Weight { + // Proof Size summary in bytes: + // Measured: `221` + // Estimated: `3686` + // Minimum execution time: 28_421_000 picoseconds. + Weight::from_parts(29_235_000, 0) + .saturating_add(Weight::from_parts(0, 3686)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:1 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Tips (r:0 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[0, 16384]`. + /// The range of component `t` is `[1, 13]`. + fn tip_new(r: u32, t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `74 + t * (64 ±0)` + // Estimated: `3539 + t * (64 ±0)` + // Minimum execution time: 19_215_000 picoseconds. + Weight::from_parts(18_521_677, 0) + .saturating_add(Weight::from_parts(0, 3539)) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_600, 0).saturating_mul(r.into())) + // Standard Error: 5_637 + .saturating_add(Weight::from_parts(171_000, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(t.into())) + } + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// The range of component `t` is `[1, 13]`. + fn tip(t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `295 + t * (112 ±0)` + // Estimated: `3760 + t * (112 ±0)` + // Minimum execution time: 15_664_000 picoseconds. + Weight::from_parts(16_047_212, 0) + .saturating_add(Weight::from_parts(0, 3760)) + // Standard Error: 1_859 + .saturating_add(Weight::from_parts(133_685, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) + } + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// The range of component `t` is `[1, 13]`. + fn close_tip(t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `334 + t * (112 ±0)` + // Estimated: `3790 + t * (112 ±0)` + // Minimum execution time: 61_465_000 picoseconds. + Weight::from_parts(62_876_205, 0) + .saturating_add(Weight::from_parts(0, 3790)) + // Standard Error: 6_840 + .saturating_add(Weight::from_parts(133_654, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) + } + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// The range of component `t` is `[1, 13]`. + fn slash_tip(t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `269` + // Estimated: `3734` + // Minimum execution time: 14_539_000 picoseconds. + Weight::from_parts(15_138_065, 0) + .saturating_add(Weight::from_parts(0, 3734)) + // Standard Error: 1_577 + .saturating_add(Weight::from_parts(6_176, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_treasury.rs b/polkadot/runtime/polkadot/src/weights/pallet_treasury.rs new file mode 100644 index 0000000000000000000000000000000000000000..669bfdeb7cfd4f831d39ac11e8a90fc66d5c5d42 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_treasury.rs @@ -0,0 +1,154 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_treasury` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_treasury +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_treasury`. +pub struct WeightInfo(PhantomData); +impl pallet_treasury::WeightInfo for WeightInfo { + /// Storage: Treasury ProposalCount (r:1 w:1) + /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:0 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + fn spend() -> Weight { + // Proof Size summary in bytes: + // Measured: `6` + // Estimated: `1887` + // Minimum execution time: 14_843_000 picoseconds. + Weight::from_parts(15_346_000, 0) + .saturating_add(Weight::from_parts(0, 1887)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Treasury ProposalCount (r:1 w:1) + /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:0 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + fn propose_spend() -> Weight { + // Proof Size summary in bytes: + // Measured: `107` + // Estimated: `1489` + // Minimum execution time: 27_443_000 picoseconds. + Weight::from_parts(28_046_000, 0) + .saturating_add(Weight::from_parts(0, 1489)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Treasury Proposals (r:1 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn reject_proposal() -> Weight { + // Proof Size summary in bytes: + // Measured: `265` + // Estimated: `3593` + // Minimum execution time: 42_227_000 picoseconds. + Weight::from_parts(44_158_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Treasury Proposals (r:1 w:0) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 99]`. + fn approve_proposal(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `433 + p * (8 ±0)` + // Estimated: `3573` + // Minimum execution time: 9_538_000 picoseconds. + Weight::from_parts(11_238_300, 0) + .saturating_add(Weight::from_parts(0, 3573)) + // Standard Error: 1_300 + .saturating_add(Weight::from_parts(72_785, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + fn remove_approval() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `1887` + // Minimum execution time: 7_582_000 picoseconds. + Weight::from_parts(7_778_000, 0) + .saturating_add(Weight::from_parts(0, 1887)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Treasury Deactivated (r:1 w:1) + /// Proof: Treasury Deactivated (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:100 w:100) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:200 w:200) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 100]`. + fn on_initialize_proposals(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `251 + p * (251 ±0)` + // Estimated: `1887 + p * (5206 ±0)` + // Minimum execution time: 45_157_000 picoseconds. + Weight::from_parts(40_228_554, 0) + .saturating_add(Weight::from_parts(0, 1887)) + // Standard Error: 17_245 + .saturating_add(Weight::from_parts(43_213_942, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 5206).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_utility.rs b/polkadot/runtime/polkadot/src/weights/pallet_utility.rs new file mode 100644 index 0000000000000000000000000000000000000000..1315ad6f8c44787ba936d49474034889bb67d073 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_utility.rs @@ -0,0 +1,102 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_utility` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_utility +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_utility`. +pub struct WeightInfo(PhantomData); +impl pallet_utility::WeightInfo for WeightInfo { + /// The range of component `c` is `[0, 1000]`. + fn batch(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_489_000 picoseconds. + Weight::from_parts(13_259_019, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2_263 + .saturating_add(Weight::from_parts(5_239_842, 0).saturating_mul(c.into())) + } + fn as_derivative() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_128_000 picoseconds. + Weight::from_parts(5_402_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `c` is `[0, 1000]`. + fn batch_all(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_609_000 picoseconds. + Weight::from_parts(9_345_211, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2_018 + .saturating_add(Weight::from_parts(5_550_153, 0).saturating_mul(c.into())) + } + fn dispatch_as() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_803_000 picoseconds. + Weight::from_parts(9_123_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `c` is `[0, 1000]`. + fn force_batch(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_630_000 picoseconds. + Weight::from_parts(8_158_486, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1_533 + .saturating_add(Weight::from_parts(5_246_137, 0).saturating_mul(c.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_vesting.rs b/polkadot/runtime/polkadot/src/weights/pallet_vesting.rs new file mode 100644 index 0000000000000000000000000000000000000000..916ca4bf6b9c7cc4f90e26ea3b38a76b105d10ce --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_vesting.rs @@ -0,0 +1,241 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_vesting` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_vesting +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_vesting`. +pub struct WeightInfo(PhantomData); +impl pallet_vesting::WeightInfo for WeightInfo { + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `314 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 34_121_000 picoseconds. + Weight::from_parts(33_874_584, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_001 + .saturating_add(Weight::from_parts(43_368, 0).saturating_mul(l.into())) + // Standard Error: 3_560 + .saturating_add(Weight::from_parts(80_668, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `314 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 37_615_000 picoseconds. + Weight::from_parts(37_040_523, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_513 + .saturating_add(Weight::from_parts(44_043, 0).saturating_mul(l.into())) + // Standard Error: 2_692 + .saturating_add(Weight::from_parts(76_579, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `417 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 36_953_000 picoseconds. + Weight::from_parts(35_679_094, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_788 + .saturating_add(Weight::from_parts(55_569, 0).saturating_mul(l.into())) + // Standard Error: 3_182 + .saturating_add(Weight::from_parts(95_878, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `417 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 39_817_000 picoseconds. + Weight::from_parts(40_592_159, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_675 + .saturating_add(Weight::from_parts(34_692, 0).saturating_mul(l.into())) + // Standard Error: 4_760 + .saturating_add(Weight::from_parts(65_300, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `488 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 72_258_000 picoseconds. + Weight::from_parts(74_062_243, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 3_135 + .saturating_add(Weight::from_parts(50_768, 0).saturating_mul(l.into())) + // Standard Error: 5_578 + .saturating_add(Weight::from_parts(83_913, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn force_vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `591 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `6196` + // Minimum execution time: 75_260_000 picoseconds. + Weight::from_parts(75_838_762, 0) + .saturating_add(Weight::from_parts(0, 6196)) + // Standard Error: 2_742 + .saturating_add(Weight::from_parts(57_676, 0).saturating_mul(l.into())) + // Standard Error: 4_879 + .saturating_add(Weight::from_parts(106_745, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn not_unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `415 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 37_553_000 picoseconds. + Weight::from_parts(36_199_505, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_594 + .saturating_add(Weight::from_parts(60_107, 0).saturating_mul(l.into())) + // Standard Error: 2_945 + .saturating_add(Weight::from_parts(104_552, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `415 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 41_939_000 picoseconds. + Weight::from_parts(42_113_365, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_119 + .saturating_add(Weight::from_parts(44_822, 0).saturating_mul(l.into())) + // Standard Error: 3_914 + .saturating_add(Weight::from_parts(73_401, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_whitelist.rs b/polkadot/runtime/polkadot/src/weights/pallet_whitelist.rs new file mode 100644 index 0000000000000000000000000000000000000000..fd3831a3ef5943288496d87b38b73bcaed2332b9 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_whitelist.rs @@ -0,0 +1,118 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_whitelist` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_whitelist +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_whitelist`. +pub struct WeightInfo(PhantomData); +impl pallet_whitelist::WeightInfo for WeightInfo { + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn whitelist_call() -> Weight { + // Proof Size summary in bytes: + // Measured: `118` + // Estimated: `3556` + // Minimum execution time: 20_665_000 picoseconds. + Weight::from_parts(21_174_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn remove_whitelisted_call() -> Weight { + // Proof Size summary in bytes: + // Measured: `247` + // Estimated: `3556` + // Minimum execution time: 18_337_000 picoseconds. + Weight::from_parts(18_705_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:1 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: Measured) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 4194294]`. + fn dispatch_whitelisted_call(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `323 + n * (1 ±0)` + // Estimated: `3787 + n * (1 ±0)` + // Minimum execution time: 30_433_000 picoseconds. + Weight::from_parts(30_800_000, 0) + .saturating_add(Weight::from_parts(0, 3787)) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_558, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) + } + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 10000]`. + fn dispatch_whitelisted_call_with_preimage(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `247` + // Estimated: `3556` + // Minimum execution time: 22_062_000 picoseconds. + Weight::from_parts(22_797_644, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_493, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/pallet_xcm.rs b/polkadot/runtime/polkadot/src/weights/pallet_xcm.rs new file mode 100644 index 0000000000000000000000000000000000000000..abbd5b1f2b9624d99a7fdaa6ad3f2cbde84355bc --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/pallet_xcm.rs @@ -0,0 +1,284 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_xcm +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/var/lib/gitlab-runner/builds/zyw4fam_/0/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=polkadot-dev +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm`. +pub struct WeightInfo(PhantomData); +impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn send() -> Weight { + // Proof Size summary in bytes: + // Measured: `527` + // Estimated: `3992` + // Minimum execution time: 38_390_000 picoseconds. + Weight::from_parts(38_885_000, 0) + .saturating_add(Weight::from_parts(0, 3992)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(3)) + } + fn teleport_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 23_170_000 picoseconds. + Weight::from_parts(23_644_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn reserve_transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 22_672_000 picoseconds. + Weight::from_parts(23_138_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + fn execute() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: XcmPallet SupportedVersion (r:0 w:1) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + fn force_xcm_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_462_000 picoseconds. + Weight::from_parts(9_853_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn force_default_xcm_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_769_000 picoseconds. + Weight::from_parts(3_001_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: XcmPallet VersionNotifiers (r:1 w:1) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet QueryCounter (r:1 w:1) + /// Proof Skipped: XcmPallet QueryCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet Queries (r:0 w:1) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + fn force_subscribe_version_notify() -> Weight { + // Proof Size summary in bytes: + // Measured: `527` + // Estimated: `3992` + // Minimum execution time: 41_707_000 picoseconds. + Weight::from_parts(42_742_000, 0) + .saturating_add(Weight::from_parts(0, 3992)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: XcmPallet VersionNotifiers (r:1 w:1) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet Queries (r:0 w:1) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + fn force_unsubscribe_version_notify() -> Weight { + // Proof Size summary in bytes: + // Measured: `799` + // Estimated: `4264` + // Minimum execution time: 46_077_000 picoseconds. + Weight::from_parts(46_504_000, 0) + .saturating_add(Weight::from_parts(0, 4264)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: XcmPallet XcmExecutionSuspended (r:0 w:1) + /// Proof Skipped: XcmPallet XcmExecutionSuspended (max_values: Some(1), max_size: None, mode: Measured) + fn force_suspension() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_849_000 picoseconds. + Weight::from_parts(3_018_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: XcmPallet SupportedVersion (r:4 w:2) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + fn migrate_supported_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `229` + // Estimated: `11119` + // Minimum execution time: 17_729_000 picoseconds. + Weight::from_parts(18_210_000, 0) + .saturating_add(Weight::from_parts(0, 11119)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifiers (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + fn migrate_version_notifiers() -> Weight { + // Proof Size summary in bytes: + // Measured: `233` + // Estimated: `11123` + // Minimum execution time: 17_615_000 picoseconds. + Weight::from_parts(18_157_000, 0) + .saturating_add(Weight::from_parts(0, 11123)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:5 w:0) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn already_notified_target() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `13608` + // Minimum execution time: 19_112_000 picoseconds. + Weight::from_parts(19_512_000, 0) + .saturating_add(Weight::from_parts(0, 13608)) + .saturating_add(T::DbWeight::get().reads(5)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:2 w:1) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn notify_current_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `597` + // Estimated: `6537` + // Minimum execution time: 38_643_000 picoseconds. + Weight::from_parts(39_380_000, 0) + .saturating_add(Weight::from_parts(0, 6537)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:3 w:0) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn notify_target_migration_fail() -> Weight { + // Proof Size summary in bytes: + // Measured: `272` + // Estimated: `8687` + // Minimum execution time: 9_326_000 picoseconds. + Weight::from_parts(9_772_000, 0) + .saturating_add(Weight::from_parts(0, 8687)) + .saturating_add(T::DbWeight::get().reads(3)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn migrate_version_notify_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `240` + // Estimated: `11130` + // Minimum execution time: 18_184_000 picoseconds. + Weight::from_parts(18_487_000, 0) + .saturating_add(Weight::from_parts(0, 11130)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn migrate_and_notify_old_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `601` + // Estimated: `11491` + // Minimum execution time: 45_891_000 picoseconds. + Weight::from_parts(47_130_000, 0) + .saturating_add(Weight::from_parts(0, 11491)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(5)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_common_auctions.rs b/polkadot/runtime/polkadot/src/weights/runtime_common_auctions.rs new file mode 100644 index 0000000000000000000000000000000000000000..8fdac1990620c754b9c0d694aa5ed32987da4d2f --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_common_auctions.rs @@ -0,0 +1,143 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::auctions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::auctions +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/runtime_common_auctions.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::auctions`. +pub struct WeightInfo(PhantomData); +impl runtime_common::auctions::WeightInfo for WeightInfo { + /// Storage: Auctions AuctionInfo (r:1 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Auctions AuctionCounter (r:1 w:1) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn new_auction() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `1493` + // Minimum execution time: 13_598_000 picoseconds. + Weight::from_parts(14_292_000, 0) + .saturating_add(Weight::from_parts(0, 1493)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions Winning (r:1 w:1) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:2 w:2) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn bid() -> Weight { + // Proof Size summary in bytes: + // Measured: `661` + // Estimated: `6060` + // Minimum execution time: 93_532_000 picoseconds. + Weight::from_parts(99_534_000, 0) + .saturating_add(Weight::from_parts(0, 6060)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Auctions AuctionInfo (r:1 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe NextRandomness (r:1 w:0) + /// Proof: Babe NextRandomness (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: Babe EpochStart (r:1 w:0) + /// Proof: Babe EpochStart (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Auctions Winning (r:3600 w:3600) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:37 w:36) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:36 w:36) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Slots Leases (r:7 w:7) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + fn on_initialize() -> Weight { + // Proof Size summary in bytes: + // Measured: `6947699` + // Estimated: `15822990` + // Minimum execution time: 7_832_854_000 picoseconds. + Weight::from_parts(8_120_980_000, 0) + .saturating_add(Weight::from_parts(0, 15822990)) + .saturating_add(T::DbWeight::get().reads(3688)) + .saturating_add(T::DbWeight::get().writes(3683)) + } + /// Storage: Auctions ReservedAmounts (r:37 w:36) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:36 w:36) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Auctions Winning (r:3600 w:3600) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions AuctionInfo (r:0 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + fn cancel_auction() -> Weight { + // Proof Size summary in bytes: + // Measured: `177732` + // Estimated: `15822990` + // Minimum execution time: 6_046_611_000 picoseconds. + Weight::from_parts(6_137_707_000, 0) + .saturating_add(Weight::from_parts(0, 15822990)) + .saturating_add(T::DbWeight::get().reads(3673)) + .saturating_add(T::DbWeight::get().writes(3673)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_common_claims.rs b/polkadot/runtime/polkadot/src/weights/runtime_common_claims.rs new file mode 100644 index 0000000000000000000000000000000000000000..b16ed97bc3ba5e74fc66a41cc26ae3dbfe5f65b1 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_common_claims.rs @@ -0,0 +1,169 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::claims` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::claims +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/runtime_common_claims.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::claims`. +pub struct WeightInfo(PhantomData); +impl runtime_common::claims::WeightInfo for WeightInfo { + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + fn claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `586` + // Estimated: `4764` + // Minimum execution time: 192_126_000 picoseconds. + Weight::from_parts(210_300_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:0 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Claims (r:0 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:0 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + fn mint_claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `182` + // Estimated: `1667` + // Minimum execution time: 15_323_000 picoseconds. + Weight::from_parts(16_648_000, 0) + .saturating_add(Weight::from_parts(0, 1667)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + fn claim_attest() -> Weight { + // Proof Size summary in bytes: + // Measured: `586` + // Estimated: `4764` + // Minimum execution time: 198_285_000 picoseconds. + Weight::from_parts(211_990_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Claims Preclaims (r:1 w:1) + /// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + fn attest() -> Weight { + // Proof Size summary in bytes: + // Measured: `660` + // Estimated: `4764` + // Minimum execution time: 98_860_000 picoseconds. + Weight::from_parts(110_990_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Claims Claims (r:1 w:2) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:2) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:2) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Preclaims (r:1 w:1) + /// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured) + fn move_claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `406` + // Estimated: `3871` + // Minimum execution time: 27_962_000 picoseconds. + Weight::from_parts(30_903_000, 0) + .saturating_add(Weight::from_parts(0, 3871)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(7)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_common_crowdloan.rs b/polkadot/runtime/polkadot/src/weights/runtime_common_crowdloan.rs new file mode 100644 index 0000000000000000000000000000000000000000..f9b84ff2f3e241d3aced50c22c2a6580bfa9d8aa --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_common_crowdloan.rs @@ -0,0 +1,225 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::crowdloan` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::crowdloan +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/runtime_common_crowdloan.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::crowdloan`. +pub struct WeightInfo(PhantomData); +impl runtime_common::crowdloan::WeightInfo for WeightInfo { + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan NextFundIndex (r:1 w:1) + /// Proof Skipped: Crowdloan NextFundIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn create() -> Weight { + // Proof Size summary in bytes: + // Measured: `415` + // Estimated: `3880` + // Minimum execution time: 67_401_000 picoseconds. + Weight::from_parts(73_047_000, 0) + .saturating_add(Weight::from_parts(0, 3880)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Crowdloan EndingsCount (r:1 w:0) + /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + fn contribute() -> Weight { + // Proof Size summary in bytes: + // Measured: `463` + // Estimated: `3928` + // Minimum execution time: 158_577_000 picoseconds. + Weight::from_parts(163_468_000, 0) + .saturating_add(Weight::from_parts(0, 3928)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + /// Proof Skipped: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + fn withdraw() -> Weight { + // Proof Size summary in bytes: + // Measured: `690` + // Estimated: `6196` + // Minimum execution time: 86_038_000 picoseconds. + Weight::from_parts(93_214_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `k` is `[0, 1000]`. + fn refund(k: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `128 + k * (189 ±0)` + // Estimated: `141 + k * (189 ±0)` + // Minimum execution time: 63_322_000 picoseconds. + Weight::from_parts(65_003_000, 0) + .saturating_add(Weight::from_parts(0, 141)) + // Standard Error: 27_401 + .saturating_add(Weight::from_parts(45_003_555, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(k.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(k.into()))) + .saturating_add(Weight::from_parts(0, 189).saturating_mul(k.into())) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn dissolve() -> Weight { + // Proof Size summary in bytes: + // Measured: `515` + // Estimated: `6196` + // Minimum execution time: 49_151_000 picoseconds. + Weight::from_parts(55_069_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + fn edit() -> Weight { + // Proof Size summary in bytes: + // Measured: `235` + // Estimated: `3700` + // Minimum execution time: 26_691_000 picoseconds. + Weight::from_parts(28_891_000, 0) + .saturating_add(Weight::from_parts(0, 3700)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Crowdloan Funds (r:1 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + fn add_memo() -> Weight { + // Proof Size summary in bytes: + // Measured: `412` + // Estimated: `3877` + // Minimum execution time: 46_088_000 picoseconds. + Weight::from_parts(49_781_000, 0) + .saturating_add(Weight::from_parts(0, 3877)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Crowdloan Funds (r:1 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + fn poke() -> Weight { + // Proof Size summary in bytes: + // Measured: `239` + // Estimated: `3704` + // Minimum execution time: 25_350_000 picoseconds. + Weight::from_parts(29_241_000, 0) + .saturating_add(Weight::from_parts(0, 3704)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Crowdloan EndingsCount (r:1 w:1) + /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan Funds (r:100 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Paras ParaLifecycles (r:100 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:100 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions Winning (r:1 w:1) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:100 w:100) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:100 w:100) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `n` is `[2, 100]`. + fn on_initialize(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `130 + n * (356 ±0)` + // Estimated: `5385 + n * (2832 ±0)` + // Minimum execution time: 154_247_000 picoseconds. + Weight::from_parts(18_164_126, 0) + .saturating_add(Weight::from_parts(0, 5385)) + // Standard Error: 71_727 + .saturating_add(Weight::from_parts(72_599_775, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2832).saturating_mul(n.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_common_paras_registrar.rs b/polkadot/runtime/polkadot/src/weights/runtime_common_paras_registrar.rs new file mode 100644 index 0000000000000000000000000000000000000000..d176b83a648b84fc89a0e10dcc58fea1096d5cce --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_common_paras_registrar.rs @@ -0,0 +1,224 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::paras_registrar` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::paras_registrar +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/runtime_common_paras_registrar.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::paras_registrar`. +pub struct WeightInfo(PhantomData); +impl runtime_common::paras_registrar::WeightInfo for WeightInfo { + /// Storage: Registrar NextFreeParaId (r:1 w:1) + /// Proof Skipped: Registrar NextFreeParaId (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + fn reserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `70` + // Estimated: `3535` + // Minimum execution time: 30_388_000 picoseconds. + Weight::from_parts(30_995_000, 0) + .saturating_add(Weight::from_parts(0, 3535)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:0 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpcomingParasGenesis (r:0 w:1) + /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) + fn register() -> Weight { + // Proof Size summary in bytes: + // Measured: `645` + // Estimated: `4110` + // Minimum execution time: 6_371_660_000 picoseconds. + Weight::from_parts(6_872_164_000, 0) + .saturating_add(Weight::from_parts(0, 4110)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:0 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpcomingParasGenesis (r:0 w:1) + /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) + fn force_register() -> Weight { + // Proof Size summary in bytes: + // Measured: `535` + // Estimated: `4000` + // Minimum execution time: 6_530_996_000 picoseconds. + Weight::from_parts(7_099_049_000, 0) + .saturating_add(Weight::from_parts(0, 4000)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeHash (r:1 w:0) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: Registrar PendingSwap (r:0 w:1) + /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) + fn deregister() -> Weight { + // Proof Size summary in bytes: + // Measured: `476` + // Estimated: `3941` + // Minimum execution time: 61_803_000 picoseconds. + Weight::from_parts(65_036_000, 0) + .saturating_add(Weight::from_parts(0, 3941)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Registrar Paras (r:1 w:0) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:2 w:2) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar PendingSwap (r:1 w:1) + /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan Funds (r:2 w:2) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:2 w:2) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + fn swap() -> Weight { + // Proof Size summary in bytes: + // Measured: `713` + // Estimated: `6653` + // Minimum execution time: 67_847_000 picoseconds. + Weight::from_parts(71_909_000, 0) + .saturating_add(Weight::from_parts(0, 6653)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Paras FutureCodeHash (r:1 w:1) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:1 w:1) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeCooldowns (r:1 w:1) + /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[1, 3145728]`. + fn schedule_code_upgrade(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `493` + // Estimated: `3958` + // Minimum execution time: 44_170_000 picoseconds. + Weight::from_parts(44_955_000, 0) + .saturating_add(Weight::from_parts(0, 3958)) + // Standard Error: 6 + .saturating_add(Weight::from_parts(2_501, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[1, 1048576]`. + fn set_current_head(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_735_000 picoseconds. + Weight::from_parts(8_851_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_044, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_common_slots.rs b/polkadot/runtime/polkadot/src/weights/runtime_common_slots.rs new file mode 100644 index 0000000000000000000000000000000000000000..7197c8721d8e43b1579dbeeda025008551e9e540 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_common_slots.rs @@ -0,0 +1,135 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::slots` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::slots +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/runtime_common_slots.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::slots`. +pub struct WeightInfo(PhantomData); +impl runtime_common::slots::WeightInfo for WeightInfo { + /// Storage: Slots Leases (r:1 w:1) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_lease() -> Weight { + // Proof Size summary in bytes: + // Measured: `220` + // Estimated: `3685` + // Minimum execution time: 30_634_000 picoseconds. + Weight::from_parts(31_305_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Slots Leases (r:101 w:100) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:200 w:200) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:100 w:100) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 100]`. + /// The range of component `t` is `[0, 100]`. + fn manage_lease_period_start(c: u32, t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `12 + c * (47 ±0) + t * (308 ±0)` + // Estimated: `2789 + c * (2526 ±0) + t * (2789 ±0)` + // Minimum execution time: 752_614_000 picoseconds. + Weight::from_parts(775_359_000, 0) + .saturating_add(Weight::from_parts(0, 2789)) + // Standard Error: 95_470 + .saturating_add(Weight::from_parts(3_269_112, 0).saturating_mul(c.into())) + // Standard Error: 95_470 + .saturating_add(Weight::from_parts(13_826_144, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(t.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(t.into()))) + .saturating_add(Weight::from_parts(0, 2526).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 2789).saturating_mul(t.into())) + } + /// Storage: Slots Leases (r:1 w:1) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:8 w:8) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn clear_all_leases() -> Weight { + // Proof Size summary in bytes: + // Measured: `2692` + // Estimated: `21814` + // Minimum execution time: 155_965_000 picoseconds. + Weight::from_parts(162_544_000, 0) + .saturating_add(Weight::from_parts(0, 21814)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(9)) + } + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + fn trigger_onboard() -> Weight { + // Proof Size summary in bytes: + // Measured: `617` + // Estimated: `4082` + // Minimum execution time: 34_811_000 picoseconds. + Weight::from_parts(39_327_000, 0) + .saturating_add(Weight::from_parts(0, 4082)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_parachains_configuration.rs b/polkadot/runtime/polkadot/src/weights/runtime_parachains_configuration.rs new file mode 100644 index 0000000000000000000000000000000000000000..39b0d893edbb54b20778afb3e4b6693f0855f168 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_parachains_configuration.rs @@ -0,0 +1,157 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::configuration` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-fljshgub-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("polkadot-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_parachains::configuration +// --chain=polkadot-dev +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::configuration`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::configuration::WeightInfo for WeightInfo { + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_block_number() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_330_000 picoseconds. + Weight::from_parts(9_663_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_u32() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_155_000 picoseconds. + Weight::from_parts(9_554_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_option_u32() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_299_000 picoseconds. + Weight::from_parts(9_663_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn set_hrmp_open_request_ttl() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_000_000_000_000 picoseconds. + Weight::from_parts(2_000_000_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_balance() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_130_000 picoseconds. + Weight::from_parts(9_554_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_executor_params() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 10_177_000 picoseconds. + Weight::from_parts(10_632_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_perbill() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_136_000 picoseconds. + Weight::from_parts(9_487_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_parachains_disputes.rs b/polkadot/runtime/polkadot/src/weights/runtime_parachains_disputes.rs new file mode 100644 index 0000000000000000000000000000000000000000..2746924dc87b9fc206279903ff310e9dbbf085c1 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_parachains_disputes.rs @@ -0,0 +1,64 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::disputes` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::disputes +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/runtime_parachains_disputes.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::disputes`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::disputes::WeightInfo for WeightInfo { + /// Storage: ParasDisputes Frozen (r:0 w:1) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + fn force_unfreeze() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_674_000 picoseconds. + Weight::from_parts(2_822_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_parachains_disputes_slashing.rs b/polkadot/runtime/polkadot/src/weights/runtime_parachains_disputes_slashing.rs new file mode 100644 index 0000000000000000000000000000000000000000..eda2f14214b11f68c8a08625a99e6a0cc562c194 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_parachains_disputes_slashing.rs @@ -0,0 +1,101 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::disputes::slashing` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::disputes::slashing +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/runtime_parachains_disputes_slashing.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::disputes::slashing`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::disputes::slashing::WeightInfo for WeightInfo { + /// Storage: Session CurrentIndex (r:1 w:0) + /// Proof Skipped: Session CurrentIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Historical HistoricalSessions (r:1 w:0) + /// Proof: Historical HistoricalSessions (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: ParasSlashing UnappliedSlashes (r:1 w:1) + /// Proof Skipped: ParasSlashing UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:1 w:1) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:1 w:1) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:1 w:1) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session DisabledValidators (r:1 w:1) + /// Proof Skipped: Session DisabledValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[4, 1000]`. + fn report_dispute_lost(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `5392 + n * (185 ±0)` + // Estimated: `8618 + n * (188 ±0)` + // Minimum execution time: 123_913_000 picoseconds. + Weight::from_parts(158_003_304, 0) + .saturating_add(Weight::from_parts(0, 8618)) + // Standard Error: 3_048 + .saturating_add(Weight::from_parts(361_664, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(17)) + .saturating_add(T::DbWeight::get().writes(10)) + .saturating_add(Weight::from_parts(0, 188).saturating_mul(n.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_parachains_hrmp.rs b/polkadot/runtime/polkadot/src/weights/runtime_parachains_hrmp.rs new file mode 100644 index 0000000000000000000000000000000000000000..82d8c30bacad485ba137614a3417547723f27bf3 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_parachains_hrmp.rs @@ -0,0 +1,295 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::hrmp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::hrmp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/runtime_parachains_hrmp.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::hrmp`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::hrmp::WeightInfo for WeightInfo { + /// Storage: Paras ParaLifecycles (r:2 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_init_open_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `666` + // Estimated: `6606` + // Minimum execution time: 41_092_000 picoseconds. + Weight::from_parts(43_188_000, 0) + .saturating_add(Weight::from_parts(0, 6606)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_accept_open_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `898` + // Estimated: `4363` + // Minimum execution time: 43_872_000 picoseconds. + Weight::from_parts(45_130_000, 0) + .saturating_add(Weight::from_parts(0, 4363)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_close_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `769` + // Estimated: `4234` + // Minimum execution time: 36_749_000 picoseconds. + Weight::from_parts(37_721_000, 0) + .saturating_add(Weight::from_parts(0, 4234)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:254 w:254) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:0 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelContents (r:0 w:254) + /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:0 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 127]`. + /// The range of component `e` is `[0, 127]`. + fn force_clean_hrmp(i: u32, e: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `197 + e * (100 ±0) + i * (100 ±0)` + // Estimated: `3659 + e * (2575 ±0) + i * (2575 ±0)` + // Minimum execution time: 1_241_128_000 picoseconds. + Weight::from_parts(1_249_625_000, 0) + .saturating_add(Weight::from_parts(0, 3659)) + // Standard Error: 114_117 + .saturating_add(Weight::from_parts(3_676_253, 0).saturating_mul(i.into())) + // Standard Error: 114_117 + .saturating_add(Weight::from_parts(3_657_525, 0).saturating_mul(e.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into()))) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(e.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(i.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(e.into()))) + .saturating_add(Weight::from_parts(0, 2575).saturating_mul(e.into())) + .saturating_add(Weight::from_parts(0, 2575).saturating_mul(i.into())) + } + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:256 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:128 w:128) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:0 w:128) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn force_process_hrmp_open(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `741 + c * (136 ±0)` + // Estimated: `2196 + c * (5086 ±0)` + // Minimum execution time: 10_559_000 picoseconds. + Weight::from_parts(7_421_722, 0) + .saturating_add(Weight::from_parts(0, 2196)) + // Standard Error: 17_031 + .saturating_add(Weight::from_parts(21_174_297, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((6_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 5086).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:128 w:128) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequests (r:0 w:128) + /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelContents (r:0 w:128) + /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn force_process_hrmp_close(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `268 + c * (124 ±0)` + // Estimated: `1728 + c * (2600 ±0)` + // Minimum execution time: 6_657_000 picoseconds. + Weight::from_parts(2_696_128, 0) + .saturating_add(Weight::from_parts(0, 1728)) + // Standard Error: 13_124 + .saturating_add(Weight::from_parts(13_190_422, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 2600).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn hrmp_cancel_open_request(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `959 + c * (13 ±0)` + // Estimated: `4228 + c * (15 ±0)` + // Minimum execution time: 22_102_000 picoseconds. + Weight::from_parts(29_549_361, 0) + .saturating_add(Weight::from_parts(0, 4228)) + // Standard Error: 2_209 + .saturating_add(Weight::from_parts(132_354, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 15).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn clean_open_channel_requests(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `176 + c * (63 ±0)` + // Estimated: `1655 + c * (2538 ±0)` + // Minimum execution time: 5_362_000 picoseconds. + Weight::from_parts(5_817_072, 0) + .saturating_add(Weight::from_parts(0, 1655)) + // Standard Error: 4_287 + .saturating_add(Weight::from_parts(3_550_045, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 2538).saturating_mul(c.into())) + } + /// Storage: Paras ParaLifecycles (r:2 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:2 w:2) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:2 w:2) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + fn force_open_hrmp_channel(_c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `666` + // Estimated: `6606` + // Minimum execution time: 56_136_000 picoseconds. + Weight::from_parts(57_227_000, 0) + .saturating_add(Weight::from_parts(0, 6606)) + .saturating_add(T::DbWeight::get().reads(14)) + .saturating_add(T::DbWeight::get().writes(8)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_parachains_inclusion.rs b/polkadot/runtime/polkadot/src/weights/runtime_parachains_inclusion.rs new file mode 100644 index 0000000000000000000000000000000000000000..c1e89a1ea9889828ae2d773f81484eb425a1e243 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_parachains_inclusion.rs @@ -0,0 +1,77 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::inclusion` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::inclusion +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/runtime_parachains_inclusion.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::inclusion`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::inclusion::WeightInfo for WeightInfo { + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:999) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65586), added: 68061, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// The range of component `i` is `[1, 1000]`. + fn receive_upward_messages(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `66077` + // Estimated: `69051` + // Minimum execution time: 124_710_000 picoseconds. + Weight::from_parts(126_824_000, 0) + .saturating_add(Weight::from_parts(0, 69051)) + // Standard Error: 127_283 + .saturating_add(Weight::from_parts(110_113_768, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_parachains_initializer.rs b/polkadot/runtime/polkadot/src/weights/runtime_parachains_initializer.rs new file mode 100644 index 0000000000000000000000000000000000000000..87e60aaeb24db96c1adf465524557769d60b5ebb --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_parachains_initializer.rs @@ -0,0 +1,69 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::initializer` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::initializer +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/runtime_parachains_initializer.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::initializer`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::initializer::WeightInfo for WeightInfo { + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `d` is `[0, 65536]`. + fn force_approve(d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + d * (11 ±0)` + // Estimated: `1480 + d * (11 ±0)` + // Minimum execution time: 3_619_000 picoseconds. + Weight::from_parts(3_743_000, 0) + .saturating_add(Weight::from_parts(0, 1480)) + // Standard Error: 17 + .saturating_add(Weight::from_parts(3_045, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 11).saturating_mul(d.into())) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_parachains_paras.rs b/polkadot/runtime/polkadot/src/weights/runtime_parachains_paras.rs new file mode 100644 index 0000000000000000000000000000000000000000..06f67211eade4180c956a7d5abc8c07b09395baf --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_parachains_paras.rs @@ -0,0 +1,297 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::paras` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=polkadot-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::paras +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/runtime_parachains_paras.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::paras`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::paras::WeightInfo for WeightInfo { + /// Storage: Paras CurrentCodeHash (r:1 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PastCodeMeta (r:1 w:1) + /// Proof Skipped: Paras PastCodeMeta (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PastCodePruning (r:1 w:1) + /// Proof Skipped: Paras PastCodePruning (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PastCodeHash (r:0 w:1) + /// Proof Skipped: Paras PastCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:0 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn force_set_current_code(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `8309` + // Estimated: `11774` + // Minimum execution time: 33_840_000 picoseconds. + Weight::from_parts(34_093_000, 0) + .saturating_add(Weight::from_parts(0, 11774)) + // Standard Error: 5 + .saturating_add(Weight::from_parts(2_436, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// The range of component `s` is `[1, 1048576]`. + fn force_set_current_head(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_922_000 picoseconds. + Weight::from_parts(8_254_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_040, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: Paras Heads (r:0 w:1) + fn force_set_most_recent_context() -> Weight { + Weight::from_parts(10_155_000, 0) + // Standard Error: 0 + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras FutureCodeHash (r:1 w:1) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeCooldowns (r:1 w:1) + /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn force_schedule_code_upgrade(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `8744` + // Estimated: `12209` + // Minimum execution time: 52_554_000 picoseconds. + Weight::from_parts(53_345_000, 0) + .saturating_add(Weight::from_parts(0, 12209)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(2_405, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `s` is `[1, 1048576]`. + fn force_note_new_head(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `95` + // Estimated: `3560` + // Minimum execution time: 14_465_000 picoseconds. + Weight::from_parts(20_861_569, 0) + .saturating_add(Weight::from_parts(0, 3560)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_002, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + fn force_queue_action() -> Weight { + // Proof Size summary in bytes: + // Measured: `4288` + // Estimated: `7753` + // Minimum execution time: 21_354_000 picoseconds. + Weight::from_parts(21_865_000, 0) + .saturating_add(Weight::from_parts(0, 7753)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn add_trusted_validation_code(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `975` + // Estimated: `4440` + // Minimum execution time: 102_448_000 picoseconds. + Weight::from_parts(101_036_531, 0) + .saturating_add(Weight::from_parts(0, 4440)) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_850, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Paras CodeByHashRefs (r:1 w:0) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:0 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + fn poke_unused_validation_code() -> Weight { + // Proof Size summary in bytes: + // Measured: `28` + // Estimated: `3493` + // Minimum execution time: 6_803_000 picoseconds. + Weight::from_parts(7_013_000, 0) + .saturating_add(Weight::from_parts(0, 3493)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement() -> Weight { + // Proof Size summary in bytes: + // Measured: `26682` + // Estimated: `30147` + // Minimum execution time: 121_645_000 picoseconds. + Weight::from_parts(125_576_000, 0) + .saturating_add(Weight::from_parts(0, 30147)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras UpcomingUpgrades (r:1 w:1) + /// Proof Skipped: Paras UpcomingUpgrades (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:0 w:100) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_upgrade_accept() -> Weight { + // Proof Size summary in bytes: + // Measured: `27552` + // Estimated: `31017` + // Minimum execution time: 956_753_000 picoseconds. + Weight::from_parts(978_268_000, 0) + .saturating_add(Weight::from_parts(0, 31017)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(104)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_upgrade_reject() -> Weight { + // Proof Size summary in bytes: + // Measured: `27214` + // Estimated: `30679` + // Minimum execution time: 112_500_000 picoseconds. + Weight::from_parts(120_090_000, 0) + .saturating_add(Weight::from_parts(0, 30679)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_onboarding_accept() -> Weight { + // Proof Size summary in bytes: + // Measured: `27020` + // Estimated: `30485` + // Minimum execution time: 760_189_000 picoseconds. + Weight::from_parts(776_400_000, 0) + .saturating_add(Weight::from_parts(0, 30485)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_onboarding_reject() -> Weight { + // Proof Size summary in bytes: + // Measured: `26682` + // Estimated: `30147` + // Minimum execution time: 113_010_000 picoseconds. + Weight::from_parts(118_335_000, 0) + .saturating_add(Weight::from_parts(0, 30147)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/runtime_parachains_paras_inherent.rs b/polkadot/runtime/polkadot/src/weights/runtime_parachains_paras_inherent.rs new file mode 100644 index 0000000000000000000000000000000000000000..70eb764305e4097ca02805a74b3d78aed98c7f78 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_parachains_paras_inherent.rs @@ -0,0 +1,353 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::paras_inherent` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-xerhrdyb-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_parachains::paras_inherent +// --chain=polkadot-dev +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::paras_inherent`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::paras_inherent::WeightInfo for WeightInfo { + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaSessionInfo Sessions (r:1 w:0) + /// Proof Skipped: ParaSessionInfo Sessions (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:1) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes BackersOnDisputes (r:1 w:1) + /// Proof Skipped: ParasDisputes BackersOnDisputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Included (r:1 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `v` is `[10, 200]`. + fn enter_variable_disputes(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `50915` + // Estimated: `56855 + v * (23 ±0)` + // Minimum execution time: 999_704_000 picoseconds. + Weight::from_parts(455_751_887, 0) + .saturating_add(Weight::from_parts(0, 56855)) + // Standard Error: 14_301 + .saturating_add(Weight::from_parts(57_084_663, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(28)) + .saturating_add(T::DbWeight::get().writes(15)) + .saturating_add(Weight::from_parts(0, 23).saturating_mul(v.into())) + } + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:0) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion AvailabilityBitfields (r:0 w:1) + /// Proof Skipped: ParaInclusion AvailabilityBitfields (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Included (r:0 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + fn enter_bitfields() -> Weight { + // Proof Size summary in bytes: + // Measured: `42748` + // Estimated: `48688` + // Minimum execution time: 485_153_000 picoseconds. + Weight::from_parts(504_774_000, 0) + .saturating_add(Weight::from_parts(0, 48688)) + .saturating_add(T::DbWeight::get().reads(26)) + .saturating_add(T::DbWeight::get().writes(16)) + } + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:0) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: ParasDisputes Included (r:0 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `v` is `[101, 200]`. + fn enter_backed_candidates_variable(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `42784` + // Estimated: `48724` + // Minimum execution time: 6_906_795_000 picoseconds. + Weight::from_parts(1_315_944_667, 0) + .saturating_add(Weight::from_parts(0, 48724)) + // Standard Error: 31_132 + .saturating_add(Weight::from_parts(55_792_755, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(29)) + .saturating_add(T::DbWeight::get().writes(15)) + } + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:0) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeHash (r:1 w:0) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:1 w:0) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: ParasDisputes Included (r:0 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + fn enter_backed_candidate_code_upgrade() -> Weight { + // Proof Size summary in bytes: + // Measured: `42811` + // Estimated: `48751` + // Minimum execution time: 44_487_810_000 picoseconds. + Weight::from_parts(46_317_208_000, 0) + .saturating_add(Weight::from_parts(0, 48751)) + .saturating_add(T::DbWeight::get().reads(31)) + .saturating_add(T::DbWeight::get().writes(15)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/xcm/mod.rs b/polkadot/runtime/polkadot/src/weights/xcm/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..acef102b446f13835e04fd66fc64e778f4b28a52 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/xcm/mod.rs @@ -0,0 +1,290 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +mod pallet_xcm_benchmarks_fungible; +mod pallet_xcm_benchmarks_generic; + +use crate::Runtime; +use frame_support::weights::Weight; +use sp_std::prelude::*; +use xcm::{latest::prelude::*, DoubleEncoded}; + +use pallet_xcm_benchmarks_fungible::WeightInfo as XcmBalancesWeight; +use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; + +/// Types of asset supported by the Polkadot runtime. +pub enum AssetTypes { + /// An asset backed by `pallet-balances`. + Balances, + /// Unknown asset. + Unknown, +} + +impl From<&MultiAsset> for AssetTypes { + fn from(asset: &MultiAsset) -> Self { + match asset { + MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), .. } => + AssetTypes::Balances, + _ => AssetTypes::Unknown, + } + } +} + +trait WeighMultiAssets { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight; +} + +// Polkadot only knows about one asset, the balances pallet. +const MAX_ASSETS: u64 = 1; + +impl WeighMultiAssets for MultiAssetFilter { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { + match self { + Self::Definite(assets) => assets + .inner() + .into_iter() + .map(From::from) + .map(|t| match t { + AssetTypes::Balances => balances_weight, + AssetTypes::Unknown => Weight::MAX, + }) + .fold(Weight::zero(), |acc, x| acc.saturating_add(x)), + // We don't support any NFTs on Polkadot, so these two variants will always match + // only 1 kind of fungible asset. + Self::Wild(AllOf { .. } | AllOfCounted { .. }) => balances_weight, + Self::Wild(AllCounted(count)) => + balances_weight.saturating_mul(MAX_ASSETS.min(*count as u64)), + Self::Wild(All) => balances_weight.saturating_mul(MAX_ASSETS), + } + } +} + +impl WeighMultiAssets for MultiAssets { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { + self.inner() + .into_iter() + .map(|m| >::from(m)) + .map(|t| match t { + AssetTypes::Balances => balances_weight, + AssetTypes::Unknown => Weight::MAX, + }) + .fold(Weight::zero(), |acc, x| acc.saturating_add(x)) + } +} + +pub struct PolkadotXcmWeight(core::marker::PhantomData); +impl XcmWeightInfo for PolkadotXcmWeight { + fn withdraw_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) + } + fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { + // Polkadot doesn't support ReserveAssetDeposited, so this benchmark has a default weight + assets.weigh_multi_assets(XcmBalancesWeight::::reserve_asset_deposited()) + } + fn receive_teleported_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) + } + fn query_response( + _query_id: &u64, + _response: &Response, + _max_weight: &Weight, + _querier: &Option, + ) -> Weight { + XcmGeneric::::query_response() + } + fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) + } + fn transfer_reserve_asset( + assets: &MultiAssets, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::transfer_reserve_asset()) + } + fn transact( + _origin_kind: &OriginKind, + _require_weight_at_most: &Weight, + _call: &DoubleEncoded, + ) -> Weight { + XcmGeneric::::transact() + } + fn hrmp_new_channel_open_request( + _sender: &u32, + _max_message_size: &u32, + _max_capacity: &u32, + ) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn hrmp_channel_accepted(_recipient: &u32) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn hrmp_channel_closing(_initiator: &u32, _sender: &u32, _recipient: &u32) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn clear_origin() -> Weight { + XcmGeneric::::clear_origin() + } + fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + XcmGeneric::::descend_origin() + } + fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::report_error() + } + + fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::deposit_asset()) + } + fn deposit_reserve_asset( + assets: &MultiAssetFilter, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::deposit_reserve_asset()) + } + fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + // Polkadot does not currently support exchange asset operations + Weight::MAX + } + fn initiate_reserve_withdraw( + assets: &MultiAssetFilter, + _reserve: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) + } + fn initiate_teleport( + assets: &MultiAssetFilter, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::initiate_teleport()) + } + fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + XcmGeneric::::report_holding() + } + fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + XcmGeneric::::buy_execution() + } + fn refund_surplus() -> Weight { + XcmGeneric::::refund_surplus() + } + fn set_error_handler(_xcm: &Xcm) -> Weight { + XcmGeneric::::set_error_handler() + } + fn set_appendix(_xcm: &Xcm) -> Weight { + XcmGeneric::::set_appendix() + } + fn clear_error() -> Weight { + XcmGeneric::::clear_error() + } + fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + XcmGeneric::::claim_asset() + } + fn trap(_code: &u64) -> Weight { + XcmGeneric::::trap() + } + fn subscribe_version(_query_id: &QueryId, _max_response_weight: &Weight) -> Weight { + XcmGeneric::::subscribe_version() + } + fn unsubscribe_version() -> Weight { + XcmGeneric::::unsubscribe_version() + } + fn burn_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + } + fn expect_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + } + fn expect_origin(_origin: &Option) -> Weight { + XcmGeneric::::expect_origin() + } + fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { + XcmGeneric::::expect_error() + } + fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight { + XcmGeneric::::expect_transact_status() + } + fn query_pallet(_module_name: &Vec, _response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::query_pallet() + } + fn expect_pallet( + _index: &u32, + _name: &Vec, + _module_name: &Vec, + _crate_major: &u32, + _min_crate_minor: &u32, + ) -> Weight { + XcmGeneric::::expect_pallet() + } + fn report_transact_status(_response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::report_transact_status() + } + fn clear_transact_status() -> Weight { + XcmGeneric::::clear_transact_status() + } + fn universal_origin(_: &Junction) -> Weight { + // Polkadot does not currently support universal origin operations + Weight::MAX + } + fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { + // Polkadot relay should not support export message operations + Weight::MAX + } + fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Polkadot does not currently support asset locking operations + Weight::MAX + } + fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Polkadot does not currently support asset locking operations + Weight::MAX + } + fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Polkadot does not currently support asset locking operations + Weight::MAX + } + fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Polkadot does not currently support asset locking operations + Weight::MAX + } + fn set_fees_mode(_: &bool) -> Weight { + XcmGeneric::::set_fees_mode() + } + fn set_topic(_topic: &[u8; 32]) -> Weight { + XcmGeneric::::set_topic() + } + fn clear_topic() -> Weight { + XcmGeneric::::clear_topic() + } + fn alias_origin(_: &MultiLocation) -> Weight { + // XCM Executor does not currently support alias origin operations + Weight::MAX + } + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + XcmGeneric::::unpaid_execution() + } +} + +#[test] +fn all_counted_has_a_sane_weight_upper_limit() { + let assets = MultiAssetFilter::Wild(AllCounted(4294967295)); + let weight = Weight::from_parts(1000, 1000); + + assert_eq!(assets.weigh_multi_assets(weight), weight * MAX_ASSETS); +} diff --git a/polkadot/runtime/polkadot/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs b/polkadot/runtime/polkadot/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs new file mode 100644 index 0000000000000000000000000000000000000000..038e9f17361b0637755662337b2139c2e1bcc10d --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs @@ -0,0 +1,208 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm_benchmarks::fungible` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-23, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-xerhrdyb-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_xcm_benchmarks::fungible +// --chain=polkadot-dev +// --header=./file_header.txt +// --template=./xcm/pallet-xcm-benchmarks/template.hbs +// --output=./runtime/polkadot/src/weights/xcm/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm_benchmarks::fungible`. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + pub(crate) fn withdraw_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `3593` + // Minimum execution time: 24_801_000 picoseconds. + Weight::from_parts(25_567_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + pub(crate) fn transfer_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `6196` + // Minimum execution time: 53_090_000 picoseconds. + Weight::from_parts(54_157_000, 6196) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn transfer_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `628` + // Estimated: `6196` + // Minimum execution time: 80_084_000 picoseconds. + Weight::from_parts(81_110_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn reserve_asset_deposited() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_000_000_000_000 picoseconds. + Weight::from_parts(2_000_000_000_000, 0) + } + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn initiate_reserve_withdraw() -> Weight { + // Proof Size summary in bytes: + // Measured: `527` + // Estimated: `3992` + // Minimum execution time: 32_535_000 picoseconds. + Weight::from_parts(33_276_000, 3992) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + pub(crate) fn receive_teleported_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `3593` + // Minimum execution time: 24_283_000 picoseconds. + Weight::from_parts(25_042_000, 3593) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + pub(crate) fn deposit_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 25_002_000 picoseconds. + Weight::from_parts(25_816_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn deposit_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `527` + // Estimated: `3992` + // Minimum execution time: 55_355_000 picoseconds. + Weight::from_parts(56_410_000, 3992) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn initiate_teleport() -> Weight { + // Proof Size summary in bytes: + // Measured: `527` + // Estimated: `3992` + // Minimum execution time: 57_258_000 picoseconds. + Weight::from_parts(58_205_000, 3992) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(5)) + } +} diff --git a/polkadot/runtime/polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs new file mode 100644 index 0000000000000000000000000000000000000000..0b61e7cd8d1f8ad45e19fd73ddda2edb629d93c6 --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -0,0 +1,327 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm_benchmarks::generic` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-04-14, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --pallet=pallet_xcm_benchmarks::generic +// --chain=polkadot-dev +// --header=./file_header.txt +// --template=./xcm/pallet-xcm-benchmarks/template.hbs +// --output=./runtime/polkadot/src/weights/xcm/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_xcm_benchmarks::generic`. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + // Storage: Configuration ActiveConfig (r:1 w:0) + // Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + // Storage: XcmPallet SupportedVersion (r:1 w:0) + // Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + // Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + // Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + // Storage: XcmPallet SafeXcmVersion (r:1 w:0) + // Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub fn report_holding() -> Weight { + // Proof Size summary in bytes: + // Measured: `514` + // Estimated: `17934` + // Minimum execution time: 33_813_000 picoseconds. + Weight::from_parts(34_357_000, 17934) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(3)) + } + pub fn buy_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_067_000 picoseconds. + Weight::from_parts(3_153_000, 0) + } + // Storage: XcmPallet Queries (r:1 w:0) + // Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + pub fn query_response() -> Weight { + // Proof Size summary in bytes: + // Measured: `169` + // Estimated: `3634` + // Minimum execution time: 12_236_000 picoseconds. + Weight::from_parts(12_725_000, 3634) + .saturating_add(T::DbWeight::get().reads(1)) + } + pub fn transact() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_193_000 picoseconds. + Weight::from_parts(13_427_000, 0) + } + pub fn refund_surplus() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_393_000 picoseconds. + Weight::from_parts(3_464_000, 0) + } + pub fn set_error_handler() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_955_000 picoseconds. + Weight::from_parts(3_068_000, 0) + } + pub fn set_appendix() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_004_000 picoseconds. + Weight::from_parts(3_107_000, 0) + } + pub fn clear_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_981_000 picoseconds. + Weight::from_parts(3_039_000, 0) + } + pub fn descend_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_814_000 picoseconds. + Weight::from_parts(3_897_000, 0) + } + pub fn clear_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_921_000 picoseconds. + Weight::from_parts(3_010_000, 0) + } + // Storage: Configuration ActiveConfig (r:1 w:0) + // Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + // Storage: XcmPallet SupportedVersion (r:1 w:0) + // Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + // Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + // Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + // Storage: XcmPallet SafeXcmVersion (r:1 w:0) + // Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub fn report_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `514` + // Estimated: `17934` + // Minimum execution time: 28_324_000 picoseconds. + Weight::from_parts(28_690_000, 17934) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(3)) + } + // Storage: XcmPallet AssetTraps (r:1 w:1) + // Proof Skipped: XcmPallet AssetTraps (max_values: None, max_size: None, mode: Measured) + pub fn claim_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `226` + // Estimated: `3691` + // Minimum execution time: 16_430_000 picoseconds. + Weight::from_parts(16_774_000, 3691) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub fn trap() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_916_000 picoseconds. + Weight::from_parts(3_035_000, 0) + } + // Storage: XcmPallet VersionNotifyTargets (r:1 w:1) + // Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + // Storage: XcmPallet SupportedVersion (r:1 w:0) + // Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + // Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + // Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + // Storage: XcmPallet SafeXcmVersion (r:1 w:0) + // Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub fn subscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `514` + // Estimated: `21913` + // Minimum execution time: 35_915_000 picoseconds. + Weight::from_parts(36_519_000, 21913) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: XcmPallet VersionNotifyTargets (r:0 w:1) + // Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + pub fn unsubscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_344_000 picoseconds. + Weight::from_parts(5_487_000, 0) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub fn burn_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_684_000 picoseconds. + Weight::from_parts(4_801_000, 0) + } + pub fn expect_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_228_000 picoseconds. + Weight::from_parts(3_325_000, 0) + } + pub fn expect_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_059_000 picoseconds. + Weight::from_parts(3_153_000, 0) + } + pub fn expect_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_037_000 picoseconds. + Weight::from_parts(3_128_000, 0) + } + pub fn expect_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_287_000 picoseconds. + Weight::from_parts(3_360_000, 0) + } + // Storage: Configuration ActiveConfig (r:1 w:0) + // Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + // Storage: XcmPallet SupportedVersion (r:1 w:0) + // Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + // Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + // Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + // Storage: XcmPallet SafeXcmVersion (r:1 w:0) + // Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub fn query_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `514` + // Estimated: `17934` + // Minimum execution time: 35_467_000 picoseconds. + Weight::from_parts(36_011_000, 17934) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(3)) + } + pub fn expect_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_630_000 picoseconds. + Weight::from_parts(8_870_000, 0) + } + // Storage: Configuration ActiveConfig (r:1 w:0) + // Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + // Storage: XcmPallet SupportedVersion (r:1 w:0) + // Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + // Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + // Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + // Storage: XcmPallet SafeXcmVersion (r:1 w:0) + // Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub fn report_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `514` + // Estimated: `17934` + // Minimum execution time: 28_630_000 picoseconds. + Weight::from_parts(29_085_000, 17934) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(3)) + } + pub fn clear_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_997_000 picoseconds. + Weight::from_parts(3_096_000, 0) + } + pub fn set_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_984_000 picoseconds. + Weight::from_parts(3_059_000, 0) + } + pub fn clear_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_969_000 picoseconds. + Weight::from_parts(3_006_000, 0) + } + pub fn set_fees_mode() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_045_000 picoseconds. + Weight::from_parts(3_087_000, 0) + } + pub fn unpaid_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_141_000 picoseconds. + Weight::from_parts(3_251_000, 0) + } +} diff --git a/polkadot/runtime/polkadot/src/xcm_config.rs b/polkadot/runtime/polkadot/src/xcm_config.rs new file mode 100644 index 0000000000000000000000000000000000000000..6c45f1cec402e83850d6b8d8ab3cccd31f6734f5 --- /dev/null +++ b/polkadot/runtime/polkadot/src/xcm_config.rs @@ -0,0 +1,431 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! XCM configuration for Polkadot. + +use super::{ + parachains_origin, AccountId, AllPalletsWithSystem, Balances, Dmp, FellowshipAdmin, + GeneralAdmin, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, + TransactionByteFee, WeightToFee, XcmPallet, +}; +use frame_support::{ + match_types, parameter_types, + traits::{Contains, Everything, Nothing}, + weights::Weight, +}; +use frame_system::EnsureRoot; +use pallet_xcm::XcmPassthrough; +use polkadot_runtime_constants::{ + currency::CENTS, system_parachain::*, xcm::body::FELLOWSHIP_ADMIN_INDEX, +}; +use runtime_common::{ + crowdloan, paras_registrar, + xcm_sender::{ChildParachainRouter, ExponentialPrice}, + ToAuthor, +}; +use sp_core::ConstU32; +use xcm::latest::prelude::*; +use xcm_builder::{ + AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, + AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative, + ChildParachainConvertsVia, CurrencyAdapter as XcmCurrencyAdapter, IsConcrete, MintLocation, + OriginToPluralityVoice, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, + WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, +}; +use xcm_executor::traits::WithOriginFilter; + +parameter_types! { + /// The location of the DOT token, from the context of this chain. Since this token is native to this + /// chain, we make it synonymous with it and thus it is the `Here` location, which means "equivalent to + /// the context". + pub const TokenLocation: MultiLocation = Here.into_location(); + /// The Polkadot network ID. This is named. + pub const ThisNetwork: NetworkId = NetworkId::Polkadot; + /// Our location in the universe of consensus systems. + pub const UniversalLocation: InteriorMultiLocation = X1(GlobalConsensus(ThisNetwork::get())); + /// The Checking Account, which holds any native assets that have been teleported out and not back in (yet). + pub CheckAccount: AccountId = XcmPallet::check_account(); + /// The Checking Account along with the indication that the local chain is able to mint tokens. + pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); +} + +/// The canonical means of converting a `MultiLocation` into an `AccountId`, used when we want to +/// determine the sovereign account controlled by a location. +pub type SovereignAccountOf = ( + // We can convert a child parachain using the standard `AccountId` conversion. + ChildParachainConvertsVia, + // We can directly alias an `AccountId32` into a local account. + AccountId32Aliases, +); + +/// Our asset transactor. This is what allows us to interact with the runtime assets from the point +/// of view of XCM-only concepts like `MultiLocation` and `MultiAsset`. +/// +/// Ours is only aware of the Balances pallet, which is mapped to `TokenLocation`. +pub type LocalAssetTransactor = XcmCurrencyAdapter< + // Use this currency: + Balances, + // Use this currency when it is a fungible asset matching the given location or name: + IsConcrete, + // We can convert the MultiLocations with our converter above: + SovereignAccountOf, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We track our teleports in/out to keep total issuance correct. + LocalCheckAccount, +>; + +/// The means that we convert an XCM origin `MultiLocation` into the runtime's `Origin` type for +/// local dispatch. This is a conversion function from an `OriginKind` type along with the +/// `MultiLocation` value and returns an `Origin` value or an error. +type LocalOriginConverter = ( + // If the origin kind is `Sovereign`, then return a `Signed` origin with the account determined + // by the `SovereignAccountOf` converter. + SovereignSignedViaLocation, + // If the origin kind is `Native` and the XCM origin is a child parachain, then we can express + // it with the special `parachains_origin::Origin` origin variant. + ChildParachainAsNative, + // If the origin kind is `Native` and the XCM origin is the `AccountId32` location, then it can + // be expressed using the `Signed` origin variant. + SignedAccountId32AsNative, + // Xcm origins can be represented natively under the Xcm pallet's Xcm origin. + XcmPassthrough, +); + +parameter_types! { + /// The amount of weight an XCM operation takes. This is a safe overestimate. + pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 1024); + /// Maximum number of instructions in a single XCM fragment. A sanity check against weight + /// calculations getting too crazy. + pub const MaxInstructions: u32 = 100; + /// The asset ID for the asset that we use to pay for message delivery fees. + pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); + /// The base fee for the message delivery fees. + pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); +} + +/// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our +/// individual routers. +pub type XcmRouter = WithUniqueTopic<( + // Only one router so far - use DMP to communicate with child parachains. + ChildParachainRouter< + Runtime, + XcmPallet, + ExponentialPrice, + >, +)>; + +parameter_types! { + pub const Dot: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); + pub const StatemintLocation: MultiLocation = Parachain(STATEMINT_ID).into_location(); + pub const DotForStatemint: (MultiAssetFilter, MultiLocation) = (Dot::get(), StatemintLocation::get()); + pub const CollectivesLocation: MultiLocation = Parachain(COLLECTIVES_ID).into_location(); + pub const DotForCollectives: (MultiAssetFilter, MultiLocation) = (Dot::get(), CollectivesLocation::get()); + pub const MaxAssetsIntoHolding: u32 = 64; +} + +/// Polkadot Relay recognizes/respects the Statemint chain as a teleporter. +pub type TrustedTeleporters = + (xcm_builder::Case, xcm_builder::Case); + +match_types! { + pub type OnlyParachains: impl Contains = { + MultiLocation { parents: 0, interior: X1(Parachain(_)) } + }; + pub type CollectivesOrFellows: impl Contains = { + MultiLocation { parents: 0, interior: X1(Parachain(COLLECTIVES_ID)) } | + MultiLocation { parents: 0, interior: X2(Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }) } + }; +} + +/// The barriers one of which must be passed for an XCM message to be executed. +pub type Barrier = TrailingSetTopicAsId<( + // Weight that is paid for may be consumed. + TakeWeightCredit, + // Expected responses are OK. + AllowKnownQueryResponses, + WithComputedOrigin< + ( + // If the message is one that immediately attemps to pay for execution, then allow it. + AllowTopLevelPaidExecutionFrom, + // Subscriptions for version tracking are OK. + AllowSubscriptionsFrom, + // Collectives and Fellows plurality get free execution. + AllowExplicitUnpaidExecutionFrom, + ), + UniversalLocation, + ConstU32<8>, + >, +)>; + +/// A call filter for the XCM Transact instruction. This is a temporary measure until we +/// properly account for proof size weights. +/// +/// Calls that are allowed through this filter must: +/// 1. Have a fixed weight; +/// 2. Cannot lead to another call being made; +/// 3. Have a defined proof size weight, e.g. no unbounded vecs in call parameters. +pub struct SafeCallFilter; +impl Contains for SafeCallFilter { + fn contains(call: &RuntimeCall) -> bool { + #[cfg(feature = "runtime-benchmarks")] + { + if matches!(call, RuntimeCall::System(frame_system::Call::remark_with_event { .. })) { + return true + } + } + + match call { + RuntimeCall::System( + frame_system::Call::kill_prefix { .. } | frame_system::Call::set_heap_pages { .. }, + ) | + RuntimeCall::Babe(..) | + RuntimeCall::Timestamp(..) | + RuntimeCall::Indices(..) | + RuntimeCall::Balances(..) | + RuntimeCall::Crowdloan( + crowdloan::Call::create { .. } | + crowdloan::Call::contribute { .. } | + crowdloan::Call::withdraw { .. } | + crowdloan::Call::refund { .. } | + crowdloan::Call::dissolve { .. } | + crowdloan::Call::edit { .. } | + crowdloan::Call::poke { .. } | + crowdloan::Call::contribute_all { .. }, + ) | + RuntimeCall::Staking( + pallet_staking::Call::bond { .. } | + pallet_staking::Call::bond_extra { .. } | + pallet_staking::Call::unbond { .. } | + pallet_staking::Call::withdraw_unbonded { .. } | + pallet_staking::Call::validate { .. } | + pallet_staking::Call::nominate { .. } | + pallet_staking::Call::chill { .. } | + pallet_staking::Call::set_payee { .. } | + pallet_staking::Call::set_controller { .. } | + pallet_staking::Call::set_validator_count { .. } | + pallet_staking::Call::increase_validator_count { .. } | + pallet_staking::Call::scale_validator_count { .. } | + pallet_staking::Call::force_no_eras { .. } | + pallet_staking::Call::force_new_era { .. } | + pallet_staking::Call::set_invulnerables { .. } | + pallet_staking::Call::force_unstake { .. } | + pallet_staking::Call::force_new_era_always { .. } | + pallet_staking::Call::payout_stakers { .. } | + pallet_staking::Call::rebond { .. } | + pallet_staking::Call::reap_stash { .. } | + pallet_staking::Call::set_staking_configs { .. } | + pallet_staking::Call::chill_other { .. } | + pallet_staking::Call::force_apply_min_commission { .. }, + ) | + RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) | + RuntimeCall::Grandpa(..) | + RuntimeCall::ImOnline(..) | + RuntimeCall::Treasury(..) | + RuntimeCall::ConvictionVoting(..) | + RuntimeCall::Referenda( + pallet_referenda::Call::place_decision_deposit { .. } | + pallet_referenda::Call::refund_decision_deposit { .. } | + pallet_referenda::Call::cancel { .. } | + pallet_referenda::Call::kill { .. } | + pallet_referenda::Call::nudge_referendum { .. } | + pallet_referenda::Call::one_fewer_deciding { .. }, + ) | + RuntimeCall::Claims( + super::claims::Call::claim { .. } | + super::claims::Call::mint_claim { .. } | + super::claims::Call::move_claim { .. }, + ) | + RuntimeCall::Utility(pallet_utility::Call::as_derivative { .. }) | + RuntimeCall::Identity( + pallet_identity::Call::add_registrar { .. } | + pallet_identity::Call::set_identity { .. } | + pallet_identity::Call::clear_identity { .. } | + pallet_identity::Call::request_judgement { .. } | + pallet_identity::Call::cancel_request { .. } | + pallet_identity::Call::set_fee { .. } | + pallet_identity::Call::set_account_id { .. } | + pallet_identity::Call::set_fields { .. } | + pallet_identity::Call::provide_judgement { .. } | + pallet_identity::Call::kill_identity { .. } | + pallet_identity::Call::add_sub { .. } | + pallet_identity::Call::rename_sub { .. } | + pallet_identity::Call::remove_sub { .. } | + pallet_identity::Call::quit_sub { .. }, + ) | + RuntimeCall::Vesting(..) | + RuntimeCall::Bounties( + pallet_bounties::Call::propose_bounty { .. } | + pallet_bounties::Call::approve_bounty { .. } | + pallet_bounties::Call::propose_curator { .. } | + pallet_bounties::Call::unassign_curator { .. } | + pallet_bounties::Call::accept_curator { .. } | + pallet_bounties::Call::award_bounty { .. } | + pallet_bounties::Call::claim_bounty { .. } | + pallet_bounties::Call::close_bounty { .. }, + ) | + RuntimeCall::ChildBounties(..) | + RuntimeCall::ElectionProviderMultiPhase(..) | + RuntimeCall::VoterList(..) | + RuntimeCall::NominationPools( + pallet_nomination_pools::Call::join { .. } | + pallet_nomination_pools::Call::bond_extra { .. } | + pallet_nomination_pools::Call::claim_payout { .. } | + pallet_nomination_pools::Call::unbond { .. } | + pallet_nomination_pools::Call::pool_withdraw_unbonded { .. } | + pallet_nomination_pools::Call::withdraw_unbonded { .. } | + pallet_nomination_pools::Call::create { .. } | + pallet_nomination_pools::Call::create_with_pool_id { .. } | + pallet_nomination_pools::Call::set_state { .. } | + pallet_nomination_pools::Call::set_configs { .. } | + pallet_nomination_pools::Call::update_roles { .. } | + pallet_nomination_pools::Call::chill { .. }, + ) | + RuntimeCall::Hrmp(..) | + RuntimeCall::Registrar( + paras_registrar::Call::deregister { .. } | + paras_registrar::Call::swap { .. } | + paras_registrar::Call::remove_lock { .. } | + paras_registrar::Call::reserve { .. } | + paras_registrar::Call::add_lock { .. }, + ) | + RuntimeCall::XcmPallet(pallet_xcm::Call::limited_reserve_transfer_assets { + .. + }) | + RuntimeCall::Whitelist(pallet_whitelist::Call::whitelist_call { .. }) | + RuntimeCall::Proxy(..) => true, + _ => false, + } + } +} + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = LocalOriginConverter; + // Polkadot Relay recognises no chains which act as reserves. + type IsReserve = (); + type IsTeleporter = TrustedTeleporters; + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = WeightInfoBounds< + crate::weights::xcm::PolkadotXcmWeight, + RuntimeCall, + MaxInstructions, + >; + // The weight trader piggybacks on the existing transaction-fee conversion logic. + type Trader = + UsingComponents>; + type ResponseHandler = XcmPallet; + type AssetTrap = XcmPallet; + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = XcmPallet; + type SubscriptionService = XcmPallet; + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + // No bridges yet... + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = WithOriginFilter; + type SafeCallFilter = SafeCallFilter; + type Aliasers = Nothing; +} + +parameter_types! { + // `GeneralAdmin` pluralistic body. + pub const GeneralAdminBodyId: BodyId = BodyId::Administration; + // StakingAdmin pluralistic body. + pub const StakingAdminBodyId: BodyId = BodyId::Defense; + // FellowshipAdmin pluralistic body. + pub const FellowshipAdminBodyId: BodyId = BodyId::Index(FELLOWSHIP_ADMIN_INDEX); +} + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parachain(1000).into()); +} + +/// Type to convert the `GeneralAdmin` origin to a Plurality `MultiLocation` value. +pub type GeneralAdminToPlurality = + OriginToPluralityVoice; + +/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior +/// location of this chain. +pub type LocalOriginToLocation = ( + GeneralAdminToPlurality, + // And a usual Signed origin to be used in XCM as a corresponding AccountId32 + SignedToAccountId32, +); + +/// Type to convert the `StakingAdmin` origin to a Plurality `MultiLocation` value. +pub type StakingAdminToPlurality = + OriginToPluralityVoice; + +/// Type to convert the `FellowshipAdmin` origin to a Plurality `MultiLocation` value. +pub type FellowshipAdminToPlurality = + OriginToPluralityVoice; + +/// Type to convert a pallet `Origin` type value into a `MultiLocation` value which represents an +/// interior location of this chain for a destination chain. +pub type LocalPalletOriginToLocation = ( + // GeneralAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + GeneralAdminToPlurality, + // StakingAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + StakingAdminToPlurality, + // FellowshipAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + FellowshipAdminToPlurality, +); + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + // We only allow the root, the general admin, the fellowship admin and the staking admin to send + // messages. + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = XcmRouter; + // Anyone can execute XCM messages locally... + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + // ...but they must match our filter, which rejects all. + type XcmExecuteFilter = Nothing; // == Deny All + type XcmExecutor = xcm_executor::XcmExecutor; + type XcmTeleportFilter = Everything; // == Allow All + type XcmReserveTransferFilter = Everything; // == Allow All + type Weigher = WeightInfoBounds< + crate::weights::xcm::PolkadotXcmWeight, + RuntimeCall, + MaxInstructions, + >; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = (); + type TrustedLockers = (); + type SovereignAccountOf = SovereignAccountOf; + type MaxLockers = ConstU32<8>; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = crate::weights::pallet_xcm::WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} diff --git a/polkadot/runtime/rococo/Cargo.toml b/polkadot/runtime/rococo/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..527bc1af9ccc5b5871827bdbc7fd2077d438baf0 --- /dev/null +++ b/polkadot/runtime/rococo/Cargo.toml @@ -0,0 +1,280 @@ +[package] +name = "rococo-runtime" +build = "build.rs" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +log = { version = "0.4.17", default-features = false } +serde = { version = "1.0.163", default-features = false } +serde_derive = { version = "1.0.117", optional = true } +static_assertions = "1.1.0" +smallvec = "1.8.0" + +authority-discovery-primitives = { package = "sp-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +beefy-primitives = { package = "sp-consensus-beefy", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +binary-merkle-tree = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +rococo-runtime-constants = { package = "rococo-runtime-constants", path = "./constants", default-features = false } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +offchain-primitives = { package = "sp-offchain", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +tx-pool-api = { package = "sp-transaction-pool", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +block-builder-api = { package = "sp-block-builder", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +pallet-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-beefy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-beefy-mmr = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-bounties = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-child-bounties = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-state-trie-migration = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-democracy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-elections-phragmen = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-executive = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-identity = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-im-online = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-indices = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-message-queue = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-mmr = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-multisig = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-nis = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-offences = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-preimage = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-proxy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-recovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-scheduler = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-society = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = ["experimental"] } +pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system = {git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-tips = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-xcm = { path = "../../xcm/pallet-xcm", default-features = false, features=["experimental"] } +pallet-xcm-benchmarks = { path = "../../xcm/pallet-xcm-benchmarks", default-features = false, optional = true } + +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +hex-literal = { version = "0.4.1" } + +runtime-common = { package = "polkadot-runtime-common", path = "../common", default-features = false, features=["experimental"] } +runtime-parachains = { package = "polkadot-runtime-parachains", path = "../parachains", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } +polkadot-parachain = { path = "../../parachain", default-features = false } + +xcm = { package = "xcm", path = "../../xcm", default-features = false } +xcm-executor = { package = "xcm-executor", path = "../../xcm/xcm-executor", default-features = false } +xcm-builder = { package = "xcm-builder", path = "../../xcm/xcm-builder", default-features = false } + +[dev-dependencies] +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "master" } +remote-externalities = { git = "https://github.com/paritytech/substrate", branch = "master", package = "frame-remote-externalities" } +sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } +separator = "0.4.1" +serde_json = "1.0.96" +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +tokio = { version = "1.24.2", features = ["macros"] } + +[build-dependencies] +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = ["std"] +no_std = [] +std = [ + "authority-discovery-primitives/std", + "primitives/std", + "parity-scale-codec/std", + "scale-info/std", + "inherents/std", + "sp-core/std", + "sp-api/std", + "tx-pool-api/std", + "block-builder-api/std", + "offchain-primitives/std", + "sp-std/std", + "sp-io/std", + "frame-support/std", + "frame-executive/std", + "pallet-authority-discovery/std", + "pallet-authorship/std", + "pallet-balances/std", + "pallet-beefy/std", + "pallet-beefy-mmr/std", + "pallet-bounties/std", + "pallet-child-bounties/std", + "pallet-state-trie-migration/std", + "pallet-transaction-payment/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-collective/std", + "pallet-elections-phragmen/std", + "pallet-democracy/std", + "pallet-nis/std", + "pallet-grandpa/std", + "pallet-identity/std", + "pallet-im-online/std", + "pallet-indices/std", + "pallet-membership/std", + "pallet-message-queue/std", + "pallet-mmr/std", + "pallet-multisig/std", + "pallet-offences/std", + "pallet-preimage/std", + "pallet-proxy/std", + "pallet-recovery/std", + "pallet-scheduler/std", + "pallet-session/std", + "pallet-society/std", + "pallet-sudo/std", + "pallet-staking/std", + "pallet-timestamp/std", + "pallet-tips/std", + "pallet-treasury/std", + "pallet-utility/std", + "pallet-vesting/std", + "pallet-babe/std", + "pallet-xcm/std", + "polkadot-parachain/std", + "sp-mmr-primitives/std", + "sp-runtime/std", + "sp-staking/std", + "frame-system/std", + "frame-system-rpc-runtime-api/std", + "sp-version/std", + "serde_derive", + "serde/std", + "log/std", + "babe-primitives/std", + "sp-session/std", + "runtime-common/std", + "runtime-parachains/std", + "frame-try-runtime/std", + "beefy-primitives/std", + "rococo-runtime-constants/std", + "xcm/std", + "xcm-executor/std", + "xcm-builder/std", +] +runtime-benchmarks = [ + "runtime-common/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "pallet-babe/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-bounties/runtime-benchmarks", + "pallet-child-bounties/runtime-benchmarks", + "pallet-collective/runtime-benchmarks", + "pallet-democracy/runtime-benchmarks", + "pallet-elections-phragmen/runtime-benchmarks", + "pallet-nis/runtime-benchmarks", + "pallet-grandpa/runtime-benchmarks", + "pallet-identity/runtime-benchmarks", + "pallet-im-online/runtime-benchmarks", + "pallet-indices/runtime-benchmarks", + "pallet-membership/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "pallet-multisig/runtime-benchmarks", + "pallet-preimage/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", + "pallet-society/runtime-benchmarks", + "pallet-recovery/runtime-benchmarks", + "pallet-staking/runtime-benchmarks", + "pallet-sudo/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-tips/runtime-benchmarks", + "pallet-treasury/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", + "pallet-vesting/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "frame-system-benchmarking/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + "runtime-parachains/runtime-benchmarks", + "pallet-xcm-benchmarks/runtime-benchmarks", +] +try-runtime = [ + "frame-executive/try-runtime", + "frame-try-runtime", + "frame-system/try-runtime", + "pallet-authority-discovery/try-runtime", + "pallet-authorship/try-runtime", + "pallet-balances/try-runtime", + "pallet-babe/try-runtime", + "pallet-beefy/try-runtime", + "pallet-beefy-mmr/try-runtime", + "pallet-bounties/try-runtime", + "pallet-child-bounties/try-runtime", + "pallet-transaction-payment/try-runtime", + "pallet-collective/try-runtime", + "pallet-elections-phragmen/try-runtime", + "pallet-democracy/try-runtime", + "pallet-grandpa/try-runtime", + "pallet-identity/try-runtime", + "pallet-im-online/try-runtime", + "pallet-indices/try-runtime", + "pallet-membership/try-runtime", + "pallet-message-queue/try-runtime", + "pallet-mmr/try-runtime", + "pallet-multisig/try-runtime", + "pallet-nis/try-runtime", + "pallet-offences/try-runtime", + "pallet-preimage/try-runtime", + "pallet-proxy/try-runtime", + "pallet-recovery/try-runtime", + "pallet-scheduler/try-runtime", + "pallet-session/try-runtime", + "pallet-society/try-runtime", + "pallet-sudo/try-runtime", + "pallet-staking/try-runtime", + "pallet-state-trie-migration/try-runtime", + "pallet-timestamp/try-runtime", + "pallet-tips/try-runtime", + "pallet-treasury/try-runtime", + "pallet-utility/try-runtime", + "pallet-vesting/try-runtime", + "pallet-xcm/try-runtime", + "runtime-common/try-runtime", + "runtime-parachains/try-runtime", +] +# When enabled, the runtime API will not be build. +# +# This is required by Cumulus to access certain types of the +# runtime without clashing with the runtime API exported functions +# in WASM. +disable-runtime-api = [] + +# Set timing constants (e.g. session period) to faster versions to speed up testing. +fast-runtime = [] + +runtime-metrics = ["runtime-parachains/runtime-metrics", "sp-io/with-tracing"] diff --git a/polkadot/runtime/rococo/README.md b/polkadot/runtime/rococo/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0f35665ca1726104a4d95b613894f99b05d476a5 --- /dev/null +++ b/polkadot/runtime/rococo/README.md @@ -0,0 +1,11 @@ +# Rococo: v2.1 + +Rococo is a testnet runtime with no stability guarantees. + +## How to run `rococo-local` + +The [Cumulus Tutorial](https://docs.substrate.io/tutorials/v3/cumulus/start-relay/) details building, starting, and testing `rococo-local` and parachains connecting to it. + +## How to register a parachain on the Rococo testnet + +The [parachain registration process](https://docs.substrate.io/tutorials/v3/cumulus/rococo/) on the public Rococo testnet is also outlined. diff --git a/polkadot/runtime/rococo/build.rs b/polkadot/runtime/rococo/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..e7134e0ef723eae59cbd65a79ad7dda47d958b52 --- /dev/null +++ b/polkadot/runtime/rococo/build.rs @@ -0,0 +1,25 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// 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_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .import_memory() + .export_heap_base() + .build() +} diff --git a/polkadot/runtime/rococo/constants/Cargo.toml b/polkadot/runtime/rococo/constants/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..e7bc81f199a1b4e776bcbc6c67ff2ea10728ace2 --- /dev/null +++ b/polkadot/runtime/rococo/constants/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "rococo-runtime-constants" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +smallvec = "1.8.0" + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../../primitives", default-features = false } +runtime-common = { package = "polkadot-runtime-common", path = "../../common", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-weights = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } + +[features] +default = ["std"] +std = [ + "frame-support/std", + "primitives/std", + "runtime-common/std", + "sp-core/std", + "sp-runtime/std", + "sp-weights/std" +] diff --git a/polkadot/runtime/rococo/constants/src/lib.rs b/polkadot/runtime/rococo/constants/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..214e2f3fa980e8793c2683c544cb69b2d0d8d00e --- /dev/null +++ b/polkadot/runtime/rococo/constants/src/lib.rs @@ -0,0 +1,130 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod weights; + +/// Money matters. +pub mod currency { + use primitives::Balance; + + /// The existential deposit. + pub const EXISTENTIAL_DEPOSIT: Balance = 1 * CENTS; + + pub const UNITS: Balance = 1_000_000_000_000; + pub const CENTS: Balance = UNITS / 30_000; + pub const GRAND: Balance = CENTS * 100_000; + pub const MILLICENTS: Balance = CENTS / 1_000; + + pub const fn deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 2_000 * CENTS + (bytes as Balance) * 100 * MILLICENTS + } +} + +/// Time and blocks. +pub mod time { + use primitives::{BlockNumber, Moment}; + use runtime_common::prod_or_fast; + pub const MILLISECS_PER_BLOCK: Moment = 6000; + pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; + pub const DEFAULT_EPOCH_DURATION: BlockNumber = prod_or_fast!(1 * HOURS, 1 * MINUTES); + frame_support::parameter_types! { + pub storage EpochDurationInBlocks: BlockNumber = DEFAULT_EPOCH_DURATION; + } + + // These time units are defined in number of blocks. + pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); + pub const HOURS: BlockNumber = MINUTES * 60; + pub const DAYS: BlockNumber = HOURS * 24; + pub const WEEKS: BlockNumber = DAYS * 7; + + // 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. + // The choice of is done in accordance to the slot duration and expected target + // block time, for safely resisting network delays of maximum two seconds. + // + pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); +} + +/// Fee-related. +pub mod fee { + use crate::weights::ExtrinsicBaseWeight; + use frame_support::weights::{ + WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, + }; + use primitives::Balance; + use smallvec::smallvec; + pub use sp_runtime::Perbill; + + /// The block saturation level. Fees will be updates based on this value. + pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); + + /// 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, `frame_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. + pub struct WeightToFee; + impl WeightToFeePolynomial for WeightToFee { + type Balance = Balance; + fn polynomial() -> WeightToFeeCoefficients { + // in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: + let p = super::currency::CENTS; + let q = 10 * Balance::from(ExtrinsicBaseWeight::get().ref_time()); + smallvec![WeightToFeeCoefficient { + degree: 1, + negative: false, + coeff_frac: Perbill::from_rational(p % q, q), + coeff_integer: p / q, + }] + } + } +} + +#[cfg(test)] +mod tests { + use super::{ + currency::{CENTS, MILLICENTS}, + fee::WeightToFee, + }; + use crate::weights::ExtrinsicBaseWeight; + use frame_support::weights::WeightToFee as WeightToFeeT; + use runtime_common::MAXIMUM_BLOCK_WEIGHT; + + #[test] + // Test that the fee for `MAXIMUM_BLOCK_WEIGHT` of weight has sane bounds. + fn full_block_fee_is_correct() { + // A full block should cost between 1,000 and 10,000 CENTS. + let full_block = WeightToFee::weight_to_fee(&MAXIMUM_BLOCK_WEIGHT); + assert!(full_block >= 1_000 * CENTS); + assert!(full_block <= 10_000 * CENTS); + } + + #[test] + // This function tests that the fee for `ExtrinsicBaseWeight` of weight is correct + fn extrinsic_base_fee_is_correct() { + // `ExtrinsicBaseWeight` should cost 1/10 of a CENT + println!("Base: {}", ExtrinsicBaseWeight::get()); + let x = WeightToFee::weight_to_fee(&ExtrinsicBaseWeight::get()); + let y = CENTS / 10; + assert!(x.max(y) - x.min(y) < MILLICENTS); + } +} diff --git a/polkadot/runtime/rococo/constants/src/weights/block_weights.rs b/polkadot/runtime/rococo/constants/src/weights/block_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..e2aa4a6cab7febc90418c3222819109e256a18c8 --- /dev/null +++ b/polkadot/runtime/rococo/constants/src/weights/block_weights.rs @@ -0,0 +1,81 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26 (Y/M/D) +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! +//! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Development` +//! WARMUPS: `10`, REPEAT: `100` +//! WEIGHT-PATH: `runtime/rococo/constants/src/weights/` +//! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` + +// Executed Command: +// ./target/production/polkadot +// benchmark +// overhead +// --chain=rococo-dev +// --execution=wasm +// --wasm-execution=compiled +// --weight-path=runtime/rococo/constants/src/weights/ +// --warmup=10 +// --repeat=100 +// --header=./file_header.txt + +use sp_core::parameter_types; +use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; + +parameter_types! { + /// Time to execute an empty block. + /// Calculated by multiplying the *Average* with `1.0` and adding `0`. + /// + /// Stats nanoseconds: + /// Min, Max: 408_659, 450_716 + /// Average: 417_412 + /// Median: 411_177 + /// Std-Dev: 12242.31 + /// + /// Percentiles nanoseconds: + /// 99th: 445_142 + /// 95th: 442_275 + /// 75th: 414_217 + pub const BlockExecutionWeight: Weight = + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(417_412), 0); +} + +#[cfg(test)] +mod test_weights { + use sp_weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::BlockExecutionWeight::get(); + + // At least 100 µs. + assert!( + w.ref_time() >= 100u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 100 µs." + ); + // At most 50 ms. + assert!( + w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 50 ms." + ); + } +} diff --git a/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs b/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..adce840ebbc120a4e7905ad6312b9d27b1e8d3fb --- /dev/null +++ b/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs @@ -0,0 +1,81 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26 (Y/M/D) +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! +//! SHORT-NAME: `extrinsic`, LONG-NAME: `ExtrinsicBase`, RUNTIME: `Development` +//! WARMUPS: `10`, REPEAT: `100` +//! WEIGHT-PATH: `runtime/rococo/constants/src/weights/` +//! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` + +// Executed Command: +// ./target/production/polkadot +// benchmark +// overhead +// --chain=rococo-dev +// --execution=wasm +// --wasm-execution=compiled +// --weight-path=runtime/rococo/constants/src/weights/ +// --warmup=10 +// --repeat=100 +// --header=./file_header.txt + +use sp_core::parameter_types; +use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; + +parameter_types! { + /// Time to execute a NO-OP extrinsic, for example `System::remark`. + /// Calculated by multiplying the *Average* with `1.0` and adding `0`. + /// + /// Stats nanoseconds: + /// Min, Max: 97_574, 100_119 + /// Average: 98_236 + /// Median: 98_179 + /// Std-Dev: 394.9 + /// + /// Percentiles nanoseconds: + /// 99th: 99_893 + /// 95th: 98_850 + /// 75th: 98_318 + pub const ExtrinsicBaseWeight: Weight = + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(98_236), 0); +} + +#[cfg(test)] +mod test_weights { + use sp_weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::ExtrinsicBaseWeight::get(); + + // At least 10 µs. + assert!( + w.ref_time() >= 10u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 10 µs." + ); + // At most 1 ms. + assert!( + w.ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 1 ms." + ); + } +} diff --git a/polkadot/runtime/rococo/constants/src/weights/mod.rs b/polkadot/runtime/rococo/constants/src/weights/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..23812ce7ed0528c394f84042fb9842eb617a834b --- /dev/null +++ b/polkadot/runtime/rococo/constants/src/weights/mod.rs @@ -0,0 +1,28 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Expose the auto generated weight files. + +pub mod block_weights; +pub mod extrinsic_weights; +pub mod paritydb_weights; +pub mod rocksdb_weights; + +pub use block_weights::BlockExecutionWeight; +pub use extrinsic_weights::ExtrinsicBaseWeight; +pub use paritydb_weights::constants::ParityDbWeight; +pub use rocksdb_weights::constants::RocksDbWeight; diff --git a/polkadot/runtime/rococo/constants/src/weights/paritydb_weights.rs b/polkadot/runtime/rococo/constants/src/weights/paritydb_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..25679703831a13b8d1bb7fb7dd4d92fa84b1f255 --- /dev/null +++ b/polkadot/runtime/rococo/constants/src/weights/paritydb_weights.rs @@ -0,0 +1,63 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// `ParityDB` can be enabled with a feature flag, but is still experimental. These weights + /// are available for brave runtime engineers who may want to try this out as default. + pub const ParityDbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 8_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + write: 50_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use super::constants::ParityDbWeight as W; + use frame_support::weights::constants; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/polkadot/runtime/rococo/constants/src/weights/rocksdb_weights.rs b/polkadot/runtime/rococo/constants/src/weights/rocksdb_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..3dd817aa6f137085b0e5fdf2b11b7f50e5c8b002 --- /dev/null +++ b/polkadot/runtime/rococo/constants/src/weights/rocksdb_weights.rs @@ -0,0 +1,63 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// By default, Substrate uses `RocksDB`, so this will be the weight used throughout + /// the runtime. + pub const RocksDbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 25_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + write: 100_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use super::constants::RocksDbWeight as W; + use frame_support::weights::constants; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..6894bd7bbf4422c2f9e3f81ad27c8f0a51f19891 --- /dev/null +++ b/polkadot/runtime/rococo/src/lib.rs @@ -0,0 +1,2322 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Rococo runtime for v1 parachains. + +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit. +#![recursion_limit = "512"] + +use pallet_nis::WithMaximumOf; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use primitives::{ + slashing, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, + CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash, + Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce, + OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, SessionInfo, Signature, + ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID, +}; +use runtime_common::{ + assigned_slots, auctions, claims, crowdloan, impl_runtime_weights, impls::ToAuthor, + paras_registrar, paras_sudo_wrapper, prod_or_fast, slots, BlockHashCount, BlockLength, + SlowAdjustingFeeUpdate, +}; +use scale_info::TypeInfo; +use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*}; + +use runtime_parachains::{ + assigner as parachains_assigner, assigner_on_demand as parachains_assigner_on_demand, + assigner_parachains as parachains_assigner_parachains, + configuration as parachains_configuration, disputes as parachains_disputes, + disputes::slashing as parachains_slashing, + dmp as parachains_dmp, hrmp as parachains_hrmp, inclusion as parachains_inclusion, + inclusion::{AggregateMessageOrigin, UmpQueueId}, + initializer as parachains_initializer, origin as parachains_origin, paras as parachains_paras, + paras_inherent as parachains_paras_inherent, + runtime_api_impl::v5 as parachains_runtime_api_impl, + scheduler as parachains_scheduler, session_info as parachains_session_info, + shared as parachains_shared, +}; + +use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; +use beefy_primitives::{ + ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}, + mmr::{BeefyDataProvider, MmrLeafVersion}, +}; + +use frame_support::{ + construct_runtime, parameter_types, + traits::{ + Contains, EitherOfDiverse, InstanceFilter, KeyOwnerProofSystem, LockIdentifier, + PrivilegeCmp, ProcessMessage, ProcessMessageError, StorageMapShim, WithdrawReasons, + }, + weights::{ConstantMultiplier, WeightMeter}, + PalletId, +}; +use frame_system::EnsureRoot; +use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +use pallet_session::historical as session_historical; +use pallet_transaction_payment::{CurrencyAdapter, FeeDetails, RuntimeDispatchInfo}; +use sp_core::{ConstU128, OpaqueMetadata, H256}; +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, + traits::{ + AccountIdLookup, BlakeTwo256, Block as BlockT, ConstU32, ConvertInto, + Extrinsic as ExtrinsicT, Keccak256, OpaqueKeys, SaturatedConversion, Verify, + }, + transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, FixedU128, KeyTypeId, Perbill, Percent, Permill, RuntimeDebug, +}; +use sp_staking::SessionIndex; +#[cfg(any(feature = "std", test))] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; +use static_assertions::const_assert; +use xcm::latest::Junction; + +pub use frame_system::Call as SystemCall; +pub use pallet_balances::Call as BalancesCall; + +/// Constant values used within the runtime. +use rococo_runtime_constants::{currency::*, fee::*, time::*}; + +// Weights used in the runtime. +mod weights; + +// XCM configurations. +pub mod xcm_config; + +mod validator_manager; + +impl_runtime_weights!(rococo_runtime_constants); + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +/// Runtime version (Rococo). +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("rococo"), + impl_name: create_runtime_str!("parity-rococo-v2.0"), + authoring_version: 0, + spec_version: 9430, + impl_version: 0, + #[cfg(not(feature = "disable-runtime-api"))] + apis: RUNTIME_API_VERSIONS, + #[cfg(feature = "disable-runtime-api")] + apis: sp_version::create_apis_vec![[]], + transaction_version: 22, + state_version: 1, +}; + +/// The BABE epoch configuration at genesis. +pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration = + babe_primitives::BabeEpochConfiguration { + c: PRIMARY_PROBABILITY, + allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots, + }; + +/// Native version. +#[cfg(any(feature = "std", test))] +pub fn native_version() -> NativeVersion { + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } +} + +/// We currently allow all calls. +pub struct BaseFilter; +impl Contains for BaseFilter { + fn contains(_call: &RuntimeCall) -> bool { + true + } +} + +parameter_types! { + pub const Version: RuntimeVersion = VERSION; + pub const SS58Prefix: u8 = 42; +} + +impl frame_system::Config for Runtime { + type BaseCallFilter = BaseFilter; + type BlockWeights = BlockWeights; + type BlockLength = BlockLength; + type DbWeight = RocksDbWeight; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = Nonce; + type Hash = Hash; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = AccountIdLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = Version; + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = weights::frame_system::WeightInfo; + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * + BlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; + pub const NoPreimagePostponement: Option = Some(10); +} + +type ScheduleOrigin = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionAtLeast, +>; + +/// Used the compare the privilege of an origin inside the scheduler. +pub struct OriginPrivilegeCmp; + +impl PrivilegeCmp for OriginPrivilegeCmp { + fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option { + if left == right { + return Some(Ordering::Equal) + } + + match (left, right) { + // Root is greater than anything. + (OriginCaller::system(frame_system::RawOrigin::Root), _) => Some(Ordering::Greater), + // Check which one has more yes votes. + ( + OriginCaller::Council(pallet_collective::RawOrigin::Members(l_yes_votes, l_count)), + OriginCaller::Council(pallet_collective::RawOrigin::Members(r_yes_votes, r_count)), + ) => Some((l_yes_votes * r_count).cmp(&(r_yes_votes * l_count))), + // For every other origin we don't care, as they are not used for `ScheduleOrigin`. + _ => None, + } + } +} + +impl pallet_scheduler::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = ScheduleOrigin; + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type WeightInfo = weights::pallet_scheduler::WeightInfo; + type OriginPrivilegeCmp = OriginPrivilegeCmp; + type Preimages = Preimage; +} + +parameter_types! { + pub const PreimageBaseDeposit: Balance = deposit(2, 64); + pub const PreimageByteDeposit: Balance = deposit(0, 1); +} + +impl pallet_preimage::Config for Runtime { + type WeightInfo = weights::pallet_preimage::WeightInfo; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type BaseDeposit = PreimageBaseDeposit; + type ByteDeposit = PreimageByteDeposit; +} + +parameter_types! { + pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; + pub ReportLongevity: u64 = EpochDurationInBlocks::get() as u64 * 10; +} + +impl pallet_babe::Config for Runtime { + type EpochDuration = EpochDurationInBlocks; + type ExpectedBlockTime = ExpectedBlockTime; + // session module is the trigger + type EpochChangeTrigger = pallet_babe::ExternalTrigger; + type DisabledValidators = Session; + type WeightInfo = (); + type MaxAuthorities = MaxAuthorities; + type MaxNominators = ConstU32<0>; + type KeyOwnerProof = + >::Proof; + type EquivocationReportSystem = + pallet_babe::EquivocationReportSystem; +} + +parameter_types! { + pub const IndexDeposit: Balance = 100 * CENTS; +} + +impl pallet_indices::Config for Runtime { + type AccountIndex = AccountIndex; + type Currency = Balances; + type Deposit = IndexDeposit; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_indices::WeightInfo; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = weights::pallet_balances::WeightInfo; + type FreezeIdentifier = (); + type MaxFreezes = ConstU32<1>; + type RuntimeHoldReason = RuntimeHoldReason; + type MaxHolds = ConstU32<1>; +} + +parameter_types! { + pub const TransactionByteFee: Balance = 10 * MILLICENTS; + /// This value increases the priority of `Operational` transactions by adding + /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`. + pub const OperationalFeeMultiplier: u8 = 5; +} + +impl pallet_transaction_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter>; + type OperationalFeeMultiplier = OperationalFeeMultiplier; + type WeightToFee = WeightToFee; + type LengthToFee = ConstantMultiplier; + type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; +} + +parameter_types! { + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; +} +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = Babe; + type MinimumPeriod = MinimumPeriod; + type WeightInfo = weights::pallet_timestamp::WeightInfo; +} + +impl pallet_authorship::Config for Runtime { + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; + type EventHandler = ImOnline; +} + +impl_opaque_keys! { + pub struct SessionKeys { + pub grandpa: Grandpa, + pub babe: Babe, + pub im_online: ImOnline, + pub para_validator: Initializer, + pub para_assignment: ParaSessionInfo, + pub authority_discovery: AuthorityDiscovery, + pub beefy: Beefy, + } +} + +/// Special `ValidatorIdOf` implementation that is just returning the input as result. +pub struct ValidatorIdOf; +impl sp_runtime::traits::Convert> for ValidatorIdOf { + fn convert(a: AccountId) -> Option { + Some(a) + } +} + +impl pallet_session::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = AccountId; + type ValidatorIdOf = ValidatorIdOf; + type ShouldEndSession = Babe; + type NextSessionRotation = Babe; + type SessionManager = pallet_session::historical::NoteHistoricalRoot; + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; + type WeightInfo = weights::pallet_session::WeightInfo; +} + +pub struct FullIdentificationOf; +impl sp_runtime::traits::Convert> for FullIdentificationOf { + fn convert(_: AccountId) -> Option<()> { + Some(Default::default()) + } +} + +impl pallet_session::historical::Config for Runtime { + type FullIdentification = (); + type FullIdentificationOf = FullIdentificationOf; +} + +parameter_types! { + pub const SessionsPerEra: SessionIndex = 6; + pub const BondingDuration: sp_staking::EraIndex = 28; +} + +parameter_types! { + pub LaunchPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1, "ROC_LAUNCH_PERIOD"); + pub VotingPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1 * MINUTES, "ROC_VOTING_PERIOD"); + pub FastTrackVotingPeriod: BlockNumber = prod_or_fast!(3 * HOURS, 1 * MINUTES, "ROC_FAST_TRACK_VOTING_PERIOD"); + pub const MinimumDeposit: Balance = 100 * CENTS; + pub EnactmentPeriod: BlockNumber = prod_or_fast!(8 * DAYS, 1, "ROC_ENACTMENT_PERIOD"); + pub CooloffPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1 * MINUTES, "ROC_COOLOFF_PERIOD"); + pub const InstantAllowed: bool = true; + pub const MaxVotes: u32 = 100; + pub const MaxProposals: u32 = 100; +} + +impl pallet_democracy::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type EnactmentPeriod = EnactmentPeriod; + type VoteLockingPeriod = EnactmentPeriod; + type LaunchPeriod = LaunchPeriod; + type VotingPeriod = VotingPeriod; + type MinimumDeposit = MinimumDeposit; + type SubmitOrigin = frame_system::EnsureSigned; + /// A straight majority of the council can decide what their next motion is. + type ExternalOrigin = + pallet_collective::EnsureProportionAtLeast; + /// A majority can have the next scheduled referendum be a straight majority-carries vote. + type ExternalMajorityOrigin = + pallet_collective::EnsureProportionAtLeast; + /// A unanimous council can have the next scheduled referendum be a straight default-carries + /// (NTB) vote. + type ExternalDefaultOrigin = + pallet_collective::EnsureProportionAtLeast; + /// Two thirds of the technical committee can have an `ExternalMajority/ExternalDefault` vote + /// be tabled immediately and with a shorter voting/enactment period. + type FastTrackOrigin = + pallet_collective::EnsureProportionAtLeast; + type InstantOrigin = + pallet_collective::EnsureProportionAtLeast; + type InstantAllowed = InstantAllowed; + type FastTrackVotingPeriod = FastTrackVotingPeriod; + // To cancel a proposal which has been passed, 2/3 of the council must agree to it. + type CancellationOrigin = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionAtLeast, + >; + type BlacklistOrigin = EnsureRoot; + // To cancel a proposal before it has been passed, the technical committee must be unanimous or + // Root must agree. + type CancelProposalOrigin = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionAtLeast, + >; + // Any single technical committee member may veto a coming council proposal, however they can + // only do it once and it lasts only for the cooloff period. + type VetoOrigin = pallet_collective::EnsureMember; + type CooloffPeriod = CooloffPeriod; + type Slash = Treasury; + type Scheduler = Scheduler; + type PalletsOrigin = OriginCaller; + type MaxVotes = MaxVotes; + type WeightInfo = weights::pallet_democracy::WeightInfo; + type MaxProposals = MaxProposals; + type Preimages = Preimage; + type MaxDeposits = ConstU32<100>; + type MaxBlacklisted = ConstU32<100>; +} + +parameter_types! { + pub CouncilMotionDuration: BlockNumber = prod_or_fast!(3 * DAYS, 2 * MINUTES, "ROC_MOTION_DURATION"); + pub const CouncilMaxProposals: u32 = 100; + pub const CouncilMaxMembers: u32 = 100; + pub MaxProposalWeight: Weight = Perbill::from_percent(50) * BlockWeights::get().max_block; +} + +type CouncilCollective = pallet_collective::Instance1; +impl pallet_collective::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type Proposal = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type MotionDuration = CouncilMotionDuration; + type MaxProposals = CouncilMaxProposals; + type MaxMembers = CouncilMaxMembers; + type DefaultVote = pallet_collective::PrimeDefaultVote; + type SetMembersOrigin = EnsureRoot; + type WeightInfo = weights::pallet_collective_council::WeightInfo; + type MaxProposalWeight = MaxProposalWeight; +} + +parameter_types! { + pub const CandidacyBond: Balance = 100 * CENTS; + // 1 storage item created, key size is 32 bytes, value size is 16+16. + pub const VotingBondBase: Balance = deposit(1, 64); + // additional data per vote is 32 bytes (account id). + pub const VotingBondFactor: Balance = deposit(0, 32); + /// Daily council elections + pub TermDuration: BlockNumber = prod_or_fast!(24 * HOURS, 2 * MINUTES, "ROC_TERM_DURATION"); + pub const DesiredMembers: u32 = 19; + pub const DesiredRunnersUp: u32 = 19; + pub const MaxVoters: u32 = 10 * 1000; + pub const MaxVotesPerVoter: u32 = 16; + pub const MaxCandidates: u32 = 1000; + pub const PhragmenElectionPalletId: LockIdentifier = *b"phrelect"; +} + +// Make sure that there are no more than MaxMembers members elected via phragmen. +const_assert!(DesiredMembers::get() <= CouncilMaxMembers::get()); + +impl pallet_elections_phragmen::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type ChangeMembers = Council; + type InitializeMembers = Council; + type CurrencyToVote = runtime_common::CurrencyToVote; + type CandidacyBond = CandidacyBond; + type VotingBondBase = VotingBondBase; + type VotingBondFactor = VotingBondFactor; + type LoserCandidate = Treasury; + type KickedMember = Treasury; + type DesiredMembers = DesiredMembers; + type DesiredRunnersUp = DesiredRunnersUp; + type TermDuration = TermDuration; + type MaxVoters = MaxVoters; + type MaxVotesPerVoter = MaxVotesPerVoter; + type MaxCandidates = MaxCandidates; + type PalletId = PhragmenElectionPalletId; + type WeightInfo = weights::pallet_elections_phragmen::WeightInfo; +} + +parameter_types! { + pub TechnicalMotionDuration: BlockNumber = prod_or_fast!(3 * DAYS, 2 * MINUTES, "ROC_MOTION_DURATION"); + pub const TechnicalMaxProposals: u32 = 100; + pub const TechnicalMaxMembers: u32 = 100; +} + +type TechnicalCollective = pallet_collective::Instance2; +impl pallet_collective::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type Proposal = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type MotionDuration = TechnicalMotionDuration; + type MaxProposals = TechnicalMaxProposals; + type MaxMembers = TechnicalMaxMembers; + type DefaultVote = pallet_collective::PrimeDefaultVote; + type SetMembersOrigin = EnsureRoot; + type WeightInfo = weights::pallet_collective_technical_committee::WeightInfo; + type MaxProposalWeight = MaxProposalWeight; +} + +type MoreThanHalfCouncil = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionMoreThan, +>; + +impl pallet_membership::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type AddOrigin = MoreThanHalfCouncil; + type RemoveOrigin = MoreThanHalfCouncil; + type SwapOrigin = MoreThanHalfCouncil; + type ResetOrigin = MoreThanHalfCouncil; + type PrimeOrigin = MoreThanHalfCouncil; + type MembershipInitialized = TechnicalCommittee; + type MembershipChanged = TechnicalCommittee; + type MaxMembers = TechnicalMaxMembers; + type WeightInfo = weights::pallet_membership::WeightInfo; +} + +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: Balance = 2000 * CENTS; + pub const ProposalBondMaximum: Balance = 1 * GRAND; + pub const SpendPeriod: BlockNumber = 6 * DAYS; + pub const Burn: Permill = Permill::from_perthousand(2); + pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); + + pub const TipCountdown: BlockNumber = 1 * DAYS; + pub const TipFindersFee: Percent = Percent::from_percent(20); + pub const TipReportDepositBase: Balance = 100 * CENTS; + pub const DataDepositPerByte: Balance = 1 * CENTS; + pub const MaxApprovals: u32 = 100; + pub const MaxAuthorities: u32 = 100_000; + pub const MaxKeys: u32 = 10_000; + pub const MaxPeerInHeartbeats: u32 = 10_000; +} + +type ApproveOrigin = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionAtLeast, +>; + +impl pallet_treasury::Config for Runtime { + type PalletId = TreasuryPalletId; + type Currency = Balances; + type ApproveOrigin = ApproveOrigin; + type RejectOrigin = MoreThanHalfCouncil; + type RuntimeEvent = RuntimeEvent; + type OnSlash = Treasury; + type ProposalBond = ProposalBond; + type ProposalBondMinimum = ProposalBondMinimum; + type ProposalBondMaximum = ProposalBondMaximum; + type SpendPeriod = SpendPeriod; + type Burn = Burn; + type BurnDestination = Society; + type MaxApprovals = MaxApprovals; + type WeightInfo = weights::pallet_treasury::WeightInfo; + type SpendFunds = Bounties; + type SpendOrigin = frame_support::traits::NeverEnsureOrigin; +} + +parameter_types! { + pub const BountyDepositBase: Balance = 100 * CENTS; + pub const BountyDepositPayoutDelay: BlockNumber = 4 * DAYS; + pub const BountyUpdatePeriod: BlockNumber = 90 * DAYS; + pub const MaximumReasonLength: u32 = 16384; + pub const CuratorDepositMultiplier: Permill = Permill::from_percent(50); + pub const CuratorDepositMin: Balance = 10 * CENTS; + pub const CuratorDepositMax: Balance = 500 * CENTS; + pub const BountyValueMinimum: Balance = 200 * CENTS; +} + +impl pallet_bounties::Config for Runtime { + type BountyDepositBase = BountyDepositBase; + type BountyDepositPayoutDelay = BountyDepositPayoutDelay; + type BountyUpdatePeriod = BountyUpdatePeriod; + type CuratorDepositMultiplier = CuratorDepositMultiplier; + type CuratorDepositMin = CuratorDepositMin; + type CuratorDepositMax = CuratorDepositMax; + type BountyValueMinimum = BountyValueMinimum; + type ChildBountyManager = ChildBounties; + type DataDepositPerByte = DataDepositPerByte; + type RuntimeEvent = RuntimeEvent; + type MaximumReasonLength = MaximumReasonLength; + type WeightInfo = weights::pallet_bounties::WeightInfo; +} + +parameter_types! { + pub const MaxActiveChildBountyCount: u32 = 100; + pub const ChildBountyValueMinimum: Balance = BountyValueMinimum::get() / 10; +} + +impl pallet_child_bounties::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type MaxActiveChildBountyCount = MaxActiveChildBountyCount; + type ChildBountyValueMinimum = ChildBountyValueMinimum; + type WeightInfo = weights::pallet_child_bounties::WeightInfo; +} + +impl pallet_tips::Config for Runtime { + type MaximumReasonLength = MaximumReasonLength; + type DataDepositPerByte = DataDepositPerByte; + type Tippers = PhragmenElection; + type TipCountdown = TipCountdown; + type TipFindersFee = TipFindersFee; + type TipReportDepositBase = TipReportDepositBase; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_tips::WeightInfo; +} + +impl pallet_offences::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type IdentificationTuple = pallet_session::historical::IdentificationTuple; + type OnOffenceHandler = (); +} + +impl pallet_authority_discovery::Config for Runtime { + type MaxAuthorities = MaxAuthorities; +} + +parameter_types! { + pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +impl pallet_im_online::Config for Runtime { + type AuthorityId = ImOnlineId; + type RuntimeEvent = RuntimeEvent; + type ValidatorSet = Historical; + type NextSessionRotation = Babe; + type ReportUnresponsiveness = Offences; + type UnsignedPriority = ImOnlineUnsignedPriority; + type WeightInfo = weights::pallet_im_online::WeightInfo; + type MaxKeys = MaxKeys; + type MaxPeerInHeartbeats = MaxPeerInHeartbeats; +} + +parameter_types! { + pub const MaxSetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); +} + +impl pallet_grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type MaxAuthorities = MaxAuthorities; + type MaxNominators = ConstU32<0>; + type MaxSetIdSessionEntries = MaxSetIdSessionEntries; + type KeyOwnerProof = >::Proof; + type EquivocationReportSystem = + pallet_grandpa::EquivocationReportSystem; +} + +/// Submits a transaction with the node's public and signature type. Adheres to the signed extension +/// format of the chain. +impl frame_system::offchain::CreateSignedTransaction for Runtime +where + RuntimeCall: From, +{ + fn create_transaction>( + call: RuntimeCall, + public: ::Signer, + account: AccountId, + nonce: ::Nonce, + ) -> Option<(RuntimeCall, ::SignaturePayload)> { + use sp_runtime::traits::StaticLookup; + // take the biggest period possible. + let period = + BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; + + let current_block = System::block_number() + .saturated_into::() + // The `System::block_number` is initialized with `n+1`, + // so the actual block number is `n`. + .saturating_sub(1); + let tip = 0; + let extra: SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(generic::Era::mortal( + period, + current_block, + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + ); + let raw_payload = SignedPayload::new(call, extra) + .map_err(|e| { + log::warn!("Unable to create signed payload: {:?}", e); + }) + .ok()?; + let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; + let (call, extra, _) = raw_payload.deconstruct(); + let address = ::Lookup::unlookup(account); + Some((call, (address, signature, extra))) + } +} + +impl frame_system::offchain::SigningTypes for Runtime { + type Public = ::Signer; + type Signature = Signature; +} + +impl frame_system::offchain::SendTransactionTypes for Runtime +where + RuntimeCall: From, +{ + type Extrinsic = UncheckedExtrinsic; + type OverarchingCall = RuntimeCall; +} + +parameter_types! { + pub Prefix: &'static [u8] = b"Pay ROCs to the Rococo account:"; +} + +impl claims::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type VestingSchedule = Vesting; + type Prefix = Prefix; + type MoveClaimOrigin = + pallet_collective::EnsureProportionMoreThan; + type WeightInfo = weights::runtime_common_claims::WeightInfo; +} + +parameter_types! { + // Minimum 100 bytes/ROC deposited (1 CENT/byte) + pub const BasicDeposit: Balance = 1000 * CENTS; // 258 bytes on-chain + pub const FieldDeposit: Balance = 250 * CENTS; // 66 bytes on-chain + pub const SubAccountDeposit: Balance = 200 * CENTS; // 53 bytes on-chain + pub const MaxSubAccounts: u32 = 100; + pub const MaxAdditionalFields: u32 = 100; + pub const MaxRegistrars: u32 = 20; +} + +impl pallet_identity::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BasicDeposit = BasicDeposit; + type FieldDeposit = FieldDeposit; + type SubAccountDeposit = SubAccountDeposit; + type MaxSubAccounts = MaxSubAccounts; + type MaxAdditionalFields = MaxAdditionalFields; + type MaxRegistrars = MaxRegistrars; + type Slashed = Treasury; + type ForceOrigin = MoreThanHalfCouncil; + type RegistrarOrigin = MoreThanHalfCouncil; + type WeightInfo = weights::pallet_identity::WeightInfo; +} + +impl pallet_utility::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type PalletsOrigin = OriginCaller; + type WeightInfo = weights::pallet_utility::WeightInfo; +} + +parameter_types! { + // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. + pub const DepositBase: Balance = deposit(1, 88); + // Additional storage item size of 32 bytes. + pub const DepositFactor: Balance = deposit(0, 32); + pub const MaxSignatories: u32 = 100; +} + +impl pallet_multisig::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type DepositBase = DepositBase; + type DepositFactor = DepositFactor; + type MaxSignatories = MaxSignatories; + type WeightInfo = weights::pallet_multisig::WeightInfo; +} + +parameter_types! { + pub const ConfigDepositBase: Balance = 500 * CENTS; + pub const FriendDepositFactor: Balance = 50 * CENTS; + pub const MaxFriends: u16 = 9; + pub const RecoveryDeposit: Balance = 500 * CENTS; +} + +impl pallet_recovery::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type ConfigDepositBase = ConfigDepositBase; + type FriendDepositFactor = FriendDepositFactor; + type MaxFriends = MaxFriends; + type RecoveryDeposit = RecoveryDeposit; +} + +parameter_types! { + pub const SocietyPalletId: PalletId = PalletId(*b"py/socie"); +} + +impl pallet_society::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type GraceStrikes = ConstU32<1>; + type PeriodSpend = ConstU128<{ 50_000 * CENTS }>; + type VotingPeriod = ConstU32<{ 5 * DAYS }>; + type ClaimPeriod = ConstU32<{ 2 * DAYS }>; + type MaxLockDuration = ConstU32<{ 36 * 30 * DAYS }>; + type FounderSetOrigin = EnsureRoot; + type ChallengePeriod = ConstU32<{ 7 * DAYS }>; + type MaxPayouts = ConstU32<8>; + type MaxBids = ConstU32<512>; + type PalletId = SocietyPalletId; + type WeightInfo = (); +} + +parameter_types! { + pub const MinVestedTransfer: Balance = 100 * CENTS; + pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = + WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); +} + +impl pallet_vesting::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BlockNumberToBalance = ConvertInto; + type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = weights::pallet_vesting::WeightInfo; + type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; + const MAX_VESTING_SCHEDULES: u32 = 28; +} + +parameter_types! { + // One storage item; key size 32, value size 8; . + pub const ProxyDepositBase: Balance = deposit(1, 8); + // Additional storage item size of 33 bytes. + pub const ProxyDepositFactor: Balance = deposit(0, 33); + pub const MaxProxies: u16 = 32; + pub const AnnouncementDepositBase: Balance = deposit(1, 8); + pub const AnnouncementDepositFactor: Balance = deposit(0, 66); + pub const MaxPending: u16 = 32; +} + +/// The type used to represent the kinds of proxying allowed. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + RuntimeDebug, + MaxEncodedLen, + TypeInfo, +)] +pub enum ProxyType { + Any, + NonTransfer, + Governance, + IdentityJudgement, + CancelProxy, + Auction, + Society, + OnDemandOrdering, +} +impl Default for ProxyType { + fn default() -> Self { + Self::Any + } +} +impl InstanceFilter for ProxyType { + fn filter(&self, c: &RuntimeCall) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => matches!( + c, + RuntimeCall::System(..) | + RuntimeCall::Babe(..) | + RuntimeCall::Timestamp(..) | + RuntimeCall::Indices(pallet_indices::Call::claim {..}) | + RuntimeCall::Indices(pallet_indices::Call::free {..}) | + RuntimeCall::Indices(pallet_indices::Call::freeze {..}) | + // Specifically omitting Indices `transfer`, `force_transfer` + // Specifically omitting the entire Balances pallet + RuntimeCall::Session(..) | + RuntimeCall::Grandpa(..) | + RuntimeCall::ImOnline(..) | + RuntimeCall::Democracy(..) | + RuntimeCall::Council(..) | + RuntimeCall::TechnicalCommittee(..) | + RuntimeCall::PhragmenElection(..) | + RuntimeCall::TechnicalMembership(..) | + RuntimeCall::Treasury(..) | + RuntimeCall::Bounties(..) | + RuntimeCall::ChildBounties(..) | + RuntimeCall::Tips(..) | + RuntimeCall::Claims(..) | + RuntimeCall::Utility(..) | + RuntimeCall::Identity(..) | + RuntimeCall::Society(..) | + RuntimeCall::Recovery(pallet_recovery::Call::as_recovered {..}) | + RuntimeCall::Recovery(pallet_recovery::Call::vouch_recovery {..}) | + RuntimeCall::Recovery(pallet_recovery::Call::claim_recovery {..}) | + RuntimeCall::Recovery(pallet_recovery::Call::close_recovery {..}) | + RuntimeCall::Recovery(pallet_recovery::Call::remove_recovery {..}) | + RuntimeCall::Recovery(pallet_recovery::Call::cancel_recovered {..}) | + // Specifically omitting Recovery `create_recovery`, `initiate_recovery` + RuntimeCall::Vesting(pallet_vesting::Call::vest {..}) | + RuntimeCall::Vesting(pallet_vesting::Call::vest_other {..}) | + // Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer` + RuntimeCall::Scheduler(..) | + RuntimeCall::Proxy(..) | + RuntimeCall::Multisig(..) | + RuntimeCall::Nis(..) | + RuntimeCall::Registrar(paras_registrar::Call::register {..}) | + RuntimeCall::Registrar(paras_registrar::Call::deregister {..}) | + // Specifically omitting Registrar `swap` + RuntimeCall::Registrar(paras_registrar::Call::reserve {..}) | + RuntimeCall::Crowdloan(..) | + RuntimeCall::Slots(..) | + RuntimeCall::Auctions(..) // Specifically omitting the entire XCM Pallet + ), + ProxyType::Governance => + matches!( + c, + RuntimeCall::Democracy(..) | + RuntimeCall::Council(..) | RuntimeCall::TechnicalCommittee(..) | + RuntimeCall::PhragmenElection(..) | + RuntimeCall::Treasury(..) | + RuntimeCall::Bounties(..) | + RuntimeCall::Tips(..) | RuntimeCall::Utility(..) | + RuntimeCall::ChildBounties(..) + ), + ProxyType::IdentityJudgement => matches!( + c, + RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. }) | + RuntimeCall::Utility(..) + ), + ProxyType::CancelProxy => { + matches!(c, RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })) + }, + ProxyType::Auction => matches!( + c, + RuntimeCall::Auctions { .. } | + RuntimeCall::Crowdloan { .. } | + RuntimeCall::Registrar { .. } | + RuntimeCall::Multisig(..) | + RuntimeCall::Slots { .. } + ), + ProxyType::Society => matches!(c, RuntimeCall::Society(..)), + ProxyType::OnDemandOrdering => matches!(c, RuntimeCall::OnDemandAssignmentProvider(..)), + } + } + fn is_superset(&self, o: &Self) -> bool { + match (self, o) { + (x, y) if x == y => true, + (ProxyType::Any, _) => true, + (_, ProxyType::Any) => false, + (ProxyType::NonTransfer, _) => true, + _ => false, + } + } +} + +impl pallet_proxy::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type ProxyType = ProxyType; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type MaxProxies = MaxProxies; + type WeightInfo = weights::pallet_proxy::WeightInfo; + type MaxPending = MaxPending; + type CallHasher = BlakeTwo256; + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; +} + +impl parachains_origin::Config for Runtime {} + +impl parachains_configuration::Config for Runtime { + type WeightInfo = weights::runtime_parachains_configuration::WeightInfo; +} + +impl parachains_shared::Config for Runtime {} + +impl parachains_session_info::Config for Runtime { + type ValidatorSet = Historical; +} + +/// Special `RewardValidators` that does nothing ;) +pub struct RewardValidators; +impl runtime_parachains::inclusion::RewardValidators for RewardValidators { + fn reward_backing(_: impl IntoIterator) {} + fn reward_bitfields(_: impl IntoIterator) {} +} + +impl parachains_inclusion::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type DisputesHandler = ParasDisputes; + type RewardValidators = RewardValidators; + type MessageQueue = MessageQueue; + type WeightInfo = weights::runtime_parachains_inclusion::WeightInfo; +} + +parameter_types! { + pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +impl parachains_paras::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::runtime_parachains_paras::WeightInfo; + type UnsignedPriority = ParasUnsignedPriority; + type QueueFootprinter = ParaInclusion; + type NextSessionRotation = Babe; +} + +parameter_types! { + /// Amount of weight that can be spent per block to service messages. + /// + /// # WARNING + /// + /// This is not a good value for para-chains since the `Scheduler` already uses up to 80% block weight. + pub MessageQueueServiceWeight: Weight = Perbill::from_percent(20) * BlockWeights::get().max_block; + pub const MessageQueueHeapSize: u32 = 32 * 1024; + pub const MessageQueueMaxStale: u32 = 96; +} + +/// Message processor to handle any messages that were enqueued into the `MessageQueue` pallet. +pub struct MessageProcessor; +impl ProcessMessage for MessageProcessor { + type Origin = AggregateMessageOrigin; + + fn process_message( + message: &[u8], + origin: Self::Origin, + meter: &mut WeightMeter, + id: &mut [u8; 32], + ) -> Result { + let para = match origin { + AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para, + }; + xcm_builder::ProcessXcmMessage::< + Junction, + xcm_executor::XcmExecutor, + RuntimeCall, + >::process_message(message, Junction::Parachain(para.into()), meter, id) + } +} + +impl pallet_message_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Size = u32; + type HeapSize = MessageQueueHeapSize; + type MaxStale = MessageQueueMaxStale; + type ServiceWeight = MessageQueueServiceWeight; + #[cfg(not(feature = "runtime-benchmarks"))] + type MessageProcessor = MessageProcessor; + #[cfg(feature = "runtime-benchmarks")] + type MessageProcessor = + pallet_message_queue::mock_helpers::NoopMessageProcessor; + type QueueChangeHandler = ParaInclusion; + type QueuePausedQuery = (); + type WeightInfo = weights::pallet_message_queue::WeightInfo; +} + +impl parachains_dmp::Config for Runtime {} + +impl parachains_hrmp::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type ChannelManager = EnsureRoot; + type Currency = Balances; + type WeightInfo = weights::runtime_parachains_hrmp::WeightInfo; +} + +impl parachains_paras_inherent::Config for Runtime { + type WeightInfo = weights::runtime_parachains_paras_inherent::WeightInfo; +} + +impl parachains_scheduler::Config for Runtime { + type AssignmentProvider = ParaAssignmentProvider; +} + +parameter_types! { + pub const OnDemandTrafficDefaultValue: FixedU128 = FixedU128::from_u32(1); +} + +impl parachains_assigner_on_demand::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type TrafficDefaultValue = OnDemandTrafficDefaultValue; + type WeightInfo = weights::runtime_parachains_assigner_on_demand::WeightInfo; +} + +impl parachains_assigner_parachains::Config for Runtime {} + +impl parachains_assigner::Config for Runtime { + type OnDemandAssignmentProvider = OnDemandAssignmentProvider; + type ParachainsAssignmentProvider = ParachainsAssignmentProvider; +} + +impl parachains_initializer::Config for Runtime { + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type ForceOrigin = EnsureRoot; + type WeightInfo = weights::runtime_parachains_initializer::WeightInfo; +} + +impl parachains_disputes::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RewardValidators = (); + type SlashingHandler = parachains_slashing::SlashValidatorsForDisputes; + type WeightInfo = weights::runtime_parachains_disputes::WeightInfo; +} + +impl parachains_slashing::Config for Runtime { + type KeyOwnerProofSystem = Historical; + type KeyOwnerProof = + >::Proof; + type KeyOwnerIdentification = >::IdentificationTuple; + type HandleReports = parachains_slashing::SlashingReportHandler< + Self::KeyOwnerIdentification, + Offences, + ReportLongevity, + >; + type WeightInfo = parachains_slashing::TestWeightInfo; + type BenchmarkingConfig = parachains_slashing::BenchConfig<200>; +} + +parameter_types! { + pub const ParaDeposit: Balance = 40 * UNITS; +} + +impl paras_registrar::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type OnSwap = (Crowdloan, Slots); + type ParaDeposit = ParaDeposit; + type DataDepositPerByte = DataDepositPerByte; + type WeightInfo = weights::runtime_common_paras_registrar::WeightInfo; +} + +parameter_types! { + pub LeasePeriod: BlockNumber = prod_or_fast!(1 * DAYS, 1 * DAYS, "ROC_LEASE_PERIOD"); +} + +impl slots::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Registrar = Registrar; + type LeasePeriod = LeasePeriod; + type LeaseOffset = (); + type ForceOrigin = MoreThanHalfCouncil; + type WeightInfo = weights::runtime_common_slots::WeightInfo; +} + +parameter_types! { + pub const CrowdloanId: PalletId = PalletId(*b"py/cfund"); + pub const SubmissionDeposit: Balance = 3 * GRAND; + pub const MinContribution: Balance = 3_000 * CENTS; + pub const RemoveKeysLimit: u32 = 1000; + // Allow 32 bytes for an additional memo to a crowdloan. + pub const MaxMemoLength: u8 = 32; +} + +impl crowdloan::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type PalletId = CrowdloanId; + type SubmissionDeposit = SubmissionDeposit; + type MinContribution = MinContribution; + type RemoveKeysLimit = RemoveKeysLimit; + type Registrar = Registrar; + type Auctioneer = Auctions; + type MaxMemoLength = MaxMemoLength; + type WeightInfo = weights::runtime_common_crowdloan::WeightInfo; +} + +parameter_types! { + // The average auction is 7 days long, so this will be 70% for ending period. + // 5 Days = 72000 Blocks @ 6 sec per block + pub const EndingPeriod: BlockNumber = 5 * DAYS; + // ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples + pub const SampleLength: BlockNumber = 2 * MINUTES; +} + +type AuctionInitiate = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionAtLeast, +>; + +impl auctions::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Leaser = Slots; + type Registrar = Registrar; + type EndingPeriod = EndingPeriod; + type SampleLength = SampleLength; + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type InitiateOrigin = AuctionInitiate; + type WeightInfo = weights::runtime_common_auctions::WeightInfo; +} + +type NisCounterpartInstance = pallet_balances::Instance2; +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ConstU128<10_000_000_000>; // One RTC cent + type AccountStore = StorageMapShim< + pallet_balances::Account, + AccountId, + pallet_balances::AccountData, + >; + type MaxLocks = ConstU32<4>; + type MaxReserves = ConstU32<4>; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = weights::pallet_balances_nis_counterpart_balances::WeightInfo; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +parameter_types! { + pub const NisBasePeriod: BlockNumber = 30 * DAYS; + pub const MinBid: Balance = 100 * UNITS; + pub MinReceipt: Perquintill = Perquintill::from_rational(1u64, 10_000_000u64); + pub const IntakePeriod: BlockNumber = 5 * MINUTES; + pub MaxIntakeWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10; + pub const ThawThrottle: (Perquintill, BlockNumber) = (Perquintill::from_percent(25), 5); + pub storage NisTarget: Perquintill = Perquintill::zero(); + pub const NisPalletId: PalletId = PalletId(*b"py/nis "); +} + +impl pallet_nis::Config for Runtime { + type WeightInfo = weights::pallet_nis::WeightInfo; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type CurrencyBalance = Balance; + type FundOrigin = frame_system::EnsureSigned; + type Counterpart = NisCounterpartBalances; + type CounterpartAmount = WithMaximumOf>; + type Deficit = (); // Mint + type IgnoredIssuance = (); + type Target = NisTarget; + type PalletId = NisPalletId; + type QueueCount = ConstU32<300>; + type MaxQueueLen = ConstU32<1000>; + type FifoQueueLen = ConstU32<250>; + type BasePeriod = NisBasePeriod; + type MinBid = MinBid; + type MinReceipt = MinReceipt; + type IntakePeriod = IntakePeriod; + type MaxIntakeWeight = MaxIntakeWeight; + type ThawThrottle = ThawThrottle; + type RuntimeHoldReason = RuntimeHoldReason; +} + +parameter_types! { + pub const BeefySetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); +} + +impl pallet_beefy::Config for Runtime { + type BeefyId = BeefyId; + type MaxAuthorities = MaxAuthorities; + type MaxNominators = ConstU32<0>; + type MaxSetIdSessionEntries = BeefySetIdSessionEntries; + type OnNewValidatorSet = MmrLeaf; + type WeightInfo = (); + type KeyOwnerProof = >::Proof; + type EquivocationReportSystem = + pallet_beefy::EquivocationReportSystem; +} + +/// MMR helper types. +mod mmr { + use super::Runtime; + pub use pallet_mmr::primitives::*; + + pub type Leaf = <::LeafData as LeafDataProvider>::LeafData; + pub type Hashing = ::Hashing; + pub type Hash = ::Output; +} + +impl pallet_mmr::Config for Runtime { + const INDEXING_PREFIX: &'static [u8] = mmr::INDEXING_PREFIX; + type Hashing = Keccak256; + type OnNewRoot = pallet_beefy_mmr::DepositBeefyDigest; + type WeightInfo = (); + type LeafData = pallet_beefy_mmr::Pallet; +} + +parameter_types! { + /// Version of the produced MMR leaf. + /// + /// The version consists of two parts; + /// - `major` (3 bits) + /// - `minor` (5 bits) + /// + /// `major` should be updated only if decoding the previous MMR Leaf format from the payload + /// is not possible (i.e. backward incompatible change). + /// `minor` should be updated if fields are added to the previous MMR Leaf, which given SCALE + /// encoding does not prevent old leafs from being decoded. + /// + /// Hence we expect `major` to be changed really rarely (think never). + /// See [`MmrLeafVersion`] type documentation for more details. + pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0); +} + +pub struct ParaHeadsRootProvider; +impl BeefyDataProvider for ParaHeadsRootProvider { + fn extra_data() -> H256 { + let mut para_heads: Vec<(u32, Vec)> = Paras::parachains() + .into_iter() + .filter_map(|id| Paras::para_head(&id).map(|head| (id.into(), head.0))) + .collect(); + para_heads.sort(); + binary_merkle_tree::merkle_root::( + para_heads.into_iter().map(|pair| pair.encode()), + ) + .into() + } +} + +impl pallet_beefy_mmr::Config for Runtime { + type LeafVersion = LeafVersion; + type BeefyAuthorityToMerkleLeaf = pallet_beefy_mmr::BeefyEcdsaToEthereum; + type LeafExtra = H256; + type BeefyDataProvider = ParaHeadsRootProvider; +} + +impl paras_sudo_wrapper::Config for Runtime {} + +parameter_types! { + pub const PermanentSlotLeasePeriodLength: u32 = 365; + pub const TemporarySlotLeasePeriodLength: u32 = 5; + pub const MaxTemporarySlotPerLeasePeriod: u32 = 5; +} + +impl assigned_slots::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type AssignSlotOrigin = EnsureRoot; + type Leaser = Slots; + type PermanentSlotLeasePeriodLength = PermanentSlotLeasePeriodLength; + type TemporarySlotLeasePeriodLength = TemporarySlotLeasePeriodLength; + type MaxTemporarySlotPerLeasePeriod = MaxTemporarySlotPerLeasePeriod; + type WeightInfo = weights::runtime_common_assigned_slots::WeightInfo; +} + +impl validator_manager::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type PrivilegedOrigin = EnsureRoot; +} + +impl pallet_sudo::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type WeightInfo = weights::pallet_sudo::WeightInfo; +} + +construct_runtime! { + pub enum Runtime + { + // Basic stuff; balances is uncallable initially. + System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, + + // Babe must be before session. + Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned} = 1, + + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, + Indices: pallet_indices::{Pallet, Call, Storage, Config, Event} = 3, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 4, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 33, + + // Consensus support. + // Authorship must be before session in order to note author in the correct session and era + // for im-online. + Authorship: pallet_authorship::{Pallet, Storage} = 5, + Offences: pallet_offences::{Pallet, Storage, Event} = 7, + Historical: session_historical::{Pallet} = 34, + + // BEEFY Bridges support. + Beefy: pallet_beefy::{Pallet, Call, Storage, Config, ValidateUnsigned} = 240, + // MMR leaf construction must be before session in order to have leaf contents + // refer to block consistently. see substrate issue #11797 for details. + Mmr: pallet_mmr::{Pallet, Storage} = 241, + MmrLeaf: pallet_beefy_mmr::{Pallet, Storage} = 242, + + Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 8, + Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned} = 10, + ImOnline: pallet_im_online::{Pallet, Call, Storage, Event, ValidateUnsigned, Config} = 11, + AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config} = 12, + + // Governance stuff; uncallable initially. + Democracy: pallet_democracy::{Pallet, Call, Storage, Config, Event} = 13, + Council: pallet_collective::::{Pallet, Call, Storage, Origin, Event, Config} = 14, + TechnicalCommittee: pallet_collective::::{Pallet, Call, Storage, Origin, Event, Config} = 15, + PhragmenElection: pallet_elections_phragmen::{Pallet, Call, Storage, Event, Config} = 16, + TechnicalMembership: pallet_membership::::{Pallet, Call, Storage, Event, Config} = 17, + Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 18, + + // Claims. Usable initially. + Claims: claims::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 19, + + // Utility module. + Utility: pallet_utility::{Pallet, Call, Event} = 24, + + // Less simple identity module. + Identity: pallet_identity::{Pallet, Call, Storage, Event} = 25, + + // Society module. + Society: pallet_society::{Pallet, Call, Storage, Event} = 26, + + // Social recovery module. + Recovery: pallet_recovery::{Pallet, Call, Storage, Event} = 27, + + // Vesting. Usable initially, but removed once all vesting is finished. + Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config} = 28, + + // System scheduler. + Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 29, + + // Proxy module. Late addition. + Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 30, + + // Multisig module. Late addition. + Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 31, + + // Preimage registrar. + Preimage: pallet_preimage::{Pallet, Call, Storage, Event} = 32, + + // Bounties modules. + Bounties: pallet_bounties::{Pallet, Call, Storage, Event} = 35, + ChildBounties: pallet_child_bounties = 40, + + // Tips module. + Tips: pallet_tips::{Pallet, Call, Storage, Event} = 36, + + // NIS pallet. + Nis: pallet_nis::{Pallet, Call, Storage, Event, HoldReason} = 38, +// pub type NisCounterpartInstance = pallet_balances::Instance2; + NisCounterpartBalances: pallet_balances:: = 45, + + // Parachains pallets. Start indices at 50 to leave room. + ParachainsOrigin: parachains_origin::{Pallet, Origin} = 50, + Configuration: parachains_configuration::{Pallet, Call, Storage, Config} = 51, + ParasShared: parachains_shared::{Pallet, Call, Storage} = 52, + ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event} = 53, + ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent} = 54, + ParaScheduler: parachains_scheduler::{Pallet, Storage} = 55, + Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 56, + Initializer: parachains_initializer::{Pallet, Call, Storage} = 57, + Dmp: parachains_dmp::{Pallet, Storage} = 58, + Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 60, + ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 61, + ParasDisputes: parachains_disputes::{Pallet, Call, Storage, Event} = 62, + ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned} = 63, + MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 64, + ParaAssignmentProvider: parachains_assigner::{Pallet, Storage} = 65, + OnDemandAssignmentProvider: parachains_assigner_on_demand::{Pallet, Call, Storage, Event} = 66, + ParachainsAssignmentProvider: parachains_assigner_parachains::{Pallet} = 67, + + // Parachain Onboarding Pallets. Start indices at 70 to leave room. + Registrar: paras_registrar::{Pallet, Call, Storage, Event, Config} = 70, + Slots: slots::{Pallet, Call, Storage, Event} = 71, + Auctions: auctions::{Pallet, Call, Storage, Event} = 72, + Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 73, + + // Pallet for sending XCM. + XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 99, + + ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call} = 250, + AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event, Config} = 251, + + // Validator Manager pallet. + ValidatorManager: validator_manager::{Pallet, Call, Storage, Event} = 252, + + // State trie migration pallet, only temporary. + StateTrieMigration: pallet_state_trie_migration = 254, + + // Sudo. + Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 255, + } +} + +/// The address format for describing accounts. +pub type Address = sp_runtime::MultiAddress; +/// Block header type as expected by this runtime. +pub type Header = generic::Header; +/// Block type as expected by this runtime. +pub type Block = generic::Block; +/// A Block signed with a Justification +pub type SignedBlock = generic::SignedBlock; +/// `BlockId` type as expected by this runtime. +pub type BlockId = generic::BlockId; +/// The `SignedExtension` to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckMortality, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); + +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + generic::UncheckedExtrinsic; + +/// All migrations that will run on the next runtime upgrade. +/// +/// This contains the combined migrations of the last 10 releases. It allows to skip runtime +/// upgrades in case governance decides to do so. THE ORDER IS IMPORTANT. +pub type Migrations = migrations::Unreleased; + +/// The runtime migrations per release. +#[allow(deprecated, missing_docs)] +pub mod migrations { + use super::*; + + /// Unreleased migrations. Add new ones here: + pub type Unreleased = ( + pallet_society::migrations::VersionCheckedMigrateToV2, + pallet_im_online::migration::v1::Migration, + parachains_configuration::migration::v7::MigrateToV7, + assigned_slots::migration::v1::VersionCheckedMigrateToV1, + parachains_scheduler::migration::v1::MigrateToV1, + parachains_configuration::migration::v8::MigrateToV8, + ); +} + +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, + Migrations, +>; +/// The payload being signed in transactions. +pub type SignedPayload = generic::SignedPayload; + +parameter_types! { + // The deposit configuration for the singed migration. Specially if you want to allow any signed account to do the migration (see `SignedFilter`, these deposits should be high) + pub const MigrationSignedDepositPerItem: Balance = 1 * CENTS; + pub const MigrationSignedDepositBase: Balance = 20 * CENTS * 100; + pub const MigrationMaxKeyLen: u32 = 512; +} + +impl pallet_state_trie_migration::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type SignedDepositPerItem = MigrationSignedDepositPerItem; + type SignedDepositBase = MigrationSignedDepositBase; + type ControlOrigin = EnsureRoot; + // specific account for the migration, can trigger the signed migrations. + type SignedFilter = frame_system::EnsureSignedBy; + + // Use same weights as substrate ones. + type WeightInfo = pallet_state_trie_migration::weights::SubstrateWeight; + type MaxKeyLen = MigrationMaxKeyLen; +} + +frame_support::ord_parameter_types! { + pub const MigController: AccountId = AccountId::from(hex_literal::hex!("52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649")); +} + +#[cfg(feature = "runtime-benchmarks")] +mod benches { + frame_benchmarking::define_benchmarks!( + // Polkadot + // NOTE: Make sure to prefix these with `runtime_common::` so + // the that path resolves correctly in the generated file. + [runtime_common::assigned_slots, AssignedSlots] + [runtime_common::auctions, Auctions] + [runtime_common::crowdloan, Crowdloan] + [runtime_common::claims, Claims] + [runtime_common::slots, Slots] + [runtime_common::paras_registrar, Registrar] + [runtime_parachains::configuration, Configuration] + [runtime_parachains::hrmp, Hrmp] + [runtime_parachains::disputes, ParasDisputes] + [runtime_parachains::inclusion, ParaInclusion] + [runtime_parachains::initializer, Initializer] + [runtime_parachains::paras_inherent, ParaInherent] + [runtime_parachains::paras, Paras] + [runtime_parachains::assigner_on_demand, OnDemandAssignmentProvider] + // Substrate + [pallet_balances, Balances] + [pallet_balances, NisCounterpartBalances] + [frame_benchmarking::baseline, Baseline::] + [pallet_bounties, Bounties] + [pallet_child_bounties, ChildBounties] + [pallet_collective, Council] + [pallet_collective, TechnicalCommittee] + [pallet_democracy, Democracy] + [pallet_elections_phragmen, PhragmenElection] + [pallet_nis, Nis] + [pallet_identity, Identity] + [pallet_im_online, ImOnline] + [pallet_indices, Indices] + [pallet_membership, TechnicalMembership] + [pallet_message_queue, MessageQueue] + [pallet_multisig, Multisig] + [pallet_preimage, Preimage] + [pallet_proxy, Proxy] + [pallet_recovery, Recovery] + [pallet_scheduler, Scheduler] + [pallet_sudo, Sudo] + [frame_system, SystemBench::] + [pallet_timestamp, Timestamp] + [pallet_tips, Tips] + [pallet_treasury, Treasury] + [pallet_utility, Utility] + [pallet_vesting, Vesting] + // XCM + [pallet_xcm, XcmPallet] + [pallet_xcm_benchmarks::fungible, pallet_xcm_benchmarks::fungible::Pallet::] + [pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::] + ); +} + +#[cfg(not(feature = "disable-runtime-api"))] +sp_api::impl_runtime_apis! { + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block); + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } + } + + impl block_builder_api::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: inherents::InherentData, + ) -> inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl tx_pool_api::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl offchain_primitives::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl primitives::runtime_api::ParachainHost for Runtime { + fn validators() -> Vec { + parachains_runtime_api_impl::validators::() + } + + fn validator_groups() -> (Vec>, GroupRotationInfo) { + parachains_runtime_api_impl::validator_groups::() + } + + fn availability_cores() -> Vec> { + parachains_runtime_api_impl::availability_cores::() + } + + fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option> { + parachains_runtime_api_impl::persisted_validation_data::(para_id, assumption) + } + + fn assumed_validation_data( + para_id: ParaId, + expected_persisted_validation_data_hash: Hash, + ) -> Option<(PersistedValidationData, ValidationCodeHash)> { + parachains_runtime_api_impl::assumed_validation_data::( + para_id, + expected_persisted_validation_data_hash, + ) + } + + fn check_validation_outputs( + para_id: ParaId, + outputs: primitives::CandidateCommitments, + ) -> bool { + parachains_runtime_api_impl::check_validation_outputs::(para_id, outputs) + } + + fn session_index_for_child() -> SessionIndex { + parachains_runtime_api_impl::session_index_for_child::() + } + + fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option { + parachains_runtime_api_impl::validation_code::(para_id, assumption) + } + + fn candidate_pending_availability(para_id: ParaId) -> Option> { + parachains_runtime_api_impl::candidate_pending_availability::(para_id) + } + + fn candidate_events() -> Vec> { + parachains_runtime_api_impl::candidate_events::(|ev| { + match ev { + RuntimeEvent::ParaInclusion(ev) => { + Some(ev) + } + _ => None, + } + }) + } + + fn session_info(index: SessionIndex) -> Option { + parachains_runtime_api_impl::session_info::(index) + } + + fn session_executor_params(session_index: SessionIndex) -> Option { + parachains_runtime_api_impl::session_executor_params::(session_index) + } + + fn dmq_contents(recipient: ParaId) -> Vec> { + parachains_runtime_api_impl::dmq_contents::(recipient) + } + + fn inbound_hrmp_channels_contents( + recipient: ParaId + ) -> BTreeMap>> { + parachains_runtime_api_impl::inbound_hrmp_channels_contents::(recipient) + } + + fn validation_code_by_hash(hash: ValidationCodeHash) -> Option { + parachains_runtime_api_impl::validation_code_by_hash::(hash) + } + + fn on_chain_votes() -> Option> { + parachains_runtime_api_impl::on_chain_votes::() + } + + fn submit_pvf_check_statement( + stmt: primitives::PvfCheckStatement, + signature: primitives::ValidatorSignature + ) { + parachains_runtime_api_impl::submit_pvf_check_statement::(stmt, signature) + } + + fn pvfs_require_precheck() -> Vec { + parachains_runtime_api_impl::pvfs_require_precheck::() + } + + fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option + { + parachains_runtime_api_impl::validation_code_hash::(para_id, assumption) + } + + fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState)> { + parachains_runtime_api_impl::get_session_disputes::() + } + + fn unapplied_slashes( + ) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> { + parachains_runtime_api_impl::unapplied_slashes::() + } + + fn key_ownership_proof( + validator_id: ValidatorId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((PARACHAIN_KEY_TYPE_ID, validator_id)) + .map(|p| p.encode()) + .map(slashing::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_dispute_lost( + dispute_proof: slashing::DisputeProof, + key_ownership_proof: slashing::OpaqueKeyOwnershipProof, + ) -> Option<()> { + parachains_runtime_api_impl::submit_unsigned_slashing_report::( + dispute_proof, + key_ownership_proof, + ) + } + } + + #[api_version(3)] + impl beefy_primitives::BeefyApi for Runtime { + fn beefy_genesis() -> Option { + Beefy::genesis_block() + } + + fn validator_set() -> Option> { + Beefy::validator_set() + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: beefy_primitives::EquivocationProof< + BlockNumber, + BeefyId, + BeefySignature, + >, + key_owner_proof: beefy_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Beefy::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + + fn generate_key_ownership_proof( + _set_id: beefy_primitives::ValidatorSetId, + authority_id: BeefyId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((beefy_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(beefy_primitives::OpaqueKeyOwnershipProof::new) + } + } + + #[api_version(2)] + impl mmr::MmrApi for Runtime { + fn mmr_root() -> Result { + Ok(Mmr::mmr_root()) + } + + fn mmr_leaf_count() -> Result { + Ok(Mmr::mmr_leaves()) + } + + fn generate_proof( + block_numbers: Vec, + best_known_block_number: Option, + ) -> Result<(Vec, mmr::Proof), mmr::Error> { + Mmr::generate_proof(block_numbers, best_known_block_number).map( + |(leaves, proof)| { + ( + leaves + .into_iter() + .map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf)) + .collect(), + proof, + ) + }, + ) + } + + fn verify_proof(leaves: Vec, proof: mmr::Proof) + -> Result<(), mmr::Error> + { + let leaves = leaves.into_iter().map(|leaf| + leaf.into_opaque_leaf() + .try_decode() + .ok_or(mmr::Error::Verify)).collect::, mmr::Error>>()?; + Mmr::verify_leaves(leaves, proof) + } + + fn verify_proof_stateless( + root: mmr::Hash, + leaves: Vec, + proof: mmr::Proof + ) -> Result<(), mmr::Error> { + let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect(); + pallet_mmr::verify_leaves_proof::(root, nodes, proof) + } + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> Vec<(GrandpaId, u64)> { + Grandpa::grandpa_authorities() + } + + fn current_set_id() -> fg_primitives::SetId { + Grandpa::current_set_id() + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: fg_primitives::EquivocationProof< + ::Hash, + sp_runtime::traits::NumberFor, + >, + key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Grandpa::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + + fn generate_key_ownership_proof( + _set_id: fg_primitives::SetId, + authority_id: fg_primitives::AuthorityId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((fg_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(fg_primitives::OpaqueKeyOwnershipProof::new) + } + } + + impl babe_primitives::BabeApi for Runtime { + fn configuration() -> babe_primitives::BabeConfiguration { + let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG); + babe_primitives::BabeConfiguration { + slot_duration: Babe::slot_duration(), + epoch_length: EpochDurationInBlocks::get().into(), + c: epoch_config.c, + authorities: Babe::authorities().to_vec(), + randomness: Babe::randomness(), + allowed_slots: epoch_config.allowed_slots, + } + } + + fn current_epoch_start() -> babe_primitives::Slot { + Babe::current_epoch_start() + } + + fn current_epoch() -> babe_primitives::Epoch { + Babe::current_epoch() + } + + fn next_epoch() -> babe_primitives::Epoch { + Babe::next_epoch() + } + + fn generate_key_ownership_proof( + _slot: babe_primitives::Slot, + authority_id: babe_primitives::AuthorityId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((babe_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(babe_primitives::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: babe_primitives::EquivocationProof<::Header>, + key_owner_proof: babe_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Babe::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + } + + impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + parachains_runtime_api_impl::relevant_authority_ids::() + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Nonce { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< + Block, + Balance, + > for Runtime { + fn query_info(uxt: ::Extrinsic, len: u32) -> RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details(uxt: ::Extrinsic, len: u32) -> FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl pallet_beefy_mmr::BeefyMmrApi for RuntimeApi { + fn authority_set_proof() -> beefy_primitives::mmr::BeefyAuthoritySet { + MmrLeaf::authority_set_proof() + } + + fn next_authority_set_proof() -> beefy_primitives::mmr::BeefyNextAuthoritySet { + MmrLeaf::next_authority_set_proof() + } + } + + #[cfg(feature = "try-runtime")] + impl frame_try_runtime::TryRuntime for Runtime { + fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { + log::info!("try-runtime::on_runtime_upgrade rococo."); + let weight = Executive::try_runtime_upgrade(checks).unwrap(); + (weight, BlockWeights::get().max_block) + } + + fn execute_block( + block: Block, + state_root_check: bool, + signature_check: bool, + select: frame_try_runtime::TryStateSelect, + ) -> Weight { + // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to + // have a backtrace here. + Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap() + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + + use frame_system_benchmarking::Pallet as SystemBench; + use frame_benchmarking::baseline::Pallet as Baseline; + + let mut list = Vec::::new(); + list_benchmarks!(list, extra); + + let storage_info = AllPalletsWithSystem::storage_info(); + return (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig, + ) -> Result< + Vec, + sp_runtime::RuntimeString, + > { + use frame_support::traits::WhitelistedStorageKeys; + use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError}; + use frame_system_benchmarking::Pallet as SystemBench; + use frame_benchmarking::baseline::Pallet as Baseline; + use sp_storage::TrackedStorageKey; + use xcm::latest::prelude::*; + use xcm_config::{ + LocalCheckAccount, LocationConverter, Rockmine, TokenLocation, XcmConfig, + }; + + impl frame_system_benchmarking::Config for Runtime {} + impl frame_benchmarking::baseline::Config for Runtime {} + impl pallet_xcm_benchmarks::Config for Runtime { + type XcmConfig = XcmConfig; + type AccountIdConverter = LocationConverter; + fn valid_destination() -> Result { + Ok(Rockmine::get()) + } + fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + // Rococo only knows about ROC + vec![MultiAsset{ + id: Concrete(TokenLocation::get()), + fun: Fungible(1_000_000 * UNITS), + }].into() + } + } + + parameter_types! { + pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + Rockmine::get(), + MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, + )); + pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + } + + impl pallet_xcm_benchmarks::fungible::Config for Runtime { + type TransactAsset = Balances; + + type CheckedAccount = LocalCheckAccount; + type TrustedTeleporter = TrustedTeleporter; + type TrustedReserve = TrustedReserve; + + fn get_multi_asset() -> MultiAsset { + MultiAsset { + id: Concrete(TokenLocation::get()), + fun: Fungible(1 * UNITS), + } + } + } + + impl pallet_xcm_benchmarks::generic::Config for Runtime { + type RuntimeCall = RuntimeCall; + + fn worst_case_response() -> (u64, Response) { + (0u64, Response::Version(Default::default())) + } + + fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + // Rococo doesn't support asset exchanges + Err(BenchmarkError::Skip) + } + + fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + // The XCM executor of Rococo doesn't have a configured `UniversalAliases` + Err(BenchmarkError::Skip) + } + + fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + Ok((Rockmine::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) + } + + fn subscribe_origin() -> Result { + Ok(Rockmine::get()) + } + + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + let origin = Rockmine::get(); + let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = MultiLocation { parents: 0, interior: Here }; + Ok((origin, ticket, assets)) + } + + fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + // Rococo doesn't support asset locking + Err(BenchmarkError::Skip) + } + + fn export_message_origin_and_destination( + ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + // Rococo doesn't support exporting messages + Err(BenchmarkError::Skip) + } + + fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + // The XCM executor of Rococo doesn't have a configured `Aliasers` + Err(BenchmarkError::Skip) + } + } + + let mut whitelist: Vec = AllPalletsWithSystem::whitelisted_storage_keys(); + let treasury_key = frame_system::Account::::hashed_key_for(Treasury::account_id()); + whitelist.push(treasury_key.to_vec().into()); + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + + add_benchmarks!(params, batches); + + Ok(batches) + } + } +} + +#[cfg(test)] +mod tests { + use std::collections::HashSet; + + use super::*; + use frame_support::traits::WhitelistedStorageKeys; + use sp_core::hexdisplay::HexDisplay; + + #[test] + fn check_whitelist() { + let whitelist: HashSet = AllPalletsWithSystem::whitelisted_storage_keys() + .iter() + .map(|e| HexDisplay::from(&e.key).to_string()) + .collect(); + + // Block number + assert!( + whitelist.contains("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac") + ); + // Total issuance + assert!( + whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80") + ); + // Execution phase + assert!( + whitelist.contains("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a") + ); + // Event count + assert!( + whitelist.contains("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850") + ); + // System events + assert!( + whitelist.contains("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7") + ); + // XcmPallet VersionDiscoveryQueue + assert!( + whitelist.contains("1405f2411d0af5a7ff397e7c9dc68d194a222ba0333561192e474c59ed8e30e1") + ); + // XcmPallet SafeXcmVersion + assert!( + whitelist.contains("1405f2411d0af5a7ff397e7c9dc68d196323ae84c43568be0d1394d5d0d522c4") + ); + } +} + +#[cfg(test)] +mod encoding_tests { + use super::*; + + #[test] + fn nis_hold_reason_encoding_is_correct() { + assert_eq!(RuntimeHoldReason::Nis(pallet_nis::HoldReason::NftReceipt).encode(), [38, 0]); + } +} + +#[cfg(all(test, feature = "try-runtime"))] +mod remote_tests { + use super::*; + use frame_try_runtime::{runtime_decl_for_try_runtime::TryRuntime, UpgradeCheckSelect}; + use remote_externalities::{ + Builder, Mode, OfflineConfig, OnlineConfig, SnapshotConfig, Transport, + }; + use std::env::var; + + #[tokio::test] + async fn run_migrations() { + if var("RUN_MIGRATION_TESTS").is_err() { + return + } + + sp_tracing::try_init_simple(); + let transport: Transport = + var("WS").unwrap_or("wss://rococo-rpc.polkadot.io:443".to_string()).into(); + let maybe_state_snapshot: Option = var("SNAP").map(|s| s.into()).ok(); + let mut ext = Builder::::default() + .mode(if let Some(state_snapshot) = maybe_state_snapshot { + Mode::OfflineOrElseOnline( + OfflineConfig { state_snapshot: state_snapshot.clone() }, + OnlineConfig { + transport, + state_snapshot: Some(state_snapshot), + ..Default::default() + }, + ) + } else { + Mode::Online(OnlineConfig { transport, ..Default::default() }) + }) + .build() + .await + .unwrap(); + ext.execute_with(|| Runtime::on_runtime_upgrade(UpgradeCheckSelect::PreAndPost)); + } +} diff --git a/polkadot/runtime/rococo/src/validator_manager.rs b/polkadot/runtime/rococo/src/validator_manager.rs new file mode 100644 index 0000000000000000000000000000000000000000..0677ba7fbb2b29afda7039ba8b396cb2d66131d8 --- /dev/null +++ b/polkadot/runtime/rococo/src/validator_manager.rs @@ -0,0 +1,143 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A pallet for managing validators on Rococo. + +use sp_staking::SessionIndex; +use sp_std::vec::Vec; + +pub use pallet::*; + +type Session = pallet_session::Pallet; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::{dispatch::DispatchResult, pallet_prelude::*, traits::EnsureOrigin}; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + /// Configuration for the parachain proposer. + #[pallet::config] + pub trait Config: frame_system::Config + pallet_session::Config { + /// The overreaching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// Privileged origin that can add or remove validators. + type PrivilegedOrigin: EnsureOrigin<::RuntimeOrigin>; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// New validators were added to the set. + ValidatorsRegistered(Vec), + /// Validators were removed from the set. + ValidatorsDeregistered(Vec), + } + + /// Validators that should be retired, because their Parachain was deregistered. + #[pallet::storage] + pub(crate) type ValidatorsToRetire = + StorageValue<_, Vec, ValueQuery>; + + /// Validators that should be added. + #[pallet::storage] + pub(crate) type ValidatorsToAdd = StorageValue<_, Vec, ValueQuery>; + + #[pallet::call] + impl Pallet { + /// Add new validators to the set. + /// + /// The new validators will be active from current session + 2. + #[pallet::call_index(0)] + #[pallet::weight({100_000})] + pub fn register_validators( + origin: OriginFor, + validators: Vec, + ) -> DispatchResult { + T::PrivilegedOrigin::ensure_origin(origin)?; + + validators.clone().into_iter().for_each(|v| ValidatorsToAdd::::append(v)); + + Self::deposit_event(Event::ValidatorsRegistered(validators)); + Ok(()) + } + + /// Remove validators from the set. + /// + /// The removed validators will be deactivated from current session + 2. + #[pallet::call_index(1)] + #[pallet::weight({100_000})] + pub fn deregister_validators( + origin: OriginFor, + validators: Vec, + ) -> DispatchResult { + T::PrivilegedOrigin::ensure_origin(origin)?; + + validators.clone().into_iter().for_each(|v| ValidatorsToRetire::::append(v)); + + Self::deposit_event(Event::ValidatorsDeregistered(validators)); + Ok(()) + } + } +} + +impl pallet_session::SessionManager for Pallet { + fn new_session(new_index: SessionIndex) -> Option> { + if new_index <= 1 { + return None + } + + let mut validators = Session::::validators(); + + ValidatorsToRetire::::take().iter().for_each(|v| { + if let Some(pos) = validators.iter().position(|r| r == v) { + validators.swap_remove(pos); + } + }); + + ValidatorsToAdd::::take().into_iter().for_each(|v| { + if !validators.contains(&v) { + validators.push(v); + } + }); + + Some(validators) + } + + fn end_session(_: SessionIndex) {} + + fn start_session(_start_index: SessionIndex) {} +} + +impl pallet_session::historical::SessionManager for Pallet { + fn new_session(new_index: SessionIndex) -> Option> { + >::new_session(new_index) + .map(|r| r.into_iter().map(|v| (v, Default::default())).collect()) + } + + fn start_session(start_index: SessionIndex) { + >::start_session(start_index) + } + + fn end_session(end_index: SessionIndex) { + >::end_session(end_index) + } +} diff --git a/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs b/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs new file mode 100644 index 0000000000000000000000000000000000000000..dfba0cfc4aa90938c70376796117eea9ff00b676 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs @@ -0,0 +1,105 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `frame_benchmarking::baseline` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=frame_benchmarking::baseline +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/frame_benchmarking_baseline.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_benchmarking::baseline`. +pub struct WeightInfo(PhantomData); +impl frame_benchmarking::baseline::WeightInfo for WeightInfo { + /// The range of component `i` is `[0, 1000000]`. + fn addition(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 157_000 picoseconds. + Weight::from_parts(175_233, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 1000000]`. + fn subtraction(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 149_000 picoseconds. + Weight::from_parts(183_285, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 1000000]`. + fn multiplication(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 158_000 picoseconds. + Weight::from_parts(184_720, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 1000000]`. + fn division(_i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 152_000 picoseconds. + Weight::from_parts(177_496, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn hashing() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 19_907_376_000 picoseconds. + Weight::from_parts(19_988_727_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `i` is `[0, 100]`. + fn sr25519_verification(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 198_000 picoseconds. + Weight::from_parts(228_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 20_467 + .saturating_add(Weight::from_parts(47_443_635, 0).saturating_mul(i.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/frame_system.rs b/polkadot/runtime/rococo/src/weights/frame_system.rs new file mode 100644 index 0000000000000000000000000000000000000000..7765d669a577cc110722b4453dfa33b9dbe6bd35 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/frame_system.rs @@ -0,0 +1,144 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `frame_system` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=frame_system +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system`. +pub struct WeightInfo(PhantomData); +impl frame_system::WeightInfo for WeightInfo { + /// The range of component `b` is `[0, 3932160]`. + fn remark(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_283_000 picoseconds. + Weight::from_parts(2_305_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(366, 0).saturating_mul(b.into())) + } + /// The range of component `b` is `[0, 3932160]`. + fn remark_with_event(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_435_000 picoseconds. + Weight::from_parts(7_581_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(1_408, 0).saturating_mul(b.into())) + } + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a686561707061676573` (r:0 w:1) + /// Proof Skipped: unknown `0x3a686561707061676573` (r:0 w:1) + fn set_heap_pages() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1485` + // Minimum execution time: 4_010_000 picoseconds. + Weight::from_parts(4_112_000, 0) + .saturating_add(Weight::from_parts(0, 1485)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a636f6465` (r:0 w:1) + /// Proof Skipped: unknown `0x3a636f6465` (r:0 w:1) + fn set_code() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1485` + // Minimum execution time: 80_405_511_000 picoseconds. + Weight::from_parts(83_066_478_000, 0) + .saturating_add(Weight::from_parts(0, 1485)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 1000]`. + fn set_storage(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_210_000 picoseconds. + Weight::from_parts(2_247_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2_058 + .saturating_add(Weight::from_parts(673_943, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 1000]`. + fn kill_storage(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_125_000 picoseconds. + Weight::from_parts(2_154_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 816 + .saturating_add(Weight::from_parts(491_194, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `p` is `[0, 1000]`. + fn kill_prefix(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `129 + p * (69 ±0)` + // Estimated: `125 + p * (70 ±0)` + // Minimum execution time: 4_002_000 picoseconds. + Weight::from_parts(4_145_000, 0) + .saturating_add(Weight::from_parts(0, 125)) + // Standard Error: 1_108 + .saturating_add(Weight::from_parts(1_014_971, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/mod.rs b/polkadot/runtime/rococo/src/weights/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..21558ca3fb90548f08d90bb79fcea531165d3287 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/mod.rs @@ -0,0 +1,59 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! A list of the different weight modules for our runtime. + +pub mod frame_system; +pub mod pallet_balances; +pub mod pallet_balances_nis_counterpart_balances; +pub mod pallet_bounties; +pub mod pallet_child_bounties; +pub mod pallet_collective_council; +pub mod pallet_collective_technical_committee; +pub mod pallet_democracy; +pub mod pallet_elections_phragmen; +pub mod pallet_identity; +pub mod pallet_im_online; +pub mod pallet_indices; +pub mod pallet_membership; +pub mod pallet_message_queue; +pub mod pallet_multisig; +pub mod pallet_nis; +pub mod pallet_preimage; +pub mod pallet_proxy; +pub mod pallet_scheduler; +pub mod pallet_session; +pub mod pallet_sudo; +pub mod pallet_timestamp; +pub mod pallet_tips; +pub mod pallet_treasury; +pub mod pallet_utility; +pub mod pallet_vesting; +pub mod pallet_xcm; +pub mod runtime_common_assigned_slots; +pub mod runtime_common_auctions; +pub mod runtime_common_claims; +pub mod runtime_common_crowdloan; +pub mod runtime_common_paras_registrar; +pub mod runtime_common_slots; +pub mod runtime_parachains_assigner_on_demand; +pub mod runtime_parachains_configuration; +pub mod runtime_parachains_disputes; +pub mod runtime_parachains_hrmp; +pub mod runtime_parachains_inclusion; +pub mod runtime_parachains_initializer; +pub mod runtime_parachains_paras; +pub mod runtime_parachains_paras_inherent; +pub mod xcm; diff --git a/polkadot/runtime/rococo/src/weights/pallet_balances.rs b/polkadot/runtime/rococo/src/weights/pallet_balances.rs new file mode 100644 index 0000000000000000000000000000000000000000..972c097372f4bf75c5891f575cb4ebd0ec59b8f2 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_balances.rs @@ -0,0 +1,99 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +//! Autogenerated weights for `pallet_balances` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-11-16, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `bm6`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_balances +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `pallet_balances`. +pub struct WeightInfo(PhantomData); +impl pallet_balances::WeightInfo for WeightInfo { + // Storage: System Account (r:1 w:1) + fn transfer_allow_death() -> Weight { + // Minimum execution time: 40_106 nanoseconds. + Weight::from_parts(40_750_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_keep_alive() -> Weight { + // Minimum execution time: 30_737 nanoseconds. + Weight::from_parts(31_295_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn force_set_balance_creating() -> Weight { + // Minimum execution time: 23_902 nanoseconds. + Weight::from_parts(24_338_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn force_set_balance_killing() -> Weight { + // Minimum execution time: 26_492 nanoseconds. + Weight::from_parts(26_866_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:2 w:2) + fn force_transfer() -> Weight { + // Minimum execution time: 40_384 nanoseconds. + Weight::from_parts(41_000_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(2 as u64)) + .saturating_add(T::DbWeight::get().writes(2 as u64)) + } + // Storage: System Account (r:1 w:1) + fn transfer_all() -> Weight { + // Minimum execution time: 35_115 nanoseconds. + Weight::from_parts(35_696_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: System Account (r:1 w:1) + fn force_unreserve() -> Weight { + // Minimum execution time: 20_274 nanoseconds. + Weight::from_parts(20_885_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + fn upgrade_accounts(_: u32) -> Weight { + Weight::from_parts(0, 0) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs b/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs new file mode 100644 index 0000000000000000000000000000000000000000..597a67de4b99d7d67e2e221a3b1a905427339254 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs @@ -0,0 +1,175 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_balances` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_balances +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_balances`. +pub struct WeightInfo(PhantomData); +impl pallet_balances::WeightInfo for WeightInfo { + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:2 w:2) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_allow_death() -> Weight { + // Proof Size summary in bytes: + // Measured: `219` + // Estimated: `6164` + // Minimum execution time: 54_122_000 picoseconds. + Weight::from_parts(54_834_000, 0) + .saturating_add(Weight::from_parts(0, 6164)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:0) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:2 w:2) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_keep_alive() -> Weight { + // Proof Size summary in bytes: + // Measured: `219` + // Estimated: `6164` + // Minimum execution time: 41_749_000 picoseconds. + Weight::from_parts(42_193_000, 0) + .saturating_add(Weight::from_parts(0, 6164)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + fn force_set_balance_creating() -> Weight { + // Proof Size summary in bytes: + // Measured: `217` + // Estimated: `3577` + // Minimum execution time: 16_008_000 picoseconds. + Weight::from_parts(16_328_000, 0) + .saturating_add(Weight::from_parts(0, 3577)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + fn force_set_balance_killing() -> Weight { + // Proof Size summary in bytes: + // Measured: `393` + // Estimated: `3593` + // Minimum execution time: 26_277_000 picoseconds. + Weight::from_parts(26_932_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:2 w:2) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `322` + // Estimated: `6196` + // Minimum execution time: 57_020_000 picoseconds. + Weight::from_parts(57_661_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: NisCounterpartBalances Account (r:2 w:2) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:0) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_all() -> Weight { + // Proof Size summary in bytes: + // Measured: `219` + // Estimated: `6164` + // Minimum execution time: 50_630_000 picoseconds. + Weight::from_parts(51_191_000, 0) + .saturating_add(Weight::from_parts(0, 6164)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_unreserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `391` + // Estimated: `3593` + // Minimum execution time: 21_915_000 picoseconds. + Weight::from_parts(22_295_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: NisCounterpartBalances Account (r:999 w:999) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: System Account (r:999 w:999) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `u` is `[1, 1000]`. + /// The range of component `u` is `[1, 1000]`. + fn upgrade_accounts(u: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + u * (256 ±0)` + // Estimated: `990 + u * (2603 ±0)` + // Minimum execution time: 21_290_000 picoseconds. + Weight::from_parts(21_622_000, 0) + .saturating_add(Weight::from_parts(0, 990)) + // Standard Error: 13_372 + .saturating_add(Weight::from_parts(15_527_611, 0).saturating_mul(u.into())) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(u.into()))) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(u.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_bounties.rs b/polkadot/runtime/rococo/src/weights/pallet_bounties.rs new file mode 100644 index 0000000000000000000000000000000000000000..38d3645316f25faba74fff9d37c66db2ab4f08d9 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_bounties.rs @@ -0,0 +1,164 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_bounties` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_bounties +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bounties`. +pub struct WeightInfo(PhantomData); +impl pallet_bounties::WeightInfo for WeightInfo { + /// Storage: Bounties BountyCount (r:1 w:1) + /// Proof: Bounties BountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:0 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// The range of component `d` is `[0, 16384]`. + fn propose_bounty(d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `210` + // Estimated: `3593` + // Minimum execution time: 28_907_000 picoseconds. + Weight::from_parts(31_356_074, 0) + .saturating_add(Weight::from_parts(0, 3593)) + // Standard Error: 18 + .saturating_add(Weight::from_parts(606, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + fn approve_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn propose_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn unassign_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn accept_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn award_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn claim_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + fn close_bounty_proposed() -> Weight { + // Proof Size summary in bytes: + // Measured: `482` + // Estimated: `3642` + // Minimum execution time: 46_020_000 picoseconds. + Weight::from_parts(46_711_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + fn close_bounty_active() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn extend_bounty_expiry() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// The range of component `b` is `[0, 100]`. + fn spend_funds(_b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1887` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(2_405_233, 0) + .saturating_add(Weight::from_parts(0, 1887)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs b/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs new file mode 100644 index 0000000000000000000000000000000000000000..e8c798d45e727618b892e4ebd7e11d7ba81f66ca --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs @@ -0,0 +1,115 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_child_bounties` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_child_bounties +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_child_bounties`. +pub struct WeightInfo(PhantomData); +impl pallet_child_bounties::WeightInfo for WeightInfo { + /// The range of component `d` is `[0, 16384]`. + fn add_child_bounty(_d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn propose_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn accept_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn unassign_curator() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn award_child_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn claim_child_bounty() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn close_child_bounty_added() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn close_child_bounty_active() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_collective.rs b/polkadot/runtime/rococo/src/weights/pallet_collective.rs new file mode 100644 index 0000000000000000000000000000000000000000..9bf6671e2297112790655e99037f0ab412556ddc --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_collective.rs @@ -0,0 +1,196 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +//! Autogenerated weights for `pallet_collective` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-09-08, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_collective +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight}}; +use sp_std::marker::PhantomData; + +/// Weight functions for `pallet_collective`. +pub struct WeightInfo(PhantomData); +impl pallet_collective::WeightInfo for WeightInfo { + // Storage: Collective Members (r:1 w:1) + // Storage: Collective Proposals (r:1 w:0) + // Storage: Collective Voting (r:100 w:100) + // Storage: Collective Prime (r:0 w:1) + /// The range of component `m` is `[1, 100]`. + /// The range of component `n` is `[1, 100]`. + /// The range of component `p` is `[1, 100]`. + fn set_members(m: u32, _n: u32, p: u32, ) -> Weight { + Weight::from_parts(0 as u64, 0) + // Standard Error: 15_000 + .saturating_add(Weight::from_parts(10_832_000 as u64, 0).saturating_mul(m as u64)) + // Standard Error: 15_000 + .saturating_add(Weight::from_parts(12_894_000 as u64, 0).saturating_mul(p as u64)) + .saturating_add(T::DbWeight::get().reads(2 as u64)) + .saturating_add(T::DbWeight::get().reads((1 as u64).saturating_mul(p as u64))) + .saturating_add(T::DbWeight::get().writes(2 as u64)) + .saturating_add(T::DbWeight::get().writes((1 as u64).saturating_mul(p as u64))) + } + // Storage: Collective Members (r:1 w:0) + /// The range of component `b` is `[1, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn execute(b: u32, m: u32, ) -> Weight { + Weight::from_parts(19_069_000 as u64, 0) + // Standard Error: 0 + .saturating_add(Weight::from_parts(2_000 as u64, 0).saturating_mul(b as u64)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(13_000 as u64, 0).saturating_mul(m as u64)) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + } + // Storage: Collective Members (r:1 w:0) + // Storage: Collective ProposalOf (r:1 w:0) + /// The range of component `b` is `[1, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn propose_execute(b: u32, m: u32, ) -> Weight { + Weight::from_parts(20_794_000 as u64, 0) + // Standard Error: 0 + .saturating_add(Weight::from_parts(2_000 as u64, 0).saturating_mul(b as u64)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(22_000 as u64, 0).saturating_mul(m as u64)) + .saturating_add(T::DbWeight::get().reads(2 as u64)) + } + // Storage: Collective Members (r:1 w:0) + // Storage: Collective ProposalOf (r:1 w:1) + // Storage: Collective Proposals (r:1 w:1) + // Storage: Collective ProposalCount (r:1 w:1) + // Storage: Collective Voting (r:0 w:1) + /// The range of component `b` is `[1, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { + Weight::from_parts(27_870_000 as u64, 0) + // Standard Error: 0 + .saturating_add(Weight::from_parts(3_000 as u64, 0).saturating_mul(b as u64)) + // Standard Error: 1_000 + .saturating_add(Weight::from_parts(22_000 as u64, 0).saturating_mul(m as u64)) + // Standard Error: 1_000 + .saturating_add(Weight::from_parts(94_000 as u64, 0).saturating_mul(p as u64)) + .saturating_add(T::DbWeight::get().reads(4 as u64)) + .saturating_add(T::DbWeight::get().writes(4 as u64)) + } + // Storage: Collective Members (r:1 w:0) + // Storage: Collective Voting (r:1 w:1) + /// The range of component `m` is `[5, 100]`. + fn vote(m: u32, ) -> Weight { + Weight::from_parts(27_249_000 as u64, 0) + // Standard Error: 0 + .saturating_add(Weight::from_parts(35_000 as u64, 0).saturating_mul(m as u64)) + .saturating_add(T::DbWeight::get().reads(2 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + // Storage: Collective Voting (r:1 w:1) + // Storage: Collective Members (r:1 w:0) + // Storage: Collective Proposals (r:1 w:1) + // Storage: Collective ProposalOf (r:0 w:1) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_disapproved(m: u32, p: u32, ) -> Weight { + Weight::from_parts(30_754_000 as u64, 0) + // Standard Error: 0 + .saturating_add(Weight::from_parts(28_000 as u64, 0).saturating_mul(m as u64)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(81_000 as u64, 0).saturating_mul(p as u64)) + .saturating_add(T::DbWeight::get().reads(3 as u64)) + .saturating_add(T::DbWeight::get().writes(3 as u64)) + } + // Storage: Collective Voting (r:1 w:1) + // Storage: Collective Members (r:1 w:0) + // Storage: Collective ProposalOf (r:1 w:1) + // Storage: Collective Proposals (r:1 w:1) + /// The range of component `b` is `[1, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { + Weight::from_parts(39_508_000 as u64, 0) + // Standard Error: 0 + .saturating_add(Weight::from_parts(1_000 as u64, 0).saturating_mul(b as u64)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(29_000 as u64, 0).saturating_mul(m as u64)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(90_000 as u64, 0).saturating_mul(p as u64)) + .saturating_add(T::DbWeight::get().reads(4 as u64)) + .saturating_add(T::DbWeight::get().writes(3 as u64)) + } + // Storage: Collective Voting (r:1 w:1) + // Storage: Collective Members (r:1 w:0) + // Storage: Collective Prime (r:1 w:0) + // Storage: Collective Proposals (r:1 w:1) + // Storage: Collective ProposalOf (r:0 w:1) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_disapproved(m: u32, p: u32, ) -> Weight { + Weight::from_parts(32_769_000 as u64, 0) + // Standard Error: 0 + .saturating_add(Weight::from_parts(31_000 as u64, 0).saturating_mul(m as u64)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(83_000 as u64, 0).saturating_mul(p as u64)) + .saturating_add(T::DbWeight::get().reads(4 as u64)) + .saturating_add(T::DbWeight::get().writes(3 as u64)) + } + // Storage: Collective Voting (r:1 w:1) + // Storage: Collective Members (r:1 w:0) + // Storage: Collective Prime (r:1 w:0) + // Storage: Collective ProposalOf (r:1 w:1) + // Storage: Collective Proposals (r:1 w:1) + /// The range of component `b` is `[1, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { + Weight::from_parts(41_704_000 as u64, 0) + // Standard Error: 0 + .saturating_add(Weight::from_parts(1_000 as u64, 0).saturating_mul(b as u64)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(28_000 as u64, 0).saturating_mul(m as u64)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(92_000 as u64, 0).saturating_mul(p as u64)) + .saturating_add(T::DbWeight::get().reads(5 as u64)) + .saturating_add(T::DbWeight::get().writes(3 as u64)) + } + // Storage: Collective Proposals (r:1 w:1) + // Storage: Collective Voting (r:0 w:1) + // Storage: Collective ProposalOf (r:0 w:1) + /// The range of component `p` is `[1, 100]`. + fn disapprove_proposal(p: u32, ) -> Weight { + Weight::from_parts(22_720_000 as u64, 0) + // Standard Error: 2_000 + .saturating_add(Weight::from_parts(74_000 as u64, 0).saturating_mul(p as u64)) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(3 as u64)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_collective_council.rs b/polkadot/runtime/rococo/src/weights/pallet_collective_council.rs new file mode 100644 index 0000000000000000000000000000000000000000..835bdef7e67387d97edd1e7004a4a5d454711960 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_collective_council.rs @@ -0,0 +1,322 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_collective` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_collective +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_collective`. +pub struct WeightInfo(PhantomData); +impl pallet_collective::WeightInfo for WeightInfo { + /// Storage: Council Members (r:1 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:100 w:100) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Prime (r:0 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + fn set_members(m: u32, _n: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + m * (3232 ±0) + p * (3190 ±0)` + // Estimated: `15795 + m * (1967 ±16) + p * (4332 ±16)` + // Minimum execution time: 17_182_000 picoseconds. + Weight::from_parts(17_462_000, 0) + .saturating_add(Weight::from_parts(0, 15795)) + // Standard Error: 42_032 + .saturating_add(Weight::from_parts(4_868_618, 0).saturating_mul(m.into())) + // Standard Error: 42_032 + .saturating_add(Weight::from_parts(7_289_594, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 1967).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 4332).saturating_mul(p.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `136 + m * (32 ±0)` + // Estimated: `1622 + m * (32 ±0)` + // Minimum execution time: 16_507_000 picoseconds. + Weight::from_parts(16_066_632, 0) + .saturating_add(Weight::from_parts(0, 1622)) + // Standard Error: 21 + .saturating_add(Weight::from_parts(982, 0).saturating_mul(b.into())) + // Standard Error: 220 + .saturating_add(Weight::from_parts(14_026, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:0) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn propose_execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `136 + m * (32 ±0)` + // Estimated: `3602 + m * (32 ±0)` + // Minimum execution time: 18_990_000 picoseconds. + Weight::from_parts(18_411_713, 0) + .saturating_add(Weight::from_parts(0, 3602)) + // Standard Error: 15 + .saturating_add(Weight::from_parts(1_166, 0).saturating_mul(b.into())) + // Standard Error: 164 + .saturating_add(Weight::from_parts(23_067, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalCount (r:1 w:1) + /// Proof Skipped: Council ProposalCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:0 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `426 + m * (32 ±0) + p * (36 ±0)` + // Estimated: `3818 + m * (33 ±0) + p * (36 ±0)` + // Minimum execution time: 25_500_000 picoseconds. + Weight::from_parts(26_304_307, 0) + .saturating_add(Weight::from_parts(0, 3818)) + // Standard Error: 49 + .saturating_add(Weight::from_parts(2_243, 0).saturating_mul(b.into())) + // Standard Error: 515 + .saturating_add(Weight::from_parts(18_905, 0).saturating_mul(m.into())) + // Standard Error: 508 + .saturating_add(Weight::from_parts(120_761, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 33).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[5, 100]`. + /// The range of component `m` is `[5, 100]`. + fn vote(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `875 + m * (64 ±0)` + // Estimated: `4339 + m * (64 ±0)` + // Minimum execution time: 22_166_000 picoseconds. + Weight::from_parts(22_901_859, 0) + .saturating_add(Weight::from_parts(0, 4339)) + // Standard Error: 238 + .saturating_add(Weight::from_parts(40_475, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `464 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3909 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 27_064_000 picoseconds. + Weight::from_parts(27_961_599, 0) + .saturating_add(Weight::from_parts(0, 3909)) + // Standard Error: 401 + .saturating_add(Weight::from_parts(22_196, 0).saturating_mul(m.into())) + // Standard Error: 391 + .saturating_add(Weight::from_parts(115_698, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `766 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4083 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 38_302_000 picoseconds. + Weight::from_parts(40_639_640, 0) + .saturating_add(Weight::from_parts(0, 4083)) + // Standard Error: 123 + .saturating_add(Weight::from_parts(1_914, 0).saturating_mul(b.into())) + // Standard Error: 1_272 + .saturating_add(Weight::from_parts(150_067, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:0) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `484 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3929 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 30_017_000 picoseconds. + Weight::from_parts(30_565_580, 0) + .saturating_add(Weight::from_parts(0, 3929)) + // Standard Error: 378 + .saturating_add(Weight::from_parts(24_396, 0).saturating_mul(m.into())) + // Standard Error: 369 + .saturating_add(Weight::from_parts(114_807, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:0) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `786 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4103 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 40_911_000 picoseconds. + Weight::from_parts(42_312_485, 0) + .saturating_add(Weight::from_parts(0, 4103)) + // Standard Error: 83 + .saturating_add(Weight::from_parts(2_208, 0).saturating_mul(b.into())) + // Standard Error: 879 + .saturating_add(Weight::from_parts(20_173, 0).saturating_mul(m.into())) + // Standard Error: 857 + .saturating_add(Weight::from_parts(146_302, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) + } + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:0 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `p` is `[1, 100]`. + /// The range of component `p` is `[1, 100]`. + fn disapprove_proposal(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `293 + p * (32 ±0)` + // Estimated: `1778 + p * (32 ±0)` + // Minimum execution time: 15_465_000 picoseconds. + Weight::from_parts(17_387_663, 0) + .saturating_add(Weight::from_parts(0, 1778)) + // Standard Error: 450 + .saturating_add(Weight::from_parts(110_406, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_collective_technical_committee.rs b/polkadot/runtime/rococo/src/weights/pallet_collective_technical_committee.rs new file mode 100644 index 0000000000000000000000000000000000000000..6d66dc871cd54edcd9c846fc0a3e059d1f8a42ce --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_collective_technical_committee.rs @@ -0,0 +1,324 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_collective` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_collective +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_collective`. +pub struct WeightInfo(PhantomData); +impl pallet_collective::WeightInfo for WeightInfo { + /// Storage: TechnicalCommittee Members (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:100 w:100) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + /// The range of component `m` is `[0, 100]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `p` is `[0, 100]`. + fn set_members(m: u32, _n: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + m * (3232 ±0) + p * (3190 ±0)` + // Estimated: `15766 + m * (1967 ±16) + p * (4332 ±16)` + // Minimum execution time: 17_826_000 picoseconds. + Weight::from_parts(18_046_000, 0) + .saturating_add(Weight::from_parts(0, 15766)) + // Standard Error: 42_164 + .saturating_add(Weight::from_parts(4_858_188, 0).saturating_mul(m.into())) + // Standard Error: 42_164 + .saturating_add(Weight::from_parts(7_379_354, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 1967).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 4332).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `107 + m * (32 ±0)` + // Estimated: `1593 + m * (32 ±0)` + // Minimum execution time: 16_992_000 picoseconds. + Weight::from_parts(16_555_669, 0) + .saturating_add(Weight::from_parts(0, 1593)) + // Standard Error: 18 + .saturating_add(Weight::from_parts(976, 0).saturating_mul(b.into())) + // Standard Error: 189 + .saturating_add(Weight::from_parts(12_101, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:0) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[1, 100]`. + fn propose_execute(b: u32, m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `107 + m * (32 ±0)` + // Estimated: `3573 + m * (32 ±0)` + // Minimum execution time: 19_900_000 picoseconds. + Weight::from_parts(19_068_072, 0) + .saturating_add(Weight::from_parts(0, 3573)) + // Standard Error: 12 + .saturating_add(Weight::from_parts(1_161, 0).saturating_mul(b.into())) + // Standard Error: 129 + .saturating_add(Weight::from_parts(22_376, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalCount (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[2, 100]`. + /// The range of component `p` is `[1, 100]`. + fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `397 + m * (32 ±0) + p * (36 ±0)` + // Estimated: `3789 + m * (33 ±0) + p * (36 ±0)` + // Minimum execution time: 26_264_000 picoseconds. + Weight::from_parts(27_099_606, 0) + .saturating_add(Weight::from_parts(0, 3789)) + // Standard Error: 50 + .saturating_add(Weight::from_parts(2_278, 0).saturating_mul(b.into())) + // Standard Error: 525 + .saturating_add(Weight::from_parts(19_424, 0).saturating_mul(m.into())) + // Standard Error: 519 + .saturating_add(Weight::from_parts(120_852, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 33).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[5, 100]`. + /// The range of component `m` is `[5, 100]`. + fn vote(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `846 + m * (64 ±0)` + // Estimated: `4310 + m * (64 ±0)` + // Minimum execution time: 22_954_000 picoseconds. + Weight::from_parts(23_675_214, 0) + .saturating_add(Weight::from_parts(0, 4310)) + // Standard Error: 256 + .saturating_add(Weight::from_parts(40_562, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:0 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `435 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3880 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 27_797_000 picoseconds. + Weight::from_parts(28_934_600, 0) + .saturating_add(Weight::from_parts(0, 3880)) + // Standard Error: 374 + .saturating_add(Weight::from_parts(20_716, 0).saturating_mul(m.into())) + // Standard Error: 364 + .saturating_add(Weight::from_parts(115_491, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `737 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4054 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 39_160_000 picoseconds. + Weight::from_parts(40_470_419, 0) + .saturating_add(Weight::from_parts(0, 4054)) + // Standard Error: 82 + .saturating_add(Weight::from_parts(2_146, 0).saturating_mul(b.into())) + // Standard Error: 869 + .saturating_add(Weight::from_parts(21_442, 0).saturating_mul(m.into())) + // Standard Error: 847 + .saturating_add(Weight::from_parts(144_479, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:0 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_disapproved(m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `455 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3900 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 30_953_000 picoseconds. + Weight::from_parts(31_427_489, 0) + .saturating_add(Weight::from_parts(0, 3900)) + // Standard Error: 397 + .saturating_add(Weight::from_parts(24_280, 0).saturating_mul(m.into())) + // Standard Error: 387 + .saturating_add(Weight::from_parts(116_864, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Voting (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:1 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + /// The range of component `b` is `[2, 1024]`. + /// The range of component `m` is `[4, 100]`. + /// The range of component `p` is `[1, 100]`. + fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `757 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4074 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 41_468_000 picoseconds. + Weight::from_parts(43_538_242, 0) + .saturating_add(Weight::from_parts(0, 4074)) + // Standard Error: 80 + .saturating_add(Weight::from_parts(1_994, 0).saturating_mul(b.into())) + // Standard Error: 853 + .saturating_add(Weight::from_parts(19_637, 0).saturating_mul(m.into())) + // Standard Error: 831 + .saturating_add(Weight::from_parts(144_674, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) + } + /// Storage: TechnicalCommittee Proposals (r:1 w:1) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Voting (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: TechnicalCommittee ProposalOf (r:0 w:1) + /// Proof Skipped: TechnicalCommittee ProposalOf (max_values: None, max_size: None, mode: Measured) + /// The range of component `p` is `[1, 100]`. + /// The range of component `p` is `[1, 100]`. + fn disapprove_proposal(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `264 + p * (32 ±0)` + // Estimated: `1749 + p * (32 ±0)` + // Minimum execution time: 15_998_000 picoseconds. + Weight::from_parts(17_837_641, 0) + .saturating_add(Weight::from_parts(0, 1749)) + // Standard Error: 422 + .saturating_add(Weight::from_parts(111_526, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_democracy.rs b/polkadot/runtime/rococo/src/weights/pallet_democracy.rs new file mode 100644 index 0000000000000000000000000000000000000000..00629a5c1103cba6813566097b9590104e712347 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_democracy.rs @@ -0,0 +1,525 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_democracy` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_democracy +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_democracy`. +pub struct WeightInfo(PhantomData); +impl pallet_democracy::WeightInfo for WeightInfo { + /// Storage: Democracy PublicPropCount (r:1 w:1) + /// Proof: Democracy PublicPropCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:0) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:0 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + fn propose() -> Weight { + // Proof Size summary in bytes: + // Measured: `4734` + // Estimated: `18187` + // Minimum execution time: 39_492_000 picoseconds. + Weight::from_parts(39_853_000, 0) + .saturating_add(Weight::from_parts(0, 18187)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + fn second() -> Weight { + // Proof Size summary in bytes: + // Measured: `3489` + // Estimated: `6695` + // Minimum execution time: 36_683_000 picoseconds. + Weight::from_parts(37_121_000, 0) + .saturating_add(Weight::from_parts(0, 6695)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + fn vote_new() -> Weight { + // Proof Size summary in bytes: + // Measured: `3365` + // Estimated: `7260` + // Minimum execution time: 48_191_000 picoseconds. + Weight::from_parts(48_936_000, 0) + .saturating_add(Weight::from_parts(0, 7260)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + fn vote_existing() -> Weight { + // Proof Size summary in bytes: + // Measured: `3387` + // Estimated: `7260` + // Minimum execution time: 52_175_000 picoseconds. + Weight::from_parts(53_011_000, 0) + .saturating_add(Weight::from_parts(0, 7260)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy Cancellations (r:1 w:1) + /// Proof: Democracy Cancellations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn emergency_cancel() -> Weight { + // Proof Size summary in bytes: + // Measured: `299` + // Estimated: `3666` + // Minimum execution time: 26_255_000 picoseconds. + Weight::from_parts(26_768_000, 0) + .saturating_add(Weight::from_parts(0, 3666)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:3 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:0 w:1) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + fn blacklist() -> Weight { + // Proof Size summary in bytes: + // Measured: `5843` + // Estimated: `18187` + // Minimum execution time: 96_376_000 picoseconds. + Weight::from_parts(97_222_000, 0) + .saturating_add(Weight::from_parts(0, 18187)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:0) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + fn external_propose() -> Weight { + // Proof Size summary in bytes: + // Measured: `3349` + // Estimated: `6703` + // Minimum execution time: 13_815_000 picoseconds. + Weight::from_parts(14_071_000, 0) + .saturating_add(Weight::from_parts(0, 6703)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:0 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + fn external_propose_majority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_456_000 picoseconds. + Weight::from_parts(3_716_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:0 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + fn external_propose_default() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_610_000 picoseconds. + Weight::from_parts(3_768_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:1) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:2) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:0 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + fn fast_track() -> Weight { + // Proof Size summary in bytes: + // Measured: `219` + // Estimated: `3518` + // Minimum execution time: 27_514_000 picoseconds. + Weight::from_parts(27_905_000, 0) + .saturating_add(Weight::from_parts(0, 3518)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:1) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn veto_external() -> Weight { + // Proof Size summary in bytes: + // Measured: `3452` + // Estimated: `6703` + // Minimum execution time: 31_250_000 picoseconds. + Weight::from_parts(31_604_000, 0) + .saturating_add(Weight::from_parts(0, 6703)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn cancel_proposal() -> Weight { + // Proof Size summary in bytes: + // Measured: `5754` + // Estimated: `18187` + // Minimum execution time: 79_757_000 picoseconds. + Weight::from_parts(83_603_000, 0) + .saturating_add(Weight::from_parts(0, 18187)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:0 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + fn cancel_referendum() -> Weight { + // Proof Size summary in bytes: + // Measured: `204` + // Estimated: `3518` + // Minimum execution time: 20_034_000 picoseconds. + Weight::from_parts(20_674_000, 0) + .saturating_add(Weight::from_parts(0, 3518)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Democracy LowestUnbaked (r:1 w:1) + /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:0) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn on_initialize_base(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `177 + r * (86 ±0)` + // Estimated: `1489 + r * (2676 ±0)` + // Minimum execution time: 7_053_000 picoseconds. + Weight::from_parts(10_157_848, 0) + .saturating_add(Weight::from_parts(0, 1489)) + // Standard Error: 5_462 + .saturating_add(Weight::from_parts(2_710_889, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy LowestUnbaked (r:1 w:1) + /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:0) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy LastTabledWasExternal (r:1 w:0) + /// Proof: Democracy LastTabledWasExternal (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn on_initialize_base_with_launch_period(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `177 + r * (86 ±0)` + // Estimated: `18187 + r * (2676 ±0)` + // Minimum execution time: 9_585_000 picoseconds. + Weight::from_parts(13_021_372, 0) + .saturating_add(Weight::from_parts(0, 18187)) + // Standard Error: 6_031 + .saturating_add(Weight::from_parts(2_707_449, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy VotingOf (r:3 w:3) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:99) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn delegate(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `729 + r * (108 ±0)` + // Estimated: `19800 + r * (2676 ±0)` + // Minimum execution time: 41_109_000 picoseconds. + Weight::from_parts(46_477_334, 0) + .saturating_add(Weight::from_parts(0, 19800)) + // Standard Error: 9_372 + .saturating_add(Weight::from_parts(3_815_232, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy VotingOf (r:2 w:2) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:99) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn undelegate(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `426 + r * (108 ±0)` + // Estimated: `13530 + r * (2676 ±0)` + // Minimum execution time: 21_283_000 picoseconds. + Weight::from_parts(23_372_139, 0) + .saturating_add(Weight::from_parts(0, 13530)) + // Standard Error: 6_191 + .saturating_add(Weight::from_parts(3_768_585, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) + } + /// Storage: Democracy PublicProps (r:0 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + fn clear_public_proposals() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_510_000 picoseconds. + Weight::from_parts(3_642_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn unlock_remove(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `458` + // Estimated: `7260` + // Minimum execution time: 23_647_000 picoseconds. + Weight::from_parts(36_627_552, 0) + .saturating_add(Weight::from_parts(0, 7260)) + // Standard Error: 2_937 + .saturating_add(Weight::from_parts(34_132, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `r` is `[0, 99]`. + fn unlock_set(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `459 + r * (22 ±0)` + // Estimated: `7260` + // Minimum execution time: 33_932_000 picoseconds. + Weight::from_parts(35_331_660, 0) + .saturating_add(Weight::from_parts(0, 7260)) + // Standard Error: 615 + .saturating_add(Weight::from_parts(60_730, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 100]`. + fn remove_vote(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `661 + r * (26 ±0)` + // Estimated: `7260` + // Minimum execution time: 16_605_000 picoseconds. + Weight::from_parts(19_057_092, 0) + .saturating_add(Weight::from_parts(0, 7260)) + // Standard Error: 873 + .saturating_add(Weight::from_parts(68_964, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 100]`. + fn remove_other_vote(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `661 + r * (26 ±0)` + // Estimated: `7260` + // Minimum execution time: 16_801_000 picoseconds. + Weight::from_parts(19_166_788, 0) + .saturating_add(Weight::from_parts(0, 7260)) + // Standard Error: 1_008 + .saturating_add(Weight::from_parts(69_851, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn set_external_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `361` + // Estimated: `3556` + // Minimum execution time: 19_207_000 picoseconds. + Weight::from_parts(19_693_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn clear_external_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `219` + // Estimated: `3518` + // Minimum execution time: 17_333_000 picoseconds. + Weight::from_parts(17_555_000, 0) + .saturating_add(Weight::from_parts(0, 3518)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn set_proposal_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `4893` + // Estimated: `18187` + // Minimum execution time: 33_859_000 picoseconds. + Weight::from_parts(34_538_000, 0) + .saturating_add(Weight::from_parts(0, 18187)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn clear_proposal_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `4755` + // Estimated: `18187` + // Minimum execution time: 31_155_000 picoseconds. + Weight::from_parts(31_520_000, 0) + .saturating_add(Weight::from_parts(0, 18187)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn set_referendum_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `216` + // Estimated: `3556` + // Minimum execution time: 15_924_000 picoseconds. + Weight::from_parts(16_151_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Democracy ReferendumInfoOf (r:1 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + fn clear_referendum_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `235` + // Estimated: `3666` + // Minimum execution time: 18_983_000 picoseconds. + Weight::from_parts(19_280_000, 0) + .saturating_add(Weight::from_parts(0, 3666)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_elections_phragmen.rs b/polkadot/runtime/rococo/src/weights/pallet_elections_phragmen.rs new file mode 100644 index 0000000000000000000000000000000000000000..fe6aca5ab881d457ac8c40c8191f655a43261bb2 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_elections_phragmen.rs @@ -0,0 +1,315 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_elections_phragmen` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_elections_phragmen +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_elections_phragmen`. +pub struct WeightInfo(PhantomData); +impl pallet_elections_phragmen::WeightInfo for WeightInfo { + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// The range of component `v` is `[1, 16]`. + fn vote_equal(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `331 + v * (80 ±0)` + // Estimated: `4764 + v * (80 ±0)` + // Minimum execution time: 30_910_000 picoseconds. + Weight::from_parts(31_851_802, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 4_099 + .saturating_add(Weight::from_parts(137_675, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// The range of component `v` is `[2, 16]`. + fn vote_more(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `299 + v * (80 ±0)` + // Estimated: `4764 + v * (80 ±0)` + // Minimum execution time: 42_670_000 picoseconds. + Weight::from_parts(43_351_345, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_986 + .saturating_add(Weight::from_parts(142_231, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// The range of component `v` is `[2, 16]`. + fn vote_less(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `331 + v * (80 ±0)` + // Estimated: `4764 + v * (80 ±0)` + // Minimum execution time: 42_782_000 picoseconds. + Weight::from_parts(43_611_866, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_968 + .saturating_add(Weight::from_parts(125_939, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Voting (r:1 w:1) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + fn remove_voter() -> Weight { + // Proof Size summary in bytes: + // Measured: `853` + // Estimated: `4764` + // Minimum execution time: 44_301_000 picoseconds. + Weight::from_parts(44_843_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: PhragmenElection Candidates (r:1 w:1) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `c` is `[1, 1000]`. + fn submit_candidacy(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2678 + c * (48 ±0)` + // Estimated: `4161 + c * (48 ±0)` + // Minimum execution time: 33_576_000 picoseconds. + Weight::from_parts(26_859_487, 0) + .saturating_add(Weight::from_parts(0, 4161)) + // Standard Error: 854 + .saturating_add(Weight::from_parts(81_887, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:1) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `c` is `[1, 1000]`. + fn renounce_candidacy_candidate(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `250 + c * (48 ±0)` + // Estimated: `1722 + c * (48 ±0)` + // Minimum execution time: 29_671_000 picoseconds. + Weight::from_parts(22_509_800, 0) + .saturating_add(Weight::from_parts(0, 1722)) + // Standard Error: 908 + .saturating_add(Weight::from_parts(58_320, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) + } + /// Storage: PhragmenElection Members (r:1 w:1) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + fn renounce_candidacy_members() -> Weight { + // Proof Size summary in bytes: + // Measured: `2952` + // Estimated: `4437` + // Minimum execution time: 45_934_000 picoseconds. + Weight::from_parts(46_279_000, 0) + .saturating_add(Weight::from_parts(0, 4437)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + fn renounce_candidacy_runners_up() -> Weight { + // Proof Size summary in bytes: + // Measured: `1647` + // Estimated: `3132` + // Minimum execution time: 30_291_000 picoseconds. + Weight::from_parts(30_611_000, 0) + .saturating_add(Weight::from_parts(0, 3132)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + fn remove_member_without_replacement() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_000_000_000_000 picoseconds. + Weight::from_parts(2_000_000_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: PhragmenElection Members (r:1 w:1) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + fn remove_member_with_replacement() -> Weight { + // Proof Size summary in bytes: + // Measured: `2952` + // Estimated: `4437` + // Minimum execution time: 63_178_000 picoseconds. + Weight::from_parts(63_850_000, 0) + .saturating_add(Weight::from_parts(0, 4437)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: PhragmenElection Voting (r:10001 w:10000) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:0) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Candidates (r:1 w:0) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Balances Locks (r:10000 w:10000) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:10000 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: System Account (r:10000 w:10000) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `v` is `[5000, 10000]`. + /// The range of component `d` is `[0, 5000]`. + fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `35961 + v * (808 ±0)` + // Estimated: `39702 + v * (3774 ±0)` + // Minimum execution time: 379_638_846_000 picoseconds. + Weight::from_parts(380_443_068_000, 0) + .saturating_add(Weight::from_parts(0, 39702)) + // Standard Error: 318_371 + .saturating_add(Weight::from_parts(46_236_987, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(v.into())) + } + /// Storage: PhragmenElection Candidates (r:1 w:1) + /// Proof Skipped: PhragmenElection Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:1) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection RunnersUp (r:1 w:1) + /// Proof Skipped: PhragmenElection RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PhragmenElection Voting (r:10001 w:0) + /// Proof Skipped: PhragmenElection Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:962 w:962) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: PhragmenElection ElectionRounds (r:1 w:1) + /// Proof Skipped: PhragmenElection ElectionRounds (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:0 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `c` is `[1, 1000]`. + /// The range of component `v` is `[1, 10000]`. + /// The range of component `e` is `[10000, 160000]`. + fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + e * (28 ±0) + v * (607 ±0)` + // Estimated: `2771509 + c * (2560 ±0) + e * (16 ±0) + v * (2744 ±4)` + // Minimum execution time: 35_941_980_000 picoseconds. + Weight::from_parts(36_032_688_000, 0) + .saturating_add(Weight::from_parts(0, 2771509)) + // Standard Error: 554_972 + .saturating_add(Weight::from_parts(43_733_923, 0).saturating_mul(v.into())) + // Standard Error: 35_614 + .saturating_add(Weight::from_parts(2_430_249, 0).saturating_mul(e.into())) + .saturating_add(T::DbWeight::get().reads(265)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 2560).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 16).saturating_mul(e.into())) + .saturating_add(Weight::from_parts(0, 2744).saturating_mul(v.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_identity.rs b/polkadot/runtime/rococo/src/weights/pallet_identity.rs new file mode 100644 index 0000000000000000000000000000000000000000..e10c042dde6aa167e63b56244f7f5dcb21960915 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_identity.rs @@ -0,0 +1,354 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_identity` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_identity +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_identity`. +pub struct WeightInfo(PhantomData); +impl pallet_identity::WeightInfo for WeightInfo { + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn add_registrar(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `32 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 12_290_000 picoseconds. + Weight::from_parts(12_664_362, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_347 + .saturating_add(Weight::from_parts(88_179, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn set_identity(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `442 + r * (5 ±0)` + // Estimated: `11003` + // Minimum execution time: 31_373_000 picoseconds. + Weight::from_parts(30_435_545, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 2_307 + .saturating_add(Weight::from_parts(92_753, 0).saturating_mul(r.into())) + // Standard Error: 450 + .saturating_add(Weight::from_parts(449_529, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:100 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn set_subs_new(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `11003 + s * (2589 ±0)` + // Minimum execution time: 9_251_000 picoseconds. + Weight::from_parts(22_039_210, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 40_779 + .saturating_add(Weight::from_parts(2_898_525, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(s.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 2589).saturating_mul(s.into())) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 100]`. + fn set_subs_old(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `194 + p * (32 ±0)` + // Estimated: `11003` + // Minimum execution time: 9_329_000 picoseconds. + Weight::from_parts(24_055_061, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 3_428 + .saturating_add(Weight::from_parts(1_130_604, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + } + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `s` is `[0, 100]`. + /// The range of component `x` is `[0, 100]`. + fn clear_identity(_r: u32, s: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 53_365_000 picoseconds. + Weight::from_parts(35_391_422, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_353 + .saturating_add(Weight::from_parts(1_074_019, 0).saturating_mul(s.into())) + // Standard Error: 1_353 + .saturating_add(Weight::from_parts(229_947, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn request_judgement(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `367 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 32_509_000 picoseconds. + Weight::from_parts(31_745_585, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 2_214 + .saturating_add(Weight::from_parts(83_822, 0).saturating_mul(r.into())) + // Standard Error: 432 + .saturating_add(Weight::from_parts(458_801, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn cancel_request(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `398 + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 29_609_000 picoseconds. + Weight::from_parts(28_572_602, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 2_528 + .saturating_add(Weight::from_parts(85_593, 0).saturating_mul(r.into())) + // Standard Error: 493 + .saturating_add(Weight::from_parts(468_140, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_fee(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_793_000 picoseconds. + Weight::from_parts(8_173_888, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_569 + .saturating_add(Weight::from_parts(72_367, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_account_id(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_708_000 picoseconds. + Weight::from_parts(8_091_149, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 869 + .saturating_add(Weight::from_parts(87_993, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_fields(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_601_000 picoseconds. + Weight::from_parts(8_038_414, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_041 + .saturating_add(Weight::from_parts(82_588, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + /// The range of component `x` is `[0, 100]`. + fn provide_judgement(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `445 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 23_114_000 picoseconds. + Weight::from_parts(22_076_548, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 2_881 + .saturating_add(Weight::from_parts(109_812, 0).saturating_mul(r.into())) + // Standard Error: 533 + .saturating_add(Weight::from_parts(733_244, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `s` is `[0, 100]`. + /// The range of component `x` is `[0, 100]`. + fn kill_identity(r: u32, s: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `676 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 70_007_000 picoseconds. + Weight::from_parts(50_186_495, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 6_533 + .saturating_add(Weight::from_parts(15_486, 0).saturating_mul(r.into())) + // Standard Error: 1_275 + .saturating_add(Weight::from_parts(1_085_117, 0).saturating_mul(s.into())) + // Standard Error: 1_275 + .saturating_add(Weight::from_parts(228_226, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 99]`. + fn add_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `475 + s * (36 ±0)` + // Estimated: `11003` + // Minimum execution time: 28_453_000 picoseconds. + Weight::from_parts(33_165_934, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_217 + .saturating_add(Weight::from_parts(65_401, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 100]`. + fn rename_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `591 + s * (3 ±0)` + // Estimated: `11003` + // Minimum execution time: 12_846_000 picoseconds. + Weight::from_parts(14_710_284, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 496 + .saturating_add(Weight::from_parts(19_539, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 100]`. + fn remove_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `638 + s * (35 ±0)` + // Estimated: `11003` + // Minimum execution time: 32_183_000 picoseconds. + Weight::from_parts(35_296_731, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 854 + .saturating_add(Weight::from_parts(52_028, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 99]`. + fn quit_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `704 + s * (37 ±0)` + // Estimated: `6723` + // Minimum execution time: 24_941_000 picoseconds. + Weight::from_parts(27_433_059, 0) + .saturating_add(Weight::from_parts(0, 6723)) + // Standard Error: 856 + .saturating_add(Weight::from_parts(57_463, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_im_online.rs b/polkadot/runtime/rococo/src/weights/pallet_im_online.rs new file mode 100644 index 0000000000000000000000000000000000000000..b866426de52a3abc7608f96bb192a1ae4fbb1d90 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_im_online.rs @@ -0,0 +1,76 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_im_online` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `build-host`, CPU: `AMD EPYC 7601 32-Core Processor` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_im_online +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_im_online`. +pub struct WeightInfo(PhantomData); +impl pallet_im_online::WeightInfo for WeightInfo { + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session CurrentIndex (r:1 w:0) + /// Proof Skipped: Session CurrentIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ImOnline Keys (r:1 w:0) + /// Proof: ImOnline Keys (max_values: Some(1), max_size: Some(320002), added: 320497, mode: MaxEncodedLen) + /// Storage: unknown `0x39e295d143ed41353167609a3d816584` (r:1 w:0) + /// Proof Skipped: unknown `0x39e295d143ed41353167609a3d816584` (r:1 w:0) + /// Storage: ImOnline ReceivedHeartbeats (r:1 w:1) + /// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(1028), added: 3503, mode: MaxEncodedLen) + /// Storage: ImOnline AuthoredBlocks (r:1 w:0) + /// Proof: ImOnline AuthoredBlocks (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// The range of component `k` is `[1, 1000]`. + fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `394 + k * (32 ±0)` + // Estimated: `321487 + k * (1761 ±0)` + // Minimum execution time: 132_910_000 picoseconds. + Weight::from_parts(149_854_501, 0) + .saturating_add(Weight::from_parts(0, 321487)) + // Standard Error: 3_317 + .saturating_add(Weight::from_parts(61_141, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 1761).saturating_mul(k.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_indices.rs b/polkadot/runtime/rococo/src/weights/pallet_indices.rs new file mode 100644 index 0000000000000000000000000000000000000000..99ffd3210ed24f04e170a66c57b01ea9232b0475 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_indices.rs @@ -0,0 +1,114 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_indices` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_indices +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_indices`. +pub struct WeightInfo(PhantomData); +impl pallet_indices::WeightInfo for WeightInfo { + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `142` + // Estimated: `3534` + // Minimum execution time: 25_107_000 picoseconds. + Weight::from_parts(25_655_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `341` + // Estimated: `3593` + // Minimum execution time: 36_208_000 picoseconds. + Weight::from_parts(36_521_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn free() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3534` + // Minimum execution time: 25_915_000 picoseconds. + Weight::from_parts(26_220_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `341` + // Estimated: `3593` + // Minimum execution time: 28_232_000 picoseconds. + Weight::from_parts(28_845_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn freeze() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3534` + // Minimum execution time: 27_282_000 picoseconds. + Weight::from_parts(27_754_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_membership.rs b/polkadot/runtime/rococo/src/weights/pallet_membership.rs new file mode 100644 index 0000000000000000000000000000000000000000..4486c7a270c47e790f51f76148b7592a15ff0fbc --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_membership.rs @@ -0,0 +1,204 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_membership` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_membership +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_membership`. +pub struct WeightInfo(PhantomData); +impl pallet_membership::WeightInfo for WeightInfo { + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 99]`. + fn add_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `140 + m * (64 ±0)` + // Estimated: `4687 + m * (64 ±0)` + // Minimum execution time: 17_084_000 picoseconds. + Weight::from_parts(17_897_754, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 295 + .saturating_add(Weight::from_parts(30_882, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[2, 100]`. + fn remove_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `244 + m * (64 ±0)` + // Estimated: `4687 + m * (64 ±0)` + // Minimum execution time: 19_550_000 picoseconds. + Weight::from_parts(20_467_978, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 330 + .saturating_add(Weight::from_parts(31_881, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[2, 100]`. + fn swap_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `244 + m * (64 ±0)` + // Estimated: `4687 + m * (64 ±0)` + // Minimum execution time: 19_994_000 picoseconds. + Weight::from_parts(20_663_824, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 337 + .saturating_add(Weight::from_parts(44_806, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn reset_member(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `244 + m * (64 ±0)` + // Estimated: `4687 + m * (64 ±0)` + // Minimum execution time: 18_978_000 picoseconds. + Weight::from_parts(21_273_577, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 2_765 + .saturating_add(Weight::from_parts(152_082, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn change_key(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `244 + m * (64 ±0)` + // Estimated: `4687 + m * (64 ±0)` + // Minimum execution time: 20_005_000 picoseconds. + Weight::from_parts(21_280_089, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 672 + .saturating_add(Weight::from_parts(41_961, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Members (r:1 w:0) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalMembership Prime (r:0 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn set_prime(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `32 + m * (32 ±0)` + // Estimated: `4687 + m * (32 ±0)` + // Minimum execution time: 8_168_000 picoseconds. + Weight::from_parts(8_579_141, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 215 + .saturating_add(Weight::from_parts(9_557, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) + } + /// Storage: TechnicalMembership Prime (r:0 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `m` is `[1, 100]`. + fn clear_prime(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_344_000 picoseconds. + Weight::from_parts(3_551_700, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 86 + .saturating_add(Weight::from_parts(832, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs b/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs new file mode 100644 index 0000000000000000000000000000000000000000..e1e360d374a0646b4fed8a29f3509565309d89c0 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs @@ -0,0 +1,196 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_message_queue` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_message_queue +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_message_queue`. +pub struct WeightInfo(PhantomData); +impl pallet_message_queue::WeightInfo for WeightInfo { + /// Storage: MessageQueue ServiceHead (r:1 w:0) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn ready_ring_knit() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `6050` + // Minimum execution time: 12_106_000 picoseconds. + Weight::from_parts(12_387_000, 0) + .saturating_add(Weight::from_parts(0, 6050)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + fn ready_ring_unknit() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `6050` + // Minimum execution time: 11_227_000 picoseconds. + Weight::from_parts(11_616_000, 0) + .saturating_add(Weight::from_parts(0, 6050)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn service_queue_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `42` + // Estimated: `3520` + // Minimum execution time: 5_052_000 picoseconds. + Weight::from_parts(5_216_000, 0) + .saturating_add(Weight::from_parts(0, 3520)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + fn service_page_base_completion() -> Weight { + // Proof Size summary in bytes: + // Measured: `115` + // Estimated: `36283` + // Minimum execution time: 6_522_000 picoseconds. + Weight::from_parts(6_794_000, 0) + .saturating_add(Weight::from_parts(0, 36283)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + fn service_page_base_no_completion() -> Weight { + // Proof Size summary in bytes: + // Measured: `115` + // Estimated: `36283` + // Minimum execution time: 6_918_000 picoseconds. + Weight::from_parts(7_083_000, 0) + .saturating_add(Weight::from_parts(0, 36283)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_page_item() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 28_445_000 picoseconds. + Weight::from_parts(28_659_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn bump_service_head() -> Weight { + // Proof Size summary in bytes: + // Measured: `149` + // Estimated: `3520` + // Minimum execution time: 7_224_000 picoseconds. + Weight::from_parts(7_441_000, 0) + .saturating_add(Weight::from_parts(0, 3520)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn reap_page() -> Weight { + // Proof Size summary in bytes: + // Measured: `33232` + // Estimated: `36283` + // Minimum execution time: 45_211_000 picoseconds. + Weight::from_parts(45_505_000, 0) + .saturating_add(Weight::from_parts(0, 36283)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn execute_overweight_page_removed() -> Weight { + // Proof Size summary in bytes: + // Measured: `33232` + // Estimated: `36283` + // Minimum execution time: 52_346_000 picoseconds. + Weight::from_parts(52_745_000, 0) + .saturating_add(Weight::from_parts(0, 36283)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn execute_overweight_page_updated() -> Weight { + // Proof Size summary in bytes: + // Measured: `33232` + // Estimated: `36283` + // Minimum execution time: 72_567_000 picoseconds. + Weight::from_parts(73_300_000, 0) + .saturating_add(Weight::from_parts(0, 36283)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_multisig.rs b/polkadot/runtime/rococo/src/weights/pallet_multisig.rs new file mode 100644 index 0000000000000000000000000000000000000000..a4f33fe198ca167e9b8112a13b1549ba727da354 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_multisig.rs @@ -0,0 +1,162 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_multisig` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_multisig +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_multisig`. +pub struct WeightInfo(PhantomData); +impl pallet_multisig::WeightInfo for WeightInfo { + /// The range of component `z` is `[0, 10000]`. + fn as_multi_threshold_1(z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 11_475_000 picoseconds. + Weight::from_parts(11_904_745, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(492, 0).saturating_mul(z.into())) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_create(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `193 + s * (2 ±0)` + // Estimated: `6811` + // Minimum execution time: 38_857_000 picoseconds. + Weight::from_parts(33_611_791, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 400 + .saturating_add(Weight::from_parts(59_263, 0).saturating_mul(s.into())) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_211, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[3, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_approve(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `211` + // Estimated: `6811` + // Minimum execution time: 25_715_000 picoseconds. + Weight::from_parts(20_607_294, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 285 + .saturating_add(Weight::from_parts(58_225, 0).saturating_mul(s.into())) + // Standard Error: 2 + .saturating_add(Weight::from_parts(1_160, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_complete(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `317 + s * (33 ±0)` + // Estimated: `6811` + // Minimum execution time: 43_751_000 picoseconds. + Weight::from_parts(37_398_513, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 426 + .saturating_add(Weight::from_parts(70_904, 0).saturating_mul(s.into())) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_235, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn approve_as_multi_create(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `193 + s * (2 ±0)` + // Estimated: `6811` + // Minimum execution time: 31_278_000 picoseconds. + Weight::from_parts(32_075_573, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 452 + .saturating_add(Weight::from_parts(62_018, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn approve_as_multi_approve(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `211` + // Estimated: `6811` + // Minimum execution time: 18_178_000 picoseconds. + Weight::from_parts(18_649_867, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 293 + .saturating_add(Weight::from_parts(56_475, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn cancel_as_multi(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `383 + s * (1 ±0)` + // Estimated: `6811` + // Minimum execution time: 32_265_000 picoseconds. + Weight::from_parts(32_984_014, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 452 + .saturating_add(Weight::from_parts(59_934, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_nis.rs b/polkadot/runtime/rococo/src/weights/pallet_nis.rs new file mode 100644 index 0000000000000000000000000000000000000000..35dad482129e6c63e0aca0aceb544c66fba78ee7 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_nis.rs @@ -0,0 +1,249 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_nis` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_nis +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_nis`. +pub struct WeightInfo(PhantomData); +impl pallet_nis::WeightInfo for WeightInfo { + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 999]`. + fn place_bid(l: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `6209 + l * (48 ±0)` + // Estimated: `51487` + // Minimum execution time: 44_704_000 picoseconds. + Weight::from_parts(44_933_886, 0) + .saturating_add(Weight::from_parts(0, 51487)) + // Standard Error: 712 + .saturating_add(Weight::from_parts(71_570, 0).saturating_mul(l.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + fn place_bid_max() -> Weight { + // Proof Size summary in bytes: + // Measured: `54211` + // Estimated: `51487` + // Minimum execution time: 126_544_000 picoseconds. + Weight::from_parts(128_271_000, 0) + .saturating_add(Weight::from_parts(0, 51487)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// The range of component `l` is `[1, 1000]`. + fn retract_bid(l: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `6209 + l * (48 ±0)` + // Estimated: `51487` + // Minimum execution time: 47_640_000 picoseconds. + Weight::from_parts(42_214_261, 0) + .saturating_add(Weight::from_parts(0, 51487)) + // Standard Error: 732 + .saturating_add(Weight::from_parts(87_277, 0).saturating_mul(l.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Nis Summary (r:1 w:0) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn fund_deficit() -> Weight { + // Proof Size summary in bytes: + // Measured: `225` + // Estimated: `3593` + // Minimum execution time: 38_031_000 picoseconds. + Weight::from_parts(38_441_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + fn communify() -> Weight { + // Proof Size summary in bytes: + // Measured: `469` + // Estimated: `3593` + // Minimum execution time: 69_269_000 picoseconds. + Weight::from_parts(70_000_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + fn privatize() -> Weight { + // Proof Size summary in bytes: + // Measured: `659` + // Estimated: `3593` + // Minimum execution time: 85_763_000 picoseconds. + Weight::from_parts(86_707_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + fn thaw_private() -> Weight { + // Proof Size summary in bytes: + // Measured: `387` + // Estimated: `3593` + // Minimum execution time: 47_336_000 picoseconds. + Weight::from_parts(47_623_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn thaw_communal() -> Weight { + // Proof Size summary in bytes: + // Measured: `604` + // Estimated: `3593` + // Minimum execution time: 90_972_000 picoseconds. + Weight::from_parts(92_074_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + fn process_queues() -> Weight { + // Proof Size summary in bytes: + // Measured: `6658` + // Estimated: `7487` + // Minimum execution time: 21_469_000 picoseconds. + Weight::from_parts(21_983_000, 0) + .saturating_add(Weight::from_parts(0, 7487)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + fn process_queue() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `51487` + // Minimum execution time: 4_912_000 picoseconds. + Weight::from_parts(5_013_000, 0) + .saturating_add(Weight::from_parts(0, 51487)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Nis Receipts (r:0 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + fn process_bid() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_048_000 picoseconds. + Weight::from_parts(7_278_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_preimage.rs b/polkadot/runtime/rococo/src/weights/pallet_preimage.rs new file mode 100644 index 0000000000000000000000000000000000000000..b067e6a6d91e31e745f78c36eb96e6aced428452 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_preimage.rs @@ -0,0 +1,215 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_preimage` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_preimage +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_preimage`. +pub struct WeightInfo(PhantomData); +impl pallet_preimage::WeightInfo for WeightInfo { + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `215` + // Estimated: `3556` + // Minimum execution time: 31_040_000 picoseconds. + Weight::from_parts(31_236_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_974, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_requested_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `178` + // Estimated: `3556` + // Minimum execution time: 18_025_000 picoseconds. + Weight::from_parts(18_264_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_974, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_no_deposit_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `178` + // Estimated: `3556` + // Minimum execution time: 17_122_000 picoseconds. + Weight::from_parts(17_332_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_968, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unnote_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `361` + // Estimated: `3556` + // Minimum execution time: 38_218_000 picoseconds. + Weight::from_parts(39_841_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unnote_no_deposit_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `216` + // Estimated: `3556` + // Minimum execution time: 23_217_000 picoseconds. + Weight::from_parts(24_246_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `260` + // Estimated: `3556` + // Minimum execution time: 21_032_000 picoseconds. + Weight::from_parts(21_844_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_no_deposit_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `216` + // Estimated: `3556` + // Minimum execution time: 13_954_000 picoseconds. + Weight::from_parts(14_501_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_unnoted_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `114` + // Estimated: `3556` + // Minimum execution time: 14_874_000 picoseconds. + Weight::from_parts(15_380_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_requested_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `178` + // Estimated: `3556` + // Minimum execution time: 10_199_000 picoseconds. + Weight::from_parts(10_493_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unrequest_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `216` + // Estimated: `3556` + // Minimum execution time: 21_772_000 picoseconds. + Weight::from_parts(22_554_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn unrequest_unnoted_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `178` + // Estimated: `3556` + // Minimum execution time: 10_115_000 picoseconds. + Weight::from_parts(10_452_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn unrequest_multi_referenced_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `178` + // Estimated: `3556` + // Minimum execution time: 10_031_000 picoseconds. + Weight::from_parts(10_310_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_proxy.rs b/polkadot/runtime/rococo/src/weights/pallet_proxy.rs new file mode 100644 index 0000000000000000000000000000000000000000..d9737a85c05ad2b55759c141539f34fc60d3c808 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_proxy.rs @@ -0,0 +1,219 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_proxy` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_proxy +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_proxy`. +pub struct WeightInfo(PhantomData); +impl pallet_proxy::WeightInfo for WeightInfo { + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 15_956_000 picoseconds. + Weight::from_parts(16_300_358, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 652 + .saturating_add(Weight::from_parts(30_807, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn proxy_announced(a: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `554 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `5698` + // Minimum execution time: 37_584_000 picoseconds. + Weight::from_parts(37_858_207, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 1_868 + .saturating_add(Weight::from_parts(148_967, 0).saturating_mul(a.into())) + // Standard Error: 1_930 + .saturating_add(Weight::from_parts(13_017, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn remove_announcement(a: u32, _p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + a * (68 ±0)` + // Estimated: `5698` + // Minimum execution time: 24_642_000 picoseconds. + Weight::from_parts(25_526_588, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 1_138 + .saturating_add(Weight::from_parts(131_157, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn reject_announcement(a: u32, _p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + a * (68 ±0)` + // Estimated: `5698` + // Minimum execution time: 24_377_000 picoseconds. + Weight::from_parts(25_464_033, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 1_116 + .saturating_add(Weight::from_parts(130_722, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn announce(a: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `486 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `5698` + // Minimum execution time: 34_202_000 picoseconds. + Weight::from_parts(34_610_079, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 1_234 + .saturating_add(Weight::from_parts(134_197, 0).saturating_mul(a.into())) + // Standard Error: 1_275 + .saturating_add(Weight::from_parts(15_970, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn add_proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 25_492_000 picoseconds. + Weight::from_parts(25_984_867, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 893 + .saturating_add(Weight::from_parts(51_868, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn remove_proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 25_492_000 picoseconds. + Weight::from_parts(26_283_445, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 1_442 + .saturating_add(Weight::from_parts(53_504, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn remove_proxies(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 22_083_000 picoseconds. + Weight::from_parts(22_688_835, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 994 + .saturating_add(Weight::from_parts(32_994, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn create_pure(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `239` + // Estimated: `4706` + // Minimum execution time: 27_042_000 picoseconds. + Weight::from_parts(27_624_587, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 671 + .saturating_add(Weight::from_parts(5_888, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 30]`. + fn kill_pure(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `264 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 23_396_000 picoseconds. + Weight::from_parts(24_003_080, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 684 + .saturating_add(Weight::from_parts(29_878, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs b/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs new file mode 100644 index 0000000000000000000000000000000000000000..e4732a2d17dca5180a8e07d5cddd19acd55f1b76 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs @@ -0,0 +1,204 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_scheduler` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_scheduler +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_scheduler`. +pub struct WeightInfo(PhantomData); +impl pallet_scheduler::WeightInfo for WeightInfo { + /// Storage: Scheduler IncompleteSince (r:1 w:1) + /// Proof: Scheduler IncompleteSince (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn service_agendas_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `69` + // Estimated: `1489` + // Minimum execution time: 4_741_000 picoseconds. + Weight::from_parts(4_939_000, 0) + .saturating_add(Weight::from_parts(0, 1489)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 50]`. + fn service_agenda_base(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 4_504_000 picoseconds. + Weight::from_parts(7_569_333, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 1_818 + .saturating_add(Weight::from_parts(771_180, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_task_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_709_000 picoseconds. + Weight::from_parts(5_929_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Preimage PreimageFor (r:1 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: Measured) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// The range of component `s` is `[128, 4194304]`. + fn service_task_fetched(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `251 + s * (1 ±0)` + // Estimated: `3716 + s * (1 ±0)` + // Minimum execution time: 20_710_000 picoseconds. + Weight::from_parts(20_918_000, 0) + .saturating_add(Weight::from_parts(0, 3716)) + // Standard Error: 9 + .saturating_add(Weight::from_parts(1_257, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(s.into())) + } + /// Storage: Scheduler Lookup (r:0 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + fn service_task_named() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_262_000 picoseconds. + Weight::from_parts(7_412_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_task_periodic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_774_000 picoseconds. + Weight::from_parts(5_887_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn execute_dispatch_signed() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_777_000 picoseconds. + Weight::from_parts(2_865_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn execute_dispatch_unsigned() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_739_000 picoseconds. + Weight::from_parts(2_827_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 49]`. + fn schedule(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 14_788_000 picoseconds. + Weight::from_parts(17_705_748, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 1_703 + .saturating_add(Weight::from_parts(760_991, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: Scheduler Lookup (r:0 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 50]`. + fn cancel(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 18_716_000 picoseconds. + Weight::from_parts(18_220_022, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 1_508 + .saturating_add(Weight::from_parts(1_357_835, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 49]`. + fn schedule_named(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `293 + s * (185 ±0)` + // Estimated: `42428` + // Minimum execution time: 17_719_000 picoseconds. + Weight::from_parts(21_657_806, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 2_645 + .saturating_add(Weight::from_parts(794_184, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 50]`. + fn cancel_named(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `319 + s * (185 ±0)` + // Estimated: `42428` + // Minimum execution time: 20_225_000 picoseconds. + Weight::from_parts(20_494_405, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 1_890 + .saturating_add(Weight::from_parts(1_379_025, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_session.rs b/polkadot/runtime/rococo/src/weights/pallet_session.rs new file mode 100644 index 0000000000000000000000000000000000000000..dbeca534add8259fdf77010296d0c6d557365204 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_session.rs @@ -0,0 +1,62 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +//! Autogenerated weights for `pallet_session` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-03-15, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_session +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/polkadot/src/weights/pallet_session.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `pallet_session`. +pub struct WeightInfo(PhantomData); +impl pallet_session::WeightInfo for WeightInfo { + // Storage: Staking Ledger (r:1 w:0) + // Storage: Session NextKeys (r:1 w:1) + // Storage: Session KeyOwner (r:6 w:6) + fn set_keys() -> Weight { + Weight::from_parts(36_115_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(8 as u64)) + .saturating_add(T::DbWeight::get().writes(7 as u64)) + } + // Storage: Staking Ledger (r:1 w:0) + // Storage: Session NextKeys (r:1 w:1) + // Storage: Session KeyOwner (r:0 w:6) + fn purge_keys() -> Weight { + Weight::from_parts(21_459_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(2 as u64)) + .saturating_add(T::DbWeight::get().writes(7 as u64)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_sudo.rs b/polkadot/runtime/rococo/src/weights/pallet_sudo.rs new file mode 100644 index 0000000000000000000000000000000000000000..83215af5b8aecf5a79b084f24d0cfd8506f5b559 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_sudo.rs @@ -0,0 +1,84 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_sudo` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_sudo +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_sudo`. +pub struct WeightInfo(PhantomData); +impl pallet_sudo::WeightInfo for WeightInfo { + /// Storage: Sudo Key (r:1 w:1) + /// Proof: Sudo Key (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + fn set_key() -> Weight { + // Proof Size summary in bytes: + // Measured: `132` + // Estimated: `1517` + // Minimum execution time: 13_047_000 picoseconds. + Weight::from_parts(13_325_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Sudo Key (r:1 w:0) + /// Proof: Sudo Key (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + fn sudo() -> Weight { + // Proof Size summary in bytes: + // Measured: `132` + // Estimated: `1517` + // Minimum execution time: 13_250_000 picoseconds. + Weight::from_parts(13_544_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: Sudo Key (r:1 w:0) + /// Proof: Sudo Key (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + fn sudo_as() -> Weight { + // Proof Size summary in bytes: + // Measured: `132` + // Estimated: `1517` + // Minimum execution time: 13_424_000 picoseconds. + Weight::from_parts(13_801_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) + .saturating_add(T::DbWeight::get().reads(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs b/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs new file mode 100644 index 0000000000000000000000000000000000000000..1bb2e227ab7d540ba8cfd9e4609e957bf025d57c --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs @@ -0,0 +1,72 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_timestamp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_timestamp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_timestamp`. +pub struct WeightInfo(PhantomData); +impl pallet_timestamp::WeightInfo for WeightInfo { + /// Storage: Timestamp Now (r:1 w:1) + /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + fn set() -> Weight { + // Proof Size summary in bytes: + // Measured: `311` + // Estimated: `1493` + // Minimum execution time: 10_103_000 picoseconds. + Weight::from_parts(10_597_000, 0) + .saturating_add(Weight::from_parts(0, 1493)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn on_finalize() -> Weight { + // Proof Size summary in bytes: + // Measured: `94` + // Estimated: `0` + // Minimum execution time: 4_718_000 picoseconds. + Weight::from_parts(4_839_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_tips.rs b/polkadot/runtime/rococo/src/weights/pallet_tips.rs new file mode 100644 index 0000000000000000000000000000000000000000..c4710afd78e2bf2fa6b0501140845681295eee0b --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_tips.rs @@ -0,0 +1,161 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_tips` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_tips +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_tips`. +pub struct WeightInfo(PhantomData); +impl pallet_tips::WeightInfo for WeightInfo { + /// Storage: Tips Reasons (r:1 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[0, 16384]`. + fn report_awesome(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3469` + // Minimum execution time: 27_741_000 picoseconds. + Weight::from_parts(28_495_173, 0) + .saturating_add(Weight::from_parts(0, 3469)) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_433, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + fn retract_tip() -> Weight { + // Proof Size summary in bytes: + // Measured: `221` + // Estimated: `3686` + // Minimum execution time: 27_275_000 picoseconds. + Weight::from_parts(27_649_000, 0) + .saturating_add(Weight::from_parts(0, 3686)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:1 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Tips (r:0 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[0, 16384]`. + /// The range of component `t` is `[1, 19]`. + fn tip_new(r: u32, t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `74 + t * (64 ±0)` + // Estimated: `3539 + t * (64 ±0)` + // Minimum execution time: 19_809_000 picoseconds. + Weight::from_parts(18_182_607, 0) + .saturating_add(Weight::from_parts(0, 3539)) + // Standard Error: 5 + .saturating_add(Weight::from_parts(1_303, 0).saturating_mul(r.into())) + // Standard Error: 5_156 + .saturating_add(Weight::from_parts(151_789, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 64).saturating_mul(t.into())) + } + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// The range of component `t` is `[1, 19]`. + fn tip(t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `295 + t * (112 ±0)` + // Estimated: `3760 + t * (112 ±0)` + // Minimum execution time: 15_528_000 picoseconds. + Weight::from_parts(15_717_755, 0) + .saturating_add(Weight::from_parts(0, 3760)) + // Standard Error: 6_569 + .saturating_add(Weight::from_parts(146_426, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) + } + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: PhragmenElection Members (r:1 w:0) + /// Proof Skipped: PhragmenElection Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// The range of component `t` is `[1, 19]`. + fn close_tip(t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `334 + t * (112 ±0)` + // Estimated: `3790 + t * (112 ±0)` + // Minimum execution time: 58_304_000 picoseconds. + Weight::from_parts(60_138_785, 0) + .saturating_add(Weight::from_parts(0, 3790)) + // Standard Error: 7_636 + .saturating_add(Weight::from_parts(86_665, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) + } + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// The range of component `t` is `[1, 19]`. + fn slash_tip(t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `269` + // Estimated: `3734` + // Minimum execution time: 15_097_000 picoseconds. + Weight::from_parts(15_497_872, 0) + .saturating_add(Weight::from_parts(0, 3734)) + // Standard Error: 785 + .saturating_add(Weight::from_parts(18_377, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_treasury.rs b/polkadot/runtime/rococo/src/weights/pallet_treasury.rs new file mode 100644 index 0000000000000000000000000000000000000000..041d976d82570d711b409fdb4253b56eb45dc15b --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_treasury.rs @@ -0,0 +1,143 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_treasury` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_treasury +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_treasury`. +pub struct WeightInfo(PhantomData); +impl pallet_treasury::WeightInfo for WeightInfo { + fn spend() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 204_000 picoseconds. + Weight::from_parts(233_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Treasury ProposalCount (r:1 w:1) + /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:0 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + fn propose_spend() -> Weight { + // Proof Size summary in bytes: + // Measured: `107` + // Estimated: `1489` + // Minimum execution time: 27_592_000 picoseconds. + Weight::from_parts(27_960_000, 0) + .saturating_add(Weight::from_parts(0, 1489)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Treasury Proposals (r:1 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn reject_proposal() -> Weight { + // Proof Size summary in bytes: + // Measured: `265` + // Estimated: `3593` + // Minimum execution time: 40_336_000 picoseconds. + Weight::from_parts(41_085_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Treasury Proposals (r:1 w:0) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 99]`. + fn approve_proposal(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `433 + p * (8 ±0)` + // Estimated: `3573` + // Minimum execution time: 9_938_000 picoseconds. + Weight::from_parts(12_061_206, 0) + .saturating_add(Weight::from_parts(0, 3573)) + // Standard Error: 801 + .saturating_add(Weight::from_parts(26_602, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + fn remove_approval() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `1887` + // Minimum execution time: 7_421_000 picoseconds. + Weight::from_parts(7_620_000, 0) + .saturating_add(Weight::from_parts(0, 1887)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Treasury Deactivated (r:1 w:1) + /// Proof: Treasury Deactivated (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:100 w:100) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:201 w:201) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 100]`. + fn on_initialize_proposals(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `296 + p * (251 ±0)` + // Estimated: `3593 + p * (5206 ±0)` + // Minimum execution time: 62_706_000 picoseconds. + Weight::from_parts(61_351_470, 0) + .saturating_add(Weight::from_parts(0, 3593)) + // Standard Error: 32_787 + .saturating_add(Weight::from_parts(37_873_920, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 5206).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_utility.rs b/polkadot/runtime/rococo/src/weights/pallet_utility.rs new file mode 100644 index 0000000000000000000000000000000000000000..f50f60eaad7fec2c09e9d5620db0551f1c7b1364 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_utility.rs @@ -0,0 +1,99 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_utility` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_utility +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_utility`. +pub struct WeightInfo(PhantomData); +impl pallet_utility::WeightInfo for WeightInfo { + /// The range of component `c` is `[0, 1000]`. + fn batch(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_738_000 picoseconds. + Weight::from_parts(2_704_821, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2_999 + .saturating_add(Weight::from_parts(4_627_278, 0).saturating_mul(c.into())) + } + fn as_derivative() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_294_000 picoseconds. + Weight::from_parts(5_467_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `c` is `[0, 1000]`. + fn batch_all(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_828_000 picoseconds. + Weight::from_parts(4_650_678, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2_789 + .saturating_add(Weight::from_parts(4_885_004, 0).saturating_mul(c.into())) + } + fn dispatch_as() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_020_000 picoseconds. + Weight::from_parts(9_205_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `c` is `[0, 1000]`. + fn force_batch(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_852_000 picoseconds. + Weight::from_parts(20_703_134, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3_924 + .saturating_add(Weight::from_parts(4_604_529, 0).saturating_mul(c.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_vesting.rs b/polkadot/runtime/rococo/src/weights/pallet_vesting.rs new file mode 100644 index 0000000000000000000000000000000000000000..fd820f1aea3241521e650b1e6af3af32236a465d --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_vesting.rs @@ -0,0 +1,238 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_vesting` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_vesting +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_vesting`. +pub struct WeightInfo(PhantomData); +impl pallet_vesting::WeightInfo for WeightInfo { + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `277 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 32_820_000 picoseconds. + Weight::from_parts(31_640_992, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 449 + .saturating_add(Weight::from_parts(45_254, 0).saturating_mul(l.into())) + // Standard Error: 800 + .saturating_add(Weight::from_parts(72_178, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `277 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 36_054_000 picoseconds. + Weight::from_parts(35_825_428, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 749 + .saturating_add(Weight::from_parts(31_738, 0).saturating_mul(l.into())) + // Standard Error: 1_333 + .saturating_add(Weight::from_parts(40_580, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `380 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 35_440_000 picoseconds. + Weight::from_parts(34_652_647, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 517 + .saturating_add(Weight::from_parts(41_942, 0).saturating_mul(l.into())) + // Standard Error: 920 + .saturating_add(Weight::from_parts(66_074, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `380 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 38_880_000 picoseconds. + Weight::from_parts(39_625_819, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_032 + .saturating_add(Weight::from_parts(29_856, 0).saturating_mul(l.into())) + // Standard Error: 1_837 + .saturating_add(Weight::from_parts(6_210, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `451 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 68_294_000 picoseconds. + Weight::from_parts(68_313_394, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 983 + .saturating_add(Weight::from_parts(48_156, 0).saturating_mul(l.into())) + // Standard Error: 1_750 + .saturating_add(Weight::from_parts(87_719, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn force_vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `554 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `6196` + // Minimum execution time: 70_529_000 picoseconds. + Weight::from_parts(70_619_962, 0) + .saturating_add(Weight::from_parts(0, 6196)) + // Standard Error: 1_259 + .saturating_add(Weight::from_parts(50_685, 0).saturating_mul(l.into())) + // Standard Error: 2_241 + .saturating_add(Weight::from_parts(91_444, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn not_unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `378 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 36_428_000 picoseconds. + Weight::from_parts(35_604_430, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 504 + .saturating_add(Weight::from_parts(43_191, 0).saturating_mul(l.into())) + // Standard Error: 931 + .saturating_add(Weight::from_parts(66_795, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `378 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 40_696_000 picoseconds. + Weight::from_parts(39_741_284, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 478 + .saturating_add(Weight::from_parts(43_792, 0).saturating_mul(l.into())) + // Standard Error: 883 + .saturating_add(Weight::from_parts(66_540, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs new file mode 100644 index 0000000000000000000000000000000000000000..43b4358b89038530ad66545e195aece5a4e0c874 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs @@ -0,0 +1,278 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/var/lib/gitlab-runner/builds/zyw4fam_/0/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=rococo-dev +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm`. +pub struct WeightInfo(PhantomData); +impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn send() -> Weight { + // Proof Size summary in bytes: + // Measured: `565` + // Estimated: `4030` + // Minimum execution time: 37_039_000 picoseconds. + Weight::from_parts(37_605_000, 0) + .saturating_add(Weight::from_parts(0, 4030)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(3)) + } + fn teleport_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 21_646_000 picoseconds. + Weight::from_parts(22_119_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn reserve_transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 21_353_000 picoseconds. + Weight::from_parts(21_768_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn execute() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_942_000 picoseconds. + Weight::from_parts(10_110_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: XcmPallet SupportedVersion (r:0 w:1) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + fn force_xcm_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_951_000 picoseconds. + Weight::from_parts(10_182_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn force_default_xcm_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_163_000 picoseconds. + Weight::from_parts(3_298_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: XcmPallet VersionNotifiers (r:1 w:1) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet QueryCounter (r:1 w:1) + /// Proof Skipped: XcmPallet QueryCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet Queries (r:0 w:1) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + fn force_subscribe_version_notify() -> Weight { + // Proof Size summary in bytes: + // Measured: `565` + // Estimated: `4030` + // Minimum execution time: 41_207_000 picoseconds. + Weight::from_parts(41_879_000, 0) + .saturating_add(Weight::from_parts(0, 4030)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: XcmPallet VersionNotifiers (r:1 w:1) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet Queries (r:0 w:1) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + fn force_unsubscribe_version_notify() -> Weight { + // Proof Size summary in bytes: + // Measured: `837` + // Estimated: `4302` + // Minimum execution time: 44_763_000 picoseconds. + Weight::from_parts(45_368_000, 0) + .saturating_add(Weight::from_parts(0, 4302)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: XcmPallet XcmExecutionSuspended (r:0 w:1) + /// Proof Skipped: XcmPallet XcmExecutionSuspended (max_values: Some(1), max_size: None, mode: Measured) + fn force_suspension() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_089_000 picoseconds. + Weight::from_parts(3_246_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: XcmPallet SupportedVersion (r:4 w:2) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + fn migrate_supported_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `229` + // Estimated: `11119` + // Minimum execution time: 16_733_000 picoseconds. + Weight::from_parts(17_354_000, 0) + .saturating_add(Weight::from_parts(0, 11119)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifiers (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + fn migrate_version_notifiers() -> Weight { + // Proof Size summary in bytes: + // Measured: `233` + // Estimated: `11123` + // Minimum execution time: 16_959_000 picoseconds. + Weight::from_parts(17_306_000, 0) + .saturating_add(Weight::from_parts(0, 11123)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:5 w:0) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn already_notified_target() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `13608` + // Minimum execution time: 17_964_000 picoseconds. + Weight::from_parts(18_548_000, 0) + .saturating_add(Weight::from_parts(0, 13608)) + .saturating_add(T::DbWeight::get().reads(5)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:2 w:1) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn notify_current_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `635` + // Estimated: `6575` + // Minimum execution time: 39_436_000 picoseconds. + Weight::from_parts(39_669_000, 0) + .saturating_add(Weight::from_parts(0, 6575)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:3 w:0) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn notify_target_migration_fail() -> Weight { + // Proof Size summary in bytes: + // Measured: `272` + // Estimated: `8687` + // Minimum execution time: 8_991_000 picoseconds. + Weight::from_parts(9_248_000, 0) + .saturating_add(Weight::from_parts(0, 8687)) + .saturating_add(T::DbWeight::get().reads(3)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn migrate_version_notify_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `240` + // Estimated: `11130` + // Minimum execution time: 17_614_000 picoseconds. + Weight::from_parts(17_948_000, 0) + .saturating_add(Weight::from_parts(0, 11130)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn migrate_and_notify_old_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `639` + // Estimated: `11529` + // Minimum execution time: 45_531_000 picoseconds. + Weight::from_parts(46_533_000, 0) + .saturating_add(Weight::from_parts(0, 11529)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(5)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs b/polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs new file mode 100644 index 0000000000000000000000000000000000000000..a6beeded428649fdda8530fda4c10492867f11a2 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs @@ -0,0 +1,151 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::assigned_slots` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-ynta1nyy-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_common::assigned_slots +// --chain=rococo-dev +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::assigned_slots`. +pub struct WeightInfo(PhantomData); +impl runtime_common::assigned_slots::WeightInfo for WeightInfo { + /// Storage: `Registrar::Paras` (r:1 w:1) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:1) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AssignedSlots::PermanentSlots` (r:1 w:1) + /// Proof: `AssignedSlots::PermanentSlots` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::TemporarySlots` (r:1 w:0) + /// Proof: `AssignedSlots::TemporarySlots` (`max_values`: None, `max_size`: Some(61), added: 2536, mode: `MaxEncodedLen`) + /// Storage: `Slots::Leases` (r:1 w:1) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AssignedSlots::PermanentSlotCount` (r:1 w:1) + /// Proof: `AssignedSlots::PermanentSlotCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::MaxPermanentSlots` (r:1 w:0) + /// Proof: `AssignedSlots::MaxPermanentSlots` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn assign_perm_parachain_slot() -> Weight { + // Proof Size summary in bytes: + // Measured: `673` + // Estimated: `4138` + // Minimum execution time: 84_646_000 picoseconds. + Weight::from_parts(91_791_000, 0) + .saturating_add(Weight::from_parts(0, 4138)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: `Registrar::Paras` (r:1 w:1) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:1) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AssignedSlots::PermanentSlots` (r:1 w:0) + /// Proof: `AssignedSlots::PermanentSlots` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::TemporarySlots` (r:1 w:1) + /// Proof: `AssignedSlots::TemporarySlots` (`max_values`: None, `max_size`: Some(61), added: 2536, mode: `MaxEncodedLen`) + /// Storage: `Slots::Leases` (r:1 w:1) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AssignedSlots::TemporarySlotCount` (r:1 w:1) + /// Proof: `AssignedSlots::TemporarySlotCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::MaxTemporarySlots` (r:1 w:0) + /// Proof: `AssignedSlots::MaxTemporarySlots` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::ActiveTemporarySlotCount` (r:1 w:1) + /// Proof: `AssignedSlots::ActiveTemporarySlotCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn assign_temp_parachain_slot() -> Weight { + // Proof Size summary in bytes: + // Measured: `673` + // Estimated: `4138` + // Minimum execution time: 68_091_000 picoseconds. + Weight::from_parts(77_310_000, 0) + .saturating_add(Weight::from_parts(0, 4138)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: `AssignedSlots::PermanentSlots` (r:1 w:0) + /// Proof: `AssignedSlots::PermanentSlots` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::TemporarySlots` (r:1 w:1) + /// Proof: `AssignedSlots::TemporarySlots` (`max_values`: None, `max_size`: Some(61), added: 2536, mode: `MaxEncodedLen`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Slots::Leases` (r:1 w:1) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AssignedSlots::TemporarySlotCount` (r:1 w:1) + /// Proof: `AssignedSlots::TemporarySlotCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn unassign_parachain_slot() -> Weight { + // Proof Size summary in bytes: + // Measured: `823` + // Estimated: `4288` + // Minimum execution time: 38_081_000 picoseconds. + Weight::from_parts(40_987_000, 0) + .saturating_add(Weight::from_parts(0, 4288)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `AssignedSlots::MaxPermanentSlots` (r:0 w:1) + /// Proof: `AssignedSlots::MaxPermanentSlots` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn set_max_permanent_slots() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_182_000 picoseconds. + Weight::from_parts(7_437_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `AssignedSlots::MaxTemporarySlots` (r:0 w:1) + /// Proof: `AssignedSlots::MaxTemporarySlots` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn set_max_temporary_slots() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_153_000 picoseconds. + Weight::from_parts(7_456_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs b/polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs new file mode 100644 index 0000000000000000000000000000000000000000..3cd7c7a47e90ee1bf6590d0421faf580c1c776f6 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs @@ -0,0 +1,140 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::auctions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_common::auctions +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_common_auctions.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::auctions`. +pub struct WeightInfo(PhantomData); +impl runtime_common::auctions::WeightInfo for WeightInfo { + /// Storage: Auctions AuctionInfo (r:1 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Auctions AuctionCounter (r:1 w:1) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn new_auction() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `1493` + // Minimum execution time: 12_805_000 picoseconds. + Weight::from_parts(13_153_000, 0) + .saturating_add(Weight::from_parts(0, 1493)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions Winning (r:1 w:1) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:2 w:2) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn bid() -> Weight { + // Proof Size summary in bytes: + // Measured: `728` + // Estimated: `6060` + // Minimum execution time: 77_380_000 picoseconds. + Weight::from_parts(80_503_000, 0) + .saturating_add(Weight::from_parts(0, 6060)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Auctions AuctionInfo (r:1 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe NextRandomness (r:1 w:0) + /// Proof: Babe NextRandomness (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: Babe EpochStart (r:1 w:0) + /// Proof: Babe EpochStart (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Auctions Winning (r:3600 w:3600) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:37 w:36) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:36 w:36) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Slots Leases (r:2 w:2) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + fn on_initialize() -> Weight { + // Proof Size summary in bytes: + // Measured: `6947789` + // Estimated: `15822990` + // Minimum execution time: 6_311_055_000 picoseconds. + Weight::from_parts(6_409_142_000, 0) + .saturating_add(Weight::from_parts(0, 15822990)) + .saturating_add(T::DbWeight::get().reads(3683)) + .saturating_add(T::DbWeight::get().writes(3678)) + } + /// Storage: Auctions ReservedAmounts (r:37 w:36) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:36 w:36) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Auctions Winning (r:3600 w:3600) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions AuctionInfo (r:0 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + fn cancel_auction() -> Weight { + // Proof Size summary in bytes: + // Measured: `177732` + // Estimated: `15822990` + // Minimum execution time: 4_849_561_000 picoseconds. + Weight::from_parts(4_955_226_000, 0) + .saturating_add(Weight::from_parts(0, 15822990)) + .saturating_add(T::DbWeight::get().reads(3673)) + .saturating_add(T::DbWeight::get().writes(3673)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_claims.rs b/polkadot/runtime/rococo/src/weights/runtime_common_claims.rs new file mode 100644 index 0000000000000000000000000000000000000000..52e0dd24afa0aa5e4cd75d53f53ca7d032ca9588 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_common_claims.rs @@ -0,0 +1,166 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::claims` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_common::claims +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_common_claims.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::claims`. +pub struct WeightInfo(PhantomData); +impl runtime_common::claims::WeightInfo for WeightInfo { + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + fn claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `558` + // Estimated: `4764` + // Minimum execution time: 144_931_000 picoseconds. + Weight::from_parts(156_550_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:0 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Claims (r:0 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:0 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + fn mint_claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `216` + // Estimated: `1701` + // Minimum execution time: 11_300_000 picoseconds. + Weight::from_parts(11_642_000, 0) + .saturating_add(Weight::from_parts(0, 1701)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + fn claim_attest() -> Weight { + // Proof Size summary in bytes: + // Measured: `558` + // Estimated: `4764` + // Minimum execution time: 149_112_000 picoseconds. + Weight::from_parts(153_872_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Claims Preclaims (r:1 w:1) + /// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + fn attest() -> Weight { + // Proof Size summary in bytes: + // Measured: `632` + // Estimated: `4764` + // Minimum execution time: 69_619_000 picoseconds. + Weight::from_parts(79_242_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Claims Claims (r:1 w:2) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:2) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:2) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Preclaims (r:1 w:1) + /// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured) + fn move_claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `440` + // Estimated: `3905` + // Minimum execution time: 22_066_000 picoseconds. + Weight::from_parts(22_483_000, 0) + .saturating_add(Weight::from_parts(0, 3905)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(7)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs b/polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs new file mode 100644 index 0000000000000000000000000000000000000000..0e7420cba2e6c981d4f9c0dd9e3c95c9ce26f1c5 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs @@ -0,0 +1,222 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::crowdloan` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_common::crowdloan +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_common_crowdloan.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::crowdloan`. +pub struct WeightInfo(PhantomData); +impl runtime_common::crowdloan::WeightInfo for WeightInfo { + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan NextFundIndex (r:1 w:1) + /// Proof Skipped: Crowdloan NextFundIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn create() -> Weight { + // Proof Size summary in bytes: + // Measured: `438` + // Estimated: `3903` + // Minimum execution time: 50_399_000 picoseconds. + Weight::from_parts(51_641_000, 0) + .saturating_add(Weight::from_parts(0, 3903)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Crowdloan EndingsCount (r:1 w:0) + /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + fn contribute() -> Weight { + // Proof Size summary in bytes: + // Measured: `530` + // Estimated: `3995` + // Minimum execution time: 128_898_000 picoseconds. + Weight::from_parts(130_277_000, 0) + .saturating_add(Weight::from_parts(0, 3995)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + /// Proof Skipped: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + fn withdraw() -> Weight { + // Proof Size summary in bytes: + // Measured: `689` + // Estimated: `6196` + // Minimum execution time: 69_543_000 picoseconds. + Weight::from_parts(71_522_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `k` is `[0, 1000]`. + fn refund(k: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `127 + k * (189 ±0)` + // Estimated: `140 + k * (189 ±0)` + // Minimum execution time: 50_735_000 picoseconds. + Weight::from_parts(52_282_000, 0) + .saturating_add(Weight::from_parts(0, 140)) + // Standard Error: 21_607 + .saturating_add(Weight::from_parts(38_955_985, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(k.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(k.into()))) + .saturating_add(Weight::from_parts(0, 189).saturating_mul(k.into())) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn dissolve() -> Weight { + // Proof Size summary in bytes: + // Measured: `515` + // Estimated: `6196` + // Minimum execution time: 43_100_000 picoseconds. + Weight::from_parts(44_272_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + fn edit() -> Weight { + // Proof Size summary in bytes: + // Measured: `235` + // Estimated: `3700` + // Minimum execution time: 18_702_000 picoseconds. + Weight::from_parts(19_408_000, 0) + .saturating_add(Weight::from_parts(0, 3700)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Crowdloan Funds (r:1 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + fn add_memo() -> Weight { + // Proof Size summary in bytes: + // Measured: `412` + // Estimated: `3877` + // Minimum execution time: 25_568_000 picoseconds. + Weight::from_parts(26_203_000, 0) + .saturating_add(Weight::from_parts(0, 3877)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Crowdloan Funds (r:1 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + fn poke() -> Weight { + // Proof Size summary in bytes: + // Measured: `239` + // Estimated: `3704` + // Minimum execution time: 17_832_000 picoseconds. + Weight::from_parts(18_769_000, 0) + .saturating_add(Weight::from_parts(0, 3704)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Crowdloan EndingsCount (r:1 w:1) + /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan Funds (r:100 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Paras ParaLifecycles (r:100 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:100 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions Winning (r:1 w:1) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:100 w:100) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:100 w:100) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `n` is `[2, 100]`. + fn on_initialize(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `197 + n * (356 ±0)` + // Estimated: `5385 + n * (2832 ±0)` + // Minimum execution time: 128_319_000 picoseconds. + Weight::from_parts(130_877_000, 0) + .saturating_add(Weight::from_parts(0, 5385)) + // Standard Error: 61_381 + .saturating_add(Weight::from_parts(60_209_202, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2832).saturating_mul(n.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs b/polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs new file mode 100644 index 0000000000000000000000000000000000000000..0a56562a1a95f24e9efddc6c26e16c4feeaf37c2 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs @@ -0,0 +1,221 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::paras_registrar` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_common::paras_registrar +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_common_paras_registrar.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::paras_registrar`. +pub struct WeightInfo(PhantomData); +impl runtime_common::paras_registrar::WeightInfo for WeightInfo { + /// Storage: Registrar NextFreeParaId (r:1 w:1) + /// Proof Skipped: Registrar NextFreeParaId (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + fn reserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `97` + // Estimated: `3562` + // Minimum execution time: 29_948_000 picoseconds. + Weight::from_parts(30_433_000, 0) + .saturating_add(Weight::from_parts(0, 3562)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:0 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpcomingParasGenesis (r:0 w:1) + /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) + fn register() -> Weight { + // Proof Size summary in bytes: + // Measured: `616` + // Estimated: `4081` + // Minimum execution time: 6_332_113_000 picoseconds. + Weight::from_parts(6_407_158_000, 0) + .saturating_add(Weight::from_parts(0, 4081)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:0 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpcomingParasGenesis (r:0 w:1) + /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) + fn force_register() -> Weight { + // Proof Size summary in bytes: + // Measured: `533` + // Estimated: `3998` + // Minimum execution time: 6_245_403_000 picoseconds. + Weight::from_parts(6_289_575_000, 0) + .saturating_add(Weight::from_parts(0, 3998)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeHash (r:1 w:0) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: Registrar PendingSwap (r:0 w:1) + /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) + fn deregister() -> Weight { + // Proof Size summary in bytes: + // Measured: `476` + // Estimated: `3941` + // Minimum execution time: 49_822_000 picoseconds. + Weight::from_parts(50_604_000, 0) + .saturating_add(Weight::from_parts(0, 3941)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Registrar Paras (r:1 w:0) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:2 w:2) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar PendingSwap (r:1 w:1) + /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan Funds (r:2 w:2) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:2 w:2) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + fn swap() -> Weight { + // Proof Size summary in bytes: + // Measured: `780` + // Estimated: `6720` + // Minimum execution time: 55_166_000 picoseconds. + Weight::from_parts(56_913_000, 0) + .saturating_add(Weight::from_parts(0, 6720)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Paras FutureCodeHash (r:1 w:1) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:1 w:1) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeCooldowns (r:1 w:1) + /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[1, 3145728]`. + fn schedule_code_upgrade(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `464` + // Estimated: `3929` + // Minimum execution time: 43_650_000 picoseconds. + Weight::from_parts(43_918_000, 0) + .saturating_add(Weight::from_parts(0, 3929)) + // Standard Error: 6 + .saturating_add(Weight::from_parts(2_041, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[1, 1048576]`. + fn set_current_head(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_666_000 picoseconds. + Weight::from_parts(8_893_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(855, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_slots.rs b/polkadot/runtime/rococo/src/weights/runtime_common_slots.rs new file mode 100644 index 0000000000000000000000000000000000000000..23ab1ed3ee0efff9e95fd3526d022c9becad7b93 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_common_slots.rs @@ -0,0 +1,132 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::slots` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_common::slots +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_common_slots.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::slots`. +pub struct WeightInfo(PhantomData); +impl runtime_common::slots::WeightInfo for WeightInfo { + /// Storage: Slots Leases (r:1 w:1) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_lease() -> Weight { + // Proof Size summary in bytes: + // Measured: `287` + // Estimated: `3752` + // Minimum execution time: 29_932_000 picoseconds. + Weight::from_parts(30_334_000, 0) + .saturating_add(Weight::from_parts(0, 3752)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Slots Leases (r:101 w:100) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:200 w:200) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:100 w:100) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 100]`. + /// The range of component `t` is `[0, 100]`. + fn manage_lease_period_start(c: u32, t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `26 + c * (47 ±0) + t * (308 ±0)` + // Estimated: `2800 + c * (2526 ±0) + t * (2789 ±0)` + // Minimum execution time: 634_547_000 picoseconds. + Weight::from_parts(643_045_000, 0) + .saturating_add(Weight::from_parts(0, 2800)) + // Standard Error: 81_521 + .saturating_add(Weight::from_parts(2_705_219, 0).saturating_mul(c.into())) + // Standard Error: 81_521 + .saturating_add(Weight::from_parts(11_464_132, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(t.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(t.into()))) + .saturating_add(Weight::from_parts(0, 2526).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 2789).saturating_mul(t.into())) + } + /// Storage: Slots Leases (r:1 w:1) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:8 w:8) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn clear_all_leases() -> Weight { + // Proof Size summary in bytes: + // Measured: `2759` + // Estimated: `21814` + // Minimum execution time: 129_756_000 picoseconds. + Weight::from_parts(131_810_000, 0) + .saturating_add(Weight::from_parts(0, 21814)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(9)) + } + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + fn trigger_onboard() -> Weight { + // Proof Size summary in bytes: + // Measured: `707` + // Estimated: `4172` + // Minimum execution time: 29_527_000 picoseconds. + Weight::from_parts(30_055_000, 0) + .saturating_add(Weight::from_parts(0, 4172)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs new file mode 100644 index 0000000000000000000000000000000000000000..ac0f05301b486dbdbb8c0ca004e195ab47171ff3 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs @@ -0,0 +1,91 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::assigner_on_demand` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-fljshgub-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_parachains::assigner_on_demand +// --chain=rococo-dev +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::assigner_on_demand`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::assigner_on_demand::WeightInfo for WeightInfo { + /// Storage: `OnDemandAssignmentProvider::SpotTraffic` (r:1 w:0) + /// Proof: `OnDemandAssignmentProvider::SpotTraffic` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `OnDemandAssignmentProvider::OnDemandQueue` (r:1 w:1) + /// Proof: `OnDemandAssignmentProvider::OnDemandQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// The range of component `s` is `[1, 9999]`. + fn place_order_keep_alive(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `297 + s * (4 ±0)` + // Estimated: `3762 + s * (4 ±0)` + // Minimum execution time: 33_522_000 picoseconds. + Weight::from_parts(35_436_835, 0) + .saturating_add(Weight::from_parts(0, 3762)) + // Standard Error: 129 + .saturating_add(Weight::from_parts(14_041, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) + } + /// Storage: `OnDemandAssignmentProvider::SpotTraffic` (r:1 w:0) + /// Proof: `OnDemandAssignmentProvider::SpotTraffic` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `OnDemandAssignmentProvider::OnDemandQueue` (r:1 w:1) + /// Proof: `OnDemandAssignmentProvider::OnDemandQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// The range of component `s` is `[1, 9999]`. + fn place_order_allow_death(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `297 + s * (4 ±0)` + // Estimated: `3762 + s * (4 ±0)` + // Minimum execution time: 33_488_000 picoseconds. + Weight::from_parts(34_848_934, 0) + .saturating_add(Weight::from_parts(0, 3762)) + // Standard Error: 143 + .saturating_add(Weight::from_parts(14_215, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs new file mode 100644 index 0000000000000000000000000000000000000000..29f387657786afd1e07c207d733b7cfddfd4d83a --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs @@ -0,0 +1,157 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::configuration` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-fljshgub-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_parachains::configuration +// --chain=rococo-dev +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::configuration`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::configuration::WeightInfo for WeightInfo { + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_block_number() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_051_000 picoseconds. + Weight::from_parts(9_496_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_u32() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_104_000 picoseconds. + Weight::from_parts(9_403_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_option_u32() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_112_000 picoseconds. + Weight::from_parts(9_495_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn set_hrmp_open_request_ttl() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_000_000_000_000 picoseconds. + Weight::from_parts(2_000_000_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_balance() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_011_000 picoseconds. + Weight::from_parts(9_460_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_executor_params() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_940_000 picoseconds. + Weight::from_parts(10_288_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_perbill() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_192_000 picoseconds. + Weight::from_parts(9_595_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs new file mode 100644 index 0000000000000000000000000000000000000000..63a8c3addc7da4296041627ee8492945945bce7f --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs @@ -0,0 +1,61 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::disputes` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_parachains::disputes +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_parachains_disputes.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::disputes`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::disputes::WeightInfo for WeightInfo { + /// Storage: ParasDisputes Frozen (r:0 w:1) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + fn force_unfreeze() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_937_000 picoseconds. + Weight::from_parts(3_082_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs new file mode 100644 index 0000000000000000000000000000000000000000..9f1cf65efa649972f111be4029b00ca40c7554da --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs @@ -0,0 +1,292 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::hrmp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_parachains::hrmp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_parachains_hrmp.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::hrmp`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::hrmp::WeightInfo for WeightInfo { + /// Storage: Paras ParaLifecycles (r:2 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_init_open_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `704` + // Estimated: `6644` + // Minimum execution time: 41_564_000 picoseconds. + Weight::from_parts(42_048_000, 0) + .saturating_add(Weight::from_parts(0, 6644)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_accept_open_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `936` + // Estimated: `4401` + // Minimum execution time: 43_570_000 picoseconds. + Weight::from_parts(44_089_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_close_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `807` + // Estimated: `4272` + // Minimum execution time: 36_594_000 picoseconds. + Weight::from_parts(37_090_000, 0) + .saturating_add(Weight::from_parts(0, 4272)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:254 w:254) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:0 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelContents (r:0 w:254) + /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:0 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 127]`. + /// The range of component `e` is `[0, 127]`. + fn force_clean_hrmp(i: u32, e: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `264 + e * (100 ±0) + i * (100 ±0)` + // Estimated: `3726 + e * (2575 ±0) + i * (2575 ±0)` + // Minimum execution time: 1_085_140_000 picoseconds. + Weight::from_parts(1_100_901_000, 0) + .saturating_add(Weight::from_parts(0, 3726)) + // Standard Error: 98_982 + .saturating_add(Weight::from_parts(3_229_112, 0).saturating_mul(i.into())) + // Standard Error: 98_982 + .saturating_add(Weight::from_parts(3_210_944, 0).saturating_mul(e.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into()))) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(e.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(i.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(e.into()))) + .saturating_add(Weight::from_parts(0, 2575).saturating_mul(e.into())) + .saturating_add(Weight::from_parts(0, 2575).saturating_mul(i.into())) + } + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:256 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:128 w:128) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:0 w:128) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn force_process_hrmp_open(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `779 + c * (136 ±0)` + // Estimated: `2234 + c * (5086 ±0)` + // Minimum execution time: 10_497_000 picoseconds. + Weight::from_parts(6_987_455, 0) + .saturating_add(Weight::from_parts(0, 2234)) + // Standard Error: 18_540 + .saturating_add(Weight::from_parts(18_788_534, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((6_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 5086).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:128 w:128) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequests (r:0 w:128) + /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelContents (r:0 w:128) + /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn force_process_hrmp_close(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `335 + c * (124 ±0)` + // Estimated: `1795 + c * (2600 ±0)` + // Minimum execution time: 6_575_000 picoseconds. + Weight::from_parts(1_228_642, 0) + .saturating_add(Weight::from_parts(0, 1795)) + // Standard Error: 14_826 + .saturating_add(Weight::from_parts(11_604_038, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 2600).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn hrmp_cancel_open_request(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1026 + c * (13 ±0)` + // Estimated: `4295 + c * (15 ±0)` + // Minimum execution time: 22_301_000 picoseconds. + Weight::from_parts(26_131_473, 0) + .saturating_add(Weight::from_parts(0, 4295)) + // Standard Error: 830 + .saturating_add(Weight::from_parts(49_448, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 15).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn clean_open_channel_requests(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `243 + c * (63 ±0)` + // Estimated: `1722 + c * (2538 ±0)` + // Minimum execution time: 5_234_000 picoseconds. + Weight::from_parts(7_350_270, 0) + .saturating_add(Weight::from_parts(0, 1722)) + // Standard Error: 3_105 + .saturating_add(Weight::from_parts(2_981_935, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 2538).saturating_mul(c.into())) + } + /// Storage: Paras ParaLifecycles (r:2 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:2 w:2) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:2 w:2) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + fn force_open_hrmp_channel(_c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `704` + // Estimated: `6644` + // Minimum execution time: 55_611_000 picoseconds. + Weight::from_parts(56_488_000, 0) + .saturating_add(Weight::from_parts(0, 6644)) + .saturating_add(T::DbWeight::get().reads(14)) + .saturating_add(T::DbWeight::get().writes(8)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs new file mode 100644 index 0000000000000000000000000000000000000000..a121ad774cefecf91e57838e03107fde22674f94 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs @@ -0,0 +1,74 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::inclusion` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_parachains::inclusion +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_parachains_inclusion.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::inclusion`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::inclusion::WeightInfo for WeightInfo { + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:999) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// The range of component `i` is `[1, 1000]`. + fn receive_upward_messages(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `33280` + // Estimated: `36283` + // Minimum execution time: 71_094_000 picoseconds. + Weight::from_parts(71_436_000, 0) + .saturating_add(Weight::from_parts(0, 36283)) + // Standard Error: 22_149 + .saturating_add(Weight::from_parts(51_495_472, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs new file mode 100644 index 0000000000000000000000000000000000000000..5c627507dfb682a603152fee2155b620773dcd49 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs @@ -0,0 +1,66 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::initializer` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_parachains::initializer +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_parachains_initializer.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::initializer`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::initializer::WeightInfo for WeightInfo { + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `d` is `[0, 65536]`. + fn force_approve(d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + d * (11 ±0)` + // Estimated: `1480 + d * (11 ±0)` + // Minimum execution time: 3_771_000 picoseconds. + Weight::from_parts(6_491_437, 0) + .saturating_add(Weight::from_parts(0, 1480)) + // Standard Error: 9 + .saturating_add(Weight::from_parts(1_356, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 11).saturating_mul(d.into())) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs new file mode 100644 index 0000000000000000000000000000000000000000..dfd95006dc7d0a6cedeeab9908d99a2c1c7e561a --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs @@ -0,0 +1,294 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::paras` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_parachains::paras +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_parachains_paras.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::paras`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::paras::WeightInfo for WeightInfo { + /// Storage: Paras CurrentCodeHash (r:1 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PastCodeMeta (r:1 w:1) + /// Proof Skipped: Paras PastCodeMeta (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PastCodePruning (r:1 w:1) + /// Proof Skipped: Paras PastCodePruning (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PastCodeHash (r:0 w:1) + /// Proof Skipped: Paras PastCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:0 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn force_set_current_code(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `8309` + // Estimated: `11774` + // Minimum execution time: 31_941_000 picoseconds. + Weight::from_parts(32_139_000, 0) + .saturating_add(Weight::from_parts(0, 11774)) + // Standard Error: 5 + .saturating_add(Weight::from_parts(2_011, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// The range of component `s` is `[1, 1048576]`. + fn force_set_current_head(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_275_000 picoseconds. + Weight::from_parts(8_321_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(858, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: Paras Heads (r:0 w:1) + fn force_set_most_recent_context() -> Weight { + Weight::from_parts(10_155_000, 0) + // Standard Error: 0 + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras FutureCodeHash (r:1 w:1) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeCooldowns (r:1 w:1) + /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn force_schedule_code_upgrade(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `8715` + // Estimated: `12180` + // Minimum execution time: 49_923_000 picoseconds. + Weight::from_parts(50_688_000, 0) + .saturating_add(Weight::from_parts(0, 12180)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_976, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `s` is `[1, 1048576]`. + fn force_note_new_head(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `95` + // Estimated: `3560` + // Minimum execution time: 14_408_000 picoseconds. + Weight::from_parts(14_647_000, 0) + .saturating_add(Weight::from_parts(0, 3560)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(858, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + fn force_queue_action() -> Weight { + // Proof Size summary in bytes: + // Measured: `4288` + // Estimated: `7753` + // Minimum execution time: 20_009_000 picoseconds. + Weight::from_parts(20_518_000, 0) + .saturating_add(Weight::from_parts(0, 7753)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn add_trusted_validation_code(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `946` + // Estimated: `4411` + // Minimum execution time: 80_626_000 picoseconds. + Weight::from_parts(52_721_755, 0) + .saturating_add(Weight::from_parts(0, 4411)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Paras CodeByHashRefs (r:1 w:0) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:0 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + fn poke_unused_validation_code() -> Weight { + // Proof Size summary in bytes: + // Measured: `28` + // Estimated: `3493` + // Minimum execution time: 6_692_000 picoseconds. + Weight::from_parts(7_009_000, 0) + .saturating_add(Weight::from_parts(0, 3493)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement() -> Weight { + // Proof Size summary in bytes: + // Measured: `26682` + // Estimated: `30147` + // Minimum execution time: 87_994_000 picoseconds. + Weight::from_parts(89_933_000, 0) + .saturating_add(Weight::from_parts(0, 30147)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras UpcomingUpgrades (r:1 w:1) + /// Proof Skipped: Paras UpcomingUpgrades (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:0 w:100) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_upgrade_accept() -> Weight { + // Proof Size summary in bytes: + // Measured: `27523` + // Estimated: `30988` + // Minimum execution time: 783_222_000 picoseconds. + Weight::from_parts(794_959_000, 0) + .saturating_add(Weight::from_parts(0, 30988)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(104)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_upgrade_reject() -> Weight { + // Proof Size summary in bytes: + // Measured: `27214` + // Estimated: `30679` + // Minimum execution time: 87_424_000 picoseconds. + Weight::from_parts(88_737_000, 0) + .saturating_add(Weight::from_parts(0, 30679)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_onboarding_accept() -> Weight { + // Proof Size summary in bytes: + // Measured: `26991` + // Estimated: `30456` + // Minimum execution time: 612_485_000 picoseconds. + Weight::from_parts(621_670_000, 0) + .saturating_add(Weight::from_parts(0, 30456)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_onboarding_reject() -> Weight { + // Proof Size summary in bytes: + // Measured: `26682` + // Estimated: `30147` + // Minimum execution time: 86_673_000 picoseconds. + Weight::from_parts(87_424_000, 0) + .saturating_add(Weight::from_parts(0, 30147)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs new file mode 100644 index 0000000000000000000000000000000000000000..a102d1903b2f2b4a757edf3bb96809c982f31383 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs @@ -0,0 +1,173 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . +//! Autogenerated weights for `runtime_parachains::paras_inherent` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-11-20, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 128 + +// Executed Command: +// target/release/polkadot +// benchmark +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_parachains::paras_inherent +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs +// --header=./file_header.txt + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `runtime_parachains::paras_inherent`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::paras_inherent::WeightInfo for WeightInfo { + // Storage: ParaInherent Included (r:1 w:1) + // Storage: System ParentHash (r:1 w:0) + // Storage: ParaScheduler AvailabilityCores (r:1 w:1) + // Storage: ParasShared CurrentSessionIndex (r:1 w:0) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: ParaSessionInfo Sessions (r:1 w:0) + // Storage: ParasDisputes Disputes (r:1 w:1) + // Storage: ParasDisputes Included (r:1 w:1) + // Storage: ParasDisputes SpamSlots (r:1 w:1) + // Storage: ParasDisputes Frozen (r:1 w:0) + // Storage: ParaInclusion PendingAvailability (r:2 w:1) + // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + // Storage: Paras Parachains (r:1 w:0) + // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Storage: Hrmp HrmpChannelDigests (r:1 w:1) + // Storage: Paras FutureCodeUpgrades (r:1 w:0) + // Storage: ParaScheduler SessionStartBlock (r:1 w:0) + // Storage: ParaScheduler ParathreadQueue (r:1 w:1) + // Storage: ParaScheduler Scheduled (r:1 w:1) + // Storage: ParaScheduler ValidatorGroups (r:1 w:0) + // Storage: Ump NeedsDispatch (r:1 w:1) + // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) + // Storage: ParaInherent OnChainVotes (r:0 w:1) + // Storage: Hrmp HrmpWatermarks (r:0 w:1) + // Storage: Paras Heads (r:0 w:1) + fn enter_variable_disputes(v: u32, ) -> Weight { + Weight::from_parts(352_590_000 as u64, 0) + // Standard Error: 13_000 + .saturating_add(Weight::from_parts(49_254_000 as u64, 0).saturating_mul(v as u64)) + .saturating_add(T::DbWeight::get().reads(24 as u64)) + .saturating_add(T::DbWeight::get().writes(16 as u64)) + } + // Storage: ParaInherent Included (r:1 w:1) + // Storage: System ParentHash (r:1 w:0) + // Storage: ParaScheduler AvailabilityCores (r:1 w:1) + // Storage: ParasShared CurrentSessionIndex (r:1 w:0) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: ParasDisputes Frozen (r:1 w:0) + // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + // Storage: Paras Parachains (r:1 w:0) + // Storage: ParaInclusion PendingAvailability (r:2 w:1) + // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Storage: Hrmp HrmpChannelDigests (r:1 w:1) + // Storage: Paras FutureCodeUpgrades (r:1 w:0) + // Storage: ParasDisputes Disputes (r:1 w:0) + // Storage: ParaScheduler SessionStartBlock (r:1 w:0) + // Storage: ParaScheduler ParathreadQueue (r:1 w:1) + // Storage: ParaScheduler Scheduled (r:1 w:1) + // Storage: ParaScheduler ValidatorGroups (r:1 w:0) + // Storage: Ump NeedsDispatch (r:1 w:1) + // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) + // Storage: ParaInclusion AvailabilityBitfields (r:0 w:1) + // Storage: ParaInherent OnChainVotes (r:0 w:1) + // Storage: ParasDisputes Included (r:0 w:1) + // Storage: Hrmp HrmpWatermarks (r:0 w:1) + // Storage: Paras Heads (r:0 w:1) + fn enter_bitfields() -> Weight { + Weight::from_parts(299_878_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(21 as u64)) + .saturating_add(T::DbWeight::get().writes(15 as u64)) + } + // Storage: ParaInherent Included (r:1 w:1) + // Storage: System ParentHash (r:1 w:0) + // Storage: ParaScheduler AvailabilityCores (r:1 w:1) + // Storage: ParasShared CurrentSessionIndex (r:1 w:0) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: ParasDisputes Frozen (r:1 w:0) + // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + // Storage: Paras Parachains (r:1 w:0) + // Storage: ParaInclusion PendingAvailability (r:2 w:1) + // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Storage: Hrmp HrmpChannelDigests (r:1 w:1) + // Storage: Paras FutureCodeUpgrades (r:1 w:0) + // Storage: ParasDisputes Disputes (r:2 w:0) + // Storage: ParaScheduler SessionStartBlock (r:1 w:0) + // Storage: ParaScheduler ParathreadQueue (r:1 w:1) + // Storage: ParaScheduler Scheduled (r:1 w:1) + // Storage: ParaScheduler ValidatorGroups (r:1 w:0) + // Storage: Paras PastCodeMeta (r:1 w:0) + // Storage: Paras CurrentCodeHash (r:1 w:0) + // Storage: Ump RelayDispatchQueueSize (r:1 w:0) + // Storage: Ump NeedsDispatch (r:1 w:1) + // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) + // Storage: ParaInherent OnChainVotes (r:0 w:1) + // Storage: ParasDisputes Included (r:0 w:1) + // Storage: Hrmp HrmpWatermarks (r:0 w:1) + // Storage: Paras Heads (r:0 w:1) + fn enter_backed_candidates_variable(_v: u32) -> Weight { + Weight::from_parts(442_472_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(25 as u64)) + .saturating_add(T::DbWeight::get().writes(14 as u64)) + } + // Storage: ParaInherent Included (r:1 w:1) + // Storage: System ParentHash (r:1 w:0) + // Storage: ParaScheduler AvailabilityCores (r:1 w:1) + // Storage: ParasShared CurrentSessionIndex (r:1 w:0) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: ParasDisputes Frozen (r:1 w:0) + // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + // Storage: Paras Parachains (r:1 w:0) + // Storage: ParaInclusion PendingAvailability (r:2 w:1) + // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Storage: Hrmp HrmpChannelDigests (r:1 w:1) + // Storage: Paras FutureCodeUpgrades (r:1 w:0) + // Storage: ParasDisputes Disputes (r:2 w:0) + // Storage: ParaScheduler SessionStartBlock (r:1 w:0) + // Storage: ParaScheduler ParathreadQueue (r:1 w:1) + // Storage: ParaScheduler Scheduled (r:1 w:1) + // Storage: ParaScheduler ValidatorGroups (r:1 w:0) + // Storage: Paras PastCodeMeta (r:1 w:0) + // Storage: Paras CurrentCodeHash (r:1 w:0) + // Storage: Ump RelayDispatchQueueSize (r:1 w:0) + // Storage: Ump NeedsDispatch (r:1 w:1) + // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) + // Storage: ParaInherent OnChainVotes (r:0 w:1) + // Storage: ParasDisputes Included (r:0 w:1) + // Storage: Hrmp HrmpWatermarks (r:0 w:1) + // Storage: Paras Heads (r:0 w:1) + fn enter_backed_candidate_code_upgrade() -> Weight { + Weight::from_parts(36_903_411_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(25 as u64)) + .saturating_add(T::DbWeight::get().writes(14 as u64)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/xcm/mod.rs b/polkadot/runtime/rococo/src/weights/xcm/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..1d613717dc52798ece0ac9c484b8f91b66f53803 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/xcm/mod.rs @@ -0,0 +1,290 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +mod pallet_xcm_benchmarks_fungible; +mod pallet_xcm_benchmarks_generic; + +use crate::Runtime; +use frame_support::weights::Weight; +use sp_std::prelude::*; +use xcm::{latest::prelude::*, DoubleEncoded}; + +use pallet_xcm_benchmarks_fungible::WeightInfo as XcmBalancesWeight; +use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; + +/// Types of asset supported by the Rococo runtime. +pub enum AssetTypes { + /// An asset backed by `pallet-balances`. + Balances, + /// Unknown asset. + Unknown, +} + +impl From<&MultiAsset> for AssetTypes { + fn from(asset: &MultiAsset) -> Self { + match asset { + MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), .. } => + AssetTypes::Balances, + _ => AssetTypes::Unknown, + } + } +} + +trait WeighMultiAssets { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight; +} + +// Rococo only knows about one asset, the balances pallet. +const MAX_ASSETS: u64 = 1; + +impl WeighMultiAssets for MultiAssetFilter { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { + match self { + Self::Definite(assets) => assets + .inner() + .into_iter() + .map(From::from) + .map(|t| match t { + AssetTypes::Balances => balances_weight, + AssetTypes::Unknown => Weight::MAX, + }) + .fold(Weight::zero(), |acc, x| acc.saturating_add(x)), + // We don't support any NFTs on Rococo, so these two variants will always match + // only 1 kind of fungible asset. + Self::Wild(AllOf { .. } | AllOfCounted { .. }) => balances_weight, + Self::Wild(AllCounted(count)) => + balances_weight.saturating_mul(MAX_ASSETS.min(*count as u64)), + Self::Wild(All) => balances_weight.saturating_mul(MAX_ASSETS), + } + } +} + +impl WeighMultiAssets for MultiAssets { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { + self.inner() + .into_iter() + .map(|m| >::from(m)) + .map(|t| match t { + AssetTypes::Balances => balances_weight, + AssetTypes::Unknown => Weight::MAX, + }) + .fold(Weight::zero(), |acc, x| acc.saturating_add(x)) + } +} + +pub struct RococoXcmWeight(core::marker::PhantomData); +impl XcmWeightInfo for RococoXcmWeight { + fn withdraw_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) + } + fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { + // Rococo doesn't support ReserveAssetDeposited, so this benchmark has a default weight + assets.weigh_multi_assets(XcmBalancesWeight::::reserve_asset_deposited()) + } + fn receive_teleported_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) + } + fn query_response( + _query_id: &u64, + _response: &Response, + _max_weight: &Weight, + _querier: &Option, + ) -> Weight { + XcmGeneric::::query_response() + } + fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) + } + fn transfer_reserve_asset( + assets: &MultiAssets, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::transfer_reserve_asset()) + } + fn transact( + _origin_kind: &OriginKind, + _require_weight_at_most: &Weight, + _call: &DoubleEncoded, + ) -> Weight { + XcmGeneric::::transact() + } + fn hrmp_new_channel_open_request( + _sender: &u32, + _max_message_size: &u32, + _max_capacity: &u32, + ) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn hrmp_channel_accepted(_recipient: &u32) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn hrmp_channel_closing(_initiator: &u32, _sender: &u32, _recipient: &u32) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn clear_origin() -> Weight { + XcmGeneric::::clear_origin() + } + fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + XcmGeneric::::descend_origin() + } + fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::report_error() + } + + fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::deposit_asset()) + } + fn deposit_reserve_asset( + assets: &MultiAssetFilter, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::deposit_reserve_asset()) + } + fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + // Rococo does not currently support exchange asset operations + Weight::MAX + } + fn initiate_reserve_withdraw( + assets: &MultiAssetFilter, + _reserve: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) + } + fn initiate_teleport( + assets: &MultiAssetFilter, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::initiate_teleport()) + } + fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + XcmGeneric::::report_holding() + } + fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + XcmGeneric::::buy_execution() + } + fn refund_surplus() -> Weight { + XcmGeneric::::refund_surplus() + } + fn set_error_handler(_xcm: &Xcm) -> Weight { + XcmGeneric::::set_error_handler() + } + fn set_appendix(_xcm: &Xcm) -> Weight { + XcmGeneric::::set_appendix() + } + fn clear_error() -> Weight { + XcmGeneric::::clear_error() + } + fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + XcmGeneric::::claim_asset() + } + fn trap(_code: &u64) -> Weight { + XcmGeneric::::trap() + } + fn subscribe_version(_query_id: &QueryId, _max_response_weight: &Weight) -> Weight { + XcmGeneric::::subscribe_version() + } + fn unsubscribe_version() -> Weight { + XcmGeneric::::unsubscribe_version() + } + fn burn_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + } + fn expect_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + } + fn expect_origin(_origin: &Option) -> Weight { + XcmGeneric::::expect_origin() + } + fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { + XcmGeneric::::expect_error() + } + fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight { + XcmGeneric::::expect_transact_status() + } + fn query_pallet(_module_name: &Vec, _response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::query_pallet() + } + fn expect_pallet( + _index: &u32, + _name: &Vec, + _module_name: &Vec, + _crate_major: &u32, + _min_crate_minor: &u32, + ) -> Weight { + XcmGeneric::::expect_pallet() + } + fn report_transact_status(_response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::report_transact_status() + } + fn clear_transact_status() -> Weight { + XcmGeneric::::clear_transact_status() + } + fn universal_origin(_: &Junction) -> Weight { + // Rococo does not currently support universal origin operations + Weight::MAX + } + fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { + // Rococo relay should not support export message operations + Weight::MAX + } + fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Rococo does not currently support asset locking operations + Weight::MAX + } + fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Rococo does not currently support asset locking operations + Weight::MAX + } + fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Rococo does not currently support asset locking operations + Weight::MAX + } + fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Rococo does not currently support asset locking operations + Weight::MAX + } + fn set_fees_mode(_: &bool) -> Weight { + XcmGeneric::::set_fees_mode() + } + fn set_topic(_topic: &[u8; 32]) -> Weight { + XcmGeneric::::set_topic() + } + fn clear_topic() -> Weight { + XcmGeneric::::clear_topic() + } + fn alias_origin(_: &MultiLocation) -> Weight { + // XCM Executor does not currently support alias origin operations + Weight::MAX + } + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + XcmGeneric::::unpaid_execution() + } +} + +#[test] +fn all_counted_has_a_sane_weight_upper_limit() { + let assets = MultiAssetFilter::Wild(AllCounted(4294967295)); + let weight = Weight::from_parts(1000, 1000); + + assert_eq!(assets.weigh_multi_assets(weight), weight * MAX_ASSETS); +} diff --git a/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs b/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs new file mode 100644 index 0000000000000000000000000000000000000000..59c49e4f8c821beb00a9493ad7b07928cfe6daf9 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs @@ -0,0 +1,179 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm_benchmarks::fungible` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-gghbxkbs-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_xcm_benchmarks::fungible +// --chain=rococo-dev +// --header=./file_header.txt +// --template=./xcm/pallet-xcm-benchmarks/template.hbs +// --output=./runtime/rococo/src/weights/xcm/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm_benchmarks::fungible`. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn withdraw_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `3593` + // Minimum execution time: 24_892_000 picoseconds. + Weight::from_parts(25_219_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn transfer_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `6196` + // Minimum execution time: 52_112_000 picoseconds. + Weight::from_parts(53_104_000, 6196) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn transfer_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `210` + // Estimated: `6196` + // Minimum execution time: 76_459_000 picoseconds. + Weight::from_parts(79_152_000, 6196) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn reserve_asset_deposited() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_000_000_000_000 picoseconds. + Weight::from_parts(2_000_000_000_000, 0) + } + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn initiate_reserve_withdraw() -> Weight { + // Proof Size summary in bytes: + // Measured: `109` + // Estimated: `3574` + // Minimum execution time: 29_734_000 picoseconds. + Weight::from_parts(30_651_000, 3574) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn receive_teleported_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `3593` + // Minimum execution time: 23_028_000 picoseconds. + Weight::from_parts(23_687_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn deposit_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 26_399_000 picoseconds. + Weight::from_parts(27_262_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn deposit_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `109` + // Estimated: `3593` + // Minimum execution time: 52_015_000 picoseconds. + Weight::from_parts(53_498_000, 3593) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn initiate_teleport() -> Weight { + // Proof Size summary in bytes: + // Measured: `109` + // Estimated: `3593` + // Minimum execution time: 53_833_000 picoseconds. + Weight::from_parts(55_688_000, 3593) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs new file mode 100644 index 0000000000000000000000000000000000000000..df2f9b2d0e8d4e031af8daa016ecefa85f6d1ff3 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -0,0 +1,351 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm_benchmarks::generic` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-02, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm3`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/var/lib/gitlab-runner/builds/zyw4fam_/0/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_xcm_benchmarks::generic +// --chain=rococo-dev +// --header=./file_header.txt +// --template=./xcm/pallet-xcm-benchmarks/template.hbs +// --output=./runtime/rococo/src/weights/xcm/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm_benchmarks::generic`. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn report_holding() -> Weight { + // Proof Size summary in bytes: + // Measured: `565` + // Estimated: `4030` + // Minimum execution time: 36_305_000 picoseconds. + Weight::from_parts(37_096_000, 4030) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + pub(crate) fn buy_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_831_000 picoseconds. + Weight::from_parts(2_904_000, 0) + } + /// Storage: XcmPallet Queries (r:1 w:0) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + pub(crate) fn query_response() -> Weight { + // Proof Size summary in bytes: + // Measured: `169` + // Estimated: `3634` + // Minimum execution time: 11_769_000 picoseconds. + Weight::from_parts(12_122_000, 3634) + .saturating_add(T::DbWeight::get().reads(1)) + } + pub(crate) fn transact() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 12_293_000 picoseconds. + Weight::from_parts(12_522_000, 0) + } + pub(crate) fn refund_surplus() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_858_000 picoseconds. + Weight::from_parts(2_965_000, 0) + } + pub(crate) fn set_error_handler() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_623_000 picoseconds. + Weight::from_parts(2_774_000, 0) + } + pub(crate) fn set_appendix() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_664_000 picoseconds. + Weight::from_parts(2_752_000, 0) + } + pub(crate) fn clear_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_646_000 picoseconds. + Weight::from_parts(2_709_000, 0) + } + pub(crate) fn descend_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_602_000 picoseconds. + Weight::from_parts(3_669_000, 0) + } + pub(crate) fn clear_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_609_000 picoseconds. + Weight::from_parts(2_721_000, 0) + } + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn report_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `565` + // Estimated: `4030` + // Minimum execution time: 31_776_000 picoseconds. + Weight::from_parts(32_354_000, 4030) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: XcmPallet AssetTraps (r:1 w:1) + /// Proof Skipped: XcmPallet AssetTraps (max_values: None, max_size: None, mode: Measured) + pub(crate) fn claim_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `226` + // Estimated: `3691` + // Minimum execution time: 15_912_000 picoseconds. + Weight::from_parts(16_219_000, 3691) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub(crate) fn trap() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_704_000 picoseconds. + Weight::from_parts(2_777_000, 0) + } + /// Storage: XcmPallet VersionNotifyTargets (r:1 w:1) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn subscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `565` + // Estimated: `4030` + // Minimum execution time: 38_690_000 picoseconds. + Weight::from_parts(39_157_000, 4030) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:0 w:1) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + pub(crate) fn unsubscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_943_000 picoseconds. + Weight::from_parts(5_128_000, 0) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub(crate) fn burn_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_438_000 picoseconds. + Weight::from_parts(6_500_000, 0) + } + pub(crate) fn expect_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_773_000 picoseconds. + Weight::from_parts(4_840_000, 0) + } + pub(crate) fn expect_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_818_000 picoseconds. + Weight::from_parts(2_893_000, 0) + } + pub(crate) fn expect_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_611_000 picoseconds. + Weight::from_parts(2_708_000, 0) + } + pub(crate) fn expect_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_870_000 picoseconds. + Weight::from_parts(2_958_000, 0) + } + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn query_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `565` + // Estimated: `4030` + // Minimum execution time: 40_735_000 picoseconds. + Weight::from_parts(66_023_000, 4030) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + pub(crate) fn expect_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_293_000 picoseconds. + Weight::from_parts(18_088_000, 0) + } + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn report_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `565` + // Estimated: `4030` + // Minimum execution time: 31_438_000 picoseconds. + Weight::from_parts(32_086_000, 4030) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + pub(crate) fn clear_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_676_000 picoseconds. + Weight::from_parts(2_746_000, 0) + } + pub(crate) fn set_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_629_000 picoseconds. + Weight::from_parts(2_724_000, 0) + } + pub(crate) fn clear_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_602_000 picoseconds. + Weight::from_parts(2_671_000, 0) + } + pub(crate) fn set_fees_mode() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_681_000 picoseconds. + Weight::from_parts(2_768_000, 0) + } + pub(crate) fn unpaid_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_764_000 picoseconds. + Weight::from_parts(2_865_000, 0) + } +} diff --git a/polkadot/runtime/rococo/src/xcm_config.rs b/polkadot/runtime/rococo/src/xcm_config.rs new file mode 100644 index 0000000000000000000000000000000000000000..356cffaa0ba2b6582582c1bdc2e48f5dbe6bb951 --- /dev/null +++ b/polkadot/runtime/rococo/src/xcm_config.rs @@ -0,0 +1,365 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! XCM configuration for Rococo. + +use super::{ + parachains_origin, AccountId, AllPalletsWithSystem, Balances, Dmp, ParaId, Runtime, + RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, WeightToFee, XcmPallet, +}; +use frame_support::{ + match_types, parameter_types, + traits::{Contains, Everything, Nothing}, + weights::Weight, +}; +use frame_system::EnsureRoot; +use rococo_runtime_constants::currency::CENTS; +use runtime_common::{ + crowdloan, paras_registrar, + xcm_sender::{ChildParachainRouter, ExponentialPrice}, + ToAuthor, +}; +use sp_core::ConstU32; +use xcm::latest::prelude::*; +use xcm_builder::{ + AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, + AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative, + ChildParachainConvertsVia, ChildSystemParachainAsSuperuser, + CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds, IsChildSystemParachain, IsConcrete, + MintLocation, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, + TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, + WithUniqueTopic, +}; +use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; + +parameter_types! { + pub const TokenLocation: MultiLocation = Here.into_location(); + pub const ThisNetwork: NetworkId = NetworkId::Rococo; + pub UniversalLocation: InteriorMultiLocation = ThisNetwork::get().into(); + pub CheckAccount: AccountId = XcmPallet::check_account(); + pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); +} + +pub type LocationConverter = + (ChildParachainConvertsVia, AccountId32Aliases); + +/// Our asset transactor. This is what allows us to interest with the runtime facilities from the +/// point of view of XCM-only concepts like `MultiLocation` and `MultiAsset`. +/// +/// Ours is only aware of the Balances pallet, which is mapped to `RocLocation`. +pub type LocalAssetTransactor = XcmCurrencyAdapter< + // Use this currency: + Balances, + // Use this currency when it is a fungible asset matching the given location or name: + IsConcrete, + // We can convert the MultiLocations with our converter above: + LocationConverter, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We track our teleports in/out to keep total issuance correct. + LocalCheckAccount, +>; + +/// The means that we convert an the XCM message origin location into a local dispatch origin. +type LocalOriginConverter = ( + // A `Signed` origin of the sovereign account that the original location controls. + SovereignSignedViaLocation, + // A child parachain, natively expressed, has the `Parachain` origin. + ChildParachainAsNative, + // The AccountId32 location type can be expressed natively as a `Signed` origin. + SignedAccountId32AsNative, + // A system child parachain, expressed as a Superuser, converts to the `Root` origin. + ChildSystemParachainAsSuperuser, +); + +parameter_types! { + /// The amount of weight an XCM operation takes. This is a safe overestimate. + pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); + /// The asset ID for the asset that we use to pay for message delivery fees. + pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); + /// The base fee for the message delivery fees. + pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); +} + +/// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our +/// individual routers. +pub type XcmRouter = WithUniqueTopic<( + // Only one router so far - use DMP to communicate with child parachains. + ChildParachainRouter< + Runtime, + XcmPallet, + ExponentialPrice, + >, +)>; + +parameter_types! { + pub const Roc: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); + pub const Rockmine: MultiLocation = Parachain(1000).into_location(); + pub const Contracts: MultiLocation = Parachain(1002).into_location(); + pub const Encointer: MultiLocation = Parachain(1003).into_location(); + pub const Tick: MultiLocation = Parachain(100).into_location(); + pub const Trick: MultiLocation = Parachain(110).into_location(); + pub const Track: MultiLocation = Parachain(120).into_location(); + pub const RocForTick: (MultiAssetFilter, MultiLocation) = (Roc::get(), Tick::get()); + pub const RocForTrick: (MultiAssetFilter, MultiLocation) = (Roc::get(), Trick::get()); + pub const RocForTrack: (MultiAssetFilter, MultiLocation) = (Roc::get(), Track::get()); + pub const RocForRockmine: (MultiAssetFilter, MultiLocation) = (Roc::get(), Rockmine::get()); + pub const RocForContracts: (MultiAssetFilter, MultiLocation) = (Roc::get(), Contracts::get()); + pub const RocForEncointer: (MultiAssetFilter, MultiLocation) = (Roc::get(), Encointer::get()); + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} +pub type TrustedTeleporters = ( + xcm_builder::Case, + xcm_builder::Case, + xcm_builder::Case, + xcm_builder::Case, + xcm_builder::Case, + xcm_builder::Case, +); + +match_types! { + pub type OnlyParachains: impl Contains = { + MultiLocation { parents: 0, interior: X1(Parachain(_)) } + }; +} + +/// The barriers one of which must be passed for an XCM message to be executed. +pub type Barrier = TrailingSetTopicAsId<( + // Weight that is paid for may be consumed. + TakeWeightCredit, + // Expected responses are OK. + AllowKnownQueryResponses, + WithComputedOrigin< + ( + // If the message is one that immediately attemps to pay for execution, then allow it. + AllowTopLevelPaidExecutionFrom, + // Messages coming from system parachains need not pay for execution. + AllowExplicitUnpaidExecutionFrom>, + // Subscriptions for version tracking are OK. + AllowSubscriptionsFrom, + ), + UniversalLocation, + ConstU32<8>, + >, +)>; + +/// A call filter for the XCM Transact instruction. This is a temporary measure until we +/// properly account for proof size weights. +/// +/// Calls that are allowed through this filter must: +/// 1. Have a fixed weight; +/// 2. Cannot lead to another call being made; +/// 3. Have a defined proof size weight, e.g. no unbounded vecs in call parameters. +pub struct SafeCallFilter; +impl Contains for SafeCallFilter { + fn contains(call: &RuntimeCall) -> bool { + #[cfg(feature = "runtime-benchmarks")] + { + if matches!(call, RuntimeCall::System(frame_system::Call::remark_with_event { .. })) { + return true + } + } + + match call { + RuntimeCall::System( + frame_system::Call::kill_prefix { .. } | frame_system::Call::set_heap_pages { .. }, + ) | + RuntimeCall::Babe(..) | + RuntimeCall::Timestamp(..) | + RuntimeCall::Indices(..) | + RuntimeCall::Balances(..) | + RuntimeCall::Crowdloan( + crowdloan::Call::create { .. } | + crowdloan::Call::contribute { .. } | + crowdloan::Call::withdraw { .. } | + crowdloan::Call::refund { .. } | + crowdloan::Call::dissolve { .. } | + crowdloan::Call::edit { .. } | + crowdloan::Call::poke { .. } | + crowdloan::Call::contribute_all { .. }, + ) | + RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) | + RuntimeCall::Grandpa(..) | + RuntimeCall::ImOnline(..) | + RuntimeCall::Democracy( + pallet_democracy::Call::second { .. } | + pallet_democracy::Call::vote { .. } | + pallet_democracy::Call::emergency_cancel { .. } | + pallet_democracy::Call::fast_track { .. } | + pallet_democracy::Call::veto_external { .. } | + pallet_democracy::Call::cancel_referendum { .. } | + pallet_democracy::Call::delegate { .. } | + pallet_democracy::Call::undelegate { .. } | + pallet_democracy::Call::clear_public_proposals { .. } | + pallet_democracy::Call::unlock { .. } | + pallet_democracy::Call::remove_vote { .. } | + pallet_democracy::Call::remove_other_vote { .. } | + pallet_democracy::Call::blacklist { .. } | + pallet_democracy::Call::cancel_proposal { .. }, + ) | + RuntimeCall::Council( + pallet_collective::Call::vote { .. } | + pallet_collective::Call::disapprove_proposal { .. } | + pallet_collective::Call::close { .. }, + ) | + RuntimeCall::TechnicalCommittee( + pallet_collective::Call::vote { .. } | + pallet_collective::Call::disapprove_proposal { .. } | + pallet_collective::Call::close { .. }, + ) | + RuntimeCall::PhragmenElection( + pallet_elections_phragmen::Call::remove_voter { .. } | + pallet_elections_phragmen::Call::submit_candidacy { .. } | + pallet_elections_phragmen::Call::renounce_candidacy { .. } | + pallet_elections_phragmen::Call::remove_member { .. } | + pallet_elections_phragmen::Call::clean_defunct_voters { .. }, + ) | + RuntimeCall::TechnicalMembership( + pallet_membership::Call::add_member { .. } | + pallet_membership::Call::remove_member { .. } | + pallet_membership::Call::swap_member { .. } | + pallet_membership::Call::change_key { .. } | + pallet_membership::Call::set_prime { .. } | + pallet_membership::Call::clear_prime { .. }, + ) | + RuntimeCall::Treasury(..) | + RuntimeCall::Claims( + super::claims::Call::claim { .. } | + super::claims::Call::mint_claim { .. } | + super::claims::Call::move_claim { .. }, + ) | + RuntimeCall::Utility(pallet_utility::Call::as_derivative { .. }) | + RuntimeCall::Identity( + pallet_identity::Call::add_registrar { .. } | + pallet_identity::Call::set_identity { .. } | + pallet_identity::Call::clear_identity { .. } | + pallet_identity::Call::request_judgement { .. } | + pallet_identity::Call::cancel_request { .. } | + pallet_identity::Call::set_fee { .. } | + pallet_identity::Call::set_account_id { .. } | + pallet_identity::Call::set_fields { .. } | + pallet_identity::Call::provide_judgement { .. } | + pallet_identity::Call::kill_identity { .. } | + pallet_identity::Call::add_sub { .. } | + pallet_identity::Call::rename_sub { .. } | + pallet_identity::Call::remove_sub { .. } | + pallet_identity::Call::quit_sub { .. }, + ) | + RuntimeCall::Society(..) | + RuntimeCall::Recovery(..) | + RuntimeCall::Vesting(..) | + RuntimeCall::Bounties( + pallet_bounties::Call::propose_bounty { .. } | + pallet_bounties::Call::approve_bounty { .. } | + pallet_bounties::Call::propose_curator { .. } | + pallet_bounties::Call::unassign_curator { .. } | + pallet_bounties::Call::accept_curator { .. } | + pallet_bounties::Call::award_bounty { .. } | + pallet_bounties::Call::claim_bounty { .. } | + pallet_bounties::Call::close_bounty { .. }, + ) | + RuntimeCall::ChildBounties(..) | + RuntimeCall::Hrmp(..) | + RuntimeCall::Registrar( + paras_registrar::Call::deregister { .. } | + paras_registrar::Call::swap { .. } | + paras_registrar::Call::remove_lock { .. } | + paras_registrar::Call::reserve { .. } | + paras_registrar::Call::add_lock { .. }, + ) | + RuntimeCall::XcmPallet(pallet_xcm::Call::limited_reserve_transfer_assets { + .. + }) => true, + _ => false, + } + } +} + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = LocalOriginConverter; + type IsReserve = (); + type IsTeleporter = TrustedTeleporters; + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = WeightInfoBounds< + crate::weights::xcm::RococoXcmWeight, + RuntimeCall, + MaxInstructions, + >; + type Trader = + UsingComponents>; + type ResponseHandler = XcmPallet; + type AssetTrap = XcmPallet; + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = XcmPallet; + type SubscriptionService = XcmPallet; + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = WithOriginFilter; + type SafeCallFilter = SafeCallFilter; + type Aliasers = Nothing; +} + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parachain(1000).into()); +} + +/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior +/// location of this chain. +pub type LocalOriginToLocation = ( + // A usual Signed origin to be used in XCM as a corresponding AccountId32 + SignedToAccountId32, +); +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = XcmRouter; + // Anyone can execute XCM messages locally. + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + // Anyone is able to use reserve transfers regardless of who they are and what they want to + // transfer. + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = IsConcrete; + type TrustedLockers = (); + type SovereignAccountOf = LocationConverter; + type MaxLockers = ConstU32<8>; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = crate::weights::pallet_xcm::WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} diff --git a/polkadot/runtime/test-runtime/Cargo.toml b/polkadot/runtime/test-runtime/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..9dcd8fe83a27a6fa91ab35270f352bb58cf28be3 --- /dev/null +++ b/polkadot/runtime/test-runtime/Cargo.toml @@ -0,0 +1,139 @@ +[package] +name = "polkadot-test-runtime" +build = "build.rs" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +log = { version = "0.4.17", default-features = false } +rustc-hex = { version = "2.1.0", default-features = false } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.163", default-features = false } +serde_derive = { version = "1.0.117", optional = true } +smallvec = "1.8.0" + +authority-discovery-primitives = { package = "sp-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +beefy-primitives = { package = "sp-consensus-beefy", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +offchain-primitives = { package = "sp-offchain", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +tx-pool-api = { package = "sp-transaction-pool", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +block-builder-api = { package = "sp-block-builder", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +pallet-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-executive = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-indices = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-offences = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking-reward-curve = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-system = {git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +test-runtime-constants = { package = "test-runtime-constants", path = "./constants", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +runtime-common = { package = "polkadot-runtime-common", path = "../common", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } +pallet-xcm = { path = "../../xcm/pallet-xcm", default-features = false } +polkadot-parachain = { path = "../../parachain", default-features = false } +polkadot-runtime-parachains = { path = "../parachains", default-features = false } +xcm-builder = { path = "../../xcm/xcm-builder", default-features = false } +xcm-executor = { path = "../../xcm/xcm-executor", default-features = false } +xcm = { path = "../../xcm", default-features = false } + +[dev-dependencies] +hex-literal = "0.4.1" +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "master" } +sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } +serde_json = "1.0.96" + +[build-dependencies] +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = ["std"] +no_std = [] +only-staking = [] +runtime-metrics = ["polkadot-runtime-parachains/runtime-metrics", "sp-io/with-tracing"] + +std = [ + "authority-discovery-primitives/std", + "pallet-authority-discovery/std", + "bitvec/std", + "primitives/std", + "rustc-hex/std", + "parity-scale-codec/std", + "scale-info/std", + "inherents/std", + "sp-core/std", + "polkadot-parachain/std", + "pallet-xcm/std", + "xcm-builder/std", + "xcm-executor/std", + "xcm/std", + "sp-api/std", + "tx-pool-api/std", + "block-builder-api/std", + "offchain-primitives/std", + "sp-std/std", + "sp-io/std", + "frame-support/std", + "pallet-authorship/std", + "pallet-balances/std", + "pallet-transaction-payment/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "frame-executive/std", + "pallet-grandpa/std", + "pallet-indices/std", + "pallet-offences/std", + "sp-runtime/std", + "sp-staking/std", + "pallet-session/std", + "pallet-staking/std", + "frame-system/std", + "frame-system-rpc-runtime-api/std", + "test-runtime-constants/std", + "pallet-timestamp/std", + "sp-version/std", + "pallet-vesting/std", + "serde_derive", + "serde/std", + "pallet-babe/std", + "babe-primitives/std", + "beefy-primitives/std", + "sp-session/std", + "runtime-common/std", + "log/std", + "frame-election-provider-support/std", + "pallet-sudo/std", +] + +runtime-benchmarks = [ + "pallet-xcm/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", +] diff --git a/polkadot/runtime/test-runtime/build.rs b/polkadot/runtime/test-runtime/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..404ba3f2fdbdfdc68d35d0dd08958448f30d90c6 --- /dev/null +++ b/polkadot/runtime/test-runtime/build.rs @@ -0,0 +1,25 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .import_memory() + .export_heap_base() + .build() +} diff --git a/polkadot/runtime/test-runtime/constants/Cargo.toml b/polkadot/runtime/test-runtime/constants/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..84d8ae8ce56052bccf08b486232d2a4b12ddcffa --- /dev/null +++ b/polkadot/runtime/test-runtime/constants/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "test-runtime-constants" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +smallvec = "1.8.0" + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../../primitives", default-features = false } +runtime-common = { package = "polkadot-runtime-common", path = "../../common", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-weights = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } + +[features] +default = ["std"] +std = [ + "sp-core/std", + "sp-runtime/std", + "sp-weights/std", + "runtime-common/std", + "primitives/std", + "frame-support/std", +] diff --git a/polkadot/runtime/test-runtime/constants/src/lib.rs b/polkadot/runtime/test-runtime/constants/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..77c83b063cf0f8fb7771545faa074b315fa75a03 --- /dev/null +++ b/polkadot/runtime/test-runtime/constants/src/lib.rs @@ -0,0 +1,89 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod weights; + +/// Money matters. +pub mod currency { + use primitives::Balance; + + pub const DOTS: Balance = 1_000_000_000_000; + pub const DOLLARS: Balance = DOTS; + pub const CENTS: Balance = DOLLARS / 100; + pub const MILLICENTS: Balance = CENTS / 1_000; +} + +/// Time and blocks. +pub mod time { + use primitives::{BlockNumber, Moment}; + // Testnet + pub const MILLISECS_PER_BLOCK: Moment = 6000; + pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; + // 30 seconds for now + pub const EPOCH_DURATION_IN_SLOTS: BlockNumber = MINUTES / 2; + + // These time units are defined in number of blocks. + pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); + pub const HOURS: BlockNumber = MINUTES * 60; + pub const DAYS: BlockNumber = HOURS * 24; + + // 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. + // The choice of is done in accordance to the slot duration and expected target + // block time, for safely resisting network delays of maximum two seconds. + // + pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); +} + +/// Fee-related. +pub mod fee { + use crate::weights::ExtrinsicBaseWeight; + use frame_support::weights::{ + WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, + }; + use primitives::Balance; + use smallvec::smallvec; + pub use sp_runtime::Perbill; + + /// The block saturation level. Fees will be updates based on this value. + pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); + + /// 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, `frame_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. + pub struct WeightToFee; + impl WeightToFeePolynomial for WeightToFee { + type Balance = Balance; + fn polynomial() -> WeightToFeeCoefficients { + let p = super::currency::CENTS; + let q = 10 * Balance::from(ExtrinsicBaseWeight::get().ref_time()); + smallvec![WeightToFeeCoefficient { + degree: 1, + negative: false, + coeff_frac: Perbill::from_rational(p % q, q), + coeff_integer: p / q, + }] + } + } +} diff --git a/polkadot/runtime/test-runtime/constants/src/weights/block_weights.rs b/polkadot/runtime/test-runtime/constants/src/weights/block_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..e7fdb2aae2a01ec06076de83d94817e540e205dd --- /dev/null +++ b/polkadot/runtime/test-runtime/constants/src/weights/block_weights.rs @@ -0,0 +1,53 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, Weight}, + }; + + parameter_types! { + /// Importing a block with 0 Extrinsics. + pub const BlockExecutionWeight: Weight = + Weight::from_parts(constants::WEIGHT_REF_TIME_PER_NANOS.saturating_mul(5_000_000), 0); + } + + #[cfg(test)] + mod test_weights { + use frame_support::weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::constants::BlockExecutionWeight::get(); + + // At least 100 µs. + assert!( + w.ref_time() >= 100u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 100 µs." + ); + // At most 50 ms. + assert!( + w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 50 ms." + ); + } + } +} diff --git a/polkadot/runtime/test-runtime/constants/src/weights/extrinsic_weights.rs b/polkadot/runtime/test-runtime/constants/src/weights/extrinsic_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..1a4adb968bb7195428ea00d59cd92dcd3b6eea5f --- /dev/null +++ b/polkadot/runtime/test-runtime/constants/src/weights/extrinsic_weights.rs @@ -0,0 +1,53 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, Weight}, + }; + + parameter_types! { + /// Executing a NO-OP `System::remarks` Extrinsic. + pub const ExtrinsicBaseWeight: Weight = + Weight::from_parts(constants::WEIGHT_REF_TIME_PER_NANOS.saturating_mul(125_000), 0); + } + + #[cfg(test)] + mod test_weights { + use frame_support::weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::constants::ExtrinsicBaseWeight::get(); + + // At least 10 µs. + assert!( + w.ref_time() >= 10u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 10 µs." + ); + // At most 1 ms. + assert!( + w.ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 1 ms." + ); + } + } +} diff --git a/polkadot/runtime/test-runtime/constants/src/weights/mod.rs b/polkadot/runtime/test-runtime/constants/src/weights/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..30fa2c4060689ff98cc427c84f81866172845e52 --- /dev/null +++ b/polkadot/runtime/test-runtime/constants/src/weights/mod.rs @@ -0,0 +1,28 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Expose the auto generated weight files. + +pub mod block_weights; +pub mod extrinsic_weights; +pub mod paritydb_weights; +pub mod rocksdb_weights; + +pub use block_weights::constants::BlockExecutionWeight; +pub use extrinsic_weights::constants::ExtrinsicBaseWeight; +pub use paritydb_weights::constants::ParityDbWeight; +pub use rocksdb_weights::constants::RocksDbWeight; diff --git a/polkadot/runtime/test-runtime/constants/src/weights/paritydb_weights.rs b/polkadot/runtime/test-runtime/constants/src/weights/paritydb_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..25679703831a13b8d1bb7fb7dd4d92fa84b1f255 --- /dev/null +++ b/polkadot/runtime/test-runtime/constants/src/weights/paritydb_weights.rs @@ -0,0 +1,63 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// `ParityDB` can be enabled with a feature flag, but is still experimental. These weights + /// are available for brave runtime engineers who may want to try this out as default. + pub const ParityDbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 8_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + write: 50_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use super::constants::ParityDbWeight as W; + use frame_support::weights::constants; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/polkadot/runtime/test-runtime/constants/src/weights/rocksdb_weights.rs b/polkadot/runtime/test-runtime/constants/src/weights/rocksdb_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..3dd817aa6f137085b0e5fdf2b11b7f50e5c8b002 --- /dev/null +++ b/polkadot/runtime/test-runtime/constants/src/weights/rocksdb_weights.rs @@ -0,0 +1,63 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// By default, Substrate uses `RocksDB`, so this will be the weight used throughout + /// the runtime. + pub const RocksDbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 25_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + write: 100_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use super::constants::RocksDbWeight as W; + use frame_support::weights::constants; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..b2397299430de240ddc43b0812f69ecabcdf19aa --- /dev/null +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -0,0 +1,1139 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Polkadot runtime. This can be compiled with `#[no_std]`, ready for Wasm. + +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. +#![recursion_limit = "256"] + +use pallet_transaction_payment::CurrencyAdapter; +use parity_scale_codec::Encode; +use sp_std::{collections::btree_map::BTreeMap, prelude::*}; + +use polkadot_runtime_parachains::{ + assigner_parachains as parachains_assigner_parachains, + configuration as parachains_configuration, disputes as parachains_disputes, + disputes::slashing as parachains_slashing, dmp as parachains_dmp, hrmp as parachains_hrmp, + inclusion as parachains_inclusion, initializer as parachains_initializer, + origin as parachains_origin, paras as parachains_paras, + paras_inherent as parachains_paras_inherent, runtime_api_impl::v5 as runtime_impl, + scheduler as parachains_scheduler, session_info as parachains_session_info, + shared as parachains_shared, +}; + +use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; +use beefy_primitives::ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}; +use frame_election_provider_support::{ + bounds::{ElectionBounds, ElectionBoundsBuilder}, + onchain, SequentialPhragmen, +}; +use frame_support::{ + construct_runtime, parameter_types, + traits::{Everything, KeyOwnerProofSystem, WithdrawReasons}, +}; +use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; +use pallet_session::historical as session_historical; +use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; +use polkadot_runtime_parachains::reward_points::RewardValidatorsWithEraPoints; +use primitives::{ + slashing, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, + CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, + Hash as HashT, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce, + OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, + SessionInfo as SessionInfoData, Signature, ValidationCode, ValidationCodeHash, ValidatorId, + ValidatorIndex, PARACHAIN_KEY_TYPE_ID, +}; +use runtime_common::{ + claims, impl_runtime_weights, paras_sudo_wrapper, BlockHashCount, BlockLength, + SlowAdjustingFeeUpdate, +}; +use sp_core::{ConstU32, OpaqueMetadata}; +use sp_mmr_primitives as mmr; +use sp_runtime::{ + create_runtime_str, + curve::PiecewiseLinear, + generic, impl_opaque_keys, + traits::{ + BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT, OpaqueKeys, + SaturatedConversion, StaticLookup, Verify, + }, + transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, KeyTypeId, Perbill, +}; +use sp_staking::SessionIndex; +#[cfg(any(feature = "std", test))] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; + +pub use pallet_balances::Call as BalancesCall; +#[cfg(feature = "std")] +pub use pallet_staking::StakerStatus; +pub use pallet_sudo::Call as SudoCall; +pub use pallet_timestamp::Call as TimestampCall; +pub use parachains_paras::Call as ParasCall; +pub use paras_sudo_wrapper::Call as ParasSudoWrapperCall; +#[cfg(any(feature = "std", test))] +pub use sp_runtime::BuildStorage; + +/// Constant values used within the runtime. +use test_runtime_constants::{currency::*, fee::*, time::*}; +pub mod xcm_config; + +impl_runtime_weights!(test_runtime_constants); + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +/// Runtime version (Test). +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("polkadot-test-runtime"), + impl_name: create_runtime_str!("parity-polkadot-test-runtime"), + authoring_version: 2, + spec_version: 1056, + impl_version: 0, + apis: RUNTIME_API_VERSIONS, + transaction_version: 1, + state_version: 1, +}; + +/// The BABE epoch configuration at genesis. +pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration = + babe_primitives::BabeEpochConfiguration { + c: PRIMARY_PROBABILITY, + allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots, + }; + +/// Native version. +#[cfg(any(feature = "std", test))] +pub fn native_version() -> NativeVersion { + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } +} + +sp_api::decl_runtime_apis! { + pub trait GetLastTimestamp { + /// Returns the last timestamp of a runtime. + fn get_last_timestamp() -> u64; + } +} + +parameter_types! { + pub const Version: RuntimeVersion = VERSION; + pub const SS58Prefix: u8 = 42; +} + +impl frame_system::Config for Runtime { + type BaseCallFilter = Everything; + type BlockWeights = BlockWeights; + type BlockLength = BlockLength; + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = Nonce; + type Hash = HashT; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = Indices; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = Version; + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +impl frame_system::offchain::SendTransactionTypes for Runtime +where + RuntimeCall: From, +{ + type OverarchingCall = RuntimeCall; + type Extrinsic = UncheckedExtrinsic; +} + +parameter_types! { + pub storage EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64; + pub storage ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; + pub ReportLongevity: u64 = + BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get(); +} + +impl pallet_babe::Config for Runtime { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; + + // session module is the trigger + type EpochChangeTrigger = pallet_babe::ExternalTrigger; + + type DisabledValidators = (); + + type WeightInfo = (); + + type MaxAuthorities = MaxAuthorities; + type MaxNominators = MaxNominatorRewardedPerValidator; + + type KeyOwnerProof = + >::Proof; + + type EquivocationReportSystem = (); +} + +parameter_types! { + pub storage IndexDeposit: Balance = 1 * DOLLARS; +} + +impl pallet_indices::Config for Runtime { + type AccountIndex = AccountIndex; + type Currency = Balances; + type Deposit = IndexDeposit; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); +} + +parameter_types! { + pub const ExistentialDeposit: Balance = 1 * CENTS; + pub storage MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +parameter_types! { + pub storage TransactionByteFee: Balance = 10 * MILLICENTS; + /// This value increases the priority of `Operational` transactions by adding + /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`. + pub const OperationalFeeMultiplier: u8 = 5; +} + +impl pallet_transaction_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter; + type OperationalFeeMultiplier = OperationalFeeMultiplier; + type WeightToFee = WeightToFee; + type LengthToFee = frame_support::weights::ConstantMultiplier; + type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; +} + +parameter_types! { + pub storage SlotDuration: u64 = SLOT_DURATION; + pub storage MinimumPeriod: u64 = SlotDuration::get() / 2; +} +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = Babe; + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +impl pallet_authorship::Config for Runtime { + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; + type EventHandler = Staking; +} + +parameter_types! { + pub storage Period: BlockNumber = 10 * MINUTES; + pub storage Offset: BlockNumber = 0; +} + +impl_opaque_keys! { + pub struct SessionKeys { + pub grandpa: Grandpa, + pub babe: Babe, + pub para_validator: Initializer, + pub para_assignment: ParaSessionInfo, + pub authority_discovery: AuthorityDiscovery, + } +} + +impl pallet_session::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = AccountId; + type ValidatorIdOf = pallet_staking::StashOf; + type ShouldEndSession = Babe; + type NextSessionRotation = Babe; + type SessionManager = Staking; + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; + type WeightInfo = (); +} + +impl pallet_session::historical::Config for Runtime { + type FullIdentification = pallet_staking::Exposure; + type FullIdentificationOf = pallet_staking::ExposureOf; +} + +pallet_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! { + // Six sessions in an era (6 hours). + pub storage SessionsPerEra: SessionIndex = 6; + // 28 eras for unbonding (7 days). + pub storage BondingDuration: sp_staking::EraIndex = 28; + // 27 eras in which slashes can be cancelled (a bit less than 7 days). + pub storage SlashDeferDuration: sp_staking::EraIndex = 27; + pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; + pub storage MaxNominatorRewardedPerValidator: u32 = 64; + pub storage OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17); + pub const MaxAuthorities: u32 = 100_000; + pub const OnChainMaxWinners: u32 = u32::MAX; + // Unbounded number of election targets and voters. + pub ElectionBoundsOnChain: ElectionBounds = ElectionBoundsBuilder::default().build(); +} + +pub struct OnChainSeqPhragmen; +impl onchain::Config for OnChainSeqPhragmen { + type System = Runtime; + type Solver = SequentialPhragmen; + type DataProvider = Staking; + type WeightInfo = (); + type Bounds = ElectionBoundsOnChain; + type MaxWinners = OnChainMaxWinners; +} + +/// Upper limit on the number of NPOS nominations. +const MAX_QUOTA_NOMINATIONS: u32 = 16; + +impl pallet_staking::Config for Runtime { + type Currency = Balances; + type CurrencyBalance = Balance; + type UnixTime = Timestamp; + type CurrencyToVote = runtime_common::CurrencyToVote; + type RewardRemainder = (); + type RuntimeEvent = RuntimeEvent; + type Slash = (); + type Reward = (); + type SessionsPerEra = SessionsPerEra; + type BondingDuration = BondingDuration; + type SlashDeferDuration = SlashDeferDuration; + type AdminOrigin = frame_system::EnsureNever<()>; + type SessionInterface = Self; + type EraPayout = pallet_staking::ConvertCurve; + type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; + type OffendingValidatorsThreshold = OffendingValidatorsThreshold; + type NextNewSession = Session; + type ElectionProvider = onchain::OnChainExecution; + type GenesisElectionProvider = onchain::OnChainExecution; + // Use the nominator map to iter voter AND no-ops for all SortedListProvider hooks. The + // migration to bags-list is a no-op, but the storage version will be updated. + type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; + type TargetList = pallet_staking::UseValidatorsMap; + type NominationsQuota = pallet_staking::FixedNominationsQuota; + type MaxUnlockingChunks = frame_support::traits::ConstU32<32>; + type HistoryDepth = frame_support::traits::ConstU32<84>; + type BenchmarkingConfig = runtime_common::StakingBenchmarkingConfig; + type EventListeners = (); + type WeightInfo = (); +} + +parameter_types! { + pub MaxSetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); +} + +impl pallet_grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + + type WeightInfo = (); + type MaxAuthorities = MaxAuthorities; + type MaxNominators = MaxNominatorRewardedPerValidator; + type MaxSetIdSessionEntries = MaxSetIdSessionEntries; + + type KeyOwnerProof = sp_core::Void; + type EquivocationReportSystem = (); +} + +impl frame_system::offchain::CreateSignedTransaction for Runtime +where + RuntimeCall: From, +{ + fn create_transaction>( + call: RuntimeCall, + public: ::Signer, + account: AccountId, + nonce: ::Nonce, + ) -> Option<(RuntimeCall, ::SignaturePayload)> { + let period = + BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; + + let current_block = System::block_number().saturated_into::().saturating_sub(1); + let tip = 0; + let extra: SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(generic::Era::mortal( + period, + current_block, + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + ); + let raw_payload = SignedPayload::new(call, extra) + .map_err(|e| { + log::warn!("Unable to create signed payload: {:?}", e); + }) + .ok()?; + let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; + let (call, extra, _) = raw_payload.deconstruct(); + let address = Indices::unlookup(account); + Some((call, (address, signature, extra))) + } +} + +impl frame_system::offchain::SigningTypes for Runtime { + type Public = ::Signer; + type Signature = Signature; +} + +impl pallet_offences::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type IdentificationTuple = pallet_session::historical::IdentificationTuple; + type OnOffenceHandler = Staking; +} + +impl pallet_authority_discovery::Config for Runtime { + type MaxAuthorities = MaxAuthorities; +} + +parameter_types! { + pub storage LeasePeriod: BlockNumber = 100_000; + pub storage EndingPeriod: BlockNumber = 1000; +} + +parameter_types! { + pub Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:"; +} + +impl claims::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type VestingSchedule = Vesting; + type Prefix = Prefix; + type MoveClaimOrigin = frame_system::EnsureRoot; + type WeightInfo = claims::TestWeightInfo; +} + +parameter_types! { + pub storage MinVestedTransfer: Balance = 100 * DOLLARS; + pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = + WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); +} + +impl pallet_vesting::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BlockNumberToBalance = ConvertInto; + type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = (); + type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; + const MAX_VESTING_SCHEDULES: u32 = 28; +} + +impl pallet_sudo::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type WeightInfo = (); +} + +impl parachains_configuration::Config for Runtime { + type WeightInfo = parachains_configuration::TestWeightInfo; +} + +impl parachains_shared::Config for Runtime {} + +impl parachains_inclusion::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type DisputesHandler = ParasDisputes; + type RewardValidators = RewardValidatorsWithEraPoints; + type MessageQueue = (); + type WeightInfo = (); +} + +impl parachains_disputes::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RewardValidators = (); + type SlashingHandler = parachains_slashing::SlashValidatorsForDisputes; + type WeightInfo = parachains_disputes::TestWeightInfo; +} + +impl parachains_slashing::Config for Runtime { + type KeyOwnerProofSystem = Historical; + type KeyOwnerProof = + >::Proof; + type KeyOwnerIdentification = >::IdentificationTuple; + type HandleReports = parachains_slashing::SlashingReportHandler< + Self::KeyOwnerIdentification, + Offences, + ReportLongevity, + >; + type WeightInfo = parachains_disputes::slashing::TestWeightInfo; + type BenchmarkingConfig = parachains_slashing::BenchConfig<1000>; +} + +impl parachains_paras_inherent::Config for Runtime { + type WeightInfo = parachains_paras_inherent::TestWeightInfo; +} + +impl parachains_initializer::Config for Runtime { + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type ForceOrigin = frame_system::EnsureRoot; + type WeightInfo = (); +} + +impl parachains_session_info::Config for Runtime { + type ValidatorSet = Historical; +} + +parameter_types! { + pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +impl parachains_paras::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = parachains_paras::TestWeightInfo; + type UnsignedPriority = ParasUnsignedPriority; + type QueueFootprinter = ParaInclusion; + type NextSessionRotation = Babe; +} + +impl parachains_dmp::Config for Runtime {} + +parameter_types! { + pub const FirstMessageFactorPercent: u64 = 100; +} + +impl parachains_hrmp::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type ChannelManager = frame_system::EnsureRoot; + type Currency = Balances; + type WeightInfo = parachains_hrmp::TestWeightInfo; +} + +impl parachains_assigner_parachains::Config for Runtime {} + +impl parachains_scheduler::Config for Runtime { + type AssignmentProvider = ParaAssignmentProvider; +} + +impl paras_sudo_wrapper::Config for Runtime {} + +impl parachains_origin::Config for Runtime {} + +impl pallet_test_notifier::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; +} + +#[frame_support::pallet(dev_mode)] +pub mod pallet_test_notifier { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use pallet_xcm::ensure_response; + use sp_runtime::DispatchResult; + use xcm::latest::prelude::*; + use xcm_executor::traits::QueryHandler as XcmQueryHandler; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + pallet_xcm::Config { + type RuntimeEvent: IsType<::RuntimeEvent> + From>; + type RuntimeOrigin: IsType<::RuntimeOrigin> + + Into::RuntimeOrigin>>; + type RuntimeCall: IsType<::RuntimeCall> + From>; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + QueryPrepared(QueryId), + NotifyQueryPrepared(QueryId), + ResponseReceived(MultiLocation, QueryId, Response), + } + + #[pallet::error] + pub enum Error { + UnexpectedId, + BadAccountFormat, + } + + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight(1_000_000)] + pub fn prepare_new_query(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + let id = who + .using_encoded(|mut d| <[u8; 32]>::decode(&mut d)) + .map_err(|_| Error::::BadAccountFormat)?; + let qid = as XcmQueryHandler>::new_query( + Junction::AccountId32 { network: None, id }, + 100u32.into(), + Here, + ); + Self::deposit_event(Event::::QueryPrepared(qid)); + Ok(()) + } + + #[pallet::call_index(1)] + #[pallet::weight(1_000_000)] + pub fn prepare_new_notify_query(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + let id = who + .using_encoded(|mut d| <[u8; 32]>::decode(&mut d)) + .map_err(|_| Error::::BadAccountFormat)?; + let call = + Call::::notification_received { query_id: 0, response: Default::default() }; + let qid = pallet_xcm::Pallet::::new_notify_query( + Junction::AccountId32 { network: None, id }, + ::RuntimeCall::from(call), + 100u32.into(), + Here, + ); + Self::deposit_event(Event::::NotifyQueryPrepared(qid)); + Ok(()) + } + + #[pallet::call_index(2)] + #[pallet::weight(1_000_000)] + pub fn notification_received( + origin: OriginFor, + query_id: QueryId, + response: Response, + ) -> DispatchResult { + let responder = ensure_response(::RuntimeOrigin::from(origin))?; + Self::deposit_event(Event::::ResponseReceived(responder, query_id, response)); + Ok(()) + } + } +} + +construct_runtime! { + pub enum Runtime + { + // Basic stuff; balances is uncallable initially. + System: frame_system::{Pallet, Call, Storage, Config, Event}, + + // Must be before session. + Babe: pallet_babe::{Pallet, Call, Storage, Config}, + + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + Indices: pallet_indices::{Pallet, Call, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + + // Consensus support. + Authorship: pallet_authorship::{Pallet, Storage}, + Staking: pallet_staking::{Pallet, Call, Storage, Config, Event}, + Offences: pallet_offences::{Pallet, Storage, Event}, + Historical: session_historical::{Pallet}, + Session: pallet_session::{Pallet, Call, Storage, Event, Config}, + Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event}, + AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config}, + + // Claims. Usable initially. + Claims: claims::{Pallet, Call, Storage, Event, Config, ValidateUnsigned}, + + // Vesting. Usable initially, but removed once all vesting is finished. + Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config}, + + // Parachains runtime modules + Configuration: parachains_configuration::{Pallet, Call, Storage, Config}, + ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event}, + ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent}, + Initializer: parachains_initializer::{Pallet, Call, Storage}, + Paras: parachains_paras::{Pallet, Call, Storage, Event, ValidateUnsigned}, + ParasShared: parachains_shared::{Pallet, Call, Storage}, + Scheduler: parachains_scheduler::{Pallet, Storage}, + ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call}, + ParasOrigin: parachains_origin::{Pallet, Origin}, + ParaSessionInfo: parachains_session_info::{Pallet, Storage}, + Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event}, + Dmp: parachains_dmp::{Pallet, Storage}, + Xcm: pallet_xcm::{Pallet, Call, Event, Origin}, + ParasDisputes: parachains_disputes::{Pallet, Storage, Event}, + ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned}, + ParaAssignmentProvider: parachains_assigner_parachains::{Pallet}, + + Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event}, + + TestNotifier: pallet_test_notifier::{Pallet, Call, Event}, + } +} + +/// The address format for describing accounts. +pub type Address = sp_runtime::MultiAddress; +/// Block header type as expected by this runtime. +pub type Header = generic::Header; +/// Block type as expected by this runtime. +pub type Block = generic::Block; +/// A Block signed with a Justification +pub type SignedBlock = generic::SignedBlock; +/// `BlockId` type as expected by this runtime. +pub type BlockId = generic::BlockId; +/// The `SignedExtension` to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckMortality, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + generic::UncheckedExtrinsic; + +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, +>; +/// The payload being signed in transactions. +pub type SignedPayload = generic::SignedPayload; + +pub type Hash = ::Hash; +pub type Extrinsic = ::Extrinsic; + +sp_api::impl_runtime_apis! { + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block); + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } + } + + impl block_builder_api::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: inherents::InherentData, + ) -> inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl tx_pool_api::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl offchain_primitives::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + runtime_impl::relevant_authority_ids::() + } + } + + impl primitives::runtime_api::ParachainHost for Runtime { + fn validators() -> Vec { + runtime_impl::validators::() + } + + fn validator_groups() -> (Vec>, GroupRotationInfo) { + runtime_impl::validator_groups::() + } + + fn availability_cores() -> Vec> { + runtime_impl::availability_cores::() + } + + fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option> + { + runtime_impl::persisted_validation_data::(para_id, assumption) + } + + fn assumed_validation_data( + para_id: ParaId, + expected_persisted_validation_data_hash: Hash, + ) -> Option<(PersistedValidationData, ValidationCodeHash)> { + runtime_impl::assumed_validation_data::( + para_id, + expected_persisted_validation_data_hash, + ) + } + + fn check_validation_outputs( + para_id: ParaId, + outputs: primitives::CandidateCommitments, + ) -> bool { + runtime_impl::check_validation_outputs::(para_id, outputs) + } + + fn session_index_for_child() -> SessionIndex { + runtime_impl::session_index_for_child::() + } + + fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option + { + runtime_impl::validation_code::(para_id, assumption) + } + + fn candidate_pending_availability(para_id: ParaId) -> Option> { + runtime_impl::candidate_pending_availability::(para_id) + } + + fn candidate_events() -> Vec> { + runtime_impl::candidate_events::(|trait_event| trait_event.try_into().ok()) + } + + fn session_info(index: SessionIndex) -> Option { + runtime_impl::session_info::(index) + } + + fn session_executor_params(session_index: SessionIndex) -> Option { + runtime_impl::session_executor_params::(session_index) + } + + fn dmq_contents( + recipient: ParaId, + ) -> Vec> { + runtime_impl::dmq_contents::(recipient) + } + + fn inbound_hrmp_channels_contents( + recipient: ParaId, + ) -> BTreeMap>> { + runtime_impl::inbound_hrmp_channels_contents::(recipient) + } + + fn validation_code_by_hash(hash: ValidationCodeHash) -> Option { + runtime_impl::validation_code_by_hash::(hash) + } + + fn on_chain_votes() -> Option> { + runtime_impl::on_chain_votes::() + } + + fn submit_pvf_check_statement( + stmt: primitives::PvfCheckStatement, + signature: primitives::ValidatorSignature, + ) { + runtime_impl::submit_pvf_check_statement::(stmt, signature) + } + + fn pvfs_require_precheck() -> Vec { + runtime_impl::pvfs_require_precheck::() + } + + fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option + { + runtime_impl::validation_code_hash::(para_id, assumption) + } + + fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState)> { + runtime_impl::get_session_disputes::() + } + + fn unapplied_slashes( + ) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> { + runtime_impl::unapplied_slashes::() + } + + fn key_ownership_proof( + validator_id: ValidatorId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((PARACHAIN_KEY_TYPE_ID, validator_id)) + .map(|p| p.encode()) + .map(slashing::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_dispute_lost( + dispute_proof: slashing::DisputeProof, + key_ownership_proof: slashing::OpaqueKeyOwnershipProof, + ) -> Option<()> { + runtime_impl::submit_unsigned_slashing_report::( + dispute_proof, + key_ownership_proof, + ) + } + } + + impl beefy_primitives::BeefyApi for Runtime { + fn beefy_genesis() -> Option { + // dummy implementation due to lack of BEEFY pallet. + None + } + + fn validator_set() -> Option> { + // dummy implementation due to lack of BEEFY pallet. + None + } + + fn submit_report_equivocation_unsigned_extrinsic( + _equivocation_proof: beefy_primitives::EquivocationProof< + BlockNumber, + BeefyId, + BeefySignature, + >, + _key_owner_proof: beefy_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + + fn generate_key_ownership_proof( + _set_id: beefy_primitives::ValidatorSetId, + _authority_id: BeefyId, + ) -> Option { + None + } + } + + impl mmr::MmrApi for Runtime { + fn mmr_root() -> Result { + Err(mmr::Error::PalletNotIncluded) + } + + fn mmr_leaf_count() -> Result { + Err(mmr::Error::PalletNotIncluded) + } + + fn generate_proof( + _block_numbers: Vec, + _best_known_block_number: Option, + ) -> Result<(Vec, mmr::Proof), mmr::Error> { + Err(mmr::Error::PalletNotIncluded) + } + + fn verify_proof(_leaves: Vec, _proof: mmr::Proof) + -> Result<(), mmr::Error> + { + Err(mmr::Error::PalletNotIncluded) + } + + fn verify_proof_stateless( + _root: Hash, + _leaves: Vec, + _proof: mmr::Proof + ) -> Result<(), mmr::Error> { + Err(mmr::Error::PalletNotIncluded) + } + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> Vec<(GrandpaId, u64)> { + Grandpa::grandpa_authorities() + } + + fn current_set_id() -> fg_primitives::SetId { + Grandpa::current_set_id() + } + + fn submit_report_equivocation_unsigned_extrinsic( + _equivocation_proof: fg_primitives::EquivocationProof< + ::Hash, + sp_runtime::traits::NumberFor, + >, + _key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + + fn generate_key_ownership_proof( + _set_id: fg_primitives::SetId, + _authority_id: fg_primitives::AuthorityId, + ) -> Option { + None + } + } + + impl babe_primitives::BabeApi for Runtime { + fn configuration() -> babe_primitives::BabeConfiguration { + let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG); + babe_primitives::BabeConfiguration { + slot_duration: Babe::slot_duration(), + epoch_length: EpochDuration::get(), + c: epoch_config.c, + authorities: Babe::authorities().to_vec(), + randomness: Babe::randomness(), + allowed_slots: epoch_config.allowed_slots, + } + } + + fn current_epoch_start() -> babe_primitives::Slot { + Babe::current_epoch_start() + } + + fn current_epoch() -> babe_primitives::Epoch { + Babe::current_epoch() + } + + fn next_epoch() -> babe_primitives::Epoch { + Babe::next_epoch() + } + + fn generate_key_ownership_proof( + _slot: babe_primitives::Slot, + _authority_id: babe_primitives::AuthorityId, + ) -> Option { + None + } + + fn submit_report_equivocation_unsigned_extrinsic( + _equivocation_proof: babe_primitives::EquivocationProof<::Header>, + _key_owner_proof: babe_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Nonce { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< + Block, + Balance, + > for Runtime { + fn query_info(uxt: ::Extrinsic, len: u32) -> RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details(uxt: ::Extrinsic, len: u32) -> FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi + for Runtime + { + fn query_call_info(call: RuntimeCall, len: u32) -> RuntimeDispatchInfo { + TransactionPayment::query_call_info(call, len) + } + fn query_call_fee_details(call: RuntimeCall, len: u32) -> FeeDetails { + TransactionPayment::query_call_fee_details(call, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl crate::GetLastTimestamp for Runtime { + fn get_last_timestamp() -> u64 { + Timestamp::now() + } + } +} diff --git a/polkadot/runtime/test-runtime/src/xcm_config.rs b/polkadot/runtime/test-runtime/src/xcm_config.rs new file mode 100644 index 0000000000000000000000000000000000000000..2113bbae66adaebfc6014d93999c758be759f7db --- /dev/null +++ b/polkadot/runtime/test-runtime/src/xcm_config.rs @@ -0,0 +1,159 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use frame_support::{ + parameter_types, + traits::{Everything, Nothing}, + weights::Weight, +}; +use frame_system::EnsureRoot; +use xcm::latest::prelude::*; +use xcm_builder::{ + AllowUnpaidExecutionFrom, EnsureXcmOrigin, FixedWeightBounds, SignedAccountId32AsNative, + SignedToAccountId32, +}; +use xcm_executor::{ + traits::{TransactAsset, WeightTrader}, + Assets, +}; + +parameter_types! { + pub const BaseXcmWeight: xcm::latest::Weight = Weight::from_parts(1_000, 1_000); + pub const AnyNetwork: Option = None; + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 16; + pub const UniversalLocation: xcm::latest::InteriorMultiLocation = xcm::latest::Junctions::Here; +} + +/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior +/// location of this chain. +pub type LocalOriginToLocation = ( + // And a usual Signed origin to be used in XCM as a corresponding AccountId32 + SignedToAccountId32, +); + +pub struct DoNothingRouter; +impl SendXcm for DoNothingRouter { + type Ticket = (); + fn validate(_dest: &mut Option, _msg: &mut Option>) -> SendResult<()> { + Ok(((), MultiAssets::new())) + } + fn deliver(_: ()) -> Result { + Ok([0; 32]) + } +} + +pub type Barrier = AllowUnpaidExecutionFrom; + +pub struct DummyAssetTransactor; +impl TransactAsset for DummyAssetTransactor { + fn deposit_asset(_what: &MultiAsset, _who: &MultiLocation, _context: &XcmContext) -> XcmResult { + Ok(()) + } + + fn withdraw_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _maybe_context: Option<&XcmContext>, + ) -> Result { + let asset: MultiAsset = (Parent, 100_000).into(); + Ok(asset.into()) + } +} + +pub struct DummyWeightTrader; +impl WeightTrader for DummyWeightTrader { + fn new() -> Self { + DummyWeightTrader + } + + fn buy_weight( + &mut self, + _weight: Weight, + _payment: Assets, + _context: &XcmContext, + ) -> Result { + Ok(Assets::default()) + } +} + +type OriginConverter = ( + pallet_xcm::XcmPassthrough, + SignedAccountId32AsNative, +); + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = super::RuntimeCall; + type XcmSender = DoNothingRouter; + type AssetTransactor = DummyAssetTransactor; + type OriginConverter = OriginConverter; + type IsReserve = (); + type IsTeleporter = (); + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = DummyWeightTrader; + type ResponseHandler = super::Xcm; + type AssetTrap = super::Xcm; + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = super::Xcm; + type SubscriptionService = super::Xcm; + type PalletInstancesInfo = (); + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = super::RuntimeCall; + type SafeCallFilter = Everything; + type Aliasers = Nothing; +} + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(xcm::latest::Junctions::Here.into()); +} + +impl pallet_xcm::Config for crate::Runtime { + // The config types here are entirely configurable, since the only one that is sorely needed + // is `XcmExecutor`, which will be used in unit tests located in xcm-executor. + type RuntimeEvent = crate::RuntimeEvent; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type UniversalLocation = UniversalLocation; + type SendXcmOrigin = EnsureXcmOrigin; + type Weigher = FixedWeightBounds; + type XcmRouter = DoNothingRouter; + type XcmExecuteFilter = Everything; + type XcmExecutor = xcm_executor::XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type RuntimeOrigin = crate::RuntimeOrigin; + type RuntimeCall = crate::RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = crate::Balances; + type CurrencyMatcher = (); + type TrustedLockers = (); + type SovereignAccountOf = (); + type MaxLockers = frame_support::traits::ConstU32<8>; + type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = pallet_xcm::TestWeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..0231198ba820e362ccd36a511fc8ae2a2bbc821e --- /dev/null +++ b/polkadot/runtime/westend/Cargo.toml @@ -0,0 +1,301 @@ +[package] +name = "westend-runtime" +build = "build.rs" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +log = { version = "0.4.17", default-features = false } +rustc-hex = { version = "2.1.0", default-features = false } +serde = { version = "1.0.163", default-features = false } +serde_derive = { version = "1.0.117", optional = true } +smallvec = "1.8.0" + +authority-discovery-primitives = { package = "sp-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +beefy-primitives = { package = "sp-consensus-beefy", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +binary-merkle-tree = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +offchain-primitives = { package = "sp-offchain", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +tx-pool-api = { package = "sp-transaction-pool", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +block-builder-api = { package = "sp-block-builder", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-executive = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +westend-runtime-constants = { package = "westend-runtime-constants", path = "./constants", default-features = false } +pallet-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-bags-list = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-beefy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-beefy-mmr = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-democracy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-elections-phragmen = { package = "pallet-elections-phragmen", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-fast-unstake = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-identity = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-im-online = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-indices = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-message-queue = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-mmr = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-multisig = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-nomination-pools = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-offences = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-preimage = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-proxy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-recovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-scheduler = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-society = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-staking-reward-curve = { package = "pallet-staking-reward-curve", git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-staking-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-state-trie-migration = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-nomination-pools-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-xcm = { path = "../../xcm/pallet-xcm", default-features = false, features=["experimental"] } +pallet-xcm-benchmarks = { path = "../../xcm/pallet-xcm-benchmarks", default-features = false, optional = true } + +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-election-provider-support-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-nomination-pools-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-offences-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +pallet-session-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +hex-literal = { version = "0.4.1", optional = true } + +runtime-common = { package = "polkadot-runtime-common", path = "../common", default-features = false, features=["experimental"] } +primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } +polkadot-parachain = { path = "../../parachain", default-features = false } +runtime-parachains = { package = "polkadot-runtime-parachains", path = "../parachains", default-features = false } + +xcm = { package = "xcm", path = "../../xcm", default-features = false } +xcm-executor = { package = "xcm-executor", path = "../../xcm/xcm-executor", default-features = false } +xcm-builder = { package = "xcm-builder", path = "../../xcm/xcm-builder", default-features = false } + +[dev-dependencies] +hex-literal = "0.4.1" +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "master" } +serde_json = "1.0.96" +remote-externalities = { git = "https://github.com/paritytech/substrate", branch = "master", package = "frame-remote-externalities" } +tokio = { version = "1.24.2", features = ["macros"] } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +[build-dependencies] +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = ["std"] +no_std = [] +only-staking = [] +std = [ + "authority-discovery-primitives/std", + "bitvec/std", + "primitives/std", + "rustc-hex/std", + "parity-scale-codec/std", + "scale-info/std", + "inherents/std", + "sp-core/std", + "polkadot-parachain/std", + "sp-api/std", + "tx-pool-api/std", + "block-builder-api/std", + "offchain-primitives/std", + "sp-std/std", + "sp-io/std", + "frame-support/std", + "pallet-authority-discovery/std", + "pallet-authorship/std", + "pallet-balances/std", + "pallet-beefy/std", + "pallet-beefy-mmr/std", + "pallet-transaction-payment/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-collective/std", + "pallet-elections-phragmen/std", + "pallet-election-provider-multi-phase/std", + "pallet-fast-unstake/std", + "pallet-democracy/std", + "pallet-grandpa/std", + "pallet-identity/std", + "pallet-im-online/std", + "pallet-indices/std", + "pallet-membership/std", + "pallet-message-queue/std", + "pallet-mmr/std", + "beefy-primitives/std", + "pallet-multisig/std", + "pallet-nomination-pools/std", + "pallet-nomination-pools-runtime-api/std", + "pallet-offences/std", + "pallet-preimage/std", + "pallet-proxy/std", + "pallet-recovery/std", + "pallet-scheduler/std", + "pallet-session/std", + "pallet-society/std", + "pallet-staking/std", + "pallet-staking-runtime-api/std", + "pallet-state-trie-migration/std", + "pallet-sudo/std", + "pallet-timestamp/std", + "pallet-treasury/std", + "pallet-utility/std", + "pallet-vesting/std", + "pallet-xcm/std", + "pallet-babe/std", + "pallet-bags-list/std", + "frame-executive/std", + "sp-application-crypto/std", + "sp-mmr-primitives/std", + "sp-runtime/std", + "sp-staking/std", + "frame-system/std", + "frame-system-rpc-runtime-api/std", + "westend-runtime-constants/std", + "sp-version/std", + "serde_derive", + "serde/std", + "log/std", + "babe-primitives/std", + "sp-session/std", + "runtime-common/std", + "runtime-parachains/std", + "frame-try-runtime/std", + "sp-npos-elections/std", + "xcm/std", + "xcm-executor/std", + "xcm-builder/std", + "frame-election-provider-support/std", +] +runtime-benchmarks = [ + "runtime-common/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "pallet-babe/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-collective/runtime-benchmarks", + "pallet-democracy/runtime-benchmarks", + "pallet-elections-phragmen/runtime-benchmarks", + "pallet-election-provider-multi-phase/runtime-benchmarks", + "pallet-election-provider-support-benchmarking/runtime-benchmarks", + "pallet-fast-unstake/runtime-benchmarks", + "pallet-grandpa/runtime-benchmarks", + "pallet-identity/runtime-benchmarks", + "pallet-im-online/runtime-benchmarks", + "pallet-indices/runtime-benchmarks", + "pallet-membership/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "pallet-multisig/runtime-benchmarks", + "pallet-nomination-pools-benchmarking/runtime-benchmarks", + "pallet-preimage/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", + "pallet-recovery/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", + "pallet-society/runtime-benchmarks", + "pallet-staking/runtime-benchmarks", + "pallet-sudo/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-treasury/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", + "pallet-vesting/runtime-benchmarks", + "pallet-offences-benchmarking/runtime-benchmarks", + "pallet-session-benchmarking/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "frame-system-benchmarking/runtime-benchmarks", + "hex-literal", + "xcm-builder/runtime-benchmarks", + "pallet-xcm-benchmarks/runtime-benchmarks", + "frame-election-provider-support/runtime-benchmarks", + "pallet-bags-list/runtime-benchmarks", + "runtime-parachains/runtime-benchmarks", +] +try-runtime = [ + "frame-executive/try-runtime", + "frame-system/try-runtime", + "frame-try-runtime", + "runtime-common/try-runtime", + "pallet-authority-discovery/try-runtime", + "pallet-authorship/try-runtime", + "pallet-balances/try-runtime", + "pallet-beefy/try-runtime", + "pallet-beefy-mmr/try-runtime", + "pallet-transaction-payment/try-runtime", + "pallet-collective/try-runtime", + "pallet-elections-phragmen/try-runtime", + "pallet-election-provider-multi-phase/try-runtime", + "pallet-fast-unstake/try-runtime", + "pallet-democracy/try-runtime", + "pallet-grandpa/try-runtime", + "pallet-identity/try-runtime", + "pallet-im-online/try-runtime", + "pallet-indices/try-runtime", + "pallet-membership/try-runtime", + "pallet-message-queue/try-runtime", + "pallet-mmr/try-runtime", + "pallet-multisig/try-runtime", + "pallet-nomination-pools/try-runtime", + "pallet-offences/try-runtime", + "pallet-preimage/try-runtime", + "pallet-proxy/try-runtime", + "pallet-recovery/try-runtime", + "pallet-scheduler/try-runtime", + "pallet-session/try-runtime", + "pallet-society/try-runtime", + "pallet-staking/try-runtime", + "pallet-state-trie-migration/try-runtime", + "pallet-sudo/try-runtime", + "pallet-timestamp/try-runtime", + "pallet-treasury/try-runtime", + "pallet-utility/try-runtime", + "pallet-vesting/try-runtime", + "pallet-xcm/try-runtime", + "pallet-babe/try-runtime", + "pallet-bags-list/try-runtime", +] +# When enabled, the runtime API will not be build. +# +# This is required by Cumulus to access certain types of the +# runtime without clashing with the runtime API exported functions +# in WASM. +disable-runtime-api = [] + +# Set timing constants (e.g. session period) to faster versions to speed up testing. +fast-runtime = [] + +runtime-metrics = ["runtime-parachains/runtime-metrics", "sp-io/with-tracing"] diff --git a/polkadot/runtime/westend/build.rs b/polkadot/runtime/westend/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..428c971bc132a5c7e856e6485246c4fd2ff57822 --- /dev/null +++ b/polkadot/runtime/westend/build.rs @@ -0,0 +1,25 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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 Polkadot. If not, see . + +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .import_memory() + .export_heap_base() + .build() +} diff --git a/polkadot/runtime/westend/constants/Cargo.toml b/polkadot/runtime/westend/constants/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..63e9ad34a7f287287f129885bb0c9f5248ad0da4 --- /dev/null +++ b/polkadot/runtime/westend/constants/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "westend-runtime-constants" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +smallvec = "1.8.0" + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +primitives = { package = "polkadot-primitives", path = "../../../primitives", default-features = false } +runtime-common = { package = "polkadot-runtime-common", path = "../../common", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-weights = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } + +[features] +default = ["std"] +std = [ + "frame-support/std", + "primitives/std", + "runtime-common/std", + "sp-core/std", + "sp-runtime/std", + "sp-weights/std" +] diff --git a/polkadot/runtime/westend/constants/src/lib.rs b/polkadot/runtime/westend/constants/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..f9830dab3325b62b2a9003498911e79e7778e0d3 --- /dev/null +++ b/polkadot/runtime/westend/constants/src/lib.rs @@ -0,0 +1,127 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod weights; + +/// Money matters. +pub mod currency { + use primitives::Balance; + + /// The existential deposit. + pub const EXISTENTIAL_DEPOSIT: Balance = 1 * CENTS; + + pub const UNITS: Balance = 1_000_000_000_000; + pub const CENTS: Balance = UNITS / 100; + pub const MILLICENTS: Balance = CENTS / 1_000; + pub const GRAND: Balance = CENTS * 100_000; + + pub const fn deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 100 * CENTS + (bytes as Balance) * 5 * MILLICENTS + } +} + +/// Time and blocks. +pub mod time { + use primitives::{BlockNumber, Moment}; + use runtime_common::prod_or_fast; + + pub const MILLISECS_PER_BLOCK: Moment = 6000; + pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; + pub const EPOCH_DURATION_IN_SLOTS: BlockNumber = prod_or_fast!(1 * HOURS, 1 * MINUTES); + + // These time units are defined in number of blocks. + pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); + pub const HOURS: BlockNumber = MINUTES * 60; + pub const DAYS: BlockNumber = HOURS * 24; + + // 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. + // The choice of is done in accordance to the slot duration and expected target + // block time, for safely resisting network delays of maximum two seconds. + // + pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); +} + +/// Fee-related. +pub mod fee { + use crate::weights::ExtrinsicBaseWeight; + use frame_support::weights::{ + WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, + }; + use primitives::Balance; + use smallvec::smallvec; + pub use sp_runtime::Perbill; + + /// The block saturation level. Fees will be updates based on this value. + pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); + + /// 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,` MAXIMUM_BLOCK_WEIGHT`] + /// - [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. + pub struct WeightToFee; + impl WeightToFeePolynomial for WeightToFee { + type Balance = Balance; + fn polynomial() -> WeightToFeeCoefficients { + // in Westend, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: + let p = super::currency::CENTS; + let q = 10 * Balance::from(ExtrinsicBaseWeight::get().ref_time()); + smallvec![WeightToFeeCoefficient { + degree: 1, + negative: false, + coeff_frac: Perbill::from_rational(p % q, q), + coeff_integer: p / q, + }] + } + } +} + +#[cfg(test)] +mod tests { + use super::{ + currency::{CENTS, MILLICENTS, UNITS}, + fee::WeightToFee, + }; + use crate::weights::ExtrinsicBaseWeight; + use frame_support::weights::WeightToFee as WeightToFeeT; + use runtime_common::MAXIMUM_BLOCK_WEIGHT; + + #[test] + // Test that the fee for `MAXIMUM_BLOCK_WEIGHT` of weight has sane bounds. + fn full_block_fee_is_correct() { + // A full block should cost between 10 and 100 UNITS. + let full_block = WeightToFee::weight_to_fee(&MAXIMUM_BLOCK_WEIGHT); + assert!(full_block >= 10 * UNITS); + assert!(full_block <= 100 * UNITS); + } + + #[test] + // This function tests that the fee for `ExtrinsicBaseWeight` of weight is correct + fn extrinsic_base_fee_is_correct() { + // `ExtrinsicBaseWeight` should cost 1/10 of a CENT + println!("Base: {}", ExtrinsicBaseWeight::get()); + let x = WeightToFee::weight_to_fee(&ExtrinsicBaseWeight::get()); + let y = CENTS / 10; + assert!(x.max(y) - x.min(y) < MILLICENTS); + } +} diff --git a/polkadot/runtime/westend/constants/src/weights/block_weights.rs b/polkadot/runtime/westend/constants/src/weights/block_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..ab14b155188bea11a8697aac740418181d02a855 --- /dev/null +++ b/polkadot/runtime/westend/constants/src/weights/block_weights.rs @@ -0,0 +1,81 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14 (Y/M/D) +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! +//! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Development` +//! WARMUPS: `10`, REPEAT: `100` +//! WEIGHT-PATH: `runtime/westend/constants/src/weights/` +//! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` + +// Executed Command: +// ./target/production/polkadot +// benchmark +// overhead +// --chain=westend-dev +// --execution=wasm +// --wasm-execution=compiled +// --weight-path=runtime/westend/constants/src/weights/ +// --warmup=10 +// --repeat=100 +// --header=./file_header.txt + +use sp_core::parameter_types; +use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; + +parameter_types! { + /// Time to execute an empty block. + /// Calculated by multiplying the *Average* with `1.0` and adding `0`. + /// + /// Stats nanoseconds: + /// Min, Max: 449_093, 498_211 + /// Average: 461_988 + /// Median: 459_070 + /// Std-Dev: 10124.58 + /// + /// Percentiles nanoseconds: + /// 99th: 493_580 + /// 95th: 482_929 + /// 75th: 464_502 + pub const BlockExecutionWeight: Weight = + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(461_988), 0); +} + +#[cfg(test)] +mod test_weights { + use sp_weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::BlockExecutionWeight::get(); + + // At least 100 µs. + assert!( + w.ref_time() >= 100u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 100 µs." + ); + // At most 50 ms. + assert!( + w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 50 ms." + ); + } +} diff --git a/polkadot/runtime/westend/constants/src/weights/extrinsic_weights.rs b/polkadot/runtime/westend/constants/src/weights/extrinsic_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..2542bc9ab64d211ec22b3063b31f911d70359860 --- /dev/null +++ b/polkadot/runtime/westend/constants/src/weights/extrinsic_weights.rs @@ -0,0 +1,81 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14 (Y/M/D) +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! +//! SHORT-NAME: `extrinsic`, LONG-NAME: `ExtrinsicBase`, RUNTIME: `Development` +//! WARMUPS: `10`, REPEAT: `100` +//! WEIGHT-PATH: `runtime/westend/constants/src/weights/` +//! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` + +// Executed Command: +// ./target/production/polkadot +// benchmark +// overhead +// --chain=westend-dev +// --execution=wasm +// --wasm-execution=compiled +// --weight-path=runtime/westend/constants/src/weights/ +// --warmup=10 +// --repeat=100 +// --header=./file_header.txt + +use sp_core::parameter_types; +use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; + +parameter_types! { + /// Time to execute a NO-OP extrinsic, for example `System::remark`. + /// Calculated by multiplying the *Average* with `1.0` and adding `0`. + /// + /// Stats nanoseconds: + /// Min, Max: 112_202, 116_271 + /// Average: 113_632 + /// Median: 113_689 + /// Std-Dev: 576.31 + /// + /// Percentiles nanoseconds: + /// 99th: 114_688 + /// 95th: 114_367 + /// 75th: 113_969 + pub const ExtrinsicBaseWeight: Weight = + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(113_632), 0); +} + +#[cfg(test)] +mod test_weights { + use sp_weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::ExtrinsicBaseWeight::get(); + + // At least 10 µs. + assert!( + w.ref_time() >= 10u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 10 µs." + ); + // At most 1 ms. + assert!( + w.ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 1 ms." + ); + } +} diff --git a/polkadot/runtime/westend/constants/src/weights/mod.rs b/polkadot/runtime/westend/constants/src/weights/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..23812ce7ed0528c394f84042fb9842eb617a834b --- /dev/null +++ b/polkadot/runtime/westend/constants/src/weights/mod.rs @@ -0,0 +1,28 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Expose the auto generated weight files. + +pub mod block_weights; +pub mod extrinsic_weights; +pub mod paritydb_weights; +pub mod rocksdb_weights; + +pub use block_weights::BlockExecutionWeight; +pub use extrinsic_weights::ExtrinsicBaseWeight; +pub use paritydb_weights::constants::ParityDbWeight; +pub use rocksdb_weights::constants::RocksDbWeight; diff --git a/polkadot/runtime/westend/constants/src/weights/paritydb_weights.rs b/polkadot/runtime/westend/constants/src/weights/paritydb_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..25679703831a13b8d1bb7fb7dd4d92fa84b1f255 --- /dev/null +++ b/polkadot/runtime/westend/constants/src/weights/paritydb_weights.rs @@ -0,0 +1,63 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// `ParityDB` can be enabled with a feature flag, but is still experimental. These weights + /// are available for brave runtime engineers who may want to try this out as default. + pub const ParityDbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 8_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + write: 50_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use super::constants::ParityDbWeight as W; + use frame_support::weights::constants; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/polkadot/runtime/westend/constants/src/weights/rocksdb_weights.rs b/polkadot/runtime/westend/constants/src/weights/rocksdb_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..3dd817aa6f137085b0e5fdf2b11b7f50e5c8b002 --- /dev/null +++ b/polkadot/runtime/westend/constants/src/weights/rocksdb_weights.rs @@ -0,0 +1,63 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// By default, Substrate uses `RocksDB`, so this will be the weight used throughout + /// the runtime. + pub const RocksDbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 25_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + write: 100_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use super::constants::RocksDbWeight as W; + use frame_support::weights::constants; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/polkadot/runtime/westend/src/bag_thresholds.rs b/polkadot/runtime/westend/src/bag_thresholds.rs new file mode 100644 index 0000000000000000000000000000000000000000..de28520d461989caeeb2f5e3617f9e273789dace --- /dev/null +++ b/polkadot/runtime/westend/src/bag_thresholds.rs @@ -0,0 +1,234 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated voter bag thresholds. +//! +//! Generated on 2021-07-05T14:35:50.538338181+00:00 +//! for the westend runtime. + +/// Existential weight for this runtime. +#[cfg(any(test, feature = "std"))] +#[allow(unused)] +pub const EXISTENTIAL_WEIGHT: u64 = 10_000_000_000; + +/// Constant ratio between bags for this runtime. +#[cfg(any(test, feature = "std"))] +#[allow(unused)] +pub const CONSTANT_RATIO: f64 = 1.1131723507077667; + +/// Upper thresholds delimiting the bag list. +pub const THRESHOLDS: [u64; 200] = [ + 10_000_000_000, + 11_131_723_507, + 12_391_526_824, + 13_793_905_044, + 15_354_993_703, + 17_092_754_435, + 19_027_181_634, + 21_180_532_507, + 23_577_583_160, + 26_245_913_670, + 29_216_225_417, + 32_522_694_326, + 36_203_364_094, + 40_300_583_912, + 44_861_495_728, + 49_938_576_656, + 55_590_242_767, + 61_881_521_217, + 68_884_798_439, + 76_680_653_006, + 85_358_782_760, + 95_019_036_859, + 105_772_564_622, + 117_743_094_401, + 131_068_357_174, + 145_901_671_259, + 162_413_706_368, + 180_794_447_305, + 201_255_379_901, + 224_031_924_337, + 249_386_143_848, + 277_609_759_981, + 309_027_509_097, + 344_000_878_735, + 382_932_266_827, + 426_269_611_626, + 474_511_545_609, + 528_213_132_664, + 587_992_254_562, + 654_536_720_209, + 728_612_179_460, + 811_070_932_564, + 902_861_736_593, + 1_005_040_721_687, + 1_118_783_542_717, + 1_245_398_906_179, + 1_386_343_627_960, + 1_543_239_395_225, + 1_717_891_425_287, + 1_912_309_236_147, + 2_128_729_767_682, + 2_369_643_119_512, + 2_637_821_201_686, + 2_936_349_627_828, + 3_268_663_217_709, + 3_638_585_517_729, + 4_050_372_794_022, + 4_508_763_004_364, + 5_019_030_312_352, + 5_587_045_771_074, + 6_219_344_874_498, + 6_923_202_753_807, + 7_706_717_883_882, + 8_578_905_263_043, + 9_549_800_138_161, + 10_630_573_468_586, + 11_833_660_457_397, + 13_172_903_628_838, + 14_663_712_098_160, + 16_323_238_866_411, + 18_170_578_180_087, + 20_226_985_226_447, + 22_516_120_692_255, + 25_064_322_999_817, + 27_900_911_352_605, + 31_058_523_077_268, + 34_573_489_143_434, + 38_486_252_181_966, + 42_841_831_811_331, + 47_690_342_626_046, + 53_087_570_807_094, + 59_095_615_988_698, + 65_783_605_766_662, + 73_228_491_069_308, + 81_515_931_542_404, + 90_741_281_135_191, + 101_010_685_227_495, + 112_442_301_921_293, + 125_167_661_548_718, + 139_333_180_038_781, + 155_101_843_555_358, + 172_655_083_789_626, + 192_194_865_483_744, + 213_946_010_204_502, + 238_158_783_103_893, + 265_111_772_429_462, + 295_115_094_915_607, + 328_513_963_936_552, + 365_692_661_475_578, + 407_078_959_611_349, + 453_149_042_394_237, + 504_432_984_742_966, + 561_520_851_400_862, + 625_069_486_125_324, + 695_810_069_225_823, + 774_556_530_406_243, + 862_214_913_708_369, + 959_793_802_308_039, + 1_068_415_923_109_985, + 1_189_331_064_661_951, + 1_323_930_457_019_515, + 1_473_762_779_014_021, + 1_640_551_977_100_649, + 1_826_217_100_807_404, + 2_032_894_383_008_501, + 2_262_961_819_074_188, + 2_519_066_527_700_738, + 2_804_155_208_229_882, + 3_121_508_044_894_685, + 3_474_776_448_088_622, + 3_868_025_066_902_796, + 4_305_778_556_320_752, + 4_793_073_637_166_665, + 5_335_517_047_800_242, + 5_939_350_054_341_159, + 6_611_520_261_667_250, + 7_359_761_551_432_161, + 8_192_683_066_856_378, + 9_119_868_268_136_230, + 10_151_985_198_186_376, + 11_300_909_227_415_580, + 12_579_859_689_817_292, + 14_003_551_982_487_792, + 15_588_366_878_604_342, + 17_352_539_001_951_086, + 19_316_366_631_550_092, + 21_502_445_250_375_680, + 23_935_927_525_325_748, + 26_644_812_709_737_600, + 29_660_268_798_266_784, + 33_016_991_140_790_860, + 36_753_601_641_491_664, + 40_913_093_136_236_104, + 45_543_324_061_189_736, + 50_697_569_104_240_168, + 56_435_132_174_936_472, + 62_822_028_745_677_552, + 69_931_745_415_056_768, + 77_846_085_432_775_824, + 86_656_109_914_600_688, + 96_463_185_576_826_656, + 107_380_151_045_315_664, + 119_532_615_158_469_088, + 133_060_402_202_199_856, + 148_119_160_705_543_712, + 164_882_154_307_451_552, + 183_542_255_300_186_560, + 204_314_163_786_713_728, + 227_436_877_985_347_776, + 253_176_444_104_585_088, + 281_829_017_427_734_464, + 313_724_269_827_691_328, + 349_229_182_918_168_832, + 388_752_270_484_770_624, + 432_748_278_778_513_664, + 481_723_418_752_617_984, + 536_241_190_443_833_600, + 596_928_866_512_693_376, + 664_484_709_541_257_600, + 739_686_006_129_409_280, + 823_398_010_228_713_984, + 916_583_898_614_395_264, + 1_020_315_853_041_475_584, + 1_135_787_396_594_579_584, + 1_264_327_126_171_442_688, + 1_407_413_999_103_859_968, + 1_566_694_349_801_462_272, + 1_744_000_832_209_069_824, + 1_941_373_506_026_471_680, + 2_161_083_309_305_266_176, + 2_405_658_187_494_662_656, + 2_677_912_179_572_818_944, + 2_980_977_795_924_034_048, + 3_318_342_060_496_414_208, + 3_693_886_631_935_247_360, + 4_111_932_465_319_354_368, + 4_577_289_528_371_127_808, + 5_095_312_144_166_932_480, + 5_671_960_597_112_134_656, + 6_313_869_711_009_142_784, + 7_028_425_188_266_614_784, + 7_823_848_588_596_424_704, + 8_709_291_924_949_524_480, + 9_694_942_965_096_232_960, + 10_792_142_450_433_898_496, + 12_013_514_580_722_579_456, + 13_373_112_266_084_982_784, + 14_886_578_817_516_689_408, + 16_571_327_936_291_497_984, + 18_446_744_073_709_551_615, +]; diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..9ae30c376010ed2af96b58eae556fc5ac3d3c7a5 --- /dev/null +++ b/polkadot/runtime/westend/src/lib.rs @@ -0,0 +1,2218 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The Westend runtime. This can be compiled with `#[no_std]`, ready for Wasm. + +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 512. +#![recursion_limit = "512"] + +use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; +use beefy_primitives::{ + ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}, + mmr::{BeefyDataProvider, MmrLeafVersion}, +}; +use frame_election_provider_support::{bounds::ElectionBoundsBuilder, onchain, SequentialPhragmen}; +use frame_support::{ + construct_runtime, parameter_types, + traits::{ + ConstU32, InstanceFilter, KeyOwnerProofSystem, ProcessMessage, ProcessMessageError, + WithdrawReasons, + }, + weights::{ConstantMultiplier, WeightMeter}, + PalletId, +}; +use frame_system::EnsureRoot; +use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +use pallet_session::historical as session_historical; +use pallet_transaction_payment::{CurrencyAdapter, FeeDetails, RuntimeDispatchInfo}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use primitives::{ + slashing, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, + CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash, + Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce, + OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, + SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, + ValidatorSignature, PARACHAIN_KEY_TYPE_ID, +}; +use runtime_common::{ + assigned_slots, auctions, crowdloan, elections::OnChainAccuracy, impl_runtime_weights, + impls::ToAuthor, paras_registrar, paras_sudo_wrapper, prod_or_fast, slots, BalanceToU256, + BlockHashCount, BlockLength, CurrencyToVote, SlowAdjustingFeeUpdate, U256ToBalance, +}; +use runtime_parachains::{ + assigner_parachains as parachains_assigner_parachains, + configuration as parachains_configuration, disputes as parachains_disputes, + disputes::slashing as parachains_slashing, + dmp as parachains_dmp, hrmp as parachains_hrmp, inclusion as parachains_inclusion, + inclusion::{AggregateMessageOrigin, UmpQueueId}, + initializer as parachains_initializer, origin as parachains_origin, paras as parachains_paras, + paras_inherent as parachains_paras_inherent, reward_points as parachains_reward_points, + runtime_api_impl::v5 as parachains_runtime_api_impl, + scheduler as parachains_scheduler, session_info as parachains_session_info, + shared as parachains_shared, +}; +use scale_info::TypeInfo; +use sp_core::{OpaqueMetadata, RuntimeDebug, H256}; +use sp_runtime::{ + create_runtime_str, + curve::PiecewiseLinear, + generic, impl_opaque_keys, + traits::{ + AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT, + Keccak256, OpaqueKeys, SaturatedConversion, Verify, + }, + transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, FixedU128, KeyTypeId, Perbill, +}; +use sp_staking::SessionIndex; +use sp_std::{collections::btree_map::BTreeMap, prelude::*}; +#[cfg(any(feature = "std", test))] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; +use xcm::latest::Junction; + +pub use frame_system::Call as SystemCall; +pub use pallet_balances::Call as BalancesCall; +pub use pallet_election_provider_multi_phase::Call as EPMCall; +#[cfg(feature = "std")] +pub use pallet_staking::StakerStatus; +use pallet_staking::UseValidatorsMap; +pub use pallet_timestamp::Call as TimestampCall; +use sp_runtime::traits::Get; +#[cfg(any(feature = "std", test))] +pub use sp_runtime::BuildStorage; + +/// Constant values used within the runtime. +use westend_runtime_constants::{currency::*, fee::*, time::*}; + +mod bag_thresholds; +mod weights; +pub mod xcm_config; + +#[cfg(test)] +mod tests; + +impl_runtime_weights!(westend_runtime_constants); + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +/// Runtime version (Westend). +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("westend"), + impl_name: create_runtime_str!("parity-westend"), + authoring_version: 2, + spec_version: 9430, + impl_version: 0, + #[cfg(not(feature = "disable-runtime-api"))] + apis: RUNTIME_API_VERSIONS, + #[cfg(feature = "disable-runtime-api")] + apis: sp_version::create_apis_vec![[]], + transaction_version: 22, + state_version: 1, +}; + +/// The BABE epoch configuration at genesis. +pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration = + babe_primitives::BabeEpochConfiguration { + c: PRIMARY_PROBABILITY, + allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots, + }; + +/// Native version. +#[cfg(any(feature = "std", test))] +pub fn native_version() -> NativeVersion { + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } +} + +parameter_types! { + pub const Version: RuntimeVersion = VERSION; + pub const SS58Prefix: u8 = 42; +} + +impl frame_system::Config for Runtime { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = BlockWeights; + type BlockLength = BlockLength; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = Nonce; + type Hash = Hash; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = AccountIdLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type DbWeight = RocksDbWeight; + type Version = Version; + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = weights::frame_system::WeightInfo; + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub MaximumSchedulerWeight: frame_support::weights::Weight = Perbill::from_percent(80) * + BlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; + pub const NoPreimagePostponement: Option = Some(10); +} + +impl pallet_scheduler::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureRoot; + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type WeightInfo = weights::pallet_scheduler::WeightInfo; + type OriginPrivilegeCmp = frame_support::traits::EqualPrivilegeOnly; + type Preimages = Preimage; +} + +parameter_types! { + pub const PreimageMaxSize: u32 = 4096 * 1024; + pub const PreimageBaseDeposit: Balance = deposit(2, 64); + pub const PreimageByteDeposit: Balance = deposit(0, 1); +} + +impl pallet_preimage::Config for Runtime { + type WeightInfo = weights::pallet_preimage::WeightInfo; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type BaseDeposit = PreimageBaseDeposit; + type ByteDeposit = PreimageByteDeposit; +} + +parameter_types! { + pub const EpochDuration: u64 = prod_or_fast!( + EPOCH_DURATION_IN_SLOTS as u64, + 2 * MINUTES as u64 + ); + pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; + pub const ReportLongevity: u64 = + BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get(); +} + +impl pallet_babe::Config for Runtime { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; + + // session module is the trigger + type EpochChangeTrigger = pallet_babe::ExternalTrigger; + + type DisabledValidators = Session; + + type WeightInfo = (); + + type MaxAuthorities = MaxAuthorities; + type MaxNominators = MaxNominatorRewardedPerValidator; + + type KeyOwnerProof = + >::Proof; + + type EquivocationReportSystem = + pallet_babe::EquivocationReportSystem; +} + +parameter_types! { + pub const IndexDeposit: Balance = 100 * CENTS; +} + +impl pallet_indices::Config for Runtime { + type AccountIndex = AccountIndex; + type Currency = Balances; + type Deposit = IndexDeposit; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_indices::WeightInfo; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = weights::pallet_balances::WeightInfo; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +parameter_types! { + pub const BeefySetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); +} + +impl pallet_beefy::Config for Runtime { + type BeefyId = BeefyId; + type MaxAuthorities = MaxAuthorities; + type MaxNominators = MaxNominatorRewardedPerValidator; + type MaxSetIdSessionEntries = BeefySetIdSessionEntries; + type OnNewValidatorSet = BeefyMmrLeaf; + type WeightInfo = (); + type KeyOwnerProof = >::Proof; + type EquivocationReportSystem = + pallet_beefy::EquivocationReportSystem; +} + +impl pallet_mmr::Config for Runtime { + const INDEXING_PREFIX: &'static [u8] = mmr::INDEXING_PREFIX; + type Hashing = Keccak256; + type OnNewRoot = pallet_beefy_mmr::DepositBeefyDigest; + type WeightInfo = (); + type LeafData = pallet_beefy_mmr::Pallet; +} + +/// MMR helper types. +mod mmr { + use super::Runtime; + pub use pallet_mmr::primitives::*; + + pub type Leaf = <::LeafData as LeafDataProvider>::LeafData; + pub type Hashing = ::Hashing; + pub type Hash = ::Output; +} + +parameter_types! { + /// Version of the produced MMR leaf. + /// + /// The version consists of two parts; + /// - `major` (3 bits) + /// - `minor` (5 bits) + /// + /// `major` should be updated only if decoding the previous MMR Leaf format from the payload + /// is not possible (i.e. backward incompatible change). + /// `minor` should be updated if fields are added to the previous MMR Leaf, which given SCALE + /// encoding does not prevent old leafs from being decoded. + /// + /// Hence we expect `major` to be changed really rarely (think never). + /// See [`MmrLeafVersion`] type documentation for more details. + pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0); +} + +/// A BEEFY data provider that merkelizes all the parachain heads at the current block +/// (sorted by their parachain id). +pub struct ParaHeadsRootProvider; +impl BeefyDataProvider for ParaHeadsRootProvider { + fn extra_data() -> H256 { + let mut para_heads: Vec<(u32, Vec)> = Paras::parachains() + .into_iter() + .filter_map(|id| Paras::para_head(&id).map(|head| (id.into(), head.0))) + .collect(); + para_heads.sort_by_key(|k| k.0); + binary_merkle_tree::merkle_root::( + para_heads.into_iter().map(|pair| pair.encode()), + ) + .into() + } +} + +impl pallet_beefy_mmr::Config for Runtime { + type LeafVersion = LeafVersion; + type BeefyAuthorityToMerkleLeaf = pallet_beefy_mmr::BeefyEcdsaToEthereum; + type LeafExtra = H256; + type BeefyDataProvider = ParaHeadsRootProvider; +} + +parameter_types! { + pub const TransactionByteFee: Balance = 10 * MILLICENTS; + /// This value increases the priority of `Operational` transactions by adding + /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`. + pub const OperationalFeeMultiplier: u8 = 5; +} + +impl pallet_transaction_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter>; + type OperationalFeeMultiplier = OperationalFeeMultiplier; + type WeightToFee = WeightToFee; + type LengthToFee = ConstantMultiplier; + type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; +} + +parameter_types! { + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; +} +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = Babe; + type MinimumPeriod = MinimumPeriod; + type WeightInfo = weights::pallet_timestamp::WeightInfo; +} + +impl pallet_authorship::Config for Runtime { + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; + type EventHandler = (Staking, ImOnline); +} + +parameter_types! { + pub const Period: BlockNumber = 10 * MINUTES; + pub const Offset: BlockNumber = 0; +} + +impl_opaque_keys! { + pub struct OldSessionKeys { + pub grandpa: Grandpa, + pub babe: Babe, + pub im_online: ImOnline, + pub para_validator: Initializer, + pub para_assignment: ParaSessionInfo, + pub authority_discovery: AuthorityDiscovery, + } +} + +impl_opaque_keys! { + pub struct SessionKeys { + pub grandpa: Grandpa, + pub babe: Babe, + pub im_online: ImOnline, + pub para_validator: Initializer, + pub para_assignment: ParaSessionInfo, + pub authority_discovery: AuthorityDiscovery, + pub beefy: Beefy, + } +} + +// remove this when removing `OldSessionKeys` +fn transform_session_keys(v: AccountId, old: OldSessionKeys) -> SessionKeys { + SessionKeys { + grandpa: old.grandpa, + babe: old.babe, + im_online: old.im_online, + para_validator: old.para_validator, + para_assignment: old.para_assignment, + authority_discovery: old.authority_discovery, + beefy: { + // From Session::upgrade_keys(): + // + // Care should be taken that the raw versions of the + // added keys are unique for every `ValidatorId, KeyTypeId` combination. + // This is an invariant that the session pallet typically maintains internally. + // + // So, produce a dummy value that's unique for the `ValidatorId, KeyTypeId` combination. + let mut id: BeefyId = sp_application_crypto::ecdsa::Public::from_raw([0u8; 33]).into(); + let id_raw: &mut [u8] = id.as_mut(); + id_raw[1..33].copy_from_slice(v.as_ref()); + id_raw[0..4].copy_from_slice(b"beef"); + id + }, + } +} + +impl pallet_session::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = AccountId; + type ValidatorIdOf = pallet_staking::StashOf; + type ShouldEndSession = Babe; + type NextSessionRotation = Babe; + type SessionManager = pallet_session::historical::NoteHistoricalRoot; + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; + type WeightInfo = weights::pallet_session::WeightInfo; +} + +impl pallet_session::historical::Config for Runtime { + type FullIdentification = pallet_staking::Exposure; + type FullIdentificationOf = pallet_staking::ExposureOf; +} + +pub struct MaybeSignedPhase; + +impl Get for MaybeSignedPhase { + fn get() -> u32 { + // 1 day = 4 eras -> 1 week = 28 eras. We want to disable signed phase once a week to test + // the fallback unsigned phase is able to compute elections on Westend. + if Staking::current_era().unwrap_or(1) % 28 == 0 { + 0 + } else { + SignedPhase::get() + } + } +} + +parameter_types! { + // phase durations. 1/4 of the last session for each. + pub SignedPhase: u32 = prod_or_fast!( + EPOCH_DURATION_IN_SLOTS / 4, + (1 * MINUTES).min(EpochDuration::get().saturated_into::() / 2) + ); + pub UnsignedPhase: u32 = prod_or_fast!( + EPOCH_DURATION_IN_SLOTS / 4, + (1 * MINUTES).min(EpochDuration::get().saturated_into::() / 2) + ); + + // signed config + pub const SignedMaxSubmissions: u32 = 128; + pub const SignedMaxRefunds: u32 = 128 / 4; + pub const SignedDepositBase: Balance = deposit(2, 0); + pub const SignedDepositByte: Balance = deposit(0, 10) / 1024; + // Each good submission will get 1 WND as reward + pub SignedRewardBase: Balance = 1 * UNITS; + pub BetterUnsignedThreshold: Perbill = Perbill::from_rational(5u32, 10_000); + + // 1 hour session, 15 minutes unsigned phase, 4 offchain executions. + pub OffchainRepeat: BlockNumber = UnsignedPhase::get() / 4; + + pub const MaxElectingVoters: u32 = 22_500; + /// We take the top 22500 nominators as electing voters and all of the validators as electable + /// targets. Whilst this is the case, we cannot and shall not increase the size of the + /// validator intentions. + pub ElectionBounds: frame_election_provider_support::bounds::ElectionBounds = + ElectionBoundsBuilder::default().voters_count(MaxElectingVoters::get().into()).build(); + // Maximum winners that can be chosen as active validators + pub const MaxActiveValidators: u32 = 1000; + +} + +frame_election_provider_support::generate_solution_type!( + #[compact] + pub struct NposCompactSolution16::< + VoterIndex = u32, + TargetIndex = u16, + Accuracy = sp_runtime::PerU16, + MaxVoters = MaxElectingVoters, + >(16) +); + +pub struct OnChainSeqPhragmen; +impl onchain::Config for OnChainSeqPhragmen { + type System = Runtime; + type Solver = SequentialPhragmen; + type DataProvider = Staking; + type WeightInfo = weights::frame_election_provider_support::WeightInfo; + type MaxWinners = MaxActiveValidators; + type Bounds = ElectionBounds; +} + +impl pallet_election_provider_multi_phase::MinerConfig for Runtime { + type AccountId = AccountId; + type MaxLength = OffchainSolutionLengthLimit; + type MaxWeight = OffchainSolutionWeightLimit; + type Solution = NposCompactSolution16; + type MaxVotesPerVoter = < + ::DataProvider + as + frame_election_provider_support::ElectionDataProvider + >::MaxVotesPerVoter; + type MaxWinners = MaxActiveValidators; + + // The unsigned submissions have to respect the weight of the submit_unsigned call, thus their + // weight estimate function is wired to this call's weight. + fn solution_weight(v: u32, t: u32, a: u32, d: u32) -> Weight { + < + ::WeightInfo + as + pallet_election_provider_multi_phase::WeightInfo + >::submit_unsigned(v, t, a, d) + } +} + +impl pallet_election_provider_multi_phase::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type EstimateCallFee = TransactionPayment; + type SignedPhase = MaybeSignedPhase; + type UnsignedPhase = UnsignedPhase; + type SignedMaxSubmissions = SignedMaxSubmissions; + type SignedMaxRefunds = SignedMaxRefunds; + type SignedRewardBase = SignedRewardBase; + type SignedDepositBase = SignedDepositBase; + type SignedDepositByte = SignedDepositByte; + type SignedDepositWeight = (); + type SignedMaxWeight = + ::MaxWeight; + type MinerConfig = Self; + type SlashHandler = (); // burn slashes + type RewardHandler = (); // nothing to do upon rewards + type BetterUnsignedThreshold = BetterUnsignedThreshold; + type BetterSignedThreshold = (); + type OffchainRepeat = OffchainRepeat; + type MinerTxPriority = NposSolutionPriority; + type DataProvider = Staking; + #[cfg(any(feature = "fast-runtime", feature = "runtime-benchmarks"))] + type Fallback = onchain::OnChainExecution; + #[cfg(not(any(feature = "fast-runtime", feature = "runtime-benchmarks")))] + type Fallback = frame_election_provider_support::NoElection<( + AccountId, + BlockNumber, + Staking, + MaxActiveValidators, + )>; + type GovernanceFallback = onchain::OnChainExecution; + type Solver = SequentialPhragmen< + AccountId, + pallet_election_provider_multi_phase::SolutionAccuracyOf, + (), + >; + type BenchmarkingConfig = runtime_common::elections::BenchmarkConfig; + type ForceOrigin = EnsureRoot; + type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo; + type MaxWinners = MaxActiveValidators; + type ElectionBounds = ElectionBounds; +} + +parameter_types! { + pub const BagThresholds: &'static [u64] = &bag_thresholds::THRESHOLDS; +} + +type VoterBagsListInstance = pallet_bags_list::Instance1; +impl pallet_bags_list::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ScoreProvider = Staking; + type WeightInfo = weights::pallet_bags_list::WeightInfo; + type BagThresholds = BagThresholds; + type Score = sp_npos_elections::VoteWeight; +} + +pallet_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! { + // Six sessions in an era (6 hours). + pub const SessionsPerEra: SessionIndex = prod_or_fast!(6, 1); + // 2 eras for unbonding (12 hours). + pub const BondingDuration: sp_staking::EraIndex = 2; + // 1 era in which slashes can be cancelled (6 hours). + pub const SlashDeferDuration: sp_staking::EraIndex = 1; + pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; + pub const MaxNominatorRewardedPerValidator: u32 = 64; + pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17); + pub const MaxNominations: u32 = ::LIMIT as u32; +} + +impl pallet_staking::Config for Runtime { + type Currency = Balances; + type CurrencyBalance = Balance; + type UnixTime = Timestamp; + type CurrencyToVote = CurrencyToVote; + type RewardRemainder = (); + type RuntimeEvent = RuntimeEvent; + type Slash = (); + type Reward = (); + type SessionsPerEra = SessionsPerEra; + type BondingDuration = BondingDuration; + type SlashDeferDuration = SlashDeferDuration; + type AdminOrigin = EnsureRoot; + type SessionInterface = Self; + type EraPayout = pallet_staking::ConvertCurve; + type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; + type OffendingValidatorsThreshold = OffendingValidatorsThreshold; + type NextNewSession = Session; + type ElectionProvider = ElectionProviderMultiPhase; + type GenesisElectionProvider = onchain::OnChainExecution; + type VoterList = VoterList; + type TargetList = UseValidatorsMap; + type NominationsQuota = pallet_staking::FixedNominationsQuota<{ MaxNominations::get() }>; + type MaxUnlockingChunks = frame_support::traits::ConstU32<32>; + type HistoryDepth = frame_support::traits::ConstU32<84>; + type BenchmarkingConfig = runtime_common::StakingBenchmarkingConfig; + type EventListeners = NominationPools; + type WeightInfo = weights::pallet_staking::WeightInfo; +} + +impl pallet_fast_unstake::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BatchSize = frame_support::traits::ConstU32<64>; + type Deposit = frame_support::traits::ConstU128<{ UNITS }>; + type ControlOrigin = EnsureRoot; + type Staking = Staking; + type MaxErasToCheckPerBlock = ConstU32<1>; + #[cfg(feature = "runtime-benchmarks")] + type MaxBackersPerValidator = MaxNominatorRewardedPerValidator; + type WeightInfo = weights::pallet_fast_unstake::WeightInfo; +} + +parameter_types! { + pub const MaxAuthorities: u32 = 100_000; +} + +impl pallet_offences::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type IdentificationTuple = pallet_session::historical::IdentificationTuple; + type OnOffenceHandler = Staking; +} + +impl pallet_authority_discovery::Config for Runtime { + type MaxAuthorities = MaxAuthorities; +} + +parameter_types! { + pub const NposSolutionPriority: TransactionPriority = TransactionPriority::max_value() / 2; + pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); + pub const MaxKeys: u32 = 10_000; + pub const MaxPeerInHeartbeats: u32 = 10_000; +} + +impl pallet_im_online::Config for Runtime { + type AuthorityId = ImOnlineId; + type RuntimeEvent = RuntimeEvent; + type ValidatorSet = Historical; + type NextSessionRotation = Babe; + type ReportUnresponsiveness = Offences; + type UnsignedPriority = ImOnlineUnsignedPriority; + type WeightInfo = weights::pallet_im_online::WeightInfo; + type MaxKeys = MaxKeys; + type MaxPeerInHeartbeats = MaxPeerInHeartbeats; +} + +parameter_types! { + pub const MaxSetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); +} + +impl pallet_grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + + type WeightInfo = (); + type MaxAuthorities = MaxAuthorities; + type MaxNominators = MaxNominatorRewardedPerValidator; + type MaxSetIdSessionEntries = MaxSetIdSessionEntries; + + type KeyOwnerProof = >::Proof; + + type EquivocationReportSystem = + pallet_grandpa::EquivocationReportSystem; +} + +/// Submits a transaction with the node's public and signature type. Adheres to the signed extension +/// format of the chain. +impl frame_system::offchain::CreateSignedTransaction for Runtime +where + RuntimeCall: From, +{ + fn create_transaction>( + call: RuntimeCall, + public: ::Signer, + account: AccountId, + nonce: ::Nonce, + ) -> Option<(RuntimeCall, ::SignaturePayload)> { + use sp_runtime::traits::StaticLookup; + // take the biggest period possible. + let period = + BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; + + let current_block = System::block_number() + .saturated_into::() + // The `System::block_number` is initialized with `n+1`, + // so the actual block number is `n`. + .saturating_sub(1); + let tip = 0; + let extra: SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(generic::Era::mortal( + period, + current_block, + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + ); + let raw_payload = SignedPayload::new(call, extra) + .map_err(|e| { + log::warn!("Unable to create signed payload: {:?}", e); + }) + .ok()?; + let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; + let (call, extra, _) = raw_payload.deconstruct(); + let address = ::Lookup::unlookup(account); + Some((call, (address, signature, extra))) + } +} + +impl frame_system::offchain::SigningTypes for Runtime { + type Public = ::Signer; + type Signature = Signature; +} + +impl frame_system::offchain::SendTransactionTypes for Runtime +where + RuntimeCall: From, +{ + type OverarchingCall = RuntimeCall; + type Extrinsic = UncheckedExtrinsic; +} + +parameter_types! { + // Minimum 100 bytes/KSM deposited (1 CENT/byte) + pub const BasicDeposit: Balance = 1000 * CENTS; // 258 bytes on-chain + pub const FieldDeposit: Balance = 250 * CENTS; // 66 bytes on-chain + pub const SubAccountDeposit: Balance = 200 * CENTS; // 53 bytes on-chain + pub const MaxSubAccounts: u32 = 100; + pub const MaxAdditionalFields: u32 = 100; + pub const MaxRegistrars: u32 = 20; +} + +impl pallet_identity::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Slashed = (); + type BasicDeposit = BasicDeposit; + type FieldDeposit = FieldDeposit; + type SubAccountDeposit = SubAccountDeposit; + type MaxSubAccounts = MaxSubAccounts; + type MaxAdditionalFields = MaxAdditionalFields; + type MaxRegistrars = MaxRegistrars; + type RegistrarOrigin = frame_system::EnsureRoot; + type ForceOrigin = frame_system::EnsureRoot; + type WeightInfo = weights::pallet_identity::WeightInfo; +} + +impl pallet_utility::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type PalletsOrigin = OriginCaller; + type WeightInfo = weights::pallet_utility::WeightInfo; +} + +parameter_types! { + // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. + pub const DepositBase: Balance = deposit(1, 88); + // Additional storage item size of 32 bytes. + pub const DepositFactor: Balance = deposit(0, 32); + pub const MaxSignatories: u32 = 100; +} + +impl pallet_multisig::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type DepositBase = DepositBase; + type DepositFactor = DepositFactor; + type MaxSignatories = MaxSignatories; + type WeightInfo = weights::pallet_multisig::WeightInfo; +} + +parameter_types! { + pub const ConfigDepositBase: Balance = 500 * CENTS; + pub const FriendDepositFactor: Balance = 50 * CENTS; + pub const MaxFriends: u16 = 9; + pub const RecoveryDeposit: Balance = 500 * CENTS; +} + +impl pallet_recovery::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type ConfigDepositBase = ConfigDepositBase; + type FriendDepositFactor = FriendDepositFactor; + type MaxFriends = MaxFriends; + type RecoveryDeposit = RecoveryDeposit; +} + +parameter_types! { + pub const MinVestedTransfer: Balance = 100 * CENTS; + pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = + WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); +} + +impl pallet_vesting::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BlockNumberToBalance = ConvertInto; + type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = weights::pallet_vesting::WeightInfo; + type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; + const MAX_VESTING_SCHEDULES: u32 = 28; +} + +impl pallet_sudo::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type WeightInfo = weights::pallet_sudo::WeightInfo; +} + +parameter_types! { + // One storage item; key size 32, value size 8; . + pub const ProxyDepositBase: Balance = deposit(1, 8); + // Additional storage item size of 33 bytes. + pub const ProxyDepositFactor: Balance = deposit(0, 33); + pub const MaxProxies: u16 = 32; + pub const AnnouncementDepositBase: Balance = deposit(1, 8); + pub const AnnouncementDepositFactor: Balance = deposit(0, 66); + pub const MaxPending: u16 = 32; +} + +/// The type used to represent the kinds of proxying allowed. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + RuntimeDebug, + MaxEncodedLen, + TypeInfo, +)] +pub enum ProxyType { + Any, + NonTransfer, + Staking, + SudoBalances, + IdentityJudgement, + CancelProxy, + Auction, + NominationPools, +} +impl Default for ProxyType { + fn default() -> Self { + Self::Any + } +} +impl InstanceFilter for ProxyType { + fn filter(&self, c: &RuntimeCall) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => matches!( + c, + RuntimeCall::System(..) | + RuntimeCall::Babe(..) | + RuntimeCall::Timestamp(..) | + RuntimeCall::Indices(pallet_indices::Call::claim{..}) | + RuntimeCall::Indices(pallet_indices::Call::free{..}) | + RuntimeCall::Indices(pallet_indices::Call::freeze{..}) | + // Specifically omitting Indices `transfer`, `force_transfer` + // Specifically omitting the entire Balances pallet + RuntimeCall::Staking(..) | + RuntimeCall::Session(..) | + RuntimeCall::Grandpa(..) | + RuntimeCall::ImOnline(..) | + RuntimeCall::Utility(..) | + RuntimeCall::Identity(..) | + RuntimeCall::Recovery(pallet_recovery::Call::as_recovered{..}) | + RuntimeCall::Recovery(pallet_recovery::Call::vouch_recovery{..}) | + RuntimeCall::Recovery(pallet_recovery::Call::claim_recovery{..}) | + RuntimeCall::Recovery(pallet_recovery::Call::close_recovery{..}) | + RuntimeCall::Recovery(pallet_recovery::Call::remove_recovery{..}) | + RuntimeCall::Recovery(pallet_recovery::Call::cancel_recovered{..}) | + // Specifically omitting Recovery `create_recovery`, `initiate_recovery` + RuntimeCall::Vesting(pallet_vesting::Call::vest{..}) | + RuntimeCall::Vesting(pallet_vesting::Call::vest_other{..}) | + // Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer` + RuntimeCall::Scheduler(..) | + // Specifically omitting Sudo pallet + RuntimeCall::Proxy(..) | + RuntimeCall::Multisig(..) | + RuntimeCall::Registrar(paras_registrar::Call::register{..}) | + RuntimeCall::Registrar(paras_registrar::Call::deregister{..}) | + // Specifically omitting Registrar `swap` + RuntimeCall::Registrar(paras_registrar::Call::reserve{..}) | + RuntimeCall::Crowdloan(..) | + RuntimeCall::Slots(..) | + RuntimeCall::Auctions(..) | // Specifically omitting the entire XCM Pallet + RuntimeCall::VoterList(..) | + RuntimeCall::NominationPools(..) | + RuntimeCall::FastUnstake(..) + ), + ProxyType::Staking => { + matches!( + c, + RuntimeCall::Staking(..) | + RuntimeCall::Session(..) | RuntimeCall::Utility(..) | + RuntimeCall::FastUnstake(..) | + RuntimeCall::VoterList(..) | + RuntimeCall::NominationPools(..) + ) + }, + ProxyType::NominationPools => { + matches!(c, RuntimeCall::NominationPools(..) | RuntimeCall::Utility(..)) + }, + ProxyType::SudoBalances => match c { + RuntimeCall::Sudo(pallet_sudo::Call::sudo { call: ref x }) => { + matches!(x.as_ref(), &RuntimeCall::Balances(..)) + }, + RuntimeCall::Utility(..) => true, + _ => false, + }, + ProxyType::IdentityJudgement => matches!( + c, + RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. }) | + RuntimeCall::Utility(..) + ), + ProxyType::CancelProxy => { + matches!(c, RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })) + }, + ProxyType::Auction => matches!( + c, + RuntimeCall::Auctions(..) | + RuntimeCall::Crowdloan(..) | + RuntimeCall::Registrar(..) | + RuntimeCall::Slots(..) + ), + } + } + fn is_superset(&self, o: &Self) -> bool { + match (self, o) { + (x, y) if x == y => true, + (ProxyType::Any, _) => true, + (_, ProxyType::Any) => false, + (ProxyType::NonTransfer, _) => true, + _ => false, + } + } +} + +impl pallet_proxy::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type ProxyType = ProxyType; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type MaxProxies = MaxProxies; + type WeightInfo = weights::pallet_proxy::WeightInfo; + type MaxPending = MaxPending; + type CallHasher = BlakeTwo256; + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; +} + +impl parachains_origin::Config for Runtime {} + +impl parachains_configuration::Config for Runtime { + type WeightInfo = weights::runtime_parachains_configuration::WeightInfo; +} + +impl parachains_shared::Config for Runtime {} + +impl parachains_session_info::Config for Runtime { + type ValidatorSet = Historical; +} + +impl parachains_inclusion::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type DisputesHandler = ParasDisputes; + type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints; + type MessageQueue = MessageQueue; + type WeightInfo = weights::runtime_parachains_inclusion::WeightInfo; +} + +parameter_types! { + pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +impl parachains_paras::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::runtime_parachains_paras::WeightInfo; + type UnsignedPriority = ParasUnsignedPriority; + type QueueFootprinter = ParaInclusion; + type NextSessionRotation = Babe; +} + +parameter_types! { + /// Amount of weight that can be spent per block to service messages. + /// + /// # WARNING + /// + /// This is not a good value for para-chains since the `Scheduler` already uses up to 80% block weight. + pub MessageQueueServiceWeight: Weight = Perbill::from_percent(20) * BlockWeights::get().max_block; + pub const MessageQueueHeapSize: u32 = 128 * 1024; + pub const MessageQueueMaxStale: u32 = 48; +} + +/// Message processor to handle any messages that were enqueued into the `MessageQueue` pallet. +pub struct MessageProcessor; +impl ProcessMessage for MessageProcessor { + type Origin = AggregateMessageOrigin; + + fn process_message( + message: &[u8], + origin: Self::Origin, + meter: &mut WeightMeter, + id: &mut [u8; 32], + ) -> Result { + let para = match origin { + AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para, + }; + xcm_builder::ProcessXcmMessage::< + Junction, + xcm_executor::XcmExecutor, + RuntimeCall, + >::process_message(message, Junction::Parachain(para.into()), meter, id) + } +} + +impl pallet_message_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Size = u32; + type HeapSize = MessageQueueHeapSize; + type MaxStale = MessageQueueMaxStale; + type ServiceWeight = MessageQueueServiceWeight; + #[cfg(not(feature = "runtime-benchmarks"))] + type MessageProcessor = MessageProcessor; + #[cfg(feature = "runtime-benchmarks")] + type MessageProcessor = + pallet_message_queue::mock_helpers::NoopMessageProcessor; + type QueueChangeHandler = ParaInclusion; + type QueuePausedQuery = (); + type WeightInfo = weights::pallet_message_queue::WeightInfo; +} + +impl parachains_dmp::Config for Runtime {} + +impl parachains_hrmp::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type ChannelManager = EnsureRoot; + type Currency = Balances; + type WeightInfo = weights::runtime_parachains_hrmp::WeightInfo; +} + +impl parachains_paras_inherent::Config for Runtime { + type WeightInfo = weights::runtime_parachains_paras_inherent::WeightInfo; +} + +impl parachains_scheduler::Config for Runtime { + type AssignmentProvider = ParaAssignmentProvider; +} + +impl parachains_assigner_parachains::Config for Runtime {} + +impl parachains_initializer::Config for Runtime { + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type ForceOrigin = EnsureRoot; + type WeightInfo = weights::runtime_parachains_initializer::WeightInfo; +} + +impl paras_sudo_wrapper::Config for Runtime {} + +parameter_types! { + pub const PermanentSlotLeasePeriodLength: u32 = 26; + pub const TemporarySlotLeasePeriodLength: u32 = 1; + pub const MaxTemporarySlotPerLeasePeriod: u32 = 5; +} + +impl assigned_slots::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type AssignSlotOrigin = EnsureRoot; + type Leaser = Slots; + type PermanentSlotLeasePeriodLength = PermanentSlotLeasePeriodLength; + type TemporarySlotLeasePeriodLength = TemporarySlotLeasePeriodLength; + type MaxTemporarySlotPerLeasePeriod = MaxTemporarySlotPerLeasePeriod; + type WeightInfo = weights::runtime_common_assigned_slots::WeightInfo; +} + +impl parachains_disputes::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints; + type SlashingHandler = parachains_slashing::SlashValidatorsForDisputes; + type WeightInfo = weights::runtime_parachains_disputes::WeightInfo; +} + +impl parachains_slashing::Config for Runtime { + type KeyOwnerProofSystem = Historical; + type KeyOwnerProof = + >::Proof; + type KeyOwnerIdentification = >::IdentificationTuple; + type HandleReports = parachains_slashing::SlashingReportHandler< + Self::KeyOwnerIdentification, + Offences, + ReportLongevity, + >; + type WeightInfo = weights::runtime_parachains_disputes_slashing::WeightInfo; + type BenchmarkingConfig = parachains_slashing::BenchConfig<300>; +} + +parameter_types! { + pub const ParaDeposit: Balance = 2000 * CENTS; + pub const DataDepositPerByte: Balance = deposit(0, 1); +} + +impl paras_registrar::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type OnSwap = (Crowdloan, Slots); + type ParaDeposit = ParaDeposit; + type DataDepositPerByte = DataDepositPerByte; + type WeightInfo = weights::runtime_common_paras_registrar::WeightInfo; +} + +parameter_types! { + pub const LeasePeriod: BlockNumber = 28 * DAYS; +} + +impl slots::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Registrar = Registrar; + type LeasePeriod = LeasePeriod; + type LeaseOffset = (); + type ForceOrigin = EnsureRoot; + type WeightInfo = weights::runtime_common_slots::WeightInfo; +} + +parameter_types! { + pub const CrowdloanId: PalletId = PalletId(*b"py/cfund"); + pub const SubmissionDeposit: Balance = 100 * 100 * CENTS; + pub const MinContribution: Balance = 100 * CENTS; + pub const RemoveKeysLimit: u32 = 500; + // Allow 32 bytes for an additional memo to a crowdloan. + pub const MaxMemoLength: u8 = 32; +} + +impl crowdloan::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type PalletId = CrowdloanId; + type SubmissionDeposit = SubmissionDeposit; + type MinContribution = MinContribution; + type RemoveKeysLimit = RemoveKeysLimit; + type Registrar = Registrar; + type Auctioneer = Auctions; + type MaxMemoLength = MaxMemoLength; + type WeightInfo = weights::runtime_common_crowdloan::WeightInfo; +} + +parameter_types! { + // The average auction is 7 days long, so this will be 70% for ending period. + // 5 Days = 72000 Blocks @ 6 sec per block + pub const EndingPeriod: BlockNumber = 5 * DAYS; + // ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples + pub const SampleLength: BlockNumber = 2 * MINUTES; +} + +impl auctions::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Leaser = Slots; + type Registrar = Registrar; + type EndingPeriod = EndingPeriod; + type SampleLength = SampleLength; + type Randomness = pallet_babe::RandomnessFromOneEpochAgo; + type InitiateOrigin = EnsureRoot; + type WeightInfo = weights::runtime_common_auctions::WeightInfo; +} + +parameter_types! { + pub const PoolsPalletId: PalletId = PalletId(*b"py/nopls"); + pub const MaxPointsToBalance: u8 = 10; +} + +impl pallet_nomination_pools::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_nomination_pools::WeightInfo; + type Currency = Balances; + type RewardCounter = FixedU128; + type BalanceToU256 = BalanceToU256; + type U256ToBalance = U256ToBalance; + type Staking = Staking; + type PostUnbondingPoolsWindow = ConstU32<4>; + type MaxMetadataLen = ConstU32<256>; + // we use the same number of allowed unlocking chunks as with staking. + type MaxUnbonding = ::MaxUnlockingChunks; + type PalletId = PoolsPalletId; + type MaxPointsToBalance = MaxPointsToBalance; +} + +parameter_types! { + // The deposit configuration for the singed migration. Specially if you want to allow any signed account to do the migration (see `SignedFilter`, these deposits should be high) + pub const MigrationSignedDepositPerItem: Balance = 1 * CENTS; + pub const MigrationSignedDepositBase: Balance = 20 * CENTS * 100; + pub const MigrationMaxKeyLen: u32 = 512; +} + +construct_runtime! { + pub enum Runtime + { + // Basic stuff; balances is uncallable initially. + System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, + + // Babe must be before session. + Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned} = 1, + + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, + Indices: pallet_indices::{Pallet, Call, Storage, Config, Event} = 3, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 4, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 26, + + // Consensus support. + // Authorship must be before session in order to note author in the correct session and era + // for im-online and staking. + Authorship: pallet_authorship::{Pallet, Storage} = 5, + Staking: pallet_staking::{Pallet, Call, Storage, Config, Event} = 6, + Offences: pallet_offences::{Pallet, Storage, Event} = 7, + Historical: session_historical::{Pallet} = 27, + + // BEEFY Bridges support. + Beefy: pallet_beefy::{Pallet, Call, Storage, Config, ValidateUnsigned} = 200, + // MMR leaf construction must be before session in order to have leaf contents + // refer to block consistently. see substrate issue #11797 for details. + Mmr: pallet_mmr::{Pallet, Storage} = 201, + BeefyMmrLeaf: pallet_beefy_mmr::{Pallet, Storage} = 202, + + Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 8, + Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned} = 10, + ImOnline: pallet_im_online::{Pallet, Call, Storage, Event, ValidateUnsigned, Config} = 11, + AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config} = 12, + + // Utility module. + Utility: pallet_utility::{Pallet, Call, Event} = 16, + + // Less simple identity module. + Identity: pallet_identity::{Pallet, Call, Storage, Event} = 17, + + // Social recovery module. + Recovery: pallet_recovery::{Pallet, Call, Storage, Event} = 18, + + // Vesting. Usable initially, but removed once all vesting is finished. + Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config} = 19, + + // System scheduler. + Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 20, + + // Preimage registrar. + Preimage: pallet_preimage::{Pallet, Call, Storage, Event} = 28, + + // Sudo. + Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 21, + + // Proxy module. Late addition. + Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 22, + + // Multisig module. Late addition. + Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 23, + + // Election pallet. Only works with staking, but placed here to maintain indices. + ElectionProviderMultiPhase: pallet_election_provider_multi_phase::{Pallet, Call, Storage, Event, ValidateUnsigned} = 24, + + // Provides a semi-sorted list of nominators for staking. + VoterList: pallet_bags_list::::{Pallet, Call, Storage, Event} = 25, + + // Nomination pools for staking. + NominationPools: pallet_nomination_pools::{Pallet, Call, Storage, Event, Config} = 29, + + // Fast unstake pallet: extension to staking. + FastUnstake: pallet_fast_unstake = 30, + + // Parachains pallets. Start indices at 40 to leave room. + ParachainsOrigin: parachains_origin::{Pallet, Origin} = 41, + Configuration: parachains_configuration::{Pallet, Call, Storage, Config} = 42, + ParasShared: parachains_shared::{Pallet, Call, Storage} = 43, + ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event} = 44, + ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent} = 45, + ParaScheduler: parachains_scheduler::{Pallet, Storage} = 46, + Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 47, + Initializer: parachains_initializer::{Pallet, Call, Storage} = 48, + Dmp: parachains_dmp::{Pallet, Storage} = 49, + // RIP Ump 50 + Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 51, + ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 52, + ParasDisputes: parachains_disputes::{Pallet, Call, Storage, Event} = 53, + ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned} = 54, + ParaAssignmentProvider: parachains_assigner_parachains::{Pallet, Storage} = 55, + + // Parachain Onboarding Pallets. Start indices at 60 to leave room. + Registrar: paras_registrar::{Pallet, Call, Storage, Event, Config} = 60, + Slots: slots::{Pallet, Call, Storage, Event} = 61, + ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call} = 62, + Auctions: auctions::{Pallet, Call, Storage, Event} = 63, + Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 64, + AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event, Config} = 65, + + // Pallet for sending XCM. + XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 99, + + // Generalized message queue + MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 100, + } +} + +/// The address format for describing accounts. +pub type Address = sp_runtime::MultiAddress; +/// Block header type as expected by this runtime. +pub type Header = generic::Header; +/// Block type as expected by this runtime. +pub type Block = generic::Block; +/// A Block signed with a Justification +pub type SignedBlock = generic::SignedBlock; +/// `BlockId` type as expected by this runtime. +pub type BlockId = generic::BlockId; +/// The `SignedExtension` to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckMortality, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); + +pub struct NominationPoolsMigrationV4OldPallet; +impl Get for NominationPoolsMigrationV4OldPallet { + fn get() -> Perbill { + Perbill::from_percent(100) + } +} + +/// All migrations that will run on the next runtime upgrade. +/// +/// This contains the combined migrations of the last 10 releases. It allows to skip runtime +/// upgrades in case governance decides to do so. THE ORDER IS IMPORTANT. +pub type Migrations = migrations::Unreleased; + +/// The runtime migrations per release. +#[allow(deprecated, missing_docs)] +pub mod migrations { + use super::*; + + /// Upgrade Session keys to include BEEFY key. + /// When this is removed, should also remove `OldSessionKeys`. + pub struct UpgradeSessionKeys; + impl frame_support::traits::OnRuntimeUpgrade for UpgradeSessionKeys { + fn on_runtime_upgrade() -> Weight { + Session::upgrade_keys::(transform_session_keys); + Perbill::from_percent(50) * BlockWeights::get().max_block + } + } + + /// Unreleased migrations. Add new ones here: + pub type Unreleased = ( + pallet_im_online::migration::v1::Migration, + parachains_configuration::migration::v7::MigrateToV7, + assigned_slots::migration::v1::VersionCheckedMigrateToV1, + parachains_scheduler::migration::v1::MigrateToV1, + parachains_configuration::migration::v8::MigrateToV8, + UpgradeSessionKeys, + ); +} + +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + generic::UncheckedExtrinsic; +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, + Migrations, +>; +/// The payload being signed in transactions. +pub type SignedPayload = generic::SignedPayload; + +#[cfg(feature = "runtime-benchmarks")] +mod benches { + frame_benchmarking::define_benchmarks!( + // Polkadot + // NOTE: Make sure to prefix these with `runtime_common::` so + // the that path resolves correctly in the generated file. + [runtime_common::assigned_slots, AssignedSlots] + [runtime_common::auctions, Auctions] + [runtime_common::crowdloan, Crowdloan] + [runtime_common::paras_registrar, Registrar] + [runtime_common::slots, Slots] + [runtime_parachains::configuration, Configuration] + [runtime_parachains::disputes, ParasDisputes] + [runtime_parachains::disputes::slashing, ParasSlashing] + [runtime_parachains::hrmp, Hrmp] + [runtime_parachains::inclusion, ParaInclusion] + [runtime_parachains::initializer, Initializer] + [runtime_parachains::paras, Paras] + [runtime_parachains::paras_inherent, ParaInherent] + // Substrate + [pallet_bags_list, VoterList] + [pallet_balances, Balances] + [pallet_election_provider_multi_phase, ElectionProviderMultiPhase] + [frame_election_provider_support, ElectionProviderBench::] + [pallet_fast_unstake, FastUnstake] + [pallet_identity, Identity] + [pallet_im_online, ImOnline] + [pallet_indices, Indices] + [pallet_message_queue, MessageQueue] + [pallet_multisig, Multisig] + [pallet_nomination_pools, NominationPoolsBench::] + [pallet_offences, OffencesBench::] + [pallet_preimage, Preimage] + [pallet_proxy, Proxy] + [pallet_recovery, Recovery] + [pallet_scheduler, Scheduler] + [pallet_session, SessionBench::] + [pallet_staking, Staking] + [pallet_sudo, Sudo] + [frame_system, SystemBench::] + [pallet_timestamp, Timestamp] + [pallet_utility, Utility] + [pallet_vesting, Vesting] + // XCM + [pallet_xcm, XcmPallet] + // NOTE: Make sure you point to the individual modules below. + [pallet_xcm_benchmarks::fungible, XcmBalances] + [pallet_xcm_benchmarks::generic, XcmGeneric] + ); +} + +#[cfg(not(feature = "disable-runtime-api"))] +sp_api::impl_runtime_apis! { + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block); + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } + } + + impl block_builder_api::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: inherents::InherentData, + ) -> inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl tx_pool_api::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl offchain_primitives::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl primitives::runtime_api::ParachainHost for Runtime { + fn validators() -> Vec { + parachains_runtime_api_impl::validators::() + } + + fn validator_groups() -> (Vec>, GroupRotationInfo) { + parachains_runtime_api_impl::validator_groups::() + } + + fn availability_cores() -> Vec> { + parachains_runtime_api_impl::availability_cores::() + } + + fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option> { + parachains_runtime_api_impl::persisted_validation_data::(para_id, assumption) + } + + fn assumed_validation_data( + para_id: ParaId, + expected_persisted_validation_data_hash: Hash, + ) -> Option<(PersistedValidationData, ValidationCodeHash)> { + parachains_runtime_api_impl::assumed_validation_data::( + para_id, + expected_persisted_validation_data_hash, + ) + } + + fn check_validation_outputs( + para_id: ParaId, + outputs: primitives::CandidateCommitments, + ) -> bool { + parachains_runtime_api_impl::check_validation_outputs::(para_id, outputs) + } + + fn session_index_for_child() -> SessionIndex { + parachains_runtime_api_impl::session_index_for_child::() + } + + fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option { + parachains_runtime_api_impl::validation_code::(para_id, assumption) + } + + fn candidate_pending_availability(para_id: ParaId) -> Option> { + parachains_runtime_api_impl::candidate_pending_availability::(para_id) + } + + fn candidate_events() -> Vec> { + parachains_runtime_api_impl::candidate_events::(|ev| { + match ev { + RuntimeEvent::ParaInclusion(ev) => { + Some(ev) + } + _ => None, + } + }) + } + + fn session_info(index: SessionIndex) -> Option { + parachains_runtime_api_impl::session_info::(index) + } + + fn session_executor_params(session_index: SessionIndex) -> Option { + parachains_runtime_api_impl::session_executor_params::(session_index) + } + + fn dmq_contents(recipient: ParaId) -> Vec> { + parachains_runtime_api_impl::dmq_contents::(recipient) + } + + fn inbound_hrmp_channels_contents( + recipient: ParaId + ) -> BTreeMap>> { + parachains_runtime_api_impl::inbound_hrmp_channels_contents::(recipient) + } + + fn validation_code_by_hash(hash: ValidationCodeHash) -> Option { + parachains_runtime_api_impl::validation_code_by_hash::(hash) + } + + fn on_chain_votes() -> Option> { + parachains_runtime_api_impl::on_chain_votes::() + } + + fn submit_pvf_check_statement( + stmt: PvfCheckStatement, + signature: ValidatorSignature, + ) { + parachains_runtime_api_impl::submit_pvf_check_statement::(stmt, signature) + } + + fn pvfs_require_precheck() -> Vec { + parachains_runtime_api_impl::pvfs_require_precheck::() + } + + fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption) + -> Option + { + parachains_runtime_api_impl::validation_code_hash::(para_id, assumption) + } + + fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState)> { + parachains_runtime_api_impl::get_session_disputes::() + } + + fn unapplied_slashes( + ) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> { + parachains_runtime_api_impl::unapplied_slashes::() + } + + fn key_ownership_proof( + validator_id: ValidatorId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((PARACHAIN_KEY_TYPE_ID, validator_id)) + .map(|p| p.encode()) + .map(slashing::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_dispute_lost( + dispute_proof: slashing::DisputeProof, + key_ownership_proof: slashing::OpaqueKeyOwnershipProof, + ) -> Option<()> { + parachains_runtime_api_impl::submit_unsigned_slashing_report::( + dispute_proof, + key_ownership_proof, + ) + } + } + + impl beefy_primitives::BeefyApi for Runtime { + fn beefy_genesis() -> Option { + Beefy::genesis_block() + } + + fn validator_set() -> Option> { + Beefy::validator_set() + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: beefy_primitives::EquivocationProof< + BlockNumber, + BeefyId, + BeefySignature, + >, + key_owner_proof: beefy_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Beefy::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + + fn generate_key_ownership_proof( + _set_id: beefy_primitives::ValidatorSetId, + authority_id: BeefyId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((beefy_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(beefy_primitives::OpaqueKeyOwnershipProof::new) + } + } + + impl mmr::MmrApi for Runtime { + fn mmr_root() -> Result { + Ok(Mmr::mmr_root()) + } + + fn mmr_leaf_count() -> Result { + Ok(Mmr::mmr_leaves()) + } + + fn generate_proof( + block_numbers: Vec, + best_known_block_number: Option, + ) -> Result<(Vec, mmr::Proof), mmr::Error> { + Mmr::generate_proof(block_numbers, best_known_block_number).map( + |(leaves, proof)| { + ( + leaves + .into_iter() + .map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf)) + .collect(), + proof, + ) + }, + ) + } + + fn verify_proof(leaves: Vec, proof: mmr::Proof) + -> Result<(), mmr::Error> + { + let leaves = leaves.into_iter().map(|leaf| + leaf.into_opaque_leaf() + .try_decode() + .ok_or(mmr::Error::Verify)).collect::, mmr::Error>>()?; + Mmr::verify_leaves(leaves, proof) + } + + fn verify_proof_stateless( + root: mmr::Hash, + leaves: Vec, + proof: mmr::Proof + ) -> Result<(), mmr::Error> { + let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect(); + pallet_mmr::verify_leaves_proof::(root, nodes, proof) + } + } + + impl pallet_beefy_mmr::BeefyMmrApi for RuntimeApi { + fn authority_set_proof() -> beefy_primitives::mmr::BeefyAuthoritySet { + BeefyMmrLeaf::authority_set_proof() + } + + fn next_authority_set_proof() -> beefy_primitives::mmr::BeefyNextAuthoritySet { + BeefyMmrLeaf::next_authority_set_proof() + } + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> Vec<(GrandpaId, u64)> { + Grandpa::grandpa_authorities() + } + + fn current_set_id() -> fg_primitives::SetId { + Grandpa::current_set_id() + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: fg_primitives::EquivocationProof< + ::Hash, + sp_runtime::traits::NumberFor, + >, + key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Grandpa::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + + fn generate_key_ownership_proof( + _set_id: fg_primitives::SetId, + authority_id: fg_primitives::AuthorityId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((fg_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(fg_primitives::OpaqueKeyOwnershipProof::new) + } + } + + impl babe_primitives::BabeApi for Runtime { + fn configuration() -> babe_primitives::BabeConfiguration { + let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG); + babe_primitives::BabeConfiguration { + slot_duration: Babe::slot_duration(), + epoch_length: EpochDuration::get(), + c: epoch_config.c, + authorities: Babe::authorities().to_vec(), + randomness: Babe::randomness(), + allowed_slots: epoch_config.allowed_slots, + } + } + + fn current_epoch_start() -> babe_primitives::Slot { + Babe::current_epoch_start() + } + + fn current_epoch() -> babe_primitives::Epoch { + Babe::current_epoch() + } + + fn next_epoch() -> babe_primitives::Epoch { + Babe::next_epoch() + } + + fn generate_key_ownership_proof( + _slot: babe_primitives::Slot, + authority_id: babe_primitives::AuthorityId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((babe_primitives::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(babe_primitives::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: babe_primitives::EquivocationProof<::Header>, + key_owner_proof: babe_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Babe::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + } + + impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + parachains_runtime_api_impl::relevant_authority_ids::() + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Nonce { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< + Block, + Balance, + > for Runtime { + fn query_info(uxt: ::Extrinsic, len: u32) -> RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details(uxt: ::Extrinsic, len: u32) -> FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi + for Runtime + { + fn query_call_info(call: RuntimeCall, len: u32) -> RuntimeDispatchInfo { + TransactionPayment::query_call_info(call, len) + } + fn query_call_fee_details(call: RuntimeCall, len: u32) -> FeeDetails { + TransactionPayment::query_call_fee_details(call, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl pallet_nomination_pools_runtime_api::NominationPoolsApi< + Block, + AccountId, + Balance, + > for Runtime { + fn pending_rewards(member: AccountId) -> Balance { + NominationPools::api_pending_rewards(member).unwrap_or_default() + } + + fn points_to_balance(pool_id: pallet_nomination_pools::PoolId, points: Balance) -> Balance { + NominationPools::api_points_to_balance(pool_id, points) + } + + fn balance_to_points(pool_id: pallet_nomination_pools::PoolId, new_funds: Balance) -> Balance { + NominationPools::api_balance_to_points(pool_id, new_funds) + } + } + + impl pallet_staking_runtime_api::StakingApi for Runtime { + fn nominations_quota(balance: Balance) -> u32 { + Staking::api_nominations_quota(balance) + } + } + + #[cfg(feature = "try-runtime")] + impl frame_try_runtime::TryRuntime for Runtime { + fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { + log::info!("try-runtime::on_runtime_upgrade westend."); + let weight = Executive::try_runtime_upgrade(checks).unwrap(); + (weight, BlockWeights::get().max_block) + } + + fn execute_block( + block: Block, + state_root_check: bool, + signature_check: bool, + select: frame_try_runtime::TryStateSelect, + ) -> Weight { + // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to + // have a backtrace here. + Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap() + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + + use pallet_session_benchmarking::Pallet as SessionBench; + use pallet_offences_benchmarking::Pallet as OffencesBench; + use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench; + use frame_system_benchmarking::Pallet as SystemBench; + use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; + + type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; + type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::; + + let mut list = Vec::::new(); + list_benchmarks!(list, extra); + + let storage_info = AllPalletsWithSystem::storage_info(); + return (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig, + ) -> Result< + Vec, + sp_runtime::RuntimeString, + > { + use frame_support::traits::WhitelistedStorageKeys; + use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError}; + use sp_storage::TrackedStorageKey; + // Trying to add benchmarks directly to some pallets caused cyclic dependency issues. + // To get around that, we separated the benchmarks into its own crate. + use pallet_session_benchmarking::Pallet as SessionBench; + use pallet_offences_benchmarking::Pallet as OffencesBench; + use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench; + use frame_system_benchmarking::Pallet as SystemBench; + use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; + + impl pallet_session_benchmarking::Config for Runtime {} + impl pallet_offences_benchmarking::Config for Runtime {} + impl pallet_election_provider_support_benchmarking::Config for Runtime {} + impl frame_system_benchmarking::Config for Runtime {} + impl pallet_nomination_pools_benchmarking::Config for Runtime {} + impl runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {} + + use xcm::latest::{ + AssetId::*, Fungibility::*, InteriorMultiLocation, Junction, Junctions::*, + MultiAsset, MultiAssets, MultiLocation, NetworkId, Response, + }; + use xcm_config::{Westmint, TokenLocation}; + + impl pallet_xcm_benchmarks::Config for Runtime { + type XcmConfig = xcm_config::XcmConfig; + type AccountIdConverter = xcm_config::LocationConverter; + fn valid_destination() -> Result { + Ok(Westmint::get()) + } + fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + // Westend only knows about WND. + vec![MultiAsset{ + id: Concrete(TokenLocation::get()), + fun: Fungible(1_000_000 * UNITS), + }].into() + } + } + + parameter_types! { + pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + Westmint::get(), + MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, + )); + pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + } + + impl pallet_xcm_benchmarks::fungible::Config for Runtime { + type TransactAsset = Balances; + + type CheckedAccount = xcm_config::LocalCheckAccount; + type TrustedTeleporter = TrustedTeleporter; + type TrustedReserve = TrustedReserve; + + fn get_multi_asset() -> MultiAsset { + MultiAsset { + id: Concrete(TokenLocation::get()), + fun: Fungible(1 * UNITS), + } + } + } + + impl pallet_xcm_benchmarks::generic::Config for Runtime { + type RuntimeCall = RuntimeCall; + + fn worst_case_response() -> (u64, Response) { + (0u64, Response::Version(Default::default())) + } + + fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + // Westend doesn't support asset exchanges + Err(BenchmarkError::Skip) + } + + fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + // The XCM executor of Westend doesn't have a configured `UniversalAliases` + Err(BenchmarkError::Skip) + } + + fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + Ok((Westmint::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) + } + + fn subscribe_origin() -> Result { + Ok(Westmint::get()) + } + + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + let origin = Westmint::get(); + let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = MultiLocation { parents: 0, interior: Here }; + Ok((origin, ticket, assets)) + } + + fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + // Westend doesn't support asset locking + Err(BenchmarkError::Skip) + } + + fn export_message_origin_and_destination( + ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + // Westend doesn't support exporting messages + Err(BenchmarkError::Skip) + } + + fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + // The XCM executor of Westend doesn't have a configured `Aliasers` + Err(BenchmarkError::Skip) + } + } + + type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; + type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::; + + let whitelist: Vec = AllPalletsWithSystem::whitelisted_storage_keys(); + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + + add_benchmarks!(params, batches); + + Ok(batches) + } + } +} + +#[cfg(all(test, feature = "try-runtime"))] +mod remote_tests { + use super::*; + use frame_try_runtime::{runtime_decl_for_try_runtime::TryRuntime, UpgradeCheckSelect}; + use remote_externalities::{ + Builder, Mode, OfflineConfig, OnlineConfig, SnapshotConfig, Transport, + }; + use std::env::var; + + #[tokio::test] + async fn run_migrations() { + if var("RUN_MIGRATION_TESTS").is_err() { + return + } + + sp_tracing::try_init_simple(); + let transport: Transport = + var("WS").unwrap_or("wss://westend-rpc.polkadot.io:443".to_string()).into(); + let maybe_state_snapshot: Option = var("SNAP").map(|s| s.into()).ok(); + let mut ext = Builder::::default() + .mode(if let Some(state_snapshot) = maybe_state_snapshot { + Mode::OfflineOrElseOnline( + OfflineConfig { state_snapshot: state_snapshot.clone() }, + OnlineConfig { + transport, + state_snapshot: Some(state_snapshot), + ..Default::default() + }, + ) + } else { + Mode::Online(OnlineConfig { transport, ..Default::default() }) + }) + .build() + .await + .unwrap(); + ext.execute_with(|| Runtime::on_runtime_upgrade(UpgradeCheckSelect::PreAndPost)); + } +} + +mod clean_state_migration { + use super::Runtime; + use frame_support::{pallet_prelude::*, storage_alias, traits::OnRuntimeUpgrade}; + use pallet_state_trie_migration::MigrationLimits; + + #[cfg(not(feature = "std"))] + use sp_std::prelude::*; + + #[storage_alias] + type AutoLimits = StorageValue, ValueQuery>; + + // Actual type of value is `MigrationTask`, putting a dummy + // one to avoid the trait constraint on T. + // Since we only use `kill` it is fine. + #[storage_alias] + type MigrationProcess = StorageValue; + + #[storage_alias] + type SignedMigrationMaxLimits = StorageValue; + + /// Initialize an automatic migration process. + pub struct CleanMigrate; + + impl OnRuntimeUpgrade for CleanMigrate { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + Ok(Default::default()) + } + + fn on_runtime_upgrade() -> frame_support::weights::Weight { + MigrationProcess::kill(); + AutoLimits::kill(); + SignedMigrationMaxLimits::kill(); + ::DbWeight::get().writes(3) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + frame_support::ensure!( + !AutoLimits::exists() && !SignedMigrationMaxLimits::exists(), + "State migration clean.", + ); + Ok(()) + } + } +} diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..78062662fee04cbc9dfd0d035407c2cc5449dd60 --- /dev/null +++ b/polkadot/runtime/westend/src/tests.rs @@ -0,0 +1,93 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests for the Westend Runtime Configuration + +use std::collections::HashSet; + +use crate::*; +use frame_support::traits::WhitelistedStorageKeys; +use sp_core::hexdisplay::HexDisplay; +use xcm::latest::prelude::*; + +#[test] +fn remove_keys_weight_is_sensible() { + use runtime_common::crowdloan::WeightInfo; + let max_weight = ::WeightInfo::refund(RemoveKeysLimit::get()); + // Max remove keys limit should be no more than half the total block weight. + assert!((max_weight * 2).all_lt(BlockWeights::get().max_block)); +} + +#[test] +fn sample_size_is_sensible() { + use runtime_common::auctions::WeightInfo; + // Need to clean up all samples at the end of an auction. + let samples: BlockNumber = EndingPeriod::get() / SampleLength::get(); + let max_weight: frame_support::weights::Weight = + RocksDbWeight::get().reads_writes(samples.into(), samples.into()); + // Max sample cleanup should be no more than half the total block weight. + assert!((max_weight * 2).all_lt(BlockWeights::get().max_block)); + assert!((::WeightInfo::on_initialize() * 2) + .all_lt(BlockWeights::get().max_block)); +} + +#[test] +fn call_size() { + RuntimeCall::assert_size_under(256); +} + +#[test] +fn sanity_check_teleport_assets_weight() { + // This test sanity checks that at least 50 teleports can exist in a block. + // Usually when XCM runs into an issue, it will return a weight of `Weight::MAX`, + // so this test will certainly ensure that this problem does not occur. + use frame_support::dispatch::GetDispatchInfo; + let weight = pallet_xcm::Call::::teleport_assets { + dest: Box::new(Here.into()), + beneficiary: Box::new(Here.into()), + assets: Box::new((Here, 200_000).into()), + fee_asset_item: 0, + } + .get_dispatch_info() + .weight; + + assert!((weight * 50).all_lt(BlockWeights::get().max_block)); +} + +#[test] +fn check_whitelist() { + let whitelist: HashSet = AllPalletsWithSystem::whitelisted_storage_keys() + .iter() + .map(|e| HexDisplay::from(&e.key).to_string()) + .collect(); + + // Block number + assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac")); + // Total issuance + assert!(whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80")); + // Execution phase + assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a")); + // Event count + assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850")); + // System events + assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7")); + // Configuration ActiveConfig + assert!(whitelist.contains("06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385")); + // XcmPallet VersionDiscoveryQueue + assert!(whitelist.contains("1405f2411d0af5a7ff397e7c9dc68d194a222ba0333561192e474c59ed8e30e1")); + // XcmPallet SafeXcmVersion + assert!(whitelist.contains("1405f2411d0af5a7ff397e7c9dc68d196323ae84c43568be0d1394d5d0d522c4")); +} diff --git a/polkadot/runtime/westend/src/weights/frame_election_provider_support.rs b/polkadot/runtime/westend/src/weights/frame_election_provider_support.rs new file mode 100644 index 0000000000000000000000000000000000000000..8c098f5130acf05eb14ed0911d19bda02159bfda --- /dev/null +++ b/polkadot/runtime/westend/src/weights/frame_election_provider_support.rs @@ -0,0 +1,83 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `frame_election_provider_support` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=frame_election_provider_support +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_election_provider_support`. +pub struct WeightInfo(PhantomData); +impl frame_election_provider_support::WeightInfo for WeightInfo { + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `d` is `[5, 16]`. + fn phragmen(v: u32, _t: u32, d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_980_226_000 picoseconds. + Weight::from_parts(7_460_761_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 175_219 + .saturating_add(Weight::from_parts(7_887_353, 0).saturating_mul(v.into())) + // Standard Error: 17_913_846 + .saturating_add(Weight::from_parts(1_549_115_489, 0).saturating_mul(d.into())) + } + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `d` is `[5, 16]`. + fn phragmms(v: u32, _t: u32, d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_753_214_000 picoseconds. + Weight::from_parts(5_108_654_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 145_622 + .saturating_add(Weight::from_parts(6_118_763, 0).saturating_mul(v.into())) + // Standard Error: 14_887_919 + .saturating_add(Weight::from_parts(1_488_590_343, 0).saturating_mul(d.into())) + } +} diff --git a/polkadot/runtime/westend/src/weights/frame_system.rs b/polkadot/runtime/westend/src/weights/frame_system.rs new file mode 100644 index 0000000000000000000000000000000000000000..deef0959363c6431081ed154980c99f9f9c49e56 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/frame_system.rs @@ -0,0 +1,147 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `frame_system` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=frame_system +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system`. +pub struct WeightInfo(PhantomData); +impl frame_system::WeightInfo for WeightInfo { + /// The range of component `b` is `[0, 3932160]`. + fn remark(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_050_000 picoseconds. + Weight::from_parts(2_094_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(490, 0).saturating_mul(b.into())) + } + /// The range of component `b` is `[0, 3932160]`. + fn remark_with_event(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_620_000 picoseconds. + Weight::from_parts(7_824_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 6 + .saturating_add(Weight::from_parts(2_180, 0).saturating_mul(b.into())) + } + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a686561707061676573` (r:0 w:1) + /// Proof Skipped: unknown `0x3a686561707061676573` (r:0 w:1) + fn set_heap_pages() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1485` + // Minimum execution time: 3_746_000 picoseconds. + Weight::from_parts(4_096_000, 0) + .saturating_add(Weight::from_parts(0, 1485)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a636f6465` (r:0 w:1) + /// Proof Skipped: unknown `0x3a636f6465` (r:0 w:1) + fn set_code() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1485` + // Minimum execution time: 120_822_538_000 picoseconds. + Weight::from_parts(128_806_623_000, 0) + .saturating_add(Weight::from_parts(0, 1485)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 1000]`. + fn set_storage(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_128_000 picoseconds. + Weight::from_parts(2_198_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3_376 + .saturating_add(Weight::from_parts(824_994, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 1000]`. + fn kill_storage(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_110_000 picoseconds. + Weight::from_parts(2_200_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1_859 + .saturating_add(Weight::from_parts(630_789, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `p` is `[0, 1000]`. + fn kill_prefix(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `132 + p * (69 ±0)` + // Estimated: `107 + p * (70 ±0)` + // Minimum execution time: 4_151_000 picoseconds. + Weight::from_parts(4_226_000, 0) + .saturating_add(Weight::from_parts(0, 107)) + // Standard Error: 4_953 + .saturating_add(Weight::from_parts(1_418_957, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) + } +} diff --git a/polkadot/runtime/westend/src/weights/mod.rs b/polkadot/runtime/westend/src/weights/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..531de5527de52deb2d3979658f6a28f5b5194787 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/mod.rs @@ -0,0 +1,53 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! A list of the different weight modules for our runtime. + +pub mod frame_election_provider_support; +pub mod frame_system; +pub mod pallet_bags_list; +pub mod pallet_balances; +pub mod pallet_election_provider_multi_phase; +pub mod pallet_fast_unstake; +pub mod pallet_identity; +pub mod pallet_im_online; +pub mod pallet_indices; +pub mod pallet_message_queue; +pub mod pallet_multisig; +pub mod pallet_nomination_pools; +pub mod pallet_preimage; +pub mod pallet_proxy; +pub mod pallet_scheduler; +pub mod pallet_session; +pub mod pallet_staking; +pub mod pallet_sudo; +pub mod pallet_timestamp; +pub mod pallet_utility; +pub mod pallet_vesting; +pub mod pallet_xcm; +pub mod runtime_common_assigned_slots; +pub mod runtime_common_auctions; +pub mod runtime_common_crowdloan; +pub mod runtime_common_paras_registrar; +pub mod runtime_common_slots; +pub mod runtime_parachains_configuration; +pub mod runtime_parachains_disputes; +pub mod runtime_parachains_disputes_slashing; +pub mod runtime_parachains_hrmp; +pub mod runtime_parachains_inclusion; +pub mod runtime_parachains_initializer; +pub mod runtime_parachains_paras; +pub mod runtime_parachains_paras_inherent; +pub mod xcm; diff --git a/polkadot/runtime/westend/src/weights/pallet_bags_list.rs b/polkadot/runtime/westend/src/weights/pallet_bags_list.rs new file mode 100644 index 0000000000000000000000000000000000000000..53e4857bd287ebe28ab52e250a489f6370000a50 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_bags_list.rs @@ -0,0 +1,109 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_bags_list` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_bags_list +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bags_list`. +pub struct WeightInfo(PhantomData); +impl pallet_bags_list::WeightInfo for WeightInfo { + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:4 w:4) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn rebag_non_terminal() -> Weight { + // Proof Size summary in bytes: + // Measured: `1656` + // Estimated: `11506` + // Minimum execution time: 60_240_000 picoseconds. + Weight::from_parts(62_834_000, 0) + .saturating_add(Weight::from_parts(0, 11506)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn rebag_terminal() -> Weight { + // Proof Size summary in bytes: + // Measured: `1550` + // Estimated: `8877` + // Minimum execution time: 59_084_000 picoseconds. + Weight::from_parts(60_589_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: VoterList ListNodes (r:4 w:4) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:2 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:2 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn put_in_front_of() -> Weight { + // Proof Size summary in bytes: + // Measured: `1861` + // Estimated: `11506` + // Minimum execution time: 65_945_000 picoseconds. + Weight::from_parts(67_429_000, 0) + .saturating_add(Weight::from_parts(0, 11506)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(6)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_balances.rs b/polkadot/runtime/westend/src/weights/pallet_balances.rs new file mode 100644 index 0000000000000000000000000000000000000000..4508507206c27ae10137194d62d1981c6a59b23d --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_balances.rs @@ -0,0 +1,153 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_balances` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_balances +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_balances`. +pub struct WeightInfo(PhantomData); +impl pallet_balances::WeightInfo for WeightInfo { + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_allow_death() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 57_163_000 picoseconds. + Weight::from_parts(58_105_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_keep_alive() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 43_085_000 picoseconds. + Weight::from_parts(43_779_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_set_balance_creating() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 16_153_000 picoseconds. + Weight::from_parts(16_725_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_set_balance_killing() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 23_335_000 picoseconds. + Weight::from_parts(23_715_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `6196` + // Minimum execution time: 58_776_000 picoseconds. + Weight::from_parts(59_353_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer_all() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 52_826_000 picoseconds. + Weight::from_parts(53_816_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_unreserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 19_400_000 picoseconds. + Weight::from_parts(19_746_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:999 w:999) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `u` is `[1, 1000]`. + fn upgrade_accounts(u: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + u * (135 ±0)` + // Estimated: `990 + u * (2603 ±0)` + // Minimum execution time: 18_465_000 picoseconds. + Weight::from_parts(18_670_000, 0) + .saturating_add(Weight::from_parts(0, 990)) + // Standard Error: 22_827 + .saturating_add(Weight::from_parts(17_357_501, 0).saturating_mul(u.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_election_provider_multi_phase.rs b/polkadot/runtime/westend/src/weights/pallet_election_provider_multi_phase.rs new file mode 100644 index 0000000000000000000000000000000000000000..cd315cda2a7b0d38ecdac128317ab35db708d014 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_election_provider_multi_phase.rs @@ -0,0 +1,270 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_election_provider_multi_phase` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_election_provider_multi_phase +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_election_provider_multi_phase`. +pub struct WeightInfo(PhantomData); +impl pallet_election_provider_multi_phase::WeightInfo for WeightInfo { + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentPlannedSession (r:1 w:0) + /// Proof: Staking CurrentPlannedSession (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Babe EpochIndex (r:1 w:0) + /// Proof: Babe EpochIndex (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe GenesisSlot (r:1 w:0) + /// Proof: Babe GenesisSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Staking ForceEra (r:1 w:0) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + fn on_initialize_nothing() -> Weight { + // Proof Size summary in bytes: + // Measured: `919` + // Estimated: `3481` + // Minimum execution time: 18_263_000 picoseconds. + Weight::from_parts(19_329_000, 0) + .saturating_add(Weight::from_parts(0, 3481)) + .saturating_add(T::DbWeight::get().reads(8)) + } + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + fn on_initialize_open_signed() -> Weight { + // Proof Size summary in bytes: + // Measured: `6` + // Estimated: `1491` + // Minimum execution time: 9_839_000 picoseconds. + Weight::from_parts(10_245_000, 0) + .saturating_add(Weight::from_parts(0, 1491)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + fn on_initialize_open_unsigned() -> Weight { + // Proof Size summary in bytes: + // Measured: `6` + // Estimated: `1491` + // Minimum execution time: 10_981_000 picoseconds. + Weight::from_parts(11_231_000, 0) + .saturating_add(Weight::from_parts(0, 1491)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + fn finalize_signed_phase_accept_solution() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 31_786_000 picoseconds. + Weight::from_parts(32_205_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn finalize_signed_phase_reject_solution() -> Weight { + // Proof Size summary in bytes: + // Measured: `174` + // Estimated: `3593` + // Minimum execution time: 21_236_000 picoseconds. + Weight::from_parts(21_972_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + fn create_snapshot_internal(v: u32, _t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 633_519_000 picoseconds. + Weight::from_parts(654_417_363, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 25_140 + .saturating_add(Weight::from_parts(454_358, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `a` is `[500, 800]`. + /// The range of component `d` is `[200, 400]`. + fn elect_queued(a: u32, d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `229 + a * (768 ±0) + d * (48 ±0)` + // Estimated: `3781 + a * (768 ±0) + d * (49 ±0)` + // Minimum execution time: 397_371_000 picoseconds. + Weight::from_parts(434_700_000, 0) + .saturating_add(Weight::from_parts(0, 3781)) + // Standard Error: 15_899 + .saturating_add(Weight::from_parts(877_242, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(9)) + .saturating_add(Weight::from_parts(0, 768).saturating_mul(a.into())) + .saturating_add(Weight::from_parts(0, 49).saturating_mul(d.into())) + } + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TransactionPayment NextFeeMultiplier (r:1 w:0) + /// Proof: TransactionPayment NextFeeMultiplier (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) + fn submit() -> Weight { + // Proof Size summary in bytes: + // Measured: `7368` + // Estimated: `8853` + // Minimum execution time: 62_891_000 picoseconds. + Weight::from_parts(68_415_000, 0) + .saturating_add(Weight::from_parts(0, 8853)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `a` is `[500, 800]`. + /// The range of component `d` is `[200, 400]`. + fn submit_unsigned(v: u32, t: u32, a: u32, _d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `110 + t * (32 ±0) + v * (553 ±0)` + // Estimated: `1595 + t * (32 ±0) + v * (553 ±0)` + // Minimum execution time: 6_652_347_000 picoseconds. + Weight::from_parts(7_246_265_000, 0) + .saturating_add(Weight::from_parts(0, 1595)) + // Standard Error: 35_723 + .saturating_add(Weight::from_parts(282_336, 0).saturating_mul(v.into())) + // Standard Error: 105_863 + .saturating_add(Weight::from_parts(6_158_464, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) + .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) + } + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[1000, 2000]`. + /// The range of component `t` is `[500, 1000]`. + /// The range of component `a` is `[500, 800]`. + /// The range of component `d` is `[200, 400]`. + fn feasibility_check(v: u32, t: u32, a: u32, _d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `85 + t * (32 ±0) + v * (553 ±0)` + // Estimated: `1570 + t * (32 ±0) + v * (553 ±0)` + // Minimum execution time: 5_508_561_000 picoseconds. + Weight::from_parts(6_001_538_000, 0) + .saturating_add(Weight::from_parts(0, 1570)) + // Standard Error: 34_050 + .saturating_add(Weight::from_parts(712_513, 0).saturating_mul(v.into())) + // Standard Error: 100_904 + .saturating_add(Weight::from_parts(4_080_970, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) + .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_fast_unstake.rs b/polkadot/runtime/westend/src/weights/pallet_fast_unstake.rs new file mode 100644 index 0000000000000000000000000000000000000000..8c061688fc66b14261fe2fd81ff81ebd395a601b --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_fast_unstake.rs @@ -0,0 +1,203 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_fast_unstake` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_fast_unstake +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_fast_unstake`. +pub struct WeightInfo(PhantomData); +impl pallet_fast_unstake::WeightInfo for WeightInfo { + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:1) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(3087), added: 3582, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:0) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:64 w:0) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Bonded (r:64 w:64) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:64 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:64 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: System Account (r:64 w:64) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:64 w:64) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:64 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:0 w:64) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:64) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 64]`. + fn on_idle_unstake(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1090 + b * (344 ±0)` + // Estimated: `4572 + b * (3774 ±0)` + // Minimum execution time: 88_455_000 picoseconds. + Weight::from_parts(4_625_058, 0) + .saturating_add(Weight::from_parts(0, 4572)) + // Standard Error: 92_258 + .saturating_add(Weight::from_parts(61_451_756, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(b.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(b.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(b.into())) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:1) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(3087), added: 3582, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:0) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStakers (r:257 w:0) + /// Proof Skipped: Staking ErasStakers (max_values: None, max_size: None, mode: Measured) + /// The range of component `v` is `[1, 256]`. + /// The range of component `b` is `[1, 64]`. + fn on_idle_check(v: u32, b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1304 + b * (48 ±0) + v * (2485 ±0)` + // Estimated: `4622 + b * (49 ±0) + v * (4961 ±0)` + // Minimum execution time: 737_381_000 picoseconds. + Weight::from_parts(747_714_000, 0) + .saturating_add(Weight::from_parts(0, 4622)) + // Standard Error: 4_194_752 + .saturating_add(Weight::from_parts(135_818_708, 0).saturating_mul(v.into())) + // Standard Error: 16_783_682 + .saturating_add(Weight::from_parts(525_457_699, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 49).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 4961).saturating_mul(v.into())) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: FastUnstake Queue (r:1 w:1) + /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:0) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(3087), added: 3582, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:1) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn register_fast_unstake() -> Weight { + // Proof Size summary in bytes: + // Measured: `1826` + // Estimated: `4764` + // Minimum execution time: 122_429_000 picoseconds. + Weight::from_parts(125_427_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(15)) + .saturating_add(T::DbWeight::get().writes(9)) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: FastUnstake Queue (r:1 w:1) + /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:0) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(3087), added: 3582, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:1) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn deregister() -> Weight { + // Proof Size summary in bytes: + // Measured: `1118` + // Estimated: `4572` + // Minimum execution time: 43_442_000 picoseconds. + Weight::from_parts(44_728_000, 0) + .saturating_add(Weight::from_parts(0, 4572)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: FastUnstake ErasToCheckPerBlock (r:0 w:1) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn control() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_471_000 picoseconds. + Weight::from_parts(2_667_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_identity.rs b/polkadot/runtime/westend/src/weights/pallet_identity.rs new file mode 100644 index 0000000000000000000000000000000000000000..8c11482ebdc13693d59cd299189b2b18753aeb06 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_identity.rs @@ -0,0 +1,359 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_identity` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_identity +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_identity`. +pub struct WeightInfo(PhantomData); +impl pallet_identity::WeightInfo for WeightInfo { + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn add_registrar(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `32 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 11_550_000 picoseconds. + Weight::from_parts(12_323_322, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_709 + .saturating_add(Weight::from_parts(131_132, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn set_identity(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `442 + r * (5 ±0)` + // Estimated: `11003` + // Minimum execution time: 32_882_000 picoseconds. + Weight::from_parts(30_046_973, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 7_269 + .saturating_add(Weight::from_parts(250_439, 0).saturating_mul(r.into())) + // Standard Error: 1_418 + .saturating_add(Weight::from_parts(483_981, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:100 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn set_subs_new(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `11003 + s * (2589 ±0)` + // Minimum execution time: 9_045_000 picoseconds. + Weight::from_parts(22_036_189, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 4_819 + .saturating_add(Weight::from_parts(3_134_467, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(s.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 2589).saturating_mul(s.into())) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 100]`. + fn set_subs_old(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `194 + p * (32 ±0)` + // Estimated: `11003` + // Minimum execution time: 8_836_000 picoseconds. + Weight::from_parts(23_025_121, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 4_111 + .saturating_add(Weight::from_parts(1_313_487, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + } + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `s` is `[0, 100]`. + /// The range of component `x` is `[0, 100]`. + fn clear_identity(r: u32, s: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 60_177_000 picoseconds. + Weight::from_parts(26_533_717, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 20_957 + .saturating_add(Weight::from_parts(475_120, 0).saturating_mul(r.into())) + // Standard Error: 4_092 + .saturating_add(Weight::from_parts(1_348_869, 0).saturating_mul(s.into())) + // Standard Error: 4_092 + .saturating_add(Weight::from_parts(314_033, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn request_judgement(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `367 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 32_818_000 picoseconds. + Weight::from_parts(32_253_281, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 7_973 + .saturating_add(Weight::from_parts(124_283, 0).saturating_mul(r.into())) + // Standard Error: 1_555 + .saturating_add(Weight::from_parts(512_825, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `x` is `[0, 100]`. + fn cancel_request(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `398 + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 29_931_000 picoseconds. + Weight::from_parts(28_643_196, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 5_154 + .saturating_add(Weight::from_parts(147_560, 0).saturating_mul(r.into())) + // Standard Error: 1_005 + .saturating_add(Weight::from_parts(490_754, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_fee(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_221_000 picoseconds. + Weight::from_parts(7_620_590, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 3_611 + .saturating_add(Weight::from_parts(118_590, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_account_id(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_426_000 picoseconds. + Weight::from_parts(7_928_489, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_447 + .saturating_add(Weight::from_parts(106_416, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + fn set_fields(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `89 + r * (57 ±0)` + // Estimated: `2626` + // Minimum execution time: 7_359_000 picoseconds. + Weight::from_parts(7_803_303, 0) + .saturating_add(Weight::from_parts(0, 2626)) + // Standard Error: 1_272 + .saturating_add(Weight::from_parts(102_561, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 19]`. + /// The range of component `x` is `[0, 100]`. + fn provide_judgement(r: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `445 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 22_742_000 picoseconds. + Weight::from_parts(21_879_281, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 10_027 + .saturating_add(Weight::from_parts(154_816, 0).saturating_mul(r.into())) + // Standard Error: 1_855 + .saturating_add(Weight::from_parts(803_084, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 20]`. + /// The range of component `s` is `[0, 100]`. + /// The range of component `x` is `[0, 100]`. + fn kill_identity(r: u32, s: u32, x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `676 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 64_467_000 picoseconds. + Weight::from_parts(27_806_692, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 22_702 + .saturating_add(Weight::from_parts(666_376, 0).saturating_mul(r.into())) + // Standard Error: 4_433 + .saturating_add(Weight::from_parts(1_396_065, 0).saturating_mul(s.into())) + // Standard Error: 4_433 + .saturating_add(Weight::from_parts(300_762, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 99]`. + fn add_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `475 + s * (36 ±0)` + // Estimated: `11003` + // Minimum execution time: 29_629_000 picoseconds. + Weight::from_parts(33_761_925, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 2_047 + .saturating_add(Weight::from_parts(132_184, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 100]`. + fn rename_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `591 + s * (3 ±0)` + // Estimated: `11003` + // Minimum execution time: 13_204_000 picoseconds. + Weight::from_parts(14_376_165, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_699 + .saturating_add(Weight::from_parts(45_951, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 100]`. + fn remove_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `638 + s * (35 ±0)` + // Estimated: `11003` + // Minimum execution time: 33_254_000 picoseconds. + Weight::from_parts(35_772_961, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_649 + .saturating_add(Weight::from_parts(116_697, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 99]`. + fn quit_sub(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `704 + s * (37 ±0)` + // Estimated: `6723` + // Minimum execution time: 24_613_000 picoseconds. + Weight::from_parts(26_548_039, 0) + .saturating_add(Weight::from_parts(0, 6723)) + // Standard Error: 1_602 + .saturating_add(Weight::from_parts(112_354, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_im_online.rs b/polkadot/runtime/westend/src/weights/pallet_im_online.rs new file mode 100644 index 0000000000000000000000000000000000000000..a83cd43804dfdc1ca8827a1988221dd0c6f4ee4d --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_im_online.rs @@ -0,0 +1,77 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_im_online` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-30, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `build-host`, CPU: `AMD EPYC 7601 32-Core Processor` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_im_online +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_im_online`. +pub struct WeightInfo(PhantomData); +impl pallet_im_online::WeightInfo for WeightInfo { + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session CurrentIndex (r:1 w:0) + /// Proof Skipped: Session CurrentIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ImOnline Keys (r:1 w:0) + /// Proof: ImOnline Keys (max_values: Some(1), max_size: Some(320002), added: 320497, mode: MaxEncodedLen) + /// Storage: ImOnline ReceivedHeartbeats (r:1 w:1) + /// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(1028), added: 3503, mode: MaxEncodedLen) + /// Storage: ImOnline AuthoredBlocks (r:1 w:0) + /// Proof: ImOnline AuthoredBlocks (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// The range of component `k` is `[1, 1000]`. + fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `361 + k * (32 ±0)` + // Estimated: `321487 + k * (1761 ±0)` + // Minimum execution time: 122_571_000 picoseconds. + Weight::from_parts(162_954_849, 0) + .saturating_add(Weight::from_parts(0, 321487)) + // Standard Error: 8_676 + .saturating_add(Weight::from_parts(11_122, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 1761).saturating_mul(k.into())) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_indices.rs b/polkadot/runtime/westend/src/weights/pallet_indices.rs new file mode 100644 index 0000000000000000000000000000000000000000..42316cd90780173f47a9eb4071bdedf6f3e54492 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_indices.rs @@ -0,0 +1,117 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_indices` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_indices +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_indices`. +pub struct WeightInfo(PhantomData); +impl pallet_indices::WeightInfo for WeightInfo { + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn claim() -> Weight { + // Proof Size summary in bytes: + // Measured: `142` + // Estimated: `3534` + // Minimum execution time: 24_553_000 picoseconds. + Weight::from_parts(25_288_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `341` + // Estimated: `3593` + // Minimum execution time: 35_932_000 picoseconds. + Weight::from_parts(36_801_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn free() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3534` + // Minimum execution time: 25_574_000 picoseconds. + Weight::from_parts(26_123_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `341` + // Estimated: `3593` + // Minimum execution time: 27_605_000 picoseconds. + Weight::from_parts(28_569_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + fn freeze() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3534` + // Minimum execution time: 27_447_000 picoseconds. + Weight::from_parts(28_136_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_message_queue.rs b/polkadot/runtime/westend/src/weights/pallet_message_queue.rs new file mode 100644 index 0000000000000000000000000000000000000000..17eff948781980cfa722718f1feae8eadc341ae2 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_message_queue.rs @@ -0,0 +1,193 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_message_queue` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_message_queue +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_message_queue`. +pub struct WeightInfo(PhantomData); +impl pallet_message_queue::WeightInfo for WeightInfo { + /// Storage: MessageQueue ServiceHead (r:1 w:0) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn ready_ring_knit() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `6050` + // Minimum execution time: 12_154_000 picoseconds. + Weight::from_parts(12_559_000, 0) + .saturating_add(Weight::from_parts(0, 6050)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + fn ready_ring_unknit() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `6050` + // Minimum execution time: 11_166_000 picoseconds. + Weight::from_parts(11_526_000, 0) + .saturating_add(Weight::from_parts(0, 6050)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn service_queue_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `42` + // Estimated: `3520` + // Minimum execution time: 4_160_000 picoseconds. + Weight::from_parts(4_445_000, 0) + .saturating_add(Weight::from_parts(0, 3520)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(131122), added: 133597, mode: MaxEncodedLen) + fn service_page_base_completion() -> Weight { + // Proof Size summary in bytes: + // Measured: `115` + // Estimated: `134587` + // Minimum execution time: 5_872_000 picoseconds. + Weight::from_parts(6_105_000, 0) + .saturating_add(Weight::from_parts(0, 134587)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(131122), added: 133597, mode: MaxEncodedLen) + fn service_page_base_no_completion() -> Weight { + // Proof Size summary in bytes: + // Measured: `115` + // Estimated: `134587` + // Minimum execution time: 6_145_000 picoseconds. + Weight::from_parts(6_522_000, 0) + .saturating_add(Weight::from_parts(0, 134587)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_page_item() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 173_117_000 picoseconds. + Weight::from_parts(175_271_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + fn bump_service_head() -> Weight { + // Proof Size summary in bytes: + // Measured: `149` + // Estimated: `3520` + // Minimum execution time: 6_429_000 picoseconds. + Weight::from_parts(6_743_000, 0) + .saturating_add(Weight::from_parts(0, 3520)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(131122), added: 133597, mode: MaxEncodedLen) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn reap_page() -> Weight { + // Proof Size summary in bytes: + // Measured: `131252` + // Estimated: `134587` + // Minimum execution time: 97_068_000 picoseconds. + Weight::from_parts(100_467_000, 0) + .saturating_add(Weight::from_parts(0, 134587)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(131122), added: 133597, mode: MaxEncodedLen) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn execute_overweight_page_removed() -> Weight { + // Proof Size summary in bytes: + // Measured: `131252` + // Estimated: `134587` + // Minimum execution time: 126_674_000 picoseconds. + Weight::from_parts(134_114_000, 0) + .saturating_add(Weight::from_parts(0, 134587)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(131122), added: 133597, mode: MaxEncodedLen) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + fn execute_overweight_page_updated() -> Weight { + // Proof Size summary in bytes: + // Measured: `131252` + // Estimated: `134587` + // Minimum execution time: 204_926_000 picoseconds. + Weight::from_parts(221_900_000, 0) + .saturating_add(Weight::from_parts(0, 134587)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_multisig.rs b/polkadot/runtime/westend/src/weights/pallet_multisig.rs new file mode 100644 index 0000000000000000000000000000000000000000..616aea9c8e73f0bf078de9d5e4cb55d8565b40b9 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_multisig.rs @@ -0,0 +1,165 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_multisig` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_multisig +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_multisig`. +pub struct WeightInfo(PhantomData); +impl pallet_multisig::WeightInfo for WeightInfo { + /// The range of component `z` is `[0, 10000]`. + fn as_multi_threshold_1(z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_218_000 picoseconds. + Weight::from_parts(14_749_472, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 10 + .saturating_add(Weight::from_parts(507, 0).saturating_mul(z.into())) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_create(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `309 + s * (2 ±0)` + // Estimated: `6811` + // Minimum execution time: 45_891_000 picoseconds. + Weight::from_parts(33_546_627, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 2_347 + .saturating_add(Weight::from_parts(136_466, 0).saturating_mul(s.into())) + // Standard Error: 23 + .saturating_add(Weight::from_parts(1_595, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[3, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_approve(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `286` + // Estimated: `6811` + // Minimum execution time: 30_355_000 picoseconds. + Weight::from_parts(19_611_682, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 1_383 + .saturating_add(Weight::from_parts(123_652, 0).saturating_mul(s.into())) + // Standard Error: 13 + .saturating_add(Weight::from_parts(1_488, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + /// The range of component `z` is `[0, 10000]`. + fn as_multi_complete(s: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `392 + s * (33 ±0)` + // Estimated: `6811` + // Minimum execution time: 50_453_000 picoseconds. + Weight::from_parts(35_628_285, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 3_693 + .saturating_add(Weight::from_parts(203_453, 0).saturating_mul(s.into())) + // Standard Error: 36 + .saturating_add(Weight::from_parts(1_726, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn approve_as_multi_create(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `314 + s * (2 ±0)` + // Estimated: `6811` + // Minimum execution time: 32_500_000 picoseconds. + Weight::from_parts(33_231_806, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 1_511 + .saturating_add(Weight::from_parts(134_500, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn approve_as_multi_approve(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `286` + // Estimated: `6811` + // Minimum execution time: 17_906_000 picoseconds. + Weight::from_parts(18_757_928, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 1_172 + .saturating_add(Weight::from_parts(113_535, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// The range of component `s` is `[2, 100]`. + fn cancel_as_multi(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `458 + s * (1 ±0)` + // Estimated: `6811` + // Minimum execution time: 33_018_000 picoseconds. + Weight::from_parts(34_186_533, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 1_188 + .saturating_add(Weight::from_parts(128_449, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_nomination_pools.rs b/polkadot/runtime/westend/src/weights/pallet_nomination_pools.rs new file mode 100644 index 0000000000000000000000000000000000000000..9d43eb2498927cac586eb56c4247d262adee27b0 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_nomination_pools.rs @@ -0,0 +1,601 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_nomination_pools` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_nomination_pools +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_nomination_pools`. +pub struct WeightInfo(PhantomData); +impl pallet_nomination_pools::WeightInfo for WeightInfo { + /// Storage: NominationPools MinJoinBond (r:1 w:0) + /// Proof: NominationPools MinJoinBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembersPerPool (r:1 w:0) + /// Proof: NominationPools MaxPoolMembersPerPool (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembers (r:1 w:0) + /// Proof: NominationPools MaxPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn join() -> Weight { + // Proof Size summary in bytes: + // Measured: `3281` + // Estimated: `8877` + // Minimum execution time: 196_298_000 picoseconds. + Weight::from_parts(202_857_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(19)) + .saturating_add(T::DbWeight::get().writes(12)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn bond_extra_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `3291` + // Estimated: `8877` + // Minimum execution time: 191_639_000 picoseconds. + Weight::from_parts(197_000_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(12)) + } + /// Storage: NominationPools ClaimPermissions (r:1 w:0) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn bond_extra_other() -> Weight { + // Proof Size summary in bytes: + // Measured: `3186` + // Estimated: `8799` + // Minimum execution time: 224_836_000 picoseconds. + Weight::from_parts(230_990_000, 0) + .saturating_add(Weight::from_parts(0, 8799)) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(12)) + } + /// Storage: NominationPools ClaimPermissions (r:1 w:0) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn claim_payout() -> Weight { + // Proof Size summary in bytes: + // Measured: `1137` + // Estimated: `4182` + // Minimum execution time: 79_609_000 picoseconds. + Weight::from_parts(81_434_000, 0) + .saturating_add(Weight::from_parts(0, 4182)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: NominationPools SubPoolsStorage (r:1 w:1) + /// Proof: NominationPools SubPoolsStorage (max_values: None, max_size: Some(261), added: 2736, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForSubPoolsStorage (r:1 w:1) + /// Proof: NominationPools CounterForSubPoolsStorage (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn unbond() -> Weight { + // Proof Size summary in bytes: + // Measured: `3560` + // Estimated: `8877` + // Minimum execution time: 175_473_000 picoseconds. + Weight::from_parts(179_976_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(20)) + .saturating_add(T::DbWeight::get().writes(13)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn pool_withdraw_unbonded(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1614` + // Estimated: `4764` + // Minimum execution time: 63_011_000 picoseconds. + Weight::from_parts(65_966_680, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_422 + .saturating_add(Weight::from_parts(58_078, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools SubPoolsStorage (r:1 w:1) + /// Proof: NominationPools SubPoolsStorage (max_values: None, max_size: Some(261), added: 2736, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools ClaimPermissions (r:0 w:1) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_update(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2042` + // Estimated: `4764` + // Minimum execution time: 134_765_000 picoseconds. + Weight::from_parts(140_539_571, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 4_169 + .saturating_add(Weight::from_parts(61_448, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools SubPoolsStorage (r:1 w:1) + /// Proof: NominationPools SubPoolsStorage (max_values: None, max_size: Some(261), added: 2736, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:0) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools ReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools ReversePoolIdLookup (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools CounterForReversePoolIdLookup (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForRewardPools (r:1 w:1) + /// Proof: NominationPools CounterForRewardPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForSubPoolsStorage (r:1 w:1) + /// Proof: NominationPools CounterForSubPoolsStorage (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools Metadata (r:1 w:1) + /// Proof: NominationPools Metadata (max_values: None, max_size: Some(270), added: 2745, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForBondedPools (r:1 w:1) + /// Proof: NominationPools CounterForBondedPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: NominationPools ClaimPermissions (r:0 w:1) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_kill(_s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2398` + // Estimated: `6196` + // Minimum execution time: 226_632_000 picoseconds. + Weight::from_parts(234_263_474, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(21)) + .saturating_add(T::DbWeight::get().writes(18)) + } + /// Storage: NominationPools LastPoolId (r:1 w:1) + /// Proof: NominationPools LastPoolId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MinCreateBond (r:1 w:0) + /// Proof: NominationPools MinCreateBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MinJoinBond (r:1 w:0) + /// Proof: NominationPools MinJoinBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPools (r:1 w:0) + /// Proof: NominationPools MaxPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForBondedPools (r:1 w:1) + /// Proof: NominationPools CounterForBondedPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools PoolMembers (r:1 w:1) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembersPerPool (r:1 w:0) + /// Proof: NominationPools MaxPoolMembersPerPool (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembers (r:1 w:0) + /// Proof: NominationPools MaxPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForPoolMembers (r:1 w:1) + /// Proof: NominationPools CounterForPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForRewardPools (r:1 w:1) + /// Proof: NominationPools CounterForRewardPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools ReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools ReversePoolIdLookup (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForReversePoolIdLookup (r:1 w:1) + /// Proof: NominationPools CounterForReversePoolIdLookup (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + fn create() -> Weight { + // Proof Size summary in bytes: + // Measured: `1222` + // Estimated: `6196` + // Minimum execution time: 197_132_000 picoseconds. + Weight::from_parts(202_099_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(22)) + .saturating_add(T::DbWeight::get().writes(15)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:1 w:0) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:17 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 16]`. + fn nominate(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1779` + // Estimated: `4556 + n * (2520 ±0)` + // Minimum execution time: 68_142_000 picoseconds. + Weight::from_parts(68_977_842, 0) + .saturating_add(Weight::from_parts(0, 4556)) + // Standard Error: 10_560 + .saturating_add(Weight::from_parts(1_606_142, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(Weight::from_parts(0, 2520).saturating_mul(n.into())) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + fn set_state() -> Weight { + // Proof Size summary in bytes: + // Measured: `1367` + // Estimated: `4556` + // Minimum execution time: 36_343_000 picoseconds. + Weight::from_parts(37_669_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools Metadata (r:1 w:1) + /// Proof: NominationPools Metadata (max_values: None, max_size: Some(270), added: 2745, mode: MaxEncodedLen) + /// Storage: NominationPools CounterForMetadata (r:1 w:1) + /// Proof: NominationPools CounterForMetadata (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 256]`. + fn set_metadata(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `497` + // Estimated: `3735` + // Minimum execution time: 14_157_000 picoseconds. + Weight::from_parts(15_201_514, 0) + .saturating_add(Weight::from_parts(0, 3735)) + // Standard Error: 194 + .saturating_add(Weight::from_parts(718, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: NominationPools MinJoinBond (r:0 w:1) + /// Proof: NominationPools MinJoinBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembers (r:0 w:1) + /// Proof: NominationPools MaxPoolMembers (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPoolMembersPerPool (r:0 w:1) + /// Proof: NominationPools MaxPoolMembersPerPool (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MinCreateBond (r:0 w:1) + /// Proof: NominationPools MinCreateBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:0 w:1) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: NominationPools MaxPools (r:0 w:1) + /// Proof: NominationPools MaxPools (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn set_configs() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_082_000 picoseconds. + Weight::from_parts(6_275_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + fn update_roles() -> Weight { + // Proof Size summary in bytes: + // Measured: `497` + // Estimated: `3685` + // Minimum execution time: 19_952_000 picoseconds. + Weight::from_parts(20_880_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn chill() -> Weight { + // Proof Size summary in bytes: + // Measured: `1942` + // Estimated: `4556` + // Minimum execution time: 66_233_000 picoseconds. + Weight::from_parts(68_181_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn set_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `736` + // Estimated: `3685` + // Minimum execution time: 33_533_000 picoseconds. + Weight::from_parts(34_915_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + fn set_commission_max() -> Weight { + // Proof Size summary in bytes: + // Measured: `537` + // Estimated: `3685` + // Minimum execution time: 18_920_000 picoseconds. + Weight::from_parts(19_410_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:1) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + fn set_commission_change_rate() -> Weight { + // Proof Size summary in bytes: + // Measured: `497` + // Estimated: `3685` + // Minimum execution time: 19_388_000 picoseconds. + Weight::from_parts(20_346_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools PoolMembers (r:1 w:0) + /// Proof: NominationPools PoolMembers (max_values: None, max_size: Some(717), added: 3192, mode: MaxEncodedLen) + /// Storage: NominationPools ClaimPermissions (r:1 w:1) + /// Proof: NominationPools ClaimPermissions (max_values: None, max_size: Some(41), added: 2516, mode: MaxEncodedLen) + fn set_claim_permission() -> Weight { + // Proof Size summary in bytes: + // Measured: `508` + // Estimated: `4182` + // Minimum execution time: 14_137_000 picoseconds. + Weight::from_parts(14_846_000, 0) + .saturating_add(Weight::from_parts(0, 4182)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: NominationPools BondedPools (r:1 w:0) + /// Proof: NominationPools BondedPools (max_values: None, max_size: Some(220), added: 2695, mode: MaxEncodedLen) + /// Storage: NominationPools RewardPools (r:1 w:1) + /// Proof: NominationPools RewardPools (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: NominationPools GlobalMaxCommission (r:1 w:0) + /// Proof: NominationPools GlobalMaxCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn claim_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `934` + // Estimated: `3685` + // Minimum execution time: 66_667_000 picoseconds. + Weight::from_parts(68_573_000, 0) + .saturating_add(Weight::from_parts(0, 3685)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_offences.rs b/polkadot/runtime/westend/src/weights/pallet_offences.rs new file mode 100644 index 0000000000000000000000000000000000000000..2a0039844d4f4acc350ef95a123b69b99b017165 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_offences.rs @@ -0,0 +1,222 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_offences` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_offences +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_offences`. +pub struct WeightInfo(PhantomData); +impl pallet_offences::WeightInfo for WeightInfo { + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:100 w:100) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:100 w:100) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1700 w:1700) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:1700 w:1700) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:100 w:100) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:300 w:300) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:100 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking NominatorSlashInEra (r:1600 w:1600) + /// Proof: Staking NominatorSlashInEra (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// The range of component `r` is `[1, 100]`. + /// The range of component `o` is `[2, 100]`. + /// The range of component `n` is `[0, 16]`. + fn report_offence_im_online(_r: u32, o: u32, n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + n * (3462 ±0) + o * (1042 ±0)` + // Estimated: `88666 + n * (157019 ±38) + o * (26384 ±6)` + // Minimum execution time: 535_077_000 picoseconds. + Weight::from_parts(552_420_000, 0) + .saturating_add(Weight::from_parts(0, 88666)) + // Standard Error: 4_786_756 + .saturating_add(Weight::from_parts(434_857_612, 0).saturating_mul(o.into())) + // Standard Error: 29_086_480 + .saturating_add(Weight::from_parts(365_733_267, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(124)) + .saturating_add(T::DbWeight::get().reads((37_u64).saturating_mul(o.into()))) + .saturating_add(T::DbWeight::get().reads((187_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(117)) + .saturating_add(T::DbWeight::get().writes((36_u64).saturating_mul(o.into()))) + .saturating_add(T::DbWeight::get().writes((187_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 157019).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 26384).saturating_mul(o.into())) + } + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:1 w:1) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:1 w:1) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:17 w:17) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:17 w:17) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking NominatorSlashInEra (r:16 w:16) + /// Proof: Staking NominatorSlashInEra (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// The range of component `n` is `[0, 16]`. + fn report_offence_grandpa(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1763 + n * (65 ±0)` + // Estimated: `8149 + n * (2551 ±0)` + // Minimum execution time: 98_496_000 picoseconds. + Weight::from_parts(103_619_589, 0) + .saturating_add(Weight::from_parts(0, 8149)) + // Standard Error: 46_011 + .saturating_add(Weight::from_parts(12_464_366, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(19)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(13)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2551).saturating_mul(n.into())) + } + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:1 w:1) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:1 w:1) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:17 w:17) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:17 w:17) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking NominatorSlashInEra (r:16 w:16) + /// Proof: Staking NominatorSlashInEra (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// The range of component `n` is `[0, 16]`. + fn report_offence_babe(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1763 + n * (65 ±0)` + // Estimated: `8149 + n * (2551 ±0)` + // Minimum execution time: 98_531_000 picoseconds. + Weight::from_parts(104_912_692, 0) + .saturating_add(Weight::from_parts(0, 8149)) + // Standard Error: 40_911 + .saturating_add(Weight::from_parts(12_219_649, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(19)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(13)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2551).saturating_mul(n.into())) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_preimage.rs b/polkadot/runtime/westend/src/weights/pallet_preimage.rs new file mode 100644 index 0000000000000000000000000000000000000000..39d3626b189f6e9078556cb68d59de9a3aa2d99d --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_preimage.rs @@ -0,0 +1,218 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_preimage` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_preimage +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_preimage`. +pub struct WeightInfo(PhantomData); +impl pallet_preimage::WeightInfo for WeightInfo { + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `181` + // Estimated: `3556` + // Minimum execution time: 30_248_000 picoseconds. + Weight::from_parts(30_746_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 11 + .saturating_add(Weight::from_parts(3_563, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_requested_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 16_748_000 picoseconds. + Weight::from_parts(17_025_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 12 + .saturating_add(Weight::from_parts(3_559, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 4194304]`. + fn note_no_deposit_preimage(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 16_353_000 picoseconds. + Weight::from_parts(16_501_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 11 + .saturating_add(Weight::from_parts(3_615, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unnote_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `327` + // Estimated: `3556` + // Minimum execution time: 52_924_000 picoseconds. + Weight::from_parts(77_162_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unnote_no_deposit_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `182` + // Estimated: `3556` + // Minimum execution time: 33_660_000 picoseconds. + Weight::from_parts(53_453_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `226` + // Estimated: `3556` + // Minimum execution time: 29_363_000 picoseconds. + Weight::from_parts(47_779_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_no_deposit_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `182` + // Estimated: `3556` + // Minimum execution time: 21_614_000 picoseconds. + Weight::from_parts(37_598_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_unnoted_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `3556` + // Minimum execution time: 28_867_000 picoseconds. + Weight::from_parts(41_737_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn request_requested_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 11_595_000 picoseconds. + Weight::from_parts(16_316_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + fn unrequest_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `182` + // Estimated: `3556` + // Minimum execution time: 33_521_000 picoseconds. + Weight::from_parts(50_094_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn unrequest_unnoted_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 11_048_000 picoseconds. + Weight::from_parts(15_393_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + fn unrequest_multi_referenced_preimage() -> Weight { + // Proof Size summary in bytes: + // Measured: `144` + // Estimated: `3556` + // Minimum execution time: 11_983_000 picoseconds. + Weight::from_parts(14_983_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_proxy.rs b/polkadot/runtime/westend/src/weights/pallet_proxy.rs new file mode 100644 index 0000000000000000000000000000000000000000..f5b1d82f4e527c01478df62b888fb0a3f11681d5 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_proxy.rs @@ -0,0 +1,224 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_proxy` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_proxy +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_proxy`. +pub struct WeightInfo(PhantomData); +impl pallet_proxy::WeightInfo for WeightInfo { + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 14_951_000 picoseconds. + Weight::from_parts(15_649_274, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 1_337 + .saturating_add(Weight::from_parts(40_845, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn proxy_announced(a: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `554 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `5698` + // Minimum execution time: 39_918_000 picoseconds. + Weight::from_parts(42_018_315, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 5_101 + .saturating_add(Weight::from_parts(126_969, 0).saturating_mul(a.into())) + // Standard Error: 5_270 + .saturating_add(Weight::from_parts(11_500, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn remove_announcement(a: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + a * (68 ±0)` + // Estimated: `5698` + // Minimum execution time: 24_217_000 picoseconds. + Weight::from_parts(25_376_229, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 1_898 + .saturating_add(Weight::from_parts(161_111, 0).saturating_mul(a.into())) + // Standard Error: 1_961 + .saturating_add(Weight::from_parts(1_782, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn reject_announcement(a: u32, _p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + a * (68 ±0)` + // Estimated: `5698` + // Minimum execution time: 24_271_000 picoseconds. + Weight::from_parts(25_651_673, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 1_978 + .saturating_add(Weight::from_parts(151_891, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `a` is `[0, 31]`. + /// The range of component `p` is `[1, 31]`. + fn announce(a: u32, p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `486 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `5698` + // Minimum execution time: 34_245_000 picoseconds. + Weight::from_parts(37_454_762, 0) + .saturating_add(Weight::from_parts(0, 5698)) + // Standard Error: 4_843 + .saturating_add(Weight::from_parts(143_291, 0).saturating_mul(a.into())) + // Standard Error: 5_003 + .saturating_add(Weight::from_parts(24_694, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn add_proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 25_126_000 picoseconds. + Weight::from_parts(26_203_164, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 3_603 + .saturating_add(Weight::from_parts(71_361, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn remove_proxy(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 25_250_000 picoseconds. + Weight::from_parts(26_297_960, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 2_721 + .saturating_add(Weight::from_parts(75_139, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn remove_proxies(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `227 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 22_452_000 picoseconds. + Weight::from_parts(23_229_684, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 12_315 + .saturating_add(Weight::from_parts(52_592, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[1, 31]`. + fn create_pure(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `239` + // Estimated: `4706` + // Minimum execution time: 26_951_000 picoseconds. + Weight::from_parts(27_827_133, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 4_052 + .saturating_add(Weight::from_parts(23_418, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// The range of component `p` is `[0, 30]`. + fn kill_pure(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `264 + p * (37 ±0)` + // Estimated: `4706` + // Minimum execution time: 23_068_000 picoseconds. + Weight::from_parts(23_856_231, 0) + .saturating_add(Weight::from_parts(0, 4706)) + // Standard Error: 2_855 + .saturating_add(Weight::from_parts(49_524, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_recovery.rs b/polkadot/runtime/westend/src/weights/pallet_recovery.rs new file mode 100644 index 0000000000000000000000000000000000000000..54c5d2dd38337eff87d2ca16a7e31e00e5b8867a --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_recovery.rs @@ -0,0 +1,186 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_recovery` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_recovery +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_recovery`. +pub struct WeightInfo(PhantomData); +impl pallet_recovery::WeightInfo for WeightInfo { + /// Storage: Recovery Proxy (r:1 w:0) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + fn as_recovered() -> Weight { + // Proof Size summary in bytes: + // Measured: `111` + // Estimated: `3545` + // Minimum execution time: 8_588_000 picoseconds. + Weight::from_parts(8_886_000, 0) + .saturating_add(Weight::from_parts(0, 3545)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: Recovery Proxy (r:0 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + fn set_recovered() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_893_000 picoseconds. + Weight::from_parts(9_158_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery Recoverable (r:1 w:1) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 9]`. + fn create_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `6` + // Estimated: `3816` + // Minimum execution time: 24_859_000 picoseconds. + Weight::from_parts(25_746_629, 0) + .saturating_add(Weight::from_parts(0, 3816)) + // Standard Error: 4_934 + .saturating_add(Weight::from_parts(144_496, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + fn initiate_recovery() -> Weight { + // Proof Size summary in bytes: + // Measured: `102` + // Estimated: `3854` + // Minimum execution time: 28_280_000 picoseconds. + Weight::from_parts(29_100_000, 0) + .saturating_add(Weight::from_parts(0, 3854)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 9]`. + fn vouch_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `190 + n * (64 ±0)` + // Estimated: `3854` + // Minimum execution time: 18_189_000 picoseconds. + Weight::from_parts(18_864_727, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 4_843 + .saturating_add(Weight::from_parts(192_783, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:0) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: Recovery Proxy (r:1 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 9]`. + fn claim_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `222 + n * (64 ±0)` + // Estimated: `3854` + // Minimum execution time: 22_925_000 picoseconds. + Weight::from_parts(23_927_125, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 7_089 + .saturating_add(Weight::from_parts(95_688, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 9]`. + fn close_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `341 + n * (32 ±0)` + // Estimated: `3854` + // Minimum execution time: 33_473_000 picoseconds. + Weight::from_parts(34_619_626, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 5_883 + .saturating_add(Weight::from_parts(109_238, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Recovery ActiveRecoveries (r:1 w:0) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: Recovery Recoverable (r:1 w:1) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 9]`. + fn remove_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `223 + n * (32 ±0)` + // Estimated: `3854` + // Minimum execution time: 30_514_000 picoseconds. + Weight::from_parts(31_743_967, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 8_762 + .saturating_add(Weight::from_parts(113_056, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Recovery Proxy (r:1 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + fn cancel_recovered() -> Weight { + // Proof Size summary in bytes: + // Measured: `111` + // Estimated: `3545` + // Minimum execution time: 10_398_000 picoseconds. + Weight::from_parts(10_764_000, 0) + .saturating_add(Weight::from_parts(0, 3545)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_scheduler.rs b/polkadot/runtime/westend/src/weights/pallet_scheduler.rs new file mode 100644 index 0000000000000000000000000000000000000000..7291b98093300ef887d422051dcf6be7274c0d12 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_scheduler.rs @@ -0,0 +1,207 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_scheduler` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_scheduler +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_scheduler`. +pub struct WeightInfo(PhantomData); +impl pallet_scheduler::WeightInfo for WeightInfo { + /// Storage: Scheduler IncompleteSince (r:1 w:1) + /// Proof: Scheduler IncompleteSince (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn service_agendas_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `69` + // Estimated: `1489` + // Minimum execution time: 3_991_000 picoseconds. + Weight::from_parts(4_160_000, 0) + .saturating_add(Weight::from_parts(0, 1489)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 50]`. + fn service_agenda_base(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 3_647_000 picoseconds. + Weight::from_parts(6_608_270, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 2_516 + .saturating_add(Weight::from_parts(892_866, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_task_base() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_552_000 picoseconds. + Weight::from_parts(5_836_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Preimage PreimageFor (r:1 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: Measured) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// The range of component `s` is `[128, 4194304]`. + fn service_task_fetched(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `217 + s * (1 ±0)` + // Estimated: `3682 + s * (1 ±0)` + // Minimum execution time: 20_583_000 picoseconds. + Weight::from_parts(20_771_000, 0) + .saturating_add(Weight::from_parts(0, 3682)) + // Standard Error: 11 + .saturating_add(Weight::from_parts(2_250, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(s.into())) + } + /// Storage: Scheduler Lookup (r:0 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + fn service_task_named() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_271_000 picoseconds. + Weight::from_parts(7_447_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn service_task_periodic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_547_000 picoseconds. + Weight::from_parts(5_776_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn execute_dispatch_signed() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_480_000 picoseconds. + Weight::from_parts(2_628_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn execute_dispatch_unsigned() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_479_000 picoseconds. + Weight::from_parts(2_626_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 49]`. + fn schedule(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 13_350_000 picoseconds. + Weight::from_parts(15_289_847, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 5_375 + .saturating_add(Weight::from_parts(974_567, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: Scheduler Lookup (r:0 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 50]`. + fn cancel(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `116 + s * (177 ±0)` + // Estimated: `42428` + // Minimum execution time: 17_646_000 picoseconds. + Weight::from_parts(15_858_434, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 5_354 + .saturating_add(Weight::from_parts(1_697_642, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 49]`. + fn schedule_named(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `293 + s * (185 ±0)` + // Estimated: `42428` + // Minimum execution time: 16_419_000 picoseconds. + Weight::from_parts(19_868_760, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 6_915 + .saturating_add(Weight::from_parts(1_010_225, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 50]`. + fn cancel_named(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `319 + s * (185 ±0)` + // Estimated: `42428` + // Minimum execution time: 19_574_000 picoseconds. + Weight::from_parts(18_453_197, 0) + .saturating_add(Weight::from_parts(0, 42428)) + // Standard Error: 6_009 + .saturating_add(Weight::from_parts(1_707_130, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_session.rs b/polkadot/runtime/westend/src/weights/pallet_session.rs new file mode 100644 index 0000000000000000000000000000000000000000..7e779039e669fb9ac15cb303aa8e784090b68e5c --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_session.rs @@ -0,0 +1,85 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_session` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_session +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_session`. +pub struct WeightInfo(PhantomData); +impl pallet_session::WeightInfo for WeightInfo { + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Session NextKeys (r:1 w:1) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session KeyOwner (r:6 w:6) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) + fn set_keys() -> Weight { + // Proof Size summary in bytes: + // Measured: `1954` + // Estimated: `17794` + // Minimum execution time: 62_746_000 picoseconds. + Weight::from_parts(70_413_000, 0) + .saturating_add(Weight::from_parts(0, 17794)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Session NextKeys (r:1 w:1) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session KeyOwner (r:0 w:6) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) + fn purge_keys() -> Weight { + // Proof Size summary in bytes: + // Measured: `1818` + // Estimated: `5283` + // Minimum execution time: 42_715_000 picoseconds. + Weight::from_parts(49_740_000, 0) + .saturating_add(Weight::from_parts(0, 5283)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(7)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_staking.rs b/polkadot/runtime/westend/src/weights/pallet_staking.rs new file mode 100644 index 0000000000000000000000000000000000000000..099693d26b505817a390ddb7757a7ea38b75f812 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_staking.rs @@ -0,0 +1,796 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_staking` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_staking +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_staking`. +pub struct WeightInfo(PhantomData); +impl pallet_staking::WeightInfo for WeightInfo { + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + fn bond() -> Weight { + // Proof Size summary in bytes: + // Measured: `1014` + // Estimated: `4764` + // Minimum execution time: 51_108_000 picoseconds. + Weight::from_parts(52_521_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn bond_extra() -> Weight { + // Proof Size summary in bytes: + // Measured: `1959` + // Estimated: `8877` + // Minimum execution time: 96_564_000 picoseconds. + Weight::from_parts(100_133_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + fn unbond() -> Weight { + // Proof Size summary in bytes: + // Measured: `2166` + // Estimated: `8877` + // Minimum execution time: 97_705_000 picoseconds. + Weight::from_parts(102_055_000, 0) + .saturating_add(Weight::from_parts(0, 8877)) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_update(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `981` + // Estimated: `4764` + // Minimum execution time: 45_257_000 picoseconds. + Weight::from_parts(47_309_508, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_343 + .saturating_add(Weight::from_parts(61_484, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Staking SpanSlash (r:0 w:100) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn withdraw_unbonded_kill(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2221 + s * (4 ±0)` + // Estimated: `6248 + s * (4 ±0)` + // Minimum execution time: 94_800_000 picoseconds. + Weight::from_parts(101_763_223, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 6_481 + .saturating_add(Weight::from_parts(1_450_372, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(13)) + .saturating_add(T::DbWeight::get().writes(11)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking MinValidatorBond (r:1 w:0) + /// Proof: Staking MinValidatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking MinCommission (r:1 w:0) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking MaxValidatorsCount (r:1 w:0) + /// Proof: Staking MaxValidatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:1) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn validate() -> Weight { + // Proof Size summary in bytes: + // Measured: `1343` + // Estimated: `4556` + // Minimum execution time: 57_763_000 picoseconds. + Weight::from_parts(59_394_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:128 w:128) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// The range of component `k` is `[1, 128]`. + fn kick(k: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1248 + k * (569 ±0)` + // Estimated: `4556 + k * (3033 ±0)` + // Minimum execution time: 35_501_000 picoseconds. + Weight::from_parts(32_260_525, 0) + .saturating_add(Weight::from_parts(0, 4556)) + // Standard Error: 34_554 + .saturating_add(Weight::from_parts(10_625_386, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) + .saturating_add(Weight::from_parts(0, 3033).saturating_mul(k.into())) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:1 w:0) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:17 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 16]`. + fn nominate(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1839 + n * (102 ±0)` + // Estimated: `6248 + n * (2520 ±0)` + // Minimum execution time: 67_970_000 picoseconds. + Weight::from_parts(65_110_939, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 32_193 + .saturating_add(Weight::from_parts(4_688_614, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(Weight::from_parts(0, 2520).saturating_mul(n.into())) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn chill() -> Weight { + // Proof Size summary in bytes: + // Measured: `1675` + // Estimated: `6248` + // Minimum execution time: 59_515_000 picoseconds. + Weight::from_parts(62_462_000, 0) + .saturating_add(Weight::from_parts(0, 6248)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + fn set_payee() -> Weight { + // Proof Size summary in bytes: + // Measured: `771` + // Estimated: `4556` + // Minimum execution time: 13_943_000 picoseconds. + Weight::from_parts(14_384_000, 0) + .saturating_add(Weight::from_parts(0, 4556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:2 w:2) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + fn set_controller() -> Weight { + // Proof Size summary in bytes: + // Measured: `870` + // Estimated: `8122` + // Minimum execution time: 21_212_000 picoseconds. + Weight::from_parts(22_061_000, 0) + .saturating_add(Weight::from_parts(0, 8122)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Staking ValidatorCount (r:0 w:1) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn set_validator_count() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_977_000 picoseconds. + Weight::from_parts(3_217_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking ForceEra (r:0 w:1) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + fn force_no_eras() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_152_000 picoseconds. + Weight::from_parts(9_949_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking ForceEra (r:0 w:1) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + fn force_new_era() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_509_000 picoseconds. + Weight::from_parts(9_838_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking ForceEra (r:0 w:1) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + fn force_new_era_always() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_480_000 picoseconds. + Weight::from_parts(9_755_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking Invulnerables (r:0 w:1) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `v` is `[0, 1000]`. + fn set_invulnerables(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_140_000 picoseconds. + Weight::from_parts(3_438_665, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 93 + .saturating_add(Weight::from_parts(15_688, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:0 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Staking SpanSlash (r:0 w:100) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// The range of component `s` is `[0, 100]`. + fn force_unstake(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1947 + s * (4 ±0)` + // Estimated: `6248 + s * (4 ±0)` + // Minimum execution time: 86_729_000 picoseconds. + Weight::from_parts(93_633_668, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 6_522 + .saturating_add(Weight::from_parts(1_421_038, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(12)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) + } + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `s` is `[1, 1000]`. + fn cancel_deferred_slash(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `66606` + // Estimated: `70071` + // Minimum execution time: 135_155_000 picoseconds. + Weight::from_parts(960_317_735, 0) + .saturating_add(Weight::from_parts(0, 70071)) + // Standard Error: 59_264 + .saturating_add(Weight::from_parts(4_884_888, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasValidatorReward (r:1 w:0) + /// Proof: Staking ErasValidatorReward (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:65 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking ErasStakersClipped (r:1 w:0) + /// Proof Skipped: Staking ErasStakersClipped (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasRewardPoints (r:1 w:0) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasValidatorPrefs (r:1 w:0) + /// Proof: Staking ErasValidatorPrefs (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:65 w:0) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: System Account (r:65 w:65) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `n` is `[0, 64]`. + fn payout_stakers_dead_controller(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `5773 + n * (151 ±0)` + // Estimated: `8579 + n * (2603 ±0)` + // Minimum execution time: 92_788_000 picoseconds. + Weight::from_parts(129_527_249, 0) + .saturating_add(Weight::from_parts(0, 8579)) + // Standard Error: 73_346 + .saturating_add(Weight::from_parts(33_413_624, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(n.into())) + } + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasValidatorReward (r:1 w:0) + /// Proof: Staking ErasValidatorReward (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:65 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:65 w:65) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking ErasStakersClipped (r:1 w:0) + /// Proof Skipped: Staking ErasStakersClipped (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasRewardPoints (r:1 w:0) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasValidatorPrefs (r:1 w:0) + /// Proof: Staking ErasValidatorPrefs (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:65 w:0) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: System Account (r:65 w:65) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:65 w:65) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:65 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `n` is `[0, 64]`. + fn payout_stakers_alive_staked(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `8056 + n * (396 ±0)` + // Estimated: `10634 + n * (3774 ±0)` + // Minimum execution time: 118_795_000 picoseconds. + Weight::from_parts(181_663_036, 0) + .saturating_add(Weight::from_parts(0, 10634)) + // Standard Error: 132_894 + .saturating_add(Weight::from_parts(51_369_596, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(n.into())) + } + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// The range of component `l` is `[1, 32]`. + fn rebond(l: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1960 + l * (5 ±0)` + // Estimated: `8877` + // Minimum execution time: 88_870_000 picoseconds. + Weight::from_parts(92_783_195, 0) + .saturating_add(Weight::from_parts(0, 8877)) + // Standard Error: 7_412 + .saturating_add(Weight::from_parts(49_785, 0).saturating_mul(l.into())) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Staking Bonded (r:1 w:1) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:1) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Staking SpanSlash (r:0 w:100) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// The range of component `s` is `[1, 100]`. + fn reap_stash(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2221 + s * (4 ±0)` + // Estimated: `6248 + s * (4 ±0)` + // Minimum execution time: 102_112_000 picoseconds. + Weight::from_parts(103_755_459, 0) + .saturating_add(Weight::from_parts(0, 6248)) + // Standard Error: 6_107 + .saturating_add(Weight::from_parts(1_436_139, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(11)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) + } + /// Storage: VoterList CounterForListNodes (r:1 w:0) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:178 w:0) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:110 w:0) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:110 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:11 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:110 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:110 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// Storage: Staking CounterForValidators (r:1 w:0) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinimumValidatorCount (r:1 w:0) + /// Proof: Staking MinimumValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:1) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStakersClipped (r:0 w:10) + /// Proof Skipped: Staking ErasStakersClipped (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasValidatorPrefs (r:0 w:10) + /// Proof: Staking ErasValidatorPrefs (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + /// Storage: Staking ErasStakers (r:0 w:10) + /// Proof Skipped: Staking ErasStakers (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking ErasTotalStake (r:0 w:1) + /// Proof: Staking ErasTotalStake (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:0 w:1) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking MinimumActiveStake (r:0 w:1) + /// Proof: Staking MinimumActiveStake (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// The range of component `v` is `[1, 10]`. + /// The range of component `n` is `[0, 100]`. + fn new_era(v: u32, n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + n * (716 ±0) + v * (3594 ±0)` + // Estimated: `456136 + n * (3566 ±0) + v * (3566 ±0)` + // Minimum execution time: 547_465_000 picoseconds. + Weight::from_parts(557_541_000, 0) + .saturating_add(Weight::from_parts(0, 456136)) + // Standard Error: 2_380_806 + .saturating_add(Weight::from_parts(78_379_807, 0).saturating_mul(v.into())) + // Standard Error: 237_234 + .saturating_add(Weight::from_parts(22_772_283, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(185)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(v.into())) + } + /// Storage: VoterList CounterForListNodes (r:1 w:0) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:178 w:0) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2000 w:0) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:2000 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1000 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:2000 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:2000 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// Storage: Staking MinimumActiveStake (r:0 w:1) + /// Proof: Staking MinimumActiveStake (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// The range of component `v` is `[500, 1000]`. + /// The range of component `n` is `[500, 1000]`. + fn get_npos_voters(v: u32, n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `3151 + n * (907 ±0) + v * (391 ±0)` + // Estimated: `456136 + n * (3566 ±0) + v * (3566 ±0)` + // Minimum execution time: 39_710_080_000 picoseconds. + Weight::from_parts(42_191_823_000, 0) + .saturating_add(Weight::from_parts(0, 456136)) + // Standard Error: 506_609 + .saturating_add(Weight::from_parts(7_688_462, 0).saturating_mul(v.into())) + // Standard Error: 506_609 + .saturating_add(Weight::from_parts(6_303_908, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(180)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(v.into())) + } + /// Storage: Staking CounterForValidators (r:1 w:0) + /// Proof: Staking CounterForValidators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1001 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: System BlockWeight (r:1 w:1) + /// Proof: System BlockWeight (max_values: Some(1), max_size: Some(48), added: 543, mode: MaxEncodedLen) + /// The range of component `v` is `[500, 1000]`. + fn get_npos_targets(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `951 + v * (50 ±0)` + // Estimated: `3510 + v * (2520 ±0)` + // Minimum execution time: 2_603_304_000 picoseconds. + Weight::from_parts(481_860_383, 0) + .saturating_add(Weight::from_parts(0, 3510)) + // Standard Error: 55_189 + .saturating_add(Weight::from_parts(4_786_173, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) + } + /// Storage: Staking MinCommission (r:0 w:1) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinValidatorBond (r:0 w:1) + /// Proof: Staking MinValidatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking MaxValidatorsCount (r:0 w:1) + /// Proof: Staking MaxValidatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ChillThreshold (r:0 w:1) + /// Proof: Staking ChillThreshold (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:0 w:1) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:0 w:1) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + fn set_staking_configs_all_set() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_453_000 picoseconds. + Weight::from_parts(6_857_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking MinCommission (r:0 w:1) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinValidatorBond (r:0 w:1) + /// Proof: Staking MinValidatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking MaxValidatorsCount (r:0 w:1) + /// Proof: Staking MaxValidatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ChillThreshold (r:0 w:1) + /// Proof: Staking ChillThreshold (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:0 w:1) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:0 w:1) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + fn set_staking_configs_all_remove() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_037_000 picoseconds. + Weight::from_parts(6_303_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking ChillThreshold (r:1 w:0) + /// Proof: Staking ChillThreshold (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Staking MaxNominatorsCount (r:1 w:0) + /// Proof: Staking MaxNominatorsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking MinNominatorBond (r:1 w:0) + /// Proof: Staking MinNominatorBond (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:2 w:2) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn chill_other() -> Weight { + // Proof Size summary in bytes: + // Measured: `1798` + // Estimated: `6248` + // Minimum execution time: 72_578_000 picoseconds. + Weight::from_parts(74_232_000, 0) + .saturating_add(Weight::from_parts(0, 6248)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Staking MinCommission (r:1 w:0) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:1) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + fn force_apply_min_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `661` + // Estimated: `3510` + // Minimum execution time: 13_066_000 picoseconds. + Weight::from_parts(13_421_000, 0) + .saturating_add(Weight::from_parts(0, 3510)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Staking MinCommission (r:0 w:1) + /// Proof: Staking MinCommission (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn set_min_commission() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_057_000 picoseconds. + Weight::from_parts(3_488_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_sudo.rs b/polkadot/runtime/westend/src/weights/pallet_sudo.rs new file mode 100644 index 0000000000000000000000000000000000000000..8a220173ee57a45dd122c1aad020151c5bb5f1e6 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_sudo.rs @@ -0,0 +1,87 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_sudo` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_sudo +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_sudo`. +pub struct WeightInfo(PhantomData); +impl pallet_sudo::WeightInfo for WeightInfo { + /// Storage: Sudo Key (r:1 w:1) + /// Proof: Sudo Key (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + fn set_key() -> Weight { + // Proof Size summary in bytes: + // Measured: `132` + // Estimated: `1517` + // Minimum execution time: 12_360_000 picoseconds. + Weight::from_parts(12_803_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Sudo Key (r:1 w:0) + /// Proof: Sudo Key (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + fn sudo() -> Weight { + // Proof Size summary in bytes: + // Measured: `132` + // Estimated: `1517` + // Minimum execution time: 12_158_000 picoseconds. + Weight::from_parts(12_506_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: Sudo Key (r:1 w:0) + /// Proof: Sudo Key (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + fn sudo_as() -> Weight { + // Proof Size summary in bytes: + // Measured: `132` + // Estimated: `1517` + // Minimum execution time: 12_286_000 picoseconds. + Weight::from_parts(12_664_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) + .saturating_add(T::DbWeight::get().reads(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_timestamp.rs b/polkadot/runtime/westend/src/weights/pallet_timestamp.rs new file mode 100644 index 0000000000000000000000000000000000000000..d8fb8c1ed76f64e1904d4aea76d420071a460b3a --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_timestamp.rs @@ -0,0 +1,75 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_timestamp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_timestamp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_timestamp`. +pub struct WeightInfo(PhantomData); +impl pallet_timestamp::WeightInfo for WeightInfo { + /// Storage: Timestamp Now (r:1 w:1) + /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + fn set() -> Weight { + // Proof Size summary in bytes: + // Measured: `311` + // Estimated: `1493` + // Minimum execution time: 9_722_000 picoseconds. + Weight::from_parts(10_041_000, 0) + .saturating_add(Weight::from_parts(0, 1493)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn on_finalize() -> Weight { + // Proof Size summary in bytes: + // Measured: `94` + // Estimated: `0` + // Minimum execution time: 3_834_000 picoseconds. + Weight::from_parts(3_960_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_utility.rs b/polkadot/runtime/westend/src/weights/pallet_utility.rs new file mode 100644 index 0000000000000000000000000000000000000000..f8238e9351dc011ccb42542b4c1cd5df71a74e1a --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_utility.rs @@ -0,0 +1,102 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_utility` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_utility +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_utility`. +pub struct WeightInfo(PhantomData); +impl pallet_utility::WeightInfo for WeightInfo { + /// The range of component `c` is `[0, 1000]`. + fn batch(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_791_000 picoseconds. + Weight::from_parts(7_720_310, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2_420 + .saturating_add(Weight::from_parts(5_114_338, 0).saturating_mul(c.into())) + } + fn as_derivative() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_892_000 picoseconds. + Weight::from_parts(5_122_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `c` is `[0, 1000]`. + fn batch_all(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_816_000 picoseconds. + Weight::from_parts(12_736_198, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2_696 + .saturating_add(Weight::from_parts(5_378_828, 0).saturating_mul(c.into())) + } + fn dispatch_as() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_890_000 picoseconds. + Weight::from_parts(9_286_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// The range of component `c` is `[0, 1000]`. + fn force_batch(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_823_000 picoseconds. + Weight::from_parts(7_235_613, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2_817 + .saturating_add(Weight::from_parts(5_113_539, 0).saturating_mul(c.into())) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_vesting.rs b/polkadot/runtime/westend/src/weights/pallet_vesting.rs new file mode 100644 index 0000000000000000000000000000000000000000..4ccd524ffc28de68a8a19f5e7e78d495f2fa00bd --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_vesting.rs @@ -0,0 +1,241 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_vesting` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_vesting +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_vesting`. +pub struct WeightInfo(PhantomData); +impl pallet_vesting::WeightInfo for WeightInfo { + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `348 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 35_225_000 picoseconds. + Weight::from_parts(34_420_748, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_341 + .saturating_add(Weight::from_parts(41_794, 0).saturating_mul(l.into())) + // Standard Error: 4_166 + .saturating_add(Weight::from_parts(114_507, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `348 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 38_507_000 picoseconds. + Weight::from_parts(38_552_717, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_406 + .saturating_add(Weight::from_parts(42_332, 0).saturating_mul(l.into())) + // Standard Error: 4_282 + .saturating_add(Weight::from_parts(67_638, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_locked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `451 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 36_919_000 picoseconds. + Weight::from_parts(35_087_984, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_435 + .saturating_add(Weight::from_parts(66_131, 0).saturating_mul(l.into())) + // Standard Error: 4_333 + .saturating_add(Weight::from_parts(125_178, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[1, 28]`. + fn vest_other_unlocked(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `451 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 40_393_000 picoseconds. + Weight::from_parts(39_522_987, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_958 + .saturating_add(Weight::from_parts(46_626, 0).saturating_mul(l.into())) + // Standard Error: 3_484 + .saturating_add(Weight::from_parts(94_547, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `522 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 72_925_000 picoseconds. + Weight::from_parts(75_858_529, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 3_995 + .saturating_add(Weight::from_parts(70_032, 0).saturating_mul(l.into())) + // Standard Error: 7_108 + .saturating_add(Weight::from_parts(160_507, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[0, 27]`. + fn force_vested_transfer(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `625 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `6196` + // Minimum execution time: 74_405_000 picoseconds. + Weight::from_parts(78_253_087, 0) + .saturating_add(Weight::from_parts(0, 6196)) + // Standard Error: 3_708 + .saturating_add(Weight::from_parts(56_748, 0).saturating_mul(l.into())) + // Standard Error: 6_598 + .saturating_add(Weight::from_parts(146_713, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn not_unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `449 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 37_715_000 picoseconds. + Weight::from_parts(36_483_330, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_146 + .saturating_add(Weight::from_parts(55_976, 0).saturating_mul(l.into())) + // Standard Error: 3_964 + .saturating_add(Weight::from_parts(116_455, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `449 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 42_102_000 picoseconds. + Weight::from_parts(41_671_515, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 2_743 + .saturating_add(Weight::from_parts(47_496, 0).saturating_mul(l.into())) + // Standard Error: 5_065 + .saturating_add(Weight::from_parts(95_785, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/westend/src/weights/pallet_xcm.rs b/polkadot/runtime/westend/src/weights/pallet_xcm.rs new file mode 100644 index 0000000000000000000000000000000000000000..7f2a1de44e93909a718c83e546024572ac7347dc --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_xcm.rs @@ -0,0 +1,284 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_xcm +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/var/lib/gitlab-runner/builds/zyw4fam_/0/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=westend-dev +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm`. +pub struct WeightInfo(PhantomData); +impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn send() -> Weight { + // Proof Size summary in bytes: + // Measured: `169` + // Estimated: `3634` + // Minimum execution time: 33_628_000 picoseconds. + Weight::from_parts(34_633_000, 0) + .saturating_add(Weight::from_parts(0, 3634)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + fn teleport_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 21_535_000 picoseconds. + Weight::from_parts(21_936_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn reserve_transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 21_576_000 picoseconds. + Weight::from_parts(21_942_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + fn execute() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: XcmPallet SupportedVersion (r:0 w:1) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + fn force_xcm_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_764_000 picoseconds. + Weight::from_parts(9_927_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn force_default_xcm_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_824_000 picoseconds. + Weight::from_parts(2_935_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: XcmPallet VersionNotifiers (r:1 w:1) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet QueryCounter (r:1 w:1) + /// Proof Skipped: XcmPallet QueryCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet Queries (r:0 w:1) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + fn force_subscribe_version_notify() -> Weight { + // Proof Size summary in bytes: + // Measured: `169` + // Estimated: `3634` + // Minimum execution time: 38_436_000 picoseconds. + Weight::from_parts(39_300_000, 0) + .saturating_add(Weight::from_parts(0, 3634)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: XcmPallet VersionNotifiers (r:1 w:1) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet Queries (r:0 w:1) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + fn force_unsubscribe_version_notify() -> Weight { + // Proof Size summary in bytes: + // Measured: `361` + // Estimated: `3826` + // Minimum execution time: 41_600_000 picoseconds. + Weight::from_parts(42_703_000, 0) + .saturating_add(Weight::from_parts(0, 3826)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: XcmPallet XcmExecutionSuspended (r:0 w:1) + /// Proof Skipped: XcmPallet XcmExecutionSuspended (max_values: Some(1), max_size: None, mode: Measured) + fn force_suspension() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_792_000 picoseconds. + Weight::from_parts(2_958_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: XcmPallet SupportedVersion (r:4 w:2) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + fn migrate_supported_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `229` + // Estimated: `11119` + // Minimum execution time: 17_640_000 picoseconds. + Weight::from_parts(18_011_000, 0) + .saturating_add(Weight::from_parts(0, 11119)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifiers (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifiers (max_values: None, max_size: None, mode: Measured) + fn migrate_version_notifiers() -> Weight { + // Proof Size summary in bytes: + // Measured: `233` + // Estimated: `11123` + // Minimum execution time: 17_325_000 picoseconds. + Weight::from_parts(17_896_000, 0) + .saturating_add(Weight::from_parts(0, 11123)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:5 w:0) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn already_notified_target() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `13608` + // Minimum execution time: 19_295_000 picoseconds. + Weight::from_parts(19_840_000, 0) + .saturating_add(Weight::from_parts(0, 13608)) + .saturating_add(T::DbWeight::get().reads(5)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:2 w:1) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn notify_current_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `239` + // Estimated: `6179` + // Minimum execution time: 35_819_000 picoseconds. + Weight::from_parts(36_708_000, 0) + .saturating_add(Weight::from_parts(0, 6179)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:3 w:0) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn notify_target_migration_fail() -> Weight { + // Proof Size summary in bytes: + // Measured: `272` + // Estimated: `8687` + // Minimum execution time: 9_572_000 picoseconds. + Weight::from_parts(9_907_000, 0) + .saturating_add(Weight::from_parts(0, 8687)) + .saturating_add(T::DbWeight::get().reads(3)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + fn migrate_version_notify_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `240` + // Estimated: `11130` + // Minimum execution time: 17_376_000 picoseconds. + Weight::from_parts(17_870_000, 0) + .saturating_add(Weight::from_parts(0, 11130)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:4 w:2) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn migrate_and_notify_old_targets() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `11133` + // Minimum execution time: 43_468_000 picoseconds. + Weight::from_parts(44_327_000, 0) + .saturating_add(Weight::from_parts(0, 11133)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(6)) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_common_assigned_slots.rs b/polkadot/runtime/westend/src/weights/runtime_common_assigned_slots.rs new file mode 100644 index 0000000000000000000000000000000000000000..c3f1060a9ac0bce7f9bcaa36739f1d7199a8d737 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_common_assigned_slots.rs @@ -0,0 +1,151 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::assigned_slots` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-ynta1nyy-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_common::assigned_slots +// --chain=westend-dev +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::assigned_slots`. +pub struct WeightInfo(PhantomData); +impl runtime_common::assigned_slots::WeightInfo for WeightInfo { + /// Storage: `Registrar::Paras` (r:1 w:1) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:1) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AssignedSlots::PermanentSlots` (r:1 w:1) + /// Proof: `AssignedSlots::PermanentSlots` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::TemporarySlots` (r:1 w:0) + /// Proof: `AssignedSlots::TemporarySlots` (`max_values`: None, `max_size`: Some(61), added: 2536, mode: `MaxEncodedLen`) + /// Storage: `Slots::Leases` (r:1 w:1) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AssignedSlots::PermanentSlotCount` (r:1 w:1) + /// Proof: `AssignedSlots::PermanentSlotCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::MaxPermanentSlots` (r:1 w:0) + /// Proof: `AssignedSlots::MaxPermanentSlots` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn assign_perm_parachain_slot() -> Weight { + // Proof Size summary in bytes: + // Measured: `640` + // Estimated: `4105` + // Minimum execution time: 74_788_000 picoseconds. + Weight::from_parts(79_847_000, 0) + .saturating_add(Weight::from_parts(0, 4105)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: `Registrar::Paras` (r:1 w:1) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:1) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AssignedSlots::PermanentSlots` (r:1 w:0) + /// Proof: `AssignedSlots::PermanentSlots` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::TemporarySlots` (r:1 w:1) + /// Proof: `AssignedSlots::TemporarySlots` (`max_values`: None, `max_size`: Some(61), added: 2536, mode: `MaxEncodedLen`) + /// Storage: `Slots::Leases` (r:1 w:1) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AssignedSlots::TemporarySlotCount` (r:1 w:1) + /// Proof: `AssignedSlots::TemporarySlotCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::MaxTemporarySlots` (r:1 w:0) + /// Proof: `AssignedSlots::MaxTemporarySlots` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::ActiveTemporarySlotCount` (r:1 w:1) + /// Proof: `AssignedSlots::ActiveTemporarySlotCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn assign_temp_parachain_slot() -> Weight { + // Proof Size summary in bytes: + // Measured: `640` + // Estimated: `4105` + // Minimum execution time: 73_324_000 picoseconds. + Weight::from_parts(77_993_000, 0) + .saturating_add(Weight::from_parts(0, 4105)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: `AssignedSlots::PermanentSlots` (r:1 w:0) + /// Proof: `AssignedSlots::PermanentSlots` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) + /// Storage: `AssignedSlots::TemporarySlots` (r:1 w:1) + /// Proof: `AssignedSlots::TemporarySlots` (`max_values`: None, `max_size`: Some(61), added: 2536, mode: `MaxEncodedLen`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Slots::Leases` (r:1 w:1) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AssignedSlots::TemporarySlotCount` (r:1 w:1) + /// Proof: `AssignedSlots::TemporarySlotCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn unassign_parachain_slot() -> Weight { + // Proof Size summary in bytes: + // Measured: `592` + // Estimated: `4057` + // Minimum execution time: 32_796_000 picoseconds. + Weight::from_parts(35_365_000, 0) + .saturating_add(Weight::from_parts(0, 4057)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `AssignedSlots::MaxPermanentSlots` (r:0 w:1) + /// Proof: `AssignedSlots::MaxPermanentSlots` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn set_max_permanent_slots() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_104_000 picoseconds. + Weight::from_parts(7_358_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `AssignedSlots::MaxTemporarySlots` (r:0 w:1) + /// Proof: `AssignedSlots::MaxTemporarySlots` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn set_max_temporary_slots() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_097_000 picoseconds. + Weight::from_parts(7_429_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_common_auctions.rs b/polkadot/runtime/westend/src/weights/runtime_common_auctions.rs new file mode 100644 index 0000000000000000000000000000000000000000..a6f5bbe5a1da3054a0ab17c2a8c2db94471d17c9 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_common_auctions.rs @@ -0,0 +1,143 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::auctions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::auctions +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_common_auctions.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::auctions`. +pub struct WeightInfo(PhantomData); +impl runtime_common::auctions::WeightInfo for WeightInfo { + /// Storage: Auctions AuctionInfo (r:1 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Auctions AuctionCounter (r:1 w:1) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn new_auction() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `1493` + // Minimum execution time: 12_041_000 picoseconds. + Weight::from_parts(12_640_000, 0) + .saturating_add(Weight::from_parts(0, 1493)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions Winning (r:1 w:1) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:2 w:2) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn bid() -> Weight { + // Proof Size summary in bytes: + // Measured: `571` + // Estimated: `6060` + // Minimum execution time: 89_277_000 picoseconds. + Weight::from_parts(108_557_000, 0) + .saturating_add(Weight::from_parts(0, 6060)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Auctions AuctionInfo (r:1 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe NextRandomness (r:1 w:0) + /// Proof: Babe NextRandomness (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: Babe EpochStart (r:1 w:0) + /// Proof: Babe EpochStart (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Auctions Winning (r:3600 w:3600) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:37 w:36) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:36 w:36) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Slots Leases (r:7 w:7) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + fn on_initialize() -> Weight { + // Proof Size summary in bytes: + // Measured: `6947683` + // Estimated: `15822990` + // Minimum execution time: 7_694_178_000 picoseconds. + Weight::from_parts(9_153_568_000, 0) + .saturating_add(Weight::from_parts(0, 15822990)) + .saturating_add(T::DbWeight::get().reads(3688)) + .saturating_add(T::DbWeight::get().writes(3683)) + } + /// Storage: Auctions ReservedAmounts (r:37 w:36) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:36 w:36) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Auctions Winning (r:3600 w:3600) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions AuctionInfo (r:0 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + fn cancel_auction() -> Weight { + // Proof Size summary in bytes: + // Measured: `177732` + // Estimated: `15822990` + // Minimum execution time: 5_806_569_000 picoseconds. + Weight::from_parts(6_418_685_000, 0) + .saturating_add(Weight::from_parts(0, 15822990)) + .saturating_add(T::DbWeight::get().reads(3673)) + .saturating_add(T::DbWeight::get().writes(3673)) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_common_crowdloan.rs b/polkadot/runtime/westend/src/weights/runtime_common_crowdloan.rs new file mode 100644 index 0000000000000000000000000000000000000000..97b0279544c761d2c344f189e16e7d7484242d57 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_common_crowdloan.rs @@ -0,0 +1,225 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::crowdloan` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::crowdloan +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_common_crowdloan.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::crowdloan`. +pub struct WeightInfo(PhantomData); +impl runtime_common::crowdloan::WeightInfo for WeightInfo { + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan NextFundIndex (r:1 w:1) + /// Proof Skipped: Crowdloan NextFundIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn create() -> Weight { + // Proof Size summary in bytes: + // Measured: `438` + // Estimated: `3903` + // Minimum execution time: 54_721_000 picoseconds. + Weight::from_parts(73_165_000, 0) + .saturating_add(Weight::from_parts(0, 3903)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Crowdloan EndingsCount (r:1 w:0) + /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + fn contribute() -> Weight { + // Proof Size summary in bytes: + // Measured: `424` + // Estimated: `3889` + // Minimum execution time: 150_157_000 picoseconds. + Weight::from_parts(188_213_000, 0) + .saturating_add(Weight::from_parts(0, 3889)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + /// Proof Skipped: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + fn withdraw() -> Weight { + // Proof Size summary in bytes: + // Measured: `690` + // Estimated: `6196` + // Minimum execution time: 88_125_000 picoseconds. + Weight::from_parts(108_202_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// The range of component `k` is `[0, 500]`. + fn refund(k: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `176 + k * (188 ±0)` + // Estimated: `201 + k * (189 ±0)` + // Minimum execution time: 51_261_000 picoseconds. + Weight::from_parts(69_033_000, 0) + .saturating_add(Weight::from_parts(0, 201)) + // Standard Error: 41_860 + .saturating_add(Weight::from_parts(42_987_746, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(k.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(k.into()))) + .saturating_add(Weight::from_parts(0, 189).saturating_mul(k.into())) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn dissolve() -> Weight { + // Proof Size summary in bytes: + // Measured: `515` + // Estimated: `6196` + // Minimum execution time: 48_316_000 picoseconds. + Weight::from_parts(60_935_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + fn edit() -> Weight { + // Proof Size summary in bytes: + // Measured: `235` + // Estimated: `3700` + // Minimum execution time: 22_070_000 picoseconds. + Weight::from_parts(34_570_000, 0) + .saturating_add(Weight::from_parts(0, 3700)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Crowdloan Funds (r:1 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + fn add_memo() -> Weight { + // Proof Size summary in bytes: + // Measured: `412` + // Estimated: `3877` + // Minimum execution time: 35_055_000 picoseconds. + Weight::from_parts(55_008_000, 0) + .saturating_add(Weight::from_parts(0, 3877)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Crowdloan Funds (r:1 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + fn poke() -> Weight { + // Proof Size summary in bytes: + // Measured: `239` + // Estimated: `3704` + // Minimum execution time: 22_412_000 picoseconds. + Weight::from_parts(31_728_000, 0) + .saturating_add(Weight::from_parts(0, 3704)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Crowdloan EndingsCount (r:1 w:1) + /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan Funds (r:100 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Paras ParaLifecycles (r:100 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:100 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions Winning (r:1 w:1) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:100 w:100) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:100 w:100) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `n` is `[2, 100]`. + fn on_initialize(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `91 + n * (356 ±0)` + // Estimated: `5385 + n * (2832 ±0)` + // Minimum execution time: 151_113_000 picoseconds. + Weight::from_parts(1_510_902, 0) + .saturating_add(Weight::from_parts(0, 5385)) + // Standard Error: 159_249 + .saturating_add(Weight::from_parts(70_348_920, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2832).saturating_mul(n.into())) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_common_paras_registrar.rs b/polkadot/runtime/westend/src/weights/runtime_common_paras_registrar.rs new file mode 100644 index 0000000000000000000000000000000000000000..50290c0fe59f64031258b2fe2d1ff16124d60701 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_common_paras_registrar.rs @@ -0,0 +1,218 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::paras_registrar` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::paras_registrar +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_common_paras_registrar.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::paras_registrar`. +pub struct WeightInfo(PhantomData); +impl runtime_common::paras_registrar::WeightInfo for WeightInfo { + /// Storage: Registrar NextFreeParaId (r:1 w:1) + /// Proof Skipped: Registrar NextFreeParaId (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + fn reserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `97` + // Estimated: `3562` + // Minimum execution time: 31_208_000 picoseconds. + Weight::from_parts(31_867_000, 0) + .saturating_add(Weight::from_parts(0, 3562)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:0 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpcomingParasGenesis (r:0 w:1) + /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) + fn register() -> Weight { + // Proof Size summary in bytes: + // Measured: `329` + // Estimated: `3794` + // Minimum execution time: 6_237_532_000 picoseconds. + Weight::from_parts(7_848_788_000, 0) + .saturating_add(Weight::from_parts(0, 3794)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:0 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpcomingParasGenesis (r:0 w:1) + /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) + fn force_register() -> Weight { + // Proof Size summary in bytes: + // Measured: `246` + // Estimated: `3711` + // Minimum execution time: 6_167_803_000 picoseconds. + Weight::from_parts(7_781_982_000, 0) + .saturating_add(Weight::from_parts(0, 3711)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeHash (r:1 w:0) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: Registrar PendingSwap (r:0 w:1) + /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) + fn deregister() -> Weight { + // Proof Size summary in bytes: + // Measured: `476` + // Estimated: `3941` + // Minimum execution time: 54_133_000 picoseconds. + Weight::from_parts(68_544_000, 0) + .saturating_add(Weight::from_parts(0, 3941)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Registrar Paras (r:1 w:0) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:2 w:2) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar PendingSwap (r:1 w:1) + /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan Funds (r:2 w:2) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:2 w:2) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + fn swap() -> Weight { + // Proof Size summary in bytes: + // Measured: `674` + // Estimated: `6614` + // Minimum execution time: 62_690_000 picoseconds. + Weight::from_parts(73_010_000, 0) + .saturating_add(Weight::from_parts(0, 6614)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(8)) + } + /// Storage: Paras FutureCodeHash (r:1 w:1) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:1 w:1) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeCooldowns (r:1 w:1) + /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[1, 3145728]`. + fn schedule_code_upgrade(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `177` + // Estimated: `3642` + // Minimum execution time: 39_804_000 picoseconds. + Weight::from_parts(40_135_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + // Standard Error: 11 + .saturating_add(Weight::from_parts(2_744, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[1, 1048576]`. + fn set_current_head(b: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_804_000 picoseconds. + Weight::from_parts(8_956_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_029, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_common_slots.rs b/polkadot/runtime/westend/src/weights/runtime_common_slots.rs new file mode 100644 index 0000000000000000000000000000000000000000..c95859221fa726dd79f15d34bb3ed0c4083f37ec --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_common_slots.rs @@ -0,0 +1,135 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::slots` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::slots +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_common_slots.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::slots`. +pub struct WeightInfo(PhantomData); +impl runtime_common::slots::WeightInfo for WeightInfo { + /// Storage: Slots Leases (r:1 w:1) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn force_lease() -> Weight { + // Proof Size summary in bytes: + // Measured: `181` + // Estimated: `3646` + // Minimum execution time: 30_033_000 picoseconds. + Weight::from_parts(30_893_000, 0) + .saturating_add(Weight::from_parts(0, 3646)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Slots Leases (r:101 w:100) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:200 w:200) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:100 w:100) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 100]`. + /// The range of component `t` is `[0, 100]`. + fn manage_lease_period_start(c: u32, t: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + c * (47 ±0) + t * (308 ±0)` + // Estimated: `2694 + c * (2526 ±0) + t * (2789 ±0)` + // Minimum execution time: 737_927_000 picoseconds. + Weight::from_parts(769_816_000, 0) + .saturating_add(Weight::from_parts(0, 2694)) + // Standard Error: 112_360 + .saturating_add(Weight::from_parts(3_515_663, 0).saturating_mul(c.into())) + // Standard Error: 112_360 + .saturating_add(Weight::from_parts(14_335_474, 0).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(t.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(t.into()))) + .saturating_add(Weight::from_parts(0, 2526).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 2789).saturating_mul(t.into())) + } + /// Storage: Slots Leases (r:1 w:1) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:8 w:8) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn clear_all_leases() -> Weight { + // Proof Size summary in bytes: + // Measured: `2653` + // Estimated: `21814` + // Minimum execution time: 153_832_000 picoseconds. + Weight::from_parts(170_790_000, 0) + .saturating_add(Weight::from_parts(0, 21814)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(9)) + } + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + fn trigger_onboard() -> Weight { + // Proof Size summary in bytes: + // Measured: `601` + // Estimated: `4066` + // Minimum execution time: 31_647_000 picoseconds. + Weight::from_parts(41_735_000, 0) + .saturating_add(Weight::from_parts(0, 4066)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_parachains_configuration.rs b/polkadot/runtime/westend/src/weights/runtime_parachains_configuration.rs new file mode 100644 index 0000000000000000000000000000000000000000..585dc9058f21ec29b15040470d4a4c663c18d303 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_parachains_configuration.rs @@ -0,0 +1,157 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::configuration` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-fljshgub-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_parachains::configuration +// --chain=westend-dev +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::configuration`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::configuration::WeightInfo for WeightInfo { + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_block_number() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_616_000 picoseconds. + Weight::from_parts(9_961_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_u32() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_587_000 picoseconds. + Weight::from_parts(9_964_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_option_u32() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_650_000 picoseconds. + Weight::from_parts(9_960_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn set_hrmp_open_request_ttl() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_000_000_000_000 picoseconds. + Weight::from_parts(2_000_000_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_balance() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_545_000 picoseconds. + Weight::from_parts(9_845_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_executor_params() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 10_258_000 picoseconds. + Weight::from_parts(10_607_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_perbill() -> Weight { + // Proof Size summary in bytes: + // Measured: `127` + // Estimated: `1612` + // Minimum execution time: 9_502_000 picoseconds. + Weight::from_parts(9_902_000, 0) + .saturating_add(Weight::from_parts(0, 1612)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_parachains_disputes.rs b/polkadot/runtime/westend/src/weights/runtime_parachains_disputes.rs new file mode 100644 index 0000000000000000000000000000000000000000..4a6a6079cf131a8d39ef3a812d2309b955762764 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_parachains_disputes.rs @@ -0,0 +1,64 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::disputes` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::disputes +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_parachains_disputes.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::disputes`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::disputes::WeightInfo for WeightInfo { + /// Storage: ParasDisputes Frozen (r:0 w:1) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + fn force_unfreeze() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_782_000 picoseconds. + Weight::from_parts(2_926_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_parachains_disputes_slashing.rs b/polkadot/runtime/westend/src/weights/runtime_parachains_disputes_slashing.rs new file mode 100644 index 0000000000000000000000000000000000000000..8600717fee1e222f587c19cc7cf44f36d2bde6d2 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_parachains_disputes_slashing.rs @@ -0,0 +1,101 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::disputes::slashing` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::disputes::slashing +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_parachains_disputes_slashing.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::disputes::slashing`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::disputes::slashing::WeightInfo for WeightInfo { + /// Storage: Session CurrentIndex (r:1 w:0) + /// Proof Skipped: Session CurrentIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Historical HistoricalSessions (r:1 w:0) + /// Proof: Historical HistoricalSessions (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: ParasSlashing UnappliedSlashes (r:1 w:1) + /// Proof Skipped: ParasSlashing UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences ConcurrentReportsIndex (r:1 w:1) + /// Proof Skipped: Offences ConcurrentReportsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Offences Reports (r:1 w:1) + /// Proof Skipped: Offences Reports (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SlashRewardFraction (r:1 w:0) + /// Proof: Staking SlashRewardFraction (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Staking Invulnerables (r:1 w:0) + /// Proof Skipped: Staking Invulnerables (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ValidatorSlashInEra (r:1 w:1) + /// Proof: Staking ValidatorSlashInEra (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:1 w:1) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking SpanSlash (r:1 w:1) + /// Proof: Staking SpanSlash (max_values: None, max_size: Some(76), added: 2551, mode: MaxEncodedLen) + /// Storage: Staking OffendingValidators (r:1 w:1) + /// Proof Skipped: Staking OffendingValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session DisabledValidators (r:1 w:1) + /// Proof Skipped: Session DisabledValidators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking UnappliedSlashes (r:1 w:1) + /// Proof Skipped: Staking UnappliedSlashes (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[4, 300]`. + fn report_dispute_lost(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `4531 + n * (189 ±0)` + // Estimated: `7843 + n * (192 ±0)` + // Minimum execution time: 88_189_000 picoseconds. + Weight::from_parts(165_880_925, 0) + .saturating_add(Weight::from_parts(0, 7843)) + // Standard Error: 11_760 + .saturating_add(Weight::from_parts(419_347, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(9)) + .saturating_add(Weight::from_parts(0, 192).saturating_mul(n.into())) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_parachains_hrmp.rs b/polkadot/runtime/westend/src/weights/runtime_parachains_hrmp.rs new file mode 100644 index 0000000000000000000000000000000000000000..e6ff97fa08784d5f9fc75d9274295c2ee666843a --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_parachains_hrmp.rs @@ -0,0 +1,285 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::hrmp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::hrmp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_parachains_hrmp.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::hrmp`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::hrmp::WeightInfo for WeightInfo { + /// Storage: Paras ParaLifecycles (r:2 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_init_open_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `307` + // Estimated: `6247` + // Minimum execution time: 35_676_000 picoseconds. + Weight::from_parts(36_608_000, 0) + .saturating_add(Weight::from_parts(0, 6247)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_accept_open_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `421` + // Estimated: `3886` + // Minimum execution time: 32_773_000 picoseconds. + Weight::from_parts(33_563_000, 0) + .saturating_add(Weight::from_parts(0, 3886)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + fn hrmp_close_channel() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3703` + // Minimum execution time: 28_134_000 picoseconds. + Weight::from_parts(29_236_000, 0) + .saturating_add(Weight::from_parts(0, 3703)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:254 w:254) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:0 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelContents (r:0 w:254) + /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:0 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// The range of component `i` is `[0, 127]`. + /// The range of component `e` is `[0, 127]`. + fn force_clean_hrmp(i: u32, e: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `158 + e * (100 ±0) + i * (100 ±0)` + // Estimated: `3620 + e * (2575 ±0) + i * (2575 ±0)` + // Minimum execution time: 1_217_145_000 picoseconds. + Weight::from_parts(1_251_187_000, 0) + .saturating_add(Weight::from_parts(0, 3620)) + // Standard Error: 118_884 + .saturating_add(Weight::from_parts(4_002_678, 0).saturating_mul(i.into())) + // Standard Error: 118_884 + .saturating_add(Weight::from_parts(3_641_596, 0).saturating_mul(e.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into()))) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(e.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(i.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(e.into()))) + .saturating_add(Weight::from_parts(0, 2575).saturating_mul(e.into())) + .saturating_add(Weight::from_parts(0, 2575).saturating_mul(i.into())) + } + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:256 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:128 w:128) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:0 w:128) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn force_process_hrmp_open(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `386 + c * (136 ±0)` + // Estimated: `1841 + c * (5086 ±0)` + // Minimum execution time: 6_277_000 picoseconds. + Weight::from_parts(6_357_000, 0) + .saturating_add(Weight::from_parts(0, 1841)) + // Standard Error: 41_189 + .saturating_add(Weight::from_parts(22_159_709, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((6_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 5086).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:128 w:128) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequests (r:0 w:128) + /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelContents (r:0 w:128) + /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn force_process_hrmp_close(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `229 + c * (124 ±0)` + // Estimated: `1689 + c * (2600 ±0)` + // Minimum execution time: 5_070_000 picoseconds. + Weight::from_parts(5_225_000, 0) + .saturating_add(Weight::from_parts(0, 1689)) + // Standard Error: 24_173 + .saturating_add(Weight::from_parts(13_645_307, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 2600).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn hrmp_cancel_open_request(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `920 + c * (13 ±0)` + // Estimated: `4189 + c * (15 ±0)` + // Minimum execution time: 20_449_000 picoseconds. + Weight::from_parts(30_861_799, 0) + .saturating_add(Weight::from_parts(0, 4189)) + // Standard Error: 6_642 + .saturating_add(Weight::from_parts(236_293, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 15).saturating_mul(c.into())) + } + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[0, 128]`. + fn clean_open_channel_requests(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `137 + c * (63 ±0)` + // Estimated: `1616 + c * (2538 ±0)` + // Minimum execution time: 3_911_000 picoseconds. + Weight::from_parts(5_219_837, 0) + .saturating_add(Weight::from_parts(0, 1616)) + // Standard Error: 10_219 + .saturating_add(Weight::from_parts(3_647_782, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 2538).saturating_mul(c.into())) + } + /// Storage: Paras ParaLifecycles (r:2 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:2 w:2) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:2 w:2) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + fn force_open_hrmp_channel(_c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `307` + // Estimated: `6247` + // Minimum execution time: 50_870_000 picoseconds. + Weight::from_parts(53_335_000, 0) + .saturating_add(Weight::from_parts(0, 6247)) + .saturating_add(T::DbWeight::get().reads(13)) + .saturating_add(T::DbWeight::get().writes(8)) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_parachains_inclusion.rs b/polkadot/runtime/westend/src/weights/runtime_parachains_inclusion.rs new file mode 100644 index 0000000000000000000000000000000000000000..767097f660e81c2fc411334389b351a6c38d8b6d --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_parachains_inclusion.rs @@ -0,0 +1,75 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::inclusion` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::inclusion +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_parachains_inclusion.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::inclusion`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::inclusion::WeightInfo for WeightInfo { + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:999) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(131122), added: 133597, mode: MaxEncodedLen) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// The range of component `i` is `[1, 1000]`. + fn receive_upward_messages(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `131297` + // Estimated: `134587` + // Minimum execution time: 209_898_000 picoseconds. + Weight::from_parts(210_955_000, 0) + .saturating_add(Weight::from_parts(0, 134587)) + // Standard Error: 97_069 + .saturating_add(Weight::from_parts(207_030_437, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_parachains_initializer.rs b/polkadot/runtime/westend/src/weights/runtime_parachains_initializer.rs new file mode 100644 index 0000000000000000000000000000000000000000..81aca5c958d90d96c90dba0f30d8555e4332db59 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_parachains_initializer.rs @@ -0,0 +1,69 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::initializer` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::initializer +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_parachains_initializer.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::initializer`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::initializer::WeightInfo for WeightInfo { + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `d` is `[0, 65536]`. + fn force_approve(d: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + d * (11 ±0)` + // Estimated: `1480 + d * (11 ±0)` + // Minimum execution time: 3_714_000 picoseconds. + Weight::from_parts(3_872_000, 0) + .saturating_add(Weight::from_parts(0, 1480)) + // Standard Error: 28 + .saturating_add(Weight::from_parts(3_378, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 11).saturating_mul(d.into())) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_parachains_paras.rs b/polkadot/runtime/westend/src/weights/runtime_parachains_paras.rs new file mode 100644 index 0000000000000000000000000000000000000000..07623f60b01235e78549744f03a7e40784bd9e29 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_parachains_paras.rs @@ -0,0 +1,289 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::paras` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::paras +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_parachains_paras.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::paras`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::paras::WeightInfo for WeightInfo { + /// Storage: Paras CurrentCodeHash (r:1 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PastCodeMeta (r:1 w:1) + /// Proof Skipped: Paras PastCodeMeta (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PastCodePruning (r:1 w:1) + /// Proof Skipped: Paras PastCodePruning (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PastCodeHash (r:0 w:1) + /// Proof Skipped: Paras PastCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:0 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn force_set_current_code(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `8309` + // Estimated: `11774` + // Minimum execution time: 33_453_000 picoseconds. + Weight::from_parts(33_700_000, 0) + .saturating_add(Weight::from_parts(0, 11774)) + // Standard Error: 10 + .saturating_add(Weight::from_parts(2_659, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// The range of component `s` is `[1, 1048576]`. + fn force_set_current_head(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_284_000 picoseconds. + Weight::from_parts(8_565_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_025, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: Paras Heads (r:0 w:1) + fn force_set_most_recent_context() -> Weight { + Weight::from_parts(10_155_000, 0) + // Standard Error: 0 + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + /// Storage: Paras FutureCodeHash (r:1 w:1) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeCooldowns (r:1 w:1) + /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn force_schedule_code_upgrade(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `8428` + // Estimated: `11893` + // Minimum execution time: 48_719_000 picoseconds. + Weight::from_parts(49_132_000, 0) + .saturating_add(Weight::from_parts(0, 11893)) + // Standard Error: 11 + .saturating_add(Weight::from_parts(2_657, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `s` is `[1, 1048576]`. + fn force_note_new_head(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `95` + // Estimated: `3560` + // Minimum execution time: 13_693_000 picoseconds. + Weight::from_parts(537_294, 0) + .saturating_add(Weight::from_parts(0, 3560)) + // Standard Error: 6 + .saturating_add(Weight::from_parts(1_032, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + fn force_queue_action() -> Weight { + // Proof Size summary in bytes: + // Measured: `4288` + // Estimated: `7753` + // Minimum execution time: 20_183_000 picoseconds. + Weight::from_parts(20_890_000, 0) + .saturating_add(Weight::from_parts(0, 7753)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// The range of component `c` is `[1, 3145728]`. + fn add_trusted_validation_code(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `659` + // Estimated: `4124` + // Minimum execution time: 99_465_000 picoseconds. + Weight::from_parts(90_033_344, 0) + .saturating_add(Weight::from_parts(0, 4124)) + // Standard Error: 11 + .saturating_add(Weight::from_parts(1_925, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Paras CodeByHashRefs (r:1 w:0) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:0 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + fn poke_unused_validation_code() -> Weight { + // Proof Size summary in bytes: + // Measured: `28` + // Estimated: `3493` + // Minimum execution time: 5_920_000 picoseconds. + Weight::from_parts(6_146_000, 0) + .saturating_add(Weight::from_parts(0, 3493)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement() -> Weight { + // Proof Size summary in bytes: + // Measured: `26682` + // Estimated: `30147` + // Minimum execution time: 114_738_000 picoseconds. + Weight::from_parts(122_023_000, 0) + .saturating_add(Weight::from_parts(0, 30147)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras UpcomingUpgrades (r:1 w:1) + /// Proof Skipped: Paras UpcomingUpgrades (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:0 w:100) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_upgrade_accept() -> Weight { + // Proof Size summary in bytes: + // Measured: `27236` + // Estimated: `30701` + // Minimum execution time: 954_433_000 picoseconds. + Weight::from_parts(974_709_000, 0) + .saturating_add(Weight::from_parts(0, 30701)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(104)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_upgrade_reject() -> Weight { + // Proof Size summary in bytes: + // Measured: `27214` + // Estimated: `30679` + // Minimum execution time: 110_626_000 picoseconds. + Weight::from_parts(139_677_000, 0) + .saturating_add(Weight::from_parts(0, 30679)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_onboarding_accept() -> Weight { + // Proof Size summary in bytes: + // Measured: `26704` + // Estimated: `30169` + // Minimum execution time: 746_347_000 picoseconds. + Weight::from_parts(783_272_000, 0) + .saturating_add(Weight::from_parts(0, 30169)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + fn include_pvf_check_statement_finalize_onboarding_reject() -> Weight { + // Proof Size summary in bytes: + // Measured: `26682` + // Estimated: `30147` + // Minimum execution time: 110_046_000 picoseconds. + Weight::from_parts(120_274_000, 0) + .saturating_add(Weight::from_parts(0, 30147)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/runtime_parachains_paras_inherent.rs b/polkadot/runtime/westend/src/weights/runtime_parachains_paras_inherent.rs new file mode 100644 index 0000000000000000000000000000000000000000..0dd64f054d009ac1aa01e251b01652ea2dd909c4 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_parachains_paras_inherent.rs @@ -0,0 +1,345 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `runtime_parachains::paras_inherent` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-xerhrdyb-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_parachains::paras_inherent +// --chain=westend-dev +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_parachains::paras_inherent`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::paras_inherent::WeightInfo for WeightInfo { + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: ParaSessionInfo Sessions (r:1 w:0) + /// Proof Skipped: ParaSessionInfo Sessions (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:1) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes BackersOnDisputes (r:1 w:1) + /// Proof Skipped: ParasDisputes BackersOnDisputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Included (r:1 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `v` is `[10, 200]`. + fn enter_variable_disputes(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `50518` + // Estimated: `56458 + v * (23 ±0)` + // Minimum execution time: 998_338_000 picoseconds. + Weight::from_parts(468_412_001, 0) + .saturating_add(Weight::from_parts(0, 56458)) + // Standard Error: 20_559 + .saturating_add(Weight::from_parts(56_965_025, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(27)) + .saturating_add(T::DbWeight::get().writes(15)) + .saturating_add(Weight::from_parts(0, 23).saturating_mul(v.into())) + } + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:0) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion AvailabilityBitfields (r:0 w:1) + /// Proof Skipped: ParaInclusion AvailabilityBitfields (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Included (r:0 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + fn enter_bitfields() -> Weight { + // Proof Size summary in bytes: + // Measured: `42352` + // Estimated: `48292` + // Minimum execution time: 457_404_000 picoseconds. + Weight::from_parts(485_416_000, 0) + .saturating_add(Weight::from_parts(0, 48292)) + .saturating_add(T::DbWeight::get().reads(25)) + .saturating_add(T::DbWeight::get().writes(16)) + } + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:0) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: ParasDisputes Included (r:0 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + /// The range of component `v` is `[101, 200]`. + fn enter_backed_candidates_variable(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `42387` + // Estimated: `48327` + // Minimum execution time: 6_864_029_000 picoseconds. + Weight::from_parts(1_237_704_892, 0) + .saturating_add(Weight::from_parts(0, 48327)) + // Standard Error: 33_413 + .saturating_add(Weight::from_parts(56_199_819, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(28)) + .saturating_add(T::DbWeight::get().writes(15)) + } + /// Storage: ParaInherent Included (r:1 w:1) + /// Proof Skipped: ParaInherent Included (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler AvailabilityCores (r:1 w:1) + /// Proof Skipped: ParaScheduler AvailabilityCores (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Babe AuthorVrfRandomness (r:1 w:0) + /// Proof: Babe AuthorVrfRandomness (max_values: Some(1), max_size: Some(33), added: 528, mode: MaxEncodedLen) + /// Storage: ParaInherent OnChainVotes (r:1 w:1) + /// Proof Skipped: ParaInherent OnChainVotes (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasDisputes Frozen (r:1 w:0) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailability (r:2 w:1) + /// Proof Skipped: ParaInclusion PendingAvailability (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + /// Proof Skipped: ParaInclusion PendingAvailabilityCommitments (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaSessionInfo AccountKeys (r:1 w:0) + /// Proof Skipped: ParaSessionInfo AccountKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking ActiveEra (r:1 w:0) + /// Proof: Staking ActiveEra (max_values: Some(1), max_size: Some(13), added: 508, mode: MaxEncodedLen) + /// Storage: Staking ErasRewardPoints (r:1 w:1) + /// Proof Skipped: Staking ErasRewardPoints (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:1) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelDigests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpChannelDigests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasDisputes Disputes (r:1 w:0) + /// Proof Skipped: ParasDisputes Disputes (max_values: None, max_size: None, mode: Measured) + /// Storage: ParaScheduler SessionStartBlock (r:1 w:0) + /// Proof Skipped: ParaScheduler SessionStartBlock (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ParathreadQueue (r:1 w:1) + /// Proof Skipped: ParaScheduler ParathreadQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler Scheduled (r:1 w:1) + /// Proof Skipped: ParaScheduler Scheduled (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParaScheduler ValidatorGroups (r:1 w:0) + /// Proof Skipped: ParaScheduler ValidatorGroups (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeHash (r:1 w:0) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:1 w:0) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: ParasDisputes Included (r:0 w:1) + /// Proof Skipped: ParasDisputes Included (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpWatermarks (r:0 w:1) + /// Proof Skipped: Hrmp HrmpWatermarks (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + fn enter_backed_candidate_code_upgrade() -> Weight { + // Proof Size summary in bytes: + // Measured: `42414` + // Estimated: `48354` + // Minimum execution time: 43_320_529_000 picoseconds. + Weight::from_parts(45_622_613_000, 0) + .saturating_add(Weight::from_parts(0, 48354)) + .saturating_add(T::DbWeight::get().reads(30)) + .saturating_add(T::DbWeight::get().writes(15)) + } +} diff --git a/polkadot/runtime/westend/src/weights/xcm/mod.rs b/polkadot/runtime/westend/src/weights/xcm/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..c6fa6bb93eb6ab69b256597bbedd59210bfcbf67 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/xcm/mod.rs @@ -0,0 +1,293 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +mod pallet_xcm_benchmarks_fungible; +mod pallet_xcm_benchmarks_generic; + +use crate::Runtime; +use frame_support::weights::Weight; +use sp_std::prelude::*; +use xcm::{ + latest::{prelude::*, QueryResponseInfo}, + DoubleEncoded, +}; + +use pallet_xcm_benchmarks_fungible::WeightInfo as XcmBalancesWeight; +use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; + +/// Types of asset supported by the westend runtime. +pub enum AssetTypes { + /// An asset backed by `pallet-balances`. + Balances, + /// Unknown asset. + Unknown, +} + +impl From<&MultiAsset> for AssetTypes { + fn from(asset: &MultiAsset) -> Self { + match asset { + MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), .. } => + AssetTypes::Balances, + _ => AssetTypes::Unknown, + } + } +} + +trait WeighMultiAssets { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight; +} + +// Westend only knows about one asset, the balances pallet. +const MAX_ASSETS: u64 = 1; + +impl WeighMultiAssets for MultiAssetFilter { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { + match self { + Self::Definite(assets) => assets + .inner() + .into_iter() + .map(From::from) + .map(|t| match t { + AssetTypes::Balances => balances_weight, + AssetTypes::Unknown => Weight::MAX, + }) + .fold(Weight::zero(), |acc, x| acc.saturating_add(x)), + // We don't support any NFTs on Westend, so these two variants will always match + // only 1 kind of fungible asset. + Self::Wild(AllOf { .. } | AllOfCounted { .. }) => balances_weight, + Self::Wild(AllCounted(count)) => + balances_weight.saturating_mul(MAX_ASSETS.min(*count as u64)), + Self::Wild(All) => balances_weight.saturating_mul(MAX_ASSETS), + } + } +} + +impl WeighMultiAssets for MultiAssets { + fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { + self.inner() + .into_iter() + .map(|m| >::from(m)) + .map(|t| match t { + AssetTypes::Balances => balances_weight, + AssetTypes::Unknown => Weight::MAX, + }) + .fold(Weight::zero(), |acc, x| acc.saturating_add(x)) + } +} + +pub struct WestendXcmWeight(core::marker::PhantomData); +impl XcmWeightInfo for WestendXcmWeight { + fn withdraw_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) + } + fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { + // Westend doesn't support ReserveAssetDeposited, so this benchmark has a default weight + assets.weigh_multi_assets(XcmBalancesWeight::::reserve_asset_deposited()) + } + fn receive_teleported_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) + } + fn query_response( + _query_id: &u64, + _response: &Response, + _max_weight: &Weight, + _querier: &Option, + ) -> Weight { + XcmGeneric::::query_response() + } + fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) + } + fn transfer_reserve_asset( + assets: &MultiAssets, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::transfer_reserve_asset()) + } + fn transact( + _origin_kind: &OriginKind, + _require_weight_at_most: &Weight, + _call: &DoubleEncoded, + ) -> Weight { + XcmGeneric::::transact() + } + fn hrmp_new_channel_open_request( + _sender: &u32, + _max_message_size: &u32, + _max_capacity: &u32, + ) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn hrmp_channel_accepted(_recipient: &u32) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn hrmp_channel_closing(_initiator: &u32, _sender: &u32, _recipient: &u32) -> Weight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn clear_origin() -> Weight { + XcmGeneric::::clear_origin() + } + fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + XcmGeneric::::descend_origin() + } + fn report_error(_query_repsonse_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::report_error() + } + + fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::deposit_asset()) + } + fn deposit_reserve_asset( + assets: &MultiAssetFilter, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::deposit_reserve_asset()) + } + fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + // Westend does not currently support exchange asset operations + Weight::MAX + } + fn initiate_reserve_withdraw( + assets: &MultiAssetFilter, + _reserve: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) + } + fn initiate_teleport( + assets: &MultiAssetFilter, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> Weight { + assets.weigh_multi_assets(XcmBalancesWeight::::initiate_teleport()) + } + fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + XcmGeneric::::report_holding() + } + fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + XcmGeneric::::buy_execution() + } + fn refund_surplus() -> Weight { + XcmGeneric::::refund_surplus() + } + fn set_error_handler(_xcm: &Xcm) -> Weight { + XcmGeneric::::set_error_handler() + } + fn set_appendix(_xcm: &Xcm) -> Weight { + XcmGeneric::::set_appendix() + } + fn clear_error() -> Weight { + XcmGeneric::::clear_error() + } + fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + XcmGeneric::::claim_asset() + } + fn trap(_code: &u64) -> Weight { + XcmGeneric::::trap() + } + fn subscribe_version(_query_id: &QueryId, _max_response_weight: &Weight) -> Weight { + XcmGeneric::::subscribe_version() + } + fn unsubscribe_version() -> Weight { + XcmGeneric::::unsubscribe_version() + } + fn burn_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + } + fn expect_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + } + fn expect_origin(_origin: &Option) -> Weight { + XcmGeneric::::expect_origin() + } + fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { + XcmGeneric::::expect_error() + } + fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight { + XcmGeneric::::expect_transact_status() + } + fn query_pallet(_module_name: &Vec, _response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::query_pallet() + } + fn expect_pallet( + _index: &u32, + _name: &Vec, + _module_name: &Vec, + _crate_major: &u32, + _min_crate_minor: &u32, + ) -> Weight { + XcmGeneric::::expect_pallet() + } + fn report_transact_status(_response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::report_transact_status() + } + fn clear_transact_status() -> Weight { + XcmGeneric::::clear_transact_status() + } + fn universal_origin(_: &Junction) -> Weight { + // Westend does not currently support universal origin operations + Weight::MAX + } + fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { + // Westend relay should not support export message operations + Weight::MAX + } + fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Westend does not currently support asset locking operations + Weight::MAX + } + fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Westend does not currently support asset locking operations + Weight::MAX + } + fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Westend does not currently support asset locking operations + Weight::MAX + } + fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + // Westend does not currently support asset locking operations + Weight::MAX + } + fn set_fees_mode(_: &bool) -> Weight { + XcmGeneric::::set_fees_mode() + } + fn set_topic(_topic: &[u8; 32]) -> Weight { + XcmGeneric::::set_topic() + } + fn clear_topic() -> Weight { + XcmGeneric::::clear_topic() + } + fn alias_origin(_: &MultiLocation) -> Weight { + // XCM Executor does not currently support alias origin operations + Weight::MAX + } + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + XcmGeneric::::unpaid_execution() + } +} + +#[test] +fn all_counted_has_a_sane_weight_upper_limit() { + let assets = MultiAssetFilter::Wild(AllCounted(4294967295)); + let weight = Weight::from_parts(1000, 1000); + + assert_eq!(assets.weigh_multi_assets(weight), weight * MAX_ASSETS); +} diff --git a/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs b/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs new file mode 100644 index 0000000000000000000000000000000000000000..b92749bfa15b314573052ed4472bc664cd39e3ae --- /dev/null +++ b/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs @@ -0,0 +1,179 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm_benchmarks::fungible` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-gghbxkbs-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_xcm_benchmarks::fungible +// --chain=westend-dev +// --header=./file_header.txt +// --template=./xcm/pallet-xcm-benchmarks/template.hbs +// --output=./runtime/westend/src/weights/xcm/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm_benchmarks::fungible`. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn withdraw_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `3593` + // Minimum execution time: 24_887_000 picoseconds. + Weight::from_parts(25_361_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn transfer_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `6196` + // Minimum execution time: 52_408_000 picoseconds. + Weight::from_parts(53_387_000, 6196) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn transfer_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `177` + // Estimated: `6196` + // Minimum execution time: 74_753_000 picoseconds. + Weight::from_parts(76_838_000, 6196) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn reserve_asset_deposited() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_000_000_000_000 picoseconds. + Weight::from_parts(2_000_000_000_000, 0) + } + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn initiate_reserve_withdraw() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3541` + // Minimum execution time: 29_272_000 picoseconds. + Weight::from_parts(30_061_000, 3541) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn receive_teleported_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `3593` + // Minimum execution time: 23_112_000 picoseconds. + Weight::from_parts(23_705_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + pub(crate) fn deposit_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 26_077_000 picoseconds. + Weight::from_parts(26_486_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn deposit_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3593` + // Minimum execution time: 51_022_000 picoseconds. + Weight::from_parts(52_498_000, 3593) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + pub(crate) fn initiate_teleport() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3593` + // Minimum execution time: 53_062_000 picoseconds. + Weight::from_parts(54_300_000, 3593) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs new file mode 100644 index 0000000000000000000000000000000000000000..49beb85c2784aa9d6746559322642e6f83c617e5 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -0,0 +1,340 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm_benchmarks::generic` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-02, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bm3`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --pallet=pallet_xcm_benchmarks::generic +// --chain=westend-dev +// --header=./file_header.txt +// --template=./xcm/pallet-xcm-benchmarks/template.hbs +// --output=./runtime/westend/src/weights/xcm/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm_benchmarks::generic`. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn report_holding() -> Weight { + // Proof Size summary in bytes: + // Measured: `169` + // Estimated: `3634` + // Minimum execution time: 30_790_000 picoseconds. + Weight::from_parts(31_265_000, 3634) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + pub(crate) fn buy_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_741_000 picoseconds. + Weight::from_parts(2_823_000, 0) + } + /// Storage: XcmPallet Queries (r:1 w:0) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + pub(crate) fn query_response() -> Weight { + // Proof Size summary in bytes: + // Measured: `169` + // Estimated: `3634` + // Minimum execution time: 10_848_000 picoseconds. + Weight::from_parts(11_183_000, 3634) + .saturating_add(T::DbWeight::get().reads(1)) + } + pub(crate) fn transact() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 12_145_000 picoseconds. + Weight::from_parts(12_366_000, 0) + } + pub(crate) fn refund_surplus() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_837_000 picoseconds. + Weight::from_parts(2_939_000, 0) + } + pub(crate) fn set_error_handler() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_526_000 picoseconds. + Weight::from_parts(2_622_000, 0) + } + pub(crate) fn set_appendix() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_603_000 picoseconds. + Weight::from_parts(2_642_000, 0) + } + pub(crate) fn clear_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_500_000 picoseconds. + Weight::from_parts(2_573_000, 0) + } + pub(crate) fn descend_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_323_000 picoseconds. + Weight::from_parts(3_401_000, 0) + } + pub(crate) fn clear_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_557_000 picoseconds. + Weight::from_parts(2_620_000, 0) + } + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn report_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `169` + // Estimated: `3634` + // Minimum execution time: 25_828_000 picoseconds. + Weight::from_parts(26_318_000, 3634) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: XcmPallet AssetTraps (r:1 w:1) + /// Proof Skipped: XcmPallet AssetTraps (max_values: None, max_size: None, mode: Measured) + pub(crate) fn claim_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `226` + // Estimated: `3691` + // Minimum execution time: 14_794_000 picoseconds. + Weight::from_parts(15_306_000, 3691) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub(crate) fn trap() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_534_000 picoseconds. + Weight::from_parts(2_574_000, 0) + } + /// Storage: XcmPallet VersionNotifyTargets (r:1 w:1) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn subscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `169` + // Estimated: `3634` + // Minimum execution time: 32_218_000 picoseconds. + Weight::from_parts(32_945_000, 3634) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: XcmPallet VersionNotifyTargets (r:0 w:1) + /// Proof Skipped: XcmPallet VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + pub(crate) fn unsubscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_983_000 picoseconds. + Weight::from_parts(5_132_000, 0) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub(crate) fn burn_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_101_000 picoseconds. + Weight::from_parts(4_228_000, 0) + } + pub(crate) fn expect_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_740_000 picoseconds. + Weight::from_parts(2_814_000, 0) + } + pub(crate) fn expect_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_716_000 picoseconds. + Weight::from_parts(2_795_000, 0) + } + pub(crate) fn expect_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_550_000 picoseconds. + Weight::from_parts(2_601_000, 0) + } + pub(crate) fn expect_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_762_000 picoseconds. + Weight::from_parts(2_849_000, 0) + } + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn query_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `169` + // Estimated: `3634` + // Minimum execution time: 31_709_000 picoseconds. + Weight::from_parts(32_288_000, 3634) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + pub(crate) fn expect_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_209_000 picoseconds. + Weight::from_parts(7_332_000, 0) + } + /// Storage: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Proof Skipped: unknown `0x3a696e747261626c6f636b5f656e74726f7079` (r:1 w:1) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + pub(crate) fn report_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `169` + // Estimated: `3634` + // Minimum execution time: 26_161_000 picoseconds. + Weight::from_parts(26_605_000, 3634) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) + } + pub(crate) fn clear_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_539_000 picoseconds. + Weight::from_parts(2_647_000, 0) + } + pub(crate) fn set_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_494_000 picoseconds. + Weight::from_parts(2_588_000, 0) + } + pub(crate) fn clear_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_510_000 picoseconds. + Weight::from_parts(2_590_000, 0) + } + pub(crate) fn set_fees_mode() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_491_000 picoseconds. + Weight::from_parts(2_546_000, 0) + } + pub(crate) fn unpaid_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_696_000 picoseconds. + Weight::from_parts(2_816_000, 0) + } +} diff --git a/polkadot/runtime/westend/src/xcm_config.rs b/polkadot/runtime/westend/src/xcm_config.rs new file mode 100644 index 0000000000000000000000000000000000000000..a83c38c9f66f655055c39ec12ceca5d890aa5b0f --- /dev/null +++ b/polkadot/runtime/westend/src/xcm_config.rs @@ -0,0 +1,310 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! XCM configurations for Westend. + +use super::{ + parachains_origin, weights, AccountId, AllPalletsWithSystem, Balances, Dmp, ParaId, Runtime, + RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, WeightToFee, XcmPallet, +}; +use frame_support::{ + parameter_types, + traits::{Contains, Everything, Nothing}, +}; +use frame_system::EnsureRoot; +use runtime_common::{ + crowdloan, paras_registrar, + xcm_sender::{ChildParachainRouter, ExponentialPrice}, + ToAuthor, +}; +use sp_core::ConstU32; +use westend_runtime_constants::currency::CENTS; +use xcm::latest::prelude::*; +use xcm_builder::{ + AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, + AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative, + ChildParachainConvertsVia, ChildSystemParachainAsSuperuser, + CurrencyAdapter as XcmCurrencyAdapter, IsChildSystemParachain, IsConcrete, MintLocation, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, +}; +use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; + +parameter_types! { + pub const TokenLocation: MultiLocation = Here.into_location(); + pub const ThisNetwork: NetworkId = Westend; + pub UniversalLocation: InteriorMultiLocation = ThisNetwork::get().into(); + pub CheckAccount: AccountId = XcmPallet::check_account(); + pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); + /// The asset ID for the asset that we use to pay for message delivery fees. + pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); + /// The base fee for the message delivery fees. + pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); +} + +pub type LocationConverter = + (ChildParachainConvertsVia, AccountId32Aliases); + +pub type LocalAssetTransactor = XcmCurrencyAdapter< + // Use this currency: + Balances, + // Use this currency when it is a fungible asset matching the given location or name: + IsConcrete, + // We can convert the MultiLocations with our converter above: + LocationConverter, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // It's a native asset so we keep track of the teleports to maintain total issuance. + LocalCheckAccount, +>; + +type LocalOriginConverter = ( + SovereignSignedViaLocation, + ChildParachainAsNative, + SignedAccountId32AsNative, + ChildSystemParachainAsSuperuser, +); + +/// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our +/// individual routers. +pub type XcmRouter = WithUniqueTopic<( + // Only one router so far - use DMP to communicate with child parachains. + ChildParachainRouter< + Runtime, + XcmPallet, + ExponentialPrice, + >, +)>; + +parameter_types! { + pub const Westmint: MultiLocation = Parachain(1000).into_location(); + pub const Collectives: MultiLocation = Parachain(1001).into_location(); + pub const Wnd: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); + pub const WndForWestmint: (MultiAssetFilter, MultiLocation) = (Wnd::get(), Westmint::get()); + pub const WndForCollectives: (MultiAssetFilter, MultiLocation) = (Wnd::get(), Collectives::get()); + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parachain(1000).into()); +} + +pub type TrustedTeleporters = + (xcm_builder::Case, xcm_builder::Case); + +/// The barriers one of which must be passed for an XCM message to be executed. +pub type Barrier = TrailingSetTopicAsId<( + // Weight that is paid for may be consumed. + TakeWeightCredit, + // Expected responses are OK. + AllowKnownQueryResponses, + WithComputedOrigin< + ( + // If the message is one that immediately attemps to pay for execution, then allow it. + AllowTopLevelPaidExecutionFrom, + // Messages coming from system parachains need not pay for execution. + AllowExplicitUnpaidExecutionFrom>, + // Subscriptions for version tracking are OK. + AllowSubscriptionsFrom, + ), + UniversalLocation, + ConstU32<8>, + >, +)>; + +/// A call filter for the XCM Transact instruction. This is a temporary measure until we +/// properly account for proof size weights. +/// +/// Calls that are allowed through this filter must: +/// 1. Have a fixed weight; +/// 2. Cannot lead to another call being made; +/// 3. Have a defined proof size weight, e.g. no unbounded vecs in call parameters. +pub struct SafeCallFilter; +impl Contains for SafeCallFilter { + fn contains(call: &RuntimeCall) -> bool { + #[cfg(feature = "runtime-benchmarks")] + { + if matches!(call, RuntimeCall::System(frame_system::Call::remark_with_event { .. })) { + return true + } + } + + match call { + RuntimeCall::System( + frame_system::Call::kill_prefix { .. } | frame_system::Call::set_heap_pages { .. }, + ) | + RuntimeCall::Babe(..) | + RuntimeCall::Timestamp(..) | + RuntimeCall::Indices(..) | + RuntimeCall::Balances(..) | + RuntimeCall::Crowdloan( + crowdloan::Call::create { .. } | + crowdloan::Call::contribute { .. } | + crowdloan::Call::withdraw { .. } | + crowdloan::Call::refund { .. } | + crowdloan::Call::dissolve { .. } | + crowdloan::Call::edit { .. } | + crowdloan::Call::poke { .. } | + crowdloan::Call::contribute_all { .. }, + ) | + RuntimeCall::Staking( + pallet_staking::Call::bond { .. } | + pallet_staking::Call::bond_extra { .. } | + pallet_staking::Call::unbond { .. } | + pallet_staking::Call::withdraw_unbonded { .. } | + pallet_staking::Call::validate { .. } | + pallet_staking::Call::nominate { .. } | + pallet_staking::Call::chill { .. } | + pallet_staking::Call::set_payee { .. } | + pallet_staking::Call::set_controller { .. } | + pallet_staking::Call::set_validator_count { .. } | + pallet_staking::Call::increase_validator_count { .. } | + pallet_staking::Call::scale_validator_count { .. } | + pallet_staking::Call::force_no_eras { .. } | + pallet_staking::Call::force_new_era { .. } | + pallet_staking::Call::set_invulnerables { .. } | + pallet_staking::Call::force_unstake { .. } | + pallet_staking::Call::force_new_era_always { .. } | + pallet_staking::Call::payout_stakers { .. } | + pallet_staking::Call::rebond { .. } | + pallet_staking::Call::reap_stash { .. } | + pallet_staking::Call::set_staking_configs { .. } | + pallet_staking::Call::chill_other { .. } | + pallet_staking::Call::force_apply_min_commission { .. }, + ) | + RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) | + RuntimeCall::Grandpa(..) | + RuntimeCall::ImOnline(..) | + RuntimeCall::Utility(pallet_utility::Call::as_derivative { .. }) | + RuntimeCall::Identity( + pallet_identity::Call::add_registrar { .. } | + pallet_identity::Call::set_identity { .. } | + pallet_identity::Call::clear_identity { .. } | + pallet_identity::Call::request_judgement { .. } | + pallet_identity::Call::cancel_request { .. } | + pallet_identity::Call::set_fee { .. } | + pallet_identity::Call::set_account_id { .. } | + pallet_identity::Call::set_fields { .. } | + pallet_identity::Call::provide_judgement { .. } | + pallet_identity::Call::kill_identity { .. } | + pallet_identity::Call::add_sub { .. } | + pallet_identity::Call::rename_sub { .. } | + pallet_identity::Call::remove_sub { .. } | + pallet_identity::Call::quit_sub { .. }, + ) | + RuntimeCall::Recovery(..) | + RuntimeCall::Vesting(..) | + RuntimeCall::ElectionProviderMultiPhase(..) | + RuntimeCall::VoterList(..) | + RuntimeCall::NominationPools( + pallet_nomination_pools::Call::join { .. } | + pallet_nomination_pools::Call::bond_extra { .. } | + pallet_nomination_pools::Call::claim_payout { .. } | + pallet_nomination_pools::Call::unbond { .. } | + pallet_nomination_pools::Call::pool_withdraw_unbonded { .. } | + pallet_nomination_pools::Call::withdraw_unbonded { .. } | + pallet_nomination_pools::Call::create { .. } | + pallet_nomination_pools::Call::create_with_pool_id { .. } | + pallet_nomination_pools::Call::set_state { .. } | + pallet_nomination_pools::Call::set_configs { .. } | + pallet_nomination_pools::Call::update_roles { .. } | + pallet_nomination_pools::Call::chill { .. }, + ) | + RuntimeCall::Hrmp(..) | + RuntimeCall::Registrar( + paras_registrar::Call::deregister { .. } | + paras_registrar::Call::swap { .. } | + paras_registrar::Call::remove_lock { .. } | + paras_registrar::Call::reserve { .. } | + paras_registrar::Call::add_lock { .. }, + ) | + RuntimeCall::XcmPallet(pallet_xcm::Call::limited_reserve_transfer_assets { + .. + }) => true, + _ => false, + } + } +} + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = LocalOriginConverter; + type IsReserve = (); + type IsTeleporter = TrustedTeleporters; + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = + WeightInfoBounds, RuntimeCall, MaxInstructions>; + type Trader = + UsingComponents>; + type ResponseHandler = XcmPallet; + type AssetTrap = XcmPallet; + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = XcmPallet; + type SubscriptionService = XcmPallet; + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = WithOriginFilter; + type SafeCallFilter = SafeCallFilter; + type Aliasers = Nothing; +} + +/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior +/// location of this chain. +pub type LocalOriginToLocation = ( + // And a usual Signed origin to be used in XCM as a corresponding AccountId32 + SignedToAccountId32, +); + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = XcmRouter; + // Anyone can execute XCM messages locally... + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + // ...but they must match our filter, which rejects everything. + type XcmExecuteFilter = Nothing; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type Weigher = + WeightInfoBounds, RuntimeCall, MaxInstructions>; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = IsConcrete; + type TrustedLockers = (); + type SovereignAccountOf = LocationConverter; + type MaxLockers = ConstU32<8>; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = crate::weights::pallet_xcm::WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} diff --git a/polkadot/rustfmt.toml b/polkadot/rustfmt.toml new file mode 100644 index 0000000000000000000000000000000000000000..e2c4a037f37fe229bd237cf50c4bb218814b890f --- /dev/null +++ b/polkadot/rustfmt.toml @@ -0,0 +1,28 @@ +# Basic +edition = "2021" +hard_tabs = true +max_width = 100 +use_small_heuristics = "Max" + +# Imports +imports_granularity = "Crate" +reorder_imports = true + +# Consistency +newline_style = "Unix" + +# Format comments +comment_width = 100 +wrap_comments = true + +# Misc +chain_width = 80 +spaces_around_ranges = false +binop_separator = "Back" +reorder_impl_items = false +match_arm_leading_pipes = "Preserve" +match_arm_blocks = false +match_block_trailing_comma = true +trailing_comma = "Vertical" +trailing_semicolon = false +use_field_init_shorthand = true diff --git a/polkadot/scripts/adder-collator.sh b/polkadot/scripts/adder-collator.sh new file mode 100755 index 0000000000000000000000000000000000000000..8f98aba24c626c8262a93177e1ccd6995ff02256 --- /dev/null +++ b/polkadot/scripts/adder-collator.sh @@ -0,0 +1,191 @@ +#!/usr/bin/env bash + +# Run a two node local net with adder-collator. + +set -e + +chainspec="rococo-local" + +# disabled until we can actually successfully register the chain with polkadot-js-api +# if ! command -v polkadot-js-api > /dev/null; then +# echo "polkadot-js-api required; try" +# echo " sudo yarn global add @polkadot/api-cli" +# exit 1 +# fi + +PROJECT_ROOT=$(git rev-parse --show-toplevel) +# shellcheck disable=SC1090 +source "$(dirname "$0")"/common.sh + +cd "$PROJECT_ROOT" + +last_modified_rust_file=$( + find . -path ./target -prune -o -type f -name '*.rs' -printf '%T@ %p\n' | + sort -nr | + head -1 | + cut -d' ' -f2- +) + +polkadot="target/release/polkadot" +adder_collator="target/release/adder-collator" + +# ensure the polkadot binary exists and is up to date +if [ ! -x "$polkadot" ] || [ "$polkadot" -ot "$last_modified_rust_file" ]; then + cargo build --release +fi +# likewise for the adder collator +if [ ! -x "$adder_collator" ] || [ "$adder_collator" -ot "$last_modified_rust_file" ]; then + cargo build --release -p test-parachain-adder-collator +fi + +genesis="$(mktemp --directory)" +genesis_state="$genesis/state" +validation_code="$genesis/validation_code" + +"$adder_collator" export-genesis-state > "$genesis_state" +"$adder_collator" export-genesis-wasm > "$validation_code" + + +# setup variables +node_offset=0 +declare -a node_pids +declare -a node_pipes + +# create a sed expression which injects the node name and stream type into each line +function make_sed_expr() { + name="$1" + type="$2" + + printf "s/^/%16s %s: /" "$name" "$type" +} + +# turn a string into a flag +function flagify() { + printf -- '--%s' "$(tr '[:upper:]' '[:lower:]' <<< "$1")" +} + +# start a node and label its output +# +# This function takes a single argument, the node name. +# The name must be one of those which can be passed to the polkadot binary, in un-flagged form, +# one of: +# alice, bob, charlie, dave, eve, ferdie, one, two +function run_node() { + name="$1" + # create a named pipe so we can get the node's PID while also sedding its output + local stdout + local stderr + stdout=$(mktemp --dry-run --tmpdir) + stderr=$(mktemp --dry-run --tmpdir) + mkfifo "$stdout" + mkfifo "$stderr" + node_pipes+=("$stdout") + node_pipes+=("$stderr") + + # compute ports from offset + local port=$((30333+node_offset)) + local rpc_port=$((9933+node_offset)) + local ws_port=$((9944+node_offset)) + local prometheus_port=$((9615+node_offset)) + node_offset=$((node_offset+1)) + + # start the node + "$polkadot" \ + --chain "$chainspec" \ + --tmp \ + --port "$port" \ + --rpc-port "$rpc_port" \ + --ws-port "$ws_port" \ + --prometheus-port "$prometheus_port" \ + --rpc-cors all \ + "$(flagify "$name")" \ + > "$stdout" \ + 2> "$stderr" \ + & + local pid=$! + node_pids+=("$pid") + + # send output from the stdout pipe to stdout, prepending the node name + sed -e "$(make_sed_expr "$name" "OUT")" "$stdout" >&1 & + # send output from the stderr pipe to stderr, prepending the node name + sed -e "$(make_sed_expr "$name" "ERR")" "$stderr" >&2 & +} + +# start an adder collator and label its output +# +# This function takes a single argument, the node name. This affects only the tagging. +function run_adder_collator() { + name="$1" + # create a named pipe so we can get the node's PID while also sedding its output + local stdout + local stderr + stdout=$(mktemp --dry-run --tmpdir) + stderr=$(mktemp --dry-run --tmpdir) + mkfifo "$stdout" + mkfifo "$stderr" + node_pipes+=("$stdout") + node_pipes+=("$stderr") + + # compute ports from offset + local port=$((30333+node_offset)) + local rpc_port=$((9933+node_offset)) + local ws_port=$((9944+node_offset)) + local prometheus_port=$((9615+node_offset)) + node_offset=$((node_offset+1)) + + # start the node + "$adder_collator" \ + --chain "$chainspec" \ + --tmp \ + --port "$port" \ + --rpc-port "$rpc_port" \ + --ws-port "$ws_port" \ + --prometheus-port "$prometheus_port" \ + --rpc-cors all \ + > "$stdout" \ + 2> "$stderr" \ + & + local pid=$! + node_pids+=("$pid") + + # send output from the stdout pipe to stdout, prepending the node name + sed -e "$(make_sed_expr "$name" "OUT")" "$stdout" >&1 & + # send output from the stderr pipe to stderr, prepending the node name + sed -e "$(make_sed_expr "$name" "ERR")" "$stderr" >&2 & +} + + +# clean up the nodes when this script exits +function finish { + for node_pid in "${node_pids[@]}"; do + kill -9 "$node_pid" + done + for node_pipe in "${node_pipes[@]}"; do + rm "$node_pipe" + done + rm -rf "$genesis" +} +trap finish EXIT + +# start the nodes +run_node Alice +run_node Bob +run_adder_collator AdderCollator + +# register the adder collator +# doesn't work yet due to https://github.com/polkadot-js/tools/issues/185 +# polkadot-js-api \ +# --ws ws://localhost:9944 \ +# --sudo \ +# --seed "//Alice" \ +# tx.registrar.registerPara \ +# 100 \ +# '{"scheduling":"Always"}' \ +# "@$validation_code" \ +# "@$genesis_state" + +# now wait; this will exit on its own only if both subprocesses exit +# the practical implication, as both subprocesses are supposed to run forever, is that +# this script will also run forever, until killed, at which point the exit trap should kill +# the subprocesses +wait diff --git a/polkadot/scripts/build-demos.sh b/polkadot/scripts/build-demos.sh new file mode 100755 index 0000000000000000000000000000000000000000..285da143c17d8ec4c0f4147dea62dc34843050bf --- /dev/null +++ b/polkadot/scripts/build-demos.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# This script assumes that all pre-requisites are installed. + +set -e + +PROJECT_ROOT=`git rev-parse --show-toplevel` +source `dirname "$0"`/common.sh + +export CARGO_INCREMENTAL=0 + +# Save current directory. +pushd . + +cd $ROOT + +for DEMO in "${DEMOS[@]}" +do + echo "*** Building wasm binaries in $DEMO" + cd "$PROJECT_ROOT/$DEMO" + + ./build.sh + + cd - >> /dev/null +done + +# Restore initial directory. +popd diff --git a/polkadot/scripts/build-only-wasm.sh b/polkadot/scripts/build-only-wasm.sh new file mode 100755 index 0000000000000000000000000000000000000000..b6da3319c8214aeca3ca54b76fda87d83077eec5 --- /dev/null +++ b/polkadot/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/polkadot/scripts/ci/changelog/.gitignore b/polkadot/scripts/ci/changelog/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..4fbcc523b04cf0aba6c866a38250a83c16deb8d8 --- /dev/null +++ b/polkadot/scripts/ci/changelog/.gitignore @@ -0,0 +1,4 @@ +changelog.md +*.json +release*.md +.env diff --git a/polkadot/scripts/ci/changelog/Gemfile b/polkadot/scripts/ci/changelog/Gemfile new file mode 100644 index 0000000000000000000000000000000000000000..46b058e3c5004c85f4ef79b867d2a6638a7e8cd4 --- /dev/null +++ b/polkadot/scripts/ci/changelog/Gemfile @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +source 'https://rubygems.org' + +git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } + +gem 'octokit', '~> 4' + +gem 'git_diff_parser', '~> 3' + +gem 'toml', '~> 0.3.0' + +gem 'rake', group: :dev + +gem 'optparse', '~> 0.1.1' + +gem 'logger', '~> 1.4' + +gem 'changelogerator', '0.10.1' + +gem 'test-unit', group: :dev + +gem 'rubocop', group: :dev, require: false diff --git a/polkadot/scripts/ci/changelog/Gemfile.lock b/polkadot/scripts/ci/changelog/Gemfile.lock new file mode 100644 index 0000000000000000000000000000000000000000..422aa3a8844bbc48f4f23ce2f96e5dce609a626e --- /dev/null +++ b/polkadot/scripts/ci/changelog/Gemfile.lock @@ -0,0 +1,84 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.8.0) + public_suffix (>= 2.0.2, < 5.0) + ast (2.4.2) + changelogerator (0.10.1) + git_diff_parser (~> 3) + octokit (~> 4) + faraday (1.8.0) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0.1) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.1) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + multipart-post (>= 1.2, < 3) + ruby2_keywords (>= 0.0.4) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.0) + faraday-excon (1.1.0) + faraday-httpclient (1.0.1) + faraday-net_http (1.0.1) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + git_diff_parser (3.2.0) + logger (1.4.4) + multipart-post (2.1.1) + octokit (4.21.0) + faraday (>= 0.9) + sawyer (~> 0.8.0, >= 0.5.3) + optparse (0.1.1) + parallel (1.21.0) + parser (3.0.2.0) + ast (~> 2.4.1) + parslet (2.0.0) + power_assert (2.0.1) + public_suffix (4.0.6) + rainbow (3.0.0) + rake (13.0.6) + regexp_parser (2.1.1) + rexml (3.2.5) + rubocop (1.23.0) + parallel (~> 1.10) + parser (>= 3.0.0.0) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.12.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.13.0) + parser (>= 3.0.1.1) + ruby-progressbar (1.11.0) + ruby2_keywords (0.0.5) + sawyer (0.8.2) + addressable (>= 2.3.5) + faraday (> 0.8, < 2.0) + test-unit (3.5.1) + power_assert + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + unicode-display_width (2.1.0) + +PLATFORMS + x86_64-darwin-20 + x86_64-darwin-22 + +DEPENDENCIES + changelogerator (= 0.10.1) + git_diff_parser (~> 3) + logger (~> 1.4) + octokit (~> 4) + optparse (~> 0.1.1) + rake + rubocop + test-unit + toml (~> 0.3.0) + +BUNDLED WITH + 2.4.6 diff --git a/polkadot/scripts/ci/changelog/README.md b/polkadot/scripts/ci/changelog/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ab3c1fd214ee72529c663220c847476c8b8e3a82 --- /dev/null +++ b/polkadot/scripts/ci/changelog/README.md @@ -0,0 +1,80 @@ +# Changelog + +Currently, the changelog is built locally. It will be moved to CI once labels stabilize. + +For now, a bit of preparation is required before you can run the script: +- fetch the srtool digests +- store them under the `digests` folder as `-srtool-digest.json` +- ensure the `.env` file is up to date with correct information. See below for an example + +The content of the release notes is generated from the template files under the `scripts/ci/changelog/templates` folder. For readability and maintenance, the template is split into several small snippets. + +Run: +``` +./bin/changelog [] +``` + +For instance: +``` +./bin/changelog v0.9.18 +``` + +A file called `release-notes.md` will be generated and can be used for the release. + +## ENV + +You may use the following ENV for testing: + +``` +RUSTC_STABLE="rustc 1.56.1 (59eed8a2a 2021-11-01)" +RUSTC_NIGHTLY="rustc 1.57.0-nightly (51e514c0f 2021-09-12)" +PRE_RELEASE=true +HIDE_SRTOOL_SHELL=true +DEBUG=1 +NO_CACHE=1 +``` +## Considered labels + +The following list will likely evolve over time and it will be hard to keep it in sync. +In any case, if you want to find all the labels that are used, search for `meta` in the templates. +Currently, the considered labels are: + +- Priority: C labels +- Audit: D labels +- E4 => new host function +- E2 => database migration +- B0 => silent, not showing up +- B1 => noteworthy +- T0 => node +- T1 => runtime + +Note that labels with the same letter are mutually exclusive. +A PR should not have both `B0` and `B5`, or both `C1` and `C9`. In case of conflicts, the template will +decide which label will be considered. + +## Dev and debuggin + +### Hot Reload + +The following command allows **Hot Reload**: +``` +fswatch templates -e ".*\.md$" | xargs -n1 -I{} ./bin/changelog v0.9.18 +``` +### Caching + +By default, if the changelog data from Github is already present, the calls to the Github API will be skipped +and the local version of the data will be used. This is much faster. +If you know that some labels have changed in Github, you will want to refresh the data. +You can then either delete manually the `.json` file or `export NO_CACHE=1` to force refreshing the data. + +## Full PR list + +At times, it may be useful to get a raw full PR list. +In order to produce this list, you first need to fetch the the latest `context.json` from the `release-notes-context` artifacts you can find [here](https://github.com/paritytech/polkadot/actions/workflows/release-30_publish-draft-release.yml). You may store this `context.json` under `scripts/ci/changelog`. + +Using the `full_pr_list.md.tera` template, you can generate the `raw` list of changes: + +``` +cd scripts/ci/changelog +tera --env --env-key env --template templates/full_pr_list.md.tera context.json +``` diff --git a/polkadot/scripts/ci/changelog/bin/changelog b/polkadot/scripts/ci/changelog/bin/changelog new file mode 100755 index 0000000000000000000000000000000000000000..e642a44890433f01314490253b508a5d8641488a --- /dev/null +++ b/polkadot/scripts/ci/changelog/bin/changelog @@ -0,0 +1,105 @@ +#!/usr/bin/env ruby + +# frozen_string_literal: true + +# call for instance as: +# ./bin/changelog [] [] +# for instance, for the release notes of v1.2.3: +# ./bin/changelog v1.2.3 +# or +# ./bin/changelog v1.2.3 v1.2.2 +# +# You may set the ENV NO_CACHE to force fetching from Github +# You should also ensure you set the ENV: GITHUB_TOKEN + +require_relative '../lib/changelog' +require 'logger' + +logger = Logger.new($stdout) +logger.level = Logger::DEBUG +logger.debug('Starting') + +changelogerator_version = `changelogerator --version` +logger.debug(changelogerator_version) + +owner = 'paritytech' +repo = 'polkadot' + +gh_polkadot = SubRef.new(format('%s/%s', { owner: owner, repo: repo })) +last_release_ref = gh_polkadot.get_last_ref() + +polkadot_ref2 = ARGV[0] || 'HEAD' +polkadot_ref1 = ARGV[1] || last_release_ref + +output = ARGV[2] || 'release-notes.md' + +ENV['REF1'] = polkadot_ref1 +ENV['REF2'] = polkadot_ref2 + +substrate_ref1 = gh_polkadot.get_dependency_reference(polkadot_ref1, 'sp-io') +substrate_ref2 = gh_polkadot.get_dependency_reference(polkadot_ref2, 'sp-io') + +logger.debug("Polkadot from: #{polkadot_ref1}") +logger.debug("Polkadot to: #{polkadot_ref2}") + +logger.debug("Substrate from: #{substrate_ref1}") +logger.debug("Substrate to: #{substrate_ref2}") + +substrate_data = 'substrate.json' +polkadot_data = 'polkadot.json' + +logger.debug("Using SUBSTRATE: #{substrate_data}") +logger.debug("Using POLKADOT: #{polkadot_data}") + +logger.warn('NO_CACHE set') if ENV['NO_CACHE'] + +if ENV['NO_CACHE'] || !File.file?(polkadot_data) + logger.debug(format('Fetching data for Polkadot into %s', polkadot_data)) + cmd = format('changelogerator %s/%s -f %s -t %s > %s', + { owner: owner, repo: 'polkadot', from: polkadot_ref1, to: polkadot_ref2, output: polkadot_data }) + system(cmd) +else + logger.debug("Re-using:#{polkadot_data}") +end + +if ENV['NO_CACHE'] || !File.file?(substrate_data) + logger.debug(format('Fetching data for Substrate into %s', substrate_data)) + cmd = format('changelogerator %s/%s -f %s -t %s > %s', + { owner: owner, repo: 'substrate', from: substrate_ref1, to: substrate_ref2, output: substrate_data }) + system(cmd) +else + logger.debug("Re-using:#{substrate_data}") +end + +KUSAMA_DIGEST = ENV['KUSAMA_DIGEST'] || 'digests/kusama_srtool_output.json' +WESTEND_DIGEST = ENV['WESTEND_DIGEST'] || 'digests/westend_srtool_output.json' +ROCOCO_DIGEST = ENV['ROCOCO_DIGEST'] || 'digests/rococo_srtool_output.json' +POLKADOT_DIGEST = ENV['POLKADOT_DIGEST'] || 'digests/polkadot_srtool_output.json' + +# Here we compose all the pieces together into one +# single big json file. +cmd = format('jq \ + --slurpfile substrate %s \ + --slurpfile polkadot %s \ + --slurpfile srtool_kusama %s \ + --slurpfile srtool_westend %s \ + --slurpfile srtool_rococo %s \ + --slurpfile srtool_polkadot %s \ + -n \'{ + substrate: $substrate[0], + polkadot: $polkadot[0], + srtool: [ + { name: "kusama", data: $srtool_kusama[0] }, + { name: "westend", data: $srtool_westend[0] }, + { name: "rococo", data: $srtool_rococo[0] }, + { name: "polkadot", data: $srtool_polkadot[0] } + ] }\' > context.json', substrate_data, polkadot_data, + KUSAMA_DIGEST, + WESTEND_DIGEST, + ROCOCO_DIGEST, + POLKADOT_DIGEST) +system(cmd) + +cmd = format('tera --env --env-key env --include-path templates \ + --template templates/template.md.tera context.json > %s', output) +system(cmd) diff --git a/polkadot/scripts/ci/changelog/digests/.gitignore b/polkadot/scripts/ci/changelog/digests/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a6c57f5fb2ffba0a6af4278619c2983394d237cc --- /dev/null +++ b/polkadot/scripts/ci/changelog/digests/.gitignore @@ -0,0 +1 @@ +*.json diff --git a/polkadot/scripts/ci/changelog/digests/.gitkeep b/polkadot/scripts/ci/changelog/digests/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/polkadot/scripts/ci/changelog/lib/changelog.rb b/polkadot/scripts/ci/changelog/lib/changelog.rb new file mode 100644 index 0000000000000000000000000000000000000000..e98baf82f01f8ecbc5b3e2424387576b1afc4ae7 --- /dev/null +++ b/polkadot/scripts/ci/changelog/lib/changelog.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +# A Class to find Substrate references +class SubRef + require 'octokit' + require 'toml' + + attr_reader :client, :repository + + def initialize(github_repo) + @client = Octokit::Client.new( + access_token: ENV['GITHUB_TOKEN'] + ) + @repository = @client.repository(github_repo) + end + + # This function checks the Cargo.lock of a given + # Rust project, for a given package, and fetches + # the dependency git ref. + def get_dependency_reference(ref, package) + cargo = TOML::Parser.new( + Base64.decode64( + @client.contents( + @repository.full_name, + path: 'Cargo.lock', + query: { ref: ref.to_s } + ).content + ) + ).parsed + cargo['package'].find { |p| p['name'] == package }['source'].split('#').last + end + + # Get the git ref of the last release for the repo. + # repo is given in the form paritytech/polkadot + def get_last_ref() + 'refs/tags/' + @client.latest_release(@repository.full_name).tag_name + end +end diff --git a/polkadot/scripts/ci/changelog/templates/_free_notes.md.tera b/polkadot/scripts/ci/changelog/templates/_free_notes.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..c4a841a992515a0016f8aec99cc0038e7428cafb --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/_free_notes.md.tera @@ -0,0 +1,10 @@ + +{# This file uses the Markdown format with additional templating such as this comment. -#} +{# Such a comment will not show up in the rendered release notes. -#} +{# The content of this file (if any) will be inserted at the top of the release notes -#} +{# and generated for each new release candidate. -#} +{# Ensure you leave an empty line at both top and bottom of this file. -#} + + + + diff --git a/polkadot/scripts/ci/changelog/templates/change.md.tera b/polkadot/scripts/ci/changelog/templates/change.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..cfde3be6e85f1f400d3894063d1ffaf9c7870e6c --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/change.md.tera @@ -0,0 +1,43 @@ +{# This macro shows ONE change #} +{%- macro change(c, cml="[C]", dot="[P]", sub="[S]") -%} + +{%- if c.meta.C and c.meta.C.agg.max >= 7 -%} +{%- set prio = " ‼️ HIGH" -%} +{%- elif c.meta.C and c.meta.C.agg.max >= 3 -%} +{%- set prio = " ❗️ Medium" -%} +{%- elif c.meta.C and c.meta.C.agg.max < 3 -%} +{%- set prio = " Low" -%} +{%- else -%} +{%- set prio = "" -%} +{%- endif -%} + +{%- set audit = "" -%} + +{%- if c.meta.D and c.meta.D.D1 -%} +{%- set audit = "✅ audited " -%} +{%- elif c.meta.D and c.meta.D.D2 -%} +{%- set audit = "✅ trivial " -%} +{%- elif c.meta.D and c.meta.D.D3 -%} +{%- set audit = "✅ trivial " -%} +{%- elif c.meta.D and c.meta.D.D5 -%} +{%- set audit = "⏳ pending non-critical audit " -%} +{%- else -%} +{%- set audit = "" -%} +{%- endif -%} + +{%- if c.html_url is containing("polkadot") -%} +{%- set repo = dot -%} +{%- elif c.html_url is containing("substrate") -%} +{%- set repo = sub -%} +{%- else -%} +{%- set repo = " " -%} +{%- endif -%} + +{%- if c.meta.T and c.meta.T.T6 -%} +{%- set xcm = " [✉️ XCM]" -%} +{%- else -%} +{%- set xcm = "" -%} +{%- endif -%} + +{{- repo }} {{ audit }}[`#{{c.number}}`]({{c.html_url}}) {{- prio }} - {{ c.title | capitalize | truncate(length=120, end="…") }}{{xcm }} +{%- endmacro change -%} diff --git a/polkadot/scripts/ci/changelog/templates/changes.md.tera b/polkadot/scripts/ci/changelog/templates/changes.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..f598b2fe83f78bf22b97d832afb61e44c11eba53 --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/changes.md.tera @@ -0,0 +1,15 @@ +{# This include generates the section showing the changes #} +## Changes + +### Legend + +- {{ DOT }} Polkadot +- {{ SUB }} Substrate + +{% include "changes_client.md.tera" %} + +{% include "changes_runtime.md.tera" %} + +{% include "changes_api.md.tera" %} + +{% include "changes_misc.md.tera" %} diff --git a/polkadot/scripts/ci/changelog/templates/changes_api.md.tera b/polkadot/scripts/ci/changelog/templates/changes_api.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..29e08b8cd38254cc975d34ef449ab8f8e0a8d42b --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/changes_api.md.tera @@ -0,0 +1,17 @@ +{% import "change.md.tera" as m_c -%} +### API + +{#- The changes are sorted by merge date #} +{%- for pr in changes | sort(attribute="merged_at") %} + +{%- if pr.meta.B %} + {%- if pr.meta.B.B0 %} + {#- We skip silent ones -#} + {%- else -%} + + {%- if pr.meta.T and pr.meta.T.T2 and not pr.title is containing("ompanion") %} +- {{ m_c::change(c=pr) }} + {%- endif -%} + {% endif -%} + {% endif -%} +{% endfor %} diff --git a/polkadot/scripts/ci/changelog/templates/changes_client.md.tera b/polkadot/scripts/ci/changelog/templates/changes_client.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..6d31961c3650193137cea14e975febad07199510 --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/changes_client.md.tera @@ -0,0 +1,17 @@ +{% import "change.md.tera" as m_c -%} +### Client + +{#- The changes are sorted by merge date #} +{%- for pr in changes | sort(attribute="merged_at") %} + +{%- if pr.meta.B %} + {%- if pr.meta.B.B0 %} + {#- We skip silent ones -#} + {%- else -%} + + {%- if pr.meta.T and pr.meta.T.T0 and not pr.title is containing("ompanion") %} +- {{ m_c::change(c=pr) }} + {%- endif -%} + {% endif -%} + {% endif -%} +{% endfor %} diff --git a/polkadot/scripts/ci/changelog/templates/changes_misc.md.tera b/polkadot/scripts/ci/changelog/templates/changes_misc.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..725b03081eb36d34dc0435deb2c4f3d1ef0f8da9 --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/changes_misc.md.tera @@ -0,0 +1,42 @@ +{%- import "change.md.tera" as m_c -%} + +{%- set_global misc_count = 0 -%} +{#- First pass to count #} +{%- for pr in changes -%} + {%- if pr.meta.B %} + {%- if pr.meta.B.B0 -%} + {#- We skip silent ones -#} + {%- else -%} + {%- if pr.meta.T and pr.meta.T.agg.max > 2 %} +{%- set_global misc_count = misc_count + 1 -%} + {%- endif -%} + {% endif -%} + {% endif -%} +{% endfor -%} + + +{%- if misc_count > 0 %} +### Misc + +{% if misc_count > 10 %} +There are other misc. changes. You can expand the list below to view them all. +

Other misc. changes +{% endif -%} + +{#- The changes are sorted by merge date #} +{%- for pr in changes | sort(attribute="merged_at") %} + {%- if pr.meta.B and not pr.title is containing("ompanion") %} + {%- if pr.meta.B.B0 %} + {#- We skip silent ones -#} + {%- else -%} + {%- if pr.meta.T and pr.meta.T.agg.max > 2 %} +- {{ m_c::change(c=pr) }} + {%- endif -%} + {% endif -%} + {% endif -%} +{% endfor %} + +{% if misc_count > 10 %} +
+{% endif -%} +{% endif -%} diff --git a/polkadot/scripts/ci/changelog/templates/changes_runtime.md.tera b/polkadot/scripts/ci/changelog/templates/changes_runtime.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..bd126c0628c4089ddc8eee8cde345b4234c2ef0d --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/changes_runtime.md.tera @@ -0,0 +1,19 @@ +{%- import "change.md.tera" as m_c -%} + +### Runtime + +{#- The changes are sorted by merge date -#} +{% for pr in changes | sort(attribute="merged_at") -%} + +{%- if pr.meta.B -%} +{%- if pr.meta.B.B0 -%} +{#- We skip silent ones -#} +{%- else -%} + +{%- if pr.meta.T and pr.meta.T.T1 and not pr.title is containing("ompanion") %} +- {{ m_c::change(c=pr) }} +{%- endif -%} +{%- endif -%} + +{%- endif -%} +{%- endfor %} diff --git a/polkadot/scripts/ci/changelog/templates/compiler.md.tera b/polkadot/scripts/ci/changelog/templates/compiler.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..6fa1baa6506197768fb1ac82b1961daa8ac5f9fa --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/compiler.md.tera @@ -0,0 +1,7 @@ +## Rust compiler versions + +This release was built and tested against the following versions of `rustc`. +Other versions may work. + +- Rust Stable: `{{ env.RUSTC_STABLE }}` +- Rust Nightly: `{{ env.RUSTC_NIGHTLY }}` diff --git a/polkadot/scripts/ci/changelog/templates/debug.md.tera b/polkadot/scripts/ci/changelog/templates/debug.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..8c829b09ffe2b1d7ba91d6e6ba43f80701efe558 --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/debug.md.tera @@ -0,0 +1,8 @@ +{%- set to_ignore = changes | filter(attribute="meta.B.B0") %} + + diff --git a/polkadot/scripts/ci/changelog/templates/docker_image.md.tera b/polkadot/scripts/ci/changelog/templates/docker_image.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..4a3793a86ad2450fd16096b08ba39097cd5dfb63 --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/docker_image.md.tera @@ -0,0 +1,11 @@ + +## Docker image + +The docker image for this release can be found at [Docker hub](https://hub.docker.com/r/parity/polkadot/tags?page=1&ordering=last_updated) +(It will be available a few minutes after the release has been published). + +You may pull it using: + +``` +docker pull parity/polkadot:latest +``` diff --git a/polkadot/scripts/ci/changelog/templates/full_pr_list.md.tera b/polkadot/scripts/ci/changelog/templates/full_pr_list.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..1cdab310652fc9bd42ce08d51c94ce7286c3b2f8 --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/full_pr_list.md.tera @@ -0,0 +1,16 @@ +{# This is a helper template to get the FULL PR list #} +{# It is not used in the release notes #} + +# PR list + +## substrate + +{%- for change in substrate.changes %} + - [S] [`{{ change.number }}`]({{ change.html_url }}) - {{ change.title }} +{%- endfor %} + +## polkadot + +{%- for change in polkadot.changes %} + - [P] [`{{ change.number }}`]({{ change.html_url }}) - {{ change.title }} +{%- endfor %} diff --git a/polkadot/scripts/ci/changelog/templates/global_priority.md.tera b/polkadot/scripts/ci/changelog/templates/global_priority.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..fe3d634f19dd1393e32ee8ad9f97f3f5419d688a --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/global_priority.md.tera @@ -0,0 +1,22 @@ +{% import "high_priority.md.tera" as m_p -%} +## Upgrade Priority + +{%- set polkadot_prio = 0 -%} +{%- set substrate_prio = 0 -%} + +{# We fetch the various priorities #} +{%- if polkadot.meta.C -%} + {%- set polkadot_prio = polkadot.meta.C.max -%} +{%- endif -%} +{%- if substrate.meta.C -%} + {%- set substrate_prio = substrate.meta.C.max -%} +{%- endif -%} + +{# We compute the global priority #} +{%- set global_prio = polkadot_prio -%} +{%- if substrate_prio > global_prio -%} + {%- set global_prio = substrate_prio -%} +{%- endif -%} + +{#- We show the result #} +{{ m_p::high_priority(p=global_prio, changes=changes) }} diff --git a/polkadot/scripts/ci/changelog/templates/high_priority.md.tera b/polkadot/scripts/ci/changelog/templates/high_priority.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..39938da44d172e4755cf9dde57ec2cfdf8ebc618 --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/high_priority.md.tera @@ -0,0 +1,38 @@ +{%- import "change.md.tera" as m_c -%} + +{# This macro convert a priority level into readable output #} +{%- macro high_priority(p, changes) -%} + +{%- if p >= 7 -%} + {%- set prio = "‼️ HIGH" -%} + {%- set text = "This is a **high priority** release and you must upgrade as as soon as possible." -%} +{%- elif p >= 3 -%} + {%- set prio = "❗️ Medium" -%} + {%- set text = "This is a medium priority release and you should upgrade in a timely manner." -%} +{%- else -%} + {%- set prio = "Low" -%} + {%- set text = "This is a low priority release and you may upgrade at your convenience." -%} +{%- endif %} + + + +{%- if prio %} +{{prio}}: {{text}} + +{% if p >= 3 %} +The changes motivating this priority level are: +{% for pr in changes | sort(attribute="merged_at") -%} + {%- if pr.meta.C -%} + {%- if pr.meta.C.agg.max >= p %} +- {{ m_c::change(c=pr) }} +{%- if pr.meta.T and pr.meta.T.T1 %} (RUNTIME) +{% endif %} + {%- endif -%} + {%- endif -%} +{%- endfor -%} +{%- else -%} + +{%- endif -%} +{%- endif -%} + +{%- endmacro priority -%} diff --git a/polkadot/scripts/ci/changelog/templates/host_functions-list.md.tera b/polkadot/scripts/ci/changelog/templates/host_functions-list.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..954d41e40d3b6f962432495aecd0917dcffc8ad3 --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/host_functions-list.md.tera @@ -0,0 +1,12 @@ +{%- import "change.md.tera" as m_c -%} + +{% for pr in changes | sort(attribute="merged_at") -%} + +{%- if pr.meta.B and pr.meta.B.B0 -%} +{#- We skip silent ones -#} +{%- else -%} + {%- if pr.meta.E and pr.meta.E.E3 -%} +- {{ m_c::change(c=pr) }} + {% endif -%} +{% endif -%} +{%- endfor -%} diff --git a/polkadot/scripts/ci/changelog/templates/host_functions.md.tera b/polkadot/scripts/ci/changelog/templates/host_functions.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..e38bc5d71828d066e1f4b2efd96f588cf46606bf --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/host_functions.md.tera @@ -0,0 +1,44 @@ +{%- import "change.md.tera" as m_c -%} + +{%- set_global host_fn_count = 0 -%} +{%- set_global upgrade_first = 0 -%} + +{% for pr in changes | sort(attribute="merged_at") -%} + +{%- if pr.meta.B and pr.meta.B.B0 -%} +{#- We skip silent ones -#} +{%- else -%} + {%- if pr.meta.E and pr.meta.E.E3 -%} + {%- set_global host_fn_count = host_fn_count + 1 -%} + - {{ m_c::change(c=pr) }} + {% endif -%} + {%- if pr.meta.E and pr.meta.E.E4 -%} + {%- set_global upgrade_first = upgrade_first + 1 -%} + - {{ m_c::change(c=pr) }} + {% endif -%} +{% endif -%} +{%- endfor -%} + + + +{%- if upgrade_first != 0 %} +## Node upgrade required +⚠️ There is a runtime change that will require nodes to be upgraded BEFORE the runtime upgrade. + +⚠️ It is critical that you update your client before the chain switches to the new runtime. +{%- endif %} + + + +## Host functions + +{% if host_fn_count == 0 %} +ℹ️ This release does not contain any change related to host functions. +{% elif host_fn_count == 1 -%} +{# ---- #} +ℹ️ The runtimes in this release contain one change related to **host function**s: +{% include "host_functions-list.md.tera" -%} +{%- else -%} +ℹ️ The runtimes in this release contain {{ host_fn_count }} changes related to **host function**s: +{% include "host_functions-list.md.tera" -%} +{%- endif %} diff --git a/polkadot/scripts/ci/changelog/templates/migrations-db.md.tera b/polkadot/scripts/ci/changelog/templates/migrations-db.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..130a61a12cb2a2fb35bec99fd395609612a10b3e --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/migrations-db.md.tera @@ -0,0 +1,30 @@ +{% import "change.md.tera" as m_c %} +{%- set_global db_migration_count = 0 -%} +{%- for pr in changes -%} + {%- if pr.meta.B and pr.meta.B.B0 %} + {#- We skip silent ones -#} + {%- elif pr.meta.E and pr.meta.E.E1 -%} + {%- set_global db_migration_count = db_migration_count + 1 -%} + {%- endif -%} +{%- endfor %} + +## Database Migrations + +Database migrations are operations upgrading the database to the latest stand. +Some migrations may break compatibility, making a backup of your database is highly recommended. + +{% if db_migration_count == 0 -%} +ℹ️ There is no database migration in this release. +{%- elif db_migration_count == 1 -%} +⚠️ There is one database migration in this release: +{%- else -%} +⚠️ There are {{ db_migration_count }} database migrations in this release: +{%- endif %} +{% for pr in changes | sort(attribute="merged_at") -%} + +{%- if pr.meta.B and pr.meta.B.B0 %} +{#- We skip silent ones -#} +{%- elif pr.meta.E and pr.meta.E.E1 -%} +- {{ m_c::change(c=pr) }} +{% endif -%} +{% endfor -%} diff --git a/polkadot/scripts/ci/changelog/templates/migrations-runtime.md.tera b/polkadot/scripts/ci/changelog/templates/migrations-runtime.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..25517a142eb390e9aab19f34a2b3781ed994056c --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/migrations-runtime.md.tera @@ -0,0 +1,29 @@ +{%- import "change.md.tera" as m_c %} +{%- set_global runtime_migration_count = 0 -%} +{%- for pr in changes -%} + {%- if pr.meta.B and pr.meta.B.B0 %} + {#- We skip silent ones -#} + {%- elif pr.meta.E and pr.meta.E.E0 -%} + {%- set_global runtime_migration_count = runtime_migration_count + 1 -%} + {%- endif -%} +{%- endfor %} + +## Runtime Migrations + +Runtime migrations are operations running once during a runtime upgrade. + +{% if runtime_migration_count == 0 -%} +ℹ️ There is no runtime migration in this release. +{%- elif runtime_migration_count == 1 -%} +⚠️ There is one runtime migration in this release: +{%- else -%} +⚠️ There are {{ runtime_migration_count }} runtime migrations in this release: +{%- endif %} +{% for pr in changes | sort(attribute="merged_at") -%} + +{%- if pr.meta.B and pr.meta.B.B0 %} +{#- We skip silent ones -#} +{%- elif pr.meta.E and pr.meta.E.E0 -%} +- {{ m_c::change(c=pr) }} +{% endif -%} +{% endfor -%} diff --git a/polkadot/scripts/ci/changelog/templates/pre_release.md.tera b/polkadot/scripts/ci/changelog/templates/pre_release.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..7d4ad42dd8fe9ba42f9d5d1f98ec80d70445b28b --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/pre_release.md.tera @@ -0,0 +1,11 @@ +{%- if env.PRE_RELEASE == "true" -%} +
⚠️ This is a pre-release + +**Release candidates** are **pre-releases** and may not be final. +Although they are reasonably tested, there may be additional changes or issues +before an official release is tagged. Use at your own discretion, and consider +only using final releases on critical production infrastructure. +
+{% else -%} + +{%- endif %} diff --git a/polkadot/scripts/ci/changelog/templates/runtime.md.tera b/polkadot/scripts/ci/changelog/templates/runtime.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..cd7edf28f7a3eabb0767ae54087fb29fa2bc406e --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/runtime.md.tera @@ -0,0 +1,28 @@ +{# This macro shows one runtime #} +{%- macro runtime(runtime) -%} + +### {{ runtime.name | capitalize }} + +{%- if runtime.data.runtimes.compressed.subwasm.compression.compressed %} +{%- set compressed = "Yes" %} +{%- else %} +{%- set compressed = "No" %} +{%- endif %} + +{%- set comp_ratio = 100 - (runtime.data.runtimes.compressed.subwasm.compression.size_compressed / runtime.data.runtimes.compressed.subwasm.compression.size_decompressed *100) %} + + + + + +``` +🏋️ Runtime Size: {{ runtime.data.runtimes.compressed.subwasm.size | filesizeformat }} ({{ runtime.data.runtimes.compressed.subwasm.size }} bytes) +🔥 Core Version: {{ runtime.data.runtimes.compressed.subwasm.core_version.specName }}-{{ runtime.data.runtimes.compressed.subwasm.core_version.specVersion }} ({{ runtime.data.runtimes.compressed.subwasm.core_version.implName }}-{{ runtime.data.runtimes.compressed.subwasm.core_version.implVersion }}.tx{{ runtime.data.runtimes.compressed.subwasm.core_version.transactionVersion }}.au{{ runtime.data.runtimes.compressed.subwasm.core_version.authoringVersion }}) +🗜 Compressed: {{ compressed }}: {{ comp_ratio | round(method="ceil", precision=2) }}% +🎁 Metadata version: V{{ runtime.data.runtimes.compressed.subwasm.metadata_version }} +🗳️ system.setCode hash: {{ runtime.data.runtimes.compressed.subwasm.proposal_hash }} +🗳️ authorizeUpgrade hash: {{ runtime.data.runtimes.compressed.subwasm.parachain_authorize_upgrade_hash }} +🗳️ Blake2-256 hash: {{ runtime.data.runtimes.compressed.subwasm.blake2_256 }} +📦 IPFS: {{ runtime.data.runtimes.compressed.subwasm.ipfs_hash }} +``` +{%- endmacro runtime %} diff --git a/polkadot/scripts/ci/changelog/templates/runtimes.md.tera b/polkadot/scripts/ci/changelog/templates/runtimes.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..0847382689fb5336eeedeb1fbb712d317797efcb --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/runtimes.md.tera @@ -0,0 +1,19 @@ +{# This include shows the list and details of the runtimes #} +{%- import "runtime.md.tera" as m_r -%} + +{# --- #} + +## Runtimes + +{% set rtm = srtool[0] -%} + +The information about the runtimes included in this release can be found below. +The runtimes have been built using [{{ rtm.data.gen }}](https://github.com/paritytech/srtool) and `{{ rtm.data.rustc }}`. + +{%- for runtime in srtool | sort(attribute="name") %} +{%- set HIDE_VAR = "HIDE_SRTOOL_" ~ runtime.name | upper %} +{%- if not env is containing(HIDE_VAR) %} + +{{ m_r::runtime(runtime=runtime) }} +{%- endif %} +{%- endfor %} diff --git a/polkadot/scripts/ci/changelog/templates/template.md.tera b/polkadot/scripts/ci/changelog/templates/template.md.tera new file mode 100644 index 0000000000000000000000000000000000000000..e04636b4b2277418790376535e39b189c12ce496 --- /dev/null +++ b/polkadot/scripts/ci/changelog/templates/template.md.tera @@ -0,0 +1,37 @@ +{# This is the entry point of the template -#} + +{% include "pre_release.md.tera" -%} + +{% if env.PRE_RELEASE == "true" -%} +This pre-release contains the changes from `{{ env.REF1 | replace(from="refs/tags/", to="") }}` to `{{ env.REF2 | replace(from="refs/tags/", to="") }}`. +{%- else -%} +This release contains the changes from `{{ env.REF1 | replace(from="refs/tags/", to="") }}` to `{{ env.REF2 | replace(from="refs/tags/", to="") }}`. +{% endif -%} + +{%- set changes = polkadot.changes | concat(with=substrate.changes) -%} +{%- include "debug.md.tera" -%} + +{%- set CML = "[C]" -%} +{%- set DOT = "[P]" -%} +{%- set SUB = "[S]" -%} + +{# -- Manual free notes section -- #} +{% include "_free_notes.md.tera" -%} + +{# -- Important automatic section -- #} +{% include "global_priority.md.tera" -%} + +{% include "host_functions.md.tera" -%} + +{% include "migrations-db.md.tera" -%} + +{% include "migrations-runtime.md.tera" -%} +{# --------------------------------- #} + +{% include "compiler.md.tera" -%} + +{% include "runtimes.md.tera" -%} + +{% include "changes.md.tera" -%} + +{% include "docker_image.md.tera" -%} diff --git a/polkadot/scripts/ci/changelog/test/test_basic.rb b/polkadot/scripts/ci/changelog/test/test_basic.rb new file mode 100644 index 0000000000000000000000000000000000000000..d099fadca43328d034cf753046274414b141888b --- /dev/null +++ b/polkadot/scripts/ci/changelog/test/test_basic.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require_relative '../lib/changelog' +require 'test/unit' + +class TestChangelog < Test::Unit::TestCase + def test_get_dep_ref_polkadot + c = SubRef.new('paritytech/polkadot') + ref = '13c2695' + package = 'sc-cli' + result = c.get_dependency_reference(ref, package) + assert_equal('7db0768a85dc36a3f2a44d042b32f3715c00a90d', result) + end + + def test_get_dep_ref_invalid_ref + c = SubRef.new('paritytech/polkadot') + ref = '9999999' + package = 'sc-cli' + assert_raise do + c.get_dependency_reference(ref, package) + end + end +end diff --git a/polkadot/scripts/ci/common/lib.sh b/polkadot/scripts/ci/common/lib.sh new file mode 100755 index 0000000000000000000000000000000000000000..e490ec22d5bf4f845c6c662122f8849b0f39d534 --- /dev/null +++ b/polkadot/scripts/ci/common/lib.sh @@ -0,0 +1,265 @@ +#!/bin/sh + +api_base="https://api.github.com/repos" + +# Function to take 2 git tags/commits and get any lines from commit messages +# that contain something that looks like a PR reference: e.g., (#1234) +sanitised_git_logs(){ + git --no-pager log --pretty=format:"%s" "$1...$2" | + # Only find messages referencing a PR + grep -E '\(#[0-9]+\)' | + # Strip any asterisks + sed 's/^* //g' +} + +# Checks whether a tag on github has been verified +# repo: 'organization/repo' +# tagver: 'v1.2.3' +# Usage: check_tag $repo $tagver +check_tag () { + repo=$1 + tagver=$2 + if [ -n "$GITHUB_RELEASE_TOKEN" ]; then + echo '[+] Fetching tag using privileged token' + tag_out=$(curl -H "Authorization: token $GITHUB_RELEASE_TOKEN" -s "$api_base/$repo/git/refs/tags/$tagver") + else + echo '[+] Fetching tag using unprivileged token' + tag_out=$(curl -H "Authorization: token $GITHUB_PR_TOKEN" -s "$api_base/$repo/git/refs/tags/$tagver") + fi + tag_sha=$(echo "$tag_out" | jq -r .object.sha) + object_url=$(echo "$tag_out" | jq -r .object.url) + if [ "$tag_sha" = "null" ]; then + return 2 + fi + echo "[+] Tag object SHA: $tag_sha" + verified_str=$(curl -H "Authorization: token $GITHUB_RELEASE_TOKEN" -s "$object_url" | jq -r .verification.verified) + if [ "$verified_str" = "true" ]; then + # Verified, everything is good + return 0 + else + # Not verified. Bad juju. + return 1 + fi +} + +# Checks whether a given PR has a given label. +# repo: 'organization/repo' +# pr_id: 12345 +# label: B1-silent +# Usage: has_label $repo $pr_id $label +has_label(){ + repo="$1" + pr_id="$2" + label="$3" + + # These will exist if the function is called in Gitlab. + # If the function's called in Github, we should have GITHUB_ACCESS_TOKEN set + # already. + if [ -n "$GITHUB_RELEASE_TOKEN" ]; then + GITHUB_TOKEN="$GITHUB_RELEASE_TOKEN" + elif [ -n "$GITHUB_PR_TOKEN" ]; then + GITHUB_TOKEN="$GITHUB_PR_TOKEN" + fi + + out=$(curl -H "Authorization: token $GITHUB_TOKEN" -s "$api_base/$repo/pulls/$pr_id") + [ -n "$(echo "$out" | tr -d '\r\n' | jq ".labels | .[] | select(.name==\"$label\")")" ] +} + +github_label () { + echo + echo "# run github-api job for labeling it ${1}" + curl -sS -X POST \ + -F "token=${CI_JOB_TOKEN}" \ + -F "ref=master" \ + -F "variables[LABEL]=${1}" \ + -F "variables[PRNO]=${CI_COMMIT_REF_NAME}" \ + -F "variables[PROJECT]=paritytech/polkadot" \ + "${GITLAB_API}/projects/${GITHUB_API_PROJECT}/trigger/pipeline" +} + +# Formats a message into a JSON string for posting to Matrix +# message: 'any plaintext message' +# formatted_message: 'optional message formatted in html' +# Usage: structure_message $content $formatted_content (optional) +structure_message() { + if [ -z "$2" ]; then + body=$(jq -Rs --arg body "$1" '{"msgtype": "m.text", $body}' < /dev/null) + else + body=$(jq -Rs --arg body "$1" --arg formatted_body "$2" '{"msgtype": "m.text", $body, "format": "org.matrix.custom.html", $formatted_body}' < /dev/null) + fi + echo "$body" +} + +# Post a message to a matrix room +# body: '{body: "JSON string produced by structure_message"}' +# room_id: !fsfSRjgjBWEWffws:matrix.parity.io +# access_token: see https://matrix.org/docs/guides/client-server-api/ +# Usage: send_message $body (json formatted) $room_id $access_token +send_message() { + curl -XPOST -d "$1" "https://m.parity.io/_matrix/client/r0/rooms/$2/send/m.room.message?access_token=$3" +} + +# Pretty-printing functions +boldprint () { printf "|\n| \033[1m%s\033[0m\n|\n" "${@}"; } +boldcat () { printf "|\n"; while read -r l; do printf "| \033[1m%s\033[0m\n" "${l}"; done; printf "|\n" ; } + +skip_if_companion_pr() { + url="https://api.github.com/repos/paritytech/polkadot/pulls/${CI_COMMIT_REF_NAME}" + echo "[+] API URL: $url" + + pr_title=$(curl -sSL -H "Authorization: token ${GITHUB_PR_TOKEN}" "$url" | jq -r .title) + echo "[+] PR title: $pr_title" + + if echo "$pr_title" | grep -qi '^companion'; then + echo "[!] PR is a companion PR. Build is already done in substrate" + exit 0 + else + echo "[+] PR is not a companion PR. Proceeding test" + fi +} + +# Fetches the tag name of the latest release from a repository +# repo: 'organisation/repo' +# Usage: latest_release 'paritytech/polkadot' +latest_release() { + curl -s "$api_base/$1/releases/latest" | jq -r '.tag_name' +} + +# Check for runtime changes between two commits. This is defined as any changes +# to /primitives/src/* and any *production* chains under /runtime +has_runtime_changes() { + from=$1 + to=$2 + + if git diff --name-only "${from}...${to}" \ + | grep -q -e '^runtime/polkadot' -e '^runtime/kusama' -e '^primitives/src/' -e '^runtime/common' + then + return 0 + else + return 1 + fi +} + +# given a bootnode and the path to a chainspec file, this function will create a new chainspec file +# with only the bootnode specified and test whether that bootnode provides peers +# The optional third argument is the index of the bootnode in the list of bootnodes, this is just used to pick an ephemeral +# port for the node to run on. If you're only testing one, it'll just use the first ephemeral port +# BOOTNODE: /dns/polkadot-connect-0.parity.io/tcp/443/wss/p2p/12D3KooWEPmjoRpDSUuiTjvyNDd8fejZ9eNWH5bE965nyBMDrB4o +# CHAINSPEC_FILE: /path/to/polkadot.json +check_bootnode(){ + BOOTNODE=$1 + BASE_CHAINSPEC=$2 + RUNTIME=$(basename "$BASE_CHAINSPEC" | cut -d '.' -f 1) + MIN_PEERS=1 + + # Generate a temporary chainspec file containing only the bootnode we care about + TMP_CHAINSPEC_FILE="$RUNTIME.$(echo "$BOOTNODE" | tr '/' '_').tmp.json" + jq ".bootNodes = [\"$BOOTNODE\"] " < "$CHAINSPEC_FILE" > "$TMP_CHAINSPEC_FILE" + + # Grab an unused port by binding to port 0 and then immediately closing the socket + # This is a bit of a hack, but it's the only way to do it in the shell + RPC_PORT=$(python -c "import socket; s=socket.socket(); s.bind(('', 0)); print(s.getsockname()[1]); s.close()") + + echo "[+] Checking bootnode $BOOTNODE" + polkadot --chain "$TMP_CHAINSPEC_FILE" --no-mdns --rpc-port="$RPC_PORT" --tmp > /dev/null 2>&1 & + # Wait a few seconds for the node to start up + sleep 5 + POLKADOT_PID=$! + + MAX_POLLS=10 + TIME_BETWEEN_POLLS=3 + for _ in $(seq 1 "$MAX_POLLS"); do + # Check the health endpoint of the RPC node + PEERS="$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"system_health","params":[],"id":1}' http://localhost:"$RPC_PORT" | jq -r '.result.peers')" + # Sometimes due to machine load or other reasons, we don't get a response from the RPC node + # If $PEERS is an empty variable, make it 0 so we can still do the comparison + if [ -z "$PEERS" ]; then + PEERS=0 + fi + if [ "$PEERS" -ge $MIN_PEERS ]; then + echo "[+] $PEERS peers found for $BOOTNODE" + echo " Bootnode appears contactable" + kill $POLKADOT_PID + # Delete the temporary chainspec file now we're done running the node + rm "$TMP_CHAINSPEC_FILE" + return 0 + fi + sleep "$TIME_BETWEEN_POLLS" + done + kill $POLKADOT_PID + # Delete the temporary chainspec file now we're done running the node + rm "$TMP_CHAINSPEC_FILE" + echo "[!] No peers found for $BOOTNODE" + echo " Bootnode appears unreachable" + return 1 +} + +# Assumes the ENV are set: +# - RELEASE_ID +# - GITHUB_TOKEN +# - REPO in the form paritytech/polkadot +fetch_release_artifacts() { + echo "Release ID : $RELEASE_ID" + echo "Repo : $REPO" + + curl -L -s \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${GITHUB_TOKEN}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${REPO}/releases/${RELEASE_ID} > release.json + + # Get Asset ids + ids=($(jq -r '.assets[].id' < release.json )) + count=$(jq '.assets|length' < release.json ) + + # Fetch artifacts + mkdir -p "./release-artifacts" + pushd "./release-artifacts" > /dev/null + + iter=1 + for id in "${ids[@]}" + do + echo " - $iter/$count: downloading asset id: $id..." + curl -s -OJ -L -H "Accept: application/octet-stream" \ + -H "Authorization: Token ${GITHUB_TOKEN}" \ + "https://api.github.com/repos/${REPO}/releases/assets/$id" + iter=$((iter + 1)) + done + + pwd + ls -al --color + popd > /dev/null +} + +# Check the checksum for a given binary +function check_sha256() { + echo "Checking SHA256 for $1" + shasum -qc $1.sha256 +} + +# Import GPG keys of the release team members +# This is done in parallel as it can take a while sometimes +function import_gpg_keys() { + GPG_KEYSERVER=${GPG_KEYSERVER:-"keyserver.ubuntu.com"} + SEC="9D4B2B6EB8F97156D19669A9FF0812D491B96798" + WILL="2835EAF92072BC01D188AF2C4A092B93E97CE1E2" + EGOR="E6FC4D4782EB0FA64A4903CCDB7D3555DD3932D3" + MARA="533C920F40E73A21EEB7E9EBF27AEA7E7594C9CF" + MORGAN="2E92A9D8B15D7891363D1AE8AF9E6C43F7F8C4CF" + + echo "Importing GPG keys from $GPG_KEYSERVER in parallel" + for key in $SEC $WILL $EGOR $MARA $MORGAN; do + ( + echo "Importing GPG key $key" + gpg --no-tty --quiet --keyserver $GPG_KEYSERVER --recv-keys $key + echo -e "5\ny\n" | gpg --no-tty --command-fd 0 --expert --edit-key $key trust; + ) & + done + wait +} + +# Check the GPG signature for a given binary +function check_gpg() { + echo "Checking GPG Signature for $1" + gpg --no-tty --verify -q $1.asc $1 +} diff --git a/polkadot/scripts/ci/dockerfiles/adder-collator/build-injected.sh b/polkadot/scripts/ci/dockerfiles/adder-collator/build-injected.sh new file mode 100755 index 0000000000000000000000000000000000000000..9a1857bc7ab4714d01d5cc337d5444bf85916449 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/adder-collator/build-injected.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Sample call: +# $0 /path/to/folder_with_binary +# This script replace the former dedicated Dockerfile +# and shows how to use the generic binary_injected.dockerfile + +PROJECT_ROOT=`git rev-parse --show-toplevel` + +export BINARY=adder-collator,undying-collator +export BIN_FOLDER=$1 + +$PROJECT_ROOT/scripts/ci/dockerfiles/build-injected.sh diff --git a/polkadot/scripts/ci/dockerfiles/adder-collator/test-build.sh b/polkadot/scripts/ci/dockerfiles/adder-collator/test-build.sh new file mode 100755 index 0000000000000000000000000000000000000000..171e0309f807971eaa79133f3de3b8d125787cbe --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/adder-collator/test-build.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +TMP=$(mktemp -d) +ENGINE=${ENGINE:-podman} + +# TODO: Switch to /bin/bash when the image is built from parity/base-bin + +# Fetch some binaries +$ENGINE run --user root --rm -i \ + --pull always \ + -v "$TMP:/export" \ + --entrypoint /usr/bin/bash \ + paritypr/colander:master -c \ + 'cp "$(which adder-collator)" /export' + +$ENGINE run --user root --rm -i \ + --pull always \ + -v "$TMP:/export" \ + --entrypoint /usr/bin/bash \ + paritypr/colander:master -c \ + 'cp "$(which undying-collator)" /export' + +./build-injected.sh $TMP diff --git a/polkadot/scripts/ci/dockerfiles/binary_injected.Dockerfile b/polkadot/scripts/ci/dockerfiles/binary_injected.Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..cee81a2eb8ae06412109d942b5ca3d322c0cdf1e --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/binary_injected.Dockerfile @@ -0,0 +1,48 @@ +FROM docker.io/parity/base-bin + +# This file allows building a Generic container image +# based on one or multiple pre-built Linux binaries. +# Some defaults are set to polkadot but all can be overriden. + +SHELL ["/bin/bash", "-c"] + +# metadata +ARG VCS_REF +ARG BUILD_DATE +ARG IMAGE_NAME + +# That can be a single one or a comma separated list +ARG BINARY=polkadot + +ARG BIN_FOLDER=. +ARG DOC_URL=https://github.com/paritytech/polkadot +ARG DESCRIPTION="Polkadot: a platform for web3" +ARG AUTHORS="devops-team@parity.io" +ARG VENDOR="Parity Technologies" + +LABEL io.parity.image.authors=${AUTHORS} \ + io.parity.image.vendor="${VENDOR}" \ + io.parity.image.revision="${VCS_REF}" \ + io.parity.image.title="${IMAGE_NAME}" \ + io.parity.image.created="${BUILD_DATE}" \ + io.parity.image.documentation="${DOC_URL}" \ + io.parity.image.description="${DESCRIPTION}" \ + io.parity.image.source="https://github.com/paritytech/polkadot/blob/${VCS_REF}/scripts/ci/dockerfiles/binary_injected.Dockerfile" + +USER root +WORKDIR /app + +# add polkadot binary to docker image +# sample for polkadot: COPY ./polkadot ./polkadot-*-worker /usr/local/bin/ +COPY entrypoint.sh . +COPY "bin/*" "/usr/local/bin/" +RUN chmod -R a+rx "/usr/local/bin" + +USER parity +ENV BINARY=${BINARY} + +# ENTRYPOINT +ENTRYPOINT ["/app/entrypoint.sh"] + +# We call the help by default +CMD ["--help"] diff --git a/polkadot/scripts/ci/dockerfiles/build-injected.sh b/polkadot/scripts/ci/dockerfiles/build-injected.sh new file mode 100755 index 0000000000000000000000000000000000000000..d0e7fee3646e439343767b8d5ee4645f0061412f --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/build-injected.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +set -e + +# This script allows building a Container Image from a Linux +# binary that is injected into a base-image. + +ENGINE=${ENGINE:-podman} + +if [ "$ENGINE" == "podman" ]; then + PODMAN_FLAGS="--format docker" +else + PODMAN_FLAGS="" +fi + +CONTEXT=$(mktemp -d) +REGISTRY=${REGISTRY:-docker.io} + +# The following line ensure we know the project root +PROJECT_ROOT=${PROJECT_ROOT:-$(git rev-parse --show-toplevel)} +DOCKERFILE=${DOCKERFILE:-$PROJECT_ROOT/scripts/ci/dockerfiles/binary_injected.Dockerfile} +VERSION_TOML=$(grep "^version " $PROJECT_ROOT/Cargo.toml | grep -oE "([0-9\.]+-?[0-9]+)") + +#n The following VAR have default that can be overriden +DOCKER_OWNER=${DOCKER_OWNER:-parity} + +# We may get 1..n binaries, comma separated +BINARY=${BINARY:-polkadot} +IFS=',' read -r -a BINARIES <<< "$BINARY" + +VERSION=${VERSION:-$VERSION_TOML} +BIN_FOLDER=${BIN_FOLDER:-.} + +IMAGE=${IMAGE:-${REGISTRY}/${DOCKER_OWNER}/${BINARIES[0]}} +DESCRIPTION_DEFAULT="Injected Container image built for ${BINARY}" +DESCRIPTION=${DESCRIPTION:-$DESCRIPTION_DEFAULT} + +VCS_REF=${VCS_REF:-01234567} + +# Build the image +echo "Using engine: $ENGINE" +echo "Using Dockerfile: $DOCKERFILE" +echo "Using context: $CONTEXT" +echo "Building ${IMAGE}:latest container image for ${BINARY} v${VERSION} from ${BIN_FOLDER} hang on!" +echo "BIN_FOLDER=$BIN_FOLDER" +echo "CONTEXT=$CONTEXT" + +# We need all binaries and resources available in the Container build "CONTEXT" +mkdir -p $CONTEXT/bin +for bin in "${BINARIES[@]}" +do + echo "Copying $BIN_FOLDER/$bin to context: $CONTEXT/bin" + cp "$BIN_FOLDER/$bin" "$CONTEXT/bin" +done + +cp "$PROJECT_ROOT/scripts/ci/dockerfiles/entrypoint.sh" "$CONTEXT" + +echo "Building image: ${IMAGE}" + +TAGS=${TAGS[@]:-latest} +IFS=',' read -r -a TAG_ARRAY <<< "$TAGS" +TAG_ARGS=" " + +echo "The image ${IMAGE} will be tagged with ${TAG_ARRAY[*]}" +for tag in "${TAG_ARRAY[@]}"; do + TAG_ARGS+="--tag ${IMAGE}:${tag} " +done + +echo "$TAG_ARGS" + +# time \ +$ENGINE build \ + ${PODMAN_FLAGS} \ + --build-arg VCS_REF="${VCS_REF}" \ + --build-arg BUILD_DATE=$(date -u '+%Y-%m-%dT%H:%M:%SZ') \ + --build-arg IMAGE_NAME="${IMAGE}" \ + --build-arg BINARY="${BINARY}" \ + --build-arg BIN_FOLDER="${BIN_FOLDER}" \ + --build-arg DESCRIPTION="${DESCRIPTION}" \ + ${TAG_ARGS} \ + -f "${DOCKERFILE}" \ + ${CONTEXT} + +echo "Your Container image for ${IMAGE} is ready" +$ENGINE images + +if [[ -z "${SKIP_IMAGE_VALIDATION}" ]]; then + echo "Check the image ${IMAGE}:${TAG_ARRAY[0]}" + $ENGINE run --rm -i "${IMAGE}:${TAG_ARRAY[0]}" --version + + echo "Query binaries" + $ENGINE run --rm -i --entrypoint /bin/bash "${IMAGE}:${TAG_ARRAY[0]}" -c 'echo BINARY: $BINARY' +fi diff --git a/polkadot/scripts/ci/dockerfiles/entrypoint.sh b/polkadot/scripts/ci/dockerfiles/entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..eaa815faf6a45307047f07768826aa44f71afac0 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/entrypoint.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +# Sanity check +if [ -z "$BINARY" ] +then + echo "BINARY ENV not defined, this should never be the case. Aborting..." + exit 1 +fi + +# If the user built the image with multiple binaries, +# we consider the first one to be the canonical one +# To start with another binary, the user can either: +# - use the --entrypoint option +# - pass the ENV BINARY with a single binary +IFS=',' read -r -a BINARIES <<< "$BINARY" +BIN0=${BINARIES[0]} +echo "Starting binary $BIN0" +$BIN0 $@ diff --git a/polkadot/scripts/ci/dockerfiles/malus/build-injected.sh b/polkadot/scripts/ci/dockerfiles/malus/build-injected.sh new file mode 100755 index 0000000000000000000000000000000000000000..99bd5fde1d5a87dec433a9662575eaf31f1ccf54 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/malus/build-injected.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Sample call: +# $0 /path/to/folder_with_binary +# This script replace the former dedicated Dockerfile +# and shows how to use the generic binary_injected.dockerfile + +PROJECT_ROOT=`git rev-parse --show-toplevel` + +export BINARY=malus,polkadot-execute-worker,polkadot-prepare-worker +export BIN_FOLDER=$1 +# export TAGS=... + +$PROJECT_ROOT/scripts/ci/dockerfiles/build-injected.sh diff --git a/polkadot/scripts/ci/dockerfiles/malus/test-build.sh b/polkadot/scripts/ci/dockerfiles/malus/test-build.sh new file mode 100755 index 0000000000000000000000000000000000000000..3114e9e2adf12c84663568f5fddf91e690621287 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/malus/test-build.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +TMP=$(mktemp -d) +ENGINE=${ENGINE:-podman} + +export TAGS=latest,beta,7777,1.0.2-rc23 + +# Fetch some binaries +$ENGINE run --user root --rm -i \ + --pull always \ + -v "$TMP:/export" \ + --entrypoint /bin/bash \ + paritypr/malus:7217 -c \ + 'cp "$(which malus)" /export' + +echo "Checking binaries we got:" +ls -al $TMP + +./build-injected.sh $TMP diff --git a/polkadot/scripts/ci/dockerfiles/polkadot/README.md b/polkadot/scripts/ci/dockerfiles/polkadot/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e331d8984c2cee5e4b79a851809e303751e3bb57 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/polkadot/README.md @@ -0,0 +1,9 @@ +# Self built Docker image + +The Polkadot repo contains several options to build Docker images for Polkadot. + +This folder contains a self-contained image that does not require a Linux pre-built binary. + +Instead, building the image is possible on any host having docker installed and will +build Polkadot inside Docker. That also means that no Rust toolchain is required on the host +machine for the build to succeed. diff --git a/polkadot/scripts/ci/dockerfiles/polkadot/build-injected.sh b/polkadot/scripts/ci/dockerfiles/polkadot/build-injected.sh new file mode 100755 index 0000000000000000000000000000000000000000..22774c7b712244a79503ae96ae87a5fffb7315fd --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/polkadot/build-injected.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Sample call: +# $0 /path/to/folder_with_binary +# This script replace the former dedicated Dockerfile +# and shows how to use the generic binary_injected.dockerfile + +PROJECT_ROOT=`git rev-parse --show-toplevel` + +export BINARY=polkadot,polkadot-execute-worker,polkadot-prepare-worker +export BIN_FOLDER=$1 + +$PROJECT_ROOT/scripts/ci/dockerfiles/build-injected.sh diff --git a/polkadot/scripts/ci/dockerfiles/polkadot/docker-compose-local.yml b/polkadot/scripts/ci/dockerfiles/polkadot/docker-compose-local.yml new file mode 100644 index 0000000000000000000000000000000000000000..1ff3a1ccaac252b5c8e5230b4584329ce6448865 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/polkadot/docker-compose-local.yml @@ -0,0 +1,50 @@ +version: '3' +services: + node_alice: + ports: + - "30333:30333" + - "9933:9933" + - "9944:9944" + - "9615:9615" + image: parity/polkadot:latest + volumes: + - "polkadot-data-alice:/data" + command: | + --chain=polkadot-local + --alice + -d /data + --node-key 0000000000000000000000000000000000000000000000000000000000000001 + networks: + testing_net: + ipv4_address: 172.28.1.1 + + node_bob: + ports: + - "30344:30333" + - "9935:9933" + - "9945:9944" + - "29615:9615" + image: parity/polkadot:latest + volumes: + - "polkadot-data-bob:/data" + links: + - "node_alice:alice" + command: | + --chain=polkadot-local + --bob + -d /data + --bootnodes '/ip4/172.28.1.1/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR' + networks: + testing_net: + ipv4_address: 172.28.1.2 + +volumes: + polkadot-data-alice: + polkadot-data-bob: + +networks: + testing_net: + ipam: + driver: default + config: + - subnet: 172.28.0.0/16 diff --git a/polkadot/scripts/ci/dockerfiles/polkadot/docker-compose.yml b/polkadot/scripts/ci/dockerfiles/polkadot/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..524b1164796ac3f11f4fe30ec48a98e50e23c90f --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/polkadot/docker-compose.yml @@ -0,0 +1,22 @@ +version: '3' +services: + polkadot: + image: parity/polkadot:latest + + ports: + - "127.0.0.1:30333:30333/tcp" + - "127.0.0.1:9933:9933/tcp" + - "127.0.0.1:9944:9944/tcp" + - "127.0.0.1:9615:9615/tcp" + + volumes: + - "polkadot-data:/data" + + command: | + --unsafe-rpc-external + --unsafe-ws-external + --rpc-cors all + --prometheus-external + +volumes: + polkadot-data: diff --git a/polkadot/scripts/ci/dockerfiles/polkadot/polkadot_Dockerfile.README.md b/polkadot/scripts/ci/dockerfiles/polkadot/polkadot_Dockerfile.README.md new file mode 100644 index 0000000000000000000000000000000000000000..7e89cb55f3de5e016362cb50b5a5e5d0cc3e5713 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/polkadot/polkadot_Dockerfile.README.md @@ -0,0 +1,7 @@ +# Polkadot official Docker image + +## [Polkadot](https://polkadot.network/) + +## [GitHub](https://github.com/paritytech/polkadot) + +## [Polkadot Wiki](https://wiki.polkadot.network/) diff --git a/polkadot/scripts/ci/dockerfiles/polkadot/polkadot_builder.Dockerfile b/polkadot/scripts/ci/dockerfiles/polkadot/polkadot_builder.Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..f263c836bbfe780820b0da1a0387f1b6e72be46f --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/polkadot/polkadot_builder.Dockerfile @@ -0,0 +1,36 @@ +# This is the build stage for Polkadot. Here we create the binary in a temporary image. +FROM docker.io/paritytech/ci-linux:production as builder + +WORKDIR /polkadot +COPY . /polkadot + +RUN cargo build --locked --release + +# This is the 2nd stage: a very small image where we copy the Polkadot binary." +FROM docker.io/parity/base-bin:latest + +LABEL description="Multistage Docker image for Polkadot: a platform for web3" \ + io.parity.image.type="builder" \ + io.parity.image.authors="chevdor@gmail.com, devops-team@parity.io" \ + io.parity.image.vendor="Parity Technologies" \ + io.parity.image.description="Polkadot: a platform for web3" \ + io.parity.image.source="https://github.com/paritytech/polkadot/blob/${VCS_REF}/scripts/ci/dockerfiles/polkadot/polkadot_builder.Dockerfile" \ + io.parity.image.documentation="https://github.com/paritytech/polkadot/" + +COPY --from=builder /polkadot/target/release/polkadot /usr/local/bin + +RUN useradd -m -u 1000 -U -s /bin/sh -d /polkadot polkadot && \ + mkdir -p /data /polkadot/.local/share && \ + chown -R polkadot:polkadot /data && \ + ln -s /data /polkadot/.local/share/polkadot && \ +# unclutter and minimize the attack surface + rm -rf /usr/bin /usr/sbin && \ +# check if executable works in this container + /usr/local/bin/polkadot --version + +USER polkadot + +EXPOSE 30333 9933 9944 9615 +VOLUME ["/data"] + +ENTRYPOINT ["/usr/local/bin/polkadot"] diff --git a/polkadot/scripts/ci/dockerfiles/polkadot/polkadot_injected_debian.Dockerfile b/polkadot/scripts/ci/dockerfiles/polkadot/polkadot_injected_debian.Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..e2c72dcfe2e92411317ce86c0fb965b6246f52ea --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/polkadot/polkadot_injected_debian.Dockerfile @@ -0,0 +1,53 @@ +FROM docker.io/library/ubuntu:20.04 + +# metadata +ARG VCS_REF +ARG BUILD_DATE +ARG POLKADOT_VERSION +ARG POLKADOT_GPGKEY=9D4B2B6EB8F97156D19669A9FF0812D491B96798 +ARG GPG_KEYSERVER="keyserver.ubuntu.com" + +LABEL io.parity.image.authors="devops-team@parity.io" \ + io.parity.image.vendor="Parity Technologies" \ + io.parity.image.title="parity/polkadot" \ + io.parity.image.description="Polkadot: a platform for web3. This is the official Parity image with an injected binary." \ + io.parity.image.source="https://github.com/paritytech/polkadot/blob/${VCS_REF}/scripts/ci/dockerfiles/polkadot/polkadot_injected_debian.Dockerfile" \ + io.parity.image.revision="${VCS_REF}" \ + io.parity.image.created="${BUILD_DATE}" \ + io.parity.image.documentation="https://github.com/paritytech/polkadot/" + +# show backtraces +ENV RUST_BACKTRACE 1 + +# install tools and dependencies +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + libssl1.1 \ + ca-certificates \ + gnupg && \ + useradd -m -u 1000 -U -s /bin/sh -d /polkadot polkadot && \ +# add repo's gpg keys and install the published polkadot binary + gpg --keyserver ${GPG_KEYSERVER} --recv-keys ${POLKADOT_GPGKEY} && \ + gpg --export ${POLKADOT_GPGKEY} > /usr/share/keyrings/parity.gpg && \ + echo 'deb [signed-by=/usr/share/keyrings/parity.gpg] https://releases.parity.io/deb release main' > /etc/apt/sources.list.d/parity.list && \ + apt-get update && \ + apt-get install -y --no-install-recommends polkadot=${POLKADOT_VERSION#?} && \ +# apt cleanup + apt-get autoremove -y && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* ; \ + mkdir -p /data /polkadot/.local/share && \ + chown -R polkadot:polkadot /data && \ + ln -s /data /polkadot/.local/share/polkadot + +USER polkadot + +# check if executable works in this container +RUN /usr/bin/polkadot --version +RUN /usr/bin/polkadot-execute-worker --version +RUN /usr/bin/polkadot-prepare-worker --version + +EXPOSE 30333 9933 9944 +VOLUME ["/polkadot"] + +ENTRYPOINT ["/usr/bin/polkadot"] diff --git a/polkadot/scripts/ci/dockerfiles/polkadot/test-build.sh b/polkadot/scripts/ci/dockerfiles/polkadot/test-build.sh new file mode 100755 index 0000000000000000000000000000000000000000..d2d904561cb559d0dbb6d62e94cefa8d01213a06 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/polkadot/test-build.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +TMP=$(mktemp -d) +ENGINE=${ENGINE:-podman} + +# You need to build an injected image first + +# Fetch some binaries +$ENGINE run --user root --rm -i \ + -v "$TMP:/export" \ + --entrypoint /bin/bash \ + parity/polkadot -c \ + 'cp "$(which polkadot)" /export' + +echo "Checking binaries we got:" +tree $TMP + +./build-injected.sh $TMP diff --git a/polkadot/scripts/ci/dockerfiles/staking-miner/README.md b/polkadot/scripts/ci/dockerfiles/staking-miner/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3610e11303167b1b3b8deb4ef2a9c37a60c77a1f --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/staking-miner/README.md @@ -0,0 +1,37 @@ +# staking-miner container image + +## Build using the Builder + +``` +./build.sh +``` + +## Build the injected Image + +You first need a valid Linux binary to inject. Let's assume this binary is located in `BIN_FOLDER`. + +``` +./build-injected.sh "$BIN_FOLDER" +``` + +## Test + +Here is how to test the image. We can generate a valid seed but the staking-miner will quickly notice that our +account is not funded and "does not exist". + +You may pass any ENV supported by the binary and must provide at least a few such as `SEED` and `URI`: +``` +ENV SEED="" +ENV URI="wss://rpc.polkadot.io:443" +ENV RUST_LOG="info" +``` + +``` +export SEED=$(subkey generate -n polkadot --output-type json | jq -r .secretSeed) +podman run --rm -it \ + -e URI="wss://rpc.polkadot.io:443" \ + -e RUST_LOG="info" \ + -e SEED \ + localhost/parity/staking-miner \ + dry-run seq-phragmen +``` diff --git a/polkadot/scripts/ci/dockerfiles/staking-miner/build-injected.sh b/polkadot/scripts/ci/dockerfiles/staking-miner/build-injected.sh new file mode 100755 index 0000000000000000000000000000000000000000..536636df6a918d252af9db49bed0fed8b493d473 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/staking-miner/build-injected.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Sample call: +# $0 /path/to/folder_with_staking-miner_binary +# This script replace the former dedicated staking-miner "injected" Dockerfile +# and shows how to use the generic binary_injected.dockerfile + +PROJECT_ROOT=`git rev-parse --show-toplevel` + +export BINARY=staking-miner +export BIN_FOLDER=$1 + +$PROJECT_ROOT/scripts/ci/dockerfiles/build-injected.sh diff --git a/polkadot/scripts/ci/dockerfiles/staking-miner/build.sh b/polkadot/scripts/ci/dockerfiles/staking-miner/build.sh new file mode 100755 index 0000000000000000000000000000000000000000..67c82afcd2ce52ea002ef4df8761e471f5d9d10b --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/staking-miner/build.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Sample call: +# $0 /path/to/folder_with_staking-miner_binary +# This script replace the former dedicated staking-miner "injected" Dockerfile +# and shows how to use the generic binary_injected.dockerfile + +PROJECT_ROOT=`git rev-parse --show-toplevel` +ENGINE=podman + +echo "Building the staking-miner using the Builder image" +echo "PROJECT_ROOT=$PROJECT_ROOT" +$ENGINE build -t staking-miner -f staking-miner_builder.Dockerfile "$PROJECT_ROOT" diff --git a/polkadot/scripts/ci/dockerfiles/staking-miner/staking-miner_Dockerfile.README.md b/polkadot/scripts/ci/dockerfiles/staking-miner/staking-miner_Dockerfile.README.md new file mode 100644 index 0000000000000000000000000000000000000000..ce424c42f479a657191fb412a476fa04e1430b03 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/staking-miner/staking-miner_Dockerfile.README.md @@ -0,0 +1,3 @@ +# Staking-miner Docker image + +## [GitHub](https://github.com/paritytech/polkadot/tree/master/utils/staking-miner) diff --git a/polkadot/scripts/ci/dockerfiles/staking-miner/staking-miner_builder.Dockerfile b/polkadot/scripts/ci/dockerfiles/staking-miner/staking-miner_builder.Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..0ae77f36c79d0888c29c2f8211b21fc120db6037 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/staking-miner/staking-miner_builder.Dockerfile @@ -0,0 +1,43 @@ +FROM paritytech/ci-linux:production as builder + +# metadata +ARG VCS_REF +ARG BUILD_DATE +ARG IMAGE_NAME="staking-miner" +ARG PROFILE=production + +LABEL description="This is the build stage. Here we create the binary." + +WORKDIR /app +COPY . /app +RUN cargo build --locked --profile $PROFILE --package staking-miner + +# ===== SECOND STAGE ====== + +FROM docker.io/parity/base-bin:latest +LABEL description="This is the 2nd stage: a very small image where we copy the binary." +LABEL io.parity.image.authors="devops-team@parity.io" \ + io.parity.image.vendor="Parity Technologies" \ + io.parity.image.title="${IMAGE_NAME}" \ + io.parity.image.description="${IMAGE_NAME} for substrate based chains" \ + io.parity.image.source="https://github.com/paritytech/polkadot/blob/${VCS_REF}/scripts/ci/dockerfiles/${IMAGE_NAME}/${IMAGE_NAME}_builder.Dockerfile" \ + io.parity.image.revision="${VCS_REF}" \ + io.parity.image.created="${BUILD_DATE}" \ + io.parity.image.documentation="https://github.com/paritytech/polkadot/" + +ARG PROFILE=release +COPY --from=builder /app/target/$PROFILE/staking-miner /usr/local/bin + +# show backtraces +ENV RUST_BACKTRACE 1 + +USER parity + +ENV SEED="" +ENV URI="wss://rpc.polkadot.io" +ENV RUST_LOG="info" + +# check if the binary works in this container +RUN /usr/local/bin/staking-miner --version + +ENTRYPOINT [ "/usr/local/bin/staking-miner" ] diff --git a/polkadot/scripts/ci/dockerfiles/staking-miner/test-build.sh b/polkadot/scripts/ci/dockerfiles/staking-miner/test-build.sh new file mode 100755 index 0000000000000000000000000000000000000000..0ce74e2df296d267bdc1f4daba701ca57acdbaa1 --- /dev/null +++ b/polkadot/scripts/ci/dockerfiles/staking-miner/test-build.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +TMP=$(mktemp -d) +ENGINE=${ENGINE:-podman} + +# You need to build an injected image first + +# Fetch some binaries +$ENGINE run --user root --rm -i \ + -v "$TMP:/export" \ + --entrypoint /bin/bash \ + parity/staking-miner -c \ + 'cp "$(which staking-miner)" /export' + +echo "Checking binaries we got:" +tree $TMP + +./build-injected.sh $TMP diff --git a/polkadot/scripts/ci/github/check-rel-br b/polkadot/scripts/ci/github/check-rel-br new file mode 100755 index 0000000000000000000000000000000000000000..1b49ae621722a42d9adbb7f018ff66ee0e935762 --- /dev/null +++ b/polkadot/scripts/ci/github/check-rel-br @@ -0,0 +1,127 @@ +#!/usr/bin/env bash + +# This script helps running sanity checks on a release branch +# It is intended to be ran from the repo and from the release branch + +# NOTE: The diener runs do take time and are not really required because +# if we missed the diener runs, the Cargo.lock that we check won't pass +# the tests. See https://github.com/bkchr/diener/issues/17 + +grv=$(git remote --verbose | grep push) +export RUST_LOG=none +REPO=$(echo "$grv" | cut -d ' ' -f1 | cut -d$'\t' -f2 | sed 's/.*github.com\/\(.*\)/\1/g' | cut -d '/' -f2 | cut -d '.' -f1 | sort | uniq) +echo "[+] Detected repo: $REPO" + +BRANCH=$(git branch --show-current) +if ! [[ "$BRANCH" =~ ^release.*$ || "$BRANCH" =~ ^polkadot.*$ ]]; then + echo "This script is meant to run only on a RELEASE branch." + echo "Try one of the following branch:" + git branch -r --format "%(refname:short)" --sort=-committerdate | grep -Ei '/?release' | head + exit 1 +fi +echo "[+] Working on $BRANCH" + +# Tried to get the version of the release from the branch +# input: release-foo-v0.9.22 or release-bar-v9220 or release-foo-v0.9.220 +# output: 0.9.22 +get_version() { + branch=$1 + [[ $branch =~ -v(.*) ]] + version=${BASH_REMATCH[1]} + if [[ $version =~ \. ]]; then + MAJOR=$(($(echo $version | cut -d '.' -f1))) + MINOR=$(($(echo $version | cut -d '.' -f2))) + PATCH=$(($(echo $version | cut -d '.' -f3))) + echo $MAJOR.$MINOR.${PATCH:0:2} + else + MAJOR=$(echo $(($version / 100000))) + remainer=$(($version - $MAJOR * 100000)) + MINOR=$(echo $(($remainer / 1000))) + remainer=$(($remainer - $MINOR * 1000)) + PATCH=$(echo $(($remainer / 10))) + echo $MAJOR.$MINOR.$PATCH + fi +} + +# return the name of the release branch for a given repo and version +get_release_branch() { + repo=$1 + version=$2 + case $repo in + polkadot) + echo "release-v$version" + ;; + + substrate) + echo "polkadot-v$version" + ;; + + *) + echo "Repo $repo is not supported, exiting" + exit 1 + ;; + esac +} + +# repo = substrate / polkadot +check_release_branch_repo() { + repo=$1 + branch=$2 + + echo "[+] Checking deps for $repo=$branch" + + POSTIVE=$(cat Cargo.lock | grep "$repo?branch=$branch" | sort | uniq | wc -l) + NEGATIVE=$(cat Cargo.lock | grep "$repo?branch=" | grep -v $branch | sort | uniq | wc -l) + + if [[ $POSTIVE -eq 1 && $NEGATIVE -eq 0 ]]; then + echo -e "[+] ✅ Looking good" + cat Cargo.lock | grep "$repo?branch=" | sort | uniq | sed 's/^/\t - /' + return 0 + else + echo -e "[+] ❌ Something seems to be wrong, we want 1 unique match and 0 non match (1, 0) and we got ($(($POSTIVE)), $(($NEGATIVE)))" + cat Cargo.lock | grep "$repo?branch=" | sort | uniq | sed 's/^/\t - /' + return 1 + fi +} + +# Check a release branch +check_release_branches() { + SUBSTRATE_BRANCH=$1 + POLKADOT_BRANCH=$2 + + check_release_branch_repo substrate $SUBSTRATE_BRANCH + ret_a1=$? + + ret_b1=0 + if [ $POLKADOT_BRANCH ]; then + check_release_branch_repo polkadot $POLKADOT_BRANCH + ret_b1=$? + fi + + STATUS=$(($ret_a1 + $ret_b1)) + + return $STATUS +} + +VERSION=$(get_version $BRANCH) +echo "[+] Target version: v$VERSION" + +case $REPO in + polkadot) + substrate=$(get_release_branch substrate $VERSION) + + check_release_branches $substrate + ;; + + cumulus) + polkadot=$(get_release_branch polkadot $VERSION) + substrate=$(get_release_branch substrate $VERSION) + + check_release_branches $substrate $polkadot + ;; + + *) + echo "REPO $REPO is not supported, exiting" + exit 1 + ;; +esac diff --git a/polkadot/scripts/ci/github/check_bootnodes.sh b/polkadot/scripts/ci/github/check_bootnodes.sh new file mode 100755 index 0000000000000000000000000000000000000000..f98a58cda2c846e0538d54c03c8bee998fba1261 --- /dev/null +++ b/polkadot/scripts/ci/github/check_bootnodes.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +# In this script, we check each bootnode for a given chainspec file and ensure they are contactable. +# We do this by removing every bootnode from the chainspec with the exception of the one +# we want to check. Then we spin up a node using this new chainspec, wait a little while +# and then check our local node's RPC endpoint for the number of peers. If the node hasn't +# been able to contact any other nodes, we can reason that the bootnode we used is not well-connected +# or is otherwise uncontactable. + +# shellcheck source=scripts/ci/common/lib.sh +source "$(dirname "${0}")/../common/lib.sh" +CHAINSPEC_FILE="$1" +RUNTIME=$(basename "$CHAINSPEC_FILE" | cut -d '.' -f 1) + +trap cleanup EXIT INT TERM + +cleanup(){ + echo "[+] Script interrupted or ended. Cleaning up..." + # Kill all the polkadot processes + killall polkadot > /dev/null 2>&1 + exit $1 +} + +# count the number of bootnodes +BOOTNODES=$( jq -r '.bootNodes | length' "$CHAINSPEC_FILE" ) +# Make a temporary dir for chainspec files +# Store an array of the bad bootnodes +BAD_BOOTNODES=() +GOOD_BOOTNODES=() +PIDS=() + +echo "[+] Checking $BOOTNODES bootnodes for $RUNTIME" +for i in $(seq 0 $((BOOTNODES-1))); do + BOOTNODE=$( jq -r .bootNodes["$i"] < "$CHAINSPEC_FILE" ) + # Check each bootnode in parallel + check_bootnode "$BOOTNODE" "$CHAINSPEC_FILE" & + PIDS+=($!) + # Hold off 5 seconds between attempting to spawn nodes to stop the machine from getting overloaded + sleep 5 +done +RESPS=() +# Wait for all the nodes to finish +for pid in "${PIDS[@]}"; do + wait "$pid" + RESPS+=($?) +done +echo +# For any bootnodes that failed, add them to the bad bootnodes array +for i in "${!RESPS[@]}"; do + if [ "${RESPS[$i]}" -ne 0 ]; then + BAD_BOOTNODES+=("$( jq -r .bootNodes["$i"] < "$CHAINSPEC_FILE" )") + fi +done +# For any bootnodes that succeeded, add them to the good bootnodes array +for i in "${!RESPS[@]}"; do + if [ "${RESPS[$i]}" -eq 0 ]; then + GOOD_BOOTNODES+=("$( jq -r .bootNodes["$i"] < "$CHAINSPEC_FILE" )") + fi +done + +# If we've got any uncontactable bootnodes for this runtime, print them +if [ ${#BAD_BOOTNODES[@]} -gt 0 ]; then + echo "[!] Bad bootnodes found for $RUNTIME:" + for i in "${BAD_BOOTNODES[@]}"; do + echo " $i" + done + cleanup 1 +else + echo "[+] All bootnodes for $RUNTIME are contactable" + cleanup 0 +fi diff --git a/polkadot/scripts/ci/github/check_labels.sh b/polkadot/scripts/ci/github/check_labels.sh new file mode 100755 index 0000000000000000000000000000000000000000..12f07b3495e3bb59fda9142aaa1af6ce38925114 --- /dev/null +++ b/polkadot/scripts/ci/github/check_labels.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +#shellcheck source=../common/lib.sh +source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/../common/lib.sh" + +repo="$GITHUB_REPOSITORY" +pr="$GITHUB_PR" + +ensure_labels() { + for label in "$@"; do + if has_label "$repo" "$pr" "$label"; then + return 0 + fi + done + return 1 +} + +# Must have one of the following labels +releasenotes_labels=( + 'B0-silent' + 'B1-releasenotes' + 'B7-runtimenoteworthy' +) + +# Must be an ordered list of priorities, lowest first +priority_labels=( + 'C1-low 📌' + 'C3-medium 📣' + 'C7-high ❗️' + 'C9-critical ‼️' +) + +audit_labels=( + 'D1-audited 👍' + 'D2-notlive 💤' + 'D3-trivial 🧸' + 'D5-nicetohaveaudit ⚠️' + 'D9-needsaudit 👮' +) + +echo "[+] Checking release notes (B) labels for $CI_COMMIT_BRANCH" +if ensure_labels "${releasenotes_labels[@]}"; then + echo "[+] Release notes label detected. All is well." +else + echo "[!] Release notes label not detected. Please add one of: ${releasenotes_labels[*]}" + exit 1 +fi + +echo "[+] Checking release priority (C) labels for $CI_COMMIT_BRANCH" +if ensure_labels "${priority_labels[@]}"; then + echo "[+] Release priority label detected. All is well." +else + echo "[!] Release priority label not detected. Please add one of: ${priority_labels[*]}" + exit 1 +fi + +if has_runtime_changes "${BASE_SHA}" "${HEAD_SHA}"; then + echo "[+] Runtime changes detected. Checking audit (D) labels" + if ensure_labels "${audit_labels[@]}"; then + echo "[+] Release audit label detected. All is well." + else + echo "[!] Release audit label not detected. Please add one of: ${audit_labels[*]}" + exit 1 + fi +fi + +# If the priority is anything other than the lowest, we *must not* have a B0-silent +# label +if has_label "$repo" "$GITHUB_PR" 'B0-silent' && + ! has_label "$repo" "$GITHUB_PR" "${priority_labels[0]}"; then + echo "[!] Changes with a priority higher than C1-low *MUST* have a B- label that is not B0-Silent" + exit 1 +fi + +exit 0 diff --git a/polkadot/scripts/ci/github/check_new_bootnodes.sh b/polkadot/scripts/ci/github/check_new_bootnodes.sh new file mode 100755 index 0000000000000000000000000000000000000000..604db6a4e367b6377bf802070c442c38208266af --- /dev/null +++ b/polkadot/scripts/ci/github/check_new_bootnodes.sh @@ -0,0 +1,42 @@ +#!/bin/bash +set -e +# shellcheck source=scripts/ci/common/lib.sh +source "$(dirname "${0}")/../common/lib.sh" + +# This script checks any new bootnodes added since the last git commit + +RUNTIMES=( kusama westend polkadot ) + +WAS_ERROR=0 + +for RUNTIME in "${RUNTIMES[@]}"; do + CHAINSPEC_FILE="node/service/chain-specs/$RUNTIME.json" + # Get the bootnodes from master's chainspec + git show origin/master:"$CHAINSPEC_FILE" | jq '{"oldNodes": .bootNodes}' > "$RUNTIME-old-bootnodes.json" + # Get the bootnodes from the current branch's chainspec + git show HEAD:"$CHAINSPEC_FILE" | jq '{"newNodes": .bootNodes}' > "$RUNTIME-new-bootnodes.json" + # Make a chainspec containing only the new bootnodes + jq ".bootNodes = $(jq -rs '.[0] * .[1] | .newNodes-.oldNodes' \ + "$RUNTIME-new-bootnodes.json" "$RUNTIME-old-bootnodes.json")" \ + < "node/service/chain-specs/$RUNTIME.json" \ + > "$RUNTIME-new-chainspec.json" + # exit early if the new chainspec has no bootnodes + if [ "$(jq -r '.bootNodes | length' "$RUNTIME-new-chainspec.json")" -eq 0 ]; then + echo "[+] No new bootnodes for $RUNTIME" + # Clean up the temporary files + rm "$RUNTIME-new-chainspec.json" "$RUNTIME-old-bootnodes.json" "$RUNTIME-new-bootnodes.json" + continue + fi + # Check the new bootnodes + if ! "scripts/ci/github/check_bootnodes.sh" "$RUNTIME-new-chainspec.json"; then + WAS_ERROR=1 + fi + # Clean up the temporary files + rm "$RUNTIME-new-chainspec.json" "$RUNTIME-old-bootnodes.json" "$RUNTIME-new-bootnodes.json" +done + + +if [ $WAS_ERROR -eq 1 ]; then + echo "[!] One of the new bootnodes failed to connect. Please check logs above." + exit 1 +fi diff --git a/polkadot/scripts/ci/github/check_weights_swc.sh b/polkadot/scripts/ci/github/check_weights_swc.sh new file mode 100755 index 0000000000000000000000000000000000000000..35652f4fde83690e78f4d1d4e47f4e333b3fc2fe --- /dev/null +++ b/polkadot/scripts/ci/github/check_weights_swc.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# Need to set globstar for ** magic +shopt -s globstar + +RUNTIME=$1 +VERSION=$2 +echo "
" +echo "Weight changes for $RUNTIME" +echo +swc compare commits \ + --method asymptotic \ + --offline \ + --path-pattern "./runtime/$RUNTIME/src/weights/**/*.rs" \ + --no-color \ + --format markdown \ + --strip-path-prefix "runtime/$RUNTIME/src/weights/" \ + "$VERSION" + #--ignore-errors +echo +echo "
" diff --git a/polkadot/scripts/ci/github/extrinsic-ordering-filter.sh b/polkadot/scripts/ci/github/extrinsic-ordering-filter.sh new file mode 100755 index 0000000000000000000000000000000000000000..4fd3337f64a6e9ea93848685cdf2fbac8b0340e7 --- /dev/null +++ b/polkadot/scripts/ci/github/extrinsic-ordering-filter.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# This script is used in a Github Workflow. It helps filtering out what is interesting +# when comparing metadata and spot what would require a tx version bump. + +# shellcheck disable=SC2002,SC2086 + +FILE=$1 + +# Higlight indexes that were deleted +function find_deletions() { + echo "\n## Deletions\n" + RES=$(cat "$FILE" | grep -n '\[\-\]' | tr -s " ") + if [ "$RES" ]; then + echo "$RES" | awk '{ printf "%s\\n", $0 }' + else + echo "n/a" + fi +} + +# Highlight indexes that have been deleted +function find_index_changes() { + echo "\n## Index changes\n" + RES=$(cat "$FILE" | grep -E -n -i 'idx:\s*([0-9]+)\s*(->)\s*([0-9]+)' | tr -s " ") + if [ "$RES" ]; then + echo "$RES" | awk '{ printf "%s\\n", $0 }' + else + echo "n/a" + fi +} + +# Highlight values that decreased +function find_decreases() { + echo "\n## Decreases\n" + OUT=$(cat "$FILE" | grep -E -i -o '([0-9]+)\s*(->)\s*([0-9]+)' | awk '$1 > $3 { printf "%s;", $0 }') + IFS=$';' LIST=("$OUT") + unset RES + for line in "${LIST[@]}"; do + RES="$RES\n$(cat "$FILE" | grep -E -i -n \"$line\" | tr -s " ")" + done + + if [ "$RES" ]; then + echo "$RES" | awk '{ printf "%s\\n", $0 }' | sort -u -g | uniq + else + echo "n/a" + fi +} + +echo "\n------------------------------ SUMMARY -------------------------------" +echo "\n⚠️ This filter is here to help spotting changes that should be reviewed carefully." +echo "\n⚠️ It catches only index changes, deletions and value decreases". + +find_deletions "$FILE" +find_index_changes "$FILE" +find_decreases "$FILE" +echo "\n----------------------------------------------------------------------\n" diff --git a/polkadot/scripts/ci/github/generate_release_text.rb b/polkadot/scripts/ci/github/generate_release_text.rb new file mode 100644 index 0000000000000000000000000000000000000000..83b3853a342d1e7a2570276a3b2eb526a79090a5 --- /dev/null +++ b/polkadot/scripts/ci/github/generate_release_text.rb @@ -0,0 +1,148 @@ +# frozen_string_literal: true + +require 'base64' +require 'changelogerator' +require 'erb' +require 'git' +require 'json' +require 'octokit' +require 'toml' +require_relative './lib.rb' + +# A logger only active when NOT running in CI +def logger(s) + puts "▶ DEBUG: %s" % [s] if ENV['CI'] != 'true' +end + +# Check if all the required ENV are set +# This is especially convenient when testing locally +def check_env() + if ENV['CI'] != 'true' then + logger("Running locally") + vars = ['GITHUB_REF', 'GITHUB_TOKEN', 'GITHUB_WORKSPACE', 'GITHUB_REPOSITORY', 'RUSTC_STABLE', 'RUSTC_NIGHTLY'] + vars.each { |x| + env = (ENV[x] || "") + if env.length > 0 then + logger("- %s:\tset: %s, len: %d" % [x, env.length > 0 || false, env.length]) + else + logger("- %s:\tset: %s, len: %d" % [x, env.length > 0 || false, env.length]) + end + } + end +end + +check_env() + +current_ref = ENV['GITHUB_REF'] +token = ENV['GITHUB_TOKEN'] + +logger("Connecting to Github") +github_client = Octokit::Client.new( + access_token: token +) + +polkadot_path = ENV['GITHUB_WORKSPACE'] + '/polkadot/' + +# Generate an ERB renderer based on the template .erb file +renderer = ERB.new( + File.read(File.join(polkadot_path, 'scripts/ci/github/polkadot_release.erb')), + trim_mode: '<>' +) + +# get ref of last polkadot release +last_ref = 'refs/tags/' + github_client.latest_release(ENV['GITHUB_REPOSITORY']).tag_name +logger("Last ref: " + last_ref) + +logger("Generate changelog for Polkadot") +polkadot_cl = Changelog.new( + 'paritytech/polkadot', last_ref, current_ref, token: token +) + +# Gets the substrate commit hash used for a given polkadot ref +def get_substrate_commit(client, ref) + cargo = TOML::Parser.new( + Base64.decode64( + client.contents( + ENV['GITHUB_REPOSITORY'], + path: 'Cargo.lock', + query: { ref: ref.to_s } + ).content + ) + ).parsed + cargo['package'].find { |p| p['name'] == 'sc-cli' }['source'].split('#').last +end + +substrate_prev_sha = get_substrate_commit(github_client, last_ref) +substrate_cur_sha = get_substrate_commit(github_client, current_ref) + +logger("Generate changelog for Substrate") +substrate_cl = Changelog.new( + 'paritytech/substrate', substrate_prev_sha, substrate_cur_sha, + token: token, + prefix: true +) + +# Combine all changes into a single array and filter out companions +all_changes = (polkadot_cl.changes + substrate_cl.changes).reject do |c| + c[:title] =~ /[Cc]ompanion/ +end + +# Set all the variables needed for a release + +misc_changes = Changelog.changes_with_label(all_changes, 'B1-releasenotes') +client_changes = Changelog.changes_with_label(all_changes, 'B5-clientnoteworthy') +runtime_changes = Changelog.changes_with_label(all_changes, 'B7-runtimenoteworthy') + +# Add the audit status for runtime changes +runtime_changes.each do |c| + if c[:labels].any? { |l| l[:name] == 'D1-audited 👍' } + c[:pretty_title] = "✅ `audited` #{c[:pretty_title]}" + next + end + if c[:labels].any? { |l| l[:name] == 'D2-notlive 💤' } + c[:pretty_title] = "✅ `not live` #{c[:pretty_title]}" + next + end + if c[:labels].any? { |l| l[:name] == 'D3-trivial 🧸' } + c[:pretty_title] = "✅ `trivial` #{c[:pretty_title]}" + next + end + if c[:labels].any? { |l| l[:name] == 'D5-nicetohaveaudit ⚠️' } + c[:pretty_title] = "⏳ `pending non-critical audit` #{c[:pretty_title]}" + next + end + if c[:labels].any? { |l| l[:name] == 'D9-needsaudit 👮' } + c[:pretty_title] = "❌ `AWAITING AUDIT` #{c[:pretty_title]}" + next + end + c[:pretty_title] = "⭕️ `unknown audit requirements` #{c[:pretty_title]}" +end + +# The priority of users upgraded is determined by the highest-priority +# *Client* change +release_priority = Changelog.highest_priority_for_changes(client_changes) + +# Pulled from the previous Github step +rustc_stable = ENV['RUSTC_STABLE'] +rustc_nightly = ENV['RUSTC_NIGHTLY'] +polkadot_runtime = get_runtime('polkadot', polkadot_path) +kusama_runtime = get_runtime('kusama', polkadot_path) +westend_runtime = get_runtime('westend', polkadot_path) +rococo_runtime = get_runtime('rococo', polkadot_path) + +# These json files should have been downloaded as part of the build-runtimes +# github action + +polkadot_json = JSON.parse( + File.read( + "#{ENV['GITHUB_WORKSPACE']}/polkadot-srtool-json/polkadot_srtool_output.json" + ) +) + +kusama_json = JSON.parse( + File.read( + "#{ENV['GITHUB_WORKSPACE']}/kusama-srtool-json/kusama_srtool_output.json" + ) +) + +puts renderer.result diff --git a/polkadot/scripts/ci/github/lib.rb b/polkadot/scripts/ci/github/lib.rb new file mode 100644 index 0000000000000000000000000000000000000000..14663acaf31a32c739243c445d41a7f3d3774074 --- /dev/null +++ b/polkadot/scripts/ci/github/lib.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# Gets the runtime version for a given runtime from the filesystem. +# Optionally accepts a path that is the root of the project which defaults to +# the current working directory +def get_runtime(runtime: nil, path: '.', runtime_dir: 'runtime') + File.open(path + "/#{runtime_dir}/#{runtime}/src/lib.rs") do |f| + f.find { |l| l =~ /spec_version/ }.match(/[0-9]+/)[0] + end +end diff --git a/polkadot/scripts/ci/github/polkadot_release.erb b/polkadot/scripts/ci/github/polkadot_release.erb new file mode 100644 index 0000000000000000000000000000000000000000..3fcf07dddc5c61dccf22eab54ba4efe9246a4cae --- /dev/null +++ b/polkadot/scripts/ci/github/polkadot_release.erb @@ -0,0 +1,42 @@ +<%= print release_priority[:text] %> <%= puts " due to changes: *#{Changelog.changes_with_label(all_changes, release_priority[:label]).map(&:pretty_title).join(", ")}*" if release_priority[:priority] > 1 %> + +Native runtimes: + +- Polkadot: **<%= polkadot_runtime %>** +- Kusama: **<%= kusama_runtime %>** +- Westend: **<%= westend_runtime %>** + +This release was tested against the following versions of `rustc`. Other versions may work. + +- <%= rustc_stable %> +- <%= rustc_nightly %> + +WASM runtimes built with [<%= polkadot_json['info']['generator']['name'] %> v<%= polkadot_json['info']['generator']['version'] %>](https://github.com/paritytech/srtool) using `<%= polkadot_json['rustc'] %>`. + +Proposal hashes: +* `polkadot_runtime-v<%= polkadot_runtime %>.compact.compressed.wasm`: `<%= polkadot_json['runtimes']['compressed']['prop'] %>` +* `kusama_runtime-v<%= kusama_runtime %>.compact.compressed.wasm`: `<%= kusama_json['runtimes']['compressed']['prop'] %>` + +<% unless misc_changes.empty? %> +## Changes + +<% misc_changes.each do |c| %> +* <%= c[:pretty_title] %> +<% end %> +<% end %> + +<% unless client_changes.empty? %> +## Client + +<% client_changes.each do |c| %> +* <%= c[:pretty_title] %> +<% end %> +<% end %> + +<% unless runtime_changes.empty? %> +## Runtime + +<% runtime_changes.each do |c| %> +* <%= c[:pretty_title] %> +<% end %> +<% end %> diff --git a/polkadot/scripts/ci/github/run_fuzzer.sh b/polkadot/scripts/ci/github/run_fuzzer.sh new file mode 100755 index 0000000000000000000000000000000000000000..b73a83beab91ff1219c1b82e9aeb7f9b40ebcb2c --- /dev/null +++ b/polkadot/scripts/ci/github/run_fuzzer.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +timeout --signal INT 5h cargo hfuzz run $1 +status=$? + +if [ $status -ne 124 ]; then + echo "Found a panic!" + # TODO: provide Minimal Reproducible Input + # TODO: message on Matrix + exit 1 +else + echo "Didn't find any problem in 5 hours of fuzzing" +fi diff --git a/polkadot/scripts/ci/github/verify_updated_weights.sh b/polkadot/scripts/ci/github/verify_updated_weights.sh new file mode 100755 index 0000000000000000000000000000000000000000..54db1de21ca00af1bff26b9fdb22932578e3f511 --- /dev/null +++ b/polkadot/scripts/ci/github/verify_updated_weights.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +ROOT="$(dirname "$0")/../../.." +RUNTIME="$1" + +# If we're on a mac, use gdate for date command (requires coreutils installed via brew) +if [[ "$OSTYPE" == "darwin"* ]]; then + DATE="gdate" +else + DATE="date" +fi + +function check_date() { + # Get the dates as input arguments + LAST_RUN="$1" + TODAY="$($DATE +%Y-%m-%d)" + # Calculate the date two days before today + CUTOFF=$($DATE -d "$TODAY - 2 days" +%Y-%m-%d) + + if [[ "$LAST_RUN" > "$CUTOFF" ]]; then + return 0 + else + return 1 + fi +} + +check_weights(){ + FILE=$1 + CUR_DATE=$2 + DATE_REGEX='[0-9]{4}-[0-9]{2}-[0-9]{2}' + LAST_UPDATE="$(grep -E "//! DATE: $DATE_REGEX" "$FILE" | sed -r "s/.*DATE: ($DATE_REGEX).*/\1/")" + # If the file does not contain a date, flag it as an error. + if [ -z "$LAST_UPDATE" ]; then + echo "Skipping $FILE, no date found." + return 0 + fi + if ! check_date "$LAST_UPDATE" ; then + echo "ERROR: $FILE was not updated for the current date. Last update: $LAST_UPDATE" + return 1 + fi + # echo "OK: $FILE" +} + +echo "Checking weights for $RUNTIME" +CUR_DATE="$(date +%Y-%m-%d)" +HAS_ERROR=0 +for FILE in "$ROOT"/runtime/"$RUNTIME"/src/weights/*.rs; do + if ! check_weights "$FILE" "$CUR_DATE"; then + HAS_ERROR=1 + fi +done + +if [ $HAS_ERROR -eq 1 ]; then + echo "ERROR: One or more weights files were not updated during the last benchmark run. Check the logs above." + exit 1 +fi \ No newline at end of file diff --git a/polkadot/scripts/ci/gitlab/check_extrinsics_ordering.sh b/polkadot/scripts/ci/gitlab/check_extrinsics_ordering.sh new file mode 100755 index 0000000000000000000000000000000000000000..8a7385f03f9f2347e4c66f2f12d7803cde0ff184 --- /dev/null +++ b/polkadot/scripts/ci/gitlab/check_extrinsics_ordering.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +set -e + +# Include the common functions library +#shellcheck source=../common/lib.sh +. "$(dirname "${0}")/../common/lib.sh" + +HEAD_BIN=./artifacts/polkadot +HEAD_WS=ws://localhost:9944 +RELEASE_WS=ws://localhost:9945 + +runtimes=( + "westend" + "kusama" + "polkadot" +) + +# First we fetch the latest released binary +latest_release=$(latest_release 'paritytech/polkadot') +RELEASE_BIN="./polkadot-$latest_release" +echo "[+] Fetching binary for Polkadot version $latest_release" +curl -L "https://github.com/paritytech/polkadot/releases/download/$latest_release/polkadot" > "$RELEASE_BIN" || exit 1 +chmod +x "$RELEASE_BIN" + + +for RUNTIME in "${runtimes[@]}"; do + echo "[+] Checking runtime: ${RUNTIME}" + + release_transaction_version=$( + git show "origin/release:runtime/${RUNTIME}/src/lib.rs" | \ + grep 'transaction_version' + ) + + current_transaction_version=$( + grep 'transaction_version' "./runtime/${RUNTIME}/src/lib.rs" + ) + + echo "[+] Release: ${release_transaction_version}" + echo "[+] Ours: ${current_transaction_version}" + + if [ ! "$release_transaction_version" = "$current_transaction_version" ]; then + echo "[+] Transaction version for ${RUNTIME} has been bumped since last release." + exit 0 + fi + + # Start running the nodes in the background + $HEAD_BIN --chain="$RUNTIME-local" --tmp & + $RELEASE_BIN --chain="$RUNTIME-local" --ws-port 9945 --tmp & + jobs + + # Sleep a little to allow the nodes to spin up and start listening + TIMEOUT=5 + for i in $(seq $TIMEOUT); do + sleep 1 + if [ "$(lsof -nP -iTCP -sTCP:LISTEN | grep -c '994[45]')" == 2 ]; then + echo "[+] Both nodes listening" + break + fi + if [ "$i" == $TIMEOUT ]; then + echo "[!] Both nodes not listening after $i seconds. Exiting" + exit 1 + fi + done + sleep 5 + + changed_extrinsics=$( + polkadot-js-metadata-cmp "$RELEASE_WS" "$HEAD_WS" \ + | sed 's/^ \+//g' | grep -e 'idx: [0-9]\+ -> [0-9]\+' || true + ) + + if [ -n "$changed_extrinsics" ]; then + echo "[!] Extrinsics indexing/ordering has changed in the ${RUNTIME} runtime! If this change is intentional, please bump transaction_version in lib.rs. Changed extrinsics:" + echo "$changed_extrinsics" + exit 1 + fi + + echo "[+] No change in extrinsics ordering for the ${RUNTIME} runtime" + jobs -p | xargs kill; sleep 5 +done + +# Sleep a little to let the jobs die properly +sleep 5 diff --git a/polkadot/scripts/ci/gitlab/check_runtime.sh b/polkadot/scripts/ci/gitlab/check_runtime.sh new file mode 100755 index 0000000000000000000000000000000000000000..9618bbfa1c769a8e56e4bbef50b52f9f917e49a2 --- /dev/null +++ b/polkadot/scripts/ci/gitlab/check_runtime.sh @@ -0,0 +1,204 @@ +#!/usr/bin/env bash + +# Check for any changes in any runtime directories (e.g., ^runtime/polkadot) as +# well as directories common to all runtimes (e.g., ^runtime/common). If there +# are no changes, check if the Substrate git SHA in Cargo.lock has been +# changed. If so, pull the repo and verify if {spec,impl}_versions have been +# altered since the previous Substrate version used. +# +# If there were changes to any runtimes or common dirs, we iterate over each +# runtime (defined in the $runtimes() array), and check if {spec,impl}_version +# have been changed since the last release. + +set -e # fail on any error + +#Include the common functions library +#shellcheck source=../common/lib.sh +. "$(dirname "${0}")/../common/lib.sh" + +SUBSTRATE_REPO="https://github.com/paritytech/substrate" +SUBSTRATE_REPO_CARGO="git\+${SUBSTRATE_REPO}" +SUBSTRATE_VERSIONS_FILE="bin/node/runtime/src/lib.rs" + +# figure out the latest release tag +boldprint "make sure we have all tags (including those from the release branch)" +git fetch --depth="${GIT_DEPTH:-100}" origin release +git fetch --depth="${GIT_DEPTH:-100}" origin 'refs/tags/*:refs/tags/*' +LATEST_TAG="$(git tag -l | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+-?[0-9]*$' | sort -V | tail -n 1)" +boldprint "latest release tag ${LATEST_TAG}" + +boldprint "latest 10 commits of ${CI_COMMIT_REF_NAME}" +git --no-pager log --graph --oneline --decorate=short -n 10 + +boldprint "make sure the master branch is available in shallow clones" +git fetch --depth="${GIT_DEPTH:-100}" origin master + + +runtimes=( + "kusama" + "polkadot" + "westend" + "rococo" +) + +common_dirs=( + "common" +) + +# Helper function to join elements in an array with a multi-char delimiter +# https://stackoverflow.com/questions/1527049/how-can-i-join-elements-of-an-array-in-bash +function join_by { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; } + +boldprint "check if the wasm sources changed since ${LATEST_TAG}" +if ! has_runtime_changes "${LATEST_TAG}" "${CI_COMMIT_SHA}"; then + boldprint "no changes to any runtime source code detected" + # continue checking if Cargo.lock was updated with a new substrate reference + # and if that change includes a {spec|impl}_version update. + + SUBSTRATE_REFS_CHANGED="$( + git diff "refs/tags/${LATEST_TAG}...${CI_COMMIT_SHA}" Cargo.lock \ + | sed -n -r "s~^[\+\-]source = \"${SUBSTRATE_REPO_CARGO}#([a-f0-9]+)\".*$~\1~p" | sort -u | wc -l + )" + + # check Cargo.lock for substrate ref change + case "${SUBSTRATE_REFS_CHANGED}" in + (0) + boldprint "substrate refs not changed in Cargo.lock" + exit 0 + ;; + (2) + boldprint "substrate refs updated since ${LATEST_TAG}" + ;; + (*) + boldprint "check unsupported: more than one commit targeted in repo ${SUBSTRATE_REPO_CARGO}" + exit 1 + esac + + + SUBSTRATE_PREV_REF="$( + git diff "refs/tags/${LATEST_TAG}...${CI_COMMIT_SHA}" Cargo.lock \ + | sed -n -r "s~^\-source = \"${SUBSTRATE_REPO_CARGO}#([a-f0-9]+)\".*$~\1~p" | sort -u | head -n 1 + )" + + SUBSTRATE_NEW_REF="$( + git diff "refs/tags/${LATEST_TAG}...${CI_COMMIT_SHA}" Cargo.lock \ + | sed -n -r "s~^\+source = \"${SUBSTRATE_REPO_CARGO}#([a-f0-9]+)\".*$~\1~p" | sort -u | head -n 1 + )" + + + boldcat < ${add_spec_version} + +EOT + continue + + else + # check for impl_version updates: if only the impl versions changed, we assume + # there is no consensus-critical logic that has changed. + + add_impl_version="$( + git diff refs/tags/"${LATEST_TAG}...${CI_COMMIT_SHA}" "runtime/${RUNTIME}/src/lib.rs" \ + | sed -n -r 's/^\+[[:space:]]+impl_version: +([0-9]+),$/\1/p' + )" + sub_impl_version="$( + git diff refs/tags/"${LATEST_TAG}...${CI_COMMIT_SHA}" "runtime/${RUNTIME}/src/lib.rs" \ + | sed -n -r 's/^\-[[:space:]]+impl_version: +([0-9]+),$/\1/p' + )" + + + # see if the impl version changed + if [ "${add_impl_version}" != "${sub_impl_version}" ] + then + boldcat < ${add_impl_version} + +EOT + continue + fi + + failed_runtime_checks+=("$RUNTIME") + fi +done + +if [ ${#failed_runtime_checks} -gt 0 ]; then + boldcat < ./artifacts/VERSION + - echo -n ${EXTRATAG} > ./artifacts/EXTRATAG + - echo -n ${CI_JOB_ID} > ./artifacts/BUILD_LINUX_JOB_ID + - RELEASE_VERSION=$(./artifacts/polkadot -V | awk '{print $2}'| awk -F "-" '{print $1}') + - echo -n "v${RELEASE_VERSION}" > ./artifacts/BUILD_RELEASE_VERSION + +build-test-collators: + stage: build + # this is an artificial job dependency, for pipeline optimization using GitLab's DAGs + # the job can be found in check.yml + needs: + - job: job-starter + artifacts: false + extends: + - .docker-env + - .common-refs + - .compiler-info + - .collect-artifacts + script: + - time cargo build --locked --profile testnet --verbose -p test-parachain-adder-collator + - time cargo build --locked --profile testnet --verbose -p test-parachain-undying-collator + # pack artifacts + - mkdir -p ./artifacts + - mv ./target/testnet/adder-collator ./artifacts/. + - mv ./target/testnet/undying-collator ./artifacts/. + - echo -n "${CI_COMMIT_REF_NAME}" > ./artifacts/VERSION + - echo -n "${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}" > ./artifacts/EXTRATAG + - echo "adder-collator version = $(cat ./artifacts/VERSION) (EXTRATAG = $(cat ./artifacts/EXTRATAG))" + - echo "undying-collator version = $(cat ./artifacts/VERSION) (EXTRATAG = $(cat ./artifacts/EXTRATAG))" + +build-malus: + stage: build + # this is an artificial job dependency, for pipeline optimization using GitLab's DAGs + # the job can be found in check.yml + needs: + - job: job-starter + artifacts: false + extends: + - .docker-env + - .common-refs + - .compiler-info + - .collect-artifacts + script: + - time cargo build --locked --profile testnet --verbose -p polkadot-test-malus + # pack artifacts + - mkdir -p ./artifacts + - mv ./target/testnet/malus ./artifacts/. + - mv ./target/testnet/polkadot-execute-worker ./artifacts/. + - mv ./target/testnet/polkadot-prepare-worker ./artifacts/. + - echo -n "${CI_COMMIT_REF_NAME}" > ./artifacts/VERSION + - echo -n "${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}" > ./artifacts/EXTRATAG + - echo "polkadot-test-malus = $(cat ./artifacts/VERSION) (EXTRATAG = $(cat ./artifacts/EXTRATAG))" + +build-staking-miner: + stage: build + # this is an artificial job dependency, for pipeline optimization using GitLab's DAGs + # the job can be found in check.yml + needs: + - job: job-starter + artifacts: false + extends: + - .docker-env + - .common-refs + - .compiler-info + - .collect-artifacts + script: + - time cargo build --locked --release --package staking-miner + # pack artifacts + - mkdir -p ./artifacts + - mv ./target/release/staking-miner ./artifacts/. + - echo -n "${CI_COMMIT_REF_NAME}" > ./artifacts/VERSION + - echo -n "${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}" > ./artifacts/EXTRATAG + - echo "staking-miner = $(cat ./artifacts/VERSION) (EXTRATAG = $(cat ./artifacts/EXTRATAG))" + +build-rustdoc: + stage: build + # this is an artificial job dependency, for pipeline optimization using GitLab's DAGs + # the job can be found in test.yml + needs: + - job: test-deterministic-wasm + artifacts: false + extends: + - .docker-env + - .test-refs + variables: + SKIP_WASM_BUILD: 1 + artifacts: + name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}-doc" + when: on_success + expire_in: 1 days + paths: + - ./crate-docs/ + script: + # FIXME: it fails with `RUSTDOCFLAGS="-Dwarnings"` and `--all-features` + # FIXME: return to stable when https://github.com/rust-lang/rust/issues/96937 gets into stable + - time cargo doc --workspace --verbose --no-deps + - rm -f ./target/doc/.lock + - mv ./target/doc ./crate-docs + # FIXME: remove me after CI image gets nonroot + - chown -R nonroot:nonroot ./crate-docs + - echo "" > ./crate-docs/index.html + +build-implementers-guide: + stage: build + # this is an artificial job dependency, for pipeline optimization using GitLab's DAGs + # the job can be found in test.yml + needs: + - job: test-deterministic-wasm + artifacts: false + extends: + - .kubernetes-env + - .test-refs + - .collect-artifacts-short + # git depth is set on purpose: https://github.com/paritytech/polkadot/issues/6284 + variables: + GIT_STRATEGY: clone + GIT_DEPTH: 0 + CI_IMAGE: paritytech/mdbook-utils:e14aae4a-20221123 + script: + - mdbook build ./roadmap/implementers-guide + - mkdir -p artifacts + - mv roadmap/implementers-guide/book artifacts/ + +build-short-benchmark: + stage: build + # this is an artificial job dependency, for pipeline optimization using GitLab's DAGs + # the job can be found in check.yml + needs: + - job: job-starter + artifacts: false + extends: + - .docker-env + - .test-refs + - .collect-artifacts + script: + - cargo build --profile release --locked --features=runtime-benchmarks + - mkdir artifacts + - cp ./target/release/polkadot ./artifacts/ diff --git a/polkadot/scripts/ci/gitlab/pipeline/check.yml b/polkadot/scripts/ci/gitlab/pipeline/check.yml new file mode 100644 index 0000000000000000000000000000000000000000..9b2ad5e738332aba11b27b825439fccd9db82bc3 --- /dev/null +++ b/polkadot/scripts/ci/gitlab/pipeline/check.yml @@ -0,0 +1,136 @@ +# This file is part of .gitlab-ci.yml +# Here are all jobs that are executed during "check" stage + +check-runtime: + stage: check + image: paritytech/tools:latest + extends: + - .kubernetes-env + rules: + - if: $CI_COMMIT_REF_NAME =~ /^release-v[0-9]+\.[0-9]+.*$/ # i.e. release-v0.9.27 + variables: + GITLAB_API: "https://gitlab.parity.io/api/v4" + GITHUB_API_PROJECT: "parity%2Finfrastructure%2Fgithub-api" + script: + - ./scripts/ci/gitlab/check_runtime.sh + allow_failure: true + +cargo-fmt: + stage: check + extends: + - .docker-env + - .test-refs + script: + - cargo +nightly --version + - cargo +nightly fmt --all -- --check + allow_failure: true + +# Disabled in https://github.com/paritytech/polkadot/pull/7512 +.spellcheck_disabled: + stage: check + extends: + - .docker-env + - .test-refs + script: + - cargo spellcheck --version + # compare with the commit parent to the PR, given it's from a default branch + - git fetch origin +${CI_DEFAULT_BRANCH}:${CI_DEFAULT_BRANCH} + - echo "___Spellcheck is going to check your diff___" + - cargo spellcheck list-files -vvv $(git diff --diff-filter=AM --name-only $(git merge-base ${CI_COMMIT_SHA} ${CI_DEFAULT_BRANCH} -- :^bridges)) + - time cargo spellcheck check -vvv --cfg=scripts/ci/gitlab/spellcheck.toml --checkers hunspell --code 1 + $(git diff --diff-filter=AM --name-only $(git merge-base ${CI_COMMIT_SHA} ${CI_DEFAULT_BRANCH} -- :^bridges)) + allow_failure: true + +check-try-runtime: + stage: check + extends: + - .docker-env + - .test-refs + - .compiler-info + script: + # Check that everything compiles with `try-runtime` feature flag. + - cargo check --locked --features try-runtime --all + +# More info can be found here: https://github.com/paritytech/polkadot/pull/5865 +.check-runtime-migration: + stage: check + extends: + - .docker-env + - .test-pr-refs + - .compiler-info + script: + - | + export RUST_LOG=remote-ext=debug,runtime=debug + echo "---------- Running try-runtime for ${NETWORK} ----------" + time cargo install --locked --git https://github.com/paritytech/try-runtime-cli --rev a93c9b5abe5d31a4cf1936204f7e5c489184b521 + time cargo build --release --locked -p "$NETWORK"-runtime --features try-runtime + time try-runtime \ + --runtime ./target/release/wbuild/"$NETWORK"-runtime/target/wasm32-unknown-unknown/release/"$NETWORK"_runtime.wasm \ + on-runtime-upgrade --checks=pre-and-post live --uri wss://${NETWORK}-try-runtime-node.parity-chains.parity.io:443 + +check-runtime-migration-polkadot: + stage: check + extends: + - .docker-env + - .test-pr-refs + - .compiler-info + - .check-runtime-migration + variables: + NETWORK: "polkadot" + allow_failure: true # FIXME https://github.com/paritytech/substrate/issues/13107 + +check-runtime-migration-kusama: + stage: check + extends: + - .docker-env + - .test-pr-refs + - .compiler-info + - .check-runtime-migration + variables: + NETWORK: "kusama" + allow_failure: true # FIXME https://github.com/paritytech/substrate/issues/13107 + +check-runtime-migration-westend: + stage: check + extends: + - .docker-env + - .test-pr-refs + - .compiler-info + - .check-runtime-migration + variables: + NETWORK: "westend" + allow_failure: true # FIXME https://github.com/paritytech/substrate/issues/13107 + +check-runtime-migration-rococo: + stage: check + extends: + - .docker-env + - .test-pr-refs + - .compiler-info + - .check-runtime-migration + variables: + NETWORK: "rococo" + allow_failure: true # FIXME https://github.com/paritytech/substrate/issues/13107 + +# is broken, need to fix +check-no-default-features: + stage: check + extends: + - .docker-env + - .test-refs + - .compiler-info + script: + # Check that polkadot-cli will compile no default features. + - pushd ./node/service && cargo check --locked --no-default-features && popd + - pushd ./cli && cargo check --locked --no-default-features --features "service" && popd + - exit 0 + +# this is artificial job to run some build and tests using DAG +job-starter: + stage: check + image: paritytech/tools:latest + extends: + - .kubernetes-env + - .common-refs + script: + - echo ok diff --git a/polkadot/scripts/ci/gitlab/pipeline/publish.yml b/polkadot/scripts/ci/gitlab/pipeline/publish.yml new file mode 100644 index 0000000000000000000000000000000000000000..c224094125e375e527b11557b4e584a75c2ea44d --- /dev/null +++ b/polkadot/scripts/ci/gitlab/pipeline/publish.yml @@ -0,0 +1,276 @@ +# This file is part of .gitlab-ci.yml +# Here are all jobs that are executed during "publish" stage + +# This image is used in testnets +# Release image is handled by the Github Action here: +# .github/workflows/publish-docker-release.yml +publish-polkadot-debug-image: + stage: publish + extends: + - .kubernetes-env + - .build-push-image + rules: + # Don't run when triggered from another pipeline + - if: $CI_PIPELINE_SOURCE == "pipeline" + when: never + - if: $CI_PIPELINE_SOURCE == "web" + - if: $CI_PIPELINE_SOURCE == "schedule" + - if: $CI_COMMIT_REF_NAME == "master" + - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs + - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + variables: + IMAGE_NAME: "polkadot-debug" + BINARY: "polkadot,polkadot-execute-worker,polkadot-prepare-worker" + needs: + - job: build-linux-stable + artifacts: true + after_script: + - !reference [.build-push-image, after_script] + # pass artifacts to the zombienet-tests job + # https://docs.gitlab.com/ee/ci/multi_project_pipelines.html#with-variable-inheritance + - echo "PARACHAINS_IMAGE_NAME=${IMAGE}" > ./artifacts/parachains.env + - echo "PARACHAINS_IMAGE_TAG=$(cat ./artifacts/EXTRATAG)" >> ./artifacts/parachains.env + artifacts: + reports: + # this artifact is used in zombienet-tests job + dotenv: ./artifacts/parachains.env + expire_in: 1 days + +publish-test-collators-image: + # service image for Simnet + stage: publish + extends: + - .kubernetes-env + - .build-push-image + - .zombienet-refs + variables: + IMAGE_NAME: "colander" + BINARY: "adder-collator,undying-collator" + needs: + - job: build-test-collators + artifacts: true + after_script: + - !reference [.build-push-image, after_script] + # pass artifacts to the zombienet-tests job + - echo "COLLATOR_IMAGE_NAME=${IMAGE}" > ./artifacts/collator.env + - echo "COLLATOR_IMAGE_TAG=$(cat ./artifacts/EXTRATAG)" >> ./artifacts/collator.env + artifacts: + reports: + # this artifact is used in zombienet-tests job + dotenv: ./artifacts/collator.env + +publish-malus-image: + # service image for Simnet + stage: publish + extends: + - .kubernetes-env + - .build-push-image + - .zombienet-refs + variables: + IMAGE_NAME: "malus" + BINARY: "malus,polkadot-execute-worker,polkadot-prepare-worker" + needs: + - job: build-malus + artifacts: true + after_script: + - !reference [.build-push-image, after_script] + # pass artifacts to the zombienet-tests job + - echo "MALUS_IMAGE_NAME=${IMAGE}" > ./artifacts/malus.env + - echo "MALUS_IMAGE_TAG=$(cat ./artifacts/EXTRATAG)" >> ./artifacts/malus.env + artifacts: + reports: + # this artifact is used in zombienet-tests job + dotenv: ./artifacts/malus.env + +publish-staking-miner-image: + stage: publish + extends: + - .kubernetes-env + - .build-push-image + - .publish-refs + variables: + IMAGE_NAME: "staking-miner" + BINARY: "staking-miner" + DOCKER_OWNER: "paritytech" + DOCKER_USER: "${Docker_Hub_User_Parity}" + DOCKER_PASS: "${Docker_Hub_Pass_Parity}" + needs: + - job: build-staking-miner + artifacts: true + +publish-polkadot-image-description: + stage: publish + image: paritytech/dockerhub-description + variables: + DOCKER_USERNAME: ${Docker_Hub_User_Parity} + DOCKER_PASSWORD: ${Docker_Hub_Pass_Parity} + DOCKERHUB_REPOSITORY: parity/polkadot + SHORT_DESCRIPTION: "Polkadot Official Docker Image" + README_FILEPATH: $CI_PROJECT_DIR/scripts/ci/dockerfiles/polkadot/polkadot_Dockerfile.README.md + rules: + - if: $CI_COMMIT_REF_NAME == "master" + changes: + - scripts/ci/dockerfiles/polkadot/polkadot_Dockerfile.README.md + - if: $CI_PIPELINE_SOURCE == "schedule" + when: never + script: + - cd / && sh entrypoint.sh + tags: + - kubernetes-parity-build + +publish-staking-miner-image-description: + stage: publish + image: paritytech/dockerhub-description + variables: + DOCKER_USERNAME: ${Docker_Hub_User_Parity} + DOCKER_PASSWORD: ${Docker_Hub_Pass_Parity} + DOCKERHUB_REPOSITORY: paritytech/staking-miner + SHORT_DESCRIPTION: "Staking-miner Docker Image" + README_FILEPATH: $CI_PROJECT_DIR/scripts/ci/dockerfiles/staking-miner/staking-miner_Dockerfile.README.md + rules: + - if: $CI_COMMIT_REF_NAME == "master" + changes: + - scripts/ci/dockerfiles/staking-miner/staking-miner_Dockerfile.README.md + - if: $CI_PIPELINE_SOURCE == "schedule" + when: never + script: + - cd / && sh entrypoint.sh + tags: + - kubernetes-parity-build + +publish-s3-release: + stage: publish + extends: + - .kubernetes-env + needs: + - job: build-linux-stable + artifacts: true + variables: + CI_IMAGE: paritytech/awscli:latest + GIT_STRATEGY: none + PREFIX: "builds/polkadot/${ARCH}-${DOCKER_OS}" + rules: + - if: $CI_PIPELINE_SOURCE == "pipeline" + when: never + # publishing binaries nightly + - if: $CI_PIPELINE_SOURCE == "schedule" + before_script: + - !reference [.build-push-image, before_script] + script: + - echo "uploading objects to https://releases.parity.io/${PREFIX}/${VERSION}" + - aws s3 sync --acl public-read ./artifacts/ s3://${AWS_BUCKET}/${PREFIX}/${VERSION}/ + - echo "update objects at https://releases.parity.io/${PREFIX}/${EXTRATAG}" + - find ./artifacts -type f | while read file; do + name="${file#./artifacts/}"; + aws s3api copy-object + --copy-source ${AWS_BUCKET}/${PREFIX}/${VERSION}/${name} + --bucket ${AWS_BUCKET} --key ${PREFIX}/${EXTRATAG}/${name}; + done + - | + cat <<-EOM + | + | polkadot binary paths: + | + | - https://releases.parity.io/${PREFIX}/${EXTRATAG}/polkadot + | - https://releases.parity.io/${PREFIX}/${VERSION}/polkadot + | + EOM + after_script: + - aws s3 ls s3://${AWS_BUCKET}/${PREFIX}/${EXTRATAG}/ + --recursive --human-readable --summarize + +publish-rustdoc: + stage: publish + extends: + - .kubernetes-env + variables: + CI_IMAGE: paritytech/tools:latest + rules: + - if: $CI_PIPELINE_SOURCE == "pipeline" + when: never + - if: $CI_PIPELINE_SOURCE == "web" && $CI_COMMIT_REF_NAME == "master" + - if: $CI_COMMIT_REF_NAME == "master" + # `needs:` can be removed after CI image gets nonroot. In this case `needs:` stops other + # artifacts from being dowloaded by this job. + needs: + - job: build-rustdoc + artifacts: true + - job: build-implementers-guide + artifacts: true + script: + # Save README and docs + - cp -r ./crate-docs/ /tmp/doc/ + - cp -r ./artifacts/book/ /tmp/ + # setup ssh + - eval $(ssh-agent) + - ssh-add - <<< ${GITHUB_SSH_PRIV_KEY} + - mkdir ~/.ssh && touch ~/.ssh/known_hosts + - ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts + # Set git config + - git config user.email "devops-team@parity.io" + - git config user.name "${GITHUB_USER}" + - git config remote.origin.url "git@github.com:/paritytech/${CI_PROJECT_NAME}.git" + - git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" + - git fetch origin gh-pages + - git checkout gh-pages + # Remove everything and restore generated docs and README + - cp index.html /tmp + - cp README.md /tmp + - rm -rf ./* + # dir for rustdoc + - mkdir -p doc + # dir for implementors guide + - mkdir -p book + - mv /tmp/doc/* doc/ + - mv /tmp/book/html/* book/ + - mv /tmp/index.html . + - mv /tmp/README.md . + # Upload files + - git add --all --force + # `git commit` has an exit code of > 0 if there is nothing to commit. + # This causes GitLab to exit immediately and marks this job failed. + # We don't want to mark the entire job failed if there's nothing to + # publish though, hence the `|| true`. + - git commit -m "Updated docs for ${CI_COMMIT_REF_NAME}" || + echo "___Nothing to commit___" + - git push origin gh-pages --force + - echo "___Rustdoc was successfully published to https://paritytech.github.io/polkadot/___" + after_script: + - rm -rf .git/ ./* + +.update-substrate-template-repository: + stage: publish + extends: .kubernetes-env + variables: + GIT_STRATEGY: none + rules: + # The template is only updated for FINAL releases + # i.e. the rule should not cover RC or patch releases + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+$/ # e.g. v1.0 + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/ # e.g. v1.0.0 + script: + - git clone --depth=1 --branch="$PIPELINE_SCRIPTS_TAG" https://github.com/paritytech/pipeline-scripts + - export POLKADOT_BRANCH="polkadot-$CI_COMMIT_TAG" + - git clone --depth=1 --branch="$POLKADOT_BRANCH" https://github.com/paritytech/"$TEMPLATE_SOURCE" + - cd "$TEMPLATE_SOURCE" + - ../pipeline-scripts/update_substrate_template.sh + --repo-name "$TARGET_REPOSITORY" + --template-path "$TEMPLATE_PATH" + --github-api-token "$GITHUB_TOKEN" + --polkadot-branch "$POLKADOT_BRANCH" + +# Ref: https://github.com/paritytech/opstooling/issues/111 +update-node-template: + extends: .update-substrate-template-repository + variables: + TARGET_REPOSITORY: substrate-node-template + TEMPLATE_SOURCE: substrate + TEMPLATE_PATH: bin/node-template + +# Ref: https://github.com/paritytech/opstooling/issues/111 +update-parachain-template: + extends: .update-substrate-template-repository + variables: + TARGET_REPOSITORY: substrate-parachain-template + TEMPLATE_SOURCE: cumulus + TEMPLATE_PATH: parachain-template diff --git a/polkadot/scripts/ci/gitlab/pipeline/short-benchmarks.yml b/polkadot/scripts/ci/gitlab/pipeline/short-benchmarks.yml new file mode 100644 index 0000000000000000000000000000000000000000..dd150e5916e263c74e1d6bf98872142705800982 --- /dev/null +++ b/polkadot/scripts/ci/gitlab/pipeline/short-benchmarks.yml @@ -0,0 +1,27 @@ +# This file is part of .gitlab-ci.yml +# Here are all jobs that are executed during "short-benchmarks" stage + +# Run all pallet benchmarks only once to check if there are any errors +short-benchmark-polkadot: &short-bench + stage: short-benchmarks + extends: + - .test-pr-refs + - .docker-env + # this is an artificial job dependency, for pipeline optimization using GitLab's DAGs + needs: + - job: build-short-benchmark + artifacts: true + variables: + RUNTIME: polkadot + script: + - ./artifacts/polkadot benchmark pallet --wasm-execution compiled --chain $RUNTIME-dev --pallet "*" --extrinsic "*" --steps 2 --repeat 1 + +short-benchmark-kusama: + <<: *short-bench + variables: + RUNTIME: kusama + +short-benchmark-westend: + <<: *short-bench + variables: + RUNTIME: westend diff --git a/polkadot/scripts/ci/gitlab/pipeline/test.yml b/polkadot/scripts/ci/gitlab/pipeline/test.yml new file mode 100644 index 0000000000000000000000000000000000000000..963df0aa03031daef11fce665694cd5866d05c86 --- /dev/null +++ b/polkadot/scripts/ci/gitlab/pipeline/test.yml @@ -0,0 +1,119 @@ +# This file is part of .gitlab-ci.yml +# Here are all jobs that are executed during "test" stage + +# It's more like a check and it belongs to the previous stage, but we want to run this job with real tests in parallel +find-fail-ci-phrase: + stage: test + variables: + CI_IMAGE: "paritytech/tools:latest" + ASSERT_REGEX: "FAIL-CI" + GIT_DEPTH: 1 + extends: + - .kubernetes-env + script: + - set +e + - rg --line-number --hidden --type rust --glob '!{.git,target}' "$ASSERT_REGEX" .; exit_status=$? + - if [ $exit_status -eq 0 ]; then + echo "$ASSERT_REGEX was found, exiting with 1"; + exit 1; + else + echo "No $ASSERT_REGEX was found, exiting with 0"; + exit 0; + fi + +test-linux-stable: + stage: test + # this is an artificial job dependency, for pipeline optimization using GitLab's DAGs + # the job can be found in check.yml + needs: + - job: job-starter + artifacts: false + extends: + - .docker-env + - .common-refs + - .pipeline-stopper-artifacts + before_script: + - !reference [.compiler-info, before_script] + - !reference [.pipeline-stopper-vars, before_script] + variables: + RUST_TOOLCHAIN: stable + # Enable debug assertions since we are running optimized builds for testing + # but still want to have debug assertions. + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + script: + - time cargo test --workspace --profile testnet --verbose --locked --features=runtime-benchmarks,runtime-metrics,try-runtime,ci-only-tests + # Run `polkadot-runtime-parachains` tests a second time because `paras_inherent::enter` tests are gated by not having + # the `runtime-benchmarks` feature enabled. + - time cargo test --profile testnet --verbose --locked --features=runtime-metrics,try-runtime -p polkadot-runtime-parachains + +test-linux-oldkernel-stable: + extends: test-linux-stable + tags: + - oldkernel-vm + +.check-dependent-project: &check-dependent-project + stage: test + extends: + - .docker-env + - .test-pr-refs + script: + - git clone + --depth=1 + "--branch=$PIPELINE_SCRIPTS_TAG" + https://github.com/paritytech/pipeline-scripts + - ./pipeline-scripts/check_dependent_project.sh + --org paritytech + --dependent-repo "$DEPENDENT_REPO" + --github-api-token "$GITHUB_PR_TOKEN" + --extra-dependencies "$EXTRA_DEPENDENCIES" + --companion-overrides "$COMPANION_OVERRIDES" + +check-dependent-cumulus: + <<: *check-dependent-project + variables: + DEPENDENT_REPO: cumulus + EXTRA_DEPENDENCIES: substrate + COMPANION_OVERRIDES: | + polkadot: release-v* + cumulus: polkadot-v* + +test-node-metrics: + stage: test + extends: + - .docker-env + - .test-refs + - .compiler-info + variables: + RUST_TOOLCHAIN: stable + # Enable debug assertions since we are running optimized builds for testing + # but still want to have debug assertions. + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + script: + # Build the required workers. + - cargo build --bin polkadot-execute-worker --bin polkadot-prepare-worker --profile testnet --verbose --locked + # Run tests. + - time cargo test --profile testnet --verbose --locked --features=runtime-metrics -p polkadot-node-metrics + +test-deterministic-wasm: + stage: test + extends: + - .docker-env + - .test-refs + - .compiler-info + script: + - ./scripts/ci/gitlab/test_deterministic_wasm.sh + +cargo-clippy: + stage: test + # this is an artificial job dependency, for pipeline optimization using GitLab's DAGs + # the job can be found in check.yml + needs: + - job: job-starter + artifacts: false + extends: + - .docker-env + - .test-refs + script: + - echo $RUSTFLAGS + - cargo version && cargo clippy --version + - SKIP_WASM_BUILD=1 env -u RUSTFLAGS cargo clippy -q --locked --all-targets --workspace diff --git a/polkadot/scripts/ci/gitlab/pipeline/weights.yml b/polkadot/scripts/ci/gitlab/pipeline/weights.yml new file mode 100644 index 0000000000000000000000000000000000000000..edca9e769b4338a20d7099f8bc4a9bb839883286 --- /dev/null +++ b/polkadot/scripts/ci/gitlab/pipeline/weights.yml @@ -0,0 +1,39 @@ +# This file is part of .gitlab-ci.yml +# Here are all jobs that are executed during "weights" stage + +update_polkadot_weights: &update-weights + # The update-weights pipeline defaults to `interruptible: false` so that we'll be able to + # reach and run the benchmarking jobs despite the "Auto-cancel redundant pipelines" CI setting. + # The setting is relevant because future pipelines (e.g. created for new commits or other schedules) + # might otherwise cancel the benchmark jobs early. + interruptible: false + stage: weights + timeout: 1d + when: manual + image: $CI_IMAGE + variables: + RUNTIME: polkadot + artifacts: + paths: + - ${RUNTIME}_weights_${CI_COMMIT_SHORT_SHA}.patch + script: + - ./scripts/ci/run_benches_for_runtime.sh $RUNTIME + - git diff -P > ${RUNTIME}_weights_${CI_COMMIT_SHORT_SHA}.patch + # uses the "shell" executors + tags: + - weights + +update_kusama_weights: + <<: *update-weights + variables: + RUNTIME: kusama + +update_westend_weights: + <<: *update-weights + variables: + RUNTIME: westend + +update_rococo_weights: + <<: *update-weights + variables: + RUNTIME: rococo diff --git a/polkadot/scripts/ci/gitlab/pipeline/zombienet.yml b/polkadot/scripts/ci/gitlab/pipeline/zombienet.yml new file mode 100644 index 0000000000000000000000000000000000000000..62e081d1de0e5f4b61f2c1dc34a2ab53a73f3fe7 --- /dev/null +++ b/polkadot/scripts/ci/gitlab/pipeline/zombienet.yml @@ -0,0 +1,444 @@ +# This file is part of .gitlab-ci.yml +# Here are all jobs that are executed during "zombienet" stage + +zombienet-tests-parachains-smoke-test: + stage: zombienet + image: "${ZOMBIENET_IMAGE}" + extends: + - .kubernetes-env + - .zombienet-refs + needs: + - job: publish-polkadot-debug-image + - job: publish-malus-image + - job: publish-test-collators-image + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/smoke" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${MALUS_IMAGE_NAME} ${MALUS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie,zombie::network-node + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export MALUS_IMAGE=${MALUS_IMAGE_NAME}:${MALUS_IMAGE_TAG} + - export COL_IMAGE="docker.io/paritypr/colander:7292" # The collator image is fixed + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="0001-parachains-smoke-test.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-parachains-pvf: + stage: zombienet + image: "${ZOMBIENET_IMAGE}" + extends: + - .kubernetes-env + - .zombienet-refs + needs: + - job: publish-polkadot-debug-image + - job: publish-test-collators-image + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/functional" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "COL_IMAGE=${COLLATOR_IMAGE_NAME}:${COLLATOR_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie,zombie::network-node + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export MALUS_IMAGE=${MALUS_IMAGE_NAME}:${MALUS_IMAGE_TAG} + - export COL_IMAGE=${COLLATOR_IMAGE_NAME}:${COLLATOR_IMAGE_TAG} + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="0001-parachains-pvf.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-parachains-disputes: + stage: zombienet + image: "${ZOMBIENET_IMAGE}" + extends: + - .kubernetes-env + - .zombienet-refs + needs: + - job: publish-polkadot-debug-image + - job: publish-test-collators-image + - job: publish-malus-image + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/functional" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE_NAME}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${MALUS_IMAGE_NAME} ${MALUS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie,zombie::network-node + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export MALUS_IMAGE=${MALUS_IMAGE_NAME}:${MALUS_IMAGE_TAG} + - export COL_IMAGE=${COLLATOR_IMAGE_NAME}:${COLLATOR_IMAGE_TAG} + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="0002-parachains-disputes.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-parachains-disputes-garbage-candidate: + stage: zombienet + image: "${ZOMBIENET_IMAGE}" + extends: + - .kubernetes-env + - .zombienet-refs + needs: + - job: publish-polkadot-debug-image + - job: publish-test-collators-image + - job: publish-malus-image + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/functional" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE_NAME}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${MALUS_IMAGE_NAME} ${MALUS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie,zombie::network-node + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export MALUS_IMAGE=${MALUS_IMAGE_NAME}:${MALUS_IMAGE_TAG} + - export COL_IMAGE=${COLLATOR_IMAGE_NAME}:${COLLATOR_IMAGE_TAG} + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="0003-parachains-garbage-candidate.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-parachains-disputes-past-session: + stage: zombienet + image: "${ZOMBIENET_IMAGE}" + extends: + - .kubernetes-env + - .zombienet-refs + needs: + - job: publish-polkadot-debug-image + - job: publish-test-collators-image + - job: publish-malus-image + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/functional" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE_NAME}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${MALUS_IMAGE_NAME} ${MALUS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie,zombie::network-node + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export MALUS_IMAGE=${MALUS_IMAGE_NAME}:${MALUS_IMAGE_TAG} + - export COL_IMAGE=${COLLATOR_IMAGE_NAME}:${COLLATOR_IMAGE_TAG} + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="0004-parachains-disputes-past-session.zndsl" + allow_failure: true + retry: 2 + tags: + - zombienet-polkadot-integration-test + + +zombienet-test-parachains-upgrade-smoke-test: + stage: zombienet + image: "${ZOMBIENET_IMAGE}" + extends: + - .kubernetes-env + - .zombienet-refs + needs: + - job: publish-polkadot-debug-image + - job: publish-malus-image + - job: publish-test-collators-image + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/smoke" + before_script: + - echo "ZombieNet Tests Config" + - echo "${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG}" + - echo "docker.io/parity/polkadot-collator:latest" + - echo "${ZOMBIENET_IMAGE}" + - echo "${GH_DIR}" + - export DEBUG=zombie,zombie::network-node + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export COL_IMAGE="docker.io/parity/polkadot-collator:latest" # Use cumulus lastest image + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="0002-parachains-upgrade-smoke-test.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-misc-paritydb: + stage: zombienet + image: "${ZOMBIENET_IMAGE}" + extends: + - .kubernetes-env + - .zombienet-refs + needs: + - job: publish-polkadot-debug-image + - job: publish-test-collators-image + artifacts: true + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/misc" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE_NAME}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie,zombie::network-node + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export COL_IMAGE=${COLLATOR_IMAGE_NAME}:${COLLATOR_IMAGE_TAG} + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="0001-paritydb.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-misc-upgrade-node: + stage: zombienet + image: "${ZOMBIENET_IMAGE}" + extends: + - .kubernetes-env + - .zombienet-refs + needs: + - job: publish-polkadot-debug-image + - job: publish-test-collators-image + - job: build-linux-stable + artifacts: true + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/misc" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE_NAME}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie,zombie::network-node + - export ZOMBIENET_INTEGRATION_TEST_IMAGE="docker.io/parity/polkadot:latest" + - export COL_IMAGE=${COLLATOR_IMAGE_NAME}:${COLLATOR_IMAGE_TAG} + - BUILD_LINUX_JOB_ID="$(cat ./artifacts/BUILD_LINUX_JOB_ID)" + - export POLKADOT_PR_ARTIFACTS_URL="https://gitlab.parity.io/parity/mirrors/polkadot/-/jobs/${BUILD_LINUX_JOB_ID}/artifacts/raw/artifacts" + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="0002-upgrade-node.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-malus-dispute-valid: + stage: zombienet + image: "${ZOMBIENET_IMAGE}" + extends: + - .kubernetes-env + - .zombienet-refs + needs: + - job: publish-polkadot-debug-image + - job: publish-malus-image + - job: publish-test-collators-image + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/node/malus/integrationtests" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE_NAME}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${MALUS_IMAGE_NAME} ${MALUS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie* + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export MALUS_IMAGE=${MALUS_IMAGE_NAME}:${MALUS_IMAGE_TAG} + - export COL_IMAGE=${COLLATOR_IMAGE_NAME}:${COLLATOR_IMAGE_TAG} + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="0001-dispute-valid-block.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-deregister-register-validator: + stage: zombienet + image: "${ZOMBIENET_IMAGE}" + extends: + - .kubernetes-env + - .zombienet-refs + needs: + - job: publish-polkadot-debug-image + artifacts: true + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/smoke" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE_NAME}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie* + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export MALUS_IMAGE=${MALUS_IMAGE_NAME}:${MALUS_IMAGE_TAG} + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="0003-deregister-register-validator-smoke.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-beefy-and-mmr: + stage: zombienet + image: "${ZOMBIENET_IMAGE}" + extends: + - .kubernetes-env + - .zombienet-refs + needs: + - job: publish-polkadot-debug-image + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/functional" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE_NAME}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie* + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="0003-beefy-and-mmr.zndsl" + allow_failure: true + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-async-backing-compatibility: + stage: zombienet + extends: + - .kubernetes-env + - .zombienet-refs + image: "${ZOMBIENET_IMAGE}" + needs: + - job: publish-polkadot-debug-image + - job: publish-test-collators-image + - job: build-linux-stable + artifacts: true + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/async_backing" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE_NAME}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie,zombie::network-node + - BUILD_RELEASE_VERSION="$(cat ./artifacts/BUILD_RELEASE_VERSION)" + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export ZOMBIENET_INTEGRATION_TEST_SECONDARY_IMAGE="docker.io/parity/polkadot:${BUILD_RELEASE_VERSION}" + - export COL_IMAGE=${COLLATOR_IMAGE_NAME}:${COLLATOR_IMAGE_TAG} + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="001-async-backing-compatibility.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-async-backing-runtime-upgrade: + stage: zombienet + extends: + - .kubernetes-env + - .zombienet-refs + image: "${ZOMBIENET_IMAGE}" + needs: + - job: publish-polkadot-debug-image + - job: publish-test-collators-image + - job: build-linux-stable + artifacts: true + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/async_backing" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE_NAME}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie,zombie::network-node + - BUILD_RELEASE_VERSION="$(cat ./artifacts/BUILD_RELEASE_VERSION)" + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export ZOMBIENET_INTEGRATION_TEST_SECONDARY_IMAGE="docker.io/parity/polkadot:${BUILD_RELEASE_VERSION}" + - export COL_IMAGE=${COLLATOR_IMAGE_NAME}:${COLLATOR_IMAGE_TAG} + - export POLKADOT_PR_BIN_URL="https://gitlab.parity.io/parity/mirrors/polkadot/-/jobs/${BUILD_LINUX_JOB_ID}/artifacts/raw/artifacts/polkadot" + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="002-async-backing-runtime-upgrade.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test + +zombienet-tests-async-backing-collator-mix: + stage: zombienet + extends: + - .kubernetes-env + - .zombienet-refs + image: "${ZOMBIENET_IMAGE}" + needs: + - job: publish-polkadot-debug-image + - job: publish-test-collators-image + - job: build-linux-stable + artifacts: true + variables: + RUN_IN_CONTAINER: "1" + GH_DIR: "https://github.com/paritytech/polkadot/tree/${CI_COMMIT_SHORT_SHA}/zombienet_tests/async_backing" + before_script: + - echo "Zombie-net Tests Config" + - echo "${ZOMBIENET_IMAGE_NAME}" + - echo "${PARACHAINS_IMAGE_NAME} ${PARACHAINS_IMAGE_TAG}" + - echo "${GH_DIR}" + - export DEBUG=zombie,zombie::network-node + - BUILD_RELEASE_VERSION="$(cat ./artifacts/BUILD_RELEASE_VERSION)" + - export ZOMBIENET_INTEGRATION_TEST_IMAGE=${PARACHAINS_IMAGE_NAME}:${PARACHAINS_IMAGE_TAG} + - export ZOMBIENET_INTEGRATION_TEST_SECONDARY_IMAGE="docker.io/parity/polkadot:${BUILD_RELEASE_VERSION}" + - export COL_IMAGE=${COLLATOR_IMAGE_NAME}:${COLLATOR_IMAGE_TAG} + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-env-manager.sh + --github-remote-dir="${GH_DIR}" + --test="003-async-backing-collator-mix.zndsl" + allow_failure: false + retry: 2 + tags: + - zombienet-polkadot-integration-test diff --git a/polkadot/scripts/ci/gitlab/prettier.sh b/polkadot/scripts/ci/gitlab/prettier.sh new file mode 100755 index 0000000000000000000000000000000000000000..299bbee179dcaeff3fbadffd89fb4548ac878555 --- /dev/null +++ b/polkadot/scripts/ci/gitlab/prettier.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +# meant to be installed via +# git config filter.ci-prettier.clean "scripts/ci/gitlab/prettier.sh" + +prettier --parser yaml diff --git a/polkadot/scripts/ci/gitlab/spellcheck.toml b/polkadot/scripts/ci/gitlab/spellcheck.toml new file mode 100644 index 0000000000000000000000000000000000000000..636cafa2cc4e93484215284c897ded7b507cec54 --- /dev/null +++ b/polkadot/scripts/ci/gitlab/spellcheck.toml @@ -0,0 +1,34 @@ +[hunspell] +lang = "en_US" +search_dirs = ["."] +extra_dictionaries = ["lingua.dic"] +skip_os_lookups = true +use_builtin = true + +[hunspell.quirks] +# He tagged it as 'TheGreatestOfAllTimes' +transform_regex = [ +# `Type`'s + "^'([^\\s])'$", +# 5x +# 10.7% + "^[0-9_]+(?:\\.[0-9]*)?(x|%)$", +# Transforms' + "^(.*)'$", +# backslashes + "^\\+$", + "^[0-9]*+k|MB|Mb|ms|Mbit|nd|th|rd$", +# single char `=` `>` `%` .. + "^=|>|<|%$", +# 22_100 + "^(?:[0-9]+_)+[0-9]+$", +# V5, v5, P1.2, etc + "[A-Za-z][0-9]", +# ~50 + "~[0-9]+", + "ABI", + "bool", + "sigil", +] +allow_concatenation = true +allow_dashes = true diff --git a/polkadot/scripts/ci/gitlab/test_deterministic_wasm.sh b/polkadot/scripts/ci/gitlab/test_deterministic_wasm.sh new file mode 100755 index 0000000000000000000000000000000000000000..b4292376942156e326517d3b3df3c99424270e6b --- /dev/null +++ b/polkadot/scripts/ci/gitlab/test_deterministic_wasm.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +#shellcheck source=../common/lib.sh +source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/../common/lib.sh" + +# build runtime +WASM_BUILD_NO_COLOR=1 cargo build --verbose --release -p kusama-runtime -p polkadot-runtime -p westend-runtime +# make checksum +sha256sum target/release/wbuild/*-runtime/target/wasm32-unknown-unknown/release/*.wasm > checksum.sha256 +# clean up - FIXME: can we reuse some of the artifacts? +cargo clean +# build again +WASM_BUILD_NO_COLOR=1 cargo build --verbose --release -p kusama-runtime -p polkadot-runtime -p westend-runtime +# confirm checksum +sha256sum -c checksum.sha256 diff --git a/polkadot/scripts/ci/run_benches_for_runtime.sh b/polkadot/scripts/ci/run_benches_for_runtime.sh new file mode 100755 index 0000000000000000000000000000000000000000..296985a42764767c9a6c98b1c51d8a8939e7210d --- /dev/null +++ b/polkadot/scripts/ci/run_benches_for_runtime.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +# Runs all benchmarks for all pallets, for a given runtime, provided by $1 +# Should be run on a reference machine to gain accurate benchmarks +# current reference machine: https://github.com/paritytech/substrate/pull/5848 + +runtime="$1" + +echo "[+] Compiling benchmarks..." +cargo build --profile production --locked --features=runtime-benchmarks + +# Load all pallet names in an array. +PALLETS=($( + ./target/production/polkadot benchmark pallet --list --chain="${runtime}-dev" |\ + tail -n+2 |\ + cut -d',' -f1 |\ + sort |\ + uniq +)) + +echo "[+] Benchmarking ${#PALLETS[@]} pallets for runtime $runtime" + +# Define the error file. +ERR_FILE="benchmarking_errors.txt" +# Delete the error file before each run. +rm -f $ERR_FILE + +# Benchmark each pallet. +for PALLET in "${PALLETS[@]}"; do + echo "[+] Benchmarking $PALLET for $runtime"; + + output_file="" + if [[ $PALLET == *"::"* ]]; then + # translates e.g. "pallet_foo::bar" to "pallet_foo_bar" + output_file="${PALLET//::/_}.rs" + fi + + OUTPUT=$( + ./target/production/polkadot benchmark pallet \ + --chain="${runtime}-dev" \ + --steps=50 \ + --repeat=20 \ + --pallet="$PALLET" \ + --extrinsic="*" \ + --wasm-execution=compiled \ + --header=./file_header.txt \ + --output="./runtime/${runtime}/src/weights/${output_file}" 2>&1 + ) + if [ $? -ne 0 ]; then + echo "$OUTPUT" >> "$ERR_FILE" + echo "[-] Failed to benchmark $PALLET. Error written to $ERR_FILE; continuing..." + fi +done + +# Update the block and extrinsic overhead weights. +echo "[+] Benchmarking block and extrinsic overheads..." +OUTPUT=$( + ./target/production/polkadot benchmark overhead \ + --chain="${runtime}-dev" \ + --wasm-execution=compiled \ + --weight-path="runtime/${runtime}/constants/src/weights/" \ + --warmup=10 \ + --repeat=100 \ + --header=./file_header.txt +) +if [ $? -ne 0 ]; then + echo "$OUTPUT" >> "$ERR_FILE" + echo "[-] Failed to benchmark the block and extrinsic overheads. Error written to $ERR_FILE; continuing..." +fi + +# Check if the error file exists. +if [ -f "$ERR_FILE" ]; then + echo "[-] Some benchmarks failed. See: $ERR_FILE" +else + echo "[+] All benchmarks passed." +fi diff --git a/polkadot/scripts/common.sh b/polkadot/scripts/common.sh new file mode 100644 index 0000000000000000000000000000000000000000..56e16bd48121a438c4089b4577d4c3238e5296a6 --- /dev/null +++ b/polkadot/scripts/common.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +ROOT=`dirname "$0"` + +# A list of directories which contain wasm projects. +SRCS=( + "runtime/wasm" +) + +DEMOS=( + "test-parachains/" +) + +# Make pushd/popd silent. + +pushd () { + command pushd "$@" > /dev/null +} + +popd () { + command popd "$@" > /dev/null +} diff --git a/polkadot/scripts/init.sh b/polkadot/scripts/init.sh new file mode 100755 index 0000000000000000000000000000000000000000..cf5ecf97926fea7a5e8fd2a91df96853f90e8ee7 --- /dev/null +++ b/polkadot/scripts/init.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +set -e + +echo "*** Initializing WASM build environment" + +if [ -z $CI_PROJECT_NAME ] ; then + rustup update nightly + rustup update stable +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/polkadot/scripts/packaging/deb-maintainer-scripts/postinst b/polkadot/scripts/packaging/deb-maintainer-scripts/postinst new file mode 100644 index 0000000000000000000000000000000000000000..3ac5cd04c3760487e7680e2f84336238563ce4fe --- /dev/null +++ b/polkadot/scripts/packaging/deb-maintainer-scripts/postinst @@ -0,0 +1,17 @@ +#!/bin/sh + +set -e + +action="$1" +config_file="/etc/default/polkadot" + +if [ "$action" = "configure" ]; then + # Make user and group + getent group polkadot >/dev/null 2>&1 || addgroup --system polkadot + getent passwd polkadot >/dev/null 2>&1 || + adduser --system --home /home/polkadot --disabled-password \ + --ingroup polkadot polkadot + if [ ! -e "$config_file" ]; then + echo 'POLKADOT_CLI_ARGS=""' > /etc/default/polkadot + fi +fi diff --git a/polkadot/scripts/packaging/polkadot.service b/polkadot/scripts/packaging/polkadot.service new file mode 100644 index 0000000000000000000000000000000000000000..7fb549c97f8b9ee439e960d1ff233aff8a6bd514 --- /dev/null +++ b/polkadot/scripts/packaging/polkadot.service @@ -0,0 +1,37 @@ +[Unit] +Description=Polkadot Node +After=network.target +Documentation=https://github.com/paritytech/polkadot + +[Service] +EnvironmentFile=-/etc/default/polkadot +ExecStart=/usr/bin/polkadot $POLKADOT_CLI_ARGS +User=polkadot +Group=polkadot +Restart=always +RestartSec=120 +CapabilityBoundingSet= +LockPersonality=true +NoNewPrivileges=true +PrivateDevices=true +PrivateMounts=true +PrivateTmp=true +PrivateUsers=true +ProtectClock=true +ProtectControlGroups=true +ProtectHostname=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectSystem=strict +RemoveIPC=true +RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX +RestrictNamespaces=true +RestrictSUIDSGID=true +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallFilter=landlock_add_rule landlock_create_ruleset landlock_restrict_self seccomp +SystemCallFilter=~@clock @module @mount @reboot @swap @privileged +UMask=0027 + +[Install] +WantedBy=multi-user.target diff --git a/polkadot/scripts/prepare-test-net.sh b/polkadot/scripts/prepare-test-net.sh new file mode 100755 index 0000000000000000000000000000000000000000..c908aba308a39bdbc9a1a691cd13bb933a15f56e --- /dev/null +++ b/polkadot/scripts/prepare-test-net.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +set -e + +if [ "$#" -ne 1 ]; then + echo "Please provide the number of initial validators!" + exit 1 +fi + +generate_account_id() { + subkey inspect ${3:-} ${4:-} "$SECRET//$1//$2" | grep "Account ID" | awk '{ print $3 }' +} + +generate_address() { + subkey inspect ${3:-} ${4:-} "$SECRET//$1//$2" | grep "SS58 Address" | awk '{ print $3 }' +} + +generate_public_key() { + subkey inspect ${3:-} ${4:-} "$SECRET//$1//$2" | grep "Public key (hex)" | awk '{ print $4 }' +} + +generate_address_and_public_key() { + ADDRESS=$(generate_address $1 $2 $3) + PUBLIC_KEY=$(generate_public_key $1 $2 $3) + + printf "//$ADDRESS\nhex![\"${PUBLIC_KEY#'0x'}\"].unchecked_into()," +} + +generate_address_and_account_id() { + ACCOUNT=$(generate_account_id $1 $2 $3) + ADDRESS=$(generate_address $1 $2 $3) + if ${4:-false}; then + INTO="unchecked_into" + else + INTO="into" + fi + + printf "//$ADDRESS\nhex![\"${ACCOUNT#'0x'}\"].$INTO()," +} + +V_NUM=$1 + +AUTHORITIES="" + +for i in $(seq 1 $V_NUM); do + AUTHORITIES+="(\n" + AUTHORITIES+="$(generate_address_and_account_id $i stash)\n" + AUTHORITIES+="$(generate_address_and_account_id $i controller)\n" + AUTHORITIES+="$(generate_address_and_account_id $i babe '--scheme sr25519' true)\n" + AUTHORITIES+="$(generate_address_and_account_id $i grandpa '--scheme ed25519' true)\n" + AUTHORITIES+="$(generate_address_and_account_id $i im_online '--scheme sr25519' true)\n" + AUTHORITIES+="$(generate_address_and_account_id $i para_validator '--scheme sr25519' true)\n" + AUTHORITIES+="$(generate_address_and_account_id $i para_assignment '--scheme sr25519' true)\n" + AUTHORITIES+="$(generate_address_and_account_id $i authority_discovery '--scheme sr25519' true)\n" + AUTHORITIES+="$(generate_address_and_public_key $i beefy '--scheme ecdsa' true)\n" + AUTHORITIES+="),\n" +done + +printf "$AUTHORITIES" diff --git a/polkadot/scripts/release.sh b/polkadot/scripts/release.sh new file mode 100755 index 0000000000000000000000000000000000000000..323fee1af01be50ae4f4c8f526ba8bd6d39be8ce --- /dev/null +++ b/polkadot/scripts/release.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -e + +# This script is to be run when we are happy with a release candidate. +# It accepts a single argument: version, in the format 'v1.2.3' + +version="$1" +if [ -z "$version" ]; then + echo "No version specified, cannot continue" + exit 1 +fi + +if [[ ! "$version" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Version should be in the format v1.2.3" + exit 1 +fi + +echo '[+] Checking out the release branch' +git checkout release +echo '[+] Pulling latest version of the release branch from github' +git pull +echo '[+] Attempting to merge the release-candidate branch to the release branch' +git merge "$version" +echo '[+] Tagging the release' +git tag -s -m "$version" "$version" +echo '[+] Pushing the release branch and tag to Github. A new release will be created shortly' +git push origin release +git push origin "refs/tags/$version" diff --git a/polkadot/scripts/run_all_benches.sh b/polkadot/scripts/run_all_benches.sh new file mode 100755 index 0000000000000000000000000000000000000000..923013f351555c348cdd5c169f8d7382ac5f0a5b --- /dev/null +++ b/polkadot/scripts/run_all_benches.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Runs all benchmarks for all pallets, for each of the runtimes specified below +# Should be run on a reference machine to gain accurate benchmarks +# current reference machine: https://github.com/paritytech/substrate/pull/5848 + +runtimes=( + polkadot + kusama + westend +) + +for runtime in "${runtimes[@]}"; do + "$(dirname "$0")/run_benches_for_runtime.sh" "$runtime" +done diff --git a/polkadot/scripts/two-node-local-net.sh b/polkadot/scripts/two-node-local-net.sh new file mode 100755 index 0000000000000000000000000000000000000000..4e3291b015ad569f129d2234000c083cbbb9d9e1 --- /dev/null +++ b/polkadot/scripts/two-node-local-net.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +# Run a two node local net. +# Unlike the docker-compose script in the /docker folder, this version builds the nodes based +# on the current state of the code, instead of depending on a published version. + +set -e + +# chainspec defaults to polkadot-local if no arguments are passed to this script; +# if arguments are passed in, the first is the chainspec +chainspec="${1:-polkadot-local}" + +PROJECT_ROOT=$(git rev-parse --show-toplevel) +# shellcheck disable=SC1090 +source "$(dirname "$0")"/common.sh + +cd "$PROJECT_ROOT" + +last_modified_rust_file=$( + find . -path ./target -prune -o -type f -name '*.rs' -printf '%T@ %p\n' | + sort -nr | + head -1 | + cut -d' ' -f2- +) + +polkadot="target/release/polkadot" + +# ensure the polkadot binary exists and is up to date +if [ ! -x "$polkadot" ] || [ "$polkadot" -ot "$last_modified_rust_file" ]; then + cargo build --release +fi + +# setup variables +node_offset=0 +declare -a node_pids +declare -a node_pipes + +# create a sed expression which injects the node name and stream type into each line +function make_sed_expr() { + name="$1" + type="$2" + + printf "s/^/%8s %s: /" "$name" "$type" +} + +# turn a string into a flag +function flagify() { + printf -- '--%s' "$(tr '[:upper:]' '[:lower:]' <<< "$1")" +} + +# start a node and label its output +# +# This function takes a single argument, the node name. +# The name must be one of those which can be passed to the polkadot binary, in un-flagged form, +# one of: +# alice, bob, charlie, dave, eve, ferdie, one, two +function run_node() { + name="$1" + # create a named pipe so we can get the node's PID while also sedding its output + local stdout + local stderr + stdout=$(mktemp --dry-run --tmpdir) + stderr=$(mktemp --dry-run --tmpdir) + mkfifo "$stdout" + mkfifo "$stderr" + node_pipes+=("$stdout") + node_pipes+=("$stderr") + + # compute ports from offset + local port=$((30333+node_offset)) + local rpc_port=$((9933+node_offset)) + local ws_port=$((9944+node_offset)) + node_offset=$((node_offset+1)) + + # start the node + "$polkadot" \ + --chain "$chainspec" \ + --tmp \ + --port "$port" \ + --rpc-port "$rpc_port" \ + --ws-port "$ws_port" \ + --rpc-cors all \ + "$(flagify "$name")" \ + > "$stdout" \ + 2> "$stderr" \ + & + local pid=$! + node_pids+=("$pid") + + # send output from the stdout pipe to stdout, prepending the node name + sed -e "$(make_sed_expr "$name" "OUT")" "$stdout" >&1 & + # send output from the stderr pipe to stderr, prepending the node name + sed -e "$(make_sed_expr "$name" "ERR")" "$stderr" >&2 & +} + + +# clean up the nodes when this script exits +function finish { + for node_pid in "${node_pids[@]}"; do + kill -9 "$node_pid" + done + for node_pipe in "${node_pipes[@]}"; do + rm "$node_pipe" + done +} +trap finish EXIT + +# start the nodes +run_node Alice +run_node Bob + +# now wait; this will exit on its own only if both subprocesses exit +# the practical implication, as both subprocesses are supposed to run forever, is that +# this script will also run forever, until killed, at which point the exit trap should kill +# the subprocesses +wait diff --git a/polkadot/scripts/update-rust-stable.sh b/polkadot/scripts/update-rust-stable.sh new file mode 100755 index 0000000000000000000000000000000000000000..6aae75d8cb2daa2dee5a332d19c31cd8f4fe818f --- /dev/null +++ b/polkadot/scripts/update-rust-stable.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# Script for updating the UI tests for a new rust stable version. +# +# It needs to be called like this: +# +# update-rust-stable.sh 1.61 +# +# This will run all UI tests with the rust stable 1.61. The script +# requires that rustup is installed. +set -e + +if [ "$#" -ne 1 ]; then + echo "Please specify the rust version to use. E.g. update-rust-stable.sh 1.61" + exit +fi + +RUST_VERSION=$1 + +if ! command -v rustup &> /dev/null +then + echo "rustup needs to be installed" + exit +fi + +rustup install $RUST_VERSION +rustup component add rust-src --toolchain $RUST_VERSION + +# Ensure we run the ui tests +export RUN_UI_TESTS=1 +# We don't need any wasm files for ui tests +export SKIP_WASM_BUILD=1 +# Let trybuild overwrite the .stderr files +export TRYBUILD=overwrite + +# Run all the relevant UI tests +# +# Any new UI tests in different crates need to be added here as well. +rustup run $RUST_VERSION cargo test -p orchestra ui diff --git a/polkadot/src/README.adoc b/polkadot/src/README.adoc new file mode 100644 index 0000000000000000000000000000000000000000..4ec8e18d8afe90105104bf0d5434f8f7fc8c94ff --- /dev/null +++ b/polkadot/src/README.adoc @@ -0,0 +1,5 @@ + += Polkadot Src + +placeholder +//TODO Write content :) (https://github.com/paritytech/polkadot/issues/159) diff --git a/polkadot/src/bin/execute-worker.rs b/polkadot/src/bin/execute-worker.rs new file mode 100644 index 0000000000000000000000000000000000000000..72cab799d753e814beae0a337e30b7c21269f08d --- /dev/null +++ b/polkadot/src/bin/execute-worker.rs @@ -0,0 +1,23 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Execute worker. + +polkadot_node_core_pvf_common::decl_worker_main!( + "execute-worker", + polkadot_node_core_pvf_execute_worker::worker_entrypoint, + env!("SUBSTRATE_CLI_IMPL_VERSION") +); diff --git a/polkadot/src/bin/prepare-worker.rs b/polkadot/src/bin/prepare-worker.rs new file mode 100644 index 0000000000000000000000000000000000000000..695f66cc7b7d3cae5c35a36af9570ce3911ed432 --- /dev/null +++ b/polkadot/src/bin/prepare-worker.rs @@ -0,0 +1,23 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Prepare worker. + +polkadot_node_core_pvf_common::decl_worker_main!( + "prepare-worker", + polkadot_node_core_pvf_prepare_worker::worker_entrypoint, + env!("SUBSTRATE_CLI_IMPL_VERSION") +); diff --git a/polkadot/src/main.rs b/polkadot/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..5986d8cea7bb5029ed34bb953f6c02aac009d1e9 --- /dev/null +++ b/polkadot/src/main.rs @@ -0,0 +1,33 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Polkadot CLI + +#![warn(missing_docs)] + +use color_eyre::eyre; + +/// Global allocator. Changing it to another allocator will require changing +/// `memory_stats::MemoryAllocationTracker`. +#[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))] +#[global_allocator] +pub static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; + +fn main() -> eyre::Result<()> { + color_eyre::install()?; + polkadot_cli::run()?; + Ok(()) +} diff --git a/polkadot/statement-table/Cargo.toml b/polkadot/statement-table/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..6c1a3d143454b2cc2499d2991a138e7ed3119fba --- /dev/null +++ b/polkadot/statement-table/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "polkadot-statement-table" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +primitives = { package = "polkadot-primitives", path = "../primitives" } diff --git a/polkadot/statement-table/README.adoc b/polkadot/statement-table/README.adoc new file mode 100644 index 0000000000000000000000000000000000000000..a4da4dee80ff5fc9917d93fa705e66220fb34696 --- /dev/null +++ b/polkadot/statement-table/README.adoc @@ -0,0 +1,5 @@ + += Polkadot Statement table + +placeholder +//TODO Write content :) (https://github.com/paritytech/polkadot/issues/159) diff --git a/polkadot/statement-table/src/generic.rs b/polkadot/statement-table/src/generic.rs new file mode 100644 index 0000000000000000000000000000000000000000..a427aae42fb9523a21a416a106b61f56e8be46c2 --- /dev/null +++ b/polkadot/statement-table/src/generic.rs @@ -0,0 +1,989 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The statement table: generic implementation. +//! +//! This stores messages other authorities issue about candidates. +//! +//! These messages are used to create a proposal submitted to a BFT consensus process. +//! +//! Each parachain is associated with a committee of authorities, who issue statements +//! indicating whether the candidate is valid or invalid. Once a threshold of the committee +//! has signed validity statements, the candidate may be marked includable. + +use std::{ + collections::hash_map::{self, Entry, HashMap}, + fmt::Debug, + hash::Hash, +}; + +use primitives::{ValidatorSignature, ValidityAttestation as PrimitiveValidityAttestation}; + +use parity_scale_codec::{Decode, Encode}; + +/// Context for the statement table. +pub trait Context { + /// An authority ID + type AuthorityId: Debug + Hash + Eq + Clone; + /// The digest (hash or other unique attribute) of a candidate. + type Digest: Debug + Hash + Eq + Clone; + /// The group ID type + type GroupId: Debug + Hash + Ord + Eq + Clone; + /// A signature type. + type Signature: Debug + Eq + Clone; + /// Candidate type. In practice this will be a candidate receipt. + type Candidate: Debug + Ord + Eq + Clone; + + /// get the digest of a candidate. + fn candidate_digest(candidate: &Self::Candidate) -> Self::Digest; + + /// get the group of a candidate. + fn candidate_group(candidate: &Self::Candidate) -> Self::GroupId; + + /// Whether a authority is a member of a group. + /// Members are meant to submit candidates and vote on validity. + fn is_member_of(&self, authority: &Self::AuthorityId, group: &Self::GroupId) -> bool; + + /// requisite number of votes for validity from a group. + fn requisite_votes(&self, group: &Self::GroupId) -> usize; +} + +/// Table configuration. +pub struct Config { + /// When this is true, the table will allow multiple seconded candidates + /// per authority. This flag means that higher-level code is responsible for + /// bounding the number of candidates. + pub allow_multiple_seconded: bool, +} + +/// Statements circulated among peers. +#[derive(PartialEq, Eq, Debug, Clone, Encode, Decode)] +pub enum Statement { + /// Broadcast by an authority to indicate that this is its candidate for inclusion. + /// + /// Broadcasting two different candidate messages per round is not allowed. + #[codec(index = 1)] + Seconded(Candidate), + /// Broadcast by a authority to attest that the candidate with given digest is valid. + #[codec(index = 2)] + Valid(Digest), +} + +/// A signed statement. +#[derive(PartialEq, Eq, Debug, Clone, Encode, Decode)] +pub struct SignedStatement { + /// The statement. + pub statement: Statement, + /// The signature. + pub signature: Signature, + /// The sender. + pub sender: AuthorityId, +} + +/// Misbehavior: voting more than one way on candidate validity. +/// +/// Since there are three possible ways to vote, a double vote is possible in +/// three possible combinations (unordered) +#[derive(PartialEq, Eq, Debug, Clone)] +pub enum ValidityDoubleVote { + /// Implicit vote by issuing and explicitly voting validity. + IssuedAndValidity((Candidate, Signature), (Digest, Signature)), +} + +impl ValidityDoubleVote { + /// Deconstruct this misbehavior into two `(Statement, Signature)` pairs, erasing the + /// information about precisely what the problem was. + pub fn deconstruct( + self, + ) -> ((Statement, Signature), (Statement, Signature)) + where + Ctx: Context, + Candidate: Debug + Ord + Eq + Clone, + Digest: Debug + Hash + Eq + Clone, + Signature: Debug + Eq + Clone, + { + match self { + Self::IssuedAndValidity((c, s1), (d, s2)) => + ((Statement::Seconded(c), s1), (Statement::Valid(d), s2)), + } + } +} + +/// Misbehavior: multiple signatures on same statement. +#[derive(PartialEq, Eq, Debug, Clone)] +pub enum DoubleSign { + /// On candidate. + Seconded(Candidate, Signature, Signature), + /// On validity. + Validity(Digest, Signature, Signature), +} + +impl DoubleSign { + /// Deconstruct this misbehavior into a statement with two signatures, erasing the information + /// about precisely where in the process the issue was detected. + pub fn deconstruct(self) -> (Statement, Signature, Signature) { + match self { + Self::Seconded(candidate, a, b) => (Statement::Seconded(candidate), a, b), + Self::Validity(digest, a, b) => (Statement::Valid(digest), a, b), + } + } +} + +/// Misbehavior: declaring multiple candidates. +#[derive(PartialEq, Eq, Debug, Clone)] +pub struct MultipleCandidates { + /// The first candidate seen. + pub first: (Candidate, Signature), + /// The second candidate seen. + pub second: (Candidate, Signature), +} + +/// Misbehavior: submitted statement for wrong group. +#[derive(PartialEq, Eq, Debug, Clone)] +pub struct UnauthorizedStatement { + /// A signed statement which was submitted without proper authority. + pub statement: SignedStatement, +} + +/// Different kinds of misbehavior. All of these kinds of malicious misbehavior +/// are easily provable and extremely disincentivized. +#[derive(PartialEq, Eq, Debug, Clone)] +pub enum Misbehavior { + /// Voted invalid and valid on validity. + ValidityDoubleVote(ValidityDoubleVote), + /// Submitted multiple candidates. + MultipleCandidates(MultipleCandidates), + /// Submitted a message that was unauthorized. + UnauthorizedStatement(UnauthorizedStatement), + /// Submitted two valid signatures for the same message. + DoubleSign(DoubleSign), +} + +/// Type alias for misbehavior corresponding to context type. +pub type MisbehaviorFor = Misbehavior< + ::Candidate, + ::Digest, + ::AuthorityId, + ::Signature, +>; + +// Kinds of votes for validity on a particular candidate. +#[derive(Clone, PartialEq, Eq)] +enum ValidityVote { + // Implicit validity vote. + Issued(Signature), + // Direct validity vote. + Valid(Signature), +} + +/// A summary of import of a statement. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Summary { + /// The digest of the candidate referenced. + pub candidate: Digest, + /// The group that the candidate is in. + pub group_id: Group, + /// How many validity votes are currently witnessed. + pub validity_votes: usize, +} + +/// A validity attestation. +#[derive(Clone, PartialEq, Decode, Encode)] +pub enum ValidityAttestation { + /// implicit validity attestation by issuing. + /// This corresponds to issuance of a `Candidate` statement. + Implicit(Signature), + /// An explicit attestation. This corresponds to issuance of a + /// `Valid` statement. + Explicit(Signature), +} + +impl Into for ValidityAttestation { + fn into(self) -> PrimitiveValidityAttestation { + match self { + Self::Implicit(s) => PrimitiveValidityAttestation::Implicit(s), + Self::Explicit(s) => PrimitiveValidityAttestation::Explicit(s), + } + } +} + +/// An attested-to candidate. +#[derive(Clone, PartialEq, Decode, Encode)] +pub struct AttestedCandidate { + /// The group ID that the candidate is in. + pub group_id: Group, + /// The candidate data. + pub candidate: Candidate, + /// Validity attestations. + pub validity_votes: Vec<(AuthorityId, ValidityAttestation)>, +} + +/// Stores votes and data about a candidate. +pub struct CandidateData { + group_id: Ctx::GroupId, + candidate: Ctx::Candidate, + validity_votes: HashMap>, +} + +impl CandidateData { + /// Yield a full attestation for a candidate. + /// If the candidate can be included, it will return `Some`. + pub fn attested( + &self, + validity_threshold: usize, + ) -> Option> { + let valid_votes = self.validity_votes.len(); + if valid_votes < validity_threshold { + return None + } + + let validity_votes = self + .validity_votes + .iter() + .map(|(a, v)| match *v { + ValidityVote::Valid(ref s) => (a.clone(), ValidityAttestation::Explicit(s.clone())), + ValidityVote::Issued(ref s) => + (a.clone(), ValidityAttestation::Implicit(s.clone())), + }) + .collect(); + + Some(AttestedCandidate { + group_id: self.group_id.clone(), + candidate: self.candidate.clone(), + validity_votes, + }) + } + + fn summary(&self, digest: Ctx::Digest) -> Summary { + Summary { + candidate: digest, + group_id: self.group_id.clone(), + validity_votes: self.validity_votes.len(), + } + } +} + +// authority metadata +struct AuthorityData { + proposals: Vec<(Ctx::Digest, Ctx::Signature)>, +} + +impl Default for AuthorityData { + fn default() -> Self { + AuthorityData { proposals: Vec::new() } + } +} + +/// Type alias for the result of a statement import. +pub type ImportResult = Result< + Option::Digest, ::GroupId>>, + MisbehaviorFor, +>; + +/// Stores votes +pub struct Table { + authority_data: HashMap>, + detected_misbehavior: HashMap>>, + candidate_votes: HashMap>, + config: Config, +} + +impl Table { + /// Create a new `Table` from a `Config`. + pub fn new(config: Config) -> Self { + Table { + authority_data: HashMap::default(), + detected_misbehavior: HashMap::default(), + candidate_votes: HashMap::default(), + config, + } + } + + /// Get the attested candidate for `digest`. + /// + /// Returns `Some(_)` if the candidate exists and is includable. + pub fn attested_candidate( + &self, + digest: &Ctx::Digest, + context: &Ctx, + ) -> Option> { + self.candidate_votes.get(digest).and_then(|data| { + let v_threshold = context.requisite_votes(&data.group_id); + data.attested(v_threshold) + }) + } + + /// Import a signed statement. Signatures should be checked for validity, and the + /// sender should be checked to actually be an authority. + /// + /// Validity and invalidity statements are only valid if the corresponding + /// candidate has already been imported. + /// + /// If this returns `None`, the statement was either duplicate or invalid. + pub fn import_statement( + &mut self, + context: &Ctx, + statement: SignedStatement, + ) -> Option> { + let SignedStatement { statement, signature, sender: signer } = statement; + + let res = match statement { + Statement::Seconded(candidate) => + self.import_candidate(context, signer.clone(), candidate, signature), + Statement::Valid(digest) => + self.validity_vote(context, signer.clone(), digest, ValidityVote::Valid(signature)), + }; + + match res { + Ok(maybe_summary) => maybe_summary, + Err(misbehavior) => { + // all misbehavior in agreement is provable and actively malicious. + // punishments may be cumulative. + self.detected_misbehavior.entry(signer).or_default().push(misbehavior); + None + }, + } + } + + /// Get a candidate by digest. + pub fn get_candidate(&self, digest: &Ctx::Digest) -> Option<&Ctx::Candidate> { + self.candidate_votes.get(digest).map(|d| &d.candidate) + } + + /// Access all witnessed misbehavior. + pub fn get_misbehavior(&self) -> &HashMap>> { + &self.detected_misbehavior + } + + /// Create a draining iterator of misbehaviors. + /// + /// This consumes all detected misbehaviors, even if the iterator is not completely consumed. + pub fn drain_misbehaviors(&mut self) -> DrainMisbehaviors<'_, Ctx> { + self.detected_misbehavior.drain().into() + } + + fn import_candidate( + &mut self, + context: &Ctx, + authority: Ctx::AuthorityId, + candidate: Ctx::Candidate, + signature: Ctx::Signature, + ) -> ImportResult { + let group = Ctx::candidate_group(&candidate); + if !context.is_member_of(&authority, &group) { + return Err(Misbehavior::UnauthorizedStatement(UnauthorizedStatement { + statement: SignedStatement { + signature, + statement: Statement::Seconded(candidate), + sender: authority, + }, + })) + } + + // check that authority hasn't already specified another candidate. + let digest = Ctx::candidate_digest(&candidate); + + let new_proposal = match self.authority_data.entry(authority.clone()) { + Entry::Occupied(mut occ) => { + // if digest is different, fetch candidate and + // note misbehavior. + let existing = occ.get_mut(); + + if !self.config.allow_multiple_seconded && existing.proposals.len() == 1 { + let (old_digest, old_sig) = &existing.proposals[0]; + + if old_digest != &digest { + const EXISTENCE_PROOF: &str = + "when proposal first received from authority, candidate \ + votes entry is created. proposal here is `Some`, therefore \ + candidate votes entry exists; qed"; + + let old_candidate = self + .candidate_votes + .get(old_digest) + .expect(EXISTENCE_PROOF) + .candidate + .clone(); + + return Err(Misbehavior::MultipleCandidates(MultipleCandidates { + first: (old_candidate, old_sig.clone()), + second: (candidate, signature.clone()), + })) + } + + false + } else if self.config.allow_multiple_seconded && + existing.proposals.iter().any(|(ref od, _)| od == &digest) + { + false + } else { + existing.proposals.push((digest.clone(), signature.clone())); + true + } + }, + Entry::Vacant(vacant) => { + vacant + .insert(AuthorityData { proposals: vec![(digest.clone(), signature.clone())] }); + true + }, + }; + + // NOTE: altering this code may affect the existence proof above. ensure it remains + // valid. + if new_proposal { + self.candidate_votes + .entry(digest.clone()) + .or_insert_with(move || CandidateData { + group_id: group, + candidate, + validity_votes: HashMap::new(), + }); + } + + self.validity_vote(context, authority, digest, ValidityVote::Issued(signature)) + } + + fn validity_vote( + &mut self, + context: &Ctx, + from: Ctx::AuthorityId, + digest: Ctx::Digest, + vote: ValidityVote, + ) -> ImportResult { + let votes = match self.candidate_votes.get_mut(&digest) { + None => return Ok(None), + Some(votes) => votes, + }; + + // check that this authority actually can vote in this group. + if !context.is_member_of(&from, &votes.group_id) { + let sig = match vote { + ValidityVote::Valid(s) => s, + ValidityVote::Issued(_) => panic!( + "implicit issuance vote only cast from `import_candidate` after \ + checking group membership of issuer; qed" + ), + }; + + return Err(Misbehavior::UnauthorizedStatement(UnauthorizedStatement { + statement: SignedStatement { + signature: sig, + sender: from, + statement: Statement::Valid(digest), + }, + })) + } + + // check for double votes. + match votes.validity_votes.entry(from.clone()) { + Entry::Occupied(occ) => { + let make_vdv = |v| Misbehavior::ValidityDoubleVote(v); + let make_ds = |ds| Misbehavior::DoubleSign(ds); + return if occ.get() != &vote { + Err(match (occ.get().clone(), vote) { + // valid vote conflicting with candidate statement + (ValidityVote::Issued(iss), ValidityVote::Valid(good)) | + (ValidityVote::Valid(good), ValidityVote::Issued(iss)) => + make_vdv(ValidityDoubleVote::IssuedAndValidity( + (votes.candidate.clone(), iss), + (digest, good), + )), + + // two signatures on same candidate + (ValidityVote::Issued(a), ValidityVote::Issued(b)) => + make_ds(DoubleSign::Seconded(votes.candidate.clone(), a, b)), + + // two signatures on same validity vote + (ValidityVote::Valid(a), ValidityVote::Valid(b)) => + make_ds(DoubleSign::Validity(digest, a, b)), + }) + } else { + Ok(None) + } + }, + Entry::Vacant(vacant) => { + vacant.insert(vote); + }, + } + + Ok(Some(votes.summary(digest))) + } +} + +type Drain<'a, Ctx> = hash_map::Drain<'a, ::AuthorityId, Vec>>; + +struct MisbehaviorForAuthority { + id: Ctx::AuthorityId, + misbehaviors: Vec>, +} + +impl From<(Ctx::AuthorityId, Vec>)> + for MisbehaviorForAuthority +{ + fn from((id, mut misbehaviors): (Ctx::AuthorityId, Vec>)) -> Self { + // we're going to be popping items off this list in the iterator, so reverse it now to + // preserve the original ordering. + misbehaviors.reverse(); + Self { id, misbehaviors } + } +} + +impl Iterator for MisbehaviorForAuthority { + type Item = (Ctx::AuthorityId, MisbehaviorFor); + + fn next(&mut self) -> Option { + self.misbehaviors.pop().map(|misbehavior| (self.id.clone(), misbehavior)) + } +} + +pub struct DrainMisbehaviors<'a, Ctx: Context> { + drain: Drain<'a, Ctx>, + in_progress: Option>, +} + +impl<'a, Ctx: Context> From> for DrainMisbehaviors<'a, Ctx> { + fn from(drain: Drain<'a, Ctx>) -> Self { + Self { drain, in_progress: None } + } +} + +impl<'a, Ctx: Context> DrainMisbehaviors<'a, Ctx> { + fn maybe_item(&mut self) -> Option<(Ctx::AuthorityId, MisbehaviorFor)> { + self.in_progress.as_mut().and_then(Iterator::next) + } +} + +impl<'a, Ctx: Context> Iterator for DrainMisbehaviors<'a, Ctx> { + type Item = (Ctx::AuthorityId, MisbehaviorFor); + + fn next(&mut self) -> Option { + // Note: this implementation will prematurely return `None` if `self.drain.next()` ever + // returns a tuple whose vector is empty. That will never currently happen, as the only + // modification to the backing map is currently via `drain` and + // `entry(...).or_default().push(...)`. However, future code changes might change that + // property. + self.maybe_item().or_else(|| { + self.in_progress = self.drain.next().map(Into::into); + self.maybe_item() + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::collections::HashMap; + + fn create_single_seconded() -> Table { + Table::new(Config { allow_multiple_seconded: false }) + } + + fn create_many_seconded() -> Table { + Table::new(Config { allow_multiple_seconded: true }) + } + + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + struct AuthorityId(usize); + + #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] + struct GroupId(usize); + + // group, body + #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] + struct Candidate(usize, usize); + + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + struct Signature(usize); + + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + struct Digest(usize); + + #[derive(Debug, PartialEq, Eq)] + struct TestContext { + // v -> parachain group + authorities: HashMap, + } + + impl Context for TestContext { + type AuthorityId = AuthorityId; + type Digest = Digest; + type Candidate = Candidate; + type GroupId = GroupId; + type Signature = Signature; + + fn candidate_digest(candidate: &Candidate) -> Digest { + Digest(candidate.1) + } + + fn candidate_group(candidate: &Candidate) -> GroupId { + GroupId(candidate.0) + } + + fn is_member_of(&self, authority: &AuthorityId, group: &GroupId) -> bool { + self.authorities.get(authority).map(|v| v == group).unwrap_or(false) + } + + fn requisite_votes(&self, id: &GroupId) -> usize { + let mut total_validity = 0; + + for validity in self.authorities.values() { + if validity == id { + total_validity += 1 + } + } + + total_validity / 2 + 1 + } + } + + #[test] + fn submitting_two_candidates_can_be_misbehavior() { + let context = TestContext { + authorities: { + let mut map = HashMap::new(); + map.insert(AuthorityId(1), GroupId(2)); + map + }, + }; + + let mut table = create_single_seconded(); + let statement_a = SignedStatement { + statement: Statement::Seconded(Candidate(2, 100)), + signature: Signature(1), + sender: AuthorityId(1), + }; + + let statement_b = SignedStatement { + statement: Statement::Seconded(Candidate(2, 999)), + signature: Signature(1), + sender: AuthorityId(1), + }; + + table.import_statement(&context, statement_a); + assert!(!table.detected_misbehavior.contains_key(&AuthorityId(1))); + + table.import_statement(&context, statement_b); + assert_eq!( + table.detected_misbehavior[&AuthorityId(1)][0], + Misbehavior::MultipleCandidates(MultipleCandidates { + first: (Candidate(2, 100), Signature(1)), + second: (Candidate(2, 999), Signature(1)), + }) + ); + } + + #[test] + fn submitting_two_candidates_can_be_allowed() { + let context = TestContext { + authorities: { + let mut map = HashMap::new(); + map.insert(AuthorityId(1), GroupId(2)); + map + }, + }; + + let mut table = create_many_seconded(); + let statement_a = SignedStatement { + statement: Statement::Seconded(Candidate(2, 100)), + signature: Signature(1), + sender: AuthorityId(1), + }; + + let statement_b = SignedStatement { + statement: Statement::Seconded(Candidate(2, 999)), + signature: Signature(1), + sender: AuthorityId(1), + }; + + table.import_statement(&context, statement_a); + assert!(!table.detected_misbehavior.contains_key(&AuthorityId(1))); + + table.import_statement(&context, statement_b); + assert!(!table.detected_misbehavior.contains_key(&AuthorityId(1))); + } + + #[test] + fn submitting_candidate_from_wrong_group_is_misbehavior() { + let context = TestContext { + authorities: { + let mut map = HashMap::new(); + map.insert(AuthorityId(1), GroupId(3)); + map + }, + }; + + let mut table = create_single_seconded(); + let statement = SignedStatement { + statement: Statement::Seconded(Candidate(2, 100)), + signature: Signature(1), + sender: AuthorityId(1), + }; + + table.import_statement(&context, statement); + + assert_eq!( + table.detected_misbehavior[&AuthorityId(1)][0], + Misbehavior::UnauthorizedStatement(UnauthorizedStatement { + statement: SignedStatement { + statement: Statement::Seconded(Candidate(2, 100)), + signature: Signature(1), + sender: AuthorityId(1), + }, + }) + ); + } + + #[test] + fn unauthorized_votes() { + let context = TestContext { + authorities: { + let mut map = HashMap::new(); + map.insert(AuthorityId(1), GroupId(2)); + map.insert(AuthorityId(2), GroupId(3)); + map + }, + }; + + let mut table = create_single_seconded(); + + let candidate_a = SignedStatement { + statement: Statement::Seconded(Candidate(2, 100)), + signature: Signature(1), + sender: AuthorityId(1), + }; + let candidate_a_digest = Digest(100); + + table.import_statement(&context, candidate_a); + assert!(!table.detected_misbehavior.contains_key(&AuthorityId(1))); + assert!(!table.detected_misbehavior.contains_key(&AuthorityId(2))); + + // authority 2 votes for validity on 1's candidate. + let bad_validity_vote = SignedStatement { + statement: Statement::Valid(candidate_a_digest), + signature: Signature(2), + sender: AuthorityId(2), + }; + table.import_statement(&context, bad_validity_vote); + + assert_eq!( + table.detected_misbehavior[&AuthorityId(2)][0], + Misbehavior::UnauthorizedStatement(UnauthorizedStatement { + statement: SignedStatement { + statement: Statement::Valid(candidate_a_digest), + signature: Signature(2), + sender: AuthorityId(2), + }, + }) + ); + } + + #[test] + fn candidate_double_signature_is_misbehavior() { + let context = TestContext { + authorities: { + let mut map = HashMap::new(); + map.insert(AuthorityId(1), GroupId(2)); + map.insert(AuthorityId(2), GroupId(2)); + map + }, + }; + + let mut table = create_single_seconded(); + let statement = SignedStatement { + statement: Statement::Seconded(Candidate(2, 100)), + signature: Signature(1), + sender: AuthorityId(1), + }; + + table.import_statement(&context, statement); + assert!(!table.detected_misbehavior.contains_key(&AuthorityId(1))); + + let invalid_statement = SignedStatement { + statement: Statement::Seconded(Candidate(2, 100)), + signature: Signature(999), + sender: AuthorityId(1), + }; + + table.import_statement(&context, invalid_statement); + assert!(table.detected_misbehavior.contains_key(&AuthorityId(1))); + } + + #[test] + fn issue_and_vote_is_misbehavior() { + let context = TestContext { + authorities: { + let mut map = HashMap::new(); + map.insert(AuthorityId(1), GroupId(2)); + map + }, + }; + + let mut table = create_single_seconded(); + let statement = SignedStatement { + statement: Statement::Seconded(Candidate(2, 100)), + signature: Signature(1), + sender: AuthorityId(1), + }; + let candidate_digest = Digest(100); + + table.import_statement(&context, statement); + assert!(!table.detected_misbehavior.contains_key(&AuthorityId(1))); + + let extra_vote = SignedStatement { + statement: Statement::Valid(candidate_digest), + signature: Signature(1), + sender: AuthorityId(1), + }; + + table.import_statement(&context, extra_vote); + assert_eq!( + table.detected_misbehavior[&AuthorityId(1)][0], + Misbehavior::ValidityDoubleVote(ValidityDoubleVote::IssuedAndValidity( + (Candidate(2, 100), Signature(1)), + (Digest(100), Signature(1)), + )) + ); + } + + #[test] + fn candidate_attested_works() { + let validity_threshold = 6; + + let mut candidate = CandidateData:: { + group_id: GroupId(4), + candidate: Candidate(4, 12345), + validity_votes: HashMap::new(), + }; + + assert!(candidate.attested(validity_threshold).is_none()); + + for i in 0..validity_threshold { + candidate + .validity_votes + .insert(AuthorityId(i + 100), ValidityVote::Valid(Signature(i + 100))); + } + + assert!(candidate.attested(validity_threshold).is_some()); + + candidate.validity_votes.insert( + AuthorityId(validity_threshold + 100), + ValidityVote::Valid(Signature(validity_threshold + 100)), + ); + + assert!(candidate.attested(validity_threshold).is_some()); + } + + #[test] + fn includability_works() { + let context = TestContext { + authorities: { + let mut map = HashMap::new(); + map.insert(AuthorityId(1), GroupId(2)); + map.insert(AuthorityId(2), GroupId(2)); + map.insert(AuthorityId(3), GroupId(2)); + map + }, + }; + + // have 2/3 validity guarantors note validity. + let mut table = create_single_seconded(); + let statement = SignedStatement { + statement: Statement::Seconded(Candidate(2, 100)), + signature: Signature(1), + sender: AuthorityId(1), + }; + let candidate_digest = Digest(100); + + table.import_statement(&context, statement); + + assert!(!table.detected_misbehavior.contains_key(&AuthorityId(1))); + assert!(table.attested_candidate(&candidate_digest, &context).is_none()); + + let vote = SignedStatement { + statement: Statement::Valid(candidate_digest), + signature: Signature(2), + sender: AuthorityId(2), + }; + + table.import_statement(&context, vote); + assert!(!table.detected_misbehavior.contains_key(&AuthorityId(2))); + assert!(table.attested_candidate(&candidate_digest, &context).is_some()); + } + + #[test] + fn candidate_import_gives_summary() { + let context = TestContext { + authorities: { + let mut map = HashMap::new(); + map.insert(AuthorityId(1), GroupId(2)); + map + }, + }; + + let mut table = create_single_seconded(); + let statement = SignedStatement { + statement: Statement::Seconded(Candidate(2, 100)), + signature: Signature(1), + sender: AuthorityId(1), + }; + + let summary = table + .import_statement(&context, statement) + .expect("candidate import to give summary"); + + assert_eq!(summary.candidate, Digest(100)); + assert_eq!(summary.group_id, GroupId(2)); + assert_eq!(summary.validity_votes, 1); + } + + #[test] + fn candidate_vote_gives_summary() { + let context = TestContext { + authorities: { + let mut map = HashMap::new(); + map.insert(AuthorityId(1), GroupId(2)); + map.insert(AuthorityId(2), GroupId(2)); + map + }, + }; + + let mut table = create_single_seconded(); + let statement = SignedStatement { + statement: Statement::Seconded(Candidate(2, 100)), + signature: Signature(1), + sender: AuthorityId(1), + }; + let candidate_digest = Digest(100); + + table.import_statement(&context, statement); + assert!(!table.detected_misbehavior.contains_key(&AuthorityId(1))); + + let vote = SignedStatement { + statement: Statement::Valid(candidate_digest), + signature: Signature(2), + sender: AuthorityId(2), + }; + + let summary = + table.import_statement(&context, vote).expect("candidate vote to give summary"); + + assert!(!table.detected_misbehavior.contains_key(&AuthorityId(2))); + + assert_eq!(summary.candidate, Digest(100)); + assert_eq!(summary.group_id, GroupId(2)); + assert_eq!(summary.validity_votes, 2); + } +} diff --git a/polkadot/statement-table/src/lib.rs b/polkadot/statement-table/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..d4629330ac01512e2dc2b0f441d2302f0fd38624 --- /dev/null +++ b/polkadot/statement-table/src/lib.rs @@ -0,0 +1,72 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The statement table. +//! +//! This stores messages other authorities issue about candidates. +//! +//! These messages are used to create a proposal submitted to a BFT consensus process. +//! +//! Proposals are formed of sets of candidates which have the requisite number of +//! validity and availability votes. +//! +//! Each parachain is associated with two sets of authorities: those which can +//! propose and attest to validity of candidates, and those who can only attest +//! to availability. + +pub mod generic; + +pub use generic::{Config, Context, Table}; + +/// Concrete instantiations suitable for v2 primitives. +pub mod v2 { + use crate::generic; + use primitives::{ + CandidateHash, CommittedCandidateReceipt, CompactStatement as PrimitiveStatement, Id, + ValidatorIndex, ValidatorSignature, + }; + + /// Statements about candidates on the network. + pub type Statement = generic::Statement; + + /// Signed statements about candidates. + pub type SignedStatement = generic::SignedStatement< + CommittedCandidateReceipt, + CandidateHash, + ValidatorIndex, + ValidatorSignature, + >; + + /// Kinds of misbehavior, along with proof. + pub type Misbehavior = generic::Misbehavior< + CommittedCandidateReceipt, + CandidateHash, + ValidatorIndex, + ValidatorSignature, + >; + + /// A summary of import of a statement. + pub type Summary = generic::Summary; + + impl<'a> From<&'a Statement> for PrimitiveStatement { + fn from(s: &'a Statement) -> PrimitiveStatement { + match *s { + generic::Statement::Valid(s) => PrimitiveStatement::Valid(s), + generic::Statement::Seconded(ref s) => PrimitiveStatement::Seconded(s.hash()), + } + } + } +} diff --git a/polkadot/tests/benchmark_block.rs b/polkadot/tests/benchmark_block.rs new file mode 100644 index 0000000000000000000000000000000000000000..bc91b31bc7b64430b757b9f87f39a0eb34b7238f --- /dev/null +++ b/polkadot/tests/benchmark_block.rs @@ -0,0 +1,94 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +// Unix only since it uses signals. +#![cfg(unix)] + +use assert_cmd::cargo::cargo_bin; +use nix::{ + sys::signal::{kill, Signal::SIGINT}, + unistd::Pid, +}; +use std::{ + path::Path, + process::{self, Command}, + result::Result, + time::Duration, +}; +use tempfile::tempdir; + +pub mod common; + +static RUNTIMES: [&str; 4] = ["polkadot", "kusama", "westend", "rococo"]; + +/// `benchmark block` works for all dev runtimes using the wasm executor. +#[tokio::test] +async fn benchmark_block_works() { + for runtime in RUNTIMES { + let tmp_dir = tempdir().expect("could not create a temp dir"); + let base_path = tmp_dir.path(); + let runtime = format!("{}-dev", runtime); + + // Build a chain with a single block. + build_chain(&runtime, base_path).await.unwrap(); + // Benchmark the one block. + benchmark_block(&runtime, base_path, 1).unwrap(); + } +} + +/// Builds a chain with one block for the given runtime and base path. +async fn build_chain(runtime: &str, base_path: &Path) -> Result<(), String> { + let mut cmd = Command::new(cargo_bin("polkadot")) + .stdout(process::Stdio::piped()) + .stderr(process::Stdio::piped()) + .args(["--chain", runtime, "--force-authoring", "--alice"]) + .arg("-d") + .arg(base_path) + .arg("--no-hardware-benchmarks") + .spawn() + .unwrap(); + + let (ws_url, _) = common::find_ws_url_from_output(cmd.stderr.take().unwrap()); + + // Wait for the chain to produce one block. + let ok = common::wait_n_finalized_blocks(1, Duration::from_secs(60), &ws_url).await; + // Send SIGINT to node. + kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap(); + // Wait for the node to handle it and exit. + assert!(common::wait_for(&mut cmd, 30).map(|x| x.success()).unwrap_or_default()); + + ok.map_err(|e| format!("Node did not build the chain: {:?}", e)) +} + +/// Benchmarks the given block with the wasm executor. +fn benchmark_block(runtime: &str, base_path: &Path, block: u32) -> Result<(), String> { + // Invoke `benchmark block` with all options to make sure that they are valid. + let status = Command::new(cargo_bin("polkadot")) + .args(["benchmark", "block", "--chain", runtime]) + .arg("-d") + .arg(base_path) + .args(["--from", &block.to_string(), "--to", &block.to_string()]) + .args(["--repeat", "1"]) + .args(["--wasm-execution", "compiled"]) + .status() + .map_err(|e| format!("command failed: {:?}", e))?; + + if !status.success() { + return Err("Command failed".into()) + } + + Ok(()) +} diff --git a/polkadot/tests/benchmark_extrinsic.rs b/polkadot/tests/benchmark_extrinsic.rs new file mode 100644 index 0000000000000000000000000000000000000000..e701fd9c923c2eb736ed34493a865afcca6d6145 --- /dev/null +++ b/polkadot/tests/benchmark_extrinsic.rs @@ -0,0 +1,57 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use assert_cmd::cargo::cargo_bin; +use std::{process::Command, result::Result}; + +static RUNTIMES: [&str; 4] = ["polkadot", "kusama", "westend", "rococo"]; + +static EXTRINSICS: [(&str, &str); 2] = [("system", "remark"), ("balances", "transfer_keep_alive")]; + +/// `benchmark extrinsic` works for all dev runtimes and some extrinsics. +#[test] +fn benchmark_extrinsic_works() { + for runtime in RUNTIMES { + for (pallet, extrinsic) in EXTRINSICS { + let runtime = format!("{}-dev", runtime); + assert!(benchmark_extrinsic(&runtime, pallet, extrinsic).is_ok()); + } + } +} + +/// `benchmark extrinsic` rejects all non-dev runtimes. +#[test] +fn benchmark_extrinsic_rejects_non_dev_runtimes() { + for runtime in RUNTIMES { + assert!(benchmark_extrinsic(runtime, "system", "remark").is_err()); + } +} + +fn benchmark_extrinsic(runtime: &str, pallet: &str, extrinsic: &str) -> Result<(), String> { + let status = Command::new(cargo_bin("polkadot")) + .args(["benchmark", "extrinsic", "--chain", runtime]) + .args(["--pallet", pallet, "--extrinsic", extrinsic]) + // Run with low repeats for faster execution. + .args(["--repeat=1", "--warmup=1", "--max-ext-per-block=1"]) + .status() + .map_err(|e| format!("command failed: {:?}", e))?; + + if !status.success() { + return Err("Command failed".into()) + } + + Ok(()) +} diff --git a/polkadot/tests/benchmark_overhead.rs b/polkadot/tests/benchmark_overhead.rs new file mode 100644 index 0000000000000000000000000000000000000000..295479594eb9ba56a5d64e2df34a014bdd8ecd9f --- /dev/null +++ b/polkadot/tests/benchmark_overhead.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use assert_cmd::cargo::cargo_bin; +use std::{process::Command, result::Result}; +use tempfile::tempdir; + +static RUNTIMES: [&str; 4] = ["polkadot", "kusama", "westend", "rococo"]; + +/// `benchmark overhead` works for all dev runtimes. +#[test] +fn benchmark_overhead_works() { + for runtime in RUNTIMES { + let runtime = format!("{}-dev", runtime); + assert!(benchmark_overhead(runtime).is_ok()); + } +} + +/// `benchmark overhead` rejects all non-dev runtimes. +#[test] +fn benchmark_overhead_rejects_non_dev_runtimes() { + for runtime in RUNTIMES { + assert!(benchmark_overhead(runtime.into()).is_err()); + } +} + +fn benchmark_overhead(runtime: String) -> Result<(), String> { + let tmp_dir = tempdir().expect("could not create a temp dir"); + let base_path = tmp_dir.path(); + + // Invoke `benchmark overhead` with all options to make sure that they are valid. + let status = Command::new(cargo_bin("polkadot")) + .args(["benchmark", "overhead", "--chain", &runtime]) + .arg("-d") + .arg(base_path) + .arg("--weight-path") + .arg(base_path) + .args(["--warmup", "5", "--repeat", "5"]) + .args(["--add", "100", "--mul", "1.2", "--metric", "p75"]) + // Only put 5 extrinsics into the block otherwise it takes forever to build it + // especially for a non-release builds. + .args(["--max-ext-per-block", "5"]) + .status() + .map_err(|e| format!("command failed: {:?}", e))?; + + if !status.success() { + return Err("Command failed".into()) + } + + // Weight files have been created. + assert!(base_path.join("block_weights.rs").exists()); + assert!(base_path.join("extrinsic_weights.rs").exists()); + Ok(()) +} diff --git a/polkadot/tests/benchmark_storage_works.rs b/polkadot/tests/benchmark_storage_works.rs new file mode 100644 index 0000000000000000000000000000000000000000..e789e8ae15e3ff2a5cab5e517180b32b533de0c1 --- /dev/null +++ b/polkadot/tests/benchmark_storage_works.rs @@ -0,0 +1,53 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![cfg(feature = "runtime-benchmarks")] + +use assert_cmd::cargo::cargo_bin; +use std::{ + path::Path, + process::{Command, ExitStatus}, +}; +use tempfile::tempdir; + +/// The `benchmark storage` command works for the dev runtime. +#[test] +fn benchmark_storage_works() { + let tmp_dir = tempdir().expect("could not create a temp dir"); + let base_path = tmp_dir.path(); + + // Benchmarking the storage works and creates the weight file. + assert!(benchmark_storage("rocksdb", base_path).success()); + assert!(base_path.join("rocksdb_weights.rs").exists()); + + assert!(benchmark_storage("paritydb", base_path).success()); + assert!(base_path.join("paritydb_weights.rs").exists()); +} + +/// Invoke the `benchmark storage` sub-command. +fn benchmark_storage(db: &str, base_path: &Path) -> ExitStatus { + Command::new(cargo_bin("polkadot")) + .args(["benchmark", "storage", "--dev"]) + .arg("--db") + .arg(db) + .arg("--weight-path") + .arg(base_path) + .args(["--state-version", "0"]) + .args(["--warmups", "0"]) + .args(["--add", "100", "--mul", "1.2", "--metric", "p75"]) + .status() + .unwrap() +} diff --git a/polkadot/tests/common.rs b/polkadot/tests/common.rs new file mode 100644 index 0000000000000000000000000000000000000000..940a0c6f18d0fe47575df6177fcc4f84fa7f3071 --- /dev/null +++ b/polkadot/tests/common.rs @@ -0,0 +1,102 @@ +// Copyright (C) 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 polkadot_core_primitives::{Block, Hash, Header}; +use std::{ + io::{BufRead, BufReader, Read}, + process::{Child, ExitStatus}, + thread, + time::Duration, +}; +use substrate_rpc_client::{ws_client, ChainApi}; +use tokio::time::timeout; + +/// Wait for the given `child` the given amount of `secs`. +/// +/// Returns the `Some(exit status)` or `None` if the process did not finish in the given time. +pub fn wait_for(child: &mut Child, secs: usize) -> Option { + for _ in 0..secs { + match child.try_wait().unwrap() { + Some(status) => return Some(status), + None => thread::sleep(Duration::from_secs(1)), + } + } + eprintln!("Took to long to exit. Killing..."); + let _ = child.kill(); + child.wait().unwrap(); + + None +} + +/// Wait for at least `n` blocks to be finalized within the specified time. +pub async fn wait_n_finalized_blocks( + n: usize, + timeout_duration: Duration, + url: &str, +) -> Result<(), tokio::time::error::Elapsed> { + timeout(timeout_duration, wait_n_finalized_blocks_from(n, url)).await +} + +/// Wait for at least `n` blocks to be finalized from a specified node. +async fn wait_n_finalized_blocks_from(n: usize, url: &str) { + let mut built_blocks = std::collections::HashSet::new(); + let mut interval = tokio::time::interval(Duration::from_secs(6)); + + loop { + let rpc = match ws_client(url).await { + Ok(rpc_service) => rpc_service, + Err(_) => continue, + }; + + if let Ok(block) = ChainApi::<(), Hash, Header, Block>::finalized_head(&rpc).await { + built_blocks.insert(block); + if built_blocks.len() > n { + break + } + }; + interval.tick().await; + } +} + +/// Read the WS address from the output. +/// +/// This is hack to get the actual binded sockaddr because +/// polkadot assigns a random port if the specified port was already binded. +/// +/// You must call +/// `Command::new("cmd").stdout(process::Stdio::piped()).stderr(process::Stdio::piped())` +/// for this to work. +pub fn find_ws_url_from_output(read: impl Read + Send) -> (String, String) { + let mut data = String::new(); + + let ws_url = BufReader::new(read) + .lines() + .find_map(|line| { + let line = line.expect("failed to obtain next line from stdout for port discovery"); + + data.push_str(&line); + + // does the line contain our port (we expect this specific output from substrate). + let sock_addr = match line.split_once("Running JSON-RPC server: addr=") { + None => return None, + Some((_, after)) => after.split_once(',').unwrap().0, + }; + + Some(format!("ws://{}", sock_addr)) + }) + .unwrap_or_else(|| panic!("Could not find address in process output:\n{}", &data)); + (ws_url, data) +} diff --git a/polkadot/tests/invalid_order_arguments.rs b/polkadot/tests/invalid_order_arguments.rs new file mode 100644 index 0000000000000000000000000000000000000000..8b5f4e31c17a7fcf5429bfb0131f81390c7e0834 --- /dev/null +++ b/polkadot/tests/invalid_order_arguments.rs @@ -0,0 +1,33 @@ +// Copyright (C) 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 assert_cmd::cargo::cargo_bin; +use std::process::Command; +use tempfile::tempdir; + +#[test] +#[cfg(unix)] +fn invalid_order_arguments() { + let tmpdir = tempdir().expect("could not create temp dir"); + + let status = Command::new(cargo_bin("polkadot")) + .args(["--dev", "invalid_order_arguments", "-d"]) + .arg(tmpdir.path()) + .arg("-y") + .status() + .unwrap(); + assert!(!status.success()); +} diff --git a/polkadot/tests/purge_chain_works.rs b/polkadot/tests/purge_chain_works.rs new file mode 100644 index 0000000000000000000000000000000000000000..3e9a378147810e5d2edf377fa7c5ed93ecf16952 --- /dev/null +++ b/polkadot/tests/purge_chain_works.rs @@ -0,0 +1,128 @@ +// Copyright (C) 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 assert_cmd::cargo::cargo_bin; +use std::{ + process::{self, Command}, + time::Duration, +}; +use tempfile::tempdir; + +pub mod common; + +#[tokio::test] +#[cfg(unix)] +async fn purge_chain_rocksdb_works() { + use nix::{ + sys::signal::{kill, Signal::SIGINT}, + unistd::Pid, + }; + + let tmpdir = tempdir().expect("could not create temp dir"); + + let mut cmd = Command::new(cargo_bin("polkadot")) + .stdout(process::Stdio::piped()) + .stderr(process::Stdio::piped()) + .args(["--dev", "-d"]) + .arg(tmpdir.path()) + .arg("--port") + .arg("33034") + .arg("--no-hardware-benchmarks") + .spawn() + .unwrap(); + + let (ws_url, _) = common::find_ws_url_from_output(cmd.stderr.take().unwrap()); + + // Let it produce 1 block. + common::wait_n_finalized_blocks(1, Duration::from_secs(60), &ws_url) + .await + .unwrap(); + + // Send SIGINT to node. + kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap(); + // Wait for the node to handle it and exit. + assert!(common::wait_for(&mut cmd, 30).map(|x| x.success()).unwrap_or_default()); + assert!(tmpdir.path().join("chains/polkadot_dev").exists()); + assert!(tmpdir.path().join("chains/polkadot_dev/db/full").exists()); + assert!(tmpdir.path().join("chains/polkadot_dev/db/full/parachains").exists()); + + // Purge chain + let status = Command::new(cargo_bin("polkadot")) + .args(["purge-chain", "--dev", "-d"]) + .arg(tmpdir.path()) + .arg("-y") + .status() + .unwrap(); + assert!(status.success()); + + // Make sure that the chain folder exists, but `db/full` is deleted. + assert!(tmpdir.path().join("chains/polkadot_dev").exists()); + assert!(!tmpdir.path().join("chains/polkadot_dev/db/full").exists()); +} + +#[tokio::test] +#[cfg(unix)] +async fn purge_chain_paritydb_works() { + use nix::{ + sys::signal::{kill, Signal::SIGINT}, + unistd::Pid, + }; + + let tmpdir = tempdir().expect("could not create temp dir"); + + let mut cmd = Command::new(cargo_bin("polkadot")) + .stdout(process::Stdio::piped()) + .stderr(process::Stdio::piped()) + .args(["--dev", "-d"]) + .arg(tmpdir.path()) + .arg("--database") + .arg("paritydb-experimental") + .arg("--no-hardware-benchmarks") + .spawn() + .unwrap(); + + let (ws_url, _) = common::find_ws_url_from_output(cmd.stderr.take().unwrap()); + + // Let it produce 1 block. + common::wait_n_finalized_blocks(1, Duration::from_secs(60), &ws_url) + .await + .unwrap(); + + // Send SIGINT to node. + kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap(); + // Wait for the node to handle it and exit. + assert!(common::wait_for(&mut cmd, 30).map(|x| x.success()).unwrap_or_default()); + assert!(tmpdir.path().join("chains/polkadot_dev").exists()); + assert!(tmpdir.path().join("chains/polkadot_dev/paritydb/full").exists()); + assert!(tmpdir.path().join("chains/polkadot_dev/paritydb/parachains").exists()); + + // Purge chain + let status = Command::new(cargo_bin("polkadot")) + .args(["purge-chain", "--dev", "-d"]) + .arg(tmpdir.path()) + .arg("--database") + .arg("paritydb-experimental") + .arg("-y") + .status() + .unwrap(); + assert!(status.success()); + + // Make sure that the chain folder exists, but `db/full` is deleted. + assert!(tmpdir.path().join("chains/polkadot_dev").exists()); + assert!(!tmpdir.path().join("chains/polkadot_dev/paritydb/full").exists()); + // Parachains removal requires calling "purge-chain --parachains". + assert!(tmpdir.path().join("chains/polkadot_dev/paritydb/parachains").exists()); +} diff --git a/polkadot/tests/running_the_node_and_interrupt.rs b/polkadot/tests/running_the_node_and_interrupt.rs new file mode 100644 index 0000000000000000000000000000000000000000..d3935cbb02ad176e56e1a248b9410f71b714ec95 --- /dev/null +++ b/polkadot/tests/running_the_node_and_interrupt.rs @@ -0,0 +1,68 @@ +// Copyright (C) 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 assert_cmd::cargo::cargo_bin; +use std::{ + process::{self, Command}, + time::Duration, +}; +use tempfile::tempdir; + +pub mod common; + +#[tokio::test] +#[cfg(unix)] +async fn running_the_node_works_and_can_be_interrupted() { + use nix::{ + sys::signal::{ + kill, + Signal::{self, SIGINT, SIGTERM}, + }, + unistd::Pid, + }; + + async fn run_command_and_kill(signal: Signal) { + let tmpdir = tempdir().expect("coult not create temp dir"); + + let mut cmd = Command::new(cargo_bin("polkadot")) + .stdout(process::Stdio::piped()) + .stderr(process::Stdio::piped()) + .args(["--dev", "-d"]) + .arg(tmpdir.path()) + .arg("--no-hardware-benchmarks") + .spawn() + .unwrap(); + + let (ws_url, _) = common::find_ws_url_from_output(cmd.stderr.take().unwrap()); + + // Let it produce three blocks. + common::wait_n_finalized_blocks(3, Duration::from_secs(60), &ws_url) + .await + .unwrap(); + + assert!(cmd.try_wait().unwrap().is_none(), "the process should still be running"); + kill(Pid::from_raw(cmd.id().try_into().unwrap()), signal).unwrap(); + assert_eq!( + common::wait_for(&mut cmd, 30).map(|x| x.success()), + Some(true), + "the process must exit gracefully after signal {}", + signal, + ); + } + + run_command_and_kill(SIGINT).await; + run_command_and_kill(SIGTERM).await; +} diff --git a/polkadot/tests/workers.rs b/polkadot/tests/workers.rs new file mode 100644 index 0000000000000000000000000000000000000000..2872a1298dcd10c06c82e7f865fc76b7e62f0d92 --- /dev/null +++ b/polkadot/tests/workers.rs @@ -0,0 +1,38 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use polkadot_cli::NODE_VERSION; +use std::process::Command; + +const PREPARE_WORKER_EXE: &str = env!("CARGO_BIN_EXE_polkadot-prepare-worker"); +const EXECUTE_WORKER_EXE: &str = env!("CARGO_BIN_EXE_polkadot-execute-worker"); + +#[test] +fn worker_binaries_have_same_version_as_node() { + let prep_worker_version = + Command::new(&PREPARE_WORKER_EXE).args(["--version"]).output().unwrap().stdout; + let prep_worker_version = std::str::from_utf8(&prep_worker_version) + .expect("version is printed as a string; qed") + .trim(); + assert_eq!(prep_worker_version, NODE_VERSION); + + let exec_worker_version = + Command::new(&EXECUTE_WORKER_EXE).args(["--version"]).output().unwrap().stdout; + let exec_worker_version = std::str::from_utf8(&exec_worker_version) + .expect("version is printed as a string; qed") + .trim(); + assert_eq!(exec_worker_version, NODE_VERSION); +} diff --git a/polkadot/utils/generate-bags/Cargo.toml b/polkadot/utils/generate-bags/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..1a0f1d3fbfcfcf0a69e8dec55046fc372930f9ec --- /dev/null +++ b/polkadot/utils/generate-bags/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "polkadot-voter-bags" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +clap = { version = "4.0.9", features = ["derive"] } + +generate-bags = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } + +westend-runtime = { path = "../../runtime/westend" } +kusama-runtime = { path = "../../runtime/kusama" } +polkadot-runtime = { path = "../../runtime/polkadot" } diff --git a/polkadot/utils/generate-bags/src/main.rs b/polkadot/utils/generate-bags/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..6d0b0e19e899691f8ea0d6d41fbcba59303631a5 --- /dev/null +++ b/polkadot/utils/generate-bags/src/main.rs @@ -0,0 +1,76 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Make the set of voting bag thresholds to be used in `voter_bags.rs`. +//! +//! Generally speaking this script can be run once per runtime and never +//! touched again. It can be reused to regenerate a wholly different +//! quantity of bags, or if the existential deposit changes, etc. + +use clap::{Parser, ValueEnum}; +use generate_bags::generate_thresholds; +use kusama_runtime::Runtime as KusamaRuntime; +use polkadot_runtime::Runtime as PolkadotRuntime; +use std::path::{Path, PathBuf}; +use westend_runtime::Runtime as WestendRuntime; + +#[derive(Clone, Debug, ValueEnum)] +#[value(rename_all = "PascalCase")] +enum Runtime { + Westend, + Kusama, + Polkadot, +} + +impl Runtime { + fn generate_thresholds_fn( + &self, + ) -> Box Result<(), std::io::Error>> { + match self { + Runtime::Westend => Box::new(generate_thresholds::), + Runtime::Kusama => Box::new(generate_thresholds::), + Runtime::Polkadot => Box::new(generate_thresholds::), + } + } +} + +#[derive(Debug, Parser)] +struct Opt { + /// How many bags to generate. + #[arg(long, default_value_t = 200)] + n_bags: usize, + + /// Which runtime to generate. + #[arg(long, ignore_case = true, value_enum, default_value_t = Runtime::Polkadot)] + runtime: Runtime, + + /// Where to write the output. + output: PathBuf, + + /// The total issuance of the native currency. + #[arg(short, long)] + total_issuance: u128, + + /// The minimum account balance (i.e. existential deposit) for the native currency. + #[arg(short, long)] + minimum_balance: u128, +} + +fn main() -> Result<(), std::io::Error> { + let Opt { n_bags, output, runtime, total_issuance, minimum_balance } = Opt::parse(); + + runtime.generate_thresholds_fn()(n_bags, &output, total_issuance, minimum_balance) +} diff --git a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..c84c95ab0498f370faa7821dcbf44e6ad04e4583 --- /dev/null +++ b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "remote-ext-tests-bags-list" +publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +polkadot-runtime = { path = "../../../runtime/polkadot" } +kusama-runtime = { path = "../../../runtime/kusama" } +westend-runtime = { path = "../../../runtime/westend" } +polkadot-runtime-constants = { path = "../../../runtime/polkadot/constants" } +kusama-runtime-constants = { path = "../../../runtime/kusama/constants" } +westend-runtime-constants = { path = "../../../runtime/westend/constants" } + +pallet-bags-list-remote-tests = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } + +clap = { version = "4.0.9", features = ["derive"] } +log = "0.4.17" +tokio = { version = "1.24.2", features = ["macros"] } diff --git a/polkadot/utils/remote-ext-tests/bags-list/README.md b/polkadot/utils/remote-ext-tests/bags-list/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4955e29b3cb262953cea98f5e216da930d2a5d1a --- /dev/null +++ b/polkadot/utils/remote-ext-tests/bags-list/README.md @@ -0,0 +1,3 @@ +# Remote Extension Tests For Pallet Bags List + +Integration tests that use state from live chains via remote externalities. diff --git a/polkadot/utils/remote-ext-tests/bags-list/src/main.rs b/polkadot/utils/remote-ext-tests/bags-list/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..6fb66ab2160147e8373ef1d115bda10f0249cfa6 --- /dev/null +++ b/polkadot/utils/remote-ext-tests/bags-list/src/main.rs @@ -0,0 +1,144 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Remote tests for bags-list pallet. + +use clap::{Parser, ValueEnum}; + +#[derive(Clone, Debug, ValueEnum)] +#[value(rename_all = "PascalCase")] +enum Command { + CheckMigration, + SanityCheck, + Snapshot, +} + +#[derive(Clone, Debug, ValueEnum)] +#[value(rename_all = "PascalCase")] +enum Runtime { + Polkadot, + Kusama, + Westend, +} + +#[derive(Parser)] +struct Cli { + #[arg(long, short, default_value = "wss://kusama-rpc.polkadot.io:443")] + uri: String, + #[arg(long, short, ignore_case = true, value_enum, default_value_t = Runtime::Kusama)] + runtime: Runtime, + #[arg(long, short, ignore_case = true, value_enum, default_value_t = Command::SanityCheck)] + command: Command, + #[arg(long, short)] + snapshot_limit: Option, +} + +#[tokio::main] +async fn main() { + let options = Cli::parse(); + sp_tracing::try_init_simple(); + + log::info!( + target: "remote-ext-tests", + "using runtime {:?} / command: {:?}", + options.runtime, + options.command + ); + + use pallet_bags_list_remote_tests::*; + match options.runtime { + Runtime::Polkadot => sp_core::crypto::set_default_ss58_version( + ::SS58Prefix::get() + .try_into() + .unwrap(), + ), + Runtime::Kusama => sp_core::crypto::set_default_ss58_version( + ::SS58Prefix::get() + .try_into() + .unwrap(), + ), + Runtime::Westend => sp_core::crypto::set_default_ss58_version( + ::SS58Prefix::get() + .try_into() + .unwrap(), + ), + }; + + match (options.runtime, options.command) { + (Runtime::Kusama, Command::CheckMigration) => { + use kusama_runtime::{Block, Runtime}; + use kusama_runtime_constants::currency::UNITS; + migration::execute::(UNITS as u64, "KSM", options.uri.clone()).await; + }, + (Runtime::Kusama, Command::SanityCheck) => { + use kusama_runtime::{Block, Runtime}; + use kusama_runtime_constants::currency::UNITS; + try_state::execute::(UNITS as u64, "KSM", options.uri.clone()).await; + }, + (Runtime::Kusama, Command::Snapshot) => { + use kusama_runtime::{Block, Runtime}; + use kusama_runtime_constants::currency::UNITS; + snapshot::execute::( + options.snapshot_limit, + UNITS.try_into().unwrap(), + options.uri.clone(), + ) + .await; + }, + + (Runtime::Westend, Command::CheckMigration) => { + use westend_runtime::{Block, Runtime}; + use westend_runtime_constants::currency::UNITS; + migration::execute::(UNITS as u64, "WND", options.uri.clone()).await; + }, + (Runtime::Westend, Command::SanityCheck) => { + use westend_runtime::{Block, Runtime}; + use westend_runtime_constants::currency::UNITS; + try_state::execute::(UNITS as u64, "WND", options.uri.clone()).await; + }, + (Runtime::Westend, Command::Snapshot) => { + use westend_runtime::{Block, Runtime}; + use westend_runtime_constants::currency::UNITS; + snapshot::execute::( + options.snapshot_limit, + UNITS.try_into().unwrap(), + options.uri.clone(), + ) + .await; + }, + + (Runtime::Polkadot, Command::CheckMigration) => { + use polkadot_runtime::{Block, Runtime}; + use polkadot_runtime_constants::currency::UNITS; + migration::execute::(UNITS as u64, "DOT", options.uri.clone()).await; + }, + (Runtime::Polkadot, Command::SanityCheck) => { + use polkadot_runtime::{Block, Runtime}; + use polkadot_runtime_constants::currency::UNITS; + try_state::execute::(UNITS as u64, "DOT", options.uri.clone()).await; + }, + (Runtime::Polkadot, Command::Snapshot) => { + use polkadot_runtime::{Block, Runtime}; + use polkadot_runtime_constants::currency::UNITS; + snapshot::execute::( + options.snapshot_limit, + UNITS.try_into().unwrap(), + options.uri.clone(), + ) + .await; + }, + } +} diff --git a/polkadot/utils/staking-miner/.gitignore b/polkadot/utils/staking-miner/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..db7cff848330b52bc5135e811ba222a2fc303a0b --- /dev/null +++ b/polkadot/utils/staking-miner/.gitignore @@ -0,0 +1,2 @@ +*.key +*.bin diff --git a/polkadot/utils/staking-miner/Cargo.toml b/polkadot/utils/staking-miner/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..f63425bb74e4669972aeead81c2b3183d36cd5e7 --- /dev/null +++ b/polkadot/utils/staking-miner/Cargo.toml @@ -0,0 +1,54 @@ +[[bin]] +name = "staking-miner" +path = "src/main.rs" + +[package] +name = "staking-miner" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +publish = false + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.6.1" } +clap = { version = "4.0.9", features = ["derive", "env"] } +tracing-subscriber = { version = "0.3.11", features = ["env-filter"] } +jsonrpsee = { version = "0.16.2", features = ["ws-client", "macros"] } +log = "0.4.17" +paste = "1.0.7" +serde = "1.0.163" +serde_json = "1.0" +thiserror = "1.0.31" +tokio = { version = "1.24.2", features = ["macros", "rt-multi-thread", "sync"] } +remote-externalities = { git = "https://github.com/paritytech/substrate", branch = "master", package = "frame-remote-externalities" } +signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "master" } + +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" } + +core-primitives = { package = "polkadot-core-primitives", path = "../../core-primitives" } + +runtime-common = { package = "polkadot-runtime-common", path = "../../runtime/common" } +polkadot-runtime = { path = "../../runtime/polkadot" } +kusama-runtime = { path = "../../runtime/kusama" } +westend-runtime = { path = "../../runtime/westend" } +exitcode = "1.1" + +sub-tokens = { git = "https://github.com/paritytech/substrate-debug-kit", branch = "master" } +signal-hook = "0.3" +futures-util = "0.3" + +[dev-dependencies] +assert_cmd = "2.0.4" diff --git a/polkadot/utils/staking-miner/README.md b/polkadot/utils/staking-miner/README.md new file mode 100644 index 0000000000000000000000000000000000000000..7e7254dc7759f3cf811922eb670a4ff9aa542cff --- /dev/null +++ b/polkadot/utils/staking-miner/README.md @@ -0,0 +1,70 @@ +# Staking Miner + +Substrate chains validators compute a basic solution for the NPoS election. The optimization of the solution is computing-intensive and can be delegated to the `staking-miner`. The `staking-miner` does not act as validator and focuses solely on the optimization of the solution. + +The staking miner connects to a specified chain and keeps listening to new Signed phase of the [pallet-election-provider-multi-phase](https://crates.parity.io/pallet_election_provider_multi_phase/index.html) in order to submit solutions to the NPoS election. When the correct time comes, it computes its solution and submit it to the chain. +The default miner algorithm is [sequential-phragmen](https://crates.parity.io/sp_npos_elections/phragmen/fn.seq_phragmen_core.html)] with a configurable number of balancing iterations that improve the score. + +Running the staking-miner requires passing the seed of a funded account in order to pay the fees for the transactions that will be sent. The same account's balance is used to reserve deposits as well. The best solution in each round is rewarded. All correct solutions will get their bond back. Any invalid solution will lose their bond. + +You can check the help with: +``` +staking-miner --help +``` + +## Building + +You can build from the root of the Polkadot repository using: +``` +cargo build --profile production --locked --package staking-miner --bin staking-miner +``` + +## Docker + +There are 2 options to build a staking-miner Docker image: +- injected binary: the binary is first built on a Linux host and then injected into a Docker base image. This method only works if you have a Linux host or access to a pre-built binary from a Linux host. +- multi-stage: the binary is entirely built within the multi-stage Docker image. There is no requirement on the host in terms of OS and the host does not even need to have any Rust toolchain installed. + +### Building the injected image + +First build the binary as documented [above](#building). +You may then inject the binary into a Docker base image: `parity/base-bin` (running the command from the root of the Polkadot repository): +``` +TODO: UPDATE THAT +docker build -t staking-miner -f scripts/ci/dockerfiles/staking-miner/staking-miner_injected.Dockerfile target/release +``` + +### Building the multi-stage image + +Unlike the injected image that requires a Linux pre-built binary, this option does not requires a Linux host, nor Rust to be installed. +The trade-off however is that it takes a little longer to build and this option is less ideal for CI tasks. +You may build the multi-stage image the root of the Polkadot repository with: +``` +TODO: UPDATE THAT +docker build -t staking-miner -f scripts/ci/dockerfiles/staking-miner/staking-miner_builder.Dockerfile . +``` + +### Running + +A Docker container, especially one holding one of your `SEED` should be kept as secure as possible. +While it won't prevent a malicious actor to read your `SEED` if they gain access to your container, it is nonetheless recommended running this container in `read-only` mode: + +``` +# The following line starts with an extra space on purpose: + SEED=0x1234... + +docker run --rm -i \ + --name staking-miner \ + --read-only \ + -e RUST_LOG=info \ + -e SEED=$SEED \ + -e URI=wss://your-node:9944 \ + staking-miner dry-run +``` + +### Test locally + +Make sure you've built Polkadot, then: + +1. `cargo run -p polkadot --features fast-runtime -- --chain polkadot-dev --tmp --alice -lruntime=debug` +2. `cargo run -p staking-miner -- --uri ws://localhost:9944 monitor --seed-or-path //Alice phrag-mms` diff --git a/polkadot/utils/staking-miner/src/dry_run.rs b/polkadot/utils/staking-miner/src/dry_run.rs new file mode 100644 index 0000000000000000000000000000000000000000..7e46f630a1f5e581143a1c91c87823d23b934bd0 --- /dev/null +++ b/polkadot/utils/staking-miner/src/dry_run.rs @@ -0,0 +1,166 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The dry-run command. + +use crate::{opts::DryRunConfig, prelude::*, rpc::*, signer::Signer, Error, SharedRpcClient}; +use codec::Encode; +use frame_support::traits::Currency; +use sp_core::Bytes; +use sp_npos_elections::ElectionScore; + +/// Forcefully create the snapshot. This can be used to compute the election at anytime. +fn force_create_snapshot(ext: &mut Ext) -> Result<(), Error> { + ext.execute_with(|| { + if >::exists() { + log::info!(target: LOG_TARGET, "snapshot already exists."); + Ok(()) + } else { + log::info!(target: LOG_TARGET, "creating a fake snapshot now."); + >::create_snapshot().map(|_| ()).map_err(Into::into) + } + }) +} + +/// Helper method to print the encoded size of the snapshot. +async fn print_info( + rpc: &SharedRpcClient, + ext: &mut Ext, + raw_solution: &EPM::RawSolution>, + extrinsic: &Bytes, +) where + ::Currency: Currency, +{ + ext.execute_with(|| { + log::info!( + target: LOG_TARGET, + "Snapshot Metadata: {:?}", + >::snapshot_metadata() + ); + log::info!( + target: LOG_TARGET, + "Snapshot Encoded Length: {:?}", + >::snapshot() + .expect("snapshot must exist before calling `measure_snapshot_size`") + .encode() + .len() + ); + + let snapshot_size = + >::snapshot_metadata().expect("snapshot must exist by now; qed."); + let deposit = EPM::Pallet::::deposit_for(raw_solution, snapshot_size); + + let score = { + let ElectionScore { minimal_stake, sum_stake, sum_stake_squared } = raw_solution.score; + [Token::from(minimal_stake), Token::from(sum_stake), Token::from(sum_stake_squared)] + }; + + log::info!( + target: LOG_TARGET, + "solution score {:?} / deposit {:?} / length {:?}", + score, + Token::from(deposit), + raw_solution.encode().len(), + ); + }); + + let info = rpc.payment_query_info(&extrinsic, None).await; + + log::info!( + target: LOG_TARGET, + "payment_queryInfo: (fee = {}) {:?}", + info.as_ref() + .map(|d| Token::from(d.partial_fee)) + .unwrap_or_else(|_| Token::from(0)), + info, + ); +} + +/// Find the stake threshold in order to have at most `count` voters. +#[allow(unused)] +fn find_threshold(ext: &mut Ext, count: usize) { + ext.execute_with(|| { + let mut voters = >::snapshot() + .expect("snapshot must exist before calling `measure_snapshot_size`") + .voters; + voters.sort_by_key(|(_voter, weight, _targets)| std::cmp::Reverse(*weight)); + match voters.get(count) { + Some(threshold_voter) => println!("smallest allowed voter is {:?}", threshold_voter), + None => { + println!("requested truncation to {} voters but had only {}", count, voters.len()); + println!("smallest current voter: {:?}", voters.last()); + }, + } + }) +} + +macro_rules! dry_run_cmd_for { ($runtime:ident) => { paste::paste! { + /// Execute the dry-run command. + pub(crate) async fn []( + rpc: SharedRpcClient, + config: DryRunConfig, + signer: Signer, + ) -> Result<(), Error<$crate::[<$runtime _runtime_exports>]::Runtime>> { + use $crate::[<$runtime _runtime_exports>]::*; + let pallets = if config.force_snapshot { + vec!["Staking".to_string(), "BagsList".to_string()] + } else { + Default::default() + }; + let mut ext = crate::create_election_ext::(rpc.clone(), config.at, pallets).await?; + if config.force_snapshot { + force_create_snapshot::(&mut ext)?; + }; + + log::debug!(target: LOG_TARGET, "solving with {:?}", config.solver); + let raw_solution = crate::mine_with::(&config.solver, &mut ext, false)?; + + let nonce = crate::get_account_info::(&rpc, &signer.account, config.at) + .await? + .map(|i| i.nonce) + .expect("signer account is checked to exist upon startup; it can only die if it \ + transfers funds out of it, or get slashed. If it does not exist at this point, \ + it is likely due to a bug, or the signer got slashed. Terminating." + ); + let tip = 0 as Balance; + let era = sp_runtime::generic::Era::Immortal; + let extrinsic = ext.execute_with(|| create_uxt(raw_solution.clone(), signer.clone(), nonce, tip, era)); + + let bytes = sp_core::Bytes(extrinsic.encode().to_vec()); + print_info::(&rpc, &mut ext, &raw_solution, &bytes).await; + + let feasibility_result = ext.execute_with(|| { + EPM::Pallet::::feasibility_check(raw_solution.clone(), EPM::ElectionCompute::Signed) + }); + log::info!(target: LOG_TARGET, "feasibility result is {:?}", feasibility_result.map(|_| ())); + + let dispatch_result = ext.execute_with(|| { + // manually tweak the phase. + EPM::CurrentPhase::::put(EPM::Phase::Signed); + EPM::Pallet::::submit(frame_system::RawOrigin::Signed(signer.account).into(), Box::new(raw_solution)) + }); + log::info!(target: LOG_TARGET, "dispatch result is {:?}", dispatch_result); + + let dry_run_fut = rpc.dry_run(&bytes, None); + let outcome: sp_runtime::ApplyExtrinsicResult = await_request_and_decode(dry_run_fut).await.map_err::, _>(Into::into)?; + log::info!(target: LOG_TARGET, "dry-run outcome is {:?}", outcome); + Ok(()) + } +}}} + +dry_run_cmd_for!(polkadot); +dry_run_cmd_for!(kusama); +dry_run_cmd_for!(westend); diff --git a/polkadot/utils/staking-miner/src/emergency_solution.rs b/polkadot/utils/staking-miner/src/emergency_solution.rs new file mode 100644 index 0000000000000000000000000000000000000000..9ea9f90756e22f458fc1c4e6872d77b7a246282b --- /dev/null +++ b/polkadot/utils/staking-miner/src/emergency_solution.rs @@ -0,0 +1,65 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The emergency-solution command. + +use crate::{prelude::*, EmergencySolutionConfig, Error, SharedRpcClient}; +use codec::Encode; +use std::io::Write; + +macro_rules! emergency_solution_cmd_for { ($runtime:ident) => { paste::paste! { + /// Execute the emergency-solution command. + pub(crate) async fn []( + client: SharedRpcClient, + config: EmergencySolutionConfig, + ) -> Result<(), Error<$crate::[<$runtime _runtime_exports>]::Runtime>> { + use $crate::[<$runtime _runtime_exports>]::*; + + let mut ext = crate::create_election_ext::(client, config.at, vec![]).await?; + let raw_solution = crate::mine_with::(&config.solver, &mut ext, false)?; + + ext.execute_with(|| { + assert!(EPM::Pallet::::current_phase().is_emergency()); + + log::info!(target: LOG_TARGET, "mined solution with {:?}", &raw_solution.score); + + let ready_solution = EPM::Pallet::::feasibility_check(raw_solution, EPM::ElectionCompute::Signed)?; + let encoded_size = ready_solution.encoded_size(); + let score = ready_solution.score; + let mut supports = ready_solution.supports.into_inner(); + // maybe truncate. + if let Some(take) = config.take { + log::info!(target: LOG_TARGET, "truncating {} winners to {}", supports.len(), take); + supports.sort_unstable_by_key(|(_, s)| s.total); + supports.truncate(take); + } + + // write to file and stdout. + let encoded_support = supports.encode(); + let mut supports_file = std::fs::File::create("solution.supports.bin")?; + supports_file.write_all(&encoded_support)?; + + log::info!(target: LOG_TARGET, "ReadySolution: size {:?} / score = {:?}", encoded_size, score); + log::trace!(target: LOG_TARGET, "Supports: {}", sp_core::hexdisplay::HexDisplay::from(&encoded_support)); + + Ok(()) + }) + } +}}} + +emergency_solution_cmd_for!(polkadot); +emergency_solution_cmd_for!(kusama); +emergency_solution_cmd_for!(westend); diff --git a/polkadot/utils/staking-miner/src/main.rs b/polkadot/utils/staking-miner/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..90b2c7366a1bab6b1a742d0274f872341e3c3a9a --- /dev/null +++ b/polkadot/utils/staking-miner/src/main.rs @@ -0,0 +1,665 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! # Polkadot Staking Miner. +//! +//! Simple bot capable of monitoring a polkadot (and cousins) chain and submitting solutions to the +//! `pallet-election-provider-multi-phase`. See `--help` for more details. +//! +//! # Implementation Notes: +//! +//! - First draft: Be aware that this is the first draft and there might be bugs, or undefined +//! behaviors. Don't attach this bot to an account with lots of funds. +//! - Quick to crash: The bot is written so that it only continues to work if everything goes well. +//! In case of any failure (RPC, logic, IO), it will crash. This was a decision to simplify the +//! development. It is intended to run this bot with a `restart = true` way, so that it reports it +//! crash, but resumes work thereafter. + +// Silence erroneous warning about unsafe not being required whereas it is +// see https://github.com/rust-lang/rust/issues/49112 +#![allow(unused_unsafe)] + +mod dry_run; +mod emergency_solution; +mod monitor; +mod opts; +mod prelude; +mod rpc; +mod runtime_versions; +mod signer; + +pub(crate) use prelude::*; +pub(crate) use signer::get_account_info; + +use crate::opts::*; +use clap::Parser; +use frame_election_provider_support::NposSolver; +use frame_support::traits::Get; +use futures_util::StreamExt; +use jsonrpsee::ws_client::{WsClient, WsClientBuilder}; +use remote_externalities::{Builder, Mode, OnlineConfig, Transport}; +use rpc::{RpcApiClient, SharedRpcClient}; +use runtime_versions::RuntimeVersions; +use signal_hook::consts::signal::*; +use signal_hook_tokio::Signals; +use sp_npos_elections::BalancingConfig; +use std::{ops::Deref, sync::Arc, time::Duration}; +use tracing_subscriber::{fmt, EnvFilter}; + +pub(crate) enum AnyRuntime { + Polkadot, + Kusama, + Westend, +} + +pub(crate) static mut RUNTIME: AnyRuntime = AnyRuntime::Polkadot; + +macro_rules! construct_runtime_prelude { + ($runtime:ident) => { paste::paste! { + pub(crate) mod [<$runtime _runtime_exports>] { + pub(crate) use crate::prelude::EPM; + pub(crate) use [<$runtime _runtime>]::*; + pub(crate) use crate::monitor::[] as monitor_cmd; + pub(crate) use crate::dry_run::[] as dry_run_cmd; + pub(crate) use crate::emergency_solution::[] as emergency_solution_cmd; + pub(crate) use private::{[] as create_uxt}; + + mod private { + use super::*; + pub(crate) fn []( + raw_solution: EPM::RawSolution>, + signer: crate::signer::Signer, + nonce: crate::prelude::Nonce, + tip: crate::prelude::Balance, + era: sp_runtime::generic::Era, + ) -> UncheckedExtrinsic { + use codec::Encode as _; + use sp_core::Pair as _; + use sp_runtime::traits::StaticLookup as _; + + let crate::signer::Signer { account, pair, .. } = signer; + + let local_call = EPMCall::::submit { raw_solution: Box::new(raw_solution) }; + let call: RuntimeCall = as std::convert::TryInto>::try_into(local_call) + .expect("election provider pallet must exist in the runtime, thus \ + inner call can be converted, qed." + ); + + let extra: SignedExtra = crate::[](nonce, tip, era); + let raw_payload = SignedPayload::new(call, extra).expect("creating signed payload infallible; qed."); + let signature = raw_payload.using_encoded(|payload| { + pair.sign(payload) + }); + let (call, extra, _) = raw_payload.deconstruct(); + let address = ::Lookup::unlookup(account); + let extrinsic = UncheckedExtrinsic::new_signed(call, address, signature.into(), extra); + log::debug!( + target: crate::LOG_TARGET, "constructed extrinsic {} with length {}", + sp_core::hexdisplay::HexDisplay::from(&extrinsic.encode()), + extrinsic.encode().len(), + ); + extrinsic + } + } + }} + }; +} + +// NOTE: we might be able to use some code from the bridges repo here. +fn signed_ext_builder_polkadot( + nonce: Nonce, + tip: Balance, + era: sp_runtime::generic::Era, +) -> polkadot_runtime_exports::SignedExtra { + use polkadot_runtime_exports::Runtime; + ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(era), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + runtime_common::claims::PrevalidateAttests::::new(), + ) +} + +fn signed_ext_builder_kusama( + nonce: Nonce, + tip: Balance, + era: sp_runtime::generic::Era, +) -> kusama_runtime_exports::SignedExtra { + use kusama_runtime_exports::Runtime; + ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(era), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + ) +} + +fn signed_ext_builder_westend( + nonce: Nonce, + tip: Balance, + era: sp_runtime::generic::Era, +) -> westend_runtime_exports::SignedExtra { + use westend_runtime_exports::Runtime; + ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(era), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + ) +} + +construct_runtime_prelude!(polkadot); +construct_runtime_prelude!(kusama); +construct_runtime_prelude!(westend); + +// NOTE: this is no longer used extensively, most of the per-runtime stuff us delegated to +// `construct_runtime_prelude` and macro's the import directly from it. A part of the code is also +// still generic over `T`. My hope is to still make everything generic over a `Runtime`, but sadly +// that is not currently possible as each runtime has its unique `Call`, and all Calls are not +// sharing any generic trait. In other words, to create the `UncheckedExtrinsic` of each chain, you +// need the concrete `Call` of that chain as well. +#[macro_export] +macro_rules! any_runtime { + ($($code:tt)*) => { + unsafe { + match $crate::RUNTIME { + $crate::AnyRuntime::Polkadot => { + #[allow(unused)] + use $crate::polkadot_runtime_exports::*; + $($code)* + }, + $crate::AnyRuntime::Kusama => { + #[allow(unused)] + use $crate::kusama_runtime_exports::*; + $($code)* + }, + $crate::AnyRuntime::Westend => { + #[allow(unused)] + use $crate::westend_runtime_exports::*; + $($code)* + } + } + } + } +} + +/// Same as [`any_runtime`], but instead of returning a `Result`, this simply returns `()`. Useful +/// for situations where the result is not useful and un-ergonomic to handle. +#[macro_export] +macro_rules! any_runtime_unit { + ($($code:tt)*) => { + unsafe { + match $crate::RUNTIME { + $crate::AnyRuntime::Polkadot => { + #[allow(unused)] + use $crate::polkadot_runtime_exports::*; + let _ = $($code)*; + }, + $crate::AnyRuntime::Kusama => { + #[allow(unused)] + use $crate::kusama_runtime_exports::*; + let _ = $($code)*; + }, + $crate::AnyRuntime::Westend => { + #[allow(unused)] + use $crate::westend_runtime_exports::*; + let _ = $($code)*; + } + } + } + } +} + +#[derive(frame_support::DebugNoBound, thiserror::Error)] +enum Error { + Io(#[from] std::io::Error), + JsonRpsee(#[from] jsonrpsee::core::Error), + RpcHelperError(#[from] rpc::RpcHelperError), + Codec(#[from] codec::Error), + Crypto(sp_core::crypto::SecretStringError), + RemoteExternalities(&'static str), + PalletMiner(EPM::unsigned::MinerError), + PalletElection(EPM::ElectionError), + PalletFeasibility(EPM::FeasibilityError), + AccountDoesNotExists, + IncorrectPhase, + AlreadySubmitted, + VersionMismatch, + StrategyNotSatisfied, + Other(String), +} + +impl From for Error { + fn from(e: sp_core::crypto::SecretStringError) -> Error { + Error::Crypto(e) + } +} + +impl From for Error { + fn from(e: EPM::unsigned::MinerError) -> Error { + Error::PalletMiner(e) + } +} + +impl From> for Error { + fn from(e: EPM::ElectionError) -> Error { + Error::PalletElection(e) + } +} + +impl From for Error { + fn from(e: EPM::FeasibilityError) -> Error { + Error::PalletFeasibility(e) + } +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + as std::fmt::Debug>::fmt(self, f) + } +} + +frame_support::parameter_types! { + /// Number of balancing iterations for a solution algorithm. Set based on the [`Solvers`] CLI + /// config. + pub static BalanceIterations: usize = 10; + pub static Balancing: Option = Some( BalancingConfig { iterations: BalanceIterations::get(), tolerance: 0 } ); +} + +/// Build the Ext at hash with all the data of `ElectionProviderMultiPhase` and any additional +/// pallets. +async fn create_election_ext( + client: SharedRpcClient, + at: Option, + additional: Vec, +) -> Result> +where + T: EPM::Config, +{ + use frame_support::{storage::generator::StorageMap, traits::PalletInfo}; + use sp_core::hashing::twox_128; + + let mut pallets = vec![::PalletInfo::name::>() + .expect("Pallet always has name; qed.") + .to_string()]; + pallets.extend(additional); + Builder::::new() + .mode(Mode::Online(OnlineConfig { + transport: Transport::Uri(client.uri().to_owned()), + at, + pallets, + hashed_prefixes: vec![>::prefix_hash()], + hashed_keys: vec![[twox_128(b"System"), twox_128(b"Number")].concat()], + ..Default::default() + })) + .build() + .await + .map_err(|why| Error::::RemoteExternalities(why)) + .map(|rx| rx.inner_ext) +} + +/// Compute the election. It expects to NOT be `Phase::Off`. In other words, the snapshot must +/// exists on the given externalities. +fn mine_solution( + ext: &mut Ext, + do_feasibility: bool, +) -> Result>, Error> +where + T: EPM::Config, + S: NposSolver< + Error = <::Solver as NposSolver>::Error, + AccountId = <::Solver as NposSolver>::AccountId, + >, +{ + ext.execute_with(|| { + let (solution, _) = >::mine_solution().map_err::, _>(Into::into)?; + if do_feasibility { + let _ = >::feasibility_check( + solution.clone(), + EPM::ElectionCompute::Signed, + )?; + } + Ok(solution) + }) +} + +/// Mine a solution with the given `solver`. +fn mine_with( + solver: &Solver, + ext: &mut Ext, + do_feasibility: bool, +) -> Result>, Error> +where + T: EPM::Config, + T::Solver: NposSolver, +{ + use frame_election_provider_support::{PhragMMS, SequentialPhragmen}; + + match solver { + Solver::SeqPhragmen { iterations } => { + BalanceIterations::set(*iterations); + mine_solution::< + T, + SequentialPhragmen< + ::AccountId, + sp_runtime::Perbill, + Balancing, + >, + >(ext, do_feasibility) + }, + Solver::PhragMMS { iterations } => { + BalanceIterations::set(*iterations); + mine_solution::< + T, + PhragMMS<::AccountId, sp_runtime::Perbill, Balancing>, + >(ext, do_feasibility) + }, + } +} + +#[allow(unused)] +fn mine_dpos(ext: &mut Ext) -> Result<(), Error> { + ext.execute_with(|| { + use std::collections::BTreeMap; + use EPM::RoundSnapshot; + let RoundSnapshot { voters, .. } = EPM::Snapshot::::get().unwrap(); + let desired_targets = EPM::DesiredTargets::::get().unwrap(); + let mut candidates_and_backing = BTreeMap::::new(); + voters.into_iter().for_each(|(who, stake, targets)| { + if targets.is_empty() { + println!("target = {:?}", (who, stake, targets)); + return + } + let share: u128 = (stake as u128) / (targets.len() as u128); + for target in targets { + *candidates_and_backing.entry(target.clone()).or_default() += share + } + }); + + let mut candidates_and_backing = + candidates_and_backing.into_iter().collect::>(); + candidates_and_backing.sort_by_key(|(_, total_stake)| *total_stake); + let winners = candidates_and_backing + .into_iter() + .rev() + .take(desired_targets as usize) + .collect::>(); + let score = { + let min_staker = *winners.last().map(|(_, stake)| stake).unwrap(); + let sum_stake = winners.iter().fold(0u128, |acc, (_, stake)| acc + stake); + let sum_squared = winners.iter().fold(0u128, |acc, (_, stake)| acc + stake); + [min_staker, sum_stake, sum_squared] + }; + println!("mined a dpos-like solution with score = {:?}", score); + Ok(()) + }) +} + +pub(crate) async fn check_versions( + rpc: &SharedRpcClient, + print: bool, +) -> Result<(), Error> { + let linked_version = T::Version::get(); + let on_chain_version = rpc + .runtime_version(None) + .await + .expect("runtime version RPC should always work; qed"); + + let do_print = || { + log::info!( + target: LOG_TARGET, + "linked version {:?}", + (&linked_version.spec_name, &linked_version.spec_version) + ); + log::info!( + target: LOG_TARGET, + "on-chain version {:?}", + (&on_chain_version.spec_name, &on_chain_version.spec_version) + ); + }; + + if print { + do_print(); + } + + // we relax the checking here a bit, which should not cause any issues in production (a chain + // that messes up its spec name is highly unlikely), but it allows us to do easier testing. + if linked_version.spec_name != on_chain_version.spec_name || + linked_version.spec_version != on_chain_version.spec_version + { + if !print { + do_print(); + } + log::error!( + target: LOG_TARGET, + "VERSION MISMATCH: any transaction will fail with bad-proof" + ); + Err(Error::VersionMismatch) + } else { + Ok(()) + } +} + +/// Control how we exit the application +fn controlled_exit(code: i32) { + log::info!(target: LOG_TARGET, "Exiting application"); + std::process::exit(code); +} + +/// Handles the various signal and exit the application +/// when appropriate. +async fn handle_signals(mut signals: Signals) { + let mut keyboard_sig_count: u8 = 0; + while let Some(signal) = signals.next().await { + match signal { + // Interrupts come from the keyboard + SIGQUIT | SIGINT => { + if keyboard_sig_count >= 1 { + log::info!( + target: LOG_TARGET, + "Received keyboard termination signal #{}/{}, quitting...", + keyboard_sig_count + 1, + 2 + ); + controlled_exit(exitcode::OK); + } + keyboard_sig_count += 1; + log::warn!( + target: LOG_TARGET, + "Received keyboard termination signal #{}, if you keep doing that I will really quit", + keyboard_sig_count + ); + }, + + SIGKILL | SIGTERM => { + log::info!(target: LOG_TARGET, "Received SIGKILL | SIGTERM, quitting..."); + controlled_exit(exitcode::OK); + }, + _ => unreachable!(), + } + } +} + +#[tokio::main] +async fn main() { + fmt().with_env_filter(EnvFilter::from_default_env()).init(); + + let Opt { uri, command, connection_timeout, request_timeout } = Opt::parse(); + log::debug!(target: LOG_TARGET, "attempting to connect to {:?}", uri); + + let signals = Signals::new(&[SIGTERM, SIGINT, SIGQUIT]).expect("Failed initializing Signals"); + let handle = signals.handle(); + let signals_task = tokio::spawn(handle_signals(signals)); + + let rpc = loop { + match SharedRpcClient::new( + &uri, + Duration::from_secs(connection_timeout as u64), + Duration::from_secs(request_timeout as u64), + ) + .await + { + Ok(client) => break client, + Err(why) => { + log::warn!( + target: LOG_TARGET, + "failed to connect to client due to {:?}, retrying soon..", + why + ); + tokio::time::sleep(std::time::Duration::from_millis(2500)).await; + }, + } + }; + + let chain: String = rpc.system_chain().await.expect("system_chain infallible; qed."); + match chain.to_lowercase().as_str() { + "polkadot" | "development" => { + sp_core::crypto::set_default_ss58_version( + sp_core::crypto::Ss58AddressFormatRegistry::PolkadotAccount.into(), + ); + sub_tokens::dynamic::set_name("DOT"); + sub_tokens::dynamic::set_decimal_points(10_000_000_000); + // safety: this program will always be single threaded, thus accessing global static is + // safe. + unsafe { + RUNTIME = AnyRuntime::Polkadot; + } + }, + "kusama" | "kusama-dev" => { + sp_core::crypto::set_default_ss58_version( + sp_core::crypto::Ss58AddressFormatRegistry::KusamaAccount.into(), + ); + sub_tokens::dynamic::set_name("KSM"); + sub_tokens::dynamic::set_decimal_points(1_000_000_000_000); + // safety: this program will always be single threaded, thus accessing global static is + // safe. + unsafe { + RUNTIME = AnyRuntime::Kusama; + } + }, + "westend" => { + sp_core::crypto::set_default_ss58_version( + sp_core::crypto::Ss58AddressFormatRegistry::PolkadotAccount.into(), + ); + sub_tokens::dynamic::set_name("WND"); + sub_tokens::dynamic::set_decimal_points(1_000_000_000_000); + // safety: this program will always be single threaded, thus accessing global static is + // safe. + unsafe { + RUNTIME = AnyRuntime::Westend; + } + }, + _ => { + eprintln!("unexpected chain: {:?}", chain); + return + }, + } + log::info!(target: LOG_TARGET, "connected to chain {:?}", chain); + + any_runtime_unit! { + check_versions::(&rpc, true).await + }; + + let outcome = any_runtime! { + match command { + Command::Monitor(monitor_config) => + { + let signer_account = any_runtime! { + signer::signer_uri_from_string::(&monitor_config.seed_or_path , &rpc) + .await + .expect("Provided account is invalid, terminating.") + }; + monitor_cmd(rpc, monitor_config, signer_account).await + .map_err(|e| { + log::error!(target: LOG_TARGET, "Monitor error: {:?}", e); + })}, + Command::DryRun(dryrun_config) => { + let signer_account = any_runtime! { + signer::signer_uri_from_string::(&dryrun_config.seed_or_path , &rpc) + .await + .expect("Provided account is invalid, terminating.") + }; + dry_run_cmd(rpc, dryrun_config, signer_account).await + .map_err(|e| { + log::error!(target: LOG_TARGET, "DryRun error: {:?}", e); + })}, + Command::EmergencySolution(emergency_solution_config) => + emergency_solution_cmd(rpc, emergency_solution_config).await + .map_err(|e| { + log::error!(target: LOG_TARGET, "EmergencySolution error: {:?}", e); + }), + Command::Info(info_opts) => { + let remote_runtime_version = rpc.runtime_version(None).await.expect("runtime_version infallible; qed."); + + let builtin_version = any_runtime! { + Version::get() + }; + + let versions = RuntimeVersions::new(&remote_runtime_version, &builtin_version); + + if !info_opts.json { + println!("{}", versions); + } else { + let versions = serde_json::to_string_pretty(&versions).expect("Failed serializing version info"); + println!("{}", versions); + } + Ok(()) + } + } + }; + log::info!(target: LOG_TARGET, "round of execution finished. outcome = {:?}", outcome); + + handle.close(); + let _ = signals_task.await; +} + +#[cfg(test)] +mod tests { + use super::*; + + fn get_version() -> sp_version::RuntimeVersion { + T::Version::get() + } + + #[test] + fn any_runtime_works() { + unsafe { + RUNTIME = AnyRuntime::Polkadot; + } + let polkadot_version = any_runtime! { get_version::() }; + + unsafe { + RUNTIME = AnyRuntime::Kusama; + } + let kusama_version = any_runtime! { get_version::() }; + + assert_eq!(polkadot_version.spec_name, "polkadot".into()); + assert_eq!(kusama_version.spec_name, "kusama".into()); + } +} diff --git a/polkadot/utils/staking-miner/src/monitor.rs b/polkadot/utils/staking-miner/src/monitor.rs new file mode 100644 index 0000000000000000000000000000000000000000..607ecb6baa42c9b24a2453044271a6446b16d285 --- /dev/null +++ b/polkadot/utils/staking-miner/src/monitor.rs @@ -0,0 +1,478 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! The monitor command. + +use crate::{ + prelude::*, rpc::*, signer::Signer, Error, MonitorConfig, SharedRpcClient, SubmissionStrategy, +}; +use codec::Encode; +use jsonrpsee::core::Error as RpcError; +use sc_transaction_pool_api::TransactionStatus; +use sp_core::storage::StorageKey; +use sp_runtime::Perbill; +use std::sync::Arc; +use tokio::sync::{mpsc, Mutex}; +use EPM::{signed::SubmissionIndicesOf, SignedSubmissionOf}; + +/// Ensure that now is the signed phase. +async fn ensure_signed_phase>( + rpc: &SharedRpcClient, + at: B::Hash, +) -> Result<(), Error> { + let key = StorageKey(EPM::CurrentPhase::::hashed_key().to_vec()); + let phase = rpc + .get_storage_and_decode::>(&key, Some(at)) + .await + .map_err::, _>(Into::into)? + .unwrap_or_default(); + + if phase.is_signed() { + Ok(()) + } else { + Err(Error::IncorrectPhase) + } +} + +/// Ensure that our current `us` have not submitted anything previously. +async fn ensure_no_previous_solution( + rpc: &SharedRpcClient, + at: Hash, + us: &AccountId, +) -> Result<(), Error> +where + T: EPM::Config + frame_system::Config, + B: BlockT, +{ + let indices_key = StorageKey(EPM::SignedSubmissionIndices::::hashed_key().to_vec()); + + let indices: SubmissionIndicesOf = rpc + .get_storage_and_decode(&indices_key, Some(at)) + .await + .map_err::, _>(Into::into)? + .unwrap_or_default(); + + for (_score, _bn, idx) in indices { + let key = StorageKey(EPM::SignedSubmissionsMap::::hashed_key_for(idx)); + + if let Some(submission) = rpc + .get_storage_and_decode::>(&key, Some(at)) + .await + .map_err::, _>(Into::into)? + { + if &submission.who == us { + return Err(Error::AlreadySubmitted) + } + } + } + + Ok(()) +} + +/// `true` if `our_score` should pass the onchain `best_score` with the given strategy. +pub(crate) fn score_passes_strategy( + our_score: sp_npos_elections::ElectionScore, + best_score: sp_npos_elections::ElectionScore, + strategy: SubmissionStrategy, +) -> bool { + match strategy { + SubmissionStrategy::Always => true, + SubmissionStrategy::IfLeading => + our_score == best_score || + our_score.strict_threshold_better(best_score, Perbill::zero()), + SubmissionStrategy::ClaimBetterThan(epsilon) => + our_score.strict_threshold_better(best_score, epsilon), + SubmissionStrategy::ClaimNoWorseThan(epsilon) => + !best_score.strict_threshold_better(our_score, epsilon), + } +} + +/// Reads all current solutions and checks the scores according to the `SubmissionStrategy`. +async fn ensure_strategy_met( + rpc: &SharedRpcClient, + at: Hash, + score: sp_npos_elections::ElectionScore, + strategy: SubmissionStrategy, + max_submissions: u32, +) -> Result<(), Error> { + // don't care about current scores. + if matches!(strategy, SubmissionStrategy::Always) { + return Ok(()) + } + + let indices_key = StorageKey(EPM::SignedSubmissionIndices::::hashed_key().to_vec()); + + let indices: SubmissionIndicesOf = rpc + .get_storage_and_decode(&indices_key, Some(at)) + .await + .map_err::, _>(Into::into)? + .unwrap_or_default(); + + if indices.len() >= max_submissions as usize { + log::debug!(target: LOG_TARGET, "The submissions queue is full"); + } + + // default score is all zeros, any score is better than it. + let best_score = indices.last().map(|(score, _, _)| *score).unwrap_or_default(); + log::debug!(target: LOG_TARGET, "best onchain score is {:?}", best_score); + + if score_passes_strategy(score, best_score, strategy) { + Ok(()) + } else { + Err(Error::StrategyNotSatisfied) + } +} + +async fn get_latest_head( + rpc: &SharedRpcClient, + mode: &str, +) -> Result> { + if mode == "head" { + match rpc.block_hash(None).await { + Ok(Some(hash)) => Ok(hash), + Ok(None) => Err(Error::Other("Best head not found".into())), + Err(e) => Err(e.into()), + } + } else { + rpc.finalized_head().await.map_err(Into::into) + } +} + +macro_rules! monitor_cmd_for { ($runtime:tt) => { paste::paste! { + + /// The monitor command. + pub(crate) async fn []( + rpc: SharedRpcClient, + config: MonitorConfig, + signer: Signer, + ) -> Result<(), Error<$crate::[<$runtime _runtime_exports>]::Runtime>> { + use $crate::[<$runtime _runtime_exports>]::*; + type StakingMinerError = Error<$crate::[<$runtime _runtime_exports>]::Runtime>; + + let heads_subscription = || + if config.listen == "head" { + rpc.subscribe_new_heads() + } else { + rpc.subscribe_finalized_heads() + }; + + let mut subscription = heads_subscription().await?; + let (tx, mut rx) = mpsc::unbounded_channel::(); + let submit_lock = Arc::new(Mutex::new(())); + + loop { + let at = tokio::select! { + maybe_rp = subscription.next() => { + match maybe_rp { + Some(Ok(r)) => r, + Some(Err(e)) => { + log::error!(target: LOG_TARGET, "subscription failed to decode Header {:?}, this is bug please file an issue", e); + return Err(e.into()); + } + // The subscription was dropped, should only happen if: + // - the connection was closed. + // - the subscription could not keep up with the server. + None => { + log::warn!(target: LOG_TARGET, "subscription to `subscribeNewHeads/subscribeFinalizedHeads` terminated. Retrying.."); + subscription = heads_subscription().await?; + continue + } + } + }, + maybe_err = rx.recv() => { + match maybe_err { + Some(err) => return Err(err), + None => unreachable!("at least one sender kept in the main loop should always return Some; qed"), + } + } + }; + + // Spawn task and non-recoverable errors are sent back to the main task + // such as if the connection has been closed. + tokio::spawn( + send_and_watch_extrinsic(rpc.clone(), tx.clone(), at, signer.clone(), config.clone(), submit_lock.clone()) + ); + } + + /// Construct extrinsic at given block and watch it. + async fn send_and_watch_extrinsic( + rpc: SharedRpcClient, + tx: mpsc::UnboundedSender, + at: Header, + signer: Signer, + config: MonitorConfig, + submit_lock: Arc>, + ) { + + async fn flatten( + handle: tokio::task::JoinHandle> + ) -> Result { + match handle.await { + Ok(Ok(result)) => Ok(result), + Ok(Err(err)) => Err(err), + Err(err) => panic!("tokio spawn task failed; kill task: {:?}", err), + } + } + + let hash = at.hash(); + log::trace!(target: LOG_TARGET, "new event at #{:?} ({:?})", at.number, hash); + + // block on this because if this fails there is no way to recover from + // that error i.e, upgrade/downgrade required. + if let Err(err) = crate::check_versions::(&rpc, false).await { + let _ = tx.send(err.into()); + return; + } + + let rpc1 = rpc.clone(); + let rpc2 = rpc.clone(); + let account = signer.account.clone(); + + let signed_phase_fut = tokio::spawn(async move { + ensure_signed_phase::(&rpc1, hash).await + }); + + tokio::time::sleep(std::time::Duration::from_secs(config.delay as u64)).await; + + let no_prev_sol_fut = tokio::spawn(async move { + ensure_no_previous_solution::(&rpc2, hash, &account).await + }); + + // Run the calls in parallel and return once all has completed or any failed. + if let Err(err) = tokio::try_join!(flatten(signed_phase_fut), flatten(no_prev_sol_fut)) { + log::debug!(target: LOG_TARGET, "Skipping block {}; {}", at.number, err); + return; + } + + let _lock = submit_lock.lock().await; + + let mut ext = match crate::create_election_ext::(rpc.clone(), Some(hash), vec![]).await { + Ok(ext) => ext, + Err(err) => { + log::debug!(target: LOG_TARGET, "Skipping block {}; {}", at.number, err); + return; + } + }; + + // mine a solution, and run feasibility check on it as well. + let raw_solution = match crate::mine_with::(&config.solver, &mut ext, true) { + Ok(r) => r, + Err(err) => { + let _ = tx.send(err.into()); + return; + } + }; + + let score = raw_solution.score; + log::info!(target: LOG_TARGET, "mined solution with {:?}", score); + + let nonce = match crate::get_account_info::(&rpc, &signer.account, Some(hash)).await { + Ok(maybe_account) => { + let acc = maybe_account.expect(crate::signer::SIGNER_ACCOUNT_WILL_EXIST); + acc.nonce + } + Err(err) => { + let _ = tx.send(err); + return; + } + }; + + let tip = 0 as Balance; + let period = ::BlockHashCount::get() / 2; + let current_block = at.number.saturating_sub(1); + let era = sp_runtime::generic::Era::mortal(period.into(), current_block.into()); + + log::trace!( + target: LOG_TARGET, "transaction mortality: {:?} -> {:?}", + era.birth(current_block.into()), + era.death(current_block.into()), + ); + + let extrinsic = ext.execute_with(|| create_uxt(raw_solution, signer.clone(), nonce, tip, era)); + let bytes = sp_core::Bytes(extrinsic.encode()); + + let rpc1 = rpc.clone(); + let rpc2 = rpc.clone(); + let rpc3 = rpc.clone(); + + let latest_head = match get_latest_head::(&rpc, &config.listen).await { + Ok(hash) => hash, + Err(e) => { + log::debug!(target: LOG_TARGET, "Skipping to submit at block {}; {}", at.number, e); + return; + } + }; + + let ensure_strategy_met_fut = tokio::spawn(async move { + ensure_strategy_met::( + &rpc1, + latest_head, + score, + config.submission_strategy, + SignedMaxSubmissions::get() + ).await + }); + + let ensure_signed_phase_fut = tokio::spawn(async move { + ensure_signed_phase::(&rpc2, latest_head).await + }); + + let account = signer.account.clone(); + let no_prev_sol_fut = tokio::spawn(async move { + ensure_no_previous_solution::(&rpc3, latest_head, &account).await + }); + + // Run the calls in parallel and return once all has completed or any failed. + if let Err(err) = tokio::try_join!( + flatten(ensure_strategy_met_fut), + flatten(ensure_signed_phase_fut), + flatten(no_prev_sol_fut), + ) { + log::debug!(target: LOG_TARGET, "Skipping to submit at block {}; {}", at.number, err); + return; + } + + let mut tx_subscription = match rpc.watch_extrinsic(&bytes).await { + Ok(sub) => sub, + Err(RpcError::RestartNeeded(e)) => { + let _ = tx.send(RpcError::RestartNeeded(e).into()); + return + }, + Err(why) => { + // This usually happens when we've been busy with mining for a few blocks, and + // now we're receiving the subscriptions of blocks in which we were busy. In + // these blocks, we still don't have a solution, so we re-compute a new solution + // and submit it with an outdated `Nonce`, which yields most often `Stale` + // error. NOTE: to improve this overall, and to be able to introduce an array of + // other fancy features, we should make this multi-threaded and do the + // computation outside of this callback. + log::warn!( + target: LOG_TARGET, + "failing to submit a transaction {:?}. ignore block: {}", + why, at.number + ); + return; + }, + }; + + while let Some(rp) = tx_subscription.next().await { + let status_update = match rp { + Ok(r) => r, + Err(e) => { + log::error!(target: LOG_TARGET, "subscription failed to decode TransactionStatus {:?}, this is a bug please file an issue", e); + let _ = tx.send(e.into()); + return; + }, + }; + + log::trace!(target: LOG_TARGET, "status update {:?}", status_update); + match status_update { + TransactionStatus::Ready | + TransactionStatus::Broadcast(_) | + TransactionStatus::Future => continue, + TransactionStatus::InBlock((hash, _)) => { + log::info!(target: LOG_TARGET, "included at {:?}", hash); + let key = StorageKey( + frame_support::storage::storage_prefix(b"System", b"Events").to_vec(), + ); + + let events = match rpc.get_storage_and_decode::< + Vec::Hash>>, + >(&key, Some(hash)) + .await { + Ok(rp) => rp.unwrap_or_default(), + Err(RpcHelperError::JsonRpsee(RpcError::RestartNeeded(e))) => { + let _ = tx.send(RpcError::RestartNeeded(e).into()); + return; + } + // Decoding or other RPC error => just terminate the task. + Err(e) => { + log::warn!(target: LOG_TARGET, "get_storage [key: {:?}, hash: {:?}] failed: {:?}; skip block: {}", + key, hash, e, at.number + ); + return; + } + }; + + log::info!(target: LOG_TARGET, "events at inclusion {:?}", events); + }, + TransactionStatus::Retracted(hash) => { + log::info!(target: LOG_TARGET, "Retracted at {:?}", hash); + }, + TransactionStatus::Finalized((hash, _)) => { + log::info!(target: LOG_TARGET, "Finalized at {:?}", hash); + break + }, + _ => { + log::warn!( + target: LOG_TARGET, + "Stopping listen due to other status {:?}", + status_update + ); + break + }, + }; + } + } + } +}}} + +monitor_cmd_for!(polkadot); +monitor_cmd_for!(kusama); +monitor_cmd_for!(westend); + +#[cfg(test)] +pub mod tests { + use super::*; + + #[test] + fn score_passes_strategy_works() { + let s = |x| sp_npos_elections::ElectionScore { minimal_stake: x, ..Default::default() }; + let two = Perbill::from_percent(2); + + // anything passes Always + assert!(score_passes_strategy(s(0), s(0), SubmissionStrategy::Always)); + assert!(score_passes_strategy(s(5), s(0), SubmissionStrategy::Always)); + assert!(score_passes_strategy(s(5), s(10), SubmissionStrategy::Always)); + + // if leading + assert!(score_passes_strategy(s(0), s(0), SubmissionStrategy::IfLeading)); + assert!(score_passes_strategy(s(1), s(0), SubmissionStrategy::IfLeading)); + assert!(score_passes_strategy(s(2), s(0), SubmissionStrategy::IfLeading)); + assert!(!score_passes_strategy(s(5), s(10), SubmissionStrategy::IfLeading)); + assert!(!score_passes_strategy(s(9), s(10), SubmissionStrategy::IfLeading)); + assert!(score_passes_strategy(s(10), s(10), SubmissionStrategy::IfLeading)); + + // if better by 2% + assert!(!score_passes_strategy(s(50), s(100), SubmissionStrategy::ClaimBetterThan(two))); + assert!(!score_passes_strategy(s(100), s(100), SubmissionStrategy::ClaimBetterThan(two))); + assert!(!score_passes_strategy(s(101), s(100), SubmissionStrategy::ClaimBetterThan(two))); + assert!(!score_passes_strategy(s(102), s(100), SubmissionStrategy::ClaimBetterThan(two))); + assert!(score_passes_strategy(s(103), s(100), SubmissionStrategy::ClaimBetterThan(two))); + assert!(score_passes_strategy(s(150), s(100), SubmissionStrategy::ClaimBetterThan(two))); + + // if no less than 2% worse + assert!(!score_passes_strategy(s(50), s(100), SubmissionStrategy::ClaimNoWorseThan(two))); + assert!(!score_passes_strategy(s(97), s(100), SubmissionStrategy::ClaimNoWorseThan(two))); + assert!(score_passes_strategy(s(98), s(100), SubmissionStrategy::ClaimNoWorseThan(two))); + assert!(score_passes_strategy(s(99), s(100), SubmissionStrategy::ClaimNoWorseThan(two))); + assert!(score_passes_strategy(s(100), s(100), SubmissionStrategy::ClaimNoWorseThan(two))); + assert!(score_passes_strategy(s(101), s(100), SubmissionStrategy::ClaimNoWorseThan(two))); + assert!(score_passes_strategy(s(102), s(100), SubmissionStrategy::ClaimNoWorseThan(two))); + assert!(score_passes_strategy(s(103), s(100), SubmissionStrategy::ClaimNoWorseThan(two))); + assert!(score_passes_strategy(s(150), s(100), SubmissionStrategy::ClaimNoWorseThan(two))); + } +} diff --git a/polkadot/utils/staking-miner/src/opts.rs b/polkadot/utils/staking-miner/src/opts.rs new file mode 100644 index 0000000000000000000000000000000000000000..ecffe45310144caf5a8e73868f132bb8379e0b79 --- /dev/null +++ b/polkadot/utils/staking-miner/src/opts.rs @@ -0,0 +1,366 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::prelude::*; +use clap::Parser; +use sp_runtime::Perbill; +use std::str::FromStr; + +#[derive(Debug, Clone, Parser)] +#[cfg_attr(test, derive(PartialEq))] +#[command(author, version, about)] +pub(crate) struct Opt { + /// The `ws` node to connect to. + #[arg(long, short, default_value = DEFAULT_URI, env = "URI", global = true)] + pub uri: String, + + /// WS connection timeout in number of seconds. + #[arg(long, default_value_t = 60)] + pub connection_timeout: usize, + + /// WS request timeout in number of seconds. + #[arg(long, default_value_t = 60 * 10)] + pub request_timeout: usize, + + #[command(subcommand)] + pub command: Command, +} + +#[derive(Debug, Clone, Parser)] +#[cfg_attr(test, derive(PartialEq))] +pub(crate) enum Command { + /// Monitor for the phase being signed, then compute. + Monitor(MonitorConfig), + + /// Just compute a solution now, and don't submit it. + DryRun(DryRunConfig), + + /// Provide a solution that can be submitted to the chain as an emergency response. + EmergencySolution(EmergencySolutionConfig), + + /// Return information about the current version + Info(InfoOpts), +} + +#[derive(Debug, Clone, Parser)] +#[cfg_attr(test, derive(PartialEq))] +pub(crate) struct MonitorConfig { + /// The path to a file containing the seed of the account. If the file is not found, the seed + /// is used as-is. + /// + /// Can also be provided via the `SEED` environment variable. + /// + /// WARNING: Don't use an account with a large stash for this. Based on how the bot is + /// configured, it might re-try and lose funds through transaction fees/deposits. + #[arg(long, short, env = "SEED")] + pub seed_or_path: String, + + /// They type of event to listen to. + /// + /// Typically, finalized is safer and there is no chance of anything going wrong, but it can be + /// slower. It is recommended to use finalized, if the duration of the signed phase is longer + /// than the the finality delay. + #[arg(long, default_value = "head", value_parser = ["head", "finalized"])] + pub listen: String, + + /// The solver algorithm to use. + #[command(subcommand)] + pub solver: Solver, + + /// Submission strategy to use. + /// + /// Possible options: + /// + /// `--submission-strategy if-leading`: only submit if leading. + /// + /// `--submission-strategy always`: always submit. + /// + /// `--submission-strategy "percent-better "`: submit if the submission is `n` percent + /// better. + /// + /// `--submission-strategy "no-worse-than "`: submit if submission is no more than + /// `n` percent worse. + #[clap(long, default_value = "if-leading")] + pub submission_strategy: SubmissionStrategy, + + /// Delay in number seconds to wait until starting mining a solution. + /// + /// At every block when a solution is attempted + /// a delay can be enforced to avoid submitting at + /// "same time" and risk potential races with other miners. + /// + /// When this is enabled and there are competing solutions, your solution might not be + /// submitted if the scores are equal. + #[arg(long, default_value_t = 0)] + pub delay: usize, +} + +#[derive(Debug, Clone, Parser)] +#[cfg_attr(test, derive(PartialEq))] +pub(crate) struct DryRunConfig { + /// The path to a file containing the seed of the account. If the file is not found, the seed + /// is used as-is. + /// + /// Can also be provided via the `SEED` environment variable. + /// + /// WARNING: Don't use an account with a large stash for this. Based on how the bot is + /// configured, it might re-try and lose funds through transaction fees/deposits. + #[arg(long, short, env = "SEED")] + pub seed_or_path: String, + + /// The block hash at which scraping happens. If none is provided, the latest head is used. + #[arg(long)] + pub at: Option, + + /// The solver algorithm to use. + #[command(subcommand)] + pub solver: Solver, + + /// Force create a new snapshot, else expect one to exist onchain. + #[arg(long)] + pub force_snapshot: bool, +} + +#[derive(Debug, Clone, Parser)] +#[cfg_attr(test, derive(PartialEq))] +pub(crate) struct EmergencySolutionConfig { + /// The block hash at which scraping happens. If none is provided, the latest head is used. + #[arg(long)] + pub at: Option, + + /// The solver algorithm to use. + #[command(subcommand)] + pub solver: Solver, + + /// The number of top backed winners to take. All are taken, if not provided. + pub take: Option, +} + +#[derive(Debug, Clone, Parser)] +#[cfg_attr(test, derive(PartialEq))] +pub(crate) struct InfoOpts { + /// Serialize the output as json + #[arg(long, short)] + pub json: bool, +} + +/// Submission strategy to use. +#[derive(Debug, Copy, Clone)] +#[cfg_attr(test, derive(PartialEq))] +pub enum SubmissionStrategy { + /// Always submit. + Always, + /// Only submit if at the time, we are the best (or equal to it). + IfLeading, + /// Submit if we are no worse than `Perbill` worse than the best. + ClaimNoWorseThan(Perbill), + /// Submit if we are leading, or if the solution that's leading is more that the given + /// `Perbill` better than us. This helps detect obviously fake solutions and still combat them. + ClaimBetterThan(Perbill), +} + +#[derive(Debug, Clone, Parser)] +#[cfg_attr(test, derive(PartialEq))] +pub(crate) enum Solver { + SeqPhragmen { + #[arg(long, default_value_t = 10)] + iterations: usize, + }, + PhragMMS { + #[arg(long, default_value_t = 10)] + iterations: usize, + }, +} + +/// Custom `impl` to parse `SubmissionStrategy` from CLI. +/// +/// Possible options: +/// * --submission-strategy if-leading: only submit if leading +/// * --submission-strategy always: always submit +/// * --submission-strategy "percent-better ": submit if submission is `n` percent better. +/// * --submission-strategy "no-worse-than": submit if submission is no more than `n` +/// percent worse. +impl FromStr for SubmissionStrategy { + type Err = String; + + fn from_str(s: &str) -> Result { + let s = s.trim(); + + let res = if s == "if-leading" { + Self::IfLeading + } else if s == "always" { + Self::Always + } else if let Some(percent) = s.strip_prefix("no-worse-than ") { + let percent: u32 = percent.parse().map_err(|e| format!("{:?}", e))?; + Self::ClaimNoWorseThan(Perbill::from_percent(percent)) + } else if let Some(percent) = s.strip_prefix("percent-better ") { + let percent: u32 = percent.parse().map_err(|e| format!("{:?}", e))?; + Self::ClaimBetterThan(Perbill::from_percent(percent)) + } else { + return Err(s.into()) + }; + Ok(res) + } +} + +#[cfg(test)] +mod test_super { + use super::*; + + #[test] + fn cli_monitor_works() { + let opt = Opt::try_parse_from([ + env!("CARGO_PKG_NAME"), + "--uri", + "hi", + "monitor", + "--seed-or-path", + "//Alice", + "--listen", + "head", + "--delay", + "12", + "seq-phragmen", + ]) + .unwrap(); + + assert_eq!( + opt, + Opt { + uri: "hi".to_string(), + connection_timeout: 60, + request_timeout: 10 * 60, + command: Command::Monitor(MonitorConfig { + seed_or_path: "//Alice".to_string(), + listen: "head".to_string(), + solver: Solver::SeqPhragmen { iterations: 10 }, + submission_strategy: SubmissionStrategy::IfLeading, + delay: 12, + }), + } + ); + } + + #[test] + fn cli_dry_run_works() { + let opt = Opt::try_parse_from([ + env!("CARGO_PKG_NAME"), + "--uri", + "hi", + "dry-run", + "--seed-or-path", + "//Alice", + "phrag-mms", + ]) + .unwrap(); + + assert_eq!( + opt, + Opt { + uri: "hi".to_string(), + connection_timeout: 60, + request_timeout: 10 * 60, + command: Command::DryRun(DryRunConfig { + seed_or_path: "//Alice".to_string(), + at: None, + solver: Solver::PhragMMS { iterations: 10 }, + force_snapshot: false, + }), + } + ); + } + + #[test] + fn cli_emergency_works() { + let opt = Opt::try_parse_from([ + env!("CARGO_PKG_NAME"), + "--uri", + "hi", + "emergency-solution", + "99", + "phrag-mms", + "--iterations", + "1337", + ]) + .unwrap(); + + assert_eq!( + opt, + Opt { + uri: "hi".to_string(), + connection_timeout: 60, + request_timeout: 10 * 60, + command: Command::EmergencySolution(EmergencySolutionConfig { + take: Some(99), + at: None, + solver: Solver::PhragMMS { iterations: 1337 } + }), + } + ); + } + + #[test] + fn cli_info_works() { + let opt = Opt::try_parse_from([env!("CARGO_PKG_NAME"), "--uri", "hi", "info"]).unwrap(); + + assert_eq!( + opt, + Opt { + uri: "hi".to_string(), + connection_timeout: 60, + request_timeout: 10 * 60, + command: Command::Info(InfoOpts { json: false }) + } + ); + } + + #[test] + fn cli_request_conn_timeout_works() { + let opt = Opt::try_parse_from([ + env!("CARGO_PKG_NAME"), + "--uri", + "hi", + "--request-timeout", + "10", + "--connection-timeout", + "9", + "info", + ]) + .unwrap(); + + assert_eq!( + opt, + Opt { + uri: "hi".to_string(), + connection_timeout: 9, + request_timeout: 10, + command: Command::Info(InfoOpts { json: false }) + } + ); + } + + #[test] + fn submission_strategy_from_str_works() { + use std::str::FromStr; + + assert_eq!(SubmissionStrategy::from_str("if-leading"), Ok(SubmissionStrategy::IfLeading)); + assert_eq!(SubmissionStrategy::from_str("always"), Ok(SubmissionStrategy::Always)); + assert_eq!( + SubmissionStrategy::from_str(" percent-better 99 "), + Ok(SubmissionStrategy::ClaimBetterThan(Perbill::from_percent(99))) + ); + } +} diff --git a/polkadot/utils/staking-miner/src/prelude.rs b/polkadot/utils/staking-miner/src/prelude.rs new file mode 100644 index 0000000000000000000000000000000000000000..fb701ece2384d8f1286e4573ebad0c00724dbb42 --- /dev/null +++ b/polkadot/utils/staking-miner/src/prelude.rs @@ -0,0 +1,55 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Types that we don't fetch from a particular runtime and just assume that they are constant all +//! of the place. +//! +//! It is actually easy to convert the rest as well, but it'll be a lot of noise in our codebase, +//! needing to sprinkle `any_runtime` in a few extra places. + +/// The account id type. +pub type AccountId = core_primitives::AccountId; +/// The block number type. +pub type BlockNumber = core_primitives::BlockNumber; +/// The balance type. +pub type Balance = core_primitives::Balance; +/// Index of a transaction in the chain. +pub type Nonce = core_primitives::Nonce; +/// The hash type. We re-export it here, but we can easily get it from block as well. +pub type Hash = core_primitives::Hash; +/// The header type. We re-export it here, but we can easily get it from block as well. +pub type Header = core_primitives::Header; +/// The block type. +pub type Block = core_primitives::Block; + +pub use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; + +/// Default URI to connect to. +pub const DEFAULT_URI: &str = "wss://rpc.polkadot.io:443"; +/// The logging target. +pub const LOG_TARGET: &str = "staking-miner"; + +/// The election provider pallet. +pub use pallet_election_provider_multi_phase as EPM; + +/// The externalities type. +pub type Ext = sp_state_machine::TestExternalities>; + +/// The key pair type being used. We "strongly" assume sr25519 for simplicity. +pub type Pair = sp_core::sr25519::Pair; + +/// A dynamic token type used to represent account balances. +pub type Token = sub_tokens::dynamic::DynamicToken; diff --git a/polkadot/utils/staking-miner/src/rpc.rs b/polkadot/utils/staking-miner/src/rpc.rs new file mode 100644 index 0000000000000000000000000000000000000000..2d25616e2a179e7eb993e2423dfe7496b022baca --- /dev/null +++ b/polkadot/utils/staking-miner/src/rpc.rs @@ -0,0 +1,182 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! JSON-RPC related types and helpers. + +use super::*; +use jsonrpsee::{ + core::{Error as RpcError, RpcResult}, + proc_macros::rpc, +}; +use pallet_transaction_payment::RuntimeDispatchInfo; +use sc_transaction_pool_api::TransactionStatus; +use sp_core::{storage::StorageKey, Bytes}; +use sp_version::RuntimeVersion; +use std::{future::Future, time::Duration}; + +#[derive(frame_support::DebugNoBound, thiserror::Error)] +pub(crate) enum RpcHelperError { + JsonRpsee(#[from] jsonrpsee::core::Error), + Codec(#[from] codec::Error), +} + +impl std::fmt::Display for RpcHelperError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + ::fmt(self, f) + } +} + +#[rpc(client)] +pub trait RpcApi { + /// Fetch system name. + #[method(name = "system_chain")] + async fn system_chain(&self) -> RpcResult; + + /// Fetch a storage key. + #[method(name = "state_getStorage")] + async fn storage(&self, key: &StorageKey, hash: Option) -> RpcResult>; + + /// Fetch the runtime version. + #[method(name = "state_getRuntimeVersion")] + async fn runtime_version(&self, at: Option) -> RpcResult; + + /// Fetch the payment query info. + #[method(name = "payment_queryInfo")] + async fn payment_query_info( + &self, + encoded_xt: &Bytes, + at: Option<&Hash>, + ) -> RpcResult>; + + /// Dry run an extrinsic at a given block. Return SCALE encoded + /// [`sp_runtime::ApplyExtrinsicResult`]. + #[method(name = "system_dryRun")] + async fn dry_run(&self, extrinsic: &Bytes, at: Option) -> RpcResult; + + /// Get hash of the n-th block in the canon chain. + /// + /// By default returns latest block hash. + #[method(name = "chain_getBlockHash", aliases = ["chain_getHead"], blocking)] + fn block_hash(&self, hash: Option) -> RpcResult>; + + /// Get hash of the last finalized block in the canon chain. + #[method(name = "chain_getFinalizedHead", aliases = ["chain_getFinalisedHead"], blocking)] + fn finalized_head(&self) -> RpcResult; + + /// Submit an extrinsic to watch. + /// + /// See [`TransactionStatus`](sc_transaction_pool_api::TransactionStatus) for details on + /// transaction life cycle. + #[subscription( + name = "author_submitAndWatchExtrinsic" => "author_extrinsicUpdate", + unsubscribe = "author_unwatchExtrinsic", + item = TransactionStatus + )] + fn watch_extrinsic(&self, bytes: &Bytes); + + /// New head subscription. + #[subscription( + name = "chain_subscribeNewHeads" => "newHead", + unsubscribe = "chain_unsubscribeNewHeads", + item = Header + )] + fn subscribe_new_heads(&self); + + /// Finalized head subscription. + #[subscription( + name = "chain_subscribeFinalizedHeads" => "chain_finalizedHead", + unsubscribe = "chain_unsubscribeFinalizedHeads", + item = Header + )] + fn subscribe_finalized_heads(&self); +} + +type Uri = String; + +/// Wraps a shared web-socket JSON-RPC client that can be cloned. +#[derive(Clone, Debug)] +pub(crate) struct SharedRpcClient(Arc, Uri); + +impl Deref for SharedRpcClient { + type Target = WsClient; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl SharedRpcClient { + /// Get the URI of the client. + pub fn uri(&self) -> &str { + &self.1 + } + + /// Create a new shared JSON-RPC web-socket client. + pub(crate) async fn new( + uri: &str, + connection_timeout: Duration, + request_timeout: Duration, + ) -> Result { + let client = WsClientBuilder::default() + .connection_timeout(connection_timeout) + .max_request_body_size(u32::MAX) + .request_timeout(request_timeout) + .max_concurrent_requests(u32::MAX as usize) + .build(uri) + .await?; + Ok(Self(Arc::new(client), uri.to_owned())) + } + + /// Get a storage item and decode it as `T`. + /// + /// # Return value: + /// + /// The function returns: + /// + /// * `Ok(Some(val))` if successful. + /// * `Ok(None)` if the storage item was not found. + /// * `Err(e)` if the JSON-RPC call failed. + pub(crate) async fn get_storage_and_decode<'a, T: codec::Decode>( + &self, + key: &StorageKey, + hash: Option, + ) -> Result, RpcHelperError> { + if let Some(bytes) = self.storage(key, hash).await? { + let decoded = ::decode(&mut &*bytes.0) + .map_err::(Into::into)?; + Ok(Some(decoded)) + } else { + Ok(None) + } + } +} + +/// Takes a future that returns `Bytes` and tries to decode those bytes into the type `Dec`. +/// Warning: don't use for storage, it will fail for non-existent storage items. +/// +/// # Return value: +/// +/// The function returns: +/// +/// * `Ok(val)` if successful. +/// * `Err(RpcHelperError::JsonRpsee)` if the JSON-RPC call failed. +/// * `Err(RpcHelperError::Codec)` if `Bytes` could not be decoded. +pub(crate) async fn await_request_and_decode<'a, Dec: codec::Decode>( + req: impl Future>, +) -> Result { + let bytes = req.await?; + Dec::decode(&mut &*bytes.0).map_err::(Into::into) +} diff --git a/polkadot/utils/staking-miner/src/runtime_versions.rs b/polkadot/utils/staking-miner/src/runtime_versions.rs new file mode 100644 index 0000000000000000000000000000000000000000..38af05ead24143ae122e4e0ac2732c0de8f6c145 --- /dev/null +++ b/polkadot/utils/staking-miner/src/runtime_versions.rs @@ -0,0 +1,90 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use sp_version::RuntimeVersion; +use std::fmt; + +#[derive(Debug, serde::Serialize)] +pub(crate) struct RuntimeWrapper<'a>(pub &'a RuntimeVersion); + +impl<'a> fmt::Display for RuntimeWrapper<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let width = 16; + + writeln!( + f, + r#" impl_name : {impl_name:>width$} + spec_name : {spec_name:>width$} + spec_version : {spec_version:>width$} + transaction_version : {transaction_version:>width$} + impl_version : {impl_version:>width$} + authoringVersion : {authoring_version:>width$} + state_version : {state_version:>width$}"#, + spec_name = self.0.spec_name.to_string(), + impl_name = self.0.impl_name.to_string(), + spec_version = self.0.spec_version, + impl_version = self.0.impl_version, + authoring_version = self.0.authoring_version, + transaction_version = self.0.transaction_version, + state_version = self.0.state_version, + ) + } +} + +impl<'a> From<&'a RuntimeVersion> for RuntimeWrapper<'a> { + fn from(r: &'a RuntimeVersion) -> Self { + RuntimeWrapper(r) + } +} + +#[derive(Debug, serde::Serialize)] +pub(crate) struct RuntimeVersions<'a> { + /// The `RuntimeVersion` linked in the staking-miner + pub linked: RuntimeWrapper<'a>, + + /// The `RuntimeVersion` reported by the node we connect to via RPC + pub remote: RuntimeWrapper<'a>, + + /// This `bool` reports whether both remote and linked `RuntimeVersion` are compatible + /// and if the staking-miner is expected to work properly against the remote runtime + compatible: bool, +} + +impl<'a> RuntimeVersions<'a> { + pub fn new( + remote_runtime_version: &'a RuntimeVersion, + linked_runtime_version: &'a RuntimeVersion, + ) -> Self { + Self { + remote: remote_runtime_version.into(), + linked: linked_runtime_version.into(), + compatible: are_runtimes_compatible(remote_runtime_version, linked_runtime_version), + } + } +} + +/// Check whether runtimes are compatible. Currently we only support equality. +fn are_runtimes_compatible(r1: &RuntimeVersion, r2: &RuntimeVersion) -> bool { + r1 == r2 +} + +impl<'a> fmt::Display for RuntimeVersions<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let _ = write!(f, "- linked:\n{}", self.linked); + let _ = write!(f, "- remote :\n{}", self.remote); + write!(f, "Compatible: {}", if self.compatible { "YES" } else { "NO" }) + } +} diff --git a/polkadot/utils/staking-miner/src/signer.rs b/polkadot/utils/staking-miner/src/signer.rs new file mode 100644 index 0000000000000000000000000000000000000000..e6677ccd3a66149e25affb5286140a5b44a6a3e4 --- /dev/null +++ b/polkadot/utils/staking-miner/src/signer.rs @@ -0,0 +1,84 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Wrappers around creating a signer account. + +use crate::{prelude::*, rpc::SharedRpcClient, AccountId, Error, Nonce, Pair, LOG_TARGET}; +use frame_system::AccountInfo; +use sp_core::{crypto::Pair as _, storage::StorageKey}; + +pub(crate) const SIGNER_ACCOUNT_WILL_EXIST: &str = + "signer account is checked to exist upon startup; it can only die if it transfers funds out \ + of it, or get slashed. If it does not exist at this point, it is likely due to a bug, or the \ + signer got slashed. Terminating."; + +/// Some information about the signer. Redundant at this point, but makes life easier. +#[derive(Clone)] +pub(crate) struct Signer { + /// The account id. + pub(crate) account: AccountId, + + /// The full crypto key-pair. + pub(crate) pair: Pair, +} + +pub(crate) async fn get_account_info + EPM::Config>( + rpc: &SharedRpcClient, + who: &T::AccountId, + maybe_at: Option, +) -> Result>, Error> { + rpc.get_storage_and_decode::>( + &StorageKey(>::hashed_key_for(&who)), + maybe_at, + ) + .await + .map_err(Into::into) +} + +/// Read the signer account's URI +pub(crate) async fn signer_uri_from_string< + T: frame_system::Config< + AccountId = AccountId, + Nonce = Nonce, + AccountData = pallet_balances::AccountData, + Hash = Hash, + > + EPM::Config, +>( + mut seed_or_path: &str, + client: &SharedRpcClient, +) -> Result> { + seed_or_path = seed_or_path.trim(); + + let seed = match std::fs::read(seed_or_path) { + Ok(s) => String::from_utf8(s).map_err(|_| Error::::AccountDoesNotExists)?, + Err(_) => seed_or_path.to_string(), + }; + let seed = seed.trim(); + + let pair = Pair::from_string(seed, None)?; + let account = T::AccountId::from(pair.public()); + let _info = get_account_info::(client, &account, None) + .await? + .ok_or(Error::::AccountDoesNotExists)?; + log::info!( + target: LOG_TARGET, + "loaded account {:?}, free: {:?}, info: {:?}", + &account, + Token::from(_info.data.free), + _info + ); + Ok(Signer { account, pair }) +} diff --git a/polkadot/utils/staking-miner/tests/cli.rs b/polkadot/utils/staking-miner/tests/cli.rs new file mode 100644 index 0000000000000000000000000000000000000000..1ced1239e5530c0b1a656ef3197fdaf9a4334dd1 --- /dev/null +++ b/polkadot/utils/staking-miner/tests/cli.rs @@ -0,0 +1,49 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use assert_cmd::{cargo::cargo_bin, Command}; +use serde_json::{Result, Value}; + +#[test] +fn cli_version_works() { + let crate_name = env!("CARGO_PKG_NAME"); + let output = Command::new(cargo_bin(crate_name)).arg("--version").output().unwrap(); + + assert!(output.status.success(), "command returned with non-success exit code"); + let version = String::from_utf8_lossy(&output.stdout).trim().to_owned(); + + assert_eq!(version, format!("{} {}", crate_name, env!("CARGO_PKG_VERSION"))); +} + +#[test] +fn cli_info_works() { + let crate_name = env!("CARGO_PKG_NAME"); + let output = Command::new(cargo_bin(crate_name)) + .arg("info") + .arg("--json") + .env("RUST_LOG", "none") + .output() + .unwrap(); + + assert!(output.status.success(), "command returned with non-success exit code"); + let info = String::from_utf8_lossy(&output.stdout).trim().to_owned(); + let v: Result = serde_json::from_str(&info); + let v = v.unwrap(); + assert!(!v["builtin"].to_string().is_empty()); + assert!(!v["builtin"]["spec_name"].to_string().is_empty()); + assert!(!v["builtin"]["spec_version"].to_string().is_empty()); + assert!(!v["remote"].to_string().is_empty()); +} diff --git a/polkadot/xcm/Cargo.toml b/polkadot/xcm/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..a03d392d5fd04e315ae2e2f60ec12f15d1ffac2c --- /dev/null +++ b/polkadot/xcm/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "xcm" +description = "The basic XCM datastructures." +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +bounded-collections = { version = "0.1.8", default-features = false, features = ["serde"] } +derivative = { version = "2.2.0", default-features = false, features = [ "use_core" ] } +impl-trait-for-tuples = "0.2.2" +log = { version = "0.4.17", default-features = false } +parity-scale-codec = { version = "3.6.1", default-features = false, features = [ "derive", "max-encoded-len" ] } +scale-info = { version = "2.5.0", default-features = false, features = ["derive", "serde"] } +sp-weights = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, features = ["serde"] } +serde = { version = "1.0.163", default-features = false, features = ["alloc", "derive"] } +xcm-procedural = { path = "procedural" } + +[dev-dependencies] +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } +hex = "0.4.3" +hex-literal = "0.4.1" + +[features] +default = ["std"] +wasm-api = [] +std = [ + "bounded-collections/std", + "parity-scale-codec/std", + "scale-info/std", + "serde/std", + "sp-weights/std", +] diff --git a/polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml b/polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..a77b58059b420cfc1b66f2cffbb607aaa694f632 --- /dev/null +++ b/polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml @@ -0,0 +1,57 @@ +[package] +name = "pallet-xcm-benchmarks" +authors.workspace = true +edition.workspace = true +license.workspace = true +version.workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +frame-support = { default-features = false, branch = "master", git = "https://github.com/paritytech/substrate" } +frame-system = { default-features = false, branch = "master", git = "https://github.com/paritytech/substrate" } +sp-runtime = { default-features = false, branch = "master", git = "https://github.com/paritytech/substrate" } +sp-std = { default-features = false, branch = "master", git = "https://github.com/paritytech/substrate" } +sp-io = { default-features = false, branch = "master", git = "https://github.com/paritytech/substrate" } +xcm-executor = { path = "../xcm-executor", default-features = false } +frame-benchmarking = { default-features = false, branch = "master", git = "https://github.com/paritytech/substrate" } +xcm = { path = "..", default-features = false } +xcm-builder = { path = "../xcm-builder", default-features = false } +log = "0.4.17" + +[dev-dependencies] +pallet-balances = { branch = "master", git = "https://github.com/paritytech/substrate" } +pallet-assets = { branch = "master", git = "https://github.com/paritytech/substrate" } +sp-core = { branch = "master", git = "https://github.com/paritytech/substrate" } +sp-tracing = { branch = "master", git = "https://github.com/paritytech/substrate" } +xcm = { path = ".." } +# temp +pallet-xcm = { path = "../pallet-xcm" } +polkadot-runtime-common = { path = "../../runtime/common" } +# westend-runtime = { path = "../../runtime/westend", features = ["runtime-benchmarks"] } +polkadot-primitives = { path = "../../primitives" } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", + "xcm-builder/std", + "xcm-executor/std" +] +runtime-benchmarks = [ + "xcm-builder/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..504b795403991dc3229f005027baa8fc97790617 --- /dev/null +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs @@ -0,0 +1,282 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::{account_and_location, new_executor, AssetTransactorOf, XcmCallOf}; +use frame_benchmarking::{benchmarks_instance_pallet, BenchmarkError, BenchmarkResult}; +use frame_support::{ + pallet_prelude::Get, + traits::fungible::{Inspect, Mutate}, +}; +use sp_runtime::traits::{Bounded, Zero}; +use sp_std::{prelude::*, vec}; +use xcm::latest::prelude::*; +use xcm_executor::traits::{ConvertLocation, TransactAsset}; + +benchmarks_instance_pallet! { + where_clause { where + < + < + T::TransactAsset + as + Inspect + >::Balance + as + TryInto + >::Error: sp_std::fmt::Debug, + } + + withdraw_asset { + let (sender_account, sender_location) = account_and_location::(1); + let worst_case_holding = T::worst_case_holding(0); + let asset = T::get_multi_asset(); + + >::deposit_asset( + &asset, + &sender_location, + &XcmContext { + origin: Some(sender_location.clone()), + message_id: [0; 32], + topic: None, + }, + ).unwrap(); + // check the assets of origin. + assert!(!T::TransactAsset::balance(&sender_account).is_zero()); + + let mut executor = new_executor::(sender_location); + executor.set_holding(worst_case_holding.into()); + let instruction = Instruction::>::WithdrawAsset(vec![asset.clone()].into()); + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // check one of the assets of origin. + assert!(T::TransactAsset::balance(&sender_account).is_zero()); + assert!(executor.holding().ensure_contains(&vec![asset].into()).is_ok()); + } + + transfer_asset { + let (sender_account, sender_location) = account_and_location::(1); + let asset = T::get_multi_asset(); + let assets: MultiAssets = vec![ asset.clone() ].into(); + // this xcm doesn't use holding + + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap(); + + >::deposit_asset( + &asset, + &sender_location, + &XcmContext { + origin: Some(sender_location.clone()), + message_id: [0; 32], + topic: None, + }, + ).unwrap(); + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + let mut executor = new_executor::(sender_location); + let instruction = Instruction::TransferAsset { assets, beneficiary: dest_location }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + assert!(T::TransactAsset::balance(&sender_account).is_zero()); + assert!(!T::TransactAsset::balance(&dest_account).is_zero()); + } + + transfer_reserve_asset { + let (sender_account, sender_location) = account_and_location::(1); + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap(); + + let asset = T::get_multi_asset(); + >::deposit_asset( + &asset, + &sender_location, + &XcmContext { + origin: Some(sender_location.clone()), + message_id: [0; 32], + topic: None, + }, + ).unwrap(); + let assets: MultiAssets = vec![ asset ].into(); + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + let mut executor = new_executor::(sender_location); + let instruction = Instruction::TransferReserveAsset { + assets, + dest: dest_location, + xcm: Xcm::new() + }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + assert!(T::TransactAsset::balance(&sender_account).is_zero()); + assert!(!T::TransactAsset::balance(&dest_account).is_zero()); + // TODO: Check sender queue is not empty. #4426 + } + + reserve_asset_deposited { + let (trusted_reserve, transferable_reserve_asset) = T::TrustedReserve::get() + .ok_or(BenchmarkError::Override( + BenchmarkResult::from_weight(T::BlockWeights::get().max_block) + ))?; + + let assets: MultiAssets = vec![ transferable_reserve_asset ].into(); + + let mut executor = new_executor::(trusted_reserve); + let instruction = Instruction::ReserveAssetDeposited(assets.clone()); + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + assert!(executor.holding().ensure_contains(&assets).is_ok()); + } + + initiate_reserve_withdraw { + let holding = T::worst_case_holding(1); + let assets_filter = MultiAssetFilter::Definite(holding.clone()); + let reserve = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + let instruction = Instruction::InitiateReserveWithdraw { assets: assets_filter, reserve, xcm: Xcm(vec![]) }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // The execute completing successfully is as good as we can check. + // TODO: Potentially add new trait to XcmSender to detect a queued outgoing message. #4426 + } + + receive_teleported_asset { + // If there is no trusted teleporter, then we skip this benchmark. + let (trusted_teleporter, teleportable_asset) = T::TrustedTeleporter::get() + .ok_or(BenchmarkError::Skip)?; + + if let Some((checked_account, _)) = T::CheckedAccount::get() { + T::TransactAsset::mint_into( + &checked_account, + < + T::TransactAsset + as + Inspect + >::Balance::max_value() / 2u32.into(), + )?; + } + + let assets: MultiAssets = vec![ teleportable_asset ].into(); + + let mut executor = new_executor::(trusted_teleporter); + let instruction = Instruction::ReceiveTeleportedAsset(assets.clone()); + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm).map_err(|_| { + BenchmarkError::Override( + BenchmarkResult::from_weight(T::BlockWeights::get().max_block) + ) + })?; + } verify { + assert!(executor.holding().ensure_contains(&assets).is_ok()); + } + + deposit_asset { + let asset = T::get_multi_asset(); + let mut holding = T::worst_case_holding(1); + + // Add our asset to the holding. + holding.push(asset.clone()); + + // our dest must have no balance initially. + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap(); + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + let instruction = Instruction::>::DepositAsset { + assets: asset.into(), + beneficiary: dest_location, + }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // dest should have received some asset. + assert!(!T::TransactAsset::balance(&dest_account).is_zero()) + } + + deposit_reserve_asset { + let asset = T::get_multi_asset(); + let mut holding = T::worst_case_holding(1); + + // Add our asset to the holding. + holding.push(asset.clone()); + + // our dest must have no balance initially. + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap(); + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + let instruction = Instruction::>::DepositReserveAsset { + assets: asset.into(), + dest: dest_location, + xcm: Xcm::new(), + }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // dest should have received some asset. + assert!(!T::TransactAsset::balance(&dest_account).is_zero()) + } + + initiate_teleport { + let asset = T::get_multi_asset(); + let mut holding = T::worst_case_holding(0); + + // Add our asset to the holding. + holding.push(asset.clone()); + + // Checked account starts at zero + assert!(T::CheckedAccount::get().map_or(true, |(c, _)| T::TransactAsset::balance(&c).is_zero())); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + let instruction = Instruction::>::InitiateTeleport { + assets: asset.into(), + dest: T::valid_destination()?, + xcm: Xcm::new(), + }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + if let Some((checked_account, _)) = T::CheckedAccount::get() { + // teleport checked account should have received some asset. + assert!(!T::TransactAsset::balance(&checked_account).is_zero()); + } + } + + impl_benchmark_test_suite!( + Pallet, + crate::fungible::mock::new_test_ext(), + crate::fungible::mock::Test + ); +} diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..f5759afc06464141fe1823d10ff662ca3cac64f0 --- /dev/null +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs @@ -0,0 +1,213 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A mock runtime for XCM benchmarking. + +use crate::{fungible as xcm_balances_benchmark, mock::*}; +use frame_benchmarking::BenchmarkError; +use frame_support::{ + parameter_types, + traits::{ConstU32, Everything, Nothing}, + weights::Weight, +}; +use sp_core::H256; +use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; +use xcm::latest::prelude::*; +use xcm_builder::{AllowUnpaidExecutionFrom, MintLocation}; + +type Block = frame_system::mocking::MockBlock; + +// For testing the pallet, we construct a mock runtime. +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + XcmBalancesBenchmark: xcm_balances_benchmark::{Pallet}, + } +); + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, u64::MAX)); +} +impl frame_system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Nonce = u64; + type Hash = H256; + type RuntimeCall = RuntimeCall; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 7; +} + +impl pallet_balances::Config for Test { + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type Balance = u64; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +parameter_types! { + pub const AssetDeposit: u64 = 100 * ExistentialDeposit::get(); + pub const ApprovalDeposit: u64 = 1 * ExistentialDeposit::get(); + pub const StringLimit: u32 = 50; + pub const MetadataDepositBase: u64 = 10 * ExistentialDeposit::get(); + pub const MetadataDepositPerByte: u64 = 1 * ExistentialDeposit::get(); +} + +pub struct MatchAnyFungible; +impl xcm_executor::traits::MatchesFungible for MatchAnyFungible { + fn matches_fungible(m: &MultiAsset) -> Option { + use sp_runtime::traits::SaturatedConversion; + match m { + MultiAsset { fun: Fungible(amount), .. } => Some((*amount).saturated_into::()), + _ => None, + } + } +} + +// Use balances as the asset transactor. +pub type AssetTransactor = xcm_builder::CurrencyAdapter< + Balances, + MatchAnyFungible, + AccountIdConverter, + u64, + CheckingAccount, +>; + +parameter_types! { + /// Maximum number of instructions in a single XCM fragment. A sanity check against weight + /// calculations getting too crazy. + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = DevNull; + type AssetTransactor = AssetTransactor; + type OriginConverter = (); + type IsReserve = TrustedReserves; + type IsTeleporter = TrustedTeleporters; + type UniversalLocation = UniversalLocation; + type Barrier = AllowUnpaidExecutionFrom; + type Weigher = xcm_builder::FixedWeightBounds; + type Trader = xcm_builder::FixedRateOfFungible; + type ResponseHandler = DevNull; + type AssetTrap = (); + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = (); + type SubscriptionService = (); + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; + type Aliasers = Nothing; +} + +impl crate::Config for Test { + type XcmConfig = XcmConfig; + type AccountIdConverter = AccountIdConverter; + fn valid_destination() -> Result { + let valid_destination: MultiLocation = + X1(AccountId32 { network: None, id: [0u8; 32] }).into(); + + Ok(valid_destination) + } + fn worst_case_holding(depositable_count: u32) -> MultiAssets { + crate::mock_worst_case_holding( + depositable_count, + ::MaxAssetsIntoHolding::get(), + ) + } +} + +pub type TrustedTeleporters = xcm_builder::Case; +pub type TrustedReserves = xcm_builder::Case; + +parameter_types! { + pub const CheckingAccount: Option<(u64, MintLocation)> = Some((100, MintLocation::Local)); + pub const ChildTeleporter: MultiLocation = Parachain(1000).into_location(); + pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + ChildTeleporter::get(), + MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(100) }, + )); + pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some(( + ChildTeleporter::get(), + MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(100) }, + )); + pub const TeleportConcreteFungible: (MultiAssetFilter, MultiLocation) = + (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); + pub const ReserveConcreteFungible: (MultiAssetFilter, MultiLocation) = + (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); +} + +impl xcm_balances_benchmark::Config for Test { + type TransactAsset = Balances; + type CheckedAccount = CheckingAccount; + type TrustedTeleporter = TrustedTeleporter; + type TrustedReserve = TrustedReserve; + + fn get_multi_asset() -> MultiAsset { + let amount = + >::minimum_balance() as u128; + MultiAsset { id: Concrete(Here.into()), fun: Fungible(amount) } + } +} + +#[cfg(feature = "runtime-benchmarks")] +pub fn new_test_ext() -> sp_io::TestExternalities { + use sp_runtime::BuildStorage; + let t = RuntimeGenesisConfig { ..Default::default() }.build_storage().unwrap(); + sp_tracing::try_init_simple(); + t.into() +} diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..292921eb595fb082c5c46c1c078d0346c1053970 --- /dev/null +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs @@ -0,0 +1,52 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +// Benchmarking for the `AssetTransactor` trait via `Fungible`. + +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; +#[cfg(test)] +mod mock; + +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::Get; + #[pallet::config] + pub trait Config: frame_system::Config + crate::Config { + /// The type of `fungible` that is being used under the hood. + /// + /// This is useful for testing and checking. + type TransactAsset: frame_support::traits::fungible::Mutate; + + /// The account used to check assets being teleported. + type CheckedAccount: Get>; + + /// A trusted location which we allow teleports from, and the asset we allow to teleport. + type TrustedTeleporter: Get>; + + /// A trusted location where reserve assets are stored, and the asset we allow to be + /// reserves. + type TrustedReserve: Get>; + + /// Give me a fungible asset that your asset transactor is going to accept. + fn get_multi_asset() -> xcm::latest::MultiAsset; + } + + #[pallet::pallet] + pub struct Pallet(_); +} diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..4583ecdba89fc395997fe50b0b86f437297011f9 --- /dev/null +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs @@ -0,0 +1,640 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use crate::{new_executor, XcmCallOf}; +use codec::Encode; +use frame_benchmarking::{benchmarks, BenchmarkError}; +use frame_support::dispatch::GetDispatchInfo; +use sp_std::vec; +use xcm::{ + latest::{prelude::*, MaxDispatchErrorLen, MaybeErrorCode, Weight}, + DoubleEncoded, +}; +use xcm_executor::{ExecutorError, FeesMode}; + +benchmarks! { + report_holding { + let holding = T::worst_case_holding(0); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.clone().into()); + + let instruction = Instruction::>::ReportHolding { + response_info: QueryResponseInfo { + destination: T::valid_destination()?, + query_id: Default::default(), + max_weight: Weight::MAX, + }, + // Worst case is looking through all holdings for every asset explicitly. + assets: Definite(holding), + }; + + let xcm = Xcm(vec![instruction]); + + } : { + executor.bench_process(xcm)?; + } verify { + // The completion of execution above is enough to validate this is completed. + } + + // This benchmark does not use any additional orders or instructions. This should be managed + // by the `deep` and `shallow` implementation. + buy_execution { + let holding = T::worst_case_holding(0).into(); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding); + + let fee_asset = Concrete(Here.into()); + + let instruction = Instruction::>::BuyExecution { + fees: (fee_asset, 100_000_000u128).into(), // should be something inside of holding + weight_limit: WeightLimit::Unlimited, + }; + + let xcm = Xcm(vec![instruction]); + } : { + executor.bench_process(xcm)?; + } verify { + + } + + query_response { + let mut executor = new_executor::(Default::default()); + let (query_id, response) = T::worst_case_response(); + let max_weight = Weight::MAX; + let querier: Option = Some(Here.into()); + let instruction = Instruction::QueryResponse { query_id, response, max_weight, querier }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // The assert above is enough to show this XCM succeeded + } + + // We don't care about the call itself, since that is accounted for in the weight parameter + // and included in the final weight calculation. So this is just the overhead of submitting + // a noop call. + transact { + let (origin, noop_call) = T::transact_origin_and_runtime_call()?; + let mut executor = new_executor::(origin); + let double_encoded_noop_call: DoubleEncoded<_> = noop_call.encode().into(); + + let instruction = Instruction::Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: noop_call.get_dispatch_info().weight, + call: double_encoded_noop_call, + }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // TODO Make the assertion configurable? + } + + refund_surplus { + let holding = T::worst_case_holding(0).into(); + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding); + executor.set_total_surplus(Weight::from_parts(1337, 1337)); + executor.set_total_refunded(Weight::zero()); + + let instruction = Instruction::>::RefundSurplus; + let xcm = Xcm(vec![instruction]); + } : { + let result = executor.bench_process(xcm)?; + } verify { + assert_eq!(executor.total_surplus(), &Weight::from_parts(1337, 1337)); + assert_eq!(executor.total_refunded(), &Weight::from_parts(1337, 1337)); + } + + set_error_handler { + let mut executor = new_executor::(Default::default()); + let instruction = Instruction::>::SetErrorHandler(Xcm(vec![])); + let xcm = Xcm(vec![instruction]); + } : { + executor.bench_process(xcm)?; + } verify { + assert_eq!(executor.error_handler(), &Xcm(vec![])); + } + + set_appendix { + let mut executor = new_executor::(Default::default()); + let appendix = Xcm(vec![]); + let instruction = Instruction::>::SetAppendix(appendix); + let xcm = Xcm(vec![instruction]); + } : { + executor.bench_process(xcm)?; + } verify { + assert_eq!(executor.appendix(), &Xcm(vec![])); + } + + clear_error { + let mut executor = new_executor::(Default::default()); + executor.set_error(Some((5u32, XcmError::Overflow))); + let instruction = Instruction::>::ClearError; + let xcm = Xcm(vec![instruction]); + } : { + executor.bench_process(xcm)?; + } verify { + assert!(executor.error().is_none()) + } + + descend_origin { + let mut executor = new_executor::(Default::default()); + let who = X2(OnlyChild, OnlyChild); + let instruction = Instruction::DescendOrigin(who.clone()); + let xcm = Xcm(vec![instruction]); + } : { + executor.bench_process(xcm)?; + } verify { + assert_eq!( + executor.origin(), + &Some(MultiLocation { + parents: 0, + interior: who, + }), + ); + } + + clear_origin { + let mut executor = new_executor::(Default::default()); + let instruction = Instruction::ClearOrigin; + let xcm = Xcm(vec![instruction]); + } : { + executor.bench_process(xcm)?; + } verify { + assert_eq!(executor.origin(), &None); + } + + report_error { + let mut executor = new_executor::(Default::default()); + executor.set_error(Some((0u32, XcmError::Unimplemented))); + let query_id = Default::default(); + let destination = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; + let max_weight = Default::default(); + + let instruction = Instruction::ReportError(QueryResponseInfo { + query_id, destination, max_weight + }); + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // the execution succeeding is all we need to verify this xcm was successful + } + + claim_asset { + use xcm_executor::traits::DropAssets; + + let (origin, ticket, assets) = T::claimable_asset()?; + + // We place some items into the asset trap to claim. + ::AssetTrap::drop_assets( + &origin, + assets.clone().into(), + &XcmContext { + origin: Some(origin.clone()), + message_id: [0; 32], + topic: None, + }, + ); + + // Assets should be in the trap now. + + let mut executor = new_executor::(origin); + let instruction = Instruction::ClaimAsset { assets: assets.clone(), ticket }; + let xcm = Xcm(vec![instruction]); + } :{ + executor.bench_process(xcm)?; + } verify { + assert!(executor.holding().ensure_contains(&assets).is_ok()); + } + + trap { + let mut executor = new_executor::(Default::default()); + let instruction = Instruction::Trap(10); + let xcm = Xcm(vec![instruction]); + // In order to access result in the verification below, it needs to be defined here. + let mut _result = Ok(()); + } : { + _result = executor.bench_process(xcm); + } verify { + assert!(matches!(_result, Err(ExecutorError { + xcm_error: XcmError::Trap(10), + .. + }))); + } + + subscribe_version { + use xcm_executor::traits::VersionChangeNotifier; + let origin = T::subscribe_origin()?; + let query_id = Default::default(); + let max_response_weight = Default::default(); + let mut executor = new_executor::(origin.clone()); + let instruction = Instruction::SubscribeVersion { query_id, max_response_weight }; + let xcm = Xcm(vec![instruction]); + } : { + executor.bench_process(xcm)?; + } verify { + assert!(::SubscriptionService::is_subscribed(&origin)); + } + + unsubscribe_version { + use xcm_executor::traits::VersionChangeNotifier; + // First we need to subscribe to notifications. + let (origin, _) = T::transact_origin_and_runtime_call()?; + let query_id = Default::default(); + let max_response_weight = Default::default(); + ::SubscriptionService::start( + &origin, + query_id, + max_response_weight, + &XcmContext { + origin: Some(origin.clone()), + message_id: [0; 32], + topic: None, + }, + ).map_err(|_| "Could not start subscription")?; + assert!(::SubscriptionService::is_subscribed(&origin)); + + let mut executor = new_executor::(origin.clone()); + let instruction = Instruction::UnsubscribeVersion; + let xcm = Xcm(vec![instruction]); + } : { + executor.bench_process(xcm)?; + } verify { + assert!(!::SubscriptionService::is_subscribed(&origin)); + } + + burn_asset { + let holding = T::worst_case_holding(0); + let assets = holding.clone(); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + + let instruction = Instruction::BurnAsset(assets.into()); + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + assert!(executor.holding().is_empty()); + } + + expect_asset { + let holding = T::worst_case_holding(0); + let assets = holding.clone(); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + + let instruction = Instruction::ExpectAsset(assets.into()); + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // `execute` completing successfully is as good as we can check. + } + + expect_origin { + let expected_origin = Parent.into(); + let mut executor = new_executor::(Default::default()); + + let instruction = Instruction::ExpectOrigin(Some(expected_origin)); + let xcm = Xcm(vec![instruction]); + let mut _result = Ok(()); + }: { + _result = executor.bench_process(xcm); + } verify { + assert!(matches!(_result, Err(ExecutorError { + xcm_error: XcmError::ExpectationFalse, + .. + }))); + } + + expect_error { + let mut executor = new_executor::(Default::default()); + executor.set_error(Some((3u32, XcmError::Overflow))); + + let instruction = Instruction::ExpectError(None); + let xcm = Xcm(vec![instruction]); + let mut _result = Ok(()); + }: { + _result = executor.bench_process(xcm); + } verify { + assert!(matches!(_result, Err(ExecutorError { + xcm_error: XcmError::ExpectationFalse, + .. + }))); + } + + expect_transact_status { + let mut executor = new_executor::(Default::default()); + let worst_error = || -> MaybeErrorCode { + vec![0; MaxDispatchErrorLen::get() as usize].into() + }; + executor.set_transact_status(worst_error()); + + let instruction = Instruction::ExpectTransactStatus(worst_error()); + let xcm = Xcm(vec![instruction]); + let mut _result = Ok(()); + }: { + _result = executor.bench_process(xcm); + } verify { + assert!(matches!(_result, Ok(..))); + } + + query_pallet { + let query_id = Default::default(); + let destination = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; + let max_weight = Default::default(); + let mut executor = new_executor::(Default::default()); + + let instruction = Instruction::QueryPallet { + module_name: b"frame_system".to_vec(), + response_info: QueryResponseInfo { destination, query_id, max_weight }, + }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // TODO: Potentially add new trait to XcmSender to detect a queued outgoing message. #4426 + } + + expect_pallet { + let mut executor = new_executor::(Default::default()); + + let instruction = Instruction::ExpectPallet { + index: 0, + name: b"System".to_vec(), + module_name: b"frame_system".to_vec(), + crate_major: 4, + min_crate_minor: 0, + }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // the execution succeeding is all we need to verify this xcm was successful + } + + report_transact_status { + let query_id = Default::default(); + let destination = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; + let max_weight = Default::default(); + + let mut executor = new_executor::(Default::default()); + executor.set_transact_status(b"MyError".to_vec().into()); + + let instruction = Instruction::ReportTransactStatus(QueryResponseInfo { + query_id, + destination, + max_weight, + }); + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // TODO: Potentially add new trait to XcmSender to detect a queued outgoing message. #4426 + } + + clear_transact_status { + let mut executor = new_executor::(Default::default()); + executor.set_transact_status(b"MyError".to_vec().into()); + + let instruction = Instruction::ClearTransactStatus; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + assert_eq!(executor.transact_status(), &MaybeErrorCode::Success); + } + + set_topic { + let mut executor = new_executor::(Default::default()); + + let instruction = Instruction::SetTopic([1; 32]); + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + assert_eq!(executor.topic(), &Some([1; 32])); + } + + clear_topic { + let mut executor = new_executor::(Default::default()); + executor.set_topic(Some([2; 32])); + + let instruction = Instruction::ClearTopic; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + assert_eq!(executor.topic(), &None); + } + + exchange_asset { + let (give, want) = T::worst_case_asset_exchange().map_err(|_| BenchmarkError::Skip)?; + let assets = give.clone(); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(give.into()); + let instruction = Instruction::ExchangeAsset { + give: assets.into(), + want: want.clone(), + maximal: true, + }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + assert_eq!(executor.holding(), &want.into()); + } + + universal_origin { + let (origin, alias) = T::universal_alias().map_err(|_| BenchmarkError::Skip)?; + + let mut executor = new_executor::(origin); + + let instruction = Instruction::UniversalOrigin(alias.clone()); + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + use frame_support::traits::Get; + let universal_location = ::UniversalLocation::get(); + assert_eq!(executor.origin(), &Some(X1(alias).relative_to(&universal_location))); + } + + export_message { + let x in 1 .. 1000; + // The `inner_xcm` influences `ExportMessage` total weight based on + // `inner_xcm.encoded_size()`, so for this benchmark use smallest encoded instruction + // to approximate weight per "unit" of encoded size; then actual weight can be estimated + // to be `inner_xcm.encoded_size() * benchmarked_unit`. + // Use `ClearOrigin` as the small encoded instruction. + let inner_xcm = Xcm(vec![ClearOrigin; x as usize]); + // Get `origin`, `network` and `destination` from configured runtime. + let (origin, network, destination) = T::export_message_origin_and_destination()?; + let mut executor = new_executor::(origin); + let xcm = Xcm(vec![ExportMessage { + network, destination, xcm: inner_xcm, + }]); + }: { + executor.bench_process(xcm)?; + } verify { + // The execute completing successfully is as good as we can check. + // TODO: Potentially add new trait to XcmSender to detect a queued outgoing message. #4426 + } + + set_fees_mode { + let mut executor = new_executor::(Default::default()); + executor.set_fees_mode(FeesMode { jit_withdraw: false }); + + let instruction = Instruction::SetFeesMode { jit_withdraw: true }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + assert_eq!(executor.fees_mode(), &FeesMode { jit_withdraw: true }); + } + + lock_asset { + let (unlocker, owner, asset) = T::unlockable_asset()?; + + let mut executor = new_executor::(owner); + executor.set_holding(asset.clone().into()); + + let instruction = Instruction::LockAsset { asset, unlocker }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // TODO: Potentially add new trait to XcmSender to detect a queued outgoing message. #4426 + } + + unlock_asset { + use xcm_executor::traits::{AssetLock, Enact}; + + let (unlocker, owner, asset) = T::unlockable_asset()?; + + let mut executor = new_executor::(unlocker.clone()); + + // We first place the asset in lock first... + ::AssetLocker::prepare_lock( + unlocker, + asset.clone(), + owner.clone(), + ) + .map_err(|_| BenchmarkError::Skip)? + .enact() + .map_err(|_| BenchmarkError::Skip)?; + + // ... then unlock them with the UnlockAsset instruction. + let instruction = Instruction::UnlockAsset { asset, target: owner }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + + } + + note_unlockable { + use xcm_executor::traits::{AssetLock, Enact}; + + let (unlocker, owner, asset) = T::unlockable_asset()?; + + let mut executor = new_executor::(unlocker.clone()); + + // We first place the asset in lock first... + ::AssetLocker::prepare_lock( + unlocker, + asset.clone(), + owner.clone(), + ) + .map_err(|_| BenchmarkError::Skip)? + .enact() + .map_err(|_| BenchmarkError::Skip)?; + + // ... then note them as unlockable with the NoteUnlockable instruction. + let instruction = Instruction::NoteUnlockable { asset, owner }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + + } + + request_unlock { + use xcm_executor::traits::{AssetLock, Enact}; + + let (locker, owner, asset) = T::unlockable_asset()?; + + // We first place the asset in lock first... + ::AssetLocker::prepare_lock( + locker.clone(), + asset.clone(), + owner.clone(), + ) + .map_err(|_| BenchmarkError::Skip)? + .enact() + .map_err(|_| BenchmarkError::Skip)?; + + // ... then request for an unlock with the RequestUnlock instruction. + let mut executor = new_executor::(owner); + let instruction = Instruction::RequestUnlock { asset, locker }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + // TODO: Potentially add new trait to XcmSender to detect a queued outgoing message. #4426 + } + + unpaid_execution { + let mut executor = new_executor::(Default::default()); + executor.set_origin(Some(Here.into())); + + let instruction = Instruction::>::UnpaidExecution { + weight_limit: WeightLimit::Unlimited, + check_origin: Some(Here.into()), + }; + + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } + + alias_origin { + let (origin, target) = T::alias_origin().map_err(|_| BenchmarkError::Skip)?; + + let mut executor = new_executor::(origin); + + let instruction = Instruction::AliasOrigin(target.clone()); + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + assert_eq!(executor.origin(), &Some(target)); + } + + impl_benchmark_test_suite!( + Pallet, + crate::generic::mock::new_test_ext(), + crate::generic::mock::Test + ); +} diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..1b244f316de9f4dd2979c859c8f818739d7ee6b1 --- /dev/null +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs @@ -0,0 +1,226 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! A mock runtime for XCM benchmarking. + +use crate::{generic, mock::*, *}; +use codec::Decode; +use frame_support::{ + match_types, parameter_types, + traits::{Everything, OriginTrait}, + weights::Weight, +}; +use sp_core::H256; +use sp_runtime::traits::{BlakeTwo256, IdentityLookup, TrailingZeroInput}; +use xcm_builder::{ + test_utils::{ + Assets, TestAssetExchanger, TestAssetLocker, TestAssetTrap, TestSubscriptionService, + TestUniversalAliases, + }, + AliasForeignAccountId32, AllowUnpaidExecutionFrom, +}; +use xcm_executor::traits::ConvertOrigin; + +type Block = frame_system::mocking::MockBlock; + +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + XcmGenericBenchmarks: generic::{Pallet}, + } +); + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, u64::MAX)); +} + +impl frame_system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Nonce = u64; + type Hash = H256; + type RuntimeCall = RuntimeCall; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +/// The benchmarks in this pallet should never need an asset transactor to begin with. +pub struct NoAssetTransactor; +impl xcm_executor::traits::TransactAsset for NoAssetTransactor { + fn deposit_asset(_: &MultiAsset, _: &MultiLocation, _: &XcmContext) -> Result<(), XcmError> { + unreachable!(); + } + + fn withdraw_asset( + _: &MultiAsset, + _: &MultiLocation, + _: Option<&XcmContext>, + ) -> Result { + unreachable!(); + } +} + +parameter_types! { + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +match_types! { + pub type OnlyParachains: impl Contains = { + MultiLocation { parents: 0, interior: X1(Parachain(_)) } + }; +} + +type Aliasers = AliasForeignAccountId32; +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = DevNull; + type AssetTransactor = NoAssetTransactor; + type OriginConverter = AlwaysSignedByDefault; + type IsReserve = AllAssetLocationsPass; + type IsTeleporter = (); + type UniversalLocation = UniversalLocation; + type Barrier = AllowUnpaidExecutionFrom; + type Weigher = xcm_builder::FixedWeightBounds; + type Trader = xcm_builder::FixedRateOfFungible; + type ResponseHandler = DevNull; + type AssetTrap = TestAssetTrap; + type AssetLocker = TestAssetLocker; + type AssetExchanger = TestAssetExchanger; + type AssetClaims = TestAssetTrap; + type SubscriptionService = TestSubscriptionService; + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + // No bridges yet... + type MessageExporter = (); + type UniversalAliases = TestUniversalAliases; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; + type Aliasers = Aliasers; +} + +impl crate::Config for Test { + type XcmConfig = XcmConfig; + type AccountIdConverter = AccountIdConverter; + fn valid_destination() -> Result { + let valid_destination: MultiLocation = + Junction::AccountId32 { network: None, id: [0u8; 32] }.into(); + + Ok(valid_destination) + } + fn worst_case_holding(depositable_count: u32) -> MultiAssets { + crate::mock_worst_case_holding( + depositable_count, + ::MaxAssetsIntoHolding::get(), + ) + } +} + +impl generic::Config for Test { + type RuntimeCall = RuntimeCall; + + fn worst_case_response() -> (u64, Response) { + let assets: MultiAssets = (Concrete(Here.into()), 100).into(); + (0, Response::Assets(assets)) + } + + fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + Ok(Default::default()) + } + + fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + Ok((Here.into(), GlobalConsensus(ByGenesis([0; 32])))) + } + + fn transact_origin_and_runtime_call( + ) -> Result<(MultiLocation, ::RuntimeCall), BenchmarkError> { + Ok((Default::default(), frame_system::Call::remark_with_event { remark: vec![] }.into())) + } + + fn subscribe_origin() -> Result { + Ok(Default::default()) + } + + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + let assets: MultiAssets = (Concrete(Here.into()), 100).into(); + let ticket = MultiLocation { parents: 0, interior: X1(GeneralIndex(0)) }; + Ok((Default::default(), ticket, assets)) + } + + fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + let assets: MultiAsset = (Concrete(Here.into()), 100).into(); + Ok((Default::default(), Default::default(), assets)) + } + + fn export_message_origin_and_destination( + ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + // No MessageExporter in tests + Err(BenchmarkError::Skip) + } + + fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + let origin: MultiLocation = + (Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(); + let target: MultiLocation = AccountId32 { network: None, id: [0; 32] }.into(); + Ok((origin, target)) + } +} + +#[cfg(feature = "runtime-benchmarks")] +pub fn new_test_ext() -> sp_io::TestExternalities { + use sp_runtime::BuildStorage; + let t = RuntimeGenesisConfig { ..Default::default() }.build_storage().unwrap(); + sp_tracing::try_init_simple(); + t.into() +} + +pub struct AlwaysSignedByDefault(core::marker::PhantomData); +impl ConvertOrigin for AlwaysSignedByDefault +where + RuntimeOrigin: OriginTrait, + ::AccountId: Decode, +{ + fn convert_origin( + _origin: impl Into, + _kind: OriginKind, + ) -> Result { + Ok(RuntimeOrigin::signed( + ::AccountId::decode(&mut TrailingZeroInput::zeroes()) + .expect("infinite length input; no invalid inputs for type; qed"), + )) + } +} diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..195066ee5b48441ea915872fa1ce1163d00772ac --- /dev/null +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs @@ -0,0 +1,95 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; +#[cfg(test)] +mod mock; + +#[frame_support::pallet] +pub mod pallet { + use frame_benchmarking::BenchmarkError; + use frame_support::{ + dispatch::{Dispatchable, GetDispatchInfo}, + pallet_prelude::Encode, + }; + use xcm::latest::{ + InteriorMultiLocation, Junction, MultiAsset, MultiAssets, MultiLocation, NetworkId, + Response, + }; + + #[pallet::config] + pub trait Config: frame_system::Config + crate::Config { + type RuntimeCall: Dispatchable + + GetDispatchInfo + + From> + + Encode; + + /// The response which causes the most runtime weight. + fn worst_case_response() -> (u64, Response); + + /// The pair of asset collections which causes the most runtime weight if demanded to be + /// exchanged. + /// + /// The first element in the returned tuple represents the assets that are being exchanged + /// from, whereas the second element represents the assets that are being exchanged to. + /// + /// If set to `Err`, benchmarks which rely on an `exchange_asset` will be skipped. + fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError>; + + /// A `(MultiLocation, Junction)` that is one of the `UniversalAliases` configured by the + /// XCM executor. + /// + /// If set to `Err`, benchmarks which rely on a universal alias will be skipped. + fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError>; + + /// The `MultiLocation` and `RuntimeCall` used for successful transaction XCMs. + /// + /// If set to `Err`, benchmarks which rely on a `transact_origin_and_runtime_call` will be + /// skipped. + fn transact_origin_and_runtime_call( + ) -> Result<(MultiLocation, >::RuntimeCall), BenchmarkError>; + + /// A valid `MultiLocation` we can successfully subscribe to. + /// + /// If set to `Err`, benchmarks which rely on a `subscribe_origin` will be skipped. + fn subscribe_origin() -> Result; + + /// Return an origin, ticket, and assets that can be trapped and claimed. + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError>; + + /// Return an unlocker, owner and assets that can be locked and unlocked. + fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError>; + + /// A `(MultiLocation, NetworkId, InteriorMultiLocation)` we can successfully export message + /// to. + /// + /// If set to `Err`, benchmarks which rely on `export_message` will be skipped. + fn export_message_origin_and_destination( + ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError>; + + /// A `(MultiLocation, MultiLocation)` that is one of the `Aliasers` configured by the XCM + /// executor. + /// + /// If set to `Err`, benchmarks which rely on a universal alias will be skipped. + fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError>; + } + + #[pallet::pallet] + pub struct Pallet(_); +} diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..c6a96343595345b041d4d7f7fc26dc4643a0a40a --- /dev/null +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs @@ -0,0 +1,110 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Pallet that serves no other purpose than benchmarking raw messages [`Xcm`]. + +#![cfg_attr(not(feature = "std"), no_std)] + +use codec::Encode; +use frame_benchmarking::{account, BenchmarkError}; +use sp_std::prelude::*; +use xcm::latest::prelude::*; +use xcm_executor::{traits::ConvertLocation, Config as XcmConfig}; + +pub mod fungible; +pub mod generic; + +#[cfg(test)] +mod mock; + +/// A base trait for all individual pallets +pub trait Config: frame_system::Config { + /// The XCM configurations. + /// + /// These might affect the execution of XCM messages, such as defining how the + /// `TransactAsset` is implemented. + type XcmConfig: XcmConfig; + + /// A converter between a multi-location to a sovereign account. + type AccountIdConverter: ConvertLocation; + + /// Does any necessary setup to create a valid destination for XCM messages. + /// Returns that destination's multi-location to be used in benchmarks. + fn valid_destination() -> Result; + + /// Worst case scenario for a holding account in this runtime. + fn worst_case_holding(depositable_count: u32) -> MultiAssets; +} + +const SEED: u32 = 0; + +/// The XCM executor to use for doing stuff. +pub type ExecutorOf = xcm_executor::XcmExecutor<::XcmConfig>; +/// The overarching call type. +pub type OverArchingCallOf = ::RuntimeCall; +/// The asset transactor of our executor +pub type AssetTransactorOf = <::XcmConfig as XcmConfig>::AssetTransactor; +/// The call type of executor's config. Should eventually resolve to the same overarching call type. +pub type XcmCallOf = <::XcmConfig as XcmConfig>::RuntimeCall; + +pub fn mock_worst_case_holding(depositable_count: u32, max_assets: u32) -> MultiAssets { + let fungibles_amount: u128 = 100; + let holding_fungibles = max_assets / 2 - depositable_count; + let holding_non_fungibles = holding_fungibles; + (0..holding_fungibles) + .map(|i| { + MultiAsset { + id: Concrete(GeneralIndex(i as u128).into()), + fun: Fungible(fungibles_amount * i as u128), + } + .into() + }) + .chain(core::iter::once(MultiAsset { id: Concrete(Here.into()), fun: Fungible(u128::MAX) })) + .chain((0..holding_non_fungibles).map(|i| MultiAsset { + id: Concrete(GeneralIndex(i as u128).into()), + fun: NonFungible(asset_instance_from(i)), + })) + .collect::>() + .into() +} + +pub fn asset_instance_from(x: u32) -> AssetInstance { + let bytes = x.encode(); + let mut instance = [0u8; 4]; + instance.copy_from_slice(&bytes); + AssetInstance::Array4(instance) +} + +pub fn new_executor(origin: MultiLocation) -> ExecutorOf { + ExecutorOf::::new(origin, [0; 32]) +} + +/// Build a multi-location from an account id. +fn account_id_junction(index: u32) -> Junction { + let account: T::AccountId = account("account", index, SEED); + let mut encoded = account.encode(); + encoded.resize(32, 0u8); + let mut id = [0u8; 32]; + id.copy_from_slice(&encoded); + Junction::AccountId32 { network: None, id } +} + +pub fn account_and_location(index: u32) -> (T::AccountId, MultiLocation) { + let location: MultiLocation = account_id_junction::(index).into(); + let account = T::AccountIdConverter::convert_location(&location).unwrap(); + + (account, location) +} diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..e02c5bf08615bae8d1b428768f925412025f9a06 --- /dev/null +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs @@ -0,0 +1,71 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::*; +use frame_support::{parameter_types, traits::ContainsPair}; +use xcm::latest::Weight; + +// An xcm sender/receiver akin to > /dev/null +pub struct DevNull; +impl xcm::opaque::latest::SendXcm for DevNull { + type Ticket = (); + fn validate(_: &mut Option, _: &mut Option>) -> SendResult<()> { + Ok(((), MultiAssets::new())) + } + fn deliver(_: ()) -> Result { + Ok([0; 32]) + } +} + +impl xcm_executor::traits::OnResponse for DevNull { + fn expecting_response(_: &MultiLocation, _: u64, _: Option<&MultiLocation>) -> bool { + false + } + fn on_response( + _: &MultiLocation, + _: u64, + _: Option<&MultiLocation>, + _: Response, + _: Weight, + _: &XcmContext, + ) -> Weight { + Weight::zero() + } +} + +pub struct AccountIdConverter; +impl xcm_executor::traits::ConvertLocation for AccountIdConverter { + fn convert_location(ml: &MultiLocation) -> Option { + match ml { + MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, .. }) } => + Some(::decode(&mut &*id.to_vec()).unwrap()), + _ => None, + } + } +} + +parameter_types! { + pub UniversalLocation: InteriorMultiLocation = Junction::Parachain(101).into(); + pub UnitWeightCost: Weight = Weight::from_parts(10, 10); + pub WeightPrice: (AssetId, u128, u128) = (Concrete(Here.into()), 1_000_000, 1024); +} + +pub struct AllAssetLocationsPass; +impl ContainsPair for AllAssetLocationsPass { + fn contains(_: &MultiAsset, _: &MultiLocation) -> bool { + true + } +} diff --git a/polkadot/xcm/pallet-xcm-benchmarks/template.hbs b/polkadot/xcm/pallet-xcm-benchmarks/template.hbs new file mode 100644 index 0000000000000000000000000000000000000000..81cdf62812b671cc3ba9cd75ce00abea301776fb --- /dev/null +++ b/polkadot/xcm/pallet-xcm-benchmarks/template.hbs @@ -0,0 +1,64 @@ +{{header}} +//! Autogenerated weights for `{{pallet}}` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {{version}} +//! DATE: {{date}}, STEPS: `{{cmd.steps}}`, REPEAT: `{{cmd.repeat}}`, LOW RANGE: `{{cmd.lowest_range_values}}`, HIGH RANGE: `{{cmd.highest_range_values}}` +//! WORST CASE MAP SIZE: `{{cmd.worst_case_map_values}}` +//! HOSTNAME: `{{hostname}}`, CPU: `{{cpuname}}` +//! WASM-EXECUTION: {{cmd.wasm_execution}}, CHAIN: {{cmd.chain}}, DB CACHE: {{cmd.db_cache}} + +// Executed Command: +{{#each args as |arg|}} +// {{arg}} +{{/each}} + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `{{pallet}}`. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + {{#each benchmarks as |benchmark|}} + {{#each benchmark.comments as |comment|}} + /// {{comment}} + {{/each}} + {{#each benchmark.component_ranges as |range|}} + /// The range of component `{{range.name}}` is `[{{range.min}}, {{range.max}}]`. + {{/each}} + pub(crate) fn {{benchmark.name~}} + ( + {{~#each benchmark.components as |c| ~}} + {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}} + ) -> Weight { + // Proof Size summary in bytes: + // Measured: `{{benchmark.base_recorded_proof_size}}{{#each benchmark.component_recorded_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Estimated: `{{benchmark.base_calculated_proof_size}}{{#each benchmark.component_calculated_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Minimum execution time: {{underscore benchmark.min_execution_time}}_000 picoseconds. + Weight::from_parts({{underscore benchmark.base_weight}}, {{benchmark.base_calculated_proof_size}}) + {{#each benchmark.component_weight as |cw|}} + // Standard Error: {{underscore cw.error}} + .saturating_add(Weight::from_parts({{underscore cw.slope}}, 0).saturating_mul({{cw.name}}.into())) + {{/each}} + {{#if (ne benchmark.base_reads "0")}} + .saturating_add(T::DbWeight::get().reads({{benchmark.base_reads}})) + {{/if}} + {{#each benchmark.component_reads as |cr|}} + .saturating_add(T::DbWeight::get().reads(({{cr.slope}}_u64).saturating_mul({{cr.name}}.into()))) + {{/each}} + {{#if (ne benchmark.base_writes "0")}} + .saturating_add(T::DbWeight::get().writes({{benchmark.base_writes}})) + {{/if}} + {{#each benchmark.component_writes as |cw|}} + .saturating_add(T::DbWeight::get().writes(({{cw.slope}}_u64).saturating_mul({{cw.name}}.into()))) + {{/each}} + {{#each benchmark.component_calculated_proof_size as |cp|}} + .saturating_add(Weight::from_parts(0, {{cp.slope}}).saturating_mul({{cp.name}}.into())) + {{/each}} + } + {{/each}} +} diff --git a/polkadot/xcm/pallet-xcm/Cargo.toml b/polkadot/xcm/pallet-xcm/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7d5d278b0e0a4371b0631ebc38eaa13aa3e01314 --- /dev/null +++ b/polkadot/xcm/pallet-xcm/Cargo.toml @@ -0,0 +1,60 @@ +[package] +name = "pallet-xcm" +authors.workspace = true +edition.workspace = true +license.workspace = true +version.workspace = true + + +[dependencies] +bounded-collections = { version = "0.1.8", default-features = false } +codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.163", optional = true, features = ["derive"] } +log = { version = "0.4.17", default-features = false } + +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } + +xcm = { path = "..", default-features = false } +xcm-executor = { path = "../xcm-executor", default-features = false } + +[dev-dependencies] +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } +polkadot-runtime-parachains = { path = "../../runtime/parachains" } +polkadot-parachain = { path = "../../parachain" } +xcm-builder = { path = "../xcm-builder" } + +[features] +default = ["std"] +# Enable `VersionedRuntimeUpgrade` for the migrations that is currently still experimental. +experimental = [ + "frame-support/experimental" +] +std = [ + "bounded-collections/std", + "codec/std", + "scale-info/std", + "serde", + "sp-std/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "xcm/std", + "xcm-executor/std", +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/polkadot/xcm/pallet-xcm/src/benchmarking.rs b/polkadot/xcm/pallet-xcm/src/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..aca4bd1fb3fa92b812bc11d9957286310047a98b --- /dev/null +++ b/polkadot/xcm/pallet-xcm/src/benchmarking.rs @@ -0,0 +1,198 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use bounded_collections::{ConstU32, WeakBoundedVec}; +use frame_benchmarking::{benchmarks, BenchmarkError, BenchmarkResult}; +use frame_support::weights::Weight; +use frame_system::RawOrigin; +use sp_std::prelude::*; +use xcm::{latest::prelude::*, v2}; + +type RuntimeOrigin = ::RuntimeOrigin; + +benchmarks! { + send { + let send_origin = + T::SendXcmOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + if T::SendXcmOrigin::try_origin(send_origin.clone()).is_err() { + return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))) + } + let msg = Xcm(vec![ClearOrigin]); + let versioned_dest: VersionedMultiLocation = T::ReachableDest::get().ok_or( + BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), + )? + .into(); + let versioned_msg = VersionedXcm::from(msg); + }: _>(send_origin, Box::new(versioned_dest), Box::new(versioned_msg)) + + teleport_assets { + let asset: MultiAsset = (Here, 10).into(); + let send_origin = + T::ExecuteXcmOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let origin_location = T::ExecuteXcmOrigin::try_origin(send_origin.clone()) + .map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; + if !T::XcmTeleportFilter::contains(&(origin_location, vec![asset.clone()])) { + return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))) + } + + let recipient = [0u8; 32]; + let versioned_dest: VersionedMultiLocation = T::ReachableDest::get().ok_or( + BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), + )? + .into(); + let versioned_beneficiary: VersionedMultiLocation = + AccountId32 { network: None, id: recipient.into() }.into(); + let versioned_assets: VersionedMultiAssets = asset.into(); + }: _>(send_origin, Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0) + + reserve_transfer_assets { + let asset: MultiAsset = (Here, 10).into(); + let send_origin = + T::ExecuteXcmOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let origin_location = T::ExecuteXcmOrigin::try_origin(send_origin.clone()) + .map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; + if !T::XcmReserveTransferFilter::contains(&(origin_location, vec![asset.clone()])) { + return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))) + } + + let recipient = [0u8; 32]; + let versioned_dest: VersionedMultiLocation = T::ReachableDest::get().ok_or( + BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), + )? + .into(); + let versioned_beneficiary: VersionedMultiLocation = + AccountId32 { network: None, id: recipient.into() }.into(); + let versioned_assets: VersionedMultiAssets = asset.into(); + }: _>(send_origin, Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0) + + execute { + let execute_origin = + T::ExecuteXcmOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let origin_location = T::ExecuteXcmOrigin::try_origin(execute_origin.clone()) + .map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; + let msg = Xcm(vec![ClearOrigin]); + if !T::XcmExecuteFilter::contains(&(origin_location, msg.clone())) { + return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))) + } + let versioned_msg = VersionedXcm::from(msg); + }: _>(execute_origin, Box::new(versioned_msg), Weight::zero()) + + force_xcm_version { + let loc = T::ReachableDest::get().ok_or( + BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), + )?; + let xcm_version = 2; + }: _(RawOrigin::Root, Box::new(loc), xcm_version) + + force_default_xcm_version {}: _(RawOrigin::Root, Some(2)) + + force_subscribe_version_notify { + let versioned_loc: VersionedMultiLocation = T::ReachableDest::get().ok_or( + BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), + )? + .into(); + }: _(RawOrigin::Root, Box::new(versioned_loc)) + + force_unsubscribe_version_notify { + let loc = T::ReachableDest::get().ok_or( + BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), + )?; + let versioned_loc: VersionedMultiLocation = loc.into(); + let _ = Pallet::::request_version_notify(loc); + }: _(RawOrigin::Root, Box::new(versioned_loc)) + + force_suspension {}: _(RawOrigin::Root, true) + + migrate_supported_version { + let old_version = XCM_VERSION - 1; + let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + SupportedVersion::::insert(old_version, loc, old_version); + }: { + Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateSupportedVersion, Weight::zero()); + } + + migrate_version_notifiers { + let old_version = XCM_VERSION - 1; + let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + VersionNotifiers::::insert(old_version, loc, 0); + }: { + Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateVersionNotifiers, Weight::zero()); + } + + already_notified_target { + let loc = T::ReachableDest::get().ok_or( + BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads(1))), + )?; + let loc = VersionedMultiLocation::from(loc); + let current_version = T::AdvertisedXcmVersion::get(); + VersionNotifyTargets::::insert(current_version, loc, (0, Weight::zero(), current_version)); + }: { + Pallet::::check_xcm_version_change(VersionMigrationStage::NotifyCurrentTargets(None), Weight::zero()); + } + + notify_current_targets { + let loc = T::ReachableDest::get().ok_or( + BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))), + )?; + let loc = VersionedMultiLocation::from(loc); + let current_version = T::AdvertisedXcmVersion::get(); + let old_version = current_version - 1; + VersionNotifyTargets::::insert(current_version, loc, (0, Weight::zero(), old_version)); + }: { + Pallet::::check_xcm_version_change(VersionMigrationStage::NotifyCurrentTargets(None), Weight::zero()); + } + + notify_target_migration_fail { + let bad_loc: v2::MultiLocation = v2::Junction::Plurality { + id: v2::BodyId::Named(WeakBoundedVec::>::try_from(vec![0; 32]) + .expect("vec has a length of 32 bits; qed")), + part: v2::BodyPart::Voice, + } + .into(); + let bad_loc = VersionedMultiLocation::from(bad_loc); + let current_version = T::AdvertisedXcmVersion::get(); + VersionNotifyTargets::::insert(current_version, bad_loc, (0, Weight::zero(), current_version)); + }: { + Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); + } + + migrate_version_notify_targets { + let current_version = T::AdvertisedXcmVersion::get(); + let old_version = current_version - 1; + let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + VersionNotifyTargets::::insert(old_version, loc, (0, Weight::zero(), current_version)); + }: { + Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); + } + + migrate_and_notify_old_targets { + let loc = T::ReachableDest::get().ok_or( + BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))), + )?; + let loc = VersionedMultiLocation::from(loc); + let old_version = T::AdvertisedXcmVersion::get() - 1; + VersionNotifyTargets::::insert(old_version, loc, (0, Weight::zero(), old_version)); + }: { + Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); + } + + impl_benchmark_test_suite!( + Pallet, + crate::mock::new_test_ext_with_balances(Vec::new()), + crate::mock::Test + ); +} diff --git a/polkadot/xcm/pallet-xcm/src/lib.rs b/polkadot/xcm/pallet-xcm/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..aefcf30910ed90a6f989e8db56cfa7f8ef558ef1 --- /dev/null +++ b/polkadot/xcm/pallet-xcm/src/lib.rs @@ -0,0 +1,2261 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Pallet to handle XCM messages. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; + +pub mod migration; + +use codec::{Decode, Encode, EncodeLike, MaxEncodedLen}; +use frame_support::traits::{ + Contains, ContainsPair, Currency, Defensive, EnsureOrigin, Get, LockableCurrency, OriginTrait, +}; +use scale_info::TypeInfo; +use sp_runtime::{ + traits::{ + AccountIdConversion, BadOrigin, BlakeTwo256, BlockNumberProvider, Hash, Saturating, Zero, + }, + RuntimeDebug, +}; +use sp_std::{boxed::Box, marker::PhantomData, prelude::*, result::Result, vec}; +use xcm::{latest::QueryResponseInfo, prelude::*}; +use xcm_executor::traits::{ConvertOrigin, Properties}; + +use frame_support::{ + dispatch::{Dispatchable, GetDispatchInfo}, + pallet_prelude::*, + traits::WithdrawReasons, + PalletId, +}; +use frame_system::pallet_prelude::*; +pub use pallet::*; +use xcm_executor::{ + traits::{ + CheckSuspension, ClaimAssets, ConvertLocation, DropAssets, MatchesFungible, OnResponse, + QueryHandler, QueryResponseStatus, VersionChangeNotifier, WeightBounds, + }, + Assets, +}; + +pub trait WeightInfo { + fn send() -> Weight; + fn teleport_assets() -> Weight; + fn reserve_transfer_assets() -> Weight; + fn execute() -> Weight; + fn force_xcm_version() -> Weight; + fn force_default_xcm_version() -> Weight; + fn force_subscribe_version_notify() -> Weight; + fn force_unsubscribe_version_notify() -> Weight; + fn force_suspension() -> Weight; + fn migrate_supported_version() -> Weight; + fn migrate_version_notifiers() -> Weight; + fn already_notified_target() -> Weight; + fn notify_current_targets() -> Weight; + fn notify_target_migration_fail() -> Weight; + fn migrate_version_notify_targets() -> Weight; + fn migrate_and_notify_old_targets() -> Weight; +} + +/// fallback implementation +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn send() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn teleport_assets() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn reserve_transfer_assets() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn execute() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn force_xcm_version() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn force_default_xcm_version() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn force_subscribe_version_notify() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn force_unsubscribe_version_notify() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn force_suspension() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn migrate_supported_version() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn migrate_version_notifiers() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn already_notified_target() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn notify_current_targets() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn notify_target_migration_fail() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn migrate_version_notify_targets() -> Weight { + Weight::from_parts(100_000_000, 0) + } + + fn migrate_and_notify_old_targets() -> Weight { + Weight::from_parts(100_000_000, 0) + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::{ + dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}, + parameter_types, + }; + use frame_system::Config as SysConfig; + use sp_core::H256; + use xcm_executor::traits::{MatchesFungible, WeightBounds}; + + parameter_types! { + /// An implementation of `Get` which just returns the latest XCM version which we can + /// support. + pub const CurrentXcmVersion: u32 = XCM_VERSION; + } + + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + #[pallet::without_storage_info] + pub struct Pallet(_); + + pub type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + + #[pallet::config] + /// The module configuration trait. + pub trait Config: frame_system::Config { + /// The overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// A lockable currency. + // TODO: We should really use a trait which can handle multiple currencies. + type Currency: LockableCurrency>; + + /// The `MultiAsset` matcher for `Currency`. + type CurrencyMatcher: MatchesFungible>; + + /// Required origin for sending XCM messages. If successful, it resolves to `MultiLocation` + /// which exists as an interior location within this chain's XCM context. + type SendXcmOrigin: EnsureOrigin< + ::RuntimeOrigin, + Success = MultiLocation, + >; + + /// The type used to actually dispatch an XCM to its destination. + type XcmRouter: SendXcm; + + /// Required origin for executing XCM messages, including the teleport functionality. If + /// successful, then it resolves to `MultiLocation` which exists as an interior location + /// within this chain's XCM context. + type ExecuteXcmOrigin: EnsureOrigin< + ::RuntimeOrigin, + Success = MultiLocation, + >; + + /// Our XCM filter which messages to be executed using `XcmExecutor` must pass. + type XcmExecuteFilter: Contains<(MultiLocation, Xcm<::RuntimeCall>)>; + + /// Something to execute an XCM message. + type XcmExecutor: ExecuteXcm<::RuntimeCall>; + + /// Our XCM filter which messages to be teleported using the dedicated extrinsic must pass. + type XcmTeleportFilter: Contains<(MultiLocation, Vec)>; + + /// Our XCM filter which messages to be reserve-transferred using the dedicated extrinsic + /// must pass. + type XcmReserveTransferFilter: Contains<(MultiLocation, Vec)>; + + /// Means of measuring the weight consumed by an XCM message locally. + type Weigher: WeightBounds<::RuntimeCall>; + + /// This chain's Universal Location. + type UniversalLocation: Get; + + /// The runtime `Origin` type. + type RuntimeOrigin: From + From<::RuntimeOrigin>; + + /// The runtime `Call` type. + type RuntimeCall: Parameter + + GetDispatchInfo + + IsType<::RuntimeCall> + + Dispatchable< + RuntimeOrigin = ::RuntimeOrigin, + PostInfo = PostDispatchInfo, + >; + + const VERSION_DISCOVERY_QUEUE_SIZE: u32; + + /// The latest supported version that we advertise. Generally just set it to + /// `pallet_xcm::CurrentXcmVersion`. + type AdvertisedXcmVersion: Get; + + /// The origin that is allowed to call privileged operations on the XCM pallet + type AdminOrigin: EnsureOrigin<::RuntimeOrigin>; + + /// The assets which we consider a given origin is trusted if they claim to have placed a + /// lock. + type TrustedLockers: ContainsPair; + + /// How to get an `AccountId` value from a `MultiLocation`, useful for handling asset locks. + type SovereignAccountOf: ConvertLocation; + + /// The maximum number of local XCM locks that a single account may have. + type MaxLockers: Get; + + /// The maximum number of consumers a single remote lock may have. + type MaxRemoteLockConsumers: Get; + + /// The ID type for local consumers of remote locks. + type RemoteLockConsumerIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + + /// A `MultiLocation` that can be reached via `XcmRouter`. Used only in benchmarks. + /// + /// If `None`, the benchmarks that depend on a reachable destination will be skipped. + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest: Get>; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// Execution of an XCM message was attempted. + Attempted { outcome: xcm::latest::Outcome }, + /// A XCM message was sent. + Sent { + origin: MultiLocation, + destination: MultiLocation, + message: Xcm<()>, + message_id: XcmHash, + }, + /// Query response received which does not match a registered query. This may be because a + /// matching query was never registered, it may be because it is a duplicate response, or + /// because the query timed out. + UnexpectedResponse { origin: MultiLocation, query_id: QueryId }, + /// Query response has been received and is ready for taking with `take_response`. There is + /// no registered notification call. + ResponseReady { query_id: QueryId, response: Response }, + /// Query response has been received and query is removed. The registered notification has + /// been dispatched and executed successfully. + Notified { query_id: QueryId, pallet_index: u8, call_index: u8 }, + /// Query response has been received and query is removed. The registered notification + /// could not be dispatched because the dispatch weight is greater than the maximum weight + /// originally budgeted by this runtime for the query result. + NotifyOverweight { + query_id: QueryId, + pallet_index: u8, + call_index: u8, + actual_weight: Weight, + max_budgeted_weight: Weight, + }, + /// Query response has been received and query is removed. There was a general error with + /// dispatching the notification call. + NotifyDispatchError { query_id: QueryId, pallet_index: u8, call_index: u8 }, + /// Query response has been received and query is removed. The dispatch was unable to be + /// decoded into a `Call`; this might be due to dispatch function having a signature which + /// is not `(origin, QueryId, Response)`. + NotifyDecodeFailed { query_id: QueryId, pallet_index: u8, call_index: u8 }, + /// Expected query response has been received but the origin location of the response does + /// not match that expected. The query remains registered for a later, valid, response to + /// be received and acted upon. + InvalidResponder { + origin: MultiLocation, + query_id: QueryId, + expected_location: Option, + }, + /// Expected query response has been received but the expected origin location placed in + /// storage by this runtime previously cannot be decoded. The query remains registered. + /// + /// This is unexpected (since a location placed in storage in a previously executing + /// runtime should be readable prior to query timeout) and dangerous since the possibly + /// valid response will be dropped. Manual governance intervention is probably going to be + /// needed. + InvalidResponderVersion { origin: MultiLocation, query_id: QueryId }, + /// Received query response has been read and removed. + ResponseTaken { query_id: QueryId }, + /// Some assets have been placed in an asset trap. + AssetsTrapped { hash: H256, origin: MultiLocation, assets: VersionedMultiAssets }, + /// An XCM version change notification message has been attempted to be sent. + /// + /// The cost of sending it (borne by the chain) is included. + VersionChangeNotified { + destination: MultiLocation, + result: XcmVersion, + cost: MultiAssets, + message_id: XcmHash, + }, + /// The supported version of a location has been changed. This might be through an + /// automatic notification or a manual intervention. + SupportedVersionChanged { location: MultiLocation, version: XcmVersion }, + /// A given location which had a version change subscription was dropped owing to an error + /// sending the notification to it. + NotifyTargetSendFail { location: MultiLocation, query_id: QueryId, error: XcmError }, + /// A given location which had a version change subscription was dropped owing to an error + /// migrating the location to our new XCM format. + NotifyTargetMigrationFail { location: VersionedMultiLocation, query_id: QueryId }, + /// Expected query response has been received but the expected querier location placed in + /// storage by this runtime previously cannot be decoded. The query remains registered. + /// + /// This is unexpected (since a location placed in storage in a previously executing + /// runtime should be readable prior to query timeout) and dangerous since the possibly + /// valid response will be dropped. Manual governance intervention is probably going to be + /// needed. + InvalidQuerierVersion { origin: MultiLocation, query_id: QueryId }, + /// Expected query response has been received but the querier location of the response does + /// not match the expected. The query remains registered for a later, valid, response to + /// be received and acted upon. + InvalidQuerier { + origin: MultiLocation, + query_id: QueryId, + expected_querier: MultiLocation, + maybe_actual_querier: Option, + }, + /// A remote has requested XCM version change notification from us and we have honored it. + /// A version information message is sent to them and its cost is included. + VersionNotifyStarted { destination: MultiLocation, cost: MultiAssets, message_id: XcmHash }, + /// We have requested that a remote chain send us XCM version change notifications. + VersionNotifyRequested { + destination: MultiLocation, + cost: MultiAssets, + message_id: XcmHash, + }, + /// We have requested that a remote chain stops sending us XCM version change + /// notifications. + VersionNotifyUnrequested { + destination: MultiLocation, + cost: MultiAssets, + message_id: XcmHash, + }, + /// Fees were paid from a location for an operation (often for using `SendXcm`). + FeesPaid { paying: MultiLocation, fees: MultiAssets }, + /// Some assets have been claimed from an asset trap + AssetsClaimed { hash: H256, origin: MultiLocation, assets: VersionedMultiAssets }, + } + + #[pallet::origin] + #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub enum Origin { + /// It comes from somewhere in the XCM space wanting to transact. + Xcm(MultiLocation), + /// It comes as an expected response from an XCM location. + Response(MultiLocation), + } + impl From for Origin { + fn from(location: MultiLocation) -> Origin { + Origin::Xcm(location) + } + } + + #[pallet::error] + pub enum Error { + /// The desired destination was unreachable, generally because there is a no way of routing + /// to it. + Unreachable, + /// There was some other issue (i.e. not to do with routing) in sending the message. + /// Perhaps a lack of space for buffering the message. + SendFailure, + /// The message execution fails the filter. + Filtered, + /// The message's weight could not be determined. + UnweighableMessage, + /// The destination `MultiLocation` provided cannot be inverted. + DestinationNotInvertible, + /// The assets to be sent are empty. + Empty, + /// Could not re-anchor the assets to declare the fees for the destination chain. + CannotReanchor, + /// Too many assets have been attempted for transfer. + TooManyAssets, + /// Origin is invalid for sending. + InvalidOrigin, + /// The version of the `Versioned` value used is not able to be interpreted. + BadVersion, + /// The given location could not be used (e.g. because it cannot be expressed in the + /// desired version of XCM). + BadLocation, + /// The referenced subscription could not be found. + NoSubscription, + /// The location is invalid since it already has a subscription from us. + AlreadySubscribed, + /// Invalid asset for the operation. + InvalidAsset, + /// The owner does not own (all) of the asset that they wish to do the operation on. + LowBalance, + /// The asset owner has too many locks on the asset. + TooManyLocks, + /// The given account is not an identifiable sovereign account for any location. + AccountNotSovereign, + /// The operation required fees to be paid which the initiator could not meet. + FeesNotMet, + /// A remote lock with the corresponding data could not be found. + LockNotFound, + /// The unlock operation cannot succeed because there are still consumers of the lock. + InUse, + } + + impl From for Error { + fn from(e: SendError) -> Self { + match e { + SendError::Fees => Error::::FeesNotMet, + SendError::NotApplicable => Error::::Unreachable, + _ => Error::::SendFailure, + } + } + } + + /// The status of a query. + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + pub enum QueryStatus { + /// The query was sent but no response has yet been received. + Pending { + /// The `QueryResponse` XCM must have this origin to be considered a reply for this + /// query. + responder: VersionedMultiLocation, + /// The `QueryResponse` XCM must have this value as the `querier` field to be + /// considered a reply for this query. If `None` then the querier is ignored. + maybe_match_querier: Option, + maybe_notify: Option<(u8, u8)>, + timeout: BlockNumber, + }, + /// The query is for an ongoing version notification subscription. + VersionNotifier { origin: VersionedMultiLocation, is_active: bool }, + /// A response has been received. + Ready { response: VersionedResponse, at: BlockNumber }, + } + + #[derive(Copy, Clone)] + pub(crate) struct LatestVersionedMultiLocation<'a>(pub(crate) &'a MultiLocation); + impl<'a> EncodeLike for LatestVersionedMultiLocation<'a> {} + impl<'a> Encode for LatestVersionedMultiLocation<'a> { + fn encode(&self) -> Vec { + let mut r = VersionedMultiLocation::from(MultiLocation::default()).encode(); + r.truncate(1); + self.0.using_encoded(|d| r.extend_from_slice(d)); + r + } + } + + #[derive(Clone, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, TypeInfo)] + pub enum VersionMigrationStage { + MigrateSupportedVersion, + MigrateVersionNotifiers, + NotifyCurrentTargets(Option>), + MigrateAndNotifyOldTargets, + } + + impl Default for VersionMigrationStage { + fn default() -> Self { + Self::MigrateSupportedVersion + } + } + + /// The latest available query index. + #[pallet::storage] + pub(super) type QueryCounter = StorageValue<_, QueryId, ValueQuery>; + + /// The ongoing queries. + #[pallet::storage] + #[pallet::getter(fn query)] + pub(super) type Queries = + StorageMap<_, Blake2_128Concat, QueryId, QueryStatus>, OptionQuery>; + + /// The existing asset traps. + /// + /// Key is the blake2 256 hash of (origin, versioned `MultiAssets`) pair. Value is the number of + /// times this pair has been trapped (usually just 1 if it exists at all). + #[pallet::storage] + #[pallet::getter(fn asset_trap)] + pub(super) type AssetTraps = StorageMap<_, Identity, H256, u32, ValueQuery>; + + /// Default version to encode XCM when latest version of destination is unknown. If `None`, + /// then the destinations whose XCM version is unknown are considered unreachable. + #[pallet::storage] + #[pallet::whitelist_storage] + pub(super) type SafeXcmVersion = StorageValue<_, XcmVersion, OptionQuery>; + + /// The Latest versions that we know various locations support. + #[pallet::storage] + pub(super) type SupportedVersion = StorageDoubleMap< + _, + Twox64Concat, + XcmVersion, + Blake2_128Concat, + VersionedMultiLocation, + XcmVersion, + OptionQuery, + >; + + /// All locations that we have requested version notifications from. + #[pallet::storage] + pub(super) type VersionNotifiers = StorageDoubleMap< + _, + Twox64Concat, + XcmVersion, + Blake2_128Concat, + VersionedMultiLocation, + QueryId, + OptionQuery, + >; + + /// The target locations that are subscribed to our version changes, as well as the most recent + /// of our versions we informed them of. + #[pallet::storage] + pub(super) type VersionNotifyTargets = StorageDoubleMap< + _, + Twox64Concat, + XcmVersion, + Blake2_128Concat, + VersionedMultiLocation, + (QueryId, Weight, XcmVersion), + OptionQuery, + >; + + pub struct VersionDiscoveryQueueSize(PhantomData); + impl Get for VersionDiscoveryQueueSize { + fn get() -> u32 { + T::VERSION_DISCOVERY_QUEUE_SIZE + } + } + + /// Destinations whose latest XCM version we would like to know. Duplicates not allowed, and + /// the `u32` counter is the number of times that a send to the destination has been attempted, + /// which is used as a prioritization. + #[pallet::storage] + #[pallet::whitelist_storage] + pub(super) type VersionDiscoveryQueue = StorageValue< + _, + BoundedVec<(VersionedMultiLocation, u32), VersionDiscoveryQueueSize>, + ValueQuery, + >; + + /// The current migration's stage, if any. + #[pallet::storage] + pub(super) type CurrentMigration = + StorageValue<_, VersionMigrationStage, OptionQuery>; + + #[derive(Clone, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, TypeInfo, MaxEncodedLen)] + #[scale_info(skip_type_params(MaxConsumers))] + pub struct RemoteLockedFungibleRecord> { + /// Total amount of the asset held by the remote lock. + pub amount: u128, + /// The owner of the locked asset. + pub owner: VersionedMultiLocation, + /// The location which holds the original lock. + pub locker: VersionedMultiLocation, + /// Local consumers of the remote lock with a consumer identifier and the amount + /// of fungible asset every consumer holds. + /// Every consumer can hold up to total amount of the remote lock. + pub consumers: BoundedVec<(ConsumerIdentifier, u128), MaxConsumers>, + } + + impl> RemoteLockedFungibleRecord { + /// Amount of the remote lock in use by consumers. + /// Returns `None` if the remote lock has no consumers. + pub fn amount_held(&self) -> Option { + self.consumers.iter().max_by(|x, y| x.1.cmp(&y.1)).map(|max| max.1) + } + } + + /// Fungible assets which we know are locked on a remote chain. + #[pallet::storage] + pub(super) type RemoteLockedFungibles = StorageNMap< + _, + ( + NMapKey, + NMapKey, + NMapKey, + ), + RemoteLockedFungibleRecord, + OptionQuery, + >; + + /// Fungible assets which we know are locked on this chain. + #[pallet::storage] + pub(super) type LockedFungibles = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + BoundedVec<(BalanceOf, VersionedMultiLocation), T::MaxLockers>, + OptionQuery, + >; + + /// Global suspension state of the XCM executor. + #[pallet::storage] + pub(super) type XcmExecutionSuspended = StorageValue<_, bool, ValueQuery>; + + #[pallet::genesis_config] + pub struct GenesisConfig { + #[serde(skip)] + pub _config: sp_std::marker::PhantomData, + /// The default version to encode outgoing XCM messages with. + pub safe_xcm_version: Option, + } + + impl Default for GenesisConfig { + fn default() -> Self { + Self { safe_xcm_version: Some(XCM_VERSION), _config: Default::default() } + } + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + SafeXcmVersion::::set(self.safe_xcm_version); + } + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(_n: BlockNumberFor) -> Weight { + let mut weight_used = Weight::zero(); + if let Some(migration) = CurrentMigration::::get() { + // Consume 10% of block at most + let max_weight = T::BlockWeights::get().max_block / 10; + let (w, maybe_migration) = Self::check_xcm_version_change(migration, max_weight); + CurrentMigration::::set(maybe_migration); + weight_used.saturating_accrue(w); + } + + // Here we aim to get one successful version negotiation request sent per block, ordered + // by the destinations being most sent to. + let mut q = VersionDiscoveryQueue::::take().into_inner(); + // TODO: correct weights. + weight_used.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + q.sort_by_key(|i| i.1); + while let Some((versioned_dest, _)) = q.pop() { + if let Ok(dest) = MultiLocation::try_from(versioned_dest) { + if Self::request_version_notify(dest).is_ok() { + // TODO: correct weights. + weight_used.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + break + } + } + } + // Should never fail since we only removed items. But better safe than panicking as it's + // way better to drop the queue than panic on initialize. + if let Ok(q) = BoundedVec::try_from(q) { + VersionDiscoveryQueue::::put(q); + } + weight_used + } + } + + pub mod migrations { + use super::*; + use frame_support::traits::{PalletInfoAccess, StorageVersion}; + + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + enum QueryStatusV0 { + Pending { + responder: VersionedMultiLocation, + maybe_notify: Option<(u8, u8)>, + timeout: BlockNumber, + }, + VersionNotifier { + origin: VersionedMultiLocation, + is_active: bool, + }, + Ready { + response: VersionedResponse, + at: BlockNumber, + }, + } + impl From> for QueryStatus { + fn from(old: QueryStatusV0) -> Self { + use QueryStatusV0::*; + match old { + Pending { responder, maybe_notify, timeout } => QueryStatus::Pending { + responder, + maybe_notify, + timeout, + maybe_match_querier: Some(MultiLocation::here().into()), + }, + VersionNotifier { origin, is_active } => + QueryStatus::VersionNotifier { origin, is_active }, + Ready { response, at } => QueryStatus::Ready { response, at }, + } + } + } + + pub fn migrate_to_v1( + ) -> frame_support::weights::Weight { + let on_chain_storage_version =

::on_chain_storage_version(); + log::info!( + target: "runtime::xcm", + "Running migration storage v1 for xcm with storage version {:?}", + on_chain_storage_version, + ); + + if on_chain_storage_version < 1 { + let mut count = 0; + Queries::::translate::>, _>(|_key, value| { + count += 1; + Some(value.into()) + }); + StorageVersion::new(1).put::

(); + log::info!( + target: "runtime::xcm", + "Running migration storage v1 for xcm with storage version {:?} was complete", + on_chain_storage_version, + ); + // calculate and return migration weights + T::DbWeight::get().reads_writes(count as u64 + 1, count as u64 + 1) + } else { + log::warn!( + target: "runtime::xcm", + "Attempted to apply migration to v1 but failed because storage version is {:?}", + on_chain_storage_version, + ); + T::DbWeight::get().reads(1) + } + } + } + + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::send())] + pub fn send( + origin: OriginFor, + dest: Box, + message: Box>, + ) -> DispatchResult { + let origin_location = T::SendXcmOrigin::ensure_origin(origin)?; + let interior: Junctions = + origin_location.try_into().map_err(|_| Error::::InvalidOrigin)?; + let dest = MultiLocation::try_from(*dest).map_err(|()| Error::::BadVersion)?; + let message: Xcm<()> = (*message).try_into().map_err(|()| Error::::BadVersion)?; + + let message_id = + Self::send_xcm(interior, dest, message.clone()).map_err(Error::::from)?; + let e = Event::Sent { origin: origin_location, destination: dest, message, message_id }; + Self::deposit_event(e); + Ok(()) + } + + /// Teleport some assets from the local chain to some destination chain. + /// + /// Fee payment on the destination side is made from the asset in the `assets` vector of + /// index `fee_asset_item`. The weight limit for fees is not provided and thus is unlimited, + /// with all fees taken as needed from the asset. + /// + /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. + /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, + /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send + /// from relay to parachain. + /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will + /// generally be an `AccountId32` value. + /// - `assets`: The assets to be withdrawn. The first item should be the currency used to to + /// pay the fee on the `dest` side. May not be empty. + /// - `fee_asset_item`: The index into `assets` of the item which should be used to pay + /// fees. + #[pallet::call_index(1)] + #[pallet::weight({ + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); + match (maybe_assets, maybe_dest) { + (Ok(assets), Ok(dest)) => { + use sp_std::vec; + let count = assets.len() as u32; + let mut message = Xcm(vec![ + WithdrawAsset(assets), + SetFeesMode { jit_withdraw: true }, + InitiateTeleport { + assets: Wild(AllCounted(count)), + dest, + xcm: Xcm(vec![]), + }, + ]); + T::Weigher::weight(&mut message).map_or(Weight::MAX, |w| T::WeightInfo::teleport_assets().saturating_add(w)) + } + _ => Weight::MAX, + } + })] + pub fn teleport_assets( + origin: OriginFor, + dest: Box, + beneficiary: Box, + assets: Box, + fee_asset_item: u32, + ) -> DispatchResult { + Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_item, None) + } + + /// Transfer some assets from the local chain to the sovereign account of a destination + /// chain and forward a notification XCM. + /// + /// Fee payment on the destination side is made from the asset in the `assets` vector of + /// index `fee_asset_item`. The weight limit for fees is not provided and thus is unlimited, + /// with all fees taken as needed from the asset. + /// + /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. + /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, + /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send + /// from relay to parachain. + /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will + /// generally be an `AccountId32` value. + /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the + /// fee on the `dest` side. + /// - `fee_asset_item`: The index into `assets` of the item which should be used to pay + /// fees. + #[pallet::call_index(2)] + #[pallet::weight({ + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); + match (maybe_assets, maybe_dest) { + (Ok(assets), Ok(dest)) => { + use sp_std::vec; + let mut message = Xcm(vec![ + SetFeesMode { jit_withdraw: true }, + TransferReserveAsset { assets, dest, xcm: Xcm(vec![]) } + ]); + T::Weigher::weight(&mut message).map_or(Weight::MAX, |w| T::WeightInfo::reserve_transfer_assets().saturating_add(w)) + } + _ => Weight::MAX, + } + })] + pub fn reserve_transfer_assets( + origin: OriginFor, + dest: Box, + beneficiary: Box, + assets: Box, + fee_asset_item: u32, + ) -> DispatchResult { + Self::do_reserve_transfer_assets( + origin, + dest, + beneficiary, + assets, + fee_asset_item, + None, + ) + } + + /// Execute an XCM message from a local, signed, origin. + /// + /// An event is deposited indicating whether `msg` could be executed completely or only + /// partially. + /// + /// No more than `max_weight` will be used in its attempted execution. If this is less than + /// the maximum amount of weight that the message could take to be executed, then no + /// execution attempt will be made. + /// + /// NOTE: A successful return to this does *not* imply that the `msg` was executed + /// successfully to completion; only that *some* of it was executed. + #[pallet::call_index(3)] + #[pallet::weight(max_weight.saturating_add(T::WeightInfo::execute()))] + pub fn execute( + origin: OriginFor, + message: Box::RuntimeCall>>, + max_weight: Weight, + ) -> DispatchResultWithPostInfo { + let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; + let hash = message.using_encoded(sp_io::hashing::blake2_256); + let message = (*message).try_into().map_err(|()| Error::::BadVersion)?; + let value = (origin_location, message); + ensure!(T::XcmExecuteFilter::contains(&value), Error::::Filtered); + let (origin_location, message) = value; + let outcome = T::XcmExecutor::execute_xcm_in_credit( + origin_location, + message, + hash, + max_weight, + max_weight, + ); + let result = + Ok(Some(outcome.weight_used().saturating_add(T::WeightInfo::execute())).into()); + Self::deposit_event(Event::Attempted { outcome }); + result + } + + /// Extoll that a particular destination can be communicated with through a particular + /// version of XCM. + /// + /// - `origin`: Must be an origin specified by AdminOrigin. + /// - `location`: The destination that is being described. + /// - `xcm_version`: The latest version of XCM that `location` supports. + #[pallet::call_index(4)] + #[pallet::weight(T::WeightInfo::force_xcm_version())] + pub fn force_xcm_version( + origin: OriginFor, + location: Box, + version: XcmVersion, + ) -> DispatchResult { + T::AdminOrigin::ensure_origin(origin)?; + let location = *location; + SupportedVersion::::insert( + XCM_VERSION, + LatestVersionedMultiLocation(&location), + version, + ); + Self::deposit_event(Event::SupportedVersionChanged { location, version }); + Ok(()) + } + + /// Set a safe XCM version (the version that XCM should be encoded with if the most recent + /// version a destination can accept is unknown). + /// + /// - `origin`: Must be an origin specified by AdminOrigin. + /// - `maybe_xcm_version`: The default XCM encoding version, or `None` to disable. + #[pallet::call_index(5)] + #[pallet::weight(T::WeightInfo::force_default_xcm_version())] + pub fn force_default_xcm_version( + origin: OriginFor, + maybe_xcm_version: Option, + ) -> DispatchResult { + T::AdminOrigin::ensure_origin(origin)?; + SafeXcmVersion::::set(maybe_xcm_version); + Ok(()) + } + + /// Ask a location to notify us regarding their XCM version and any changes to it. + /// + /// - `origin`: Must be an origin specified by AdminOrigin. + /// - `location`: The location to which we should subscribe for XCM version notifications. + #[pallet::call_index(6)] + #[pallet::weight(T::WeightInfo::force_subscribe_version_notify())] + pub fn force_subscribe_version_notify( + origin: OriginFor, + location: Box, + ) -> DispatchResult { + T::AdminOrigin::ensure_origin(origin)?; + let location: MultiLocation = + (*location).try_into().map_err(|()| Error::::BadLocation)?; + Self::request_version_notify(location).map_err(|e| { + match e { + XcmError::InvalidLocation => Error::::AlreadySubscribed, + _ => Error::::InvalidOrigin, + } + .into() + }) + } + + /// Require that a particular destination should no longer notify us regarding any XCM + /// version changes. + /// + /// - `origin`: Must be an origin specified by AdminOrigin. + /// - `location`: The location to which we are currently subscribed for XCM version + /// notifications which we no longer desire. + #[pallet::call_index(7)] + #[pallet::weight(T::WeightInfo::force_unsubscribe_version_notify())] + pub fn force_unsubscribe_version_notify( + origin: OriginFor, + location: Box, + ) -> DispatchResult { + T::AdminOrigin::ensure_origin(origin)?; + let location: MultiLocation = + (*location).try_into().map_err(|()| Error::::BadLocation)?; + Self::unrequest_version_notify(location).map_err(|e| { + match e { + XcmError::InvalidLocation => Error::::NoSubscription, + _ => Error::::InvalidOrigin, + } + .into() + }) + } + + /// Transfer some assets from the local chain to the sovereign account of a destination + /// chain and forward a notification XCM. + /// + /// Fee payment on the destination side is made from the asset in the `assets` vector of + /// index `fee_asset_item`, up to enough to pay for `weight_limit` of weight. If more weight + /// is needed than `weight_limit`, then the operation will fail and the assets send may be + /// at risk. + /// + /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. + /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, + /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send + /// from relay to parachain. + /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will + /// generally be an `AccountId32` value. + /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the + /// fee on the `dest` side. + /// - `fee_asset_item`: The index into `assets` of the item which should be used to pay + /// fees. + /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. + #[pallet::call_index(8)] + #[pallet::weight({ + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); + match (maybe_assets, maybe_dest) { + (Ok(assets), Ok(dest)) => { + use sp_std::vec; + let mut message = Xcm(vec![ + SetFeesMode { jit_withdraw: true }, + TransferReserveAsset { assets, dest, xcm: Xcm(vec![]) } + ]); + T::Weigher::weight(&mut message).map_or(Weight::MAX, |w| T::WeightInfo::reserve_transfer_assets().saturating_add(w)) + } + _ => Weight::MAX, + } + })] + pub fn limited_reserve_transfer_assets( + origin: OriginFor, + dest: Box, + beneficiary: Box, + assets: Box, + fee_asset_item: u32, + weight_limit: WeightLimit, + ) -> DispatchResult { + Self::do_reserve_transfer_assets( + origin, + dest, + beneficiary, + assets, + fee_asset_item, + Some(weight_limit), + ) + } + + /// Teleport some assets from the local chain to some destination chain. + /// + /// Fee payment on the destination side is made from the asset in the `assets` vector of + /// index `fee_asset_item`, up to enough to pay for `weight_limit` of weight. If more weight + /// is needed than `weight_limit`, then the operation will fail and the assets send may be + /// at risk. + /// + /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. + /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, + /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send + /// from relay to parachain. + /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will + /// generally be an `AccountId32` value. + /// - `assets`: The assets to be withdrawn. The first item should be the currency used to to + /// pay the fee on the `dest` side. May not be empty. + /// - `fee_asset_item`: The index into `assets` of the item which should be used to pay + /// fees. + /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. + #[pallet::call_index(9)] + #[pallet::weight({ + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); + match (maybe_assets, maybe_dest) { + (Ok(assets), Ok(dest)) => { + use sp_std::vec; + let count = assets.len() as u32; + let mut message = Xcm(vec![ + WithdrawAsset(assets), + SetFeesMode { jit_withdraw: true }, + InitiateTeleport { assets: Wild(AllCounted(count)), dest, xcm: Xcm(vec![]) }, + ]); + T::Weigher::weight(&mut message).map_or(Weight::MAX, |w| T::WeightInfo::teleport_assets().saturating_add(w)) + } + _ => Weight::MAX, + } + })] + pub fn limited_teleport_assets( + origin: OriginFor, + dest: Box, + beneficiary: Box, + assets: Box, + fee_asset_item: u32, + weight_limit: WeightLimit, + ) -> DispatchResult { + Self::do_teleport_assets( + origin, + dest, + beneficiary, + assets, + fee_asset_item, + Some(weight_limit), + ) + } + + /// Set or unset the global suspension state of the XCM executor. + /// + /// - `origin`: Must be an origin specified by AdminOrigin. + /// - `suspended`: `true` to suspend, `false` to resume. + #[pallet::call_index(10)] + #[pallet::weight(T::WeightInfo::force_suspension())] + pub fn force_suspension(origin: OriginFor, suspended: bool) -> DispatchResult { + T::AdminOrigin::ensure_origin(origin)?; + XcmExecutionSuspended::::set(suspended); + Ok(()) + } + } +} + +/// The maximum number of distinct assets allowed to be transferred in a single helper extrinsic. +const MAX_ASSETS_FOR_TRANSFER: usize = 2; + +impl QueryHandler for Pallet { + type QueryId = u64; + type BlockNumber = BlockNumberFor; + type Error = XcmError; + type UniversalLocation = T::UniversalLocation; + + /// Attempt to create a new query ID and register it as a query that is yet to respond. + fn new_query( + responder: impl Into, + timeout: BlockNumberFor, + match_querier: impl Into, + ) -> Self::QueryId { + Self::do_new_query(responder, None, timeout, match_querier).into() + } + + /// To check the status of the query, use `fn query()` passing the resultant `QueryId` + /// value. + fn report_outcome( + message: &mut Xcm<()>, + responder: impl Into, + timeout: Self::BlockNumber, + ) -> Result { + let responder = responder.into(); + let destination = Self::UniversalLocation::get() + .invert_target(&responder) + .map_err(|()| XcmError::LocationNotInvertible)?; + let query_id = Self::new_query(responder, timeout, Here); + let response_info = QueryResponseInfo { destination, query_id, max_weight: Weight::zero() }; + let report_error = Xcm(vec![ReportError(response_info)]); + message.0.insert(0, SetAppendix(report_error)); + Ok(query_id) + } + + /// Removes response when ready and emits [Event::ResponseTaken] event. + fn take_response(query_id: Self::QueryId) -> QueryResponseStatus { + match Queries::::get(query_id) { + Some(QueryStatus::Ready { response, at }) => match response.try_into() { + Ok(response) => { + Queries::::remove(query_id); + Self::deposit_event(Event::ResponseTaken { query_id }); + QueryResponseStatus::Ready { response, at } + }, + Err(_) => QueryResponseStatus::UnexpectedVersion, + }, + Some(QueryStatus::Pending { timeout, .. }) => QueryResponseStatus::Pending { timeout }, + Some(_) => QueryResponseStatus::UnexpectedVersion, + None => QueryResponseStatus::NotFound, + } + } + + #[cfg(feature = "runtime-benchmarks")] + fn expect_response(id: Self::QueryId, response: Response) { + let response = response.into(); + Queries::::insert( + id, + QueryStatus::Ready { response, at: frame_system::Pallet::::block_number() }, + ); + } +} + +impl Pallet { + fn do_reserve_transfer_assets( + origin: OriginFor, + dest: Box, + beneficiary: Box, + assets: Box, + fee_asset_item: u32, + maybe_weight_limit: Option, + ) -> DispatchResult { + let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; + let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; + let beneficiary: MultiLocation = + (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; + let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + + ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); + let value = (origin_location, assets.into_inner()); + ensure!(T::XcmReserveTransferFilter::contains(&value), Error::::Filtered); + let (origin_location, assets) = value; + let context = T::UniversalLocation::get(); + let fees = assets + .get(fee_asset_item as usize) + .ok_or(Error::::Empty)? + .clone() + .reanchored(&dest, context) + .map_err(|_| Error::::CannotReanchor)?; + let max_assets = assets.len() as u32; + let assets: MultiAssets = assets.into(); + let weight_limit = match maybe_weight_limit { + Some(weight_limit) => weight_limit, + None => { + let fees = fees.clone(); + let mut remote_message = Xcm(vec![ + ReserveAssetDeposited(assets.clone()), + ClearOrigin, + BuyExecution { fees, weight_limit: Limited(Weight::zero()) }, + DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary }, + ]); + // use local weight for remote message and hope for the best. + let remote_weight = T::Weigher::weight(&mut remote_message) + .map_err(|()| Error::::UnweighableMessage)?; + Limited(remote_weight) + }, + }; + let xcm = Xcm(vec![ + BuyExecution { fees, weight_limit }, + DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary }, + ]); + let mut message = Xcm(vec![ + SetFeesMode { jit_withdraw: true }, + TransferReserveAsset { assets, dest, xcm }, + ]); + let weight = + T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; + let hash = message.using_encoded(sp_io::hashing::blake2_256); + let outcome = + T::XcmExecutor::execute_xcm_in_credit(origin_location, message, hash, weight, weight); + Self::deposit_event(Event::Attempted { outcome }); + Ok(()) + } + + fn do_teleport_assets( + origin: OriginFor, + dest: Box, + beneficiary: Box, + assets: Box, + fee_asset_item: u32, + maybe_weight_limit: Option, + ) -> DispatchResult { + let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; + let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; + let beneficiary: MultiLocation = + (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; + let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + + ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); + let value = (origin_location, assets.into_inner()); + ensure!(T::XcmTeleportFilter::contains(&value), Error::::Filtered); + let (origin_location, assets) = value; + let context = T::UniversalLocation::get(); + let fees = assets + .get(fee_asset_item as usize) + .ok_or(Error::::Empty)? + .clone() + .reanchored(&dest, context) + .map_err(|_| Error::::CannotReanchor)?; + let max_assets = assets.len() as u32; + let assets: MultiAssets = assets.into(); + let weight_limit = match maybe_weight_limit { + Some(weight_limit) => weight_limit, + None => { + let fees = fees.clone(); + let mut remote_message = Xcm(vec![ + ReceiveTeleportedAsset(assets.clone()), + ClearOrigin, + BuyExecution { fees, weight_limit: Limited(Weight::zero()) }, + DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary }, + ]); + // use local weight for remote message and hope for the best. + let remote_weight = T::Weigher::weight(&mut remote_message) + .map_err(|()| Error::::UnweighableMessage)?; + Limited(remote_weight) + }, + }; + let xcm = Xcm(vec![ + BuyExecution { fees, weight_limit }, + DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary }, + ]); + let mut message = Xcm(vec![ + WithdrawAsset(assets), + SetFeesMode { jit_withdraw: true }, + InitiateTeleport { assets: Wild(AllCounted(max_assets)), dest, xcm }, + ]); + let weight = + T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; + let hash = message.using_encoded(sp_io::hashing::blake2_256); + let outcome = + T::XcmExecutor::execute_xcm_in_credit(origin_location, message, hash, weight, weight); + Self::deposit_event(Event::Attempted { outcome }); + Ok(()) + } + + /// Will always make progress, and will do its best not to use much more than `weight_cutoff` + /// in doing so. + pub(crate) fn check_xcm_version_change( + mut stage: VersionMigrationStage, + weight_cutoff: Weight, + ) -> (Weight, Option) { + let mut weight_used = Weight::zero(); + + let sv_migrate_weight = T::WeightInfo::migrate_supported_version(); + let vn_migrate_weight = T::WeightInfo::migrate_version_notifiers(); + let vnt_already_notified_weight = T::WeightInfo::already_notified_target(); + let vnt_notify_weight = T::WeightInfo::notify_current_targets(); + let vnt_migrate_weight = T::WeightInfo::migrate_version_notify_targets(); + let vnt_migrate_fail_weight = T::WeightInfo::notify_target_migration_fail(); + let vnt_notify_migrate_weight = T::WeightInfo::migrate_and_notify_old_targets(); + + use VersionMigrationStage::*; + + if stage == MigrateSupportedVersion { + // We assume that supported XCM version only ever increases, so just cycle through lower + // XCM versioned from the current. + for v in 0..XCM_VERSION { + for (old_key, value) in SupportedVersion::::drain_prefix(v) { + if let Ok(new_key) = old_key.into_latest() { + SupportedVersion::::insert(XCM_VERSION, new_key, value); + } + weight_used.saturating_accrue(sv_migrate_weight); + if weight_used.any_gte(weight_cutoff) { + return (weight_used, Some(stage)) + } + } + } + stage = MigrateVersionNotifiers; + } + if stage == MigrateVersionNotifiers { + for v in 0..XCM_VERSION { + for (old_key, value) in VersionNotifiers::::drain_prefix(v) { + if let Ok(new_key) = old_key.into_latest() { + VersionNotifiers::::insert(XCM_VERSION, new_key, value); + } + weight_used.saturating_accrue(vn_migrate_weight); + if weight_used.any_gte(weight_cutoff) { + return (weight_used, Some(stage)) + } + } + } + stage = NotifyCurrentTargets(None); + } + + let xcm_version = T::AdvertisedXcmVersion::get(); + + if let NotifyCurrentTargets(maybe_last_raw_key) = stage { + let mut iter = match maybe_last_raw_key { + Some(k) => VersionNotifyTargets::::iter_prefix_from(XCM_VERSION, k), + None => VersionNotifyTargets::::iter_prefix(XCM_VERSION), + }; + while let Some((key, value)) = iter.next() { + let (query_id, max_weight, target_xcm_version) = value; + let new_key: MultiLocation = match key.clone().try_into() { + Ok(k) if target_xcm_version != xcm_version => k, + _ => { + // We don't early return here since we need to be certain that we + // make some progress. + weight_used.saturating_accrue(vnt_already_notified_weight); + continue + }, + }; + let response = Response::Version(xcm_version); + let message = + Xcm(vec![QueryResponse { query_id, response, max_weight, querier: None }]); + let event = match send_xcm::(new_key, message) { + Ok((message_id, cost)) => { + let value = (query_id, max_weight, xcm_version); + VersionNotifyTargets::::insert(XCM_VERSION, key, value); + Event::VersionChangeNotified { + destination: new_key, + result: xcm_version, + cost, + message_id, + } + }, + Err(e) => { + VersionNotifyTargets::::remove(XCM_VERSION, key); + Event::NotifyTargetSendFail { location: new_key, query_id, error: e.into() } + }, + }; + Self::deposit_event(event); + weight_used.saturating_accrue(vnt_notify_weight); + if weight_used.any_gte(weight_cutoff) { + let last = Some(iter.last_raw_key().into()); + return (weight_used, Some(NotifyCurrentTargets(last))) + } + } + stage = MigrateAndNotifyOldTargets; + } + if stage == MigrateAndNotifyOldTargets { + for v in 0..XCM_VERSION { + for (old_key, value) in VersionNotifyTargets::::drain_prefix(v) { + let (query_id, max_weight, target_xcm_version) = value; + let new_key = match MultiLocation::try_from(old_key.clone()) { + Ok(k) => k, + Err(()) => { + Self::deposit_event(Event::NotifyTargetMigrationFail { + location: old_key, + query_id: value.0, + }); + weight_used.saturating_accrue(vnt_migrate_fail_weight); + if weight_used.any_gte(weight_cutoff) { + return (weight_used, Some(stage)) + } + continue + }, + }; + + let versioned_key = LatestVersionedMultiLocation(&new_key); + if target_xcm_version == xcm_version { + VersionNotifyTargets::::insert(XCM_VERSION, versioned_key, value); + weight_used.saturating_accrue(vnt_migrate_weight); + } else { + // Need to notify target. + let response = Response::Version(xcm_version); + let message = Xcm(vec![QueryResponse { + query_id, + response, + max_weight, + querier: None, + }]); + let event = match send_xcm::(new_key, message) { + Ok((message_id, cost)) => { + VersionNotifyTargets::::insert( + XCM_VERSION, + versioned_key, + (query_id, max_weight, xcm_version), + ); + Event::VersionChangeNotified { + destination: new_key, + result: xcm_version, + cost, + message_id, + } + }, + Err(e) => Event::NotifyTargetSendFail { + location: new_key, + query_id, + error: e.into(), + }, + }; + Self::deposit_event(event); + weight_used.saturating_accrue(vnt_notify_migrate_weight); + } + if weight_used.any_gte(weight_cutoff) { + return (weight_used, Some(stage)) + } + } + } + } + (weight_used, None) + } + + /// Request that `dest` informs us of its version. + pub fn request_version_notify(dest: impl Into) -> XcmResult { + let dest = dest.into(); + let versioned_dest = VersionedMultiLocation::from(dest); + let already = VersionNotifiers::::contains_key(XCM_VERSION, &versioned_dest); + ensure!(!already, XcmError::InvalidLocation); + let query_id = QueryCounter::::mutate(|q| { + let r = *q; + q.saturating_inc(); + r + }); + // TODO #3735: Correct weight. + let instruction = SubscribeVersion { query_id, max_response_weight: Weight::zero() }; + let (message_id, cost) = send_xcm::(dest, Xcm(vec![instruction]))?; + Self::deposit_event(Event::VersionNotifyRequested { destination: dest, cost, message_id }); + VersionNotifiers::::insert(XCM_VERSION, &versioned_dest, query_id); + let query_status = + QueryStatus::VersionNotifier { origin: versioned_dest, is_active: false }; + Queries::::insert(query_id, query_status); + Ok(()) + } + + /// Request that `dest` ceases informing us of its version. + pub fn unrequest_version_notify(dest: impl Into) -> XcmResult { + let dest = dest.into(); + let versioned_dest = LatestVersionedMultiLocation(&dest); + let query_id = VersionNotifiers::::take(XCM_VERSION, versioned_dest) + .ok_or(XcmError::InvalidLocation)?; + let (message_id, cost) = send_xcm::(dest, Xcm(vec![UnsubscribeVersion]))?; + Self::deposit_event(Event::VersionNotifyUnrequested { + destination: dest, + cost, + message_id, + }); + Queries::::remove(query_id); + Ok(()) + } + + /// Relay an XCM `message` from a given `interior` location in this context to a given `dest` + /// location. The `fee_payer` is charged for the delivery unless `None` in which case fees + /// are not charged (and instead borne by the chain). + pub fn send_xcm( + interior: impl Into, + dest: impl Into, + mut message: Xcm<()>, + ) -> Result { + let interior = interior.into(); + let dest = dest.into(); + let maybe_fee_payer = if interior != Junctions::Here { + message.0.insert(0, DescendOrigin(interior)); + Some(interior.into()) + } else { + None + }; + log::debug!(target: "xcm::send_xcm", "dest: {:?}, message: {:?}", &dest, &message); + let (ticket, price) = validate_send::(dest, message)?; + if let Some(fee_payer) = maybe_fee_payer { + Self::charge_fees(fee_payer, price).map_err(|_| SendError::Fees)?; + } + T::XcmRouter::deliver(ticket) + } + + pub fn check_account() -> T::AccountId { + const ID: PalletId = PalletId(*b"py/xcmch"); + AccountIdConversion::::into_account_truncating(&ID) + } + + /// Create a new expectation of a query response with the querier being here. + fn do_new_query( + responder: impl Into, + maybe_notify: Option<(u8, u8)>, + timeout: BlockNumberFor, + match_querier: impl Into, + ) -> u64 { + QueryCounter::::mutate(|q| { + let r = *q; + q.saturating_inc(); + Queries::::insert( + r, + QueryStatus::Pending { + responder: responder.into().into(), + maybe_match_querier: Some(match_querier.into().into()), + maybe_notify, + timeout, + }, + ); + r + }) + } + + /// Consume `message` and return another which is equivalent to it except that it reports + /// back the outcome and dispatches `notify` on this chain. + /// + /// - `message`: The message whose outcome should be reported. + /// - `responder`: The origin from which a response should be expected. + /// - `notify`: A dispatchable function which will be called once the outcome of `message` is + /// known. It may be a dispatchable in any pallet of the local chain, but other than the usual + /// origin, it must accept exactly two arguments: `query_id: QueryId` and `outcome: Response`, + /// and in that order. It should expect that the origin is `Origin::Response` and will contain + /// the responder's location. + /// - `timeout`: The block number after which it is permissible for `notify` not to be called + /// even if a response is received. + /// + /// `report_outcome_notify` may return an error if the `responder` is not invertible. + /// + /// It is assumed that the querier of the response will be `Here`. + /// + /// NOTE: `notify` gets called as part of handling an incoming message, so it should be + /// lightweight. Its weight is estimated during this function and stored ready for + /// weighing `ReportOutcome` on the way back. If it turns out to be heavier once it returns + /// then reporting the outcome will fail. Futhermore if the estimate is too high, then it + /// may be put in the overweight queue and need to be manually executed. + pub fn report_outcome_notify( + message: &mut Xcm<()>, + responder: impl Into, + notify: impl Into<::RuntimeCall>, + timeout: BlockNumberFor, + ) -> Result<(), XcmError> { + let responder = responder.into(); + let destination = T::UniversalLocation::get() + .invert_target(&responder) + .map_err(|()| XcmError::LocationNotInvertible)?; + let notify: ::RuntimeCall = notify.into(); + let max_weight = notify.get_dispatch_info().weight; + let query_id = Self::new_notify_query(responder, notify, timeout, Here); + let response_info = QueryResponseInfo { destination, query_id, max_weight }; + let report_error = Xcm(vec![ReportError(response_info)]); + message.0.insert(0, SetAppendix(report_error)); + Ok(()) + } + + /// Attempt to create a new query ID and register it as a query that is yet to respond, and + /// which will call a dispatchable when a response happens. + pub fn new_notify_query( + responder: impl Into, + notify: impl Into<::RuntimeCall>, + timeout: BlockNumberFor, + match_querier: impl Into, + ) -> u64 { + let notify = notify.into().using_encoded(|mut bytes| Decode::decode(&mut bytes)).expect( + "decode input is output of Call encode; Call guaranteed to have two enums; qed", + ); + Self::do_new_query(responder, Some(notify), timeout, match_querier) + } + + /// Note that a particular destination to whom we would like to send a message is unknown + /// and queue it for version discovery. + fn note_unknown_version(dest: &MultiLocation) { + log::trace!( + target: "xcm::pallet_xcm::note_unknown_version", + "XCM version is unknown for destination: {:?}", + dest, + ); + let versioned_dest = VersionedMultiLocation::from(*dest); + VersionDiscoveryQueue::::mutate(|q| { + if let Some(index) = q.iter().position(|i| &i.0 == &versioned_dest) { + // exists - just bump the count. + q[index].1.saturating_inc(); + } else { + let _ = q.try_push((versioned_dest, 1)); + } + }); + } + + /// Withdraw given `assets` from the given `location` and pay as XCM fees. + /// + /// Fails if: + /// - the `assets` are not known on this chain; + /// - the `assets` cannot be withdrawn with that location as the Origin. + fn charge_fees(location: MultiLocation, assets: MultiAssets) -> DispatchResult { + T::XcmExecutor::charge_fees(location, assets.clone()) + .map_err(|_| Error::::FeesNotMet)?; + Self::deposit_event(Event::FeesPaid { paying: location, fees: assets }); + Ok(()) + } +} + +pub struct LockTicket { + sovereign_account: T::AccountId, + amount: BalanceOf, + unlocker: MultiLocation, + item_index: Option, +} + +impl xcm_executor::traits::Enact for LockTicket { + fn enact(self) -> Result<(), xcm_executor::traits::LockError> { + use xcm_executor::traits::LockError::UnexpectedState; + let mut locks = LockedFungibles::::get(&self.sovereign_account).unwrap_or_default(); + match self.item_index { + Some(index) => { + ensure!(locks.len() > index, UnexpectedState); + ensure!(locks[index].1.try_as::<_>() == Ok(&self.unlocker), UnexpectedState); + locks[index].0 = locks[index].0.max(self.amount); + }, + None => { + locks + .try_push((self.amount, self.unlocker.into())) + .map_err(|(_balance, _location)| UnexpectedState)?; + }, + } + LockedFungibles::::insert(&self.sovereign_account, locks); + T::Currency::extend_lock( + *b"py/xcmlk", + &self.sovereign_account, + self.amount, + WithdrawReasons::all(), + ); + Ok(()) + } +} + +pub struct UnlockTicket { + sovereign_account: T::AccountId, + amount: BalanceOf, + unlocker: MultiLocation, +} + +impl xcm_executor::traits::Enact for UnlockTicket { + fn enact(self) -> Result<(), xcm_executor::traits::LockError> { + use xcm_executor::traits::LockError::UnexpectedState; + let mut locks = + LockedFungibles::::get(&self.sovereign_account).ok_or(UnexpectedState)?; + let mut maybe_remove_index = None; + let mut locked = BalanceOf::::zero(); + let mut found = false; + // We could just as well do with with an into_iter, filter_map and collect, however this way + // avoids making an allocation. + for (i, x) in locks.iter_mut().enumerate() { + if x.1.try_as::<_>().defensive() == Ok(&self.unlocker) { + x.0 = x.0.saturating_sub(self.amount); + if x.0.is_zero() { + maybe_remove_index = Some(i); + } + found = true; + } + locked = locked.max(x.0); + } + ensure!(found, UnexpectedState); + if let Some(remove_index) = maybe_remove_index { + locks.swap_remove(remove_index); + } + LockedFungibles::::insert(&self.sovereign_account, locks); + let reasons = WithdrawReasons::all(); + T::Currency::set_lock(*b"py/xcmlk", &self.sovereign_account, locked, reasons); + Ok(()) + } +} + +pub struct ReduceTicket { + key: (u32, T::AccountId, VersionedAssetId), + amount: u128, + locker: VersionedMultiLocation, + owner: VersionedMultiLocation, +} + +impl xcm_executor::traits::Enact for ReduceTicket { + fn enact(self) -> Result<(), xcm_executor::traits::LockError> { + use xcm_executor::traits::LockError::UnexpectedState; + let mut record = RemoteLockedFungibles::::get(&self.key).ok_or(UnexpectedState)?; + ensure!(self.locker == record.locker && self.owner == record.owner, UnexpectedState); + let new_amount = record.amount.checked_sub(self.amount).ok_or(UnexpectedState)?; + ensure!(record.amount_held().map_or(true, |h| new_amount >= h), UnexpectedState); + if new_amount == 0 { + RemoteLockedFungibles::::remove(&self.key); + } else { + record.amount = new_amount; + RemoteLockedFungibles::::insert(&self.key, &record); + } + Ok(()) + } +} + +impl xcm_executor::traits::AssetLock for Pallet { + type LockTicket = LockTicket; + type UnlockTicket = UnlockTicket; + type ReduceTicket = ReduceTicket; + + fn prepare_lock( + unlocker: MultiLocation, + asset: MultiAsset, + owner: MultiLocation, + ) -> Result, xcm_executor::traits::LockError> { + use xcm_executor::traits::LockError::*; + let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?; + let amount = T::CurrencyMatcher::matches_fungible(&asset).ok_or(UnknownAsset)?; + ensure!(T::Currency::free_balance(&sovereign_account) >= amount, AssetNotOwned); + let locks = LockedFungibles::::get(&sovereign_account).unwrap_or_default(); + let item_index = locks.iter().position(|x| x.1.try_as::<_>() == Ok(&unlocker)); + ensure!(item_index.is_some() || locks.len() < T::MaxLockers::get() as usize, NoResources); + Ok(LockTicket { sovereign_account, amount, unlocker, item_index }) + } + + fn prepare_unlock( + unlocker: MultiLocation, + asset: MultiAsset, + owner: MultiLocation, + ) -> Result, xcm_executor::traits::LockError> { + use xcm_executor::traits::LockError::*; + let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?; + let amount = T::CurrencyMatcher::matches_fungible(&asset).ok_or(UnknownAsset)?; + ensure!(T::Currency::free_balance(&sovereign_account) >= amount, AssetNotOwned); + let locks = LockedFungibles::::get(&sovereign_account).unwrap_or_default(); + let item_index = + locks.iter().position(|x| x.1.try_as::<_>() == Ok(&unlocker)).ok_or(NotLocked)?; + ensure!(locks[item_index].0 >= amount, NotLocked); + Ok(UnlockTicket { sovereign_account, amount, unlocker }) + } + + fn note_unlockable( + locker: MultiLocation, + asset: MultiAsset, + mut owner: MultiLocation, + ) -> Result<(), xcm_executor::traits::LockError> { + use xcm_executor::traits::LockError::*; + ensure!(T::TrustedLockers::contains(&locker, &asset), NotTrusted); + let amount = match asset.fun { + Fungible(a) => a, + NonFungible(_) => return Err(Unimplemented), + }; + owner.remove_network_id(); + let account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?; + let locker = locker.into(); + let owner = owner.into(); + let id: VersionedAssetId = asset.id.into(); + let key = (XCM_VERSION, account, id); + let mut record = + RemoteLockedFungibleRecord { amount, owner, locker, consumers: BoundedVec::default() }; + if let Some(old) = RemoteLockedFungibles::::get(&key) { + // Make sure that the new record wouldn't clobber any old data. + ensure!(old.locker == record.locker && old.owner == record.owner, WouldClobber); + record.consumers = old.consumers; + record.amount = record.amount.max(old.amount); + } + RemoteLockedFungibles::::insert(&key, record); + Ok(()) + } + + fn prepare_reduce_unlockable( + locker: MultiLocation, + asset: MultiAsset, + mut owner: MultiLocation, + ) -> Result { + use xcm_executor::traits::LockError::*; + let amount = match asset.fun { + Fungible(a) => a, + NonFungible(_) => return Err(Unimplemented), + }; + owner.remove_network_id(); + let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?; + let locker = locker.into(); + let owner = owner.into(); + let id: VersionedAssetId = asset.id.into(); + let key = (XCM_VERSION, sovereign_account, id); + + let record = RemoteLockedFungibles::::get(&key).ok_or(NotLocked)?; + // Make sure that the record contains what we expect and there's enough to unlock. + ensure!(locker == record.locker && owner == record.owner, WouldClobber); + ensure!(record.amount >= amount, NotEnoughLocked); + ensure!( + record.amount_held().map_or(true, |h| record.amount.saturating_sub(amount) >= h), + InUse + ); + Ok(ReduceTicket { key, amount, locker, owner }) + } +} + +impl WrapVersion for Pallet { + fn wrap_version( + dest: &MultiLocation, + xcm: impl Into>, + ) -> Result, ()> { + SupportedVersion::::get(XCM_VERSION, LatestVersionedMultiLocation(dest)) + .or_else(|| { + Self::note_unknown_version(dest); + SafeXcmVersion::::get() + }) + .ok_or_else(|| { + log::trace!( + target: "xcm::pallet_xcm::wrap_version", + "Could not determine a version to wrap XCM for destination: {:?}", + dest, + ); + () + }) + .and_then(|v| xcm.into().into_version(v.min(XCM_VERSION))) + } +} + +impl VersionChangeNotifier for Pallet { + /// Start notifying `location` should the XCM version of this chain change. + /// + /// When it does, this type should ensure a `QueryResponse` message is sent with the given + /// `query_id` & `max_weight` and with a `response` of `Response::Version`. This should happen + /// until/unless `stop` is called with the correct `query_id`. + /// + /// If the `location` has an ongoing notification and when this function is called, then an + /// error should be returned. + fn start( + dest: &MultiLocation, + query_id: QueryId, + max_weight: Weight, + _context: &XcmContext, + ) -> XcmResult { + let versioned_dest = LatestVersionedMultiLocation(dest); + let already = VersionNotifyTargets::::contains_key(XCM_VERSION, versioned_dest); + ensure!(!already, XcmError::InvalidLocation); + + let xcm_version = T::AdvertisedXcmVersion::get(); + let response = Response::Version(xcm_version); + let instruction = QueryResponse { query_id, response, max_weight, querier: None }; + let (message_id, cost) = send_xcm::(*dest, Xcm(vec![instruction]))?; + Self::deposit_event(Event::::VersionNotifyStarted { + destination: *dest, + cost, + message_id, + }); + + let value = (query_id, max_weight, xcm_version); + VersionNotifyTargets::::insert(XCM_VERSION, versioned_dest, value); + Ok(()) + } + + /// Stop notifying `location` should the XCM change. This is a no-op if there was never a + /// subscription. + fn stop(dest: &MultiLocation, _context: &XcmContext) -> XcmResult { + VersionNotifyTargets::::remove(XCM_VERSION, LatestVersionedMultiLocation(dest)); + Ok(()) + } + + /// Return true if a location is subscribed to XCM version changes. + fn is_subscribed(dest: &MultiLocation) -> bool { + let versioned_dest = LatestVersionedMultiLocation(dest); + VersionNotifyTargets::::contains_key(XCM_VERSION, versioned_dest) + } +} + +impl DropAssets for Pallet { + fn drop_assets(origin: &MultiLocation, assets: Assets, _context: &XcmContext) -> Weight { + if assets.is_empty() { + return Weight::zero() + } + let versioned = VersionedMultiAssets::from(MultiAssets::from(assets)); + let hash = BlakeTwo256::hash_of(&(&origin, &versioned)); + AssetTraps::::mutate(hash, |n| *n += 1); + Self::deposit_event(Event::AssetsTrapped { hash, origin: *origin, assets: versioned }); + // TODO #3735: Put the real weight in there. + Weight::zero() + } +} + +impl ClaimAssets for Pallet { + fn claim_assets( + origin: &MultiLocation, + ticket: &MultiLocation, + assets: &MultiAssets, + _context: &XcmContext, + ) -> bool { + let mut versioned = VersionedMultiAssets::from(assets.clone()); + match (ticket.parents, &ticket.interior) { + (0, X1(GeneralIndex(i))) => + versioned = match versioned.into_version(*i as u32) { + Ok(v) => v, + Err(()) => return false, + }, + (0, Here) => (), + _ => return false, + }; + let hash = BlakeTwo256::hash_of(&(origin, versioned.clone())); + match AssetTraps::::get(hash) { + 0 => return false, + 1 => AssetTraps::::remove(hash), + n => AssetTraps::::insert(hash, n - 1), + } + Self::deposit_event(Event::AssetsClaimed { hash, origin: *origin, assets: versioned }); + return true + } +} + +impl OnResponse for Pallet { + fn expecting_response( + origin: &MultiLocation, + query_id: QueryId, + querier: Option<&MultiLocation>, + ) -> bool { + match Queries::::get(query_id) { + Some(QueryStatus::Pending { responder, maybe_match_querier, .. }) => + MultiLocation::try_from(responder).map_or(false, |r| origin == &r) && + maybe_match_querier.map_or(true, |match_querier| { + MultiLocation::try_from(match_querier).map_or(false, |match_querier| { + querier.map_or(false, |q| q == &match_querier) + }) + }), + Some(QueryStatus::VersionNotifier { origin: r, .. }) => + MultiLocation::try_from(r).map_or(false, |r| origin == &r), + _ => false, + } + } + + fn on_response( + origin: &MultiLocation, + query_id: QueryId, + querier: Option<&MultiLocation>, + response: Response, + max_weight: Weight, + _context: &XcmContext, + ) -> Weight { + let origin = *origin; + match (response, Queries::::get(query_id)) { + ( + Response::Version(v), + Some(QueryStatus::VersionNotifier { origin: expected_origin, is_active }), + ) => { + let origin: MultiLocation = match expected_origin.try_into() { + Ok(o) if o == origin => o, + Ok(o) => { + Self::deposit_event(Event::InvalidResponder { + origin, + query_id, + expected_location: Some(o), + }); + return Weight::zero() + }, + _ => { + Self::deposit_event(Event::InvalidResponder { + origin, + query_id, + expected_location: None, + }); + // TODO #3735: Correct weight for this. + return Weight::zero() + }, + }; + // TODO #3735: Check max_weight is correct. + if !is_active { + Queries::::insert( + query_id, + QueryStatus::VersionNotifier { origin: origin.into(), is_active: true }, + ); + } + // We're being notified of a version change. + SupportedVersion::::insert( + XCM_VERSION, + LatestVersionedMultiLocation(&origin), + v, + ); + Self::deposit_event(Event::SupportedVersionChanged { + location: origin, + version: v, + }); + Weight::zero() + }, + ( + response, + Some(QueryStatus::Pending { responder, maybe_notify, maybe_match_querier, .. }), + ) => { + if let Some(match_querier) = maybe_match_querier { + let match_querier = match MultiLocation::try_from(match_querier) { + Ok(mq) => mq, + Err(_) => { + Self::deposit_event(Event::InvalidQuerierVersion { origin, query_id }); + return Weight::zero() + }, + }; + if querier.map_or(true, |q| q != &match_querier) { + Self::deposit_event(Event::InvalidQuerier { + origin, + query_id, + expected_querier: match_querier, + maybe_actual_querier: querier.cloned(), + }); + return Weight::zero() + } + } + let responder = match MultiLocation::try_from(responder) { + Ok(r) => r, + Err(_) => { + Self::deposit_event(Event::InvalidResponderVersion { origin, query_id }); + return Weight::zero() + }, + }; + if origin != responder { + Self::deposit_event(Event::InvalidResponder { + origin, + query_id, + expected_location: Some(responder), + }); + return Weight::zero() + } + return match maybe_notify { + Some((pallet_index, call_index)) => { + // This is a bit horrible, but we happen to know that the `Call` will + // be built by `(pallet_index: u8, call_index: u8, QueryId, Response)`. + // So we just encode that and then re-encode to a real Call. + let bare = (pallet_index, call_index, query_id, response); + if let Ok(call) = bare.using_encoded(|mut bytes| { + ::RuntimeCall::decode(&mut bytes) + }) { + Queries::::remove(query_id); + let weight = call.get_dispatch_info().weight; + if weight.any_gt(max_weight) { + let e = Event::NotifyOverweight { + query_id, + pallet_index, + call_index, + actual_weight: weight, + max_budgeted_weight: max_weight, + }; + Self::deposit_event(e); + return Weight::zero() + } + let dispatch_origin = Origin::Response(origin).into(); + match call.dispatch(dispatch_origin) { + Ok(post_info) => { + let e = Event::Notified { query_id, pallet_index, call_index }; + Self::deposit_event(e); + post_info.actual_weight + }, + Err(error_and_info) => { + let e = Event::NotifyDispatchError { + query_id, + pallet_index, + call_index, + }; + Self::deposit_event(e); + // Not much to do with the result as it is. It's up to the + // parachain to ensure that the message makes sense. + error_and_info.post_info.actual_weight + }, + } + .unwrap_or(weight) + } else { + let e = + Event::NotifyDecodeFailed { query_id, pallet_index, call_index }; + Self::deposit_event(e); + Weight::zero() + } + }, + None => { + let e = Event::ResponseReady { query_id, response: response.clone() }; + Self::deposit_event(e); + let at = frame_system::Pallet::::current_block_number(); + let response = response.into(); + Queries::::insert(query_id, QueryStatus::Ready { response, at }); + Weight::zero() + }, + } + }, + _ => { + let e = Event::UnexpectedResponse { origin, query_id }; + Self::deposit_event(e); + Weight::zero() + }, + } + } +} + +impl CheckSuspension for Pallet { + fn is_suspended( + _origin: &MultiLocation, + _instructions: &mut [Instruction], + _max_weight: Weight, + _properties: &mut Properties, + ) -> bool { + XcmExecutionSuspended::::get() + } +} + +/// Ensure that the origin `o` represents an XCM (`Transact`) origin. +/// +/// Returns `Ok` with the location of the XCM sender or an `Err` otherwise. +pub fn ensure_xcm(o: OuterOrigin) -> Result +where + OuterOrigin: Into>, +{ + match o.into() { + Ok(Origin::Xcm(location)) => Ok(location), + _ => Err(BadOrigin), + } +} + +/// Ensure that the origin `o` represents an XCM response origin. +/// +/// Returns `Ok` with the location of the responder or an `Err` otherwise. +pub fn ensure_response(o: OuterOrigin) -> Result +where + OuterOrigin: Into>, +{ + match o.into() { + Ok(Origin::Response(location)) => Ok(location), + _ => Err(BadOrigin), + } +} + +/// Filter for `MultiLocation` to find those which represent a strict majority approval of an +/// identified plurality. +/// +/// May reasonably be used with `EnsureXcm`. +pub struct IsMajorityOfBody(PhantomData<(Prefix, Body)>); +impl, Body: Get> Contains + for IsMajorityOfBody +{ + fn contains(l: &MultiLocation) -> bool { + let maybe_suffix = l.match_and_split(&Prefix::get()); + matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part.is_majority()) + } +} + +/// Filter for `MultiLocation` to find those which represent a voice of an identified plurality. +/// +/// May reasonably be used with `EnsureXcm`. +pub struct IsVoiceOfBody(PhantomData<(Prefix, Body)>); +impl, Body: Get> Contains + for IsVoiceOfBody +{ + fn contains(l: &MultiLocation) -> bool { + let maybe_suffix = l.match_and_split(&Prefix::get()); + matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part == &BodyPart::Voice) + } +} + +/// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and filter +/// the `Origin::Xcm` item. +pub struct EnsureXcm(PhantomData); +impl, F: Contains> EnsureOrigin for EnsureXcm +where + O::PalletsOrigin: From + TryInto, +{ + type Success = MultiLocation; + + fn try_origin(outer: O) -> Result { + outer.try_with_caller(|caller| { + caller.try_into().and_then(|o| match o { + Origin::Xcm(location) if F::contains(&location) => Ok(location), + Origin::Xcm(location) => Err(Origin::Xcm(location).into()), + o => Err(o.into()), + }) + }) + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + Ok(O::from(Origin::Xcm(Here.into()))) + } +} + +/// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and filter +/// the `Origin::Response` item. +pub struct EnsureResponse(PhantomData); +impl, F: Contains> EnsureOrigin + for EnsureResponse +where + O::PalletsOrigin: From + TryInto, +{ + type Success = MultiLocation; + + fn try_origin(outer: O) -> Result { + outer.try_with_caller(|caller| { + caller.try_into().and_then(|o| match o { + Origin::Response(responder) => Ok(responder), + o => Err(o.into()), + }) + }) + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + Ok(O::from(Origin::Response(Here.into()))) + } +} + +/// A simple passthrough where we reuse the `MultiLocation`-typed XCM origin as the inner value of +/// this crate's `Origin::Xcm` value. +pub struct XcmPassthrough(PhantomData); +impl> ConvertOrigin + for XcmPassthrough +{ + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + match kind { + OriginKind::Xcm => Ok(crate::Origin::Xcm(origin).into()), + _ => Err(origin), + } + } +} diff --git a/polkadot/xcm/pallet-xcm/src/migration.rs b/polkadot/xcm/pallet-xcm/src/migration.rs new file mode 100644 index 0000000000000000000000000000000000000000..08809f0d2f2e674e35321910d713eed8362b66b7 --- /dev/null +++ b/polkadot/xcm/pallet-xcm/src/migration.rs @@ -0,0 +1,76 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::{Config, Pallet, VersionNotifyTargets}; +use frame_support::{ + pallet_prelude::*, + traits::{OnRuntimeUpgrade, StorageVersion}, + weights::Weight, +}; + +const DEFAULT_PROOF_SIZE: u64 = 64 * 1024; + +pub mod v1 { + use super::*; + use crate::{CurrentMigration, VersionMigrationStage}; + + /// Named with the 'VersionUnchecked'-prefix because although this implements some version + /// checking, the version checking is not complete as it will begin failing after the upgrade is + /// enacted on-chain. + /// + /// Use experimental [`VersionCheckedMigrateToV1`] instead. + pub struct VersionUncheckedMigrateToV1(sp_std::marker::PhantomData); + impl OnRuntimeUpgrade for VersionUncheckedMigrateToV1 { + fn on_runtime_upgrade() -> Weight { + let mut weight = T::DbWeight::get().reads(1); + + if StorageVersion::get::>() != 0 { + log::warn!("skipping v1, should be removed"); + return weight + } + + weight.saturating_accrue(T::DbWeight::get().writes(1)); + CurrentMigration::::put(VersionMigrationStage::default()); + + let translate = |pre: (u64, u64, u32)| -> Option<(u64, Weight, u32)> { + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + let translated = (pre.0, Weight::from_parts(pre.1, DEFAULT_PROOF_SIZE), pre.2); + log::info!("Migrated VersionNotifyTarget {:?} to {:?}", pre, translated); + Some(translated) + }; + + VersionNotifyTargets::::translate_values(translate); + + log::info!("v1 applied successfully"); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + StorageVersion::new(1).put::>(); + weight + } + } + + /// Version checked migration to v1. + /// + /// Wrapped in VersionedRuntimeUpgrade so the pre/post checks don't begin failing after the + /// upgrade is enacted on-chain. + #[cfg(feature = "experimental")] + pub type VersionCheckedMigrateToV1 = frame_support::migrations::VersionedRuntimeUpgrade< + 0, + 1, + VersionUncheckedMigrateToV1, + crate::pallet::Pallet, + ::DbWeight, + >; +} diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..b56b1af82defd2d21a1deb378508df817483f959 --- /dev/null +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -0,0 +1,399 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use codec::Encode; +use frame_support::{ + construct_runtime, parameter_types, + traits::{ConstU32, Everything, Nothing}, + weights::Weight, +}; +use frame_system::EnsureRoot; +use polkadot_parachain::primitives::Id as ParaId; +use polkadot_runtime_parachains::origin; +use sp_core::H256; +use sp_runtime::{traits::IdentityLookup, AccountId32, BuildStorage}; +pub use sp_std::{cell::RefCell, fmt::Debug, marker::PhantomData}; +use xcm::prelude::*; +use xcm_builder::{ + AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, + AllowTopLevelPaidExecutionFrom, Case, ChildParachainAsNative, ChildParachainConvertsVia, + ChildSystemParachainAsSuperuser, CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, + FixedWeightBounds, IsConcrete, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, TakeWeightCredit, +}; +use xcm_executor::XcmExecutor; + +use crate::{self as pallet_xcm, TestWeightInfo}; + +pub type AccountId = AccountId32; +pub type Balance = u128; +type Block = frame_system::mocking::MockBlock; + +#[frame_support::pallet] +pub mod pallet_test_notifier { + use crate::{ensure_response, QueryId}; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use sp_runtime::DispatchResult; + use xcm::latest::prelude::*; + use xcm_executor::traits::QueryHandler; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + crate::Config { + type RuntimeEvent: IsType<::RuntimeEvent> + From>; + type RuntimeOrigin: IsType<::RuntimeOrigin> + + Into::RuntimeOrigin>>; + type RuntimeCall: IsType<::RuntimeCall> + From>; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + QueryPrepared(QueryId), + NotifyQueryPrepared(QueryId), + ResponseReceived(MultiLocation, QueryId, Response), + } + + #[pallet::error] + pub enum Error { + UnexpectedId, + BadAccountFormat, + } + + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight(Weight::from_parts(1_000_000, 1_000_000))] + pub fn prepare_new_query(origin: OriginFor, querier: MultiLocation) -> DispatchResult { + let who = ensure_signed(origin)?; + let id = who + .using_encoded(|mut d| <[u8; 32]>::decode(&mut d)) + .map_err(|_| Error::::BadAccountFormat)?; + let qid = as QueryHandler>::new_query( + Junction::AccountId32 { network: None, id }, + 100u32.into(), + querier, + ); + Self::deposit_event(Event::::QueryPrepared(qid)); + Ok(()) + } + + #[pallet::call_index(1)] + #[pallet::weight(Weight::from_parts(1_000_000, 1_000_000))] + pub fn prepare_new_notify_query( + origin: OriginFor, + querier: MultiLocation, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + let id = who + .using_encoded(|mut d| <[u8; 32]>::decode(&mut d)) + .map_err(|_| Error::::BadAccountFormat)?; + let call = + Call::::notification_received { query_id: 0, response: Default::default() }; + let qid = crate::Pallet::::new_notify_query( + Junction::AccountId32 { network: None, id }, + ::RuntimeCall::from(call), + 100u32.into(), + querier, + ); + Self::deposit_event(Event::::NotifyQueryPrepared(qid)); + Ok(()) + } + + #[pallet::call_index(2)] + #[pallet::weight(Weight::from_parts(1_000_000, 1_000_000))] + pub fn notification_received( + origin: OriginFor, + query_id: QueryId, + response: Response, + ) -> DispatchResult { + let responder = ensure_response(::RuntimeOrigin::from(origin))?; + Self::deposit_event(Event::::ResponseReceived(responder, query_id, response)); + Ok(()) + } + } +} + +construct_runtime!( + pub enum Test + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + ParasOrigin: origin::{Pallet, Origin}, + XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config}, + TestNotifier: pallet_test_notifier::{Pallet, Call, Event}, + } +); + +thread_local! { + pub static SENT_XCM: RefCell)>> = RefCell::new(Vec::new()); +} +pub(crate) fn sent_xcm() -> Vec<(MultiLocation, Xcm<()>)> { + SENT_XCM.with(|q| (*q.borrow()).clone()) +} +pub(crate) fn take_sent_xcm() -> Vec<(MultiLocation, Xcm<()>)> { + SENT_XCM.with(|q| { + let mut r = Vec::new(); + std::mem::swap(&mut r, &mut *q.borrow_mut()); + r + }) +} +/// Sender that never returns error, always sends +pub struct TestSendXcm; +impl SendXcm for TestSendXcm { + type Ticket = (MultiLocation, Xcm<()>); + fn validate( + dest: &mut Option, + msg: &mut Option>, + ) -> SendResult<(MultiLocation, Xcm<()>)> { + let pair = (dest.take().unwrap(), msg.take().unwrap()); + Ok((pair, MultiAssets::new())) + } + fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + let hash = fake_message_hash(&pair.1); + SENT_XCM.with(|q| q.borrow_mut().push(pair)); + Ok(hash) + } +} +/// Sender that returns error if `X8` junction and stops routing +pub struct TestSendXcmErrX8; +impl SendXcm for TestSendXcmErrX8 { + type Ticket = (MultiLocation, Xcm<()>); + fn validate( + dest: &mut Option, + msg: &mut Option>, + ) -> SendResult<(MultiLocation, Xcm<()>)> { + let (dest, msg) = (dest.take().unwrap(), msg.take().unwrap()); + if dest.len() == 8 { + Err(SendError::Transport("Destination location full")) + } else { + Ok(((dest, msg), MultiAssets::new())) + } + } + fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + let hash = fake_message_hash(&pair.1); + SENT_XCM.with(|q| q.borrow_mut().push(pair)); + Ok(hash) + } +} + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Test { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = Everything; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub ExistentialDeposit: Balance = 1; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Test { + type MaxLocks = MaxLocks; + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +parameter_types! { + pub const RelayLocation: MultiLocation = Here.into_location(); + pub const AnyNetwork: Option = None; + pub UniversalLocation: InteriorMultiLocation = Here; + pub UnitWeightCost: u64 = 1_000; +} + +pub type SovereignAccountOf = + (ChildParachainConvertsVia, AccountId32Aliases); + +pub type LocalAssetTransactor = + XcmCurrencyAdapter, SovereignAccountOf, AccountId, ()>; + +type LocalOriginConverter = ( + SovereignSignedViaLocation, + ChildParachainAsNative, + SignedAccountId32AsNative, + ChildSystemParachainAsSuperuser, +); + +parameter_types! { + pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); + pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (Concrete(RelayLocation::get()), 1, 1); + pub TrustedAssets: (MultiAssetFilter, MultiLocation) = (All.into(), Here.into()); + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +pub type Barrier = ( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom, + AllowKnownQueryResponses, + AllowSubscriptionsFrom, +); + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = TestSendXcm; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = LocalOriginConverter; + type IsReserve = (); + type IsTeleporter = Case; + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = FixedRateOfFungible; + type ResponseHandler = XcmPallet; + type AssetTrap = XcmPallet; + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = XcmPallet; + type SubscriptionService = XcmPallet; + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; + type Aliasers = Nothing; +} + +pub type LocalOriginToLocation = SignedToAccountId32; + +parameter_types! { + pub static AdvertisedXcmVersion: pallet_xcm::XcmVersion = 3; +} + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parachain(1000).into()); +} + +impl pallet_xcm::Config for Test { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = (TestSendXcmErrX8, TestSendXcm); + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = AdvertisedXcmVersion; + type TrustedLockers = (); + type SovereignAccountOf = AccountId32Aliases<(), AccountId32>; + type Currency = Balances; + type CurrencyMatcher = IsConcrete; + type MaxLockers = frame_support::traits::ConstU32<8>; + type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = TestWeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} + +impl origin::Config for Test {} + +impl pallet_test_notifier::Config for Test { + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; +} + +pub(crate) fn last_event() -> RuntimeEvent { + System::events().pop().expect("RuntimeEvent expected").event +} + +pub(crate) fn last_events(n: usize) -> Vec { + System::events().into_iter().map(|e| e.event).rev().take(n).rev().collect() +} + +pub(crate) fn buy_execution(fees: impl Into) -> Instruction { + use xcm::latest::prelude::*; + BuyExecution { fees: fees.into(), weight_limit: Unlimited } +} + +pub(crate) fn buy_limited_execution( + fees: impl Into, + weight: Weight, +) -> Instruction { + use xcm::latest::prelude::*; + BuyExecution { fees: fees.into(), weight_limit: Limited(weight) } +} + +pub(crate) fn new_test_ext_with_balances( + balances: Vec<(AccountId, Balance)>, +) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + pallet_balances::GenesisConfig:: { balances } + .assimilate_storage(&mut t) + .unwrap(); + + pallet_xcm::GenesisConfig:: { safe_xcm_version: Some(2), ..Default::default() } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +pub(crate) fn fake_message_hash(message: &Xcm) -> XcmHash { + message.using_encoded(sp_io::hashing::blake2_256) +} diff --git a/polkadot/xcm/pallet-xcm/src/tests.rs b/polkadot/xcm/pallet-xcm/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..6ff9f1d893c890bed05ee6e84489126a90c07c8b --- /dev/null +++ b/polkadot/xcm/pallet-xcm/src/tests.rs @@ -0,0 +1,1216 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::{ + mock::*, AssetTraps, CurrentMigration, Error, LatestVersionedMultiLocation, Queries, + QueryStatus, VersionDiscoveryQueue, VersionMigrationStage, VersionNotifiers, + VersionNotifyTargets, +}; +use frame_support::{ + assert_noop, assert_ok, + traits::{Currency, Hooks}, + weights::Weight, +}; +use polkadot_parachain::primitives::Id as ParaId; +use sp_runtime::traits::{AccountIdConversion, BlakeTwo256, Hash}; +use xcm::{latest::QueryResponseInfo, prelude::*}; +use xcm_builder::AllowKnownQueryResponses; +use xcm_executor::{ + traits::{Properties, QueryHandler, QueryResponseStatus, ShouldExecute}, + XcmExecutor, +}; + +const ALICE: AccountId = AccountId::new([0u8; 32]); +const BOB: AccountId = AccountId::new([1u8; 32]); +const PARA_ID: u32 = 2000; +const INITIAL_BALANCE: u128 = 100; +const SEND_AMOUNT: u128 = 10; + +#[test] +fn report_outcome_notify_works() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let mut message = + Xcm(vec![TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }]); + let call = pallet_test_notifier::Call::notification_received { + query_id: 0, + response: Default::default(), + }; + let notify = RuntimeCall::TestNotifier(call); + new_test_ext_with_balances(balances).execute_with(|| { + XcmPallet::report_outcome_notify( + &mut message, + Parachain(PARA_ID).into_location(), + notify, + 100, + ) + .unwrap(); + assert_eq!( + message, + Xcm(vec![ + SetAppendix(Xcm(vec![ReportError(QueryResponseInfo { + destination: Parent.into(), + query_id: 0, + max_weight: Weight::from_parts(1_000_000, 1_000_000), + })])), + TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }, + ]) + ); + let querier: MultiLocation = Here.into(); + let status = QueryStatus::Pending { + responder: MultiLocation::from(Parachain(PARA_ID)).into(), + maybe_notify: Some((4, 2)), + timeout: 100, + maybe_match_querier: Some(querier.into()), + }; + assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); + + let message = Xcm(vec![QueryResponse { + query_id: 0, + response: Response::ExecutionResult(None), + max_weight: Weight::from_parts(1_000_000, 1_000_000), + querier: Some(querier), + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(PARA_ID), + message, + hash, + Weight::from_parts(1_000_000_000, 1_000_000_000), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!( + last_events(2), + vec![ + RuntimeEvent::TestNotifier(pallet_test_notifier::Event::ResponseReceived( + Parachain(PARA_ID).into(), + 0, + Response::ExecutionResult(None), + )), + RuntimeEvent::XcmPallet(crate::Event::Notified { + query_id: 0, + pallet_index: 4, + call_index: 2 + }), + ] + ); + assert_eq!(crate::Queries::::iter().collect::>(), vec![]); + }); +} + +#[test] +fn report_outcome_works() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let mut message = + Xcm(vec![TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }]); + new_test_ext_with_balances(balances).execute_with(|| { + XcmPallet::report_outcome(&mut message, Parachain(PARA_ID).into_location(), 100).unwrap(); + assert_eq!( + message, + Xcm(vec![ + SetAppendix(Xcm(vec![ReportError(QueryResponseInfo { + destination: Parent.into(), + query_id: 0, + max_weight: Weight::zero(), + })])), + TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }, + ]) + ); + let querier: MultiLocation = Here.into(); + let status = QueryStatus::Pending { + responder: MultiLocation::from(Parachain(PARA_ID)).into(), + maybe_notify: None, + timeout: 100, + maybe_match_querier: Some(querier.into()), + }; + assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); + + let message = Xcm(vec![QueryResponse { + query_id: 0, + response: Response::ExecutionResult(None), + max_weight: Weight::zero(), + querier: Some(querier), + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(PARA_ID), + message, + hash, + Weight::from_parts(1_000_000_000, 1_000_000_000), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::ResponseReady { + query_id: 0, + response: Response::ExecutionResult(None), + }) + ); + + let response = + QueryResponseStatus::Ready { response: Response::ExecutionResult(None), at: 1 }; + assert_eq!(XcmPallet::take_response(0), response); + }); +} + +#[test] +fn custom_querier_works() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + new_test_ext_with_balances(balances).execute_with(|| { + let querier: MultiLocation = + (Parent, AccountId32 { network: None, id: ALICE.into() }).into(); + + let r = TestNotifier::prepare_new_query(RuntimeOrigin::signed(ALICE), querier); + assert_eq!(r, Ok(())); + let status = QueryStatus::Pending { + responder: MultiLocation::from(AccountId32 { network: None, id: ALICE.into() }).into(), + maybe_notify: None, + timeout: 100, + maybe_match_querier: Some(querier.into()), + }; + assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); + + // Supplying no querier when one is expected will fail + let message = Xcm(vec![QueryResponse { + query_id: 0, + response: Response::ExecutionResult(None), + max_weight: Weight::zero(), + querier: None, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm_in_credit( + AccountId32 { network: None, id: ALICE.into() }, + message, + hash, + Weight::from_parts(1_000_000_000, 1_000_000_000), + Weight::from_parts(1_000, 1_000), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier { + origin: AccountId32 { network: None, id: ALICE.into() }.into(), + query_id: 0, + expected_querier: querier, + maybe_actual_querier: None, + }), + ); + + // Supplying the wrong querier will also fail + let message = Xcm(vec![QueryResponse { + query_id: 0, + response: Response::ExecutionResult(None), + max_weight: Weight::zero(), + querier: Some(MultiLocation::here()), + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm_in_credit( + AccountId32 { network: None, id: ALICE.into() }, + message, + hash, + Weight::from_parts(1_000_000_000, 1_000_000_000), + Weight::from_parts(1_000, 1_000), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier { + origin: AccountId32 { network: None, id: ALICE.into() }.into(), + query_id: 0, + expected_querier: querier, + maybe_actual_querier: Some(MultiLocation::here()), + }), + ); + + // Multiple failures should not have changed the query state + let message = Xcm(vec![QueryResponse { + query_id: 0, + response: Response::ExecutionResult(None), + max_weight: Weight::zero(), + querier: Some(querier), + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + AccountId32 { network: None, id: ALICE.into() }, + message, + hash, + Weight::from_parts(1_000_000_000, 1_000_000_000), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::ResponseReady { + query_id: 0, + response: Response::ExecutionResult(None), + }) + ); + + let response = + QueryResponseStatus::Ready { response: Response::ExecutionResult(None), at: 1 }; + assert_eq!(XcmPallet::take_response(0), response); + }); +} + +/// Test sending an `XCM` message (`XCM::ReserveAssetDeposit`) +/// +/// Asserts that the expected message is sent and the event is emitted +#[test] +fn send_works() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + new_test_ext_with_balances(balances).execute_with(|| { + let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let message = Xcm(vec![ + ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), + ClearOrigin, + buy_execution((Parent, SEND_AMOUNT)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: sender }, + ]); + + let versioned_dest = Box::new(RelayLocation::get().into()); + let versioned_message = Box::new(VersionedXcm::from(message.clone())); + assert_ok!(XcmPallet::send( + RuntimeOrigin::signed(ALICE), + versioned_dest, + versioned_message + )); + let sent_message = Xcm(Some(DescendOrigin(sender.try_into().unwrap())) + .into_iter() + .chain(message.0.clone().into_iter()) + .collect()); + let id = fake_message_hash(&sent_message); + assert_eq!(sent_xcm(), vec![(Here.into(), sent_message)]); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::Sent { + origin: sender, + destination: RelayLocation::get(), + message, + message_id: id, + }) + ); + }); +} + +/// Test that sending an `XCM` message fails when the `XcmRouter` blocks the +/// matching message format +/// +/// Asserts that `send` fails with `Error::SendFailure` +#[test] +fn send_fails_when_xcm_router_blocks() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + new_test_ext_with_balances(balances).execute_with(|| { + let sender: MultiLocation = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let message = Xcm(vec![ + ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), + buy_execution((Parent, SEND_AMOUNT)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: sender }, + ]); + assert_noop!( + XcmPallet::send( + RuntimeOrigin::signed(ALICE), + Box::new(MultiLocation::ancestor(8).into()), + Box::new(VersionedXcm::from(message.clone())), + ), + crate::Error::::SendFailure + ); + }); +} + +/// Test `teleport_assets` +/// +/// Asserts that the sender's balance is decreased as a result of execution of +/// local effects. +#[test] +fn teleport_assets_works() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = BaseXcmWeight::get() * 3; + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + let dest: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + assert_ok!(XcmPallet::teleport_assets( + RuntimeOrigin::signed(ALICE), + Box::new(RelayLocation::get().into()), + Box::new(dest.into()), + Box::new((Here, SEND_AMOUNT).into()), + 0, + )); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT); + assert_eq!( + sent_xcm(), + vec![( + RelayLocation::get().into(), + Xcm(vec![ + ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()), + ClearOrigin, + buy_limited_execution((Here, SEND_AMOUNT), Weight::from_parts(4000, 4000)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + ]), + )] + ); + let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1); + let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap(); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + ); + }); +} + +/// Test `limited_teleport_assets` +/// +/// Asserts that the sender's balance is decreased as a result of execution of +/// local effects. +#[test] +fn limited_teleport_assets_works() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = BaseXcmWeight::get() * 3; + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + let dest: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + assert_ok!(XcmPallet::limited_teleport_assets( + RuntimeOrigin::signed(ALICE), + Box::new(RelayLocation::get().into()), + Box::new(dest.into()), + Box::new((Here, SEND_AMOUNT).into()), + 0, + WeightLimit::Limited(Weight::from_parts(5000, 5000)), + )); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT); + assert_eq!( + sent_xcm(), + vec![( + RelayLocation::get().into(), + Xcm(vec![ + ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()), + ClearOrigin, + buy_limited_execution((Here, SEND_AMOUNT), Weight::from_parts(5000, 5000)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + ]), + )] + ); + let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1); + let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap(); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + ); + }); +} + +/// Test `limited_teleport_assets` with unlimited weight +/// +/// Asserts that the sender's balance is decreased as a result of execution of +/// local effects. +#[test] +fn unlimited_teleport_assets_works() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = BaseXcmWeight::get() * 3; + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + let dest: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + assert_ok!(XcmPallet::limited_teleport_assets( + RuntimeOrigin::signed(ALICE), + Box::new(RelayLocation::get().into()), + Box::new(dest.into()), + Box::new((Here, SEND_AMOUNT).into()), + 0, + WeightLimit::Unlimited, + )); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT); + assert_eq!( + sent_xcm(), + vec![( + RelayLocation::get().into(), + Xcm(vec![ + ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()), + ClearOrigin, + buy_execution((Here, SEND_AMOUNT)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + ]), + )] + ); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + ); + }); +} + +/// Test `reserve_transfer_assets` +/// +/// Asserts that the sender's balance is decreased and the beneficiary's balance +/// is increased. Verifies the correct message is sent and event is emitted. +#[test] +fn reserve_transfer_assets_works() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = BaseXcmWeight::get() * 2; + let dest: MultiLocation = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + assert_ok!(XcmPallet::reserve_transfer_assets( + RuntimeOrigin::signed(ALICE), + Box::new(Parachain(PARA_ID).into()), + Box::new(dest.into()), + Box::new((Here, SEND_AMOUNT).into()), + 0, + )); + // Alice spent amount + assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT); + // Destination account (parachain account) has amount + let para_acc: AccountId = ParaId::from(PARA_ID).into_account_truncating(); + assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE + SEND_AMOUNT); + assert_eq!( + sent_xcm(), + vec![( + Parachain(PARA_ID).into(), + Xcm(vec![ + ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), + ClearOrigin, + buy_limited_execution((Parent, SEND_AMOUNT), Weight::from_parts(4000, 4000)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + ]), + )] + ); + let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1); + let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap(); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + ); + }); +} + +/// Test `limited_reserve_transfer_assets` +/// +/// Asserts that the sender's balance is decreased and the beneficiary's balance +/// is increased. Verifies the correct message is sent and event is emitted. +#[test] +fn limited_reserve_transfer_assets_works() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = BaseXcmWeight::get() * 2; + let dest: MultiLocation = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + assert_ok!(XcmPallet::limited_reserve_transfer_assets( + RuntimeOrigin::signed(ALICE), + Box::new(Parachain(PARA_ID).into()), + Box::new(dest.into()), + Box::new((Here, SEND_AMOUNT).into()), + 0, + WeightLimit::Limited(Weight::from_parts(5000, 5000)), + )); + // Alice spent amount + assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT); + // Destination account (parachain account) has amount + let para_acc: AccountId = ParaId::from(PARA_ID).into_account_truncating(); + assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE + SEND_AMOUNT); + assert_eq!( + sent_xcm(), + vec![( + Parachain(PARA_ID).into(), + Xcm(vec![ + ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), + ClearOrigin, + buy_limited_execution((Parent, SEND_AMOUNT), Weight::from_parts(5000, 5000)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + ]), + )] + ); + let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1); + let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap(); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + ); + }); +} + +/// Test `limited_reserve_transfer_assets` with unlimited weight purchasing +/// +/// Asserts that the sender's balance is decreased and the beneficiary's balance +/// is increased. Verifies the correct message is sent and event is emitted. +#[test] +fn unlimited_reserve_transfer_assets_works() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = BaseXcmWeight::get() * 2; + let dest: MultiLocation = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + assert_ok!(XcmPallet::limited_reserve_transfer_assets( + RuntimeOrigin::signed(ALICE), + Box::new(Parachain(PARA_ID).into()), + Box::new(dest.into()), + Box::new((Here, SEND_AMOUNT).into()), + 0, + WeightLimit::Unlimited, + )); + // Alice spent amount + assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT); + // Destination account (parachain account) has amount + let para_acc: AccountId = ParaId::from(PARA_ID).into_account_truncating(); + assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE + SEND_AMOUNT); + assert_eq!( + sent_xcm(), + vec![( + Parachain(PARA_ID).into(), + Xcm(vec![ + ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), + ClearOrigin, + buy_execution((Parent, SEND_AMOUNT)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + ]), + )] + ); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + ); + }); +} + +/// Test local execution of XCM +/// +/// Asserts that the sender's balance is decreased and the beneficiary's balance +/// is increased. Verifies the expected event is emitted. +#[test] +fn execute_withdraw_to_deposit_works() { + let balances = vec![ + (ALICE, INITIAL_BALANCE), + (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), + ]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = BaseXcmWeight::get() * 3; + let dest: MultiLocation = Junction::AccountId32 { network: None, id: BOB.into() }.into(); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + assert_ok!(XcmPallet::execute( + RuntimeOrigin::signed(ALICE), + Box::new(VersionedXcm::from(Xcm(vec![ + WithdrawAsset((Here, SEND_AMOUNT).into()), + buy_execution((Here, SEND_AMOUNT)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + ]))), + weight + )); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT); + assert_eq!(Balances::total_balance(&BOB), SEND_AMOUNT); + assert_eq!( + last_event(), + RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + ); + }); +} + +/// Test drop/claim assets. +#[test] +fn trapped_assets_can_be_claimed() { + let balances = vec![(ALICE, INITIAL_BALANCE), (BOB, INITIAL_BALANCE)]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = BaseXcmWeight::get() * 6; + let dest: MultiLocation = Junction::AccountId32 { network: None, id: BOB.into() }.into(); + + assert_ok!(XcmPallet::execute( + RuntimeOrigin::signed(ALICE), + Box::new(VersionedXcm::from(Xcm(vec![ + WithdrawAsset((Here, SEND_AMOUNT).into()), + buy_execution((Here, SEND_AMOUNT)), + // Don't propagated the error into the result. + SetErrorHandler(Xcm(vec![ClearError])), + // This will make an error. + Trap(0), + // This would succeed, but we never get to it. + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + ]))), + weight + )); + let source: MultiLocation = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let trapped = AssetTraps::::iter().collect::>(); + let vma = VersionedMultiAssets::from(MultiAssets::from((Here, SEND_AMOUNT))); + let hash = BlakeTwo256::hash_of(&(source, vma.clone())); + assert_eq!( + last_events(2), + vec![ + RuntimeEvent::XcmPallet(crate::Event::AssetsTrapped { + hash, + origin: source, + assets: vma + }), + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete(BaseXcmWeight::get() * 5) + }), + ] + ); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT); + assert_eq!(Balances::total_balance(&BOB), INITIAL_BALANCE); + + let expected = vec![(hash, 1u32)]; + assert_eq!(trapped, expected); + + let weight = BaseXcmWeight::get() * 3; + assert_ok!(XcmPallet::execute( + RuntimeOrigin::signed(ALICE), + Box::new(VersionedXcm::from(Xcm(vec![ + ClaimAsset { assets: (Here, SEND_AMOUNT).into(), ticket: Here.into() }, + buy_execution((Here, SEND_AMOUNT)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + ]))), + weight + )); + + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT); + assert_eq!(Balances::total_balance(&BOB), INITIAL_BALANCE + SEND_AMOUNT); + assert_eq!(AssetTraps::::iter().collect::>(), vec![]); + + let weight = BaseXcmWeight::get() * 3; + assert_ok!(XcmPallet::execute( + RuntimeOrigin::signed(ALICE), + Box::new(VersionedXcm::from(Xcm(vec![ + ClaimAsset { assets: (Here, SEND_AMOUNT).into(), ticket: Here.into() }, + buy_execution((Here, SEND_AMOUNT)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + ]))), + weight + )); + let outcome = Outcome::Incomplete(BaseXcmWeight::get(), XcmError::UnknownClaim); + assert_eq!(last_event(), RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome })); + }); +} + +#[test] +fn fake_latest_versioned_multilocation_works() { + use codec::Encode; + let remote: MultiLocation = Parachain(1000).into(); + let versioned_remote = LatestVersionedMultiLocation(&remote); + assert_eq!(versioned_remote.encode(), remote.into_versioned().encode()); +} + +#[test] +fn basic_subscription_works() { + new_test_ext_with_balances(vec![]).execute_with(|| { + let remote: MultiLocation = Parachain(1000).into(); + assert_ok!(XcmPallet::force_subscribe_version_notify( + RuntimeOrigin::root(), + Box::new(remote.into()), + )); + + assert_eq!( + Queries::::iter().collect::>(), + vec![(0, QueryStatus::VersionNotifier { origin: remote.into(), is_active: false })] + ); + assert_eq!( + VersionNotifiers::::iter().collect::>(), + vec![(XCM_VERSION, remote.into(), 0)] + ); + + assert_eq!( + take_sent_xcm(), + vec![( + remote, + Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]), + ),] + ); + + let weight = BaseXcmWeight::get(); + let mut message = Xcm::<()>(vec![ + // Remote supports XCM v2 + QueryResponse { + query_id: 0, + max_weight: Weight::zero(), + response: Response::Version(1), + querier: None, + }, + ]); + assert_ok!(AllowKnownQueryResponses::::should_execute( + &remote, + message.inner_mut(), + weight, + &mut Properties { weight_credit: Weight::zero(), message_id: None }, + )); + }); +} + +#[test] +fn subscriptions_increment_id() { + new_test_ext_with_balances(vec![]).execute_with(|| { + let remote: MultiLocation = Parachain(1000).into(); + assert_ok!(XcmPallet::force_subscribe_version_notify( + RuntimeOrigin::root(), + Box::new(remote.into()), + )); + + let remote2: MultiLocation = Parachain(1001).into(); + assert_ok!(XcmPallet::force_subscribe_version_notify( + RuntimeOrigin::root(), + Box::new(remote2.into()), + )); + + assert_eq!( + take_sent_xcm(), + vec![ + ( + remote, + Xcm(vec![SubscribeVersion { + query_id: 0, + max_response_weight: Weight::zero() + }]), + ), + ( + remote2, + Xcm(vec![SubscribeVersion { + query_id: 1, + max_response_weight: Weight::zero() + }]), + ), + ] + ); + }); +} + +#[test] +fn double_subscription_fails() { + new_test_ext_with_balances(vec![]).execute_with(|| { + let remote: MultiLocation = Parachain(1000).into(); + assert_ok!(XcmPallet::force_subscribe_version_notify( + RuntimeOrigin::root(), + Box::new(remote.into()), + )); + assert_noop!( + XcmPallet::force_subscribe_version_notify( + RuntimeOrigin::root(), + Box::new(remote.into()) + ), + Error::::AlreadySubscribed, + ); + }) +} + +#[test] +fn unsubscribe_works() { + new_test_ext_with_balances(vec![]).execute_with(|| { + let remote: MultiLocation = Parachain(1000).into(); + assert_ok!(XcmPallet::force_subscribe_version_notify( + RuntimeOrigin::root(), + Box::new(remote.into()), + )); + assert_ok!(XcmPallet::force_unsubscribe_version_notify( + RuntimeOrigin::root(), + Box::new(remote.into()) + )); + assert_noop!( + XcmPallet::force_unsubscribe_version_notify( + RuntimeOrigin::root(), + Box::new(remote.into()) + ), + Error::::NoSubscription, + ); + + assert_eq!( + take_sent_xcm(), + vec![ + ( + remote, + Xcm(vec![SubscribeVersion { + query_id: 0, + max_response_weight: Weight::zero() + }]), + ), + (remote, Xcm(vec![UnsubscribeVersion]),), + ] + ); + }); +} + +/// Parachain 1000 is asking us for a version subscription. +#[test] +fn subscription_side_works() { + new_test_ext_with_balances(vec![]).execute_with(|| { + AdvertisedXcmVersion::set(1); + + let remote: MultiLocation = Parachain(1000).into(); + let weight = BaseXcmWeight::get(); + let message = + Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); + assert_eq!(r, Outcome::Complete(weight)); + + let instr = QueryResponse { + query_id: 0, + max_weight: Weight::zero(), + response: Response::Version(1), + querier: None, + }; + assert_eq!(take_sent_xcm(), vec![(remote, Xcm(vec![instr]))]); + + // A runtime upgrade which doesn't alter the version sends no notifications. + CurrentMigration::::put(VersionMigrationStage::default()); + XcmPallet::on_initialize(1); + assert_eq!(take_sent_xcm(), vec![]); + + // New version. + AdvertisedXcmVersion::set(2); + + // A runtime upgrade which alters the version does send notifications. + CurrentMigration::::put(VersionMigrationStage::default()); + XcmPallet::on_initialize(2); + let instr = QueryResponse { + query_id: 0, + max_weight: Weight::zero(), + response: Response::Version(2), + querier: None, + }; + assert_eq!(take_sent_xcm(), vec![(remote, Xcm(vec![instr]))]); + }); +} + +#[test] +fn subscription_side_upgrades_work_with_notify() { + new_test_ext_with_balances(vec![]).execute_with(|| { + AdvertisedXcmVersion::set(1); + + // An entry from a previous runtime with v2 XCM. + let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 2)); + let v3_location = Parachain(1003).into_versioned(); + VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 2)); + + // New version. + AdvertisedXcmVersion::set(3); + + // A runtime upgrade which alters the version does send notifications. + CurrentMigration::::put(VersionMigrationStage::default()); + XcmPallet::on_initialize(1); + + let instr1 = QueryResponse { + query_id: 70, + max_weight: Weight::zero(), + response: Response::Version(3), + querier: None, + }; + let instr3 = QueryResponse { + query_id: 72, + max_weight: Weight::zero(), + response: Response::Version(3), + querier: None, + }; + let mut sent = take_sent_xcm(); + sent.sort_by_key(|k| match (k.1).0[0] { + QueryResponse { query_id: q, .. } => q, + _ => 0, + }); + assert_eq!( + sent, + vec![ + (Parachain(1001).into(), Xcm(vec![instr1])), + (Parachain(1003).into(), Xcm(vec![instr3])), + ] + ); + + let mut contents = VersionNotifyTargets::::iter().collect::>(); + contents.sort_by_key(|k| k.2 .0); + assert_eq!( + contents, + vec![ + (XCM_VERSION, Parachain(1001).into_versioned(), (70, Weight::zero(), 3)), + (XCM_VERSION, Parachain(1003).into_versioned(), (72, Weight::zero(), 3)), + ] + ); + }); +} + +#[test] +fn subscription_side_upgrades_work_without_notify() { + new_test_ext_with_balances(vec![]).execute_with(|| { + // An entry from a previous runtime with v2 XCM. + let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 2)); + let v3_location = Parachain(1003).into_versioned(); + VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 2)); + + // A runtime upgrade which alters the version does send notifications. + CurrentMigration::::put(VersionMigrationStage::default()); + XcmPallet::on_initialize(1); + + let mut contents = VersionNotifyTargets::::iter().collect::>(); + contents.sort_by_key(|k| k.2 .0); + assert_eq!( + contents, + vec![ + (XCM_VERSION, Parachain(1001).into_versioned(), (70, Weight::zero(), 3)), + (XCM_VERSION, Parachain(1003).into_versioned(), (72, Weight::zero(), 3)), + ] + ); + }); +} + +#[test] +fn subscriber_side_subscription_works() { + new_test_ext_with_balances(vec![]).execute_with(|| { + let remote: MultiLocation = Parachain(1000).into(); + assert_ok!(XcmPallet::force_subscribe_version_notify( + RuntimeOrigin::root(), + Box::new(remote.into()), + )); + take_sent_xcm(); + + // Assume subscription target is working ok. + + let weight = BaseXcmWeight::get(); + let message = Xcm(vec![ + // Remote supports XCM v2 + QueryResponse { + query_id: 0, + max_weight: Weight::zero(), + response: Response::Version(1), + querier: None, + }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); + assert_eq!(r, Outcome::Complete(weight)); + assert_eq!(take_sent_xcm(), vec![]); + + // This message cannot be sent to a v2 remote. + let v2_msg = xcm::v2::Xcm::<()>(vec![xcm::v2::Instruction::Trap(0)]); + assert_eq!(XcmPallet::wrap_version(&remote, v2_msg.clone()), Err(())); + + let message = Xcm(vec![ + // Remote upgraded to XCM v2 + QueryResponse { + query_id: 0, + max_weight: Weight::zero(), + response: Response::Version(2), + querier: None, + }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); + assert_eq!(r, Outcome::Complete(weight)); + + // This message can now be sent to remote as it's v2. + assert_eq!( + XcmPallet::wrap_version(&remote, v2_msg.clone()), + Ok(VersionedXcm::from(v2_msg)) + ); + }); +} + +/// We should auto-subscribe when we don't know the remote's version. +#[test] +fn auto_subscription_works() { + new_test_ext_with_balances(vec![]).execute_with(|| { + let remote_v2: MultiLocation = Parachain(1000).into(); + let remote_v3: MultiLocation = Parachain(1001).into(); + + assert_ok!(XcmPallet::force_default_xcm_version(RuntimeOrigin::root(), Some(2))); + + // Wrapping a version for a destination we don't know elicits a subscription. + let msg_v2 = xcm::v2::Xcm::<()>(vec![xcm::v2::Instruction::Trap(0)]); + let msg_v3 = xcm::v3::Xcm::<()>(vec![xcm::v3::Instruction::ClearTopic]); + assert_eq!( + XcmPallet::wrap_version(&remote_v2, msg_v2.clone()), + Ok(VersionedXcm::from(msg_v2.clone())), + ); + assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v3.clone()), Err(())); + + let expected = vec![(remote_v2.into(), 2)]; + assert_eq!(VersionDiscoveryQueue::::get().into_inner(), expected); + + assert_eq!( + XcmPallet::wrap_version(&remote_v3, msg_v2.clone()), + Ok(VersionedXcm::from(msg_v2.clone())), + ); + assert_eq!(XcmPallet::wrap_version(&remote_v3, msg_v3.clone()), Err(())); + + let expected = vec![(remote_v2.into(), 2), (remote_v3.into(), 2)]; + assert_eq!(VersionDiscoveryQueue::::get().into_inner(), expected); + + XcmPallet::on_initialize(1); + assert_eq!( + take_sent_xcm(), + vec![( + remote_v3, + Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]), + )] + ); + + // Assume remote_v3 is working ok and XCM version 3. + + let weight = BaseXcmWeight::get(); + let message = Xcm(vec![ + // Remote supports XCM v3 + QueryResponse { + query_id: 0, + max_weight: Weight::zero(), + response: Response::Version(3), + querier: None, + }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm(remote_v3, message, hash, weight); + assert_eq!(r, Outcome::Complete(weight)); + + // V2 messages can be sent to remote_v3 under XCM v3. + assert_eq!( + XcmPallet::wrap_version(&remote_v3, msg_v2.clone()), + Ok(VersionedXcm::from(msg_v2.clone()).into_version(3).unwrap()), + ); + // This message can now be sent to remote_v3 as it's v3. + assert_eq!( + XcmPallet::wrap_version(&remote_v3, msg_v3.clone()), + Ok(VersionedXcm::from(msg_v3.clone())) + ); + + XcmPallet::on_initialize(2); + assert_eq!( + take_sent_xcm(), + vec![( + remote_v2, + Xcm(vec![SubscribeVersion { query_id: 1, max_response_weight: Weight::zero() }]), + )] + ); + + // Assume remote_v2 is working ok and XCM version 2. + + let weight = BaseXcmWeight::get(); + let message = Xcm(vec![ + // Remote supports XCM v2 + QueryResponse { + query_id: 1, + max_weight: Weight::zero(), + response: Response::Version(2), + querier: None, + }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm(remote_v2, message, hash, weight); + assert_eq!(r, Outcome::Complete(weight)); + + // v3 messages cannot be sent to remote_v2... + assert_eq!( + XcmPallet::wrap_version(&remote_v2, msg_v2.clone()), + Ok(VersionedXcm::V2(msg_v2)) + ); + assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v3.clone()), Err(())); + }) +} + +#[test] +fn subscription_side_upgrades_work_with_multistage_notify() { + new_test_ext_with_balances(vec![]).execute_with(|| { + AdvertisedXcmVersion::set(1); + + // An entry from a previous runtime with v0 XCM. + let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 1)); + let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1002).into()); + VersionNotifyTargets::::insert(2, v2_location, (71, Weight::zero(), 1)); + let v3_location = Parachain(1003).into_versioned(); + VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 1)); + + // New version. + AdvertisedXcmVersion::set(3); + + // A runtime upgrade which alters the version does send notifications. + CurrentMigration::::put(VersionMigrationStage::default()); + let mut maybe_migration = CurrentMigration::::take(); + let mut counter = 0; + while let Some(migration) = maybe_migration.take() { + counter += 1; + let (_, m) = XcmPallet::check_xcm_version_change(migration, Weight::zero()); + maybe_migration = m; + } + assert_eq!(counter, 4); + + let instr1 = QueryResponse { + query_id: 70, + max_weight: Weight::zero(), + response: Response::Version(3), + querier: None, + }; + let instr2 = QueryResponse { + query_id: 71, + max_weight: Weight::zero(), + response: Response::Version(3), + querier: None, + }; + let instr3 = QueryResponse { + query_id: 72, + max_weight: Weight::zero(), + response: Response::Version(3), + querier: None, + }; + let mut sent = take_sent_xcm(); + sent.sort_by_key(|k| match (k.1).0[0] { + QueryResponse { query_id: q, .. } => q, + _ => 0, + }); + assert_eq!( + sent, + vec![ + (Parachain(1001).into(), Xcm(vec![instr1])), + (Parachain(1002).into(), Xcm(vec![instr2])), + (Parachain(1003).into(), Xcm(vec![instr3])), + ] + ); + + let mut contents = VersionNotifyTargets::::iter().collect::>(); + contents.sort_by_key(|k| k.2 .0); + assert_eq!( + contents, + vec![ + (XCM_VERSION, Parachain(1001).into_versioned(), (70, Weight::zero(), 3)), + (XCM_VERSION, Parachain(1002).into_versioned(), (71, Weight::zero(), 3)), + (XCM_VERSION, Parachain(1003).into_versioned(), (72, Weight::zero(), 3)), + ] + ); + }); +} diff --git a/polkadot/xcm/procedural/Cargo.toml b/polkadot/xcm/procedural/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..a821a73669e01ac5e7d37451537ebd8bb9cb9920 --- /dev/null +++ b/polkadot/xcm/procedural/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "xcm-procedural" +authors.workspace = true +edition.workspace = true +license.workspace = true +version.workspace = true + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0.56" +quote = "1.0.28" +syn = "2.0.15" +Inflector = "0.11.4" diff --git a/polkadot/xcm/procedural/src/lib.rs b/polkadot/xcm/procedural/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..2ebccadf50be805c2f66db0a703e0f09bf43861d --- /dev/null +++ b/polkadot/xcm/procedural/src/lib.rs @@ -0,0 +1,49 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Procedural macros used in XCM. + +use proc_macro::TokenStream; + +mod v2; +mod v3; +mod weight_info; + +#[proc_macro] +pub fn impl_conversion_functions_for_multilocation_v2(input: TokenStream) -> TokenStream { + v2::multilocation::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + +#[proc_macro_derive(XcmWeightInfoTrait)] +pub fn derive_xcm_weight_info(item: TokenStream) -> TokenStream { + weight_info::derive(item) +} + +#[proc_macro] +pub fn impl_conversion_functions_for_multilocation_v3(input: TokenStream) -> TokenStream { + v3::multilocation::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + +#[proc_macro] +pub fn impl_conversion_functions_for_junctions_v3(input: TokenStream) -> TokenStream { + v3::junctions::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/polkadot/xcm/procedural/src/v2.rs b/polkadot/xcm/procedural/src/v2.rs new file mode 100644 index 0000000000000000000000000000000000000000..dc2694a666f0262e961f2fe0dfd844e5651e1cd0 --- /dev/null +++ b/polkadot/xcm/procedural/src/v2.rs @@ -0,0 +1,183 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +pub mod multilocation { + use proc_macro2::{Span, TokenStream}; + use quote::{format_ident, quote}; + use syn::{Result, Token}; + + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")) + } + + // Support up to 8 Parents in a tuple, assuming that most use cases don't go past 8 parents. + let from_tuples = generate_conversion_from_tuples(8); + let from_v3 = generate_conversion_from_v3(); + + Ok(quote! { + #from_tuples + #from_v3 + }) + } + + fn generate_conversion_from_tuples(max_parents: u8) -> TokenStream { + let mut from_tuples = (0..8usize) + .map(|num_junctions| { + let junctions = + (0..=num_junctions).map(|_| format_ident!("Junction")).collect::>(); + let idents = + (0..=num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); + let variant = &format_ident!("X{}", num_junctions + 1); + let array_size = num_junctions + 1; + + let mut from_tuple = quote! { + impl From<( #(#junctions,)* )> for MultiLocation { + fn from( ( #(#idents,)* ): ( #(#junctions,)* ) ) -> Self { + MultiLocation { parents: 0, interior: Junctions::#variant( #(#idents),* ) } + } + } + + impl From<(u8, #(#junctions),*)> for MultiLocation { + fn from( ( parents, #(#idents),* ): (u8, #(#junctions),* ) ) -> Self { + MultiLocation { parents, interior: Junctions::#variant( #(#idents),* ) } + } + } + + impl From<(Ancestor, #(#junctions),*)> for MultiLocation { + fn from( ( Ancestor(parents), #(#idents),* ): (Ancestor, #(#junctions),* ) ) -> Self { + MultiLocation { parents, interior: Junctions::#variant( #(#idents),* ) } + } + } + + impl From<[Junction; #array_size]> for MultiLocation { + fn from(j: [Junction; #array_size]) -> Self { + let [#(#idents),*] = j; + MultiLocation { parents: 0, interior: Junctions::#variant( #(#idents),* ) } + } + } + }; + + let from_parent_tuples = (1..=max_parents).map(|cur_parents| { + let parents = + (0..cur_parents).map(|_| format_ident!("Parent")).collect::>(); + let underscores = + (0..cur_parents).map(|_| Token![_](Span::call_site())).collect::>(); + + quote! { + impl From<( #(#parents,)* #(#junctions),* )> for MultiLocation { + fn from( (#(#underscores,)* #(#idents),*): ( #(#parents,)* #(#junctions),* ) ) -> Self { + MultiLocation { parents: #cur_parents, interior: Junctions::#variant( #(#idents),* ) } + } + } + } + }); + + from_tuple.extend(from_parent_tuples); + from_tuple + }) + .collect::(); + + let from_parent_junctions_tuples = (1..=max_parents).map(|cur_parents| { + let parents = (0..cur_parents).map(|_| format_ident!("Parent")).collect::>(); + let underscores = + (0..cur_parents).map(|_| Token![_](Span::call_site())).collect::>(); + + quote! { + impl From<( #(#parents,)* Junctions )> for MultiLocation { + fn from( (#(#underscores,)* junctions): ( #(#parents,)* Junctions ) ) -> Self { + MultiLocation { parents: #cur_parents, interior: junctions } + } + } + } + }); + from_tuples.extend(from_parent_junctions_tuples); + + quote! { + impl From for MultiLocation { + fn from(junctions: Junctions) -> Self { + MultiLocation { parents: 0, interior: junctions } + } + } + + impl From<(u8, Junctions)> for MultiLocation { + fn from((parents, interior): (u8, Junctions)) -> Self { + MultiLocation { parents, interior } + } + } + + impl From<(Ancestor, Junctions)> for MultiLocation { + fn from((Ancestor(parents), interior): (Ancestor, Junctions)) -> Self { + MultiLocation { parents, interior } + } + } + + impl From<()> for MultiLocation { + fn from(_: ()) -> Self { + MultiLocation { parents: 0, interior: Junctions::Here } + } + } + + impl From<(u8,)> for MultiLocation { + fn from((parents,): (u8,)) -> Self { + MultiLocation { parents, interior: Junctions::Here } + } + } + + impl From for MultiLocation { + fn from(x: Junction) -> Self { + MultiLocation { parents: 0, interior: Junctions::X1(x) } + } + } + + impl From<[Junction; 0]> for MultiLocation { + fn from(_: [Junction; 0]) -> Self { + MultiLocation { parents: 0, interior: Junctions::Here } + } + } + + #from_tuples + } + } + + fn generate_conversion_from_v3() -> TokenStream { + let match_variants = (0..8u8) + .map(|cur_num| { + let num_ancestors = cur_num + 1; + let variant = format_ident!("X{}", num_ancestors); + let idents = (0..=cur_num).map(|i| format_ident!("j{}", i)).collect::>(); + + quote! { + crate::v3::Junctions::#variant( #(#idents),* ) => + #variant( #( core::convert::TryInto::try_into(#idents)? ),* ), + } + }) + .collect::(); + + quote! { + impl core::convert::TryFrom for Junctions { + type Error = (); + fn try_from(mut new: crate::v3::Junctions) -> core::result::Result { + use Junctions::*; + Ok(match new { + crate::v3::Junctions::Here => Here, + #match_variants + }) + } + } + } + } +} diff --git a/polkadot/xcm/procedural/src/v3.rs b/polkadot/xcm/procedural/src/v3.rs new file mode 100644 index 0000000000000000000000000000000000000000..246f90a46a3e7e2ba5a60f0a95c47a52f0d34aae --- /dev/null +++ b/polkadot/xcm/procedural/src/v3.rs @@ -0,0 +1,186 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote}; +use syn::{Result, Token}; + +const MAX_JUNCTIONS: usize = 8; + +pub mod multilocation { + use super::*; + + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")) + } + + let from_tuples = generate_conversion_from_tuples(8, 8); + + Ok(quote! { + #from_tuples + }) + } + + fn generate_conversion_from_tuples(max_junctions: usize, max_parents: usize) -> TokenStream { + let mut from_tuples = (0..=max_junctions) + .map(|num_junctions| { + let types = (0..num_junctions).map(|i| format_ident!("J{}", i)).collect::>(); + let idents = + (0..num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); + let array_size = num_junctions; + let interior = if num_junctions == 0 { + quote!(Junctions::Here) + } else { + let variant = format_ident!("X{}", num_junctions); + quote! { + Junctions::#variant( #(#idents .into()),* ) + } + }; + + let mut from_tuple = quote! { + impl< #(#types : Into,)* > From<( Ancestor, #( #types ),* )> for MultiLocation { + fn from( ( Ancestor(parents), #(#idents),* ): ( Ancestor, #( #types ),* ) ) -> Self { + MultiLocation { parents, interior: #interior } + } + } + + impl From<[Junction; #array_size]> for MultiLocation { + fn from(j: [Junction; #array_size]) -> Self { + let [#(#idents),*] = j; + MultiLocation { parents: 0, interior: #interior } + } + } + }; + + let from_parent_tuples = (0..=max_parents).map(|cur_parents| { + let parents = + (0..cur_parents).map(|_| format_ident!("Parent")).collect::>(); + let underscores = + (0..cur_parents).map(|_| Token![_](Span::call_site())).collect::>(); + + quote! { + impl< #(#types : Into,)* > From<( #( #parents , )* #( #types , )* )> for MultiLocation { + fn from( ( #(#underscores,)* #(#idents,)* ): ( #(#parents,)* #(#types,)* ) ) -> Self { + Self { parents: #cur_parents as u8, interior: #interior } + } + } + } + }); + + from_tuple.extend(from_parent_tuples); + from_tuple + }) + .collect::(); + + let from_parent_junctions_tuples = (0..=max_parents).map(|cur_parents| { + let parents = (0..cur_parents).map(|_| format_ident!("Parent")).collect::>(); + let underscores = + (0..cur_parents).map(|_| Token![_](Span::call_site())).collect::>(); + + quote! { + impl From<( #(#parents,)* Junctions )> for MultiLocation { + fn from( (#(#underscores,)* junctions): ( #(#parents,)* Junctions ) ) -> Self { + MultiLocation { parents: #cur_parents as u8, interior: junctions } + } + } + } + }); + from_tuples.extend(from_parent_junctions_tuples); + + quote! { + impl From<(Ancestor, Junctions)> for MultiLocation { + fn from((Ancestor(parents), interior): (Ancestor, Junctions)) -> Self { + MultiLocation { parents, interior } + } + } + + impl From for MultiLocation { + fn from(x: Junction) -> Self { + MultiLocation { parents: 0, interior: Junctions::X1(x) } + } + } + + #from_tuples + } + } +} + +pub mod junctions { + use super::*; + + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")) + } + + // Support up to 8 Parents in a tuple, assuming that most use cases don't go past 8 parents. + let from_v2 = generate_conversion_from_v2(MAX_JUNCTIONS); + let from_tuples = generate_conversion_from_tuples(MAX_JUNCTIONS); + + Ok(quote! { + #from_v2 + #from_tuples + }) + } + + fn generate_conversion_from_tuples(max_junctions: usize) -> TokenStream { + (1..=max_junctions) + .map(|num_junctions| { + let idents = + (0..num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); + let types = (0..num_junctions).map(|i| format_ident!("J{}", i)).collect::>(); + let variant = &format_ident!("X{}", num_junctions); + + quote! { + impl<#(#types : Into,)*> From<( #(#types,)* )> for Junctions { + fn from( ( #(#idents,)* ): ( #(#types,)* ) ) -> Self { + Self::#variant( #(#idents .into()),* ) + } + } + } + }) + .collect() + } + + fn generate_conversion_from_v2(max_junctions: usize) -> TokenStream { + let match_variants = (0..max_junctions) + .map(|cur_num| { + let num_ancestors = cur_num + 1; + let variant = format_ident!("X{}", num_ancestors); + let idents = (0..=cur_num).map(|i| format_ident!("j{}", i)).collect::>(); + + quote! { + crate::v2::Junctions::#variant( #(#idents),* ) => + #variant( #( core::convert::TryInto::try_into(#idents)? ),* ), + } + }) + .collect::(); + + quote! { + impl core::convert::TryFrom for Junctions { + type Error = (); + fn try_from(mut old: crate::v2::Junctions) -> core::result::Result { + use Junctions::*; + Ok(match old { + crate::v2::Junctions::Here => Here, + #match_variants + }) + } + } + } + } +} diff --git a/polkadot/xcm/procedural/src/weight_info.rs b/polkadot/xcm/procedural/src/weight_info.rs new file mode 100644 index 0000000000000000000000000000000000000000..dde4b94ecc07425b44ad8cf30c677ae7a3e22cd8 --- /dev/null +++ b/polkadot/xcm/procedural/src/weight_info.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use inflector::Inflector; +use quote::format_ident; + +pub fn derive(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input: syn::DeriveInput = match syn::parse(item) { + Ok(input) => input, + Err(e) => return e.into_compile_error().into(), + }; + + let syn::DeriveInput { generics, data, .. } = input; + + match data { + syn::Data::Enum(syn::DataEnum { variants, .. }) => { + let methods = variants.into_iter().map(|syn::Variant { ident, fields, .. }| { + let snake_cased_ident = format_ident!("{}", ident.to_string().to_snake_case()); + let ref_fields = + fields.into_iter().enumerate().map(|(idx, syn::Field { ident, ty, .. })| { + let field_name = ident.unwrap_or_else(|| format_ident!("_{}", idx)); + let field_ty = match ty { + syn::Type::Reference(r) => { + // If the type is already a reference, do nothing + quote::quote!(#r) + }, + t => { + // Otherwise, make it a reference + quote::quote!(&#t) + }, + }; + + quote::quote!(#field_name: #field_ty,) + }); + quote::quote!(fn #snake_cased_ident( #(#ref_fields)* ) -> Weight;) + }); + + let res = quote::quote! { + pub trait XcmWeightInfo #generics { + #(#methods)* + } + }; + res.into() + }, + syn::Data::Struct(syn::DataStruct { struct_token, .. }) => { + let msg = "structs are not supported by 'derive(XcmWeightInfo)'"; + syn::Error::new(struct_token.span, msg).into_compile_error().into() + }, + syn::Data::Union(syn::DataUnion { union_token, .. }) => { + let msg = "unions are not supported by 'derive(XcmWeightInfo)'"; + syn::Error::new(union_token.span, msg).into_compile_error().into() + }, + } +} diff --git a/polkadot/xcm/src/double_encoded.rs b/polkadot/xcm/src/double_encoded.rs new file mode 100644 index 0000000000000000000000000000000000000000..c4c1276fad8dd14167d9fa9c0df27671268d7c51 --- /dev/null +++ b/polkadot/xcm/src/double_encoded.rs @@ -0,0 +1,129 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::MAX_XCM_DECODE_DEPTH; +use alloc::vec::Vec; +use parity_scale_codec::{Decode, DecodeLimit, Encode}; + +/// Wrapper around the encoded and decoded versions of a value. +/// Caches the decoded value once computed. +#[derive(Encode, Decode, scale_info::TypeInfo)] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(T))] +pub struct DoubleEncoded { + encoded: Vec, + #[codec(skip)] + decoded: Option, +} + +impl Clone for DoubleEncoded { + fn clone(&self) -> Self { + Self { encoded: self.encoded.clone(), decoded: None } + } +} + +impl PartialEq for DoubleEncoded { + fn eq(&self, other: &Self) -> bool { + self.encoded.eq(&other.encoded) + } +} +impl Eq for DoubleEncoded {} + +impl core::fmt::Debug for DoubleEncoded { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + self.encoded.fmt(f) + } +} + +impl From> for DoubleEncoded { + fn from(encoded: Vec) -> Self { + Self { encoded, decoded: None } + } +} + +impl DoubleEncoded { + pub fn into(self) -> DoubleEncoded { + DoubleEncoded::from(self) + } + + pub fn from(e: DoubleEncoded) -> Self { + Self { encoded: e.encoded, decoded: None } + } + + /// Provides an API similar to `AsRef` that provides access to the inner value. + /// `AsRef` implementation would expect an `&Option` return type. + pub fn as_ref(&self) -> Option<&T> { + self.decoded.as_ref() + } +} + +impl DoubleEncoded { + /// Decode the inner encoded value and store it. + /// Returns a reference to the value in case of success and `Err(())` in case the decoding + /// fails. + pub fn ensure_decoded(&mut self) -> Result<&T, ()> { + if self.decoded.is_none() { + self.decoded = + T::decode_all_with_depth_limit(MAX_XCM_DECODE_DEPTH, &mut &self.encoded[..]).ok(); + } + self.decoded.as_ref().ok_or(()) + } + + /// Move the decoded value out or (if not present) decode `encoded`. + pub fn take_decoded(&mut self) -> Result { + self.decoded + .take() + .or_else(|| { + T::decode_all_with_depth_limit(MAX_XCM_DECODE_DEPTH, &mut &self.encoded[..]).ok() + }) + .ok_or(()) + } + + /// Provides an API similar to `TryInto` that allows fallible conversion to the inner value + /// type. `TryInto` implementation would collide with std blanket implementation based on + /// `TryFrom`. + pub fn try_into(mut self) -> Result { + self.ensure_decoded()?; + self.decoded.ok_or(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ensure_decoded_works() { + let val: u64 = 42; + let mut encoded: DoubleEncoded<_> = Encode::encode(&val).into(); + assert_eq!(encoded.ensure_decoded(), Ok(&val)); + } + + #[test] + fn take_decoded_works() { + let val: u64 = 42; + let mut encoded: DoubleEncoded<_> = Encode::encode(&val).into(); + assert_eq!(encoded.take_decoded(), Ok(val)); + } + + #[test] + fn try_into_works() { + let val: u64 = 42; + let encoded: DoubleEncoded<_> = Encode::encode(&val).into(); + assert_eq!(encoded.try_into(), Ok(val)); + } +} diff --git a/polkadot/xcm/src/lib.rs b/polkadot/xcm/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..a012c5f53fbf24cc4ec2c9e202573e3228d13f6d --- /dev/null +++ b/polkadot/xcm/src/lib.rs @@ -0,0 +1,459 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// 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 Polkadot. If not, see . + +//! Cross-Consensus Message format data structures. + +// NOTE, this crate is meant to be used in many different environments, notably wasm, but not +// necessarily related to FRAME or even Substrate. +// +// Hence, `no_std` rather than sp-runtime. +#![no_std] +extern crate alloc; + +use derivative::Derivative; +use parity_scale_codec::{Decode, Encode, Error as CodecError, Input, MaxEncodedLen}; +use scale_info::TypeInfo; + +pub mod v2; +pub mod v3; + +pub mod lts { + pub use super::v3::*; +} + +pub mod latest { + pub use super::v3::*; +} + +mod double_encoded; +pub use double_encoded::DoubleEncoded; + +#[cfg(test)] +mod tests; + +/// Maximum nesting level for XCM decoding. +pub const MAX_XCM_DECODE_DEPTH: u32 = 8; + +/// A version of XCM. +pub type Version = u32; + +#[derive(Clone, Eq, PartialEq, Debug)] +pub enum Unsupported {} +impl Encode for Unsupported {} +impl Decode for Unsupported { + fn decode(_: &mut I) -> Result { + Err("Not decodable".into()) + } +} + +/// Attempt to convert `self` into a particular version of itself. +pub trait IntoVersion: Sized { + /// Consume `self` and return same value expressed in some particular `version` of XCM. + fn into_version(self, version: Version) -> Result; + + /// Consume `self` and return same value expressed the latest version of XCM. + fn into_latest(self) -> Result { + self.into_version(latest::VERSION) + } +} + +pub trait TryAs { + fn try_as(&self) -> Result<&T, ()>; +} + +macro_rules! versioned_type { + ($(#[$attr:meta])* pub enum $n:ident { + $(#[$index3:meta])+ + V3($v3:ty), + }) => { + #[derive(Derivative, Encode, Decode, TypeInfo)] + #[derivative( + Clone(bound = ""), + Eq(bound = ""), + PartialEq(bound = ""), + Debug(bound = "") + )] + #[codec(encode_bound())] + #[codec(decode_bound())] + $(#[$attr])* + pub enum $n { + $(#[$index3])* + V3($v3), + } + impl $n { + pub fn try_as(&self) -> Result<&T, ()> where Self: TryAs { + >::try_as(&self) + } + } + impl TryAs<$v3> for $n { + fn try_as(&self) -> Result<&$v3, ()> { + match &self { + Self::V3(ref x) => Ok(x), + } + } + } + impl IntoVersion for $n { + fn into_version(self, n: Version) -> Result { + Ok(match n { + 3 => Self::V3(self.try_into()?), + _ => return Err(()), + }) + } + } + impl> From for $n { + fn from(x: T) -> Self { + $n::V3(x.into()) + } + } + impl TryFrom<$n> for $v3 { + type Error = (); + fn try_from(x: $n) -> Result { + use $n::*; + match x { + V3(x) => Ok(x), + } + } + } + impl MaxEncodedLen for $n { + fn max_encoded_len() -> usize { + <$v3>::max_encoded_len() + } + } + }; + + ($(#[$attr:meta])* pub enum $n:ident { + $(#[$index2:meta])+ + V2($v2:ty), + $(#[$index3:meta])+ + V3($v3:ty), + }) => { + #[derive(Derivative, Encode, Decode, TypeInfo)] + #[derivative( + Clone(bound = ""), + Eq(bound = ""), + PartialEq(bound = ""), + Debug(bound = "") + )] + #[codec(encode_bound())] + #[codec(decode_bound())] + $(#[$attr])* + pub enum $n { + $(#[$index2])* + V2($v2), + $(#[$index3])* + V3($v3), + } + impl $n { + pub fn try_as(&self) -> Result<&T, ()> where Self: TryAs { + >::try_as(&self) + } + } + impl TryAs<$v2> for $n { + fn try_as(&self) -> Result<&$v2, ()> { + match &self { + Self::V2(ref x) => Ok(x), + _ => Err(()), + } + } + } + impl TryAs<$v3> for $n { + fn try_as(&self) -> Result<&$v3, ()> { + match &self { + Self::V3(ref x) => Ok(x), + _ => Err(()), + } + } + } + impl IntoVersion for $n { + fn into_version(self, n: Version) -> Result { + Ok(match n { + 1 | 2 => Self::V2(self.try_into()?), + 3 => Self::V3(self.try_into()?), + _ => return Err(()), + }) + } + } + impl From<$v2> for $n { + fn from(x: $v2) -> Self { + $n::V2(x) + } + } + impl> From for $n { + fn from(x: T) -> Self { + $n::V3(x.into()) + } + } + impl TryFrom<$n> for $v2 { + type Error = (); + fn try_from(x: $n) -> Result { + use $n::*; + match x { + V2(x) => Ok(x), + V3(x) => x.try_into(), + } + } + } + impl TryFrom<$n> for $v3 { + type Error = (); + fn try_from(x: $n) -> Result { + use $n::*; + match x { + V2(x) => x.try_into(), + V3(x) => Ok(x), + } + } + } + impl MaxEncodedLen for $n { + fn max_encoded_len() -> usize { + <$v3>::max_encoded_len() + } + } + }; +} + +versioned_type! { + /// A single version's `Response` value, together with its version code. + pub enum VersionedAssetId { + #[codec(index = 3)] + V3(v3::AssetId), + } +} + +versioned_type! { + /// A single version's `Response` value, together with its version code. + pub enum VersionedResponse { + #[codec(index = 2)] + V2(v2::Response), + #[codec(index = 3)] + V3(v3::Response), + } +} + +versioned_type! { + /// A single `NetworkId` value, together with its version code. + pub enum VersionedNetworkId { + #[codec(index = 2)] + V2(v2::NetworkId), + #[codec(index = 3)] + V3(v3::NetworkId), + } +} + +versioned_type! { + /// A single `Junction` value, together with its version code. + pub enum VersionedJunction { + #[codec(index = 2)] + V2(v2::Junction), + #[codec(index = 3)] + V3(v3::Junction), + } +} + +versioned_type! { + /// A single `MultiLocation` value, together with its version code. + #[derive(Ord, PartialOrd)] + pub enum VersionedMultiLocation { + #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index + V2(v2::MultiLocation), + #[codec(index = 3)] + V3(v3::MultiLocation), + } +} + +versioned_type! { + /// A single `InteriorMultiLocation` value, together with its version code. + pub enum VersionedInteriorMultiLocation { + #[codec(index = 2)] // while this is same as v1::Junctions, VersionedInteriorMultiLocation is introduced in v3 + V2(v2::InteriorMultiLocation), + #[codec(index = 3)] + V3(v3::InteriorMultiLocation), + } +} + +versioned_type! { + /// A single `MultiAsset` value, together with its version code. + pub enum VersionedMultiAsset { + #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index + V2(v2::MultiAsset), + #[codec(index = 3)] + V3(v3::MultiAsset), + } +} + +versioned_type! { + /// A single `MultiAssets` value, together with its version code. + pub enum VersionedMultiAssets { + #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index + V2(v2::MultiAssets), + #[codec(index = 3)] + V3(v3::MultiAssets), + } +} + +/// A single XCM message, together with its version code. +#[derive(Derivative, Encode, Decode, TypeInfo)] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(RuntimeCall))] +pub enum VersionedXcm { + #[codec(index = 2)] + V2(v2::Xcm), + #[codec(index = 3)] + V3(v3::Xcm), +} + +impl IntoVersion for VersionedXcm { + fn into_version(self, n: Version) -> Result { + Ok(match n { + 2 => Self::V2(self.try_into()?), + 3 => Self::V3(self.try_into()?), + _ => return Err(()), + }) + } +} + +impl From> for VersionedXcm { + fn from(x: v2::Xcm) -> Self { + VersionedXcm::V2(x) + } +} + +impl From> for VersionedXcm { + fn from(x: v3::Xcm) -> Self { + VersionedXcm::V3(x) + } +} + +impl TryFrom> for v2::Xcm { + type Error = (); + fn try_from(x: VersionedXcm) -> Result { + use VersionedXcm::*; + match x { + V2(x) => Ok(x), + V3(x) => x.try_into(), + } + } +} + +impl TryFrom> for v3::Xcm { + type Error = (); + fn try_from(x: VersionedXcm) -> Result { + use VersionedXcm::*; + match x { + V2(x) => x.try_into(), + V3(x) => Ok(x), + } + } +} + +/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `MultiLocation` which will +/// interpret it. +pub trait WrapVersion { + fn wrap_version( + dest: &latest::MultiLocation, + xcm: impl Into>, + ) -> Result, ()>; +} + +/// `()` implementation does nothing with the XCM, just sending with whatever version it was +/// authored as. +impl WrapVersion for () { + fn wrap_version( + _: &latest::MultiLocation, + xcm: impl Into>, + ) -> Result, ()> { + Ok(xcm.into()) + } +} + +/// `WrapVersion` implementation which attempts to always convert the XCM to version 2 before +/// wrapping it. +pub struct AlwaysV2; +impl WrapVersion for AlwaysV2 { + fn wrap_version( + _: &latest::MultiLocation, + xcm: impl Into>, + ) -> Result, ()> { + Ok(VersionedXcm::::V2(xcm.into().try_into()?)) + } +} + +/// `WrapVersion` implementation which attempts to always convert the XCM to version 3 before +/// wrapping it. +pub struct AlwaysV3; +impl WrapVersion for AlwaysV3 { + fn wrap_version( + _: &latest::MultiLocation, + xcm: impl Into>, + ) -> Result, ()> { + Ok(VersionedXcm::::V3(xcm.into().try_into()?)) + } +} + +/// `WrapVersion` implementation which attempts to always convert the XCM to the latest version +/// before wrapping it. +pub type AlwaysLatest = AlwaysV3; + +/// `WrapVersion` implementation which attempts to always convert the XCM to the most recent Long- +/// Term-Support version before wrapping it. +pub type AlwaysLts = AlwaysV3; + +pub mod prelude { + pub use super::{ + latest::prelude::*, AlwaysLatest, AlwaysLts, AlwaysV2, AlwaysV3, IntoVersion, Unsupported, + Version as XcmVersion, VersionedAssetId, VersionedInteriorMultiLocation, + VersionedMultiAsset, VersionedMultiAssets, VersionedMultiLocation, VersionedResponse, + VersionedXcm, WrapVersion, + }; +} + +pub mod opaque { + pub mod v2 { + // Everything from v2 + pub use crate::v2::*; + // Then override with the opaque types in v2 + pub use crate::v2::opaque::{Instruction, Xcm}; + } + pub mod v3 { + // Everything from v3 + pub use crate::v3::*; + // Then override with the opaque types in v3 + pub use crate::v3::opaque::{Instruction, Xcm}; + } + + pub mod latest { + pub use super::v3::*; + } + + pub mod lts { + pub use super::v3::*; + } + + /// The basic `VersionedXcm` type which just uses the `Vec` as an encoded call. + pub type VersionedXcm = super::VersionedXcm<()>; +} + +// A simple trait to get the weight of some object. +pub trait GetWeight { + fn weight(&self) -> latest::Weight; +} + +#[test] +fn conversion_works() { + use latest::prelude::*; + let _: VersionedMultiAssets = (Here, 1u128).into(); +} diff --git a/polkadot/xcm/src/tests.rs b/polkadot/xcm/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..10b14ffec992941a912cb944484411f09e21b984 --- /dev/null +++ b/polkadot/xcm/src/tests.rs @@ -0,0 +1,183 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::*; +use alloc::vec; + +#[test] +fn encode_decode_versioned_asset_id_v3() { + let asset_id = VersionedAssetId::V3(v3::AssetId::Abstract([1; 32])); + let encoded = asset_id.encode(); + + assert_eq!( + encoded, + hex_literal::hex!("03010101010101010101010101010101010101010101010101010101010101010101"), + "encode format changed" + ); + assert_eq!(encoded[0], 3, "bad version number"); + + let decoded = VersionedAssetId::decode(&mut &encoded[..]).unwrap(); + assert_eq!(asset_id, decoded); +} + +#[test] +fn encode_decode_versioned_response_v2() { + let response = VersionedResponse::V2(v2::Response::Null); + let encoded = response.encode(); + + assert_eq!(encoded, hex_literal::hex!("0200"), "encode format changed"); + assert_eq!(encoded[0], 2, "bad version number"); + + let decoded = VersionedResponse::decode(&mut &encoded[..]).unwrap(); + assert_eq!(response, decoded); +} + +#[test] +fn encode_decode_versioned_response_v3() { + let response = VersionedResponse::V3(v3::Response::Null); + let encoded = response.encode(); + + assert_eq!(encoded, hex_literal::hex!("0300"), "encode format changed"); + assert_eq!(encoded[0], 3, "bad version number"); + + let decoded = VersionedResponse::decode(&mut &encoded[..]).unwrap(); + assert_eq!(response, decoded); +} + +#[test] +fn encode_decode_versioned_multi_location_v2() { + let location = VersionedMultiLocation::V2(v2::MultiLocation::new(0, v2::Junctions::Here)); + let encoded = location.encode(); + + assert_eq!(encoded, hex_literal::hex!("010000"), "encode format changed"); + assert_eq!(encoded[0], 1, "bad version number"); // this is introduced in v1 + + let decoded = VersionedMultiLocation::decode(&mut &encoded[..]).unwrap(); + assert_eq!(location, decoded); +} + +#[test] +fn encode_decode_versioned_multi_location_v3() { + let location = VersionedMultiLocation::V3(v3::MultiLocation::new(0, v3::Junctions::Here)); + let encoded = location.encode(); + + assert_eq!(encoded, hex_literal::hex!("030000"), "encode format changed"); + assert_eq!(encoded[0], 3, "bad version number"); + + let decoded = VersionedMultiLocation::decode(&mut &encoded[..]).unwrap(); + assert_eq!(location, decoded); +} + +#[test] +fn encode_decode_versioned_interior_multi_location_v2() { + let location = VersionedInteriorMultiLocation::V2(v2::InteriorMultiLocation::Here); + let encoded = location.encode(); + + assert_eq!(encoded, hex_literal::hex!("0200"), "encode format changed"); + assert_eq!(encoded[0], 2, "bad version number"); + + let decoded = VersionedInteriorMultiLocation::decode(&mut &encoded[..]).unwrap(); + assert_eq!(location, decoded); +} + +#[test] +fn encode_decode_versioned_interior_multi_location_v3() { + let location = VersionedInteriorMultiLocation::V3(v3::InteriorMultiLocation::Here); + let encoded = location.encode(); + + assert_eq!(encoded, hex_literal::hex!("0300"), "encode format changed"); + assert_eq!(encoded[0], 3, "bad version number"); + + let decoded = VersionedInteriorMultiLocation::decode(&mut &encoded[..]).unwrap(); + assert_eq!(location, decoded); +} + +#[test] +fn encode_decode_versioned_multi_asset_v2() { + let asset = VersionedMultiAsset::V2(v2::MultiAsset::from(((0, v2::Junctions::Here), 1))); + let encoded = asset.encode(); + + assert_eq!(encoded, hex_literal::hex!("010000000004"), "encode format changed"); + assert_eq!(encoded[0], 1, "bad version number"); + + let decoded = VersionedMultiAsset::decode(&mut &encoded[..]).unwrap(); + assert_eq!(asset, decoded); +} + +#[test] +fn encode_decode_versioned_multi_asset_v3() { + let asset = VersionedMultiAsset::V3(v3::MultiAsset::from((v3::MultiLocation::default(), 1))); + let encoded = asset.encode(); + + assert_eq!(encoded, hex_literal::hex!("030000000004"), "encode format changed"); + assert_eq!(encoded[0], 3, "bad version number"); + + let decoded = VersionedMultiAsset::decode(&mut &encoded[..]).unwrap(); + assert_eq!(asset, decoded); +} + +#[test] +fn encode_decode_versioned_multi_assets_v2() { + let assets = VersionedMultiAssets::V2(v2::MultiAssets::from(vec![v2::MultiAsset::from(( + (0, v2::Junctions::Here), + 1, + ))])); + let encoded = assets.encode(); + + assert_eq!(encoded, hex_literal::hex!("01040000000004"), "encode format changed"); + assert_eq!(encoded[0], 1, "bad version number"); + + let decoded = VersionedMultiAssets::decode(&mut &encoded[..]).unwrap(); + assert_eq!(assets, decoded); +} + +#[test] +fn encode_decode_versioned_multi_assets_v3() { + let assets = VersionedMultiAssets::V3(v3::MultiAssets::from(vec![ + (v3::MultiAsset::from((v3::MultiLocation::default(), 1))), + ])); + let encoded = assets.encode(); + + assert_eq!(encoded, hex_literal::hex!("03040000000004"), "encode format changed"); + assert_eq!(encoded[0], 3, "bad version number"); + + let decoded = VersionedMultiAssets::decode(&mut &encoded[..]).unwrap(); + assert_eq!(assets, decoded); +} + +#[test] +fn encode_decode_versioned_xcm_v2() { + let xcm = VersionedXcm::V2(v2::Xcm::<()>::new()); + let encoded = xcm.encode(); + + assert_eq!(encoded, hex_literal::hex!("0200"), "encode format changed"); + assert_eq!(encoded[0], 2, "bad version number"); + + let decoded = VersionedXcm::decode(&mut &encoded[..]).unwrap(); + assert_eq!(xcm, decoded); +} + +#[test] +fn encode_decode_versioned_xcm_v3() { + let xcm = VersionedXcm::V3(v3::Xcm::<()>::new()); + let encoded = xcm.encode(); + + assert_eq!(encoded, hex_literal::hex!("0300"), "encode format changed"); + assert_eq!(encoded[0], 3, "bad version number"); + + let decoded = VersionedXcm::decode(&mut &encoded[..]).unwrap(); + assert_eq!(xcm, decoded); +} diff --git a/polkadot/xcm/src/v2/junction.rs b/polkadot/xcm/src/v2/junction.rs new file mode 100644 index 0000000000000000000000000000000000000000..73a5029994624b1c12ef8b7d9bd393b98e8660cd --- /dev/null +++ b/polkadot/xcm/src/v2/junction.rs @@ -0,0 +1,122 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Support data structures for `MultiLocation`, primarily the `Junction` datatype. + +use super::{BodyId, BodyPart, Junctions, MultiLocation, NetworkId}; +use crate::v3::Junction as NewJunction; +use bounded_collections::{ConstU32, WeakBoundedVec}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// A single item in a path to describe the relative location of a consensus system. +/// +/// Each item assumes a pre-existing location as its context and is defined in terms of it. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum Junction { + /// An indexed parachain belonging to and operated by the context. + /// + /// Generally used when the context is a Polkadot Relay-chain. + Parachain(#[codec(compact)] u32), + /// A 32-byte identifier for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// Generally used when the context is a Substrate-based chain. + AccountId32 { network: NetworkId, id: [u8; 32] }, + /// An 8-byte index for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// May be used when the context is a Frame-based chain and includes e.g. an indices pallet. + AccountIndex64 { + network: NetworkId, + #[codec(compact)] + index: u64, + }, + /// A 20-byte identifier for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// May be used when the context is an Ethereum or Bitcoin chain or smart-contract. + AccountKey20 { network: NetworkId, key: [u8; 20] }, + /// An instanced, indexed pallet that forms a constituent part of the context. + /// + /// Generally used when the context is a Frame-based chain. + PalletInstance(u8), + /// A non-descript index within the context location. + /// + /// Usage will vary widely owing to its generality. + /// + /// NOTE: Try to avoid using this and instead use a more specific item. + GeneralIndex(#[codec(compact)] u128), + /// A nondescript datum acting as a key within the context location. + /// + /// Usage will vary widely owing to its generality. + /// + /// NOTE: Try to avoid using this and instead use a more specific item. + GeneralKey(WeakBoundedVec>), + /// The unambiguous child. + /// + /// Not currently used except as a fallback when deriving ancestry. + OnlyChild, + /// A pluralistic body existing within consensus. + /// + /// Typical to be used to represent a governance origin of a chain, but could in principle be + /// used to represent things such as multisigs also. + Plurality { id: BodyId, part: BodyPart }, +} + +impl TryFrom for Junction { + type Error = (); + + fn try_from(value: NewJunction) -> Result { + use NewJunction::*; + Ok(match value { + Parachain(id) => Self::Parachain(id), + AccountId32 { network, id } => Self::AccountId32 { network: network.try_into()?, id }, + AccountIndex64 { network, index } => + Self::AccountIndex64 { network: network.try_into()?, index }, + AccountKey20 { network, key } => + Self::AccountKey20 { network: network.try_into()?, key }, + PalletInstance(index) => Self::PalletInstance(index), + GeneralIndex(id) => Self::GeneralIndex(id), + GeneralKey { length, data } => Self::GeneralKey( + data[0..data.len().min(length as usize)] + .to_vec() + .try_into() + .expect("key is bounded to 32 and so will never be out of bounds; qed"), + ), + OnlyChild => Self::OnlyChild, + Plurality { id, part } => Self::Plurality { id: id.into(), part: part.into() }, + _ => return Err(()), + }) + } +} + +impl Junction { + /// Convert `self` into a `MultiLocation` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub const fn into(self) -> MultiLocation { + MultiLocation { parents: 0, interior: Junctions::X1(self) } + } + + /// Convert `self` into a `MultiLocation` containing `n` parents. + /// + /// Similar to `Self::into`, with the added ability to specify the number of parent junctions. + pub const fn into_exterior(self, n: u8) -> MultiLocation { + MultiLocation { parents: n, interior: Junctions::X1(self) } + } +} diff --git a/polkadot/xcm/src/v2/mod.rs b/polkadot/xcm/src/v2/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..8a67b771c9e97844406ff0415967bde7ff3a7ce1 --- /dev/null +++ b/polkadot/xcm/src/v2/mod.rs @@ -0,0 +1,1131 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// 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 Cumulus. If not, see . + +//! # XCM Version 2 +//! Version 2 of the Cross-Consensus Message format data structures. The comprehensive list of +//! changes can be found in +//! [this PR description](https://github.com/paritytech/polkadot/pull/3629#issue-968428279). +//! +//! ## Changes to be aware of +//! The biggest change here is the restructuring of XCM messages: instead of having `Order` and +//! `Xcm` types, the `Xcm` type now simply wraps a `Vec` containing `Instruction`s. However, most +//! changes should still be automatically convertible via the `try_from` and `from` conversion +//! functions. +//! +//! ### Junction +//! - No special attention necessary +//! +//! ### `MultiLocation` +//! - No special attention necessary +//! +//! ### `MultiAsset` +//! - No special attention necessary +//! +//! ### XCM and Order +//! - `Xcm` and `Order` variants are now combined under a single `Instruction` enum. +//! - `Order` is now obsolete and replaced entirely by `Instruction`. +//! - `Xcm` is now a simple wrapper around a `Vec`. +//! - During conversion from `Order` to `Instruction`, we do not handle `BuyExecution`s that have +//! nested XCMs, i.e. if the `instructions` field in the `BuyExecution` enum struct variant is not +//! empty, then the conversion will fail. To address this, rewrite the XCM using `Instruction`s in +//! chronological order. +//! - During conversion from `Xcm` to `Instruction`, we do not handle `RelayedFrom` messages at all. +//! +//! ### XCM Pallet +//! - The `Weigher` configuration item must have sensible weights defined for `BuyExecution` and +//! `DepositAsset` instructions. Failing that, dispatch calls to `teleport_assets` and +//! `reserve_transfer_assets` will fail with `UnweighableMessage`. + +use super::{ + v3::{ + BodyId as NewBodyId, BodyPart as NewBodyPart, Instruction as NewInstruction, + NetworkId as NewNetworkId, Response as NewResponse, WeightLimit as NewWeightLimit, + Xcm as NewXcm, + }, + DoubleEncoded, GetWeight, +}; +use alloc::{vec, vec::Vec}; +use bounded_collections::{ConstU32, WeakBoundedVec}; +use core::{fmt::Debug, result}; +use derivative::Derivative; +use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +mod junction; +mod multiasset; +mod multilocation; +mod traits; + +pub use junction::Junction; +pub use multiasset::{ + AssetId, AssetInstance, Fungibility, MultiAsset, MultiAssetFilter, MultiAssets, + WildFungibility, WildMultiAsset, +}; +pub use multilocation::{ + Ancestor, AncestorThen, InteriorMultiLocation, Junctions, MultiLocation, Parent, ParentThen, +}; +pub use traits::{Error, ExecuteXcm, Outcome, Result, SendError, SendResult, SendXcm}; + +/// Basically just the XCM (more general) version of `ParachainDispatchOrigin`. +#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] +pub enum OriginKind { + /// Origin should just be the native dispatch origin representation for the sender in the + /// local runtime framework. For Cumulus/Frame chains this is the `Parachain` or `Relay` origin + /// if coming from a chain, though there may be others if the `MultiLocation` XCM origin has a + /// primary/native dispatch origin form. + Native, + + /// Origin should just be the standard account-based origin with the sovereign account of + /// the sender. For Cumulus/Frame chains, this is the `Signed` origin. + SovereignAccount, + + /// Origin should be the super-user. For Cumulus/Frame chains, this is the `Root` origin. + /// This will not usually be an available option. + Superuser, + + /// Origin should be interpreted as an XCM native origin and the `MultiLocation` should be + /// encoded directly in the dispatch origin unchanged. For Cumulus/Frame chains, this will be + /// the `pallet_xcm::Origin::Xcm` type. + Xcm, +} + +/// A global identifier of an account-bearing consensus system. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum NetworkId { + /// Unidentified/any. + Any, + /// Some named network. + Named(WeakBoundedVec>), + /// The Polkadot Relay chain + Polkadot, + /// Kusama. + Kusama, +} + +impl TryFrom> for NetworkId { + type Error = (); + fn try_from(new: Option) -> result::Result { + match new { + None => Ok(NetworkId::Any), + Some(id) => Self::try_from(id), + } + } +} + +impl TryFrom for NetworkId { + type Error = (); + fn try_from(new: NewNetworkId) -> result::Result { + use NewNetworkId::*; + match new { + Polkadot => Ok(NetworkId::Polkadot), + Kusama => Ok(NetworkId::Kusama), + _ => Err(()), + } + } +} + +/// An identifier of a pluralistic body. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum BodyId { + /// The only body in its context. + Unit, + /// A named body. + Named(WeakBoundedVec>), + /// An indexed body. + Index(#[codec(compact)] u32), + /// The unambiguous executive body (for Polkadot, this would be the Polkadot council). + Executive, + /// The unambiguous technical body (for Polkadot, this would be the Technical Committee). + Technical, + /// The unambiguous legislative body (for Polkadot, this could be considered the opinion of a + /// majority of lock-voters). + Legislative, + /// The unambiguous judicial body (this doesn't exist on Polkadot, but if it were to get a + /// "grand oracle", it may be considered as that). + Judicial, + /// The unambiguous defense body (for Polkadot, an opinion on the topic given via a public + /// referendum on the `staking_admin` track). + Defense, + /// The unambiguous administration body (for Polkadot, an opinion on the topic given via a + /// public referendum on the `general_admin` track). + Administration, + /// The unambiguous treasury body (for Polkadot, an opinion on the topic given via a public + /// referendum on the `treasurer` track). + Treasury, +} + +impl From for BodyId { + fn from(n: NewBodyId) -> Self { + use NewBodyId::*; + match n { + Unit => Self::Unit, + Moniker(n) => Self::Named( + n[..] + .to_vec() + .try_into() + .expect("array size is 4 and so will never be out of bounds; qed"), + ), + Index(n) => Self::Index(n), + Executive => Self::Executive, + Technical => Self::Technical, + Legislative => Self::Legislative, + Judicial => Self::Judicial, + Defense => Self::Defense, + Administration => Self::Administration, + Treasury => Self::Treasury, + } + } +} + +/// A part of a pluralistic body. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum BodyPart { + /// The body's declaration, under whatever means it decides. + Voice, + /// A given number of members of the body. + Members { + #[codec(compact)] + count: u32, + }, + /// A given number of members of the body, out of some larger caucus. + Fraction { + #[codec(compact)] + nom: u32, + #[codec(compact)] + denom: u32, + }, + /// No less than the given proportion of members of the body. + AtLeastProportion { + #[codec(compact)] + nom: u32, + #[codec(compact)] + denom: u32, + }, + /// More than than the given proportion of members of the body. + MoreThanProportion { + #[codec(compact)] + nom: u32, + #[codec(compact)] + denom: u32, + }, +} + +impl BodyPart { + /// Returns `true` if the part represents a strict majority (> 50%) of the body in question. + pub fn is_majority(&self) -> bool { + match self { + BodyPart::Fraction { nom, denom } if *nom * 2 > *denom => true, + BodyPart::AtLeastProportion { nom, denom } if *nom * 2 > *denom => true, + BodyPart::MoreThanProportion { nom, denom } if *nom * 2 >= *denom => true, + _ => false, + } + } +} + +impl From for BodyPart { + fn from(n: NewBodyPart) -> Self { + use NewBodyPart::*; + match n { + Voice => Self::Voice, + Members { count } => Self::Members { count }, + Fraction { nom, denom } => Self::Fraction { nom, denom }, + AtLeastProportion { nom, denom } => Self::AtLeastProportion { nom, denom }, + MoreThanProportion { nom, denom } => Self::MoreThanProportion { nom, denom }, + } + } +} + +/// This module's XCM version. +pub const VERSION: super::Version = 2; + +/// An identifier for a query. +pub type QueryId = u64; + +#[derive(Derivative, Default, Encode, Decode, TypeInfo)] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(RuntimeCall))] +pub struct Xcm(pub Vec>); + +impl Xcm { + /// Create an empty instance. + pub fn new() -> Self { + Self(vec![]) + } + + /// Return `true` if no instructions are held in `self`. + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Return the number of instructions held in `self`. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Consume and either return `self` if it contains some instructions, or if it's empty, then + /// instead return the result of `f`. + pub fn or_else(self, f: impl FnOnce() -> Self) -> Self { + if self.0.is_empty() { + f() + } else { + self + } + } + + /// Return the first instruction, if any. + pub fn first(&self) -> Option<&Instruction> { + self.0.first() + } + + /// Return the last instruction, if any. + pub fn last(&self) -> Option<&Instruction> { + self.0.last() + } + + /// Return the only instruction, contained in `Self`, iff only one exists (`None` otherwise). + pub fn only(&self) -> Option<&Instruction> { + if self.0.len() == 1 { + self.0.first() + } else { + None + } + } + + /// Return the only instruction, contained in `Self`, iff only one exists (returns `self` + /// otherwise). + pub fn into_only(mut self) -> core::result::Result, Self> { + if self.0.len() == 1 { + self.0.pop().ok_or(self) + } else { + Err(self) + } + } +} + +/// A prelude for importing all types typically used when interacting with XCM messages. +pub mod prelude { + mod contents { + pub use super::super::{ + Ancestor, AncestorThen, + AssetId::{self, *}, + AssetInstance::{self, *}, + BodyId, BodyPart, Error as XcmError, ExecuteXcm, + Fungibility::{self, *}, + Instruction::*, + InteriorMultiLocation, + Junction::{self, *}, + Junctions::{self, *}, + MultiAsset, + MultiAssetFilter::{self, *}, + MultiAssets, MultiLocation, + NetworkId::{self, *}, + OriginKind, Outcome, Parent, ParentThen, QueryId, Response, Result as XcmResult, + SendError, SendResult, SendXcm, + WeightLimit::{self, *}, + WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible}, + WildMultiAsset::{self, *}, + XcmWeightInfo, VERSION as XCM_VERSION, + }; + } + pub use super::{Instruction, Xcm}; + pub use contents::*; + pub mod opaque { + pub use super::{ + super::opaque::{Instruction, Xcm}, + contents::*, + }; + } +} + +/// Response data to a query. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] +pub enum Response { + /// No response. Serves as a neutral default. + Null, + /// Some assets. + Assets(MultiAssets), + /// The outcome of an XCM instruction. + ExecutionResult(Option<(u32, Error)>), + /// An XCM version. + Version(super::Version), +} + +impl Default for Response { + fn default() -> Self { + Self::Null + } +} + +/// An optional weight limit. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] +pub enum WeightLimit { + /// No weight limit imposed. + Unlimited, + /// Weight limit imposed of the inner value. + Limited(#[codec(compact)] u64), +} + +impl From> for WeightLimit { + fn from(x: Option) -> Self { + match x { + Some(w) => WeightLimit::Limited(w), + None => WeightLimit::Unlimited, + } + } +} + +impl From for Option { + fn from(x: WeightLimit) -> Self { + match x { + WeightLimit::Limited(w) => Some(w), + WeightLimit::Unlimited => None, + } + } +} + +impl TryFrom for WeightLimit { + type Error = (); + fn try_from(x: NewWeightLimit) -> result::Result { + use NewWeightLimit::*; + match x { + Limited(w) => Ok(Self::Limited(w.ref_time())), + Unlimited => Ok(Self::Unlimited), + } + } +} + +/// Local weight type; execution time in picoseconds. +pub type Weight = u64; + +/// Cross-Consensus Message: A message from one consensus system to another. +/// +/// Consensus systems that may send and receive messages include blockchains and smart contracts. +/// +/// All messages are delivered from a known *origin*, expressed as a `MultiLocation`. +/// +/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the +/// outer XCM format, known as `VersionedXcm`. +#[derive(Derivative, Encode, Decode, TypeInfo, xcm_procedural::XcmWeightInfoTrait)] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(RuntimeCall))] +pub enum Instruction { + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into the Holding + /// Register. + /// + /// - `assets`: The asset(s) to be withdrawn into holding. + /// + /// Kind: *Command*. + /// + /// Errors: + WithdrawAsset(MultiAssets), + + /// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` + /// system and equivalent derivatives should be placed into the Holding Register. + /// + /// - `assets`: The asset(s) that are minted into holding. + /// + /// Safety: `origin` must be trusted to have received and be storing `assets` such that they + /// may later be withdrawn should this system send a corresponding message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + ReserveAssetDeposited(MultiAssets), + + /// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should + /// be created and placed into the Holding Register. + /// + /// - `assets`: The asset(s) that are minted into the Holding Register. + /// + /// Safety: `origin` must be trusted to have irrevocably destroyed the corresponding `assets` + /// prior as a consequence of sending this message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + ReceiveTeleportedAsset(MultiAssets), + + /// Respond with information that the local system is expecting. + /// + /// - `query_id`: The identifier of the query that resulted in this message being sent. + /// - `response`: The message content. + /// - `max_weight`: The maximum weight that handling this response should take. + /// + /// Safety: No concerns. + /// + /// Kind: *Information*. + /// + /// Errors: + QueryResponse { + #[codec(compact)] + query_id: QueryId, + response: Response, + #[codec(compact)] + max_weight: u64, + }, + + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets + /// under the ownership of `beneficiary`. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `beneficiary`: The new owner for the assets. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + TransferAsset { assets: MultiAssets, beneficiary: MultiLocation }, + + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets + /// under the ownership of `dest` within this consensus system (i.e. its sovereign account). + /// + /// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given + /// `xcm`. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `dest`: The location whose sovereign account will own the assets and thus the effective + /// beneficiary for the assets and the notification target for the reserve asset deposit + /// message. + /// - `xcm`: The instructions that should follow the `ReserveAssetDeposited` instruction, which + /// is sent onwards to `dest`. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + TransferReserveAsset { assets: MultiAssets, dest: MultiLocation, xcm: Xcm<()> }, + + /// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed + /// by the kind of origin `origin_type`. + /// + /// - `origin_type`: The means of expressing the message origin as a dispatch origin. + /// - `max_weight`: The weight of `call`; this should be at least the chain's calculated weight + /// and will be used in the weight determination arithmetic. + /// - `call`: The encoded transaction to be applied. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + Transact { + origin_type: OriginKind, + #[codec(compact)] + require_weight_at_most: u64, + call: DoubleEncoded, + }, + + /// A message to notify about a new incoming HRMP channel. This message is meant to be sent by + /// the relay-chain to a para. + /// + /// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel + /// opening. + /// - `max_message_size`: The maximum size of a message proposed by the sender. + /// - `max_capacity`: The maximum number of messages that can be queued in the channel. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + HrmpNewChannelOpenRequest { + #[codec(compact)] + sender: u32, + #[codec(compact)] + max_message_size: u32, + #[codec(compact)] + max_capacity: u32, + }, + + /// A message to notify about that a previously sent open channel request has been accepted by + /// the recipient. That means that the channel will be opened during the next relay-chain + /// session change. This message is meant to be sent by the relay-chain to a para. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + /// + /// Errors: + HrmpChannelAccepted { + // NOTE: We keep this as a structured item to a) keep it consistent with the other Hrmp + // items; and b) because the field's meaning is not obvious/mentioned from the item name. + #[codec(compact)] + recipient: u32, + }, + + /// A message to notify that the other party in an open channel decided to close it. In + /// particular, `initiator` is going to close the channel opened from `sender` to the + /// `recipient`. The close will be enacted at the next relay-chain session change. This message + /// is meant to be sent by the relay-chain to a para. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + /// + /// Errors: + HrmpChannelClosing { + #[codec(compact)] + initiator: u32, + #[codec(compact)] + sender: u32, + #[codec(compact)] + recipient: u32, + }, + + /// Clear the origin. + /// + /// This may be used by the XCM author to ensure that later instructions cannot command the + /// authority of the origin (e.g. if they are being relayed from an untrusted source, as often + /// the case with `ReserveAssetDeposited`). + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + ClearOrigin, + + /// Mutate the origin to some interior location. + /// + /// Kind: *Command* + /// + /// Errors: + DescendOrigin(InteriorMultiLocation), + + /// Immediately report the contents of the Error Register to the given destination via XCM. + /// + /// A `QueryResponse` message of type `ExecutionOutcome` is sent to `dest` with the given + /// `query_id` and the outcome of the XCM. + /// + /// - `query_id`: An identifier that will be replicated into the returned XCM message. + /// - `dest`: A valid destination for the returned XCM message. + /// - `max_response_weight`: The maximum amount of weight that the `QueryResponse` item which + /// is sent as a reply may take to execute. NOTE: If this is unexpectedly large then the + /// response may not execute at all. + /// + /// Kind: *Command* + /// + /// Errors: + ReportError { + #[codec(compact)] + query_id: QueryId, + dest: MultiLocation, + #[codec(compact)] + max_response_weight: u64, + }, + + /// Remove the asset(s) (`assets`) from the Holding Register and place equivalent assets under + /// the ownership of `beneficiary` within this consensus system. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `max_assets`: The maximum number of unique assets/asset instances to remove from holding. + /// Only the first `max_assets` assets/instances of those matched by `assets` will be + /// removed, prioritized under standard asset ordering. Any others will remain in holding. + /// - `beneficiary`: The new owner for the assets. + /// + /// Kind: *Command* + /// + /// Errors: + DepositAsset { + assets: MultiAssetFilter, + #[codec(compact)] + max_assets: u32, + beneficiary: MultiLocation, + }, + + /// Remove the asset(s) (`assets`) from the Holding Register and place equivalent assets under + /// the ownership of `dest` within this consensus system (i.e. deposit them into its sovereign + /// account). + /// + /// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given `effects`. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `max_assets`: The maximum number of unique assets/asset instances to remove from holding. + /// Only the first `max_assets` assets/instances of those matched by `assets` will be + /// removed, prioritized under standard asset ordering. Any others will remain in holding. + /// - `dest`: The location whose sovereign account will own the assets and thus the effective + /// beneficiary for the assets and the notification target for the reserve asset deposit + /// message. + /// - `xcm`: The orders that should follow the `ReserveAssetDeposited` instruction which is + /// sent onwards to `dest`. + /// + /// Kind: *Command* + /// + /// Errors: + DepositReserveAsset { + assets: MultiAssetFilter, + #[codec(compact)] + max_assets: u32, + dest: MultiLocation, + xcm: Xcm<()>, + }, + + /// Remove the asset(s) (`give`) from the Holding Register and replace them with alternative + /// assets. + /// + /// The minimum amount of assets to be received into the Holding Register for the order not to + /// fail may be stated. + /// + /// - `give`: The asset(s) to remove from holding. + /// - `receive`: The minimum amount of assets(s) which `give` should be exchanged for. + /// + /// Kind: *Command* + /// + /// Errors: + ExchangeAsset { give: MultiAssetFilter, receive: MultiAssets }, + + /// Remove the asset(s) (`assets`) from holding and send a `WithdrawAsset` XCM message to a + /// reserve location. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The + /// sovereign account of this consensus system *on the reserve location* will have + /// appropriate assets withdrawn and `effects` will be executed on them. There will typically + /// be only one valid location on any given asset/chain combination. + /// - `xcm`: The instructions to execute on the assets once withdrawn *on the reserve + /// location*. + /// + /// Kind: *Command* + /// + /// Errors: + InitiateReserveWithdraw { assets: MultiAssetFilter, reserve: MultiLocation, xcm: Xcm<()> }, + + /// Remove the asset(s) (`assets`) from holding and send a `ReceiveTeleportedAsset` XCM message + /// to a `dest` location. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `dest`: A valid location that respects teleports coming from this location. + /// - `xcm`: The instructions to execute on the assets once arrived *on the destination + /// location*. + /// + /// NOTE: The `dest` location *MUST* respect this origin as a valid teleportation origin for + /// all `assets`. If it does not, then the assets may be lost. + /// + /// Kind: *Command* + /// + /// Errors: + InitiateTeleport { assets: MultiAssetFilter, dest: MultiLocation, xcm: Xcm<()> }, + + /// Send a `Balances` XCM message with the `assets` value equal to the holding contents, or a + /// portion thereof. + /// + /// - `query_id`: An identifier that will be replicated into the returned XCM message. + /// - `dest`: A valid destination for the returned XCM message. This may be limited to the + /// current origin. + /// - `assets`: A filter for the assets that should be reported back. The assets reported back + /// will be, asset-wise, *the lesser of this value and the holding register*. No wildcards + /// will be used when reporting assets back. + /// - `max_response_weight`: The maximum amount of weight that the `QueryResponse` item which + /// is sent as a reply may take to execute. NOTE: If this is unexpectedly large then the + /// response may not execute at all. + /// + /// Kind: *Command* + /// + /// Errors: + QueryHolding { + #[codec(compact)] + query_id: QueryId, + dest: MultiLocation, + assets: MultiAssetFilter, + #[codec(compact)] + max_response_weight: u64, + }, + + /// Pay for the execution of some XCM `xcm` and `orders` with up to `weight` + /// picoseconds of execution time, paying for this with up to `fees` from the Holding Register. + /// + /// - `fees`: The asset(s) to remove from the Holding Register to pay for fees. + /// - `weight_limit`: The maximum amount of weight to purchase; this must be at least the + /// expected maximum weight of the total XCM to be executed for the + /// `AllowTopLevelPaidExecutionFrom` barrier to allow the XCM be executed. + /// + /// Kind: *Command* + /// + /// Errors: + BuyExecution { fees: MultiAsset, weight_limit: WeightLimit }, + + /// Refund any surplus weight previously bought with `BuyExecution`. + /// + /// Kind: *Command* + /// + /// Errors: None. + RefundSurplus, + + /// Set the Error Handler Register. This is code that should be called in the case of an error + /// happening. + /// + /// An error occurring within execution of this code will _NOT_ result in the error register + /// being set, nor will an error handler be called due to it. The error handler and appendix + /// may each still be set. + /// + /// The apparent weight of this instruction is inclusive of the inner `Xcm`; the executing + /// weight however includes only the difference between the previous handler and the new + /// handler, which can reasonably be negative, which would result in a surplus. + /// + /// Kind: *Command* + /// + /// Errors: None. + SetErrorHandler(Xcm), + + /// Set the Appendix Register. This is code that should be called after code execution + /// (including the error handler if any) is finished. This will be called regardless of whether + /// an error occurred. + /// + /// Any error occurring due to execution of this code will result in the error register being + /// set, and the error handler (if set) firing. + /// + /// The apparent weight of this instruction is inclusive of the inner `Xcm`; the executing + /// weight however includes only the difference between the previous appendix and the new + /// appendix, which can reasonably be negative, which would result in a surplus. + /// + /// Kind: *Command* + /// + /// Errors: None. + SetAppendix(Xcm), + + /// Clear the Error Register. + /// + /// Kind: *Command* + /// + /// Errors: None. + ClearError, + + /// Create some assets which are being held on behalf of the origin. + /// + /// - `assets`: The assets which are to be claimed. This must match exactly with the assets + /// claimable by the origin of the ticket. + /// - `ticket`: The ticket of the asset; this is an abstract identifier to help locate the + /// asset. + /// + /// Kind: *Command* + /// + /// Errors: + ClaimAsset { assets: MultiAssets, ticket: MultiLocation }, + + /// Always throws an error of type `Trap`. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `Trap`: All circumstances, whose inner value is the same as this item's inner value. + Trap(#[codec(compact)] u64), + + /// Ask the destination system to respond with the most recent version of XCM that they + /// support in a `QueryResponse` instruction. Any changes to this should also elicit similar + /// responses when they happen. + /// + /// - `query_id`: An identifier that will be replicated into the returned XCM message. + /// - `max_response_weight`: The maximum amount of weight that the `QueryResponse` item which + /// is sent as a reply may take to execute. NOTE: If this is unexpectedly large then the + /// response may not execute at all. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible* + SubscribeVersion { + #[codec(compact)] + query_id: QueryId, + #[codec(compact)] + max_response_weight: u64, + }, + + /// Cancel the effect of a previous `SubscribeVersion` instruction. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible* + UnsubscribeVersion, +} + +impl Xcm { + pub fn into(self) -> Xcm { + Xcm::from(self) + } + pub fn from(xcm: Xcm) -> Self { + Self(xcm.0.into_iter().map(Instruction::::from).collect()) + } +} + +impl Instruction { + pub fn into(self) -> Instruction { + Instruction::from(self) + } + pub fn from(xcm: Instruction) -> Self { + use Instruction::*; + match xcm { + WithdrawAsset(assets) => WithdrawAsset(assets), + ReserveAssetDeposited(assets) => ReserveAssetDeposited(assets), + ReceiveTeleportedAsset(assets) => ReceiveTeleportedAsset(assets), + QueryResponse { query_id, response, max_weight } => + QueryResponse { query_id, response, max_weight }, + TransferAsset { assets, beneficiary } => TransferAsset { assets, beneficiary }, + TransferReserveAsset { assets, dest, xcm } => + TransferReserveAsset { assets, dest, xcm }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_type, require_weight_at_most, call } => + Transact { origin_type, require_weight_at_most, call: call.into() }, + ReportError { query_id, dest, max_response_weight } => + ReportError { query_id, dest, max_response_weight }, + DepositAsset { assets, max_assets, beneficiary } => + DepositAsset { assets, max_assets, beneficiary }, + DepositReserveAsset { assets, max_assets, dest, xcm } => + DepositReserveAsset { assets, max_assets, dest, xcm }, + ExchangeAsset { give, receive } => ExchangeAsset { give, receive }, + InitiateReserveWithdraw { assets, reserve, xcm } => + InitiateReserveWithdraw { assets, reserve, xcm }, + InitiateTeleport { assets, dest, xcm } => InitiateTeleport { assets, dest, xcm }, + QueryHolding { query_id, dest, assets, max_response_weight } => + QueryHolding { query_id, dest, assets, max_response_weight }, + BuyExecution { fees, weight_limit } => BuyExecution { fees, weight_limit }, + ClearOrigin => ClearOrigin, + DescendOrigin(who) => DescendOrigin(who), + RefundSurplus => RefundSurplus, + SetErrorHandler(xcm) => SetErrorHandler(xcm.into()), + SetAppendix(xcm) => SetAppendix(xcm.into()), + ClearError => ClearError, + ClaimAsset { assets, ticket } => ClaimAsset { assets, ticket }, + Trap(code) => Trap(code), + SubscribeVersion { query_id, max_response_weight } => + SubscribeVersion { query_id, max_response_weight }, + UnsubscribeVersion => UnsubscribeVersion, + } + } +} + +// TODO: Automate Generation +impl> GetWeight for Instruction { + fn weight(&self) -> sp_weights::Weight { + use Instruction::*; + match self { + WithdrawAsset(assets) => sp_weights::Weight::from_parts(W::withdraw_asset(assets), 0), + ReserveAssetDeposited(assets) => + sp_weights::Weight::from_parts(W::reserve_asset_deposited(assets), 0), + ReceiveTeleportedAsset(assets) => + sp_weights::Weight::from_parts(W::receive_teleported_asset(assets), 0), + QueryResponse { query_id, response, max_weight } => + sp_weights::Weight::from_parts(W::query_response(query_id, response, max_weight), 0), + TransferAsset { assets, beneficiary } => + sp_weights::Weight::from_parts(W::transfer_asset(assets, beneficiary), 0), + TransferReserveAsset { assets, dest, xcm } => + sp_weights::Weight::from_parts(W::transfer_reserve_asset(&assets, dest, xcm), 0), + Transact { origin_type, require_weight_at_most, call } => + sp_weights::Weight::from_parts( + W::transact(origin_type, require_weight_at_most, call), + 0, + ), + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + sp_weights::Weight::from_parts( + W::hrmp_new_channel_open_request(sender, max_message_size, max_capacity), + 0, + ), + HrmpChannelAccepted { recipient } => + sp_weights::Weight::from_parts(W::hrmp_channel_accepted(recipient), 0), + HrmpChannelClosing { initiator, sender, recipient } => sp_weights::Weight::from_parts( + W::hrmp_channel_closing(initiator, sender, recipient), + 0, + ), + ClearOrigin => sp_weights::Weight::from_parts(W::clear_origin(), 0), + DescendOrigin(who) => sp_weights::Weight::from_parts(W::descend_origin(who), 0), + ReportError { query_id, dest, max_response_weight } => sp_weights::Weight::from_parts( + W::report_error(query_id, dest, max_response_weight), + 0, + ), + DepositAsset { assets, max_assets, beneficiary } => + sp_weights::Weight::from_parts(W::deposit_asset(assets, max_assets, beneficiary), 0), + DepositReserveAsset { assets, max_assets, dest, xcm } => + sp_weights::Weight::from_parts( + W::deposit_reserve_asset(assets, max_assets, dest, xcm), + 0, + ), + ExchangeAsset { give, receive } => + sp_weights::Weight::from_parts(W::exchange_asset(give, receive), 0), + InitiateReserveWithdraw { assets, reserve, xcm } => sp_weights::Weight::from_parts( + W::initiate_reserve_withdraw(assets, reserve, xcm), + 0, + ), + InitiateTeleport { assets, dest, xcm } => + sp_weights::Weight::from_parts(W::initiate_teleport(assets, dest, xcm), 0), + QueryHolding { query_id, dest, assets, max_response_weight } => + sp_weights::Weight::from_parts( + W::query_holding(query_id, dest, assets, max_response_weight), + 0, + ), + BuyExecution { fees, weight_limit } => + sp_weights::Weight::from_parts(W::buy_execution(fees, weight_limit), 0), + RefundSurplus => sp_weights::Weight::from_parts(W::refund_surplus(), 0), + SetErrorHandler(xcm) => sp_weights::Weight::from_parts(W::set_error_handler(xcm), 0), + SetAppendix(xcm) => sp_weights::Weight::from_parts(W::set_appendix(xcm), 0), + ClearError => sp_weights::Weight::from_parts(W::clear_error(), 0), + ClaimAsset { assets, ticket } => + sp_weights::Weight::from_parts(W::claim_asset(assets, ticket), 0), + Trap(code) => sp_weights::Weight::from_parts(W::trap(code), 0), + SubscribeVersion { query_id, max_response_weight } => sp_weights::Weight::from_parts( + W::subscribe_version(query_id, max_response_weight), + 0, + ), + UnsubscribeVersion => sp_weights::Weight::from_parts(W::unsubscribe_version(), 0), + } + } +} + +pub mod opaque { + /// The basic concrete type of `Xcm`, which doesn't make any assumptions about the + /// format of a call other than it is pre-encoded. + pub type Xcm = super::Xcm<()>; + + /// The basic concrete type of `Instruction`, which doesn't make any assumptions about the + /// format of a call other than it is pre-encoded. + pub type Instruction = super::Instruction<()>; +} + +// Convert from a v3 response to a v2 response +impl TryFrom for Response { + type Error = (); + fn try_from(response: NewResponse) -> result::Result { + Ok(match response { + NewResponse::Assets(assets) => Self::Assets(assets.try_into()?), + NewResponse::Version(version) => Self::Version(version), + NewResponse::ExecutionResult(error) => Self::ExecutionResult(match error { + Some((i, e)) => Some((i, e.try_into()?)), + None => None, + }), + NewResponse::Null => Self::Null, + _ => return Err(()), + }) + } +} + +// Convert from a v3 XCM to a v2 XCM. +impl TryFrom> for Xcm { + type Error = (); + fn try_from(new_xcm: NewXcm) -> result::Result { + Ok(Xcm(new_xcm.0.into_iter().map(TryInto::try_into).collect::>()?)) + } +} + +// Convert from a v3 instruction to a v2 instruction +impl TryFrom> for Instruction { + type Error = (); + fn try_from(instruction: NewInstruction) -> result::Result { + use NewInstruction::*; + Ok(match instruction { + WithdrawAsset(assets) => Self::WithdrawAsset(assets.try_into()?), + ReserveAssetDeposited(assets) => Self::ReserveAssetDeposited(assets.try_into()?), + ReceiveTeleportedAsset(assets) => Self::ReceiveTeleportedAsset(assets.try_into()?), + QueryResponse { query_id, response, max_weight, .. } => Self::QueryResponse { + query_id, + response: response.try_into()?, + max_weight: max_weight.ref_time(), + }, + TransferAsset { assets, beneficiary } => Self::TransferAsset { + assets: assets.try_into()?, + beneficiary: beneficiary.try_into()?, + }, + TransferReserveAsset { assets, dest, xcm } => Self::TransferReserveAsset { + assets: assets.try_into()?, + dest: dest.try_into()?, + xcm: xcm.try_into()?, + }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + Self::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => Self::HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + Self::HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_kind, require_weight_at_most, call } => Self::Transact { + origin_type: origin_kind, + require_weight_at_most: require_weight_at_most.ref_time(), + call: call.into(), + }, + ReportError(response_info) => Self::ReportError { + query_id: response_info.query_id, + dest: response_info.destination.try_into()?, + max_response_weight: response_info.max_weight.ref_time(), + }, + DepositAsset { assets, beneficiary } => { + let max_assets = assets.count().ok_or(())?; + let beneficiary = beneficiary.try_into()?; + let assets = assets.try_into()?; + Self::DepositAsset { assets, max_assets, beneficiary } + }, + DepositReserveAsset { assets, dest, xcm } => { + let max_assets = assets.count().ok_or(())?; + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + let assets = assets.try_into()?; + Self::DepositReserveAsset { assets, max_assets, dest, xcm } + }, + ExchangeAsset { give, want, .. } => { + let give = give.try_into()?; + let receive = want.try_into()?; + Self::ExchangeAsset { give, receive } + }, + InitiateReserveWithdraw { assets, reserve, xcm } => { + // No `max_assets` here, so if there's a connt, then we cannot translate. + let assets = assets.try_into()?; + let reserve = reserve.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateReserveWithdraw { assets, reserve, xcm } + }, + InitiateTeleport { assets, dest, xcm } => { + // No `max_assets` here, so if there's a connt, then we cannot translate. + let assets = assets.try_into()?; + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateTeleport { assets, dest, xcm } + }, + ReportHolding { response_info, assets } => Self::QueryHolding { + query_id: response_info.query_id, + dest: response_info.destination.try_into()?, + assets: assets.try_into()?, + max_response_weight: response_info.max_weight.ref_time(), + }, + BuyExecution { fees, weight_limit } => { + let fees = fees.try_into()?; + let weight_limit = weight_limit.try_into()?; + Self::BuyExecution { fees, weight_limit } + }, + ClearOrigin => Self::ClearOrigin, + DescendOrigin(who) => Self::DescendOrigin(who.try_into()?), + RefundSurplus => Self::RefundSurplus, + SetErrorHandler(xcm) => Self::SetErrorHandler(xcm.try_into()?), + SetAppendix(xcm) => Self::SetAppendix(xcm.try_into()?), + ClearError => Self::ClearError, + ClaimAsset { assets, ticket } => { + let assets = assets.try_into()?; + let ticket = ticket.try_into()?; + Self::ClaimAsset { assets, ticket } + }, + Trap(code) => Self::Trap(code), + SubscribeVersion { query_id, max_response_weight } => Self::SubscribeVersion { + query_id, + max_response_weight: max_response_weight.ref_time(), + }, + UnsubscribeVersion => Self::UnsubscribeVersion, + _ => return Err(()), + }) + } +} diff --git a/polkadot/xcm/src/v2/multiasset.rs b/polkadot/xcm/src/v2/multiasset.rs new file mode 100644 index 0000000000000000000000000000000000000000..fdd7797a123049132452e692f8aa3dfe1829d1d5 --- /dev/null +++ b/polkadot/xcm/src/v2/multiasset.rs @@ -0,0 +1,618 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// 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 Polkadot. If not, see . + +//! Cross-Consensus Message format asset data structures. +//! +//! This encompasses four types for representing assets: +//! - `MultiAsset`: A description of a single asset, either an instance of a non-fungible or some +//! amount of a fungible. +//! - `MultiAssets`: A collection of `MultiAsset`s. These are stored in a `Vec` and sorted with +//! fungibles first. +//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific +//! kind. +//! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently +//! filtering an XCM holding account. + +use super::MultiLocation; +use crate::v3::{ + AssetId as NewAssetId, AssetInstance as NewAssetInstance, Fungibility as NewFungibility, + MultiAsset as NewMultiAsset, MultiAssetFilter as NewMultiAssetFilter, + MultiAssets as NewMultiAssets, WildFungibility as NewWildFungibility, + WildMultiAsset as NewWildMultiAsset, +}; +use alloc::{vec, vec::Vec}; +use core::cmp::Ordering; +use parity_scale_codec::{self as codec, Decode, Encode}; +use scale_info::TypeInfo; + +/// A general identifier for an instance of a non-fungible asset class. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum AssetInstance { + /// Undefined - used if the non-fungible asset class has only one instance. + Undefined, + + /// A compact index. Technically this could be greater than `u128`, but this implementation + /// supports only values up to `2**128 - 1`. + Index(#[codec(compact)] u128), + + /// A 4-byte fixed-length datum. + Array4([u8; 4]), + + /// An 8-byte fixed-length datum. + Array8([u8; 8]), + + /// A 16-byte fixed-length datum. + Array16([u8; 16]), + + /// A 32-byte fixed-length datum. + Array32([u8; 32]), + + /// An arbitrary piece of data. Use only when necessary. + Blob(Vec), +} + +impl From<()> for AssetInstance { + fn from(_: ()) -> Self { + Self::Undefined + } +} + +impl From<[u8; 4]> for AssetInstance { + fn from(x: [u8; 4]) -> Self { + Self::Array4(x) + } +} + +impl From<[u8; 8]> for AssetInstance { + fn from(x: [u8; 8]) -> Self { + Self::Array8(x) + } +} + +impl From<[u8; 16]> for AssetInstance { + fn from(x: [u8; 16]) -> Self { + Self::Array16(x) + } +} + +impl From<[u8; 32]> for AssetInstance { + fn from(x: [u8; 32]) -> Self { + Self::Array32(x) + } +} + +impl From> for AssetInstance { + fn from(x: Vec) -> Self { + Self::Blob(x) + } +} + +impl TryFrom for AssetInstance { + type Error = (); + fn try_from(value: NewAssetInstance) -> Result { + use NewAssetInstance::*; + Ok(match value { + Undefined => Self::Undefined, + Index(n) => Self::Index(n), + Array4(n) => Self::Array4(n), + Array8(n) => Self::Array8(n), + Array16(n) => Self::Array16(n), + Array32(n) => Self::Array32(n), + }) + } +} + +/// Classification of an asset being concrete or abstract. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum AssetId { + Concrete(MultiLocation), + Abstract(Vec), +} + +impl> From for AssetId { + fn from(x: T) -> Self { + Self::Concrete(x.into()) + } +} + +impl From> for AssetId { + fn from(x: Vec) -> Self { + Self::Abstract(x) + } +} + +impl TryFrom for AssetId { + type Error = (); + fn try_from(old: NewAssetId) -> Result { + use NewAssetId::*; + Ok(match old { + Concrete(l) => Self::Concrete(l.try_into()?), + Abstract(v) => { + let zeroes = v.iter().rev().position(|n| *n != 0).unwrap_or(v.len()); + Self::Abstract(v[0..(32 - zeroes)].to_vec()) + }, + }) + } +} + +impl AssetId { + /// Prepend a `MultiLocation` to a concrete asset, giving it a new root location. + pub fn prepend_with(&mut self, prepend: &MultiLocation) -> Result<(), ()> { + if let AssetId::Concrete(ref mut l) = self { + l.prepend_with(prepend.clone()).map_err(|_| ())?; + } + Ok(()) + } + + /// Mutate the asset to represent the same value from the perspective of a new `target` + /// location. The local chain's location is provided in `ancestry`. + pub fn reanchor(&mut self, target: &MultiLocation, ancestry: &MultiLocation) -> Result<(), ()> { + if let AssetId::Concrete(ref mut l) = self { + l.reanchor(target, ancestry)?; + } + Ok(()) + } + + /// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding + /// `MultiAsset` value. + pub fn into_multiasset(self, fun: Fungibility) -> MultiAsset { + MultiAsset { fun, id: self } + } + + /// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding + /// `WildMultiAsset` wildcard (`AllOf`) value. + pub fn into_wild(self, fun: WildFungibility) -> WildMultiAsset { + WildMultiAsset::AllOf { fun, id: self } + } +} + +/// Classification of whether an asset is fungible or not, along with a mandatory amount or +/// instance. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum Fungibility { + Fungible(#[codec(compact)] u128), + NonFungible(AssetInstance), +} + +impl Fungibility { + pub fn is_kind(&self, w: WildFungibility) -> bool { + use Fungibility::*; + use WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible}; + matches!((self, w), (Fungible(_), WildFungible) | (NonFungible(_), WildNonFungible)) + } +} + +impl From for Fungibility { + fn from(amount: u128) -> Fungibility { + debug_assert_ne!(amount, 0); + Fungibility::Fungible(amount) + } +} + +impl> From for Fungibility { + fn from(instance: T) -> Fungibility { + Fungibility::NonFungible(instance.into()) + } +} + +impl TryFrom for Fungibility { + type Error = (); + fn try_from(value: NewFungibility) -> Result { + use NewFungibility::*; + Ok(match value { + Fungible(n) => Self::Fungible(n), + NonFungible(i) => Self::NonFungible(i.try_into()?), + }) + } +} + +#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct MultiAsset { + pub id: AssetId, + pub fun: Fungibility, +} + +impl PartialOrd for MultiAsset { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for MultiAsset { + fn cmp(&self, other: &Self) -> Ordering { + match (&self.fun, &other.fun) { + (Fungibility::Fungible(..), Fungibility::NonFungible(..)) => Ordering::Less, + (Fungibility::NonFungible(..), Fungibility::Fungible(..)) => Ordering::Greater, + _ => (&self.id, &self.fun).cmp(&(&other.id, &other.fun)), + } + } +} + +impl, B: Into> From<(A, B)> for MultiAsset { + fn from((id, fun): (A, B)) -> MultiAsset { + MultiAsset { fun: fun.into(), id: id.into() } + } +} + +impl MultiAsset { + pub fn is_fungible(&self, maybe_id: Option) -> bool { + use Fungibility::*; + matches!(self.fun, Fungible(..)) && maybe_id.map_or(true, |i| i == self.id) + } + + pub fn is_non_fungible(&self, maybe_id: Option) -> bool { + use Fungibility::*; + matches!(self.fun, NonFungible(..)) && maybe_id.map_or(true, |i| i == self.id) + } + + /// Prepend a `MultiLocation` to a concrete asset, giving it a new root location. + pub fn prepend_with(&mut self, prepend: &MultiLocation) -> Result<(), ()> { + self.id.prepend_with(prepend) + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `ancestry`. + pub fn reanchor(&mut self, target: &MultiLocation, ancestry: &MultiLocation) -> Result<(), ()> { + self.id.reanchor(target, ancestry) + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `ancestry`. + pub fn reanchored( + mut self, + target: &MultiLocation, + ancestry: &MultiLocation, + ) -> Result { + self.id.reanchor(target, ancestry)?; + Ok(self) + } + + /// Returns true if `self` is a super-set of the given `inner`. + pub fn contains(&self, inner: &MultiAsset) -> bool { + use Fungibility::*; + if self.id == inner.id { + match (&self.fun, &inner.fun) { + (Fungible(a), Fungible(i)) if a >= i => return true, + (NonFungible(a), NonFungible(i)) if a == i => return true, + _ => (), + } + } + false + } +} + +impl TryFrom for MultiAsset { + type Error = (); + fn try_from(new: NewMultiAsset) -> Result { + Ok(Self { id: new.id.try_into()?, fun: new.fun.try_into()? }) + } +} + +/// A `Vec` of `MultiAsset`s. There may be no duplicate fungible items in here and when decoding, +/// they must be sorted. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct MultiAssets(Vec); + +impl Decode for MultiAssets { + fn decode(input: &mut I) -> Result { + Self::from_sorted_and_deduplicated(Vec::::decode(input)?) + .map_err(|()| "Out of order".into()) + } +} + +impl TryFrom for MultiAssets { + type Error = (); + fn try_from(new: NewMultiAssets) -> Result { + let v = new + .into_inner() + .into_iter() + .map(MultiAsset::try_from) + .collect::, ()>>()?; + Ok(MultiAssets(v)) + } +} + +impl From> for MultiAssets { + fn from(mut assets: Vec) -> Self { + let mut res = Vec::with_capacity(assets.len()); + if !assets.is_empty() { + assets.sort(); + let mut iter = assets.into_iter(); + if let Some(first) = iter.next() { + let last = iter.fold(first, |a, b| -> MultiAsset { + match (a, b) { + ( + MultiAsset { fun: Fungibility::Fungible(a_amount), id: a_id }, + MultiAsset { fun: Fungibility::Fungible(b_amount), id: b_id }, + ) if a_id == b_id => MultiAsset { + id: a_id, + fun: Fungibility::Fungible(a_amount.saturating_add(b_amount)), + }, + ( + MultiAsset { fun: Fungibility::NonFungible(a_instance), id: a_id }, + MultiAsset { fun: Fungibility::NonFungible(b_instance), id: b_id }, + ) if a_id == b_id && a_instance == b_instance => + MultiAsset { fun: Fungibility::NonFungible(a_instance), id: a_id }, + (to_push, to_remember) => { + res.push(to_push); + to_remember + }, + } + }); + res.push(last); + } + } + Self(res) + } +} + +impl> From for MultiAssets { + fn from(x: T) -> Self { + Self(vec![x.into()]) + } +} + +impl MultiAssets { + /// A new (empty) value. + pub fn new() -> Self { + Self(Vec::new()) + } + + /// Create a new instance of `MultiAssets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// Returns `Ok` if the operation succeeds and `Err` if `r` is out of order or had duplicates. + /// If you can't guarantee that `r` is sorted and deduplicated, then use + /// `From::>::from` which is infallible. + pub fn from_sorted_and_deduplicated(r: Vec) -> Result { + if r.is_empty() { + return Ok(Self(Vec::new())) + } + r.iter().skip(1).try_fold(&r[0], |a, b| -> Result<&MultiAsset, ()> { + if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) { + Ok(b) + } else { + Err(()) + } + })?; + Ok(Self(r)) + } + + /// Create a new instance of `MultiAssets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// In release mode, this skips any checks to ensure that `r` is correct, making it a + /// negligible-cost operation. Generally though you should avoid using it unless you have a + /// strict proof that `r` is valid. + #[cfg(test)] + pub fn from_sorted_and_deduplicated_skip_checks(r: Vec) -> Self { + Self::from_sorted_and_deduplicated(r).expect("Invalid input r is not sorted/deduped") + } + /// Create a new instance of `MultiAssets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// In release mode, this skips any checks to ensure that `r` is correct, making it a + /// negligible-cost operation. Generally though you should avoid using it unless you have a + /// strict proof that `r` is valid. + /// + /// In test mode, this checks anyway and panics on fail. + #[cfg(not(test))] + pub fn from_sorted_and_deduplicated_skip_checks(r: Vec) -> Self { + Self(r) + } + + /// Add some asset onto the list, saturating. This is quite a laborious operation since it + /// maintains the ordering. + pub fn push(&mut self, a: MultiAsset) { + if let Fungibility::Fungible(ref amount) = a.fun { + for asset in self.0.iter_mut().filter(|x| x.id == a.id) { + if let Fungibility::Fungible(ref mut balance) = asset.fun { + *balance = balance.saturating_add(*amount); + return + } + } + } + self.0.push(a); + self.0.sort(); + } + + /// Returns `true` if this definitely represents no asset. + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + + /// Returns true if `self` is a super-set of the given `inner`. + pub fn contains(&self, inner: &MultiAsset) -> bool { + self.0.iter().any(|i| i.contains(inner)) + } + + /// Consume `self` and return the inner vec. + pub fn drain(self) -> Vec { + self.0 + } + + /// Return a reference to the inner vec. + pub fn inner(&self) -> &Vec { + &self.0 + } + + /// Return the number of distinct asset instances contained. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Prepend a `MultiLocation` to any concrete asset items, giving it a new root location. + pub fn prepend_with(&mut self, prefix: &MultiLocation) -> Result<(), ()> { + self.0.iter_mut().try_for_each(|i| i.prepend_with(prefix)) + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `ancestry`. + pub fn reanchor(&mut self, target: &MultiLocation, ancestry: &MultiLocation) -> Result<(), ()> { + self.0.iter_mut().try_for_each(|i| i.reanchor(target, ancestry)) + } + + /// Return a reference to an item at a specific index or `None` if it doesn't exist. + pub fn get(&self, index: usize) -> Option<&MultiAsset> { + self.0.get(index) + } +} + +/// Classification of whether an asset is fungible or not. +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum WildFungibility { + Fungible, + NonFungible, +} + +impl TryFrom for WildFungibility { + type Error = (); + fn try_from(value: NewWildFungibility) -> Result { + use NewWildFungibility::*; + Ok(match value { + Fungible => Self::Fungible, + NonFungible => Self::NonFungible, + }) + } +} + +/// A wildcard representing a set of assets. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum WildMultiAsset { + /// All assets in the holding register, up to `usize` individual assets (different instances of + /// non-fungibles could be separate assets). + All, + /// All assets in the holding register of a given fungibility and ID. If operating on + /// non-fungibles, then a limit is provided for the maximum amount of matching instances. + AllOf { id: AssetId, fun: WildFungibility }, +} + +impl WildMultiAsset { + /// Returns true if `self` is a super-set of the given `inner`. + /// + /// Typically, any wildcard is never contained in anything else, and a wildcard can contain any + /// other non-wildcard. For more details, see the implementation and tests. + pub fn contains(&self, inner: &MultiAsset) -> bool { + use WildMultiAsset::*; + match self { + AllOf { fun, id } => inner.fun.is_kind(*fun) && &inner.id == id, + All => true, + } + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `ancestry`. + pub fn reanchor(&mut self, target: &MultiLocation, ancestry: &MultiLocation) -> Result<(), ()> { + use WildMultiAsset::*; + match self { + AllOf { ref mut id, .. } => id.reanchor(target, ancestry).map_err(|_| ()), + All => Ok(()), + } + } +} + +impl, B: Into> From<(A, B)> for WildMultiAsset { + fn from((id, fun): (A, B)) -> WildMultiAsset { + WildMultiAsset::AllOf { fun: fun.into(), id: id.into() } + } +} + +/// `MultiAsset` collection, either `MultiAssets` or a single wildcard. +/// +/// Note: Vectors of wildcards whose encoding is supported in XCM v0 are unsupported +/// in this implementation and will result in a decode error. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum MultiAssetFilter { + Definite(MultiAssets), + Wild(WildMultiAsset), +} + +impl> From for MultiAssetFilter { + fn from(x: T) -> Self { + Self::Wild(x.into()) + } +} + +impl From for MultiAssetFilter { + fn from(x: MultiAsset) -> Self { + Self::Definite(vec![x].into()) + } +} + +impl From> for MultiAssetFilter { + fn from(x: Vec) -> Self { + Self::Definite(x.into()) + } +} + +impl From for MultiAssetFilter { + fn from(x: MultiAssets) -> Self { + Self::Definite(x) + } +} + +impl MultiAssetFilter { + /// Returns true if `self` is a super-set of the given `inner`. + /// + /// Typically, any wildcard is never contained in anything else, and a wildcard can contain any + /// other non-wildcard. For more details, see the implementation and tests. + pub fn contains(&self, inner: &MultiAsset) -> bool { + match self { + MultiAssetFilter::Definite(ref assets) => assets.contains(inner), + MultiAssetFilter::Wild(ref wild) => wild.contains(inner), + } + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `ancestry`. + pub fn reanchor(&mut self, target: &MultiLocation, ancestry: &MultiLocation) -> Result<(), ()> { + match self { + MultiAssetFilter::Definite(ref mut assets) => assets.reanchor(target, ancestry), + MultiAssetFilter::Wild(ref mut wild) => wild.reanchor(target, ancestry), + } + } +} + +impl TryFrom for WildMultiAsset { + type Error = (); + fn try_from(new: NewWildMultiAsset) -> Result { + use NewWildMultiAsset::*; + Ok(match new { + AllOf { id, fun } | AllOfCounted { id, fun, .. } => + Self::AllOf { id: id.try_into()?, fun: fun.try_into()? }, + All | AllCounted(_) => Self::All, + }) + } +} + +impl TryFrom for MultiAssetFilter { + type Error = (); + fn try_from(old: NewMultiAssetFilter) -> Result { + use NewMultiAssetFilter::*; + Ok(match old { + Definite(x) => Self::Definite(x.try_into()?), + Wild(x) => Self::Wild(x.try_into()?), + }) + } +} diff --git a/polkadot/xcm/src/v2/multilocation.rs b/polkadot/xcm/src/v2/multilocation.rs new file mode 100644 index 0000000000000000000000000000000000000000..9fb74e8afb35b59ad6231e7d7c8b86b19a537f45 --- /dev/null +++ b/polkadot/xcm/src/v2/multilocation.rs @@ -0,0 +1,1110 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Cross-Consensus Message format data structures. + +use super::Junction; +use crate::v3::MultiLocation as NewMultiLocation; +use core::{mem, result}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// A relative path between state-bearing consensus systems. +/// +/// A location in a consensus system is defined as an *isolatable state machine* held within global +/// consensus. The location in question need not have a sophisticated consensus algorithm of its +/// own; a single account within Ethereum, for example, could be considered a location. +/// +/// A very-much non-exhaustive list of types of location include: +/// - A (normal, layer-1) block chain, e.g. the Bitcoin mainnet or a parachain. +/// - A layer-0 super-chain, e.g. the Polkadot Relay chain. +/// - A layer-2 smart contract, e.g. an ERC-20 on Ethereum. +/// - A logical functional component of a chain, e.g. a single instance of a pallet on a Frame-based +/// Substrate chain. +/// - An account. +/// +/// A `MultiLocation` is a *relative identifier*, meaning that it can only be used to define the +/// relative path between two locations, and cannot generally be used to refer to a location +/// universally. It is comprised of an integer number of parents specifying the number of times to +/// "escape" upwards into the containing consensus system and then a number of *junctions*, each +/// diving down and specifying some interior portion of state (which may be considered a +/// "sub-consensus" system). +/// +/// This specific `MultiLocation` implementation uses a `Junctions` datatype which is a Rust `enum` +/// in order to make pattern matching easier. There are occasions where it is important to ensure +/// that a value is strictly an interior location, in those cases, `Junctions` may be used. +/// +/// The `MultiLocation` value of `Null` simply refers to the interpreting consensus system. +#[derive(Clone, Decode, Encode, Eq, PartialEq, Ord, PartialOrd, Debug, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct MultiLocation { + /// The number of parent junctions at the beginning of this `MultiLocation`. + pub parents: u8, + /// The interior (i.e. non-parent) junctions that this `MultiLocation` contains. + pub interior: Junctions, +} + +impl Default for MultiLocation { + fn default() -> Self { + Self { parents: 0, interior: Junctions::Here } + } +} + +/// A relative location which is constrained to be an interior location of the context. +/// +/// See also `MultiLocation`. +pub type InteriorMultiLocation = Junctions; + +impl MultiLocation { + /// Creates a new `MultiLocation` with the given number of parents and interior junctions. + pub fn new(parents: u8, junctions: Junctions) -> MultiLocation { + MultiLocation { parents, interior: junctions } + } + + /// Consume `self` and return the equivalent `VersionedMultiLocation` value. + pub fn versioned(self) -> crate::VersionedMultiLocation { + self.into() + } + + /// Creates a new `MultiLocation` with 0 parents and a `Here` interior. + /// + /// The resulting `MultiLocation` can be interpreted as the "current consensus system". + pub const fn here() -> MultiLocation { + MultiLocation { parents: 0, interior: Junctions::Here } + } + + /// Creates a new `MultiLocation` which evaluates to the parent context. + pub const fn parent() -> MultiLocation { + MultiLocation { parents: 1, interior: Junctions::Here } + } + + /// Creates a new `MultiLocation` which evaluates to the grand parent context. + pub const fn grandparent() -> MultiLocation { + MultiLocation { parents: 2, interior: Junctions::Here } + } + + /// Creates a new `MultiLocation` with `parents` and an empty (`Here`) interior. + pub const fn ancestor(parents: u8) -> MultiLocation { + MultiLocation { parents, interior: Junctions::Here } + } + + /// Whether the `MultiLocation` has no parents and has a `Here` interior. + pub const fn is_here(&self) -> bool { + self.parents == 0 && self.interior.len() == 0 + } + + /// Return a reference to the interior field. + pub fn interior(&self) -> &Junctions { + &self.interior + } + + /// Return a mutable reference to the interior field. + pub fn interior_mut(&mut self) -> &mut Junctions { + &mut self.interior + } + + /// Returns the number of `Parent` junctions at the beginning of `self`. + pub const fn parent_count(&self) -> u8 { + self.parents + } + + /// Returns boolean indicating whether `self` contains only the specified amount of + /// parents and no interior junctions. + pub const fn contains_parents_only(&self, count: u8) -> bool { + matches!(self.interior, Junctions::Here) && self.parents == count + } + + /// Returns the number of parents and junctions in `self`. + pub const fn len(&self) -> usize { + self.parent_count() as usize + self.interior.len() + } + + /// Returns the first interior junction, or `None` if the location is empty or contains only + /// parents. + pub fn first_interior(&self) -> Option<&Junction> { + self.interior.first() + } + + /// Returns last junction, or `None` if the location is empty or contains only parents. + pub fn last(&self) -> Option<&Junction> { + self.interior.last() + } + + /// Splits off the first interior junction, returning the remaining suffix (first item in tuple) + /// and the first element (second item in tuple) or `None` if it was empty. + pub fn split_first_interior(self) -> (MultiLocation, Option) { + let MultiLocation { parents, interior: junctions } = self; + let (suffix, first) = junctions.split_first(); + let multilocation = MultiLocation { parents, interior: suffix }; + (multilocation, first) + } + + /// Splits off the last interior junction, returning the remaining prefix (first item in tuple) + /// and the last element (second item in tuple) or `None` if it was empty or if `self` only + /// contains parents. + pub fn split_last_interior(self) -> (MultiLocation, Option) { + let MultiLocation { parents, interior: junctions } = self; + let (prefix, last) = junctions.split_last(); + let multilocation = MultiLocation { parents, interior: prefix }; + (multilocation, last) + } + + /// Mutates `self`, suffixing its interior junctions with `new`. Returns `Err` with `new` in + /// case of overflow. + pub fn push_interior(&mut self, new: Junction) -> result::Result<(), Junction> { + self.interior.push(new) + } + + /// Mutates `self`, prefixing its interior junctions with `new`. Returns `Err` with `new` in + /// case of overflow. + pub fn push_front_interior(&mut self, new: Junction) -> result::Result<(), Junction> { + self.interior.push_front(new) + } + + /// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with + /// theoriginal value of `self` in case of overflow. + pub fn pushed_with_interior(self, new: Junction) -> result::Result { + match self.interior.pushed_with(new) { + Ok(i) => Ok(MultiLocation { interior: i, parents: self.parents }), + Err((i, j)) => Err((MultiLocation { interior: i, parents: self.parents }, j)), + } + } + + /// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the + /// original value of `self` in case of overflow. + pub fn pushed_front_with_interior( + self, + new: Junction, + ) -> result::Result { + match self.interior.pushed_front_with(new) { + Ok(i) => Ok(MultiLocation { interior: i, parents: self.parents }), + Err((i, j)) => Err((MultiLocation { interior: i, parents: self.parents }, j)), + } + } + + /// Returns the junction at index `i`, or `None` if the location is a parent or if the location + /// does not contain that many elements. + pub fn at(&self, i: usize) -> Option<&Junction> { + let num_parents = self.parents as usize; + if i < num_parents { + return None + } + self.interior.at(i - num_parents) + } + + /// Returns a mutable reference to the junction at index `i`, or `None` if the location is a + /// parent or if it doesn't contain that many elements. + pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> { + let num_parents = self.parents as usize; + if i < num_parents { + return None + } + self.interior.at_mut(i - num_parents) + } + + /// Decrements the parent count by 1. + pub fn dec_parent(&mut self) { + self.parents = self.parents.saturating_sub(1); + } + + /// Removes the first interior junction from `self`, returning it + /// (or `None` if it was empty or if `self` contains only parents). + pub fn take_first_interior(&mut self) -> Option { + self.interior.take_first() + } + + /// Removes the last element from `interior`, returning it (or `None` if it was empty or if + /// `self` only contains parents). + pub fn take_last(&mut self) -> Option { + self.interior.take_last() + } + + /// Ensures that `self` has the same number of parents as `prefix`, its junctions begins with + /// the junctions of `prefix` and that it has a single `Junction` item following. + /// If so, returns a reference to this `Junction` item. + /// + /// # Example + /// ```rust + /// # use xcm::v2::{Junctions::*, Junction::*, MultiLocation}; + /// # fn main() { + /// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild)); + /// assert_eq!( + /// m.match_and_split(&MultiLocation::new(1, X1(PalletInstance(3)))), + /// Some(&OnlyChild), + /// ); + /// assert_eq!(m.match_and_split(&MultiLocation::new(1, Here)), None); + /// # } + /// ``` + pub fn match_and_split(&self, prefix: &MultiLocation) -> Option<&Junction> { + if self.parents != prefix.parents { + return None + } + self.interior.match_and_split(&prefix.interior) + } + + /// Returns whether `self` has the same number of parents as `prefix` and its junctions begins + /// with the junctions of `prefix`. + /// + /// # Example + /// ```rust + /// # use xcm::v2::{Junctions::*, Junction::*, MultiLocation}; + /// let m = MultiLocation::new(1, X3(PalletInstance(3), OnlyChild, OnlyChild)); + /// assert!(m.starts_with(&MultiLocation::new(1, X1(PalletInstance(3))))); + /// assert!(!m.starts_with(&MultiLocation::new(1, X1(GeneralIndex(99))))); + /// assert!(!m.starts_with(&MultiLocation::new(0, X1(PalletInstance(3))))); + /// ``` + pub fn starts_with(&self, prefix: &MultiLocation) -> bool { + if self.parents != prefix.parents { + return false + } + self.interior.starts_with(&prefix.interior) + } + + /// Mutate `self` so that it is suffixed with `suffix`. + /// + /// Does not modify `self` and returns `Err` with `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use xcm::v2::{Junctions::*, Junction::*, MultiLocation}; + /// # fn main() { + /// let mut m = MultiLocation::new(1, X1(Parachain(21))); + /// assert_eq!(m.append_with(X1(PalletInstance(3))), Ok(())); + /// assert_eq!(m, MultiLocation::new(1, X2(Parachain(21), PalletInstance(3)))); + /// # } + /// ``` + pub fn append_with(&mut self, suffix: Junctions) -> Result<(), Junctions> { + if self.interior.len().saturating_add(suffix.len()) > MAX_JUNCTIONS { + return Err(suffix) + } + for j in suffix.into_iter() { + self.interior.push(j).expect("Already checked the sum of the len()s; qed") + } + Ok(()) + } + + /// Mutate `self` so that it is prefixed with `prefix`. + /// + /// Does not modify `self` and returns `Err` with `prefix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use xcm::v2::{Junctions::*, Junction::*, MultiLocation}; + /// # fn main() { + /// let mut m = MultiLocation::new(2, X1(PalletInstance(3))); + /// assert_eq!(m.prepend_with(MultiLocation::new(1, X2(Parachain(21), OnlyChild))), Ok(())); + /// assert_eq!(m, MultiLocation::new(1, X1(PalletInstance(3)))); + /// # } + /// ``` + pub fn prepend_with(&mut self, mut prefix: MultiLocation) -> Result<(), MultiLocation> { + // prefix self (suffix) + // P .. P I .. I p .. p i .. i + let prepend_interior = prefix.interior.len().saturating_sub(self.parents as usize); + let final_interior = self.interior.len().saturating_add(prepend_interior); + if final_interior > MAX_JUNCTIONS { + return Err(prefix) + } + let suffix_parents = (self.parents as usize).saturating_sub(prefix.interior.len()); + let final_parents = (prefix.parents as usize).saturating_add(suffix_parents); + if final_parents > 255 { + return Err(prefix) + } + + // cancel out the final item on the prefix interior for one of the suffix's parents. + while self.parents > 0 && prefix.take_last().is_some() { + self.dec_parent(); + } + + // now we have either removed all suffix's parents or prefix interior. + // this means we can combine the prefix's and suffix's remaining parents/interior since + // we know that with at least one empty, the overall order will be respected: + // prefix self (suffix) + // P .. P (I) p .. p i .. i => P + p .. (no I) i + // -- or -- + // P .. P I .. I (p) i .. i => P (no p) .. I + i + + self.parents = self.parents.saturating_add(prefix.parents); + for j in prefix.interior.into_iter().rev() { + self.push_front_interior(j) + .expect("final_interior no greater than MAX_JUNCTIONS; qed"); + } + Ok(()) + } + + /// Consume `self` and return the value representing the same location from the point of view + /// of `target`. The context of `self` is provided as `ancestry`. + /// + /// Returns an `Err` with the unmodified `self` in the case of error. + pub fn reanchored( + mut self, + target: &MultiLocation, + ancestry: &MultiLocation, + ) -> Result { + match self.reanchor(target, ancestry) { + Ok(()) => Ok(self), + Err(()) => Err(self), + } + } + + /// Mutate `self` so that it represents the same location from the point of view of `target`. + /// The context of `self` is provided as `ancestry`. + /// + /// Does not modify `self` in case of overflow. + pub fn reanchor(&mut self, target: &MultiLocation, ancestry: &MultiLocation) -> Result<(), ()> { + // TODO: https://github.com/paritytech/polkadot/issues/4489 Optimize this. + + // 1. Use our `ancestry` to figure out how the `target` would address us. + let inverted_target = ancestry.inverted(target)?; + + // 2. Prepend `inverted_target` to `self` to get self's location from the perspective of + // `target`. + self.prepend_with(inverted_target).map_err(|_| ())?; + + // 3. Given that we know some of `target` ancestry, ensure that any parents in `self` are + // strictly needed. + self.simplify(target.interior()); + + Ok(()) + } + + /// Treating `self` as a context, determine how it would be referenced by a `target` location. + pub fn inverted(&self, target: &MultiLocation) -> Result { + use Junction::OnlyChild; + let mut ancestry = self.clone(); + let mut junctions = Junctions::Here; + for _ in 0..target.parent_count() { + junctions = junctions + .pushed_front_with(ancestry.interior.take_last().unwrap_or(OnlyChild)) + .map_err(|_| ())?; + } + let parents = target.interior().len() as u8; + Ok(MultiLocation::new(parents, junctions)) + } + + /// Remove any unneeded parents/junctions in `self` based on the given context it will be + /// interpreted in. + pub fn simplify(&mut self, context: &Junctions) { + if context.len() < self.parents as usize { + // Not enough context + return + } + while self.parents > 0 { + let maybe = context.at(context.len() - (self.parents as usize)); + match (self.interior.first(), maybe) { + (Some(i), Some(j)) if i == j => { + self.interior.take_first(); + self.parents -= 1; + }, + _ => break, + } + } + } +} + +impl TryFrom for MultiLocation { + type Error = (); + fn try_from(x: NewMultiLocation) -> result::Result { + Ok(MultiLocation { parents: x.parents, interior: x.interior.try_into()? }) + } +} + +/// A unit struct which can be converted into a `MultiLocation` of `parents` value 1. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Parent; +impl From for MultiLocation { + fn from(_: Parent) -> Self { + MultiLocation { parents: 1, interior: Junctions::Here } + } +} + +/// A tuple struct which can be converted into a `MultiLocation` of `parents` value 1 with the inner +/// interior. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct ParentThen(pub Junctions); +impl From for MultiLocation { + fn from(ParentThen(interior): ParentThen) -> Self { + MultiLocation { parents: 1, interior } + } +} + +/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Ancestor(pub u8); +impl From for MultiLocation { + fn from(Ancestor(parents): Ancestor) -> Self { + MultiLocation { parents, interior: Junctions::Here } + } +} + +/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value and the +/// inner interior. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct AncestorThen(pub u8, pub Interior); +impl> From> for MultiLocation { + fn from(AncestorThen(parents, interior): AncestorThen) -> Self { + MultiLocation { parents, interior: interior.into() } + } +} + +xcm_procedural::impl_conversion_functions_for_multilocation_v2!(); + +/// Maximum number of `Junction`s that a `Junctions` can contain. +const MAX_JUNCTIONS: usize = 8; + +/// Non-parent junctions that can be constructed, up to the length of 8. This specific `Junctions` +/// implementation uses a Rust `enum` in order to make pattern matching easier. +/// +/// Parent junctions cannot be constructed with this type. Refer to `MultiLocation` for +/// instructions on constructing parent junctions. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum Junctions { + /// The interpreting consensus system. + Here, + /// A relative path comprising 1 junction. + X1(Junction), + /// A relative path comprising 2 junctions. + X2(Junction, Junction), + /// A relative path comprising 3 junctions. + X3(Junction, Junction, Junction), + /// A relative path comprising 4 junctions. + X4(Junction, Junction, Junction, Junction), + /// A relative path comprising 5 junctions. + X5(Junction, Junction, Junction, Junction, Junction), + /// A relative path comprising 6 junctions. + X6(Junction, Junction, Junction, Junction, Junction, Junction), + /// A relative path comprising 7 junctions. + X7(Junction, Junction, Junction, Junction, Junction, Junction, Junction), + /// A relative path comprising 8 junctions. + X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction), +} + +pub struct JunctionsIterator(Junctions); +impl Iterator for JunctionsIterator { + type Item = Junction; + fn next(&mut self) -> Option { + self.0.take_first() + } +} + +impl DoubleEndedIterator for JunctionsIterator { + fn next_back(&mut self) -> Option { + self.0.take_last() + } +} + +pub struct JunctionsRefIterator<'a> { + junctions: &'a Junctions, + next: usize, + back: usize, +} + +impl<'a> Iterator for JunctionsRefIterator<'a> { + type Item = &'a Junction; + fn next(&mut self) -> Option<&'a Junction> { + if self.next.saturating_add(self.back) >= self.junctions.len() { + return None + } + + let result = self.junctions.at(self.next); + self.next += 1; + result + } +} + +impl<'a> DoubleEndedIterator for JunctionsRefIterator<'a> { + fn next_back(&mut self) -> Option<&'a Junction> { + let next_back = self.back.saturating_add(1); + // checked_sub here, because if the result is less than 0, we end iteration + let index = self.junctions.len().checked_sub(next_back)?; + if self.next > index { + return None + } + self.back = next_back; + + self.junctions.at(index) + } +} + +impl<'a> IntoIterator for &'a Junctions { + type Item = &'a Junction; + type IntoIter = JunctionsRefIterator<'a>; + fn into_iter(self) -> Self::IntoIter { + JunctionsRefIterator { junctions: self, next: 0, back: 0 } + } +} + +impl IntoIterator for Junctions { + type Item = Junction; + type IntoIter = JunctionsIterator; + fn into_iter(self) -> Self::IntoIter { + JunctionsIterator(self) + } +} + +impl Junctions { + /// Convert `self` into a `MultiLocation` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub const fn into(self) -> MultiLocation { + MultiLocation { parents: 0, interior: self } + } + + /// Convert `self` into a `MultiLocation` containing `n` parents. + /// + /// Similar to `Self::into`, with the added ability to specify the number of parent junctions. + pub const fn into_exterior(self, n: u8) -> MultiLocation { + MultiLocation { parents: n, interior: self } + } + + /// Returns first junction, or `None` if the location is empty. + pub fn first(&self) -> Option<&Junction> { + match &self { + Junctions::Here => None, + Junctions::X1(ref a) => Some(a), + Junctions::X2(ref a, ..) => Some(a), + Junctions::X3(ref a, ..) => Some(a), + Junctions::X4(ref a, ..) => Some(a), + Junctions::X5(ref a, ..) => Some(a), + Junctions::X6(ref a, ..) => Some(a), + Junctions::X7(ref a, ..) => Some(a), + Junctions::X8(ref a, ..) => Some(a), + } + } + + /// Returns last junction, or `None` if the location is empty. + pub fn last(&self) -> Option<&Junction> { + match &self { + Junctions::Here => None, + Junctions::X1(ref a) => Some(a), + Junctions::X2(.., ref a) => Some(a), + Junctions::X3(.., ref a) => Some(a), + Junctions::X4(.., ref a) => Some(a), + Junctions::X5(.., ref a) => Some(a), + Junctions::X6(.., ref a) => Some(a), + Junctions::X7(.., ref a) => Some(a), + Junctions::X8(.., ref a) => Some(a), + } + } + + /// Splits off the first junction, returning the remaining suffix (first item in tuple) and the + /// first element (second item in tuple) or `None` if it was empty. + pub fn split_first(self) -> (Junctions, Option) { + match self { + Junctions::Here => (Junctions::Here, None), + Junctions::X1(a) => (Junctions::Here, Some(a)), + Junctions::X2(a, b) => (Junctions::X1(b), Some(a)), + Junctions::X3(a, b, c) => (Junctions::X2(b, c), Some(a)), + Junctions::X4(a, b, c, d) => (Junctions::X3(b, c, d), Some(a)), + Junctions::X5(a, b, c, d, e) => (Junctions::X4(b, c, d, e), Some(a)), + Junctions::X6(a, b, c, d, e, f) => (Junctions::X5(b, c, d, e, f), Some(a)), + Junctions::X7(a, b, c, d, e, f, g) => (Junctions::X6(b, c, d, e, f, g), Some(a)), + Junctions::X8(a, b, c, d, e, f, g, h) => (Junctions::X7(b, c, d, e, f, g, h), Some(a)), + } + } + + /// Splits off the last junction, returning the remaining prefix (first item in tuple) and the + /// last element (second item in tuple) or `None` if it was empty. + pub fn split_last(self) -> (Junctions, Option) { + match self { + Junctions::Here => (Junctions::Here, None), + Junctions::X1(a) => (Junctions::Here, Some(a)), + Junctions::X2(a, b) => (Junctions::X1(a), Some(b)), + Junctions::X3(a, b, c) => (Junctions::X2(a, b), Some(c)), + Junctions::X4(a, b, c, d) => (Junctions::X3(a, b, c), Some(d)), + Junctions::X5(a, b, c, d, e) => (Junctions::X4(a, b, c, d), Some(e)), + Junctions::X6(a, b, c, d, e, f) => (Junctions::X5(a, b, c, d, e), Some(f)), + Junctions::X7(a, b, c, d, e, f, g) => (Junctions::X6(a, b, c, d, e, f), Some(g)), + Junctions::X8(a, b, c, d, e, f, g, h) => (Junctions::X7(a, b, c, d, e, f, g), Some(h)), + } + } + + /// Removes the first element from `self`, returning it (or `None` if it was empty). + pub fn take_first(&mut self) -> Option { + let mut d = Junctions::Here; + mem::swap(&mut *self, &mut d); + let (tail, head) = d.split_first(); + *self = tail; + head + } + + /// Removes the last element from `self`, returning it (or `None` if it was empty). + pub fn take_last(&mut self) -> Option { + let mut d = Junctions::Here; + mem::swap(&mut *self, &mut d); + let (head, tail) = d.split_last(); + *self = head; + tail + } + + /// Mutates `self` to be appended with `new` or returns an `Err` with `new` if would overflow. + pub fn push(&mut self, new: Junction) -> result::Result<(), Junction> { + let mut dummy = Junctions::Here; + mem::swap(self, &mut dummy); + match dummy.pushed_with(new) { + Ok(s) => { + *self = s; + Ok(()) + }, + Err((s, j)) => { + *self = s; + Err(j) + }, + } + } + + /// Mutates `self` to be prepended with `new` or returns an `Err` with `new` if would overflow. + pub fn push_front(&mut self, new: Junction) -> result::Result<(), Junction> { + let mut dummy = Junctions::Here; + mem::swap(self, &mut dummy); + match dummy.pushed_front_with(new) { + Ok(s) => { + *self = s; + Ok(()) + }, + Err((s, j)) => { + *self = s; + Err(j) + }, + } + } + + /// Consumes `self` and returns a `Junctions` suffixed with `new`, or an `Err` with the + /// original value of `self` and `new` in case of overflow. + pub fn pushed_with(self, new: Junction) -> result::Result { + Ok(match self { + Junctions::Here => Junctions::X1(new), + Junctions::X1(a) => Junctions::X2(a, new), + Junctions::X2(a, b) => Junctions::X3(a, b, new), + Junctions::X3(a, b, c) => Junctions::X4(a, b, c, new), + Junctions::X4(a, b, c, d) => Junctions::X5(a, b, c, d, new), + Junctions::X5(a, b, c, d, e) => Junctions::X6(a, b, c, d, e, new), + Junctions::X6(a, b, c, d, e, f) => Junctions::X7(a, b, c, d, e, f, new), + Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(a, b, c, d, e, f, g, new), + s => Err((s, new))?, + }) + } + + /// Consumes `self` and returns a `Junctions` prefixed with `new`, or an `Err` with the + /// original value of `self` and `new` in case of overflow. + pub fn pushed_front_with(self, new: Junction) -> result::Result { + Ok(match self { + Junctions::Here => Junctions::X1(new), + Junctions::X1(a) => Junctions::X2(new, a), + Junctions::X2(a, b) => Junctions::X3(new, a, b), + Junctions::X3(a, b, c) => Junctions::X4(new, a, b, c), + Junctions::X4(a, b, c, d) => Junctions::X5(new, a, b, c, d), + Junctions::X5(a, b, c, d, e) => Junctions::X6(new, a, b, c, d, e), + Junctions::X6(a, b, c, d, e, f) => Junctions::X7(new, a, b, c, d, e, f), + Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(new, a, b, c, d, e, f, g), + s => Err((s, new))?, + }) + } + + /// Returns the number of junctions in `self`. + pub const fn len(&self) -> usize { + match &self { + Junctions::Here => 0, + Junctions::X1(..) => 1, + Junctions::X2(..) => 2, + Junctions::X3(..) => 3, + Junctions::X4(..) => 4, + Junctions::X5(..) => 5, + Junctions::X6(..) => 6, + Junctions::X7(..) => 7, + Junctions::X8(..) => 8, + } + } + + /// Returns the junction at index `i`, or `None` if the location doesn't contain that many + /// elements. + pub fn at(&self, i: usize) -> Option<&Junction> { + Some(match (i, self) { + (0, Junctions::X1(ref a)) => a, + (0, Junctions::X2(ref a, ..)) => a, + (0, Junctions::X3(ref a, ..)) => a, + (0, Junctions::X4(ref a, ..)) => a, + (0, Junctions::X5(ref a, ..)) => a, + (0, Junctions::X6(ref a, ..)) => a, + (0, Junctions::X7(ref a, ..)) => a, + (0, Junctions::X8(ref a, ..)) => a, + (1, Junctions::X2(_, ref a)) => a, + (1, Junctions::X3(_, ref a, ..)) => a, + (1, Junctions::X4(_, ref a, ..)) => a, + (1, Junctions::X5(_, ref a, ..)) => a, + (1, Junctions::X6(_, ref a, ..)) => a, + (1, Junctions::X7(_, ref a, ..)) => a, + (1, Junctions::X8(_, ref a, ..)) => a, + (2, Junctions::X3(_, _, ref a)) => a, + (2, Junctions::X4(_, _, ref a, ..)) => a, + (2, Junctions::X5(_, _, ref a, ..)) => a, + (2, Junctions::X6(_, _, ref a, ..)) => a, + (2, Junctions::X7(_, _, ref a, ..)) => a, + (2, Junctions::X8(_, _, ref a, ..)) => a, + (3, Junctions::X4(_, _, _, ref a)) => a, + (3, Junctions::X5(_, _, _, ref a, ..)) => a, + (3, Junctions::X6(_, _, _, ref a, ..)) => a, + (3, Junctions::X7(_, _, _, ref a, ..)) => a, + (3, Junctions::X8(_, _, _, ref a, ..)) => a, + (4, Junctions::X5(_, _, _, _, ref a)) => a, + (4, Junctions::X6(_, _, _, _, ref a, ..)) => a, + (4, Junctions::X7(_, _, _, _, ref a, ..)) => a, + (4, Junctions::X8(_, _, _, _, ref a, ..)) => a, + (5, Junctions::X6(_, _, _, _, _, ref a)) => a, + (5, Junctions::X7(_, _, _, _, _, ref a, ..)) => a, + (5, Junctions::X8(_, _, _, _, _, ref a, ..)) => a, + (6, Junctions::X7(_, _, _, _, _, _, ref a)) => a, + (6, Junctions::X8(_, _, _, _, _, _, ref a, ..)) => a, + (7, Junctions::X8(_, _, _, _, _, _, _, ref a)) => a, + _ => return None, + }) + } + + /// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't + /// contain that many elements. + pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> { + Some(match (i, self) { + (0, Junctions::X1(ref mut a)) => a, + (0, Junctions::X2(ref mut a, ..)) => a, + (0, Junctions::X3(ref mut a, ..)) => a, + (0, Junctions::X4(ref mut a, ..)) => a, + (0, Junctions::X5(ref mut a, ..)) => a, + (0, Junctions::X6(ref mut a, ..)) => a, + (0, Junctions::X7(ref mut a, ..)) => a, + (0, Junctions::X8(ref mut a, ..)) => a, + (1, Junctions::X2(_, ref mut a)) => a, + (1, Junctions::X3(_, ref mut a, ..)) => a, + (1, Junctions::X4(_, ref mut a, ..)) => a, + (1, Junctions::X5(_, ref mut a, ..)) => a, + (1, Junctions::X6(_, ref mut a, ..)) => a, + (1, Junctions::X7(_, ref mut a, ..)) => a, + (1, Junctions::X8(_, ref mut a, ..)) => a, + (2, Junctions::X3(_, _, ref mut a)) => a, + (2, Junctions::X4(_, _, ref mut a, ..)) => a, + (2, Junctions::X5(_, _, ref mut a, ..)) => a, + (2, Junctions::X6(_, _, ref mut a, ..)) => a, + (2, Junctions::X7(_, _, ref mut a, ..)) => a, + (2, Junctions::X8(_, _, ref mut a, ..)) => a, + (3, Junctions::X4(_, _, _, ref mut a)) => a, + (3, Junctions::X5(_, _, _, ref mut a, ..)) => a, + (3, Junctions::X6(_, _, _, ref mut a, ..)) => a, + (3, Junctions::X7(_, _, _, ref mut a, ..)) => a, + (3, Junctions::X8(_, _, _, ref mut a, ..)) => a, + (4, Junctions::X5(_, _, _, _, ref mut a)) => a, + (4, Junctions::X6(_, _, _, _, ref mut a, ..)) => a, + (4, Junctions::X7(_, _, _, _, ref mut a, ..)) => a, + (4, Junctions::X8(_, _, _, _, ref mut a, ..)) => a, + (5, Junctions::X6(_, _, _, _, _, ref mut a)) => a, + (5, Junctions::X7(_, _, _, _, _, ref mut a, ..)) => a, + (5, Junctions::X8(_, _, _, _, _, ref mut a, ..)) => a, + (6, Junctions::X7(_, _, _, _, _, _, ref mut a)) => a, + (6, Junctions::X8(_, _, _, _, _, _, ref mut a, ..)) => a, + (7, Junctions::X8(_, _, _, _, _, _, _, ref mut a)) => a, + _ => return None, + }) + } + + /// Returns a reference iterator over the junctions. + pub fn iter(&self) -> JunctionsRefIterator { + JunctionsRefIterator { junctions: self, next: 0, back: 0 } + } + + /// Returns a reference iterator over the junctions in reverse. + #[deprecated(note = "Please use iter().rev()")] + pub fn iter_rev(&self) -> impl Iterator + '_ { + self.iter().rev() + } + + /// Consumes `self` and returns an iterator over the junctions in reverse. + #[deprecated(note = "Please use into_iter().rev()")] + pub fn into_iter_rev(self) -> impl Iterator { + self.into_iter().rev() + } + + /// Ensures that self begins with `prefix` and that it has a single `Junction` item following. + /// If so, returns a reference to this `Junction` item. + /// + /// # Example + /// ```rust + /// # use xcm::v2::{Junctions::*, Junction::*}; + /// # fn main() { + /// let mut m = X3(Parachain(2), PalletInstance(3), OnlyChild); + /// assert_eq!(m.match_and_split(&X2(Parachain(2), PalletInstance(3))), Some(&OnlyChild)); + /// assert_eq!(m.match_and_split(&X1(Parachain(2))), None); + /// # } + /// ``` + pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> { + if prefix.len() + 1 != self.len() || !self.starts_with(prefix) { + return None + } + self.at(prefix.len()) + } + + /// Returns whether `self` begins with or is equal to `prefix`. + /// + /// # Example + /// ```rust + /// # use xcm::v2::{Junctions::*, Junction::*}; + /// let mut j = X3(Parachain(2), PalletInstance(3), OnlyChild); + /// assert!(j.starts_with(&X2(Parachain(2), PalletInstance(3)))); + /// assert!(j.starts_with(&j)); + /// assert!(j.starts_with(&X1(Parachain(2)))); + /// assert!(!j.starts_with(&X1(Parachain(999)))); + /// assert!(!j.starts_with(&X4(Parachain(2), PalletInstance(3), OnlyChild, OnlyChild))); + /// ``` + pub fn starts_with(&self, prefix: &Junctions) -> bool { + if self.len() < prefix.len() { + return false + } + prefix.iter().zip(self.iter()).all(|(l, r)| l == r) + } +} + +impl TryFrom for Junctions { + type Error = (); + fn try_from(x: MultiLocation) -> result::Result { + if x.parents > 0 { + Err(()) + } else { + Ok(x.interior) + } + } +} + +#[cfg(test)] +mod tests { + use super::{Ancestor, AncestorThen, Junctions::*, MultiLocation, Parent, ParentThen}; + use crate::opaque::v2::{Junction::*, NetworkId::*}; + use parity_scale_codec::{Decode, Encode}; + + #[test] + fn inverted_works() { + let ancestry: MultiLocation = (Parachain(1000), PalletInstance(42)).into(); + let target = (Parent, PalletInstance(69)).into(); + let expected = (Parent, PalletInstance(42)).into(); + let inverted = ancestry.inverted(&target).unwrap(); + assert_eq!(inverted, expected); + + let ancestry: MultiLocation = (Parachain(1000), PalletInstance(42), GeneralIndex(1)).into(); + let target = (Parent, Parent, PalletInstance(69), GeneralIndex(2)).into(); + let expected = (Parent, Parent, PalletInstance(42), GeneralIndex(1)).into(); + let inverted = ancestry.inverted(&target).unwrap(); + assert_eq!(inverted, expected); + } + + #[test] + fn simplify_basic_works() { + let mut location: MultiLocation = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = X2(Parachain(1000), PalletInstance(42)); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: MultiLocation = (Parent, PalletInstance(42), GeneralIndex(69)).into(); + let context = X1(PalletInstance(42)); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: MultiLocation = (Parent, PalletInstance(42), GeneralIndex(69)).into(); + let context = X2(Parachain(1000), PalletInstance(42)); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: MultiLocation = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = X3(OnlyChild, Parachain(1000), PalletInstance(42)); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + } + + #[test] + fn simplify_incompatible_location_fails() { + let mut location: MultiLocation = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = X3(Parachain(1000), PalletInstance(42), GeneralIndex(42)); + let expected = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: MultiLocation = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = X1(Parachain(1000)); + let expected = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + location.simplify(&context); + assert_eq!(location, expected); + } + + #[test] + fn reanchor_works() { + let mut id: MultiLocation = (Parent, Parachain(1000), GeneralIndex(42)).into(); + let ancestry = Parachain(2000).into(); + let target = (Parent, Parachain(1000)).into(); + let expected = GeneralIndex(42).into(); + id.reanchor(&target, &ancestry).unwrap(); + assert_eq!(id, expected); + } + + #[test] + fn encode_and_decode_works() { + let m = MultiLocation { + parents: 1, + interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }), + }; + let encoded = m.encode(); + assert_eq!(encoded, [1, 2, 0, 168, 2, 0, 92].to_vec()); + let decoded = MultiLocation::decode(&mut &encoded[..]); + assert_eq!(decoded, Ok(m)); + } + + #[test] + fn match_and_split_works() { + let m = MultiLocation { + parents: 1, + interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }), + }; + assert_eq!(m.match_and_split(&MultiLocation { parents: 1, interior: Here }), None); + assert_eq!( + m.match_and_split(&MultiLocation { parents: 1, interior: X1(Parachain(42)) }), + Some(&AccountIndex64 { network: Any, index: 23 }) + ); + assert_eq!(m.match_and_split(&m), None); + } + + #[test] + fn starts_with_works() { + let full: MultiLocation = + (Parent, Parachain(1000), AccountId32 { network: Any, id: [0; 32] }).into(); + let identity: MultiLocation = full.clone(); + let prefix: MultiLocation = (Parent, Parachain(1000)).into(); + let wrong_parachain: MultiLocation = (Parent, Parachain(1001)).into(); + let wrong_account: MultiLocation = + (Parent, Parachain(1000), AccountId32 { network: Any, id: [1; 32] }).into(); + let no_parents: MultiLocation = (Parachain(1000)).into(); + let too_many_parents: MultiLocation = (Parent, Parent, Parachain(1000)).into(); + + assert!(full.starts_with(&identity)); + assert!(full.starts_with(&prefix)); + assert!(!full.starts_with(&wrong_parachain)); + assert!(!full.starts_with(&wrong_account)); + assert!(!full.starts_with(&no_parents)); + assert!(!full.starts_with(&too_many_parents)); + } + + #[test] + fn append_with_works() { + let acc = AccountIndex64 { network: Any, index: 23 }; + let mut m = MultiLocation { parents: 1, interior: X1(Parachain(42)) }; + assert_eq!(m.append_with(X2(PalletInstance(3), acc.clone())), Ok(())); + assert_eq!( + m, + MultiLocation { + parents: 1, + interior: X3(Parachain(42), PalletInstance(3), acc.clone()) + } + ); + + // cannot append to create overly long multilocation + let acc = AccountIndex64 { network: Any, index: 23 }; + let m = MultiLocation { + parents: 254, + interior: X5(Parachain(42), OnlyChild, OnlyChild, OnlyChild, OnlyChild), + }; + let suffix = X4(PalletInstance(3), acc.clone(), OnlyChild, OnlyChild); + assert_eq!(m.clone().append_with(suffix.clone()), Err(suffix)); + } + + #[test] + fn prepend_with_works() { + let mut m = MultiLocation { + parents: 1, + interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }), + }; + assert_eq!(m.prepend_with(MultiLocation { parents: 1, interior: X1(OnlyChild) }), Ok(())); + assert_eq!( + m, + MultiLocation { + parents: 1, + interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) + } + ); + + // cannot prepend to create overly long multilocation + let mut m = MultiLocation { parents: 254, interior: X1(Parachain(42)) }; + let prefix = MultiLocation { parents: 2, interior: Here }; + assert_eq!(m.prepend_with(prefix.clone()), Err(prefix)); + + let prefix = MultiLocation { parents: 1, interior: Here }; + assert_eq!(m.prepend_with(prefix), Ok(())); + assert_eq!(m, MultiLocation { parents: 255, interior: X1(Parachain(42)) }); + } + + #[test] + fn double_ended_ref_iteration_works() { + let m = X3(Parachain(1000), Parachain(3), PalletInstance(5)); + let mut iter = m.iter(); + + let first = iter.next().unwrap(); + assert_eq!(first, &Parachain(1000)); + let third = iter.next_back().unwrap(); + assert_eq!(third, &PalletInstance(5)); + let second = iter.next_back().unwrap(); + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + assert_eq!(second, &Parachain(3)); + + let res = Here + .pushed_with(first.clone()) + .unwrap() + .pushed_with(second.clone()) + .unwrap() + .pushed_with(third.clone()) + .unwrap(); + assert_eq!(m, res); + + // make sure there's no funny business with the 0 indexing + let m = Here; + let mut iter = m.iter(); + + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + } + + #[test] + fn conversion_from_other_types_works() { + fn takes_multilocation>(_arg: Arg) {} + + takes_multilocation(Parent); + takes_multilocation(Here); + takes_multilocation(X1(Parachain(42))); + takes_multilocation((255, PalletInstance(8))); + takes_multilocation((Ancestor(5), Parachain(1), PalletInstance(3))); + takes_multilocation((Ancestor(2), Here)); + takes_multilocation(AncestorThen( + 3, + X2(Parachain(43), AccountIndex64 { network: Any, index: 155 }), + )); + takes_multilocation((Parent, AccountId32 { network: Any, id: [0; 32] })); + takes_multilocation((Parent, Here)); + takes_multilocation(ParentThen(X1(Parachain(75)))); + takes_multilocation([Parachain(100), PalletInstance(3)]); + } +} diff --git a/polkadot/xcm/src/v2/traits.rs b/polkadot/xcm/src/v2/traits.rs new file mode 100644 index 0000000000000000000000000000000000000000..ae03cf5547bad2223d430325b98b469eda8274a8 --- /dev/null +++ b/polkadot/xcm/src/v2/traits.rs @@ -0,0 +1,354 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// 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 Cumulus. If not, see . + +//! Cross-Consensus Message format data structures. + +use crate::v3::Error as NewError; +use core::result; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; + +use super::*; + +#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] +pub enum Error { + // Errors that happen due to instructions being executed. These alone are defined in the + // XCM specification. + /// An arithmetic overflow happened. + #[codec(index = 0)] + Overflow, + /// The instruction is intentionally unsupported. + #[codec(index = 1)] + Unimplemented, + /// Origin Register does not contain a value value for a reserve transfer notification. + #[codec(index = 2)] + UntrustedReserveLocation, + /// Origin Register does not contain a value value for a teleport notification. + #[codec(index = 3)] + UntrustedTeleportLocation, + /// `MultiLocation` value too large to descend further. + #[codec(index = 4)] + MultiLocationFull, + /// `MultiLocation` value ascend more parents than known ancestors of local location. + #[codec(index = 5)] + MultiLocationNotInvertible, + /// The Origin Register does not contain a valid value for instruction. + #[codec(index = 6)] + BadOrigin, + /// The location parameter is not a valid value for the instruction. + #[codec(index = 7)] + InvalidLocation, + /// The given asset is not handled. + #[codec(index = 8)] + AssetNotFound, + /// An asset transaction (like withdraw or deposit) failed (typically due to type conversions). + #[codec(index = 9)] + FailedToTransactAsset(#[codec(skip)] &'static str), + /// An asset cannot be withdrawn, potentially due to lack of ownership, availability or rights. + #[codec(index = 10)] + NotWithdrawable, + /// An asset cannot be deposited under the ownership of a particular location. + #[codec(index = 11)] + LocationCannotHold, + /// Attempt to send a message greater than the maximum supported by the transport protocol. + #[codec(index = 12)] + ExceedsMaxMessageSize, + /// The given message cannot be translated into a format supported by the destination. + #[codec(index = 13)] + DestinationUnsupported, + /// Destination is routable, but there is some issue with the transport mechanism. + #[codec(index = 14)] + Transport(#[codec(skip)] &'static str), + /// Destination is known to be unroutable. + #[codec(index = 15)] + Unroutable, + /// Used by `ClaimAsset` when the given claim could not be recognized/found. + #[codec(index = 16)] + UnknownClaim, + /// Used by `Transact` when the functor cannot be decoded. + #[codec(index = 17)] + FailedToDecode, + /// Used by `Transact` to indicate that the given weight limit could be breached by the + /// functor. + #[codec(index = 18)] + MaxWeightInvalid, + /// Used by `BuyExecution` when the Holding Register does not contain payable fees. + #[codec(index = 19)] + NotHoldingFees, + /// Used by `BuyExecution` when the fees declared to purchase weight are insufficient. + #[codec(index = 20)] + TooExpensive, + /// Used by the `Trap` instruction to force an error intentionally. Its code is included. + #[codec(index = 21)] + Trap(u64), + + // Errors that happen prior to instructions being executed. These fall outside of the XCM + // spec. + /// XCM version not able to be handled. + UnhandledXcmVersion, + /// Execution of the XCM would potentially result in a greater weight used than weight limit. + WeightLimitReached(Weight), + /// The XCM did not pass the barrier condition for execution. + /// + /// The barrier condition differs on different chains and in different circumstances, but + /// generally it means that the conditions surrounding the message were not such that the chain + /// considers the message worth spending time executing. Since most chains lift the barrier to + /// execution on appropriate payment, presentation of an NFT voucher, or based on the message + /// origin, it means that none of those were the case. + Barrier, + /// The weight of an XCM message is not computable ahead of execution. + WeightNotComputable, +} + +impl TryFrom for Error { + type Error = (); + fn try_from(new_error: NewError) -> result::Result { + use NewError::*; + Ok(match new_error { + Overflow => Self::Overflow, + Unimplemented => Self::Unimplemented, + UntrustedReserveLocation => Self::UntrustedReserveLocation, + UntrustedTeleportLocation => Self::UntrustedTeleportLocation, + LocationFull => Self::MultiLocationFull, + LocationNotInvertible => Self::MultiLocationNotInvertible, + BadOrigin => Self::BadOrigin, + InvalidLocation => Self::InvalidLocation, + AssetNotFound => Self::AssetNotFound, + FailedToTransactAsset(s) => Self::FailedToTransactAsset(s), + NotWithdrawable => Self::NotWithdrawable, + LocationCannotHold => Self::LocationCannotHold, + ExceedsMaxMessageSize => Self::ExceedsMaxMessageSize, + DestinationUnsupported => Self::DestinationUnsupported, + Transport(s) => Self::Transport(s), + Unroutable => Self::Unroutable, + UnknownClaim => Self::UnknownClaim, + FailedToDecode => Self::FailedToDecode, + MaxWeightInvalid => Self::MaxWeightInvalid, + NotHoldingFees => Self::NotHoldingFees, + TooExpensive => Self::TooExpensive, + Trap(i) => Self::Trap(i), + _ => return Err(()), + }) + } +} + +impl From for Error { + fn from(e: SendError) -> Self { + match e { + SendError::NotApplicable(..) | SendError::Unroutable => Error::Unroutable, + SendError::Transport(s) => Error::Transport(s), + SendError::DestinationUnsupported => Error::DestinationUnsupported, + SendError::ExceedsMaxMessageSize => Error::ExceedsMaxMessageSize, + } + } +} + +pub type Result = result::Result<(), Error>; + +/// Outcome of an XCM execution. +#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] +pub enum Outcome { + /// Execution completed successfully; given weight was used. + Complete(Weight), + /// Execution started, but did not complete successfully due to the given error; given weight + /// was used. + Incomplete(Weight, Error), + /// Execution did not start due to the given error. + Error(Error), +} + +impl Outcome { + pub fn ensure_complete(self) -> Result { + match self { + Outcome::Complete(_) => Ok(()), + Outcome::Incomplete(_, e) => Err(e), + Outcome::Error(e) => Err(e), + } + } + pub fn ensure_execution(self) -> result::Result { + match self { + Outcome::Complete(w) => Ok(w), + Outcome::Incomplete(w, _) => Ok(w), + Outcome::Error(e) => Err(e), + } + } + /// How much weight was used by the XCM execution attempt. + pub fn weight_used(&self) -> Weight { + match self { + Outcome::Complete(w) => *w, + Outcome::Incomplete(w, _) => *w, + Outcome::Error(_) => 0, + } + } +} + +/// Type of XCM message executor. +pub trait ExecuteXcm { + /// Execute some XCM `message` from `origin` using no more than `weight_limit` weight. The + /// weight limit is a basic hard-limit and the implementation may place further restrictions or + /// requirements on weight and other aspects. + fn execute_xcm( + origin: impl Into, + message: Xcm, + weight_limit: Weight, + ) -> Outcome { + let origin = origin.into(); + log::debug!( + target: "xcm::execute_xcm", + "origin: {:?}, message: {:?}, weight_limit: {:?}", + origin, + message, + weight_limit, + ); + Self::execute_xcm_in_credit(origin, message, weight_limit, 0) + } + + /// Execute some XCM `message` from `origin` using no more than `weight_limit` weight. + /// + /// Some amount of `weight_credit` may be provided which, depending on the implementation, may + /// allow execution without associated payment. + fn execute_xcm_in_credit( + origin: impl Into, + message: Xcm, + weight_limit: Weight, + weight_credit: Weight, + ) -> Outcome; +} + +impl ExecuteXcm for () { + fn execute_xcm_in_credit( + _origin: impl Into, + _message: Xcm, + _weight_limit: Weight, + _weight_credit: Weight, + ) -> Outcome { + Outcome::Error(Error::Unimplemented) + } +} + +/// Error result value when attempting to send an XCM message. +#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, scale_info::TypeInfo)] +pub enum SendError { + /// The message and destination combination was not recognized as being reachable. + /// + /// This is not considered fatal: if there are alternative transport routes available, then + /// they may be attempted. For this reason, the destination and message are contained. + NotApplicable(MultiLocation, Xcm<()>), + /// Destination is routable, but there is some issue with the transport mechanism. This is + /// considered fatal. + /// A human-readable explanation of the specific issue is provided. + Transport(#[codec(skip)] &'static str), + /// Destination is known to be unroutable. This is considered fatal. + Unroutable, + /// The given message cannot be translated into a format that the destination can be expected + /// to interpret. + DestinationUnsupported, + /// Message could not be sent due to its size exceeding the maximum allowed by the transport + /// layer. + ExceedsMaxMessageSize, +} + +/// Result value when attempting to send an XCM message. +pub type SendResult = result::Result<(), SendError>; + +/// Utility for sending an XCM message. +/// +/// These can be amalgamated in tuples to form sophisticated routing systems. In tuple format, each +/// router might return `NotApplicable` to pass the execution to the next sender item. Note that +/// each `NotApplicable` might alter the destination and the XCM message for to the next router. +/// +/// +/// # Example +/// ```rust +/// # use xcm::v2::prelude::*; +/// # use parity_scale_codec::Encode; +/// +/// /// A sender that only passes the message through and does nothing. +/// struct Sender1; +/// impl SendXcm for Sender1 { +/// fn send_xcm(destination: impl Into, message: Xcm<()>) -> SendResult { +/// return Err(SendError::NotApplicable(destination.into(), message)) +/// } +/// } +/// +/// /// A sender that accepts a message that has an X2 junction, otherwise stops the routing. +/// struct Sender2; +/// impl SendXcm for Sender2 { +/// fn send_xcm(destination: impl Into, message: Xcm<()>) -> SendResult { +/// if let MultiLocation { parents: 0, interior: X2(j1, j2) } = destination.into() { +/// Ok(()) +/// } else { +/// Err(SendError::Unroutable) +/// } +/// } +/// } +/// +/// /// A sender that accepts a message from a parent, passing through otherwise. +/// struct Sender3; +/// impl SendXcm for Sender3 { +/// fn send_xcm(destination: impl Into, message: Xcm<()>) -> SendResult { +/// let destination = destination.into(); +/// match destination { +/// MultiLocation { parents: 1, interior: Here } => Ok(()), +/// _ => Err(SendError::NotApplicable(destination, message)), +/// } +/// } +/// } +/// +/// // A call to send via XCM. We don't really care about this. +/// # fn main() { +/// let call: Vec = ().encode(); +/// let message = Xcm(vec![Instruction::Transact { +/// origin_type: OriginKind::Superuser, +/// require_weight_at_most: 0, +/// call: call.into(), +/// }]); +/// +/// assert!( +/// // Sender2 will block this. +/// <(Sender1, Sender2, Sender3) as SendXcm>::send_xcm(Parent, message.clone()) +/// .is_err() +/// ); +/// +/// assert!( +/// // Sender3 will catch this. +/// <(Sender1, Sender3) as SendXcm>::send_xcm(Parent, message.clone()) +/// .is_ok() +/// ); +/// # } +/// ``` +pub trait SendXcm { + /// Send an XCM `message` to a given `destination`. + /// + /// If it is not a destination which can be reached with this type but possibly could by others, + /// then it *MUST* return `NotApplicable`. Any other error will cause the tuple implementation + /// to exit early without trying other type fields. + fn send_xcm(destination: impl Into, message: Xcm<()>) -> SendResult; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl SendXcm for Tuple { + fn send_xcm(destination: impl Into, message: Xcm<()>) -> SendResult { + for_tuples!( #( + // we shadow `destination` and `message` in each expansion for the next one. + let (destination, message) = match Tuple::send_xcm(destination, message) { + Err(SendError::NotApplicable(d, m)) => (d, m), + o @ _ => return o, + }; + )* ); + Err(SendError::NotApplicable(destination.into(), message)) + } +} diff --git a/polkadot/xcm/src/v3/junction.rs b/polkadot/xcm/src/v3/junction.rs new file mode 100644 index 0000000000000000000000000000000000000000..b5dd5bc7c88fe5a24792e3bc2660809435ebae08 --- /dev/null +++ b/polkadot/xcm/src/v3/junction.rs @@ -0,0 +1,467 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Support data structures for `MultiLocation`, primarily the `Junction` datatype. + +use super::{Junctions, MultiLocation}; +use crate::{ + v2::{ + BodyId as OldBodyId, BodyPart as OldBodyPart, Junction as OldJunction, + NetworkId as OldNetworkId, + }, + VersionedMultiLocation, +}; +use bounded_collections::{BoundedSlice, BoundedVec, ConstU32}; +use core::convert::{TryFrom, TryInto}; +use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; +use serde::{Deserialize, Serialize}; + +/// A global identifier of a data structure existing within consensus. +/// +/// Maintenance note: Networks with global consensus and which are practically bridgeable within the +/// Polkadot ecosystem are given preference over explicit naming in this enumeration. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, +)] +pub enum NetworkId { + /// Network specified by the first 32 bytes of its genesis block. + ByGenesis([u8; 32]), + /// Network defined by the first 32-bytes of the hash and number of some block it contains. + ByFork { block_number: u64, block_hash: [u8; 32] }, + /// The Polkadot mainnet Relay-chain. + Polkadot, + /// The Kusama canary-net Relay-chain. + Kusama, + /// The Westend testnet Relay-chain. + Westend, + /// The Rococo testnet Relay-chain. + Rococo, + /// The Wococo testnet Relay-chain. + Wococo, + /// An Ethereum network specified by its chain ID. + Ethereum { + /// The EIP-155 chain ID. + #[codec(compact)] + chain_id: u64, + }, + /// The Bitcoin network, including hard-forks supported by Bitcoin Core development team. + BitcoinCore, + /// The Bitcoin network, including hard-forks supported by Bitcoin Cash developers. + BitcoinCash, +} + +impl From for Option { + fn from(old: OldNetworkId) -> Option { + use OldNetworkId::*; + match old { + Any => None, + Named(_) => None, + Polkadot => Some(NetworkId::Polkadot), + Kusama => Some(NetworkId::Kusama), + } + } +} + +impl TryFrom for NetworkId { + type Error = (); + fn try_from(old: OldNetworkId) -> Result { + use OldNetworkId::*; + match old { + Any | Named(_) => Err(()), + Polkadot => Ok(NetworkId::Polkadot), + Kusama => Ok(NetworkId::Kusama), + } + } +} + +/// An identifier of a pluralistic body. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, +)] +pub enum BodyId { + /// The only body in its context. + Unit, + /// A named body. + Moniker([u8; 4]), + /// An indexed body. + Index(#[codec(compact)] u32), + /// The unambiguous executive body (for Polkadot, this would be the Polkadot council). + Executive, + /// The unambiguous technical body (for Polkadot, this would be the Technical Committee). + Technical, + /// The unambiguous legislative body (for Polkadot, this could be considered the opinion of a + /// majority of lock-voters). + Legislative, + /// The unambiguous judicial body (this doesn't exist on Polkadot, but if it were to get a + /// "grand oracle", it may be considered as that). + Judicial, + /// The unambiguous defense body (for Polkadot, an opinion on the topic given via a public + /// referendum on the `staking_admin` track). + Defense, + /// The unambiguous administration body (for Polkadot, an opinion on the topic given via a + /// public referendum on the `general_admin` track). + Administration, + /// The unambiguous treasury body (for Polkadot, an opinion on the topic given via a public + /// referendum on the `treasurer` track). + Treasury, +} + +impl TryFrom for BodyId { + type Error = (); + fn try_from(value: OldBodyId) -> Result { + use OldBodyId::*; + Ok(match value { + Unit => Self::Unit, + Named(n) => + if n.len() == 4 { + let mut r = [0u8; 4]; + r.copy_from_slice(&n[..]); + Self::Moniker(r) + } else { + return Err(()) + }, + Index(n) => Self::Index(n), + Executive => Self::Executive, + Technical => Self::Technical, + Legislative => Self::Legislative, + Judicial => Self::Judicial, + Defense => Self::Defense, + Administration => Self::Administration, + Treasury => Self::Treasury, + }) + } +} + +/// A part of a pluralistic body. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, +)] +pub enum BodyPart { + /// The body's declaration, under whatever means it decides. + Voice, + /// A given number of members of the body. + Members { + #[codec(compact)] + count: u32, + }, + /// A given number of members of the body, out of some larger caucus. + Fraction { + #[codec(compact)] + nom: u32, + #[codec(compact)] + denom: u32, + }, + /// No less than the given proportion of members of the body. + AtLeastProportion { + #[codec(compact)] + nom: u32, + #[codec(compact)] + denom: u32, + }, + /// More than than the given proportion of members of the body. + MoreThanProportion { + #[codec(compact)] + nom: u32, + #[codec(compact)] + denom: u32, + }, +} + +impl BodyPart { + /// Returns `true` if the part represents a strict majority (> 50%) of the body in question. + pub fn is_majority(&self) -> bool { + match self { + BodyPart::Fraction { nom, denom } if *nom * 2 > *denom => true, + BodyPart::AtLeastProportion { nom, denom } if *nom * 2 > *denom => true, + BodyPart::MoreThanProportion { nom, denom } if *nom * 2 >= *denom => true, + _ => false, + } + } +} + +impl TryFrom for BodyPart { + type Error = (); + fn try_from(value: OldBodyPart) -> Result { + use OldBodyPart::*; + Ok(match value { + Voice => Self::Voice, + Members { count } => Self::Members { count }, + Fraction { nom, denom } => Self::Fraction { nom, denom }, + AtLeastProportion { nom, denom } => Self::AtLeastProportion { nom, denom }, + MoreThanProportion { nom, denom } => Self::MoreThanProportion { nom, denom }, + }) + } +} + +/// A single item in a path to describe the relative location of a consensus system. +/// +/// Each item assumes a pre-existing location as its context and is defined in terms of it. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, +)] +pub enum Junction { + /// An indexed parachain belonging to and operated by the context. + /// + /// Generally used when the context is a Polkadot Relay-chain. + Parachain(#[codec(compact)] u32), + /// A 32-byte identifier for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// Generally used when the context is a Substrate-based chain. + AccountId32 { network: Option, id: [u8; 32] }, + /// An 8-byte index for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// May be used when the context is a Frame-based chain and includes e.g. an indices pallet. + AccountIndex64 { + network: Option, + #[codec(compact)] + index: u64, + }, + /// A 20-byte identifier for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// May be used when the context is an Ethereum or Bitcoin chain or smart-contract. + AccountKey20 { network: Option, key: [u8; 20] }, + /// An instanced, indexed pallet that forms a constituent part of the context. + /// + /// Generally used when the context is a Frame-based chain. + // TODO XCMv4 inner should be `Compact`. + PalletInstance(u8), + /// A non-descript index within the context location. + /// + /// Usage will vary widely owing to its generality. + /// + /// NOTE: Try to avoid using this and instead use a more specific item. + GeneralIndex(#[codec(compact)] u128), + /// A nondescript array datum, 32 bytes, acting as a key within the context + /// location. + /// + /// Usage will vary widely owing to its generality. + /// + /// NOTE: Try to avoid using this and instead use a more specific item. + // Note this is implemented as an array with a length rather than using `BoundedVec` owing to + // the bound for `Copy`. + GeneralKey { length: u8, data: [u8; 32] }, + /// The unambiguous child. + /// + /// Not currently used except as a fallback when deriving context. + OnlyChild, + /// A pluralistic body existing within consensus. + /// + /// Typical to be used to represent a governance origin of a chain, but could in principle be + /// used to represent things such as multisigs also. + Plurality { id: BodyId, part: BodyPart }, + /// A global network capable of externalizing its own consensus. This is not generally + /// meaningful outside of the universal level. + GlobalConsensus(NetworkId), +} + +impl From for Junction { + fn from(n: NetworkId) -> Self { + Self::GlobalConsensus(n) + } +} + +impl From<[u8; 32]> for Junction { + fn from(id: [u8; 32]) -> Self { + Self::AccountId32 { network: None, id } + } +} + +impl From>> for Junction { + fn from(key: BoundedVec>) -> Self { + key.as_bounded_slice().into() + } +} + +impl<'a> From>> for Junction { + fn from(key: BoundedSlice<'a, u8, ConstU32<32>>) -> Self { + let mut data = [0u8; 32]; + data[..key.len()].copy_from_slice(&key[..]); + Self::GeneralKey { length: key.len() as u8, data } + } +} + +impl<'a> TryFrom<&'a Junction> for BoundedSlice<'a, u8, ConstU32<32>> { + type Error = (); + fn try_from(key: &'a Junction) -> Result { + match key { + Junction::GeneralKey { length, data } => + BoundedSlice::try_from(&data[..data.len().min(*length as usize)]).map_err(|_| ()), + _ => Err(()), + } + } +} + +impl From<[u8; 20]> for Junction { + fn from(key: [u8; 20]) -> Self { + Self::AccountKey20 { network: None, key } + } +} + +impl From for Junction { + fn from(index: u64) -> Self { + Self::AccountIndex64 { network: None, index } + } +} + +impl From for Junction { + fn from(id: u128) -> Self { + Self::GeneralIndex(id) + } +} + +impl TryFrom for Junction { + type Error = (); + fn try_from(value: OldJunction) -> Result { + use OldJunction::*; + Ok(match value { + Parachain(id) => Self::Parachain(id), + AccountId32 { network, id } => Self::AccountId32 { network: network.into(), id }, + AccountIndex64 { network, index } => + Self::AccountIndex64 { network: network.into(), index }, + AccountKey20 { network, key } => Self::AccountKey20 { network: network.into(), key }, + PalletInstance(index) => Self::PalletInstance(index), + GeneralIndex(id) => Self::GeneralIndex(id), + GeneralKey(key) => match key.len() { + len @ 0..=32 => Self::GeneralKey { + length: len as u8, + data: { + let mut data = [0u8; 32]; + data[..len].copy_from_slice(&key[..]); + data + }, + }, + _ => return Err(()), + }, + OnlyChild => Self::OnlyChild, + Plurality { id, part } => + Self::Plurality { id: id.try_into()?, part: part.try_into()? }, + }) + } +} + +impl Junction { + /// Convert `self` into a `MultiLocation` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub const fn into_location(self) -> MultiLocation { + MultiLocation { parents: 0, interior: Junctions::X1(self) } + } + + /// Convert `self` into a `MultiLocation` containing `n` parents. + /// + /// Similar to `Self::into_location`, with the added ability to specify the number of parent + /// junctions. + pub const fn into_exterior(self, n: u8) -> MultiLocation { + MultiLocation { parents: n, interior: Junctions::X1(self) } + } + + /// Convert `self` into a `VersionedMultiLocation` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub const fn into_versioned(self) -> VersionedMultiLocation { + self.into_location().into_versioned() + } + + /// Remove the `NetworkId` value. + pub fn remove_network_id(&mut self) { + use Junction::*; + match self { + AccountId32 { ref mut network, .. } | + AccountIndex64 { ref mut network, .. } | + AccountKey20 { ref mut network, .. } => *network = None, + _ => {}, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloc::vec; + + #[test] + fn junction_round_trip_works() { + let j = Junction::GeneralKey { length: 32, data: [1u8; 32] }; + let k = Junction::try_from(OldJunction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + + let j = OldJunction::GeneralKey(vec![1u8; 32].try_into().unwrap()); + let k = OldJunction::try_from(Junction::try_from(j.clone()).unwrap()).unwrap(); + assert_eq!(j, k); + + let j = Junction::from(BoundedVec::try_from(vec![1u8, 2, 3, 4]).unwrap()); + let k = Junction::try_from(OldJunction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + let s: BoundedSlice<_, _> = (&k).try_into().unwrap(); + assert_eq!(s, &[1u8, 2, 3, 4][..]); + + let j = OldJunction::GeneralKey(vec![1u8, 2, 3, 4].try_into().unwrap()); + let k = OldJunction::try_from(Junction::try_from(j.clone()).unwrap()).unwrap(); + assert_eq!(j, k); + } +} diff --git a/polkadot/xcm/src/v3/junctions.rs b/polkadot/xcm/src/v3/junctions.rs new file mode 100644 index 0000000000000000000000000000000000000000..201a80fb7658c6f1c919b9c16951d949dad4ca00 --- /dev/null +++ b/polkadot/xcm/src/v3/junctions.rs @@ -0,0 +1,721 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! XCM `Junctions`/`InteriorMultiLocation` datatype. + +use super::{Junction, MultiLocation, NetworkId}; +use core::{convert::TryFrom, mem, result}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// Maximum number of `Junction`s that a `Junctions` can contain. +pub(crate) const MAX_JUNCTIONS: usize = 8; + +/// Non-parent junctions that can be constructed, up to the length of 8. This specific `Junctions` +/// implementation uses a Rust `enum` in order to make pattern matching easier. +/// +/// Parent junctions cannot be constructed with this type. Refer to `MultiLocation` for +/// instructions on constructing parent junctions. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + serde::Serialize, + serde::Deserialize, +)] +pub enum Junctions { + /// The interpreting consensus system. + Here, + /// A relative path comprising 1 junction. + X1(Junction), + /// A relative path comprising 2 junctions. + X2(Junction, Junction), + /// A relative path comprising 3 junctions. + X3(Junction, Junction, Junction), + /// A relative path comprising 4 junctions. + X4(Junction, Junction, Junction, Junction), + /// A relative path comprising 5 junctions. + X5(Junction, Junction, Junction, Junction, Junction), + /// A relative path comprising 6 junctions. + X6(Junction, Junction, Junction, Junction, Junction, Junction), + /// A relative path comprising 7 junctions. + X7(Junction, Junction, Junction, Junction, Junction, Junction, Junction), + /// A relative path comprising 8 junctions. + X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction), +} + +pub struct JunctionsIterator(Junctions); +impl Iterator for JunctionsIterator { + type Item = Junction; + fn next(&mut self) -> Option { + self.0.take_first() + } +} + +impl DoubleEndedIterator for JunctionsIterator { + fn next_back(&mut self) -> Option { + self.0.take_last() + } +} + +pub struct JunctionsRefIterator<'a> { + junctions: &'a Junctions, + next: usize, + back: usize, +} + +impl<'a> Iterator for JunctionsRefIterator<'a> { + type Item = &'a Junction; + fn next(&mut self) -> Option<&'a Junction> { + if self.next.saturating_add(self.back) >= self.junctions.len() { + return None + } + + let result = self.junctions.at(self.next); + self.next += 1; + result + } +} + +impl<'a> DoubleEndedIterator for JunctionsRefIterator<'a> { + fn next_back(&mut self) -> Option<&'a Junction> { + let next_back = self.back.saturating_add(1); + // checked_sub here, because if the result is less than 0, we end iteration + let index = self.junctions.len().checked_sub(next_back)?; + if self.next > index { + return None + } + self.back = next_back; + + self.junctions.at(index) + } +} +impl<'a> IntoIterator for &'a Junctions { + type Item = &'a Junction; + type IntoIter = JunctionsRefIterator<'a>; + fn into_iter(self) -> Self::IntoIter { + JunctionsRefIterator { junctions: self, next: 0, back: 0 } + } +} + +impl IntoIterator for Junctions { + type Item = Junction; + type IntoIter = JunctionsIterator; + fn into_iter(self) -> Self::IntoIter { + JunctionsIterator(self) + } +} + +impl Junctions { + /// Convert `self` into a `MultiLocation` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub const fn into_location(self) -> MultiLocation { + MultiLocation { parents: 0, interior: self } + } + + /// Convert `self` into a `MultiLocation` containing `n` parents. + /// + /// Similar to `Self::into_location`, with the added ability to specify the number of parent + /// junctions. + pub const fn into_exterior(self, n: u8) -> MultiLocation { + MultiLocation { parents: n, interior: self } + } + + /// Remove the `NetworkId` value in any `Junction`s. + pub fn remove_network_id(&mut self) { + self.for_each_mut(Junction::remove_network_id); + } + + /// Treating `self` as the universal context, return the location of the local consensus system + /// from the point of view of the given `target`. + pub fn invert_target(mut self, target: &MultiLocation) -> Result { + let mut junctions = Self::Here; + for _ in 0..target.parent_count() { + junctions = junctions + .pushed_front_with(self.take_last().unwrap_or(Junction::OnlyChild)) + .map_err(|_| ())?; + } + let parents = target.interior().len() as u8; + Ok(MultiLocation::new(parents, junctions)) + } + + /// Execute a function `f` on every junction. We use this since we cannot implement a mutable + /// `Iterator` without unsafe code. + pub fn for_each_mut(&mut self, mut x: impl FnMut(&mut Junction)) { + match self { + Junctions::Here => {}, + Junctions::X1(a) => { + x(a); + }, + Junctions::X2(a, b) => { + x(a); + x(b); + }, + Junctions::X3(a, b, c) => { + x(a); + x(b); + x(c); + }, + Junctions::X4(a, b, c, d) => { + x(a); + x(b); + x(c); + x(d); + }, + Junctions::X5(a, b, c, d, e) => { + x(a); + x(b); + x(c); + x(d); + x(e); + }, + Junctions::X6(a, b, c, d, e, f) => { + x(a); + x(b); + x(c); + x(d); + x(e); + x(f); + }, + Junctions::X7(a, b, c, d, e, f, g) => { + x(a); + x(b); + x(c); + x(d); + x(e); + x(f); + x(g); + }, + Junctions::X8(a, b, c, d, e, f, g, h) => { + x(a); + x(b); + x(c); + x(d); + x(e); + x(f); + x(g); + x(h); + }, + } + } + + /// Extract the network ID treating this value as a universal location. + /// + /// This will return an `Err` if the first item is not a `GlobalConsensus`, which would indicate + /// that this value is not a universal location. + pub fn global_consensus(&self) -> Result { + if let Some(Junction::GlobalConsensus(network)) = self.first() { + Ok(*network) + } else { + Err(()) + } + } + + /// Extract the network ID and the interior consensus location, treating this value as a + /// universal location. + /// + /// This will return an `Err` if the first item is not a `GlobalConsensus`, which would indicate + /// that this value is not a universal location. + pub fn split_global(self) -> Result<(NetworkId, Junctions), ()> { + match self.split_first() { + (location, Some(Junction::GlobalConsensus(network))) => Ok((network, location)), + _ => return Err(()), + } + } + + /// Treat `self` as a universal location and the context of `relative`, returning the universal + /// location of relative. + /// + /// This will return an error if `relative` has as many (or more) parents than there are + /// junctions in `self`, implying that relative refers into a different global consensus. + pub fn within_global(mut self, relative: MultiLocation) -> Result { + if self.len() <= relative.parents as usize { + return Err(()) + } + for _ in 0..relative.parents { + self.take_last(); + } + for j in relative.interior { + self.push(j).map_err(|_| ())?; + } + Ok(self) + } + + /// Consumes `self` and returns how `viewer` would address it locally. + pub fn relative_to(mut self, viewer: &Junctions) -> MultiLocation { + let mut i = 0; + while match (self.first(), viewer.at(i)) { + (Some(x), Some(y)) => x == y, + _ => false, + } { + self = self.split_first().0; + // NOTE: Cannot overflow as loop can only iterate at most `MAX_JUNCTIONS` times. + i += 1; + } + // AUDIT NOTES: + // - above loop ensures that `i <= viewer.len()`. + // - `viewer.len()` is at most `MAX_JUNCTIONS`, so won't overflow a `u8`. + MultiLocation { parents: (viewer.len() - i) as u8, interior: self } + } + + /// Returns first junction, or `None` if the location is empty. + pub fn first(&self) -> Option<&Junction> { + match &self { + Junctions::Here => None, + Junctions::X1(ref a) => Some(a), + Junctions::X2(ref a, ..) => Some(a), + Junctions::X3(ref a, ..) => Some(a), + Junctions::X4(ref a, ..) => Some(a), + Junctions::X5(ref a, ..) => Some(a), + Junctions::X6(ref a, ..) => Some(a), + Junctions::X7(ref a, ..) => Some(a), + Junctions::X8(ref a, ..) => Some(a), + } + } + + /// Returns last junction, or `None` if the location is empty. + pub fn last(&self) -> Option<&Junction> { + match &self { + Junctions::Here => None, + Junctions::X1(ref a) => Some(a), + Junctions::X2(.., ref a) => Some(a), + Junctions::X3(.., ref a) => Some(a), + Junctions::X4(.., ref a) => Some(a), + Junctions::X5(.., ref a) => Some(a), + Junctions::X6(.., ref a) => Some(a), + Junctions::X7(.., ref a) => Some(a), + Junctions::X8(.., ref a) => Some(a), + } + } + + /// Splits off the first junction, returning the remaining suffix (first item in tuple) and the + /// first element (second item in tuple) or `None` if it was empty. + pub fn split_first(self) -> (Junctions, Option) { + match self { + Junctions::Here => (Junctions::Here, None), + Junctions::X1(a) => (Junctions::Here, Some(a)), + Junctions::X2(a, b) => (Junctions::X1(b), Some(a)), + Junctions::X3(a, b, c) => (Junctions::X2(b, c), Some(a)), + Junctions::X4(a, b, c, d) => (Junctions::X3(b, c, d), Some(a)), + Junctions::X5(a, b, c, d, e) => (Junctions::X4(b, c, d, e), Some(a)), + Junctions::X6(a, b, c, d, e, f) => (Junctions::X5(b, c, d, e, f), Some(a)), + Junctions::X7(a, b, c, d, e, f, g) => (Junctions::X6(b, c, d, e, f, g), Some(a)), + Junctions::X8(a, b, c, d, e, f, g, h) => (Junctions::X7(b, c, d, e, f, g, h), Some(a)), + } + } + + /// Splits off the last junction, returning the remaining prefix (first item in tuple) and the + /// last element (second item in tuple) or `None` if it was empty. + pub fn split_last(self) -> (Junctions, Option) { + match self { + Junctions::Here => (Junctions::Here, None), + Junctions::X1(a) => (Junctions::Here, Some(a)), + Junctions::X2(a, b) => (Junctions::X1(a), Some(b)), + Junctions::X3(a, b, c) => (Junctions::X2(a, b), Some(c)), + Junctions::X4(a, b, c, d) => (Junctions::X3(a, b, c), Some(d)), + Junctions::X5(a, b, c, d, e) => (Junctions::X4(a, b, c, d), Some(e)), + Junctions::X6(a, b, c, d, e, f) => (Junctions::X5(a, b, c, d, e), Some(f)), + Junctions::X7(a, b, c, d, e, f, g) => (Junctions::X6(a, b, c, d, e, f), Some(g)), + Junctions::X8(a, b, c, d, e, f, g, h) => (Junctions::X7(a, b, c, d, e, f, g), Some(h)), + } + } + + /// Removes the first element from `self`, returning it (or `None` if it was empty). + pub fn take_first(&mut self) -> Option { + let mut d = Junctions::Here; + mem::swap(&mut *self, &mut d); + let (tail, head) = d.split_first(); + *self = tail; + head + } + + /// Removes the last element from `self`, returning it (or `None` if it was empty). + pub fn take_last(&mut self) -> Option { + let mut d = Junctions::Here; + mem::swap(&mut *self, &mut d); + let (head, tail) = d.split_last(); + *self = head; + tail + } + + /// Mutates `self` to be appended with `new` or returns an `Err` with `new` if would overflow. + pub fn push(&mut self, new: impl Into) -> result::Result<(), Junction> { + let new = new.into(); + let mut dummy = Junctions::Here; + mem::swap(self, &mut dummy); + match dummy.pushed_with(new) { + Ok(s) => { + *self = s; + Ok(()) + }, + Err((s, j)) => { + *self = s; + Err(j) + }, + } + } + + /// Mutates `self` to be prepended with `new` or returns an `Err` with `new` if would overflow. + pub fn push_front(&mut self, new: impl Into) -> result::Result<(), Junction> { + let new = new.into(); + let mut dummy = Junctions::Here; + mem::swap(self, &mut dummy); + match dummy.pushed_front_with(new) { + Ok(s) => { + *self = s; + Ok(()) + }, + Err((s, j)) => { + *self = s; + Err(j) + }, + } + } + + /// Consumes `self` and returns a `Junctions` suffixed with `new`, or an `Err` with the + /// original value of `self` and `new` in case of overflow. + pub fn pushed_with(self, new: impl Into) -> result::Result { + let new = new.into(); + Ok(match self { + Junctions::Here => Junctions::X1(new), + Junctions::X1(a) => Junctions::X2(a, new), + Junctions::X2(a, b) => Junctions::X3(a, b, new), + Junctions::X3(a, b, c) => Junctions::X4(a, b, c, new), + Junctions::X4(a, b, c, d) => Junctions::X5(a, b, c, d, new), + Junctions::X5(a, b, c, d, e) => Junctions::X6(a, b, c, d, e, new), + Junctions::X6(a, b, c, d, e, f) => Junctions::X7(a, b, c, d, e, f, new), + Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(a, b, c, d, e, f, g, new), + s => Err((s, new))?, + }) + } + + /// Consumes `self` and returns a `Junctions` prefixed with `new`, or an `Err` with the + /// original value of `self` and `new` in case of overflow. + pub fn pushed_front_with( + self, + new: impl Into, + ) -> result::Result { + let new = new.into(); + Ok(match self { + Junctions::Here => Junctions::X1(new), + Junctions::X1(a) => Junctions::X2(new, a), + Junctions::X2(a, b) => Junctions::X3(new, a, b), + Junctions::X3(a, b, c) => Junctions::X4(new, a, b, c), + Junctions::X4(a, b, c, d) => Junctions::X5(new, a, b, c, d), + Junctions::X5(a, b, c, d, e) => Junctions::X6(new, a, b, c, d, e), + Junctions::X6(a, b, c, d, e, f) => Junctions::X7(new, a, b, c, d, e, f), + Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(new, a, b, c, d, e, f, g), + s => Err((s, new))?, + }) + } + + /// Mutate `self` so that it is suffixed with `suffix`. + /// + /// Does not modify `self` and returns `Err` with `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation}; + /// # fn main() { + /// let mut m = X1(Parachain(21)); + /// assert_eq!(m.append_with(X1(PalletInstance(3))), Ok(())); + /// assert_eq!(m, X2(Parachain(21), PalletInstance(3))); + /// # } + /// ``` + pub fn append_with(&mut self, suffix: impl Into) -> Result<(), Junctions> { + let suffix = suffix.into(); + if self.len().saturating_add(suffix.len()) > MAX_JUNCTIONS { + return Err(suffix) + } + for j in suffix.into_iter() { + self.push(j).expect("Already checked the sum of the len()s; qed") + } + Ok(()) + } + + /// Returns the number of junctions in `self`. + pub const fn len(&self) -> usize { + match &self { + Junctions::Here => 0, + Junctions::X1(..) => 1, + Junctions::X2(..) => 2, + Junctions::X3(..) => 3, + Junctions::X4(..) => 4, + Junctions::X5(..) => 5, + Junctions::X6(..) => 6, + Junctions::X7(..) => 7, + Junctions::X8(..) => 8, + } + } + + /// Returns the junction at index `i`, or `None` if the location doesn't contain that many + /// elements. + pub fn at(&self, i: usize) -> Option<&Junction> { + Some(match (i, self) { + (0, Junctions::X1(ref a)) => a, + (0, Junctions::X2(ref a, ..)) => a, + (0, Junctions::X3(ref a, ..)) => a, + (0, Junctions::X4(ref a, ..)) => a, + (0, Junctions::X5(ref a, ..)) => a, + (0, Junctions::X6(ref a, ..)) => a, + (0, Junctions::X7(ref a, ..)) => a, + (0, Junctions::X8(ref a, ..)) => a, + (1, Junctions::X2(_, ref a)) => a, + (1, Junctions::X3(_, ref a, ..)) => a, + (1, Junctions::X4(_, ref a, ..)) => a, + (1, Junctions::X5(_, ref a, ..)) => a, + (1, Junctions::X6(_, ref a, ..)) => a, + (1, Junctions::X7(_, ref a, ..)) => a, + (1, Junctions::X8(_, ref a, ..)) => a, + (2, Junctions::X3(_, _, ref a)) => a, + (2, Junctions::X4(_, _, ref a, ..)) => a, + (2, Junctions::X5(_, _, ref a, ..)) => a, + (2, Junctions::X6(_, _, ref a, ..)) => a, + (2, Junctions::X7(_, _, ref a, ..)) => a, + (2, Junctions::X8(_, _, ref a, ..)) => a, + (3, Junctions::X4(_, _, _, ref a)) => a, + (3, Junctions::X5(_, _, _, ref a, ..)) => a, + (3, Junctions::X6(_, _, _, ref a, ..)) => a, + (3, Junctions::X7(_, _, _, ref a, ..)) => a, + (3, Junctions::X8(_, _, _, ref a, ..)) => a, + (4, Junctions::X5(_, _, _, _, ref a)) => a, + (4, Junctions::X6(_, _, _, _, ref a, ..)) => a, + (4, Junctions::X7(_, _, _, _, ref a, ..)) => a, + (4, Junctions::X8(_, _, _, _, ref a, ..)) => a, + (5, Junctions::X6(_, _, _, _, _, ref a)) => a, + (5, Junctions::X7(_, _, _, _, _, ref a, ..)) => a, + (5, Junctions::X8(_, _, _, _, _, ref a, ..)) => a, + (6, Junctions::X7(_, _, _, _, _, _, ref a)) => a, + (6, Junctions::X8(_, _, _, _, _, _, ref a, ..)) => a, + (7, Junctions::X8(_, _, _, _, _, _, _, ref a)) => a, + _ => return None, + }) + } + + /// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't + /// contain that many elements. + pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> { + Some(match (i, self) { + (0, Junctions::X1(ref mut a)) => a, + (0, Junctions::X2(ref mut a, ..)) => a, + (0, Junctions::X3(ref mut a, ..)) => a, + (0, Junctions::X4(ref mut a, ..)) => a, + (0, Junctions::X5(ref mut a, ..)) => a, + (0, Junctions::X6(ref mut a, ..)) => a, + (0, Junctions::X7(ref mut a, ..)) => a, + (0, Junctions::X8(ref mut a, ..)) => a, + (1, Junctions::X2(_, ref mut a)) => a, + (1, Junctions::X3(_, ref mut a, ..)) => a, + (1, Junctions::X4(_, ref mut a, ..)) => a, + (1, Junctions::X5(_, ref mut a, ..)) => a, + (1, Junctions::X6(_, ref mut a, ..)) => a, + (1, Junctions::X7(_, ref mut a, ..)) => a, + (1, Junctions::X8(_, ref mut a, ..)) => a, + (2, Junctions::X3(_, _, ref mut a)) => a, + (2, Junctions::X4(_, _, ref mut a, ..)) => a, + (2, Junctions::X5(_, _, ref mut a, ..)) => a, + (2, Junctions::X6(_, _, ref mut a, ..)) => a, + (2, Junctions::X7(_, _, ref mut a, ..)) => a, + (2, Junctions::X8(_, _, ref mut a, ..)) => a, + (3, Junctions::X4(_, _, _, ref mut a)) => a, + (3, Junctions::X5(_, _, _, ref mut a, ..)) => a, + (3, Junctions::X6(_, _, _, ref mut a, ..)) => a, + (3, Junctions::X7(_, _, _, ref mut a, ..)) => a, + (3, Junctions::X8(_, _, _, ref mut a, ..)) => a, + (4, Junctions::X5(_, _, _, _, ref mut a)) => a, + (4, Junctions::X6(_, _, _, _, ref mut a, ..)) => a, + (4, Junctions::X7(_, _, _, _, ref mut a, ..)) => a, + (4, Junctions::X8(_, _, _, _, ref mut a, ..)) => a, + (5, Junctions::X6(_, _, _, _, _, ref mut a)) => a, + (5, Junctions::X7(_, _, _, _, _, ref mut a, ..)) => a, + (5, Junctions::X8(_, _, _, _, _, ref mut a, ..)) => a, + (6, Junctions::X7(_, _, _, _, _, _, ref mut a)) => a, + (6, Junctions::X8(_, _, _, _, _, _, ref mut a, ..)) => a, + (7, Junctions::X8(_, _, _, _, _, _, _, ref mut a)) => a, + _ => return None, + }) + } + + /// Returns a reference iterator over the junctions. + pub fn iter(&self) -> JunctionsRefIterator { + JunctionsRefIterator { junctions: self, next: 0, back: 0 } + } + + /// Ensures that self begins with `prefix` and that it has a single `Junction` item following. + /// If so, returns a reference to this `Junction` item. + /// + /// # Example + /// ```rust + /// # use xcm::v3::{Junctions::*, Junction::*}; + /// # fn main() { + /// let mut m = X3(Parachain(2), PalletInstance(3), OnlyChild); + /// assert_eq!(m.match_and_split(&X2(Parachain(2), PalletInstance(3))), Some(&OnlyChild)); + /// assert_eq!(m.match_and_split(&X1(Parachain(2))), None); + /// # } + /// ``` + pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> { + if prefix.len() + 1 != self.len() { + return None + } + for i in 0..prefix.len() { + if prefix.at(i) != self.at(i) { + return None + } + } + return self.at(prefix.len()) + } + + pub fn starts_with(&self, prefix: &Junctions) -> bool { + prefix.len() <= self.len() && prefix.iter().zip(self.iter()).all(|(x, y)| x == y) + } +} + +impl TryFrom for Junctions { + type Error = MultiLocation; + fn try_from(x: MultiLocation) -> result::Result { + if x.parents > 0 { + Err(x) + } else { + Ok(x.interior) + } + } +} + +impl> From for Junctions { + fn from(x: T) -> Self { + Self::X1(x.into()) + } +} + +impl From<[Junction; 0]> for Junctions { + fn from(_: [Junction; 0]) -> Self { + Self::Here + } +} + +impl From<()> for Junctions { + fn from(_: ()) -> Self { + Self::Here + } +} + +xcm_procedural::impl_conversion_functions_for_junctions_v3!(); + +#[cfg(test)] +mod tests { + use super::{super::prelude::*, *}; + + #[test] + fn inverting_works() { + let context: InteriorMultiLocation = (Parachain(1000), PalletInstance(42)).into(); + let target = (Parent, PalletInstance(69)).into(); + let expected = (Parent, PalletInstance(42)).into(); + let inverted = context.invert_target(&target).unwrap(); + assert_eq!(inverted, expected); + + let context: InteriorMultiLocation = + (Parachain(1000), PalletInstance(42), GeneralIndex(1)).into(); + let target = (Parent, Parent, PalletInstance(69), GeneralIndex(2)).into(); + let expected = (Parent, Parent, PalletInstance(42), GeneralIndex(1)).into(); + let inverted = context.invert_target(&target).unwrap(); + assert_eq!(inverted, expected); + } + + #[test] + fn relative_to_works() { + use Junctions::*; + use NetworkId::*; + assert_eq!(X1(Polkadot.into()).relative_to(&X1(Kusama.into())), (Parent, Polkadot).into()); + let base = X3(Kusama.into(), Parachain(1), PalletInstance(1)); + + // Ancestors. + assert_eq!(Here.relative_to(&base), (Parent, Parent, Parent).into()); + assert_eq!(X1(Kusama.into()).relative_to(&base), (Parent, Parent).into()); + assert_eq!(X2(Kusama.into(), Parachain(1)).relative_to(&base), (Parent,).into()); + assert_eq!( + X3(Kusama.into(), Parachain(1), PalletInstance(1)).relative_to(&base), + Here.into() + ); + + // Ancestors with one child. + assert_eq!( + X1(Polkadot.into()).relative_to(&base), + (Parent, Parent, Parent, Polkadot).into() + ); + assert_eq!( + X2(Kusama.into(), Parachain(2)).relative_to(&base), + (Parent, Parent, Parachain(2)).into() + ); + assert_eq!( + X3(Kusama.into(), Parachain(1), PalletInstance(2)).relative_to(&base), + (Parent, PalletInstance(2)).into() + ); + assert_eq!( + X4(Kusama.into(), Parachain(1), PalletInstance(1), [1u8; 32].into()).relative_to(&base), + ([1u8; 32],).into() + ); + + // Ancestors with grandchildren. + assert_eq!( + X2(Polkadot.into(), Parachain(1)).relative_to(&base), + (Parent, Parent, Parent, Polkadot, Parachain(1)).into() + ); + assert_eq!( + X3(Kusama.into(), Parachain(2), PalletInstance(1)).relative_to(&base), + (Parent, Parent, Parachain(2), PalletInstance(1)).into() + ); + assert_eq!( + X4(Kusama.into(), Parachain(1), PalletInstance(2), [1u8; 32].into()).relative_to(&base), + (Parent, PalletInstance(2), [1u8; 32]).into() + ); + assert_eq!( + X5(Kusama.into(), Parachain(1), PalletInstance(1), [1u8; 32].into(), 1u128.into()) + .relative_to(&base), + ([1u8; 32], 1u128).into() + ); + } + + #[test] + fn global_consensus_works() { + use Junctions::*; + use NetworkId::*; + assert_eq!(X1(Polkadot.into()).global_consensus(), Ok(Polkadot)); + assert_eq!(X2(Kusama.into(), 1u64.into()).global_consensus(), Ok(Kusama)); + assert_eq!(Here.global_consensus(), Err(())); + assert_eq!(X1(1u64.into()).global_consensus(), Err(())); + assert_eq!(X2(1u64.into(), Kusama.into()).global_consensus(), Err(())); + } + + #[test] + fn test_conversion() { + use super::{Junction::*, Junctions::*, NetworkId::*}; + let x: Junctions = GlobalConsensus(Polkadot).into(); + assert_eq!(x, X1(GlobalConsensus(Polkadot))); + let x: Junctions = Polkadot.into(); + assert_eq!(x, X1(GlobalConsensus(Polkadot))); + let x: Junctions = (Polkadot, Kusama).into(); + assert_eq!(x, X2(GlobalConsensus(Polkadot), GlobalConsensus(Kusama))); + } +} diff --git a/polkadot/xcm/src/v3/mod.rs b/polkadot/xcm/src/v3/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..36086795786270d75a0a2c2a987f66688233e8cd --- /dev/null +++ b/polkadot/xcm/src/v3/mod.rs @@ -0,0 +1,1429 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// 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 Polkadot. If not, see . + +//! Version 3 of the Cross-Consensus Message format data structures. + +use super::v2::{ + Instruction as OldInstruction, Response as OldResponse, WeightLimit as OldWeightLimit, + Xcm as OldXcm, +}; +use crate::{DoubleEncoded, GetWeight}; +use alloc::{vec, vec::Vec}; +use bounded_collections::{parameter_types, BoundedVec}; +use core::{ + convert::{TryFrom, TryInto}, + fmt::Debug, + result, +}; +use derivative::Derivative; +use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +mod junction; +pub(crate) mod junctions; +mod multiasset; +mod multilocation; +mod traits; + +pub use junction::{BodyId, BodyPart, Junction, NetworkId}; +pub use junctions::Junctions; +pub use multiasset::{ + AssetId, AssetInstance, Fungibility, MultiAsset, MultiAssetFilter, MultiAssets, + WildFungibility, WildMultiAsset, +}; +pub use multilocation::{ + Ancestor, AncestorThen, InteriorMultiLocation, MultiLocation, Parent, ParentThen, +}; +pub use traits::{ + send_xcm, validate_send, Error, ExecuteXcm, Outcome, PreparedMessage, Result, SendError, + SendResult, SendXcm, Weight, XcmHash, +}; +// These parts of XCM v2 are unchanged in XCM v3, and are re-imported here. +pub use super::v2::OriginKind; + +/// This module's XCM version. +pub const VERSION: super::Version = 3; + +/// An identifier for a query. +pub type QueryId = u64; + +#[derive(Derivative, Default, Encode, Decode, TypeInfo)] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(Call))] +pub struct Xcm(pub Vec>); + +impl Xcm { + /// Create an empty instance. + pub fn new() -> Self { + Self(vec![]) + } + + /// Return `true` if no instructions are held in `self`. + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Return the number of instructions held in `self`. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Return a reference to the inner value. + pub fn inner(&self) -> &[Instruction] { + &self.0 + } + + /// Return a mutable reference to the inner value. + pub fn inner_mut(&mut self) -> &mut Vec> { + &mut self.0 + } + + /// Consume and return the inner value. + pub fn into_inner(self) -> Vec> { + self.0 + } + + /// Return an iterator over references to the items. + pub fn iter(&self) -> impl Iterator> { + self.0.iter() + } + + /// Return an iterator over mutable references to the items. + pub fn iter_mut(&mut self) -> impl Iterator> { + self.0.iter_mut() + } + + /// Consume and return an iterator over the items. + pub fn into_iter(self) -> impl Iterator> { + self.0.into_iter() + } + + /// Consume and either return `self` if it contains some instructions, or if it's empty, then + /// instead return the result of `f`. + pub fn or_else(self, f: impl FnOnce() -> Self) -> Self { + if self.0.is_empty() { + f() + } else { + self + } + } + + /// Return the first instruction, if any. + pub fn first(&self) -> Option<&Instruction> { + self.0.first() + } + + /// Return the last instruction, if any. + pub fn last(&self) -> Option<&Instruction> { + self.0.last() + } + + /// Return the only instruction, contained in `Self`, iff only one exists (`None` otherwise). + pub fn only(&self) -> Option<&Instruction> { + if self.0.len() == 1 { + self.0.first() + } else { + None + } + } + + /// Return the only instruction, contained in `Self`, iff only one exists (returns `self` + /// otherwise). + pub fn into_only(mut self) -> core::result::Result, Self> { + if self.0.len() == 1 { + self.0.pop().ok_or(self) + } else { + Err(self) + } + } +} + +impl From>> for Xcm { + fn from(c: Vec>) -> Self { + Self(c) + } +} + +impl From> for Vec> { + fn from(c: Xcm) -> Self { + c.0 + } +} + +/// A prelude for importing all types typically used when interacting with XCM messages. +pub mod prelude { + mod contents { + pub use super::super::{ + send_xcm, validate_send, Ancestor, AncestorThen, + AssetId::{self, *}, + AssetInstance::{self, *}, + BodyId, BodyPart, Error as XcmError, ExecuteXcm, + Fungibility::{self, *}, + Instruction::*, + InteriorMultiLocation, + Junction::{self, *}, + Junctions::{self, *}, + MaybeErrorCode, MultiAsset, + MultiAssetFilter::{self, *}, + MultiAssets, MultiLocation, + NetworkId::{self, *}, + OriginKind, Outcome, PalletInfo, Parent, ParentThen, PreparedMessage, QueryId, + QueryResponseInfo, Response, Result as XcmResult, SendError, SendResult, SendXcm, + Weight, + WeightLimit::{self, *}, + WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible}, + WildMultiAsset::{self, *}, + XcmContext, XcmHash, XcmWeightInfo, VERSION as XCM_VERSION, + }; + } + pub use super::{Instruction, Xcm}; + pub use contents::*; + pub mod opaque { + pub use super::{ + super::opaque::{Instruction, Xcm}, + contents::*, + }; + } +} + +parameter_types! { + pub MaxPalletNameLen: u32 = 48; + /// Maximum size of the encoded error code coming from a `Dispatch` result, used for + /// `MaybeErrorCode`. This is not (yet) enforced, so it's just an indication of expectation. + pub MaxDispatchErrorLen: u32 = 128; + pub MaxPalletsInfo: u32 = 64; +} + +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +pub struct PalletInfo { + #[codec(compact)] + index: u32, + name: BoundedVec, + module_name: BoundedVec, + #[codec(compact)] + major: u32, + #[codec(compact)] + minor: u32, + #[codec(compact)] + patch: u32, +} + +impl PalletInfo { + pub fn new( + index: u32, + name: Vec, + module_name: Vec, + major: u32, + minor: u32, + patch: u32, + ) -> result::Result { + let name = BoundedVec::try_from(name).map_err(|_| Error::Overflow)?; + let module_name = BoundedVec::try_from(module_name).map_err(|_| Error::Overflow)?; + + Ok(Self { index, name, module_name, major, minor, patch }) + } +} + +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +pub enum MaybeErrorCode { + Success, + Error(BoundedVec), + TruncatedError(BoundedVec), +} + +impl From> for MaybeErrorCode { + fn from(v: Vec) -> Self { + match BoundedVec::try_from(v) { + Ok(error) => MaybeErrorCode::Error(error), + Err(error) => MaybeErrorCode::TruncatedError(BoundedVec::truncate_from(error)), + } + } +} + +impl Default for MaybeErrorCode { + fn default() -> MaybeErrorCode { + MaybeErrorCode::Success + } +} + +/// Response data to a query. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +pub enum Response { + /// No response. Serves as a neutral default. + Null, + /// Some assets. + Assets(MultiAssets), + /// The outcome of an XCM instruction. + ExecutionResult(Option<(u32, Error)>), + /// An XCM version. + Version(super::Version), + /// The index, instance name, pallet name and version of some pallets. + PalletsInfo(BoundedVec), + /// The status of a dispatch attempt using `Transact`. + DispatchResult(MaybeErrorCode), +} + +impl Default for Response { + fn default() -> Self { + Self::Null + } +} + +/// Information regarding the composition of a query response. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] +pub struct QueryResponseInfo { + /// The destination to which the query response message should be send. + pub destination: MultiLocation, + /// The `query_id` field of the `QueryResponse` message. + #[codec(compact)] + pub query_id: QueryId, + /// The `max_weight` field of the `QueryResponse` message. + pub max_weight: Weight, +} + +/// An optional weight limit. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] +pub enum WeightLimit { + /// No weight limit imposed. + Unlimited, + /// Weight limit imposed of the inner value. + Limited(Weight), +} + +impl From> for WeightLimit { + fn from(x: Option) -> Self { + match x { + Some(w) => WeightLimit::Limited(w), + None => WeightLimit::Unlimited, + } + } +} + +impl From for Option { + fn from(x: WeightLimit) -> Self { + match x { + WeightLimit::Limited(w) => Some(w), + WeightLimit::Unlimited => None, + } + } +} + +impl TryFrom for WeightLimit { + type Error = (); + fn try_from(x: OldWeightLimit) -> result::Result { + use OldWeightLimit::*; + match x { + Limited(w) => Ok(Self::Limited(Weight::from_parts(w, DEFAULT_PROOF_SIZE))), + Unlimited => Ok(Self::Unlimited), + } + } +} + +/// Contextual data pertaining to a specific list of XCM instructions. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] +pub struct XcmContext { + /// The current value of the Origin register of the `XCVM`. + pub origin: Option, + /// The identity of the XCM; this may be a hash of its versioned encoding but could also be + /// a high-level identity set by an appropriate barrier. + pub message_id: XcmHash, + /// The current value of the Topic register of the `XCVM`. + pub topic: Option<[u8; 32]>, +} + +impl XcmContext { + /// Constructor which sets the message ID to the supplied parameter and leaves the origin and + /// topic unset. + #[deprecated = "Use `with_message_id` instead."] + pub fn with_message_hash(message_id: XcmHash) -> XcmContext { + XcmContext { origin: None, message_id, topic: None } + } + + /// Constructor which sets the message ID to the supplied parameter and leaves the origin and + /// topic unset. + pub fn with_message_id(message_id: XcmHash) -> XcmContext { + XcmContext { origin: None, message_id, topic: None } + } +} + +/// Cross-Consensus Message: A message from one consensus system to another. +/// +/// Consensus systems that may send and receive messages include blockchains and smart contracts. +/// +/// All messages are delivered from a known *origin*, expressed as a `MultiLocation`. +/// +/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the +/// outer XCM format, known as `VersionedXcm`. +#[derive(Derivative, Encode, Decode, TypeInfo, xcm_procedural::XcmWeightInfoTrait)] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(Call))] +pub enum Instruction { + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into the Holding + /// Register. + /// + /// - `assets`: The asset(s) to be withdrawn into holding. + /// + /// Kind: *Command*. + /// + /// Errors: + WithdrawAsset(MultiAssets), + + /// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` + /// system and equivalent derivatives should be placed into the Holding Register. + /// + /// - `assets`: The asset(s) that are minted into holding. + /// + /// Safety: `origin` must be trusted to have received and be storing `assets` such that they + /// may later be withdrawn should this system send a corresponding message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + ReserveAssetDeposited(MultiAssets), + + /// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should + /// be created and placed into the Holding Register. + /// + /// - `assets`: The asset(s) that are minted into the Holding Register. + /// + /// Safety: `origin` must be trusted to have irrevocably destroyed the corresponding `assets` + /// prior as a consequence of sending this message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + ReceiveTeleportedAsset(MultiAssets), + + /// Respond with information that the local system is expecting. + /// + /// - `query_id`: The identifier of the query that resulted in this message being sent. + /// - `response`: The message content. + /// - `max_weight`: The maximum weight that handling this response should take. + /// - `querier`: The location responsible for the initiation of the response, if there is one. + /// In general this will tend to be the same location as the receiver of this message. NOTE: + /// As usual, this is interpreted from the perspective of the receiving consensus system. + /// + /// Safety: Since this is information only, there are no immediate concerns. However, it should + /// be remembered that even if the Origin behaves reasonably, it can always be asked to make + /// a response to a third-party chain who may or may not be expecting the response. Therefore + /// the `querier` should be checked to match the expected value. + /// + /// Kind: *Information*. + /// + /// Errors: + QueryResponse { + #[codec(compact)] + query_id: QueryId, + response: Response, + max_weight: Weight, + querier: Option, + }, + + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets + /// under the ownership of `beneficiary`. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `beneficiary`: The new owner for the assets. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + TransferAsset { assets: MultiAssets, beneficiary: MultiLocation }, + + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets + /// under the ownership of `dest` within this consensus system (i.e. its sovereign account). + /// + /// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given + /// `xcm`. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `dest`: The location whose sovereign account will own the assets and thus the effective + /// beneficiary for the assets and the notification target for the reserve asset deposit + /// message. + /// - `xcm`: The instructions that should follow the `ReserveAssetDeposited` instruction, which + /// is sent onwards to `dest`. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + TransferReserveAsset { assets: MultiAssets, dest: MultiLocation, xcm: Xcm<()> }, + + /// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed + /// by the kind of origin `origin_kind`. + /// + /// The Transact Status Register is set according to the result of dispatching the call. + /// + /// - `origin_kind`: The means of expressing the message origin as a dispatch origin. + /// - `require_weight_at_most`: The weight of `call`; this should be at least the chain's + /// calculated weight and will be used in the weight determination arithmetic. + /// - `call`: The encoded transaction to be applied. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + Transact { origin_kind: OriginKind, require_weight_at_most: Weight, call: DoubleEncoded }, + + /// A message to notify about a new incoming HRMP channel. This message is meant to be sent by + /// the relay-chain to a para. + /// + /// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel + /// opening. + /// - `max_message_size`: The maximum size of a message proposed by the sender. + /// - `max_capacity`: The maximum number of messages that can be queued in the channel. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + HrmpNewChannelOpenRequest { + #[codec(compact)] + sender: u32, + #[codec(compact)] + max_message_size: u32, + #[codec(compact)] + max_capacity: u32, + }, + + /// A message to notify about that a previously sent open channel request has been accepted by + /// the recipient. That means that the channel will be opened during the next relay-chain + /// session change. This message is meant to be sent by the relay-chain to a para. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + /// + /// Errors: + HrmpChannelAccepted { + // NOTE: We keep this as a structured item to a) keep it consistent with the other Hrmp + // items; and b) because the field's meaning is not obvious/mentioned from the item name. + #[codec(compact)] + recipient: u32, + }, + + /// A message to notify that the other party in an open channel decided to close it. In + /// particular, `initiator` is going to close the channel opened from `sender` to the + /// `recipient`. The close will be enacted at the next relay-chain session change. This message + /// is meant to be sent by the relay-chain to a para. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + /// + /// Errors: + HrmpChannelClosing { + #[codec(compact)] + initiator: u32, + #[codec(compact)] + sender: u32, + #[codec(compact)] + recipient: u32, + }, + + /// Clear the origin. + /// + /// This may be used by the XCM author to ensure that later instructions cannot command the + /// authority of the origin (e.g. if they are being relayed from an untrusted source, as often + /// the case with `ReserveAssetDeposited`). + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + ClearOrigin, + + /// Mutate the origin to some interior location. + /// + /// Kind: *Command* + /// + /// Errors: + DescendOrigin(InteriorMultiLocation), + + /// Immediately report the contents of the Error Register to the given destination via XCM. + /// + /// A `QueryResponse` message of type `ExecutionOutcome` is sent to the described destination. + /// + /// - `response_info`: Information for making the response. + /// + /// Kind: *Command* + /// + /// Errors: + ReportError(QueryResponseInfo), + + /// Remove the asset(s) (`assets`) from the Holding Register and place equivalent assets under + /// the ownership of `beneficiary` within this consensus system. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `beneficiary`: The new owner for the assets. + /// + /// Kind: *Command* + /// + /// Errors: + DepositAsset { assets: MultiAssetFilter, beneficiary: MultiLocation }, + + /// Remove the asset(s) (`assets`) from the Holding Register and place equivalent assets under + /// the ownership of `dest` within this consensus system (i.e. deposit them into its sovereign + /// account). + /// + /// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given `effects`. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `dest`: The location whose sovereign account will own the assets and thus the effective + /// beneficiary for the assets and the notification target for the reserve asset deposit + /// message. + /// - `xcm`: The orders that should follow the `ReserveAssetDeposited` instruction which is + /// sent onwards to `dest`. + /// + /// Kind: *Command* + /// + /// Errors: + DepositReserveAsset { assets: MultiAssetFilter, dest: MultiLocation, xcm: Xcm<()> }, + + /// Remove the asset(s) (`want`) from the Holding Register and replace them with alternative + /// assets. + /// + /// The minimum amount of assets to be received into the Holding Register for the order not to + /// fail may be stated. + /// + /// - `give`: The maximum amount of assets to remove from holding. + /// - `want`: The minimum amount of assets which `give` should be exchanged for. + /// - `maximal`: If `true`, then prefer to give as much as possible up to the limit of `give` + /// and receive accordingly more. If `false`, then prefer to give as little as possible in + /// order to receive as little as possible while receiving at least `want`. + /// + /// Kind: *Command* + /// + /// Errors: + ExchangeAsset { give: MultiAssetFilter, want: MultiAssets, maximal: bool }, + + /// Remove the asset(s) (`assets`) from holding and send a `WithdrawAsset` XCM message to a + /// reserve location. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The + /// sovereign account of this consensus system *on the reserve location* will have + /// appropriate assets withdrawn and `effects` will be executed on them. There will typically + /// be only one valid location on any given asset/chain combination. + /// - `xcm`: The instructions to execute on the assets once withdrawn *on the reserve + /// location*. + /// + /// Kind: *Command* + /// + /// Errors: + InitiateReserveWithdraw { assets: MultiAssetFilter, reserve: MultiLocation, xcm: Xcm<()> }, + + /// Remove the asset(s) (`assets`) from holding and send a `ReceiveTeleportedAsset` XCM message + /// to a `dest` location. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `dest`: A valid location that respects teleports coming from this location. + /// - `xcm`: The instructions to execute on the assets once arrived *on the destination + /// location*. + /// + /// NOTE: The `dest` location *MUST* respect this origin as a valid teleportation origin for + /// all `assets`. If it does not, then the assets may be lost. + /// + /// Kind: *Command* + /// + /// Errors: + InitiateTeleport { assets: MultiAssetFilter, dest: MultiLocation, xcm: Xcm<()> }, + + /// Report to a given destination the contents of the Holding Register. + /// + /// A `QueryResponse` message of type `Assets` is sent to the described destination. + /// + /// - `response_info`: Information for making the response. + /// - `assets`: A filter for the assets that should be reported back. The assets reported back + /// will be, asset-wise, *the lesser of this value and the holding register*. No wildcards + /// will be used when reporting assets back. + /// + /// Kind: *Command* + /// + /// Errors: + ReportHolding { response_info: QueryResponseInfo, assets: MultiAssetFilter }, + + /// Pay for the execution of some XCM `xcm` and `orders` with up to `weight` + /// picoseconds of execution time, paying for this with up to `fees` from the Holding Register. + /// + /// - `fees`: The asset(s) to remove from the Holding Register to pay for fees. + /// - `weight_limit`: The maximum amount of weight to purchase; this must be at least the + /// expected maximum weight of the total XCM to be executed for the + /// `AllowTopLevelPaidExecutionFrom` barrier to allow the XCM be executed. + /// + /// Kind: *Command* + /// + /// Errors: + BuyExecution { fees: MultiAsset, weight_limit: WeightLimit }, + + /// Refund any surplus weight previously bought with `BuyExecution`. + /// + /// Kind: *Command* + /// + /// Errors: None. + RefundSurplus, + + /// Set the Error Handler Register. This is code that should be called in the case of an error + /// happening. + /// + /// An error occurring within execution of this code will _NOT_ result in the error register + /// being set, nor will an error handler be called due to it. The error handler and appendix + /// may each still be set. + /// + /// The apparent weight of this instruction is inclusive of the inner `Xcm`; the executing + /// weight however includes only the difference between the previous handler and the new + /// handler, which can reasonably be negative, which would result in a surplus. + /// + /// Kind: *Command* + /// + /// Errors: None. + SetErrorHandler(Xcm), + + /// Set the Appendix Register. This is code that should be called after code execution + /// (including the error handler if any) is finished. This will be called regardless of whether + /// an error occurred. + /// + /// Any error occurring due to execution of this code will result in the error register being + /// set, and the error handler (if set) firing. + /// + /// The apparent weight of this instruction is inclusive of the inner `Xcm`; the executing + /// weight however includes only the difference between the previous appendix and the new + /// appendix, which can reasonably be negative, which would result in a surplus. + /// + /// Kind: *Command* + /// + /// Errors: None. + SetAppendix(Xcm), + + /// Clear the Error Register. + /// + /// Kind: *Command* + /// + /// Errors: None. + ClearError, + + /// Create some assets which are being held on behalf of the origin. + /// + /// - `assets`: The assets which are to be claimed. This must match exactly with the assets + /// claimable by the origin of the ticket. + /// - `ticket`: The ticket of the asset; this is an abstract identifier to help locate the + /// asset. + /// + /// Kind: *Command* + /// + /// Errors: + ClaimAsset { assets: MultiAssets, ticket: MultiLocation }, + + /// Always throws an error of type `Trap`. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `Trap`: All circumstances, whose inner value is the same as this item's inner value. + Trap(#[codec(compact)] u64), + + /// Ask the destination system to respond with the most recent version of XCM that they + /// support in a `QueryResponse` instruction. Any changes to this should also elicit similar + /// responses when they happen. + /// + /// - `query_id`: An identifier that will be replicated into the returned XCM message. + /// - `max_response_weight`: The maximum amount of weight that the `QueryResponse` item which + /// is sent as a reply may take to execute. NOTE: If this is unexpectedly large then the + /// response may not execute at all. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible* + SubscribeVersion { + #[codec(compact)] + query_id: QueryId, + max_response_weight: Weight, + }, + + /// Cancel the effect of a previous `SubscribeVersion` instruction. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible* + UnsubscribeVersion, + + /// Reduce Holding by up to the given assets. + /// + /// Holding is reduced by as much as possible up to the assets in the parameter. It is not an + /// error if the Holding does not contain the assets (to make this an error, use `ExpectAsset` + /// prior). + /// + /// Kind: *Command* + /// + /// Errors: *Infallible* + BurnAsset(MultiAssets), + + /// Throw an error if Holding does not contain at least the given assets. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If Holding Register does not contain the assets in the parameter. + ExpectAsset(MultiAssets), + + /// Ensure that the Origin Register equals some given value and throw an error if not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If Origin Register is not equal to the parameter. + ExpectOrigin(Option), + + /// Ensure that the Error Register equals some given value and throw an error if not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If the value of the Error Register is not equal to the parameter. + ExpectError(Option<(u32, Error)>), + + /// Ensure that the Transact Status Register equals some given value and throw an error if + /// not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If the value of the Transact Status Register is not equal to the + /// parameter. + ExpectTransactStatus(MaybeErrorCode), + + /// Query the existence of a particular pallet type. + /// + /// - `module_name`: The module name of the pallet to query. + /// - `response_info`: Information for making the response. + /// + /// Sends a `QueryResponse` to Origin whose data field `PalletsInfo` containing the information + /// of all pallets on the local chain whose name is equal to `name`. This is empty in the case + /// that the local chain is not based on Substrate Frame. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + QueryPallet { module_name: Vec, response_info: QueryResponseInfo }, + + /// Ensure that a particular pallet with a particular version exists. + /// + /// - `index: Compact`: The index which identifies the pallet. An error if no pallet exists at + /// this index. + /// - `name: Vec`: Name which must be equal to the name of the pallet. + /// - `module_name: Vec`: Module name which must be equal to the name of the module in + /// which the pallet exists. + /// - `crate_major: Compact`: Version number which must be equal to the major version of the + /// crate which implements the pallet. + /// - `min_crate_minor: Compact`: Version number which must be at most the minor version of the + /// crate which implements the pallet. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: In case any of the expectations are broken. + ExpectPallet { + #[codec(compact)] + index: u32, + name: Vec, + module_name: Vec, + #[codec(compact)] + crate_major: u32, + #[codec(compact)] + min_crate_minor: u32, + }, + + /// Send a `QueryResponse` message containing the value of the Transact Status Register to some + /// destination. + /// + /// - `query_response_info`: The information needed for constructing and sending the + /// `QueryResponse` message. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + ReportTransactStatus(QueryResponseInfo), + + /// Set the Transact Status Register to its default, cleared, value. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Infallible*. + ClearTransactStatus, + + /// Set the Origin Register to be some child of the Universal Ancestor. + /// + /// Safety: Should only be usable if the Origin is trusted to represent the Universal Ancestor + /// child in general. In general, no Origin should be able to represent the Universal Ancestor + /// child which is the root of the local consensus system since it would by extension + /// allow it to act as any location within the local consensus. + /// + /// The `Junction` parameter should generally be a `GlobalConsensus` variant since it is only + /// these which are children of the Universal Ancestor. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + UniversalOrigin(Junction), + + /// Send a message on to Non-Local Consensus system. + /// + /// This will tend to utilize some extra-consensus mechanism, the obvious one being a bridge. + /// A fee may be charged; this may be determined based on the contents of `xcm`. It will be + /// taken from the Holding register. + /// + /// - `network`: The remote consensus system to which the message should be exported. + /// - `destination`: The location relative to the remote consensus system to which the message + /// should be sent on arrival. + /// - `xcm`: The message to be exported. + /// + /// As an example, to export a message for execution on Statemine (parachain #1000 in the + /// Kusama network), you would call with `network: NetworkId::Kusama` and + /// `destination: X1(Parachain(1000))`. Alternatively, to export a message for execution on + /// Polkadot, you would call with `network: NetworkId:: Polkadot` and `destination: Here`. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + ExportMessage { network: NetworkId, destination: InteriorMultiLocation, xcm: Xcm<()> }, + + /// Lock the locally held asset and prevent further transfer or withdrawal. + /// + /// This restriction may be removed by the `UnlockAsset` instruction being called with an + /// Origin of `unlocker` and a `target` equal to the current `Origin`. + /// + /// If the locking is successful, then a `NoteUnlockable` instruction is sent to `unlocker`. + /// + /// - `asset`: The asset(s) which should be locked. + /// - `unlocker`: The value which the Origin must be for a corresponding `UnlockAsset` + /// instruction to work. + /// + /// Kind: *Command*. + /// + /// Errors: + LockAsset { asset: MultiAsset, unlocker: MultiLocation }, + + /// Remove the lock over `asset` on this chain and (if nothing else is preventing it) allow the + /// asset to be transferred. + /// + /// - `asset`: The asset to be unlocked. + /// - `target`: The owner of the asset on the local chain. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + UnlockAsset { asset: MultiAsset, target: MultiLocation }, + + /// Asset (`asset`) has been locked on the `origin` system and may not be transferred. It may + /// only be unlocked with the receipt of the `UnlockAsset` instruction from this chain. + /// + /// - `asset`: The asset(s) which are now unlockable from this origin. + /// - `owner`: The owner of the asset on the chain in which it was locked. This may be a + /// location specific to the origin network. + /// + /// Safety: `origin` must be trusted to have locked the corresponding `asset` + /// prior as a consequence of sending this message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + NoteUnlockable { asset: MultiAsset, owner: MultiLocation }, + + /// Send an `UnlockAsset` instruction to the `locker` for the given `asset`. + /// + /// This may fail if the local system is making use of the fact that the asset is locked or, + /// of course, if there is no record that the asset actually is locked. + /// + /// - `asset`: The asset(s) to be unlocked. + /// - `locker`: The location from which a previous `NoteUnlockable` was sent and to which an + /// `UnlockAsset` should be sent. + /// + /// Kind: *Command*. + /// + /// Errors: + RequestUnlock { asset: MultiAsset, locker: MultiLocation }, + + /// Sets the Fees Mode Register. + /// + /// - `jit_withdraw`: The fees mode item; if set to `true` then fees for any instructions are + /// withdrawn as needed using the same mechanism as `WithdrawAssets`. + /// + /// Kind: *Command*. + /// + /// Errors: + SetFeesMode { jit_withdraw: bool }, + + /// Set the Topic Register. + /// + /// The 32-byte array identifier in the parameter is not guaranteed to be + /// unique; if such a property is desired, it is up to the code author to + /// enforce uniqueness. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: + SetTopic([u8; 32]), + + /// Clear the Topic Register. + /// + /// Kind: *Command* + /// + /// Errors: None. + ClearTopic, + + /// Alter the current Origin to another given origin. + /// + /// Kind: *Command* + /// + /// Errors: If the existing state would not allow such a change. + AliasOrigin(MultiLocation), + + /// A directive to indicate that the origin expects free execution of the message. + /// + /// At execution time, this instruction just does a check on the Origin register. + /// However, at the barrier stage messages starting with this instruction can be disregarded if + /// the origin is not acceptable for free execution or the `weight_limit` is `Limited` and + /// insufficient. + /// + /// Kind: *Indication* + /// + /// Errors: If the given origin is `Some` and not equal to the current Origin register. + UnpaidExecution { weight_limit: WeightLimit, check_origin: Option }, +} + +impl Xcm { + pub fn into(self) -> Xcm { + Xcm::from(self) + } + pub fn from(xcm: Xcm) -> Self { + Self(xcm.0.into_iter().map(Instruction::::from).collect()) + } +} + +impl Instruction { + pub fn into(self) -> Instruction { + Instruction::from(self) + } + pub fn from(xcm: Instruction) -> Self { + use Instruction::*; + match xcm { + WithdrawAsset(assets) => WithdrawAsset(assets), + ReserveAssetDeposited(assets) => ReserveAssetDeposited(assets), + ReceiveTeleportedAsset(assets) => ReceiveTeleportedAsset(assets), + QueryResponse { query_id, response, max_weight, querier } => + QueryResponse { query_id, response, max_weight, querier }, + TransferAsset { assets, beneficiary } => TransferAsset { assets, beneficiary }, + TransferReserveAsset { assets, dest, xcm } => + TransferReserveAsset { assets, dest, xcm }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_kind, require_weight_at_most, call } => + Transact { origin_kind, require_weight_at_most, call: call.into() }, + ReportError(response_info) => ReportError(response_info), + DepositAsset { assets, beneficiary } => DepositAsset { assets, beneficiary }, + DepositReserveAsset { assets, dest, xcm } => DepositReserveAsset { assets, dest, xcm }, + ExchangeAsset { give, want, maximal } => ExchangeAsset { give, want, maximal }, + InitiateReserveWithdraw { assets, reserve, xcm } => + InitiateReserveWithdraw { assets, reserve, xcm }, + InitiateTeleport { assets, dest, xcm } => InitiateTeleport { assets, dest, xcm }, + ReportHolding { response_info, assets } => ReportHolding { response_info, assets }, + BuyExecution { fees, weight_limit } => BuyExecution { fees, weight_limit }, + ClearOrigin => ClearOrigin, + DescendOrigin(who) => DescendOrigin(who), + RefundSurplus => RefundSurplus, + SetErrorHandler(xcm) => SetErrorHandler(xcm.into()), + SetAppendix(xcm) => SetAppendix(xcm.into()), + ClearError => ClearError, + ClaimAsset { assets, ticket } => ClaimAsset { assets, ticket }, + Trap(code) => Trap(code), + SubscribeVersion { query_id, max_response_weight } => + SubscribeVersion { query_id, max_response_weight }, + UnsubscribeVersion => UnsubscribeVersion, + BurnAsset(assets) => BurnAsset(assets), + ExpectAsset(assets) => ExpectAsset(assets), + ExpectOrigin(origin) => ExpectOrigin(origin), + ExpectError(error) => ExpectError(error), + ExpectTransactStatus(transact_status) => ExpectTransactStatus(transact_status), + QueryPallet { module_name, response_info } => + QueryPallet { module_name, response_info }, + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + ExpectPallet { index, name, module_name, crate_major, min_crate_minor }, + ReportTransactStatus(response_info) => ReportTransactStatus(response_info), + ClearTransactStatus => ClearTransactStatus, + UniversalOrigin(j) => UniversalOrigin(j), + ExportMessage { network, destination, xcm } => + ExportMessage { network, destination, xcm }, + LockAsset { asset, unlocker } => LockAsset { asset, unlocker }, + UnlockAsset { asset, target } => UnlockAsset { asset, target }, + NoteUnlockable { asset, owner } => NoteUnlockable { asset, owner }, + RequestUnlock { asset, locker } => RequestUnlock { asset, locker }, + SetFeesMode { jit_withdraw } => SetFeesMode { jit_withdraw }, + SetTopic(topic) => SetTopic(topic), + ClearTopic => ClearTopic, + AliasOrigin(location) => AliasOrigin(location), + UnpaidExecution { weight_limit, check_origin } => + UnpaidExecution { weight_limit, check_origin }, + } + } +} + +// TODO: Automate Generation +impl> GetWeight for Instruction { + fn weight(&self) -> Weight { + use Instruction::*; + match self { + WithdrawAsset(assets) => W::withdraw_asset(assets), + ReserveAssetDeposited(assets) => W::reserve_asset_deposited(assets), + ReceiveTeleportedAsset(assets) => W::receive_teleported_asset(assets), + QueryResponse { query_id, response, max_weight, querier } => + W::query_response(query_id, response, max_weight, querier), + TransferAsset { assets, beneficiary } => W::transfer_asset(assets, beneficiary), + TransferReserveAsset { assets, dest, xcm } => + W::transfer_reserve_asset(&assets, dest, xcm), + Transact { origin_kind, require_weight_at_most, call } => + W::transact(origin_kind, require_weight_at_most, call), + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + W::hrmp_new_channel_open_request(sender, max_message_size, max_capacity), + HrmpChannelAccepted { recipient } => W::hrmp_channel_accepted(recipient), + HrmpChannelClosing { initiator, sender, recipient } => + W::hrmp_channel_closing(initiator, sender, recipient), + ClearOrigin => W::clear_origin(), + DescendOrigin(who) => W::descend_origin(who), + ReportError(response_info) => W::report_error(&response_info), + DepositAsset { assets, beneficiary } => W::deposit_asset(assets, beneficiary), + DepositReserveAsset { assets, dest, xcm } => + W::deposit_reserve_asset(assets, dest, xcm), + ExchangeAsset { give, want, maximal } => W::exchange_asset(give, want, maximal), + InitiateReserveWithdraw { assets, reserve, xcm } => + W::initiate_reserve_withdraw(assets, reserve, xcm), + InitiateTeleport { assets, dest, xcm } => W::initiate_teleport(assets, dest, xcm), + ReportHolding { response_info, assets } => W::report_holding(&response_info, &assets), + BuyExecution { fees, weight_limit } => W::buy_execution(fees, weight_limit), + RefundSurplus => W::refund_surplus(), + SetErrorHandler(xcm) => W::set_error_handler(xcm), + SetAppendix(xcm) => W::set_appendix(xcm), + ClearError => W::clear_error(), + ClaimAsset { assets, ticket } => W::claim_asset(assets, ticket), + Trap(code) => W::trap(code), + SubscribeVersion { query_id, max_response_weight } => + W::subscribe_version(query_id, max_response_weight), + UnsubscribeVersion => W::unsubscribe_version(), + BurnAsset(assets) => W::burn_asset(assets), + ExpectAsset(assets) => W::expect_asset(assets), + ExpectOrigin(origin) => W::expect_origin(origin), + ExpectError(error) => W::expect_error(error), + ExpectTransactStatus(transact_status) => W::expect_transact_status(transact_status), + QueryPallet { module_name, response_info } => + W::query_pallet(module_name, response_info), + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + W::expect_pallet(index, name, module_name, crate_major, min_crate_minor), + ReportTransactStatus(response_info) => W::report_transact_status(response_info), + ClearTransactStatus => W::clear_transact_status(), + UniversalOrigin(j) => W::universal_origin(j), + ExportMessage { network, destination, xcm } => + W::export_message(network, destination, xcm), + LockAsset { asset, unlocker } => W::lock_asset(asset, unlocker), + UnlockAsset { asset, target } => W::unlock_asset(asset, target), + NoteUnlockable { asset, owner } => W::note_unlockable(asset, owner), + RequestUnlock { asset, locker } => W::request_unlock(asset, locker), + SetFeesMode { jit_withdraw } => W::set_fees_mode(jit_withdraw), + SetTopic(topic) => W::set_topic(topic), + ClearTopic => W::clear_topic(), + AliasOrigin(location) => W::alias_origin(location), + UnpaidExecution { weight_limit, check_origin } => + W::unpaid_execution(weight_limit, check_origin), + } + } +} + +pub mod opaque { + /// The basic concrete type of `Xcm`, which doesn't make any assumptions about the + /// format of a call other than it is pre-encoded. + pub type Xcm = super::Xcm<()>; + + /// The basic concrete type of `Instruction`, which doesn't make any assumptions about the + /// format of a call other than it is pre-encoded. + pub type Instruction = super::Instruction<()>; +} + +// Convert from a v2 response to a v3 response. +impl TryFrom for Response { + type Error = (); + fn try_from(old_response: OldResponse) -> result::Result { + match old_response { + OldResponse::Assets(assets) => Ok(Self::Assets(assets.try_into()?)), + OldResponse::Version(version) => Ok(Self::Version(version)), + OldResponse::ExecutionResult(error) => Ok(Self::ExecutionResult(match error { + Some((i, e)) => Some((i, e.try_into()?)), + None => None, + })), + OldResponse::Null => Ok(Self::Null), + } + } +} + +// Convert from a v2 XCM to a v3 XCM. +impl TryFrom> for Xcm { + type Error = (); + fn try_from(old_xcm: OldXcm) -> result::Result { + Ok(Xcm(old_xcm.0.into_iter().map(TryInto::try_into).collect::>()?)) + } +} + +/// Default value for the proof size weight component when converting from V2. Set at 64 KB. +/// NOTE: Make sure this is removed after we properly account for PoV weights. +const DEFAULT_PROOF_SIZE: u64 = 64 * 1024; + +// Convert from a v2 instruction to a v3 instruction. +impl TryFrom> for Instruction { + type Error = (); + fn try_from(old_instruction: OldInstruction) -> result::Result { + use OldInstruction::*; + Ok(match old_instruction { + WithdrawAsset(assets) => Self::WithdrawAsset(assets.try_into()?), + ReserveAssetDeposited(assets) => Self::ReserveAssetDeposited(assets.try_into()?), + ReceiveTeleportedAsset(assets) => Self::ReceiveTeleportedAsset(assets.try_into()?), + QueryResponse { query_id, response, max_weight } => Self::QueryResponse { + query_id, + response: response.try_into()?, + max_weight: Weight::from_parts(max_weight, DEFAULT_PROOF_SIZE), + querier: None, + }, + TransferAsset { assets, beneficiary } => Self::TransferAsset { + assets: assets.try_into()?, + beneficiary: beneficiary.try_into()?, + }, + TransferReserveAsset { assets, dest, xcm } => Self::TransferReserveAsset { + assets: assets.try_into()?, + dest: dest.try_into()?, + xcm: xcm.try_into()?, + }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + Self::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => Self::HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + Self::HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_type, require_weight_at_most, call } => Self::Transact { + origin_kind: origin_type, + require_weight_at_most: Weight::from_parts( + require_weight_at_most, + DEFAULT_PROOF_SIZE, + ), + call: call.into(), + }, + ReportError { query_id, dest, max_response_weight } => { + let response_info = QueryResponseInfo { + destination: dest.try_into()?, + query_id, + max_weight: Weight::from_parts(max_response_weight, DEFAULT_PROOF_SIZE), + }; + Self::ReportError(response_info) + }, + DepositAsset { assets, max_assets, beneficiary } => Self::DepositAsset { + assets: (assets, max_assets).try_into()?, + beneficiary: beneficiary.try_into()?, + }, + DepositReserveAsset { assets, max_assets, dest, xcm } => { + let assets = (assets, max_assets).try_into()?; + Self::DepositReserveAsset { assets, dest: dest.try_into()?, xcm: xcm.try_into()? } + }, + ExchangeAsset { give, receive } => { + let give = give.try_into()?; + let want = receive.try_into()?; + Self::ExchangeAsset { give, want, maximal: true } + }, + InitiateReserveWithdraw { assets, reserve, xcm } => Self::InitiateReserveWithdraw { + assets: assets.try_into()?, + reserve: reserve.try_into()?, + xcm: xcm.try_into()?, + }, + InitiateTeleport { assets, dest, xcm } => Self::InitiateTeleport { + assets: assets.try_into()?, + dest: dest.try_into()?, + xcm: xcm.try_into()?, + }, + QueryHolding { query_id, dest, assets, max_response_weight } => { + let response_info = QueryResponseInfo { + destination: dest.try_into()?, + query_id, + max_weight: Weight::from_parts(max_response_weight, DEFAULT_PROOF_SIZE), + }; + Self::ReportHolding { response_info, assets: assets.try_into()? } + }, + BuyExecution { fees, weight_limit } => Self::BuyExecution { + fees: fees.try_into()?, + weight_limit: weight_limit.try_into()?, + }, + ClearOrigin => Self::ClearOrigin, + DescendOrigin(who) => Self::DescendOrigin(who.try_into()?), + RefundSurplus => Self::RefundSurplus, + SetErrorHandler(xcm) => Self::SetErrorHandler(xcm.try_into()?), + SetAppendix(xcm) => Self::SetAppendix(xcm.try_into()?), + ClearError => Self::ClearError, + ClaimAsset { assets, ticket } => { + let assets = assets.try_into()?; + let ticket = ticket.try_into()?; + Self::ClaimAsset { assets, ticket } + }, + Trap(code) => Self::Trap(code), + SubscribeVersion { query_id, max_response_weight } => Self::SubscribeVersion { + query_id, + max_response_weight: Weight::from_parts(max_response_weight, DEFAULT_PROOF_SIZE), + }, + UnsubscribeVersion => Self::UnsubscribeVersion, + }) + } +} + +#[cfg(test)] +mod tests { + use super::{prelude::*, *}; + use crate::v2::{ + Junctions::Here as OldHere, MultiAssetFilter as OldMultiAssetFilter, + WildMultiAsset as OldWildMultiAsset, + }; + + #[test] + fn basic_roundtrip_works() { + let xcm = Xcm::<()>(vec![TransferAsset { + assets: (Here, 1u128).into(), + beneficiary: Here.into(), + }]); + let old_xcm = OldXcm::<()>(vec![OldInstruction::TransferAsset { + assets: (OldHere, 1).into(), + beneficiary: OldHere.into(), + }]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn teleport_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + ReceiveTeleportedAsset((Here, 1u128).into()), + ClearOrigin, + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm: OldXcm<()> = OldXcm::<()>(vec![ + OldInstruction::ReceiveTeleportedAsset((OldHere, 1).into()), + OldInstruction::ClearOrigin, + OldInstruction::DepositAsset { + assets: crate::v2::MultiAssetFilter::Wild(crate::v2::WildMultiAsset::All), + max_assets: 1, + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn reserve_deposit_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + ReserveAssetDeposited((Here, 1u128).into()), + ClearOrigin, + BuyExecution { + fees: (Here, 1u128).into(), + weight_limit: Some(Weight::from_parts(1, DEFAULT_PROOF_SIZE)).into(), + }, + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::ReserveAssetDeposited((OldHere, 1).into()), + OldInstruction::ClearOrigin, + OldInstruction::BuyExecution { + fees: (OldHere, 1).into(), + weight_limit: Some(1).into(), + }, + OldInstruction::DepositAsset { + assets: crate::v2::MultiAssetFilter::Wild(crate::v2::WildMultiAsset::All), + max_assets: 1, + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn deposit_asset_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + WithdrawAsset((Here, 1u128).into()), + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::WithdrawAsset((OldHere, 1).into()), + OldInstruction::DepositAsset { + assets: OldMultiAssetFilter::Wild(OldWildMultiAsset::All), + max_assets: 1, + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn deposit_reserve_asset_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + WithdrawAsset((Here, 1u128).into()), + DepositReserveAsset { + assets: Wild(AllCounted(1)), + dest: Here.into(), + xcm: Xcm::<()>(vec![]), + }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::WithdrawAsset((OldHere, 1).into()), + OldInstruction::DepositReserveAsset { + assets: OldMultiAssetFilter::Wild(OldWildMultiAsset::All), + max_assets: 1, + dest: OldHere.into(), + xcm: OldXcm::<()>(vec![]), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } +} diff --git a/polkadot/xcm/src/v3/multiasset.rs b/polkadot/xcm/src/v3/multiasset.rs new file mode 100644 index 0000000000000000000000000000000000000000..1668d1b870dcf12bb76ced97cd25aa3dfb929d83 --- /dev/null +++ b/polkadot/xcm/src/v3/multiasset.rs @@ -0,0 +1,977 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// 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 Polkadot. If not, see . + +//! Cross-Consensus Message format asset data structures. +//! +//! This encompasses four types for representing assets: +//! - `MultiAsset`: A description of a single asset, either an instance of a non-fungible or some +//! amount of a fungible. +//! - `MultiAssets`: A collection of `MultiAsset`s. These are stored in a `Vec` and sorted with +//! fungibles first. +//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific +//! kind. +//! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently +//! filtering an XCM holding account. + +use super::{InteriorMultiLocation, MultiLocation}; +use crate::v2::{ + AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility, + MultiAsset as OldMultiAsset, MultiAssetFilter as OldMultiAssetFilter, + MultiAssets as OldMultiAssets, WildFungibility as OldWildFungibility, + WildMultiAsset as OldWildMultiAsset, +}; +use alloc::{vec, vec::Vec}; +use core::{ + cmp::Ordering, + convert::{TryFrom, TryInto}, +}; +use parity_scale_codec::{self as codec, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// A general identifier for an instance of a non-fungible asset class. +#[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo, MaxEncodedLen, +)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum AssetInstance { + /// Undefined - used if the non-fungible asset class has only one instance. + Undefined, + + /// A compact index. Technically this could be greater than `u128`, but this implementation + /// supports only values up to `2**128 - 1`. + Index(#[codec(compact)] u128), + + /// A 4-byte fixed-length datum. + Array4([u8; 4]), + + /// An 8-byte fixed-length datum. + Array8([u8; 8]), + + /// A 16-byte fixed-length datum. + Array16([u8; 16]), + + /// A 32-byte fixed-length datum. + Array32([u8; 32]), +} + +impl TryFrom for AssetInstance { + type Error = (); + fn try_from(value: OldAssetInstance) -> Result { + use OldAssetInstance::*; + Ok(match value { + Undefined => Self::Undefined, + Index(n) => Self::Index(n), + Array4(n) => Self::Array4(n), + Array8(n) => Self::Array8(n), + Array16(n) => Self::Array16(n), + Array32(n) => Self::Array32(n), + Blob(_) => return Err(()), + }) + } +} + +impl From<()> for AssetInstance { + fn from(_: ()) -> Self { + Self::Undefined + } +} + +impl From<[u8; 4]> for AssetInstance { + fn from(x: [u8; 4]) -> Self { + Self::Array4(x) + } +} + +impl From<[u8; 8]> for AssetInstance { + fn from(x: [u8; 8]) -> Self { + Self::Array8(x) + } +} + +impl From<[u8; 16]> for AssetInstance { + fn from(x: [u8; 16]) -> Self { + Self::Array16(x) + } +} + +impl From<[u8; 32]> for AssetInstance { + fn from(x: [u8; 32]) -> Self { + Self::Array32(x) + } +} + +impl From for AssetInstance { + fn from(x: u8) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u16) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u32) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u64) -> Self { + Self::Index(x as u128) + } +} + +impl TryFrom for () { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Undefined => Ok(()), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 4] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array4(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 8] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array8(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 16] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array16(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 32] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array32(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for u8 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u16 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u32 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u64 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u128 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => Ok(x), + _ => Err(()), + } + } +} + +/// Classification of whether an asset is fungible or not, along with a mandatory amount or +/// instance. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum Fungibility { + /// A fungible asset; we record a number of units, as a `u128` in the inner item. + Fungible(#[codec(compact)] u128), + /// A non-fungible asset. We record the instance identifier in the inner item. Only one asset + /// of each instance identifier may ever be in existence at once. + NonFungible(AssetInstance), +} + +#[derive(Decode)] +enum UncheckedFungibility { + Fungible(#[codec(compact)] u128), + NonFungible(AssetInstance), +} + +impl Decode for Fungibility { + fn decode(input: &mut I) -> Result { + match UncheckedFungibility::decode(input)? { + UncheckedFungibility::Fungible(a) if a != 0 => Ok(Self::Fungible(a)), + UncheckedFungibility::NonFungible(i) => Ok(Self::NonFungible(i)), + UncheckedFungibility::Fungible(_) => + Err("Fungible asset of zero amount is not allowed".into()), + } + } +} + +impl Fungibility { + pub fn is_kind(&self, w: WildFungibility) -> bool { + use Fungibility::*; + use WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible}; + matches!((self, w), (Fungible(_), WildFungible) | (NonFungible(_), WildNonFungible)) + } +} + +impl From for Fungibility { + fn from(amount: i32) -> Fungibility { + debug_assert_ne!(amount, 0); + Fungibility::Fungible(amount as u128) + } +} + +impl From for Fungibility { + fn from(amount: u128) -> Fungibility { + debug_assert_ne!(amount, 0); + Fungibility::Fungible(amount) + } +} + +impl> From for Fungibility { + fn from(instance: T) -> Fungibility { + Fungibility::NonFungible(instance.into()) + } +} + +impl TryFrom for Fungibility { + type Error = (); + fn try_from(value: OldFungibility) -> Result { + use OldFungibility::*; + Ok(match value { + Fungible(n) => Self::Fungible(n), + NonFungible(i) => Self::NonFungible(i.try_into()?), + }) + } +} + +/// Classification of whether an asset is fungible or not. +#[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, +)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum WildFungibility { + /// The asset is fungible. + Fungible, + /// The asset is not fungible. + NonFungible, +} + +impl TryFrom for WildFungibility { + type Error = (); + fn try_from(value: OldWildFungibility) -> Result { + use OldWildFungibility::*; + Ok(match value { + Fungible => Self::Fungible, + NonFungible => Self::NonFungible, + }) + } +} + +/// Classification of an asset being concrete or abstract. +#[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, +)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum AssetId { + /// A specific location identifying an asset. + Concrete(MultiLocation), + /// An abstract location; this is a name which may mean different specific locations on + /// different chains at different times. + Abstract([u8; 32]), +} + +impl> From for AssetId { + fn from(x: T) -> Self { + Self::Concrete(x.into()) + } +} + +impl From<[u8; 32]> for AssetId { + fn from(x: [u8; 32]) -> Self { + Self::Abstract(x) + } +} + +impl TryFrom for AssetId { + type Error = (); + fn try_from(old: OldAssetId) -> Result { + use OldAssetId::*; + Ok(match old { + Concrete(l) => Self::Concrete(l.try_into()?), + Abstract(v) if v.len() <= 32 => { + let mut r = [0u8; 32]; + r[..v.len()].copy_from_slice(&v[..]); + Self::Abstract(r) + }, + _ => return Err(()), + }) + } +} + +impl AssetId { + /// Prepend a `MultiLocation` to a concrete asset, giving it a new root location. + pub fn prepend_with(&mut self, prepend: &MultiLocation) -> Result<(), ()> { + if let AssetId::Concrete(ref mut l) = self { + l.prepend_with(*prepend).map_err(|_| ())?; + } + Ok(()) + } + + /// Mutate the asset to represent the same value from the perspective of a new `target` + /// location. The local chain's location is provided in `context`. + pub fn reanchor( + &mut self, + target: &MultiLocation, + context: InteriorMultiLocation, + ) -> Result<(), ()> { + if let AssetId::Concrete(ref mut l) = self { + l.reanchor(target, context)?; + } + Ok(()) + } + + /// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding + /// `MultiAsset` value. + pub fn into_multiasset(self, fun: Fungibility) -> MultiAsset { + MultiAsset { fun, id: self } + } + + /// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding + /// `WildMultiAsset` wildcard (`AllOf`) value. + pub fn into_wild(self, fun: WildFungibility) -> WildMultiAsset { + WildMultiAsset::AllOf { fun, id: self } + } +} + +/// Either an amount of a single fungible asset, or a single well-identified non-fungible asset. +#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct MultiAsset { + /// The overall asset identity (aka *class*, in the case of a non-fungible). + pub id: AssetId, + /// The fungibility of the asset, which contains either the amount (in the case of a fungible + /// asset) or the *instance ID*, the secondary asset identifier. + pub fun: Fungibility, +} + +impl PartialOrd for MultiAsset { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for MultiAsset { + fn cmp(&self, other: &Self) -> Ordering { + match (&self.fun, &other.fun) { + (Fungibility::Fungible(..), Fungibility::NonFungible(..)) => Ordering::Less, + (Fungibility::NonFungible(..), Fungibility::Fungible(..)) => Ordering::Greater, + _ => (&self.id, &self.fun).cmp(&(&other.id, &other.fun)), + } + } +} + +impl, B: Into> From<(A, B)> for MultiAsset { + fn from((id, fun): (A, B)) -> MultiAsset { + MultiAsset { fun: fun.into(), id: id.into() } + } +} + +impl MultiAsset { + pub fn is_fungible(&self, maybe_id: Option) -> bool { + use Fungibility::*; + matches!(self.fun, Fungible(..)) && maybe_id.map_or(true, |i| i == self.id) + } + + pub fn is_non_fungible(&self, maybe_id: Option) -> bool { + use Fungibility::*; + matches!(self.fun, NonFungible(..)) && maybe_id.map_or(true, |i| i == self.id) + } + + /// Prepend a `MultiLocation` to a concrete asset, giving it a new root location. + pub fn prepend_with(&mut self, prepend: &MultiLocation) -> Result<(), ()> { + self.id.prepend_with(prepend) + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + pub fn reanchor( + &mut self, + target: &MultiLocation, + context: InteriorMultiLocation, + ) -> Result<(), ()> { + self.id.reanchor(target, context) + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + pub fn reanchored( + mut self, + target: &MultiLocation, + context: InteriorMultiLocation, + ) -> Result { + self.id.reanchor(target, context)?; + Ok(self) + } + + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &MultiAsset) -> bool { + use Fungibility::*; + if self.id == inner.id { + match (&self.fun, &inner.fun) { + (Fungible(a), Fungible(i)) if a >= i => return true, + (NonFungible(a), NonFungible(i)) if a == i => return true, + _ => (), + } + } + false + } +} + +impl TryFrom for MultiAsset { + type Error = (); + fn try_from(old: OldMultiAsset) -> Result { + Ok(Self { id: old.id.try_into()?, fun: old.fun.try_into()? }) + } +} + +/// A `Vec` of `MultiAsset`s. +/// +/// There are a number of invariants which the construction and mutation functions must ensure are +/// maintained: +/// - It may contain no items of duplicate asset class; +/// - All items must be ordered; +/// - The number of items should grow no larger than `MAX_ITEMS_IN_MULTIASSETS`. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, Default)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct MultiAssets(Vec); + +/// Maximum number of items we expect in a single `MultiAssets` value. Note this is not (yet) +/// enforced, and just serves to provide a sensible `max_encoded_len` for `MultiAssets`. +const MAX_ITEMS_IN_MULTIASSETS: usize = 20; + +impl MaxEncodedLen for MultiAssets { + fn max_encoded_len() -> usize { + MultiAsset::max_encoded_len() * MAX_ITEMS_IN_MULTIASSETS + } +} + +impl Decode for MultiAssets { + fn decode(input: &mut I) -> Result { + Self::from_sorted_and_deduplicated(Vec::::decode(input)?) + .map_err(|()| "Out of order".into()) + } +} + +impl TryFrom for MultiAssets { + type Error = (); + fn try_from(old: OldMultiAssets) -> Result { + let v = old + .drain() + .into_iter() + .map(MultiAsset::try_from) + .collect::, ()>>()?; + Ok(MultiAssets(v)) + } +} + +impl From> for MultiAssets { + fn from(mut assets: Vec) -> Self { + let mut res = Vec::with_capacity(assets.len()); + if !assets.is_empty() { + assets.sort(); + let mut iter = assets.into_iter(); + if let Some(first) = iter.next() { + let last = iter.fold(first, |a, b| -> MultiAsset { + match (a, b) { + ( + MultiAsset { fun: Fungibility::Fungible(a_amount), id: a_id }, + MultiAsset { fun: Fungibility::Fungible(b_amount), id: b_id }, + ) if a_id == b_id => MultiAsset { + id: a_id, + fun: Fungibility::Fungible(a_amount.saturating_add(b_amount)), + }, + ( + MultiAsset { fun: Fungibility::NonFungible(a_instance), id: a_id }, + MultiAsset { fun: Fungibility::NonFungible(b_instance), id: b_id }, + ) if a_id == b_id && a_instance == b_instance => + MultiAsset { fun: Fungibility::NonFungible(a_instance), id: a_id }, + (to_push, to_remember) => { + res.push(to_push); + to_remember + }, + } + }); + res.push(last); + } + } + Self(res) + } +} + +impl> From for MultiAssets { + fn from(x: T) -> Self { + Self(vec![x.into()]) + } +} + +impl MultiAssets { + /// A new (empty) value. + pub fn new() -> Self { + Self(Vec::new()) + } + + /// Create a new instance of `MultiAssets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// Returns `Ok` if the operation succeeds and `Err` if `r` is out of order or had duplicates. + /// If you can't guarantee that `r` is sorted and deduplicated, then use + /// `From::>::from` which is infallible. + pub fn from_sorted_and_deduplicated(r: Vec) -> Result { + if r.is_empty() { + return Ok(Self(Vec::new())) + } + r.iter().skip(1).try_fold(&r[0], |a, b| -> Result<&MultiAsset, ()> { + if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) { + Ok(b) + } else { + Err(()) + } + })?; + Ok(Self(r)) + } + + /// Create a new instance of `MultiAssets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// In release mode, this skips any checks to ensure that `r` is correct, making it a + /// negligible-cost operation. Generally though you should avoid using it unless you have a + /// strict proof that `r` is valid. + #[cfg(test)] + pub fn from_sorted_and_deduplicated_skip_checks(r: Vec) -> Self { + Self::from_sorted_and_deduplicated(r).expect("Invalid input r is not sorted/deduped") + } + /// Create a new instance of `MultiAssets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// In release mode, this skips any checks to ensure that `r` is correct, making it a + /// negligible-cost operation. Generally though you should avoid using it unless you have a + /// strict proof that `r` is valid. + /// + /// In test mode, this checks anyway and panics on fail. + #[cfg(not(test))] + pub fn from_sorted_and_deduplicated_skip_checks(r: Vec) -> Self { + Self(r) + } + + /// Add some asset onto the list, saturating. This is quite a laborious operation since it + /// maintains the ordering. + pub fn push(&mut self, a: MultiAsset) { + for asset in self.0.iter_mut().filter(|x| x.id == a.id) { + match (&a.fun, &mut asset.fun) { + (Fungibility::Fungible(amount), Fungibility::Fungible(balance)) => { + *balance = balance.saturating_add(*amount); + return + }, + (Fungibility::NonFungible(inst1), Fungibility::NonFungible(inst2)) + if inst1 == inst2 => + return, + _ => (), + } + } + self.0.push(a); + self.0.sort(); + } + + /// Returns `true` if this definitely represents no asset. + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &MultiAsset) -> bool { + self.0.iter().any(|i| i.contains(inner)) + } + + /// Consume `self` and return the inner vec. + #[deprecated = "Use `into_inner()` instead"] + pub fn drain(self) -> Vec { + self.0 + } + + /// Consume `self` and return the inner vec. + pub fn into_inner(self) -> Vec { + self.0 + } + + /// Return a reference to the inner vec. + pub fn inner(&self) -> &Vec { + &self.0 + } + + /// Return the number of distinct asset instances contained. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Prepend a `MultiLocation` to any concrete asset items, giving it a new root location. + pub fn prepend_with(&mut self, prefix: &MultiLocation) -> Result<(), ()> { + self.0.iter_mut().try_for_each(|i| i.prepend_with(prefix)) + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + pub fn reanchor( + &mut self, + target: &MultiLocation, + context: InteriorMultiLocation, + ) -> Result<(), ()> { + self.0.iter_mut().try_for_each(|i| i.reanchor(target, context)) + } + + /// Return a reference to an item at a specific index or `None` if it doesn't exist. + pub fn get(&self, index: usize) -> Option<&MultiAsset> { + self.0.get(index) + } +} + +/// A wildcard representing a set of assets. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum WildMultiAsset { + /// All assets in Holding. + All, + /// All assets in Holding of a given fungibility and ID. + AllOf { id: AssetId, fun: WildFungibility }, + /// All assets in Holding, up to `u32` individual assets (different instances of non-fungibles + /// are separate assets). + AllCounted(#[codec(compact)] u32), + /// All assets in Holding of a given fungibility and ID up to `count` individual assets + /// (different instances of non-fungibles are separate assets). + AllOfCounted { + id: AssetId, + fun: WildFungibility, + #[codec(compact)] + count: u32, + }, +} + +impl TryFrom for WildMultiAsset { + type Error = (); + fn try_from(old: OldWildMultiAsset) -> Result { + use OldWildMultiAsset::*; + Ok(match old { + AllOf { id, fun } => Self::AllOf { id: id.try_into()?, fun: fun.try_into()? }, + All => Self::All, + }) + } +} + +impl TryFrom<(OldWildMultiAsset, u32)> for WildMultiAsset { + type Error = (); + fn try_from(old: (OldWildMultiAsset, u32)) -> Result { + use OldWildMultiAsset::*; + let count = old.1; + Ok(match old.0 { + AllOf { id, fun } => + Self::AllOfCounted { id: id.try_into()?, fun: fun.try_into()?, count }, + All => Self::AllCounted(count), + }) + } +} + +impl WildMultiAsset { + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &MultiAsset) -> bool { + use WildMultiAsset::*; + match self { + AllOfCounted { count: 0, .. } | AllCounted(0) => false, + AllOf { fun, id } | AllOfCounted { id, fun, .. } => + inner.fun.is_kind(*fun) && &inner.id == id, + All | AllCounted(_) => true, + } + } + + /// Returns true if the wild element of `self` matches `inner`. + /// + /// Note that for `Counted` variants of wildcards, then it will disregard the count except for + /// always returning `false` when equal to 0. + #[deprecated = "Use `contains` instead"] + pub fn matches(&self, inner: &MultiAsset) -> bool { + self.contains(inner) + } + + /// Mutate the asset to represent the same value from the perspective of a new `target` + /// location. The local chain's location is provided in `context`. + pub fn reanchor( + &mut self, + target: &MultiLocation, + context: InteriorMultiLocation, + ) -> Result<(), ()> { + use WildMultiAsset::*; + match self { + AllOf { ref mut id, .. } | AllOfCounted { ref mut id, .. } => + id.reanchor(target, context), + All | AllCounted(_) => Ok(()), + } + } + + /// Maximum count of assets allowed to match, if any. + pub fn count(&self) -> Option { + use WildMultiAsset::*; + match self { + AllOfCounted { count, .. } | AllCounted(count) => Some(*count), + All | AllOf { .. } => None, + } + } + + /// Explicit limit on number of assets allowed to match, if any. + pub fn limit(&self) -> Option { + self.count() + } + + /// Consume self and return the equivalent version but counted and with the `count` set to the + /// given parameter. + pub fn counted(self, count: u32) -> Self { + use WildMultiAsset::*; + match self { + AllOfCounted { fun, id, .. } | AllOf { fun, id } => AllOfCounted { fun, id, count }, + All | AllCounted(_) => AllCounted(count), + } + } +} + +impl, B: Into> From<(A, B)> for WildMultiAsset { + fn from((id, fun): (A, B)) -> WildMultiAsset { + WildMultiAsset::AllOf { fun: fun.into(), id: id.into() } + } +} + +/// `MultiAsset` collection, defined either by a number of `MultiAssets` or a single wildcard. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum MultiAssetFilter { + /// Specify the filter as being everything contained by the given `MultiAssets` inner. + Definite(MultiAssets), + /// Specify the filter as the given `WildMultiAsset` wildcard. + Wild(WildMultiAsset), +} + +impl> From for MultiAssetFilter { + fn from(x: T) -> Self { + Self::Wild(x.into()) + } +} + +impl From for MultiAssetFilter { + fn from(x: MultiAsset) -> Self { + Self::Definite(vec![x].into()) + } +} + +impl From> for MultiAssetFilter { + fn from(x: Vec) -> Self { + Self::Definite(x.into()) + } +} + +impl From for MultiAssetFilter { + fn from(x: MultiAssets) -> Self { + Self::Definite(x) + } +} + +impl MultiAssetFilter { + /// Returns true if `inner` would be matched by `self`. + /// + /// Note that for `Counted` variants of wildcards, then it will disregard the count except for + /// always returning `false` when equal to 0. + pub fn matches(&self, inner: &MultiAsset) -> bool { + match self { + MultiAssetFilter::Definite(ref assets) => assets.contains(inner), + MultiAssetFilter::Wild(ref wild) => wild.contains(inner), + } + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + pub fn reanchor( + &mut self, + target: &MultiLocation, + context: InteriorMultiLocation, + ) -> Result<(), ()> { + match self { + MultiAssetFilter::Definite(ref mut assets) => assets.reanchor(target, context), + MultiAssetFilter::Wild(ref mut wild) => wild.reanchor(target, context), + } + } + + /// Maximum count of assets it is possible to match, if known. + pub fn count(&self) -> Option { + use MultiAssetFilter::*; + match self { + Definite(x) => Some(x.len() as u32), + Wild(x) => x.count(), + } + } + + /// Explicit limit placed on the number of items, if any. + pub fn limit(&self) -> Option { + use MultiAssetFilter::*; + match self { + Definite(_) => None, + Wild(x) => x.limit(), + } + } +} + +impl TryFrom for MultiAssetFilter { + type Error = (); + fn try_from(old: OldMultiAssetFilter) -> Result { + Ok(match old { + OldMultiAssetFilter::Definite(x) => Self::Definite(x.try_into()?), + OldMultiAssetFilter::Wild(x) => Self::Wild(x.try_into()?), + }) + } +} + +impl TryFrom<(OldMultiAssetFilter, u32)> for MultiAssetFilter { + type Error = (); + fn try_from(old: (OldMultiAssetFilter, u32)) -> Result { + let count = old.1; + Ok(match old.0 { + OldMultiAssetFilter::Definite(x) if count >= x.len() as u32 => + Self::Definite(x.try_into()?), + OldMultiAssetFilter::Wild(x) => Self::Wild((x, count).try_into()?), + _ => return Err(()), + }) + } +} + +#[cfg(test)] +mod tests { + use super::super::prelude::*; + + #[test] + fn conversion_works() { + let _: MultiAssets = (Here, 1u128).into(); + } + + #[test] + fn from_sorted_and_deduplicated_works() { + use super::*; + use alloc::vec; + + let empty = vec![]; + let r = MultiAssets::from_sorted_and_deduplicated(empty); + assert_eq!(r, Ok(MultiAssets(vec![]))); + + let dup_fun = vec![(Here, 100).into(), (Here, 10).into()]; + let r = MultiAssets::from_sorted_and_deduplicated(dup_fun); + assert!(r.is_err()); + + let dup_nft = vec![(Here, *b"notgood!").into(), (Here, *b"notgood!").into()]; + let r = MultiAssets::from_sorted_and_deduplicated(dup_nft); + assert!(r.is_err()); + + let good_fun = vec![(Here, 10).into(), (Parent, 10).into()]; + let r = MultiAssets::from_sorted_and_deduplicated(good_fun.clone()); + assert_eq!(r, Ok(MultiAssets(good_fun))); + + let bad_fun = vec![(Parent, 10).into(), (Here, 10).into()]; + let r = MultiAssets::from_sorted_and_deduplicated(bad_fun); + assert!(r.is_err()); + + let good_abstract_fun = vec![(Here, 100).into(), ([0u8; 32], 10).into()]; + let r = MultiAssets::from_sorted_and_deduplicated(good_abstract_fun.clone()); + assert_eq!(r, Ok(MultiAssets(good_abstract_fun))); + + let bad_abstract_fun = vec![([0u8; 32], 10).into(), (Here, 10).into()]; + let r = MultiAssets::from_sorted_and_deduplicated(bad_abstract_fun); + assert!(r.is_err()); + + let good_nft = vec![(Here, ()).into(), (Here, *b"good").into()]; + let r = MultiAssets::from_sorted_and_deduplicated(good_nft.clone()); + assert_eq!(r, Ok(MultiAssets(good_nft))); + + let bad_nft = vec![(Here, *b"bad!").into(), (Here, ()).into()]; + let r = MultiAssets::from_sorted_and_deduplicated(bad_nft); + assert!(r.is_err()); + + let good_abstract_nft = vec![(Here, ()).into(), ([0u8; 32], ()).into()]; + let r = MultiAssets::from_sorted_and_deduplicated(good_abstract_nft.clone()); + assert_eq!(r, Ok(MultiAssets(good_abstract_nft))); + + let bad_abstract_nft = vec![([0u8; 32], ()).into(), (Here, ()).into()]; + let r = MultiAssets::from_sorted_and_deduplicated(bad_abstract_nft); + assert!(r.is_err()); + + let mixed_good = vec![(Here, 10).into(), (Here, *b"good").into()]; + let r = MultiAssets::from_sorted_and_deduplicated(mixed_good.clone()); + assert_eq!(r, Ok(MultiAssets(mixed_good))); + + let mixed_bad = vec![(Here, *b"bad!").into(), (Here, 10).into()]; + let r = MultiAssets::from_sorted_and_deduplicated(mixed_bad); + assert!(r.is_err()); + } +} diff --git a/polkadot/xcm/src/v3/multilocation.rs b/polkadot/xcm/src/v3/multilocation.rs new file mode 100644 index 0000000000000000000000000000000000000000..07f829d014c0bfdcb8a640ae334df6cb4428e5d7 --- /dev/null +++ b/polkadot/xcm/src/v3/multilocation.rs @@ -0,0 +1,720 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! XCM `MultiLocation` datatype. + +use super::{Junction, Junctions}; +use crate::{v2::MultiLocation as OldMultiLocation, VersionedMultiLocation}; +use core::{ + convert::{TryFrom, TryInto}, + result, +}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// A relative path between state-bearing consensus systems. +/// +/// A location in a consensus system is defined as an *isolatable state machine* held within global +/// consensus. The location in question need not have a sophisticated consensus algorithm of its +/// own; a single account within Ethereum, for example, could be considered a location. +/// +/// A very-much non-exhaustive list of types of location include: +/// - A (normal, layer-1) block chain, e.g. the Bitcoin mainnet or a parachain. +/// - A layer-0 super-chain, e.g. the Polkadot Relay chain. +/// - A layer-2 smart contract, e.g. an ERC-20 on Ethereum. +/// - A logical functional component of a chain, e.g. a single instance of a pallet on a Frame-based +/// Substrate chain. +/// - An account. +/// +/// A `MultiLocation` is a *relative identifier*, meaning that it can only be used to define the +/// relative path between two locations, and cannot generally be used to refer to a location +/// universally. It is comprised of an integer number of parents specifying the number of times to +/// "escape" upwards into the containing consensus system and then a number of *junctions*, each +/// diving down and specifying some interior portion of state (which may be considered a +/// "sub-consensus" system). +/// +/// This specific `MultiLocation` implementation uses a `Junctions` datatype which is a Rust `enum` +/// in order to make pattern matching easier. There are occasions where it is important to ensure +/// that a value is strictly an interior location, in those cases, `Junctions` may be used. +/// +/// The `MultiLocation` value of `Null` simply refers to the interpreting consensus system. +#[derive( + Copy, + Clone, + Decode, + Encode, + Eq, + PartialEq, + Ord, + PartialOrd, + Debug, + TypeInfo, + MaxEncodedLen, + serde::Serialize, + serde::Deserialize, +)] +pub struct MultiLocation { + /// The number of parent junctions at the beginning of this `MultiLocation`. + pub parents: u8, + /// The interior (i.e. non-parent) junctions that this `MultiLocation` contains. + pub interior: Junctions, +} + +impl Default for MultiLocation { + fn default() -> Self { + Self { parents: 0, interior: Junctions::Here } + } +} + +/// A relative location which is constrained to be an interior location of the context. +/// +/// See also `MultiLocation`. +pub type InteriorMultiLocation = Junctions; + +impl MultiLocation { + /// Creates a new `MultiLocation` with the given number of parents and interior junctions. + pub fn new(parents: u8, interior: impl Into) -> MultiLocation { + MultiLocation { parents, interior: interior.into() } + } + + /// Consume `self` and return the equivalent `VersionedMultiLocation` value. + pub const fn into_versioned(self) -> VersionedMultiLocation { + VersionedMultiLocation::V3(self) + } + + /// Creates a new `MultiLocation` with 0 parents and a `Here` interior. + /// + /// The resulting `MultiLocation` can be interpreted as the "current consensus system". + pub const fn here() -> MultiLocation { + MultiLocation { parents: 0, interior: Junctions::Here } + } + + /// Creates a new `MultiLocation` which evaluates to the parent context. + pub const fn parent() -> MultiLocation { + MultiLocation { parents: 1, interior: Junctions::Here } + } + + /// Creates a new `MultiLocation` which evaluates to the grand parent context. + pub const fn grandparent() -> MultiLocation { + MultiLocation { parents: 2, interior: Junctions::Here } + } + + /// Creates a new `MultiLocation` with `parents` and an empty (`Here`) interior. + pub const fn ancestor(parents: u8) -> MultiLocation { + MultiLocation { parents, interior: Junctions::Here } + } + + /// Whether the `MultiLocation` has no parents and has a `Here` interior. + pub const fn is_here(&self) -> bool { + self.parents == 0 && self.interior.len() == 0 + } + + /// Remove the `NetworkId` value in any interior `Junction`s. + pub fn remove_network_id(&mut self) { + self.interior.remove_network_id(); + } + + /// Return a reference to the interior field. + pub fn interior(&self) -> &Junctions { + &self.interior + } + + /// Return a mutable reference to the interior field. + pub fn interior_mut(&mut self) -> &mut Junctions { + &mut self.interior + } + + /// Returns the number of `Parent` junctions at the beginning of `self`. + pub const fn parent_count(&self) -> u8 { + self.parents + } + + /// Returns boolean indicating whether `self` contains only the specified amount of + /// parents and no interior junctions. + pub const fn contains_parents_only(&self, count: u8) -> bool { + matches!(self.interior, Junctions::Here) && self.parents == count + } + + /// Returns the number of parents and junctions in `self`. + pub const fn len(&self) -> usize { + self.parent_count() as usize + self.interior.len() + } + + /// Returns the first interior junction, or `None` if the location is empty or contains only + /// parents. + pub fn first_interior(&self) -> Option<&Junction> { + self.interior.first() + } + + /// Returns last junction, or `None` if the location is empty or contains only parents. + pub fn last(&self) -> Option<&Junction> { + self.interior.last() + } + + /// Splits off the first interior junction, returning the remaining suffix (first item in tuple) + /// and the first element (second item in tuple) or `None` if it was empty. + pub fn split_first_interior(self) -> (MultiLocation, Option) { + let MultiLocation { parents, interior: junctions } = self; + let (suffix, first) = junctions.split_first(); + let multilocation = MultiLocation { parents, interior: suffix }; + (multilocation, first) + } + + /// Splits off the last interior junction, returning the remaining prefix (first item in tuple) + /// and the last element (second item in tuple) or `None` if it was empty or if `self` only + /// contains parents. + pub fn split_last_interior(self) -> (MultiLocation, Option) { + let MultiLocation { parents, interior: junctions } = self; + let (prefix, last) = junctions.split_last(); + let multilocation = MultiLocation { parents, interior: prefix }; + (multilocation, last) + } + + /// Mutates `self`, suffixing its interior junctions with `new`. Returns `Err` with `new` in + /// case of overflow. + pub fn push_interior(&mut self, new: impl Into) -> result::Result<(), Junction> { + self.interior.push(new) + } + + /// Mutates `self`, prefixing its interior junctions with `new`. Returns `Err` with `new` in + /// case of overflow. + pub fn push_front_interior( + &mut self, + new: impl Into, + ) -> result::Result<(), Junction> { + self.interior.push_front(new) + } + + /// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with + /// theoriginal value of `self` in case of overflow. + pub fn pushed_with_interior( + self, + new: impl Into, + ) -> result::Result { + match self.interior.pushed_with(new) { + Ok(i) => Ok(MultiLocation { interior: i, parents: self.parents }), + Err((i, j)) => Err((MultiLocation { interior: i, parents: self.parents }, j)), + } + } + + /// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the + /// original value of `self` in case of overflow. + pub fn pushed_front_with_interior( + self, + new: impl Into, + ) -> result::Result { + match self.interior.pushed_front_with(new) { + Ok(i) => Ok(MultiLocation { interior: i, parents: self.parents }), + Err((i, j)) => Err((MultiLocation { interior: i, parents: self.parents }, j)), + } + } + + /// Returns the junction at index `i`, or `None` if the location is a parent or if the location + /// does not contain that many elements. + pub fn at(&self, i: usize) -> Option<&Junction> { + let num_parents = self.parents as usize; + if i < num_parents { + return None + } + self.interior.at(i - num_parents) + } + + /// Returns a mutable reference to the junction at index `i`, or `None` if the location is a + /// parent or if it doesn't contain that many elements. + pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> { + let num_parents = self.parents as usize; + if i < num_parents { + return None + } + self.interior.at_mut(i - num_parents) + } + + /// Decrements the parent count by 1. + pub fn dec_parent(&mut self) { + self.parents = self.parents.saturating_sub(1); + } + + /// Removes the first interior junction from `self`, returning it + /// (or `None` if it was empty or if `self` contains only parents). + pub fn take_first_interior(&mut self) -> Option { + self.interior.take_first() + } + + /// Removes the last element from `interior`, returning it (or `None` if it was empty or if + /// `self` only contains parents). + pub fn take_last(&mut self) -> Option { + self.interior.take_last() + } + + /// Ensures that `self` has the same number of parents as `prefix`, its junctions begins with + /// the junctions of `prefix` and that it has a single `Junction` item following. + /// If so, returns a reference to this `Junction` item. + /// + /// # Example + /// ```rust + /// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation}; + /// # fn main() { + /// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild)); + /// assert_eq!( + /// m.match_and_split(&MultiLocation::new(1, X1(PalletInstance(3)))), + /// Some(&OnlyChild), + /// ); + /// assert_eq!(m.match_and_split(&MultiLocation::new(1, Here)), None); + /// # } + /// ``` + pub fn match_and_split(&self, prefix: &MultiLocation) -> Option<&Junction> { + if self.parents != prefix.parents { + return None + } + self.interior.match_and_split(&prefix.interior) + } + + pub fn starts_with(&self, prefix: &MultiLocation) -> bool { + self.parents == prefix.parents && self.interior.starts_with(&prefix.interior) + } + + /// Mutate `self` so that it is suffixed with `suffix`. + /// + /// Does not modify `self` and returns `Err` with `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent}; + /// # fn main() { + /// let mut m: MultiLocation = (Parent, Parachain(21), 69u64).into(); + /// assert_eq!(m.append_with((Parent, PalletInstance(3))), Ok(())); + /// assert_eq!(m, MultiLocation::new(1, X2(Parachain(21), PalletInstance(3)))); + /// # } + /// ``` + pub fn append_with(&mut self, suffix: impl Into) -> Result<(), Self> { + let prefix = core::mem::replace(self, suffix.into()); + match self.prepend_with(prefix) { + Ok(()) => Ok(()), + Err(prefix) => Err(core::mem::replace(self, prefix)), + } + } + + /// Consume `self` and return its value suffixed with `suffix`. + /// + /// Returns `Err` with the original value of `self` and `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent}; + /// # fn main() { + /// let mut m: MultiLocation = (Parent, Parachain(21), 69u64).into(); + /// let r = m.appended_with((Parent, PalletInstance(3))).unwrap(); + /// assert_eq!(r, MultiLocation::new(1, X2(Parachain(21), PalletInstance(3)))); + /// # } + /// ``` + pub fn appended_with(mut self, suffix: impl Into) -> Result { + match self.append_with(suffix) { + Ok(()) => Ok(self), + Err(suffix) => Err((self, suffix)), + } + } + + /// Mutate `self` so that it is prefixed with `prefix`. + /// + /// Does not modify `self` and returns `Err` with `prefix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent}; + /// # fn main() { + /// let mut m: MultiLocation = (Parent, Parent, PalletInstance(3)).into(); + /// assert_eq!(m.prepend_with((Parent, Parachain(21), OnlyChild)), Ok(())); + /// assert_eq!(m, MultiLocation::new(1, X1(PalletInstance(3)))); + /// # } + /// ``` + pub fn prepend_with(&mut self, prefix: impl Into) -> Result<(), Self> { + // prefix self (suffix) + // P .. P I .. I p .. p i .. i + let mut prefix = prefix.into(); + let prepend_interior = prefix.interior.len().saturating_sub(self.parents as usize); + let final_interior = self.interior.len().saturating_add(prepend_interior); + if final_interior > super::junctions::MAX_JUNCTIONS { + return Err(prefix) + } + let suffix_parents = (self.parents as usize).saturating_sub(prefix.interior.len()); + let final_parents = (prefix.parents as usize).saturating_add(suffix_parents); + if final_parents > 255 { + return Err(prefix) + } + + // cancel out the final item on the prefix interior for one of the suffix's parents. + while self.parents > 0 && prefix.take_last().is_some() { + self.dec_parent(); + } + + // now we have either removed all suffix's parents or prefix interior. + // this means we can combine the prefix's and suffix's remaining parents/interior since + // we know that with at least one empty, the overall order will be respected: + // prefix self (suffix) + // P .. P (I) p .. p i .. i => P + p .. (no I) i + // -- or -- + // P .. P I .. I (p) i .. i => P (no p) .. I + i + + self.parents = self.parents.saturating_add(prefix.parents); + for j in prefix.interior.into_iter().rev() { + self.push_front_interior(j) + .expect("final_interior no greater than MAX_JUNCTIONS; qed"); + } + Ok(()) + } + + /// Consume `self` and return its value prefixed with `prefix`. + /// + /// Returns `Err` with the original value of `self` and `prefix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use xcm::v3::{Junctions::*, Junction::*, MultiLocation, Parent}; + /// # fn main() { + /// let m: MultiLocation = (Parent, Parent, PalletInstance(3)).into(); + /// let r = m.prepended_with((Parent, Parachain(21), OnlyChild)).unwrap(); + /// assert_eq!(r, MultiLocation::new(1, X1(PalletInstance(3)))); + /// # } + /// ``` + pub fn prepended_with(mut self, prefix: impl Into) -> Result { + match self.prepend_with(prefix) { + Ok(()) => Ok(self), + Err(prefix) => Err((self, prefix)), + } + } + + /// Mutate `self` so that it represents the same location from the point of view of `target`. + /// The context of `self` is provided as `context`. + /// + /// Does not modify `self` in case of overflow. + pub fn reanchor( + &mut self, + target: &MultiLocation, + context: InteriorMultiLocation, + ) -> Result<(), ()> { + // TODO: https://github.com/paritytech/polkadot/issues/4489 Optimize this. + + // 1. Use our `context` to figure out how the `target` would address us. + let inverted_target = context.invert_target(target)?; + + // 2. Prepend `inverted_target` to `self` to get self's location from the perspective of + // `target`. + self.prepend_with(inverted_target).map_err(|_| ())?; + + // 3. Given that we know some of `target` context, ensure that any parents in `self` are + // strictly needed. + self.simplify(target.interior()); + + Ok(()) + } + + /// Consume `self` and return a new value representing the same location from the point of view + /// of `target`. The context of `self` is provided as `context`. + /// + /// Returns the original `self` in case of overflow. + pub fn reanchored( + mut self, + target: &MultiLocation, + context: InteriorMultiLocation, + ) -> Result { + match self.reanchor(target, context) { + Ok(()) => Ok(self), + Err(()) => Err(self), + } + } + + /// Remove any unneeded parents/junctions in `self` based on the given context it will be + /// interpreted in. + pub fn simplify(&mut self, context: &Junctions) { + if context.len() < self.parents as usize { + // Not enough context + return + } + while self.parents > 0 { + let maybe = context.at(context.len() - (self.parents as usize)); + match (self.interior.first(), maybe) { + (Some(i), Some(j)) if i == j => { + self.interior.take_first(); + self.parents -= 1; + }, + _ => break, + } + } + } +} + +impl TryFrom for MultiLocation { + type Error = (); + fn try_from(x: OldMultiLocation) -> result::Result { + Ok(MultiLocation { parents: x.parents, interior: x.interior.try_into()? }) + } +} + +/// A unit struct which can be converted into a `MultiLocation` of `parents` value 1. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Parent; +impl From for MultiLocation { + fn from(_: Parent) -> Self { + MultiLocation { parents: 1, interior: Junctions::Here } + } +} + +/// A tuple struct which can be converted into a `MultiLocation` of `parents` value 1 with the inner +/// interior. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct ParentThen(pub Junctions); +impl From for MultiLocation { + fn from(ParentThen(interior): ParentThen) -> Self { + MultiLocation { parents: 1, interior } + } +} + +/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Ancestor(pub u8); +impl From for MultiLocation { + fn from(Ancestor(parents): Ancestor) -> Self { + MultiLocation { parents, interior: Junctions::Here } + } +} + +/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value and the +/// inner interior. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct AncestorThen(pub u8, pub Interior); +impl> From> for MultiLocation { + fn from(AncestorThen(parents, interior): AncestorThen) -> Self { + MultiLocation { parents, interior: interior.into() } + } +} + +xcm_procedural::impl_conversion_functions_for_multilocation_v3!(); + +#[cfg(test)] +mod tests { + use crate::v3::prelude::*; + use parity_scale_codec::{Decode, Encode}; + + #[test] + fn conversion_works() { + let x: MultiLocation = Parent.into(); + assert_eq!(x, MultiLocation { parents: 1, interior: Here }); + // let x: MultiLocation = (Parent,).into(); + // assert_eq!(x, MultiLocation { parents: 1, interior: Here }); + // let x: MultiLocation = (Parent, Parent).into(); + // assert_eq!(x, MultiLocation { parents: 2, interior: Here }); + let x: MultiLocation = (Parent, Parent, OnlyChild).into(); + assert_eq!(x, MultiLocation { parents: 2, interior: OnlyChild.into() }); + let x: MultiLocation = OnlyChild.into(); + assert_eq!(x, MultiLocation { parents: 0, interior: OnlyChild.into() }); + let x: MultiLocation = (OnlyChild,).into(); + assert_eq!(x, MultiLocation { parents: 0, interior: OnlyChild.into() }); + } + + #[test] + fn simplify_basic_works() { + let mut location: MultiLocation = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = X2(Parachain(1000), PalletInstance(42)); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: MultiLocation = (Parent, PalletInstance(42), GeneralIndex(69)).into(); + let context = X1(PalletInstance(42)); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: MultiLocation = (Parent, PalletInstance(42), GeneralIndex(69)).into(); + let context = X2(Parachain(1000), PalletInstance(42)); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: MultiLocation = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = X3(OnlyChild, Parachain(1000), PalletInstance(42)); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + } + + #[test] + fn simplify_incompatible_location_fails() { + let mut location: MultiLocation = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = X3(Parachain(1000), PalletInstance(42), GeneralIndex(42)); + let expected = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: MultiLocation = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = X1(Parachain(1000)); + let expected = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + location.simplify(&context); + assert_eq!(location, expected); + } + + #[test] + fn reanchor_works() { + let mut id: MultiLocation = (Parent, Parachain(1000), GeneralIndex(42)).into(); + let context = Parachain(2000).into(); + let target = (Parent, Parachain(1000)).into(); + let expected = GeneralIndex(42).into(); + id.reanchor(&target, context).unwrap(); + assert_eq!(id, expected); + } + + #[test] + fn encode_and_decode_works() { + let m = MultiLocation { + parents: 1, + interior: X2(Parachain(42), AccountIndex64 { network: None, index: 23 }), + }; + let encoded = m.encode(); + assert_eq!(encoded, [1, 2, 0, 168, 2, 0, 92].to_vec()); + let decoded = MultiLocation::decode(&mut &encoded[..]); + assert_eq!(decoded, Ok(m)); + } + + #[test] + fn match_and_split_works() { + let m = MultiLocation { + parents: 1, + interior: X2(Parachain(42), AccountIndex64 { network: None, index: 23 }), + }; + assert_eq!(m.match_and_split(&MultiLocation { parents: 1, interior: Here }), None); + assert_eq!( + m.match_and_split(&MultiLocation { parents: 1, interior: X1(Parachain(42)) }), + Some(&AccountIndex64 { network: None, index: 23 }) + ); + assert_eq!(m.match_and_split(&m), None); + } + + #[test] + fn append_with_works() { + let acc = AccountIndex64 { network: None, index: 23 }; + let mut m = MultiLocation { parents: 1, interior: X1(Parachain(42)) }; + assert_eq!(m.append_with(X2(PalletInstance(3), acc)), Ok(())); + assert_eq!( + m, + MultiLocation { parents: 1, interior: X3(Parachain(42), PalletInstance(3), acc) } + ); + + // cannot append to create overly long multilocation + let acc = AccountIndex64 { network: None, index: 23 }; + let m = MultiLocation { + parents: 254, + interior: X5(Parachain(42), OnlyChild, OnlyChild, OnlyChild, OnlyChild), + }; + let suffix: MultiLocation = (PalletInstance(3), acc, OnlyChild, OnlyChild).into(); + assert_eq!(m.clone().append_with(suffix), Err(suffix)); + } + + #[test] + fn prepend_with_works() { + let mut m = MultiLocation { + parents: 1, + interior: X2(Parachain(42), AccountIndex64 { network: None, index: 23 }), + }; + assert_eq!(m.prepend_with(MultiLocation { parents: 1, interior: X1(OnlyChild) }), Ok(())); + assert_eq!( + m, + MultiLocation { + parents: 1, + interior: X2(Parachain(42), AccountIndex64 { network: None, index: 23 }) + } + ); + + // cannot prepend to create overly long multilocation + let mut m = MultiLocation { parents: 254, interior: X1(Parachain(42)) }; + let prefix = MultiLocation { parents: 2, interior: Here }; + assert_eq!(m.prepend_with(prefix), Err(prefix)); + + let prefix = MultiLocation { parents: 1, interior: Here }; + assert_eq!(m.prepend_with(prefix), Ok(())); + assert_eq!(m, MultiLocation { parents: 255, interior: X1(Parachain(42)) }); + } + + #[test] + fn double_ended_ref_iteration_works() { + let m = X3(Parachain(1000), Parachain(3), PalletInstance(5)); + let mut iter = m.iter(); + + let first = iter.next().unwrap(); + assert_eq!(first, &Parachain(1000)); + let third = iter.next_back().unwrap(); + assert_eq!(third, &PalletInstance(5)); + let second = iter.next_back().unwrap(); + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + assert_eq!(second, &Parachain(3)); + + let res = Here + .pushed_with(*first) + .unwrap() + .pushed_with(*second) + .unwrap() + .pushed_with(*third) + .unwrap(); + assert_eq!(m, res); + + // make sure there's no funny business with the 0 indexing + let m = Here; + let mut iter = m.iter(); + + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + } + + #[test] + fn conversion_from_other_types_works() { + use crate::v2; + use core::convert::TryInto; + + fn takes_multilocation>(_arg: Arg) {} + + takes_multilocation(Parent); + takes_multilocation(Here); + takes_multilocation(X1(Parachain(42))); + takes_multilocation((Ancestor(255), PalletInstance(8))); + takes_multilocation((Ancestor(5), Parachain(1), PalletInstance(3))); + takes_multilocation((Ancestor(2), Here)); + takes_multilocation(AncestorThen( + 3, + X2(Parachain(43), AccountIndex64 { network: None, index: 155 }), + )); + takes_multilocation((Parent, AccountId32 { network: None, id: [0; 32] })); + takes_multilocation((Parent, Here)); + takes_multilocation(ParentThen(X1(Parachain(75)))); + takes_multilocation([Parachain(100), PalletInstance(3)]); + + assert_eq!( + v2::MultiLocation::from(v2::Junctions::Here).try_into(), + Ok(MultiLocation::here()) + ); + assert_eq!(v2::MultiLocation::from(v2::Parent).try_into(), Ok(MultiLocation::parent())); + assert_eq!( + v2::MultiLocation::from((v2::Parent, v2::Parent, v2::Junction::GeneralIndex(42u128),)) + .try_into(), + Ok(MultiLocation { parents: 2, interior: X1(GeneralIndex(42u128)) }), + ); + } +} diff --git a/polkadot/xcm/src/v3/traits.rs b/polkadot/xcm/src/v3/traits.rs new file mode 100644 index 0000000000000000000000000000000000000000..128be42c2a2b335adcf5414a0228e6001aeaa2e5 --- /dev/null +++ b/polkadot/xcm/src/v3/traits.rs @@ -0,0 +1,599 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// 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 Polkadot. If not, see . + +//! Cross-Consensus Message format data structures. + +use crate::v2::Error as OldError; +use core::result; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +pub use sp_weights::Weight; + +use super::*; + +/// Error codes used in XCM. The first errors codes have explicit indices and are part of the XCM +/// format. Those trailing are merely part of the XCM implementation; there is no expectation that +/// they will retain the same index over time. +#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] +pub enum Error { + // Errors that happen due to instructions being executed. These alone are defined in the + // XCM specification. + /// An arithmetic overflow happened. + #[codec(index = 0)] + Overflow, + /// The instruction is intentionally unsupported. + #[codec(index = 1)] + Unimplemented, + /// Origin Register does not contain a value value for a reserve transfer notification. + #[codec(index = 2)] + UntrustedReserveLocation, + /// Origin Register does not contain a value value for a teleport notification. + #[codec(index = 3)] + UntrustedTeleportLocation, + /// `MultiLocation` value too large to descend further. + #[codec(index = 4)] + LocationFull, + /// `MultiLocation` value ascend more parents than known ancestors of local location. + #[codec(index = 5)] + LocationNotInvertible, + /// The Origin Register does not contain a valid value for instruction. + #[codec(index = 6)] + BadOrigin, + /// The location parameter is not a valid value for the instruction. + #[codec(index = 7)] + InvalidLocation, + /// The given asset is not handled. + #[codec(index = 8)] + AssetNotFound, + /// An asset transaction (like withdraw or deposit) failed (typically due to type conversions). + #[codec(index = 9)] + FailedToTransactAsset(#[codec(skip)] &'static str), + /// An asset cannot be withdrawn, potentially due to lack of ownership, availability or rights. + #[codec(index = 10)] + NotWithdrawable, + /// An asset cannot be deposited under the ownership of a particular location. + #[codec(index = 11)] + LocationCannotHold, + /// Attempt to send a message greater than the maximum supported by the transport protocol. + #[codec(index = 12)] + ExceedsMaxMessageSize, + /// The given message cannot be translated into a format supported by the destination. + #[codec(index = 13)] + DestinationUnsupported, + /// Destination is routable, but there is some issue with the transport mechanism. + #[codec(index = 14)] + Transport(#[codec(skip)] &'static str), + /// Destination is known to be unroutable. + #[codec(index = 15)] + Unroutable, + /// Used by `ClaimAsset` when the given claim could not be recognized/found. + #[codec(index = 16)] + UnknownClaim, + /// Used by `Transact` when the functor cannot be decoded. + #[codec(index = 17)] + FailedToDecode, + /// Used by `Transact` to indicate that the given weight limit could be breached by the + /// functor. + #[codec(index = 18)] + MaxWeightInvalid, + /// Used by `BuyExecution` when the Holding Register does not contain payable fees. + #[codec(index = 19)] + NotHoldingFees, + /// Used by `BuyExecution` when the fees declared to purchase weight are insufficient. + #[codec(index = 20)] + TooExpensive, + /// Used by the `Trap` instruction to force an error intentionally. Its code is included. + #[codec(index = 21)] + Trap(u64), + /// Used by `ExpectAsset`, `ExpectError` and `ExpectOrigin` when the expectation was not true. + #[codec(index = 22)] + ExpectationFalse, + /// The provided pallet index was not found. + #[codec(index = 23)] + PalletNotFound, + /// The given pallet's name is different to that expected. + #[codec(index = 24)] + NameMismatch, + /// The given pallet's version has an incompatible version to that expected. + #[codec(index = 25)] + VersionIncompatible, + /// The given operation would lead to an overflow of the Holding Register. + #[codec(index = 26)] + HoldingWouldOverflow, + /// The message was unable to be exported. + #[codec(index = 27)] + ExportError, + /// `MultiLocation` value failed to be reanchored. + #[codec(index = 28)] + ReanchorFailed, + /// No deal is possible under the given constraints. + #[codec(index = 29)] + NoDeal, + /// Fees were required which the origin could not pay. + #[codec(index = 30)] + FeesNotMet, + /// Some other error with locking. + #[codec(index = 31)] + LockError, + /// The state was not in a condition where the operation was valid to make. + #[codec(index = 32)] + NoPermission, + /// The universal location of the local consensus is improper. + #[codec(index = 33)] + Unanchored, + /// An asset cannot be deposited, probably because (too much of) it already exists. + #[codec(index = 34)] + NotDepositable, + + // Errors that happen prior to instructions being executed. These fall outside of the XCM + // spec. + /// XCM version not able to be handled. + UnhandledXcmVersion, + /// Execution of the XCM would potentially result in a greater weight used than weight limit. + WeightLimitReached(Weight), + /// The XCM did not pass the barrier condition for execution. + /// + /// The barrier condition differs on different chains and in different circumstances, but + /// generally it means that the conditions surrounding the message were not such that the chain + /// considers the message worth spending time executing. Since most chains lift the barrier to + /// execution on appropriate payment, presentation of an NFT voucher, or based on the message + /// origin, it means that none of those were the case. + Barrier, + /// The weight of an XCM message is not computable ahead of execution. + WeightNotComputable, + /// Recursion stack limit reached + ExceedsStackLimit, +} + +impl MaxEncodedLen for Error { + fn max_encoded_len() -> usize { + // TODO: max_encoded_len doesn't quite work here as it tries to take notice of the fields + // marked `codec(skip)`. We can hard-code it with the right answer for now. + 1 + } +} + +impl TryFrom for Error { + type Error = (); + fn try_from(old_error: OldError) -> result::Result { + use OldError::*; + Ok(match old_error { + Overflow => Self::Overflow, + Unimplemented => Self::Unimplemented, + UntrustedReserveLocation => Self::UntrustedReserveLocation, + UntrustedTeleportLocation => Self::UntrustedTeleportLocation, + MultiLocationFull => Self::LocationFull, + MultiLocationNotInvertible => Self::LocationNotInvertible, + BadOrigin => Self::BadOrigin, + InvalidLocation => Self::InvalidLocation, + AssetNotFound => Self::AssetNotFound, + FailedToTransactAsset(s) => Self::FailedToTransactAsset(s), + NotWithdrawable => Self::NotWithdrawable, + LocationCannotHold => Self::LocationCannotHold, + ExceedsMaxMessageSize => Self::ExceedsMaxMessageSize, + DestinationUnsupported => Self::DestinationUnsupported, + Transport(s) => Self::Transport(s), + Unroutable => Self::Unroutable, + UnknownClaim => Self::UnknownClaim, + FailedToDecode => Self::FailedToDecode, + MaxWeightInvalid => Self::MaxWeightInvalid, + NotHoldingFees => Self::NotHoldingFees, + TooExpensive => Self::TooExpensive, + Trap(i) => Self::Trap(i), + _ => return Err(()), + }) + } +} + +impl From for Error { + fn from(e: SendError) -> Self { + match e { + SendError::NotApplicable | SendError::Unroutable | SendError::MissingArgument => + Error::Unroutable, + SendError::Transport(s) => Error::Transport(s), + SendError::DestinationUnsupported => Error::DestinationUnsupported, + SendError::ExceedsMaxMessageSize => Error::ExceedsMaxMessageSize, + SendError::Fees => Error::FeesNotMet, + } + } +} + +pub type Result = result::Result<(), Error>; + +/* +TODO: XCMv4 +/// Outcome of an XCM execution. +#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] +pub enum Outcome { + /// Execution completed successfully; given weight was used. + Complete { used: Weight }, + /// Execution started, but did not complete successfully due to the given error; given weight + /// was used. + Incomplete { used: Weight, error: Error }, + /// Execution did not start due to the given error. + Error { error: Error }, +} + +impl Outcome { + pub fn ensure_complete(self) -> Result { + match self { + Outcome::Complete { .. } => Ok(()), + Outcome::Incomplete { error, .. } => Err(error), + Outcome::Error { error, .. } => Err(error), + } + } + pub fn ensure_execution(self) -> result::Result { + match self { + Outcome::Complete { used, .. } => Ok(used), + Outcome::Incomplete { used, .. } => Ok(used), + Outcome::Error { error, .. } => Err(error), + } + } + /// How much weight was used by the XCM execution attempt. + pub fn weight_used(&self) -> Weight { + match self { + Outcome::Complete { used, .. } => *used, + Outcome::Incomplete { used, .. } => *used, + Outcome::Error { .. } => Weight::zero(), + } + } +} + +impl From for Outcome { + fn from(error: Error) -> Self { + Self::Error { error, maybe_id: None } + } +} +*/ + +/// Outcome of an XCM execution. +#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] +pub enum Outcome { + /// Execution completed successfully; given weight was used. + Complete(Weight), + /// Execution started, but did not complete successfully due to the given error; given weight + /// was used. + Incomplete(Weight, Error), + /// Execution did not start due to the given error. + Error(Error), +} + +impl Outcome { + pub fn ensure_complete(self) -> Result { + match self { + Outcome::Complete(_) => Ok(()), + Outcome::Incomplete(_, e) => Err(e), + Outcome::Error(e) => Err(e), + } + } + pub fn ensure_execution(self) -> result::Result { + match self { + Outcome::Complete(w) => Ok(w), + Outcome::Incomplete(w, _) => Ok(w), + Outcome::Error(e) => Err(e), + } + } + /// How much weight was used by the XCM execution attempt. + pub fn weight_used(&self) -> Weight { + match self { + Outcome::Complete(w) => *w, + Outcome::Incomplete(w, _) => *w, + Outcome::Error(_) => Weight::zero(), + } + } +} + +pub trait PreparedMessage { + fn weight_of(&self) -> Weight; +} + +/// Type of XCM message executor. +pub trait ExecuteXcm { + type Prepared: PreparedMessage; + fn prepare(message: Xcm) -> result::Result>; + fn execute( + origin: impl Into, + pre: Self::Prepared, + id: &mut XcmHash, + weight_credit: Weight, + ) -> Outcome; + fn prepare_and_execute( + origin: impl Into, + message: Xcm, + id: &mut XcmHash, + weight_limit: Weight, + weight_credit: Weight, + ) -> Outcome { + let pre = match Self::prepare(message) { + Ok(x) => x, + Err(_) => return Outcome::Error(Error::WeightNotComputable), + }; + let xcm_weight = pre.weight_of(); + if xcm_weight.any_gt(weight_limit) { + return Outcome::Error(Error::WeightLimitReached(xcm_weight)) + } + Self::execute(origin, pre, id, weight_credit) + } + + /// Execute some XCM `message` with the message `hash` from `origin` using no more than + /// `weight_limit` weight. + /// + /// The weight limit is a basic hard-limit and the implementation may place further + /// restrictions or requirements on weight and other aspects. + // TODO: XCMv4 + // #[deprecated = "Use `prepare_and_execute` instead"] + fn execute_xcm( + origin: impl Into, + message: Xcm, + hash: XcmHash, + weight_limit: Weight, + ) -> Outcome { + let origin = origin.into(); + log::debug!( + target: "xcm::execute_xcm", + "origin: {:?}, message: {:?}, weight_limit: {:?}", + origin, + message, + weight_limit, + ); + Self::execute_xcm_in_credit(origin, message, hash, weight_limit, Weight::zero()) + } + + /// Execute some XCM `message` with the message `hash` from `origin` using no more than + /// `weight_limit` weight. + /// + /// Some amount of `weight_credit` may be provided which, depending on the implementation, may + /// allow execution without associated payment. + // TODO: XCMv4 + // #[deprecated = "Use `prepare_and_execute` instead"] + fn execute_xcm_in_credit( + origin: impl Into, + message: Xcm, + mut hash: XcmHash, + weight_limit: Weight, + weight_credit: Weight, + ) -> Outcome { + let pre = match Self::prepare(message) { + Ok(x) => x, + Err(_) => return Outcome::Error(Error::WeightNotComputable), + }; + let xcm_weight = pre.weight_of(); + if xcm_weight.any_gt(weight_limit) { + return Outcome::Error(Error::WeightLimitReached(xcm_weight)) + } + Self::execute(origin, pre, &mut hash, weight_credit) + } + + /// Deduct some `fees` to the sovereign account of the given `location` and place them as per + /// the convention for fees. + fn charge_fees(location: impl Into, fees: MultiAssets) -> Result; +} + +pub enum Weightless {} +impl PreparedMessage for Weightless { + fn weight_of(&self) -> Weight { + unreachable!() + } +} + +impl ExecuteXcm for () { + type Prepared = Weightless; + fn prepare(message: Xcm) -> result::Result> { + Err(message) + } + fn execute( + _: impl Into, + _: Self::Prepared, + _: &mut XcmHash, + _: Weight, + ) -> Outcome { + unreachable!() + } + fn charge_fees(_location: impl Into, _fees: MultiAssets) -> Result { + Err(Error::Unimplemented) + } +} + +/// Error result value when attempting to send an XCM message. +#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, scale_info::TypeInfo)] +pub enum SendError { + /// The message and destination combination was not recognized as being reachable. + /// + /// This is not considered fatal: if there are alternative transport routes available, then + /// they may be attempted. + NotApplicable, + /// Destination is routable, but there is some issue with the transport mechanism. This is + /// considered fatal. + /// A human-readable explanation of the specific issue is provided. + Transport(#[codec(skip)] &'static str), + /// Destination is known to be unroutable. This is considered fatal. + Unroutable, + /// The given message cannot be translated into a format that the destination can be expected + /// to interpret. + DestinationUnsupported, + /// Message could not be sent due to its size exceeding the maximum allowed by the transport + /// layer. + ExceedsMaxMessageSize, + /// A needed argument is `None` when it should be `Some`. + MissingArgument, + /// Fees needed to be paid in order to send the message and they were unavailable. + Fees, +} + +/// A hash type for identifying messages. +pub type XcmHash = [u8; 32]; + +/// Result value when attempting to send an XCM message. +pub type SendResult = result::Result<(T, MultiAssets), SendError>; + +/// Utility for sending an XCM message to a given location. +/// +/// These can be amalgamated in tuples to form sophisticated routing systems. In tuple format, each +/// router might return `NotApplicable` to pass the execution to the next sender item. Note that +/// each `NotApplicable` might alter the destination and the XCM message for to the next router. +/// +/// # Example +/// ```rust +/// # use parity_scale_codec::Encode; +/// # use xcm::v3::{prelude::*, Weight}; +/// # use xcm::VersionedXcm; +/// # use std::convert::Infallible; +/// +/// /// A sender that only passes the message through and does nothing. +/// struct Sender1; +/// impl SendXcm for Sender1 { +/// type Ticket = Infallible; +/// fn validate(_: &mut Option, _: &mut Option>) -> SendResult { +/// Err(SendError::NotApplicable) +/// } +/// fn deliver(_: Infallible) -> Result { +/// unreachable!() +/// } +/// } +/// +/// /// A sender that accepts a message that has an X2 junction, otherwise stops the routing. +/// struct Sender2; +/// impl SendXcm for Sender2 { +/// type Ticket = (); +/// fn validate(destination: &mut Option, message: &mut Option>) -> SendResult<()> { +/// match destination.as_ref().ok_or(SendError::MissingArgument)? { +/// MultiLocation { parents: 0, interior: X2(j1, j2) } => Ok(((), MultiAssets::new())), +/// _ => Err(SendError::Unroutable), +/// } +/// } +/// fn deliver(_: ()) -> Result { +/// Ok([0; 32]) +/// } +/// } +/// +/// /// A sender that accepts a message from a parent, passing through otherwise. +/// struct Sender3; +/// impl SendXcm for Sender3 { +/// type Ticket = (); +/// fn validate(destination: &mut Option, message: &mut Option>) -> SendResult<()> { +/// match destination.as_ref().ok_or(SendError::MissingArgument)? { +/// MultiLocation { parents: 1, interior: Here } => Ok(((), MultiAssets::new())), +/// _ => Err(SendError::NotApplicable), +/// } +/// } +/// fn deliver(_: ()) -> Result { +/// Ok([0; 32]) +/// } +/// } +/// +/// // A call to send via XCM. We don't really care about this. +/// # fn main() { +/// let call: Vec = ().encode(); +/// let message = Xcm(vec![Instruction::Transact { +/// origin_kind: OriginKind::Superuser, +/// require_weight_at_most: Weight::zero(), +/// call: call.into(), +/// }]); +/// let message_hash = message.using_encoded(sp_io::hashing::blake2_256); +/// +/// // Sender2 will block this. +/// assert!(send_xcm::<(Sender1, Sender2, Sender3)>(Parent.into(), message.clone()).is_err()); +/// +/// // Sender3 will catch this. +/// assert!(send_xcm::<(Sender1, Sender3)>(Parent.into(), message.clone()).is_ok()); +/// # } +/// ``` +pub trait SendXcm { + /// Intermediate value which connects the two phases of the send operation. + type Ticket; + + /// Check whether the given `_message` is deliverable to the given `_destination` and if so + /// determine the cost which will be paid by this chain to do so, returning a `Validated` token + /// which can be used to enact delivery. + /// + /// The `destination` and `message` must be `Some` (or else an error will be returned) and they + /// may only be consumed if the `Err` is not `NotApplicable`. + /// + /// If it is not a destination which can be reached with this type but possibly could by others, + /// then this *MUST* return `NotApplicable`. Any other error will cause the tuple + /// implementation to exit early without trying other type fields. + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult; + + /// Actually carry out the delivery operation for a previously validated message sending. + fn deliver(ticket: Self::Ticket) -> result::Result; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl SendXcm for Tuple { + for_tuples! { type Ticket = (#( Option ),* ); } + + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { + let mut maybe_cost: Option = None; + let one_ticket: Self::Ticket = (for_tuples! { #( + if maybe_cost.is_some() { + None + } else { + match Tuple::validate(destination, message) { + Err(SendError::NotApplicable) => None, + Err(e) => { return Err(e) }, + Ok((v, c)) => { + maybe_cost = Some(c); + Some(v) + }, + } + } + ),* }); + if let Some(cost) = maybe_cost { + Ok((one_ticket, cost)) + } else { + Err(SendError::NotApplicable) + } + } + + fn deliver(one_ticket: Self::Ticket) -> result::Result { + for_tuples!( #( + if let Some(validated) = one_ticket.Tuple { + return Tuple::deliver(validated); + } + )* ); + Err(SendError::Unroutable) + } +} + +/// Convenience function for using a `SendXcm` implementation. Just interprets the `dest` and wraps +/// both in `Some` before passing them as as mutable references into `T::send_xcm`. +pub fn validate_send(dest: MultiLocation, msg: Xcm<()>) -> SendResult { + T::validate(&mut Some(dest), &mut Some(msg)) +} + +/// Convenience function for using a `SendXcm` implementation. Just interprets the `dest` and wraps +/// both in `Some` before passing them as as mutable references into `T::send_xcm`. +/// +/// Returns either `Ok` with the price of the delivery, or `Err` with the reason why the message +/// could not be sent. +/// +/// Generally you'll want to validate and get the price first to ensure that the sender can pay it +/// before actually doing the delivery. +pub fn send_xcm( + dest: MultiLocation, + msg: Xcm<()>, +) -> result::Result<(XcmHash, MultiAssets), SendError> { + let (ticket, price) = T::validate(&mut Some(dest), &mut Some(msg))?; + let hash = T::deliver(ticket)?; + Ok((hash, price)) +} diff --git a/polkadot/xcm/xcm-builder/Cargo.toml b/polkadot/xcm/xcm-builder/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..6e4db10168648f5f7603b75f61c58c0e2c2729ca --- /dev/null +++ b/polkadot/xcm/xcm-builder/Cargo.toml @@ -0,0 +1,62 @@ +[package] +name = "xcm-builder" +description = "Tools & types for building with XCM and its executor." +authors.workspace = true +edition.workspace = true +license.workspace = true +version.workspace = true + +[dependencies] +impl-trait-for-tuples = "0.2.1" +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +xcm = { path = "..", default-features = false } +xcm-executor = { path = "../xcm-executor", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-weights = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +log = { version = "0.4.17", default-features = false } + +# Polkadot dependencies +polkadot-parachain = { path = "../../parachain", default-features = false } + +[dev-dependencies] +primitive-types = "0.12.1" +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-xcm = { path = "../pallet-xcm" } +pallet-salary = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-assets = { git = "https://github.com/paritytech/substrate", branch = "master" } +primitives = { package = "polkadot-primitives", path = "../../primitives" } +polkadot-runtime-parachains = { path = "../../runtime/parachains" } +assert_matches = "1.5.0" +polkadot-test-runtime = { path = "../../runtime/test-runtime" } + +[features] +default = ["std"] +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", +] +std = [ + "log/std", + "parity-scale-codec/std", + "scale-info/std", + "xcm/std", + "xcm-executor/std", + "sp-std/std", + "sp-arithmetic/std", + "sp-io/std", + "sp-runtime/std", + "sp-weights/std", + "frame-support/std", + "frame-system/std", + "polkadot-parachain/std", + "pallet-transaction-payment/std", +] diff --git a/polkadot/xcm/xcm-builder/src/asset_conversion.rs b/polkadot/xcm/xcm-builder/src/asset_conversion.rs new file mode 100644 index 0000000000000000000000000000000000000000..a246436a9d6d3ece32175f80b4c97ccc37c65530 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/asset_conversion.rs @@ -0,0 +1,348 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM. + +use frame_support::traits::{Contains, Get}; +use sp_runtime::traits::MaybeEquivalence; +use sp_std::{marker::PhantomData, prelude::*, result}; +use xcm::latest::prelude::*; +use xcm_executor::traits::{Error as MatchError, MatchesFungibles, MatchesNonFungibles}; + +/// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be +/// `TryFrom/TryInto`) into a `GeneralIndex` junction, prefixed by some `MultiLocation` value. +/// The `MultiLocation` value will typically be a `PalletInstance` junction. +pub struct AsPrefixedGeneralIndex( + PhantomData<(Prefix, AssetId, ConvertAssetId)>, +); +impl< + Prefix: Get, + AssetId: Clone, + ConvertAssetId: MaybeEquivalence, + > MaybeEquivalence + for AsPrefixedGeneralIndex +{ + fn convert(id: &MultiLocation) -> Option { + let prefix = Prefix::get(); + if prefix.parent_count() != id.parent_count() || + prefix + .interior() + .iter() + .enumerate() + .any(|(index, junction)| id.interior().at(index) != Some(junction)) + { + return None + } + match id.interior().at(prefix.interior().len()) { + Some(Junction::GeneralIndex(id)) => ConvertAssetId::convert(id), + _ => None, + } + } + fn convert_back(what: &AssetId) -> Option { + let mut location = Prefix::get(); + let id = ConvertAssetId::convert_back(what)?; + location.push_interior(Junction::GeneralIndex(id)).ok()?; + Some(location) + } +} + +pub struct ConvertedConcreteId( + PhantomData<(AssetId, Balance, ConvertAssetId, ConvertOther)>, +); +impl< + AssetId: Clone, + Balance: Clone, + ConvertAssetId: MaybeEquivalence, + ConvertBalance: MaybeEquivalence, + > MatchesFungibles + for ConvertedConcreteId +{ + fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { + let (amount, id) = match (&a.fun, &a.id) { + (Fungible(ref amount), Concrete(ref id)) => (amount, id), + _ => return Err(MatchError::AssetNotHandled), + }; + let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; + let amount = + ConvertBalance::convert(amount).ok_or(MatchError::AmountToBalanceConversionFailed)?; + Ok((what, amount)) + } +} +impl< + ClassId: Clone, + InstanceId: Clone, + ConvertClassId: MaybeEquivalence, + ConvertInstanceId: MaybeEquivalence, + > MatchesNonFungibles + for ConvertedConcreteId +{ + fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { + let (instance, class) = match (&a.fun, &a.id) { + (NonFungible(ref instance), Concrete(ref class)) => (instance, class), + _ => return Err(MatchError::AssetNotHandled), + }; + let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?; + let instance = + ConvertInstanceId::convert(instance).ok_or(MatchError::InstanceConversionFailed)?; + Ok((what, instance)) + } +} + +pub struct ConvertedAbstractId( + PhantomData<(AssetId, Balance, ConvertAssetId, ConvertOther)>, +); +impl< + AssetId: Clone, + Balance: Clone, + ConvertAssetId: MaybeEquivalence<[u8; 32], AssetId>, + ConvertBalance: MaybeEquivalence, + > MatchesFungibles + for ConvertedAbstractId +{ + fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { + let (amount, id) = match (&a.fun, &a.id) { + (Fungible(ref amount), Abstract(ref id)) => (amount, id), + _ => return Err(MatchError::AssetNotHandled), + }; + let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; + let amount = + ConvertBalance::convert(amount).ok_or(MatchError::AmountToBalanceConversionFailed)?; + Ok((what, amount)) + } +} +impl< + ClassId: Clone, + InstanceId: Clone, + ConvertClassId: MaybeEquivalence<[u8; 32], ClassId>, + ConvertInstanceId: MaybeEquivalence, + > MatchesNonFungibles + for ConvertedAbstractId +{ + fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { + let (instance, class) = match (&a.fun, &a.id) { + (NonFungible(ref instance), Abstract(ref class)) => (instance, class), + _ => return Err(MatchError::AssetNotHandled), + }; + let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?; + let instance = + ConvertInstanceId::convert(instance).ok_or(MatchError::InstanceConversionFailed)?; + Ok((what, instance)) + } +} + +#[deprecated = "Use `ConvertedConcreteId` instead"] +pub type ConvertedConcreteAssetId = ConvertedConcreteId; +#[deprecated = "Use `ConvertedAbstractId` instead"] +pub type ConvertedAbstractAssetId = ConvertedAbstractId; + +pub struct MatchedConvertedConcreteId( + PhantomData<(AssetId, Balance, MatchAssetId, ConvertAssetId, ConvertOther)>, +); +impl< + AssetId: Clone, + Balance: Clone, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, + ConvertBalance: MaybeEquivalence, + > MatchesFungibles + for MatchedConvertedConcreteId +{ + fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { + let (amount, id) = match (&a.fun, &a.id) { + (Fungible(ref amount), Concrete(ref id)) if MatchAssetId::contains(id) => (amount, id), + _ => return Err(MatchError::AssetNotHandled), + }; + let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; + let amount = + ConvertBalance::convert(amount).ok_or(MatchError::AmountToBalanceConversionFailed)?; + Ok((what, amount)) + } +} +impl< + ClassId: Clone, + InstanceId: Clone, + MatchClassId: Contains, + ConvertClassId: MaybeEquivalence, + ConvertInstanceId: MaybeEquivalence, + > MatchesNonFungibles + for MatchedConvertedConcreteId +{ + fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { + let (instance, class) = match (&a.fun, &a.id) { + (NonFungible(ref instance), Concrete(ref class)) if MatchClassId::contains(class) => + (instance, class), + _ => return Err(MatchError::AssetNotHandled), + }; + let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?; + let instance = + ConvertInstanceId::convert(instance).ok_or(MatchError::InstanceConversionFailed)?; + Ok((what, instance)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use xcm_executor::traits::JustTry; + + struct OnlyParentZero; + impl Contains for OnlyParentZero { + fn contains(a: &MultiLocation) -> bool { + match a { + MultiLocation { parents: 0, .. } => true, + _ => false, + } + } + } + + #[test] + fn matched_converted_concrete_id_for_fungibles_works() { + type AssetIdForTrustBackedAssets = u32; + type Balance = u128; + frame_support::parameter_types! { + pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(50).into(); + } + + // ConvertedConcreteId cfg + type Converter = MatchedConvertedConcreteId< + AssetIdForTrustBackedAssets, + Balance, + OnlyParentZero, + AsPrefixedGeneralIndex< + TrustBackedAssetsPalletLocation, + AssetIdForTrustBackedAssets, + JustTry, + >, + JustTry, + >; + assert_eq!( + TrustBackedAssetsPalletLocation::get(), + MultiLocation { parents: 0, interior: X1(PalletInstance(50)) } + ); + + // err - does not match + assert_eq!( + Converter::matches_fungibles(&MultiAsset { + id: Concrete(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1)))), + fun: Fungible(12345), + }), + Err(MatchError::AssetNotHandled) + ); + + // err - matches, but convert fails + assert_eq!( + Converter::matches_fungibles(&MultiAsset { + id: Concrete(MultiLocation::new( + 0, + X2(PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }) + )), + fun: Fungible(12345), + }), + Err(MatchError::AssetIdConversionFailed) + ); + + // err - matches, but NonFungible + assert_eq!( + Converter::matches_fungibles(&MultiAsset { + id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + fun: NonFungible(Index(54321)), + }), + Err(MatchError::AssetNotHandled) + ); + + // ok + assert_eq!( + Converter::matches_fungibles(&MultiAsset { + id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + fun: Fungible(12345), + }), + Ok((1, 12345)) + ); + } + + #[test] + fn matched_converted_concrete_id_for_nonfungibles_works() { + type ClassId = u32; + type ClassInstanceId = u64; + frame_support::parameter_types! { + pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(50).into(); + } + + // ConvertedConcreteId cfg + struct ClassInstanceIdConverter; + impl MaybeEquivalence for ClassInstanceIdConverter { + fn convert(value: &AssetInstance) -> Option { + (*value).try_into().ok() + } + + fn convert_back(value: &ClassInstanceId) -> Option { + Some(AssetInstance::from(*value)) + } + } + + type Converter = MatchedConvertedConcreteId< + ClassId, + ClassInstanceId, + OnlyParentZero, + AsPrefixedGeneralIndex, + ClassInstanceIdConverter, + >; + assert_eq!( + TrustBackedAssetsPalletLocation::get(), + MultiLocation { parents: 0, interior: X1(PalletInstance(50)) } + ); + + // err - does not match + assert_eq!( + Converter::matches_nonfungibles(&MultiAsset { + id: Concrete(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1)))), + fun: NonFungible(Index(54321)), + }), + Err(MatchError::AssetNotHandled) + ); + + // err - matches, but convert fails + assert_eq!( + Converter::matches_nonfungibles(&MultiAsset { + id: Concrete(MultiLocation::new( + 0, + X2(PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }) + )), + fun: NonFungible(Index(54321)), + }), + Err(MatchError::AssetIdConversionFailed) + ); + + // err - matches, but Fungible vs NonFungible + assert_eq!( + Converter::matches_nonfungibles(&MultiAsset { + id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + fun: Fungible(12345), + }), + Err(MatchError::AssetNotHandled) + ); + + // ok + assert_eq!( + Converter::matches_nonfungibles(&MultiAsset { + id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + fun: NonFungible(Index(54321)), + }), + Ok((1, 54321)) + ); + } +} diff --git a/polkadot/xcm/xcm-builder/src/barriers.rs b/polkadot/xcm/xcm-builder/src/barriers.rs new file mode 100644 index 0000000000000000000000000000000000000000..353e111b813b66e95fd7a0e7876ca9658afe0c94 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/barriers.rs @@ -0,0 +1,443 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Various implementations for `ShouldExecute`. + +use crate::{CreateMatcher, MatchXcm}; +use frame_support::{ + ensure, + traits::{Contains, Get, ProcessMessageError}, +}; +use polkadot_parachain::primitives::IsSystem; +use sp_std::{cell::Cell, marker::PhantomData, ops::ControlFlow, result::Result}; +use xcm::prelude::*; +use xcm_executor::traits::{CheckSuspension, OnResponse, Properties, ShouldExecute}; + +/// Execution barrier that just takes `max_weight` from `properties.weight_credit`. +/// +/// Useful to allow XCM execution by local chain users via extrinsics. +/// E.g. `pallet_xcm::reserve_asset_transfer` to transfer a reserve asset +/// out of the local chain to another one. +pub struct TakeWeightCredit; +impl ShouldExecute for TakeWeightCredit { + fn should_execute( + _origin: &MultiLocation, + _instructions: &mut [Instruction], + max_weight: Weight, + properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + log::trace!( + target: "xcm::barriers", + "TakeWeightCredit origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", + _origin, _instructions, max_weight, properties, + ); + properties.weight_credit = properties + .weight_credit + .checked_sub(&max_weight) + .ok_or(ProcessMessageError::Overweight(max_weight))?; + Ok(()) + } +} + +const MAX_ASSETS_FOR_BUY_EXECUTION: usize = 1; + +/// Allows execution from `origin` if it is contained in `T` (i.e. `T::Contains(origin)`) taking +/// payments into account. +/// +/// Only allows for `TeleportAsset`, `WithdrawAsset`, `ClaimAsset` and `ReserveAssetDeposit` XCMs +/// because they are the only ones that place assets in the Holding Register to pay for execution. +pub struct AllowTopLevelPaidExecutionFrom(PhantomData); +impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + max_weight: Weight, + _properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + log::trace!( + target: "xcm::barriers", + "AllowTopLevelPaidExecutionFrom origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", + origin, instructions, max_weight, _properties, + ); + + ensure!(T::contains(origin), ProcessMessageError::Unsupported); + // We will read up to 5 instructions. This allows up to 3 `ClearOrigin` instructions. We + // allow for more than one since anything beyond the first is a no-op and it's conceivable + // that composition of operations might result in more than one being appended. + let end = instructions.len().min(5); + instructions[..end] + .matcher() + .match_next_inst(|inst| match inst { + ReceiveTeleportedAsset(..) | ReserveAssetDeposited(..) => Ok(()), + WithdrawAsset(ref assets) if assets.len() <= MAX_ASSETS_FOR_BUY_EXECUTION => Ok(()), + ClaimAsset { ref assets, .. } if assets.len() <= MAX_ASSETS_FOR_BUY_EXECUTION => + Ok(()), + _ => Err(ProcessMessageError::BadFormat), + })? + .skip_inst_while(|inst| matches!(inst, ClearOrigin))? + .match_next_inst(|inst| match inst { + BuyExecution { weight_limit: Limited(ref mut weight), .. } + if weight.all_gte(max_weight) => + { + *weight = max_weight; + Ok(()) + }, + BuyExecution { ref mut weight_limit, .. } if weight_limit == &Unlimited => { + *weight_limit = Limited(max_weight); + Ok(()) + }, + _ => Err(ProcessMessageError::Overweight(max_weight)), + })?; + Ok(()) + } +} + +/// A derivative barrier, which scans the first `MaxPrefixes` instructions for origin-alterers and +/// then evaluates `should_execute` of the `InnerBarrier` based on the remaining instructions and +/// the newly computed origin. +/// +/// This effectively allows for the possibility of distinguishing an origin which is acting as a +/// router for its derivative locations (or as a bridge for a remote location) and an origin which +/// is actually trying to send a message for itself. In the former case, the message will be +/// prefixed with origin-mutating instructions. +/// +/// Any barriers which should be interpreted based on the computed origin rather than the original +/// message origin should be subject to this. This is the case for most barriers since the +/// effective origin is generally more important than the routing origin. Any other barriers, and +/// especially those which should be interpreted only the routing origin should not be subject to +/// this. +/// +/// E.g. +/// ```nocompile +/// type MyBarrier = ( +/// TakeWeightCredit, +/// AllowTopLevelPaidExecutionFrom, +/// WithComputedOrigin<( +/// AllowTopLevelPaidExecutionFrom, +/// AllowUnpaidExecutionFrom, +/// AllowSubscriptionsFrom, +/// AllowKnownQueryResponses, +/// )>, +/// ); +/// ``` +/// +/// In the above example, `AllowUnpaidExecutionFrom` appears once underneath +/// `WithComputedOrigin`. This is in order to distinguish between messages which are notionally +/// from a derivative location of `ParentLocation` but that just happened to be sent via +/// `ParentLocaction` rather than messages that were sent by the parent. +/// +/// Similarly `AllowTopLevelPaidExecutionFrom` appears twice: once inside of `WithComputedOrigin` +/// where we provide the list of origins which are derivative origins, and then secondly outside +/// of `WithComputedOrigin` where we provide the list of locations which are direct origins. It's +/// reasonable for these lists to be merged into one and that used both inside and out. +/// +/// Finally, we see `AllowSubscriptionsFrom` and `AllowKnownQueryResponses` are both inside of +/// `WithComputedOrigin`. This means that if a message begins with origin-mutating instructions, +/// then it must be the finally computed origin which we accept subscriptions or expect a query +/// response from. For example, even if an origin appeared in the `AllowedSubscribers` list, we +/// would ignore this rule if it began with origin mutators and they changed the origin to something +/// which was not on the list. +pub struct WithComputedOrigin( + PhantomData<(InnerBarrier, LocalUniversal, MaxPrefixes)>, +); +impl< + InnerBarrier: ShouldExecute, + LocalUniversal: Get, + MaxPrefixes: Get, + > ShouldExecute for WithComputedOrigin +{ + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + max_weight: Weight, + properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + log::trace!( + target: "xcm::barriers", + "WithComputedOrigin origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", + origin, instructions, max_weight, properties, + ); + let mut actual_origin = *origin; + let skipped = Cell::new(0usize); + // NOTE: We do not check the validity of `UniversalOrigin` here, meaning that a malicious + // origin could place a `UniversalOrigin` in order to spoof some location which gets free + // execution. This technical could get it past the barrier condition, but the execution + // would instantly fail since the first instruction would cause an error with the + // invalid UniversalOrigin. + instructions.matcher().match_next_inst_while( + |_| skipped.get() < MaxPrefixes::get() as usize, + |inst| { + match inst { + UniversalOrigin(new_global) => { + // Note the origin is *relative to local consensus*! So we need to escape + // local consensus with the `parents` before diving in into the + // `universal_location`. + actual_origin = X1(*new_global).relative_to(&LocalUniversal::get()); + }, + DescendOrigin(j) => { + let Ok(_) = actual_origin.append_with(*j) else { + return Err(ProcessMessageError::Unsupported) + }; + }, + _ => return Ok(ControlFlow::Break(())), + }; + skipped.set(skipped.get() + 1); + Ok(ControlFlow::Continue(())) + }, + )?; + InnerBarrier::should_execute( + &actual_origin, + &mut instructions[skipped.get()..], + max_weight, + properties, + ) + } +} + +/// Sets the message ID to `t` using a `SetTopic(t)` in the last position if present. +/// +/// Note that the message ID does not necessarily have to be unique; it is the +/// sender's responsibility to ensure uniqueness. +/// +/// Requires some inner barrier to pass on the rest of the message. +pub struct TrailingSetTopicAsId(PhantomData); +impl ShouldExecute for TrailingSetTopicAsId { + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + max_weight: Weight, + properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + log::trace!( + target: "xcm::barriers", + "TrailingSetTopicAsId origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", + origin, instructions, max_weight, properties, + ); + let until = if let Some(SetTopic(t)) = instructions.last() { + properties.message_id = Some(*t); + instructions.len() - 1 + } else { + instructions.len() + }; + InnerBarrier::should_execute(&origin, &mut instructions[..until], max_weight, properties) + } +} + +/// Barrier condition that allows for a `SuspensionChecker` that controls whether or not the XCM +/// executor will be suspended from executing the given XCM. +pub struct RespectSuspension(PhantomData<(Inner, SuspensionChecker)>); +impl ShouldExecute for RespectSuspension +where + Inner: ShouldExecute, + SuspensionChecker: CheckSuspension, +{ + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + max_weight: Weight, + properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + if SuspensionChecker::is_suspended(origin, instructions, max_weight, properties) { + Err(ProcessMessageError::Yield) + } else { + Inner::should_execute(origin, instructions, max_weight, properties) + } + } +} + +/// Allows execution from any origin that is contained in `T` (i.e. `T::Contains(origin)`). +/// +/// Use only for executions from completely trusted origins, from which no permissionless messages +/// can be sent. +pub struct AllowUnpaidExecutionFrom(PhantomData); +impl> ShouldExecute for AllowUnpaidExecutionFrom { + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + _max_weight: Weight, + _properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + log::trace!( + target: "xcm::barriers", + "AllowUnpaidExecutionFrom origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", + origin, instructions, _max_weight, _properties, + ); + ensure!(T::contains(origin), ProcessMessageError::Unsupported); + Ok(()) + } +} + +/// Allows execution from any origin that is contained in `T` (i.e. `T::Contains(origin)`) if the +/// message begins with the instruction `UnpaidExecution`. +/// +/// Use only for executions from trusted origin groups. +pub struct AllowExplicitUnpaidExecutionFrom(PhantomData); +impl> ShouldExecute for AllowExplicitUnpaidExecutionFrom { + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + max_weight: Weight, + _properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + log::trace!( + target: "xcm::barriers", + "AllowExplicitUnpaidExecutionFrom origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", + origin, instructions, max_weight, _properties, + ); + ensure!(T::contains(origin), ProcessMessageError::Unsupported); + instructions.matcher().match_next_inst(|inst| match inst { + UnpaidExecution { weight_limit: Limited(m), .. } if m.all_gte(max_weight) => Ok(()), + UnpaidExecution { weight_limit: Unlimited, .. } => Ok(()), + _ => Err(ProcessMessageError::Overweight(max_weight)), + })?; + Ok(()) + } +} + +/// Allows a message only if it is from a system-level child parachain. +pub struct IsChildSystemParachain(PhantomData); +impl> Contains for IsChildSystemParachain { + fn contains(l: &MultiLocation) -> bool { + matches!( + l.interior(), + Junctions::X1(Junction::Parachain(id)) + if ParaId::from(*id).is_system() && l.parent_count() == 0, + ) + } +} + +/// Allows only messages if the generic `ResponseHandler` expects them via `expecting_response`. +pub struct AllowKnownQueryResponses(PhantomData); +impl ShouldExecute for AllowKnownQueryResponses { + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + _max_weight: Weight, + _properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + log::trace!( + target: "xcm::barriers", + "AllowKnownQueryResponses origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", + origin, instructions, _max_weight, _properties, + ); + instructions + .matcher() + .assert_remaining_insts(1)? + .match_next_inst(|inst| match inst { + QueryResponse { query_id, querier, .. } + if ResponseHandler::expecting_response(origin, *query_id, querier.as_ref()) => + Ok(()), + _ => Err(ProcessMessageError::BadFormat), + })?; + Ok(()) + } +} + +/// Allows execution from `origin` if it is just a straight `SubscribeVersion` or +/// `UnsubscribeVersion` instruction. +pub struct AllowSubscriptionsFrom(PhantomData); +impl> ShouldExecute for AllowSubscriptionsFrom { + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + _max_weight: Weight, + _properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + log::trace!( + target: "xcm::barriers", + "AllowSubscriptionsFrom origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", + origin, instructions, _max_weight, _properties, + ); + ensure!(T::contains(origin), ProcessMessageError::Unsupported); + instructions + .matcher() + .assert_remaining_insts(1)? + .match_next_inst(|inst| match inst { + SubscribeVersion { .. } | UnsubscribeVersion => Ok(()), + _ => Err(ProcessMessageError::BadFormat), + })?; + Ok(()) + } +} + +/// Deny executing the XCM if it matches any of the Deny filter regardless of anything else. +/// If it passes the Deny, and matches one of the Allow cases then it is let through. +pub struct DenyThenTry(PhantomData, PhantomData) +where + Deny: ShouldExecute, + Allow: ShouldExecute; + +impl ShouldExecute for DenyThenTry +where + Deny: ShouldExecute, + Allow: ShouldExecute, +{ + fn should_execute( + origin: &MultiLocation, + message: &mut [Instruction], + max_weight: Weight, + properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + Deny::should_execute(origin, message, max_weight, properties)?; + Allow::should_execute(origin, message, max_weight, properties) + } +} + +// See issue +pub struct DenyReserveTransferToRelayChain; +impl ShouldExecute for DenyReserveTransferToRelayChain { + fn should_execute( + origin: &MultiLocation, + message: &mut [Instruction], + _max_weight: Weight, + _properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + message.matcher().match_next_inst_while( + |_| true, + |inst| match inst { + InitiateReserveWithdraw { + reserve: MultiLocation { parents: 1, interior: Here }, + .. + } | + DepositReserveAsset { + dest: MultiLocation { parents: 1, interior: Here }, .. + } | + TransferReserveAsset { + dest: MultiLocation { parents: 1, interior: Here }, .. + } => { + Err(ProcessMessageError::Unsupported) // Deny + }, + + // An unexpected reserve transfer has arrived from the Relay Chain. Generally, + // `IsReserve` should not allow this, but we just log it here. + ReserveAssetDeposited { .. } + if matches!(origin, MultiLocation { parents: 1, interior: Here }) => + { + log::warn!( + target: "xcm::barrier", + "Unexpected ReserveAssetDeposited from the Relay Chain", + ); + Ok(ControlFlow::Continue(())) + }, + + _ => Ok(ControlFlow::Continue(())), + }, + )?; + + // Permit everything else + Ok(()) + } +} diff --git a/polkadot/xcm/xcm-builder/src/currency_adapter.rs b/polkadot/xcm/xcm-builder/src/currency_adapter.rs new file mode 100644 index 0000000000000000000000000000000000000000..4dbd4fe8bcd0342d2bfe3722c2900f01f613bcf6 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/currency_adapter.rs @@ -0,0 +1,235 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Adapters to work with `frame_support::traits::Currency` through XCM. + +use super::MintLocation; +use frame_support::traits::{ExistenceRequirement::AllowDeath, Get, WithdrawReasons}; +use sp_runtime::traits::CheckedSub; +use sp_std::{marker::PhantomData, result}; +use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result, XcmContext}; +use xcm_executor::{ + traits::{ConvertLocation, MatchesFungible, TransactAsset}, + Assets, +}; + +/// Asset transaction errors. +enum Error { + /// The given asset is not handled. (According to [`XcmError::AssetNotFound`]) + AssetNotHandled, + /// `MultiLocation` to `AccountId` conversion failed. + AccountIdConversionFailed, +} + +impl From for XcmError { + fn from(e: Error) -> Self { + use XcmError::FailedToTransactAsset; + match e { + Error::AssetNotHandled => XcmError::AssetNotFound, + Error::AccountIdConversionFailed => FailedToTransactAsset("AccountIdConversionFailed"), + } + } +} + +/// Simple adapter to use a currency as asset transactor. This type can be used as `type +/// AssetTransactor` in `xcm::Config`. +/// +/// # Example +/// ``` +/// use parity_scale_codec::Decode; +/// use frame_support::{parameter_types, PalletId}; +/// use sp_runtime::traits::{AccountIdConversion, TrailingZeroInput}; +/// use xcm::latest::prelude::*; +/// use xcm_builder::{ParentIsPreset, CurrencyAdapter, IsConcrete}; +/// +/// /// Our chain's account id. +/// type AccountId = sp_runtime::AccountId32; +/// +/// /// Our relay chain's location. +/// parameter_types! { +/// pub RelayChain: MultiLocation = Parent.into(); +/// pub CheckingAccount: AccountId = PalletId(*b"checking").into_account_truncating(); +/// } +/// +/// /// Some items that implement `ConvertLocation`. Can be more, but for now we just assume we accept +/// /// messages from the parent (relay chain). +/// pub type LocationConverter = (ParentIsPreset); +/// +/// /// Just a dummy implementation of `Currency`. Normally this would be `Balances`. +/// pub type CurrencyImpl = (); +/// +/// /// Final currency adapter. This can be used in `xcm::Config` to specify how asset related transactions happen. +/// pub type AssetTransactor = CurrencyAdapter< +/// // Use this `Currency` impl instance: +/// CurrencyImpl, +/// // The matcher: use the currency when the asset is a concrete asset in our relay chain. +/// IsConcrete, +/// // The local converter: default account of the parent relay chain. +/// LocationConverter, +/// // Our chain's account ID type. +/// AccountId, +/// // The checking account. Can be any deterministic inaccessible account. +/// CheckingAccount, +/// >; +/// ``` +pub struct CurrencyAdapter( + PhantomData<(Currency, Matcher, AccountIdConverter, AccountId, CheckedAccount)>, +); + +impl< + Currency: frame_support::traits::Currency, + Matcher: MatchesFungible, + AccountIdConverter: ConvertLocation, + AccountId: Clone, // can't get away without it since Currency is generic over it. + CheckedAccount: Get>, + > CurrencyAdapter +{ + fn can_accrue_checked(_checked_account: AccountId, _amount: Currency::Balance) -> Result { + Ok(()) + } + fn can_reduce_checked(checked_account: AccountId, amount: Currency::Balance) -> Result { + let new_balance = Currency::free_balance(&checked_account) + .checked_sub(&amount) + .ok_or(XcmError::NotWithdrawable)?; + Currency::ensure_can_withdraw( + &checked_account, + amount, + WithdrawReasons::TRANSFER, + new_balance, + ) + .map_err(|_| XcmError::NotWithdrawable) + } + fn accrue_checked(checked_account: AccountId, amount: Currency::Balance) { + Currency::deposit_creating(&checked_account, amount); + Currency::deactivate(amount); + } + fn reduce_checked(checked_account: AccountId, amount: Currency::Balance) { + let ok = + Currency::withdraw(&checked_account, amount, WithdrawReasons::TRANSFER, AllowDeath) + .is_ok(); + if ok { + Currency::reactivate(amount); + } else { + frame_support::defensive!( + "`can_check_in` must have returned `true` immediately prior; qed" + ); + } + } +} + +impl< + Currency: frame_support::traits::Currency, + Matcher: MatchesFungible, + AccountIdConverter: ConvertLocation, + AccountId: Clone, // can't get away without it since Currency is generic over it. + CheckedAccount: Get>, + > TransactAsset + for CurrencyAdapter +{ + fn can_check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> Result { + log::trace!(target: "xcm::currency_adapter", "can_check_in origin: {:?}, what: {:?}", _origin, what); + // Check we handle this asset. + let amount: Currency::Balance = + Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?; + match CheckedAccount::get() { + Some((checked_account, MintLocation::Local)) => + Self::can_reduce_checked(checked_account, amount), + Some((checked_account, MintLocation::NonLocal)) => + Self::can_accrue_checked(checked_account, amount), + None => Ok(()), + } + } + + fn check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + log::trace!(target: "xcm::currency_adapter", "check_in origin: {:?}, what: {:?}", _origin, what); + if let Some(amount) = Matcher::matches_fungible(what) { + match CheckedAccount::get() { + Some((checked_account, MintLocation::Local)) => + Self::reduce_checked(checked_account, amount), + Some((checked_account, MintLocation::NonLocal)) => + Self::accrue_checked(checked_account, amount), + None => (), + } + } + } + + fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> Result { + log::trace!(target: "xcm::currency_adapter", "check_out dest: {:?}, what: {:?}", _dest, what); + let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?; + match CheckedAccount::get() { + Some((checked_account, MintLocation::Local)) => + Self::can_accrue_checked(checked_account, amount), + Some((checked_account, MintLocation::NonLocal)) => + Self::can_reduce_checked(checked_account, amount), + None => Ok(()), + } + } + + fn check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + log::trace!(target: "xcm::currency_adapter", "check_out dest: {:?}, what: {:?}", _dest, what); + if let Some(amount) = Matcher::matches_fungible(what) { + match CheckedAccount::get() { + Some((checked_account, MintLocation::Local)) => + Self::accrue_checked(checked_account, amount), + Some((checked_account, MintLocation::NonLocal)) => + Self::reduce_checked(checked_account, amount), + None => (), + } + } + } + + fn deposit_asset(what: &MultiAsset, who: &MultiLocation, _context: &XcmContext) -> Result { + log::trace!(target: "xcm::currency_adapter", "deposit_asset what: {:?}, who: {:?}", what, who); + // Check we handle this asset. + let amount = Matcher::matches_fungible(&what).ok_or(Error::AssetNotHandled)?; + let who = + AccountIdConverter::convert_location(who).ok_or(Error::AccountIdConversionFailed)?; + let _imbalance = Currency::deposit_creating(&who, amount); + Ok(()) + } + + fn withdraw_asset( + what: &MultiAsset, + who: &MultiLocation, + _maybe_context: Option<&XcmContext>, + ) -> result::Result { + log::trace!(target: "xcm::currency_adapter", "withdraw_asset what: {:?}, who: {:?}", what, who); + // Check we handle this asset. + let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?; + let who = + AccountIdConverter::convert_location(who).ok_or(Error::AccountIdConversionFailed)?; + Currency::withdraw(&who, amount, WithdrawReasons::TRANSFER, AllowDeath) + .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; + Ok(what.clone().into()) + } + + fn internal_transfer_asset( + asset: &MultiAsset, + from: &MultiLocation, + to: &MultiLocation, + _context: &XcmContext, + ) -> result::Result { + log::trace!(target: "xcm::currency_adapter", "internal_transfer_asset asset: {:?}, from: {:?}, to: {:?}", asset, from, to); + let amount = Matcher::matches_fungible(asset).ok_or(Error::AssetNotHandled)?; + let from = + AccountIdConverter::convert_location(from).ok_or(Error::AccountIdConversionFailed)?; + let to = + AccountIdConverter::convert_location(to).ok_or(Error::AccountIdConversionFailed)?; + Currency::transfer(&from, &to, amount, AllowDeath) + .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; + Ok(asset.clone().into()) + } +} diff --git a/polkadot/xcm/xcm-builder/src/filter_asset_location.rs b/polkadot/xcm/xcm-builder/src/filter_asset_location.rs new file mode 100644 index 0000000000000000000000000000000000000000..68dd86d9bfeb371e4a4baca92a0e20b31d32f3fc --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/filter_asset_location.rs @@ -0,0 +1,42 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Various implementations of `ContainsPair`. + +use frame_support::traits::{ContainsPair, Get}; +use sp_std::marker::PhantomData; +use xcm::latest::{AssetId::Concrete, MultiAsset, MultiAssetFilter, MultiLocation}; + +/// Accepts an asset iff it is a native asset. +pub struct NativeAsset; +impl ContainsPair for NativeAsset { + fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + log::trace!(target: "xcm::contains", "NativeAsset asset: {:?}, origin: {:?}", asset, origin); + matches!(asset.id, Concrete(ref id) if id == origin) + } +} + +/// Accepts an asset if it is contained in the given `T`'s `Get` implementation. +pub struct Case(PhantomData); +impl> ContainsPair + for Case +{ + fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + log::trace!(target: "xcm::contains", "Case asset: {:?}, origin: {:?}", asset, origin); + let (a, o) = T::get(); + a.matches(asset) && &o == origin + } +} diff --git a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs new file mode 100644 index 0000000000000000000000000000000000000000..d7fded01e2db7a0114bada2bdce5a06249907efc --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs @@ -0,0 +1,410 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM. + +use frame_support::traits::{ + tokens::{ + fungibles, Fortitude::Polite, Precision::Exact, Preservation::Preserve, Provenance::Minted, + }, + Contains, Get, +}; +use sp_std::{marker::PhantomData, prelude::*, result}; +use xcm::latest::prelude::*; +use xcm_executor::traits::{ConvertLocation, Error as MatchError, MatchesFungibles, TransactAsset}; + +/// `TransactAsset` implementation to convert a `fungibles` implementation to become usable in XCM. +pub struct FungiblesTransferAdapter( + PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)>, +); +impl< + Assets: fungibles::Mutate, + Matcher: MatchesFungibles, + AccountIdConverter: ConvertLocation, + AccountId: Clone, // can't get away without it since Currency is generic over it. + > TransactAsset for FungiblesTransferAdapter +{ + fn internal_transfer_asset( + what: &MultiAsset, + from: &MultiLocation, + to: &MultiLocation, + _context: &XcmContext, + ) -> result::Result { + log::trace!( + target: "xcm::fungibles_adapter", + "internal_transfer_asset what: {:?}, from: {:?}, to: {:?}", + what, from, to + ); + // Check we handle this asset. + let (asset_id, amount) = Matcher::matches_fungibles(what)?; + let source = AccountIdConverter::convert_location(from) + .ok_or(MatchError::AccountIdConversionFailed)?; + let dest = AccountIdConverter::convert_location(to) + .ok_or(MatchError::AccountIdConversionFailed)?; + Assets::transfer(asset_id, &source, &dest, amount, Preserve) + .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; + Ok(what.clone().into()) + } +} + +/// The location which is allowed to mint a particular asset. +#[derive(Copy, Clone, Eq, PartialEq)] +pub enum MintLocation { + /// This chain is allowed to mint the asset. When we track teleports of the asset we ensure + /// that no more of the asset returns back to the chain than has been sent out. + Local, + /// This chain is not allowed to mint the asset. When we track teleports of the asset we ensure + /// that no more of the asset is sent out from the chain than has been previously received. + NonLocal, +} + +/// Simple trait to indicate whether an asset is subject to having its teleportation into and out of +/// this chain recorded and if so in what `MintLocation`. +/// +/// The overall purpose of asset-checking is to ensure either no more assets are teleported into a +/// chain than the outstanding balance of assets which were previously teleported out (as in the +/// case of locally-minted assets); or that no more assets are teleported out of a chain than the +/// outstanding balance of assets which have previously been teleported in (as in the case of chains +/// where the `asset` is not minted locally). +pub trait AssetChecking { + /// Return the teleportation asset-checking policy for the given `asset`. `None` implies no + /// checking. Otherwise the policy detailed by the inner `MintLocation` should be respected by + /// teleportation. + fn asset_checking(asset: &AssetId) -> Option; +} + +/// Implementation of `AssetChecking` which subjects no assets to having their teleportations +/// recorded. +pub struct NoChecking; +impl AssetChecking for NoChecking { + fn asset_checking(_: &AssetId) -> Option { + None + } +} + +/// Implementation of `AssetChecking` which subjects a given set of assets `T` to having their +/// teleportations recorded with a `MintLocation::Local`. +pub struct LocalMint(sp_std::marker::PhantomData); +impl> AssetChecking for LocalMint { + fn asset_checking(asset: &AssetId) -> Option { + match T::contains(asset) { + true => Some(MintLocation::Local), + false => None, + } + } +} + +/// Implementation of `AssetChecking` which subjects a given set of assets `T` to having their +/// teleportations recorded with a `MintLocation::NonLocal`. +pub struct NonLocalMint(sp_std::marker::PhantomData); +impl> AssetChecking for NonLocalMint { + fn asset_checking(asset: &AssetId) -> Option { + match T::contains(asset) { + true => Some(MintLocation::NonLocal), + false => None, + } + } +} + +/// Implementation of `AssetChecking` which subjects a given set of assets `L` to having their +/// teleportations recorded with a `MintLocation::Local` and a second set of assets `R` to having +/// their teleportations recorded with a `MintLocation::NonLocal`. +pub struct DualMint(sp_std::marker::PhantomData<(L, R)>); +impl, R: Contains> AssetChecking + for DualMint +{ + fn asset_checking(asset: &AssetId) -> Option { + if L::contains(asset) { + Some(MintLocation::Local) + } else if R::contains(asset) { + Some(MintLocation::NonLocal) + } else { + None + } + } +} + +pub struct FungiblesMutateAdapter< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, +>(PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>); + +impl< + Assets: fungibles::Mutate, + Matcher: MatchesFungibles, + AccountIdConverter: ConvertLocation, + AccountId: Clone, // can't get away without it since Currency is generic over it. + CheckAsset: AssetChecking, + CheckingAccount: Get, + > + FungiblesMutateAdapter +{ + fn can_accrue_checked(asset_id: Assets::AssetId, amount: Assets::Balance) -> XcmResult { + let checking_account = CheckingAccount::get(); + Assets::can_deposit(asset_id, &checking_account, amount, Minted) + .into_result() + .map_err(|_| XcmError::NotDepositable) + } + fn can_reduce_checked(asset_id: Assets::AssetId, amount: Assets::Balance) -> XcmResult { + let checking_account = CheckingAccount::get(); + Assets::can_withdraw(asset_id, &checking_account, amount) + .into_result(false) + .map_err(|_| XcmError::NotWithdrawable) + .map(|_| ()) + } + fn accrue_checked(asset_id: Assets::AssetId, amount: Assets::Balance) { + let checking_account = CheckingAccount::get(); + let ok = Assets::mint_into(asset_id, &checking_account, amount).is_ok(); + debug_assert!(ok, "`can_accrue_checked` must have returned `true` immediately prior; qed"); + } + fn reduce_checked(asset_id: Assets::AssetId, amount: Assets::Balance) { + let checking_account = CheckingAccount::get(); + let ok = Assets::burn_from(asset_id, &checking_account, amount, Exact, Polite).is_ok(); + debug_assert!(ok, "`can_reduce_checked` must have returned `true` immediately prior; qed"); + } +} + +impl< + Assets: fungibles::Mutate, + Matcher: MatchesFungibles, + AccountIdConverter: ConvertLocation, + AccountId: Clone, // can't get away without it since Currency is generic over it. + CheckAsset: AssetChecking, + CheckingAccount: Get, + > TransactAsset + for FungiblesMutateAdapter< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + > +{ + fn can_check_in( + _origin: &MultiLocation, + what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + log::trace!( + target: "xcm::fungibles_adapter", + "can_check_in origin: {:?}, what: {:?}", + _origin, what + ); + // Check we handle this asset. + let (asset_id, amount) = Matcher::matches_fungibles(what)?; + match CheckAsset::asset_checking(&asset_id) { + // We track this asset's teleports to ensure no more come in than have gone out. + Some(MintLocation::Local) => Self::can_reduce_checked(asset_id, amount), + // We track this asset's teleports to ensure no more go out than have come in. + Some(MintLocation::NonLocal) => Self::can_accrue_checked(asset_id, amount), + _ => Ok(()), + } + } + + fn check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + log::trace!( + target: "xcm::fungibles_adapter", + "check_in origin: {:?}, what: {:?}", + _origin, what + ); + if let Ok((asset_id, amount)) = Matcher::matches_fungibles(what) { + match CheckAsset::asset_checking(&asset_id) { + // We track this asset's teleports to ensure no more come in than have gone out. + Some(MintLocation::Local) => Self::reduce_checked(asset_id, amount), + // We track this asset's teleports to ensure no more go out than have come in. + Some(MintLocation::NonLocal) => Self::accrue_checked(asset_id, amount), + _ => (), + } + } + } + + fn can_check_out( + _origin: &MultiLocation, + what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + log::trace!( + target: "xcm::fungibles_adapter", + "can_check_in origin: {:?}, what: {:?}", + _origin, what + ); + // Check we handle this asset. + let (asset_id, amount) = Matcher::matches_fungibles(what)?; + match CheckAsset::asset_checking(&asset_id) { + // We track this asset's teleports to ensure no more come in than have gone out. + Some(MintLocation::Local) => Self::can_accrue_checked(asset_id, amount), + // We track this asset's teleports to ensure no more go out than have come in. + Some(MintLocation::NonLocal) => Self::can_reduce_checked(asset_id, amount), + _ => Ok(()), + } + } + + fn check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + log::trace!( + target: "xcm::fungibles_adapter", + "check_out dest: {:?}, what: {:?}", + _dest, what + ); + if let Ok((asset_id, amount)) = Matcher::matches_fungibles(what) { + match CheckAsset::asset_checking(&asset_id) { + // We track this asset's teleports to ensure no more come in than have gone out. + Some(MintLocation::Local) => Self::accrue_checked(asset_id, amount), + // We track this asset's teleports to ensure no more go out than have come in. + Some(MintLocation::NonLocal) => Self::reduce_checked(asset_id, amount), + _ => (), + } + } + } + + fn deposit_asset(what: &MultiAsset, who: &MultiLocation, _context: &XcmContext) -> XcmResult { + log::trace!( + target: "xcm::fungibles_adapter", + "deposit_asset what: {:?}, who: {:?}", + what, who, + ); + // Check we handle this asset. + let (asset_id, amount) = Matcher::matches_fungibles(what)?; + let who = AccountIdConverter::convert_location(who) + .ok_or(MatchError::AccountIdConversionFailed)?; + Assets::mint_into(asset_id, &who, amount) + .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; + Ok(()) + } + + fn withdraw_asset( + what: &MultiAsset, + who: &MultiLocation, + _maybe_context: Option<&XcmContext>, + ) -> result::Result { + log::trace!( + target: "xcm::fungibles_adapter", + "withdraw_asset what: {:?}, who: {:?}", + what, who, + ); + // Check we handle this asset. + let (asset_id, amount) = Matcher::matches_fungibles(what)?; + let who = AccountIdConverter::convert_location(who) + .ok_or(MatchError::AccountIdConversionFailed)?; + Assets::burn_from(asset_id, &who, amount, Exact, Polite) + .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; + Ok(what.clone().into()) + } +} + +pub struct FungiblesAdapter< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, +>(PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>); +impl< + Assets: fungibles::Mutate, + Matcher: MatchesFungibles, + AccountIdConverter: ConvertLocation, + AccountId: Clone, // can't get away without it since Currency is generic over it. + CheckAsset: AssetChecking, + CheckingAccount: Get, + > TransactAsset + for FungiblesAdapter +{ + fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + FungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::can_check_in(origin, what, context) + } + + fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + FungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::check_in(origin, what, context) + } + + fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + FungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::can_check_out(dest, what, context) + } + + fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + FungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::check_out(dest, what, context) + } + + fn deposit_asset(what: &MultiAsset, who: &MultiLocation, context: &XcmContext) -> XcmResult { + FungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::deposit_asset(what, who, context) + } + + fn withdraw_asset( + what: &MultiAsset, + who: &MultiLocation, + maybe_context: Option<&XcmContext>, + ) -> result::Result { + FungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::withdraw_asset(what, who, maybe_context) + } + + fn internal_transfer_asset( + what: &MultiAsset, + from: &MultiLocation, + to: &MultiLocation, + context: &XcmContext, + ) -> result::Result { + FungiblesTransferAdapter::::internal_transfer_asset( + what, from, to, context + ) + } +} diff --git a/polkadot/xcm/xcm-builder/src/lib.rs b/polkadot/xcm/xcm-builder/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..e3f91040963840d2b29ceaa30fc1a8e373de4817 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/lib.rs @@ -0,0 +1,109 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! # XCM-Builder +//! +//! Types and helpers for *building* XCM configuration. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(test)] +mod tests; + +#[cfg(feature = "std")] +pub mod test_utils; + +mod location_conversion; +#[allow(deprecated)] +pub use location_conversion::ForeignChainAliasAccount; +pub use location_conversion::{ + Account32Hash, AccountId32Aliases, AccountKey20Aliases, AliasesIntoAccountId32, + ChildParachainConvertsVia, DescribeAccountId32Terminal, DescribeAccountIdTerminal, + DescribeAccountKey20Terminal, DescribeAllTerminal, DescribeFamily, DescribeLocation, + DescribePalletTerminal, DescribeTerminus, GlobalConsensusConvertsFor, + GlobalConsensusParachainConvertsFor, HashedDescription, ParentIsPreset, + SiblingParachainConvertsVia, +}; + +mod origin_conversion; +pub use origin_conversion::{ + BackingToPlurality, ChildParachainAsNative, ChildSystemParachainAsSuperuser, EnsureXcmOrigin, + OriginToPluralityVoice, ParentAsSuperuser, RelayChainAsNative, SiblingParachainAsNative, + SiblingSystemParachainAsSuperuser, SignedAccountId32AsNative, SignedAccountKey20AsNative, + SignedToAccountId32, SovereignSignedViaLocation, +}; + +mod asset_conversion; +pub use asset_conversion::{ + AsPrefixedGeneralIndex, ConvertedAbstractId, ConvertedConcreteId, MatchedConvertedConcreteId, +}; +#[allow(deprecated)] +pub use asset_conversion::{ConvertedAbstractAssetId, ConvertedConcreteAssetId}; + +mod barriers; +pub use barriers::{ + AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, AllowSubscriptionsFrom, + AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, DenyReserveTransferToRelayChain, + DenyThenTry, IsChildSystemParachain, RespectSuspension, TakeWeightCredit, TrailingSetTopicAsId, + WithComputedOrigin, +}; + +mod process_xcm_message; +pub use process_xcm_message::ProcessXcmMessage; + +mod currency_adapter; +pub use currency_adapter::CurrencyAdapter; + +mod fungibles_adapter; +pub use fungibles_adapter::{ + AssetChecking, DualMint, FungiblesAdapter, FungiblesMutateAdapter, FungiblesTransferAdapter, + LocalMint, MintLocation, NoChecking, NonLocalMint, +}; + +mod nonfungibles_adapter; +pub use nonfungibles_adapter::{ + NonFungiblesAdapter, NonFungiblesMutateAdapter, NonFungiblesTransferAdapter, +}; + +mod weight; +pub use weight::{ + FixedRateOfFungible, FixedWeightBounds, TakeRevenue, UsingComponents, WeightInfoBounds, +}; + +mod matches_token; +pub use matches_token::{IsAbstract, IsConcrete}; + +mod matcher; +pub use matcher::{CreateMatcher, MatchXcm, Matcher}; + +mod filter_asset_location; +pub use filter_asset_location::{Case, NativeAsset}; + +mod routing; +pub use routing::{WithTopicSource, WithUniqueTopic}; + +mod universal_exports; +pub use universal_exports::{ + ensure_is_remote, BridgeBlobDispatcher, BridgeMessage, DispatchBlob, DispatchBlobError, + ExporterFor, HaulBlob, HaulBlobError, HaulBlobExporter, NetworkExportTable, + SovereignPaidRemoteExporter, UnpaidLocalExporter, UnpaidRemoteExporter, +}; + +mod origin_aliases; +pub use origin_aliases::AliasForeignAccountId32; + +mod pay; +pub use pay::{FixedLocation, LocatableAssetId, PayAccountId32OnChainOverXcm, PayOverXcm}; diff --git a/polkadot/xcm/xcm-builder/src/location_conversion.rs b/polkadot/xcm/xcm-builder/src/location_conversion.rs new file mode 100644 index 0000000000000000000000000000000000000000..26b48fc88adcea2ca7cdb9d64402b6844a88942e --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/location_conversion.rs @@ -0,0 +1,928 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::universal_exports::ensure_is_remote; +use frame_support::traits::Get; +use parity_scale_codec::{Compact, Decode, Encode}; +use sp_io::hashing::blake2_256; +use sp_runtime::traits::{AccountIdConversion, Convert, TrailingZeroInput}; +use sp_std::{marker::PhantomData, prelude::*}; +use xcm::latest::prelude::*; +use xcm_executor::traits::ConvertLocation; + +/// Means of converting a location into a stable and unique descriptive identifier. +pub trait DescribeLocation { + /// Create a description of the given `location` if possible. No two locations should have the + /// same descriptor. + fn describe_location(location: &MultiLocation) -> Option>; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl DescribeLocation for Tuple { + fn describe_location(l: &MultiLocation) -> Option> { + for_tuples!( #( + match Tuple::describe_location(l) { + Some(result) => return Some(result), + None => {}, + } + )* ); + None + } +} + +pub struct DescribeTerminus; +impl DescribeLocation for DescribeTerminus { + fn describe_location(l: &MultiLocation) -> Option> { + match (l.parents, &l.interior) { + (0, Here) => Some(Vec::new()), + _ => return None, + } + } +} + +pub struct DescribePalletTerminal; +impl DescribeLocation for DescribePalletTerminal { + fn describe_location(l: &MultiLocation) -> Option> { + match (l.parents, &l.interior) { + (0, X1(PalletInstance(i))) => + Some((b"Pallet", Compact::::from(*i as u32)).encode()), + _ => return None, + } + } +} + +pub struct DescribeAccountId32Terminal; +impl DescribeLocation for DescribeAccountId32Terminal { + fn describe_location(l: &MultiLocation) -> Option> { + match (l.parents, &l.interior) { + (0, X1(AccountId32 { id, .. })) => Some((b"AccountId32", id).encode()), + _ => return None, + } + } +} + +pub struct DescribeAccountKey20Terminal; +impl DescribeLocation for DescribeAccountKey20Terminal { + fn describe_location(l: &MultiLocation) -> Option> { + match (l.parents, &l.interior) { + (0, X1(AccountKey20 { key, .. })) => Some((b"AccountKey20", key).encode()), + _ => return None, + } + } +} + +pub type DescribeAccountIdTerminal = (DescribeAccountId32Terminal, DescribeAccountKey20Terminal); + +pub type DescribeAllTerminal = ( + DescribeTerminus, + DescribePalletTerminal, + DescribeAccountId32Terminal, + DescribeAccountKey20Terminal, +); + +pub struct DescribeFamily(PhantomData); +impl DescribeLocation for DescribeFamily { + fn describe_location(l: &MultiLocation) -> Option> { + match (l.parents, l.interior.first()) { + (0, Some(Parachain(index))) => { + let tail = l.interior.split_first().0; + let interior = Suffix::describe_location(&tail.into())?; + Some((b"ChildChain", Compact::::from(*index), interior).encode()) + }, + (1, Some(Parachain(index))) => { + let tail = l.interior.split_first().0; + let interior = Suffix::describe_location(&tail.into())?; + Some((b"SiblingChain", Compact::::from(*index), interior).encode()) + }, + (1, _) => { + let tail = l.interior.into(); + let interior = Suffix::describe_location(&tail)?; + Some((b"ParentChain", interior).encode()) + }, + _ => return None, + } + } +} + +pub struct HashedDescription(PhantomData<(AccountId, Describe)>); +impl + Clone, Describe: DescribeLocation> ConvertLocation + for HashedDescription +{ + fn convert_location(value: &MultiLocation) -> Option { + Some(blake2_256(&Describe::describe_location(value)?).into()) + } +} + +/// This is a describer for legacy support of the `ForeignChainAliasAccount` preimage. New chains +/// are recommended to use the more extensible `HashedDescription` type. +pub struct LegacyDescribeForeignChainAccount; +impl DescribeLocation for LegacyDescribeForeignChainAccount { + fn describe_location(location: &MultiLocation) -> Option> { + Some(match location { + // Used on the relay chain for sending paras that use 32 byte accounts + MultiLocation { + parents: 0, + interior: X2(Parachain(para_id), AccountId32 { id, .. }), + } => LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 0), + + // Used on the relay chain for sending paras that use 20 byte accounts + MultiLocation { + parents: 0, + interior: X2(Parachain(para_id), AccountKey20 { key, .. }), + } => LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 0), + + // Used on para-chain for sending paras that use 32 byte accounts + MultiLocation { + parents: 1, + interior: X2(Parachain(para_id), AccountId32 { id, .. }), + } => LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 1), + + // Used on para-chain for sending paras that use 20 byte accounts + MultiLocation { + parents: 1, + interior: X2(Parachain(para_id), AccountKey20 { key, .. }), + } => LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 1), + + // Used on para-chain for sending from the relay chain + MultiLocation { parents: 1, interior: X1(AccountId32 { id, .. }) } => + LegacyDescribeForeignChainAccount::from_relay_32(id, 1), + + // No other conversions provided + _ => return None, + }) + } +} + +/// Prefix for generating alias account for accounts coming +/// from chains that use 32 byte long representations. +pub const FOREIGN_CHAIN_PREFIX_PARA_32: [u8; 37] = *b"ForeignChainAliasAccountPrefix_Para32"; + +/// Prefix for generating alias account for accounts coming +/// from chains that use 20 byte long representations. +pub const FOREIGN_CHAIN_PREFIX_PARA_20: [u8; 37] = *b"ForeignChainAliasAccountPrefix_Para20"; + +/// Prefix for generating alias account for accounts coming +/// from the relay chain using 32 byte long representations. +pub const FOREIGN_CHAIN_PREFIX_RELAY: [u8; 36] = *b"ForeignChainAliasAccountPrefix_Relay"; + +impl LegacyDescribeForeignChainAccount { + fn from_para_32(para_id: &u32, id: &[u8; 32], parents: u8) -> Vec { + (FOREIGN_CHAIN_PREFIX_PARA_32, para_id, id, parents).encode() + } + + fn from_para_20(para_id: &u32, id: &[u8; 20], parents: u8) -> Vec { + (FOREIGN_CHAIN_PREFIX_PARA_20, para_id, id, parents).encode() + } + + fn from_relay_32(id: &[u8; 32], parents: u8) -> Vec { + (FOREIGN_CHAIN_PREFIX_RELAY, id, parents).encode() + } +} + +/// This is deprecated in favor of the more modular `HashedDescription` converter. If +/// your chain has previously used this, then you can retain backwards compatibility using +/// `HashedDescription` and a tuple with `LegacyDescribeForeignChainAccount` as the first +/// element. For example: +/// +/// ```nocompile +/// pub type LocationToAccount = HashedDescription< +/// // Legacy conversion - MUST BE FIRST! +/// LegacyDescribeForeignChainAccount, +/// // Other conversions +/// DescribeTerminus, +/// DescribePalletTerminal, +/// >; +/// ``` +/// +/// This type is equivalent to the above but without any other conversions. +/// +/// ### Old documentation +/// +/// This converter will for a given `AccountId32`/`AccountKey20` +/// always generate the same "remote" account for a specific +/// sending chain. +/// I.e. the user gets the same remote account +/// on every consuming para-chain and relay chain. +/// +/// Can be used as a converter in `SovereignSignedViaLocation` +/// +/// ## Example +/// Assuming the following network layout. +/// +/// ```notrust +/// R +/// / \ +/// / \ +/// P1 P2 +/// / \ / \ +/// / \ / \ +/// P1.1 P1.2 P2.1 P2.2 +/// ``` +/// Then a given account A will have the same alias accounts in the +/// same plane. So, it is important which chain account A acts from. +/// E.g. +/// * From P1.2 A will act as +/// * hash(`ParaPrefix`, A, 1, 1) on P1.2 +/// * hash(`ParaPrefix`, A, 1, 0) on P1 +/// * From P1 A will act as +/// * hash(`RelayPrefix`, A, 1) on P1.2 & P1.1 +/// * hash(`ParaPrefix`, A, 1, 1) on P2 +/// * hash(`ParaPrefix`, A, 1, 0) on R +/// +/// Note that the alias accounts have overlaps but never on the same +/// chain when the sender comes from different chains. +#[deprecated = "Use `HashedDescription` instead"] +pub type ForeignChainAliasAccount = + HashedDescription; + +pub struct Account32Hash(PhantomData<(Network, AccountId)>); +impl>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> + ConvertLocation for Account32Hash +{ + fn convert_location(location: &MultiLocation) -> Option { + Some(("multiloc", location).using_encoded(blake2_256).into()) + } +} + +/// A [`MultiLocation`] consisting of a single `Parent` [`Junction`] will be converted to the +/// parent `AccountId`. +pub struct ParentIsPreset(PhantomData); +impl ConvertLocation for ParentIsPreset { + fn convert_location(location: &MultiLocation) -> Option { + if location.contains_parents_only(1) { + Some( + b"Parent" + .using_encoded(|b| AccountId::decode(&mut TrailingZeroInput::new(b))) + .expect("infinite length input; no invalid inputs for type; qed"), + ) + } else { + None + } + } +} + +pub struct ChildParachainConvertsVia(PhantomData<(ParaId, AccountId)>); +impl + Into + AccountIdConversion, AccountId: Clone> + ConvertLocation for ChildParachainConvertsVia +{ + fn convert_location(location: &MultiLocation) -> Option { + match location { + MultiLocation { parents: 0, interior: X1(Parachain(id)) } => + Some(ParaId::from(*id).into_account_truncating()), + _ => None, + } + } +} + +pub struct SiblingParachainConvertsVia(PhantomData<(ParaId, AccountId)>); +impl + Into + AccountIdConversion, AccountId: Clone> + ConvertLocation for SiblingParachainConvertsVia +{ + fn convert_location(location: &MultiLocation) -> Option { + match location { + MultiLocation { parents: 1, interior: X1(Parachain(id)) } => + Some(ParaId::from(*id).into_account_truncating()), + _ => None, + } + } +} + +/// Extracts the `AccountId32` from the passed `location` if the network matches. +pub struct AccountId32Aliases(PhantomData<(Network, AccountId)>); +impl>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> + ConvertLocation for AccountId32Aliases +{ + fn convert_location(location: &MultiLocation) -> Option { + let id = match *location { + MultiLocation { parents: 0, interior: X1(AccountId32 { id, network: None }) } => id, + MultiLocation { parents: 0, interior: X1(AccountId32 { id, network }) } + if network == Network::get() => + id, + _ => return None, + }; + Some(id.into()) + } +} + +/// Conversion implementation which converts from a `[u8; 32]`-based `AccountId` into a +/// `MultiLocation` consisting solely of a `AccountId32` junction with a fixed value for its +/// network (provided by `Network`) and the `AccountId`'s `[u8; 32]` datum for the `id`. +pub struct AliasesIntoAccountId32(PhantomData<(Network, AccountId)>); +impl<'a, Network: Get>, AccountId: Clone + Into<[u8; 32]> + Clone> + Convert<&'a AccountId, MultiLocation> for AliasesIntoAccountId32 +{ + fn convert(who: &AccountId) -> MultiLocation { + AccountId32 { network: Network::get(), id: who.clone().into() }.into() + } +} + +pub struct AccountKey20Aliases(PhantomData<(Network, AccountId)>); +impl>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone> + ConvertLocation for AccountKey20Aliases +{ + fn convert_location(location: &MultiLocation) -> Option { + let key = match *location { + MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network: None }) } => key, + MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network }) } + if network == Network::get() => + key, + _ => return None, + }; + Some(key.into()) + } +} + +/// Converts a location which is a top-level relay chain (which provides its own consensus) into a +/// 32-byte `AccountId`. +/// +/// This will always result in the *same account ID* being returned for the same Relay-chain, +/// regardless of the relative security of this Relay-chain compared to the local chain. +/// +/// Note: No distinction is made between the cases when the given `UniversalLocation` lies within +/// the same consensus system (i.e. is itself or a parent) and when it is a foreign consensus +/// system. +pub struct GlobalConsensusConvertsFor( + PhantomData<(UniversalLocation, AccountId)>, +); +impl, AccountId: From<[u8; 32]> + Clone> + ConvertLocation for GlobalConsensusConvertsFor +{ + fn convert_location(location: &MultiLocation) -> Option { + let universal_source = UniversalLocation::get(); + log::trace!( + target: "xcm::location_conversion", + "GlobalConsensusConvertsFor universal_source: {:?}, location: {:?}", + universal_source, location, + ); + let (remote_network, remote_location) = + ensure_is_remote(universal_source, *location).ok()?; + + match remote_location { + Here => Some(AccountId::from(Self::from_params(&remote_network))), + _ => None, + } + } +} +impl GlobalConsensusConvertsFor { + fn from_params(network: &NetworkId) -> [u8; 32] { + (b"glblcnsnss_", network).using_encoded(blake2_256) + } +} + +/// Converts a location which is a top-level parachain (i.e. a parachain held on a +/// Relay-chain which provides its own consensus) into a 32-byte `AccountId`. +/// +/// This will always result in the *same account ID* being returned for the same +/// parachain index under the same Relay-chain, regardless of the relative security of +/// this Relay-chain compared to the local chain. +/// +/// Note: No distinction is made when the local chain happens to be the parachain in +/// question or its Relay-chain. +/// +/// WARNING: This results in the same `AccountId` value being generated regardless +/// of the relative security of the local chain and the Relay-chain of the input +/// location. This may not have any immediate security risks, however since it creates +/// commonalities between chains with different security characteristics, it could +/// possibly form part of a more sophisticated attack scenario. +pub struct GlobalConsensusParachainConvertsFor( + PhantomData<(UniversalLocation, AccountId)>, +); +impl, AccountId: From<[u8; 32]> + Clone> + ConvertLocation for GlobalConsensusParachainConvertsFor +{ + fn convert_location(location: &MultiLocation) -> Option { + let universal_source = UniversalLocation::get(); + log::trace!( + target: "xcm::location_conversion", + "GlobalConsensusParachainConvertsFor universal_source: {:?}, location: {:?}", + universal_source, location, + ); + let devolved = ensure_is_remote(universal_source, *location).ok()?; + let (remote_network, remote_location) = devolved; + + match remote_location { + X1(Parachain(remote_network_para_id)) => + Some(AccountId::from(Self::from_params(&remote_network, &remote_network_para_id))), + _ => None, + } + } +} +impl + GlobalConsensusParachainConvertsFor +{ + fn from_params(network: &NetworkId, para_id: &u32) -> [u8; 32] { + (b"glblcnsnss/prchn_", network, para_id).using_encoded(blake2_256) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + pub type ForeignChainAliasAccount = + HashedDescription; + + use frame_support::parameter_types; + use xcm::latest::Junction; + + fn account20() -> Junction { + AccountKey20 { network: None, key: Default::default() } + } + + fn account32() -> Junction { + AccountId32 { network: None, id: Default::default() } + } + + // Network Topology + // v Source + // Relay -> Para 1 -> SmartContract -> Account + // -> Para 2 -> Account + // ^ Target + // + // Inputs and outputs written as file paths: + // + // input location (source to target): ../../../para_2/account32_default + // context (root to source): para_1/account20_default/account20_default + // => + // output (target to source): ../../para_1/account20_default/account20_default + #[test] + fn inverter_works_in_tree() { + parameter_types! { + pub UniversalLocation: InteriorMultiLocation = X3(Parachain(1), account20(), account20()); + } + + let input = MultiLocation::new(3, X2(Parachain(2), account32())); + let inverted = UniversalLocation::get().invert_target(&input).unwrap(); + assert_eq!(inverted, MultiLocation::new(2, X3(Parachain(1), account20(), account20()))); + } + + // Network Topology + // v Source + // Relay -> Para 1 -> SmartContract -> Account + // ^ Target + #[test] + fn inverter_uses_context_as_inverted_location() { + parameter_types! { + pub UniversalLocation: InteriorMultiLocation = X2(account20(), account20()); + } + + let input = MultiLocation::grandparent(); + let inverted = UniversalLocation::get().invert_target(&input).unwrap(); + assert_eq!(inverted, X2(account20(), account20()).into()); + } + + // Network Topology + // v Source + // Relay -> Para 1 -> CollectivePallet -> Plurality + // ^ Target + #[test] + fn inverter_uses_only_child_on_missing_context() { + parameter_types! { + pub UniversalLocation: InteriorMultiLocation = PalletInstance(5).into(); + } + + let input = MultiLocation::grandparent(); + let inverted = UniversalLocation::get().invert_target(&input).unwrap(); + assert_eq!(inverted, (OnlyChild, PalletInstance(5)).into()); + } + + #[test] + fn inverter_errors_when_location_is_too_large() { + parameter_types! { + pub UniversalLocation: InteriorMultiLocation = Here; + } + + let input = MultiLocation { parents: 99, interior: X1(Parachain(88)) }; + let inverted = UniversalLocation::get().invert_target(&input); + assert_eq!(inverted, Err(())); + } + + #[test] + fn global_consensus_converts_for_works() { + parameter_types! { + pub UniversalLocationInNetwork1: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([1; 32])), Parachain(1234)); + pub UniversalLocationInNetwork2: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([2; 32])), Parachain(1234)); + } + let network_1 = UniversalLocationInNetwork1::get().global_consensus().expect("NetworkId"); + let network_2 = UniversalLocationInNetwork2::get().global_consensus().expect("NetworkId"); + let network_3 = ByGenesis([3; 32]); + let network_4 = ByGenesis([4; 32]); + let network_5 = ByGenesis([5; 32]); + + let test_data = vec![ + (MultiLocation::parent(), false), + (MultiLocation::new(0, Here), false), + (MultiLocation::new(0, X1(GlobalConsensus(network_1))), false), + (MultiLocation::new(1, X1(GlobalConsensus(network_1))), false), + (MultiLocation::new(2, X1(GlobalConsensus(network_1))), false), + (MultiLocation::new(0, X1(GlobalConsensus(network_2))), false), + (MultiLocation::new(1, X1(GlobalConsensus(network_2))), false), + (MultiLocation::new(2, X1(GlobalConsensus(network_2))), true), + (MultiLocation::new(0, X2(GlobalConsensus(network_2), Parachain(1000))), false), + (MultiLocation::new(1, X2(GlobalConsensus(network_2), Parachain(1000))), false), + (MultiLocation::new(2, X2(GlobalConsensus(network_2), Parachain(1000))), false), + ]; + + for (location, expected_result) in test_data { + let result = + GlobalConsensusConvertsFor::::convert_location( + &location, + ); + match result { + Some(account) => { + assert_eq!( + true, expected_result, + "expected_result: {}, but conversion passed: {:?}, location: {:?}", + expected_result, account, location + ); + match &location { + MultiLocation { interior: X1(GlobalConsensus(network)), .. } => + assert_eq!( + account, + GlobalConsensusConvertsFor::::from_params(network), + "expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location + ), + _ => panic!("expected_result: {}, conversion passed: {:?}, but MultiLocation does not match expected pattern, location: {:?}", expected_result, account, location) + } + }, + None => { + assert_eq!( + false, expected_result, + "expected_result: {} - but conversion failed, location: {:?}", + expected_result, location + ); + }, + } + } + + // all success + let res_1_gc_network_3 = + GlobalConsensusConvertsFor::::convert_location( + &MultiLocation::new(2, X1(GlobalConsensus(network_3))), + ) + .expect("conversion is ok"); + let res_2_gc_network_3 = + GlobalConsensusConvertsFor::::convert_location( + &MultiLocation::new(2, X1(GlobalConsensus(network_3))), + ) + .expect("conversion is ok"); + let res_1_gc_network_4 = + GlobalConsensusConvertsFor::::convert_location( + &MultiLocation::new(2, X1(GlobalConsensus(network_4))), + ) + .expect("conversion is ok"); + let res_2_gc_network_4 = + GlobalConsensusConvertsFor::::convert_location( + &MultiLocation::new(2, X1(GlobalConsensus(network_4))), + ) + .expect("conversion is ok"); + let res_1_gc_network_5 = + GlobalConsensusConvertsFor::::convert_location( + &MultiLocation::new(2, X1(GlobalConsensus(network_5))), + ) + .expect("conversion is ok"); + let res_2_gc_network_5 = + GlobalConsensusConvertsFor::::convert_location( + &MultiLocation::new(2, X1(GlobalConsensus(network_5))), + ) + .expect("conversion is ok"); + + assert_ne!(res_1_gc_network_3, res_1_gc_network_4); + assert_ne!(res_1_gc_network_4, res_1_gc_network_5); + assert_ne!(res_1_gc_network_3, res_1_gc_network_5); + + assert_eq!(res_1_gc_network_3, res_2_gc_network_3); + assert_eq!(res_1_gc_network_4, res_2_gc_network_4); + assert_eq!(res_1_gc_network_5, res_2_gc_network_5); + } + + #[test] + fn global_consensus_parachain_converts_for_works() { + parameter_types! { + pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([9; 32])), Parachain(1234)); + } + + let test_data = vec![ + (MultiLocation::parent(), false), + (MultiLocation::new(0, X1(Parachain(1000))), false), + (MultiLocation::new(1, X1(Parachain(1000))), false), + ( + MultiLocation::new( + 2, + X3( + GlobalConsensus(ByGenesis([0; 32])), + Parachain(1000), + AccountId32 { network: None, id: [1; 32].into() }, + ), + ), + false, + ), + (MultiLocation::new(2, X1(GlobalConsensus(ByGenesis([0; 32])))), false), + ( + MultiLocation::new(0, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), + false, + ), + ( + MultiLocation::new(1, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), + false, + ), + (MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), true), + ( + MultiLocation::new(3, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), + false, + ), + ( + MultiLocation::new(9, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), + false, + ), + ]; + + for (location, expected_result) in test_data { + let result = + GlobalConsensusParachainConvertsFor::::convert_location( + &location, + ); + match result { + Some(account) => { + assert_eq!( + true, expected_result, + "expected_result: {}, but conversion passed: {:?}, location: {:?}", + expected_result, account, location + ); + match &location { + MultiLocation { interior: X2(GlobalConsensus(network), Parachain(para_id)), .. } => + assert_eq!( + account, + GlobalConsensusParachainConvertsFor::::from_params(network, para_id), + "expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location + ), + _ => assert_eq!( + true, + expected_result, + "expected_result: {}, conversion passed: {:?}, but MultiLocation does not match expected pattern, location: {:?}", expected_result, account, location + ) + } + }, + None => { + assert_eq!( + false, expected_result, + "expected_result: {} - but conversion failed, location: {:?}", + expected_result, location + ); + }, + } + } + + // all success + let res_gc_a_p1000 = + GlobalConsensusParachainConvertsFor::::convert_location( + &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1000))), + ) + .expect("conversion is ok"); + let res_gc_a_p1001 = + GlobalConsensusParachainConvertsFor::::convert_location( + &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1001))), + ) + .expect("conversion is ok"); + let res_gc_b_p1000 = + GlobalConsensusParachainConvertsFor::::convert_location( + &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1000))), + ) + .expect("conversion is ok"); + let res_gc_b_p1001 = + GlobalConsensusParachainConvertsFor::::convert_location( + &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1001))), + ) + .expect("conversion is ok"); + assert_ne!(res_gc_a_p1000, res_gc_a_p1001); + assert_ne!(res_gc_a_p1000, res_gc_b_p1000); + assert_ne!(res_gc_a_p1000, res_gc_b_p1001); + assert_ne!(res_gc_b_p1000, res_gc_b_p1001); + assert_ne!(res_gc_b_p1000, res_gc_a_p1001); + assert_ne!(res_gc_b_p1001, res_gc_a_p1001); + } + + #[test] + fn remote_account_convert_on_para_sending_para_32() { + let mul = MultiLocation { + parents: 1, + interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }), + }; + let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); + + assert_eq!( + [ + 181, 186, 132, 152, 52, 210, 226, 199, 8, 235, 213, 242, 94, 70, 250, 170, 19, 163, + 196, 102, 245, 14, 172, 184, 2, 148, 108, 87, 230, 163, 204, 32 + ], + rem_1 + ); + + let mul = MultiLocation { + parents: 1, + interior: X2( + Parachain(1), + AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }, + ), + }; + + assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); + + let mul = MultiLocation { + parents: 1, + interior: X2(Parachain(2), AccountId32 { network: None, id: [0u8; 32] }), + }; + let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); + + assert_eq!( + [ + 183, 188, 66, 169, 82, 250, 45, 30, 142, 119, 184, 55, 177, 64, 53, 114, 12, 147, + 128, 10, 60, 45, 41, 193, 87, 18, 86, 49, 127, 233, 243, 143 + ], + rem_2 + ); + + assert_ne!(rem_1, rem_2); + } + + #[test] + fn remote_account_convert_on_para_sending_para_20() { + let mul = MultiLocation { + parents: 1, + interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }), + }; + let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); + + assert_eq!( + [ + 210, 60, 37, 255, 116, 38, 221, 26, 85, 82, 252, 125, 220, 19, 41, 91, 185, 69, + 102, 83, 120, 63, 15, 212, 74, 141, 82, 203, 187, 212, 77, 120 + ], + rem_1 + ); + + let mul = MultiLocation { + parents: 1, + interior: X2( + Parachain(1), + AccountKey20 { network: Some(NetworkId::Polkadot), key: [0u8; 20] }, + ), + }; + + assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); + + let mul = MultiLocation { + parents: 1, + interior: X2(Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }), + }; + let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); + + assert_eq!( + [ + 197, 16, 31, 199, 234, 80, 166, 55, 178, 135, 95, 48, 19, 128, 9, 167, 51, 99, 215, + 147, 94, 171, 28, 157, 29, 107, 240, 22, 10, 104, 99, 186 + ], + rem_2 + ); + + assert_ne!(rem_1, rem_2); + } + + #[test] + fn remote_account_convert_on_para_sending_relay() { + let mul = MultiLocation { + parents: 1, + interior: X1(AccountId32 { network: None, id: [0u8; 32] }), + }; + let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); + + assert_eq!( + [ + 227, 12, 152, 241, 220, 53, 26, 27, 1, 167, 167, 214, 61, 161, 255, 96, 56, 16, + 221, 59, 47, 45, 40, 193, 88, 92, 4, 167, 164, 27, 112, 99 + ], + rem_1 + ); + + let mul = MultiLocation { + parents: 1, + interior: X1(AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }), + }; + + assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); + + let mul = MultiLocation { + parents: 1, + interior: X1(AccountId32 { network: None, id: [1u8; 32] }), + }; + let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); + + assert_eq!( + [ + 143, 195, 87, 73, 129, 2, 163, 211, 239, 51, 55, 235, 82, 173, 162, 206, 158, 237, + 166, 73, 254, 62, 131, 6, 170, 241, 209, 116, 105, 69, 29, 226 + ], + rem_2 + ); + + assert_ne!(rem_1, rem_2); + } + + #[test] + fn remote_account_convert_on_relay_sending_para_20() { + let mul = MultiLocation { + parents: 0, + interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }), + }; + let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); + + assert_eq!( + [ + 25, 251, 15, 92, 148, 141, 236, 238, 50, 108, 133, 56, 118, 11, 250, 122, 81, 160, + 104, 160, 97, 200, 210, 49, 208, 142, 64, 144, 24, 110, 246, 101 + ], + rem_1 + ); + + let mul = MultiLocation { + parents: 0, + interior: X2(Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }), + }; + let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); + + assert_eq!( + [ + 88, 157, 224, 235, 76, 88, 201, 143, 206, 227, 14, 192, 177, 245, 75, 62, 41, 10, + 107, 182, 61, 57, 239, 112, 43, 151, 58, 111, 150, 153, 234, 189 + ], + rem_2 + ); + + assert_ne!(rem_1, rem_2); + } + + #[test] + fn remote_account_convert_on_relay_sending_para_32() { + let mul = MultiLocation { + parents: 0, + interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }), + }; + let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); + + assert_eq!( + [ + 45, 120, 232, 0, 226, 49, 106, 48, 65, 181, 184, 147, 224, 235, 198, 152, 183, 156, + 67, 57, 67, 67, 187, 104, 171, 23, 140, 21, 183, 152, 63, 20 + ], + rem_1 + ); + + let mul = MultiLocation { + parents: 0, + interior: X2( + Parachain(1), + AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }, + ), + }; + + assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); + + let mul = MultiLocation { + parents: 0, + interior: X2(Parachain(2), AccountId32 { network: None, id: [0u8; 32] }), + }; + let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); + + assert_eq!( + [ + 97, 119, 110, 66, 239, 113, 96, 234, 127, 92, 66, 204, 53, 129, 33, 119, 213, 192, + 171, 100, 139, 51, 39, 62, 196, 163, 16, 213, 160, 44, 100, 228 + ], + rem_2 + ); + + assert_ne!(rem_1, rem_2); + } + + #[test] + fn remote_account_fails_with_bad_multilocation() { + let mul = MultiLocation { + parents: 1, + interior: X1(AccountKey20 { network: None, key: [0u8; 20] }), + }; + assert!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).is_none()); + } +} diff --git a/polkadot/xcm/xcm-builder/src/matcher.rs b/polkadot/xcm/xcm-builder/src/matcher.rs new file mode 100644 index 0000000000000000000000000000000000000000..4a3c896a159ff81601dcbd9fa07e04975aaffb64 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/matcher.rs @@ -0,0 +1,191 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// 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 Polkadot. If not, see . + +//! XCM matcher API, used primarily for writing barrier conditions. + +use core::ops::ControlFlow; +use frame_support::traits::ProcessMessageError; +use xcm::latest::{Instruction, MultiLocation}; + +/// Creates an instruction matcher from an XCM. Since XCM versions differ, we need to make a trait +/// here to unify the interfaces among them. +pub trait CreateMatcher { + /// The concrete matcher type. + type Matcher; + + /// Method that creates and returns the matcher type from `Self`. + fn matcher(self) -> Self::Matcher; +} + +impl<'a, Call> CreateMatcher for &'a mut [Instruction] { + type Matcher = Matcher<'a, Call>; + + fn matcher(self) -> Self::Matcher { + let total_inst = self.len(); + + Matcher { xcm: self, current_idx: 0, total_inst } + } +} + +/// API that allows to pattern-match against anything that is contained within an XCM. +/// +/// The intended usage of the matcher API is to enable the ability to chain successive methods of +/// this trait together, along with the ? operator for the purpose of facilitating the writing, +/// maintenance and auditability of XCM barriers. +/// +/// Example: +/// ```rust +/// use frame_support::traits::ProcessMessageError; +/// use xcm::latest::Instruction; +/// use xcm_builder::{CreateMatcher, MatchXcm}; +/// +/// let mut msg = [Instruction::<()>::ClearOrigin]; +/// let res = msg +/// .matcher() +/// .assert_remaining_insts(1)? +/// .match_next_inst(|inst| match inst { +/// Instruction::<()>::ClearOrigin => Ok(()), +/// _ => Err(ProcessMessageError::BadFormat), +/// }); +/// assert!(res.is_ok()); +/// +/// Ok::<(), ProcessMessageError>(()) +/// ``` +pub trait MatchXcm { + /// The concrete instruction type. Necessary to specify as it changes between XCM versions. + type Inst; + /// The `MultiLocation` type. Necessary to specify as it changes between XCM versions. + type Loc; + /// The error type to throw when errors happen during matching. + type Error; + + /// Returns success if the number of instructions that still have not been iterated over + /// equals `n`, otherwise returns an error. + fn assert_remaining_insts(self, n: usize) -> Result + where + Self: Sized; + + /// Accepts a closure `f` that contains an argument signifying the next instruction to be + /// iterated over. The closure can then be used to check whether the instruction matches a + /// given condition, and can also be used to mutate the fields of an instruction. + /// + /// The closure `f` returns success when the instruction passes the condition, otherwise it + /// returns an error, which will ultimately be returned by this function. + fn match_next_inst(self, f: F) -> Result + where + Self: Sized, + F: FnMut(&mut Self::Inst) -> Result<(), Self::Error>; + + /// Attempts to continuously iterate through the instructions while applying `f` to each of + /// them, until either the last instruction or `cond` returns false. + /// + /// If `f` returns an error, then iteration halts and the function returns that error. + /// Otherwise, `f` returns a `ControlFlow` which signifies whether the iteration breaks or + /// continues. + fn match_next_inst_while(self, cond: C, f: F) -> Result + where + Self: Sized, + C: Fn(&Self::Inst) -> bool, + F: FnMut(&mut Self::Inst) -> Result, Self::Error>; + + /// Iterate instructions forward until `cond` returns false. When there are no more instructions + /// to be read, an error is returned. + fn skip_inst_while(self, cond: C) -> Result + where + Self: Sized, + C: Fn(&Self::Inst) -> bool, + { + Self::match_next_inst_while(self, cond, |_| Ok(ControlFlow::Continue(()))) + } +} + +/// Struct created from calling `fn matcher()` on a mutable slice of `Instruction`s. +/// +/// Implements `MatchXcm` to allow an iterator-like API to match against each `Instruction` +/// contained within the slice, which facilitates the building of XCM barriers. +pub struct Matcher<'a, Call> { + pub(crate) xcm: &'a mut [Instruction], + pub(crate) current_idx: usize, + pub(crate) total_inst: usize, +} + +impl<'a, Call> MatchXcm for Matcher<'a, Call> { + type Error = ProcessMessageError; + type Inst = Instruction; + type Loc = MultiLocation; + + fn assert_remaining_insts(self, n: usize) -> Result + where + Self: Sized, + { + if self.total_inst - self.current_idx != n { + return Err(ProcessMessageError::BadFormat) + } + + Ok(self) + } + + fn match_next_inst(mut self, mut f: F) -> Result + where + Self: Sized, + F: FnMut(&mut Self::Inst) -> Result<(), Self::Error>, + { + if self.current_idx < self.total_inst { + f(&mut self.xcm[self.current_idx])?; + self.current_idx += 1; + Ok(self) + } else { + Err(ProcessMessageError::BadFormat) + } + } + + fn match_next_inst_while(mut self, cond: C, mut f: F) -> Result + where + Self: Sized, + C: Fn(&Self::Inst) -> bool, + F: FnMut(&mut Self::Inst) -> Result, Self::Error>, + { + if self.current_idx >= self.total_inst { + return Err(ProcessMessageError::BadFormat) + } + + while self.current_idx < self.total_inst && cond(&self.xcm[self.current_idx]) { + if let ControlFlow::Break(()) = f(&mut self.xcm[self.current_idx])? { + break + } + self.current_idx += 1; + } + + Ok(self) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::{vec, vec::Vec}; + use xcm::latest::prelude::*; + + #[test] + fn match_next_inst_while_works() { + let mut xcm: Vec> = vec![ClearOrigin]; + + let _ = xcm + .matcher() + .match_next_inst_while(|_| true, |_| Ok(ControlFlow::Continue(()))) + .unwrap(); + } +} diff --git a/polkadot/xcm/xcm-builder/src/matches_token.rs b/polkadot/xcm/xcm-builder/src/matches_token.rs new file mode 100644 index 0000000000000000000000000000000000000000..ddb25799be62dc3ddf6e3f0850bdbe18b29a2165 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/matches_token.rs @@ -0,0 +1,109 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Various implementations for the `MatchesFungible` trait. + +use frame_support::traits::Get; +use sp_std::marker::PhantomData; +use xcm::latest::{ + AssetId::{Abstract, Concrete}, + AssetInstance, + Fungibility::{Fungible, NonFungible}, + MultiAsset, MultiLocation, +}; +use xcm_executor::traits::{MatchesFungible, MatchesNonFungible}; + +/// Converts a `MultiAsset` into balance `B` if it is a concrete fungible with an id equal to that +/// given by `T`'s `Get`. +/// +/// # Example +/// +/// ``` +/// use xcm::latest::{MultiLocation, Parent}; +/// use xcm_builder::IsConcrete; +/// use xcm_executor::traits::MatchesFungible; +/// +/// frame_support::parameter_types! { +/// pub TargetLocation: MultiLocation = Parent.into(); +/// } +/// +/// # fn main() { +/// let asset = (Parent, 999).into(); +/// // match `asset` if it is a concrete asset in `TargetLocation`. +/// assert_eq!( as MatchesFungible>::matches_fungible(&asset), Some(999)); +/// # } +/// ``` +pub struct IsConcrete(PhantomData); +impl, B: TryFrom> MatchesFungible for IsConcrete { + fn matches_fungible(a: &MultiAsset) -> Option { + match (&a.id, &a.fun) { + (Concrete(ref id), Fungible(ref amount)) if id == &T::get() => + (*amount).try_into().ok(), + _ => None, + } + } +} +impl, I: TryFrom> MatchesNonFungible for IsConcrete { + fn matches_nonfungible(a: &MultiAsset) -> Option { + match (&a.id, &a.fun) { + (Concrete(id), NonFungible(instance)) if id == &T::get() => (*instance).try_into().ok(), + _ => None, + } + } +} + +/// Same as [`IsConcrete`] but for a fungible with abstract location. +/// +/// # Example +/// +/// ``` +/// use xcm::latest::prelude::*; +/// use xcm_builder::IsAbstract; +/// use xcm_executor::traits::{MatchesFungible, MatchesNonFungible}; +/// +/// frame_support::parameter_types! { +/// pub TargetLocation: [u8; 32] = [7u8; 32]; +/// } +/// +/// # fn main() { +/// let asset = ([7u8; 32], 999u128).into(); +/// // match `asset` if it is an abstract asset in `TargetLocation`. +/// assert_eq!( as MatchesFungible>::matches_fungible(&asset), Some(999)); +/// let nft = ([7u8; 32], [42u8; 4]).into(); +/// assert_eq!( +/// as MatchesNonFungible<[u8; 4]>>::matches_nonfungible(&nft), +/// Some([42u8; 4]) +/// ); +/// # } +/// ``` +pub struct IsAbstract(PhantomData); +impl, B: TryFrom> MatchesFungible for IsAbstract { + fn matches_fungible(a: &MultiAsset) -> Option { + match (&a.id, &a.fun) { + (Abstract(ref id), Fungible(ref amount)) if id == &T::get() => + (*amount).try_into().ok(), + _ => None, + } + } +} +impl, B: TryFrom> MatchesNonFungible for IsAbstract { + fn matches_nonfungible(a: &MultiAsset) -> Option { + match (&a.id, &a.fun) { + (Abstract(id), NonFungible(instance)) if id == &T::get() => (*instance).try_into().ok(), + _ => None, + } + } +} diff --git a/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs b/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs new file mode 100644 index 0000000000000000000000000000000000000000..6cf5980df0e9e2227c8bda76a41493efcd248e32 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs @@ -0,0 +1,346 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM. + +use crate::{AssetChecking, MintLocation}; +use frame_support::{ + ensure, + traits::{tokens::nonfungibles, Get}, +}; +use sp_std::{marker::PhantomData, prelude::*, result}; +use xcm::latest::prelude::*; +use xcm_executor::traits::{ + ConvertLocation, Error as MatchError, MatchesNonFungibles, TransactAsset, +}; + +const LOG_TARGET: &str = "xcm::nonfungibles_adapter"; + +pub struct NonFungiblesTransferAdapter( + PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)>, +); +impl< + Assets: nonfungibles::Transfer, + Matcher: MatchesNonFungibles, + AccountIdConverter: ConvertLocation, + AccountId: Clone, // can't get away without it since Currency is generic over it. + > TransactAsset for NonFungiblesTransferAdapter +{ + fn transfer_asset( + what: &MultiAsset, + from: &MultiLocation, + to: &MultiLocation, + context: &XcmContext, + ) -> result::Result { + log::trace!( + target: LOG_TARGET, + "transfer_asset what: {:?}, from: {:?}, to: {:?}, context: {:?}", + what, + from, + to, + context, + ); + // Check we handle this asset. + let (class, instance) = Matcher::matches_nonfungibles(what)?; + let destination = AccountIdConverter::convert_location(to) + .ok_or(MatchError::AccountIdConversionFailed)?; + Assets::transfer(&class, &instance, &destination) + .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; + Ok(what.clone().into()) + } +} + +pub struct NonFungiblesMutateAdapter< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, +>(PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>); + +impl< + Assets: nonfungibles::Mutate, + Matcher: MatchesNonFungibles, + AccountIdConverter: ConvertLocation, + AccountId: Clone + Eq, // can't get away without it since Currency is generic over it. + CheckAsset: AssetChecking, + CheckingAccount: Get>, + > + NonFungiblesMutateAdapter< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + > +{ + fn can_accrue_checked(class: Assets::CollectionId, instance: Assets::ItemId) -> XcmResult { + ensure!(Assets::owner(&class, &instance).is_none(), XcmError::NotDepositable); + Ok(()) + } + fn can_reduce_checked(class: Assets::CollectionId, instance: Assets::ItemId) -> XcmResult { + if let Some(checking_account) = CheckingAccount::get() { + // This is an asset whose teleports we track. + let owner = Assets::owner(&class, &instance); + ensure!(owner == Some(checking_account), XcmError::NotWithdrawable); + ensure!(Assets::can_transfer(&class, &instance), XcmError::NotWithdrawable); + } + Ok(()) + } + fn accrue_checked(class: Assets::CollectionId, instance: Assets::ItemId) { + if let Some(checking_account) = CheckingAccount::get() { + let ok = Assets::mint_into(&class, &instance, &checking_account).is_ok(); + debug_assert!(ok, "`mint_into` cannot generally fail; qed"); + } + } + fn reduce_checked(class: Assets::CollectionId, instance: Assets::ItemId) { + let ok = Assets::burn(&class, &instance, None).is_ok(); + debug_assert!(ok, "`can_check_in` must have returned `true` immediately prior; qed"); + } +} + +impl< + Assets: nonfungibles::Mutate, + Matcher: MatchesNonFungibles, + AccountIdConverter: ConvertLocation, + AccountId: Clone + Eq, // can't get away without it since Currency is generic over it. + CheckAsset: AssetChecking, + CheckingAccount: Get>, + > TransactAsset + for NonFungiblesMutateAdapter< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + > +{ + fn can_check_in(_origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + log::trace!( + target: LOG_TARGET, + "can_check_in origin: {:?}, what: {:?}, context: {:?}", + _origin, + what, + context, + ); + // Check we handle this asset. + let (class, instance) = Matcher::matches_nonfungibles(what)?; + match CheckAsset::asset_checking(&class) { + // We track this asset's teleports to ensure no more come in than have gone out. + Some(MintLocation::Local) => Self::can_reduce_checked(class, instance), + // We track this asset's teleports to ensure no more go out than have come in. + Some(MintLocation::NonLocal) => Self::can_accrue_checked(class, instance), + _ => Ok(()), + } + } + + fn check_in(_origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + log::trace!( + target: LOG_TARGET, + "check_in origin: {:?}, what: {:?}, context: {:?}", + _origin, + what, + context, + ); + if let Ok((class, instance)) = Matcher::matches_nonfungibles(what) { + match CheckAsset::asset_checking(&class) { + // We track this asset's teleports to ensure no more come in than have gone out. + Some(MintLocation::Local) => Self::reduce_checked(class, instance), + // We track this asset's teleports to ensure no more go out than have come in. + Some(MintLocation::NonLocal) => Self::accrue_checked(class, instance), + _ => (), + } + } + } + + fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + log::trace!( + target: LOG_TARGET, + "can_check_out dest: {:?}, what: {:?}, context: {:?}", + _dest, + what, + context, + ); + // Check we handle this asset. + let (class, instance) = Matcher::matches_nonfungibles(what)?; + match CheckAsset::asset_checking(&class) { + // We track this asset's teleports to ensure no more come in than have gone out. + Some(MintLocation::Local) => Self::can_accrue_checked(class, instance), + // We track this asset's teleports to ensure no more go out than have come in. + Some(MintLocation::NonLocal) => Self::can_reduce_checked(class, instance), + _ => Ok(()), + } + } + + fn check_out(_dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + log::trace!( + target: LOG_TARGET, + "check_out dest: {:?}, what: {:?}, context: {:?}", + _dest, + what, + context, + ); + if let Ok((class, instance)) = Matcher::matches_nonfungibles(what) { + match CheckAsset::asset_checking(&class) { + // We track this asset's teleports to ensure no more come in than have gone out. + Some(MintLocation::Local) => Self::accrue_checked(class, instance), + // We track this asset's teleports to ensure no more go out than have come in. + Some(MintLocation::NonLocal) => Self::reduce_checked(class, instance), + _ => (), + } + } + } + + fn deposit_asset(what: &MultiAsset, who: &MultiLocation, context: &XcmContext) -> XcmResult { + log::trace!( + target: LOG_TARGET, + "deposit_asset what: {:?}, who: {:?}, context: {:?}", + what, + who, + context, + ); + // Check we handle this asset. + let (class, instance) = Matcher::matches_nonfungibles(what)?; + let who = AccountIdConverter::convert_location(who) + .ok_or(MatchError::AccountIdConversionFailed)?; + Assets::mint_into(&class, &instance, &who) + .map_err(|e| XcmError::FailedToTransactAsset(e.into())) + } + + fn withdraw_asset( + what: &MultiAsset, + who: &MultiLocation, + maybe_context: Option<&XcmContext>, + ) -> result::Result { + log::trace!( + target: LOG_TARGET, + "withdraw_asset what: {:?}, who: {:?}, maybe_context: {:?}", + what, + who, + maybe_context, + ); + // Check we handle this asset. + let who = AccountIdConverter::convert_location(who) + .ok_or(MatchError::AccountIdConversionFailed)?; + let (class, instance) = Matcher::matches_nonfungibles(what)?; + Assets::burn(&class, &instance, Some(&who)) + .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; + Ok(what.clone().into()) + } +} + +pub struct NonFungiblesAdapter< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, +>(PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>); +impl< + Assets: nonfungibles::Mutate + nonfungibles::Transfer, + Matcher: MatchesNonFungibles, + AccountIdConverter: ConvertLocation, + AccountId: Clone + Eq, // can't get away without it since Currency is generic over it. + CheckAsset: AssetChecking, + CheckingAccount: Get>, + > TransactAsset + for NonFungiblesAdapter +{ + fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + NonFungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::can_check_in(origin, what, context) + } + + fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + NonFungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::check_in(origin, what, context) + } + + fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + NonFungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::can_check_out(dest, what, context) + } + + fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + NonFungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::check_out(dest, what, context) + } + + fn deposit_asset(what: &MultiAsset, who: &MultiLocation, context: &XcmContext) -> XcmResult { + NonFungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::deposit_asset(what, who, context) + } + + fn withdraw_asset( + what: &MultiAsset, + who: &MultiLocation, + maybe_context: Option<&XcmContext>, + ) -> result::Result { + NonFungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::withdraw_asset(what, who, maybe_context) + } + + fn transfer_asset( + what: &MultiAsset, + from: &MultiLocation, + to: &MultiLocation, + context: &XcmContext, + ) -> result::Result { + NonFungiblesTransferAdapter::::transfer_asset( + what, from, to, context, + ) + } +} diff --git a/polkadot/xcm/xcm-builder/src/origin_aliases.rs b/polkadot/xcm/xcm-builder/src/origin_aliases.rs new file mode 100644 index 0000000000000000000000000000000000000000..82c5f71b7a12955d341cf427e747b001fa83ef96 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/origin_aliases.rs @@ -0,0 +1,38 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implementation for `ContainsPair`. + +use frame_support::traits::{Contains, ContainsPair}; +use sp_std::marker::PhantomData; +use xcm::latest::prelude::*; + +/// Alias a Foreign `AccountId32` with a local `AccountId32` if the foreign `AccountId32` matches +/// the `Prefix` pattern. +/// +/// Requires that the prefixed origin `AccountId32` matches the target `AccountId32`. +pub struct AliasForeignAccountId32(PhantomData); +impl> ContainsPair + for AliasForeignAccountId32 +{ + fn contains(origin: &MultiLocation, target: &MultiLocation) -> bool { + if let (prefix, Some(account_id @ AccountId32 { .. })) = origin.split_last_interior() { + return Prefix::contains(&prefix) && + *target == MultiLocation { parents: 0, interior: X1(account_id) } + } + false + } +} diff --git a/polkadot/xcm/xcm-builder/src/origin_conversion.rs b/polkadot/xcm/xcm-builder/src/origin_conversion.rs new file mode 100644 index 0000000000000000000000000000000000000000..112b26869a998f54f91bf67ab4d4f7b673d92d4d --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/origin_conversion.rs @@ -0,0 +1,345 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Various implementations for `ConvertOrigin`. + +use frame_support::traits::{EnsureOrigin, Get, GetBacking, OriginTrait}; +use frame_system::RawOrigin as SystemRawOrigin; +use polkadot_parachain::primitives::IsSystem; +use sp_runtime::traits::TryConvert; +use sp_std::marker::PhantomData; +use xcm::latest::{BodyId, BodyPart, Junction, Junctions::*, MultiLocation, NetworkId, OriginKind}; +use xcm_executor::traits::{ConvertLocation, ConvertOrigin}; + +/// Sovereign accounts use the system's `Signed` origin with an account ID derived from the +/// `LocationConverter`. +pub struct SovereignSignedViaLocation( + PhantomData<(LocationConverter, RuntimeOrigin)>, +); +impl, RuntimeOrigin: OriginTrait> + ConvertOrigin for SovereignSignedViaLocation +where + RuntimeOrigin::AccountId: Clone, +{ + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + log::trace!( + target: "xcm::origin_conversion", + "SovereignSignedViaLocation origin: {:?}, kind: {:?}", + origin, kind, + ); + if let OriginKind::SovereignAccount = kind { + let location = LocationConverter::convert_location(&origin).ok_or(origin)?; + Ok(RuntimeOrigin::signed(location).into()) + } else { + Err(origin) + } + } +} + +pub struct ParentAsSuperuser(PhantomData); +impl ConvertOrigin for ParentAsSuperuser { + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + log::trace!(target: "xcm::origin_conversion", "ParentAsSuperuser origin: {:?}, kind: {:?}", origin, kind); + if kind == OriginKind::Superuser && origin.contains_parents_only(1) { + Ok(RuntimeOrigin::root()) + } else { + Err(origin) + } + } +} + +pub struct ChildSystemParachainAsSuperuser( + PhantomData<(ParaId, RuntimeOrigin)>, +); +impl, RuntimeOrigin: OriginTrait> ConvertOrigin + for ChildSystemParachainAsSuperuser +{ + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + log::trace!(target: "xcm::origin_conversion", "ChildSystemParachainAsSuperuser origin: {:?}, kind: {:?}", origin, kind); + match (kind, origin) { + ( + OriginKind::Superuser, + MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) }, + ) if ParaId::from(id).is_system() => Ok(RuntimeOrigin::root()), + (_, origin) => Err(origin), + } + } +} + +pub struct SiblingSystemParachainAsSuperuser( + PhantomData<(ParaId, RuntimeOrigin)>, +); +impl, RuntimeOrigin: OriginTrait> ConvertOrigin + for SiblingSystemParachainAsSuperuser +{ + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + log::trace!( + target: "xcm::origin_conversion", + "SiblingSystemParachainAsSuperuser origin: {:?}, kind: {:?}", + origin, kind, + ); + match (kind, origin) { + ( + OriginKind::Superuser, + MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) }, + ) if ParaId::from(id).is_system() => Ok(RuntimeOrigin::root()), + (_, origin) => Err(origin), + } + } +} + +pub struct ChildParachainAsNative( + PhantomData<(ParachainOrigin, RuntimeOrigin)>, +); +impl, RuntimeOrigin: From> ConvertOrigin + for ChildParachainAsNative +{ + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + log::trace!(target: "xcm::origin_conversion", "ChildParachainAsNative origin: {:?}, kind: {:?}", origin, kind); + match (kind, origin) { + ( + OriginKind::Native, + MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) }, + ) => Ok(RuntimeOrigin::from(ParachainOrigin::from(id))), + (_, origin) => Err(origin), + } + } +} + +pub struct SiblingParachainAsNative( + PhantomData<(ParachainOrigin, RuntimeOrigin)>, +); +impl, RuntimeOrigin: From> ConvertOrigin + for SiblingParachainAsNative +{ + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + log::trace!( + target: "xcm::origin_conversion", + "SiblingParachainAsNative origin: {:?}, kind: {:?}", + origin, kind, + ); + match (kind, origin) { + ( + OriginKind::Native, + MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) }, + ) => Ok(RuntimeOrigin::from(ParachainOrigin::from(id))), + (_, origin) => Err(origin), + } + } +} + +// Our Relay-chain has a native origin given by the `Get`ter. +pub struct RelayChainAsNative( + PhantomData<(RelayOrigin, RuntimeOrigin)>, +); +impl, RuntimeOrigin> ConvertOrigin + for RelayChainAsNative +{ + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + log::trace!(target: "xcm::origin_conversion", "RelayChainAsNative origin: {:?}, kind: {:?}", origin, kind); + if kind == OriginKind::Native && origin.contains_parents_only(1) { + Ok(RelayOrigin::get()) + } else { + Err(origin) + } + } +} + +pub struct SignedAccountId32AsNative(PhantomData<(Network, RuntimeOrigin)>); +impl>, RuntimeOrigin: OriginTrait> ConvertOrigin + for SignedAccountId32AsNative +where + RuntimeOrigin::AccountId: From<[u8; 32]>, +{ + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + log::trace!( + target: "xcm::origin_conversion", + "SignedAccountId32AsNative origin: {:?}, kind: {:?}", + origin, kind, + ); + match (kind, origin) { + ( + OriginKind::Native, + MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, network }) }, + ) if matches!(network, None) || network == Network::get() => + Ok(RuntimeOrigin::signed(id.into())), + (_, origin) => Err(origin), + } + } +} + +pub struct SignedAccountKey20AsNative( + PhantomData<(Network, RuntimeOrigin)>, +); +impl>, RuntimeOrigin: OriginTrait> ConvertOrigin + for SignedAccountKey20AsNative +where + RuntimeOrigin::AccountId: From<[u8; 20]>, +{ + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + log::trace!( + target: "xcm::origin_conversion", + "SignedAccountKey20AsNative origin: {:?}, kind: {:?}", + origin, kind, + ); + match (kind, origin) { + ( + OriginKind::Native, + MultiLocation { parents: 0, interior: X1(Junction::AccountKey20 { key, network }) }, + ) if (matches!(network, None) || network == Network::get()) => + Ok(RuntimeOrigin::signed(key.into())), + (_, origin) => Err(origin), + } + } +} + +/// `EnsureOrigin` barrier to convert from dispatch origin to XCM origin, if one exists. +pub struct EnsureXcmOrigin(PhantomData<(RuntimeOrigin, Conversion)>); +impl> + EnsureOrigin for EnsureXcmOrigin +where + RuntimeOrigin::PalletsOrigin: PartialEq, +{ + type Success = MultiLocation; + fn try_origin(o: RuntimeOrigin) -> Result { + let o = match Conversion::try_convert(o) { + Ok(location) => return Ok(location), + Err(o) => o, + }; + // We institute a root fallback so root can always represent the context. This + // guarantees that `successful_origin` will work. + if o.caller() == RuntimeOrigin::root().caller() { + Ok(Here.into()) + } else { + Err(o) + } + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + Ok(RuntimeOrigin::root()) + } +} + +/// `Convert` implementation to convert from some a `Signed` (system) `Origin` into an +/// `AccountId32`. +/// +/// Typically used when configuring `pallet-xcm` for allowing normal accounts to dispatch an XCM +/// from an `AccountId32` origin. +pub struct SignedToAccountId32( + PhantomData<(RuntimeOrigin, AccountId, Network)>, +); +impl< + RuntimeOrigin: OriginTrait + Clone, + AccountId: Into<[u8; 32]>, + Network: Get>, + > TryConvert + for SignedToAccountId32 +where + RuntimeOrigin::PalletsOrigin: From> + + TryInto, Error = RuntimeOrigin::PalletsOrigin>, +{ + fn try_convert(o: RuntimeOrigin) -> Result { + o.try_with_caller(|caller| match caller.try_into() { + Ok(SystemRawOrigin::Signed(who)) => + Ok(Junction::AccountId32 { network: Network::get(), id: who.into() }.into()), + Ok(other) => Err(other.into()), + Err(other) => Err(other), + }) + } +} + +/// `Convert` implementation to convert from some an origin which implements `Backing` into a +/// corresponding `Plurality` `MultiLocation`. +/// +/// Typically used when configuring `pallet-xcm` for allowing a collective's Origin to dispatch an +/// XCM from a `Plurality` origin. +pub struct BackingToPlurality( + PhantomData<(RuntimeOrigin, COrigin, Body)>, +); +impl> + TryConvert for BackingToPlurality +where + RuntimeOrigin::PalletsOrigin: + From + TryInto, +{ + fn try_convert(o: RuntimeOrigin) -> Result { + o.try_with_caller(|caller| match caller.try_into() { + Ok(co) => match co.get_backing() { + Some(backing) => Ok(Junction::Plurality { + id: Body::get(), + part: BodyPart::Fraction { nom: backing.approvals, denom: backing.eligible }, + } + .into()), + None => Err(co.into()), + }, + Err(other) => Err(other), + }) + } +} + +/// `Convert` implementation to convert from an origin which passes the check of an `EnsureOrigin` +/// into a voice of a given pluralistic `Body`. +pub struct OriginToPluralityVoice( + PhantomData<(RuntimeOrigin, EnsureBodyOrigin, Body)>, +); +impl, Body: Get> + TryConvert + for OriginToPluralityVoice +{ + fn try_convert(o: RuntimeOrigin) -> Result { + match EnsureBodyOrigin::try_origin(o) { + Ok(_) => Ok(Junction::Plurality { id: Body::get(), part: BodyPart::Voice }.into()), + Err(o) => Err(o), + } + } +} diff --git a/polkadot/xcm/xcm-builder/src/pay.rs b/polkadot/xcm/xcm-builder/src/pay.rs new file mode 100644 index 0000000000000000000000000000000000000000..e36d26e425be3d0981e80ff93127e07a9c522805 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/pay.rs @@ -0,0 +1,205 @@ +// Copyright Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! `PayOverXcm` struct for paying through XCM and getting the status back. + +use frame_support::traits::{ + tokens::{Pay, PaymentStatus}, + Get, +}; +use sp_runtime::traits::Convert; +use sp_std::{marker::PhantomData, vec}; +use xcm::{opaque::lts::Weight, prelude::*}; +use xcm_executor::traits::{QueryHandler, QueryResponseStatus}; + +/// Implementation of the `frame_support::traits::tokens::Pay` trait, to allow +/// for XCM-based payments of a given `Balance` of some asset ID existing on some chain under +/// ownership of some `Interior` location of the local chain to a particular `Beneficiary`. The +/// `AssetKind` value is not itself bounded (to avoid the issue of needing to wrap some preexisting +/// datatype), however a converter type `AssetKindToLocatableAsset` must be provided in order to +/// translate it into a `LocatableAsset`, which comprises both an XCM `MultiLocation` describing +/// the XCM endpoint on which the asset to be paid resides and an XCM `AssetId` to identify the +/// specific asset at that endpoint. +/// +/// This relies on the XCM `TransferAsset` instruction. A trait `BeneficiaryRefToLocation` must be +/// provided in order to convert the `Beneficiary` reference into a location usable by +/// `TransferAsset`. +/// +/// `PayOverXcm::pay` is asynchronous, and returns a `QueryId` which can then be used in +/// `check_payment` to check the status of the XCM transaction. +/// +/// See also `PayAccountId32OverXcm` which is similar to this except that `BeneficiaryRefToLocation` +/// need not be supplied and `Beneficiary` must implement `Into<[u8; 32]>`. +pub struct PayOverXcm< + Interior, + Router, + Querier, + Timeout, + Beneficiary, + AssetKind, + AssetKindToLocatableAsset, + BeneficiaryRefToLocation, +>( + PhantomData<( + Interior, + Router, + Querier, + Timeout, + Beneficiary, + AssetKind, + AssetKindToLocatableAsset, + BeneficiaryRefToLocation, + )>, +); +impl< + Interior: Get, + Router: SendXcm, + Querier: QueryHandler, + Timeout: Get, + Beneficiary: Clone, + AssetKind, + AssetKindToLocatableAsset: Convert, + BeneficiaryRefToLocation: for<'a> Convert<&'a Beneficiary, MultiLocation>, + > Pay + for PayOverXcm< + Interior, + Router, + Querier, + Timeout, + Beneficiary, + AssetKind, + AssetKindToLocatableAsset, + BeneficiaryRefToLocation, + > +{ + type Beneficiary = Beneficiary; + type AssetKind = AssetKind; + type Balance = u128; + type Id = Querier::QueryId; + type Error = xcm::latest::Error; + + fn pay( + who: &Self::Beneficiary, + asset_kind: Self::AssetKind, + amount: Self::Balance, + ) -> Result { + let locatable = AssetKindToLocatableAsset::convert(asset_kind); + let LocatableAssetId { asset_id, location: asset_location } = locatable; + let destination = Querier::UniversalLocation::get() + .invert_target(&asset_location) + .map_err(|()| Self::Error::LocationNotInvertible)?; + let beneficiary = BeneficiaryRefToLocation::convert(&who); + + let query_id = Querier::new_query(asset_location, Timeout::get(), Interior::get()); + + let message = Xcm(vec![ + DescendOrigin(Interior::get()), + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + SetAppendix(Xcm(vec![ReportError(QueryResponseInfo { + destination, + query_id, + max_weight: Weight::zero(), + })])), + TransferAsset { + beneficiary, + assets: vec![MultiAsset { id: asset_id, fun: Fungibility::Fungible(amount) }] + .into(), + }, + ]); + + let (ticket, _) = Router::validate(&mut Some(asset_location), &mut Some(message))?; + Router::deliver(ticket)?; + Ok(query_id.into()) + } + + fn check_payment(id: Self::Id) -> PaymentStatus { + use QueryResponseStatus::*; + match Querier::take_response(id) { + Ready { response, .. } => match response { + Response::ExecutionResult(None) => PaymentStatus::Success, + Response::ExecutionResult(Some(_)) => PaymentStatus::Failure, + _ => PaymentStatus::Unknown, + }, + Pending { .. } => PaymentStatus::InProgress, + NotFound | UnexpectedVersion => PaymentStatus::Unknown, + } + } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful(_: &Self::Beneficiary, _: Self::AssetKind, _: Self::Balance) { + // We cannot generally guarantee this will go through successfully since we don't have any + // control over the XCM transport layers. We just assume that the benchmark environment + // will be sending it somewhere sensible. + } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_concluded(id: Self::Id) { + Querier::expect_response(id, Response::ExecutionResult(None)); + } +} + +/// Specialization of the [`PayOverXcm`] trait to allow `[u8; 32]`-based `AccountId` values to be +/// paid on a remote chain. +/// +/// Implementation of the [`frame_support::traits::tokens::Pay`] trait, to allow +/// for XCM payments of a given `Balance` of `AssetKind` existing on a `DestinationChain` under +/// ownership of some `Interior` location of the local chain to a particular `Beneficiary`. +/// +/// This relies on the XCM `TransferAsset` instruction. `Beneficiary` must implement +/// `Into<[u8; 32]>` (as 32-byte `AccountId`s generally do), and the actual XCM beneficiary will be +/// the location consisting of a single `AccountId32` junction with an appropriate account and no +/// specific network. +/// +/// `PayOverXcm::pay` is asynchronous, and returns a `QueryId` which can then be used in +/// `check_payment` to check the status of the XCM transaction. +pub type PayAccountId32OnChainOverXcm< + DestinationChain, + Interior, + Router, + Querier, + Timeout, + Beneficiary, + AssetKind, +> = PayOverXcm< + Interior, + Router, + Querier, + Timeout, + Beneficiary, + AssetKind, + crate::AliasesIntoAccountId32<(), Beneficiary>, + FixedLocation, +>; + +/// Simple struct which contains both an XCM `location` and `asset_id` to identify an asset which +/// exists on some chain. +pub struct LocatableAssetId { + /// The asset's ID. + pub asset_id: AssetId, + /// The (relative) location in which the asset ID is meaningful. + pub location: MultiLocation, +} + +/// Adapter `struct` which implements a conversion from any `AssetKind` into a [`LocatableAsset`] +/// value using a fixed `Location` for the `location` field. +pub struct FixedLocation(sp_std::marker::PhantomData); +impl, AssetKind: Into> Convert + for FixedLocation +{ + fn convert(value: AssetKind) -> LocatableAssetId { + LocatableAssetId { asset_id: value.into(), location: Location::get() } + } +} diff --git a/polkadot/xcm/xcm-builder/src/process_xcm_message.rs b/polkadot/xcm/xcm-builder/src/process_xcm_message.rs new file mode 100644 index 0000000000000000000000000000000000000000..8130d1732935da4629b71d2421c00bdb9d5e5b9c --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/process_xcm_message.rs @@ -0,0 +1,155 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Implementation of `ProcessMessage` for an `ExecuteXcm` implementation. + +use frame_support::{ + ensure, + traits::{ProcessMessage, ProcessMessageError}, +}; +use parity_scale_codec::{Decode, FullCodec, MaxEncodedLen}; +use scale_info::TypeInfo; +use sp_std::{fmt::Debug, marker::PhantomData}; +use sp_weights::{Weight, WeightMeter}; +use xcm::prelude::*; + +/// A message processor that delegates execution to an [`XcmExecutor`]. +pub struct ProcessXcmMessage( + PhantomData<(MessageOrigin, XcmExecutor, Call)>, +); +impl< + MessageOrigin: Into + FullCodec + MaxEncodedLen + Clone + Eq + PartialEq + TypeInfo + Debug, + XcmExecutor: ExecuteXcm, + Call, + > ProcessMessage for ProcessXcmMessage +{ + type Origin = MessageOrigin; + + /// Process the given message, using no more than the remaining `weight` to do so. + fn process_message( + message: &[u8], + origin: Self::Origin, + meter: &mut WeightMeter, + id: &mut XcmHash, + ) -> Result { + let versioned_message = VersionedXcm::::decode(&mut &message[..]) + .map_err(|_| ProcessMessageError::Corrupt)?; + let message = Xcm::::try_from(versioned_message) + .map_err(|_| ProcessMessageError::Unsupported)?; + let pre = XcmExecutor::prepare(message).map_err(|_| ProcessMessageError::Unsupported)?; + let required = pre.weight_of(); + ensure!(meter.can_consume(required), ProcessMessageError::Overweight(required)); + + let (consumed, result) = match XcmExecutor::execute(origin.into(), pre, id, Weight::zero()) + { + Outcome::Complete(w) => (w, Ok(true)), + Outcome::Incomplete(w, _) => (w, Ok(false)), + // In the error-case we assume the worst case and consume all possible weight. + Outcome::Error(_) => (required, Err(ProcessMessageError::Unsupported)), + }; + meter.consume(consumed); + result + } +} + +#[cfg(test)] +mod tests { + use super::*; + use frame_support::{ + assert_err, assert_ok, + traits::{ProcessMessageError, ProcessMessageError::*}, + }; + use parity_scale_codec::Encode; + use polkadot_test_runtime::*; + use xcm::{v2, v3, VersionedXcm}; + + const ORIGIN: Junction = Junction::OnlyChild; + /// The processor to use for tests. + type Processor = + ProcessXcmMessage, RuntimeCall>; + + #[test] + fn process_message_trivial_works() { + // ClearOrigin works. + assert!(process(v2_xcm(true)).unwrap()); + assert!(process(v3_xcm(true)).unwrap()); + } + + #[test] + fn process_message_trivial_fails() { + // Trap makes it fail. + assert!(!process(v3_xcm(false)).unwrap()); + assert!(!process(v3_xcm(false)).unwrap()); + } + + #[test] + fn process_message_corrupted_fails() { + let msgs: &[&[u8]] = &[&[], &[55, 66], &[123, 222, 233]]; + for msg in msgs { + assert_err!(process_raw(msg), Corrupt); + } + } + + #[test] + fn process_message_overweight_fails() { + for msg in [v3_xcm(true), v3_xcm(false), v3_xcm(false), v2_xcm(false)] { + let msg = &msg.encode()[..]; + + // Errors if we stay below a weight limit of 1000. + for i in 0..10 { + let meter = &mut WeightMeter::from_limit((i * 10).into()); + let mut id = [0; 32]; + assert_err!( + Processor::process_message(msg, ORIGIN, meter, &mut id), + Overweight(1000.into()) + ); + assert_eq!(meter.consumed(), 0.into()); + } + + // Works with a limit of 1000. + let meter = &mut WeightMeter::from_limit(1000.into()); + let mut id = [0; 32]; + assert_ok!(Processor::process_message(msg, ORIGIN, meter, &mut id)); + assert_eq!(meter.consumed(), 1000.into()); + } + } + + fn v2_xcm(success: bool) -> VersionedXcm { + let instr = if success { + v3::Instruction::::ClearOrigin + } else { + v3::Instruction::::Trap(1) + }; + VersionedXcm::V3(v3::Xcm::(vec![instr])) + } + + fn v3_xcm(success: bool) -> VersionedXcm { + let instr = if success { + v2::Instruction::::ClearOrigin + } else { + v2::Instruction::::Trap(1) + }; + VersionedXcm::V2(v2::Xcm::(vec![instr])) + } + + fn process(msg: VersionedXcm) -> Result { + process_raw(msg.encode().as_slice()) + } + + fn process_raw(raw: &[u8]) -> Result { + Processor::process_message(raw, ORIGIN, &mut WeightMeter::max_limit(), &mut [0; 32]) + } +} diff --git a/polkadot/xcm/xcm-builder/src/routing.rs b/polkadot/xcm/xcm-builder/src/routing.rs new file mode 100644 index 0000000000000000000000000000000000000000..39e9eab410bf14106b8817a8c2944cd0f5081f36 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/routing.rs @@ -0,0 +1,107 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Various implementations for `SendXcm`. + +use frame_system::unique; +use parity_scale_codec::Encode; +use sp_std::{marker::PhantomData, result::Result}; +use xcm::prelude::*; + +/// Wrapper router which, if the message does not already end with a `SetTopic` instruction, +/// appends one to the message filled with a universally unique ID. This ID is returned from a +/// successful `deliver`. +/// +/// If the message does already end with a `SetTopic` instruction, then it is the responsibility +/// of the code author to ensure that the ID supplied to `SetTopic` is universally unique. Due to +/// this property, consumers of the topic ID must be aware that a user-supplied ID may not be +/// unique. +/// +/// This is designed to be at the top-level of any routers, since it will always mutate the +/// passed `message` reference into a `None`. Don't try to combine it within a tuple except as the +/// last element. +pub struct WithUniqueTopic(PhantomData); +impl SendXcm for WithUniqueTopic { + type Ticket = (Inner::Ticket, [u8; 32]); + + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { + let mut message = message.take().ok_or(SendError::MissingArgument)?; + let unique_id = if let Some(SetTopic(id)) = message.last() { + *id + } else { + let unique_id = unique(&message); + message.0.push(SetTopic(unique_id)); + unique_id + }; + let (ticket, assets) = Inner::validate(destination, &mut Some(message)) + .map_err(|_| SendError::NotApplicable)?; + Ok(((ticket, unique_id), assets)) + } + + fn deliver(ticket: Self::Ticket) -> Result { + let (ticket, unique_id) = ticket; + Inner::deliver(ticket)?; + Ok(unique_id) + } +} + +pub trait SourceTopic { + fn source_topic(entropy: impl Encode) -> XcmHash; +} + +impl SourceTopic for () { + fn source_topic(_: impl Encode) -> XcmHash { + [0u8; 32] + } +} + +/// Wrapper router which, if the message does not already end with a `SetTopic` instruction, +/// prepends one to the message filled with an ID from `TopicSource`. This ID is returned from a +/// successful `deliver`. +/// +/// This is designed to be at the top-level of any routers, since it will always mutate the +/// passed `message` reference into a `None`. Don't try to combine it within a tuple except as the +/// last element. +pub struct WithTopicSource(PhantomData<(Inner, TopicSource)>); +impl SendXcm for WithTopicSource { + type Ticket = (Inner::Ticket, [u8; 32]); + + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { + let mut message = message.take().ok_or(SendError::MissingArgument)?; + let unique_id = if let Some(SetTopic(id)) = message.last() { + *id + } else { + let unique_id = TopicSource::source_topic(&message); + message.0.push(SetTopic(unique_id)); + unique_id + }; + let (ticket, assets) = Inner::validate(destination, &mut Some(message)) + .map_err(|_| SendError::NotApplicable)?; + Ok(((ticket, unique_id), assets)) + } + + fn deliver(ticket: Self::Ticket) -> Result { + let (ticket, unique_id) = ticket; + Inner::deliver(ticket)?; + Ok(unique_id) + } +} diff --git a/polkadot/xcm/xcm-builder/src/test_utils.rs b/polkadot/xcm/xcm-builder/src/test_utils.rs new file mode 100644 index 0000000000000000000000000000000000000000..d0f867ba62d6af0f642600c8b6aeabc0b9fbcf08 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/test_utils.rs @@ -0,0 +1,216 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +// Shared test utilities and implementations for the XCM Builder. + +use frame_support::{ + parameter_types, + traits::{Contains, CrateVersion, PalletInfoData, PalletsInfoAccess}, +}; +use sp_std::vec::Vec; +pub use xcm::latest::{prelude::*, Weight}; +use xcm_executor::traits::{ClaimAssets, DropAssets, VersionChangeNotifier}; +pub use xcm_executor::{ + traits::{ + AssetExchange, AssetLock, ConvertOrigin, Enact, LockError, OnResponse, TransactAsset, + }, + Assets, Config, +}; + +parameter_types! { + pub static SubscriptionRequests: Vec<(MultiLocation, Option<(QueryId, Weight)>)> = vec![]; + pub static MaxAssetsIntoHolding: u32 = 4; +} + +pub struct TestSubscriptionService; + +impl VersionChangeNotifier for TestSubscriptionService { + fn start( + location: &MultiLocation, + query_id: QueryId, + max_weight: Weight, + _context: &XcmContext, + ) -> XcmResult { + let mut r = SubscriptionRequests::get(); + r.push((*location, Some((query_id, max_weight)))); + SubscriptionRequests::set(r); + Ok(()) + } + fn stop(location: &MultiLocation, _context: &XcmContext) -> XcmResult { + let mut r = SubscriptionRequests::get(); + r.retain(|(l, _q)| l != location); + r.push((*location, None)); + SubscriptionRequests::set(r); + Ok(()) + } + fn is_subscribed(location: &MultiLocation) -> bool { + let r = SubscriptionRequests::get(); + r.iter().any(|(l, q)| l == location && q.is_some()) + } +} + +parameter_types! { + pub static TrappedAssets: Vec<(MultiLocation, MultiAssets)> = vec![]; +} + +pub struct TestAssetTrap; + +impl DropAssets for TestAssetTrap { + fn drop_assets(origin: &MultiLocation, assets: Assets, _context: &XcmContext) -> Weight { + let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get(); + t.push((*origin, assets.into())); + TrappedAssets::set(t); + Weight::from_parts(5, 5) + } +} + +impl ClaimAssets for TestAssetTrap { + fn claim_assets( + origin: &MultiLocation, + ticket: &MultiLocation, + what: &MultiAssets, + _context: &XcmContext, + ) -> bool { + let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get(); + if let (0, X1(GeneralIndex(i))) = (ticket.parents, &ticket.interior) { + if let Some((l, a)) = t.get(*i as usize) { + if l == origin && a == what { + t.swap_remove(*i as usize); + TrappedAssets::set(t); + return true + } + } + } + false + } +} + +pub struct TestAssetExchanger; + +impl AssetExchange for TestAssetExchanger { + fn exchange_asset( + _origin: Option<&MultiLocation>, + _give: Assets, + want: &MultiAssets, + _maximal: bool, + ) -> Result { + Ok(want.clone().into()) + } +} + +pub struct TestPalletsInfo; +impl PalletsInfoAccess for TestPalletsInfo { + fn count() -> usize { + 2 + } + fn infos() -> Vec { + vec![ + PalletInfoData { + index: 0, + name: "System", + module_name: "pallet_system", + crate_version: CrateVersion { major: 1, minor: 10, patch: 1 }, + }, + PalletInfoData { + index: 1, + name: "Balances", + module_name: "pallet_balances", + crate_version: CrateVersion { major: 1, minor: 42, patch: 69 }, + }, + ] + } +} + +pub struct TestUniversalAliases; +impl Contains<(MultiLocation, Junction)> for TestUniversalAliases { + fn contains(aliases: &(MultiLocation, Junction)) -> bool { + &aliases.0 == &Here.into_location() && &aliases.1 == &GlobalConsensus(ByGenesis([0; 32])) + } +} + +parameter_types! { + pub static LockedAssets: Vec<(MultiLocation, MultiAsset)> = vec![]; +} + +pub struct TestLockTicket(MultiLocation, MultiAsset); +impl Enact for TestLockTicket { + fn enact(self) -> Result<(), LockError> { + let mut locked_assets = LockedAssets::get(); + locked_assets.push((self.0, self.1)); + LockedAssets::set(locked_assets); + Ok(()) + } +} +pub struct TestUnlockTicket(MultiLocation, MultiAsset); +impl Enact for TestUnlockTicket { + fn enact(self) -> Result<(), LockError> { + let mut locked_assets = LockedAssets::get(); + if let Some((idx, _)) = locked_assets + .iter() + .enumerate() + .find(|(_, (origin, asset))| origin == &self.0 && asset == &self.1) + { + locked_assets.remove(idx); + } + LockedAssets::set(locked_assets); + Ok(()) + } +} +pub struct TestReduceTicket; +impl Enact for TestReduceTicket { + fn enact(self) -> Result<(), LockError> { + Ok(()) + } +} + +pub struct TestAssetLocker; +impl AssetLock for TestAssetLocker { + type LockTicket = TestLockTicket; + type UnlockTicket = TestUnlockTicket; + type ReduceTicket = TestReduceTicket; + + fn prepare_lock( + unlocker: MultiLocation, + asset: MultiAsset, + _owner: MultiLocation, + ) -> Result { + Ok(TestLockTicket(unlocker, asset)) + } + + fn prepare_unlock( + unlocker: MultiLocation, + asset: MultiAsset, + _owner: MultiLocation, + ) -> Result { + Ok(TestUnlockTicket(unlocker, asset)) + } + + fn note_unlockable( + _locker: MultiLocation, + _asset: MultiAsset, + _owner: MultiLocation, + ) -> Result<(), LockError> { + Ok(()) + } + + fn prepare_reduce_unlockable( + _locker: MultiLocation, + _asset: MultiAsset, + _owner: MultiLocation, + ) -> Result { + Ok(TestReduceTicket) + } +} diff --git a/polkadot/xcm/xcm-builder/src/tests/aliases.rs b/polkadot/xcm/xcm-builder/src/tests/aliases.rs new file mode 100644 index 0000000000000000000000000000000000000000..f686926a2522fab1e1564b5ed88161ffb7558734 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/aliases.rs @@ -0,0 +1,85 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +#[test] +fn alias_foreign_account_sibling_prefix() { + // Accounts Differ + assert!(!AliasForeignAccountId32::::contains( + &(Parent, Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(), + &(AccountId32 { network: None, id: [1; 32] }).into() + )); + + assert!(AliasForeignAccountId32::::contains( + &(Parent, Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(), + &(AccountId32 { network: None, id: [0; 32] }).into() + )); +} + +#[test] +fn alias_foreign_account_child_prefix() { + // Accounts Differ + assert!(!AliasForeignAccountId32::::contains( + &(Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(), + &(AccountId32 { network: None, id: [1; 32] }).into() + )); + + assert!(AliasForeignAccountId32::::contains( + &(Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(), + &(AccountId32 { network: None, id: [0; 32] }).into() + )); +} + +#[test] +fn alias_foreign_account_parent_prefix() { + // Accounts Differ + assert!(!AliasForeignAccountId32::::contains( + &(Parent, AccountId32 { network: None, id: [0; 32] }).into(), + &(AccountId32 { network: None, id: [1; 32] }).into() + )); + + assert!(AliasForeignAccountId32::::contains( + &(Parent, AccountId32 { network: None, id: [0; 32] }).into(), + &(AccountId32 { network: None, id: [0; 32] }).into() + )); +} + +#[test] +fn alias_origin_should_work() { + AllowUnpaidFrom::set(vec![ + (Parent, Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(), + (Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(), + ]); + + let message = Xcm(vec![AliasOrigin((AccountId32 { network: None, id: [0; 32] }).into())]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + (Parachain(1), AccountId32 { network: None, id: [0; 32] }), + message.clone(), + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NoPermission)); + + let r = XcmExecutor::::execute_xcm( + (Parent, Parachain(1), AccountId32 { network: None, id: [0; 32] }), + message.clone(), + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/assets.rs b/polkadot/xcm/xcm-builder/src/tests/assets.rs new file mode 100644 index 0000000000000000000000000000000000000000..e1d61a9d1c6daccf729318db6445e30e7bcf774d --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/assets.rs @@ -0,0 +1,467 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +#[test] +fn exchange_asset_should_work() { + AllowUnpaidFrom::set(vec![Parent.into()]); + add_asset(Parent, (Parent, 1000u128)); + set_exchange_assets(vec![(Here, 100u128).into()]); + let message = Xcm(vec![ + WithdrawAsset((Parent, 100u128).into()), + SetAppendix( + vec![DepositAsset { assets: AllCounted(2).into(), beneficiary: Parent.into() }].into(), + ), + ExchangeAsset { + give: Definite((Parent, 50u128).into()), + want: (Here, 50u128).into(), + maximal: true, + }, + ]); + let hash = fake_message_hash(&message); + let r = + XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); + assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + assert_eq!(asset_list(Parent), vec![(Here, 100u128).into(), (Parent, 950u128).into()]); + assert_eq!(exchange_assets(), vec![(Parent, 50u128).into()].into()); +} + +#[test] +fn exchange_asset_without_maximal_should_work() { + AllowUnpaidFrom::set(vec![Parent.into()]); + add_asset(Parent, (Parent, 1000u128)); + set_exchange_assets(vec![(Here, 100u128).into()]); + let message = Xcm(vec![ + WithdrawAsset((Parent, 100u128).into()), + SetAppendix( + vec![DepositAsset { assets: AllCounted(2).into(), beneficiary: Parent.into() }].into(), + ), + ExchangeAsset { + give: Definite((Parent, 50).into()), + want: (Here, 50u128).into(), + maximal: false, + }, + ]); + let hash = fake_message_hash(&message); + let r = + XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); + assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + assert_eq!(asset_list(Parent), vec![(Here, 50u128).into(), (Parent, 950u128).into()]); + assert_eq!(exchange_assets(), vec![(Here, 50u128).into(), (Parent, 50u128).into()].into()); +} + +#[test] +fn exchange_asset_should_fail_when_no_deal_possible() { + AllowUnpaidFrom::set(vec![Parent.into()]); + add_asset(Parent, (Parent, 1000u128)); + set_exchange_assets(vec![(Here, 100u128).into()]); + let message = Xcm(vec![ + WithdrawAsset((Parent, 150u128).into()), + SetAppendix( + vec![DepositAsset { assets: AllCounted(2).into(), beneficiary: Parent.into() }].into(), + ), + ExchangeAsset { + give: Definite((Parent, 150u128).into()), + want: (Here, 150u128).into(), + maximal: false, + }, + ]); + let hash = fake_message_hash(&message); + let r = + XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(40, 40), XcmError::NoDeal)); + assert_eq!(asset_list(Parent), vec![(Parent, 1000u128).into()]); + assert_eq!(exchange_assets(), vec![(Here, 100u128).into()].into()); +} + +#[test] +fn paying_reserve_deposit_should_work() { + AllowPaidFrom::set(vec![Parent.into()]); + add_reserve(Parent.into(), (Parent, WildFungible).into()); + WeightPrice::set((Parent.into(), 1_000_000_000_000, 1024 * 1024)); + + let fees = (Parent, 60u128).into(); + let message = Xcm(vec![ + ReserveAssetDeposited((Parent, 100u128).into()), + BuyExecution { fees, weight_limit: Limited(Weight::from_parts(30, 30)) }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: Here.into() }, + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(50, 50); + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + assert_eq!(asset_list(Here), vec![(Parent, 40u128).into()]); +} + +#[test] +fn transfer_should_work() { + // we'll let them have message execution for free. + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + // Child parachain #1 owns 1000 tokens held by us in reserve. + add_asset(Parachain(1), (Here, 1000)); + // They want to transfer 100 of them to their sibling parachain #2 + let message = Xcm(vec![TransferAsset { + assets: (Here, 100u128).into(), + beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!( + asset_list(AccountIndex64 { index: 3, network: None }), + vec![(Here, 100u128).into()] + ); + assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); + assert_eq!(sent_xcm(), vec![]); +} + +#[test] +fn reserve_transfer_should_work() { + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + // Child parachain #1 owns 1000 tokens held by us in reserve. + add_asset(Parachain(1), (Here, 1000)); + // The remote account owned by gav. + let three: MultiLocation = X1(AccountIndex64 { index: 3, network: None }).into(); + + // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 + // and let them know to hand it to account #3. + let message = Xcm(vec![TransferReserveAsset { + assets: (Here, 100u128).into(), + dest: Parachain(2).into(), + xcm: Xcm::<()>(vec![DepositAsset { assets: AllCounted(1).into(), beneficiary: three }]), + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + + let expected_msg = Xcm::<()>(vec![ + ReserveAssetDeposited((Parent, 100u128).into()), + ClearOrigin, + DepositAsset { assets: AllCounted(1).into(), beneficiary: three }, + ]); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!(asset_list(Parachain(2)), vec![(Here, 100).into()]); + assert_eq!(sent_xcm(), vec![(Parachain(2).into(), expected_msg, expected_hash)]); +} + +#[test] +fn burn_should_work() { + // we'll let them have message execution for free. + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + // Child parachain #1 owns 1000 tokens held by us in reserve. + add_asset(Parachain(1), (Here, 1000)); + // They want to burn 100 of them + let message = Xcm(vec![ + WithdrawAsset((Here, 1000u128).into()), + BurnAsset((Here, 100u128).into()), + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Parachain(1).into() }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); + assert_eq!(sent_xcm(), vec![]); + + // Now they want to burn 1000 of them, which will actually only burn 900. + let message = Xcm(vec![ + WithdrawAsset((Here, 900u128).into()), + BurnAsset((Here, 1000u128).into()), + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Parachain(1).into() }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + assert_eq!(asset_list(Parachain(1)), vec![]); + assert_eq!(sent_xcm(), vec![]); +} + +#[test] +fn basic_asset_trap_should_work() { + // we'll let them have message execution for free. + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into(), X1(Parachain(2)).into()]); + + // Child parachain #1 owns 1000 tokens held by us in reserve. + add_asset(Parachain(1), (Here, 1000)); + // They want to transfer 100 of them to their sibling parachain #2 but have a problem + let message = Xcm(vec![ + WithdrawAsset((Here, 100u128).into()), + DepositAsset { + assets: Wild(AllCounted(0)), // <<< 0 is an error. + beneficiary: AccountIndex64 { index: 3, network: None }.into(), + }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(20, 20), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(25, 25))); + assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); + assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); + + // Incorrect ticket doesn't work. + let message = Xcm(vec![ + ClaimAsset { assets: (Here, 100u128).into(), ticket: GeneralIndex(1).into() }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: AccountIndex64 { index: 3, network: None }.into(), + }, + ]); + let hash = fake_message_hash(&message); + let old_trapped_assets = TrappedAssets::get(); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(20, 20), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); + assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); + assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); + assert_eq!(old_trapped_assets, TrappedAssets::get()); + + // Incorrect origin doesn't work. + let message = Xcm(vec![ + ClaimAsset { assets: (Here, 100u128).into(), ticket: GeneralIndex(0).into() }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: AccountIndex64 { index: 3, network: None }.into(), + }, + ]); + let hash = fake_message_hash(&message); + let old_trapped_assets = TrappedAssets::get(); + let r = XcmExecutor::::execute_xcm( + Parachain(2), + message, + hash, + Weight::from_parts(20, 20), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); + assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); + assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); + assert_eq!(old_trapped_assets, TrappedAssets::get()); + + // Incorrect assets doesn't work. + let message = Xcm(vec![ + ClaimAsset { assets: (Here, 101u128).into(), ticket: GeneralIndex(0).into() }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: AccountIndex64 { index: 3, network: None }.into(), + }, + ]); + let hash = fake_message_hash(&message); + let old_trapped_assets = TrappedAssets::get(); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(20, 20), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); + assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); + assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); + assert_eq!(old_trapped_assets, TrappedAssets::get()); + + let message = Xcm(vec![ + ClaimAsset { assets: (Here, 100u128).into(), ticket: GeneralIndex(0).into() }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: AccountIndex64 { index: 3, network: None }.into(), + }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(20, 20), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); + assert_eq!( + asset_list(AccountIndex64 { index: 3, network: None }), + vec![(Here, 100u128).into()] + ); + + // Same again doesn't work :-) + let message = Xcm(vec![ + ClaimAsset { assets: (Here, 100u128).into(), ticket: GeneralIndex(0).into() }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: AccountIndex64 { index: 3, network: None }.into(), + }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(20, 20), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); +} + +#[test] +fn max_assets_limit_should_work() { + // we'll let them have message execution for free. + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + // Child parachain #1 owns 1000 tokens held by us in reserve. + add_asset(Parachain(1), ([1u8; 32], 1000u128)); + add_asset(Parachain(1), ([2u8; 32], 1000u128)); + add_asset(Parachain(1), ([3u8; 32], 1000u128)); + add_asset(Parachain(1), ([4u8; 32], 1000u128)); + add_asset(Parachain(1), ([5u8; 32], 1000u128)); + add_asset(Parachain(1), ([6u8; 32], 1000u128)); + add_asset(Parachain(1), ([7u8; 32], 1000u128)); + add_asset(Parachain(1), ([8u8; 32], 1000u128)); + add_asset(Parachain(1), ([9u8; 32], 1000u128)); + + // Attempt to withdraw 8 (=2x4)different assets. This will succeed. + let message = Xcm(vec![ + WithdrawAsset(([1u8; 32], 100u128).into()), + WithdrawAsset(([2u8; 32], 100u128).into()), + WithdrawAsset(([3u8; 32], 100u128).into()), + WithdrawAsset(([4u8; 32], 100u128).into()), + WithdrawAsset(([5u8; 32], 100u128).into()), + WithdrawAsset(([6u8; 32], 100u128).into()), + WithdrawAsset(([7u8; 32], 100u128).into()), + WithdrawAsset(([8u8; 32], 100u128).into()), + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(100, 100), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(85, 85))); + + // Attempt to withdraw 9 different assets will fail. + let message = Xcm(vec![ + WithdrawAsset(([1u8; 32], 100u128).into()), + WithdrawAsset(([2u8; 32], 100u128).into()), + WithdrawAsset(([3u8; 32], 100u128).into()), + WithdrawAsset(([4u8; 32], 100u128).into()), + WithdrawAsset(([5u8; 32], 100u128).into()), + WithdrawAsset(([6u8; 32], 100u128).into()), + WithdrawAsset(([7u8; 32], 100u128).into()), + WithdrawAsset(([8u8; 32], 100u128).into()), + WithdrawAsset(([9u8; 32], 100u128).into()), + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(100, 100), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(95, 95), XcmError::HoldingWouldOverflow)); + + // Attempt to withdraw 4 different assets and then the same 4 and then a different 4 will + // succeed. + let message = Xcm(vec![ + WithdrawAsset(([1u8; 32], 100u128).into()), + WithdrawAsset(([2u8; 32], 100u128).into()), + WithdrawAsset(([3u8; 32], 100u128).into()), + WithdrawAsset(([4u8; 32], 100u128).into()), + WithdrawAsset(([1u8; 32], 100u128).into()), + WithdrawAsset(([2u8; 32], 100u128).into()), + WithdrawAsset(([3u8; 32], 100u128).into()), + WithdrawAsset(([4u8; 32], 100u128).into()), + WithdrawAsset(([5u8; 32], 100u128).into()), + WithdrawAsset(([6u8; 32], 100u128).into()), + WithdrawAsset(([7u8; 32], 100u128).into()), + WithdrawAsset(([8u8; 32], 100u128).into()), + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(200, 200), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(125, 125))); + + // Attempt to withdraw 4 different assets and then a different 4 and then the same 4 will fail. + let message = Xcm(vec![ + WithdrawAsset(([1u8; 32], 100u128).into()), + WithdrawAsset(([2u8; 32], 100u128).into()), + WithdrawAsset(([3u8; 32], 100u128).into()), + WithdrawAsset(([4u8; 32], 100u128).into()), + WithdrawAsset(([5u8; 32], 100u128).into()), + WithdrawAsset(([6u8; 32], 100u128).into()), + WithdrawAsset(([7u8; 32], 100u128).into()), + WithdrawAsset(([8u8; 32], 100u128).into()), + WithdrawAsset(([1u8; 32], 100u128).into()), + WithdrawAsset(([2u8; 32], 100u128).into()), + WithdrawAsset(([3u8; 32], 100u128).into()), + WithdrawAsset(([4u8; 32], 100u128).into()), + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(200, 200), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(95, 95), XcmError::HoldingWouldOverflow)); + + // Attempt to withdraw 4 different assets and then a different 4 and then the same 4 will fail. + let message = Xcm(vec![ + WithdrawAsset(MultiAssets::from(vec![ + ([1u8; 32], 100u128).into(), + ([2u8; 32], 100u128).into(), + ([3u8; 32], 100u128).into(), + ([4u8; 32], 100u128).into(), + ([5u8; 32], 100u128).into(), + ([6u8; 32], 100u128).into(), + ([7u8; 32], 100u128).into(), + ([8u8; 32], 100u128).into(), + ])), + WithdrawAsset(([1u8; 32], 100u128).into()), + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(200, 200), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(25, 25), XcmError::HoldingWouldOverflow)); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/barriers.rs b/polkadot/xcm/xcm-builder/src/tests/barriers.rs new file mode 100644 index 0000000000000000000000000000000000000000..99a9dd5a6609fe59e5e5ac6af073d8031c41c14c --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/barriers.rs @@ -0,0 +1,311 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use xcm_executor::traits::Properties; + +use super::*; + +fn props(weight_credit: Weight) -> Properties { + Properties { weight_credit, message_id: None } +} + +#[test] +fn take_weight_credit_barrier_should_work() { + let mut message = + Xcm::<()>(vec![TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() }]); + let mut properties = props(Weight::from_parts(10, 10)); + let r = TakeWeightCredit::should_execute( + &Parent.into(), + message.inner_mut(), + Weight::from_parts(10, 10), + &mut properties, + ); + assert_eq!(r, Ok(())); + assert_eq!(properties.weight_credit, Weight::zero()); + + let r = TakeWeightCredit::should_execute( + &Parent.into(), + message.inner_mut(), + Weight::from_parts(10, 10), + &mut properties, + ); + assert_eq!(r, Err(ProcessMessageError::Overweight(Weight::from_parts(10, 10)))); + assert_eq!(properties.weight_credit, Weight::zero()); +} + +#[test] +fn computed_origin_should_work() { + let mut message = Xcm::<()>(vec![ + UniversalOrigin(GlobalConsensus(Kusama)), + DescendOrigin(Parachain(100).into()), + DescendOrigin(PalletInstance(69).into()), + WithdrawAsset((Parent, 100).into()), + BuyExecution { + fees: (Parent, 100).into(), + weight_limit: Limited(Weight::from_parts(100, 100)), + }, + TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() }, + ]); + + AllowPaidFrom::set(vec![( + Parent, + Parent, + GlobalConsensus(Kusama), + Parachain(100), + PalletInstance(69), + ) + .into()]); + + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parent.into(), + message.inner_mut(), + Weight::from_parts(100, 100), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Unsupported)); + + let r = WithComputedOrigin::< + AllowTopLevelPaidExecutionFrom>, + ExecutorUniversalLocation, + ConstU32<2>, + >::should_execute( + &Parent.into(), + message.inner_mut(), + Weight::from_parts(100, 100), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Unsupported)); + + let r = WithComputedOrigin::< + AllowTopLevelPaidExecutionFrom>, + ExecutorUniversalLocation, + ConstU32<5>, + >::should_execute( + &Parent.into(), + message.inner_mut(), + Weight::from_parts(100, 100), + &mut props(Weight::zero()), + ); + assert_eq!(r, Ok(())); +} + +#[test] +fn allow_unpaid_should_work() { + let mut message = + Xcm::<()>(vec![TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() }]); + + AllowUnpaidFrom::set(vec![Parent.into()]); + + let r = AllowUnpaidExecutionFrom::>::should_execute( + &Parachain(1).into(), + message.inner_mut(), + Weight::from_parts(10, 10), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Unsupported)); + + let r = AllowUnpaidExecutionFrom::>::should_execute( + &Parent.into(), + message.inner_mut(), + Weight::from_parts(10, 10), + &mut props(Weight::zero()), + ); + assert_eq!(r, Ok(())); +} + +#[test] +fn allow_explicit_unpaid_should_work() { + let mut bad_message1 = + Xcm::<()>(vec![TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() }]); + + let mut bad_message2 = Xcm::<()>(vec![ + UnpaidExecution { + weight_limit: Limited(Weight::from_parts(10, 10)), + check_origin: Some(Parent.into()), + }, + TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() }, + ]); + + let mut good_message = Xcm::<()>(vec![ + UnpaidExecution { + weight_limit: Limited(Weight::from_parts(20, 20)), + check_origin: Some(Parent.into()), + }, + TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() }, + ]); + + AllowExplicitUnpaidFrom::set(vec![Parent.into()]); + + let r = AllowExplicitUnpaidExecutionFrom::>::should_execute( + &Parachain(1).into(), + good_message.inner_mut(), + Weight::from_parts(20, 20), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Unsupported)); + + let r = AllowExplicitUnpaidExecutionFrom::>::should_execute( + &Parent.into(), + bad_message1.inner_mut(), + Weight::from_parts(20, 20), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Overweight(Weight::from_parts(20, 20)))); + + let r = AllowExplicitUnpaidExecutionFrom::>::should_execute( + &Parent.into(), + bad_message2.inner_mut(), + Weight::from_parts(20, 20), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Overweight(Weight::from_parts(20, 20)))); + + let r = AllowExplicitUnpaidExecutionFrom::>::should_execute( + &Parent.into(), + good_message.inner_mut(), + Weight::from_parts(20, 20), + &mut props(Weight::zero()), + ); + assert_eq!(r, Ok(())); + + let mut message_with_different_weight_parts = Xcm::<()>(vec![ + UnpaidExecution { + weight_limit: Limited(Weight::from_parts(20, 10)), + check_origin: Some(Parent.into()), + }, + TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() }, + ]); + + let r = AllowExplicitUnpaidExecutionFrom::>::should_execute( + &Parent.into(), + message_with_different_weight_parts.inner_mut(), + Weight::from_parts(20, 20), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Overweight(Weight::from_parts(20, 20)))); + + let r = AllowExplicitUnpaidExecutionFrom::>::should_execute( + &Parent.into(), + message_with_different_weight_parts.inner_mut(), + Weight::from_parts(10, 10), + &mut props(Weight::zero()), + ); + assert_eq!(r, Ok(())); +} + +#[test] +fn allow_paid_should_work() { + AllowPaidFrom::set(vec![Parent.into()]); + + let mut message = + Xcm::<()>(vec![TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() }]); + + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parachain(1).into(), + message.inner_mut(), + Weight::from_parts(10, 10), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Unsupported)); + + let fees = (Parent, 1).into(); + let mut underpaying_message = Xcm::<()>(vec![ + ReserveAssetDeposited((Parent, 100).into()), + BuyExecution { fees, weight_limit: Limited(Weight::from_parts(20, 20)) }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: Here.into() }, + ]); + + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parent.into(), + underpaying_message.inner_mut(), + Weight::from_parts(30, 30), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Overweight(Weight::from_parts(30, 30)))); + + let fees = (Parent, 1).into(); + let mut paying_message = Xcm::<()>(vec![ + ReserveAssetDeposited((Parent, 100).into()), + BuyExecution { fees, weight_limit: Limited(Weight::from_parts(30, 30)) }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: Here.into() }, + ]); + + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parachain(1).into(), + paying_message.inner_mut(), + Weight::from_parts(30, 30), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Unsupported)); + + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parent.into(), + paying_message.inner_mut(), + Weight::from_parts(30, 30), + &mut props(Weight::zero()), + ); + assert_eq!(r, Ok(())); + + let fees = (Parent, 1).into(); + let mut paying_message_with_different_weight_parts = Xcm::<()>(vec![ + WithdrawAsset((Parent, 100).into()), + BuyExecution { fees, weight_limit: Limited(Weight::from_parts(20, 10)) }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: Here.into() }, + ]); + + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parent.into(), + paying_message_with_different_weight_parts.inner_mut(), + Weight::from_parts(20, 20), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Overweight(Weight::from_parts(20, 20)))); + + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parent.into(), + paying_message_with_different_weight_parts.inner_mut(), + Weight::from_parts(10, 10), + &mut props(Weight::zero()), + ); + assert_eq!(r, Ok(())) +} + +#[test] +fn suspension_should_work() { + TestSuspender::set_suspended(true); + AllowUnpaidFrom::set(vec![Parent.into()]); + + let mut message = + Xcm::<()>(vec![TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() }]); + let r = RespectSuspension::>, TestSuspender>::should_execute( + &Parent.into(), + message.inner_mut(), + Weight::from_parts(10, 10), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Yield)); + + TestSuspender::set_suspended(false); + let mut message = + Xcm::<()>(vec![TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() }]); + let r = RespectSuspension::>, TestSuspender>::should_execute( + &Parent.into(), + message.inner_mut(), + Weight::from_parts(10, 10), + &mut props(Weight::zero()), + ); + assert_eq!(r, Ok(())); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/basic.rs b/polkadot/xcm/xcm-builder/src/tests/basic.rs new file mode 100644 index 0000000000000000000000000000000000000000..02fcd8962dbfb98b7077bfd5ca11203fe31f2581 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/basic.rs @@ -0,0 +1,106 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +#[test] +fn basic_setup_works() { + add_reserve(Parent.into(), Wild((Parent, WildFungible).into())); + assert!( + ::IsReserve::contains(&(Parent, 100u128).into(), &Parent.into(),) + ); + + assert_eq!(to_account(Parachain(1)), Ok(1001)); + assert_eq!(to_account(Parachain(50)), Ok(1050)); + assert_eq!(to_account((Parent, Parachain(1))), Ok(2001)); + assert_eq!(to_account((Parent, Parachain(50))), Ok(2050)); + assert_eq!( + to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 1, network: None }))), + Ok(1), + ); + assert_eq!( + to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 42, network: None }))), + Ok(42), + ); + assert_eq!(to_account(Here), Ok(3000)); +} + +#[test] +fn weigher_should_work() { + let mut message = Xcm(vec![ + ReserveAssetDeposited((Parent, 100u128).into()), + BuyExecution { + fees: (Parent, 1u128).into(), + weight_limit: Limited(Weight::from_parts(30, 30)), + }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: Here.into() }, + ]); + assert_eq!( + ::Weigher::weight(&mut message), + Ok(Weight::from_parts(30, 30)) + ); +} + +#[test] +fn code_registers_should_work() { + // we'll let them have message execution for free. + AllowUnpaidFrom::set(vec![Here.into()]); + // We own 1000 of our tokens. + add_asset(Here, (Here, 21u128)); + let mut message = Xcm(vec![ + // Set our error handler - this will fire only on the second message, when there's an error + SetErrorHandler(Xcm(vec![ + TransferAsset { + assets: (Here, 2u128).into(), + beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + }, + // It was handled fine. + ClearError, + ])), + // Set the appendix - this will always fire. + SetAppendix(Xcm(vec![TransferAsset { + assets: (Here, 4u128).into(), + beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + }])), + // First xfer always works ok + TransferAsset { + assets: (Here, 1u128).into(), + beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + }, + // Second xfer results in error on the second message - our error handler will fire. + TransferAsset { + assets: (Here, 8u128).into(), + beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + }, + ]); + // Weight limit of 70 is needed. + let limit = ::Weigher::weight(&mut message).unwrap(); + assert_eq!(limit, Weight::from_parts(70, 70)); + + let hash = fake_message_hash(&message); + + let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(50, 50))); // We don't pay the 20 weight for the error handler. + assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 13u128).into()]); + assert_eq!(asset_list(Here), vec![(Here, 8u128).into()]); + assert_eq!(sent_xcm(), vec![]); + + let r = XcmExecutor::::execute_xcm(Here, message, hash, limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); // We pay the full weight here. + assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 20u128).into()]); + assert_eq!(asset_list(Here), vec![(Here, 1u128).into()]); + assert_eq!(sent_xcm(), vec![]); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs new file mode 100644 index 0000000000000000000000000000000000000000..406843a0fe8ae69fe9b9754890c40e9138e45701 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs @@ -0,0 +1,128 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This test is when we're sending an XCM from a parachain which hosts a bridge to another +//! network's bridge parachain. The destination of the XCM is within the global consensus of the +//! remote side of the bridge. + +use super::*; + +parameter_types! { + pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); + pub RemoteUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); +} +type TheBridge = + TestBridge>; +type Router = + TestTopic, UniversalLocation>>; + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) | GlobalConsensus(Remote::get()) +/// | +/// | +/// | +/// | +/// Parachain(1) ===> Parachain(1) +/// ``` +#[test] +fn sending_to_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + let dest = (Parent, Parent, Remote::get(), Parachain(1)).into(); + assert_eq!(send_xcm::(dest, msg).unwrap().1, (Here, 100).into()); + assert_eq!(TheBridge::service(), 1); + assert_eq!( + take_received_remote_messages(), + vec![( + Here.into(), + xcm_with_topic( + [0; 32], + vec![ + UniversalOrigin(Local::get().into()), + DescendOrigin(Parachain(1).into()), + Trap(1), + ] + ) + )] + ); + }); +} + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) | GlobalConsensus(Remote::get()) +/// | +/// | +/// | +/// | +/// Parachain(1) ===> Parachain(1) ==> Parachain(1000) +/// ``` +#[test] +fn sending_to_parachain_of_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + let dest = (Parent, Parent, Remote::get(), Parachain(1000)).into(); + assert_eq!(send_xcm::(dest, msg).unwrap().1, (Here, 100).into()); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + (Parent, Parachain(1000)).into(), + xcm_with_topic( + [0; 32], + vec![ + UniversalOrigin(Local::get().into()), + DescendOrigin(Parachain(1).into()), + Trap(1), + ], + ), + )]; + assert_eq!(take_received_remote_messages(), expected); + }); +} + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) | GlobalConsensus(Remote::get()) +/// | /\ +/// | || +/// | || +/// | || +/// Parachain(1) ===> Parachain(1) +/// ``` +#[test] +fn sending_to_relay_chain_of_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + let dest = (Parent, Parent, Remote::get()).into(); + assert_eq!(send_xcm::(dest, msg).unwrap().1, (Here, 100).into()); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + Parent.into(), + xcm_with_topic( + [0; 32], + vec![ + UniversalOrigin(Local::get().into()), + DescendOrigin(Parachain(1).into()), + Trap(1), + ], + ), + )]; + assert_eq!(take_received_remote_messages(), expected); + }); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs new file mode 100644 index 0000000000000000000000000000000000000000..02c454bb2129184e14da7b1892de07b6aa6b7d73 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs @@ -0,0 +1,80 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This test is when we're sending an XCM from a relay-chain which hosts a bridge to another +//! relay-chain. The destination of the XCM is within the global consensus of the +//! remote side of the bridge. + +use super::*; + +parameter_types! { + pub UniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); + pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); +} +type TheBridge = + TestBridge>; +type Router = + TestTopic, UniversalLocation>>; + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) ========> GlobalConsensus(Remote::get()) +/// | +/// ``` +#[test] +fn sending_to_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + assert_eq!( + send_xcm::((Parent, Remote::get()).into(), msg).unwrap().1, + (Here, 100).into() + ); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + Here.into(), + xcm_with_topic([0; 32], vec![UniversalOrigin(Local::get().into()), Trap(1)]), + )]; + assert_eq!(take_received_remote_messages(), expected); + assert_eq!(RoutingLog::take(), vec![]); + }); +} + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) ========> GlobalConsensus(Remote::get()) +/// | || +/// | || +/// | || +/// | \/ +/// | Parachain(1000) +/// ``` +#[test] +fn sending_to_parachain_of_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + let dest = (Parent, Remote::get(), Parachain(1000)).into(); + assert_eq!(send_xcm::(dest, msg).unwrap().1, (Here, 100).into()); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + Parachain(1000).into(), + xcm_with_topic([0; 32], vec![UniversalOrigin(Local::get().into()), Trap(1)]), + )]; + assert_eq!(take_received_remote_messages(), expected); + assert_eq!(RoutingLog::take(), vec![]); + }); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..45630dbfc2484c23c14a1cbc283c5403a9f56d62 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs @@ -0,0 +1,279 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests specific to the bridging primitives + +use super::mock::*; +use crate::{universal_exports::*, WithTopicSource}; +use frame_support::{parameter_types, traits::Get}; +use std::{cell::RefCell, marker::PhantomData}; +use xcm_executor::{ + traits::{export_xcm, validate_export}, + XcmExecutor, +}; +use SendError::*; + +mod local_para_para; +mod local_relay_relay; +mod paid_remote_relay_relay; +mod remote_para_para; +mod remote_para_para_via_relay; +mod remote_relay_relay; + +parameter_types! { + pub Local: NetworkId = ByGenesis([0; 32]); + pub Remote: NetworkId = ByGenesis([1; 32]); + pub Price: MultiAssets = MultiAssets::from((Here, 100u128)); + pub static UsingTopic: bool = false; +} + +std::thread_local! { + static BRIDGE_TRAFFIC: RefCell>> = RefCell::new(Vec::new()); +} + +fn maybe_with_topic(f: impl Fn()) { + UsingTopic::set(false); + f(); + UsingTopic::set(true); + f(); +} + +fn xcm_with_topic(topic: XcmHash, mut xcm: Vec>) -> Xcm { + if UsingTopic::get() { + xcm.push(SetTopic(topic)); + } + Xcm(xcm) +} + +fn fake_id() -> XcmHash { + [255; 32] +} + +fn test_weight(mut count: u64) -> Weight { + if UsingTopic::get() { + count += 1; + } + Weight::from_parts(count * 10, count * 10) +} + +fn maybe_forward_id_for(topic: &XcmHash) -> XcmHash { + match UsingTopic::get() { + true => forward_id_for(topic), + false => fake_id(), + } +} + +enum TestTicket { + Basic(T::Ticket), + Topic( as SendXcm>::Ticket), +} + +struct TestTopic(PhantomData); +impl SendXcm for TestTopic { + type Ticket = TestTicket; + fn deliver(ticket: Self::Ticket) -> core::result::Result { + match ticket { + TestTicket::Basic(t) => R::deliver(t), + TestTicket::Topic(t) => WithTopicSource::::deliver(t), + } + } + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { + Ok(if UsingTopic::get() { + let (t, a) = WithTopicSource::::validate(destination, message)?; + (TestTicket::Topic(t), a) + } else { + let (t, a) = R::validate(destination, message)?; + (TestTicket::Basic(t), a) + }) + } +} + +struct TestBridge(PhantomData); +impl TestBridge { + fn service() -> u64 { + BRIDGE_TRAFFIC + .with(|t| t.borrow_mut().drain(..).map(|b| D::dispatch_blob(b).map_or(0, |()| 1)).sum()) + } +} +impl HaulBlob for TestBridge { + fn haul_blob(blob: Vec) -> Result<(), HaulBlobError> { + BRIDGE_TRAFFIC.with(|t| t.borrow_mut().push(blob)); + Ok(()) + } +} + +std::thread_local! { + static REMOTE_INCOMING_XCM: RefCell)>> = RefCell::new(Vec::new()); +} +struct TestRemoteIncomingRouter; +impl SendXcm for TestRemoteIncomingRouter { + type Ticket = (MultiLocation, Xcm<()>); + fn validate( + dest: &mut Option, + msg: &mut Option>, + ) -> SendResult<(MultiLocation, Xcm<()>)> { + let pair = (dest.take().unwrap(), msg.take().unwrap()); + Ok((pair, MultiAssets::new())) + } + fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + let hash = fake_id(); + REMOTE_INCOMING_XCM.with(|q| q.borrow_mut().push(pair)); + Ok(hash) + } +} + +fn take_received_remote_messages() -> Vec<(MultiLocation, Xcm<()>)> { + REMOTE_INCOMING_XCM.with(|r| r.replace(vec![])) +} + +/// This is a dummy router which accepts messages destined for `Remote` from `Local` +/// and then executes them for free in a context simulated to be like that of our `Remote`. +struct UnpaidExecutingRouter( + PhantomData<(Local, Remote, RemoteExporter)>, +); + +fn price( + n: NetworkId, + c: u32, + s: &InteriorMultiLocation, + d: &InteriorMultiLocation, + m: &Xcm<()>, +) -> Result { + Ok(validate_export::(n, c, *s, *d, m.clone())?.1) +} + +fn deliver( + n: NetworkId, + c: u32, + s: InteriorMultiLocation, + d: InteriorMultiLocation, + m: Xcm<()>, +) -> Result { + export_xcm::(n, c, s, d, m).map(|(hash, _)| hash) +} + +#[derive(Eq, PartialEq, Clone, Debug)] +pub struct LogEntry { + local: Junctions, + remote: Junctions, + id: XcmHash, + message: Xcm<()>, + outcome: Outcome, + paid: bool, +} + +parameter_types! { + pub static RoutingLog: Vec = vec![]; +} + +impl, Remote: Get, RemoteExporter: ExportXcm> SendXcm + for UnpaidExecutingRouter +{ + type Ticket = Xcm<()>; + + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult> { + let expect_dest = Remote::get().relative_to(&Local::get()); + if destination.as_ref().ok_or(MissingArgument)? != &expect_dest { + return Err(NotApplicable) + } + let message = message.take().ok_or(MissingArgument)?; + Ok((message, MultiAssets::new())) + } + + fn deliver(message: Xcm<()>) -> Result { + // We now pretend that the message was delivered from `Local` to `Remote`, and execute + // so we need to ensure that the `TestConfig` is set up properly for executing as + // though it is `Remote`. + ExecutorUniversalLocation::set(Remote::get()); + let origin = Local::get().relative_to(&Remote::get()); + AllowUnpaidFrom::set(vec![origin]); + set_exporter_override(price::, deliver::); + // The we execute it: + let mut id = fake_id(); + let outcome = XcmExecutor::::prepare_and_execute( + origin, + message.clone().into(), + &mut id, + Weight::from_parts(2_000_000_000_000, 2_000_000_000_000), + Weight::zero(), + ); + let local = Local::get(); + let remote = Remote::get(); + let entry = LogEntry { local, remote, id, message, outcome: outcome.clone(), paid: false }; + RoutingLog::mutate(|l| l.push(entry)); + match outcome { + Outcome::Complete(..) => Ok(id), + Outcome::Incomplete(..) => Err(Transport("Error executing")), + Outcome::Error(..) => Err(Transport("Unable to execute")), + } + } +} + +/// This is a dummy router which accepts messages destined for `Remote` from `Local` +/// and then executes them in a context simulated to be like that of our `Remote`. Payment is +/// needed. +struct ExecutingRouter(PhantomData<(Local, Remote, RemoteExporter)>); +impl, Remote: Get, RemoteExporter: ExportXcm> SendXcm + for ExecutingRouter +{ + type Ticket = Xcm<()>; + + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult> { + let expect_dest = Remote::get().relative_to(&Local::get()); + if destination.as_ref().ok_or(MissingArgument)? != &expect_dest { + return Err(NotApplicable) + } + let message = message.take().ok_or(MissingArgument)?; + Ok((message, MultiAssets::new())) + } + + fn deliver(message: Xcm<()>) -> Result { + // We now pretend that the message was delivered from `Local` to `Remote`, and execute + // so we need to ensure that the `TestConfig` is set up properly for executing as + // though it is `Remote`. + ExecutorUniversalLocation::set(Remote::get()); + let origin = Local::get().relative_to(&Remote::get()); + AllowPaidFrom::set(vec![origin]); + set_exporter_override(price::, deliver::); + // Then we execute it: + let mut id = fake_id(); + let outcome = XcmExecutor::::prepare_and_execute( + origin, + message.clone().into(), + &mut id, + Weight::from_parts(2_000_000_000_000, 2_000_000_000_000), + Weight::zero(), + ); + let local = Local::get(); + let remote = Remote::get(); + let entry = LogEntry { local, remote, id, message, outcome: outcome.clone(), paid: true }; + RoutingLog::mutate(|l| l.push(entry)); + match outcome { + Outcome::Complete(..) => Ok(id), + Outcome::Incomplete(..) => Err(Transport("Error executing")), + Outcome::Error(..) => Err(Transport("Unable to execute")), + } + } +} diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs new file mode 100644 index 0000000000000000000000000000000000000000..7593ea5f17c084ac7f31aaeb439e4dc7a19924c2 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs @@ -0,0 +1,194 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This test is when we're sending an XCM from a parachain whose relay-chain hosts a bridge to +//! another relay-chain. The destination of the XCM is within the global consensus of the +//! remote side of the bridge. +//! +//! The Relay-chain here requires payment by the parachain for use of the bridge. This is expressed +//! under the standard XCM weight and the weight pricing. + +use super::*; + +parameter_types! { + pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(100)); + pub RelayUniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); + pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); + pub BridgeTable: Vec<(NetworkId, MultiLocation, Option)> + = vec![(Remote::get(), MultiLocation::parent(), Some((Parent, 200u128 + if UsingTopic::get() { 20 } else { 0 }).into()))]; + // ^^^ 100 to use the bridge (export) and 100 for the remote execution weight (5 instructions + // x (10 + 10) weight each). +} +type TheBridge = + TestBridge>; +type RelayExporter = HaulBlobExporter; +type LocalInnerRouter = ExecutingRouter; +type LocalBridgeRouter = SovereignPaidRemoteExporter< + NetworkExportTable, + LocalInnerRouter, + UniversalLocation, +>; +type LocalRouter = TestTopic<(LocalInnerRouter, LocalBridgeRouter)>; + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) ========> GlobalConsensus(Remote::get()) +/// /\ | +/// || | +/// || | +/// || | +/// Parachain(100) | +/// ``` +#[test] +fn sending_to_bridged_chain_works() { + maybe_with_topic(|| { + let dest: MultiLocation = (Parent, Parent, Remote::get()).into(); + + // Initialize the local relay so that our parachain has funds to pay for export. + clear_assets(Parachain(100)); + add_asset(Parachain(100), (Here, 1000u128)); + + let price = 200u128 + if UsingTopic::get() { 20 } else { 0 }; + + let msg = Xcm(vec![Trap(1)]); + assert_eq!(send_xcm::(dest, msg).unwrap().1, (Parent, price).into()); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + Here.into(), + xcm_with_topic( + [0; 32], + vec![ + UniversalOrigin(Local::get().into()), + DescendOrigin(Parachain(100).into()), + Trap(1), + ], + ), + )]; + assert_eq!(take_received_remote_messages(), expected); + + // The export cost 50 ref time and 50 proof size weight units (and thus 100 units of + // balance). + assert_eq!(asset_list(Parachain(100)), vec![(Here, 1000u128 - price).into()]); + + let entry = LogEntry { + local: UniversalLocation::get(), + remote: RelayUniversalLocation::get(), + id: maybe_forward_id_for(&[0; 32]), + message: xcm_with_topic( + maybe_forward_id_for(&[0; 32]), + vec![ + WithdrawAsset(MultiAsset::from((Here, price)).into()), + BuyExecution { fees: (Here, price).into(), weight_limit: Unlimited }, + ExportMessage { + network: ByGenesis([1; 32]), + destination: Here, + xcm: xcm_with_topic([0; 32], vec![Trap(1)]), + }, + RefundSurplus, + DepositAsset { assets: Wild(All), beneficiary: Parachain(100).into() }, + ], + ), + outcome: Outcome::Complete(test_weight(5)), + paid: true, + }; + assert_eq!(RoutingLog::take(), vec![entry]); + }); +} +#[test] +fn sending_to_bridged_chain_without_funds_fails() { + let dest: MultiLocation = (Parent, Parent, Remote::get()).into(); + // Routing won't work if we don't have enough funds. + assert_eq!( + send_xcm::(dest, Xcm(vec![Trap(1)])), + Err(SendError::Transport("Error executing")), + ); +} + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) ========> GlobalConsensus(Remote::get()) +/// /\ | || +/// || | || +/// || | || +/// || | \/ +/// Parachain(100) | Parachain(100) +/// ``` +#[test] +fn sending_to_parachain_of_bridged_chain_works() { + maybe_with_topic(|| { + let dest: MultiLocation = (Parent, Parent, Remote::get(), Parachain(100)).into(); + + // Initialize the local relay so that our parachain has funds to pay for export. + clear_assets(Parachain(100)); + add_asset(Parachain(100), (Here, 1000u128)); + + let price = 200u128 + if UsingTopic::get() { 20 } else { 0 }; + + let msg = Xcm(vec![Trap(1)]); + assert_eq!(send_xcm::(dest, msg).unwrap().1, (Parent, price).into()); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + Parachain(100).into(), + xcm_with_topic( + [0; 32], + vec![ + UniversalOrigin(Local::get().into()), + DescendOrigin(Parachain(100).into()), + Trap(1), + ], + ), + )]; + assert_eq!(take_received_remote_messages(), expected); + + // The export cost 50 ref time and 50 proof size weight units (and thus 100 units of + // balance). + assert_eq!(asset_list(Parachain(100)), vec![(Here, 1000u128 - price).into()]); + + let entry = LogEntry { + local: UniversalLocation::get(), + remote: RelayUniversalLocation::get(), + id: maybe_forward_id_for(&[0; 32]), + message: xcm_with_topic( + maybe_forward_id_for(&[0; 32]), + vec![ + WithdrawAsset(MultiAsset::from((Here, price)).into()), + BuyExecution { fees: (Here, price).into(), weight_limit: Unlimited }, + ExportMessage { + network: ByGenesis([1; 32]), + destination: Parachain(100).into(), + xcm: xcm_with_topic([0; 32], vec![Trap(1)]), + }, + RefundSurplus, + DepositAsset { assets: Wild(All), beneficiary: Parachain(100).into() }, + ], + ), + outcome: Outcome::Complete(test_weight(5)), + paid: true, + }; + assert_eq!(RoutingLog::take(), vec![entry]); + }); +} +#[test] +fn sending_to_parachain_of_bridged_chain_without_funds_fails() { + let dest: MultiLocation = (Parent, Parent, Remote::get(), Parachain(100)).into(); + // Routing won't work if we don't have enough funds. + assert_eq!( + send_xcm::(dest, Xcm(vec![Trap(1)])), + Err(SendError::Transport("Error executing")), + ); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs new file mode 100644 index 0000000000000000000000000000000000000000..124a909bc072b01810a8708841514f292725095a --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs @@ -0,0 +1,197 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This test is when we're sending an XCM from a parachain whose sibling parachain hosts a +//! bridge to a parachain from another global consensus. The destination of the XCM is within +//! the global consensus of the remote side of the bridge. + +use super::*; + +parameter_types! { + pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1000)); + pub ParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); + pub RemoteParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); + pub BridgeTable: Vec<(NetworkId, MultiLocation, Option)> + = vec![(Remote::get(), (Parent, Parachain(1)).into(), None)]; +} +type TheBridge = TestBridge< + BridgeBlobDispatcher, +>; +type RelayExporter = HaulBlobExporter; +type LocalInnerRouter = + UnpaidExecutingRouter; +type LocalBridgingRouter = + UnpaidRemoteExporter, LocalInnerRouter, UniversalLocation>; +type LocalRouter = TestTopic<(LocalInnerRouter, LocalBridgingRouter)>; + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) | GlobalConsensus(Remote::get()) +/// | +/// | +/// | +/// | +/// Parachain(1000) ===> Parachain(1) ===> Parachain(1) +/// ``` +#[test] +fn sending_to_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + assert_eq!( + send_xcm::((Parent, Parent, Remote::get(), Parachain(1)).into(), msg) + .unwrap() + .1, + MultiAssets::new() + ); + assert_eq!(TheBridge::service(), 1); + assert_eq!( + take_received_remote_messages(), + vec![( + Here.into(), + xcm_with_topic( + [0; 32], + vec![ + UniversalOrigin(Local::get().into()), + DescendOrigin(Parachain(1000).into()), + Trap(1) + ] + ) + )] + ); + let entry = LogEntry { + local: UniversalLocation::get(), + remote: ParaBridgeUniversalLocation::get(), + id: maybe_forward_id_for(&[0; 32]), + message: xcm_with_topic( + maybe_forward_id_for(&[0; 32]), + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + ExportMessage { + network: ByGenesis([1; 32]), + destination: Parachain(1).into(), + xcm: xcm_with_topic([0; 32], vec![Trap(1)]), + }, + ], + ), + outcome: Outcome::Complete(test_weight(2)), + paid: false, + }; + assert_eq!(RoutingLog::take(), vec![entry]); + }); +} + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) | GlobalConsensus(Remote::get()) +/// | +/// | +/// | +/// | +/// Parachain(1000) ===> Parachain(1) ===> Parachain(1) ===> Parachain(1000) +/// ``` +#[test] +fn sending_to_sibling_of_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + let dest = (Parent, Parent, Remote::get(), Parachain(1000)).into(); + assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + (Parent, Parachain(1000)).into(), + xcm_with_topic( + [0; 32], + vec![ + UniversalOrigin(Local::get().into()), + DescendOrigin(Parachain(1000).into()), + Trap(1), + ], + ), + )]; + assert_eq!(take_received_remote_messages(), expected); + let entry = LogEntry { + local: UniversalLocation::get(), + remote: ParaBridgeUniversalLocation::get(), + id: maybe_forward_id_for(&[0; 32]), + message: xcm_with_topic( + maybe_forward_id_for(&[0; 32]), + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + ExportMessage { + network: ByGenesis([1; 32]), + destination: Parachain(1000).into(), + xcm: xcm_with_topic([0; 32], vec![Trap(1)]), + }, + ], + ), + outcome: Outcome::Complete(test_weight(2)), + paid: false, + }; + assert_eq!(RoutingLog::take(), vec![entry]); + }); +} + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) | GlobalConsensus(Remote::get()) +/// | /\ +/// | || +/// | || +/// | || +/// Parachain(1000) ===> Parachain(1) ===> Parachain(1) +/// ``` +#[test] +fn sending_to_relay_of_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + let dest = (Parent, Parent, Remote::get()).into(); + assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + Parent.into(), + xcm_with_topic( + [0; 32], + vec![ + UniversalOrigin(Local::get().into()), + DescendOrigin(Parachain(1000).into()), + Trap(1), + ], + ), + )]; + assert_eq!(take_received_remote_messages(), expected); + let entry = LogEntry { + local: UniversalLocation::get(), + remote: ParaBridgeUniversalLocation::get(), + id: maybe_forward_id_for(&[0; 32]), + message: xcm_with_topic( + maybe_forward_id_for(&[0; 32]), + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + ExportMessage { + network: ByGenesis([1; 32]), + destination: Here, + xcm: xcm_with_topic([0; 32], vec![Trap(1)]), + }, + ], + ), + outcome: Outcome::Complete(test_weight(2)), + paid: false, + }; + assert_eq!(RoutingLog::take(), vec![entry]); + }); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs new file mode 100644 index 0000000000000000000000000000000000000000..2ff1f9fb9764695b5290a0b34c50d38f19fc84fb --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs @@ -0,0 +1,174 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This test is when we're sending an XCM from a relay-chain whose child parachain hosts a +//! bridge to a parachain from another global consensus. The destination of the XCM is within +//! the global consensus of the remote side of the bridge. + +use super::*; + +parameter_types! { + pub UniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); + pub ParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); + pub RemoteParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); + pub BridgeTable: Vec<(NetworkId, MultiLocation, Option)> + = vec![(Remote::get(), Parachain(1).into(), None)]; +} +type TheBridge = TestBridge< + BridgeBlobDispatcher, +>; +type RelayExporter = HaulBlobExporter; +type LocalInnerRouter = + UnpaidExecutingRouter; +type LocalBridgingRouter = + UnpaidRemoteExporter, LocalInnerRouter, UniversalLocation>; +type LocalRouter = TestTopic<(LocalInnerRouter, LocalBridgingRouter)>; + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) | GlobalConsensus(Remote::get()) +/// || | +/// || | +/// || | +/// \/ | +/// Parachain(1) ===> Parachain(1) +/// ``` +#[test] +fn sending_to_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + assert_eq!( + send_xcm::((Parent, Remote::get(), Parachain(1)).into(), msg) + .unwrap() + .1, + MultiAssets::new() + ); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + Here.into(), + xcm_with_topic([0; 32], vec![UniversalOrigin(Local::get().into()), Trap(1)]), + )]; + assert_eq!(take_received_remote_messages(), expected); + let entry = LogEntry { + local: UniversalLocation::get(), + remote: ParaBridgeUniversalLocation::get(), + id: maybe_forward_id_for(&[0; 32]), + message: xcm_with_topic( + maybe_forward_id_for(&[0; 32]), + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + ExportMessage { + network: ByGenesis([1; 32]), + destination: Parachain(1).into(), + xcm: xcm_with_topic([0; 32], vec![Trap(1)]), + }, + ], + ), + outcome: Outcome::Complete(test_weight(2)), + paid: false, + }; + assert_eq!(RoutingLog::take(), vec![entry]); + }); +} + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) | GlobalConsensus(Remote::get()) +/// || | +/// || | +/// || | +/// \/ | +/// Parachain(1) ===> Parachain(1) ===> Parachain(1000) +/// ``` +#[test] +fn sending_to_sibling_of_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + let dest = (Parent, Remote::get(), Parachain(1000)).into(); + assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + (Parent, Parachain(1000)).into(), + xcm_with_topic([0; 32], vec![UniversalOrigin(Local::get().into()), Trap(1)]), + )]; + assert_eq!(take_received_remote_messages(), expected); + let entry = LogEntry { + local: UniversalLocation::get(), + remote: ParaBridgeUniversalLocation::get(), + id: maybe_forward_id_for(&[0; 32]), + message: xcm_with_topic( + maybe_forward_id_for(&[0; 32]), + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + ExportMessage { + network: ByGenesis([1; 32]), + destination: Parachain(1000).into(), + xcm: xcm_with_topic([0; 32], vec![Trap(1)]), + }, + ], + ), + outcome: Outcome::Complete(test_weight(2)), + paid: false, + }; + assert_eq!(RoutingLog::take(), vec![entry]); + }); +} + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) | GlobalConsensus(Remote::get()) +/// || | /\ +/// || | || +/// || | || +/// \/ | || +/// Parachain(1) ===> Parachain(1) +/// ``` +#[test] +fn sending_to_relay_of_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + let dest = (Parent, Remote::get()).into(); + assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + Parent.into(), + xcm_with_topic([0; 32], vec![UniversalOrigin(Local::get().into()), Trap(1)]), + )]; + assert_eq!(take_received_remote_messages(), expected); + let entry = LogEntry { + local: UniversalLocation::get(), + remote: ParaBridgeUniversalLocation::get(), + id: maybe_forward_id_for(&[0; 32]), + message: xcm_with_topic( + maybe_forward_id_for(&[0; 32]), + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + ExportMessage { + network: ByGenesis([1; 32]), + destination: Here, + xcm: xcm_with_topic([0; 32], vec![Trap(1)]), + }, + ], + ), + outcome: Outcome::Complete(test_weight(2)), + paid: false, + }; + assert_eq!(RoutingLog::take(), vec![entry]); + }); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs new file mode 100644 index 0000000000000000000000000000000000000000..cdd6b89b7b1b53cfe789715ae7cded58e7830e66 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs @@ -0,0 +1,143 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! This test is when we're sending an XCM from a parachain whose relay-chain hosts a bridge to +//! another relay-chain. The destination of the XCM is within the global consensus of the +//! remote side of the bridge. + +use super::*; + +parameter_types! { + pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1000)); + pub RelayUniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); + pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); + pub BridgeTable: Vec<(NetworkId, MultiLocation, Option)> + = vec![(Remote::get(), MultiLocation::parent(), None)]; +} +type TheBridge = + TestBridge>; +type RelayExporter = HaulBlobExporter; +type LocalInnerRouter = + UnpaidExecutingRouter; +type LocalBridgeRouter = + UnpaidRemoteExporter, LocalInnerRouter, UniversalLocation>; +type LocalRouter = TestTopic<(LocalInnerRouter, LocalBridgeRouter)>; + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) ========> GlobalConsensus(Remote::get()) +/// /\ | +/// || | +/// || | +/// || | +/// Parachain(1000) | +/// ``` +#[test] +fn sending_to_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + assert_eq!( + send_xcm::((Parent, Parent, Remote::get()).into(), msg).unwrap().1, + MultiAssets::new() + ); + assert_eq!(TheBridge::service(), 1); + assert_eq!( + take_received_remote_messages(), + vec![( + Here.into(), + xcm_with_topic( + [0; 32], + vec![ + UniversalOrigin(Local::get().into()), + DescendOrigin(Parachain(1000).into()), + Trap(1) + ] + ) + )] + ); + let entry = LogEntry { + local: UniversalLocation::get(), + remote: RelayUniversalLocation::get(), + id: maybe_forward_id_for(&[0; 32]), + message: xcm_with_topic( + maybe_forward_id_for(&[0; 32]), + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + ExportMessage { + network: ByGenesis([1; 32]), + destination: Here, + xcm: xcm_with_topic([0; 32], vec![Trap(1)]), + }, + ], + ), + outcome: Outcome::Complete(test_weight(2)), + paid: false, + }; + assert_eq!(RoutingLog::take(), vec![entry]); + }); +} + +/// ```nocompile +/// local | remote +/// | +/// GlobalConsensus(Local::get()) ========> GlobalConsensus(Remote::get()) +/// /\ | || +/// || | || +/// || | || +/// || | \/ +/// Parachain(1000) | Parachain(1000) +/// ``` +#[test] +fn sending_to_parachain_of_bridged_chain_works() { + maybe_with_topic(|| { + let msg = Xcm(vec![Trap(1)]); + let dest = (Parent, Parent, Remote::get(), Parachain(1000)).into(); + assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(TheBridge::service(), 1); + let expected = vec![( + Parachain(1000).into(), + xcm_with_topic( + [0; 32], + vec![ + UniversalOrigin(Local::get().into()), + DescendOrigin(Parachain(1000).into()), + Trap(1), + ], + ), + )]; + assert_eq!(take_received_remote_messages(), expected); + let entry = LogEntry { + local: UniversalLocation::get(), + remote: RelayUniversalLocation::get(), + id: maybe_forward_id_for(&[0; 32]), + message: xcm_with_topic( + maybe_forward_id_for(&[0; 32]), + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + ExportMessage { + network: ByGenesis([1; 32]), + destination: Parachain(1000).into(), + xcm: xcm_with_topic([0; 32], vec![Trap(1)]), + }, + ], + ), + outcome: Outcome::Complete(test_weight(2)), + paid: false, + }; + assert_eq!(RoutingLog::take(), vec![entry]); + }) +} diff --git a/polkadot/xcm/xcm-builder/src/tests/expecting.rs b/polkadot/xcm/xcm-builder/src/tests/expecting.rs new file mode 100644 index 0000000000000000000000000000000000000000..6d5e0ff47b51f11f13e1139c3b1f75479bd70960 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/expecting.rs @@ -0,0 +1,187 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +#[test] +fn expect_pallet_should_work() { + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 + // and let them know to hand it to account #3. + let message = Xcm(vec![ExpectPallet { + index: 1, + name: b"Balances".as_ref().into(), + module_name: b"pallet_balances".as_ref().into(), + crate_major: 1, + min_crate_minor: 42, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + + let message = Xcm(vec![ExpectPallet { + index: 1, + name: b"Balances".as_ref().into(), + module_name: b"pallet_balances".as_ref().into(), + crate_major: 1, + min_crate_minor: 41, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); +} + +#[test] +fn expect_pallet_should_fail_correctly() { + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + let message = Xcm(vec![ExpectPallet { + index: 1, + name: b"Balances".as_ref().into(), + module_name: b"pallet_balances".as_ref().into(), + crate_major: 1, + min_crate_minor: 60, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); + + let message = Xcm(vec![ExpectPallet { + index: 1, + name: b"System".as_ref().into(), + module_name: b"pallet_balances".as_ref().into(), + crate_major: 1, + min_crate_minor: 42, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); + + let message = Xcm(vec![ExpectPallet { + index: 1, + name: b"Balances".as_ref().into(), + module_name: b"pallet_system".as_ref().into(), + crate_major: 1, + min_crate_minor: 42, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); + + let message = Xcm(vec![ExpectPallet { + index: 0, + name: b"Balances".as_ref().into(), + module_name: b"pallet_balances".as_ref().into(), + crate_major: 1, + min_crate_minor: 42, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); + + let message = Xcm(vec![ExpectPallet { + index: 2, + name: b"Balances".as_ref().into(), + module_name: b"pallet_balances".as_ref().into(), + crate_major: 1, + min_crate_minor: 42, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::PalletNotFound)); + + let message = Xcm(vec![ExpectPallet { + index: 1, + name: b"Balances".as_ref().into(), + module_name: b"pallet_balances".as_ref().into(), + crate_major: 2, + min_crate_minor: 42, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); + + let message = Xcm(vec![ExpectPallet { + index: 1, + name: b"Balances".as_ref().into(), + module_name: b"pallet_balances".as_ref().into(), + crate_major: 0, + min_crate_minor: 42, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); + + let message = Xcm(vec![ExpectPallet { + index: 1, + name: b"Balances".as_ref().into(), + module_name: b"pallet_balances".as_ref().into(), + crate_major: 1, + min_crate_minor: 43, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/locking.rs b/polkadot/xcm/xcm-builder/src/tests/locking.rs new file mode 100644 index 0000000000000000000000000000000000000000..f4ef618ac0e73bc6427b29b77bef491397367350 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/locking.rs @@ -0,0 +1,238 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; +use LockTraceItem::*; + +#[test] +fn lock_roundtrip_should_work() { + // Account #3 and Parachain #1 can execute for free + AllowUnpaidFrom::set(vec![(3u64,).into(), (Parent, Parachain(1)).into()]); + // Account #3 owns 1000 native parent tokens. + add_asset((3u64,), (Parent, 1000u128)); + // Sending a message costs 10 parent-tokens. + set_send_price((Parent, 10u128)); + + // They want to lock 100 of the native parent tokens to be unlocked only by Parachain #1. + let message = Xcm(vec![ + WithdrawAsset((Parent, 100u128).into()), + SetAppendix( + vec![DepositAsset { assets: AllCounted(2).into(), beneficiary: (3u64,).into() }].into(), + ), + LockAsset { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into() }, + ]); + let hash = fake_message_hash(&message); + let r = + XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); + assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); + + let expected_msg = Xcm::<()>(vec![NoteUnlockable { + owner: (Parent, Parachain(42), 3u64).into(), + asset: (Parent, 100u128).into(), + }]); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!(sent_xcm(), vec![((Parent, Parachain(1)).into(), expected_msg, expected_hash)]); + assert_eq!( + take_lock_trace(), + vec![Lock { + asset: (Parent, 100u128).into(), + owner: (3u64,).into(), + unlocker: (Parent, Parachain(1)).into(), + }] + ); + + // Now we'll unlock it. + let message = + Xcm(vec![UnlockAsset { asset: (Parent, 100u128).into(), target: (3u64,).into() }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + (Parent, Parachain(1)), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); +} + +#[test] +fn auto_fee_paying_should_work() { + // Account #3 and Parachain #1 can execute for free + AllowUnpaidFrom::set(vec![(3u64,).into()]); + // Account #3 owns 1000 native parent tokens. + add_asset((3u64,), (Parent, 1000u128)); + // Sending a message costs 10 parent-tokens. + set_send_price((Parent, 10u128)); + + // They want to lock 100 of the native parent tokens to be unlocked only by Parachain #1. + let message = Xcm(vec![ + SetFeesMode { jit_withdraw: true }, + LockAsset { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into() }, + ]); + let hash = fake_message_hash(&message); + let r = + XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); + assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); +} + +#[test] +fn lock_should_fail_correctly() { + // Account #3 can execute for free + AllowUnpaidFrom::set(vec![(3u64,).into(), (Parent, Parachain(1)).into()]); + + // #3 wants to lock 100 of the native parent tokens to be unlocked only by parachain ../#1, + // but they don't have any. + let message = Xcm(vec![LockAsset { + asset: (Parent, 100u128).into(), + unlocker: (Parent, Parachain(1)).into(), + }]); + let hash = fake_message_hash(&message); + let r = + XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::LockError)); + assert_eq!(sent_xcm(), vec![]); + assert_eq!(take_lock_trace(), vec![]); + + // Account #3 owns 1000 native parent tokens. + add_asset((3u64,), (Parent, 1000u128)); + // But we require a price to be paid for the sending + set_send_price((Parent, 10u128)); + + // #3 wants to lock 100 of the native parent tokens to be unlocked only by parachain ../#1, + // but there's nothing to pay the fees for sending the notification message. + let message = Xcm(vec![LockAsset { + asset: (Parent, 100u128).into(), + unlocker: (Parent, Parachain(1)).into(), + }]); + let hash = fake_message_hash(&message); + let r = + XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotHoldingFees)); + assert_eq!(sent_xcm(), vec![]); + assert_eq!(take_lock_trace(), vec![]); +} + +#[test] +fn remote_unlock_roundtrip_should_work() { + // Account #3 can execute for free + AllowUnpaidFrom::set(vec![(3u64,).into(), (Parent, Parachain(1)).into()]); + // Account #3 owns 1000 native parent tokens. + add_asset((3u64,), (Parent, 1000u128)); + // Sending a message costs 10 parent-tokens. + set_send_price((Parent, 10u128)); + + // We have been told by Parachain #1 that Account #3 has locked funds which we can unlock. + // Previously, we must have sent a LockAsset instruction to Parachain #1. + // This caused Parachain #1 to send us the NoteUnlockable instruction. + let message = + Xcm(vec![NoteUnlockable { asset: (Parent, 100u128).into(), owner: (3u64,).into() }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + (Parent, Parachain(1)), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!( + take_lock_trace(), + vec![Note { + asset: (Parent, 100u128).into(), + owner: (3u64,).into(), + locker: (Parent, Parachain(1)).into(), + }] + ); + + // Let's request those funds be unlocked. + let message = Xcm(vec![ + WithdrawAsset((Parent, 100u128).into()), + SetAppendix( + vec![DepositAsset { assets: AllCounted(2).into(), beneficiary: (3u64,).into() }].into(), + ), + RequestUnlock { asset: (Parent, 100u128).into(), locker: (Parent, Parachain(1)).into() }, + ]); + let hash = fake_message_hash(&message); + let r = + XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); + assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); + + let expected_msg = Xcm::<()>(vec![UnlockAsset { + target: (Parent, Parachain(42), 3u64).into(), + asset: (Parent, 100u128).into(), + }]); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!(sent_xcm(), vec![((Parent, Parachain(1)).into(), expected_msg, expected_hash)]); + assert_eq!( + take_lock_trace(), + vec![Reduce { + asset: (Parent, 100u128).into(), + owner: (3u64,).into(), + locker: (Parent, Parachain(1)).into(), + }] + ); +} + +#[test] +fn remote_unlock_should_fail_correctly() { + // Account #3 can execute for free + AllowUnpaidFrom::set(vec![(3u64,).into(), (Parent, Parachain(1)).into()]); + // But we require a price to be paid for the sending + set_send_price((Parent, 10u128)); + + // We want to unlock 100 of the native parent tokens which were locked for us on parachain. + // This won't work as we don't have any record of them being locked for us. + // No message will be sent and no lock records changed. + let message = Xcm(vec![RequestUnlock { + asset: (Parent, 100u128).into(), + locker: (Parent, Parachain(1)).into(), + }]); + let hash = fake_message_hash(&message); + let r = + XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::LockError)); + assert_eq!(sent_xcm(), vec![]); + assert_eq!(take_lock_trace(), vec![]); + + // We have been told by Parachain #1 that Account #3 has locked funds which we can unlock. + let message = + Xcm(vec![NoteUnlockable { asset: (Parent, 100u128).into(), owner: (3u64,).into() }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + (Parent, Parachain(1)), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + let _discard = take_lock_trace(); + + // We want to unlock 100 of the native parent tokens which were locked for us on parachain. + // This won't work now as we don't have the funds to send the onward message. + // No message will be sent and no lock records changed. + let message = Xcm(vec![RequestUnlock { + asset: (Parent, 100u128).into(), + locker: (Parent, Parachain(1)).into(), + }]); + let hash = fake_message_hash(&message); + let r = + XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotHoldingFees)); + + assert_eq!(sent_xcm(), vec![]); + assert_eq!(take_lock_trace(), vec![]); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/mock.rs b/polkadot/xcm/xcm-builder/src/tests/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..0e7b748106efefaf87af4e7b5772ffa7ddfc3f1d --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/mock.rs @@ -0,0 +1,755 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Mock implementations to test XCM builder configuration types. + +use crate::{ + barriers::{AllowSubscriptionsFrom, RespectSuspension, TrailingSetTopicAsId}, + test_utils::*, +}; +pub use crate::{ + AliasForeignAccountId32, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, + AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, FixedRateOfFungible, + FixedWeightBounds, TakeWeightCredit, +}; +use frame_support::traits::{ContainsPair, Everything}; +pub use frame_support::{ + dispatch::{ + DispatchError, DispatchInfo, DispatchResultWithPostInfo, Dispatchable, GetDispatchInfo, + Parameter, PostDispatchInfo, + }, + ensure, match_types, parameter_types, + sp_runtime::DispatchErrorWithPostInfo, + traits::{ConstU32, Contains, Get, IsInVec}, +}; +pub use parity_scale_codec::{Decode, Encode}; +pub use sp_io::hashing::blake2_256; +pub use sp_std::{ + cell::{Cell, RefCell}, + collections::{btree_map::BTreeMap, btree_set::BTreeSet}, + fmt::Debug, + marker::PhantomData, +}; +pub use xcm::latest::{prelude::*, Weight}; +use xcm_executor::traits::{Properties, QueryHandler, QueryResponseStatus}; +pub use xcm_executor::{ + traits::{ + AssetExchange, AssetLock, CheckSuspension, ConvertOrigin, Enact, ExportXcm, FeeManager, + FeeReason, LockError, OnResponse, TransactAsset, + }, + Assets, Config, +}; + +pub enum TestOrigin { + Root, + Relay, + Signed(u64), + Parachain(u32), +} + +/// A dummy call. +/// +/// Each item contains the amount of weight that it *wants* to consume as the first item, and the +/// actual amount (if different from the former) in the second option. +#[derive(Debug, Encode, Decode, Eq, PartialEq, Clone, Copy, scale_info::TypeInfo)] +pub enum TestCall { + OnlyRoot(Weight, Option), + OnlyParachain(Weight, Option, Option), + OnlySigned(Weight, Option, Option), + Any(Weight, Option), +} +impl Dispatchable for TestCall { + type RuntimeOrigin = TestOrigin; + type Config = (); + type Info = (); + type PostInfo = PostDispatchInfo; + fn dispatch(self, origin: Self::RuntimeOrigin) -> DispatchResultWithPostInfo { + let mut post_info = PostDispatchInfo::default(); + let maybe_actual = match self { + TestCall::OnlyRoot(_, maybe_actual) | + TestCall::OnlySigned(_, maybe_actual, _) | + TestCall::OnlyParachain(_, maybe_actual, _) | + TestCall::Any(_, maybe_actual) => maybe_actual, + }; + post_info.actual_weight = maybe_actual; + if match (&origin, &self) { + (TestOrigin::Parachain(i), TestCall::OnlyParachain(_, _, Some(j))) => i == j, + (TestOrigin::Signed(i), TestCall::OnlySigned(_, _, Some(j))) => i == j, + (TestOrigin::Root, TestCall::OnlyRoot(..)) | + (TestOrigin::Parachain(_), TestCall::OnlyParachain(_, _, None)) | + (TestOrigin::Signed(_), TestCall::OnlySigned(_, _, None)) | + (_, TestCall::Any(..)) => true, + _ => false, + } { + Ok(post_info) + } else { + Err(DispatchErrorWithPostInfo { error: DispatchError::BadOrigin, post_info }) + } + } +} + +impl GetDispatchInfo for TestCall { + fn get_dispatch_info(&self) -> DispatchInfo { + let weight = *match self { + TestCall::OnlyRoot(estimate, ..) | + TestCall::OnlyParachain(estimate, ..) | + TestCall::OnlySigned(estimate, ..) | + TestCall::Any(estimate, ..) => estimate, + }; + DispatchInfo { weight, ..Default::default() } + } +} + +thread_local! { + pub static SENT_XCM: RefCell, XcmHash)>> = RefCell::new(Vec::new()); + pub static EXPORTED_XCM: RefCell< + Vec<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash)> + > = RefCell::new(Vec::new()); + pub static EXPORTER_OVERRIDE: RefCell, + ) -> Result, + fn( + NetworkId, + u32, + InteriorMultiLocation, + InteriorMultiLocation, + Xcm<()>, + ) -> Result, + )>> = RefCell::new(None); + pub static SEND_PRICE: RefCell = RefCell::new(MultiAssets::new()); + pub static SUSPENDED: Cell = Cell::new(false); +} +pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm, XcmHash)> { + SENT_XCM.with(|q| (*q.borrow()).clone()) +} +pub fn set_send_price(p: impl Into) { + SEND_PRICE.with(|l| l.replace(p.into().into())); +} +pub fn exported_xcm( +) -> Vec<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, opaque::Xcm, XcmHash)> { + EXPORTED_XCM.with(|q| (*q.borrow()).clone()) +} +pub fn set_exporter_override( + price: fn( + NetworkId, + u32, + &InteriorMultiLocation, + &InteriorMultiLocation, + &Xcm<()>, + ) -> Result, + deliver: fn( + NetworkId, + u32, + InteriorMultiLocation, + InteriorMultiLocation, + Xcm<()>, + ) -> Result, +) { + EXPORTER_OVERRIDE.with(|x| x.replace(Some((price, deliver)))); +} +#[allow(dead_code)] +pub fn clear_exporter_override() { + EXPORTER_OVERRIDE.with(|x| x.replace(None)); +} +pub struct TestMessageSender; +impl SendXcm for TestMessageSender { + type Ticket = (MultiLocation, Xcm<()>, XcmHash); + fn validate( + dest: &mut Option, + msg: &mut Option>, + ) -> SendResult<(MultiLocation, Xcm<()>, XcmHash)> { + let msg = msg.take().unwrap(); + let hash = fake_message_hash(&msg); + let triplet = (dest.take().unwrap(), msg, hash); + Ok((triplet, SEND_PRICE.with(|l| l.borrow().clone()))) + } + fn deliver(triplet: (MultiLocation, Xcm<()>, XcmHash)) -> Result { + let hash = triplet.2; + SENT_XCM.with(|q| q.borrow_mut().push(triplet)); + Ok(hash) + } +} +pub struct TestMessageExporter; +impl ExportXcm for TestMessageExporter { + type Ticket = (NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash); + fn validate( + network: NetworkId, + channel: u32, + uni_src: &mut Option, + dest: &mut Option, + msg: &mut Option>, + ) -> SendResult<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash)> + { + let (s, d, m) = (uni_src.take().unwrap(), dest.take().unwrap(), msg.take().unwrap()); + let r: Result = EXPORTER_OVERRIDE.with(|e| { + if let Some((ref f, _)) = &*e.borrow() { + f(network, channel, &s, &d, &m) + } else { + Ok(MultiAssets::new()) + } + }); + let h = fake_message_hash(&m); + match r { + Ok(price) => Ok(((network, channel, s, d, m, h), price)), + Err(e) => { + *uni_src = Some(s); + *dest = Some(d); + *msg = Some(m); + Err(e) + }, + } + } + fn deliver( + tuple: (NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash), + ) -> Result { + EXPORTER_OVERRIDE.with(|e| { + if let Some((_, ref f)) = &*e.borrow() { + let (network, channel, uni_src, dest, msg, _hash) = tuple; + f(network, channel, uni_src, dest, msg) + } else { + let hash = tuple.5; + EXPORTED_XCM.with(|q| q.borrow_mut().push(tuple)); + Ok(hash) + } + }) + } +} + +thread_local! { + pub static ASSETS: RefCell> = RefCell::new(BTreeMap::new()); +} +pub fn assets(who: impl Into) -> Assets { + ASSETS.with(|a| a.borrow().get(&who.into()).cloned()).unwrap_or_default() +} +pub fn asset_list(who: impl Into) -> Vec { + MultiAssets::from(assets(who)).into_inner() +} +pub fn add_asset(who: impl Into, what: impl Into) { + ASSETS.with(|a| a.borrow_mut().entry(who.into()).or_insert(Assets::new()).subsume(what.into())); +} +pub fn clear_assets(who: impl Into) { + ASSETS.with(|a| a.borrow_mut().remove(&who.into())); +} + +pub struct TestAssetTransactor; +impl TransactAsset for TestAssetTransactor { + fn deposit_asset( + what: &MultiAsset, + who: &MultiLocation, + _context: &XcmContext, + ) -> Result<(), XcmError> { + add_asset(*who, what.clone()); + Ok(()) + } + + fn withdraw_asset( + what: &MultiAsset, + who: &MultiLocation, + _maybe_context: Option<&XcmContext>, + ) -> Result { + ASSETS.with(|a| { + a.borrow_mut() + .get_mut(who) + .ok_or(XcmError::NotWithdrawable)? + .try_take(what.clone().into()) + .map_err(|_| XcmError::NotWithdrawable) + }) + } +} + +pub fn to_account(l: impl Into) -> Result { + Ok(match l.into() { + // Siblings at 2000+id + MultiLocation { parents: 1, interior: X1(Parachain(id)) } => 2000 + id as u64, + // Accounts are their number + MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) } => index, + // Children at 1000+id + MultiLocation { parents: 0, interior: X1(Parachain(id)) } => 1000 + id as u64, + // Self at 3000 + MultiLocation { parents: 0, interior: Here } => 3000, + // Parent at 3001 + MultiLocation { parents: 1, interior: Here } => 3001, + l => { + // Is it a foreign-consensus? + let uni = ExecutorUniversalLocation::get(); + if l.parents as usize != uni.len() { + return Err(l) + } + match l.first_interior() { + Some(GlobalConsensus(Kusama)) => 4000, + Some(GlobalConsensus(Polkadot)) => 4001, + _ => return Err(l), + } + }, + }) +} + +pub struct TestOriginConverter; +impl ConvertOrigin for TestOriginConverter { + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + use OriginKind::*; + match (kind, origin.into()) { + (Superuser, _) => Ok(TestOrigin::Root), + (SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)), + (Native, MultiLocation { parents: 0, interior: X1(Parachain(id)) }) => + Ok(TestOrigin::Parachain(id)), + (Native, MultiLocation { parents: 1, interior: Here }) => Ok(TestOrigin::Relay), + (Native, MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) }) => + Ok(TestOrigin::Signed(index)), + (_, origin) => Err(origin), + } + } +} + +thread_local! { + pub static IS_RESERVE: RefCell>> = RefCell::new(BTreeMap::new()); + pub static IS_TELEPORTER: RefCell>> = RefCell::new(BTreeMap::new()); + pub static UNIVERSAL_ALIASES: RefCell> = RefCell::new(BTreeSet::new()); +} +pub fn add_reserve(from: MultiLocation, asset: MultiAssetFilter) { + IS_RESERVE.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); +} +#[allow(dead_code)] +pub fn add_teleporter(from: MultiLocation, asset: MultiAssetFilter) { + IS_TELEPORTER.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); +} +pub fn add_universal_alias(bridge: impl Into, consensus: impl Into) { + UNIVERSAL_ALIASES.with(|r| r.borrow_mut().insert((bridge.into(), consensus.into()))); +} +pub fn clear_universal_aliases() { + UNIVERSAL_ALIASES.with(|r| r.replace(Default::default())); +} + +pub struct TestIsReserve; +impl ContainsPair for TestIsReserve { + fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + IS_RESERVE + .with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.matches(asset)))) + } +} +pub struct TestIsTeleporter; +impl ContainsPair for TestIsTeleporter { + fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + IS_TELEPORTER + .with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.matches(asset)))) + } +} + +pub struct TestUniversalAliases; +impl Contains<(MultiLocation, Junction)> for TestUniversalAliases { + fn contains(t: &(MultiLocation, Junction)) -> bool { + UNIVERSAL_ALIASES.with(|r| r.borrow().contains(t)) + } +} + +pub enum ResponseSlot { + Expecting(MultiLocation), + Received(Response), +} +thread_local! { + pub static QUERIES: RefCell> = RefCell::new(BTreeMap::new()); +} +pub struct TestResponseHandler; +impl OnResponse for TestResponseHandler { + fn expecting_response( + origin: &MultiLocation, + query_id: u64, + _querier: Option<&MultiLocation>, + ) -> bool { + QUERIES.with(|q| match q.borrow().get(&query_id) { + Some(ResponseSlot::Expecting(ref l)) => l == origin, + _ => false, + }) + } + fn on_response( + _origin: &MultiLocation, + query_id: u64, + _querier: Option<&MultiLocation>, + response: xcm::latest::Response, + _max_weight: Weight, + _context: &XcmContext, + ) -> Weight { + QUERIES.with(|q| { + q.borrow_mut().entry(query_id).and_modify(|v| { + if matches!(*v, ResponseSlot::Expecting(..)) { + *v = ResponseSlot::Received(response); + } + }); + }); + Weight::from_parts(10, 10) + } +} +pub fn expect_response(query_id: u64, from: MultiLocation) { + QUERIES.with(|q| q.borrow_mut().insert(query_id, ResponseSlot::Expecting(from))); +} +pub fn response(query_id: u64) -> Option { + QUERIES.with(|q| { + q.borrow().get(&query_id).and_then(|v| match v { + ResponseSlot::Received(r) => Some(r.clone()), + _ => None, + }) + }) +} + +/// Mock implementation of the [`QueryHandler`] trait for creating XCM success queries and expecting +/// responses. +pub struct TestQueryHandler(core::marker::PhantomData<(T, BlockNumber)>); +impl QueryHandler + for TestQueryHandler +{ + type QueryId = u64; + type BlockNumber = BlockNumber; + type Error = XcmError; + type UniversalLocation = T::UniversalLocation; + + fn new_query( + responder: impl Into, + _timeout: Self::BlockNumber, + _match_querier: impl Into, + ) -> Self::QueryId { + let query_id = 1; + expect_response(query_id, responder.into()); + query_id + } + + fn report_outcome( + message: &mut Xcm<()>, + responder: impl Into, + timeout: Self::BlockNumber, + ) -> Result { + let responder = responder.into(); + let destination = Self::UniversalLocation::get() + .invert_target(&responder) + .map_err(|()| XcmError::LocationNotInvertible)?; + let query_id = Self::new_query(responder, timeout, Here); + let response_info = QueryResponseInfo { destination, query_id, max_weight: Weight::zero() }; + let report_error = Xcm(vec![ReportError(response_info)]); + message.0.insert(0, SetAppendix(report_error)); + Ok(query_id) + } + + fn take_response(query_id: Self::QueryId) -> QueryResponseStatus { + QUERIES + .with(|q| { + q.borrow().get(&query_id).and_then(|v| match v { + ResponseSlot::Received(r) => Some(QueryResponseStatus::Ready { + response: r.clone(), + at: Self::BlockNumber::zero(), + }), + _ => Some(QueryResponseStatus::NotFound), + }) + }) + .unwrap_or(QueryResponseStatus::NotFound) + } + + #[cfg(feature = "runtime-benchmarks")] + fn expect_response(_id: Self::QueryId, _response: xcm::latest::Response) { + // Unnecessary since it's only a test implementation + } +} + +parameter_types! { + pub static ExecutorUniversalLocation: InteriorMultiLocation + = (ByGenesis([0; 32]), Parachain(42)).into(); + pub UnitWeightCost: Weight = Weight::from_parts(10, 10); +} +parameter_types! { + // Nothing is allowed to be paid/unpaid by default. + pub static AllowExplicitUnpaidFrom: Vec = vec![]; + pub static AllowUnpaidFrom: Vec = vec![]; + pub static AllowPaidFrom: Vec = vec![]; + pub static AllowSubsFrom: Vec = vec![]; + // 1_000_000_000_000 => 1 unit of asset for 1 unit of ref time weight. + // 1024 * 1024 => 1 unit of asset for 1 unit of proof size weight. + pub static WeightPrice: (AssetId, u128, u128) = + (From::from(Here), 1_000_000_000_000, 1024 * 1024); + pub static MaxInstructions: u32 = 100; +} + +pub struct TestSuspender; +impl CheckSuspension for TestSuspender { + fn is_suspended( + _origin: &MultiLocation, + _instructions: &mut [Instruction], + _max_weight: Weight, + _properties: &mut Properties, + ) -> bool { + SUSPENDED.with(|s| s.get()) + } +} + +impl TestSuspender { + pub fn set_suspended(suspended: bool) { + SUSPENDED.with(|s| s.set(suspended)); + } +} + +pub type TestBarrier = ( + TakeWeightCredit, + AllowKnownQueryResponses, + AllowTopLevelPaidExecutionFrom>, + AllowExplicitUnpaidExecutionFrom>, + AllowUnpaidExecutionFrom>, + AllowSubscriptionsFrom>, +); + +thread_local! { + pub static IS_WAIVED: RefCell> = RefCell::new(vec![]); +} +#[allow(dead_code)] +pub fn set_fee_waiver(waived: Vec) { + IS_WAIVED.with(|l| l.replace(waived)); +} + +pub struct TestFeeManager; +impl FeeManager for TestFeeManager { + fn is_waived(_: Option<&MultiLocation>, r: FeeReason) -> bool { + IS_WAIVED.with(|l| l.borrow().contains(&r)) + } + fn handle_fee(_: MultiAssets) {} +} + +#[derive(Clone, Eq, PartialEq, Debug)] +pub enum LockTraceItem { + Lock { unlocker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, + Unlock { unlocker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, + Note { locker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, + Reduce { locker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, +} +thread_local! { + pub static NEXT_INDEX: RefCell = RefCell::new(0); + pub static LOCK_TRACE: RefCell> = RefCell::new(Vec::new()); + pub static ALLOWED_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); + pub static ALLOWED_REQUEST_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); +} + +pub fn take_lock_trace() -> Vec { + LOCK_TRACE.with(|l| l.replace(Vec::new())) +} +pub fn allow_unlock( + unlocker: impl Into, + asset: impl Into, + owner: impl Into, +) { + ALLOWED_UNLOCKS.with(|l| { + l.borrow_mut() + .entry((owner.into(), unlocker.into())) + .or_default() + .subsume(asset.into()) + }); +} +pub fn disallow_unlock( + unlocker: impl Into, + asset: impl Into, + owner: impl Into, +) { + ALLOWED_UNLOCKS.with(|l| { + l.borrow_mut() + .entry((owner.into(), unlocker.into())) + .or_default() + .saturating_take(asset.into().into()) + }); +} +pub fn unlock_allowed(unlocker: &MultiLocation, asset: &MultiAsset, owner: &MultiLocation) -> bool { + ALLOWED_UNLOCKS.with(|l| { + l.borrow_mut() + .get(&(*owner, *unlocker)) + .map_or(false, |x| x.contains_asset(asset)) + }) +} +pub fn allow_request_unlock( + locker: impl Into, + asset: impl Into, + owner: impl Into, +) { + ALLOWED_REQUEST_UNLOCKS.with(|l| { + l.borrow_mut() + .entry((owner.into(), locker.into())) + .or_default() + .subsume(asset.into()) + }); +} +pub fn disallow_request_unlock( + locker: impl Into, + asset: impl Into, + owner: impl Into, +) { + ALLOWED_REQUEST_UNLOCKS.with(|l| { + l.borrow_mut() + .entry((owner.into(), locker.into())) + .or_default() + .saturating_take(asset.into().into()) + }); +} +pub fn request_unlock_allowed( + locker: &MultiLocation, + asset: &MultiAsset, + owner: &MultiLocation, +) -> bool { + ALLOWED_REQUEST_UNLOCKS.with(|l| { + l.borrow_mut() + .get(&(*owner, *locker)) + .map_or(false, |x| x.contains_asset(asset)) + }) +} + +pub struct TestTicket(LockTraceItem); +impl Enact for TestTicket { + fn enact(self) -> Result<(), LockError> { + match &self.0 { + LockTraceItem::Lock { unlocker, asset, owner } => + allow_unlock(*unlocker, asset.clone(), *owner), + LockTraceItem::Unlock { unlocker, asset, owner } => + disallow_unlock(*unlocker, asset.clone(), *owner), + LockTraceItem::Reduce { locker, asset, owner } => + disallow_request_unlock(*locker, asset.clone(), *owner), + _ => {}, + } + LOCK_TRACE.with(move |l| l.borrow_mut().push(self.0)); + Ok(()) + } +} + +pub struct TestAssetLock; +impl AssetLock for TestAssetLock { + type LockTicket = TestTicket; + type UnlockTicket = TestTicket; + type ReduceTicket = TestTicket; + + fn prepare_lock( + unlocker: MultiLocation, + asset: MultiAsset, + owner: MultiLocation, + ) -> Result { + ensure!(assets(owner).contains_asset(&asset), LockError::AssetNotOwned); + Ok(TestTicket(LockTraceItem::Lock { unlocker, asset, owner })) + } + + fn prepare_unlock( + unlocker: MultiLocation, + asset: MultiAsset, + owner: MultiLocation, + ) -> Result { + ensure!(unlock_allowed(&unlocker, &asset, &owner), LockError::NotLocked); + Ok(TestTicket(LockTraceItem::Unlock { unlocker, asset, owner })) + } + + fn note_unlockable( + locker: MultiLocation, + asset: MultiAsset, + owner: MultiLocation, + ) -> Result<(), LockError> { + allow_request_unlock(locker, asset.clone(), owner); + let item = LockTraceItem::Note { locker, asset, owner }; + LOCK_TRACE.with(move |l| l.borrow_mut().push(item)); + Ok(()) + } + + fn prepare_reduce_unlockable( + locker: MultiLocation, + asset: MultiAsset, + owner: MultiLocation, + ) -> Result { + ensure!(request_unlock_allowed(&locker, &asset, &owner), LockError::NotLocked); + Ok(TestTicket(LockTraceItem::Reduce { locker, asset, owner })) + } +} + +thread_local! { + pub static EXCHANGE_ASSETS: RefCell = RefCell::new(Assets::new()); +} +pub fn set_exchange_assets(assets: impl Into) { + EXCHANGE_ASSETS.with(|a| a.replace(assets.into().into())); +} +pub fn exchange_assets() -> MultiAssets { + EXCHANGE_ASSETS.with(|a| a.borrow().clone().into()) +} +pub struct TestAssetExchange; +impl AssetExchange for TestAssetExchange { + fn exchange_asset( + _origin: Option<&MultiLocation>, + give: Assets, + want: &MultiAssets, + maximal: bool, + ) -> Result { + let mut have = EXCHANGE_ASSETS.with(|l| l.borrow().clone()); + ensure!(have.contains_assets(want), give); + let get = if maximal { + std::mem::replace(&mut have, Assets::new()) + } else { + have.saturating_take(want.clone().into()) + }; + have.subsume_assets(give); + EXCHANGE_ASSETS.with(|l| l.replace(have)); + Ok(get) + } +} + +match_types! { + pub type SiblingPrefix: impl Contains = { + MultiLocation { parents: 1, interior: X1(Parachain(_)) } + }; + pub type ChildPrefix: impl Contains = { + MultiLocation { parents: 0, interior: X1(Parachain(_)) } + }; + pub type ParentPrefix: impl Contains = { + MultiLocation { parents: 1, interior: Here } + }; +} + +pub struct TestConfig; +impl Config for TestConfig { + type RuntimeCall = TestCall; + type XcmSender = TestMessageSender; + type AssetTransactor = TestAssetTransactor; + type OriginConverter = TestOriginConverter; + type IsReserve = TestIsReserve; + type IsTeleporter = TestIsTeleporter; + type UniversalLocation = ExecutorUniversalLocation; + type Barrier = TrailingSetTopicAsId>; + type Weigher = FixedWeightBounds; + type Trader = FixedRateOfFungible; + type ResponseHandler = TestResponseHandler; + type AssetTrap = TestAssetTrap; + type AssetLocker = TestAssetLock; + type AssetExchanger = TestAssetExchange; + type AssetClaims = TestAssetTrap; + type SubscriptionService = TestSubscriptionService; + type PalletInstancesInfo = TestPalletsInfo; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = TestFeeManager; + type UniversalAliases = TestUniversalAliases; + type MessageExporter = TestMessageExporter; + type CallDispatcher = TestCall; + type SafeCallFilter = Everything; + type Aliasers = AliasForeignAccountId32; +} + +pub fn fungible_multi_asset(location: MultiLocation, amount: u128) -> MultiAsset { + (AssetId::from(location), Fungibility::Fungible(amount)).into() +} + +pub fn fake_message_hash(message: &Xcm) -> XcmHash { + message.using_encoded(sp_io::hashing::blake2_256) +} diff --git a/polkadot/xcm/xcm-builder/src/tests/mod.rs b/polkadot/xcm/xcm-builder/src/tests/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e11caf6282be70314d4245a413194f41c7e1082f --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/mod.rs @@ -0,0 +1,41 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::{test_utils::*, *}; +use core::convert::TryInto; +use frame_support::{ + assert_err, + traits::{ConstU32, ContainsPair, ProcessMessageError}, + weights::constants::{WEIGHT_PROOF_SIZE_PER_MB, WEIGHT_REF_TIME_PER_SECOND}, +}; +use xcm_executor::{traits::prelude::*, Config, XcmExecutor}; + +mod mock; +use mock::*; + +mod aliases; +mod assets; +mod barriers; +mod basic; +mod bridging; +mod expecting; +mod locking; +mod origins; +mod pay; +mod querying; +mod transacting; +mod version_subscriptions; +mod weight; diff --git a/polkadot/xcm/xcm-builder/src/tests/origins.rs b/polkadot/xcm/xcm-builder/src/tests/origins.rs new file mode 100644 index 0000000000000000000000000000000000000000..d3d6278eff8eb19f36b2e5c2964b8cd341595a1b --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/origins.rs @@ -0,0 +1,140 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +#[test] +fn universal_origin_should_work() { + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into(), X1(Parachain(2)).into()]); + clear_universal_aliases(); + // Parachain 1 may represent Kusama to us + add_universal_alias(Parachain(1), Kusama); + // Parachain 2 may represent Polkadot to us + add_universal_alias(Parachain(2), Polkadot); + + let message = Xcm(vec![ + UniversalOrigin(GlobalConsensus(Kusama)), + TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(2), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::InvalidLocation)); + + let message = Xcm(vec![ + UniversalOrigin(GlobalConsensus(Kusama)), + TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::NotWithdrawable)); + + add_asset((Ancestor(2), GlobalConsensus(Kusama)), (Parent, 100)); + let message = Xcm(vec![ + UniversalOrigin(GlobalConsensus(Kusama)), + TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(asset_list((Ancestor(2), GlobalConsensus(Kusama))), vec![]); +} + +#[test] +fn export_message_should_work() { + // Bridge chain (assumed to be Relay) lets Parachain #1 have message execution for free. + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + // Local parachain #1 issues a transfer asset on Polkadot Relay-chain, transfering 100 Planck to + // Polkadot parachain #2. + let expected_message = Xcm(vec![TransferAsset { + assets: (Here, 100u128).into(), + beneficiary: Parachain(2).into(), + }]); + let expected_hash = fake_message_hash(&expected_message); + let message = Xcm(vec![ExportMessage { + network: Polkadot, + destination: Here, + xcm: expected_message.clone(), + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + let uni_src = (ByGenesis([0; 32]), Parachain(42), Parachain(1)).into(); + assert_eq!( + exported_xcm(), + vec![(Polkadot, 403611790, uni_src, Here, expected_message, expected_hash)] + ); +} + +#[test] +fn unpaid_execution_should_work() { + // Bridge chain (assumed to be Relay) lets Parachain #1 have message execution for free. + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + // Bridge chain (assumed to be Relay) lets Parachain #2 have message execution for free if it + // asks. + AllowExplicitUnpaidFrom::set(vec![X1(Parachain(2)).into()]); + // Asking for unpaid execution of up to 9 weight on the assumption it is origin of #2. + let message = Xcm(vec![UnpaidExecution { + weight_limit: Limited(Weight::from_parts(9, 9)), + check_origin: Some(Parachain(2).into()), + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message.clone(), + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::BadOrigin)); + let r = XcmExecutor::::execute_xcm( + Parachain(2), + message.clone(), + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Error(XcmError::Barrier)); + + let message = Xcm(vec![UnpaidExecution { + weight_limit: Limited(Weight::from_parts(10, 10)), + check_origin: Some(Parachain(2).into()), + }]); + let r = XcmExecutor::::execute_xcm( + Parachain(2), + message.clone(), + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..c663b0a4d76f41b7e9a184f63202ace61376089a --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs @@ -0,0 +1,336 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +use frame_support::traits::{AsEnsureOriginWithArg, Nothing}; + +use frame_support::derive_impl; + +use frame_support::{ + construct_runtime, parameter_types, + traits::{ConstU32, Everything}, +}; +use frame_system::{EnsureRoot, EnsureSigned}; +use polkadot_test_runtime::SignedExtra; +use primitives::{AccountIndex, BlakeTwo256, Signature}; +use sp_runtime::{generic, traits::MaybeEquivalence, AccountId32, BuildStorage}; +use xcm_executor::{traits::ConvertLocation, XcmExecutor}; + +pub type Address = sp_runtime::MultiAddress; +pub type UncheckedExtrinsic = + generic::UncheckedExtrinsic; +pub type Header = generic::Header; +pub type Block = generic::Block; + +pub type BlockNumber = u32; +pub type AccountId = AccountId32; + +construct_runtime!( + pub struct Test { + System: frame_system, + Balances: pallet_balances, + Assets: pallet_assets, + Salary: pallet_salary, + XcmPallet: pallet_xcm, + } +); + +parameter_types! { + pub const BlockHashCount: BlockNumber = 250; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Test { + type Block = Block; + type BlockHashCount = BlockHashCount; + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type PalletInfo = PalletInfo; + type OnSetCode = (); + type AccountData = pallet_balances::AccountData; + type AccountId = AccountId; + type Lookup = sp_runtime::traits::IdentityLookup; +} + +pub type Balance = u128; + +parameter_types! { + pub const ExistentialDeposit: Balance = 1; +} + +impl pallet_balances::Config for Test { + type MaxLocks = ConstU32<0>; + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +parameter_types! { + pub const AssetDeposit: u128 = 1_000_000; + pub const MetadataDepositBase: u128 = 1_000_000; + pub const MetadataDepositPerByte: u128 = 100_000; + pub const AssetAccountDeposit: u128 = 1_000_000; + pub const ApprovalDeposit: u128 = 1_000_000; + pub const AssetsStringLimit: u32 = 50; + pub const RemoveItemsLimit: u32 = 50; +} + +impl pallet_assets::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type AssetId = AssetIdForAssets; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = EnsureRoot; + type AssetDeposit = AssetDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type AssetAccountDeposit = AssetAccountDeposit; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type WeightInfo = (); + type RemoveItemsLimit = RemoveItemsLimit; + type AssetIdParameter = AssetIdForAssets; + type CallbackHandle = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); +} + +parameter_types! { + pub const RelayLocation: MultiLocation = Here.into_location(); + pub const AnyNetwork: Option = None; + pub UniversalLocation: InteriorMultiLocation = (ByGenesis([0; 32]), Parachain(42)).into(); + pub UnitWeightCost: u64 = 1_000; + pub static AdvertisedXcmVersion: u32 = 3; + pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); + pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (Concrete(RelayLocation::get()), 1, 1); + pub TrustedAssets: (MultiAssetFilter, MultiLocation) = (All.into(), Here.into()); + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; + pub CheckingAccount: AccountId = XcmPallet::check_account(); +} + +type AssetIdForAssets = u128; + +pub struct FromMultiLocationToAsset( + core::marker::PhantomData<(MultiLocation, AssetId)>, +); +impl MaybeEquivalence + for FromMultiLocationToAsset +{ + fn convert(value: &MultiLocation) -> Option { + match value { + MultiLocation { parents: 0, interior: Here } => Some(0 as AssetIdForAssets), + MultiLocation { parents: 1, interior: Here } => Some(1 as AssetIdForAssets), + MultiLocation { parents: 0, interior: X2(PalletInstance(1), GeneralIndex(index)) } + if ![0, 1].contains(index) => + Some(*index as AssetIdForAssets), + _ => None, + } + } + + fn convert_back(value: &AssetIdForAssets) -> Option { + match value { + 0u128 => Some(MultiLocation { parents: 1, interior: Here }), + para_id @ 1..=1000 => + Some(MultiLocation { parents: 1, interior: X1(Parachain(*para_id as u32)) }), + _ => None, + } + } +} + +pub type LocalOriginToLocation = SignedToAccountId32; +pub type LocalAssetsTransactor = FungiblesAdapter< + Assets, + ConvertedConcreteId< + AssetIdForAssets, + Balance, + FromMultiLocationToAsset, + JustTry, + >, + SovereignAccountOf, + AccountId, + NoChecking, + CheckingAccount, +>; + +type OriginConverter = ( + pallet_xcm::XcmPassthrough, + SignedAccountId32AsNative, +); +type Barrier = AllowUnpaidExecutionFrom; + +pub struct DummyWeightTrader; +impl WeightTrader for DummyWeightTrader { + fn new() -> Self { + DummyWeightTrader + } + + fn buy_weight( + &mut self, + _weight: Weight, + _payment: xcm_executor::Assets, + _context: &XcmContext, + ) -> Result { + Ok(xcm_executor::Assets::default()) + } +} + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = TestMessageSender; + type AssetTransactor = LocalAssetsTransactor; + type OriginConverter = OriginConverter; + type IsReserve = (); + type IsTeleporter = (); + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = DummyWeightTrader; + type ResponseHandler = XcmPallet; + type AssetTrap = XcmPallet; + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = XcmPallet; + type SubscriptionService = XcmPallet; + type PalletInstancesInfo = (); + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; + type Aliasers = Nothing; +} + +parameter_types! { + pub TreasuryAccountId: AccountId = AccountId::new([42u8; 32]); +} + +pub struct TreasuryToAccount; +impl ConvertLocation for TreasuryToAccount { + fn convert_location(location: &MultiLocation) -> Option { + match location { + MultiLocation { + parents: 1, + interior: + X2(Parachain(42), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), + } => Some(TreasuryAccountId::get()), // Hardcoded test treasury account id + _ => None, + } + } +} + +type SovereignAccountOf = ( + AccountId32Aliases, + TreasuryToAccount, + HashedDescription>, +); + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parachain(1000).into()); +} + +impl pallet_xcm::Config for Test { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = TestMessageSender; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = AdvertisedXcmVersion; + type TrustedLockers = (); + type SovereignAccountOf = SovereignAccountOf; + type Currency = Balances; + type CurrencyMatcher = IsConcrete; + type MaxLockers = frame_support::traits::ConstU32<8>; + type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = pallet_xcm::TestWeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} + +pub const UNITS: Balance = 1_000_000_000_000; +pub const INITIAL_BALANCE: Balance = 100 * UNITS; +pub const MINIMUM_BALANCE: Balance = 1 * UNITS; + +pub fn sibling_chain_account_id(para_id: u32, account: [u8; 32]) -> AccountId { + let location: MultiLocation = + (Parent, Parachain(para_id), Junction::AccountId32 { id: account, network: None }).into(); + SovereignAccountOf::convert_location(&location).unwrap() +} + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let admin_account: AccountId = AccountId::new([0u8; 32]); + pallet_assets::GenesisConfig:: { + assets: vec![ + (0, admin_account.clone(), true, MINIMUM_BALANCE), + (1, admin_account.clone(), true, MINIMUM_BALANCE), + (100, admin_account.clone(), true, MINIMUM_BALANCE), + ], + metadata: vec![ + (0, "Native token".encode(), "NTV".encode(), 12), + (1, "Relay token".encode(), "RLY".encode(), 12), + (100, "Test token".encode(), "TST".encode(), 12), + ], + accounts: vec![ + (0, sibling_chain_account_id(42, [3u8; 32]), INITIAL_BALANCE), + (1, TreasuryAccountId::get(), INITIAL_BALANCE), + (100, TreasuryAccountId::get(), INITIAL_BALANCE), + ], + } + .assimilate_storage(&mut t) + .unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +pub fn next_block() { + System::set_block_number(System::block_number() + 1); +} + +pub fn run_to(block_number: BlockNumber) { + while System::block_number() < block_number { + next_block(); + } +} diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mod.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..8adf1ad2f5e1bed18ee6deccf495d4b01a1f58eb --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/pay/mod.rs @@ -0,0 +1,21 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +mod mock; +mod pay; +mod salary; diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs b/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs new file mode 100644 index 0000000000000000000000000000000000000000..28b2feec0c231438c94d8e890a41e855498f6ded --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs @@ -0,0 +1,158 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests for making sure `PayOverXcm::pay` generates the correct message and sends it to the +//! correct destination + +use super::{mock::*, *}; +use frame_support::{assert_ok, traits::tokens::Pay}; + +/// Type representing both a location and an asset that is held at that location. +/// The id of the held asset is relative to the location where it is being held. +#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq)] +pub struct AssetKind { + destination: MultiLocation, + asset_id: AssetId, +} + +pub struct LocatableAssetKindConverter; +impl sp_runtime::traits::Convert for LocatableAssetKindConverter { + fn convert(value: AssetKind) -> LocatableAssetId { + LocatableAssetId { asset_id: value.asset_id, location: value.destination } + } +} + +parameter_types! { + pub SenderAccount: AccountId = AccountId::new([3u8; 32]); + pub InteriorAccount: InteriorMultiLocation = AccountId32 { id: SenderAccount::get().into(), network: None }.into(); + pub InteriorBody: InteriorMultiLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); + pub Timeout: BlockNumber = 5; // 5 blocks +} + +/// Scenario: +/// Account #3 on the local chain, parachain 42, controls an amount of funds on parachain 2. +/// [`PayOverXcm::pay`] creates the correct message for account #3 to pay another account, account +/// #5, on parachain 2, remotely, in its native token. +#[test] +fn pay_over_xcm_works() { + let recipient = AccountId::new([5u8; 32]); + let asset_kind = + AssetKind { destination: (Parent, Parachain(2)).into(), asset_id: Here.into() }; + let amount = 10 * UNITS; + + new_test_ext().execute_with(|| { + // Check starting balance + assert_eq!(mock::Assets::balance(0, &recipient), 0); + + assert_ok!(PayOverXcm::< + InteriorAccount, + TestMessageSender, + TestQueryHandler, + Timeout, + AccountId, + AssetKind, + LocatableAssetKindConverter, + AliasesIntoAccountId32, + >::pay(&recipient, asset_kind, amount)); + + let expected_message = Xcm(vec![ + DescendOrigin(AccountId32 { id: SenderAccount::get().into(), network: None }.into()), + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + SetAppendix(Xcm(vec![ReportError(QueryResponseInfo { + destination: (Parent, Parachain(42)).into(), + query_id: 1, + max_weight: Weight::zero(), + })])), + TransferAsset { + assets: (Here, amount).into(), + beneficiary: AccountId32 { id: recipient.clone().into(), network: None }.into(), + }, + ]); + let expected_hash = fake_message_hash(&expected_message); + + assert_eq!( + sent_xcm(), + vec![((Parent, Parachain(2)).into(), expected_message, expected_hash)] + ); + + let (_, message, hash) = sent_xcm()[0].clone(); + let message = + Xcm::<::RuntimeCall>::from(message.clone()); + + // Execute message in parachain 2 with parachain 42's origin + let origin = (Parent, Parachain(42)); + XcmExecutor::::execute_xcm(origin, message, hash, Weight::MAX); + assert_eq!(mock::Assets::balance(0, &recipient), amount); + }); +} + +/// Scenario: +/// A pluralistic body, a Treasury, on the local chain, parachain 42, controls an amount of funds +/// on parachain 2. [`PayOverXcm::pay`] creates the correct message for the treasury to pay +/// another account, account #7, on parachain 2, remotely, in the relay's token. +#[test] +fn pay_over_xcm_governance_body() { + let recipient = AccountId::new([7u8; 32]); + let asset_kind = + AssetKind { destination: (Parent, Parachain(2)).into(), asset_id: Parent.into() }; + let amount = 10 * UNITS; + + let relay_asset_index = 1; + + new_test_ext().execute_with(|| { + // Check starting balance + assert_eq!(mock::Assets::balance(relay_asset_index, &recipient), 0); + + assert_ok!(PayOverXcm::< + InteriorBody, + TestMessageSender, + TestQueryHandler, + Timeout, + AccountId, + AssetKind, + LocatableAssetKindConverter, + AliasesIntoAccountId32, + >::pay(&recipient, asset_kind, amount)); + + let expected_message = Xcm(vec![ + DescendOrigin(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into()), + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + SetAppendix(Xcm(vec![ReportError(QueryResponseInfo { + destination: (Parent, Parachain(42)).into(), + query_id: 1, + max_weight: Weight::zero(), + })])), + TransferAsset { + assets: (Parent, amount).into(), + beneficiary: AccountId32 { id: recipient.clone().into(), network: None }.into(), + }, + ]); + let expected_hash = fake_message_hash(&expected_message); + assert_eq!( + sent_xcm(), + vec![((Parent, Parachain(2)).into(), expected_message, expected_hash)] + ); + + let (_, message, hash) = sent_xcm()[0].clone(); + let message = + Xcm::<::RuntimeCall>::from(message.clone()); + + // Execute message in parachain 2 with parachain 42's origin + let origin = (Parent, Parachain(42)); + XcmExecutor::::execute_xcm(origin, message, hash, Weight::MAX); + assert_eq!(mock::Assets::balance(relay_asset_index, &recipient), amount); + }); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs b/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs new file mode 100644 index 0000000000000000000000000000000000000000..1d40345f302abb725fac66da866b3a81ab73805c --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs @@ -0,0 +1,172 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests for the integration between `PayOverXcm` and the salary pallet + +use super::{mock::*, *}; + +use frame_support::{ + assert_ok, + traits::{tokens::GetSalary, RankedMembers}, +}; +use sp_runtime::{traits::ConvertToValue, DispatchResult}; + +parameter_types! { + pub Interior: InteriorMultiLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); + pub Timeout: BlockNumber = 5; + pub AssetHub: MultiLocation = (Parent, Parachain(1)).into(); + pub AssetIdGeneralIndex: u128 = 100; + pub AssetHubAssetId: AssetId = (PalletInstance(1), GeneralIndex(AssetIdGeneralIndex::get())).into(); + pub LocatableAsset: LocatableAssetId = LocatableAssetId { asset_id: AssetHubAssetId::get(), location: AssetHub::get() }; +} + +type SalaryPayOverXcm = PayOverXcm< + Interior, + TestMessageSender, + TestQueryHandler, + Timeout, + AccountId, + (), + ConvertToValue, + AliasesIntoAccountId32, +>; + +type Rank = u128; + +thread_local! { + pub static CLUB: RefCell> = RefCell::new(BTreeMap::new()); +} + +pub struct TestClub; +impl RankedMembers for TestClub { + type AccountId = AccountId; + type Rank = Rank; + + fn min_rank() -> Self::Rank { + 0 + } + fn rank_of(who: &Self::AccountId) -> Option { + CLUB.with(|club| club.borrow().get(who).cloned()) + } + fn induct(who: &Self::AccountId) -> DispatchResult { + CLUB.with(|club| club.borrow_mut().insert(who.clone(), 0)); + Ok(()) + } + fn promote(who: &Self::AccountId) -> DispatchResult { + CLUB.with(|club| { + club.borrow_mut().entry(who.clone()).and_modify(|rank| *rank += 1); + }); + Ok(()) + } + fn demote(who: &Self::AccountId) -> DispatchResult { + CLUB.with(|club| match club.borrow().get(who) { + None => Err(sp_runtime::DispatchError::Unavailable), + Some(&0) => { + club.borrow_mut().remove(&who); + Ok(()) + }, + Some(_) => { + club.borrow_mut().entry(who.clone()).and_modify(|rank| *rank += 1); + Ok(()) + }, + }) + } +} + +fn set_rank(who: AccountId, rank: u128) { + CLUB.with(|club| club.borrow_mut().insert(who, rank)); +} + +parameter_types! { + pub const RegistrationPeriod: BlockNumber = 2; + pub const PayoutPeriod: BlockNumber = 2; + pub const FixedSalaryAmount: Balance = 10 * UNITS; + pub static Budget: Balance = FixedSalaryAmount::get(); +} + +pub struct FixedSalary; +impl GetSalary for FixedSalary { + fn get_salary(_rank: Rank, _who: &AccountId) -> Balance { + FixedSalaryAmount::get() + } +} + +impl pallet_salary::Config for Test { + type WeightInfo = (); + type RuntimeEvent = RuntimeEvent; + type Paymaster = SalaryPayOverXcm; + type Members = TestClub; + type Salary = FixedSalary; + type RegistrationPeriod = RegistrationPeriod; + type PayoutPeriod = PayoutPeriod; + type Budget = Budget; +} + +/// Scenario: +/// The salary pallet is used to pay a member over XCM. +/// The correct XCM message is generated and when executed in the remote chain, +/// the member receives the salary. +#[test] +fn salary_pay_over_xcm_works() { + let recipient = AccountId::new([1u8; 32]); + + new_test_ext().execute_with(|| { + // Set the recipient as a member of a ranked collective + set_rank(recipient.clone(), 1); + + // Check starting balance + assert_eq!(mock::Assets::balance(AssetIdGeneralIndex::get(), &recipient.clone()), 0); + + // Use salary pallet to call `PayOverXcm::pay` + assert_ok!(Salary::init(RuntimeOrigin::signed(recipient.clone()))); + run_to(5); + assert_ok!(Salary::induct(RuntimeOrigin::signed(recipient.clone()))); + assert_ok!(Salary::bump(RuntimeOrigin::signed(recipient.clone()))); + assert_ok!(Salary::register(RuntimeOrigin::signed(recipient.clone()))); + run_to(7); + assert_ok!(Salary::payout(RuntimeOrigin::signed(recipient.clone()))); + + // Get message from mock transport layer + let (_, message, hash) = sent_xcm()[0].clone(); + // Change type from `Xcm<()>` to `Xcm` to be able to execute later + let message = + Xcm::<::RuntimeCall>::from(message.clone()); + + let expected_message: Xcm = Xcm::(vec![ + DescendOrigin(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into()), + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + SetAppendix(Xcm(vec![ReportError(QueryResponseInfo { + destination: (Parent, Parachain(42)).into(), + query_id: 1, + max_weight: Weight::zero(), + })])), + TransferAsset { + assets: (AssetHubAssetId::get(), FixedSalaryAmount::get()).into(), + beneficiary: AccountId32 { id: recipient.clone().into(), network: None }.into(), + }, + ]); + assert_eq!(message, expected_message); + + // Execute message as the asset hub + XcmExecutor::::execute_xcm((Parent, Parachain(42)), message, hash, Weight::MAX); + + // Recipient receives the payment + assert_eq!( + mock::Assets::balance(AssetIdGeneralIndex::get(), &recipient), + FixedSalaryAmount::get() + ); + }); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/querying.rs b/polkadot/xcm/xcm-builder/src/tests/querying.rs new file mode 100644 index 0000000000000000000000000000000000000000..8fbb55eb25423908194cf891794b6632348c5bd8 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/querying.rs @@ -0,0 +1,120 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +#[test] +fn pallet_query_should_work() { + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 + // and let them know to hand it to account #3. + let message = Xcm(vec![QueryPallet { + module_name: "Error".into(), + response_info: QueryResponseInfo { + destination: Parachain(1).into(), + query_id: 1, + max_weight: Weight::from_parts(50, 50), + }, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + + let expected_msg = Xcm::<()>(vec![QueryResponse { + query_id: 1, + max_weight: Weight::from_parts(50, 50), + response: Response::PalletsInfo(Default::default()), + querier: Some(Here.into()), + }]); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!(sent_xcm(), vec![(Parachain(1).into(), expected_msg, expected_hash)]); +} + +#[test] +fn pallet_query_with_results_should_work() { + AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 + // and let them know to hand it to account #3. + let message = Xcm(vec![QueryPallet { + module_name: "pallet_balances".into(), + response_info: QueryResponseInfo { + destination: Parachain(1).into(), + query_id: 1, + max_weight: Weight::from_parts(50, 50), + }, + }]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm( + Parachain(1), + message, + hash, + Weight::from_parts(50, 50), + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + + let expected_msg = Xcm::<()>(vec![QueryResponse { + query_id: 1, + max_weight: Weight::from_parts(50, 50), + response: Response::PalletsInfo( + vec![PalletInfo::new( + 1, + b"Balances".as_ref().into(), + b"pallet_balances".as_ref().into(), + 1, + 42, + 69, + ) + .unwrap()] + .try_into() + .unwrap(), + ), + querier: Some(Here.into()), + }]); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!(sent_xcm(), vec![(Parachain(1).into(), expected_msg, expected_hash)]); +} + +#[test] +fn prepaid_result_of_query_should_get_free_execution() { + let query_id = 33; + // We put this in manually here, but normally this would be done at the point of crafting the + // message. + expect_response(query_id, Parent.into()); + + let the_response = Response::Assets((Parent, 100u128).into()); + let message = Xcm::(vec![QueryResponse { + query_id, + response: the_response.clone(), + max_weight: Weight::from_parts(10, 10), + querier: Some(Here.into()), + }]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(10, 10); + + // First time the response gets through since we're expecting it... + let r = XcmExecutor::::execute_xcm(Parent, message.clone(), hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(response(query_id).unwrap(), the_response); + + // Second time it doesn't, since we're not. + let r = XcmExecutor::::execute_xcm(Parent, message.clone(), hash, weight_limit); + assert_eq!(r, Outcome::Error(XcmError::Barrier)); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/transacting.rs b/polkadot/xcm/xcm-builder/src/tests/transacting.rs new file mode 100644 index 0000000000000000000000000000000000000000..743ad7039f7ff30497fd14b4feed6775c6450d1c --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/transacting.rs @@ -0,0 +1,250 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +#[test] +fn transacting_should_work() { + AllowUnpaidFrom::set(vec![Parent.into()]); + + let message = Xcm::(vec![Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(50, 50), + call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), + }]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(60, 60); + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(60, 60))); +} + +#[test] +fn transacting_should_respect_max_weight_requirement() { + AllowUnpaidFrom::set(vec![Parent.into()]); + + let message = Xcm::(vec![Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(40, 40), + call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), + }]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(60, 60); + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(50, 50), XcmError::MaxWeightInvalid)); +} + +#[test] +fn transacting_should_refund_weight() { + AllowUnpaidFrom::set(vec![Parent.into()]); + + let message = Xcm::(vec![Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(50, 50), + call: TestCall::Any(Weight::from_parts(50, 50), Some(Weight::from_parts(30, 30))) + .encode() + .into(), + }]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(60, 60); + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); +} + +#[test] +fn paid_transacting_should_refund_payment_for_unused_weight() { + let one: MultiLocation = AccountIndex64 { index: 1, network: None }.into(); + AllowPaidFrom::set(vec![one]); + add_asset(AccountIndex64 { index: 1, network: None }, (Parent, 200u128)); + WeightPrice::set((Parent.into(), 1_000_000_000_000, 1024 * 1024)); + + let origin = one; + let fees = (Parent, 200u128).into(); + let message = Xcm::(vec![ + WithdrawAsset((Parent, 200u128).into()), // enough for 200 units of weight. + BuyExecution { fees, weight_limit: Limited(Weight::from_parts(100, 100)) }, + Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(50, 50), + // call estimated at 50 but only takes 10. + call: TestCall::Any(Weight::from_parts(50, 50), Some(Weight::from_parts(10, 10))) + .encode() + .into(), + }, + RefundSurplus, + DepositAsset { assets: AllCounted(1).into(), beneficiary: one }, + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(100, 100); + let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(60, 60))); + assert_eq!( + asset_list(AccountIndex64 { index: 1, network: None }), + vec![(Parent, 80u128).into()] + ); +} + +#[test] +fn report_successful_transact_status_should_work() { + AllowUnpaidFrom::set(vec![Parent.into()]); + + let message = Xcm::(vec![ + Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(50, 50), + call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), + }, + ReportTransactStatus(QueryResponseInfo { + destination: Parent.into(), + query_id: 42, + max_weight: Weight::from_parts(5000, 5000), + }), + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(70, 70); + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let expected_msg = Xcm(vec![QueryResponse { + response: Response::DispatchResult(MaybeErrorCode::Success), + query_id: 42, + max_weight: Weight::from_parts(5000, 5000), + querier: Some(Here.into()), + }]); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!(sent_xcm(), vec![(Parent.into(), expected_msg, expected_hash)]); +} + +#[test] +fn report_failed_transact_status_should_work() { + AllowUnpaidFrom::set(vec![Parent.into()]); + + let message = Xcm::(vec![ + Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(50, 50), + call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(), + }, + ReportTransactStatus(QueryResponseInfo { + destination: Parent.into(), + query_id: 42, + max_weight: Weight::from_parts(5000, 5000), + }), + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(70, 70); + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let expected_msg = Xcm(vec![QueryResponse { + response: Response::DispatchResult(vec![2].into()), + query_id: 42, + max_weight: Weight::from_parts(5000, 5000), + querier: Some(Here.into()), + }]); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!(sent_xcm(), vec![(Parent.into(), expected_msg, expected_hash)]); +} + +#[test] +fn expect_successful_transact_status_should_work() { + AllowUnpaidFrom::set(vec![Parent.into()]); + + let message = Xcm::(vec![ + Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(50, 50), + call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success), + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(70, 70); + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + + let message = Xcm::(vec![ + Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(50, 50), + call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success), + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(70, 70); + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(70, 70), XcmError::ExpectationFalse)); +} + +#[test] +fn expect_failed_transact_status_should_work() { + AllowUnpaidFrom::set(vec![Parent.into()]); + + let message = Xcm::(vec![ + Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(50, 50), + call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(), + }, + ExpectTransactStatus(vec![2].into()), + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(70, 70); + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + + let message = Xcm::(vec![ + Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(50, 50), + call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), + }, + ExpectTransactStatus(vec![2].into()), + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(70, 70); + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(70, 70), XcmError::ExpectationFalse)); +} + +#[test] +fn clear_transact_status_should_work() { + AllowUnpaidFrom::set(vec![Parent.into()]); + + let message = Xcm::(vec![ + Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(50, 50), + call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(), + }, + ClearTransactStatus, + ReportTransactStatus(QueryResponseInfo { + destination: Parent.into(), + query_id: 42, + max_weight: Weight::from_parts(5000, 5000), + }), + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(80, 80); + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(80, 80))); + let expected_msg = Xcm(vec![QueryResponse { + response: Response::DispatchResult(MaybeErrorCode::Success), + query_id: 42, + max_weight: Weight::from_parts(5000, 5000), + querier: Some(Here.into()), + }]); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!(sent_xcm(), vec![(Parent.into(), expected_msg, expected_hash)]); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs b/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs new file mode 100644 index 0000000000000000000000000000000000000000..44ab7d34c51bbfc619bb66b08c094775191029d7 --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs @@ -0,0 +1,149 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +#[test] +fn simple_version_subscriptions_should_work() { + AllowSubsFrom::set(vec![Parent.into()]); + + let origin = Parachain(1000); + let message = Xcm::(vec![ + SetAppendix(Xcm(vec![])), + SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(20, 20); + let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); + assert_eq!(r, Outcome::Error(XcmError::Barrier)); + + let origin = Parachain(1000); + let message = Xcm::(vec![SubscribeVersion { + query_id: 42, + max_response_weight: Weight::from_parts(5000, 5000), + }]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(10, 10); + let r = XcmExecutor::::execute_xcm(origin, message.clone(), hash, weight_limit); + assert_eq!(r, Outcome::Error(XcmError::Barrier)); + + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + + assert_eq!( + SubscriptionRequests::get(), + vec![(Parent.into(), Some((42, Weight::from_parts(5000, 5000))))] + ); +} + +#[test] +fn version_subscription_instruction_should_work() { + let origin = Parachain(1000); + let message = Xcm::(vec![ + DescendOrigin(X1(AccountIndex64 { index: 1, network: None })), + SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(20, 20); + let r = XcmExecutor::::execute_xcm_in_credit( + origin, + message, + hash, + weight_limit, + weight_limit, + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::BadOrigin)); + + let message = Xcm::(vec![ + SetAppendix(Xcm(vec![])), + SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm_in_credit( + origin, + message, + hash, + weight_limit, + weight_limit, + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + + assert_eq!( + SubscriptionRequests::get(), + vec![(Parachain(1000).into(), Some((42, Weight::from_parts(5000, 5000))))] + ); +} + +#[test] +fn simple_version_unsubscriptions_should_work() { + AllowSubsFrom::set(vec![Parent.into()]); + + let origin = Parachain(1000); + let message = Xcm::(vec![SetAppendix(Xcm(vec![])), UnsubscribeVersion]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(20, 20); + let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); + assert_eq!(r, Outcome::Error(XcmError::Barrier)); + + let origin = Parachain(1000); + let message = Xcm::(vec![UnsubscribeVersion]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(10, 10); + let r = XcmExecutor::::execute_xcm(origin, message.clone(), hash, weight_limit); + assert_eq!(r, Outcome::Error(XcmError::Barrier)); + + let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + + assert_eq!(SubscriptionRequests::get(), vec![(Parent.into(), None)]); + assert_eq!(sent_xcm(), vec![]); +} + +#[test] +fn version_unsubscription_instruction_should_work() { + let origin = Parachain(1000); + + // Not allowed to do it when origin has been changed. + let message = Xcm::(vec![ + DescendOrigin(X1(AccountIndex64 { index: 1, network: None })), + UnsubscribeVersion, + ]); + let hash = fake_message_hash(&message); + let weight_limit = Weight::from_parts(20, 20); + let r = XcmExecutor::::execute_xcm_in_credit( + origin, + message, + hash, + weight_limit, + weight_limit, + ); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::BadOrigin)); + + // Fine to do it when origin is untouched. + let message = Xcm::(vec![SetAppendix(Xcm(vec![])), UnsubscribeVersion]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm_in_credit( + origin, + message, + hash, + weight_limit, + weight_limit, + ); + assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + + assert_eq!(SubscriptionRequests::get(), vec![(Parachain(1000).into(), None)]); + assert_eq!(sent_xcm(), vec![]); +} diff --git a/polkadot/xcm/xcm-builder/src/tests/weight.rs b/polkadot/xcm/xcm-builder/src/tests/weight.rs new file mode 100644 index 0000000000000000000000000000000000000000..a2fb265413f546f519e2f11661579fb93b078baa --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/tests/weight.rs @@ -0,0 +1,206 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use super::*; + +#[test] +fn fixed_rate_of_fungible_should_work() { + parameter_types! { + pub static WeightPrice: (AssetId, u128, u128) = + (Here.into(), WEIGHT_REF_TIME_PER_SECOND.into(), WEIGHT_PROOF_SIZE_PER_MB.into()); + } + + let mut trader = FixedRateOfFungible::::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // supplies 100 unit of asset, 80 still remains after purchasing weight + assert_eq!( + trader.buy_weight( + Weight::from_parts(10, 10), + fungible_multi_asset(Here.into(), 100).into(), + &ctx, + ), + Ok(fungible_multi_asset(Here.into(), 80).into()), + ); + // should have nothing left, as 5 + 5 = 10, and we supplied 10 units of asset. + assert_eq!( + trader.buy_weight( + Weight::from_parts(5, 5), + fungible_multi_asset(Here.into(), 10).into(), + &ctx, + ), + Ok(vec![].into()), + ); + // should have 5 left, as there are no proof size components + assert_eq!( + trader.buy_weight( + Weight::from_parts(5, 0), + fungible_multi_asset(Here.into(), 10).into(), + &ctx, + ), + Ok(fungible_multi_asset(Here.into(), 5).into()), + ); + // not enough to purchase the combined weights + assert_err!( + trader.buy_weight( + Weight::from_parts(5, 5), + fungible_multi_asset(Here.into(), 5).into(), + &ctx, + ), + XcmError::TooExpensive, + ); +} + +#[test] +fn errors_should_return_unused_weight() { + // we'll let them have message execution for free. + AllowUnpaidFrom::set(vec![Here.into()]); + // We own 1000 of our tokens. + add_asset(Here, (Here, 11u128)); + let mut message = Xcm(vec![ + // First xfer results in an error on the last message only + TransferAsset { + assets: (Here, 1u128).into(), + beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + }, + // Second xfer results in error third message and after + TransferAsset { + assets: (Here, 2u128).into(), + beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + }, + // Third xfer results in error second message and after + TransferAsset { + assets: (Here, 4u128).into(), + beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + }, + ]); + // Weight limit of 70 is needed. + let limit = ::Weigher::weight(&mut message).unwrap(); + assert_eq!(limit, Weight::from_parts(30, 30)); + + let hash = fake_message_hash(&message); + + let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); + assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 7u128).into()]); + assert_eq!(asset_list(Here), vec![(Here, 4u128).into()]); + assert_eq!(sent_xcm(), vec![]); + + let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(30, 30), XcmError::NotWithdrawable)); + assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 10u128).into()]); + assert_eq!(asset_list(Here), vec![(Here, 1u128).into()]); + assert_eq!(sent_xcm(), vec![]); + + let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::NotWithdrawable)); + assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 11u128).into()]); + assert_eq!(asset_list(Here), vec![]); + assert_eq!(sent_xcm(), vec![]); + + let r = XcmExecutor::::execute_xcm(Here, message, hash, limit); + assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotWithdrawable)); + assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 11u128).into()]); + assert_eq!(asset_list(Here), vec![]); + assert_eq!(sent_xcm(), vec![]); +} + +#[test] +fn weight_bounds_should_respect_instructions_limit() { + MaxInstructions::set(3); + let mut message = Xcm(vec![ClearOrigin; 4]); + // 4 instructions are too many. + assert_eq!(::Weigher::weight(&mut message), Err(())); + + let mut message = + Xcm(vec![SetErrorHandler(Xcm(vec![ClearOrigin])), SetAppendix(Xcm(vec![ClearOrigin]))]); + // 4 instructions are too many, even when hidden within 2. + assert_eq!(::Weigher::weight(&mut message), Err(())); + + let mut message = + Xcm(vec![SetErrorHandler(Xcm(vec![SetErrorHandler(Xcm(vec![SetErrorHandler(Xcm( + vec![ClearOrigin], + ))]))]))]); + // 4 instructions are too many, even when it's just one that's 3 levels deep. + assert_eq!(::Weigher::weight(&mut message), Err(())); + + let mut message = + Xcm(vec![SetErrorHandler(Xcm(vec![SetErrorHandler(Xcm(vec![ClearOrigin]))]))]); + // 3 instructions are OK. + assert_eq!( + ::Weigher::weight(&mut message), + Ok(Weight::from_parts(30, 30)) + ); +} + +#[test] +fn weight_trader_tuple_should_work() { + let para_1: MultiLocation = Parachain(1).into(); + let para_2: MultiLocation = Parachain(2).into(); + + parameter_types! { + pub static HereWeightPrice: (AssetId, u128, u128) = + (Here.into(), WEIGHT_REF_TIME_PER_SECOND.into(), WEIGHT_PROOF_SIZE_PER_MB.into()); + pub static Para1WeightPrice: (AssetId, u128, u128) = + (Parachain(1).into(), WEIGHT_REF_TIME_PER_SECOND.into(), WEIGHT_PROOF_SIZE_PER_MB.into()); + } + + type Traders = ( + // trader one + FixedRateOfFungible, + // trader two + FixedRateOfFungible, + ); + + let mut traders = Traders::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // trader one buys weight + assert_eq!( + traders.buy_weight( + Weight::from_parts(5, 5), + fungible_multi_asset(Here.into(), 10).into(), + &ctx + ), + Ok(vec![].into()), + ); + // trader one refunds + assert_eq!( + traders.refund_weight(Weight::from_parts(2, 2), &ctx), + Some(fungible_multi_asset(Here.into(), 4)) + ); + + let mut traders = Traders::new(); + // trader one failed; trader two buys weight + assert_eq!( + traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(para_1, 10).into(), &ctx), + Ok(vec![].into()), + ); + // trader two refunds + assert_eq!( + traders.refund_weight(Weight::from_parts(2, 2), &ctx), + Some(fungible_multi_asset(para_1, 4)) + ); + + let mut traders = Traders::new(); + // all traders fails + assert_err!( + traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(para_2, 10).into(), &ctx), + XcmError::TooExpensive, + ); + // and no refund + assert_eq!(traders.refund_weight(Weight::from_parts(2, 2), &ctx), None); +} diff --git a/polkadot/xcm/xcm-builder/src/universal_exports.rs b/polkadot/xcm/xcm-builder/src/universal_exports.rs new file mode 100644 index 0000000000000000000000000000000000000000..0ee627e0ee903d56b81a1b1f22ce80dd2b3a0fdc --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/universal_exports.rs @@ -0,0 +1,455 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Traits and utilities to help with origin mutation and bridging. + +use frame_support::{ensure, traits::Get}; +use parity_scale_codec::{Decode, Encode}; +use sp_std::{convert::TryInto, marker::PhantomData, prelude::*}; +use xcm::prelude::*; +use xcm_executor::traits::{validate_export, ExportXcm}; +use SendError::*; + +/// Returns the network ID and consensus location within that network of the remote +/// location `dest` which is itself specified as a location relative to the local +/// chain, itself situated at `universal_local` within the consensus universe. If +/// `dest` is not a location in remote consensus, then an error is returned. +pub fn ensure_is_remote( + universal_local: impl Into, + dest: impl Into, +) -> Result<(NetworkId, InteriorMultiLocation), MultiLocation> { + let dest = dest.into(); + let universal_local = universal_local.into(); + let local_net = match universal_local.global_consensus() { + Ok(x) => x, + Err(_) => return Err(dest), + }; + let universal_destination: InteriorMultiLocation = universal_local + .into_location() + .appended_with(dest) + .map_err(|x| x.1)? + .try_into()?; + let (remote_dest, remote_net) = match universal_destination.split_first() { + (d, Some(GlobalConsensus(n))) if n != local_net => (d, n), + _ => return Err(dest), + }; + Ok((remote_net, remote_dest)) +} + +/// Implementation of `SendXcm` which uses the given `ExportXcm` implementation in order to forward +/// the message over a bridge. +/// +/// No effort is made to charge for any bridge fees, so this can only be used when it is known +/// that the message sending cannot be abused in any way. +/// +/// This is only useful when the local chain has bridging capabilities. +pub struct UnpaidLocalExporter( + PhantomData<(Exporter, UniversalLocation)>, +); +impl> SendXcm + for UnpaidLocalExporter +{ + type Ticket = Exporter::Ticket; + + fn validate( + dest: &mut Option, + xcm: &mut Option>, + ) -> SendResult { + let d = dest.take().ok_or(MissingArgument)?; + let universal_source = UniversalLocation::get(); + let devolved = match ensure_is_remote(universal_source, d) { + Ok(x) => x, + Err(d) => { + *dest = Some(d); + return Err(NotApplicable) + }, + }; + let (network, destination) = devolved; + let xcm = xcm.take().ok_or(SendError::MissingArgument)?; + validate_export::(network, 0, universal_source, destination, xcm) + } + + fn deliver(ticket: Exporter::Ticket) -> Result { + Exporter::deliver(ticket) + } +} + +pub trait ExporterFor { + /// Return the locally-routable bridge (if any) capable of forwarding `message` to the + /// `remote_location` on the remote `network`, together with the payment which is required. + /// + /// The payment is specified from the local context, not the bridge chain. This is the + /// total amount to withdraw in to Holding and should cover both payment for the execution on + /// the bridge chain as well as payment for the use of the `ExportMessage` instruction. + fn exporter_for( + network: &NetworkId, + remote_location: &InteriorMultiLocation, + message: &Xcm<()>, + ) -> Option<(MultiLocation, Option)>; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl ExporterFor for Tuple { + fn exporter_for( + network: &NetworkId, + remote_location: &InteriorMultiLocation, + message: &Xcm<()>, + ) -> Option<(MultiLocation, Option)> { + for_tuples!( #( + if let Some(r) = Tuple::exporter_for(network, remote_location, message) { + return Some(r); + } + )* ); + None + } +} + +pub struct NetworkExportTable(sp_std::marker::PhantomData); +impl)>>> ExporterFor + for NetworkExportTable +{ + fn exporter_for( + network: &NetworkId, + _: &InteriorMultiLocation, + _: &Xcm<()>, + ) -> Option<(MultiLocation, Option)> { + T::get().into_iter().find(|(ref j, ..)| j == network).map(|(_, l, p)| (l, p)) + } +} + +pub fn forward_id_for(original_id: &XcmHash) -> XcmHash { + (b"forward_id_for", original_id).using_encoded(sp_io::hashing::blake2_256) +} + +/// Implementation of `SendXcm` which wraps the message inside an `ExportMessage` instruction +/// and sends it to a destination known to be able to handle it. +/// +/// No effort is made to make payment to the bridge for its services, so the bridge location +/// must have been configured with a barrier rule allowing unpaid execution for this message +/// coming from our origin. +/// +/// This is only useful if we have special dispensation by the remote bridges to have the +/// `ExportMessage` instruction executed without payment. +/// +/// The `XcmHash` value returned by `deliver` will always be the same as that returned by the +/// message exporter (`Bridges`). Generally this should take notice of the message should it +/// end with the `SetTopic` instruction. +/// +/// In the case that the message ends with a `SetTopic(T)` (as should be the case if the top-level +/// router is `EnsureUniqueTopic`), then the forwarding message (i.e. the one carrying the +/// export instruction *to* the bridge in local consensus) will also end with a `SetTopic` whose +/// inner is `forward_id_for(T)`. If this is not the case then the onward message will not be given +/// the `SetTopic` afterword. +pub struct UnpaidRemoteExporter( + PhantomData<(Bridges, Router, UniversalLocation)>, +); +impl> SendXcm + for UnpaidRemoteExporter +{ + type Ticket = Router::Ticket; + + fn validate( + dest: &mut Option, + xcm: &mut Option>, + ) -> SendResult { + let d = dest.ok_or(MissingArgument)?; + let devolved = ensure_is_remote(UniversalLocation::get(), d).map_err(|_| NotApplicable)?; + let (remote_network, remote_location) = devolved; + let xcm = xcm.take().ok_or(MissingArgument)?; + + let (bridge, maybe_payment) = + Bridges::exporter_for(&remote_network, &remote_location, &xcm).ok_or(NotApplicable)?; + ensure!(maybe_payment.is_none(), Unroutable); + + // `xcm` should already end with `SetTopic` - if it does, then extract and derive into + // an onward topic ID. + let maybe_forward_id = match xcm.last() { + Some(SetTopic(t)) => Some(forward_id_for(t)), + _ => None, + }; + + // We then send a normal message to the bridge asking it to export the prepended + // message to the remote chain. This will only work if the bridge will do the message + // export for free. Common-good chains will typically be afforded this. + let mut message = Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + ExportMessage { network: remote_network, destination: remote_location, xcm }, + ]); + if let Some(forward_id) = maybe_forward_id { + message.0.push(SetTopic(forward_id)); + } + validate_send::(bridge, message) + } + + fn deliver(validation: Self::Ticket) -> Result { + Router::deliver(validation) + } +} + +/// Implementation of `SendXcm` which wraps the message inside an `ExportMessage` instruction +/// and sends it to a destination known to be able to handle it. +/// +/// The `ExportMessage` instruction on the bridge is paid for from the local chain's sovereign +/// account on the bridge. The amount paid is determined through the `ExporterFor` trait. +/// +/// The `XcmHash` value returned by `deliver` will always be the same as that returned by the +/// message exporter (`Bridges`). Generally this should take notice of the message should it +/// end with the `SetTopic` instruction. +/// +/// In the case that the message ends with a `SetTopic(T)` (as should be the case if the top-level +/// router is `EnsureUniqueTopic`), then the forwarding message (i.e. the one carrying the +/// export instruction *to* the bridge in local consensus) will also end with a `SetTopic` whose +/// inner is `forward_id_for(T)`. If this is not the case then the onward message will not be given +/// the `SetTopic` afterword. +pub struct SovereignPaidRemoteExporter( + PhantomData<(Bridges, Router, UniversalLocation)>, +); +impl> SendXcm + for SovereignPaidRemoteExporter +{ + type Ticket = Router::Ticket; + + fn validate( + dest: &mut Option, + xcm: &mut Option>, + ) -> SendResult { + let d = *dest.as_ref().ok_or(MissingArgument)?; + let devolved = ensure_is_remote(UniversalLocation::get(), d).map_err(|_| NotApplicable)?; + let (remote_network, remote_location) = devolved; + + let xcm = xcm.take().ok_or(MissingArgument)?; + + // `xcm` should already end with `SetTopic` - if it does, then extract and derive into + // an onward topic ID. + let maybe_forward_id = match xcm.last() { + Some(SetTopic(t)) => Some(forward_id_for(t)), + _ => None, + }; + + let (bridge, maybe_payment) = + Bridges::exporter_for(&remote_network, &remote_location, &xcm).ok_or(NotApplicable)?; + + let local_from_bridge = + UniversalLocation::get().invert_target(&bridge).map_err(|_| Unroutable)?; + let export_instruction = + ExportMessage { network: remote_network, destination: remote_location, xcm }; + + let mut message = Xcm(if let Some(ref payment) = maybe_payment { + let fees = payment + .clone() + .reanchored(&bridge, UniversalLocation::get()) + .map_err(|_| Unroutable)?; + vec![ + WithdrawAsset(fees.clone().into()), + BuyExecution { fees, weight_limit: Unlimited }, + export_instruction, + RefundSurplus, + DepositAsset { assets: All.into(), beneficiary: local_from_bridge }, + ] + } else { + vec![export_instruction] + }); + if let Some(forward_id) = maybe_forward_id { + message.0.push(SetTopic(forward_id)); + } + + // We then send a normal message to the bridge asking it to export the prepended + // message to the remote chain. + let (v, mut cost) = validate_send::(bridge, message)?; + if let Some(bridge_payment) = maybe_payment { + cost.push(bridge_payment); + } + Ok((v, cost)) + } + + fn deliver(ticket: Router::Ticket) -> Result { + Router::deliver(ticket) + } +} + +pub trait DispatchBlob { + /// Takes an incoming blob from over some point-to-point link (usually from some sort of + /// inter-consensus bridge) and then does what needs to be done with it. Usually this means + /// forwarding it on into some other location sharing our consensus or possibly just enqueuing + /// it for execution locally if it is destined for the local chain. + /// + /// NOTE: The API does not provide for any kind of weight or fee management; the size of the + /// `blob` is known to the caller and so the operation must have a linear weight relative to + /// `blob`'s length. This means that you will generally only want to **enqueue** the blob, not + /// enact it. Fees must be handled by the caller. + fn dispatch_blob(blob: Vec) -> Result<(), DispatchBlobError>; +} + +pub trait HaulBlob { + /// Sends a blob over some point-to-point link. This will generally be implemented by a bridge. + fn haul_blob(blob: Vec) -> Result<(), HaulBlobError>; +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum HaulBlobError { + /// Represents point-to-point link failure with a human-readable explanation of the specific + /// issue is provided. + Transport(&'static str), +} + +impl From for SendError { + fn from(err: HaulBlobError) -> Self { + match err { + HaulBlobError::Transport(reason) => SendError::Transport(reason), + } + } +} + +#[derive(Clone, Encode, Decode)] +pub struct BridgeMessage { + /// The message destination as a *Universal Location*. This means it begins with a + /// `GlobalConsensus` junction describing the network under which global consensus happens. + /// If this does not match our global consensus then it's a fatal error. + universal_dest: VersionedInteriorMultiLocation, + message: VersionedXcm<()>, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum DispatchBlobError { + Unbridgable, + InvalidEncoding, + UnsupportedLocationVersion, + UnsupportedXcmVersion, + RoutingError, + NonUniversalDestination, + WrongGlobal, +} + +pub struct BridgeBlobDispatcher( + PhantomData<(Router, OurPlace, OurPlaceBridgeInstance)>, +); +impl< + Router: SendXcm, + OurPlace: Get, + OurPlaceBridgeInstance: Get>, + > DispatchBlob for BridgeBlobDispatcher +{ + fn dispatch_blob(blob: Vec) -> Result<(), DispatchBlobError> { + let our_universal = OurPlace::get(); + let our_global = + our_universal.global_consensus().map_err(|()| DispatchBlobError::Unbridgable)?; + let BridgeMessage { universal_dest, message } = + Decode::decode(&mut &blob[..]).map_err(|_| DispatchBlobError::InvalidEncoding)?; + let universal_dest: InteriorMultiLocation = universal_dest + .try_into() + .map_err(|_| DispatchBlobError::UnsupportedLocationVersion)?; + // `universal_dest` is the desired destination within the universe: first we need to check + // we're in the right global consensus. + let intended_global = universal_dest + .global_consensus() + .map_err(|()| DispatchBlobError::NonUniversalDestination)?; + ensure!(intended_global == our_global, DispatchBlobError::WrongGlobal); + let dest = universal_dest.relative_to(&our_universal); + let mut message: Xcm<()> = + message.try_into().map_err(|_| DispatchBlobError::UnsupportedXcmVersion)?; + + // Prepend our bridge instance discriminator. + // Can be used for fine-grained control of origin on destination in case of multiple bridge + // instances, e.g. restrict `type UniversalAliases` and `UniversalOrigin` instruction to + // trust just particular bridge instance for `NetworkId`. + if let Some(bridge_instance) = OurPlaceBridgeInstance::get() { + message.0.insert(0, DescendOrigin(bridge_instance)); + } + + let _ = send_xcm::(dest, message).map_err(|_| DispatchBlobError::RoutingError)?; + Ok(()) + } +} + +pub struct HaulBlobExporter( + PhantomData<(Bridge, BridgedNetwork, Price)>, +); +impl, Price: Get> ExportXcm + for HaulBlobExporter +{ + type Ticket = (Vec, XcmHash); + + fn validate( + network: NetworkId, + _channel: u32, + universal_source: &mut Option, + destination: &mut Option, + message: &mut Option>, + ) -> Result<((Vec, XcmHash), MultiAssets), SendError> { + let bridged_network = BridgedNetwork::get(); + ensure!(&network == &bridged_network, SendError::NotApplicable); + // We don't/can't use the `channel` for this adapter. + let dest = destination.take().ok_or(SendError::MissingArgument)?; + let universal_dest = match dest.pushed_front_with(GlobalConsensus(bridged_network)) { + Ok(d) => d.into(), + Err((dest, _)) => { + *destination = Some(dest); + return Err(SendError::NotApplicable) + }, + }; + let (local_net, local_sub) = universal_source + .take() + .ok_or(SendError::MissingArgument)? + .split_global() + .map_err(|()| SendError::Unroutable)?; + let mut message = message.take().ok_or(SendError::MissingArgument)?; + let maybe_id = match message.last() { + Some(SetTopic(t)) => Some(*t), + _ => None, + }; + message.0.insert(0, UniversalOrigin(GlobalConsensus(local_net))); + if local_sub != Here { + message.0.insert(1, DescendOrigin(local_sub)); + } + let message = VersionedXcm::from(message); + let id = maybe_id.unwrap_or_else(|| message.using_encoded(sp_io::hashing::blake2_256)); + let blob = BridgeMessage { universal_dest, message }.encode(); + Ok(((blob, id), Price::get())) + } + + fn deliver((blob, id): (Vec, XcmHash)) -> Result { + Bridge::haul_blob(blob)?; + Ok(id) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ensure_is_remote_works() { + // A Kusama parachain is remote from the Polkadot Relay. + let x = ensure_is_remote(Polkadot, (Parent, Kusama, Parachain(1000))); + assert_eq!(x, Ok((Kusama, Parachain(1000).into()))); + + // Polkadot Relay is remote from a Kusama parachain. + let x = ensure_is_remote((Kusama, Parachain(1000)), (Parent, Parent, Polkadot)); + assert_eq!(x, Ok((Polkadot, Here))); + + // Our own parachain is local. + let x = ensure_is_remote(Polkadot, Parachain(1000)); + assert_eq!(x, Err(Parachain(1000).into())); + + // Polkadot's parachain is not remote if we are Polkadot. + let x = ensure_is_remote(Polkadot, (Parent, Polkadot, Parachain(1000))); + assert_eq!(x, Err((Parent, Polkadot, Parachain(1000)).into())); + + // If we don't have a consensus ancestor, then we cannot determine remoteness. + let x = ensure_is_remote((), (Parent, Polkadot, Parachain(1000))); + assert_eq!(x, Err((Parent, Polkadot, Parachain(1000)).into())); + } +} diff --git a/polkadot/xcm/xcm-builder/src/weight.rs b/polkadot/xcm/xcm-builder/src/weight.rs new file mode 100644 index 0000000000000000000000000000000000000000..f1c14a4c65176b6e427e6fdfdd47e8775707c04a --- /dev/null +++ b/polkadot/xcm/xcm-builder/src/weight.rs @@ -0,0 +1,260 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use frame_support::{ + dispatch::GetDispatchInfo, + traits::{tokens::currency::Currency as CurrencyT, Get, OnUnbalanced as OnUnbalancedT}, + weights::{ + constants::{WEIGHT_PROOF_SIZE_PER_MB, WEIGHT_REF_TIME_PER_SECOND}, + WeightToFee as WeightToFeeT, + }, +}; +use parity_scale_codec::Decode; +use sp_runtime::traits::{SaturatedConversion, Saturating, Zero}; +use sp_std::{marker::PhantomData, result::Result}; +use xcm::latest::{prelude::*, Weight}; +use xcm_executor::{ + traits::{WeightBounds, WeightTrader}, + Assets, +}; + +pub struct FixedWeightBounds(PhantomData<(T, C, M)>); +impl, C: Decode + GetDispatchInfo, M: Get> WeightBounds + for FixedWeightBounds +{ + fn weight(message: &mut Xcm) -> Result { + log::trace!(target: "xcm::weight", "FixedWeightBounds message: {:?}", message); + let mut instructions_left = M::get(); + Self::weight_with_limit(message, &mut instructions_left) + } + fn instr_weight(instruction: &Instruction) -> Result { + Self::instr_weight_with_limit(instruction, &mut u32::max_value()) + } +} + +impl, C: Decode + GetDispatchInfo, M> FixedWeightBounds { + fn weight_with_limit(message: &Xcm, instrs_limit: &mut u32) -> Result { + let mut r: Weight = Weight::zero(); + *instrs_limit = instrs_limit.checked_sub(message.0.len() as u32).ok_or(())?; + for m in message.0.iter() { + r = r.checked_add(&Self::instr_weight_with_limit(m, instrs_limit)?).ok_or(())?; + } + Ok(r) + } + fn instr_weight_with_limit( + instruction: &Instruction, + instrs_limit: &mut u32, + ) -> Result { + let instr_weight = match instruction { + Transact { require_weight_at_most, .. } => *require_weight_at_most, + SetErrorHandler(xcm) | SetAppendix(xcm) => Self::weight_with_limit(xcm, instrs_limit)?, + _ => Weight::zero(), + }; + T::get().checked_add(&instr_weight).ok_or(()) + } +} + +pub struct WeightInfoBounds(PhantomData<(W, C, M)>); +impl WeightBounds for WeightInfoBounds +where + W: XcmWeightInfo, + C: Decode + GetDispatchInfo, + M: Get, + Instruction: xcm::GetWeight, +{ + fn weight(message: &mut Xcm) -> Result { + log::trace!(target: "xcm::weight", "WeightInfoBounds message: {:?}", message); + let mut instructions_left = M::get(); + Self::weight_with_limit(message, &mut instructions_left) + } + fn instr_weight(instruction: &Instruction) -> Result { + Self::instr_weight_with_limit(instruction, &mut u32::max_value()) + } +} + +impl WeightInfoBounds +where + W: XcmWeightInfo, + C: Decode + GetDispatchInfo, + M: Get, + Instruction: xcm::GetWeight, +{ + fn weight_with_limit(message: &Xcm, instrs_limit: &mut u32) -> Result { + let mut r: Weight = Weight::zero(); + *instrs_limit = instrs_limit.checked_sub(message.0.len() as u32).ok_or(())?; + for m in message.0.iter() { + r = r.checked_add(&Self::instr_weight_with_limit(m, instrs_limit)?).ok_or(())?; + } + Ok(r) + } + fn instr_weight_with_limit( + instruction: &Instruction, + instrs_limit: &mut u32, + ) -> Result { + use xcm::GetWeight; + let instr_weight = match instruction { + Transact { require_weight_at_most, .. } => *require_weight_at_most, + SetErrorHandler(xcm) | SetAppendix(xcm) => Self::weight_with_limit(xcm, instrs_limit)?, + _ => Weight::zero(), + }; + instruction.weight().checked_add(&instr_weight).ok_or(()) + } +} + +/// Function trait for handling some revenue. Similar to a negative imbalance (credit) handler, but +/// for a `MultiAsset`. Sensible implementations will deposit the asset in some known treasury or +/// block-author account. +pub trait TakeRevenue { + /// Do something with the given `revenue`, which is a single non-wildcard `MultiAsset`. + fn take_revenue(revenue: MultiAsset); +} + +/// Null implementation just burns the revenue. +impl TakeRevenue for () { + fn take_revenue(_revenue: MultiAsset) {} +} + +/// Simple fee calculator that requires payment in a single fungible at a fixed rate. +/// +/// The constant `Get` type parameter should be the fungible ID, the amount of it required for one +/// second of weight and the amount required for 1 MB of proof. +pub struct FixedRateOfFungible, R: TakeRevenue>( + Weight, + u128, + PhantomData<(T, R)>, +); +impl, R: TakeRevenue> WeightTrader for FixedRateOfFungible { + fn new() -> Self { + Self(Weight::zero(), 0, PhantomData) + } + + fn buy_weight( + &mut self, + weight: Weight, + payment: Assets, + context: &XcmContext, + ) -> Result { + log::trace!( + target: "xcm::weight", + "FixedRateOfFungible::buy_weight weight: {:?}, payment: {:?}, context: {:?}", + weight, payment, context, + ); + let (id, units_per_second, units_per_mb) = T::get(); + let amount = (units_per_second * (weight.ref_time() as u128) / + (WEIGHT_REF_TIME_PER_SECOND as u128)) + + (units_per_mb * (weight.proof_size() as u128) / (WEIGHT_PROOF_SIZE_PER_MB as u128)); + if amount == 0 { + return Ok(payment) + } + let unused = + payment.checked_sub((id, amount).into()).map_err(|_| XcmError::TooExpensive)?; + self.0 = self.0.saturating_add(weight); + self.1 = self.1.saturating_add(amount); + Ok(unused) + } + + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + log::trace!(target: "xcm::weight", "FixedRateOfFungible::refund_weight weight: {:?}, context: {:?}", weight, context); + let (id, units_per_second, units_per_mb) = T::get(); + let weight = weight.min(self.0); + let amount = (units_per_second * (weight.ref_time() as u128) / + (WEIGHT_REF_TIME_PER_SECOND as u128)) + + (units_per_mb * (weight.proof_size() as u128) / (WEIGHT_PROOF_SIZE_PER_MB as u128)); + self.0 -= weight; + self.1 = self.1.saturating_sub(amount); + if amount > 0 { + Some((id, amount).into()) + } else { + None + } + } +} + +impl, R: TakeRevenue> Drop for FixedRateOfFungible { + fn drop(&mut self) { + if self.1 > 0 { + R::take_revenue((T::get().0, self.1).into()); + } + } +} + +/// Weight trader which uses the configured `WeightToFee` to set the right price for weight and then +/// places any weight bought into the right account. +pub struct UsingComponents< + WeightToFee: WeightToFeeT, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, +>( + Weight, + Currency::Balance, + PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>, +); +impl< + WeightToFee: WeightToFeeT, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > WeightTrader for UsingComponents +{ + fn new() -> Self { + Self(Weight::zero(), Zero::zero(), PhantomData) + } + + fn buy_weight( + &mut self, + weight: Weight, + payment: Assets, + context: &XcmContext, + ) -> Result { + log::trace!(target: "xcm::weight", "UsingComponents::buy_weight weight: {:?}, payment: {:?}, context: {:?}", weight, payment, context); + let amount = WeightToFee::weight_to_fee(&weight); + let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?; + let required = (Concrete(AssetId::get()), u128_amount).into(); + let unused = payment.checked_sub(required).map_err(|_| XcmError::TooExpensive)?; + self.0 = self.0.saturating_add(weight); + self.1 = self.1.saturating_add(amount); + Ok(unused) + } + + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + log::trace!(target: "xcm::weight", "UsingComponents::refund_weight weight: {:?}, context: {:?}", weight, context); + let weight = weight.min(self.0); + let amount = WeightToFee::weight_to_fee(&weight); + self.0 -= weight; + self.1 = self.1.saturating_sub(amount); + let amount: u128 = amount.saturated_into(); + if amount > 0 { + Some((AssetId::get(), amount).into()) + } else { + None + } + } +} +impl< + WeightToFee: WeightToFeeT, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > Drop for UsingComponents +{ + fn drop(&mut self) { + OnUnbalanced::on_unbalanced(Currency::issue(self.1)); + } +} diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..f799be7e401309dd5c12db2f64a1c6cf808411ef --- /dev/null +++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs @@ -0,0 +1,272 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use frame_support::{ + construct_runtime, parameter_types, + traits::{ConstU32, Everything, Nothing}, + weights::Weight, +}; +use frame_system::EnsureRoot; +use parity_scale_codec::Encode; +use primitive_types::H256; +use sp_runtime::{traits::IdentityLookup, AccountId32, BuildStorage}; +use sp_std::cell::RefCell; + +use polkadot_parachain::primitives::Id as ParaId; +use polkadot_runtime_parachains::{configuration, origin, shared}; +use xcm::latest::{opaque, prelude::*}; +use xcm_executor::XcmExecutor; + +use xcm_builder::{ + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, + ChildParachainAsNative, ChildParachainConvertsVia, ChildSystemParachainAsSuperuser, + CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, FixedWeightBounds, + IsChildSystemParachain, IsConcrete, MintLocation, RespectSuspension, SignedAccountId32AsNative, + SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, +}; + +pub type AccountId = AccountId32; +pub type Balance = u128; + +thread_local! { + pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); +} +pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm, XcmHash)> { + SENT_XCM.with(|q| (*q.borrow()).clone()) +} +pub struct TestSendXcm; +impl SendXcm for TestSendXcm { + type Ticket = (MultiLocation, Xcm<()>, XcmHash); + fn validate( + dest: &mut Option, + msg: &mut Option>, + ) -> SendResult<(MultiLocation, Xcm<()>, XcmHash)> { + let msg = msg.take().unwrap(); + let hash = fake_message_hash(&msg); + let triplet = (dest.take().unwrap(), msg, hash); + Ok((triplet, MultiAssets::new())) + } + fn deliver(triplet: (MultiLocation, Xcm<()>, XcmHash)) -> Result { + let hash = triplet.2; + SENT_XCM.with(|q| q.borrow_mut().push(triplet)); + Ok(hash) + } +} + +// copied from kusama constants +pub const UNITS: Balance = 1_000_000_000_000; +pub const CENTS: Balance = UNITS / 30_000; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = Everything; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub ExistentialDeposit: Balance = 1 * CENTS; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +impl shared::Config for Runtime {} + +impl configuration::Config for Runtime { + type WeightInfo = configuration::TestWeightInfo; +} + +// aims to closely emulate the Kusama XcmConfig +parameter_types! { + pub const KsmLocation: MultiLocation = MultiLocation::here(); + pub const KusamaNetwork: NetworkId = NetworkId::Kusama; + pub UniversalLocation: InteriorMultiLocation = Here; + pub CheckAccount: (AccountId, MintLocation) = (XcmPallet::check_account(), MintLocation::Local); +} + +pub type SovereignAccountOf = + (ChildParachainConvertsVia, AccountId32Aliases); + +pub type LocalCurrencyAdapter = XcmCurrencyAdapter< + Balances, + IsConcrete, + SovereignAccountOf, + AccountId, + CheckAccount, +>; + +pub type LocalAssetTransactor = (LocalCurrencyAdapter,); + +type LocalOriginConverter = ( + SovereignSignedViaLocation, + ChildParachainAsNative, + SignedAccountId32AsNative, + ChildSystemParachainAsSuperuser, +); + +parameter_types! { + pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 1024); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (KsmLocation::get().into(), 1, 1); +} + +pub type Barrier = ( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom, + // Unused/Untested + AllowUnpaidExecutionFrom>, +); + +parameter_types! { + pub KusamaForStatemine: (MultiAssetFilter, MultiLocation) = + (Wild(AllOf { id: Concrete(Here.into()), fun: WildFungible }), Parachain(1000).into()); + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 4; +} + +pub type TrustedTeleporters = (xcm_builder::Case,); + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = TestSendXcm; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = LocalOriginConverter; + type IsReserve = (); + type IsTeleporter = TrustedTeleporters; + type UniversalLocation = UniversalLocation; + type Barrier = RespectSuspension; + type Weigher = FixedWeightBounds; + type Trader = FixedRateOfFungible; + type ResponseHandler = XcmPallet; + type AssetTrap = XcmPallet; + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = XcmPallet; + type SubscriptionService = XcmPallet; + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; + type Aliasers = Nothing; +} + +pub type LocalOriginToLocation = SignedToAccountId32; + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Here.into()); +} + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type UniversalLocation = UniversalLocation; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = TestSendXcm; + // Anyone can execute XCM messages locally... + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmExecuteFilter = Nothing; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type RuntimeCall = RuntimeCall; + type RuntimeOrigin = RuntimeOrigin; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type TrustedLockers = (); + type SovereignAccountOf = (); + type Currency = Balances; + type CurrencyMatcher = IsConcrete; + type MaxLockers = frame_support::traits::ConstU32<8>; + type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = pallet_xcm::TestWeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} + +impl origin::Config for Runtime {} + +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + ParasOrigin: origin::{Pallet, Origin}, + XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin}, + } +); + +pub fn kusama_like_with_balances(balances: Vec<(AccountId, Balance)>) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + pallet_balances::GenesisConfig:: { balances } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +pub fn fake_message_hash(message: &Xcm) -> XcmHash { + message.using_encoded(sp_io::hashing::blake2_256) +} diff --git a/polkadot/xcm/xcm-builder/tests/scenarios.rs b/polkadot/xcm/xcm-builder/tests/scenarios.rs new file mode 100644 index 0000000000000000000000000000000000000000..3e735720aa7620ce4d18450e55eff90f83101db3 --- /dev/null +++ b/polkadot/xcm/xcm-builder/tests/scenarios.rs @@ -0,0 +1,300 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +mod mock; + +use mock::{ + fake_message_hash, kusama_like_with_balances, AccountId, Balance, Balances, BaseXcmWeight, + System, XcmConfig, CENTS, +}; +use polkadot_parachain::primitives::Id as ParaId; +use sp_runtime::traits::AccountIdConversion; +use xcm::latest::prelude::*; +use xcm_executor::XcmExecutor; + +pub const ALICE: AccountId = AccountId::new([0u8; 32]); +pub const PARA_ID: u32 = 2000; +pub const INITIAL_BALANCE: u128 = 100_000_000_000; +pub const REGISTER_AMOUNT: Balance = 10 * CENTS; + +// Construct a `BuyExecution` order. +fn buy_execution() -> Instruction { + BuyExecution { fees: (Here, REGISTER_AMOUNT).into(), weight_limit: Unlimited } +} + +/// Scenario: +/// A parachain transfers funds on the relay-chain to another parachain's account. +/// +/// Asserts that the parachain accounts are updated as expected. +#[test] +fn withdraw_and_deposit_works() { + let para_acc: AccountId = ParaId::from(PARA_ID).into_account_truncating(); + let balances = vec![(ALICE, INITIAL_BALANCE), (para_acc.clone(), INITIAL_BALANCE)]; + kusama_like_with_balances(balances).execute_with(|| { + let other_para_id = 3000; + let amount = REGISTER_AMOUNT; + let weight = BaseXcmWeight::get() * 3; + let message = Xcm(vec![ + WithdrawAsset((Here, amount).into()), + buy_execution(), + DepositAsset { + assets: AllCounted(1).into(), + beneficiary: Parachain(other_para_id).into(), + }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); + assert_eq!(r, Outcome::Complete(weight)); + let other_para_acc: AccountId = ParaId::from(other_para_id).into_account_truncating(); + assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - amount); + assert_eq!(Balances::free_balance(other_para_acc), amount); + }); +} + +/// Scenario: +/// Alice simply wants to transfer funds to Bob's account via XCM. +/// +/// Asserts that the balances are updated correctly and the correct events are fired. +#[test] +fn transfer_asset_works() { + let bob = AccountId::new([1u8; 32]); + let balances = vec![(ALICE, INITIAL_BALANCE), (bob.clone(), INITIAL_BALANCE)]; + kusama_like_with_balances(balances).execute_with(|| { + let amount = REGISTER_AMOUNT; + let weight = BaseXcmWeight::get(); + let message = Xcm(vec![TransferAsset { + assets: (Here, amount).into(), + beneficiary: AccountId32 { network: None, id: bob.clone().into() }.into(), + }]); + let hash = fake_message_hash(&message); + // Use `execute_xcm_in_credit` here to pass through the barrier + let r = XcmExecutor::::execute_xcm_in_credit( + AccountId32 { network: None, id: ALICE.into() }, + message, + hash, + weight, + weight, + ); + System::assert_last_event( + pallet_balances::Event::Transfer { from: ALICE, to: bob.clone(), amount }.into(), + ); + assert_eq!(r, Outcome::Complete(weight)); + assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - amount); + assert_eq!(Balances::free_balance(bob), INITIAL_BALANCE + amount); + }); +} + +/// Scenario: +/// A parachain wants to be notified that a transfer worked correctly. +/// It includes a `QueryHolding` order after the deposit to get notified on success. +/// This somewhat abuses `QueryHolding` as an indication of execution success. It works because +/// order execution halts on error (so no `QueryResponse` will be sent if the previous order +/// failed). The inner response sent due to the query is not used. +/// +/// Asserts that the balances are updated correctly and the expected XCM is sent. +#[test] +fn report_holding_works() { + use xcm::opaque::latest::prelude::*; + let para_acc: AccountId = ParaId::from(PARA_ID).into_account_truncating(); + let balances = vec![(ALICE, INITIAL_BALANCE), (para_acc.clone(), INITIAL_BALANCE)]; + kusama_like_with_balances(balances).execute_with(|| { + let other_para_id = 3000; + let amount = REGISTER_AMOUNT; + let weight = BaseXcmWeight::get() * 4; + let response_info = QueryResponseInfo { + destination: Parachain(PARA_ID).into(), + query_id: 1234, + max_weight: Weight::from_parts(1_000_000_000, 1_000_000_000), + }; + let message = Xcm(vec![ + WithdrawAsset((Here, amount).into()), + buy_execution(), + DepositAsset { + assets: AllCounted(1).into(), + beneficiary: OnlyChild.into(), // invalid destination + }, + // is not triggered becasue the deposit fails + ReportHolding { response_info: response_info.clone(), assets: All.into() }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); + assert_eq!( + r, + Outcome::Incomplete( + weight - BaseXcmWeight::get(), + XcmError::FailedToTransactAsset("AccountIdConversionFailed") + ) + ); + // there should be no query response sent for the failed deposit + assert_eq!(mock::sent_xcm(), vec![]); + assert_eq!(Balances::free_balance(para_acc.clone()), INITIAL_BALANCE - amount); + + // now do a successful transfer + let message = Xcm(vec![ + WithdrawAsset((Here, amount).into()), + buy_execution(), + DepositAsset { + assets: AllCounted(1).into(), + beneficiary: Parachain(other_para_id).into(), + }, + // used to get a notification in case of success + ReportHolding { response_info: response_info.clone(), assets: AllCounted(1).into() }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); + assert_eq!(r, Outcome::Complete(weight)); + let other_para_acc: AccountId = ParaId::from(other_para_id).into_account_truncating(); + assert_eq!(Balances::free_balance(other_para_acc), amount); + assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - 2 * amount); + let expected_msg = Xcm(vec![QueryResponse { + query_id: response_info.query_id, + response: Response::Assets(vec![].into()), + max_weight: response_info.max_weight, + querier: Some(Here.into()), + }]); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!( + mock::sent_xcm(), + vec![(Parachain(PARA_ID).into(), expected_msg, expected_hash,)] + ); + }); +} + +/// Scenario: +/// A parachain wants to move KSM from Kusama to Statemine. +/// The parachain sends an XCM to withdraw funds combined with a teleport to the destination. +/// +/// This way of moving funds from a relay to a parachain will only work for trusted chains. +/// Reserve based transfer should be used to move KSM to a community parachain. +/// +/// Asserts that the balances are updated accordingly and the correct XCM is sent. +#[test] +fn teleport_to_statemine_works() { + use xcm::opaque::latest::prelude::*; + let para_acc: AccountId = ParaId::from(PARA_ID).into_account_truncating(); + let balances = vec![(ALICE, INITIAL_BALANCE), (para_acc.clone(), INITIAL_BALANCE)]; + kusama_like_with_balances(balances).execute_with(|| { + let statemine_id = 1000; + let other_para_id = 3000; + let amount = REGISTER_AMOUNT; + let teleport_effects = vec![ + buy_execution(), // unchecked mock value + DepositAsset { + assets: AllCounted(1).into(), + beneficiary: (Parent, Parachain(PARA_ID)).into(), + }, + ]; + let weight = BaseXcmWeight::get() * 3; + + // teleports are allowed to community chains, even in the absence of trust from their side. + let message = Xcm(vec![ + WithdrawAsset((Here, amount).into()), + buy_execution(), + InitiateTeleport { + assets: All.into(), + dest: Parachain(other_para_id).into(), + xcm: Xcm(teleport_effects.clone()), + }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); + assert_eq!(r, Outcome::Complete(weight)); + let expected_msg = Xcm(vec![ReceiveTeleportedAsset((Parent, amount).into()), ClearOrigin] + .into_iter() + .chain(teleport_effects.clone().into_iter()) + .collect()); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!( + mock::sent_xcm(), + vec![(Parachain(other_para_id).into(), expected_msg, expected_hash,)] + ); + + // teleports are allowed from statemine to kusama. + let message = Xcm(vec![ + WithdrawAsset((Here, amount).into()), + buy_execution(), + InitiateTeleport { + assets: All.into(), + dest: Parachain(statemine_id).into(), + xcm: Xcm(teleport_effects.clone()), + }, + ]); + let hash = fake_message_hash(&message); + let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); + assert_eq!(r, Outcome::Complete(weight)); + // 2 * amount because of the other teleport above + assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - 2 * amount); + let expected_msg = Xcm(vec![ReceiveTeleportedAsset((Parent, amount).into()), ClearOrigin] + .into_iter() + .chain(teleport_effects.clone().into_iter()) + .collect()); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!( + mock::sent_xcm(), + vec![ + (Parachain(other_para_id).into(), expected_msg.clone(), expected_hash,), + (Parachain(statemine_id).into(), expected_msg, expected_hash,) + ] + ); + }); +} + +/// Scenario: +/// A parachain wants to move KSM from Kusama to the parachain. +/// It withdraws funds and then deposits them into the reserve account of the destination chain. +/// to the destination. +/// +/// Asserts that the balances are updated accordingly and the correct XCM is sent. +#[test] +fn reserve_based_transfer_works() { + use xcm::opaque::latest::prelude::*; + let para_acc: AccountId = ParaId::from(PARA_ID).into_account_truncating(); + let balances = vec![(ALICE, INITIAL_BALANCE), (para_acc.clone(), INITIAL_BALANCE)]; + kusama_like_with_balances(balances).execute_with(|| { + let other_para_id = 3000; + let amount = REGISTER_AMOUNT; + let transfer_effects = vec![ + buy_execution(), // unchecked mock value + DepositAsset { + assets: AllCounted(1).into(), + beneficiary: (Parent, Parachain(PARA_ID)).into(), + }, + ]; + let message = Xcm(vec![ + WithdrawAsset((Here, amount).into()), + buy_execution(), + DepositReserveAsset { + assets: AllCounted(1).into(), + dest: Parachain(other_para_id).into(), + xcm: Xcm(transfer_effects.clone()), + }, + ]); + let hash = fake_message_hash(&message); + let weight = BaseXcmWeight::get() * 3; + let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); + assert_eq!(r, Outcome::Complete(weight)); + assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - amount); + let expected_msg = Xcm(vec![ReserveAssetDeposited((Parent, amount).into()), ClearOrigin] + .into_iter() + .chain(transfer_effects.into_iter()) + .collect()); + let expected_hash = fake_message_hash(&expected_msg); + assert_eq!( + mock::sent_xcm(), + vec![(Parachain(other_para_id).into(), expected_msg, expected_hash,)] + ); + }); +} diff --git a/polkadot/xcm/xcm-executor/Cargo.toml b/polkadot/xcm/xcm-executor/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..92e6dc95442fc041934a00ec5ef200f280e1d072 --- /dev/null +++ b/polkadot/xcm/xcm-executor/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "xcm-executor" +description = "An abstract and configurable XCM message executor." +authors.workspace = true +edition.workspace = true +license.workspace = true +version.workspace = true + +[dependencies] +impl-trait-for-tuples = "0.2.2" +environmental = { version = "1.1.4", default-features = false } +parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } +xcm = { path = "..", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-weights = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +log = { version = "0.4.17", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false, optional = true } + +[features] +default = ["std"] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", +] +std = [ + "parity-scale-codec/std", + "xcm/std", + "sp-std/std", + "sp-io/std", + "sp-arithmetic/std", + "sp-core/std", + "sp-runtime/std", + "sp-weights/std", + "frame-support/std", + "log/std", + "frame-benchmarking/std", +] diff --git a/polkadot/xcm/xcm-executor/integration-tests/Cargo.toml b/polkadot/xcm/xcm-executor/integration-tests/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..cec9754baa31f6d57a02a1138ce899a13ff2d4ac --- /dev/null +++ b/polkadot/xcm/xcm-executor/integration-tests/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "xcm-executor-integration-tests" +description = "Integration tests for the XCM Executor" +authors.workspace = true +edition.workspace = true +license.workspace = true +version.workspace = true +publish = false + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.6.1" } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } +futures = "0.3.21" +pallet-xcm = { path = "../../pallet-xcm" } +polkadot-test-client = { path = "../../../node/test/client" } +polkadot-test-runtime = { path = "../../../runtime/test-runtime" } +polkadot-test-service = { path = "../../../node/test/service" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" } +xcm = { path = "../..", default-features = false } +xcm-executor = { path = ".." } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[features] +default = ["std"] +std = [ + "xcm/std", + "sp-runtime/std", + "frame-support/std", +] diff --git a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..d8c77f8317e1ff961e3a221b01b7ea45db4be80a --- /dev/null +++ b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs @@ -0,0 +1,281 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg(test)] + +use codec::Encode; +use frame_support::{dispatch::GetDispatchInfo, weights::Weight}; +use polkadot_test_client::{ + BlockBuilderExt, ClientBlockImportExt, DefaultTestClientBuilderExt, InitPolkadotBlockBuilder, + TestClientBuilder, TestClientBuilderExt, +}; +use polkadot_test_runtime::{pallet_test_notifier, xcm_config::XcmConfig}; +use polkadot_test_service::construct_extrinsic; +use sp_runtime::traits::Block; +use sp_state_machine::InspectState; +use xcm::{latest::prelude::*, VersionedResponse, VersionedXcm}; +use xcm_executor::traits::WeightBounds; + +#[test] +fn basic_buy_fees_message_executes() { + sp_tracing::try_init_simple(); + let mut client = TestClientBuilder::new().build(); + + let msg = Xcm(vec![ + WithdrawAsset((Parent, 100).into()), + BuyExecution { fees: (Parent, 1).into(), weight_limit: Unlimited }, + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Parent.into() }, + ]); + + let mut block_builder = client.init_polkadot_block_builder(); + + let execute = construct_extrinsic( + &client, + polkadot_test_runtime::RuntimeCall::Xcm(pallet_xcm::Call::execute { + message: Box::new(VersionedXcm::from(msg)), + max_weight: Weight::from_parts(1_000_000_000, 1024 * 1024), + }), + sp_keyring::Sr25519Keyring::Alice, + 0, + ); + + block_builder.push_polkadot_extrinsic(execute).expect("pushes extrinsic"); + + let block = block_builder.build().expect("Finalizes the block").block; + let block_hash = block.hash(); + + futures::executor::block_on(client.import(sp_consensus::BlockOrigin::Own, block)) + .expect("imports the block"); + + client.state_at(block_hash).expect("state should exist").inspect_state(|| { + assert!(polkadot_test_runtime::System::events().iter().any(|r| matches!( + r.event, + polkadot_test_runtime::RuntimeEvent::Xcm(pallet_xcm::Event::Attempted { + outcome: Outcome::Complete(_) + }), + ))); + }); +} + +#[test] +fn transact_recursion_limit_works() { + sp_tracing::try_init_simple(); + let mut client = TestClientBuilder::new().build(); + + let mut msg = Xcm(vec![ClearOrigin]); + let max_weight = ::Weigher::weight(&mut msg).unwrap(); + let mut call = polkadot_test_runtime::RuntimeCall::Xcm(pallet_xcm::Call::execute { + message: Box::new(VersionedXcm::from(msg)), + max_weight, + }); + + for _ in 0..11 { + let mut msg = Xcm(vec![ + WithdrawAsset((Parent, 1_000).into()), + BuyExecution { fees: (Parent, 1).into(), weight_limit: Unlimited }, + Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: call.get_dispatch_info().weight, + call: call.encode().into(), + }, + ]); + let max_weight = ::Weigher::weight(&mut msg).unwrap(); + call = polkadot_test_runtime::RuntimeCall::Xcm(pallet_xcm::Call::execute { + message: Box::new(VersionedXcm::from(msg)), + max_weight, + }); + } + + let mut block_builder = client.init_polkadot_block_builder(); + + let execute = construct_extrinsic(&client, call, sp_keyring::Sr25519Keyring::Alice, 0); + + block_builder.push_polkadot_extrinsic(execute).expect("pushes extrinsic"); + + let block = block_builder.build().expect("Finalizes the block").block; + let block_hash = block.hash(); + + futures::executor::block_on(client.import(sp_consensus::BlockOrigin::Own, block)) + .expect("imports the block"); + + client.state_at(block_hash).expect("state should exist").inspect_state(|| { + assert!(polkadot_test_runtime::System::events().iter().any(|r| matches!( + r.event, + polkadot_test_runtime::RuntimeEvent::Xcm(pallet_xcm::Event::Attempted { + outcome: Outcome::Incomplete(_, XcmError::ExceedsStackLimit) + }), + ))); + }); +} + +#[test] +fn query_response_fires() { + use pallet_test_notifier::Event::*; + use pallet_xcm::QueryStatus; + use polkadot_test_runtime::RuntimeEvent::TestNotifier; + + sp_tracing::try_init_simple(); + let mut client = TestClientBuilder::new().build(); + + let mut block_builder = client.init_polkadot_block_builder(); + + let execute = construct_extrinsic( + &client, + polkadot_test_runtime::RuntimeCall::TestNotifier( + pallet_test_notifier::Call::prepare_new_query {}, + ), + sp_keyring::Sr25519Keyring::Alice, + 0, + ); + + block_builder.push_polkadot_extrinsic(execute).expect("pushes extrinsic"); + + let block = block_builder.build().expect("Finalizes the block").block; + let block_hash = block.hash(); + + futures::executor::block_on(client.import(sp_consensus::BlockOrigin::Own, block)) + .expect("imports the block"); + + let mut query_id = None; + client.state_at(block_hash).expect("state should exist").inspect_state(|| { + for r in polkadot_test_runtime::System::events().iter() { + match r.event { + TestNotifier(QueryPrepared(q)) => query_id = Some(q), + _ => (), + } + } + }); + let query_id = query_id.unwrap(); + + let mut block_builder = client.init_polkadot_block_builder(); + + let response = Response::ExecutionResult(None); + let max_weight = Weight::from_parts(1_000_000, 1024 * 1024); + let querier = Some(Here.into()); + let msg = Xcm(vec![QueryResponse { query_id, response, max_weight, querier }]); + let msg = Box::new(VersionedXcm::from(msg)); + + let execute = construct_extrinsic( + &client, + polkadot_test_runtime::RuntimeCall::Xcm(pallet_xcm::Call::execute { + message: msg, + max_weight: Weight::from_parts(1_000_000_000, 1024 * 1024), + }), + sp_keyring::Sr25519Keyring::Alice, + 1, + ); + + block_builder.push_polkadot_extrinsic(execute).expect("pushes extrinsic"); + + let block = block_builder.build().expect("Finalizes the block").block; + let block_hash = block.hash(); + + futures::executor::block_on(client.import(sp_consensus::BlockOrigin::Own, block)) + .expect("imports the block"); + + client.state_at(block_hash).expect("state should exist").inspect_state(|| { + assert!(polkadot_test_runtime::System::events().iter().any(|r| matches!( + r.event, + polkadot_test_runtime::RuntimeEvent::Xcm(pallet_xcm::Event::ResponseReady { + query_id: q, + response: Response::ExecutionResult(None), + }) if q == query_id, + ))); + assert_eq!( + polkadot_test_runtime::Xcm::query(query_id), + Some(QueryStatus::Ready { + response: VersionedResponse::V3(Response::ExecutionResult(None)), + at: 2u32.into() + }), + ) + }); +} + +#[test] +fn query_response_elicits_handler() { + use pallet_test_notifier::Event::*; + use polkadot_test_runtime::RuntimeEvent::TestNotifier; + + sp_tracing::try_init_simple(); + let mut client = TestClientBuilder::new().build(); + + let mut block_builder = client.init_polkadot_block_builder(); + + let execute = construct_extrinsic( + &client, + polkadot_test_runtime::RuntimeCall::TestNotifier( + pallet_test_notifier::Call::prepare_new_notify_query {}, + ), + sp_keyring::Sr25519Keyring::Alice, + 0, + ); + + block_builder.push_polkadot_extrinsic(execute).expect("pushes extrinsic"); + + let block = block_builder.build().expect("Finalizes the block").block; + let block_hash = block.hash(); + + futures::executor::block_on(client.import(sp_consensus::BlockOrigin::Own, block)) + .expect("imports the block"); + + let mut query_id = None; + client.state_at(block_hash).expect("state should exist").inspect_state(|| { + for r in polkadot_test_runtime::System::events().iter() { + match r.event { + TestNotifier(NotifyQueryPrepared(q)) => query_id = Some(q), + _ => (), + } + } + }); + let query_id = query_id.unwrap(); + + let mut block_builder = client.init_polkadot_block_builder(); + + let response = Response::ExecutionResult(None); + let max_weight = Weight::from_parts(1_000_000, 1024 * 1024); + let querier = Some(Here.into()); + let msg = Xcm(vec![QueryResponse { query_id, response, max_weight, querier }]); + + let execute = construct_extrinsic( + &client, + polkadot_test_runtime::RuntimeCall::Xcm(pallet_xcm::Call::execute { + message: Box::new(VersionedXcm::from(msg)), + max_weight: Weight::from_parts(1_000_000_000, 1024 * 1024), + }), + sp_keyring::Sr25519Keyring::Alice, + 1, + ); + + block_builder.push_polkadot_extrinsic(execute).expect("pushes extrinsic"); + + let block = block_builder.build().expect("Finalizes the block").block; + let block_hash = block.hash(); + + futures::executor::block_on(client.import(sp_consensus::BlockOrigin::Own, block)) + .expect("imports the block"); + + client.state_at(block_hash).expect("state should exist").inspect_state(|| { + assert!(polkadot_test_runtime::System::events().iter().any(|r| matches!( + r.event, + TestNotifier(ResponseReceived( + MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { .. }) }, + q, + Response::ExecutionResult(None), + )) if q == query_id, + ))); + }); +} diff --git a/polkadot/xcm/xcm-executor/src/assets.rs b/polkadot/xcm/xcm-executor/src/assets.rs new file mode 100644 index 0000000000000000000000000000000000000000..d8d8936df33187388522a705df08847a73f63245 --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/assets.rs @@ -0,0 +1,854 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use sp_runtime::{traits::Saturating, RuntimeDebug}; +use sp_std::{ + collections::{btree_map::BTreeMap, btree_set::BTreeSet}, + mem, + prelude::*, +}; +use xcm::latest::{ + AssetId, AssetInstance, + Fungibility::{Fungible, NonFungible}, + InteriorMultiLocation, MultiAsset, MultiAssetFilter, MultiAssets, MultiLocation, + WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible}, + WildMultiAsset::{All, AllCounted, AllOf, AllOfCounted}, +}; + +/// List of non-wildcard fungible and non-fungible assets. +#[derive(Default, Clone, RuntimeDebug, Eq, PartialEq)] +pub struct Assets { + /// The fungible assets. + pub fungible: BTreeMap, + + /// The non-fungible assets. + // TODO: Consider BTreeMap> + // or even BTreeMap> + pub non_fungible: BTreeSet<(AssetId, AssetInstance)>, +} + +impl From for Assets { + fn from(asset: MultiAsset) -> Assets { + let mut result = Self::default(); + result.subsume(asset); + result + } +} + +impl From> for Assets { + fn from(assets: Vec) -> Assets { + let mut result = Self::default(); + for asset in assets.into_iter() { + result.subsume(asset) + } + result + } +} + +impl From for Assets { + fn from(assets: MultiAssets) -> Assets { + assets.into_inner().into() + } +} + +impl From for Vec { + fn from(a: Assets) -> Self { + a.into_assets_iter().collect() + } +} + +impl From for MultiAssets { + fn from(a: Assets) -> Self { + a.into_assets_iter().collect::>().into() + } +} + +/// An error emitted by `take` operations. +#[derive(Debug)] +pub enum TakeError { + /// There was an attempt to take an asset without saturating (enough of) which did not exist. + AssetUnderflow(MultiAsset), +} + +impl Assets { + /// New value, containing no assets. + pub fn new() -> Self { + Self::default() + } + + /// Total number of distinct assets. + pub fn len(&self) -> usize { + self.fungible.len() + self.non_fungible.len() + } + + /// Returns `true` if `self` contains no assets. + pub fn is_empty(&self) -> bool { + self.fungible.is_empty() && self.non_fungible.is_empty() + } + + /// A borrowing iterator over the fungible assets. + pub fn fungible_assets_iter(&self) -> impl Iterator + '_ { + self.fungible + .iter() + .map(|(id, &amount)| MultiAsset { fun: Fungible(amount), id: *id }) + } + + /// A borrowing iterator over the non-fungible assets. + pub fn non_fungible_assets_iter(&self) -> impl Iterator + '_ { + self.non_fungible + .iter() + .map(|(id, instance)| MultiAsset { fun: NonFungible(*instance), id: *id }) + } + + /// A consuming iterator over all assets. + pub fn into_assets_iter(self) -> impl Iterator { + self.fungible + .into_iter() + .map(|(id, amount)| MultiAsset { fun: Fungible(amount), id }) + .chain( + self.non_fungible + .into_iter() + .map(|(id, instance)| MultiAsset { fun: NonFungible(instance), id }), + ) + } + + /// A borrowing iterator over all assets. + pub fn assets_iter(&self) -> impl Iterator + '_ { + self.fungible_assets_iter().chain(self.non_fungible_assets_iter()) + } + + /// Mutate `self` to contain all given `assets`, saturating if necessary. + /// + /// NOTE: [`Assets`] are always sorted, allowing us to optimize this function from `O(n^2)` to + /// `O(n)`. + pub fn subsume_assets(&mut self, mut assets: Assets) { + let mut f_iter = assets.fungible.iter_mut(); + let mut g_iter = self.fungible.iter_mut(); + if let (Some(mut f), Some(mut g)) = (f_iter.next(), g_iter.next()) { + loop { + if f.0 == g.0 { + // keys are equal. in this case, we add `self`'s balance for the asset onto + // `assets`, balance, knowing that the `append` operation which follows will + // clobber `self`'s value and only use `assets`'s. + (*f.1).saturating_accrue(*g.1); + } + if f.0 <= g.0 { + f = match f_iter.next() { + Some(x) => x, + None => break, + }; + } + if f.0 >= g.0 { + g = match g_iter.next() { + Some(x) => x, + None => break, + }; + } + } + } + self.fungible.append(&mut assets.fungible); + self.non_fungible.append(&mut assets.non_fungible); + } + + /// Mutate `self` to contain the given `asset`, saturating if necessary. + /// + /// Wildcard values of `asset` do nothing. + pub fn subsume(&mut self, asset: MultiAsset) { + match asset.fun { + Fungible(amount) => { + self.fungible + .entry(asset.id) + .and_modify(|e| *e = e.saturating_add(amount)) + .or_insert(amount); + }, + NonFungible(instance) => { + self.non_fungible.insert((asset.id, instance)); + }, + } + } + + /// Swaps two mutable Assets, without deinitializing either one. + pub fn swapped(&mut self, mut with: Assets) -> Self { + mem::swap(&mut *self, &mut with); + with + } + + /// Alter any concretely identified assets by prepending the given `MultiLocation`. + /// + /// WARNING: For now we consider this infallible and swallow any errors. It is thus the caller's + /// responsibility to ensure that any internal asset IDs are able to be prepended without + /// overflow. + pub fn prepend_location(&mut self, prepend: &MultiLocation) { + let mut fungible = Default::default(); + mem::swap(&mut self.fungible, &mut fungible); + self.fungible = fungible + .into_iter() + .map(|(mut id, amount)| { + let _ = id.prepend_with(prepend); + (id, amount) + }) + .collect(); + let mut non_fungible = Default::default(); + mem::swap(&mut self.non_fungible, &mut non_fungible); + self.non_fungible = non_fungible + .into_iter() + .map(|(mut class, inst)| { + let _ = class.prepend_with(prepend); + (class, inst) + }) + .collect(); + } + + /// Mutate the assets to be interpreted as the same assets from the perspective of a `target` + /// chain. The local chain's `context` is provided. + /// + /// Any assets which were unable to be reanchored are introduced into `failed_bin`. + pub fn reanchor( + &mut self, + target: &MultiLocation, + context: InteriorMultiLocation, + mut maybe_failed_bin: Option<&mut Self>, + ) { + let mut fungible = Default::default(); + mem::swap(&mut self.fungible, &mut fungible); + self.fungible = fungible + .into_iter() + .filter_map(|(mut id, amount)| match id.reanchor(target, context) { + Ok(()) => Some((id, amount)), + Err(()) => { + maybe_failed_bin.as_mut().map(|f| f.fungible.insert(id, amount)); + None + }, + }) + .collect(); + let mut non_fungible = Default::default(); + mem::swap(&mut self.non_fungible, &mut non_fungible); + self.non_fungible = non_fungible + .into_iter() + .filter_map(|(mut class, inst)| match class.reanchor(target, context) { + Ok(()) => Some((class, inst)), + Err(()) => { + maybe_failed_bin.as_mut().map(|f| f.non_fungible.insert((class, inst))); + None + }, + }) + .collect(); + } + + /// Returns `true` if `asset` is contained within `self`. + pub fn contains_asset(&self, asset: &MultiAsset) -> bool { + match asset { + MultiAsset { fun: Fungible(amount), id } => + self.fungible.get(id).map_or(false, |a| a >= amount), + MultiAsset { fun: NonFungible(instance), id } => + self.non_fungible.contains(&(*id, *instance)), + } + } + + /// Returns `true` if all `assets` are contained within `self`. + pub fn contains_assets(&self, assets: &MultiAssets) -> bool { + assets.inner().iter().all(|a| self.contains_asset(a)) + } + + /// Returns `true` if all `assets` are contained within `self`. + pub fn contains(&self, assets: &Assets) -> bool { + assets + .fungible + .iter() + .all(|(k, v)| self.fungible.get(k).map_or(false, |a| a >= v)) && + self.non_fungible.is_superset(&assets.non_fungible) + } + + /// Returns an error unless all `assets` are contained in `self`. In the case of an error, the + /// first asset in `assets` which is not wholly in `self` is returned. + pub fn ensure_contains(&self, assets: &MultiAssets) -> Result<(), TakeError> { + for asset in assets.inner().iter() { + match asset { + MultiAsset { fun: Fungible(amount), id } => { + if self.fungible.get(id).map_or(true, |a| a < amount) { + return Err(TakeError::AssetUnderflow((*id, *amount).into())) + } + }, + MultiAsset { fun: NonFungible(instance), id } => { + let id_instance = (*id, *instance); + if !self.non_fungible.contains(&id_instance) { + return Err(TakeError::AssetUnderflow(id_instance.into())) + } + }, + } + } + return Ok(()) + } + + /// Mutates `self` to its original value less `mask` and returns assets that were removed. + /// + /// If `saturate` is `true`, then `self` is considered to be masked by `mask`, thereby avoiding + /// any attempt at reducing it by assets it does not contain. In this case, the function is + /// infallible. If `saturate` is `false` and `mask` references a definite asset which `self` + /// does not contain then an error is returned. + /// + /// The number of unique assets which are removed will respect the `count` parameter in the + /// counted wildcard variants. + /// + /// Returns `Ok` with the definite assets token from `self` and mutates `self` to its value + /// minus `mask`. Returns `Err` in the non-saturating case where `self` did not contain (enough + /// of) a definite asset to be removed. + fn general_take( + &mut self, + mask: MultiAssetFilter, + saturate: bool, + ) -> Result { + let mut taken = Assets::new(); + let maybe_limit = mask.limit().map(|x| x as usize); + match mask { + // TODO: Counted variants where we define `limit`. + MultiAssetFilter::Wild(All) | MultiAssetFilter::Wild(AllCounted(_)) => { + if maybe_limit.map_or(true, |l| self.len() <= l) { + return Ok(self.swapped(Assets::new())) + } else { + let fungible = mem::replace(&mut self.fungible, Default::default()); + fungible.into_iter().for_each(|(c, amount)| { + if maybe_limit.map_or(true, |l| taken.len() < l) { + taken.fungible.insert(c, amount); + } else { + self.fungible.insert(c, amount); + } + }); + let non_fungible = mem::replace(&mut self.non_fungible, Default::default()); + non_fungible.into_iter().for_each(|(c, instance)| { + if maybe_limit.map_or(true, |l| taken.len() < l) { + taken.non_fungible.insert((c, instance)); + } else { + self.non_fungible.insert((c, instance)); + } + }); + } + }, + MultiAssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | + MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => + if maybe_limit.map_or(true, |l| l >= 1) { + if let Some((id, amount)) = self.fungible.remove_entry(&id) { + taken.fungible.insert(id, amount); + } + }, + MultiAssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | + MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => { + let non_fungible = mem::replace(&mut self.non_fungible, Default::default()); + non_fungible.into_iter().for_each(|(c, instance)| { + if c == id && maybe_limit.map_or(true, |l| taken.len() < l) { + taken.non_fungible.insert((c, instance)); + } else { + self.non_fungible.insert((c, instance)); + } + }); + }, + MultiAssetFilter::Definite(assets) => { + if !saturate { + self.ensure_contains(&assets)?; + } + for asset in assets.into_inner().into_iter() { + match asset { + MultiAsset { fun: Fungible(amount), id } => { + let (remove, amount) = match self.fungible.get_mut(&id) { + Some(self_amount) => { + let amount = amount.min(*self_amount); + *self_amount -= amount; + (*self_amount == 0, amount) + }, + None => (false, 0), + }; + if remove { + self.fungible.remove(&id); + } + if amount > 0 { + taken.subsume(MultiAsset::from((id, amount)).into()); + } + }, + MultiAsset { fun: NonFungible(instance), id } => { + let id_instance = (id, instance); + if self.non_fungible.remove(&id_instance) { + taken.subsume(id_instance.into()) + } + }, + } + } + }, + } + Ok(taken) + } + + /// Mutates `self` to its original value less `mask` and returns `true` iff it contains at least + /// `mask`. + /// + /// Returns `Ok` with the non-wildcard equivalence of `mask` taken and mutates `self` to its + /// value minus `mask` if `self` contains `asset`, and return `Err` otherwise. + pub fn saturating_take(&mut self, asset: MultiAssetFilter) -> Assets { + self.general_take(asset, true) + .expect("general_take never results in error when saturating") + } + + /// Mutates `self` to its original value less `mask` and returns `true` iff it contains at least + /// `mask`. + /// + /// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its + /// value minus `asset` if `self` contains `asset`, and return `Err` otherwise. + pub fn try_take(&mut self, mask: MultiAssetFilter) -> Result { + self.general_take(mask, false) + } + + /// Consumes `self` and returns its original value excluding `asset` iff it contains at least + /// `asset`. + pub fn checked_sub(mut self, asset: MultiAsset) -> Result { + match asset.fun { + Fungible(amount) => { + let remove = if let Some(balance) = self.fungible.get_mut(&asset.id) { + if *balance >= amount { + *balance -= amount; + *balance == 0 + } else { + return Err(self) + } + } else { + return Err(self) + }; + if remove { + self.fungible.remove(&asset.id); + } + Ok(self) + }, + NonFungible(instance) => + if self.non_fungible.remove(&(asset.id, instance)) { + Ok(self) + } else { + Err(self) + }, + } + } + + /// Return the assets in `self`, but (asset-wise) of no greater value than `mask`. + /// + /// The number of unique assets which are returned will respect the `count` parameter in the + /// counted wildcard variants of `mask`. + /// + /// Example: + /// + /// ``` + /// use xcm_executor::Assets; + /// use xcm::latest::prelude::*; + /// let assets_i_have: Assets = vec![ (Here, 100).into(), ([0; 32], 100).into() ].into(); + /// let assets_they_want: MultiAssetFilter = vec![ (Here, 200).into(), ([0; 32], 50).into() ].into(); + /// + /// let assets_we_can_trade: Assets = assets_i_have.min(&assets_they_want); + /// assert_eq!(assets_we_can_trade.into_assets_iter().collect::>(), vec![ + /// (Here, 100).into(), ([0; 32], 50).into(), + /// ]); + /// ``` + pub fn min(&self, mask: &MultiAssetFilter) -> Assets { + let mut masked = Assets::new(); + let maybe_limit = mask.limit().map(|x| x as usize); + if maybe_limit.map_or(false, |l| l == 0) { + return masked + } + match mask { + MultiAssetFilter::Wild(All) | MultiAssetFilter::Wild(AllCounted(_)) => { + if maybe_limit.map_or(true, |l| self.len() <= l) { + return self.clone() + } else { + for (&c, &amount) in self.fungible.iter() { + masked.fungible.insert(c, amount); + if maybe_limit.map_or(false, |l| masked.len() >= l) { + return masked + } + } + for (c, instance) in self.non_fungible.iter() { + masked.non_fungible.insert((*c, *instance)); + if maybe_limit.map_or(false, |l| masked.len() >= l) { + return masked + } + } + } + }, + MultiAssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | + MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => + if let Some(&amount) = self.fungible.get(&id) { + masked.fungible.insert(*id, amount); + }, + MultiAssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | + MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => + for (c, instance) in self.non_fungible.iter() { + if c == id { + masked.non_fungible.insert((*c, *instance)); + if maybe_limit.map_or(false, |l| masked.len() >= l) { + return masked + } + } + }, + MultiAssetFilter::Definite(assets) => + for asset in assets.inner().iter() { + match asset { + MultiAsset { fun: Fungible(amount), id } => { + if let Some(m) = self.fungible.get(id) { + masked.subsume((*id, Fungible(*amount.min(m))).into()); + } + }, + MultiAsset { fun: NonFungible(instance), id } => { + let id_instance = (*id, *instance); + if self.non_fungible.contains(&id_instance) { + masked.subsume(id_instance.into()); + } + }, + } + }, + } + masked + } +} + +#[cfg(test)] +mod tests { + use super::*; + use xcm::latest::prelude::*; + #[allow(non_snake_case)] + /// Abstract fungible constructor + fn AF(id: u8, amount: u128) -> MultiAsset { + ([id; 32], amount).into() + } + #[allow(non_snake_case)] + /// Abstract non-fungible constructor + fn ANF(class: u8, instance_id: u8) -> MultiAsset { + ([class; 32], [instance_id; 4]).into() + } + #[allow(non_snake_case)] + /// Concrete fungible constructor + fn CF(amount: u128) -> MultiAsset { + (Here, amount).into() + } + #[allow(non_snake_case)] + /// Concrete non-fungible constructor + fn CNF(instance_id: u8) -> MultiAsset { + (Here, [instance_id; 4]).into() + } + + fn test_assets() -> Assets { + let mut assets = Assets::new(); + assets.subsume(AF(1, 100)); + assets.subsume(ANF(2, 20)); + assets.subsume(CF(300)); + assets.subsume(CNF(40)); + assets + } + + #[test] + fn subsume_assets_works() { + let t1 = test_assets(); + let mut t2 = Assets::new(); + t2.subsume(AF(1, 50)); + t2.subsume(ANF(2, 10)); + t2.subsume(CF(300)); + t2.subsume(CNF(50)); + let mut r1 = t1.clone(); + r1.subsume_assets(t2.clone()); + let mut r2 = t1.clone(); + for a in t2.assets_iter() { + r2.subsume(a) + } + assert_eq!(r1, r2); + } + + #[test] + fn checked_sub_works() { + let t = test_assets(); + let t = t.checked_sub(AF(1, 50)).unwrap(); + let t = t.checked_sub(AF(1, 51)).unwrap_err(); + let t = t.checked_sub(AF(1, 50)).unwrap(); + let t = t.checked_sub(AF(1, 1)).unwrap_err(); + let t = t.checked_sub(CF(150)).unwrap(); + let t = t.checked_sub(CF(151)).unwrap_err(); + let t = t.checked_sub(CF(150)).unwrap(); + let t = t.checked_sub(CF(1)).unwrap_err(); + let t = t.checked_sub(ANF(2, 21)).unwrap_err(); + let t = t.checked_sub(ANF(2, 20)).unwrap(); + let t = t.checked_sub(ANF(2, 20)).unwrap_err(); + let t = t.checked_sub(CNF(41)).unwrap_err(); + let t = t.checked_sub(CNF(40)).unwrap(); + let t = t.checked_sub(CNF(40)).unwrap_err(); + assert_eq!(t, Assets::new()); + } + + #[test] + fn into_assets_iter_works() { + let assets = test_assets(); + let mut iter = assets.into_assets_iter(); + // Order defined by implementation: CF, AF, CNF, ANF + assert_eq!(Some(CF(300)), iter.next()); + assert_eq!(Some(AF(1, 100)), iter.next()); + assert_eq!(Some(CNF(40)), iter.next()); + assert_eq!(Some(ANF(2, 20)), iter.next()); + assert_eq!(None, iter.next()); + } + + #[test] + fn assets_into_works() { + let mut assets_vec: Vec = Vec::new(); + assets_vec.push(AF(1, 100)); + assets_vec.push(ANF(2, 20)); + assets_vec.push(CF(300)); + assets_vec.push(CNF(40)); + // Push same group of tokens again + assets_vec.push(AF(1, 100)); + assets_vec.push(ANF(2, 20)); + assets_vec.push(CF(300)); + assets_vec.push(CNF(40)); + + let assets: Assets = assets_vec.into(); + let mut iter = assets.into_assets_iter(); + // Fungibles add + assert_eq!(Some(CF(600)), iter.next()); + assert_eq!(Some(AF(1, 200)), iter.next()); + // Non-fungibles collapse + assert_eq!(Some(CNF(40)), iter.next()); + assert_eq!(Some(ANF(2, 20)), iter.next()); + assert_eq!(None, iter.next()); + } + + #[test] + fn min_all_and_none_works() { + let assets = test_assets(); + let none = MultiAssets::new().into(); + let all = All.into(); + + let none_min = assets.min(&none); + assert_eq!(None, none_min.assets_iter().next()); + let all_min = assets.min(&all); + assert!(all_min.assets_iter().eq(assets.assets_iter())); + } + + #[test] + fn min_counted_works() { + let mut assets = Assets::new(); + assets.subsume(AF(1, 100)); + assets.subsume(ANF(2, 20)); + assets.subsume(CNF(40)); + assets.subsume(AF(10, 50)); + assets.subsume(ANF(2, 40)); + assets.subsume(ANF(2, 30)); + assets.subsume(CF(3000)); + assets.subsume(CNF(80)); + assets.subsume(ANF(3, 10)); + let fungible = WildMultiAsset::from(([1u8; 32], WildFungible)).counted(2).into(); + let non_fungible = WildMultiAsset::from(([2u8; 32], WildNonFungible)).counted(2).into(); + let all = WildMultiAsset::AllCounted(6).into(); + + let fungible = assets.min(&fungible); + let fungible = fungible.assets_iter().collect::>(); + assert_eq!(fungible, vec![AF(1, 100)]); + let non_fungible = assets.min(&non_fungible); + let non_fungible = non_fungible.assets_iter().collect::>(); + assert_eq!(non_fungible, vec![ANF(2, 20), ANF(2, 30)]); + let all = assets.min(&all); + let all = all.assets_iter().collect::>(); + assert_eq!(all, vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 20),]); + } + + #[test] + fn min_all_abstract_works() { + let assets = test_assets(); + let fungible = Wild(([1u8; 32], WildFungible).into()); + let non_fungible = Wild(([2u8; 32], WildNonFungible).into()); + + let fungible = assets.min(&fungible); + let fungible = fungible.assets_iter().collect::>(); + assert_eq!(fungible, vec![AF(1, 100)]); + let non_fungible = assets.min(&non_fungible); + let non_fungible = non_fungible.assets_iter().collect::>(); + assert_eq!(non_fungible, vec![ANF(2, 20)]); + } + + #[test] + fn min_all_concrete_works() { + let assets = test_assets(); + let fungible = Wild((Here, WildFungible).into()); + let non_fungible = Wild((Here, WildNonFungible).into()); + + let fungible = assets.min(&fungible); + let fungible = fungible.assets_iter().collect::>(); + assert_eq!(fungible, vec![CF(300)]); + let non_fungible = assets.min(&non_fungible); + let non_fungible = non_fungible.assets_iter().collect::>(); + assert_eq!(non_fungible, vec![CNF(40)]); + } + + #[test] + fn min_basic_works() { + let assets1 = test_assets(); + + let mut assets2 = Assets::new(); + // This is less than 100, so it will decrease to 50 + assets2.subsume(AF(1, 50)); + // This asset does not exist, so not included + assets2.subsume(ANF(2, 40)); + // This is more then 300, so it should stay at 300 + assets2.subsume(CF(600)); + // This asset should be included + assets2.subsume(CNF(40)); + let assets2: MultiAssets = assets2.into(); + + let assets_min = assets1.min(&assets2.into()); + let assets_min = assets_min.into_assets_iter().collect::>(); + assert_eq!(assets_min, vec![CF(300), AF(1, 50), CNF(40)]); + } + + #[test] + fn saturating_take_all_and_none_works() { + let mut assets = test_assets(); + + let taken_none = assets.saturating_take(vec![].into()); + assert_eq!(None, taken_none.assets_iter().next()); + let taken_all = assets.saturating_take(All.into()); + // Everything taken + assert_eq!(None, assets.assets_iter().next()); + let all_iter = taken_all.assets_iter(); + assert!(all_iter.eq(test_assets().assets_iter())); + } + + #[test] + fn saturating_take_all_abstract_works() { + let mut assets = test_assets(); + let fungible = Wild(([1u8; 32], WildFungible).into()); + let non_fungible = Wild(([2u8; 32], WildNonFungible).into()); + + let fungible = assets.saturating_take(fungible); + let fungible = fungible.assets_iter().collect::>(); + assert_eq!(fungible, vec![AF(1, 100)]); + let non_fungible = assets.saturating_take(non_fungible); + let non_fungible = non_fungible.assets_iter().collect::>(); + assert_eq!(non_fungible, vec![ANF(2, 20)]); + // Assets drained of abstract + let final_assets = assets.assets_iter().collect::>(); + assert_eq!(final_assets, vec![CF(300), CNF(40)]); + } + + #[test] + fn saturating_take_all_concrete_works() { + let mut assets = test_assets(); + let fungible = Wild((Here, WildFungible).into()); + let non_fungible = Wild((Here, WildNonFungible).into()); + + let fungible = assets.saturating_take(fungible); + let fungible = fungible.assets_iter().collect::>(); + assert_eq!(fungible, vec![CF(300)]); + let non_fungible = assets.saturating_take(non_fungible); + let non_fungible = non_fungible.assets_iter().collect::>(); + assert_eq!(non_fungible, vec![CNF(40)]); + // Assets drained of concrete + let assets = assets.assets_iter().collect::>(); + assert_eq!(assets, vec![AF(1, 100), ANF(2, 20)]); + } + + #[test] + fn saturating_take_basic_works() { + let mut assets1 = test_assets(); + + let mut assets2 = Assets::new(); + // We should take 50 + assets2.subsume(AF(1, 50)); + // This asset should not be taken + assets2.subsume(ANF(2, 40)); + // This is more then 300, so it takes everything + assets2.subsume(CF(600)); + // This asset should be taken + assets2.subsume(CNF(40)); + let assets2: MultiAssets = assets2.into(); + + let taken = assets1.saturating_take(assets2.into()); + let taken = taken.into_assets_iter().collect::>(); + assert_eq!(taken, vec![CF(300), AF(1, 50), CNF(40)]); + + let assets = assets1.into_assets_iter().collect::>(); + assert_eq!(assets, vec![AF(1, 50), ANF(2, 20)]); + } + + #[test] + fn try_take_all_counted_works() { + let mut assets = Assets::new(); + assets.subsume(AF(1, 100)); + assets.subsume(ANF(2, 20)); + assets.subsume(CNF(40)); + assets.subsume(AF(10, 50)); + assets.subsume(ANF(2, 40)); + assets.subsume(ANF(2, 30)); + assets.subsume(CF(3000)); + assets.subsume(CNF(80)); + assets.subsume(ANF(3, 10)); + let all = assets.try_take(WildMultiAsset::AllCounted(6).into()).unwrap(); + assert_eq!( + MultiAssets::from(all).inner(), + &vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 20),] + ); + assert_eq!(MultiAssets::from(assets).inner(), &vec![ANF(2, 30), ANF(2, 40), ANF(3, 10),]); + } + + #[test] + fn try_take_fungibles_counted_works() { + let mut assets = Assets::new(); + assets.subsume(AF(1, 100)); + assets.subsume(ANF(2, 20)); + assets.subsume(CNF(40)); + assets.subsume(AF(10, 50)); + assets.subsume(ANF(2, 40)); + assets.subsume(ANF(2, 30)); + assets.subsume(CF(3000)); + assets.subsume(CNF(80)); + assets.subsume(ANF(3, 10)); + let mask = WildMultiAsset::from(([1u8; 32], WildFungible)).counted(2).into(); + let taken = assets.try_take(mask).unwrap(); + assert_eq!(MultiAssets::from(taken).inner(), &vec![AF(1, 100)]); + assert_eq!( + MultiAssets::from(assets).inner(), + &vec![ + CF(3000), + AF(10, 50), + CNF(40), + CNF(80), + ANF(2, 20), + ANF(2, 30), + ANF(2, 40), + ANF(3, 10), + ] + ); + } + + #[test] + fn try_take_non_fungibles_counted_works() { + let mut assets = Assets::new(); + assets.subsume(AF(1, 100)); + assets.subsume(ANF(2, 20)); + assets.subsume(CNF(40)); + assets.subsume(AF(10, 50)); + assets.subsume(ANF(2, 40)); + assets.subsume(ANF(2, 30)); + assets.subsume(CF(3000)); + assets.subsume(CNF(80)); + assets.subsume(ANF(3, 10)); + let mask = WildMultiAsset::from(([2u8; 32], WildNonFungible)).counted(2).into(); + let taken = assets.try_take(mask).unwrap(); + assert_eq!(MultiAssets::from(taken).inner(), &vec![ANF(2, 20), ANF(2, 30),]); + assert_eq!( + MultiAssets::from(assets).inner(), + &vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 40), ANF(3, 10),] + ); + } +} diff --git a/polkadot/xcm/xcm-executor/src/config.rs b/polkadot/xcm/xcm-executor/src/config.rs new file mode 100644 index 0000000000000000000000000000000000000000..1fc5cef39215380e2015c8d9d5dd273f3e15a87a --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/config.rs @@ -0,0 +1,113 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::traits::{ + AssetExchange, AssetLock, CallDispatcher, ClaimAssets, ConvertOrigin, DropAssets, ExportXcm, + FeeManager, OnResponse, ShouldExecute, TransactAsset, VersionChangeNotifier, WeightBounds, + WeightTrader, +}; +use frame_support::{ + dispatch::{Dispatchable, GetDispatchInfo, Parameter, PostDispatchInfo}, + traits::{Contains, ContainsPair, Get, PalletsInfoAccess}, +}; +use xcm::prelude::*; + +/// The trait to parameterize the `XcmExecutor`. +pub trait Config { + /// The outer call dispatch type. + type RuntimeCall: Parameter + Dispatchable + GetDispatchInfo; + + /// How to send an onward XCM message. + type XcmSender: SendXcm; + + /// How to withdraw and deposit an asset. + type AssetTransactor: TransactAsset; + + /// How to get a call origin from a `OriginKind` value. + type OriginConverter: ConvertOrigin<::RuntimeOrigin>; + + /// Combinations of (Asset, Location) pairs which we trust as reserves. + type IsReserve: ContainsPair; + + /// Combinations of (Asset, Location) pairs which we trust as teleporters. + type IsTeleporter: ContainsPair; + + /// A list of (Origin, Target) pairs allowing a given Origin to be substituted with its + /// corresponding Target pair. + type Aliasers: ContainsPair; + + /// This chain's Universal Location. + type UniversalLocation: Get; + + /// Whether we should execute the given XCM at all. + type Barrier: ShouldExecute; + + /// The means of determining an XCM message's weight. + type Weigher: WeightBounds; + + /// The means of purchasing weight credit for XCM execution. + type Trader: WeightTrader; + + /// What to do when a response of a query is found. + type ResponseHandler: OnResponse; + + /// The general asset trap - handler for when assets are left in the Holding Register at the + /// end of execution. + type AssetTrap: DropAssets; + + /// Handler for asset locking. + type AssetLocker: AssetLock; + + /// Handler for exchanging assets. + type AssetExchanger: AssetExchange; + + /// The handler for when there is an instruction to claim assets. + type AssetClaims: ClaimAssets; + + /// How we handle version subscription requests. + type SubscriptionService: VersionChangeNotifier; + + /// Information on all pallets. + type PalletInstancesInfo: PalletsInfoAccess; + + /// The maximum number of assets we target to have in the Holding Register at any one time. + /// + /// NOTE: In the worse case, the Holding Register may contain up to twice as many assets as this + /// and any benchmarks should take that into account. + type MaxAssetsIntoHolding: Get; + + /// Configure the fees. + type FeeManager: FeeManager; + + /// The method of exporting a message. + type MessageExporter: ExportXcm; + + /// The origin locations and specific universal junctions to which they are allowed to elevate + /// themselves. + type UniversalAliases: Contains<(MultiLocation, Junction)>; + + /// The call dispatcher used by XCM. + /// + /// XCM will use this to dispatch any calls. When no special call dispatcher is required, + /// this can be set to the same type as `Self::Call`. + type CallDispatcher: CallDispatcher; + + /// The safe call filter for `Transact`. + /// + /// Use this type to explicitly whitelist calls that cannot undergo recursion. This is a + /// temporary measure until we properly account for proof size weights for XCM instructions. + type SafeCallFilter: Contains; +} diff --git a/polkadot/xcm/xcm-executor/src/lib.rs b/polkadot/xcm/xcm-executor/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..a48cd3259d67a0ae0eaab55a373489122d1e8037 --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/lib.rs @@ -0,0 +1,1028 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +use frame_support::{ + dispatch::GetDispatchInfo, + ensure, + traits::{Contains, ContainsPair, Get, PalletsInfoAccess}, +}; +use parity_scale_codec::{Decode, Encode}; +use sp_core::defer; +use sp_io::hashing::blake2_128; +use sp_std::{marker::PhantomData, prelude::*}; +use sp_weights::Weight; +use xcm::latest::prelude::*; + +pub mod traits; +use traits::{ + validate_export, AssetExchange, AssetLock, CallDispatcher, ClaimAssets, ConvertOrigin, + DropAssets, Enact, ExportXcm, FeeManager, FeeReason, OnResponse, Properties, ShouldExecute, + TransactAsset, VersionChangeNotifier, WeightBounds, WeightTrader, +}; + +mod assets; +pub use assets::Assets; +mod config; +pub use config::Config; + +/// A struct to specify how fees are being paid. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct FeesMode { + /// If true, then the fee assets are taken directly from the origin's on-chain account, + /// otherwise the fee assets are taken from the holding register. + /// + /// Defaults to false. + pub jit_withdraw: bool, +} + +const RECURSION_LIMIT: u8 = 10; + +environmental::environmental!(recursion_count: u8); + +/// The XCM executor. +pub struct XcmExecutor { + holding: Assets, + holding_limit: usize, + context: XcmContext, + original_origin: MultiLocation, + trader: Config::Trader, + /// The most recent error result and instruction index into the fragment in which it occurred, + /// if any. + error: Option<(u32, XcmError)>, + /// The surplus weight, defined as the amount by which `max_weight` is + /// an over-estimate of the actual weight consumed. We do it this way to avoid needing the + /// execution engine to keep track of all instructions' weights (it only needs to care about + /// the weight of dynamically determined instructions such as `Transact`). + total_surplus: Weight, + total_refunded: Weight, + error_handler: Xcm, + error_handler_weight: Weight, + appendix: Xcm, + appendix_weight: Weight, + transact_status: MaybeErrorCode, + fees_mode: FeesMode, + _config: PhantomData, +} + +#[cfg(feature = "runtime-benchmarks")] +impl XcmExecutor { + pub fn holding(&self) -> &Assets { + &self.holding + } + pub fn set_holding(&mut self, v: Assets) { + self.holding = v + } + pub fn holding_limit(&self) -> &usize { + &self.holding_limit + } + pub fn set_holding_limit(&mut self, v: usize) { + self.holding_limit = v + } + pub fn origin(&self) -> &Option { + &self.context.origin + } + pub fn set_origin(&mut self, v: Option) { + self.context.origin = v + } + pub fn original_origin(&self) -> &MultiLocation { + &self.original_origin + } + pub fn set_original_origin(&mut self, v: MultiLocation) { + self.original_origin = v + } + pub fn trader(&self) -> &Config::Trader { + &self.trader + } + pub fn set_trader(&mut self, v: Config::Trader) { + self.trader = v + } + pub fn error(&self) -> &Option<(u32, XcmError)> { + &self.error + } + pub fn set_error(&mut self, v: Option<(u32, XcmError)>) { + self.error = v + } + pub fn total_surplus(&self) -> &Weight { + &self.total_surplus + } + pub fn set_total_surplus(&mut self, v: Weight) { + self.total_surplus = v + } + pub fn total_refunded(&self) -> &Weight { + &self.total_refunded + } + pub fn set_total_refunded(&mut self, v: Weight) { + self.total_refunded = v + } + pub fn error_handler(&self) -> &Xcm { + &self.error_handler + } + pub fn set_error_handler(&mut self, v: Xcm) { + self.error_handler = v + } + pub fn error_handler_weight(&self) -> &Weight { + &self.error_handler_weight + } + pub fn set_error_handler_weight(&mut self, v: Weight) { + self.error_handler_weight = v + } + pub fn appendix(&self) -> &Xcm { + &self.appendix + } + pub fn set_appendix(&mut self, v: Xcm) { + self.appendix = v + } + pub fn appendix_weight(&self) -> &Weight { + &self.appendix_weight + } + pub fn set_appendix_weight(&mut self, v: Weight) { + self.appendix_weight = v + } + pub fn transact_status(&self) -> &MaybeErrorCode { + &self.transact_status + } + pub fn set_transact_status(&mut self, v: MaybeErrorCode) { + self.transact_status = v + } + pub fn fees_mode(&self) -> &FeesMode { + &self.fees_mode + } + pub fn set_fees_mode(&mut self, v: FeesMode) { + self.fees_mode = v + } + pub fn topic(&self) -> &Option<[u8; 32]> { + &self.context.topic + } + pub fn set_topic(&mut self, v: Option<[u8; 32]>) { + self.context.topic = v; + } +} + +pub struct WeighedMessage(Weight, Xcm); +impl PreparedMessage for WeighedMessage { + fn weight_of(&self) -> Weight { + self.0 + } +} + +impl ExecuteXcm for XcmExecutor { + type Prepared = WeighedMessage; + fn prepare( + mut message: Xcm, + ) -> Result> { + match Config::Weigher::weight(&mut message) { + Ok(weight) => Ok(WeighedMessage(weight, message)), + Err(_) => Err(message), + } + } + fn execute( + origin: impl Into, + WeighedMessage(xcm_weight, mut message): WeighedMessage, + id: &mut XcmHash, + weight_credit: Weight, + ) -> Outcome { + let origin = origin.into(); + log::trace!( + target: "xcm::execute_xcm_in_credit", + "origin: {:?}, message: {:?}, weight_credit: {:?}", + origin, + message, + weight_credit, + ); + let mut properties = Properties { weight_credit, message_id: None }; + if let Err(e) = Config::Barrier::should_execute( + &origin, + message.inner_mut(), + xcm_weight, + &mut properties, + ) { + log::trace!( + target: "xcm::execute_xcm_in_credit", + "Barrier blocked execution! Error: {:?}. (origin: {:?}, message: {:?}, properties: {:?})", + e, + origin, + message, + properties, + ); + return Outcome::Error(XcmError::Barrier) + } + + *id = properties.message_id.unwrap_or(*id); + + let mut vm = Self::new(origin, *id); + + while !message.0.is_empty() { + let result = vm.process(message); + log::trace!(target: "xcm::execute_xcm_in_credit", "result: {:?}", result); + message = if let Err(error) = result { + vm.total_surplus.saturating_accrue(error.weight); + vm.error = Some((error.index, error.xcm_error)); + vm.take_error_handler().or_else(|| vm.take_appendix()) + } else { + vm.drop_error_handler(); + vm.take_appendix() + } + } + + vm.post_process(xcm_weight) + } + + fn charge_fees(origin: impl Into, fees: MultiAssets) -> XcmResult { + let origin = origin.into(); + if !Config::FeeManager::is_waived(Some(&origin), FeeReason::ChargeFees) { + for asset in fees.inner() { + Config::AssetTransactor::withdraw_asset(&asset, &origin, None)?; + } + Config::FeeManager::handle_fee(fees); + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct ExecutorError { + pub index: u32, + pub xcm_error: XcmError, + pub weight: Weight, +} + +#[cfg(feature = "runtime-benchmarks")] +impl From for frame_benchmarking::BenchmarkError { + fn from(error: ExecutorError) -> Self { + log::error!( + "XCM ERROR >> Index: {:?}, Error: {:?}, Weight: {:?}", + error.index, + error.xcm_error, + error.weight + ); + Self::Stop("xcm executor error: see error logs") + } +} + +impl XcmExecutor { + pub fn new(origin: impl Into, message_id: XcmHash) -> Self { + let origin = origin.into(); + Self { + holding: Assets::new(), + holding_limit: Config::MaxAssetsIntoHolding::get() as usize, + context: XcmContext { origin: Some(origin), message_id, topic: None }, + original_origin: origin, + trader: Config::Trader::new(), + error: None, + total_surplus: Weight::zero(), + total_refunded: Weight::zero(), + error_handler: Xcm(vec![]), + error_handler_weight: Weight::zero(), + appendix: Xcm(vec![]), + appendix_weight: Weight::zero(), + transact_status: Default::default(), + fees_mode: FeesMode { jit_withdraw: false }, + _config: PhantomData, + } + } + + #[cfg(feature = "runtime-benchmarks")] + pub fn bench_process(&mut self, xcm: Xcm) -> Result<(), ExecutorError> { + self.process(xcm) + } + + fn process(&mut self, xcm: Xcm) -> Result<(), ExecutorError> { + log::trace!( + target: "xcm::process", + "origin: {:?}, total_surplus/refunded: {:?}/{:?}, error_handler_weight: {:?}", + self.origin_ref(), + self.total_surplus, + self.total_refunded, + self.error_handler_weight, + ); + let mut result = Ok(()); + for (i, instr) in xcm.0.into_iter().enumerate() { + match &mut result { + r @ Ok(()) => { + // Initialize the recursion count only the first time we hit this code in our + // potential recursive execution. + let inst_res = recursion_count::using_once(&mut 1, || { + recursion_count::with(|count| { + if *count > RECURSION_LIMIT { + return Err(XcmError::ExceedsStackLimit) + } + *count = count.saturating_add(1); + Ok(()) + }) + // This should always return `Some`, but let's play it safe. + .unwrap_or(Ok(()))?; + + // Ensure that we always decrement the counter whenever we finish processing + // the instruction. + defer! { + recursion_count::with(|count| { + *count = count.saturating_sub(1); + }); + } + + self.process_instruction(instr) + }); + if let Err(e) = inst_res { + log::trace!(target: "xcm::execute", "!!! ERROR: {:?}", e); + *r = Err(ExecutorError { + index: i as u32, + xcm_error: e, + weight: Weight::zero(), + }); + } + }, + Err(ref mut error) => + if let Ok(x) = Config::Weigher::instr_weight(&instr) { + error.weight.saturating_accrue(x) + }, + } + } + result + } + + /// Execute any final operations after having executed the XCM message. + /// This includes refunding surplus weight, trapping extra holding funds, and returning any + /// errors during execution. + pub fn post_process(mut self, xcm_weight: Weight) -> Outcome { + // We silently drop any error from our attempt to refund the surplus as it's a charitable + // thing so best-effort is all we will do. + let _ = self.refund_surplus(); + drop(self.trader); + + let mut weight_used = xcm_weight.saturating_sub(self.total_surplus); + + if !self.holding.is_empty() { + log::trace!( + target: "xcm::execute_xcm_in_credit", + "Trapping assets in holding register: {:?}, context: {:?} (original_origin: {:?})", + self.holding, self.context, self.original_origin, + ); + let effective_origin = self.context.origin.as_ref().unwrap_or(&self.original_origin); + let trap_weight = + Config::AssetTrap::drop_assets(effective_origin, self.holding, &self.context); + weight_used.saturating_accrue(trap_weight); + }; + + match self.error { + None => Outcome::Complete(weight_used), + // TODO: #2841 #REALWEIGHT We should deduct the cost of any instructions following + // the error which didn't end up being executed. + Some((_i, e)) => { + log::trace!(target: "xcm::execute_xcm_in_credit", "Execution errored at {:?}: {:?} (original_origin: {:?})", _i, e, self.original_origin); + Outcome::Incomplete(weight_used, e) + }, + } + } + + fn origin_ref(&self) -> Option<&MultiLocation> { + self.context.origin.as_ref() + } + + fn cloned_origin(&self) -> Option { + self.context.origin + } + + /// Send an XCM, charging fees from Holding as needed. + fn send( + &mut self, + dest: MultiLocation, + msg: Xcm<()>, + reason: FeeReason, + ) -> Result { + let (ticket, fee) = validate_send::(dest, msg)?; + if !Config::FeeManager::is_waived(self.origin_ref(), reason) { + let paid = self.holding.try_take(fee.into()).map_err(|_| XcmError::NotHoldingFees)?; + Config::FeeManager::handle_fee(paid.into()); + } + Config::XcmSender::deliver(ticket).map_err(Into::into) + } + + /// Remove the registered error handler and return it. Do not refund its weight. + fn take_error_handler(&mut self) -> Xcm { + let mut r = Xcm::(vec![]); + sp_std::mem::swap(&mut self.error_handler, &mut r); + self.error_handler_weight = Weight::zero(); + r + } + + /// Drop the registered error handler and refund its weight. + fn drop_error_handler(&mut self) { + self.error_handler = Xcm::(vec![]); + self.total_surplus.saturating_accrue(self.error_handler_weight); + self.error_handler_weight = Weight::zero(); + } + + /// Remove the registered appendix and return it. + fn take_appendix(&mut self) -> Xcm { + let mut r = Xcm::(vec![]); + sp_std::mem::swap(&mut self.appendix, &mut r); + self.appendix_weight = Weight::zero(); + r + } + + fn subsume_asset(&mut self, asset: MultiAsset) -> Result<(), XcmError> { + // worst-case, holding.len becomes 2 * holding_limit. + ensure!(self.holding.len() < self.holding_limit * 2, XcmError::HoldingWouldOverflow); + self.holding.subsume(asset); + Ok(()) + } + + fn subsume_assets(&mut self, assets: Assets) -> Result<(), XcmError> { + // worst-case, holding.len becomes 2 * holding_limit. + // this guarantees that if holding.len() == holding_limit and you have holding_limit more + // items (which has a best case outcome of holding.len() == holding_limit), then you'll + // be guaranteed of making the operation. + let worst_case_holding_len = self.holding.len() + assets.len(); + ensure!(worst_case_holding_len <= self.holding_limit * 2, XcmError::HoldingWouldOverflow); + self.holding.subsume_assets(assets); + Ok(()) + } + + /// Refund any unused weight. + fn refund_surplus(&mut self) -> Result<(), XcmError> { + let current_surplus = self.total_surplus.saturating_sub(self.total_refunded); + if current_surplus.any_gt(Weight::zero()) { + self.total_refunded.saturating_accrue(current_surplus); + if let Some(w) = self.trader.refund_weight(current_surplus, &self.context) { + self.subsume_asset(w)?; + } + } + Ok(()) + } + + /// Process a single XCM instruction, mutating the state of the XCM virtual machine. + fn process_instruction( + &mut self, + instr: Instruction, + ) -> Result<(), XcmError> { + log::trace!( + target: "xcm::process_instruction", + "=== {:?}", + instr + ); + match instr { + WithdrawAsset(assets) => { + // Take `assets` from the origin account (on-chain) and place in holding. + let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + for asset in assets.into_inner().into_iter() { + Config::AssetTransactor::withdraw_asset(&asset, &origin, Some(&self.context))?; + self.subsume_asset(asset)?; + } + Ok(()) + }, + ReserveAssetDeposited(assets) => { + // check whether we trust origin to be our reserve location for this asset. + let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + for asset in assets.into_inner().into_iter() { + // Must ensure that we recognise the asset as being managed by the origin. + ensure!( + Config::IsReserve::contains(&asset, &origin), + XcmError::UntrustedReserveLocation + ); + self.subsume_asset(asset)?; + } + Ok(()) + }, + TransferAsset { assets, beneficiary } => { + // Take `assets` from the origin account (on-chain) and place into dest account. + let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?; + for asset in assets.inner() { + Config::AssetTransactor::transfer_asset( + &asset, + origin, + &beneficiary, + &self.context, + )?; + } + Ok(()) + }, + TransferReserveAsset { mut assets, dest, xcm } => { + let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?; + // Take `assets` from the origin account (on-chain) and place into dest account. + for asset in assets.inner() { + Config::AssetTransactor::transfer_asset(asset, origin, &dest, &self.context)?; + } + let reanchor_context = Config::UniversalLocation::get(); + assets.reanchor(&dest, reanchor_context).map_err(|()| XcmError::LocationFull)?; + let mut message = vec![ReserveAssetDeposited(assets), ClearOrigin]; + message.extend(xcm.0.into_iter()); + self.send(dest, Xcm(message), FeeReason::TransferReserveAsset)?; + Ok(()) + }, + ReceiveTeleportedAsset(assets) => { + let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + // check whether we trust origin to teleport this asset to us via config trait. + for asset in assets.inner() { + // We only trust the origin to send us assets that they identify as their + // sovereign assets. + ensure!( + Config::IsTeleporter::contains(asset, &origin), + XcmError::UntrustedTeleportLocation + ); + // We should check that the asset can actually be teleported in (for this to be + // in error, there would need to be an accounting violation by one of the + // trusted chains, so it's unlikely, but we don't want to punish a possibly + // innocent chain/user). + Config::AssetTransactor::can_check_in(&origin, asset, &self.context)?; + } + for asset in assets.into_inner().into_iter() { + Config::AssetTransactor::check_in(&origin, &asset, &self.context); + self.subsume_asset(asset)?; + } + Ok(()) + }, + Transact { origin_kind, require_weight_at_most, mut call } => { + // We assume that the Relay-chain is allowed to use transact on this parachain. + let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + + // TODO: #2841 #TRANSACTFILTER allow the trait to issue filters for the relay-chain + let message_call = call.take_decoded().map_err(|_| XcmError::FailedToDecode)?; + ensure!(Config::SafeCallFilter::contains(&message_call), XcmError::NoPermission); + let dispatch_origin = Config::OriginConverter::convert_origin(origin, origin_kind) + .map_err(|_| XcmError::BadOrigin)?; + let weight = message_call.get_dispatch_info().weight; + ensure!(weight.all_lte(require_weight_at_most), XcmError::MaxWeightInvalid); + let maybe_actual_weight = + match Config::CallDispatcher::dispatch(message_call, dispatch_origin) { + Ok(post_info) => { + self.transact_status = MaybeErrorCode::Success; + post_info.actual_weight + }, + Err(error_and_info) => { + self.transact_status = error_and_info.error.encode().into(); + error_and_info.post_info.actual_weight + }, + }; + let actual_weight = maybe_actual_weight.unwrap_or(weight); + let surplus = weight.saturating_sub(actual_weight); + // We assume that the `Config::Weigher` will counts the `require_weight_at_most` + // for the estimate of how much weight this instruction will take. Now that we know + // that it's less, we credit it. + // + // We make the adjustment for the total surplus, which is used eventually + // reported back to the caller and this ensures that they account for the total + // weight consumed correctly (potentially allowing them to do more operations in a + // block than they otherwise would). + self.total_surplus.saturating_accrue(surplus); + Ok(()) + }, + QueryResponse { query_id, response, max_weight, querier } => { + let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?; + Config::ResponseHandler::on_response( + origin, + query_id, + querier.as_ref(), + response, + max_weight, + &self.context, + ); + Ok(()) + }, + DescendOrigin(who) => self + .context + .origin + .as_mut() + .ok_or(XcmError::BadOrigin)? + .append_with(who) + .map_err(|_| XcmError::LocationFull), + ClearOrigin => { + self.context.origin = None; + Ok(()) + }, + ReportError(response_info) => { + // Report the given result by sending a QueryResponse XCM to a previously given + // outcome destination if one was registered. + self.respond( + self.cloned_origin(), + Response::ExecutionResult(self.error), + response_info, + FeeReason::Report, + )?; + Ok(()) + }, + DepositAsset { assets, beneficiary } => { + let deposited = self.holding.saturating_take(assets); + for asset in deposited.into_assets_iter() { + Config::AssetTransactor::deposit_asset(&asset, &beneficiary, &self.context)?; + } + Ok(()) + }, + DepositReserveAsset { assets, dest, xcm } => { + let deposited = self.holding.saturating_take(assets); + for asset in deposited.assets_iter() { + Config::AssetTransactor::deposit_asset(&asset, &dest, &self.context)?; + } + // Note that we pass `None` as `maybe_failed_bin` and drop any assets which cannot + // be reanchored because we have already called `deposit_asset` on all assets. + let assets = Self::reanchored(deposited, &dest, None); + let mut message = vec![ReserveAssetDeposited(assets), ClearOrigin]; + message.extend(xcm.0.into_iter()); + self.send(dest, Xcm(message), FeeReason::DepositReserveAsset)?; + Ok(()) + }, + InitiateReserveWithdraw { assets, reserve, xcm } => { + // Note that here we are able to place any assets which could not be reanchored + // back into Holding. + let assets = Self::reanchored( + self.holding.saturating_take(assets), + &reserve, + Some(&mut self.holding), + ); + let mut message = vec![WithdrawAsset(assets), ClearOrigin]; + message.extend(xcm.0.into_iter()); + self.send(reserve, Xcm(message), FeeReason::InitiateReserveWithdraw)?; + Ok(()) + }, + InitiateTeleport { assets, dest, xcm } => { + // We must do this first in order to resolve wildcards. + let assets = self.holding.saturating_take(assets); + for asset in assets.assets_iter() { + // We should check that the asset can actually be teleported out (for this to + // be in error, there would need to be an accounting violation by ourselves, + // so it's unlikely, but we don't want to allow that kind of bug to leak into + // a trusted chain. + Config::AssetTransactor::can_check_out(&dest, &asset, &self.context)?; + } + for asset in assets.assets_iter() { + Config::AssetTransactor::check_out(&dest, &asset, &self.context); + } + // Note that we pass `None` as `maybe_failed_bin` and drop any assets which cannot + // be reanchored because we have already checked all assets out. + let assets = Self::reanchored(assets, &dest, None); + let mut message = vec![ReceiveTeleportedAsset(assets), ClearOrigin]; + message.extend(xcm.0.into_iter()); + self.send(dest, Xcm(message), FeeReason::InitiateTeleport)?; + Ok(()) + }, + ReportHolding { response_info, assets } => { + // Note that we pass `None` as `maybe_failed_bin` since no assets were ever removed + // from Holding. + let assets = + Self::reanchored(self.holding.min(&assets), &response_info.destination, None); + self.respond( + self.cloned_origin(), + Response::Assets(assets), + response_info, + FeeReason::Report, + )?; + Ok(()) + }, + BuyExecution { fees, weight_limit } => { + // There is no need to buy any weight is `weight_limit` is `Unlimited` since it + // would indicate that `AllowTopLevelPaidExecutionFrom` was unused for execution + // and thus there is some other reason why it has been determined that this XCM + // should be executed. + if let Some(weight) = Option::::from(weight_limit) { + // pay for `weight` using up to `fees` of the holding register. + let max_fee = + self.holding.try_take(fees.into()).map_err(|_| XcmError::NotHoldingFees)?; + let unspent = self.trader.buy_weight(weight, max_fee, &self.context)?; + self.subsume_assets(unspent)?; + } + Ok(()) + }, + RefundSurplus => self.refund_surplus(), + SetErrorHandler(mut handler) => { + let handler_weight = Config::Weigher::weight(&mut handler) + .map_err(|()| XcmError::WeightNotComputable)?; + self.total_surplus.saturating_accrue(self.error_handler_weight); + self.error_handler = handler; + self.error_handler_weight = handler_weight; + Ok(()) + }, + SetAppendix(mut appendix) => { + let appendix_weight = Config::Weigher::weight(&mut appendix) + .map_err(|()| XcmError::WeightNotComputable)?; + self.total_surplus.saturating_accrue(self.appendix_weight); + self.appendix = appendix; + self.appendix_weight = appendix_weight; + Ok(()) + }, + ClearError => { + self.error = None; + Ok(()) + }, + ClaimAsset { assets, ticket } => { + let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?; + let ok = Config::AssetClaims::claim_assets(origin, &ticket, &assets, &self.context); + ensure!(ok, XcmError::UnknownClaim); + for asset in assets.into_inner().into_iter() { + self.subsume_asset(asset)?; + } + Ok(()) + }, + Trap(code) => Err(XcmError::Trap(code)), + SubscribeVersion { query_id, max_response_weight } => { + let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?; + // We don't allow derivative origins to subscribe since it would otherwise pose a + // DoS risk. + ensure!(&self.original_origin == origin, XcmError::BadOrigin); + Config::SubscriptionService::start( + origin, + query_id, + max_response_weight, + &self.context, + ) + }, + UnsubscribeVersion => { + let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?; + ensure!(&self.original_origin == origin, XcmError::BadOrigin); + Config::SubscriptionService::stop(origin, &self.context) + }, + BurnAsset(assets) => { + self.holding.saturating_take(assets.into()); + Ok(()) + }, + ExpectAsset(assets) => + self.holding.ensure_contains(&assets).map_err(|_| XcmError::ExpectationFalse), + ExpectOrigin(origin) => { + ensure!(self.context.origin == origin, XcmError::ExpectationFalse); + Ok(()) + }, + ExpectError(error) => { + ensure!(self.error == error, XcmError::ExpectationFalse); + Ok(()) + }, + ExpectTransactStatus(transact_status) => { + ensure!(self.transact_status == transact_status, XcmError::ExpectationFalse); + Ok(()) + }, + QueryPallet { module_name, response_info } => { + let pallets = Config::PalletInstancesInfo::infos() + .into_iter() + .filter(|x| x.module_name.as_bytes() == &module_name[..]) + .map(|x| { + PalletInfo::new( + x.index as u32, + x.name.as_bytes().into(), + x.module_name.as_bytes().into(), + x.crate_version.major as u32, + x.crate_version.minor as u32, + x.crate_version.patch as u32, + ) + }) + .collect::, XcmError>>()?; + let QueryResponseInfo { destination, query_id, max_weight } = response_info; + let response = + Response::PalletsInfo(pallets.try_into().map_err(|_| XcmError::Overflow)?); + let querier = Self::to_querier(self.cloned_origin(), &destination)?; + let instruction = QueryResponse { query_id, response, max_weight, querier }; + let message = Xcm(vec![instruction]); + self.send(destination, message, FeeReason::QueryPallet)?; + Ok(()) + }, + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => { + let pallet = Config::PalletInstancesInfo::infos() + .into_iter() + .find(|x| x.index == index as usize) + .ok_or(XcmError::PalletNotFound)?; + ensure!(pallet.name.as_bytes() == &name[..], XcmError::NameMismatch); + ensure!(pallet.module_name.as_bytes() == &module_name[..], XcmError::NameMismatch); + let major = pallet.crate_version.major as u32; + ensure!(major == crate_major, XcmError::VersionIncompatible); + let minor = pallet.crate_version.minor as u32; + ensure!(minor >= min_crate_minor, XcmError::VersionIncompatible); + Ok(()) + }, + ReportTransactStatus(response_info) => { + self.respond( + self.cloned_origin(), + Response::DispatchResult(self.transact_status.clone()), + response_info, + FeeReason::Report, + )?; + Ok(()) + }, + ClearTransactStatus => { + self.transact_status = Default::default(); + Ok(()) + }, + UniversalOrigin(new_global) => { + let universal_location = Config::UniversalLocation::get(); + ensure!(universal_location.first() != Some(&new_global), XcmError::InvalidLocation); + let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin_xform = (origin, new_global); + let ok = Config::UniversalAliases::contains(&origin_xform); + ensure!(ok, XcmError::InvalidLocation); + let (_, new_global) = origin_xform; + let new_origin = X1(new_global).relative_to(&universal_location); + self.context.origin = Some(new_origin); + Ok(()) + }, + ExportMessage { network, destination, xcm } => { + // The actual message sent to the bridge for forwarding is prepended with + // `UniversalOrigin` and `DescendOrigin` in order to ensure that the message is + // executed with this Origin. + // + // Prepend the desired message with instructions which effectively rewrite the + // origin. + // + // This only works because the remote chain empowers the bridge + // to speak for the local network. + let origin = self.context.origin.ok_or(XcmError::BadOrigin)?; + let universal_source = Config::UniversalLocation::get() + .within_global(origin) + .map_err(|()| XcmError::Unanchored)?; + let hash = (self.origin_ref(), &destination).using_encoded(blake2_128); + let channel = u32::decode(&mut hash.as_ref()).unwrap_or(0); + // Hash identifies the lane on the exporter which we use. We use the pairwise + // combination of the origin and destination to ensure origin/destination pairs will + // generally have their own lanes. + let (ticket, fee) = validate_export::( + network, + channel, + universal_source, + destination, + xcm, + )?; + self.take_fee(fee, FeeReason::Export(network))?; + Config::MessageExporter::deliver(ticket)?; + Ok(()) + }, + LockAsset { asset, unlocker } => { + let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let (remote_asset, context) = Self::try_reanchor(asset.clone(), &unlocker)?; + let lock_ticket = Config::AssetLocker::prepare_lock(unlocker, asset, origin)?; + let owner = + origin.reanchored(&unlocker, context).map_err(|_| XcmError::ReanchorFailed)?; + let msg = Xcm::<()>(vec![NoteUnlockable { asset: remote_asset, owner }]); + let (ticket, price) = validate_send::(unlocker, msg)?; + self.take_fee(price, FeeReason::LockAsset)?; + lock_ticket.enact()?; + Config::XcmSender::deliver(ticket)?; + Ok(()) + }, + UnlockAsset { asset, target } => { + let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + Config::AssetLocker::prepare_unlock(origin, asset, target)?.enact()?; + Ok(()) + }, + NoteUnlockable { asset, owner } => { + let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + Config::AssetLocker::note_unlockable(origin, asset, owner)?; + Ok(()) + }, + RequestUnlock { asset, locker } => { + let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let remote_asset = Self::try_reanchor(asset.clone(), &locker)?.0; + let remote_target = Self::try_reanchor_multilocation(origin, &locker)?.0; + let reduce_ticket = + Config::AssetLocker::prepare_reduce_unlockable(locker, asset, origin)?; + let msg = + Xcm::<()>(vec![UnlockAsset { asset: remote_asset, target: remote_target }]); + let (ticket, price) = validate_send::(locker, msg)?; + self.take_fee(price, FeeReason::RequestUnlock)?; + reduce_ticket.enact()?; + Config::XcmSender::deliver(ticket)?; + Ok(()) + }, + ExchangeAsset { give, want, maximal } => { + let give = self.holding.saturating_take(give); + let r = + Config::AssetExchanger::exchange_asset(self.origin_ref(), give, &want, maximal); + let completed = r.is_ok(); + let received = r.unwrap_or_else(|a| a); + for asset in received.into_assets_iter() { + self.holding.subsume(asset); + } + if completed { + Ok(()) + } else { + Err(XcmError::NoDeal) + } + }, + SetFeesMode { jit_withdraw } => { + self.fees_mode = FeesMode { jit_withdraw }; + Ok(()) + }, + SetTopic(topic) => { + self.context.topic = Some(topic); + Ok(()) + }, + ClearTopic => { + self.context.topic = None; + Ok(()) + }, + AliasOrigin(target) => { + let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?; + if Config::Aliasers::contains(origin, &target) { + self.context.origin = Some(target); + Ok(()) + } else { + Err(XcmError::NoPermission) + } + }, + UnpaidExecution { check_origin, .. } => { + ensure!( + check_origin.is_none() || self.context.origin == check_origin, + XcmError::BadOrigin + ); + Ok(()) + }, + HrmpNewChannelOpenRequest { .. } => Err(XcmError::Unimplemented), + HrmpChannelAccepted { .. } => Err(XcmError::Unimplemented), + HrmpChannelClosing { .. } => Err(XcmError::Unimplemented), + } + } + + fn take_fee(&mut self, fee: MultiAssets, reason: FeeReason) -> XcmResult { + if Config::FeeManager::is_waived(self.origin_ref(), reason) { + return Ok(()) + } + let paid = if self.fees_mode.jit_withdraw { + let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?; + for asset in fee.inner() { + Config::AssetTransactor::withdraw_asset(&asset, origin, Some(&self.context))?; + } + fee + } else { + self.holding.try_take(fee.into()).map_err(|_| XcmError::NotHoldingFees)?.into() + }; + Config::FeeManager::handle_fee(paid); + Ok(()) + } + + /// Calculates what `local_querier` would be from the perspective of `destination`. + fn to_querier( + local_querier: Option, + destination: &MultiLocation, + ) -> Result, XcmError> { + Ok(match local_querier { + None => None, + Some(q) => Some( + q.reanchored(&destination, Config::UniversalLocation::get()) + .map_err(|_| XcmError::ReanchorFailed)?, + ), + }) + } + + /// Send a bare `QueryResponse` message containing `response` informed by the given `info`. + /// + /// The `local_querier` argument is the querier (if any) specified from the *local* perspective. + fn respond( + &mut self, + local_querier: Option, + response: Response, + info: QueryResponseInfo, + fee_reason: FeeReason, + ) -> Result { + let querier = Self::to_querier(local_querier, &info.destination)?; + let QueryResponseInfo { destination, query_id, max_weight } = info; + let instruction = QueryResponse { query_id, response, max_weight, querier }; + let message = Xcm(vec![instruction]); + let (ticket, fee) = validate_send::(destination, message)?; + if !Config::FeeManager::is_waived(self.origin_ref(), fee_reason) { + let paid = self.holding.try_take(fee.into()).map_err(|_| XcmError::NotHoldingFees)?; + Config::FeeManager::handle_fee(paid.into()); + } + Config::XcmSender::deliver(ticket).map_err(Into::into) + } + + fn try_reanchor( + asset: MultiAsset, + destination: &MultiLocation, + ) -> Result<(MultiAsset, InteriorMultiLocation), XcmError> { + let reanchor_context = Config::UniversalLocation::get(); + let asset = asset + .reanchored(&destination, reanchor_context) + .map_err(|()| XcmError::ReanchorFailed)?; + Ok((asset, reanchor_context)) + } + + fn try_reanchor_multilocation( + location: MultiLocation, + destination: &MultiLocation, + ) -> Result<(MultiLocation, InteriorMultiLocation), XcmError> { + let reanchor_context = Config::UniversalLocation::get(); + let location = location + .reanchored(&destination, reanchor_context) + .map_err(|_| XcmError::ReanchorFailed)?; + Ok((location, reanchor_context)) + } + + /// NOTE: Any assets which were unable to be reanchored are introduced into `failed_bin`. + fn reanchored( + mut assets: Assets, + dest: &MultiLocation, + maybe_failed_bin: Option<&mut Assets>, + ) -> MultiAssets { + let reanchor_context = Config::UniversalLocation::get(); + assets.reanchor(dest, reanchor_context, maybe_failed_bin); + assets.into_assets_iter().collect::>().into() + } +} diff --git a/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs b/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs new file mode 100644 index 0000000000000000000000000000000000000000..0cb188d348de7b4ff7e7cd3ce3a3d99e83976907 --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs @@ -0,0 +1,58 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::Assets; +use xcm::prelude::*; + +/// A service for exchanging assets. +pub trait AssetExchange { + /// Handler for exchanging an asset. + /// + /// - `origin`: The location attempting the exchange; this should generally not matter. + /// - `give`: The assets which have been removed from the caller. + /// - `want`: The minimum amount of assets which should be given to the caller in case any + /// exchange happens. If more assets are provided, then they should generally be of the same + /// asset class if at all possible. + /// - `maximal`: If `true`, then as much as possible should be exchanged. + /// + /// `Ok` is returned along with the new set of assets which have been exchanged for `give`. At + /// least want must be in the set. Some assets originally in `give` may also be in this set. In + /// the case of returning an `Err`, then `give` is returned. + fn exchange_asset( + origin: Option<&MultiLocation>, + give: Assets, + want: &MultiAssets, + maximal: bool, + ) -> Result; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl AssetExchange for Tuple { + fn exchange_asset( + origin: Option<&MultiLocation>, + give: Assets, + want: &MultiAssets, + maximal: bool, + ) -> Result { + for_tuples!( #( + let give = match Tuple::exchange_asset(origin, give, want, maximal) { + Ok(r) => return Ok(r), + Err(a) => a, + }; + )* ); + Err(give) + } +} diff --git a/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs b/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs new file mode 100644 index 0000000000000000000000000000000000000000..b5a2b22f5fc5b2eae80a5f5a42b22cd99d82901a --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs @@ -0,0 +1,152 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use sp_std::convert::Infallible; +use xcm::prelude::*; + +#[derive(Debug)] +pub enum LockError { + NotApplicable, + WouldClobber, + BadOrigin, + NotLocked, + NotEnoughLocked, + Unimplemented, + NotTrusted, + BadOwner, + UnknownAsset, + AssetNotOwned, + NoResources, + UnexpectedState, + InUse, +} + +impl From for XcmError { + fn from(e: LockError) -> XcmError { + use LockError::*; + match e { + NotApplicable => XcmError::AssetNotFound, + BadOrigin => XcmError::BadOrigin, + WouldClobber | NotLocked | NotEnoughLocked | Unimplemented | NotTrusted | + BadOwner | UnknownAsset | AssetNotOwned | NoResources | UnexpectedState | InUse => + XcmError::LockError, + } + } +} + +pub trait Enact { + /// Enact a lock. This should generally be infallible if called immediately after being + /// received. + fn enact(self) -> Result<(), LockError>; +} + +impl Enact for Infallible { + fn enact(self) -> Result<(), LockError> { + unreachable!() + } +} + +/// Define a handler for notification of an asset being locked and for the unlock instruction. +pub trait AssetLock { + /// `Enact` implementer for `prepare_lock`. This type may be dropped safely to avoid doing the + /// lock. + type LockTicket: Enact; + + /// `Enact` implementer for `prepare_unlock`. This type may be dropped safely to avoid doing the + /// unlock. + type UnlockTicket: Enact; + + /// `Enact` implementer for `prepare_reduce_unlockable`. This type may be dropped safely to + /// avoid doing the unlock. + type ReduceTicket: Enact; + + /// Prepare to lock an asset. On success, a `Self::LockTicket` it returned, which can be used + /// to actually enact the lock. + /// + /// WARNING: Don't call this with an undropped instance of `Self::LockTicket` or + /// `Self::UnlockTicket`. + fn prepare_lock( + unlocker: MultiLocation, + asset: MultiAsset, + owner: MultiLocation, + ) -> Result; + + /// Prepare to unlock an asset. On success, a `Self::UnlockTicket` it returned, which can be + /// used to actually enact the lock. + /// + /// WARNING: Don't call this with an undropped instance of `Self::LockTicket` or + /// `Self::UnlockTicket`. + fn prepare_unlock( + locker: MultiLocation, + asset: MultiAsset, + owner: MultiLocation, + ) -> Result; + + /// Handler for when a location reports to us that an asset has been locked for us to unlock + /// at a later stage. + /// + /// If there is no way to handle the lock report, then this should return an error so that the + /// sending chain can ensure the lock does not remain. + /// + /// We should only act upon this message if we believe that the `origin` is honest. + fn note_unlockable( + locker: MultiLocation, + asset: MultiAsset, + owner: MultiLocation, + ) -> Result<(), LockError>; + + /// Handler for when an owner wishes to unlock an asset on a remote chain. + /// + /// Returns a ticket which can be used to actually note the reduction in unlockable assets that + /// `owner` commands on `locker`. + /// + /// WARNING: Don't call this with an undropped instance of `Self::ReduceTicket`. + fn prepare_reduce_unlockable( + locker: MultiLocation, + asset: MultiAsset, + owner: MultiLocation, + ) -> Result; +} + +impl AssetLock for () { + type LockTicket = Infallible; + type UnlockTicket = Infallible; + type ReduceTicket = Infallible; + fn prepare_lock( + _: MultiLocation, + _: MultiAsset, + _: MultiLocation, + ) -> Result { + Err(LockError::NotApplicable) + } + fn prepare_unlock( + _: MultiLocation, + _: MultiAsset, + _: MultiLocation, + ) -> Result { + Err(LockError::NotApplicable) + } + fn note_unlockable(_: MultiLocation, _: MultiAsset, _: MultiLocation) -> Result<(), LockError> { + Err(LockError::NotApplicable) + } + fn prepare_reduce_unlockable( + _: MultiLocation, + _: MultiAsset, + _: MultiLocation, + ) -> Result { + Err(LockError::NotApplicable) + } +} diff --git a/polkadot/xcm/xcm-executor/src/traits/conversion.rs b/polkadot/xcm/xcm-executor/src/traits/conversion.rs new file mode 100644 index 0000000000000000000000000000000000000000..dac099ffaf8e400a7d75cbd9009482ab375ea5db --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/conversion.rs @@ -0,0 +1,152 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use frame_support::traits::{Contains, OriginTrait}; +use sp_runtime::{traits::Dispatchable, DispatchErrorWithPostInfo}; +use sp_std::{marker::PhantomData, result::Result}; +use xcm::latest::prelude::*; + +/// Means of converting a location into an account identifier. +pub trait ConvertLocation { + /// Convert the `location` into `Some` account ID, or `None` if not possible. + fn convert_location(location: &MultiLocation) -> Option; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl ConvertLocation for Tuple { + fn convert_location(l: &MultiLocation) -> Option { + for_tuples!( #( + match Tuple::convert_location(l) { + Some(result) => return Some(result), + None => {}, + } + )* ); + None + } +} + +/// A converter `trait` for origin types. +/// +/// Can be amalgamated into tuples. If any of the tuple elements returns `Ok(_)`, it short circuits. +/// Else, the `Err(_)` of the last tuple item is returned. Each intermediate `Err(_)` might return a +/// different `origin` of type `Origin` which is passed to the next convert item. +/// +/// ```rust +/// # use xcm::latest::{MultiLocation, Junctions, Junction, OriginKind}; +/// # use xcm_executor::traits::ConvertOrigin; +/// // A convertor that will bump the para id and pass it to the next one. +/// struct BumpParaId; +/// impl ConvertOrigin for BumpParaId { +/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { +/// match origin.into() { +/// MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(id)) } => { +/// Err(Junctions::X1(Junction::Parachain(id + 1)).into()) +/// } +/// _ => unreachable!() +/// } +/// } +/// } +/// +/// struct AcceptPara7; +/// impl ConvertOrigin for AcceptPara7 { +/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { +/// match origin.into() { +/// MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(id)) } if id == 7 => { +/// Ok(7) +/// } +/// o => Err(o) +/// } +/// } +/// } +/// # fn main() { +/// let origin: MultiLocation = Junctions::X1(Junction::Parachain(6)).into(); +/// assert!( +/// <(BumpParaId, AcceptPara7) as ConvertOrigin>::convert_origin(origin, OriginKind::Native) +/// .is_ok() +/// ); +/// # } +/// ``` +pub trait ConvertOrigin { + /// Attempt to convert `origin` to the generic `Origin` whilst consuming it. + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl ConvertOrigin for Tuple { + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + for_tuples!( #( + let origin = match Tuple::convert_origin(origin, kind) { + Err(o) => o, + r => return r + }; + )* ); + let origin = origin.into(); + log::trace!( + target: "xcm::convert_origin", + "could not convert: origin: {:?}, kind: {:?}", + origin, + kind, + ); + Err(origin) + } +} + +/// Defines how a call is dispatched with given origin. +/// Allows to customize call dispatch, such as adapting the origin based on the call +/// or modifying the call. +pub trait CallDispatcher { + fn dispatch( + call: Call, + origin: Call::RuntimeOrigin, + ) -> Result>; +} + +pub struct WithOriginFilter(PhantomData); +impl CallDispatcher for WithOriginFilter +where + Call: Dispatchable, + Call::RuntimeOrigin: OriginTrait, + <::RuntimeOrigin as OriginTrait>::Call: 'static, + Filter: Contains<<::RuntimeOrigin as OriginTrait>::Call> + 'static, +{ + fn dispatch( + call: Call, + mut origin: ::RuntimeOrigin, + ) -> Result< + ::PostInfo, + DispatchErrorWithPostInfo<::PostInfo>, + > { + origin.add_filter(Filter::contains); + call.dispatch(origin) + } +} + +// We implement it for every calls so they can dispatch themselves +// (without any change). +impl CallDispatcher for Call { + fn dispatch( + call: Call, + origin: Call::RuntimeOrigin, + ) -> Result> { + call.dispatch(origin) + } +} diff --git a/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs b/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs new file mode 100644 index 0000000000000000000000000000000000000000..9753f3a4213fd98b903bd9dbc3496f32445a714b --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs @@ -0,0 +1,89 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::Assets; +use core::marker::PhantomData; +use frame_support::traits::Contains; +use xcm::latest::{MultiAssets, MultiLocation, Weight, XcmContext}; + +/// Define a handler for when some non-empty `Assets` value should be dropped. +pub trait DropAssets { + /// Handler for receiving dropped assets. Returns the weight consumed by this operation. + fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight; +} +impl DropAssets for () { + fn drop_assets(_origin: &MultiLocation, _assets: Assets, _context: &XcmContext) -> Weight { + Weight::zero() + } +} + +/// Morph a given `DropAssets` implementation into one which can filter based on assets. This can +/// be used to ensure that `Assets` values which hold no value are ignored. +pub struct FilterAssets(PhantomData<(D, A)>); + +impl> DropAssets for FilterAssets { + fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight { + if A::contains(&assets) { + D::drop_assets(origin, assets, context) + } else { + Weight::zero() + } + } +} + +/// Morph a given `DropAssets` implementation into one which can filter based on origin. This can +/// be used to ban origins which don't have proper protections/policies against misuse of the +/// asset trap facility don't get to use it. +pub struct FilterOrigin(PhantomData<(D, O)>); + +impl> DropAssets for FilterOrigin { + fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight { + if O::contains(origin) { + D::drop_assets(origin, assets, context) + } else { + Weight::zero() + } + } +} + +/// Define any handlers for the `AssetClaim` instruction. +pub trait ClaimAssets { + /// Claim any assets available to `origin` and return them in a single `Assets` value, together + /// with the weight used by this operation. + fn claim_assets( + origin: &MultiLocation, + ticket: &MultiLocation, + what: &MultiAssets, + context: &XcmContext, + ) -> bool; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl ClaimAssets for Tuple { + fn claim_assets( + origin: &MultiLocation, + ticket: &MultiLocation, + what: &MultiAssets, + context: &XcmContext, + ) -> bool { + for_tuples!( #( + if Tuple::claim_assets(origin, ticket, what, context) { + return true; + } + )* ); + false + } +} diff --git a/polkadot/xcm/xcm-executor/src/traits/export.rs b/polkadot/xcm/xcm-executor/src/traits/export.rs new file mode 100644 index 0000000000000000000000000000000000000000..7aeccd44566a67732617e70276751210c7da1ce4 --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/export.rs @@ -0,0 +1,146 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use xcm::latest::prelude::*; + +/// Utility for delivering a message to a system under a different (non-local) consensus with a +/// spoofed origin. This essentially defines the behaviour of the `ExportMessage` XCM instruction. +/// +/// This is quite different to `SendXcm`; `SendXcm` assumes that the local side's location will be +/// preserved to be represented as the value of the Origin register in the messages execution. +/// +/// This trait on the other hand assumes that we do not necessarily want the Origin register to +/// contain the local (i.e. the caller chain's) location, since it will generally be exporting a +/// message on behalf of another consensus system. Therefore in addition to the message, the +/// destination must be given in two parts: the network and the interior location within it. +/// +/// We also require the caller to state exactly what location they purport to be representing. The +/// destination must accept the local location to represent that location or the operation will +/// fail. +pub trait ExportXcm { + /// Intermediate value which connects the two phases of the export operation. + type Ticket; + + /// Check whether the given `message` is deliverable to the given `destination` on `network`, + /// spoofing its source as `universal_source` and if so determine the cost which will be paid by + /// this chain to do so, returning a `Ticket` token which can be used to enact delivery. + /// + /// The `channel` to be used on the `network`'s export mechanism (bridge, probably) must also + /// be provided. + /// + /// The `destination` and `message` must be `Some` (or else an error will be returned) and they + /// may only be consumed if the `Err` is not `NotApplicable`. + /// + /// If it is not a destination which can be reached with this type but possibly could by others, + /// then this *MUST* return `NotApplicable`. Any other error will cause the tuple + /// implementation (used to compose routing systems from different delivery agents) to exit + /// early without trying alternative means of delivery. + fn validate( + network: NetworkId, + channel: u32, + universal_source: &mut Option, + destination: &mut Option, + message: &mut Option>, + ) -> SendResult; + + /// Actually carry out the delivery operation for a previously validated message sending. + /// + /// The implementation should do everything possible to ensure that this function is infallible + /// if called immediately after `validate`. Returning an error here would result in a price + /// paid without the service being delivered. + fn deliver(ticket: Self::Ticket) -> Result; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl ExportXcm for Tuple { + for_tuples! { type Ticket = (#( Option ),* ); } + + fn validate( + network: NetworkId, + channel: u32, + universal_source: &mut Option, + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { + let mut maybe_cost: Option = None; + let one_ticket: Self::Ticket = (for_tuples! { #( + if maybe_cost.is_some() { + None + } else { + match Tuple::validate(network, channel, universal_source, destination, message) { + Err(SendError::NotApplicable) => None, + Err(e) => { return Err(e) }, + Ok((v, c)) => { + maybe_cost = Some(c); + Some(v) + }, + } + } + ),* }); + if let Some(cost) = maybe_cost { + Ok((one_ticket, cost)) + } else { + Err(SendError::NotApplicable) + } + } + + fn deliver(mut one_ticket: Self::Ticket) -> Result { + for_tuples!( #( + if let Some(validated) = one_ticket.Tuple.take() { + return Tuple::deliver(validated); + } + )* ); + Err(SendError::Unroutable) + } +} + +/// Convenience function for using a `SendXcm` implementation. Just interprets the `dest` and wraps +/// both in `Some` before passing them as as mutable references into `T::send_xcm`. +pub fn validate_export( + network: NetworkId, + channel: u32, + universal_source: InteriorMultiLocation, + dest: InteriorMultiLocation, + msg: Xcm<()>, +) -> SendResult { + T::validate(network, channel, &mut Some(universal_source), &mut Some(dest), &mut Some(msg)) +} + +/// Convenience function for using a `SendXcm` implementation. Just interprets the `dest` and wraps +/// both in `Some` before passing them as as mutable references into `T::send_xcm`. +/// +/// Returns either `Ok` with the price of the delivery, or `Err` with the reason why the message +/// could not be sent. +/// +/// Generally you'll want to validate and get the price first to ensure that the sender can pay it +/// before actually doing the delivery. +pub fn export_xcm( + network: NetworkId, + channel: u32, + universal_source: InteriorMultiLocation, + dest: InteriorMultiLocation, + msg: Xcm<()>, +) -> Result<(XcmHash, MultiAssets), SendError> { + let (ticket, price) = T::validate( + network, + channel, + &mut Some(universal_source), + &mut Some(dest), + &mut Some(msg), + )?; + let hash = T::deliver(ticket)?; + Ok((hash, price)) +} diff --git a/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs b/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs new file mode 100644 index 0000000000000000000000000000000000000000..ad2e108e7dee7fc29fe95765390936aab6d603fc --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs @@ -0,0 +1,59 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use xcm::prelude::*; + +/// Handle stuff to do with taking fees in certain XCM instructions. +pub trait FeeManager { + /// Determine if a fee which would normally payable should be waived. + fn is_waived(origin: Option<&MultiLocation>, r: FeeReason) -> bool; + + /// Do something with the fee which has been paid. Doing nothing here silently burns the + /// fees. + fn handle_fee(fee: MultiAssets); +} + +/// Context under which a fee is paid. +#[derive(Copy, Clone, Eq, PartialEq)] +pub enum FeeReason { + /// When a reporting instruction is called. + Report, + /// When the `TransferReserveAsset` instruction is called. + TransferReserveAsset, + /// When the `DepositReserveAsset` instruction is called. + DepositReserveAsset, + /// When the `InitiateReserveWithdraw` instruction is called. + InitiateReserveWithdraw, + /// When the `InitiateTeleport` instruction is called. + InitiateTeleport, + /// When the `QueryPallet` instruction is called. + QueryPallet, + /// When the `ExportMessage` instruction is called (and includes the network ID). + Export(NetworkId), + /// The `charge_fees` API. + ChargeFees, + /// When the `LockAsset` instruction is called. + LockAsset, + /// When the `RequestUnlock` instruction is called. + RequestUnlock, +} + +impl FeeManager for () { + fn is_waived(_: Option<&MultiLocation>, _: FeeReason) -> bool { + true + } + fn handle_fee(_: MultiAssets) {} +} diff --git a/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs b/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs new file mode 100644 index 0000000000000000000000000000000000000000..b162a8b0729ded0d8b75b663fcf03edd6f229429 --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs @@ -0,0 +1,35 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use frame_support::traits::ContainsPair; +use xcm::latest::{MultiAsset, MultiLocation}; + +/// Filters assets/location pairs. +/// +/// Can be amalgamated into tuples. If any item returns `true`, it short-circuits, else `false` is +/// returned. +#[deprecated = "Use `frame_support::traits::ContainsPair` instead"] +pub trait FilterAssetLocation { + /// A filter to distinguish between asset/location pairs. + fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool; +} + +#[allow(deprecated)] +impl> FilterAssetLocation for T { + fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + T::contains(asset, origin) + } +} diff --git a/polkadot/xcm/xcm-executor/src/traits/mod.rs b/polkadot/xcm/xcm-executor/src/traits/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..a9439968fa6ca5b2d1bfae6097d985ae5a887f19 --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/mod.rs @@ -0,0 +1,58 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Various traits used in configuring the executor. + +mod conversion; +pub use conversion::{CallDispatcher, ConvertLocation, ConvertOrigin, WithOriginFilter}; +mod drop_assets; +pub use drop_assets::{ClaimAssets, DropAssets}; +mod asset_lock; +pub use asset_lock::{AssetLock, Enact, LockError}; +mod asset_exchange; +pub use asset_exchange::AssetExchange; +mod export; +pub use export::{export_xcm, validate_export, ExportXcm}; +mod fee_manager; +pub use fee_manager::{FeeManager, FeeReason}; +mod filter_asset_location; +#[allow(deprecated)] +pub use filter_asset_location::FilterAssetLocation; +mod token_matching; +pub use token_matching::{ + Error, MatchesFungible, MatchesFungibles, MatchesNonFungible, MatchesNonFungibles, +}; +mod on_response; +pub use on_response::{OnResponse, QueryHandler, QueryResponseStatus, VersionChangeNotifier}; +mod should_execute; +pub use should_execute::{CheckSuspension, Properties, ShouldExecute}; +mod transact_asset; +pub use transact_asset::TransactAsset; +mod weight; +#[deprecated = "Use `sp_runtime::traits::` instead"] +pub use sp_runtime::traits::{Identity, TryConvertInto as JustTry}; +pub use weight::{WeightBounds, WeightTrader}; + +pub mod prelude { + pub use super::{ + export_xcm, validate_export, AssetExchange, AssetLock, ClaimAssets, ConvertOrigin, + DropAssets, Enact, Error, ExportXcm, FeeManager, FeeReason, LockError, MatchesFungible, + MatchesFungibles, MatchesNonFungible, MatchesNonFungibles, OnResponse, ShouldExecute, + TransactAsset, VersionChangeNotifier, WeightBounds, WeightTrader, WithOriginFilter, + }; + #[allow(deprecated)] + pub use super::{Identity, JustTry}; +} diff --git a/polkadot/xcm/xcm-executor/src/traits/on_response.rs b/polkadot/xcm/xcm-executor/src/traits/on_response.rs new file mode 100644 index 0000000000000000000000000000000000000000..b0f8b35bb98f430c8c89d54c8be05f92ab2b9559 --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/on_response.rs @@ -0,0 +1,169 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::Xcm; +use core::result; +use frame_support::{ + dispatch::fmt::Debug, + pallet_prelude::{Get, TypeInfo}, +}; +use parity_scale_codec::{FullCodec, MaxEncodedLen}; +use sp_arithmetic::traits::Zero; +use xcm::latest::{ + Error as XcmError, InteriorMultiLocation, MultiLocation, QueryId, Response, + Result as XcmResult, Weight, XcmContext, +}; + +/// Define what needs to be done upon receiving a query response. +pub trait OnResponse { + /// Returns `true` if we are expecting a response from `origin` for query `query_id` that was + /// queried by `querier`. + fn expecting_response( + origin: &MultiLocation, + query_id: u64, + querier: Option<&MultiLocation>, + ) -> bool; + /// Handler for receiving a `response` from `origin` relating to `query_id` initiated by + /// `querier`. + fn on_response( + origin: &MultiLocation, + query_id: u64, + querier: Option<&MultiLocation>, + response: Response, + max_weight: Weight, + context: &XcmContext, + ) -> Weight; +} +impl OnResponse for () { + fn expecting_response( + _origin: &MultiLocation, + _query_id: u64, + _querier: Option<&MultiLocation>, + ) -> bool { + false + } + fn on_response( + _origin: &MultiLocation, + _query_id: u64, + _querier: Option<&MultiLocation>, + _response: Response, + _max_weight: Weight, + _context: &XcmContext, + ) -> Weight { + Weight::zero() + } +} + +/// Trait for a type which handles notifying a destination of XCM version changes. +pub trait VersionChangeNotifier { + /// Start notifying `location` should the XCM version of this chain change. + /// + /// When it does, this type should ensure a `QueryResponse` message is sent with the given + /// `query_id` & `max_weight` and with a `response` of `Response::Version`. This should happen + /// until/unless `stop` is called with the correct `query_id`. + /// + /// If the `location` has an ongoing notification and when this function is called, then an + /// error should be returned. + fn start( + location: &MultiLocation, + query_id: QueryId, + max_weight: Weight, + context: &XcmContext, + ) -> XcmResult; + + /// Stop notifying `location` should the XCM change. Returns an error if there is no existing + /// notification set up. + fn stop(location: &MultiLocation, context: &XcmContext) -> XcmResult; + + /// Return true if a location is subscribed to XCM version changes. + fn is_subscribed(location: &MultiLocation) -> bool; +} + +impl VersionChangeNotifier for () { + fn start(_: &MultiLocation, _: QueryId, _: Weight, _: &XcmContext) -> XcmResult { + Err(XcmError::Unimplemented) + } + fn stop(_: &MultiLocation, _: &XcmContext) -> XcmResult { + Err(XcmError::Unimplemented) + } + fn is_subscribed(_: &MultiLocation) -> bool { + false + } +} + +/// The possible state of an XCM query response. +#[derive(Debug, PartialEq, Eq)] +pub enum QueryResponseStatus { + /// The response has arrived, and includes the inner Response and the block number it arrived + /// at. + Ready { response: Response, at: BlockNumber }, + /// The response has not yet arrived, the XCM might still be executing or the response might be + /// in transit. + Pending { timeout: BlockNumber }, + /// No response with the given `QueryId` was found, or the response was already queried and + /// removed from local storage. + NotFound, + /// Got an unexpected XCM version. + UnexpectedVersion, +} + +/// Provides methods to expect responses from XCMs and query their status. +pub trait QueryHandler { + type QueryId: From + + FullCodec + + MaxEncodedLen + + TypeInfo + + Clone + + Eq + + PartialEq + + Debug + + Copy; + type BlockNumber: Zero; + type Error; + type UniversalLocation: Get; + + /// Attempt to create a new query ID and register it as a query that is yet to respond. + fn new_query( + responder: impl Into, + timeout: Self::BlockNumber, + match_querier: impl Into, + ) -> QueryId; + + /// Consume `message` and return another which is equivalent to it except that it reports + /// back the outcome. + /// + /// - `message`: The message whose outcome should be reported. + /// - `responder`: The origin from which a response should be expected. + /// - `timeout`: The block number after which it is permissible to return `NotFound` from + /// `take_response`. + /// + /// `report_outcome` may return an error if the `responder` is not invertible. + /// + /// It is assumed that the querier of the response will be `Here`. + /// The response can be queried with `take_response`. + fn report_outcome( + message: &mut Xcm<()>, + responder: impl Into, + timeout: Self::BlockNumber, + ) -> result::Result; + + /// Attempt to remove and return the response of query with ID `query_id`. + fn take_response(id: Self::QueryId) -> QueryResponseStatus; + + /// Makes sure to expect a response with the given id. + #[cfg(feature = "runtime-benchmarks")] + fn expect_response(id: Self::QueryId, response: Response); +} diff --git a/polkadot/xcm/xcm-executor/src/traits/should_execute.rs b/polkadot/xcm/xcm-executor/src/traits/should_execute.rs new file mode 100644 index 0000000000000000000000000000000000000000..d85458b54709d0a9c80dcf661723a198fac85c88 --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/should_execute.rs @@ -0,0 +1,113 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use frame_support::traits::ProcessMessageError; +use sp_std::result::Result; +use xcm::latest::{Instruction, MultiLocation, Weight, XcmHash}; + +/// Properyies of an XCM message and its imminent execution. +#[derive(Clone, Eq, PartialEq, Debug)] +pub struct Properties { + /// The amount of weight that the system has determined this + /// message may utilize in its execution. Typically non-zero only because of prior fee + /// payment, but could in principle be due to other factors. + pub weight_credit: Weight, + /// The identity of the message, if one is known. If left as `None`, then it will generally + /// default to the hash of the message which may be non-unique. + pub message_id: Option, +} + +/// Trait to determine whether the execution engine should actually execute a given XCM. +/// +/// Can be amalgamated into a tuple to have multiple trials. If any of the tuple elements returns +/// `Ok()`, the execution stops. Else, `Err(_)` is returned if all elements reject the message. +pub trait ShouldExecute { + /// Returns `true` if the given `message` may be executed. + /// + /// - `origin`: The origin (sender) of the message. + /// - `instructions`: The message itself. + /// - `max_weight`: The (possibly over-) estimation of the weight of execution of the message. + /// - `properties`: Various pre-established properties of the message which may be mutated by + /// this API. + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + max_weight: Weight, + properties: &mut Properties, + ) -> Result<(), ProcessMessageError>; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl ShouldExecute for Tuple { + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + max_weight: Weight, + properties: &mut Properties, + ) -> Result<(), ProcessMessageError> { + for_tuples!( #( + match Tuple::should_execute(origin, instructions, max_weight, properties) { + Ok(()) => return Ok(()), + _ => (), + } + )* ); + log::trace!( + target: "xcm::should_execute", + "did not pass barrier: origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", + origin, + instructions, + max_weight, + properties, + ); + Err(ProcessMessageError::Unsupported) + } +} + +/// Trait to determine whether the execution engine is suspended from executing a given XCM. +/// +/// The trait method is given the same parameters as `ShouldExecute::should_execute`, so that the +/// implementer will have all the context necessary to determine whether or not to suspend the +/// XCM executor. +/// +/// Can be chained together in tuples to have multiple rounds of checks. If all of the tuple +/// elements returns false, then execution is not suspended. Otherwise, execution is suspended +/// if any of the tuple elements returns true. +pub trait CheckSuspension { + fn is_suspended( + origin: &MultiLocation, + instructions: &mut [Instruction], + max_weight: Weight, + properties: &mut Properties, + ) -> bool; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl CheckSuspension for Tuple { + fn is_suspended( + origin: &MultiLocation, + instruction: &mut [Instruction], + max_weight: Weight, + properties: &mut Properties, + ) -> bool { + for_tuples!( #( + if Tuple::is_suspended(origin, instruction, max_weight, properties) { + return true + } + )* ); + + false + } +} diff --git a/polkadot/xcm/xcm-executor/src/traits/token_matching.rs b/polkadot/xcm/xcm-executor/src/traits/token_matching.rs new file mode 100644 index 0000000000000000000000000000000000000000..ad65a8630217248c97a1fdaef94cde48aef1b42f --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/token_matching.rs @@ -0,0 +1,107 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use sp_std::result; +use xcm::latest::prelude::*; + +pub trait MatchesFungible { + fn matches_fungible(a: &MultiAsset) -> Option; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl MatchesFungible for Tuple { + fn matches_fungible(a: &MultiAsset) -> Option { + for_tuples!( #( + match Tuple::matches_fungible(a) { o @ Some(_) => return o, _ => () } + )* ); + log::trace!(target: "xcm::matches_fungible", "did not match fungible asset: {:?}", &a); + None + } +} + +pub trait MatchesNonFungible { + fn matches_nonfungible(a: &MultiAsset) -> Option; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl MatchesNonFungible for Tuple { + fn matches_nonfungible(a: &MultiAsset) -> Option { + for_tuples!( #( + match Tuple::matches_nonfungible(a) { o @ Some(_) => return o, _ => () } + )* ); + log::trace!(target: "xcm::matches_non_fungible", "did not match non-fungible asset: {:?}", &a); + None + } +} + +/// Errors associated with [`MatchesFungibles`] operation. +#[derive(Debug, PartialEq, Eq)] +pub enum Error { + /// The given asset is not handled. (According to [`XcmError::AssetNotFound`]) + AssetNotHandled, + /// `MultiLocation` to `AccountId` conversion failed. + AccountIdConversionFailed, + /// `u128` amount to currency `Balance` conversion failed. + AmountToBalanceConversionFailed, + /// `MultiLocation` to `AssetId`/`ClassId` conversion failed. + AssetIdConversionFailed, + /// `AssetInstance` to non-fungibles instance ID conversion failed. + InstanceConversionFailed, +} + +impl From for XcmError { + fn from(e: Error) -> Self { + use XcmError::FailedToTransactAsset; + match e { + Error::AssetNotHandled => XcmError::AssetNotFound, + Error::AccountIdConversionFailed => FailedToTransactAsset("AccountIdConversionFailed"), + Error::AmountToBalanceConversionFailed => + FailedToTransactAsset("AmountToBalanceConversionFailed"), + Error::AssetIdConversionFailed => FailedToTransactAsset("AssetIdConversionFailed"), + Error::InstanceConversionFailed => FailedToTransactAsset("InstanceConversionFailed"), + } + } +} + +pub trait MatchesFungibles { + fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error>; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl MatchesFungibles for Tuple { + fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error> { + for_tuples!( #( + match Tuple::matches_fungibles(a) { o @ Ok(_) => return o, _ => () } + )* ); + log::trace!(target: "xcm::matches_fungibles", "did not match fungibles asset: {:?}", &a); + Err(Error::AssetNotHandled) + } +} + +pub trait MatchesNonFungibles { + fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(AssetId, Instance), Error>; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl MatchesNonFungibles for Tuple { + fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(AssetId, Instance), Error> { + for_tuples!( #( + match Tuple::matches_nonfungibles(a) { o @ Ok(_) => return o, _ => () } + )* ); + log::trace!(target: "xcm::matches_non_fungibles", "did not match fungibles asset: {:?}", &a); + Err(Error::AssetNotHandled) + } +} diff --git a/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs b/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs new file mode 100644 index 0000000000000000000000000000000000000000..34cdb0c7141356edd4113d576f45069a569eabe9 --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs @@ -0,0 +1,456 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::Assets; +use sp_std::result::Result; +use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result as XcmResult, XcmContext}; + +/// Facility for asset transacting. +/// +/// This should work with as many asset/location combinations as possible. Locations to support may +/// include non-account locations such as a `MultiLocation::X1(Junction::Parachain)`. Different +/// chains may handle them in different ways. +/// +/// Can be amalgamated as a tuple of items that implement this trait. In such executions, if any of +/// the transactors returns `Ok(())`, then it will short circuit. Else, execution is passed to the +/// next transactor. +pub trait TransactAsset { + /// Ensure that `check_in` will do as expected. + /// + /// When composed as a tuple, all type-items are called and at least one must result in `Ok`. + fn can_check_in( + _origin: &MultiLocation, + _what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + Err(XcmError::Unimplemented) + } + + /// An asset has been teleported in from the given origin. This should do whatever housekeeping + /// is needed. + /// + /// NOTE: This will make only a best-effort at bookkeeping. The caller should ensure that + /// `can_check_in` has returned with `Ok` in order to guarantee that this operation proceeds + /// properly. + /// + /// Implementation note: In general this will do one of two things: On chains where the asset is + /// native, it will reduce the assets from a special "teleported" account so that a) + /// total-issuance is preserved; and b) to ensure that no more assets can be teleported in than + /// were teleported out overall (this should not be needed if the teleporting chains are to be + /// trusted, but better to be safe than sorry). On chains where the asset is not native then it + /// will generally just be a no-op. + /// + /// When composed as a tuple, all type-items are called. It is up to the implementer that there + /// exists no value for `_what` which can cause side-effects for more than one of the + /// type-items. + fn check_in(_origin: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {} + + /// Ensure that `check_out` will do as expected. + /// + /// When composed as a tuple, all type-items are called and at least one must result in `Ok`. + fn can_check_out( + _dest: &MultiLocation, + _what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + Err(XcmError::Unimplemented) + } + + /// An asset has been teleported out to the given destination. This should do whatever + /// housekeeping is needed. + /// + /// Implementation note: In general this will do one of two things: On chains where the asset is + /// native, it will increase the assets in a special "teleported" account so that a) + /// total-issuance is preserved; and b) to ensure that no more assets can be teleported in than + /// were teleported out overall (this should not be needed if the teleporting chains are to be + /// trusted, but better to be safe than sorry). On chains where the asset is not native then it + /// will generally just be a no-op. + /// + /// When composed as a tuple, all type-items are called. It is up to the implementer that there + /// exists no value for `_what` which can cause side-effects for more than one of the + /// type-items. + fn check_out(_dest: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {} + + /// Deposit the `what` asset into the account of `who`. + /// + /// Implementations should return `XcmError::FailedToTransactAsset` if deposit failed. + fn deposit_asset(_what: &MultiAsset, _who: &MultiLocation, _context: &XcmContext) -> XcmResult { + Err(XcmError::Unimplemented) + } + + /// Withdraw the given asset from the consensus system. Return the actual asset(s) withdrawn, + /// which should always be equal to `_what`. + /// + /// The XCM `_maybe_context` parameter may be `None` when the caller of `withdraw_asset` is + /// outside of the context of a currently-executing XCM. An example will be the `charge_fees` + /// method in the XCM executor. + /// + /// Implementations should return `XcmError::FailedToTransactAsset` if withdraw failed. + fn withdraw_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _maybe_context: Option<&XcmContext>, + ) -> Result { + Err(XcmError::Unimplemented) + } + + /// Move an `asset` `from` one location in `to` another location. + /// + /// Returns `XcmError::FailedToTransactAsset` if transfer failed. + /// + /// ## Notes + /// This function is meant to only be implemented by the type implementing `TransactAsset`, and + /// not be called directly. Most common API usages will instead call `transfer_asset`, which in + /// turn has a default implementation that calls `internal_transfer_asset`. As such, **please + /// do not call this method directly unless you know what you're doing**. + fn internal_transfer_asset( + _asset: &MultiAsset, + _from: &MultiLocation, + _to: &MultiLocation, + _context: &XcmContext, + ) -> Result { + Err(XcmError::Unimplemented) + } + + /// Move an `asset` `from` one location in `to` another location. + /// + /// Attempts to use `internal_transfer_asset` and if not available then falls back to using a + /// two-part withdraw/deposit. + fn transfer_asset( + asset: &MultiAsset, + from: &MultiLocation, + to: &MultiLocation, + context: &XcmContext, + ) -> Result { + match Self::internal_transfer_asset(asset, from, to, context) { + Err(XcmError::AssetNotFound | XcmError::Unimplemented) => { + let assets = Self::withdraw_asset(asset, from, Some(context))?; + // Not a very forgiving attitude; once we implement roll-backs then it'll be nicer. + Self::deposit_asset(asset, to, context)?; + Ok(assets) + }, + result => result, + } + } +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl TransactAsset for Tuple { + fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + for_tuples!( #( + match Tuple::can_check_in(origin, what, context) { + Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), + r => return r, + } + )* ); + log::trace!( + target: "xcm::TransactAsset::can_check_in", + "asset not found: what: {:?}, origin: {:?}, context: {:?}", + what, + origin, + context, + ); + Err(XcmError::AssetNotFound) + } + + fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + for_tuples!( #( + Tuple::check_in(origin, what, context); + )* ); + } + + fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + for_tuples!( #( + match Tuple::can_check_out(dest, what, context) { + Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), + r => return r, + } + )* ); + log::trace!( + target: "xcm::TransactAsset::can_check_out", + "asset not found: what: {:?}, dest: {:?}, context: {:?}", + what, + dest, + context, + ); + Err(XcmError::AssetNotFound) + } + + fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + for_tuples!( #( + Tuple::check_out(dest, what, context); + )* ); + } + + fn deposit_asset(what: &MultiAsset, who: &MultiLocation, context: &XcmContext) -> XcmResult { + for_tuples!( #( + match Tuple::deposit_asset(what, who, context) { + Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), + r => return r, + } + )* ); + log::trace!( + target: "xcm::TransactAsset::deposit_asset", + "did not deposit asset: what: {:?}, who: {:?}, context: {:?}", + what, + who, + context, + ); + Err(XcmError::AssetNotFound) + } + + fn withdraw_asset( + what: &MultiAsset, + who: &MultiLocation, + maybe_context: Option<&XcmContext>, + ) -> Result { + for_tuples!( #( + match Tuple::withdraw_asset(what, who, maybe_context) { + Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), + r => return r, + } + )* ); + log::trace!( + target: "xcm::TransactAsset::withdraw_asset", + "did not withdraw asset: what: {:?}, who: {:?}, maybe_context: {:?}", + what, + who, + maybe_context, + ); + Err(XcmError::AssetNotFound) + } + + fn internal_transfer_asset( + what: &MultiAsset, + from: &MultiLocation, + to: &MultiLocation, + context: &XcmContext, + ) -> Result { + for_tuples!( #( + match Tuple::internal_transfer_asset(what, from, to, context) { + Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), + r => return r, + } + )* ); + log::trace!( + target: "xcm::TransactAsset::internal_transfer_asset", + "did not transfer asset: what: {:?}, from: {:?}, to: {:?}, context: {:?}", + what, + from, + to, + context, + ); + Err(XcmError::AssetNotFound) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use xcm::latest::Junctions::Here; + + pub struct UnimplementedTransactor; + impl TransactAsset for UnimplementedTransactor {} + + pub struct NotFoundTransactor; + impl TransactAsset for NotFoundTransactor { + fn can_check_in( + _origin: &MultiLocation, + _what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + Err(XcmError::AssetNotFound) + } + + fn can_check_out( + _dest: &MultiLocation, + _what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + Err(XcmError::AssetNotFound) + } + + fn deposit_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _context: &XcmContext, + ) -> XcmResult { + Err(XcmError::AssetNotFound) + } + + fn withdraw_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _context: Option<&XcmContext>, + ) -> Result { + Err(XcmError::AssetNotFound) + } + + fn internal_transfer_asset( + _what: &MultiAsset, + _from: &MultiLocation, + _to: &MultiLocation, + _context: &XcmContext, + ) -> Result { + Err(XcmError::AssetNotFound) + } + } + + pub struct OverflowTransactor; + impl TransactAsset for OverflowTransactor { + fn can_check_in( + _origin: &MultiLocation, + _what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + Err(XcmError::Overflow) + } + + fn can_check_out( + _dest: &MultiLocation, + _what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + Err(XcmError::Overflow) + } + + fn deposit_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _context: &XcmContext, + ) -> XcmResult { + Err(XcmError::Overflow) + } + + fn withdraw_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _context: Option<&XcmContext>, + ) -> Result { + Err(XcmError::Overflow) + } + + fn internal_transfer_asset( + _what: &MultiAsset, + _from: &MultiLocation, + _to: &MultiLocation, + _context: &XcmContext, + ) -> Result { + Err(XcmError::Overflow) + } + } + + pub struct SuccessfulTransactor; + impl TransactAsset for SuccessfulTransactor { + fn can_check_in( + _origin: &MultiLocation, + _what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + Ok(()) + } + + fn can_check_out( + _dest: &MultiLocation, + _what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + Ok(()) + } + + fn deposit_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _context: &XcmContext, + ) -> XcmResult { + Ok(()) + } + + fn withdraw_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _context: Option<&XcmContext>, + ) -> Result { + Ok(Assets::default()) + } + + fn internal_transfer_asset( + _what: &MultiAsset, + _from: &MultiLocation, + _to: &MultiLocation, + _context: &XcmContext, + ) -> Result { + Ok(Assets::default()) + } + } + + #[test] + fn defaults_to_asset_not_found() { + type MultiTransactor = + (UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor); + + assert_eq!( + MultiTransactor::deposit_asset( + &(Here, 1u128).into(), + &Here.into(), + &XcmContext::with_message_id([0; 32]), + ), + Err(XcmError::AssetNotFound) + ); + } + + #[test] + fn unimplemented_and_not_found_continue_iteration() { + type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, SuccessfulTransactor); + + assert_eq!( + MultiTransactor::deposit_asset( + &(Here, 1u128).into(), + &Here.into(), + &XcmContext::with_message_id([0; 32]), + ), + Ok(()) + ); + } + + #[test] + fn unexpected_error_stops_iteration() { + type MultiTransactor = (OverflowTransactor, SuccessfulTransactor); + + assert_eq!( + MultiTransactor::deposit_asset( + &(Here, 1u128).into(), + &Here.into(), + &XcmContext::with_message_id([0; 32]), + ), + Err(XcmError::Overflow) + ); + } + + #[test] + fn success_stops_iteration() { + type MultiTransactor = (SuccessfulTransactor, OverflowTransactor); + + assert_eq!( + MultiTransactor::deposit_asset( + &(Here, 1u128).into(), + &Here.into(), + &XcmContext::with_message_id([0; 32]), + ), + Ok(()), + ); + } +} diff --git a/polkadot/xcm/xcm-executor/src/traits/weight.rs b/polkadot/xcm/xcm-executor/src/traits/weight.rs new file mode 100644 index 0000000000000000000000000000000000000000..bc40c10074f504fa9752d6a01fb5308c84948128 --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/traits/weight.rs @@ -0,0 +1,113 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +use crate::Assets; +use sp_std::result::Result; +use xcm::latest::{prelude::*, Weight}; + +/// Determine the weight of an XCM message. +pub trait WeightBounds { + /// Return the maximum amount of weight that an attempted execution of this message could + /// consume. + fn weight(message: &mut Xcm) -> Result; + + /// Return the maximum amount of weight that an attempted execution of this instruction could + /// consume. + fn instr_weight(instruction: &Instruction) -> Result; +} + +/// A means of getting approximate weight consumption for a given destination message executor and a +/// message. +pub trait UniversalWeigher { + /// Get the upper limit of weight required for `dest` to execute `message`. + fn weigh(dest: impl Into, message: Xcm<()>) -> Result; +} + +/// Charge for weight in order to execute XCM. +/// +/// A `WeightTrader` may also be put into a tuple, in which case the default behavior of +/// `buy_weight` and `refund_weight` would be to attempt to call each tuple element's own +/// implementation of these two functions, in the order of which they appear in the tuple, +/// returning early when a successful result is returned. +pub trait WeightTrader: Sized { + /// Create a new trader instance. + fn new() -> Self; + + /// Purchase execution weight credit in return for up to a given `payment`. If less of the + /// payment is required then the surplus is returned. If the `payment` cannot be used to pay + /// for the `weight`, then an error is returned. + fn buy_weight( + &mut self, + weight: Weight, + payment: Assets, + context: &XcmContext, + ) -> Result; + + /// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight + /// was purchased using `buy_weight`. + /// + /// Default implementation refunds nothing. + fn refund_weight(&mut self, _weight: Weight, _context: &XcmContext) -> Option { + None + } +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl WeightTrader for Tuple { + fn new() -> Self { + for_tuples!( ( #( Tuple::new() ),* ) ) + } + + fn buy_weight( + &mut self, + weight: Weight, + payment: Assets, + context: &XcmContext, + ) -> Result { + let mut too_expensive_error_found = false; + let mut last_error = None; + for_tuples!( #( + match Tuple.buy_weight(weight, payment.clone(), context) { + Ok(assets) => return Ok(assets), + Err(e) => { + if let XcmError::TooExpensive = e { + too_expensive_error_found = true; + } + last_error = Some(e) + } + } + )* ); + + log::trace!(target: "xcm::buy_weight", "last_error: {:?}, too_expensive_error_found: {}", last_error, too_expensive_error_found); + + // if we have multiple traders, and first one returns `TooExpensive` and others fail e.g. + // `AssetNotFound` then it is more accurate to return `TooExpensive` then `AssetNotFound` + Err(if too_expensive_error_found { + XcmError::TooExpensive + } else { + last_error.unwrap_or(XcmError::TooExpensive) + }) + } + + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + for_tuples!( #( + if let Some(asset) = Tuple.refund_weight(weight, context) { + return Some(asset); + } + )* ); + None + } +} diff --git a/polkadot/xcm/xcm-simulator/Cargo.toml b/polkadot/xcm/xcm-simulator/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..79ee27c6041ccddc4f93d0cc31c1fc9e825ca7a8 --- /dev/null +++ b/polkadot/xcm/xcm-simulator/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "xcm-simulator" +description = "Test kit to simulate cross-chain message passing and XCM execution" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.6.1" } +paste = "1.0.7" + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master" } + +xcm = { path = "../" } +xcm-executor = { path = "../xcm-executor" } +xcm-builder = { path = "../xcm-builder" } +polkadot-core-primitives = { path = "../../core-primitives"} +polkadot-parachain = { path = "../../parachain" } +polkadot-runtime-parachains = { path = "../../runtime/parachains" } diff --git a/polkadot/xcm/xcm-simulator/example/Cargo.toml b/polkadot/xcm/xcm-simulator/example/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7d47755dc488bf5e9ff2826128b319254f4555ac --- /dev/null +++ b/polkadot/xcm/xcm-simulator/example/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "xcm-simulator-example" +description = "Examples of xcm-simulator usage." +authors.workspace = true +edition.workspace = true +license.workspace = true +version.workspace = true + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.6.1" } +scale-info = { version = "2.5.0", features = ["derive"] } +log = { version = "0.4.14", default-features = false } + +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-message-queue = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-uniques = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } + +xcm = { path = "../../" } +xcm-simulator = { path = "../" } +xcm-executor = { path = "../../xcm-executor" } +xcm-builder = { path = "../../xcm-builder" } +pallet-xcm = { path = "../../pallet-xcm" } +polkadot-core-primitives = { path = "../../../core-primitives" } +polkadot-runtime-parachains = { path = "../../../runtime/parachains" } +polkadot-parachain = { path = "../../../parachain" } + +[features] +default = [] +runtime-benchmarks = [ + "frame-system/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "pallet-uniques/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", + "polkadot-runtime-parachains/runtime-benchmarks", + "polkadot-parachain/runtime-benchmarks", +] diff --git a/polkadot/xcm/xcm-simulator/example/src/lib.rs b/polkadot/xcm/xcm-simulator/example/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..85b8ad1c5cb7bceb03ac42320432900d19471e55 --- /dev/null +++ b/polkadot/xcm/xcm-simulator/example/src/lib.rs @@ -0,0 +1,652 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +mod parachain; +mod relay_chain; + +use sp_runtime::BuildStorage; +use sp_tracing; +use xcm::prelude::*; +use xcm_executor::traits::ConvertLocation; +use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt}; + +pub const ALICE: sp_runtime::AccountId32 = sp_runtime::AccountId32::new([0u8; 32]); +pub const INITIAL_BALANCE: u128 = 1_000_000_000; + +decl_test_parachain! { + pub struct ParaA { + Runtime = parachain::Runtime, + XcmpMessageHandler = parachain::MsgQueue, + DmpMessageHandler = parachain::MsgQueue, + new_ext = para_ext(1), + } +} + +decl_test_parachain! { + pub struct ParaB { + Runtime = parachain::Runtime, + XcmpMessageHandler = parachain::MsgQueue, + DmpMessageHandler = parachain::MsgQueue, + new_ext = para_ext(2), + } +} + +decl_test_relay_chain! { + pub struct Relay { + Runtime = relay_chain::Runtime, + RuntimeCall = relay_chain::RuntimeCall, + RuntimeEvent = relay_chain::RuntimeEvent, + XcmConfig = relay_chain::XcmConfig, + MessageQueue = relay_chain::MessageQueue, + System = relay_chain::System, + new_ext = relay_ext(), + } +} + +decl_test_network! { + pub struct MockNet { + relay_chain = Relay, + parachains = vec![ + (1, ParaA), + (2, ParaB), + ], + } +} + +pub fn parent_account_id() -> parachain::AccountId { + let location = (Parent,); + parachain::LocationToAccountId::convert_location(&location.into()).unwrap() +} + +pub fn child_account_id(para: u32) -> relay_chain::AccountId { + let location = (Parachain(para),); + relay_chain::LocationToAccountId::convert_location(&location.into()).unwrap() +} + +pub fn child_account_account_id(para: u32, who: sp_runtime::AccountId32) -> relay_chain::AccountId { + let location = (Parachain(para), AccountId32 { network: None, id: who.into() }); + relay_chain::LocationToAccountId::convert_location(&location.into()).unwrap() +} + +pub fn sibling_account_account_id(para: u32, who: sp_runtime::AccountId32) -> parachain::AccountId { + let location = (Parent, Parachain(para), AccountId32 { network: None, id: who.into() }); + parachain::LocationToAccountId::convert_location(&location.into()).unwrap() +} + +pub fn parent_account_account_id(who: sp_runtime::AccountId32) -> parachain::AccountId { + let location = (Parent, AccountId32 { network: None, id: who.into() }); + parachain::LocationToAccountId::convert_location(&location.into()).unwrap() +} + +pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { + use parachain::{MsgQueue, Runtime, System}; + + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, INITIAL_BALANCE), (parent_account_id(), INITIAL_BALANCE)], + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| { + sp_tracing::try_init_simple(); + System::set_block_number(1); + MsgQueue::set_para_id(para_id.into()); + }); + ext +} + +pub fn relay_ext() -> sp_io::TestExternalities { + use relay_chain::{Runtime, RuntimeOrigin, System, Uniques}; + + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![ + (ALICE, INITIAL_BALANCE), + (child_account_id(1), INITIAL_BALANCE), + (child_account_id(2), INITIAL_BALANCE), + ], + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| { + System::set_block_number(1); + assert_eq!(Uniques::force_create(RuntimeOrigin::root(), 1, ALICE, true), Ok(())); + assert_eq!(Uniques::mint(RuntimeOrigin::signed(ALICE), 1, 42, child_account_id(1)), Ok(())); + }); + ext +} + +pub type RelayChainPalletXcm = pallet_xcm::Pallet; +pub type ParachainPalletXcm = pallet_xcm::Pallet; + +#[cfg(test)] +mod tests { + use super::*; + + use codec::Encode; + use frame_support::{assert_ok, weights::Weight}; + use xcm::latest::QueryResponseInfo; + use xcm_simulator::TestExt; + + // Helper function for forming buy execution message + fn buy_execution(fees: impl Into) -> Instruction { + BuyExecution { fees: fees.into(), weight_limit: Unlimited } + } + + #[test] + fn remote_account_ids_work() { + child_account_account_id(1, ALICE); + sibling_account_account_id(1, ALICE); + parent_account_account_id(ALICE); + } + + #[test] + fn dmp() { + MockNet::reset(); + + let remark = parachain::RuntimeCall::System( + frame_system::Call::::remark_with_event { remark: vec![1, 2, 3] }, + ); + Relay::execute_with(|| { + assert_ok!(RelayChainPalletXcm::send_xcm( + Here, + Parachain(1), + Xcm(vec![Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: Weight::from_parts(INITIAL_BALANCE as u64, 1024 * 1024), + call: remark.encode().into(), + }]), + )); + }); + + ParaA::execute_with(|| { + use parachain::{RuntimeEvent, System}; + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::System(frame_system::Event::Remarked { .. }) + ))); + }); + } + + #[test] + fn ump() { + MockNet::reset(); + + let remark = relay_chain::RuntimeCall::System( + frame_system::Call::::remark_with_event { remark: vec![1, 2, 3] }, + ); + ParaA::execute_with(|| { + assert_ok!(ParachainPalletXcm::send_xcm( + Here, + Parent, + Xcm(vec![Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: Weight::from_parts(INITIAL_BALANCE as u64, 1024 * 1024), + call: remark.encode().into(), + }]), + )); + }); + + Relay::execute_with(|| { + use relay_chain::{RuntimeEvent, System}; + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::System(frame_system::Event::Remarked { .. }) + ))); + }); + } + + #[test] + fn xcmp() { + MockNet::reset(); + + let remark = parachain::RuntimeCall::System( + frame_system::Call::::remark_with_event { remark: vec![1, 2, 3] }, + ); + ParaA::execute_with(|| { + assert_ok!(ParachainPalletXcm::send_xcm( + Here, + (Parent, Parachain(2)), + Xcm(vec![Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: Weight::from_parts(INITIAL_BALANCE as u64, 1024 * 1024), + call: remark.encode().into(), + }]), + )); + }); + + ParaB::execute_with(|| { + use parachain::{RuntimeEvent, System}; + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::System(frame_system::Event::Remarked { .. }) + ))); + }); + } + + #[test] + fn reserve_transfer() { + MockNet::reset(); + + let withdraw_amount = 123; + + Relay::execute_with(|| { + assert_ok!(RelayChainPalletXcm::reserve_transfer_assets( + relay_chain::RuntimeOrigin::signed(ALICE), + Box::new(Parachain(1).into()), + Box::new(AccountId32 { network: None, id: ALICE.into() }.into()), + Box::new((Here, withdraw_amount).into()), + 0, + )); + assert_eq!( + relay_chain::Balances::free_balance(&child_account_id(1)), + INITIAL_BALANCE + withdraw_amount + ); + }); + + ParaA::execute_with(|| { + // free execution, full amount received + assert_eq!( + pallet_balances::Pallet::::free_balance(&ALICE), + INITIAL_BALANCE + withdraw_amount + ); + }); + } + + #[test] + fn remote_locking_and_unlocking() { + MockNet::reset(); + + let locked_amount = 100; + + ParaB::execute_with(|| { + let message = Xcm(vec![LockAsset { + asset: (Here, locked_amount).into(), + unlocker: Parachain(1).into(), + }]); + assert_ok!(ParachainPalletXcm::send_xcm(Here, Parent, message.clone())); + }); + + Relay::execute_with(|| { + use pallet_balances::{BalanceLock, Reasons}; + assert_eq!( + relay_chain::Balances::locks(&child_account_id(2)), + vec![BalanceLock { + id: *b"py/xcmlk", + amount: locked_amount, + reasons: Reasons::All + }] + ); + }); + + ParaA::execute_with(|| { + assert_eq!( + parachain::MsgQueue::received_dmp(), + vec![Xcm(vec![NoteUnlockable { + owner: (Parent, Parachain(2)).into(), + asset: (Parent, locked_amount).into() + }])] + ); + }); + + ParaB::execute_with(|| { + // Request unlocking part of the funds on the relay chain + let message = Xcm(vec![RequestUnlock { + asset: (Parent, locked_amount - 50).into(), + locker: Parent.into(), + }]); + assert_ok!(ParachainPalletXcm::send_xcm(Here, (Parent, Parachain(1)), message)); + }); + + Relay::execute_with(|| { + use pallet_balances::{BalanceLock, Reasons}; + // Lock is reduced + assert_eq!( + relay_chain::Balances::locks(&child_account_id(2)), + vec![BalanceLock { + id: *b"py/xcmlk", + amount: locked_amount - 50, + reasons: Reasons::All + }] + ); + }); + } + + /// Scenario: + /// A parachain transfers an NFT resident on the relay chain to another parachain account. + /// + /// Asserts that the parachain accounts are updated as expected. + #[test] + fn withdraw_and_deposit_nft() { + MockNet::reset(); + + Relay::execute_with(|| { + assert_eq!(relay_chain::Uniques::owner(1, 42), Some(child_account_id(1))); + }); + + ParaA::execute_with(|| { + let message = Xcm(vec![TransferAsset { + assets: (GeneralIndex(1), 42u32).into(), + beneficiary: Parachain(2).into(), + }]); + // Send withdraw and deposit + assert_ok!(ParachainPalletXcm::send_xcm(Here, Parent, message)); + }); + + Relay::execute_with(|| { + assert_eq!(relay_chain::Uniques::owner(1, 42), Some(child_account_id(2))); + }); + } + + /// Scenario: + /// The relay-chain teleports an NFT to a parachain. + /// + /// Asserts that the parachain accounts are updated as expected. + #[test] + fn teleport_nft() { + MockNet::reset(); + + Relay::execute_with(|| { + // Mint the NFT (1, 69) and give it to our "parachain#1 alias". + assert_ok!(relay_chain::Uniques::mint( + relay_chain::RuntimeOrigin::signed(ALICE), + 1, + 69, + child_account_account_id(1, ALICE), + )); + // The parachain#1 alias of Alice is what must hold it on the Relay-chain for it to be + // withdrawable by Alice on the parachain. + assert_eq!( + relay_chain::Uniques::owner(1, 69), + Some(child_account_account_id(1, ALICE)) + ); + }); + ParaA::execute_with(|| { + assert_ok!(parachain::ForeignUniques::force_create( + parachain::RuntimeOrigin::root(), + (Parent, GeneralIndex(1)).into(), + ALICE, + false, + )); + assert_eq!( + parachain::ForeignUniques::owner((Parent, GeneralIndex(1)).into(), 69u32.into()), + None, + ); + assert_eq!(parachain::Balances::reserved_balance(&ALICE), 0); + + // IRL Alice would probably just execute this locally on the Relay-chain, but we can't + // easily do that here since we only send between chains. + let message = Xcm(vec![ + WithdrawAsset((GeneralIndex(1), 69u32).into()), + InitiateTeleport { + assets: AllCounted(1).into(), + dest: Parachain(1).into(), + xcm: Xcm(vec![DepositAsset { + assets: AllCounted(1).into(), + beneficiary: (AccountId32 { id: ALICE.into(), network: None },).into(), + }]), + }, + ]); + // Send teleport + let alice = AccountId32 { id: ALICE.into(), network: None }; + assert_ok!(ParachainPalletXcm::send_xcm(alice, Parent, message)); + }); + ParaA::execute_with(|| { + assert_eq!( + parachain::ForeignUniques::owner((Parent, GeneralIndex(1)).into(), 69u32.into()), + Some(ALICE), + ); + assert_eq!(parachain::Balances::reserved_balance(&ALICE), 1000); + }); + Relay::execute_with(|| { + assert_eq!(relay_chain::Uniques::owner(1, 69), None); + }); + } + + /// Scenario: + /// The relay-chain transfers an NFT into a parachain's sovereign account, who then mints a + /// trustless-backed-derivated locally. + /// + /// Asserts that the parachain accounts are updated as expected. + #[test] + fn reserve_asset_transfer_nft() { + sp_tracing::init_for_tests(); + MockNet::reset(); + + Relay::execute_with(|| { + assert_ok!(relay_chain::Uniques::force_create( + relay_chain::RuntimeOrigin::root(), + 2, + ALICE, + false + )); + assert_ok!(relay_chain::Uniques::mint( + relay_chain::RuntimeOrigin::signed(ALICE), + 2, + 69, + child_account_account_id(1, ALICE) + )); + assert_eq!( + relay_chain::Uniques::owner(2, 69), + Some(child_account_account_id(1, ALICE)) + ); + }); + ParaA::execute_with(|| { + assert_ok!(parachain::ForeignUniques::force_create( + parachain::RuntimeOrigin::root(), + (Parent, GeneralIndex(2)).into(), + ALICE, + false, + )); + assert_eq!( + parachain::ForeignUniques::owner((Parent, GeneralIndex(2)).into(), 69u32.into()), + None, + ); + assert_eq!(parachain::Balances::reserved_balance(&ALICE), 0); + + let message = Xcm(vec![ + WithdrawAsset((GeneralIndex(2), 69u32).into()), + DepositReserveAsset { + assets: AllCounted(1).into(), + dest: Parachain(1).into(), + xcm: Xcm(vec![DepositAsset { + assets: AllCounted(1).into(), + beneficiary: (AccountId32 { id: ALICE.into(), network: None },).into(), + }]), + }, + ]); + // Send transfer + let alice = AccountId32 { id: ALICE.into(), network: None }; + assert_ok!(ParachainPalletXcm::send_xcm(alice, Parent, message)); + }); + ParaA::execute_with(|| { + log::debug!(target: "xcm-exceutor", "Hello"); + assert_eq!( + parachain::ForeignUniques::owner((Parent, GeneralIndex(2)).into(), 69u32.into()), + Some(ALICE), + ); + assert_eq!(parachain::Balances::reserved_balance(&ALICE), 1000); + }); + + Relay::execute_with(|| { + assert_eq!(relay_chain::Uniques::owner(2, 69), Some(child_account_id(1))); + }); + } + + /// Scenario: + /// The relay-chain creates an asset class on a parachain and then Alice transfers her NFT into + /// that parachain's sovereign account, who then mints a trustless-backed-derivative locally. + /// + /// Asserts that the parachain accounts are updated as expected. + #[test] + fn reserve_asset_class_create_and_reserve_transfer() { + MockNet::reset(); + + Relay::execute_with(|| { + assert_ok!(relay_chain::Uniques::force_create( + relay_chain::RuntimeOrigin::root(), + 2, + ALICE, + false + )); + assert_ok!(relay_chain::Uniques::mint( + relay_chain::RuntimeOrigin::signed(ALICE), + 2, + 69, + child_account_account_id(1, ALICE) + )); + assert_eq!( + relay_chain::Uniques::owner(2, 69), + Some(child_account_account_id(1, ALICE)) + ); + + let message = Xcm(vec![Transact { + origin_kind: OriginKind::Xcm, + require_weight_at_most: Weight::from_parts(1_000_000_000, 1024 * 1024), + call: parachain::RuntimeCall::from( + pallet_uniques::Call::::create { + collection: (Parent, 2u64).into(), + admin: parent_account_id(), + }, + ) + .encode() + .into(), + }]); + // Send creation. + assert_ok!(RelayChainPalletXcm::send_xcm(Here, Parachain(1), message)); + }); + ParaA::execute_with(|| { + // Then transfer + let message = Xcm(vec![ + WithdrawAsset((GeneralIndex(2), 69u32).into()), + DepositReserveAsset { + assets: AllCounted(1).into(), + dest: Parachain(1).into(), + xcm: Xcm(vec![DepositAsset { + assets: AllCounted(1).into(), + beneficiary: (AccountId32 { id: ALICE.into(), network: None },).into(), + }]), + }, + ]); + let alice = AccountId32 { id: ALICE.into(), network: None }; + assert_ok!(ParachainPalletXcm::send_xcm(alice, Parent, message)); + }); + ParaA::execute_with(|| { + assert_eq!(parachain::Balances::reserved_balance(&parent_account_id()), 1000); + assert_eq!( + parachain::ForeignUniques::collection_owner((Parent, 2u64).into()), + Some(parent_account_id()) + ); + }); + } + + /// Scenario: + /// A parachain transfers funds on the relay chain to another parachain account. + /// + /// Asserts that the parachain accounts are updated as expected. + #[test] + fn withdraw_and_deposit() { + MockNet::reset(); + + let send_amount = 10; + + ParaA::execute_with(|| { + let message = Xcm(vec![ + WithdrawAsset((Here, send_amount).into()), + buy_execution((Here, send_amount)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: Parachain(2).into() }, + ]); + // Send withdraw and deposit + assert_ok!(ParachainPalletXcm::send_xcm(Here, Parent, message.clone())); + }); + + Relay::execute_with(|| { + assert_eq!( + relay_chain::Balances::free_balance(child_account_id(1)), + INITIAL_BALANCE - send_amount + ); + assert_eq!( + relay_chain::Balances::free_balance(child_account_id(2)), + INITIAL_BALANCE + send_amount + ); + }); + } + + /// Scenario: + /// A parachain wants to be notified that a transfer worked correctly. + /// It sends a `QueryHolding` after the deposit to get notified on success. + /// + /// Asserts that the balances are updated correctly and the expected XCM is sent. + #[test] + fn query_holding() { + MockNet::reset(); + + let send_amount = 10; + let query_id_set = 1234; + + // Send a message which fully succeeds on the relay chain + ParaA::execute_with(|| { + let message = Xcm(vec![ + WithdrawAsset((Here, send_amount).into()), + buy_execution((Here, send_amount)), + DepositAsset { assets: AllCounted(1).into(), beneficiary: Parachain(2).into() }, + ReportHolding { + response_info: QueryResponseInfo { + destination: Parachain(1).into(), + query_id: query_id_set, + max_weight: Weight::from_parts(1_000_000_000, 1024 * 1024), + }, + assets: All.into(), + }, + ]); + // Send withdraw and deposit with query holding + assert_ok!(ParachainPalletXcm::send_xcm(Here, Parent, message.clone(),)); + }); + + // Check that transfer was executed + Relay::execute_with(|| { + // Withdraw executed + assert_eq!( + relay_chain::Balances::free_balance(child_account_id(1)), + INITIAL_BALANCE - send_amount + ); + // Deposit executed + assert_eq!( + relay_chain::Balances::free_balance(child_account_id(2)), + INITIAL_BALANCE + send_amount + ); + }); + + // Check that QueryResponse message was received + ParaA::execute_with(|| { + assert_eq!( + parachain::MsgQueue::received_dmp(), + vec![Xcm(vec![QueryResponse { + query_id: query_id_set, + response: Response::Assets(MultiAssets::new()), + max_weight: Weight::from_parts(1_000_000_000, 1024 * 1024), + querier: Some(Here.into()), + }])], + ); + }); + } +} diff --git a/polkadot/xcm/xcm-simulator/example/src/parachain.rs b/polkadot/xcm/xcm-simulator/example/src/parachain.rs new file mode 100644 index 0000000000000000000000000000000000000000..9c4cbe8fcb2d8d501797cca6e6e29b77ea350cda --- /dev/null +++ b/polkadot/xcm/xcm-simulator/example/src/parachain.rs @@ -0,0 +1,461 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Parachain runtime mock. + +use codec::{Decode, Encode}; +use core::marker::PhantomData; +use frame_support::{ + construct_runtime, parameter_types, + traits::{ContainsPair, EnsureOrigin, EnsureOriginWithArg, Everything, EverythingBut, Nothing}, + weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, +}; + +use frame_system::EnsureRoot; +use sp_core::{ConstU32, H256}; +use sp_runtime::{ + traits::{Get, Hash, IdentityLookup}, + AccountId32, +}; +use sp_std::prelude::*; + +use pallet_xcm::XcmPassthrough; +use polkadot_core_primitives::BlockNumber as RelayBlockNumber; +use polkadot_parachain::primitives::{ + DmpMessageHandler, Id as ParaId, Sibling, XcmpMessageFormat, XcmpMessageHandler, +}; +use xcm::{latest::prelude::*, VersionedXcm}; +use xcm_builder::{ + Account32Hash, AccountId32Aliases, AllowUnpaidExecutionFrom, ConvertedConcreteId, + CurrencyAdapter as XcmCurrencyAdapter, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, + IsConcrete, NativeAsset, NoChecking, NonFungiblesAdapter, ParentIsPreset, + SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, +}; +use xcm_executor::{ + traits::{ConvertLocation, JustTry}, + Config, XcmExecutor, +}; + +pub type SovereignAccountOf = ( + SiblingParachainConvertsVia, + AccountId32Aliases, + ParentIsPreset, +); + +pub type AccountId = AccountId32; +pub type Balance = u128; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = Everything; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub ExistentialDeposit: Balance = 1; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +#[cfg(feature = "runtime-benchmarks")] +pub struct UniquesHelper; +#[cfg(feature = "runtime-benchmarks")] +impl pallet_uniques::BenchmarkHelper for UniquesHelper { + fn collection(i: u16) -> MultiLocation { + GeneralIndex(i as u128).into() + } + fn item(i: u16) -> AssetInstance { + AssetInstance::Index(i as u128) + } +} + +impl pallet_uniques::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CollectionId = MultiLocation; + type ItemId = AssetInstance; + type Currency = Balances; + type CreateOrigin = ForeignCreators; + type ForceOrigin = frame_system::EnsureRoot; + type CollectionDeposit = frame_support::traits::ConstU128<1_000>; + type ItemDeposit = frame_support::traits::ConstU128<1_000>; + type MetadataDepositBase = frame_support::traits::ConstU128<1_000>; + type AttributeDepositBase = frame_support::traits::ConstU128<1_000>; + type DepositPerByte = frame_support::traits::ConstU128<1>; + type StringLimit = ConstU32<64>; + type KeyLimit = ConstU32<64>; + type ValueLimit = ConstU32<128>; + type Locker = (); + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type Helper = UniquesHelper; +} + +// `EnsureOriginWithArg` impl for `CreateOrigin` which allows only XCM origins +// which are locations containing the class location. +pub struct ForeignCreators; +impl EnsureOriginWithArg for ForeignCreators { + type Success = AccountId; + + fn try_origin( + o: RuntimeOrigin, + a: &MultiLocation, + ) -> sp_std::result::Result { + let origin_location = pallet_xcm::EnsureXcm::::try_origin(o.clone())?; + if !a.starts_with(&origin_location) { + return Err(o) + } + SovereignAccountOf::convert_location(&origin_location).ok_or(o) + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin(a: &MultiLocation) -> Result { + Ok(pallet_xcm::Origin::Xcm(a.clone()).into()) + } +} + +parameter_types! { + pub const ReservedXcmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); + pub const ReservedDmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); +} + +parameter_types! { + pub const KsmLocation: MultiLocation = MultiLocation::parent(); + pub const RelayNetwork: NetworkId = NetworkId::Kusama; + pub UniversalLocation: InteriorMultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); +} + +pub type LocationToAccountId = ( + ParentIsPreset, + SiblingParachainConvertsVia, + AccountId32Aliases, + Account32Hash<(), AccountId>, +); + +pub type XcmOriginToCallOrigin = ( + SovereignSignedViaLocation, + SignedAccountId32AsNative, + XcmPassthrough, +); + +parameter_types! { + pub const UnitWeightCost: Weight = Weight::from_parts(1, 1); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(Parent.into()), 1, 1); + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; + pub ForeignPrefix: MultiLocation = (Parent,).into(); +} + +pub type LocalAssetTransactor = ( + XcmCurrencyAdapter, LocationToAccountId, AccountId, ()>, + NonFungiblesAdapter< + ForeignUniques, + ConvertedConcreteId, + SovereignAccountOf, + AccountId, + NoChecking, + (), + >, +); + +pub type XcmRouter = super::ParachainXcmRouter; +pub type Barrier = AllowUnpaidExecutionFrom; + +parameter_types! { + pub NftCollectionOne: MultiAssetFilter + = Wild(AllOf { fun: WildNonFungible, id: Concrete((Parent, GeneralIndex(1)).into()) }); + pub NftCollectionOneForRelay: (MultiAssetFilter, MultiLocation) + = (NftCollectionOne::get(), (Parent,).into()); +} +pub type TrustedTeleporters = xcm_builder::Case; +pub type TrustedReserves = EverythingBut>; + +pub struct XcmConfig; +impl Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = XcmOriginToCallOrigin; + type IsReserve = (NativeAsset, TrustedReserves); + type IsTeleporter = TrustedTeleporters; + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = FixedRateOfFungible; + type ResponseHandler = (); + type AssetTrap = (); + type AssetLocker = PolkadotXcm; + type AssetExchanger = (); + type AssetClaims = (); + type SubscriptionService = (); + type PalletInstancesInfo = (); + type FeeManager = (); + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; + type Aliasers = Nothing; +} + +#[frame_support::pallet] +pub mod mock_msg_queue { + use super::*; + use frame_support::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type XcmExecutor: ExecuteXcm; + } + + #[pallet::call] + impl Pallet {} + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::storage] + #[pallet::getter(fn parachain_id)] + pub(super) type ParachainId = StorageValue<_, ParaId, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn received_dmp)] + /// A queue of received DMP messages + pub(super) type ReceivedDmp = StorageValue<_, Vec>, ValueQuery>; + + impl Get for Pallet { + fn get() -> ParaId { + Self::parachain_id() + } + } + + pub type MessageId = [u8; 32]; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + // XCMP + /// Some XCM was executed OK. + Success(Option), + /// Some XCM failed. + Fail(Option, XcmError), + /// Bad XCM version used. + BadVersion(Option), + /// Bad XCM format used. + BadFormat(Option), + + // DMP + /// Downward message is invalid XCM. + InvalidFormat(MessageId), + /// Downward message is unsupported version of XCM. + UnsupportedVersion(MessageId), + /// Downward message executed with the given outcome. + ExecutedDownward(MessageId, Outcome), + } + + impl Pallet { + pub fn set_para_id(para_id: ParaId) { + ParachainId::::put(para_id); + } + + fn handle_xcmp_message( + sender: ParaId, + _sent_at: RelayBlockNumber, + xcm: VersionedXcm, + max_weight: Weight, + ) -> Result { + let hash = Encode::using_encoded(&xcm, T::Hashing::hash); + let message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); + let (result, event) = match Xcm::::try_from(xcm) { + Ok(xcm) => { + let location = (Parent, Parachain(sender.into())); + match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) { + Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)), + Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + // As far as the caller is concerned, this was dispatched without error, so + // we just report the weight used. + Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + } + }, + Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), + }; + Self::deposit_event(event); + result + } + } + + impl XcmpMessageHandler for Pallet { + fn handle_xcmp_messages<'a, I: Iterator>( + iter: I, + max_weight: Weight, + ) -> Weight { + for (sender, sent_at, data) in iter { + let mut data_ref = data; + let _ = XcmpMessageFormat::decode(&mut data_ref) + .expect("Simulator encodes with versioned xcm format; qed"); + + let mut remaining_fragments = data_ref; + while !remaining_fragments.is_empty() { + if let Ok(xcm) = + VersionedXcm::::decode(&mut remaining_fragments) + { + let _ = Self::handle_xcmp_message(sender, sent_at, xcm, max_weight); + } else { + debug_assert!(false, "Invalid incoming XCMP message data"); + } + } + } + max_weight + } + } + + impl DmpMessageHandler for Pallet { + fn handle_dmp_messages( + iter: impl Iterator)>, + limit: Weight, + ) -> Weight { + for (_i, (_sent_at, data)) in iter.enumerate() { + let id = sp_io::hashing::blake2_256(&data[..]); + let maybe_versioned = VersionedXcm::::decode(&mut &data[..]); + match maybe_versioned { + Err(_) => { + Self::deposit_event(Event::InvalidFormat(id)); + }, + Ok(versioned) => match Xcm::try_from(versioned) { + Err(()) => Self::deposit_event(Event::UnsupportedVersion(id)), + Ok(x) => { + let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), id, limit); + >::append(x); + Self::deposit_event(Event::ExecutedDownward(id, outcome)); + }, + }, + } + } + limit + } + } +} + +impl mock_msg_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; +} + +pub type LocalOriginToLocation = SignedToAccountId32; + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parent.into()); +} + +pub struct TrustedLockerCase(PhantomData); +impl> ContainsPair + for TrustedLockerCase +{ + fn contains(origin: &MultiLocation, asset: &MultiAsset) -> bool { + let (o, a) = T::get(); + a.matches(asset) && &o == origin + } +} + +parameter_types! { + pub RelayTokenForRelay: (MultiLocation, MultiAssetFilter) = (Parent.into(), Wild(AllOf { id: Concrete(Parent.into()), fun: WildFungible })); +} + +pub type TrustedLockers = TrustedLockerCase; + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Nothing; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = (); + type TrustedLockers = TrustedLockers; + type SovereignAccountOf = LocationToAccountId; + type MaxLockers = ConstU32<8>; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = pallet_xcm::TestWeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} + +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + MsgQueue: mock_msg_queue::{Pallet, Storage, Event}, + PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, + ForeignUniques: pallet_uniques::{Pallet, Call, Storage, Event}, + } +); diff --git a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs new file mode 100644 index 0000000000000000000000000000000000000000..6f0e92dc91b9a1c359bb48df9ba18625d867ace7 --- /dev/null +++ b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs @@ -0,0 +1,294 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Relay chain runtime mock. + +use frame_support::{ + construct_runtime, parameter_types, + traits::{AsEnsureOriginWithArg, Everything, Nothing, ProcessMessage, ProcessMessageError}, + weights::{Weight, WeightMeter}, +}; + +use frame_system::EnsureRoot; +use sp_core::{ConstU32, H256}; +use sp_runtime::{traits::IdentityLookup, AccountId32}; + +use polkadot_parachain::primitives::Id as ParaId; +use polkadot_runtime_parachains::{ + configuration, + inclusion::{AggregateMessageOrigin, UmpQueueId}, + origin, shared, +}; +use xcm::latest::prelude::*; +use xcm_builder::{ + Account32Hash, AccountId32Aliases, AllowUnpaidExecutionFrom, AsPrefixedGeneralIndex, + ChildParachainAsNative, ChildParachainConvertsVia, ChildSystemParachainAsSuperuser, + ConvertedConcreteId, CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, + FixedWeightBounds, IsConcrete, NoChecking, NonFungiblesAdapter, SignedAccountId32AsNative, + SignedToAccountId32, SovereignSignedViaLocation, +}; +use xcm_executor::{traits::JustTry, Config, XcmExecutor}; + +pub type AccountId = AccountId32; +pub type Balance = u128; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = Everything; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub ExistentialDeposit: Balance = 1; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +impl pallet_uniques::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CollectionId = u32; + type ItemId = u32; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = frame_system::EnsureRoot; + type CollectionDeposit = frame_support::traits::ConstU128<1_000>; + type ItemDeposit = frame_support::traits::ConstU128<1_000>; + type MetadataDepositBase = frame_support::traits::ConstU128<1_000>; + type AttributeDepositBase = frame_support::traits::ConstU128<1_000>; + type DepositPerByte = frame_support::traits::ConstU128<1>; + type StringLimit = ConstU32<64>; + type KeyLimit = ConstU32<64>; + type ValueLimit = ConstU32<128>; + type Locker = (); + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type Helper = (); +} + +impl shared::Config for Runtime {} + +impl configuration::Config for Runtime { + type WeightInfo = configuration::TestWeightInfo; +} + +parameter_types! { + pub const TokenLocation: MultiLocation = Here.into_location(); + pub RelayNetwork: NetworkId = ByGenesis([0; 32]); + pub const AnyNetwork: Option = None; + pub UniversalLocation: InteriorMultiLocation = Here; + pub UnitWeightCost: u64 = 1_000; +} + +pub type LocationToAccountId = ( + ChildParachainConvertsVia, + AccountId32Aliases, + Account32Hash<(), AccountId>, +); + +pub type LocalAssetTransactor = ( + XcmCurrencyAdapter, LocationToAccountId, AccountId, ()>, + NonFungiblesAdapter< + Uniques, + ConvertedConcreteId, JustTry>, + LocationToAccountId, + AccountId, + NoChecking, + (), + >, +); + +type LocalOriginConverter = ( + SovereignSignedViaLocation, + ChildParachainAsNative, + SignedAccountId32AsNative, + ChildSystemParachainAsSuperuser, +); + +parameter_types! { + pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); + pub TokensPerSecondPerByte: (AssetId, u128, u128) = + (Concrete(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +pub type XcmRouter = super::RelayChainXcmRouter; +pub type Barrier = AllowUnpaidExecutionFrom; + +pub struct XcmConfig; +impl Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = LocalOriginConverter; + type IsReserve = (); + type IsTeleporter = (); + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = FixedRateOfFungible; + type ResponseHandler = (); + type AssetTrap = (); + type AssetLocker = XcmPallet; + type AssetExchanger = (); + type AssetClaims = (); + type SubscriptionService = (); + type PalletInstancesInfo = (); + type FeeManager = (); + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; + type Aliasers = Nothing; +} + +pub type LocalOriginToLocation = SignedToAccountId32; + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parachain(1).into()); +} + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = XcmRouter; + // Anyone can execute XCM messages locally... + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmExecuteFilter = Nothing; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = IsConcrete; + type TrustedLockers = (); + type SovereignAccountOf = LocationToAccountId; + type MaxLockers = ConstU32<8>; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = pallet_xcm::TestWeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} + +parameter_types! { + pub const FirstMessageFactorPercent: u64 = 100; +} + +impl origin::Config for Runtime {} + +type Block = frame_system::mocking::MockBlock; + +parameter_types! { + /// Amount of weight that can be spent per block to service messages. + pub MessageQueueServiceWeight: Weight = Weight::from_parts(1_000_000_000, 1_000_000); + pub const MessageQueueHeapSize: u32 = 65_536; + pub const MessageQueueMaxStale: u32 = 16; +} + +/// Message processor to handle any messages that were enqueued into the `MessageQueue` pallet. +pub struct MessageProcessor; +impl ProcessMessage for MessageProcessor { + type Origin = AggregateMessageOrigin; + + fn process_message( + message: &[u8], + origin: Self::Origin, + meter: &mut WeightMeter, + id: &mut [u8; 32], + ) -> Result { + let para = match origin { + AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para, + }; + xcm_builder::ProcessXcmMessage::< + Junction, + xcm_executor::XcmExecutor, + RuntimeCall, + >::process_message(message, Junction::Parachain(para.into()), meter, id) + } +} + +impl pallet_message_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Size = u32; + type HeapSize = MessageQueueHeapSize; + type MaxStale = MessageQueueMaxStale; + type ServiceWeight = MessageQueueServiceWeight; + type MessageProcessor = MessageProcessor; + type QueueChangeHandler = (); + type QueuePausedQuery = (); + type WeightInfo = (); +} + +construct_runtime!( + pub enum Runtime + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + ParasOrigin: origin::{Pallet, Origin}, + XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin}, + Uniques: pallet_uniques::{Pallet, Call, Storage, Event}, + MessageQueue: pallet_message_queue::{Pallet, Event}, + } +); diff --git a/polkadot/xcm/xcm-simulator/fuzzer/.gitignore b/polkadot/xcm/xcm-simulator/fuzzer/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ec8de6fa0531b609f3ee1f01b95444e8b8ac3ca7 --- /dev/null +++ b/polkadot/xcm/xcm-simulator/fuzzer/.gitignore @@ -0,0 +1,5 @@ +hfuzz_target +hfuzz_workspace +cargo +coverage +ccov.zip diff --git a/polkadot/xcm/xcm-simulator/fuzzer/Cargo.toml b/polkadot/xcm/xcm-simulator/fuzzer/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..ce0528adf1f5bc82237d1e771973002bfd362e36 --- /dev/null +++ b/polkadot/xcm/xcm-simulator/fuzzer/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "xcm-simulator-fuzzer" +description = "Examples of xcm-simulator usage." +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.6.1" } +honggfuzz = "0.5.55" +arbitrary = "1.2.0" +scale-info = { version = "2.5.0", features = ["derive"] } + +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-message-queue = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } + +xcm = { path = "../../" } +xcm-simulator = { path = "../" } +xcm-executor = { path = "../../xcm-executor" } +xcm-builder = { path = "../../xcm-builder" } +pallet-xcm = { path = "../../pallet-xcm" } +polkadot-core-primitives = { path = "../../../core-primitives" } +polkadot-runtime-parachains = { path = "../../../runtime/parachains" } +polkadot-parachain = { path = "../../../parachain" } + +[features] +runtime-benchmarks = [ + "pallet-xcm/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + "frame-support/runtime-benchmarks", +] + +[[bin]] +path = "src/fuzz.rs" +name = "xcm-fuzzer" diff --git a/polkadot/xcm/xcm-simulator/fuzzer/README.md b/polkadot/xcm/xcm-simulator/fuzzer/README.md new file mode 100644 index 0000000000000000000000000000000000000000..69e8cd377b97739d0ad723fe380e668a979dcc82 --- /dev/null +++ b/polkadot/xcm/xcm-simulator/fuzzer/README.md @@ -0,0 +1,38 @@ +# XCM Simulator Fuzzer + +This project will fuzz-test the XCM simulator. It can catch reachable panics, timeouts as well as integer overflows and underflows. + +## Install dependencies + +``` +cargo install honggfuzz +``` + +## Run the fuzzer + +In this directory, run this command: + +``` +cargo hfuzz run xcm-fuzzer +``` + +## Run a single input + +In this directory, run this command: + +``` +cargo hfuzz run-debug xcm-fuzzer hfuzz_workspace/xcm-fuzzer/fuzzer_input_file +``` + +## Generate coverage + +In this directory, run these four commands: + +``` +RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" CARGO_INCREMENTAL=0 SKIP_WASM_BUILD=1 CARGO_HOME=./cargo cargo build +../../../target/debug/xcm-fuzzer hfuzz_workspace/xcm-fuzzer/input/ +zip -0 ccov.zip `find ../../../target/ \( -name "*.gc*" -o -name "test-*.gc*" \) -print` +grcov ccov.zip -s ../../../ -t html --llvm --branch --ignore-not-existing -o ./coverage +``` + +The code coverage will be in `./coverage/index.html`. diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs new file mode 100644 index 0000000000000000000000000000000000000000..441b9f4d28616fe973192ad4e2a426da14511cf7 --- /dev/null +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs @@ -0,0 +1,237 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +mod parachain; +mod relay_chain; + +use codec::DecodeLimit; +use polkadot_core_primitives::AccountId; +use polkadot_parachain::primitives::Id as ParaId; +use sp_runtime::{traits::AccountIdConversion, BuildStorage}; +use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt}; + +use frame_support::assert_ok; +use xcm::{latest::prelude::*, MAX_XCM_DECODE_DEPTH}; + +use arbitrary::{Arbitrary, Error, Unstructured}; + +pub const INITIAL_BALANCE: u128 = 1_000_000_000; + +decl_test_parachain! { + pub struct ParaA { + Runtime = parachain::Runtime, + XcmpMessageHandler = parachain::MsgQueue, + DmpMessageHandler = parachain::MsgQueue, + new_ext = para_ext(1), + } +} + +decl_test_parachain! { + pub struct ParaB { + Runtime = parachain::Runtime, + XcmpMessageHandler = parachain::MsgQueue, + DmpMessageHandler = parachain::MsgQueue, + new_ext = para_ext(2), + } +} + +decl_test_parachain! { + pub struct ParaC { + Runtime = parachain::Runtime, + XcmpMessageHandler = parachain::MsgQueue, + DmpMessageHandler = parachain::MsgQueue, + new_ext = para_ext(3), + } +} + +decl_test_relay_chain! { + pub struct Relay { + Runtime = relay_chain::Runtime, + RuntimeCall = relay_chain::RuntimeCall, + RuntimeEvent = relay_chain::RuntimeEvent, + XcmConfig = relay_chain::XcmConfig, + MessageQueue = relay_chain::MessageQueue, + System = relay_chain::System, + new_ext = relay_ext(), + } +} + +decl_test_network! { + pub struct MockNet { + relay_chain = Relay, + parachains = vec![ + (1, ParaA), + (2, ParaB), + (3, ParaC), + ], + } +} + +// An XCM message that will be generated by the fuzzer through the Arbitrary trait +struct XcmMessage { + // Source chain + source: u32, + // Destination chain + destination: u32, + // XCM message + message: Xcm<()>, +} + +impl<'a> Arbitrary<'a> for XcmMessage { + fn arbitrary(u: &mut Unstructured<'a>) -> Result { + let source: u32 = u.arbitrary()?; + let destination: u32 = u.arbitrary()?; + let mut encoded_message: &[u8] = u.arbitrary()?; + if let Ok(message) = + DecodeLimit::decode_with_depth_limit(MAX_XCM_DECODE_DEPTH, &mut encoded_message) + { + return Ok(XcmMessage { source, destination, message }) + } + Err(Error::IncorrectFormat) + } +} + +pub fn para_account_id(id: u32) -> relay_chain::AccountId { + ParaId::from(id).into_account_truncating() +} + +pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { + use parachain::{MsgQueue, Runtime, System}; + + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + pallet_balances::GenesisConfig:: { + balances: (0..6).map(|i| ([i; 32].into(), INITIAL_BALANCE)).collect(), + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| { + System::set_block_number(1); + MsgQueue::set_para_id(para_id.into()); + }); + ext +} + +pub fn relay_ext() -> sp_io::TestExternalities { + use relay_chain::{Runtime, System}; + + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + let mut balances: Vec<(AccountId, u128)> = vec![]; + balances.append(&mut (1..=3).map(|i| (para_account_id(i), INITIAL_BALANCE)).collect()); + balances.append(&mut (0..6).map(|i| ([i; 32].into(), INITIAL_BALANCE)).collect()); + + pallet_balances::GenesisConfig:: { balances } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +pub type RelayChainPalletXcm = pallet_xcm::Pallet; +pub type ParachainPalletXcm = pallet_xcm::Pallet; + +fn run_input(xcm_messages: [XcmMessage; 5]) { + MockNet::reset(); + + #[cfg(not(fuzzing))] + println!(); + + for xcm_message in xcm_messages { + if xcm_message.source % 4 == 0 { + // We get the destination for the message + let parachain_id = (xcm_message.destination % 3) + 1; + let destination: MultiLocation = Parachain(parachain_id).into(); + #[cfg(not(fuzzing))] + { + println!(" source: Relay Chain"); + println!(" destination: Parachain {parachain_id}"); + println!(" message: {:?}", xcm_message.message); + } + Relay::execute_with(|| { + assert_ok!(RelayChainPalletXcm::send_xcm(Here, destination, xcm_message.message)); + }) + } else { + // We get the source's execution method + let execute_with = match xcm_message.source % 4 { + 1 => ParaA::execute_with, + 2 => ParaB::execute_with, + _ => ParaC::execute_with, + }; + // We get the destination for the message + let destination: MultiLocation = match xcm_message.destination % 4 { + n @ 1..=3 => (Parent, Parachain(n)).into(), + _ => Parent.into(), + }; + #[cfg(not(fuzzing))] + { + let destination_str = match xcm_message.destination % 4 { + n @ 1..=3 => format!("Parachain {n}"), + _ => "Relay Chain".to_string(), + }; + println!(" source: Parachain {}", xcm_message.source % 4); + println!(" destination: {}", destination_str); + println!(" message: {:?}", xcm_message.message); + } + // We execute the message with the appropriate source and destination + execute_with(|| { + assert_ok!(ParachainPalletXcm::send_xcm(Here, destination, xcm_message.message)); + }); + } + #[cfg(not(fuzzing))] + println!(); + } + Relay::execute_with(|| {}); +} + +fn main() { + #[cfg(fuzzing)] + { + loop { + honggfuzz::fuzz!(|xcm_messages: [XcmMessage; 5]| { + run_input(xcm_messages); + }) + } + } + #[cfg(not(fuzzing))] + { + use std::{env, fs, fs::File, io::Read}; + let args: Vec<_> = env::args().collect(); + let md = fs::metadata(&args[1]).unwrap(); + let all_files = match md.is_dir() { + true => fs::read_dir(&args[1]) + .unwrap() + .map(|x| x.unwrap().path().to_str().unwrap().to_string()) + .collect::>(), + false => (args[1..]).to_vec(), + }; + println!("All_files {:?}", all_files); + for argument in all_files { + println!("Now doing file {:?}", argument); + let mut buffer: Vec = Vec::new(); + let mut f = File::open(argument).unwrap(); + f.read_to_end(&mut buffer).unwrap(); + let mut unstructured = Unstructured::new(&buffer); + if let Ok(xcm_messages) = unstructured.arbitrary() { + run_input(xcm_messages); + } + } + } +} diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs new file mode 100644 index 0000000000000000000000000000000000000000..3d0b1c82f6911bf6a6650ae1fc98ef74bef22c88 --- /dev/null +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs @@ -0,0 +1,358 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Parachain runtime mock. + +use codec::{Decode, Encode}; +use frame_support::{ + construct_runtime, parameter_types, + traits::{Everything, Nothing}, + weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, +}; + +use frame_system::EnsureRoot; +use sp_core::{ConstU32, H256}; +use sp_runtime::{ + traits::{Hash, IdentityLookup}, + AccountId32, +}; +use sp_std::prelude::*; + +use pallet_xcm::XcmPassthrough; +use polkadot_core_primitives::BlockNumber as RelayBlockNumber; +use polkadot_parachain::primitives::{ + DmpMessageHandler, Id as ParaId, Sibling, XcmpMessageFormat, XcmpMessageHandler, +}; +use xcm::{latest::prelude::*, VersionedXcm}; +use xcm_builder::{ + AccountId32Aliases, AllowUnpaidExecutionFrom, CurrencyAdapter as XcmCurrencyAdapter, + EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, IsConcrete, NativeAsset, + ParentIsPreset, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, +}; +use xcm_executor::{Config, XcmExecutor}; + +pub type AccountId = AccountId32; +pub type Balance = u128; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = Everything; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub ExistentialDeposit: Balance = 1; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +parameter_types! { + pub const ReservedXcmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); + pub const ReservedDmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); +} + +parameter_types! { + pub const KsmLocation: MultiLocation = MultiLocation::parent(); + pub const RelayNetwork: NetworkId = NetworkId::Kusama; + pub UniversalLocation: InteriorMultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); +} + +pub type LocationToAccountId = ( + ParentIsPreset, + SiblingParachainConvertsVia, + AccountId32Aliases, +); + +pub type XcmOriginToCallOrigin = ( + SovereignSignedViaLocation, + SignedAccountId32AsNative, + XcmPassthrough, +); + +parameter_types! { + pub const UnitWeightCost: Weight = Weight::from_parts(1, 1); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(Parent.into()), 1, 1); + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +pub type LocalAssetTransactor = + XcmCurrencyAdapter, LocationToAccountId, AccountId, ()>; + +pub type XcmRouter = super::ParachainXcmRouter; +pub type Barrier = AllowUnpaidExecutionFrom; + +pub struct XcmConfig; +impl Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = XcmOriginToCallOrigin; + type IsReserve = NativeAsset; + type IsTeleporter = (); + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = FixedRateOfFungible; + type ResponseHandler = (); + type AssetTrap = (); + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = (); + type SubscriptionService = (); + type PalletInstancesInfo = (); + type FeeManager = (); + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; + type Aliasers = Nothing; +} + +#[frame_support::pallet] +pub mod mock_msg_queue { + use super::*; + use frame_support::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type XcmExecutor: ExecuteXcm; + } + + #[pallet::call] + impl Pallet {} + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::storage] + #[pallet::getter(fn parachain_id)] + pub(super) type ParachainId = StorageValue<_, ParaId, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn received_dmp)] + /// A queue of received DMP messages + pub(super) type ReceivedDmp = StorageValue<_, Vec>, ValueQuery>; + + impl Get for Pallet { + fn get() -> ParaId { + Self::parachain_id() + } + } + + pub type MessageId = [u8; 32]; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + // XCMP + /// Some XCM was executed OK. + Success(Option), + /// Some XCM failed. + Fail(Option, XcmError), + /// Bad XCM version used. + BadVersion(Option), + /// Bad XCM format used. + BadFormat(Option), + + // DMP + /// Downward message is invalid XCM. + InvalidFormat(MessageId), + /// Downward message is unsupported version of XCM. + UnsupportedVersion(MessageId), + /// Downward message executed with the given outcome. + ExecutedDownward(MessageId, Outcome), + } + + impl Pallet { + pub fn set_para_id(para_id: ParaId) { + ParachainId::::put(para_id); + } + + fn handle_xcmp_message( + sender: ParaId, + _sent_at: RelayBlockNumber, + xcm: VersionedXcm, + max_weight: Weight, + ) -> Result { + let hash = Encode::using_encoded(&xcm, T::Hashing::hash); + let message_hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let (result, event) = match Xcm::::try_from(xcm) { + Ok(xcm) => { + let location = MultiLocation::new(1, X1(Parachain(sender.into()))); + match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) { + Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)), + Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + // As far as the caller is concerned, this was dispatched without error, so + // we just report the weight used. + Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + } + }, + Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), + }; + Self::deposit_event(event); + result + } + } + + impl XcmpMessageHandler for Pallet { + fn handle_xcmp_messages<'a, I: Iterator>( + iter: I, + max_weight: Weight, + ) -> Weight { + for (sender, sent_at, data) in iter { + let mut data_ref = data; + let _ = XcmpMessageFormat::decode(&mut data_ref) + .expect("Simulator encodes with versioned xcm format; qed"); + + let mut remaining_fragments = data_ref; + while !remaining_fragments.is_empty() { + if let Ok(xcm) = + VersionedXcm::::decode(&mut remaining_fragments) + { + let _ = Self::handle_xcmp_message(sender, sent_at, xcm, max_weight); + } else { + debug_assert!(false, "Invalid incoming XCMP message data"); + } + } + } + max_weight + } + } + + impl DmpMessageHandler for Pallet { + fn handle_dmp_messages( + iter: impl Iterator)>, + limit: Weight, + ) -> Weight { + for (_i, (_sent_at, data)) in iter.enumerate() { + let id = sp_io::hashing::blake2_256(&data[..]); + let maybe_msg = VersionedXcm::::decode(&mut &data[..]) + .map(Xcm::::try_from); + match maybe_msg { + Err(_) => { + Self::deposit_event(Event::InvalidFormat(id)); + }, + Ok(Err(())) => { + Self::deposit_event(Event::UnsupportedVersion(id)); + }, + Ok(Ok(x)) => { + let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), id, limit); + >::append(x); + Self::deposit_event(Event::ExecutedDownward(id, outcome)); + }, + } + } + limit + } + } +} + +impl mock_msg_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; +} + +pub type LocalOriginToLocation = SignedToAccountId32; + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parent.into()); +} + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Nothing; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = (); + type TrustedLockers = (); + type SovereignAccountOf = LocationToAccountId; + type MaxLockers = frame_support::traits::ConstU32<8>; + type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = pallet_xcm::TestWeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} + +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + MsgQueue: mock_msg_queue::{Pallet, Storage, Event}, + PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, + } +); diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs new file mode 100644 index 0000000000000000000000000000000000000000..32f3b8aa83fba13d7b3778b3603cb2b41d5d45e5 --- /dev/null +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs @@ -0,0 +1,261 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Relay chain runtime mock. + +use frame_support::{ + construct_runtime, parameter_types, + traits::{Everything, Nothing, ProcessMessage, ProcessMessageError}, + weights::{Weight, WeightMeter}, +}; + +use frame_system::EnsureRoot; +use sp_core::{ConstU32, H256}; +use sp_runtime::{traits::IdentityLookup, AccountId32}; + +use polkadot_parachain::primitives::Id as ParaId; +use polkadot_runtime_parachains::{ + configuration, + inclusion::{AggregateMessageOrigin, UmpQueueId}, + origin, shared, +}; +use xcm::latest::prelude::*; +use xcm_builder::{ + AccountId32Aliases, AllowUnpaidExecutionFrom, ChildParachainAsNative, + ChildParachainConvertsVia, ChildSystemParachainAsSuperuser, + CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, FixedWeightBounds, IsConcrete, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, +}; +use xcm_executor::{Config, XcmExecutor}; + +pub type AccountId = AccountId32; +pub type Balance = u128; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = Everything; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub ExistentialDeposit: Balance = 1; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; +} + +impl shared::Config for Runtime {} + +impl configuration::Config for Runtime { + type WeightInfo = configuration::TestWeightInfo; +} + +parameter_types! { + pub const TokenLocation: MultiLocation = Here.into_location(); + pub const ThisNetwork: NetworkId = NetworkId::ByGenesis([0; 32]); + pub const AnyNetwork: Option = None; + pub const UniversalLocation: InteriorMultiLocation = Here; +} + +pub type SovereignAccountOf = + (ChildParachainConvertsVia, AccountId32Aliases); + +pub type LocalAssetTransactor = + XcmCurrencyAdapter, SovereignAccountOf, AccountId, ()>; + +type LocalOriginConverter = ( + SovereignSignedViaLocation, + ChildParachainAsNative, + SignedAccountId32AsNative, + ChildSystemParachainAsSuperuser, +); + +parameter_types! { + pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(TokenLocation::get()), 1, 1); + pub const MaxInstructions: u32 = u32::MAX; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +pub type XcmRouter = super::RelayChainXcmRouter; +pub type Barrier = AllowUnpaidExecutionFrom; + +pub struct XcmConfig; +impl Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = LocalOriginConverter; + type IsReserve = (); + type IsTeleporter = (); + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = FixedRateOfFungible; + type ResponseHandler = (); + type AssetTrap = (); + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = (); + type SubscriptionService = (); + type PalletInstancesInfo = (); + type FeeManager = (); + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; + type Aliasers = Nothing; +} + +pub type LocalOriginToLocation = SignedToAccountId32; + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parachain(1).into()); +} + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = XcmRouter; + // Anyone can execute XCM messages locally... + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmExecuteFilter = Nothing; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = (); + type TrustedLockers = (); + type SovereignAccountOf = SovereignAccountOf; + type MaxLockers = ConstU32<8>; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = pallet_xcm::TestWeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; + type AdminOrigin = EnsureRoot; +} + +parameter_types! { + pub const FirstMessageFactorPercent: u64 = 100; +} + +impl origin::Config for Runtime {} + +type Block = frame_system::mocking::MockBlock; + +parameter_types! { + /// Amount of weight that can be spent per block to service messages. + pub MessageQueueServiceWeight: Weight = Weight::from_parts(1_000_000_000, 1_000_000); + pub const MessageQueueHeapSize: u32 = 65_536; + pub const MessageQueueMaxStale: u32 = 16; +} + +/// Message processor to handle any messages that were enqueued into the `MessageQueue` pallet. +pub struct MessageProcessor; +impl ProcessMessage for MessageProcessor { + type Origin = AggregateMessageOrigin; + + fn process_message( + message: &[u8], + origin: Self::Origin, + meter: &mut WeightMeter, + id: &mut [u8; 32], + ) -> Result { + let para = match origin { + AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para, + }; + xcm_builder::ProcessXcmMessage::< + Junction, + xcm_executor::XcmExecutor, + RuntimeCall, + >::process_message(message, Junction::Parachain(para.into()), meter, id) + } +} + +impl pallet_message_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Size = u32; + type HeapSize = MessageQueueHeapSize; + type MaxStale = MessageQueueMaxStale; + type ServiceWeight = MessageQueueServiceWeight; + #[cfg(not(feature = "runtime-benchmarks"))] + type MessageProcessor = MessageProcessor; + #[cfg(feature = "runtime-benchmarks")] + type MessageProcessor = + pallet_message_queue::mock_helpers::NoopMessageProcessor; + type QueueChangeHandler = (); + type QueuePausedQuery = (); + type WeightInfo = (); +} + +construct_runtime!( + pub enum Runtime + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + ParasOrigin: origin::{Pallet, Origin}, + XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin}, + MessageQueue: pallet_message_queue::{Pallet, Event}, + } +); diff --git a/polkadot/xcm/xcm-simulator/src/lib.rs b/polkadot/xcm/xcm-simulator/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..cf56784f7d4e228f00a2ef08d07b2f8395670a5e --- /dev/null +++ b/polkadot/xcm/xcm-simulator/src/lib.rs @@ -0,0 +1,447 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Test kit to simulate cross-chain message passing and XCM execution. + +pub use codec::Encode; +pub use paste; + +pub use frame_support::{ + traits::{EnqueueMessage, Get, ProcessMessage, ProcessMessageError, ServiceQueues}, + weights::{Weight, WeightMeter}, +}; +pub use sp_io::{hashing::blake2_256, TestExternalities}; +pub use sp_std::{cell::RefCell, collections::vec_deque::VecDeque, marker::PhantomData}; + +pub use polkadot_core_primitives::BlockNumber as RelayBlockNumber; +pub use polkadot_parachain::primitives::{ + DmpMessageHandler as DmpMessageHandlerT, Id as ParaId, XcmpMessageFormat, + XcmpMessageHandler as XcmpMessageHandlerT, +}; +pub use polkadot_runtime_parachains::{ + dmp, + inclusion::{AggregateMessageOrigin, UmpQueueId}, +}; +pub use xcm::{latest::prelude::*, VersionedXcm}; +pub use xcm_builder::ProcessXcmMessage; +pub use xcm_executor::XcmExecutor; + +pub trait TestExt { + /// Initialize the test environment. + fn new_ext() -> sp_io::TestExternalities; + /// Resets the state of the test environment. + fn reset_ext(); + /// Execute code in the context of the test externalities, without automatic + /// message processing. All messages in the message buses can be processed + /// by calling `Self::dispatch_xcm_buses()`. + fn execute_without_dispatch(execute: impl FnOnce() -> R) -> R; + /// Process all messages in the message buses + fn dispatch_xcm_buses(); + /// Execute some code in the context of the test externalities, with + /// automatic message processing. + /// Messages are dispatched once the passed closure completes. + fn execute_with(execute: impl FnOnce() -> R) -> R { + let result = Self::execute_without_dispatch(execute); + Self::dispatch_xcm_buses(); + result + } +} + +pub enum MessageKind { + Ump, + Dmp, + Xcmp, +} + +/// Encodes the provided XCM message based on the `message_kind`. +pub fn encode_xcm(message: Xcm<()>, message_kind: MessageKind) -> Vec { + match message_kind { + MessageKind::Ump | MessageKind::Dmp => VersionedXcm::<()>::from(message).encode(), + MessageKind::Xcmp => { + let fmt = XcmpMessageFormat::ConcatenatedVersionedXcm; + let mut outbound = fmt.encode(); + + let encoded = VersionedXcm::<()>::from(message).encode(); + outbound.extend_from_slice(&encoded[..]); + outbound + }, + } +} + +pub fn fake_message_hash(message: &Xcm) -> XcmHash { + message.using_encoded(blake2_256) +} + +/// The macro is implementing upward message passing(UMP) for the provided relay +/// chain struct. The struct has to provide the XCM configuration for the relay +/// chain. +/// +/// ```ignore +/// decl_test_relay_chain! { +/// pub struct Relay { +/// Runtime = relay_chain::Runtime, +/// XcmConfig = relay_chain::XcmConfig, +/// new_ext = relay_ext(), +/// } +/// } +/// ``` +#[macro_export] +#[rustfmt::skip] +macro_rules! decl_test_relay_chain { + ( + pub struct $name:ident { + Runtime = $runtime:path, + RuntimeCall = $runtime_call:path, + RuntimeEvent = $runtime_event:path, + XcmConfig = $xcm_config:path, + MessageQueue = $mq:path, + System = $system:path, + new_ext = $new_ext:expr, + } + ) => { + pub struct $name; + + $crate::__impl_ext!($name, $new_ext); + + impl $crate::ProcessMessage for $name { + type Origin = $crate::ParaId; + + fn process_message( + msg: &[u8], + para: Self::Origin, + meter: &mut $crate::WeightMeter, + id: &mut [u8; 32], + ) -> Result { + use $crate::{Weight, AggregateMessageOrigin, UmpQueueId, ServiceQueues, EnqueueMessage}; + use $mq as message_queue; + use $runtime_event as runtime_event; + + Self::execute_with(|| { + <$mq as EnqueueMessage>::enqueue_message( + msg.try_into().expect("Message too long"), + AggregateMessageOrigin::Ump(UmpQueueId::Para(para.clone())) + ); + + <$system>::reset_events(); + <$mq as ServiceQueues>::service_queues(Weight::MAX); + let events = <$system>::events(); + let event = events.last().expect("There must be at least one event"); + + match &event.event { + runtime_event::MessageQueue( + pallet_message_queue::Event::Processed {origin, ..}) => { + assert_eq!(origin, &AggregateMessageOrigin::Ump(UmpQueueId::Para(para))); + }, + event => panic!("Unexpected event: {:#?}", event), + } + Ok(true) + }) + } + } + }; +} + +/// The macro is implementing the `XcmMessageHandlerT` and `DmpMessageHandlerT` +/// traits for the provided parachain struct. Expects the provided parachain +/// struct to define the XcmpMessageHandler and DmpMessageHandler pallets that +/// contain the message handling logic. +/// +/// ```ignore +/// decl_test_parachain! { +/// pub struct ParaA { +/// Runtime = parachain::Runtime, +/// XcmpMessageHandler = parachain::MsgQueue, +/// DmpMessageHandler = parachain::MsgQueue, +/// new_ext = para_ext(), +/// } +/// } +/// ``` +#[macro_export] +macro_rules! decl_test_parachain { + ( + pub struct $name:ident { + Runtime = $runtime:path, + XcmpMessageHandler = $xcmp_message_handler:path, + DmpMessageHandler = $dmp_message_handler:path, + new_ext = $new_ext:expr, + } + ) => { + pub struct $name; + + $crate::__impl_ext!($name, $new_ext); + + impl $crate::XcmpMessageHandlerT for $name { + fn handle_xcmp_messages< + 'a, + I: Iterator, + >( + iter: I, + max_weight: $crate::Weight, + ) -> $crate::Weight { + use $crate::{TestExt, XcmpMessageHandlerT}; + + $name::execute_with(|| { + <$xcmp_message_handler>::handle_xcmp_messages(iter, max_weight) + }) + } + } + + impl $crate::DmpMessageHandlerT for $name { + fn handle_dmp_messages( + iter: impl Iterator)>, + max_weight: $crate::Weight, + ) -> $crate::Weight { + use $crate::{DmpMessageHandlerT, TestExt}; + + $name::execute_with(|| { + <$dmp_message_handler>::handle_dmp_messages(iter, max_weight) + }) + } + } + }; +} + +/// Implements the `TestExt` trait for a specified struct. +#[macro_export] +macro_rules! __impl_ext { + // entry point: generate ext name + ($name:ident, $new_ext:expr) => { + $crate::paste::paste! { + $crate::__impl_ext!(@impl $name, $new_ext, []); + } + }; + // impl + (@impl $name:ident, $new_ext:expr, $ext_name:ident) => { + thread_local! { + pub static $ext_name: $crate::RefCell<$crate::TestExternalities> + = $crate::RefCell::new($new_ext); + } + + impl $crate::TestExt for $name { + fn new_ext() -> $crate::TestExternalities { + $new_ext + } + + fn reset_ext() { + $ext_name.with(|v| *v.borrow_mut() = $new_ext); + } + + fn execute_without_dispatch(execute: impl FnOnce() -> R) -> R { + $ext_name.with(|v| v.borrow_mut().execute_with(execute)) + } + + fn dispatch_xcm_buses() { + while exists_messages_in_any_bus() { + if let Err(xcm_error) = process_relay_messages() { + panic!("Relay chain XCM execution failure: {:?}", xcm_error); + } + if let Err(xcm_error) = process_para_messages() { + panic!("Parachain XCM execution failure: {:?}", xcm_error); + } + } + } + } + }; +} + +thread_local! { + pub static PARA_MESSAGE_BUS: RefCell)>> + = RefCell::new(VecDeque::new()); + pub static RELAY_MESSAGE_BUS: RefCell)>> + = RefCell::new(VecDeque::new()); +} + +/// Declares a test network that consists of a relay chain and multiple +/// parachains. Expects a network struct as an argument and implements testing +/// functionality, `ParachainXcmRouter` and the `RelayChainXcmRouter`. The +/// struct needs to contain the relay chain struct and an indexed list of +/// parachains that are going to be in the network. +/// +/// ```ignore +/// decl_test_network! { +/// pub struct ExampleNet { +/// relay_chain = Relay, +/// parachains = vec![ +/// (1, ParaA), +/// (2, ParaB), +/// ], +/// } +/// } +/// ``` +#[macro_export] +macro_rules! decl_test_network { + ( + pub struct $name:ident { + relay_chain = $relay_chain:ty, + parachains = vec![ $( ($para_id:expr, $parachain:ty), )* ], + } + ) => { + use $crate::Encode; + pub struct $name; + + impl $name { + pub fn reset() { + use $crate::{TestExt, VecDeque}; + // Reset relay chain message bus. + $crate::RELAY_MESSAGE_BUS.with(|b| b.replace(VecDeque::new())); + // Reset parachain message bus. + $crate::PARA_MESSAGE_BUS.with(|b| b.replace(VecDeque::new())); + <$relay_chain>::reset_ext(); + $( <$parachain>::reset_ext(); )* + } + } + + /// Check if any messages exist in either message bus. + fn exists_messages_in_any_bus() -> bool { + use $crate::{RELAY_MESSAGE_BUS, PARA_MESSAGE_BUS}; + let no_relay_messages_left = RELAY_MESSAGE_BUS.with(|b| b.borrow().is_empty()); + let no_parachain_messages_left = PARA_MESSAGE_BUS.with(|b| b.borrow().is_empty()); + !(no_relay_messages_left && no_parachain_messages_left) + } + + /// Process all messages originating from parachains. + fn process_para_messages() -> $crate::XcmResult { + use $crate::{ProcessMessage, XcmpMessageHandlerT}; + + while let Some((para_id, destination, message)) = $crate::PARA_MESSAGE_BUS.with( + |b| b.borrow_mut().pop_front()) { + match destination.interior() { + $crate::Junctions::Here if destination.parent_count() == 1 => { + let encoded = $crate::encode_xcm(message, $crate::MessageKind::Ump); + let mut _id = [0; 32]; + let r = <$relay_chain>::process_message( + encoded.as_slice(), para_id, + &mut $crate::WeightMeter::max_limit(), + &mut _id, + ); + match r { + Err($crate::ProcessMessageError::Overweight(required)) => + return Err($crate::XcmError::WeightLimitReached(required)), + // Not really the correct error, but there is no "undecodable". + Err(_) => return Err($crate::XcmError::Unimplemented), + Ok(_) => (), + } + }, + $( + $crate::X1($crate::Parachain(id)) if *id == $para_id && destination.parent_count() == 1 => { + let encoded = $crate::encode_xcm(message, $crate::MessageKind::Xcmp); + let messages = vec![(para_id, 1, &encoded[..])]; + let _weight = <$parachain>::handle_xcmp_messages( + messages.into_iter(), + $crate::Weight::MAX, + ); + }, + )* + _ => { + return Err($crate::XcmError::Unroutable); + } + } + } + + Ok(()) + } + + /// Process all messages originating from the relay chain. + fn process_relay_messages() -> $crate::XcmResult { + use $crate::DmpMessageHandlerT; + + while let Some((destination, message)) = $crate::RELAY_MESSAGE_BUS.with( + |b| b.borrow_mut().pop_front()) { + match destination.interior() { + $( + $crate::X1($crate::Parachain(id)) if *id == $para_id && destination.parent_count() == 0 => { + let encoded = $crate::encode_xcm(message, $crate::MessageKind::Dmp); + // NOTE: RelayChainBlockNumber is hard-coded to 1 + let messages = vec![(1, encoded)]; + let _weight = <$parachain>::handle_dmp_messages( + messages.into_iter(), $crate::Weight::MAX, + ); + }, + )* + _ => return Err($crate::XcmError::Transport("Only sends to children parachain.")), + } + } + + Ok(()) + } + + /// XCM router for parachain. + pub struct ParachainXcmRouter($crate::PhantomData); + + impl> $crate::SendXcm for ParachainXcmRouter { + type Ticket = ($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>); + fn validate( + destination: &mut Option<$crate::MultiLocation>, + message: &mut Option<$crate::Xcm<()>>, + ) -> $crate::SendResult<($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>)> { + use $crate::XcmpMessageHandlerT; + + let d = destination.take().ok_or($crate::SendError::MissingArgument)?; + match (d.interior(), d.parent_count()) { + ($crate::Junctions::Here, 1) => {}, + $( + ($crate::X1($crate::Parachain(id)), 1) if id == &$para_id => {} + )* + _ => { + *destination = Some(d); + return Err($crate::SendError::NotApplicable) + }, + } + let m = message.take().ok_or($crate::SendError::MissingArgument)?; + Ok(((T::get(), d, m), $crate::MultiAssets::new())) + } + fn deliver( + triple: ($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>), + ) -> Result<$crate::XcmHash, $crate::SendError> { + let hash = $crate::fake_message_hash(&triple.2); + $crate::PARA_MESSAGE_BUS.with(|b| b.borrow_mut().push_back(triple)); + Ok(hash) + } + } + + /// XCM router for relay chain. + pub struct RelayChainXcmRouter; + impl $crate::SendXcm for RelayChainXcmRouter { + type Ticket = ($crate::MultiLocation, $crate::Xcm<()>); + fn validate( + destination: &mut Option<$crate::MultiLocation>, + message: &mut Option<$crate::Xcm<()>>, + ) -> $crate::SendResult<($crate::MultiLocation, $crate::Xcm<()>)> { + use $crate::DmpMessageHandlerT; + + let d = destination.take().ok_or($crate::SendError::MissingArgument)?; + match (d.interior(), d.parent_count()) { + $( + ($crate::X1($crate::Parachain(id)), 0) if id == &$para_id => {}, + )* + _ => { + *destination = Some(d); + return Err($crate::SendError::NotApplicable) + }, + } + let m = message.take().ok_or($crate::SendError::MissingArgument)?; + Ok(((d, m), $crate::MultiAssets::new())) + } + fn deliver( + pair: ($crate::MultiLocation, $crate::Xcm<()>), + ) -> Result<$crate::XcmHash, $crate::SendError> { + let hash = $crate::fake_message_hash(&pair.1); + $crate::RELAY_MESSAGE_BUS.with(|b| b.borrow_mut().push_back(pair)); + Ok(hash) + } + } + }; +} diff --git a/polkadot/zombienet_tests/.set_env b/polkadot/zombienet_tests/.set_env new file mode 100644 index 0000000000000000000000000000000000000000..f5d09f21873573adeb73abd00129b0c0ef0c309d --- /dev/null +++ b/polkadot/zombienet_tests/.set_env @@ -0,0 +1,20 @@ +pathprepend() { + for ((i=$#; i>0; i--)); + do + ARG="$@[$i]" + if [ -d "$ARG" ] && [[ ":$PATH:" != *":$ARG:"* ]]; then + PATH="$ARG${PATH:+":$PATH"}" + fi + done +} + +# paths are prepend in order, so you can manage with version will run +# by the order of this array +CUSTOM_PATHS=( + "~/polkadot/target/release" + "~/polkadot/target/testnet" + "~/cumulus/target/release" +) + +pathprepend $CUSTOM_PATHS +export PATH=$PATH diff --git a/polkadot/zombienet_tests/README.md b/polkadot/zombienet_tests/README.md new file mode 100644 index 0000000000000000000000000000000000000000..84334c3e1cfefadc053165c4646d384840268dc4 --- /dev/null +++ b/polkadot/zombienet_tests/README.md @@ -0,0 +1,60 @@ +# Zombienet tests + +_The content of this directory is meant to be used by Parity's private CI/CD infrastructure with private tools. At the moment those tools are still early stage of development and we don't know if / when they will available for public use._ + +## Contents of this directory + +`parachains` + At the moment this directory only have one test related to parachains: `/parachains-smoke-test`, that check the parachain registration and the block height. + +## Resources + +* [zombienet repo](https://github.com/paritytech/zombienet) +* [zombienet book](https://paritytech.github.io/zombienet/) + +## Running tests locally + +To run any test locally use the native provider (`zombienet test -p native ...`) you need first build the binaries. They are: + +* adder-collator -> polkadot/target/testnet/adder-collator +* malus -> polkadot/target/testnet/malus +* polkadot -> polkadot/target/testnet/polkadot, polkadot/target/testnet/polkadot-prepare-worker, polkadot/target/testnet/polkadot-execute-worker +* polkadot-collator -> cumulus/target/release/polkadot-parachain +* undying-collator -> polkadot/target/testnet/undying-collator + +To build them use: +* adder-collator -> `cargo build --profile testnet -p test-parachain-adder-collator` +* undying-collator -> `cargo build --profile testnet -p test-parachain-undying-collator` +* malus -> `cargo build --profile testnet -p polkadot-test-malus` +* polkadot (in polkadot repo) and polkadot-collator (in cumulus repo) -> `cargo build --profile testnet` + +One solution is to use the `.set_env` file (from this directory) and fill the `CUSTOM_PATHS` before *source* it to patch the PATH of your system to find the binaries you just built. + +E.g.: +``` +$ cat .set_env +(...) +# by the order of this array +CUSTOM_PATHS=( + "~/polkadot/target/release" + "~/polkadot/target/testnet" + "~/cumulus/target/release" +) +(...) + +source .set_env +``` + +Then you have your `PATH` customized and ready to run `zombienet`. + **NOTE**: You should need to do this ones per terminal session, since we are patching the `PATH` and re-exporting. **Or** you can also `source` this file in your `.bashrc` file to get executed automatically in each new session. + +Example: + +You can run a test locally by executing: +```sh +zombienet test -p native 0001-parachains-pvf.zndsl +``` + +## Questions / permissions + +Ping in element Javier (@javier:matrix.parity.io) to ask questions or grant permission to run the test from your local setup. diff --git a/polkadot/zombienet_tests/async_backing/001-async-backing-compatibility.toml b/polkadot/zombienet_tests/async_backing/001-async-backing-compatibility.toml new file mode 100644 index 0000000000000000000000000000000000000000..918fb5bf4f62c6be92009a62143fb5972d8c2292 --- /dev/null +++ b/polkadot/zombienet_tests/async_backing/001-async-backing-compatibility.toml @@ -0,0 +1,34 @@ +[settings] +timeout = 1000 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +default_command = "polkadot" + + [relaychain.default_resources] + limits = { memory = "4G", cpu = "2" } + requests = { memory = "2G", cpu = "1" } + + [[relaychain.nodes]] + name = "alice" + args = [ "-lparachain=debug,runtime=debug"] + + [[relaychain.nodes]] + name = "bob" + image = "{{ZOMBIENET_INTEGRATION_TEST_SECONDARY_IMAGE}}" + args = [ "-lparachain=debug,runtime=debug"] + +[[parachains]] +id = 100 + + [parachains.collator] + name = "collator01" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug"] + +[types.Header] +number = "u64" +parent_hash = "Hash" +post_state = "Hash" diff --git a/polkadot/zombienet_tests/async_backing/001-async-backing-compatibility.zndsl b/polkadot/zombienet_tests/async_backing/001-async-backing-compatibility.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..46c1d77acf46cec2a0925ed80bc93487e7c12452 --- /dev/null +++ b/polkadot/zombienet_tests/async_backing/001-async-backing-compatibility.zndsl @@ -0,0 +1,23 @@ +Description: Async Backing Compatibility Test +Network: ./001-async-backing-compatibility.toml +Creds: config + +# General +alice: is up +bob: is up + +# Check authority status +alice: reports node_roles is 4 +bob: reports node_roles is 4 + +# Check peers +alice: reports peers count is at least 2 within 20 seconds +bob: reports peers count is at least 2 within 20 seconds + +# Parachain registration +alice: parachain 100 is registered within 225 seconds +bob: parachain 100 is registered within 225 seconds + +# Ensure parachain progress +alice: parachain 100 block height is at least 10 within 250 seconds +bob: parachain 100 block height is at least 10 within 250 seconds diff --git a/polkadot/zombienet_tests/async_backing/002-async-backing-runtime-upgrade.toml b/polkadot/zombienet_tests/async_backing/002-async-backing-runtime-upgrade.toml new file mode 100644 index 0000000000000000000000000000000000000000..e61f7dd47ef6e09ed82173b21e58cd4445a8da28 --- /dev/null +++ b/polkadot/zombienet_tests/async_backing/002-async-backing-runtime-upgrade.toml @@ -0,0 +1,54 @@ +[settings] +timeout = 1000 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +default_command = "polkadot" + + [relaychain.default_resources] + limits = { memory = "4G", cpu = "2" } + requests = { memory = "2G", cpu = "1" } + + [[relaychain.nodes]] + name = "alice" + args = [ "-lparachain=debug,runtime=debug"] + + [[relaychain.nodes]] + name = "bob" + args = [ "-lparachain=debug,runtime=debug"] + + [[relaychain.nodes]] + name = "charlie" + image = "{{ZOMBIENET_INTEGRATION_TEST_SECONDARY_IMAGE}}" + args = [ "-lparachain=debug,runtime=debug"] + + [[relaychain.nodes]] + name = "dave" + image = "{{ZOMBIENET_INTEGRATION_TEST_SECONDARY_IMAGE}}" + args = [ "-lparachain=debug,runtime=debug"] + +[[parachains]] +id = 100 +addToGenesis = true + + [parachains.collator] + name = "collator02" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug"] + +[[parachains]] +id = 101 +addToGenesis = true + + [parachains.collator] + name = "collator02" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug"] + +[types.Header] +number = "u64" +parent_hash = "Hash" +post_state = "Hash" diff --git a/polkadot/zombienet_tests/async_backing/002-async-backing-runtime-upgrade.zndsl b/polkadot/zombienet_tests/async_backing/002-async-backing-runtime-upgrade.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..6213d1afb81e23ecd441cc566551461b0a802033 --- /dev/null +++ b/polkadot/zombienet_tests/async_backing/002-async-backing-runtime-upgrade.zndsl @@ -0,0 +1,34 @@ +Description: Async Backing Runtime Upgrade Test +Network: ./002-async-backing-runtime-upgrade.toml +Creds: config + +# General +alice: is up +bob: is up +charlie: is up +dave: is up + +# Check peers +alice: reports peers count is at least 3 within 20 seconds +bob: reports peers count is at least 3 within 20 seconds + +# Parachain registration +alice: parachain 100 is registered within 225 seconds +bob: parachain 100 is registered within 225 seconds +charlie: parachain 100 is registered within 225 seconds +dave: parachain 100 is registered within 225 seconds +alice: parachain 101 is registered within 225 seconds +bob: parachain 101 is registered within 225 seconds +charlie: parachain 101 is registered within 225 seconds +dave: parachain 101 is registered within 225 seconds + +# Ensure parachain progress +alice: parachain 100 block height is at least 10 within 250 seconds +bob: parachain 100 block height is at least 10 within 250 seconds + +# Runtime upgrade (according to previous runtime tests, avg. is 30s) +alice: run ../misc/0002-download-polkadot-from-pr.sh with "{{POLKADOT_PR_BIN_URL}}" within 40 seconds +bob: run ../misc/0002-download-polkadot-from-pr.sh with "{{POLKADOT_PR_BIN_URL}}" within 40 seconds + +# Bootstrap the runtime upgrade +sleep 30 seconds diff --git a/polkadot/zombienet_tests/async_backing/003-async-backing-collator-mix.toml b/polkadot/zombienet_tests/async_backing/003-async-backing-collator-mix.toml new file mode 100644 index 0000000000000000000000000000000000000000..4dca4d3d531268c45026a7da938b186334aee5de --- /dev/null +++ b/polkadot/zombienet_tests/async_backing/003-async-backing-collator-mix.toml @@ -0,0 +1,40 @@ +[settings] +timeout = 1000 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +default_command = "polkadot" + + [relaychain.default_resources] + limits = { memory = "4G", cpu = "2" } + requests = { memory = "2G", cpu = "1" } + + [[relaychain.nodes]] + name = "alice" + args = [ "-lparachain=debug"] + + [[relaychain.nodes]] + name = "bob" + image = "{{ZOMBIENET_INTEGRATION_TEST_SECONDARY_IMAGE}}" + args = [ "-lparachain=debug"] + +[[parachains]] +id = 100 + + [[parachains.collators]] + name = "collator01" + image = "docker.io/paritypr/colander:master" + command = "undying-collator" + args = ["-lparachain=debug"] + + [[parachains.collators]] + name = "collator02" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug"] + +[types.Header] +number = "u64" +parent_hash = "Hash" +post_state = "Hash" diff --git a/polkadot/zombienet_tests/async_backing/003-async-backing-collator-mix.zndsl b/polkadot/zombienet_tests/async_backing/003-async-backing-collator-mix.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..98436b0459cf80a4f7f494d7af9a6684da73cdf9 --- /dev/null +++ b/polkadot/zombienet_tests/async_backing/003-async-backing-collator-mix.zndsl @@ -0,0 +1,19 @@ +Description: Async Backing Collator Mix Test +Network: ./003-async-backing-collator-mix.toml +Creds: config + +# General +alice: is up +bob: is up + +# Check peers +alice: reports peers count is at least 3 within 20 seconds +bob: reports peers count is at least 3 within 20 seconds + +# Parachain registration +alice: parachain 100 is registered within 225 seconds +bob: parachain 100 is registered within 225 seconds + +# Ensure parachain progress +alice: parachain 100 block height is at least 10 within 250 seconds +bob: parachain 100 block height is at least 10 within 250 seconds diff --git a/polkadot/zombienet_tests/async_backing/README.md b/polkadot/zombienet_tests/async_backing/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9774ea3c25c96d434643d1e565a3e933fbc2412c --- /dev/null +++ b/polkadot/zombienet_tests/async_backing/README.md @@ -0,0 +1,9 @@ +# async-backing zombienet tests + +This directory contains zombienet tests made explicitly for the async-backing feature branch. + +## coverage + +- Network protocol upgrade deploying both master and async branch (compatibility). +- Runtime ugprade while running both master and async backing branch nodes. +- Async backing test with a mix of collators collating via async backing and sync backing. diff --git a/polkadot/zombienet_tests/functional/0001-parachains-pvf.toml b/polkadot/zombienet_tests/functional/0001-parachains-pvf.toml new file mode 100644 index 0000000000000000000000000000000000000000..9ae4d899e69024651580e446b96f457f1fdb885c --- /dev/null +++ b/polkadot/zombienet_tests/functional/0001-parachains-pvf.toml @@ -0,0 +1,136 @@ +[settings] +timeout = 1000 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +chain_spec_command = "polkadot build-spec --chain rococo-local --disable-default-bootnode" + +[relaychain.default_resources] +limits = { memory = "4G", cpu = "2" } +requests = { memory = "2G", cpu = "1" } + + [[relaychain.nodes]] + name = "alice" + args = [ "--alice", "-lparachain=debug,runtime=debug" ] + + [[relaychain.nodes]] + name = "bob" + args = [ "--bob", "-lparachain=debug,runtime=debug"] + + [[relaychain.nodes]] + name = "charlie" + args = [ "--charlie", "-lparachain=debug,runtime=debug" ] + + [[relaychain.nodes]] + name = "dave" + args = [ "--dave", "-lparachain=debug,runtime=debug"] + + [[relaychain.nodes]] + name = "ferdie" + args = [ "--ferdie", "-lparachain=debug,runtime=debug" ] + + [[relaychain.nodes]] + name = "eve" + args = [ "--eve", "-lparachain=debug,runtime=debug"] + + [[relaychain.nodes]] + name = "one" + args = [ "--one", "-lparachain=debug,runtime=debug" ] + + [[relaychain.nodes]] + name = "two" + args = [ "--two", "-lparachain=debug,runtime=debug"] + +[[parachains]] +id = 2000 +addToGenesis = true +genesis_state_generator = "undying-collator export-genesis-state --pov-size=100000 --pvf-complexity=1" + + [parachains.collator] + name = "collator01" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug", "--pov-size=100000", "--pvf-complexity=1", "--parachain-id=2000"] + +[[parachains]] +id = 2001 +addToGenesis = true +genesis_state_generator = "undying-collator export-genesis-state --pov-size=100000 --pvf-complexity=10" + + [parachains.collator] + name = "collator02" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug", "--pov-size=100000", "--parachain-id=2001", "--pvf-complexity=10"] + +[[parachains]] +id = 2002 +addToGenesis = true +genesis_state_generator = "undying-collator export-genesis-state --pov-size=100000 --pvf-complexity=100" + + [parachains.collator] + name = "collator03" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug", "--pov-size=100000", "--parachain-id=2002", "--pvf-complexity=100"] + +[[parachains]] +id = 2003 +addToGenesis = true +genesis_state_generator = "undying-collator export-genesis-state --pov-size=20000 --pvf-complexity=300" + + [parachains.collator] + name = "collator04" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug", "--pov-size=20000", "--parachain-id=2003", "--pvf-complexity=300"] + +[[parachains]] +id = 2004 +addToGenesis = true +genesis_state_generator = "undying-collator export-genesis-state --pov-size=100000 --pvf-complexity=300" + + [parachains.collator] + name = "collator05" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug", "--pov-size=100000", "--parachain-id=2004", "--pvf-complexity=300"] + +[[parachains]] +id = 2005 +addToGenesis = true +genesis_state_generator = "undying-collator export-genesis-state --pov-size=20000 --pvf-complexity=400" + + [parachains.collator] + name = "collator06" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug", "--pov-size=20000", "--pvf-complexity=400", "--parachain-id=2005"] + +[[parachains]] +id = 2006 +addToGenesis = true +genesis_state_generator = "undying-collator export-genesis-state --pov-size=100000 --pvf-complexity=300" + + [parachains.collator] + name = "collator07" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug", "--pov-size=100000", "--pvf-complexity=300", "--parachain-id=2006"] + +[[parachains]] +id = 2007 +addToGenesis = true +genesis_state_generator = "undying-collator export-genesis-state --pov-size=100000 --pvf-complexity=300" + + [parachains.collator] + name = "collator08" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug", "--pov-size=100000", "--pvf-complexity=300", "--parachain-id=2007"] + +[types.Header] +number = "u64" +parent_hash = "Hash" +post_state = "Hash" \ No newline at end of file diff --git a/polkadot/zombienet_tests/functional/0001-parachains-pvf.zndsl b/polkadot/zombienet_tests/functional/0001-parachains-pvf.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..46bb8bcdf72b103a9b72be9a68ff90134a54466f --- /dev/null +++ b/polkadot/zombienet_tests/functional/0001-parachains-pvf.zndsl @@ -0,0 +1,82 @@ +Description: PVF preparation & execution time +Network: ./0001-parachains-pvf.toml +Creds: config + +# Check authority status. +alice: reports node_roles is 4 +bob: reports node_roles is 4 +charlie: reports node_roles is 4 +dave: reports node_roles is 4 +eve: reports node_roles is 4 +ferdie: reports node_roles is 4 +one: reports node_roles is 4 +two: reports node_roles is 4 + +# Ensure parachains are registered. +alice: parachain 2000 is registered within 60 seconds +bob: parachain 2001 is registered within 60 seconds +charlie: parachain 2002 is registered within 60 seconds +dave: parachain 2003 is registered within 60 seconds +ferdie: parachain 2004 is registered within 60 seconds +eve: parachain 2005 is registered within 60 seconds +one: parachain 2006 is registered within 60 seconds +two: parachain 2007 is registered within 60 seconds + +# Ensure parachains made progress. +alice: parachain 2000 block height is at least 10 within 300 seconds +alice: parachain 2001 block height is at least 10 within 300 seconds +alice: parachain 2002 block height is at least 10 within 300 seconds +alice: parachain 2003 block height is at least 10 within 300 seconds +alice: parachain 2004 block height is at least 10 within 300 seconds +alice: parachain 2005 block height is at least 10 within 300 seconds +alice: parachain 2006 block height is at least 10 within 300 seconds +alice: parachain 2007 block height is at least 10 within 300 seconds + +# Check preparation time is under 10s. +# Check all buckets <= 10. +alice: reports histogram polkadot_pvf_preparation_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2", "3", "10"] within 10 seconds +bob: reports histogram polkadot_pvf_preparation_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2", "3", "10"] within 10 seconds +charlie: reports histogram polkadot_pvf_preparation_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2", "3", "10"] within 10 seconds +dave: reports histogram polkadot_pvf_preparation_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2", "3", "10"] within 10 seconds +ferdie: reports histogram polkadot_pvf_preparation_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2", "3", "10"] within 10 seconds +eve: reports histogram polkadot_pvf_preparation_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2", "3", "10"] within 10 seconds +one: reports histogram polkadot_pvf_preparation_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2", "3", "10"] within 10 seconds +two: reports histogram polkadot_pvf_preparation_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2", "3", "10"] within 10 seconds + +# Check all buckets >= 20. +alice: reports histogram polkadot_pvf_preparation_time has 0 samples in buckets ["20", "30", "60", "120", "+Inf"] within 10 seconds +bob: reports histogram polkadot_pvf_preparation_time has 0 samples in buckets ["20", "30", "60", "120", "+Inf"] within 10 seconds +charlie: reports histogram polkadot_pvf_preparation_time has 0 samples in buckets ["20", "30", "60", "120", "+Inf"] within 10 seconds +dave: reports histogram polkadot_pvf_preparation_time has 0 samples in buckets ["20", "30", "60", "120", "+Inf"] within 10 seconds +ferdie: reports histogram polkadot_pvf_preparation_time has 0 samples in buckets ["20", "30", "60", "120", "+Inf"] within 10 seconds +eve: reports histogram polkadot_pvf_preparation_time has 0 samples in buckets ["20", "30", "60", "120", "+Inf"] within 10 seconds +one: reports histogram polkadot_pvf_preparation_time has 0 samples in buckets ["20", "30", "60", "120", "+Inf"] within 10 seconds +two: reports histogram polkadot_pvf_preparation_time has 0 samples in buckets ["20", "30", "60", "120", "+Inf"] within 10 seconds + +# Check execution time. +# There are two different timeout conditions: BACKING_EXECUTION_TIMEOUT(2s) and +# APPROVAL_EXECUTION_TIMEOUT(6s). Currently these are not differentiated by metrics +# because the metrics are defined in `polkadot-node-core-pvf` which is a level below +# the relevant subsystems. +# That being said, we will take the simplifying assumption of testing only the +# 2s timeout. +# We do this check by ensuring all executions fall into bucket le="2" or lower. +# First, check if we have at least 1 sample, but we should have many more. +alice: reports histogram polkadot_pvf_execution_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2"] within 10 seconds +bob: reports histogram polkadot_pvf_execution_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2"] within 10 seconds +charlie: reports histogram polkadot_pvf_execution_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2"] within 10 seconds +dave: reports histogram polkadot_pvf_execution_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2"] within 10 seconds +ferdie: reports histogram polkadot_pvf_execution_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2"] within 10 seconds +eve: reports histogram polkadot_pvf_execution_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2"] within 10 seconds +one: reports histogram polkadot_pvf_execution_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2"] within 10 seconds +two: reports histogram polkadot_pvf_execution_time has at least 1 samples in buckets ["0.1", "0.5", "1", "2"] within 10 seconds + +# Check if we have no samples > 2s. +alice: reports histogram polkadot_pvf_execution_time has 0 samples in buckets ["3", "4", "5", "6", "+Inf"] within 10 seconds +bob: reports histogram polkadot_pvf_execution_time has 0 samples in buckets ["3", "4", "5", "6", "+Inf"] within 10 seconds +charlie: reports histogram polkadot_pvf_execution_time has 0 samples in buckets ["3", "4", "5", "6", "+Inf"] within 10 seconds +dave: reports histogram polkadot_pvf_execution_time has 0 samples in buckets ["3", "4", "5", "6", "+Inf"] within 10 seconds +ferdie: reports histogram polkadot_pvf_execution_time has 0 samples in buckets ["3", "4", "5", "6", "+Inf"] within 10 seconds +eve: reports histogram polkadot_pvf_execution_time has 0 samples in buckets ["3", "4", "5", "6", "+Inf"] within 10 seconds +one: reports histogram polkadot_pvf_execution_time has 0 samples in buckets ["3", "4", "5", "6", "+Inf"] within 10 seconds +two: reports histogram polkadot_pvf_execution_time has 0 samples in buckets ["3", "4", "5", "6", "+Inf"] within 10 seconds diff --git a/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml b/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml new file mode 100644 index 0000000000000000000000000000000000000000..a0a87d60d4e3ec381686a8dd02dbb605209dd2af --- /dev/null +++ b/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml @@ -0,0 +1,71 @@ +[settings] +timeout = 1000 + +[relaychain.genesis.runtime.runtime_genesis_config.configuration.config] + max_validators_per_core = 5 + needed_approvals = 8 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +chain_spec_command = "polkadot build-spec --chain rococo-local --disable-default-bootnode" +default_command = "polkadot" + +[relaychain.default_resources] +limits = { memory = "4G", cpu = "2" } +requests = { memory = "2G", cpu = "1" } + + [[relaychain.nodes]] + image = "{{MALUS_IMAGE}}" + name = "alice" + command = "malus dispute-ancestor --fake-validation approval-invalid" + args = [ "--alice", " -lparachain=debug,MALUS=trace" ] + + [[relaychain.nodes]] + image = "{{MALUS_IMAGE}}" + name = "bob" + command = "malus dispute-ancestor --fake-validation approval-invalid" + args = [ "--bob", "-lparachain=debug,MALUS=trace"] + + [[relaychain.nodes]] + name = "charlie" + args = [ "--charlie", "-lparachain=debug" ] + + [[relaychain.nodes]] + name = "dave" + args = [ "--dave", "-lparachain=debug"] + + [[relaychain.nodes]] + name = "ferdie" + args = [ "--ferdie", "-lparachain=debug" ] + + [[relaychain.nodes]] + name = "eve" + args = [ "--eve", "-lparachain=debug"] + + [[relaychain.nodes]] + name = "one" + args = [ "--one", "-lparachain=debug" ] + + [[relaychain.nodes]] + name = "two" + args = [ "--two", "-lparachain=debug"] + +{% for id in range(2000,2004) %} +[[parachains]] +id = {{id}} +addToGenesis = true +genesis_state_generator = "undying-collator export-genesis-state --pov-size={{25000*(id-1999)}} --pvf-complexity={{id - 1999}}" + + [parachains.collator] + image = "{{COL_IMAGE}}" + name = "collator" + command = "undying-collator" + args = ["-lparachain=debug", "--pov-size={{25000*(id-1999)}}", "--parachain-id={{id}}", "--pvf-complexity={{id - 1999}}"] + +{% endfor %} + +[types.Header] +number = "u64" +parent_hash = "Hash" +post_state = "Hash" diff --git a/polkadot/zombienet_tests/functional/0002-parachains-disputes.zndsl b/polkadot/zombienet_tests/functional/0002-parachains-disputes.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..b7d797a496bbb16920de31ae6f6b8e800dc2fa9e --- /dev/null +++ b/polkadot/zombienet_tests/functional/0002-parachains-disputes.zndsl @@ -0,0 +1,58 @@ +Description: Disputes initiation, conclusion and lag +Network: ./0002-parachains-disputes.toml +Creds: config + +# Check authority status and peers. +alice: reports node_roles is 4 +bob: reports node_roles is 4 +charlie: reports node_roles is 4 +dave: reports node_roles is 4 +eve: reports node_roles is 4 +ferdie: reports node_roles is 4 +one: reports node_roles is 4 +two: reports node_roles is 4 + +# Ensure parachains are registered. +alice: parachain 2000 is registered within 30 seconds +bob: parachain 2001 is registered within 30 seconds +charlie: parachain 2002 is registered within 30 seconds +dave: parachain 2003 is registered within 30 seconds + +# Ensure parachains made progress. +alice: parachain 2000 block height is at least 10 within 200 seconds +alice: parachain 2001 block height is at least 10 within 200 seconds +alice: parachain 2002 block height is at least 10 within 200 seconds +alice: parachain 2003 block height is at least 10 within 200 seconds + +# Check if disputes are initiated and concluded. +# TODO: check if disputes are concluded faster than initiated. +eve: reports polkadot_parachain_candidate_disputes_total is at least 10 within 15 seconds +eve: reports polkadot_parachain_candidate_dispute_concluded{validity="valid"} is at least 10 within 15 seconds +eve: reports polkadot_parachain_candidate_dispute_concluded{validity="invalid"} is 0 within 15 seconds + +# As of , we don't slash on disputes +# with `valid` outcome, so there is no offence reported. +# alice: system event contains "There is an offence reported" within 60 seconds + +# Check lag - approval +alice: reports polkadot_parachain_approval_checking_finality_lag is 0 +bob: reports polkadot_parachain_approval_checking_finality_lag is 0 +charlie: reports polkadot_parachain_approval_checking_finality_lag is 0 +dave: reports polkadot_parachain_approval_checking_finality_lag is 0 +ferdie: reports polkadot_parachain_approval_checking_finality_lag is 0 +eve: reports polkadot_parachain_approval_checking_finality_lag is 0 +one: reports polkadot_parachain_approval_checking_finality_lag is 0 +two: reports polkadot_parachain_approval_checking_finality_lag is 0 + +# Check lag - dispute conclusion +alice: reports polkadot_parachain_disputes_finality_lag is 0 +bob: reports polkadot_parachain_disputes_finality_lag is 0 +charlie: reports polkadot_parachain_disputes_finality_lag is 0 +dave: reports polkadot_parachain_disputes_finality_lag is 0 +ferdie: reports polkadot_parachain_disputes_finality_lag is 0 +eve: reports polkadot_parachain_disputes_finality_lag is 0 +one: reports polkadot_parachain_disputes_finality_lag is 0 +two: reports polkadot_parachain_disputes_finality_lag is 0 + +# Check participating in the losing side of a dispute logged +alice: log line contains "Voted against a candidate that was concluded valid." within 180 seconds diff --git a/polkadot/zombienet_tests/functional/0003-beefy-and-mmr.toml b/polkadot/zombienet_tests/functional/0003-beefy-and-mmr.toml new file mode 100644 index 0000000000000000000000000000000000000000..a8d97bc30f85e4a91d406b0115ea37afed131e11 --- /dev/null +++ b/polkadot/zombienet_tests/functional/0003-beefy-and-mmr.toml @@ -0,0 +1,16 @@ +[settings] +timeout = 1000 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +command = "polkadot" + +[[relaychain.node_groups]] +name = "validator" +count = 3 +args = ["--log=beefy=debug", "--enable-offchain-indexing=true"] + +[[relaychain.nodes]] +name = "validator-unstable" +args = ["--log=beefy=debug", "--enable-offchain-indexing=true"] diff --git a/polkadot/zombienet_tests/functional/0003-beefy-and-mmr.zndsl b/polkadot/zombienet_tests/functional/0003-beefy-and-mmr.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..8300ef051f09a8903b2469b3f36330c729c66125 --- /dev/null +++ b/polkadot/zombienet_tests/functional/0003-beefy-and-mmr.zndsl @@ -0,0 +1,39 @@ +Description: Test BEEFY voting and finality, test MMR proofs. Assumes Rococo sessions of 1 minute. +Network: ./0003-beefy-and-mmr.toml +Creds: config + +# Check authority status. +validator: reports node_roles is 4 +validator-unstable: reports node_roles is 4 + +# BEEFY sanity checks. +validator: reports substrate_beefy_validator_set_id is 0 +validator-unstable: reports substrate_beefy_validator_set_id is 0 + +# Verify voting happens and 1st mandatory block is finalized within 1st session. +validator: reports substrate_beefy_best_block is at least 1 within 60 seconds +validator-unstable: reports substrate_beefy_best_block is at least 1 within 60 seconds + +# Pause validator-unstable and test chain is making progress without it. +validator-unstable: pause + +# Verify validator sets get changed on new sessions. +validator: reports substrate_beefy_validator_set_id is at least 1 within 70 seconds +# Check next session too. +validator: reports substrate_beefy_validator_set_id is at least 2 within 130 seconds + +# Verify voting happens and blocks are being finalized for new sessions too: +# since we verified we're at least in the 3rd session, verify BEEFY finalized mandatory #21. +validator: reports substrate_beefy_best_block is at least 21 within 130 seconds + +# Custom JS to test BEEFY RPCs. +validator-0: js-script ./0003-beefy-finalized-heads.js with "validator-0,validator-1,validator-2" return is 1 within 5 seconds + +# Custom JS to test MMR RPCs. +validator: js-script ./0003-mmr-leaves.js with "21" return is 1 within 5 seconds +validator: js-script ./0003-mmr-generate-and-verify-proof.js with "validator-0,validator-1,validator-2" return is 1 within 5 seconds + +# Resume validator-unstable and verify it imports all BEEFY justification and catches up. +validator-unstable: resume +validator-unstable: reports substrate_beefy_validator_set_id is at least 2 within 30 seconds +validator-unstable: reports substrate_beefy_best_block is at least 21 within 30 seconds diff --git a/polkadot/zombienet_tests/functional/0003-beefy-finalized-heads.js b/polkadot/zombienet_tests/functional/0003-beefy-finalized-heads.js new file mode 100644 index 0000000000000000000000000000000000000000..9696a540a18ccb902b88a78abf035e81b76d80e7 --- /dev/null +++ b/polkadot/zombienet_tests/functional/0003-beefy-finalized-heads.js @@ -0,0 +1,35 @@ +const common = require('./0003-common.js'); + +async function run(_, networkInfo, nodeNames) { + const apis = await common.getApis(networkInfo, nodeNames); + + const finalizedHeads = await Promise.all( + Object.entries(apis).map(async ([nodeName, api]) => { + const finalizedHead = await api.rpc.beefy.getFinalizedHead(); + return { nodeName, finalizedHead, finalizedHeight: await api.rpc.chain.getHeader(finalizedHead).then((header) => header.number) }; + }) + ); + + // select the node with the highest finalized height + const highestFinalizedHeight = finalizedHeads.reduce( + (acc, { nodeName, finalizedHeight }) => + finalizedHeight >= acc.finalizedHeight + ? { nodeName, finalizedHeight } + : acc, + { nodeName: 'validator', finalizedHeight: 0 } + ); + + // get all block hashes up until the highest finalized height + const blockHashes = []; + for (let blockNumber = 0; blockNumber <= highestFinalizedHeight.finalizedHeight; blockNumber++) { + const blockHash = await apis[highestFinalizedHeight.nodeName].rpc.chain.getBlockHash(blockNumber); + blockHashes.push(blockHash); + } + + // verify that height(finalized_head) is at least as high as the substrate_beefy_best_block test already verified + return finalizedHeads.every(({ finalizedHead, finalizedHeight }) => + finalizedHeight >= 21 && finalizedHead.toHex() === blockHashes[finalizedHeight].toHex() + ) +} + +module.exports = { run }; diff --git a/polkadot/zombienet_tests/functional/0003-common.js b/polkadot/zombienet_tests/functional/0003-common.js new file mode 100644 index 0000000000000000000000000000000000000000..743828ec6b9e8837129d2aac77572e3acfbb7047 --- /dev/null +++ b/polkadot/zombienet_tests/functional/0003-common.js @@ -0,0 +1,16 @@ +async function getApis(networkInfo, nodeNames) { + const connectionPromises = nodeNames.map(async (nodeName) => { + const { wsUri, userDefinedTypes } = networkInfo.nodesByName[nodeName]; + const connection = await zombie.connect(wsUri, userDefinedTypes); + return { nodeName, connection }; + }); + + const connections = await Promise.all(connectionPromises); + + return connections.reduce((map, { nodeName, connection }) => { + map[nodeName] = connection; + return map; + }, {}); +} + +module.exports = { getApis }; diff --git a/polkadot/zombienet_tests/functional/0003-mmr-generate-and-verify-proof.js b/polkadot/zombienet_tests/functional/0003-mmr-generate-and-verify-proof.js new file mode 100644 index 0000000000000000000000000000000000000000..6583173e40c38a71d4c0091b10814ff72593dd15 --- /dev/null +++ b/polkadot/zombienet_tests/functional/0003-mmr-generate-and-verify-proof.js @@ -0,0 +1,26 @@ +const common = require('./0003-common.js'); + +async function run(nodeName, networkInfo, nodeNames) { + const apis = await common.getApis(networkInfo, nodeNames); + + const proof = await apis[nodeName].rpc.mmr.generateProof([1, 9, 20]); + + const root = await apis[nodeName].rpc.mmr.root() + + const proofVerifications = await Promise.all( + Object.values(apis).map(async (api) => { + return api.rpc.mmr.verifyProof(proof); + }) + ); + + const proofVerificationsStateless = await Promise.all( + Object.values(apis).map(async (api) => { + return api.rpc.mmr.verifyProofStateless(root, proof); + }) + ); + + // check that all nodes accepted the proof + return proofVerifications.every((proofVerification) => proofVerification) && proofVerificationsStateless.every((proofVerification) => proofVerification) +} + +module.exports = { run }; diff --git a/polkadot/zombienet_tests/functional/0003-mmr-leaves.js b/polkadot/zombienet_tests/functional/0003-mmr-leaves.js new file mode 100644 index 0000000000000000000000000000000000000000..df58194c5769d8037ec3166cc017427e2f3c3768 --- /dev/null +++ b/polkadot/zombienet_tests/functional/0003-mmr-leaves.js @@ -0,0 +1,9 @@ +async function run(nodeName, networkInfo, args) { + const { wsUri, userDefinedTypes } = networkInfo.nodesByName[nodeName]; + const api = await zombie.connect(wsUri, userDefinedTypes); + + const mmrLeaves = await api.query.mmr.numberOfLeaves(); + return mmrLeaves.toNumber() >= args[0] +} + +module.exports = { run }; diff --git a/polkadot/zombienet_tests/functional/0003-parachains-garbage-candidate.toml b/polkadot/zombienet_tests/functional/0003-parachains-garbage-candidate.toml new file mode 100644 index 0000000000000000000000000000000000000000..7c4f5a9f1bcab8550755bfefadd1a1c425b4ac06 --- /dev/null +++ b/polkadot/zombienet_tests/functional/0003-parachains-garbage-candidate.toml @@ -0,0 +1,46 @@ +[settings] +timeout = 1000 +bootnode = true + +[relaychain.genesis.runtime.runtime_genesis_config.configuration.config] + max_validators_per_core = 1 + needed_approvals = 2 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +chain_spec_command = "polkadot build-spec --chain rococo-local --disable-default-bootnode" +default_command = "polkadot" + +[relaychain.default_resources] +limits = { memory = "4G", cpu = "2" } +requests = { memory = "2G", cpu = "1" } + + [[relaychain.node_groups]] + name = "honest-validator" + count = 3 + args = ["-lparachain=debug,runtime=debug"] + + [[relaychain.node_groups]] + image = "{{MALUS_IMAGE}}" + name = "malus-validator" + command = "malus suggest-garbage-candidate" + args = ["-lparachain=debug,MALUS=trace"] + count = 1 + +{% for id in range(2000,2003) %} +[[parachains]] +id = {{id}} +addToGenesis = true +genesis_state_generator = "undying-collator export-genesis-state --pov-size={{10000*(id-1999)}} --pvf-complexity={{id - 1999}}" + [parachains.collator] + image = "{{COL_IMAGE}}" + name = "collator" + command = "undying-collator" + args = ["-lparachain=debug", "--pov-size={{10000*(id-1999)}}", "--parachain-id={{id}}", "--pvf-complexity={{id - 1999}}"] +{% endfor %} + +[types.Header] +number = "u64" +parent_hash = "Hash" +post_state = "Hash" diff --git a/polkadot/zombienet_tests/functional/0003-parachains-garbage-candidate.zndsl b/polkadot/zombienet_tests/functional/0003-parachains-garbage-candidate.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..c4fd3ee7c55a851770af9650f1148a27b2bee6d4 --- /dev/null +++ b/polkadot/zombienet_tests/functional/0003-parachains-garbage-candidate.zndsl @@ -0,0 +1,44 @@ +Description: Test dispute finality lag when 1/3 of parachain validators always attempt to include an invalid block +Network: ./0003-parachains-garbage-candidate.toml +Creds: config + +# Check authority status. +honest-validator-0: reports node_roles is 4 +honest-validator-1: reports node_roles is 4 +honest-validator-2: reports node_roles is 4 +malus-validator-0: reports node_roles is 4 + +# Parachains should be making progress even if we have up to 1/3 malicious validators. +honest-validator-0: parachain 2000 block height is at least 2 within 240 seconds +honest-validator-1: parachain 2001 block height is at least 2 within 180 seconds +honest-validator-2: parachain 2002 block height is at least 2 within 180 seconds + +# Check there is an offence report after dispute conclusion +honest-validator-0: system event contains "There is an offence reported" within 180 seconds +honest-validator-1: system event contains "There is an offence reported" within 180 seconds +honest-validator-2: system event contains "There is an offence reported" within 180 seconds + +# Check for chain reversion after dispute conclusion. +honest-validator-0: log line contains "reverted due to a bad parachain block" within 180 seconds +honest-validator-1: log line contains "reverted due to a bad parachain block" within 180 seconds +honest-validator-2: log line contains "reverted due to a bad parachain block" within 180 seconds + +# Check if disputes are concluded in less than 2 blocks. +honest-validator-0: reports polkadot_parachain_disputes_finality_lag is lower than 2 +honest-validator-1: reports polkadot_parachain_disputes_finality_lag is lower than 2 +honest-validator-2: reports polkadot_parachain_disputes_finality_lag is lower than 2 + +# Allow more time for malicious validator activity. +sleep 30 seconds + +# Check that garbage parachain blocks included by malicious validators are being disputed. +honest-validator-0: reports polkadot_parachain_candidate_disputes_total is at least 2 within 15 seconds +honest-validator-1: reports polkadot_parachain_candidate_disputes_total is at least 2 within 15 seconds +honest-validator-2: reports polkadot_parachain_candidate_disputes_total is at least 2 within 15 seconds + +# Disputes should always end as "invalid" +honest-validator-0: reports polkadot_parachain_candidate_dispute_concluded{validity="invalid"} is at least 2 within 15 seconds +honest-validator-1: reports polkadot_parachain_candidate_dispute_concluded{validity="valid"} is 0 within 15 seconds + +# Check participating in the losing side of a dispute logged +malus-validator: log line contains "Voted for a candidate that was concluded invalid." within 180 seconds diff --git a/polkadot/zombienet_tests/functional/0004-parachains-disputes-past-session.toml b/polkadot/zombienet_tests/functional/0004-parachains-disputes-past-session.toml new file mode 100644 index 0000000000000000000000000000000000000000..3b05c91e134333a50cd1773e7924ac2442ae332c --- /dev/null +++ b/polkadot/zombienet_tests/functional/0004-parachains-disputes-past-session.toml @@ -0,0 +1,45 @@ +[settings] +timeout = 1000 +bootnode = true + +[relaychain.genesis.runtime.configuration.config] + max_validators_per_core = 1 + needed_approvals = 3 + group_rotation_frequency = 4 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "westend-local" # using westend-local to enable slashing +default_command = "polkadot" + +[relaychain.default_resources] +limits = { memory = "4G", cpu = "2" } +requests = { memory = "2G", cpu = "1" } + + [[relaychain.nodes]] + name = "alice" + invulnerable = true # it will go offline, we don't want to disable it + args = ["-lparachain=debug,runtime=debug"] + + [[relaychain.node_groups]] + name = "honest-validator" + count = 2 + args = ["-lruntime=debug,sync=trace"] + + [[relaychain.node_groups]] + image = "{{MALUS_IMAGE}}" + name = "malus-validator" + command = "malus suggest-garbage-candidate" + args = ["-lMALUS=trace"] + count = 1 + +[[parachains]] +id = 1000 +cumulus_based = true + + [parachains.collator] + name = "collator" + command = "polkadot-parachain" + image = "docker.io/parity/polkadot-parachain:latest" + # image = "{{COL_IMAGE}}" + args = ["-lparachain=debug"] diff --git a/polkadot/zombienet_tests/functional/0004-parachains-disputes-past-session.zndsl b/polkadot/zombienet_tests/functional/0004-parachains-disputes-past-session.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..8e792f974fe383aa1e34481e6ba4e8d90ca9ecb6 --- /dev/null +++ b/polkadot/zombienet_tests/functional/0004-parachains-disputes-past-session.zndsl @@ -0,0 +1,37 @@ +Description: Past-session dispute slashing +Network: ./0004-parachains-disputes-past-session.toml +Creds: config + +alice: reports node_roles is 4 + +# pause alice so that disputes don't conclude +alice: pause + +# Ensure parachain is registered. +honest-validator-0: parachain 1000 is registered within 100 seconds + +# Ensure parachain made progress. +honest-validator-0: parachain 1000 block height is at least 1 within 300 seconds + +# There should be disputes initiated +honest-validator-0: reports polkadot_parachain_candidate_disputes_total is at least 2 within 200 seconds + +# Stop issuing disputes +malus-validator-0: pause + +# wait for the next session +sleep 120 seconds + +# But should not resolve +honest-validator-0: reports block height minus finalised block is at least 10 within 100 seconds + +# Now resume alice +alice: resume + +# Disputes should start concluding now +honest-validator-0: reports polkadot_parachain_candidate_dispute_concluded{validity="invalid"} is at least 1 within 200 seconds +# Disputes should always end as "invalid" +honest-validator-0: reports polkadot_parachain_candidate_dispute_concluded{validity="valid"} is 0 + +# Check an unsigned extrinsic is submitted +honest-validator: log line contains "Successfully reported pending slash" within 180 seconds diff --git a/polkadot/zombienet_tests/misc/0001-check_paritydb.sh b/polkadot/zombienet_tests/misc/0001-check_paritydb.sh new file mode 100644 index 0000000000000000000000000000000000000000..127efe592dbd5088a44d0b0d1d1aa7f1142f7c0f --- /dev/null +++ b/polkadot/zombienet_tests/misc/0001-check_paritydb.sh @@ -0,0 +1 @@ +ls /data/chains/rococo_local_testnet/paritydb/full 2>/dev/null diff --git a/polkadot/zombienet_tests/misc/0001-paritydb.toml b/polkadot/zombienet_tests/misc/0001-paritydb.toml new file mode 100644 index 0000000000000000000000000000000000000000..38fa56898196ae21934e786a26cb6265ed915282 --- /dev/null +++ b/polkadot/zombienet_tests/misc/0001-paritydb.toml @@ -0,0 +1,40 @@ +[settings] +timeout = 1000 +bootnode = true + +[relaychain.genesis.runtime.runtime_genesis_config.configuration.config] + max_validators_per_core = 1 + needed_approvals = 3 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +chain_spec_command = "polkadot build-spec --chain rococo-local" +default_command = "polkadot" + +[relaychain.default_resources] +limits = { memory = "4G", cpu = "2" } +requests = { memory = "2G", cpu = "1" } + + [[relaychain.node_groups]] + name = "validator" + count = 10 + args = ["-lparachain=debug", "--db=paritydb"] + +{% for id in range(2000,2010) %} +[[parachains]] +id = {{id}} +addToGenesis = true +genesis_state_generator = "undying-collator export-genesis-state --pov-size={{10000*(id-1999)}} --pvf-complexity={{id - 1999}}" + [parachains.collator] + name = "collator" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug", "--pov-size={{10000*(id-1999)}}", "--parachain-id={{id}}", "--pvf-complexity={{id - 1999}}"] + +{% endfor %} + +[types.Header] +number = "u64" +parent_hash = "Hash" +post_state = "Hash" diff --git a/polkadot/zombienet_tests/misc/0001-paritydb.zndsl b/polkadot/zombienet_tests/misc/0001-paritydb.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..4a22311de764c1936be2f5812ffb32a7471b5f8e --- /dev/null +++ b/polkadot/zombienet_tests/misc/0001-paritydb.zndsl @@ -0,0 +1,68 @@ +Description: Check that paritydb works without affecting finality lag and block production. +Network: ./0001-paritydb.toml +Creds: config + +# Check if we are using ParityDB. +validator: log line contains "Database: ParityDb" +validator: run ./0001-check_paritydb.sh within 60 seconds + +# Check authority status and peers. +validator-0: reports node_roles is 4 +validator-1: reports node_roles is 4 +validator-2: reports node_roles is 4 +validator-3: reports node_roles is 4 +validator-4: reports node_roles is 4 +validator-5: reports node_roles is 4 +validator-6: reports node_roles is 4 +validator-7: reports node_roles is 4 +validator-8: reports node_roles is 4 +validator-9: reports node_roles is 4 + +# Ensure parachains are registered. +validator-0: parachain 2000 is registered within 20 seconds +validator-0: parachain 2001 is registered +validator-0: parachain 2002 is registered +validator-0: parachain 2003 is registered +validator-0: parachain 2004 is registered +validator-0: parachain 2005 is registered +validator-0: parachain 2006 is registered +validator-0: parachain 2007 is registered +validator-0: parachain 2008 is registered +validator-0: parachain 2009 is registered + +# Ensure parachains made some progress. +validator-0: parachain 2000 block height is at least 3 within 30 seconds +validator-0: parachain 2001 block height is at least 3 within 30 seconds +validator-0: parachain 2002 block height is at least 3 within 30 seconds +validator-0: parachain 2003 block height is at least 3 within 30 seconds +validator-0: parachain 2004 block height is at least 3 within 30 seconds +validator-0: parachain 2005 block height is at least 3 within 30 seconds +validator-0: parachain 2006 block height is at least 3 within 30 seconds +validator-0: parachain 2007 block height is at least 3 within 30 seconds +validator-0: parachain 2008 block height is at least 3 within 30 seconds +validator-0: parachain 2009 block height is at least 3 within 30 seconds + +# Check lag - approval +validator-0: reports polkadot_parachain_approval_checking_finality_lag is 0 +validator-1: reports polkadot_parachain_approval_checking_finality_lag is 0 +validator-2: reports polkadot_parachain_approval_checking_finality_lag is 0 +validator-3: reports polkadot_parachain_approval_checking_finality_lag is 0 +validator-4: reports polkadot_parachain_approval_checking_finality_lag is 0 +validator-5: reports polkadot_parachain_approval_checking_finality_lag is 0 +validator-6: reports polkadot_parachain_approval_checking_finality_lag is 0 +validator-7: reports polkadot_parachain_approval_checking_finality_lag is 0 +validator-8: reports polkadot_parachain_approval_checking_finality_lag is 0 +validator-9: reports polkadot_parachain_approval_checking_finality_lag is 0 + +# Check lag - dispute conclusion +validator-0: reports polkadot_parachain_candidate_disputes_total is 0 +validator-1: reports polkadot_parachain_candidate_disputes_total is 0 +validator-2: reports polkadot_parachain_candidate_disputes_total is 0 +validator-3: reports polkadot_parachain_candidate_disputes_total is 0 +validator-4: reports polkadot_parachain_candidate_disputes_total is 0 +validator-5: reports polkadot_parachain_candidate_disputes_total is 0 +validator-6: reports polkadot_parachain_candidate_disputes_total is 0 +validator-7: reports polkadot_parachain_candidate_disputes_total is 0 +validator-8: reports polkadot_parachain_candidate_disputes_total is 0 +validator-9: reports polkadot_parachain_candidate_disputes_total is 0 + diff --git a/polkadot/zombienet_tests/misc/0002-download-polkadot-from-pr.sh b/polkadot/zombienet_tests/misc/0002-download-polkadot-from-pr.sh new file mode 100644 index 0000000000000000000000000000000000000000..0d4b2807579564f0fcbad3e43f400f8a68f082fc --- /dev/null +++ b/polkadot/zombienet_tests/misc/0002-download-polkadot-from-pr.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -euxo pipefail + +echo $@ + +CFG_DIR=/cfg + +# add CFG_DIR as first `looking dir` to allow to overrides commands. +mkdir -p $CFG_DIR +export PATH=$CFG_DIR:$PATH + +cd $CFG_DIR +# see 0002-upgrade-node.zndsl to view the args. +curl -L -O $1/polkadot +curl -L -O $1/polkadot-prepare-worker +curl -L -O $1/polkadot-execute-worker +chmod +x $CFG_DIR/polkadot $CFG_DIR/polkadot-prepare-worker $CFG_DIR/polkadot-execute-worker +echo $(polkadot --version) diff --git a/polkadot/zombienet_tests/misc/0002-upgrade-node.toml b/polkadot/zombienet_tests/misc/0002-upgrade-node.toml new file mode 100644 index 0000000000000000000000000000000000000000..b6fff6c8cb834ce97724cfd11df3ec761cac1f3e --- /dev/null +++ b/polkadot/zombienet_tests/misc/0002-upgrade-node.toml @@ -0,0 +1,51 @@ +[settings] +timeout = 1000 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" + + + [[relaychain.nodes]] + name = "alice" + args = [ "-lparachain=debug,runtime=debug", "--db paritydb" ] + substrate_cli_args_version = 1 + + [[relaychain.nodes]] + name = "bob" + args = [ "-lparachain=debug,runtime=debug", "--db rocksdb" ] + substrate_cli_args_version = 1 + + [[relaychain.nodes]] + name = "charlie" + args = [ "-lparachain=debug,runtime=debug", "--db paritydb" ] + + [[relaychain.nodes]] + name = "dave" + args = [ "-lparachain=debug,runtime=debug", "--db rocksdb" ] + + +[[parachains]] +id = 2000 +addToGenesis = true + + [parachains.collator] + name = "collator01" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug"] + +[[parachains]] +id = 2001 +addToGenesis = true + + [parachains.collator] + name = "collator02" + image = "{{COL_IMAGE}}" + command = "undying-collator" + args = ["-lparachain=debug"] + +[types.Header] +number = "u64" +parent_hash = "Hash" +post_state = "Hash" diff --git a/polkadot/zombienet_tests/misc/0002-upgrade-node.zndsl b/polkadot/zombienet_tests/misc/0002-upgrade-node.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..fdf16b7286c910bef0d2052a8a1f6c5c595352d7 --- /dev/null +++ b/polkadot/zombienet_tests/misc/0002-upgrade-node.zndsl @@ -0,0 +1,28 @@ +Description: Smoke / Upgrade Node +Network: ./0002-upgrade-node.toml +Creds: config + +charlie: parachain 2000 block height is at least 10 within 200 seconds +dave: parachain 2001 block height is at least 10 within 200 seconds + +# upgrade both nodes +# For testing using native provider you should set this env var +# POLKADOT_PR_ARTIFACTS_URL=https://gitlab.parity.io/parity/mirrors/polkadot/-/jobs/1842869/artifacts/raw/artifacts +# with the version of polkadot you want to download. + +# avg 30s in our infra +alice: run ./0002-download-polkadot-from-pr.sh with "{{POLKADOT_PR_ARTIFACTS_URL}}" within 40 seconds +bob: run ./0002-download-polkadot-from-pr.sh with "{{POLKADOT_PR_ARTIFACTS_URL}}" within 40 seconds +alice: restart after 5 seconds +bob: restart after 5 seconds + +# process bootstrap +sleep 30 seconds + +alice: is up within 10 seconds +bob: is up within 10 seconds + + +alice: parachain 2000 block height is at least 30 within 300 seconds +bob: parachain 2001 block height is at least 30 within 120 seconds + diff --git a/polkadot/zombienet_tests/misc/0003-parathreads.toml b/polkadot/zombienet_tests/misc/0003-parathreads.toml new file mode 100644 index 0000000000000000000000000000000000000000..83b6d39bffb09c560b32c5f8254401c789d203df --- /dev/null +++ b/polkadot/zombienet_tests/misc/0003-parathreads.toml @@ -0,0 +1,32 @@ +[settings] +timeout = 1000 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +command = "polkadot" + + [[relaychain.nodes]] + name = "alice" + args = [ "--alice", "-lruntime=debug,parachain=trace" ] + + [[relaychain.nodes]] + name = "bob" + args = [ "--bob", "-lruntime=debug,parachain=trace" ] + +[[parachains]] +id = 100 +add_to_genesis = false +register_para = true +onboard_as_parachain = false + + [parachains.collator] + name = "collator01" + image = "{{COL_IMAGE}}" + command = "adder-collator" + args = [ "-lruntime=debug,parachain=trace" ] + +[types.Header] +number = "u64" +parent_hash = "Hash" +post_state = "Hash" diff --git a/polkadot/zombienet_tests/smoke/0001-parachains-smoke-test.toml b/polkadot/zombienet_tests/smoke/0001-parachains-smoke-test.toml new file mode 100644 index 0000000000000000000000000000000000000000..d132945aeea0d55b878f6436172e8e3045d7949b --- /dev/null +++ b/polkadot/zombienet_tests/smoke/0001-parachains-smoke-test.toml @@ -0,0 +1,30 @@ +[settings] +timeout = 1000 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +command = "polkadot" + + [[relaychain.nodes]] + name = "alice" + args = [ "--alice", "-lruntime=debug,parachain=trace" ] + + [[relaychain.nodes]] + name = "bob" + args = [ "--bob", "-lruntime=debug,parachain=trace" ] + +[[parachains]] +id = 100 +addToGenesis = false + + [parachains.collator] + name = "collator01" + image = "{{COL_IMAGE}}" + command = "adder-collator" + args = [ "-lruntime=debug,parachain=trace" ] + +[types.Header] +number = "u64" +parent_hash = "Hash" +post_state = "Hash" diff --git a/polkadot/zombienet_tests/smoke/0001-parachains-smoke-test.zndsl b/polkadot/zombienet_tests/smoke/0001-parachains-smoke-test.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..b280a198e08579d558906e09970ce4f6a34170f2 --- /dev/null +++ b/polkadot/zombienet_tests/smoke/0001-parachains-smoke-test.zndsl @@ -0,0 +1,6 @@ +Description: Smoke Test +Network: ./0001-parachains-smoke-test.toml +Creds: config + +alice: parachain 100 is registered within 225 seconds +alice: parachain 100 block height is at least 10 within 400 seconds diff --git a/polkadot/zombienet_tests/smoke/0002-parachains-upgrade-smoke-test.toml b/polkadot/zombienet_tests/smoke/0002-parachains-upgrade-smoke-test.toml new file mode 100644 index 0000000000000000000000000000000000000000..0becb408550a61e4a05af7ca80b4df79acedee00 --- /dev/null +++ b/polkadot/zombienet_tests/smoke/0002-parachains-upgrade-smoke-test.toml @@ -0,0 +1,38 @@ +[settings] +timeout = 1000 +bootnode = true + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +command = "polkadot" + + [[relaychain.nodes]] + name = "alice" + extra_args = [ "--alice" ] + + [[relaychain.nodes.env]] + name = "RUST_LOG" + value = "runtime=debug,parachain=trace,cumulus-collator=trace,aura=trace" + + [[relaychain.nodes]] + name = "bob" + extra_args = [ "--bob" ] + + [[relaychain.nodes.env]] + name = "RUST_LOG" + value = "runtime=debug,parachain=trace,cumulus-collator=trace,aura=trace" + +[[parachains]] +id = 100 +addToGenesis = true +cumulus_based = true + + [parachains.collator] + name = "collator01" + image = "{{COL_IMAGE}}" + command = "polkadot-collator" + + [[parachains.collator.env]] + name = "RUST_LOG" + value = "runtime=debug,parachain=trace,cumulus-collator=trace,aura=trace" diff --git a/polkadot/zombienet_tests/smoke/0002-parachains-upgrade-smoke-test.zndsl b/polkadot/zombienet_tests/smoke/0002-parachains-upgrade-smoke-test.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..bcea5aa1646e65bf6d2aec1ec82bfb5f042c0f23 --- /dev/null +++ b/polkadot/zombienet_tests/smoke/0002-parachains-upgrade-smoke-test.zndsl @@ -0,0 +1,8 @@ +Description: Smoke Test +Network: ./0002-parachains-upgrade-smoke-test.toml +Creds: config + +alice: parachain 100 is registered within 225 seconds +alice: parachain 100 block height is at least 10 within 460 seconds +alice: parachain 100 perform dummy upgrade within 200 seconds +alice: parachain 100 block height is at least 14 within 200 seconds diff --git a/polkadot/zombienet_tests/smoke/0003-deregister-register-validator-smoke.toml b/polkadot/zombienet_tests/smoke/0003-deregister-register-validator-smoke.toml new file mode 100644 index 0000000000000000000000000000000000000000..48c79a861bed4faaa74feb7fdb2655fc945082ed --- /dev/null +++ b/polkadot/zombienet_tests/smoke/0003-deregister-register-validator-smoke.toml @@ -0,0 +1,23 @@ +[settings] +timeout = 1000 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "rococo-local" +command = "polkadot" + + [[relaychain.nodes]] + name = "alice" + args = ["-lruntime=debug,parachain=trace" ] + + [[relaychain.nodes]] + name = "bob" + args = [ "-lruntime=debug,parachain=trace" ] + + [[relaychain.nodes]] + name = "charlie" + args = [ "-lruntime=debug,parachain=trace" ] + + [[relaychain.nodes]] + name = "dave" + args = [ "-lruntime=debug,parachain=trace" ] diff --git a/polkadot/zombienet_tests/smoke/0003-deregister-register-validator-smoke.zndsl b/polkadot/zombienet_tests/smoke/0003-deregister-register-validator-smoke.zndsl new file mode 100644 index 0000000000000000000000000000000000000000..05e83110e4fe7325284438d2d6f39efb4ddbe0d9 --- /dev/null +++ b/polkadot/zombienet_tests/smoke/0003-deregister-register-validator-smoke.zndsl @@ -0,0 +1,23 @@ +Description: Deregister / Register Validator Smoke +Network: ./0003-deregister-register-validator-smoke.toml +Creds: config + +# ensure is in the validator set +dave: reports polkadot_node_is_parachain_validator is 1 within 240 secs +dave: reports polkadot_node_is_active_validator is 1 within 240 secs + +# deregister and check +alice: js-script ./0003-deregister-register-validator.js with "deregister,dave" return is 0 within 30 secs + +# Wait 2 sessions. The authority set change is enacted at curent_session + 2. +sleep 120 seconds +dave: reports polkadot_node_is_parachain_validator is 0 within 180 secs +dave: reports polkadot_node_is_active_validator is 0 within 180 secs + +# register and check +alice: js-script ./0003-deregister-register-validator.js with "register,dave" return is 0 within 30 secs + +# Wait 2 sessions. The authority set change is enacted at curent_session + 2. +sleep 120 seconds +dave: reports polkadot_node_is_parachain_validator is 1 within 180 secs +dave: reports polkadot_node_is_active_validator is 1 within 180 secs diff --git a/polkadot/zombienet_tests/smoke/0003-deregister-register-validator.js b/polkadot/zombienet_tests/smoke/0003-deregister-register-validator.js new file mode 100644 index 0000000000000000000000000000000000000000..9963ce74d64e8c81d38c0ce8a141346e979f7c30 --- /dev/null +++ b/polkadot/zombienet_tests/smoke/0003-deregister-register-validator.js @@ -0,0 +1,46 @@ +const assert = require("assert"); + +function nameCase(string) { + return string.charAt(0).toUpperCase() + string.slice(1); +} + +async function run(nodeName, networkInfo, jsArgs) { + const {wsUri, userDefinedTypes} = networkInfo.nodesByName[nodeName]; + const api = await zombie.connect(wsUri, userDefinedTypes); + const action = jsArgs[0] === "register" ? "registerValidators" : "deregisterValidators" + const validatorName = jsArgs[1]; // used as seed + + await zombie.util.cryptoWaitReady(); + + // account to submit tx + const keyring = new zombie.Keyring({ type: "sr25519" }); + const alice = keyring.addFromUri("//Alice"); + const validatorStash = keyring.createFromUri(`//${nameCase(validatorName)}//stash`); + + await new Promise(async (resolve, reject) => { + const unsub = await api.tx.sudo + .sudo(api.tx.validatorManager[action]([validatorStash.address])) + .signAndSend(alice, (result) => { + console.log(`Current status is ${result.status}`); + if (result.status.isInBlock) { + console.log( + `Transaction included at blockHash ${result.status.asInBlock}` + ); + } else if (result.status.isFinalized) { + console.log( + `Transaction finalized at blockHash ${result.status.asFinalized}` + ); + unsub(); + return resolve(); + } else if (result.isError) { + console.log(`Transaction Error`); + unsub(); + return reject(); + } + }); + }); + + return 0; +} + +module.exports = { run }